openimageio-1.3.12~dfsg0.orig/0000755000175000017500000000000012271062644014321 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/CREDITS0000644000175000017500000000516512271062644015350 0ustar mfvmfvThis is a list of all the authors of OpenImageIO. Any such list is very inexact, and can't convey everybody's precise level of contribution (which is constantly shifting, anyway). However, I've made two tiers: (1) major developers who have contributed at least several hundred lines of code (noting their main contributions, if easily identifiable); (2) everybody else who has contributed any code at all. Major contributors (roughly in order of joining the project): Larry Gritz core classes & API, ImageCache/TextureSystem, iv, TIFF, JPEG, OpenEXR, HDR, PNG, zfile, Field3D, docs Philip Nemec unit testing framework Dan Wexler Windows port Chris Kulla texture system improvements Chris Foster lots of odds and ends, tinyformat, best code reviewer! Leszek Godlewski ICO, Targa, DDS, DPX, Cineon, RLA David Gordon build issues, Python bindings Robert Matusewicz Windows port, BMP, JPEG-2000, FITS, SGI, WebP Ismael Cortes iv improvements Dinko Galetik Python bindings Malcolm Humphreys color transfer methods Alan Jones Softimage PIC Krzysztof Blicharski sockets Nuno Cardoso PNM Mikael Sundell IFF Jeremy Selan Color space issues, maketx improvements, OpenColorIO integration Daniel Wyatt PSD Mariusz Szczepanczyk GIF Other contributors (alphabetically): Vishal Agrawal Jeph Alapat Shane Ambler Basileios Anastasatos Cassian Andrei Mark Boorer Solomon Boulos Nicolas Burtnyk Kevin Brightwell Fabien Castan Duncan Chan Irena Damsky Brent Davis Ben De Luca Nandan Dubey Sebastian Elsner Julien Enche Marcos Fajardo Delai Felinto Marie Fetiveau Henri Fousse Vitor Franchi Manuel Gamito Ananth Garre Deepak Gopinath Puneet Jain Saket Jalan Pavel Karneliuk Vinod Khare Konrad Kleine Alexander Kuleshov Pete Larabell Michel Lerenard Rui Li Hugh Macdonald Lukasz Maliszewski Justina Mikonyte Paul Molodowitch Ramon Montoya Alexander Murashko Samuel Nicholas M Joonas Pihlaja Carl Rand Sam Richards Jeremy Rose Ryen Alex Schworer Aman Shah Richard Shaw Stefan Stavrev Cliff Stein Mikael Sundell Ott Tinn Edgar Velazquez-Armendariz Matteo F. Vescovi Mark Visser Brecht Van Lommel Wormszer Xo Wang Nicholas Yue If you know of somebody that I missed, please let me know: lg (at) openimageio.org openimageio-1.3.12~dfsg0.orig/CHANGES0000644000175000017500000027161112271062644015324 0ustar mfvmfvChanges: Release 1.3.12 (25 Jan 2014 -- compared to 1.3.11) -------------------------------------------------- * Add .sxr and .mxr as possible filename extensions for OpenEXR. * PNG: add "png:compressionlevel" and "compression" strategy attributes. * Fix recent build break where OIIO would no longer compile properly against OpenEXR <= 1.6. * oiiotool --origin could crash with certain large ImageCache-backed images. Release 1.3.11 (8 Jan 2014 -- compared to 1.3.10) ------------------------------------------------- * DPX output: honor the "Software" metadata attribute passed in. * OpenEXR: fix crashing bug when reading stringvector attributes in the file. * Fix build breaks when building against OpenEXR 1.x. * Fix warnings with Boost Python + gcc 4.8. Release 1.3.10 (2 Jan 2014 -- compared to 1.3.9) ------------------------------------------------ * OpenEXR fix: multi-part EXR (2.0) didn't write the required "name" attribute for each part. * iconvert: properly handle multi-image files for formats that can't append subimages. * iv info window should print native file info, not translated ImageBuf/ImageCache info. * Improved strutil_test now much more comprehensively unit tests Strutil. * Strutil::split() fixes bug when maxsplit is not the default value. * Fix ImageCache::get_pixels() for the chbegin != 0 case, when cache and output buffer types were not identical. * DPX bug fix -- inappropriate use of "dpx_ImageDescriptor" could make invalid DPX files (especially when reading metadata from one DPX file, changing the number of channels, then writing out again as a DPX file). Release 1.3 (2 Dec 2013 -- compared to 1.2.x) ---------------------------------------------- Major new features and improvements: * Huge overhaul of the Python bindings: TypeDesc, ImageSpec (1.3.2), ImageInput, ImageOutput (1.3.3), ROI, ImageBuf (1.3.4), ImageBufAlgo (1.3.6). The Python bindings were pretty rusty, badly tested, undocumented, and had not kept up with recent changes in the C++ APIs. That's all fixed now, the Python APIs are finally first-class citizens (including full functionality, unit tests, and docs), and we intend to keep it that way. * The ability for an application to supply custom ImageInput and associate them with a file extension. Those II's can do anything, including generate image data procedurally. * GIF reader Public API changes: * Large overhaul of the Python bindings. See the (finally existing!) docs. * ImageBufAlgo: * New functions: nonzero_region(); ociodisplay(), resize() variety that lets you specify the filter by name; 2-argument (non-in-place) versions of add, sub, mul, rangecompress, rangeexpand, unpremult, premult, clamp fixNonFinite; sub() varieties that take float or float* operands. * Removed several IBA functions that have been deprecated since 1.2. * Deprecated the single-image in-place versions of add, sub, mul, rangecompress, rangeexpand, unpremult, premult, clamp fixNonFinite. * ImageBuf: * read() and init_spec() are no longer required, somewhat simplifying application code that uses ImageBuf. All ImageBuf API calls automatically read the spec and/or pixels from their named file if they are needed, if it has not already been done. (1.3.4) * save() is deprecated, and new ImageBuf::write() is now preferred (naming symmetry). (1.3.4) * New set_write_format() and IB::set_write_tiles() allow override of default choices for data format and tile size for subsequent calls to ImageBuf::write(). (1.3.4) * ImageCache / TextureSystem: * ImageCache::add_file() lets you seed the ImageCache with a "virtual file" that will read from a custom ImageInput. This lets you add "procedural images" to the IC. * ImageCache::add_tile() lets you add tiles to the ImageCache. The caller can initialize those tiles with any pixel values it chooses. * A new variety of IC/TS::destroy() takes a 'bool teardown' parameter that, when true, does a complete teardown of the underlying ImageCache, even if it's the "shared" one. (1.3.7) * OIIO::declare_imageio_format() exposes a way to give OIIO a custom ImageInput and/or ImageOutput (via factory functions) and associate them with particular file extensions. This makes it especially easy for an app to make a procedural image generator that looks to the entire rest of OIIO like a regular image file. (1.3.2) * TypeDesc::VECSEMANTICS now have additional enum tags for TIMECODE and KEYCODE to indicate that the data represents an SMPTE timecode or SMPTE keycode, respectively. (1.3.7) Fixes, minor enhancements, and performance improvements: * oiiotool improvements: * --autotrim Shrinks pixel data window upon output to trim black edges. (1.3.2) * --siappend Appends subimages of top two images on the stack. (1.2.2) * --datadump will print all pixel values of an image (debugging tool) (1.3.6) * --flatten turns a "deep" image into a flat one by depth-compositing within each pixel (1.3.6). * --ociodisplay applies an OpenColorIO display transformation. (1.3.7) * Fix memory leak when processing frame range. (1.2.1/1.3.2) * --help now returns a success error code, not a failure. (1.2.1/1.3.2) * Fix incorrect help message about --ociolook. (1.2.1/1.3.2) * Fix typo in "oiio:Colorspace" attribute name that interfered with correct color space conversion in --colorconvert. (1.2.1) * Many fixes and improvements to XMP & IPTC metadata handling. (1.2.2) * Multithread speed improvement when opening files by reducing how much time ImageInput::create and/or ImageOutput::create hold a global mutex. * oiiotool --origin and --fullpixels, when operating on cropped or overscanned image, could sometimes do the wrong thing. (1.2.2/1.3.3) * oiiotool --colorconvert did not work properly when the color transformation was detected to be a no-op. (1.2.2/1.3.3) * oiiotool --fit did not handle padding or offsets properly. (1.2.2/1.3.3) * Changed/improved the behavior of --rangecompress/--rangeexpand. (1.3.3) * 'oiiotool --pattern checker' was incorrect when nonzero offsets were used. (1.2.3/1.3.4) * oiiotool --runstats prints the total time/memory on every iteration when doing file sequence wildcard iteration. (1.3.4) * Eliminated a particular situation that might hit an ASSERT. Instead, bubble up a real error message. (1.3.4) * oiiotool --resize and --resample fixed for overscan images (1.3.5) * --ociolook applies OCIO looks. (1.3.6) * Supports printf-style frame range wildcards ('%04d') in addition to the '#' style, and scan for matching frames if no explicit framespec is provided. (1.3.6) * ImageBufAlgo improvements: * colorconvert() did not work properly when the color transformation was detected to be a no-op. * colorconvert(): added a variety that specifies color spaces by name. * New ociolook() function applies OCIO "looks." (1.3.6) * checker() was incorrect when nonzero offsets were used. * checker() now has default values of 0 for the 'offset' parameters (and so may be omitted if you want 0 offsets). (1.3.4) * unsharp_mask() bug when src and dst were different data formats. (1.2.3/1.3.4) * Better dealing with cases of IBA functions detecting and issuing errors when inputs that must be initialized are not. (1.3.4) * We changed the behavior of rangecompress/rangeexpand. We swear the new way is better. (1.3.3) * New nonzero_region() returns the shrink-wrapped nonzero pixel data window. (1.3.2) * resize() has a new variety that lets you specify the filter by name (rather than allocating ans passing a Filter2D*). * resize() and resample() fixed to more robustly handle overscan images. (1.3.5) * over()/zover() are no longer restricted to float images. (1.3.7) * ImageBuf: * ImageBuf::write() writes untiled images by default, fixing some tricky issues when IB's start thinking they're tiled because of interaction with the ImageCache (which makes everything look tiled). * ImageBuf::file_format_name() never worked properly, now is fixed (1.3.4) * Fixed bug that caused incorrect ImageBuf::copy_pixels() when the two IB's had different data types. (1.3.4/1.2.3) * Improved iterator's handling of how overscanned pixels interact with wrap modes. (1.3.6) * Fixed a bug with black wrap mode not working correctly. (1.3.7/1.2.4) * ImageCache/TextureSystem: * More careful with texture de-duplication -- texture value lookups use de-duplication, but metadata lookups (e.g., get_texture_info) uses the metadata from the original file. * get_image_info/get_texture_info queries for "datawindow" and "displaywindow". (1.3.6) * The multi-point version of environment() was broken. (1.3.9) * maketx: --hicomp uses the new range compression/expansion formula. (1.3.3) * DPX: * support multi-image (often used for stereo frames). * Fixed DPX input that didn't recognized offset/cropped images. (1.2.2/1.3.3, another fix in 1.3.4) * Fixed DPX output crash with cropped images. (1.2.2/1.3.3) * Now correctly get and set "smpte:TimeCode" and "smpte:KeyCode" metadata. (1.3.7). * OpenEXR: * Fixed write_scanlines handling of per-channel data types (1.3.6) * Several OpenEXR 2.0 deep file fixes: only some compression types supported, write_tiles passed wrong parameters, must suppress some attribute names. (1.2.3/1.3.6) * Now correctly get and set "smpte:TimeCode" and "smpte:KeyCode" metadata. (1.3.7). * JPEG: fixed that some JPEG files were not being recognized because of magic number issues. * TGA: Correctly unassociate alpha if it's from an unasociated file; also, always write unassociated data because so few Targa readers in the wild seem to properly handle associated alpha. * PNG: More correct handling of unassociated alpha. * TIFF: More correct handling of unassociated alpha. * PSD: fix handling of associated vs unassociated alpha. (1.2.3) * maketx fixed to handle inputs that are a mixture of cropped and overscanned. (1.3.5) * Fix segfault if OCIO is set to a non-existant file. (1.3.6) * Slight performance increase when writing images to disk (1.3.6) * Many fixes to make OIIO compile with libc++ (clang's new C++ library, and the default on OSX Mavericks). (1.2.3/1.3.6, 1.3.7) * Fixed several potential buffer overflow errors from unsafe strcpy. (1.3.8) Build/test system improvements: * Fix broken tests under Windows. (1.3.2) * Many fixes for compiler warnings on various platforms: fmath_test.cpp, field3dinput.cpp, sysutil.cpp, argparse.cpp, oiiotool.cpp. (1.2.1/1.3.2) * Fixes problems on little-endian architecture with texture3d.cpp. (1.2.1/1.3.2) * Fix compilation problems on architectures with gcc, but no 'pause' instruction. (1.2.1/1.3.2) * Fix build search path for correctly finding libopenjpeg 1.5. (1.2.1) * Work around bug in older MSVC versions wherein Filesystem::open needed to explicitly seek to the beginning of a file. (1.2.1/1.3.2) * Build fixes for FreeBSD. (1.2.1/1.3.2, 1.2.4/1.3.6) * Fix testsuite/oiiotool on Windows -- windows shell doesn't expand wildcards. (1.2.1/1.3.2) * Fix warnings for new GCC 4.8 compiler. * Always search for and use the release HDF5 libraries, not the debugging ones, even when building debug OIIO (this fixes errors when a system does not have the debugging HDF5 libraries installed). (1.2.2/1.3.3) * Extensive unit tests in the testsuite for the Python bindings. * Fix compiler error on MIPS platform. (1.2.2/1.3.3) * Add FIELD3D_HOME description to 'make help' (1.2.2/1.3.3) * Add cmake variables ILMBASE_CUSTOM_INCLUDE_DIR, ILMBASE_CUSTOM_LIB_DIR, OPENEXR_CUSTOM_INCLUDE_DIR, and OPENEXR_CUSTOM_LIB_DIR to make it easier to have site-specific hints for these packages' locations. (1.3.4) * Add BOOST_HOME and OCIO_HOME controls from the top-level Makefile wrapper. (1.3.4/1.2.3) * Accommodate new cmake release that slightly changes the HDF5 library naming. (1.3.6) * Various fixes to make the code compile properly with libc++ (clang's rewrite of the C++ standard library). (1.3.6) * Updated PugiXML (partly to help compilation with libc++) (1.3.6) * Better support for NOTHREADS (for some legacy systems) (1.3.6) * Fix to __attribute__(visibility) for gcc < 4.1.2 (1.3.6) * Improve the CMake build files to fully quote path constructions to make it more robust for builds with paths containing spaces. (1.3.7) * Moved the main CMakeLists.txt file to the top level directory, per usual CMake conventions. (1.3.7) Developer goodies: * Docs improvement: full documentation of ImageBufAlgo. (1.2.1/1.3.2) * Merge improved "Tinyformat" that fixes a bug in some old glibc versions (1.3.2). * Now each command line tools explicitly converts to UTF native arguments, rather than relying on it happening in ArgParse (which no longer does so). (1.3.2) * Strutil::contains() and icontains(). (1.2.2/1.3.3) * Updatd "Tinyformat" to the latest release (1.3.6) * Sysutil::physical_memory() tries to figure out the total physical memory on the machine. (1.3.6) * Strutil::safe_strcpy (1.3.8) * ParamValue now allows get/set of the hidden 'interp' field. (1.3.9) Release 1.2.3 (1 Nov 2013) -------------------------- * 'oiiotool --pattern checker' (and ImageBufAlgo::checker) was incorrect when nonzero offsets were used. * ImageBufAlgo::unsharp_mask() bug when src and dst were different data formats. * PSD: fix handling of associated vs unassociated alpha. * Fixed bug that caused incorrect ImageBuf::copy_pixels() when the two IB's had different data types. * Add BOOST_HOME and OCIO_HOME controls from the top-level Makefile wrapper. * Several OpenEXR 2.0 deep file fixes: only some compression types supported, write_tiles passed wrong parameters, must suppress some attribute names. * DPX - several fixes to properly handle images with nonzero origins. * Fixes for recent cmake not finding HDF5 properly. * Many fixes to make OIIO compile with libc++ (clang's new C++ library, and the default on OSX Mavericks). * Fix OpenEXR write_scanlines handling of per-channel data types. * Upgraded PugiXML to a more modern version (necessary for clean compile with libc++). Release 1.2.2 (1 Oct 2013) -------------------------- * New features: * New oiiotool --siappend : append subimages of top two images on stack. * Utilities: added Strutil::contains() and icontains(). * Fixes: * Fixes in handling XMP & IPTC metadata. * oiiotool --origin and --fullpixels did not correctly propagate their changes to the output images. * oiiotool --colorconvert (and the underlying ImageBufAlgo::colorconvert) could crash if given a color conversion recognized as a no-op. * DPX output could crash when writing crop images. * DPX input was not recognizing the proper image offset or originalsize. * oiiotool --fit wasn't padding correctly or modifying offsets properly. * Build fixes: * Fix compiler error on MIPS platform. * Add FIELD3D_HOME description to 'make help' * Always use the HDF5 release libraries (for Field3D), not the debug ones. Release 1.2.1 (5 Aug 2013) --------------------------- * oiiotool: Fix memory leak when processing frame range. * Docs improvement: full documentation of ImageBufAlgo. * oiiotool --help now returns a success error code, not a failure. * oiiotool: fix incorrect help message about --ociolook. * oiiotool: Fix typo in "oiio:Colorspace" attribute name that interfered with correct color space conversion in --colorconvert. * Many fixes for compiler warnings on various platforms: fmath_test.cpp, field3dinput.cpp, sysutil.cpp, argparse.cpp, oiiotool.cpp. * Fixes problems on little-endian architecture with texture3d.cpp. * Fix compilation problems on architectures with gcc, but no 'pause' instruction. * Fix build search path for correctly finding libopenjpeg 1.5. * Work around bug in older MSVC versions wherein Filesystem::open needed to explicitly seek to the beginning of a file. * Build fixes for FreeBSD. * Fix testsuite/oiiotool on Windows -- windows shell doesn't expand wildcards. Release 1.2 (8 July 2013) ------------------------- Major new features and improvements: * New oiiotool commands: --swap Exchanges the top two items on the image stack. --fit Resize image to fit into a given resolution (keeping aspect). --ch Select/cull/reorder/add channels within an image. --chappend Merge two images by appending their color channels. --chnames Rename some or all of the color channels in an image. --zover Depth compositing --cadd Add constant per-channel values to all pixels --cmul Multiply an imge by a scalar or per-channel constant. --fillholes Smoothly interpolate for hole filling. --resample Similar to --resize, but just uses closest pixel lookup. --clamp Clamp pixel values --rangeexpand Expand range for certain HDR processing --rangecompress Compress range for certain HDR processing --unpremult Divide colors by alpha (un-premultiply). --premult Multiply colors by alpha. --kernel Make a convolution kernel using a filter name. --convolve Convolve two images. --blur Blur an image. --unsharp Sharpen an image using an unsharp mask. --paste Paste one image on another. --mosaic Create a rectilinear image mosaic. --transpose Transpose an image (flip along the diagonal axis) --chsum Sum all channels in each pixel --cshift Circular shift an image pixels --fft --ifft Forward and inverse Fourier transform --colorcount Counts how many pixels are one of a list of colors. --rangecheck Counts how many pixels fall outside the given range. --ociolook Apply OpenColorIO "looks" * oiiotool can loop over entire numeric frame ranges by specifying wildcard filenames such as "foo.#.tif" or "bar.1-10#.exr". * oiiotool --frames and --framepadding give more explicit control over frame range wildcards. * Significant performance improvements when reading and writing images using the ImageBuf::read and ImageCache::get_pixels interfaces, and in some cases also when using regular ImageInput. This also translates to improved performance and memory use for oiiotool and maketx. * At least doubled the performance of maketx for large images when run on multi-core machines. * Significant performance improvements when using ImageBuf::Iterator or ConstIterator to traverse the pixels in an ImageBuf, and the iterators now support "wrap" modes (black, clamp, periodic, mirror). * maketx --hicomp does "highlight compensation" by compressing the HDR value range prior to inter-MIP resizes, then re-expanding the range. * Field3D writer (it could read f3d files before, but not write them). * idiff can now compare that are not the same size (treating pixels beyond the pixel data window is being 0 valued). * maketx --lightprobe turns a "lightprobe" iamge into a latlong environment map. * Significant improvements and fixes to EXIF, IPTC, and XMP metadata reading and writing. * Significant thread scalability improvements to TextureSystem and ImageCache. * Huge overhaul of functionality, style, and performance of the entire ImageBufAlgo set of functions (see the "Public API changes" section below, and the imagebufalgo.h file for details). Public API changes: * ImageOutput semantics change: If the spec passed to open() has spec.format set fo UNKNOWN, then select a default data format for the output file that is "most likely to be able to be read" and/or "most typical for files of that format in the wild." Also, ImageOutput::open() will never fail because a requested data format is unavailable; if the requested format is not supported, a reasonable alternate will always be chosen. * ImageBuf has been changed to a "PIMPL" idiom, wherein all the internals are no longer exposed in the public API. This allows us to change ImageBuf internals in the future without breaking API or link compatibility (and thus giving us more freedom to backport important improvements to prior releases). * Overhaul of ImageBufAlgo functions: they all take an ROI parameter; use the DISPATCH macros to make them work with all pixel data types where practical (previously, many supported float only); use Iterator rather than getpixel/setpixel, leading to huge speed improvements; multithread when operating on enough pixels, leading to huge speed improvements; work on 3D (volume) images where applicable; always gracefully handle uninitialized dest image or undefined ROI. * New ImageBufAlgo functions: channels(), channel_append(), mul(), paste(), zover(), add() and mul() varieties that that add/multiply a constant amount to all pixels, fillholes_pp(), resample(), clamp(), rangecompress(), rangeexpand(), make_kernel(), unsharp_mask(), transpose(), channel_sum(), circular_shift(), fft(), ifft(), color_count(), color_range_check(). [look in imagebufalgo.h for documentation.] * ImageBufAlgo::make_texture() allows you to do the same thing that maketx does, but from inside an application and without launching a shell invocation of maketx. Two varieties exist: one that takes a filename and reads from disk, another that takes an ImageBuf already in memory. * ImageBuf Iterator/ConstIterator now take "wrap" mode parameters that allow out-of-range iterators to be able to retrieve valid data. Supported wrap modes include black, clamp, periodic, and mirror. This simplifies a lot of algorithms using IB::Iterator, they can now be written to rely on wrap behavior rather than being cluttered with checks for "if (it.exits())" clauses. * ImageBufAlgo::computePixelHashSHA1 has been refactored to take ROI, a block size, and thread count, and thus can be parallelized with threads. The block size means that rather than computing a single SHA-1 for all the pixels, it computes separate (parallel) SHA-1 for each group of blocksize scanlines, then returns the SHA-1 of all the individual SHA-1 hashed blocks. This is just as strong a hash as before, thought the value is different than doing the whole thing at once, but by breaking it into blocks the computation can be multithreaded. * ImageBuf::swap() makes it easy to swap two ImageBuf's. * ImageSpec::get_channelformats is now const (and always should have been). Fixes, minor enhancements, and performance improvements: * TextureSystem improvements: * Make sure "black" wrap wins out over "fill" value when they conflict (looking up an out-of-range channel beyond the pixel data window). * "mirror" wrap mode was slightly incorrect and has been fixed. * oiiotool improvements: * oiiotool -v breaks down timing by individual function. * oiiotool has been sped up by forcing read of the whole image up front for reasonably-sized files (instead of relying on ImageCache). * oiiotool does not write output images if fatal errors have occurred. * oiiotool --diff: Better error handling, better error printing, and now it can compare images with differing data windows or channel numbers ("missing" channels or pixels are presumed to be 0 for the purposes of comparing). * oiiotool --resize (and --fit): properly handle the case of resizing to the same size as the original image. * oiiotool -d CHAN=TYPE can set the output for just one channel. * ImageBufAlgo improvements: * Internal overhaul of IBA::resize to greatly speed it up. * Improve IBA::resize to handle the image edge better -- instead of clamping, just don't consider nonexistant pixels. * More careful selection of filter when resizing (IBA::resize, oiiotool --resize and --fit, and maketx). * Fix IBA::paste() error when the foreground image runs off the end of the background image. * Bug fix when computing SHA-1 hash of 0-sized images. * Image format support improvements: * Bug fix where some format readers (PNM, SGI, and IFF) would leave the file handle opened if the ImageInput was destroyed without calling close() first. Now we guarantee that destroying the II always causes the file to close(). * DPX: output allocation bug fix; properly set pixel aspect ratio for DPX write. * IFF: bug fix for endian swap for IFF file input. * JPEG2000: fix warnings, make sure event manager transfer object remains valid. * OpenEXR: when reading, was botching the ordering of per-channel data formats. * SGI write: bug fix for the case of 15 bpp RLE encoding, was double-swapping bytes. * Targa: more robust check for presence of alpha channels; bug fix where R and B channels were reversed for certain kinds of palette images. * TIFF: Store the orientation flag properly when outputting a TIFF file. * maketx improvements: * maketx --chnames allows you to rename the channels when you create a texture. * maketx bug fixes: incorrect weighting when resizing MIP levels for latlong environment map images that could make visible artifacts on some intermediate MIP levels. * encode_exif() didn't copy the right number of bytes. * Python bindings: ImageSpec extra_attribs now properly responds to iterator calls. * Fix bug in sRGB -> linear conversion. * iv: make pixelview display coordinates & color even when outside the data window. Build/test system improvements: * Many fixes to improve builds and eliminate warnings on Windows and MinGW. * Fix missing InterlockedExchangeAdd64 for Windows XP. * New make/cmake boags: OIIO_BUILD_TOOLS=0 will exclude building of the command line tools (just build libraries), OIIO_BUILD_TESTS=0 will exclude building of unit test binaries. * Improved matching of testsuite reference images on different platforms. * Lots of fixes to compiler warnings on newer gcc and clang releases. * Unit tests for Timer class. * libOpenImageio/imagespeed_test benchmarks various methods of reading and writing files and iterating image pixels (to help us know what to optimize). * If OpenSSL is available at build time, OIIO will use its SHA-1 implementation instead of our own (theirs is faster). We still fall back on ours if OpenSSL is not available or when OIIO is built with USE_OPENSSL=0. * Allow default the shared library suffix to be overridden with the CMake variable OVERRIDE_SHARED_LIBRARY_SUFFIX. * Eliminated all uses of the custom DEBUG symbol, and instead use the more standard idiom "#ifndef NDEBUG". * Compatibility fixes for Python3. * MSVC 2008: Prevent a redefinition error when using boost::shared_ptr. * Fixes for compatibility with libtiff 4.0. * Fixes for MSVC debug mode having out-of-bound exceptions. * Fixes for libjpeg 9.x. * Compile to treat warnings as errors (you can disable this with STOP_ON_WARNING=0). * New filter: "sharp-gaussian". * Fix various Windows build errors. * Improvements to the build when finding IlmBase/OpenEXR. * Various fixes to compile on ARM architecture. * Fixes to compile on ESA/390 mainframe (!). * testtex --threadtimes, --trials, --iters, --nodup, --wedge. These are helpful in using testtext to benchmark the texture system. * Improvements to make more tests work properly on Windows. Developer goodies: * Improved ASSERT and DASSERT macros to not generate warning for certain debug compiles; key their debug behavior by the absence of the standard NDEBUG idiom rather than presence of a custom DEBUG symbol; rename the message variants ASSERT_MSG and DASSERT_MSG. * Change the default for Sysutil::memory_used to report resident memory rather than virtual process size. * Multithread/parallel version of utility function convert_image(). * imagebufalgo.h improvements and expansion of the various DISPATCH_* macros. * New Filesystem utilities: parent_path(), get_directory_entries(). * New Strutil utilities: extract_from_list_string * spinlock tweaks make it faster than TBB's spin locks! * By default, we no longer build or use TBB (it's considered deprecated, but in 1.2 can still be turned on with USE_TBB=1). * In fmath.h, added definitions for safe_inversesqrt, safelog, safe_log2, safe_log10, safe_logb. * In typedesc.h, added TypeDesc::tostring() function. * unordered_map_concurrent.h contains a template for a thread-safe unordered_map that is very efficient even for large number of threads simultaneously accessing it. * Documentation: Finally, a chapter in the PDF docs that fully describes the ImageBuf class. Release 1.1.13 (24 Jun 2013) ---------------------------- * Texture: make sure wrap mode "black" wins over "fill" value when they conflict. Release 1.1.12 (20 Jun 2013) ---------------------------- * Fix oiiotool '#' wildcard, was broken on Windows. * Fix an overflow problem that plagued 'maketx' when running on input larger than 32k x 32k (among other possible failures). Release 1.1.11 (29 May 2013) ---------------------------- * IFF input: bug in endian swap of 16 bit IFF files. * oiiotool: fix a minor bug where tiled files were output inappropriately. (Had been patched in master some time ago.) * fmath.h additions: safe_inversesqrt, safe_log, safe_log2, safe_log10, safe_logb. These are versions that clamp their inputs so that they can't throw exceptions or return Inf or NaN. * Fix to not incorrectly print ImageCache stats for certain broken files. Release 1.1.10 (13 Apr 2013) ---------------------------- * IBA::fillholes() and oiiotool --fillholes can smoothly fill in alpha holes with nearby colors. Great for extrapolating the empty areas of texture atlas images so that filtered texture lookups pull in a plausible color at part edges. * IBA::clamp and oiiotool --clamp clamp pixel values to a scalar or per-channel min and/or max, or clamp alpha to [0,1]. * IBA::rangecompress()/rangeexpand(), and oiiotool --rangecompress / --rangeexpand compress the excess >1 values of HDR images to a log scale (leaving the <= 1 part linear), and re-expand to the usual linear scale. This is very helpful to reduce ringing artifacts that can happen when an HDR image is resized with a good filter with negative lobes (such as lanczos3), by doing a range compression, then the resize, then range expansion. It's not mathematically correct and loses energy, but it often makes a much more pleasing result. * maketx --hicomp does highlight compression -- automatically doing a range compress before each high-quality resize step, and then a range expansion and clamp-to-zero (squash negative pixels) after each resize. * DPX - when writing DPX files, properly set the pixel aspect ratio. Release 1.1.9 (2 Apr 2013) -------------------------- * IBA::resize and oiiotool --resize/--fit: Bug fixes to resize filter size selection fix artifacts wherein extreme zooms could end up with black stripes in places where the filters fell entirely between samples. * oiiotool --fit: fix subtle bugs with aspect ratio preservation for images with differing data and display windows; and allow "filter=..." to override the default filter used for fit. * Resize improvement: fix potential artifacts at the image edges resulting from odd clamping behavior. * Even more frame range wildcard flexibility with oiiotool --frames and --framepadding options. * oiiotool --resize and --fit (and the underlying IBA::resize()) have been sped up significantly and are now also multithreaded. Release 1.1.8 (15 Mar 2013) --------------------------- * oiiotool --chappend (and ImageBufAlgo::channel_append() underneath) allow you to take two files and concatenate their color channels. * oiiotool --chnames allows you to rename some or all of a file's color channels. * oiiotool can loop over entire frame ranges by specifying wildcard filenames such as "foo.#.tif" or "bar.1-10#.exr". * Cmake: OVERRIDE_SHARED_LIBRARY_SUFFIX allows the shared library suffix to be overridden (e.g., if you need to force .so names on OSX rather than the usual default of .dylib). Release 1.1.7 (21 Feb 2013) --------------------------- * Back out dangerous change to thread.h that was in 1.1.6, which could cause performance problems. * Compile fix for WIN32 in strutil.cpp * Compile fix for Windows XP - add implementation of InterlockedExchangeAdd64 Release 1.1.6 (11 Feb 2013) --------------------------- * Fix bug that could generate NaNs or other bad values near the poles of very blurry environment lookups specifically from OpenEXR latlong env maps. * Fix bug in oiiotool --crop where it could mis-parse the geometric parameter. * Fix bug in ImageCache::invalidate() where it did not properly delete the fingerprint of an invalidated file. * Cleanup and fixes in the oiiotool command line help messages. * New function ImageBufAlgo::paste() copies a region from one IB to another. * oiiotool --fit resizes an image to fit into a given resolution (keeping the original aspect ratio and padding with black if needed). * ImageBufAlgo::channels() and "oiiotool --ch" have been extended to allow new channels (specified to be filled with numeric constants) to also be named. * New function ImageBufAlgo::mul() and "oiiotool --cmul" let you multiply an image by a scalar constant (or per-channel constant). * Important maketx bug fix: when creating latlong environment maps as OpenEXR files, it was adding energy near the poles, making low-res MIP levels too bright near the poles. * Fix to "oiiotool --text" and "oiiotool --fill" -- both were incorrectly making the base image black rather than drawing overtop of the previous image. * Fix FreeBSD compile when not using TBB. * New oiiotool --swap exchanges the top two items on the image stack. Release 1.1.5 (29 Jan 2013) --------------------------- * Bug fix in ImageBufAlgo::parallel_image utility template -- care when not enough work chunks to dole out to all the threads (was previously sending work to threads with nonsensical ROI's, now we just stop when all the regions have been doled out). * Additional optional argument to IBA::zover that, when nonzero, will treat z=0 pixels as infinitely far away, not super close. You can turn this on from oiiotool with: oiiotool --zover:zeroisinf=1 ... Release 1.1.4 (27 Jan 2013) --------------------------- * ImageBufAlgo::make_texture() allows you to do the same thing that maketx does, but from inside an application and without launching a shell invocation of maketx. * oiiotool now recognizes --metamatch and --nometamatch arguments which cause metadata names matching (or only info NOT matching) the given regular expression to be printed with --info. * oiiotool --zover does z (depth) composites (it's like a regular "over", but uses the z depth at each pixel to determine which of the two images is the foreground and which is the background). * ImageBufAlgo::zover() performs z compositing (same as oiiotool --zover). * ImageBufAlgo::fixNonFinite didn't work properly with 'half' image buffers. * Performance improvements when reading and writing images. * Fix error when writing tiled 'float' TIFF images, corrupted output. (Could easily happen when using 'maketx' to convert float images into TIFF textures.) * Eliminate warnings when compiling with Clang 3.2. * New CMake variable "USE_EXTERNAL_TBB" can optionally be set to force use of an external TBB library rather than the embedded one. * Additional testsuite tests (doesn't affect users, but makes bugs easier to catch). * Fix build problem with SHA1.cpp on some platforms. Release 1.1.3 (9 Jan 2013) --------------------------- * Build fix: incorrectly named OpenEXR 2.x files. * Bug fix in oiiotool --croptofull on OSX * Build fixes for MinGW on Windows. * maketx --fullpixels option ignores any origin or display window in the source image, pretending the pixel data is the entire 0-1 image range starting at the origin (useful when the source image is created by an application that incorrectly writes it out as if it were a crop window). * maketx no longer will clobber existing ImageDescription metadata when it adds SHA-1 hash or other info as it creates the texture. * Many additional Exif and IPTC tags are correctly recognized. * maketx and oiiotool recognize and take advantage of IPTC:ImageHistory metadata. Release 1.1.2 (5 Dec 2012) -------------------------- * maketx fixes -- was botching creation of textures from source images that were crop windows (pixel window smaller than display window). * Minor bug fix to Timer when repeatedly starting and restopping (Apple only). * Bug fix in ustring:find_last_not_of. Release 1.1.1 (16 Nov 2012) --------------------------- * Altered the ImageInput::read_scanlines, read_tiles, read_native_scanlines, read_native_tiles, read_native_deep_scanlines, read_native_deep_tiles, and the channel-subset version of ImageSpec::pixel_bytes, so that instead of specifying channel subsets as (firstchan, nchans), they are specified as [chbegin, chend), to match how spatial extents are done, as well as how channel ranges already were specified in ROI and ImageBuf. We hate changing API meanings, but we really think this is better and more consistent. Note that the two common uses of channel subsets were firstchan=0,nchans=nchannels (select all channels) and firstchan=foo,nchans=1, and we have rigged it so that [chbegin,chend) returns the same channels in both of these cases (in the latter case, because we retrieve a minimum of 1 channel), so we believe this is unlikely to break working code in the vast majority of cases. * OpenEXR: support reading and writing V2f attributes. * OIIO::getattribute("extension_list") returns a list of all formats supported, and all extensions for each format, in the form: "formatA:ext1,ext2,ext3;formatB:ext4,ext5;..." * The new ImageCache per-file stats that list numbers of tiles read per MIPmap level have been reformatted slightly, and now print only for files that are actually MIP-mapped. * New ImageCache::get_pixels() variety that can retrieve a subset of channels. * Substantial speedup of ImageCache::get_pixels, used to be about 50% more expensive to call IC::get_pixels compared to a direct call to ImageInput::read_image; now is only about 15% more expensive to use the cache. Release 1.1 (9 Nov 2012) ------------------------ Major new features and improvements: * Support for reading and writing "deep" images (including OpenEXR 2.0). * Big ImageCache/TextureSystem improvements: - Improved accuracy of anisotropic texture filtering, especially when combined with "blur." - Improve performance in cases with high numbers of threads using the TS simultaneously (mostly due to use of reader-writer locks on the tile cache rather than unique locks). * New ImageBufAlgo functions: fromIplImage() : converts/copies an OpenCV image to an ImageBuf. capture_image() : captures from a camera device (only if OpenCV is found) over() : Porter/Duff "over" compositing operation render_text() : render text into an image histogram() : compute value histogram information for an image histogram_draw() : compute an image containing a graph of the histogram of another image channels() : select, shuffle, truncate, or extend channels of an image. * New oiiotool commands: --capture : captures from a camera device (only if OpenCV is found) --pattern constant : creates a constant-color image --over : Porter/Duff "over" compositing operation --text : render text into an image. --histogram : computes an image containing a graph of the histogram of the input image. --fill : fills a region with a solid color --ch : select, shuffle, truncate, or extend channels API changes: * A new static ImageInput::open(filename [,config]) combines the old create-and-open idiom into a single call, which is also much more efficient because it won't needlessly open and close the file multiple times. This is now the preferred method for reading a file, though the old-style create() and open() still work as always. * Deep image support: ImageInput adds read_native_deep_scanlines, read_native_deep_tiles, read_native_deep_image, and ImageOutput adds write_deep_scanlines, write_deep_tiles, write_deep_image, as well as a supports("deepdata") query. Also, a 'deep' field has been added to ImageSpec, and some deep data access functions have been added to ImageBuf. * Altered the ImageInput::read_scanlines, read_tiles, read_native_scanlines, read_native_tiles, read_native_deep_scanlines, read_native_deep_tiles so that instead of specifying channel subsets as (firstchan, nchans), they are specified as [chbegin, chend), to match how spatial extents are done, as well as how channel ranges already were specified in ROI and ImageBuf. We hate changing API meanings, but we really think this is better and more consistent. Note that the two common uses of channel subsets were firstchan=0,nchans=nchannels (select all channels) and firstchan=foo,nchans=1, and we have rigged it so that [chbegin,chend) returns the same channels in both of these cases (in the latter case, because we retrieve a minimum of 1 channel), so we believe this is unlikely to break working code in the vast majority of cases. * ImageInput plugins now may supply a valid_file(filename) method which detects whether a given file is in the right format, less expensively than doing a full open() and checking for errors. (It's probably the same cost as before when the file is not the right time, but when it is, it's less expensive because it can stop as soon as it knows it's the right type, without needing to do a full header read and ImageSpec setup.) * New ImageCache::get_pixels() method that can retrieve a subset of channels. * Removed various error_message() functions that had been deprecated for a long time (in favor of newer getmessage() functions). * Define a namespace alias 'OIIO' that gets you past all the custom namespacesin a convenient way. * TextureOpt now contains a 'subimagename' field that allows subimages to be addressed by name as well as by index (only for multi-image textures, of course). * ImageBuf improvements: - A new constructor allows an ImageBuf to "wrap" an existing buffer memory owned by the calling application without allocating/copying. - Renamed the old ImageBuf::copy_pixels -> get_pixels, and it now works for 3D (volumetric) buffers. - New ImageBuf::copy(), and eliminated operator= which was confusing. - New ImageBuf methods: reres(), copy_metadata(), copy_pixels(), get_pixel_channels(). - ImageBuf::specmod() allows writable access to the ImageSpec (caution!). - Better error reporting mechanism. - get_pixels and get_pixel_channels take optional strides. * ImageBufAlgo changes: - Many ImageBufAlgo functions now take a 'ROI' that restricts the operation to a particular range of pixels within the image (usually defaulting to the whole image), and for some operations a range of channels. - zero() and fill() take ROI arguments. - ImageBufAlgo::CompareResults struct changed the failure and warning counts to imagesize_t so they can't overflow int for large images. * OIIO::getattribute("format_list") now can retrieve the comma-separated list of all known image file formats. * OIIO::getattribute("extension_list") returns a list of all formats supported, and all extensions for each format, in the form: "formatA:ext1,ext2,ext3;formatB:ext4,ext5;..." Fixes, minor enhancements, and performance improvements: * ImageCache/TextureSystem: - Anisotropic texture lookups are more robust when the derivatives are tiny. - Attribute "deduplicate" controls whether the identical-image deduplication is enabled (on by default). - Attribute "substitute_image" lets you force all texture references to a single image (helpful for debugging). - Texture files are no longer limited to having tile sizes that are powers of 2. - Much faster TIFF texture access (by speeding up switching of MIPmap levels). - More graceful handling of the inability to free handles or tiles under extreme conditions. Rather than assert when we can't free enough to stay within limits, just issue an error and allow the limits to be exceeded (hopefully only by a little, and temporarily). - Detailed per-file stats now track the number of tile reads per MIPmap level. - Attribute "unassociatedalpha" (when nonzero) requests that IC images not convert unassociated alpha image to associated alpha. - Substantial speedup of ImageCache::get_pixels, used to be about 50% more expensive to call IC::get_pixels compared to a direct call to ImageInput::read_image; now is only about 15% more expensive to use the cache. * iconvert handles the int32 and uint32 cases. * Bug fix in to_native_rectangle, which could lead to errors in certain data format conversions. * iv improvements: - better behavior after closing the last image of the sequence. - file load/save dialogs can filter to show just certain image file types. - remember last open dialog directory - "About" dialog has a link to the OIIO home page * Improve ::create to more robustly handle files whose extensions don't match their actual formats. * OpenImageIO::geterror() is now thread-specific, so separate threads will no longer clobber each others' error messages. * OpenEXR: support for building with OpenEXR 2.x, including use of multi-part EXR and "deep" data. * Fix reading bugs in DPX and Cineon. * DPX: fix endianness problem for 15 bit DPX output. * PNG: fix handling of gamma for sRGB images. * oiiotool fixes: print MIP messages correctly (it was only printing for the first MIP level); make sure stray "oiio:BitsPerSample" in an input file doesn't mess up the -d flags. * Field3D fixes: properly catch exceptions thrown by the Field3D open(); conform metadata to Field3D conventions; multi-layer f3d files will present as a multi-image file with the "oiio:subimagename" giving a unique name for each layer subimage; * OpenEXR: suppress format-specific metadata from other formats. * OpenEXR: support reading and writing V2f attributes. * Targa: fix several bugs that were preventing certain metadata from being written properly. * TIFF: recognize the SAMPLEFORMAT_IEEEFP/bitspersample=16 as an image composed of "half" pixels; enable PREDICTOR_FLOATINGPOINT to give slightly better compression of float images. * Handle UTF-8 paths properly on Windows. * Removed the obsolete "iprocess" utility. * Fix allocation and stride bugs when dealing with images having different data formats per channel, and tiled images with partially filled border tiles. * Field3D: Bug fix when reading vector f3d files. * Significant performance improvements of our atomics and spin locks when compiling with USE_TBB=0. * Fix quantize() to properly round rather than truncate. * ImageBufAlgo functions now by convention will save error messages into the error state of their output ImageBuf parameter. * Improve I/O error checking -- many file reads/writes did not previously have their result status checked. * Fixed missing OpenEXR open() error message. * Clean up error reporting in iconvert. * Fixes to handle Windows utf8 filenames properly. * ImageBufAlgo::compare() gives a sensible error (rather than an assertion) if the images being compared are not float. * maketx: - Better error messages for a variety of things that could go wrong when reading or writing image files. - Fixes for bug preventing certain ImageCache efficiencies. - new option --ignore-unassoc leaves unassociated alpha data as it is (no auto-conversion to associated alpha) and/or ignores the tags for an input file that is associated but incorrectly tagged as unassociated alpha. - Option --monochrome-detect was buggy for images with alpha. - Option --constant-color-detect didn't do anything; now it works. - New option: --compression allows you to override the default compresion. * oiiotool & info: the --hash command had a bug wherein when applied to images there were MIP-mapped, would hash the lowest-res MIP level rather than the highest-res. This could result in two different images, if they happened to have the same average color, to incorrectly report the same SHA-1 hash. Note that this did NOT affect non-MIPmapped images, nor did it affect the SHA-1 hashing that occurred in maketx to allow the TextureSystem to detect duplicate textures. Build/test system improvements: * Various Windows build fixes, including fixes for Windows 7, and improvements to running the testsuite on Windows. * Testsuite additions and improvements: png fmath_test * Compilation fixes on FreeBSD. * Compilation fixes on GNU Hurd platform. * Compilation and warning fixes for Clang 3.1. * Add FIELD3D_HOME build variable to allow explicit path to Field3D implementation. * Remove support for Boost < 1.40. * Improved unit tests for atomics, spin locks, and rw locks. * Avoid generating iv man pages when USE_QT=0 * New testtex options: --aniso, --stblur * CMake option 'EXTRA_CPP_DEFINITIONS' lets custom builds inject site-specific compiler flags. * Make/cmake option: HIDE_SYMBOLS=1 will try to restrict symbol visibility so that only symbols intended to be part of the public APIs will be visible in the library when linked. * The old DLLPUBLIC and LLEXPORT macros, which could clash with other packages, have been renamed to OIIO_API and OIIO_EXPORT. * Greatly reduced output when building with cmake; by default, most non-error status messages only are printed when VERBOSE=1 compilation is requested. Developer goodies: * Strutil new utilities: iequals, istarts_with, iends_with, to_lower, to_upper, strip, join. * Use Chris Foster's 'tinyformat' for type-safe printf-like formatting, and this now forms the basis of Strutil::format, ustring::format, and many of the classes' error() methods. * TypeDesc::equivalent() tests for type equality but allows triples with different' vector semantics to match. * In timer.h, a new time_trial() template that makes multiple trial benchmarks easy. * Macros for memory and cache alignment (in sysutil.h). * Extend Filesystem::searchpath_find() to be able to search recursively. * Strutil::strip() strips whitespace (or other specified character sets) from the beginning or ending of strings. * Change threads.h to set USE_TBB=0 if undefined as a compiler flag; this makes it easier to use threads.h in other applications without worrying about TBB at all. * Windows utf8 filename utilities path_to_windows_native and path_from_windows_native. Release 1.0.10 (5 Nov 2012) --------------------------- * ImageCache: more graceful handling of the inability to free handles or tiles under extreme conditions. Rather than assert when we can't free enough to stay within limits, just issue an error and allow the limits to be exceeded (hopefully only by a little, and temporarily). * ImageCache: Detailed per-file stats now track the number of tile reads per MIPmap level. * ImageCache attribute "unassociatedalpha" (when nonzero) requests that IC images not convert unassociated alpha image to associated alpha. * maketx option --ignore-unassoc leaves unassociated alpha data as it is (no auto-conversion to associated alpha) and/or ignores the tags for an input file that is associated but incorrectly tagged as unassociated alpha. * oiiotool & info: the --hash command had a bug wherein when applied to images there were MIP-mapped, would hash the lowest-res MIP level rather than the highest-res. This could result in two different images, if they happened to have the same average color, to incorrectly report the same SHA-1 hash. Note that this did NOT affect non-MIPmapped images, nor did it affect the SHA-1 hashing that occurred in maketx to allow the TextureSystem to detect duplicate textures. Release 1.0.9 (4 Sep 2012) ---------------------------- * Improve error messages when trying to open an OpenEXR image that doesn't exist or is not a valid OpenEXR file. * Make the TextureSystem work properly with MIPmapped images whose tile size is not a power of 2 (mostly back-ported from master, but with additional fixes). Release 1.0.8 (17 July 2012) ---------------------------- * Fix quantization/truncation bug that sometimes left tiny alpha holes in 8 bit images (making some alpha value that should be 255, instead 254). * TextureSystem: fix fill_channels for monochrome+alpha images to properly expand to "RRRA." Release 1.0.7 (8 July 2012) --------------------------- * Bug fix when reading vector Field3D files. * Fix input of tiled images with per-channel formats. * Add testsuite/nonwhole-tiles and testsuite/perchannel. * Bug fix when reading binary PNM files. Release 1.0.6 (12 Jun 2012) --------------------------- * Fix allocation and stride bugs in that could overrun a buffer when reading tiled images whose resolution was not a whole number of tiles. * Fix stride bugs when reading scanline images with differing data types per channel. * Fixes for FreeBSD compilation. Release 1.0.5 (3 Jun 2012) -------------------------- * Various fixes for FreeBSD/kFreeBSD systems. * Various fixes to compile with Clang 3.1 without warnings. * Fixed some DPX and Cineon bugs related to channel names. * Fixed some mangled text in the PDF documentation. * Developer goodie: TypeDesc::equivalent() tests two TypeDesc's for equality, but allows 'triples' with differing vector semantics to match. Release 1.0.4 (2 May 2012) -------------------------- * DPX fixes for 12 bit DPX and packing methods. * Cineon fixes: remove buggy 32 and 64 bit output, which wasn't needed; fix for 10 bit -> 16 bit promotion. * bmp fix: wasn't setting oiio:BitsPerSample correctly. * oiiotool fixes: improved argument help and add man page generation; print data format info correctly for non-byte bit depths; better inference of output tile size and data format from the inputs (when not explicitly requested); --resize n% was broken; print data format info correctly for non-byte bit depths. * iinfo fixes: make --stats print correctly; print data format info correctly for non-byte bit depths. * Fix roundoff error when converting from float buffers to int image files. * More precise filter normalization in ImageBufAlgo::resize (and therefore oiiotool --resize). Release 1.0.3 (16 Apr 2012) --------------------------- * Fix reading bugs in DPX and Cineon. * iconvert handles the int32 and uint32 cases. * Bug fix in to_native_rectangle, which could lead to errors in certain data format conversions. * Various Windows build fixes, including fixes for Windows 7. * Compilation fixes on FreeBSD. Release 1.0.2 (19 Mar 2012) ---------------------------- * Fixed TARGA reader bug where for 16-bpp, 4-channel images, we weren't reading the alpha properly. * Fix ill-formed default output names for maketx (and in the process, add Filesystem::replace_extension utility). * Threading performance improvement in the texture system as a result of wrapping various internal "iequals" calls to pass a static locale rather than relying on their default behavior that would use a mutex underneath to access a global locale. Release 1.0.1 (13 Mar 2012, compared to 1.0.0) ---------------------------------------------- Fixes, minor enhancements, and performance improvements: * Improvements in anisotropic texture filtering quality. * oiiotool --hash prints the SHA-1 hash of each input image. * oiiotool: properly print error message and exit when an input file cannot be opened. * Changed the default behavior of idiff and "oiiotool --diff" to print the pixel difference report only for failures (not for successful matches), unless in verbose (-v) mode. Developer goodies: * dassert.h: New ASSERTMSG and DASSERTMSG allow even more flexible assertion messages with full printf argument generality. * Windows compilation fixes. * Major testsuite overhaul: All tests are copied and run in the build/ARCH/testsuite directory, no longer leaving any clutter in the "source" testsuite area. The testing scripts have been cleaned up and greatly simplified. An individual test can be run using "make test TEST=name" (also works with regular expressions). The usual "make test" will exclude tests that are expected to be broken (such as tests for portions of the system that were not built because their required libraries were not found), but "make testall" will run all tests including nominally "broken" ones. Release 1.0 (25 Feb 2012, compared to 0.10.5) --------------------------------------------- Major new features and improvements: * New ImageInput & ImageOutput methods that can efficiently read/write multiple scanlines or tiles at a time. * New ImageInput methods that can read a subset of channels from an image. * WebP format reader/writer. * PSD (Adobe Photoshop) format reader. * RLA (Wavefront) format reader/writer. * Cineon support is re-enabled after various bug fixes. * New utility: oiiotool. This is still a work in progress, but largely subsumes the functionality of iprocess, iinfo, iconvert, idiff. * Use OpenColorIO (www.opencolorio.org) for color space conversion, if detected at build time and a valid OCIO configuration is found at runtime. Color conversion commands have been added to oiiotool and maketx. API changes: * New ImageInput & ImageOutput methods that can efficiently read/write multiple scanlines or tiles at a time: read_scanlines, read_tiles, write_scanlines, write_tiles. * New ImageInput methods that can read a subset of channels from an image. * Change the last couple functions that took min/max pixel range specifications to conform to our usual [begin,end) convention -- write_rectangle and to_native_rectangle. * exif_encode, exif_decode now available as general utilities (previously were private to the JPEG plugin). * New ImageOutput::supports() queries: "displaywindow" queries whether the file format is able to handle differing display ("full") and pixel data windows, "negativeorigin" queries whether data origin or full/display origin may be negative. * TextureSystem and ImageCache now accept attribute "options", that is a comma-separated list of name=value setings (e.g. "max_memory_MB=256,max_files=1000"). Also, upon startup, the environment variables OPENIMAGEIO_TEXTURE_OPTIONS and OPENIMAGEIO_IMAGECACHE_OPTIONS are parsed for these startup values. * TextureSystem/ImageCache: add a separate "plugin_searchpath" attribute separate from the "searchpath" for images. Fixes, minor enhancements, and performance improvements: * ImageBufAlgo new algorithms: compare, compare_Yee, isConstantChannel, fixNonFinite. * TextureOpt: add ustring-aware versions of the decode_wrapmode utility. * TypeDesc: allow stream << output. * iv: raised maximum ImageCache size from 2 GB to 8 GB. * PNM: fix bug where file exceptions could go uncaught. * Properly create coefficients for Kodak color transform. * iprocess: Fix bug calling read. * maketx new options: --opaque-detect omits alpha from texture whose input images had alpha=1 everywhere; --mipimage option allows custom MIP levels to be assembled; --fixnan repairs NaN & Inf values in the inputs. * Fixed bugs in sinc and Blackman-Harris filters. * ImageCache/TextureSystem -- new reset_stats() method resets all the statistics back to zero. * TIFF: better handling of unexpected bitsperpixel combinations; support the nonstandard use of IEEEFP/16bit as "half"; fix many small bugs related to unusual depth depths and contig/separate conversions. * JPEG-2000 plugin rewritten to use OpenJpeg library instead of Jasper. * DPX: various bug fixes. * RLA plugin overhauled and now has good support for non-8-bit depths. * oiiotool improvements: --pop, --dup, --selectmip, --origin, --incolorspace, --tocolorspace, --colorconvert. * TextureSystem supports textures with "overscan" (including proper maketx support for input images with overscan). * TS/IC invalidate_all previously cleared all fingerprint info, but now only clears fingerprints for individual files that are invalidated (this makes for better duplicate detection). Build system improvements: * Support compilation on FreeBSD. * Improved custom detection of boost-python on Windows. * Easier to compile OIIO without using TBB. Developer goodies: * ArgParse enhancements: make %! indicate a bool that's set to false if the option is found, %@ indicates an immediate callback, allow callbacks for bool options, option matching ignores characters after ':' in the option, wrap lines at word breaks when printing usage help. * Generate man pages for the command-line tools. * Strutil additions: escape_chars, unescape_chars, word_wrap. * Filesystem additions: filename(), extension(). * Sysutil additions: terminal_columns() * Use github.com/OpenImageIO/oiio-images project for test images that are too big to fit in testsuite. * Fixed bugs in Timer::lap(). * Aded 'invert' algorithm to fmath.h. * Clarify Timer docs and fix Apple-specific bug. * testtex improvements: --wrap Release 0.10.5 (20 Feb 2012) ---------------------------- * Improvements to anisotropic texture filtering: (1) fix for degenerate derivatives that could corrupt the filter footpring calculations, resulting in an infinitely long major axis; (2) more efficient subpixel filtering for very narrow anisotropic footprints when on the highest-res MIP level. Release 0.10.4 (November 20, 2011) ---------------------------------- * Important texture bug fix: Improve robustness of texture lookups with very small derivatives. The previous bug/misunderstanding had the result of some filter footprints with very small (but valid) derivatives inappropriately using the highest-resolution MIPmap level and maximum anisotropy, resulting in terrible performance, alising, and in some cases visible seams on the boundary between where this happened and where it didn't. Be aware that the fixed code will make some areas of texture look less sharp, but that's only because it was aliasing before and using a totally incorrect MIPmap level. Release 0.10.3 (November 5, 2011) --------------------------------- * New ImageCache/TextureSystem option: "autoscanline", which, when autotile is turned on, causes the virtual tiles to be the full width of the image scanlines, rather than square. This improves performance for some apps. * Bug fix: PNG files with both associated alpha and gamma correction lost precision when converting. * Bug fix: ICO and Targa did not properly force requested (but unsupported) UINT16 output to be UINT8. * maketx (and Filter classes): fixes to sinc, blackman-harris filters. * Minor Python binding bug fixes. * Allow stream << of TypeDesc. * Fix minor Timer::lap() bug. Release 0.10.2 (August 6, 2011) ------------------------------- * Improve the performance of ustring constructor when highly multithread. * Remove old out-of-date Doxygen html pages. Release 0.10.1 (August 2, 2011) ------------------------------- * Fix TextureSystem::get_texture_info(file,"exists") (and the equivalent for ImageCache), it was previously incorrectly giving an error if the file didn't exist. * Fixed an error where we were losing the error message if ImageInput::create failed. * maketx: --hash is deprecated, the SHA-1 hash is always computed; the hash takes into account upstream image changes, such as resizing; the --filter command line argument only takes the filter name, the width is now automatically computed. * Add static methods to Filter classes allowing queries about the names and vital info about all available filters. * New Filesystem::is_regular() wraps the boost is_regular and catches exceptions. * iv: raise the maximum ImageCache settable in the UI from 2GB to 8GB. * Bug fixes with per-channel data formats. * Add Strutil::escape_chars() and unescape_chars() utility functions. * TextureOpt: add ustring-aware versions of the decode_wrapmode() utility. Release 0.10 (June 9 2010) -------------------------- Major new features and improvements: * TextureSystem: fix longstanding texture quality issues: underestimation of anisotropic filter footprint, improved metric for determining when to switch to bicubic filtering, better MIP level selection for non-square images. * maketx --filter allows you to specify the filter for resizing and downsizing to generate MIPmap levels (this lets you choose a filter that is better than the default "box"). * TextureSystem option "gray_to_rgb", when set to nonzero, promotes grayscale (single channel) texture lookups to RGB (rather than using the fill color for missing channel. * IFF (Maya) support from Mikael Sundell. API changes: * TextureSystem has additional API entry points for apps that want to retrieve an opaque texture handle and per-thread info and then pass it back to texture lookups, saving some name resolution and per-thread retrieval time. (The old routines that do this all automatically still work just fine.) * New ImageBufAlgo utilities: setNumChannels, isConstantColor, isMonochrome, computePixelHashSHA1, transform. Fixes, minor enhancements, and performance improvements: * ImageCache/TextuerSystem: - option "accept_untiled" wasn't properly recognized (0.9.1); new attribute "accept_unmipped" (default to 1), when set to zero, will treat any un-MIPmapped file as an error (analogous to the existing "accept_untiled") (0.9.2); - fix deadlock when file handles are exhausted (0.9.3); invalidate_all() no longer closes all files unconditionally, only the ones actually invalidated; - fix longstanding problem where multiple threads could redundantly open and read the same file if they need it simultaneously and it isn't in cache already; - get_pixels issues a single error from a corrupt file, rather than reporting error after error on the same file. * Texture: Fixes to make latlong environment maps more correct for OpenEXR files, which have some particular unique conventions. (0.9.1); bug fix to TextureOpt default initializer that could screw up texture lookups. (0.9.1) * maketx fixes: the -oiio command line option also enables hash generation; resize properly if any of the dimensions change (previously only did if ALL dimensions changed) (0.9.3); --nchannels lets you set the number of output channels. * Added ImageBufAlgo::transform to allow for 'flip' & 'flop' in iprocess. (0.9.1) * DPX: fix file reading when number of channels not equal to 3 (0.9.3); support for endianness specification, fix lots of problems writing metadata. * BMP: RGB-to-BGR conversion fixed, force UINT8 output; scanline size was incorrect when copying to temporary buffers. * JPEG: reader is more robust to corrupted files and other problems. * JPEG-2000: support files with more than 8 bits per channel. * Targa: properly expand 5 bit per channel to full bytes. * Fixed incorrectly set "ResolutionUnit" and "BitsPerSample" usage in several format plugins. * Improved handling of file formats that allow unassociated alpha. * iv: display non-Latin filenames properly. * iconvert --noclobber option ensures that existing files aren't overwritten. * iinfo: fixes to properly print subimage and mipmap statistics. For developers / build issues: * Fix USE_TBB macro on Windows build. (0.9.1) * Fixes required for Windows compile in conjunction with OSL. (0.9.1) * Removed some pointless debugging output to the console. (0.9.1) * Fix subtle bug in convert_type utility function that was causing a slight incorrect rounding when converting float to a signed integer type. (0.9.3) * Fix to compile properly against Boost 1.46. (0.9.3) * Update pugixml from 0.5 to 1.0. * Remove boost::test and gtest as dependencies, use our own macros. * Fixes to allow use of libtiff 4.0. * make USE_JASPER=0 USE_FIELD3D=0 make it easy to disable Jasper and Field3D as dependencies. * Various fixes to make cleaner compiles with clang. * ustring: Added find* methods that match those of std::string, expose make_unique, is_unique, and from_unique helper functions. * Add Filesystem::exists and Filesystem::is_directory. Release 0.9 (Dec 9 2010, updated Feb 23, 2011) ---------------------------------------------- Major new features: * New format plugin: DPX * New format plugin: Cineon (currently read only) (r1599,1600,1601,1617) * New format plugin: Ptex (currently read only) (r1655,1664). * New format plugin: Field3D (currently read only) (r1659,1666,1669) * Support for files that are simultaneously multi-image and where each subimage may also be mipmapped (these concepts were previously comingled). This mainly effects ImageInput::seek_subimage and ImageOutput::open, as well as some minor methods of ImageCache and ImageBuf. (r1655,1656,1664,1671) * Support for per-channel data formats via the new ImageSpec::channelformats vector and interpreting read_foo/write_foo format parameter of UKNOWN as a request for the true native format. (r1674) * Full support of TextureSystem environment() for lat-long maps. API changes: * Single-point texture lookup struct (TextureOpt) and additional single-point texture lookup entry points. (r1679) * Filter{1D,2D} class now has a destroy() method to match its create(), and create() accepts "bspline" and "catrom" as synonyms for the existing "b-spline" and "catmull-rom" fileters. (r1542) * Add methods to ImageSpec to read/write an XML representation of the ImageSpec (r1574). * Finally put all the helper classes (ustring, TypeDesc, etc.) that were in the main OpenImageIO namespace, as well as centralized version numbering and custom namespace control. * ParamList now has a method to remove attributes. * Color handling change: color space now is a metadata string, "oiio:ColorSpace", not 'linearity' data member of ImageSpec; remnants of bad 'dither' ideas have been removed; "BitsPerSample" metadata has been renamed "oiio:BitsPerSample" and several bugs have been fixed related to it in some of the image plugins. * Moved some ImageBuf methods into functions in imagebufalgo.h. Fixes, minor enhancements, and performance improvements: * OpenEXR: Allow read/write with different data formats per channel (r1674). * SGI: add support for files with any number of channels (r1630). * PNG: improve PNG write speed by 4x by adjusting compression tradeoffs (r1677) * JPEG: assume sRGB unless EXIF says otherwise (r1693); fix broken JPEG 4-channel to 3-channel conversion (r1696). * PNM: monochrome data was output incorrectly in both binary & ascii forms; adopt the Netbpm convention for endianness in the 16 bit case; open binary image files in binary mode to avoid newline mangling (r1709). * TIFF: more sensible checkpointing logic greatly reduces header rewriting. * iinfo: add --stats option (r1618) * iv: Now can sort the image list by file date, metadata date, name, or file path (r1514). * ImageCache: fixed bug that allowed the max_open_files limit to be exceeded (r1657); raise the default IC cache size to 256 MB (r1663); automip unmipped files even if they are tiled (r1670); fix bug wherein an invalidated and modified file would continue to flush in subsequent invalidations, even if the file was not modified again (r1712/0.8.8). * New ImageBuf algorithm: computePixelStats (r1618) * Fixes in ImageCache and ImageBuf to allow correct handling of 3D (volumetric) files. (r1659,1660) * ImageCache fixed to ensure that multiple threads don't try to concurrently open the same file. * Properly append error messages; ASSERT if the error message buffer exceeds 16 MB (which means somebody is failing to call geterror) (1672) * Fix subtle Strutil::format and ustring::format crasher bugs with long strings (r1654 - 0.8.8). * Print the OIIO version in the ImageCache stats so we don't guess when somebody sends us a log file with complaints. * ImageCache::getattribute can retrieve its interesting internal statistics individually by name. (r1721) * idiff and iv increased their IC cache size. (r1722) * idiff bug fixes: (1) files with different number of MIPmap levels immediately failed, whereas they should have compared their top levels, and only fail if the "-a" flag was used; (2) some failure modes incorrectly printed a "PASS" message despite actually failing. (r1722) * Changed the environment variable that contains the plugin search path from IMAGEIO_LIBRARY_PATH to OPENIMAGEIO_LIBRARY_PATH. (r1723) * Bug fix to ImageInput::read_image -- could crash due to an internal buffer allocated as the wrong size. (r1724) * Bug fixes to write_image(), related to subtle stride errors. * Improved strhash, fewer ustring hash collisions. * New maketx functionality: --constant-color-detect, --monochrome-detect, --prman, --oiio (look in docs for explanation). For developers / build issues: * testtex: print memory use (r1522) * Embedded plugins are now built within the OIIO namespace, if defined (r1559). * Fixed implementation of TypeDesc construction from a string. (r1562) * Incorporate PugiXML for XML parsing/writing needs (r1569). * In-progress socket I/O plugin is in the code base, but not yet fully supported. * Disable python support if boost_python is not found. (r1701) Release 0.8 (May 26 2010) ------------------------- Major new features: * Python bindings for the ImageInput, ImageOutput, ImageSpec, ImageBuf, and ImageCache classes. * New format plugin: SGI image file * New format plugin: PNM/PPM/PGM/PBM * New format plugin: DDS (currently reading only) * New format plugin: Softimage PIC (currently reading only) API changes: * New "linearity" tags include AdobeRGB, Rec709, and KodakLog. * ColorTransfer helper class can convert among the linearity types, and may be optionally passed to convert_image and convert_types. * Added to fmath.h: sincos, exp2f, log2f * Renamed ErrHandler::ErrCode enums with EH_ prefix (to fix conflicts with some Windows headers). * ustring now has getstats() and memory() methods. Fixes, minor enhancements, and performance improvements: * ImageInput::create() error messages are more helpful. * Fixed some error messages in FITS output, iconvert. * maketx: Console flushes in status messages to that a calling process will get status messages right away. * Fix subtle ImageCache bug with invalidate(). * ImageCache/TextureSystem have improved multithreading performance when large untiled files are needed simultaneously by many threads. * TextureSystem: new 'missingcolor' texture option that, when provided, can specify a color that will be used for missing textures rather than generating errors. (If not supplied, missing tex is still an error.) * BMP plugin enhancements. * TIFF: support 64-bit float pixels, proper random scanline access emulation for all appropriate compression types, handle incorrectly set-to-zero image_full_width and image_full_height. (r1515 - 0.8.1) * PNG: properly handle palette images, unassociated alpha, gamma correction, endianness for 16-bit files, and has vastly better memory consumption due to reading scanlines individually rather than buffering the whole image (r1523 - 0.8.1); fix clamping/wrapping problem for certain values when alpha > color. (r1605 - 0.8.3) * iv fixes: fix improper recentering after image reload; fix crash when image info window opened without any image files loaded; better status window message when image reads fail; iv goes into background properly in Windows; "slide show" mode; pixel view display moves if you need to look at pixels underneath it; * ImageCache bug: previously couldn't designate a cache > 2GB (because of integer overflow issues). * ImageCache::get_image_info and TextureSystem::get_texture_info now respond to a new "exists" query that merely tests for existance of the file. (0.8.1) * ImageCache/TextureSystem fix for a threading logic bug that could potentially lead to a deadlock (and definitely led to hitting a DASSERT when compiled for DEBUG mode). (0.8.1) * maketx performance improvements: --noresize is now the default (use --resize if you really want power-of-two resizing); much better performance because it doesn't use ImageCache unless the image being converted is very large; takes advantage of multiple cores by automatically multithreading (the number of threads can be controlled by the "-t" option, with the default to use the same number of threads as hardware cores). (r1546 - 0.8.2) * Fix potential crash in read_tile for files with tiles so big that they would not fit on the stack (heap allocation used instead). (0.8.2) * OpenEXR: add support for vector metadata attributes. (r1554 - 0.8.2) * Improve TIFF open error messages. (r1570 - 0.8.3) * Make ImageCache::get_pixels() and TextureSystem::get_texels() safe for crop windows -- fill with zero outside the valid pixel data area. (r1579 - 0.8.3) * In ImageCache::attribute (and by extension, TS::attribute), only invalidate the cache if the attributes actually CHANGED. (r1582 - 0.8.3) * maketx: --checknan option double checks that no source image pixels are NaN or Inf (r1584 - 0.8.3). * Fixed crash that could result from certain XML strings embedded in TIFF headers (uncaught exception). (0.8.5) * Fixed ImageCache deadlock when using autotile. (r1631 - 0.8.6) * Fixed a longstanding performance issue with ImageCache automip, wherein an unmipped file that is larger than the cache size leads to pathological thrashing. The solution is to automatically raise the cache size to be large enough to automip the file without danger of thrashing. (r1657 - 0.8.7) For developers / build issues: * EMBEDPLUGINS=1 is now the default. This means that all the format plugins that come with OIIO are compiled into the main library, so there's no reason for users to set $IMAGEIO_LIBRARY_PATH unless they need custom format plugins not supplied with the main distribution. * Fix compiler warnings (mostly under Windows): TBB stuff, ustring, windows.h. * Option to build static libraries (with 'make LINKSTATIC=1'). * Fixes to make clean compilation with gcc-4.4.2. * Allow custom 'platform' designation in the build. * Allow custom installation destination ('make INSTALLDIR=...'). * ustring now takes half the memory (by no longer redundantly storing the characters on Linux and OS X). * Always use TBB (better performance on Windows for atomics). [0.8.2] Release 0.7 (Nov 26 2009) -------------------------- Major new features: * New format plugin: JPEG-2000 (r1050) * New format plugin: FITS (r1287 et al) * TextureSystem: two new entries to TextureOptions which allow the texture system to return the derivatives in s and t of the texture. (r1308) API changes: * Added imagespec() method to ImageCache and TextureSystem that returns a reference to the internal ImageSpec of the image. This is much more efficient than get_imagespec, but beware, the pointer is only valid until somebody calls invalidate() on the file. (r1266) * TextureOptions: eliminated the 'alpha' field. Added the dresultds and dresultdt fields. * Extend TypeDesc to include INT64 and UINT64. (r1145) Fixes, minor enhancements, and performance improvements: * Make EMBEDPLUGINS=1 the default. (0.7.1) * Improvements to the Targa plugin, bringing it into compliance with TGA 2.0 (r1163, r1297) * Fixed PNG-related crashes on 64 bit machines. (r1336) * iv improvements: support for multichannel images and different color modes (r1129), support auto use mipmap level based on zooming (r1093), correct pixelview for rotated images (r1092), fix off-by-one error with some zoom levels (r1089). * maketx: fixed problem where it was sometimes not setting the output data format to match the input data format correctly (r1290), fixed problems with writing EXR files with --nomipmap (r1286), fixed cases where data window was not the same as display window (i.e. crop or overscan). * ImageCache/TextureSystem: various threading and performance improvements. (r1188, r1211, r1288, r1299) * TS: fixed incorrect "texturetype" results of get_texture_info. (r1314) * IC/TS: fixed crasher bugs when doing get_pixels of images that had non-zero data window origin. (r1313) * IC/TS: better error messages and recovery from spooky open and read_tile failures. (r1321) * When IC/TS reads and entire (untiled) image, the file is closed afterwards. This is especially helpful on Windows where open files are locked to writing by other processes. (r1298) * HUGE speedup of ImageCache::get_image_info (and TS::get_texture_info) b replacing strcmp's with ustring == (r1281). * IC: fixed various subtle logic errors with broken files and invalidate/invalidate_all. (r1252, r1279) * IC/TS: fixed memory leak of per-thread imagecache data and subtle race conditions. (r1057, r1216, r1222, r1238) * TS: fixed problem where missing or broken textures weren't using the right fill color. (r1268) * IC: Clamp cache size to a reasonable lower limit (r1256) * TS: improvements to filter estimation (1134) and bicubic interpolation numerical stability and speed (r1166, r1179, r1333). * IC: when autotile=0 but automip=1, fixed bug that was wasting HUGE amounts of memory by using the wrong resolution for mip levels! (r1147) * IC: fix an edge case where tiles could leak. (r1044) * Fixed some hairy static initialization problems with ustring (r1280) * Use a spin lock rather than block in ustring constructor gives HUGE speedup especially on Windows. (r1167) * TS: Make everything work for textures whose image origin is not (0,0) or whose pixel data window doesn't match the image window (i.e. crop windows or overscan). (r1332) * IC/TS: Correctly invalidate files afected by recently changed "automip" setting. (r1337) * IC/TS: fix crash that could occur with non-existant textures in combination with invalidate_all(). (r1338) * Make create() error messages more helpful. (0.7.1) For developers: * Build more easily when older OpenEXR versions are found. (r1082) * HTML Doxygen documentation on the public APIs. (r1311, r1312, et al) * Sysutil::this_program_path finds the full path of the running program. (r1304) * Better compiler-side error checking of printf-like functions (r1302) * A new site/... area where important users with local build customization needs can check in (reasonably sized) custom makefiles or other helpful things. (r1284) * New ErrorHandler class, currently unused by OIIO itself, but very handy. (r1265) * Fixed lots of compiler warnings. * Upgraded to a more recent TBB, which fixed some atomic problems. (r1211) * ustring: make string comparison safe for empty strings. (r1330) * Include file fixes for gcc 4.4. (r1331) * Regularize all #include references to Imath and Openexr to . (r1335) Release 0.6 (Jul 20, 2009) -------------------------- Major new features: * Everything has been ported to Windows. * iv: handle older cards or versions of OpenGL, including lack of GLSL, non-pow2 textures, etc. Generally should now be usable (if slightly degraded functionality) for most OpenGL 1.x implementations. (r764) * ImageBuf that only reads images is now automatically backed by ImageCache. In the process, add Iterator and ConstIterator as "safe" and efficient ways to visit all the pixels within a region of the image, and eliminate the unsafe pixeladdr() method. Also added ImageCache::attribute("forcefloat") to conveniently force all ImageCache internal storage to be float. (r770,771,772,775,803,805) * iv can now support "big" images, in particular larger than the OpenGL texture limit (4k), and also very big images via the use of ImageCache (r912). * Truevision Targa (TGA) support. (r776,792) API changes: * In a variety of places that specified pixel rectangles (including ImageCache::get_pixels and TextureSystem::get_texels), specify regions as (xbegin,xend,ybegin,yend) rather than (xmin, ymin, xmax, ymax). Note that 'end' is, like STL, one past the last pixel. (r771) * All classes now query error messages using geterror(). Previously some used geterror() and others used error_message(). The old error_message is deprecated and will be removed in a future release (r957). Fixes and minor enhancements: * OpenEXR plugin improvements: don't set "textureformat" attribute unless it really is a mip-mapped texture. Preserve the mipmap rounding mode when copying OpenEXR files, by using the "openexr:roundingmode" metadata (r801). Properly mark the alpha and z channels in the ImageSpec (r885). * TIFF plugin improvements: handle 2 bpp images, properly name channels when reading palette images (r802), no longer uses the PREDICTOR_FLOATINGPOINT, since older versions of libtiff can't read those files (r752). Properly set the Exif sRGB marker (r888). * BMP plugin improvements: allows top-down scanlines as well as bottom-up, correctly reads 4-, 8- and 24-bit images that have scanlines padded to 4-byte boundaries. * ImageBuf algorithms: crop, add (r892). * EXPERIMENTAL: 'iprocess' utility that lets you do some simple image processing operations (r892). * ImageCache additional statistics: file open time (r743), alert if mip-mapped images are accessed at only their highest-res level (r743). Properly emulates random access reads of LZW-compressed files (r920). * iv: fix problems displaying images whose width was not a multiple of 4 bytes (r767), when loading small images, the window starts out a usable minimum size, iv always raises the window upon first opening, fix pixelview of alpha in RGB images (r939). * iv: Fix off-by-one error that drew the last scanline incorrectly sometimes (r1089). Give feedback when doing a slow repaint (r1089). * iv improvements: fix skew-like problems with Intel cards, fix non-GLSL texture mapping, limit texture size to 4096^2 to keep GL memory use reasonable make "Reload" work again after breaking a few patches ago (r1090). * maketx: in the case where the input texture was already float and needed no pow2 rounding, we didn't get the tiling or other metadata right (r824) * ImageCache and TextureSystem do a better job of reporting low-level ImageInput errors up the chain (r945). * ImageCache: new option "accept_untiled", when set to zero, will reject untiled images (r979). * 'maketx --hash' embeds a SHA-1 fingerprint of the source image's pixels in the texture file header's "ImageDescription" field. ImageCache (and TextureSystem) will recognize these and eliminate redundant I/O when it finds multiple files with identical pixels. (r741,742) * iinfo: eliminate --md5 in favor of --hash (computing SHA-1). (r749) * Fix ImageCache and TextureSystem to have thread-specific error reporting. (r1045) * TextureSystem: fixed subtle bug in destruction order that could double-free per-thread data. (r1057) * ImageCache: now get_image_info("format") returns teh native data format of the file. (r1058) * maketx: properly handle input files where the data window is not the same as the display window or if the image offset was nonzero. The correct semantics are that the DISPLAY window is what maps to [0,1] in texture space. (r1059) For developers: * Lots of fixes for Windows compilation (r754, r860) * A build option for whether or not to use TBB for atomics. (r780) * New test suite entries: tiff-suite, tiff-depths (r787,788), openexr-suite, openexr-multires, openexr-chroma (r789,790,791). * New unit tests for ImageBuf::zero, ImageBuf::fill, ImageBufAlgo::crop (r891). * Reorganization of unit tests. * Improvements to ArgParse internals and interface. * All the macros that prevent double-inclusion of header files have had their names changed from FILENAME_H to OPENIMAGEIO_FILENAME_H so that they don't conflict with other package (r967). * Reorganized test suite hierarchy. * Optionally allow the entire library to be enclosed in a versioned namespace (via 'make NAMESPACE=foo') . * Upgraded to a more recent version of TBB that seems to have fixed some bugs with atomic counters. (r1027) Release 0.5 (31 May 2009) ------------------------- Features: * New image format plugins: zfile (r529), ICO (r579,585,588,619,637), BMP (reads only) (r580,584,614,625) * Support for multiple subimages in iinfo (r607), iconvert, idiff (r631), * ImageCache and TextureSystem: better stats (r528, r717), bug fixes for large untiled images (r558,561), anisotropic improvements, stats improvements, thread safety improvements (r566), invalidate/invalidate_all (r591), better error reporting (r606), thread safety fixes (r650), fix problem when filter size was precisely at a mipmap level it blurred to higher level (r687), avoid problems when blur > 1 and there is no 1x1 mip level (r687). * maketx: --shadow (r530), --nomipmap (r531), big speedups (r699). * idiff: add RMS error and PSNR (r622). * OpenEXR plugin: support "openexr:lineOrder" attribute so random-tile-order files may be written (r569). * API: better handling of huge images that could have sizes > 32 bits (r575) Fixes and minor enhancements: * iinfo: fix - lack of help message when no files specified (r513). * maketx: make -u work properly (r517), wasn't honoring --separate (r532). * iconvert: add --separate and --contig (r535). * TIFF plugin: work around error in old versions of libtiff for IPTC packets (r674). * JPEG plugin: if linearity is sRGB, set Exif:ColorSpace correctly (r536) * iv: more robust to certain OpenGL versions (r550), support for OpenGL versions that don't support non-pow2 textures (r563), correct texture mapping when GL_NV_texture_rectangle is the best texture mapping extension we can find (r572). * idiff: refactored to use ImageBuf internally (r541) For developers: * Switch to CMake for builds. * Build enhancements: 'make USE_OPENGL=0' (r512), better handling of certain system OpenGL headers (r512), more robust with Qt location (r542), handle older Boost 1.35 (r574). * Tests: test_libOpenImageIO (r581), ico (r621), * More work towards clean windows compilation (r659,672). Release 0.4 (15 Mar 2009 - not formally released) ------------------------------------------------- (compared to the 'initial' developer release of 1 Sep 2008) Features: * Lots of work on docs. * API changes: - Replaced ParamBaseType/ParamType with TypeDesc. - ImageSpec: add full_{x,y,z} fields. - Changed ImageInput/ImageOutput create(), open(), and suports() to take std::string instead of char* (r297) - Added ImageOutput::copy_image (r428) - TypeDesc - distinguish COLOR from NOXFORM. (r466) - ImageInput:open(name,newspec,config). (r482) * igrep utility searches metadata of images (r447,455,499) * iconvert: add --caption, --keyword, --clear-keywords, --adjust-time --attrib, --inplace (r484,488,491), --compression (r354), --quality (r362). * iv: put into background after launch unless -F arg (r240), alt-leftmouse zooms, handle sRGB correctly, GAMMA env variable, full HDR for half and float (r243), honor full/display window versus data window (r300), better view re-centering behavior (r355), fix orientation bugs (r363,380,381). * TextureSystem: single point texture lookups (r247), have all routines return a bool giving error status, rename gettextureinfo -> get_texture_info, add get_imagespec, get_texels, geterror (r252,265), replace hard-coded get/set routines with generic attribute/getattribute (r321), accept non-tiled and non-mipped textures (r317,319,388,389,390), separate the image cache into a separate ImageCache class that may be used independently of TextureSystem (r326,327,393), better statistics including per-file stats (r333,360,375,429), invalidate method (r460). * TIFF plugin: read/write EXIF, IPTC IIM, and IPTC XPM/XML data (r406,407,456,458) * JPEG plugin: read/write IPTC IIM, XMP, and GPS metadata (r408,411,458,461), implement ImageOutput::copy_data() can copy images without altering pixel values (r483). Fixes and minor enhancements: * ImageBuf: add option to read() that allows data format conversion (r244), add oriented{x,y} and oriented_full_{width,height} methods (r296). * TextureSystem: fix bicubic filetering (r309), big memory savings by not having libtiff use memory mapping (r332), lots of performance tuning (r351), anisotropic texture improvements (r364), bug fixes for search paths (r459). * iinfo: print color space and file format info (r241), better printing of matrix metadata (r365), new options -f, -m (r501). * idiff: bug fix - not producing difference image (r402) * maketx: deduce default file format from extension (r275). * All format plugins: better error detection in open() for senseless resolutions (r294,295) * OpenEXR plugin: handle float as well as half data, fixes when image origin is not (0,0) (r291), fix leak of exr writer (r292), conform to common conventions for camera matrix naming (r367), regularize capitalization of metadata (r412) * TIFF plugin: bug fix for combination of tile + separate (r304), fixes to retrieval of matrix tags (r366) * HDR plugin: emulate random access of scanlines (r387), better error reporting (r451). * JPEG plugin: respect "CompressionQuality" (r361), emulate random access of scanlines (r387), properly read & write JPEG_COM marker for comments (r403), assume sRGB unless the metadata say otherwise (r414). For developers: * Preliminary work on Windows port (r398,399) * Include all the needed .h files in the dist area (r251) * Handle older gcc (r273), older boost (r301,431), older OpenEXR (r301), older libtiff (r432). * 'make EMBEDPLUGINS=1' compiles the bundled plugins right into main library (r302). * Put header files in dist/ARCH/include/OpenImageIO (r303), rename src/libimageio -> src/libOpenImageIO (r382). Initial developer release 0.1 (9/1/08): --------------------------------------- * ImageInput, ImageOutput, TextureSystem APIs pretty mature * Plugins: TIFF, JPEG/JFIF, OpenEXR, PNG, HDR/rgbe * iv - basic display, multiple images, menus, status bar, info window, basic prefs window, pixel view tool, zoom, pan, open, open recent, close, save as, view subimages, view channels, gamma, exposure, fit window to image, fit image to window, full screen. * iconvert * idiff * maketx * API docs for ImageInput, ImageOutput, writing plugins * Linux and OSX openimageio-1.3.12~dfsg0.orig/src/0000755000175000017500000000000012271062644015110 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/pnm.imageio/0000755000175000017500000000000012271062644017313 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/pnm.imageio/pnmoutput.cpp0000644000175000017500000001705612271062644022103 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include "filesystem.h" #include "imageio.h" OIIO_PLUGIN_NAMESPACE_BEGIN class PNMOutput : public ImageOutput { public: virtual ~PNMOutput (); virtual const char * format_name (void) const { return "pnm"; } virtual bool supports (const std::string &feature) const { // Support nothing nonstandard return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: std::string m_filename; ///< Stash the filename std::ofstream m_file; unsigned int m_max_val, m_pnm_type; std::vector m_scratch; }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *pnm_output_imageio_create () { return new PNMOutput; } OIIO_EXPORT const char * pnm_output_extensions[] = { "ppm","pgm","pbm","pnm", NULL }; OIIO_PLUGIN_EXPORTS_END inline void write_ascii_binary (std::ostream & file, const unsigned char * data, const stride_t stride, const ImageSpec & spec) { for (int x = 0; x < spec.width; x++) file << (data[x * stride] ? '1' : '0') << "\n"; } inline void write_raw_binary (std::ostream & file, const unsigned char * data, const stride_t stride, const ImageSpec & spec) { unsigned char val; for (int x = 0; x < spec.width;) { val=0; for (int bit=7; bit >= 0 && x < spec.width; x++, bit--) val += (data[x * stride] ? (1 << bit) : 0); file.write ((char*)&val, sizeof (char)); } } template inline void write_ascii (std::ostream &file, const T *data, const stride_t stride, const ImageSpec &spec, unsigned int max_val) { unsigned int pixel, val; for (int x = 0; x < spec.width; x++){ pixel = x * stride; for (int c = 0; c < spec.nchannels; c++) { val = data [pixel + c]; val = val * max_val / std::numeric_limits::max(); file << val << "\n"; } } } template inline void write_raw (std::ostream &file, const T *data, const stride_t stride, const ImageSpec &spec, unsigned int max_val) { unsigned char byte; unsigned int pixel, val; for (int x = 0; x < spec.width; x++) { pixel = x * stride; for (int c = 0; c < spec.nchannels; c++) { val = data[pixel + c]; val = val * max_val / std::numeric_limits::max(); if (sizeof(T) == 2) { // Writing a 16bit ppm file // I'll adopt the practice of Netpbm and write the MSB first byte = static_cast(val >> 8); file.write ((char*)&byte, 1); byte = static_cast(val & 0xff); file.write ((char*)&byte, 1); } else { // This must be an 8bit ppm file byte = static_cast(val); file.write ((char*)&byte, 1); } } } } PNMOutput::~PNMOutput () { close (); } bool PNMOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } close (); // Close any already-opened file m_spec = userspec; // Stash the spec m_spec.set_format (TypeDesc::UINT8); // Force 8 bit output int bits_per_sample = m_spec.get_int_attribute ("oiio:BitsPerSample", 8); if (bits_per_sample == 1) m_pnm_type = 4; else if (m_spec.nchannels == 1) m_pnm_type = 5; else m_pnm_type = 6; if (!m_spec.get_int_attribute ("pnm:binary", 1)) { m_pnm_type -= 3; Filesystem::open (m_file, name); } else Filesystem::open (m_file, name, std::ios::out|std::ios::binary); if (!m_file.is_open()) return false; m_max_val = (1 << bits_per_sample) - 1; // Write header m_file << "P" << m_pnm_type << std::endl; m_file << m_spec.width << " " << m_spec.height << std::endl; if (m_pnm_type != 1 && m_pnm_type != 4) // only non-monochrome m_file << m_max_val << std::endl; return m_file.good(); } bool PNMOutput::close () { if (m_file.is_open()) m_file.close(); return true; } bool PNMOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { if (!m_file.is_open()) return false; if (z) return false; m_spec.auto_stride (xstride, format, spec().nchannels); const void *origdata = data; data = to_native_scanline (format, data, xstride, m_scratch); if (data != origdata) // a conversion happened... xstride = spec().nchannels; switch (m_pnm_type){ case 1: write_ascii_binary (m_file, (unsigned char *) data, xstride, m_spec); break; case 2: case 3: if (m_max_val > std::numeric_limits::max()) write_ascii (m_file, (unsigned short *) data, xstride, m_spec, m_max_val); else write_ascii (m_file, (unsigned char *) data, xstride, m_spec, m_max_val); break; case 4: write_raw_binary (m_file, (unsigned char *) data, xstride, m_spec); break; case 5: case 6: if (m_max_val > std::numeric_limits::max()) write_raw (m_file, (unsigned short *) data, xstride, m_spec, m_max_val); else write_raw (m_file, (unsigned char *) data, xstride, m_spec, m_max_val); break; default: return false; } return m_file.good(); } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/pnm.imageio/pnminput.cpp0000644000175000017500000002400512271062644021672 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "export.h" #include "filesystem.h" #include "imageio.h" OIIO_PLUGIN_NAMESPACE_BEGIN class PNMInput : public ImageInput { public: PNMInput() { } virtual ~PNMInput() { close(); } virtual const char* format_name (void) const { return "pnm"; } virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (); virtual int current_subimage (void) const { return 0; } virtual bool read_native_scanline (int y, int z, void *data); private: std::ifstream m_file; std::string m_current_line; ///< Buffer the image pixels const char * m_pos; unsigned int m_pnm_type, m_max_val; bool read_file_scanline (void * data); bool read_file_header (); }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput* pnm_input_imageio_create () { return new PNMInput; } OIIO_EXPORT int pnm_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char* pnm_input_extensions[] = { "ppm","pgm","pbm","pnm", NULL }; OIIO_PLUGIN_EXPORTS_END inline bool nextLine (std::ifstream &file, std::string ¤t_line, const char * &pos) { if (!file.good()) return false; getline (file, current_line); if (file.fail()) return false; pos = current_line.c_str(); return true; } inline const char * nextToken (std::ifstream &file, std::string ¤t_line, const char * &pos) { while (1) { while (isspace (*pos)) pos++; if (*pos) break; else nextLine (file, current_line, pos); } return pos; } inline const char * skipComments (std::ifstream &file, std::string ¤t_line, const char * & pos, char comment = '#') { while (1) { nextToken (file, current_line, pos); if (*pos == comment) nextLine (file, current_line, pos); else break; } return pos; } inline bool nextVal (std::ifstream & file, std::string ¤t_line, const char * &pos, int &val, char comment = '#') { skipComments (file, current_line, pos, comment); if (!isdigit (*pos)) return false; val = strtol (pos,(char**) &pos, 10); return true; } template inline void invert (const T *read, T *write, imagesize_t nvals) { for (imagesize_t i=0; i < nvals; i++) write[i] = std::numeric_limits::max() - read[i]; } template inline bool ascii_to_raw (std::ifstream &file, std::string ¤t_line, const char * &pos, T *write, imagesize_t nvals, T max) { if (max) for (imagesize_t i=0; i < nvals; i++) { int tmp; if (!nextVal (file, current_line, pos, tmp)) return false; write[i] = std::min ((int)max, tmp) * std::numeric_limits::max() / max; } else for (imagesize_t i=0; i < nvals; i++) write[i] = std::numeric_limits::max(); return true; } template inline void raw_to_raw (const T *read, T *write, imagesize_t nvals, T max) { if (max) for (imagesize_t i=0; i < nvals; i++) { int tmp = read[i]; write[i] = std::min ((int)max, tmp) * std::numeric_limits::max() / max; } else for (imagesize_t i=0; i < nvals; i++) write[i] = std::numeric_limits::max(); } inline void unpack (const unsigned char * read, unsigned char * write, imagesize_t size) { imagesize_t w = 0, r = 0; unsigned char bit = 0x7, byte = 0; for (imagesize_t x = 0; x < size; x++) { if (bit == 0x7) byte = ~read[r++]; write[w++] = 0 - ((byte & (1 << bit)) >> bit);//assign expanded bit bit = (bit - 1) & 0x7; // limit bit to [0; 8[ } } template inline bool read_int (std::istream &in, T &dest, char comment='#') { T ret; char c; while (!in.eof()) { in >> ret; if (!in.good()){ in.clear(); in >> c; if (c == comment) in.ignore (std::numeric_limits::max(), '\n'); else return false; } else { dest = ret; return true; } } return false; } bool PNMInput::read_file_scanline (void * data) { try { std::vector buf; bool good = true; if (!m_file.is_open()) return false; int nsamples = m_spec.width * m_spec.nchannels; if (m_pnm_type >= 4 && m_pnm_type <= 6){ int numbytes; if (m_pnm_type == 4) numbytes = (m_spec.width + 7) / 8; else numbytes = m_spec.scanline_bytes(); buf.resize (numbytes); m_file.read ((char*)&buf[0], numbytes); if (!m_file.good()) return false; } switch (m_pnm_type) { //Ascii case 1: good &= ascii_to_raw (m_file, m_current_line, m_pos, (unsigned char *) data, nsamples, (unsigned char)m_max_val); invert ((unsigned char *)data, (unsigned char *)data, nsamples); break; case 2: case 3: if (m_max_val > std::numeric_limits::max()) good &= ascii_to_raw (m_file, m_current_line, m_pos, (unsigned short *) data, nsamples, (unsigned short)m_max_val); else good &= ascii_to_raw (m_file, m_current_line, m_pos, (unsigned char *) data, nsamples, (unsigned char)m_max_val); break; //Raw case 4: unpack (&buf[0], (unsigned char *)data, nsamples); break; case 5: case 6: if (m_max_val > std::numeric_limits::max()) raw_to_raw ((unsigned short *)&buf[0], (unsigned short *) data, nsamples, (unsigned short)m_max_val); else raw_to_raw ((unsigned char *)&buf[0], (unsigned char *) data, nsamples, (unsigned char)m_max_val); break; default: return false; } return good; } catch (const std::exception &e) { error ("PNM exception: %s", e.what()); return false; } } bool PNMInput::read_file_header () { try { unsigned int width, height; char c; if (!m_file.is_open()) return false; m_file >> c >> m_pnm_type; //MagicNumber if (c != 'P') return false; if (!(m_pnm_type >= 1 && m_pnm_type <= 6)) return false; //Size if (!read_int (m_file, width)) return false; if (!read_int (m_file, height)) return false; //Max Val if (m_pnm_type != 1 && m_pnm_type != 4) { if (!read_int (m_file, m_max_val)) return false; } else m_max_val = 1; //Space before content if (!(isspace (m_file.get()) && m_file.good())) return false; if (m_pnm_type == 3 || m_pnm_type == 6) m_spec = ImageSpec (width, height, 3, (m_max_val > 255) ? TypeDesc::UINT16 : TypeDesc::UINT8); else m_spec = ImageSpec (width, height, 1, (m_max_val > 255) ? TypeDesc::UINT16 : TypeDesc::UINT8); if (m_spec.nchannels == 1) m_spec.channelnames[0] = "I"; else m_spec.default_channel_names(); if (m_pnm_type >= 1 && m_pnm_type <= 3) m_spec.attribute ("pnm:binary", 0); else m_spec.attribute ("pnm:binary", 1); m_spec.attribute ("oiio:BitsPerSample", ceilf (logf (m_max_val + 1)/logf (2))); return true; } catch (const std::exception &e) { error ("PNM exception: %s", e.what()); return false; } } bool PNMInput::open (const std::string &name, ImageSpec &newspec) { close(); //close previously opened file Filesystem::open (m_file, name, std::ios::in|std::ios::binary); m_current_line = ""; m_pos = m_current_line.c_str(); if (!read_file_header()) return false; newspec = m_spec; return true; } bool PNMInput::close () { if (m_file.is_open()) m_file.close(); return true; } bool PNMInput::read_native_scanline (int y, int z, void *data) { if (z) return false; if (!read_file_scanline (data)) return false; return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/pnm.imageio/CMakeLists.txt0000644000175000017500000000005512271062644022053 0ustar mfvmfvadd_oiio_plugin (pnminput.cpp pnmoutput.cpp) openimageio-1.3.12~dfsg0.orig/src/doc/0000755000175000017500000000000012272140545015653 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/doc/stdmetadata.tex0000644000175000017500000006536412271062644020710 0ustar mfvmfv\chapter{Metadata conventions} \label{chap:stdmetadata} The \ImageSpec class, described thoroughly in Section~\ref{sec:ImageSpec}, provides the basic description of an image that are essential across all formats --- resolution, number of channels, pixel data format, etc. Individual images may have additional data, stored as name/value pairs in the {\cf extra_attribs} field. Though literally \emph{anything} can be stored in {\cf extra_attribs} --- it's specifically designed for format- and user-extensibility --- this chapter establishes some guidelines and lays out all of the field names that \product understands. \section{Description of the image} \apiitem{"ImageDescription" : string} The image description, title, caption, or comments. \apiend \apiitem{"Keywords" : string} Semicolon-separated keywords describing the contents of the image. (Semicolons are used rather than commas because of the common case of a comma being part of a keyword itself, e.g., ``Kurt Vonnegut, Jr.'' or ``Washington, DC.'') \apiend \apiitem{"Artist" : string} The artist, creator, or owner of the image. \apiend \apiitem{"Copyright" : string} Any copyright notice or owner of the image. \apiend \apiitem{"DateTime" : string} The creation date of the image, in the following format: {\cf YYYY:MM:DD HH:MM:SS} (exactly 19 characters long, not including a terminating NULL). For example, 7:30am on Dec 31, 2008 is encoded as \qkw{2008:12:31 07:30:00}. \apiend \apiitem{"DocumentName" : string} The name of an overall document that this image is a part of. \apiend \apiitem{"Software" : string} The software that was used to create the image. \apiend \apiitem{"HostComputer" : string} The name or identity of the computer that created the image. \apiend \section{Display hints} \label{metadata:displayhints} \apiitem{"oiio:ColorSpace" : string} The name of the color space of the color channels. Values incude: \qkw{Linear}, \qkw{sRGB}, \qkw{GammaCorrected}, \qkw{AdobeRGB}, \qkw{Rec709}, and \qkw{KodakLog}. \apiend \apiitem{"oiio:Gamma" : float} If the color space is \qkw{GammaCorrected}, this value is the gamma exponent. \apiend \apiitem{"oiio:BorderColor" : float[nchannels]} The color presumed to be filling any parts of the display/full image window that are not overlapping the pixel data window. If not supplied, the default is black (0 in all channels). \apiend \apiitem{"Orientation" : int} \index{Orientation} \label{metadata:orientation} By default, image pixels are ordered from the top of the display to the bottom, and within each scanline, from left to right (i.e., the same ordering as English text and scan progression on a CRT). But the \qkw{Orientation} field can suggest that it should be displayed with a different orientation, according to the TIFF/EXIF conventions: \begin{tabular}{p{0.3in} p{4in}} 1 & normal (top to bottom, left to right) \\ 2 & flipped horizontally (top to botom, right to left) \\ 3 & rotate $180^\circ$ (bottom to top, right to left) \\ 4 & flipped vertically (bottom to top, left to right) \\ 5 & transposed (left to right, top to bottom) \\ 6 & rotated $90^\circ$ clockwise (right to left, top to bottom) \\ 7 & transverse (right to left, bottom to top) \\ 8 & rotated $90^\circ$ counter-clockwise (left to right, bottom to top) \\ \end{tabular} \apiend \apiitem{"PixelAspectRatio" : float} The aspect ratio ($x/y$) of the individual pixels, with square pixels being 1.0 (the default). \apiend \apiitem{"XResolution" : float \\ "YResolution" : float \\ "ResolutionUnit" : string} The number of horizontal ($x$) and vertical ($y$) pixels per resolution unit. This ties the image to a physical size (where applicable, such as with a scanned image, or an image that will eventually be printed). Different file formats may dictate different resolution units. For example, the TIFF ImageIO plugin supports \qkw{none}, \qkw{in}, and \qkw{cm}. \apiend \section{Disk file format info/hints} \apiitem{"oiio:BitsPerSample" : int} Number of bits per sample \emph{in the file}. Note that this may not match the reported {\cf ImageSpec::format}, if the plugin is translating from an unsupported format. For example, if a file stores 4 bit grayscale per channel, the {\cf "oiio:BitsPerSample"} may be 4 but the {\cf format} field may be {\cf TypeDesc::UINT8} (because the \product APIs do not support fewer than 8 bits per sample). \apiend \apiitem{"oiio:UnassociatedAlpha" : int} Whether the data in the file stored alpha channels (if any) that were unassociated with the color (i.e., color not ``premultiplied'' by the alpha coverage value). \apiend \apiitem{"planarconfig" : string} \qkw{contig} indicates that the file has contiguous pixels (RGB RGB RGB...), whereas \qkw{separate} indicate that the file stores each channel separately (RRR...GGG...BBB...). Note that only contiguous pixels are transmitted through the \product APIs, but this metadata indicates how it is (or should be) stored in the file, if possible. \apiend \apiitem{"compression" : string} Indicates the type of compression the file uses. Supported compression modes will vary from \ImageInput plugin to plugin, and each plugin should document the modes it supports. If {\cf ImageInput::open} is called with an \ImageSpec that specifies an compression mode not supported by that \ImageInput, it will choose a reasonable default. As an example, the TIFF \ImageInput plugin supports \qkw{none}, \qkw{lzw}, \qkw{ccittrle}, \qkw{zip} (the default), \qkw{packbits}. \apiend \apiitem{"CompressionQuality" : int} Indicates the quality of compression to use (0--100), for those plugins and compression methods that allow a variable amount of compression, with higher numbers indicating higher image fidelity. \apiend \section{Photographs or scanned images} The following metadata items are specific to photos or captured images. \apiitem{"Make" : string} For captured or scanned image, the make of the camera or scanner. \apiend \apiitem{"Model" : string} For captured or scanned image, the model of the camera or scanner. \apiend \apiitem{"ExposureTime" : float} The exposure time (in seconds) of the captured image. \apiend \apiitem{"FNumber" : float} The f/stop of the camera when it captured the image. \apiend \section{Texture Information} Several standard metadata are very helpful for images that are intended to be used as textures (especially for \product's \TextureSystem). \apiitem{"textureformat" : string} The kind of texture that this image is intended to be. We suggest the following names: \noindent \begin{tabular}{p{1.75in} p{3.25in}} \qkw{Plain Texture} & Ordinary 2D texture \\ \qkw{Volume Texture} & 3D volumetric texture \\ \qkw{Shadow} & Ordinary $z$-depth shadow map \\ \qkw{CubeFace Shadow} & Cube-face shadow map \\ \qkw{Volume Shadow} & Volumetric (``deep'') shadow map \\ \qkw{LatLong Environment} & Latitude-longitude (rectangular) environment map \\ \qkw{CubeFace Environment} & Cube-face environment map \\ \end{tabular} \apiend \apiitem{"wrapmodes" : string} Give the intended texture \emph{wrap mode} indicating what happens with texture coordinates outside the $[0...1]$ range. We suggest the following names: \qkw{black}, \qkw{periodic}, \qkw{clamp}, \qkw{mirror}. If the wrap mode is different in each direction, they should simply be separated by a comma. For example, \qkw{black} means black wrap in both directions, whereas \qkw{clamp,periodic} means to clamp in $u$ and be periodic in $v$. \apiend \apiitem{"fovcot" : float} The cotangent ($x/y$) of the field of view of the original image (which may not be the same as the aspect ratio of the pixels of the texture, which may have been resized). \apiend \apiitem{"worldtocamera" : matrix44} For shadow maps or rendered images this item (of type {\cf TypeDesc::PT_MATRIX}) is the world-to-camera matrix describing the camera position. \apiend \apiitem{"worldtoscreen" : matrix44} For shadow maps or rendered images this item (of type {\cf TypeDesc::PT_MATRIX}) is the world-to-screen matrix describing the full projection of the 3D view onto a $[-1...1] \times [-1...1]$ 2D domain. \apiend \apiitem{"oiio:updirection" : string} For environment maps, indicates which direction is ``up'' (valid values are \qkw{y} or \qkw{z}), to disambiguate conventions for environment map orientation. \apiend \apiitem{"oiio:sampleborder" : int} If not present or 0 (the default), the conversion from pixel integer coordinates $(i,j)$ to texture coordinates $(s,t)$ follows the usual convention of $s = (i+0.5)/\mathit{xres}$ and $t = (j+0.5)/\mathit{yres}$. However, if this attribute is present and nonzero, the first and last row/column of pixels lie exactly at the $s$ or $t = 0$ or $1$ boundaries, i.e., $s = i/(\mathit{xres}-1)$ and $t = j/(\mathit{yres}-1)$. \apiend \section{Exif metadata} \label{sec:metadata:exif} \index{Exif metadata} % FIXME -- unsupported/undocumented: ExifVersion, FlashpixVersion, % ComponentsConfiguration, MakerNote, UserComment, RelatedSoundFile, % OECF, SubjectArea, SpatialFrequencyResponse, % CFAPattern, DeviceSettingDescription % % SubjectLocation -- unsupported, but we could do it The following Exif metadata tags correspond to items in the ``standard'' set of metadata. \medskip \begin{tabular}{p{1.5in} p{3.5in}} {\bf Exif tag} & {\bf \product metadata convention} \\ \hline ColorSpace & (reflected in \qkw{oiio:ColorSpace}) \\ ExposureTime & \qkw{ExposureTime} \\ FNumber & \qkw{FNumber} \\ \end{tabular} \medskip The other remaining Exif metadata tags all include the ``Exif:'' prefix to keep it from clashing with other names that may be used for other purposes. \apiitem{"Exif:ExposureProgram" : int} The exposure program used to set exposure when the picture was taken: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & unknown \\ 1 & manual \\ 2 & normal program \\ 3 & aperture priority \\ 4 & shutter priority \\ 5 & Creative program (biased toward depth of field) \\ 6 & Action program (biased toward fast shutter speed) \\ 7 & Portrait mode (closeup photo with background out of focus) \\ 8 & Landscape mode (background in focus) \end{tabular} \apiend \apiitem{"Exif:SpectralSensitivity" : string} The camera's spectral sensitivity, using the ASTM conventions. \apiend \apiitem{"Exif:ISOSpeedRatings" : int} The ISO speed and ISO latitude of the camera as specified in ISO 12232. \apiend %\apiitem{"Exif:OECF", TIFF_NOTYPE } // skip it %\apiitem{"Exif:ExifVersion", TIFF_NOTYPE } // skip it \apiitem{"Exif:DateTimeOriginal" : string} Date and time that the original image data was generated (in \qkw{YYYY:MM:DD HH:MM:SS} format). \apiend \apiitem{"Exif:DateTimeDigitized" : string} Date and time that the image was stored as digital data (in \qkw{YYYY:MM:DD HH:MM:SS} format). \apiend %\apiitem{"Exif:ComponentsConfiguration",TIFF_UNDEFINED } \apiitem{"Exif:CompressedBitsPerPixel" : float } The compression mode used, measured in compressed bits per pixel. \apiend \apiitem{"Exif:ShutterSpeedValue" : float } Shutter speed, in APEX units: $-\log_2 (\mathit{exposure time})$ \apiend \apiitem{"Exif:ApertureValue" : float } Aperture, in APEX units: $2 \log_2 (\mathit{fnumber})$ \apiend \apiitem{"Exif:BrightnessValue" : float } Brightness value, assumed to be in the range of $-99.99$ -- $99.99$. \apiend \apiitem{"Exif:ExposureBiasValue" : float } Exposure bias, assumed to be in the range of $-99.99$ -- $99.99$. \apiend \apiitem{"Exif:MaxApertureValue" : float } Smallest F number of the lens, in APEX units: $2 \log_2 (\mathit{fnumber})$ \apiend \apiitem{"Exif:SubjectDistance" : float } Distance to the subject, in meters. \apiend \apiitem{"Exif:MeteringMode" : int} The metering mode: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & unknown \\ 1 & average \\ 2 & center-weighted average \\ 3 & spot \\ 4 & multi-spot \\ 5 & pattern \\ 6 & partial \\ 255 & other \end{tabular} \apiend \apiitem{"Exif:LightSource" : int} The kind of light source: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & unknown \\ 1 & daylight \\ 2 & tungsten (incandescent light) \\ 4 & flash \\ 9 & fine weather \\ 10 & cloudy weather \\ 11 & shade \\ 12 & daylight fluorescent (D 5700-7100K) \\ 13 & day white fluorescent (N 4600-5400K) \\ 14 & cool white fuorescent (W 3900 - 4500K) \\ 15 & white fluorescent (WW 3200 - 3700K) \\ 17 & standard light A \\ 18 & standard light B \\ 19 & standard light C \\ 20 & D55 \\ 21 & D65 \\ 22 & D75 \\ 23 & D50 \\ 24 & ISO studio tungsten \\ 255 & other light source \end{tabular} \apiend \apiitem{"Exif:Flash" int} A sum of: \smallskip \begin{tabular}{p{0.3in} p{4in}} 1 & if the flash fired \\ \hline 0 & no strobe return detection function \\ 4 & strobe return light was not detected \\ 6 & strobe return light was detected \\ \hline 8 & compulsary flash firing \\ 16 & compulsary flash supression \\ 24 & auto-flash mode \\ \hline 32 & no flash function (0 if flash function present) \\ \hline 64 & red-eye reduction supported (0 if no red-eye reduction mode) \end{tabular} \apiend \apiitem{"Exif:FocalLength" : float } Actual focal length of the lens, in mm. \apiend \apiitem{"Exif:SecurityClassification" : string} Security classification of the image: `C' = confidential, `R' = restricted, `S' = secret, `T' = top secret, `U' = unclassified. \apiend \apiitem{"Exif:ImageHistory" : string} Image history. \apiend %\apiitem{"Exif:SubjectArea",TIFF_NOTYPE } // skip %\apiitem{"Exif:MakerNote",TIFF_NOTYPE } // skip it %\apiitem{"Exif:UserComment",TIFF_NOTYPE }// skip it \apiitem{"Exif:SubsecTime" : string} Fractions of a second to augment the \qkw{DateTime} (expressed as text of the digits to the right of the decimal). \apiend \apiitem{"Exif:SubsecTimeOriginal" : string} Fractions of a second to augment the \qkw{Exif:DateTimeOriginal} (expressed as text of the digits to the right of the decimal). \apiend \apiitem{"Exif:SubsecTimeDigitized" : string} Fractions of a second to augment the \qkw{Exif:DateTimeDigital} (expressed as text of the digits to the right of the decimal). \apiend %\apiitem{"Exif:FlashPixVersion",TIFF_NOTYPE } \apiitem{"Exif:PixelXDimension" : int \\ "Exif:PixelYDimension" : int } The $x$ and $y$ dimensions of the valid pixel area. FIXME -- better explanation? \apiend %\apiitem{"Exif:RelatedSoundFile", TIFF_NOTYPE }// skip \apiitem{"Exif:FlashEnergy" : float } Strobe energy when the image was captures, measured in Beam Candle Power Seconds (BCPS). \apiend %\apiitem{"Exif:SpatialFrequencyResponse",TIFF_NOTYPE } \apiitem{"Exif:FocalPlaneXResolution" : float \\ "Exif:FocalPlaneYResolution" : float \\ "Exif:FocalPlaneResolutionUnit" : int} The number of pixels in the $x$ and $y$ dimension, per resolution unit. The codes for resolution units are: \smallskip \begin{tabular}{p{0.3in} p{4in}} 1 & none \\ 2 & inches \\ 3 & cm \\ 4 & mm \\ 5 & $\mu$m \\ \end{tabular} \apiend %\apiitem{"Exif:SubjectLocation" : int} // FIXME: short[2] \apiitem{"Exif:ExposureIndex" : float } The exposure index selected on the camera. \apiend \apiitem{"Exif:SensingMethod" : int} The image sensor type on the camra: \smallskip \begin{tabular}{p{0.3in} p{4in}} 1 & undefined \\ 2 & one-chip color area sensor \\ 3 & two-chip color area sensor \\ 4 & three-chip color area sensor \\ 5 & color sequential area sensor \\ 7 & trilinear sensor \\ 8 & color trilinear sensor \end{tabular} \apiend \apiitem{"Exif:FileSource" : int} The source type of the scanned image, if known: \smallskip \begin{tabular}{p{0.3in} p{4in}} 1 & film scanner \\ 2 & reflection print scanner \\ 3 & digital camera \\ \end{tabular} \apiend \apiitem{"Exif:SceneType" : int} Set to 1, if a directly-photographed image, otherwise it should not be present. \apiend %\apiitem{"Exif:CFAPattern",TIFF_NOTYPE } \apiitem{"Exif:CustomRendered" : int} Set to 0 for a normal process, 1 if some custom processing has been performed on the image data. \apiend \apiitem{"Exif:ExposureMode" : int} The exposure mode: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & auto \\ 1 & manual \\ 2 & auto-bracket \end{tabular} \apiend \apiitem{"Exif:WhiteBalance" : int} Set to 0 for auto white balance, 1 for manual white balance. \apiend \apiitem{"Exif:DigitalZoomRatio" : float } The digital zoom ratio used when the image was shot. \apiend \apiitem{"Exif:FocalLengthIn35mmFilm" : int} The equivalent focal length of a 35mm camera, in mm. \apiend \apiitem{"Exif:SceneCaptureType" : int} The type of scene that was shot: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & standard \\ 1 & landscape \\ 2 & portrait \\ 3 & night scene \end{tabular} \apiend \apiitem{"Exif:GainControl" : float } The degree of overall gain adjustment: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & none \\ 1 & low gain up \\ 2 & high gain up \\ 3 & low gain down \\ 4 & high gain down \end{tabular} \apiend \apiitem{"Exif:Contrast" : int} The direction of contrast processing applied by the camera: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & normal \\ 1 & soft \\ 2 & hard \end{tabular} \apiend \apiitem{"Exif:Saturation" : int} The direction of saturation processing applied by the camera: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & normal \\ 1 & low saturation \\ 2 & high saturation \end{tabular} \apiend \apiitem{"Exif:Sharpness" : int} The direction of sharpness processing applied by the camera: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & normal \\ 1 & soft \\ 2 & hard \end{tabular} \apiend %\apiitem{"Exif:DeviceSettingDescription",TIFF_NOTYPE } \apiitem{"Exif:SubjectDistanceRange" : int} The distance to the subject: \smallskip \begin{tabular}{p{0.3in} p{4in}} 0 & unknown \\ 1 & macro \\ 2 & close \\ 3 & distant \end{tabular} \apiend \apiitem{"Exif:ImageUniqueID" : string} A unique identifier for the image, as 16 ASCII hexidecimal digits representing a 128-bit number. \apiend \section{GPS Exif metadata} \label{sec:metadata:GPS} \index{GPS metadata} The following GPS-related Exif metadata tags correspond to items in the ``standard'' set of metadata. %\apiitem{"GPS:VersionID" : int} %\apiend \apiitem{"GPS:LatitudeRef" : string} Whether the \qkw{GPS:Latitude} tag refers to north or south: \qkw{N} or \qkw{S}. \apiend \apiitem{"GPS:Latitude" : float[3]} The degrees, minutes, and seconds of latitude (see also \qkw{GPS:LatitudeRef}). \apiend \apiitem{"GPS:LongitudeRef" : string} Whether the \qkw{GPS:Longitude} tag refers to east or west: \qkw{E} or \qkw{W}. \apiend \apiitem{"GPS:Longitude" : float[3]} The degrees, minutes, and seconds of longitude (see also \qkw{GPS:LongitudeRef}). \apiend \apiitem{"GPS:AltitudeRef" : string} A value of 0 indicates that the altitude is above sea level, 1 indicates below sea level. \apiend \apiitem{"GPS:Altitude" : float} Absolute value of the altitude, in meters, relative to sea level (see \qkw{GPS:AltitudeRef} for whether it's above or below sea level). \apiend \apiitem{"GPS:TimeStamp" : float[3]} Gives the hours, minutes, and seconds, in UTC. \apiend \apiitem{"GPS:Satellites" : string} Information about what satellites were visible. \apiend \apiitem{"GPS:Status" : string} \qkw{A} indicates a measurement in progress, \qkw{V} indicates measurement interoperability. \apiend \apiitem{"GPS:MeasureMode" : string} \qkw{2} indicates a 2D measurement, \qkw{3} indicates a 3D measurement. \apiend \apiitem{"GPS:DOP" : float} Data degree of precision. \apiend \apiitem{"GPS:SpeedRef" : string} Indicates the units of the related \qkw{GPS:Speed} tag: \qkw{K} for km/h, \qkw{M} for miles/h, \qkw{N} for knots. \apiend \apiitem{"GPS:Speed" : float} Speed of the GPS receiver (see \qkw{GPS:SpeedRef} for the units). \apiend \apiitem{"GPS:TrackRef" : string} Describes the meaning of the \qkw{GPS:Track} field: \qkw{T} for true direction, \qkw{M} for magnetic direction. \apiend \apiitem{"GPS:Track" : float} Direction of the GPS receiver movement (from 0--359.99). The related \qkw{GPS:TrackRef} indicate whether it's true or magnetic. \apiend \apiitem{"GPS:ImgDirectionRef" : string} Describes the meaning of the \qkw{GPS:ImgDirection} field: \qkw{T} for true direction, \qkw{M} for magnetic direction. \apiend \apiitem{"GPS:ImgDirection" : float} Direction of the image when captured (from 0--359.99). The related \qkw{GPS:ImgDirectionRef} indicate whether it's true or magnetic. \apiend \apiitem{"GPS:MapDatum" : string} The geodetic survey data used by the GPS receiver. \apiend \apiitem{"GPS:DestLatitudeRef" : string} Whether the \qkw{GPS:DestLatitude} tag refers to north or south: \qkw{N} or \qkw{S}. \apiend \apiitem{"GPS:DestLatitude" : float[3]} The degrees, minutes, and seconds of latitude of the destination (see also \qkw{GPS:DestLatitudeRef}). \apiend \apiitem{"GPS:DestLongitudeRef" : string} Whether the \qkw{GPS:DestLongitude} tag refers to east or west: \qkw{E} or \qkw{W}. \apiend \apiitem{"GPS:DestLongitude" : float[3]} The degrees, minutes, and seconds of longitude of the destination (see also \qkw{GPS:DestLongitudeRef}). \apiend \apiitem{"GPS:DestBearingRef" : string} Describes the meaning of the \qkw{GPS:DestBearing} field: \qkw{T} for true direction, \qkw{M} for magnetic direction. \apiend \apiitem{"GPS:DestBearing" : float} Bearing to the destination point (from 0--359.99). The related \qkw{GPS:DestBearingRef} indicate whether it's true or magnetic. \apiend \apiitem{"GPS:DestDistanceRef" : string} Indicates the units of the related \qkw{GPS:DestDistance} tag: \qkw{K} for km, \qkw{M} for miles, \qkw{N} for knots. \apiend \apiitem{"GPS:DestDistance" : float} Distance to the destination (see \qkw{GPS:DestDistanceRef} for the units). \apiend \apiitem{"GPS:ProcessingMethod" : string} Processing method information. \apiend \apiitem{"GPS:AreaInformation" : string} Name of the GPS area. \apiend \apiitem{"GPS:DateStamp" : string} Date according to the GPS device, in format \qkw{YYYY:MM:DD}. \apiend \apiitem{"GPS:Differential" : int} If 1, indicates that differential correction was applied. \apiend \apiitem{"GPS:HPositioningError" : float} Positioning error. \apiend \section{IPTC metadata} \label{sec:metadata:iptc} \index{IPTC metadata} The IPTC (International Press Telecommunications Council) publishes conventions for storing image metadata, and this standard is growing in popularity and is commonly used in photo-browsing programs to record captions and keywords. The following IPTC metadata items correspond exactly to metadata in the \product conventions, so it is recommended that you use the standards and that plugins supporting IPTC metadata respond likewise: \medskip \begin{tabular}{p{1.5in} p{3.5in}} {\bf IPTC tag} & {\bf \product metadata convention} \\ \hline Caption & \qkw{ImageDescription} \\[0.5ex] Keyword & IPTC keywords should be concatenated, separated by semicolons ({\cf ;}), and stored as the \qkw{Keywords} attribute. \\[0.5ex] ExposureTime & \qkw{ExposureTime} \\[0.5ex] CopyrightNotice & \qkw{Copyright} \\[0.5ex] Creator & \qkw{Artist} \\ \end{tabular} \bigskip The remainder of IPTC metadata fields should use the following names, prefixed with ``IPTC:'' to avoid conflicts with other plugins or standards. \apiitem{"IPTC:ObjecTypeReference" : string} Object type reference. \apiend \apiitem{"IPTC:ObjectAttributeReference" : string} Object attribute reference. \apiend \apiitem{"IPTC:ObjectName" : string} The name of the object in the picture. \apiend \apiitem{"IPTC:EditStatus" : string} Edit status. \apiend \apiitem{"IPTC:SubjectReference" : string} Subject reference. \apiend \apiitem{"IPTC:Category" : string} Category. \apiend % \apiitem{ 25, "Keywords" : string} %\apiend % FIXME \apiitem{"IPTC:ContentLocationCode" : string} Code for content location. \apiend \apiitem{"IPTC:ContentLocationName" : string} Name of content location. \apiend \apiitem{"IPTC:ReleaseDate" : string \\ "IPTC:ReleaseTime" : string} Release date and time. \apiend \apiitem{"IPTC:ExpirationDate" : string \\ "IPTC:ExpirationTime" : string} Expiration date and time. \apiend \apiitem{"IPTC:Instructions" : string} Special instructions for handling the image. \apiend \apiitem{"IPTC:ReferenceService" : string \\ "IPTC:ReferenceDate" : string \\ "IPTC:ReferenceNumber" : string} Reference date, service, and number. \apiend \apiitem{"IPTC:DateCreated" : string \\ "IPTC:TimeCreated" : string} Date and time that the image was created. \apiend \apiitem{"IPTC:DigitalCreationDate" : string \\ "IPTC:DigitalCreationTime" : string} Date and time that the image was digitized. \apiend %\apiitem{"IPTC:Creator" : string} %The creator of the image. This is optinal and, If present, %is expected to be the same as the data in the standard \qkw{Artist} field. %\apiend \apiitem{"IPTC:ProgramVersion" : string} The version number of the creation software. \apiend \apiitem{"IPTC:AuthorsPosition" : string} The job title or position of the creator of the image. \apiend \apiitem{"IPTC:City" : string \\ "IPTC:Sublocation" : string \\ "IPTC:State" : string \\ "IPTC:Country" : string \\ "IPTC:CountryCode" : string} The city, sublocation within the city, state, country, and country code of the location of the image. \apiend \apiitem{"IPTC:Headline" : string} Any headline that is meant to accompany the image. \apiend \apiitem{"IPTC:Provider" : string} The provider of the image, or credit line. \apiend \apiitem{"IPTC:Source" : string} The source of the image. \apiend %\apiitem{"IPTC:CopyrightNotice" : string} %The copyright notice for the image. This is optinal and, If present, %is expected to be the same as the data in the standard \qkw{Copyright} field. %\apiend \apiitem{"IPTC:Contact" : string} The contact information for the image (possibly including name, address, email, etc.). \apiend %\apiitem{"IPTC:Caption", string } %The caption, abstract, or description of the image. %This is optional and, if present, is expected to be the same as the %data in the standard \qkw{ImageDescription} field. %\apiend \apiitem{"IPTC:CaptionWriter" : string} The name of the person who wrote the caption or description of the image. \apiend \apiitem{"IPTC:JobID" : string \\ "IPTC:MasterDocumentID" : string \\ "IPTC:ShortDocumentID" : string \\ "IPTC:UniqueDocumentID" : string \\ "IPTC:OwnerID" : string } Various identification tags. \apiend \apiitem{"IPTC:Prefs" : string \\ "IPTC:ClassifyState" : string \\ "IPTC:SimilarityIndex" : string} Who knows what the heck these are? \apiend \apiitem{"IPTC:DocumentNotes" : string} Notes about the image or document. \apiend \apiitem{"IPTC:DocumentHistory" : string} The history of the image or document. \apiend \section{SMPTE metadata} \label{sec:metadata:smpte} \index{SMPTE metadata} \apiitem{"smpte:TimeCode" : int[2]} SMPTE time code, encoded as an array of 2 32-bit integers (as a \TypeDesc, it will be tagged with vecsemantics {\cf TIMECODE}). \apiend \apiitem{"smpte:KeyCode" : int[7]} SMPTE key code, encoded as an array of 7 32-bit integers (as a \TypeDesc, it will be tagged with vecsemantics {\cf KEYCODE}). \apiend \section{Extension conventions} To avoid conflicts with other plugins, or with any additional standard metadata names that may be added in future verions of \product, it is strongly advised that writers of new plugins should prefix their metadata with the name of the format, much like the \qkw{Exif:} and \qkw{IPTC:} metadata. \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/oiiotool.tex0000644000175000017500000014643212271062644020246 0ustar mfvmfv\chapter{{\kw oiiotool}: the OIIO Swiss Army Knife} \label{chap:oiiotool} \indexapi{oiiotool} \section{Overview} The \oiiotool program will read images (from any file format for which an \ImageInput plugin can be found), perform various operations on them, and write images (in any format for which an \ImageOutput plugin can be found). The \oiiotool utility is invoked as follows: \medskip \hspace{0.25in} \oiiotool \emph{args} \medskip \oiiotool maintains an \emph{image stack}, with the top image in the stack also called the \emph{current image}. The stack begins containing no images. \oiiotool arguments consist of image names, or commands. When an image name is encountered, that image is pushed on the stack and becomes the new \emph{current image}. Most other commands either alter the current image (replacing it with the alteration), or in some cases will pull more than one image off the stack (such as the current image and the next item on the stack) and then push a new image. \subsubsection*{Optional arguments} Some commands stand completely on their own (like {\cf --flip}), others take one or more arguments (like {\cf --resize} or {\cf -o}): \smallskip \hspace{0.25in} {\cf oiiotool foo.jpg --flip --resize 640x480 -o out.tif} \smallskip A few commands take optional modifiers for options that are so rarely-used or confusing that they should not be required arguments. In these cases, they are appended to the command name, after a colon (``{\cf :}''), and with a \emph{name}{\cf =}\emph{value} format. As an example: \smallskip \hspace{0.25in} {\cf oiiotool --capture:camera=1 -o out.tif} \smallskip \subsubsection*{Frame sequences} It is also possible to have \oiiotool operate on numbered sequences of images. In effect, this will execute the \oiiotool command several times, making substitutions to the sequence arguments in turn. Image sequences are specified by having filename arguments to oiiotool use either a numeric range wildcard (designated such as ``{\cf 1-10\#}'' or a {\cf printf}-like notation ``{\cf 1-10\%d}''), or spelling out a more complex pattern with {\cf --frames}. For example: \begin{code} oiiotool big.1-3#.tif --resize 100x100 -o small.1-3#.tif oiiotool big.1-3%04d.tif --resize 100x100 -o small.1-3%04d.tif oiiotool --frames 1-3 big.#.tif --resize 100x100 -o small.#.tif oiiotool --frames 1-3 big.%04d.tif --resize 100x100 -o small.%04d.tif \end{code} \noindent Any of those will be the equivalent of having issued the following sequence of commands: \begin{code} oiiotool big.0001.tif --resize 100x100 -o small.0001.tif oiiotool big.0002.tif --resize 100x100 -o small.0002.tif oiiotool big.0003.tif --resize 100x100 -o small.0003.tif \end{code} The frame range may be forwards ({\cf 1-5}) or backwards ({\cf 5-1}), and may give a step size to skip frames ({\cf 1-5x2} means 1, 3, 5) or take the complement of the step size set ({\cf 1-5y2} means 2, 4) and may combine subsequences with a comma. If you are using the {\cf \#} or {\cf @} wildcards, then the wildcard characters themselves specify how many digits to pad with leading zeroes, with {\cf \#} indicating 4 digits and {\cf @} indicating one digit (these may be combined: {\cf \#@@} means 6 digits). An optional {\cf --framepadding} can also be used to override the number of padding digits. For example, \begin{code} oiiotool --framepadding 3 --frames 3,4,10-20x2 blah.#.tif \end{code} \noindent would match {\cf blah.003.tif}, {\cf blah.004.tif}, {\cf blah.010.tif}, {\cf blah.012.tif}, {\cf blah.014.tif}, {\cf blah.016.tif}, {\cf blah.018.tif}, {\cf blah.020.tif}. Alternately, you can use the {\cf printf} notation, such as \begin{code} oiiotool --frames 3,4,10-20x2 blah.%03d.tif \end{code} \section{\oiiotool Tutorial / Recipes} This section will give quick examples of common uses of \oiiotool to get you started. They should be fairly intuitive, but you can read the subsequent sections of this chapter for all the details on every command. \subsection*{Printing information about images} To print the name, format, resolution, and data type of an image (or many images): \begin{code} oiiotool --info *.tif \end{code} \noindent To also print the full metadata about each input image, use both {\cf --info} and {\cf -v}: \begin{code} oiiotool --info -v *.tif \end{code} \noindent To print info about all subimages and/or MIP-map levels of each input image, use the {\cf -a} flag: \begin{code} oiiotool --info -v -a mipmap.exr \end{code} \noindent To print statistics giving the minimum, maximum, average, and standard deviation of each channel of an image, as well as other information about the pixels: \begin{code} oiiotool --stats img_2012.jpg \end{code} \noindent The {\cf --info}, {\cf --stats}, {\cf -v}, and {\cf -a} flags may be used in any combination. \subsection*{Converting between file formats} It's a snap to convert among image formats supported by \product (i.e., for which \ImageInput and \ImageOutput plugins can be found). The \oiiotool utility will simply infer the file format from the file extension. The following example converts a PNG image to JPEG: \begin{code} oiiotool lena.png -o lena.jpg \end{code} The first argument ({\cf lena.png}) is a filename, causing \oiiotool to read the file and makes it the current image. The {\cf -o} command outputs the current image to the filename specified by the next argument. Thus, the above command should be read to mean, ``Read {\cf lena.png} into the current image, then output the current image as {\cf lena.jpg} (using whatever file format is traditionally associated with the {\cf .jpg} extension).'' \subsection*{Comparing two images} To print a report of the differences between two images of the same resolution: \begin{code} oiiotool old.tif new.tif --diff \end{code} \noindent If you also want to save an image showing just the differences: \begin{code} oiiotool old.tif new.tif --diff --sub --abs -o diff.tif \end{code} This looks complicated, but it's really simple: read {\cf old.tif}, read {\cf new.tif} (pushing {\cf old.tif} down on the image stack), report the differences between them, subtract {\cf new.tif} from {\cf old.tif} and replace them both with the difference image, replace that with its absolute value, then save that image to {\cf diff.tif}. \subsection*{Changing the data format or bit depth} Just use the {\cf -d} option to specify a pixel data format for all subsequent outputs. For example, assuming that {\cf in.tif} uses 16-bit unsigned integer pixels, the following will convert it to an 8-bit unsigned pixels: \begin{code} oiiotool in.tif -d uint8 -o out.tif \end{code} For formats that support per-channel data formats, you can override the format for one particular channel using {\cf -d CHNAME=TYPE}. For example, assuming {\cf rgbaz.exr} is a {\cf float} RGBAZ file, and we wish to convert it to be {\cf half} for RGBA, and {\cf float} for Z. That can be accomplished with the following command: \begin{code} oiiotool rgbaz.tif -d half -d Z=float -o rgbaz2.exr \end{code} \subsection*{Changing the compression} The following command converts writes a TIFF file, specifically using LZW compression: \begin{code} oiiotool in.tif --compression lzw -o compressed.tif \end{code} The following command writes its results as a JPEG file at a compression quality of 50 (pretty severe compression): \begin{code} oiiotool big.jpg --quality 50 -o small.jpg \end{code} \subsection*{Converting between scanline and tiled images} Convert a scanline file to a tiled file with $16 \times 16$ tiles: \begin{code} oiiotool s.tif --tile 16 16 -o t.tif \end{code} \noindent Convert a tiled file to scanline: \begin{code} oiiotool t.tif --scanline -o s.tif \end{code} \subsection*{Adding captions or metadata} \begin{code} oiiotool foo.jpg --caption "Hawaii vacation" -o bar.jpg oiiotool foo.jpg --keyword "volcano,lava" -o bar.jpg oiiotool in.exr --attrib "FStop" 22.0 -o out.exr \end{code} \subsection*{Scale the values in an image} Reduce the brightness of the R, G, and B channels by 10\%, but leave the A channel at its original value: \begin{code} oiiotool original.exr --cmul 0.9,0.9,0.9,1.0 -o out.exr \end{code} \subsection*{Resize an image} Resize by a known scale factor: \begin{code} oiiotool original.tif --resize 200% -o big.tif oiiotool original.tif --resize 25% -o small.tif \end{code} \noindent Resize to a specific resolution: \begin{code} oiiotool original.tif --resize 1024x768 -o specific.tif \end{code} \noindent Resize to fit into a given resolution, keeping the original aspect ratio and padding with black where necessary: \begin{code} oiiotool original.tif --fit 640x480 -o fit.tif \end{code} \subsection*{Color convert an image} This command linearizes a JPEG assumed to be in sRGB, saving as an HDRI OpenEXR file: \begin{code} oiiotool photo.jpg --colorconvert sRGB linear -o output.exr \end{code} \noindent And the other direction: \begin{code} oiiotool render.exr --colorconvert linear sRGB -o fortheweb.png \end{code} \noindent This converts between two named color spaces (presumably defined by your facility's OpenColorIO configuration): \begin{code} oiiotool in.dpx --colorconvert lg10 lnf -o out.exr \end{code} \subsection*{Channel reordering and padding} \noindent Turn a single channel image into gray RGB: \begin{code} oiiotool gray.tif --ch 0,0,0 -o rgb.tif \end{code} \noindent Copy just the color from an RGBA file, truncating the A, yielding RGB only: \begin{code} oiiotool rgba.tif --ch R,G,B -o rgb.tif \end{code} \noindent Zero out the red and green channels: \begin{code} oiiotool rgb.tif --ch =0,=0,B -o justblue.tif \end{code} \noindent Swap the red and blue channels from an RGBA image: \begin{code} oiiotool rgba.tif --ch 2,1,0,3 -o bgra.tif \end{code} \noindent Extract just the named channels from a complicted many-channel image, and add an alpha channel that is 1 everywhere: \begin{code} oiiotool allmyaovs.exr --ch spec.R,spec.G,spec.B,=1 -o spec.exr \end{code} \noindent Add a channel to an RGBA image, setting it to 3.0 everywhere, and naming it ``Z'' so it will be recognized as a $z$ channel: \begin{code} oiiotool rgba.exr --ch R,G,B,A,Z=3.0 -o rgbaz.exr \end{code} \subsection*{Composite a sequence of images} \noindent Composite foreground images over background images for a series of files with frame numbers in their names: \begin{code} oiiotool fg.1-50%04d.exr bg.1-50%04d.exr --over -o comp.1-50%04d.exr \end{code} \noindent Or, \begin{code} oiiotool --frames 1-50 fg.%04d.exr bg.%04d.exr --over -o comp.%04d.exr \end{code} \newpage \section{\oiiotool commands: general} \apiitem{--help} Prints usage information to the terminal. \apiend \apiitem{-v} Verbose status messages --- print out more information about what \oiiotool is doing at every step. \apiend \apiitem{-q} Quet mode --- print out less information about what \oiiotool is doing (only errors). \apiend \apiitem{--runstats} Print timing and memory statistics about the work done by \oiiotool. \apiend \apiitem{-a} Performs all operations on all subimages and/or MIPmap levels of each input image. Without {\cf -a}, generally each input image will really only read the top-level MIPmap of the first subimage of the file. \apiend \apiitem{--info} Prints information about each input image as it is read. If verbose mode is turned on ({\cf -v}), all the metadata for the image is printed. If verbose mode is not turned on, only the resolution and data format are printed. \apiend \apiitem{--metamatch \emph{regex} \\ --no-metamatch \emph{regex}} Regular expressions to restrict which metadata are output when using {\cf oiiotool --info -v}. The {\cf --metamatch} expression causes only metadata whose name matches to print; non-matches are not output. The {\cf --no-metamatch} expression causes metadata whose name matches to be suppressed; others (non-matches) are printed. It is not advised to use both of these options at the same time (probably nothing bad will happen, but it's hard to reason about the behavior in that case). \apiend \apiitem{--stats} Prints detailed statistical information about each input image as it is read. \apiend \apiitem{--hash} Print the SHA-1 hash of the pixels of each input image. \apiend \apiitem{--diff} This command computes the difference of the current image and the next image on the stack, and prints a report of those differences (how many pixels differed, the maximum amount, etc.). This command does not alter the image stack. \apiend \apiitem{--colorcount \emph{r1,g1,b1,...:r2,g2,b2,...:...}} Given a list of colors separated by colons or semicolons, where each color is a list of comma-separated values (for each channel), examine all pixels of the current image and print a short report of how many pixels matched each of the colors. \noindent Optional appended arguments include: \begin{tabular}{p{10pt} p{0.75in} p{3.75in}} & {\cf eps=}\emph{r,g,b,...} & Tolerance for matching colors (default: 0.001 for all channels). \end{tabular} \noindent Examples: \begin{code} oiiotool test.tif --colorcount "0.792,0,0,1;0.722,0,0,1" \end{code} \noindent might produce the following output: \begin{code} 10290 0.792,0,0,1 11281 0.722,0,0,1 \end{code} \noindent Notice that use of double quotes (\qkw{ }) around the list of color arguments, in order to make sure that the command shell does not interpret the semicolon ({\cf ;}) as a statement separator. An alternate way to specify multiple colors is to separate them with a colon ({\cf :}), for example: \begin{code} oiiotool test.tif --colorcount 0.792,0,0,1:0.722,0,0,1 \end{code} \noindent Another example: \begin{code} oiiotool test.tif --colorcount:eps=.01,.01,.01,1000 "0.792,0,0,1" \end{code} \noindent This example sets a larger epsilon for the R, G, and B channels (so that, for example, a pixel with value [0.795,0,0] would also match), and by setting the epsilon to 1000 for the alpha channel, it effectively ensures that alpha will not be considered in the matching of pixels to the color value. \apiend \apiitem{--rangecheck \emph{Rlow,Glow,Blow,...} \emph{Rhi,Bhi,Ghi,...}} Given a two colors (each a comma-separated list of values for each channel), print a count of the number of pixels in the image that has channel values outside the [low,hi] range. Any channels not specified will assume a low of 0.0 and high of 1.0. \noindent Example: \begin{code} oiiotool test.exr --rangecheck 0,0,0 1,1,1 \end{code} \noindent might produce the following output: \begin{code} 0 < 0,0,0 221 > 1,1,1 65315 within range \end{code} \apiend \apiitem{--no-clobber} Sets ``no clobber'' mode, in which existing images on disk will never be overridden, even if the {\cf -o} command specifies that file. \apiend \apiitem{--threads \emph{n}} Use \emph{n} execution threads if it helps to speed up image operations. The default (also if $n=0$) is to use as many threads as there are cores present in the hardware. \apiend \apiitem{--frames \emph{seq}\\ --framepadding \emph{n}} Describes the frame range to substitute for the {\cf \#} or {\cf \%0Nd} numeric wildcards. The sequence is a comma-separated list of subsequences; each subsequence is a single frame (e.g., {\cf 100}), a range of frames ({\cf 100-150}), or a frame range with step ({\cf 100-150x4} means {\cf 100,104,108,...}). The frame padding is the number of digits (with leading zeroes applied) that the frame numbers should have. It defaults to 4. For example, \begin{code} oiiotool --framepadding 3 --frames 3,4,10-20x2 blah.#.tif \end{code} \noindent would match {\cf blah.003.tif}, {\cf blah.004.tif}, {\cf blah.010.tif}, {\cf blah.012.tif}, {\cf blah.014.tif}, {\cf blah.016.tif}, {\cf blah.018.tif}, {\cf blah.020.tif}. \apiend \begin{comment} \apiitem{--inplace} Causes the output to \emph{replace} the input file, rather than create a new file with a different name. Without this flag, \oiiotool expects two file names, which will be used to specify the input and output files, respectively. But when {\cf --inplace} option is used, any number of file names $\ge 1$ may be specified, and the image conversion commands are applied to each file in turn, with the output being saved under the original file name. This is useful for applying the same conversion to many files. For example, the following example will add the caption ``Hawaii vacation'' to all JPEG files in the current directory: \begin{code} oiiotool --inplace --adjust-time --caption "Hawaii vacation" *.jpg \end{code} \apiend \end{comment} \section{\oiiotool commands: reading and writing images} The commands described in this section read images, write images, or control the way that subsequent images will be written upon output. \apiitem{\rm \emph{filename}} If a command-line option is the name of an image file, that file will be read and will become the new \emph{current image}, with the previous current image pushed onto the image stack. \apiend \apiitem{-o \rm \emph{filename}} Outputs the current image to the named file. This does not remove the current image, it merely saves a copy of it. \apiend \apiitem{-d {\rm \emph{datatype}} \\ -d {\rm \emph{channelname}{\cf =}\emph{datatype}}} Attempts to set the pixel data type of all subsequent outputs. If no channel is named, sets \emph{all} channels to be the specified data type. If a specific channel is named, then the data type will be overridden for just that channel (multiple {\cf -d} commands may be used). Valid types are: {\cf uint8}, {\cf sint8}, {\cf uint16}, {\cf sint16}, {\cf half}, {\cf float}, {\cf double}. The types {\cf uint10} and {\cf uint12} may be used to request 10- or 12-bit unsigned integers. If the output file format does not support them, {\cf uint16} will be substituted. If the {\cf -d} option is not supplied, the output data type will be the same as the data format of the input files, if possible. In any case, if the output file type does not support the requested data type, it will instead use whichever supported data type results in the least amount of precision lost. \apiend % FIXME -- no it doesn't! %\apiitem{-g {\rm \emph{gamma}}} %Applies a gamma correction of $1/\mathrm{gamma}$ to the pixels as they %are output. %\apiend %\apiitem{--sRGB} %Explicitly tags the image as being in sRGB color space. Note that this %does not alter pixel values, it only marks which color space those %values refer to (and only works for file formats that understand such %things). An example use of this command is if you have an image %that is not explicitly marked as being in any particular color space, %but you know that the values are sRGB. %\apiend \apiitem{--scanline} Requests that subsequent output files be scanline-oriented, if scanline orientation is supported by the output file format. By default, the output file will be scanline if the input is scanline, or tiled if the input is tiled. \apiend \apiitem{--tile {\rm \emph{x}} {\rm \emph{y}}} Requests that subsequent output files be tiled, with the given $x \times y$ tile size, if tiled images are supported by the output format. By default, the output file will take on the tiledness and tile size of the input file. \apiend \apiitem{--compression {\rm \emph{method}}} Sets the compression method for subsequent output images. Each \ImageOutput plugin will have its own set of methods that it supports. By default, the output image will use the same compression technique as the input image (assuming it is supported by the output format, otherwise it will use the default compression method of the output plugin). \apiend \apiitem{--quality {\rm \emph{q}}} Sets the compression quality, on a 1--100 floating-point scale. This only has an effect if the particular compression method supports a quality metric (as JPEG does). \apiend \apiitem{--planarconfig {\rm \emph{config}}} Sets the planar configuration of subsequent outputs (if supported by their formats). Valid choices are: {\cf config} for contiguous (or interleaved) packing of channels in the file (e.g., RGBRGBRGB...), {\cf separate} for separate channel planes (e.g., RRRR...GGGG...BBBB...), or {\cf default} for the default choice for the given format. This command will be ignored for output files whose file format does not support the given choice. \apiend \apiitem{--adjust-time} When this flag is present, after writing each output, the resulting file's modification time will be adjusted to match any \qkw{DateTime} metadata in the image. After doing this, a directory listing will show file times that match when the original image was created or captured, rather than simply when \oiiotool was run. This has no effect on image files that don't contain any \qkw{DateTime} metadata. \apiend \apiitem{--noautocrop} For subsequent outputs, do \emph{not} automatically crop images whose formats don't support separate pixel data and full/display windows. Without this, the default is that outputs will be cropped or padded with black as necessary when written to formats that don't support the concepts of pixel data windows and full/display windows. This is a non-issue for file formats that support these concepts, such as OpenEXR. \apiend \apiitem{--autotrim} For subsequent outputs, if the output format supports separate pixel data and full/display windows, automatically trim the output so that it writes the minimal data window that contains all the non-zero valued pixels. In other words, trim off any all-black border rows and columns before writing the file. \apiend \section{\oiiotool commands that change the current image metadata} This section describes \oiiotool commands that alter the metadata of the current image, but do not alter its pixel values. Only the current (i.e., top of stack) image is affected, not any images further down the stack. If the {\cf -a} flag has previously been set, these commands apply to all subimages or MIPmap levels of the current top image. Otherwise, they only apply to the highest-resolution MIPmap level of the first subimage of the current top image. \apiitem{--attrib {\rm \emph{name value}}} Adds or replaces metadata with the given \emph{name} to have the specified \emph{value}. It will try to infer the type of the metadata from the value: if the value contains only numerals (with optional leading minus sign), it will be saved as {\cf int} metadata; if it also contains a decimal point, it will be saved as {\cf float} metadata; otherwise, it will be saved as a {\cf string} metadata. For example, you could explicitly set the IPTC location metadata fields with: \begin{code} oiiotool --attrib "IPTC:City" "Berkeley" in.jpg out.jpg \end{code} \apiend \apiitem{--sattrib {\rm \emph{name value}}} Adds or replaces metadata with the given \emph{name} to have the specified \emph{value}, forcing it to be interpreted as a {\cf string}. This is helpful if you want to set a {\cf string} metadata to a value that the {\cf --attrib} command would normally interpret as a number. \apiend \apiitem{--caption {\rm \emph{text}}} Sets the image metadata \qkw{ImageDescription}. This has no effect if the output image format does not support some kind of title, caption, or description metadata field. Be careful to enclose \emph{text} in quotes if you want your caption to include spaces or certain punctuation! \apiend \apiitem{--keyword {\rm \emph{text}}} Adds a keyword to the image metadata \qkw{Keywords}. Any existing keywords will be preserved, not replaced, and the new keyword will not be added if it is an exact duplicate of existing keywords. This has no effect if the output image format does not support some kind of keyword field. Be careful to enclose \emph{text} in quotes if you want your keyword to include spaces or certain punctuation. For image formats that have only a single field for keywords, \OpenImageIO will concatenate the keywords, separated by semicolon (`;'), so don't use semicolons within your keywords. \apiend \apiitem{--clear-keywords} Clears all existing keywords in the current image. \apiend \apiitem{--orientation {\rm \emph{orient}}} Explicitly sets the image's \qkw{Orientation} metadata to a numeric value (see Section~\ref{metadata:orientation} for the numeric codes). This only changes the metadata field that specifies how the image should be displayed, it does NOT alter the pixels themselves, and so has no effect for image formats that don't support some kind of orientation metadata. \apiend \apiitem{--rotcw \\ --rotccw \\ --rot180} Adjusts the image's \qkw{Orientation} metadata by rotating it $90^\circ$ clockwise, $90^\circ$ degrees counter-clockwise, or $180^\circ$, respectively, compared to its current setting. This only changes the metadata field that specifies how the image should be displayed, it does NOT alter the pixels themselves, and so has no effect for image formats that don't support some kind of orientation metadata. \apiend \apiitem{--origin {\rm \emph{offset}}} Set the pixel data window origin, essentially translating the existing pixel data window to a different position on the image plane. The offset is in the form \begin{code} [+-]x[+-]y \end{code} \noindent Examples: \begin{code} --origin +20+10 x=20, y=10 --origin +0-40 x=0, y=-40 \end{code} \apiend \apiitem{--fullsize {\rm \emph{size}}} Set the display/full window size and/or offset. The size is in the form \\ \emph{width}\,{\cf x}\,\emph{height}{\cf [+-]}\emph{xoffset}{\cf [+-]}\emph{yoffset} \\ If either the offset or resolution is omitted, it will remain unchanged. \noindent Examples: \begin{tabular}{p{2in} p{4in}} {\cf --fullsize 1920x1080} & resolution w=1920, h=1080, offset unchanged \\ {\cf --fullsize -20-30} & resolution unchanged, x=-20, y=-30 \\ {\cf --fullsize 1024x768+100+0} & resolution w=1024, h=768, offset x=100, y=0 \end{tabular} \apiend \apiitem{--fullpixels} Set the full/display window range to exactly cover the pixel data window. \apiend \apiitem{--chnames {\rm \emph{name-list}}} Rename some or all of the channels of the top image to the given comma-separated list. Any completely empty channel names in the list will not be changed. For example, \begin{code} oiiotool in.exr --chnames ",,,A,Z" -o out.exr \end{code} \noindent will rename channel 3 to be \qkw{A} and channel 4 to be \qkw{Z}, but will leave channels 0--3 with their old names. \apiend \section{\oiiotool commands that adjust the image stack} \apiitem{--pop} Pop the image stack, discarding the current image and thereby making the next image on the stack into the new current image. \apiend \apiitem{--dup} Duplicate the current image and push the duplicate on the stack. Note that this results in both the current and the next image on the stack being identical copies. \apiend \apiitem{--swap} Swap the current image and the next one on the stack. \apiend \apiitem{--selectmip {\rm \emph{level}}} If the current image is MIP-mapped, replace the current image with a new image consisting of only the given \emph{level} of the MIPmap. Level 0 is the highest resolution version, level 1 is the next-lower resolution version, etc. \apiend \apiitem{--unmip} If the current image is MIP-mapped, discard all but the top level (i.e., replacing the current image with a new image consisting of only the highest-resolution level). Note that this is equivalent to {\cf --selectmip 0}. \apiend \apiitem{--subimage {\rm \emph{n}}} If the current image has multiple subimages, replace the current image with a new image consisting of only the given subimage. \apiend \apiitem{--siappend {\rm \emph{n}}} \NEW % 1.3 Replaces the two two images on the stack with a new image comprised of the subimages of both images appended together. \apiend \apiitem{--ch {\rm \emph{channellist}}} Replaces the top image with a new copy whose channels have been reordered as given by the \emph{channellist}. The {\cf channellist} is a comma-separated list of channel names and/or numbers (e.g., \qkw{R,G,B}, \qkw{A}, \qkw{B,G,R}, \qkw{4,5,6,A}). Channel numbers outside the valid range of input channels, or unknown names, will be replaced by black channels. \NEW % 1.3? A channel designation beginning with the {\cf =} character and followed by a number is a \emph{literal value} that will be used to fill that channel. If the \emph{channellist} is shorter than the number of channels in the source image, unspecified channels will be omitted. \apiend \apiitem{--chappend} Replaces the top two images on the stack with a new image comprised of the channels of both images appended together. \apiend \apiitem{--flatten} \index{deep images} \NEW % 1.3 If the top image is ``deep,'' then ``flatten'' it by compositing the depth samples in each pixel. \apiend \section{\oiiotool commands that make entirely new images} \apiitem{--create {\rm \emph{size channels}}} Create new black image with the given size and number of channels, pushing it onto the image stack and making it the new current image. The \emph{size} is in the form \\ \emph{width}\,{\cf x}\,\emph{height}{\cf [+-]}\emph{xoffset}{\cf [+-]}\emph{yoffset} \\ If the offset is omitted, it will be $x=0,y=0$. \noindent Examples: \begin{tabular}{p{2in} p{4in}} {\cf --create 1920x1080 3} & RGB with w=1920, h=1080, x=0, y=0 \\ {\cf --create 1024x768+100+0 4} & RGBA with w=1024, h=768, x=100, y=0 \end{tabular} \apiend \apiitem{--pattern {\rm \emph{patternname size channels}}} Create new image with the given size and number of channels, initialize its pixels to the named pattern, and push it onto the image stack to make it the new current image. The \emph{size} is in the form \\ \emph{width}\,{\cf x}\,\emph{height}{\cf [+-]}\emph{xoffset}{\cf [+-]}\emph{yoffset} \\ If the offset is omitted, it will be $x=0,y=0$. The patterns recognized include the following: \begin{tabular}{p{1in} p{4in}} {\cf black} & A black image (all pixels 0.0) \\ {\cf constant} & A constant color image, defaulting to white, but the color can be set with the optional {\cf :color=r,g,b,...} arguments giving a numerical value for each channel. \\ {\cf checker} & A black and white checkerboard pattern. The optional argument {\cf :width=} sets with width of the checkers (defaulting to 8 pixels). \end{tabular} \noindent Examples: \apiitem{--pattern constant:color=0.3,0.5,0.1,1.0 640x480 4} \vspace{10pt} A constant 4-channel, $640\times 480$ image with all pixels (0.5, 0.5, 0.1, 1). \apiend \apiitem{--pattern checker:width=16 512x512 3} \vspace{10pt} An $512 \times 512$ RGB image with a 16-pixel-wide checker pattern. \apiend \apiend \apiitem{--kernel {\rm \emph{name size}}} Create new 1-channel {\cf float} image big enough to hold the named kernel and size (size is expressed as \emph{width}{\cf x}\emph{height}, e.g. {\cf 5x5}). The \emph{width} and \emph{height} are allowed to be floating-point numbers. The kernel image will have its origin offset so that the kernel center is at (0,0), and and will be normalized (the sum of all pixel values will be 1.0). Kernel names can be: {\cf gaussian}, {\cf sharp-gaussian}, {\cf box}, {\cf triangle}, {\cf blackman-harris}, {\cf mitchell}, {\cf b-spline}, {\cf disk}. There are also {\cf catmull-rom} and {\cf lanczos3}, but they are fixed-size kernels that don't scale with the width, and are therefore probably less useful in most cases. \noindent Examples: \begin{code} oiiotool --kernel gaussian 11x11 -o gaussian.exr \end{code} \apiend \apiitem{--capture} Capture a frame from a camera device, pushing it onto the image stack and making it the new current image. Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.5in}} & {\cf camera=}\emph{num} & Select which camera number to capture (default: 0). \end{tabular} \noindent Examples: \begin{tabular}{p{2in} p{4in}} {\cf --capture} & Capture from the default camera. \\ {\cf --capture:camera=1} & Capture from camera 2. \\ \end{tabular} \apiend \section{\oiiotool commands that do image processing} \apiitem{--add} Replace the \emph{two} top images with a new image that is the sum of those images. \apiend \apiitem{--sub} Replace the \emph{two} top images with a new image that is the difference between the first and second images. \apiend \apiitem{--mul} Replace the \emph{two} top images with a new image that the pixel-by-pixel, channel-by-channel multiplicative product of the first and second images. \apiend \apiitem{--abs} Replace the current image with a new image that has each pixel consisting of the \emph{absolute value} of he old pixel value. \apiend \apiitem{--cadd {\rm \emph{value}} \\ --cadd {\rm \emph{value0,value1,value2...}}} Add a constant value to all the pixels in the current image. If a single constant value is given, it will be added to all color channels. Alternatively, a series of comma-separated constant values (with no spaces!) may be used to specifiy a different value to add to each channel in the image, respectively. \apiend \apiitem{--cmul {\rm \emph{value}} \\ --cmul {\rm \emph{value0,value1,value2...}}} Multiply all the pixel values in the top image by a constant value. If a single constant value is given, all color channels will have their values multiplied by the same value. Alternatively, a series of comma-separated constant values (with no spaces!) may be used to specifiy a different multiplier for each channel in the image, respectively. \apiend \apiitem{--chsum} Replaces the top image by a copy that contains only 1 color channel, whose value at each pixel is the sum of all channels of the original image. Using the optional {\cf weight} allows you to customize the weight of each channel in the sum. \begin{tabular}{p{10pt} p{1in} p{3.5in}} & {\cf weight=}\emph{r,g,...} & Specify the weight of each channel (default: 1). \end{tabular} \noindent Example: \begin{code} oiiotool RGB.tif --chsum:weight=.2126,.7152,.0722 -o luma.tif \end{code} \apiend \apiitem{--paste {\rm \emph{location}}} Takes two images -- the first is the ``foreground'' and the second is the ``background'' -- and uses the pixels of the foreground to replace those of the backgroud beginning at the upper left \emph{location} (expressed as {\cf +}\emph{xpos}{\cf +}\emph{ypos}, e.g., {\cf +100+50}, or of course using {\cf -} for negative offsets). \apiend \apiitem{--mosaic {\rm \emph{size}}} Removes \emph{w}{\cf x}\emph{h} images, dictated by the \emph{size}, and turns them into a single image mosaic. Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.5in}} & {\cf pad=}\emph{num} & Select the number of pixels of black padding to add between images (default: 0). \end{tabular} \noindent Examples: \begin{code} oiiotool left.tif right.tif --mosaic:pad=16 2x1 -o out.tif oiiotool 0.tif 1.tif 2.tif 3.tif 4.tif --mosaic:pad=16 2x2 -o out.tif \end{code} \apiend \apiitem{--over} \index{composite} Replace the \emph{two} top images with a new image that is the Porter/Duff ``over'' composite with the first image as the foreground and the second image as the background. Both input images must have the same number and order of channels and must contain an alpha channel. \apiend \apiitem{--zover} \index{depth composite} Replace the \emph{two} top images with a new image that is a \emph{depth composite} of the two images -- the operation is the Porter/Duff ``over'' composite, but each pixel individually will choose which of the two images is the foreground and which background, depending on the ``Z'' channel values for that pixel (larger Z means farther away). Both input images must have the same number and order of channels and must contain both depth/Z and alpha channels. Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.5in}} & {\cf zeroisinf=}\emph{num} & If nonzero, indicates that $z=0$ pixels should be treated as if they were infinitely far away. (The default is 0, meaning that ``zero means zero.''). \end{tabular} \apiend \apiitem{--flip} Replace the current image with a new image that is flipped vertically, with the top scanline becoming the bottom, and vice versa. \apiend \apiitem{--flop} Replace the current image with a new image that is flopped horizontally, with the leftmost column becoming the rightmost, and vice versa. \apiend \apiitem{--flipflop} Replace the current image with a new image that is both flipped and flopped, which is the same as a 180 degree rotation. \apiend \apiitem{--transpose} Replace the current image with a new image that is trasposed about the $xy$ axis (x and coordinates and size are flipped). \apiend \apiitem{--cshift {\rm \emph{offset}}} Circularly shift the pixels of the image by the given offset (expressed as {\cf +10+100} to move by 10 pixels horizontally and 100 pixels vertically, or {\cf +50-30} to move by 50 pixels horizontally and $-30$ pixels vertically. \emph{Circular} shifting means that the pixels wrap to the other side as they shift. \apiend \apiitem{--crop {\rm \emph{size}}} Replace the current image with a new copy with the given \emph{size}, cropping old pixels no longer needed, padding black pixels where they previously did not exist in the old image, and adjusting the offsets if requested. The size is in the form \\ \spc\spc \emph{width}\,{\cf x}\,\emph{height}{\cf [+-]}\emph{xoffset}{\cf [+-]}\emph{yoffset} \\ or~~~~ \spc \emph{xmin,ymin,xmax,ymax} \\ \noindent Examples: \begin{tabular}{p{2in} p{4in}} {\cf --crop 100x120+35+40} & resolution w=100, h=120, offset x=35, y=40 \\ {\cf --crop 35,40,134,159} & resolution w=100, h=120, offset x=35, y=40 \end{tabular} \apiend \apiitem{--croptofull} Replace the current image with a new image that is ropped or padded as necessary to make the pixel data window exactly cover the full/display window. \apiend \apiitem{--resample {\rm \emph{size}}} Replace the current image with a new image that is resampled to the given pixel data resolution rapidly, but at a low quality, by simply copying the ``closest'' pixel. The \emph{size} is in the form \\ \spc\spc \emph{width}\,{\cf x}\,\emph{height} \\ or~~~~ \spc \emph{scale}{\verb|%|} \\ \noindent Examples: \begin{tabular}{p{2in} p{4in}} {\cf --resample 1024x768} & new resolution w=100, h=120 \\ {\cf --resample 50{\verb|%|}} & reduce resolution to 50\verb|%| \\ {\cf --resample 300{\verb|%|}} & increase resolution by 3x \end{tabular} \apiend \apiitem{--resize {\rm \emph{size}}} Replace the current image with a new image that is resized to the given pixel data resolution. The \emph{size} is in the form \\ \spc\spc \emph{width}\,{\cf x}\,\emph{height} \\ or~~~~ \spc \emph{scale}{\verb|%|} \\ Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.75in}} & {\cf filter=}\emph{name} & Filter name. The default is {\cf blackman-harris} when increasing resolution, {\cf lanczos3} when decreasing resolution. \\ \end{tabular} \noindent Examples: \begin{tabular}{p{2in} p{4in}} {\cf --resize 1024x768} & new resolution w=100, h=120 \\ {\cf --resize 50{\verb|%|}} & reduce resolution to 50\verb|%| \\ {\cf --resize 300{\verb|%|}} & increase resolution by 3x \end{tabular} \apiend \apiitem{--fit {\rm \emph{size}}} Replace the current image with a new image that is resized to fit into the given pixel data resolution, keeping the original aspect ratio and padding with black pixels if the requested image size does not have the same aspect ratio. The \emph{size} is in the form \\ \spc\spc \emph{width}\,{\cf x}\,\emph{height} \\ or~~~~ \spc \emph{width}\,{\cf x}\,\emph{height}{\cf [+-]}\emph{xorigin}{\cf [+-]}\emph{yorigin} \\ Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.75in}} & {\cf filter=}\emph{name} & Filter name. The default is {\cf blackman-harris} when increasing resolution, {\cf lanczos3} when decreasing resolution. \\ & {\cf pad=}\emph{p} & If the argument is nonzero, will pad with black pixels to make the resulting image exactly the size specified, if the source and desired size are not the same aspect ratio. \end{tabular} \noindent Examples: \begin{code} oiiotool in.exr --fit:pad=1 640x480 -o out.exr oiiotool in.exr --fit 1024x1024 -o out.exr \end{code} \apiend \apiitem{--convolve} Use the top image as a kernel to convolve the next image farther down the stack, replacing both with the result. \noindent Examples: \begin{code} # Use a kernel image already prepared oiiotool image.exr kernel.exr --convolve -o output.exr # Construct a kernel image on the fly with --kernel oiiotool image.exr --kernel gaussian 5x5 --convolve -o blurred.exr \end{code} \apiend \apiitem{--blur {\rm \emph{size}}} Blur the top image with a blur kernel of the given size expressed as \emph{width}{\cf x}\emph{height}. (The sizes may be floating point numbers.) Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.75in}} & {\cf kernel=}\emph{name} & Kernel name. The default is {\cf gaussian}. \end{tabular} \noindent Examples: \begin{code} oiiotool image.jpg --blur 5x5 -o blurred.jpg oiiotool image.jpg --blur:kernel=bspline 7x7 -o blurred.jpg \end{code} \apiend \apiitem{--unsharp} Unblur the top image using an ``unsharp mask.'' Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.75in}} & {\cf kernel=}\emph{name} & Name of the blur kernel (default: {\cf gaussian}). \\ & {\cf width=}\emph{w} & Width of the blur kernel (default: 3). \\ & {\cf contrast=}\emph{c} & Contrast scale (default: 1.0) \\ & {\cf threshold=}\emph{t} & Threshold for applying the difference (default: 0) \end{tabular} \noindent Examples: \begin{code} oiiotool image.jpg --unsharp -o sharper.jpg oiiotool image.jpg --unsharp:width=5:contrast=1.5 -o sharper.jpg \end{code} \apiend \apiitem{--fft \\ --ifft} Performs forward and inverse unitized discrete Fourier transform. The forward FFT always transforms only the first channel of the top image on the stack, and results in a 2-channel image (with real and imaginary channels). The inverse FFT transforms the first two channels of the top image on the stack (assuming they are real and imaginary, respectively) and results in a single channel result (with the real component only of the spatial domain result). \noindent Examples: \begin{code} # Select the blue channel and take its DCT oiiotool image.jpg --ch 2 --fft -o fft.exr # Reconstruct from the FFT oiiotool fft.exr --ifft -o reconstructed.exr # Output the power spectrum: real^2 + imag^2 oiiotool fft.exr --dup --mul --chsum -o powerspectrum.exr \end{code} \apiend \apiitem{--fixnan {\rm \emph{streategy}}} Replace the top image with a copy in which any pixels that contained {\cf NaN} or {\cf Inf} values (hereafter referred to collectively as ``nonfinite'') are repaired. If \emph{strategy} is {\cf black}, nonfinite values will be replaced with {\cf 0}. If \emph{strategy} is {\cf box3}, nonfinite values will be replaced by the average of all the finite values within a $3 \times 3$ region surrounding the pixel. \apiend \apiitem{--clamp} Replace the top image with a copy in which pixel values have been clamped. Optional arguments include: Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.75in}} & {\cf min=}\emph{val} & Specify a minimum value for all channels. \\ & {\cf min=}\emph{val0,val1,...} & Specify minimum value for each channel individually. \\ & {\cf max=}\emph{val} & Specify a maximum value for all channels. \\ & {\cf max=}\emph{val0,val1,...} & Specify maximum value for each channel individually. \\ & {\cf clampalpha=}\emph{val} & If \emph{val} is nonzero, will additionally clamp the alpha channel to [0,1]. (Default: 0, no additional alpha clamp.) \end{tabular} If no value is given for either the minimum or maximum, it will NOT clamp in that direction. For the variety of minimum and maximum that specify per-channel values, a missing value indicates that the corresponding channel should not be clamped. \noindent Examples: \begin{tabular}{p{2in} p{4in}} {\cf --clamp:min=0} & Clamp all channels to a mimimum of 0 (all \\ & negative values are changed to 0). \\ {\cf --clamp:min=0:max=1} & Clamp all channels to [0,1]. \\ {\cf --clamp:clampalpha=1} & Clamp the designated alpha channel to [0,1]. \\ {\cf --clamp:min=,,0:max=,,3.0} & Clamp the third channel to [0,3], do not clamp \\ & other channels. \end{tabular} \apiend \apiitem{--rangecompress \\ --rangeexpand} Range compression re-maps input values to a logarithmic scale. Range expansion is the inverse mapping back to a linear scale. Range compression and expansion only applies to color channels; alpha or z channels will not be modified. By default, this transformation will happen to each color channel independently. But if the optional {\cf luma} argument is nonzero and the image has at least 3 channels and the first three channels are not alpha or depth, they will be assumed to be RGB and the pixel scaling will be done using the luminance and applied equally to all color channels. This can help to preserve color even when remapping intensity. Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.75in}} & {\cf luma=}\emph{val} & If \emph{val} is 0, turns off the luma behavior. \end{tabular} Range compression and expansion can be useful in cases where high contrast super-white ($> 1$) pixels (such as very bright highlights in HDR captured or rendered images) can produce undesirable artifacts, such as if you resize an HDR image using a filter with negative lobes -- which could result in objectionable ringing or even negative result pixel values. For example, \begin{smallcode} oiiotool hdr.exr --rangecompress --resize 512x512 --rangeexpand -o resized.exr \end{smallcode} \apiend \apiitem{--fillholes} Replace the top image with a copy in which any pixels that had $\alpha < 1$ are ``filled'' in a smooth way using data from surrounding $\alpha > 0$ pixels, resulting in an image that is $\alpha = 1$ and plausible color everywhere. This can be used both to fill internal ``holes'' as well as to extend an image out. \apiend \apiitem{--text {\rm \emph{words}}} Draw (rasterize) text overtop of the current image. \begin{tabular}{p{10pt} p{1in} p{3.75in}} & {\cf x=}\emph{xpos} & $x$ position (in pixel coordinates) of the text \\ & {\cf y=}\emph{ypos} & $y$ position (in pixel coordinates) of the text \\ & {\cf size=}\emph{size} & font size (height, in pixels) \\ & {\cf font=}\emph{name} & font name, full path to the font file on disk (use double quotes {\cf "name"} if the path name includes spaces) \\ & {\cf color=}\emph{r,g,b,...} & specify the color of the text \\ \end{tabular} The default positions the text starting at the center of the image, drawn 16 pixels high in opaque white in all channels (1,1,1,...), and using a default font (which may be system dependent). \noindent Examples: \begin{code} oiiotool in.exr --text:x=10:y=400:size=40 "Hello world" -o out.exr \end{code} \apiend \section{\oiiotool commands for color management} \apiitem{--iscolorspace {\rm \emph{colorspace}}} Alter the metadata of the current image so that it thinks its pixels are in the named color space. This does not alter the pixels of the image, it only changes \oiiotool's understanding of what color space those those pixels are in. \apiend \apiitem{--colorconvert {\rm \emph{fromspace tospace}}} Replace the current image with a new image whose pixels are transformed from the named \emph{fromspace} color space into the named \emph{tospace} (disregarding any notion it may have previously had about the color space of the current image). If OIIO has been compiled with OpenColorIO support and the environment variable {\cf \$OCIO} is set to point to a valid OpenColorIO configuration file, you will have access to all the color spaces that are known by that OCIO configuration. If {\cf \$OCIO} does not point to a valid configuration file or OIIO was not compiled with OCIO support, then the only color space transformats available are {\cf linear} to {\cf Rec709} (and vice versa) and {\cf linear} to {\cf sRGB} (and vice versa). If you ask for \oiiotool help ({\cf oiiotool --help}), at the very bottom you will see the list of all color spaces that \oiiotool knows about. \apiend \apiitem{--tocolorspace {\rm \emph{tospace}}} Replace the current image with a new image whose pixels are transformed from their existing color space (as best understood or guessed by OIIO) into the named \emph{tospace}. This is equivalent to a use of {\cf oiiotool --colorconvert} where the \emph{fromspace} is automatically deduced. \apiend \apiitem{--ociolook {\rm \emph{lookname}}} Replace the current image with a new image whose pixels are transformed using the named OpenColorIO look description. Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.75in}} & {\cf from=}\emph{val} & Assume the image is in the named color space. If no {\cf from=} is supplied, it will try to deduce it from the image's metadata or previous {\cf --iscolorspace} directives. \\ & {\cf to=}\emph{val} & Convert to the named space after applying the look. \\ & {\cf inverse=}\emph{val} & If \emph{val} is nonzero, inverts the color transformation and look application. \\ & {\cf key=}\emph{name} & \\ & {\cf value=}\emph{str} & Adds a key/value pair to the ``context'' that OpenColorIO will used when applying the look. \\ \end{tabular} This command is only meaningful if OIIO was compiled with OCIO support and the environment variable {\cf \$OCIO} is set to point to a valid OpenColorIO configuration file. If you ask for \oiiotool help ({\cf oiiotool --help}), at the very bottom you will see the list of all looks that \oiiotool knows about. \noindent Examples: \begin{tinycode} oiiotool in.jpg --ociolook:from=vd8:to=vd8:key=SHOT:value=pe0012 match -o cc.jpg \end{tinycode} \apiend \apiitem{--ociodisplay {\rm \emph{displayname viewname}}} Replace the current image with a new image whose pixels are transformed using the named OpenColorIO ``display'' transformation given by the \emph{displayname} and \emph{viewname}. Optional appended arguments include: \begin{tabular}{p{10pt} p{1in} p{3.75in}} & {\cf from=}\emph{val} & Assume the image is in the named color space. If no {\cf from=} is supplied, it will try to deduce it from the image's metadata or previous {\cf --iscolorspace} directives. \\ & {\cf key=}\emph{name} & \\ & {\cf value=}\emph{str} & Adds a key/value pair to the ``context'' that OpenColorIO will used when applying the look. \\ \end{tabular} This command is only meaningful if OIIO was compiled with OCIO support and the environment variable {\cf \$OCIO} is set to point to a valid OpenColorIO configuration file. If you ask for \oiiotool help ({\cf oiiotool --help}), at the very bottom you will see the list of all looks that \oiiotool knows about. \noindent Examples: \begin{tinycode} oiiotool in.exr --ociodisplay:from=lnf:key=SHOT:value=pe0012 sRGB Film -o cc.jpg \end{tinycode} \apiend \apiitem{--unpremult} Divide all color channels (those not alpha or z) of the current image by the alpha value, to ``un-premultiply'' them. This presumes that the image starts of as ``associated alpha,'' a.k.a.\ ``premultipled.'' Pixels in which the alpha channel is 0 will not be modified (since the operation is undefined in that case). This is a no-op if there is no identified alpha channel. \apiend \apiitem{--premult} Multiply all color channels (those not alpha or z) of the current image by the alpha value, to ``premultiply'' them. This presumes that the image starts of as ``unassociated alpha,'' a.k.a.\ ``non-premultipled.'' \apiend openimageio-1.3.12~dfsg0.orig/src/doc/moreverb.sty0000644000175000017500000001330512271062644020241 0ustar mfvmfv%% %% This is file `moreverb.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% moreverb.dtx (with options: `moreverb') %% %% Copyright Robin Fairbairns, 1997 2002 %% %% This file is distributed under the terms of the latex project public %% licence (LPPL: see CTAN macros/latex/base/lppl.txt), version 1.2 or %% (at your convenience) any later version. %% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{moreverb} [2008/06/03 v2.3 `more' verbatim facilities% ] \@ifundefined{verbatim@processline}{\RequirePackage{verbatim}}{} \newwrite \verbatim@out \def\verbatimwrite#1{% \@bsphack \immediate\openout \verbatim@out #1 \let\do\@makeother\dospecials \catcode`\^^M\active \catcode`\^^I=12 \def\verbatim@processline{% \immediate\write\verbatim@out {\the\verbatim@line}}% \verbatim@start} \def\endverbatimwrite{% \immediate\closeout\verbatim@out \@esphack} \newcount\tab@position \newcount\tab@size \def\verbatimtabsize{8\relax} \def\@xobeytab{% \loop \toks@\expandafter{\the\toks@\@xobeysp}% \advance\tab@position-1 \ifnum\tab@position>0 \repeat } \begingroup \catcode`\^^I=\active \gdef\@vobeytabs{\catcode`\^^I\active\let^^I\@xobeytab}% \endgroup \def\verbatim@tabexpand#1{% \ifx#1\@nil \the\toks@ \expandafter\par \else \ifx#1\@xobeytab \@xobeytab \else \toks@\expandafter{\the\toks@#1}% \advance\tab@position\m@ne \fi \ifnum\tab@position=0 \tab@position\tab@size \fi \expandafter\verbatim@tabexpand \fi } \newcount\listing@line \listing@line=1 \def\listing@step{1\relax} \def\listinglabel#1{\llap{\small\rmfamily\the#1}\hskip\listingoffset\relax} \def\thelisting@line{% \setbox0\hbox{\listinglabel\listing@line}% \@tempcnta=\listing@line \divide\@tempcnta\listing@step \multiply\@tempcnta\listing@step \ifnum\listing@line=\@ne \unhbox0 \else \ifnum\@tempcnta=\listing@line \unhbox0 \else \hskip\wd0 \fi \fi} \providecommand\listingoffset{1.5em} \newcommand\listing[2][1]{% \global\listing@line=#2\relax \gdef\listing@step{#1\relax} \listingcont} \def\listingcont{% \tab@size=\verbatimtabsize \def\verbatim@processline{\tab@position\tab@size \thelisting@line \global\advance\listing@line1 \toks@{}% \expandafter\verbatim@tabexpand\the\verbatim@line\@nil}% \@verbatim\frenchspacing\@vobeyspaces\@vobeytabs\verbatim@start} \let\endlisting=\endtrivlist \let\endlistingcont=\endtrivlist \expandafter\newcommand\csname listing*\endcsname[2][1]{% \global\listing@line=#2\relax \gdef\listing@step{#1\relax} \csname listingcont*\endcsname} \@namedef{listingcont*}{% \def\verbatim@processline{% \thelisting@line \global\advance\listing@line1 \the\verbatim@line\par}% \@verbatim\verbatim@start} \expandafter\let\csname endlisting*\endcsname\endtrivlist \expandafter\let\csname endlistingcont*\endcsname\endtrivlist \def\listinginput{% \@ifnextchar[%] {\@listinginput}% {\@listinginput[1]}} \begingroup \catcode`\~=\active \lccode`\~=`\^^M \lccode`\N=`\N \lowercase{\endgroup \def\@listinginput[#1]#2#3{\begingroup \global\listing@line=#2 \gdef\listing@step{#1\relax} \tab@size=\verbatimtabsize \def\verbatim@processline{\tab@position\tab@size \thelisting@line \global\advance\listing@line1 \toks@{}% \expandafter\verbatim@tabexpand\the\verbatim@line\@nil}% \@verbatim\frenchspacing\@vobeyspaces\@vobeytabs \def\verbatim@addtoline##1~{% \verbatim@line\expandafter{\the\verbatim@line##1}}% \openin\verbatim@in@stream=#3 \ifeof\verbatim@in@stream \PackageWarning{moreverb}{No file #3.}% \else \do@verbatimtabinput \closein\verbatim@in@stream \fi \endtrivlist\endgroup \@doendpe }% } \def\verbatimcmd{% \PackageError{moreverb}{The verbatimcmd environment is obsolete}% {Use alltt (from the LaTeX required package alltt) in place of verbatimcmd}% } \let\endverbatimcmd\relax \def\boxedverbatim{% \def\verbatim@processline{% {\setbox0=\hbox{\the\verbatim@line}% \hsize=\wd0 \the\verbatim@line\par}}% \@minipagetrue % DPC \@tempswatrue % DPC \@totalleftmargin\z@ % MH \setbox0=\vbox\bgroup \verbatim } \def\endboxedverbatim{% \endverbatim \unskip\setbox0=\lastbox % DPC \egroup \fbox{\box0}% } \newenvironment{verbatimtab}{\obeylines\@verbatimtab}{\endtrivlist} \newcommand\@verbatimtab[1][\verbatimtabsize]{% \do@verbatimtab{#1}{% \@verbatim\frenchspacing\@vobeyspaces\@vobeytabs\verbatim@start}% } \def\do@verbatimtab#1#2{% \tab@size=#1 \def\verbatim@processline{\tab@position\tab@size \toks@{}% \expandafter\verbatim@tabexpand\the\verbatim@line\@nil}% #2% } \def\verbatimtabinput{% \@ifnextchar[%] {\@verbatimtabinput}% {\@verbatimtabinput[\verbatimtabsize]}} \begingroup \catcode`\~=\active \lccode`\~=`\^^M \lccode`\N=`\N \lowercase{\endgroup \def\@verbatimtabinput[#1]#2{\begingroup \do@verbatimtab{#1}{% \@verbatim\frenchspacing\@vobeyspaces\@vobeytabs}% \def\verbatim@addtoline##1~{% \verbatim@line\expandafter{\the\verbatim@line##1}}% \openin\verbatim@in@stream=#2 \ifeof\verbatim@in@stream \PackageWarning{moreverb}{No file #2.} \else \@addtofilelist{#2}% \do@verbatimtabinput \closein\verbatim@in@stream \fi \endtrivlist\endgroup\@doendpe}% } \def\do@verbatimtabinput{% \read\verbatim@in@stream to \verbtab@line \ifeof\verbatim@in@stream \else \expandafter\verbatim@addtoline\verbtab@line \verbatim@processline \verbatim@startline \expandafter\do@verbatimtabinput \fi } \endinput %% %% End of file `moreverb.sty'. openimageio-1.3.12~dfsg0.orig/src/doc/macros.tex0000644000175000017500000001232212271062644017663 0ustar mfvmfv%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Larry's favorite LaTeX macros for making technical books. These have % been refined for years, starting with SIGGRAPH course notes in the % '90's, further refined for _Advanced RenderMan_. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Define typesetting commands for filenames and code % % Just like Advanced RenderMan -- all code in courier, keywords in text % courier but not bold. \def\codefont{\ttfamily} % font to use for code \def\ce{\codefont\bfseries} % emphasize something in code % % Define typesetting commands for filenames and code % \def\cf{\codefont} % abbreviation for \codefont \def\fn{\codefont} % in-line filenames & unix commands \def\kw{\codefont} % in-line keyword \newcommand{\var}[1]{{\kw \emph{#1}}} % variable \newcommand{\qkw}[1]{{\kw "#1"}} % quoted keyword \newcommand{\qkws}[1]{{\small \kw "#1"}} % quoted keyword, small \newcommand{\qkwf}[1]{{\footnotesize \kw "#1"}} % quoted keyword, tiny % Define some environments for easy typesetting of small amounts of % code. These are mostly just wrappers around verbatim, but the % different varieties also change font sizes. \newenvironment{code}{\small \verbatimtab}{\endverbatimtab} \newenvironment{smallcode}{\small \renewcommand{\baselinestretch}{0.8} \verbatimtab}{\endverbatimtab \renewcommand{\baselinestretch}{1}} \newenvironment{tinycode}{\footnotesize \renewcommand{\baselinestretch}{0.75} \verbatimtab}{\endverbatimtab \renewcommand{\baselinestretch}{1}} \begin{htmlonly} \renewenvironment{code}{\begin{verbatim}}{\end{verbatim}} \newenvironment{smallcode}{\begin{verbatim}}{\end{verbatim}} \newenvironment{tinycode}{\begin{verbatim}}{\end{verbatim}} \end{htmlonly} \newcommand{\includedcode}[1]{{\small \verbatimtabinput{#1}}} \newcommand{\smallincludedcode}[1]{{\small \renewcommand{\baselinestretch}{0.8} \verbatimtabinput{#1} \renewcommand{\baselinestretch}{1}}} \newcommand{\tinyincludedcode}[1]{{\footnotesize \renewcommand{\baselinestretch}{0.75} \verbatimtabinput{#1} \renewcommand{\baselinestretch}{1}}} % Also create a hyphenation list, essentially just to guarantee that % type names aren't hyphenated %\hyphenation{Attribute} % Handy for parameter lists \def\pl{\emph{parameterlist}\xspace} \def\epl{\emph{...parameterlist...}\xspace} \hyphenation{parameterlist} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Defs of variables and functions that we frequently refer to in % text. % \def\ParamType{{\kw ParamType}\xspace} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %begin{latexonly} \newenvironment{apilist}{\begin{list}{}{\medskip \item[]}}{\end{list}} \newcommand{\apiitem}[1]{\vspace{12pt} \noindent {\bf\tt #1} \vspace{-10pt}\begin{apilist}\nopagebreak[4]} \newcommand{\apiend}{\end{apilist}\medskip\pagebreak[2]} \def\bigspc{\makebox[72pt]{}} \def\spc{\makebox[24pt]{}} \def\halfspc{\makebox[12pt]{}} \def\neghalfspc{\hspace{-12pt}} \def\negspc{\hspace{-24pt}} \def\chapwidthbegin{} \def\chapwidthend{} %end{latexonly} \begin{htmlonly} \newcommand{\apiitem}[1]{\medskip \noindent {\bf #1} \begin{quote}} \newcommand{\apiend}{\end{quote}} \def\halfspc{\begin{rawhtml}     \end{rawhtml}} \def\spc{\halfspc\halfspc} \pagecolor[named]{White} \def\chapwidthbegin{\begin{rawhtml}

\end{rawhtml}} \def\chapwidthend{\begin{rawhtml}
\end{rawhtml}} \end{htmlonly} \newcommand{\apibinding}[3]{\apiitem{#1\\[1ex]#2\\[1ex]#3}} \newcommand{\CPPBINDING}[1]{\par {\small C++ BINDING:}\par {\spc \codefont #1}} \newcommand{\PARAMETERS}{\par {\small PARAMETERS:} \par} \newcommand{\EXAMPLE}{\par {\small EXAMPLE:} \par} \newcommand{\EXAMPLES}{\par {\small EXAMPLES:} \par} \newcommand{\SEEALSO}{\par \hspace{-20pt} See Also: \par} % The \begin{algorithm} \end{algorithm} macros (in algorithm.sty) are % great for code that can fit all on one page. But when it can't, use % these macros. The first parameter is the caption, the second is the % label name. \newcommand{\longalgorithmbegin}[2]{\noindent\hrulefill \\ \refstepcounter{algorithm} \noindent {\bf Listing \arabic{chapter}.\arabic{algorithm}}: #1 \label{#2} \\ \addcontentsline{loa}{algorithm}{\numberline {\arabic{algorithm}} #1} \noindent\hrulefill } \newcommand{\longalgorithmend}{\noindent\hrulefill \\} \def\NEW{\marginpar[\medskip\hfill~\fbox{\sffamily \Huge NEW!}~]{\medskip~\fbox{\sffamily \Huge NEW!}~}} \newcommand{\NEWdown}[1]{\marginpar[\vspace{#1}\hfill\fbox{\sffamily \Huge NEW!}]{\vspace{#1}\fbox{\sffamily \Huge NEW!}}} \def\DEPRECATED{\marginpar[\medskip\hfill~\fbox{\sffamily \Large Deprecated}]{\medskip~\fbox{\sffamily \Large Deprecated}}} \newcommand{\DEPRECATEDdown}[1]{\marginpar{\vspace{#1}\fbox{\sffamily \Large Deprecated}}} \def\CHANGED{\marginpar[\medskip\hfill~\fbox{\sffamily \huge CHANGED!}~]{\medskip~\fbox{\sffamily \huge CHANGED!}~}} \def\ENHANCED{\marginpar[\medskip\hfill~\fbox{\sffamily \huge ENHANCED}~]{\medskip~\fbox{\sffamily \huge ENHANCED}~}} \newcommand{\indexapi}[1]{\index{#1@\tt#1\rm}} \newenvironment{annotate}{\medskip\sffamily\em\noindent}{\medskip} %\newenvironment{annotate}{\begin{comment}}{\end{comment}} openimageio-1.3.12~dfsg0.orig/src/doc/Description.txt0000644000175000017500000000100212271062644020672 0ustar mfvmfvOpenImageIO consists of: * Simple APIs for reading and writing image files in a format-agnostic manner, and plugins to read many common image formats including TIFF, JPEG, OpenEXR, PNG, HDR, ICO, and BMP. * Image utilities, including an image viewer, printing image information, format conversion, image comparison, and others. * A library for image texture lookups, and a managed image cache that allows an application to access hundreds of GB of image data using little runtime RAM. openimageio-1.3.12~dfsg0.orig/src/doc/openimageio.tex0000644000175000017500000001115512271062644020676 0ustar mfvmfv\documentclass[11pt,letterpaper]{book} \setlength{\oddsidemargin}{0.5in} \setlength{\topmargin}{0in} \setlength{\evensidemargin}{0.3in} \setlength{\textwidth}{5.75in} \setlength{\textheight}{8.5in} %\setlength{\oddsidemargin}{1.25in} %\setlength{\evensidemargin}{0.5in} % don't do this \usepackage{times} % Better fonts than Computer Modern %\usepackage{times} \renewcommand{\sfdefault}{phv} \renewcommand{\rmdefault}{ptm} % don't replace tt -- old is better \renewcommand{\ttdefault}{pcr} %\usepackage{apalike} %\usepackage{pslatex} \usepackage{techref} %\usepackage{epsfig} \usepackage{verbatim} \usepackage{moreverb} \usepackage{graphicx} \usepackage{xspace} %\usepackage{multicol} %\usepackage{color} \usepackage{html} \usepackage{array} \usepackage{multirow} \usepackage{longtable} %\usepackage{version} \usepackage{makeidx} %\usepackage{showidx} \usepackage[chapter]{algorithm} \floatname{algorithm}{Listing} \usepackage{syntax} \usepackage{fancyhdr} \pagestyle{fancy} \fancyhead[LE,RO]{\bfseries\thepage} \fancyhead[LO]{\bfseries\rightmark} \fancyhead[RE]{\bfseries\leftmark} \fancyfoot[C]{\bfseries OpenImageIO Programmer's Documentation} \renewcommand{\footrulewidth}{1pt} \def\product{{\sffamily OpenImageIO}\xspace} \def\OpenImageIO{{\sffamily OpenImageIO}\xspace} \def\versionnumber{1.3} \def\productver{\product\ {\sffamily \versionnumber}\xspace} \def\producthome{{\codefont \$IMAGEIOHOME}\xspace} \def\ivbinary{{\codefont iv}\xspace} \def\maketx{{\codefont maketx}\xspace} \def\iconvert{{\codefont iconvert}\xspace} \def\idiff{{\codefont idiff}\xspace} \def\iinfo{{\codefont iinfo}\xspace} \def\igrep{{\codefont igrep}\xspace} \def\oiiotool{{\codefont oiiotool}\xspace} \def\ImageSpec{{\codefont ImageSpec}\xspace} \def\ImageInput{{\codefont ImageInput}\xspace} \def\ImageOutput{{\codefont ImageOutput}\xspace} \def\ParamBaseType{{\codefont ParamBaseType}\xspace} \def\TypeDesc{{\codefont TypeDesc}\xspace} \def\ParamValue{{\codefont ParamValue}\xspace} \def\ParamValueList{{\codefont ParamValueList}\xspace} \def\ImageBuf{{\codefont ImageBuf}\xspace} \def\ImageCache{{\codefont ImageCache}\xspace} \def\TextureSystem{{\codefont TextureSystem}\xspace} \def\ROI{{\codefont ROI}\xspace} \def\IBA{{\codefont ImageBufAlgo}\xspace} \def\NULL{{\codefont NULL}\xspace} %\def\opencall{{\codefont open()}\xspace} \def\writeimage{{\codefont write\_image()}\xspace} \def\writescanline{{\codefont write\_scanline()}\xspace} \def\writetile{{\codefont write\_tile()}\xspace} \def\readimage{{\codefont read\_image()}\xspace} \def\readscanline{{\codefont read\_scanline()}\xspace} \def\readtile{{\codefont read\_tile()}\xspace} \def\AutoStride{{\codefont AutoStride}\xspace} \title{ {\Huge{\bf \product} %\textregistered\ {\bf\sffamily \versionnumber} \medskip \\ \huge Programmer Documentation \\ % \large (in progress) } \bigskip } \author{Editor: Larry Gritz \\ \emph{lg@openimageio.org} \bigskip \\ } \date{{\large %Editor: Larry Gritz \\[2ex] Date: 14 Nov 2013 \\ (with corrections, 2 Jan 2014) }} \include{macros} \makeindex \begin{document} \frontmatter \maketitle \include{copyr} \vspace*{2in} \begin{centering} \emph{I kinda like ``Oy-e-oh'' with a bit of a groaning Yiddish accent, as in\\ ``OIIO, did you really write yet another file I/O library?''} \\ \end{centering} \medskip \begin{centering} \center Dan Wexler \\ \end{centering} \setcounter{tocdepth}{1} \tableofcontents \mainmatter \include{oiiointro} \part{The OpenImageIO Library} \include{imageioapi} \include{imageoutput} \include{imageinput} \include{writingplugins} \include{builtinplugins} \include{imagecache} \include{texturesys} \include{imagebuf} \include{imagebufalgo} \include{pythonbindings} \part{Image Utilities} \include{oiiotool} \chapter{The {\kw iv} Image Viewer} \label{chap:iv} \indexapi{iv} The {\cf iv} program is a great interactive image viewer. Because {\cf iv} is built on top on \product, it can display images of any formats readable by \ImageInput plugins on hand. \medskip More documentation on this later. \include{iinfo} \include{iconvert} \include{igrep} \include{idiff} \include{maketx} \part{Appendices} \begin{appendix} %\include{typedesc} \chapter{Building OpenImageIO} \include{stdmetadata} %\include{header} \include{glossary} \end{appendix} \backmatter %\bibliographystyle{alpha} %% Select for [GH95] \bibliographystyle{apalike} %% Select for (Gritz and Hahn, 1995) %\addcontentsline{toc}{chapter}{Bibliography} %\bibliography{bmrtbib} \addcontentsline{toc}{chapter}{Index} \printindex \end{document} % Canonical figure %\begin{figure}[ht] %\noindent %\includegraphics[width=5in]{Figures/bredow/foo} %\caption{Caption %\label{fig:foo}} %\end{figure} openimageio-1.3.12~dfsg0.orig/src/doc/oiiointro.tex0000644000175000017500000003001212271062644020406 0ustar mfvmfv\chapter{Introduction} \label{chap:oiiointro} Welcome to \product! \bigskip \section{Overview} \product provides simple but powerful \ImageInput and \ImageOutput APIs that abstract the reading and writing of 2D image file formats. They don't support every possible way of encoding images in memory, but for a reasonable and common set of desired functionality, they provide an exceptionally easy way for an application using the APIs support a wide --- and extensible --- selection of image formats without knowing the details of any of these formats. Concrete instances of these APIs, each of which implements the ability to read and/or write a different image file format, are stored as plugins (i.e., dynamic libraries, DLL's, or DSO's) that are loaded at runtime. The \product distribution contains such plugins for several popular formats. Any user may create conforming plugins that implement reading and writing capabilities for other image formats, and any application that uses \product would be able to use those plugins. The library also implements the helper class {\kw ImageBuf}, which is a handy way to store and manipulate images in memory. {\kw ImageBuf} itself uses \ImageInput and \ImageOutput for its file I/O, and therefore is also agnostic as to image file formats. The {\kw ImageCache} class transparently manages a cache so that it can access truly vast amounts of image data (thousands of image files totaling hundreds of GB) very efficiently using only a tiny amount (tens of megabytes at most) of runtime memory. Additionally, a {\kw TextureSystem} class provides filtered MIP-map texture lookups, atop the nice caching behavior of {\kw ImageCache}. Finally, the \product distribution contains several utility programs that operate on images, each of which is built atop \ImageInput and \ImageOutput, and therefore may read or write any image file type for which an appropriate plugin is found at runtime. Paramount among these utilities is {\fn iv}, a really fantastic and powerful image viewing application. Additionally, there are programs for converting images among different formats, comparing image data between two images, and examining image metadata. All of this is released as ``open source'' software using the very permissive ``New BSD'' license. So you should feel free to use any or all of \product in your own software, whether it is private or public, open source or proprietary, free or commercial. You may also modify it on your own. You are encouraged to contribute to the continued development of \product and to share any improvements that you make on your own, though you are by no means required to do so. \section{Simplifying Assumptions} \product is not the only image library in the world. Certainly there are many fine libraries that implement a single image format (including the excellent {\fn libtiff}, {\fn jpeg-6b}, and {\fn OpenEXR} that \product itself relies on). Many libraries attempt to present a uniform API for reading and writing multiple image file formats. Most of these support a fixed set of image formats, though a few of these also attempt to provide an extensible set by using the plugin approach. But in our experience, these libraries are all flawed in one or more ways: (1) They either support only a few formats, or many formats but with the majority of them somehow incomplete or incorrect. (2) Their APIs are not sufficiently expressive as to handle all the image features we need (such as tiled images, which is critical for our texture library). (3) Their APIs are \emph{too complete}, trying to handle every possible permutation of image format features, and as a result are horribly complicated. The third sin is the most severe, and is almost always the main problem at the end of the day. Even among the many open source image libraries that rely on extensible plugins, we have not found one that is both sufficiently flexible and has APIs anywhere near as simple to understand and use as those of \product. Good design is usually a matter of deciding what \emph{not} to do, and \product is no exception. We achieve power and elegance only by making simplifying assumptions. Among them: \begin{itemize} \item \product only deals with ordinary 2D images, and to a limited extent 3D volumes, and image files that contain multiple (but finite) independent images within them. \product {\bf~ does not deal with motion picture files.} At least, not currently. \item Pixel data are 8- 16- or 32-bit int (signed or unsigned), 16- 32- or 64-bit float. NOTHING ELSE. No $<8$ bit images, or pixels boundaries that aren't byte boundaries. Files with $<8$ bits will appear to the client as 8-bit unsigned grayscale images. \item Only fully elaborated, non-compressed data are accepted and returned by the API. Compression or special encodings are handled entirely within an \product plugin. \item Color space is grayscale or RGB. Non-spectral data, such as XYZ, CMYK, or YUV, are converted to RGB upon reading.\ \item All color channels can be treated (by apps or readers/writers) as having the same data format (though there is a way to deal with per-channel formats for apps and readers/writers that truly need it). \item All image channels in a subimage are sampled at the same resolution. For file formats that allow some channels to be subsampled, they will be automatically up-sampled to the highest resolution channel in the subimage. \item Color information is always in the order R, G, B, and the alpha channel, if any, always follows RGB, and z channel (if any) always follows alpha. So if a file actually stores ABGR, the plugin is expected to rearrange it as RGBA. \end{itemize} It's important to remember that these restrictions apply to data passed through the APIs, not to the files themselves. It's perfectly fine to have an \product plugin that supports YUV data, or 4 bits per channel, or any other exotic feature. You could even write a movie-reading \ImageInput (despite \product's claims of not supporting movies) and make it look to the client like it's just a series of images within the file. It's just that all the nonconforming details are handled entirely within the \product plugin and are not exposed through the main \product APIs. \subsection*{Historical Origins} \product is the evolution of concepts and tools I've been working on for two decades. In the 1980's, every program I wrote that output images would have a simple, custom format and viewer. I soon graduated to using a standard image file format (TIFF) with my own library implementation. Then I switched to Sam Leffler's stable and complete {\fn libtiff}. In the mid-to-late-1990's, I worked at Pixar as one of the main implementors of PhotoRealistic RenderMan, which had \emph{display drivers} that consisted of an API for opening files and outputting pixels, and a set of DSO/DLL plugins that each implement image output for each of a dozen or so different file format. The plugins all responded to the same API, so the renderer itself did not need to know how to the details of the image file formats, and users could (in theory, but rarely in practice) extend the set of output image formats the renderer could use by writing their own plugins. This was the seed of a good idea, but PRMan's display driver plugin API was abstruse and hard to use. So when I started Exluna in 2000, Matt Pharr, Craig Kolb, and I designed a new API for image output for our own renderer, Entropy. This API, called ``ExDisplay,'' was C++, and much simpler, clearer, and easier to use than PRMan's display drivers. NVIDIA's Gelato (circa 2002), whose early work was done by myself, Dan Wexler, Jonathan Rice, and Eric Enderton, had an API called ``ImageIO.'' ImageIO was \emph{much} more powerful and descriptive than ExDisplay, and had an API for \emph{reading} as well as writing images. Gelato was not only ``format agnostic'' for its image output, but also for its image input (textures, image viewer, and other image utilities). We released the API specification and headers (though not the library implementation) using the BSD open source license, firmly repudiating any notion that the API should be specific to NVIDIA or Gelato. For Gelato 3.0 (circa 2007), we refined ImageIO again (by this time, Philip Nemec was also a major influence, in addition to Dan, Eric, and myself\footnote{Gelato as a whole had many other contributors; those I've named here are the ones I recall contributing to the design or implementation of the ImageIO APIs}). This revision was not a major overhaul but more of a fine tuning. Our ideas were clearly approaching stability. But, alas, the Gelato project was canceled before Gelato 3.0 was released, and despite our prodding, NVIDIA executives would not open source the full ImageIO code and related tools. After I left NVIDIA, I was determined to recreate this work once again -- and ONLY once more -- and release it as open source from the start. Thus, \product was born. I started with the existing Gelato ImageIO specification and headers (which were BSD licensed all along), and made some more refinements since I had to rewrite the entire implementation from scratch anyway. I think the additional changes are all improvements. This is the software you have in your hands today. \subsection*{Acknowledgments} \begin{comment} The direct precursor to \product was Gelato's ImageIO, which was co-designed and implemented by Larry Gritz, Dan Wexler, Jonathan Rice, Eric Enderton, and Philip Nemec. Big thanks to our bosses at NVIDIA for allowing us to share the API spec and headers under the BSD license. And thanks to their inability to open source their own implementation in a timely manner, I was forced to create this clearly superior descendant. \end{comment} \product incorporates or depends upon several other open source packages: \begin{itemize} \item {\cf libtiff} \copyright\ 1988-1997 Sam Leffler and 1991-1997 Silicon Graphics, Inc. \\ {\cf http://www.remotesensing.org/libtiff} \item {\cf IJG libjpeg} \copyright\ 1991-1998, Thomas G. Lane. {\cf http://www.ijg.org} \item OpenEXR, Ilmbase, and Half \copyright\ 2006, Industrial Light \& Magic.\\ {\cf http://www.openexr.com} \item {\cf zlib} \copyright\ 1995-2005 Jean-loup Gailly and Mark Adler. {\cf http://www.zlib.net} \item {\cf libpng} \copyright\ 1998-2008 Glenn Randers-Pehrson, et al. {\cf http://www.libpng.org} \item Thread Building Blocks (TBB) \copyright\ 2005--2008 Intel Corporation.\\ {\cf http://www.threadingbuildingblocks.org/} \item The SHA-1 implemenation we use is public domain by Dominik Reichl \\ {\cf http://www.dominik-reichl.de/} \item Boost \copyright\ various authors. {\cf http://www.boost.org} \item GLEW \copyright\ 2002-2007 Milan Ikits, et al. {\cf http://glew.sourceforge.net} \item Jasper \copyright\ 2001-2006 Michael David Adams, et al. \\ {\cf http://www.ece.uvic.ca/~mdadams/jasper/} \item Squish \copyright\ 2006 Simon Brown. {\cf http://sjbrown.co.uk/?code=squish} \item PugiXML \copyright\ 2006-2009 by Arseny Kapoulkine (based on work \copyright 2003 Kristen Wegner). {\cf http://pugixml.org/} \item DPX reader/writer \copyright\ 2009 Patrick A.\ Palmer. {\cf http://code.google.com/p/dpx} \item Ptex \copyright\ 2009 Disney Enterprises, Inc. {\cf http://ptex.us} \item Field3D \copyright\ 2009 Sony Pictures Imageworks. {\cf http://sites.google.com/site/field3d/} \item {\cf tinyformat.h} \copyright\ 2011 Chris Foster. {\cf http://github.com/c42f/tinyformat} \item {\cf lookup3} code by Bob Jenkins, Public Domain. {\cf http://burtleburtle.net/bob/c/lookup3.c} \item {\cf xxhash} \copyright 2012 Yann Collet (BSD Licensed). {\cf http://code.google.com/p/xxhash/} \item {\cf KissFFT} \copyright 2003--2010 Mark Borgerding (BSD Licensed). {\cf http://sourceforge.net/projects/kissfft/} \item {\cf GIFLIB} \copyright 1997 Eric S. Raymond (MIT Licensed). % https://launchpad.net/ubuntu/precise/+source/giflib/+copyright {\cf http://giflib.sourceforge.net/} \end{itemize} These other packages are all distributed under licenses that allow them to be used by and distributed with \product. \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/copyr.tex0000644000175000017500000000412512271062644017535 0ustar mfvmfv\newpage \label{speccopyr} \vspace*{0.2in} \noindent The OpenImageIO source code and documentation are: \vspace*{0.2in} \noindent Copyright (c) 2008-2013 Larry Gritz, et al. All Rights Reserved. \vspace{0.5in} The code that implements OpenImageIO is licensed under the BSD 3-clause (also sometimes known as ``new BSD'' or ``modified BSD'') license: \vspace{0.25in} Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: \begin{itemize} \item Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \item Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \item Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. \end{itemize} THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \vspace{0.5in} This manual and other text documentation about OpenImageIO are licensed under the Creative Commons Attribution 3.0 Unported License. \\ \smallskip \spc \includegraphics[width=0.85in]{Figures/CC-30BY.png} \spc http://creativecommons.org/licenses/by/3.0/ \bigskip openimageio-1.3.12~dfsg0.orig/src/doc/notes.txt0000644000175000017500000001074612271062644017556 0ustar mfvmfvProposed menus: File New window ^N New tab ^T x Open ^O Open Recent Save ^S Save As... Save Window As... Save Selection As... x Reload x Close ^W Delete image on disk Preferences ^, x Quit ^Q Edit Cut (??? is this the same as clear?) Copy Paste Clear Region of Interest Prioritize Region of Interest Crop Region of Interest Select all images ^A Annotate Image ? View x Fit image (zoom to fill current window) x Fit window (adjust window to fit current zoom level of image) x Full screen x Channel mode (color, red, green, blue, alpha, luminance) View as depth, false, random x Zoom in x Zoom out x Stop up/down x Gamma up/down x Toggle last image Foreground/background images x Prev/next image x Prev/next subimage x Prev/next channel Subtract (image difference against last) Stereo mode Tools Mouse mode (zoom/pan, select, wipe) [ note: In zoom/pan mode, L/R click is zoom in/out, middle drag is pan, shift-drag is select. ] x Pixel view Thumbnails Hide controls Disconnect Overwrite render Store render Show error log Help --- Standard tags: int oiio:bitspersample - for the *file* -- may differ from what format implies) string compression - name of compression scheme to use string planarconfig - "separate" or "contiguous" string datetime - "yyyy:mm:dd hh:mm:ss" (TIFF DateTime, OpenEXR capDate) string copyright (TIFF Copyright, OpenEXR owner) [ should it be owner? ] string artist (TIFF Artist) string name (TIFF DocumentName) string host (TIFF HostName) string description (TIFF ImageDescription) string software (TIFF Software) string make (TIFF Make) string model (TIFF Model) string textureformat string wrapmodes matrix worldtocamera matrix worldtoscreen float fovcot int[nchannels] bitspersample ? - allow per-channel description? int xresolution (pixels per resolutionunit) int yresolution string resolutionunit ("none", "in", "cm") float pixelaspectratio int orientation ??? float aperture float exposuretime float fstop float focallength tiff-specific: tiff_Predictor tiff_RowsPerStrip tiff_SubfileType tiff_PhotometricInterpretation tiff_Planarconfig openexr-specific openexr_foo - arbitrary float, int, matrix, string exif_ShutterSpeedValue --- Assumptions about in-core image representation (NOT file!): * Pixel data are 8- 16- or 32-bit int (signed or unsigned), 16- 32- or 16-bit float. NOTHING ELSE. No <8 bit images, or pixels boundaries that aren't byte boundaries. Files with <8 bits will appear to the client as 8-bit unsigned grayscale images. * Color space is grayscale or RGB. XYZ, CMYK, YUV, or other non-spectral pixel data are converted to RGB upon reading. (Though you could write a custom ImageIO plugin that would preserve some other color space upon read, or convert to some other color space upon write.) * All color channels have the same data format. Upon read, an ImageInput ought to convert all channels to the one with the highest precision in the file. * All image channels in a subimage are sampled at the same resolution. For file formats that allow some channels to be subsampled, they will be automatically up-resed to the highest resolution channel in the subimage. * Color information is always in the order R, G, B, and the alpha channel, if any, always follows RGB, and z channel (if any) always follows alpha. So if a file actually stores ABGR, the plugin is expected to rearrange it as RGBA. --- operations zoom (in + out) (ctrl-+/-, alt-left mouse) drag/pan (always middle mouse) select (a rectangle) (shift-left mouse) draw (lines) info/pick selectors none shift ctrl alt buttons left right middle middle should always pan shift-left should always select alt-mouse should always zoom operations zoom (in + out) (ctrl-+/-, alt-left mouse) drag/pan (always middle mouse) select (a rectangle) (shift-left mouse) draw (lines) info/pick selectors none shift ctrl alt buttons left right middle middle should always pan shift-left should always select alt-mouse should always zoom openimageio-1.3.12~dfsg0.orig/src/doc/idiff.tex0000644000175000017500000002067612271062644017473 0ustar mfvmfv\chapter{Comparing Images With {\kw idiff}} \label{chap:idiff} \indexapi{idiff} \section{Overview} The {\cf idiff} program compares two images, printing a report about how different they are and optionally producing a third image that records the pixel-by-pixel differences between them. There are a variety of options and ways to compare (absolute pixel difference, various thresholds for warnings and errors, and also an optional perceptual difference metric). Because {\cf idiff} is built on top on \product, it can compare two images of any formats readable by \ImageInput plugins on hand. They may have any (or different) file formats, data formats, etc. \section{Using {\cf idiff}} The {\cf idiff} utility is invoked as follows: \bigskip \hspace{0.25in} {\cf idiff} [\emph{options}] \emph{image1} \emph{image2} \medskip Where \emph{input1} and \emph{input2} are the names of two image files that should be compared. They may be of any format recognized by \product (i.e., for which image-reading plugins are available). If the two input images are not the same resolutions, or do not have the same number of channels, the comparison will return FAILURE immediately and will not attempt to compare the pixels of the two images. If they are the same dimensions, the pixels of the two images will be compared, and a report will be printed including the mean and maximum error, how many pixels were above the warning and failure thresholds, and whether the result is {\cf PASS}, {\cf WARNING}, or {\cf FAILURE}. For example: \begin{code} $ idiff a.jpg b.jpg Comparing "a.jpg" and "b.jpg" Mean error = 0.00450079 RMS error = 0.00764215 Peak SNR = 42.3357 Max error = 0.254902 @ (700, 222, B) 574062 pixels (82.1%) over 1e-06 574062 pixels (82.1%) over 1e-06 FAILURE \end{code} % $ The ``mean error'' is the average difference (per channel, per pixel). The ``max error'' is the largest difference in any pixel channel, and will point out on which pixel and channel it was found. It will also give a count of how many pixels were above the warning and failure thresholds. The metadata of the two images (e.g., the comments) are not currently compared; only differences in pixel values are taken into consideration. \subsection*{Raising the thresholds} By default, if any pixels differ between the images, the comparison will fail. You can allow \emph{some} differences to still pass by raising the failure thresholds. The following example will allow images to pass the comparison test, as long as no more than 10\% of the pixels differ by 0.004 (just above a 1/255 threshold): \begin{code} idiff -fail 0.004 -failpercent 10 a.jpg b.jpg \end{code} But what happens if a just a few pixels are very different? Maybe you want that to fail, also. The following adjustment will fail if at least 10\% of pixels differ by 0.004, or if \emph{any} pixel differs by more than 0.25: \begin{code} idiff -fail 0.004 -failpercent 10 -hardfail 0.25 a.jpg b.jpg \end{code} If none of the failure criteria are met, and yet some pixels are still different, it will still give a WARNING. But you can also raise the warning threshold in a similar way: \begin{code} idiff -fail 0.004 -failpercent 10 -hardfail 0.25 \ -warn 0.004 -warnpercent 3 a.jpg b.jpg \end{code} \noindent The above example will PASS as long as fewer than 3\% of pixels differ by more than 0.004. If it does, it will be a WARNING as long as no more than 10\% of pixels differ by 0.004 and no pixel differs by more than 0.25, otherwise it is a FAILURE. %\subsection*{Perceptual differences} \subsection*{Output a difference image} Ordinary text output will tell you how many pixels failed or were warnings, and which pixel had the biggest difference. But sometimes you need to see visually where the images differ. You can get {\cf idiff} to save an image of the differences between the two input images: \begin{code} idiff -o diff.tif -abs a.jpg b.jpg \end{code} The {\cf -abs} flag saves the absolute value of the differences (i.e., all positive values or zero). If you omit the {\cf -abs}, pixels in which {\cf a.jpg} have smaller values than {\cf b.jpg} will be negative in the difference image (be careful in this case of using a file format that doesn't support negative values). You can also scale the difference image with the {\cf -scale}, making them easier to see. And the {\cf -od} flag can be used to output a difference image only if the comparison fails, but not if the images pass within the designated threshold (thus saving you the trouble and space of saving a black image). \section{{\cf idiff} Reference} The various command-line options are discussed below: \subsection*{General options} \apiitem{--help} Prints usage information to the terminal. \apiend \apiitem{-v} Verbose output --- more detail about what it finds when comparing images, even when the comparison does not fail. \apiend \apiitem{-a} Compare all subimages. Without this flag, only the first subimage of each file will be compared. \apiend \subsection*{Thresholds and comparison options} \apiitem{-fail {\rm \emph{A}} \\ -failpercent {\rm \emph{B}} \\ -hardfail {\rm \emph{C}}} Sets the threshold for {\cf FAILURE}: if more than \emph{B}\% of pixels (on a 0-100 floating point scale) are greater than \emph{A} different, or if \emph{any} pixels are more than \emph{C} different. The defaults are to fail if more than 0\% (any) pixels differ by more than 0.00001 (1e-6), and \emph{C} is infinite. \apiend \apiitem{-warn {\rm \emph{A}} \\ -warnpercent {\rm \emph{B}} \\ -hardwarn {\rm \emph{C}}} Sets the threshold for {\cf WARNING}: if more than \emph{B}\% of pixels (on a 0-100 floating point scale) are greater than \emph{A} different, or if \emph{any} pixels are more than \emph{C} different. The defaults are to warn if more than 0\% (any) pixels differ by more than 0.00001 (1e-6), and \emph{C} is infinite. \apiend \apiitem{-p} Does an additional test on the images to attempt to see if they are \emph{perceptually} different (whether you are likely to discern a difference visually), using Hector Yee's metric. If this option is enabled, the statistics will additionally show a report on how many pixels failed the perceptual test, and the test overall will fail if more than the ``fail percentage'' failed the perceptual test. \apiend \subsection*{Difference image output} \apiitem{-o {\rm \emph{outputfile}}} Outputs a \emph{difference image} to the designated file. This difference image pixels consist are each of the value of the corresponding pixel from \emph{image1} minus the value of the pixel \emph{image2}. The file extension of the output file is used to determine the file format to write (e.g., \qkw{out.tif} will write a TIFF file, \qkw{out.jpg} will write a JPEG, etc.). The data format of the output file will be format of whichever of the two input images has higher precision (or the maximum precision that the designated output format is capable of, if that is less than either of the input imges). Note that pixels whose value is lower in \emph{image1} than in \emph{image2}, this will result in negative pixels (which may be clamped to zero if the image format does not support negative values)), unless the {\cf -abs} option is also used. \apiend \apiitem{-abs} Will cause the output image to consist of the \emph{absolute value} of the difference between the two input images (so all values in the difference image $\ge 0$). \apiend \apiitem{-scale {\rm \emph{factor}}} Scales the values in the difference image by the given (floating point) factor. The main use for this is to make small actual differences more visible in the resulting difference image by giving a large scale factor. \apiend \apiitem{-od} Causes a difference image to be produce \emph{only} if the image comparison fails. That is, even if the {\cf -o} option is used, images that are within the comparison threshold will not write out a useless black (or nearly black) difference image. \apiend \subsection*{Process return codes} The {\cf idiff} program will return a code that can be used by scripts to indicate the results: \medskip \begin{tabular}{p{0.3in} p{5in}} 0 & OK: the images match within the warning and error thresholds. \\ 1 & Warning: the errors differ a little, but within error thresholds. \\ 2 & Failure: the errors differ a lot, outside error thresholds. \\ 3 & The images weren't the same size and couldn't be compared. \\ 4 & File error: could not find or open input files, etc. \end{tabular} \begin{code} \end{code} openimageio-1.3.12~dfsg0.orig/src/doc/texturesys.tex0000644000175000017500000015152612271062644020650 0ustar mfvmfv\chapter{Texture Access: {\cf TextureSystem}} \label{chap:texturesystem} \index{Texture System|(} \def\TextureSystem{{\kw TextureSystem}\xspace} \def\TextureOptions{{\kw TextureOptions}\xspace} \def\TextureOpt{{\kw TextureOpt}\xspace} \section{Texture System Introduction and Theory of Operation} \label{sec:texturesys:intro} Coming soon. FIXME \section{Helper Classes} \label{sec:texturesys:helperclasses} \subsection{Imath} The texture functinality of \product uses the excellent open source {\cf Ilmbase} package's {\cf Imath} types when it requires 3D vectors and transformation matrixes. Specifically, we use {\cf Imath::V3f} for 3D positions and directions, and {\cf Imath::M44f} for $4 \times 4$ transformation matrices. To use these yourself, we recommend that you: \begin{code} #include #include \end{code} Please refer to the {\cf Ilmbase} and {\cf OpenEXR} documentation and header files for more complete information about use of these types in your own application. However, note that you are not strictly required to use these classes in your application --- {\cf Imath::V3f} has a memory layout identical to {\cf float[3]} and {\cf Imath::M44f} has a memory layout identical to {\cf float[16]}, so as long as your own internal vectors and matrices have the same memory layout, it's ok to just cast pointers to them when passing as arguments to \TextureSystem methods. \subsection{\TextureOpt} \indexapi{TextureOpt} \TextureOpt is a structure that holds many options controlling single-point texture lookups. Because each texture lookup API call takes a reference to a \TextureOpt, the call signatures remain uncluttered rather than having an ever-growing list of parameters, most of which will never vary from their defaults. Here is a brief description of the data members of a \TextureOpt structure: \apiitem{int nchannels\\ int firstchannel} The number of color channels to look up from the texture --- for example, 1 (single channel), or 3 (for an RGB triple) --- and the number of channels to look up. The defaults are firstchannel = 0, nchannels = 1. Examples: To retrieve the first three channels (typically RGB), you should have nchannels = 3, firstchannel = 0. To retrieve just the blue channel, you should have nchannels = 1, firstchannel = 2. \apiend \apiitem{int subimage \\ ustring subimagename} Specifies the subimage or face within the file to use for the texture lookup. If {\cf subimagename} is set (it defaults to the empty string), it will try to use the subimage that had a matching metadata \qkw{oiio:subimagename}, otherwise the integer {\cf subimage} will be used (which defaults to 0, i.e., the first/default subimage). Nonzero subimage indices only make sense for a texture file that supports subimages or separate images per face (such as Ptex). This will be ignored if the file does not have multiple subimages or separate per-face textures. \apiend \apiitem{Wrap swrap, twrap} Specify the \emph{wrap mode} for 2D texture lookups (and 3D volume texture lookups, using the additional {\cf rwrap} field). These fields are ignored for shadow and environment lookups. These specify what happens when texture coordinates are found to be outside the usual $[0,1]$ range over which the texture is defined. {\cf Wrap} is an enumerated type that may take on any of the following values: \begin{description} \item[\spc] \spc \item[\rm \kw{WrapBlack}] The texture is black outside the [0,1] range. \item[\rm \kw{WrapClamp}] The texture coordinates will be clamped to [0,1], i.e., the value outside [0,1] will be the same as the color at the nearest point on the border. \item[\rm \kw{WrapPeriodic}] The texture is periodic, i.e., wraps back to 0 after going past 1. \item[\rm \kw{WrapMirror}] The texture presents a mirror image at the edges, i.e., the coordinates go from 0 to 1, then back down to 0, then back up to 1, etc. \item[\rm \kw{WrapDefault}] Use whatever wrap might be specified in the texture file itself, or some other suitable default (caveat emptor). \end{description} The wrap mode does not need to be identical in the $s$ and $t$ directions. \apiend \apiitem{float swidth, twidth} For each direction, gives a multiplier for the derivatives. Note that a width of 0 indicates a point sampled lookup (assuming that blur is also zero). The default width is 1, indicating that the derivatives should guide the amount of blur applied to the texture filtering (not counting any additional \emph{blur} specified). \apiend \apiitem{float sblur, tblur} For each direction, specifies an additional amount of pre-blur to apply to the texture (\emph{after} derivatives are taken into account), expressed as a portion of the width of the texture. In other words, blur = 0.1 means that the texture lookup should act as if the texture was pre-blurred with a filter kernel with a width 1/10 the size of the full image. The default blur amount is 0, indicating a sharp texture lookup. \apiend \apiitem{float fill} Specifies the value that will be used for any color channels that are requested but not found in the file. For example, if you perform a 4-channel lookup on a 3-channel texture, the last channel will get the fill value. (Note: this behavior is affected by the \qkw{gray_to_rgb} attribute described in Section~\ref{sec:texturesys:attributes}.) \apiend \apiitem{const float* missingcolor} If not NULL, indicates that a missing or broken texture should \emph{not} be treated as an error, but rather will simply return the supplied color as the texture lookup color and {\cf texture()} will return {\cf true}. If the {\cf missingcolor} field is left at its default (a NULL pointer), a missing or broken texture will be treated as an error and {\cf texture()} will return {\cf false}. Note: When not NULL, the data must point to \emph{nchannels} contiguous floats. \apiend \apiitem{float *dresultds, *dresultdt} If not NULL (the default), these specify locations in which to store the \emph{derivatives} of the texture lookup, i.e., the change of the filtered texture per unit of $s$ and $t$, respectively. Each must point to {\cf nchannels} contiguous floats. If either is NULL, the derivative computations will not be performed. \apiend \apiitem{float bias} For shadow map lookups only, this gives the ``shadow bias'' amount. \apiend \apiitem{int samples} For shadow map lookups only, the number of samples to use for the lookup. \apiend \apiitem{Wrap rwrap \\ float rblur, rwidth \\ float *dresultdr} Specifies wrap, blur, width, and derivative results for the third component of 3D volume texture lookups. These are not used for 2D texture lookups. \apiend \subsection{\TextureOptions} \TextureOptions is a structure that holds many options controlling batched texture lookups. Because each texture lookup API call takes a reference to a \TextureOptions, the call signatures remain uncluttered rather than having an ever-growing list of parameters, most of which will never vary from their defaults. Here is a brief description of the data members of a \TextureOptions structure: \apiitem{int nchannels\\ int firstchannel} The number of color channels to look up from the texture --- for example, 1 (single channel), or 3 (for an RGB triple) --- and the number of channels to look up. The defaults are firstchannel = 0, nchannels = 1. Examples: To retrieve the first three channels (typically RGB), you should have nchannels = 3, firstchannel = 0. To retrieve just the blue channel, you should have nchannels = 1, firstchannel = 2. \apiend \apiitem{int subimage} The subimage or face within the file to use for the texture lookup. The default is 0, and larger values only make sense for a texture file that supports subimages or separate images per face (such as Ptex). This will be ignored if the file does not have multiple subimages or separate per-face textures. \apiend \apiitem{Wrap swrap, twrap} Specify the \emph{wrap mode} for 2D texture lookups (and 3D volume texture lookups, using the additional {\cf rwrap} field). These fields are ignored for shadow and environment lookups. These specify what happens when texture coordinates are found to be outside the usual $[0,1]$ range over which the texture is defined. {\cf Wrap} is an enumerated type that may take on any of the following values: \begin{description} \item[\spc] \spc \item[\rm \kw{WrapBlack}] The texture is black outside the [0,1] range. \item[\rm \kw{WrapClamp}] The texture coordinates will be clamped to [0,1], i.e., the value outside [0,1] will be the same as the color at the nearest point on the border. \item[\rm \kw{WrapPeriodic}] The texture is periodic, i.e., wraps back to 0 after going past 1. \item[\rm \kw{WrapMirror}] The texture presents a mirror image at the edges, i.e., the coordinates go from 0 to 1, then back down to 0, then back up to 1, etc. \item[\rm \kw{WrapDefault}] Use whatever wrap might be specified in the texture file itself, or some other suitable default (caveat emptor). \end{description} The wrap mode does not need to be identical in the $s$ and $t$ directions. \apiend \apiitem{VaryingRef swidth, twidth} For each direction, gives a multiplier for the derivatives. Note that a width of 0 indicates a point sampled lookup (assuming that blur is also zero). The default width is 1, indicating that the derivatives should guide the amount of blur applied to the texture filtering (not counting any additional \emph{blur} specified). \apiend \apiitem{VaryingRef sblur, tblur} For each direction, specifies an additional amount of pre-blur to apply to the texture (\emph{after} derivatives are taken into account), expressed as a portion of the width of the texture. In other words, blur = 0.1 means that the texture lookup should act as if the texture was pre-blurred with a filter kernel with a width 1/10 the size of the full image. The default blur amount is 0, indicating a sharp texture lookup. \apiend \apiitem{VaryingRef fill} Specifies the value that will be used for any color channels that are requested but not found in the file. For example, if you perform a 4-channel lookup on a 3-channel texture, the lsat channel will get the fill value. (Note: this behavior is affected by the \qkw{gray_to_rgb} attribute described in Section~\ref{sec:texturesys:attributes}.) \apiend \apiitem{VaryingRef missingcolor} If supplied, indicates that a missing or broken texture should \emph{not} be treated as an error, but rather will simply return the supplied color as the texture lookup color and {\cf texture()} will return {\cf true}. If the {\cf missingcolor} field is left at its default (a NULL pointer), a missing or broken texture will be treated as an error and {\cf texture()} will return {\cf false}. Although this is a {\cf VaryingRef}, the data must point to \emph{nchannels} contiguous floats, and if ``varying,'' the step size must be set to {\cf nchannels*sizeof(float)}, not {\cf sizeof(float)}. \apiend \apiitem{float *dresultds, *dresultdt} If not NULL (the default), these specify locations in which to store the \emph{derivatives} of the texture lookup, i.e., the change of the filtered texture per unit of $s$ and $t$, respectively. Each must point to {\cf nchannels} contiguous floats. If either is NULL, the derivative computations will not be performed. \apiend \apiitem{VaryingRef bias} For shadow map lookups only, this gives the ``shadow bias'' amount. \apiend \apiitem{VaryingRef samples} For shadow map lookups only, the number of samples to use for each lookup. \apiend \apiitem{Wrap rwrap \\ VaryingRef rblur, rwidth \\ float *dresultdr} Specifies wrap, blur, width, and derivative results for the third component of 3D volume texture lookups. These are not used for 2D texture lookups. \apiend \subsection{{\cf VaryingRef}: encapsulate uniform and varying} Many texture access API routines are designed to look up texture efficiently at many points at once. Therefore, many of the parameters to the API routines, and many of the fields in \TextureOptions need to accommodate both uniform and varying values. \emph{Uniform} means that a single value may be used for each of the many simultaneous texture lookups, whereas \emph{varying} means that a different value is provided for each of the positions where you are sampling the texture. Please read the comments in \qkw{varyingref.h} for the full gory details, but here's all you really need to know about it to use the texture functionality. Let's suppose that we have a routine whose prototype looks like this: \begin{code} void API (int n, VaryingRef x); \end{code} \noindent This means that parameter $x$ may either be a single value for use at each of the $n$ texture lookups, or it may have $n$ different values of $x$. If you want to pass a uniform value, you may do any of the following: \begin{code} float x; // just one value API (n, x); // automatically knows what to do! API (n, &x); // Also ok to pass the pointer to x API (n, VaryingRef(x)); // Wordy but correct API (n, Uniform(x)); // Shorthand \end{code} If you want to pass a varying value, i.e., an array of values, \begin{code} float x[n]; // One value for each of n points API (n, VaryingRef(x), sizeof(x)); // Wordy but correct API (n, Varying(x)); // Shorthand if stride is sizeof(x) \end{code} You can also initialize a VaryingRef directly: \begin{code} float x; // just one value float y[n]; // array of values VaryingRef r; r.init (&x); // Initialize to uniform r.init (&x, 0); // Initialize to uniform the wordy way r.init (&y, sizeof(float)); // Initialize to varying ... API (n, r); \end{code} \subsection{SIMD Run Flags} Many of the texture lookup API routines are written to accommodate queries about many points at once. Furthermore, only a subset of points may need to compute. This is all expressed using three parameters: {\cf Runflag *runflags, int beginactive, int endactive}. There are also {\cf VaryingRef} parameters such as {\cf s} and {\cf t} that act as if they are arrays. The {\cf beginactive} and {\cf endactive} indices are the first (inclusive) and last (exclusive) points that should be computed, and for each point {\cf runflags[i]} is nonzero if the point should be computed. To illustrate, here is how a routine might be written that would copy values in {\cf arg} to {\cf result} using runflags: \begin{code} void copy (Runflag *runflags, int beginactive, int endactive, VaryingRef arg, VaryingRef result) { for (int i = beginactive; i < endactive; ++i) if (runflags[i]) result[i] = arg[i]; } \end{code} \newpage \section{TextureSystem API} \label{sec:texturesys:api} \subsection{Creating and destroying texture systems} \label{sec:texturesys:api:createdestroy} \TextureSystem is an abstract API described as a pure virtual class. The actual internal implementation is not exposed through the external API of \product. Because of this, you cannot construct or destroy the concrete implementation, so two static methods of \TextureSystem are provided: \apiitem{static TextureSystem *TextureSystem::{\ce create} (bool share=true)} Creates a new \TextureSystem and returns a pointer to it. If {\cf shared} is {\cf true}, the \TextureSystem created will share its underlying \ImageCache with any other \TextureSystem's or \ImageCache's that requested shared caches. If {\cf shared} is {\cf false}, a completely unique \ImageCache will be created that is private to this particular \TextureSystem. \apiend \apiitem{static void TextureSystem::{\ce destroy} (TextureSystem *x, \\ \bigspc\bigspc bool teardown_imagecache=false)} Destroys an allocated \TextureSystem, including freeing all system resources that it holds (such as its underlying \ImageCache). This is necessary to ensure that the memory is freed in a way that matches the way it was allocated within the library. Note that simply using {\cf delete} on the pointer will not always work (at least, not on some platforms in which a DSO/DLL can end up using a different allocator than the main program). If {\cf teardown_imagecache} is {\cf true}, and the \TextureSystem's underlying \ImageCache is the \emph{shared} one, then that \ImageCache will be thoroughly destroyed, not merely releasing the reference. \apiend \subsection{Setting options and limits for the texture system} \label{sec:texturesys:api:options} The following member functions of \TextureSystem allow you to set (and in some cases retrieve) options that control the overall behavior of the texture system: \apiitem{bool {\ce attribute} (const std::string \&name, TypeDesc type, const void *val)} \indexapi{attribute} Sets an attribute (i.e., a property or option) of the \TextureSystem. The {\cf name} designates the name of the attribute, {\cf type} describes the type of data, and {\cf val} is a pointer to memory containing the new value for the attribute. If the \TextureSystem recognizes a valid attribute name that matches the type specified, the attribute will be set to the new value and {\cf attribute()} will return {\cf true}. If {\cf name} is not recognized as a valid attribute name, or if the types do not match (e.g., {\cf type} is {\cf TypeDesc::FLOAT} but the named attribute is a string), the attribute will not be modified, and {\cf attribute()} will return {\cf false}. Here are examples: \begin{code} TextureSystem *ts; ... int maxfiles = 50; ts->attribute ("max_open_files", TypeDesc::INT, &maxfiles); const char *path = "/my/path"; ts->attribute ("searchpath", TypeDesc::STRING, &path); \end{code} Note that when passing a string, you need to pass a pointer to the {\cf char*}, not a pointer to the first character. (Rationale: for an {\cf int} attribute, you pass the address of the {\cf int}. So for a string, which is a {\cf char*}, you need to pass the address of the string, i.e., a {\cf char**}). The complete list of attributes can be found at the end of this section. \apiend \apiitem{bool {\ce attribute} (const std::string \&name, int val) \\ bool {\ce attribute} (const std::string \&name, float val) \\ bool {\ce attribute} (const std::string \&name, double val) \\ bool {\ce attribute} (const std::string \&name, const char *val) \\ bool {\ce attribute} (const std::string \&name, const std::string \& val)} Specialized versions of {\cf attribute()} in which the data type is implied by the type of the argument. For example, the following are equivalent to the example above for the general (pointer) form of {\cf attribute()}: \begin{code} ts->attribute ("max_open_files", 50); ts->attribute ("searchpath", "/my/path"); \end{code} \apiend \apiitem{bool {\ce getattribute} (const std::string \&name, TypeDesc type, void *val)} \indexapi{getattribute} Gets the current value of an attribute of the \TextureSystem. The {\cf name} designates the name of the attribute, {\cf type} describes the type of data, and {\cf val} is a pointer to memory where the user would like the value placed. If the \TextureSystem recognizes a valid attribute name that matches the type specified, the attribute value will be stored at address {\cf val} and {\cf attribute()} will return {\cf true}. If {\cf name} is not recognized as a valid attribute name, or if the types do not match (e.g., {\cf type} is {\cf TypeDesc::FLOAT} but the named attribute is a string), no data will be written to {\cf val}, and {\cf attribute()} will return {\cf false}. Here are examples: \begin{code} TextureSystem *ts; ... int maxfiles; ts->getattribute ("max_open_files", TypeDesc::INT, &maxfiles); const char *path; ts->getattribute ("searchpath", TypeDesc::STRING, &path); \end{code} Note that when passing a string, you need to pass a pointer to the {\cf char*}, not a pointer to the first character. Also, the {\cf char*} will end up pointing to characters owned by the \TextureSystem; the caller does not need to ever free the memory that contains the characters. The complete list of attributes can be found at the end of this section. \apiend \apiitem{bool {\ce getattribute} (const std::string \&name, int \&val) \\ bool {\ce getattribute} (const std::string \&name, float \&val) \\ bool {\ce getattribute} (const std::string \&name, double \&val) \\ bool {\ce getattribute} (const std::string \&name, char **val) \\ bool {\ce getattribute} (const std::string \&name, std::string \& val)} Specialized versions of {\cf getattribute()} in which the data type is implied by the type of the argument. For example, the following are equivalent to the example above for the general (pointer) form of {\cf getattribute()}: \begin{code} int maxfiles; ts->getattribute ("max_open_files", &maxfiles); const char *path; ts->getattribute ("searchpath", &path); \end{code} \apiend \subsubsection*{Texture system attributes} \label{sec:texturesys:attributes} Recognized attributes include the following: \apiitem{int max_open_files \\ float max_memory_MB \\ string searchpath \\ string plugin_searchpath \\ int autotile \\ int autoscanline \\ int automip \\ int accept_untiled \\ int accept_unmipped \\ int failure_retries \\ int deduplicate \\ string substitute_image} These attributes are all passed along to the underlying \ImageCache that is used internally by the \TextureSystem. Please consult the \ImageCache attribute list in Section~\ref{sec:imagecache:api:attribute} for explanations of these attributes. \apiend \apiitem{matrix worldtocommon} The $4 \times 4$ matrix that provides the spatial transformation from ``world'' to a ``common'' coordinate system. This is used for shadow map lookups, in which the shadow map itself encodes the world coordinate system, but positions passed to {\cf shadow()} are expressed in ``common'' coordinates. \apiend \apiitem{matrix commontoworld} The $4 \times 4$ matrix that is the inverse of {\cf worldtocommon} --- that is, it transforms points from ``common'' to ``world'' coordinates. You do not need to set {\cf commontoworld} and {\cf worldtocommon} separately; just setting either one will implicitly set the other, since each is the inverse of the other. \apiend \apiitem{int gray_to_rgb} If set to nonzero, texture lookups of single-channel (grayscale) images will replicate the sole channel's values into the next two channels, making it behave like an RGB image that happens to have all three channels with identical pixel values. (Channels beyond the third will get the ``fill'' value.) The default value of zero means that all missing channels will get the ``fill'' color. \apiend \apiitem{string latlong_up} Sets the default ``up'' direction for latlong environment maps (only applies if the map itself doesn't specify a format or is in a format that explicitly requires a particular orientation). The default is \qkw{y}. (Currently any other value will result in $z$ being ``up.'') \apiend \apiitem{string options} This catch-all is simply a comma-separated list of {\cf name=value} settings of named options. For example, \begin{code} ic->attribute ("options", "max_memory_MB=512.0,autotile=1"); \end{code} \apiend \subsection{Opaque data for performance lookups} \label{sec:texturesys:api:opaque} \apiitem{Perthread * {\ce get_perthread_info} ()} \indexapi{get_perthread_info} Retrieves an opaque handle for per-thread info, to be used for {\cf get_texture_handle()} and the texture routines that take handles directly. \apiend \apiitem{TextureHandle * {\ce get_texture_handle} (ustring filename,\\ \bigspc\bigspc\bigspc Perthread *thread_info=NULL)} \indexapi{get_texture_handle} Retrieve an opaque handle for fast texture lookups. The opaque pointer {\cf thread_info} is thread-specific information returned by {\cf get_perthread_info()}. Return {\cf NULL} if something has gone horribly wrong. \apiend %\newpage \subsection{Texture Lookups} \label{sec:texturesys:api:texture} \apiitem{bool {\ce texture} (ustring filename, TextureOpt \&options,\\ \bigspc float s, float t, float dsdx, float dtdx,\\ \bigspc float dsdy, float dtdy, float *result)} \indexapi{texture} Perform a filtered 2D texture lookup on a position centered at 2D coordinates ({\cf s}, {\cf t}) from the texture identified by {\cf filename}, and using relevant texture {\cf options}. The filtered results will be stored in {\cf result[]}. We assume that this lookup will be part of an image that has pixel coordinates {\cf x} and {\cf y}. By knowing how {\cf s} and {\cf t} change from pixel to pixel in the final image, we can properly \emph{filter} or antialias the texture lookups. This information is given via derivatives {\cf dsdx} and {\cf dtdx} that define the change in {\cf s} and {\cf t} per unit of {\cf x}, and {\cf dsdy} and {\cf dtdy} that define the change in {\cf s} and {\cf t} per unit of {\cf y}. If it is impossible to know the derivatives, you may pass 0 for them, but in that case you will not receive an antialiased texture lookup. Fields within {\cf options} that are honored for 2D texture lookups include the following: \vspace{-12pt} \apiitem{int nchannels} \vspace{10pt} The number of color channels to look up from the texture. \apiend \vspace{-24pt} \apiitem{int firstchannel} \vspace{10pt} The index of the first channel to look up from the texture. \apiend \vspace{-24pt} \apiitem{int subimage} \vspace{10pt} The subimage or face within the file. This will be ignored if the file does not have multiple subimages or separate per-face textures. \apiend \vspace{-24pt} \apiitem{Wrap swrap, twrap} \vspace{10pt} Specify the \emph{wrap mode} for each direction, one of: {\cf WrapBlack}, {\cf WrapClamp}, {\cf WrapPeriodic}, {\cf WrapMirror}, or {\cf WrapDefault}. \apiend \vspace{-24pt} \apiitem{float swidth, twidth} \vspace{10pt} For each direction, gives a multiplier for the derivatives. \apiend \vspace{-24pt} \apiitem{float sblur, tblur} \vspace{10pt} For each direction, specifies an additional amount of pre-blur to apply to the texture (\emph{after} derivatives are taken into account), expressed as a portion of the width of the texture. \apiend \vspace{-24pt} \apiitem{float fill} \vspace{10pt} Specifies the value that will be used for any color channels that are requested but not found in the file. For example, if you perform a 4-channel lookup on a 3-channel texture, the last channel will get the fill value. (Note: this behavior is affected by the \qkw{gray_to_rgb} attribute described in Section~\ref{sec:texturesys:attributes}.) \apiend \vspace{-24pt} \apiitem{const float *missingcolor} \vspace{10pt} If not NULL, specifies the color that will be returned for missing or broken textures (rather than being an error). \apiend \vspace{-24pt} \apiitem{float *dresultds, *dresultdt} \vspace{10pt} If not NULL, specifies locations in which to store the $s$ and $t$ derivatives of the filtered texture lookup. \apiend This function returns {\cf true} upon success, or {\cf false} if the file was not found or could not be opened by any available ImageIO plugin. \apiend \apiitem{bool {\ce texture} (TextureHandle *texture_handle, Perthread *thread_info, \\ \bigspc TextureOpt \&options,\\ \bigspc float s, float t, float dsdx, float dtdx,\\ \bigspc float dsdy, float dtdy, float *result)} A slightly faster {\cf texture} call for applications that are willing to do the extra housekeeping of knowing the handle of the texture they are accessing and the per-thread info for the curent thread. These may be retrieved by the {\cf get_texture_handle()} and {\cf get_perthread_info()} methods, respectively. \apiend \apiitem{bool {\ce texture} (ustring filename, TextureOptions \&options,\\ \bigspc Runflag *runflags, int beginactive, int endactive,\\ \bigspc VaryingRef s, VaryingRef t,\\ \bigspc VaryingRef dsdx, VaryingRef dtdx,\\ \bigspc VaryingRef dsdy, VaryingRef dtdy,\\ \bigspc float *result)} Perform filtered 2D texture lookups on a collection of positions all at once, which may be much more efficient than repeatedly calling the single-point version of {\cf texture()}. The parameters {\cf s}, {\cf t}, {\cf dsdx}, {\cf dtdx}, and {\cf dsdy}, {\cf dtdy} are now {\cf VaryingRef}'s that may refer to either a single or an array of values, as are many of the fields in the {\cf options}. Texture will be computed at indices {\cf beginactive} through {\cf endactive} (exclusive of the end), but only at indices where {\cf runflags[i]} is nonzero. Results will be stored at corresponding positions of {\cf result}, that is, {\cf result[i*n ... (i+1)*n-1]} where $n$ is the number of channels requested by {\cf options.nchannels}. This function returns {\cf true} upon success, or {\cf false} if the file was not found or could not be opened by any available ImageIO plugin. \apiend %\newpage \subsection{Volume Texture Lookups} \label{sec:texturesys:api:texture3d} \apiitem{bool {\ce texture3d} (ustring filename, TextureOpt \&options,\\ \bigspc\spc const Imath::V3f \&P, const Imath::V3f \&dPdx,\\ \bigspc\spc const Imath::V3f \&dPdy, const Imath::V3f \&dPdz,\\ \bigspc\spc float *result)} \indexapi{texture3d} Perform a filtered 3D volumetric texture lookup on a position centered at 3D position {\cf P} from the texture identified by {\cf filename}, and using relevant texture {\cf options}. The filtered results will be stored in {\cf result[]}. We assume that this lookup will be part of an image that has pixel coordinates {\cf x} and {\cf y} and depth {\cf z}. By knowing how {\cf P} changes from pixel to pixel in the final image, and as we step in $z$ depth, we can properly \emph{filter} or antialias the texture lookups. This information is given via derivatives {\cf dPdx}, {\cf dPdy}, and {\cf dPdz} that define the changes in {\cf P} per unit of {\cf x}, {\cf y}, and {\cf z}, respectively. If it is impossible to know the derivatives, you may pass 0 for them, but in that case you will not receive an antialiased texture lookup. The {\cf P} coordinate and {\cf dPdx}, {\cf dPdy}, and {\cf dPdz} derivatives are assumed to be in some kind of common global coordinate system (usually \qkw{world} space) and will be automatically transformed into volume local coordinates, if such a transormation is specified in the volume file itself. Fields within {\cf options} that are honored for 3D texture lookups include the following: \vspace{-12pt} \apiitem{int nchannels} \vspace{10pt} The number of color channels to look up from the texture. \apiend \vspace{-24pt} \apiitem{int firstchannel} \vspace{10pt} The index of the first channel to look up from the texture. \apiend \vspace{-24pt} \apiitem{Wrap swrap, twrap, rwrap} \vspace{10pt} Specify the wrap modes for each direction, one of: {\cf WrapBlack}, {\cf WrapClamp}, {\cf WrapPeriodic}, {\cf WrapMirror}, or {\cf WrapDefault}. \apiend \vspace{-24pt} \apiitem{float swidth, twidth, rwidth} \vspace{10pt} For each direction, gives a multiplier for the derivatives. \apiend \vspace{-24pt} \apiitem{float sblur, tblur, rblur} \vspace{10pt} For each direction, specifies an additional amount of pre-blur to apply to the texture (\emph{after} derivatives are taken into account), expressed as a portion of the width of the texture. \apiend \vspace{-24pt} \apiitem{float fill} \vspace{10pt} Specifies the value that will be used for any color channels that are requested but not found in the file. For example, if you perform a 4-channel lookup on a 3-channel texture, the last channel will get the fill value. (Note: this behavior is affected by the \qkw{gray_to_rgb} attribute described in Section~\ref{sec:texturesys:attributes}.) \apiend \vspace{-24pt} \apiitem{const float *missingcolor} \vspace{10pt} If not NULL, specifies the color that will be returned for missing or broken textures (rather than being an error). \apiend \vspace{-24pt} \apiitem{float time} \vspace{10pt} A time value to use if the volume texture specifies a time-varying local transformation (default: 0). \apiend \vspace{-24pt} \apiitem{float *dresultds, *dresultdt, *dresultdr} \vspace{10pt} If not NULL, specifies locations in which to store the $s$, $t$, and $r$ derivatives of the filtered texture lookup. \apiend This function returns {\cf true} upon success, or {\cf false} if the file was not found or could not be opened by any available ImageIO plugin. \apiend \apiitem{bool {\ce texture3d} (TextureHandle *texture_handle, Perthread *thread_info, \\ \bigspc TextureOpt \&opt,\\ \bigspc const Imath::V3f \&P,\\ \bigspc const Imath::V3f \&dPdx,\\ \bigspc const Imath::V3f \&dPdy,\\ \bigspc const Imath::V3f \&dPdz,\\ \bigspc float *result)} A slightly faster {\cf texture3d} call for applications that are willing to do the extra housekeeping of knowing the handle of the texture they are accessing and the per-thread info for the curent thread. These may be retrieved by the {\cf get_texture_handle()} and {\cf get_perthread_info()} methods, respectively. \apiend \apiitem{bool {\ce texture3d} (ustring filename, TextureOptions \&options,\\ \bigspc Runflag *runflags, int beginactive, int endactive,\\ \bigspc VaryingRef P,\\ \bigspc VaryingRef dPdx,\\ \bigspc VaryingRef dPdy,\\ \bigspc VaryingRef dPdz,\\ \bigspc float *result)} Perform filtered 3D volumetric texture lookups on a collection of positions all at once, which may be much more efficient than repeatedly calling the single-point version of {\cf texture()}. The parameters {\cf P}, {\cf dPdx}, {\cf dPdy}, and {\cf dPdz} are now {\cf VaryingRef}'s that may refer to either a single or an array of values, as are all the fields in the {\cf options}. Texture will be computed at indices {\cf beginactive} through {\cf endactive} (exclusive of the end), but only at indices where {\cf runflags[i]} is nonzero. Results will be stored at corresponding positions of {\cf result}, that is, {\cf result[i*n ... (i+1)*n-1]} where $n$ is the number of channels requested by {\cf options.nchannels}. This function returns {\cf true} upon success, or {\cf false} if the file was not found or could not be opened by any available ImageIO plugin. \apiend %\newpage \subsection{Shadow Lookups} \label{sec:texturesys:api:shadow} \apiitem{bool {\ce shadow} (ustring filename, TextureOpt \&opt,\\ \bigspc const Imath::V3f \&P, const Imath::V3f \&dPdx,\\ \bigspc const Imath::V3f \&dPdy, float *result)} \indexapi{shadow} Perform a shadow map lookup on a position centered at 3D coordinate {\cf P} (in a designated ``common'' space) from the shadow map identified by {\cf filename}, and using relevant texture {\cf options}. The filtered results will be stored in {\cf result[]}. We assume that this lookup will be part of an image that has pixel coordinates {\cf x} and {\cf y}. By knowing how {\cf P} changes from pixel to pixel in the final image, we can properly \emph{filter} or antialias the texture lookups. This information is given via derivatives {\cf dPdx} and {\cf dPdy} that define the changes in {\cf P} per unit of {\cf x} and {\cf y}, respectively. If it is impossible to know the derivatives, you may pass 0 for them, but in that case you will not receive an antialiased texture lookup. Fields within {\cf options} that are honored for 2D texture lookups include the following: \vspace{-12pt} \apiitem{float swidth, twidth} \vspace{10pt} For each direction, gives a multiplier for the derivatives. \apiend \vspace{-24pt} \apiitem{float sblur, tblur} \vspace{10pt} For each direction, specifies an additional amount of pre-blur to apply to the texture (\emph{after} derivatives are taken into account), expressed as a portion of the width of the texture. \apiend \vspace{-24pt} \apiitem{float bias} \vspace{10pt} Specifies the amount of \emph{shadow bias} to use --- this effectively ignores shadow occlusion that is closer than the bias amount to the surface, helping to eliminate self-shadowing artifacts. \apiend \vspace{-24pt} \apiitem{int samples} \vspace{10pt} Specifies the number of samples to use when evaluating the shadow map. More samples will give a smoother, less noisy, appearance to the shadows, but may also take longer to compute. \apiend This function returns {\cf true} upon success, or {\cf false} if the file was not found or could not be opened by any available ImageIO plugin. \apiend \apiitem{bool {\ce shadow} (TextureHandle *texture_handle, Perthread *thread_info, \\ \bigspc TextureOpt \&opt,\\ \bigspc const Imath::V3f \&P,\\ \bigspc const Imath::V3f \&dPdx,\\ \bigspc const Imath::V3f \&dPdy,\\ \bigspc float *result)} A slightly faster {\cf shadow} call for applications that are willing to do the extra housekeeping of knowing the handle of the texture they are accessing and the per-thread info for the curent thread. These may be retrieved by the {\cf get_texture_handle()} and {\cf get_perthread_info()} methods, respectively. \apiend \apiitem{bool {\ce shadow} (ustring filename, TextureOptions \&options,\\ \bigspc Runflag *runflags, int beginactive, int endactive,\\ \bigspc VaryingRef P,\\ \bigspc VaryingRef dPdx,\\ \bigspc VaryingRef dPdy,\\ \bigspc float *result)} Perform filtered shadow map lookups on a collection of positions all at once, which may be much more efficient than repeatedly calling the single-point version of {\cf shadow()}. The parameters {\cf P}, {\cf dPdx}, and {\cf dPdy} are now {\cf VaryingRef}'s that may refer to either a single or an array of values, as are many the fields in the {\cf options}. Shadow lookups will be computed at indices {\cf beginactive} through {\cf endactive} (exclusive of the end), but only at indices where {\cf runflags[i]} is nonzero. Results will be stored at corresponding positions of {\cf result}, that is, {\cf result[i*n ... (i+1)*n-1]} where $n$ is the number of channels requested by {\cf options.nchannels}. This function returns {\cf true} upon success, or {\cf false} if the file was not found or could not be opened by any available ImageIO plugin. \apiend %\newpage \subsection{Environment Lookups} \label{sec:texturesys:api:environment} \apiitem{bool {\ce environment} (ustring filename, TextureOpt \&options,\\ \bigspc const Imath::V3f \&R, const Imath::V3f \&dRdx,\\ \bigspc const Imath::V3f \&dRdy, float *result)} \indexapi{environment} Perform a filtered directional environment map lookup in the direction of vector {\cf R}, from the texture identified by {\cf filename}, and using relevant texture {\cf options}. The filtered results will be stored in {\cf result[]}. We assume that this lookup will be part of an image that has pixel coordinates {\cf x} and {\cf y}. By knowing how {\cf R} changes from pixel to pixel in the final image, we can properly \emph{filter} or antialias the texture lookups. This information is given via derivatives {\cf dRdx} and {\cf dRdy} that define the changes in {\cf R} per unit of {\cf x} and {\cf y}, respectively. If it is impossible to know the derivatives, you may pass 0 for them, but in that case you will not receive an antialiased texture lookup. Fields within {\cf options} that are honored for 3D texture lookups include the following: \vspace{-12pt} \apiitem{int nchannels} \vspace{10pt} The number of color channels to look up from the texture. \apiend \vspace{-24pt} \apiitem{int firstchannel} \vspace{10pt} The index of the first channel to look up from the texture. \apiend \vspace{-24pt} \apiitem{float swidth, twidth} \vspace{10pt} For each direction, gives a multiplier for the derivatives. \apiend \vspace{-24pt} \apiitem{float sblur, tblur} \vspace{10pt} For each direction, specifies an additional amount of pre-blur to apply to the texture (\emph{after} derivatives are taken into account), expressed as a portion of the width of the texture. \apiend \vspace{-24pt} \apiitem{float fill} \vspace{10pt} Specifies the value that will be used for any color channels that are requested but not found in the file. For example, if you perform a 4-channel lookup on a 3-channel texture, the last channel will get the fill value. (Note: this behavior is affected by the \qkw{gray_to_rgb} attribute described in Section~\ref{sec:texturesys:attributes}.) \apiend This function returns {\cf true} upon success, or {\cf false} if the file was not found or could not be opened by any available ImageIO plugin. \apiend \apiitem{bool {\ce environment} (TextureHandle *texture_handle, Perthread *thread_info, \\ \bigspc TextureOpt \&opt,\\ \bigspc const Imath::V3f \&R,\\ \bigspc const Imath::V3f \&dRdx,\\ \bigspc const Imath::V3f \&dRdy,\\ \bigspc float *result)} A slightly faster {\cf environment} call for applications that are willing to do the extra housekeeping of knowing the handle of the texture they are accessing and the per-thread info for the curent thread. These may be retrieved by the {\cf get_texture_handle()} and {\cf get_perthread_info()} methods, respectively. \apiend \apiitem{bool {\ce environment} (ustring filename, TextureOptions \&options,\\ \bigspc Runflag *runflags, int beginactive, int endactive,\\ \bigspc VaryingRef R,\\ \bigspc VaryingRef dRdx,\\ \bigspc VaryingRef dRdy,\\ \bigspc float *result)} Perform filtered directional environment map lookups on a collection of directions all at once, which may be much more efficient than repeatedly calling the single-point version of {\cf environment()}. The parameters {\cf R}, {\cf dRdx}, and {\cf dRdy} are now {\cf VaryingRef}'s that may refer to either a single or an array of values, as are many the fields in the {\cf options}. Results will be computed at indices {\cf beginactive} through {\cf endactive} (exclusive of the end), but only at indices where {\cf runflags[i]} is nonzero. Results will be stored at corresponding positions of {\cf result}, that is, {\cf result[i*n ... (i+1)*n-1]} where $n$ is the number of channels requested by {\cf options.nchannels}. This function returns {\cf true} upon success, or {\cf false} if the file was not found or could not be opened by any available ImageIO plugin. \apiend %\newpage \subsection{Texture Metadata and Raw Texels} \label{sec:texturesys:api:gettextureinfo} \label{sec:texturesys:api:getimagespec} \apiitem{bool {\ce get_texture_info} (ustring filename, int subimage, \\ \bigspc\spc\spc ustring dataname, TypeDesc datatype, void *data)} Retrieves information about the texture named by {\cf filename}. The {\cf dataname} is a keyword indcating what information should be retrieved, {\cf datatype} is the type of data expected, and {\cf data} points to caller-owned memory where the results should be placed. It is up to the caller to ensure that {\cf data} contains enough space to hold an item of the requested {\cf datatype}. The return value is {\cf true} if {\cf get_texture_info()} is able to find the requested {\cf dataname} and it matched the requested {\cf datatype}. If the requested data was not found, or was not of the right data type, {\cf get_texture_info()} will return {\cf false}. Supported {\cf dataname} values include: \begin{description} \item[\spc] \spc \vspace{-12pt} \item[\rm \kw{exists}] Return 1 if the file exists and is an image format that OpenImageIO knows how to read, otherwise return 0. The {\cf data} pointer is not used. \item[\rm \kw{subimages}] The number of subimages/faces in the file, as an integer. \item[\rm \kw{resolution}] The resolution of the texture file, which is an array of 2 integers (described as {\cf TypeDesc(INT,2)}). \item[\rm \kw{resolution} (int[3])] The 3D resolution of the texture file, which is an array of 3 integers (described as {\cf TypeDesc(INT,3)}) The third value will e 1 unless it's a volumetric (3D) image. \item[\rm \kw{miplevels}] The number of MIPmap levels for the specified subimage (an integer). \item[\rm \kw{texturetype}] A string describing the type of texture of the given file, which describes how the texture may be used (also which texture API call is probably the right one for it). This currently may return one of: \qkw{unknown}, \qkw{Plain Texture}, \qkw{Volume Texture}, \qkw{Shadow}, or \qkw{Environment}. \item[\rm \kw{textureformat}] A string describing the format of the given file, which describes the kind of texture stored in the file. This currently may return one of: \qkw{unknown}, \qkw{Plain Texture}, \qkw{Volume Texture}, \qkw{Shadow}, \qkw{CubeFace Shadow}, \qkw{Volume Shadow}, \qkw{LatLong Environment}, or \qkw{CubeFace Environment}. Note that there are several kinds of shadows and environment maps, all accessible through the same API calls. \item[\rm \kw{channels}] The number of color channels in the file (an integer). \item[\rm \kw{datawindow}] Returns the pixel data window of the image, which is either an array of 4 integers (returning xmin, ymin, xmax, ymax) or an array of 6 integers (returning xmin, ymin, zmin, xmax, ymax, zmax). The $z$ values may be useful for 3D/volumetric images; for 2D images they will be 0). \item[\rm \kw{displaywindow}] Returns the display (a.k.a.\ full) window of the image, which is either an array of 4 integers (returning xmin, ymin, xmax, ymax) or an array of 6 integers (returning xmin, ymin, zmin, xmax, ymax, zmax). The $z$ values may be useful for 3D/volumetric images; for 2D images they will be 0). \item[\rm \kw{viewingmatrix}] The viewing matrix, which is a $4 \times 4$ matrix (an {\cf Imath::M44f}, described as {\cf TypeDesc(FLOAT,MATRIX)}). \item[\rm \kw{projectionmatrix}] The projection matrix, which is a $4 \times 4$ matrix (an {\cf Imath::M44f}, described as {\cf TypeDesc(FLOAT,MATRIX)}). \item[Anything else] -- For all other data names, the the metadata of the image file will be searched for an item that matches both the name and data type. \end{description} \apiend \apiitem{bool {\ce get_imagespec} (ustring filename, int subimage, ImageSpec \&spec)} If the named image is found and able to be opened by an available image format plugin, this function copies its image specification into {\cf spec} and returns {\cf true}. Otherwise, if the file is not found, could not be opened, or is not of a format readable by any plugin that could be found, the return value is {\cf false}. \apiend \apiitem{const ImageSpec * {\ce imagespec} (ustring filename, int subimage)} If the named image is found and able to be opened by an available image format plugin, and the designated subimage exists, this function returns a pointer to an \ImageSpec that describes it. Otherwise, if the file is not found, could not be opened, is not of a format readable by any plugin that could be find, or the designated subimage did not exist in the file, the return value is NULL. This method is much more efficient than {\cf get_imagespec()}, since it just returns a pointer to the spec held internally by the underlying \ImageCache (rather than copying the spec to the user's memory). However, the caller must beware that the pointer is only valid as long as nobody (even other threads) calls {\cf invalidate()} on the file, or {\cf invalidate_all()}, or destroys the \TextureSystem. \apiend \apiitem{bool {\ce get_texels} (ustring filename, TextureOpt \&options, int level, \\ \bigspc int xbegin, int xend, int ybegin, int yend,\\ \bigspc int zbegin, int zend, TypeDesc format, void *result)} Retrieve a rectangle of raw unfiltered texels at the named MIP-map level, storing the texel values beginning at the address specified by result. Note that the face/subimage is communicated through {\kw options.subimage}. The texel values will be converted to the type specified by format. It is up to the caller to ensure that result points to an area of memory big enough to accommodate the requested rectangle (taking into consideration its dimensions, number of channels, and data format). The rectangular region to be retrieved includes {\cf begin} but does not include {\cf end} (much like STL begin/end usage). Requested pixels that are not part of the valid pixel data region of the image file will be filled with zero values. Fields within {\cf options} that are honored for raw texel retieval include the following: \vspace{-12pt} \apiitem{int subiamge} \vspace{10pt} The subimage to retrieve. \apiend \vspace{-24pt} \apiitem{int nchannels} \vspace{10pt} The number of color channels to look up from the texture. \apiend \vspace{-24pt} \apiitem{int firstchannel} \vspace{10pt} The index of the first channel to look up from the texture. \apiend % FIXME -- we should support this %\vspace{-24pt} %\apiitem{Wrap swrap, twrap} %\vspace{10pt} %Specify the \emph{wrap mode} for each direction, one of: %{\cf WrapBlack}, {\cf WrapClamp}, {\cf WrapPeriodic}, {\cf WrapMirror}, %or {\cf WrapDefault}. %\apiend \vspace{-24pt} \apiitem{float fill} \vspace{10pt} Specifies the value that will be used for any color channels that are requested but not found in the file. For example, if you perform a 4-channel lookup on a 3-channel texture, the last channel will get the fill value. (Note: this behavior is affected by the \qkw{gray_to_rgb} attribute described in Section~\ref{sec:texturesys:attributes}.) \apiend Return true if the file is found and could be opened by an available ImageIO plugin, otherwise return false. \apiend \apiitem{std::string {\ce resolve_filename} (const std::string \&filename)} Returns the true path to the given file name, with searchpath logic applied. \apiend \subsection{Miscellaneous -- Statistics, errors, flushing the cache} \label{sec:texturesys:api:geterror} \label{sec:texturesys:api:getstats} \label{sec:texturesys:api:resetstats} \label{sec:texturesys:api:invalidate} \apiitem{std::string {\ce geterror} ()} \index{error checking} If any other API routines return {\cf false}, indicating that an error has occurred, this routine will retrieve the error and clear the error status. If no error has occurred since the last time {\cf geterror()} was called, it will return an empty string. \apiend \apiitem{std::string {\ce getstats} (int level=1, bool icstats=true)} Returns a big string containing useful statistics about the \ImageCache operations, suitable for saving to a file or outputting to the terminal. The {\cf level} indicates the amount of detail in the statistics, with higher numbers (up to a maximum of 5) yielding more and more esoteric information. If {\cf icstats} is true, the returned string will also contain all the statistics of the underlying \ImageCache, but if false will only contain texture-specific statistics. \apiend \apiitem{void {\ce reset_stats} ()} Reset most statistics to be as they were with a fresh \ImageCache. Caveat emptor: this does not flush the cache itelf, so the resulting statistics from the next set of texture requests will not match the number of tile reads, etc., that would have resulted from a new \ImageCache. \apiend \apiitem{void {\ce invalidate} (ustring filename)} Invalidate any loaded tiles or open file handles associated with the filename, so that any subsequent queries will be forced to re-open the file or re-load any tiles (even those that were previously loaded and would ordinarily be reused). A client might do this if, for example, they are aware that an image being held in the cache has been updated on disk. This is safe to do even if other procedures are currently holding reference-counted tile pointers from the named image, but those procedures will not get updated pixels until they release the tiles they are holding. \apiend \apiitem{void {\ce invalidate_all} (bool force=false)} Invalidate all loaded tiles and open file handles, so that any subsequent queries will be forced to re-open the file or re-load any tiles (even those that were previously loaded and would ordinarily be reused). A client might do this if, for example, they are aware that an image being held in the cache has been updated on disk. This is safe to do even if other procedures are currently holding reference-counted tile pointers from the named image, but those procedures will not get updated pixels until they release the tiles they are holding. If force is true, everything will be invalidated, no matter how wasteful it is, but if force is false, in actuality files will only be invalidated if their modification times have been changed since they were first opened. \apiend \index{Texture System|)} \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/imageioapi.tex0000644000175000017500000006577012271062644020522 0ustar mfvmfv\chapter{Image I/O API} \label{chap:imageioapi} \index{Image I/O API|(} \section{Data Type Descriptions: {\cf TypeDesc}} \label{sec:dataformats} \label{sec:TypeDesc} \index{data formats} There are two kinds of data that are important to \product: \begin{itemize} \item \emph{Internal data} is in the memory of the computer, used by an application program. \item \emph{Native file data} is what is stored in an image file itself (i.e., on the ``other side'' of the abstraction layer that \product provides). \end{itemize} Both internal and file data is stored in a particular \emph{data format} that describes the numerical encoding of the values. \product understands several types of data encodings, and there is a special type, \TypeDesc, that allows their enumeration and is described in the header file {\cf OpenImageIO/typedesc.h}. A \TypeDesc describes a base data format type, aggregation into simple vector and matrix types, and an array length (if it's an array). The remainder of this section describes the C++ API for \TypeDesc. See Section~\ref{sec:pythontypedesc} for the corresponding Python bindings. \TypeDesc supports the following base data format types, given by the enumerated type {\cf BASETYPE}: \medskip \begin{tabular}{l p{4.75in}} {\cf UINT8} & 8-bit integer values ranging from 0..255, corresponding to the C/C++ {\cf unsigned char}. \\ {\cf INT8} & 8-bit integer values ranging from -128..127, corresponding to the C/C++ {\cf char}. \\ {\cf UINT16} & 16-bit integer values ranging from 0..65535, corresponding to the C/C++ {\cf unsigned short}. \\ {\cf INT16} & 16-bit integer values ranging from -32768..32767, corresponding to the C/C++ {\cf short}. \\ {\cf UINT} & 32-bit integer values, corresponding to the C/C++ {\cf unsigned int}. \\ {\cf INT} & signed 32-bit integer values, corresponding to the C/C++ {\cf int}. \\ {\cf UINT64} & 64-bit integer values, corresponding to the C/C++ {\cf unsigned long long} (on most architectures). \\ {\cf INT64} & signed 64-bit integer values, corresponding to the C/C++ {\cf long long} (on most architectures). \\ {\cf FLOAT} & 32-bit IEEE floating point values, corresponding to the C/C++ {\cf float}. \\ {\cf DOUBLE} & 64-bit IEEE floating point values, corresponding to the C/C++ {\cf double}. \\ {\cf HALF} & 16-bit floating point values in the format supported by OpenEXR and OpenGL. \end{tabular} \medskip \noindent A \TypeDesc can be constructed using just this information, either as a single scalar value, or an array of scalar values: \apiitem{{\ce TypeDesc} (BASETYPE btype) \\ {\ce TypeDesc} (BASETYPE btype, int arraylength)} Construct a type description of a single scalar value of the given base type, or an array of such scalars if an array length is supplied. For example, {\cf TypeDesc(UINT8)} describes an unsigned 8-bit integer, and {\cf TypeDesc(FLOAT,7)} describes an array of 7 32-bit float values. Note also that a non-array \TypeDesc may be implicitly constructed from just the {\cf BASETYPE}, so it's okay to pass a {\cf BASETYPE} to any function parameter that takes a full \TypeDesc. \apiend \medskip \noindent In addition, \TypeDesc supports certain aggregate types, described by the enumerated type {\cf AGGREGATE}: \medskip \begin{tabular}{l p{4.75in}} {\cf SCALAR} & a single scalar value (such as a raw {\cf int} or {\cf float} in C). This is the default. \\ {\cf VEC2} & two values representing a 2D vector. \\ {\cf VEC3} & three values representing a 3D vector. \\ {\cf VEC4} & four values representing a 4D vector. \\ {\cf MATRIX44} & sixteen values representing a $4 \times 4$ matrix. \end{tabular} \medskip \noindent And optionally, a hint about the semantics of the data, described by the enumerated type {\cf VECSEMANTICS}:\footnote{It's unfortunately called {\cf VECSEMANTICS} because it used to be used strictly for 3-vectors. If we were to do it over again, it would just be {\cf SEMANTICS}.} \medskip \begin{tabular}{p{1in} p{4.25in}} {\cf NOSEMANTICS} & nothing special known. \\ {\cf COLOR} & indicates a vector that is intended to represent a ``color,'' not a spatial quantity (and of course therefore does not undergo a transformation). \\ {\cf POINT} & indicates a vector that represents a spatial position and should be transformed by a $4 \times 4$ matrix as if it had a 4th component of 1. \\ {\cf VECTOR} & indicates a vector that represents a spatial direction and should be transformed by a $4 \times 4$ matrix as if it had a 4th component of 0. \\ {\cf NORMAL} & indicates a vector that represents a surface normal and should be transformed like a vector, but using the inverse-transpose of a $4 \times 4$ matrix. \\ {\cf TIMECODE} & indicates an {\cf int[2]} representing the standard 4-byte encoding of an SMPTE timecode. \\ {\cf KEYCODE} & indicates an {\cf int[7]} representing the standard 28-byte encoding of an SMPTE keycode. \\ \end{tabular} \medskip \noindent These can be combined to fully describe a complex type: \apiitem{{\ce TypeDesc} (BASETYPE btype, AGGREGATE agg, VECSEMANTICS xform=NOSEMANTICS) \\ {\ce TypeDesc} (BASETYPE btype, AGGREGATE agg, int arraylen) \\ {\ce TypeDesc} (BASETYPE btype, AGGREGATE agg, VECSEMANTICS xform, int arraylen) } Construct a type description of an aggregate (or array of aggregates), with optional vector transformation semantics. For example, {\cf TypeDesc(HALF,COLOR)} describes an aggregate of 3 16-bit floats comprising a color, and {\cf TypeDesc(FLOAT,VEC3,POINT)} describes an aggregate of 3 32-bit floats comprising a 3D position. Note that aggregates and arrays are different. A {\cf TypeDesc(FLOAT,3)} is an array of three floats, a {\cf TypeDesc(FLOAT,COLOR)} is a single 3-channel color comprised of floats, and {\cf TypeDesc(FLOAT,3,COLOR)} is an array of 3 color values, each of which is comprised of 3 floats. \apiend \bigskip Of these, the only ones commonly used to store pixel values in image files are scalars of {\cf UINT8}, {\cf UINT16}, {\cf FLOAT}, and {\cf HALF} (the last only used by OpenEXR, to the best of our knowledge). Note that the \TypeDesc (which is also used for applications other than images) can describe many types not used by \product. Please ignore this extra complexity; only the above simple types are understood by \product as pixel storage data types, though a few others, including {\cf STRING} and {\cf MATRIX44} aggregates, are occasionally used for \emph{metadata} for certain image file formats (see Sections~\ref{sec:imageoutput:metadata}, \ref{sec:imageinput:metadata}, and the documentation of individual ImageIO plugins for details). \section{Image Specification: {\cf ImageSpec}} \label{sec:ImageSpec} \indexapi{ImageSpec} An \ImageSpec is a structure that describes the complete format specification of a single image. It contains: \begin{itemize} \item The image resolution (number of pixels). \item The origin, if its upper left corner is not located beginning at pixel (0,0). \item The full size and offset of an abstract ``full'' or ``display'' image, useful for describing cropping or overscan. \item Whether the image is organized into \emph{tiles}, and if so, the tile size. \item The \emph{native data format} of the pixel values (e.g., float, 8-bit integer, etc.). \item The number of color channels in the image (e.g., 3 for RGB images), names of the channels, and whether any particular channels represent \emph{alpha} and \emph{depth}. \item Quantization parameters describing how floating point values should be converted to integers (in cases where users pass real values but integer values are stored in the file). This is used only when writing images, not when reading them. \item A user-extensible (and format-extensible) list of any other arbitrarily-named and -typed data that may help describe the image or its disk representation. \end{itemize} The remainder of this section describes the C++ API for \ImageSpec. See Section~\ref{sec:pythonimagespec} for the corresponding Python bindings. \subsection{\ImageSpec Data Members} The \ImageSpec contains data fields for the values that are required to describe nearly any image, and an extensible list of arbitrary attributes that can hold metadata that may be user-defined or specific to individual file formats. Here are the hard-coded data fields: \apiitem{int width, height, depth \\ int x, y, z} {\cf width, height, depth} are the size of the data of this image, i.e., the number of pixels in each dimension. A {\cf depth} greater than 1 indicates a 3D ``volumetric'' image. {\cf x, y, z} indicate the \emph{origin} of the pixel data of the image. These default to (0,0,0), but setting them differently may indicate that this image is offset from the usual origin. Therefore the pixel data are defined over pixel coordinates [{\cf x} ... {\cf x+width-1}] horizontally, [{\cf y} ... {\cf y+height-1}] vertically, and [{\cf z} ... {\cf z+depth-1}] in depth. \apiend \apiitem{int full_width, full_height, full_depth \\ int full_x, full_y, full_z} These fields define a ``full'' or ``display'' image window over the region [{\cf full_x} ... {\cf full_x+full_width-1}] horizontally, [{\cf full_y} ... {\cf full_y+full_height-1}] vertically, and [{\cf full_z} ... {\cf full_z+full_depth-1}] in depth. Having the full display window different from the pixel data window can be helpful in cases where you want to indicate that your image is a \emph{crop window} of a larger image (if the pixel data window is a subset of the full display window), or that the pixels include \emph{overscan} (if the pixel data is a superset of the full display window), or may simply indicate how different non-overlapping images piece together. \apiend \apiitem{int tile_width, tile_height, tile_depth} If nonzero, indicates that the image is stored on disk organized into rectangular \emph{tiles} of the given dimension. The default of (0,0,0) indicates that the image is stored in scanline order, rather than as tiles. \apiend \apiitem{int nchannels} The number of \emph{channels} (color values) present in each pixel of the image. For example, an RGB image has 3 channels. \apiend %\newpage %\vspace{24pt} % make some space \apiitem{TypeDesc format \\[0.5ex] std::vector channelformats} Describes the native format of the pixel data values themselves, as a \TypeDesc (see \ref{sec:TypeDesc}). Typical values would be {\cf TypeDesc::UINT8} for 8-bit unsigned values, {\cf TypeDesc::FLOAT} for 32-bit floating-point values, etc. If all channels of the image have the same data format, that will be described by {\cf format} and {\cf channelformats} will be empty (zero length). If there are different data formats for each channel, they will be described in the {\cf channelformats} vector, and the {\cf format} field will indicate a single default data format for applications that don't wish to support per-channel formats (usually this will be the format of the channel that has the most precision). \apiend \apiitem{std::vector channelnames} The names of each channel, in order. Typically this will be \qkw{R}, \qkw{G},\qkw{B}, \qkw{A} (alpha), \qkw{Z} (depth), or other arbitrary names. \apiend \apiitem{int alpha_channel} The index of the channel that represents \emph{alpha} (pixel coverage and/or transparency). It defaults to -1 if no alpha channel is present, or if it is not known which channel represents alpha. \apiend \apiitem{int z_channel} The index of the channel that respresents \emph{z} or \emph{depth} (from the camera). It defaults to -1 if no depth channel is present, or if it is not know which channel represents depth. \apiend \apiitem{bool deep} If {\cf true}, this indicates that the image describes contains ``deep'' data consisting of multiple samples per pixel. If {\cf false}, it's an ordinary image with one data value (per channel) per pixel. \apiend \apiitem{int quant_black, quant_white, quant_min, quant_max;} Describes the \emph{quantization}, or mapping between real (floating-point) values and the stored integer values. Please refer to Section~\ref{sec:imageoutput:quantization} for a more complete explanation of each of these parameters. \apiend \apiitem{ParamValueList extra_attribs} A list of arbitrarily-named and arbitrarily-typed additional attributes of the image, for any metadata not described by the hard-coded fields described above. This list may be manipulated with the {\cf attribute()} and {\cf find_attribute()} methods. \apiend \subsection{\ImageSpec member functions} \label{sec:ImageSpecMemberFuncs} \noindent \ImageSpec contains the following methods that manipulate format specs or compute useful information about images given their format spec: \apiitem{{\ce ImageSpec} (int xres, int yres, int nchans, TypeDesc fmt = UINT8)} Constructs an \ImageSpec with the given $x$ and $y$ resolution, number of channels, and pixel data format. All other fields are set to the obvious defaults -- the image is an ordinary 2D image (not a volume), the image is not offset or a crop of a bigger image, the image is scanline-oriented (not tiled), channel names are ``R'', ``G'', ``B,'' and ``A'' (up to and including 4 channels, beyond that they are named ``channel \emph{n}''), the fourth channel (if it exists) is assumed to be alpha, values are assumed to be linear, and quantization (if \emph{fmt} describes an integer type) is done in such a way that the maximum positive integer range maps to (0.0, 1.0). \apiend \apiitem{void {\ce set_format} (TypeDesc fmt)} Sets the format as described, and also sets all quantization parameters to the default for that data type (as explained in Section~\ref{sec:imageoutput:quantization}). \apiend \apiitem{void {\ce default_channel_names} ()} Sets the {\cf channelnames} to reasonable defaults for the number of channels. Specifically, channel names are set to ``R'', ``G'', ``B,'' and ``A'' (up to and including 4 channels, beyond that they are named ``channel\emph{n}''. \apiend \apiitem{static TypeDesc \\ {\ce format_from_quantize} (int quant_black, int quant_white,\\ \bigspc \bigspc int quant_min, int quant_max)} Utility function that, given quantization parameters, returns a data type that may be used without unacceptable loss of significant bits. % FIXME - elaborate? \apiend \apiitem{size_t {\ce channel_bytes} () const} Returns the number of bytes comprising each channel of each pixel (i.e., the size of a single value of the type described by the {\cf format} field). \apiend \apiitem{size_t {\ce channel_bytes} (int chan, bool native=false) const} Returns the number of bytes needed for the single specified channel. If native is {\cf false} (default), compute the size of one channel of {\cf this->format}, but if native is {\cf true}, compute the size of the channel in terms of the ``native'' data format of that channel as stored in the file. \apiend \apiitem{size_t {\ce pixel_bytes} (bool native=false) const} Returns the number of bytes comprising each pixel (i.e. the number of channels multiplied by the channel size). If {\cf native} is true, this will be the sum of all the per-channel formats in {\cf channelformats}. If {\cf native} is false (the default), or if all channels use the same format, this will simply be the number of channels multiplied by the width (in bytes) of the {\cf format}. \apiend \apiitem{size_t {\ce pixel_bytes} (int chbegin, int chend, bool native=false) const} Returns the number of bytes comprising the range of channels $[${\cf chbegin}, {\cf chend}$)$ for each pixel. If {\cf native} is true, this will be the sum of the per-channel formats in {\cf channelformats} (for the given range of channels). If {\cf native} is false (the default), or if all channels use the same format, this will simply be the number of channels multiplied by the width (in bytes) of the {\cf format}. \apiend \apiitem{imagesize_t {\ce scanline_bytes} (bool native=false) const} Returns the number of bytes comprising each scanline, i.e., \\ {\cf pixel_bytes(native) * width} \\ This will return {\cf std::numeric_limits::max()} in the event of an overflow where it's not representable in an {\cf imagesize_t}. \apiend \apiitem{imagesize_t {\ce tile_pixels} () const} Returns the number of tiles comprising an image tile (if it's a tiled image). This will return {\cf std::numeric_limits::max()} in the event of an overflow where it's not representable in an {\cf imagesize_t}. \apiend \apiitem{imagesize_t {\ce tile_bytes} (bool native=false) const} Returns the number of bytes comprising an image tile (if it's a tiled image), i.e., \\ {\cf pixel_bytes(native) * tile_width * tile_height * tile_depth } \\ This will return {\cf std::numeric_limits::max()} in the event of an overflow where it's not representable in an {\cf imagesize_t}. \apiend \apiitem{imagesize_t {\ce image_pixels} () const} Returns the number of pixels comprising an entire image image of these dimensions. This will return {\cf std::numeric_limits::max()} in the event of an overflow where it's not representable in an {\cf imagesize_t}. \apiend \apiitem{imagesize_t {\ce image_bytes} (bool native=false) const} Returns the number of bytes comprising an entire image of these dimensions, i.e., \\ {\cf pixel_bytes(native) * width * height * depth } \\ This will return {\cf std::numeric_limits::max()} in the event of an overflow where it's not representable in an {\cf imagesize_t}. \apiend \apiitem{bool {\ce size_t_safe} () const} Return {\cf true} if an image described by this spec can the sizes (in pixels or bytes) of its scanlines, tiles, and the entire image can be represented by a {\cf size_t} on that platform. If this returns {\cf false}, the client application should be very careful allocating storage! \apiend % FIXME - document auto_stride() ? \apiitem{void {\ce attribute} (const std::string \&name, TypeDesc type, \\ \bigspc const void *value)} Add a metadata attribute to {\cf extra_attribs}, with the given name and data type. The {\cf value} pointer specifies the address of the data to be copied. \apiend \apiitem{void {\ce attribute} (const std::string \&name, unsigned int value)\\ void {\ce attribute} (const std::string \&name, int value)\\ void {\ce attribute} (const std::string \&name, float value)\\ void {\ce attribute} (const std::string \&name, const char *value)\\ void {\ce attribute} (const std::string \&name, const std::string \&value)} Shortcuts for passing attributes comprised of a single integer, floating-point value, or string. \apiend \apiitem{ImageIOParameter * {\ce find_attribute} (const std::string \&name,\\ \bigspc\bigspc\spc TypeDesc searchtype=UNKNOWN,\\ \bigspc\bigspc\spc bool casesensitive=false)\\ const ImageIOParameter * {\ce find_attribute} (const std::string \&name,\\ \bigspc\bigspc\spc TypeDesc searchtype=UNKNOWN,\\ \bigspc\bigspc\spc bool casesensitive=false) const \\ } Searches {\cf extra_attribs} for an attribute matching {\cf name}, returning a pointer to the attribute record, or NULL if there was no match. If {\cf searchtype} is {\cf TypeDesc::UNKNOWN}, the search will be made regardless of the data type, whereas other values of {\cf searchtype} will reject a matching name if the data type does not also match. The name comparison will be exact if {\cf casesensitive} is true, otherwise in a case-insensitive manner if {\cf caseinsensitive} is false. \apiend \apiitem{int {\ce get_int_attribute} (const std::string \&name, int defaultval=0) const} Gets an integer metadata attribute (silently converting to {\cf int} even if if the data is really int8, uint8, int16, uint16, or uint32), and simply substituting the supplied default value if no such metadata exists. This is a convenience function for when you know you are just looking for a simple integer value. \apiend \apiitem{float {\ce get_float_attribute} (const std::string \&name,\\ \bigspc\bigspc float defaultval=0) const} Gets a float metadata attribute (silently converting to {\cf float} even if the data is really half or double), simply substituting the supplied default value if no such metadata exists. This is a convenience function for when you know you are just looking for a simple float value. \apiend \apiitem{std::string {\ce get_string_attribute} (const std::string \&name, \\ \bigspc\bigspc const std::string \&defaultval=std::string()) const} Gets a string metadata attribute, simply substituting the supplied default value if no such metadata exists. This is a convenience function for when you know you are just looking for a simple string value. \apiend \apiitem{std::string {\ce metadata_val} (const ImageIOParamaeter \&p, bool human=true) const} For a given parameter (in this \ImageSpec's {\cf extra_attribs} field), format the value nicely as a string. If {\cf human} is true, use especially human-readable explanations (units, or decoding of values) for certain known metadata. \apiend \apiitem{std::string {\ce to_xml} () const} Saves the contents of the \ImageSpec as XML, returning it as a string. \apiend \apiitem{void {\ce from_xml} (const char *xml) const} Populates the fields of the \ImageSpec based on the XML passed in. \apiend \apiitem{TypeDesc {\ce channelformat} (int chan) const} Returns a \TypeDesc describing the format of the requested channel. \apiend \apiitem{void {\ce get_channelformats} (std::vector \&formats) const} Fill in an array of channel formats describing all channels in the image. (Note that this differs slightly from the member data {\cf channelformats}, which is empty if there are not separate per-channel formats.) \apiend \subsection{Miscellaneous Utilities} \label{sec:miscapi} These helper functions are not part of any other \OpenImageIO class, they just exist in the {\cf OpenImageIO} namespace as general utilities. (See Section~\ref{sec:pythonmiscapi} for the corresponding Python bindings.) \apiitem{int {\ce openimageio_version} ()} \index{version} \indexapi{openimageio_version} Returns a numeric value for the version of \product, 10000 for each major version, 100 for each minor version, 1 for each patch. For example, \product 1.2.3 would return a value of 10203. \apiend \apiitem{std::string {\ce geterror} ()} \index{error checking} \indexapi{geterror} Returns any error string describing what went wrong if {\cf ImageInput::create()} or {\cf ImageOutput::create()} failed (since in such cases, the \ImageInput or \ImageOutput itself does not exist to have its own {\cf geterror()} function called). This function returns the last error for this particular thread; separate threads will not clobber each other's global error messages. \apiend \apiitem{bool {\ce attribute} (const std::string \&name, TypeDesc type, const void *val)} \index{globalattribute} \indexapi{attribute} Sets an global attribute (i.e., a property or option) of \product. The {\cf name} designates the name of the attribute, {\cf type} describes the type of data, and {\cf val} is a pointer to memory containing the new value for the attribute. If the name is known, valid attribute that matches the type specified, the attribute will be set to the new value and {\cf attribute()} will return {\cf true}. If {\cf name} is not recognized, or if the types do not match (e.g., {\cf type} is {\cf TypeDesc::TypeFloat} but the named attribute is a string), the attribute will not be modified, and {\cf attribute()} will return {\cf false}. \noindent The following are the recognized attributes: \apiitem{int threads} \vspace{10pt} \index{threads} \label{sec:attribute:threads} Some \product operations can be accelerated if allowed to spawn multiple threads to parallelize the task. (Examples: decompressing multiple simultaneously-read OpenEXR scanlines, or many \ImageBuf operations.) This attribute sets the maximum number of threads that will be spawned. The default is 1. If set to 0, it means that it should use as many threads as there are hardware cores present on the system. \apiend \apiitem{string plugin_searchpath} \vspace{10pt} \index{plugin_searchpath} A colon-separated list of directories to search for dynamically-loaded format plugins. \apiend \apiitem{string format_list} \vspace{10pt} \index{format_list} A comma-separated list of all the names of all supported image format readers and writers. (Note: can only be retrieved by {\cf getattribute()}, cannot be set by {\cf attribute()}.) \apiend \apiitem{string extension_list} \vspace{10pt} \index{extension_list} For each format, the format name, followed by a colon, followed by a comma-separated list of all extensions that are presumed to be used for that format. Semicolons separate the lists for formats. For example, \begin{code} "tiff:tif;jpeg:jpg,jpeg;openexr:exr" \end{code} (Note: can only be retrieved by {\cf getattribute()}, cannot be set by {\cf attribute()}.) \apiend \apiend \apiitem{bool {\ce attribute} (const std::string \&name, int val) \\ bool {\ce attribute} (const std::string \&name, float val) \\ bool {\ce attribute} (const std::string \&name, const char *val) \\ bool {\ce attribute} (const std::string \&name, const std::string \& val)} Specialized versions of {\cf attribute()} in which the data type is implied by the type of the argument. \apiend \apiitem{bool {\ce getattribute} (const std::string \&name, TypeDesc type, void *val)} \indexapi{getattribute} Gets the current value of a global attribute. The {\cf name} designates the name of the attribute, {\cf type} describes the type of data, and {\cf val} is a pointer to memory where the user would like the value placed. If the attribute name is valid and matches the type specified, the attribute value will be stored at address {\cf val} and {\cf attribute()} will return {\cf true}. If {\cf name} is not recognized as a valid attribute name, or if the types do not match (e.g., {\cf type} is {\cf TypeDesc::TypeFloat} but the named attribute is a string), no data will be written to {\cf val}, and {\cf attribute()} will return {\cf false}. The complete list of attributes can be found above, in the description of the {\cf attribute()} function. \apiend \apiitem{bool {\ce getattribute} (const std::string \&name, int \&val) \\ bool {\ce getattribute} (const std::string \&name, float \&val) \\ bool {\ce getattribute} (const std::string \&name, char **val) \\ bool {\ce getattribute} (const std::string \&name, std::string \& val)} Specialized versions of {\cf getattribute()} in which the data type is implied by the type of the argument. For example, the following are equivalent to the example above for the general (pointer) form of {\cf getattribute()}: \begin{code} int maxfiles; ts->getattribute ("max_open_files", &maxfiles); const char *path; ts->getattribute ("plugin_searchpath", &path); \end{code} \apiend \apiitem{void {\ce declare_imageio_format} (const std::string \&format_name,\\ \bigspc\bigspc\spc ImageInput::Creator input_creator, \\ \bigspc\bigspc\spc const char **input_extensions,\\ \bigspc\bigspc\spc ImageOutput::Creator output_creator, \\ \bigspc\bigspc\spc const char **output_extensions)} \NEW % 1.3 Register the input and output `create' routines and list of file extensions for a particular format. \apiend \index{Image I/O API|)} \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/writingplugins.tex0000644000175000017500000005165512271062644021500 0ustar mfvmfv\chapter{Writing ImageIO Plugins} \label{chap:writingplugins} \section{Plugin Introduction} \label{sec:pluginintro} As explained in Chapters~\ref{chap:imageinput} and \ref{chap:imageoutput}, the ImageIO library does not know how to read or write any particular image formats, but rather relies on plugins located and loaded dynamically at run-time. This set of plugins, and therefore the set of image file formats that \product or its clients can read and write, is extensible without needing to modify \product itself. This chapter explains how to write your own \product plugins. We will first explain separately how to write image file readers and writers, then tie up the loose ends of how to build the plugins themselves. \section{Image Readers} \label{sec:pluginreaders} A plugin that reads a particular image file format must implement a \emph{subclass} of \ImageInput (described in Chapter~\ref{chap:imageinput}). This is actually very straightforward and consists of the following steps, which we will illustrate with a real-world example of writing a JPEG/JFIF plug-in. \begin{enumerate} \item Read the base class definition from {\fn imageio.h}. It may also be helpful to enclose the contents of your plugin in the same namespace that the \product library uses: \begin{code} #include OIIO_PLUGIN_NAMESPACE_BEGIN ... everything else ... OIIO_PLUGIN_NAMESPACE_END \end{code} \item Declare three public items: \begin{enumerate} \item An integer called \emph{name}{\cf _imageio_version} that identifies the version of the ImageIO protocol implemented by the plugin, defined in {\fn imageio.h} as the constant {\cf OIIO_PLUGIN_VERSION}. This allows the library to be sure it is not loading a plugin that was compiled against an incompatible version of \product. \item A function named \emph{name}{\cf _input_imageio_create} that takes no arguments and returns a new instance of your \ImageInput subclass. (Note that \emph{name} is the name of your format, and must match the name of the plugin itself.) \item An array of {\cf char *} called \emph{name}{\cf _input_extensions} that contains the list of file extensions that are likely to indicate a file of the right format. The list is terminated by a {\cf NULL} pointer. \end{enumerate} All of these items must be inside an `{\cf extern "C"}' block in order to avoid name mangling by the C++ compiler, and we provide handy macros {\cf OIIO_PLUGIN_EXPORTS_BEGIN} and {\cf OIIO_PLUGIN_EXPORTS_END} to make this easy. Depending on your compiler, you may need to use special commands to dictate that the symbols will be exported in the DSO; we provide a special {\cf OIIO_EXPORT} macro for this purpose, defined in {\fn export.h}. Putting this all together, we get the following for our JPEG example: \begin{code} OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int jpeg_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT JpgInput *jpeg_input_imageio_create () { return new JpgInput; } OIIO_EXPORT const char *jpeg_input_extensions[] = { "jpg", "jpe", "jpeg", NULL }; OIIO_PLUGIN_EXPORTS_END \end{code} \item The definition and implementation of an \ImageInput subclass for this file format. It must publicly inherit \ImageInput, and must overload the following methods which are ``pure virtual'' in the \ImageInput base class: \begin{enumerate} \item {\cf format_name()} should return the name of the format, which ought to match the name of the plugin and by convention is strictly lower-case and contains no whitespace. \item {\cf open()} should open the file and return true, or should return false if unable to do so (including if the file was found but turned out not to be in the format that your plugin is trying to implement). \item {\cf close()} should close the file, if open. \item {\cf read_native_scanline} should read a single scanline from the file into the address provided, uncompressing it but keeping it in its native data format without any translation. \item The virtual destructor, which should {\cf close()} if the file is still open, addition to performing any other tear-down activities. \end{enumerate} Additionally, your \ImageInput subclass may optionally choose to overload any of the following methods, which are defined in the \ImageInput base class and only need to be overloaded if the default behavior is not appropriate for your plugin: \begin{enumerate} \item[(f)] {\cf supports()}, only if your format supports any of the optional features described in Section~\ref{sec:inputsupportsfeaturelist}. \item[(g)] {\cf valid_file()}, if your format has a way to determine if a file is of the given format in a way that is less expensive than a full {\cf open()}. \item[(h)] {\cf seek_subimage()}, only if your format supports reading multiple subimages within a single file. \item[(i)] {\cf read_native_scanlines()}, only if your format has a speed advantage when reading multiple scanlines at once. If you do not supply this function, the default implementation will simply call {\cf read_scanline()} for each scanline in the range. \item[(j)] {\cf read_native_tile()}, only if your format supports reading tiled images. \item[(k)] {\cf read_native_tiles()}, only if your format supports reading tiled images and there is a speed advantage when reading multiple tiles at once. If you do not supply this function, the default implementation will simply call {\cf read_native_tile()} for each tile in the range. \item[(l)] ``Channel subset'' versions of {\cf read_native_scanlines()} and/or {\cf read_native_tiles()}, only if your format has a more efficient means of reading a subset of channels. If you do not supply these methods, the default implementation will simply use {\cf read_native_scanlines()} or {\cf read_native_tiles()} to read into a temporary all-channel buffer and then copy the channel subset into the user's buffer. \item[(m)] {\cf read_native_deep_scanlines()} and/or {\cf read_native_deep_tiles()}, only if your format supports ``deep'' data images. \end{enumerate} Here is how the class definition looks for our JPEG example. Note that the JPEG/JFIF file format does not support multiple subimages or tiled images. \begin{code} class JpgInput : public ImageInput { public: JpgInput () { init(); } virtual ~JpgInput () { close(); } virtual const char * format_name (void) const { return "jpeg"; } virtual bool open (const std::string &name, ImageSpec &spec); virtual bool read_native_scanline (int y, int z, void *data); virtual bool close (); private: FILE *m_fd; bool m_first_scanline; struct jpeg_decompress_struct m_cinfo; struct jpeg_error_mgr m_jerr; void init () { m_fd = NULL; } }; \end{code} \end{enumerate} Your subclass implementation of {\cf open()}, {\cf close()}, and {\cf read_native_scanline()} are the heart of an \ImageInput implementation. (Also {\cf read_native_tile()} and {\cf seek_subimage()}, for those image formats that support them.) The remainder of this section simply lists the full implementation of our JPEG reader, which relies heavily on the open source {\fn jpeg-6b} library to perform the actual JPEG decoding. \includedcode{../jpeg.imageio/jpeginput.cpp} \section{Image Writers} \label{sec:pluginwriters} A plugin that writes a particular image file format must implement a \emph{subclass} of \ImageOutput (described in Chapter~\ref{chap:imageoutput}). This is actually very straightforward and consists of the following steps, which we will illustrate with a real-world example of writing a JPEG/JFIF plug-in. \begin{enumerate} \item Read the base class definition from {\fn imageio.h}, just as with an image reader (see Section~\ref{sec:pluginreaders}). \item Declare three public items: \begin{enumerate} \item An integer called \emph{name}{\cf _imageio_version} that identifies the version of the ImageIO protocol implemented by the plugin, defined in {\fn imageio.h} as the constant {\cf OIIO_PLUGIN_VERSION}. This allows the library to be sure it is not loading a plugin that was compiled against an incompatible version of \product. Note that if your plugin has both a reader and writer and they are compiled as separate modules (C++ source files), you don't want to declare this in \emph{both} modules; either one is fine. \item A function named \emph{name}{\cf _output_imageio_create} that takes no arguments and returns a new instance of your \ImageOutput subclass. (Note that \emph{name} is the name of your format, and must match the name of the plugin itself.) \item An array of {\cf char *} called \emph{name}{\cf _output_extensions} that contains the list of file extensions that are likely to indicate a file of the right format. The list is terminated by a {\cf NULL} pointer. \end{enumerate} All of these items must be inside an `{\cf extern "C"}' block in order to avoid name mangling by the C++ compiler, and we provide handy macros {\cf OIIO_PLUGIN_EXPORTS_BEGIN} and {\cf OIIO_PLUGIN_EXPORTS_END} to mamke this easy. Depending on your compiler, you may need to use special commands to dictate that the symbols will be exported in the DSO; we provide a special {\cf OIIO_EXPORT} macro for this purpose, defined in {\fn export.h}. Putting this all together, we get the following for our JPEG example: \begin{code} OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int jpeg_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT JpgOutput *jpeg_output_imageio_create () { return new JpgOutput; } OIIO_EXPORT const char *jpeg_input_extensions[] = { "jpg", "jpe", "jpeg", NULL }; OIIO_PLUGIN_EXPORTS_END \end{code} \item The definition and implementation of an \ImageOutput subclass for this file format. It must publicly inherit \ImageOutput, and must overload the following methods which are ``pure virtual'' in the \ImageOutput base class: \begin{enumerate} \item {\cf format_name()} should return the name of the format, which ought to match the name of the plugin and by convention is strictly lower-case and contains no whitespace. \item {\cf supports()} should return {\cf true} if its argument names a feature supported by your format plugin, {\cf false} if it names a feature not supported by your plugin. See Section~\ref{sec:supportsfeaturelist} for the list of feature names. \item {\cf open()} should open the file and return true, or should return false if unable to do so (including if the file was found but turned out not to be in the format that your plugin is trying to implement). \item {\cf close()} should close the file, if open. \item {\cf write_scanline} should write a single scanline to the file, translating from internal to native data format and handling strides properly. \item The virtual destructor, which should {\cf close()} if the file is still open, addition to performing any other tear-down activities. \end{enumerate} Additionally, your \ImageOutput subclass may optionally choose to overload any of the following methods, which are defined in the \ImageOutput base class and only need to be overloaded if the default behavior is not appropriate for your plugin: \begin{enumerate} \item[(g)] {\cf write_scanlines()}, only if your format supports writing scanlines and you can get a performance improvement when outputting multiple scanlines at once. If you don't supply {\cf write_scanlines()}, the default implementation will simply call {\cf write_scanline()} separately for each scanline in the range. \item[(h)] {\cf write_tile()}, only if your format supports writing tiled images. \item[(i)] {\cf write_tiles()}, only if your format supports writing tiled images and you can get a performance improvement when outputting multiple tiles at once. If you don't supply {\cf write_tiles()}, the default implementation will simply call {\cf write_tile()} separately for each tile in the range. \item[(j)] {\cf write_rectangle()}, only if your format supports writing arbitrary rectangles. \item[(k)] {\cf write_image()}, only if you have a more clever method of doing so than the default implementation that calls {\cf write_scanline()} or {\cf write_tile()} repeatedly. \item[(l)] {\cf write_deep_scanlines()} and/or {\cf write_deep_tiles()}, only if your format supports ``deep'' data images. \end{enumerate} Here is how the class definition looks for our JPEG example. Note that the JPEG/JFIF file format does not support multiple subimages or tiled images. \begin{code} class JpgOutput : public ImageOutput { public: JpgOutput () { init(); } virtual ~JpgOutput () { close(); } virtual const char * format_name (void) const { return "jpeg"; } virtual bool supports (const std::string &property) const { return false; } virtual bool open (const std::string &name, const ImageSpec &spec, bool append=false); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); bool close (); private: FILE *m_fd; std::vector m_scratch; struct jpeg_compress_struct m_cinfo; struct jpeg_error_mgr m_jerr; void init () { m_fd = NULL; } }; \end{code} \end{enumerate} Your subclass implementation of {\cf open()}, {\cf close()}, and {\cf write_scanline()} are the heart of an \ImageOutput implementation. (Also {\cf write_tile()}, for those image formats that support tiled output.) An \ImageOutput implementation must properly handle all data formats and strides passed to {\cf write_scanline()} or {\cf write_tile()}, unlike an \ImageInput implementation, which only needs to read scanlines or tiles in their native format and then have the super-class handle the translation. But don't worry, all the heavy lifting can be accomplished with the following helper functions provided as protected member functions of \ImageOutput: \apiitem{const void * {\ce to_native_scanline} (TypeDesc format, const void *data, \\ \bigspc stride_t xstride, std::vector \&scratch);} Convert a full scanline of pixels (pointed to by \emph{data}) with the given \emph{format} and strides into contiguous pixels in the native format (described by the \ImageSpec returned by the {\cf spec()} member function). The location of the newly converted data is returned, which may either be the original \emph{data} itself if no data conversion was necessary and the requested layout was contiguous (thereby avoiding unnecessary memory copies), or may point into memory allocated within the \emph{scratch} vector passed by the user. In either case, the caller doesn't need to worry about thread safety or freeing any allocated memory (other than eventually destroying the scratch vector). \apiend \apiitem{const void * {\ce to_native_tile} (TypeDesc format, const void *data,\\ \bigspc stride_t xstride, stride_t ystride, stride_t zstride,\\ \bigspc std::vector \&scratch);} Convert a full tile of pixels (pointed to by \emph{data}) with the given \emph{format} and strides into contiguous pixels in the native format (described by the \ImageSpec returned by the {\cf spec()} member function). The location of the newly converted data is returned, which may either be the original \emph{data} itself if no data conversion was necessary and the requested layout was contiguous (thereby avoiding unnecessary memory copies), or may point into memory allocated within the \emph{scratch} vector passed by the user. In either case, the caller doesn't need to worry about thread safety or freeing any allocated memory (other than eventually destroying the scratch vector). \apiend \apiitem{const void * {\ce to_native_rectangle} (int xbegin, int xend, int ybegin, int yend, \\ \bigspc int zbegin, int zend, TypeDesc format, const void *data, \\ \bigspc stride_t xstride, stride_t ystride, stride_t zstride, \\ \bigspc std::vector \&scratch);} Convert a rectangle of pixels (pointed to by \emph{data}) with the given \emph{format}, dimensions, and strides into contiguous pixels in the native format (described by the \ImageSpec returned by the {\cf spec()} member function). The location of the newly converted data is returned, which may either be the original \emph{data} itself if no data conversion was necessary and the requested layout was contiguous (thereby avoiding unnecessary memory copies), or may point into memory allocated within the \emph{scratch} vector passed by the user. In either case, the caller doesn't need to worry about thread safety or freeing any allocated memory (other than eventually destroying the scratch vector). \apiend \bigskip \bigskip \noindent The remainder of this section simply lists the full implementation of our JPEG writer, which relies heavily on the open source {\fn jpeg-6b} library to perform the actual JPEG encoding. \includedcode{../jpeg.imageio/jpegoutput.cpp} \section{Tips and Conventions} \label{sec:plugintipsconventions} \product's main goal is to hide all the pesky details of individual file formats from the client application. This inevitably leads to various mismatches between a file format's true capabilities and requests that may be made through the \product APIs. This section outlines conventions, tips, and rules of thumb that we recommend for image file support. \subsection*{Readers} \begin{itemize} \item If the file format stores images in a non-spectral color space (for example, YUV), the reader should automatically convert to RGB to pass through the OIIO APIs. In such a case, the reader should signal the file's true color space via a \qkw{Foo:colorspace} attribute in the \ImageSpec. \item ``Palette'' images should be automatically converted by the reader to RGB. \item If the file supports thumbnail images in its header, the reader should store the thumbnail dimensions in attributes \qkw{thumbnail_width}, \qkw{thumbnail_height}, and \qkw{thumbnail_nchannels} (all of which should be {\cf int}), and the thumbnail pixels themselves in \qkw{thumbnail_image} as an array of channel values (the array length is the total number of channel samples in the thumbnail). \end{itemize} \subsection*{Writers} The overall rule of thumb is: try to always ``succeed'' at writing the file, outputting the closest approximation of the user's data as possible. But it is permissible to fail the {\cf open()} call if it is clearly nonsensical or there is no possible way to output a decent approximation of the user's data. Some tips: \begin{itemize} \item If the client application requests a data format not directly supported by the file type, silently write the supported data format that will result in the least precision or range loss. \item It is customary to fail a call to {\cf open()} if the \ImageSpec requested a number of color channels plainly not supported by the file format. As an exception to this rule, it is permissible for a file format that does not support alpha channels to silently drop the fourth (alpha) channel of a 4-channel output request. \item If the app requests a \qkw{Compression} not supported by the file format, you may choose as a default any lossless compression supported. Do not use a lossy compression unless you are fairly certain that the app wanted a lossy compression. \item If the file format is able to store images in a non-spectral color space (for example, YUV), the writer may accept a \qkw{Foo:colorspace} attribute in the \ImageSpec as a request to automatically convert and store the data in that format (but it will always be passed as RGB through the OIIO APIs). \item If the file format can support thumbnail images in its header, and the \ImageSpec contain attributes \qkw{thumbnail_width}, \qkw{thumbnail_height}, \qkw{thumbnail_nchannels}, and \qkw{thumbnail_image}, the writer should attempt to store the thumbnail if possible. \end{itemize} \section{Building ImageIO Plugins} \label{sec:buildingplugins} FIXME -- spell out how to compile and link plugins on each of the major platforms. \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/builtinplugins.tex0000644000175000017500000011174012271062644021453 0ustar mfvmfv\chapter{Bundled ImageIO Plugins} \label{chap:bundledplugins} \index{Plugins!bundled|(} This chapter lists all the image format plugins that are bundled with \product. For each plugin, we delineate any limitations, custom attributes, etc. The plugins are listed alphabetically by format name. \vspace{.25in} \section{BMP} \label{sec:bundledplugins:bmp} \index{BMP} BMP is a bitmap image file format used mostly on Windows systems. BMP files use the file extension {\cf .bmp}. BMP is not a nice format for high-quality or high-performance images. It only supports unsigned integer 1-, 2-, 4-, and 8- bits per channel; only grayscale, RGB, and RGBA; does not support MIPmaps, multiimage, or tiles. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.5in}|p{0.5in}|p{3.25in}} \ImageSpec Attribute & Type & BMP header data or explanation \\ \hline \qkw{XResolution} & float & hres \\ \qkw{YResolution} & float & vres \\ \qkw{ResolutionUnit} & string & always \qkw{m} (pixels per meter) \end{tabular} \vspace{.25in} \section{Cineon} \label{sec:bundledplugins:cineon} \index{Cineon} Cineon is an image file format developed by Kodak that is commonly used for scanned motion picture film and digital intermediates. Cineon files use the file extension {\cf .cin}. %FIXME \vspace{.25in} \section{DDS} \label{sec:bundledplugins:dds} \index{DDS} DDS (Direct Draw Surface) is an image file format designed by Microsoft for use in Direct3D graphics. DDS files use the extension {\cf .dds}. DDS is an awful format, with several compression modes that are all so lossy as to be completely useless for high-end graphics. Nevertheless, they are widely used in games and graphics hardware directly supports these compression modes. Alas. \product currently only supports reading DDS files, not writing them. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.5in}|p{0.5in}|p{3.5in}} \ImageSpec Attribute & Type & DDS header data or explanation \\ \hline \qkw{compression} & string & compression type \\ \qkw{oiio:BitsPerSample} & int & bits per sample \\ \qkw{textureformat} & string & Set correctly to one of \qkws{Plain Texture}, \qkws{Volume Texture}, or \qkws{CubeFace Environment}. \\ \qkw{texturetype} & string & Set correctly to one of \qkws{Plain Texture}, \qkws{Volume Texture}, or \qkws{Environment}. \\ \qkw{dds:CubeMapSides} & string & For environment maps, which cube faces are present (e.g., \qkw{+x -x +y -y} if $x$ \& $y$ faces are present, but not $z$). \\ \end{tabular} %\subsubsection*{Limitations} %\begin{itemize} %\item blah %\end{itemize} \vspace{.25in} \section{DPX} \label{sec:bundledplugins:dpx} \index{DPX} DPX (Digital Picture Exchange) is an image file format used for motion picture film scanning, output, and digital intermediates. DPX files use the file extension {\cf .dpx}. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.8in}|p{0.65in}|p{2.75in}} OIIO Attribute & Type & DPX header data or explanation \\ \hline \qkw{ImageDescription} & string & Description of image element \\ \qkw{Copyright} & string & Copyright statement \\ \qkw{Software} & string & Creator \\ \qkw{DocumentName} & string & Project name \\ \qkw{DateTime} & string & Creation date/time \\ \qkw{Orientation} & int & the orientation of the DPX image data (see \ref{metadata:orientation}) \\ \qkw{compression} & string & The compression type \\ \qkw{PixelAspectRatio} & float & pixel aspect ratio \\ \qkw{oiio:BitsPerSample} & int & the true bits per sample of the DPX file. \\ \qkw{oiio:Endian} & string & When writing, force a particular endianness for the output file (\qkw{little} or \qkw{big}) \\ \qkw{smpte:TimeCode} & int[2] & SMPTE time code (vecsemantics will be marked as TIMECODE) \\ \qkw{smpte:KeyCode} & int[7] & SMPTE key code (vecsemantics will be marked as KEYCODE) \\ \end{tabular} \noindent\begin{tabular}{p{1.8in}|p{0.65in}|p{2.75in}} OIIO Attribute & Type & DPX header data or explanation \\ \hline \qkw{dpx:Transfer} & string & Transfer characteristic \\ \qkw{dpx:Colorimetric} & string & Colorimetric specification \\ \qkw{dpx:ImageDescriptor} & string & ImageDescriptor \\ \qkw{dpx:Packing} & string & Image packing method \\ \qkw{dpx:TimeCode} & int & SMPTE time code \\ \qkw{dpx:UserBits} & int & SMPTE user bits \\ \qkw{dpx:SourceDateTime} & string & source time and date \\ \qkw{dpx:FilmEdgeCode} & string & FilmEdgeCode \\ \qkw{dpx:Signal} & string & Signal (\qkw{Undefined}, \qkw{NTSC}, \qkw{PAL}, etc.) \\ \qkw{dpx:UserData} & UCHAR[*] & User data (stored in an array whose length is whatever it was in the DPX file) \\ \qkw{dpx:EncryptKey} & int & Encryption key (-1 is not encrypted) \\ \qkw{dpx:DittoKey} & int & Ditto (0 = same as previous frame, 1 = new) \\ \qkw{dpx:LowData} & int & reference low data code value \\ \qkw{dpx:LowQuantity} & float & reference low quantity \\ \qkw{dpx:HighData} & int & reference high data code value \\ \qkw{dpx:HighQuantity} & float & reference high quantity \\ \qkw{dpx:XScannedSize} & float & X scanned size \\ \qkw{dpx:YScannedSize} & float & Y scanned size \\ \qkw{dpx:FramePosition} & int & frame position in sequence \\ \qkw{dpx:SequenceLength} & int & sequence length (frames) \\ \qkw{dpx:HeldCount} & int & held count (1 = default) \\ \qkw{dpx:FrameRate} & float & frame rate of original (frames/s) \\ \qkw{dpx:ShutterAngle} & float & shutter angle of camera (deg) \\ \qkw{dpx:Version} & string & version of header format \\ \qkw{dpx:Format} & string & format (e.g., \qkw{Academy}) \\ \qkw{dpx:FrameId} & string & frame identification \\ \qkw{dpx:SlateInfo} & string & slate information \\ \qkws{dpx:SourceImageFileName} & string & source image filename \\ \qkw{dpx:InputDevice} & string & input device name \\ \qkwf{dpx:InputDeviceSerialNumber} & string & input device serial number \\ \qkw{dpx:Interlace} & int & interlace (0 = noninterlace, 1 = 2:1 interlace)\\ \qkw{dpx:FieldNumber} & int & field number \\ \qkws{dpx:HorizontalSampleRate} & float & horizontal sampling rate (Hz) \\ \qkws{dpx:VerticalSampleRate} & float & vertical sampling rate (Hz) \\ \qkws{dpx:TemporalFrameRate} & float & temporal sampling rate (Hz) \\ \qkw{dpx:TimeOffset} & float & time offset from sync to first pixel (ms) \\ \qkw{dpx:BlackLevel} & float & black level code value \\ \qkw{dpx:BlackGain} & float & black gain \\ \qkw{dpx:BreakPoint} & float & breakpoint \\ \qkw{dpx:WhiteLevel} & float & reference white level code value \\ \qkw{dpx:IntegrationTimes} & float & integration time (s) \\ \end{tabular} %\subsubsection*{Limitations} %\begin{itemize} %\item blah %\end{itemize} \vspace{.25in} \section{Field3D} \label{sec:bundledplugins:field3d} \index{Field3D} Field3d is an open-source volume data file format. Field3d files commonly use the extension {\cf .f3d}. The official Field3D site is: \url{http://sites.google.com/site/field3d/} Currently, \product only reads Field3d files, and does not write them. Fields are comprised of multiple \emph{layers} (which appear to \product as subimages). Each layer/subimage may have a different name, resolution, and coordinate mapping. Layers may be scalar (1 channel) or vector (3 channel) fields, and the data may be {\cf half}, {\cf float}, or {\cf double}. \product always reports Field3D files as tiled. If the Field3d file has a ``block size'', the block size will be reported as the tile size. Otherwise, the tile size will be the size of the entire volume. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.6in}|p{0.6in}|p{3.0in}} \ImageSpec Attribute & Type & Field3d header data or explanation \\ \hline \qkw{ImageDescription} & string & unique layer name \\ \qkw{oiio:subimagename} & string & unique layer name \\ \qkw{field3d:partition} & string & the partition name \\ \qkw{field3d:layer} & string & the layer (a.k.a.\ attribute) name \\ \qkw{field3d:fieldtype} & string & field type, one of: \qkw{dense}, \qkw{sparse}, or \qkw{MAC} \\ \qkw{field3d:mapping} & string & the coordinate mapping type \\ \qkws{field3d:localtoworld} & matrix of doubles & if a matrixMapping, the local-to-world transformation matrix \\ \qkw{worldtocamera} & matrix & if a matrixMapping, the world-to-local coordinate mapping \\ \end{tabular} \vspace{10pt} The ``unique layer name'' is generally the partition name + ``:'' + attribute name (example: \qkw{defaultfield:density}), with the following exceptions: (1) if the partition and attribute names are identical, just one is used rather than it being pointlessly concatenated (e.g., \qkw{density}, not \qkw{density:density}); (2) if there are mutiple partitions + attribute combinations with identical names in the same file, ``.\emph{number}'' will be added after the partition name for subsequent layers (e.g., \qkw{default:density}, \qkw{default.2:density}, \qkw{default.3:density}). \vspace{.25in} \section{FITS} \label{sec:bundledplugins:fits} \index{FITS} FITS (Flexible Image Transport System) is an image file format used for scientific applications, particularly professional astronomy. FITS files use the file extension {\cf .fits}. Official FITS specs and other info may be found at: \url{http://fits.gsfc.nasa.gov/} \product supports multiple images in FITS files, and supports the following pixel data types: UINT8, UINT16, UINT32, FLOAT, DOUBLE. FITS files can store various kinds of arbitrary data arrays, but \product's support of FITS is mostly limited using FITS for image storage. Currently, \product only supports 2D FITS data (images), not 3D (volume) data, nor 1-D or higher-dimensional arrays. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.5in}|p{0.5in}|p{3.5in}} \ImageSpec Attribute & Type & FITS header data or explanation \\ \hline \qkw{Orientation} & int & derived from FITS ``ORIENTAT'' field. \\ \qkw{DateTime} & string & derived from the FITS ``DATE'' field. \\ \qkw{Comment} & string & FITS ``COMMENT'' (*) \\ \qkw{History} & string & FITS ``HISTORY'' (*) \\ \qkw{Hierarch} & string & FITS ``HIERARCH'' (*) \\[1.5ex] \emph{other} & & all other FITS keywords will be added to the \ImageSpec as arbitrary named metadata. \end{tabular} \noindent (*) Note: If the file contains multiple COMMENT, HISTORY, or HIERARCH fields, their text will be appended to form a single attribute (of each) in \product's \ImageSpec. \vspace{.25in} \section{GIF} \label{sec:bundledplugins:gif} \index{GIF} GIF (Graphics Interchange Format) is an image file format developed by CompuServe in 1987. Nowadays it is widely used to display basic animations despite its technical limitations. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.5in}|p{0.5in}|p{3.25in}} \ImageSpec Attribute & Type & GIF header data or explanation \\ \hline \qkw{gif:DelayMs} & int & Delay between frames in miliseconds. \\ \qkw{gif:Interlacing} & int & Specifies if image is interlaced (0 or 1). \\ \qkw{ImageDescription} & string & The GIF comment field. \end{tabular} \subsubsection*{Limitations} \begin{itemize} \item GIF only supports 3-channel (RGB) images and at most 8 bits per channel. \item Each subimage can include its own palette or use global palette. Palettes contain up to 256 colors of which one can be used as background color. It is then emulated with additional Alpha channel by \product's reader. \end{itemize} \vspace{.25in} \section{HDR/RGBE} \label{sec:bundledplugins:hdr} \index{HDR} \index{RGBE} HDR (High Dynamic Range), also known as RGBE (rgb with extended range), is a simple format developed for the Radiance renderer to store high dynamic range images. HDR/RGBE files commonly use the file extensions {\cf .hdr}. The format is described in this section of the Radiance documentation: \url{http://radsite.lbl.gov/radiance/refer/filefmts.pdf} RGBE does not support tiles, multiple subimages, mipmapping, true half or float pixel values, or arbitrary metadata. Only RGB (3 channel) files are supported. RGBE became important because it was developed at a time when no standard file formats supported high dynamic range, and is still used for many legacy applications and to distribute HDR environment maps. But newer formats with native HDR support, such as OpenEXR, are vastly superior and should be preferred except when legacy file access is required. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.5in}|p{0.5in}|p{3.25in}} \ImageSpec Attribute & Type & RGBE header data or explanation \\ \hline \qkw{Orientation} & int & encodes the orientation (see \ref{metadata:orientation}) \\ {\cf ImageSpec.gamma} & float & the gamma correction specified in the RGBE header. \end{tabular} \vspace{.25in} \section{ICO} \label{sec:bundledplugins:ico} \index{ICO} ICO is an image file format used for small images (usually icons) on Windows. ICO files use the file extension {\cf .ico}. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.5in}|p{0.5in}|p{3.25in}} \ImageSpec Attribute & Type & ICO header data or explanation \\ \hline \qkw{oiio:BitsPerSample} & int & the true bits per sample in the ICO file. \\ \qkw{ico:PNG} & int & if nonzero, will cause the ICO to be written out using PNG format. \end{tabular} \subsubsection*{Limitations} \begin{itemize} \item ICO only supports UINT8 and UINT16 formats; all output images will be silently converted to one of these. \item ICO only supports \emph{small} images, up to $256 \times 256$. Requests to write larger images will fail their {\cf open()} call. \end{itemize} \vspace{.25in} \vspace{.25in} \section{IFF} \label{sec:bundledplugins:iff} \index{IFF} IFF files are used by Autodesk Maya and use the file extension {\cf .iff}. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.8in}|p{0.65in}|p{2.75in}} OIIO Attribute & Type & DPX header data or explanation \\ \hline \qkw{Artist} & string & The IFF ``author'' \\ \qkw{DateTime} & string & Creation date/time \\ \qkw{compression} & string & The compression type \\ \qkw{oiio:BitsPerSample} & int & the true bits per sample of the DPX file. \\ \end{tabular} %\subsubsection*{Limitations} %\begin{itemize} %\item blah %\end{itemize} \vspace{.25in} \section{JPEG} \label{sec:bundledplugins:jpeg} \index{JPEG} JPEG (Joint Photographic Experts Group), or more properly the JFIF file format containing JPEG-compressed pixel data, is one of the most popular file formats on the Internet, with applications, and from digital cameras, scanners, and other image acquisition devices. JPEG/JFIF files usually have the file extension {\cf .jpg}, {\cf .jpe}, {\cf .jpeg}, {\cf .jif}, {\cf .jfif}, or {\cf .jfi}. The JFIF file format is described by \url{http://www.w3.org/Graphics/JPEG/jfif3.pdf}. Although we strive to support JPEG/JFIF because it is so widely used, we acknowledge that it is a poor format for high-end work: it supports only 1- and 3-channel images, has no support for alpha channels, no support for high dynamic range or even 16 bit integer pixel data, by convention stores sRGB data and is ill-suited to linear color spaces, and does not support multiple subimages or MIPmap levels. There are newer formats also blessed by the Joint Photographic Experts Group that attempt to address some of these issues, such as JPEG-2000, but these do not have anywhere near the acceptance of the original JPEG/JFIF format. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.5in}|p{0.5in}|p{3.25in}} \ImageSpec Attribute & Type & JPEG header data or explanation \\ \hline \qkw{ImageDescription} & string & the JPEG Comment field \\ \qkw{Orientation} & int & the image orientation \\[2ex] \qkw{XResolution}, \qkw{YResolution}, \qkw{ResolutionUnit} & & The resolution and units from the Exif header \\ & & \\ Exif, IPTC, XMP, GPS & & Extensive Exif, IPTC, XMP, and GPS data are supported by the reader/writer, and you should assume that nearly everything described Appendix~\ref{chap:stdmetadata} is properly translated when using JPEG files. \end{tabular} \subsubsection*{Limitations} \begin{itemize} \item JPEG/JFIF only supports 1- (grayscale) and 3-channel (RGB) images. As a special case, \product's JPEG writer will accept 4-channel image data and silently drop the alpha channel while outputting. Other channel count requests (i.e., anything other than 1, 3, and 4) will cause {\cf open()} to fail, since it is not possible to write a JFIF file with other than 1 or 3 channels. \item Since JPEG/JFIF only supports 8 bits per channel, \product's JPEG/JFIF writer will silently convert to UINT8 upon output, regardless of requests to the contrary from the calling program. \item \product's JPEG/JFIF reader and writer always operate in scanline mode and do not support tiled image input or output. \end{itemize} \vspace{.25in} \section{JPEG-2000} \label{sec:bundledplugins:jpeg2000} \index{Jpeg 2000} JPEG-2000 is a successor to the popular JPEG/JFIF format, that supports better (wavelet) compression and a number of other extensions. It's geared toward photography. JPEG-2000 files use the file extensions {\cf .jp2} or {\cf .j2k}. The official JPEG-2000 format specification and other helpful info may be found at \url{http://www.jpeg.org/JPEG2000.htm}. JPEG-2000 is not yet widely used, so \product's support of it is preliminary. In particular, we are not yet very good at handling the metadata robustly. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.75in}|p{0.5in}|p{3.0in}} \ImageSpec Attribute & Type & JPEG-2000 header data or explanation \\ \hline \qkws{jpeg2000:streamformat} & string & specifies the JPEG-2000 stream format (\qkw{none} or \qkw{jpc}) \end{tabular} \vspace{.25in} \section{OpenEXR} \label{sec:bundledplugins:openexr} \index{OpenEXR} OpenEXR is an image file format developed by Industrial Light \& Magic, and subsequently open-sourced. OpenEXR's strengths include support of high dynamic range imagery ({\cf half} and {\cf float} pixels), tiled images, explicit support of MIPmaps and cubic environment maps, arbitrary metadata, and arbitrary numbers of color channels. OpenEXR files use the file extension {\cf .exr}. The official OpenEXR site is \url{http://www.openexr.com/}. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.75in}|p{0.5in}|p{3.0in}} \ImageSpec Attribute & Type & OpenEXR header data or explanation \\ \hline {\cf width}, {\cf height}, {\cf x}, {\cf y} & & {\cf dataWindow} \\ & & \\ {\cf\small full_width}, {\cf\small full_height}, {\cf\small full_x}, {\cf\small full_y} & & {\cf displayWindow}. \\ & & \\ \qkw{worldtocamera} & matrix & worldToCamera \\ \qkw{worldtoscreen} & matrix & worldToNDC \\ \qkw{ImageDescription} & string & comments \\ \qkw{Copyright} & string & owner \\ \qkw{DateTime} & string & capDate \\ \qkw{PixelAspectRatio} & float & pixelAspectRatio \\ \qkw{ExposureTime} & float & expTime \\ \qkw{FNumber} & float & aperture \\ \qkw{compression} & string & one of: \qkw{none}, \qkw{rle}, \qkw{zip}, \qkw{piz}, \qkw{pxr24}, \qkw{b44}, or \qkw{b44a}. If the writer receives a request for a compression type it does not recognize, it will use \qkw{zip} by default. \\ \qkw{textureformat} & string & set to \qkw{Plain Texture} for MIP-mapped OpenEXR files, \qkw{CubeFace Environment} or \qkw{Latlong Environment} for OpenEXR environment maps. Non-environment non-MIP-mapped OpenEXR files will not set this attribute. \\ \qkw{wrapmodes} & string & wrapmodes \\ \qkw{smpte:TimeCode} & int[2] & SMPTE time code (vecsemantics will be marked as TIMECODE) \\ \qkw{smpte:KeyCode} & int[7] & SMPTE key code (vecsemantics will be marked as KEYCODE) \\ %\qkw{oiio:updirection} & string & Will be set to \qkw{y} for OpenEXR % latlong environment maps to indicate that OpenEXR dictates a % right-handed, ``$y$ is up'' coordinate system. \\ %\qkw{oiio:sampleborder} & int & Will be set to 1 for OpenEXR environment % maps to indicate that OpenEXR dictates that boundary texels sample exactly % on the texture border (pole, meridian, or cube edge).\\[2ex] \qkw{openexr:lineOrder} & string & the OpenEXR lineOrder attribute (set to \qkws{increasingY}, \qkws{randomY}, or \qkws{decreasingY}). \\ \qkws{openexr:roundingmode} & int & the MIPmap rounding mode of the file. \\[2ex] \emph{other} & & All other attributes will be added to the \ImageSpec by their name and apparent type. \end{tabular} \subsubsection*{Limitations} \begin{itemize} \item The OpenEXR format does not currently support multiple subimages, except for the special case of MIP-maps. \item The OpenEXR format only supports HALF, FLOAT, and UINT32 pixel data. \product's OpenEXR writer will silently convert data in formats (including the common UINT8 and UINT16 cases) to HALF data for output. \end{itemize} \vspace{.25in} \section{PNG} \label{sec:bundledplugins:png} \index{PNG} PNG (Portable Network Graphics) is an image file format developed by the open source community as an alternative to the GIF, after Unisys started enforcing patents allegedly covering techniques necessary to use GIF. PNG files use the file extension {\cf .png}. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.75in}|p{0.5in}|p{3.0in}} \ImageSpec Attribute & Type & PNG header data or explanation \\ \hline \qkw{ImageDescription} & string & Description \\ \qkw{Artist} & string & Author \\ \qkw{DocumentName} & string & Title \\ \qkw{DateTime} & string & the timestamp in the PNG header \\ \qkw{PixelAspectRatio} & float & pixel aspect ratio \\ \qkw{XResolution} \qkw{YResolution} \qkw{ResolutionUnit} & & resolution and units from the PNG header. \end{tabular} \subsubsection*{Limitations} \begin{itemize} \item PNG stupidly specifies that any alpha channel is ``unassociated'' (i.e., that the color channels are not ``premultiplied'' by alpha). This is a disaster, since it results in bad loss of precision for alpha image compositing, and even makes it impossible to properly represent certain additive glows and other desirable pixel values. \product automatically associates alpha (i.e., multiplies colors by alpha) upon input and deassociates alpha (divides colors by alpha) upon output in order to properly conform to the OIIO convention (and common sense) that all pixel values passed through the OIIO APIs should use associated alpha. \item PNG only supports UINT8 and UINT16 output; other requested formats will be automatically converted to one of these. \end{itemize} \vspace{.25in} \section{PNM / Netpbm} \label{sec:bundledplugins:pnm} \index{PNM} The Netpbm project, a.k.a.\ PNM (portable ``any'' map) defines PBM, PGM, and PPM (portable bitmap, portable graymap, portable pixmap) files. Without loss of generality, we will refer to these all collectively as ``PNM.'' These files have extensions {\cf .pbm}, {\cf .pgm}, and {\cf .ppm} and customarily correspond to bi-level bitmaps, 1-channel grayscale, and 3-channel RGB files, respectively, or {\cf .pnm} for those who reject the nonsense about naming the files depending on the number of channels and bitdepth. PNM files are not much good for anything, but because of their historical significance and extreme simplicity (that causes many ``amateur'' programs to write images in these formats), \product supports them. PNM files do not support floating point images, anything other than 1 or 3 channels, no tiles, no multi-image, no MIPmapping. It's not a smart choice unless you are sending your images back to the 1980's via a time machine. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.3in}|p{0.5in}|p{3.50in}} \ImageSpec Attribute & Type & PNG header data or explanation \\ \hline \qkw{oiio:BitsPerSample} & int & the true bits per sample of the file (1 for true PBM files, even though OIIO will report the {\cf format} as UINT8). \\ \qkw{pnm:binary} & int & nonzero if the file itself used the PNM binary format, 0 if it used ASCII. The PNM writer honors this attribute in the \ImageSpec to determine whether to write an ASCII or binary file. \end{tabular} \vspace{.25in} \section{PSD} \label{sec:bundledplugins:psd} \index{PSD} % FIXME \vspace{.25in} \section{Ptex} \label{sec:bundledplugins:ptex} \index{Ptex} Ptex is a special per-face texture format developed by Walt Disney Feature Animation. The format and software to read/write it are open source, and available from \url{http://ptex.us/}. Ptex files commonly use the file extension {\cf .ptex}. \product's support of Ptex is still incomplete. We can read pixels from Ptex files, but the \TextureSystem doesn't properly filter across face boundaries when using it as a texture. \product currently does not write Ptex files at all. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.75in}|p{0.5in}|p{3.0in}} \ImageSpec Attribute & Type & Ptex header data or explanation \\ \hline \qkw{ptex:meshType} & string & the mesh type, either \qkw{triangle} or \qkw{quad}. \\ \qkw{ptex:hasEdits} & int & nonzero if the Ptex file has edits. \\ \qkw{wrapmode} & string & the wrap mode as specified by the Ptex file. \\ \emph{other} & & Any other arbitrary metadata in the Ptex file will be stored directly as attributes in the \ImageSpec. \end{tabular} \vspace{.25in} \section{RLA} \label{sec:bundledplugins:rla} \index{RLA} RLA (Run-Length encoded, version A) is an early CGI renderer output format, originating from Wavefront Advanced Visualizer and used primarily by software developed at Wavefront. RLA files commonly use the file extension {\cf .rla}. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.75in}|p{0.5in}|p{3.0in}} \ImageSpec Attribute & Type & RLA header data or explanation \\ \hline {\cf width}, {\cf height}, {\cf x}, {\cf y} & & RLA ``active/viewable'' window. \\ & & \\ {\cf\small full_width}, {\cf\small full_height}, {\cf\small full_x}, {\cf\small full_y} & & RLA ``full'' window. \\ & & \\ \qkw{rla:FrameNumber} & int & frame sequence number. \\ \qkw{rla:Revision} & int & file format revision number, currently \qkw{0xFFFE}. \\ \qkw{rla:JobNumber} & int & job number ID of the file. \\ \qkw{rla:FieldRendered} & int & whether the image is a field-rendered (interlaced) one (\qkw{0} for false, non-zero for true). \\ \qkw{rla:FileName} & string & name under which the file was orignally saved. \\ \qkw{ImageDescription} & string & RLA ``Description'' of the image. \\ \qkw{Software} & string & name of software used to save the image. \\ \qkw{HostComputer} & string & name of machine used to save the image. \\ \qkw{Artist} & string & RLA ``UserName'': logon name of user who saved the image. \\ \qkw{rla:Aspect} & string & aspect format description string. \\ \qkw{rla:ColorChannel} & string & textual description of color channel data format (usually \qkw{rgb}). \\ \qkw{rla:Time} & string & description (format not standardized) of amount of time spent on creating the image. \\ \qkw{rla:Filter} & string & name of post-processing filter applied to the image. \\ \qkw{rla:AuxData} & string & textual description of auxiliary channel data format. \\ \qkw{rla:AspectRatio} & float & image aspect ratio. \\ \qkw{rla:RedChroma} & vec2 or vec3 of floats & red point XY (vec2) or XYZ (vec3) coordinates. \\ \qkw{rla:GreenChroma} & vec2 or vec3 of floats & green point XY (vec2) or XYZ (vec3) coordinates. \\ \qkw{rla:BlueChroma} & vec2 or vec3 of floats & blue point XY (vec2) or XYZ (vec3) coordinates. \\ \qkw{rla:WhitePoint} & vec2 or vec3 of floats & white point XY (vec2) or XYZ (vec3) coordinates. \\ \end{tabular} \subsubsection*{Limitations} \begin{itemize} \item \product will only write 1 image to 1 file, multiple subimages are not supported by the writer (but are supported by the reader). \end{itemize} \vspace{.25in} \section{SGI} \label{sec:bundledplugins:sgi} \index{SGI files} The SGI image format was a simple raster format used long ago on SGI machines. SGI files use the file extensions {\cf sgi}, {\cf rgb}, {\cf rgba}, \qkw{bw}, \qkw{int}, and \qkw{inta}. The SGI format is sometimes used for legacy apps, but has little merit otherwise: no support for tiles, no MIPmaps, no multi-subimage, only 8- and 16-bit integer pixels (no floating point), only 1-4 channels. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.75in}|p{0.5in}|p{3.0in}} \ImageSpec Attribute & Type & SGI header data or explanation \\ \hline \qkw{ImageDescription} & string & image name \\ \qkw{Compression} & string & thee compression of the SGI file (\qkw{rle}, if RLE compression is used). \end{tabular} \vspace{.25in} \section{Softimage PIC} \label{sec:bundledplugins:pic} \index{Softimage PIC} Softimage PIC is an image file format used by the SoftImage 3D application, and some other programs that needed to be compatible with it. Softimage files use the file extension {\cf .pic}. The Softimage PIC format is sometimes used for legacy apps, but has little merit otherwise, so currently \product only reads Softimage files and is unable to write them. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.75in}|p{0.5in}|p{3.0in}} \ImageSpec Attribute & Type & PIC header data or explanation \\ \hline \qkw{ImageDescription} & string & comment \\ \qkw{oiio:BitsPerSample} & int & the true bits per sample in the PIC file. \end{tabular} \vspace{.25in} \section{Targa} \label{sec:bundledplugins:targa} \index{Targa} Targa (a.k.a.\ Truevision TGA) is an image file format with little merit except that it is very simple and is used by many legacy applications. Targa files use the file extension {\cf .tga}, or, much more rarely, {\cf .tpic}. The official Targa format specification may be found at\\ \url{http://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf}. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.75in}|p{0.5in}|p{3.0in}} \ImageSpec Attribute & Type & TGA header data or explanation \\ \hline \qkw{ImageDescription} & string & comment \\ \qkw{Artist} & string & author \\ \qkw{DocumentName} & string & job name/ID \\ \qkw{Software} & string & software name \\ \qkw{DateTime} & string & TGA time stamp \\ \qkw{targa:JobTime} & string & TGA ``job time.'' \\ \qkw{Compression} & string & values of \qkw{none} and \qkw{rle} are supported. The writer will use RLE compression if any unknown compression methods are requested. \\ \qkw{targa:ImageID} & string & Image ID \\ \qkw{PixelAspectRatio} & float & pixel aspect ratio \\ \qkw{oiio:BitsPerSample} & int & the true (in the file) bits per sample. \\ \end{tabular} \\ \vspace{.25in} If the TGA file contains a thumbnail, its dimensions will be stored in the attributes \qkw{thumbnail_width}, \qkw{thumbnail_height}, and \qkw{thumbnail_nchannels}, and the thumbnail pixels themselves will be stored in \qkw{thumbnail_image} (as an array of UINT8 values, whose length is the total number of channel samples in the thumbnail). \subsubsection*{Limitations} \begin{itemize} \item The Targa reader reserves enough memory for the entire image. Therefore it is not a good choice for high-performance image use such as would be used for \ImageCache or \TextureSystem. \item Targa files only support 8- and 16-bit unsigned integers (no signed, floating point, or HDR capabilities); the \product TGA writer will silently convert all output images to UINT8 (except if UINT16 is explicitly requested). \item Targa only supports grayscale, RGB, and RGBA; the \product TGA writer will fail its call to {\cf open()} if it is asked create a file with more than 4 color channels. \end{itemize} \vspace{.25in} \section{TIFF} \label{sec:bundledplugins:tiff} \index{TIFF} TIFF (Tagged Image File Format) is a flexible file format created by Aldus, now controlled by Adobe. TIFF supports nearly everything anybody could want in an image format (and has extactly the complexity you would expect from such a requirement). TIFF files commonly use the file extensions {\cf .tif} or, {\cf .tiff}. Additionally, \product associates the following extensions with TIFF files by default: {\cf .tx}, {\cf .env}, {\cf .sm}, {\cf .vsm}. The official TIFF format specification may be found here: \url{http://partners.adobe.com/public/developer/tiff/index.html} ~ The most popular library for reading TIFF directly is {\cf libtiff}, available here: \url{http://www.remotesensing.org/libtiff/} ~ \product uses {\cf libtiff} for its TIFF reading/writing. We like TIFF a lot, especially since its complexity can be nicely hidden behind OIIO's simple APIs. It supports a wide variety of data formats (though unfortunately not {\cf half}), an arbitrary number of channels, tiles and multiple subimages (which makes it our preferred texture format), and a rich set of metadata. \product supports the vast majority of TIFF features, including: tiled images (\qkw{tiled}) as well as scanline images; multiple subimages per file (\qkw{multiimage}); MIPmapping (using multi-subimage; that means you can't use multiimage and MIPmaps simultaneously); data formats 8- 16, and 32 bit integer (both signed and unsigned), and 32- and 64-bit floating point; palette images (will convert to RGB); ``miniswhite'' photometric mode (will convert to ``minisblack''). The TIFF plugin attempts to support all the standard Exif, IPTC, and XMP metadata if present. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{2.0in}|p{0.5in}|p{2.75in}} \ImageSpec Attribute & Type & TIFF header data or explanation \\ \hline {\cf ImageSpec::x} & int & XPosition \\ {\cf ImageSpec::y} & int & YPosition \\ {\cf ImageSpec::full_width} & int & PIXAR\_IMAGEFULLWIDTH \\ {\cf ImageSpec::full_length} & int & PIXAR\_IMAGEFULLLENGTH \\ \qkw{ImageDescription} & string & ImageDescription \\ \qkw{DateTime} & string & DateTime \\ \qkw{Software} & string & Software \\ \qkw{Artist} & string & Artist \\ \qkw{Copyright} & string & Copyright \\ \qkw{Make} & string & Make \\ \qkw{Model} & string & Model \\ \qkw{DocumentName} & string & DocumentName \\ \qkw{HostComputer} & string & HostComputer \\ \qkws{XResultion} \qkws{YResolution} & float & XResolution, YResolution \\ \qkws{ResolutionUnit} & string & ResolutionUnit (\qkw{in} or \qkw{cm}). \\ \qkw{Orientation} & int & Orientation \\ \qkw{textureformat} & string & {\cf PIXAR_TEXTUREFORMAT} \\ \qkw{wrapmodes} & string & {\cf PIXAR_WRAPMODES} \\ \qkw{fovcot} & float & {\cf PIXAR_FOVCOT} \\ \qkw{worldtocamera} & matrix & PIXAR\_MATRIX\_WORLDTOCAMERA \\ \qkw{worldtoscreen} & matrix & PIXAR\_MATRIX\_WORLDTOSCREEN\\ \qkw{comrpession} & string & based on TIFF Compression (one of \qkw{none}, \qkw{lzw}, \qkw{ccittrle}, \qkw{zip}, \qkw{packbits}).\\ \qkw{tiff:compression} & int & the original integer code from the TIFF Compression tag.\\ \qkw{tiff:planarconfig} & string & PlanarConfiguration (\qkw{separate} or \qkw{contig}). The \product TIFF writer will honor such a request in the \ImageSpec.\\ \qkwf{tiff:PhotometricInterpretation} & int & Photometric \\ \qkw{tiff:PageName} & string & PageName \\ \qkw{tiff:PageNumber} & int & PageNumber \\ \qkw{tiff:RowsPerStrip} & int & RowsPerStrip \\ \qkw{tiff:subfiletype} & 1 & SubfileType \\ \qkw{Exif:*} & & A wide variety of EXIF data are honored, and are all prefixed with \qkw{Exif:}.\\ \qkw{oiio:BitsPerSample} & int & The actual bits per sample in the file (may differ from {\cf ImageSpec::format}).\\ \qkw{oiio:UnassociatedAlpha} & int & Nonzero if the alpha channel contained ``unassociated'' alpha. \\ \end{tabular} \subsubsection*{Limitations} \product's TIFF reader and writer have some limitations you should be aware of: \begin{itemize} \item No separate per-channel data formats (not supported by {\cf libtiff}). \item Only multiples of 8 bits per pixel may be passed through \product's APIs, e.g., 1-, 2-, and 4-bits per pixel will be reported by OIIO as 8 bit images; 12 bits per pixel will be reported as 16, etc. But the \qkw{oiio:BitsPerSample} attribute in the \ImageSpec will correctly report the original bit depth of the file. Note that the TIFF specification itself does not support 16-bit floating point pixels ({\cf half} data). \end{itemize} \vspace{.25in} \section{Webp} \label{sec:bundledplugins:webp} \index{WebP} % FIXME \vspace{.25in} \section{Zfile} \label{sec:bundledplugins:zfile} \index{Zfile} Zfile is a very simple format for writing a depth ($z$) image, originally from Pixar's PhotoRealistic RenderMan but now supported by many other renderers. It's extremely minimal, holding only a width, height, world-to-screen and camera-to-screen matrices, and uncompressed float pixels of the z-buffer. Zfile files use the file extension {\cf .zfile}. %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.75in}|p{0.5in}|p{3.0in}} \ImageSpec Attribute & Type & Zfile header data or explanation \\ \hline \qkw{worldtocamera} & matrix & NP \\ \qkw{worldtoscreen} & matrix & Nl \\ \end{tabular} \index{Plugins!bundled|)} \chapwidthend %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{comment} FOO () is an image file format. Strengths. FOO files use the file extension {\cf .foo}. The official FOO format specification may be found at \url{} . %\subsubsection*{Attributes} \vspace{.125in} \noindent\begin{tabular}{p{1.5in}|p{0.5in}|p{3.5in}} \ImageSpec Attribute & Type & FOO header data or explanation \\ \hline \end{tabular} \subsubsection*{Limitations} \begin{itemize} \item blah \end{itemize} \end{comment} openimageio-1.3.12~dfsg0.orig/src/doc/CLA-INDIVIDUAL0000644000175000017500000001610712271062644017632 0ustar mfvmfv Software Grant and Corporate Contributor License Agreement ("Agreement") (modeled after http://www.apache.org/licenses/) Thank you for your interest in OpenImageIO (the "Project", which collectively includes its authors, contributors, and any encompassing organization). In order to clarify the intellectual property license granted with Contributions from any person or entity, the Project must have a Contributor License Agreement ("CLA") on file that has been signed by each Contributor, indicating agreement to the license terms below. This license is for your protection as a Contributor as well as the protection of the Project and its users; it does not change your rights to use your own Contributions for any other purpose. If you have not already done so, sign this agreement, scan it, and email to info@openimageio.org. Or contact that email to request a FAX number or US postal address to mail an original. Please read this document carefully before signing and keep a copy for your records. Full name: ______________________________________________________ Mailing Address: ________________________________________________ _________________________________________________________________ _________________________________________________________________ Country: ______________________________________________________ Telephone: ______________________________________________________ Facsimile: ______________________________________________________ E-Mail: ______________________________________________________ You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the Project. In return, the Project shall not use Your Contributions in a way that is contrary to the public benefit or inconsistent with its nonprofit status and bylaws in effect at the time of the Contribution. Except for the license granted herein to the Project and recipients of software distributed by the Project, You reserve all right, title, and interest in and to Your Contributions. 1. Definitions. "You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with the Project. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to the Project for inclusion in, or documentation of, any of the products owned or managed by the Project (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Project or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Project for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution." 2. Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to the Project and to recipients of software distributed by the Project a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works. 3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to the Project and to recipients of software distributed by the Project a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed. 4. You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your Contributions, you represent that you have received permission to make Contributions on behalf of that employer, that your employer has waived such rights for your Contributions to the Project, or that your employer has executed a separate Corporate CLA with the Project. 5. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions. 6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. 7. Should You wish to submit work that is not Your original creation, You may submit it to the Project separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [named here]". 8. You agree to notify the Project of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect. Please sign: __________________________________ Date: ________________ openimageio-1.3.12~dfsg0.orig/src/doc/pythonbindings.tex0000644000175000017500000024000412271062644021436 0ustar mfvmfv\chapter{Python Bindings} \label{chap:pythonbindings} \indexapi{Python|()} \section{Overview} \OpenImageIO provides Python language bindings for much of its functionality. \smallskip You must ensure that the environment variable {\cf PYTHONPATH} includes the {\cf python} subdirectory of the \OpenImageIO installation. \smallskip A Python program must import the {\cf OpenImageIO} package: \begin{code} import OpenImageIO \end{code} \noindent In most of our examples below, we assume that for the sake of brevity, we will alias the package name as follows: \begin{code} import OpenImageIO as oiio from OpenImageIO import ImageInput, ImageOutput from OpenImageIO import ImageBuf, ImageSpec, ImageBufAlgo \end{code} \section{TypeDesc} \label{sec:pythontypedesc} The \TypeDesc class that describes data types of pixels and metadata, described in detail in Section~\ref{sec:TypeDesc}, is replicated for Python. \apiitem{BASETYPE} The {\cf BASETYPE} enum corresponds to the C++ {\cf TypeDesc::BASETYPE} and contains the following values: \\ {\cf UNKNOWN NONE UINT8 INT8 UINT16 INT16 UINT32 INT32 UINT64 INT64 \\ HALF FLOAT DOUBLE STRING PTR} \\ These names are also exported to the {\cf OpenImageIO} namespace. \apiend \apiitem{AGGREGATE} The {\cf AGGREGATE} enum corresponds to the C++ {\cf TypeDesc::AGGREGATE} and contains the following values: \\ {\cf SCALAR VEC2 VEC3 VEC4 MATRIX44} \\ These names are also exported to the {\cf OpenImageIO} namespace. \apiend \apiitem{VECSEMANTICS} The {\cf VECSEMANTICS} enum corresponds to the C++ {\cf TypeDesc::VECSEMANTICS} and contains the following values: \\ {\cf NOSEMANTICS COLOR POINT VECTOR NORMAL TIMECODE KEYCODE} \\ These names are also exported to the {\cf OpenImageIO} namespace. \apiend \apiitem{TypeDesc () \\ TypeDesc (basetype) \\ TypeDesc (basetype, aggregate) \\ TypeDesc (basetype, aggregate, vecsemantics) \\ TypeDesc (basetype, aggregate, vecsemantics, arraylen) \\ TypeDesc (str)} Construct a {\cf TypeDesc} object. \noindent Examples: \begin{code} import OpenImageIO as oiio # make a default (UNKNOWN) TypeDesc t = TypeDesc() # make a TypeDesc describing an unsigned 8 bit int t = TypeDesc(oiio.UINT8) # make a TypeDesc describing an array of 14 'half' values t = TypeDesc(oiio.HALF, oiio.SCALAR, oiio.NOSEMANTICS, 14) # make a TypeDesc describing a float point t = TypeDesc(oiio.FLOAT, oiio.VEC3, oiio.POINT) # Some constructors from a string description t = TypeDesc("uint8") t = TypeDesc("half[14]") t = TypeDesc("point") # equiv to FLOAT, VEC3, POINT \end{code} \apiend \apiitem{TypeDesc.TypeFloat() \\ TypeDesc.TypeInt() \\ TypeDesc.TypeString() \\ TypeDesc.TypeColor() \\ TypeDesc.TypePoint() \\ TypeDesc.TypeVector() \\ TypeDesc.TypeNormal() \\ TypeDesc.TypeMatrix()} Pre-constructed \TypeDesc objects for some common types. \noindent Example: \begin{code} t = TypeDesc.TypeFloat() \end{code} \apiend \apiitem{string {\ce str} (TypeDesc)} Returns a string that describes the \TypeDesc. \noindent Example: \begin{code} print str(TypeDesc(oiio.UINT16)) > int16 \end{code} \apiend \apiitem{TypeDesc.{\ce basetype} \\ TypeDesc.{\ce aggregate} \\ TypeDesc.{\ce vecsemantics} \\ TypeDesc.{\ce arraylen}} Access to the raw fields in the \TypeDesc. \noindent Example: \begin{code} t = TypeDesc(...) if t.basetype == oiio.FLOAT : print "It's made of floats" \end{code} \apiend \apiitem{int TypeDesc.{\ce size} () \\ int TypeDesc.{\ce basesize} () \\ TypeDesc TypeDesc.{\ce elementtype} () \\ int TypeDesc.{\ce numelements} () \\ int TypeDesc.{\ce elementsize} ()} The {\cf size()} is the size in bytes, of the type described. The {\cf basesize()} is the size in bytes of the {\cf basetype}. The {\cf elementtype()} is the type of each array element, if it is an array, or just the full type if it is not an array. The {\cf elementsize()} is the size, in bytes, of the {\cf elementtype} (thus, returning the same value as {\cf size()} if the type is not an array). The {\cf numelements()} method returns {\cf arraylen} if it is an array, or {\cf 1} if it is not an array. \noindent Example: \begin{code} t = TypeDesc("point[2]") print "size =", t.size() print "elementtype =", t.elementtype() print "elementsize =", t.elementsize() > size = 24 > elementtype = point > elementsize = 12 \end{code} \apiend \apiitem{bool typedesc {\ce ==} typedesc \\ bool typedesc {\ce !=} typedesc \\ bool TypeDesc.{\ce equivalent} (typedesc) \\} Test for equality or inequality. The {\cf equivalent()} method is more forgiving than {\cf ==}, in that it considers {\cf POINT}, {\cf VECTOR}, and {\cf NORMAL} vector semantics to not constitute a difference from one another. \noindent Example: \begin{code} f = TypeDesc("float") p = TypeDesc("point") v = TypeDesc("vector") print "float==point?", (f == p) print "vector==point?", (v == p) print "float.equivalent(point)?", f.equivalent(p) print "vector.equivalent(point)?", v.equivalent(p) > float==point? False > vector==point? False > float.equivalent(point)? False > vector.equivalent(point)? True \end{code} \apiend \section{ROI} \label{sec:pythonroi} The \ROI class that describes an image extent or region of interest, explained in deail in Section~\ref{sec:ROI}, is replicated for Python. \apiitem{{\ce ROI} () \\ {\ce ROI} (xbegin, xend, ybegin, yend) \\ {\ce ROI} (xbegin, xend, ybegin, yend, zbegin, zend) \\ {\ce ROI} (xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend)} Construct an \ROI with the given bounds. The constructor with no arguments makes an \ROI that is ``undefined.'' \noindent Example: \begin{code} import OpenImageIO as oiio ... roi = ROI (0, 640, 0, 480, 0, 1, 0, 4) # video res RGBA \end{code} \apiend \apiitem{int ROI.{\ce xbegin} \\ int ROI.{\ce xend} \\ int ROI.{\ce ybegin} \\ int ROI.{\ce yend} \\ int ROI.{\ce zbegin} \\ int ROI.{\ce zend} \\ int ROI.{\ce chbegin} \\ int ROI.{\ce chend}} The basic fields of the \ROI. \apiend \apiitem{ROI ROI.{\ce All}} A pre-constructed undefined \ROI. \apiend \apiitem{bool ROI.{\ce defined}} {\cf True} if the \ROI is defined, {\cf False} if the \ROI is undefined. \apiend \apiitem{int ROI.{\ce width} \\ int ROI.{\ce height} \\ int ROI.{\ce depth} \\ int ROI.{\ce nchannels}} The number of pixels in each dimension, and the number of channels, as described by the \ROI. \apiend \apiitem{int ROI.{\ce npixels}} The total number of pixels in the region described by the \ROI. \apiend \apiitem{ROI {\ce get_roi} (imagespec) \\ ROI {\ce get_roi_full} (imagespec)} Returns the \ROI corresponding to the pixel data window of the given \ImageSpec, or the display/full window, respectively. \noindent Example: \begin{code} spec = ImageSpec(...) roi = oiio.get_roi(spec) \end{code} \apiend \apiitem{{\ce set_roi} (imagespec, roi) \\ {\ce set_roi_full} (imagespec, roi)} Alter the \ImageSpec's resolution and offset to match the passed \ROI. \noindent Example: \begin{code} # spec is an ImageSpec # The following sets the full (display) window to be equal to the # pixel data window: oiio.set_roi_full (spec, oiio.get_roi(spec)) \end{code} \apiend \section{ImageSpec} \label{sec:pythonimagespec} The \ImageSpec class that describes an image, explained in deail in Section~\ref{sec:ImageSpec}, is replicated for Python. \apiitem{{\ce ImageSpec} ()\\ {\ce ImageSpec} (basetype) \\ {\ce ImageSpec} (typedesc) \\ {\ce ImageSpec} (xres, yres, nchannels, basetype) \\ {\ce ImageSpec} (xres, yres, nchannels, typespec)} Constructors of an \ImageSpec. These correspond directly to the constructors in the C++ bindings. \noindent Example: \begin{code} import OpenImageIO as oiio ... # default ctr s = ImageSpec() # construct with known pixel type, unknown resolution s = ImageSpec(oiio.UINT8) # construct with known resolution, channels, pixel data type s = ImageSpec(640, 480, 4, oiio.HALF) \end{code} \apiend \apiitem{ImageSpec.{\ce width}, ImageSpec.{\ce height}, ImageSpec.{\ce depth} \\ ImageSpec.{\ce x}, ImageSpec.{\ce y}, ImageSpec.{\ce z}} Resolution and offset of the image data ({\cf int} values). \noindent Example: \begin{code} s = ImageSpec (...) print "Data window is ({},{})-({},{})".format (s.x, s.x+s.width-1, s.y, s.y+s.height-1) \end{code} \apiend \apiitem{ImageSpec.{\ce full_width}, ImageSpec.{\ce full_height}, ImageSpec.{\ce full_depth} \\ ImageSpec.{\ce full_x}, ImageSpec.{\ce full_y}, ImageSpec.{\ce full_z}} Resolution and offset of the ``full'' display window ({\cf int} values). \apiend \apiitem{ImageSpec.{\ce tile_width}, ImageSpec.{\ce tile_height}, ImageSpec.{\ce tile_depth}} For tiled images, the resolution of the tiles ({\cf int} values). Will be {\cf 0} for untiled images. \apiend \apiitem{typedesc ImageSpec.{\ce format}} A \TypeDesc describing the pixel data. \apiend \apiitem{int ImageSpec.{\ce nchannels}} An {\cf int} giving the number of color channels in the image. \apiend \apiitem{ImageSpec.{\ce channelnames}} A tuple of strings containing the names of each color channel. \apiend \apiitem{ImageSpec.{\ce channelformats}} If all color channels have the same format, that will be {\cf ImageSpec.format}, and {\cf channelformats} will be {\cf None}. However, if there are different formats per channel, they will be stored in {\cf channelformats} as a tuple of BASETYPE values, and {\cf format} will contain the ``widest'' of them. \noindent Example: \begin{code} if spec.channelformats == None: print "All color channels are", str(spec.format) else: print "Channel formats: " for i in range(len(spec.channelformats)): print "\t", str(TypeDesc(spec.channelformats[i])) \end{code} \apiend \apiitem{ImageSpec.{\ce alpha_channel} \\ ImageSpec.{\ce z_channel}} The channel index containing the alpha or depth channel, respectively, or -1 if either one does not exist or cannot be identified. \apiend \apiitem{ImageSpec.{\ce deep}} Hold {\cf True} if the image is a \emph{deep} (multiple samples per pixel) image, of {\cf False} if it is an ordinary image. \apiend \apiitem{ImageSpec.{\ce quant_black} \\ ImageSpec.{\ce quant_white} \\ ImageSpec.{\ce quant_min} \\ ImageSpec.{\ce quant_max}} The quantization parameters used when the \ImageSpec is used to specify how to open a file for output (refer to Section~\ref{sec:imageoutput:quantization} for a more complete explanation of each of these parameters.) \apiend \apiitem{ImageSpec.{\ce set_format} (basetype) \\ ImageSpec.{\ce set_format} (typedesc)} Given a {\cf BASETYPE} or a \TypeDesc, sets the {\cf format} field and also sets all the {\cf quantize} fields to the defaults for the given data format. \noindent Example: \begin{code} s = ImageSpec () s.set_format (oiio.UINT8) \end{code} \apiend \apiitem{ImageSpec.{\ce default_channel_names} ()} Sets {\cf channel_names} to the default names given the value of the {\cf nchannels} field. \apiend \apiitem{ImageSpec.{\ce format_from_quantize} (black, white, min, max)} Given the quantization parameters, returns a \TypeDesc giving the best data format that matches the quantization. \apiend \apiitem{ImageSpec.{\ce channel_bytes} () \\ ImageSpec.{\ce channel_bytes} (channel, native=False)} Returns the size of a single channel value, in bytes (as an {\cf int}). (Analogous to the C++ member functions, see Section~\ref{sec:ImageSpecMemberFuncs} for details.) \apiend \apiitem{ImageSpec.{\ce pixel_bytes} () \\ ImageSpec.{\ce pixel_bytes} (native) \\ ImageSpec.{\ce pixel_bytes} (chbegin, chend) \\ ImageSpec.{\ce pixel_bytes} (chbegin, chend, native=False)} Returns the size of a pixel, in bytes (as an {\cf int}). (Analogous to the C++ member functions, see Section~\ref{sec:ImageSpecMemberFuncs} for details.) \apiend \apiitem{ImageSpec.{\ce scanline_bytes} (native=False) \\ ImageSpec.{\ce tile_bytes} (native=False) \\ ImageSpec.{\ce image_bytes} (native=False)} Returns the size of a scanline, tile, or the full image, in bytes (as an {\cf int}). (Analogous to the C++ member functions, see Section~\ref{sec:ImageSpecMemberFuncs} for details.) \apiend \apiitem{ImageSpec.{\ce tile_pixels} () \\ ImageSpec.{\ce image_pixels} ()} Returns the number of pixels in a tile or the full image, respectively (as an {\cf int}). (Analogous to the C++ member functions, see Section~\ref{sec:ImageSpecMemberFuncs} for details.) \apiend \apiitem{ImageSpec.{\ce attribute} (name, int) \\ ImageSpec.{\ce attribute} (name, float) \\ ImageSpec.{\ce attribute} (name, string) \\ ImageSpec.{\ce attribute} (name, typedesc, data) \\} Sets a metadata value in the {\cf extra_attribs}. If the metadata item is a single {\cf int}, {\cf float}, or {\cf string}, you can pass it directly. For other types, you must pass the \TypeDesc and then the data (for aggregate types or arrays, pass multiple values as a tuple). \noindent Example: \begin{code} s = ImageSpec (...) s.attribute ("foo_str", "blah") s.attribute ("foo_int", 14) s.attribute ("foo_float", 3.14) s.attribute ("foo_vector", TypeDesc.TypeVector, (1, 0, 11)) s.attribute ("foo_matrix", TypeDesc.TypeMatrix, (1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1)) \end{code} \apiend \apiitem{ImageSpec.{\ce get_attribute} (name) \\ ImageSpec.{\ce get_attribute} (name, typedesc)} Retrieves a named metadata value from {\cf extra_attribs}. The generic {\cf get_attribute()} function returns it regardless of type, or {\cf None} if the attribute does not exist. The typed variety will only succeed if the attribute is actually of that type specified. \noindent Example: \begin{code} foo = s.get_attribute ("foo") # None if not found foo = s.get_attribute ("foo", oiio.FLOAT) # None if not found AND float \end{code} \apiend \apiitem{ImageSpec.{\ce get_int_attribute} (name, defaultval=0) \\ ImageSpec.{\ce get_float_attribute} (name, defaultval=0.0) \\ ImageSpec.{\ce get_string_attribute} (name, defaultval="")} Retrieves a named metadata value from {\cf extra_attribs}, if it is found and is of the given type; returns the default value (or a passed value) if not found. \noindent Example: \begin{code} # If "foo" is not found, or if it's not an int, return 0 foo = s.get_int_attribute ("foo") # If "foo" is not found, or if it's not a string, return "blah" foo = s.get_string_attribute ("foo", "blah") \end{code} \apiend \apiitem{ImageSpec.{\ce extra_attribs}} Direct access to the {\cf extra_attribs} named metadata, appropriate for iterating over the entire list rather than searching for a particular named value. \vspace{-10pt} \apiitem{len(extra_attribs)} \vspace{10pt} Returns the number of extra attributes. \apiend \vspace{-24pt} \apiitem{extra_attribs[i].name} \vspace{10pt} The name of the indexed attribute. \apiend \vspace{-24pt} \apiitem{extra_attribs[i].type} \vspace{10pt} The type of the indexed attribute, as a \TypeDesc. \apiend \vspace{-24pt} \apiitem{extra_attribs[i].value} \vspace{10pt} The value of the indexed attribute. \apiend \noindent Example: \begin{code} s = ImageSpec(...) ... print "extra_attribs size is", len(s.extra_attribs) for i in range(len(s.extra_attribs)) : print i, s.extra_attribs[i].name, s.extra_attribs[i].type, " :" print "\t", s.extra_attribs[i].value print \end{code} \apiend \newpage \subsection*{Example: Header info} Here is an illustrative example of the use of \ImageSpec, a working Python function that opens a file and prints all the relevant header information: \begin{tinycode} #!/usr/bin/env python import OpenImageIO as oiio # Print the contents of an ImageSpec def print_imagespec (spec, subimage=0, mip=0) : if spec.depth <= 1 : print (" resolution %dx%d%+d%+d" % (spec.width, spec.height, spec.x, spec.y)) else : print (" resolution %dx%d%x%d+d%+d%+d" % (spec.width, spec.height, spec.depth, spec.x, spec.y, spec.z)) if (spec.width != spec.full_width or spec.height != spec.full_height or spec.depth != spec.full_depth) : if spec.full_depth <= 1 : print (" full res %dx%d%+d%+d" % (spec.full_width, spec.full_height, spec.full_x, spec.full_y)) else : print (" full res %dx%d%x%d+d%+d%+d" % (spec.full_width, spec.full_height, spec.full_depth, spec.full_x, spec.full_y, spec.full_z)) if spec.tile_width : print (" tile size %dx%dx%d" % (spec.tile_width, spec.tile_height, spec.tile_depth)) else : print " untiled" if mip >= 1 : return print " " + str(spec.nchannels), "channels:", spec.channelnames print " format = ", str(spec.format) if spec.channelformats : print " channelformats = ", spec.channelformats print " alpha channel = ", spec.alpha_channel print " z channel = ", spec.z_channel print " deep = ", spec.deep for i in range(len(spec.extra_attribs)) : if type(spec.extra_attribs[i].value) == str : print " ", spec.extra_attribs[i].name, "= \"" + spec.extra_attribs[i].value + "\"" else : print " ", spec.extra_attribs[i].name, "=", spec.extra_attribs[i].value def poor_mans_iinfo (filename) : input = ImageInput.open (filename) if not input : print 'Could not open "' + filename + '"' print "\tError: ", oiio.geterror() return print 'Opened "' + filename + '" as a ' + input.format_name() sub = 0 mip = 0 while True : if sub > 0 or mip > 0 : print "Subimage", sub, "MIP level", mip, ":" print_imagespec (input.spec(), mip=mip) mip = mip + 1 if input.seek_subimage (sub, mip) : continue # proceed to next MIP level else : sub = sub + 1 mip = 0 if input.seek_subimage (sub, mip) : continue # proceed to next subimage break # no more MIP levels or subimages input.close () \end{tinycode} \section{ImageInput} \label{sec:pythonimageinput} See Chapter~\ref{chap:imageinput} for detailed explanations of the C++ \ImageInput class APIs. The Python APIs are very similar. The biggest difference is that in C++, the various {\cf read_*} functions write the pixel values into an already-allocated array that belongs to the caller, whereas the Python versions allocate and return an array holding the pixel values (or {\cf None} if the read failed). \apiitem{ImageInput.{\ce open} (filename) \\ ImageInput.{\ce open} (filename, config_imagespec)} Creates an \ImageInput object and opens the named file. Returns the open \ImageInput upon success, or {\cf None} if it failed to open the file (after which, {\cf OpenImageIO.geterror()} will contain an error message). In the second form, the optional \ImageSpec argument {\cf config} contains attributes that may set certain options when opening the file. \noindent Example: \begin{code} input = ImageInput.open ("tahoe.jpg") if input == None : print "Error:", oiio.geterror() return \end{code} \apiend \apiitem{bool ImageInput.{\ce close} ()} Closes an open image file, returning {\cf True} if successful, {\cf False} otherwise. \noindent Example: \begin{code} input = ImageInput.open (filename) ... input.close () \end{code} \apiend \apiitem{str ImageInput.{\ce format_name} ()} Returns the format name of the open file. \noindent Example: \begin{code} input = ImageInput.open (filename) if input : print filename, "was a", input.format_name(), "file." input.close () \end{code} \apiend \apiitem{ImageSpec ImageInput.{\ce spec} ()} Returns the \ImageSpec corresponding to the currently open subimage and MIP level of the file. \noindent Example: \begin{code} input = ImageInput.open (filename) spec = input.spec() print "resolution ", spec.width, "x", spec.height \end{code} \apiend \apiitem{int ImageInput.{\ce current_subimage} () \\ int ImageInput.{\ce current_miplevel} ()} Returns the current subimage and/or MIP level of the file. \apiend \apiitem{bool ImageInput.{\ce seek_subimage} (subimage, miplevel)} Repositions the file pointer to the given subimage and MIP level within the file (starting with {\cf 0}). This function returns {\cf True} upon success, {\cf False} upon failure (which may include the file not having the specified subimage or MIP level). \noindent Example: \begin{code} input = ImageInput.open (filename) mip = 0 while True : ok = input.seek_subimage (0, mip) if not ok : break spec = input.spec() print "MIP level", mip, "is", spec.width, "x", spec.height \end{code} \apiend \apiitem{array ImageInput.{\ce read_image} (type=OpenImageIO.UNKNOWN)} Read the entire image and return the pixels as an array of $\mathit{width} \times \mathit{height} \times \mathit{depth} \times \mathit{nchannels}$ values (or {\cf None} if an error occurred). The array will be of the type specified by the {\cf TypeDesc} or {\cf BASETYPE} argument, or if the argument is missing or is {\cf TypeDesc(oiio.UNKNOWN)}, it will choose an appropriate data type that is the ``smallest'' type that can hold the actual types in the file. \noindent Example: \begin{code} input = ImageInput.open (filename) spec = input.spec () pixels = input.read_image (oiio.FLOAT) print "The first pixel is", pixels[0:spec.nchannels] print "The second pixel is", pixels[spec.nchannels:(2*spec.nchannels)] input.close () \end{code} \apiend \apiitem{array ImageInput.{\ce read_scanline} (y, z, type=OpenImageIO.UNKNOWN)} Read scanline number {\cf y} from depth plane {\cf z} from the open file, returning it as an array of $\mathit{width} \times \mathit{nchannels}$ values (or {\cf None} if an error occurred). The array will be of the type specified by the {\cf TypeDesc} or {\cf BASETYPE} argument, or if the argument is missing or is {\cf TypeDesc(oiio.UNKNOWN)}, it will choose an appropriate data type. \noindent Example: \begin{code} input = ImageInput.open (filename) spec = input.spec () if spec.tile_width == 0 : for y in range(spec.y, spec.y+spec.height) : pixels = input.read_scanline (y, spec.z, oiio.FLOAT) # process the scanline else : print "It's a tiled file" input.close () \end{code} \apiend \apiitem{array ImageInput.{\ce read_tile} (x, y, z, type=OpenImageIO.UNKNOWN)} Read the tile whose upper left corner is pixel {\cf (x,y,z)} from the open file, returning it as an array of $\mathit{width} \times \mathit{height} \times \mathit{depth} \times \mathit{nchannels}$ values (or {\cf None} if an error occurred). The array will be of the type specified by the {\cf TypeDesc} or {\cf BASETYPE} argument, or if the argument is missing or {\cf TypeDesc(oiio.UNKNOWN)}, it will choose an appropriate data type. \noindent Example: \begin{code} input = ImageInput.open (filename) spec = input.spec () if spec.tile_width > 0 : for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) : for y in range(spec.y, spec.y+spec.height, spec.tile_height) : for x in range(spec.x, spec.x+spec.width, spec.tile_width) : pixels = input.read_tile (x, y, z, oiio.FLOAT) # process the tile else : print "It's a scanline file" input.close () \end{code} \apiend \apiitem{array ImageInput.{\ce read_scanlines} (ybegin, yend, z, chbegin, chend, \\ \bigspc\bigspc\spc type=OpenImageIO.UNKNOWN) \\ array ImageInput.{\ce read_tiles} (xbegin, xend, ybegin, yend, zbegin, zend, \\ \bigspc\bigspc\spc chbegin, chend, type=OpenImageIO.UNKNOWN)} Similar to the C++ routines, these functions read multiple scanlines or tiles at once, which in some cases may be more efficient than reading each scanline or tile separately. Additionally, they allow you to read only a subset of channels. \noindent Example: \begin{code} input = ImageInput.open (filename) spec = input.spec () # Read the whole image, the equivalent of # pixels = input.read_image (type) # but do it using read_scanlines or read_tiles: if spec.tile_width == 0 : pixels = input.read_scanlines (spec.y, spec.y+spec.height, 0, 0, spec.nchannels, oiio.FLOAT) else : pixels = input.read_tiles (spec.x, spec.x+spec.width, spec.y, spec.y+spec.height, spec.z, spec.z+spec.depth, 0, spec.nchannels, oiio.FLOAT) \end{code} \apiend \apiitem{str ImageInput.{\ce geterror} ()} Retrieves the error message from the latest failed operation on an ImageInput. \noindent Example: \begin{code} input = ImageInput.open (filename) if not input : print "Open error:", oiio.geterror() # N.B. error on open must be retrieved with the global geterror(), # since there is no ImageInput object! else : pixels = input.read_image (oiio.FLOAT) if not pixels : print "Read_image error:", input.geterror() input.close () \end{code} \apiend \newpage \subsection*{Example: Reading pixel values from a file to find min/max} \begin{code} #!/usr/bin/env python import OpenImageIO as oiio def find_min_max (filename) : input = ImageInput.open (filename) if not input : print 'Could not open "' + filename + '"' print "\tError: ", oiio.geterror() return spec = input.spec() nchans = spec.nchannels pixels = input.read_image(oiio.FLOAT) if not pixels : print "Could not read:", input.geterror() return input.close() # we're done with the file at this point minval = pixels[0:nchans] # initialize to the first pixel value maxval = pixels[0:nchans] i = 0 # absolute index for z in range(spec.depth) : for y in range(spec.height) : for x in range(spec.width) : for c in range(nchans) : if pixels[i+c] < minval[c] : minval[c] = pixels[i+c] if pixels[i+c] > maxval[c] : maxval[c] = pixels[i+c] i = i + nchans # advance the index print "Min values per channel were", minval print "Max values per channel were", maxval \end{code} \newpage \section{ImageOutput} \label{sec:pythonimageoutput} See Chapter~\ref{chap:imageoutput} for detailed explanations of the C++ \ImageOutput class APIs. The Python APIs are very similar. \apiitem{ImageOutput ImageOutput.{\ce create} (fileformat, plugin_searchpath="")} Create a new \ImageOutput capable of writing the named file format (which may also be a file name, with the type deduced from the extension). There is an optional parameter giving an colon-separated search path for finding \ImageOutput plugins. The function returns an \ImageOutput object, or {\cf None} upon error (in which case, {OpenImageIO.geterror()} may be used to retrieve the error message). \noindent Example: \begin{code} import OpenImageIO as oiio output = ImageOutput.create ("myfile.tif") if not output : print "Error:", oiio.geterror() \end{code} \apiend \apiitem{str ImageOutput.{\ce format_name} ()} The file format name of a created \ImageOutput. \noindent Example: \begin{code} output = ImageOutput.create (filename) if output : print "Created output", filename, "as a", output.format_name() \end{code} \apiend \apiitem{bool ImageOutput.{\ce supports} (feature)} For a created \ImageOutput, returns {\cf True} if the file format supports the named feature (such as \qkw{tiles}, \qkw{mipmap}, etc., see Section~\ref{sec:supportsfeaturelist} for the full list), or {\cf False} if this file format does not support the feature. \noindent Example: \begin{code} output = ImageOutput.create (filename) if output : print output.format_name(), "supports..." print "tiles?", output.supports("tiles") print "multi-image?", output.supports("multiimage") print "MIP maps?", output.supports("mipmap") print "per-channel formats?", output.supports("channelformats") \end{code} \apiend \apiitem{bool ImageOutput.{\ce open} (filename, imagespec, mode)} Opens the named output file, with an \ImageSpec describing the image to be output. The {\cf mode} may be one of {\cf OpenImageIO.Create}, {\cf OpenImageIO.AppendSubimage}, or {\cf OpenImageIO.AppendMIPLevel}. See Section~\ref{sec:imageoutputopen} for details. Returns {\cf True} upon success, {\cf False} upon failure (error messages retrieved via {\cf ImageOutput.geterror()}.) \noindent Example: \begin{code} output = ImageOutput.create (filename) if not output : print "Error:", oiio.geterror() spec = ImageSpec (640, 480, 3, oiio.UINT8) ok = output.open (filename, spec, oiio.Create) if not ok : print "Could not open", filename, ":", output.geterror() \end{code} \apiend \apiitem{bool ImageOutput.{\ce open} (filename, (imagespec, ...))} This variety of {\cf open()} is used specifically for multi-subimage files. A \emph{tuple} of \ImageSpec objects is passed, one for each subimage that will be written to the file. After each subimage is written, then a regular call to {\cf open(name, newspec, {\ce AppendSubimage})} moves on to the next subimage. \apiend \apiitem{bool ImageOutput.{\ce close} ()} Closes an open output. \apiend \apiitem{ImageSpec ImageOutput.{\ce spec} ()} Retrieves the \ImageSpec of the currently-open output image. \apiend \apiitem{bool ImageOutput.{\ce write_image} (typedesc, pixels, xstride=AutoStride, \\ \bigspc\bigspc\spc ystride=AutoStride, zstride=AutoStride)} Write the currently opened image all at once. The {\cf pixels} parameter should be an {\cf array} containing data elements of the type described by the \TypeDesc. Optional strides describe data layout in the array (the default values of {\cf AutoStride} are used if the data are contiguous). Returns {\cf True} upon success, {\cf False} upon failure. \noindent Example: \begin{code} # This example reads a scanline file, then converts it to tiled # and writes to the same name. input = ImageInput.open (filename) spec = input.spec () pixels = input.read_image (oiio.FLOAT) input.close () output = ImageOutput.create (filename) if output.supports("tiles") : spec.tile_width = 64 spec.tile_height = 64 output.open (filename, spec, oiio.Create) output.write_image (oiio.FLOAT, pixels) output.close () \end{code} \apiend \apiitem{bool ImageOutput.{\ce write_scanline} (y, z, typesdesc, pixels, \\ \bigspc\bigspc xstride=AutoStride) \\ bool ImageOutput.{\ce write_scanlines} (ybegin, yend, z, typesdesc, pixels, \\ \bigspc\bigspc xstride=AutoStride)} Write one or many scanlines to the currently open file. \noindent Example: \begin{code} # Copy a TIFF image to JPEG by copying scanline by scanline. input = ImageInput.open ("in.tif") spec = input.spec () output = ImageOutput.create ("out.jpg") output.open (filename, spec, oiio.Create) for z in range(spec.z, spec.z+spec.depth) : for y in range(spec.y, spec.y+spec.height) : pixels = input.read_scanline (y, z, oiio.FLOAT) output.write_scanline (y, z, oiio.FLOAT, pixels) output.close () input.close () # The same example, but copying a whole "plane" of scanlines at a time: ... for z in range(spec.z, spec.z+spec.depth) : pixels = input.read_scanlines (spec.y, spec.y+spec.height, z, oiio.FLOAT) output.write_scanlines (spec.y, spec.y+spec.height, z, oiio.FLOAT, pixels) ... \end{code} \apiend \apiitem{bool ImageOutput.{\ce write_tile} (x, y, z, typesdesc, pixels, \\ \bigspc\bigspc\spc xstride=AutoStride, ystride=AutoStride, \\ \bigspc\bigspc\spc zstride=AutoStride) \\ bool ImageOutput.{\ce write_tiles} (xbegin, xend, ybegin, yend, zbegin, zend, \\ \bigspc\bigspc\spc xstride=AutoStride, ystride=AutoStride, \\ \bigspc\bigspc\spc zstride=AutoStride)} Write one or many tiles to the currently open file. \noindent Example: \begin{code} input = ImageInput.open (in_filename) spec = input.spec () output = ImageOutput.create (out_filename) output.open (out_filename, spec, oiio.Create) for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) : for y in range(spec.y, spec.y+spec.height, spec.tile_height) : for x in range(spec.x, spec.x+spec.width, spec.tile_width) : pixels = input.read_tile (x, y, z, oiio.FLOAT) output.read_tile (x, y, z, oiio.FLOAT, pixels) output.close () input.close () # The same example, but copying a whole row of of tiles at a time: ... for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) : for y in range(spec.y, spec.y+spec.height, spec.tile_height) : pixels = input.read_tiles (spec.x, spec.x+spec.width, y, y+tile_width, z, z+tile_width, oiio.FLOAT) output.read_tile (spec.x, spec.x+spec.width, y, y+tile_width, z, z+tile_width, oiio.FLOAT, pixels) ... \end{code} \apiend \apiitem{bool ImageOutput.{\ce copy_image} (imageinput)} Copy the current image of the open input to the open output. (The reason this may be preferred in some circumstances is that, if input and output were the same kind of input file format, they may have a special efficient technique to copy pixels unaltered, for example by avoiding the decompression/recompression round trip.) \noindent Example: \begin{code} input = ImageInput.open (in_filename) spec = input.spec () output = ImageOutput.create (out_filename) output.open (filename, spec, oiio.Create) output.copy_image (input) output.close () input.close () \end{code} \apiend \apiitem{str ImageOuput.{\ce geterror} ()} Retrieves the error message from the latest failed operation on an open file. \noindent Example: \begin{code} output = ImageOutput.create (filename) if not output : print "Create error:", oiio.geterror() # N.B. error on create must be retrieved with the global geterror(), # since there is no ImageOutput object! else : ok = output.open (filename, spec, oiio.Create) if not ok : print "Open error:", output.geterror() ok = output.write_image (oiio.FLOAT, pixels) if not ok : print "Write error:", output.geterror() output.close () \end{code} \apiend \section{ImageBuf} \label{sec:pythonimagebuf} See Chapter~\ref{chap:imagebuf} for detailed explanations of the C++ \ImageBuf class APIs. The Python APIs are very similar. \apiitem{ImageBuf {\ce ImageBuf} ()} Construct a new, empty \ImageBuf. The \ImageBuf is uninitialized and is awaiting a call to {\cf reset()} or {\cf copy()} before it is useful. \apiend \apiitem{ImageBuf {\ce ImageBuf} (filename) \\ ImageBuf {\ce ImageBuf} (filename, subimage, miplevel)} Construct a read-only \ImageBuf that will read from the named file. Optionally, a specific subimage or MIP level may be specified (defaulting to 0). \noindent Example: \begin{code} import OpenImageIO as oiio ... buf = ImageBuf ("grid.tif") \end{code} \apiend \apiitem{ImageBuf {\ce ImageBuf} (imagespec)} Construct a writeable \ImageBuf of the dimensions and data format specified by an \ImageSpec. \noindent Example: \begin{code} spec = ImageSpec (640, 480, 3, oiio.FLOAT) buf = ImageBuf (spec) \end{code} \apiend \apiitem{ImageBuf.{\ce clear} ()} Return the \ImageBuf to its pristine, uninitialized state. \noindent Example: \begin{code} buf = ImageBuf (...) # The following two commands are equivalent: buf = ImageBuf() # 1 - assign a new blank ImageBuf buf.clear() # 2 - clear the existing ImageBuf \end{code} \apiend \apiitem{ImageBuf.{\ce reset} (filename) \\ ImageBuf.{\ce reset} (filename, subimage, miplevel) \\ ImageBuf.{\ce reset} (imagespec)} Restore the \ImageBuf to its newly-constructed state, either to read from a filename (optionally specifying a subimage and MIP level) or a writeable \ImageBuf specified by an \ImageSpec. \apiend \apiitem{bool ImageBuf.{\ce read} (subimage=0, miplevel=0, force=False, convert=oiio.UNKNOWN)} Explicitly read the image from the file (of a file-reading \ImageBuf), optionally specifying a particular subimage and MIP level. If {\cf force} is {\cf True}, will force an allocation of memory and a full read (versus the default of relying on an underlying \ImageCache). If {\cf convert} is not the default of {\cf UNKNOWN}, it will force the \ImageBuf to convert the image to the specified data format (versus keeping it in the native format or relying on the \ImageCache to make a data formatting decision). Note that a call to {\cf read()} is not necessary --- any \ImageBuf API call that accesses pixel values will trigger a file read if it has not yet been done. The {\cf read()} method will return {\cf True} for success, or {\cf False} if the read could not be performed (in which case, a {\cf geterror()} call will retrieve the specific error message). \noindent Example: \begin{code} buf = ImageBuf ("mytexture.exr") buf.read (0, 2, True) # That forces an allocation and read of MIP level 2 \end{code} \apiend \apiitem{bool ImageBuf.{\ce init_spec} (filename, subimage=0, miplevel=0)} Explicitly read just the header from a file-reading \ImageBuf (if the header has not yet been read), optionally specifying a particular subimage and MIP level. The {\cf init_spec()} method will return {\cf True} for success, or {\cf False} if the read could not be performed (in which case, a {\cf geterror()} call will retrieve the specific error message). Note that a call to {\cf init_spec()} is not necessary --- any \ImageBuf API call that accesses the spec will read it automatically it has not yet been done. \apiend \apiitem{bool ImageBuf.{\ce write} (filename, fileformat="")} Write the contents of the \ImageBuf to the named file. Optionally, {\cf fileformat} can specify a particular file format to use (by default, it will infer it from the extension of the file name). \noindent Example: \begin{code} # No-frills conversion of a TIFF file to JPEG buf = ImageBuf ("in.tif") buf.write ("out.jpg") \end{code} \apiend \apiitem{bool ImageBuf.{\ce set_write_format} (format=oiio.UNKNOWN) \\ bool ImageBuf.{\ce set_write_tiles} (width=0, height=0, depth=0)} Override the data format or tile size in a subsequent call to {\cf write()}. \noindent Example: \begin{code} # Conversion to a tiled float file buf = ImageBuf ("in.tif") buf.set_write_format (oiio.FLOAT) buf.set_write_tiles (64, 64) buf.write ("out.tif") \end{code} \apiend \apiitem{ImageSpec ImageBuf.{\ce spec}() \\ ImageSpec ImageBuf.{\ce nativespec}()} {\cf ImageBuf.spec()} returns the \ImageSpec that describes the contents of the \ImageBuf. {\cf ImageBuf.nativespec()} returns an \ImageSpec that describes the contents of the file that the \ImageBuf was read from (this may differ from {\cf ImageBuf.spec()} due to format conversions, or any changes made to the \ImageBuf after the file was read, such as adding metadata). Handy rule of thumb: {\cf spec()} describes the buffer, {\cf nativespec()} describes the original file it came from. \noindent Example: \begin{code} buf = ImageBuf ("in.tif") print "Resolution is", buf.spec().width, "x", buf.spec().height \end{code} \apiend \apiitem{ImageSpec ImageBuf.{\ce specmod}()} {\cf ImageBuf.specmod()} provides writeable access to the \ImageSpec that describes the contents of the \ImageBuf. Be very careful! It is safe to modify certain metadata, but if you change the data format or resolution fields, you will get the chaos you deserve. \noindent Example: \begin{code} # Read an image, add a caption metadata, write it back out in place buf = ImageBuf ("file.tif") buf.specmod().attribute ("ImageDescription", "my photo") buf.write ("file.tif") \end{code} \apiend \apiitem{str ImageBuf.{\ce name} \\ str ImageBuf.{\ce file_format_name}} The file name and name of the file format of the image. \apiend \apiitem{int ImageBuf.{\ce subimage} \\ int ImageBuf.{\ce miplevel} \\ int ImageBuf.{\ce nsubimages} \\ int ImageBuf.{\ce nmiplevels}} Several fields giving information about the current subimage and MIP level, and the total numbers thereof in the file. \apiend \apiitem{int ImageBuf.{\ce xbegin} \\ int ImageBuf.{\ce xend} \\ int ImageBuf.{\ce ybegin} \\ int ImageBuf.{\ce yend} \\ int ImageBuf.{\ce zbegin} \\ int ImageBuf.{\ce zend}} The range of valid pixel data window. Remember that the {\cf end} is \emph{one past} the last pixel. \apiend \apiitem{int ImageBuf.{\ce xmin} \\ int ImageBuf.{\ce xmax} \\ int ImageBuf.{\ce ymin} \\ int ImageBuf.{\ce ymax} \\ int ImageBuf.{\ce zmin} \\ int ImageBuf.{\ce zmax}} The minimum and maximum (inclusive) coordinates of the pixel data window. \apiend \apiitem{int ImageBuf.{\ce orientation} \\ int ImageBuf.{\ce oriented_width} \\ int ImageBuf.{\ce oriented_height} \\ int ImageBuf.{\ce oriented_x} \\ int ImageBuf.{\ce oriented_y} \\ int ImageBuf.{\ce oriented_full_width} \\ int ImageBuf.{\ce oriented_full_height} \\ int ImageBuf.{\ce oriented_full_x} \\ int ImageBuf.{\ce oriented_full_y}} The {\cf orientation} field gives the suggested display oriententation of the image (see Section~\ref{metadata:orientation}). The other fields are helpers that give the width, height, and origin (as well as ``full'' or ``display'' resolution and origin), taking the intended orientation into consideration. \apiend \apiitem{ROI ImageBuf.{\ce roi} \\ ROI ImageBuf.{\ce roi_full}} These fields return an \ROI description of the pixel data window ({\cf roi}) and the full (a.k.a.\ ``display'') window ({\cf roi_full}). \noindent Example: \begin{code} buf = ImageBuf ("tahoe.jpg") print "Resolution is", buf.roi.width, "x", buf.roi.height \end{code} \apiend \apiitem{ImageBuf.{\ce set_full} (roi)} Changes the ``full'' (a.k.a. ``display'') window to the specified ROI. \noindent Example: \begin{code} newroi = ROI (0, 1024, 0, 768) buf.set_full (newroi) \end{code} \apiend \apiitem{bool ImageBuf.{\ce pixels_valid}} Will be {\cf True} if the file has already been read and the pixels are valid. (It is always {\cf True} for writeable \ImageBuf's.) There should be few good reasons to access these, since the spec and pixels will be automatically be read when they are needed. \apiend \apiitem{TypeDesc ImageBuf.{\ce pixeltype}} Returns the description of the data type of the pixels stored within the \ImageBuf. \apiend \apiitem{bool ImageBuf.{\ce deep}} Will be {\cf True} if the file contains ``deep'' pixel data, or {\cf False} for an ordinary images. \apiend \apiitem{ImageBuf.{\ce copy_metadata} (other_imagebuf)} Replaces the metadata (all \ImageSpec items, except for the data format and pixel data window size) with the corresponding metadata from the other \ImageBuf. \apiend \apiitem{ImageBuf.{\ce copy_pixels} (other_imagebuf)} Replace the pixels in this \ImageBuf with the values from the other \ImageBuf. \apiend \apiitem{ImageBuf.{\ce copy} (other_imagebuf)} Make this \ImageBuf a complete copy of the other \ImageBuf. \noindent Example: \begin{code} A = ImageBuf() B = ImageBuf("B.tif") A.copy (B) # Now A is a separate, duplicate copy of "B.tif" \end{code} \apiend \apiitem{ImageBuf.{\ce swap} (other_imagebuf)} Swaps the content of this \ImageBuf and the other \ImageBuf. \noindent Example: \begin{code} A = ImageBuf("A.tif") B = ImageBuf("B.tif") A.swap (B) # Now B contains the "A.tif" image and A contains the "B.tif" image \end{code} \apiend \apiitem{tuple ImageBuf.{\ce getpixel} (x, y, z=0, wrap=oiio.WrapBlack)} Retrieves pixel $(x,y,z)$ from the buffer and return it as a tuple of {\cf float} values, one for each color channel. The {\cf x, y, z} values are {\cf int} pixel coordinates. The optional {\cf wrap} parameter describes what should happen if the coordinates are outside the pixel data window (and may be: {\cf WrapBlack, WrapClamp, WrapPeriodic, WrapMirror}). \noindent Example: \begin{code} buf = ImageBuf ("tahoe.jpg") p = buf.getpixel (50, 50) print p > (0.37, 0.615, 0.97) \end{code} \apiend \apiitem{float ImageBuf.{\ce getchannel} (x, y, z, channel, wrap=oiio.WrapBlack)} Retrieves just a single channel value from pixel $(x,y,z)$ from the buffer and returns it as a {\cf float} value. The optional {\cf wrap} parameter describes what should happen if the coordinates are outside the pixel data window (and may be: {\cf WrapBlack, WrapClamp, WrapPeriodic, WrapMirror}). \noindent Example: \begin{code} buf = ImageBuf ("tahoe.jpg") green = buf.getchannel (50, 50, 0, 1) \end{code} \apiend \apiitem{tuple ImageBuf.{\ce interppixel} (x, y, wrap=oiio.WrapBlack)} Interpolates the image value at coordinates $(x,y)$ and return it as a tuple of {\cf float} values, one for each color channel. The {\cf x, y} values are continuous {\cf float} coordinates in ``pixel space.'' The optional {\cf wrap} parameter describes what should happen if the coordinates are outside the pixel data window (and may be: {\cf WrapBlack, WrapClamp, WrapPeriodic, WrapMirror}). \noindent Example: \begin{code} buf = ImageBuf ("tahoe.jpg") midx = float(buf.xbegin + buf.xend) / 2.0 midy = float(buf.ybegin + buf.yend) / 2.0 p = buf.interpixel (midx, midy) # Now p is the interpolated value from right in the center of # the data window \end{code} \apiend \apiitem{tuple ImageBuf.{\ce interppixel_NDC_full} (x, y, wrap=oiio.WrapBlack)} Interpolates the image value at coordinates $(x,y)$ and return it as a tuple of {\cf float} values, one for each color channel. The {\cf x, y} values are continuous, normalized {\cf float} coordinates in ``NDC space,'' where {\cf (0,0)} is the upper left corner of the full (a.k.a.\ ``display'') window, and {\cf (1,1)} is the lower right corner of the full/display window. The {\cf wrap} parameter describes what should happen if the coordinates are outside the pixel data window (and may be: {\cf WrapBlack, WrapClamp, WrapPeriodic, WrapMirror}). \noindent Example: \begin{code} buf = ImageBuf ("tahoe.jpg") p = buf.interpixel_NDC_full (0.5, 0.5) # Now p is the interpolated value from right in the center of # the display window \end{code} \apiend \apiitem{ImageBuf.{\ce setpixel} (x, y, pixel_value) \\ ImageBuf.{\ce setpixel} (x, y, z, pixel_value)} Sets pixel $(x,y,z)$ to be the {\cf pixel_value}, expressed as a tuple of {\cf float}s (one for each color channel). \noindent Example: \begin{code} buf = ImageBuf (ImageSpec (640, 480, 3, oiio.UINT8)) # Set the whole image to red (the dumb slow way, but it works): for y in range(buf.ybegin, buf.yend) : for x in range(buf.xbegin, buf.xend) : buf.setpixel (x, y, (1.0, 0.0, 0.0)) \end{code} \apiend \apiitem{bool ImageBuf.{\ce has_error} \\ str ImageBuf.{\ce geterror} ()} The {\cf ImageBuf.has_error} field will be {\cf True} if an error has occurred in the \ImageBuf, in which case the {\cf geterror()} method will retrieve the error message (and clear it afterwards). \noindent Example: \begin{code} buf = ImageBuf ("in.tif") buf.read () # force a read if buf.has_error : print "Error reading the file:", buf.geterror() buf.write ("out.jpg") if buf.has_error : print "Could not convert the file:", buf.geterror() \end{code} \apiend \newpage \section{ImageBufAlgo} \label{sec:pythonimagebufalgo} The C++ \IBA functions are described in detail in Chapter~\ref{chap:imagebufalgo}. They are also exposed to Python. For the majority of \IBA functions, their use in Python is identical to C++; in those cases, we will keep our descriptions of the Python bindings minimal and refer you to Chapter~\ref{chap:imagebufalgo}, saving the extended descriptions for those functions that differ from the C++ counterparts. A few things about the paramters of the \IBA function calls are identical among the functions, so we will explain once here rather than separately for each function: \begin{itemize} \item {\cf dst} is an existing \ImageBuf, which will be modified (it may be an uninitialized \ImageBuf, but it must be an \ImageBuf). \item {\cf src} parameter is an initialized \ImageBuf, which will not be modified (unless it happens to refer to the same image as {\cf dst}. \item {\cf roi}, if supplied, is an {\cf ROI} specifying a region of interst over which to operate. If omitted, the region will be the entire size of the source image(s). \item {\cf nthreads} is the maximum number of threads to use. If not supplied, it defaults to 0, meaning to use as many threads as hardware cores available. \end{itemize} Just as with the C++ \IBA functions, if {\cf dst} is an uninitialized \ImageBuf, it will be sized to reflect the {\cf roi} (which, in turn, if undefined, will be sized to be the union of the ROI's of the source images). \subsection{Pattern generation} \label{sec:iba:py:patterns} \apiitem{bool ImageBufAlgo.{\ce zero} (dst, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!zero} \indexapi{zero} Zero out the destination buffer (or a specific region of it). \smallskip \noindent Example: \begin{code} # Initialize buf to a 640x480 3-channel FLOAT buffer, zero it out buf = ImageBuf (ImageSpec (640, 480, 3, oiio.FLOAT)) ImageBufAlgo.zero (buf) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce fill} (dst, values, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!fill} \indexapi{fill} Set the pixels in {\cf dst} within the ROI to the values in the tuple {\cf values}. \smallskip \noindent Examples: \begin{code} # Draw a red rectangle into buf buf = ImageBuf (ImageSpec(640, 480, 3, TypeDesc.FLOAT) ImageBufAlgo.fill (buf, (1,0,0), ROI(50, 100, 75, 85)) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce checker} (dst, width, height, depth, color1, color2, \\ \bigspc xoffset=0, yoffset=0, zoffset=0, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!checker} \indexapi{checker} Fill {\cf dst} with a checkerboard pattern. The colors are specified as tuples giving the values for each color channel. \smallskip \noindent Examples: \begin{code} buf = ImageBuf(ImageSpec(640, 480, 3, oiio.UINT8)) ImageBufAlgo.checker (buf, 64, 64, 1, (0.1,0.1,0.1), (0.4,0.4,0.4)) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce render_text} (dst, x, y, text, fontsize=16, \\ \bigspc\bigspc fontname="", textcolor=(1,1,1,1))} \index{ImageBufAlgo!render_text} \indexapi{render_text} Render antialiased text into {\cf dst}. The {\cf textcolor} (if supplied) is a tuple giving the per-channel colors. \smallskip \noindent Examples: \begin{code} buf = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT)) ImageBufAlgo.render_text (buf, 100, 200, "Go Big Red!", 60, "Arial Bold", (1,0,0,1)) \end{code} \apiend \subsection{Image transformations and data movement} \label{sec:iba:py:transforms} \apiitem{bool ImageBufAlgo.{\ce channels} (dst, src, channelorder, newchannelnames=(), \\ \bigspc\bigspc shuffle_channel_names=False)} \index{ImageBufAlgo!channels} \indexapi{channels} Copy {\cf src} to {\cf dst}, but with channels in the order specified by the tuple {\cf channelorder}. The length of {\cf channelorder} specifies the number of channels to copy. Each element in the tuple {\cf channelorder} may be one of the following: \begin{itemize} \item {} \item {\cf int} : specifies the index (beginning at 0) of the channel to copy. \item {\cf str} : specifies the name of the channel to copy. \item {\cf float} : specifies a constant value to use for that channel. \end{itemize} Does not support in-place operation -- that is, {\cf dst} and {\cf src} must be different \ImageBuf's. If {\cf newchannelnames} is supplied, it is a tuple of new channel names. (See the C++ version for more full explanation.) \smallskip \noindent Examples: \begin{code} # Copy the first 3 channels of an RGBA, drop the alpha RGBA = ImageBuf("rgba.tif") RGB = ImageBuf() ImageBufAlgo.channels (RGB, RGBA, (0,1,2)) # Copy just the alpha channel, making a 1-channel image Alpha = ImageBuf() ImageBufAlgo.channels (Alpha, RGBA, ("alpha",)) # Swap the R and B channels BGRA = ImageBuf() ImageBufAlgo.channels (BRGA, RGBA, (2, 1, 0, 3)) # Add an alpha channel with value 1.0 everywhere to an RGB image ImageBufAlgo.channels (RGBA, RGB, ("R", "G", "B", 1.0)) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce channel_append} (dst, A, B, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!channel_append} \indexapi{channel_append} Append the channels of images {\cf A} and {\cf B} together into {\cf dst} over the region of interest. \smallskip \noindent Examples: \begin{code} RGBA = ImageBuf ("rgba.exr") Z = ImageBuf ("z.exr") RGBAZ = ImageBuf() ImageBufAlgo.channel_append (RGBAZ, RGBA, Z) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce flatten} (dst, src, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!flatten} \indexapi{flatten} \index{deep images} \NEW % 1.3 Composite the depth samples within each pixel of ``deep'' \ImageBuf\ {\cf src} and store the single resulting value per pixel in ``flat'' \ImageBuf {\cf dst}. \smallskip \noindent Examples: \begin{code} Flat = ImageBuf() ImageBufAlgo.flatten (Flat, ImageBuf("deepalpha.exr")) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce crop} (dst, src, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!crop} \indexapi{crop} Reset {\cf dst} to be the specified region of {\cf src}. \smallskip \noindent Examples: \begin{code} # Set B to be the upper left 200x100 region of A A = ImageBuf ("a.tif") B = ImageBuf() ImageBufAlgo.crop (B, A, ROI(0,200,0,100)) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce paste} (dst, xbegin, ybegin, zbegin, chbegin, \\ \bigspc\bigspc src, ROI srcroi=ROI.All, nthreads=0)} \index{ImageBufAlgo!paste} \indexapi{paste} Copy the specified region of {\cf src} into {\cf dst} beginning at offset {\cf (xbegin, ybegin, zbegin)}. \smallskip \noindent Examples: \begin{code} # Paste small.exr on top of big.exr at offset (100,100) Big = ImageBuf ("big.exr") Small = ImageBuf ("small.exr") ImageBufAlgo.paste (Big, 100, 100, 0, 0, Small) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce flip} (dst, src, roi=ROI.All, nthreads=0) \\ bool ImageBufAlgo.{\ce flop} (dst, src, roi=ROI.All, nthreads=0) \\ bool ImageBufAlgo.{\ce flipflop} (dst, src, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!flip} \indexapi{flip} \index{ImageBufAlgo!flop} \indexapi{flop} \index{ImageBufAlgo!flipflop} \indexapi{flipflop} Copy while reversing orientation vertically (flip), horizontally (flop), or both vertically and horizontally (flipflip). \smallskip \noindent Examples: \begin{code} A = ImageBuf ("tahoe.exr") B = ImageBuf() ImageBufAlgo.flip (B, A) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce transpose} (dst, src, oi=ROI.All, nthreads=0)} \index{ImageBufAlgo!transpose} \indexapi{transpose} Copy while transposing ($x \leftrightarrow y$) pixels. \smallskip \noindent Examples: \begin{code} A = ImageBuf ("tahoe.exr") B = ImageBuf() ImageBufAlgo.transpose (B, A) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce circular_shift} (dst, src, xshift, yshift, zshift=0, \\ \bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!circular_shift} \indexapi{circular_shift} Copy while circularly shifting by the given amount. \smallskip \noindent Examples: \begin{code} A = ImageBuf ("tahoe.exr") B = ImageBuf() ImageBufAlgo.circular_shift (B, A, 200, 100) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce resize} (dst, src, filtername="", filtersize=0.0, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!resize} \indexapi{resize} Set {\cf dst}, over the ROI, to be a high-quality resized version of the corresponding portion of {\cf src}. If the filter and size are not specified, an appropriate default will be chosen. \smallskip \noindent Examples: \begin{code} # Resize the image to 640x480, using the default filter Src = ImageBuf ("tahoe.exr") Dst = ImageBuf (ImageSpec (640, 480, 3, OpenImageIO.FLOAT)) ImageBufAlgo.resize (Dst, Src) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce resample} (dst, src, interpolate=True, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!resample} \indexapi{resample} Set {\cf dst}, over the ROI, to be a low-quality (but fast) resized version of the corresponding portion of {\cf src}, either using a simple ``closest pixel'' choice or by bilinaerly interpolating (depending on {\cf interpolate}). \smallskip \noindent Examples: \begin{code} # Resample quickly to 320x240 to make a low-quality thumbnail Src = ImageBuf ("tahoe.exr") Dst = ImageBuf (ImageSpec (320, 240, 3, OpenImageIO.UINT8)) ImageBufAlgo.resample (Dst, Src) \end{code} \apiend \subsection{Image arithmetic} \label{sec:iba:py:arith} \apiitem{bool ImageBufAlgo.{\ce add} (dst, A, B, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!add} \indexapi{add} Compute {\cf dst = A + B}. {\cf A} is an \ImageBuf, and {\cf B} may be an \ImageBuf, a {\cf float} (added to all channels) or a tuple giving a {\cf float} for each color channel. \smallskip \noindent Examples: \begin{code} # Add two images buf = ImageBuf () ImageBufAlgo.add (buf, ImageBuf("a.exr"), ImageBuf("b.exr")) # Add 0.2 to channels 0-2 ImageBufAlgo.add (buf, buf, (0.2,0.2,0.2,0)) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce sub} (dst, A, B, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!sub} \indexapi{sub} Compute {\cf dst = A - B}. {\cf A} is an \ImageBuf, and {\cf B} may be an \ImageBuf, a {\cf float} (added to all channels) or a tuple giving a {\cf float} for each color channel. \smallskip \noindent Examples: \begin{code} buf = ImageBuf () ImageBufAlgo.sub (buf, ImageBuf("a.exr"), ImageBuf("b.exr")) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce mul} (dst, A, B, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!mul} \indexapi{mul} Compute {\cf dst} = {\cf A * B} (channel-by-channel multiplication). {\cf A} is an \ImageBuf, and {\cf B} may be an \ImageBuf, a {\cf float} (added to all channels) or a tuple giving a {\cf float} for each color channel. \smallskip \noindent Examples: \begin{code} # Multiply the two images buf = ImageBuf () ImageBufAlgo.mul (buf, ImageBuf("a.exr"), ImageBuf("b.exr")) # Reduce intensity of buf's channels 0-2 by 50%, in place ImageBufAlgo.mul (buf, buf, (0.5, 0.5, 0.5, 1)) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce channel_sum} (dst, src, weights=(), \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!channel_sum} \indexapi{channel_sum} Converts a multi-channel image into a 1-channel image via a weighted sum of channels. The {\cf weights} is a tuple providing the weight for each channel (if not supplied, all channels will have weight 1.0). \smallskip \noindent Examples: \begin{code} # Compute luminance via a weighted sum of R,G,B # (assuming Rec709 primaries and a linear scale) luma_weights = (.2126, .7152, .0722) ImageBufAlgo.channel_sum (luma, ImageBuf("a.exr"), luma_weights) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce clamp} (dst, src, min, max, bool clampalpha01=False, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!clamp} \indexapi{clamp} Copy pixels while clamping between the {\cf min} and {\cf max} values. The {\cf min} and {\cf max} may either be tuples (one min and max value per channel), or single {\cf floats} (same value for all channels). Additionally, if {\cf clampalpha01} is {\cf True}, then any alpha channel is clamped to the 0--1 range. \smallskip \noindent Examples: \begin{code} # Clamp image buffer A in-place to the [0,1] range for all channels. ImageBufAlgo.clamp (A, A, 0.0, 1.0) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce rangecompress} (dst, src, useluma=False, \\ \bigspc\bigspc roi=ROI.All, nthreads=0) \\ bool ImageBufAlgo.{\ce rangeexpand} (dst, src, useluma=False, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!rangecompress} \indexapi{rangecompress} \index{ImageBufAlgo!rangeexpand} \indexapi{rangeexpand} Copy from {\cf src} to {\cf dst}, compressing (logarithmically) or expanding (by the inverse of the compressive transformation) the range of pixel values. Alpha and z channels are copied but not transformed. If {\cf useluma} is {\cf True}, the luma of the first three channels (presumed to be R, G, and B) are used to compute a single scale factor for all color channels, rather than scaling all channels individually (which could result in a big color shift when performing {\cf rangecompress} and {\cf rangeexpand}). \smallskip \noindent Examples: \begin{code} # Resize the image to 640x480, using a Lanczos3 filter, which # has negative lobes. To prevent those negative lobes from # producing ringing or negative pixel values for HDR data, # do range compression, then resize, then re-expand the range. # 1. Read the original image Src = ImageBuf ("tahoeHDR.exr") # 2. Range compress to a logarithmic scale Compressed = ImageBuf () ImageBufAlgo.rangecompress (Compressed, Src) # 3. Now do the resize Dst = ImageBuf () roi = ROI (0, 640, 0, 480, 0, 1, 0, Compressed.nchannels) ImageBufAlgo.resize (Dst, Compressed, "lanczos3", 6.0, roi) # 4. Expand range to be linear again (operate in-place) ImageBufAlgo.rangeexpand (Dst, Dst) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce over} (dst, A, B, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!over} \indexapi{over} Composite \ImageBuf\ {\cf A} \emph{over} \ImageBuf\ {\cf B}. \smallskip \noindent Examples: \begin{code} Composite = ImageBuf() ImageBufAlgo.over (Composite, ImageBuf("fg.exr"), ImageBuf("bg.exr")) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce zover} (dst, A, B, bool z_zeroisinf=False,\\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!zover} \indexapi{zover} Composite \ImageBuf\ {\cf A} and \ImageBuf\ {\cf B} using their respective $Z$ channels to decide which is in front on a pixel-by-pixel basis. \smallskip \noindent Examples: \begin{code} Composite = ImageBuf() ImageBufAlgo.zover (Composite, ImageBuf("fg.exr"), ImageBuf("bg.exr")) \end{code} \apiend \subsection{Image comparison and statistics} \label{sec:iba:py:stats} \begin{comment} % Not figured out yet \apiitem{bool ImageBufAlgo.{\ce computePixelStats} (PixelStats \&stats, src, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!computePixelStats} \indexapi{computePixelStats} Compute statistics about the ROI of the image {\cf src}, storing results in {\cf stats} (each of the vectors within {\cf stats} will be automatically resized to the number of channels in the image). A return value of {\cf true} indicates success, {\cf false} indicates that it was not possible to complete the operation. The {\cf PixelStats} structure is defined as follows: \begin{code} struct PixelStats { std::vector min std::vector max std::vector avg std::vector stddev std::vector nancount std::vector infcount std::vector finitecount std::vector sum, sum2 # for intermediate calculation } \end{code} \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr") ImageBufAlgo.PixelStats stats ImageBufAlgo.computePixelStats (stats, A) for (int c = 0; c < A.nchannels(); ++c) { print "Channel ", c, ":" print " min = ", stats.min[c] print " max = ", stats.max[c] print " average = ", stats.avg[c] print " standard deviation = ", stats.stddev[c] print " # NaN values = ", stats.nancount[c] print " # Inf values = ", stats.infcount[c] print " # finite values = ", stats.finitecount[c] } \end{code} \apiend \end{comment} \apiitem{bool ImageBufAlgo.{\ce compare} (A, B, failthresh, warnthresh, result, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!compare} \indexapi{compare} Numerically compare two \ImageBuf's, {\cf A} and {\cf B}. The {\cf failthresh} and {\cf warnthresh} supply failure and warning difference thresholds. The {\cf result} parameter must refer to a {\cf CompareResults} object, which is defined as a class having the following members: \begin{code} meanerror, rms_error, PSNR, maxerror # error statistics maxx, maxy, maxz, maxc # pixel of biggest difference nwarn, nfail # number of warnings and failures \end{code} \smallskip \noindent Examples: \begin{code} A = ImageBuf ("a.exr") B = ImageBuf ("b.exr") comp = OpenImageIO.CompareResults() ImageBufAlgo.compare (A, B, 1.0/255.0, 0.0, comp) if comp.nwarn == 0 and comp.nfail == 0 : print "Images match within tolerance" else : print comp.nfail, "failures,", comp.nwarn, " warnings." print "Average error was " , comp.meanerror print "RMS error was" , comp.rms_error print "PSNR was" , comp.PSNR print "largest error was ", comp.maxerror print " on pixel", (comp.maxx, comp.maxy, comp.maxz) print " channel", comp.maxc \end{code} \apiend \apiitem{tuple ImageBufAlgo.{\ce isConstantColor} (src, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!isConstantColor} \indexapi{isConstantColor} If all pixels of {\cf src} within the ROI have the same values (for the subset of channels described by {\cf roi}), return a tuple giving that color (one {\cf float} for each channel), otherwise return {\cf None}. \smallskip \noindent Examples: \begin{code} A = ImageBuf ("a.exr") color = ImageBufAlgo.isConstantColor (A) if color != None : print "The image has the same value in all pixels:", color else : print "The image is not a solid color." \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce isConstantChannel} (src, channel, val, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!isConstantChannel} \indexapi{isConstantChannel} Returns {\cf True} if all pixels of {\cf src} within the ROI have the given {\cf channel} value {\cf val}. \smallskip \noindent Examples: \begin{code} A = ImageBuf ("a.exr") alpha = A.spec.alpha_channel if alpha < 0 : print "The image does not have an alpha channel" elif ImageBufAlgo.isConstantChannel (A, alpha, 1.0) : print "The image has alpha = 1.0 everywhere" else : print "The image has alpha < 1 in at least one pixel" \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce isMonochrome} (src, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!isMonochrome} \indexapi{isMonochrome} Returns {\cf True} if the image is monochrome within the ROI. \smallskip \noindent Examples: \begin{code} A = ImageBuf ("a.exr") roi = A.roi roi.chend = min (3, roi.chend) # only test RGB, not alpha if ImageBufAlgo.isMonochrome (A, roi) : print "a.exr is really grayscale" \end{code} \apiend \begin{comment} \apiitem{bool ImageBufAlgo.{\ce color_count} (src, imagesize_t *count,\\ \bigspc int ncolors, const float *color, const float *eps=NULL, \\ \bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!color_count} \indexapi{color_count} Count how many pixels in the image (within the ROI) match a list of colors. The colors to match are in: \begin{code} colors[0 ... nchans-1] colors[nchans ... 2*nchans-1] ... colors[(ncolors-1)*nchans ... (ncolors*nchans)-1] \end{code} \noindent and so on, a total of {\cf ncolors} consecutively stored colors of {\cf nchans} channels each ({\cf nchans} is the number of channels in the image, itself, it is not passed as a parameter). The values in {\cf eps[0..nchans-1]} are the error tolerances for a match, for each channel. Setting {\cf eps[c]} to {\cf numeric_limits::max()} will effectively make it ignore the channel. Passing {\cf eps == NULL} will be interpreted as a tolerance of 0.001 for all channels (requires exact matches for 8 bit images, but allows a wee bit of imprecision for {\cf float} images. \smallskip \noindent Examples: \begin{code} A = ImageBuf ("a.exr") n = A.nchannels # Try to match two colors: pure red and green std::vector colors (2*n, numeric_limits::max()); colors[0] = 1.0; colors[1] = 0.0; colors[2] = 0.0; colors[n+0] = 0.0; colors[n+1] = 1.0; colors[n+2] = 0.0; const int ncolors = 2; imagesize_t count[ncolors]; ImageBufAlgo.color_count (A, count, ncolors); print "Number of red pixels : ", count[0] print "Number of green pixels : ", count[1] \end{code} \apiend \apiitem{bool {\ce color_range_check} (src, imagesize_t *lowcount, \\ \bigspc imagesize_t *highcount, imagesize_t *inrangecount, \\ \bigspc const float *low, const float *high, \\ \bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!color_range_check} \indexapi{color_range_check} Count how many pixels in the image (within the ROI) are outside the value range described by {\cf low[roi.chbegin..roi.chend-1]} and {\cf high[roi.chbegin..roi.chend-1]} as the low and high acceptable values for each color channel. The number of pixels containing values that fall below the lower bound will be stored in {\cf *lowcount}, the number of pixels containing values that fall above the upper bound will be stored in {\cf *highcount}, and the number of pixels for which all channels fell within the bounds will be stored in {\cf *inrangecount}. Any of these may be NULL, which simply means that the counts need not be collected or stored. \smallskip \noindent Examples: \begin{code} A = ImageBuf ("a.exr") ROI roi = get_roi (A.spec()) roi.chend = std::min (roi.chend, 4); # only compare RGBA float low[] = {0, 0, 0, 0}; float high[] = {1, 1, 1, 1}; imagesize_t lowcount, highcount, inrangecount; ImageBufAlgo.color_range_check (A, &lowcount, &highcount, &inrangecount, low, high, roi); print lowcount, " pixels had components < 0" print highcount, " pixels had components > 1" print inrangecount, " pixels were fully within [0,1] range" \end{code} \apiend \end{comment} \apiitem{std::string ImageBufAlgo.{\ce computePixelHashSHA1} (src, extrainfo = "", \\ \bigspc\bigspc roi=ROI.All, blocksize=0, nthreads=0)} \index{ImageBufAlgo!computePixelHashSHA1} \indexapi{computePixelHashSHA1} Compute the SHA-1 byte hash for all the pixels in the ROI of {\cf src}. \smallskip \noindent Examples: \begin{code} A = ImageBuf ("a.exr") hash = ImageBufAlgo.computePixelHashSHA1 (A, blocksize=64) \end{code} \apiend \begin{comment} \apiitem{bool {\ce histogram} (src, int channel, \\ \bigspc std::vector \&histogram, int bins=256, \\ \bigspc float min=0, float max=1, imagesize_t *submin=NULL, \\ \bigspc imagesize_t *supermax=NULL, roi=ROI.All)} \index{ImageBufAlgo!histogram} \indexapi{histogram} \apiend \end{comment} \subsection{Convolutions} \label{sec:iba:py:convolutions} \apiitem{bool ImageBufAlgo.{\ce make_kernel} (dst, name, width, height, \\ \bigspc\bigspc depth=1.0, normalize=True)} \index{ImageBufAlgo!make_kernel} \indexapi{make_kernel} Initialize {\cf dst} to be a 1-channel {\cf float} image of the named kernel and dimensions. If {\cf normalize} is {\cf True}, the values will be normalized so that they sum to $1.0$. If {\cf depth} $> 1$, a volumetric kernel will be created. Use with caution! Kernel names can be: \qkw{gaussian}, \qkw{sharp-gaussian}, \qkw{box}, \qkw{triangle}, \qkw{mitchell}, \qkw{blackman-harris}, \qkw{b-spline}, \qkw{catmull-rom}, \qkw{lanczos3}, \qkw{disk}, \qkw{binomial}. Note that \qkw{catmull-rom} and \qkw{lanczos3} are fixed-size kernels that don't scale with the width, and are therefore probably less useful in most cases. \smallskip \noindent Examples: \begin{code} K = ImageBuf() ImageBufAlgo.make_kernel (K, "gaussian", 5.0, 5.0) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce convolve} (dst, src, kernel, normalize=True, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!convolve} \indexapi{convolve} Replace the given ROI of {\cf dst} with the convolution of {\cf src} and a kernel (also an \ImageBuf). \smallskip \noindent Examples: \begin{code} # Blur an image with a 5x5 Gaussian kernel Src = ImageBuf ("tahoe.exr") K = ImageBuf () ImageBufAlgo.make_kernel (K, "gaussian", 5.0, 5.0) Blurred = ImageBuf () ImageBufAlgo.convolve (Blurred, Src, K) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce fft} (dst, src, roi=ROI.All, nthreads=0) \\ bool ImageBufAlgo.{\ce ifft} (dst, src, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!fft} \indexapi{fft} \index{ImageBufAlgo!ifft} \indexapi{ifft} Compute the forward or inverse discrete Fourier Transform. \smallskip \noindent Examples: \begin{code} Src = ImageBuf ("tahoe.exr") # Take the DFT of the first channel of Src Freq = ImageBuf () ImageBufAlgo.fft (Freq, Src) # At this point, Freq is a 2-channel float image (real, imag) # Convert it back from frequency domain to a spatial iamge Spatial = ImageBuf () ImageBufAlgo.ifft (Spatial, Freq) \end{code} \apiend \subsection{Image Enhancement / Restoration} \label{sec:iba:py:enhance} \apiitem{bool ImageBufAlgo.{\ce fixNonFinite} (dst, src, mode=NONFINITE_BOX3, \\ \bigspc\spc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!fixNonFinite} \indexapi{fixNonFinite} Copy pixel values from {\cf src} to {\cf dst} (within the pixel and channel range designated by {\cf roi}), and repair any non-finite ({\cf NaN} or {\cf Inf}) pixels. How the non-finite values are repaired is specified by one of the following modes: \\ {\cf OpenImageIO.NONFINITE_NONE}, \\ {\cf OpenImageIO.NONFINITE_BLACK} \\ {\cf OpenImageIO.NONFINITE_BOX3} \smallskip \noindent Examples: \begin{code} Src = ImageBuf ("tahoe.exr") ImageBufAlgo.fixNonFinite (Src, Src, OpenImageIO.NONFINITE_BOX3) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce fillholes_pushpull} (dst, src, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!fillholes_pushpull} \indexapi{fillholes_pushpull} Copy the specified ROI of {\cf src} to {\cf dst} and fill any holes (pixels where alpha $< 1$) with plausible values using a push-pull technique. The {\cf src} image must have an alpha channel. The dst image will end up with a copy of src, but will have an alpha of 1.0 everywhere, and any place where the alpha of src was < 1, dst will have a pixel color that is a plausible ``filling'' of the original alpha hole. \smallskip \noindent Examples: \begin{code} Src = ImageBuf ("holes.exr") Filled = ImageBuf () ImageBufAlgo.fillholes_pushpull (Filled, Src) \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce unsharp_mask} (dst, src, kernel="gaussian", \\ \bigspc\spc width=3.0, contrast=1.0, threshold=0.0, \\ \bigspc\spc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!unsharp_mask} \indexapi{unsharp_mask} Replace the given ROI of {\cf dst} with a sharpened version of the corresponding region of {\cf src} using the ``unsharp mask'' technique. \smallskip \noindent Examples: \begin{code} Blurry = ImageBuf ("tahoe.exr") Sharp = ImageBuf () ImageBufAlgo.unsharp_mask (Sharp, Blurry, "gaussian", 5.0) \end{code} \apiend \subsection{Color manipulation} \label{sec:iba:py:color} \apiitem{bool ImageBufAlgo.{\ce colorconvert} (dst, src, from, to, unpremult=False, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!colorconvert} \indexapi{colorconvert} Copy pixels from {\cf src} to {\cf dst} (within the ROI), while applying a color transform to the pixel values. In-place operations ({\cf dst} and {\cf src} being the same image) are supported. \smallskip \noindent Examples: \begin{code} Src = ImageBuf ("tahoe.jpg") Dst = ImageBuf () ImageBufAlgo.colorconvert (Dst, Src, "vd8", "lnf") \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce ociolook} (dst, src, looks, from, to, \\ \bigspc\spc inverse=False, unpremult=False, key="", value="", \\ \bigspc\spc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!ociolook} \indexapi{ociolook} Copy pixels from {\cf src} to {\cf dst} (within the ROI), while applying an OpenColorIO ``look'' transform to the pixel values. In-place operations ({\cf dst} and {\cf src} being the same image) are supported. \smallskip \noindent Examples: \begin{code} Src = ImageBuf ("tahoe.jpg") Dst = ImageBuf () ImageBufAlgo.ociolook (Dst, Src, "look", "vd8", "lnf", False, False, key="SHOT", value="pe0012") \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce ociodisplay} (dst, src, display, view, \\ \bigspc\spc from=None, looks=None, unpremult=False, key="", value="", \\ \bigspc\spc roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!ociodisplay} \indexapi{ociodisplay} Copy pixels from {\cf src} to {\cf dst} (within the ROI), while applying an OpenColorIO ``display'' transform to the pixel values. In-place operations ({\cf dst} and {\cf src} being the same image) are supported. \smallskip \noindent Examples: \begin{code} Src = ImageBuf ("tahoe.exr") Dst = ImageBuf () ImageBufAlgo.ociodisplay (Dst, Src, "sRGB", "Film", "lnf", False, key="SHOT", value="pe0012") \end{code} \apiend \apiitem{bool ImageBufAlgo.{\ce unpremult} (dst, src, roi=ROI.All, nthreads=0) \\ bool ImageBufAlgo.{\ce premult} (dst, src, roi=ROI.All, nthreads=0)} \index{ImageBufAlgo!unpremult} \indexapi{unpremult} \index{ImageBufAlgo!premult} \indexapi{premult} Copy pixels from {\cf src} to {\cf dst}, and un-premultiply (or premultiply) the colors by alpha. \smallskip \noindent Examples: \begin{code} # Convert in-place from associated alpha to unassociated alpha A = ImageBuf ("a.exr") ImageBufAlgo.unpremult (A, A) \end{code} \apiend \subsection{Import / export} \label{sec:iba:py:importexport} \apiitem{bool ImageBufAlgo.{\ce make_texture} (mode, input,\\ \bigspc\bigspc outputfilename, config=ImageSpec())} \index{ImageBufAlgo!make_texture} \indexapi{make_texture} Turn an input image (either an \ImageBuf or a string giving a filename) into a tiled, MIP-mapped, texture file and write to the file named by ({\cf outputfilename}). The {\cf mode} describes what type of texture file we are creating and may be one of the following: \noindent \begin{tabular}{p{4in}} {\cf OpenImageIO.MakeTxTexture} \\ {\cf OpenImageIO.MakeTxEnvLatl} \\ {\cf OpenImageIO.MakeTxEnvLatlFromLightProbe} \\ \end{tabular} The {\cf config}, if supplied, is an \ImageSpec that contains all the information and special instructions for making the texture. The full list of supported configuration options is given in Section~\ref{sec:iba:importexport}. \smallskip \noindent Examples: \begin{code} # This command line: # maketx in.exr --hicomp --filter lanczos3 --opaque-detect \ # -o texture.exr # is equivalent to: Input = ImageBuf ("in.exr") config = ImageSpec() config.attribute ("maketx:highlightcomp", 1) config.attribute ("maketx:filtername", "lanczos3") config.attribute ("maketx:opaquedetect", 1) ImageBufAlgo.make_texture (oiio.MakeTxTexture, Input, "texture.exr", config) \end{code} \apiend \apiitem{bool ImageBufAlgo::{\ce capture_image} (dst, cameranum, \\ \bigspc\bigspc convert = OpenImageIO.UNKNOWN)} \index{ImageBufAlgo!capture_image} \indexapi{capture_image} Capture a still image from a designated camera. \smallskip \noindent Examples: \begin{code} WebcamImage = ImageBuf() ImageBufAlgo.capture_image (WebcamImage, 0, OpenImageIO.UINT8) WebcamImage.save ("webcam.jpg") \end{code} \apiend \newpage \section{Miscellaneous Utilities} \label{sec:pythonmiscapi} In the main {\cf OpenImageIO} module, there are a number of values and functions that are useful. These correspond to the C++ API functions explained in Section~\ref{sec:miscapi}, please refer there for details. \apiitem{int {\ce openimageio_version}} The \product version number, 10000 for each major version, 100 for each minor version, 1 for each patch. For example, \product 1.2.3 would return a value of 10203. \apiend \apiitem{str {\ce geterror} ()} Retrieves the latest global error. \apiend \apiitem{bool {\ce attribute} (name, typedesc, value) \\ bool {\ce attribute} (name, int_value) \\ bool {\ce attribute} (name, float_value) \\ bool {\ce attribute} (name, str_value)} Sets a global attribute (see Section~\ref{sec:miscapi} for details), returning {\cf True} upon success, or {\cf False} if it was not a recognized attribute. \noindent Example: \begin{code} oiio.attribute ("threads", 0) \end{code} \apiend \index{Python|)} \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/imageinput.tex0000644000175000017500000014111712271062644020546 0ustar mfvmfv\chapter{Image I/O: Reading Images} \label{chap:imageinput} \index{Image I/O API|(} \section{Image Input Made Simple} \label{sec:imageinput:simple} Here is the simplest sequence required to open an image file, find out its resolution, and read the pixels (converting them into 8-bit values in memory, even if that's not the way they're stored in the file): \begin{code} #include OIIO_NAMESPACE_USING ... ImageInput *in = ImageInput::open (filename); if (! in) return; const ImageSpec &spec = in->spec(); int xres = spec.width; int yres = spec.height; int channels = spec.nchannels; std::vector pixels (xres*yres*channels); in->read_image (TypeDesc::UINT8, &pixels[0]); in->close (); delete in; \end{code} \noindent Here is a breakdown of what work this code is doing: \begin{itemize} \item Search for an ImageIO plugin that is capable of reading the file (\qkw{foo.jpg}), first by trying to deduce the correct plugin from the file extension, but if that fails, by opening every ImageIO plugin it can find until one will open the file without error. When it finds the right plugin, it creates a subclass instance of \ImageInput that reads the right kind of file format, and tries to fully open the file. \begin{code} ImageInput *in = ImageInput::open (filename); \end{code} \item The specification, accessible as {\cf in->spec()}, contains vital information such as the dimensions of the image, number of color channels, and data type of the pixel values. This is enough to allow us to allocate enough space for the image. \begin{code} const ImageSpec &spec = in->spec(); int xres = spec.width; int yres = spec.height; int channels = spec.nchannels; std::vector pixels (xres*yres*channels); \end{code} Note that in this example, we don't care what data format is used for the pixel data in the file --- we allocate enough space for unsigned 8-bit integer pixel values, and will rely on \product's ability to convert to our requested format from the native data format of the file. \item Read the entire image, hiding all details of the encoding of image data in the file, whether the file is scanline- or tile-based, or what is the native format of the data in the file (in this case, we request that it be automatically converted to unsigned 8-bit integers). \begin{code} in->read_image (TypeDesc::UINT8, &pixels[0]); \end{code} \item Close the file, destroy and free the \ImageInput we had created, and perform all other cleanup and release of any resources used by the plugin. \begin{code} in->close (); delete in; \end{code} \end{itemize} \section{Advanced Image Input} \label{sec:advancedimageinput} Let's walk through some of the most common things you might want to do, but that are more complex than the simple example above. \subsection{Reading individual scanlines and tiles} \label{sec:imageinput:scanlinestiles} The simple example of Section~\ref{sec:imageinput:simple} read an entire image with one call. But sometimes you want to read a large image a little at a time and do not wish to retain the entire image in memory as you process it. \product allows you to read images one scanline at a time or one tile at a time. Examining the \ImageSpec reveals whether the file is scanline or tile-oriented: a scanline image will have {\cf spec.tile_width} and {\cf spec.tile_height} set to 0, whereas a tiled images will have nonzero values for the tile dimensions. \subsubsection{Reading scanlines} Individual scanlines may be read using the \readscanline API call: \begin{code} ... in = ImageInput::open (filename); const ImageSpec &spec = in->spec(); if (spec.tile_width == 0) { std::vector scanline (spec.width*spec.channels); for (int y = 0; y < yres; ++y) { in->read_scanline (y, 0, TypeDesc::UINT8, &scanline[0]); ... process data in scanline[0..width*channels-1] ... } } else { ... handle tiles, or reject the file ... } in->close (); ... \end{code} The first two arguments to \readscanline specify which scanline is being read by its vertical ($y$) scanline number (beginning with 0) and, for volume images, its slice ($z$) number (the slice number should be 0 for 2D non-volume images). This is followed by a \TypeDesc describing the data type of the pixel buffer you are supplying, and a pointer to the pixel buffer itself. Additional optional arguments describe the data stride, which can be ignored for contiguous data (use of strides is explained in Section~\ref{sec:imageinput:strides}). Nearly all \ImageInput implementations will be most efficient reading scanlines in strict order (starting with scanline 0, then 1, up to {\kw yres-1}, without skipping any). An \ImageInput is required to accept \readscanline requests in arbitrary order, but depending on the file format and reader implementation, out-of-order scanline reads may be inefficient. There is also a {\cf read_scanlines()} function that operates similarly, except that it takes a {\cf ybegin} and {\cf yend} that specify a range, reading all scanlines {\cf ybegin} $\le y <$ {\cf yend}. For most image format readers, this is implemented as a loop over individual scanlines, but some image format readers may be able to read a contiguous block of scanlines more efficiently than reading each one individually. The full descriptions of the \readscanline and {\cf read_scanlines()} functions may be found in Section~\ref{sec:imageinput:reference}. \subsubsection{Reading tiles} Once you {\kw open()} an image file, you can find out if it is a tiled image (and the tile size) by examining the \ImageSpec's {\cf tile_width}, {\cf tile_height}, and {\cf tile_depth} fields. If they are zero, it's a scanline image and you should read pixels using \readscanline, not \readtile. \begin{code} ... in = ImageInput::open (filename); const ImageSpec &spec = in->spec(); if (spec.tile_width == 0) { ... read by scanline ... } else { // Tiles int tilesize = spec.tile_width * spec.tile_height; std::vector tile (tilesize * spec.channels); for (int y = 0; y < yres; y += spec.tile_height) { for (int x = 0; x < xres; x += spec.tile_width) { in->read_tile (x, y, 0, TypeDesc::UINT8, &tile[0]); ... process the pixels in tile[] .. } } } in->close (); ... \end{code} The first three arguments to \readtile specify which tile is being read by the pixel coordinates of any pixel contained in the tile: $x$ (column), $y$ (scanline), and $z$ (slice, which should always be 0 for 2D non-volume images). This is followed by a \TypeDesc describing the data format of the pixel buffer you are supplying, and a pointer to the pixel buffer. Pixel data will be written to your buffer in order of increasing slice, increasing scanline within each slice, and increasing column within each scanline. Additional optional arguments describe the data stride, which can be ignored for contiguous data (use of strides is explained in Section~\ref{sec:imageinput:strides}). All \ImageInput implementations are required to support reading tiles in arbitrary order (i.e., not in strict order of increasing $y$ rows, and within each row, increasing $x$ column, without missing any tiles). The full description of the \readtile function may be found in Section~\ref{sec:imageinput:reference}. \subsection{Converting formats} \label{sec:imageinput:convertingformat} The code examples of the previous sections all assumed that your internal pixel data is stored as unsigned 8-bit integers (i.e., 0-255 range). But \product is significantly more flexible. You may request that the pixels be stored in any of several formats. This is done merely by passing the {\cf read} function the data type of your pixel buffer, as one of the enumerated type \TypeDesc. %FIXME %Individual file formats, and therefore \ImageInput implementations, may %only support a subset of the formats understood by the \product library. %Each \ImageInput plugin implementation should document which data %formats it supports. An individual \ImageInput implementation may %choose to simply fail open {\kw open()}, though the recommended behavior %is for {\kw open()} to succeed but in fact choose a data format %supported by the file format that best preserves the precision and range %of the originally-requested data format. It is not required that the pixel data buffer passed to \readimage, \readscanline, or \readtile actually be in the same data format as the data in the file being read. \product will automatically convert from native data type of the file to the internal data format of your choice. For example, the following code will open a TIFF and read pixels into your internal buffer represented as {\cf float} values. This will work regardless of whether the TIFF file itself is using 8-bit, 16-bit, or float values. \begin{code} ImageInput *in = ImageInput::open ("myfile.tif"); const ImageSpec &spec = in->spec(); ... int numpixels = spec.width * spec.height; float pixels = new float [numpixels * channels]; ... in->read_image (TypeDesc::FLOAT, pixels); \end{code} \noindent Note that \readscanline and \readtile have a parameter that works in a corresponding manner. You can, of course, find out the native type of the file simply by examining {\cf spec.format}. If you wish, you may then allocate a buffer big enough for an image of that type and request the native type when reading, therefore eliminating any translation among types and seeing the actual numerical values in the file. %FIXME %Please refer to Section~\ref{sec:imageinput:quantization} for more %information on how values are translated among the supported data %formats by default, and how to change the formulas by specifying %quantization in the \ImageSpec. \subsection{Data Strides} \label{sec:imageinput:strides} In the preceeding examples, we have assumed that the buffer passed to the {\cf read} functions (i.e., the place where you want your pixels to be stored) is \emph{contiguous}, that is: \begin{itemize} \item each pixel in memory consists of a number of data values equal to the number of channels in the file; \item successive column pixels within a row directly follow each other in memory, with the first channel of pixel $x$ immediately following last channel of pixel $x-1$ of the same row; \item for whole images or tiles, the data for each row immediately follows the previous one in memory (the first pixel of row $y$ immediately follows the last column of row $y-1$); \item for 3D volumetric images, the first pixel of slice $z$ immediately follows the last pixel of of slice $z-1$. \end{itemize} Please note that this implies that \readtile will write pixel data into your buffer so that it is contiguous in the shape of a single tile, not just an offset into a whole image worth of pixels. The \readscanline function takes an optional {\cf xstride} argument, and the \readimage and \readtile functions take optional {\cf xstride}, {\cf ystride}, and {\cf zstride} values that describe the distance, in \emph{bytes}, between successive pixel columns, rows, and slices, respectively, of your pixel buffer. For any of these values that are not supplied, or are given as the special constant {\cf AutoStride}, contiguity will be assumed. By passing different stride values, you can achieve some surprisingly flexible functionality. A few representative examples follow: \begin{itemize} \item Flip an image vertically upon reading, by using \emph{negative} $y$ stride: \begin{code} unsigned char pixels[spec.width * spec.height * spec.nchannels]; int scanlinesize = spec.width * spec.nchannels * sizeof(pixels[0]); ... in->read_image (TypeDesc::UINT8, (char *)pixels+(yres-1)*scanlinesize, // offset to last AutoStride, // default x stride -scanlinesize, // special y stride AutoStride); // default z stride \end{code} \item Read a tile into its spot in a buffer whose layout matches a whole image of pixel data, rather than having a one-tile-only memory layout: \begin{code} unsigned char pixels[spec.width * spec.height * spec.nchannels]; int pixelsize = spec.nchannels * sizeof(pixels[0]); int scanlinesize = xpec.width * pixelsize; ... in->read_tile (x, y, 0, TypeDesc::UINT8, (char *)pixels + y*scanlinesize + x*pixelsize, pixelsize, scanlinesize); \end{code} \end{itemize} Please consult Section~\ref{sec:imageinput:reference} for detailed descriptions of the stride parameters to each {\cf read} function. \subsection{Reading metadata} \label{sec:imageinput:metadata} The \ImageSpec that is filled in by {\cf ImageInput::open()} specifies all the common properties that describe an image: data format, dimensions, number of channels, tiling. However, there may be a variety of additional \emph{metadata} that are present in the image file and could be queried by your application. The remainder of this section explains how to query additional metadata in the \ImageSpec. It is up to the \ImageInput to read these from the file, if indeed the file format is able to carry additional data. Individual \ImageInput implementations should document which metadata they read. \subsubsection{Channel names} In addition to specifying the number of color channels, the \ImageSpec also stores the names of those channels in its {\cf channelnames} field, which is a {\cf vector}. Its length should always be equal to the number of channels (it's the responsibility of the \ImageInput to ensure this). Only a few file formats (and thus \ImageInput implementations) have a way of specifying custom channel names, so most of the time you will see that the channel names follow the default convention of being named \qkw{R}, \qkw{G}, \qkw{B}, and \qkw{A}, for red, green, blue, and alpha, respectively. Here is example code that prints the names of the channels in an image: \begin{code} ImageInput *in = ImageInput::open (filename); const ImageSpec &spec = in->spec(); for (int i = 0; i < spec.nchannels; ++i) std::cout << "Channel " << i << " is " << spec.channelnames[i] << "\n"; \end{code} \subsubsection{Specially-designated channels} The \ImageSpec contains two fields, {\cf alpha_channel} and {\cf z_channel}, which designate which channel numbers represent alpha and $z$ depth, if any. If either is set to {\cf -1}, it indicates that it is not known which channel is used for that data. If you are doing something special with alpha or depth, it is probably safer to respect the {\cf alpha_channel} and {\cf z_channel} designations (if not set to {\cf -1}) rather than merely assuming that, for example, channel 3 is always the alpha channel. \subsubsection{Arbitrary metadata} All other metadata found in the file will be stored in the \ImageSpec's {\cf extra_attribs} field, which is a \ParamValueList, which is itself essentially a vector of \ParamValue instances. Each \ParamValue stores one meta-datum consisting of a name, type (specified by a \TypeDesc), number of values, and data pointer. If you know the name of a specific piece of metadata you want to use, you can find it using the {\cf ImageSpec::find_attribute()} method, which returns a pointer to the matching \ParamValue, or {\cf NULL} if no match was found. An optional \TypeDesc argument can narrow the search to only parameters that match the specified type as well as the name. Below is an example that looks for orientation information, expecting it to consist of a single integer: \begin{code} ImageInput *in = ImageInput::open (filename); const ImageSpec &spec = in->spec(); ... ParamValue *p = spec.find_attribute ("Orientation", TypeDesc::TypeInt); if (p) { int orientation = * (int *) p->data(); } else { std::cout << "No integer orientation in the file\n"; } \end{code} By convention, \ImageInput plugins will save all integer metadata as 32-bit integers ({\cf TypeDesc::INT} or {\cf TypeDesc::UINT}), even if the file format dictates that a particular item is stored in the file as a 8- or 16-bit integer. This is just to keep client applications from having to deal with all the types. Since there is relatively little metadata compared to pixel data, there's no real memory waste of promoting all integer types to int32 metadata. Floating-point metadata and string metadata may also exist, of course. For certain common types, there is an even simpler method for retrieving the metadata: \begin{code} int i = spec.get_int_attribute ("Orientation", 0); float f = spec.get_float_attribute ("PixelAspectRatio", 1.0f); std::string s = spec.get_string_attribute ("ImageDescription", ""); \end{code} This method simply returns the value. The second argument is the default value to use if the attribute named is not found. These versions will do automatic type conversion as well --- for example, if you ask for a float and the attribute is really an int, it will return the proper float for it; or if the attribute is a UINT16 and you call {\cf get_int_attribute}, it will succeed, promoting to an int. It is also possible to step through all the metadata, item by item. This can be accomplished using the technique of the following example: \begin{code} for (size_t i = 0; i < spec.extra_attribs.size(); ++i) { const ParamValue &p (spec.extra_attribs[i]); printf (" \%s: ", p.name.c_str()); if (p.type() == TypeDesc::TypeString) printf ("\"\%s\"", *(const char **)p.data()); else if (p.type() == TypeDesc::TypeFloat) printf ("\%g", *(const float *)p.data()); else if (p.type() == TypeDesc::TypeInt) printf ("\%d", *(const int *)p.data()); else if (p.type() == TypeDesc::UINT) printf ("\%u", *(const unsigned int *)p.data()); else if (p.type() == TypeDesc::TypeMatrix) { const float *f = (const float *)p.data(); printf ("\%f \%f \%f \%f \%f \%f \%f \%f " "\%f \%f \%f \%f \%f \%f \%f \%f", f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9], f[10], f[11], f[12], f[13], f[14], f[15]); } else printf (""); printf ("\n"); } \end{code} Each individual \ImageInput implementation should document the names, types, and meanings of all metadata attributes that they understand. \subsubsection{Color space hints} We certainly hope that you are using only modern file formats that support high precision and extended range pixels (such as OpenEXR) and keeping all your images in a linear color space. But you may have to work with file formats that dictate the use of nonlinear color values. This is prevalent in formats that store pixels only as 8-bit values, since 256 values are not enough to linearly represent colors without banding artifacts in the dim values. The {\cf ImageSpec::extra_attribs} field may store metadata that reveals the color space the image file in the \qkw{oiio:ColorSpace} attribute, which may take on any of the following values: \begin{description} \item[\halfspc \rm \qkw{Linear}] indicates that the color pixel values are known to be linear. \item[\halfspc \rm \qkw{GammaCorrected}] indicates that the color pixel values (but not alpha or $z$) have already been gamma corrected (raised to the power $1/\gamma$), and that the gamma exponent may be found in the \qkw{oiio:Gamma} metadata. \item[\halfspc \rm \qkw{sRGB}] indicates that the color pixel values are in sRGB color space. \item[\halfspc \rm \qkw{AdobeRGB}] indicates that the color pixel values are in Adobe RGB color space. \item[\halfspc \rm \qkw{Rec709}] indicates that the color pixel values are in Rec709 color space. \item[\halfspc \rm \qkw{KodakLog}] indicates that the color pixel values are in Kodak logarithmic color space. \end{description} The \ImageInput sets the \qkw{oiio:ColorSpace} metadata in a purely advisory capacity --- the {\cf read} will not convert pixel values among color spaces. Many image file formats only support nonlinear color spaces (for example, JPEG/JFIF dictates use of sRGB). So your application should intelligently deal with gamma-corrected and sRGB input, at the very least. The color space hints only describe color channels. You should assume that alpha or depth ($z$) channels (designated by the {\cf alpha_channel} and {\cf z_channel} fields, respectively) always represent linear values and should never be transformed by your application. %\subsection{Controlling quantization and encoding} %\label{sec:imageinput:quantization} % %FIXME %\subsection{Random access and repeated transmission of pixels} %\label{sec:imageinput:randomrepeated} % %FIXME \subsection{Multi-image files and MIP-maps} \label{sec:imageinput:multiimage} \label{sec:imageinput:mipmap} Some image file formats support multiple discrete subimages to be stored in one file, and/or miltiple resolutions for each image to form a MIPmap. When you {\cf open()} an \ImageInput, it will by default point to the first (i.e., number 0) subimage in the file, and the highest resolution (level 0) MIP-map level. You can switch to viewing another subimage or MIP-map level using the {\cf seek_subimage()} function: \begin{code} ImageInput *in = ImageInput::open (filename); const ImageSpec &spec = in->spec(); ... int subimage = 1; int miplevel = 0; if (in->seek_subimage (subimage, miplevel, spec)) { ... } else { ... no such subimage/miplevel ... } \end{code} The {\cf seek_subimage()} function takes three arguments: the index of the subimage to switch to (starting with 0), the MIPmap level (starting with 0 for the highest-resolution level), and a reference to an \ImageSpec, into which will be stored the spec of the new subimage/miplevel. The {\cf seek_subimage()} function returns {\cf true} upon success, and {\cf false} if no such subimage or MIP level existed. It is legal to visit subimages and MIP levels out of order; the \ImageInput is responsible for making it work properly. It is also possible to find out which subimage and MIP level is currently being viewed, using the {\cf current_subimage()} and {\cf current_miplevel()} functions, which return the index of the current subimage and MIP levels, respectively. Below is pseudocode for reading all the levels of a MIP-map (a multi-resolution image used for texture mapping) that shows how to read multi-image files: \begin{code} ImageInput *in = ImageInput::open (filename); const ImageSpec &spec = in->spec(); int num_miplevels = 0; while (in->seek_subimage (0, num_miplevels, spec)) { // Note: spec has the format of the current subimage/miplevel int npixels = spec.width * spec.height; int nchannels = spec.nchannels; unsigned char *pixels = new unsigned char [npixels * nchannels]; in->read_image (TypeDesc::UINT8, pixels); ... do whatever you want with this level, in pixels ... delete [] pixels; ++num_miplevels; } // Note: we break out of the while loop when seek_subimage fails // to find a next MIP level. in->close (); delete in; \end{code} In this example, we have used \readimage, but of course \readscanline and \readtile work as you would expect, on the current subimage and MIP level. \subsection{Per-channel formats} \label{sec:imageinput:channelformats} Some image formats allow separate per-channel data formats (for example, {\cf half} data for colors and {\cf float} data for depth). If you want to read the pixels in their true native per-channel formats, the following steps are necessary: \begin{enumerate} \item Check the \ImageSpec's {\cf channelformats} vector. If non-empty, the channels in the file do not all have the same format. \item When calling {\cf read_scanline}, {\cf read_scanlines}, {\cf read_tile}, {\cf read_tiles}, or {\cf read_image}, pass a format of {\cf TypeDesc::UNKNOWN} to indicate that you would like the raw data in native per-channel format of the file written to your {\cf data} buffer. \end{enumerate} For example, the following code fragment will read a 5-channel image to an OpenEXR file, consisting of R/G/B/A channels in {\cf half} and a Z channel in {\cf float}: \begin{code} ImageInput *in = ImageInput::open (filename); const ImageSpec &spec = in->spec(); // Allocate enough space unsigned char *pixels = new unsigned char [spec.image_bytes(true)]; in->read_image (TypeDesc::UNKNOWN, /* use native channel formats */ pixels); /* data buffer */ if (spec.channelformats.size() > 0) { ... the buffer contains packed data in the native per-channel formats ... } else { ... the buffer contains all data per spec.format ... } \end{code} \subsection{Reading ``deep'' data} \label{sec:imageinput:deepdata} \index{deep data} Some image file formats (OpenEXR only, at this time) support the concept of ``deep'' pixels -- those containing multiple samples per pixel (and a potentially differing number of them in each pixel). You can tell an image is ``deep'' from its \ImageSpec: the {\cf deep} field will be {\cf true}. Deep files cannot be read with the usual {\cf read_scanline}, {\cf read_scanlines}, {\cf read_tile}, {\cf read_tiles}, {\cf read_image} functions, due to the nature of their variable number of samples per pixel. Instead, \ImageInput has three special member functions used only for reading deep data: \begin{code} bool read_native_deep_scanlines (int ybegin, int yend, int z, int chbegin, int chend, DeepData &deepdata); bool read_native_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, DeepData &deepdata); bool read_native_deep_image (DeepData &deepdata); \end{code} It is only possible to read ``native'' data types from deep files; that is, there is no automatic translation into arbitrary data types as there is for ordinary images. All three of these functions store the resulting deep data in a special {\cf DeepData} structure, defined in {\cf imageio.h} as follows: \begin{code} struct DeepData { int npixels, nchannels; std::vector channeltypes; // for each channel [c] std::vector nsamples;// for each pixel [z][y][x] std::vector pointers; // for each channel per pixel [z][y][x][c] std::vector data; // for each sample [z][y][x][c][s] DeepData (); void init (int npix, int nchan, const TypeDesc *chbegin, const TypeDesc *chend); void alloc (); }; \end{code} Here is an example of using these methods to read a deep image from a file and print all its values: \begin{code} ImageInput *in = ImageInput::open (filename); if (! in) return; const ImageSpec &spec = in->spec(); if (spec.deep) { DeepData deepdata; in->read_native_deep_image (deepdata); int p = 0; // absolute pixel number for (int y = 0; y < spec.height; ++y) { for (int x = 0; x < spec.width; ++x) { std::cout << "Pixel " << x << "," << y << ":\n"; if (deepdata.nsamples[p] == 0) std::cout << " no samples\n"; else for (int c = 0; c < spec.nchannels; ++c) { TypeDesc type = deepdata.channeltypes[c]; std::cout << " " << spec.channelnames[c] << ": "; void *ptr = deepdata.pointers[p*spec.nchannels+c] for (int s = 0; s < deepdata.nsamples[p]; ++s) { if (type.basetype == TypeDesc::FLOAT) std::cout << ((float *)ptr)[s] << ' '; else if (type.basetype == TypeDesc::HALF) std::cout << ((half *)ptr)[s] << ' '; ... handle other types ... } std::cout << "\n"; } } } } in->close (); delete in; \end{code} \subsection{Custom search paths for plugins} \label{sec:imageinput:searchpaths} Please see Section~\ref{sec:miscapi} for discussion about setting the plugin search path via the {\cf attribute()} function. For example: \begin{code} std::string mysearch = "/usr/myapp/lib:${HOME}/plugins"; OpenImageIO::attribute ("plugin_searchpath", mysearch); ImageInput *in = ImageInput::open (filename); ... \end{code} %$ \subsection{Error checking} \label{sec:imageinput:errors} \index{error checking} Nearly every \ImageInput API function returns a {\cf bool} indicating whether the operation succeeded ({\cf true}) or failed ({\cf false}). In the case of a failure, the \ImageInput will have saved an error message describing in more detail what went wrong, and the latest error message is accessible using the \ImageInput method {\cf geterror()}, which returns the message as a {\cf std::string}. The exceptions to this rule are static methods such as the static {\cf ImageInput::open} and {\cf ImageInput::create}, which return {\cf NULL} if it could not create an appropriate \ImageInput (and open it, in the case of {\cf open()}. In such a case, since no \ImageInput is returned for which you can call its {\cf geterror()} function, there exists a global {\cf geterror()} function (in the {\cf OpenImageIO} namespace) that retrieves the latest error message resulting from a call to static {\cf open()} or {\cf create()}. Here is another version of the simple image reading code from Section~\ref{sec:imageinput:simple}, but this time it is fully elaborated with error checking and reporting: \begin{code} #include OIIO_NAMESPACE_USING ... const char *filename = "foo.jpg"; int xres, yres, channels; std::vector pixels; ImageInput *in = ImageInput::open (filename); if (! in) { std::cerr << "Could not open " << filename << ", error = " << OpenImageIO::geterror() << "\n"; return; } const ImageSpec &spec = in->spec(); xres = spec.width; yres = spec.height; channels = spec.nchannels; pixels.resize (xres*yres*channels); if (! in->read_image (TypeDesc::UINT8, pixels)) { std::cerr << "Could not read pixels from " << filename << ", error = " << in->geterror() << "\n"; delete in; return; } if (! in->close ()) { std::cerr << "Error closing " << filename << ", error = " << in->geterror() << "\n"; delete in; return; } delete in; \end{code} \newpage \section{\ImageInput Class Reference} \label{sec:imageinput:reference} \apiitem{ImageInput * {\ce open} (const std::string \&filename, \\ \bigspc\bigspc const ImageSpec *config=NULL)} Create an \ImageInput subclass instance that is able to read the given file and open it, returning the opened \ImageInput if successful. If it fails, return {\cf NULL} and set an error that can be retrieved by {\cf OpenImageIO::geterror()}. The {\cf config}, if not {\cf NULL}, points to an \ImageSpec giving requests or special instructions. \ImageInput implementations are free to not respond to any such requests, so the default implementation is just to ignore config. The {\cf open()} function will first try to make an \ImageInput corresponding to the format implied by the file extension (for example, \qkw{foo.tif} will try the TIFF plugin), but if one is not found or if the inferred one does not open the file, every known \ImageInput type will be tried until one is found that will open the file. \apiend \apiitem{ImageInput * {\ce create} (const std::string \&filename, \\ \bigspc\bigspc const std::string \&plugin_searchpath="")} Create and return an \ImageInput implementation that is able to read the given file. The {\kw plugin_searchpath} parameter is a colon-separated list of directories to search for \product plugin DSO/DLL's (not a searchpath for the image itself!). This will actually just try every ImageIO plugin it can locate, until it finds one that's able to open the file without error. This just creates the \ImageInput, it does not open the file. \apiend \apiitem{const char * {\ce format_name} (void) const} Return the name of the format implemented by this class. \apiend \apiitem{bool {\ce supports} (const std::string \&feature)} \label{sec:inputsupportsfeaturelist} Given the name of a \emph{feature}, tells if this \ImageInput instance supports that feature. The following features are recognized by this query: \begin{description} \item[\spc] \spc \item[\rm ] No queries supported at this time. \end{description} \apiend \apiitem{bool {\ce valid_file} (const std::string \&filename) const} Return {\cf true} if the named file is a file of the type for this \ImageInput. The implementation will try to determine this as efficiently as possible, in most cases much less expensively than doing a full {\cf open()}. Note that a file can appear to be of the right type (i.e., {\cf valid_file()} returning {\cf true}) but still fail a subsequent call to {\cf open()}, such as if the contents of the file are truncated, nonsensical, or otherwise corrupted. \apiend \apiitem{bool {\ce open} (const std::string \&name, ImageSpec \&newspec)} Opens the file with given name and seek to the first subimage in the file. Various file attributes are put in {\kw newspec} and a copy is also saved internally to the \ImageInput (retrievable via {\kw spec()}. From examining {\kw newspec} or {\kw spec()}, you can discern the resolution, if it's tiled, number of channels, native data format, and other metadata about the image. Return {\kw true} if the file was found and opened okay, otherwise {\kw false}. \apiend \apiitem{bool {\ce open} (const std::string \&name, ImageSpec \&newspec,\\ \bigspc const ImageSpec \&config)} Opens the file with given name, similarly to {\cf open(name, newspec)}. However, in this version, any non-default fields of {\cf config}, including metadata, will be taken to be configuration requests, preferences, or hints. The default implementation of {\cf open (name, newspec, config)} will simply ignore {\cf config} and calls the usual {\cf open (name, newspec)}. But a plugin may choose to implement this version of {\cf open} and respond in some way to the configuration requests. Supported configuration requests should be documented by each plugin. \apiend \apiitem {const ImageSpec \& {\ce spec} (void) const} Returns a reference to the image format specification of the current subimage. Note that the contents of the spec are invalid before {\kw open()} or after {\kw close()}. \apiend \apiitem{bool {\ce close} ()} Closes an open image. \apiend \apiitem{int {\ce current_subimage} (void) const} Returns the index of the subimage that is currently being read. The first subimage (or the only subimage, if there is just one) is number 0. \apiend \apiitem{bool {\ce seek_subimage} (int subimage, int miplevel, ImageSpec \&newspec)} Seek to the given subimage and MIP-map level within the open image file. The first subimage in the file has index 0, and for each subimage, the highest-resolution MIP level has index 0. Return {\kw true} on success, {\kw false} on failure (including that there is not a subimage or MIP level with those indices). The new subimage's vital statistics are put in {\kw newspec} (and also saved internally in a way that can be retrieved via {\kw spec()}). The \ImageInput is expected to give the appearance of random access to subimages and MIP levels --- in other words, if it can't randomly seek to the given subimage or MIP level, it should transparently close, reopen, and sequentially read through prior subimages and levels. \apiend \apiitem{bool {\ce read_scanline} (int y, int z, TypeDesc format, void *data,\\ \bigspc\spc\spc stride_t xstride=AutoStride)} Read the scanline that includes pixels $(*,y,z)$ into {\kw data} ($z=0$ for non-volume images), converting if necessary from the native data format of the file into the {\kw format} specified. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data will be preserved in its native format (including per-channel formats, if applicable). The {\kw xstride} value gives the data spacing of adjacent pixels (in bytes). Strides set to the special value {\kw AutoStride} imply contiguous data, i.e., \\ \spc {\kw xstride} $=$ {\kw spec.nchannels * spec.pixel_size()} \\ The \ImageInput is expected to give the appearance of random access --- in other words, if it can't randomly seek to the given scanline, it should transparently close, reopen, and sequentially read through prior scanlines. The base \ImageInput class has a default implementation that calls {\kw read_native_scanline()} and then does appropriate format conversion, so there's no reason for each format plugin to override this method. \apiend \apiitem{bool {\ce read_scanline} (int y, int z, float *data)} This simplified version of {\kw read_scanline()} reads to contiguous float pixels. \apiend \apiitem{bool {\ce read_scanlines} (int ybegin, int yend, int z,\\ \bigspc TypeDesc format, void *data,\\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride) \\ bool {\ce read_scanlines} (int ybegin, int yend, int z,\\ \bigspc int chbegin, int chend, TypeDesc format, void *data,\\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride)} Read all the scanlines that include pixels $(*,y,z)$, where $\mathit{ybegin} \le y < \mathit{yend}$, into {\kw data}. This is essentially identical to \readscanline, except that can read more than one scanline at a time, which may be more efficient for certain image format readers. The version that specifies a channel range will read only channels $[${\cf chbegin},{\cf chend}$)$ into the buffer. \apiend \apiitem{bool {\ce read_tile} (int x, int y, int z, TypeDesc format, void *data, \\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride)} Read the tile whose upper-left origin is $(x,y,z)$ into {\kw data} ($z=0$ for non-volume images), converting if necessary from the native data format of the file into the {\kw format} specified. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data will be preserved in its native format (including per-channel formats, if applicable). The stride values give the data spacing of adjacent pixels, scanlines, and volumetric slices, respectively (measured in bytes). Strides set to the special value of {\kw AutoStride} imply contiguous data, i.e., \\ \spc {\kw xstride} $=$ {\kw spec.nchannels * spec.pixel_size()} \\ \spc {\kw ystride} $=$ {\kw xstride * spec.tile_width} \\ \spc {\kw zstride} $=$ {\kw ystride * spec.tile_height} \\ The \ImageInput is expected to give the appearance of random access --- in other words, if it can't randomly seek to the given tile, it should transparently close, reopen, and sequentially read through prior tiles. The base \ImageInput class has a default implementation that calls {\cf read_native_tile()} and then does appropriate format conversion, so there's no reason for each format plugin to override this method. This function returns {\cf true} if it successfully reads the tile, otherwise {\cf false} for a failure. The call will fail if the image is not tiled, or if $(x,y,z)$ is not actually a tile boundary. \apiend \apiitem{bool {\ce read_tile} (int x, int y, int z, float *data)} Simple version of {\kw read_tile} that reads to contiguous float pixels. \apiend \apiitem{bool {\ce read_tiles} (int xbegin, int xend, int ybegin, int yend, \\ \bigspc int zbegin, int zend, TypeDesc format, void *data, \\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride) \\ bool {\ce read_tiles} (int xbegin, int xend, int ybegin, int yend, \\ \bigspc int zbegin, int zend, int chbegin, int chend,\\ \bigspc TypeDesc format, void *data, \\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride)} Read the tiles bounded by {\kw xbegin} $\le x <$ {\kw xend}, {\kw ybegin} $\le y <$ {\kw yend}, {\kw zbegin} $\le z <$ {\kw zend} into {\kw data} converting if necessary from the file's native data format into the specified buffer {\kw format}. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data will be preserved in its native format (including per-channel formats, if applicable). The stride values give the data spacing of adjacent pixels, scanlines, and volumetric slices, respectively (measured in bytes). Strides set to the special value of {\kw AutoStride} imply contiguous data, i.e., \\ \spc {\kw xstride} $=$ {\kw spec.nchannels * spec.pixel_size()} \\ \spc {\kw ystride} $=$ {\kw xstride * spec.tile_width} \\ \spc {\kw zstride} $=$ {\kw ystride * spec.tile_height} \\ The \ImageInput is expected to give the appearance of random access --- in other words, if it can't randomly seek to the given tile, it should transparently close, reopen, and sequentially read through prior tiles. The base \ImageInput class has a default implementation that calls {\cf read_native_tiles()} and then does appropriate format conversion, so there's no reason for each format plugin to override this method. This function returns {\cf true} if it successfully reads the tiles, otherwise {\cf false} for a failure. The call will fail if the image is not tiled, or if the pixel ranges do not fall along tile (or image) boundaries, or if it is not a valid tile range. The version that specifies a channel range will read only channels $[${\cf chbegin},{\cf chend}$)$ into the buffer. \apiend \apiitem{bool {\ce read_image} (TypeDesc format, void *data, \\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride, \\ \bigspc ProgressCallback progress_callback=NULL,\\ \bigspc void *progress_callback_data=NULL)} Read the entire image of {\kw spec.width * spec.height * spec.depth} pixels into data (which must already be sized large enough for the entire image) with the given strides, converting into the desired data format. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data will be preserved in its native format (including per-channel formats, if applicable). This function will automatically handle either tiles or scanlines in the file. Strides set to the special value of {\kw AutoStride} imply contiguous data, i.e., \\ \spc {\kw xstride} $=$ {\kw spec.nchannels * pixel_size()} \\ \spc {\kw ystride} $=$ {\kw xstride * spec.width} \\ \spc {\kw zstride} $=$ {\kw ystride * spec.height} \\ The function will internally either call {\kw read_scanlines} or {\kw read_tiles}, depending on whether the file is scanline- or tile-oriented. Because this may be an expensive operation, a progres callback may be passed. Periodically, it will be called as follows:\\ \begin{code} progress_callback (progress_callback_data, float done) \end{code} \noindent where \emph{done} gives the portion of the image (between 0.0 and 1.0) that has been read thus far. \apiend \apiitem{bool {\ce read_image} (float *data)} Simple version of {\kw read_image()} reads to contiguous float pixels. \apiend \apiitem{bool {\ce read_native_scanline} (int y, int z, void *data)} The {\kw read_native_scanline()} function is just like {\kw read_scanline()}, except that it keeps the data in the native format of the disk file and always reads into contiguous memory (no strides). It's up to the user to have enough space allocated and know what to do with the data. IT IS EXPECTED THAT EACH FORMAT PLUGIN WILL OVERRIDE THIS METHOD. \apiend \apiitem{bool {\ce read_native_scanlines} (int ybegin, int yend, int z, void *data)} The {\kw read_native_scanlines()} function is just like {\cf read_native_scanline}, except that it reads a range of scanlines rather than only one scanline. It is not necessary for format plugins to override this method --- a default implementation in the \ImageInput base class simply calls {\cf read_native_scanline} for each scanline in the range. But format plugins may optionally override this method if there is a way to achieve higher performance by reading multiple scanlines at once. \apiend \apiitem{bool {\ce read_native_scanlines} (int ybegin, int yend, int z, \\ \bigspc int chbegin, int chend, void *data)} A variant of {\cf read_native_scanlines} that reads only a subset of channels \\ $[${\cf chbegin},{\cf chend}$)$. If a format reader subclass does not override this method, the default implementation will simply call the all-channel version of {\cf read_native_scanlines} into a temporary buffer and copy the subset of channels. \apiend \apiitem{bool {\ce read_native_tile} (int x, int y, int z, void *data)} The {\kw read_native_tile()} function is just like {\kw read_tile()}, except that it keeps the data in the native format of the disk file and always read into contiguous memory (no strides). It's up to the user to have enough space allocated and know what to do with the data. IT IS EXPECTED THAT EACH FORMAT PLUGIN WILL OVERRIDE THIS METHOD IF IT SUPPORTS TILED IMAGES. \apiend \apiitem{bool {\ce read_native_tiles} (int xbegin, int xend, int ybegin, int yend, \\ \bigspc int zbegin, int zend, void *data)} The {\kw read_native_tiles()} function is just like {\kw read_tiles()}, except that it keeps the data in the native format of the disk file and always read into contiguous memory (no strides). If a format reader does not override this method, the default implementation it will simply be a loop calling read_native_tile for each tile in the block. \apiend \apiitem{bool {\ce read_native_tiles} (int xbegin, int xend, int ybegin, int yend, \\ \bigspc int zbegin, int zend, int chbegin, int chend, void *data)} A variant of {\kw read_native_tiles()} that reads only a subset of channels \\ $[${\cf chbegin},{\cf chend}$)$. If a format reader subclass does not override this method, the default implementation will simply call the all-channel version of {\cf read_native_tiles} into a temporary buffer and copy the subset of channels. \apiend \apiitem{bool {\ce read_native_deep_scanlines} (int ybegin, int yend, int z, \\ \bigspc int chbegin, int chend, DeepData \&deepdata) \\ bool {\ce read_native_deep_tiles} (int xbegin, int xend, int ybegin, int yend, \\ \bigspc int zbegin, int zend, int chbegin, int chend, DeepData \&deepdata) \\ bool {\ce read_native_deep_image} (DeepData \&deepdata)} Read native deep data from scanlines, tiles, or an entire image, storing the results in {\cf deepdata} (analogously to the usual {\cf read_scanlines}, {\cf read_tiles}, and {\cf read_image}, but with deep data). Only channels $[${\cf chbegin},{\cf chend}$)$ will be read. \apiend \apiitem{int {\ce send_to_input} (const char *format, ...)} General message passing between client and image input server. This is currently undefined and is reserved for future use. \apiend \apiitem{int {\ce send_to_client} (const char *format, ...)} General message passing between client and image input server. This is currently undefined and is reserved for future use. \apiend \apiitem{std::string {\ce geterror} () const} \index{error checking} Returns the current error string describing what went wrong if any of the public methods returned {\kw false} indicating an error. (Hopefully the implementation plugin called {\kw error()} with a helpful error message.) \apiend \index{Image I/O API|)} \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/Makefile0000644000175000017500000000066112271062644017320 0ustar mfvmfvPDFLATEX := pdflatex -halt-on-error -interaction=errorstopmode # by default, just make the document all: openimageio.pdf # document making rule: use pdflatex openimageio.pdf: *.tex *.aux ${PDFLATEX} openimageio.tex # special command 'make index' to regenerate the index index: openimageio_index openimageio_index: ${PDFLATEX} openimageio.tex ${PDFLATEX} openimageio.tex makeindex openimageio ${PDFLATEX} openimageio.tex openimageio-1.3.12~dfsg0.orig/src/doc/imagebufalgo.tex0000644000175000017500000020357112271062644021031 0ustar mfvmfv\chapter{Image Processing} \label{chap:imagebufalgo} \index{Image Processing|(} \index{ImageBufAlgo|(} \section{ImageBufAlgo general principles} \label{sec:iba:intro} \IBA is a set of image processing functions that operate on \ImageBuf's. The functions are declared in the header file {\cf OpenImageIO/imagebufalgo.h} and are declared in the {\cf namespace ImageBufAlgo}. \subsubsection*{Return values and error messages} All \IBA functions return a {\cf bool} that is {\cf true} if the function succeeds, {\cf false} if the function fails. Upon failure, the \emph{destination} \ImageBuf (the one that is being altered) will have an error message set. Below is an example: \begin{code} ImageBuf src ("input.exr"); ImageBuf dst; // will be the output image ... bool ok = ImageBufAlgo::crop (dst, src); if (! ok) { std::string err = dst.gas_error() ? dst.geterror() : "unknown"; std::cout << "crop error: " << err << "\n"; } \end{code} For a small minority of \IBA functions, there are only input images, and no image outputs (e.g., {\cf isMonochrome()}). In such cases, the error message should be retrieved from the first input image. \subsubsection*{Region of interest} Most \IBA functions take a destination (output) \ImageBuf and one or more source (input) \ImageBuf's. The destination \ImageBuf may or may not already be initialized (allocated and having existing pixel values). A few \IBA functions take only a single \ImageBuf parameter, which is altered in-place (and must already be initialized prior to the function call). All \IBA functions take an optional \ROI parameter describing which subset of the image should be altered. The default value of the \ROI parameter is an ``undefined'' \ROI If the destination \ImageBuf is already initialized, then the operation will be performed on the pixels in the destination that overlap the \ROI, leaving pixels in the destination which are outside the \ROI unaltered. If the \ROI is also undefined, the operation will be performed on the entire destination image. If the destination \ImageBuf is uninitialized, it will be initialized/allocated to be the size of the \ROI. If the \ROI itself is undefined, it will be set to the union of the defined pixel regions of all the input images. The usual way to use \IBA functions is to have an uninitialized destination image, and pass {\cf ROI::All()} (which is a synonym for an undefined \ROI) for the region of interest. Most \IBA functions also respect the {\cf chbegin} and {\cf chend} members of the \ROI, thus restricting the channel range on which the operation is performed. The default \ROI constructor sets up the \ROI to specify that the operation should be performed on all channels of the input image(s). \subsubsection*{Multithreading} All \IBA functions take an optional {\cf nthreads} parameter that signifies the maximum number of threads to use to parallelize the operation. The default value for {\cf nthreads} is 0, which signifies that the number of thread should be the OIIO global default set by {\cf OIIO::attribute()} (see Section~\ref{sec:attribute:threads}), which itself defaults to be the detected level of hardware concurrency (number of cores available). Generally you can ignore this parameter (or pass 0), meaning to use all the cores available in order to perform the computation as quickly as possible. The main reason to explicitly pass a different number (generally 1) is if the application is multithreaded at a high level, and the thread calling the \IBA function just wants to continue doing the computation without spawning additional threads, which might tend to crowd out the other application threads. \section{Pattern generation} \label{sec:iba:patterns} \apiitem{bool zero (ImageBuf \&dst, ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!zero} \indexapi{zero} Set the destination image pixels to 0 within the specified region. This operation is performed in-place. The {\cf dst} buffer needs to already be an initialized \ImageBuf, otherwise there's no way to know how big to make it or what data type it should have. \smallskip \noindent Examples: \begin{code} ImageBuf dst ("myfile.exr"); ... // Zero out whole buffer, keeping it the same size ImageBufAlgo::zero (dst); // Zero out just a rectangle in the upper left corner ImageBufAlgo::zero (dst, ROI (0, 100, 0, 100)); // Zero out just the green channel, leave everything else the same ROI roi = dst.roi (); roi.chbegin = 1; // green roi.chend = 2; // one past the end of the channel region ImageBufAlgo::zero (dst, roi); \end{code} \apiend \apiitem{bool fill (ImageBuf \&dst, const float *values, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!fill} \indexapi{fill} Set the pixels in the destination image within the specified region to the values in {\cf values[]}. The {\cf values} array must point to at least {\cf chend} values, or the number of channels in the image, whichever is smaller. \smallskip \noindent Examples: \begin{code} // Create a new 640x480 RGB image, fill it with pink ImageBuf A ("myimage", ImageSpec(640, 480, 3, TypeDesc::FLOAT); float pink[3] = { 1, 0.5, 0.5 }; ImageBufAlgo::fill (A, pink); // Draw a red rectangle float red[3] = { 1, 0, 0 }; ImageBufAlgo::fill (A, red, ROI(50,100, 75, 85)); \end{code} \apiend \apiitem{bool checker (ImageBuf \&dst, float width, float height, float depth, \\ \bigspc const float *color1, const float *color2, \\ \bigspc int xoffset=0, int yoffset=0, int zoffset=0, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!checker} \indexapi{checker} Set the pixels in the destination image within the specified region to a checkerboard pattern with origin given by the {\cf offset} values, checker size given by the {\cf width, height, depth} values, and alternting between {\cf color1[]} and {\cf color2[]}. The colors must point to arrays long enough to contain values for all channels in the image. \smallskip \noindent Examples: \begin{code} // Create a new 640x480 RGB image, fill it with a two-toned gray // checkerboard, the checkers being 64x64 pixels each. ImageBuf A (ImageSpec(640, 480, 3, TypeDesc::FLOAT); float dark[3] = { 0.1, 0.1, 0.1 }; float light[3] = { 0.4, 0.4, 0.4 }; ImageBufAlgo::checker (A, 64, 64, 1, dark, light, 0, 0, 0); \end{code} \apiend \apiitem{bool render_text (ImageBuf \&dst, int x, int y, \\ \bigspc const std::string \&text, int fontsize=16, \\ \bigspc const std::string \&fontname="", \\ \bigspc const float *textcolor = NULL)} \index{ImageBufAlgo!render_text} \indexapi{render_text} Render a text string into the destination, essentially doing an ``over'' of the antialiased character into the existing pixel data. The baseline of the first character will start at position ({\cf x, y}). The font is given by {\cf fontname} as a full pathname to the font file (defaulting to some reasonable system font if not supplied at all), and with a nominal height of {\cf fontsize} (in pixels). The characters will be drawn in opaque white (1.0 in all channels), unless {\cf textcolor} is supplied (and is expected to point to a {\cf float} array of length at least equal to the number of channels in {\cf dst}). \smallskip \noindent Examples: \begin{code} ImageBuf A (ImageSpec (640, 480, 4, TypeDesc::FLOAT)); ImageBufAlgo::render_text (A, 50, 100, "Hello, world"); float red[] = { 1, 0, 0, 1 }; ImageBufAlgo::render_text (A, 100, 200, "Go Big Red!", 60, "Arial Bold", red); \end{code} \apiend \section{Image transformations and data movement} \label{sec:iba:transforms} \apiitem{bool channels (ImageBuf \&dst, const ImageBuf \&src, int nchannels, \\ \bigspc const int *channelorder, const float *channelvalues=NULL, \\ \bigspc const std::string *newchannelnames=NULL, \\ \bigspc bool shuffle_channel_names=false)} \index{ImageBufAlgo!channels} \indexapi{channels} Generic channel shuffling: copy {\cf src} to {\cf dst}, but with channels in the order specified by {\cf channelorder[0..nchannels-1]}. Does not support in-place operation. For any channel in which {\cf channelorder[i]} $< 0$, it will just make {\cf dst} channel {\cf i} be a constant value set to {\cf channelvalues[i]} (if {\cf channelvalues} is not \NULL) or {\cf 0.0} (if {\cf channelvalues} is \NULL). If {\cf channelorder} is \NULL, it will be interpreted as {\cf \{0, 1, ..., nchannels-1\}}, meaning that it's only renaming channels, not reordering them. If {\cf newchannelnames} is not \NULL, it points to an array of new channel names. Channels for which {\cf newchannelnames[i]} is the empty string (or all channels, if {\cf newchannelnames == NULL}) will be named as follows: If {\cf shuffle_channel_names} is {\cf false}, the resulting dst image will have default channel names in the usual order (\qkw{R}, \qkw{G}, etc.), but if {\cf shuffle_channel_names} is {\cf true}, the names will be taken from the corresponding channels of the source image -- be careful with this, shuffling both channel ordering and their names could result in no semantic change at all, if you catch the drift. \smallskip \noindent Examples: \begin{code} // Copy the first 3 channels of an RGBA, drop the alpha ImageBuf RGBA (...); // assume it's initialized, 4 chans ImageBuf RGB; ImageBufAlgo::channels (RGB, RGBA, 3, NULL /*default ordering*/); // Copy just the alpha channel, making a 1-channel image ImageBuf Alpha; int alpha_channel[] = { 3 /* alpha channel */ }; ImageBufAlgo::channels (Alpha, RGBA, 1, &alpha_channel); // Swap the R and B channels ImageBuf BRGA; int channelorder[] = { 2 /*B*/, 1 /*G*/, 0 /*R*/, 3 /*A*/ }; ImageBufAlgo::channels (BRGA, RGBA, 4, &channelorder); // Add an alpha channel with value 1.0 everywhere to an RGB image, // keep the other channels with their old ordering, values, and // names. int channelorder[] = { 0, 1, 2, -1 /*use a float value*/ }; float channelvalues[] = { 0 /*ignore*/, 0 /*ignore*/, 0 /*ignore*/, 1.0 }; std::string channelnames[] = { "", "", "", "A" }; ImageBufAlgo::channels (RGBA, RGB, 4, channelorder, channelvalues, channelnames); \end{code} \apiend \apiitem{bool channel_append (ImageBuf \&dst, const ImageBuf \&A, const ImageBuf \&B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!channel_append} \indexapi{channel_append} Append the channels of {\cf A} and {\cf B} together into {\cf dst} over the region of interest. If the region passed is uninitialized (the default), it will be interpreted as being the union of the pixel windows of {\cf A} and {\cf B} (and all channels of both images). If {\cf dst} is not already initialized, it will be resized to be big enough for the region. \smallskip \noindent Examples: \begin{code} ImageBuf RGBA (...); // assume initialized, 4 channels ImageBuf Z (...); // assume initialized, 1 channel ImageBuf RGBAZ; ImageBufAlgo::channel_append (RGBAZ, RGBA, Z); \end{code} \apiend \apiitem{bool {\ce flatten} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!flatten} \indexapi{flatten} \index{deep images} \NEW % 1.3 Copy pixels from \emph{deep} image {\cf src} into non-deep {\cf dst}, compositing the depth samples within each pixel to yield a single ``flat'' value per pixel. If {\cf src} is not deep, it just copies the pixels without alteration. \smallskip \noindent Examples: \begin{code} ImageBuf Deep ("deepalpha.exr"); ImageBuf Flat; ImageBufAlgo::flatten (Flat, Deep); \end{code} \apiend \apiitem{bool crop (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!crop} \indexapi{crop} Reset {\cf dst} to be the specified region of {\cf src}. \smallskip \noindent Examples: \begin{code} // Set B to be the upper left 200x100 region of A ImageBuf A (...); // Assume initialized ImageBuf B; ImageBufAlgo::crop (B, A, ROI(0,200,0,100)); \end{code} \apiend \apiitem{bool paste (ImageBuf \&dst, int xbegin, int ybegin, int zbegin, int chbegin, \\ \bigspc const ImageBuf \&src, ROI srcroi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!paste} \indexapi{paste} Copy into {\cf dst}, beginning at {\cf (xbegin, ybegin, zbegin)}, the pixels of {\cf src} described by {\cf srcroi}. If {\cf srcroi} is {\cf ROI::All()}, the entirety of src will be used. It will copy into channels {\cf [chbegin...]}, as many channels as are described by {\cf srcroi}. \smallskip \noindent Examples: \begin{code} // Paste small.exr on top of big.exr at offset (100,100) ImageBuf Big ("big.exr"); ImageBuf Small ("small.exr"); ImageBufAlgo::paste (Big, 100, 100, 0, 0, Small); \end{code} \apiend \apiitem{bool {\ce flip} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!flip} \indexapi{flip} Copy {\cf src} (or a subregion of {\cf src}) to the corresponding pixels of {\cf dst}, but with the scanlines exchanged vertically. \smallskip \noindent Examples: \begin{code} ImageBuf A ("tahoe.exr"); ImageBuf B; ImageBufAlgo::flip (B, A); \end{code} \apiend \apiitem{bool {\ce flop} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!flop} \indexapi{flop} Copy {\cf src} (or a subregion of {\cf src}) to the corresponding pixels of {\cf dst}, but with the columns exchanged horizontally. \smallskip \noindent Examples: \begin{code} ImageBuf A ("tahoe.exr"); ImageBuf B; ImageBufAlgo::flop (B, A); \end{code} \apiend \apiitem{bool {\ce flipflop} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!flipflop} \indexapi{flipflop} Copy {\cf src} (or a subregion of {\cf src} to the corresponding pixels of {\cf dst}, but with both the rows exchanged vertically and the columns exchanged horizontally (this is equivalent to a 180 degree rotation). \smallskip \noindent Examples: \begin{code} ImageBuf A ("tahoe.exr"); ImageBuf B; ImageBufAlgo::flipflop (B, A); \end{code} \apiend \apiitem{bool {\ce transpose} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!transpose} \indexapi{transpose} Copy {\cf src} (or a subregion of {\cf src} to the corresponding transposed ($x \leftrightarrow y$) pixels of {\cf dst}. In other words, for all $(x,y)$ within the region, set {\cf dst[y,x] = src[x,y]}. \smallskip \noindent Examples: \begin{code} ImageBuf A ("tahoe.exr"); ImageBuf B; ImageBufAlgo::transpose (B, A); \end{code} \apiend \apiitem{bool {\ce circular_shift} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc int xshift, int yshift, int zshift=0, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!circular_shift} \indexapi{circular_shift} Copy {\cf src} (or a subregion of {\cf src} to the pixels of {\cf dst}, but circularly shifting by the given amount. To clarify, the circular shift of $[0,1,2,3,4,5]$ by $+2$ is $[4,5,0,1,2,3]$. \smallskip \noindent Examples: \begin{code} ImageBuf A ("tahoe.exr"); ImageBuf B; ImageBufAlgo::circular_shift (B, A, 200, 100); \end{code} \apiend \apiitem{bool {\ce resize} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc const std::string filtername="", float filtersize=0, \\ \bigspc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce resize} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc Filter2D *filter, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!resize} \indexapi{resize} Set {\cf dst}, over the region of interest, to be a resized version of the corresponding portion of {\cf src} (mapping such that the ``full'' image window of each correspond to each other, regardless of resolution). If {\cf dst} is not yet initialized, it will be sized according to {\cf roi}. The caller may explicitly pass a reconstruction filter, or specify one by name and size, or if the name is the empty string {\cf resize()} will choose a reasonable high-quality default if \NULL is passed. The filter is used to weight the {\cf src} pixels falling underneath it for each {\cf dst} pixel; the filter's size is expressed in pixel units of the dst image. \smallskip \noindent Examples: \begin{code} // Resize the image to 640x480, using the default filter ImageBuf Src ("tahoe.exr"); ImageBuf Dst; ROI roi (0, 640, 0, 480, 0, 1, /*chans:*/ 0, Src.nchannels()); ImageBufAlgo::resize (Dst, Src, "", 0, roi); \end{code} \apiend \apiitem{bool {\ce resample} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc bool interpolate = true, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!resample} \indexapi{resample} Set {\cf dst}, over the region of interest, to be a resized version of the corresponding portion of {\cf src} (mapping such that the ``full'' image window of each correspond to each other, regardless of resolution). If {\cf dst} is not yet initialized, it will be sized according to {\cf roi}. Unlike {\cf ImageBufAlgo::resize()}, {\cf resample()} does not take a filter; it just samples either with a bilinear interpolation (if {\cf interpolate} is {\cf true}, the default) or uses the single ``closest'' pixel (if {\cf interpolate} is {\cf false}). This makes it a lot faster than a proper {\cf resize()}, though obviously with lower quality (aliasing when downsizing, pixel replication when upsizing). \smallskip \noindent Examples: \begin{code} // Resample quickly to 320x240, using the default filter ImageBuf Src ("tahoe.exr"); ImageBuf Dst; ROI roi (0, 320, 0, 240, 0, 1, /*chans:*/ 0, Src.nchannels()); ImageBufAlgo::resample (Dst, Src, NULL, roi); \end{code} \apiend \section{Image arithmetic} \label{sec:iba:arith} \apiitem{bool {\ce add} (ImageBuf \&dst, const ImageBuf \&A, const ImageBuf \&B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce add} (ImageBuf \&dst, const ImageBuf \&A, float B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce add} (ImageBuf \&dst, const ImageBuf \&A, const float *B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!add} \indexapi{add} For all pixels and channels within the designated region, set {\cf dst} to the sum of image {\cf A} and {\cf B}. {\cf B} is either an image, a float (added to all channels) or a per-channel float array. All of the images must have the same number of channels. \smallskip \noindent Examples: \begin{code} // Add images A and B, assign to Sum ImageBuf A ("a.exr"); ImageBuf B ("b.exr"); ImageBuf Sum; ImageBufAlgo::add (Sum, A, B); // Add 0.2 to channels 0-2 of A ImageBuf A ("a.exr"), Sum; ROI roi = get_roi (A.spec()); roi.chbegin = 0; roi.chend = 3; ImageBufAlgo::add (Sum, A, 0.2, roi); \end{code} \apiend \apiitem{bool sub (ImageBuf \&dst, const ImageBuf \&A, const ImageBuf \&B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce sub} (ImageBuf \&dst, const ImageBuf \&A, float B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce sub} (ImageBuf \&dst, const ImageBuf \&A, const float *B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!sub} \indexapi{sub} For all pixels within the designated region, subtract {\cf B} from {\cf A}, putting the results into {\cf dst}. {\cf B} is either an image, a float (added to all channels) or a per-channel float array. All of the images must have the same number of channels. \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); ImageBuf B ("b.exr"); ImageBuf Difference; ImageBufAlgo::sub (Difference, A, B); \end{code} \apiend \apiitem{bool {\ce mul} (ImageBuf \&dst, const ImageBuf \&A, const ImageBuf \&B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce mul} (ImageBuf \&dst, const ImageBuf \&A, float B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce mul} (ImageBuf \&dst, const ImageBuf \&A, const float *B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!mul} \indexapi{mul} For all pixels within the designated region, multiply the pixel values of image {\cf A} by {\cf B} (channel by channel), putting the product in {\cf dst}. {\cf B} is either an image, a float (added to all channels) or a per-channel float array. All of the images must have the same number of channels. \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); ImageBuf B ("b.exr"); ImageBuf Product; ImageBufAlgo::mul (Product, A, B); // Reduce intensity of A's channels 0-2 by 50% ROI roi = get_roi (A.spec()); roi.chbegin = 0; roi.chend = 3; ImageBufAlgo::mul (A, A, 0.5, roi); \end{code} \apiend \apiitem{bool {\ce channel_sum} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc\spc const float *weights=NULL, \\ \bigspc\spc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!channel_sum} \indexapi{channel_sum} Converts a multi-channel image into a 1-channel image via a weighted sum of channels. For each pixel of {\cf src} within the designated ROI (defaulting to all of {\cf src}, if not defined), sum the channels designated by {\cf roi} and store the result in channel 0 of {\cf dst}. If {\cf weights} is not \NULL, {\cf weight[i]} will provide a per-channel weight (rather than defaulting to 1.0 for each channel). \smallskip \noindent Examples: \begin{code} // Compute luminance via a weighted sum of R,G,B // (assuming Rec709 primaries and a linear scale) float luma_weights[3] = { .2126, .7152, .0722 }; ImageBuf A ("a.exr"); ImageBuf B; ROI roi = A.roi(); roi.chbegin = 0; roi.chend = 3; ImageBufAlgo::channel_sum (B, A, luma_weights, roi); \end{code} \apiend \apiitem{bool {\ce clamp} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc float min = -std::numeric_limits::max(), \\ \bigspc float max = std::numeric_limits::max(), \\ \bigspc bool clampalpha01 = false, ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce clamp} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc const float *min = NULL, const float *max = NULL, \\ \bigspc bool clampalpha01 = false, ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!clamp} \indexapi{clamp} Copy pixels from {\cf src} to {\cf src} (within the {\cf roi}), clamping between the {\cf min} and {\cf max} values. Additionally, if {\cf clampalpha01} is {\cf true}, then any alpha channel is clamped to the 0--1 range. For the variety of {\cf clamp()} in which the {\cf min} and {\cf max} values are {\cf float}, the minimum and maximum will be applied to all color channels (or, at least, the subset of channels specified by {\cf roi}). For the variety of {\cf clamp()} in which the {\cf min} and {\cf max} parameters are pointers, they point to arrays giving per-channel minimum and maximum clamp values. If {\cf min} is \NULL, no minimum clamping is performed, and if {\cf max} is \NULL, no maximum clamping is performed. \smallskip \noindent Examples: \begin{code} // Clamp image buffer A in-place to the [0,1] range for all pixels. ImageBufAlgo::clamp (A, A, 0.0f, 1.0f); // Just clamp alpha to [0,1] ImageBufAlgo::clamp (A, A, -std::numeric_limits::max(), std::numeric_limits::max(), true); // Clamp R & G to [0,0.5], leave other channels alone std::vector min (A.nchannels(), -std::numeric_limits::max()); std::vector max (A.nchannels(), std::numeric_limits::max()); min[0] = 0.0f; max[0] = 0.5f; min[1] = 0.0f; max[1] = 0.5f; ImageBufAlgo::clamp (A, A, &min[0], &max[0], false); \end{code} \apiend \apiitem{bool {\ce rangecompress} (ImageBuf \&dst, const ImageBuf \&src, bool useluma = false, \\ \bigspc\bigspc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce rangeexpand} (ImageBuf \&dst, const ImageBuf \&src, bool useluma = false, \\ \bigspc\bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!rangecompress} \indexapi{rangecompress} \index{ImageBufAlgo!rangeexpand} \indexapi{rangeexpand} Some image operations (such as resizing with a ``good'' filter that contains negative lobes) can have objectionable artifacts when applied to images with very high-contrast regions involving extra bright pixels (such as highlights in HDR captured or rendered images). One way to address this is by compressing the range of pixel values, then performing the operation (such as a resize), then re-expanding the range of the result again. This approach can yield results that are much more pleasing (even if not exactly mathematically correct). The {\cf rangecompress} operation does the following: For all pixels and color channels of {\cf src} within region {\cf roi} (defaulting to all the defined pixels of {\cf src}), copy the pixels to {\cf dst} while applying a logarithmic transformation on their values. Alpha and z channels are copied but not transformed. The {\cf rangeexpand} operation is the opposite of {\cf rangecompress}: it copies while rescaling the logarithmic color channel values back to a linear response. If {\cf useluma} is true, the luma of the first three channels (presumed to be R, G, and B) are used to compute a single scale factor for all color channels, rather than scaling all channels individually (which could result in a big color shift when performing {\cf rangecompress} and {\cf rangeexpand}). \smallskip \noindent Examples: \begin{code} // Resize the image to 640x480, using a Lanczos3 filter, which // has negative lobes. To prevent those negative lobes from // producing ringing or negative pixel values for HDR data, // do range compression, then resize, then re-expand the range. // 1. Read the original image ImageBuf Src ("tahoeHDR.exr"); // 2. Range compress to a logarithmic scale ImageBuf Compressed; ImageBufAlgo::rangecompress (Compressed, Src); // 3. Now do the resize ImageBuf Dst; ROI roi (0, 640, 0, 480, 0, 1, /*chans:*/ 0, Compressed.nchannels()); ImageBufAlgo::resize (Dst, Comrpessed, "lanczos3", 6.0, roi); // 4. Expand range to be linear again (operate in-place) ImageBufAlgo::rangeexpand (Dst, Dst); \end{code} \apiend \apiitem{bool {\ce over} (ImageBuf \&dst, const ImageBuf \&A, const ImageBuf \&B, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!over} \indexapi{over} For all pixels within the designated region, combine the pixels of images {\cf A} and {\cf B} using the Porter-Duff ``over'' compositing operation, putting the result in {\cf dst}. Image {\cf A} is the ``foreground,'' and {\cf B} is the ``background.'' Images {\cf A} and {\cf B} must have the same number of channels and must both have an alpha channel. \smallskip \noindent Examples: \begin{code} ImageBuf A ("fg.exr"); ImageBuf B ("bg.exr"); ImageBuf Composite; ImageBufAlgo::over (Composite, A, B); \end{code} \apiend \apiitem{bool {\ce zover} (ImageBuf \&dst, const ImageBuf \&A, const ImageBuf \&B, \\ \bigspc bool z_zeroisinf = false, ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!zover} \indexapi{zover} For all pixels within the designated region, combine the pixels of images {\cf A} and {\cf B} using the Porter-Duff ``over'' compositing operation, putting the result in {\cf dst}. {\cf A} and {\cf B} must have the same number of channels and must both alpha and $z$ (depth) channels. Rather than {\cf A} always being the foreground (as it would be for the {\cf over()} function, the $z$ channel is used to select which image is foreground and which is background for each pixel separately, with a lower $z$ value being the foreground for that pixel. If {\cf z_zeroisinf} is {\cf true}, then $z=0$ values will be treated as if they are infinitely far away. \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); ImageBuf B ("b.exr"); ImageBuf Composite; ImageBufAlgo::zover (Composite, A, B); \end{code} \apiend \section{Image comparison and statistics} \label{sec:iba:stats} \apiitem{bool {\ce computePixelStats} (PixelStats \&stats, const ImageBuf \&src, \\ \bigspc\bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!computePixelStats} \indexapi{computePixelStats} Compute statistics about the ROI of the image {\cf src}, storing results in {\cf stats} (each of the vectors within {\cf stats} will be automatically resized to the number of channels in the image). A return value of {\cf true} indicates success, {\cf false} indicates that it was not possible to complete the operation. The {\cf PixelStats} structure is defined as follows: \begin{code} struct PixelStats { std::vector min; std::vector max; std::vector avg; std::vector stddev; std::vector nancount; std::vector infcount; std::vector finitecount; std::vector sum, sum2; // for intermediate calculation }; \end{code} \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); ImageBufAlgo::PixelStats stats; ImageBufAlgo::computePixelStats (stats, A); for (int c = 0; c < A.nchannels(); ++c) { std::cout << "Channel " << c << ":\n"; std::cout << " min = " << stats.min[c] << "\n"; std::cout << " max = " << stats.max[c] << "\n"; std::cout << " average = " << stats.avg[c] << "\n"; std::cout << " standard deviation = " << stats.stddev[c] << "\n"; std::cout << " # NaN values = " << stats.nancount[c] << "\n"; std::cout << " # Inf values = " << stats.infcount[c] << "\n"; std::cout << " # finite values = " << stats.finitecount[c] << "\n"; } \end{code} \apiend \apiitem{bool {\ce compare} (const ImageBuf \&A, const ImageBuf \&B, \\ \bigspc float failthresh, float warnthresh, CompareResults \&result,\\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!compare} \indexapi{compare} Numerically compare two images. The difference threshold (for any individual color channel in any pixel) for a ``failure'' is {\cf failthresh}, and for a ``warning'' is {\cf warnthresh}. The results are stored in {\cf result}. If {\cf roi} is defined, pixels will be compared for the pixel and channel range that is specified. If {\cf roi} is not defined, the comparison will be for all channels, on the union of the defined pixel windows of the two images (for either image, undefined pixels will be assumed to be black). The {\cf CompareResults} structure is defined as follows: \begin{code} struct CompareResults { double meanerror, rms_error, PSNR, maxerror; int maxx, maxy, maxz, maxc; imagesize_t nwarn, nfail; }; \end{code} \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); ImageBuf B ("b.exr"); ImageBufAlgo::CompareResults comp; ImageBufAlgo::compare (A, B, 1.0f/255.0f, 0.0f, comp); if (comp.nwarn == 0 && comp.nfail == 0) { std::cout << "Images match within tolerance\n"; } else { std::cout << "Image differed: " << comp.nfail << " failures, " << comp.nwarn << " warnings.\n"; std::cout << "Average error was " << comp.meanerror << "\n"; std::cout << "RMS error was " << comp.rms_error << "\n"; std::cout << "PSNR was " << comp.PSNR << "\n"; std::cout << "largest error was " << comp.maxerror << " on pixel (" << comp.maxx << "," << comp.maxy << "," << comp.maxz << "), channel " << comp.maxc << "\n"; } \end{code} \apiend \begin{comment} compare_Yee is a bit half-baked. Leave it out of the docs for now. FIXME \apiitem{int {\ce compare_Yee} (const ImageBuf \&A, const ImageBuf \&B, \\ \bigspc CompareResults \&result, float luminance, float fov, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!compare_Yee} \indexapi{compare_Yee} \apiend \end{comment} \apiitem{bool {\ce isConstantColor} (const ImageBuf \&src, float *color, \\ \bigspc\bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!isConstantColor} \indexapi{isConstantColor} If all pixels of {\cf src} within the ROI have the same values (for the subset of channels described by {\cf roi}), return {\cf true} and store the values in {\cf color[roi.chbegin...roi.chend-1]}. Otherwise, return {\cf false}. \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); std::vector color (A.nchannels()); if (ImageBufAlgo::isConstantColor (A, &color[0])) { std::cout << "The image has the same value in all pixels: "; for (int c = 0; c < A.nchannels(); ++c) std::cout << (c ? " " : "") << color[c]; std::cout << "\n"; } else { std::cout << "The image is not a solid color.\n"; } \end{code} \apiend \apiitem{bool {\ce isConstantChannel} (const ImageBuf \&src, int channel, float val, \\ \bigspc\bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!isConstantChannel} \indexapi{isConstantChannel} Returns {\cf true} if all pixels of {\cf src} within the ROI have the given {\cf channel} value {\cf val}. \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); int alpha = A.spec().alpha_channel; if (alpha < 0) std::cout << "The image does not have an alpha channel\n"; else if (ImageBufAlgo::isConstantChannel (A, alpha, 1.0f)) std::cout << "The image has alpha = 1.0 everywhere\n"; else std::cout << "The image has alpha < 1 in at least one pixel\n"; \end{code} \apiend \apiitem{bool {\ce isMonochrome} (const ImageBuf \&src, ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!isMonochrome} \indexapi{isMonochrome} Returns {\cf true} if the image is monochrome within the ROI, that is, for all pixels within the region, do all channels {\cf [roi.chbegin, roi.chend)} have the same value? If roi is not defined (the default), it will be understood to be all of the defined pixels and channels of source. \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); ROI roi = get_roi (A.spec()); roi.chend = std::min (3, roi.chend); // only test RGB, not alpha if (ImageBufAlgo::isMonochrome (A, roi)) std::cout << "a.exr is really grayscale\n"; \end{code} \apiend \apiitem{bool {\ce color_count} (const ImageBuf \&src, imagesize_t *count,\\ \bigspc int ncolors, const float *color, const float *eps=NULL, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!color_count} \indexapi{color_count} Count how many pixels in the image (within the ROI) match a list of colors. The colors to match are in: \begin{code} colors[0 ... nchans-1] colors[nchans ... 2*nchans-1] ... colors[(ncolors-1)*nchans ... (ncolors*nchans)-1] \end{code} \noindent and so on, a total of {\cf ncolors} consecutively stored colors of {\cf nchans} channels each ({\cf nchans} is the number of channels in the image, itself, it is not passed as a parameter). The values in {\cf eps[0..nchans-1]} are the error tolerances for a match, for each channel. Setting {\cf eps[c]} to {\cf numeric_limits::max()} will effectively make it ignore the channel. Passing {\cf eps == NULL} will be interpreted as a tolerance of 0.001 for all channels (requires exact matches for 8 bit images, but allows a wee bit of imprecision for {\cf float} images. \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); int n = A.nchannels(); // Try to match two colors: pure red and green std::vector colors (2*n, numeric_limits::max()); colors[0] = 1.0f; colors[1] = 0.0f; colors[2] = 0.0f; colors[n+0] = 0.0f; colors[n+1] = 1.0f; colors[n+2] = 0.0f; const int ncolors = 2; imagesize_t count[ncolors]; ImageBufAlgo::color_count (A, count, ncolors); std::cout << "Number of red pixels : " << count[0] << "\n"; std::cout << "Number of green pixels : " << count[1] << "\n"; \end{code} \apiend \apiitem{bool {\ce color_range_check} (const ImageBuf \&src, imagesize_t *lowcount, \\ \bigspc imagesize_t *highcount, imagesize_t *inrangecount, \\ \bigspc const float *low, const float *high, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!color_range_check} \indexapi{color_range_check} Count how many pixels in the image (within the ROI) are outside the value range described by {\cf low[roi.chbegin..roi.chend-1]} and {\cf high[roi.chbegin..roi.chend-1]} as the low and high acceptable values for each color channel. The number of pixels containing values that fall below the lower bound will be stored in {\cf *lowcount}, the number of pixels containing values that fall above the upper bound will be stored in {\cf *highcount}, and the number of pixels for which all channels fell within the bounds will be stored in {\cf *inrangecount}. Any of these may be NULL, which simply means that the counts need not be collected or stored. \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); ROI roi = get_roi (A.spec()); roi.chend = std::min (roi.chend, 4); // only compare RGBA float low[] = {0, 0, 0, 0}; float high[] = {1, 1, 1, 1}; imagesize_t lowcount, highcount, inrangecount; ImageBufAlgo::color_range_check (A, &lowcount, &highcount, &inrangecount, low, high, roi); std::cout << lowcount << " pixels had components < 0\n"; std::cout << highcount << " pixels had components > 1\n"; std::cout << inrangecount << " pixels were fully within [0,1] range\n"; \end{code} \apiend \apiitem{std::string {\ce computePixelHashSHA1} (const ImageBuf \&src, \\ \bigspc\bigspc const std::string \&extrainfo = "", \\ \bigspc\bigspc ROI roi=ROI::All(), int blocksize=0, int nthreads=0)} \index{ImageBufAlgo!computePixelHashSHA1} \indexapi{computePixelHashSHA1} Compute the SHA-1 byte hash for all the pixels in the specifed region of the image. If {\cf blocksize} $> 0$, the function will compute separate SHA-1 hashes of each {\cf blocksize} batch of scanlines, then return a hash of the individual hashes. This is just as strong a hash, but will NOT match a single hash of the entire image ({\cf blocksize == 0}). But by breaking up the hash into independent blocks, we can parallelize across multiple threads, given by {\cf nthreads}. The {\cf extrainfo} provides additional text that will be incorporated into the hash. \smallskip \noindent Examples: \begin{code} ImageBuf A ("a.exr"); std::string hash; hash = ImageBufAlgo::computePixelHashSHA1 (A, "", ROI::All(), 64); \end{code} \apiend \apiitem{bool {\ce histogram} (const ImageBuf \&src, int channel, \\ \bigspc std::vector \&histogram, int bins=256, \\ \bigspc float min=0, float max=1, imagesize_t *submin=NULL, \\ \bigspc imagesize_t *supermax=NULL, ROI roi=ROI::All())} \index{ImageBufAlgo!histogram} \indexapi{histogram} Computes a histogram of the given {\cf channel} of image {\cf src}, within the ROI, as follows: The vector {\cf histogram[0..bins-1]} will contain the count of pixels whose value was in each of the equally-sized range bins between {\cf min} and {\cf max}; if {\cf submin} is not \NULL, it specifies storage of the number of pixels whose value was $<$ {\cf min}; if {\cf supermax} is not \NULL, it specifies storage of the number of pixels whose value was $>$ {\cf max}. \smallskip \noindent Examples: \begin{code} ImageBuf Src ("tahoe.exr"); const int bins = 4; std::vector hist (bins, 0); imagesize_t submin=0, supermax=0; ImageBufAlgo::histogram (Src, 0, hist, bins, 0.0f, 1.0f, &submin, &supermax); std::cout << "Channel 0 of the image had:\n"; float binsize = (max-min)/nbins; for (int i = 0; i < nbins; ++i) hist[i] << " pixels that are >= " << (min+i*binsize) << " and " << (i == nbins-1 ? "<= " : "< ") << (min+(i+1)*binsize) << "\n"; std::cout << submin << " pixels < " << min << "\n"; std::cout << supermax << " pixels > " << max << "\n"; \end{code} \apiend \begin{comment} % I'm not documenting histogram_draw at this point because as I started % writing this section, I realized I really don't like this function % as it is written and would like to rewrite its specification when I % get the chance. \apiitem{bool {\ce histogram_draw} (ImageBuf \&dst, \bigspc const std::vector \&histogram)} \index{ImageBufAlgo!histogram_draw} \indexapi{histogram_draw} \smallskip \noindent Examples: \begin{code} \end{code} \apiend \end{comment} \section{Convolutions} \label{sec:iba:convolutions} \apiitem{bool {\ce make_kernel} (ImageBuf \&dst, const char *name, \\ \bigspc\spc float width, float height, float depth = 1.0f, \\ \bigspc\spc bool normalize = true)} \index{ImageBufAlgo!make_kernel} \indexapi{make_kernel} Initialize {\cf dst} to be a 1-channel {\cf float} image of the named kernel. The size of the {\cf dst} image will be big enough to contain the kernel given its size ({\cf width} $\times$ {\cf height}) and rounded up to odd resolution so that the center of the kernel can be at the center of the middle pixel. The kernel image will be offset so that its center is at the {\cf (0,0)} coordinate. If {\cf normalize} is true, the values will be normalized so that they sum to $1.0$. If {\cf depth} $> 1$, a volumetric kernel will be created. Use with caution! Kernel names can be: \qkw{gaussian}, \qkw{sharp-gaussian}, \qkw{box}, \qkw{triangle}, \qkw{mitchell}, \qkw{blackman-harris}, \qkw{b-spline}, \qkw{catmull-rom}, \qkw{lanczos3}, \qkw{disk}, \qkw{binomial}. Note that \qkw{catmull-rom} and \qkw{lanczos3} are fixed-size kernels that don't scale with the width, and are therefore probably less useful in most cases. \smallskip \noindent Examples: \begin{code} ImageBuf K; ImageBufAlgo::make_kernel (K, "gaussian", 5.0f, 5.0f); \end{code} \apiend \apiitem{bool {\ce convolve} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc const ImageBuf \&kernel, bool normalize = true, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!convolve} \indexapi{convolve} Replace the given ROI of {\cf dst} with the convolution of {\cf src} and a kernel. If {\cf roi} is not defined, it defaults to the full size of {\cf dst} (or {\cf src}, if {\cf dst} was uninitialized). If {\cf dst} is uninitialized, it will be allocated to be the size specified by {\cf roi}. If {\cf normalized} is {\cf true}, the kernel will be normalized for the convolution, otherwise the original values will be used. \smallskip \noindent Examples: \begin{code} // Blur an image with a 5x5 Gaussian kernel ImageBuf Src ("tahoe.exr"); ImageBuf K; ImageBufAlgo::make_kernel (K, "gaussian", 5.0f, 5.0f); ImageBuf Blurred; ImageBufAlgo::convolve (Blurred, Src, K); \end{code} \apiend \apiitem{bool {\ce fft} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce ifft} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!fft} \indexapi{fft} \index{ImageBufAlgo!ifft} \indexapi{ifft} The {\cf fft()} function takes the discrete Fourier transform (DFT) of the section of {\cf src} denoted by {\cf roi}, storing it in {\cf dst}. If {\cf roi} is not defined, it will be all of {\cf src}'s pixels. Only one channel of {\cf src} may be transformed at a time, so it will be the first channel described by {\cf roi} (or, again, channel 0 if {\cf roi} is undefined). If not already in the correct format, {\cf dst} will be re-allocated to be a 2-channel {\cf float} buffer of size {\cf roi.width()} $\times$ {\cf roi.height}, with channel 0 being the ``real'' part and channel 1 being the the ``imaginary'' part. The values returned are actually the unitary DFT, meaning that it is scaled by $1/\sqrt{\mathrm{npixels}}$. \smallskip \noindent Examples: \begin{code} ImageBuf Src ("tahoe.exr"); // Take the DFT of the first channel of Src ImageBuf Freq; ImageBufAlgo::fft (Freq, Src); // At this point, Freq is a 2-channel float image (real, imag) // Convert it back from frequency domain to a spatial iamge ImageBuf Spatial; ImageBufAlgo::ifft (Spatial, Freq); \end{code} \apiend \section{Image Enhancement / Restoration} \label{sec:iba:enhance} \apiitem{bool {\ce fixNonFinite} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc\spc NonFiniteFixMode mode = NONFINITE_BOX3, \\ \bigspc\spc int *pixelsFixed = NULL, \\ \bigspc\spc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!fixNonFinite} \indexapi{fixNonFinite} Copy pixel values from {\cf src} to {\cf dst} (within the pixel and channel range designated by {\cf roi}), and repair any non-finite ({\cf NaN} or {\cf Inf}) pixels. If {\cf pixelsFound} is not \NULL, store in it the number of pixels that contained non-finite value. How the non-finite values are repaired is specified by one of the following modes: \begin{description} \item[\spc] \spc \item[\rm \kw{NONFINITE_NONE}] do not alter the pixels (but do count the number of nonfinite pixels in {\cf *pixelsFixed}, if non-\NULL). \item[\rm \kw{NONFINITE_BLACK}] change non-finite values to 0. \item[\rm \kw{NONFINITE_BOX3}] replace non-finite values by the average of any finite pixels within a 3x3 window. \end{description} This works on all pixel data types, though it's just a copy for images with pixel data types that cannot represent {\cf NaN} or {\cf Inf} values. \smallskip \noindent Examples: \begin{code} ImageBuf Src ("tahoe.exr"); int pixelsFixed = 0; ImageBufAlgo::fixNonFinite (Src, Src, ImageBufAlgo::NONFINITE_BOX3, &pixelsFixed); std::cout << "Repaired " << pixelsFixed << " non-finite pixels\n"; \end{code} \apiend \apiitem{bool {\ce fillholes_pushpull} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!fillholes_pushpull} \indexapi{fillholes_pushpull} Copy the specified ROI of {\cf src} to {\cf dst} and fill any holes (pixels where alpha $< 1$) with plausible values using a push-pull technique. The {\cf src} image must have an alpha channel. The dst image will end up with a copy of src, but will have an alpha of 1.0 everywhere, and any place where the alpha of src was < 1, dst will have a pixel color that is a plausible ``filling'' of the original alpha hole. \smallskip \noindent Examples: \begin{code} ImageBuf Src ("holes.exr"); ImageBuf Filled; ImageBufAlgo::fillholes_pushpull (Filled, Src); \end{code} \apiend \apiitem{bool {\ce unsharp_mask} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc\spc const char *kernel = "gaussian", float width = 3.0f, \\ \bigspc\spc float contrast = 1.0f, float threshold = 0.0f, \\ \bigspc\spc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!unsharp_mask} \indexapi{unsharp_mask} Replace the given ROI of {\cf dst} with a sharpened version of the corresponding region of {\cf src} using the ``unsharp mask'' technique. Unsharp masking basically works by first blurring the image (low pass filter), subtracting this from the original image, then adding the residual back to the original to emphasize the edges. Roughly speaking, \begin{code} dst = src + contrast * thresh(src - blur(src)) \end{code} The specific blur can be selected by kernel name and width. The {\cf contrast} is a multiplier on the overall sharpening effect. The thresholding step causes all differences less than {\cf threshold} to be squashed to zero, which can be useful for suppressing sharpening of low-contrast details (like noise) but allow sharpening of higher-contrast edges. \smallskip \noindent Examples: \begin{code} ImageBuf Blurry ("tahoe.exr"); ImageBuf Sharp; ImageBufAlgo::unsharp_mask (Sharp, Blurry, "gaussian", 5.0f); \end{code} \apiend \section{Color manipulation} \label{sec:iba:color} \apiitem{bool {\ce colorconvert} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc\spc const char *from, const char *to, bool unpremult=false, \\ \bigspc\spc ROI roi=ROI::All(), int nthreads=0) \\ bool {\ce colorconvert} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc\spc const ColorProcessor *processor, bool unpremult=false, \\ \bigspc\spc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!colorconvert} \indexapi{colorconvert} Copy pixels from {\cf src} to {\cf dst} (within the ROI), while applying a color transform to the pixel values. In-place operations ({\cf dst} and {\cf src} being the same image) are supported. If {\cf unpremult} is {\cf true}, unpremultiply before color conversion, then premultiply again after the color conversion. You may want to use this flag if your image contains an alpha channel. The first form of this function specifies the ``from'' and ``to'' color spaces by name. The second form is passed a {\cf ColorProcessor}, which is is a special object created by a {\cf ColorConfig} (see {\cf OpenImageIO/color.h} for details). If OIIO was built with OpenColorIO support enabled, then the transformation may be between any two spaces supported by the active OCIO configuration, or may be a ``look'' transformation created by {\cf ColorConfig::createLookTransform}. If OIIO was not built with OpenColorIO support enabled, then the only transformations available are from \qkw{sRGB} to \qkw{linear} and vice versa. \smallskip \noindent Examples: \begin{code} #include #include using namespace OIIO; ImageBuf Src ("tahoe.jpg"); ImageBuf Dst; ColorConfig cc; ColorProcessor *processor = cc.createColorProcessor ("vd8", "lnf"); ImageBufAlgo::colorconvert (Dst, Src, processor, true); ColorProcessor::deleteColorProcessor (processor); // Equivalent, though possibly less efficient if you will be // converting many images using the same transformation: ImageBuf Src ("tahoe.jpg"); ImageBuf Dst; ImageBufAlgo::colorconvert (Dst, Src, "vd8", "lnf", true); \end{code} \apiend \apiitem{bool {\ce ociolook} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc\spc const char *looks, const char *from, const char *to, \\ \bigspc\spc bool inverse=false, bool unpremult=false, \\ \bigspc\spc const char *key=NULL, const char *value=NULL, \\ \bigspc\spc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!ociolook} \indexapi{ociolook} Copy pixels from {\cf src} to {\cf dst} (within the ROI), while applying an OpenColorIO ``look'' transform to the pixel values. In-place operations ({\cf dst} and {\cf src} being the same image) are supported. The {\cf key} and {\cf value} may optionally be used to establish a context (for example, a shot-specific transform). If {\cf inverse} is {\cf true}, it will reverse the color transformation and look application. If {\cf unpremult} is {\cf true}, unpremultiply before color conversion, then premultiply again after the color conversion. You may want to use this flag if your image contains an alpha channel. \smallskip \noindent Examples: \begin{code} ImageBuf Src ("tahoe.jpg"); ImageBuf Dst; ImageBufAlgo::ociolook (Dst, Src, "look", "vd8", "lnf", false, false, "SHOT", "pe0012"); \end{code} \apiend \apiitem{bool {\ce ociodisplay} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc\spc const char *display, const char *view, \\ \bigspc\spc const char *from=NULL, const char *looks=NULL,\\ \bigspc\spc bool unpremult=false, \\ \bigspc\spc const char *key=NULL, const char *value=NULL, \\ \bigspc\spc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!ociodisplay} \indexapi{ociodisplay} Copy pixels from {\cf src} to {\cf dst} (within the ROI), while applying an OpenColorIO ``display'' transform to the pixel values. In-place operations ({\cf dst} and {\cf src} being the same image) are supported. If {\cf from} or {\cf looks} are {\cf NULL}, it will not override the look or source color space (subtly different than passing \qkw{}, the empty string, which means to use no look or source space). The {\cf key} and {\cf value} may optionally be used to establish a context (for example, a shot-specific transform). If {\cf inverse} is {\cf true}, it will reverse the color transformation and look application. If {\cf unpremult} is {\cf true}, unpremultiply before color conversion, then premultiply again after the color conversion. You may want to use this flag if your image contains an alpha channel. \smallskip \noindent Examples: \begin{code} ImageBuf Src ("tahoe.exr"); ImageBuf Dst; ImageBufAlgo::ociodisplay (Dst, Src, "sRGB", "Film", "lnf", NULL, false, "SHOT", "pe0012"); \end{code} \apiend \apiitem{bool {\ce unpremult} (ImageBuf \&dst, const ImageBuf \&src,\\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!unpremult} \indexapi{unpremult} Copy pixels from {\cf src} to {\cf dst}, and in the process divide all color channels (those not alpha or z) by the alpha value, to ``un-premultiply'' them. This presumes that the image starts of as ``associated alpha'' a.k.a.\ ``premultipled.'' The alterations are restricted to the pixels and channels of the supplied ROI (which defaults to all of {\cf src}). Pixels in which the alpha channel is 0 will not be modified (since the operation is undefined in that case). This is just a copy if there is no identified alpha channel (and a no-op if {\cf dst} and {\cf src} are the same image). \smallskip \noindent Examples: \begin{code} // Convert in-place from associated alpha to unassociated alpha ImageBuf A ("a.exr"); ImageBufAlgo::unpremult (A, A); \end{code} \apiend \apiitem{bool {\ce premult} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!premult} \indexapi{premult} Copy pixels from {\cf src} to {\cf dst}, and in the process multiply all color channels (those not alpha or z) by the alpha value, to ``premultiply'' them. This presumes that the image starts of as ``unassociated alpha'' a.k.a.\ ``non-premultipled.'' The alterations are restricted to the pixels and channels of the supplied ROI (which defaults to all of {\cf src}). This is just a copy if there is no identified alpha channel (and a no-op if {\cf dst} and {\cf src} are the same image). \smallskip \noindent Examples: \begin{code} // Convert in-place from unassociated alpha to associated alpha ImageBuf A ("a.exr"); ImageBufAlgo::premult (A, A); \end{code} \apiend \section{Import / export} \label{sec:iba:importexport} \apiitem{bool {\ce make_texture} (MakeTextureMode mode, const ImageBuf \&input, \\ \bigspc const std::string \&outputfilename, const ImageSpec \&config,\\ \bigspc std::ostream *outstream = NULL) \\ bool {\ce make_texture} (MakeTextureMode mode, const std::string \&filename, \\ \bigspc const std::string \&outputfilename, const ImageSpec \&config,\\ \bigspc std::ostream *outstream = NULL)} \index{ImageBufAlgo!make_texture} \indexapi{make_texture} Turn an image file (either an existing \ImageBuf or specified by {\cf filename}) into a tiled, MIP-mapped, texture file and write to the file named by ({\cf outputfilename}). The {\cf mode} describes what type of texture file we are creating and may be one of the following: \noindent \begin{tabular}{p{2in}p{3in}} {\cf MakeTxTexture} & Ordinary 2D texture\\ %MakeTxShadow & \\ {\cf MakeTxEnvLatl} & Latitude-longitude environment map\\ {\cf \small MakeTxEnvLatlFromLightProbe} & Latitude-longitude environment map constructed from a ``light probe'' image.\\ \end{tabular} If the {\cf outstream} pointer is not \NULL, it should point to a stream (for example, {\cf \&std::out}, or a pointer to a local {\cf std::stringstream} to capture output), which is where console output and error messages will be deposited. The {\cf config} is an \ImageSpec that contains all the information and special instructions for making the texture. Anything set in {\cf config} (format, tile size, or named metadata) will take precedence over whatever is specified by the input file itself. Additionally, named metadata that starts with \qkw{maketx:} will not be output to the file itself, but may contain instructions controlling how the texture is created. The full list of supported configuration options is: \noindent Named fields: \begin{tabular}{ >{\cf}l p{4in}} format & Data format of the texture file (default: UNKNOWN = same format as the input) \\ tile_width & \multirow{3}{*}{Preferred tile size (default: 64x64x1)} \\ tile_height & \\ tile_depth & \\ \end{tabular} \medskip \noindent Metadata in {\cf config.extra_attribs}: \begin{longtable}{ >{\spc \cf\small}p{1.8in} >{\cf\small}l p{3in}} compression & string & Default: "zip" \\ fovcot & float & Default: aspect ratio of the image resolution \\ planarconfig & string & Default: "separate" \\ worldtocamera & matrix & World-to-camera matrix of the view. \\ worldtoscreen & matrix & World-to-screen space matrix of the view. \\ wrapmodes & string & Default: "black,black" \\ maketx:verbose & int & How much detail should go to outstream (0). \\ maketx:stats & int & If nonzero, print stats to outstream (0). \\ maketx:resize & int & If nonzero, resize to power of 2. (0) \\ maketx:nomipmap & int & If nonzero, only output the top MIP level (0). \\ maketx:updatemode & int & If nonzero, write new output only if the output file doesn't already exist, or is older than the input file. (0) \\ \multicolumn{2}{l}{\spc \cf\small maketx:constant_color_detect} \\ & int & If nonzero, detect images that are entirely one color, and change them to be low resolution (default: 0). \\ \multicolumn{2}{l}{\spc \cf\small maketx:monochrome_detect} \\ & int & If nonzero, change RGB images which have R==G==B everywhere to single-channel grayscale (default: 0). \\ maketx:opaquedetect & int & If nonzero, drop the alpha channel if alpha is 1.0 in all pixels (default: 0). \\ maketx:unpremult & int & If nonzero, unpremultiply color by alpha before color conversion, then multiply by alpha after color conversion (default: 0). \\ {\small maketx:incolorspace} & string & \\ {\small maketx:outcolorspace} & string & These two together will apply a color conversion (with OpenColorIO, if compiled). Default: "" \\ maketx:checknan & int & If nonzero, will consider it an error if the input image has any NaN pixels. (0) \\ maketx:fixnan & string & If set to "black" or "box3", will attempt to repair any NaN pixels found in the input image (default: "none"). \\ \multicolumn{2}{l}{\spc \cf\small maketx:set_full_to_pixels} \\ & int & If nonzero, doctors the full/display window of the texture to be identical to the pixel/data window and reset the origin to 0,0 (default: 0). \\ maketx:filtername & string & If set, will specify the name of a high-quality filter to use when resampling for MIPmap levels. Default: "", use bilinear resampling. \\ maketx:highlightcomp & int & If nonzero, performs highlight compensation -- range compression and expansion around the resize, plus clamping negative plxel values to zero. This reduces ringing when using filters with negative lobes. \\ maketx:nchannels & int & If nonzero, will specify how many channels the output texture should have, padding with 0 values or dropping channels, if it doesn't the number of channels in the input. (default: 0, meaning keep all input channels) \\ maketx:channelnames & string & If set, overrides the channel names of the output image (comma-separated). \\ {\small maketx:fileformatname} & string & If set, will specify the output file format. (default: "", meaning infer the format from the output filename) \\ \multicolumn{2}{l}{\spc \cf\small maketx:prman_metadata} \\ & int & If set, output some metadata that PRMan will need for its textures. (0) \\ {\small maketx:oiio_options} & int & (Deprecated; all are handled by default) \\ \multicolumn{2}{l}{\spc \cf\small maketx:prman_options} \\ & int & If nonzero, override a whole bunch of settings as needed to make textures that are compatible with PRMan. (0) \\ maketx:mipimages & string & Semicolon-separated list of alternate images to be used for individual MIPmap levels, rather than simply downsizing. (default: "") \\ \multicolumn{2}{l}{\spc \cf\small maketx:full_command_line} \\ & string & The command or program used to generate this call, will be embedded in the metadata. (default: "") \\ \multicolumn{2}{l}{\spc \cf\small maketx:ignore_unassoc} \\ & int & If nonzero, will disbelieve any evidence that the input image is unassociated alpha. (0) \\ \multicolumn{2}{l}{\spc \cf\small maketx:read_local_MB} \\ & int & If nonzero, will read the full input file locally if it is smaller than this threshold. Zero causes the system to make a good guess at a reasonable threshold (e.g. 1 GB). (0) \\ maketx:forcefloat & int & Forces a conversion through float data for the sake of ImageBuf math. (1) \\ maketx:hash & int & Compute the sha1 hash of the file in parallel. (1) \\ \multicolumn{2}{l}{\spc \cf\small maketx:allow_pixel_shift} \\ & int & Allow up to a half pixel shift per mipmap level. The fastest path may result in a slight shift in the image, accumulated for each mip level with an odd resolution. (0) \\ \end{longtable} \smallskip \noindent Examples: \begin{code} // This command line: // maketx in.exr --hicomp --filter lanczos3 --opaque-detect \ // -o texture.exr // is equivalent to: ImageBuf Input ("in.exr"); ImageSpec config; config.attribute ("maketx:highlightcomp", 1); config.attribute ("maketx:filtername", "lanczos3"); config.attribute ("maketx:opaquedetect", 1); stringstream s; bool ok = ImageBufAlgo::make_texture (ImageBufAlgo::MakeTxTexture, Input, "texture.exr", config, &s); if (! ok) std::cout << "make_texture error: " << s.str() << "\n"; \end{code} \apiend \apiitem{bool {\ce from_IplImage} (ImageBuf \&dst, const IplImage *ipl, \\ \bigspc\bigspc TypeDesc convert = TypeDesc::UNKNOWN)} \index{ImageBufAlgo!from_IplImage} \indexapi{from_IplImage} \index{OpenCV}\indexapi{IplImage}\index{Intel Image Library} Convert an {\cf IplImage}, used by OpenCV and Intel's Image Libray, and set {\cf dst} to be the same image (copying the pixels). If {\cf convert} is not set to {\cf UNKNOWN}, try to establish {\cf dst} as holding that data type and convert the {\cf IplImage} data. Return {\cf true} if ok, {\cf false} if it couldn't figure out how to make the conversion from {\cf IplImage} to an \ImageBuf. If OpenImageIO was compiled without OpenCV support, this function will return false without modifying {\cf dst}. \begin{comment} \smallskip \noindent Examples: \begin{code} \end{code} \end{comment} \apiend \apiitem{IplImage* {\ce to_IplImage} (const ImageBuf \&src)} \index{ImageBufAlgo!to_IplImage} \indexapi{to_IplImage} \index{OpenCV}\indexapi{IplImage}\index{Intel Image Library} Construct an {\cf IplImage*}, used by OpenCV and Intel's Image Library, that is equivalent to the \ImageBuf {\cf src}. If it is not possible, or if OpenImageIO was compiled without OpenCV support, then return \NULL. The ownership of the {\cf IplImage} is fully transferred to the calling application. \begin{comment} \smallskip \noindent Examples: \begin{code} \end{code} \end{comment} \apiend \apiitem{bool {\ce capture_image} (ImageBuf \&dst, int cameranum, \\ \bigspc\bigspc TypeDesc convert = TypeDesc::UNKNOWN)} \index{ImageBufAlgo!capture_image} \indexapi{capture_image} Capture a still image from a designated camera. If able to do so, store the image in {\cf dst} and return {\cf true}. If there is no such device, or support for camera capture is not available (such as if OpenCV support was not enabled at compile time), return {\cf false} and do not alter {\cf dst}. \smallskip \noindent Examples: \begin{code} ImageBuf WebcamImage; ImageBufAlgo::capture_image (WebcamImage, 0, TypeDesc::UINT8); WebcamImage.save ("webcam.jpg"); \end{code} \apiend \begin{comment} \apiitem{bool {\ce blah} (ImageBuf \&dst, const ImageBuf \&src, \\ \bigspc ROI roi=ROI::All(), int nthreads=0)} \index{ImageBufAlgo!blah} \indexapi{blah} Blah. \smallskip \noindent Examples: \begin{code} \end{code} \apiend \end{comment} \index{ImageBufAlgo|)} \index{Image Processing|)} \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/techref.sty0000644000175000017500000001541012271062644020037 0ustar mfvmfv%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % renew the commands for \chapter, \section, etc., to have the % formatting that I want. These were taken from book.cls and % modified. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \renewcommand\part{% \if@openright \cleardoublepage \else \clearpage \fi \thispagestyle{plain}% \if@twocolumn \onecolumn \@tempswatrue \else \@tempswafalse \fi \null\vfil \secdef\@part\@spart} \def\@part[#1]#2{% \ifnum \c@secnumdepth >-2\relax \refstepcounter{part}% \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}% \else \addcontentsline{toc}{part}{#1}% \fi \markboth{}{}% {\centering \interlinepenalty \@M \normalfont \ifnum \c@secnumdepth >-2\relax %lg \huge\bfseries \partname~\thepart \huge\sffamily\bfseries \partname~\thepart %lg \par \vskip 20\p@ \fi \Huge \bfseries #2\par}% \@endpart} \def\@spart#1{% {\centering \interlinepenalty \@M \normalfont %lg \Huge \bfseries #1\par}% \Huge \sffamily\bfseries #1\par}% %lg \@endpart} \def\@endpart{\vfil\newpage \if@twoside \null \thispagestyle{empty}% \newpage \fi \if@tempswa \twocolumn \fi} \renewcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi \thispagestyle{plain}% \global\@topnum\z@ \@afterindentfalse \secdef\@chapter\@schapter} \def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne \if@mainmatter \refstepcounter{chapter}% \typeout{\@chapapp\space\thechapter.}% \addcontentsline{toc}{chapter}% {\protect\numberline{\thechapter}#1}% \else \addcontentsline{toc}{chapter}{#1}% \fi \else \addcontentsline{toc}{chapter}{#1}% \fi \chaptermark{#1}% \addtocontents{lof}{\protect\addvspace{10\p@}}% \addtocontents{lot}{\protect\addvspace{10\p@}}% \if@twocolumn \@topnewpage[\@makechapterhead{#2}]% \else \@makechapterhead{#2}% \@afterheading \fi} \def\@makechapterhead#1{% \vspace*{50\p@}% {\parindent \z@ \raggedright \normalfont \ifnum \c@secnumdepth >\m@ne \if@mainmatter %lg \huge\bfseries \@chapapp\space \thechapter \Huge \sffamily \bfseries \thechapter \hspace{1em} %lg %lg \par\nobreak %lg \vskip 20\p@ \fi \fi \interlinepenalty\@M %lg \Huge \bfseries #1\par\nobreak \Huge \sffamily\bfseries #1\par\nobreak %lg \vskip 40\p@ }} \def\@schapter#1{\if@twocolumn \@topnewpage[\@makeschapterhead{#1}]% \else \@makeschapterhead{#1}% \@afterheading \fi} \def\@makeschapterhead#1{% %%% lg this is for chapter* \vspace*{50\p@}% {\parindent \z@ \raggedright \normalfont \interlinepenalty\@M %lg \Huge \bfseries #1\par\nobreak \Huge \sffamily \bfseries #1\par\nobreak %lg \vskip 40\p@ }} \renewcommand\section{\@startsection {section}{1}{\z@}% {-3.5ex \@plus -1ex \@minus -.2ex}% {2.3ex \@plus.2ex}% %lg {\normalfont\Large\bfseries}} {\normalfont\Large\sffamily\bfseries}} %lg \renewcommand\subsection{\@startsection{subsection}{2}{\z@}% {-3.25ex\@plus -1ex \@minus -.2ex}% {1.5ex \@plus .2ex}% %lg {\normalfont\large\bfseries}} {\normalfont\large\sffamily\bfseries}} %lg \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% {-3.25ex\@plus -1ex \@minus -.2ex}% {1.5ex \@plus .2ex}% %lg {\normalfont\normalsize\bfseries}} {\normalfont\normalsize\sffamily\bfseries}} %lg \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}% {3.25ex \@plus1ex \@minus.2ex}% {-1em}% {\normalfont\normalsize\bfseries}} \renewcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}% {3.25ex \@plus1ex \@minus .2ex}% {-1em}% {\normalfont\normalsize\bfseries}} %%%% % lg - added new environment for descriptions specifically for the glossary % \newenvironment{glossarydescription} {\list{}{\small \setlength{\leftmargin}{0pt} \setlength{\itemsep}{0pt} \labelwidth\z@ \itemindent-\leftmargin \let\makelabel\glossarydescriptionlabel}} {\endlist} \newcommand*\glossarydescriptionlabel[1]{\hspace\labelsep \normalfont\bfseries #1} % %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Modify the bibliography citation style % I borrowed this from apastyle, then modified it -- lg %%%%%%%% \def\@cite#1#2{(#1\if@tempswa , #2\fi)} \def\@biblabel#1{} \newlength{\bibhang} \setlength{\bibhang}{0em} \@ifundefined{chapter}{\def\thebibliography#1{\section*{\refname\@mkboth {\sl\uppercase{\refname}}{\sl\uppercase{\refname}}}\list {\relax}{ \setlength{\labelsep}{0em} %lg \setlength{\itemindent}{-\bibhang} \setlength{\leftmargin}{\bibhang}} \def\newblock{\hskip .11em plus .33em minus .07em} \sloppy\clubpenalty4000\widowpenalty4000 \sfcode`\.=1000\relax}}% {\def\thebibliography#1{\chapter*{\bibname\@mkboth {\sl\uppercase{\bibname}}{\sl\uppercase{\bibname}}}\list {\relax}{\setlength{\labelsep}{0em} \small \setlength{\itemsep}{0pt} %lg \setlength{\itemindent}{-\bibhang} \setlength{\leftmargin}{\bibhang}} \def\newblock{\hskip .11em plus .33em minus .07em} \sloppy\clubpenalty4000\widowpenalty4000 \sfcode`\.=1000\relax}} \def\@citex[#1]#2{\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi \def\@citea{}\@cite{\@for\@citeb:=#2\do {\@citea\def\@citea{; }\@ifundefined {b@\@citeb}{{\bf ?}\@warning {Citation `\@citeb' on page \thepage \space undefined}}% {\csname b@\@citeb\endcsname}}}{#1}} openimageio-1.3.12~dfsg0.orig/src/doc/imageoutput.tex0000644000175000017500000020674412271062644020757 0ustar mfvmfv\chapter{ImageOutput: Writing Images} \label{chap:imageoutput} \index{Image I/O API|(} \indexapi{ImageOutput} \section{Image Output Made Simple} \label{sec:imageoutput:simple} Here is the simplest sequence required to write the pixels of a 2D image to a file: \begin{code} #include OIIO_NAMESPACE_USING ... const char *filename = "foo.jpg"; const int xres = 640, yres = 480; const int channels = 3; // RGB unsigned char pixels[xres*yres*channels]; ImageOutput *out = ImageOutput::create (filename); if (! out) return; ImageSpec spec (xres, yres, channels, TypeDesc::UINT8); out->open (filename, spec); out->write_image (TypeDesc::UINT8, pixels); out->close (); delete out; \end{code} \noindent This little bit of code does a surprising amount of useful work: \begin{itemize} \item Search for an ImageIO plugin that is capable of writing the file (\qkw{foo.jpg}), deducing the format from the file extension. When it finds such a plugin, it creates a subclass instance of \ImageOutput that writes the right kind of file format. \begin{code} ImageOutput *out = ImageOutput::create (filename); \end{code} \item Open the file, write the correct headers, and in all other important ways prepare a file with the given dimensions ($640 \times 480$), number of color channels (3), and data format (unsigned 8-bit integer). \begin{code} ImageSpec spec (xres, yres, channels, TypeDesc::UINT8); out->open (filename, spec); \end{code} \item Write the entire image, hiding all details of the encoding of image data in the file, whether the file is scanline- or tile-based, or what is the native format of data in the file (in this case, our in-memory data is unsigned 8-bit and we've requested the same format for disk storage, but if they had been different, {\kw write_image()} would do all the conversions for us). \begin{code} out->write_image (TypeDesc::UINT8, &pixels); \end{code} \item Close the file, destroy and free the \ImageOutput we had created, and perform all other cleanup and release of any resources needed by the plugin. \begin{code} out->close (); delete out; \end{code} \end{itemize} \section{Advanced Image Output} \label{sec:imageoutput:advanced} Let's walk through many of the most common things you might want to do, but that are more complex than the simple example above. \subsection{Writing individual scanlines, tiles, and rectangles} \label{sec:imageoutput:scanlinestiles} The simple example of Section~\ref{sec:imageoutput:simple} wrote an entire image with one call. But sometimes you are generating output a little at a time and do not wish to retain the entire image in memory until it is time to write the file. \product allows you to write images one scanline at a time, one tile at a time, or by individual rectangles. \subsubsection{Writing individual scanlines} Individual scanlines may be written using the \writescanline API call: \begin{code} ... unsigned char scanline[xres*channels]; out->open (filename, spec); int z = 0; // Always zero for 2D images for (int y = 0; y < yres; ++y) { ... generate data in scanline[0..xres*channels-1] ... out->write_scanline (y, z, TypeDesc::UINT8, scanline); } out->close (); ... \end{code} The first two arguments to \writescanline specify which scanline is being written by its vertical ($y$) scanline number (beginning with 0) and, for volume images, its slice ($z$) number (the slice number should be 0 for 2D non-volume images). This is followed by a \TypeDesc describing the data you are supplying, and a pointer to the pixel data itself. Additional optional arguments describe the data stride, which can be ignored for contiguous data (use of strides is explained in Section~\ref{sec:imageoutput:strides}). All \ImageOutput implementations will accept scanlines in strict order (starting with scanline 0, then 1, up to {\kw yres-1}, without skipping any). See Section~\ref{sec:imageoutput:randomrewrite} for details on out-of-order or repeated scanlines. The full description of the \writescanline function may be found in Section~\ref{sec:imageoutput:reference}. \subsubsection{Writing individual tiles} Not all image formats (and therefore not all \ImageOutput implementations) support tiled images. If the format does not support tiles, then \writetile will fail. An application using \product should gracefully handle the case that tiled output is not available for the chosen format. Once you {\kw create()} an \ImageOutput, you can ask if it is capable of writing a tiled image by using the {\kw supports("tiles")} query: \begin{code} ... ImageOutput *out = ImageOutput::create (filename); if (! out->supports ("tiles")) { // Tiles are not supported } \end{code} Assuming that the \ImageOutput supports tiled images, you need to specifically request a tiled image when you {\kw open()} the file. This is done by setting the tile size in the \ImageSpec passed to {\kw open()}. If the tile dimensions are not set, they will default to zero, which indicates that scanline output should be used rather than tiled output. \begin{code} int tilesize = 64; ImageSpec spec (xres, yres, channels, TypeDesc::UINT8); spec.tile_width = tilesize; spec.tile_height = tilesize; out->open (filename, spec); ... \end{code} In this example, we have used square tiles (the same number of pixels horizontally and vertically), but this is not a requirement of \product. However, it is possible that some image formats may only support square tiles, or only certain tile sizes (such as restricting tile sizes to powers of two). Such restrictions should be documented by each individual plugin. \begin{code} unsigned char tile[tilesize*tilesize*channels]; int z = 0; // Always zero for 2D images for (int y = 0; y < yres; y += tilesize) { for (int x = 0; x < xres; x += tilesize) { ... generate data in tile[] .. out->write_tile (x, y, z, TypeDesc::UINT8, tile); } } out->close (); ... \end{code} The first three arguments to \writetile specify which tile is being written by the pixel coordinates of any pixel contained in the tile: $x$ (column), $y$ (scanline), and $z$ (slice, which should always be 0 for 2D non-volume images). This is followed by a \TypeDesc describing the data you are supplying, and a pointer to the tile's pixel data itself, which should be ordered by increasing slice, increasing scanline within each slice, and increasing column within each scanline. Additional optional arguments describe the data stride, which can be ignored for contiguous data (use of strides is explained in Section~\ref{sec:imageoutput:strides}). All \ImageOutput implementations that support tiles will accept tiles in strict order of increasing $y$ rows, and within each row, increasing $x$ column, without missing any tiles. See Section~\ref{sec:imageoutput:randomrewrite} for details on out-of-order or repeated tiles. The full description of the \writetile function may be found in Section~\ref{sec:imageoutput:reference}. \subsubsection{Writing arbitrary rectangles} Some \ImageOutput implementations --- such as those implementing an interactive image display, but probably not any that are outputting directly to a file --- may allow you to send arbitrary rectangular pixel regions. Once you {\kw create()} an \ImageOutput, you can ask if it is capable of accepting arbitrary rectangles by using the {\kw supports("rectangles")} query: \begin{code} ... ImageOutput *out = ImageOutput::create (filename); if (! out->supports ("rectangles")) { // Rectangles are not supported } \end{code} If rectangular regions are supported, they may be sent using the {\kw write_rectangle()} API call: \begin{code} unsigned int rect[...]; ... generate data in rect[] .. out->write_rectangle (xbegin, xend, ybegin, yend, zbegin, zend, TypeDesc::UINT8, rect); \end{code} The first six arguments to {\kw write_rectangle()} specify the region of pixels that is being transmitted by supplying the minimum and one-past-maximum pixel indices in $x$ (column), $y$ (scanline), and $z$ (slice, always 0 for 2D non-volume images).\footnote{\OpenImageIO nearly always follows the C++ STL convention of specifying ranges as {\cf [begin,end)}, that is, {\cf begin, begin+1, ..., end-1.}} The total number of pixels being transmitted is therefore: \begin{code} (xend-xbegin) * (yend-ybegin) * (zend-zbegin) \end{code} \noindent This is followed by a \TypeDesc describing the data you are supplying, and a pointer to the rectangle's pixel data itself, which should be ordered by increasing slice, increasing scanline within each slice, and increasing column within each scanline. Additional optional arguments describe the data stride, which can be ignored for contiguous data (use of strides is explained in Section~\ref{sec:imageoutput:strides}). \subsection{Converting data formats} \label{sec:imageoutput:convertingformats} The code examples of the previous sections all assumed that your internal pixel data is stored as unsigned 8-bit integers (i.e., 0-255 range). But \product is significantly more flexible. You may request that the output image be stored in any of several formats. This is done by setting the {\kw format} field of the \ImageSpec prior to calling {\kw open}. You can do this upon construction of the \ImageSpec, as in the following example that requests a spec that stores data as 16-bit unsigned integers: \begin{code} ImageSpec spec (xres, yres, channels, TypeDesc::UINT16); \end{code} \noindent Or, for an \ImageSpec that has already been constructed, you may reset its format using the {\kw set_format()} method (which also resets the various quantization fields of the spec to the defaults for the data format you have specified). \begin{code} ImageSpec spec (...); spec.set_format (TypeDesc::UINT16); \end{code} Note that resetting the format must be done \emph{before} passing the spec to {\kw open()}, or it will have no effect on the file. Individual file formats, and therefore \ImageOutput implementations, may only support a subset of the formats understood by the \product library. Each \ImageOutput plugin implementation should document which data formats it supports. An individual \ImageOutput implementation may choose to simply fail to {\kw open()}, though the recommended behavior is for {\kw open()} to succeed but in fact choose a data format supported by the file format that best preserves the precision and range of the originally-requested data format. It is not required that the pixel data passed to \writeimage, \writescanline, \writetile, or {\kw write_rectangle()} actually be in the same data format as that requested as the native format of the file. You can fully mix and match data you pass to the various {\kw write} routines and \product will automatically convert from the internal format to the native file format. For example, the following code will open a TIFF file that stores pixel data as 16-bit unsigned integers (values ranging from 0 to 65535), compute internal pixel values as floating-point values, with \writeimage performing the conversion automatically: \begin{code} ImageOutput *out = ImageOutput::create ("myfile.tif"); ImageSpec spec (xres, yres, channels, TypeDesc::UINT16); out->open (filename, spec); ... float pixels [xres*yres*channels]; ... out->write_image (TypeDesc::FLOAT, pixels); \end{code} \noindent Note that \writescanline, \writetile, and {\cf write_rectangle} have a parameter that works in a corresponding manner. Please refer to Section~\ref{sec:imageoutput:quantization} for more information on how values are translated among the supported data formats by default, and how to change the formulas by specifying quantization in the \ImageSpec. \subsection{Data Strides} \label{sec:imageoutput:strides} In the preceeding examples, we have assumed that the block of data being passed to the {\cf write} functions are \emph{contiguous}, that is: \begin{itemize} \item each pixel in memory consists of a number of data values equal to the declared number of channels that are being written to the file; \item successive column pixels within a row directly follow each other in memory, with the first channel of pixel $x$ immediately following last channel of pixel $x-1$ of the same row; \item for whole images, tiles or rectangles, the data for each row immediately follows the previous one in memory (the first pixel of row $y$ immediately follows the last column of row $y-1$); \item for 3D volumetric images, the first pixel of slice $z$ immediately follows the last pixel of of slice $z-1$. \end{itemize} Please note that this implies that data passed to \writetile be contiguous in the shape of a single tile (not just an offset into a whole image worth of pixels), and that data passed to {\cf write_rectangle()} be contiguous in the dimensions of the rectangle. The \writescanline function takes an optional {\cf xstride} argument, and the \writeimage, \writetile, and {\cf write_rectangle} functions take optional {\cf xstride}, {\cf ystride}, and {\cf zstride} values that describe the distance, in \emph{bytes}, between successive pixel columns, rows, and slices, respectively, of the data you are passing. For any of these values that are not supplied, or are given as the special constant {\cf AutoStride}, contiguity will be assumed. By passing different stride values, you can achieve some surprisingly flexible functionality. A few representative examples follow: \begin{itemize} \item Flip an image vertically upon writing, by using \emph{negative} $y$ stride: \begin{code} unsigned char pixels[xres*yres*channels]; int scanlinesize = xres * channels * sizeof(pixels[0]); ... out->write_image (TypeDesc::UINT8, (char *)pixels+(yres-1)*scanlinesize, // offset to last AutoStride, // default x stride -scanlinesize, // special y stride AutoStride); // default z stride \end{code} \item Write a tile that is embedded within a whole image of pixel data, rather than having a one-tile-only memory layout: \begin{code} unsigned char pixels[xres*yres*channels]; int pixelsize = channels * sizeof(pixels[0]); int scanlinesize = xres * pixelsize; ... out->write_tile (x, y, 0, TypeDesc::UINT8, (char *)pixels + y*scanlinesize + x*pixelsize, pixelsize, scanlinesize); \end{code} \item Write only a subset of channels to disk. In this example, our internal data layout consists of 4 channels, but we write just channel 3 to disk as a one-channel image: \begin{code} // In-memory representation is 4 channel const int xres = 640, yres = 480; const int channels = 4; // RGBA const int channelsize = sizeof(unsigned char); unsigned char pixels[xres*yres*channels]; // File representation is 1 channel ImageOutput *out = ImageOutput::create (filename); ImageSpec spec (xres, yres, 1, TypeDesc::UINT8); out->open (filename, spec); // Use strides to write out a one-channel "slice" of the image out->write_image (TypeDesc::UINT8, (char *)pixels+3*channelsize, // offset to chan 3 channels*channelsize, // 4 channel x stride AutoStride, // default y stride AutoStride); // default z stride ... \end{code} \end{itemize} Please consult Section~\ref{sec:imageoutput:reference} for detailed descriptions of the stride parameters to each {\cf write} function. \subsection{Writing a crop window or overscan region} \label{sec:imageoutput:cropwindows} \index{crop windows} \index{overscan} % FIXME -- Marcos suggests adding a figure here to illustrate % the w/h/d, xyz, full The \ImageSpec fields {\cf width}, {\cf height}, and {\cf depth} describe the dimensions of the actual pixel data. At times, it may be useful to also describe an abstract \emph{full} or \emph{display} image window, whose position and size may not correspond exactly to the data pixels. For example, a pixel data window that is a subset of the full display window might indicate a \emph{crop window}; a pixel data window that is a superset of the full display window might indicate \emph{overscan} regions (pixels defined outside the eventual viewport). The \ImageSpec fields {\cf full_width}, {\cf full_height}, and {\cf full_depth} describe the dimensions of the full display window, and {\cf full_x}, {\cf full_y}, {\cf full_z} describe its origin (upper left corner). The fields {\cf x}, {\cf y}, {\cf z} describe the origin (upper left corner) of the pixel data. These fields collectively describe an abstract full display image ranging from [{\cf full_x} ... {\cf full_x+full_width-1}] horizontally, [{\cf full_y} ... {\cf full_y+full_height-1}] vertically, and [{\cf full_z} ... {\cf full_z+full_depth-1}] in depth (if it is a 3D volume), and actual pixel data over the pixel coordinate range [{\cf x} ... {\cf x+width-1}] horizontally, [{\cf y} ... {\cf y+height-1}] vertically, and [{\cf z} ... {\cf z+depth-1}] in depth (if it is a volume). Not all image file formats have a way to describe display windows. An \ImageOutput implementation that cannot express display windows will always write out the {\cf width} $\times$ {\cf height} pixel data, may upon writing lose information about offsets or crop windows. Here is a code example that opens an image file that will contain a $32 \times 32$ pixel crop window within an abstract $640 \times 480$ full size image. Notice that the pixel indices (column, scanline, slice) passed to the {\cf write} functions are the coordinates relative to the full image, not relative to the crop widow, but the data pointer passed to the {\cf write} functions should point to the beginning of the actual pixel data being passed (not the the hypothetical start of the full data, if it was all present). \begin{code} int fullwidth = 640, fulllength = 480; // Full display image size int cropwidth = 16, croplength = 16; // Crop window size int xorigin = 32, yorigin = 128; // Crop window position unsigned char pixels [cropwidth * croplength * channels]; // Crop size! ... ImageOutput *out = ImageOutput::create (filename); ImageSpec spec (cropwidth, croplength, channels, TypeDesc::UINT8); spec.full_x = 0; spec.full_y = 0; spec.full_width = fullwidth; spec.full_length = fulllength; spec.x = xorigin; spec.y = yorigin; out->open (filename, spec); ... int z = 0; // Always zero for 2D images for (int y = yorigin; y < yorigin+croplength; ++y) { out->write_scanline (y, z, TypeDesc::UINT8, (y-yorigin)*cropwidth*channels); } out->close (); \end{code} \subsection{Writing metadata} \label{sec:imageoutput:metadata} The \ImageSpec passed to {\cf open()} can specify all the common required properties that describe an image: data format, dimensions, number of channels, tiling. However, there may be a variety of additional \emph{metadata}\footnote{\emph{Metadata} refers to data about data, in this case, data about the image that goes beyond the pixel values and description thereof.} that should be carried along with the image or saved in the file. The remainder of this section explains how to store additional metadata in the \ImageSpec. It is up to the \ImageOutput to store these in the file, if indeed the file format is able to accept the data. Individual \ImageOutput implementations should document which metadata they respect. \subsubsection{Channel names} In addition to specifying the number of color channels, it is also possible to name those channels. Only a few \ImageOutput implementations have a way of saving this in the file, but some do, so you may as well do it if you have information about what the channels represent. By convention, channel names for red, green, blue, and alpha (or a main image) should be named \qkw{R}, \qkw{G}, \qkw{B}, and \qkw{A}, respectively. Beyond this guideline, however, you can use any names you want. The \ImageSpec has a vector of strings called {\cf channelnames}. Upon construction, it starts out with reasonable default values. If you use it at all, you should make sure that it contains the same number of strings as the number of color channels in your image. Here is an example: \begin{code} int channels = 4; ImageSpec spec (width, length, channels, TypeDesc::UINT8); spec.channelnames.clear (); spec.channelnames.push_back ("R"); spec.channelnames.push_back ("G"); spec.channelnames.push_back ("B"); spec.channelnames.push_back ("A"); \end{code} Here is another example in which custom channel names are used to label the channels in an 8-channel image containing beauty pass RGB, per-channel opacity, and texture $s,t$ coordinates for each pixel. \begin{code} int channels = 8; ImageSpec spec (width, length, channels, TypeDesc::UINT8); spec.channelnames.clear (); spec.channelnames.push_back ("R"); spec.channelnames.push_back ("G"); spec.channelnames.push_back ("B"); spec.channelnames.push_back ("opacityR"); spec.channelnames.push_back ("opacityG"); spec.channelnames.push_back ("opacityB"); spec.channelnames.push_back ("texture_s"); spec.channelnames.push_back ("texture_t"); \end{code} The main advantage to naming color channels is that if you are saving to a file format that supports channel names, then any application that uses \product to read the image back has the option to retain those names and use them for helpful purposes. For example, the {\cf iv} image viewer will display the channel names when viewing individual channels or displaying numeric pixel values in ``pixel view'' mode. \subsubsection{Specially-designated channels} The \ImageSpec contains two fields, {\cf alpha_channel} and {\cf z_channel}, which can be used to designate which channel indices are used for alpha and $z$ depth, if any. Upon construction, these are both set to {\cf -1}, indicating that it is not known which channels are alpha or depth. Here is an example of setting up a 5-channel output that represents RGBAZ: \begin{code} int channels = 5; ImageSpec spec (width, length, channels, format); spec.channelnames.push_back ("R"); spec.channelnames.push_back ("G"); spec.channelnames.push_back ("B"); spec.channelnames.push_back ("A"); spec.channelnames.push_back ("Z"); spec.alpha_channel = 3; spec.z_channel = 4; \end{code} There are two advantages to designating the alpha and depth channels in this manner: \begin{itemize} \item Some file formats may require that these channels be stored in a particular order, with a particular precision, or the \ImageOutput may in some other way need to know about these special channels. \end{itemize} \subsubsection{Arbitrary metadata} For all other metadata that you wish to save in the file, you can attach the data to the \ImageSpec using the {\cf attribute()} methods. These come in polymorphic varieties that allow you to attach an attribute name and a value consisting of a single {\cf int}, {\cf unsigned int}, {\cf float}, {\cf char*}, or {\cf std::string}, as shown in the following examples: \begin{code} ImageSpec spec (...); ... unsigned int u = 1; spec.attribute ("Orientation", u); float x = 72.0; spec.attribute ("dotsize", f); std::string s = "Fabulous image writer 1.0"; spec.attribute ("Software", s); \end{code} These are convenience routines for metadata that consist of a single value of one of these common types. For other data types, or more complex arrangements, you can use the more general form of {\cf attribute()}, which takes arguments giving the name, type (as a \TypeDesc), number of values (1 for a single value, $>1$ for an array), and then a pointer to the data values. For example, \begin{code} ImageSpec spec (...); // Attach a 4x4 matrix to describe the camera coordinates float mymatrix[16] = { ... }; spec.attribute ("worldtocamera", TypeDesc::TypeMatrix, &mymatrix); // Attach an array of two floats giving the CIE neutral color float neutral[2] = { ... }; spec.attribute ("adoptedNeutral", TypeDesc(TypeDesc::FLOAT, 2), &neutral); \end{code} In general, most image file formats (and therefore most \ImageOutput implementations) are aware of only a small number of name/value pairs that they predefine and will recognize. Some file formats (OpenEXR, notably) do accept arbitrary user data and save it in the image file. If an \ImageOutput does not recognize your metadata and does not support arbitrary metadata, that metadatum will be silently ignored and will not be saved with the file. Each individual \ImageOutput implementation should document the names, types, and meanings of all metadata attributes that they understand. \subsubsection{Color space hints} We certainly hope that you are using only modern file formats that support high precision and extended range pixels (such as OpenEXR) and keeping all your images in a linear color space. But you may have to work with file formats that dictate the use of nonlinear color values. This is prevalent in formats that store pixels only as 8-bit values, since 256 values are not enough to linearly represent colors without banding artifacts in the dim values. Since this can (and probably will) happen, we have a convention for explaining what color space your image pixels are in. Each individual \ImageOutput should document how it uses this (or not). The {\cf ImageSpec::extra_attribs} field should store metadata that reveals the color space of the pixels you are sending the ImageOutput. The \qkw{oiio:ColorSpace} attribute may take on any of the following values: \begin{description} \item[\halfspc \rm \qkw{Linear}] indicates that the color pixel values are known to be linear. \item[\halfspc \rm \qkw{GammaCorrected}] indicates that the color pixel values (but not alpha or $z$) have already been gamma corrected (raised to the power $1/\gamma$), and that the gamma exponent may be found in the \qkw{oiio:Gamma} metadata. \item[\halfspc \rm \qkw{sRGB}] indicates that the color pixel values are in sRGB color space. \item[\halfspc \rm \qkw{AdobeRGB}] indicates that the color pixel values are in Adobe RGB color space. \item[\halfspc \rm \qkw{Rec709}] indicates that the color pixel values are in Rec709 color space. \item[\halfspc \rm \qkw{KodakLog}] indicates that the color pixel values are in Kodak logarithmic color space. \end{description} \noindent The color space hints only describe color channels. You should always pass alpha, depth, or other non-color channels with linear values. Here is a simple example of setting up the \ImageSpec when you know that the pixel values you are writing are linear: \begin{code} ImageSpec spec (width, length, channels, format); spec.attribute ("oiio:ColorSpace", "Linear"); ... \end{code} If a particular \ImageOutput implementation is required (by the rules of the file format it writes) to have pixels in a particular color space, then it should try to convert the color values of your image to the right color space if it is not already in that space. For example, JPEG images must be in sRGB space, so if you declare your pixels to be \qkw{Linear}, the JPEG \ImageOutput will convert to sRGB. If you leave the \qkw{oiio:ColorSpace} unset, the values will not be transformed, since the plugin can't be sure that it's not in the correct space to begin with. \subsection{Controlling quantization} \label{sec:imageoutput:quantization} It is possible that your internal data format (that in which you compute pixel values that you pass to the {\cf write} functions) is of greater precision or range than the native data format of the output file. This can occur either because you specified a lower-precision data format in the \ImageSpec that you passed to {\cf open()}, or else that the image file format dictates a particular data format that does not match your internal format. For example, you may compute {\cf float} pixels and pass those to {\cf write_image()}, but if you are writing a JPEG/JFIF file, the values must be stored in the file as 8-bit unsigned integers. The conversion from floating-point formats to integer formats (or from higher to lower integer, which is done by first converting to float) is controlled by five fields within the \ImageSpec: {\cf quant_black}, {\cf quant_white}, {\cf quant_min}, and {\cf quant_max} Float 0.0 maps to the integer value given by {\cf quant_black}, and float 1.0 maps to the integer value given by {\cf quant_white}. Finally, this result is truncated its integer value for final output. Here is the code that implements this transformation ({\cf T} is the final output integer type): \begin{code} float value = quant_black * (1 - input) + quant_white * input; T output = (T) clamp ((int)(value + 0.5), quant_min, quant_max); \end{code} The values of the quantization parameters are set in one of three ways: (1) upon construction of the \ImageSpec, they are set to the default quantization values for the given data format; (2) upon call to {\cf ImageSpec::set_format()}, the quantization values are set to the defaults for the given data format; (3) or, after being first set up in this manner, you may manually change the quantization parameters in the \ImageSpec, if you want something other than the default quantization. \noindent Default quantization for each integer type is as follows:\\ \smallskip \begin{tabular}{|l|r|r|r|r|r|} \hline {\bf Data Format} & {\bf black} & {\bf white} & {\bf min} & {\bf max} & \\ \hline {\cf UINT8} & 0 & 255 & 0 & 255 & 0.5 \\ {\cf INT8} & 0 & 127 & -128 & 127 & 0.5 \\ {\cf UINT16} & 0 & 65535 & 0 & 65535 & 0.5 \\ {\cf INT16} & 0 & 32767 & -32768 & 32767 & 0.5 \\ {\cf UINT} & 0 & 4294967295 & 0 & 4294967295 & 0.5 \\ {\cf INT} & 0 & 2147483647 & -2147483648 & 2147483647 & 0.5 \\ \hline {\cf FLOAT} & & & & & \\ {\cf HALF} & 0 & 1 & N/A & N/A & 0 \\ {\cf DOUBLE} & & & & & \\ \hline \end{tabular} \\ \smallskip \noindent Note that the default is to use the entire positive range of each integer type to represent the floating-point (0..1) range. Floating-point types do not attempt to remap values, and do not clamp (except to their full floating-point range). The default will almost always be what you want. But just as an example, here's how you would specify a quantization for a 16-bit file in which 1.0 maps to 16383 (14 bits of positive range) rather than filling the full 16 bit: \begin{code} ImageSpec spec (width, length, channels, TypeDesc::UINT16); spec.quant_black = 0; spec.quant_white = 16383; spec.quant_min = 0; spec.quant_max = 16383; \end{code} \subsection{Random access and repeated transmission of pixels} \label{sec:imageoutput:randomrewrite} All \ImageOutput implementations that support scanlines and tiles should write pixels in strict order of increasing $z$ slice, increasing $y$ scanlines/rows within each slice, and increasing $x$ column within each row. It is generally not safe to skip scanlines or tiles, or transmit them out of order, unless the plugin specifically advertises that it supports random access or rewrites, which may be queried using: \begin{code} ImageOutput *out = ImageOutput::create (filename); if (out->supports ("random_access")) ... \end{code} \noindent Similarly, you should assume the plugin will not correctly handle repeated transmissions of a scanline or tile that has already been sent, unless it advertises that it supports rewrites, which may be queried using: \begin{code} if (out->supports ("rewrite")) ... \end{code} \subsection{Multi-image files} \label{sec:imageoutput:multiimage} Some image file formats support storing multiple images within a single file. Given a created \ImageOutput, you can query whether multiple images may be stored in the file: \begin{code} ImageOutput *out = ImageOutput::create (filename); if (out->supports ("multiimage")) ... \end{code} Some image formats allow you to do the initial {\cf open()} call without declaring the specifics of the subimages, and simply append subimages as you go. You can detect this by checking \begin{code} if (out->supports ("appendsubimage")) ... \end{code} In this case, all you have to do is, after writing all the pixels of one image but before calling {\cf close()}, call {\cf open()} again for the next subimage and pass {\cf AppendSubimage} as the value for the \emph{mode} argument (see Section~\ref{sec:imageoutput:reference} for the full technical description of the arguments to {\cf open}). The {\cf close()} routine is called just once, after all subimages are completed. Here is an example: \begin{code} const char *filename = "foo.tif"; int nsubimages; // assume this is set ImageSpec specs[]; // assume these are set for each subimage unsigned char *pixels[]; // assume a buffer for each subimage // Create the ImageOutput ImageOutput *out = ImageOutput::create (filename); // Be sure we can support subimages if (subimages > 1 && (! out->supports("multiimage") || ! out->supports("appendsubimage"))) { std::cerr << "Does not support appending of subimages\n"; delete out; return; } // Use Create mode for the first level. ImageOutput::OpenMode appendmode = ImageOutput::Create; // Write the individual subimages for (int s = 0; s < nsubimages; ++s) { out->open (filename, specs[s], appendmode); out->write_image (TypeDesc::UINT8, pixels[s]); // Use AppendSubimage mode for subsequent levels appendmode = ImageOutput::AppendSubimage; } out->close (); delete out; \end{code} On the other hand, if {\cf out->supports("appendsubimage")} returns {\cf false}, then you must use a different {\cf open()} variety that allows you to declare the number of subimages and their specifications up front. Below is an example of how to write a multi-subimage file, assuming that you know all the image specifications ahead of time. This should be safe for any file format that supports multiple subimages, regardless of whether it supports appending, and thus is the preferred method for writing subimages, assuming that you are able to know the number and specification of the subimages at the time you first open the file. \begin{code} const char *filename = "foo.tif"; int nsubimages; // assume this is set ImageSpec specs[]; // assume these are set for each subimage unsigned char *pixels[]; // assume a buffer for each subimage // Create the ImageOutput ImageOutput *out = ImageOutput::create (filename); // Be sure we can support subimages if (subimages > 1 && ! out->supports ("multiimage")) { std::cerr << "Cannot write multiple subimages\n"; delete out; return; } // Open and declare all subimages out->open (filename, nsubimages, specs); // Write the individual subimages for (int s = 0; s < nsubimages; ++s) { if (s > 0) // Not needed for the first, which is already open out->open (filename, specs[s], ImageInput::AppendSubimage); out->write_image (TypeDesc::UINT8, pixels[s]); } out->close (); delete out; \end{code} In both of these examples, we have used \writeimage, but of course \writescanline, \writetile, and {\cf write_rectangle()} work as you would expect, on the current subimage. \subsection{MIP-maps} \label{sec:imageoutput:mipmap} Some image file formats support multiple copies of an image at successively lower resolutions (MIP-map levels, or an ``image pyramid''). Given a created \ImageOutput, you can query whether MIP-maps may be stored in the file: \begin{code} ImageOutput *out = ImageOutput::create (filename); if (out->supports ("mipmap")) ... \end{code} If you are working with an \ImageOutput that supports MIP-map levels, it is easy to write these levels. After writing all the pixels of one MIP-map level, call {\cf open()} again for the next MIP level and pass {\cf ImageInput::AppendMIPLevel} as the value for the \emph{mode} argument, and then write the pixels of the subsequent MIP level. (See Section~\ref{sec:imageoutput:reference} for the full technical description of the arguments to {\cf open()}.) The {\cf close()} routine is called just once, after all subimages and MIP levels are completed. Below is pseudocode for writing a MIP-map (a multi-resolution image used for texture mapping): \begin{code} const char *filename = "foo.tif"; const int xres = 512, yres = 512; const int channels = 3; // RGB unsigned char *pixels = new unsigned char [xres*yres*channels]; // Create the ImageOutput ImageOutput *out = ImageOutput::create (filename); // Be sure we can support either mipmaps or subimages if (! out->supports ("mipmap") && ! out->supports ("multiimage")) { std::cerr << "Cannot write a MIP-map\n"; delete out; return; } // Set up spec for the highest resolution ImageSpec spec (xres, yres, channels, TypeDesc::UINT8); // Use Create mode for the first level. ImageOutput::OpenMode appendmode = ImageOutput::Create; // Write images, halving every time, until we're down to // 1 pixel in either dimension while (spec.width >= 1 && spec.height >= 1) { out->open (filename, spec, appendmode); out->write_image (TypeDesc::UINT8, pixels); // Assume halve() resamples the image to half resolution halve (pixels, spec.width, spec.height); // Don't forget to change spec for the next iteration spec.width /= 2; spec.height /= 2; // For subsequent levels, change the mode argument to // open(). If the format doesn't support MIPmaps directly, // try to emulate it with subimages. if (out->supports("mipmap")) appendmode = ImageOutput::AppendMIPLevel; else appendmode = ImageOutput::AppendSubimage; } out->close (); delete out; \end{code} In this example, we have used \writeimage, but of course \writescanline, \writetile, and {\cf write_rectangle()} work as you would expect, on the current MIP level. \subsection{Per-channel formats} \label{sec:imageoutput:channelformats} Some image formats allow separate per-channel data formats (for example, {\cf half} data for colors and {\cf float} data for depth). When this is desired, the following steps are necessary: \begin{enumerate} \item Verify that the writer supports per-channel formats by checking \\ {\cf supports ("channelformats")}. \item The \ImageSpec passed to {\cf open()} should have its {\cf channelformats} vector filled with the types for each channel. \item The call to {\cf write_scanline}, {\cf read_scanlines}, {\cf write_tile}, {\cf write_tiles}, or {\cf write_image} should pass a {\cf data} pointer to the raw data, already in the native per-channel format of the file and contiguously packed, and specify that the data is of type {\cf TypeDesc::UNKNOWN}. \end{enumerate} For example, the following code fragment will write a 5-channel image to an OpenEXR file, consisting of R/G/B/A channels in {\cf half} and a Z channel in {\cf float}: \begin{code} // Mixed data type for the pixel struct Pixel { half r,g,b,a; float z; }; Pixel pixels[xres*yres]; ImageOutput *out = ImageOutput::create ("foo.exr"); // Double check that this format accepts per-channel formats if (! out->supports("channelformats")) { delete out; return; } // Prepare an ImageSpec with per-channel formats ImageSpec spec (xres, yres, 5, TypeDesc::FLOAT); spec.channelformats.push_back (TypeDesc::HALF); spec.channelformats.push_back (TypeDesc::HALF); spec.channelformats.push_back (TypeDesc::HALF); spec.channelformats.push_back (TypeDesc::HALF); spec.channelformats.push_back (TypeDesc::FLOAT); spec.channelnames.clear (); spec.channelnames.push_back ("R"); spec.channelnames.push_back ("G"); spec.channelnames.push_back ("B"); spec.channelnames.push_back ("A"); spec.channelnames.push_back ("Z"); out->open (filename, spec); out->write_image (TypeDesc::UNKNOWN, /* use channel formats */ pixels, /* data buffer */ sizeof(Pixel)); /* pixel stride */ \end{code} \subsection{Writing ``deep'' data} \label{sec:imageoutput:deepdata} \index{deep data} Some image file formats (OpenEXR only, at this time) support the concept of ``deep'' pixels -- those containing multiple samples per pixel (and a potentially differing number of them in each pixel). You can tell if a format supports deep images by checking {\cf supports("deepdata")}, and you can specify a deep data in an \ImageSpec by setting its {\cf deep} field will be {\cf true}. Deep files cannot be written with the usual {\cf write_scanline}, {\cf write_scanlines}, {\cf write_tile}, {\cf write_tiles}, {\cf write_image} functions, due to the nature of their variable number of samples per pixel. Instead, \ImageOutput has three special member functions used only for writing deep data: \begin{code} bool write_deep_scanlines (int ybegin, int yend, int z, const DeepData &deepdata); bool write_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, const DeepData &deepdata); bool write_deep_image (const DeepData &deepdata); \end{code} It is only possible to write ``native'' data types to deep files; that is, there is no automatic translation into arbitrary data types as there is for ordinary images. All three of these functions are passed deep data in a special {\cf DeepData} structure, defined in {\cf imageio.h} as follows: \begin{code} struct DeepData { int npixels, nchannels; std::vector channeltypes; // for each channel [c] std::vector nsamples;// for each pixel [z][y][x] std::vector pointers; // for each channel per pixel [z][y][x][c] std::vector data; // for each sample [z][y][x][c][s] DeepData (); // Set the size and allocate the nsamples[] vector. void init (int npix, int nchan, const TypeDesc *chbegin, const TypeDesc *chend); // Allocate data[] and set up all the pointers[] void alloc (); }; \end{code} \noindent Here is an example of using these methods to write a deep image: \begin{code} // Prepare the spec for 'half' RGBA, 'float' z int nchannels = 5; ImageSpec spec (xres, yres, nchannels); TypeDesc channeltypes[] = { TypeDesc::HALF, TypeDesc::HALF, TypeDesc::HALF, TypeDesc::HALF, TypeDesc::FLOAT }; spec.z_channel = 4; spec.channelnames[spec.z_channel] = "Z"; spec.channeltypes.assign (channeltypes+0, channeltypes+nchannels); spec.deep = true; // Prepare the data (sorry, complicated, but need to show the gist) DeepData deepdata; deepdata.init (xres*yres, 5, channeltypes+0, channeltypes+nchannels); for (int y = 0; y < yres; ++y) for (int x = 0; x < xres; ++x) deepdata.nsamples[y*xres+x] = ...num samples for that pixel...; deepdata.alloc (); // allocate pointers and data int pixel = 0; for (int y = 0; y < yres; ++y) for (int x = 0; x < xres; ++x, ++pixel) for (int chan = 0; chan < nchannels; ++chan) { void *ptr = deepdata.pointers[pixel*nchannels + c]; if (chan < 4) { // RGBA -- it's HALF data for (int samp = 0; samp < deepdata.nsamples[pixel]; ++samp) ((half *)ptr)[samp] = ...value...; } else { // z channel -- FLOAT data for (int samp = 0; samp < deepdata.nsamples[pixel]; ++samp) ((float *)ptr)[samp] = ...value...; } } } } // Create the output ImageOutput *out = ImageOutput::create (filename); if (! out) return; // Make sure the format can handle deep data and per-channel formats if (! out->supports("deepdata") || ! out->supports("channelformats")) return; // Do the I/O (this is the easy part!) out->open (filename, spec); out->write_deep_image (deepdata); out->close (); delete out; \end{code} \subsection{Copying an entire image} \label{sec:imageoutput:copyimage} Suppose you want to copy an image, perhaps with alterations to the metadata but not to the pixels. You could open an \ImageInput and perform a {\cf read_image()}, and open another \ImageOutput and call {\cf write_image()} to output the pixels from the input image. However, for compressed images, this may be inefficient due to the unnecessary decompression and subsequent re-compression. In addition, if the compression is \emph{lossy}, the output image may not contain pixel values identical to the original input. A special {\cf copy_image} method of \ImageOutput is available that attempts to copy an image from an open \ImageInput (of the same format) to the output as efficiently as possible with without altering pixel values, if at all possible. Not all format plugins will provide an implementation of {\cf copy_image} (in fact, most will not), but the default implemenatation simply copies pixels one scanline or tile at a time (with decompression/recompression) so it's still safe to call. Furthermore, even a provided {\cf copy_image} is expected to fall back on the default implementation if the input and output are not able to do an efficient copy. Nevertheless, this method is recommended for copying images so that maximal advantage will be taken in cases where savings can be had. The following is an example use of {\cf copy_image} to transfer pixels without alteration while modifying the image description metadata: \begin{code} // Open the input file const char *input = "input.jpg"; ImageInput *in = ImageInput::create (input); ImageSpec in_spec; in->open (input, in_spec); // Make an output spec, identical to the input except for metadata ImageSpec out_spec = in_spec; out_spec.attribute ("ImageDescription", "My Title"); // Create the output file and copy the image const char *output = "output.jpg"; ImageOutput *out = ImageOutput::create (output); out->open (output, out_spec); out->copy_image (in); // Clean up out->close (); delete out; in->close (); delete in; \end{code} \subsection{Custom search paths for plugins} \label{sec:imageoutput:searchpaths} When you call {\cf ImageOutput::create()}, the \product library will try to find a plugin that is able to write the format implied by your filename. These plugins are alternately known as DLL's on Windows (with the {\cf .dll} extension), DSO's on Linux (with the {\cf .so} extension), and dynamic libraries on Mac OS X (with the {\cf .dylib} extension). \product will look for matching plugins according to \emph{search paths}, which are strings giving a list of directories to search, with each directory separated by a colon (`{\cf :}'). Within a search path, any substrings of the form {\cf \$\{FOO\}} will be replaced by the value of environment variable {\cf FOO}. For example, the searchpath \qkw{\$\{HOME\}/plugins:/shared/plugins} will first check the directory \qkw{/home/tom/plugins} (assuming the user's home directory is {\cf /home/tom}), and if not found there, will then check the directory \qkw{/shared/plugins}. The first search path it will check is that stored in the environment variable {\cf OIIO_LIBRARY_PATH}. It will check each directory in turn, in the order that they are listed in the variable. If no adequate plugin is found in any of the directories listed in this environment variable, then it will check the custom searchpath passed as the optional second argument to {\cf ImageOutput::create()}, searching in the order that the directories are listed. Here is an example: \begin{code} char *mysearch = "/usr/myapp/lib:${HOME}/plugins"; ImageOutput *out = ImageOutput::create (filename, mysearch); ... \end{code} % $ \subsection{Error checking} \label{sec:imageoutput:errors} \index{error checking} Nearly every \ImageOutput API function returns a {\cf bool} indicating whether the operation succeeded ({\cf true}) or failed ({\cf false}). In the case of a failure, the \ImageOutput will have saved an error message describing in more detail what went wrong, and the latest error message is accessible using the \ImageOutput method {\cf geterror()}, which returns the message as a {\cf std::string}. The exception to this rule is {\cf ImageOutput::create}, which returns {\cf NULL} if it could not create an appropriate \ImageOutput. And in this case, since no \ImageOutput exists for which you can call its {\cf geterror()} function, there exists a global {\cf geterror()} function (in the {\cf OpenImageIO} namespace) that retrieves the latest error message resulting from a call to {\cf create}. Here is another version of the simple image writing code from Section~\ref{sec:imageoutput:simple}, but this time it is fully elaborated with error checking and reporting: \begin{code} #include OIIO_NAMESPACE_USING ... const char *filename = "foo.jpg"; const int xres = 640, yres = 480; const int channels = 3; // RGB unsigned char pixels[xres*yres*channels]; ImageOutput *out = ImageOutput::create (filename); if (! out) { std::cerr << "Could not create an ImageOutput for " << filename << ", error = " << OpenImageIO::geterror() << "\n"; return; } ImageSpec spec (xres, yres, channels, TypeDesc::UINT8); if (! out->open (filename, spec)) { std::cerr << "Could not open " << filename << ", error = " << out->geterror() << "\n"; delete out; return; } if (! out->write_image (TypeDesc::UINT8, pixels)) { std::cerr << "Could not write pixels to " << filename << ", error = " << out->geterror() << "\n"; delete out; return; } if (! out->close ()) { std::cerr << "Error closing " << filename << ", error = " << out->geterror() << "\n"; delete out; return; } delete out; \end{code} \section{\ImageOutput Class Reference} \label{sec:imageoutput:reference} \apiitem{static ImageOutput * {\ce create} (const std::string \&filename, \\ \bigspc\bigspc\spc const std::string \&plugin_searchpath="")} Create an \ImageOutput that can be used to write an image file. The type of image file (and hence, the particular subclass of \ImageOutput returned, and the plugin that contains its methods) is inferred from the extension of the file name. The {\kw plugin_searchpath} parameter is a colon-separated list of directories to search for \product plugin DSO/DLL's. \apiend \apiitem{const char * {\ce format_name} ()} Returns the canonical name of the format that this \ImageOutput instance is capable of writing. \apiend \apiitem{bool {\ce supports} (const std::string \&feature)} \label{sec:supportsfeaturelist} Given the name of a \emph{feature}, tells if this \ImageOutput instance supports that feature. The following features are recognized by this query: \begin{description} \item[\spc] \spc \item[\rm \qkw{tiles}] Is this plugin able to write tiled images? \item[\rm \qkw{rectangles}] Can this plugin accept arbitrary rectangular pixel regions (via {\kw write_rectangle()})? False indicates that pixels must be transmitted via \writescanline (if scanline-oriented) or \writetile (if tile-oriented, and only if {\kw supports("tiles")} returns true). \item[\rm \qkw{random_access}] May tiles or scanlines be written in any order? False indicates that they must be in successive order. \item[\rm \qkw{multiimage}] Does this format support multiple subimages within a single file? \item[\rm \qkw{appendsubimage}] Does this format support multiple subimages that can be successively appended at will, without needing to pre-declare the number and specifications the subimages when the file is first opened? \item[\rm \qkw{mipmap}] Does this format support resolutions per image/subimage (MIP-map levels)? \item[\rm \qkw{volumes}] Does this format support ``3D'' pixel arrays (a.k.a.\ volume images)? \item[\rm \qkw{rewrite}] Does this plugin allow the same scanline or tile to be sent more than once? Generally this is true for plugins that implement some sort of interactive display, rather than a saved image file. \item[\rm \qkw{empty}] Does this plugin support passing a NULL data pointer to the various {\kw write} routines to indicate that the entire data block is composed of pixels with value zero. Plugins that support this achieve a speedup when passing blank scanlines or tiles (since no actual data needs to be transmitted or converted). \item[\rm \qkw{channelformats}] Does this format writer support per-channel data formats, respecting the \ImageSpec's {\cf channelformats} field? (If not, it only accepts a single data format for all channels and will ignore the {\cf channelformats} field of the spec.) \item[\rm \qkw{displaywindow}] Does the image format support specifying a display (``full'') window that is distinct from the pixel data window? \item[\rm \qkw{origin}] Does the image format support specifying a pixel window origin (i.e., nonzero \ImageSpec {\cf x}, {\cf y}, {\cf z})? \item[\rm \qkw{negativeorigin}] Does the image format allow pixel and data window origins (i.e., nonzero \ImageSpec {\cf x}, {\cf y}, {\cf z}, {\cf full_x}, {\cf full_y}, {\cf full_z}) to have negative values? \item[\rm \qkw{deepdata}] Does the image format allow ``deep'' data consisting of multiple values per pixel (and potentially a differing number of values from pixel to pixel)? \end{description} \noindent This list of queries may be extended in future releases. Since this can be done simply by recognizing new query strings, and does not require any new API entry points, addition of support for new queries does not break ``link compatibility'' with previously-compiled plugins. \apiend \apiitem{bool {\ce open} (const std::string \&name, const ImageSpec \&newspec,\\ \bigspc OpenMode mode=Create)} \label{sec:imageoutputopen} Open the file with given {\kw name}, with resolution and other format data as given in {\kw newspec}. This function returns {\kw true} for success, {\kw false} for failure. Note that it is legal to call {\kw open()} multiple times on the same file without a call to {\kw close()}, if it supports multiimage and {\kw mode} is {\kw AppendSubimage}, or if it supports MIP-maps and {\kw mode} is {\kw AppendMIPLevel} -- this is interpreted as appending a subimage, or a MIP level to the current subimage, respectively. \apiend \apiitem{bool {\ce open} (const std::string \&name, int subimages, const ImageSpec *specs)} Open the file with given {\cf name}, expecting to have a given total number of subimages, described by {\cf specs[0..subimages-1]}. Return {\cf true} for success, {\cf false} for failure. Upon success, the first subimage will be open and ready for transmission of pixels. Subsequent subimages will be denoted with the usual call of {\cf open(name,spec,AppendSubimage)} (and MIP levels by {\cf open(name,spec,AppendMIPLevel)}). The purpose of this call is to accommodate format-writing libraries that must know the number and specifications of the subimages upon first opening the file; such formats can be detected by \begin{code} supports("multiimage") && ! supports("appendsubimage") \end{code} The individual specs passed to the appending {\cf open()} calls for subsequent subimages must match the ones originally passed. \apiend \apiitem{const ImageSpec \& {\ce spec} ()} Returns the spec internally associated with this currently open \ImageOutput. \apiend \apiitem{bool {\ce close} ()} Closes the currently open file associated with this \ImageOutput and frees any memory or resources associated with it. \apiend \apiitem{bool {\ce write_scanline} (int y, int z, TypeDesc format, const void *data, \\ \bigspc stride_t xstride=AutoStride)} Write the scanline that includes pixels $(*,y,z)$ from {\cf data}. For 2D non-volume images, $z$ is ignored. The {\cf xstride} value gives the data spacing of adjacent pixels (in bytes). Strides set to the special value {\kw AutoStride} imply contiguous data, i.e., \\ \spc {\kw xstride} $=$ {\kw spec.nchannels * format.size()} \\ This method automatically converts the data from the specified {\kw format} to the actual output format of the file. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to already be in the file's native format (including per-channel formats, as specified in the \ImageSpec's {\cf channelformats} field, if applicable). Return {\kw true} for success, {\kw false} for failure. It is a failure to call \writescanline with an out-of-order scanline if this format driver does not support random access. \apiend \apiitem{bool {\ce write_scanlines} (int ybegin, int yend, int z, \\ \bigspc TypeDesc format, const void *data, \\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride)} Write a block of scanlines that include pixels $(*,y,z)$, where ${\mathit ybegin} \le y < {\mathit yend}$. This is essentially identical to {\cf write_scanline()}, except that it can write more than one scanline at a time, which may be more efficient for certain image format writers. For 2D non-volume images, $z$ is ignored. The {\kw xstride} value gives the distance between successive pixels (in bytes), and {\kw ystride} gives the distance between successive scanlines. Strides set to the special value {\kw AutoStride} imply contiguous data, i.e., \\ \spc {\kw xstride} $=$ {\kw spec.nchannels*format.size()} \\ \spc {\kw ystride} $=$ {\kw spec.width*xstride} This method automatically converts the data from the specified {\kw format} to the actual output format of the file. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to already be in the file's native format (including per-channel formats, as specified in the \ImageSpec's {\cf channelformats} field, if applicable). Return {\kw true} for success, {\kw false} for failure. It is a failure to call \writescanline with an out-of-order scanline if this format driver does not support random access. \apiend \apiitem{bool {\ce write_tile} (int x, int y, int z, TypeDesc format, const void *data, \\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride)} Write the tile with $(x,y,z)$ as the upper left corner. For 2D non-volume images, $z$ is ignored. The three stride values give the distance (in bytes) between successive pixels, scanlines, and volumetric slices, respectively. Strides set to the special value {\kw AutoStride} imply contiguous data, i.e., \\ \spc {\kw xstride} $=$ {\kw spec.nchannels*format.size()} \\ \spc {\kw ystride} $=$ {\kw xstride*spec.tile_width} \\ \spc {\kw zstride} $=$ {\kw ystride*spec.tile_height} \\ This method automatically converts the data from the specified {\kw format} to the actual output format of the file. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to already be in the file's native format (including per-channel formats, as specified in the \ImageSpec's {\cf channelformats} field, if applicable). Return {\kw true} for success, {\kw false} for failure. It is a failure to call \writetile with an out-of-order tile if this format driver does not support random access. This function returns {\cf true} if it successfully writes the tile, otherwise {\cf false} for a failure. The call will fail if the image is not tiled, or if $(x,y,z)$ is not actually a tile boundary. \apiend \apiitem{bool {\ce write_tiles} (int xbegin, int xend, int ybegin, int yend,\\ \bigspc int zbegin, int zend, TypeDesc format, const void *data, \\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride)} Write the tiles that include pixels {\kw xbegin} $\le x <$ {\kw xend}, {\kw ybegin} $\le y <$ {\kw yend}, {\kw zbegin} $\le z <$ {\kw zend} from {\kw data}, converting if necessary from {\kw format} specified into the file's native data format. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data will be assumed to already be in the native format (including per-channel formats, if applicable). The stride values give the data spacing of adjacent pixels, scanlines, and volumetric slices, respectively (measured in bytes). Strides set to the special value of {\kw AutoStride} imply contiguous data, i.e., \\ \spc {\kw xstride} $=$ {\kw spec.nchannels * spec.pixel_size()} \\ \spc {\kw ystride} $=$ {\kw xstride * (xend-xbegin)} \\ \spc {\kw zstride} $=$ {\kw ystride * (yend-ybegin)} \\ The data for those tiles is assumed to be in the usual image order, as if it were just one big tile, and not ``paded'' to a whole multiple of the tile size. This function returns {\cf true} if it successfully writes the tiles, otherwise {\cf false} for a failure. The call will fail if the image is not tiled, or if the pixel ranges do not fall along tile (or image) boundaries, or if it is not a valid tile range. \apiend \apiitem{bool {\ce write_rectangle} ({\small int xbegin, int xend, int ybegin, int yend, \\ \bigspc int zbegin, int zend,} TypeDesc format, const void *data, \\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride)} Write pixels covering the range that includes pixels {\kw xbegin} $\le x <$ {\kw xend}, {\kw ybegin} $\le y <$ {\kw yend}, {\kw zbegin} $\le z <$ {\kw zend}. The three stride values give the distance (in bytes) between successive pixels, scanlines, and volumetric slices, respectively. Strides set to the special value {\kw AutoStride} imply contiguous data, i.e.,\\ \spc {\kw xstride} $=$ {\kw spec.nchannels*format.size()} \\ \spc {\kw ystride} $=$ {\kw xstride*(xend-xbegin)} \\ \spc {\kw zstride} $=$ {\kw ystride*(yend-ybegin)}\\ This method automatically converts the data from the specified {\kw format} to the actual output format of the file. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to already be in the file's native format (including per-channel formats, as specified in the \ImageSpec's {\cf channelformats} field, if applicable). Return {\kw true} for success, {\kw false} for failure. It is a failure to call {\kw write_rectangle} for a format plugin that does not return true for {\kw supports("rectangles")}. \apiend \apiitem{bool {\ce write_image} (TypeDesc format, const void *data, \\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride, \\ \bigspc ProgressCallback progress_callback=NULL,\\ \bigspc void *progress_callback_data=NULL)} Write the entire image of {\kw spec.width} $\times$ {\kw spec.height} $\times$ {\kw spec.depth} pixels, with the given strides and in the desired format. If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to already be in the file's native format (including per-channel formats, as specified in the \ImageSpec's {\cf channelformats} field, if applicable). Strides set to the special value {\kw AutoStride} imply contiguous data, i.e., \\ \spc {\kw xstride} $=$ {\kw spec.nchannels * format.size()} \\ \spc {\kw ystride} $=$ {\kw xstride * spec.width} \\ \spc {\kw zstride} $=$ {\kw ystride * spec.height}\\ The function will internally either call \writescanline or \writetile, depending on whether the file is scanline- or tile-oriented. Because this may be an expensive operation, a progress callback may be passed. Periodically, it will be called as follows: \begin{code} progress_callback (progress_callback_data, float done) \end{code} \noindent where \emph{done} gives the portion of the image (between 0.0 and 1.0) that has been written thus far. \apiend \apiitem{bool {\ce write_deep_scanlines} (int ybegin, int yend, int z, \\ \bigspc const DeepData \&deepdata) \\ bool {\ce write_deep_tiles} (int xbegin, int xend, int ybegin, int yend,\\ \bigspc int zbegin, int zend, const DeepData \&deepdata) \\ bool {\ce write_deep_image} (const DeepData \&deepdata)} Write deep data for a block of scanlines, a block of tiles, or an entire image (analogously to the usual {\cf write_scanlines}, {\cf write_tiles}, and {\cf write_image}, but with deep data). Return {\kw true} for success, {\kw false} for failure. \apiend \apiitem{bool {\ce copy_image} (ImageInput *in)} Read the current subimage of {\cf in}, and write it as the next subimage of {\cf *this}, in a way that is efficient and does not alter pixel values, if at all possible. Both {\cf in} and {\cf this} must be a properly-opened \ImageInput and \ImageOutput, respectively, and their current images must match in size and number of channels. Return {\cf true} if it works ok, {\cf false} if for some reason the operation wasn't possible. If a particular \ImageOutput implementation does not supply a {\cf copy_image} method, it will inherit the default implementation, which is to simply read scanlines or tiles from {\cf in} and write them to {\cf *this}. However, some file format implementations may have a special technique for directly copying raw pixel data from the input to the output, when both input and output are the same file type and the same data format. This can be more efficient than {\cf in->read_image} followed by {\cf out->write_image}, and avoids any unintended pixel alterations, especially for formats that use lossy compression. \apiend \apiitem{int {\ce send_to_output} (const char *format, ...)} General message passing between client and image output server. This is currently undefined and is reserved for future use. \apiend \apiitem{int {\ce send_to_client} (const char *format, ...)} General message passing between client and image output server. This is currently undefined and is reserved for future use. \apiend \apiitem{std::string {\ce geterror} ()} \index{error checking} Returns the current error string describing what went wrong if any of the public methods returned {\kw false} indicating an error. (Hopefully the implementation plugin called {\kw error()} with a helpful error message.) \apiend \index{Image I/O API|)} \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/Figures/0000755000175000017500000000000012271062644017261 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/doc/Figures/CC-30BY.png0000644000175000017500000001120312271062644020724 0ustar mfvmfv‰PNG  IHDRXcÈ à pHYs  šœ OiCCPPhotoshop ICC profilexÚSgTSé=÷ÞôBKˆ€”KoR RB‹€‘&*! Jˆ!¡ÙQÁEEÈ ˆŽŽ€ŒQ, Š Øä!¢Žƒ£ˆŠÊûá{£kÖ¼÷æÍþµ×>ç¬ó³ÏÀ –H3Q5€ ©BàƒÇÄÆáä.@ $p³d!sý#ø~<<+"À¾xÓ ÀM›À0‡ÿêB™\€„Àt‘8K€@zŽB¦@F€˜&S `ËcbãP-`'æÓ€ø™{[”! ‘ eˆDh;¬ÏVŠEX0fKÄ9Ø-0IWfH°·ÀÎ ² 0Qˆ…){`È##x„™FòW<ñ+®ç*x™²<¹$9E[-qWW.(ÎI+6aaš@.Ây™24àóÌ ‘àƒóýxήÎÎ6޶_-ê¿ÿ"bbãþåÏ«p@át~Ñþ,/³€;€mþ¢%îh^  u÷‹f²@µ éÚWópø~<ß5°j>{‘-¨]cöK'XtÀâ÷ò»oÁÔ(€hƒáÏwÿï?ýG %€fI’q^D$.Tʳ?ÇD *°AôÁ,ÀÁÜÁ ü`6„B$ÄÂBB d€r`)¬‚B(†Í°*`/Ô@4ÀQh†“p.ÂU¸=púažÁ(¼ AÈa!ÚˆbŠX#Ž™…ø!ÁH‹$ ɈQ"K‘5H1RŠT UHò=r9‡\Fº‘;È2‚ü†¼G1”²Q=Ô µC¹¨7„F¢ Ðdt1š ›Ðr´=Œ6¡çЫhÚ>CÇ0Àè3Äl0.ÆÃB±8, “c˱"¬ «Æ°V¬»‰õcϱwEÀ 6wB aAHXLXNØH¨ $4Ú 7 „QÂ'"“¨K´&ºùÄb21‡XH,#Ö/{ˆCÄ7$‰C2'¹I±¤TÒÒFÒnR#é,©›4H#“ÉÚdk²9”, +È…ääÃä3ää!ò[ b@q¤øSâ(RÊjJåå4åe˜2AU£šRݨ¡T5ZB­¡¶R¯Q‡¨4uš9̓IK¥­¢•Óhh÷i¯ètºÝ•N—ÐWÒËéGè—èôw †ƒÇˆg(›gw¯˜L¦Ó‹ÇT071ë˜ç™™oUX*¶*|‘Ê •J•&•*/T©ª¦ªÞª UóUËT©^S}®FU3Sã© Ô–«UªPëSSg©;¨‡ªg¨oT?¤~Yý‰YÃLÃOC¤Q ±_ã¼Æ c³x,!k «†u5Ä&±ÍÙ|v*»˜ý»‹=ª©¡9C3J3W³Ró”f?ã˜qøœtN ç(§—ó~ŠÞï)â)¦4L¹1e\kª–—–X«H«Q«Gë½6®í§¦½E»YûAÇJ'\'GgÎçSÙSݧ §M=:õ®.ªk¥¡»Dw¿n§î˜ž¾^€žLo§Þy½çú}/ýTýmú§õG X³ $Û Î<Å5qo</ÇÛñQC]Ã@C¥a•a—á„‘¹Ñ<£ÕFFŒiÆ\ã$ãmÆmÆ£&&!&KMêMîšRM¹¦)¦;L;LÇÍÌÍ¢ÍÖ™5›=1×2ç›ç›×›ß·`ZxZ,¶¨¶¸eI²äZ¦Yî¶¼n…Z9Y¥XUZ]³F­­%Ö»­»§§¹N“N«žÖgðñ¶É¶©·°åØÛ®¶m¶}agbg·Å®Ã“}º}ý= ‡Ù«Z~s´r:V:ޚΜî?}Åô–é/gXÏÏØ3ã¶Ë)ÄiS›ÓGgg¹sƒóˆ‹‰K‚Ë.—>.›ÆÝȽäJtõq]ázÒõ›³›Âí¨Û¯î6îiî‡ÜŸÌ4Ÿ)žY3sÐÃÈCàQåÑ? Ÿ•0k߬~OCOgµç#/c/‘W­×°·¥wª÷aï>ö>rŸã>ã<7Þ2ÞY_Ì7À·È·ËOÃož_…ßC#ÿdÿzÿѧ€%g‰A[ûøz|!¿Ž?:Ûeö²ÙíAŒ ¹AA‚­‚åÁ­!hÈì­!÷ç˜Î‘Îi…P~èÖÐaæa‹Ã~ '…‡…W†?ŽpˆXÑ1—5wÑÜCsßDúD–DÞ›g1O9¯-J5*>ª.j<Ú7º4º?Æ.fYÌÕXXIlK9.*®6nl¾ßüíó‡ââ ã{˜/È]py¡ÎÂô…§©.,:–@LˆN8”ðA*¨Œ%òw%Ž yÂÂg"/Ñ6шØC\*NòH*Mz’쑼5y$Å3¥,幄'©¼L LÝ›:žšv m2=:½1ƒ’‘qBª!M“¶gêgæfvˬe…²þÅn‹·/•Ék³¬Y- ¶B¦èTZ(×*²geWf¿Í‰Ê9–«ž+Íí̳ÊÛ7œïŸÿíÂá’¶¥†KW-X潬j9²‰Š®Û—Ø(Üxå‡oÊ¿™Ü”´©«Ä¹dÏfÒféæÞ-ž[–ª—æ—n ÙÚ´ ßV´íõöEÛ/—Í(Û»ƒ¶C¹£¿<¸¼e§ÉÎÍ;?T¤TôTúT6îÒݵa×ønÑî{¼ö4ìÕÛ[¼÷ý>ɾÛUUMÕfÕeûIû³÷?®‰ªéø–ûm]­NmqíÇÒý#¶×¹ÔÕÒ=TRÖ+ëGǾþïw- 6 UœÆâ#pDyäé÷ ß÷ :ÚvŒ{¬áÓvg/jBšòšF›Sšû[b[ºOÌ>ÑÖêÞzüGÛœ499â?rýéü§CÏdÏ&žþ¢þË®/~øÕë×Îјѡ—ò—“¿m|¥ýêÀë¯ÛÆÂƾÉx31^ôVûíÁwÜwï£ßOä| (ÿhù±õSЧû“““ÿ˜óüc3-ÛgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFžIDATxÚìš_lÛÆÇ¿GÒASÔóÔ ÚùMêK˜dÉc,­{Ù²¦$‚í¥ë"? ¨1HêV¯-ìÈJœ.’ÉÂöšXŸ Óùì"Ê-°Ev") ½I5¶>ɵۇ™n$O¤e;¶c«iš3N<ñî(òÃïýîw¿3¡”F!ŸáiÚ÷D)%€Û¿ŽãÀqxžÇñà9ï9„pà! Ä¿ ((¨CáPŽãfÛ¶Ý£cö8ŽÍêê°ö”RÿfXùIH?~ù'€úpyžw3ÇwË<ïÖq¼™€.È׃ãu\˜¶íå`ÙCv‡ ‚~’ ÂpyBèèæ›s·P©TP«Õ°¶ººÐ`d§NBê{)¼töG°g¹/Äæ@@¼w>uG¼1Döîý…:´44ÐùD"ùœŒã'õ2@ÿvç¯AÁͼ€ª>â•"–——wtÁh4б·Æ0<|–mö-X–—m –e3…o¦ä½ªø¿ÿù×Ë×Ñl4Éd’$ À®ë€x"ŽÑÌ(¾ù­çû¢`€þ³ú¼Ð+ `@Ÿ˜„6«±¢(B–eÄb1 ªÕ*Úí64MÃÊÊ k++2~5öK~ö0,Ë‚iY°,–e…M†Øñlùlñ竟#3šÅêê*dYF©TB, µi·ÛÈårÐ4 ‘H—‹—2|çÃ;ðÁBpEQD6›E&“(Š[^PUUär9:žˆãOïýÏ> Ë2aš&Sò¦éÞO¼yÍFét333Ýáé™ àõTUÅÈÈâ‰8.]¹xà€9à=,ð<>¬\I’P¯×‘Ïç·… ét­V‹ Íf£‰«Åk![Î1„t³÷·ÌNmn³Ñ„,Ë{ㇶO§ÓeÍF÷ên&8à|·ŒçQÕçCp+•JÏpÛ.‰¢ˆJ¥Â k³ªÕyð¼°9dÎwû‚¼Ó¤}àÞk©TBâ…6ú¡›Ž†R©ê{à€]»*.^)2P333Uívý¾Åß=_ÚƒK<Ÿšó< ‚.d²;ÈFÉd²G###l„ŒŒŒ„êb±’Éd§qp öþæÜ-æ-d³Y¦Â½$Q™R–——qóÆ-¶`q!om"v›6»OUU7-o×çÀûjªT* N&“at]‡¢(H¥RH¥R( [ÖMOO‡ì¯âÊJ@½]Ó@È£™ˆÇ=¹ BÀ‚Z­æºX²ÌÀ躎T*ê¤ë:t]G&“¢(=uKKKl6—eªª¢V«¹+ÀX  ·ë•ïþ! ÃØt2ó•›N§wÔçì>¨¿B;zô(kËå˜ÝjµZlÒ;þ¾häsrüUNÇOC<‡¦i=ÞÂVp5MC<ïK\‚óƒ-A1hŸ|5«ªŠ••†¡¡! …®¯ë-“ƒuÁáØõKÙǾ>įßC$ªªP…ýfÐn·ÛPÓÓÓˆD"ÍŒöo’óod02ˆµÕ5,--±ù|žÝô‘#GBàü:Ã0zêüä_k02JËaPøïÔû¶ç‡x.òÊ×§ñÛwŠÐ4 š¦A’$H’Q¡ë:M?ƒ=lÞ¾{ï.:„Â…´Y ¢(¢Óé„<ƒr¹Ìb Édù|ž©·\.³¶Á:B»ÝÆ‹ß×JWñ¿õu˜æ:LË„iZ°ý¸„cñ„ßkèòq W²`Ï¿ÿ…Cøhþ#d~‘aËÉl6ûH?àV`ê)üð̰n®cÝ4a™&LkàGø<®wÛÒI¦†F…B¡ÇõÙMZYYa³u4õñ~hÒãÙbß\<©‰‡:°mwíÒå‹ ¢(¡ïnà¦R)ÖwìÍ1/Ànw!B”l’¥OÖ–›ÜÐñü8]¸_£Æƒ:}õg¯úS=•$‰ÖëuºÓÔjµ¨$I¬¿¬ÈÔxP§ ÷kôâå‹ìü×(w¿d_ÏÐÅú5>6¨¬Èì¼(Štrr’v:-Áv::99IEQdýNž:I—>6袱@Çóã_G¸´gõ?‘ÇËŠ Ap­x ïÿåý=o.M²,ܽ[Ãk?íà‡bÀ¼w3‚«Ôßûf"‚y"?î*ùA¾§þ™F£Ñ¿±h4JË¿/SãA. ôÝ?¼Û7µPJ·-Ï}i öSöõ ^ùé+lB¯TqcîÆ¶Ûögå³H&‡Ù^ÛÜÜ L¦ú§”Müe*÷¡Âã'Ža"ßþN4° 7"ä·úÿx²üÉ'øÝÕæ«óýŠˆƒiØqöôðiœyé N|÷¾‰„c¸žkõÙê*î-ÞÃí›·ûö+«à§iSJŸ%„|ñÅŒ(òÿLz ¨ IEND®B`‚openimageio-1.3.12~dfsg0.orig/src/doc/Welcome.txt0000644000175000017500000000114412271062644020011 0ustar mfvmfvThank you for selecting OpenImageIO. You must be very wise, as well as irresistably attractive! OpenImageIO consists of: * Simple APIs for reading and writing image files in a format-agnostic manner, and plugins to read many common image formats including TIFF, JPEG, OpenEXR, PNG, HDR, ICO, and BMP. * Image utilities, including an image viewer, printing image information, format conversion, image comparison, and others. * A library for image texture lookups, and a managed image cache that allows an application to access hundreds of GB of image data using little runtime RAM. openimageio-1.3.12~dfsg0.orig/src/doc/imagecache.tex0000644000175000017500000007104612271062644020455 0ustar mfvmfv\chapter{Cached Images} \label{chap:imagecache} \index{Image Cache|(} \section{Image Cache Introduction and Theory of Operation} \label{sec:imagecache:intro} \ImageCache is a utility class that allows an application to read pixels from a large number of image files while using a remarkably small amount of memory and other resources. Of course it is possible for an application to do this directly using \ImageInput objects. But \ImageCache offers the following advantages: \begin{itemize} \item \ImageCache presents an even simpler user interface than \ImageInput --- the only supported operations are asking for an \ImageSpec describing a subimage in the file, retrieving for a block of pixels, and locking/reading/releasing individual tiles. You refer to images by filename only; you don't need to keep track of individual file handles or \ImageInput objects. You don't need to explicitly open or close files. \item The \ImageCache is completely thread-safe; if multiple threads are accessing the same file, the \ImageCache internals will handle all the locking and resource sharing. \item No matter how many image files you are accessing, the \ImageCache will maintain a reasonable number of simultaneously-open files, automatically closing files that have not been needed recently. \item No matter how large the total pixels in all the image files you are dealing with are, the \ImageCache will use only a small amount of memory. It does this by loading only the individual tiles requested, and as memory allotments are approached, automatically releasing the memory from tiles that have not been used recently. \end{itemize} In short, if you have an application that will need to read pixels from many large image files, you can rely on \ImageCache to manage all the resources for you. It is reasonable to access thousands of image files totalling hundreds of GB of pixels, efficiently and using a memory footprint on the order of 50 MB. \newpage Below are some simple code fragments that shows \ImageCache in action: \medskip \begin{code} #include OIIO_NAMESPACE_USING // Create an image cache and set some options ImageCache *cache = ImageCache::create (); cache->attribute ("max_memory_MB", 500.0); cache->attribute ("autotile", 64); // Get a block of pixels from a file. // (for brevity of this example, let's assume that 'size' is the // number of channels times the number of pixels in the requested region) float pixels[size]; cache->get_pixels ("file1.jpg", 0, 0, xbegin, xend, ybegin, yend, zbegin, zend, TypeDesc::FLOAT, pixels); // Get information about a file ImageSpec spec; bool ok = cache->get_imagespec ("file2.exr", spec); if (ok) std::cout << "resolution is " << spec.width << "x" << "spec.height << "\n"; // Request and hold a tile, do some work with its pixels, then release ImageCache::Tile *tile; tile = cache->get_tile ("file2.exr", 0, 0, x, y, z); // The tile won't be freed until we release it, so this is safe: TypeDesc format; void *p = cache->tile_pixels (tile, format); // Now p points to the raw pixels of the tile, whose data format // is given by 'format'. cache->release_tile (tile); // Now cache is permitted to free the tile when needed // Note that all files were referenced by name, we never had to open // or close any files, and all the resource and memory management // was automatic. ImageCache::destroy (cache); \end{code} \newpage \section{ImageCache API} \label{sec:imagecache:api} \subsection{Creating and destroying an image cache} \label{sec:imagecache:api:createdestroy} \ImageCache is an abstract API described as a pure virtual class. The actual internal implementation is not exposed through the external API of \product. Because of this, you cannot construct or destroy the concrete implementation, so two static methods of \ImageCache are provided: \apiitem{static ImageCache *ImageCache::{\ce create} (bool shared=true)} Creates a new \ImageCache and returns a pointer to it. If {\cf shared} is {\cf true}, {\cf create()} will return a pointer to a shared \ImageCache (so that multiple parts of an application that request an \ImageCache will all end up with the same one). If {\cf shared} is {\cf false}, a completely unique \ImageCache will be created and returned. \apiend \apiitem{static void ImageCache::{\ce destroy} (ImageCache *x, bool teardown=false)} Destroys an allocated \ImageCache, including freeing all system resources that it holds. This is necessary to ensure that the memory is freed in a way that matches the way it was allocated within the library. Note that simply using {\cf delete} on the pointer will not always work (at least, not on some platforms in which a DSO/DLL can end up using a different allocator than the main program). It is safe to destroy even a shared \ImageCache, as the implementation of {\cf destroy()} will recognize a shared one and only truly release its resources if it has been requested to be destroyed as many times as shared \ImageCache's were created. For a shared \ImageCache, if the {\cf teardown} parameter is {\cf true}, it will try to truly destroy the shared cache if nobody else is still holding a reference (otherwise, it will leave it intact). \apiend \subsection{Setting options and limits for the image cache} \label{sec:imagecache:api:attribute} The following member functions of \ImageCache allow you to set (and in some cases retrieve) options that control the overall behavior of the image cache: \apiitem{bool {\ce attribute} (const std::string \&name, TypeDesc type, const void *val)} \indexapi{attribute} Sets an attribute (i.e., a property or option) of the \ImageCache. The {\cf name} designates the name of the attribute, {\cf type} describes the type of data, and {\cf val} is a pointer to memory containing the new value for the attribute. If the \ImageCache recognizes a valid attribute name that matches the type specified, the attribute will be set to the new value and {\cf attribute()} will return {\cf true}. If {\cf name} is not recognized as a valid attribute name, or if the types do not match (e.g., {\cf type} is {\cf TypeDesc::FLOAT} but the named attribute is a string), the attribute will not be modified, and {\cf attribute()} will return {\cf false}. Here are examples: \begin{code} ImageCache *ts; ... int maxfiles = 50; ts->attribute ("max_open_files", TypeDesc::INT, &maxfiles); const char *path = "/my/path"; ts->attribute ("searchpath", TypeDesc::STRING, &path); \end{code} Note that when passing a string, you need to pass a pointer to the {\cf char*}, not a pointer to the first character. (Rationale: for an {\cf int} attribute, you pass the address of the {\cf int}. So for a string, which is a {\cf char*}, you need to pass the address of the string, i.e., a {\cf char**}). The complete list of attributes can be found at the end of this section. \apiend \apiitem{bool {\ce attribute} (const std::string \&name, int val) \\ bool {\ce attribute} (const std::string \&name, float val) \\ bool {\ce attribute} (const std::string \&name, double val) \\ bool {\ce attribute} (const std::string \&name, const char *val) \\ bool {\ce attribute} (const std::string \&name, const std::string \& val)} Specialized versions of {\cf attribute()} in which the data type is implied by the type of the argument. For example, the following are equivalent to the example above for the general (pointer) form of {\cf attribute()}: \begin{code} ts->attribute ("max_open_files", 50); ts->attribute ("searchpath", "/my/path"); \end{code} \apiend \apiitem{bool {\ce getattribute} (const std::string \&name, TypeDesc type, void *val)} \indexapi{getattribute} Gets the current value of an attribute of the \ImageCache. The {\cf name} designates the name of the attribute, {\cf type} describes the type of data, and {\cf val} is a pointer to memory where the user would like the value placed. If the \ImageCache recognizes a valid attribute name that matches the type specified, the attribute value will be stored at address {\cf val} and {\cf attribute()} will return {\cf true}. If {\cf name} is not recognized as a valid attribute name, or if the types do not match (e.g., {\cf type} is {\cf TypeDesc::FLOAT} but the named attribute is a string), no data will be written to {\cf val}, and {\cf attribute()} will return {\cf false}. Here are examples: \begin{code} ImageCache *ts; ... int maxfiles; ts->getattribute ("max_open_files", TypeDesc::INT, &maxfiles); const char *path; ts->getattribute ("searchpath", TypeDesc::STRING, &path); \end{code} Note that when passing a string, you need to pass a pointer to the {\cf char*}, not a pointer to the first character. Also, the {\cf char*} will end up pointing to characters owned by the \ImageCache; the caller does not need to ever free the memory that contains the characters. The complete list of attributes can be found at the end of this section. \apiend \apiitem{bool {\ce getattribute} (const std::string \&name, int \&val) \\ bool {\ce getattribute} (const std::string \&name, float \&val) \\ bool {\ce getattribute} (const std::string \&name, double \&val) \\ bool {\ce getattribute} (const std::string \&name, char **val) \\ bool {\ce getattribute} (const std::string \&name, std::string \& val)} Specialized versions of {\cf getattribute()} in which the data type is implied by the type of the argument. For example, the following are equivalent to the example above for the general (pointer) form of {\cf getattribute()}: \begin{code} int maxfiles; ts->getattribute ("max_open_files", &maxfiles); const char *path; ts->getattribute ("searchpath", &path); \end{code} \apiend \subsubsection*{Image cache attributes} Recognized attributes include the following: \apiitem{int max_open_files} The maximum number of file handles that the image cache will hold open simultaneously. (Default = 100) \apiend \apiitem{float max_memory_MB} The maximum amount of memory (measured in MB) that the image cache will use for its ``tile cache.'' (Default: 256.0 MB) \apiend \apiitem{string searchpath} The search path for images: a colon-separated list of directories that will be searched in order for any image name that is not specified as an absolute path. (Default: no search path.) \apiend \apiitem{string plugin_searchpath} The search path for plugins: a colon-separated list of directories that will be searched in order for any OIIO plugins, if not found in OIIO's ``lib'' directory.) (Default: no additional search path.) \apiend \apiitem{int autotile \\ int autoscanline} These attributes control how the image cache deals with images that are not ``tiled'' (i.e., are stored as scanlines). If {\cf autotile} is set to 0 (the default), an untiled image will be treated as if it were a single tile of the resolution of the whole image. This is simple and fast, but can lead to poor cache behavior if you are simultaneously accessing many large untiled images. If {\cf autotile} is nonzero (e.g., 64 is a good recommended value), any untiled images will be read and cached as if they were constructed in tiles of size: \begin{tabular}{p{2in} p{3in}} {\cf autotile} $\times$ {\cf autotile} & if {\cf autoscanline} is 0 \\ {\cf width} $\times$ {\cf autotile} & if {\cf autoscanline} is nonzero. \\ \end{tabular} In both cases, this should lead more efficient caching. The {\cf autoscanline} determines whether the ``virtual tiles'' in the cache are square (if {\cf autoscanline} is 0, the default) or if they will be as wide as the image (but only {\cf autotile} scanlines high). You should try in your application to see which leads to higher performance. \apiend \apiitem{int automip} If {\cf automip} is set to 0 (the default), an untiled single-subimage file will only be able to utilize that single subimage. If {\cf automip} is nonzero, any untiled, single-subimage (un-MIP-mapped) images will have lower-resolution MIP-map levels generated on-demand if pixels are requested from the lower-res subimages (that don't really exist). Essentially this makes the \ImageCache pretend that the file is MIP-mapped even if it isn't. \apiend \apiitem{int forcefloat} If set to nonzero, all image tiles will be converted to {\cf float} type when stored in the image cache. This can be helpful especially for users of \ImageBuf who want to simplify their image manipulations to only need to consider {\cf float} data. The default is zero, meaning that image pixels are not forced to be {\cf float} when in cache. \apiend \apiitem{int accept_untiled} When nonzero (the default), \ImageCache accepts untiled images as usual. When set to zero, \ImageCache will reject untiled images with an error condition, as if the file could not be properly read. This is sometimes helpful for applications that want to enforce use of tiled images only. \apiend \apiitem{int accept_unmipped} When nonzero (the default), \ImageCache accepts un-MIPmapped images as usual. When set to zero, \ImageCache will reject un-MIPmapped images with an error condition, as if the file could not be properly read. This is sometimes helpful for applications that want to enforce use of MIP-mapped images only. \apiend \apiitem{int failure_retries} When an {\cf open()} or {\cf read_tile()} calls fails, pause and try again, up to {\cf failure_retries} times before truly returning a failure. This is meant to address spooky disk or network failures. The default is zero, meaning that failures of open or tile reading will immediately return as a failure. \apiend \apiitem{int deduplicate} When nonzero, the \ImageCache will notice duplicate images under different names if their headers contain a SHA-1 fingerprint (as is done with \maketx-produced textures) and handle them more efficiently by avoiding redundant reads. The default is 1 (de-duplication turned on). The only reason to set it to 0 is if you specifically want to disable the de-duplication optimization. \apiend \apiitem{string substitute_image} When set to anything other than the empty string, the \ImageCache will use the named image in place of \emph{all} other images. This allows you to run an app using OIIO and (if you can manage to get this option set) automagically substitute a grid, zone plate, or other special debugging image for all image/texture use. \apiend \apiitem{int unassociatedalpha} When nonzero, will request that image format readers try to leave input images with unassociated alpha as they are, rather than automatically converting to associated alpha upon reading the pixels. The default is 0, meaning that the automatic conversion will take place. \apiend \apiitem{string options} This catch-all is simply a comma-separated list of {\cf name=value} settings of named options. For example, \begin{code} ic->attribute ("options", "max_memory_MB=512.0,autotile=1"); \end{code} \apiend \bigskip \subsection{Getting information about images} \label{sec:imagecache:api:getimageinfo} \label{sec:imagecache:api:getimagespec} \apiitem{bool {\ce get_image_info} (ustring filename, int subimage, int miplevel, \\ \bigspc\bigspc ustring dataname, TypeDesc datatype, void *data)} Retrieves information about the image named by {\cf filename}. The {\cf dataname} is a keyword indcating what information should be retrieved, {\cf datatype} is the type of data expected, and {\cf data} points to caller-owned memory where the results should be placed. It is up to the caller to ensure that {\cf data} contains enough space to hold an item of the requested {\cf datatype}. The return value is {\cf true} if {\cf get_image_info()} is able to find the requested {\cf dataname} and it matched the requested {\cf datatype}. If the requested data was not found, or was not of the right data type, {\cf get_image_info()} will return {\cf false}. Supported {\cf dataname} values include: \begin{description} \item[\spc] \spc \vspace{-12pt} \item[\rm \kw{exists}] Return 1 if the file exists and is an image format that OpenImageIO knows how to read, otherwise return 0. The {\cf data} pointer is not used. \item[\rm \kw{subimages}] The number of subimages in the file, as an integer. \item[\rm \kw{resolution}] The resolution of the image file, which is an array of 2 integers (described as {\cf TypeDesc(INT,2)}). \item[\rm \kw{miplevels}] The number of MIPmap levels for the specified subimage (an integer). \item[\rm \kw{texturetype}] A string describing the type of texture of the given file, which describes how the texture may be used (also which texture API call is probably the right one for it). This currently may return one of: \qkw{unknown}, \qkw{Plain Texture}, \qkw{Volume Texture}, \qkw{Shadow}, or \qkw{Environment}. \item[\rm \kw{textureformat}] A string describing the format of the given file, which describes the kind of texture stored in the file. This currently may return one of: \qkw{unknown}, \qkw{Plain Texture}, \qkw{Volume Texture}, \qkw{Shadow}, \qkw{CubeFace Shadow}, \qkw{Volume Shadow}, \qkw{LatLong Environment}, or \qkw{CubeFace Environment}. Note that there are several kinds of shadows and environment maps, all accessible through the same API calls. \item[\rm \kw{channels}] The number of color channels in the file (an integer). \item[\rm \kw{format}] The native data format of the pixels in the file (an integer, giving the {\cf TypeDesc::BASETYPE} of the data). Note that this is not necessarily the same as the data format stored in the image cache. \item[\rm \kw{cachedformat}] The native data format of the pixels as stored in the image cache (an integer, giving the {\cf TypeDesc::BASETYPE} of the data). Note that this is not necessarily the same as the native data format of the file. \item[\rm \kw{datawindow}] Returns the pixel data window of the image, which is either an array of 4 integers (returning xmin, ymin, xmax, ymax) or an array of 6 integers (returning xmin, ymin, zmin, xmax, ymax, zmax). The $z$ values may be useful for 3D/volumetric images; for 2D images they will be 0). \item[\rm \kw{displaywindow}] Returns the display (a.k.a.\ full) window of the image, which is either an array of 4 integers (returning xmin, ymin, xmax, ymax) or an array of 6 integers (returning xmin, ymin, zmin, xmax, ymax, zmax). The $z$ values may be useful for 3D/volumetric images; for 2D images they will be 0). \item[\rm \kw{viewingmatrix}] The viewing matrix, which is a $4 \times 4$ matrix (an {\cf Imath::M44f}, described as {\cf TypeDesc(FLOAT,MATRIX)}). \item[\rm \kw{projectionmatrix}] The projection matrix, which is a $4 \times 4$ matrix (an {\cf Imath::M44f}, described as {\cf TypeDesc(FLOAT,MATRIX)}). \item[Anything else] -- For all other data names, the the metadata of the image file will be searched for an item that matches both the name and data type. \end{description} \apiend \apiitem{bool {\ce get_imagespec} (ustring filename, ImageSpec \&spec,\\ \bigspc int subimage=0, int miplevel=0, bool native=false)} If the named image (and the specific subimage and MIP level) is found and able to be opened by an available image format plugin, and the designated subimage exists, this function copies its image specification for that subimage into {\cf spec} and returns {\cf true}. Otherwise, if the file is not found, could not be opened, is not of a format readable by any plugin that could be found, or the designated subimage did not exist in the file, the return value is {\cf false} and {\cf spec} will not be modified. If {\cf native} is {\cf false} (the default), then the spec retrieved will accurately describe the image stored internally in the cache, whereas if {\cf native} is {\cf true}, the spec retrieved will reflect the original file. These may differ due to use of certain \ImageCache settings such as \qkw{forcefloat} or \qkw{autotile}. \apiend \apiitem{const ImageSpec * {\ce imagespec} (ustring filename, int subimage=0, \\ \bigspc\bigspc\spc int miplevel=0, bool native=false)} If the named image is found and able to be opened by an available image format plugin, and the designated subimage exists, this function returns a pointer to an \ImageSpec that describes it. Otherwise, if the file is not found, could not be opened, is not of a format readable by any plugin that could be find, or the designated subimage did not exist in the file, the return value is NULL. If {\cf native} is {\cf false} (the default), then the spec retrieved will accurately describe the image stored internally in the cache, whereas if {\cf native} is {\cf true}, the spec retrieved will reflect the original file. These may differ due to use of certain \ImageCache settings such as \qkw{forcefloat} or \qkw{autotile}. This method is much more efficient than {\cf get_imagespec()}, since it just returns a pointer to the spec held internally by the \ImageCache (rather than copying the spec to the user's memory). However, the caller must beware that the pointer is only valid as long as nobody (even other threads) calls {\cf invalidate()} on the file, or {\cf invalidate_all()}, or destroys the \ImageCache. \apiend \apiitem{std::string {\ce resolve_filename} (const std::string \&filename)} Returns the true path to the given file name, with searchpath logic applied. \apiend \subsection{Getting pixels} \label{sec:imagecache:api:getpixels} \apiitem{bool {\ce get\_pixels} (ustring filename, int subimage, int miplevel, \\ \bigspc\spc int xbegin, int xend, int ybegin, int yend, \\ \bigspc\spc int zbegin, int zend, \\ \bigspc\spc TypeDesc format, void *result)} Retrieve the rectangle of pixels of the designated {\cf subimage} and {\cf miplevel}, storing the pixel values beginning at the address specified by result. The pixel values will be converted to the type specified by {\cf format}. It is up to the caller to ensure that result points to an area of memory big enough to accommodate the requested rectangle (taking into consideration its dimensions, number of channels, and data format). The rectangular region to be retrieved includes {\cf begin} but does not include {\cf end} (much like STL begin/end usage). Requested pixels that are not part of the valid pixel data region of the image file will be filled with zero values. \apiend \apiitem{bool {\ce get\_pixels} (ustring filename, int subimage, int miplevel, \\ \bigspc\spc int xbegin, int xend, int ybegin, int yend, \\ \bigspc\spc int zbegin, int zend, int chbegin, int chend,\\ \bigspc\spc TypeDesc format, void *result, \\ \bigspc\spc stride_t xstride, stride_t ystride, stride_t zstride)} Retrieve the rectangle of pixels and subset of channels of the designated {\cf subimage} and {\cf miplevel}, storing the pixel values beginning at the address specified by result and with the given strides. The pixel values will be converted to the type specified by {\cf format}. It is up to the caller to ensure that result points to an area of memory big enough to accommodate the requested rectangle (taking into consideration its dimensions, number of channels, data format, and strides). Any stride values set to {\cf AutoStride} will be assumed to indicate a contiguous data layout. The rectangular region and channel set to be retrieved includes {\cf begin} but does not include {\cf end} (much like STL begin/end usage). Requested pixels that are not part of the valid pixel data region of the image file will be filled with zero values. \apiend \subsection{Dealing with tiles} \label{sec:imagecache:api:tiles} \apiitem{ImageCache::Tile * {\ce get_tile} (ustring filename, int subimage, int miplevel, \\ \bigspc \bigspc int x, int y, int z)} Find a tile given by an image {\cf filename}, {\cf subimage}, and pixel coordinates. An opaque pointer to the tile will be returned, or {\cf NULL} if no such file (or tile within the file) exists or can be read. The tile will not be purged from the cache until after {\cf release_tile()} is called on the tile pointer. This is thread-safe. \apiend \apiitem{void {\ce release_tile} (ImageCache::Tile *tile)} After finishing with a tile, {\cf release_tile()} will allow it to once again be purged from the tile cache if required. \apiend \apiitem{const void * {\ce tile_pixels} (ImageCache::Tile *tile, TypeDesc \&format)} For a tile retrived by {\cf get_tile()}, return a pointer to the pixel data itself, and also store in {\cf format} the data type that the pixels are internally stored in (which may be different than the data type of the pixels in the disk file). This method should only be called on a tile that has been requested by {\cf get_tile()} but has not yet been released with {\cf release_tile()}. \apiend \apiitem{void {\ce invalidate} (ustring filename)} Invalidate any loaded tiles or open file handles associated with the filename, so that any subsequent queries will be forced to re-open the file or re-load any tiles (even those that were previously loaded and would ordinarily be reused). A client might do this if, for example, they are aware that an image being held in the cache has been updated on disk. This is safe to do even if other procedures are currently holding reference-counted tile pointers from the named image, but those procedures will not get updated pixels until they release the tiles they are holding. \apiend \apiitem{void {\ce invalidate_all} (bool force=false)} Invalidate all loaded tiles and open file handles, so that any subsequent queries will be forced to re-open the file or re-load any tiles (even those that were previously loaded and would ordinarily be reused). A client might do this if, for example, they are aware that an image being held in the cache has been updated on disk. This is safe to do even if other procedures are currently holding reference-counted tile pointers from the named image, but those procedures will not get updated pixels until they release the tiles they are holding. If force is true, everything will be invalidated, no matter how wasteful it is, but if force is false, in actuality files will only be invalidated if their modification times have been changed since they were first opened. \apiend \subsection{Seeding the cache} \label{sec:imagecache:api:seeding} \NEW % 1.3 \apiitem{bool {\ce add_file} (ustring filename, ImageInput::Creator creator)} This creates a file entry in the cache that, instead of reading from disk, uses a custom \ImageInput to generate the image (note that it will have no effect if there's already an image by the same name in the cache). The {\cf creator} is a factory that creates the custom \ImageInput and will be called like this: \begin{code} ImageInput *in = creator(); \end{code} Once created, the \ImageCache owns the \ImageInput and is responsible for destroying it when done. Custom \ImageInput's allow ``procedural'' images, among other things. Also, this is the method you use to set up a ``writeable'' \ImageCache images (perhaps with a type of \ImageInput that's just a stub that does as little as possible). \apiend \apiitem{bool {\ce add_tile} (ustring filename, int subimage, int miplevel,\\ \bigspc int x, int y, int z, TypeDesc format, const void *buffer,\\ \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride} \NEW % 1.3 Preemptively add a tile corresponding to the named image, at the given subimage and MIP level. The tile added is the one whose corner is (x,y,z), and buffer points to the pixels (in the given format, with supplied strides) which will be copied and inserted into the cache and made available for future lookups. \apiend \subsection{Errors and statistics} \label{sec:imagecache:api:geterror} \label{sec:imagecache:api:getstats} \label{sec:imagecache:api:resetstats} \apiitem{std::string {\ce geterror} ()} \index{error checking} If any other API routines return {\cf false}, indicating that an error has occurred, this routine will retrieve the error and clear the error status. If no error has occurred since the last time {\cf geterror()} was called, it will return an empty string. \apiend \apiitem{std::string {\ce getstats} (int level=1)} Returns a big string containing useful statistics about the \ImageCache operations, suitable for saving to a file or outputting to the terminal. The {\cf level} indicates the amount of detail in the statistics, with higher numbers (up to a maximum of 5) yielding more and more esoteric information. \apiend \apiitem{void {\ce reset_stats} ()} Reset most statistics to be as they were with a fresh \TextureSystem. Caveat emptor: this does not flush the cache itelf, so the resulting statistics from the next set of texture requests will not match the number of tile reads, etc., that would have resulted from a new \TextureSystem. \apiend \index{Image Cache|)} \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/imagebuf.tex0000644000175000017500000010505712271062644020166 0ustar mfvmfv\chapter{Image Buffers} \label{chap:imagebuf} \index{Image Buffers|(} \index{ImageBuf|(} \section{ImageBuf Introduction and Theory of Operation} \label{sec:imagebuf:intro} \ImageBuf is a utility class that stores an entire image. It provides a nice API for reading, writing, and manipulating images as a single unit, without needing to worry about any of the details of storage or I/O. \smallskip \noindent An \ImageBuf can store its pixels in one of several ways: \begin{itemize} \item Allocate ``local storage'' to hold the image pixels internal to the \ImageBuf. This storage will be freed when the \ImageBuf is destroyed. \item ``Wrap'' pixel memory already allocated by the calling application, which will continue to own that memory and be responsible for freeing it after the \ImageBuf is destroyed. \item Be ``backed'' by an \ImageCache, which will automatically be used to retreive pixels when requested, but the \ImageBuf will not allocate separate storage for it. This brings all the advantages of the \ImageCache, but can only be used for read-only \ImageBuf's that reference a stored image file. \end{itemize} All I/O involving \ImageBuf (that is, calls to {\cf read} or {\cf write}) are implemented in terms of \ImageCache, \ImageInput, and \ImageOutput underneath, and so support all of the image file formats supported by OIIO. \smallskip \noindent The \ImageBuf class definition requires that you \begin{code} #include \end{code} \subsection{Helper: \ROI} \label{sec:ROI} \indexapi{ROI} \index{region of interest} \ROI is a small helper struct that describes a rectangular region of pixels of an image (and a channel range). An \ROI holds the following data members: \apiitem{int xbegin, xend, ybegin, yend, zbegin, zend; \\ int chbegin, chend;} Describes the $x, y, z$ range of the region. The {\cf end} values are \emph{exclusive}; that is, ({\cf xbegin, ybegin, zbegin}) is the first pixel included in the range, ({\cf xend-1, yend-1, zend-1}) is the last pixel included in the range, and ({\cf xend, yend, zend}) is \emph{one past the last pixel} in each dimension. Similarly, {\cf chbegin} and {\cf chend} describe a range of channels: {\cf chbegin} is the first channel, {\cf chend} is \emph{one past the last channel}. \apiend \smallskip \noindent \ROI has the following member functions and friends: \smallskip \apiitem{ROI ()} A default-constructed \ROI has an \emph{undefined} region, which is interpreted to mean all valid pixels and all valid channels of an image. \apiend \apiitem{bool ROI::defined () const} Returns {\cf true} if the \ROI is defined, having a specified region, or {\cf false} if the \ROI is undefined. \apiend \apiitem{static ROI ROI::All ()} Returns an undefined \ROI, which is interpreted to mean all valid pixels and all valid channels of an image. \apiend \apiitem{int ROI::width () const \\ int ROI::height () const \\ int ROI::depth () const} Returns the width, height, and depth, respectively, of a defined region. These do not return sensible values for an \ROI that is not {\cf defined()}. \apiend \apiitem{imagesize_t ROI::npixels () const} For an \ROI that is {\cf defined()}, returns the total number of pixels included in the region, or {\cf 0} for an undefined \ROI. \apiend \apiitem{imagesize_t ROI::nchannels () const} For an \ROI that is {\cf defined()}, returns the number of channels in the channel range. \apiend \apiitem{ROI roi_union (const ROI \&A, const ROI \&B) \\ ROI roi_intersection (const ROI \&A, const ROI \&B)} Returns the union of two \ROI's (an \ROI that is exactly big enough to include all the pixels of both individual \ROI's) or intersection of two \ROI's (an \ROI that contains only the pixels that are contained in \emph{both} \ROI's). \apiend \apiitem{ROI get_roi (const ImageSpec \&spec) \\ ROI get_roi_full (const ImageSpec \&spec)} Return the ROI describing {\cf spec}'s pixel data window (the {\cf x, y, z, width, height, depth} fields) or the full (display) window (the {\cf full_x, full_y, full_z, full_width, full_height, full_depth} fields), respectively. \apiend \apiitem{void set_roi (const ImageSpec \&spec, const ROI \&newroi) \\ void set_roi_full (const ImageSpec \&spec, const ROI \&newroi)} Alters the {\cf spec} so to make its pixel data window or the full (display) window match {\cf newroi}. \apiend \section{Constructing, reading, and writing an \ImageBuf} \subsection*{Default constructor of an empty \ImageBuf} \apiitem{ImageBuf ()} The default constructor makes an uninitialized \ImageBuf. There isn't much you can do with an uninitialized buffer until you call {\cf reset()}. \apiend \apiitem{void clear ()} Resets the \ImageBuf to a pristine state identical to that of a freshly constructed \ImageBuf using the default constructor. \apiend \subsection*{Constructing and initializing a writeable \ImageBuf} \apiitem{ImageBuf (const ImageSpec \&spec) \\ ImageBuf (const std::string \&name, const ImageSpec \&spec)} Constructs a writeable \ImageBuf with the given specification (including resolution, data type, metadata, etc.), initially set to all black pixels. Optionally, you may name the \ImageBuf. \apiend \apiitem{void reset (const ImageSpec \&spec) \\ void reset (const std::string \&name, const ImageSpec \&spec)} Destroys any previous contents of the \ImageBuf and re-initializes it as a writeable all-black \ImageBuf with the given specification (including resolution, data type, metadata, etc.). Optionally, you may name the \ImageBuf. \apiend \subsection*{Constructing a readable \ImageBuf and reading from a file} Constructing a readable \ImageBuf that will hold an image to be read from disk. \apiitem{ImageBuf (const std::string \&name, int subimage=0, int miplevel=0, \\ \bigspc\bigspc ImageCache *imagecache=NULL)} Construct an \ImageBuf that will be used to read the named file (at the given subimage and MIP-level, defaulting to the first in the file). But don't read it yet! The image will actually be read when other methods need to access the spec and/or pixels, or when an explicit call to {\cf init_spec()} or {\cf read()} is made, whichever comes first. If {\cf imagecache} is non-NULL, the custom \ImageCache will be used (if applicable); otherwise, a NULL imagecache indicates that the global/shared \ImageCache should be used. \apiend \apiitem{void reset (const std::string \&name, int subimage=0, int miplevel=0, \\ \bigspc\bigspc ImageCache *imagecache = NULL)} Destroys any previous contents of the \ImageBuf and re-initializes it to read the named file (but doesn't actually read yet). \apiend \apiitem{bool read (int subimage=0, int miplevel=0, bool force=false, \\ \bigspc TypeDesc convert=TypeDesc::UNKNOWN, \\ \bigspc ProgressCallback progress_callback=NULL, \\ \bigspc void *progress_callback_data=NULL)} Explicitly reads the particular subimage and MIP level of the image. Generally, this will skip the expensive read if the file has already been read into the \ImageBuf (at the specified subimage and MIP level). It will clear and re-allocate memory if the previously allocated space was not appropriate for the size or data type of the image being read. If {\cf convert} is set to a specific type (not {\cf UNKNOWN}), the \ImageBuf memory will be allocated for that type specifically and converted upon read. In general, {\cf read()} will try not to do any I/O at the time of the {\cf read()} call, but rather to have the \ImageBuf ``backed'' by an \ImageCache, which will do the file I/O on demand, as pixel values are needed, and in that case the \ImageBuf doesn't actually allocate memory for the pixels (the data lives in the \ImageCache). However, there are several conditions for which the \ImageCache will be bypassed, the \ImageBuf will allocate ``local'' memory, and the disk file will be read directly into allocated buffer at the time of the {\cf read()} call: (a) if the {\cf force} parameter is {\cf true}; (b) if the {\cf convert} parameter requests a data format conversion to a type that is not the native file type and also is not one of the internal types supported by the {\cf ImageCache} (specifically, {\cf FLOAT} and {\cf UINT8}); (c) if the \ImageBuf already has local pixel memory allocated, or ``wraps'' an application buffer. If {\cf progress_callback} is non-NULL, the underlying read, if expensive, may make several calls to \begin{code} progress_callback(progress_callback_data, portion_done); \end{code} \noindent which allows you to implement some sort or progress meter. Note that if the \ImageBuf is backed by an \ImageCache, the progress callback will never be called, since no actual file I/O will occur at this time (\ImageCache will load tiles or scanlines on demand, as individual pixel values are needed). \NEW % 1.3 Note that {\cf read()} is not strictly necessary. If you are happy with the filename, subimage and MIP level specified by the \ImageBuf constructor (or the last call to {\cf reset()}), and you want the storage to be backed by the {\cf ImageCache} (including storing the pixels in whatever data format that implies), then the file contents will be automatically read the first time you make any other \ImageBuf API call that requires the spec or pixel values. The only reason to call {\cf read()} yourself is if you are changing the filename, subimage, or MIP level, or if you want to use {\cf force=true} or a specific {\cf convert} value to force data format conversion. \apiend \apiitem{bool init_spec (const std::string \&filename, int subimage, int miplevel)} This call will read the \ImageSpec for the given file, subimage, and MIP level into the \ImageBuf, but will not read the pixels or allocate any local storage (until a subsequent call to {\cf read()}). This is helpful if you have an \ImageBuf and you need to know information about the image, but don't want to do a full read yet, and maybe won't need to do the full read, depending on what's found in the spec. \NEW % 1.3 Note that {\cf init_spec()} is not strictly necessary. If you are happy with the filename, subimage and MIP level specified by the \ImageBuf constructor (or the last call to {\cf reset()}), then the spec will be automatically read the first time you make any other \ImageBuf API call that requires it. The only reason to call {\cf read()} yourself is if you are changing the filename, subimage, or MIP level, or if you want to use {\cf force=true} or a specific {\cf convert} value to force data format conversion. \apiend \subsection*{Constructing an \ImageBuf that ``wraps'' an application buffer} \apiitem{ImageBuf (const ImageSpec \&spec, void *buffer) \\ ImageBuf (const std::string \&name, const ImageSpec \&spec, void *buffer)} Constructs an ImageBuf that "wraps" a memory buffer owned by the calling application. It can write pixels to this buffer, but can't change its resolution or data type. Optionally, it names the \ImageBuf. \apiend \subsection*{Writing an \ImageBuf to a file} \apiitem{bool write (const std::string \&filename, \\ \bigspc const std::string \&fileformat = std::string(), \\ \bigspc ProgressCallback progress_callback=NULL, \\ \bigspc void *progress_callback_data=NULL) const} \NEW % 1.3 Write the image to the named file in the named format (an empty format means to infer the type from the filename extension). Return {\cf true} if all went ok, {\cf false} if there were errors writing. By default, it will always write a scanline-oriented file, unless the {\cf set_write_tiles()} method has been used to override this. Also, it will use the data format of the buffer itself, unless the {\cf set_write_format()} method has been used to override the data format. \apiend \apiitem{bool write (ImageOutput *out, \\ \bigspc ProgressCallback progress_callback=NULL, \\ \bigspc void *progress_callback_data=NULL) const} Write the image to the open \ImageOutput {\cf out}. Return {\cf true} if all went ok, {\cf false} if there were errors writing. It does NOT close the file when it's done (and so may be called in a loop to write a multi-image file). \apiend \apiitem{void set_write_format (TypeDesc format=TypeDesc::UNKNOWN) \\ set set_write_tiles (int width=0, int height=0, int depth=0)} \NEW % 1.3 These methods allow the caller to override the data format and tile sizing when using the {\cf write()} function (the variety that does not take an open {\cf ImageOutput*}). \apiend \section{Getting and setting basic information about an \ImageBuf} \apiitem{bool initialized () const} Returns {\cf true} if the \ImageBuf is initialized, {\cf false} if not yet initialized. \apiend \apiitem{IBStorage {\ce storage} () const} \NEW % 1.3 Returns an enumerated type describing the type of storage currently employed by the \ImageBuf: {\cf UNINITIALIZED} (no storage), {\cf LOCALBUFFER} (the \ImageBuf has allocated and owns the pixel memory), {\cf APPBUFFER} (the \ImageBuf ``wraps'' memory owned by the calling application), or {\cf IMAGECACHE} (the image is backed by an \ImageCache). \apiend \apiitem{const ImageSpec \& spec () const \\ const ImageSpec \& nativespec () const} The {\cf spec()} function returns a {\cf const} reference to an \ImageSpec that describes the image data held by the \ImageBuf. The {\cf nativespec()} function returns a {\cf const} reference to an \ImageSpec that describes the actual data in the file that was read. These may differ --- for example, if a data format conversion was requested, if the buffer is backed by an \ImageCache which stores the pixels internally in a different data format than that of the file, or if the file had differing per-channel data formats (\ImageBuf must contain a single data format for all channels). \apiend \apiitem{const std::string \& name (void) const} Returns the name of the buffer (name of the file, for an \ImageBuf read from disk). \apiend \apiitem{const std::string \& file_format_name (void) const} Returns the name of the file format, for an \ImageBuf read from disk (for example, \qkw{openexr}). \apiend \apiitem{int subimage () const \\ int nsubimages () const \\ int miplevel () const \\ int nmiplevels () const} The {\cf subimage()} and {\cf miplevel()} methods return the subimage and MIP level of the image held by the \ImageBuf (the file it came from may hold multiple subimages and/or MIP levels, but the \ImageBuf can only store one of those at any given time). The {\cf nsubimages()} method returns the total number of subimages in the file, and the {\cf nmiplevels()} method returns the total number of MIP levels in the currently-loaded subimage. \apiend \apiitem{int nchannels () const} Returns the number of channels stored in the buffer (this is equivalent to {\cf spec().nchannels}). \apiend \apiitem{int xbegin () const \\ int xend () const \\ int ybegin () const \\ int yend () const \\ int zbegin () const \\ int zend () const} Returns the {\cf [begin,end)} range of the pixel data window of the buffer. These are equivalent to {\cf spec().x}, {\cf spec().x+spec().width}, {\cf spec().y}, {\cf spec().y+spec().height}, {\cf spec().z}, and {\cf spec().z+spec().depth}, respectively. \apiend \apiitem{int orientation () const \\ int oriented_width () const \\ int oriented_height () const \\ int oriented_x () const \\ int oriented_y () const \\ int oriented_full_width () const \\ int oriented_full_height () const \\ int oriented_full_x () const \\ int oriented_full_y () const } The {\cf orientation()} returns the interpretation of the layout (top/bottom, left/right) of the image, per the table in Section~\ref{metadata:orientation}. The oriented width, height, x, and y describe the pixel data window after taking the display orientation into consideration. The \emph{full} versions the ``full'' (a.k.a.\ display) window after taking the display orientation into consideration. \apiend \apiitem{TypeDesc pixeltype () const} The data type of the pixels stored in the buffer (equivalent to {\cf spec().format}). \apiend \apiitem{void set_full (int xbegin, int xend, int ybegin, int yend, \\ \bigspc\spc int zbegin, int zend)} Alters the metadata of the spec in the \ImageBuf to reset the ``full'' image size (a.k.a.\ ``display window''). This does not affect the size of the pixel data window. \apiend \apiitem{ImageSpec \& specmod ()} This returns a \emph{writeable} reference to the \ImageSpec describing the buffer. It's ok to modify most of the metadata, but if you modify the spec's {\cf format}, {\cf width}, {\cf height}, or {\cf depth} fields, you get the pain you deserve, as the \ImageBuf will no longer have correct knowledge of its pixel memory layout. USE WITH EXTREME CAUTION. \apiend \section{Copying \ImageBuf's and blocks of pixels} \apiitem{bool copy (const ImageBuf \&src)} Copies {\cf src} to {\cf this} -- both pixel values and all metadata. \apiend \apiitem{void copy_metadata (const ImageBuf \&src)} Copies all metadata (except for {\cf format}, {\cf width}, {\cf height}, {\cf depth} from {\cf src} to {\cf this}. \apiend \apiitem{bool copy_pixels (const ImageBuf \&src)} Copies the pixels of {\cf src} to {\cf this}, but does not change the metadata (other than format and resolution) of {\cf this}. \apiend \apiitem{void swap (ImageBuf \&other)} Swaps the entire contents of {\cf other} and {\cf this}. \apiend \apiitem{bool get_pixel_channels (int xbegin, int xend, int ybegin, int yend, \\ \bigspc\bigspc int zbegin, int zend, int chbegin, int chend,\\ \bigspc\bigspc TypeDesc format, void *result,\\ \bigspc\bigspc stride_t xstride=AutoStride,\\ \bigspc\bigspc stride_t ystride=AutoStride,\\ \bigspc\bigspc stride_t zstride=AutoStride) const} Retrieve the rectangle of pixels spanning {\cf [xbegin..xend)} $\times$ {\cf [ybegin..yend)} $\times$ {\cf [zbegin..zend)}, channels {\cf [chbegin,chend)} (all with exclusive end), specified as integer pixel coordinates, at the current subimage and MIP-map level, storing the pixel values beginning at the address specified by {\cf result} and with the given strides (by default, {\cf AutoStride} means the usual contiguous packing of pixels) and converting into the data type described by {\cf format}. It is up to the caller to ensure that {\cf result} points to an area of memory big enough to accommodate the requested rectangle. Return {\cf true} if the operation could be completed, otherwise return {\cf false}. \apiend \apiitem{bool get_pixels (int xbegin, int xend, int ybegin, int yend, \\ \bigspc\bigspc int zbegin, int zend, TypeDesc format, \\ \bigspc\bigspc void *result, stride_t xstride=AutoStride,\\ \bigspc\bigspc stride_t ystride=AutoStride, \\ \bigspc\bigspc stride_t zstride=AutoStride) const} Retrieve the rectangle of pixels spanning {\cf [xbegin..xend)} $\times$ {\cf [ybegin..yend)} $\times$ {\cf [zbegin..zend)} (all with exclusive end), specified as integer pixel coordinates, at the current subimage and MIP-map level, storing the pixel values beginning at the address specified by {\cf result} and with the given strides (by default, {\cf AutoStride} means the usual contiguous packing of pixels) and converting into the data type described by {\cf format}. It is up to the caller to ensure that {\cf result} points to an area of memory big enough to accommodate the requested rectangle. Return {\cf true} if the operation could be completed, otherwise return {\cf false}. \apiend \section{Getting and setting individual pixel values -- simple but slow} \apiitem{float getchannel (int x, int y, int z, int c, \\ \bigspc\spc WrapMode wrap=WrapBlack) const} Returns the value of pixel {\cf x, y, z}, channel {\cf c}. The {\cf wrap} describes what value should be returned if the {\cf x, y, z} coordinates are outside the pixel data window, and may be one of: {\cf WrapBlack}, {\cf WrapClamp}, {\cf WrapPeriodic}, or {\cf WrapMirror}. \apiend \apiitem{void getpixel (int x, int y, int z, float *pixel, \\ \bigspc\spc int maxchannels=1000, WrapMode wrap=WrapBlack) const} Retrieves pixel ({\cf x, y, z}), placing its contents in {\cf pixel[0..n-1]}, where $n$ is the smaller of {\cf maxchannels} or the actual number of channels stored in the buffer. It is up to the application to ensure that {\cf pixel} points to enough memory to hold the required number of channels. The {\cf wrap} describes what value should be returned if the {\cf x, y, z} coordinates are outside the pixel data window, and may be one of: {\cf WrapBlack}, {\cf WrapClamp}, {\cf WrapPeriodic}, or {\cf WrapMirror}. \apiend \apiitem{void interppixel_NDC_full (float s, float t, float *pixel, \\ \bigspc WrapMode wrap=WrapBlack) const} Given 2D floating point image-space coordinates ({\cf s, t}), linearly interpolate the surrounding pixels to yield interpolated value {\cf pixel[0..n-1]}, where $n$ is the smaller of {\cf maxchannels} or the actual number of channels stored in the buffer. It is up to the application to ensure that {\cf pixel} points to enough memory to hold the required number of channels. The coordinates {\cf (s,t)} are in \emph{image space}, where (0,0) is the upper left corner of the full (a.k.a. ``display'') window and (1,1) is the lower right cornell of the full/display window. The {\cf wrap} describes how the image function should be computed outside the boundaries of the pixel data window, and may be one of: {\cf WrapBlack}, {\cf WrapClamp}, {\cf WrapPeriodic}, or {\cf WrapMirror}. \apiend \apiitem{void setpixel (int x, int y, int z, const float *pixel, int maxchannels=1000)} Set the pixel with coordinates {\cf (x, y, z)} to have the values {\cf pixel[0..n-1]}. The number of channels, {\cf n}, is the minimum of {\cf minchannels} and the actual number of channels in the image. \apiend \subsection*{Deep data in an \ImageBuf} \apiitem{bool deep () const} Returns {\cf true} if the \ImageBuf holds a ``deep'' image, {\cf false} if the \ImageBuf holds an ordinary pixel-based image. \apiend \apiitem{int deep_samples (int x, int y, int z=0) const} Returns the number of deep samples for the given pixel, or 0 if there are no deep samples for that pixel (including if the pixel coordinates are outside the data area). For non-deep images, it will always return 0. \apiend \apiitem{const void *deep_pixel_ptr (int x, int y, int z, int c) const} Returns a pointer to the raw array of deep samples for channel {\cf c} of pixel {\cf (x,y,z)}. This will return {\cf NULL} if the pixel coordinates or channel number are out of range, if the pixel/channel has no deep samples, or if the image is not deep. \apiend \apiitem{float deep_value (int x, int y, int z, int c, int s) const} Return the value (as a {\cf float}) of sample {\cf s} of channel {\cf c} of pixel {\cf (x,y,z)}. Return {\cf 0.0} if not a deep image or if the pixel coordinates, channel number, or sample number are out of range, or if it has no deep samples. \apiend \section{Miscellaneous} \apiitem{void error (const char *format, ...) const} This can be used to register an error associated with this \ImageBuf. \apiend \apiitem{bool has_error (void) const} Returns {\cf true} if the \ImageBuf has had an error and has an error message to retrieve via {\cf geterror()}. \apiend \apiitem{std::string geterror (void) const} Return the text of all error messages issued since {\cf geterror()} was called (or an empty string if no errors are pending). This also clears the error message for next time. \apiend \apiitem{void *localpixels (); \\ const void *localpixels () const;} Returns a raw pointer to the ``local'' pixel memory, if they are fully in RAM and not backed by an \ImageCache (in which case, {\cf NULL} will be returned). You can also test it like a {\cf bool} to find out if pixels are local. \apiend \apiitem{const void *pixeladdr (int x, int y, int z=0) const \\ void *pixeladdr (int x, int y, int z)} Return the address where pixel (x,y,z) is stored in the image buffer. Use with extreme caution! Will return NULL if the pixel values aren't local (for example, if backed by an \ImageCache). \apiend \section{Iterators -- the fast way of accessing individual pixels} Sometimes you need to visit every pixel in an \ImageBuf (or at least, every pixel in a large region). Using the {\cf getpixel} and {\cf setpixel} for this purpose is simple but very slow. But \ImageBuf provides templated {\cf Iterator} and {\cf ConstIterator} types that are very inexpensive and hide all the details of local versus cached storage. An {\cf Iterator} is associated with a particular \ImageBuf. The {\cf Iterator} has a \emph{current pixel} coordinate that it is visiting, and an \emph{iteration range} that describes a rectangular region of pixels that it will visits as it advances. It always starts at the upper left corner of the iteration region. We say that the iterator is \emph{done} after it has visited every pixel in its iteration range. We say that a pixel coordinate \emph{exists} if it is within the pixel data window of the \ImageBuf. We say that a pixel coordinate is \emph{valid} if it is within the iteration range of the iterator. The {\cf ImageBuf::ConstIterator} is identical to the {\cf Iterator}, except that {\cf ConstIterator} may be used on a {\cf const ImageBuf} and may not be used to alter the contents of the \ImageBuf. For simplicity, the remainder of this section will only discuss the {\cf Iterator}. The {\cf Iterator} is templated based on two types: {\cf BUFT} the type of the data stored in the \ImageBuf, and {\cf USERT} type type of the data that you want to manipulate with your code. {\cf USERT} defaults to {\cf float}, since usually you will want to do all your pixel math with {\cf float}. We will thus use {\cf Iterator} synonymously with {\cf Iterator}. For the remainder of this section, we will assume that you have a {\cf float}-based \ImageBuf, for example, if it were set up like this: \begin{code} ImageBuf buf ("myfile.exr"); buf.read (0, 0, true, TypeDesc::FLOAT); \end{code} \apiitem{Iterator (ImageBuf \&buf, WrapMode wrap=WrapDefault)} Initialize an iterator that will visit every pixel in the data window of {\cf buf}, and start it out pointing to the upper left corner of the data window. The {\cf wrap} describes what values will be retrieved if the iterator is positioned outside the data window of the buffer. \apiend \apiitem{Iterator (ImageBuf \&buf, const ROI \&roi, WrapMode wrap=WrapDefault)} Initialize an iterator that will visit every pixel of {\cf buf} within the region described by {\cf roi}, and start it out pointing to pixel ({\cf roi.xbegin, roi.ybegin, roi.zbegin}). The {\cf wrap} describes what values will be retrieved if the iterator is positioned outside the data window of the buffer. \apiend \apiitem{Iterator (ImageBuf \&buf, int x, int y, int z, WrapMode wrap=WrapDefault)} Initialize an iterator that will visit every pixel in the data window of {\cf buf}, and start it out pointing to pixel ({\cf x, y, z}). The {\cf wrap} describes what values will be retrieved if the iterator is positioned outside the data window of the buffer. \apiend \apiitem{Iterator::operator++ ()} The {\cf ++} operator advances the iterator to the next pixel in its iteration range. (Both prefix and postfix increment operator are supported.) \apiend \apiitem{bool Iterator::done () const} Returns {\cf true} if the iterator has completed its visit of all pixels in its iteration range. \apiend \apiitem{ROI Iterator::range () const} Returns the iteration range of the iterator, expressed as an \ROI. \apiend \apiitem{int Iterator::x () const \\ int Iterator::y () const \\ int Iterator::z () const} Returns the $x$, $y$, and $z$ pixel coordinates, respectively, of the pixel that the iterator is currently visiting. \apiend \apiitem{bool Iterator::valid () const} Returns {\cf true} if the iterator's current pixel coordinates are within its iteration range. \apiend \apiitem{bool Iterator::valid (int x, int y, int z=0) const} Returns {\cf true} if pixel coordinate ({\cf x, y, z}) are within the iterator's iteration range (regardless of where the iterator itself is currently pointing). \apiend \apiitem{bool Iterator::exists () const} Returns {\cf true} if the iterator's current pixel coordinates are within the data window of the \ImageBuf. \apiend \apiitem{bool Iterator::exists (int x, int y, int z=0) const} Returns {\cf true} if pixel coordinate ({\cf x, y, z}) are within the pixel data window of the \ImageBuf (regardless of where the iterator itself is currently pointing). \apiend \apiitem{USERT\& Iterator::operator[] (int i)} The value of channel {\cf i} of the current pixel. (The wrap mode, set up when the iterator was constructed, determines what value is returned if the iterator points outside the pixel data window of its buffer.) \apiend \apiitem{int Iterator::deep_samples () const} For deep images only, retrieves the number of deep samples for the current pixel. \apiend \apiitem{USERT\& Iterator::deep_value (int c, int s)} For deep images only, returns the value of channel {\cf c}, sample number {\cf s}, at the current pixel. \apiend \subsection*{Example: Visiting all pixels to compute an average color} \begin{code} void print_channel_averages (const std::string &filename) { // Set up the ImageBuf and read the file ImageBuf buf (filename); bool ok = buf.read (0, 0, true, TypeDesc::FLOAT); // Force a float buffer if (! ok) return; // Initialize a vector to contain the running total int nc = buf.nchannels(); std::vector total (n, 0.0f); // Iterate over all pixels of the image, summing channels separately for (ImageBuf::ConstIterator it (buf); ! it.done(); ++it) for (int c = 0; c < nc; ++c) total[c] += it[c]; // Print the averages imagesize_t npixels = buf.spec().image_pixels(); for (int c = 0; c < nc; ++c) std::cout << "Channel " << c << " avg = " (total[c] / npixels) << "\n"; } \end{code} \subsection*{Example: Set all pixels in a region to black} \label{makeblackexample} \begin{code} bool make_black (ImageBuf &buf, ROI region) { if (buf.spec().format != TypeDesc::FLOAT) return false; // Assume it's a float buffer // Clamp the region's channel range to the channels in the image roi.chend = std::min (roi.chend, buf.nchannels); // Iterate over all pixels in the region... for (ImageBuf::Iterator it (buf, region); ! it.done(); ++it) { if (! it.exists()) // Make sure the iterator is pointing continue; // to a pixel in the data window for (int c = roi.chbegin; c < roi.chend; ++c) it[c] = 0.0f; // clear the value } return true; } \end{code} \section{Dealing with buffer data types} The previous section on iterators presented examples and discussion based on the assumption that the \ImageBuf was guaranteed to store {\cf float} data and that you wanted all math to also be done as {\cf float} computations. Here we will explain how to deal with buffers and files that contain different data types. \subsection*{Strategy 1: Only have {\cf float} data in your \ImageBuf} \noindent When creating your own buffers, make sure they are {\cf float}: \begin{code} ImageSpec spec (640, 480, 3, TypeDesc::FLOAT); // <-- float buffer ImageBuf buf ("mybuf", spec); \end{code} \noindent When using \ImageCache-backed buffers, force the \ImageCache to convert everything to {\cf float}: \begin{code} // Just do this once, to set up the cache: ImageCache *cache = ImageCache::create (true /* shared cache */); cache->attribute ("forcefloat", 1); ... ImageBuf buf ("myfile.exr"); // Backed by the shared cache \end{code} \noindent Or force the read to convert to {\cf float} in the buffer if it's not a native type that would automatically stored as a {\cf float} internally to the \ImageCache:\footnote{\ImageCache only supports a limited set of types internally, currently only FLOAT and UINT8, and all other data types are converted to these automatically as they are read into the cache.} \begin{code} ImageBuf buf ("myfile.exr"); // Backed by the shared cache buf.read (0, 0, false /* don't force read to local mem */, TypeDesc::FLOAT /* but do force conversion to float*/); \end{code} \noindent Or force a read into local memory unconditionally (rather than relying on the \ImageCache), and convert to {\cf float}: \begin{code} ImageBuf buf ("myfile.exr"); buf.read (0, 0, true /*force read*/, TypeDesc::FLOAT /* force conversion */); \end{code} \subsection*{Strategy 2: Template your iterating functions based on buffer type} Consider the following alternate version of the {\cf make_black} function from Section~\ref{makeblackexample}: \begin{code} template static bool make_black_impl (ImageBuf &buf, ROI region) { // Clamp the region's channel range to the channels in the image roi.chend = std::min (roi.chend, buf.nchannels); // Iterate over all pixels in the region... for (ImageBuf::Iterator it (buf, region); ! it.done(); ++it) { if (! it.exists()) // Make sure the iterator is pointing continue; // to a pixel in the data window for (int c = roi.chbegin; c < roi.chend; ++c) it[c] = 0.0f; // clear the value } return true; } bool make_black (ImageBuf &buf, ROI region) { if (buf.spec().format == TypeDesc::FLOAT) return make_black_impl (buf, region); else if (buf.spec().format == TypeDesc::HALF) return make_black_impl (buf, region); else if (buf.spec().format == TypeDesc::UINT8) return make_black_impl (buf, region); else if (buf.spec().format == TypeDesc::UINT16) return make_black_impl (buf, region); else { buf.error ("Unsupported pixel data format %s", buf.spec().format); retrn false; } } \end{code} In this example, we make an implementation that is templated on the buffer type, and then a wrapper that calls the appropriate template specialization for each of 4 common types (and logs an error in the buffer for any other types it encounters). In fact, {\cf imagebufalgo_util.h} provides a macro to do this (and several variants, which will be discussed in more detail in the next chapter). You could rewrite the example even more simply: \begin{code} #include template static bool make_black_impl (ImageBuf &buf, ROI region) { ... same as before ... } bool make_black (ImageBuf &buf, ROI region) { OIIO_DISPATCH_COMMON_TYPES ("make_black", make_black_impl, buf.spec().format, buf, region); } \end{code} \noindent This other type-dispatching helper macros will be discussed in more detail in Chapter~\ref{chap:imagebufalgo}. \index{ImageBuf|)} \index{Image Buffers|)} \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/mainpage.h0000644000175000017500000000611212271062644017607 0ustar mfvmfv// Comments that don't go anywhere in the source code, but help to // generate the "main page" or other docs for doxygen. namespace OpenImageIO { /** @mainpage OpenImageIO Programmer Documentation @section imageio_sec Basic Image Input/Output and Helper Classes The core of OpenImageIO consists of simple classes for format-agnostic reading and writing of image files: \li ImageInput is the public API that allows you to read images. \li ImageOutput is the public API that allows you to write images. \li ImageSpec is a helper class that describes an image (resolution, data format, metadata, etc.). @section helper_sec Helper Classes used by the main APIs \li TypeDesc describes data types and is used to describe channel formats and many other things throughout %OpenImageIO. (\ref typedesc.h) \li ParamValueList and ParamValue are used for storing arbitrary name/data pairs and are used to store metadata. (\ref paramlist.h) \li \ref ustring is string class that's especially suitable for super fast string copying and comparison (== and !=) and that stores the character strings uniquely. (\ref ustring.h) @section ic_and_ts_sec Cached Images and Filtered Texture \li ImageCache provides a way to access an unlimited number of images and amount of pixel data (thousands of files, hundreds of GB of pixels) using a read-on-demand cache system that uses as little as several tens of MB of RAM. \li ImageBuf is a handy method for manipulating image pixels in memory, completely hiding even the details of reading, writing, and memory management (by being based internally upon ImageInput, ImageOutput, and ImageCache). \li TextureSystem is an API for performing filtered anisotropic texture lookups (backed by ImageCache, so it can easily scale to essentially unlimited number of texture files and/or pixel data). @section gifts_sec Gifts for developers These classes and utilities are not exposed through any of the public OIIO APIs and are not necessary to understand even for people who are integrating OIIO into their applications. But we like them, feel that they are pretty useful, and so distribute them so that OIIO users may rely on them in their own apps. \li \ref argparse.h : The ArgParse class that privides a really simple way to parse command-line arguments. \li \ref dassert.h : Handy assertion macros. \li errorhandler.h : An ErrorHandler class. \li \ref filesystem.h : Platform-independent utilties for handling file names, etc. \li \ref fmath.h : Lots of numeric utilities. \li \ref hash.h : Definitions helpful for using hash maps and hash functions. \li \ref paramlist.h : The ParamValue and ParamValueList classes. \li \ref refcnt.h : A "mix-in" class for intrusive reference counting. \li \ref strutil.h : String utilities. \li \ref sysutil.h : Platform-independent OS, hardware, and system utilities. \li \ref thread.h : Threading, mutexes, atomics, etc. \li \ref timer.h : A simple \ref Timer class. \li \ref typedesc.h : The TypeDesc class. \li \ref ustring.h : The ustring class. \li \ref varyingref.h : The VaryingRef template. */ }; openimageio-1.3.12~dfsg0.orig/src/doc/iinfo.tex0000644000175000017500000001426112271062644017507 0ustar mfvmfv\chapter{Getting Image information With {\kw iinfo}} \label{chap:iinfo} \indexapi{iinfo} %\section{Overview} The {\cf iinfo} program will print either basic information (name, resolution, format) or detailed information (including all metadata) found in images. Because {\cf iinfo} is built on top on \product, it will print information about images of any formats readable by \ImageInput plugins on hand. \section{Using {\cf iinfo}} The {\cf iinfo} utility is invoked as follows: \bigskip \hspace{0.25in} {\cf iinfo} [\emph{options}] \emph{filename} ... \medskip Where \emph{filename} (and any following strings) names the image file(s) whose information should be printed. The image files may be of any format recognized by \product (i.e., for which \ImageInput plugins are available). In its most basic usage, it simply prints the resolution, number of channels, pixel data type, and file format type of each of the files listed: \begin{code} $ iinfo img_6019m.jpg grid.tif lenna.png img_6019m.jpg : 1024 x 683, 3 channel, uint8 jpeg grid.tif : 512 x 512, 3 channel, uint8 tiff lenna.png : 120 x 120, 4 channel, uint8 png \end{code} % $ The {\cf -s} flag also prints the uncompressed sizes of each image file, plus a sum for all of the images: \begin{code} $ iinfo -s img_6019m.jpg grid.tif lenna.png img_6019m.jpg : 1024 x 683, 3 channel, uint8 jpeg (2.00 MB) grid.tif : 512 x 512, 3 channel, uint8 tiff (0.75 MB) lenna.png : 120 x 120, 4 channel, uint8 png (0.05 MB) Total size: 2.81 MB \end{code} % $ The {\cf -v} option turns on \emph{verbose mode}, which exhaustively prints all metadata about each image: \begin{code} $ iinfo -v img_6019m.jpg img_6019m.jpg : 1024 x 683, 3 channel, uint8 jpeg channel list: R, G, B Color space: sRGB ImageDescription: "Family photo" Make: "Canon" Model: "Canon EOS DIGITAL REBEL XT" Orientation: 1 (normal) XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) DateTime: "2008:05:04 19:51:19" Exif:YCbCrPositioning: 2 ExposureTime: 0.004 FNumber: 11 Exif:ExposureProgram: 2 (normal program) Exif:ISOSpeedRatings: 400 Exif:DateTimeOriginal: "2008:05:04 19:51:19" Exif:DateTimeDigitized: "2008:05:04 19:51:19" Exif:ShutterSpeedValue: 7.96579 (1/250 s) Exif:ApertureValue: 6.91887 (f/11) Exif:ExposureBiasValue: 0 Exif:MeteringMode: 5 (pattern) Exif:Flash: 16 (no flash, flash supression) Exif:FocalLength: 27 (27 mm) Exif:ColorSpace: 1 Exif:PixelXDimension: 2496 Exif:PixelYDimension: 1664 Exif:FocalPlaneXResolution: 2855.84 Exif:FocalPlaneYResolution: 2859.11 Exif:FocalPlaneResolutionUnit: 2 (inches) Exif:CustomRendered: 0 (no) Exif:ExposureMode: 0 (auto) Exif:WhiteBalance: 0 (auto) Exif:SceneCaptureType: 0 (standard) Keywords: "Carly; Jack" \end{code} % $ If the input file has multiple subimages, extra information summarizing the subimages will be printed: \begin{code} $ iinfo img_6019m.tx img_6019m.tx : 1024 x 1024, 3 channel, uint8 tiff (11 subimages) $ iinfo -v img_6019m.tx img_6019m.tx : 1024 x 1024, 3 channel, uint8 tiff 11 subimages: 1024x1024 512x512 256x256 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 channel list: R, G, B tile size: 64 x 64 ... \end{code} Furthermore, the {\cf -a} option will print information about all individual subimages: \begin{code} $ iinfo -a ../sample-images/img_6019m.tx img_6019m.tx : 1024 x 1024, 3 channel, uint8 tiff (11 subimages) subimage 0: 1024 x 1024, 3 channel, uint8 tiff subimage 1: 512 x 512, 3 channel, uint8 tiff subimage 2: 256 x 256, 3 channel, uint8 tiff subimage 3: 128 x 128, 3 channel, uint8 tiff subimage 4: 64 x 64, 3 channel, uint8 tiff subimage 5: 32 x 32, 3 channel, uint8 tiff subimage 6: 16 x 16, 3 channel, uint8 tiff subimage 7: 8 x 8, 3 channel, uint8 tiff subimage 8: 4 x 4, 3 channel, uint8 tiff subimage 9: 2 x 2, 3 channel, uint8 tiff subimage 10: 1 x 1, 3 channel, uint8 tiff $ iinfo -v -a img_6019m.tx img_6019m.tx : 1024 x 1024, 3 channel, uint8 tiff 11 subimages: 1024x1024 512x512 256x256 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 subimage 0: 1024 x 1024, 3 channel, uint8 tiff channel list: R, G, B tile size: 64 x 64 ... subimage 1: 512 x 512, 3 channel, uint8 tiff channel list: R, G, B ... ... \end{code} \section{{\cf iinfo} command-line options} \apiitem{--help} Prints usage information to the terminal. \apiend \apiitem{-v} Verbose output --- prints all metadata of the image files. \apiend \apiitem{-a} Print information about all subimages in the file(s). \apiend \apiitem{-f} Print the filename as a prefix to every line. For example, \begin{code} $ iinfo -v -f img_6019m.jpg img_6019m.jpg : 1024 x 683, 3 channel, uint8 jpeg img_6019m.jpg : channel list: R, G, B img_6019m.jpg : Color space: sRGB img_6019m.jpg : ImageDescription: "Family photo" img_6019m.jpg : Make: "Canon" ... \end{code} %$ \apiend \apiitem{-m {\rm \emph{pattern}}} Match the \emph{pattern} (specified as an extended regular expression) against data metadata field names and print only data fields whose names match. The default is to print all data fields found in the file (if {\cf -v} is given). For example, \begin{code} $ iinfo -v -f -m ImageDescription test*.jpg test3.jpg : ImageDescription: "Birthday party" test4.jpg : ImageDescription: "Hawaii vacation" test5.jpg : ImageDescription: "Bob's graduation" test6.jpg : ImageDescription: \end{code} %$ \apiend Note: the {\cf -m} option is probably not very useful without also using the {\cf -v} and {\cf -f} options. \apiitem{--hash} Displays a SHA-1 hash of the pixel data of the image (and of each subimage if combined with the {\cf -a} flag). \apiend \apiitem{-s} Show the image sizes, including a sum of all the listed images. \apiend openimageio-1.3.12~dfsg0.orig/src/doc/maketx.tex0000644000175000017500000003531012271062644017672 0ustar mfvmfv\chapter{Making Tiled MIP-Map Texture Files With {\cf maketx}} \label{chap:maketx} \indexapi{maketx} \section{Overview} The \maketx program will read an image (from any file format for which an \ImageInput plugin can be found) and then write it in a form in which it will have high performance when used by \TextureSystem (Chapter~\ref{chap:texturesystem}). This involves converting it to tiled (versus scanline) orientation, writing multiple subimages at different resolutions (MIP-map), and setting a variety of header or metadata fields appropriately for texture maps. The \maketx utility is invoked as follows: \medskip \hspace{0.25in} {\cf maketx} [\emph{options}] \emph{input}... -o \emph{output} \medskip Where \emph{input} and \emph{output} name the input image and desired output filename. The input files may be of any image format recognized by \product (i.e., for which \ImageInput plugins are available). The file format of the output image will be inferred from the file extension of the output filename (e.g., \qkw{foo.tif} will write a TIFF file). \section{{\cf maketx} command-line options} \apiitem{--help} Prints usage information to the terminal. \apiend \apiitem{-v} Verbose status messages, including runtime statistics and timing. \apiend \apiitem{-o {\rm \emph{outputname}}} Sets the name of the output texture. \apiend \apiitem{--threads \emph{n}} Use \emph{n} execution threads if it helps to speed up image operations. The default (also if $n=0$) is to use as many threads as there are cores present in the hardware. \apiend \apiitem{--format {\rm \emph{formatname}}} Specifies the image format of the output file (e.g., ``tiff'', ``OpenEXR'', etc.). If {\cf --format} is not used, \maketx will guess based on the file extension of the output filename; if it is not a recognized format extension, TIFF will be used by default. \apiend \apiitem{-d {\rm \emph{datatype}}} Attempt to sets the output pixel data type to one of: {\cf uint8}, {\cf sint8}, {\cf uint16}, {\cf sint16}, {\cf half}, {\cf float}, {\cf double}. If the {\cf -d} option is not supplied, the output data type will be the same as the data format of the input file. In either case, the output file format itself (implied by the file extension of the output filename) may trump the request if the file format simply does not support the requested data type. \apiend \apiitem{--tile {\rm \emph{x}} {\rm \emph{y}}} Specifies the tile size of the output texture. If not specified, \maketx will make $64 \times 64$ tiles. \apiend \apiitem{--separate} Forces ``separate'' (e.g., RRR...GGG...BBB) packing of channels in the output file. Without this option specified, ``contiguous'' (e.g., RGBRGBRGB...) packing of channels will be used for those file formats that support it. \apiend \apiitem{--compression {\rm \emph{method}}} Sets the compression method for the output image (the default is to try to use \qkw{zip} compression, if it is available). \apiend \apiitem{--update} Ordinarily, textures are created unconditionally (which could take several seconds for large input files if read over a network) and will be stamped with the current time. The {\cf --update} option enables \emph{update mode}I if the output file already exists and has the same time stamp as the input file, the texture will not be recreated. If the output file does not exist or has a different time than the input file, then the texture will be created be given the time stamp of the input file. \apiend \apiitem{--wrap {\rm \emph{wrapmode}} \\ --swrap {\rm \emph{wrapmode}} --twrap {\rm \emph{wrapmode}}} Sets the default \emph{wrap mode} for the texture, which determines the behavior when the texture is sampled outside the $[0,1]$ range. Valid wrap modes are: {\cf black}, {\cf clamp}, {\cf periodic}, {\cf mirror}. The default, if none is set, is {\cf black}. The {\cf --wrap} option sets the wrap mode in both directions simultaneously, while the {\cf --swrap} and {\cf --twrap} may be used to set them individually in the $s$ (horizontal) and $t$ (vertical) diretions. Although this sets the default wrap mode for a texture, note that the wrap mode may have an override specified in the texture lookup at runtime. \apiend \apiitem{--resize} Causes the highest-resolution level of the MIP-map to be a power-of-two resolution in each dimension (by rounding up the resolution of the input image). There is no good reason to do this for the sake of OIIO's texture system, but some users may require it in order to create MIP-map images that are compatible with both OIIO and other texturing systems that require power-of-2 textures. \apiend \apiitem{--filter {\rm \emph{name}}} By default, the resizing step that generates successive MIP levels uses a triangle filter to bilinearly combine pixels (for MIP levels with even number of pixels, this is also equivalent to a box filter, which merely averages groups of 4 adjacent pixels). This is fast, but for source images with high frequency content, can result in aliasing or other artifacts in the lower-resolution MIP levels. The {\cf --filter} option selects a high-quality filter to use when resizing to generate successive MIP levels. Choices include {\cf lanczos3} (our best recommendation for highest-quality filtering, a 3-lobe Lanczos filter), {\cf box}, {\cf triangle}, {\cf catrom}, {\cf blackman-harris}, {\cf gaussian}, {\cf mitchell}, {\cf bspline}, {\cf radial-lanczos3}, {\cf disk}, {\cf sinc}. If you select a filter with negative lobes (including {\cf lanczos3}, {\cf sinc}, {\cf lanczos3}, or {\cf catrom}), and your source image is an HDR image with very high contrast regions that include pixels with values $>1$, you may also wish to use the {\cf --rangecompress} option to avoid ringing artifacts. \apiend \apiitem{--hicomp} Perform highlight compensation. When HDR input data with high-contrast highlights is turned into a MIP-mapped texture using a high-quality filter with negative lobes (such as {\cf lanczos3}), objectionable ringing could appear near very high-contrast regions with pixel values $>1$. This option improves those areas by using range compression (transforming values from a linear to a logarithmic scale that greatly compresses the values $> 1$) prior to each image filtered-resize step, and then expanded back to a linear format after the resize, and also clamping resulting pixel values to be non-negative. This can result in some loss of energy, but often this is a preferable alternative to ringing artifacts in your upper MIP levels. \apiend \apiitem{--nomipmap} Causes the output to \emph{not} be MIP-mapped, i.e., only will have the highest-resolution level. \apiend \apiitem{--nchannels {\rm \emph{n}}} Sets the number of output channels. If \emph{n} is less than the number of channels in the input image, the extra channels will simply be ignored. If \emph{n} is greater than the number of channels in the input image, the additional channels will be filled with 0 values. \apiend \apiitem{--chnames {\rm \emph{a,b,...}}} Renames the channels of the output image. All the channel names are concatenated together, separated by commas. A ``blank'' entry will cause the channel to retain its previous value (for example, {\cf --chnames ,,,A} will rename channel 3 to be \qkw{A} and leave channels 0--2 as they were. \apiend \apiitem{--checknan} Checks every pixel of the input image to ensure that no NaN or Inf values are present. If such non-finite pixel values are found, an error message will be printed and {\cf maketx} will terminate without writing the output image (returning an error code). \apiend \apiitem{--fixnan {\rm \emph{streategy}}} Repairs any pixels in the input image that contained {\cf NaN} or {\cf Inf} values (hereafter referred to collectively as ``nonfinite''). If \emph{strategy} is {\cf black}, nonfinite values will be replaced with {\cf 0}. If \emph{strategy} is {\cf box3}, nonfinite values will be replaced by the average of all the finite values within a $3 \times 3$ region surrounding the pixel. \apiend \apiitem{--fullpixels} Resets the ``full'' (or ``display'') pixel range to be the ``data'' range. This is used to deal with input images that appear, in their headers, to be crop windows or overscanned images, but you want to treat them as full 0--1 range images over just their defined pixel data. \apiend %\apiitem{--ingamma {\rm \emph{value}} \\ %--outgamma {\rm \emph{value}}} %Not currently implemented %\apiend \apiitem{--Mcamera {\rm \emph{...16 floats...}} \\ --Mscreen {\rm \emph{...16 floats...}}} Sets the camera and screen matrices (sometimes called {\cf Nl} and {\cf NP}, respectively, by some renderers) in the texture file, overriding any such matrices that may be in the input image (and would ordinarily be copied to the output texture). \apiend \apiitem{--hash} Computes a SHA-1 hash on the input file's pixels and embeds this hash in the ``ImageDescription'' metadata of the output texture. This is useful in helping the \TextureSystem identify duplicate textures at runtime. \apiend \apiitem{--prman-metadata} Causes metadata \qkw{PixarTextureFormat} to be set, which is useful if you intend to create an OpenEXR texture or environment map that can be used with PRMan as well as OIIO. \apiend \apiitem{--constant-color-detect} Detects images in which all pixels are identical, and outputs the texture at a reduced resolution equal to the tile size, rather than filling endless tiles with the same constant color. That is, by substituting a low-res texture for a high-res texture if it's a constant color, you could save a lot of save disk space, I/O, and texture cache size. It also sets the \qkw{ImageDescription} to contain a special message of the form \qkw{ConstantColor=[r,g,...]}. \apiend \apiitem{--monochrome-detect} Detects multi-channel images in which all color components are identical, and outputs the texture as a single-channel image instead. That is, it changes RGB images that are gray into single-channel gray scale images. Use with caution! This is a great optimization if such textures will only have their first channel accessed, but may cause unexpected behavior if the ``client'' application will attempt to access those other channels that will no longer exist. \apiend \apiitem{--opaque-detect} Detects images that have a designated alpha channel for which the alpha value for all pixels is 1.0 (fully opaque), and omits the alpha channel from the output texture. So, for example, an RGBA input texture where A=1 for all pixels will be output just as RGB. The purpose is to save disk space, texture I/O bandwidth, and texturing time for those textures where alpha was present in the input, but clearly not necessary. Use with caution! This is a great optimization only if your use of such textures will assume that missing alpha channels are equivalent to textures whose alpha is 1.0 everywhere. \apiend \apiitem{--ignore-unassoc} Ignore any header tags in the input images that indicate that the input has ``unassociated'' alpha. When this option is used, color channels with unassociated alpha will not be automatically multiplied by alpha to turn them into associated alpha. This is also a good way to fix input images that really are associated alpha, but whose headers incorrectly indicate that they are unassociated alpha. \apiend \apiitem{--prman} PRMan is will crash in strange ways if given textures that don't have its quirky set of tile sizes and other specific metadata. If you want \maketx to generate textures that may be used with either \OpenImageIO or PRMan, you should use the {\cf --prman} option, which will set several options to make PRMan happy, overriding any contradictory settings on the command line or in the input texture. Specifically, this option sets the tile size (to 64x64 for 8 bit, 64x32 for 16 bit integer, and 32x32 for float or {\cf half} images), uses ``separate'' planar configuration ({\cf --separate}), and sets PRMan-specific metadata ({\cf --prman-metadata}). It also outputs sint16 textures if uint16 is requested (because PRMan for some reason does not accept true uint16 textures). \OpenImageIO will happily accept textures that conform to PRMan's expectations, but not vice versa. But \OpenImageIO's \TextureSystem has better performance with textures that use \maketx's default settings rather than these oddball choices. You have been warned! \apiend \apiitem{--oiio} This sets several options that we have determined are the optimal values for \OpenImageIO's \TextureSystem, overriding any contradictory settings on the command line or in the input texture. Specifically, this is the equivalent to using \\ {\cf --separate --tile 64 64 --hash}. \apiend \apiitem{--colorconvert {\rm \emph{inspace outspace}}} Convert the color space of the input image from \emph{inspace} to \emph{tospace}. If OpenColorIO is installed and finds a valid configuration, it will be used for the color conversion. If OCIO is not enabled (or cannot find a valid configuration, OIIO will at least be able to convert among linear, sRGB, and Rec709. \apiend \apiitem{--unpremult} When undergoing color some conversions, it is helpful to ``un-premultiply'' the alpha before converting color channels, and then re-multiplying by alpha. Caveat emptor -- if you don't know exactly when to use this, you probably shouldn't be using it at all. \apiend \apiitem{--mipimage {\rm \emph{filename}}} Specifies the name of an image file to use as a custom MIP-map level, instead of simply downsizing the last one. This option may be used multiple times to specify multiple levels. For example: \begin{code} maketx 256.tif --miplevel 128.tif --miplevel 64.tif -o out.tx \end{code} This will make a texture with the first MIP level taken from {\cf 256.tif}, the second level from {\cf 128.tif}, the third from {\cf 64.tif}, and then subsequent levels will be the usual downsizings of {\cf 64.tif}. \apiend \apiitem{--envlatl} Creates a latitude-longitude environment map, rather than an ordinary texture map. \apiend \apiitem{--lightprobe} Creates a latitude-longitude environment map, but in contrast to {\cf --envlatl}, the original input image is assumed to be formatted as a \emph{light probe} image\footnote{See {\cf http://www.pauldebevec.com/Probes/} for examples and an explanation of the geometric layout.}. \apiend % --shadow --shadcube % --volshad --envlatl --envcube --lightprobe --latl2envcube --vertcross % --fov % --opaquewidth \begin{comment} \section{{\cf maketx} Recipes} % FIXME This section will give quick examples of common uses of {\cf maketx}. \subsection*{Converting between file formats} It's a snap to converting among image formats supported by \product (i.e., for which \ImageInput and \ImageOutput plugins can be found). The {\cf maketx} utility will simply infer the file format from the file extension. The following example converts a PNG image to JPEG: \begin{code} maketx lena.png lena.jpg \end{code} \end{comment} openimageio-1.3.12~dfsg0.orig/src/doc/.gitignore0000644000175000017500000000010012271062644017634 0ustar mfvmfv*.aux *.idx *.log *.out *.toc /openimageio.ilg /openimageio.ind openimageio-1.3.12~dfsg0.orig/src/doc/algorithm.sty0000644000175000017500000000561012271062644020406 0ustar mfvmfv% ALGORITHM STYLE -- Released 8 April 1996 % for LaTeX-2e % Copyright -- 1994 Peter Williams % % E-mail pwil3058@bigpond.net.au % % This style file is free software; you can redistribute it and/or % modify it under the terms of the GNU Lesser General Public % License as published by the Free Software Foundation; either % version 2 of the License, or (at your option) any later version. % % This style file 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 % Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public % License along with this style file; if not, write to the % Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{algorithm} \typeout{Document Style `algorithm' - floating environment} \RequirePackage{float} \RequirePackage{ifthen} \newcommand{\ALG@within}{nothing} \newboolean{ALG@within} \setboolean{ALG@within}{false} \newcommand{\ALG@floatstyle}{ruled} \newcommand{\ALG@name}{Algorithm} \newcommand{\listalgorithmname}{List of \ALG@name s} % Declare Options % first appearance \DeclareOption{plain}{ \renewcommand{\ALG@floatstyle}{plain} } \DeclareOption{ruled}{ \renewcommand{\ALG@floatstyle}{ruled} } \DeclareOption{boxed}{ \renewcommand{\ALG@floatstyle}{boxed} } % then numbering convention \DeclareOption{part}{ \renewcommand{\ALG@within}{part} \setboolean{ALG@within}{true} } \DeclareOption{chapter}{ \renewcommand{\ALG@within}{chapter} \setboolean{ALG@within}{true} } \DeclareOption{section}{ \renewcommand{\ALG@within}{section} \setboolean{ALG@within}{true} } \DeclareOption{subsection}{ \renewcommand{\ALG@within}{subsection} \setboolean{ALG@within}{true} } \DeclareOption{subsubsection}{ \renewcommand{\ALG@within}{subsubsection} \setboolean{ALG@within}{true} } \DeclareOption{nothing}{ \renewcommand{\ALG@within}{nothing} \setboolean{ALG@within}{true} } \DeclareOption*{\edef\ALG@name{\CurrentOption}} % ALGORITHM % \ProcessOptions \floatstyle{\ALG@floatstyle} \ifthenelse{\boolean{ALG@within}}{ \ifthenelse{\equal{\ALG@within}{part}} {\newfloat{algorithm}{htbp}{loa}[part]}{} \ifthenelse{\equal{\ALG@within}{chapter}} {\newfloat{algorithm}{htbp}{loa}[chapter]}{} \ifthenelse{\equal{\ALG@within}{section}} {\newfloat{algorithm}{htbp}{loa}[section]}{} \ifthenelse{\equal{\ALG@within}{subsection}} {\newfloat{algorithm}{htbp}{loa}[subsection]}{} \ifthenelse{\equal{\ALG@within}{subsubsection}} {\newfloat{algorithm}{htbp}{loa}[subsubsection]}{} \ifthenelse{\equal{\ALG@within}{nothing}} {\newfloat{algorithm}{htbp}{loa}}{} }{ \newfloat{algorithm}{htbp}{loa} } \floatname{algorithm}{\ALG@name} \newcommand{\listofalgorithms}{\listof{algorithm}{\listalgorithmname}} openimageio-1.3.12~dfsg0.orig/src/doc/igrep.tex0000644000175000017500000000443612271062644017514 0ustar mfvmfv\chapter{Searching Image Metadata With {\kw igrep}} \label{chap:igrep} \indexapi{igrep} %\section{Overview} The {\cf igrep} program search one or more image files for metadata that match a string or regular expression. \section{Using {\cf igrep}} The {\cf igrep} utility is invoked as follows: \bigskip \hspace{0.25in} {\cf igrep} [\emph{options}] \emph{pattern} \emph{filename} ... \medskip Where \emph{pattern} is a POSIX.2 regular expression (just like the Unix/Linux {\cf grep(1)} command), and \emph{filename} (and any following names) specify images or directories that should be searched. An image file will ``match'' if any of its metadata contains values contain substring that are recognized regular expression. The image files may be of any format recognized by \product (i.e., for which \ImageInput plugins are available). Example: \begin{code} $ igrep Jack *.jpg bar.jpg: Keywords = Carly; Jack foo.jpg: Keywords = Jack test7.jpg: ImageDescription = Jack on vacation \end{code} % $ \section{{\cf igrep} command-line options} \apiitem{--help} Prints usage information to the terminal. \apiend \apiitem{-d} Print directory names as it recurses. This only happens if the {\cf -r} option is also used. \apiend \apiitem{-E} Interpret the pattern as an extended regular expression (just like {\cf egrep} or {\cf grep -E}). \apiend \apiitem{-f} Match the expression against the filename, as well as the metadata within the file. \apiend \apiitem{-i} Ignore upper/lower case distinctions. Without this flag, the expression matching will be case-sensitive. \apiend \apiitem{-l} Simply list the matching files by name, surpressing the normal output that would include the metadata name and values that matched. For example: \begin{code} $ igrep Jack *.jpg bar.jpg: Keywords = Carly; Jack foo.jpg: Keywords = Jack test7.jpg: ImageDescription = Jack on vacation $ igrep -l Jack *.jpg bar.jpg foo.jpg test7.jpg \end{code} \apiend \apiitem{-r} Recurse into directories. If this flag is present, any files specified that are directories will have any image file contained therein to be searched for a match (an so on, recursively). \apiend \apiitem{-v} Invert the sense of matching, to select image files that \emph{do not} match the expression. \apiend openimageio-1.3.12~dfsg0.orig/src/doc/CMakeLists.txt0000644000175000017500000000255112271062644020420 0ustar mfvmfvproject(documentation) set (public_docs openimageio.pdf "${OpenImageIO_SOURCE_DIR}/LICENSE" "${OpenImageIO_SOURCE_DIR}/CHANGES" ) if (INSTALL_DOCS) install (FILES ${public_docs} DESTINATION ${DOC_INSTALL_DIR} COMPONENT documentation) endif () # generate man pages using txt2man and a tiny python script to munge the # result of "$tool --help" find_program(TXT2MAN txt2man) find_package(PythonInterp) if (UNIX AND TXT2MAN AND PYTHONINTERP_FOUND) message (STATUS "Unix man page documentation will be generated") set (cli_tools oiiotool iinfo maketx idiff igrep iconvert) if (USE_QT) list (APPEND cli_tools iv) endif() foreach (tool ${cli_tools}) set (outfile "${documentation_BINARY_DIR}/${tool}.1") list (APPEND manpage_files ${outfile}) add_custom_command (OUTPUT ${outfile} COMMAND ${tool} --help | ${PYTHON_EXECUTABLE} "${documentation_SOURCE_DIR}/help2man_preformat.py" | ${TXT2MAN} -v OpenImageIO -s 1 -t ${tool} > ${outfile} DEPENDS ${tool} help2man_preformat.py) endforeach() # force man page build before install add_custom_target (man_pages ALL DEPENDS ${manpage_files}) if (INSTALL_DOCS) install (FILES ${manpage_files} DESTINATION ${MAN_INSTALL_DIR} COMPONENT documentation) endif () endif() openimageio-1.3.12~dfsg0.orig/src/doc/iconvert.tex0000644000175000017500000002726212271062644020241 0ustar mfvmfv\chapter{Converting Image Formats With {\kw iconvert}} \label{chap:iconvert} \indexapi{iconvert} \section{Overview} The {\cf iconvert} program will read an image (from any file format for which an \ImageInput plugin can be found) and then write the image to a new file (in any format for which an \ImageOutput plugin can be found). In the process, {\cf iconvert} can optionally change the file format or data format (for example, converting floating-point data to 8-bit integers), apply gamma correction, switch between tiled and scanline orientation, or alter or add certain metadata to the image. The {\cf iconvert} utility is invoked as follows: \medskip \hspace{0.25in} {\cf iconvert} [\emph{options}] \emph{input} \emph{output} \medskip Where \emph{input} and \emph{output} name the input image and desired output filename. The image files may be of any format recognized by \product (i.e., for which \ImageInput plugins are available). The file format of the output image will be inferred from the file extension of the output filename (e.g., \qkw{foo.tif} will write a TIFF file). Alternately, any number of files may be specified as follows: \medskip \hspace{0.25in} {\cf iconvert --inplace} [\emph{options}] \emph{file1 file2 ..} \medskip When the {\cf --inplace} option is used, any number of file names $\ge 1$ may be specified, and the image conversion commands are applied to each file in turn, with the output being saved under the original file name. This is useful for applying the same conversion to many files, or simply if you want to replace the input with the output rather than create a new file with a different name. \section{{\cf iconvert} Recipes} This section will give quick examples of common uses of {\cf iconvert}. \subsection*{Converting between file formats} It's a snap to converting among image formats supported by \product (i.e., for which \ImageInput and \ImageOutput plugins can be found). The {\cf iconvert} utility will simply infer the file format from the file extension. The following example converts a PNG image to JPEG: \begin{code} iconvert lena.png lena.jpg \end{code} \subsection*{Changing the data format or bit depth} Just use the {\cf -d} option to specify a pixel data format. For example, assuming that {\cf in.tif} uses 16-bit unsigned integer pixels, the following will convert it to an 8-bit unsigned pixels: \begin{code} iconvert -d uint8 in.tif out.tif \end{code} \subsection*{Changing the compression} The following command converts writes a TIFF file, specifically using LZW compression: \begin{code} iconvert --compression lzw in.tif out.tif \end{code} The following command writes its results as a JPEG file at a compression quality of 50 (pretty severe compression): \begin{code} iconvert --quality 50 big.jpg small.jpg \end{code} \subsection*{Gamma-correcting an image} The following gamma-corrects the pixels, raising all pixel values to $x^{1/2.2}$ upon writing: \begin{code} iconvert -g 2.2 in.tif out.tif \end{code} \subsection*{Converting between scanline and tiled images} Convert a scanline file to a tiled file with $16 \times 16$ tiles: \begin{code} iconvert --tile 16 16 s.tif t.tif \end{code} \noindent Convert a tiled file to scanline: \begin{code} iconvert --scanline t.tif s.tif \end{code} \subsection*{Converting images in place} You can use the {\cf --inplace} flag to cause the output to \emph{replace} the input file, rather than create a new file with a different name. For example, this will re-compress all of your TIFF files to use ZIP compression (rather than whatever they currently are using): \begin{code} iconvert --inplace --compression zip *.tif \end{code} \subsection*{Change the file modification time to the image capture time} Many image formats (including JPEGs from digital cameras) contain an internal time stamp indicating when the image was captured. But the time stamp on the file itself (what you'd see in a directory listing from your OS) most likely shows when the file was last copied, not when it was created or captured. You can use the following command to re-stamp your files so that the file system modification time matches the time that the digital image was originally captured: \begin{code} iconvert --inplace --adjust-time *.jpg \end{code} \subsection*{Add captions, keywords, IPTC tags} For formats that support it, you can add a caption/image description, keywords, or arbitrary string metadata: \begin{code} iconvert --inplace --adjust-time --caption "Hawaii vacation" *.jpg iconvert --inplace --adjust-time --keyword "John" img18.jpg img21.jpg iconvert --inplace --adjust-time --attrib IPTC:State "HI" \ --attrib IPTC:City "Honolulu" *.jpg \end{code} \medskip \section{{\cf iconvert} command-line options} \apiitem{--help} Prints usage information to the terminal. \apiend \apiitem{-v} Verbose status messages. \apiend \apiitem{--threads \emph{n}} Use \emph{n} execution threads if it helps to speed up image operations. The default (also if $n=0$) is to use as many threads as there are cores present in the hardware. \apiend \apiitem{--inplace} Causes the output to \emph{replace} the input file, rather than create a new file with a different name. Without this flag, {\cf iconvert} expects two file names, which will be used to specify the input and output files, respectively. But when {\cf --inplace} option is used, any number of file names $\ge 1$ may be specified, and the image conversion commands are applied to each file in turn, with the output being saved under the original file name. This is useful for applying the same conversion to many files. For example, the following example will add the caption ``Hawaii vacation'' to all JPEG files in the current directory: \begin{code} iconvert --inplace --adjust-time --caption "Hawaii vacation" *.jpg \end{code} \apiend \apiitem{-d {\rm \emph{datatype}}} Attempt to sets the output pixel data type to one of: {\cf uint8}, {\cf sint8}, {\cf uint16}, {\cf sint16}, {\cf half}, {\cf float}, {\cf double}. The types {\cf uint10} and {\cf uint12} may be used to request 10- or 12-bit unsigned integers. If the output file format does not support them, {\cf uint16} will be substituted. If the {\cf -d} option is not supplied, the output data type will be the same as the data format of the input file, if possible. In any case, if the output file type does not support the requested data type, it will instead use whichever supported data type results in the least amount of precision lost. \apiend % FIXME -- no it doesn't! \apiitem{-g {\rm \emph{gamma}}} Applies a gamma correction of $1/\mathrm{gamma}$ to the pixels as they are output. \apiend \apiitem{--sRGB} Explicitly tags the image as being in sRGB color space. Note that this does not alter pixel values, it only marks which color space those values refer to (and only works for file formats that understand such things). An example use of this command is if you have an image that is not explicitly marked as being in any particular color space, but you know that the values are sRGB. \apiend \apiitem{--tile {\rm \emph{x}} {\rm \emph{y}}} Requests that the output file be tiled, with the given $x \times y$ tile size, if tiled images are supported by the output format. By default, the output file will take on the tiledness and tile size of the input file. \apiend \apiitem{--scanline} Requests that the output file be scanline-oriented (even if the input file was tile-oriented), if scanline orientation is supported by the output file format. By default, the output file will be scanline if the input is scanline, or tiled if the input is tiled. \apiend \apiitem{--separate \\ --contig} Forces either ``separate'' (e.g., RRR...GGG...BBB) or ``contiguous'' (e.g., RGBRGBRGB...) packing of channels in the file. If neither of these options are present, the output file will have the same kind of channel packing as the input file. Of course, this is ignored if the output file format does not support a choice or does not support the particular choice requested. \apiend \apiitem{--compression {\rm \emph{method}}} Sets the compression method for the output image. Each \ImageOutput plugin will have its own set of methods that it supports. By default, the output image will use the same compression technique as the input image (assuming it is supported by the output format, otherwise it will use the default compression method of the output plugin). \apiend \apiitem{--quality {\rm \emph{q}}} Sets the compression quality, on a 1--100 floating-point scale. This only has an effect if the particular compression method supports a quality metric (as JPEG does). \apiend \apiitem{--no-copy-image} Ordinarily, {\cf iconvert} will attempt to use {\cf ImageOutput::copy_image} underneath to avoid de/recompression or alteration of pixel values, unless other settings clearly contradict this (such as any settings that must alter pixel values). The use of {\cf --no-copy-image} will force all pixels to be decompressed, read, and compressed/written, rather than copied in compressed form. We're not exactly sure when you would need to do this, but we put it in just in case. \apiend \apiitem{--adjust-time} When this flag is present, after writing the output, the resulting file's modification time will be adjusted to match any \qkw{DateTime} metadata in the image. After doing this, a directory listing will show file times that match when the original image was created or captured, rather than simply when {\cf iconvert} was run. This has no effect on image files that don't contain any \qkw{DateTime} metadata. \apiend \apiitem{--caption {\rm \emph{text}}} Sets the image metadata \qkw{ImageDescription}. This has no effect if the output image format does not support some kind of title, caption, or description metadata field. Be careful to enclose \emph{text} in quotes if you want your caption to include spaces or certain punctuation! \apiend \apiitem{--keyword {\rm \emph{text}}} Adds a keyword to the image metadata \qkw{Keywords}. Any existing keywords will be preserved, not replaced, and the new keyword will not be added if it is an exact duplicate of existing keywords. This has no effect if the output image format does not support some kind of keyword field. Be careful to enclose \emph{text} in quotes if you want your keyword to include spaces or certain punctuation. For image formats that have only a single field for keywords, \OpenImageIO will concatenate the keywords, separated by semicolon (`;'), so don't use semicolons within your keywords. \apiend \apiitem{--clear-keywords} Clears all existing keywords in the image. \apiend \apiitem{--attrib {\rm \emph{name text}}} Sets the named image metadata attribute to a string given by \emph{text}. For example, you could explicitly set the IPTC location metadata fields with: \begin{code} iconvert --attrib "IPTC:City" "Berkeley" in.jpg out.jpg \end{code} \apiend \apiitem{--orientation {\rm \emph{orient}}} Explicitly sets the image's \qkw{Orientation} metadata to a numeric value (see Section~\ref{metadata:orientation} for the numeric codes). This only changes the metadata field that specifies how the image should be displayed, it does NOT alter the pixels themselves, and so has no effect for image formats that don't support some kind of orientation metadata. \apiend \apiitem{--rotcw \\ --rotccw \\ --rot180} Adjusts the image's \qkw{Orientation} metadata by rotating it $90^\circ$ clockwise, $90^\circ$ degrees counter-clockwise, or $180^\circ$, respectively, compared to its current setting. This only changes the metadata field that specifies how the image should be displayed, it does NOT alter the pixels themselves, and so has no effect for image formats that don't support some kind of orientation metadata. \apiend \chapwidthend openimageio-1.3.12~dfsg0.orig/src/doc/help2man_preformat.py0000755000175000017500000000170212271062644022017 0ustar mfvmfv#!/usr/bin/python # Format the output from various oiio command line "$tool --help" invocations, # and munge such that txt2man generates a simple man page with not-too-horrible # formatting. from __future__ import print_function import sys lines = [l.rstrip().replace('\t', ' '*8) for l in sys.stdin.readlines()] print('TITLE') print(lines[0]) print() print('SYNOPSIS') for i,line in enumerate(lines[2:]): if line.lstrip().startswith('-') or line.lstrip().startswith('Options'): optStart = i+2 break print(line) print('''DESCRIPTION This program is part of the OpenImageIO (http://www.openimageio.org) tool suite. Detailed documentation is avaliable in pdf format with the OpenImageIO distribution. ''') print('OPTIONS') for line in lines[optStart:]: if not line.startswith(' '): print() print(line) elif not line.lstrip().startswith('-'): print(line.lstrip()) else: print(line) print() openimageio-1.3.12~dfsg0.orig/src/doc/CLA-CORPORATE0000644000175000017500000001656312271062644017546 0ustar mfvmfvSoftware Grant and Corporate Contributor License Agreement ("Agreement") (modeled after http://www.apache.org/licenses/ v r190612) Thank you for your interest in OpenImageIO (the "Project", which collectively includes its authors, contributors, and any encompassing organization). In order to clarify the intellectual property license granted with Contributions from any person or entity, the Project must have a Contributor License Agreement (CLA) on file that has been signed by each Contributor, indicating agreement to the license terms below. This license is for your protection as a Contributor as well as the protection of the Project and its users; it does not change your rights to use your own Contributions for any other purpose. This version of the Agreement allows an entity (the "Corporation") to submit Contributions to the Project, to authorize Contributions submitted by its designated employees to the Project, and to grant copyright and patent licenses thereto. If you have not already done so, sign this agreement, scan it, and email to info@openimageio.org. Or contact that email to request a FAX number or US postal address to mail an original. Please read this document carefully before signing and keep a copy for your records. Corporation name: ________________________________________________ Corporation address: ________________________________________________ ________________________________________________ ________________________________________________ Point of Contact: ________________________________________________ E-Mail: ________________________________________________ Telephone: _____________________ Fax: _____________________ You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the Project. In return, the Project shall not use Your Contributions in a way that is contrary to the public benefit or inconsistent with its nonprofit status and bylaws in effect at the time of the Contribution. Except for the license granted herein to the Project and recipients of software distributed by the Project, You reserve all right, title, and interest in and to Your Contributions. 1. Definitions. "You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with the Project. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "Contribution" shall mean the code, documentation or other original works of authorship expressly identified in Schedule B, as well as any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to the Project for inclusion in, or documentation of, any of the products owned or managed by the Project (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Project or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Project for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution." 2. Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to the Project and to recipients of software distributed by the Project a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works. 3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to the Project and to recipients of software distributed by the Project a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) were submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed. 4. You represent that You are legally entitled to grant the above license. You represent further that each employee of the Corporation designated on Schedule A below (or in a subsequent written modification to that Schedule) is authorized to submit Contributions on behalf of the Corporation. 5. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). 6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. 7. Should You wish to submit work that is not Your original creation, You may submit it to the Project separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [named here]". 8. It is your responsibility to notify the Project when any change is required to the list of designated employees authorized to submit Contributions on behalf of the Corporation, or to the Corporation's Point of Contact with the Project. Please sign: __________________________________ Date: _______________ Title: __________________________________ Corporation: __________________________________ Schedule A [Initial list of designated employees. NB: authorization is not tied to particular Contributions.] Schedule B [Identification of optional concurrent software grant. Would be left blank or omitted if there is no concurrent software grant.] openimageio-1.3.12~dfsg0.orig/src/doc/Doxyfile0000644000175000017500000017427012271062644017376 0ustar mfvmfv# Doxyfile 1.6.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = OpenImageIO # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = src/doc/doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = YES # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = src/include/pystring.h src/include/tbb \ src/include/export.h src/include/filter.h \ src/include/osdep.h src/include/plugin.h \ src/include/SHA1.h \ src/libOpenImageIO src/libtexture src/libutil src/iv # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *.imageio # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) # there is already a search function so this one should typically # be disabled. SEARCHENGINE = YES #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = src/doc # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = *.h # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES openimageio-1.3.12~dfsg0.orig/src/doc/glossary.tex0000644000175000017500000000544612271062644020253 0ustar mfvmfv\chapter{Glossary} \begin{description} \item[Channel] One of several data values persent in each pixel. Examples include red, green, blue, alpha, etc. The data in one channel of a pixel may be represented by a single number, whereas the pixel as a whole requires one number for each channel. \item[Client] A client (as in ``client application'') is a program or library that uses \product or any of its constituent libraries. \item[Data format] The type of numerical representation used to store a piece of data. Examples include 8-bit unsigned integers, 32-bit floating-point numbers, etc. \item[Image File Format] The specification and data layout of an image on disk. For example, TIFF, JPEG/JFIF, OpenEXR, etc. \item[Image Format Plugin] A DSO/DLL that implements the \ImageInput and \ImageOutput classes for a particular image file format. \item[Format Plugin] See \emph{image format plugin}. \item[Metadata] Data about data. As used in \product, this means Information about an image, beyond describing the values of the pixels themselves. Examples include the name of the artist that created the image, the date that an image was scanned, the camera settings used when a photograph was taken, etc. \item[Native data format] The \emph{data format} used in the disk file representing an image. Note that with \product, this may be different than the data format used by an application to store the image in the computer's RAM. \item[Pixel] One pixel element of an image, consisting of one number describing each \emph{channel} of data at a particular location in an image. \item[Plugin] See \emph{image format plugin}. \item[Scanline] A single horizontal row of pixels of an image. See also \emph{tile}. \item[Scanline Image] An image whose data layout on disk is organized by breaking the image up into horizontal scanlines, typically with the ability to read or write an entire scanline at once. See also \emph{tiled image}. \item[Tile] A rectangular region of pixels of an image. A rectangular tile is more spatially coherent than a scanline that stretches across the entire image --- that is, a pixel's neighbors are most likely in the same tile, whereas a pixel in a scanline image will typically have most of its immediate neighbors on different scanlines (requiring additional scanline reads in order to access them). \item[Tiled Image] An image whose data layout on disk is organized by breaking the image up into rectangular regions of pixels called \emph{tiles}. All the pixels in a tile can be read or written at once, and individual tiles may be read or written separately from other tiles. \item[Volume Image] A 3-D set of pixels that has not only horizontal and vertical dimensions, but also a "depth" dimension. \end{description} \chapwidthend openimageio-1.3.12~dfsg0.orig/src/iff.imageio/0000755000175000017500000000000012271062644017265 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/iff.imageio/iffinput.cpp0000644000175000017500000004007512271062644021623 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "iff_pvt.h" #include OIIO_PLUGIN_NAMESPACE_BEGIN using namespace iff_pvt; // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int iff_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *iff_input_imageio_create () { return new IffInput; } OIIO_EXPORT const char *iff_input_extensions[] = { "iff", "z", NULL }; OIIO_PLUGIN_EXPORTS_END bool IffInput::open (const std::string &name, ImageSpec &spec) { // Autodesk Maya documentation: // "Maya Image File Format - IFF // // Maya supports images in the Interchange File Format (IFF). // IFF is a generic structured file access mechanism, and is not only // limited to images. // // The openimageio IFF implementation deals specifically with Maya IFF // images with it's data blocks structured as follows: // // Header: // FOR4 CIMG // TBHD flags, width, height, compression ... // AUTH attribute ... // DATE attribute ... // FOR4 TBMP // Tiles: // RGBA tile pixels // RGBA tile pixels // RGBA tile pixels // ... // saving 'name' for later use m_filename = name; m_fd = Filesystem::fopen (m_filename, "rb"); if (!m_fd) { error ("Could not open file \"%s\"", name.c_str()); return false; } // we read header of the file that we think is IFF file if (!m_iff_header.read_header (m_fd)) { error ("\"%s\": could not read iff header", m_filename.c_str ()); close (); return false; } // image specification m_spec = ImageSpec (m_iff_header.width, m_iff_header.height, m_iff_header.pixel_channels, m_iff_header.pixel_bits == 8 ? TypeDesc::UINT8 : TypeDesc::UINT16); // set x, y m_spec.x = m_iff_header.x; m_spec.y = m_iff_header.y; // set full width, height m_spec.full_width = m_iff_header.width; m_spec.full_height = m_iff_header.height; // tiles if (m_iff_header.tile_width > 0 || m_iff_header.tile_height > 0) { m_spec.tile_width = m_iff_header.tile_width; m_spec.tile_height = m_iff_header.tile_height; // only 1 subimage for IFF m_spec.tile_depth = 1; } else { error ("\"%s\": wrong tile size", m_filename.c_str()); close (); return false; } // attributes // compression if (m_iff_header.compression == iff_pvt::RLE) { m_spec.attribute ("compression", "rle"); } // author if (m_iff_header.author.size()) { m_spec.attribute ("Artist", m_iff_header.author); } // date if (m_iff_header.date.size()) { m_spec.attribute ("DateTime", m_iff_header.date); } // file pointer is set to the beginning of tbmp data // we save this position - it will be helpful in read_native_tile m_tbmp_start = m_iff_header.tbmp_start; spec = m_spec; return true; } bool IffInput::read_native_scanline (int y, int z, void *data) { // scanline not used for Maya IFF, uses tiles instead. return false; } bool IffInput::read_native_tile (int x, int y, int z, void *data) { if (m_buf.empty ()) readimg (); // tile size int w = m_spec.width; int tw = std::min (x + m_spec.tile_width, m_spec.width) - x; int th = std::min (y + m_spec.tile_height, m_spec.height) - y; // tile data int oy=0; for(int iy = y; iy < y + th; iy++) { // in uint8_t *in_p = &m_buf[0] + (iy * w + x) * m_spec.pixel_bytes(); // out uint8_t *out_p = (uint8_t*)data + (oy * m_spec.tile_width) * m_spec.pixel_bytes(); // copy memcpy (out_p, in_p, tw * m_spec.pixel_bytes()); oy++; } return true; } bool inline IffInput::close (void) { if (m_fd) { fclose (m_fd); m_fd = NULL; } init (); return true; } bool IffInput::readimg() { uint8_t type[4]; uint32_t size; uint32_t chunksize; // seek pos // set position tile may be called randomly fseek (m_fd, m_tbmp_start, SEEK_SET); // resize buffer m_buf.resize (m_spec.image_bytes()); for (unsigned int t=0; t xmax || ymin > ymax || xmax >= m_spec.width || ymax >= m_spec.height || !tw || !th) { return false; } // tile compress bool tile_compress = false; // if tile compression fails to be less than image data stored // uncompressed the tile is written uncompressed // set channels uint8_t channels = m_iff_header.pixel_channels; // set tile size uint32_t tile_size = tw * th * channels * m_spec.channel_bytes() + 8; // test if compressed // we use the non aligned size if (tile_size > size) { tile_compress = true; } // handle 8-bit data. if (m_iff_header.pixel_bits == 8) { std::vector scratch; // set bytes. scratch.resize (image_size); if (!fread (&scratch[0], 1, scratch.size(), m_fd)) return false; // set tile data uint8_t * p = static_cast(&scratch[0]); // tile compress. if (tile_compress) { // map BGR(A) to RGB(A) for (int c =(channels * m_spec.channel_bytes()) - 1; c>=0; --c) { std::vector in (tw * th); uint8_t *in_p = &in[0]; // uncompress and increment p += uncompress_rle_channel (p, in_p, tw * th); // set tile for (uint16_t py=ymin; py<=ymax; py++) { uint8_t *out_dy = static_cast (&m_buf[0]) + (py * m_spec.width) * m_spec.pixel_bytes(); for (uint16_t px=xmin; px<=xmax; px++) { uint8_t *out_p = out_dy + px * m_spec.pixel_bytes() + c; *out_p++ = *in_p++; } } } } else { int sy=0; for (uint16_t py=ymin; py<=ymax; py++) { uint8_t *out_dy = static_cast(&m_buf[0]) + (py * m_spec.width + xmin) * m_spec.pixel_bytes(); // set tile int sx=0; for (uint16_t px=xmin; px<=xmax; px++) { uint8_t *in_p = p + (sy * tw + sx) * m_spec.pixel_bytes(); // map BGR(A) to RGB(A) for (int c=channels - 1; c>=0; --c) { uint8_t *out_p = in_p + (c * m_spec.channel_bytes()); *out_dy++ = *out_p; } sx++; } sy++; } } } // handle 16-bit data. else if (m_iff_header.pixel_bits == 16) { std::vector scratch; // set bytes. scratch.resize (image_size); if (!fread (&scratch[0], 1, scratch.size(), m_fd)) return false; // set tile data uint8_t * p = static_cast(&scratch[0]); if (tile_compress) { // set map std::vector map; if (littleendian()) { int rgb16[] = { 0, 2, 4, 1, 3, 5 }; int rgba16[] = { 0, 2, 4, 6, 1, 3, 5, 7 }; if (m_iff_header.pixel_channels == 3) { map = std::vector( rgb16, &rgb16[6] ); } else { map = std::vector( rgba16, &rgba16[8] ); } } else { int rgb16[] = { 1, 3, 5, 0, 2, 4 }; int rgba16[] = { 1, 3, 5, 7, 0, 2, 4, 6 }; if (m_iff_header.pixel_channels == 3) { map = std::vector( rgb16, &rgb16[6] ); } else { map = std::vector( rgba16, &rgba16[8] ); } } // map BGR(A)BGR(A) to RRGGBB(AA) for (int c =(channels * m_spec.channel_bytes()) - 1; c>=0; --c) { int mc = map[c]; std::vector in (tw * th); uint8_t *in_p = &in[0]; // uncompress and increment p += uncompress_rle_channel (p, in_p, tw * th); // set tile for (uint16_t py=ymin; py<=ymax; py++) { uint8_t *out_dy = static_cast (&m_buf[0]) + (py * m_spec.width) * m_spec.pixel_bytes(); for (uint16_t px=xmin; px<=xmax; px++) { uint8_t *out_p = out_dy + px * m_spec.pixel_bytes() + mc; *out_p++ = *in_p++; } } } } else { int sy=0; for (uint16_t py=ymin; py<=ymax; py++) { uint8_t *out_dy = static_cast(&m_buf[0]) + (py * m_spec.width + xmin) * m_spec.pixel_bytes(); // set scanline, make copy easier std::vector scanline (tw * m_spec.pixel_bytes()); uint16_t * sl_p = &scanline[0]; // set tile int sx=0; for (uint16_t px=xmin; px<=xmax; px++) { uint8_t *in_p = p + (sy * tw + sx) * m_spec.pixel_bytes(); // map BGR(A) to RGB(A) for (int c=channels - 1; c>=0; --c) { uint16_t pixel; uint8_t * out_p = in_p + (c * m_spec.channel_bytes()); memcpy (&pixel, out_p, 2); // swap endianness if (littleendian()) { swap_endian (&pixel); } *sl_p++ = pixel; } sx++; } // copy data memcpy (out_dy, &scanline[0], tw * m_spec.pixel_bytes()); sy++; } } } else { error ("\"%s\": unsupported number of bits per pixel for tile", m_filename.c_str()); return false; } // tile t++; } else { // skip to the next block if (fseek (m_fd, chunksize, SEEK_CUR)) return false; } } // flip buffer to make read_native_tile easier, // from tga.imageio: int bytespp = m_spec.pixel_bytes(); std::vector flip (m_spec.width * bytespp); unsigned char *src, *dst, *tmp = &flip[0]; for (int y = 0; y < m_spec.height / 2; y++) { src = &m_buf[(m_spec.height - y - 1) * m_spec.width * bytespp]; dst = &m_buf[y * m_spec.width * bytespp]; memcpy (tmp, src, m_spec.width * bytespp); memcpy (src, dst, m_spec.width * bytespp); memcpy (dst, tmp, m_spec.width * bytespp); } return true; } size_t IffInput::uncompress_rle_channel( const uint8_t * in, uint8_t * out, int size ) { const uint8_t * const _in = in; const uint8_t * const end = out + size; while (out < end) { // information. const uint8_t count = (*in & 0x7f) + 1; const bool run = (*in & 0x80) ? true : false; ++in; // find runs if (!run) { // verbatim for (int i=0; i #include "imageio.h" #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace iff_pvt { // compression numbers const uint32_t NONE = 0; const uint32_t RLE = 1; const uint32_t QRL = 2; const uint32_t QR4 = 3; const uint32_t RGB = 0x00000001; const uint32_t ALPHA = 0x00000002; const uint32_t RGBA = RGB | ALPHA; const uint32_t ZBUFFER = 0x00000004; const uint32_t BLACK = 0x00000010; // store informations about IFF file class IffFileHeader { public: // reads information about IFF file bool read_header (FILE *fd); // writes information about iff file to give file bool write_header (FILE *fd); // header information uint32_t x; uint32_t y; uint32_t width; uint32_t height; uint32_t compression; uint8_t pixel_bits; uint8_t pixel_channels; uint16_t tiles; uint16_t tile_width; uint16_t tile_height; // author string std::string author; // date string std::string date; // tbmp start uint32_t tbmp_start; // for4 start uint32_t for4_start; }; // align size inline uint32_t align_size (uint32_t size, uint32_t alignment) { uint32_t mod = size % alignment; if (mod) { mod = alignment - mod; size += mod; } return size; } // tile width inline const int & tile_width() { static int tile_w = 64; return tile_w; } // tile height inline const int & tile_height() { static int tile_h = 64; return tile_h; } // tile width size inline uint32_t tile_width_size (uint32_t width) { uint32_t tw = tile_width(); return (width + tw - 1) / tw; } // tile height size inline uint32_t tile_height_size (uint32_t height) { uint32_t th = tile_height(); return (height + th - 1) / th; } } // namespace iff_pvt class IffInput : public ImageInput { public: IffInput () { init(); } virtual ~IffInput () { close(); } virtual const char *format_name (void) const { return "iff"; } virtual bool open (const std::string &name, ImageSpec &spec); virtual bool close (void); virtual bool read_native_scanline (int y, int z, void *data); virtual bool read_native_tile (int x, int y, int z, void *data); private: FILE *m_fd; std::string m_filename; iff_pvt::IffFileHeader m_iff_header; std::vector m_buf; uint32_t m_tbmp_start; // init to initialize state void init (void) { m_fd = NULL; m_filename.clear (); m_buf.clear(); } // helper to read an image bool readimg (void); // helper to uncompress a rle channel size_t uncompress_rle_channel( const uint8_t * in, uint8_t * out, int size ); }; class IffOutput : public ImageOutput { public: IffOutput () { init (); } virtual ~IffOutput () { close (); } virtual const char *format_name (void) const { return "iff"; } virtual bool supports (const std::string &feature) const; virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode); virtual bool close (void); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); virtual bool write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride); private: FILE *m_fd; std::string m_filename; iff_pvt::IffFileHeader m_iff_header; std::vector m_buf; void init (void) { m_fd = NULL; m_filename.clear (); } // helper to compress verbatim void compress_verbatim ( const uint8_t *& in, uint8_t *& out, int size ); // helper to compress duplicate void compress_duplicate ( const uint8_t *&in, uint8_t *& out, int size ); // helper to compress a rle channel size_t compress_rle_channel ( const uint8_t *in, uint8_t *out, int size ); }; OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_IFF_H openimageio-1.3.12~dfsg0.orig/src/iff.imageio/iff_pvt.cpp0000644000175000017500000004052212271062644021431 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "iff_pvt.h" #include "dassert.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace iff_pvt; bool IffFileHeader::read_header (FILE *fd) { uint8_t type[4]; uint32_t size; uint32_t chunksize; uint32_t tbhdsize; uint32_t flags; uint16_t bytes; uint16_t prnum; uint16_t prden; // read FOR4 CIMG. for (;;) { // get type if (!fread (&type, 1, sizeof (type), fd) || // get length !fread (&size, 1, sizeof (size), fd)) return false; if (littleendian()) swap_endian (&size); chunksize = align_size (size, 4); if (type[0] == 'F' && type[1] == 'O' && type[2] == 'R' && type[3] == '4') { // get type if (!fread (&type, 1, sizeof (type), fd)) return false; // check if CIMG if (type[0] == 'C' && type[1] == 'I' && type[2] == 'M' && type[3] == 'G') { // read TBHD. for (;;) { // get type if (!fread (&type, 1, sizeof (type), fd) || // get length !fread (&size, 1, sizeof (size), fd)) return false; if (littleendian()) swap_endian (&size); chunksize = align_size (size, 4); if (type[0] == 'T' && type[1] == 'B' && type[2] == 'H' && type[3] == 'D') { tbhdsize = size; // test if table header size is correct if (tbhdsize!=24 && tbhdsize!=32) return false; // bad table header size // get width and height if (!fread (&width, 1, sizeof (width), fd) || !fread (&height, 1, sizeof (height), fd) || // get prnum and prdeb !fread (&prnum, 1, sizeof (prnum), fd) || !fread (&prden, 1, sizeof (prden), fd) || // get flags, bytes, tiles and compressed !fread (&flags, 1, sizeof (flags), fd) || !fread (&bytes, 1, sizeof (bytes), fd) || !fread (&tiles, 1, sizeof (tiles), fd) || !fread (&compression, 1, sizeof (compression), fd)) return false; // get xy if (tbhdsize == 32) { if (!fread (&x, 1, sizeof (x), fd) || !fread (&y, 1, sizeof (y), fd)) return false; } else { x = 0; y = 0; } // swap endianness if (littleendian()) { swap_endian (&width); swap_endian (&height); swap_endian (&prnum); swap_endian (&prden); swap_endian (&flags); swap_endian (&bytes); swap_endian (&tiles); swap_endian (&compression); } // tiles if (tiles == 0) return false; // non-tiles not supported // 0 no compression // 1 RLE compression // 2 QRL (not supported) // 3 QR4 (not supported) if (compression > 1) return false; // test format. if (flags & RGBA) { // test if black is set DASSERT (!(flags & BLACK)); // test for RGB channels. if (flags & RGB) { pixel_channels = 3; } // test for alpha channel if (flags & ALPHA) { pixel_channels++; } // test pixel bits if (!bytes) { pixel_bits = 8; // 8bit } else { pixel_bits = 16; // 16bit } } // Z format. else if (flags & ZBUFFER) { pixel_channels = 1; pixel_bits = 32; // 32bit // NOTE: Z_F32 support - not supported DASSERT (bytes==0); } // read AUTH, DATE or FOR4 for (;;) { // get type if (!fread (&type, 1, sizeof (type), fd) || // get length !fread (&size, 1, sizeof (size), fd)) return false; if (littleendian()) swap_endian (&size); chunksize = align_size (size, 4); if (type[0] == 'A' && type[1] == 'U' && type[2] == 'T' && type[3] == 'H') { std::vector str (chunksize); if (!fread (&str[0], 1, str.size(), fd)) return false; // get author author = std::string (&str[0], str.size()); } else if (type[0] == 'D' && type[1] == 'A' && type[2] == 'T' && type[3] == 'E') { std::vector str (chunksize); if (!fread (&str[0], 1, str.size(), fd)) return false; // get date date = std::string (&str[0], str.size()); } else if (type[0] == 'F' && type[1] == 'O' && type[2] == 'R' && type[3] == '4') { // get type if (!fread (&type, 1, sizeof (type), fd)) return false; // check if CIMG if (type[0] == 'T' && type[1] == 'B' && type[2] == 'M' && type[3] == 'P') { // tbmp position for later user in in // read_native_tile tbmp_start = ftell (fd); // read first RGBA block to detect tile size. for (unsigned int t=0; t xmax || ymin > ymax || xmax >= width || ymax >= height) { return false; } // set tile width and height tile_width = xmax - xmin + 1; tile_height = ymax - ymin + 1; // done, return return true; } // skip to the next block. if (fseek (fd, chunksize, SEEK_CUR)) return false; } } else { // skip to the next block. if (fseek (fd, chunksize, SEEK_CUR)) return false; } } else { // skip to the next block. if (fseek (fd, chunksize, SEEK_CUR)) return false; } } // TBHD done, break break; } // skip to the next block. if (fseek (fd, chunksize, SEEK_CUR)) return false; } } } // skip to the next block. if (fseek (fd, chunksize, SEEK_CUR)) return false; } return false; } bool IffFileHeader::write_header (FILE *fd) { uint32_t length = 0; uint32_t flags = 0; uint16_t prnum = 0; uint16_t prden = 0; // write 'FOR4' type std::string tmpstr = "FOR4"; if (!fwrite (tmpstr.c_str(), tmpstr.length(), 1, fd)) return false; // write 'FOR4' length, only reserve it for now if (littleendian()) swap_endian (&length); if (!fwrite (&length, sizeof (length), 1, fd)) return false; // write 'CIMG' type tmpstr = "CIMG"; if (!fwrite (tmpstr.c_str(), tmpstr.length(), 1, fd)) return false; // write 'TBHD' type tmpstr = "TBHD"; if (!fwrite (tmpstr.c_str(), tmpstr.length(), 1, fd)) return false; // 'TBHD' length, 32 bytes length = 32; if (littleendian()) swap_endian (&length); if (!fwrite (&length, sizeof (length), 1, fd)) return false; // write width and height if (littleendian()) { swap_endian (&width); swap_endian (&height); } if (!fwrite (&width, sizeof (width), 1, fd) || !fwrite (&height, sizeof (height), 1, fd)) return false; // write prnum and prden prnum = 1; prden = 1; if (littleendian()) { swap_endian (&prnum); swap_endian (&prden); } if (!fwrite (&prnum, sizeof (prnum), 1, fd) || !fwrite (&prden, sizeof (prden), 1, fd)) return false; // write flags and channels if (pixel_channels == 3) { flags = RGB; } else { flags = RGBA; } uint16_t tmpint; if (pixel_bits == 8) { tmpint = 0; } else { tmpint = 1; } if (littleendian()) { swap_endian (&flags); swap_endian (&tmpint); } if (!fwrite (&flags, sizeof (flags), 1, fd) || !fwrite (&tmpint, sizeof (tmpint), 1, fd)) return false; // write tiles if (littleendian()) { swap_endian (&tiles); } if (!fwrite (&tiles, sizeof (tiles), 1, fd)) return false; // write compression // 0 no compression // 1 RLE compression // 2 QRL (not supported) // 3 QR4 (not supported) if (littleendian()) { swap_endian (&compression); } if (!fwrite (&compression, sizeof (compression), 1, fd)) return false; // write x and y if (littleendian()) { swap_endian (&x); swap_endian (&y); } if (!fwrite (&x, sizeof (x), 1, fd) || !fwrite (&y, sizeof (y), 1, fd)) return false; // for4 position for later user in // close for4_start = ftell (fd); // write 'FOR4' type tmpstr = "FOR4"; if (!fwrite (tmpstr.c_str(), tmpstr.length(), 1, fd)) return false; // write 'FOR4' length, only reserve it for now length = 0; if (littleendian()) swap_endian (&length); if (!fwrite (&length, sizeof (length), 1, fd)) return false; // write 'TBMP' type tmpstr = "TBMP"; if (!fwrite (tmpstr.c_str(), tmpstr.length(), 1, fd)) return false; return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/iff.imageio/iffoutput.cpp0000644000175000017500000005415612271062644022031 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "iff_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace iff_pvt; // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *iff_output_imageio_create () { return new IffOutput; } OIIO_EXPORT const char *iff_output_extensions[] = { "iff", "z", NULL }; OIIO_PLUGIN_EXPORTS_END bool IffOutput::supports (const std::string &feature) const { if (feature == "tiles") return true; // Everything else, we either don't support or don't know about return false; } bool IffOutput::open (const std::string &name, const ImageSpec &spec, OpenMode mode) { // Autodesk Maya documentation: // "Maya Image File Format - IFF // // Maya supports images in the Interchange File Format (IFF). // IFF is a generic structured file access mechanism, and is not only // limited to images. // // The openimageio IFF implementation deals specifically with Maya IFF // images with it's data blocks structured as follows: // // Header: // FOR4 CIMG // TBHD flags, width, height, compression ... // AUTH attribute ... // DATE attribute ... // FOR4 TBMP // Tiles: // RGBA tile pixels // RGBA tile pixels // RGBA tile pixels // ... if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } close (); // Close any already-opened file // saving 'name' and 'spec' for later use m_filename = name; m_spec = spec; // tiles m_spec.tile_width = tile_width(); m_spec.tile_height = tile_height(); m_fd = Filesystem::fopen (m_filename, "wb"); if (!m_fd) { error ("Unable to open file \"%s\"", m_filename.c_str ()); return false; } // IFF image files only supports UINT8 and UINT16. If something // else was requested, revert to the one most likely to be readable // by any IFF reader: UINT8 if (m_spec.format != TypeDesc::UINT8 && m_spec.format != TypeDesc::UINT16) m_spec.set_format (TypeDesc::UINT8); // check if the client wants the image to be run length encoded // currently only RGB RLE compression is supported, we default to RLE // as Maya does not handle non-compressed IFF's very well. m_iff_header.compression = (m_spec.get_string_attribute ("compression", "none") == std::string("none")) ? NONE : RLE; // we write the header of the file m_iff_header.x = m_spec.x; m_iff_header.y = m_spec.y; m_iff_header.width = m_spec.width; m_iff_header.height = m_spec.height; m_iff_header.tiles = tile_width_size (m_spec.width) * tile_height_size (m_spec.height); m_iff_header.pixel_bits = m_spec.format == TypeDesc::UINT8 ? 8 : 16; m_iff_header.pixel_channels = m_spec.nchannels; m_iff_header.author = m_spec.get_string_attribute ("Artist"); m_iff_header.date = m_spec.get_string_attribute ("DateTime"); if (!m_iff_header.write_header (m_fd)) { error ("\"%s\": could not write iff header", m_filename.c_str ()); close (); return false; } return true; } bool IffOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { // scanline not used for Maya IFF, uses tiles instead. return false; } bool IffOutput::write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride) { if (m_buf.empty ()) // resize buffer m_buf.resize (m_spec.image_bytes()); // auto stride m_spec.auto_stride (xstride, ystride, zstride, format, spec().nchannels, spec().tile_width, spec().tile_height); // native tile std::vector scratch; data = to_native_tile (format, data, xstride, ystride, zstride, scratch); x -= m_spec.x; // Account for offset, so x,y are file relative, not y -= m_spec.y; // image relative // tile size int w = m_spec.width; int tw = std::min (x + m_spec.tile_width, m_spec.width) - x; int th = std::min (y + m_spec.tile_height, m_spec.height) - y; // tile data int iy=0; for(int oy = y; oy < y + th; oy++) { // in uint8_t *in_p = (uint8_t*)data + (iy * m_spec.tile_width) * m_spec.pixel_bytes(); // out uint8_t *out_p = &m_buf[0] + (oy * w + x) * m_spec.pixel_bytes(); // copy memcpy (out_p, in_p, tw * m_spec.pixel_bytes()); iy++; } return true; } inline bool IffOutput::close (void) { if (m_fd) { // flip buffer to make write tile easier, // from tga.imageio: int bytespp = m_spec.pixel_bytes(); std::vector flip (m_spec.width * bytespp); unsigned char *src, *dst, *tmp = &flip[0]; for (int y = 0; y < m_spec.height / 2; y++) { src = &m_buf[(m_spec.height - y - 1) * m_spec.width * bytespp]; dst = &m_buf[y * m_spec.width * bytespp]; memcpy (tmp, src, m_spec.width * bytespp); memcpy (src, dst, m_spec.width * bytespp); memcpy (dst, tmp, m_spec.width * bytespp); } // write y-tiles for(uint32_t ty=0; ty scratch; scratch.resize (tile_length); uint8_t * out_p = static_cast(&scratch[0]); // handle 8-bit data if (m_spec.format == TypeDesc::UINT8) { if (tile_compress) { uint32_t index = 0, size = 0; std::vector tmp; // set bytes. tmp.resize (tile_length * 2); // map: RGB(A) to BGRA for (int c =(channels * m_spec.channel_bytes()) - 1; c>=0; --c) { std::vector in (tw * th); uint8_t *in_p = &in[0]; // set tile for (uint16_t py=ymin; py<=ymax; py++) { const uint8_t * in_dy = &m_buf[0] + (py * m_spec.width) * m_spec.pixel_bytes(); for (uint16_t px=xmin; px<=xmax; px++) { // get pixel uint8_t pixel; const uint8_t * in_dx = in_dy + px * m_spec.pixel_bytes() + c; memcpy (&pixel, in_dx, 1); // set pixel *in_p++ = pixel; } } // compress rle channel size = compress_rle_channel (&in[0], &tmp[0] + index, tw * th); index += size; } // if size exceeds tile length write uncompressed if (index < tile_length) { memcpy (&scratch[0], &tmp[0], index); // set tile length tile_length = index; // append xmin, xmax, ymin and ymax length = index + 8; // set length uint32_t align = align_size (length, 4); if (align > length) { out_p = &scratch[0] + index; // Pad. for (uint32_t i=0; i=0; --c) { // get pixel uint8_t pixel; const uint8_t * in_dx = in_dy + px * m_spec.pixel_bytes() + c * m_spec.channel_bytes(); memcpy (&pixel, in_dx, 1); // set pixel *out_p++ = pixel; } } } } } // handle 16-bit data else if (m_spec.format == TypeDesc::UINT16) { if (tile_compress) { uint32_t index = 0, size = 0; std::vector tmp; // set bytes. tmp.resize (tile_length * 2); // set map std::vector map; if (littleendian()) { int rgb16[] = { 0, 2, 4, 1, 3, 5 }; int rgba16[] = { 0, 2, 4, 7, 1, 3, 5, 6 }; if (m_iff_header.pixel_channels == 3) { map = std::vector( rgb16, &rgb16[6] ); } else { map = std::vector( rgba16, &rgba16[8] ); } } else { int rgb16[] = { 1, 3, 5, 0, 2, 4 }; int rgba16[] = { 1, 3, 5, 7, 0, 2, 4, 6 }; if (m_iff_header.pixel_channels == 3) { map = std::vector( rgb16, &rgb16[6] ); } else { map = std::vector( rgba16, &rgba16[8] ); } } // map: RRGGBB(AA) to BGR(A)BGR(A) for (int c =(channels * m_spec.channel_bytes()) - 1; c>=0; --c) { int mc = map[c]; std::vector in (tw * th); uint8_t *in_p = &in[0]; // set tile for (uint16_t py=ymin; py<=ymax; py++) { const uint8_t * in_dy = &m_buf[0] + (py * m_spec.width) * m_spec.pixel_bytes(); for (uint16_t px=xmin; px<=xmax; px++) { // get pixel uint8_t pixel; const uint8_t * in_dx = in_dy + px * m_spec.pixel_bytes() + mc; memcpy (&pixel, in_dx, 1); // set pixel. *in_p++ = pixel; } } // compress rle channel size = compress_rle_channel (&in[0], &tmp[0] + index, tw * th); index += size; } // if size exceeds tile length write uncompressed if (index < tile_length) { memcpy (&scratch[0], &tmp[0], index); // set tile length tile_length = index; // append xmin, xmax, ymin and ymax length = index + 8; // set length uint32_t align = align_size (length, 4); if (align > length) { out_p = &scratch[0] + index; // Pad. for (uint32_t i=0; i=0; --c) { uint16_t pixel; const uint8_t * in_dx = in_dy + px * m_spec.pixel_bytes() + c * m_spec.channel_bytes(); memcpy (&pixel, in_dx, 2); if (littleendian()) { swap_endian (&pixel); } // set pixel *out_p++ = pixel; (*out_p)++; // avoid gcc4.x warning } } } } } // write 'RGBA' length if (littleendian()) swap_endian (&length); if (!fwrite (&length, sizeof (length), 1, m_fd)) return false; // write xmin, xmax, ymin and ymax if (littleendian()) { swap_endian (&xmin); swap_endian (&ymin); swap_endian (&xmax); swap_endian (&ymax); } if (!fwrite (&xmin, sizeof (xmin), 1, m_fd) || !fwrite (&ymin, sizeof (ymin), 1, m_fd) || !fwrite (&xmax, sizeof (xmax), 1, m_fd) || !fwrite (&ymax, sizeof (ymax), 1, m_fd)) return false; // write tile if (!fwrite (&scratch[0], tile_length, 1, m_fd)) return false; } } // set sizes uint32_t pos, tmppos; pos = ftell (m_fd); uint32_t p0 = pos - 8; uint32_t p1 = p0 - m_iff_header.for4_start; // set pos tmppos = 4; fseek (m_fd, tmppos, SEEK_SET); // write FOR4 CIMG if (littleendian()) { swap_endian (&p0); } if (!fwrite (&p0, sizeof (p0), 1, m_fd)) return false; // set pos tmppos = m_iff_header.for4_start + 4; fseek (m_fd, tmppos, SEEK_SET); // write FOR4 TBMP if (littleendian()) { swap_endian (&p1); } if (!fwrite (&p1, sizeof (p1), 1, m_fd)) return false; // close the stream fclose (m_fd); m_fd = NULL; } return true; } void IffOutput::compress_verbatim ( const uint8_t *& in, uint8_t *& out, int size) { int count = 1; unsigned char byte = 0; // two in a row or count for (; count < size; ++count) { if (in[count - 1] == in[count]) { if (byte == in[count - 1]) { count -= 2; break; } } byte = in[count - 1]; } // copy *out++ = count - 1; memcpy (out, in, count); out += count; in += count; } void IffOutput::compress_duplicate ( const uint8_t *& in, uint8_t *& out, int size) { int count = 1; for (; count < size; ++count) { if (in[count - 1] != in[count]) break; } const bool run = count > 1; const int length = run ? 1 : count; // copy *out++ = ((count - 1) & 0x7f) | (run << 7); *out = *in; out += length; in += count; } size_t IffOutput::compress_rle_channel ( const uint8_t * in, uint8_t * out, int size) { const uint8_t * const _out = out; const uint8_t * const end = in + size; while (in < end) { // find runs const int max = std::min (0x7f + 1, static_cast(end - in)); if (max > 0) { if (in[0] != in[1]) { // compress verbatim compress_verbatim (in, out, max); } else { // compress duplicate compress_duplicate (in, out, max); } } } const size_t r = out - _out; return r; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/iff.imageio/CMakeLists.txt0000644000175000017500000000007112271062644022023 0ustar mfvmfvadd_oiio_plugin (iffinput.cpp iffoutput.cpp iff_pvt.cpp) openimageio-1.3.12~dfsg0.orig/src/webp.imageio/0000755000175000017500000000000012271062644017456 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/webp.imageio/webpoutput.cpp0000644000175000017500000001352212271062644022403 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include "filesystem.h" #include "imageio.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace webp_pvt { class WebpOutput : public ImageOutput { public: WebpOutput(){ init(); } virtual ~WebpOutput(){ close(); } virtual const char* format_name () const { return "webp"; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool supports (const std::string &property) const { return false; } virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); virtual bool close(); private: WebPPicture m_webp_picture; WebPConfig m_webp_config; std::string m_filename; FILE *m_file; int m_scanline_size; std::vector m_uncompressed_image; void init() { m_scanline_size = 0; m_file = NULL; } }; static int WebpImageWriter(const uint8_t* img_data, size_t data_size, const WebPPicture* const webp_img) { FILE *out_file = (FILE*)webp_img->custom_ptr; size_t wb = fwrite (img_data, data_size, sizeof(uint8_t), out_file); if (wb != sizeof(uint8_t)) { //FIXME Bad write occurred } return 1; } bool WebpOutput::open (const std::string &name, const ImageSpec &spec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } // saving 'name' and 'spec' for later use m_filename = name; m_spec = spec; m_file = Filesystem::fopen (m_filename, "wb"); if (!m_file) { error ("Unable to open file \"%s\"", m_filename.c_str ()); return false; } if (!WebPPictureInit(&m_webp_picture)) { error("Couldn't initialize WebPPicture\n"); close(); return false; } m_webp_picture.width = m_spec.width; m_webp_picture.height = m_spec.height; m_webp_picture.writer = WebpImageWriter; m_webp_picture.custom_ptr = (void*)m_file; if (!WebPConfigInit(&m_webp_config)) { error("Couldn't initialize WebPPicture\n"); close(); return false; } m_webp_config.method = 6; int compression_quality = 100; const ImageIOParameter *qual = m_spec.find_attribute ("CompressionQuality", TypeDesc::INT); if (qual) { compression_quality = *static_cast(qual->data()); } m_webp_config.quality = compression_quality; // forcing UINT8 format m_spec.set_format (TypeDesc::UINT8); m_scanline_size = m_spec.width * m_spec.nchannels; const int image_buffer = m_spec.height * m_scanline_size; m_uncompressed_image.resize(image_buffer, 0); return true; } bool WebpOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { if (y > m_spec.height) { error ("Attempt to write too many scanlines to %s", m_filename.c_str()); close (); return false; } std::vector scratch; data = to_native_scanline (format, data, xstride, scratch); memcpy(&m_uncompressed_image[y*m_scanline_size], data, m_scanline_size); if (y == m_spec.height - 1) { if (m_spec.nchannels == 4) { WebPPictureImportRGBA(&m_webp_picture, &m_uncompressed_image[0], m_scanline_size); } else { WebPPictureImportRGB(&m_webp_picture, &m_uncompressed_image[0], m_scanline_size); } if (!WebPEncode(&m_webp_config, &m_webp_picture)) { error ("Failed to encode %s as WebP image", m_filename.c_str()); close(); return false; } } return true; } bool WebpOutput::close() { if (m_file) { WebPPictureFree(&m_webp_picture); fclose(m_file); m_file = NULL; } return true; } } // namespace webp_pvt OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *webp_output_imageio_create () { return new webp_pvt::WebpOutput; } OIIO_EXPORT const char *webp_output_extensions[] = { "webp", NULL }; OIIO_PLUGIN_EXPORTS_END OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/webp.imageio/webpinput.cpp0000644000175000017500000001117212271062644022201 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include "imageio.h" #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace webp_pvt { class WebpInput : public ImageInput { public: WebpInput() { init(); } virtual ~WebpInput() { close(); } virtual const char* format_name() const { return "webp"; } virtual bool open (const std::string &name, ImageSpec &spec); virtual bool read_native_scanline (int y, int z, void *data); virtual bool close (); private: std::string m_filename; uint8_t *m_decoded_image; long int m_image_size; long int m_scanline_size; FILE *m_file; void init() { m_image_size = m_scanline_size = 0; m_decoded_image = NULL; m_file = NULL; } }; bool WebpInput::open (const std::string &name, ImageSpec &spec) { m_filename = name; m_file = Filesystem::fopen(m_filename, "rb"); if (!m_file) { error ("Could not open file \"%s\"", m_filename.c_str()); return false; } fseek (m_file, 0, SEEK_END); m_image_size = ftell(m_file); fseek (m_file, 0, SEEK_SET); std::vector encoded_image; encoded_image.resize(m_image_size, 0); size_t numRead = fread(&encoded_image[0], sizeof(uint8_t), encoded_image.size(), m_file); if (numRead != encoded_image.size()) { error ("Read failure for \"%s\" (expected %d bytes, read %d)", m_filename, encoded_image.size(), numRead); close (); return false; } int width = 0, height = 0; if(!WebPGetInfo(&encoded_image[0], encoded_image.size(), &width, &height)) { error ("%s is not a WebP image file", m_filename.c_str()); close(); return false; } const int CHANNEL_NUM = 4; m_scanline_size = width * CHANNEL_NUM; m_spec = ImageSpec(width, height, CHANNEL_NUM, TypeDesc::UINT8); spec = m_spec; if (!(m_decoded_image = WebPDecodeRGBA(&encoded_image[0], encoded_image.size(), &m_spec.width, &m_spec.height))) { error ("Couldn't decode %s", m_filename.c_str()); close(); return false; } return true; } bool WebpInput::read_native_scanline (int y, int z, void *data) { if (y < 0 || y >= m_spec.width) // out of range scanline return false; memcpy(data, &m_decoded_image[y*m_scanline_size], m_scanline_size); return true; } bool WebpInput::close() { if (m_file) { fclose(m_file); m_file = NULL; } if (m_decoded_image) { free(m_decoded_image); // this was allocated by WebPDecodeRGB and should be fread by free m_decoded_image = NULL; } return true; } } // namespace webp_pvt // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int webp_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *webp_input_imageio_create () { return new webp_pvt::WebpInput; } OIIO_EXPORT const char *webp_input_extensions[] = { "webp", NULL }; OIIO_PLUGIN_EXPORTS_END OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/webp.imageio/CMakeLists.txt0000644000175000017500000000023212271062644022213 0ustar mfvmfvif (WEBP_FOUND) include_directories (${WEBP_INCLUDE_DIR}) add_oiio_plugin (webpinput.cpp webpoutput.cpp LINK_LIBRARIES ${WEBP_LIBRARY}) endif() openimageio-1.3.12~dfsg0.orig/src/dds.imageio/0000755000175000017500000000000012271062644017273 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/dds.imageio/dds_pvt.h0000644000175000017500000001216412271062644021113 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_DDS_PVT_H #define OPENIMAGEIO_DDS_PVT_H #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace DDS_pvt { // IneQuation was here #define DDS_MAKE4CC(a, b, c, d) (a | b << 8 | c << 16 | d << 24) #define DDS_4CC_DXT1 DDS_MAKE4CC('D', 'X', 'T', '1') #define DDS_4CC_DXT2 DDS_MAKE4CC('D', 'X', 'T', '2') #define DDS_4CC_DXT3 DDS_MAKE4CC('D', 'X', 'T', '3') #define DDS_4CC_DXT4 DDS_MAKE4CC('D', 'X', 'T', '4') #define DDS_4CC_DXT5 DDS_MAKE4CC('D', 'X', 'T', '5') /// DDS pixel format flags. Channel flags are only applicable for uncompressed /// images. /// enum { DDS_PF_ALPHA = 0x00000001, ///< image has alpha channel DDS_PF_FOURCC = 0x00000004, ///< image is compressed DDS_PF_LUMINANCE = 0x00020000, ///< image has luminance data DDS_PF_RGB = 0x00000040 ///< image has RGB data }; /// DDS pixel format structure. /// typedef struct { uint32_t size; ///< structure size, must be 32 uint32_t flags; ///< flags to indicate valid fields uint32_t fourCC; ///< compression four-character code uint32_t bpp; ///< bits per pixel uint32_t rmask; ///< bitmask for the red channel uint32_t gmask; ///< bitmask for the green channel uint32_t bmask; ///< bitmask for the blue channel uint32_t amask; ///< bitmask for the alpha channel } dds_pixformat; /// DDS caps flags, field 1. /// enum { DDS_CAPS1_COMPLEX = 0x00000008, ///< >2D image or cube map DDS_CAPS1_TEXTURE = 0x00001000, ///< should be set for all DDS files DDS_CAPS1_MIPMAP = 0x00400000 ///< image has mipmaps }; /// DDS caps flags, field 2. /// enum { DDS_CAPS2_CUBEMAP = 0x00000200, ///< image is a cube map DDS_CAPS2_CUBEMAP_POSITIVEX = 0x00000400, ///< +x side DDS_CAPS2_CUBEMAP_NEGATIVEX = 0x00000800, ///< -x side DDS_CAPS2_CUBEMAP_POSITIVEY = 0x00001000, ///< +y side DDS_CAPS2_CUBEMAP_NEGATIVEY = 0x00002000, ///< -y side DDS_CAPS2_CUBEMAP_POSITIVEZ = 0x00004000, ///< +z side DDS_CAPS2_CUBEMAP_NEGATIVEZ = 0x00008000, ///< -z side DDS_CAPS2_VOLUME = 0x00200000 ///< image is a 3D texture }; /// DDS caps structure. /// typedef struct { uint32_t flags1; ///< flags to indicate certain surface properties uint32_t flags2; ///< flags to indicate certain surface properties } dds_caps; /// DDS global flags - indicate valid header fields. /// enum { DDS_CAPS = 0x00000001, DDS_HEIGHT = 0x00000002, DDS_WIDTH = 0x00000004, DDS_PITCH = 0x00000008, DDS_PIXELFORMAT = 0x00001000, DDS_MIPMAPCOUNT = 0x00020000, DDS_LINEARSIZE = 0x00080000, DDS_DEPTH = 0x00800000 }; /// DDS file header. /// Please note that this layout is not identical to the one found in a file. /// typedef struct { uint32_t fourCC; ///< file four-character code uint32_t size; ///< structure size, must be 124 uint32_t flags; ///< flags to indicate valid fields uint32_t height; ///< image height uint32_t width; ///< image width uint32_t pitch; ///< bytes per scanline (uncmp.)/total byte size (cmp.) uint32_t depth; ///< image depth (for 3D textures) uint32_t mipmaps; ///< number of mipmaps // 11 reserved 4-byte fields come in here dds_pixformat fmt; ///< pixel format dds_caps caps; ///< DirectDraw Surface caps } dds_header; } // namespace DDS_pvt OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_DDS_PVT_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/ddsinput.cpp0000644000175000017500000005547012271062644021644 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "dds_pvt.h" #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "fmath.h" #include "squish/squish.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace DDS_pvt; // uncomment the following define to enable 3x2 cube map layout //#define DDS_3X2_CUBE_MAP_LAYOUT class DDSInput : public ImageInput { public: DDSInput () { init(); } virtual ~DDSInput () { close(); } virtual const char * format_name (void) const { return "dds"; } virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (); virtual int current_subimage (void) const { return m_subimage; } virtual int current_miplevel (void) const { return m_miplevel; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual bool read_native_scanline (int y, int z, void *data); virtual bool read_native_tile (int x, int y, int z, void *data); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle std::vector m_buf; ///< Buffer the image pixels int m_subimage; int m_miplevel; int m_nchans; ///< Number of colour channels in image int m_nfaces; ///< Number of cube map sides in image int m_Bpp; ///< Number of bytes per pixel int m_redL, m_redR; ///< Bit shifts to extract red channel int m_greenL, m_greenR; ///< Bit shifts to extract green channel int m_blueL, m_blueR; ///< Bit shifts to extract blue channel int m_alphaL, m_alphaR; ///< Bit shifts to extract alpha channel dds_header m_dds; ///< DDS header /// Reset everything to initial state /// void init () { m_file = NULL; m_subimage = -1; m_miplevel = -1; m_buf.clear (); } /// Helper function: read the image as scanlines (all but cubemaps). /// bool readimg_scanlines (); /// Helper function: read the image as tiles (cubemaps only). /// bool readimg_tiles (); /// Helper function: calculate bit shifts to properly extract channel data /// inline void calc_shifts (int mask, int& left, int& right); /// Helper function: performs the actual file seeking. /// void internal_seek_subimage (int cubeface, int miplevel, unsigned int& w, unsigned int& h, unsigned int& d); /// Helper function: performs the actual pixel decoding. bool internal_readimg (unsigned char *dst, int w, int h, int d); /// Helper: read, with error detection /// bool fread (void *buf, size_t itemsize, size_t nitems) { size_t n = ::fread (buf, itemsize, nitems, m_file); if (n != nitems) error ("Read error"); return n == nitems; } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *dds_input_imageio_create () { return new DDSInput; } OIIO_EXPORT int dds_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * dds_input_extensions[] = { "dds", NULL }; OIIO_PLUGIN_EXPORTS_END bool DDSInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; m_file = Filesystem::fopen (name, "rb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } // due to struct packing, we may get a corrupt header if we just load the // struct from file; to adress that, read every member individually // save some typing #define RH(memb) if (! fread (&m_dds.memb, sizeof (m_dds.memb), 1)) \ return false RH(fourCC); RH(size); RH(flags); RH(height); RH(width); RH(pitch); RH(depth); RH(mipmaps); // advance the file pointer by 44 bytes (reserved fields) fseek (m_file, 44, SEEK_CUR); // pixel format struct RH(fmt.size); RH(fmt.flags); RH(fmt.fourCC); RH(fmt.bpp); RH(fmt.rmask); RH(fmt.gmask); RH(fmt.bmask); RH(fmt.amask); // caps RH(caps.flags1); RH(caps.flags2); // advance the file pointer by 8 bytes (reserved fields) fseek (m_file, 8, SEEK_CUR); #undef RH if (bigendian()) { // DDS files are little-endian // only swap values which are not flags or bitmasks swap_endian (&m_dds.size); swap_endian (&m_dds.height); swap_endian (&m_dds.width); swap_endian (&m_dds.pitch); swap_endian (&m_dds.depth); swap_endian (&m_dds.mipmaps); swap_endian (&m_dds.fmt.size); swap_endian (&m_dds.fmt.bpp); } /*std::cerr << "[dds] fourCC: " << ((char *)&m_dds.fourCC)[0] << ((char *)&m_dds.fourCC)[1] << ((char *)&m_dds.fourCC)[2] << ((char *)&m_dds.fourCC)[3] << " (" << m_dds.fourCC << ")\n"; std::cerr << "[dds] size: " << m_dds.size << "\n"; std::cerr << "[dds] flags: " << m_dds.flags << "\n"; std::cerr << "[dds] pitch: " << m_dds.pitch << "\n"; std::cerr << "[dds] width: " << m_dds.width << "\n"; std::cerr << "[dds] height: " << m_dds.height << "\n"; std::cerr << "[dds] depth: " << m_dds.depth << "\n"; std::cerr << "[dds] mipmaps: " << m_dds.mipmaps << "\n"; std::cerr << "[dds] fmt.size: " << m_dds.fmt.size << "\n"; std::cerr << "[dds] fmt.flags: " << m_dds.fmt.flags << "\n"; std::cerr << "[dds] fmt.fourCC: " << ((char *)&m_dds.fmt.fourCC)[0] << ((char *)&m_dds.fmt.fourCC)[1] << ((char *)&m_dds.fmt.fourCC)[2] << ((char *)&m_dds.fmt.fourCC)[3] << " (" << m_dds.fmt.fourCC << ")\n"; std::cerr << "[dds] fmt.bpp: " << m_dds.fmt.bpp << "\n"; std::cerr << "[dds] caps.flags1: " << m_dds.caps.flags1 << "\n"; std::cerr << "[dds] caps.flags2: " << m_dds.caps.flags2 << "\n";*/ // sanity checks - valid 4CC, correct struct sizes and flags which should // be always present, regardless of the image type, size etc., also check // for impossible flag combinations if (m_dds.fourCC != DDS_MAKE4CC('D', 'D', 'S', ' ') || m_dds.size != 124 || m_dds.fmt.size != 32 || !(m_dds.caps.flags1 & DDS_CAPS1_TEXTURE) || !(m_dds.flags & DDS_CAPS) || !(m_dds.flags & DDS_PIXELFORMAT) || (m_dds.caps.flags2 & DDS_CAPS2_VOLUME && !(m_dds.caps.flags1 & DDS_CAPS1_COMPLEX && m_dds.flags & DDS_DEPTH)) || (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP && !(m_dds.caps.flags1 & DDS_CAPS1_COMPLEX))){ error ("Invalid DDS header, possibly corrupt file"); return false; } // make sure all dimensions are > 0 and that we have at least one channel // (for uncompressed images) if (!(m_dds.flags & DDS_WIDTH) || !m_dds.width || !(m_dds.flags & DDS_HEIGHT) || !m_dds.height || ((m_dds.flags & DDS_DEPTH) && !m_dds.depth) || (!(m_dds.fmt.flags & DDS_PF_FOURCC) && !((m_dds.fmt.flags & DDS_PF_RGB) | (m_dds.fmt.flags & DDS_PF_LUMINANCE) | (m_dds.fmt.flags & DDS_PF_ALPHA)))) { error ("Image with no data"); return false; } // validate the pixel format // TODO: support DXGI and the "wackier" uncompressed formats if (m_dds.fmt.flags & DDS_PF_FOURCC && m_dds.fmt.fourCC != DDS_4CC_DXT1 && m_dds.fmt.fourCC != DDS_4CC_DXT2 && m_dds.fmt.fourCC != DDS_4CC_DXT3 && m_dds.fmt.fourCC != DDS_4CC_DXT4 && m_dds.fmt.fourCC != DDS_4CC_DXT5) { error ("Unsupported compression type"); return false; } // determine the number of channels we have if (m_dds.fmt.flags & DDS_PF_FOURCC) { // squish decompresses everything to RGBA anyway /*if (m_dds.fmt.fourCC == DDS_4CC_DXT1) m_nchans = 3; // no alpha in DXT1 else*/ m_nchans = 4; } else { m_nchans = ((m_dds.fmt.flags & DDS_PF_LUMINANCE) ? 1 : 3) + ((m_dds.fmt.flags & DDS_PF_ALPHA) ? 1 : 0); // also calculate bytes per pixel and the bit shifts m_Bpp = (m_dds.fmt.bpp + 7) >> 3; if (!(m_dds.fmt.flags & DDS_PF_LUMINANCE)) { calc_shifts (m_dds.fmt.rmask, m_redL, m_redR); calc_shifts (m_dds.fmt.gmask, m_greenL, m_greenR); calc_shifts (m_dds.fmt.bmask, m_blueL, m_blueR); calc_shifts (m_dds.fmt.amask, m_alphaL, m_alphaR); } } // fix depth, pitch and mipmaps for later use, if needed if (!(m_dds.fmt.flags & DDS_PF_FOURCC && m_dds.flags & DDS_PITCH)) m_dds.pitch = m_dds.width * m_Bpp; if (!(m_dds.caps.flags2 & DDS_CAPS2_VOLUME)) m_dds.depth = 1; if (!(m_dds.flags & DDS_MIPMAPCOUNT)) m_dds.mipmaps = 1; // count cube map faces if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP) { m_nfaces = 0; for (int flag = DDS_CAPS2_CUBEMAP_POSITIVEX; flag <= DDS_CAPS2_CUBEMAP_NEGATIVEZ; flag <<= 1) { if (m_dds.caps.flags2 & flag) m_nfaces++; } } else m_nfaces = 1; seek_subimage(0, 0, m_spec); newspec = spec (); return true; } inline void DDSInput::calc_shifts (int mask, int& left, int& right) { if (mask == 0) { left = right = 0; return; } int i, tmp = mask; for (i = 0; i < 32; i++, tmp >>= 1) { if (tmp & 1) break; } right = i; for (i = 0; i < 8; i++, tmp >>= 1) { if (!(tmp & 1)) break; } left = 8 - i; } // NOTE: This function has no sanity checks! It's a private method and relies // on the input being correct and valid! void DDSInput::internal_seek_subimage (int cubeface, int miplevel, unsigned int& w, unsigned int& h, unsigned int& d) { // early out for cubemaps that don't contain the requested face if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP && !(m_dds.caps.flags2 & (DDS_CAPS2_CUBEMAP_POSITIVEX << cubeface))) { w = h = d = 0; return; } // we can easily calculate the offsets because both compressed and // uncompressed images have predictable length // calculate the offset; start with after the header unsigned int ofs = 128; unsigned int len; // this loop is used to iterate over cube map sides, or run once in the // case of ordinary 2D or 3D images for (int j = 0; j <= cubeface; j++) { w = m_dds.width; h = m_dds.height; d = m_dds.depth; // skip subimages preceding the one we're seeking to // if we have no mipmaps, the modulo formula doesn't work and we // don't skip at all, so just add the offset and continue if (m_dds.mipmaps < 2) { if (j > 0) { if (m_dds.fmt.flags & DDS_PF_FOURCC) // only check for DXT1 - all other formats have same block // size len = squish::GetStorageRequirements(w, h, m_dds.fmt.fourCC == DDS_4CC_DXT1 ? squish::kDxt1 : squish::kDxt5); else len = w * h * d * m_Bpp; ofs += len; } continue; } for (int i = 0; i < miplevel; i++) { if (m_dds.fmt.flags & DDS_PF_FOURCC) // only check for DXT1 - all other formats have same block size len = squish::GetStorageRequirements(w, h, m_dds.fmt.fourCC == DDS_4CC_DXT1 ? squish::kDxt1 : squish::kDxt5); else len = w * h * d * m_Bpp; ofs += len; w >>= 1; if (!w) w = 1; h >>= 1; if (!h) h = 1; d >>= 1; if (!d) d = 1; } } // seek to the offset we've found fseek (m_file, ofs, SEEK_SET); } bool DDSInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { // early out if (subimage == current_subimage() && miplevel == current_miplevel()) { newspec = m_spec; return true; } if (subimage != 0) return false; // don't seek if the image doesn't contain mipmaps, isn't 3D or a cube map, // and don't seek out of bounds if (miplevel < 0 || (!(m_dds.caps.flags1 & DDS_CAPS1_COMPLEX) && miplevel != 0) || (unsigned int)miplevel >= m_dds.mipmaps) return false; // clear buffer so that readimage is called m_buf.clear(); // for cube maps, the seek will be performed when reading a tile instead unsigned int w = 0, h = 0, d = 0; if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP) { // calc sizes separately for cube maps w = m_dds.width; h = m_dds.height; d = m_dds.depth; for (int i = 1; i < miplevel; i++) { w >>= 1; if (w < 1) w = 1; h >>= 1; if (h < 1) h = 1; d >>= 1; if (d < 1) d = 1; } // create imagespec for the 3x2 cube map layout #ifdef DDS_3X2_CUBE_MAP_LAYOUT m_spec = ImageSpec (w * 3, h * 2, m_nchans, TypeDesc::UINT8); #else // 1x6 layout m_spec = ImageSpec (w, h * 6, m_nchans, TypeDesc::UINT8); #endif // DDS_3X2_CUBE_MAP_LAYOUT m_spec.depth = d; m_spec.tile_width = m_spec.full_width = w; m_spec.tile_height = m_spec.full_height = h; m_spec.tile_depth = m_spec.full_depth = d; } else { internal_seek_subimage(0, miplevel, w, h, d); // create imagespec m_spec = ImageSpec (w, h, m_nchans, TypeDesc::UINT8); m_spec.depth = d; } // fill the imagespec if (m_dds.fmt.flags & DDS_PF_FOURCC) { std::string tempstr = ""; tempstr += ((char *)&m_dds.fmt.fourCC)[0]; tempstr += ((char *)&m_dds.fmt.fourCC)[1]; tempstr += ((char *)&m_dds.fmt.fourCC)[2]; tempstr += ((char *)&m_dds.fmt.fourCC)[3]; m_spec.attribute ("compression", tempstr); } m_spec.attribute ("oiio:BitsPerSample", m_dds.fmt.bpp); m_spec.default_channel_names (); // detect texture type if (m_dds.caps.flags2 & DDS_CAPS2_VOLUME) { m_spec.attribute ("texturetype", "Volume Texture"); m_spec.attribute ("textureformat", "Volume Texture"); } else if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP) { m_spec.attribute ("texturetype", "Environment"); m_spec.attribute ("textureformat", "CubeFace Environment"); // check available cube map sides std::string sides = ""; if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP_POSITIVEX) sides += "+x"; if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP_NEGATIVEX) { if (sides.size()) sides += " "; sides += "-x"; } if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP_POSITIVEY) { if (sides.size()) sides += " "; sides += "+y"; } if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP_NEGATIVEY) { if (sides.size()) sides += " "; sides += "-y"; } if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP_POSITIVEZ) { if (sides.size()) sides += " "; sides += "+z"; } if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP_NEGATIVEZ) { if (sides.size()) sides += " "; sides += "-z"; } m_spec.attribute ("dds:CubeMapSides", sides); } else { m_spec.attribute ("texturetype", "Plain Texture"); m_spec.attribute ("textureformat", "Plain Texture"); } m_subimage = subimage; m_miplevel = miplevel; newspec = spec (); return true; } bool DDSInput::internal_readimg (unsigned char *dst, int w, int h, int d) { if (m_dds.fmt.flags & DDS_PF_FOURCC) { // compressed image int flags = 0; switch (m_dds.fmt.fourCC) { case DDS_4CC_DXT1: flags = squish::kDxt1; break; // DXT2 and 3 are the same, only 2 has pre-multiplied alpha case DDS_4CC_DXT2: case DDS_4CC_DXT3: flags = squish::kDxt3; break; // DXT4 and 5 are the same, only 4 has pre-multiplied alpha case DDS_4CC_DXT4: case DDS_4CC_DXT5: flags = squish::kDxt5; break; } // create source buffer std::vector tmp(squish::GetStorageRequirements (w, h, flags)); // load image into buffer if (! fread (&tmp[0], tmp.size(), 1)) return false; // decompress image squish::DecompressImage (dst, w, h, &tmp[0], flags); tmp.clear(); // correct pre-multiplied alpha, if necessary if (m_dds.fmt.fourCC == DDS_4CC_DXT2 || m_dds.fmt.fourCC == DDS_4CC_DXT4) { int k; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { k = (y * w + x) * 4; dst[k + 0] = (unsigned char)((int)dst[k + 0] * 255 / (int)dst[k + 3]); dst[k + 1] = (unsigned char)((int)dst[k + 1] * 255 / (int)dst[k + 3]); dst[k + 2] = (unsigned char)((int)dst[k + 2] * 255 / (int)dst[k + 3]); } } } } else { // uncompressed image // HACK: shortcut for luminance if (m_dds.fmt.flags & DDS_PF_LUMINANCE) { return fread (dst, w * m_Bpp, h); } int k, pixel = 0; for (int z = 0; z < d; z++) { for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (! fread (&pixel, 1, m_Bpp)) return false; k = (z * h * w + y * w + x) * m_spec.nchannels; dst[k + 0] = ((pixel & m_dds.fmt.rmask) >> m_redR) << m_redL; dst[k + 1] = ((pixel & m_dds.fmt.gmask) >> m_greenR) << m_greenL; dst[k + 2] = ((pixel & m_dds.fmt.bmask) >> m_blueR) << m_blueL; if (m_dds.fmt.flags & DDS_PF_ALPHA) dst[k + 3] = ((pixel & m_dds.fmt.amask) >> m_alphaR) << m_alphaL; } } } } return true; } bool DDSInput::readimg_scanlines () { //std::cerr << "[dds] readimg: " << ftell (m_file) << "\n"; // resize destination buffer m_buf.resize (m_spec.scanline_bytes() * m_spec.height * m_spec.depth /*/ (1 << m_miplevel)*/); return internal_readimg (&m_buf[0], m_spec.width, m_spec.height, m_spec.depth); } bool DDSInput::readimg_tiles () { // resize destination buffer m_buf.resize (m_spec.tile_bytes()); return internal_readimg (&m_buf[0], m_spec.tile_width, m_spec.tile_height, m_spec.tile_depth); } bool DDSInput::close () { if (m_file) { fclose (m_file); m_file = NULL; } init(); // Reset to initial state return true; } bool DDSInput::read_native_scanline (int y, int z, void *data) { // don't proceed if a cube map - use tiles then instead if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP) return false; if (m_buf.empty ()) readimg_scanlines (); size_t size = spec().scanline_bytes(); memcpy (data, &m_buf[0] + z * m_spec.height * size + y * size, size); return true; } bool DDSInput::read_native_tile (int x, int y, int z, void *data) { // static ints to keep track of the current cube face and re-seek and // re-read face static int lastx = -1, lasty = -1, lastz = -1; // don't proceed if not a cube map - use scanlines then instead if (!(m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP)) return false; // make sure we get the right dimensions if (x % m_spec.tile_width || y % m_spec.tile_height || z % m_spec.tile_width) return false; if (m_buf.empty() || x != lastx || y != lasty || z != lastz) { lastx = x; lasty = y; lastz = z; unsigned int w, h, d; #ifdef DDS_3X2_CUBE_MAP_LAYOUT internal_seek_subimage (((x / m_spec.tile_width) << 1) + y / m_spec.tile_height, m_miplevel, w, h, d); #else // 1x6 layout internal_seek_subimage (y / m_spec.tile_height, m_miplevel, w, h, d); #endif // DDS_3X2_CUBE_MAP_LAYOUT if (!w && !h && !d) // face not present in file, black-pad the image memset (&m_buf[0], 0, m_spec.tile_bytes()); else readimg_tiles (); } memcpy (data, &m_buf[0], m_spec.tile_bytes()); return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/0000755000175000017500000000000012271062644020607 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/simd.h0000644000175000017500000000274612271062644021725 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_SIMD_H #define SQUISH_SIMD_H #include "maths.h" #if SQUISH_USE_ALTIVEC #include "simd_ve.h" #elif SQUISH_USE_SSE #include "simd_sse.h" #else #include "simd_float.h" #endif #endif // ndef SQUISH_SIMD_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/rangefit.cpp0000644000175000017500000001170212271062644023113 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #include "rangefit.h" #include "colourset.h" #include "colourblock.h" #include namespace squish { RangeFit::RangeFit( ColourSet const* colours, int flags, float* metric ) : ColourFit( colours, flags ) { // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) if( metric ) m_metric = Vec3( metric[0], metric[1], metric[2] ); else m_metric = Vec3( 1.0f ); // initialise the best error m_besterror = FLT_MAX; // cache some values int const count = m_colours->GetCount(); Vec3 const* values = m_colours->GetPoints(); float const* weights = m_colours->GetWeights(); // get the covariance matrix Sym3x3 covariance = ComputeWeightedCovariance( count, values, weights ); // compute the principle component Vec3 principle = ComputePrincipleComponent( covariance ); // get the min and max range as the codebook endpoints Vec3 start( 0.0f ); Vec3 end( 0.0f ); if( count > 0 ) { float min, max; // compute the range start = end = values[0]; min = max = Dot( values[0], principle ); for( int i = 1; i < count; ++i ) { float val = Dot( values[i], principle ); if( val < min ) { start = values[i]; min = val; } else if( val > max ) { end = values[i]; max = val; } } } // clamp the output to [0, 1] Vec3 const one( 1.0f ); Vec3 const zero( 0.0f ); start = Min( one, Max( zero, start ) ); end = Min( one, Max( zero, end ) ); // clamp to the grid and save Vec3 const grid( 31.0f, 63.0f, 31.0f ); Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f ); Vec3 const half( 0.5f ); m_start = Truncate( grid*start + half )*gridrcp; m_end = Truncate( grid*end + half )*gridrcp; } void RangeFit::Compress3( void* block ) { // cache some values int const count = m_colours->GetCount(); Vec3 const* values = m_colours->GetPoints(); // create a codebook Vec3 codes[3]; codes[0] = m_start; codes[1] = m_end; codes[2] = 0.5f*m_start + 0.5f*m_end; // match each point to the closest code u8 closest[16]; float error = 0.0f; for( int i = 0; i < count; ++i ) { // find the closest code float dist = FLT_MAX; int idx = 0; for( int j = 0; j < 3; ++j ) { float d = LengthSquared( m_metric*( values[i] - codes[j] ) ); if( d < dist ) { dist = d; idx = j; } } // save the index closest[i] = ( u8 )idx; // accumulate the error error += dist; } // save this scheme if it wins if( error < m_besterror ) { // remap the indices u8 indices[16]; m_colours->RemapIndices( closest, indices ); // save the block WriteColourBlock3( m_start, m_end, indices, block ); // save the error m_besterror = error; } } void RangeFit::Compress4( void* block ) { // cache some values int const count = m_colours->GetCount(); Vec3 const* values = m_colours->GetPoints(); // create a codebook Vec3 codes[4]; codes[0] = m_start; codes[1] = m_end; codes[2] = ( 2.0f/3.0f )*m_start + ( 1.0f/3.0f )*m_end; codes[3] = ( 1.0f/3.0f )*m_start + ( 2.0f/3.0f )*m_end; // match each point to the closest code u8 closest[16]; float error = 0.0f; for( int i = 0; i < count; ++i ) { // find the closest code float dist = FLT_MAX; int idx = 0; for( int j = 0; j < 4; ++j ) { float d = LengthSquared( m_metric*( values[i] - codes[j] ) ); if( d < dist ) { dist = d; idx = j; } } // save the index closest[i] = ( u8 )idx; // accumulate the error error += dist; } // save this scheme if it wins if( error < m_besterror ) { // remap the indices u8 indices[16]; m_colours->RemapIndices( closest, indices ); // save the block WriteColourBlock4( m_start, m_end, indices, block ); // save the error m_besterror = error; } } } // namespace squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/singlecolourfit.h0000644000175000017500000000354612271062644024200 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_SINGLECOLOURFIT_H #define SQUISH_SINGLECOLOURFIT_H #include "squish.h" #include "colourfit.h" namespace squish { class ColourSet; struct SingleColourLookup; class SingleColourFit : public ColourFit { public: SingleColourFit( ColourSet const* colours, int flags ); private: virtual void Compress3( void* block ); virtual void Compress4( void* block ); void ComputeEndPoints( SingleColourLookup const* const* lookups ); u8 m_colour[3]; Vec3 m_start; Vec3 m_end; u8 m_index; int m_error; int m_besterror; }; } // namespace squish #endif // ndef SQUISH_SINGLECOLOURFIT_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/colourset.h0000644000175000017500000000364612271062644023010 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_COLOURSET_H #define SQUISH_COLOURSET_H #include "squish.h" #include "maths.h" namespace squish { /*! @brief Represents a set of block colours */ class ColourSet { public: ColourSet( u8 const* rgba, int mask, int flags ); int GetCount() const { return m_count; } Vec3 const* GetPoints() const { return m_points; } float const* GetWeights() const { return m_weights; } bool IsTransparent() const { return m_transparent; } void RemapIndices( u8 const* source, u8* target ) const; private: int m_count; Vec3 m_points[16]; float m_weights[16]; int m_remap[16]; bool m_transparent; }; } // namespace sqish #endif // ndef SQUISH_COLOURSET_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/maths.cpp0000644000175000017500000001444312271062644022435 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ /*! @file The symmetric eigensystem solver algorithm is from http://www.geometrictools.com/Documentation/EigenSymmetric3x3.pdf */ #include "maths.h" #include "simd.h" #include namespace squish { Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights ) { // compute the centroid float total = 0.0f; Vec3 centroid( 0.0f ); for( int i = 0; i < n; ++i ) { total += weights[i]; centroid += weights[i]*points[i]; } if( total > FLT_EPSILON ) centroid /= total; // accumulate the covariance matrix Sym3x3 covariance( 0.0f ); for( int i = 0; i < n; ++i ) { Vec3 a = points[i] - centroid; Vec3 b = weights[i]*a; covariance[0] += a.X()*b.X(); covariance[1] += a.X()*b.Y(); covariance[2] += a.X()*b.Z(); covariance[3] += a.Y()*b.Y(); covariance[4] += a.Y()*b.Z(); covariance[5] += a.Z()*b.Z(); } // return it return covariance; } #if 0 static Vec3 GetMultiplicity1Evector( Sym3x3 const& matrix, float evalue ) { // compute M Sym3x3 m; m[0] = matrix[0] - evalue; m[1] = matrix[1]; m[2] = matrix[2]; m[3] = matrix[3] - evalue; m[4] = matrix[4]; m[5] = matrix[5] - evalue; // compute U Sym3x3 u; u[0] = m[3]*m[5] - m[4]*m[4]; u[1] = m[2]*m[4] - m[1]*m[5]; u[2] = m[1]*m[4] - m[2]*m[3]; u[3] = m[0]*m[5] - m[2]*m[2]; u[4] = m[1]*m[2] - m[4]*m[0]; u[5] = m[0]*m[3] - m[1]*m[1]; // find the largest component float mc = std::fabs( u[0] ); int mi = 0; for( int i = 1; i < 6; ++i ) { float c = std::fabs( u[i] ); if( c > mc ) { mc = c; mi = i; } } // pick the column with this component switch( mi ) { case 0: return Vec3( u[0], u[1], u[2] ); case 1: case 3: return Vec3( u[1], u[3], u[4] ); default: return Vec3( u[2], u[4], u[5] ); } } static Vec3 GetMultiplicity2Evector( Sym3x3 const& matrix, float evalue ) { // compute M Sym3x3 m; m[0] = matrix[0] - evalue; m[1] = matrix[1]; m[2] = matrix[2]; m[3] = matrix[3] - evalue; m[4] = matrix[4]; m[5] = matrix[5] - evalue; // find the largest component float mc = std::fabs( m[0] ); int mi = 0; for( int i = 1; i < 6; ++i ) { float c = std::fabs( m[i] ); if( c > mc ) { mc = c; mi = i; } } // pick the first eigenvector based on this index switch( mi ) { case 0: case 1: return Vec3( -m[1], m[0], 0.0f ); case 2: return Vec3( m[2], 0.0f, -m[0] ); case 3: case 4: return Vec3( 0.0f, -m[4], m[3] ); default: return Vec3( 0.0f, -m[5], m[4] ); } } Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ) { // compute the cubic coefficients float c0 = matrix[0]*matrix[3]*matrix[5] + 2.0f*matrix[1]*matrix[2]*matrix[4] - matrix[0]*matrix[4]*matrix[4] - matrix[3]*matrix[2]*matrix[2] - matrix[5]*matrix[1]*matrix[1]; float c1 = matrix[0]*matrix[3] + matrix[0]*matrix[5] + matrix[3]*matrix[5] - matrix[1]*matrix[1] - matrix[2]*matrix[2] - matrix[4]*matrix[4]; float c2 = matrix[0] + matrix[3] + matrix[5]; // compute the quadratic coefficients float a = c1 - ( 1.0f/3.0f )*c2*c2; float b = ( -2.0f/27.0f )*c2*c2*c2 + ( 1.0f/3.0f )*c1*c2 - c0; // compute the root count check float Q = 0.25f*b*b + ( 1.0f/27.0f )*a*a*a; // test the multiplicity if( FLT_EPSILON < Q ) { // only one root, which implies we have a multiple of the identity return Vec3( 1.0f ); } else if( Q < -FLT_EPSILON ) { // three distinct roots float theta = std::atan2( std::sqrt( -Q ), -0.5f*b ); float rho = std::sqrt( 0.25f*b*b - Q ); float rt = std::pow( rho, 1.0f/3.0f ); float ct = std::cos( theta/3.0f ); float st = std::sin( theta/3.0f ); float l1 = ( 1.0f/3.0f )*c2 + 2.0f*rt*ct; float l2 = ( 1.0f/3.0f )*c2 - rt*( ct + ( float )sqrt( 3.0f )*st ); float l3 = ( 1.0f/3.0f )*c2 - rt*( ct - ( float )sqrt( 3.0f )*st ); // pick the larger if( std::fabs( l2 ) > std::fabs( l1 ) ) l1 = l2; if( std::fabs( l3 ) > std::fabs( l1 ) ) l1 = l3; // get the eigenvector return GetMultiplicity1Evector( matrix, l1 ); } else // if( -FLT_EPSILON <= Q && Q <= FLT_EPSILON ) { // two roots float rt; if( b < 0.0f ) rt = -std::pow( -0.5f*b, 1.0f/3.0f ); else rt = std::pow( 0.5f*b, 1.0f/3.0f ); float l1 = ( 1.0f/3.0f )*c2 + rt; // repeated float l2 = ( 1.0f/3.0f )*c2 - 2.0f*rt; // get the eigenvector if( std::fabs( l1 ) > std::fabs( l2 ) ) return GetMultiplicity2Evector( matrix, l1 ); else return GetMultiplicity1Evector( matrix, l2 ); } } #else #define POWER_ITERATION_COUNT 8 Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ) { Vec4 const row0( matrix[0], matrix[1], matrix[2], 0.0f ); Vec4 const row1( matrix[1], matrix[3], matrix[4], 0.0f ); Vec4 const row2( matrix[2], matrix[4], matrix[5], 0.0f ); Vec4 v = VEC4_CONST( 1.0f ); for( int i = 0; i < POWER_ITERATION_COUNT; ++i ) { // matrix multiply Vec4 w = row0*v.SplatX(); w = MultiplyAdd(row1, v.SplatY(), w); w = MultiplyAdd(row2, v.SplatZ(), w); // get max component from xyz in all channels Vec4 a = Max(w.SplatX(), Max(w.SplatY(), w.SplatZ())); // divide through and advance v = w*Reciprocal(a); } return v.GetVec3(); } #endif } // namespace squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/rangefit.h0000644000175000017500000000334012271062644022557 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_RANGEFIT_H #define SQUISH_RANGEFIT_H #include "squish.h" #include "colourfit.h" #include "maths.h" namespace squish { class ColourSet; class RangeFit : public ColourFit { public: RangeFit( ColourSet const* colours, int flags, float* metric ); private: virtual void Compress3( void* block ); virtual void Compress4( void* block ); Vec3 m_metric; Vec3 m_start; Vec3 m_end; float m_besterror; }; } // squish #endif // ndef SQUISH_RANGEFIT_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/alpha.cpp0000644000175000017500000002003612271062644022401 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #include "alpha.h" #include #include namespace squish { static int FloatToInt( float a, int limit ) { // use ANSI round-to-zero behaviour to get round-to-nearest int i = ( int )( a + 0.5f ); // clamp to the limit if( i < 0 ) i = 0; else if( i > limit ) i = limit; // done return i; } void CompressAlphaDxt3( u8 const* rgba, int mask, void* block ) { u8* bytes = reinterpret_cast< u8* >( block ); // quantise and pack the alpha values pairwise for( int i = 0; i < 8; ++i ) { // quantise down to 4 bits float alpha1 = ( float )rgba[8*i + 3] * ( 15.0f/255.0f ); float alpha2 = ( float )rgba[8*i + 7] * ( 15.0f/255.0f ); int quant1 = FloatToInt( alpha1, 15 ); int quant2 = FloatToInt( alpha2, 15 ); // set alpha to zero where masked int bit1 = 1 << ( 2*i ); int bit2 = 1 << ( 2*i + 1 ); if( ( mask & bit1 ) == 0 ) quant1 = 0; if( ( mask & bit2 ) == 0 ) quant2 = 0; // pack into the byte bytes[i] = ( u8 )( quant1 | ( quant2 << 4 ) ); } } void DecompressAlphaDxt3( u8* rgba, void const* block ) { u8 const* bytes = reinterpret_cast< u8 const* >( block ); // unpack the alpha values pairwise for( int i = 0; i < 8; ++i ) { // quantise down to 4 bits u8 quant = bytes[i]; // unpack the values u8 lo = quant & 0x0f; u8 hi = quant & 0xf0; // convert back up to bytes rgba[8*i + 3] = lo | ( lo << 4 ); rgba[8*i + 7] = hi | ( hi >> 4 ); } } static void FixRange( int& min, int& max, int steps ) { if( max - min < steps ) max = std::min( min + steps, 255 ); if( max - min < steps ) min = std::max( 0, max - steps ); } static int FitCodes( u8 const* rgba, int mask, u8 const* codes, u8* indices ) { // fit each alpha value to the codebook int err = 0; for( int i = 0; i < 16; ++i ) { // check this pixel is valid int bit = 1 << i; if( ( mask & bit ) == 0 ) { // use the first code indices[i] = 0; continue; } // find the least error and corresponding index int value = rgba[4*i + 3]; int least = INT_MAX; int index = 0; for( int j = 0; j < 8; ++j ) { // get the squared error from this code int dist = ( int )value - ( int )codes[j]; dist *= dist; // compare with the best so far if( dist < least ) { least = dist; index = j; } } // save this index and accumulate the error indices[i] = ( u8 )index; err += least; } // return the total error return err; } static void WriteAlphaBlock( int alpha0, int alpha1, u8 const* indices, void* block ) { u8* bytes = reinterpret_cast< u8* >( block ); // write the first two bytes bytes[0] = ( u8 )alpha0; bytes[1] = ( u8 )alpha1; // pack the indices with 3 bits each u8* dest = bytes + 2; u8 const* src = indices; for( int i = 0; i < 2; ++i ) { // pack 8 3-bit values int value = 0; for( int j = 0; j < 8; ++j ) { int index = *src++; value |= ( index << 3*j ); } // store in 3 bytes for( int j = 0; j < 3; ++j ) { int byte = ( value >> 8*j ) & 0xff; *dest++ = ( u8 )byte; } } } static void WriteAlphaBlock5( int alpha0, int alpha1, u8 const* indices, void* block ) { // check the relative values of the endpoints if( alpha0 > alpha1 ) { // swap the indices u8 swapped[16]; for( int i = 0; i < 16; ++i ) { u8 index = indices[i]; if( index == 0 ) swapped[i] = 1; else if( index == 1 ) swapped[i] = 0; else if( index <= 5 ) swapped[i] = 7 - index; else swapped[i] = index; } // write the block WriteAlphaBlock( alpha1, alpha0, swapped, block ); } else { // write the block WriteAlphaBlock( alpha0, alpha1, indices, block ); } } static void WriteAlphaBlock7( int alpha0, int alpha1, u8 const* indices, void* block ) { // check the relative values of the endpoints if( alpha0 < alpha1 ) { // swap the indices u8 swapped[16]; for( int i = 0; i < 16; ++i ) { u8 index = indices[i]; if( index == 0 ) swapped[i] = 1; else if( index == 1 ) swapped[i] = 0; else swapped[i] = 9 - index; } // write the block WriteAlphaBlock( alpha1, alpha0, swapped, block ); } else { // write the block WriteAlphaBlock( alpha0, alpha1, indices, block ); } } void CompressAlphaDxt5( u8 const* rgba, int mask, void* block ) { // get the range for 5-alpha and 7-alpha interpolation int min5 = 255; int max5 = 0; int min7 = 255; int max7 = 0; for( int i = 0; i < 16; ++i ) { // check this pixel is valid int bit = 1 << i; if( ( mask & bit ) == 0 ) continue; // incorporate into the min/max int value = rgba[4*i + 3]; if( value < min7 ) min7 = value; if( value > max7 ) max7 = value; if( value != 0 && value < min5 ) min5 = value; if( value != 255 && value > max5 ) max5 = value; } // handle the case that no valid range was found if( min5 > max5 ) min5 = max5; if( min7 > max7 ) min7 = max7; // fix the range to be the minimum in each case FixRange( min5, max5, 5 ); FixRange( min7, max7, 7 ); // set up the 5-alpha code book u8 codes5[8]; codes5[0] = ( u8 )min5; codes5[1] = ( u8 )max5; for( int i = 1; i < 5; ++i ) codes5[1 + i] = ( u8 )( ( ( 5 - i )*min5 + i*max5 )/5 ); codes5[6] = 0; codes5[7] = 255; // set up the 7-alpha code book u8 codes7[8]; codes7[0] = ( u8 )min7; codes7[1] = ( u8 )max7; for( int i = 1; i < 7; ++i ) codes7[1 + i] = ( u8 )( ( ( 7 - i )*min7 + i*max7 )/7 ); // fit the data to both code books u8 indices5[16]; u8 indices7[16]; int err5 = FitCodes( rgba, mask, codes5, indices5 ); int err7 = FitCodes( rgba, mask, codes7, indices7 ); // save the block with least error if( err5 <= err7 ) WriteAlphaBlock5( min5, max5, indices5, block ); else WriteAlphaBlock7( min7, max7, indices7, block ); } void DecompressAlphaDxt5( u8* rgba, void const* block ) { // get the two alpha values u8 const* bytes = reinterpret_cast< u8 const* >( block ); int alpha0 = bytes[0]; int alpha1 = bytes[1]; // compare the values to build the codebook u8 codes[8]; codes[0] = ( u8 )alpha0; codes[1] = ( u8 )alpha1; if( alpha0 <= alpha1 ) { // use 5-alpha codebook for( int i = 1; i < 5; ++i ) codes[1 + i] = ( u8 )( ( ( 5 - i )*alpha0 + i*alpha1 )/5 ); codes[6] = 0; codes[7] = 255; } else { // use 7-alpha codebook for( int i = 1; i < 7; ++i ) codes[1 + i] = ( u8 )( ( ( 7 - i )*alpha0 + i*alpha1 )/7 ); } // decode the indices u8 indices[16]; u8 const* src = bytes + 2; u8* dest = indices; for( int i = 0; i < 2; ++i ) { // grab 3 bytes int value = 0; for( int j = 0; j < 3; ++j ) { int byte = *src++; value |= ( byte << 8*j ); } // unpack 8 3-bit values from it for( int j = 0; j < 8; ++j ) { int index = ( value >> 3*j ) & 0x7; *dest++ = ( u8 )index; } } // write out the indexed codebook values for( int i = 0; i < 16; ++i ) rgba[4*i + 3] = codes[indices[i]]; } } // namespace squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/ChangeLog0000644000175000017500000000340212271062644022360 0ustar mfvmfv1.10 * Iterative cluster fit is now considered to be a new compression mode * The core cluster fit is now 4x faster using contributions by Ignacio Castano from NVIDIA * The single colour lookup table has been halved by exploiting symmetry 1.9 * Added contributed SSE1 truncate implementation * Changed use of SQUISH_USE_SSE to be 1 for SSE and 2 for SSE2 instructions * Cluster fit is now iterative to further reduce image error 1.8 * Switched from using floor to trunc for much better SSE performance (again) * Xcode build now expects libpng in /usr/local for extra/squishpng 1.7 * Fixed floating-point equality issue in clusterfit sort (x86 affected only) * Implemented proper SSE(2) floor function for 50% speedup on SSE builds * The range fit implementation now uses the correct colour metric 1.6 * Fixed bug in CompressImage where masked pixels were not skipped over * DXT3 and DXT5 alpha compression now properly use the mask to ignore pixels * Fixed major DXT1 bug that can generate unexpected transparent pixels 1.5 * Added CompressMasked function to handle incomplete DXT blocks more cleanly * Added kWeightColourByAlpha flag for better quality images when alpha blending 1.4 * Fixed stack overflow in rangefit 1.3 * Worked around SSE floor implementation bug, proper fix needed! * This release has visual studio and makefile builds that work 1.2 * Added provably optimal single colour compressor * Added extra/squishgen.cpp that generates single colour lookup tables 1.1 * Fixed a DXT1 colour output bug * Changed argument order for Decompress function to match Compress * Added GetStorageRequirements function * Added CompressImage function * Added DecompressImage function * Moved squishtool.cpp to extra/squishpng.cpp * Added extra/squishtest.cpp 1.0 * Initial release openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/simd_float.h0000644000175000017500000000771112271062644023107 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_SIMD_FLOAT_H #define SQUISH_SIMD_FLOAT_H #include namespace squish { #define VEC4_CONST( X ) Vec4( X ) class Vec4 { public: typedef Vec4 const& Arg; Vec4() {} explicit Vec4( float s ) : m_x( s ), m_y( s ), m_z( s ), m_w( s ) { } Vec4( float x, float y, float z, float w ) : m_x( x ), m_y( y ), m_z( z ), m_w( w ) { } Vec3 GetVec3() const { return Vec3( m_x, m_y, m_z ); } Vec4 SplatX() const { return Vec4( m_x ); } Vec4 SplatY() const { return Vec4( m_y ); } Vec4 SplatZ() const { return Vec4( m_z ); } Vec4 SplatW() const { return Vec4( m_w ); } Vec4& operator+=( Arg v ) { m_x += v.m_x; m_y += v.m_y; m_z += v.m_z; m_w += v.m_w; return *this; } Vec4& operator-=( Arg v ) { m_x -= v.m_x; m_y -= v.m_y; m_z -= v.m_z; m_w -= v.m_w; return *this; } Vec4& operator*=( Arg v ) { m_x *= v.m_x; m_y *= v.m_y; m_z *= v.m_z; m_w *= v.m_w; return *this; } friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) { Vec4 copy( left ); return copy += right; } friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) { Vec4 copy( left ); return copy -= right; } friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) { Vec4 copy( left ); return copy *= right; } //! Returns a*b + c friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) { return a*b + c; } //! Returns -( a*b - c ) friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) { return c - a*b; } friend Vec4 Reciprocal( Vec4::Arg v ) { return Vec4( 1.0f/v.m_x, 1.0f/v.m_y, 1.0f/v.m_z, 1.0f/v.m_w ); } friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) { return Vec4( std::min( left.m_x, right.m_x ), std::min( left.m_y, right.m_y ), std::min( left.m_z, right.m_z ), std::min( left.m_w, right.m_w ) ); } friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) { return Vec4( std::max( left.m_x, right.m_x ), std::max( left.m_y, right.m_y ), std::max( left.m_z, right.m_z ), std::max( left.m_w, right.m_w ) ); } friend Vec4 Truncate( Vec4::Arg v ) { return Vec4( v.m_x > 0.0f ? std::floor( v.m_x ) : std::ceil( v.m_x ), v.m_y > 0.0f ? std::floor( v.m_y ) : std::ceil( v.m_y ), v.m_z > 0.0f ? std::floor( v.m_z ) : std::ceil( v.m_z ), v.m_w > 0.0f ? std::floor( v.m_w ) : std::ceil( v.m_w ) ); } friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) { return left.m_x < right.m_x || left.m_y < right.m_y || left.m_z < right.m_z || left.m_w < right.m_w; } private: float m_x; float m_y; float m_z; float m_w; }; } // namespace squish #endif // ndef SQUISH_SIMD_FLOAT_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/colourfit.h0000644000175000017500000000336312271062644022773 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_COLOURFIT_H #define SQUISH_COLOURFIT_H #include "squish.h" #include #include "maths.h" namespace squish { class ColourSet; class ColourFit { public: ColourFit( ColourSet const* colours, int flags ); virtual ~ColourFit(); void Compress( void* block ); protected: virtual void Compress3( void* block ) = 0; virtual void Compress4( void* block ) = 0; ColourSet const* m_colours; int m_flags; }; } // namespace squish #endif // ndef SQUISH_COLOURFIT_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/maths.h0000644000175000017500000001042212271062644022073 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_MATHS_H #define SQUISH_MATHS_H #include #include #include "config.h" namespace squish { class Vec3 { public: typedef Vec3 const& Arg; Vec3() { } explicit Vec3( float s ) { m_x = s; m_y = s; m_z = s; } Vec3( float x, float y, float z ) { m_x = x; m_y = y; m_z = z; } float X() const { return m_x; } float Y() const { return m_y; } float Z() const { return m_z; } Vec3 operator-() const { return Vec3( -m_x, -m_y, -m_z ); } Vec3& operator+=( Arg v ) { m_x += v.m_x; m_y += v.m_y; m_z += v.m_z; return *this; } Vec3& operator-=( Arg v ) { m_x -= v.m_x; m_y -= v.m_y; m_z -= v.m_z; return *this; } Vec3& operator*=( Arg v ) { m_x *= v.m_x; m_y *= v.m_y; m_z *= v.m_z; return *this; } Vec3& operator*=( float s ) { m_x *= s; m_y *= s; m_z *= s; return *this; } Vec3& operator/=( Arg v ) { m_x /= v.m_x; m_y /= v.m_y; m_z /= v.m_z; return *this; } Vec3& operator/=( float s ) { float t = 1.0f/s; m_x *= t; m_y *= t; m_z *= t; return *this; } friend Vec3 operator+( Arg left, Arg right ) { Vec3 copy( left ); return copy += right; } friend Vec3 operator-( Arg left, Arg right ) { Vec3 copy( left ); return copy -= right; } friend Vec3 operator*( Arg left, Arg right ) { Vec3 copy( left ); return copy *= right; } friend Vec3 operator*( Arg left, float right ) { Vec3 copy( left ); return copy *= right; } friend Vec3 operator*( float left, Arg right ) { Vec3 copy( right ); return copy *= left; } friend Vec3 operator/( Arg left, Arg right ) { Vec3 copy( left ); return copy /= right; } friend Vec3 operator/( Arg left, float right ) { Vec3 copy( left ); return copy /= right; } friend float Dot( Arg left, Arg right ) { return left.m_x*right.m_x + left.m_y*right.m_y + left.m_z*right.m_z; } friend Vec3 Min( Arg left, Arg right ) { return Vec3( std::min( left.m_x, right.m_x ), std::min( left.m_y, right.m_y ), std::min( left.m_z, right.m_z ) ); } friend Vec3 Max( Arg left, Arg right ) { return Vec3( std::max( left.m_x, right.m_x ), std::max( left.m_y, right.m_y ), std::max( left.m_z, right.m_z ) ); } friend Vec3 Truncate( Arg v ) { return Vec3( v.m_x > 0.0f ? std::floor( v.m_x ) : std::ceil( v.m_x ), v.m_y > 0.0f ? std::floor( v.m_y ) : std::ceil( v.m_y ), v.m_z > 0.0f ? std::floor( v.m_z ) : std::ceil( v.m_z ) ); } private: float m_x; float m_y; float m_z; }; inline float LengthSquared( Vec3::Arg v ) { return Dot( v, v ); } class Sym3x3 { public: Sym3x3() { } Sym3x3( float s ) { for( int i = 0; i < 6; ++i ) m_x[i] = s; } float operator[]( int index ) const { return m_x[index]; } float& operator[]( int index ) { return m_x[index]; } private: float m_x[6]; }; Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights ); Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ); } // namespace squish #endif // ndef SQUISH_MATHS_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/singlecolourfit.cpp0000644000175000017500000001045312271062644024526 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #include "singlecolourfit.h" #include "colourset.h" #include "colourblock.h" namespace squish { struct SourceBlock { u8 start; u8 end; u8 error; }; struct SingleColourLookup { SourceBlock sources[2]; }; #include "singlecolourlookup.inl" static int FloatToInt( float a, int limit ) { // use ANSI round-to-zero behaviour to get round-to-nearest int i = ( int )( a + 0.5f ); // clamp to the limit if( i < 0 ) i = 0; else if( i > limit ) i = limit; // done return i; } SingleColourFit::SingleColourFit( ColourSet const* colours, int flags ) : ColourFit( colours, flags ) { // grab the single colour Vec3 const* values = m_colours->GetPoints(); m_colour[0] = ( u8 )FloatToInt( 255.0f*values->X(), 255 ); m_colour[1] = ( u8 )FloatToInt( 255.0f*values->Y(), 255 ); m_colour[2] = ( u8 )FloatToInt( 255.0f*values->Z(), 255 ); // initialise the best error m_besterror = INT_MAX; } void SingleColourFit::Compress3( void* block ) { // build the table of lookups SingleColourLookup const* const lookups[] = { lookup_5_3, lookup_6_3, lookup_5_3 }; // find the best end-points and index ComputeEndPoints( lookups ); // build the block if we win if( m_error < m_besterror ) { // remap the indices u8 indices[16]; m_colours->RemapIndices( &m_index, indices ); // save the block WriteColourBlock3( m_start, m_end, indices, block ); // save the error m_besterror = m_error; } } void SingleColourFit::Compress4( void* block ) { // build the table of lookups SingleColourLookup const* const lookups[] = { lookup_5_4, lookup_6_4, lookup_5_4 }; // find the best end-points and index ComputeEndPoints( lookups ); // build the block if we win if( m_error < m_besterror ) { // remap the indices u8 indices[16]; m_colours->RemapIndices( &m_index, indices ); // save the block WriteColourBlock4( m_start, m_end, indices, block ); // save the error m_besterror = m_error; } } void SingleColourFit::ComputeEndPoints( SingleColourLookup const* const* lookups ) { // check each index combination (endpoint or intermediate) m_error = INT_MAX; for( int index = 0; index < 2; ++index ) { // check the error for this codebook index SourceBlock const* sources[3]; int error = 0; for( int channel = 0; channel < 3; ++channel ) { // grab the lookup table and index for this channel SingleColourLookup const* lookup = lookups[channel]; int target = m_colour[channel]; // store a pointer to the source for this channel sources[channel] = lookup[target].sources + index; // accumulate the error int diff = sources[channel]->error; error += diff*diff; } // keep it if the error is lower if( error < m_error ) { m_start = Vec3( ( float )sources[0]->start/31.0f, ( float )sources[1]->start/63.0f, ( float )sources[2]->start/31.0f ); m_end = Vec3( ( float )sources[0]->end/31.0f, ( float )sources[1]->end/63.0f, ( float )sources[2]->end/31.0f ); m_index = ( u8 )( 2*index ); m_error = error; } } } } // namespace squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/simd_ve.h0000644000175000017500000001004712271062644022410 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_SIMD_VE_H #define SQUISH_SIMD_VE_H #include #undef bool namespace squish { #define VEC4_CONST( X ) Vec4( ( vector float ){ X } ) class Vec4 { public: typedef Vec4 Arg; Vec4() {} explicit Vec4( vector float v ) : m_v( v ) {} Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {} Vec4& operator=( Vec4 const& arg ) { m_v = arg.m_v; return *this; } explicit Vec4( float s ) { union { vector float v; float c[4]; } u; u.c[0] = s; u.c[1] = s; u.c[2] = s; u.c[3] = s; m_v = u.v; } Vec4( float x, float y, float z, float w ) { union { vector float v; float c[4]; } u; u.c[0] = x; u.c[1] = y; u.c[2] = z; u.c[3] = w; m_v = u.v; } Vec3 GetVec3() const { union { vector float v; float c[4]; } u; u.v = m_v; return Vec3( u.c[0], u.c[1], u.c[2] ); } Vec4 SplatX() const { return Vec4( vec_splat( m_v, 0 ) ); } Vec4 SplatY() const { return Vec4( vec_splat( m_v, 1 ) ); } Vec4 SplatZ() const { return Vec4( vec_splat( m_v, 2 ) ); } Vec4 SplatW() const { return Vec4( vec_splat( m_v, 3 ) ); } Vec4& operator+=( Arg v ) { m_v = vec_add( m_v, v.m_v ); return *this; } Vec4& operator-=( Arg v ) { m_v = vec_sub( m_v, v.m_v ); return *this; } Vec4& operator*=( Arg v ) { m_v = vec_madd( m_v, v.m_v, ( vector float ){ -0.0f } ); return *this; } friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) { return Vec4( vec_add( left.m_v, right.m_v ) ); } friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) { return Vec4( vec_sub( left.m_v, right.m_v ) ); } friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) { return Vec4( vec_madd( left.m_v, right.m_v, ( vector float ){ -0.0f } ) ); } //! Returns a*b + c friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) { return Vec4( vec_madd( a.m_v, b.m_v, c.m_v ) ); } //! Returns -( a*b - c ) friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) { return Vec4( vec_nmsub( a.m_v, b.m_v, c.m_v ) ); } friend Vec4 Reciprocal( Vec4::Arg v ) { // get the reciprocal estimate vector float estimate = vec_re( v.m_v ); // one round of Newton-Rhaphson refinement vector float diff = vec_nmsub( estimate, v.m_v, ( vector float ){ 1.0f } ); return Vec4( vec_madd( diff, estimate, estimate ) ); } friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) { return Vec4( vec_min( left.m_v, right.m_v ) ); } friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) { return Vec4( vec_max( left.m_v, right.m_v ) ); } friend Vec4 Truncate( Vec4::Arg v ) { return Vec4( vec_trunc( v.m_v ) ); } friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) { return vec_any_lt( left.m_v, right.m_v ) != 0; } private: vector float m_v; }; } // namespace squish #endif // ndef SQUISH_SIMD_VE_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/squish.cpp0000644000175000017500000001442112271062644022631 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #include "squish.h" #include "colourset.h" #include "maths.h" #include "rangefit.h" #include "clusterfit.h" #include "colourblock.h" #include "alpha.h" #include "singlecolourfit.h" namespace squish { static int FixFlags( int flags ) { // grab the flag bits int method = flags & ( kDxt1 | kDxt3 | kDxt5 ); int fit = flags & ( kColourIterativeClusterFit | kColourClusterFit | kColourRangeFit ); int extra = flags & kWeightColourByAlpha; // set defaults if( method != kDxt3 && method != kDxt5 ) method = kDxt1; if( fit != kColourRangeFit && fit != kColourIterativeClusterFit ) fit = kColourClusterFit; // done return method | fit | extra; } void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric ) { // fix any bad flags flags = FixFlags( flags ); // get the block locations void* colourBlock = block; void* alphaBock = block; if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) colourBlock = reinterpret_cast< u8* >( block ) + 8; // create the minimal point set ColourSet colours( rgba, mask, flags ); // check the compression type and compress colour if( colours.GetCount() == 1 ) { // always do a single colour fit SingleColourFit fit( &colours, flags ); fit.Compress( colourBlock ); } else if( ( flags & kColourRangeFit ) != 0 || colours.GetCount() == 0 ) { // do a range fit RangeFit fit( &colours, flags, metric ); fit.Compress( colourBlock ); } else { // default to a cluster fit (could be iterative or not) ClusterFit fit( &colours, flags, metric ); fit.Compress( colourBlock ); } // compress alpha separately if necessary if( ( flags & kDxt3 ) != 0 ) CompressAlphaDxt3( rgba, mask, alphaBock ); else if( ( flags & kDxt5 ) != 0 ) CompressAlphaDxt5( rgba, mask, alphaBock ); } void Decompress( u8* rgba, void const* block, int flags ) { // fix any bad flags flags = FixFlags( flags ); // get the block locations void const* colourBlock = block; void const* alphaBock = block; if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) colourBlock = reinterpret_cast< u8 const* >( block ) + 8; // decompress colour DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); // decompress alpha separately if necessary if( ( flags & kDxt3 ) != 0 ) DecompressAlphaDxt3( rgba, alphaBock ); else if( ( flags & kDxt5 ) != 0 ) DecompressAlphaDxt5( rgba, alphaBock ); } int GetStorageRequirements( int width, int height, int flags ) { // fix any bad flags flags = FixFlags( flags ); // compute the storage requirements int blockcount = ( ( width + 3 )/4 ) * ( ( height + 3 )/4 ); int blocksize = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; return blockcount*blocksize; } void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric ) { // fix any bad flags flags = FixFlags( flags ); // initialise the block output u8* targetBlock = reinterpret_cast< u8* >( blocks ); int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; // loop over blocks for( int y = 0; y < height; y += 4 ) { for( int x = 0; x < width; x += 4 ) { // build the 4x4 block of pixels u8 sourceRgba[16*4]; u8* targetPixel = sourceRgba; int mask = 0; for( int py = 0; py < 4; ++py ) { for( int px = 0; px < 4; ++px ) { // get the source pixel in the image int sx = x + px; int sy = y + py; // enable if we're in the image if( sx < width && sy < height ) { // copy the rgba value u8 const* sourcePixel = rgba + 4*( width*sy + sx ); for( int i = 0; i < 4; ++i ) *targetPixel++ = *sourcePixel++; // enable this pixel mask |= ( 1 << ( 4*py + px ) ); } else { // skip this pixel as its outside the image targetPixel += 4; } } } // compress it into the output CompressMasked( sourceRgba, mask, targetBlock, flags, metric ); // advance targetBlock += bytesPerBlock; } } } void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ) { // fix any bad flags flags = FixFlags( flags ); // initialise the block input u8 const* sourceBlock = reinterpret_cast< u8 const* >( blocks ); int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; // loop over blocks for( int y = 0; y < height; y += 4 ) { for( int x = 0; x < width; x += 4 ) { // decompress the block u8 targetRgba[4*16]; Decompress( targetRgba, sourceBlock, flags ); // write the decompressed pixels to the correct image locations u8 const* sourcePixel = targetRgba; for( int py = 0; py < 4; ++py ) { for( int px = 0; px < 4; ++px ) { // get the target location int sx = x + px; int sy = y + py; if( sx < width && sy < height ) { u8* targetPixel = rgba + 4*( width*sy + sx ); // copy the rgba value for( int i = 0; i < 4; ++i ) *targetPixel++ = *sourcePixel++; } else { // skip this pixel as its outside the image sourcePixel += 4; } } } // advance sourceBlock += bytesPerBlock; } } } } // namespace squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/singlecolourlookup.inl0000644000175000017500000011255512271062644025263 0ustar mfvmfv static SingleColourLookup const lookup_5_3[] = { { { { 0, 0, 0 }, { 0, 0, 0 } } }, { { { 0, 0, 1 }, { 0, 0, 1 } } }, { { { 0, 0, 2 }, { 0, 0, 2 } } }, { { { 0, 0, 3 }, { 0, 1, 1 } } }, { { { 0, 0, 4 }, { 0, 1, 0 } } }, { { { 1, 0, 3 }, { 0, 1, 1 } } }, { { { 1, 0, 2 }, { 0, 1, 2 } } }, { { { 1, 0, 1 }, { 0, 2, 1 } } }, { { { 1, 0, 0 }, { 0, 2, 0 } } }, { { { 1, 0, 1 }, { 0, 2, 1 } } }, { { { 1, 0, 2 }, { 0, 2, 2 } } }, { { { 1, 0, 3 }, { 0, 3, 1 } } }, { { { 1, 0, 4 }, { 0, 3, 0 } } }, { { { 2, 0, 3 }, { 0, 3, 1 } } }, { { { 2, 0, 2 }, { 0, 3, 2 } } }, { { { 2, 0, 1 }, { 0, 4, 1 } } }, { { { 2, 0, 0 }, { 0, 4, 0 } } }, { { { 2, 0, 1 }, { 0, 4, 1 } } }, { { { 2, 0, 2 }, { 0, 4, 2 } } }, { { { 2, 0, 3 }, { 0, 5, 1 } } }, { { { 2, 0, 4 }, { 0, 5, 0 } } }, { { { 3, 0, 3 }, { 0, 5, 1 } } }, { { { 3, 0, 2 }, { 0, 5, 2 } } }, { { { 3, 0, 1 }, { 0, 6, 1 } } }, { { { 3, 0, 0 }, { 0, 6, 0 } } }, { { { 3, 0, 1 }, { 0, 6, 1 } } }, { { { 3, 0, 2 }, { 0, 6, 2 } } }, { { { 3, 0, 3 }, { 0, 7, 1 } } }, { { { 3, 0, 4 }, { 0, 7, 0 } } }, { { { 4, 0, 4 }, { 0, 7, 1 } } }, { { { 4, 0, 3 }, { 0, 7, 2 } } }, { { { 4, 0, 2 }, { 1, 7, 1 } } }, { { { 4, 0, 1 }, { 1, 7, 0 } } }, { { { 4, 0, 0 }, { 0, 8, 0 } } }, { { { 4, 0, 1 }, { 0, 8, 1 } } }, { { { 4, 0, 2 }, { 2, 7, 1 } } }, { { { 4, 0, 3 }, { 2, 7, 0 } } }, { { { 4, 0, 4 }, { 0, 9, 0 } } }, { { { 5, 0, 3 }, { 0, 9, 1 } } }, { { { 5, 0, 2 }, { 3, 7, 1 } } }, { { { 5, 0, 1 }, { 3, 7, 0 } } }, { { { 5, 0, 0 }, { 0, 10, 0 } } }, { { { 5, 0, 1 }, { 0, 10, 1 } } }, { { { 5, 0, 2 }, { 0, 10, 2 } } }, { { { 5, 0, 3 }, { 0, 11, 1 } } }, { { { 5, 0, 4 }, { 0, 11, 0 } } }, { { { 6, 0, 3 }, { 0, 11, 1 } } }, { { { 6, 0, 2 }, { 0, 11, 2 } } }, { { { 6, 0, 1 }, { 0, 12, 1 } } }, { { { 6, 0, 0 }, { 0, 12, 0 } } }, { { { 6, 0, 1 }, { 0, 12, 1 } } }, { { { 6, 0, 2 }, { 0, 12, 2 } } }, { { { 6, 0, 3 }, { 0, 13, 1 } } }, { { { 6, 0, 4 }, { 0, 13, 0 } } }, { { { 7, 0, 3 }, { 0, 13, 1 } } }, { { { 7, 0, 2 }, { 0, 13, 2 } } }, { { { 7, 0, 1 }, { 0, 14, 1 } } }, { { { 7, 0, 0 }, { 0, 14, 0 } } }, { { { 7, 0, 1 }, { 0, 14, 1 } } }, { { { 7, 0, 2 }, { 0, 14, 2 } } }, { { { 7, 0, 3 }, { 0, 15, 1 } } }, { { { 7, 0, 4 }, { 0, 15, 0 } } }, { { { 8, 0, 4 }, { 0, 15, 1 } } }, { { { 8, 0, 3 }, { 0, 15, 2 } } }, { { { 8, 0, 2 }, { 1, 15, 1 } } }, { { { 8, 0, 1 }, { 1, 15, 0 } } }, { { { 8, 0, 0 }, { 0, 16, 0 } } }, { { { 8, 0, 1 }, { 0, 16, 1 } } }, { { { 8, 0, 2 }, { 2, 15, 1 } } }, { { { 8, 0, 3 }, { 2, 15, 0 } } }, { { { 8, 0, 4 }, { 0, 17, 0 } } }, { { { 9, 0, 3 }, { 0, 17, 1 } } }, { { { 9, 0, 2 }, { 3, 15, 1 } } }, { { { 9, 0, 1 }, { 3, 15, 0 } } }, { { { 9, 0, 0 }, { 0, 18, 0 } } }, { { { 9, 0, 1 }, { 0, 18, 1 } } }, { { { 9, 0, 2 }, { 0, 18, 2 } } }, { { { 9, 0, 3 }, { 0, 19, 1 } } }, { { { 9, 0, 4 }, { 0, 19, 0 } } }, { { { 10, 0, 3 }, { 0, 19, 1 } } }, { { { 10, 0, 2 }, { 0, 19, 2 } } }, { { { 10, 0, 1 }, { 0, 20, 1 } } }, { { { 10, 0, 0 }, { 0, 20, 0 } } }, { { { 10, 0, 1 }, { 0, 20, 1 } } }, { { { 10, 0, 2 }, { 0, 20, 2 } } }, { { { 10, 0, 3 }, { 0, 21, 1 } } }, { { { 10, 0, 4 }, { 0, 21, 0 } } }, { { { 11, 0, 3 }, { 0, 21, 1 } } }, { { { 11, 0, 2 }, { 0, 21, 2 } } }, { { { 11, 0, 1 }, { 0, 22, 1 } } }, { { { 11, 0, 0 }, { 0, 22, 0 } } }, { { { 11, 0, 1 }, { 0, 22, 1 } } }, { { { 11, 0, 2 }, { 0, 22, 2 } } }, { { { 11, 0, 3 }, { 0, 23, 1 } } }, { { { 11, 0, 4 }, { 0, 23, 0 } } }, { { { 12, 0, 4 }, { 0, 23, 1 } } }, { { { 12, 0, 3 }, { 0, 23, 2 } } }, { { { 12, 0, 2 }, { 1, 23, 1 } } }, { { { 12, 0, 1 }, { 1, 23, 0 } } }, { { { 12, 0, 0 }, { 0, 24, 0 } } }, { { { 12, 0, 1 }, { 0, 24, 1 } } }, { { { 12, 0, 2 }, { 2, 23, 1 } } }, { { { 12, 0, 3 }, { 2, 23, 0 } } }, { { { 12, 0, 4 }, { 0, 25, 0 } } }, { { { 13, 0, 3 }, { 0, 25, 1 } } }, { { { 13, 0, 2 }, { 3, 23, 1 } } }, { { { 13, 0, 1 }, { 3, 23, 0 } } }, { { { 13, 0, 0 }, { 0, 26, 0 } } }, { { { 13, 0, 1 }, { 0, 26, 1 } } }, { { { 13, 0, 2 }, { 0, 26, 2 } } }, { { { 13, 0, 3 }, { 0, 27, 1 } } }, { { { 13, 0, 4 }, { 0, 27, 0 } } }, { { { 14, 0, 3 }, { 0, 27, 1 } } }, { { { 14, 0, 2 }, { 0, 27, 2 } } }, { { { 14, 0, 1 }, { 0, 28, 1 } } }, { { { 14, 0, 0 }, { 0, 28, 0 } } }, { { { 14, 0, 1 }, { 0, 28, 1 } } }, { { { 14, 0, 2 }, { 0, 28, 2 } } }, { { { 14, 0, 3 }, { 0, 29, 1 } } }, { { { 14, 0, 4 }, { 0, 29, 0 } } }, { { { 15, 0, 3 }, { 0, 29, 1 } } }, { { { 15, 0, 2 }, { 0, 29, 2 } } }, { { { 15, 0, 1 }, { 0, 30, 1 } } }, { { { 15, 0, 0 }, { 0, 30, 0 } } }, { { { 15, 0, 1 }, { 0, 30, 1 } } }, { { { 15, 0, 2 }, { 0, 30, 2 } } }, { { { 15, 0, 3 }, { 0, 31, 1 } } }, { { { 15, 0, 4 }, { 0, 31, 0 } } }, { { { 16, 0, 4 }, { 0, 31, 1 } } }, { { { 16, 0, 3 }, { 0, 31, 2 } } }, { { { 16, 0, 2 }, { 1, 31, 1 } } }, { { { 16, 0, 1 }, { 1, 31, 0 } } }, { { { 16, 0, 0 }, { 4, 28, 0 } } }, { { { 16, 0, 1 }, { 4, 28, 1 } } }, { { { 16, 0, 2 }, { 2, 31, 1 } } }, { { { 16, 0, 3 }, { 2, 31, 0 } } }, { { { 16, 0, 4 }, { 4, 29, 0 } } }, { { { 17, 0, 3 }, { 4, 29, 1 } } }, { { { 17, 0, 2 }, { 3, 31, 1 } } }, { { { 17, 0, 1 }, { 3, 31, 0 } } }, { { { 17, 0, 0 }, { 4, 30, 0 } } }, { { { 17, 0, 1 }, { 4, 30, 1 } } }, { { { 17, 0, 2 }, { 4, 30, 2 } } }, { { { 17, 0, 3 }, { 4, 31, 1 } } }, { { { 17, 0, 4 }, { 4, 31, 0 } } }, { { { 18, 0, 3 }, { 4, 31, 1 } } }, { { { 18, 0, 2 }, { 4, 31, 2 } } }, { { { 18, 0, 1 }, { 5, 31, 1 } } }, { { { 18, 0, 0 }, { 5, 31, 0 } } }, { { { 18, 0, 1 }, { 5, 31, 1 } } }, { { { 18, 0, 2 }, { 5, 31, 2 } } }, { { { 18, 0, 3 }, { 6, 31, 1 } } }, { { { 18, 0, 4 }, { 6, 31, 0 } } }, { { { 19, 0, 3 }, { 6, 31, 1 } } }, { { { 19, 0, 2 }, { 6, 31, 2 } } }, { { { 19, 0, 1 }, { 7, 31, 1 } } }, { { { 19, 0, 0 }, { 7, 31, 0 } } }, { { { 19, 0, 1 }, { 7, 31, 1 } } }, { { { 19, 0, 2 }, { 7, 31, 2 } } }, { { { 19, 0, 3 }, { 8, 31, 1 } } }, { { { 19, 0, 4 }, { 8, 31, 0 } } }, { { { 20, 0, 4 }, { 8, 31, 1 } } }, { { { 20, 0, 3 }, { 8, 31, 2 } } }, { { { 20, 0, 2 }, { 9, 31, 1 } } }, { { { 20, 0, 1 }, { 9, 31, 0 } } }, { { { 20, 0, 0 }, { 12, 28, 0 } } }, { { { 20, 0, 1 }, { 12, 28, 1 } } }, { { { 20, 0, 2 }, { 10, 31, 1 } } }, { { { 20, 0, 3 }, { 10, 31, 0 } } }, { { { 20, 0, 4 }, { 12, 29, 0 } } }, { { { 21, 0, 3 }, { 12, 29, 1 } } }, { { { 21, 0, 2 }, { 11, 31, 1 } } }, { { { 21, 0, 1 }, { 11, 31, 0 } } }, { { { 21, 0, 0 }, { 12, 30, 0 } } }, { { { 21, 0, 1 }, { 12, 30, 1 } } }, { { { 21, 0, 2 }, { 12, 30, 2 } } }, { { { 21, 0, 3 }, { 12, 31, 1 } } }, { { { 21, 0, 4 }, { 12, 31, 0 } } }, { { { 22, 0, 3 }, { 12, 31, 1 } } }, { { { 22, 0, 2 }, { 12, 31, 2 } } }, { { { 22, 0, 1 }, { 13, 31, 1 } } }, { { { 22, 0, 0 }, { 13, 31, 0 } } }, { { { 22, 0, 1 }, { 13, 31, 1 } } }, { { { 22, 0, 2 }, { 13, 31, 2 } } }, { { { 22, 0, 3 }, { 14, 31, 1 } } }, { { { 22, 0, 4 }, { 14, 31, 0 } } }, { { { 23, 0, 3 }, { 14, 31, 1 } } }, { { { 23, 0, 2 }, { 14, 31, 2 } } }, { { { 23, 0, 1 }, { 15, 31, 1 } } }, { { { 23, 0, 0 }, { 15, 31, 0 } } }, { { { 23, 0, 1 }, { 15, 31, 1 } } }, { { { 23, 0, 2 }, { 15, 31, 2 } } }, { { { 23, 0, 3 }, { 16, 31, 1 } } }, { { { 23, 0, 4 }, { 16, 31, 0 } } }, { { { 24, 0, 4 }, { 16, 31, 1 } } }, { { { 24, 0, 3 }, { 16, 31, 2 } } }, { { { 24, 0, 2 }, { 17, 31, 1 } } }, { { { 24, 0, 1 }, { 17, 31, 0 } } }, { { { 24, 0, 0 }, { 20, 28, 0 } } }, { { { 24, 0, 1 }, { 20, 28, 1 } } }, { { { 24, 0, 2 }, { 18, 31, 1 } } }, { { { 24, 0, 3 }, { 18, 31, 0 } } }, { { { 24, 0, 4 }, { 20, 29, 0 } } }, { { { 25, 0, 3 }, { 20, 29, 1 } } }, { { { 25, 0, 2 }, { 19, 31, 1 } } }, { { { 25, 0, 1 }, { 19, 31, 0 } } }, { { { 25, 0, 0 }, { 20, 30, 0 } } }, { { { 25, 0, 1 }, { 20, 30, 1 } } }, { { { 25, 0, 2 }, { 20, 30, 2 } } }, { { { 25, 0, 3 }, { 20, 31, 1 } } }, { { { 25, 0, 4 }, { 20, 31, 0 } } }, { { { 26, 0, 3 }, { 20, 31, 1 } } }, { { { 26, 0, 2 }, { 20, 31, 2 } } }, { { { 26, 0, 1 }, { 21, 31, 1 } } }, { { { 26, 0, 0 }, { 21, 31, 0 } } }, { { { 26, 0, 1 }, { 21, 31, 1 } } }, { { { 26, 0, 2 }, { 21, 31, 2 } } }, { { { 26, 0, 3 }, { 22, 31, 1 } } }, { { { 26, 0, 4 }, { 22, 31, 0 } } }, { { { 27, 0, 3 }, { 22, 31, 1 } } }, { { { 27, 0, 2 }, { 22, 31, 2 } } }, { { { 27, 0, 1 }, { 23, 31, 1 } } }, { { { 27, 0, 0 }, { 23, 31, 0 } } }, { { { 27, 0, 1 }, { 23, 31, 1 } } }, { { { 27, 0, 2 }, { 23, 31, 2 } } }, { { { 27, 0, 3 }, { 24, 31, 1 } } }, { { { 27, 0, 4 }, { 24, 31, 0 } } }, { { { 28, 0, 4 }, { 24, 31, 1 } } }, { { { 28, 0, 3 }, { 24, 31, 2 } } }, { { { 28, 0, 2 }, { 25, 31, 1 } } }, { { { 28, 0, 1 }, { 25, 31, 0 } } }, { { { 28, 0, 0 }, { 28, 28, 0 } } }, { { { 28, 0, 1 }, { 28, 28, 1 } } }, { { { 28, 0, 2 }, { 26, 31, 1 } } }, { { { 28, 0, 3 }, { 26, 31, 0 } } }, { { { 28, 0, 4 }, { 28, 29, 0 } } }, { { { 29, 0, 3 }, { 28, 29, 1 } } }, { { { 29, 0, 2 }, { 27, 31, 1 } } }, { { { 29, 0, 1 }, { 27, 31, 0 } } }, { { { 29, 0, 0 }, { 28, 30, 0 } } }, { { { 29, 0, 1 }, { 28, 30, 1 } } }, { { { 29, 0, 2 }, { 28, 30, 2 } } }, { { { 29, 0, 3 }, { 28, 31, 1 } } }, { { { 29, 0, 4 }, { 28, 31, 0 } } }, { { { 30, 0, 3 }, { 28, 31, 1 } } }, { { { 30, 0, 2 }, { 28, 31, 2 } } }, { { { 30, 0, 1 }, { 29, 31, 1 } } }, { { { 30, 0, 0 }, { 29, 31, 0 } } }, { { { 30, 0, 1 }, { 29, 31, 1 } } }, { { { 30, 0, 2 }, { 29, 31, 2 } } }, { { { 30, 0, 3 }, { 30, 31, 1 } } }, { { { 30, 0, 4 }, { 30, 31, 0 } } }, { { { 31, 0, 3 }, { 30, 31, 1 } } }, { { { 31, 0, 2 }, { 30, 31, 2 } } }, { { { 31, 0, 1 }, { 31, 31, 1 } } }, { { { 31, 0, 0 }, { 31, 31, 0 } } } }; static SingleColourLookup const lookup_6_3[] = { { { { 0, 0, 0 }, { 0, 0, 0 } } }, { { { 0, 0, 1 }, { 0, 1, 1 } } }, { { { 0, 0, 2 }, { 0, 1, 0 } } }, { { { 1, 0, 1 }, { 0, 2, 1 } } }, { { { 1, 0, 0 }, { 0, 2, 0 } } }, { { { 1, 0, 1 }, { 0, 3, 1 } } }, { { { 1, 0, 2 }, { 0, 3, 0 } } }, { { { 2, 0, 1 }, { 0, 4, 1 } } }, { { { 2, 0, 0 }, { 0, 4, 0 } } }, { { { 2, 0, 1 }, { 0, 5, 1 } } }, { { { 2, 0, 2 }, { 0, 5, 0 } } }, { { { 3, 0, 1 }, { 0, 6, 1 } } }, { { { 3, 0, 0 }, { 0, 6, 0 } } }, { { { 3, 0, 1 }, { 0, 7, 1 } } }, { { { 3, 0, 2 }, { 0, 7, 0 } } }, { { { 4, 0, 1 }, { 0, 8, 1 } } }, { { { 4, 0, 0 }, { 0, 8, 0 } } }, { { { 4, 0, 1 }, { 0, 9, 1 } } }, { { { 4, 0, 2 }, { 0, 9, 0 } } }, { { { 5, 0, 1 }, { 0, 10, 1 } } }, { { { 5, 0, 0 }, { 0, 10, 0 } } }, { { { 5, 0, 1 }, { 0, 11, 1 } } }, { { { 5, 0, 2 }, { 0, 11, 0 } } }, { { { 6, 0, 1 }, { 0, 12, 1 } } }, { { { 6, 0, 0 }, { 0, 12, 0 } } }, { { { 6, 0, 1 }, { 0, 13, 1 } } }, { { { 6, 0, 2 }, { 0, 13, 0 } } }, { { { 7, 0, 1 }, { 0, 14, 1 } } }, { { { 7, 0, 0 }, { 0, 14, 0 } } }, { { { 7, 0, 1 }, { 0, 15, 1 } } }, { { { 7, 0, 2 }, { 0, 15, 0 } } }, { { { 8, 0, 1 }, { 0, 16, 1 } } }, { { { 8, 0, 0 }, { 0, 16, 0 } } }, { { { 8, 0, 1 }, { 0, 17, 1 } } }, { { { 8, 0, 2 }, { 0, 17, 0 } } }, { { { 9, 0, 1 }, { 0, 18, 1 } } }, { { { 9, 0, 0 }, { 0, 18, 0 } } }, { { { 9, 0, 1 }, { 0, 19, 1 } } }, { { { 9, 0, 2 }, { 0, 19, 0 } } }, { { { 10, 0, 1 }, { 0, 20, 1 } } }, { { { 10, 0, 0 }, { 0, 20, 0 } } }, { { { 10, 0, 1 }, { 0, 21, 1 } } }, { { { 10, 0, 2 }, { 0, 21, 0 } } }, { { { 11, 0, 1 }, { 0, 22, 1 } } }, { { { 11, 0, 0 }, { 0, 22, 0 } } }, { { { 11, 0, 1 }, { 0, 23, 1 } } }, { { { 11, 0, 2 }, { 0, 23, 0 } } }, { { { 12, 0, 1 }, { 0, 24, 1 } } }, { { { 12, 0, 0 }, { 0, 24, 0 } } }, { { { 12, 0, 1 }, { 0, 25, 1 } } }, { { { 12, 0, 2 }, { 0, 25, 0 } } }, { { { 13, 0, 1 }, { 0, 26, 1 } } }, { { { 13, 0, 0 }, { 0, 26, 0 } } }, { { { 13, 0, 1 }, { 0, 27, 1 } } }, { { { 13, 0, 2 }, { 0, 27, 0 } } }, { { { 14, 0, 1 }, { 0, 28, 1 } } }, { { { 14, 0, 0 }, { 0, 28, 0 } } }, { { { 14, 0, 1 }, { 0, 29, 1 } } }, { { { 14, 0, 2 }, { 0, 29, 0 } } }, { { { 15, 0, 1 }, { 0, 30, 1 } } }, { { { 15, 0, 0 }, { 0, 30, 0 } } }, { { { 15, 0, 1 }, { 0, 31, 1 } } }, { { { 15, 0, 2 }, { 0, 31, 0 } } }, { { { 16, 0, 2 }, { 1, 31, 1 } } }, { { { 16, 0, 1 }, { 1, 31, 0 } } }, { { { 16, 0, 0 }, { 0, 32, 0 } } }, { { { 16, 0, 1 }, { 2, 31, 0 } } }, { { { 16, 0, 2 }, { 0, 33, 0 } } }, { { { 17, 0, 1 }, { 3, 31, 0 } } }, { { { 17, 0, 0 }, { 0, 34, 0 } } }, { { { 17, 0, 1 }, { 4, 31, 0 } } }, { { { 17, 0, 2 }, { 0, 35, 0 } } }, { { { 18, 0, 1 }, { 5, 31, 0 } } }, { { { 18, 0, 0 }, { 0, 36, 0 } } }, { { { 18, 0, 1 }, { 6, 31, 0 } } }, { { { 18, 0, 2 }, { 0, 37, 0 } } }, { { { 19, 0, 1 }, { 7, 31, 0 } } }, { { { 19, 0, 0 }, { 0, 38, 0 } } }, { { { 19, 0, 1 }, { 8, 31, 0 } } }, { { { 19, 0, 2 }, { 0, 39, 0 } } }, { { { 20, 0, 1 }, { 9, 31, 0 } } }, { { { 20, 0, 0 }, { 0, 40, 0 } } }, { { { 20, 0, 1 }, { 10, 31, 0 } } }, { { { 20, 0, 2 }, { 0, 41, 0 } } }, { { { 21, 0, 1 }, { 11, 31, 0 } } }, { { { 21, 0, 0 }, { 0, 42, 0 } } }, { { { 21, 0, 1 }, { 12, 31, 0 } } }, { { { 21, 0, 2 }, { 0, 43, 0 } } }, { { { 22, 0, 1 }, { 13, 31, 0 } } }, { { { 22, 0, 0 }, { 0, 44, 0 } } }, { { { 22, 0, 1 }, { 14, 31, 0 } } }, { { { 22, 0, 2 }, { 0, 45, 0 } } }, { { { 23, 0, 1 }, { 15, 31, 0 } } }, { { { 23, 0, 0 }, { 0, 46, 0 } } }, { { { 23, 0, 1 }, { 0, 47, 1 } } }, { { { 23, 0, 2 }, { 0, 47, 0 } } }, { { { 24, 0, 1 }, { 0, 48, 1 } } }, { { { 24, 0, 0 }, { 0, 48, 0 } } }, { { { 24, 0, 1 }, { 0, 49, 1 } } }, { { { 24, 0, 2 }, { 0, 49, 0 } } }, { { { 25, 0, 1 }, { 0, 50, 1 } } }, { { { 25, 0, 0 }, { 0, 50, 0 } } }, { { { 25, 0, 1 }, { 0, 51, 1 } } }, { { { 25, 0, 2 }, { 0, 51, 0 } } }, { { { 26, 0, 1 }, { 0, 52, 1 } } }, { { { 26, 0, 0 }, { 0, 52, 0 } } }, { { { 26, 0, 1 }, { 0, 53, 1 } } }, { { { 26, 0, 2 }, { 0, 53, 0 } } }, { { { 27, 0, 1 }, { 0, 54, 1 } } }, { { { 27, 0, 0 }, { 0, 54, 0 } } }, { { { 27, 0, 1 }, { 0, 55, 1 } } }, { { { 27, 0, 2 }, { 0, 55, 0 } } }, { { { 28, 0, 1 }, { 0, 56, 1 } } }, { { { 28, 0, 0 }, { 0, 56, 0 } } }, { { { 28, 0, 1 }, { 0, 57, 1 } } }, { { { 28, 0, 2 }, { 0, 57, 0 } } }, { { { 29, 0, 1 }, { 0, 58, 1 } } }, { { { 29, 0, 0 }, { 0, 58, 0 } } }, { { { 29, 0, 1 }, { 0, 59, 1 } } }, { { { 29, 0, 2 }, { 0, 59, 0 } } }, { { { 30, 0, 1 }, { 0, 60, 1 } } }, { { { 30, 0, 0 }, { 0, 60, 0 } } }, { { { 30, 0, 1 }, { 0, 61, 1 } } }, { { { 30, 0, 2 }, { 0, 61, 0 } } }, { { { 31, 0, 1 }, { 0, 62, 1 } } }, { { { 31, 0, 0 }, { 0, 62, 0 } } }, { { { 31, 0, 1 }, { 0, 63, 1 } } }, { { { 31, 0, 2 }, { 0, 63, 0 } } }, { { { 32, 0, 2 }, { 1, 63, 1 } } }, { { { 32, 0, 1 }, { 1, 63, 0 } } }, { { { 32, 0, 0 }, { 16, 48, 0 } } }, { { { 32, 0, 1 }, { 2, 63, 0 } } }, { { { 32, 0, 2 }, { 16, 49, 0 } } }, { { { 33, 0, 1 }, { 3, 63, 0 } } }, { { { 33, 0, 0 }, { 16, 50, 0 } } }, { { { 33, 0, 1 }, { 4, 63, 0 } } }, { { { 33, 0, 2 }, { 16, 51, 0 } } }, { { { 34, 0, 1 }, { 5, 63, 0 } } }, { { { 34, 0, 0 }, { 16, 52, 0 } } }, { { { 34, 0, 1 }, { 6, 63, 0 } } }, { { { 34, 0, 2 }, { 16, 53, 0 } } }, { { { 35, 0, 1 }, { 7, 63, 0 } } }, { { { 35, 0, 0 }, { 16, 54, 0 } } }, { { { 35, 0, 1 }, { 8, 63, 0 } } }, { { { 35, 0, 2 }, { 16, 55, 0 } } }, { { { 36, 0, 1 }, { 9, 63, 0 } } }, { { { 36, 0, 0 }, { 16, 56, 0 } } }, { { { 36, 0, 1 }, { 10, 63, 0 } } }, { { { 36, 0, 2 }, { 16, 57, 0 } } }, { { { 37, 0, 1 }, { 11, 63, 0 } } }, { { { 37, 0, 0 }, { 16, 58, 0 } } }, { { { 37, 0, 1 }, { 12, 63, 0 } } }, { { { 37, 0, 2 }, { 16, 59, 0 } } }, { { { 38, 0, 1 }, { 13, 63, 0 } } }, { { { 38, 0, 0 }, { 16, 60, 0 } } }, { { { 38, 0, 1 }, { 14, 63, 0 } } }, { { { 38, 0, 2 }, { 16, 61, 0 } } }, { { { 39, 0, 1 }, { 15, 63, 0 } } }, { { { 39, 0, 0 }, { 16, 62, 0 } } }, { { { 39, 0, 1 }, { 16, 63, 1 } } }, { { { 39, 0, 2 }, { 16, 63, 0 } } }, { { { 40, 0, 1 }, { 17, 63, 1 } } }, { { { 40, 0, 0 }, { 17, 63, 0 } } }, { { { 40, 0, 1 }, { 18, 63, 1 } } }, { { { 40, 0, 2 }, { 18, 63, 0 } } }, { { { 41, 0, 1 }, { 19, 63, 1 } } }, { { { 41, 0, 0 }, { 19, 63, 0 } } }, { { { 41, 0, 1 }, { 20, 63, 1 } } }, { { { 41, 0, 2 }, { 20, 63, 0 } } }, { { { 42, 0, 1 }, { 21, 63, 1 } } }, { { { 42, 0, 0 }, { 21, 63, 0 } } }, { { { 42, 0, 1 }, { 22, 63, 1 } } }, { { { 42, 0, 2 }, { 22, 63, 0 } } }, { { { 43, 0, 1 }, { 23, 63, 1 } } }, { { { 43, 0, 0 }, { 23, 63, 0 } } }, { { { 43, 0, 1 }, { 24, 63, 1 } } }, { { { 43, 0, 2 }, { 24, 63, 0 } } }, { { { 44, 0, 1 }, { 25, 63, 1 } } }, { { { 44, 0, 0 }, { 25, 63, 0 } } }, { { { 44, 0, 1 }, { 26, 63, 1 } } }, { { { 44, 0, 2 }, { 26, 63, 0 } } }, { { { 45, 0, 1 }, { 27, 63, 1 } } }, { { { 45, 0, 0 }, { 27, 63, 0 } } }, { { { 45, 0, 1 }, { 28, 63, 1 } } }, { { { 45, 0, 2 }, { 28, 63, 0 } } }, { { { 46, 0, 1 }, { 29, 63, 1 } } }, { { { 46, 0, 0 }, { 29, 63, 0 } } }, { { { 46, 0, 1 }, { 30, 63, 1 } } }, { { { 46, 0, 2 }, { 30, 63, 0 } } }, { { { 47, 0, 1 }, { 31, 63, 1 } } }, { { { 47, 0, 0 }, { 31, 63, 0 } } }, { { { 47, 0, 1 }, { 32, 63, 1 } } }, { { { 47, 0, 2 }, { 32, 63, 0 } } }, { { { 48, 0, 2 }, { 33, 63, 1 } } }, { { { 48, 0, 1 }, { 33, 63, 0 } } }, { { { 48, 0, 0 }, { 48, 48, 0 } } }, { { { 48, 0, 1 }, { 34, 63, 0 } } }, { { { 48, 0, 2 }, { 48, 49, 0 } } }, { { { 49, 0, 1 }, { 35, 63, 0 } } }, { { { 49, 0, 0 }, { 48, 50, 0 } } }, { { { 49, 0, 1 }, { 36, 63, 0 } } }, { { { 49, 0, 2 }, { 48, 51, 0 } } }, { { { 50, 0, 1 }, { 37, 63, 0 } } }, { { { 50, 0, 0 }, { 48, 52, 0 } } }, { { { 50, 0, 1 }, { 38, 63, 0 } } }, { { { 50, 0, 2 }, { 48, 53, 0 } } }, { { { 51, 0, 1 }, { 39, 63, 0 } } }, { { { 51, 0, 0 }, { 48, 54, 0 } } }, { { { 51, 0, 1 }, { 40, 63, 0 } } }, { { { 51, 0, 2 }, { 48, 55, 0 } } }, { { { 52, 0, 1 }, { 41, 63, 0 } } }, { { { 52, 0, 0 }, { 48, 56, 0 } } }, { { { 52, 0, 1 }, { 42, 63, 0 } } }, { { { 52, 0, 2 }, { 48, 57, 0 } } }, { { { 53, 0, 1 }, { 43, 63, 0 } } }, { { { 53, 0, 0 }, { 48, 58, 0 } } }, { { { 53, 0, 1 }, { 44, 63, 0 } } }, { { { 53, 0, 2 }, { 48, 59, 0 } } }, { { { 54, 0, 1 }, { 45, 63, 0 } } }, { { { 54, 0, 0 }, { 48, 60, 0 } } }, { { { 54, 0, 1 }, { 46, 63, 0 } } }, { { { 54, 0, 2 }, { 48, 61, 0 } } }, { { { 55, 0, 1 }, { 47, 63, 0 } } }, { { { 55, 0, 0 }, { 48, 62, 0 } } }, { { { 55, 0, 1 }, { 48, 63, 1 } } }, { { { 55, 0, 2 }, { 48, 63, 0 } } }, { { { 56, 0, 1 }, { 49, 63, 1 } } }, { { { 56, 0, 0 }, { 49, 63, 0 } } }, { { { 56, 0, 1 }, { 50, 63, 1 } } }, { { { 56, 0, 2 }, { 50, 63, 0 } } }, { { { 57, 0, 1 }, { 51, 63, 1 } } }, { { { 57, 0, 0 }, { 51, 63, 0 } } }, { { { 57, 0, 1 }, { 52, 63, 1 } } }, { { { 57, 0, 2 }, { 52, 63, 0 } } }, { { { 58, 0, 1 }, { 53, 63, 1 } } }, { { { 58, 0, 0 }, { 53, 63, 0 } } }, { { { 58, 0, 1 }, { 54, 63, 1 } } }, { { { 58, 0, 2 }, { 54, 63, 0 } } }, { { { 59, 0, 1 }, { 55, 63, 1 } } }, { { { 59, 0, 0 }, { 55, 63, 0 } } }, { { { 59, 0, 1 }, { 56, 63, 1 } } }, { { { 59, 0, 2 }, { 56, 63, 0 } } }, { { { 60, 0, 1 }, { 57, 63, 1 } } }, { { { 60, 0, 0 }, { 57, 63, 0 } } }, { { { 60, 0, 1 }, { 58, 63, 1 } } }, { { { 60, 0, 2 }, { 58, 63, 0 } } }, { { { 61, 0, 1 }, { 59, 63, 1 } } }, { { { 61, 0, 0 }, { 59, 63, 0 } } }, { { { 61, 0, 1 }, { 60, 63, 1 } } }, { { { 61, 0, 2 }, { 60, 63, 0 } } }, { { { 62, 0, 1 }, { 61, 63, 1 } } }, { { { 62, 0, 0 }, { 61, 63, 0 } } }, { { { 62, 0, 1 }, { 62, 63, 1 } } }, { { { 62, 0, 2 }, { 62, 63, 0 } } }, { { { 63, 0, 1 }, { 63, 63, 1 } } }, { { { 63, 0, 0 }, { 63, 63, 0 } } } }; static SingleColourLookup const lookup_5_4[] = { { { { 0, 0, 0 }, { 0, 0, 0 } } }, { { { 0, 0, 1 }, { 0, 1, 1 } } }, { { { 0, 0, 2 }, { 0, 1, 0 } } }, { { { 0, 0, 3 }, { 0, 1, 1 } } }, { { { 0, 0, 4 }, { 0, 2, 1 } } }, { { { 1, 0, 3 }, { 0, 2, 0 } } }, { { { 1, 0, 2 }, { 0, 2, 1 } } }, { { { 1, 0, 1 }, { 0, 3, 1 } } }, { { { 1, 0, 0 }, { 0, 3, 0 } } }, { { { 1, 0, 1 }, { 1, 2, 1 } } }, { { { 1, 0, 2 }, { 1, 2, 0 } } }, { { { 1, 0, 3 }, { 0, 4, 0 } } }, { { { 1, 0, 4 }, { 0, 5, 1 } } }, { { { 2, 0, 3 }, { 0, 5, 0 } } }, { { { 2, 0, 2 }, { 0, 5, 1 } } }, { { { 2, 0, 1 }, { 0, 6, 1 } } }, { { { 2, 0, 0 }, { 0, 6, 0 } } }, { { { 2, 0, 1 }, { 2, 3, 1 } } }, { { { 2, 0, 2 }, { 2, 3, 0 } } }, { { { 2, 0, 3 }, { 0, 7, 0 } } }, { { { 2, 0, 4 }, { 1, 6, 1 } } }, { { { 3, 0, 3 }, { 1, 6, 0 } } }, { { { 3, 0, 2 }, { 0, 8, 0 } } }, { { { 3, 0, 1 }, { 0, 9, 1 } } }, { { { 3, 0, 0 }, { 0, 9, 0 } } }, { { { 3, 0, 1 }, { 0, 9, 1 } } }, { { { 3, 0, 2 }, { 0, 10, 1 } } }, { { { 3, 0, 3 }, { 0, 10, 0 } } }, { { { 3, 0, 4 }, { 2, 7, 1 } } }, { { { 4, 0, 4 }, { 2, 7, 0 } } }, { { { 4, 0, 3 }, { 0, 11, 0 } } }, { { { 4, 0, 2 }, { 1, 10, 1 } } }, { { { 4, 0, 1 }, { 1, 10, 0 } } }, { { { 4, 0, 0 }, { 0, 12, 0 } } }, { { { 4, 0, 1 }, { 0, 13, 1 } } }, { { { 4, 0, 2 }, { 0, 13, 0 } } }, { { { 4, 0, 3 }, { 0, 13, 1 } } }, { { { 4, 0, 4 }, { 0, 14, 1 } } }, { { { 5, 0, 3 }, { 0, 14, 0 } } }, { { { 5, 0, 2 }, { 2, 11, 1 } } }, { { { 5, 0, 1 }, { 2, 11, 0 } } }, { { { 5, 0, 0 }, { 0, 15, 0 } } }, { { { 5, 0, 1 }, { 1, 14, 1 } } }, { { { 5, 0, 2 }, { 1, 14, 0 } } }, { { { 5, 0, 3 }, { 0, 16, 0 } } }, { { { 5, 0, 4 }, { 0, 17, 1 } } }, { { { 6, 0, 3 }, { 0, 17, 0 } } }, { { { 6, 0, 2 }, { 0, 17, 1 } } }, { { { 6, 0, 1 }, { 0, 18, 1 } } }, { { { 6, 0, 0 }, { 0, 18, 0 } } }, { { { 6, 0, 1 }, { 2, 15, 1 } } }, { { { 6, 0, 2 }, { 2, 15, 0 } } }, { { { 6, 0, 3 }, { 0, 19, 0 } } }, { { { 6, 0, 4 }, { 1, 18, 1 } } }, { { { 7, 0, 3 }, { 1, 18, 0 } } }, { { { 7, 0, 2 }, { 0, 20, 0 } } }, { { { 7, 0, 1 }, { 0, 21, 1 } } }, { { { 7, 0, 0 }, { 0, 21, 0 } } }, { { { 7, 0, 1 }, { 0, 21, 1 } } }, { { { 7, 0, 2 }, { 0, 22, 1 } } }, { { { 7, 0, 3 }, { 0, 22, 0 } } }, { { { 7, 0, 4 }, { 2, 19, 1 } } }, { { { 8, 0, 4 }, { 2, 19, 0 } } }, { { { 8, 0, 3 }, { 0, 23, 0 } } }, { { { 8, 0, 2 }, { 1, 22, 1 } } }, { { { 8, 0, 1 }, { 1, 22, 0 } } }, { { { 8, 0, 0 }, { 0, 24, 0 } } }, { { { 8, 0, 1 }, { 0, 25, 1 } } }, { { { 8, 0, 2 }, { 0, 25, 0 } } }, { { { 8, 0, 3 }, { 0, 25, 1 } } }, { { { 8, 0, 4 }, { 0, 26, 1 } } }, { { { 9, 0, 3 }, { 0, 26, 0 } } }, { { { 9, 0, 2 }, { 2, 23, 1 } } }, { { { 9, 0, 1 }, { 2, 23, 0 } } }, { { { 9, 0, 0 }, { 0, 27, 0 } } }, { { { 9, 0, 1 }, { 1, 26, 1 } } }, { { { 9, 0, 2 }, { 1, 26, 0 } } }, { { { 9, 0, 3 }, { 0, 28, 0 } } }, { { { 9, 0, 4 }, { 0, 29, 1 } } }, { { { 10, 0, 3 }, { 0, 29, 0 } } }, { { { 10, 0, 2 }, { 0, 29, 1 } } }, { { { 10, 0, 1 }, { 0, 30, 1 } } }, { { { 10, 0, 0 }, { 0, 30, 0 } } }, { { { 10, 0, 1 }, { 2, 27, 1 } } }, { { { 10, 0, 2 }, { 2, 27, 0 } } }, { { { 10, 0, 3 }, { 0, 31, 0 } } }, { { { 10, 0, 4 }, { 1, 30, 1 } } }, { { { 11, 0, 3 }, { 1, 30, 0 } } }, { { { 11, 0, 2 }, { 4, 24, 0 } } }, { { { 11, 0, 1 }, { 1, 31, 1 } } }, { { { 11, 0, 0 }, { 1, 31, 0 } } }, { { { 11, 0, 1 }, { 1, 31, 1 } } }, { { { 11, 0, 2 }, { 2, 30, 1 } } }, { { { 11, 0, 3 }, { 2, 30, 0 } } }, { { { 11, 0, 4 }, { 2, 31, 1 } } }, { { { 12, 0, 4 }, { 2, 31, 0 } } }, { { { 12, 0, 3 }, { 4, 27, 0 } } }, { { { 12, 0, 2 }, { 3, 30, 1 } } }, { { { 12, 0, 1 }, { 3, 30, 0 } } }, { { { 12, 0, 0 }, { 4, 28, 0 } } }, { { { 12, 0, 1 }, { 3, 31, 1 } } }, { { { 12, 0, 2 }, { 3, 31, 0 } } }, { { { 12, 0, 3 }, { 3, 31, 1 } } }, { { { 12, 0, 4 }, { 4, 30, 1 } } }, { { { 13, 0, 3 }, { 4, 30, 0 } } }, { { { 13, 0, 2 }, { 6, 27, 1 } } }, { { { 13, 0, 1 }, { 6, 27, 0 } } }, { { { 13, 0, 0 }, { 4, 31, 0 } } }, { { { 13, 0, 1 }, { 5, 30, 1 } } }, { { { 13, 0, 2 }, { 5, 30, 0 } } }, { { { 13, 0, 3 }, { 8, 24, 0 } } }, { { { 13, 0, 4 }, { 5, 31, 1 } } }, { { { 14, 0, 3 }, { 5, 31, 0 } } }, { { { 14, 0, 2 }, { 5, 31, 1 } } }, { { { 14, 0, 1 }, { 6, 30, 1 } } }, { { { 14, 0, 0 }, { 6, 30, 0 } } }, { { { 14, 0, 1 }, { 6, 31, 1 } } }, { { { 14, 0, 2 }, { 6, 31, 0 } } }, { { { 14, 0, 3 }, { 8, 27, 0 } } }, { { { 14, 0, 4 }, { 7, 30, 1 } } }, { { { 15, 0, 3 }, { 7, 30, 0 } } }, { { { 15, 0, 2 }, { 8, 28, 0 } } }, { { { 15, 0, 1 }, { 7, 31, 1 } } }, { { { 15, 0, 0 }, { 7, 31, 0 } } }, { { { 15, 0, 1 }, { 7, 31, 1 } } }, { { { 15, 0, 2 }, { 8, 30, 1 } } }, { { { 15, 0, 3 }, { 8, 30, 0 } } }, { { { 15, 0, 4 }, { 10, 27, 1 } } }, { { { 16, 0, 4 }, { 10, 27, 0 } } }, { { { 16, 0, 3 }, { 8, 31, 0 } } }, { { { 16, 0, 2 }, { 9, 30, 1 } } }, { { { 16, 0, 1 }, { 9, 30, 0 } } }, { { { 16, 0, 0 }, { 12, 24, 0 } } }, { { { 16, 0, 1 }, { 9, 31, 1 } } }, { { { 16, 0, 2 }, { 9, 31, 0 } } }, { { { 16, 0, 3 }, { 9, 31, 1 } } }, { { { 16, 0, 4 }, { 10, 30, 1 } } }, { { { 17, 0, 3 }, { 10, 30, 0 } } }, { { { 17, 0, 2 }, { 10, 31, 1 } } }, { { { 17, 0, 1 }, { 10, 31, 0 } } }, { { { 17, 0, 0 }, { 12, 27, 0 } } }, { { { 17, 0, 1 }, { 11, 30, 1 } } }, { { { 17, 0, 2 }, { 11, 30, 0 } } }, { { { 17, 0, 3 }, { 12, 28, 0 } } }, { { { 17, 0, 4 }, { 11, 31, 1 } } }, { { { 18, 0, 3 }, { 11, 31, 0 } } }, { { { 18, 0, 2 }, { 11, 31, 1 } } }, { { { 18, 0, 1 }, { 12, 30, 1 } } }, { { { 18, 0, 0 }, { 12, 30, 0 } } }, { { { 18, 0, 1 }, { 14, 27, 1 } } }, { { { 18, 0, 2 }, { 14, 27, 0 } } }, { { { 18, 0, 3 }, { 12, 31, 0 } } }, { { { 18, 0, 4 }, { 13, 30, 1 } } }, { { { 19, 0, 3 }, { 13, 30, 0 } } }, { { { 19, 0, 2 }, { 16, 24, 0 } } }, { { { 19, 0, 1 }, { 13, 31, 1 } } }, { { { 19, 0, 0 }, { 13, 31, 0 } } }, { { { 19, 0, 1 }, { 13, 31, 1 } } }, { { { 19, 0, 2 }, { 14, 30, 1 } } }, { { { 19, 0, 3 }, { 14, 30, 0 } } }, { { { 19, 0, 4 }, { 14, 31, 1 } } }, { { { 20, 0, 4 }, { 14, 31, 0 } } }, { { { 20, 0, 3 }, { 16, 27, 0 } } }, { { { 20, 0, 2 }, { 15, 30, 1 } } }, { { { 20, 0, 1 }, { 15, 30, 0 } } }, { { { 20, 0, 0 }, { 16, 28, 0 } } }, { { { 20, 0, 1 }, { 15, 31, 1 } } }, { { { 20, 0, 2 }, { 15, 31, 0 } } }, { { { 20, 0, 3 }, { 15, 31, 1 } } }, { { { 20, 0, 4 }, { 16, 30, 1 } } }, { { { 21, 0, 3 }, { 16, 30, 0 } } }, { { { 21, 0, 2 }, { 18, 27, 1 } } }, { { { 21, 0, 1 }, { 18, 27, 0 } } }, { { { 21, 0, 0 }, { 16, 31, 0 } } }, { { { 21, 0, 1 }, { 17, 30, 1 } } }, { { { 21, 0, 2 }, { 17, 30, 0 } } }, { { { 21, 0, 3 }, { 20, 24, 0 } } }, { { { 21, 0, 4 }, { 17, 31, 1 } } }, { { { 22, 0, 3 }, { 17, 31, 0 } } }, { { { 22, 0, 2 }, { 17, 31, 1 } } }, { { { 22, 0, 1 }, { 18, 30, 1 } } }, { { { 22, 0, 0 }, { 18, 30, 0 } } }, { { { 22, 0, 1 }, { 18, 31, 1 } } }, { { { 22, 0, 2 }, { 18, 31, 0 } } }, { { { 22, 0, 3 }, { 20, 27, 0 } } }, { { { 22, 0, 4 }, { 19, 30, 1 } } }, { { { 23, 0, 3 }, { 19, 30, 0 } } }, { { { 23, 0, 2 }, { 20, 28, 0 } } }, { { { 23, 0, 1 }, { 19, 31, 1 } } }, { { { 23, 0, 0 }, { 19, 31, 0 } } }, { { { 23, 0, 1 }, { 19, 31, 1 } } }, { { { 23, 0, 2 }, { 20, 30, 1 } } }, { { { 23, 0, 3 }, { 20, 30, 0 } } }, { { { 23, 0, 4 }, { 22, 27, 1 } } }, { { { 24, 0, 4 }, { 22, 27, 0 } } }, { { { 24, 0, 3 }, { 20, 31, 0 } } }, { { { 24, 0, 2 }, { 21, 30, 1 } } }, { { { 24, 0, 1 }, { 21, 30, 0 } } }, { { { 24, 0, 0 }, { 24, 24, 0 } } }, { { { 24, 0, 1 }, { 21, 31, 1 } } }, { { { 24, 0, 2 }, { 21, 31, 0 } } }, { { { 24, 0, 3 }, { 21, 31, 1 } } }, { { { 24, 0, 4 }, { 22, 30, 1 } } }, { { { 25, 0, 3 }, { 22, 30, 0 } } }, { { { 25, 0, 2 }, { 22, 31, 1 } } }, { { { 25, 0, 1 }, { 22, 31, 0 } } }, { { { 25, 0, 0 }, { 24, 27, 0 } } }, { { { 25, 0, 1 }, { 23, 30, 1 } } }, { { { 25, 0, 2 }, { 23, 30, 0 } } }, { { { 25, 0, 3 }, { 24, 28, 0 } } }, { { { 25, 0, 4 }, { 23, 31, 1 } } }, { { { 26, 0, 3 }, { 23, 31, 0 } } }, { { { 26, 0, 2 }, { 23, 31, 1 } } }, { { { 26, 0, 1 }, { 24, 30, 1 } } }, { { { 26, 0, 0 }, { 24, 30, 0 } } }, { { { 26, 0, 1 }, { 26, 27, 1 } } }, { { { 26, 0, 2 }, { 26, 27, 0 } } }, { { { 26, 0, 3 }, { 24, 31, 0 } } }, { { { 26, 0, 4 }, { 25, 30, 1 } } }, { { { 27, 0, 3 }, { 25, 30, 0 } } }, { { { 27, 0, 2 }, { 28, 24, 0 } } }, { { { 27, 0, 1 }, { 25, 31, 1 } } }, { { { 27, 0, 0 }, { 25, 31, 0 } } }, { { { 27, 0, 1 }, { 25, 31, 1 } } }, { { { 27, 0, 2 }, { 26, 30, 1 } } }, { { { 27, 0, 3 }, { 26, 30, 0 } } }, { { { 27, 0, 4 }, { 26, 31, 1 } } }, { { { 28, 0, 4 }, { 26, 31, 0 } } }, { { { 28, 0, 3 }, { 28, 27, 0 } } }, { { { 28, 0, 2 }, { 27, 30, 1 } } }, { { { 28, 0, 1 }, { 27, 30, 0 } } }, { { { 28, 0, 0 }, { 28, 28, 0 } } }, { { { 28, 0, 1 }, { 27, 31, 1 } } }, { { { 28, 0, 2 }, { 27, 31, 0 } } }, { { { 28, 0, 3 }, { 27, 31, 1 } } }, { { { 28, 0, 4 }, { 28, 30, 1 } } }, { { { 29, 0, 3 }, { 28, 30, 0 } } }, { { { 29, 0, 2 }, { 30, 27, 1 } } }, { { { 29, 0, 1 }, { 30, 27, 0 } } }, { { { 29, 0, 0 }, { 28, 31, 0 } } }, { { { 29, 0, 1 }, { 29, 30, 1 } } }, { { { 29, 0, 2 }, { 29, 30, 0 } } }, { { { 29, 0, 3 }, { 29, 30, 1 } } }, { { { 29, 0, 4 }, { 29, 31, 1 } } }, { { { 30, 0, 3 }, { 29, 31, 0 } } }, { { { 30, 0, 2 }, { 29, 31, 1 } } }, { { { 30, 0, 1 }, { 30, 30, 1 } } }, { { { 30, 0, 0 }, { 30, 30, 0 } } }, { { { 30, 0, 1 }, { 30, 31, 1 } } }, { { { 30, 0, 2 }, { 30, 31, 0 } } }, { { { 30, 0, 3 }, { 30, 31, 1 } } }, { { { 30, 0, 4 }, { 31, 30, 1 } } }, { { { 31, 0, 3 }, { 31, 30, 0 } } }, { { { 31, 0, 2 }, { 31, 30, 1 } } }, { { { 31, 0, 1 }, { 31, 31, 1 } } }, { { { 31, 0, 0 }, { 31, 31, 0 } } } }; static SingleColourLookup const lookup_6_4[] = { { { { 0, 0, 0 }, { 0, 0, 0 } } }, { { { 0, 0, 1 }, { 0, 1, 0 } } }, { { { 0, 0, 2 }, { 0, 2, 0 } } }, { { { 1, 0, 1 }, { 0, 3, 1 } } }, { { { 1, 0, 0 }, { 0, 3, 0 } } }, { { { 1, 0, 1 }, { 0, 4, 0 } } }, { { { 1, 0, 2 }, { 0, 5, 0 } } }, { { { 2, 0, 1 }, { 0, 6, 1 } } }, { { { 2, 0, 0 }, { 0, 6, 0 } } }, { { { 2, 0, 1 }, { 0, 7, 0 } } }, { { { 2, 0, 2 }, { 0, 8, 0 } } }, { { { 3, 0, 1 }, { 0, 9, 1 } } }, { { { 3, 0, 0 }, { 0, 9, 0 } } }, { { { 3, 0, 1 }, { 0, 10, 0 } } }, { { { 3, 0, 2 }, { 0, 11, 0 } } }, { { { 4, 0, 1 }, { 0, 12, 1 } } }, { { { 4, 0, 0 }, { 0, 12, 0 } } }, { { { 4, 0, 1 }, { 0, 13, 0 } } }, { { { 4, 0, 2 }, { 0, 14, 0 } } }, { { { 5, 0, 1 }, { 0, 15, 1 } } }, { { { 5, 0, 0 }, { 0, 15, 0 } } }, { { { 5, 0, 1 }, { 0, 16, 0 } } }, { { { 5, 0, 2 }, { 1, 15, 0 } } }, { { { 6, 0, 1 }, { 0, 17, 0 } } }, { { { 6, 0, 0 }, { 0, 18, 0 } } }, { { { 6, 0, 1 }, { 0, 19, 0 } } }, { { { 6, 0, 2 }, { 3, 14, 0 } } }, { { { 7, 0, 1 }, { 0, 20, 0 } } }, { { { 7, 0, 0 }, { 0, 21, 0 } } }, { { { 7, 0, 1 }, { 0, 22, 0 } } }, { { { 7, 0, 2 }, { 4, 15, 0 } } }, { { { 8, 0, 1 }, { 0, 23, 0 } } }, { { { 8, 0, 0 }, { 0, 24, 0 } } }, { { { 8, 0, 1 }, { 0, 25, 0 } } }, { { { 8, 0, 2 }, { 6, 14, 0 } } }, { { { 9, 0, 1 }, { 0, 26, 0 } } }, { { { 9, 0, 0 }, { 0, 27, 0 } } }, { { { 9, 0, 1 }, { 0, 28, 0 } } }, { { { 9, 0, 2 }, { 7, 15, 0 } } }, { { { 10, 0, 1 }, { 0, 29, 0 } } }, { { { 10, 0, 0 }, { 0, 30, 0 } } }, { { { 10, 0, 1 }, { 0, 31, 0 } } }, { { { 10, 0, 2 }, { 9, 14, 0 } } }, { { { 11, 0, 1 }, { 0, 32, 0 } } }, { { { 11, 0, 0 }, { 0, 33, 0 } } }, { { { 11, 0, 1 }, { 2, 30, 0 } } }, { { { 11, 0, 2 }, { 0, 34, 0 } } }, { { { 12, 0, 1 }, { 0, 35, 0 } } }, { { { 12, 0, 0 }, { 0, 36, 0 } } }, { { { 12, 0, 1 }, { 3, 31, 0 } } }, { { { 12, 0, 2 }, { 0, 37, 0 } } }, { { { 13, 0, 1 }, { 0, 38, 0 } } }, { { { 13, 0, 0 }, { 0, 39, 0 } } }, { { { 13, 0, 1 }, { 5, 30, 0 } } }, { { { 13, 0, 2 }, { 0, 40, 0 } } }, { { { 14, 0, 1 }, { 0, 41, 0 } } }, { { { 14, 0, 0 }, { 0, 42, 0 } } }, { { { 14, 0, 1 }, { 6, 31, 0 } } }, { { { 14, 0, 2 }, { 0, 43, 0 } } }, { { { 15, 0, 1 }, { 0, 44, 0 } } }, { { { 15, 0, 0 }, { 0, 45, 0 } } }, { { { 15, 0, 1 }, { 8, 30, 0 } } }, { { { 15, 0, 2 }, { 0, 46, 0 } } }, { { { 16, 0, 2 }, { 0, 47, 0 } } }, { { { 16, 0, 1 }, { 1, 46, 0 } } }, { { { 16, 0, 0 }, { 0, 48, 0 } } }, { { { 16, 0, 1 }, { 0, 49, 0 } } }, { { { 16, 0, 2 }, { 0, 50, 0 } } }, { { { 17, 0, 1 }, { 2, 47, 0 } } }, { { { 17, 0, 0 }, { 0, 51, 0 } } }, { { { 17, 0, 1 }, { 0, 52, 0 } } }, { { { 17, 0, 2 }, { 0, 53, 0 } } }, { { { 18, 0, 1 }, { 4, 46, 0 } } }, { { { 18, 0, 0 }, { 0, 54, 0 } } }, { { { 18, 0, 1 }, { 0, 55, 0 } } }, { { { 18, 0, 2 }, { 0, 56, 0 } } }, { { { 19, 0, 1 }, { 5, 47, 0 } } }, { { { 19, 0, 0 }, { 0, 57, 0 } } }, { { { 19, 0, 1 }, { 0, 58, 0 } } }, { { { 19, 0, 2 }, { 0, 59, 0 } } }, { { { 20, 0, 1 }, { 7, 46, 0 } } }, { { { 20, 0, 0 }, { 0, 60, 0 } } }, { { { 20, 0, 1 }, { 0, 61, 0 } } }, { { { 20, 0, 2 }, { 0, 62, 0 } } }, { { { 21, 0, 1 }, { 8, 47, 0 } } }, { { { 21, 0, 0 }, { 0, 63, 0 } } }, { { { 21, 0, 1 }, { 1, 62, 0 } } }, { { { 21, 0, 2 }, { 1, 63, 0 } } }, { { { 22, 0, 1 }, { 10, 46, 0 } } }, { { { 22, 0, 0 }, { 2, 62, 0 } } }, { { { 22, 0, 1 }, { 2, 63, 0 } } }, { { { 22, 0, 2 }, { 3, 62, 0 } } }, { { { 23, 0, 1 }, { 11, 47, 0 } } }, { { { 23, 0, 0 }, { 3, 63, 0 } } }, { { { 23, 0, 1 }, { 4, 62, 0 } } }, { { { 23, 0, 2 }, { 4, 63, 0 } } }, { { { 24, 0, 1 }, { 13, 46, 0 } } }, { { { 24, 0, 0 }, { 5, 62, 0 } } }, { { { 24, 0, 1 }, { 5, 63, 0 } } }, { { { 24, 0, 2 }, { 6, 62, 0 } } }, { { { 25, 0, 1 }, { 14, 47, 0 } } }, { { { 25, 0, 0 }, { 6, 63, 0 } } }, { { { 25, 0, 1 }, { 7, 62, 0 } } }, { { { 25, 0, 2 }, { 7, 63, 0 } } }, { { { 26, 0, 1 }, { 16, 45, 0 } } }, { { { 26, 0, 0 }, { 8, 62, 0 } } }, { { { 26, 0, 1 }, { 8, 63, 0 } } }, { { { 26, 0, 2 }, { 9, 62, 0 } } }, { { { 27, 0, 1 }, { 16, 48, 0 } } }, { { { 27, 0, 0 }, { 9, 63, 0 } } }, { { { 27, 0, 1 }, { 10, 62, 0 } } }, { { { 27, 0, 2 }, { 10, 63, 0 } } }, { { { 28, 0, 1 }, { 16, 51, 0 } } }, { { { 28, 0, 0 }, { 11, 62, 0 } } }, { { { 28, 0, 1 }, { 11, 63, 0 } } }, { { { 28, 0, 2 }, { 12, 62, 0 } } }, { { { 29, 0, 1 }, { 16, 54, 0 } } }, { { { 29, 0, 0 }, { 12, 63, 0 } } }, { { { 29, 0, 1 }, { 13, 62, 0 } } }, { { { 29, 0, 2 }, { 13, 63, 0 } } }, { { { 30, 0, 1 }, { 16, 57, 0 } } }, { { { 30, 0, 0 }, { 14, 62, 0 } } }, { { { 30, 0, 1 }, { 14, 63, 0 } } }, { { { 30, 0, 2 }, { 15, 62, 0 } } }, { { { 31, 0, 1 }, { 16, 60, 0 } } }, { { { 31, 0, 0 }, { 15, 63, 0 } } }, { { { 31, 0, 1 }, { 24, 46, 0 } } }, { { { 31, 0, 2 }, { 16, 62, 0 } } }, { { { 32, 0, 2 }, { 16, 63, 0 } } }, { { { 32, 0, 1 }, { 17, 62, 0 } } }, { { { 32, 0, 0 }, { 25, 47, 0 } } }, { { { 32, 0, 1 }, { 17, 63, 0 } } }, { { { 32, 0, 2 }, { 18, 62, 0 } } }, { { { 33, 0, 1 }, { 18, 63, 0 } } }, { { { 33, 0, 0 }, { 27, 46, 0 } } }, { { { 33, 0, 1 }, { 19, 62, 0 } } }, { { { 33, 0, 2 }, { 19, 63, 0 } } }, { { { 34, 0, 1 }, { 20, 62, 0 } } }, { { { 34, 0, 0 }, { 28, 47, 0 } } }, { { { 34, 0, 1 }, { 20, 63, 0 } } }, { { { 34, 0, 2 }, { 21, 62, 0 } } }, { { { 35, 0, 1 }, { 21, 63, 0 } } }, { { { 35, 0, 0 }, { 30, 46, 0 } } }, { { { 35, 0, 1 }, { 22, 62, 0 } } }, { { { 35, 0, 2 }, { 22, 63, 0 } } }, { { { 36, 0, 1 }, { 23, 62, 0 } } }, { { { 36, 0, 0 }, { 31, 47, 0 } } }, { { { 36, 0, 1 }, { 23, 63, 0 } } }, { { { 36, 0, 2 }, { 24, 62, 0 } } }, { { { 37, 0, 1 }, { 24, 63, 0 } } }, { { { 37, 0, 0 }, { 32, 47, 0 } } }, { { { 37, 0, 1 }, { 25, 62, 0 } } }, { { { 37, 0, 2 }, { 25, 63, 0 } } }, { { { 38, 0, 1 }, { 26, 62, 0 } } }, { { { 38, 0, 0 }, { 32, 50, 0 } } }, { { { 38, 0, 1 }, { 26, 63, 0 } } }, { { { 38, 0, 2 }, { 27, 62, 0 } } }, { { { 39, 0, 1 }, { 27, 63, 0 } } }, { { { 39, 0, 0 }, { 32, 53, 0 } } }, { { { 39, 0, 1 }, { 28, 62, 0 } } }, { { { 39, 0, 2 }, { 28, 63, 0 } } }, { { { 40, 0, 1 }, { 29, 62, 0 } } }, { { { 40, 0, 0 }, { 32, 56, 0 } } }, { { { 40, 0, 1 }, { 29, 63, 0 } } }, { { { 40, 0, 2 }, { 30, 62, 0 } } }, { { { 41, 0, 1 }, { 30, 63, 0 } } }, { { { 41, 0, 0 }, { 32, 59, 0 } } }, { { { 41, 0, 1 }, { 31, 62, 0 } } }, { { { 41, 0, 2 }, { 31, 63, 0 } } }, { { { 42, 0, 1 }, { 32, 61, 0 } } }, { { { 42, 0, 0 }, { 32, 62, 0 } } }, { { { 42, 0, 1 }, { 32, 63, 0 } } }, { { { 42, 0, 2 }, { 41, 46, 0 } } }, { { { 43, 0, 1 }, { 33, 62, 0 } } }, { { { 43, 0, 0 }, { 33, 63, 0 } } }, { { { 43, 0, 1 }, { 34, 62, 0 } } }, { { { 43, 0, 2 }, { 42, 47, 0 } } }, { { { 44, 0, 1 }, { 34, 63, 0 } } }, { { { 44, 0, 0 }, { 35, 62, 0 } } }, { { { 44, 0, 1 }, { 35, 63, 0 } } }, { { { 44, 0, 2 }, { 44, 46, 0 } } }, { { { 45, 0, 1 }, { 36, 62, 0 } } }, { { { 45, 0, 0 }, { 36, 63, 0 } } }, { { { 45, 0, 1 }, { 37, 62, 0 } } }, { { { 45, 0, 2 }, { 45, 47, 0 } } }, { { { 46, 0, 1 }, { 37, 63, 0 } } }, { { { 46, 0, 0 }, { 38, 62, 0 } } }, { { { 46, 0, 1 }, { 38, 63, 0 } } }, { { { 46, 0, 2 }, { 47, 46, 0 } } }, { { { 47, 0, 1 }, { 39, 62, 0 } } }, { { { 47, 0, 0 }, { 39, 63, 0 } } }, { { { 47, 0, 1 }, { 40, 62, 0 } } }, { { { 47, 0, 2 }, { 48, 46, 0 } } }, { { { 48, 0, 2 }, { 40, 63, 0 } } }, { { { 48, 0, 1 }, { 41, 62, 0 } } }, { { { 48, 0, 0 }, { 41, 63, 0 } } }, { { { 48, 0, 1 }, { 48, 49, 0 } } }, { { { 48, 0, 2 }, { 42, 62, 0 } } }, { { { 49, 0, 1 }, { 42, 63, 0 } } }, { { { 49, 0, 0 }, { 43, 62, 0 } } }, { { { 49, 0, 1 }, { 48, 52, 0 } } }, { { { 49, 0, 2 }, { 43, 63, 0 } } }, { { { 50, 0, 1 }, { 44, 62, 0 } } }, { { { 50, 0, 0 }, { 44, 63, 0 } } }, { { { 50, 0, 1 }, { 48, 55, 0 } } }, { { { 50, 0, 2 }, { 45, 62, 0 } } }, { { { 51, 0, 1 }, { 45, 63, 0 } } }, { { { 51, 0, 0 }, { 46, 62, 0 } } }, { { { 51, 0, 1 }, { 48, 58, 0 } } }, { { { 51, 0, 2 }, { 46, 63, 0 } } }, { { { 52, 0, 1 }, { 47, 62, 0 } } }, { { { 52, 0, 0 }, { 47, 63, 0 } } }, { { { 52, 0, 1 }, { 48, 61, 0 } } }, { { { 52, 0, 2 }, { 48, 62, 0 } } }, { { { 53, 0, 1 }, { 56, 47, 0 } } }, { { { 53, 0, 0 }, { 48, 63, 0 } } }, { { { 53, 0, 1 }, { 49, 62, 0 } } }, { { { 53, 0, 2 }, { 49, 63, 0 } } }, { { { 54, 0, 1 }, { 58, 46, 0 } } }, { { { 54, 0, 0 }, { 50, 62, 0 } } }, { { { 54, 0, 1 }, { 50, 63, 0 } } }, { { { 54, 0, 2 }, { 51, 62, 0 } } }, { { { 55, 0, 1 }, { 59, 47, 0 } } }, { { { 55, 0, 0 }, { 51, 63, 0 } } }, { { { 55, 0, 1 }, { 52, 62, 0 } } }, { { { 55, 0, 2 }, { 52, 63, 0 } } }, { { { 56, 0, 1 }, { 61, 46, 0 } } }, { { { 56, 0, 0 }, { 53, 62, 0 } } }, { { { 56, 0, 1 }, { 53, 63, 0 } } }, { { { 56, 0, 2 }, { 54, 62, 0 } } }, { { { 57, 0, 1 }, { 62, 47, 0 } } }, { { { 57, 0, 0 }, { 54, 63, 0 } } }, { { { 57, 0, 1 }, { 55, 62, 0 } } }, { { { 57, 0, 2 }, { 55, 63, 0 } } }, { { { 58, 0, 1 }, { 56, 62, 1 } } }, { { { 58, 0, 0 }, { 56, 62, 0 } } }, { { { 58, 0, 1 }, { 56, 63, 0 } } }, { { { 58, 0, 2 }, { 57, 62, 0 } } }, { { { 59, 0, 1 }, { 57, 63, 1 } } }, { { { 59, 0, 0 }, { 57, 63, 0 } } }, { { { 59, 0, 1 }, { 58, 62, 0 } } }, { { { 59, 0, 2 }, { 58, 63, 0 } } }, { { { 60, 0, 1 }, { 59, 62, 1 } } }, { { { 60, 0, 0 }, { 59, 62, 0 } } }, { { { 60, 0, 1 }, { 59, 63, 0 } } }, { { { 60, 0, 2 }, { 60, 62, 0 } } }, { { { 61, 0, 1 }, { 60, 63, 1 } } }, { { { 61, 0, 0 }, { 60, 63, 0 } } }, { { { 61, 0, 1 }, { 61, 62, 0 } } }, { { { 61, 0, 2 }, { 61, 63, 0 } } }, { { { 62, 0, 1 }, { 62, 62, 1 } } }, { { { 62, 0, 0 }, { 62, 62, 0 } } }, { { { 62, 0, 1 }, { 62, 63, 0 } } }, { { { 62, 0, 2 }, { 63, 62, 0 } } }, { { { 63, 0, 1 }, { 63, 63, 1 } } }, { { { 63, 0, 0 }, { 63, 63, 0 } } } }; openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/simd_sse.h0000644000175000017500000001156012271062644022571 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_SIMD_SSE_H #define SQUISH_SIMD_SSE_H #include #if ( SQUISH_USE_SSE > 1 ) #include #endif #define SQUISH_SSE_SPLAT( a ) \ ( ( a ) | ( ( a ) << 2 ) | ( ( a ) << 4 ) | ( ( a ) << 6 ) ) #define SQUISH_SSE_SHUF( x, y, z, w ) \ ( ( x ) | ( ( y ) << 2 ) | ( ( z ) << 4 ) | ( ( w ) << 6 ) ) namespace squish { #define VEC4_CONST( X ) Vec4( X ) class Vec4 { public: typedef Vec4 const& Arg; Vec4() {} explicit Vec4( __m128 v ) : m_v( v ) {} Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {} Vec4& operator=( Vec4 const& arg ) { m_v = arg.m_v; return *this; } explicit Vec4( float s ) : m_v( _mm_set1_ps( s ) ) {} Vec4( float x, float y, float z, float w ) : m_v( _mm_setr_ps( x, y, z, w ) ) {} Vec3 GetVec3() const { #ifdef __GNUC__ __attribute__ ((__aligned__ (16))) float c[4]; #else __declspec(align(16)) float c[4]; #endif _mm_store_ps( c, m_v ); return Vec3( c[0], c[1], c[2] ); } Vec4 SplatX() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 0 ) ) ); } Vec4 SplatY() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 1 ) ) ); } Vec4 SplatZ() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 2 ) ) ); } Vec4 SplatW() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 3 ) ) ); } Vec4& operator+=( Arg v ) { m_v = _mm_add_ps( m_v, v.m_v ); return *this; } Vec4& operator-=( Arg v ) { m_v = _mm_sub_ps( m_v, v.m_v ); return *this; } Vec4& operator*=( Arg v ) { m_v = _mm_mul_ps( m_v, v.m_v ); return *this; } friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) { return Vec4( _mm_add_ps( left.m_v, right.m_v ) ); } friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) { return Vec4( _mm_sub_ps( left.m_v, right.m_v ) ); } friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) { return Vec4( _mm_mul_ps( left.m_v, right.m_v ) ); } //! Returns a*b + c friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) { return Vec4( _mm_add_ps( _mm_mul_ps( a.m_v, b.m_v ), c.m_v ) ); } //! Returns -( a*b - c ) friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) { return Vec4( _mm_sub_ps( c.m_v, _mm_mul_ps( a.m_v, b.m_v ) ) ); } friend Vec4 Reciprocal( Vec4::Arg v ) { // get the reciprocal estimate __m128 estimate = _mm_rcp_ps( v.m_v ); // one round of Newton-Rhaphson refinement __m128 diff = _mm_sub_ps( _mm_set1_ps( 1.0f ), _mm_mul_ps( estimate, v.m_v ) ); return Vec4( _mm_add_ps( _mm_mul_ps( diff, estimate ), estimate ) ); } friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) { return Vec4( _mm_min_ps( left.m_v, right.m_v ) ); } friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) { return Vec4( _mm_max_ps( left.m_v, right.m_v ) ); } friend Vec4 Truncate( Vec4::Arg v ) { #if ( SQUISH_USE_SSE == 1 ) // convert to ints __m128 input = v.m_v; __m64 lo = _mm_cvttps_pi32( input ); __m64 hi = _mm_cvttps_pi32( _mm_movehl_ps( input, input ) ); // convert to floats __m128 part = _mm_movelh_ps( input, _mm_cvtpi32_ps( input, hi ) ); __m128 truncated = _mm_cvtpi32_ps( part, lo ); // clear out the MMX multimedia state to allow FP calls later _mm_empty(); return Vec4( truncated ); #else // use SSE2 instructions return Vec4( _mm_cvtepi32_ps( _mm_cvttps_epi32( v.m_v ) ) ); #endif } friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) { __m128 bits = _mm_cmplt_ps( left.m_v, right.m_v ); int value = _mm_movemask_ps( bits ); return value != 0; } private: __m128 m_v; }; } // namespace squish #endif // ndef SQUISH_SIMD_SSE_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/config.h0000644000175000017500000000355212271062644022232 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_CONFIG_H #define SQUISH_CONFIG_H // Set to 1 when building squish to use Altivec instructions. #ifndef SQUISH_USE_ALTIVEC #define SQUISH_USE_ALTIVEC 0 #endif // Set to 1 or 2 when building squish to use SSE or SSE2 instructions. #ifndef SQUISH_USE_SSE #define SQUISH_USE_SSE 0 #endif // Internally set SQUISH_USE_SIMD when either Altivec or SSE is available. #if SQUISH_USE_ALTIVEC && SQUISH_USE_SSE #error "Cannot enable both Altivec and SSE!" #endif #if SQUISH_USE_ALTIVEC || SQUISH_USE_SSE #define SQUISH_USE_SIMD 1 #else #define SQUISH_USE_SIMD 0 #endif #endif // ndef SQUISH_CONFIG_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/colourblock.h0000644000175000017500000000326512271062644023304 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_COLOURBLOCK_H #define SQUISH_COLOURBLOCK_H #include "squish.h" #include "maths.h" namespace squish { void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); void DecompressColour( u8* rgba, void const* block, bool isDxt1 ); } // namespace squish #endif // ndef SQUISH_COLOURBLOCK_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/colourset.cpp0000644000175000017500000000664312271062644023343 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #include "colourset.h" namespace squish { ColourSet::ColourSet( u8 const* rgba, int mask, int flags ) : m_count( 0 ), m_transparent( false ) { // check the compression mode for dxt1 bool isDxt1 = ( ( flags & kDxt1 ) != 0 ); bool weightByAlpha = ( ( flags & kWeightColourByAlpha ) != 0 ); // create the minimal set for( int i = 0; i < 16; ++i ) { // check this pixel is enabled int bit = 1 << i; if( ( mask & bit ) == 0 ) { m_remap[i] = -1; continue; } // check for transparent pixels when using dxt1 if( isDxt1 && rgba[4*i + 3] < 128 ) { m_remap[i] = -1; m_transparent = true; continue; } // loop over previous points for a match for( int j = 0;; ++j ) { // allocate a new point if( j == i ) { // normalise coordinates to [0,1] float x = ( float )rgba[4*i] / 255.0f; float y = ( float )rgba[4*i + 1] / 255.0f; float z = ( float )rgba[4*i + 2] / 255.0f; // ensure there is always non-zero weight even for zero alpha float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f; // add the point m_points[m_count] = Vec3( x, y, z ); m_weights[m_count] = ( weightByAlpha ? w : 1.0f ); m_remap[i] = m_count; // advance ++m_count; break; } // check for a match int oldbit = 1 << j; bool match = ( ( mask & oldbit ) != 0 ) && ( rgba[4*i] == rgba[4*j] ) && ( rgba[4*i + 1] == rgba[4*j + 1] ) && ( rgba[4*i + 2] == rgba[4*j + 2] ) && ( rgba[4*j + 3] >= 128 || !isDxt1 ); if( match ) { // get the index of the match int index = m_remap[j]; // ensure there is always non-zero weight even for zero alpha float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f; // map to this point and increase the weight m_weights[index] += ( weightByAlpha ? w : 1.0f ); m_remap[i] = index; break; } } } // square root the weights for( int i = 0; i < m_count; ++i ) m_weights[i] = std::sqrt( m_weights[i] ); } void ColourSet::RemapIndices( u8 const* source, u8* target ) const { for( int i = 0; i < 16; ++i ) { int j = m_remap[i]; if( j == -1 ) target[i] = 3; else target[i] = source[j]; } } } // namespace squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/colourfit.cpp0000644000175000017500000000331212271062644023320 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #include "colourfit.h" #include "colourset.h" namespace squish { ColourFit::ColourFit( ColourSet const* colours, int flags ) : m_colours( colours ), m_flags( flags ) { } ColourFit::~ColourFit() { } void ColourFit::Compress( void* block ) { bool isDxt1 = ( ( m_flags & kDxt1 ) != 0 ); if( isDxt1 ) { Compress3( block ); if( !m_colours->IsTransparent() ) Compress4( block ); } else Compress4( block ); } } // namespace squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/README0000644000175000017500000000272212271062644021472 0ustar mfvmfvLICENSE ------- The squish library is distributed under the terms and conditions of the MIT license. This license is specified at the top of each source file and must be preserved in its entirety. BUILDING AND INSTALLING THE LIBRARY ----------------------------------- If you are using Visual Studio 2003 or above under Windows then load the Visual Studio 2003 project in the vs7 folder. By default, the library is built using SSE2 optimisations. To change this either change or remove the SQUISH_USE_SSE=2 from the preprocessor symbols. If you are using a Mac then load the Xcode 2.2 project in the distribution. By default, the library is built using Altivec optimisations. To change this either change or remove SQUISH_USE_ALTIVEC=1 from the preprocessor symbols. I guess I'll have to think about changing this for the new Intel Macs that are rolling out... If you are using unix then first edit the config file in the base directory of the distribution, enabling Altivec or SSE with the USE_ALTIVEC or USE_SSE variables, and editing the optimisation flags passed to the C++ compiler if necessary. Then make can be used to build the library, and make install (from the superuser account) can be used to install (into /usr/local by default). REPORTING BUGS OR FEATURE REQUESTS ---------------------------------- Feedback can be sent to Simon Brown (the developer) at si@sjbrown.co.uk New releases are announced on the squish library homepage at http://sjbrown.co.uk/?code=squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/colourblock.cpp0000644000175000017500000001216512271062644023636 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #include "colourblock.h" namespace squish { static int FloatToInt( float a, int limit ) { // use ANSI round-to-zero behaviour to get round-to-nearest int i = ( int )( a + 0.5f ); // clamp to the limit if( i < 0 ) i = 0; else if( i > limit ) i = limit; // done return i; } static int FloatTo565( Vec3::Arg colour ) { // get the components in the correct range int r = FloatToInt( 31.0f*colour.X(), 31 ); int g = FloatToInt( 63.0f*colour.Y(), 63 ); int b = FloatToInt( 31.0f*colour.Z(), 31 ); // pack into a single value return ( r << 11 ) | ( g << 5 ) | b; } static void WriteColourBlock( int a, int b, u8* indices, void* block ) { // get the block as bytes u8* bytes = ( u8* )block; // write the endpoints bytes[0] = ( u8 )( a & 0xff ); bytes[1] = ( u8 )( a >> 8 ); bytes[2] = ( u8 )( b & 0xff ); bytes[3] = ( u8 )( b >> 8 ); // write the indices for( int i = 0; i < 4; ++i ) { u8 const* ind = indices + 4*i; bytes[4 + i] = ind[0] | ( ind[1] << 2 ) | ( ind[2] << 4 ) | ( ind[3] << 6 ); } } void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ) { // get the packed values int a = FloatTo565( start ); int b = FloatTo565( end ); // remap the indices u8 remapped[16]; if( a <= b ) { // use the indices directly for( int i = 0; i < 16; ++i ) remapped[i] = indices[i]; } else { // swap a and b std::swap( a, b ); for( int i = 0; i < 16; ++i ) { if( indices[i] == 0 ) remapped[i] = 1; else if( indices[i] == 1 ) remapped[i] = 0; else remapped[i] = indices[i]; } } // write the block WriteColourBlock( a, b, remapped, block ); } void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ) { // get the packed values int a = FloatTo565( start ); int b = FloatTo565( end ); // remap the indices u8 remapped[16]; if( a < b ) { // swap a and b std::swap( a, b ); for( int i = 0; i < 16; ++i ) remapped[i] = ( indices[i] ^ 0x1 ) & 0x3; } else if( a == b ) { // use index 0 for( int i = 0; i < 16; ++i ) remapped[i] = 0; } else { // use the indices directly for( int i = 0; i < 16; ++i ) remapped[i] = indices[i]; } // write the block WriteColourBlock( a, b, remapped, block ); } static int Unpack565( u8 const* packed, u8* colour ) { // build the packed value int value = ( int )packed[0] | ( ( int )packed[1] << 8 ); // get the components in the stored range u8 red = ( u8 )( ( value >> 11 ) & 0x1f ); u8 green = ( u8 )( ( value >> 5 ) & 0x3f ); u8 blue = ( u8 )( value & 0x1f ); // scale up to 8 bits colour[0] = ( red << 3 ) | ( red >> 2 ); colour[1] = ( green << 2 ) | ( green >> 4 ); colour[2] = ( blue << 3 ) | ( blue >> 2 ); colour[3] = 255; // return the value return value; } void DecompressColour( u8* rgba, void const* block, bool isDxt1 ) { // get the block bytes u8 const* bytes = reinterpret_cast< u8 const* >( block ); // unpack the endpoints u8 codes[16]; int a = Unpack565( bytes, codes ); int b = Unpack565( bytes + 2, codes + 4 ); // generate the midpoints for( int i = 0; i < 3; ++i ) { int c = codes[i]; int d = codes[4 + i]; if( isDxt1 && a <= b ) { codes[8 + i] = ( u8 )( ( c + d )/2 ); codes[12 + i] = 0; } else { codes[8 + i] = ( u8 )( ( 2*c + d )/3 ); codes[12 + i] = ( u8 )( ( c + 2*d )/3 ); } } // fill in alpha for the intermediate values codes[8 + 3] = 255; codes[12 + 3] = ( isDxt1 && a <= b ) ? 0 : 255; // unpack the indices u8 indices[16]; for( int i = 0; i < 4; ++i ) { u8* ind = indices + 4*i; u8 packed = bytes[4 + i]; ind[0] = packed & 0x3; ind[1] = ( packed >> 2 ) & 0x3; ind[2] = ( packed >> 4 ) & 0x3; ind[3] = ( packed >> 6 ) & 0x3; } // store out the colours for( int i = 0; i < 16; ++i ) { u8 offset = 4*indices[i]; for( int j = 0; j < 4; ++j ) rgba[4*i + j] = codes[offset + j]; } } } // namespace squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/clusterfit.h0000644000175000017500000000376512271062644023157 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Copyright (c) 2007 Ignacio Castano icastano@nvidia.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_CLUSTERFIT_H #define SQUISH_CLUSTERFIT_H #include "squish.h" #include "maths.h" #include "simd.h" #include "colourfit.h" namespace squish { class ClusterFit : public ColourFit { public: ClusterFit( ColourSet const* colours, int flags, float* metric ); private: bool ConstructOrdering( Vec3 const& axis, int iteration ); virtual void Compress3( void* block ); virtual void Compress4( void* block ); enum { kMaxIterations = 8 }; int m_iterationCount; Vec3 m_principle; u8 m_order[16*kMaxIterations]; Vec4 m_points_weights[16]; Vec4 m_xsum_wsum; Vec4 m_metric; Vec4 m_besterror; }; } // namespace squish #endif // ndef SQUISH_CLUSTERFIT_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/squish.h0000644000175000017500000002573512271062644022310 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_H #define SQUISH_H //! All squish API functions live in this namespace. namespace squish { // ----------------------------------------------------------------------------- //! Typedef a quantity that is a single unsigned byte. typedef unsigned char u8; // ----------------------------------------------------------------------------- enum { //! Use DXT1 compression. kDxt1 = ( 1 << 0 ), //! Use DXT3 compression. kDxt3 = ( 1 << 1 ), //! Use DXT5 compression. kDxt5 = ( 1 << 2 ), //! Use a very slow but very high quality colour compressor. kColourIterativeClusterFit = ( 1 << 8 ), //! Use a slow but high quality colour compressor (the default). kColourClusterFit = ( 1 << 3 ), //! Use a fast but low quality colour compressor. kColourRangeFit = ( 1 << 4 ), //! Weight the colour by alpha during cluster fit (disabled by default). kWeightColourByAlpha = ( 1 << 7 ) }; // ----------------------------------------------------------------------------- /*! @brief Compresses a 4x4 block of pixels. @param rgba The rgba values of the 16 source pixels. @param mask The valid pixel mask. @param block Storage for the compressed DXT block. @param flags Compression flags. @param metric An optional perceptual metric. The source pixels should be presented as a contiguous array of 16 rgba values, with each component as 1 byte each. In memory this should be: { r1, g1, b1, a1, .... , r16, g16, b16, a16 } The mask parameter enables only certain pixels within the block. The lowest bit enables the first pixel and so on up to the 16th bit. Bits beyond the 16th bit are ignored. Pixels that are not enabled are allowed to take arbitrary colours in the output block. An example of how this can be used is in the CompressImage function to disable pixels outside the bounds of the image when the width or height is not divisible by 4. The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, however, DXT1 will be used by default if none is specified. When using DXT1 compression, 8 bytes of storage are required for the compressed DXT block. DXT3 and DXT5 compression require 16 bytes of storage per block. The flags parameter can also specify a preferred colour compressor to use when fitting the RGB components of the data. Possible colour compressors are: kColourClusterFit (the default), kColourRangeFit (very fast, low quality) or kColourIterativeClusterFit (slowest, best quality). When using kColourClusterFit or kColourIterativeClusterFit, an additional flag can be specified to weight the importance of each pixel by its alpha value. For images that are rendered using alpha blending, this can significantly increase the perceived quality. The metric parameter can be used to weight the relative importance of each colour channel, or pass NULL to use the default uniform weight of { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that allowed either uniform or "perceptual" weights with the fixed values { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a contiguous array of 3 floats. */ void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric = 0 ); // ----------------------------------------------------------------------------- /*! @brief Compresses a 4x4 block of pixels. @param rgba The rgba values of the 16 source pixels. @param block Storage for the compressed DXT block. @param flags Compression flags. @param metric An optional perceptual metric. The source pixels should be presented as a contiguous array of 16 rgba values, with each component as 1 byte each. In memory this should be: { r1, g1, b1, a1, .... , r16, g16, b16, a16 } The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, however, DXT1 will be used by default if none is specified. When using DXT1 compression, 8 bytes of storage are required for the compressed DXT block. DXT3 and DXT5 compression require 16 bytes of storage per block. The flags parameter can also specify a preferred colour compressor to use when fitting the RGB components of the data. Possible colour compressors are: kColourClusterFit (the default), kColourRangeFit (very fast, low quality) or kColourIterativeClusterFit (slowest, best quality). When using kColourClusterFit or kColourIterativeClusterFit, an additional flag can be specified to weight the importance of each pixel by its alpha value. For images that are rendered using alpha blending, this can significantly increase the perceived quality. The metric parameter can be used to weight the relative importance of each colour channel, or pass NULL to use the default uniform weight of { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that allowed either uniform or "perceptual" weights with the fixed values { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a contiguous array of 3 floats. This method is an inline that calls CompressMasked with a mask of 0xffff, provided for compatibility with older versions of squish. */ inline void Compress( u8 const* rgba, void* block, int flags, float* metric = 0 ) { CompressMasked( rgba, 0xffff, block, flags, metric ); } // ----------------------------------------------------------------------------- /*! @brief Decompresses a 4x4 block of pixels. @param rgba Storage for the 16 decompressed pixels. @param block The compressed DXT block. @param flags Compression flags. The decompressed pixels will be written as a contiguous array of 16 rgba values, with each component as 1 byte each. In memory this is: { r1, g1, b1, a1, .... , r16, g16, b16, a16 } The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, however, DXT1 will be used by default if none is specified. All other flags are ignored. */ void Decompress( u8* rgba, void const* block, int flags ); // ----------------------------------------------------------------------------- /*! @brief Computes the amount of compressed storage required. @param width The width of the image. @param height The height of the image. @param flags Compression flags. The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, however, DXT1 will be used by default if none is specified. All other flags are ignored. Most DXT images will be a multiple of 4 in each dimension, but this function supports arbitrary size images by allowing the outer blocks to be only partially used. */ int GetStorageRequirements( int width, int height, int flags ); // ----------------------------------------------------------------------------- /*! @brief Compresses an image in memory. @param rgba The pixels of the source. @param width The width of the source image. @param height The height of the source image. @param blocks Storage for the compressed output. @param flags Compression flags. @param metric An optional perceptual metric. The source pixels should be presented as a contiguous array of width*height rgba values, with each component as 1 byte each. In memory this should be: { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, however, DXT1 will be used by default if none is specified. When using DXT1 compression, 8 bytes of storage are required for each compressed DXT block. DXT3 and DXT5 compression require 16 bytes of storage per block. The flags parameter can also specify a preferred colour compressor to use when fitting the RGB components of the data. Possible colour compressors are: kColourClusterFit (the default), kColourRangeFit (very fast, low quality) or kColourIterativeClusterFit (slowest, best quality). When using kColourClusterFit or kColourIterativeClusterFit, an additional flag can be specified to weight the importance of each pixel by its alpha value. For images that are rendered using alpha blending, this can significantly increase the perceived quality. The metric parameter can be used to weight the relative importance of each colour channel, or pass NULL to use the default uniform weight of { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that allowed either uniform or "perceptual" weights with the fixed values { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a contiguous array of 3 floats. Internally this function calls squish::CompressMasked for each block, which allows for pixels outside the image to take arbitrary values. The function squish::GetStorageRequirements can be called to compute the amount of memory to allocate for the compressed output. */ void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric = 0 ); // ----------------------------------------------------------------------------- /*! @brief Decompresses an image in memory. @param rgba Storage for the decompressed pixels. @param width The width of the source image. @param height The height of the source image. @param blocks The compressed DXT blocks. @param flags Compression flags. The decompressed pixels will be written as a contiguous array of width*height 16 rgba values, with each component as 1 byte each. In memory this is: { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, however, DXT1 will be used by default if none is specified. All other flags are ignored. Internally this function calls squish::Decompress for each block. */ void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ); // ----------------------------------------------------------------------------- } // namespace squish #endif // ndef SQUISH_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/alpha.h0000644000175000017500000000321512271062644022046 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #ifndef SQUISH_ALPHA_H #define SQUISH_ALPHA_H #include "squish.h" namespace squish { void CompressAlphaDxt3( u8 const* rgba, int mask, void* block ); void CompressAlphaDxt5( u8 const* rgba, int mask, void* block ); void DecompressAlphaDxt3( u8* rgba, void const* block ); void DecompressAlphaDxt5( u8* rgba, void const* block ); } // namespace squish #endif // ndef SQUISH_ALPHA_H openimageio-1.3.12~dfsg0.orig/src/dds.imageio/squish/clusterfit.cpp0000644000175000017500000002756212271062644023513 0ustar mfvmfv/* ----------------------------------------------------------------------------- Copyright (c) 2006 Simon Brown si@sjbrown.co.uk Copyright (c) 2007 Ignacio Castano icastano@nvidia.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------- */ #include "clusterfit.h" #include "colourset.h" #include "colourblock.h" #include namespace squish { ClusterFit::ClusterFit( ColourSet const* colours, int flags, float* metric ) : ColourFit( colours, flags ) { // set the iteration count m_iterationCount = ( m_flags & kColourIterativeClusterFit ) ? kMaxIterations : 1; // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) if( metric ) m_metric = Vec4( metric[0], metric[1], metric[2], 1.0f ); else m_metric = VEC4_CONST( 1.0f ); // initialise the best error m_besterror = VEC4_CONST( FLT_MAX ); // cache some values int const count = m_colours->GetCount(); Vec3 const* values = m_colours->GetPoints(); // get the covariance matrix Sym3x3 covariance = ComputeWeightedCovariance( count, values, m_colours->GetWeights() ); // compute the principle component m_principle = ComputePrincipleComponent( covariance ); } bool ClusterFit::ConstructOrdering( Vec3 const& axis, int iteration ) { // cache some values int const count = m_colours->GetCount(); Vec3 const* values = m_colours->GetPoints(); // build the list of dot products float dps[16]; u8* order = ( u8* )m_order + 16*iteration; for( int i = 0; i < count; ++i ) { dps[i] = Dot( values[i], axis ); order[i] = ( u8 )i; } // stable sort using them for( int i = 0; i < count; ++i ) { for( int j = i; j > 0 && dps[j] < dps[j - 1]; --j ) { std::swap( dps[j], dps[j - 1] ); std::swap( order[j], order[j - 1] ); } } // check this ordering is unique for( int it = 0; it < iteration; ++it ) { u8 const* prev = ( u8* )m_order + 16*it; bool same = true; for( int i = 0; i < count; ++i ) { if( order[i] != prev[i] ) { same = false; break; } } if( same ) return false; } // copy the ordering and weight all the points Vec3 const* unweighted = m_colours->GetPoints(); float const* weights = m_colours->GetWeights(); m_xsum_wsum = VEC4_CONST( 0.0f ); for( int i = 0; i < count; ++i ) { int j = order[i]; Vec4 p( unweighted[j].X(), unweighted[j].Y(), unweighted[j].Z(), 1.0f ); Vec4 w( weights[j] ); Vec4 x = p*w; m_points_weights[i] = x; m_xsum_wsum += x; } return true; } void ClusterFit::Compress3( void* block ) { // declare variables int const count = m_colours->GetCount(); Vec4 const two = VEC4_CONST( 2.0 ); Vec4 const one = VEC4_CONST( 1.0f ); Vec4 const half_half2( 0.5f, 0.5f, 0.5f, 0.25f ); Vec4 const zero = VEC4_CONST( 0.0f ); Vec4 const half = VEC4_CONST( 0.5f ); Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f ); // prepare an ordering using the principle axis ConstructOrdering( m_principle, 0 ); // check all possible clusters and iterate on the total order Vec4 beststart = VEC4_CONST( 0.0f ); Vec4 bestend = VEC4_CONST( 0.0f ); Vec4 besterror = m_besterror; u8 bestindices[16]; int bestiteration = 0; int besti = 0, bestj = 0; // loop over iterations (we avoid the case that all points in first or last cluster) for( int iterationIndex = 0;; ) { // first cluster [0,i) is at the start Vec4 part0 = VEC4_CONST( 0.0f ); for( int i = 0; i < count; ++i ) { // second cluster [i,j) is half along Vec4 part1 = ( i == 0 ) ? m_points_weights[0] : VEC4_CONST( 0.0f ); int jmin = ( i == 0 ) ? 1 : i; for( int j = jmin;; ) { // last cluster [j,count) is at the end Vec4 part2 = m_xsum_wsum - part1 - part0; // compute least squares terms directly Vec4 alphax_sum = MultiplyAdd( part1, half_half2, part0 ); Vec4 alpha2_sum = alphax_sum.SplatW(); Vec4 betax_sum = MultiplyAdd( part1, half_half2, part2 ); Vec4 beta2_sum = betax_sum.SplatW(); Vec4 alphabeta_sum = ( part1*half_half2 ).SplatW(); // compute the least-squares optimal points Vec4 factor = Reciprocal( NegativeMultiplySubtract( alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum ) ); Vec4 a = NegativeMultiplySubtract( betax_sum, alphabeta_sum, alphax_sum*beta2_sum )*factor; Vec4 b = NegativeMultiplySubtract( alphax_sum, alphabeta_sum, betax_sum*alpha2_sum )*factor; // clamp to the grid a = Min( one, Max( zero, a ) ); b = Min( one, Max( zero, b ) ); a = Truncate( MultiplyAdd( grid, a, half ) )*gridrcp; b = Truncate( MultiplyAdd( grid, b, half ) )*gridrcp; // compute the error (we skip the constant xxsum) Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum ); Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 ); Vec4 e4 = MultiplyAdd( two, e3, e1 ); // apply the metric to the error term Vec4 e5 = e4*m_metric; Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ(); // keep the solution if it wins if( CompareAnyLessThan( error, besterror ) ) { beststart = a; bestend = b; besti = i; bestj = j; besterror = error; bestiteration = iterationIndex; } // advance if( j == count ) break; part1 += m_points_weights[j]; ++j; } // advance part0 += m_points_weights[i]; } // stop if we didn't improve in this iteration if( bestiteration != iterationIndex ) break; // advance if possible ++iterationIndex; if( iterationIndex == m_iterationCount ) break; // stop if a new iteration is an ordering that has already been tried Vec3 axis = ( bestend - beststart ).GetVec3(); if( !ConstructOrdering( axis, iterationIndex ) ) break; } // save the block if necessary if( CompareAnyLessThan( besterror, m_besterror ) ) { // remap the indices u8 const* order = ( u8* )m_order + 16*bestiteration; u8 unordered[16]; for( int m = 0; m < besti; ++m ) unordered[order[m]] = 0; for( int m = besti; m < bestj; ++m ) unordered[order[m]] = 2; for( int m = bestj; m < count; ++m ) unordered[order[m]] = 1; m_colours->RemapIndices( unordered, bestindices ); // save the block WriteColourBlock3( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); // save the error m_besterror = besterror; } } void ClusterFit::Compress4( void* block ) { // declare variables int const count = m_colours->GetCount(); Vec4 const two = VEC4_CONST( 2.0f ); Vec4 const one = VEC4_CONST( 1.0f ); Vec4 const onethird_onethird2( 1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 1.0f/9.0f ); Vec4 const twothirds_twothirds2( 2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f, 4.0f/9.0f ); Vec4 const twonineths = VEC4_CONST( 2.0f/9.0f ); Vec4 const zero = VEC4_CONST( 0.0f ); Vec4 const half = VEC4_CONST( 0.5f ); Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f ); // prepare an ordering using the principle axis ConstructOrdering( m_principle, 0 ); // check all possible clusters and iterate on the total order Vec4 beststart = VEC4_CONST( 0.0f ); Vec4 bestend = VEC4_CONST( 0.0f ); Vec4 besterror = m_besterror; u8 bestindices[16]; int bestiteration = 0; int besti = 0, bestj = 0, bestk = 0; // loop over iterations (we avoid the case that all points in first or last cluster) for( int iterationIndex = 0;; ) { // first cluster [0,i) is at the start Vec4 part0 = VEC4_CONST( 0.0f ); for( int i = 0; i < count; ++i ) { // second cluster [i,j) is one third along Vec4 part1 = VEC4_CONST( 0.0f ); for( int j = i;; ) { // third cluster [j,k) is two thirds along Vec4 part2 = ( j == 0 ) ? m_points_weights[0] : VEC4_CONST( 0.0f ); int kmin = ( j == 0 ) ? 1 : j; for( int k = kmin;; ) { // last cluster [k,count) is at the end Vec4 part3 = m_xsum_wsum - part2 - part1 - part0; // compute least squares terms directly Vec4 const alphax_sum = MultiplyAdd( part2, onethird_onethird2, MultiplyAdd( part1, twothirds_twothirds2, part0 ) ); Vec4 const alpha2_sum = alphax_sum.SplatW(); Vec4 const betax_sum = MultiplyAdd( part1, onethird_onethird2, MultiplyAdd( part2, twothirds_twothirds2, part3 ) ); Vec4 const beta2_sum = betax_sum.SplatW(); Vec4 const alphabeta_sum = twonineths*( part1 + part2 ).SplatW(); // compute the least-squares optimal points Vec4 factor = Reciprocal( NegativeMultiplySubtract( alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum ) ); Vec4 a = NegativeMultiplySubtract( betax_sum, alphabeta_sum, alphax_sum*beta2_sum )*factor; Vec4 b = NegativeMultiplySubtract( alphax_sum, alphabeta_sum, betax_sum*alpha2_sum )*factor; // clamp to the grid a = Min( one, Max( zero, a ) ); b = Min( one, Max( zero, b ) ); a = Truncate( MultiplyAdd( grid, a, half ) )*gridrcp; b = Truncate( MultiplyAdd( grid, b, half ) )*gridrcp; // compute the error (we skip the constant xxsum) Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum ); Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 ); Vec4 e4 = MultiplyAdd( two, e3, e1 ); // apply the metric to the error term Vec4 e5 = e4*m_metric; Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ(); // keep the solution if it wins if( CompareAnyLessThan( error, besterror ) ) { beststart = a; bestend = b; besterror = error; besti = i; bestj = j; bestk = k; bestiteration = iterationIndex; } // advance if( k == count ) break; part2 += m_points_weights[k]; ++k; } // advance if( j == count ) break; part1 += m_points_weights[j]; ++j; } // advance part0 += m_points_weights[i]; } // stop if we didn't improve in this iteration if( bestiteration != iterationIndex ) break; // advance if possible ++iterationIndex; if( iterationIndex == m_iterationCount ) break; // stop if a new iteration is an ordering that has already been tried Vec3 axis = ( bestend - beststart ).GetVec3(); if( !ConstructOrdering( axis, iterationIndex ) ) break; } // save the block if necessary if( CompareAnyLessThan( besterror, m_besterror ) ) { // remap the indices u8 const* order = ( u8* )m_order + 16*bestiteration; u8 unordered[16]; for( int m = 0; m < besti; ++m ) unordered[order[m]] = 0; for( int m = besti; m < bestj; ++m ) unordered[order[m]] = 2; for( int m = bestj; m < bestk; ++m ) unordered[order[m]] = 3; for( int m = bestk; m < count; ++m ) unordered[order[m]] = 1; m_colours->RemapIndices( unordered, bestindices ); // save the block WriteColourBlock4( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); // save the error m_besterror = besterror; } } } // namespace squish openimageio-1.3.12~dfsg0.orig/src/dds.imageio/ddsoutput.cpp0000644000175000017500000001015112271062644022030 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "dds_pvt.h" #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace DDS_pvt; class DDSOutput : public ImageOutput { public: DDSOutput (); virtual ~DDSOutput (); virtual const char * format_name (void) const { return "dds"; } virtual bool supports (const std::string &feature) const { // Support nothing nonstandard return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle std::vector m_scratch; // Initialize private members to pre-opened state void init (void) { m_file = NULL; } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *dds_output_imageio_create () { return new DDSOutput; } // OIIO_EXPORT int dds_imageio_version = OIIO_PLUGIN_VERSION; // it's in tgainput.cpp OIIO_EXPORT const char * dds_output_extensions[] = { "dds", NULL }; OIIO_PLUGIN_EXPORTS_END DDSOutput::DDSOutput () { init (); } DDSOutput::~DDSOutput () { // Close, if not already done. close (); } bool DDSOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } close (); // Close any already-opened file m_spec = userspec; // Stash the spec m_file = Filesystem::fopen (name, "wb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } error ("DDS writing is not supported yet, please poke Leszek in the " "mailing list"); return false; } bool DDSOutput::close () { if (m_file) { // close the stream fclose (m_file); m_file = NULL; } init (); // re-initialize return true; // How can we fail? // Epicly. -- IneQuation } bool DDSOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/dds.imageio/CMakeLists.txt0000644000175000017500000000043212271062644022032 0ustar mfvmfvadd_oiio_plugin (ddsinput.cpp ddsoutput.cpp squish/alpha.cpp squish/clusterfit.cpp squish/colourblock.cpp squish/colourfit.cpp squish/colourset.cpp squish/maths.cpp squish/rangefit.cpp squish/singlecolourfit.cpp squish/squish.cpp) openimageio-1.3.12~dfsg0.orig/src/softimage.imageio/0000755000175000017500000000000012271062644020477 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/softimage.imageio/softimage_pvt.h0000644000175000017500000000652612271062644023530 0ustar mfvmfv/* OpenImageIO and all code, documentation, and other materials contained therein are: Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_SOFTIMAGE_H #define OPENIMAGEIO_SOFTIMAGE_H #include #include #include #include "filesystem.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace softimage_pvt { class PicFileHeader { public: // Read pic header from file bool read_header (FILE *fd); // PIC header uint32_t magic; // Softimage magic number float version; // Storage format - 1 is RLE, 0 is RAW char comment[80]; // Comment char id[4]; // ID - should be PICT uint16_t width; // X size in pixels uint16_t height; // Y size in pixels float ratio; // Pixel aspect ratio uint16_t fields; // The scanline setting - No Pictures, Odd, Even or every uint16_t pad; // unused private: void swap_endian(); }; // class PicFileHeader class ChannelPacket { public: //channel packet contains info on the image data ChannelPacket() { chained = 0; } // !brief get a list of the channels contained in this channel packet std::vector channels() const; uint8_t chained; //0 if this is the last channel packet uint8_t size; //Number of bits per pixel per channel uint8_t type; //Data encoding and type uint8_t channelCode; //bitset for channels }; // class ChannelPacket enum channelCodes { RED_CHANNEL = 0x80, GREEN_CHANNEL = 0x40, BLUE_CHANNEL = 0x20, ALPHA_CHANNEL = 0x10 }; // enum channelCodes enum encoding { UNCOMPRESSED, PURE_RUN_LENGTH, MIXED_RUN_LENGTH }; // enum encoding } //namespace softimage_pvt OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_PIC_H openimageio-1.3.12~dfsg0.orig/src/softimage.imageio/softimage_pvt.cpp0000644000175000017500000000562212271062644024057 0ustar mfvmfv/* OpenImageIO and all code, documentation, and other materials contained therein are: Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "softimage_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int softimage_imageio_version = OIIO_PLUGIN_VERSION; OIIO_PLUGIN_EXPORTS_END namespace softimage_pvt { void PicFileHeader::swap_endian() { OIIO::swap_endian (&magic); OIIO::swap_endian (&width); OIIO::swap_endian (&height); OIIO::swap_endian (&version); OIIO::swap_endian (&ratio); OIIO::swap_endian (&fields); } bool PicFileHeader::read_header (FILE* fd) { int byte_count = 0; byte_count += fread (this, 1, sizeof (PicFileHeader), fd); // Check if we're running on a little endian processor if (littleendian ()) swap_endian(); return (byte_count == sizeof (PicFileHeader)); } std::vector ChannelPacket::channels () const { std::vector chanMap; // Check for the channels and add them to the chanMap if (channelCode & RED_CHANNEL) chanMap.push_back (0); if (channelCode & GREEN_CHANNEL) chanMap.push_back (1); if (channelCode & BLUE_CHANNEL) chanMap.push_back (2); if (channelCode & ALPHA_CHANNEL) chanMap.push_back (3); return chanMap; } } // namespace softimage_pvt OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/softimage.imageio/softimageoutput.cpp0000644000175000017500000000402512271062644024443 0ustar mfvmfv/* OpenImageIO and all code, documentation, and other materials contained therein are: Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "softimage_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace softimage_pvt; // symbols required for OpenImageIO plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *softimage_output_imageio_create() { return NULL; // new SoftimageOutput; } OIIO_EXPORT const char *softimage_output_extensions[] = { "pic", NULL }; OIIO_PLUGIN_EXPORTS_END OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/softimage.imageio/softimageinput.cpp0000644000175000017500000004343512271062644024252 0ustar mfvmfv/* OpenImageIO and all code, documentation, and other materials contained therein are: Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "softimage_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace softimage_pvt; class SoftimageInput : public ImageInput { public: SoftimageInput() { init(); } virtual ~SoftimageInput() { close(); } virtual const char *format_name (void) const { return "softimage"; } virtual bool open (const std::string &name, ImageSpec &spec); virtual bool close(); virtual bool read_native_scanline (int y, int z, void *data); private: /// Resets the core data members to defaults. /// void init (); /// Read a scanline from m_fd. /// bool read_next_scanline (void * data); /// Read uncompressed pixel data from m_fd. /// bool read_pixels_uncompressed (const softimage_pvt::ChannelPacket & curPacket, void * data); /// Read pure run length encoded pixels. /// bool read_pixels_pure_run_length (const softimage_pvt::ChannelPacket & curPacket, void * data); /// Read mixed run length encoded pixels. /// bool read_pixels_mixed_run_length (const softimage_pvt::ChannelPacket & curPacket, void * data); FILE *m_fd; softimage_pvt::PicFileHeader m_pic_header; std::vector m_channel_packets; std::string m_filename; std::vector m_scanline_markers; }; // symbols required for OpenImageIO plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *softimage_input_imageio_create() { return new SoftimageInput; } OIIO_EXPORT const char *softimage_input_extensions[] = { "pic", NULL }; OIIO_PLUGIN_EXPORTS_END void SoftimageInput::init () { m_fd = NULL; m_filename.clear(); m_channel_packets.clear(); m_scanline_markers.clear(); } bool SoftimageInput::open (const std::string& name, ImageSpec& spec) { // Remember the filename m_filename = name; m_fd = Filesystem::fopen (m_filename, "rb"); if (!m_fd) { error ("Could not open file \"%s\"", name.c_str()); return false; } // Try read the header if (! m_pic_header.read_header (m_fd)) { error ("\"%s\": failed to read header", m_filename.c_str()); close(); return false; } // Check whether it has the pic magic number if (m_pic_header.magic != 0x5380f634) { error ("\"%s\" is not a Softimage Pic file, magic number of 0x%X is not Pic", m_filename.c_str(), m_pic_header.magic); close(); return false; } // Get the ChannelPackets ChannelPacket curPacket; int nchannels = 0; do { // Read the next packet into curPacket and store it off if (fread (&curPacket, 1, sizeof (ChannelPacket), m_fd) != sizeof (ChannelPacket)) { error ("Unexpected end of file \"%s\".", m_filename.c_str()); close(); return false; } m_channel_packets.push_back (curPacket); // Add the number of channels in this packet to nchannels nchannels += curPacket.channels().size(); } while (curPacket.chained); // Get the depth per pixel per channel TypeDesc chanType = TypeDesc::UINT8; if (curPacket.size == 16) chanType = TypeDesc::UINT16; // Set the details in the ImageSpec m_spec = ImageSpec (m_pic_header.width, m_pic_header.height, nchannels, chanType); m_spec.attribute ("BitsPerSample", (int)curPacket.size); if (m_pic_header.comment[0] != 0) { char comment[81]; strncpy (comment, m_pic_header.comment, 80); comment[80] = 0; m_spec.attribute ("ImageDescription", comment); } // Build the scanline index fpos_t curPos; fgetpos (m_fd, &curPos); m_scanline_markers.push_back(curPos); spec = m_spec; return true; } bool SoftimageInput::read_native_scanline (int y, int z, void* data) { bool result = false; if (y == (int)m_scanline_markers.size() - 1) { // we're up to this scanline result = read_next_scanline(data); // save the marker for the next scanline if we haven't got the who images if (m_scanline_markers.size() < m_pic_header.height) { fpos_t curPos; fgetpos(m_fd, &curPos); m_scanline_markers.push_back(curPos); } } else if (y >= (int)m_scanline_markers.size()) { // we haven't yet read this far fpos_t curPos; // Store the ones before this without pulling the pixels do { if (!read_next_scanline(NULL)) return false; fgetpos(m_fd, &curPos); m_scanline_markers.push_back(curPos); } while ((int)m_scanline_markers.size() <= y); result = read_next_scanline(data); fgetpos(m_fd, &curPos); m_scanline_markers.push_back(curPos); } else { // We've already got the index for this scanline and moved past // Let's seek to the scanline's data if (fsetpos (m_fd, &m_scanline_markers[y])) { error ("Failed to seek to scanline %d in \"%s\"", y, m_filename.c_str()); close(); return false; } result = read_next_scanline(data); // If the index isn't complete let's shift the file pointer back to the latest readline if (m_scanline_markers.size() < m_pic_header.height) { if (fsetpos (m_fd, &m_scanline_markers[m_scanline_markers.size() - 1])) { error ("Failed to restore to scanline %llu in \"%s\"", (long long unsigned int)m_scanline_markers.size() - 1, m_filename.c_str()); close(); return false; } } } return result; } bool SoftimageInput::close() { if (m_fd) { fclose (m_fd); m_fd = NULL; } init (); return true; } inline bool SoftimageInput::read_next_scanline (void * data) { // Each scanline is stored using one or more channel packets. // We go through each of those to pull the data for (size_t i = 0; i < m_channel_packets.size(); i++) { if (m_channel_packets[i].type & UNCOMPRESSED) { if (!read_pixels_uncompressed (m_channel_packets[i], data)) { error ("Failed to read uncompressed pixel data from \"%s\"", m_filename.c_str()); close(); return false; } } else if (m_channel_packets[i].type & PURE_RUN_LENGTH) { if (!read_pixels_pure_run_length (m_channel_packets[i], data)) { error ("Failed to read pure run length encoded pixel data from \"%s\"", m_filename.c_str()); close(); return false; } } else if (m_channel_packets[i].type & MIXED_RUN_LENGTH) { if (!read_pixels_mixed_run_length (m_channel_packets[i], data)) { error ("Failed to read mixed run length encoded pixel data from \"%s\"", m_filename.c_str()); close(); return false; } } } return true; } inline bool SoftimageInput::read_pixels_uncompressed (const softimage_pvt::ChannelPacket & curPacket, void * data) { // We're going to need to use the channels more than once std::vector channels = curPacket.channels(); // We'll need to use the pixelChannelSize a bit size_t pixelChannelSize = curPacket.size / 8; if (data) { // data pointer is set so we're supposed to write data there uint8_t * scanlineData = (uint8_t *)data; for (size_t pixelX=0; pixelX < m_pic_header.width; pixelX++) { for (size_t curChan=0; curChan < channels.size(); curChan++) { for (size_t byte=0; byte < pixelChannelSize; byte++) { // Get which byte we should be placing this in depending on endianness size_t curByte = byte; if (littleendian()) curByte = ((pixelChannelSize) - 1) - curByte; //read the data into the correct place if (fread (&scanlineData[(pixelX * pixelChannelSize * m_spec.nchannels) + (channels[curChan] * pixelChannelSize) + curByte], 1, 1, m_fd) != 1) return false; } } } } else { // data pointer is null so we should just seek to the next scanline // If the seek fails return false if (fseek (m_fd, m_pic_header.width * pixelChannelSize * channels.size(), SEEK_CUR)) return false; } return true; } inline bool SoftimageInput::read_pixels_pure_run_length (const softimage_pvt::ChannelPacket & curPacket, void * data) { // How many pixels we've read so far this line size_t linePixelCount = 0; // Number of repeats of this value uint8_t curCount = 0; // We'll need to use the pixelChannelSize a bit size_t pixelChannelSize = curPacket.size / 8; // We're going to need to use the channels more than once std::vector channels = curPacket.channels(); // Read the pixels until we've read them all while (linePixelCount < m_pic_header.width) { // Read the repeats for the run length - return false if read fails if (fread (&curCount, 1, 1, m_fd) != 1) return false; if (data) { // data pointer is set so we're supposed to write data there size_t pixelSize = pixelChannelSize * channels.size(); uint8_t * pixelData = new uint8_t[pixelSize]; if (fread (pixelData, pixelSize, 1, m_fd) != pixelSize) return false; // Now we've got the pixel value we need to push it into the data uint8_t * scanlineData = (uint8_t *)data; for (size_t pixelX=linePixelCount; pixelX < linePixelCount+curCount; pixelX++) { for (size_t curChan=0; curChan < channels.size(); curChan++) { for (size_t byte=0; byte < pixelChannelSize; byte++) { // Get which byte we should be placing this in depending on endianness size_t curByte = byte; if (littleendian()) curByte = ((pixelChannelSize) - 1) - curByte; //put the data into the correct place scanlineData[(pixelX * pixelChannelSize * m_spec.nchannels) + (channels[curChan] * pixelChannelSize) + curByte] = pixelData[(curChan * pixelChannelSize) + curByte]; } } } delete[] pixelData; } else { // data pointer is null so we should just seek to the next scanline // If the seek fails return false if (fseek (m_fd, pixelChannelSize * channels.size(), SEEK_CUR)) return false; } // Add these pixels to the current pixel count linePixelCount += curCount; } return true; } inline bool SoftimageInput::read_pixels_mixed_run_length (const softimage_pvt::ChannelPacket & curPacket, void * data) { // How many pixels we've read so far this line size_t linePixelCount = 0; // Number of repeats of this value uint8_t curCount = 0; // We'll need to use the pixelChannelSize a bit size_t pixelChannelSize = curPacket.size / 8; // We're going to need to use the channels more than once std::vector channels = curPacket.channels(); // Read the pixels until we've read them all while (linePixelCount < m_pic_header.width) { // Read the repeats for the run length - return false if read fails if (fread (&curCount, 1, 1, m_fd) != 1) return false; if (curCount < 128) { // It's a raw packet - so this means the count is 1 less then the actual value curCount++; // Just to be safe let's make sure this wouldn't take us // past the end of this scanline if (curCount + linePixelCount > m_pic_header.width) curCount = m_pic_header.width - linePixelCount; if (data) { // data pointer is set so we're supposed to write data there uint8_t * scanlineData = (uint8_t *)data; for (size_t pixelX=linePixelCount; pixelX < linePixelCount+curCount; pixelX++) { for (size_t curChan=0; curChan < channels.size(); curChan++) { for (size_t byte=0; byte < pixelChannelSize; byte++) { // Get which byte we should be placing this in depending on endianness size_t curByte = byte; if (littleendian()) curByte = ((pixelChannelSize) - 1) - curByte; //read the data into the correct place if (fread (&scanlineData[(pixelX * pixelChannelSize * m_spec.nchannels) + (channels[curChan] * pixelChannelSize) + curByte], 1, 1, m_fd) != 1) return false; } } } } else { // data pointer is null so we should just seek to the // next scanline If the seek fails return false. if (fseek (m_fd, curCount * pixelChannelSize * channels.size(), SEEK_CUR)) return false; } // Add these pixels to the current pixel count linePixelCount += curCount; } else { // It's a run length encoded packet uint16_t longCount = 0; if (curCount == 128) { // This is a long count so the next 16bits of the file // are an unsigned int containing the count. If the // read fails we should return false. if (fread (&longCount, 1, 2, m_fd) != 2) return false; // longCount is in big endian format - if we're not // let's swap it if (littleendian()) OIIO::swap_endian (&longCount); } else { longCount = curCount - 127; } if (data) { // data pointer is set so we're supposed to write data there size_t pixelSize = pixelChannelSize * channels.size(); uint8_t * pixelData = new uint8_t[pixelSize]; if (fread (pixelData, 1, pixelSize, m_fd) != pixelSize) return false; // Now we've got the pixel value we need to push it into // the data. uint8_t * scanlineData = (uint8_t *)data; for (size_t pixelX=linePixelCount; pixelX < linePixelCount+longCount; pixelX++) { for (size_t curChan=0; curChan < channels.size(); curChan++) { for (size_t byte=0; byte < pixelChannelSize; byte++) { // Get which byte we should be placing this // in depending on endianness. size_t curByte = byte; if (littleendian()) curByte = ((pixelChannelSize) - 1) - curByte; //put the data into the correct place scanlineData[(pixelX * pixelChannelSize * m_spec.nchannels) + (channels[curChan] * pixelChannelSize) + curByte] = pixelData[(curChan * pixelChannelSize) + curByte]; } } } delete[] pixelData; } else { // data pointer is null so we should just seek to the // next scanline. If the seek fails return false. if (fseek (m_fd, pixelChannelSize * channels.size(), SEEK_CUR)) return false; } // Add these pixels to the current pixel count. linePixelCount += longCount; } } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/softimage.imageio/CMakeLists.txt0000644000175000017500000000011312271062644023232 0ustar mfvmfvadd_oiio_plugin (softimageinput.cpp softimageoutput.cpp softimage_pvt.cpp) openimageio-1.3.12~dfsg0.orig/src/hdr.imageio/0000755000175000017500000000000012271062644017276 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/hdr.imageio/hdrinput.cpp0000644000175000017500000001426312271062644021645 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "imageio.h" #include "filesystem.h" #include "fmath.h" #include "rgbe.h" OIIO_PLUGIN_NAMESPACE_BEGIN ///////////////////////////////////////////////////////////////////////////// // .hdr / .rgbe files - HDR files from Radiance // // General info on the hdr/rgbe format can be found at: // http://local.wasp.uwa.edu.au/~pbourke/dataformats/pic/ // The source code in rgbe.{h,cpp} originally came from: // http://www.graphics.cornell.edu/~bjw/rgbe.html // But it's been modified in several minor ways by LG. // Also see Greg Ward's "Real Pixels" chapter in Graphics Gems II for an // explanation of the encoding that's used in Radiance rgba files. ///////////////////////////////////////////////////////////////////////////// class HdrInput : public ImageInput { public: HdrInput () { init(); } virtual ~HdrInput () { close(); } virtual const char * format_name (void) const { return "hdr"; } virtual bool open (const std::string &name, ImageSpec &spec); virtual bool read_native_scanline (int y, int z, void *data); virtual bool close (); virtual int current_subimage (void) const { return m_subimage; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); private: std::string m_filename; ///< File name FILE *m_fd; ///< The open file handle int m_subimage; ///< What subimage are we looking at? int m_next_scanline; ///< Next scanline to read char rgbe_error[1024]; ///< Buffer for RGBE library error msgs void init () { m_fd = NULL; m_subimage = -1; m_next_scanline = 0; } }; // Export version number and create function symbols OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int hdr_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *hdr_input_imageio_create () { return new HdrInput; } OIIO_EXPORT const char *hdr_input_extensions[] = { "hdr", "rgbe", NULL }; OIIO_PLUGIN_EXPORTS_END bool HdrInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; return seek_subimage (0, 0, newspec); } bool HdrInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { // HDR doesn't support multiple subimages or mipmaps if (subimage != 0 || miplevel != 0) return false; // Skip the hard work if we're already on the requested subimage if (subimage == current_subimage()) { newspec = spec(); return true; } close(); // Check that file exists and can be opened m_fd = Filesystem::fopen (m_filename, "rb"); if (m_fd == NULL) { error ("Could not open file \"%s\"", m_filename.c_str()); return false; } rgbe_header_info h; int width, height; int r = RGBE_ReadHeader (m_fd, &width, &height, &h, rgbe_error); if (r != RGBE_RETURN_SUCCESS) { error ("%s", rgbe_error); close (); return false; } m_spec = ImageSpec (width, height, 3, TypeDesc::FLOAT); if (h.valid & RGBE_VALID_GAMMA) m_spec.attribute ("oiio:Gamma", h.gamma); if (h.valid & RGBE_VALID_ORIENTATION) m_spec.attribute ("Orientation", h.orientation); // FIXME -- should we do anything about exposure, software, // pixaspect, primaries? (N.B. rgbe.c doesn't even handle most of them) m_subimage = subimage; m_next_scanline = 0; newspec = m_spec; return true; } bool HdrInput::read_native_scanline (int y, int z, void *data) { if (m_next_scanline > y) { // User is trying to read an earlier scanline than the one we're // up to. Easy fix: close the file and re-open. ImageSpec dummyspec; int subimage = current_subimage(); int miplevel = current_miplevel(); if (! close () || ! open (m_filename, dummyspec) || ! seek_subimage (subimage, miplevel, dummyspec)) return false; // Somehow, the re-open failed assert (m_next_scanline == 0 && current_subimage() == subimage && current_miplevel() == miplevel); } while (m_next_scanline <= y) { // Keep reading until we're read the scanline we really need int r = RGBE_ReadPixels_RLE (m_fd, (float *)data, m_spec.width, 1, rgbe_error); ++m_next_scanline; if (r != RGBE_RETURN_SUCCESS) { error ("%s", rgbe_error); return false; } } return true; } bool HdrInput::close () { if (m_fd) fclose (m_fd); init (); // Reset to initial state return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/hdr.imageio/rgbe.cpp0000644000175000017500000004030612271062644020724 0ustar mfvmfv/* THIS CODE CARRIES NO GUARANTEE OF USABILITY OR FITNESS FOR ANY PURPOSE. * WHILE THE AUTHORS HAVE TRIED TO ENSURE THE PROGRAM WORKS CORRECTLY, * IT IS STRICTLY USE AT YOUR OWN RISK. */ #include "rgbe.h" #include #include #include #include /* This file contains code to read and write four byte rgbe file format developed by Greg Ward. It handles the conversions between rgbe and pixels consisting of floats. The data is assumed to be an array of floats. By default there are three floats per pixel in the order red, green, blue. (RGBE_DATA_??? values control this.) Only the mimimal header reading and writing is implemented. Each routine does error checking and will return a status value as defined below. This code is intended as a skeleton so feel free to modify it to suit your needs. (Place notice here if you modified the code.) posted to http://www.graphics.cornell.edu/~bjw/ written by Bruce Walter (bjw@graphics.cornell.edu) 5/26/95 based on code written by Greg Ward Various modifications by Larry Gritz (lg@larrygritz.com), July 1998: 1. Fix RGBE_ReadHeader to handle changes in the order of header fields that can be found in some .hdr files on the net. 2. Correctly read and write images of all 8 orientations (not just -Y+X) and specify the orientation in the rgbe_header_info structure. 3. Change the default programtype string from "RGBE" to "RADIANCE" since I noticed that some hdr/rgbe readers (including OS X's preivew util) will only accept "RADIANCE" as the programtype. */ #if defined(_CPLUSPLUS) || defined(__cplusplus) /* define if your compiler understands inline commands */ #define INLINE inline #else #define INLINE #endif /* offsets to red, green, and blue components in a data (float) pixel */ #define RGBE_DATA_RED 0 #define RGBE_DATA_GREEN 1 #define RGBE_DATA_BLUE 2 /* number of floats per pixel */ #define RGBE_DATA_SIZE 3 OIIO_PLUGIN_NAMESPACE_BEGIN enum rgbe_error_codes { rgbe_read_error, rgbe_write_error, rgbe_format_error, rgbe_memory_error, }; /* default error routine. change this to change error handling */ static int rgbe_error(int rgbe_error_code, const char *msg, char *errbuf) { switch (rgbe_error_code) { case rgbe_read_error: if (errbuf) strcpy (errbuf, "RGBE read error"); else perror("RGBE read error"); break; case rgbe_write_error: if (errbuf) strcpy (errbuf, "RGBE write error"); else perror("RGBE write error"); break; case rgbe_format_error: if (errbuf) sprintf(errbuf,"RGBE bad file format: %s\n", msg); else fprintf(stderr,"RGBE bad file format: %s\n",msg); break; default: case rgbe_memory_error: if (errbuf) sprintf(errbuf,"RGBE error: %s\n",msg); else fprintf(stderr,"RGBE error: %s\n",msg); break; } return RGBE_RETURN_FAILURE; } /* standard conversion from float pixels to rgbe pixels */ /* note: you can remove the "inline"s if your compiler complains about it */ static INLINE void float2rgbe(unsigned char rgbe[4], float red, float green, float blue) { float v; int e; v = red; if (green > v) v = green; if (blue > v) v = blue; if (v < 1e-32) { rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; } else { v = frexpf(v,&e) * 256.0f/v; rgbe[0] = (unsigned char) (red * v); rgbe[1] = (unsigned char) (green * v); rgbe[2] = (unsigned char) (blue * v); rgbe[3] = (unsigned char) (e + 128); } } /* standard conversion from rgbe to float pixels */ /* note: Ward uses ldexp(col+0.5,exp-(128+8)). However we wanted pixels */ /* in the range [0,1] to map back into the range [0,1]. */ static INLINE void rgbe2float(float *red, float *green, float *blue, unsigned char rgbe[4]) { float f; if (rgbe[3]) { /*nonzero pixel*/ f = ldexpf(1.0f,rgbe[3]-(int)(128+8)); *red = rgbe[0] * f; *green = rgbe[1] * f; *blue = rgbe[2] * f; } else *red = *green = *blue = 0.0; } /* default minimal header. modify if you want more information in header */ int RGBE_WriteHeader(FILE *fp, int width, int height, rgbe_header_info *info, char *errbuf) { const char *programtype = "RADIANCE"; /* N.B. from Larry Gritz: * Plenty of readers will refuse to read .rgbe/.hdr files if their * program type is not "RADIANCE". So I changed the default * programtype from Bruce Walter's original "RGBE", which many readers * refuse to accept. (Mac OS X's "preview" utility is one such reader!) */ if (info && (info->valid & RGBE_VALID_PROGRAMTYPE)) programtype = info->programtype; if (fprintf(fp,"#?%s\n",programtype) < 0) return rgbe_error(rgbe_write_error,NULL, errbuf); /* The #? is to identify file type, the programtype is optional. */ if (info && (info->valid & RGBE_VALID_GAMMA)) { if (fprintf(fp,"GAMMA=%g\n",info->gamma) < 0) return rgbe_error(rgbe_write_error,NULL, errbuf); } if (info && (info->valid & RGBE_VALID_EXPOSURE)) { if (fprintf(fp,"EXPOSURE=%g\n",info->exposure) < 0) return rgbe_error(rgbe_write_error,NULL, errbuf); } if (fprintf(fp,"FORMAT=32-bit_rle_rgbe\n\n") < 0) return rgbe_error(rgbe_write_error,NULL, errbuf); if (fprintf(fp, "-Y %d +X %d\n", height, width) < 0) return rgbe_error(rgbe_write_error,NULL, errbuf); return RGBE_RETURN_SUCCESS; } /* minimal header reading. modify if you want to parse more information */ int RGBE_ReadHeader(FILE *fp, int *width, int *height, rgbe_header_info *info, char *errbuf) { char buf[128]; float tempf; size_t i; if (info) { info->valid = 0; info->programtype[0] = 0; info->gamma = info->exposure = 1.0; } if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == NULL) return rgbe_error(rgbe_read_error,NULL, errbuf); if ((buf[0] != '#')||(buf[1] != '?')) { /* if you want to require the magic token then uncomment the next line */ /*return rgbe_error(rgbe_format_error,"bad initial token"); */ } else if (info) { info->valid |= RGBE_VALID_PROGRAMTYPE; for(i=0;i<(int)sizeof(info->programtype)-1;i++) { if ((buf[i+2] == 0) || isspace(buf[i+2])) break; info->programtype[i] = buf[i+2]; } info->programtype[i] = 0; if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0) return rgbe_error(rgbe_read_error,NULL, errbuf); } bool found_FORMAT_line = false; for(;;) { if ((buf[0] == 0)||(buf[0] == '\n')) { if (found_FORMAT_line) break; return rgbe_error(rgbe_format_error,"no FORMAT specifier found", errbuf); } else if (strcmp(buf,"FORMAT=32-bit_rle_rgbe\n") == 0) { found_FORMAT_line = true; /* LG says no: break; // format found so break out of loop */ } else if (info && (sscanf(buf,"GAMMA=%g",&tempf) == 1)) { info->gamma = tempf; info->valid |= RGBE_VALID_GAMMA; } else if (info && (sscanf(buf,"EXPOSURE=%g",&tempf) == 1)) { info->exposure = tempf; info->valid |= RGBE_VALID_EXPOSURE; } if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0) return rgbe_error(rgbe_read_error,NULL, errbuf); } if (strcmp(buf,"\n") != 0) { printf ("Found '%s'\n", buf); return rgbe_error(rgbe_format_error, "missing blank line after FORMAT specifier", errbuf); } if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0) return rgbe_error(rgbe_read_error,NULL, errbuf); if (sscanf(buf,"-Y %d +X %d",height,width) == 2) { if (info) { info->orientation = 1; info->valid |= RGBE_VALID_ORIENTATION; } } else if (sscanf(buf,"-Y %d -X %d",height,width) == 2) { if (info) { info->orientation = 2; info->valid |= RGBE_VALID_ORIENTATION; } } else if (sscanf(buf,"+Y %d -X %d",height,width) == 2) { if (info) { info->orientation = 3; info->valid |= RGBE_VALID_ORIENTATION; } } else if (sscanf(buf,"+Y %d +X %d",height,width) == 2) { if (info) { info->orientation = 4; info->valid |= RGBE_VALID_ORIENTATION; } } else if (sscanf(buf,"+X %d -Y %d",height,width) == 2) { if (info) { info->orientation = 5; info->valid |= RGBE_VALID_ORIENTATION; } } else if (sscanf(buf,"+X %d +Y %d",height,width) == 2) { if (info) { info->orientation = 6; info->valid |= RGBE_VALID_ORIENTATION; } } else if (sscanf(buf,"-X %d +Y %d",height,width) == 2) { if (info) { info->orientation = 7; info->valid |= RGBE_VALID_ORIENTATION; } } else if (sscanf(buf,"-X %d -Y %d",height,width) == 2) { if (info) { info->orientation = 8; info->valid |= RGBE_VALID_ORIENTATION; } } else { return rgbe_error(rgbe_format_error,"missing image size specifier", errbuf); } return RGBE_RETURN_SUCCESS; } /* simple write routine that does not use run length encoding */ /* These routines can be made faster by allocating a larger buffer and fread-ing and fwrite-ing the data in larger chunks */ int RGBE_WritePixels(FILE *fp, float *data, int numpixels, char *errbuf) { unsigned char rgbe[4]; while (numpixels-- > 0) { float2rgbe(rgbe,data[RGBE_DATA_RED], data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]); data += RGBE_DATA_SIZE; if (fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) return rgbe_error(rgbe_write_error,NULL, errbuf); } return RGBE_RETURN_SUCCESS; } /* simple read routine. will not correctly handle run length encoding */ int RGBE_ReadPixels(FILE *fp, float *data, int numpixels, char *errbuf) { unsigned char rgbe[4]; while(numpixels-- > 0) { if (fread(rgbe, sizeof(rgbe), 1, fp) < 1) return rgbe_error(rgbe_read_error,NULL, errbuf); rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE],rgbe); data += RGBE_DATA_SIZE; } return RGBE_RETURN_SUCCESS; } /* The code below is only needed for the run-length encoded files. */ /* Run length encoding adds considerable complexity but does */ /* save some space. For each scanline, each channel (r,g,b,e) is */ /* encoded separately for better compression. */ static int RGBE_WriteBytes_RLE(FILE *fp, unsigned char *data, int numbytes, char *errbuf) { #define MINRUNLENGTH 4 int cur, beg_run, run_count, old_run_count, nonrun_count; unsigned char buf[2]; cur = 0; while(cur < numbytes) { beg_run = cur; /* find next run of length at least 4 if one exists */ run_count = old_run_count = 0; while((run_count < MINRUNLENGTH) && (beg_run < numbytes)) { beg_run += run_count; old_run_count = run_count; run_count = 1; while((data[beg_run] == data[beg_run + run_count]) && (beg_run + run_count < numbytes) && (run_count < 127)) run_count++; } /* if data before next big run is a short run then write it as such */ if ((old_run_count > 1)&&(old_run_count == beg_run - cur)) { buf[0] = 128 + old_run_count; /*write short run*/ buf[1] = data[cur]; if (fwrite(buf,sizeof(buf[0])*2,1,fp) < 1) return rgbe_error(rgbe_write_error,NULL, errbuf); cur = beg_run; } /* write out bytes until we reach the start of the next run */ while(cur < beg_run) { nonrun_count = beg_run - cur; if (nonrun_count > 128) nonrun_count = 128; buf[0] = nonrun_count; if (fwrite(buf,sizeof(buf[0]),1,fp) < 1) return rgbe_error(rgbe_write_error,NULL, errbuf); if (fwrite(&data[cur],sizeof(data[0])*nonrun_count,1,fp) < 1) return rgbe_error(rgbe_write_error,NULL, errbuf); cur += nonrun_count; } /* write out next run if one was found */ if (run_count >= MINRUNLENGTH) { buf[0] = 128 + run_count; buf[1] = data[beg_run]; if (fwrite(buf,sizeof(buf[0])*2,1,fp) < 1) return rgbe_error(rgbe_write_error,NULL, errbuf); cur += run_count; } } return RGBE_RETURN_SUCCESS; #undef MINRUNLENGTH } int RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width, int num_scanlines, char *errbuf) { unsigned char rgbe[4]; unsigned char *buffer; int i, err; if ((scanline_width < 8)||(scanline_width > 0x7fff)) /* run length encoding is not allowed so write flat*/ return RGBE_WritePixels(fp,data,scanline_width*num_scanlines); buffer = (unsigned char *)malloc(sizeof(unsigned char)*4*scanline_width); if (buffer == NULL) /* no buffer space so write flat */ return RGBE_WritePixels(fp,data,scanline_width*num_scanlines); while(num_scanlines-- > 0) { rgbe[0] = 2; rgbe[1] = 2; rgbe[2] = scanline_width >> 8; rgbe[3] = scanline_width & 0xFF; if (fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) { free(buffer); return rgbe_error(rgbe_write_error,NULL, errbuf); } for(i=0;i 0x7fff)) /* run length encoding is not allowed so read flat*/ return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines); scanline_buffer = NULL; /* read in each successive scanline */ while(num_scanlines > 0) { if (fread(rgbe,sizeof(rgbe),1,fp) < 1) { free(scanline_buffer); return rgbe_error(rgbe_read_error,NULL, errbuf); } if ((rgbe[0] != 2)||(rgbe[1] != 2)||(rgbe[2] & 0x80)) { /* this file is not run length encoded */ rgbe2float(&data[0],&data[1],&data[2],rgbe); data += RGBE_DATA_SIZE; free(scanline_buffer); return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines-1); } if ((((int)rgbe[2])<<8 | rgbe[3]) != scanline_width) { free(scanline_buffer); return rgbe_error(rgbe_format_error,"wrong scanline width", errbuf); } if (scanline_buffer == NULL) scanline_buffer = (unsigned char *) malloc(sizeof(unsigned char)*4*scanline_width); if (scanline_buffer == NULL) return rgbe_error(rgbe_memory_error,"unable to allocate buffer space", errbuf); ptr = &scanline_buffer[0]; /* read each of the four channels for the scanline into the buffer */ for(i=0;i<4;i++) { ptr_end = &scanline_buffer[(i+1)*scanline_width]; while(ptr < ptr_end) { if (fread(buf,sizeof(buf[0])*2,1,fp) < 1) { free(scanline_buffer); return rgbe_error(rgbe_read_error,NULL, errbuf); } if (buf[0] > 128) { /* a run of the same value */ count = buf[0]-128; if ((count == 0)||(count > ptr_end - ptr)) { free(scanline_buffer); return rgbe_error(rgbe_format_error,"bad scanline data", errbuf); } while(count-- > 0) *ptr++ = buf[1]; } else { /* a non-run */ count = buf[0]; if ((count == 0)||(count > ptr_end - ptr)) { free(scanline_buffer); return rgbe_error(rgbe_format_error,"bad scanline data", errbuf); } *ptr++ = buf[1]; if (--count > 0) { if (fread(ptr,sizeof(*ptr)*count,1,fp) < 1) { free(scanline_buffer); return rgbe_error(rgbe_read_error,NULL, errbuf); } ptr += count; } } } } /* now convert data from buffer into floats */ for(i=0;i #include #include #include "imageio.h" #include "filesystem.h" #include "fmath.h" #include "strutil.h" #include "rgbe.h" OIIO_PLUGIN_NAMESPACE_BEGIN class HdrOutput : public ImageOutput { public: HdrOutput () { init(); } virtual ~HdrOutput () { close(); } virtual const char * format_name (void) const { return "hdr"; } virtual bool supports (const std::string &property) const { return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); bool close (); private: FILE *m_fd; std::vector scratch; char rgbe_error[1024]; ///< Buffer for RGBE library error msgs void init (void) { m_fd = NULL; } }; OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *hdr_output_imageio_create () { return new HdrOutput; } OIIO_EXPORT const char *hdr_output_extensions[] = { "hdr", "rgbe", NULL }; OIIO_PLUGIN_EXPORTS_END bool HdrOutput::open (const std::string &name, const ImageSpec &newspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } // Save spec for later use m_spec = newspec; // HDR always behaves like floating point m_spec.set_format (TypeDesc::FLOAT); // Check for things HDR can't support if (m_spec.nchannels != 3) { error ("HDR can only support 3-channel images"); return false; } if (m_spec.width < 1 || m_spec.height < 1) { error ("Image resolution must be at least 1x1, you asked for %d x %d", m_spec.width, m_spec.height); return false; } if (m_spec.depth < 1) m_spec.depth = 1; if (m_spec.depth > 1) { error ("%s does not support volume images (depth > 1)", format_name()); return false; } m_spec.set_format (TypeDesc::FLOAT); // Native rgbe is float32 only m_fd = Filesystem::fopen (name, "wb"); if (m_fd == NULL) { error ("Unable to open file"); return false; } rgbe_header_info h; h.valid = 0; // Most readers seem to think that rgbe files are valid only if they // identify themselves as from "RADIANCE". h.valid |= RGBE_VALID_PROGRAMTYPE; Strutil::safe_strcpy (h.programtype, "RADIANCE", sizeof(h.programtype)); ImageIOParameter *p; p = m_spec.find_attribute ("Orientation", TypeDesc::INT); if (p) { h.valid |= RGBE_VALID_ORIENTATION; h.orientation = * (int *)p->data(); } // FIXME -- should we do anything about gamma, exposure, software, // pixaspect, primaries? (N.B. rgbe.c doesn't even handle most of them) int r = RGBE_WriteHeader (m_fd, m_spec.width, m_spec.height, &h, rgbe_error); if (r != RGBE_RETURN_SUCCESS) error ("%s", rgbe_error); return true; } bool HdrOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { data = to_native_scanline (format, data, xstride, scratch); int r = RGBE_WritePixels_RLE (m_fd, (float *)data, m_spec.width, 1, rgbe_error); if (r != RGBE_RETURN_SUCCESS) error ("%s", rgbe_error); return (r == RGBE_RETURN_SUCCESS); } bool HdrOutput::close () { if (m_fd != NULL) { fclose (m_fd); m_fd = NULL; } init(); return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/hdr.imageio/rgbe.h0000644000175000017500000000471012271062644020370 0ustar mfvmfv#ifndef _H_RGBE #define _H_RGBE /* THIS CODE CARRIES NO GUARANTEE OF USABILITY OR FITNESS FOR ANY PURPOSE. * WHILE THE AUTHORS HAVE TRIED TO ENSURE THE PROGRAM WORKS CORRECTLY, * IT IS STRICTLY USE AT YOUR OWN RISK. */ /* utility for reading and writing Ward's rgbe image format. See rgbe.txt file for more details. */ #include #include "imageio.h" OIIO_PLUGIN_NAMESPACE_BEGIN typedef struct { int valid; /* indicate which fields are valid */ char programtype[16]; /* listed at beginning of file to identify it * after "#?". defaults to "RGBE" */ float gamma; /* image has already been gamma corrected with * given gamma. defaults to 1.0 (no correction) */ float exposure; /* a value of 1.0 in an image corresponds to * watts/steradian/m^2. * defaults to 1.0 */ int orientation; /* Orientation of the image. Use the same coded * values as the TIFF and JPEG/JFIF/EXIF specs. * defaults to 1 (-Y +X) * (added by Larry Gritz, 7/2008) */ } rgbe_header_info; /* flags indicating which fields in an rgbe_header_info are valid */ #define RGBE_VALID_PROGRAMTYPE 0x01 #define RGBE_VALID_GAMMA 0x02 #define RGBE_VALID_EXPOSURE 0x04 #define RGBE_VALID_ORIENTATION 0x08 /* return codes for rgbe routines */ #define RGBE_RETURN_SUCCESS 0 #define RGBE_RETURN_FAILURE -1 /* read or write headers */ /* you may set rgbe_header_info to null if you want to */ int RGBE_WriteHeader(FILE *fp, int width, int height, rgbe_header_info *info, char *errbuf=NULL); int RGBE_ReadHeader(FILE *fp, int *width, int *height, rgbe_header_info *info, char *errbuf=NULL); /* read or write pixels */ /* can read or write pixels in chunks of any size including single pixels*/ int RGBE_WritePixels(FILE *fp, float *data, int numpixels, char *errbuf=NULL); int RGBE_ReadPixels(FILE *fp, float *data, int numpixels, char *errbuf=NULL); /* read or write run length encoded files */ /* must be called to read or write whole scanlines */ int RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width, int num_scanlines, char *errbuf=NULL); int RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width, int num_scanlines, char *errbuf=NULL); OIIO_PLUGIN_NAMESPACE_END #endif /* _H_RGBE */ openimageio-1.3.12~dfsg0.orig/src/hdr.imageio/CMakeLists.txt0000644000175000017500000000006612271062644022040 0ustar mfvmfvadd_oiio_plugin (rgbe.cpp hdrinput.cpp hdroutput.cpp) openimageio-1.3.12~dfsg0.orig/src/maketx/0000755000175000017500000000000012271062644016401 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/maketx/maketx.cpp0000644000175000017500000004043512271062644020404 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #include #include "argparse.h" #include "dassert.h" #include "filesystem.h" #include "fmath.h" #include "strutil.h" #include "sysutil.h" #include "timer.h" #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "thread.h" #include "filter.h" OIIO_NAMESPACE_USING // # FIXME: Refactor all statics into a struct // Basic runtime options static std::string full_command_line; static std::vector filenames; static std::string outputfilename; static bool verbose = false; static bool stats = false; static int nthreads = 0; // default: use #cores threads if available // Conversion modes. If none are true, we just make an ordinary texture. static bool mipmapmode = false; static bool shadowmode = false; static bool envlatlmode = false; static bool envcubemode = false; static bool lightprobemode = false; static ColorConfig colorconfig; static std::string filter_help_string () { std::string s ("Select filter for resizing (choices:"); for (int i = 0, e = Filter2D::num_filters(); i < e; ++i) { FilterDesc d; Filter2D::get_filterdesc (i, &d); s.append (" "); s.append (d.name); } s.append (", default=box)"); return s; } static std::string colortitle_help_string () { std::string s ("Color Management Options "); if(ColorConfig::supportsOpenColorIO()) { s += "(OpenColorIO enabled)"; } else { s += "(OpenColorIO DISABLED)"; } return s; } static std::string colorconvert_help_string () { std::string s = "Apply a color space conversion to the image. " "If the output color space is not the same bit depth " "as input color space, it is your responsibility to set the data format " "to the proper bit depth using the -d option. "; s += " (choices: "; if (colorconfig.error() || colorconfig.getNumColorSpaces()==0) { s += "NONE"; } else { for (int i=0; i < colorconfig.getNumColorSpaces(); ++i) { if (i!=0) s += ", "; s += colorconfig.getColorSpaceNameByIndex(i); } } s += ")"; return s; } static int parse_files (int argc, const char *argv[]) { for (int i = 0; i < argc; i++) filenames.push_back (argv[i]); return 0; } static void getargs (int argc, char *argv[], ImageSpec &configspec) { bool help = false; // Basic runtime options std::string dataformatname = ""; std::string fileformatname = ""; std::vector mipimages; int tile[3] = { 64, 64, 1 }; // FIXME if we ever support volume MIPmaps std::string compression = "zip"; bool updatemode = false; bool checknan = false; std::string fixnan; // none, black, box3 bool set_full_to_pixels = false; bool do_highlight_compensation = false; std::string filtername; // Options controlling file metadata or mipmap creation float fovcot = 0.0f; std::string wrap = "black"; std::string swrap; std::string twrap; bool doresize = false; Imath::M44f Mcam(0.0f), Mscr(0.0f); // Initialize to 0 bool separate = false; bool nomipmap = false; bool prman_metadata = false; bool constant_color_detect = false; bool monochrome_detect = false; bool opaque_detect = false; int nchannels = -1; bool prman = false; bool oiio = false; bool ignore_unassoc = false; // ignore unassociated alpha tags bool unpremult = false; std::string incolorspace; std::string outcolorspace; std::string channelnames; filenames.clear(); ArgParse ap; ap.options ("maketx -- convert images to tiled, MIP-mapped textures\n" OIIO_INTRO_STRING "\n" "Usage: maketx [options] file...", "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose status messages", "-o %s", &outputfilename, "Output filename", "--new", NULL, "", "--old", NULL, "Old mode", "--threads %d", &nthreads, "Number of threads (default: #cores)", "-u", &updatemode, "Update mode", "--format %s", &fileformatname, "Specify output file format (default: guess from extension)", "--nchannels %d", &nchannels, "Specify the number of output image channels.", "--chnames %s", &channelnames, "Rename channels (comma-separated)", "-d %s", &dataformatname, "Set the output data format to one of: " "uint8, sint8, uint16, sint16, half, float", "--tile %d %d", &tile[0], &tile[1], "Specify tile size", "--separate", &separate, "Use planarconfig separate (default: contiguous)", "--compression %s", &compression, "Set the compression method (default = zip, if possible)", "--fovcot %f", &fovcot, "Override the frame aspect ratio. Default is width/height.", "--wrap %s", &wrap, "Specify wrap mode (black, clamp, periodic, mirror)", "--swrap %s", &swrap, "Specific s wrap mode separately", "--twrap %s", &twrap, "Specific t wrap mode separately", "--resize", &doresize, "Resize textures to power of 2 (default: no)", "--noresize %!", &doresize, "Do not resize textures to power of 2 (deprecated)", "--filter %s", &filtername, filter_help_string().c_str(), "--hicomp", &do_highlight_compensation, "Compress HDR range before resize, expand after.", "--nomipmap", &nomipmap, "Do not make multiple MIP-map levels", "--checknan", &checknan, "Check for NaN/Inf values (abort if found)", "--fixnan %s", &fixnan, "Attempt to fix NaN/Inf values in the image (options: none, black, box3)", "--fullpixels", &set_full_to_pixels, "Set the 'full' image range to be the pixel data window", "--Mcamera %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", &Mcam[0][0], &Mcam[0][1], &Mcam[0][2], &Mcam[0][3], &Mcam[1][0], &Mcam[1][1], &Mcam[1][2], &Mcam[1][3], &Mcam[2][0], &Mcam[2][1], &Mcam[2][2], &Mcam[2][3], &Mcam[3][0], &Mcam[3][1], &Mcam[3][2], &Mcam[3][3], "Set the camera matrix", "--Mscreen %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", &Mscr[0][0], &Mscr[0][1], &Mscr[0][2], &Mscr[0][3], &Mscr[1][0], &Mscr[1][1], &Mscr[1][2], &Mscr[1][3], &Mscr[2][0], &Mscr[2][1], &Mscr[2][2], &Mscr[2][3], &Mscr[3][0], &Mscr[3][1], &Mscr[3][2], &Mscr[3][3], "Set the screen matrix", "--hash", NULL, "", "--prman-metadata", &prman_metadata, "Add prman specific metadata", "--constant-color-detect", &constant_color_detect, "Create 1-tile textures from constant color inputs", "--monochrome-detect", &monochrome_detect, "Create 1-channel textures from monochrome inputs", "--opaque-detect", &opaque_detect, "Drop alpha channel that is always 1.0", "--ignore-unassoc", &ignore_unassoc, "Ignore unassociated alpha tags in input (don't autoconvert)", "--stats", &stats, "Print runtime statistics", "--mipimage %L", &mipimages, "Specify an individual MIP level", "", "Basic modes (default is plain texture):", "--shadow", &shadowmode, "Create shadow map", "--envlatl", &envlatlmode, "Create lat/long environment map", "--lightprobe", &lightprobemode, "Create lat/long environment map from a light probe", // "--envcube", &envcubemode, "Create cubic env map (file order: px, nx, py, ny, pz, nz) (UNIMP)", "", colortitle_help_string().c_str(), "--colorconvert %s %s", &incolorspace, &outcolorspace, colorconvert_help_string().c_str(), "--unpremult", &unpremult, "Unpremultiply before color conversion, then premultiply " "after the color conversion. You'll probably want to use this flag " "if your image contains an alpha channel.", "", "Configuration Presets", "--prman", &prman, "Use PRMan-safe settings for tile size, planarconfig, and metadata.", "--oiio", &oiio, "Use OIIO-optimized settings for tile size, planarconfig, metadata.", NULL); if (ap.parse (argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help || filenames.empty()) { ap.usage (); exit (EXIT_FAILURE); } int optionsum = ((int)shadowmode + (int)envlatlmode + (int)envcubemode + (int)lightprobemode); if (optionsum > 1) { std::cerr << "maketx ERROR: At most one of the following options may be set:\n" << "\t--shadow --envlatl --envcube --lightprobe\n"; ap.usage (); exit (EXIT_FAILURE); } if (optionsum == 0) mipmapmode = true; if (prman && oiio) { std::cerr << "maketx ERROR: '--prman' compatibility, and '--oiio' optimizations are mutually exclusive.\n"; std::cerr << "\tIf you'd like both prman and oiio compatibility, you should choose --prman\n"; std::cerr << "\t(at the expense of oiio-specific optimizations)\n"; ap.usage (); exit (EXIT_FAILURE); } if (filenames.size() != 1) { std::cerr << "maketx ERROR: requires exactly one input filename\n"; exit (EXIT_FAILURE); } // std::cout << "Converting " << filenames[0] << " to " << outputfilename << "\n"; // Figure out which data format we want for output if (! dataformatname.empty()) { if (dataformatname == "uint8") configspec.format = TypeDesc::UINT8; else if (dataformatname == "int8" || dataformatname == "sint8") configspec.format = TypeDesc::INT8; else if (dataformatname == "uint16") configspec.format = TypeDesc::UINT16; else if (dataformatname == "int16" || dataformatname == "sint16") configspec.format = TypeDesc::INT16; else if (dataformatname == "half") configspec.format = TypeDesc::HALF; else if (dataformatname == "float") configspec.format = TypeDesc::FLOAT; else if (dataformatname == "double") configspec.format = TypeDesc::DOUBLE; } configspec.tile_width = tile[0]; configspec.tile_height = tile[1]; configspec.tile_depth = tile[2]; configspec.attribute ("compression", compression); if (fovcot != 0.0f) configspec.attribute ("fovcot", fovcot); configspec.attribute ("planarconfig", separate ? "separate" : "contig"); if (Mcam != Imath::M44f(0.0f)) configspec.attribute ("worldtocamera", TypeDesc::TypeMatrix, &Mcam); if (Mscr != Imath::M44f(0.0f)) configspec.attribute ("worldtoscreen", TypeDesc::TypeMatrix, &Mscr); std::string wrapmodes = (swrap.size() ? swrap : wrap) + ',' + (twrap.size() ? twrap : wrap); configspec.attribute ("wrapmodes", wrapmodes); configspec.attribute ("maketx:verbose", verbose); configspec.attribute ("maketx:stats", stats); configspec.attribute ("maketx:resize", doresize); configspec.attribute ("maketx:nomipmap", nomipmap); configspec.attribute ("maketx:updatemode", updatemode); configspec.attribute ("maketx:constant_color_detect", constant_color_detect); configspec.attribute ("maketx:monochrome_detect", monochrome_detect); configspec.attribute ("maketx:opaque_detect", opaque_detect); configspec.attribute ("maketx:unpremult", unpremult); configspec.attribute ("maketx:incolorspace", incolorspace); configspec.attribute ("maketx:outcolorspace", outcolorspace); configspec.attribute ("maketx:checknan", checknan); configspec.attribute ("maketx:fixnan", fixnan); configspec.attribute ("maketx:set_full_to_pixels", set_full_to_pixels); configspec.attribute ("maketx:highlightcomp", (int)do_highlight_compensation); if (filtername.size()) configspec.attribute ("maketx:filtername", filtername); configspec.attribute ("maketx:nchannels", nchannels); configspec.attribute ("maketx:channelnames", channelnames); if (fileformatname.size()) configspec.attribute ("maketx:fileformatname", fileformatname); configspec.attribute ("maketx:prman_metadata", prman_metadata); configspec.attribute ("maketx:oiio_options", oiio); configspec.attribute ("maketx:prman_options", prman); if (mipimages.size()) configspec.attribute ("maketx:mipimages", Strutil::join(mipimages,";")); std::string cmdline = Strutil::format ("OpenImageIO %s : %s", OIIO_VERSION_STRING, ap.command_line()); configspec.attribute ("Software", cmdline); configspec.attribute ("maketx:full_command_line", cmdline); if (ignore_unassoc) { configspec.attribute ("maketx:ignore_unassoc", (int)ignore_unassoc); ImageCache *ic = ImageCache::create (); // get the shared one ic->attribute ("unassociatedalpha", (int)ignore_unassoc); } } int main (int argc, char *argv[]) { Timer alltimer; ImageSpec configspec; Filesystem::convert_native_arguments (argc, (const char **)argv); getargs (argc, argv, configspec); OIIO::attribute ("threads", nthreads); // N.B. This will apply to the default IC that any ImageBuf's get. ImageCache *ic = ImageCache::create (); // get the shared one ic->attribute ("forcefloat", 1); // Force float upon read ic->attribute ("max_memory_MB", 1024.0); // 1 GB cache ImageBufAlgo::MakeTextureMode mode = ImageBufAlgo::MakeTxTexture; if (shadowmode) mode = ImageBufAlgo::MakeTxShadow; if (envlatlmode) mode = ImageBufAlgo::MakeTxEnvLatl; if (lightprobemode) mode = ImageBufAlgo::MakeTxEnvLatlFromLightProbe; bool ok = ImageBufAlgo::make_texture (mode, filenames[0], outputfilename, configspec, &std::cout); if (stats) std::cout << "\n" << ic->getstats(); return ok ? 0 : EXIT_FAILURE; } openimageio-1.3.12~dfsg0.orig/src/maketx/CMakeLists.txt0000644000175000017500000000040012271062644021133 0ustar mfvmfvset (maketx_srcs maketx.cpp) add_executable (maketx ${maketx_srcs}) set_target_properties (maketx PROPERTIES FOLDER "Tools") link_ilmbase (maketx) target_link_libraries (maketx OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) oiio_install_targets (maketx) openimageio-1.3.12~dfsg0.orig/src/tiff.imageio/0000755000175000017500000000000012271062644017451 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/tiff.imageio/tiffoutput.cpp0000644000175000017500000005442612271062644022401 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include "dassert.h" #include "imageio.h" #include "filesystem.h" #include "strutil.h" #include "sysutil.h" #include "timer.h" #include OIIO_PLUGIN_NAMESPACE_BEGIN namespace { // This is the default interval between checkpoints. // While these are cheap, we need to throttle them // so we don't checkpoint too often... (each checkpoint // re-writes the tiff header and any new tiles / scanlines) static double DEFAULT_CHECKPOINT_INTERVAL_SECONDS = 5.0; static int MIN_SCANLINES_OR_TILES_PER_CHECKPOINT = 16; } class TIFFOutput : public ImageOutput { public: TIFFOutput (); virtual ~TIFFOutput (); virtual const char * format_name (void) const { return "tiff"; } virtual bool supports (const std::string &feature) const; virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); virtual bool write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride); private: TIFF *m_tif; std::vector m_scratch; int m_planarconfig; Timer m_checkpointTimer; int m_checkpointItems; // Initialize private members to pre-opened state void init (void) { m_tif = NULL; m_checkpointItems = 0; } // Convert planar contiguous to planar separate data format void contig_to_separate (int n, const char *contig, char *separate); // Add a parameter to the output bool put_parameter (const std::string &name, TypeDesc type, const void *data); }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *tiff_output_imageio_create () { return new TIFFOutput; } OIIO_EXPORT int tiff_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * tiff_output_extensions[] = { "tiff", "tif", "tx", "env", "sm", "vsm", NULL }; OIIO_PLUGIN_EXPORTS_END TIFFOutput::TIFFOutput () { init (); } TIFFOutput::~TIFFOutput () { // Close, if not already done. close (); } bool TIFFOutput::supports (const std::string &feature) const { if (feature == "tiles") return true; if (feature == "multiimage") return true; if (feature == "appendsubimage") return true; if (feature == "displaywindow") return true; if (feature == "origin") return true; // N.B. TIFF doesn't support "negativeorigin" // FIXME: we could support "volumes" and "empty" // Everything else, we either don't support or don't know about return false; } bool TIFFOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode == AppendMIPLevel) { error ("%s does not support MIP levels", format_name()); return false; } close (); // Close any already-opened file m_spec = userspec; // Stash the spec // Check for things this format doesn't support if (m_spec.width < 1 || m_spec.height < 1) { error ("Image resolution must be at least 1x1, you asked for %d x %d", m_spec.width, m_spec.height); return false; } if (m_spec.depth < 1) m_spec.depth = 1; // Open the file #ifdef _WIN32 std::wstring wname = Strutil::utf8_to_utf16 (name); m_tif = TIFFOpenW (wname.c_str(), mode == AppendSubimage ? "a" : "w"); #else m_tif = TIFFOpen (name.c_str(), mode == AppendSubimage ? "a" : "w"); #endif if (! m_tif) { error ("Can't open \"%s\" for output.", name.c_str()); return false; } TIFFSetField (m_tif, TIFFTAG_XPOSITION, (float)m_spec.x); TIFFSetField (m_tif, TIFFTAG_YPOSITION, (float)m_spec.y); TIFFSetField (m_tif, TIFFTAG_IMAGEWIDTH, m_spec.width); TIFFSetField (m_tif, TIFFTAG_IMAGELENGTH, m_spec.height); if ((m_spec.full_width != 0 || m_spec.full_height != 0) && (m_spec.full_width != m_spec.width || m_spec.full_height != m_spec.height)) { TIFFSetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLWIDTH, m_spec.full_width); TIFFSetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLLENGTH, m_spec.full_height); } if (m_spec.tile_width) { TIFFSetField (m_tif, TIFFTAG_TILEWIDTH, m_spec.tile_width); TIFFSetField (m_tif, TIFFTAG_TILELENGTH, m_spec.tile_height); } else { // Scanline images must set rowsperstrip TIFFSetField (m_tif, TIFFTAG_ROWSPERSTRIP, 32); } TIFFSetField (m_tif, TIFFTAG_SAMPLESPERPIXEL, m_spec.nchannels); int orientation = m_spec.get_int_attribute("Orientation", 1); TIFFSetField (m_tif, TIFFTAG_ORIENTATION, orientation); int bps, sampformat; switch (m_spec.format.basetype) { case TypeDesc::INT8: bps = 8; sampformat = SAMPLEFORMAT_INT; break; case TypeDesc::UINT8: bps = 8; sampformat = SAMPLEFORMAT_UINT; break; case TypeDesc::INT16: bps = 16; sampformat = SAMPLEFORMAT_INT; break; case TypeDesc::UINT16: bps = 16; sampformat = SAMPLEFORMAT_UINT; break; case TypeDesc::HALF: // Silently change requests for unsupported 'half' to 'float' m_spec.set_format (TypeDesc::FLOAT); case TypeDesc::FLOAT: bps = 32; sampformat = SAMPLEFORMAT_IEEEFP; break; case TypeDesc::DOUBLE: bps = 64; sampformat = SAMPLEFORMAT_IEEEFP; break; default: // Everything else, including UNKNOWN -- default to 8 bit bps = 8; sampformat = SAMPLEFORMAT_UINT; m_spec.set_format (TypeDesc::UINT8); break; } TIFFSetField (m_tif, TIFFTAG_BITSPERSAMPLE, bps); TIFFSetField (m_tif, TIFFTAG_SAMPLEFORMAT, sampformat); int photo = (m_spec.nchannels > 1 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK); TIFFSetField (m_tif, TIFFTAG_PHOTOMETRIC, photo); // ExtraSamples tag if (m_spec.nchannels > 3) { bool unass = m_spec.get_int_attribute("oiio:UnassociatedAlpha", 0); short e = m_spec.nchannels-3; std::vector extra (e); for (int c = 0; c < e; ++c) { if (m_spec.alpha_channel == (c+3)) extra[c] = unass ? EXTRASAMPLE_UNASSALPHA : EXTRASAMPLE_ASSOCALPHA; else extra[c] = EXTRASAMPLE_UNSPECIFIED; } TIFFSetField (m_tif, TIFFTAG_EXTRASAMPLES, e, &extra[0]); } // Default to LZW compression if no request came with the user spec if (! m_spec.find_attribute("compression")) m_spec.attribute ("compression", "lzw"); ImageIOParameter *param; const char *str = NULL; // Did the user request separate planar configuration? m_planarconfig = PLANARCONFIG_CONTIG; if ((param = m_spec.find_attribute("planarconfig", TypeDesc::STRING)) || (param = m_spec.find_attribute("tiff:planarconfig", TypeDesc::STRING))) { str = *(char **)param->data(); if (str && Strutil::iequals (str, "separate")) { m_planarconfig = PLANARCONFIG_SEPARATE; if (! m_spec.tile_width) { // I can only seem to make separate planarconfig work when // rowsperstrip is 1. TIFFSetField (m_tif, TIFFTAG_ROWSPERSTRIP, 1); } } } TIFFSetField (m_tif, TIFFTAG_PLANARCONFIG, m_planarconfig); // Automatically set date field if the client didn't supply it. if (! m_spec.find_attribute("DateTime")) { time_t now; time (&now); struct tm mytm; Sysutil::get_local_time (&now, &mytm); std::string date = Strutil::format ("%4d:%02d:%02d %2d:%02d:%02d", mytm.tm_year+1900, mytm.tm_mon+1, mytm.tm_mday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec); m_spec.attribute ("DateTime", date); } if (Strutil::iequals (m_spec.get_string_attribute ("oiio:ColorSpace"), "sRGB")) m_spec.attribute ("Exif:ColorSpace", 1); // Deal with all other params for (size_t p = 0; p < m_spec.extra_attribs.size(); ++p) put_parameter (m_spec.extra_attribs[p].name().string(), m_spec.extra_attribs[p].type(), m_spec.extra_attribs[p].data()); std::vector iptc; encode_iptc_iim (m_spec, iptc); if (iptc.size()) { iptc.resize ((iptc.size()+3) & (0xffff-3)); // round up TIFFSetField (m_tif, TIFFTAG_RICHTIFFIPTC, iptc.size()/4, &iptc[0]); } std::string xmp = encode_xmp (m_spec, true); if (! xmp.empty()) TIFFSetField (m_tif, TIFFTAG_XMLPACKET, xmp.size(), xmp.c_str()); TIFFCheckpointDirectory (m_tif); // Ensure the header is written early m_checkpointTimer.start(); // Initialize the to the fileopen time m_checkpointItems = 0; // Number of tiles or scanlines we've written return true; } bool TIFFOutput::put_parameter (const std::string &name, TypeDesc type, const void *data) { if (Strutil::iequals(name, "Artist") && type == TypeDesc::STRING) { TIFFSetField (m_tif, TIFFTAG_ARTIST, *(char**)data); return true; } if (Strutil::iequals(name, "Compression") && type == TypeDesc::STRING) { int compress = COMPRESSION_LZW; // default const char *str = *(char **)data; if (str) { if (Strutil::iequals (str, "none")) compress = COMPRESSION_NONE; else if (Strutil::iequals (str, "lzw")) compress = COMPRESSION_LZW; else if (Strutil::istarts_with (str, "zip") || Strutil::iequals (str, "deflate")) compress = COMPRESSION_ADOBE_DEFLATE; else if (Strutil::iequals (str, "packbits")) compress = COMPRESSION_PACKBITS; else if (Strutil::iequals (str, "ccittrle")) compress = COMPRESSION_CCITTRLE; } TIFFSetField (m_tif, TIFFTAG_COMPRESSION, compress); // Use predictor when using compression if (compress == COMPRESSION_LZW || compress == COMPRESSION_ADOBE_DEFLATE) { if (m_spec.format == TypeDesc::FLOAT || m_spec.format == TypeDesc::DOUBLE || m_spec.format == TypeDesc::HALF) { TIFFSetField (m_tif, TIFFTAG_PREDICTOR, PREDICTOR_FLOATINGPOINT); // N.B. Very old versions of libtiff did not support this // predictor. It's possible that certain apps can't read // floating point TIFFs with this set. But since it's been // documented since 2005, let's take our chances. Comment // out the above line if this is problematic. } else TIFFSetField (m_tif, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL); } } if (Strutil::iequals(name, "Copyright") && type == TypeDesc::STRING) { TIFFSetField (m_tif, TIFFTAG_COPYRIGHT, *(char**)data); return true; } if (Strutil::iequals(name, "DateTime") && type == TypeDesc::STRING) { TIFFSetField (m_tif, TIFFTAG_DATETIME, *(char**)data); return true; } if ((Strutil::iequals(name, "name") || Strutil::iequals(name, "DocumentName")) && type == TypeDesc::STRING) { TIFFSetField (m_tif, TIFFTAG_DOCUMENTNAME, *(char**)data); return true; } if (Strutil::iequals(name,"fovcot") && type == TypeDesc::FLOAT) { double d = *(float *)data; TIFFSetField (m_tif, TIFFTAG_PIXAR_FOVCOT, d); return true; } if ((Strutil::iequals(name, "host") || Strutil::iequals(name, "HostComputer")) && type == TypeDesc::STRING) { TIFFSetField (m_tif, TIFFTAG_HOSTCOMPUTER, *(char**)data); return true; } if ((Strutil::iequals(name, "description") || Strutil::iequals(name, "ImageDescription")) && type == TypeDesc::STRING) { TIFFSetField (m_tif, TIFFTAG_IMAGEDESCRIPTION, *(char**)data); return true; } if (Strutil::iequals(name, "tiff:Predictor") && type == TypeDesc::INT) { TIFFSetField (m_tif, TIFFTAG_PREDICTOR, *(int *)data); return true; } if (Strutil::iequals(name, "ResolutionUnit") && type == TypeDesc::STRING) { const char *s = *(char**)data; bool ok = true; if (Strutil::iequals (s, "none")) TIFFSetField (m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE); else if (Strutil::iequals (s, "in") || Strutil::iequals (s, "inch")) TIFFSetField (m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); else if (Strutil::iequals (s, "cm")) TIFFSetField (m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER); else ok = false; return ok; } if (Strutil::iequals(name, "ResolutionUnit") && type == TypeDesc::UINT) { TIFFSetField (m_tif, TIFFTAG_RESOLUTIONUNIT, *(unsigned int *)data); return true; } if (Strutil::iequals(name, "tiff:RowsPerStrip") && ! m_spec.tile_width /* don't set rps for tiled files */ && m_planarconfig == PLANARCONFIG_CONTIG /* only for contig */) { if (type == TypeDesc::INT) { TIFFSetField (m_tif, TIFFTAG_ROWSPERSTRIP, std::min (*(int*)data, m_spec.height)); return true; } else if (type == TypeDesc::STRING) { // Back-compatibility with Entropy and PRMan TIFFSetField (m_tif, TIFFTAG_ROWSPERSTRIP, std::min (atoi(*(char **)data), m_spec.height)); return true; } } if (Strutil::iequals(name, "Software") && type == TypeDesc::STRING) { TIFFSetField (m_tif, TIFFTAG_SOFTWARE, *(char**)data); return true; } if (Strutil::iequals(name, "tiff:SubFileType") && type == TypeDesc::INT) { TIFFSetField (m_tif, TIFFTAG_SUBFILETYPE, *(int*)data); return true; } if (Strutil::iequals(name, "textureformat") && type == TypeDesc::STRING) { TIFFSetField (m_tif, TIFFTAG_PIXAR_TEXTUREFORMAT, *(char**)data); return true; } if (Strutil::iequals(name, "wrapmodes") && type == TypeDesc::STRING) { TIFFSetField (m_tif, TIFFTAG_PIXAR_WRAPMODES, *(char**)data); return true; } if (Strutil::iequals(name, "worldtocamera") && type == TypeDesc::TypeMatrix) { TIFFSetField (m_tif, TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, data); return true; } if (Strutil::iequals(name, "worldtoscreen") && type == TypeDesc::TypeMatrix) { TIFFSetField (m_tif, TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, data); return true; } if (Strutil::iequals(name, "XResolution") && type == TypeDesc::FLOAT) { TIFFSetField (m_tif, TIFFTAG_XRESOLUTION, *(float *)data); return true; } if (Strutil::iequals(name, "YResolution") && type == TypeDesc::FLOAT) { TIFFSetField (m_tif, TIFFTAG_YRESOLUTION, *(float *)data); return true; } // FIXME -- we don't currently support writing of EXIF fields. TIFF // in theory allows it, using a custom IFD directory, but at // present, it appears that libtiff only supports reading custom // IFD's, not writing them. return false; } bool TIFFOutput::close () { if (m_tif) TIFFClose (m_tif); // N.B. TIFFClose doesn't return a status code init (); // re-initialize return true; // How can we fail? } /// Helper: Convert n pixels from contiguous (RGBRGBRGB) to separate /// (RRRGGGBBB) planarconfig. void TIFFOutput::contig_to_separate (int n, const char *contig, char *separate) { int channelbytes = m_spec.channel_bytes(); for (int p = 0; p < n; ++p) // loop over pixels for (int c = 0; c < m_spec.nchannels; ++c) // loop over channels for (int i = 0; i < channelbytes; ++i) // loop over data bytes separate[(c*n+p)*channelbytes+i] = contig[(p*m_spec.nchannels+c)*channelbytes+i]; } bool TIFFOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { m_spec.auto_stride (xstride, format, spec().nchannels); const void *origdata = data; data = to_native_scanline (format, data, xstride, m_scratch); y -= m_spec.y; if (m_planarconfig == PLANARCONFIG_SEPARATE) { // Convert from contiguous (RGBRGBRGB) to separate (RRRGGGBBB) int plane_bytes = m_spec.width * m_spec.format.size(); std::vector scratch2 (m_spec.scanline_bytes()); std::swap (m_scratch, scratch2); m_scratch.resize (m_spec.scanline_bytes()); contig_to_separate (m_spec.width, (const char *)data, (char *)&m_scratch[0]); for (int c = 0; c < m_spec.nchannels; ++c) { if (TIFFWriteScanline (m_tif, (tdata_t)&m_scratch[plane_bytes*c], y, c) < 0) { error ("TIFFWriteScanline failed"); return false; } } } else { // No contig->separate is necessary. But we still use scratch // space since TIFFWriteScanline is destructive when // TIFFTAG_PREDICTOR is used. if (data == origdata) { m_scratch.assign ((unsigned char *)data, (unsigned char *)data+m_spec.scanline_bytes()); data = &m_scratch[0]; } if (TIFFWriteScanline (m_tif, (tdata_t)data, y) < 0) { error ("TIFFWriteScanline failed"); return false; } } // Should we checkpoint? Only if we have enough scanlines and enough // time has passed if (m_checkpointTimer() > DEFAULT_CHECKPOINT_INTERVAL_SECONDS && m_checkpointItems >= MIN_SCANLINES_OR_TILES_PER_CHECKPOINT) { TIFFCheckpointDirectory (m_tif); m_checkpointTimer.lap(); m_checkpointItems = 0; } else { ++m_checkpointItems; } return true; } bool TIFFOutput::write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride) { if (! m_spec.valid_tile_range (x, x, y, y, z, z)) return false; m_spec.auto_stride (xstride, ystride, zstride, format, spec().nchannels, spec().tile_width, spec().tile_height); x -= m_spec.x; // Account for offset, so x,y are file relative, not y -= m_spec.y; // image relative const void *origdata = data; // Stash original pointer data = to_native_tile (format, data, xstride, ystride, zstride, m_scratch); if (m_planarconfig == PLANARCONFIG_SEPARATE && m_spec.nchannels > 1) { // Convert from contiguous (RGBRGBRGB) to separate (RRRGGGBBB) imagesize_t tile_pixels = m_spec.tile_pixels(); imagesize_t plane_bytes = tile_pixels * m_spec.format.size(); DASSERT (plane_bytes*m_spec.nchannels == m_spec.tile_bytes()); m_scratch.resize (m_spec.tile_bytes()); boost::scoped_array separate_heap; char *separate = NULL; imagesize_t separate_size = plane_bytes * m_spec.nchannels; if (separate_size <= (1<<16)) separate = ALLOCA (char, separate_size); // <=64k ? stack else { // >64k ? heap separate_heap.reset (new char [separate_size]); // will auto-free separate = separate_heap.get(); } contig_to_separate (tile_pixels, (const char *)data, separate); for (int c = 0; c < m_spec.nchannels; ++c) { if (TIFFWriteTile (m_tif, (tdata_t)&separate[plane_bytes*c], x, y, z, c) < 0) { error ("TIFFWriteTile failed"); return false; } } } else { // No contig->separate is necessary. But we still use scratch // space since TIFFWriteTile is destructive when // TIFFTAG_PREDICTOR is used. if (data == origdata) { m_scratch.assign ((unsigned char *)data, (unsigned char *)data + m_spec.tile_bytes()); data = &m_scratch[0]; } if (TIFFWriteTile (m_tif, (tdata_t)data, x, y, z, 0) < 0) { error ("TIFFWriteTile failed"); return false; } } // Should we checkpoint? Only if we have enough tiles and enough time has passed if (m_checkpointTimer() > DEFAULT_CHECKPOINT_INTERVAL_SECONDS && m_checkpointItems >= MIN_SCANLINES_OR_TILES_PER_CHECKPOINT) { TIFFCheckpointDirectory (m_tif); m_checkpointTimer.lap(); m_checkpointItems = 0; } else { ++m_checkpointItems; } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/tiff.imageio/tiffinput.cpp0000644000175000017500000013227412271062644022176 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "thread.h" #include "strutil.h" #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN // General TIFF information: // TIFF 6.0 spec: // http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf // Other Adobe TIFF docs: // http://partners.adobe.com/public/developer/tiff/index.html // Adobe extensions to allow 16 (and 24) bit float in TIFF (ugh, not on // their developer page, only on Chris Cox's web site?): // http://chriscox.org/TIFFTN3d1.pdf // Libtiff: // http://remotesensing.org/libtiff/ // Helper struct for constructing tables of TIFF tags struct TIFF_tag_info { int tifftag; // TIFF tag used for this info const char *name; // Attribute name we use, or NULL to ignore the tag TIFFDataType tifftype; // Data type that TIFF wants }; // Note about MIP-maps versus subimages: // // TIFF files support subimages, but do not explicitly support // multiresolution/MIP maps. So we have always used subimages to store // MIP levels. // // At present, TIFF is the only format people use for multires textures // that don't explicitly support it, so rather than make the // TextureSystem have to handle both cases, we choose instead to emulate // MIP with subimage in a way that's purely within the TIFFInput class. // To the outside world, it really does look MIP-mapped. This only // kicks in for TIFF files that have the "textureformat" metadata set. // // The internal m_subimage really does contain the subimage, but for the // MIP emulation case, we report the subimage as the MIP level, and 0 as // the subimage. It is indeed a tangled web of deceit we weave. class TIFFInput : public ImageInput { public: TIFFInput () { init(); } virtual ~TIFFInput () { close(); } virtual const char * format_name (void) const { return "tiff"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool open (const std::string &name, ImageSpec &newspec, const ImageSpec &config); virtual bool close (); virtual int current_subimage (void) const { // If m_emulate_mipmap is true, pretend subimages are mipmap levels return m_emulate_mipmap ? 0 : m_subimage; } virtual int current_miplevel (void) const { // If m_emulate_mipmap is true, pretend subimages are mipmap levels return m_emulate_mipmap ? m_subimage : 0; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual bool read_native_scanline (int y, int z, void *data); virtual bool read_native_tile (int x, int y, int z, void *data); private: TIFF *m_tif; ///< libtiff handle std::string m_filename; ///< Stash the filename std::vector m_scratch; ///< Scratch space for us to use int m_subimage; ///< What subimage are we looking at? int m_next_scanline; ///< Next scanline we'll read bool m_no_random_access; ///< Should we avoid random access? bool m_emulate_mipmap; ///< Should we emulate mip with subimage? bool m_keep_unassociated_alpha; ///< If the image is unassociated, please /// try to keep it that way! bool m_convert_alpha; ///< Do we need to associate alpha? bool m_separate; ///< Separate planarconfig? unsigned short m_planarconfig; ///< Planar config of the file unsigned short m_bitspersample; ///< Of the *file*, not the client's view unsigned short m_photometric; ///< Of the *file*, not the client's view std::vector m_colormap; ///< Color map for palette images // Reset everything to initial state void init () { m_tif = NULL; m_subimage = -1; m_emulate_mipmap = false; m_keep_unassociated_alpha = false; m_convert_alpha = false; m_separate = false; m_colormap.clear(); } void close_tif () { if (m_tif) { TIFFClose (m_tif); m_tif = NULL; } } // Read tags from the current directory of m_tif and fill out spec. // If read_meta is false, assume that m_spec already contains valid // metadata and should not be cleared or rewritten. void readspec (bool read_meta=true); // Convert planar separate to contiguous data format void separate_to_contig (int n, const unsigned char *separate, unsigned char *contig); // Convert palette to RGB void palette_to_rgb (int n, const unsigned char *palettepels, unsigned char *rgb); // Convert in-bits to out-bits (outbits must be 8, 16, 32, and // inbits < outbits) void bit_convert (int n, const unsigned char *in, int inbits, void *out, int outbits); void invert_photometric (int n, void *data); // Convert from unassociated/non-premultiplied alpha to // associated/premultiplied template void unassociate (T *data, int size, int nchannels, int alpha_channel) { double scale = std::numeric_limits::is_integer ? 1.0/std::numeric_limits::max() : 1.0; for ( ; size; --size, data += nchannels) for (int c = 0; c < nchannels; c++) if (c != alpha_channel) { double f = data[c]; data[c] = T (f * (data[alpha_channel] * scale)); } } void unassalpha_to_assocalpha (int n, void *data); // Calling TIFFGetField (tif, tag, &dest) is supposed to work fine for // simple types... as long as the tag types in the file are the correct // advertised types. But for some types -- which we never expect, but // it turns out can sometimes happen, TIFFGetField will try to pull // a second argument (a void**) off the stack, and that can crash the // program! Ick. So to avoid this, we always push a pointer, which // we expect NOT to be altered, and if it is, it's a danger sign (plus // we didn't crash). bool safe_tiffgetfield (const std::string &name, int tag, void *dest) { void *ptr = NULL; // dummy -- expect it to stay NULL bool ok = TIFFGetField (m_tif, tag, dest, &ptr); if (ptr) { #ifndef NDEBUG std::cerr << "Error safe_tiffgetfield : did not expect ptr set on " << name << " " << (void *)ptr << "\n"; #endif // return false; } return ok; } // Get a string tiff tag field and put it into extra_params void get_string_attribute (const std::string &name, int tag) { char *s = NULL; if (safe_tiffgetfield (name, tag, &s)) if (s && *s) m_spec.attribute (name, s); } // Get a matrix tiff tag field and put it into extra_params void get_matrix_attribute (const std::string &name, int tag) { float *f = NULL; if (safe_tiffgetfield (name, tag, &f) && f) m_spec.attribute (name, TypeDesc::TypeMatrix, f); } // Get a float tiff tag field and put it into extra_params void get_float_attribute (const std::string &name, int tag) { float f[16]; if (safe_tiffgetfield (name, tag, f)) m_spec.attribute (name, f[0]); } // Get an int tiff tag field and put it into extra_params void get_int_attribute (const std::string &name, int tag) { int i; if (safe_tiffgetfield (name, tag, &i)) m_spec.attribute (name, i); } // Get an int tiff tag field and put it into extra_params void get_short_attribute (const std::string &name, int tag) { // Make room for two shorts, in case the tag is not the type we // expect, and libtiff writes a long instead. unsigned short s[2] = {0,0}; if (safe_tiffgetfield (name, tag, &s)) { int i = s[0]; m_spec.attribute (name, i); } } // Search for TIFF tag 'tagid' having type 'tifftype', and if found, // add it in the obvious way to m_spec under the name 'oiioname'. void find_tag (int tifftag, TIFFDataType tifftype, const char *oiioname) { #ifdef TIFF_VERSION_BIG const TIFFField *info = TIFFFindField (m_tif, tifftag, tifftype); #else const TIFFFieldInfo *info = TIFFFindFieldInfo (m_tif, tifftag, tifftype); #endif if (! info) { // Something has gone wrong, libtiff doesn't think the field type // is the same as we do. return; } if (tifftype == TIFF_ASCII) get_string_attribute (oiioname, tifftag); else if (tifftype == TIFF_SHORT) get_short_attribute (oiioname, tifftag); else if (tifftype == TIFF_LONG) get_int_attribute (oiioname, tifftag); else if (tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL || tifftype == TIFF_FLOAT || tifftype == TIFF_DOUBLE) get_float_attribute (oiioname, tifftag); } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *tiff_input_imageio_create () { return new TIFFInput; } // OIIO_EXPORT int tiff_imageio_version = OIIO_PLUGIN_VERSION; // it's in tiffoutput.cpp OIIO_EXPORT const char * tiff_input_extensions[] = { "tiff", "tif", "tx", "env", "sm", "vsm", NULL }; OIIO_PLUGIN_EXPORTS_END // Someplace to store an error message from the TIFF error handler static std::string lasterr; static mutex lasterr_mutex; static void my_error_handler (const char *str, const char *format, va_list ap) { lock_guard lock (lasterr_mutex); lasterr = Strutil::vformat (format, ap); } bool TIFFInput::valid_file (const std::string &filename) const { FILE *file = Filesystem::fopen (filename, "r"); if (! file) return false; // needs to be able to open unsigned short magic[2] = { 0, 0 }; size_t numRead = fread (magic, sizeof(unsigned short), 2, file); fclose (file); if (numRead != 2) // fread failed return false; if (magic[0] != TIFF_LITTLEENDIAN && magic[0] != TIFF_BIGENDIAN) return false; // not the right byte order if ((magic[0] == TIFF_LITTLEENDIAN) != littleendian()) swap_endian (&magic[1], 1); return (magic[1] == 42 /* Classic TIFF */ || magic[1] == 43 /* Big TIFF */); } bool TIFFInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; m_subimage = -1; return seek_subimage (0, 0, newspec); } bool TIFFInput::open (const std::string &name, ImageSpec &newspec, const ImageSpec &config) { // Check 'config' for any special requests if (config.get_int_attribute("oiio:UnassociatedAlpha", 0) == 1) m_keep_unassociated_alpha = true; return open (name, newspec); } bool TIFFInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (subimage < 0) // Illegal return false; if (m_emulate_mipmap) { // Emulating MIPmap? Pretend one subimage, many MIP levels. if (subimage != 0) return false; subimage = miplevel; } else { // No MIPmap emulation if (miplevel != 0) return false; } if (subimage == m_subimage) { // We're already pointing to the right subimage newspec = m_spec; return true; } // If we're emulating a MIPmap, only resolution is allowed to change // between MIP levels, so if we already have a valid level in m_spec, // we don't need to re-parse metadata, it's guaranteed to be the same. bool read_meta = !(m_emulate_mipmap && m_tif && m_subimage >= 0); if (! m_tif) { // Use our own error handler to keep libtiff from spewing to stderr lock_guard lock (lasterr_mutex); TIFFSetErrorHandler (my_error_handler); TIFFSetWarningHandler (my_error_handler); } if (! m_tif) { #ifdef _WIN32 std::wstring wfilename = Strutil::utf8_to_utf16 (m_filename); m_tif = TIFFOpenW (wfilename.c_str(), "rm"); #else m_tif = TIFFOpen (m_filename.c_str(), "rm"); #endif if (m_tif == NULL) { error ("Could not open file: %s", lasterr.length() ? lasterr.c_str() : m_filename.c_str()); return false; } m_subimage = 0; } m_next_scanline = 0; // next scanline we'll read if (TIFFSetDirectory (m_tif, subimage)) { m_subimage = subimage; readspec (read_meta); newspec = m_spec; if (newspec.format == TypeDesc::UNKNOWN) { error ("No support for data format of \"%s\"", m_filename.c_str()); return false; } return true; } else { error ("%s", lasterr.length() ? lasterr.c_str() : m_filename.c_str()); m_subimage = -1; return false; } } // Tags we can handle in a totally automated fasion, just copying // straight to an ImageSpec. static const TIFF_tag_info tiff_tag_table[] = { { TIFFTAG_IMAGEDESCRIPTION, "ImageDescription", TIFF_ASCII }, { TIFFTAG_ORIENTATION, "Orientation", TIFF_SHORT }, { TIFFTAG_XRESOLUTION, "XResolution", TIFF_RATIONAL }, { TIFFTAG_YRESOLUTION, "YResolution", TIFF_RATIONAL }, { TIFFTAG_RESOLUTIONUNIT, "ResolutionUnit",TIFF_SHORT }, { TIFFTAG_MAKE, "Make", TIFF_ASCII }, { TIFFTAG_MODEL, "Model", TIFF_ASCII }, { TIFFTAG_SOFTWARE, "Software", TIFF_ASCII }, { TIFFTAG_ARTIST, "Artist", TIFF_ASCII }, { TIFFTAG_COPYRIGHT, "Copyright", TIFF_ASCII }, { TIFFTAG_DATETIME, "DateTime", TIFF_ASCII }, { TIFFTAG_DOCUMENTNAME, "DocumentName", TIFF_ASCII }, { TIFFTAG_PAGENAME, "tiff:PageName", TIFF_ASCII }, { TIFFTAG_PAGENUMBER, "tiff:PageNumber", TIFF_SHORT }, { TIFFTAG_HOSTCOMPUTER, "HostComputer", TIFF_ASCII }, { TIFFTAG_PIXAR_TEXTUREFORMAT, "textureformat", TIFF_ASCII }, { TIFFTAG_PIXAR_WRAPMODES, "wrapmodes", TIFF_ASCII }, { TIFFTAG_PIXAR_FOVCOT, "fovcot", TIFF_FLOAT }, { 0, NULL, TIFF_NOTYPE } }; // Tags we may come across in the EXIF directory. static const TIFF_tag_info exif_tag_table[] = { { EXIFTAG_EXPOSURETIME, "ExposureTime", TIFF_RATIONAL }, { EXIFTAG_FNUMBER, "FNumber", TIFF_RATIONAL }, { EXIFTAG_EXPOSUREPROGRAM, "Exif:ExposureProgram", TIFF_SHORT }, // ?? translate to ascii names? { EXIFTAG_SPECTRALSENSITIVITY, "Exif:SpectralSensitivity", TIFF_ASCII }, { EXIFTAG_ISOSPEEDRATINGS, "Exif:ISOSpeedRatings", TIFF_SHORT }, { EXIFTAG_OECF, "Exif:OECF", TIFF_NOTYPE }, // skip it { EXIFTAG_EXIFVERSION, "Exif:ExifVersion", TIFF_NOTYPE }, // skip it { EXIFTAG_DATETIMEORIGINAL, "Exif:DateTimeOriginal", TIFF_ASCII }, { EXIFTAG_DATETIMEDIGITIZED,"Exif:DateTimeDigitized", TIFF_ASCII }, { EXIFTAG_COMPONENTSCONFIGURATION, "Exif:ComponentsConfiguration", TIFF_UNDEFINED }, { EXIFTAG_COMPRESSEDBITSPERPIXEL, "Exif:CompressedBitsPerPixel", TIFF_RATIONAL }, { EXIFTAG_SHUTTERSPEEDVALUE,"Exif:ShutterSpeedValue", TIFF_SRATIONAL }, // APEX units { EXIFTAG_APERTUREVALUE, "Exif:ApertureValue", TIFF_RATIONAL }, // APEX units { EXIFTAG_BRIGHTNESSVALUE, "Exif:BrightnessValue", TIFF_SRATIONAL }, { EXIFTAG_EXPOSUREBIASVALUE,"Exif:ExposureBiasValue", TIFF_SRATIONAL }, { EXIFTAG_MAXAPERTUREVALUE, "Exif:MaxApertureValue",TIFF_RATIONAL }, { EXIFTAG_SUBJECTDISTANCE, "Exif:SubjectDistance", TIFF_RATIONAL }, { EXIFTAG_METERINGMODE, "Exif:MeteringMode", TIFF_SHORT }, { EXIFTAG_LIGHTSOURCE, "Exif:LightSource", TIFF_SHORT }, { EXIFTAG_FLASH, "Exif:Flash", TIFF_SHORT }, { EXIFTAG_FOCALLENGTH, "Exif:FocalLength", TIFF_RATIONAL }, // mm { EXIFTAG_SUBJECTAREA, "Exif:SubjectArea", TIFF_NOTYPE }, // skip { EXIFTAG_MAKERNOTE, "Exif:MakerNote", TIFF_NOTYPE }, // skip it { EXIFTAG_USERCOMMENT, "Exif:UserComment", TIFF_NOTYPE }, // skip it { EXIFTAG_SUBSECTIME, "Exif:SubsecTime", TIFF_ASCII }, { EXIFTAG_SUBSECTIMEORIGINAL,"Exif:SubsecTimeOriginal", TIFF_ASCII }, { EXIFTAG_SUBSECTIMEDIGITIZED,"Exif:SubsecTimeDigitized", TIFF_ASCII }, { EXIFTAG_FLASHPIXVERSION, "Exif:FlashPixVersion", TIFF_NOTYPE }, // skip "Exif:FlashPixVesion", TIFF_NOTYPE }, { EXIFTAG_COLORSPACE, "Exif:ColorSpace", TIFF_SHORT }, { EXIFTAG_PIXELXDIMENSION, "Exif:PixelXDimension", TIFF_LONG }, { EXIFTAG_PIXELYDIMENSION, "Exif:PixelYDimension", TIFF_LONG }, { EXIFTAG_RELATEDSOUNDFILE, "Exif:RelatedSoundFile", TIFF_NOTYPE }, // skip { EXIFTAG_FLASHENERGY, "Exif:FlashEnergy", TIFF_RATIONAL }, { EXIFTAG_SPATIALFREQUENCYRESPONSE, "Exif:SpatialFrequencyResponse", TIFF_NOTYPE }, { EXIFTAG_FOCALPLANEXRESOLUTION, "Exif:FocalPlaneXResolution", TIFF_RATIONAL }, { EXIFTAG_FOCALPLANEYRESOLUTION, "Exif:FocalPlaneYResolution", TIFF_RATIONAL }, { EXIFTAG_FOCALPLANERESOLUTIONUNIT, "Exif:FocalPlaneResolutionUnit", TIFF_SHORT }, // Symbolic? { EXIFTAG_SUBJECTLOCATION, "Exif:SubjectLocation", TIFF_SHORT }, // FIXME: short[2] { EXIFTAG_EXPOSUREINDEX, "Exif:ExposureIndex", TIFF_RATIONAL }, { EXIFTAG_SENSINGMETHOD, "Exif:SensingMethod", TIFF_SHORT }, { EXIFTAG_FILESOURCE, "Exif:FileSource", TIFF_NOTYPE }, { EXIFTAG_SCENETYPE, "Exif:SceneType", TIFF_NOTYPE }, { EXIFTAG_CFAPATTERN, "Exif:CFAPattern", TIFF_NOTYPE }, { EXIFTAG_CUSTOMRENDERED, "Exif:CustomRendered", TIFF_SHORT }, { EXIFTAG_EXPOSUREMODE, "Exif:ExposureMode", TIFF_SHORT }, { EXIFTAG_WHITEBALANCE, "Exif:WhiteBalance", TIFF_SHORT }, { EXIFTAG_DIGITALZOOMRATIO, "Exif:DigitalZoomRatio",TIFF_RATIONAL }, { EXIFTAG_FOCALLENGTHIN35MMFILM, "Exif:FocalLengthIn35mmFilm", TIFF_SHORT }, { EXIFTAG_SCENECAPTURETYPE, "Exif:SceneCaptureType",TIFF_SHORT }, { EXIFTAG_GAINCONTROL, "Exif:GainControl", TIFF_RATIONAL }, { EXIFTAG_CONTRAST, "Exif:Contrast", TIFF_SHORT }, { EXIFTAG_SATURATION, "Exif:Saturation", TIFF_SHORT }, { EXIFTAG_SHARPNESS, "Exif:Sharpness", TIFF_SHORT }, { EXIFTAG_DEVICESETTINGDESCRIPTION, "Exif:DeviceSettingDescription", TIFF_NOTYPE }, { EXIFTAG_SUBJECTDISTANCERANGE, "Exif:SubjectDistanceRange", TIFF_SHORT }, { EXIFTAG_IMAGEUNIQUEID, "Exif:ImageUniqueID", TIFF_ASCII }, { 0, NULL, TIFF_NOTYPE } }; void TIFFInput::readspec (bool read_meta) { uint32 width = 0, height = 0, depth = 0; unsigned short nchans = 1; TIFFGetField (m_tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField (m_tif, TIFFTAG_IMAGELENGTH, &height); TIFFGetFieldDefaulted (m_tif, TIFFTAG_IMAGEDEPTH, &depth); TIFFGetFieldDefaulted (m_tif, TIFFTAG_SAMPLESPERPIXEL, &nchans); if (read_meta) { // clear the whole m_spec and start fresh m_spec = ImageSpec ((int)width, (int)height, (int)nchans); } else { // assume m_spec is valid, except for things that might differ // between MIP levels m_spec.width = (int)width; m_spec.height = (int)height; m_spec.depth = (int)depth; m_spec.full_x = 0; m_spec.full_y = 0; m_spec.full_z = 0; m_spec.full_width = (int)width; m_spec.full_height = (int)height; m_spec.full_depth = (int)depth; m_spec.nchannels = (int)nchans; } float x = 0, y = 0; TIFFGetField (m_tif, TIFFTAG_XPOSITION, &x); TIFFGetField (m_tif, TIFFTAG_YPOSITION, &y); m_spec.x = (int)x; m_spec.y = (int)y; m_spec.z = 0; // FIXME? - TIFF spec describes the positions as in resolutionunit. // What happens if this is not unitless pixels? Are we interpreting // it all wrong? if (TIFFGetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLWIDTH, &width) == 1 && width > 0) m_spec.full_width = width; if (TIFFGetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLLENGTH, &height) == 1 && height > 0) m_spec.full_height = height; if (TIFFIsTiled (m_tif)) { TIFFGetField (m_tif, TIFFTAG_TILEWIDTH, &m_spec.tile_width); TIFFGetField (m_tif, TIFFTAG_TILELENGTH, &m_spec.tile_height); TIFFGetFieldDefaulted (m_tif, TIFFTAG_TILEDEPTH, &m_spec.tile_depth); } else { m_spec.tile_width = 0; m_spec.tile_height = 0; m_spec.tile_depth = 0; } m_bitspersample = 8; TIFFGetField (m_tif, TIFFTAG_BITSPERSAMPLE, &m_bitspersample); m_spec.attribute ("oiio:BitsPerSample", (int)m_bitspersample); unsigned short sampleformat = SAMPLEFORMAT_UINT; TIFFGetFieldDefaulted (m_tif, TIFFTAG_SAMPLEFORMAT, &sampleformat); switch (m_bitspersample) { case 1: case 2: case 4: case 6: // Make 1, 2, 4, 6 bpp look like byte images case 8: if (sampleformat == SAMPLEFORMAT_UINT) m_spec.set_format (TypeDesc::UINT8); else if (sampleformat == SAMPLEFORMAT_INT) m_spec.set_format (TypeDesc::INT8); else m_spec.set_format (TypeDesc::UINT8); // punt break; case 10: case 12: case 14: // Make 10, 12, 14 bpp look like 16 bit images case 16: if (sampleformat == SAMPLEFORMAT_UINT) m_spec.set_format (TypeDesc::UINT16); else if (sampleformat == SAMPLEFORMAT_INT) m_spec.set_format (TypeDesc::INT16); else if (sampleformat == SAMPLEFORMAT_IEEEFP) { m_spec.set_format (TypeDesc::HALF); // Adobe extension, see http://chriscox.org/TIFFTN3d1.pdf } else m_spec.set_format (TypeDesc::UNKNOWN); break; case 32: if (sampleformat == SAMPLEFORMAT_IEEEFP) m_spec.set_format (TypeDesc::FLOAT); else if (sampleformat == SAMPLEFORMAT_UINT) m_spec.set_format (TypeDesc::UINT32); else if (sampleformat == SAMPLEFORMAT_INT) m_spec.set_format (TypeDesc::INT32); else m_spec.set_format (TypeDesc::UNKNOWN); break; case 64: if (sampleformat == SAMPLEFORMAT_IEEEFP) m_spec.set_format (TypeDesc::DOUBLE); else m_spec.set_format (TypeDesc::UNKNOWN); break; default: m_spec.set_format (TypeDesc::UNKNOWN); break; } // If we've been instructed to skip reading metadata, because it is // guaranteed to be identical to what we already have in m_spec, // skip everything following. if (! read_meta) return; // Use the table for all the obvious things that can be mindlessly // shoved into the image spec. for (int i = 0; tiff_tag_table[i].name; ++i) find_tag (tiff_tag_table[i].tifftag, tiff_tag_table[i].tifftype, tiff_tag_table[i].name); // Now we need to get fields "by hand" for anything else that is less // straightforward... m_photometric = (m_spec.nchannels == 1 ? PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB); TIFFGetField (m_tif, TIFFTAG_PHOTOMETRIC, &m_photometric); m_spec.attribute ("tiff:PhotometricInterpretation", (int)m_photometric); if (m_photometric == PHOTOMETRIC_PALETTE) { // Read the color map unsigned short *r = NULL, *g = NULL, *b = NULL; TIFFGetField (m_tif, TIFFTAG_COLORMAP, &r, &g, &b); ASSERT (r != NULL && g != NULL && b != NULL); m_colormap.clear (); m_colormap.insert (m_colormap.end(), r, r + (1 << m_bitspersample)); m_colormap.insert (m_colormap.end(), g, g + (1 << m_bitspersample)); m_colormap.insert (m_colormap.end(), b, b + (1 << m_bitspersample)); // Palette TIFF images are always 3 channels (to the client) m_spec.nchannels = 3; m_spec.default_channel_names (); // FIXME - what about palette + extra (alpha?) channels? Is that // allowed? And if so, ever encountered in the wild? } TIFFGetFieldDefaulted (m_tif, TIFFTAG_PLANARCONFIG, &m_planarconfig); m_separate = (m_planarconfig == PLANARCONFIG_SEPARATE && m_spec.nchannels > 1 && m_photometric != PHOTOMETRIC_PALETTE); m_spec.attribute ("tiff:PlanarConfiguration", (int)m_planarconfig); if (m_planarconfig == PLANARCONFIG_SEPARATE) m_spec.attribute ("planarconfig", "separate"); else m_spec.attribute ("planarconfig", "contig"); int compress = 0; TIFFGetFieldDefaulted (m_tif, TIFFTAG_COMPRESSION, &compress); m_spec.attribute ("tiff:Compression", compress); switch (compress) { case COMPRESSION_NONE : m_spec.attribute ("compression", "none"); break; case COMPRESSION_LZW : m_spec.attribute ("compression", "lzw"); break; case COMPRESSION_CCITTRLE : m_spec.attribute ("compression", "ccittrle"); break; case COMPRESSION_DEFLATE : case COMPRESSION_ADOBE_DEFLATE : m_spec.attribute ("compression", "zip"); break; case COMPRESSION_PACKBITS : m_spec.attribute ("compression", "packbits"); break; default: break; } int rowsperstrip = -1; if (! m_spec.tile_width) { TIFFGetField (m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); if (rowsperstrip > 0) m_spec.attribute ("tiff:RowsPerStrip", rowsperstrip); } // The libtiff docs say that only uncompressed images, or those with // rowsperstrip==1, support random access to scanlines. m_no_random_access = (compress != COMPRESSION_NONE && rowsperstrip != 1); short resunit = -1; TIFFGetField (m_tif, TIFFTAG_RESOLUTIONUNIT, &resunit); switch (resunit) { case RESUNIT_NONE : m_spec.attribute ("ResolutionUnit", "none"); break; case RESUNIT_INCH : m_spec.attribute ("ResolutionUnit", "in"); break; case RESUNIT_CENTIMETER : m_spec.attribute ("ResolutionUnit", "cm"); break; } get_matrix_attribute ("worldtocamera", TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA); get_matrix_attribute ("worldtoscreen", TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN); get_int_attribute ("tiff:subfiletype", TIFFTAG_SUBFILETYPE); // FIXME -- should subfiletype be "conventionized" and used for all // plugins uniformly? // Do we care about fillorder? No, the TIFF spec says, "We // recommend that FillOrder=2 (lsb-to-msb) be used only in // special-purpose applications". So OIIO will assume msb-to-lsb // convention until somebody finds a TIFF file in the wild that // breaks this assumption. // Special names for shadow maps char *s = NULL; TIFFGetField (m_tif, TIFFTAG_PIXAR_TEXTUREFORMAT, &s); if (s) m_emulate_mipmap = true; if (s && ! strcmp (s, "Shadow")) { for (int c = 0; c < m_spec.nchannels; ++c) m_spec.channelnames[c] = "z"; } unsigned short *sampleinfo = NULL; unsigned short extrasamples = 0; TIFFGetFieldDefaulted (m_tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo); // std::cerr << "Extra samples = " << extrasamples << "\n"; bool alpha_is_unassociated = false; // basic assumption if (extrasamples) { // If the TIFF ExtraSamples tag was specified, use that to figure // out the meaning of alpha. int colorchannels = 3; if (m_photometric == PHOTOMETRIC_MINISWHITE || m_photometric == PHOTOMETRIC_MINISBLACK || m_photometric == PHOTOMETRIC_PALETTE || m_photometric == PHOTOMETRIC_MASK) colorchannels = 1; for (int i = 0, c = colorchannels; i < extrasamples && c < m_spec.nchannels; ++i, ++c) { // std::cerr << " extra " << i << " " << sampleinfo[i] << "\n"; if (sampleinfo[i] == EXTRASAMPLE_ASSOCALPHA) { // This is the alpha channel, associated as usual m_spec.alpha_channel = c; } else if (sampleinfo[i] == EXTRASAMPLE_UNASSALPHA) { // This is the alpha channel, but color is unassociated m_spec.alpha_channel = c; alpha_is_unassociated = true; if (m_keep_unassociated_alpha) m_spec.attribute ("oiio:UnassociatedAlpha", 1); } else { DASSERT (sampleinfo[i] == EXTRASAMPLE_UNSPECIFIED); // This extra channel is not alpha at all. Undo any // assumptions we previously made about this channel. if (m_spec.alpha_channel == c) { m_spec.channelnames[c] = Strutil::format("channel%d", c); m_spec.alpha_channel = -1; } } } if (m_spec.alpha_channel >= 0) m_spec.channelnames[m_spec.alpha_channel] = "A"; } // Will we need to do alpha conversions? m_convert_alpha = (m_spec.alpha_channel >= 0 && alpha_is_unassociated && ! m_keep_unassociated_alpha); // N.B. we currently ignore the following TIFF fields: // GrayResponseCurve GrayResponseUnit // MaxSampleValue MinSampleValue // NewSubfileType SubfileType(deprecated) // Colorimetry fields // Search for an EXIF IFD in the TIFF file, and if found, rummage // around for Exif fields. #if TIFFLIB_VERSION > 20050912 /* compat with old TIFF libs - skip Exif */ toff_t exifoffset = 0; if (TIFFGetField (m_tif, TIFFTAG_EXIFIFD, &exifoffset) && TIFFReadEXIFDirectory (m_tif, exifoffset)) { for (int i = 0; exif_tag_table[i].name; ++i) find_tag (exif_tag_table[i].tifftag, exif_tag_table[i].tifftype, exif_tag_table[i].name); // I'm not sure what state TIFFReadEXIFDirectory leaves us. // So to be safe, close and re-seek. TIFFClose (m_tif); #ifdef _WIN32 std::wstring wfilename = Strutil::utf8_to_utf16 (m_filename); m_tif = TIFFOpenW (wfilename.c_str(), "rm"); #else m_tif = TIFFOpen (m_filename.c_str(), "rm"); #endif TIFFSetDirectory (m_tif, m_subimage); // A few tidbits to look for ImageIOParameter *p; if ((p = m_spec.find_attribute ("Exif:ColorSpace", TypeDesc::INT))) { // Exif spec says that anything other than 0xffff==uncalibrated // should be interpreted to be sRGB. if (*(const int *)p->data() != 0xffff) m_spec.attribute ("oiio::ColorSpace", "sRGB"); } } #endif #if TIFFLIB_VERSION >= 20051230 // Search for IPTC metadata in IIM form -- but older versions of // libtiff botch the size, so ignore it for very old libtiff. int iptcsize = 0; const void *iptcdata = NULL; if (TIFFGetField (m_tif, TIFFTAG_RICHTIFFIPTC, &iptcsize, &iptcdata)) { std::vector iptc ((uint32 *)iptcdata, (uint32 *)iptcdata+iptcsize); if (TIFFIsByteSwapped (m_tif)) TIFFSwabArrayOfLong ((uint32*)&iptc[0], iptcsize); decode_iptc_iim (&iptc[0], iptcsize*4, m_spec); } #endif // Search for an XML packet containing XMP (IPTC, Exif, etc.) int xmlsize = 0; const void *xmldata = NULL; if (TIFFGetField (m_tif, TIFFTAG_XMLPACKET, &xmlsize, &xmldata)) { // std::cerr << "Found XML data, size " << xmlsize << "\n"; if (xmldata && xmlsize) { std::string xml ((const char *)xmldata, xmlsize); decode_xmp (xml, m_spec); } } #if 0 // Experimental -- look for photoshop data int photoshopsize = 0; const void *photoshopdata = NULL; if (TIFFGetField (m_tif, TIFFTAG_PHOTOSHOP, &photoshopsize, &photoshopdata)) { std::cerr << "Found PHOTOSHOP data, size " << photoshopsize << "\n"; if (photoshopdata && photoshopsize) { // std::string photoshop ((const char *)photoshopdata, photoshopsize); // std::cerr << "PHOTOSHOP:\n" << photoshop << "\n---\n"; } } #endif } bool TIFFInput::close () { close_tif (); init(); // Reset to initial state return true; } /// Helper: Convert n pixels from separate (RRRGGGBBB) to contiguous /// (RGBRGBRGB) planarconfig. void TIFFInput::separate_to_contig (int n, const unsigned char *separate, unsigned char *contig) { int channelbytes = m_spec.channel_bytes(); for (int p = 0; p < n; ++p) // loop over pixels for (int c = 0; c < m_spec.nchannels; ++c) // loop over channels for (int i = 0; i < channelbytes; ++i) // loop over data bytes contig[(p*m_spec.nchannels+c)*channelbytes+i] = separate[(c*n+p)*channelbytes+i]; } void TIFFInput::palette_to_rgb (int n, const unsigned char *palettepels, unsigned char *rgb) { size_t vals_per_byte = 8 / m_bitspersample; size_t entries = 1 << m_bitspersample; int highest = entries-1; DASSERT (m_spec.nchannels == 3); DASSERT (m_colormap.size() == 3*entries); for (int x = 0; x < n; ++x) { int i = palettepels[x/vals_per_byte]; i >>= (m_bitspersample * (vals_per_byte - 1 - (x % vals_per_byte))); i &= highest; *rgb++ = m_colormap[0*entries+i] / 257; *rgb++ = m_colormap[1*entries+i] / 257; *rgb++ = m_colormap[2*entries+i] / 257; } } void TIFFInput::bit_convert (int n, const unsigned char *in, int inbits, void *out, int outbits) { ASSERT (inbits >= 1 && inbits < 31); // surely bugs if not int highest = (1 << inbits) - 1; int B = 0, b = 0; // Invariant: // So far, we have used in[0..B-1] and the high b bits of in[B]. for (int i = 0; i < n; ++i) { long long val = 0; int valbits = 0; // bits so far we've accumulated in val while (valbits < inbits) { // Invariant: we have already accumulated valbits of the next // needed value (of a total of inbits), living in the valbits // low bits of val. int out_left = inbits - valbits; // How much more we still need int in_left = 8 - b; // Bits still available in in[B]. if (in_left <= out_left) { // Eat the rest of this byte: // |---------|--------| // b in_left val <<= in_left; val |= in[B] & ~(0xffffffff << in_left); ++B; b = 0; valbits += in_left; } else { // Eat just the bits we need: // |--|---------|-----| // b out_left extra val <<= out_left; int extra = 8 - b - out_left; val |= (in[B] >> extra) & ~(0xffffffff << out_left); b += out_left; valbits = inbits; } } if (outbits == 8) ((unsigned char *)out)[i] = (unsigned char) ((val * 0xff) / highest); else if (outbits == 16) ((unsigned short *)out)[i] = (unsigned short) ((val * 0xffff) / highest); else ((unsigned int *)out)[i] = (unsigned int) ((val * 0xffffffff) / highest); } } void TIFFInput::invert_photometric (int n, void *data) { switch (m_spec.format.basetype) { case TypeDesc::UINT8: { unsigned char *d = (unsigned char *) data; for (int i = 0; i < n; ++i) d[i] = 255 - d[i]; break; } default: break; } } void TIFFInput::unassalpha_to_assocalpha (int n, void *data) { switch (m_spec.format.basetype) { case TypeDesc::UINT8: unassociate ((unsigned char *)data, n, m_spec.nchannels, m_spec.alpha_channel); break; case TypeDesc::INT8: unassociate ((char *)data, n, m_spec.nchannels, m_spec.alpha_channel); break; case TypeDesc::UINT16: unassociate ((unsigned short *)data, n, m_spec.nchannels, m_spec.alpha_channel); break; case TypeDesc::INT16: unassociate ((short *)data, n, m_spec.nchannels, m_spec.alpha_channel); break; case TypeDesc::FLOAT: unassociate ((float *)data, n, m_spec.nchannels, m_spec.alpha_channel); break; case TypeDesc::DOUBLE: unassociate ((double *)data, n, m_spec.nchannels, m_spec.alpha_channel); break; default: break; } } bool TIFFInput::read_native_scanline (int y, int z, void *data) { y -= m_spec.y; // For compression modes that don't support random access to scanlines // (which I *think* is only LZW), we need to emulate random access by // re-seeking. if (m_no_random_access) { if (m_next_scanline > y) { // User is trying to read an earlier scanline than the one we're // up to. Easy fix: start over. // FIXME: I'm too tired to look into it now, but I wonder if // it is able to randomly seek to the first line in any // "strip", in which case we don't need to start from 0, just // start from the beginning of the strip we need. ImageSpec dummyspec; int old_subimage = current_subimage(); int old_miplevel = current_miplevel(); if (! close () || ! open (m_filename, dummyspec) || ! seek_subimage (old_subimage, old_miplevel, dummyspec)) { return false; // Somehow, the re-open failed } ASSERT (m_next_scanline == 0 && current_subimage() == old_subimage && current_miplevel() == old_miplevel); } while (m_next_scanline < y) { // Keep reading until we're read the scanline we really need m_scratch.resize (m_spec.scanline_bytes()); if (TIFFReadScanline (m_tif, &m_scratch[0], m_next_scanline) < 0) { error ("%s", lasterr.c_str()); return false; } ++m_next_scanline; } } m_next_scanline = y+1; int nvals = m_spec.width * m_spec.nchannels; m_scratch.resize (m_spec.scanline_bytes()); bool no_bit_convert = (m_bitspersample == 8 || m_bitspersample == 16 || m_bitspersample == 32); if (m_photometric == PHOTOMETRIC_PALETTE) { // Convert from palette to RGB if (TIFFReadScanline (m_tif, &m_scratch[0], y) < 0) { error ("%s", lasterr.c_str()); return false; } palette_to_rgb (m_spec.width, &m_scratch[0], (unsigned char *)data); } else { // Not palette int plane_bytes = m_spec.width * m_spec.format.size(); int planes = m_separate ? m_spec.nchannels : 1; std::vector scratch2 (m_separate ? m_spec.scanline_bytes() : 0); // Where to read? Directly into user data if no channel shuffling // or bit shifting is needed, otherwise into scratch space. unsigned char *readbuf = (no_bit_convert && !m_separate) ? (unsigned char *)data : &m_scratch[0]; // Perform the reads. Note that for contig, planes==1, so it will // only do one TIFFReadScanline. for (int c = 0; c < planes; ++c) /* planes==1 for contig */ if (TIFFReadScanline (m_tif, &readbuf[plane_bytes*c], y, c) < 0) { error ("%s", lasterr.c_str()); return false; } if (m_bitspersample < 8) { // m_scratch now holds nvals n-bit values, contig or separate std::swap (m_scratch, scratch2); for (int c = 0; c < planes; ++c) /* planes==1 for contig */ bit_convert (m_separate ? m_spec.width : nvals, &scratch2[plane_bytes*c], m_bitspersample, m_separate ? &m_scratch[plane_bytes*c] : (unsigned char *)data+plane_bytes*c, 8); } else if (m_bitspersample > 8 && m_bitspersample < 16) { // m_scratch now holds nvals n-bit values, contig or separate std::swap (m_scratch, scratch2); for (int c = 0; c < planes; ++c) /* planes==1 for contig */ bit_convert (m_separate ? m_spec.width : nvals, &scratch2[plane_bytes*c], m_bitspersample, m_separate ? &m_scratch[plane_bytes*c] : (unsigned char *)data+plane_bytes*c, 16); } if (m_separate) { // Convert from separate (RRRGGGBBB) to contiguous (RGBRGBRGB). // We know the data is in m_scratch at this point, so // contiguize it into the user data area. separate_to_contig (m_spec.width, &m_scratch[0], (unsigned char *)data); } } if (m_photometric == PHOTOMETRIC_MINISWHITE) invert_photometric (nvals, data); // If alpha is unassociated and we aren't requested to keep it that // way, multiply the colors by alpha per the usual OIIO conventions // to deliver associated color & alpha. if (m_convert_alpha) unassalpha_to_assocalpha (m_spec.width, data); return true; } bool TIFFInput::read_native_tile (int x, int y, int z, void *data) { x -= m_spec.x; y -= m_spec.y; imagesize_t tile_pixels = m_spec.tile_pixels(); imagesize_t nvals = tile_pixels * m_spec.nchannels; m_scratch.resize (m_spec.tile_bytes()); bool no_bit_convert = (m_bitspersample == 8 || m_bitspersample == 16 || m_bitspersample == 32); if (m_photometric == PHOTOMETRIC_PALETTE) { // Convert from palette to RGB if (TIFFReadTile (m_tif, &m_scratch[0], x, y, z, 0) < 0) { error ("%s", lasterr.c_str()); return false; } palette_to_rgb (tile_pixels, &m_scratch[0], (unsigned char *)data); } else { // Not palette imagesize_t plane_bytes = m_spec.tile_pixels() * m_spec.format.size(); int planes = m_separate ? m_spec.nchannels : 1; std::vector scratch2 (m_separate ? m_spec.tile_bytes() : 0); // Where to read? Directly into user data if no channel shuffling // or bit shifting is needed, otherwise into scratch space. unsigned char *readbuf = (no_bit_convert && !m_separate) ? (unsigned char *)data : &m_scratch[0]; // Perform the reads. Note that for contig, planes==1, so it will // only do one TIFFReadTile. for (int c = 0; c < planes; ++c) /* planes==1 for contig */ if (TIFFReadTile (m_tif, &readbuf[plane_bytes*c], x, y, z, c) < 0) { error ("%s", lasterr.c_str()); return false; } if (m_bitspersample < 8) { // m_scratch now holds nvals n-bit values, contig or separate std::swap (m_scratch, scratch2); for (int c = 0; c < planes; ++c) /* planes==1 for contig */ bit_convert (m_separate ? tile_pixels : nvals, &scratch2[plane_bytes*c], m_bitspersample, m_separate ? &m_scratch[plane_bytes*c] : (unsigned char *)data+plane_bytes*c, 8); } else if (m_bitspersample > 8 && m_bitspersample < 16) { // m_scratch now holds nvals n-bit values, contig or separate std::swap (m_scratch, scratch2); for (int c = 0; c < planes; ++c) /* planes==1 for contig */ bit_convert (m_separate ? tile_pixels : nvals, &scratch2[plane_bytes*c], m_bitspersample, m_separate ? &m_scratch[plane_bytes*c] : (unsigned char *)data+plane_bytes*c, 16); } if (m_separate) { // Convert from separate (RRRGGGBBB) to contiguous (RGBRGBRGB). // We know the data is in m_scratch at this point, so // contiguize it into the user data area. separate_to_contig (tile_pixels, &m_scratch[0], (unsigned char *)data); } } if (m_photometric == PHOTOMETRIC_MINISWHITE) invert_photometric (tile_pixels, data); // If alpha is unassociated and we aren't requested to keep it that // way, multiply the colors by alpha per the usual OIIO conventions // to deliver associated color & alpha. if (m_convert_alpha) unassalpha_to_assocalpha (tile_pixels, data); return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/tiff.imageio/CMakeLists.txt0000644000175000017500000000044212271062644022211 0ustar mfvmfvfind_package (TIFF) find_package (JPEG) find_package (ZLIB) if (TIFF_FOUND AND JPEG_FOUND AND ZLIB_FOUND) include_directories (${TIFF_INCLUDE_DIR}) add_oiio_plugin (tiffinput.cpp tiffoutput.cpp LINK_LIBRARIES ${TIFF_LIBRARIES} ${JPEG_LIBRARIES} ${ZLIB_LIBRARIES}) endif () openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/0000755000175000017500000000000012271062644017314 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/dpx.imageio/dpxinput.cpp0000644000175000017500000006365712271062644021714 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "libdpx/DPX.h" #include "libdpx/DPXColorConverter.h" #include //For TimeCode support #include "typedesc.h" #include "imageio.h" #include "fmath.h" #include "strutil.h" #include OIIO_PLUGIN_NAMESPACE_BEGIN class DPXInput : public ImageInput { public: DPXInput () : m_stream(NULL), m_dataPtr(NULL) { init(); } virtual ~DPXInput () { close(); } virtual const char * format_name (void) const { return "dpx"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (); virtual int current_subimage (void) const { return m_subimage; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual bool read_native_scanline (int y, int z, void *data); private: int m_subimage; InStream *m_stream; dpx::Reader m_dpx; std::vector m_userBuf; bool m_wantRaw; unsigned char *m_dataPtr; /// Reset everything to initial state /// void init () { if (m_stream) { m_stream->Close (); delete m_stream; m_stream = NULL; } delete m_dataPtr; m_dataPtr = NULL; m_userBuf.clear (); } /// Helper function - retrieve string for libdpx characteristic /// std::string get_characteristic_string (dpx::Characteristic c); /// Helper function - retrieve string for libdpx descriptor /// std::string get_descriptor_string (dpx::Descriptor c); /// Helper function - fill int array with KeyCode values /// void get_keycode_values (int *array); /// Helper function - convert Imf::TimeCode to string; /// std::string get_timecode_string (Imf::TimeCode &tc); }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *dpx_input_imageio_create () { return new DPXInput; } OIIO_EXPORT int dpx_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * dpx_input_extensions[] = { "dpx", NULL }; OIIO_PLUGIN_EXPORTS_END bool DPXInput::valid_file (const std::string &filename) const { InStream *stream = new InStream(); if (! stream) return false; bool ok = false; if (stream->Open(filename.c_str())) { dpx::Reader dpx; dpx.SetInStream(stream); ok = dpx.ReadHeader(); stream->Close(); } delete stream; return ok; } bool DPXInput::open (const std::string &name, ImageSpec &newspec) { // open the image m_stream = new InStream(); if (! m_stream->Open(name.c_str())) { error ("Could not open file \"%s\"", name.c_str()); return false; } m_dpx.SetInStream(m_stream); if (! m_dpx.ReadHeader()) { error ("Could not read header"); return false; } bool ok = seek_subimage (0, 0, newspec); newspec = spec (); return ok; } bool DPXInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (miplevel != 0) return false; if (subimage < 0 || subimage >= m_dpx.header.ImageElementCount ()) return false; m_subimage = subimage; // check if the client asked us for raw data m_wantRaw = newspec.get_int_attribute ("dpx:RawData", 0) != 0; // create imagespec TypeDesc typedesc; switch (m_dpx.header.ComponentDataSize(subimage)) { case dpx::kByte: typedesc = m_dpx.header.DataSign (subimage) ? TypeDesc::INT8 : TypeDesc::UINT8; break; case dpx::kWord: typedesc = m_dpx.header.DataSign (subimage) ? TypeDesc::INT16 : TypeDesc::UINT16; break; case dpx::kInt: typedesc = m_dpx.header.DataSign (subimage) ? TypeDesc::INT32 : TypeDesc::UINT32; break; case dpx::kFloat: typedesc = TypeDesc::FLOAT; break; case dpx::kDouble: typedesc = TypeDesc::DOUBLE; break; default: error ("Invalid component data size"); return false; } m_spec = ImageSpec (m_dpx.header.Width(), m_dpx.header.Height(), m_dpx.header.ImageElementComponentCount(subimage), typedesc); m_spec.x = m_dpx.header.xOffset; m_spec.y = m_dpx.header.yOffset; if ((int)m_dpx.header.xOriginalSize > 0) m_spec.full_width = m_dpx.header.xOriginalSize; if ((int)m_dpx.header.yOriginalSize > 0) m_spec.full_height = m_dpx.header.yOriginalSize; // fill channel names m_spec.channelnames.clear (); switch (m_dpx.header.ImageDescriptor(subimage)) { /*case dpx::kUserDefinedDescriptor: break;*/ case dpx::kRed: m_spec.channelnames.push_back("R"); break; case dpx::kGreen: m_spec.channelnames.push_back("G"); break; case dpx::kBlue: m_spec.channelnames.push_back("B"); break; case dpx::kAlpha: m_spec.channelnames.push_back("A"); m_spec.alpha_channel = 0; break; case dpx::kLuma: // FIXME: do we treat this as intensity or do we use Y' as per // convention to differentiate it from linear luminance? m_spec.channelnames.push_back("Y'"); break; case dpx::kDepth: m_spec.channelnames.push_back("Z"); m_spec.z_channel = 0; break; /*case dpx::kCompositeVideo: break;*/ case dpx::kRGB: case dpx::kRGBA: case dpx::kABGR: // colour converter will swap the bytes for us m_spec.default_channel_names (); break; case dpx::kCbYCrY: if (m_wantRaw) { m_spec.channelnames.push_back("CbCr"); m_spec.channelnames.push_back("Y"); } else { m_spec.nchannels = 3; m_spec.default_channel_names (); } break; case dpx::kCbYACrYA: if (m_wantRaw) { m_spec.channelnames.push_back("CbCr"); m_spec.channelnames.push_back("Y"); m_spec.channelnames.push_back("A"); m_spec.alpha_channel = 2; } else { m_spec.nchannels = 4; m_spec.default_channel_names (); } break; case dpx::kCbYCr: if (m_wantRaw) { m_spec.channelnames.push_back("Cb"); m_spec.channelnames.push_back("Y"); m_spec.channelnames.push_back("Cr"); } else m_spec.default_channel_names (); break; case dpx::kCbYCrA: if (m_wantRaw) { m_spec.channelnames.push_back("Cb"); m_spec.channelnames.push_back("Y"); m_spec.channelnames.push_back("Cr"); m_spec.channelnames.push_back("A"); m_spec.alpha_channel = 3; } else { m_spec.default_channel_names (); } break; default: { for (int i = 0; i < m_dpx.header.ImageElementComponentCount(subimage); i++) { std::string ch = Strutil::format("channel%d", i); m_spec.channelnames.push_back(ch); } } } // bits per pixel m_spec.attribute ("oiio:BitsPerSample", m_dpx.header.BitDepth(subimage)); // image orientation - see appendix B.2 of the OIIO documentation int orientation; switch (m_dpx.header.ImageOrientation ()) { case dpx::kLeftToRightTopToBottom: orientation = 1; break; case dpx::kRightToLeftTopToBottom: orientation = 2; break; case dpx::kLeftToRightBottomToTop: orientation = 4; break; case dpx::kRightToLeftBottomToTop: orientation = 3; break; case dpx::kTopToBottomLeftToRight: orientation = 5; break; case dpx::kTopToBottomRightToLeft: orientation = 6; break; case dpx::kBottomToTopLeftToRight: orientation = 8; break; case dpx::kBottomToTopRightToLeft: orientation = 7; break; default: orientation = 0; break; } m_spec.attribute ("Orientation", orientation); // image linearity switch (m_dpx.header.Transfer (subimage)) { case dpx::kLinear: m_spec.attribute ("oiio:ColorSpace", "Linear"); break; case dpx::kLogarithmic: m_spec.attribute ("oiio:ColorSpace", "KodakLog"); break; case dpx::kITUR709: m_spec.attribute ("oiio:ColorSpace", "Rec709"); break; case dpx::kUserDefined: if (! isnan (m_dpx.header.Gamma ()) && m_dpx.header.Gamma () != 0) { m_spec.attribute ("oiio:ColorSpace", "GammaCorrected"); m_spec.attribute ("oiio:Gamma", (float) m_dpx.header.Gamma ()); break; } // intentional fall-through /*case dpx::kPrintingDensity: case dpx::kUnspecifiedVideo: case dpx::kSMPTE274M: case dpx::kITUR601: case dpx::kITUR602: case dpx::kNTSCCompositeVideo: case dpx::kPALCompositeVideo: case dpx::kZLinear: case dpx::kZHomogeneous: case dpx::kUndefinedCharacteristic:*/ default: break; } m_spec.attribute ("dpx:Transfer", get_characteristic_string (m_dpx.header.Transfer (subimage))); // colorimetric characteristic m_spec.attribute ("dpx:Colorimetric", get_characteristic_string (m_dpx.header.Colorimetric (subimage))); // general metadata // some non-compliant writers will dump a field filled with 0xFF rather // than a NULL string termination on the first character, so take that // into account, too if (m_dpx.header.copyright[0] && m_dpx.header.copyright[0] != (char)0xFF) m_spec.attribute ("Copyright", m_dpx.header.copyright); if (m_dpx.header.creator[0] && m_dpx.header.creator[0] != (char)0xFF) m_spec.attribute ("Software", m_dpx.header.creator); if (m_dpx.header.project[0] && m_dpx.header.project[0] != (char)0xFF) m_spec.attribute ("DocumentName", m_dpx.header.project); if (m_dpx.header.creationTimeDate[0]) { // libdpx's date/time format is pretty close to OIIO's (libdpx uses // %Y:%m:%d:%H:%M:%S%Z) char date[24]; Strutil::safe_strcpy(date, m_dpx.header.creationTimeDate, sizeof(date)); date[10] = ' '; date[19] = 0; m_spec.attribute ("DateTime", date); } if (m_dpx.header.ImageEncoding (subimage) == dpx::kRLE) m_spec.attribute ("compression", "rle"); char buf[32 + 1]; m_dpx.header.Description (subimage, buf); if (buf[0] && buf[0] != -1) m_spec.attribute ("ImageDescription", buf); m_spec.attribute ("PixelAspectRatio", m_dpx.header.AspectRatio(0) / (float)m_dpx.header.AspectRatio(1)); // DPX-specific metadata m_spec.attribute ("dpx:ImageDescriptor", get_descriptor_string (m_dpx.header.ImageDescriptor (subimage))); // save some typing by using macros // "internal" macros #define DPX_SET_ATTRIB_S(x, n, s) m_spec.attribute (s, \ m_dpx.header.x (n)) #define DPX_SET_ATTRIB(x, n) DPX_SET_ATTRIB_S(x, n, "dpx:" #x) // set without checking for bogus attributes #define DPX_SET_ATTRIB_N(x) DPX_SET_ATTRIB(x, subimage) // set with checking for bogus attributes #define DPX_SET_ATTRIB_BYTE(x) if (m_dpx.header.x () != 0xFF) \ DPX_SET_ATTRIB(x, ) #define DPX_SET_ATTRIB_INT_N(x) if (m_dpx.header.x (subimage) != 0xFFFFFFFF) \ DPX_SET_ATTRIB(x, subimage) #define DPX_SET_ATTRIB_INT(x) if (m_dpx.header.x () != 0xFFFFFFFF) \ DPX_SET_ATTRIB(x, ) #define DPX_SET_ATTRIB_FLOAT_N(x) if (! isnan(m_dpx.header.x (subimage))) \ DPX_SET_ATTRIB(x, subimage) #define DPX_SET_ATTRIB_FLOAT(x) if (! isnan(m_dpx.header.x ())) \ DPX_SET_ATTRIB(x, ) // see comment above Copyright, Software and DocumentName #define DPX_SET_ATTRIB_STR(X, x) if (m_dpx.header.x[0] \ && m_dpx.header.x[0] != -1) \ m_spec.attribute ("dpx:" #X, \ m_dpx.header.x) DPX_SET_ATTRIB_INT(EncryptKey); DPX_SET_ATTRIB_INT(DittoKey); DPX_SET_ATTRIB_INT_N(LowData); DPX_SET_ATTRIB_FLOAT_N(LowQuantity); DPX_SET_ATTRIB_INT_N(HighData); DPX_SET_ATTRIB_FLOAT_N(HighQuantity); DPX_SET_ATTRIB_INT_N(EndOfLinePadding); DPX_SET_ATTRIB_INT_N(EndOfImagePadding); DPX_SET_ATTRIB_FLOAT(XScannedSize); DPX_SET_ATTRIB_FLOAT(YScannedSize); DPX_SET_ATTRIB_INT(FramePosition); DPX_SET_ATTRIB_INT(SequenceLength); DPX_SET_ATTRIB_INT(HeldCount); DPX_SET_ATTRIB_FLOAT(FrameRate); DPX_SET_ATTRIB_FLOAT(ShutterAngle); DPX_SET_ATTRIB_STR(Version, version); DPX_SET_ATTRIB_STR(Format, format); DPX_SET_ATTRIB_STR(FrameId, frameId); DPX_SET_ATTRIB_STR(SlateInfo, slateInfo); DPX_SET_ATTRIB_STR(SourceImageFileName, sourceImageFileName); DPX_SET_ATTRIB_STR(InputDevice, inputDevice); DPX_SET_ATTRIB_STR(InputDeviceSerialNumber, inputDeviceSerialNumber); DPX_SET_ATTRIB_BYTE(Interlace); DPX_SET_ATTRIB_BYTE(FieldNumber); DPX_SET_ATTRIB_FLOAT(HorizontalSampleRate); DPX_SET_ATTRIB_FLOAT(VerticalSampleRate); DPX_SET_ATTRIB_FLOAT(TemporalFrameRate); DPX_SET_ATTRIB_FLOAT(TimeOffset); DPX_SET_ATTRIB_FLOAT(BlackLevel); DPX_SET_ATTRIB_FLOAT(BlackGain); DPX_SET_ATTRIB_FLOAT(BreakPoint); DPX_SET_ATTRIB_FLOAT(WhiteLevel); DPX_SET_ATTRIB_FLOAT(IntegrationTimes); #undef DPX_SET_ATTRIB_STR #undef DPX_SET_ATTRIB_FLOAT #undef DPX_SET_ATTRIB_FLOAT_N #undef DPX_SET_ATTRIB_INT #undef DPX_SET_ATTRIB_INT_N #undef DPX_SET_ATTRIB_N #undef DPX_SET_ATTRIB #undef DPX_SET_ATTRIB_S std::string tmpstr; switch (m_dpx.header.ImagePacking (subimage)) { case dpx::kPacked: tmpstr = "Packed"; break; case dpx::kFilledMethodA: tmpstr = "Filled, method A"; break; case dpx::kFilledMethodB: tmpstr = "Filled, method B"; break; } if (!tmpstr.empty ()) m_spec.attribute ("dpx:Packing", tmpstr); if (m_dpx.header.filmManufacturingIdCode[0] != 0) { int kc[7]; get_keycode_values (kc); m_spec.attribute("smpte:KeyCode", TypeDesc::TypeKeyCode, kc); } if (m_dpx.header.timeCode != 0xFFFFFFFF) { unsigned int timecode[2] = {m_dpx.header.timeCode, m_dpx.header.userBits}; m_spec.attribute("smpte:TimeCode", TypeDesc::TypeTimeCode, timecode); // This attribute is dpx specific and is left in for backwards compatability. // Users should utilise the new smpte:TimeCode attribute instead Imf::TimeCode tc(m_dpx.header.timeCode, m_dpx.header.userBits); m_spec.attribute ("dpx:TimeCode", get_timecode_string(tc)); } // This attribute is dpx specific and is left in for backwards compatability. // Users should utilise the new smpte:TimeCode attribute instead if (m_dpx.header.userBits != 0xFFFFFFFF) m_spec.attribute ("dpx:UserBits", m_dpx.header.userBits); if (m_dpx.header.sourceTimeDate[0]) { // libdpx's date/time format is pretty close to OIIO's (libdpx uses // %Y:%m:%d:%H:%M:%S%Z) char date[24]; Strutil::safe_strcpy(date, m_dpx.header.sourceTimeDate, sizeof(date)); date[10] = ' '; date[19] = 0; m_spec.attribute ("dpx:SourceDateTime", date); } m_dpx.header.FilmEdgeCode(buf); if (buf[0]) m_spec.attribute ("dpx:FilmEdgeCode", buf); tmpstr.clear (); switch (m_dpx.header.Signal ()) { case dpx::kUndefined: tmpstr = "Undefined"; break; case dpx::kNTSC: tmpstr = "NTSC"; break; case dpx::kPAL: tmpstr = "PAL"; break; case dpx::kPAL_M: tmpstr = "PAL-M"; break; case dpx::kSECAM: tmpstr = "SECAM"; break; case dpx::k525LineInterlace43AR: tmpstr = "YCbCr ITU-R 601-5 525i, 4:3"; break; case dpx::k625LineInterlace43AR: tmpstr = "YCbCr ITU-R 601-5 625i, 4:3"; break; case dpx::k525LineInterlace169AR: tmpstr = "YCbCr ITU-R 601-5 525i, 16:9"; break; case dpx::k625LineInterlace169AR: tmpstr = "YCbCr ITU-R 601-5 625i, 16:9"; break; case dpx::k1050LineInterlace169AR: tmpstr = "YCbCr 1050i, 16:9"; break; case dpx::k1125LineInterlace169AR_274: tmpstr = "YCbCr 1125i, 16:9 (SMPTE 274M)"; break; case dpx::k1250LineInterlace169AR: tmpstr = "YCbCr 1250i, 16:9"; break; case dpx::k1125LineInterlace169AR_240: tmpstr = "YCbCr 1125i, 16:9 (SMPTE 240M)"; break; case dpx::k525LineProgressive169AR: tmpstr = "YCbCr 525p, 16:9"; break; case dpx::k625LineProgressive169AR: tmpstr = "YCbCr 625p, 16:9"; break; case dpx::k750LineProgressive169AR: tmpstr = "YCbCr 750p, 16:9 (SMPTE 296M)"; break; case dpx::k1125LineProgressive169AR: tmpstr = "YCbCr 1125p, 16:9 (SMPTE 274M)"; break; case dpx::k255: // don't set the attribute at all break; default: tmpstr = Strutil::format ("Undefined %d", (int)m_dpx.header.Signal ()); break; } if (!tmpstr.empty ()) m_spec.attribute ("dpx:Signal", tmpstr); // read in user data; don't bother if the buffer is already filled (user // data is per-file, not per-element) if (m_userBuf.empty () && m_dpx.header.UserSize () != 0 && m_dpx.header.UserSize () != 0xFFFFFFFF) { m_userBuf.resize (m_dpx.header.UserSize ()); m_dpx.ReadUserData (&m_userBuf[0]); } if (!m_userBuf.empty ()) m_spec.attribute ("dpx:UserData", TypeDesc (TypeDesc::UCHAR, m_dpx.header.UserSize ()), &m_userBuf[0]); dpx::Block block(0, 0, m_dpx.header.Width () - 1, 0); int bufsize = dpx::QueryRGBBufferSize (m_dpx.header, subimage, block); if (bufsize == 0 && !m_wantRaw) { error ("Unable to deliver RGB data from source data"); return false; } else if (!m_wantRaw && bufsize > 0) m_dataPtr = new unsigned char[bufsize]; else // no need to allocate another buffer m_dataPtr = NULL; newspec = m_spec; return true; } bool DPXInput::close () { init(); // Reset to initial state return true; } bool DPXInput::read_native_scanline (int y, int z, void *data) { dpx::Block block(0, y-m_spec.y, m_dpx.header.Width () - 1, y-m_spec.y); if (m_wantRaw) { // fast path - just read the scanline in if (!m_dpx.ReadBlock (m_subimage, (unsigned char *)data, block)) return false; } else { // read the scanline and convert to RGB void *ptr = m_dataPtr == NULL ? data : (void *)m_dataPtr; if (!m_dpx.ReadBlock (m_subimage, (unsigned char *)ptr, block)) return false; if (!dpx::ConvertToRGB (m_dpx.header, m_subimage, ptr, data, block)) return false; } return true; } std::string DPXInput::get_characteristic_string (dpx::Characteristic c) { switch (c) { case dpx::kUserDefined: return "User defined"; case dpx::kPrintingDensity: return "Printing density"; case dpx::kLinear: return "Linear"; case dpx::kLogarithmic: return "Logarithmic"; case dpx::kUnspecifiedVideo: return "Unspecified video"; case dpx::kSMPTE274M: return "SMPTE 274M"; case dpx::kITUR709: return "ITU-R 709-4"; case dpx::kITUR601: return "ITU-R 601-5 system B or G"; case dpx::kITUR602: return "ITU-R 601-5 system M"; case dpx::kNTSCCompositeVideo: return "NTSC composite video"; case dpx::kPALCompositeVideo: return "PAL composite video"; case dpx::kZLinear: return "Z depth linear"; case dpx::kZHomogeneous: return "Z depth homogeneous"; case dpx::kUndefinedCharacteristic: default: return "Undefined"; } } std::string DPXInput::get_descriptor_string (dpx::Descriptor c) { switch (c) { case dpx::kUserDefinedDescriptor: case dpx::kUserDefined2Comp: case dpx::kUserDefined3Comp: case dpx::kUserDefined4Comp: case dpx::kUserDefined5Comp: case dpx::kUserDefined6Comp: case dpx::kUserDefined7Comp: case dpx::kUserDefined8Comp: return "User defined"; case dpx::kRed: return "Red"; case dpx::kGreen: return "Green"; case dpx::kBlue: return "Blue"; case dpx::kAlpha: return "Alpha"; case dpx::kLuma: return "Luma"; case dpx::kColorDifference: return "Color difference"; case dpx::kDepth: return "Depth"; case dpx::kCompositeVideo: return "Composite video"; case dpx::kRGB: return "RGB"; case dpx::kRGBA: return "RGBA"; case dpx::kABGR: return "ABGR"; case dpx::kCbYCrY: return "CbYCrY"; case dpx::kCbYACrYA: return "CbYACrYA"; case dpx::kCbYCr: return "CbYCr"; case dpx::kCbYCrA: return "CbYCrA"; //case dpx::kUndefinedDescriptor: default: return "Undefined"; } } void DPXInput::get_keycode_values (int *array) { std::stringstream ss; // Manufacturer code ss << std::string(m_dpx.header.filmManufacturingIdCode, 2); ss >> array[0]; ss.clear(); ss.str(""); // Film type ss << std::string(m_dpx.header.filmType, 2); ss >> array[1]; ss.clear(); ss.str(""); // Prefix ss << std::string(m_dpx.header.prefix, 6); ss >> array[2]; ss.clear(); ss.str(""); // Count ss << std::string(m_dpx.header.count, 4); ss >> array[3]; ss.clear(); ss.str(""); // Perforation Offset ss << std::string(m_dpx.header.perfsOffset, 2); ss >> array[4]; ss.clear(); ss.str(""); // Format std::string format(m_dpx.header.format, 32); int &perfsPerFrame = array[5]; int &perfsPerCount = array[6]; // default values perfsPerFrame = 4; perfsPerCount = 64; if ( format == "8kimax" ) { perfsPerFrame = 15; perfsPerCount = 120; } else if ( format.substr(0,4) == "2kvv" || format.substr(0,4) == "4kvv" ) { perfsPerFrame = 8; } else if ( format == "VistaVision" ) { perfsPerFrame = 8; } else if ( format.substr(0,4) == "2k35" || format.substr(0,4) == "4k35") { perfsPerFrame = 4; } else if ( format == "Full Aperture" ) { perfsPerFrame = 4; } else if ( format == "Academy" ) { perfsPerFrame = 4; } else if ( format.substr(0,7) == "2k3perf" || format.substr(0,7) == "4k3perf" ) { perfsPerFrame = 3; } else if ( format == "3perf" ) { perfsPerFrame = 3; } } std::string DPXInput::get_timecode_string (Imf::TimeCode &tc) { int values[] = {tc.hours(), tc.minutes(), tc.seconds(), tc.frame()}; std::stringstream ss; for (int i=0; i<4; i++) { std::ostringstream padded; padded << std::setw(2) << std::setfill('0') << values[i]; ss << padded.str(); if (i != 3) { if (i == 2) { tc.dropFrame() ? ss << ';' : ss << ':'; } else { ss << ':'; } } } return ss.str(); } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/0000755000175000017500000000000012271062644020576 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/DPX.cpp0000644000175000017500000000435112271062644021740 0ustar mfvmfv// vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "DPX.h" // determine byte order for current system // Intel processors are Little Endian // Power PC, MIPS and Ultra Sparc are Big Endian static unsigned long lValue = 0x12345678; static unsigned long *lPtr = &lValue; dpx::Endian dpx::systemByteOrder = (*(unsigned char*)lPtr == 0x78 ? dpx::kLittleEndian : dpx::kBigEndian); bool dpx::IdentifyFile(InStream *fp) { U32 magic; fp->Rewind(); if (fp->Read(&magic, sizeof(magic)) != sizeof(magic)) return false; return dpx::Header::ValidMagicCookie(magic); } bool dpx::IdentifyFile(const void *p) { U32 magic = *((U32 *) p); return dpx::Header::ValidMagicCookie(magic); } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/ElementReadStream.h0000644000175000017500000000433012271062644024310 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_ELEMENTREADSTREAM_H #define _DPX_ELEMENTREADSTREAM_H 1 #include "DPXStream.h" namespace dpx { class ElementReadStream { public: ElementReadStream(InStream *); virtual ~ElementReadStream(); virtual void Reset(); virtual bool Read(const dpx::Header &, const int element, const long offset, void * buf, const size_t size); virtual bool ReadDirect(const dpx::Header &, const int element, const long offset, void * buf, const size_t size); protected: void EndianDataCheck(const dpx::Header &, const int element, void *, const size_t size); InStream *fd; }; } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/InStream.cpp0000644000175000017500000000523512271062644023031 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include "filesystem.h" #include "DPXStream.h" InStream::InStream() : fp(0) { } InStream::~InStream() { } bool InStream::Open(const char *f) { if (this->fp) this->Close(); if ((this->fp = OIIO::Filesystem::fopen(f, "rb")) == 0) return false; return true; } void InStream::Close() { if (this->fp) { ::fclose(this->fp); this->fp = 0; } } void InStream::Rewind() { if (this->fp) ::rewind(fp); } bool InStream::Seek(long offset, Origin origin) { int o = 0; switch (origin) { case kCurrent: o = SEEK_CUR; break; case kEnd: o = SEEK_END; break; case kStart: o = SEEK_SET; break; } if (this->fp == 0) return -1; return (::fseek(this->fp, offset, o) == 0); } size_t InStream::Read(void *buf, const size_t size) { if (this->fp == 0) return 0; return ::fread(buf, 1, size, this->fp); } size_t InStream::ReadDirect(void *buf, const size_t size) { return this->Read(buf, size); } bool InStream::EndOfFile() const { if (this->fp == 0) return true; return ::feof(this->fp); } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/RunLengthEncoding.cpp0000644000175000017500000001230712271062644024662 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "DPX.h" #include "RunLengthEncoding.h" #include "ElementReadStream.h" #include "ReaderInternal.h" // Basic size of a packet is the number of bytes that all data packing methods will fit into that are whole and complete #define PACKET_REPEAT (10 * sizeof(U32)) // 320 bits repeating pattern #define BUFFER_SIZE (PACKET_REPEAT * 1002) // read in temp buffer size #define EXPANDED_BUFFER_SIZE (BUFFER_SIZE + (BUFFER_SIZE / 3)) // expaded size after unpacking (max) dpx::RunLengthEncoding::RunLengthEncoding() : buf(0) { } dpx::RunLengthEncoding::~RunLengthEncoding() { if (this->buf) delete [] buf; } void dpx::RunLengthEncoding::Reset() { if (this->buf) { delete [] buf; this->buf = 0; } } bool dpx::RunLengthEncoding::Read(const Header &dpxHeader, ElementReadStream *fd, const int element, const Block &block, void *data, const DataSize size) { int i; // just check to make sure that this element is RLE if (dpxHeader.ImageEncoding(element) != kRLE) return false; // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); const int width = dpxHeader.Width(); const int height = dpxHeader.Height(); const int byteCount = dpxHeader.ComponentByteCount(element); const U32 eolnPad = dpxHeader.EndOfLinePadding(element); //DataSize srcSize = dpxHeader.ComponentDataSize(element); // has the buffer been read in and decoded? if (this->buf == 0) { // not yet // bit depth of the image element const int bitDepth = dpxHeader.BitDepth(element); // error out if the bit depth 10 or 12 and have eoln bytes // this is particularly slow to parse and eoln padding bytes // are not needed for those formats // also if end of padding makes the line length odd, error out for that as well if (bitDepth != 8 && bitDepth != 16 && eolnPad > 0) return false; else if (bitDepth == 16 && eolnPad != 2 && eolnPad != 0) return false; // error out for real types since bit operations don't really make sense if (size == kFloat || size == kDouble) return false; // find start and possible end of the element U32 startOffset = dpxHeader.DataOffset(element); U32 endOffset = 0xffffffff; U32 currentOffset = startOffset; for (i = 0; i < MAX_ELEMENTS; i++) { if (i == element) continue; U32 doff = dpxHeader.DataOffset(i); if (doff == 0xffffffff) continue; if (doff > startOffset && (endOffset == 0xffffffff || doff < endOffset)) endOffset = doff - 1; } // size of the image const size_t imageSize = width * height * numberOfComponents; const size_t imageByteSize = imageSize * byteCount; // allocate the buffer that will store the entire image this->buf = new U8[imageByteSize]; // allocate the temporary buffer that will read in the encoded image U8 *tempBuf = new U8[EXPANDED_BUFFER_SIZE]; // xpos, ypos in decoding /*int xpos = 0; int ypos = 0;*/ // read in the encoded image block at a time bool done = false; while (!done) { // read in temp buffer size_t rs = fd->ReadDirect(dpxHeader, element, (currentOffset - startOffset), tempBuf, BUFFER_SIZE); currentOffset += rs; if (rs != BUFFER_SIZE) done = true; else if (endOffset != 0xffffffff && currentOffset >= endOffset) done = true; // if 10-bit, 12-bit, unpack or unfill // step through and decode } // no longer need temp buffer delete [] tempBuf; } #ifdef RLE_WORKING // NOT COMPLETE YET // copy buffer CopyImageBlock(dpxHeader, element, buf, srcSize, data, size, dstSize, block); #endif return true; } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/DPXHeader.cpp0000644000175000017500000005002712271062644023052 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include "DPXHeader.h" #include "EndianSwap.h" // function prototypes static void EmptyString(char *, const int); char Hex(char x) { if (x >= 10) return (x-10+'A'); else return (x+'0'); } dpx::Header::Header() : GenericHeader(), IndustryHeader(), datumSwap(true) { } dpx::GenericHeader::GenericHeader() { this->Reset(); } void dpx::GenericHeader::Reset() { // File Information this->magicNumber = MAGIC_COOKIE; this->imageOffset = ~0; EmptyString(this->version, sizeof(this->version)); OIIO::Strutil::safe_strcpy(this->version, SMPTE_VERSION, sizeof(this->version)); fileSize = sizeof(dpx::Header); this->dittoKey = 1; // new // genericSize is the size of the file/image/orientation headers // sizeof(dpx::GenericHeader) won't give the correct results because // of compiler padding // file header is 768 bytes // image header is 640 bytes // orientation header 256 bytes this->genericSize = 768 + 640 + 256; // industrySize is the size of the motion picture/television headers // motion picture header is 256 bytes // television header is 128 bytes this->industrySize = 256 + 128; this->userSize = 0; EmptyString(this->fileName, sizeof(this->fileName)); EmptyString(this->creationTimeDate, sizeof(this->creationTimeDate)); EmptyString(this->creator, sizeof(this->creator)); EmptyString(this->project, sizeof(this->project)); EmptyString(this->copyright, sizeof(this->copyright)); this->encryptKey = 0xffffffff; EmptyString(this->reserved1, sizeof(this->reserved1)); // Image Information this->imageOrientation = kUndefinedOrientation; this->numberOfElements = 0xffff; this->pixelsPerLine = this->linesPerElement = 0xffffffff; EmptyString(this->reserved2, sizeof(this->reserved2)); // Image Orientation this->xOffset = this->yOffset = 0xffffffff; this->xCenter = this->yCenter = std::numeric_limits::quiet_NaN(); this->xOriginalSize = this->yOriginalSize = 0xffffffff; EmptyString(this->sourceImageFileName, sizeof(this->sourceImageFileName)); EmptyString(this->sourceTimeDate, sizeof(this->sourceTimeDate)); EmptyString(this->inputDevice, sizeof(this->inputDevice)); EmptyString(this->inputDeviceSerialNumber, sizeof(this->inputDeviceSerialNumber)); this->border[0] = this->border[1] = this->border[2] = this->border[3] = 0xffff; this->aspectRatio[0] = this->aspectRatio[1] = 0xffffffff; this->xScannedSize = this->yScannedSize = std::numeric_limits::quiet_NaN(); EmptyString(this->reserved3, sizeof(this->reserved3)); } dpx::IndustryHeader::IndustryHeader() { this->Reset(); } void dpx::IndustryHeader::Reset() { // Motion Picture Industry Specific EmptyString(this->filmManufacturingIdCode, sizeof(this->filmManufacturingIdCode)); EmptyString(this->filmType, sizeof(this->filmType)); EmptyString(this->perfsOffset, sizeof(this->perfsOffset)); EmptyString(this->prefix, sizeof(this->prefix)); EmptyString(this->count, sizeof(this->count)); EmptyString(this->format, sizeof(this->format)); this->framePosition = this->sequenceLength = this->heldCount = 0xffffffff; this->frameRate = this->shutterAngle = std::numeric_limits::quiet_NaN(); EmptyString(this->frameId, sizeof(this->frameId)); EmptyString(this->slateInfo, sizeof(this->slateInfo)); EmptyString(this->reserved4, sizeof(this->reserved4)); // Television Industry Specific this->timeCode = this->userBits = 0xffffffff; this->interlace = this->fieldNumber = 0xff; this->videoSignal = kUndefined; this->zero = 0xff; this->horizontalSampleRate = this->verticalSampleRate = this->temporalFrameRate = std::numeric_limits::quiet_NaN(); this->timeOffset = this->gamma = std::numeric_limits::quiet_NaN(); this->blackLevel = this->blackGain = std::numeric_limits::quiet_NaN(); this->breakPoint = this->whiteLevel = this->integrationTimes = std::numeric_limits::quiet_NaN(); EmptyString(this->reserved5, sizeof(this->reserved5)); } dpx::ImageElement::ImageElement() { this->dataSign = 0xffffffff; this->lowData = 0xffffffff; this->lowQuantity = 0xffffffff; this->highData = 0xffffffff; this->highQuantity = 0xffffffff; this->descriptor = kUndefinedDescriptor; this->transfer = kUndefinedCharacteristic; this->colorimetric = kUndefinedCharacteristic; this->bitDepth = 0xff; this->packing = this->encoding = 0xffff; this->dataOffset = this->endOfLinePadding = this->endOfImagePadding = 0xffffffff; EmptyString(this->description, sizeof(this->description)); } bool dpx::Header::Read(InStream *io) { // rewind file io->Rewind(); // read in the header from the file size_t r = sizeof(GenericHeader) + sizeof(IndustryHeader); if (io->Read(&(this->magicNumber), r) != r) return false; // validate return this->Validate(); } // Check to see if the compiler placed the data members in the expected memory offsets bool dpx::Header::Check() { // genericSize is the size of the file/image/orientation headers // sizeof(dpx::GenericHeader) won't give the correct results because // of compiler padding // file header is 768 bytes // image header is 640 bytes // orientation header 256 bytes if (sizeof(GenericHeader) != (768 + 640 + 256)) return false; // industrySize is the size of the motion picture/television headers // motion picture header is 256 bytes // television header is 128 bytes if (sizeof(IndustryHeader) != (256 + 128)) return false; // data size checks if (sizeof(U8) != 1 || sizeof(U16) != 2 || sizeof(U32) != 4 || sizeof(R32) != 4 || sizeof(R64) != 8) return false; return true; } bool dpx::Header::Write(OutStream *io) { // validate and byte swap, if necessary if (!this->Validate()) return false; // write the header to the file size_t r = sizeof(GenericHeader) + sizeof(IndustryHeader); if (io->Write(&(this->magicNumber), r) != r) return false; // swap back - data is in file, now we need it native again this->Validate(); return true; } bool dpx::Header::WriteOffsetData(OutStream *io) { // calculate the number of elements this->CalculateNumberOfElements(); // write the image offset const long FIELD2 = 4; // offset to image in header if (io->Seek(FIELD2, OutStream::kStart) == false) return false; if (this->RequiresByteSwap()) SwapBytes(this->imageOffset); if (io->Write(&this->imageOffset, sizeof(U32)) == false) return false; if (this->RequiresByteSwap()) SwapBytes(this->imageOffset); // write the file size const long FIELD4 = 16; // offset to total image file size in header if (io->Seek(FIELD4, OutStream::kStart) == false) return false; if (this->RequiresByteSwap()) SwapBytes(this->fileSize); if (io->Write(&this->fileSize, sizeof(U32)) == false) return false; if (this->RequiresByteSwap()) SwapBytes(this->fileSize); // write the number of elements const long FIELD19 = 770; // offset to number of image elements in header if (io->Seek(FIELD19, OutStream::kStart) == false) return false; if (this->RequiresByteSwap()) SwapBytes(this->numberOfElements); if (io->Write(&this->numberOfElements, sizeof(U16)) == false) return false; if (this->RequiresByteSwap()) SwapBytes(this->numberOfElements); // write the image offsets const long FIELD21_12 = 808; // offset to image offset in image element data structure const long IMAGE_STRUCTURE = 72; // sizeof the image data structure int i; for (i = 0; i < MAX_ELEMENTS; i++) { // only write if there is a defined image description if (this->chan[i].descriptor == kUndefinedDescriptor) continue; // seek to the image offset entry in each image element if (io->Seek((FIELD21_12 + (IMAGE_STRUCTURE * i)), OutStream::kStart) == false) return false; // write if (this->RequiresByteSwap()) SwapBytes(this->chan[i].dataOffset); if (io->Write(&this->chan[i].dataOffset, sizeof(U32)) == false) return false; if (this->RequiresByteSwap()) SwapBytes(this->chan[i].dataOffset); } return true; } bool dpx::Header::ValidMagicCookie(const U32 magic) { U32 mc = MAGIC_COOKIE; if (magic == mc) return true; else if (magic == SwapBytes(mc)) return true; else return false; } bool dpx::Header::DetermineByteSwap(const U32 magic) const { U32 mc = MAGIC_COOKIE; bool byteSwap = false; if (magic != mc) byteSwap = true; return byteSwap; } bool dpx::Header::Validate() { // check magic cookie if (!this->ValidMagicCookie(this->magicNumber)) return false; // determine if bytes needs to be swapped around if (this->DetermineByteSwap(this->magicNumber)) { // File information SwapBytes(this->imageOffset); SwapBytes(this->fileSize); SwapBytes(this->dittoKey); SwapBytes(this->genericSize); SwapBytes(this->industrySize); SwapBytes(this->userSize); SwapBytes(this->encryptKey); // Image information SwapBytes(this->imageOrientation); SwapBytes(this->numberOfElements); SwapBytes(this->pixelsPerLine); SwapBytes(this->linesPerElement); for (int i = 0; i < MAX_ELEMENTS; i++) { SwapBytes(this->chan[i].dataSign); SwapBytes(this->chan[i].lowData); SwapBytes(this->chan[i].lowQuantity); SwapBytes(this->chan[i].highData); SwapBytes(this->chan[i].highQuantity); SwapBytes(this->chan[i].descriptor); SwapBytes(this->chan[i].transfer); SwapBytes(this->chan[i].colorimetric); SwapBytes(this->chan[i].bitDepth); SwapBytes(this->chan[i].packing); SwapBytes(this->chan[i].encoding); SwapBytes(this->chan[i].dataOffset); SwapBytes(this->chan[i].endOfLinePadding); SwapBytes(this->chan[i].endOfImagePadding); } // Image Origination information SwapBytes(this->xOffset); SwapBytes(this->yOffset); SwapBytes(this->xCenter); SwapBytes(this->yCenter); SwapBytes(this->xOriginalSize); SwapBytes(this->yOriginalSize); SwapBytes(this->border[0]); SwapBytes(this->border[1]); SwapBytes(this->border[2]); SwapBytes(this->border[3]); SwapBytes(this->aspectRatio[0]); SwapBytes(this->aspectRatio[1]); // Motion Picture Industry Specific SwapBytes(this->framePosition); SwapBytes(this->sequenceLength); SwapBytes(this->heldCount); SwapBytes(this->frameRate); SwapBytes(this->shutterAngle); // Television Industry Specific SwapBytes(this->timeCode); SwapBytes(this->userBits); SwapBytes(this->interlace); SwapBytes(this->fieldNumber); SwapBytes(this->videoSignal); SwapBytes(this->zero); SwapBytes(this->horizontalSampleRate); SwapBytes(this->verticalSampleRate); SwapBytes(this->temporalFrameRate); SwapBytes(this->timeOffset); SwapBytes(this->gamma); SwapBytes(this->blackLevel); SwapBytes(this->blackGain); SwapBytes(this->breakPoint); SwapBytes(this->whiteLevel); SwapBytes(this->integrationTimes); } return true; } void dpx::Header::Reset() { GenericHeader::Reset(); IndustryHeader::Reset(); } int dpx::GenericHeader::ImageElementComponentCount(const int element) const { int count = 1; switch (this->chan[element].descriptor) { case kUserDefinedDescriptor: case kRed: case kGreen: case kBlue: case kAlpha: case kLuma: case kColorDifference: case kDepth: count = 1; break; case kCompositeVideo: count = 1; break; case kRGB: count = 3; break; case kRGBA: case kABGR: count = 4; break; case kCbYCrY: count = 2; break; case kCbYACrYA: count = 3; break; case kCbYCr: count = 3; break; case kCbYCrA: count = 4; break; case kUserDefined2Comp: count = 2; break; case kUserDefined3Comp: count = 3; break; case kUserDefined4Comp: count = 4; break; case kUserDefined5Comp: count = 5; break; case kUserDefined6Comp: count = 6; break; case kUserDefined7Comp: count = 7; break; case kUserDefined8Comp: count = 8; break; }; return count; } int dpx::GenericHeader::ImageElementCount() const { if(this->numberOfElements>0 && this->numberOfElements<=MAX_ELEMENTS) return this->numberOfElements; // If the image header does not list a valid number of elements, // count how many defined image descriptors we have... int i = 0; while (i < MAX_ELEMENTS ) { if (this->ImageDescriptor(i) == kUndefinedDescriptor) break; i++; } return i; } void dpx::GenericHeader::CalculateNumberOfElements() { this->numberOfElements = 0xffff; int i = this->ImageElementCount(); if (i == 0) this->numberOfElements = 0xffff; else this->numberOfElements = U16(i); } void dpx::Header::CalculateOffsets() { int i; for (i = 0; i < MAX_ELEMENTS; i++) { // only write if there is a defined image description if (this->chan[i].descriptor == kUndefinedDescriptor) continue; } } dpx::DataSize dpx::GenericHeader::ComponentDataSize(const int element) const { if (element < 0 || element >= MAX_ELEMENTS) return kByte; dpx::DataSize ret; switch (this->chan[element].bitDepth) { case 8: ret = kByte; break; case 10: case 12: case 16: ret = kWord; break; case 32: ret = kFloat; break; case 64: ret = kDouble; break; default: assert(0 && "Unknown bit depth"); ret = kDouble; break; } return ret; } int dpx::GenericHeader::ComponentByteCount(const int element) const { if (element < 0 || element >= MAX_ELEMENTS) return kByte; int ret; switch (this->chan[element].bitDepth) { case 8: ret = sizeof(U8); break; case 10: case 12: case 16: ret = sizeof(U16); break; case 32: ret = sizeof(R32); break; case 64: ret = sizeof(R64); break; default: assert(0 && "Unknown bit depth"); ret = sizeof(R64); break; } return ret; } int dpx::GenericHeader::DataSizeByteCount(const DataSize ds) { int ret; switch (ds) { case kByte: ret = sizeof(U8); break; case kWord: ret = sizeof(U16); break; case kInt: ret = sizeof(U32); break; case kFloat: ret = sizeof(R32); break; case kDouble: ret = sizeof(R64); break; default: assert(0 && "Unknown data size"); ret = sizeof(R64); break; } return ret; } void dpx::IndustryHeader::FilmEdgeCode(char *edge) const { edge[0] = this->filmManufacturingIdCode[0]; edge[1] = this->filmManufacturingIdCode[1]; edge[2] = this->filmType[0]; edge[3] = this->filmType[1]; edge[4] = this->perfsOffset[0]; edge[5] = this->perfsOffset[1]; edge[6] = this->prefix[0]; edge[7] = this->prefix[1]; edge[8] = this->prefix[2]; edge[9] = this->prefix[3]; edge[10] = this->prefix[4]; edge[11] = this->prefix[5]; edge[12] = this->count[0]; edge[13] = this->count[1]; edge[14] = this->count[2]; edge[15] = this->count[3]; edge[16] = '\0'; } void dpx::IndustryHeader::SetFileEdgeCode(const char *edge) { this->filmManufacturingIdCode[0] = edge[0]; this->filmManufacturingIdCode[1] = edge[1]; this->filmType[0] = edge[2]; this->filmType[1] = edge[3]; this->perfsOffset[0] = edge[4]; this->perfsOffset[1] = edge[5]; this->prefix[0] = edge[6]; this->prefix[1] = edge[7]; this->prefix[2] = edge[8]; this->prefix[3] = edge[9]; this->prefix[4] = edge[10]; this->prefix[5] = edge[11]; this->count[0] = edge[12]; this->count[1] = edge[13]; this->count[2] = edge[14]; this->count[3] = edge[15]; } void dpx::IndustryHeader::TimeCode(char *str) const { register U32 tc = this->timeCode; ::sprintf(str, "%c%c:%c%c:%c%c:%c%c", Hex((tc & 0xf0000000) >> 28), Hex((tc & 0xf000000) >> 24), Hex((tc & 0xf00000) >> 20), Hex((tc & 0xf0000) >> 16), Hex((tc & 0xf000) >> 12), Hex((tc & 0xf00) >> 8), Hex((tc & 0xf0) >> 4), Hex(tc & 0xf)); } void dpx::IndustryHeader::UserBits(char *str) const { register U32 ub = this->userBits; ::sprintf(str, "%c%c:%c%c:%c%c:%c%c", Hex((ub & 0xf0000000) >> 28), Hex((ub & 0xf000000) >> 24), Hex((ub & 0xf00000) >> 20), Hex((ub & 0xf0000) >> 16), Hex((ub & 0xf000) >> 12), Hex((ub & 0xf00) >> 8), Hex((ub & 0xf0) >> 4), Hex(ub & 0xf)); } dpx::U32 dpx::IndustryHeader::TCFromString(const char *str) const { // make sure the string is the correct length if (::strlen(str) != 11) return U32(~0); U32 tc = 0; int i, idx = 0; U8 ch; U32 value, mask; for (i = 0; i < 8; i++, idx++) { // determine string index skipping : idx += idx % 3 == 2 ? 1 : 0; ch = str[idx]; // error check if (ch < '0' || ch > '9') return 0xffffffff; value = U32(ch - '0') << (28 - (i*4)); mask = 0xf << (28 - (i*4)); // mask in new value tc = (tc & ~mask) | (value & mask); } return tc; } void dpx::IndustryHeader::SetTimeCode(const char *str) { U32 tc = this->TCFromString(str); if (tc != 0xffffffff) this->timeCode = tc; } void dpx::IndustryHeader::SetUserBits(const char *str) { U32 ub = this->TCFromString(str); if (ub != 0xffffffff) this->userBits = ub; } static void EmptyString(char *str, const int len) { for (int i = 0; i < len; i++) str[i] = '\0'; } void dpx::GenericHeader::SetCreationTimeDate(const long sec) { struct tm *tm_time; char str[32]; #ifdef WIN32 _tzset(); #endif const time_t t = time_t(sec); tm_time = ::localtime(&t); ::strftime(str, 32, "%Y:%m:%d:%H:%M:%S%Z", tm_time); ::strncpy(this->creationTimeDate, str, 24); } void dpx::GenericHeader::SetSourceTimeDate(const long sec) { struct tm *tm_time; char str[32]; #ifdef WIN32 _tzset(); #endif const time_t t = time_t(sec); tm_time = ::localtime(&t); ::strftime(str, 32, "%Y:%m:%d:%H:%M:%S%Z", tm_time); ::strncpy(this->sourceTimeDate, str, 24); } bool dpx::Header::DatumSwap(const int element) const { if (this->datumSwap) { if (this->ImageDescriptor(element) == kRGB || this->ImageDescriptor(element) == kCbYCrY) return true; } return false; } void dpx::Header::SetDatumSwap(const bool swap) { this->datumSwap = swap; } // Height() // this function determines the height of the image taking in account for the image orientation // if an image is 1920x1080 but is oriented top to bottom, left to right then the height stored // in the image is 1920 rather than 1080 dpx::U32 dpx::Header::Height() const { U32 h; switch (this->ImageOrientation()) { case kTopToBottomLeftToRight: case kTopToBottomRightToLeft: case kBottomToTopLeftToRight: case kBottomToTopRightToLeft: h = this->PixelsPerLine(); break; default: h = this->LinesPerElement(); break; } return h; } // Width() // this function determines the width of the image taking in account for the image orientation // if an image is 1920x1080 but is oriented top to bottom, left to right then the width stored // in the image is 1920 rather than 1080 dpx::U32 dpx::Header::Width() const { U32 w; switch (this->ImageOrientation()) { case kTopToBottomLeftToRight: case kTopToBottomRightToLeft: case kBottomToTopLeftToRight: case kBottomToTopRightToLeft: w = this->LinesPerElement(); break; default: w = this->PixelsPerLine(); break; } return w; } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/Writer.cpp0000644000175000017500000002704712271062644022570 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "DPX.h" #include "DPXStream.h" #include "EndianSwap.h" #include "WriterInternal.h" dpx::Writer::Writer() : fileLoc(0) { } dpx::Writer::~Writer() { } void dpx::Writer::Start() { } void dpx::Writer::SetFileInfo(const char *fileName, const char *creationTimeDate, const char *creator, const char *project, const char *copyright, const U32 encryptKey, const bool swapEndian) { if (fileName) this->header.SetFileName(fileName); if (creationTimeDate) this->header.SetCreationTimeDate(creationTimeDate); else { time_t seconds = time(0); this->header.SetCreationTimeDate(seconds); } if (creator) this->header.SetCreator(creator); else this->header.SetCreator("OpenDPX library"); if (project) this->header.SetProject(project); if (copyright) this->header.SetCopyright(copyright); this->header.SetEncryptKey(encryptKey); if (swapEndian) this->header.magicNumber = SwapBytes(this->header.magicNumber); } void dpx::Writer::SetImageInfo(const U32 width, const U32 height) { this->header.SetImageOrientation(kLeftToRightTopToBottom); this->header.SetPixelsPerLine(width); this->header.SetLinesPerElement(height); } // returns next available or MAX_ELEMENTS if full int dpx::Writer::NextAvailElement() const { unsigned int i; for (i = 0; i < MAX_ELEMENTS; i++) { if (this->header.ImageDescriptor(i) == kUndefinedDescriptor) break; } return i; } void dpx::Writer::SetOutStream(OutStream *fd) { this->fd = fd; } bool dpx::Writer::WriteHeader() { // calculate any header info this->header.CalculateOffsets(); // seek to the beginning of the file if (!this->fd->Seek(0, OutStream::kStart)) return false; // writing the header count this->fileLoc = this->header.Size(); return this->header.Write(fd); } void dpx::Writer::SetUserData(const long size) { // TODO } bool dpx::Writer::WriteUserData(void *data) { // XXX TODO return false; } void dpx::Writer::SetElement(const int num, const Descriptor desc, const U8 bitDepth, const Characteristic transfer, const Characteristic colorimetric, const Packing packing, const Encoding encoding, const U32 dataSign, const U32 lowData, const R32 lowQuantity, const U32 highData, const R32 highQuantity, const U32 eolnPadding, const U32 eoimPadding) { // make sure the range is good if (num < 0 || num >= MAX_ELEMENTS) return; // set values this->header.SetDataSign(num, dataSign); this->header.SetLowData(num, lowData); this->header.SetLowQuantity(num, lowQuantity); this->header.SetHighData(num, highData); this->header.SetHighQuantity(num, highQuantity); this->header.SetImageDescriptor(num, desc); this->header.SetTransfer(num, transfer); this->header.SetColorimetric(num, colorimetric); this->header.SetBitDepth(num, bitDepth); this->header.SetImagePacking(num, packing); this->header.SetImageEncoding(num, encoding); this->header.SetEndOfLinePadding(num, eolnPadding); this->header.SetEndOfImagePadding(num, eoimPadding); // determine if increases element count this->header.CalculateNumberOfElements(); } // the data is processed so write it straight through // argument count is total size in bytes of the passed data bool dpx::Writer::WriteElement(const int element, void *data, const long count) { // make sure the range is good if (element < 0 || element >= MAX_ELEMENTS) return false; // make sure the entry is valid if (this->header.ImageDescriptor(element) == kUndefinedDescriptor) return false; // update file ptr this->header.SetDataOffset(element, this->fileLoc); this->fileLoc += count; // write return (this->fd->Write(data, count) > 0); } bool dpx::Writer::WriteElement(const int element, void *data) { // make sure the range is good if (element < 0 || element >= MAX_ELEMENTS) return false; // make sure the entry is valid if (this->header.ImageDescriptor(element) == kUndefinedDescriptor) return false; return this->WriteElement(element, data, this->header.ComponentDataSize(element)); } bool dpx::Writer::WriteElement(const int element, void *data, const DataSize size) { bool status = true; // make sure the range is good if (element < 0 || element >= MAX_ELEMENTS) return false; // make sure the entry is valid if (this->header.ImageDescriptor(element) == kUndefinedDescriptor) return false; // mark location in headers if (element == 0) this->header.SetImageOffset(this->fileLoc); this->header.SetDataOffset(element, this->fileLoc); // reverse the order of the components bool reverse = false; // rle encoding? const bool rle = this->header.ImageEncoding(element) == kRLE; // image parameters const U32 eolnPad = this->header.EndOfLinePadding(element); const U32 eoimPad = this->header.EndOfImagePadding(element); const U8 bitDepth = this->header.BitDepth(element); const U32 width = this->header.Width(); const U32 height = this->header.Height(); const int noc = this->header.ImageElementComponentCount(element); const Packing packing = this->header.ImagePacking(element); // check width & height, just in case if (width == 0 || height == 0) return false; // sizeof a component in an image const int bytes = (bitDepth + 7) / 8; // allocate memory for use to write blank space char *blank = 0; if (eolnPad || eoimPad) { int bsize = eolnPad > eoimPad ? eolnPad : eoimPad; blank = new char[bsize]; memset(blank, 0, bsize * sizeof(char)); } // can we write the entire memory chunk at once without any additional processing if (!rle && !this->header.RequiresByteSwap() && ((bitDepth == 8 && size == dpx::kByte) || (bitDepth == 12 && size == dpx::kWord && packing == kFilledMethodA) || (bitDepth == 16 && size == dpx::kWord) || (bitDepth == 32 && size == dpx::kFloat) || (bitDepth == 64 && size == dpx::kDouble))) { status = this->WriteThrough(data, width, height, noc, bytes, eolnPad, eoimPad, blank); if (blank) delete [] blank; return status; } else { switch (bitDepth) { case 8: if (size == dpx::kByte) this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, rle, reverse, eolnPad, blank, status, this->header.RequiresByteSwap()); else this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, rle, reverse, eolnPad, blank, status, this->header.RequiresByteSwap()); break; case 10: // are the channels stored in reverse if (this->header.ImageDescriptor(element) == kRGB && this->header.DatumSwap(element) && bitDepth == 10) reverse = true; if (size == dpx::kWord) this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, rle, reverse, eolnPad, blank, status, this->header.RequiresByteSwap()); else this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, rle, reverse, eolnPad, blank, status, this->header.RequiresByteSwap()); break; case 12: if (size == dpx::kWord) this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, rle, reverse, eolnPad, blank, status, this->header.RequiresByteSwap()); else this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, rle, reverse, eolnPad, blank, status, this->header.RequiresByteSwap()); break; case 16: if (size == dpx::kWord) this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, rle, reverse, eolnPad, blank, status, this->header.RequiresByteSwap()); else this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, rle, reverse, eolnPad, blank, status, this->header.RequiresByteSwap()); break; case 32: if (size == dpx::kFloat) this->fileLoc += WriteFloatBuffer(this->fd, size, data, width, height, noc, packing, rle, eolnPad, blank, status, this->header.RequiresByteSwap()); else this->fileLoc += WriteFloatBuffer(this->fd, size, data, width, height, noc, packing, rle, eolnPad, blank, status, this->header.RequiresByteSwap()); break; case 64: if (size == dpx::kDouble) this->fileLoc += WriteFloatBuffer(this->fd, size, data, width, height, noc, packing, rle, eolnPad, blank, status, this->header.RequiresByteSwap()); else this->fileLoc += WriteFloatBuffer(this->fd, size, data, width, height, noc, packing, rle, eolnPad, blank, status, this->header.RequiresByteSwap()); break; } } // if successful if (status && eoimPad) { // end of image padding this->fileLoc += eoimPad; status = (this->fd->Write(blank, eoimPad) > 0); } // rid of memory if (blank) delete [] blank; return status; } // the passed in image buffer is written to the file untouched bool dpx::Writer::WriteThrough(void *data, const U32 width, const U32 height, const int noc, const int bytes, const U32 eolnPad, const U32 eoimPad, char *blank) { bool status = true; const int count = width * height * noc; unsigned int i; unsigned char *imageBuf = reinterpret_cast(data); // file pointer location after write this->fileLoc += bytes * count + (eolnPad * height); // write data if (eolnPad) { // loop if have end of line padding for (i = 0; i < height; i++) { // write one line if (this->fd->Write(imageBuf+(width*bytes*i), bytes * width) == false) { status = false; break; } // write end of line padding if (this->fd->Write(blank, eoimPad) == false) { status = false; break; } } } else { // write data as one chunk if (this->fd->Write(imageBuf, bytes * count) == false) { status = false; } } // end of image padding if (status && eoimPad) { this->fileLoc += eoimPad; status = (this->fd->Write(blank, eoimPad) > 0); } return status; } bool dpx::Writer::Finish() { // write the file size in the header this->header.SetFileSize(this->fileLoc); // rewrite all of the offsets in the header return this->header.WriteOffsetData(this->fd); } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/Codec.cpp0000644000175000017500000000534412271062644022325 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "DPX.h" #include "Codec.h" #include "ElementReadStream.h" #include "ReaderInternal.h" dpx::Codec::Codec() : scanline(0) { } dpx::Codec::~Codec() { if (this->scanline) delete [] scanline; } void dpx::Codec::Reset() { if (this->scanline) { delete [] scanline; this->scanline = 0; } } bool dpx::Codec::Read(const Header &dpxHeader, ElementReadStream *fd, const int element, const Block &block, void *data, const DataSize size) { // scanline buffer if (this->scanline == 0) { // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); // bit depth of the image element const int bitDepth = dpxHeader.BitDepth(element); // size of the scanline buffer is image width * number of components * bytes per component int slsize = ((numberOfComponents * dpxHeader.Width() * (bitDepth / 8 + (bitDepth % 8 ? 1 : 0))) / sizeof(U32))+1; this->scanline = new U32[slsize]; } // read the image block return ReadImageBlock(dpxHeader, this->scanline, fd, element, block, data, size); } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/DPXStream.h0000644000175000017500000001044312271062644022560 0ustar mfvmfv/// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /*! \file DPXStream.h */ /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_DPXSTREAM_H #define _DPX_DPXSTREAM_H 1 #include /*! * \class InStream * \brief Input Stream for reading files */ class InStream { public: /*! * \enum Origin * \brief file pointing positioning offset */ enum Origin { kStart, //!< beginning of the file kCurrent, //!< current file pointer kEnd //!< end of the file }; /*! * \brief Constructor */ InStream(); /*! * \brief Destructor */ virtual ~InStream(); /*! * \brief Open file * \param fn File name * \return success true/false */ virtual bool Open(const char * fn); /*! * \brief Close file */ virtual void Close(); /*! * \brief Rewind file pointer to beginning of file */ virtual void Rewind(); /*! * \brief Read data from file * \param buf data buffer * \param size bytes to read * \return number of bytes read */ virtual size_t Read(void * buf, const size_t size); /*! * \brief Read data from file without any buffering as fast as possible * \param buf data buffer * \param size bytes to read * \return number of bytes read */ virtual size_t ReadDirect(void * buf, const size_t size); /*! * \brief Query if end of file has been reached * \return end of file true/false */ virtual bool EndOfFile() const; /*! * \brief Seek to a position in the file * \param offset offset from originating position * \param origin originating position * \return success true/false */ virtual bool Seek(long offset, Origin origin); protected: FILE *fp; }; /*! * \class OutStream * \brief Output Stream for writing files */ class OutStream { public: /*! * \enum Origin * \brief file pointing positioning offset */ enum Origin { kStart, //!< beginning of the file kCurrent, //!< current file pointer kEnd //!< end of the file }; /*! * \brief Constructor */ OutStream(); /*! * \brief Destructor */ virtual ~OutStream(); /*! * \brief Open file * \param fn File name * \return success true/false */ virtual bool Open(const char *fn); /*! * \brief Close file */ virtual void Close(); /*! * \brief Write data to file * \param buf data buffer * \param size bytes to write * \return number of bytes written */ virtual size_t Write(void * buf, const size_t size); /*! * \brief Seek to a position in the file * \param offset offset from originating position * \param origin originating position * \return success true/false */ virtual bool Seek(long offset, Origin origin); /*! * \brief Flush any buffers */ virtual void Flush(); protected: FILE *fp; }; #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/WriterInternal.h0000644000175000017500000003062712271062644023730 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_WRITERINTERNAL_H #define _DPX_WRITERINTERNAL_H 1 #include "BaseTypeConverter.h" namespace dpx { void EndianBufferSwap(int bitdepth, dpx::Packing packing, void *buf, const size_t size) { switch (bitdepth) { case 8: break; case 12: if (packing == dpx::kPacked) dpx::EndianSwapImageBuffer(buf, size / sizeof(U32)); else dpx::EndianSwapImageBuffer(buf, size / sizeof(U16)); break; case 16: dpx::EndianSwapImageBuffer(buf, size / sizeof(U16)); break; default: // 10-bit, 32-bit, 64-bit dpx::EndianSwapImageBuffer(buf, size / sizeof(U32)); } } template void MultiTypeBufferCopy(T1 *dst, T2 *src, const int len) { for (int i = 0; i < len; i++) BaseTypeConverter(src[i], dst[i]); } template void CopyWriteBuffer(DataSize src_size, unsigned char *src, IB * dst, const int len) { if (src_size == kByte) MultiTypeBufferCopy(dst, reinterpret_cast(src), len); else if (src_size == kWord) MultiTypeBufferCopy(dst, reinterpret_cast(src), len); else if (src_size == kFloat) MultiTypeBufferCopy(dst, reinterpret_cast(src), len); else if (src_size == kDouble) MultiTypeBufferCopy(dst, reinterpret_cast(src), len); } // access modifications to the buffer based on compression and packing struct BufferAccess { int offset; int length; BufferAccess() : offset(0), length(0) { } }; // \todo NOT DONE template void RleCompress(IB *src, IB *dst, const int bufsize, const int len, BufferAccess &access) { /*IB ch; int count; int i; int index = bufsize - 1; bool start = true; //bool match = true; // for each data type, have maximum length of rle datum // subtract one so it the LSBit can be used to state int maxCount; if (BITDEPTH == 8) maxCount = 0xff - 1; else if (BITDEPTH == 10) maxCount = 0x3ff - 1; else if (BITDEPTH == 12) maxCount = 0xfff - 1; else if (BITDEPTH == 16) maxCount = 0xffff - 1; else maxCount = 1000000; // high number for floats, doubles for (i = len - 1; i >= 0; i--) { if (start) { count = 1; start = false; ch = src[i]; dst[index--] = ch; } } access.offset = index; access.length = bufsize - index;*/ } template void WritePackedMethod(IB *src, IB *dst, const int len, const bool reverse, BufferAccess &access) { // pack into the same memory space U32 *dst_u32 = reinterpret_cast(dst); // bit shift count for U16 source const int shift = 16 - BITDEPTH; // bit mask U32 mask = 0; if (BITDEPTH == 10) mask = 0x03ff; else if (BITDEPTH == 12) mask = 0x0fff; else if (BITDEPTH == 8) return; int i, entry; for (i = 0; i < len; i++) { // read value and determine write location U32 value = static_cast(src[i+access.offset]) >> shift; // if reverse the order /*** XXX TODO REVERSE if (reverse) // reverse the triplets so entry would be 2,1,0,5,4,3,8,7,6,... entry = ((i / 3) * 3) + (2 - (i % 3)); else ***/ entry = i; int div = (entry * BITDEPTH) / 32; // 32 bits in a U32 int rem = (entry * BITDEPTH) % 32; // write the bits that belong in the first U32 // calculate the masked bits for the added value U32 shift_mask = mask << rem; // mask sure to mask the bits to save as part of the src_buf // so if writing bits 8-18, save the bits of the source material dst_u32[div] = (dst_u32[div] & ~shift_mask) | ((value << rem) & shift_mask); // write across multiple U16? count the carry bits int carry = BITDEPTH - (32 - rem); if (carry > 0) { U32 save = BITDEPTH - carry; dst_u32[div+1] = (dst_u32[div+1] & ~(mask >> save)) | ((value >> save) & (mask >> save)); } } // adjust offset/length access.offset = 0; access.length = (((len * BITDEPTH) / 32) + ((len * BITDEPTH) % 32 ? 1 : 0)) * 2; } // this routine expects a type of U16 template void WritePackedMethodAB_10bit(IB *src, IB *dst, const int len, const bool reverse, BufferAccess &access) { // pack into the same memory space U32 *dst_u32 = reinterpret_cast(dst); // bit shift count const U32 shift = 6; // (16 - BITDEPTH) const U32 bitdepth = 10; const U32 bitmask = 0x03ff; // shift bits over 2 if Method A const int method_shift = (METHOD == kFilledMethodA ? 2 : 0); // loop through the buffer int i; U32 value = 0; for (i = 0; i < len; i++) { int div = i / 3; // 3 10-bit values in a U32 int rem = i % 3; // write previously calculated value if (i && rem == 0) { dst_u32[div-1] = value; value = 0; } // if reverse the order if (reverse) rem = 2 - rem; // place the 10 bits in the proper place with mask U32 comp = ((static_cast(src[i+access.offset]) >> shift) << (bitdepth * rem)) << method_shift; U32 mask = (bitmask << (bitdepth * rem)) << method_shift ; // overwrite only the proper 10 bits value = (value & ~mask) | (comp & mask); } // write last dst_u32[(len+2)/3-1] = value; // adjust offset/length // multiply * 2 because it takes two U16 = U32 and this func packs into a U32 access.offset = 0; access.length = ((len / 3) + (len % 3 ? 1 : 0)) * 2; } template int WriteBuffer(OutStream *fd, DataSize src_size, void *src_buf, const U32 width, const U32 height, const int noc, const Packing packing, const bool rle, bool reverse, const int eolnPad, char *blank, bool &status, bool swapEndian) { int fileOffset = 0; // determine any impact on the max line size due to RLE // impact may be that rle is true but the data can not be compressed at all // the worst possible compression with RLE is increasing the image size by 1/3 // so we will just double the destination size if RLE int rleBufAdd = (rle ? ((width * noc / 3) + 1) : 0); // buffer access parameters BufferAccess bufaccess; bufaccess.offset = 0; bufaccess.length = width * noc; // allocate one line IB *src; IB *dst = new IB[(width * noc) + 1 + rleBufAdd]; // not exactly sure why, but the datum order is wrong when writing 4-channel images, so reverse it if (noc == 4 && BITDEPTH == 10) reverse = !reverse; // each line in the buffer for (U32 h = 0; h < height; h++) { // image buffer unsigned char *imageBuf = reinterpret_cast(src_buf); const int bytes = Header::DataSizeByteCount(src_size); // copy buffer if need to promote data types from src to destination if (SAMEBUFTYPE) { src = dst; CopyWriteBuffer(src_size, (imageBuf+(h*width*noc*bytes)+(h*eolnPad)), dst, (width*noc)); } else // not a copy, access source src = reinterpret_cast(imageBuf + (h * width * noc * bytes) + (h*eolnPad)); // if rle, compress if (rle) { RleCompress(src, dst, ((width * noc) + rleBufAdd), width * noc, bufaccess); src = dst; } // if 10 or 12 bit, pack if (BITDEPTH == 10) { if (packing == dpx::kPacked) { WritePackedMethod(src, dst, (width*noc), reverse, bufaccess); } else if (packing == kFilledMethodA) { WritePackedMethodAB_10bit(src, dst, (width*noc), reverse, bufaccess); } else // if (packing == dpx::kFilledMethodB) { WritePackedMethodAB_10bit(src, dst, (width*noc), reverse, bufaccess); } } else if (BITDEPTH == 12) { if (packing == dpx::kPacked) { WritePackedMethod(src, dst, (width*noc), reverse, bufaccess); } else if (packing == dpx::kFilledMethodB) { // shift 4 MSB down, so 0x0f00 would become 0x00f0 for (int w = 0; w < bufaccess.length; w++) dst[w] = src[bufaccess.offset+w] >> 4; bufaccess.offset = 0; } // a bitdepth of 12 by default is packed with dpx::kFilledMethodA // assumes that either a copy or rle was required // otherwise this routine should not be called with: // 12-bit Method A with the source buffer data type is kWord } // write line fileOffset += (bufaccess.length * sizeof(IB)); if (swapEndian) EndianBufferSwap(BITDEPTH, packing, dst + bufaccess.offset, bufaccess.length * sizeof(IB)); if (fd->Write(dst+bufaccess.offset, (bufaccess.length * sizeof(IB))) == false) { status = false; break; } // end of line padding if (eolnPad) { fileOffset += eolnPad; if (fd->Write(blank, eolnPad) == false) { status = false; break; } } } // done with buffer delete [] dst; return fileOffset; } template int WriteFloatBuffer(OutStream *fd, DataSize src_size, void *src_buf, const U32 width, const U32 height, const int noc, const Packing packing, const bool rle, const int eolnPad, char *blank, bool &status, bool swapEndian) { int fileOffset = 0; // determine any impact on the max line size due to RLE // impact may be that rle is true but the data can not be compressed at all // the worst possible compression with RLE is increasing the image size by 1/3 // so we will just double the destination size if RLE int rleBufAdd = (rle ? ((width * noc / 3) + 1) : 0); // buffer access parameters BufferAccess bufaccess; bufaccess.offset = 0; bufaccess.length = width * noc; // allocate one line IB *src; IB *dst = new IB[(width * noc) + rleBufAdd]; // each line in the buffer for (U32 h = 0; h < height; h++) { // image buffer unsigned char *imageBuf = reinterpret_cast(src_buf); const int bytes = Header::DataSizeByteCount(src_size); // copy buffer if need to promote data types from src to destination if (!SAMEBUFTYPE) { src = dst; CopyWriteBuffer(src_size, (imageBuf+(h*width*noc*bytes)+(h*eolnPad)), dst, (width*noc)); } else // not a copy, access source src = reinterpret_cast(imageBuf + (h * width * noc * bytes) + (h*eolnPad)); // if rle, compress if (rle) { RleCompress(src, dst, ((width * noc) + rleBufAdd), width * noc, bufaccess); src = dst; } // write line fileOffset += (bufaccess.length * sizeof(IB)); if (swapEndian) EndianBufferSwap(BITDEPTH, packing, dst + bufaccess.offset, bufaccess.length * sizeof(IB)); if (fd->Write(dst+bufaccess.offset, (bufaccess.length * sizeof(IB))) == false) { status = false; break; } // end of line padding if (eolnPad) { fileOffset += eolnPad; if (fd->Write(blank, eolnPad) == false) { status = false; break; } } } // done with buffer delete [] dst; return fileOffset; } } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/Codec.h0000644000175000017500000000500012271062644021757 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_CODEC_H #define _DPX_CODEC_H 1 #include "DPX.h" namespace dpx { /*! * \brief compress / decompress data segments * base class defaults to None */ class Codec { public: /*! * \brief constructor */ Codec(); /*! * \brief destructor */ virtual ~Codec(); /*! * \brief reset instance */ virtual void Reset(); /*! * \brief read data * \param dpxHeader dpx header information * \param fd field descriptor * \param element element (0-7) * \param block image area to read * \param data buffer * \param size size of the buffer component * \return success */ virtual bool Read(const Header &dpxHeader, ElementReadStream *fd, const int element, const Block &block, void *data, const DataSize size); protected: U32 *scanline; //!< single scanline }; } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/DPX.h0000644000175000017500000002561612271062644021414 0ustar mfvmfv// vi: ts=4 /*! \file DPX.h */ /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_H #define _DPX_H 1 #include #include #include "DPXHeader.h" #include "DPXStream.h" /*! * \def OPENDPX_VERSION * \brief OpenDPX Version */ #define OPENDPX_VERSION "0.5.0" /*! * \namespace dpx * \brief OpenDPX namespace */ namespace dpx { // forward definitions class Codec; class ElementReadStream; /*! * \enum Endian * \brief DPX files can be stored in big- or little-endian byte order */ enum Endian { kLittleEndian, //!< increasing numeric significance with increasing memory kBigEndian //!< big end first }; /*! \struct Block * \brief Rectangle block definition defined by two points */ struct Block { int x1, y1, x2, y2; /*! * \brief Constructor */ inline Block(); /*! * \brief Constructor * * \param x1 upper left x coordinate * \param y1 upper left y coordinate * \param x2 lower right x coordinate * \param y2 lower right y coordinate */ Block(const int x1, const int y1, const int x2, const int y2); /*! * \brief Set the block coordinates * * \param x1 upper left x coordinate * \param y1 upper left y coordinate * \param x2 lower right x coordinate * \param y2 lower right y coordinate */ void Set(const int x1, const int y1, const int x2, const int y2); /*! * \brief Check to see if a point is within the block * * \param x x coordinate * \param y y coordinate * \return true/false if coordinates within block */ inline bool Inside(const int x, const int y) const; /*! * \brief Rearrange coordinates if necessary so the first coordinate is upper left and the second is lower right */ inline void Check(); }; // Current platform endian byte order extern Endian systemByteOrder; // namespace functions /*! * \brief determine if the image file is DPX * * \param file buffer to read and search * \return true/false if identified as DPX */ bool IdentifyFile(InStream *file); /*! * \brief determine if the image file is DPX * * \param data memory to search * \return true/false if identified as DPX */ bool IdentifyFile(const void *data); /*! * \brief returns a char * of the default DPX file extension * * \return .dpx file extenion */ inline const char *DefaultExtension(); /*! * returns a string of the highest SMPTE DPX version supported by this library * * \return SMPTE DPX version */ inline const char *Version(); /*! * \brief returns the version string for this library * * \return OpenDPX version */ inline const char *LibraryVersion(); /*! * \class Reader * \brief DPX Image Reader class */ class Reader { public: /*! * \brief DPX header */ Header header; /*! * \brief Constructor */ Reader(); /*! * \brief Destructor */ virtual ~Reader(); /*! * \brief Set the InStream object to be used to read images * * \param stream Object to use for low level reads */ void SetInStream(InStream *stream); /*! * \brief clear any caching or memory allocated specific to an image */ void Reset(); /*! * \brief Read the dpx header into the header member * * \return success true/false */ bool ReadHeader(); /*! * \brief Read an image element into a buffer * * the size of the buffer must be large enough * simple calculation would be: * width * height * num_of_components * size_of_component * * \param element element (0-7) * \param data buffer * \return success true/false */ bool ReadImage(const int element, void *data); /*! * \brief Read a rectangular image block into a buffer from the specified image element * * \param element element (0-7) * \param data buffer * \param block image area to read * \return success true/false */ bool ReadBlock(const int element, unsigned char *data, Block &block); /*! * \brief Read the user data into a buffer. * * Buffer must be large enough to hold the user data. * * \param data buffer * \return success true/false */ bool ReadUserData(unsigned char *data); protected: InStream *fd; Codec *codex[MAX_ELEMENTS]; ElementReadStream *rio; }; /*! * \class Writer * \brief DPX Image Writer class */ class Writer { public: /*! * \brief DPX Header */ Header header; /*! * \brief Constructor */ Writer(); /*! * \brief Destructor */ virtual ~Writer(); /*! * \brief Start defining the header and writing the images */ void Start(); /*! * \brief Set the basic file information about DPX * * \param fileName name of this created file (100 characters max) * \param creationTimeDate creation time and date - format is "YYYY:MM:DD:HH:MM:SSLTZ" * where HH is 24 hour time, LTZ is local time zone using either * three character notation (i.e., -04) or five character notation * representing hours and minutes offset from Greenwich Mean time * (i.e., -0700) (24 characters max) * \param creator creator (100 characters max) * \param project project name (200 characters max) * \param copyright copyright statement (200 characters max) * \param encryptKey encryption key * \param swapEndian whether to write the image header in reverse to native endianness */ void SetFileInfo(const char *fileName, const char *creationTimeDate = 0, const char *creator = 0, const char *project = 0, const char *copyright = 0, const U32 encryptKey = ~0, const bool swapEndian = false); /*! * \brief Set the Width and Height of the images * * \param width width of the image * \param height height of the image */ void SetImageInfo(const U32 width, const U32 height); /*! * \brief Get the next available element * \return next available */ int NextAvailElement() const; /*! * \brief Set the parameters on an element * * There are 8 elements maximum in an single DPX and each element used must be set before writing the header * * \param element element number (0-7) * \param desc image descriptor * \param bitDepth bit depth of image, valid values are [8,10,12,16,32,64] * \param transfer transfer characteristic * \param colorimetric colorimetric specification * \param packing packing type * \param encoding encoding type * \param dataSign * \param lowData * \param lowQuantity * \param highData * \param highQuantity * \param eolnPadding end of line padding (in bytes) * \param eoimPadding end of image padding (in bytes) */ void SetElement(const int element = 0, const Descriptor desc = kRGB, const U8 bitDepth = 10, const Characteristic transfer = kLogarithmic, const Characteristic colorimetric = kLogarithmic, const Packing packing = kFilledMethodA, const Encoding encoding = kNone, const U32 dataSign = 0, const U32 lowData = ~0, const R32 lowQuantity = std::numeric_limits::quiet_NaN(), const U32 highData = ~0, const R32 highQuantity = std::numeric_limits::quiet_NaN(), const U32 eolnPadding = 0, const U32 eoimPadding = 0); /*! * \brief Set the OutStream object will use to write the files * * \param stream OutStream object */ void SetOutStream(OutStream *stream); /*! * \brief Set the size of the user data area * * \param size size of user data */ void SetUserData(const long size); /*! * \brief Write the header * * \return success true/false */ bool WriteHeader(); /*! * \brief Write the user data * * \param data buffer - must match size set in Writer::SetUserData() * \return success true/false */ bool WriteUserData(void *data); /*! * \brief Write the entire element to the dpx file * * \param element element number (0-7) * \param data buffer * \return success true/false */ bool WriteElement(const int element, void *data); bool WriteElement(const int element, void *data, const DataSize size); bool WriteElement(const int element, void *data, const long count); /** * \brief Finish up writing image * * \return success true/false */ bool Finish(); protected: long fileLoc; OutStream *fd; bool WriteThrough(void *, const U32, const U32, const int, const int, const U32, const U32, char *); }; } inline const char *dpx::DefaultExtension() { return "dpx"; } inline const char *dpx::Version() { return SMPTE_VERSION; } inline const char *dpx::LibraryVersion() { return OPENDPX_VERSION; } inline dpx::Block::Block() : x1(0), y1(0), x2(0), y2(0) { } inline dpx::Block::Block(const int x1, const int y1, const int x2, const int y2) : x1(x1), y1(y1), x2(x2), y2(y2) { this->Check(); } inline void dpx::Block::Set(const int x1, const int y1, const int x2, const int y2) { this->x1 = x1; this->y1 = y1; this->x2 = x2; this->y2 = y2; } // check the coordinates that x1 < x2 and y1 < y2 inline void dpx::Block::Check() { if (this->x1 > this->x2) { int t = x1; this->x1 = this->x2; this->x2 = t; } if (this->y1 > this->y2) { int t = y1; this->y1 = this->y2; this->y2 = t; } } inline bool dpx::Block::Inside(const int x, const int y) const { if (x >= this->x1 && x <= this->x2 && y >= this->y1 && y <= this->y2) return true; return false; } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/EndianSwap.h0000644000175000017500000000665512271062644023014 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_ENDIANSWAP_H #define _DPX_ENDIANSWAP_H 1 namespace dpx { template T SwapBytes(T& value) { register unsigned char *pe, *ps = reinterpret_cast(&value); register unsigned char c; register size_t s = (sizeof(T)); pe = ps + s - 1; for (size_t i = s/2; i > 0; i--) { c = *ps; *ps = *pe; *pe = c; ps++; pe--; } return value; } template <> inline unsigned short SwapBytes( unsigned short& value ) { register unsigned char *p = reinterpret_cast(&value); register unsigned char c = p[0]; p[0] = p[1]; p[1] = c; return value; } template <> inline unsigned char SwapBytes( unsigned char& value ) { return value; } template <> inline char SwapBytes( char& value ) { return value; } template void SwapBuffer(T *buf, unsigned int len) { for (unsigned int i = 0; i < len; i++) SwapBytes(buf[i]); } template void EndianSwapImageBuffer(void *data, int length) { switch (SIZE) { case dpx::kByte: break; case dpx::kWord: SwapBuffer(reinterpret_cast(data), length); break; case dpx::kInt: SwapBuffer(reinterpret_cast(data), length); break; case dpx::kFloat: SwapBuffer(reinterpret_cast(data), length); break; case dpx::kDouble: SwapBuffer(reinterpret_cast(data), length); break; } } inline void EndianSwapImageBuffer(DataSize size, void *data, int length) { switch (size) { case dpx::kByte: break; case dpx::kWord: SwapBuffer(reinterpret_cast(data), length); break; case dpx::kInt: SwapBuffer(reinterpret_cast(data), length); break; case dpx::kFloat: SwapBuffer(reinterpret_cast(data), length); break; case dpx::kDouble: SwapBuffer(reinterpret_cast(data), length); break; } } } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/ElementReadStream.cpp0000644000175000017500000000706212271062644024650 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "DPX.h" #include "EndianSwap.h" #include "ElementReadStream.h" dpx::ElementReadStream::ElementReadStream(InStream *fd) : fd(fd) { } dpx::ElementReadStream::~ElementReadStream() { } void dpx::ElementReadStream::Reset() { } bool dpx::ElementReadStream::Read(const dpx::Header &dpxHeader, const int element, const long offset, void * buf, const size_t size) { long position = dpxHeader.DataOffset(element) + offset; // seek to the memory position if (this->fd->Seek(position, InStream::kStart) == false) return false; // read in the data, calculate buffer offset if (this->fd->Read(buf, size) != size) return false; // swap the bytes if different byte order this->EndianDataCheck(dpxHeader, element, buf, size); return true; } bool dpx::ElementReadStream::ReadDirect(const dpx::Header &dpxHeader, const int element, const long offset, void * buf, const size_t size) { long position = dpxHeader.DataOffset(element) + offset; // seek to the memory position if (this->fd->Seek(position, InStream::kStart) == false) return false; // read in the data, calculate buffer offset if (this->fd->ReadDirect(buf, size) != size) return false; // swap the bytes if different byte order this->EndianDataCheck(dpxHeader, element, buf, size); return true; } void dpx::ElementReadStream::EndianDataCheck(const dpx::Header &dpxHeader, const int element, void *buf, const size_t size) { if (dpxHeader.RequiresByteSwap()) { switch (dpxHeader.BitDepth(element)) { case 8: break; case 12: if (dpxHeader.ImagePacking(element) == dpx::kPacked) dpx::EndianSwapImageBuffer(buf, size / sizeof(U32)); else dpx::EndianSwapImageBuffer(buf, size / sizeof(U16)); break; case 16: dpx::EndianSwapImageBuffer(buf, size / sizeof(U16)); break; default: // 10-bit, 32-bit, 64-bit dpx::EndianSwapImageBuffer(buf, size / sizeof(U32)); } } } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/BaseTypeConverter.h0000644000175000017500000001104712271062644024356 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_BASETYPECONVERTER_H #define _DPX_BASETYPECONVERTER_H 1 namespace dpx { // convert between all of the DPX base types in a controllable way // Note: These bit depth promotions (low precision -> high) use // a combination of bitshift and the 'or' operator in order to // fully populate the output coding space // // For example, when converting 8->16 bits, the 'simple' method // (shifting 8 bits) maps 255 to 65280. This result is not ideal // (uint16 'max' of 65535 is preferable). Overall, the best conversion // is one that approximates the 'true' floating-point scale factor. // 8->16 : 65535.0 / 255.0. 10->16 : 65535.0 / 1023.0. // For performance considerations, we choose to emulate this // floating-poing scaling with pure integer math, using a trick // where we duplicate portions of the MSB in the LSB. // // For bit depth demotions, simple truncation is used. // inline void BaseTypeConverter(U8 &src, U8 &dst) { dst = src; } inline void BaseTypeConverter(U8 &src, U16 &dst) { dst = (src << 8) | src; } inline void BaseTypeConverter(U8 &src, U32 &dst) { dst = (src << 24) | (src << 16) | (src << 8) | src; } inline void BaseTypeConverter(U8 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(U8 &src, R64 &dst) { dst = src; } inline void BaseTypeConverter(U16 &src, U8 &dst) { dst = src >> 8; } inline void BaseTypeConverter(U16 &src, U16 &dst) { dst = src; } inline void BaseTypeConverter(U16 &src, U32 &dst) { dst = (src << 16) | src; } inline void BaseTypeConverter(U16 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(U16 &src, R64 &dst) { dst = src; } inline void BaseTypeConverter(U32 &src, U8 &dst) { dst = src >> 24; } inline void BaseTypeConverter(U32 &src, U16 &dst) { dst = src >> 16; } inline void BaseTypeConverter(U32 &src, U32 &dst) { dst = src; } inline void BaseTypeConverter(U32 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(U32 &src, R64 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, U8 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, U16 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, U32 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, R64 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, U8 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, U16 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, U32 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, R64 &dst) { dst = src; } inline void BaseTypeConvertU10ToU16(U16 &src, U16 &dst) { dst = (src << 6) | (src >> 4); } inline void BaseTypeConvertU12ToU16(U16 &src, U16 &dst) { dst = (src << 4) | (src >> 8); } } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/DPXColorConverter.cpp0000644000175000017500000005365312271062644024640 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "DPXColorConverter.h" #include namespace dpx { template static inline bool SwapRGBABytes(const DATA *input, DATA *output, int pixels) { // copy the data that could be destroyed to an additional buffer in case input == output DATA tmp[2]; for (int i = 0; i < pixels; i++) { memcpy(tmp, &input[i * 4], sizeof(DATA) * 2); output[i * 4 + 0] = input[i * 4 + 3]; output[i * 4 + 1] = input[i * 4 + 2]; output[i * 4 + 2] = tmp[1]; output[i * 4 + 3] = tmp[0]; } return true; } // ======================================================================== // native formats -> RGB conversion // ======================================================================== static inline const float *GetYCbCrToRGBColorMatrix(const Characteristic space) { // YCbCr -> RGB matrices static const float Rec601[9] = { // multipliers for the corresponding signals // Y' Cb Cr /* R' = */ 1.f, 0.f, 1.402f, /* G' = */ 1.f, -0.344136f, -0.714136f, /* B' = */ 1.f, -0.772f, 0.f }, Rec709[9] = { // multipliers for the corresponding signals // Y' Cb Cr /* R' = */ 1.f, 0.f, 1.5748f, /* G' = */ 1.f, -0.187324f, -0.468124f, /* B' = */ 1.f, 1.8556f, 0.f }; switch (space) { // FIXME: research those constants! //case kPrintingDensity: //case kUnspecifiedVideo: case kITUR709: case kSMPTE274M: // SMPTE 247M has the same chromaticities as Rec709 return Rec709; case kITUR601: case kITUR602: return Rec601; //case kUserDefined: //case kNTSCCompositeVideo: //case kPALCompositeVideo: default: // ??? return NULL; } } template static inline void ConvertPixelYCbCrToRGB(const DATA CbYCr[3], DATA RGB[3], const float matrix[9]) { float tmp; for (int i = 0; i < 3; i++) { // dot product of matrix row and YCbCr pixel vector // chroma must be put in the [-0.5; 0.5] range tmp = matrix[i * 3 + 0] * CbYCr[1] // Y + matrix[i * 3 + 1] * ((float)CbYCr[0] - 0.5f * (float)max) // Cb + matrix[i * 3 + 2] * ((float)CbYCr[2] - 0.5f * (float)max); // Cr // for some reason the R and B channels get swapped, put them back in the correct order // prevent overflow RGB[2 - i] = std::max((DATA)0, static_cast(std::min(tmp, (float)max))); } } // 4:4:4 template static bool ConvertCbYCrToRGB(const Characteristic space, const DATA *input, DATA *output, const int pixels) { const float *matrix = GetYCbCrToRGBColorMatrix(space); if (matrix == NULL) return false; DATA RGB[3]; for (int i = 0; i < pixels; i++) { ConvertPixelYCbCrToRGB(&input[i * 3], RGB, matrix); memcpy(&output[i * 3], RGB, sizeof(DATA) * 3); } return true; } // 4:4:4:4 template static bool ConvertCbYCrAToRGBA(const Characteristic space, const DATA *input, DATA *output, const int pixels) { const float *matrix = GetYCbCrToRGBColorMatrix(space); if (matrix == NULL) return false; DATA RGBA[4]; for (int i = 0; i < pixels; i++) { ConvertPixelYCbCrToRGB(&input[i * 4], RGBA, matrix); RGBA[3] = input[i * 4 + 3]; memcpy(&output[i * 4], RGBA, sizeof(DATA) * 4); } return true; } // 4:2:2 template static bool ConvertCbYCrYToRGB(const Characteristic space, const DATA *input, DATA *output, const int pixels) { const float *matrix = GetYCbCrToRGBColorMatrix(space); if (matrix == NULL) return false; DATA CbYCr[3]; for (int i = 0; i < pixels; i++) { // upsample to 4:4:4 // FIXME: proper interpolation CbYCr[0] = input[(i | 1) * 2]; // Cb CbYCr[1] = input[i * 2 + 1]; // Y CbYCr[2] = input[(i & ~1) * 2]; // Cr // convert to RGB; we can pass a pointer into output because input must be != output ConvertPixelYCbCrToRGB(CbYCr, &output[i * 3], matrix); } return true; } // 4:2:2:4 template static bool ConvertCbYACrYAToRGBA(const Characteristic space, const DATA *input, DATA *output, const int pixels) { const float *matrix = GetYCbCrToRGBColorMatrix(space); if (matrix == NULL) return false; DATA CbYCr[3]; for (int i = 0; i < pixels; i++) { // upsample to 4:4:4 // FIXME: proper interpolation CbYCr[0] = input[(i | 1) * 3]; // Cb CbYCr[1] = input[i * 3 + 1]; // Y CbYCr[2] = input[(i & ~1) * 3]; // Cr // convert to RGBA; we can pass a pointer into output because input must be != output ConvertPixelYCbCrToRGB(CbYCr, &output[i * 4], matrix); output[i * 4 + 3] = input[i * 3 + 2]; // A } return true; } static inline bool ConvertToRGBInternal(const Descriptor desc, const DataSize size, const Characteristic space, const void *input, void *output, const int pixels) { switch (desc) { // redundant calls case kRGB: case kRGBA: return true; // needs swapping case kABGR: switch (size) { case kByte: return SwapRGBABytes((const U8 *)input, (U8 *)output, pixels); case kWord: return SwapRGBABytes((const U16 *)input, (U16 *)output, pixels); case kInt: return SwapRGBABytes((const U32 *)input, (U32 *)output, pixels); case kFloat: return SwapRGBABytes((const R32 *)input, (R32 *)output, pixels); case kDouble: return SwapRGBABytes((const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; // FIXME: can this be translated to RGB? //case kCompositeVideo: case kCbYCrY: switch (size) { case kByte: return ConvertCbYCrYToRGB(space, (const U8 *)input, (U8 *)output, pixels); case kWord: return ConvertCbYCrYToRGB(space, (const U16 *)input, (U16 *)output, pixels); case kInt: return ConvertCbYCrYToRGB(space, (const U32 *)input, (U32 *)output, pixels); case kFloat: return ConvertCbYCrYToRGB(space, (const R32 *)input, (R32 *)output, pixels); case kDouble: return ConvertCbYCrYToRGB(space, (const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; case kCbYCr: switch (size) { case kByte: return ConvertCbYCrToRGB(space, (const U8 *)input, (U8 *)output, pixels); case kWord: return ConvertCbYCrToRGB(space, (const U16 *)input, (U16 *)output, pixels); case kInt: return ConvertCbYCrToRGB(space, (const U32 *)input, (U32 *)output, pixels); case kFloat: return ConvertCbYCrToRGB(space, (const R32 *)input, (R32 *)output, pixels); case kDouble: return ConvertCbYCrToRGB(space, (const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; case kCbYACrYA: switch (size) { case kByte: return ConvertCbYACrYAToRGBA(space, (const U8 *)input, (U8 *)output, pixels); case kWord: return ConvertCbYACrYAToRGBA(space, (const U16 *)input, (U16 *)output, pixels); case kInt: return ConvertCbYACrYAToRGBA(space, (const U32 *)input, (U32 *)output, pixels); case kFloat: return ConvertCbYACrYAToRGBA(space, (const R32 *)input, (R32 *)output, pixels); case kDouble: return ConvertCbYACrYAToRGBA(space, (const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; case kCbYCrA: switch (size) { case kByte: return ConvertCbYCrAToRGBA(space, (const U8 *)input, (U8 *)output, pixels); case kWord: return ConvertCbYCrAToRGBA(space, (const U16 *)input, (U16 *)output, pixels); case kInt: return ConvertCbYCrAToRGBA(space, (const U32 *)input, (U32 *)output, pixels); case kFloat: return ConvertCbYCrAToRGBA(space, (const R32 *)input, (R32 *)output, pixels); case kDouble: return ConvertCbYCrAToRGBA(space, (const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; // all the rest is either irrelevant, invalid or unsupported /*case kUserDefinedDescriptor: case kRed: case kGreen: case kBlue: case kAlpha: case kLuma: case kColorDifference: case kDepth: case kUserDefined2Comp: case kUserDefined3Comp: case kUserDefined4Comp: case kUserDefined5Comp: case kUserDefined6Comp: case kUserDefined7Comp: case kUserDefined8Comp: case kUndefinedDescriptor:*/ default: return false; } } static inline int QueryRGBBufferSizeInternal(const Descriptor desc, const int pixels, const int bytes) { switch (desc) { //case kCompositeVideo: // FIXME: can this be translated to RGB? case kCbYCrY: // 4:2:2 -> RGB, requires allocation return pixels * 3 * bytes; case kCbYCr: // 4:4:4 -> RGB, can get away with sviweling case kRGB: // redundant return pixels * -3 * bytes; case kCbYACrYA: // 4:2:2:4 -> RGBA, requires allocation return pixels * 4 * bytes; case kCbYCrA: // 4:4:4:4 -> RGBA, can get away with sviweling case kRGBA: // redundant case kABGR: // only needs swapping return pixels * -4 * bytes; // all the rest is either irrelevant, invalid or unsupported /*case kUserDefinedDescriptor: case kRed: case kGreen: case kBlue: case kAlpha: case kLuma: case kColorDifference: case kDepth: case kUserDefined2Comp: case kUserDefined3Comp: case kUserDefined4Comp: case kUserDefined5Comp: case kUserDefined6Comp: case kUserDefined7Comp: case kUserDefined8Comp: case kUndefinedDescriptor:*/ default: return 0; } } int QueryRGBBufferSize(const Header &header, const int element, const Block &block) { return QueryRGBBufferSizeInternal(header.ImageDescriptor(element), (block.x2 - block.x1 + 1) * (block.y2 - block.y1 + 1), header.ComponentByteCount(element)); } int QueryRGBBufferSize(const Header &header, const int element) { return QueryRGBBufferSizeInternal(header.ImageDescriptor(element), header.Width() * header.Height(), header.ComponentByteCount(element)); } bool ConvertToRGB(const Header &header, const int element, const void *input, void *output, const Block &block) { return ConvertToRGBInternal(header.ImageDescriptor(element), header.ComponentDataSize(element), header.Colorimetric(element), input, output, (block.x2 - block.x1 + 1) * (block.y2 - block.y1 + 1)); } bool ConvertToRGB(const Header &header, const int element, const void *input, void *output) { return ConvertToRGBInternal(header.ImageDescriptor(element), header.ComponentDataSize(element), header.Colorimetric(element), input, output, header.Width() * header.Height()); } // ======================================================================== // RGB -> native formats conversion // ======================================================================== static inline const float *GetRGBToYCbCrColorMatrix(const Characteristic space) { // RGB -> YCbCr matrices static const float Rec601[9] = { // multipliers for the corresponding signals // R' G' B' /* Cb = */ -0.168736f, -0.331264f, 0.5f, /* Y' = */ 0.299f, 0.587f, 0.114f, /* Cr = */ 0.5f, -0.418688f, -0.081312f }, Rec709[9] = { // multipliers for the corresponding signals // R' G' B' /* Cb = */ -0.114572f, -0.385428f, 0.5f, /* Y' = */ 0.2126f, 0.7152f, 0.0722f, /* Cr = */ 0.5f, -0.454153f, -0.045847f }; switch (space) { // FIXME: research those constants! //case kPrintingDensity: //case kUnspecifiedVideo: case kITUR709: case kSMPTE274M: // SMPTE 247M has the same chromaticities as Rec709 return Rec709; case kITUR601: case kITUR602: return Rec601; //case kUserDefined: //case kNTSCCompositeVideo: //case kPALCompositeVideo: default: // ??? return NULL; } } template static inline void ConvertPixelRGBToYCbCr(const DATA RGB[3], DATA CbYCr[3], const float matrix[9]) { float tmp; for (int i = 0; i < 3; i++) { // dot product of matrix row and RGB pixel vector tmp = matrix[i * 3 + 0] * RGB[0] + matrix[i * 3 + 1] * RGB[1] + matrix[i * 3 + 2] * RGB[2]; // chroma (indices 0 and 2) must be put in the [0; 1] range if (i != 1) tmp += 0.5f * (float)max; // prevent overflow CbYCr[i] = std::max((DATA)0, static_cast(std::min(tmp, (float)max))); } } // 4:4:4 template static bool ConvertRGBToCbYCr(const Characteristic space, const DATA *input, DATA *output, const int pixels) { const float *matrix = GetRGBToYCbCrColorMatrix(space); if (matrix == NULL) return false; DATA CbYCr[3]; for (int i = 0; i < pixels; i++) { ConvertPixelRGBToYCbCr(&input[i * 3], CbYCr, matrix); memcpy(&output[i * 3], CbYCr, sizeof(DATA) * 3); } return true; } // 4:4:4:4 template static bool ConvertRGBAToCbYCrA(const Characteristic space, const DATA *input, DATA *output, const int pixels) { const float *matrix = GetRGBToYCbCrColorMatrix(space); if (matrix == NULL) return false; DATA CbYCrA[4]; for (int i = 0; i < pixels; i++) { ConvertPixelRGBToYCbCr(&input[i * 4], CbYCrA, matrix); CbYCrA[3] = input[i * 4 + 3]; memcpy(&output[i * 4], CbYCrA, sizeof(DATA) * 4); } return true; } // 4:2:2 template static bool ConvertRGBToCbYCrY(const Characteristic space, const DATA *input, DATA *output, const int pixels) { const float *matrix = GetRGBToYCbCrColorMatrix(space); if (matrix == NULL) return false; DATA CbYCr[3]; for (int i = 0; i < pixels; i++) { // convert to YCbCr ConvertPixelRGBToYCbCr(&input[i * 3], CbYCr, matrix); // downsample to 4:2:2 // FIXME: proper downsampling output[i * 2 + 0] = (i & 1) == 0 ? CbYCr[0] : CbYCr[2]; output[i * 2 + 1] = CbYCr[1]; } return true; } // 4:2:2:4 template static bool ConvertRGBAToCbYACrYA(const Characteristic space, const DATA *input, DATA *output, const int pixels) { const float *matrix = GetRGBToYCbCrColorMatrix(space); if (matrix == NULL) return false; DATA CbYCr[3]; for (int i = 0; i < pixels; i++) { // convert to YCbCr ConvertPixelRGBToYCbCr(&input[i * 4], CbYCr, matrix); // downsample to 4:2:2 // FIXME: proper downsampling output[i * 3 + 0] = (i & 1) == 0 ? CbYCr[0] : CbYCr[2]; output[i * 3 + 1] = CbYCr[1]; output[i * 3 + 3] = input[i * 4 + 3]; } return true; } static inline bool ConvertToNativeInternal(const Descriptor desc, const DataSize size, const Characteristic space, const void *input, void *output, const int pixels) { switch (desc) { // redundant calls case kRGB: case kRGBA: return true; // needs swapping case kABGR: switch (size) { case kByte: return SwapRGBABytes((const U8 *)input, (U8 *)output, pixels); case kWord: return SwapRGBABytes((const U16 *)input, (U16 *)output, pixels); case kInt: return SwapRGBABytes((const U32 *)input, (U32 *)output, pixels); case kFloat: return SwapRGBABytes((const R32 *)input, (R32 *)output, pixels); case kDouble: return SwapRGBABytes((const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; case kCbYCrY: switch (size) { case kByte: return ConvertRGBToCbYCrY(space, (const U8 *)input, (U8 *)output, pixels); case kWord: return ConvertRGBToCbYCrY(space, (const U16 *)input, (U16 *)output, pixels); case kInt: return ConvertRGBToCbYCrY(space, (const U32 *)input, (U32 *)output, pixels); case kFloat: return ConvertRGBToCbYCrY(space, (const R32 *)input, (R32 *)output, pixels); case kDouble: return ConvertRGBToCbYCrY(space, (const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; case kCbYCr: switch (size) { case kByte: return ConvertRGBToCbYCr(space, (const U8 *)input, (U8 *)output, pixels); case kWord: return ConvertRGBToCbYCr(space, (const U16 *)input, (U16 *)output, pixels); case kInt: return ConvertRGBToCbYCr(space, (const U32 *)input, (U32 *)output, pixels); case kFloat: return ConvertRGBToCbYCr(space, (const R32 *)input, (R32 *)output, pixels); case kDouble: return ConvertRGBToCbYCr(space, (const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; case kCbYACrYA: switch (size) { case kByte: return ConvertRGBAToCbYACrYA(space, (const U8 *)input, (U8 *)output, pixels); case kWord: return ConvertRGBAToCbYACrYA(space, (const U16 *)input, (U16 *)output, pixels); case kInt: return ConvertRGBAToCbYACrYA(space, (const U32 *)input, (U32 *)output, pixels); case kFloat: return ConvertRGBAToCbYACrYA(space, (const R32 *)input, (R32 *)output, pixels); case kDouble: return ConvertRGBAToCbYACrYA(space, (const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; case kCbYCrA: switch (size) { case kByte: return ConvertRGBAToCbYCrA(space, (const U8 *)input, (U8 *)output, pixels); case kWord: return ConvertRGBAToCbYCrA(space, (const U16 *)input, (U16 *)output, pixels); case kInt: return ConvertRGBAToCbYCrA(space, (const U32 *)input, (U32 *)output, pixels); case kFloat: return ConvertRGBAToCbYCrA(space, (const R32 *)input, (R32 *)output, pixels); case kDouble: return ConvertRGBAToCbYCrA(space, (const R64 *)input, (R64 *)output, pixels); } // shouldn't ever get here return false; // all the rest is either irrelevant, invalid or unsupported /*case kUserDefinedDescriptor: case kRed: case kGreen: case kBlue: case kAlpha: case kLuma: case kColorDifference: case kCompositeVideo: case kDepth: case kUserDefined2Comp: case kUserDefined3Comp: case kUserDefined4Comp: case kUserDefined5Comp: case kUserDefined6Comp: case kUserDefined7Comp: case kUserDefined8Comp: case kUndefinedDescriptor:*/ default: return false; } } static inline int QueryNativeBufferSizeInternal(const Descriptor desc, const int pixels, const DataSize compSize) { int bytes = compSize == kByte ? 1 : compSize == kWord ? 2 : compSize == kDouble ? 8 : 4; switch (desc) { case kCbYCrY: // RGB -> 4:2:2, requires allocation return pixels * 2 * bytes; case kCbYCr: // RGB -> 4:4:4, can get away with sviweling case kRGB: // redundant return pixels * -3 * bytes; case kCbYACrYA: // RGBA -> 4:2:2:4, requires allocation return pixels * 4 * bytes; case kCbYCrA: // RGBA -> 4:4:4:4, can get away with sviweling case kRGBA: // redundant case kABGR: // only needs swapping return pixels * -4 * bytes; // all the rest is either irrelevant, invalid or unsupported /*case kUserDefinedDescriptor: case kRed: case kGreen: case kBlue: case kAlpha: case kLuma: case kColorDifference: case kDepth: case kCompositeVideo: case kUserDefined2Comp: case kUserDefined3Comp: case kUserDefined4Comp: case kUserDefined5Comp: case kUserDefined6Comp: case kUserDefined7Comp: case kUserDefined8Comp: case kUndefinedDescriptor:*/ default: return 0; } } int QueryNativeBufferSize(const Descriptor desc, const DataSize compSize, const Block &block) { return QueryNativeBufferSizeInternal(desc, (block.x2 - block.x1 + 1) * (block.y2 - block.y1 + 1), compSize); } int QueryNativeBufferSize(const Descriptor desc, const DataSize compSize, const int width, const int height) { return QueryNativeBufferSizeInternal(desc, width * height, compSize); } bool ConvertToNative(const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const void *input, void *output, const Block &block) { return ConvertToNativeInternal(desc, compSize, cmetr, input, output, (block.x2 - block.x1 + 1) * (block.y2 - block.y1 + 1)); } bool ConvertToNative(const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const int width, const int height, const void *input, void *output) { return ConvertToNativeInternal(desc, compSize, cmetr, input, output, width * height); } } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/RunLengthEncoding.h0000644000175000017500000000513112271062644024324 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_RUNLENGTHENCODING_H #define _DPX_RUNLENGTHENCODING_H 1 #include "DPX.h" #include "Codec.h" namespace dpx { /*! * \brief compress / decompress data segments, used for RLE compression */ class RunLengthEncoding : public Codec { public: /*! * \brief constructor */ RunLengthEncoding(); /*! * \brief destructor */ virtual ~RunLengthEncoding(); /*! * \brief reset instance */ virtual void Reset(); /*! * \brief read data * \param dpxHeader dpx header information * \param fd field descriptor * \param element element (0-7) * \param block image area to read * \param data buffer * \param size size of the buffer component * \return success */ virtual bool Read(const dpx::Header &dpxHeader, ElementReadStream *fd, const int element, const Block &block, void *data, const DataSize size); protected: U8 *buf; //!< intermediate buffer }; } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/DPXHeader.h0000644000175000017500000015500512271062644022521 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /*! \file DPXHeader.h */ /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ // SMPTE DPX graphic file format v2.0 #ifndef _DPX_DPXHEADER_H #define _DPX_DPXHEADER_H 1 #include #include "strutil.h" #include "DPXStream.h" /*! * \def SMPTE_VERSION * \brief SMPTE 268M-2003 DPX Version */ #define SMPTE_VERSION "V2.0" /*! * \def MAX_ELEMENTS * \brief Maximum number of image elements */ #define MAX_ELEMENTS 8 /*! * \def MAX_COMPONENTS * \brief Maximum number of components per image element */ #define MAX_COMPONENTS 8 /*! * \def MAGIC_COOKIE * \brief HEX value of "SDPX" */ #define MAGIC_COOKIE 0x53445058 namespace dpx { // DPX data types /*! * \typedef unsigned char U8 * \brief Unsigned 8 bit integer */ typedef unsigned char U8; /*! * \typedef unsigned char U16 * \brief Unsigned 16 bit integer */ typedef unsigned short U16; /*! * \typedef unsigned char U32 * \brief Unsigned 32 bit integer */ typedef unsigned int U32; /*! * \typedef float R32 * \brief 32 bit floating point number */ typedef float R32; /*! * \typedef float R64 * \brief 64 bit floating point number */ typedef double R64; /*! * \typedef char ASCII * \brief ASCII character */ typedef char ASCII; /*! * \enum DataSize * \brief Component Data Storage Data Type */ enum DataSize { kByte, //!< 8-bit size component kWord, //!< kInt, //!< kFloat, //!< kDouble //!< }; /*! * \enum Orientation * \brief Image Orientation Code */ enum Orientation { kLeftToRightTopToBottom = 0, //!< Oriented left to right, top to bottom kRightToLeftTopToBottom = 1, //!< Oriented right to left, top to bottom kLeftToRightBottomToTop = 2, //!< Oriented left to right, bottom to top kRightToLeftBottomToTop = 3, //!< Oriented right to left, bottom to top kTopToBottomLeftToRight = 4, //!< Oriented top to bottom, left to right kTopToBottomRightToLeft = 5, //!< Oriented top to bottom, right to left kBottomToTopLeftToRight = 6, //!< Oriented bottom to top, left to right kBottomToTopRightToLeft = 7, //!< Oriented bottom to top, right to left kUndefinedOrientation = 0xffff //!< Undefined orientation }; /*! * \enum Descriptor * \brief Image element Descriptor */ enum Descriptor { kUserDefinedDescriptor = 0, //!< User defined descriptor kRed = 1, //!< Red kGreen = 2, //!< Green kBlue = 3, //!< Blue kAlpha = 4, //!< Alpha kLuma = 6, //!< Luma (Y) kColorDifference = 7, //!< Color difference kDepth = 8, //!< Depth kCompositeVideo = 9, //!< Composite video kRGB = 50, //!< R,G,B kRGBA = 51, //!< R,G,B,A kABGR = 52, //!< A,B,G,R kCbYCrY = 100, //!< Cb,Y,Cr,Y (4:2:2) kCbYACrYA = 101, //!< Cb,Y,A,Cr,Y,A (4:2:2:4) kCbYCr = 102, //!< Cb,Y,Cr (4:4:4) kCbYCrA = 103, //!< Cb,Y,Cr,A (4:4:4:4) kUserDefined2Comp = 150, //!< User defined 2 component element kUserDefined3Comp = 151, //!< User defined 3 component element kUserDefined4Comp = 152, //!< User defined 4 component element kUserDefined5Comp = 153, //!< User defined 5 component element kUserDefined6Comp = 154, //!< User defined 6 component element kUserDefined7Comp = 155, //!< User defined 7 component element kUserDefined8Comp = 156, //!< User defined 8 component element kUndefinedDescriptor = 0xff //!< Undefined descriptor }; /*! * \enum Characteristic * \brief Transfer Characteristic and Colorimetric Specification */ enum Characteristic { kUserDefined = 0, //!< User defined kPrintingDensity, //!< Printing density kLinear, //!< Linear, transfer only kLogarithmic, //!< Logarithmic, transfer only kUnspecifiedVideo, //!< Unspecified video kSMPTE274M, //!< SMPTE 274M kITUR709, //!< ITU-R 709-4 kITUR601, //!< ITU-R 601-5 system B or G kITUR602, //!< ITU-R 601-5 system M kNTSCCompositeVideo, //!< NTSC composite video kPALCompositeVideo, //!< PAL composite video kZLinear, //!< Z depth linear, transfer only kZHomogeneous, //!< Z depth homogeneous, transfer only kUndefinedCharacteristic = 0xff //!< Undefined }; /*! * \enum VideoSignal * \brief Video Signal Standard */ enum VideoSignal { kUndefined = 0, //!< Undefined kNTSC = 1, //!< NTSC kPAL = 2, //!< PAL kPAL_M = 3, //!< PAL-M kSECAM = 4, //!< SECAM k525LineInterlace43AR = 50, //!< YCbCr ITU-R 601-5 525-line, 2:1 interlace, 4:3 aspect ratio k625LineInterlace43AR = 51, //!< YCbCr ITU-R 601-5 625-line, 2:1 interlace, 4:3 aspect ratio k525LineInterlace169AR = 100, //!< YCbCr ITU-R 601-5 525-line, 2:1 interlace, 16:9 aspect ratio k625LineInterlace169AR = 101, //!< YCbCr ITU-R 601-5 625-line, 2:1 interlace, 16:9 aspect ratio k1050LineInterlace169AR = 150, //!< YCbCr 1050-line, 2:1 interlace, 16:9 aspect ratio k1125LineInterlace169AR_274 = 151, //!< YCbCr 1125-line, 2:1 interlace, 16:9 aspect ratio (SMPTE 274M) k1250LineInterlace169AR = 152, //!< YCbCr 1250-line, 2:1 interlace, 16:9 aspect ratio k1125LineInterlace169AR_240 = 153, //!< YCbCr 1125-line, 2:1 interlace, 16:9 aspect ratio (SMPTE 240M) k525LineProgressive169AR = 200, //!< YCbCr 525-line, 1:1 progressive, 16:9 aspect ratio k625LineProgressive169AR = 201, //!< YCbCr 625-line, 1:1 progressive, 16:9 aspect ratio k750LineProgressive169AR = 202, //!< YCbCr 750-line, 1:1 progressive, 16:9 aspect ratio (SMPTE 296M) k1125LineProgressive169AR = 203, //!< YCbCr 1125-line, 1:1 progressive, 16:9 aspect ratio (SMPTE 274M) k255 = 255 }; /*! * \enum Packing * \brief Component data packing method */ enum Packing { kPacked = 0, //!< Packed into 32-bit words kFilledMethodA = 1, //!< Filled to 32-bit words, method A kFilledMethodB = 2 //!< Filled to 32-bit words, method B }; /*! * \enum Encoding * \brief Component data encoding method */ enum Encoding { kNone = 0, //DetermineByteSwap(this->magicNumber); } inline const U32 Header::Size() const { return 2048; } inline U32 GenericHeader::MagicNumber() const { return this->magicNumber; } inline U32 GenericHeader::ImageOffset() const { return this->imageOffset; } inline void GenericHeader::SetImageOffset(const U32 offset) { this->imageOffset = offset; } inline void GenericHeader::Version(char *v) const { OIIO::Strutil::safe_strcpy(v, this->version, sizeof(this->version)); v[8] = '\0'; } inline void GenericHeader::SetVersion(const char * v) { OIIO::Strutil::safe_strcpy(this->version, v, sizeof(this->version)); } inline U32 GenericHeader::FileSize() const { return this->fileSize; } inline void GenericHeader::SetFileSize(const U32 fs) { this->fileSize = fs; } inline U32 GenericHeader::DittoKey() const { return this->dittoKey; } inline void GenericHeader::SetDittoKey(const U32 key) { this->dittoKey = key; } inline U32 GenericHeader::GenericSize() const { return this->genericSize; } inline U32 GenericHeader::IndustrySize() const { return this->industrySize; } inline U32 GenericHeader::UserSize() const { return this->userSize; } inline void GenericHeader::SetUserSize(const U32 size) { this->userSize = size; } inline void GenericHeader::FileName(char *fn) const { ::strncpy(fn, this->fileName, sizeof(this->fileName)); fn[100] = '\0'; } inline void GenericHeader::SetFileName(const char *fn) { ::strncpy(this->fileName, fn, sizeof(this->fileName)); } inline void GenericHeader::CreationTimeDate(char *ct) const { ::strncpy(ct, this->creationTimeDate, sizeof(this->creationTimeDate)); ct[24] = '\0'; } inline void GenericHeader::SetCreationTimeDate(const char *ct) { ::strncpy(this->creationTimeDate, ct, sizeof(this->creationTimeDate)); } inline void GenericHeader::Creator(char *creat) const { ::strncpy(creat, this->creator, sizeof(this->creator)); creat[200] = '\0'; } inline void GenericHeader::SetCreator(const char *creat) { ::strncpy(this->creator, creat, sizeof(this->creator)); } inline void GenericHeader::Project(char *prj) const { ::strncpy(prj, this->project, sizeof(this->project)); prj[200] = '\0'; } inline void GenericHeader::SetProject(const char *prj) { ::strncpy(this->project, prj, sizeof(this->project)); } inline void GenericHeader::Copyright(char *copy) const { ::strncpy(copy, this->copyright, sizeof(this->copyright)); copy[200] = '\0'; } inline void GenericHeader::SetCopyright(const char *copy) { ::strncpy(this->copyright, copy, sizeof(this->copyright)); } inline U32 GenericHeader::EncryptKey() const { return this->encryptKey; } inline void GenericHeader::SetEncryptKey(const U32 key) { this->encryptKey = key; } inline Orientation GenericHeader::ImageOrientation() const { return Orientation(this->imageOrientation); } inline void GenericHeader::SetImageOrientation(const Orientation orient) { this->imageOrientation = orient; } inline U16 GenericHeader::NumberOfElements() const { return this->numberOfElements; } inline void GenericHeader::SetNumberOfElements(const U16 num) { this->numberOfElements = num; } inline U32 GenericHeader::PixelsPerLine() const { return this->pixelsPerLine; } inline void GenericHeader::SetPixelsPerLine(const U32 ppl) { this->pixelsPerLine = ppl; } inline U32 GenericHeader::LinesPerElement() const { return this->linesPerElement; } inline void GenericHeader::SetLinesPerElement(const U32 lpe) { this->linesPerElement = lpe; } inline U32 GenericHeader::DataSign(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; return this->chan[i].dataSign; } inline void GenericHeader::SetDataSign(const int i, const U32 sign) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].dataSign = sign; } inline U32 GenericHeader::LowData(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; return this->chan[i].lowData; } inline void GenericHeader::SetLowData(const int i, const U32 data) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].lowData = data; } inline R32 GenericHeader::LowQuantity(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; return this->chan[i].lowQuantity; } inline void GenericHeader::SetLowQuantity(const int i, const R32 quant) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].lowQuantity = quant; } inline U32 GenericHeader::HighData(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; return this->chan[i].highData; } inline void GenericHeader::SetHighData(const int i, const U32 data) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].highData = data; } inline R32 GenericHeader::HighQuantity(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; return this->chan[i].highQuantity; } inline void GenericHeader::SetHighQuantity(const int i, const R32 quant) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].highQuantity = quant; } inline Descriptor GenericHeader::ImageDescriptor(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return Descriptor(0xff); return Descriptor(this->chan[i].descriptor); } inline void GenericHeader::SetImageDescriptor(const int i, const Descriptor desc) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].descriptor = desc; } inline Characteristic GenericHeader::Transfer(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return Characteristic(0xff); return Characteristic(this->chan[i].transfer); } inline void GenericHeader::SetTransfer(const int i, const Characteristic ch) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].transfer = ch; } inline Characteristic GenericHeader::Colorimetric(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return Characteristic(0xff); return Characteristic(this->chan[i].colorimetric); } inline void GenericHeader::SetColorimetric(const int i, const Characteristic c) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].colorimetric = c; } inline U8 GenericHeader::BitDepth(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xff; return this->chan[i].bitDepth; } inline void GenericHeader::SetBitDepth(const int i, const U8 depth) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].bitDepth = depth; } inline Packing GenericHeader::ImagePacking(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return Packing(0xff); return Packing(this->chan[i].packing); } inline void GenericHeader::SetImagePacking(const int i, const Packing pack) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].packing = pack; } inline Encoding GenericHeader::ImageEncoding(const int i) const { Encoding e = kNone; if (i < 0 || i >= MAX_ELEMENTS) return kNone; if (this->chan[i].encoding == 1) e = kRLE; return e; } inline void GenericHeader::SetImageEncoding(const int i, const Encoding enc) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].encoding = (enc == kNone ? 0 : 1); } inline U32 GenericHeader::DataOffset(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; return this->chan[i].dataOffset; } inline void GenericHeader::SetDataOffset(const int i, const U32 offset) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].dataOffset = offset; } inline U32 GenericHeader::EndOfLinePadding(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; if (this->chan[i].endOfLinePadding == 0xffffffff) return 0; return this->chan[i].endOfLinePadding; } inline void GenericHeader::SetEndOfLinePadding(const int i, const U32 eolp) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].endOfLinePadding = eolp; } inline U32 GenericHeader::EndOfImagePadding(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; if (this->chan[i].endOfImagePadding == 0xffffffff) return 0; return this->chan[i].endOfImagePadding; } inline void GenericHeader::SetEndOfImagePadding(const int i, const U32 eoip) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].endOfImagePadding = eoip; } inline void GenericHeader::Description(const int i, char *desc) const { if (i < 0 || i >= MAX_ELEMENTS) return; strncpy(desc, this->chan[i].description, 32); } inline void GenericHeader::SetDescription(const int i, const char *desc) { if (i < 0 || i >= MAX_ELEMENTS) return; ::strncpy(this->chan[i].description, desc, 32); } inline U32 GenericHeader::XOffset() const { return this->xOffset; } inline void GenericHeader::SetXOffset(const U32 offset) { this->xOffset = offset; } inline U32 GenericHeader::YOffset() const { return this->yOffset; } inline void GenericHeader::SetYOffset(const U32 offset) { this->yOffset = offset; } inline R32 GenericHeader::XCenter() const { return this->xCenter; } inline void GenericHeader::SetXCenter(const R32 center) { this->xCenter = center; } inline R32 GenericHeader::YCenter() const { return this->yCenter; } inline void GenericHeader::SetYCenter(const R32 center) { this->yCenter = center; } inline U32 GenericHeader::XOriginalSize() const { return this->xOriginalSize; } inline void GenericHeader::SetXOriginalSize(const U32 size) { this->xOriginalSize = size; } inline U32 GenericHeader::YOriginalSize() const { return this->yOriginalSize; } inline void GenericHeader::SetYOriginalSize(const U32 size) { this->yOriginalSize = size; } inline void GenericHeader::SourceImageFileName(char *fn) const { ::strncpy(fn, this->sourceImageFileName, sizeof(this->sourceImageFileName)); fn[100] = '\0'; } inline void GenericHeader::SetSourceImageFileName(const char *fn) { ::strncpy(this->sourceImageFileName, fn, sizeof(this->sourceImageFileName)); } inline void GenericHeader::SourceTimeDate(char *td) const { ::strncpy(td, this->sourceTimeDate, sizeof(this->sourceTimeDate)); td[24] = '\0'; } inline void GenericHeader::SetSourceTimeDate(const char *td) { ::strncpy(this->sourceTimeDate, td, sizeof(this->sourceTimeDate)); } inline void GenericHeader::InputDevice(char *dev) const { ::strncpy(dev, this->inputDevice, sizeof(this->inputDevice)); dev[32] = '\0'; } inline void GenericHeader::SetInputDevice(const char *dev) { ::strncpy(this->inputDevice, dev, sizeof(this->inputDevice)); } inline void GenericHeader::InputDeviceSerialNumber(char *sn) const { ::strncpy(sn, this->inputDeviceSerialNumber, sizeof(this->inputDeviceSerialNumber)); sn[32] = '\0'; } inline void GenericHeader::SetInputDeviceSerialNumber(const char *sn) { ::strncpy(this->inputDeviceSerialNumber, sn, sizeof(this->inputDeviceSerialNumber)); } inline U16 GenericHeader::Border(const int i) const { if (i < 0 || i > 3) return 0xffff; return this->border[i]; } inline void GenericHeader::SetBorder(const int i, const U16 bord) { if (i < 0 || i > 3) return; this->border[i] = bord; } inline U32 GenericHeader::AspectRatio(const int i) const { if (i != 0 && i != 1) return 0xffffffff; return this->aspectRatio[i]; } inline void GenericHeader::SetAspectRatio(const int i, const U32 ar) { if (i != 0 && i != 1) return; this->aspectRatio[i] = ar; } inline R32 GenericHeader::XScannedSize() const { return this->xScannedSize; } inline void GenericHeader::SetXScannedSize(const R32 size) { this->xScannedSize = size; } inline R32 GenericHeader::YScannedSize() const { return this->yScannedSize; } inline void GenericHeader::SetYScannedSize(const R32 size) { this->yScannedSize = size; } inline void IndustryHeader::Format(char *fmt) const { ::strncpy(fmt, this->format, sizeof(this->format)); fmt[32] = '\0'; } inline void IndustryHeader::SetFormat(const char *fmt) { ::strncpy(this->format, fmt, sizeof(this->format)); } inline U32 IndustryHeader::FramePosition() const { return this->framePosition; } inline void IndustryHeader::SetFramePosition(const U32 pos) { this->framePosition = pos; } inline U32 IndustryHeader::SequenceLength() const { return this->sequenceLength; } inline void IndustryHeader::SetSequenceLength(const U32 len) { this->sequenceLength = len; } inline U32 IndustryHeader::HeldCount() const { return this->heldCount; } inline void IndustryHeader::SetHeldCount(const U32 count) { this->heldCount = count; } inline R32 IndustryHeader::FrameRate() const { return this->frameRate; } inline void IndustryHeader::SetFrameRate(const R32 rate) { this->frameRate = rate; } inline R32 IndustryHeader::ShutterAngle() const { return this->shutterAngle; } inline void IndustryHeader::SetShutterAngle(const R32 angle) { this->shutterAngle = angle; } inline void IndustryHeader::FrameId(char *id) const { ::strncpy(id, this->frameId, sizeof(this->frameId)); id[32] = '\0'; } inline void IndustryHeader::SetFrameId(const char *id) { ::strncpy(this->frameId, id, sizeof(this->frameId)); } inline void IndustryHeader::SlateInfo(char *slate) const { ::strncpy(slate, this->slateInfo, sizeof(this->slateInfo)); slate[100] = '\0'; } inline void IndustryHeader::SetSlateInfo(const char *slate) { ::strncpy(this->slateInfo, slate, sizeof(this->slateInfo)); } inline U8 IndustryHeader::Interlace() const { return this->interlace; } inline void IndustryHeader::SetInterlace(const U8 lace) { this->interlace = lace; } inline U8 IndustryHeader::FieldNumber() const { return this->fieldNumber; } inline void IndustryHeader::SetFieldNumber(const U8 fn) { this->fieldNumber = fn; } inline VideoSignal IndustryHeader::Signal() const { return VideoSignal(this->videoSignal); } inline void IndustryHeader::SetSignal(const VideoSignal vs) { this->videoSignal = vs; } inline R32 IndustryHeader::HorizontalSampleRate() const { return this->horizontalSampleRate; } inline void IndustryHeader::SetHorizontalSampleRate(const R32 rate) { this->horizontalSampleRate = rate; } inline R32 IndustryHeader::VerticalSampleRate() const { return this->verticalSampleRate; } inline void IndustryHeader::SetVerticalSampleRate(const R32 rate) { this->verticalSampleRate = rate; } inline R32 IndustryHeader::TemporalFrameRate() const { return this->temporalFrameRate; } inline void IndustryHeader::SetTemporalFrameRate(const R32 rate) { this->temporalFrameRate = rate; } inline R32 IndustryHeader::TimeOffset() const { return this->timeOffset; } inline void IndustryHeader::SetTimeOffset(const R32 offset) { this->timeOffset = offset; } inline R32 IndustryHeader::Gamma() const { return this->gamma; } inline void IndustryHeader::SetGamma(const R32 g) { this->gamma = g; } inline R32 IndustryHeader::BlackLevel() const { return this->blackLevel; } inline void IndustryHeader::SetBlackLevel(const R32 bl) { this->blackLevel = bl; } inline R32 IndustryHeader::BlackGain() const { return this->blackGain; } inline void IndustryHeader::SetBlackGain(const R32 bg) { this->blackGain = bg; } inline R32 IndustryHeader::BreakPoint() const { return this->breakPoint; } inline void IndustryHeader::SetBreakPoint(const R32 bp) { this->breakPoint = bp; } inline R32 IndustryHeader::WhiteLevel() const { return this->whiteLevel; } inline void IndustryHeader::SetWhiteLevel(const R32 wl) { this->whiteLevel = wl; } inline R32 IndustryHeader::IntegrationTimes() const { return this->integrationTimes; } inline void IndustryHeader::SetIntegrationTimes(const R32 times) { this->integrationTimes = times; } } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/OutStream.cpp0000644000175000017500000000475512271062644023240 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include "filesystem.h" #include "DPXStream.h" OutStream::OutStream() : fp(0) { } OutStream::~OutStream() { } bool OutStream::Open(const char *f) { if (this->fp) this->Close(); if ((this->fp = OIIO::Filesystem::fopen(f, "wb")) == 0) return false; return true; } void OutStream::Close() { if (this->fp) { ::fclose(this->fp); this->fp = 0; } } size_t OutStream::Write(void *buf, const size_t size) { if (this->fp == 0) return false; return ::fwrite(buf, 1, size, this->fp); } bool OutStream::Seek(long offset, Origin origin) { int o = 0; switch (origin) { case kCurrent: o = SEEK_CUR; break; case kEnd: o = SEEK_END; break; case kStart: o = SEEK_SET; break; } if (this->fp == 0) return -1; return (::fseek(this->fp, offset, o) == 0); } void OutStream::Flush() { if (this->fp) ::fflush(this->fp); } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/DPXColorConverter.h0000644000175000017500000001511612271062644024275 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_COLORCONVERTER_H #define _DPX_COLORCONVERTER_H 1 #include "DPX.h" namespace dpx { // convert between all of the various pixel formats and RGB in a controllable way /*! * \brief Query the size of the buffer necessary to hold the decoded RGB data * \param header DPX header * \param element image element (0-7) * \param block image area (used only for calculating the amount of pixels, * not an offset into the buffer) * \return zero: conversion impossible or unsupported; absolute value: size * of the buffer in bytes; sign: positive - memory needs to be allocated, * negative - allocation is optional, decoded data can replace the input */ int QueryRGBBufferSize(const Header &header, const int element, const Block &block); /*! * \brief Query the size of the buffer necessary to hold the decoded RGB data * \param header DPX header * \param element image element (0-7) * \return zero: conversion impossible or unsupported; absolute value: size * of the buffer in bytes; sign: positive - memory needs to be allocated, * negative - allocation is optional, decoded data can replace the input */ int QueryRGBBufferSize(const Header &header, const int element); /*! * \brief Convert native data from the input buffer into RGB in the output buffer * \param header DPX header * \param element image element (0-7) * \param input input buffer data; can be same as output if \ref QueryRGBBufferSize returns a negative number * \param output output buffer data; can be same as input if \ref QueryRGBBufferSize returns a negative number * \param block image area (used only for calculating the amount of pixels, * not an offset into the buffer) * \return success true/false */ bool ConvertToRGB(const Header &header, const int element, const void *input, void *output, const Block &block); /*! * \brief Convert native data from the input buffer into RGB in the output buffer * \param header DPX header * \param element image element (0-7) * \param input input buffer data; can be same as output if \ref QueryRGBBufferSize returns a negative number * \param output output buffer data; can be same as input if \ref QueryRGBBufferSize returns a negative number * \return success true/false */ bool ConvertToRGB(const Header &header, const int element, const void *input, void *output); /*! * \brief Query the size of the buffer necessary to hold the encoded native data * \param desc descriptor of the target pixel format * \param compSize component data storage data type of the target pixel format * \param block image area (used only for calculating the amount of pixels, * not an offset into the buffer) * \return zero: conversion impossible or unsupported; absolute value: size * of the buffer in bytes; sign: positive - memory needs to be allocated, * negative - allocation is optional, decoded data can replace the input */ int QueryNativeBufferSize(const Descriptor desc, const DataSize compSize, const Block &block); /*! * \brief Query the size of the buffer necessary to hold the encoded native data * \param desc descriptor of the target pixel format * \param compSize component data storage data type of the target pixel format * \return zero: conversion impossible or unsupported; absolute value: size * of the buffer in bytes; sign: positive - memory needs to be allocated, * negative - allocation is optional, decoded data can replace the input */ int QueryNativeBufferSize(const Descriptor desc, const DataSize compSize, const int width, const int height); /*! * \brief Convert RGB data from the input buffer into native format in the output buffer * \param desc descriptor of the target pixel format * \param compSize component data storage data type of the target pixel format * \param cmetr colorimetric of the target pixel format * \param input input buffer data; can be same as output if \ref QueryNativeBufferSize returns a negative number * \param output output buffer data; can be same as intput if \ref QueryNativeBufferSize returns a negative number * \param block image area (used only for calculating the amount of pixels, * not an offset into the buffer) * \return success true/false */ bool ConvertToNative(const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const void *input, void *output, const Block &block); /*! * \brief Convert RGB data from the input buffer into native format in the output buffer * \param desc descriptor of the target pixel format * \param compSize component data storage data type of the target pixel format * \param cmetr colorimetric of the target pixel format * \param input input buffer data; can be same as output if \ref QueryNativeBufferSize returns a negative number * \param output output buffer data; can be same as input if \ref QueryNativeBufferSize returns a negative number * \return success true/false */ bool ConvertToNative(const Descriptor desc, const DataSize compSize, const Characteristic cmetr, const int width, const int height, const void *input, void *output); } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/ReaderInternal.h0000644000175000017500000005310512271062644023652 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DPX_READERINTERNAL_H #define _DPX_READERINTERNAL_H 1 #include #include "BaseTypeConverter.h" #define PADDINGBITS_10BITFILLEDMETHODA 2 #define PADDINGBITS_10BITFILLEDMETHODB 0 #define MASK_10BITPACKED 0xffc0 #define MULTIPLIER_10BITPACKED 2 #define REMAIN_10BITPACKED 4 #define REVERSE_10BITPACKED 6 #define MASK_12BITPACKED 0xfff0 #define MULTIPLIER_12BITPACKED 4 #define REMAIN_12BITPACKED 2 #define REVERSE_12BITPACKED 4 namespace dpx { // this function is called when the DataSize is 10 bit and the packing method is kFilledMethodA or kFilledMethodB template void Unfill10bitFilled(U32 *readBuf, const int x, BUF *data, int count, int bufoff, const int numberOfComponents) { // unpack the words in the buffer BUF *obuf = data + bufoff; int index = (x * sizeof(U32)) % numberOfComponents; for (int i = count - 1; i >= 0; i--) { // unpacking the buffer backwords register U32 word = readBuf[(i + index) / 3 / sizeof(U32)]; register U16 d1 = U16(word >> ((2 - (i + index) % 3) * 10 + PADDINGBITS) & 0x3ff); BaseTypeConvertU10ToU16(d1, d1); BaseTypeConverter(d1, obuf[i]); } #if 0 // NOTE: REVERSE -- is this something we really need to handle? // There were many dpx images that write the components backwords // because of some confusion with DPX v1 spec switch (dpxHeader.DatumSwap(element)) { case 0: // no swap for (i = count - 1; i >= 0; i--) { U32 word = readBuf[(i + index) / 3 / sizeof(U32)]; U16 d1 = U16(word >> (((i + index) % 3) * 10 + PADDINGBITS) & 0x3ff); BaseTypeConvertU10ToU16(d1, d1); BaseTypeConverter(d1, obuf[i]); } case 1: // swap the three datum around so BGR becomes RGB for (i = count - 1; i >= 0; i--) { // unpacking the buffer backwords U32 word = readBuf[(i + index) / 3 / sizeof(U32)]; U16 d1 = U16(word >> ((2 - (i + index) % 3) * 10 + PADDINGBITS) & 0x3ff); BaseTypeConvertU10ToU16(d1, d1); BaseTypeConverter(d1, obuf[i]); } // NOTE: NOT DONE case 2 case 2: // swap the second two of three datum around so YCrCb becomes YCbCr for (i = count - 1; i >= 0; i--) { // unpacking the buffer backwords U32 word = readBuf[(i + index) / 3 / sizeof(U32)]; U16 d1 = U16(word >> ((2 - (count + index) % 3) * 10 + PADDINGBITS) & 0x3ff); BaseTypeConvertU10ToU16(d1, d1); BaseTypeConverter(d1, obuf[i]); } } #endif } template bool Read10bitFilled(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) { // image height to read const int height = block.y2 - block.y1 + 1; // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); // end of line padding int eolnPad = dpxHeader.EndOfLinePadding(element); // number of datums in one row int datums = dpxHeader.Width() * numberOfComponents; // Line length in bytes rounded to 32 bits boundary int lineLength = ((datums - 1) / 3 + 1) * 4; // read in each line at a time directly into the user memory space for (int line = 0; line < height; line++) { // determine offset into image element int actline = line + block.y1; // first get line offset long offset = actline * lineLength; // add in eoln padding offset += line * eolnPad; // add in offset within the current line, rounding down so to catch any components within the word offset += block.x1 * numberOfComponents / 3 * 4; // get the read count in bytes, round to the 32-bit boundry int readSize = (block.x2 - block.x1 + 1) * numberOfComponents; readSize += readSize % 3; readSize = readSize / 3 * 4; // determine buffer offset int bufoff = line * datums; fd->Read(dpxHeader, element, offset, readBuf, readSize); // unpack the words in the buffer #if RLE_WORKING int count = (block.x2 - block.x1 + 1) * numberOfComponents; Unfill10bitFilled(readBuf, block.x1, data, count, bufoff, numberOfComponents); #else BUF *obuf = data + bufoff; int index = (block.x1 * sizeof(U32)) % numberOfComponents; for (int count = (block.x2 - block.x1 + 1) * numberOfComponents - 1; count >= 0; count--) { // unpacking the buffer backwords U16 d1 = U16(readBuf[(count + index) / 3] >> ((2 - (count + index) % 3) * 10 + PADDINGBITS) & 0x3ff); BaseTypeConvertU10ToU16(d1, d1); BaseTypeConverter(d1, obuf[count]); // work-around for 1-channel DPX images - to swap the outlying pixels, otherwise the columns are in the wrong order if (numberOfComponents == 1 && count % 3 == 0) std::swap(obuf[count], obuf[count + 2]); } #endif } return true; } template bool Read10bitFilledMethodA(const Header &dpx, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) { // padding bits for PackedMethodA is 2 return Read10bitFilled(dpx, readBuf, fd, element, block, data); } template bool Read10bitFilledMethodB(const Header &dpx, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) { return Read10bitFilled(dpx, readBuf, fd, element, block, data); } // 10 bit, packed data // 12 bit, packed data template void UnPackPacked(U32 *readBuf, const int bitDepth, BUF *data, int count, int bufoff) { // unpack the words in the buffer BUF *obuf = data + bufoff; for (int i = count - 1; i >= 0; i--) { // unpacking the buffer backwords // find the byte that the data starts in, read in as a 16 bits then shift and mask // the pattern with byte offset is: // 10 bits datasize rotates every 4 data elements // element 0 -> 6 bit shift to normalize at MSB (10 LSB shifted 6 bits) // element 1 -> 4 bit shift to normalize at MSB // element 2 -> 2 bit shift to normalize at MSB // element 3 -> 0 bit shift to normalize at MSB // 10 bit algorithm: (6-((count % 4)*2)) // the pattern repeats every 160 bits // 12 bits datasize rotates every 2 data elements // element 0 -> 4 bit shift to normalize at MSB // element 1 -> 0 bit shift to normalize at MSB // 12 bit algorithm: (4-((count % 2)*4)) // the pattern repeats every 96 bits // first determine the word that the data element completely resides in U16 *d1 = reinterpret_cast(reinterpret_cast(readBuf)+((i * bitDepth) / 8 /*bits*/)); // place the component in the MSB and mask it for both 10-bit and 12-bit U16 d2 = (*d1 << (REVERSE - ((i % REMAIN) * MULTIPLIER))) & MASK; // For the 10/12 bit cases, specialize the 16-bit conversion by // repacking into the LSB and using a specialized conversion if(bitDepth == 10) { d2 = d2 >> REVERSE; BaseTypeConvertU10ToU16(d2, d2); } else if(bitDepth == 12) { d2 = d2 >> REVERSE; BaseTypeConvertU12ToU16(d2, d2); } BaseTypeConverter(d2, obuf[i]); } } template bool ReadPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) { // image height to read const int height = block.y2 - block.y1 + 1; // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); // end of line padding int eolnPad = dpxHeader.EndOfLinePadding(element); // data size in bits const int dataSize = dpxHeader.BitDepth(element); // number of bytes const int lineSize = (dpxHeader.Width() * numberOfComponents * dataSize + 31) / 32; // read in each line at a time directly into the user memory space for (int line = 0; line < height; line++) { // determine offset into image element long offset = (line + block.y1) * (lineSize * sizeof(U32)) + (block.x1 * numberOfComponents * dataSize / 32 * sizeof(U32)) + (line * eolnPad); // calculate read size int readSize = ((block.x2 - block.x1 + 1) * numberOfComponents * dataSize); readSize += (block.x1 * numberOfComponents * dataSize % 32); // add the bits left over from the beginning of the line readSize = ((readSize + 31) / 32) * sizeof(U32); // calculate buffer offset int bufoff = line * dpxHeader.Width() * numberOfComponents; fd->Read(dpxHeader, element, offset, readBuf, readSize); // unpack the words in the buffer int count = (block.x2 - block.x1 + 1) * numberOfComponents; UnPackPacked(readBuf, dataSize, data, count, bufoff); } return true; } template bool Read10bitPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) { return ReadPacked(dpxHeader, readBuf, fd, element, block, data); } template bool Read12bitPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) { return ReadPacked(dpxHeader, readBuf, fd, element, block, data); } template bool ReadBlockTypes(const Header &dpxHeader, SRC *readBuf, IR *fd, const int element, const Block &block, BUF *data) { // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); // byte count component type const int bytes = dpxHeader.ComponentByteCount(element); // image image/height to read const int width = (block.x2 - block.x1 + 1) * numberOfComponents; const int height = block.y2 - block.y1 + 1; // end of line padding int eolnPad = dpxHeader.EndOfLinePadding(element); if (eolnPad == ~0) eolnPad = 0; // image width const int imageWidth = dpxHeader.Width(); // read in each line at a time directly into the user memory space for (int line = 0; line < height; line++) { // determine offset into image element long offset = (line + block.y1) * imageWidth * numberOfComponents * bytes + block.x1 * numberOfComponents * bytes + (line * eolnPad); if (BUFTYPE == SRCTYPE) { fd->ReadDirect(dpxHeader, element, offset, reinterpret_cast(data + (width*line)), width*bytes); } else { fd->Read(dpxHeader, element, offset, readBuf, width*bytes); // convert data for (int i = 0; i < width; i++) BaseTypeConverter(readBuf[i], data[width*line+i]); } } return true; } template bool Read12bitFilledMethodB(const Header &dpxHeader, U16 *readBuf, IR *fd, const int element, const Block &block, BUF *data) { // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); // image width & height to read const int width = (block.x2 - block.x1 + 1) * numberOfComponents; const int height = block.y2 - block.y1 + 1; // width of image const int imageWidth = dpxHeader.Width(); // end of line padding (not a required data element so check for ~0) int eolnPad = dpxHeader.EndOfLinePadding(element); if (eolnPad == ~0) eolnPad = 0; // read in each line at a time directly into the user memory space for (int line = 0; line < height; line++) { // determine offset into image element long offset = (line + block.y1) * imageWidth * numberOfComponents * 2 + block.x1 * numberOfComponents * 2 + (line * eolnPad); fd->Read(dpxHeader, element, offset, readBuf, width*2); // convert data for (int i = 0; i < width; i++) { U16 d1 = readBuf[i]; BaseTypeConvertU12ToU16(d1, d1); BaseTypeConverter(d1, data[width*line+i]); } } return true; } #ifdef RLE_WORKING template void ProcessImageBlock(const Header &dpxHeader, const int element, U32 *readBuf, const int x, BUF *data, const int bufoff) { const int bitDepth = dpxHeader.BitDepth(element); const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); const Packing packing = dpxHeader.ImagePacking(element); if (bitDepth == 10) { if (packing == kFilledMethodA) Read10bitFilledMethodA(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); Unfill10bitFilled(readBuf, x, data, count, bufoff, numberOfComponents); else if (packing == kFilledMethodB) Read10bitFilledMethodB(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); else if (packing == kPacked) Read10bitPacked(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); UnPackPacked(readBuf, dataSize, data, count, bufoff); } else if (bitDepth == 12) { if (packing == kPacked) Read12bitPacked(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); else if (packing == kFilledMethodB) Read12bitFilledMethodB(dpxHeader, reinterpret_cast(readBuf), fd, element, block, reinterpret_cast(data)); } } #endif template bool ReadImageBlock(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, BUF *data) { const int bitDepth = dpxHeader.BitDepth(element); const DataSize size = dpxHeader.ComponentDataSize(element); const Packing packing = dpxHeader.ImagePacking(element); if (bitDepth == 10) { if (packing == kFilledMethodA) return Read10bitFilledMethodA(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); else if (packing == kFilledMethodB) return Read10bitFilledMethodB(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); else if (packing == kPacked) return Read10bitPacked(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); } else if (bitDepth == 12) { if (packing == kPacked) return Read12bitPacked(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); else if (packing == kFilledMethodB) // filled method B // 12 bits fill LSB of 16 bits return Read12bitFilledMethodB(dpxHeader, reinterpret_cast(readBuf), fd, element, block, reinterpret_cast(data)); else // filled method A // 12 bits fill MSB of 16 bits return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, element, block, reinterpret_cast(data)); } else if (size == dpx::kByte) return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, element, block, reinterpret_cast(data)); else if (size == dpx::kWord) return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, element, block, reinterpret_cast(data)); else if (size == dpx::kInt) return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, element, block, reinterpret_cast(data)); else if (size == dpx::kFloat) return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, element, block, reinterpret_cast(data)); else if (size == dpx::kDouble) return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, element, block, reinterpret_cast(data)); // should not reach here return false; } template bool ReadImageBlock(const Header &dpxHeader, U32 *readBuf, IR *fd, const int element, const Block &block, void *data, const DataSize size) { if (size == dpx::kByte) return ReadImageBlock(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); else if (size == dpx::kWord) return ReadImageBlock(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); else if (size == dpx::kInt) return ReadImageBlock(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); else if (size == dpx::kFloat) return ReadImageBlock(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); else if (size == dpx::kDouble) return ReadImageBlock(dpxHeader, readBuf, fd, element, block, reinterpret_cast(data)); // should not reach here return false; } #ifdef RLE_WORKING // THIS IS PART OF THE INCOMPLETE RLE CODE // src is full image without any eoln padding template void CopyImageBlock(const Header &dpxHeader, const int element, SRC *src, DataSize srcSize, DST *dst, DataSize dstSize, const Block &block) { const int numberOfComponents = dpxHeader.ImageElementComponentCount(element); const int width = dpxHeader.Width(); const int byteCount = dpxHeader.ComponentByteCount(element); const int pixelByteCount = numberOfComponents * byteCount; int srcoff, dstoff; int x, y, nc; if (srcSize == dstSize) { int lineSize = (width * numberOfComponents * byteCount); U8 * srcU8 = reinterpret_cast(src); U8 * dstU8 = reinterpret_cast(dst); for (y = block.y1; y <= block.y2; y++) { int copySize = (block.x2 - block.x1 + 1) * numberOfComponents * byteCount; memcpy(srcU8 + (y * lineSize) + (block.x1 * numberOfComponents * byteCount), dstU8, copySize); outBuf += copySize; } return; } for (y = block.y1; y <= block.y2; y++) { dstoff = (y - block.y1) * ((block.x2 - block.x1 + 1) * numberOfComponents) - block.x1; for (x = block.x1; x <= block.x2; x++) { for (nc = 0; nc < numberOfComponents; nc++) { SRC d1 = src[(y * width * numberOfComponents) + (x * numberOfComponents) + nc]; BaseTypeConverter(d1, dst[dstoff+((x-block.x1)*numberOfComponents) + nc]); } } } } template void CopyImageBlock(const Header &dpxHeader, const int element, SRC *src, DataSize srcSize, void *dst, DataSize dstSize, const Block &block) { if (dstSize == dpx::kByte) CopyImageBlock(dpxHeader, element, src, srcSize, reinterpret_cast(dst), dstSize, block); else if (dstSize == dpx::kWord) CopyImageBlock(dpxHeader, element, src, srcSize, reinterpret_cast(dst), dstSize, block); else if (dstSize == dpx::kInt) CopyImageBlock(dpxHeader, element, src, srcSize, reinterpret_cast(dst), dstSize, block); else if (dstSize == dpx::kFloat) CopyImageBlock(dpxHeader, element, src, srcSize, reinterpret_cast(dst), dstSize, block); else if (dstSize == dpx::kDouble) CopyImageBlock(dpxHeader, element, src, srcSize, reinterpret_cast(dst), dstSize, block); } void CopyImageBlock(const Header &dpxHeader, const int element, void *src, DataSize srcSize, void *dst, DataSize dstSize, const Block &block) { if (srcSize == dpx::kByte) CopyImageBlock(dpxHeader, element, reinterpret_cast(src), srcSize, dst, dstSize, block); else if (srcSize == dpx::kWord) CopyImageBlock(dpxHeader, element, reinterpret_cast(src), srcSize, dst, dstSize, block); else if (srcSize == dpx::kInt) CopyImageBlock(dpxHeader, element, reinterpret_cast(src), srcSize, dst, dstSize, block); else if (srcSize == dpx::kFloat) CopyImageBlock(dpxHeader, element, reinterpret_cast(src), srcSize, dst, dstSize, block); else if (srcSize == dpx::kDouble) CopyImageBlock(dpxHeader, element, reinterpret_cast(src), srcSize, dst, dstSize, block); } #endif } #endif openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/libdpx/Reader.cpp0000644000175000017500000001351212271062644022506 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2009, Patrick A. Palmer. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "DPX.h" #include "EndianSwap.h" #include "ReaderInternal.h" #include "ElementReadStream.h" #include "Codec.h" #include "RunLengthEncoding.h" dpx::Reader::Reader() : fd(0), rio(0) { // initialize all of the Codec* to NULL for (int i = 0; i < MAX_ELEMENTS; i++) this->codex[i] = 0; } dpx::Reader::~Reader() { this->Reset(); } void dpx::Reader::Reset() { // delete all of the Codec * entries for (int i = 0; i < MAX_ELEMENTS; i++) if (this->codex[i]) { delete codex[i]; this->codex[i] = 0; } // Element Reader if (this->rio) { delete rio; this->rio = 0; } if (this->fd) this->rio = new ElementReadStream(this->fd); } void dpx::Reader::SetInStream(InStream *fd) { this->fd = fd; this->Reset(); } bool dpx::Reader::ReadHeader() { return this->header.Read(this->fd); } bool dpx::Reader::ReadImage(const int element, void *data) { Block block(0, 0, this->header.Width()-1, this->header.Height()-1); return this->ReadBlock(element, (unsigned char *)data, block); } /* implementation notes: dpx::readBlock reads in the image starting from the beginning of the channel. This can be optimized if the image isn't encoded; we can skip forward in the file to close to the start of (block.x1, block.y1) and determine exactly which bit will be the start. This certainly will save some time for cases where we are only reading ROIs (regions of interest). */ bool dpx::Reader::ReadBlock(const int element, unsigned char *data, Block &block) { // make sure the range is good if (element < 0 || element >= MAX_ELEMENTS) return false; // make sure the entry is valid if (this->header.ImageDescriptor(element) == kUndefinedDescriptor) return false; // get the number of components for this element descriptor const int numberOfComponents = this->header.ImageElementComponentCount(element); // bit depth of the image element const int bitDepth = this->header.BitDepth(element); // rle encoding? const bool rle = (this->header.ImageEncoding(element) == kRLE); // data size for the element const DataSize size = this->header.ComponentDataSize(element); // lets see if this can be done in a single fast read if (!rle && this->header.EndOfLinePadding(element) == 0 && ((bitDepth == 8 && size == dpx::kByte) || (bitDepth == 16 && size == dpx::kWord) || (bitDepth == 32 && size == dpx::kFloat) || (bitDepth == 64 && size == dpx::kDouble)) && block.x1 == 0 && block.x2 == (int)(this->header.Width()-1)) { // seek to the beginning of the image block if (this->fd->Seek((this->header.DataOffset(element) + (block.y1 * this->header.Width() * (bitDepth / 8) * numberOfComponents)), InStream::kStart) == false) return false; // size of the image const size_t imageSize = this->header.Width() * (block.y2 - block.y1 + 1) * numberOfComponents; const size_t imageByteSize = imageSize * bitDepth / 8; size_t rs = this->fd->ReadDirect(data, imageByteSize); if (rs != imageByteSize) return false; // swap the bytes if different byte order if (this->header.RequiresByteSwap()) dpx::EndianSwapImageBuffer(size, data, imageSize); return true; } // determine if the encoding system is loaded if (this->codex[element] == 0) { // this element reader has not been used if (rle) // TODO //this->codex[element] = new RunLengthEncoding; return false; else this->codex[element] = new Codec; } // read the image block return this->codex[element]->Read(this->header, this->rio, element, block, data, size); } bool dpx::Reader::ReadUserData(unsigned char *data) { // check to make sure there is some user data if (this->header.UserSize() == 0) return true; // seek to the beginning of the user data block if (this->fd->Seek(sizeof(GenericHeader) + sizeof(IndustryHeader), InStream::kStart) == false) return false; size_t rs = this->fd->ReadDirect(data, this->header.UserSize()); if (rs != this->header.UserSize()) return false; return true; } openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/dpxoutput.cpp0000644000175000017500000006141012271062644022076 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "libdpx/DPX.h" #include "libdpx/DPXColorConverter.h" #include "typedesc.h" #include "imageio.h" #include "fmath.h" #include "strutil.h" OIIO_PLUGIN_NAMESPACE_BEGIN static const int MAX_DPX_IMAGE_ELEMENTS = 8; // max subimages in DPX spec class DPXOutput : public ImageOutput { public: DPXOutput (); virtual ~DPXOutput (); virtual const char * format_name (void) const { return "dpx"; } virtual bool supports (const std::string &feature) const { if (feature == "multiimage" || feature == "random_access" || feature == "rewrite" || feature == "displaywindow" || feature == "origin") return true; return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool open (const std::string &name, int subimages, const ImageSpec *specs); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: OutStream *m_stream; dpx::Writer m_dpx; std::vector m_buf; std::vector m_scratch; dpx::DataSize m_datasize; dpx::Descriptor m_desc; dpx::Characteristic m_cmetr; dpx::Characteristic m_transfer; dpx::Packing m_packing; int m_bitdepth; bool m_wantRaw, m_wantSwap; int m_bytes; int m_subimage; int m_subimages_to_write; std::vector m_subimage_specs; bool m_write_pending; // subimage buffer needs to be written // Initialize private members to pre-opened state void init (void) { if (m_stream) { m_stream->Close (); delete m_stream; m_stream = NULL; } m_buf.clear (); m_subimage = 0; m_subimages_to_write = 0; m_subimage_specs.clear (); m_write_pending = false; } // Is the output file currently opened? bool is_opened () const { return (m_stream != NULL); } // flush the pending buffer bool write_buffer (); bool prep_subimage (int s, bool allocate); /// Helper function - retrieve libdpx descriptor for string /// dpx::Characteristic get_characteristic_from_string (const std::string &str); /// Helper function - retrieve libdpx descriptor given nchannels and /// the channel names. dpx::Descriptor get_image_descriptor (); /// Helper function - set keycode values from int array /// void set_keycode_values (int *array); }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *dpx_output_imageio_create () { return new DPXOutput; } // OIIO_EXPORT int dpx_imageio_version = OIIO_PLUGIN_VERSION; // it's in dpxinput.cpp OIIO_EXPORT const char * dpx_output_extensions[] = { "dpx", NULL }; OIIO_PLUGIN_EXPORTS_END DPXOutput::DPXOutput () : m_stream(NULL) { init (); } DPXOutput::~DPXOutput () { // Close, if not already done. close (); } bool DPXOutput::open (const std::string &name, int subimages, const ImageSpec *specs) { if (subimages > MAX_DPX_IMAGE_ELEMENTS) { error ("DPX does not support more than %d subimages", MAX_DPX_IMAGE_ELEMENTS); return false; }; m_subimages_to_write = subimages; m_subimage_specs.clear (); m_subimage_specs.insert (m_subimage_specs.begin(), specs, specs+subimages); return open (name, m_subimage_specs[0], Create); } bool DPXOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode == Create) { m_subimage = 0; if (m_subimage_specs.size() < 1) { m_subimage_specs.resize (1); m_subimage_specs[0] = userspec; m_subimages_to_write = 1; } } else if (mode == AppendSubimage) { if (m_write_pending) write_buffer (); ++m_subimage; if (m_subimage >= m_subimages_to_write) { error ("Exceeded the pre-declared number of subimages (%d)", m_subimages_to_write); return false; } return prep_subimage (m_subimage, true); // Nothing else to do, the header taken care of when we opened with // Create. } else if (mode == AppendMIPLevel) { error ("DPX does not support MIP-maps"); return false; } // From here out, all the heavy lifting is done for Create ASSERT (mode == Create); if (is_opened()) close (); // Close any already-opened file m_stream = new OutStream(); if (! m_stream->Open(name.c_str ())) { error ("Could not open file \"%s\"", name.c_str ()); return false; } m_dpx.SetOutStream (m_stream); m_dpx.Start (); m_subimage = 0; ImageSpec &m_spec (m_subimage_specs[m_subimage]); // alias the spec // Check for things this format doesn't support if (m_spec.width < 1 || m_spec.height < 1) { error ("Image resolution must be at least 1x1, you asked for %d x %d", m_spec.width, m_spec.height); return false; } if (m_spec.depth < 1) m_spec.depth = 1; else if (m_spec.depth > 1) { error ("DPX does not support volume images (depth > 1)"); return false; } // some metadata std::string software = m_spec.get_string_attribute ("Software", ""); std::string project = m_spec.get_string_attribute ("DocumentName", ""); std::string copyright = m_spec.get_string_attribute ("Copyright", ""); std::string datestr = m_spec.get_string_attribute ("DateTime", ""); if (datestr.size () >= 19) { // libdpx's date/time format is pretty close to OIIO's (libdpx uses // %Y:%m:%d:%H:%M:%S%Z) // NOTE: the following code relies on the DateTime attribute being properly // formatted! // assume UTC for simplicity's sake, fix it if someone complains datestr[10] = ':'; datestr.replace (19, -1, "Z"); } // check if the client wants endianness reverse to native // assume big endian per Jeremy's request, unless little endian is // explicitly specified std::string endian = m_spec.get_string_attribute ("oiio:Endian", littleendian() ? "little" : "big"); m_wantSwap = (littleendian() != Strutil::iequals (endian, "little")); m_dpx.SetFileInfo (name.c_str (), // filename datestr.c_str (), // cr. date software.empty () ? OIIO_INTRO_STRING : software.c_str (), // creator project.empty () ? NULL : project.c_str (), // project copyright.empty () ? NULL : copyright.c_str (), // copyright m_spec.get_int_attribute ("dpx:EncryptKey", ~0), // encryption key m_wantSwap); // image info m_dpx.SetImageInfo (m_spec.width, m_spec.height); for (int s = 0; s < m_subimages_to_write; ++s) { prep_subimage (s, false); m_dpx.header.SetBitDepth (s, m_bitdepth); ImageSpec &spec (m_subimage_specs[s]); bool datasign = (spec.format == TypeDesc::INT8 || spec.format == TypeDesc::INT16); m_dpx.SetElement (s, m_desc, m_bitdepth, m_transfer, m_cmetr, m_packing, dpx::kNone, datasign, spec.get_int_attribute ("dpx:LowData", 0xFFFFFFFF), spec.get_float_attribute ("dpx:LowQuantity", std::numeric_limits::quiet_NaN()), spec.get_int_attribute ("dpx:HighData", 0xFFFFFFFF), spec.get_float_attribute ("dpx:HighQuantity", std::numeric_limits::quiet_NaN()), spec.get_int_attribute ("dpx:EndOfLinePadding", 0), spec.get_int_attribute ("dpx:EndOfImagePadding", 0)); std::string desc = spec.get_string_attribute ("ImageDescription", ""); m_dpx.header.SetDescription (s, desc.c_str()); } m_dpx.header.SetXScannedSize (m_spec.get_float_attribute ("dpx:XScannedSize", std::numeric_limits::quiet_NaN())); m_dpx.header.SetYScannedSize (m_spec.get_float_attribute ("dpx:YScannedSize", std::numeric_limits::quiet_NaN())); m_dpx.header.SetFramePosition (m_spec.get_int_attribute ("dpx:FramePosition", 0xFFFFFFFF)); m_dpx.header.SetSequenceLength (m_spec.get_int_attribute ("dpx:SequenceLength", 0xFFFFFFFF)); m_dpx.header.SetHeldCount (m_spec.get_int_attribute ("dpx:HeldCount", 0xFFFFFFFF)); m_dpx.header.SetFrameRate (m_spec.get_float_attribute ("dpx:FrameRate", std::numeric_limits::quiet_NaN())); m_dpx.header.SetShutterAngle (m_spec.get_float_attribute ("dpx:ShutterAngle", std::numeric_limits::quiet_NaN())); // FIXME: should we write the input version through or always default to 2.0? /*tmpstr = m_spec.get_string_attribute ("dpx:Version", ""); if (tmpstr.size () > 0) m_dpx.header.SetVersion (tmpstr.c_str ());*/ std::string tmpstr; tmpstr = m_spec.get_string_attribute ("dpx:FrameId", ""); if (tmpstr.size () > 0) m_dpx.header.SetFrameId (tmpstr.c_str ()); tmpstr = m_spec.get_string_attribute ("dpx:SlateInfo", ""); if (tmpstr.size () > 0) m_dpx.header.SetSlateInfo (tmpstr.c_str ()); tmpstr = m_spec.get_string_attribute ("dpx:SourceImageFileName", ""); if (tmpstr.size () > 0) m_dpx.header.SetSourceImageFileName (tmpstr.c_str ()); tmpstr = m_spec.get_string_attribute ("dpx:InputDevice", ""); if (tmpstr.size () > 0) m_dpx.header.SetInputDevice (tmpstr.c_str ()); tmpstr = m_spec.get_string_attribute ("dpx:InputDeviceSerialNumber", ""); if (tmpstr.size () > 0) m_dpx.header.SetInputDeviceSerialNumber (tmpstr.c_str ()); m_dpx.header.SetInterlace (m_spec.get_int_attribute ("dpx:Interlace", 0xFF)); m_dpx.header.SetFieldNumber (m_spec.get_int_attribute ("dpx:FieldNumber", 0xFF)); m_dpx.header.SetHorizontalSampleRate (m_spec.get_float_attribute ("dpx:HorizontalSampleRate", std::numeric_limits::quiet_NaN())); m_dpx.header.SetVerticalSampleRate (m_spec.get_float_attribute ("dpx:VerticalSampleRate", std::numeric_limits::quiet_NaN())); m_dpx.header.SetTemporalFrameRate (m_spec.get_float_attribute ("dpx:TemporalFrameRate", std::numeric_limits::quiet_NaN())); m_dpx.header.SetTimeOffset (m_spec.get_float_attribute ("dpx:TimeOffset", std::numeric_limits::quiet_NaN())); m_dpx.header.SetBlackLevel (m_spec.get_float_attribute ("dpx:BlackLevel", std::numeric_limits::quiet_NaN())); m_dpx.header.SetBlackGain (m_spec.get_float_attribute ("dpx:BlackGain", std::numeric_limits::quiet_NaN())); m_dpx.header.SetBreakPoint (m_spec.get_float_attribute ("dpx:BreakPoint", std::numeric_limits::quiet_NaN())); m_dpx.header.SetWhiteLevel (m_spec.get_float_attribute ("dpx:WhiteLevel", std::numeric_limits::quiet_NaN())); m_dpx.header.SetIntegrationTimes (m_spec.get_float_attribute ("dpx:IntegrationTimes", std::numeric_limits::quiet_NaN())); float aspect = m_spec.get_float_attribute ("PixelAspectRatio", 1.0f); int aspect_num, aspect_den; float_to_rational (aspect, aspect_num, aspect_den); m_dpx.header.SetAspectRatio (0, aspect_num); m_dpx.header.SetAspectRatio (1, aspect_den); m_dpx.header.SetXOffset ((unsigned int)std::max (0, m_spec.x)); m_dpx.header.SetYOffset ((unsigned int)std::max (0, m_spec.y)); m_dpx.header.SetXOriginalSize ((unsigned int)m_spec.full_width); m_dpx.header.SetYOriginalSize ((unsigned int)m_spec.full_height); static int DpxOrientations[] = { 0, dpx::kLeftToRightTopToBottom, dpx::kRightToLeftTopToBottom, dpx::kLeftToRightBottomToTop, dpx::kRightToLeftBottomToTop, dpx::kTopToBottomLeftToRight, dpx::kTopToBottomRightToLeft, dpx::kBottomToTopLeftToRight, dpx::kBottomToTopRightToLeft }; int orient = m_spec.get_int_attribute ("Orientation", 0); orient = DpxOrientations[clamp (orient, 0, 8)]; m_dpx.header.SetImageOrientation ((dpx::Orientation)orient); ImageIOParameter *tc = m_spec.find_attribute("smpte:TimeCode", TypeDesc::TypeTimeCode, false); if (tc) { unsigned int *timecode = (unsigned int*) tc->data(); m_dpx.header.timeCode = timecode[0]; m_dpx.header.userBits = timecode[1]; } else { std::string timecode = m_spec.get_string_attribute ("dpx:TimeCode", ""); int tmpint = m_spec.get_int_attribute ("dpx:TimeCode", ~0); if (timecode.size () > 0) m_dpx.header.SetTimeCode (timecode.c_str ()); else if (tmpint != ~0) m_dpx.header.timeCode = tmpint; m_dpx.header.userBits = m_spec.get_int_attribute ("dpx:UserBits", ~0); } ImageIOParameter *kc = m_spec.find_attribute("smpte:KeyCode", TypeDesc::TypeKeyCode, false); if (kc) { int *array = (int*) kc->data(); set_keycode_values(array); // See if there is an overloaded dpx:Format std::string format = m_spec.get_string_attribute ("dpx:Format", ""); if (format.size () > 0) m_dpx.header.SetFormat (format.c_str ()); } std::string srcdate = m_spec.get_string_attribute ("dpx:SourceDateTime", ""); if (srcdate.size () >= 19) { // libdpx's date/time format is pretty close to OIIO's (libdpx uses // %Y:%m:%d:%H:%M:%S%Z) // NOTE: the following code relies on the DateTime attribute being properly // formatted! // assume UTC for simplicity's sake, fix it if someone complains srcdate[10] = ':'; srcdate.replace (19, -1, "Z"); m_dpx.header.SetSourceTimeDate (srcdate.c_str ()); } // commit! if (!m_dpx.WriteHeader ()) { error ("Failed to write DPX header"); return false; } // user data ImageIOParameter *user = m_spec.find_attribute ("dpx:UserData"); if (user && user->datasize () > 0) { if (user->datasize () > 1024 * 1024) { error ("User data block size exceeds 1 MB"); return false; } // FIXME: write the missing libdpx code /*m_dpx.SetUserData (user->datasize ()); if (!m_dpx.WriteUserData ((void *)user->data ())) { error ("Failed to write user data"); return false; }*/ } return prep_subimage (m_subimage, true); } bool DPXOutput::prep_subimage (int s, bool allocate) { m_spec = m_subimage_specs[s]; // stash the spec // determine descriptor m_desc = get_image_descriptor(); // transfer function std::string colorspace = m_spec.get_string_attribute ("oiio:ColorSpace", ""); if (Strutil::iequals (colorspace, "Linear")) m_transfer = dpx::kLinear; else if (Strutil::iequals (colorspace, "GammaCorrected")) m_transfer = dpx::kUserDefined; else if (Strutil::iequals (colorspace, "Rec709")) m_transfer = dpx::kITUR709; else if (Strutil::iequals (colorspace, "KodakLog")) m_transfer = dpx::kLogarithmic; else { std::string dpxtransfer = m_spec.get_string_attribute ("dpx:Transfer", ""); m_transfer = get_characteristic_from_string (dpxtransfer); } // colorimetric m_cmetr = get_characteristic_from_string (m_spec.get_string_attribute ("dpx:Colorimetric", "User defined")); // select packing method std::string pck = m_spec.get_string_attribute ("dpx:Packing", "Filled, method A"); if (Strutil::iequals (pck, "Packed")) m_packing = dpx::kPacked; else if (Strutil::iequals (pck, "Filled, method B")) m_packing = dpx::kFilledMethodB; else m_packing = dpx::kFilledMethodA; // calculate target bit depth m_bitdepth = m_spec.format.size () * 8; if (m_spec.format == TypeDesc::UINT16) { m_bitdepth = m_spec.get_int_attribute ("oiio:BitsPerSample", 16); if (m_bitdepth != 10 && m_bitdepth != 12 && m_bitdepth != 16) { error ("Unsupported bit depth %d", m_bitdepth); return false; } } // Bug workaround: libDPX doesn't appear to correctly support // "filled method A" for 12 bit data. Does anybody care what // packing/filling we use? Punt and just use "packed". if (m_bitdepth == 12) m_packing = dpx::kPacked; if (m_spec.format == TypeDesc::UINT8 || m_spec.format == TypeDesc::INT8) m_datasize = dpx::kByte; else if (m_spec.format == TypeDesc::UINT16 || m_spec.format == TypeDesc::INT16) m_datasize = dpx::kWord; else if (m_spec.format == TypeDesc::FLOAT || m_spec.format == TypeDesc::HALF) { m_spec.format = TypeDesc::FLOAT; m_datasize = dpx::kFloat; } else if (m_spec.format == TypeDesc::DOUBLE) m_datasize = dpx::kDouble; else { // use 16-bit unsigned integers as a failsafe m_spec.set_format (TypeDesc::UINT16); m_datasize = dpx::kWord; } // check if the client is giving us raw data to write m_wantRaw = m_spec.get_int_attribute ("dpx:RawData", 0) != 0; // see if we'll need to convert or not if (m_desc == dpx::kRGB || m_desc == dpx::kRGBA) { // shortcut for RGB(A) that gets the job done m_bytes = m_spec.scanline_bytes (); m_wantRaw = true; } else { m_bytes = dpx::QueryNativeBufferSize (m_desc, m_datasize, m_spec.width, 1); if (m_bytes == 0 && !m_wantRaw) { error ("Unable to deliver native format data from source data"); return false; } else if (m_bytes < 0) { // no need to allocate another buffer if (!m_wantRaw) m_bytes = m_spec.scanline_bytes (); else m_bytes = -m_bytes; } } if (m_bytes < 0) m_bytes = -m_bytes; // allocate space for the image data buffer if (allocate) m_buf.resize (m_bytes * m_spec.height); return true; } bool DPXOutput::write_buffer () { if (m_write_pending) { m_dpx.WriteElement (m_subimage, &m_buf[0], m_datasize); m_write_pending = false; } return true; } bool DPXOutput::close () { bool ok = true; if (m_stream) { ok &= write_buffer (); m_dpx.Finish (); } init(); // Reset to initial state return ok; } bool DPXOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { m_write_pending = true; m_spec.auto_stride (xstride, format, m_spec.nchannels); const void *origdata = data; data = to_native_scanline (format, data, xstride, m_scratch); if (data == origdata) { m_scratch.assign ((unsigned char *)data, (unsigned char *)data+m_spec.scanline_bytes()); data = &m_scratch[0]; } unsigned char *dst = &m_buf[(y-m_spec.y) * m_bytes]; if (m_wantRaw) // fast path - just dump the scanline into the buffer memcpy (dst, data, m_spec.scanline_bytes ()); else if (!dpx::ConvertToNative (m_desc, m_datasize, m_cmetr, m_spec.width, 1, data, dst)) return false; return true; } dpx::Characteristic DPXOutput::get_characteristic_from_string (const std::string &str) { if (Strutil::iequals (str, "User defined")) return dpx::kUserDefined; else if (Strutil::iequals (str, "Printing density")) return dpx::kPrintingDensity; else if (Strutil::iequals (str, "Linear")) return dpx::kLinear; else if (Strutil::iequals (str, "Logarithmic")) return dpx::kLogarithmic; else if (Strutil::iequals (str, "Unspecified video")) return dpx::kUnspecifiedVideo; else if (Strutil::iequals (str, "SMPTE 274M")) return dpx::kSMPTE274M; else if (Strutil::iequals (str, "ITU-R 709-4")) return dpx::kITUR709; else if (Strutil::iequals (str, "ITU-R 601-5 system B or G")) return dpx::kITUR601; else if (Strutil::iequals (str, "ITU-R 601-5 system M")) return dpx::kITUR602; else if (Strutil::iequals (str, "NTSC composite video")) return dpx::kNTSCCompositeVideo; else if (Strutil::iequals (str, "PAL composite video")) return dpx::kPALCompositeVideo; else if (Strutil::iequals (str, "Z depth linear")) return dpx::kZLinear; else if (Strutil::iequals (str, "Z depth homogeneous")) return dpx::kZHomogeneous; else return dpx::kUndefinedCharacteristic; } dpx::Descriptor DPXOutput::get_image_descriptor () { switch (m_spec.nchannels) { case 1: { std::string name = m_spec.channelnames.size() ? m_spec.channelnames[0] : ""; if (m_spec.z_channel == 0 || name == "Z") return dpx::kDepth; else if (m_spec.alpha_channel == 0 || name == "A") return dpx::kAlpha; else if (name == "R") return dpx::kRed; else if (name == "B") return dpx::kBlue; else if (name == "G") return dpx::kGreen; else return dpx::kLuma; } case 3: return dpx::kRGB; case 4: return dpx::kRGBA; default: if (m_spec.nchannels <= 8) return (dpx::Descriptor)((int)dpx::kUserDefined2Comp + m_spec.nchannels - 2); return dpx::kUndefinedDescriptor; } } void DPXOutput::set_keycode_values (int *array) { // Manufacturer code { std::stringstream ss; ss << std::setfill('0'); ss << std::setw(2) << array[0]; memcpy(m_dpx.header.filmManufacturingIdCode, ss.str().c_str(), 2); } // Film type { std::stringstream ss; ss << std::setfill('0'); ss << std::setw(2) << array[1]; memcpy(m_dpx.header.filmType, ss.str().c_str(), 2); } // Prefix { std::stringstream ss; ss << std::setfill('0'); ss << std::setw(6) << array[2]; memcpy(m_dpx.header.prefix, ss.str().c_str(), 6); } // Count { std::stringstream ss; ss << std::setfill('0'); ss << std::setw(4) << array[3]; memcpy(m_dpx.header.count, ss.str().c_str(), 4); } // Perforation Offset { std::stringstream ss; ss << std::setfill('0'); ss << std::setw(2) << array[4]; memcpy(m_dpx.header.perfsOffset, ss.str().c_str(), 2); } // Format int &perfsPerFrame = array[5]; int &perfsPerCount = array[6]; if (perfsPerFrame == 15 && perfsPerCount == 120) { Strutil::safe_strcpy(m_dpx.header.format, "8kimax", sizeof(m_dpx.header.format)); } else if (perfsPerFrame == 8 && perfsPerCount == 64) { Strutil::safe_strcpy(m_dpx.header.format, "VistaVision", sizeof(m_dpx.header.format)); } else if (perfsPerFrame == 4 && perfsPerCount == 64) { Strutil::safe_strcpy(m_dpx.header.format, "Full Aperture", sizeof(m_dpx.header.format)); } else if (perfsPerFrame == 3 && perfsPerCount == 64) { Strutil::safe_strcpy(m_dpx.header.format, "3perf", sizeof(m_dpx.header.format)); } else { Strutil::safe_strcpy(m_dpx.header.format, "Unknown", sizeof(m_dpx.header.format)); } } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/dpx.imageio/CMakeLists.txt0000644000175000017500000000041412271062644022053 0ustar mfvmfvadd_oiio_plugin (dpxinput.cpp dpxoutput.cpp libdpx/DPX.cpp libdpx/OutStream.cpp libdpx/RunLengthEncoding.cpp libdpx/Codec.cpp libdpx/Reader.cpp libdpx/Writer.cpp libdpx/DPXHeader.cpp libdpx/ElementReadStream.cpp libdpx/InStream.cpp libdpx/DPXColorConverter.cpp) openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/0000755000175000017500000000000012271062644017673 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imageoutput.cpp0000644000175000017500000004600712271062644022751 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "filesystem.h" #include "plugin.h" #include "thread.h" #include "strutil.h" #include "imageio.h" #include "imageio_pvt.h" #include OIIO_NAMESPACE_ENTER { using namespace pvt; bool ImageOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { // Default implementation: don't know how to write scanlines return false; } bool ImageOutput::write_scanlines (int ybegin, int yend, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride) { // Default implementation: write each scanline individually stride_t native_pixel_bytes = (stride_t) m_spec.pixel_bytes (true); if (format == TypeDesc::UNKNOWN && xstride == AutoStride) xstride = native_pixel_bytes; stride_t zstride = AutoStride; m_spec.auto_stride (xstride, ystride, zstride, format, m_spec.nchannels, m_spec.width, yend-ybegin); bool ok = true; for (int y = ybegin; ok && y < yend; ++y) { ok &= write_scanline (y, z, format, data, xstride); data = (char *)data + ystride; } return ok; } bool ImageOutput::write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride) { // Default implementation: don't know how to write tiles return false; } bool ImageOutput::write_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride) { if (! m_spec.valid_tile_range (xbegin, xend, ybegin, yend, zbegin, zend)) return false; // Default implementation: write each tile individually stride_t native_pixel_bytes = (stride_t) m_spec.pixel_bytes (true); if (format == TypeDesc::UNKNOWN && xstride == AutoStride) xstride = native_pixel_bytes; m_spec.auto_stride (xstride, ystride, zstride, format, m_spec.nchannels, xend-xbegin, yend-ybegin); bool ok = true; stride_t pixelsize = format.size() * m_spec.nchannels; boost::scoped_array buf; for (int z = zbegin; z < zend; z += std::max(1,m_spec.tile_depth)) { int zd = std::min (zend-z, m_spec.tile_depth); for (int y = ybegin; y < yend; y += m_spec.tile_height) { char *tilestart = ((char *)data + (z-zbegin)*zstride + (y-ybegin)*ystride); int yh = std::min (yend-y, m_spec.tile_height); for (int x = xbegin; ok && x < xend; x += m_spec.tile_width) { int xw = std::min (xend-x, m_spec.tile_width); // Full tiles are written directly into the user buffer, but // Partial tiles (such as at the image edge) are copied into // a padded buffer to stage them. if (xw == m_spec.tile_width && yh == m_spec.tile_height && zd == m_spec.tile_depth) { ok &= write_tile (x, y, z, format, tilestart, xstride, ystride, zstride); } else { if (! buf.get()) buf.reset (new char [pixelsize * m_spec.tile_pixels()]); OIIO::copy_image (m_spec.nchannels, xw, yh, zd, tilestart, pixelsize, xstride, ystride, zstride, &buf[0], pixelsize, pixelsize*m_spec.tile_width, pixelsize*m_spec.tile_pixels()); ok &= write_tile (x, y, z, format, &buf[0], pixelsize, pixelsize*m_spec.tile_width, pixelsize*m_spec.tile_pixels()); } tilestart += m_spec.tile_width * xstride; } } } return ok; } bool ImageOutput::write_rectangle (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride) { return false; } bool ImageOutput::write_deep_scanlines (int ybegin, int yend, int z, const DeepData &deepdata) { return false; // default: doesn't support deep images } bool ImageOutput::write_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, const DeepData &deepdata) { return false; // default: doesn't support deep images } bool ImageOutput::write_deep_image (const DeepData &deepdata) { if (m_spec.depth > 1) { error ("write_deep_image is not supported for volume (3D) images."); return false; // FIXME? - not implementing 3D deep images for now. The only // format that supports deep images at this time is OpenEXR, and // it doesn't support volumes. } if (m_spec.tile_width) { // Tiled image return write_deep_tiles (m_spec.x, m_spec.x+m_spec.width, m_spec.y, m_spec.y+m_spec.height, m_spec.z, m_spec.z+m_spec.depth, deepdata); } else { // Scanline image return write_deep_scanlines (m_spec.y, m_spec.y+m_spec.height, 0, deepdata); } } int ImageOutput::send_to_output (const char *format, ...) { // FIXME -- I can't remember how this is supposed to work return 0; } int ImageOutput::send_to_client (const char *format, ...) { // FIXME -- I can't remember how this is supposed to work return 0; } void ImageOutput::append_error (const std::string& message) const { ASSERT (m_errmessage.size() < 1024*1024*16 && "Accumulated error messages > 16MB. Try checking return codes!"); if (m_errmessage.size()) m_errmessage += '\n'; m_errmessage += message; } const void * ImageOutput::to_native_scanline (TypeDesc format, const void *data, stride_t xstride, std::vector &scratch) { return to_native_rectangle (0, m_spec.width, 0, 1, 0, 1, format, data, xstride, 0, 0, scratch); } const void * ImageOutput::to_native_tile (TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride, std::vector &scratch) { return to_native_rectangle (0, m_spec.tile_width, 0, m_spec.tile_height, 0, std::max(1,m_spec.tile_depth), format, data, xstride, ystride, zstride, scratch); } const void * ImageOutput::to_native_rectangle (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride, std::vector &scratch) { // native_pixel_bytes is the size of a pixel in the FILE, including // the per-channel format, if specified when the file was opened. stride_t native_pixel_bytes = (stride_t) m_spec.pixel_bytes (true); // perchanfile is true if the file has different per-channel formats bool perchanfile = m_spec.channelformats.size() && supports("channelformats"); // It's an error to pass per-channel data formats to a writer that // doesn't support it. if (m_spec.channelformats.size() && !perchanfile) return NULL; // native_data is true if the user is passing data in the native format bool native_data = (format == TypeDesc::UNKNOWN || (format == m_spec.format && !perchanfile)); // If the user is passing native data and they've left xstride set // to Auto, then we know it's the native pixel size. if (native_data && xstride == AutoStride) xstride = native_pixel_bytes; // Fill in the rest of the strides that haven't been set. m_spec.auto_stride (xstride, ystride, zstride, format, m_spec.nchannels, xend-xbegin, yend-ybegin); // Compute width and height from the rectangle extents int width = xend - xbegin; int height = yend - ybegin; int depth = zend - zbegin; // Do the strides indicate that the data area is contiguous? bool contiguous; if (native_data) { // If it's native data, it had better be contiguous by the // file's definition. contiguous = (xstride == (stride_t)(m_spec.pixel_bytes(native_data))); } else { // If it's not native data, we only care if the user's buffer // is contiguous. contiguous = (xstride == (stride_t)(format.size()*m_spec.nchannels)); } contiguous &= ((ystride == xstride*width || height == 1) && (zstride == ystride*height || depth == 1)); if (native_data && contiguous) { // Data are already in the native format and contiguous // just return a ptr to the original data. return data; } imagesize_t rectangle_pixels = width * height * depth; imagesize_t rectangle_values = rectangle_pixels * m_spec.nchannels; imagesize_t rectangle_bytes = rectangle_pixels * native_pixel_bytes; // Cases to handle: // 1. File has per-channel data, user passes native data -- this has // already returned above, since the data didn't need munging. // 2. File has per-channel data, user passes some other data type // 3. File has uniform data, user passes some other data type // 4. File has uniform data, user passes the right data -- note that // this case already returned if the user data was contiguous // Handle the per-channel format case (#2) where the user is passing // a non-native buffer. if (perchanfile) { if (native_data) { ASSERT (contiguous && "Per-channel native output requires contiguous strides"); } ASSERT (format != TypeDesc::UNKNOWN); ASSERT (m_spec.channelformats.size() == (size_t)m_spec.nchannels); scratch.resize (rectangle_bytes); size_t offset = 0; for (int c = 0; c < m_spec.nchannels; ++c) { TypeDesc chanformat = m_spec.channelformats[c]; convert_image (1 /* channels */, width, height, depth, (char *)data + c*format.size(), format, xstride, ystride, zstride, &scratch[offset], chanformat, native_pixel_bytes, AutoStride, AutoStride, c == m_spec.alpha_channel ? 0 : -1, c == m_spec.z_channel ? 0 : -1); offset += chanformat.size (); } return &scratch[0]; } // The remaining code is where all channels in the file have the // same data type, which may or may not be what the user passed in // (cases #3 and #4 above). imagesize_t contiguoussize = contiguous ? 0 : rectangle_values * native_pixel_bytes; contiguoussize = (contiguoussize+3) & (~3); // Round up to 4-byte boundary DASSERT ((contiguoussize & 3) == 0); imagesize_t floatsize = rectangle_values * sizeof(float); scratch.resize (contiguoussize + floatsize + rectangle_bytes); // Force contiguity if not already present if (! contiguous) { data = contiguize (data, m_spec.nchannels, xstride, ystride, zstride, (void *)&scratch[0], width, height, depth, format); } // Rather than implement the entire cross-product of possible // conversions, use float as an intermediate format, which generally // will always preserve enough precision. const float *buf; if (format == TypeDesc::FLOAT) { // Already in float format -- leave it as-is. buf = (float *)data; } else { // Convert to from 'format' to float. buf = convert_to_float (data, (float *)&scratch[contiguoussize], rectangle_values, format); } // Convert from float to native format. return parallel_convert_from_float (buf, &scratch[contiguoussize+floatsize], rectangle_values, m_spec.quant_black, m_spec.quant_white, m_spec.quant_min, m_spec.quant_max, m_spec.format); } bool ImageOutput::write_image (TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride, ProgressCallback progress_callback, void *progress_callback_data) { bool native = (format == TypeDesc::UNKNOWN); stride_t pixel_bytes = native ? (stride_t) m_spec.pixel_bytes (native) : format.size() * m_spec.nchannels; if (xstride == AutoStride) xstride = pixel_bytes; m_spec.auto_stride (xstride, ystride, zstride, format, m_spec.nchannels, m_spec.width, m_spec.height); if (supports ("rectangles")) { // Use a rectangle if we can return write_rectangle (0, m_spec.width, 0, m_spec.height, 0, m_spec.depth, format, data, xstride, ystride, zstride); } bool ok = true; if (progress_callback && progress_callback (progress_callback_data, 0.0f)) return ok; if (m_spec.tile_width && supports ("tiles")) { // Tiled image for (int z = 0; z < m_spec.depth; z += m_spec.tile_depth) { int zend = std::min (z+m_spec.z+m_spec.tile_depth, m_spec.z+m_spec.depth); for (int y = 0; y < m_spec.height; y += m_spec.tile_height) { int yend = std::min (y+m_spec.y+m_spec.tile_height, m_spec.y+m_spec.height); const char *d = (const char *)data + z*zstride + y*ystride; ok &= write_tiles (m_spec.x, m_spec.x+m_spec.width, y+m_spec.y, yend, z+m_spec.z, zend, format, d, xstride, ystride, zstride); if (progress_callback && progress_callback (progress_callback_data, (float)(z*m_spec.height+y)/(m_spec.height*m_spec.depth))) return ok; } } } else { // Scanline image const int chunk = 256; for (int z = 0; z < m_spec.depth; ++z) for (int y = 0; y < m_spec.height && ok; y += chunk) { int yend = std::min (y+m_spec.y+chunk, m_spec.y+m_spec.height); const char *d = (const char *)data + z*zstride + y*ystride; ok &= write_scanlines (y+m_spec.y, yend, z+m_spec.z, format, d, xstride, ystride); if (progress_callback && progress_callback (progress_callback_data, (float)(z*m_spec.height+y)/(m_spec.height*m_spec.depth))) return ok; } } if (progress_callback) progress_callback (progress_callback_data, 1.0f); return ok; } bool ImageOutput::copy_image (ImageInput *in) { if (! in) { error ("copy_image: no input supplied"); return false; } // Make sure the images are compatible in size const ImageSpec &inspec (in->spec()); if (inspec.width != spec().width || inspec.height != spec().height || inspec.depth != spec().depth || inspec.nchannels != spec().nchannels) { error ("Could not copy %d x %d x %d channels to %d x %d x %d channels", inspec.width, inspec.height, inspec.nchannels, spec().width, spec().height, spec().nchannels); return false; } // in most cases plugins don't allow to copy 0x0 images // but there are some exceptions (like in FITS plugin) // when we want to do this. Because 0x0 means there is no image // data in the file, we simply return true so the application thought // that everything went right. if (! spec().image_bytes()) return true; if (spec().deep) { // Special case for ''deep'' images DeepData deepdata; bool ok = in->read_native_deep_image (deepdata); if (ok) ok = write_deep_image (deepdata); else error ("%s", in->geterror()); // copy err from in to out return ok; } // Naive implementation -- read the whole image and write it back out. // FIXME -- a smarter implementation would read scanlines or tiles at // a time, to minimize mem footprint. bool native = supports("channelformats") && inspec.channelformats.size(); TypeDesc format = native ? TypeDesc::UNKNOWN : inspec.format; boost::scoped_array pixels (new char [inspec.image_bytes(native)]); bool ok = in->read_image (format, &pixels[0]); if (ok) ok = write_image (format, &pixels[0]); else error ("%s", in->geterror()); // copy err from in to out return ok; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/atomic_test.cpp0000644000175000017500000001375312271062644022723 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include "thread.h" #include "strutil.h" #include "timer.h" #include "argparse.h" #include "ustring.h" #include #include #include "unittest.h" OIIO_NAMESPACE_USING; // How do we test atomics? Run a whole bunch of threads, incrementing // and decrementing the crap out of it, and make sure it has the right // value at the end. static int iterations = 40000000; static int numthreads = 16; static int ntrials = 1; static bool verbose = false; static bool wedge = false; static spin_mutex print_mutex; // make the prints not clobber each other atomic_int ai; atomic_ll all; static void do_int_math (int iterations) { if (verbose) { spin_lock lock(print_mutex); std::cout << "thread " << boost::this_thread::get_id() << ", ai = " << ai << "\n"; } for (int i = 0; i < iterations; ++i) { ++ai; ai += 3; --ai; ai++; ai -= 3; --ai; // That should have a net change of 0, but since other threads // are doing operations simultaneously, it's only after all // threads have finished that we can be sure it's back to the // initial value. } } void test_atomic_int (int numthreads, int iterations) { ai = 42; boost::thread_group threads; for (int i = 0; i < numthreads; ++i) { threads.create_thread (boost::bind (do_int_math, iterations)); } ASSERT ((int)threads.size() == numthreads); threads.join_all (); OIIO_CHECK_EQUAL (ai, 42); } static void do_int64_math (int iterations) { if (verbose) { spin_lock lock(print_mutex); std::cout << "thread " << boost::this_thread::get_id() << ", all = " << all << "\n"; } for (int i = 0; i < iterations; ++i) { ++all; all += 3; --all; all++; all -= 3; --all; // That should have a net change of 0, but since other threads // are doing operations simultaneously, it's only after all // threads have finished that we can be sure it's back to the // initial value. } } void test_atomic_int64 (int numthreads, int iterations) { all = 0; boost::thread_group threads; for (int i = 0; i < numthreads; ++i) { threads.create_thread (boost::bind (do_int64_math, iterations)); } threads.join_all (); OIIO_CHECK_EQUAL (all, 0); } void test_atomics (int numthreads, int iterations) { test_atomic_int (numthreads, iterations); test_atomic_int64 (numthreads, iterations); } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap; ap.options ("atomic_test\n" OIIO_INTRO_STRING "\n" "Usage: atomic_test [options]", // "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose mode", "--threads %d", &numthreads, ustring::format("Number of threads (default: %d)", numthreads).c_str(), "--iters %d", &iterations, ustring::format("Number of iterations (default: %d)", iterations).c_str(), "--trials %d", &ntrials, "Number of trials", "--wedge", &wedge, "Do a wedge test", NULL); if (ap.parse (argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } } int main (int argc, char *argv[]) { getargs (argc, argv); std::cout << "hw threads = " << boost::thread::hardware_concurrency() << "\n"; std::cout << "threads\ttime (best of " << ntrials << ")\n"; std::cout << "-------\t----------\n"; static int threadcounts[] = { 1, 2, 4, 8, 12, 16, 20, 24, 28, 32, 64, 128, 1024, 1<<30 }; for (int i = 0; threadcounts[i] <= numthreads; ++i) { int nt = wedge ? threadcounts[i] : numthreads; int its = iterations/nt; double range; double t = time_trial (boost::bind(test_atomics,nt,its), ntrials, &range); std::cout << Strutil::format ("%2d\t%5.1f range %.2f\t(%d iters/thread)\n", nt, t, range, its); if (! wedge) break; // don't loop if we're not wedging } return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imageinput.cpp0000644000175000017500000007344612271062644022557 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "strutil.h" #include "fmath.h" #include "imageio.h" #include "imageio_pvt.h" #include OIIO_NAMESPACE_ENTER { using namespace pvt; // Default implementation of valid_file: try to do a full open. If it // succeeds, it's the right kind of file. We assume that most plugins // will override this with something smarter and much less expensive, // like reading just the first few bytes of the file to check for magic // numbers. bool ImageInput::valid_file (const std::string &filename) const { ImageSpec tmpspec; bool ok = const_cast(this)->open (filename, tmpspec); if (ok) const_cast(this)->close (); return ok; } ImageInput * ImageInput::open (const std::string &filename, const ImageSpec *config) { if (config == NULL) { // Without config, this is really just a call to create-with-open. return ImageInput::create (filename, true, std::string()); } // With config, create without open, then try to open with config. ImageInput *in = ImageInput::create (filename, false, std::string()); if (! in) return NULL; // create() failed ImageSpec newspec; if (in->open (filename, newspec, *config)) return in; // creted fine, opened fine, return it // The open failed. Transfer the error from 'in' to the global OIIO // error, delete the ImageInput we allocated, and return NULL. std::string err = in->geterror(); if (err.size()) pvt::error ("%s", err.c_str()); delete in; return NULL; } bool ImageInput::read_scanline (int y, int z, TypeDesc format, void *data, stride_t xstride) { // native_pixel_bytes is the size of a pixel in the FILE, including // the per-channel format. stride_t native_pixel_bytes = (stride_t) m_spec.pixel_bytes (true); // perchanfile is true if the file has different per-channel formats bool perchanfile = m_spec.channelformats.size(); // native_data is true if the user asking for data in the native format bool native_data = (format == TypeDesc::UNKNOWN || (format == m_spec.format && !perchanfile)); if (native_data && xstride == AutoStride) xstride = native_pixel_bytes; else m_spec.auto_stride (xstride, format, m_spec.nchannels); // Do the strides indicate that the data area is contiguous? bool contiguous = (native_data && xstride == native_pixel_bytes) || (!native_data && xstride == (stride_t)m_spec.pixel_bytes(false)); // If user's format and strides are set up to accept the native data // layout, read the scanline directly into the user's buffer. if (native_data && contiguous) return read_native_scanline (y, z, data); // Complex case -- either changing data type or stride int scanline_values = m_spec.width * m_spec.nchannels; unsigned char *buf = (unsigned char *) alloca (m_spec.scanline_bytes(true)); bool ok = read_native_scanline (y, z, buf); if (! ok) return false; if (! perchanfile) { // No per-channel formats -- do the conversion in one shot ok = contiguous ? convert_types (m_spec.format, buf, format, data, scanline_values) : convert_image (m_spec.nchannels, m_spec.width, 1, 1, buf, m_spec.format, AutoStride, AutoStride, AutoStride, data, format, xstride, AutoStride, AutoStride); } else { // Per-channel formats -- have to convert/copy channels individually ASSERT (m_spec.channelformats.size() == (size_t)m_spec.nchannels); size_t offset = 0; for (int c = 0; ok && c < m_spec.nchannels; ++c) { TypeDesc chanformat = m_spec.channelformats[c]; ok = convert_image (1 /* channels */, m_spec.width, 1, 1, buf+offset, chanformat, native_pixel_bytes, AutoStride, AutoStride, (char *)data + c*format.size(), format, xstride, AutoStride, AutoStride); offset += chanformat.size (); } } if (! ok) error ("ImageInput::read_scanline : no support for format %s", m_spec.format.c_str()); return ok; } bool ImageInput::read_scanlines (int ybegin, int yend, int z, TypeDesc format, void *data, stride_t xstride, stride_t ystride) { return read_scanlines (ybegin, yend, z, 0, m_spec.nchannels, format, data, xstride, ystride); } bool ImageInput::read_scanlines (int ybegin, int yend, int z, int chbegin, int chend, TypeDesc format, void *data, stride_t xstride, stride_t ystride) { chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; yend = std::min (yend, spec().y+spec().height); size_t native_pixel_bytes = m_spec.pixel_bytes (chbegin, chend, true); imagesize_t native_scanline_bytes = clamped_mult64 ((imagesize_t)m_spec.width, (imagesize_t)native_pixel_bytes); bool native = (format == TypeDesc::UNKNOWN); size_t pixel_bytes = native ? native_pixel_bytes : format.size()*nchans; if (native && xstride == AutoStride) xstride = pixel_bytes; stride_t zstride = AutoStride; m_spec.auto_stride (xstride, ystride, zstride, format, nchans, m_spec.width, m_spec.height); bool contiguous = (xstride == (stride_t) native_pixel_bytes && ystride == (stride_t) native_scanline_bytes); // If user's format and strides are set up to accept the native data // layout, read the scanlines directly into the user's buffer. bool rightformat = (format == TypeDesc::UNKNOWN) || (format == m_spec.format && m_spec.channelformats.empty()); if (rightformat && contiguous) { if (chbegin == 0 && chend == m_spec.nchannels) return read_native_scanlines (ybegin, yend, z, data); else return read_native_scanlines (ybegin, yend, z, chbegin, chend, data); } // No such luck. Read scanlines in chunks. const imagesize_t limit = 16*1024*1024; // Allocate 16 MB, or 1 scanline int chunk = std::max (1, int(limit / native_scanline_bytes)); boost::scoped_array buf (new char [chunk * native_scanline_bytes]); bool ok = true; int scanline_values = m_spec.width * nchans; for (; ok && ybegin < yend; ybegin += chunk) { int y1 = std::min (ybegin+chunk, yend); ok &= read_native_scanlines (ybegin, y1, z, chbegin, chend, &buf[0]); if (! ok) break; int nscanlines = y1 - ybegin; int chunkvalues = scanline_values * nscanlines; if (m_spec.channelformats.empty()) { // No per-channel formats -- do the conversion in one shot if (contiguous) { ok = convert_types (m_spec.format, &buf[0], format, data, chunkvalues); } else { ok = parallel_convert_image (nchans, m_spec.width, nscanlines, 1, &buf[0], m_spec.format, AutoStride, AutoStride, AutoStride, data, format, xstride, ystride, zstride); } } else { // Per-channel formats -- have to convert/copy channels individually size_t offset = 0; for (int c = 0; ok && c < nchans; ++c) { TypeDesc chanformat = m_spec.channelformats[c+chbegin]; ok = convert_image (1 /* channels */, m_spec.width, nscanlines, 1, &buf[offset], chanformat, native_pixel_bytes, AutoStride, AutoStride, (char *)data + c*format.size(), format, xstride, ystride, zstride); offset += chanformat.size (); } } if (! ok) error ("ImageInput::read_scanlines : no support for format %s", m_spec.format.c_str()); data = (char *)data + ystride*nscanlines; } return ok; } bool ImageInput::read_native_scanlines (int ybegin, int yend, int z, void *data) { // Base class implementation of read_native_scanlines just repeatedly // calls read_native_scanline, which is supplied by every plugin. // Only the hardcore ones will overload read_native_scanlines with // their own implementation. size_t ystride = m_spec.scanline_bytes (true); yend = std::min (yend, spec().y+spec().height); for (int y = ybegin; y < yend; ++y) { bool ok = read_native_scanline (y, z, data); if (! ok) return false; data = (char *)data + ystride; } return true; } bool ImageInput::read_native_scanlines (int ybegin, int yend, int z, int chbegin, int chend, void *data) { // All-channel case just reduces to the simpler read_native_scanlines. if (chbegin == 0 && chend >= m_spec.nchannels) return read_native_scanlines (ybegin, yend, z, data); // Base class implementation of read_native_scanlines (with channel // subset) just calls read_native_scanlines (all channels), and // copies the appropriate subset. size_t prefix_bytes = m_spec.pixel_bytes (0,chbegin,true); size_t subset_bytes = m_spec.pixel_bytes (chbegin,chend,true); size_t subset_ystride = m_spec.width * subset_bytes; size_t native_pixel_bytes = m_spec.pixel_bytes (true); size_t native_ystride = m_spec.width * native_pixel_bytes; boost::scoped_array buf (new char [native_ystride]); yend = std::min (yend, spec().y+spec().height); for (int y = ybegin; y < yend; ++y) { bool ok = read_native_scanline (y, z, &buf[0]); if (! ok) return false; for (int x = 0; x < m_spec.width; ++x) memcpy ((char *)data + subset_bytes*x, &buf[prefix_bytes+native_pixel_bytes*x], subset_bytes); data = (char *)data + subset_ystride; } return true; } bool ImageInput::read_tile (int x, int y, int z, TypeDesc format, void *data, stride_t xstride, stride_t ystride, stride_t zstride) { if (! m_spec.tile_width || ((x-m_spec.x) % m_spec.tile_width) != 0 || ((y-m_spec.y) % m_spec.tile_height) != 0 || ((z-m_spec.z) % m_spec.tile_depth) != 0) return false; // coordinates are not a tile corner // native_pixel_bytes is the size of a pixel in the FILE, including // the per-channel format. stride_t native_pixel_bytes = (stride_t) m_spec.pixel_bytes (true); // perchanfile is true if the file has different per-channel formats bool perchanfile = m_spec.channelformats.size(); // native_data is true if the user asking for data in the native format bool native_data = (format == TypeDesc::UNKNOWN || (format == m_spec.format && !perchanfile)); if (format == TypeDesc::UNKNOWN && xstride == AutoStride) xstride = native_pixel_bytes; m_spec.auto_stride (xstride, ystride, zstride, format, m_spec.nchannels, m_spec.tile_width, m_spec.tile_height); // Do the strides indicate that the data area is contiguous? bool contiguous = (native_data && xstride == native_pixel_bytes) || (!native_data && xstride == (stride_t)m_spec.pixel_bytes(false)); contiguous &= (ystride == xstride*m_spec.tile_width && (zstride == ystride*m_spec.tile_height || zstride == 0)); // If user's format and strides are set up to accept the native data // layout, read the tile directly into the user's buffer. if (native_data && contiguous) return read_native_tile (x, y, z, data); // Simple case // Complex case -- either changing data type or stride size_t tile_values = (size_t)m_spec.tile_pixels() * m_spec.nchannels; boost::scoped_array buf (new char [m_spec.tile_bytes(true)]); bool ok = read_native_tile (x, y, z, &buf[0]); if (! ok) return false; if (! perchanfile) { // No per-channel formats -- do the conversion in one shot ok = contiguous ? convert_types (m_spec.format, &buf[0], format, data, tile_values) : convert_image (m_spec.nchannels, m_spec.tile_width, m_spec.tile_height, m_spec.tile_depth, &buf[0], m_spec.format, AutoStride, AutoStride, AutoStride, data, format, xstride, ystride, zstride); } else { // Per-channel formats -- have to convert/copy channels individually ASSERT (m_spec.channelformats.size() == (size_t)m_spec.nchannels); size_t offset = 0; for (int c = 0; c < m_spec.nchannels; ++c) { TypeDesc chanformat = m_spec.channelformats[c]; ok = convert_image (1 /* channels */, m_spec.tile_width, m_spec.tile_height, m_spec.tile_depth, &buf[offset], chanformat, native_pixel_bytes, AutoStride, AutoStride, (char *)data + c*format.size(), format, xstride, AutoStride, AutoStride); offset += chanformat.size (); } } if (! ok) error ("ImageInput::read_tile : no support for format %s", m_spec.format.c_str()); return ok; } bool ImageInput::read_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *data, stride_t xstride, stride_t ystride, stride_t zstride) { return read_tiles (xbegin, xend, ybegin, yend, zbegin, zend, 0, m_spec.nchannels, format, data, xstride, ystride, zstride); } bool ImageInput::read_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *data, stride_t xstride, stride_t ystride, stride_t zstride) { if (! m_spec.valid_tile_range (xbegin, xend, ybegin, yend, zbegin, zend)) return false; chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; // native_pixel_bytes is the size of a pixel in the FILE, including // the per-channel format. stride_t native_pixel_bytes = (stride_t) m_spec.pixel_bytes (chbegin, chend, true); // perchanfile is true if the file has different per-channel formats bool perchanfile = m_spec.channelformats.size(); // native_data is true if the user asking for data in the native format bool native_data = (format == TypeDesc::UNKNOWN || (format == m_spec.format && !perchanfile)); if (format == TypeDesc::UNKNOWN && xstride == AutoStride) xstride = native_pixel_bytes; m_spec.auto_stride (xstride, ystride, zstride, format, nchans, xend-xbegin, yend-ybegin); // Do the strides indicate that the data area is contiguous? bool contiguous = (native_data && xstride == native_pixel_bytes) || (!native_data && xstride == (stride_t)m_spec.pixel_bytes(false)); contiguous &= (ystride == xstride*(xend-xbegin) && (zstride == ystride*(yend-ybegin) || (zend-zbegin) <= 1)); int nxtiles = (xend - xbegin + m_spec.tile_width - 1) / m_spec.tile_width; int nytiles = (yend - ybegin + m_spec.tile_height - 1) / m_spec.tile_height; int nztiles = (zend - zbegin + m_spec.tile_depth - 1) / m_spec.tile_depth; // If user's format and strides are set up to accept the native data // layout, and we're asking for a whole number of tiles (no partial // tiles at the edges), then read the tile directly into the user's // buffer. if (native_data && contiguous && (xend-xbegin) == nxtiles*m_spec.tile_width && (yend-ybegin) == nytiles*m_spec.tile_height && (zend-zbegin) == nztiles*m_spec.tile_depth) { if (chbegin == 0 && chend == m_spec.nchannels) return read_native_tiles (xbegin, xend, ybegin, yend, zbegin, zend, data); // Simple case else return read_native_tiles (xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend, data); } // No such luck. Just punt and read tiles individually. bool ok = true; stride_t pixelsize = native_data ? native_pixel_bytes : (format.size() * nchans); stride_t full_pixelsize = native_data ? m_spec.pixel_bytes(true) : (format.size() * m_spec.nchannels); stride_t full_tilewidthbytes = full_pixelsize * m_spec.tile_width; stride_t full_tilewhbytes = full_tilewidthbytes * m_spec.tile_height; stride_t full_tilebytes = full_tilewhbytes * m_spec.tile_depth; size_t prefix_bytes = m_spec.pixel_bytes (0,chbegin,true); std::vector buf; for (int z = zbegin; z < zend; z += std::max(1,m_spec.tile_depth)) { int zd = std::min (zend-z, m_spec.tile_depth); for (int y = ybegin; y < yend; y += m_spec.tile_height) { char *tilestart = ((char *)data + (z-zbegin)*zstride + (y-ybegin)*ystride); int yh = std::min (yend-y, m_spec.tile_height); for (int x = xbegin; ok && x < xend; x += m_spec.tile_width) { int xw = std::min (xend-x, m_spec.tile_width); // Full tiles are read directly into the user buffer, // but partial tiles (such as at the image edge) or // partial channel subsets are read into a buffer and // then copied. if (xw == m_spec.tile_width && yh == m_spec.tile_height && zd == m_spec.tile_depth && !perchanfile && chbegin == 0 && chend == m_spec.nchannels) { // Full tile, either native data or not needing // per-tile data format conversion. ok &= read_tile (x, y, z, format, tilestart, xstride, ystride, zstride); } else { buf.resize (full_tilebytes); ok &= read_tile (x, y, z, perchanfile ? TypeDesc::UNKNOWN : format, &buf[0], full_pixelsize, full_tilewidthbytes, full_tilewhbytes); if (ok) copy_image (nchans, xw, yh, zd, &buf[prefix_bytes], pixelsize, full_pixelsize, full_tilewidthbytes, full_tilewhbytes, tilestart, xstride, ystride, zstride); // N.B. It looks like read_tiles doesn't handle the // per-channel data types case fully, but it does! // The call to read_tile() above handles the case of // per-channel data types, converting to to desired // format, so all we have to do on our own is the // copy_image. } tilestart += m_spec.tile_width * xstride; } if (! ok) break; } } if (! ok) error ("ImageInput::read_tiles : no support for format %s", m_spec.format.c_str()); return ok; } bool ImageInput::read_native_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, void *data) { if (! m_spec.valid_tile_range (xbegin, xend, ybegin, yend, zbegin, zend)) return false; // Base class implementation of read_native_tiles just repeatedly // calls read_native_tile, which is supplied by every plugin that // supports tiles. Only the hardcore ones will overload // read_native_tiles with their own implementation. stride_t pixel_bytes = (stride_t) m_spec.pixel_bytes (true); stride_t tileystride = pixel_bytes * m_spec.tile_width; stride_t tilezstride = tileystride * m_spec.tile_height; stride_t ystride = (xend-xbegin) * pixel_bytes; stride_t zstride = (yend-ybegin) * ystride; boost::scoped_array pels (new char [m_spec.tile_bytes(true)]); for (int z = zbegin; z < zend; z += m_spec.tile_depth) { for (int y = ybegin; y < yend; y += m_spec.tile_height) { for (int x = xbegin; x < xend; x += m_spec.tile_width) { bool ok = read_native_tile (x, y, z, &pels[0]); if (! ok) return false; copy_image (m_spec.nchannels, m_spec.tile_width, m_spec.tile_height, m_spec.tile_depth, &pels[0], size_t(pixel_bytes), pixel_bytes, tileystride, tilezstride, (char *)data+ (z-zbegin)*zstride + (y-ybegin)*ystride + (x-xbegin)*pixel_bytes, pixel_bytes, ystride, zstride); } } } return true; } bool ImageInput::read_native_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, void *data) { chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; // All-channel case just reduces to the simpler read_native_scanlines. if (chbegin == 0 && chend >= m_spec.nchannels) return read_native_tiles (xbegin, xend, ybegin, yend, zbegin, zend, data); if (! m_spec.valid_tile_range (xbegin, xend, ybegin, yend, zbegin, zend)) return false; // Base class implementation of read_native_tiles just repeatedly // calls read_native_tile, which is supplied by every plugin that // supports tiles. Only the hardcore ones will overload // read_native_tiles with their own implementation. stride_t native_pixel_bytes = (stride_t) m_spec.pixel_bytes (true); stride_t native_tileystride = native_pixel_bytes * m_spec.tile_width; stride_t native_tilezstride = native_tileystride * m_spec.tile_height; size_t prefix_bytes = m_spec.pixel_bytes (0,chbegin,true); size_t subset_bytes = m_spec.pixel_bytes (chbegin,chend,true); stride_t subset_ystride = (xend-xbegin) * subset_bytes; stride_t subset_zstride = (yend-ybegin) * subset_ystride; boost::scoped_array pels (new char [m_spec.tile_bytes(true)]); for (int z = zbegin; z < zend; z += m_spec.tile_depth) { for (int y = ybegin; y < yend; y += m_spec.tile_height) { for (int x = xbegin; x < xend; x += m_spec.tile_width) { bool ok = read_native_tile (x, y, z, &pels[0]); if (! ok) return false; copy_image (nchans, m_spec.tile_width, m_spec.tile_height, m_spec.tile_depth, &pels[prefix_bytes], subset_bytes, native_pixel_bytes, native_tileystride, native_tilezstride, (char *)data+ (z-zbegin)*subset_zstride + (y-ybegin)*subset_ystride + (x-xbegin)*subset_bytes, subset_bytes, subset_ystride, subset_zstride); } } } return true; } bool ImageInput::read_image (TypeDesc format, void *data, stride_t xstride, stride_t ystride, stride_t zstride, ProgressCallback progress_callback, void *progress_callback_data) { bool native = (format == TypeDesc::UNKNOWN); stride_t pixel_bytes = native ? (stride_t) m_spec.pixel_bytes (native) : (stride_t) (format.size()*m_spec.nchannels); if (native && xstride == AutoStride) xstride = pixel_bytes; m_spec.auto_stride (xstride, ystride, zstride, format, m_spec.nchannels, m_spec.width, m_spec.height); bool ok = true; if (progress_callback) if (progress_callback (progress_callback_data, 0.0f)) return ok; if (m_spec.tile_width) { // Tiled image for (int z = 0; z < m_spec.depth; z += m_spec.tile_depth) { for (int y = 0; y < m_spec.height && ok; y += m_spec.tile_height) { ok &= read_tiles (m_spec.x, m_spec.x+m_spec.width, y+m_spec.y, std::min (y+m_spec.y+m_spec.tile_height, m_spec.y+m_spec.height), z+m_spec.z, std::min (z+m_spec.z+m_spec.tile_depth, m_spec.z+m_spec.depth), format, (char *)data + z*zstride + y*ystride, xstride, ystride, zstride); if (progress_callback && progress_callback (progress_callback_data, (float)y/m_spec.height)) return ok; } } } else { // Scanline image -- rely on read_scanlines, in chunks of 64 const int chunk = 256; for (int z = 0; z < m_spec.depth; ++z) for (int y = 0; y < m_spec.height && ok; y += chunk) { int yend = std::min (y+m_spec.y+chunk, m_spec.y+m_spec.height); ok &= read_scanlines (y+m_spec.y, yend, z+m_spec.z, format, (char *)data + z*zstride + y*ystride, xstride, ystride); if (progress_callback) if (progress_callback (progress_callback_data, (float)y/m_spec.height)) return ok; } } if (progress_callback) progress_callback (progress_callback_data, 1.0f); return ok; } bool ImageInput::read_native_deep_scanlines (int ybegin, int yend, int z, int chbegin, int chend, DeepData &deepdata) { return false; // default: doesn't support deep images } bool ImageInput::read_native_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, DeepData &deepdata) { return false; // default: doesn't support deep images } bool ImageInput::read_native_deep_image (DeepData &deepdata) { if (m_spec.depth > 1) { error ("read_native_deep_image is not supported for volume (3D) images."); return false; // FIXME? - not implementing 3D deep images for now. The only // format that supports deep images at this time is OpenEXR, and // it doesn't support volumes. } if (m_spec.tile_width) { // Tiled image return read_native_deep_tiles (m_spec.x, m_spec.x+m_spec.width, m_spec.y, m_spec.y+m_spec.height, m_spec.z, m_spec.z+m_spec.depth, 0, m_spec.nchannels, deepdata); } else { // Scanline image return read_native_deep_scanlines (m_spec.y, m_spec.y+m_spec.height, 0, 0, m_spec.nchannels, deepdata); } } int ImageInput::send_to_input (const char *format, ...) { // FIXME -- I can't remember how this is supposed to work return 0; } int ImageInput::send_to_client (const char *format, ...) { // FIXME -- I can't remember how this is supposed to work return 0; } void ImageInput::append_error (const std::string& message) const { ASSERT (m_errmessage.size() < 1024*1024*16 && "Accumulated error messages > 16MB. Try checking return codes!"); if (m_errmessage.size()) m_errmessage += '\n'; m_errmessage += message; } bool ImageInput::read_native_tile (int x, int y, int z, void * data) { return false; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebufalgo_deep.cpp0000644000175000017500000001603012271062644024016 0ustar mfvmfv/* Copyright 2013 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include "imagebuf.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #include "dassert.h" #include "sysutil.h" #include "thread.h" OIIO_NAMESPACE_ENTER { // Helper for flatten: identify channels in the spec that are important to // deciphering deep images. Return true if appropriate alphas were found. static bool find_deep_channels (const ImageSpec &spec, int &alpha_channel, int &RA_channel, int &GA_channel, int &BA_channel, int &R_channel, int &G_channel, int &B_channel, int &Z_channel, int &Zback_channel) { static const char *names[] = { "A", "RA", "GA", "BA", "R", "G", "B", "Z", "Zback", NULL }; int *chans[] = { &alpha_channel, &RA_channel, &GA_channel, &BA_channel, &R_channel, &G_channel, &B_channel, &Z_channel, &Zback_channel }; for (int i = 0; names[i]; ++i) *chans[i] = -1; for (int c = 0, e = int(spec.channelnames.size()); c < e; ++c) { for (int i = 0; names[i]; ++i) { if (spec.channelnames[c] == names[i]) { *chans[i] = c; break; } } } if (Zback_channel < 0) Zback_channel = Z_channel; return (alpha_channel >= 0 || (RA_channel >= 0 && GA_channel >= 0 && BA_channel >= 0)); } // FIXME -- NOT CORRECT! This code assumes sorted, non-overlapping samples. // That is not a valid assumption in general. We will come back to fix this. template static bool flatten_ (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(flatten_, boost::ref(dst), boost::cref(src), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // We need to convert our "cumulative" alpha values to the // "local" values that OpenEXR conventions dictate. // For cumulative values cum[i] and alpha[i], we can derive // local val[i] as follows: // cum[i] = cum[i-1] + (1 - alpha[i-1]) * val[i] // val[i] = (cum[i] - cum[i-1]) / (1 - alpha[i-1]) const ImageSpec &srcspec (src.spec()); int nc = srcspec.nchannels; int alpha_channel, RA_channel, GA_channel, BA_channel; int R_channel, G_channel, B_channel; int Z_channel, Zback_channel; if (! find_deep_channels (srcspec, alpha_channel, RA_channel, GA_channel, BA_channel, R_channel, G_channel, B_channel, Z_channel, Zback_channel)) { dst.error ("No alpha channel could be identified"); return false; } float *val = ALLOCA (float, nc); for (ImageBuf::Iterator r (dst, roi); !r.done(); ++r) { int x = r.x(), y = r.y(), z = r.z(); int samps = src.deep_samples (x, y, z); // Clear accumulated values for this pixel (0 for colors, big for Z) memset (val, 0, nc*sizeof(float)); if (Z_channel >= 0 && samps == 0) val[Z_channel] = 1.0e30; if (Zback_channel >= 0 && samps == 0) val[Zback_channel] = 1.0e30; for (int s = 0; s < samps; ++s) { float RA, GA, BA, alpha; // The running totals if (RA_channel >= 0) { RA = val[RA_channel]; GA = val[GA_channel]; BA = val[BA_channel]; alpha = (RA + GA + BA) / 3.0f; } else { alpha = val[alpha_channel]; RA = GA = BA = alpha; } if (alpha >= 1) break; for (int c = 0; c < nc; ++c) { float a = alpha; if (c == R_channel) a = RA; else if (c == G_channel) a = GA; else if (c == B_channel) a = BA; val[c] += (1.0f - a) * src.deep_value (x, y, z, c, s); } } for (int c = roi.chbegin; c < roi.chend; ++c) r[c] = val[c]; } return true; } bool ImageBufAlgo::flatten (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { // Construct an ideal spec for dst, which is like src but not deep. ImageSpec force_spec = src.spec(); force_spec.deep = false; force_spec.channelformats.clear(); if (! IBAprep (roi, &dst, &src, NULL, &force_spec)) return false; if (dst.spec().deep) { dst.error ("Cannot flatten to a deep image"); return false; } const ImageSpec &srcspec (src.spec()); int alpha_channel, RA_channel, GA_channel, BA_channel; int R_channel, G_channel, B_channel, Z_channel, Zback_channel; if (! find_deep_channels (srcspec, alpha_channel, RA_channel, GA_channel, BA_channel, R_channel, G_channel, B_channel, Z_channel, Zback_channel)) { dst.error ("No alpha channel could be identified"); return false; } OIIO_DISPATCH_TYPES ("flatten", flatten_, dst.spec().format, dst, src, roi, nthreads); return false; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imageio_pvt.h0000644000175000017500000001057012271062644022352 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Declarations for things that are used privately by ImageIO. #ifndef OPENIMAGEIO_IMAGEIO_PVT_H #define OPENIMAGEIO_IMAGEIO_PVT_H #include "imageio.h" #include "thread.h" OIIO_NAMESPACE_ENTER { namespace pvt { /// Mutex allowing thread safety of ImageOutput internals /// extern recursive_mutex imageio_mutex; extern atomic_int oiio_threads; extern ustring plugin_searchpath; extern std::string format_list; extern std::string extension_list; // For internal use - use error() below for a nicer interface. void seterror (const std::string& message); // Make sure all plugins are inventoried. Should only be called while // imageio_mutex is held. For internal use only. void catalog_all_plugins (std::string searchpath); /// Use error() privately only. Protoype is conceptually printf-like, but /// also fully typesafe: /// void error (const char *format, ...); TINYFORMAT_WRAP_FORMAT (void, error, /**/, std::ostringstream msg;, msg, seterror(msg.str());) /// Turn potentially non-contiguous-stride data (e.g. "RGBxRGBx") into /// contiguous-stride ("RGBRGB"), for any format or stride values /// (measured in bytes). Caller must pass in a dst pointing to enough /// memory to hold the contiguous rectangle. Return a ptr to where the /// contiguous data ended up, which is either dst or src (if the strides /// indicated that data were already contiguous). const void *contiguize (const void *src, int nchannels, stride_t xstride, stride_t ystride, stride_t zstride, void *dst, int width, int height, int depth, TypeDesc format); /// Turn contiguous data from any format into float data. Return a /// pointer to the converted data (which may still point to src if no /// conversion was necessary). const float *convert_to_float (const void *src, float *dst, int nvals, TypeDesc format); /// Turn contiguous float data into any format. Return a pointer to the /// converted data (which may still point to src if no conversion was /// necessary). const void *convert_from_float (const float *src, void *dst, size_t nvals, int quant_black, int quant_white, int quant_min, int quant_max, TypeDesc format); /// A version of convert_from_float that will break up big jobs with /// multiple threads. const void *parallel_convert_from_float (const float *src, void *dst, size_t nvals, int quant_black, int quant_white, int quant_min, int quant_max, TypeDesc format, int nthreads=0); } // namespace pvt } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_IMAGEIO_PVT_H openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebufalgo_compare.cpp0000644000175000017500000007666712271062644024555 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Implementation of ImageBufAlgo algorithms that analize or compare /// images. /* This header has to be included before boost/regex.hpp header If it is included after, there is an error "undefined reference to CSHA1::Update (unsigned char const*, unsigned long)" */ #include "SHA1.h" #include #include #include #include #include #include "imagebuf.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #include "dassert.h" #include "thread.h" #ifdef USE_OPENSSL #ifdef __APPLE__ // Newer OSX releaes mark OpenSSL functions as deprecated, in favor of // CDSA. Make the warnings stop. #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif #include #endif OIIO_NAMESPACE_ENTER { inline void reset (ImageBufAlgo::PixelStats &p, int nchannels) { const float inf = std::numeric_limits::infinity(); p.min.clear (); p.min.resize (nchannels, inf); p.max.clear (); p.max.resize (nchannels, -inf); p.avg.clear (); p.avg.resize (nchannels); p.stddev.clear (); p.stddev.resize (nchannels); p.nancount.clear (); p.nancount.resize (nchannels, 0); p.infcount.clear (); p.infcount.resize (nchannels, 0); p.finitecount.clear (); p.finitecount.resize (nchannels, 0); p.sum.clear (); p.sum.resize (nchannels, 0.0); p.sum2.clear (); p.sum2.resize (nchannels, 0.0); } inline void merge (ImageBufAlgo::PixelStats &sum, const ImageBufAlgo::PixelStats &p) { ASSERT (sum.min.size() == p.min.size()); for (size_t c = 0, e = sum.min.size(); c < e; ++c) { sum.min[c] = std::min (sum.min[c], p.min[c]); sum.max[c] = std::max (sum.max[c], p.max[c]); sum.nancount[c] += p.nancount[c]; sum.infcount[c] += p.infcount[c]; sum.finitecount[c] += p.finitecount[c]; sum.sum[c] += p.sum[c]; sum.sum2[c] += p.sum2[c]; } } inline void val (ImageBufAlgo::PixelStats &p, int c, float value) { if (isnan (value)) { ++p.nancount[c]; return; } if (isinf (value)) { ++p.infcount[c]; return; } ++p.finitecount[c]; p.sum[c] += value; p.sum2[c] += value*value; p.min[c] = std::min (value, p.min[c]); p.max[c] = std::max (value, p.max[c]); } inline void finalize (ImageBufAlgo::PixelStats &p) { for (size_t c = 0, e = p.min.size(); c < e; ++c) { if (p.finitecount[c] == 0) { p.min[c] = 0.0; p.max[c] = 0.0; p.avg[c] = 0.0; p.stddev[c] = 0.0; } else { double Count = static_cast(p.finitecount[c]); double davg = p.sum[c] / Count; p.avg[c] = static_cast(davg); p.stddev[c] = static_cast(sqrt(p.sum2[c]/Count - davg*davg)); } } } template static bool computePixelStats_ (const ImageBuf &src, ImageBufAlgo::PixelStats &stats, ROI roi, int nthreads) { if (! roi.defined()) roi = get_roi (src.spec()); else roi.chend = std::min (roi.chend, src.nchannels()); int nchannels = src.spec().nchannels; // Use local storage for smaller batches, then merge the batches // into the final results. This preserves precision for large // images, where the running total may be too big to incorporate the // contributions of individual pixel values without losing // precision. // // This approach works best when the batch size is the sqrt of // numpixels, which makes the num batches roughly equal to the // number of pixels / batch. ImageBufAlgo::PixelStats tmp; reset (tmp, nchannels); reset (stats, nchannels); int PIXELS_PER_BATCH = std::max (1024, static_cast(sqrt((double)src.spec().image_pixels()))); if (src.deep()) { // Loop over all pixels ... for (ImageBuf::ConstIterator s(src, roi); ! s.done(); ++s) { int samples = s.deep_samples(); if (! samples) continue; for (int c = roi.chbegin; c < roi.chend; ++c) { for (int i = 0; i < samples; ++i) { float value = s.deep_value (c, i); val (tmp, c, value); if ((tmp.finitecount[c] % PIXELS_PER_BATCH) == 0) { merge (stats, tmp); reset (tmp, nchannels); } } } } } else { // Non-deep case // Loop over all pixels ... for (ImageBuf::ConstIterator s(src, roi); ! s.done(); ++s) { for (int c = roi.chbegin; c < roi.chend; ++c) { float value = s[c]; val (tmp, c, value); if ((tmp.finitecount[c] % PIXELS_PER_BATCH) == 0) { merge (stats, tmp); reset (tmp, nchannels); } } } } // Merge anything left over merge (stats, tmp); // Compute final results finalize (stats); return true; }; bool ImageBufAlgo::computePixelStats (PixelStats &stats, const ImageBuf &src, ROI roi, int nthreads) { if (! roi.defined()) roi = get_roi (src.spec()); else roi.chend = std::min (roi.chend, src.nchannels()); int nchannels = src.spec().nchannels; if (nchannels == 0) { src.error ("%d-channel images not supported", nchannels); return false; } OIIO_DISPATCH_TYPES ("computePixelStats", computePixelStats_, src.spec().format, src, stats, roi, nthreads); return false; } template inline void compare_value (ImageBuf::ConstIterator &a, int chan, float aval, float bval, ImageBufAlgo::CompareResults &result, float &maxval, double &batcherror, double &batch_sqrerror, bool &failed, bool &warned, float failthresh, float warnthresh) { maxval = std::max (maxval, std::max (aval, bval)); double f = fabs (aval - bval); batcherror += f; batch_sqrerror += f*f; if (f > result.maxerror) { result.maxerror = f; result.maxx = a.x(); result.maxy = a.y(); result.maxz = a.z(); result.maxc = chan; } if (! warned && f > warnthresh) { ++result.nwarn; warned = true; } if (! failed && f > failthresh) { ++result.nfail; failed = true; } } template static bool compare_ (const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ImageBufAlgo::CompareResults &result, ROI roi, int nthreads) { imagesize_t npels = roi.npixels(); imagesize_t nvals = npels * roi.nchannels(); int Achannels = A.nchannels(), Bchannels = B.nchannels(); // Compare the two images. // double totalerror = 0; double totalsqrerror = 0; result.maxerror = 0; result.maxx=0, result.maxy=0, result.maxz=0, result.maxc=0; result.nfail = 0, result.nwarn = 0; float maxval = 1.0; // max possible value ImageBuf::ConstIterator a (A, roi, ImageBuf::WrapBlack); ImageBuf::ConstIterator b (B, roi, ImageBuf::WrapBlack); bool deep = A.deep(); // Break up into batches to reduce cancelation errors as the error // sums become too much larger than the error for individual pixels. const int batchsize = 4096; // As good a guess as any for ( ; ! a.done(); ) { double batcherror = 0; double batch_sqrerror = 0; if (deep) { for (int i = 0; i < batchsize && !a.done(); ++i, ++a, ++b) { bool warned = false, failed = false; // For this pixel for (int c = roi.chbegin; c < roi.chend; ++c) for (int s = 0, e = a.deep_samples(); s < e; ++s) { compare_value (a, c, a.deep_value(c,s), b.deep_value(c,s), result, maxval, batcherror, batch_sqrerror, failed, warned, failthresh, warnthresh); } } } else { // non-deep for (int i = 0; i < batchsize && !a.done(); ++i, ++a, ++b) { bool warned = false, failed = false; // For this pixel for (int c = roi.chbegin; c < roi.chend; ++c) compare_value (a, c, c < Achannels ? a[c] : 0.0f, c < Bchannels ? b[c] : 0.0f, result, maxval, batcherror, batch_sqrerror, failed, warned, failthresh, warnthresh); } } totalerror += batcherror; totalsqrerror += batch_sqrerror; } result.meanerror = totalerror / nvals; result.rms_error = sqrt (totalsqrerror / nvals); result.PSNR = 20.0 * log10 (maxval / result.rms_error); return result.nfail == 0; } bool ImageBufAlgo::compare (const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ImageBufAlgo::CompareResults &result, ROI roi, int nthreads) { // If no ROI is defined, use the union of the data windows of the two // images. if (! roi.defined()) roi = roi_union (get_roi(A.spec()), get_roi(B.spec())); roi.chend = std::min (roi.chend, std::max(A.nchannels(), B.nchannels())); // Deep and non-deep images cannot be compared if (B.deep() != A.deep()) return false; OIIO_DISPATCH_TYPES2 ("compare", compare_, A.spec().format, B.spec().format, A, B, failthresh, warnthresh, result, roi, nthreads); // FIXME - The nthreads argument is for symmetry with the rest of // ImageBufAlgo and for future expansion. But for right now, we // don't actually split by threads. Maybe later. return false; } template static inline bool isConstantColor_ (const ImageBuf &src, float *color, ROI roi, int nthreads) { // Iterate using the native typing (for speed). std::vector constval (roi.nchannels()); ImageBuf::ConstIterator s (src, roi); for (int c = roi.chbegin; c < roi.chend; ++c) constval[c] = s[c]; // Loop over all pixels ... for ( ; ! s.done(); ++s) { for (int c = roi.chbegin; c < roi.chend; ++c) if (constval[c] != s[c]) return false; } if (color) { ImageBuf::ConstIterator s (src, roi); for (int c = 0; c < roi.chbegin; ++c) color[c] = 0.0f; for (int c = roi.chbegin; c < roi.chend; ++c) color[c] = s[c]; for (int c = roi.chend; c < src.nchannels(); ++c) color[c] = 0.0f; } return true; } bool ImageBufAlgo::isConstantColor (const ImageBuf &src, float *color, ROI roi, int nthreads) { // If no ROI is defined, use the data window of src. if (! roi.defined()) roi = get_roi(src.spec()); roi.chend = std::min (roi.chend, src.nchannels()); if (roi.nchannels() == 0) return true; OIIO_DISPATCH_TYPES ("isConstantColor", isConstantColor_, src.spec().format, src, color, roi, nthreads); // FIXME - The nthreads argument is for symmetry with the rest of // ImageBufAlgo and for future expansion. But for right now, we // don't actually split by threads. Maybe later. }; template static inline bool isConstantChannel_ (const ImageBuf &src, int channel, float val, ROI roi, int nthreads) { T v = convert_type (val); for (ImageBuf::ConstIterator s(src, roi); !s.done(); ++s) if (s[channel] != v) return false; return true; } bool ImageBufAlgo::isConstantChannel (const ImageBuf &src, int channel, float val, ROI roi, int nthreads) { // If no ROI is defined, use the data window of src. if (! roi.defined()) roi = get_roi(src.spec()); if (channel < 0 || channel >= src.nchannels()) return false; // that channel doesn't exist in the image OIIO_DISPATCH_TYPES ("isConstantChannel", isConstantChannel_, src.spec().format, src, channel, val, roi, nthreads); // FIXME - The nthreads argument is for symmetry with the rest of // ImageBufAlgo and for future expansion. But for right now, we // don't actually split by threads. Maybe later. }; template static inline bool isMonochrome_ (const ImageBuf &src, ROI roi, int nthreads) { int nchannels = src.nchannels(); if (nchannels < 2) return true; // Loop over all pixels ... for (ImageBuf::ConstIterator s(src, roi); ! s.done(); ++s) { T constvalue = s[roi.chbegin]; for (int c = roi.chbegin+1; c < roi.chend; ++c) if (s[c] != constvalue) return false; } return true; } bool ImageBufAlgo::isMonochrome (const ImageBuf &src, ROI roi, int nthreads) { // If no ROI is defined, use the data window of src. if (! roi.defined()) roi = get_roi(src.spec()); roi.chend = std::min (roi.chend, src.nchannels()); if (roi.nchannels() < 2) return true; // 1 or fewer channels are always "monochrome" OIIO_DISPATCH_TYPES ("isMonochrome", isMonochrome_, src.spec().format, src, roi, nthreads); // FIXME - The nthreads argument is for symmetry with the rest of // ImageBufAlgo and for future expansion. But for right now, we // don't actually split by threads. Maybe later. }; template static bool color_count_ (const ImageBuf &src, atomic_ll *count, int ncolors, const float *color, const float *eps, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(color_count_, boost::ref(src), count, ncolors, color, eps, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case int nchannels = src.nchannels(); long long *n = ALLOCA (long long, ncolors); for (int col = 0; col < ncolors; ++col) n[col] = 0; for (ImageBuf::ConstIterator p (src, roi); !p.done(); ++p) { int coloffset = 0; for (int col = 0; col < ncolors; ++col, coloffset += nchannels) { int match = 1; for (int c = roi.chbegin; c < roi.chend; ++c) { if (fabsf(p[c] - color[coloffset+c]) > eps[c]) { match = 0; break; } } n[col] += match; } } for (int col = 0; col < ncolors; ++col) count[col] += n[col]; return true; } bool ImageBufAlgo::color_count (const ImageBuf &src, imagesize_t *count, int ncolors, const float *color, const float *eps, ROI roi, int nthreads) { // If no ROI is defined, use the data window of src. if (! roi.defined()) roi = get_roi(src.spec()); roi.chend = std::min (roi.chend, src.nchannels()); if (! eps) { float *localeps = ALLOCA (float, roi.chend); for (int c = 0; c < roi.chend; ++c) localeps[c] = 0.001f; eps = localeps; } for (int col = 0; col < ncolors; ++col) count[col] = 0; OIIO_DISPATCH_TYPES ("color_count", color_count_, src.spec().format, src, (atomic_ll *)count, ncolors, color, eps, roi, nthreads); } template static bool color_range_check_ (const ImageBuf &src, atomic_ll *lowcount, atomic_ll *highcount, atomic_ll *inrangecount, const float *low, const float *high, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(color_range_check_, boost::ref(src), lowcount, highcount, inrangecount, low, high, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case long long lc = 0, hc = 0, inrange = 0; for (ImageBuf::ConstIterator p (src, roi); !p.done(); ++p) { bool lowval = false, highval = false; for (int c = roi.chbegin; c < roi.chend; ++c) { float f = p[c]; lowval |= (f < low[c]); highval |= (f > high[c]); } if (lowval) ++lc; if (highval) ++hc; if (!lowval && !highval) ++inrange; } if (lowcount) *lowcount += lc; if (highcount) *highcount += hc; if (inrangecount) *inrangecount += inrange; return true; } bool ImageBufAlgo::color_range_check (const ImageBuf &src, imagesize_t *lowcount, imagesize_t *highcount, imagesize_t *inrangecount, const float *low, const float *high, ROI roi, int nthreads) { // If no ROI is defined, use the data window of src. if (! roi.defined()) roi = get_roi(src.spec()); roi.chend = std::min (roi.chend, src.nchannels()); if (lowcount) *lowcount = 0; if (highcount) *highcount = 0; if (inrangecount) *inrangecount = 0; OIIO_DISPATCH_TYPES ("color_range_check", color_range_check_, src.spec().format, src, (atomic_ll *)lowcount, (atomic_ll *)highcount, (atomic_ll *)inrangecount, low, high, roi, nthreads); } ROI ImageBufAlgo::nonzero_region (const ImageBuf &src, ROI roi, int nthreads) { std::vector zero (src.nchannels(), 0.0f); std::vector color (src.nchannels(), 0.0f); if (! roi.defined()) roi = get_roi (src.spec()); // Trim bottom for ( ; roi.ybegin < roi.yend; --roi.yend) { ROI test = roi; test.ybegin = roi.yend-1; if (! isConstantColor (src, &color[0], test, nthreads) || color != zero) break; } // Trim top for ( ; roi.ybegin < roi.yend; ++roi.ybegin) { ROI test = roi; test.yend = roi.ybegin+1; if (! isConstantColor (src, &color[0], test, nthreads) || color != zero) break; } // Trim right for ( ; roi.xbegin < roi.xend; --roi.xend) { ROI test = roi; test.xbegin = roi.xend-1; if (! isConstantColor (src, &color[0], test, nthreads) || color != zero) break; } // Trim left for ( ; roi.xbegin < roi.xend; ++roi.xbegin) { ROI test = roi; test.xend = roi.xbegin+1; if (! isConstantColor (src, &color[0], test, nthreads) || color != zero) break; } if (roi.depth() > 1) { // Trim zbottom for ( ; roi.zbegin < roi.zend; --roi.zend) { ROI test = roi; test.zbegin = roi.zend-1; if (! isConstantColor (src, &color[0], test, nthreads) || color != zero) break; } // Trim ztop for ( ; roi.zbegin < roi.zend; ++roi.zbegin) { ROI test = roi; test.zend = roi.zbegin+1; if (! isConstantColor (src, &color[0], test, nthreads) || color != zero) break; } } return roi; } namespace { std::string simplePixelHashSHA1 (const ImageBuf &src, const std::string & extrainfo, ROI roi) { if (! roi.defined()) roi = get_roi (src.spec()); bool localpixels = src.localpixels(); imagesize_t scanline_bytes = roi.width() * src.spec().pixel_bytes(); ASSERT (scanline_bytes < std::numeric_limits::max()); // Do it a few scanlines at a time int chunk = std::max (1, int(16*1024*1024/scanline_bytes)); std::vector tmp; if (! localpixels) tmp.resize (chunk*scanline_bytes); #ifdef USE_OPENSSL // If OpenSSL was available at build time, use its SHA-1 // implementation, which is about 20% faster than CSHA1. SHA_CTX sha; SHA1_Init (&sha); for (int z = roi.zbegin, zend=roi.zend; z < zend; ++z) { for (int y = roi.ybegin, yend=roi.yend; y < yend; y += chunk) { int y1 = std::min (y+chunk, yend); if (localpixels) { SHA1_Update (&sha, src.pixeladdr (roi.xbegin, y, z), (unsigned int) scanline_bytes*(y1-y)); } else { src.get_pixels (roi.xbegin, roi.xend, y, y1, z, z+1, src.spec().format, &tmp[0]); SHA1_Update (&sha, &tmp[0], (unsigned int) scanline_bytes*(y1-y)); } } } // If extra info is specified, also include it in the sha computation if (!extrainfo.empty()) SHA1_Update (&sha, extrainfo.c_str(), extrainfo.size()); unsigned char md[SHA_DIGEST_LENGTH]; char hash_digest[2*SHA_DIGEST_LENGTH+1]; SHA1_Final (md, &sha); for (int i = 0; i < SHA_DIGEST_LENGTH; ++i) sprintf (hash_digest+2*i, "%02X", (int)md[i]); hash_digest[2*SHA_DIGEST_LENGTH] = 0; return std::string (hash_digest); #else // Fall back on CSHA1 if OpenSSL was not available or if CSHA1 sha; sha.Reset (); for (int z = roi.zbegin, zend=roi.zend; z < zend; ++z) { for (int y = roi.ybegin, yend=roi.yend; y < yend; y += chunk) { int y1 = std::min (y+chunk, yend); if (localpixels) { sha.Update ((const unsigned char *)src.pixeladdr (roi.xbegin, y, z), (unsigned int) scanline_bytes*(y1-y)); } else { src.get_pixels (roi.xbegin, roi.xend, y, y1, z, z+1, src.spec().format, &tmp[0]); sha.Update (&tmp[0], (unsigned int) scanline_bytes*(y1-y)); } } } // If extra info is specified, also include it in the sha computation if (!extrainfo.empty()) { sha.Update ((const unsigned char*) extrainfo.c_str(), extrainfo.size()); } sha.Final (); std::string hash_digest; sha.ReportHashStl (hash_digest, CSHA1::REPORT_HEX_SHORT); return hash_digest; #endif } // Wrapper to single-threadedly SHA1 hash a region in blocks and store // the results in a designated place. static void sha1_hasher (const ImageBuf *src, ROI roi, int blocksize, std::string *results, int firstresult) { ROI broi = roi; for (int y = roi.ybegin; y < roi.yend; y += blocksize) { broi.ybegin = y; broi.yend = std::min (y+blocksize, roi.yend); std::string s = simplePixelHashSHA1 (*src, "", broi); results[firstresult++] = s; } } } // anon namespace std::string ImageBufAlgo::computePixelHashSHA1 (const ImageBuf &src, const std::string & extrainfo, ROI roi, int blocksize, int nthreads) { if (! roi.defined()) roi = get_roi (src.spec()); // Fall back to whole-image hash for only one block if (blocksize <= 0 || blocksize >= roi.height()) return simplePixelHashSHA1 (src, extrainfo, roi); // Request for 0 threads means "use the OIIO global thread count" if (nthreads <= 0) OIIO::getattribute ("threads", nthreads); int nblocks = (roi.height()+blocksize-1) / blocksize; std::vector results (nblocks); if (nthreads <= 1) { sha1_hasher (&src, roi, blocksize, &results[0], 0); } else { // parallel case boost::thread_group threads; int blocks_per_thread = (nblocks+nthreads-1) / nthreads; ROI broi = roi; for (int b = 0, t = 0; b < nblocks; b += blocks_per_thread, ++t) { int y = roi.ybegin + b*blocksize; if (y >= roi.yend) break; broi.ybegin = y; broi.yend = std::min (y+blocksize*blocks_per_thread, roi.yend); threads.add_thread (new boost::thread (sha1_hasher, &src, broi, blocksize, &results[0], b)); } threads.join_all (); } #ifdef USE_OPENSSL // If OpenSSL was available at build time, use its SHA-1 // implementation, which is about 20% faster than CSHA1. SHA_CTX sha; SHA1_Init (&sha); for (int b = 0; b < nblocks; ++b) SHA1_Update (&sha, results[b].c_str(), results[b].size()); if (extrainfo.size()) SHA1_Update (&sha, extrainfo.c_str(), extrainfo.size()); unsigned char md[SHA_DIGEST_LENGTH]; char hash_digest[2*SHA_DIGEST_LENGTH+1]; SHA1_Final (md, &sha); for (int i = 0; i < SHA_DIGEST_LENGTH; ++i) sprintf (hash_digest+2*i, "%02X", (int)md[i]); hash_digest[2*SHA_DIGEST_LENGTH] = 0; return std::string (hash_digest); #else // Fall back on CSHA1 if OpenSSL was not available or if CSHA1 sha; sha.Reset (); for (int b = 0; b < nblocks; ++b) sha.Update ((const unsigned char *)results[b].c_str(), results[b].size()); if (extrainfo.size()) sha.Update ((const unsigned char *)extrainfo.c_str(), extrainfo.size()); sha.Final (); std::string hash_digest; sha.ReportHashStl (hash_digest, CSHA1::REPORT_HEX_SHORT); return hash_digest; #endif } /// histogram_impl ----------------------------------------------------------- /// Fully type-specialized version of histogram. /// /// Pixel values in min->max range are mapped to 0->(bins-1) range, so that /// each value is placed in the appropriate bin. The formula used is: /// y = (x-min) * bins/(max-min), where y is the value in the 0->(bins-1) /// range and x is the value in the min->max range. There is one special /// case x==max for which the formula is not used and x is assigned to the /// last bin at position (bins-1) in the vector histogram. /// -------------------------------------------------------------------------- template static bool histogram_impl (const ImageBuf &A, int channel, std::vector &histogram, int bins, float min, float max, imagesize_t *submin, imagesize_t *supermax, ROI roi) { // Double check A's type. if (A.spec().format != BaseTypeFromC::value) { A.error ("Unsupported pixel data format '%s'", A.spec().format); return false; } // Initialize. ImageBuf::ConstIterator a (A, roi); float ratio = bins / (max-min); int bins_minus_1 = bins-1; bool submin_ok = submin != NULL; bool supermax_ok = supermax != NULL; if (submin_ok) *submin = 0; if (supermax_ok) *supermax = 0; histogram.assign(bins, 0); // Compute histogram. for ( ; ! a.done(); a++) { float c = a[channel]; if (c >= min && c < max) { // Map range min->max to 0->(bins-1). histogram[ (int) ((c-min) * ratio) ]++; } else if (c == max) { histogram[bins_minus_1]++; } else { if (submin_ok && c < min) (*submin)++; else if (supermax_ok) (*supermax)++; } } return true; } bool ImageBufAlgo::histogram (const ImageBuf &A, int channel, std::vector &histogram, int bins, float min, float max, imagesize_t *submin, imagesize_t *supermax, ROI roi) { if (A.spec().format != TypeDesc::TypeFloat) { A.error ("Unsupported pixel data format '%s'", A.spec().format); return false; } if (A.nchannels() == 0) { A.error ("Input image must have at least 1 channel"); return false; } if (channel < 0 || channel >= A.nchannels()) { A.error ("Invalid channel %d for input image with channels 0 to %d", channel, A.nchannels()-1); return false; } if (bins < 1) { A.error ("The number of bins must be at least 1"); return false; } if (max <= min) { A.error ("Invalid range, min must be strictly smaller than max"); return false; } // Specified ROI -> use it. Unspecified ROI -> initialize from A. if (! roi.defined()) roi = get_roi (A.spec()); histogram_impl (A, channel, histogram, bins, min, max, submin, supermax, roi); return ! A.has_error(); } bool ImageBufAlgo::histogram_draw (ImageBuf &R, const std::vector &histogram) { // Fail if there are no bins to draw. int bins = histogram.size(); if (bins == 0) { R.error ("There are no bins to draw, the histogram is empty"); return false; } // Check R and modify it if needed. int height = R.spec().height; if (R.spec().format != TypeDesc::TypeFloat || R.nchannels() != 1 || R.spec().width != bins) { ImageSpec newspec = ImageSpec (bins, height, 1, TypeDesc::FLOAT); R.reset ("dummy", newspec); } // Fill output image R with white color. ImageBuf::Iterator r (R); for ( ; ! r.done(); ++r) r[0] = 1; // Draw histogram left->right, bottom->up. imagesize_t max = *std::max_element (histogram.begin(), histogram.end()); for (int b = 0; b < bins; b++) { int bin_height = (int) ((float)histogram[b]/(float)max*height + 0.5f); if (bin_height != 0) { // Draw one bin at column b. for (int j = 1; j <= bin_height; j++) { int row = height - j; r.pos (b, row); r[0] = 0; } } } return true; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/filesystem_test.cpp0000644000175000017500000001670112271062644023627 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include "imageio.h" #include "filesystem.h" #include "unittest.h" OIIO_NAMESPACE_USING; void test_filename_decomposition () { std::cout << "filename(\"/directory/filename.ext\") = " << Filesystem::filename("/directory/filename.ext") << "\n"; OIIO_CHECK_EQUAL (Filesystem::filename("/directory/filename.ext"), "filename.ext"); std::cout << "extension(\"/directory/filename.ext\") = " << Filesystem::extension("/directory/filename.ext") << "\n"; OIIO_CHECK_EQUAL (Filesystem::extension("/directory/filename.ext"), ".ext"); OIIO_CHECK_EQUAL (Filesystem::extension("/directory/filename"), ""); OIIO_CHECK_EQUAL (Filesystem::extension("/directory/filename."), "."); } void test_filename_searchpath_find () { #if _WIN32 # define SEPARATOR "\\" #else # define SEPARATOR "/" #endif // This will be run via testsuite/unit_filesystem, from the // build/ARCH/src/libOpenImageIO directory. Two levels up will be // build/ARCH. std::vector dirs; dirs.push_back (".." SEPARATOR ".."); std::string s; // non-recursive search success s = Filesystem::searchpath_find ("License.txt", dirs, false, false); OIIO_CHECK_EQUAL (s, ".." SEPARATOR ".." SEPARATOR "License.txt"); // non-recursive search failure (file is in a subdirectory) s = Filesystem::searchpath_find ("version.h", dirs, false, false); OIIO_CHECK_EQUAL (s, ""); // recursive search success (file is in a subdirectory) s = Filesystem::searchpath_find ("version.h", dirs, false, true); OIIO_CHECK_EQUAL (s, ".." SEPARATOR ".." SEPARATOR "include" SEPARATOR "version.h"); } static void test_seq (const char *str, const char *expected) { std::vector sequence; Filesystem::enumerate_sequence (str, sequence); std::stringstream joined; for (size_t i = 0; i < sequence.size(); ++i) { if (i) joined << " "; joined << sequence[i]; } std::cout << " \"" << str << "\" -> " << joined.str() << "\n"; OIIO_CHECK_EQUAL (joined.str(), std::string(expected)); } static void test_file_seq (const char *pattern, const char *override, const std::string &expected) { std::vector numbers; std::vector names; std::string normalized_pattern; std::string frame_range; Filesystem::parse_pattern(pattern, 0, normalized_pattern, frame_range); if (override && strlen(override) > 0) frame_range = override; Filesystem::enumerate_sequence(frame_range.c_str(), numbers); Filesystem::enumerate_file_sequence (normalized_pattern, numbers, names); std::string joined = Strutil::join(names, " "); std::cout << " " << pattern; if (override) std::cout << " + " << override; std::cout << " -> " << joined << "\n"; OIIO_CHECK_EQUAL (joined, expected); } static void test_scan_file_seq (const char *pattern, const std::string &expected) { std::vector numbers; std::vector names; std::string normalized_pattern; std::string frame_range; Filesystem::parse_pattern(pattern, 0, normalized_pattern, frame_range); Filesystem::scan_for_matching_filenames (normalized_pattern, numbers, names); std::string joined = Strutil::join(names, " "); std::cout << " " << pattern; std::cout << " -> " << joined << "\n"; OIIO_CHECK_EQUAL (joined, expected); } void test_frame_sequences () { std::cout << "Testing frame number sequences:\n"; test_seq ("3", "3"); test_seq ("1-5", "1 2 3 4 5"); test_seq ("5-1", "5 4 3 2 1"); test_seq ("1-3,6,10-12", "1 2 3 6 10 11 12"); test_seq ("1-5x2", "1 3 5"); test_seq ("1-5y2", "2 4"); std::cout << "\n"; test_file_seq ("foo.1-5#.exr", NULL, "foo.0001.exr foo.0002.exr foo.0003.exr foo.0004.exr foo.0005.exr"); test_file_seq ("foo.5-1#.exr", NULL, "foo.0005.exr foo.0004.exr foo.0003.exr foo.0002.exr foo.0001.exr"); test_file_seq ("foo.1-3,6,10-12#.exr", NULL, "foo.0001.exr foo.0002.exr foo.0003.exr foo.0006.exr foo.0010.exr foo.0011.exr foo.0012.exr"); test_file_seq ("foo.1-5x2#.exr", NULL, "foo.0001.exr foo.0003.exr foo.0005.exr"); test_file_seq ("foo.1-5y2#.exr", NULL, "foo.0002.exr foo.0004.exr"); test_file_seq ("foo.#.exr", "1-5", "foo.0001.exr foo.0002.exr foo.0003.exr foo.0004.exr foo.0005.exr"); test_file_seq ("foo.#.exr", "1-5x2", "foo.0001.exr foo.0003.exr foo.0005.exr"); test_file_seq ("foo.1-3@@.exr", NULL, "foo.01.exr foo.02.exr foo.03.exr"); test_file_seq ("foo.1-3@#.exr", NULL, "foo.00001.exr foo.00002.exr foo.00003.exr"); test_file_seq ("foo.1-5%04d.exr", NULL, "foo.0001.exr foo.0002.exr foo.0003.exr foo.0004.exr foo.0005.exr"); test_file_seq ("foo.%04d.exr", "1-5", "foo.0001.exr foo.0002.exr foo.0003.exr foo.0004.exr foo.0005.exr"); test_file_seq ("foo.%4d.exr", "1-5", "foo. 1.exr foo. 2.exr foo. 3.exr foo. 4.exr foo. 5.exr"); test_file_seq ("foo.%d.exr", "1-5", "foo.1.exr foo.2.exr foo.3.exr foo.4.exr foo.5.exr"); std::cout << "\n"; } void test_scan_sequences () { std::cout << "Testing frame sequence scanning:\n"; std::vector< std::string > filenames; for (size_t i = 1; i <= 5; i++) { std::string fn = Strutil::format ("foo.%04d.exr", i); filenames.push_back (fn); std::ofstream f(fn.c_str()); f.close(); } #ifdef _WIN32 test_scan_file_seq ("foo.#.exr", ".\\foo.0001.exr .\\foo.0002.exr .\\foo.0003.exr .\\foo.0004.exr .\\foo.0005.exr"); #else test_scan_file_seq ("foo.#.exr", "./foo.0001.exr ./foo.0002.exr ./foo.0003.exr ./foo.0004.exr ./foo.0005.exr"); #endif } int main (int argc, char *argv[]) { test_filename_decomposition (); test_filename_searchpath_find (); test_frame_sequences (); test_scan_sequences (); return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/strutil_test.cpp0000644000175000017500000003315112271062644023147 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "strutil.h" #include "unittest.h" OIIO_NAMESPACE_USING; void test_format () { // Test formatting OIIO_CHECK_EQUAL (Strutil::format ("%d %f %g", int(3), 3.14f, 3.14f), "3 3.140000 3.14"); OIIO_CHECK_EQUAL (Strutil::format ("'%s' '%s'", "foo", std::string("foo")), "'foo' 'foo'"); OIIO_CHECK_EQUAL (Strutil::format ("'%3d' '%03d' '%-3d'", 3, 3, 3), "' 3' '003' '3 '"); // Test '+' format modifier OIIO_CHECK_EQUAL (Strutil::format ("%+d%+d%+d", 3, -3, 0), "+3-3+0"); // FIXME -- we should make comprehensive tests here } void test_memformat () { OIIO_CHECK_EQUAL (Strutil::memformat (15), "15 B"); OIIO_CHECK_EQUAL (Strutil::memformat (15LL*1024), "15 KB"); OIIO_CHECK_EQUAL (Strutil::memformat (15LL*1024*1024), "15.0 MB"); OIIO_CHECK_EQUAL (Strutil::memformat (15LL*1024*1024*1024), "15.0 GB"); OIIO_CHECK_EQUAL (Strutil::memformat (15LL*1024*1024+200000), "15.2 MB"); OIIO_CHECK_EQUAL (Strutil::memformat (15LL*1024*1024+200000, 3), "15.191 MB"); } void test_timeintervalformat () { OIIO_CHECK_EQUAL (Strutil::timeintervalformat (15.321), "15.3s"); OIIO_CHECK_EQUAL (Strutil::timeintervalformat (150.321), "2m 30.3s"); OIIO_CHECK_EQUAL (Strutil::timeintervalformat (15000.321), "4h 10m 0.3s"); OIIO_CHECK_EQUAL (Strutil::timeintervalformat (150000.321), "1d 17h 40m 0.3s"); OIIO_CHECK_EQUAL (Strutil::timeintervalformat (150.321, 2), "2m 30.32s"); } void test_get_rest_arguments () { int ret; std::map result; std::string base; std::string url = "someplace?arg1=value1&arg2=value2"; ret = Strutil::get_rest_arguments (url, base, result); OIIO_CHECK_EQUAL (ret, true); OIIO_CHECK_EQUAL (base, "someplace"); OIIO_CHECK_EQUAL (result["arg1"], "value1"); OIIO_CHECK_EQUAL (result["arg2"], "value2"); OIIO_CHECK_EQUAL (result["arg3"], ""); result.clear(); url = "?arg1=value1&arg2=value2"; ret = Strutil::get_rest_arguments (url, base, result); OIIO_CHECK_EQUAL (ret, true); OIIO_CHECK_EQUAL (base, ""); OIIO_CHECK_EQUAL (result["arg1"], "value1"); OIIO_CHECK_EQUAL (result["arg2"], "value2"); result.clear(); url = "arg1=value1&arg2=value2"; ret = Strutil::get_rest_arguments (url, base, result); OIIO_CHECK_EQUAL (ret, true); OIIO_CHECK_EQUAL (base, "arg1=value1&arg2=value2"); OIIO_CHECK_EQUAL (result["arg1"], ""); OIIO_CHECK_EQUAL (result["arg2"], ""); result.clear(); url = ""; ret = Strutil::get_rest_arguments (url, base, result); OIIO_CHECK_EQUAL (ret, true); OIIO_CHECK_EQUAL (base, ""); OIIO_CHECK_EQUAL (result["arg1"], ""); OIIO_CHECK_EQUAL (result["arg2"], ""); result.clear(); url = "sometextwithoutasense????&&&&&arg4=val1"; ret = Strutil::get_rest_arguments (url, base, result); OIIO_CHECK_EQUAL (ret, false); OIIO_CHECK_EQUAL (base, "sometextwithoutasense"); OIIO_CHECK_EQUAL (result["arg1"], ""); OIIO_CHECK_EQUAL (result["arg2"], ""); OIIO_CHECK_EQUAL (result["arg4"], ""); result.clear(); url = "atext?arg1value1&arg2value2"; ret = Strutil::get_rest_arguments (url, base, result); OIIO_CHECK_EQUAL (ret, false); OIIO_CHECK_EQUAL (base, "atext"); OIIO_CHECK_EQUAL (result["arg1"], ""); OIIO_CHECK_EQUAL (result["arg2"], ""); result.clear(); url = "atext?arg1=value1&arg2value2"; result["arg2"] = "somevalue"; ret = Strutil::get_rest_arguments (url, base, result); OIIO_CHECK_EQUAL (ret, false); OIIO_CHECK_EQUAL (base, "atext"); OIIO_CHECK_EQUAL (result["arg1"], "value1"); OIIO_CHECK_EQUAL (result["arg2"], "somevalue"); } void test_escape_sequences () { OIIO_CHECK_EQUAL (Strutil::unescape_chars("\\\\ \\n \\r \\017"), "\\ \n \r \017"); OIIO_CHECK_EQUAL (Strutil::escape_chars("\\ \n \r"), "\\\\ \\n \\r"); } void test_wordwrap () { std::string words = "Now is the time for all good men to come to the aid of their party."; OIIO_CHECK_EQUAL (Strutil::wordwrap(words, 24), "Now is the time for all\n" "good men to come to the\n" "aid of their party."); } void test_comparisons () { OIIO_CHECK_EQUAL (Strutil::iequals ("abc", "abc"), true); OIIO_CHECK_EQUAL (Strutil::iequals ("Abc", "aBc"), true); OIIO_CHECK_EQUAL (Strutil::iequals ("abc", "adc"), false); OIIO_CHECK_EQUAL (Strutil::istarts_with ("abcd", "ab"), true); OIIO_CHECK_EQUAL (Strutil::istarts_with ("aBcd", "Ab"), true); OIIO_CHECK_EQUAL (Strutil::istarts_with ("abcd", "ba"), false); OIIO_CHECK_EQUAL (Strutil::istarts_with ("abcd", "abcde"), false); OIIO_CHECK_EQUAL (Strutil::istarts_with ("", "a"), false); OIIO_CHECK_EQUAL (Strutil::istarts_with ("", ""), true); OIIO_CHECK_EQUAL (Strutil::istarts_with ("abc", ""), true); OIIO_CHECK_EQUAL (Strutil::iends_with ("abcd", "cd"), true); OIIO_CHECK_EQUAL (Strutil::iends_with ("aBCd", "cd"), true); OIIO_CHECK_EQUAL (Strutil::iends_with ("aBcd", "CD"), true); OIIO_CHECK_EQUAL (Strutil::iends_with ("abcd", "ba"), false); OIIO_CHECK_EQUAL (Strutil::iends_with ("abcd", "xabcd"), false); OIIO_CHECK_EQUAL (Strutil::iends_with ("", "a"), false); OIIO_CHECK_EQUAL (Strutil::iends_with ("", ""), true); OIIO_CHECK_EQUAL (Strutil::iends_with ("abc", ""), true); OIIO_CHECK_EQUAL (Strutil::contains ("abcde", "ab"), true); OIIO_CHECK_EQUAL (Strutil::contains ("abcde", "bcd"), true); OIIO_CHECK_EQUAL (Strutil::contains ("abcde", "de"), true); OIIO_CHECK_EQUAL (Strutil::contains ("abcde", "cdx"), false); OIIO_CHECK_EQUAL (Strutil::contains ("abcde", ""), true); OIIO_CHECK_EQUAL (Strutil::contains ("", ""), true); OIIO_CHECK_EQUAL (Strutil::contains ("", "x"), false); OIIO_CHECK_EQUAL (Strutil::icontains ("abcde", "ab"), true); OIIO_CHECK_EQUAL (Strutil::icontains ("Abcde", "aB"), true); OIIO_CHECK_EQUAL (Strutil::icontains ("abcde", "bcd"), true); OIIO_CHECK_EQUAL (Strutil::icontains ("Abcde", "bCd"), true); OIIO_CHECK_EQUAL (Strutil::icontains ("abcDe", "dE"), true); OIIO_CHECK_EQUAL (Strutil::icontains ("abcde", "cdx"), false); OIIO_CHECK_EQUAL (Strutil::icontains ("abcde", ""), true); OIIO_CHECK_EQUAL (Strutil::icontains ("", ""), true); OIIO_CHECK_EQUAL (Strutil::icontains ("", "x"), false); } void test_case () { std::string s; s = "abcDEF,*1"; Strutil::to_lower (s); OIIO_CHECK_EQUAL (s, "abcdef,*1"); s = "abcDEF,*1"; Strutil::to_upper (s); OIIO_CHECK_EQUAL (s, "ABCDEF,*1"); } void test_strip () { OIIO_CHECK_EQUAL (Strutil::strip ("abcdefbac", "abc"), "def"); OIIO_CHECK_EQUAL (Strutil::strip ("defghi", "abc"), "defghi"); OIIO_CHECK_EQUAL (Strutil::strip (" \tHello, world\n"), "Hello, world"); OIIO_CHECK_EQUAL (Strutil::strip (" \t"), ""); OIIO_CHECK_EQUAL (Strutil::strip (""), ""); } void test_split () { std::string s ("Now\nis the time!"); std::vector splits; // test default -- split at whitespace Strutil::split (s, splits); OIIO_CHECK_EQUAL (splits.size(), 4); OIIO_CHECK_EQUAL (splits[0], "Now"); OIIO_CHECK_EQUAL (splits[1], "is"); OIIO_CHECK_EQUAL (splits[2], "the"); OIIO_CHECK_EQUAL (splits[3], "time!"); // test custom split string Strutil::split (s, splits, " t"); OIIO_CHECK_EQUAL (splits.size(), 3); OIIO_CHECK_EQUAL (splits[0], "Now\nis"); OIIO_CHECK_EQUAL (splits[1], "he "); OIIO_CHECK_EQUAL (splits[2], "ime!"); // test maxsplit Strutil::split (s, splits, "", 2); OIIO_CHECK_EQUAL (splits.size(), 2); OIIO_CHECK_EQUAL (splits[0], "Now"); OIIO_CHECK_EQUAL (splits[1], "is the time!"); // test maxsplit with non-default sep Strutil::split (s, splits, " ", 2); OIIO_CHECK_EQUAL (splits.size(), 2); OIIO_CHECK_EQUAL (splits[0], "Now\nis"); OIIO_CHECK_EQUAL (splits[1], "the time!"); } void test_join () { std::vector seq; seq.push_back ("Now"); seq.push_back ("is"); seq.push_back ("the"); seq.push_back ("time"); OIIO_CHECK_EQUAL (Strutil::join (seq, ". "), "Now. is. the. time"); } void test_conversion () { OIIO_CHECK_EQUAL (Strutil::from_string("hi"), 0); OIIO_CHECK_EQUAL (Strutil::from_string("123"), 123); OIIO_CHECK_EQUAL (Strutil::from_string("-123"), -123); OIIO_CHECK_EQUAL (Strutil::from_string(" 123 "), 123); OIIO_CHECK_EQUAL (Strutil::from_string("123.45"), 123); OIIO_CHECK_EQUAL (Strutil::from_string("hi"), 0.0f); OIIO_CHECK_EQUAL (Strutil::from_string("123"), 123.0f); OIIO_CHECK_EQUAL (Strutil::from_string("-123"), -123.0f); OIIO_CHECK_EQUAL (Strutil::from_string("123.45"), 123.45f); OIIO_CHECK_EQUAL (Strutil::from_string(" 123.45 "), 123.45f); OIIO_CHECK_EQUAL (Strutil::from_string("123.45+12"), 123.45f); OIIO_CHECK_EQUAL (Strutil::from_string("1.2345e+2"), 123.45f); } void test_extract () { std::vector vals; vals.clear(); vals.resize (3, -1); Strutil::extract_from_list_string (vals, "1"); OIIO_CHECK_EQUAL (vals.size(), 3); OIIO_CHECK_EQUAL (vals[0], 1); OIIO_CHECK_EQUAL (vals[1], 1); OIIO_CHECK_EQUAL (vals[2], 1); vals.clear(); vals.resize (3, -1); Strutil::extract_from_list_string (vals, "1,3,5"); OIIO_CHECK_EQUAL (vals.size(), 3); OIIO_CHECK_EQUAL (vals[0], 1); OIIO_CHECK_EQUAL (vals[1], 3); OIIO_CHECK_EQUAL (vals[2], 5); vals.clear(); vals.resize (3, -1); Strutil::extract_from_list_string (vals, "1,,5"); OIIO_CHECK_EQUAL (vals.size(), 3); OIIO_CHECK_EQUAL (vals[0], 1); OIIO_CHECK_EQUAL (vals[1], -1); OIIO_CHECK_EQUAL (vals[2], 5); vals.clear(); vals.resize (3, -1); Strutil::extract_from_list_string (vals, "abc"); OIIO_CHECK_EQUAL (vals.size(), 3); OIIO_CHECK_EQUAL (vals[0], 0); OIIO_CHECK_EQUAL (vals[1], 0); OIIO_CHECK_EQUAL (vals[2], 0); vals.clear(); vals.resize (3, -1); Strutil::extract_from_list_string (vals, ""); OIIO_CHECK_EQUAL (vals.size(), 3); OIIO_CHECK_EQUAL (vals[0], -1); OIIO_CHECK_EQUAL (vals[1], -1); OIIO_CHECK_EQUAL (vals[2], -1); } void test_safe_strcpy () { { // test in-bounds copy char result[4] = { '0', '1', '2', '3' }; Strutil::safe_strcpy (result, "A", 3); OIIO_CHECK_EQUAL (result[0], 'A'); OIIO_CHECK_EQUAL (result[1], 0); OIIO_CHECK_EQUAL (result[2], '2'); // should not overwrite OIIO_CHECK_EQUAL (result[3], '3'); // should not overwrite } { // test over-bounds copy char result[4] = { '0', '1', '2', '3' }; Strutil::safe_strcpy (result, "ABC", 3); OIIO_CHECK_EQUAL (result[0], 'A'); OIIO_CHECK_EQUAL (result[1], 'B'); OIIO_CHECK_EQUAL (result[2], 0); OIIO_CHECK_EQUAL (result[3], '3'); // should not overwrite } { // test empty string copy char result[4] = { '0', '1', '2', '3' }; Strutil::safe_strcpy (result, "", 3); OIIO_CHECK_EQUAL (result[0], 0); OIIO_CHECK_EQUAL (result[1], '1'); // should not overwrite OIIO_CHECK_EQUAL (result[2], '2'); // should not overwrite OIIO_CHECK_EQUAL (result[3], '3'); // should not overwrite } { // test NULL case char result[4] = { '0', '1', '2', '3' }; Strutil::safe_strcpy (result, NULL, 3); OIIO_CHECK_EQUAL (result[0], 0); OIIO_CHECK_EQUAL (result[1], '1'); // should not overwrite OIIO_CHECK_EQUAL (result[2], '2'); // should not overwrite OIIO_CHECK_EQUAL (result[3], '3'); // should not overwrite } } int main (int argc, char *argv[]) { test_format (); test_memformat (); test_timeintervalformat (); test_get_rest_arguments (); test_escape_sequences (); test_wordwrap (); test_comparisons (); test_case (); test_strip (); test_split (); test_join (); test_conversion (); test_extract (); test_safe_strcpy (); return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/kissfft.hh0000644000175000017500000002765312271062644021702 0ustar mfvmfv// From KissFFT http://sourceforge.net/projects/kissfft/ /* Copyright (c) 2003-2010 Mark Borgerding All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef KISSFFT_CLASS_HH #include #include namespace kissfft_utils { template struct traits { typedef T_scalar scalar_type; typedef std::complex cpx_type; void fill_twiddles( std::complex * dst ,int nfft,bool inverse) { T_scalar phinc = (inverse?2:-2)* acos( (T_scalar) -1) / nfft; for (int i=0;i(0,i*phinc) ); } void prepare( std::vector< std::complex > & dst, int nfft,bool inverse, std::vector & stageRadix, std::vector & stageRemainder ) { _twiddles.resize(nfft); fill_twiddles( &_twiddles[0],nfft,inverse); dst = _twiddles; //factorize //start factoring out 4's, then 2's, then 3,5,7,9,... int n= nfft; int p=4; do { while (n % p) { switch (p) { case 4: p = 2; break; case 2: p = 3; break; default: p += 2; break; } if (p*p>n) p=n;// no more factors } n /= p; stageRadix.push_back(p); stageRemainder.push_back(n); }while(n>1); } std::vector _twiddles; const cpx_type twiddle(int i) { return _twiddles[i]; } }; } template > class kissfft { public: typedef T_traits traits_type; typedef typename traits_type::scalar_type scalar_type; typedef typename traits_type::cpx_type cpx_type; kissfft(int nfft,bool inverse,const traits_type & traits=traits_type() ) :_nfft(nfft),_inverse(inverse),_traits(traits) { _traits.prepare(_twiddles, _nfft,_inverse ,_stageRadix, _stageRemainder); } void transform(const cpx_type * src , cpx_type * dst) { kf_work(0, dst, src, 1,1); } private: void kf_work( int stage,cpx_type * Fout, const cpx_type * f, size_t fstride,size_t in_stride) { int p = _stageRadix[stage]; int m = _stageRemainder[stage]; cpx_type * Fout_beg = Fout; cpx_type * Fout_end = Fout + p*m; if (m==1) { do{ *Fout = *f; f += fstride*in_stride; }while(++Fout != Fout_end ); }else{ do{ // recursive call: // DFT of size m*p performed by doing // p instances of smaller DFTs of size m, // each one takes a decimated version of the input kf_work(stage+1, Fout , f, fstride*p,in_stride); f += fstride*in_stride; }while( (Fout += m) != Fout_end ); } Fout=Fout_beg; // recombine the p smaller DFTs switch (p) { case 2: kf_bfly2(Fout,fstride,m); break; case 3: kf_bfly3(Fout,fstride,m); break; case 4: kf_bfly4(Fout,fstride,m); break; case 5: kf_bfly5(Fout,fstride,m); break; default: kf_bfly_generic(Fout,fstride,m,p); break; } } // these were #define macros in the original kiss_fft void C_ADD( cpx_type & c,const cpx_type & a,const cpx_type & b) { c=a+b;} void C_MUL( cpx_type & c,const cpx_type & a,const cpx_type & b) { c=a*b;} void C_SUB( cpx_type & c,const cpx_type & a,const cpx_type & b) { c=a-b;} void C_ADDTO( cpx_type & c,const cpx_type & a) { c+=a;} void C_FIXDIV( cpx_type & ,int ) {} // NO-OP for float types scalar_type S_MUL( const scalar_type & a,const scalar_type & b) { return a*b;} scalar_type HALF_OF( const scalar_type & a) { return a*.5;} void C_MULBYSCALAR(cpx_type & c,const scalar_type & a) {c*=a;} void kf_bfly2( cpx_type * Fout, const size_t fstride, int m) { for (int k=0;kreal() - HALF_OF(scratch[3].real() ) , Fout->imag() - HALF_OF(scratch[3].imag() ) ); C_MULBYSCALAR( scratch[0] , epi3.imag() ); C_ADDTO(*Fout,scratch[3]); Fout[m2] = cpx_type( Fout[m].real() + scratch[0].imag() , Fout[m].imag() - scratch[0].real() ); C_ADDTO( Fout[m] , cpx_type( -scratch[0].imag(),scratch[0].real() ) ); ++Fout; }while(--k); } void kf_bfly5( cpx_type * Fout, const size_t fstride, const size_t m) { cpx_type *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; size_t u; cpx_type scratch[13]; cpx_type * twiddles = &_twiddles[0]; cpx_type *tw; cpx_type ya,yb; ya = twiddles[fstride*m]; yb = twiddles[fstride*2*m]; Fout0=Fout; Fout1=Fout0+m; Fout2=Fout0+2*m; Fout3=Fout0+3*m; Fout4=Fout0+4*m; tw=twiddles; for ( u=0; u=Norig) twidx-=Norig; C_MUL(t,scratchbuf[q] , twiddles[twidx] ); C_ADDTO( Fout[ k ] ,t); } k += m; } } } int _nfft; bool _inverse; std::vector _twiddles; std::vector _stageRadix; std::vector _stageRemainder; traits_type _traits; std::vector scratchbuf; }; #endif openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imageioplugin.cpp0000644000175000017500000004641712271062644023244 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include "dassert.h" #include "plugin.h" #include "strutil.h" #include "filesystem.h" #include "imageio.h" #include "imageio_pvt.h" OIIO_NAMESPACE_ENTER { using namespace pvt; typedef std::map InputPluginMap; typedef std::map OutputPluginMap; namespace { // Map format name to ImageInput creation static InputPluginMap input_formats; // Map format name to ImageOutput creation static OutputPluginMap output_formats; // Map file extension to ImageInput creation static InputPluginMap input_extensions; // Map file extension to ImageOutput creation static OutputPluginMap output_extensions; // Map format name to plugin handle static std::map plugin_handles; // Map format name to full path static std::map plugin_filepaths; // FIXME -- do we use the extensions above? static std::string pattern = Strutil::format (".imageio.%s", Plugin::plugin_extension()); inline void add_if_missing (std::vector &vec, const std::string &val) { if (std::find (vec.begin(), vec.end(), val) == vec.end()) vec.push_back (val); } } // anon namespace /// Register the input and output 'create' routine and list of file /// extensions for a particular format. void declare_imageio_format (const std::string &format_name, ImageInput::Creator input_creator, const char **input_extensions, ImageOutput::Creator output_creator, const char **output_extensions) { std::vector all_extensions; // Look for input creator and list of supported extensions if (input_creator) { if (input_formats.find(format_name) != input_formats.end()) input_formats[format_name] = input_creator; std::string extsym = format_name + "_input_extensions"; for (const char **e = input_extensions; e && *e; ++e) { std::string ext (*e); Strutil::to_lower (ext); if (input_formats.find(ext) == input_formats.end()) { input_formats[ext] = input_creator; add_if_missing (all_extensions, ext); } } } // Look for output creator and list of supported extensions if (output_creator) { if (output_formats.find(format_name) != output_formats.end()) output_formats[format_name] = output_creator; for (const char **e = output_extensions; e && *e; ++e) { std::string ext (*e); Strutil::to_lower (ext); if (output_formats.find(ext) == output_formats.end()) { output_formats[ext] = output_creator; add_if_missing (all_extensions, ext); } } } // Add the name to the master list of format_names, and extensions to // their master list. recursive_lock_guard lock (pvt::imageio_mutex); if (format_list.length()) format_list += std::string(","); format_list += format_name; if (extension_list.length()) extension_list += std::string(";"); extension_list += format_name + std::string(":"); extension_list += Strutil::join(all_extensions, ","); } static void catalog_plugin (const std::string &format_name, const std::string &plugin_fullpath) { // Remember the plugin std::map::const_iterator found_path; found_path = plugin_filepaths.find (format_name); if (found_path != plugin_filepaths.end()) { // Hey, we already have an entry for this format if (found_path->second == plugin_fullpath) { // It's ok if they're both the same file; just skip it. return; } // if (verbosity > 1) #ifndef NDEBUG std::cerr << "OpenImageIO WARNING: " << format_name << " had multiple plugins:\n" << "\t\"" << found_path->second << "\"\n" << " as well as\n" << "\t\"" << plugin_fullpath << "\"\n" << " Ignoring all but the first one.\n"; #endif return; } Plugin::Handle handle = Plugin::open (plugin_fullpath); if (! handle) { return; } std::string version_function = format_name + "_imageio_version"; int *plugin_version = (int *) Plugin::getsym (handle, version_function.c_str()); if (! plugin_version || *plugin_version != OIIO_PLUGIN_VERSION) { Plugin::close (handle); return; } // Add the filepath and handle to the master lists plugin_filepaths[format_name] = plugin_fullpath; plugin_handles[format_name] = handle; ImageInput::Creator input_creator = (ImageInput::Creator) Plugin::getsym (handle, format_name+"_input_imageio_create"); const char **input_extensions = (const char **) Plugin::getsym (handle, format_name+"_input_extensions"); ImageOutput::Creator output_creator = (ImageOutput::Creator) Plugin::getsym (handle, format_name+"_output_imageio_create"); const char **output_extensions = (const char **) Plugin::getsym (handle, format_name+"_output_extensions"); if (input_creator || output_creator) declare_imageio_format (format_name, input_creator, input_extensions, output_creator, output_extensions); else Plugin::close (handle); // not useful } #ifdef EMBED_PLUGINS // Make extern declarations for the input and output create routines and // list of file extensions, for the standard plugins that come with OIIO. // These won't be used unless EMBED_PLUGINS is defined. Use the PLUGENTRY // macro to make the declaration compact and easy to read. #define PLUGENTRY(name) \ ImageInput *name ## _input_imageio_create (); \ ImageOutput *name ## _output_imageio_create (); \ extern const char *name ## _output_extensions[]; \ extern const char *name ## _input_extensions[]; PLUGENTRY (bmp); PLUGENTRY (cineon); PLUGENTRY (dds); PLUGENTRY (dpx); PLUGENTRY (field3d); PLUGENTRY (fits); PLUGENTRY (gif); PLUGENTRY (hdr); PLUGENTRY (ico); PLUGENTRY (iff); PLUGENTRY (jpeg); PLUGENTRY (jpeg2000); PLUGENTRY (openexr); PLUGENTRY (png); PLUGENTRY (pnm); PLUGENTRY (psd); PLUGENTRY (ptex); PLUGENTRY (rla); PLUGENTRY (sgi); PLUGENTRY (socket); PLUGENTRY (softimage); PLUGENTRY (tiff); PLUGENTRY (targa); PLUGENTRY (webp); PLUGENTRY (zfile); #endif // defined(EMBED_PLUGINS) namespace { /// Add all the built-in plugins, those compiled right into libOpenImageIO, /// to the catalogs. This does nothing if EMBED_PLUGINS is not defined, /// in which case they'll be registered only when read from external /// DSO/DLL's. static void catalog_builtin_plugins () { #ifdef EMBED_PLUGINS // Use DECLAREPLUG macro to make this more compact and easy to read. #define DECLAREPLUG(name) \ declare_imageio_format (#name, \ (ImageInput::Creator) name ## _input_imageio_create, \ name ## _input_extensions, \ (ImageOutput::Creator) name ## _output_imageio_create, \ name ## _output_extensions) DECLAREPLUG (bmp); DECLAREPLUG (cineon); DECLAREPLUG (dds); DECLAREPLUG (dpx); #ifdef USE_FIELD3D DECLAREPLUG (field3d); #endif DECLAREPLUG (fits); #ifdef USE_GIF DECLAREPLUG (gif); #endif DECLAREPLUG (hdr); DECLAREPLUG (ico); DECLAREPLUG (iff); DECLAREPLUG (jpeg); #ifdef USE_OPENJPEG DECLAREPLUG (jpeg2000); #endif DECLAREPLUG (openexr); DECLAREPLUG (png); DECLAREPLUG (pnm); DECLAREPLUG (psd); DECLAREPLUG (ptex); DECLAREPLUG (rla); DECLAREPLUG (sgi); #ifdef USE_BOOST_ASIO DECLAREPLUG (socket); #endif DECLAREPLUG (softimage); DECLAREPLUG (tiff); DECLAREPLUG (targa); #ifdef USE_WEBP DECLAREPLUG (webp); #endif DECLAREPLUG (zfile); #endif } } // anon namespace end /// Look at ALL imageio plugins in the searchpath and add them to the /// catalog. This routine is not reentrant and should only be called /// by a routine that is holding a lock on imageio_mutex. void pvt::catalog_all_plugins (std::string searchpath) { catalog_builtin_plugins (); const char *oiio_library_path = getenv ("OIIO_LIBRARY_PATH"); if (oiio_library_path && *oiio_library_path) { std::string newpath = oiio_library_path; if (searchpath.length()) newpath = newpath + ':' + searchpath; searchpath = newpath; } size_t patlen = pattern.length(); std::vector dirs; Filesystem::searchpath_split (searchpath, dirs, true); BOOST_FOREACH (std::string &dir, dirs) { boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end for (boost::filesystem::directory_iterator itr (dir); itr != end_itr; ++itr) { std::string full_filename = itr->path().string(); std::string leaf = Filesystem::filename (full_filename); size_t found = leaf.find (pattern); if (found != std::string::npos && (found == leaf.length() - patlen)) { std::string pluginname (leaf.begin(), leaf.begin() + leaf.length() - patlen); catalog_plugin (pluginname, full_filename); } } } } ImageOutput * ImageOutput::create (const std::string &filename, const std::string &plugin_searchpath) { if (filename.empty()) { // Can't even guess if no filename given pvt::error ("ImageOutput::create() called with no filename"); return NULL; } // Extract the file extension from the filename (without the leading dot) std::string format = Filesystem::extension (filename, false); if (format.empty()) { // If the file had no extension, maybe it was itself the format name format = filename; } ImageOutput::Creator create_function = NULL; { // scope the lock: recursive_lock_guard lock (imageio_mutex); // Ensure thread safety // See if it's already in the table. If not, scan all plugins we can // find to populate the table. Strutil::to_lower (format); OutputPluginMap::const_iterator found = output_formats.find (format); if (found == output_formats.end()) { catalog_all_plugins (plugin_searchpath.size() ? plugin_searchpath : pvt::plugin_searchpath.string()); found = output_formats.find (format); } if (found != output_formats.end()) { create_function = found->second; } else { if (output_formats.empty()) { // This error is so fundamental, we echo it to stderr in // case the app is too dumb to do so. const char *msg = "ImageOutput::create() could not find any ImageOutput plugins! Perhaps you need to set OIIO_LIBRARY_PATH.\n"; fprintf (stderr, "%s", msg); pvt::error ("%s", msg); } else pvt::error ("OpenImageIO could not find a format writer for \"%s\". " "Is it a file format that OpenImageIO doesn't know about?\n", filename.c_str()); return NULL; } } ASSERT (create_function != NULL); return (ImageOutput *) create_function(); } ImageInput * ImageInput::create (const std::string &filename, const std::string &plugin_searchpath) { return create (filename, false, plugin_searchpath); } ImageInput * ImageInput::create (const std::string &filename, bool do_open, const std::string &plugin_searchpath) { if (filename.empty()) { // Can't even guess if no filename given pvt::error ("ImageInput::create() called with no filename"); return NULL; } // Extract the file extension from the filename (without the leading dot) std::string format = Filesystem::extension (filename, false); if (format.empty()) { // If the file had no extension, maybe it was itself the format name format = filename; } ImageInput::Creator create_function = NULL; { // scope the lock: recursive_lock_guard lock (imageio_mutex); // Ensure thread safety // See if it's already in the table. If not, scan all plugins we can // find to populate the table. Strutil::to_lower (format); InputPluginMap::const_iterator found = input_formats.find (format); if (found == input_formats.end()) { catalog_all_plugins (plugin_searchpath.size() ? plugin_searchpath : pvt::plugin_searchpath.string()); found = input_formats.find (format); } if (found != input_formats.end()) create_function = found->second; } // Remember which prototypes we've already tried, so we don't double dip. std::vector formats_tried; std::string specific_error; if (create_function) { if (filename != format) { // If given a full filename, double-check that our guess // based on the extension actually works. You never know // when somebody will have an incorrectly-named file, let's // deal with it robustly. formats_tried.push_back (create_function); ImageInput *in = (ImageInput *)create_function(); if (! do_open && in && in->valid_file(filename)) { // Special case: we don't need to return the file // already opened, and this ImageInput says that the // file is the right type. return in; } ImageSpec tmpspec; bool ok = in && in->open (filename, tmpspec); if (ok) { // It worked if (! do_open) in->close (); return in; } else { // Oops, it failed. Apparently, this file can't be // opened with this II. Clear create_function to force // the code below to check every plugin we know. create_function = NULL; if (in) specific_error = in->geterror(); } delete in; } } if (! create_function) { // If a plugin can't be found that was explicitly designated for // this extension, then just try every one we find and see if // any will open the file. Pass it a configuration request that // includes a "nowait" option so that it returns immediately if // it's a plugin that might wait for an event, like a socket that // doesn't yet exist). ImageSpec config; config.attribute ("nowait", (int)1); recursive_lock_guard lock (imageio_mutex); // Ensure thread safety for (InputPluginMap::const_iterator plugin = input_formats.begin(); plugin != input_formats.end(); ++plugin) { // If we already tried this create function, don't do it again if (std::find (formats_tried.begin(), formats_tried.end(), plugin->second) != formats_tried.end()) continue; formats_tried.push_back (plugin->second); // remember ImageSpec tmpspec; ImageInput *in = plugin->second(); if (! in) continue; if (! do_open && ! in->valid_file(filename)) { // Since we didn't need to open it, we just checked whether // it was a valid file, and it's not. Try the next one. delete in; continue; } // We either need to open it, or we already know it appears // to be a file of the right type. bool ok = in->open(filename, tmpspec, config); if (ok) { if (! do_open) in->close (); return in; } delete in; } } if (create_function == NULL) { recursive_lock_guard lock (imageio_mutex); // Ensure thread safety if (input_formats.empty()) { // This error is so fundamental, we echo it to stderr in // case the app is too dumb to do so. const char *msg = "ImageInput::create() could not find any ImageInput plugins!\n" " Perhaps you need to set OIIO_LIBRARY_PATH.\n"; fprintf (stderr, "%s", msg); pvt::error ("%s", msg); } else if (! specific_error.empty()) { // Pass along any specific error message we got from our // best guess of the format. pvt::error ("OpenImageIO could not open \"%s\" as %s: %s", filename.c_str(), format.c_str(), specific_error.c_str()); } else if (Filesystem::exists (filename)) pvt::error ("OpenImageIO could not find a format reader for \"%s\". " "Is it a file format that OpenImageIO doesn't know about?\n", filename.c_str()); else pvt::error ("Image \"%s\" does not exist. Also, it is not the name of an image format that OpenImageIO recognizes.\n", filename.c_str()); return NULL; } return (ImageInput *) create_function(); } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/hash_test.cpp0000644000175000017500000001227212271062644022365 0ustar mfvmfv/* Copyright 2012 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include "hash.h" #include "timer.h" #include "argparse.h" #include "strutil.h" #include "unittest.h" OIIO_NAMESPACE_USING; static int iterations = 1000000000; static int ntrials = 1; static bool verbose = false; static std::string shortstring ("abcde"); static std::string longstring (1000,char('a')); static std::vector data (1000,42); int test_bjhash_small () { void *ptr = &data[0]; int len = 2*sizeof(int); int a = 0; for (int i = 0, e = iterations/len; i < e; ++i) a += bjhash::hashlittle (ptr, len); return a; } int test_bjhash_big () { void *ptr = &data[0]; int len = (int)(data.size() * sizeof(int)); int a = 0; for (int i = 0, e = iterations/len; i < e; ++i) a += bjhash::hashlittle (ptr, len); return a; } int test_bjhash_small_words () { uint32_t *ptr = &data[0]; int len = 2*sizeof(int); int a = 0; for (int i = 0, e = iterations/len; i < e; ++i) a += bjhash::hashword (ptr, len/sizeof(int)); return a; } int test_bjhash_big_words () { uint32_t *ptr = &data[0]; int len = (int)(data.size() * sizeof(int)); int a = 0; for (int i = 0, e = iterations/len; i < e; ++i) a += bjhash::hashword (ptr, len/sizeof(int)); return a; } int test_xxhash_small () { void *ptr = &data[0]; int len = 2*sizeof(int); int a = 0; for (int i = 0, e = iterations/len; i < e; ++i) a += xxhash::XXH_fast32 (ptr, len); return a; } int test_xxhash_big () { void *ptr = &data[0]; int len = (int)(data.size() * sizeof(int)); int a = 0; for (int i = 0, e = iterations/len; i < e; ++i) a += xxhash::XXH_fast32 (ptr, len); return a; } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap; ap.options ("hash_test\n" OIIO_INTRO_STRING "\n" "Usage: hash_test [options]", // "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose mode", "--iters %d", &iterations, Strutil::format("Number of iterations (default: %d)", iterations).c_str(), "--trials %d", &ntrials, "Number of trials", NULL); if (ap.parse (argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } } int main (int argc, char *argv[]) { getargs (argc, argv); double t; t = time_trial (test_bjhash_small, ntrials); std::cout << "BJ hash of small data as bytes: " << Strutil::timeintervalformat(t, 3) << "\n"; t = time_trial (test_bjhash_small_words, ntrials); std::cout << "BJ hash of small data as words: " << Strutil::timeintervalformat(t, 3) << "\n"; t = time_trial (test_bjhash_big, ntrials); std::cout << "BJ hash of big data: " << Strutil::timeintervalformat(t, 3) << "\n"; t = time_trial (test_bjhash_big_words, ntrials); std::cout << "BJ hash of big data as words: " << Strutil::timeintervalformat(t, 3) << "\n"; t = time_trial (test_xxhash_small, ntrials); std::cout << "XX hash of small data: " << Strutil::timeintervalformat(t, 3) << "\n"; t = time_trial (test_xxhash_big, ntrials); std::cout << "XX hash of big data: " << Strutil::timeintervalformat(t, 3) << "\n"; return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/libOpenImageIO.map0000644000175000017500000000006612271062644023157 0ustar mfvmfv{ global: *OpenImageIO*; *OIIO*; local: *; }; openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/fmath_test.cpp0000644000175000017500000001264212271062644022542 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "fmath.h" #include "unittest.h" OIIO_NAMESPACE_USING; // Convert T to F to T, make sure value are preserved round trip template void test_convert_type (double tolerance = 1e-6) { if (std::numeric_limits::is_integer) { for (long long i = std::numeric_limits::min(); i <= std::numeric_limits::max(); ++i) { T in = (T)i; F f = convert_type (in); T out = convert_type (f); if (out != in) { std::cout << " convert " << (long long)in << " -> " << f << " -> " << (long long)out << "\n"; ++unit_test_failures; } } } else { for (float i = 0.0f; i <= 1.0f; i += 0.001) { T in = (T)i; F f = convert_type (in); T out = convert_type (f); if (fabs(double(out-in)) > tolerance) { std::cout << " convert " << in << " -> " << f << " -> " << out << " (diff = " << (out-in) << ")\n"; ++unit_test_failures; } } } } void test_bit_range_convert () { OIIO_CHECK_EQUAL ((bit_range_convert<10,16>(1023)), 65535); OIIO_CHECK_EQUAL ((bit_range_convert<2,8>(3)), 255); OIIO_CHECK_EQUAL ((bit_range_convert<8,8>(255)), 255); OIIO_CHECK_EQUAL ((bit_range_convert<16,10>(65535)), 1023); OIIO_CHECK_EQUAL ((bit_range_convert<2,20>(3)), 1048575); OIIO_CHECK_EQUAL ((bit_range_convert<20,2>(1048575)), 3); OIIO_CHECK_EQUAL ((bit_range_convert<20,21>(1048575)), 2097151); OIIO_CHECK_EQUAL ((bit_range_convert<32,32>(4294967295U)), 4294967295U); OIIO_CHECK_EQUAL ((bit_range_convert<32,16>(4294967295U)), 65535); // These are not expected to work, since bit_range_convert only takes a // regular 'unsigned int' as parameter. If we need >32 bit conversion, // we need to add a uint64_t version of bit_range_convert. // OIIO_CHECK_EQUAL ((bit_range_convert<33,16>(8589934591)), 65535); // OIIO_CHECK_EQUAL ((bit_range_convert<33,33>(8589934591)), 8589934591); // OIIO_CHECK_EQUAL ((bit_range_convert<64,32>(18446744073709551615)), 4294967295); } int main (int argc, char *argv[]) { std::cout << "round trip convert char/float/char\n"; test_convert_type (); std::cout << "round trip convert unsigned char/float/unsigned char\n"; test_convert_type (); std::cout << "round trip convert unsigned char/unsigned short/unsigned char\n"; test_convert_type (); std::cout << "round trip convert short/float/short\n"; test_convert_type (); std::cout << "round trip convert unsigned short/float/unsigned short\n"; test_convert_type (); std::cout << "round trip convert float/int/float \n"; test_convert_type (); std::cout << "round trip convert double/float/double\n"; test_convert_type (); std::cout << "round trip convert double/long/double\n"; test_convert_type (); std::cout << "round trip convert float/unsigned int/float\n"; test_convert_type (); // convertion to a type smaller in bytes causes error // std::cout << "round trip convert float/short/float\n"; // test_convert_type (); // std::cout << "round trip convert unsigned float/char/float\n"; // test_convert_type (); // std::cout << "round trip convert unsigned float/unsigned char/float\n"; // test_convert_type (); // std::cout << "round trip convert unsigned short/unsigned char/unsigned short\n"; // test_convert_type (); // std::cout << "round trip convert float/unsigned short/float\n"; // test_convert_type (); test_bit_range_convert(); return unit_test_failures != 0; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/exif.cpp0000644000175000017500000011774412271062644021350 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include "fmath.h" extern "C" { #include "tiff.h" } // Some EXIF tags that don't seem to be in tiff.h #ifndef EXIFTAG_SECURITYCLASSIFICATION #define EXIFTAG_SECURITYCLASSIFICATION 37394 #endif #ifndef EXIFTAG_IMAGEHISTORY #define EXIFTAG_IMAGEHISTORY 37395 #endif #ifdef TIFF_VERSION_BIG // In old versions of TIFF, this was defined in tiff.h. It's gone from // "BIG TIFF" (libtiff 4.x), so we just define it here. struct TIFFHeader { uint16_t tiff_magic; /* magic number (defines byte order) */ uint16_t tiff_version;/* TIFF version number */ uint32_t tiff_diroff; /* byte offset to first directory */ }; struct TIFFDirEntry { uint16_t tdir_tag; /* tag ID */ uint16_t tdir_type; /* data type -- see TIFFDataType enum */ uint32_t tdir_count; /* number of items; length in spec */ uint32_t tdir_offset; /* byte offset to field data */ }; #endif #include "imageio.h" #define DEBUG_EXIF_READ 0 #define DEBUG_EXIF_WRITE 0 OIIO_NAMESPACE_ENTER { namespace { // Sizes of TIFFDataType members static size_t tiff_data_sizes[] = { 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4 }; static int tiff_data_size (const TIFFDirEntry &dir) { return tiff_data_sizes[(int)dir.tdir_type] * dir.tdir_count; } struct EXIF_tag_info { int tifftag; // TIFF tag used for this info const char *name; // Attribute name we use TIFFDataType tifftype; // Data type that TIFF wants int tiffcount; // Number of items }; static const EXIF_tag_info exif_tag_table[] = { // Skip ones handled by the usual JPEG code { TIFFTAG_IMAGEWIDTH, "Exif:ImageWidth", TIFF_NOTYPE, 1 }, { TIFFTAG_IMAGELENGTH, "Exif:ImageLength", TIFF_NOTYPE, 1 }, { TIFFTAG_BITSPERSAMPLE, "Exif:BitsPerSample", TIFF_NOTYPE, 1 }, { TIFFTAG_COMPRESSION, "Exif:Compression", TIFF_NOTYPE, 1 }, { TIFFTAG_PHOTOMETRIC, "Exif:Photometric", TIFF_NOTYPE, 1 }, { TIFFTAG_SAMPLESPERPIXEL, "Exif:SamplesPerPixel", TIFF_NOTYPE, 1 }, { TIFFTAG_PLANARCONFIG, "Exif:PlanarConfig", TIFF_NOTYPE, 1 }, { TIFFTAG_YCBCRSUBSAMPLING, "Exif:YCbCrSubsampling",TIFF_SHORT, 1 }, { TIFFTAG_YCBCRPOSITIONING, "Exif:YCbCrPositioning",TIFF_SHORT, 1 }, // TIFF tags we may come across { TIFFTAG_ORIENTATION, "Orientation", TIFF_SHORT, 1 }, { TIFFTAG_XRESOLUTION, "XResolution", TIFF_RATIONAL, 1 }, { TIFFTAG_YRESOLUTION, "YResolution", TIFF_RATIONAL, 1 }, { TIFFTAG_RESOLUTIONUNIT, "ResolutionUnit",TIFF_SHORT, 1 }, { TIFFTAG_IMAGEDESCRIPTION, "ImageDescription", TIFF_ASCII, 0 }, { TIFFTAG_MAKE, "Make", TIFF_ASCII, 0 }, { TIFFTAG_MODEL, "Model", TIFF_ASCII, 0 }, { TIFFTAG_SOFTWARE, "Software", TIFF_ASCII, 0 }, { TIFFTAG_ARTIST, "Artist", TIFF_ASCII, 0 }, { TIFFTAG_COPYRIGHT, "Copyright", TIFF_ASCII, 0 }, { TIFFTAG_DATETIME, "DateTime", TIFF_ASCII, 0 }, { TIFFTAG_EXIFIFD, "Exif:ExifIFD", TIFF_NOTYPE, 1 }, { TIFFTAG_INTEROPERABILITYIFD, "Exif:InteroperabilityIFD", TIFF_NOTYPE, 1 }, { TIFFTAG_GPSIFD, "Exif:GPSIFD", TIFF_NOTYPE, 1 }, // EXIF tags we may come across { EXIFTAG_EXPOSURETIME, "ExposureTime", TIFF_RATIONAL, 1 }, { EXIFTAG_FNUMBER, "FNumber", TIFF_RATIONAL, 1 }, { EXIFTAG_EXPOSUREPROGRAM, "Exif:ExposureProgram", TIFF_SHORT, 1 }, // ?? translate to ascii names? { EXIFTAG_SPECTRALSENSITIVITY,"Exif:SpectralSensitivity", TIFF_ASCII, 0 }, { EXIFTAG_ISOSPEEDRATINGS, "Exif:ISOSpeedRatings", TIFF_SHORT, 1 }, { EXIFTAG_OECF, "Exif:OECF", TIFF_NOTYPE, 1 }, // skip it { EXIFTAG_EXIFVERSION, "Exif:ExifVersion", TIFF_NOTYPE, 1 }, // skip it { EXIFTAG_DATETIMEORIGINAL, "Exif:DateTimeOriginal", TIFF_ASCII, 0 }, { EXIFTAG_DATETIMEDIGITIZED,"Exif:DateTimeDigitized", TIFF_ASCII, 0 }, { EXIFTAG_COMPONENTSCONFIGURATION, "Exif:ComponentsConfiguration", TIFF_UNDEFINED, 1 }, { EXIFTAG_COMPRESSEDBITSPERPIXEL, "Exif:CompressedBitsPerPixel", TIFF_RATIONAL, 1 }, { EXIFTAG_SHUTTERSPEEDVALUE,"Exif:ShutterSpeedValue", TIFF_SRATIONAL, 1 }, // APEX units { EXIFTAG_APERTUREVALUE, "Exif:ApertureValue", TIFF_RATIONAL, 1 }, // APEX units { EXIFTAG_BRIGHTNESSVALUE, "Exif:BrightnessValue", TIFF_SRATIONAL, 1 }, { EXIFTAG_EXPOSUREBIASVALUE,"Exif:ExposureBiasValue", TIFF_SRATIONAL, 1 }, { EXIFTAG_MAXAPERTUREVALUE, "Exif:MaxApertureValue",TIFF_RATIONAL, 1 }, { EXIFTAG_SUBJECTDISTANCE, "Exif:SubjectDistance", TIFF_RATIONAL, 1 }, { EXIFTAG_METERINGMODE, "Exif:MeteringMode", TIFF_SHORT, 1 }, { EXIFTAG_LIGHTSOURCE, "Exif:LightSource", TIFF_SHORT, 1 }, { EXIFTAG_FLASH, "Exif:Flash", TIFF_SHORT, 1 }, { EXIFTAG_FOCALLENGTH, "Exif:FocalLength", TIFF_RATIONAL, 1 }, // mm { EXIFTAG_SECURITYCLASSIFICATION, "Exif:SecurityClassification", TIFF_ASCII, 1 }, { EXIFTAG_IMAGEHISTORY, "Exif:ImageHistory", TIFF_ASCII, 1 }, { EXIFTAG_SUBJECTAREA, "Exif:SubjectArea", TIFF_NOTYPE, 1 }, // skip { EXIFTAG_MAKERNOTE, "Exif:MakerNote", TIFF_NOTYPE, 1 }, // skip it { EXIFTAG_USERCOMMENT, "Exif:UserComment", TIFF_NOTYPE, 1 }, // skip it { EXIFTAG_SUBSECTIME, "Exif:SubsecTime", TIFF_ASCII, 0 }, { EXIFTAG_SUBSECTIMEORIGINAL,"Exif:SubsecTimeOriginal", TIFF_ASCII, 0 }, { EXIFTAG_SUBSECTIMEDIGITIZED,"Exif:SubsecTimeDigitized", TIFF_ASCII, 0 }, { EXIFTAG_FLASHPIXVERSION, "Exif:FlashPixVersion", TIFF_NOTYPE, 1 }, // skip "Exif:FlashPixVesion", TIFF_NOTYPE, 1 }, { EXIFTAG_COLORSPACE, "Exif:ColorSpace", TIFF_SHORT, 1 }, { EXIFTAG_PIXELXDIMENSION, "Exif:PixelXDimension", TIFF_LONG, 1 }, { EXIFTAG_PIXELYDIMENSION, "Exif:PixelYDimension", TIFF_LONG, 1 }, { EXIFTAG_RELATEDSOUNDFILE, "Exif:RelatedSoundFile", TIFF_NOTYPE, 1 }, // skip { EXIFTAG_FLASHENERGY, "Exif:FlashEnergy", TIFF_RATIONAL, 1 }, { EXIFTAG_SPATIALFREQUENCYRESPONSE, "Exif:SpatialFrequencyResponse", TIFF_NOTYPE, 1 }, { EXIFTAG_FOCALPLANEXRESOLUTION, "Exif:FocalPlaneXResolution", TIFF_RATIONAL, 1 }, { EXIFTAG_FOCALPLANEYRESOLUTION, "Exif:FocalPlaneYResolution", TIFF_RATIONAL, 1 }, { EXIFTAG_FOCALPLANERESOLUTIONUNIT, "Exif:FocalPlaneResolutionUnit", TIFF_SHORT, 1 }, // Symbolic? { EXIFTAG_SUBJECTLOCATION, "Exif:SubjectLocation", TIFF_SHORT, 1 }, // FIXME: short[2] { EXIFTAG_EXPOSUREINDEX, "Exif:ExposureIndex", TIFF_RATIONAL, 1 }, { EXIFTAG_SENSINGMETHOD, "Exif:SensingMethod", TIFF_SHORT, 1 }, { EXIFTAG_FILESOURCE, "Exif:FileSource", TIFF_SHORT, 1 }, { EXIFTAG_SCENETYPE, "Exif:SceneType", TIFF_SHORT, 1 }, { EXIFTAG_CFAPATTERN, "Exif:CFAPattern", TIFF_NOTYPE, 1 }, { EXIFTAG_CUSTOMRENDERED, "Exif:CustomRendered", TIFF_SHORT, 1 }, { EXIFTAG_EXPOSUREMODE, "Exif:ExposureMode", TIFF_SHORT, 1 }, { EXIFTAG_WHITEBALANCE, "Exif:WhiteBalance", TIFF_SHORT, 1 }, { EXIFTAG_DIGITALZOOMRATIO, "Exif:DigitalZoomRatio",TIFF_RATIONAL, 1 }, { EXIFTAG_FOCALLENGTHIN35MMFILM, "Exif:FocalLengthIn35mmFilm", TIFF_SHORT, 1 }, { EXIFTAG_SCENECAPTURETYPE, "Exif:SceneCaptureType",TIFF_SHORT, 1 }, { EXIFTAG_GAINCONTROL, "Exif:GainControl", TIFF_RATIONAL, 1 }, { EXIFTAG_CONTRAST, "Exif:Contrast", TIFF_SHORT, 1 }, { EXIFTAG_SATURATION, "Exif:Saturation", TIFF_SHORT, 1 }, { EXIFTAG_SHARPNESS, "Exif:Sharpness", TIFF_SHORT, 1 }, { EXIFTAG_DEVICESETTINGDESCRIPTION, "Exif:DeviceSettingDescription", TIFF_NOTYPE, 1 }, { EXIFTAG_SUBJECTDISTANCERANGE, "Exif:SubjectDistanceRange", TIFF_SHORT, 1 }, { EXIFTAG_IMAGEUNIQUEID, "Exif:ImageUniqueID", TIFF_ASCII, 0 }, { 42032, "Exif:CameraOwnerName", TIFF_ASCII, 0 }, { 42033, "Exif:BodySerialNumber", TIFF_ASCII, 0 }, { 42034, "Exif:LensSpecification",TIFF_RATIONAL, 1 }, { 42035, "Exif:LensMake", TIFF_ASCII, 0 }, { 42036, "Exif:LensModel", TIFF_ASCII, 0 }, { 42037, "Exif:LensSerialNumber", TIFF_ASCII, 0 }, { -1, NULL } // signal end of table }; enum GPSTag { GPSTAG_VERSIONID = 0, GPSTAG_LATITUDEREF = 1, GPSTAG_LATITUDE = 2, GPSTAG_LONGITUDEREF = 3, GPSTAG_LONGITUDE = 4, GPSTAG_ALTITUDEREF = 5, GPSTAG_ALTITUDE = 6, GPSTAG_TIMESTAMP = 7, GPSTAG_SATELLITES = 8, GPSTAG_STATUS = 9, GPSTAG_MEASUREMODE = 10, GPSTAG_DOP = 11, GPSTAG_SPEEDREF = 12, GPSTAG_SPEED = 13, GPSTAG_TRACKREF = 14, GPSTAG_TRACK = 15, GPSTAG_IMGDIRECTIONREF = 16, GPSTAG_IMGDIRECTION = 17, GPSTAG_MAPDATUM = 18, GPSTAG_DESTLATITUDEREF = 19, GPSTAG_DESTLATITUDE = 20, GPSTAG_DESTLONGITUDEREF = 21, GPSTAG_DESTLONGITUDE = 22, GPSTAG_DESTBEARINGREF = 23, GPSTAG_DESTBEARING = 24, GPSTAG_DESTDISTANCEREF = 25, GPSTAG_DESTDISTANCE = 26, GPSTAG_PROCESSINGMETHOD = 27, GPSTAG_AREAINFORMATION = 28, GPSTAG_DATESTAMP = 29, GPSTAG_DIFFERENTIAL = 30, GPSTAG_HPOSITIONINGERROR = 31 }; static const EXIF_tag_info gps_tag_table[] = { { GPSTAG_VERSIONID, "GPS:VersionID", TIFF_BYTE, 4 }, { GPSTAG_LATITUDEREF, "GPS:LatitudeRef", TIFF_ASCII, 2 }, { GPSTAG_LATITUDE, "GPS:Latitude", TIFF_RATIONAL, 3 }, { GPSTAG_LONGITUDEREF, "GPS:LongitudeRef", TIFF_ASCII, 2 }, { GPSTAG_LONGITUDE, "GPS:Longitude", TIFF_RATIONAL, 3 }, { GPSTAG_ALTITUDEREF, "GPS:AltitudeRef", TIFF_BYTE, 1 }, { GPSTAG_ALTITUDE, "GPS:Altitude", TIFF_RATIONAL, 1 }, { GPSTAG_TIMESTAMP, "GPS:TimeStamp", TIFF_RATIONAL, 3 }, { GPSTAG_SATELLITES, "GPS:Satellites", TIFF_ASCII, 0 }, { GPSTAG_STATUS, "GPS:Status", TIFF_ASCII, 2 }, { GPSTAG_MEASUREMODE, "GPS:MeasureMode", TIFF_ASCII, 2 }, { GPSTAG_DOP, "GPS:DOP", TIFF_RATIONAL, 1 }, { GPSTAG_SPEEDREF, "GPS:SpeedRef", TIFF_ASCII, 2 }, { GPSTAG_SPEED, "GPS:Speed", TIFF_RATIONAL, 1 }, { GPSTAG_TRACKREF, "GPS:TrackRef", TIFF_ASCII, 2 }, { GPSTAG_TRACK, "GPS:Track", TIFF_RATIONAL, 1 }, { GPSTAG_IMGDIRECTIONREF, "GPS:ImgDirectionRef", TIFF_ASCII, 2 }, { GPSTAG_IMGDIRECTION, "GPS:ImgDirection", TIFF_RATIONAL, 1 }, { GPSTAG_MAPDATUM, "GPS:MapDatum", TIFF_ASCII, 0 }, { GPSTAG_DESTLATITUDEREF, "GPS:DestLatitudeRef", TIFF_ASCII, 2 }, { GPSTAG_DESTLATITUDE, "GPS:DestLatitude", TIFF_RATIONAL, 3 }, { GPSTAG_DESTLONGITUDEREF, "GPS:DestLongitudeRef", TIFF_ASCII, 2 }, { GPSTAG_DESTLONGITUDE, "GPS:DestLongitude", TIFF_RATIONAL, 3 }, { GPSTAG_DESTBEARINGREF, "GPS:DestBearingRef", TIFF_ASCII, 2 }, { GPSTAG_DESTBEARING, "GPS:DestBearing", TIFF_RATIONAL, 1 }, { GPSTAG_DESTDISTANCEREF, "GPS:DestDistanceRef", TIFF_ASCII, 2 }, { GPSTAG_DESTDISTANCE, "GPS:DestDistance", TIFF_RATIONAL, 1 }, { GPSTAG_PROCESSINGMETHOD, "GPS:ProcessingMethod", TIFF_UNDEFINED, 1 }, { GPSTAG_AREAINFORMATION, "GPS:AreaInformation", TIFF_UNDEFINED, 1 }, { GPSTAG_DATESTAMP, "GPS:DateStamp", TIFF_ASCII, 0 }, { GPSTAG_DIFFERENTIAL, "GPS:Differential", TIFF_SHORT, 1 }, { GPSTAG_HPOSITIONINGERROR, "GPS:HPositioningError",TIFF_RATIONAL, 1 }, { -1, NULL } // signal end of table }; class TagMap { typedef std::map tagmap_t; typedef std::map namemap_t; public: TagMap (const EXIF_tag_info *tag_table) { for (int i = 0; tag_table[i].tifftag >= 0; ++i) { const EXIF_tag_info *eti = &tag_table[i]; m_tagmap[eti->tifftag] = eti; if (eti->name) m_namemap[eti->name] = eti; } } const EXIF_tag_info * find (int tag) const { tagmap_t::const_iterator i = m_tagmap.find (tag); return i == m_tagmap.end() ? NULL : i->second; } const char * name (int tag) const { tagmap_t::const_iterator i = m_tagmap.find (tag); return i == m_tagmap.end() ? NULL : i->second->name; } TIFFDataType tifftype (int tag) const { tagmap_t::const_iterator i = m_tagmap.find (tag); return i == m_tagmap.end() ? TIFF_NOTYPE : i->second->tifftype; } int tiffcount (int tag) const { tagmap_t::const_iterator i = m_tagmap.find (tag); return i == m_tagmap.end() ? 0 : i->second->tiffcount; } int tag (const std::string &name) const { namemap_t::const_iterator i = m_namemap.find (name); return i == m_namemap.end() ? -1 : i->second->tifftag; } private: tagmap_t m_tagmap; namemap_t m_namemap; }; static TagMap exif_tagmap (exif_tag_table); static TagMap gps_tagmap (gps_tag_table); #if (DEBUG_EXIF_WRITE || DEBUG_EXIF_READ) static void print_dir_entry (const TagMap &tagmap, const TIFFDirEntry &dir, const char *datastart) { int len = tiff_data_size (dir); const char *mydata = (len <= 4) ? (const char *)&dir.tdir_offset : (datastart + dir.tdir_offset); const char *name = tagmap.name(dir.tdir_tag); std::cerr << "tag=" << dir.tdir_tag << " (" << (name ? name : "unknown") << ")" << ", type=" << dir.tdir_type << ", count=" << dir.tdir_count << ", offset=" << dir.tdir_offset << " = " ; switch (dir.tdir_type) { case TIFF_ASCII : std::cerr << "'" << (char *)mydata << "'"; break; case TIFF_RATIONAL : { const unsigned int *u = (unsigned int *)mydata; for (size_t i = 0; i < dir.tdir_count; ++i) std::cerr << u[2*i] << "/" << u[2*i+1] << " = " << (double)u[2*i]/(double)u[2*i+1] << " "; } break; case TIFF_SRATIONAL : { const int *u = (int *)mydata; for (size_t i = 0; i < dir.tdir_count; ++i) std::cerr << u[2*i] << "/" << u[2*i+1] << " = " << (double)u[2*i]/(double)u[2*i+1] << " "; } break; case TIFF_SHORT : std::cerr << ((unsigned short *)mydata)[0]; break; case TIFF_LONG : std::cerr << ((unsigned int *)mydata)[0]; break; case TIFF_BYTE : case TIFF_UNDEFINED : case TIFF_NOTYPE : default: for (size_t i = 0; i < dir.tdir_count; ++i) std::cerr << (int)((unsigned char *)mydata)[i] << ' '; break; } std::cerr << "\n"; } #endif /// Add one EXIF directory entry's data to spec under the given 'name'. /// The directory entry is in *dirp, buf points to the beginning of the /// TIFF "file", i.e. all TIFF tag offsets are relative to buf. If swab /// is true, the endianness of the file doesn't match the endianness of /// the host CPU, therefore all integer and float data embedded in buf /// needs to be byte-swapped. Note that *dirp HAS already been swapped, /// if necessary, so no byte swapping on *dirp is necessary. static void add_exif_item_to_spec (ImageSpec &spec, const char *name, const TIFFDirEntry *dirp, const char *buf, bool swab) { if (dirp->tdir_type == TIFF_SHORT && dirp->tdir_count == 1) { union { uint32_t i32; uint16_t i16[2]; } convert; convert.i32 = dirp->tdir_offset; unsigned short d = convert.i16[0]; // N.B. The Exif spec says that for a 16 bit value, it's stored in // the *first* 16 bits of the offset area. if (swab) swap_endian (&d); spec.attribute (name, (unsigned int)d); } else if (dirp->tdir_type == TIFF_LONG && dirp->tdir_count == 1) { unsigned int d; d = * (const unsigned int *) &dirp->tdir_offset; // int stored in offset itself if (swab) swap_endian (&d); spec.attribute (name, (unsigned int)d); } else if (dirp->tdir_type == TIFF_RATIONAL) { int n = dirp->tdir_count; // How many float *f = (float *) alloca (n * sizeof(float)); for (int i = 0; i < n; ++i) { unsigned int num, den; num = ((const unsigned int *) &(buf[dirp->tdir_offset]))[2*i+0]; den = ((const unsigned int *) &(buf[dirp->tdir_offset]))[2*i+1]; if (swab) { swap_endian (&num); swap_endian (&den); } f[i] = (float) ((double)num / (double)den); } if (dirp->tdir_count == 1) spec.attribute (name, *f); else spec.attribute (name, TypeDesc(TypeDesc::FLOAT, n), f); } else if (dirp->tdir_type == TIFF_SRATIONAL) { int n = dirp->tdir_count; // How many float *f = (float *) alloca (n * sizeof(float)); for (int i = 0; i < n; ++i) { int num, den; num = ((const int *) &(buf[dirp->tdir_offset]))[2*i+0]; den = ((const int *) &(buf[dirp->tdir_offset]))[2*i+1]; if (swab) { swap_endian (&num); swap_endian (&den); } f[i] = (float) ((double)num / (double)den); } if (dirp->tdir_count == 1) spec.attribute (name, *f); else spec.attribute (name, TypeDesc(TypeDesc::FLOAT, n), f); } else if (dirp->tdir_type == TIFF_ASCII) { int len = tiff_data_size (*dirp); const char *ptr = (len <= 4) ? (const char *)&dirp->tdir_offset : (buf + dirp->tdir_offset); while (len && ptr[len-1] == 0) // Don't grab the terminating null --len; std::string str (ptr, len); if (strlen(str.c_str()) < str.length()) // Stray \0 in the middle str = std::string (str.c_str()); spec.attribute (name, str); } else if (dirp->tdir_type == TIFF_BYTE && dirp->tdir_count == 1) { // Not sure how to handle "bytes" generally, but certainly for just // one, add it as an int. unsigned char d; d = * (const unsigned char *) &dirp->tdir_offset; // byte stored in offset itself spec.attribute (name, (int)d); } else if (dirp->tdir_type == TIFF_UNDEFINED || dirp->tdir_type == TIFF_BYTE) { // Add it as bytes #if 0 const void *addr = dirp->tdir_count <= 4 ? (const void *) &dirp->tdir_offset : (const void *) &buf[dirp->tdir_offset]; spec.attribute (name, TypeDesc::UINT8, dirp->tdir_count, addr); #endif } else { #ifndef NDEBUG std::cerr << "didn't know how to process " << name << ", type " << dirp->tdir_type << " x " << dirp->tdir_count << "\n"; #endif } } /// Process a single TIFF directory entry embedded in the JPEG 'APP1' /// data. The directory entry is in *dirp, buf points to the beginning /// of the TIFF "file", i.e. all TIFF tag offsets are relative to buf. /// The goal is to decode the tag and put the data into appropriate /// attribute slots of spec. If swab is true, the endianness of the /// file doesn't match the endianness of the host CPU, therefore all /// integer and float data embedded in buf needs to be byte-swapped. /// Note that *dirp has not been swapped, and so is still in the native /// endianness of the file. static void read_exif_tag (ImageSpec &spec, const TIFFDirEntry *dirp, const char *buf, bool swab, std::set &ifd_offsets_seen, const TagMap &tagmap) { // Make a copy of the pointed-to TIFF directory, swab the components // if necessary. TIFFDirEntry dir = *dirp; if (swab) { swap_endian (&dir.tdir_tag); swap_endian (&dir.tdir_type); swap_endian (&dir.tdir_count); // only swab true offsets, not data embedded in the offset field if (tiff_data_size (dir) > 4) swap_endian (&dir.tdir_offset); } #if DEBUG_EXIF_READ std::cerr << "Read "; print_dir_entry (tagmap, dir, buf); #endif if (dir.tdir_tag == TIFFTAG_EXIFIFD || dir.tdir_tag == TIFFTAG_GPSIFD) { // Special case: It's a pointer to a private EXIF directory. // Handle the whole thing recursively. unsigned int offset = dirp->tdir_offset; // int stored in offset itself if (swab) swap_endian (&offset); // Don't recurse if we've already visited this IFD if (ifd_offsets_seen.find (offset) != ifd_offsets_seen.end()) { #if DEBUG_EXIF_READ std::cerr << "Early ifd exit\n"; #endif return; } ifd_offsets_seen.insert (offset); #if DEBUG_EXIF_READ std::cerr << "Now we've seen offset " << offset << "\n"; #endif const unsigned char *ifd = ((const unsigned char *)buf + offset); unsigned short ndirs = *(const unsigned short *)ifd; if (swab) swap_endian (&ndirs); #if DEBUG_EXIF_READ std::cerr << "exifid has type " << dir.tdir_type << ", offset " << dir.tdir_offset << "\n"; std::cerr << "EXIF Number of directory entries = " << ndirs << "\n"; #endif for (int d = 0; d < ndirs; ++d) read_exif_tag (spec, (const TIFFDirEntry *)(ifd+2+d*sizeof(TIFFDirEntry)), (const char *)buf, swab, ifd_offsets_seen, dir.tdir_tag == TIFFTAG_EXIFIFD ? exif_tagmap : gps_tagmap); #if DEBUG_EXIF_READ std::cerr << "> End EXIF\n"; #endif } else if (dir.tdir_tag == TIFFTAG_INTEROPERABILITYIFD) { // Special case: It's a pointer to a private EXIF directory. // Handle the whole thing recursively. unsigned int offset = dirp->tdir_offset; // int stored in offset itself if (swab) swap_endian (&offset); // Don't recurse if we've already visited this IFD if (ifd_offsets_seen.find (offset) != ifd_offsets_seen.end()) return; ifd_offsets_seen.insert (offset); #if DEBUG_EXIF_READ std::cerr << "Now we've seen offset " << offset << "\n"; #endif const unsigned char *ifd = ((const unsigned char *)buf + offset); unsigned short ndirs = *(const unsigned short *)ifd; if (swab) swap_endian (&ndirs); #if DEBUG_EXIF_READ std::cerr << "\n\nInteroperability has type " << dir.tdir_type << ", offset " << dir.tdir_offset << "\n"; std::cerr << "Interoperability Number of directory entries = " << ndirs << "\n"; #endif for (int d = 0; d < ndirs; ++d) read_exif_tag (spec, (const TIFFDirEntry *)(ifd+2+d*sizeof(TIFFDirEntry)), (const char *)buf, swab, ifd_offsets_seen, exif_tagmap); #if DEBUG_EXIF_READ std::cerr << "> End Interoperability\n\n"; #endif } else { // Everything else -- use our table to handle the general case const char *name = tagmap.name (dir.tdir_tag); if (name) { add_exif_item_to_spec (spec, name, &dir, buf, swab); } else { #if DEBUG_EXIF_READ std::cerr << "Dir : tag=" << dir.tdir_tag << ", type=" << dir.tdir_type << ", count=" << dir.tdir_count << ", offset=" << dir.tdir_offset << "\n"; #endif } } } class tagcompare { public: int operator() (const TIFFDirEntry &a, const TIFFDirEntry &b) { return (a.tdir_tag < b.tdir_tag); } }; static void append_dir_entry (const TagMap &tagmap, std::vector &dirs, std::vector &data, int tag, TIFFDataType type, size_t count, const void *mydata) { TIFFDirEntry dir; dir.tdir_tag = tag; dir.tdir_type = type; dir.tdir_count = count; int len = tiff_data_sizes[(int)type] * count; if (len <= 4) { dir.tdir_offset = 0; memcpy (&dir.tdir_offset, mydata, len); } else { dir.tdir_offset = data.size(); data.insert (data.end(), (char *)mydata, (char *)mydata + len); } #if DEBUG_EXIF_WRITE std::cerr << "Adding "; print_dir_entry (tagmap, dir, (const char *)mydata); #endif // Don't double-add BOOST_FOREACH (TIFFDirEntry &d, dirs) { if (d.tdir_tag == tag) { d = dir; return; } } dirs.push_back (dir); } /// Convert to the desired integer type and then append_dir_entry it. /// template bool append_dir_entry_integer (const ImageIOParameter &p, const TagMap &tagmap, std::vector &dirs, std::vector &data, int tag, TIFFDataType type) { T i; switch (p.type().basetype) { case TypeDesc::UINT: i = (T) *(unsigned int *)p.data(); break; case TypeDesc::INT: i = (T) *(int *)p.data(); break; case TypeDesc::UINT16: i = (T) *(unsigned short *)p.data(); break; case TypeDesc::INT16: i = (T) *(short *)p.data(); break; default: return false; } append_dir_entry (tagmap, dirs, data, tag, type, 1, &i); return true; } /// Helper: For param that needs to be added as a tag, create a TIFF /// directory entry for it in dirs and add its data in data. Set the /// directory's offset just to the position within data where it will /// reside. Don't worry about it being relative to the start of some /// TIFF structure. static void encode_exif_entry (const ImageIOParameter &p, int tag, std::vector &dirs, std::vector &data, const TagMap &tagmap) { TIFFDataType type = tagmap.tifftype (tag); size_t count = (size_t) tagmap.tiffcount (tag); TypeDesc element = p.type().elementtype(); switch (type) { case TIFF_ASCII : if (p.type() == TypeDesc::STRING) { const char *s = *(const char **) p.data(); int len = strlen(s) + 1; append_dir_entry (tagmap, dirs, data, tag, type, len, s); return; } break; case TIFF_RATIONAL : if (element == TypeDesc::FLOAT) { unsigned int *rat = (unsigned int *) alloca (2*count*sizeof(unsigned int)); const float *f = (const float *)p.data(); for (size_t i = 0; i < count; ++i) float_to_rational (f[i], rat[2*i], rat[2*i+1]); append_dir_entry (tagmap, dirs, data, tag, type, count, rat); return; } break; case TIFF_SRATIONAL : if (element == TypeDesc::FLOAT) { int *rat = (int *) alloca (2*count*sizeof(int)); const float *f = (const float *)p.data(); for (size_t i = 0; i < count; ++i) float_to_rational (f[i], rat[2*i], rat[2*i+1]); append_dir_entry (tagmap, dirs, data, tag, type, count, rat); return; } break; case TIFF_SHORT : if (append_dir_entry_integer (p, tagmap, dirs, data, tag, type)) return; break; case TIFF_LONG : if (append_dir_entry_integer (p, tagmap, dirs, data, tag, type)) return; break; case TIFF_BYTE : if (append_dir_entry_integer (p, tagmap, dirs, data, tag, type)) return; break; default: break; } #if DEBUG_EXIF_WRITE std::cerr << " Don't know how to add " << p.name() << ", tag " << tag << ", type " << type << ' ' << p.type().c_str() << "\n"; #endif } /// Given a list of directory entries, add 'offset' to their tdir_offset /// fields (unless, of course, they are less than 4 bytes of data and are /// therefore stored locally rather than having an offset at all). static void reoffset (std::vector &dirs, const TagMap &tagmap, size_t offset) { BOOST_FOREACH (TIFFDirEntry &dir, dirs) { if (tiff_data_size (dir) <= 4 && dir.tdir_tag != TIFFTAG_EXIFIFD && dir.tdir_tag != TIFFTAG_GPSIFD) { #if DEBUG_EXIF_WRITE const char *name = tagmap.name (dir.tdir_tag); std::cerr << " NO re-offset of exif entry " << " tag " << dir.tdir_tag << " " << (name ? name : "") << " to " << dir.tdir_offset << '\n'; #endif continue; } dir.tdir_offset += offset; #if DEBUG_EXIF_WRITE const char *name = tagmap.name (dir.tdir_tag); std::cerr << " re-offsetting entry " << " tag " << dir.tdir_tag << " " << (name ? name : "") << " to " << dir.tdir_offset << '\n'; #endif } } } // anon namespace // Decode a raw Exif data block and save all the metadata in an // ImageSpec. Return true if all is ok, false if the exif block was // somehow malformed. bool decode_exif (const void *exif, int length, ImageSpec &spec) { const unsigned char *buf = (const unsigned char *) exif; #if DEBUG_EXIF_READ std::cerr << "Exif dump:\n"; for (int i = 0; i < length; ++i) { if (buf[i] >= ' ') std::cerr << (char)buf[i] << ' '; std::cerr << "(" << (int)(unsigned char)buf[i] << ") "; } std::cerr << "\n"; #endif // The first item should be a standard TIFF header. Note that HERE, // not the start of the Exif blob, is where all TIFF offsets are // relative to. The header should have the right magic number (which // also tells us the endianness of the data) and an offset to the // first TIFF directory. // // N.B. Just read libtiff's "tiff.h" for info on the structure // layout of TIFF headers and directory entries. The TIFF spec // itself is also helpful in this area. TIFFHeader head = *(const TIFFHeader *)buf; if (head.tiff_magic != 0x4949 && head.tiff_magic != 0x4d4d) return false; bool host_little = littleendian(); bool file_little = (head.tiff_magic == 0x4949); bool swab = (host_little != file_little); if (swab) swap_endian (&head.tiff_diroff); // keep track of IFD offsets we've already seen to avoid infinite // recursion if there are circular references. std::set ifd_offsets_seen; // Read the directory that the header pointed to. It should contain // some number of directory entries containing tags to process. const unsigned char *ifd = (buf + head.tiff_diroff); unsigned short ndirs = *(const unsigned short *)ifd; if (swab) swap_endian (&ndirs); for (int d = 0; d < ndirs; ++d) read_exif_tag (spec, (const TIFFDirEntry *) (ifd+2+d*sizeof(TIFFDirEntry)), (const char *)buf, swab, ifd_offsets_seen, exif_tagmap); // A few tidbits to look for ImageIOParameter *p; if ((p = spec.find_attribute ("Exif:ColorSpace")) || (p = spec.find_attribute ("ColorSpace"))) { int cs = -1; if (p->type() == TypeDesc::UINT) cs = *(const unsigned int *)p->data(); else if (p->type() == TypeDesc::INT) cs = *(const int *)p->data(); else if (p->type() == TypeDesc::UINT16) cs = *(const unsigned short *)p->data(); else if (p->type() == TypeDesc::INT16) cs = *(const short *)p->data(); // Exif spec says that anything other than 0xffff==uncalibrated // should be interpreted to be sRGB. if (cs != 0xffff) spec.attribute ("oiio:ColorSpace", "sRGB"); } return true; } // Construct an Exif data block from the ImageSpec, appending the Exif // data as a big blob to the char vector. void encode_exif (const ImageSpec &spec, std::vector &blob) { // Reserve maximum space that an APP1 can take in a JPEG file, so // we can push_back to our heart's content and know that no offsets // or pointers to the exif vector's memory will change due to // reallocation. blob.reserve (0xffff); // Layout: // (tiffstart) TIFFHeader // number of top dir entries // top dir entry 0 // ... // top dir entry (point to Exif IFD) // data for top dir entries (except Exif) // // Exif IFD number of dir entries (n) // Exif IFD entry 0 // ... // Exif IFD entry n-1 // ...More Data for Exif entries... // Here is where the TIFF info starts. All TIFF tag offsets are // relative to this position within the blob. int tiffstart = blob.size(); // Handy macro -- grow the blob to accommodate a new variable, which // we position at its end. #define BLOB_ADD(vartype, varname) \ blob.resize (blob.size() + sizeof(vartype)); \ vartype & varname (* (vartype *) (&blob[0] + blob.size() - sizeof(vartype))); // Put a TIFF header BLOB_ADD (TIFFHeader, head); bool host_little = littleendian(); head.tiff_magic = host_little ? 0x4949 : 0x4d4d; head.tiff_version = 42; head.tiff_diroff = blob.size() - tiffstart; // Placeholder for number of directories BLOB_ADD (unsigned short, ndirs); ndirs = 0; // Accumulate separate tag directories for TIFF, Exif, GPS, and Interop. std::vector tiffdirs, exifdirs, gpsdirs, interopdirs; std::vector data; // Put data here int endmarker = 0; // 4 bytes of 0's that marks the end of a directory // Go through all spec attribs, add them to the appropriate tag // directory (tiff, gps, or exif). BOOST_FOREACH (const ImageIOParameter &p, spec.extra_attribs) { // Which tag domain are we using? if (! strncmp (p.name().c_str(), "GPS:", 4)) { // GPS int tag = gps_tagmap.tag (p.name().string()); encode_exif_entry (p, tag, gpsdirs, data, gps_tagmap); } else { // Not GPS int tag = exif_tagmap.tag (p.name().string()); if (tag < EXIFTAG_EXPOSURETIME || tag > EXIFTAG_IMAGEUNIQUEID) { encode_exif_entry (p, tag, tiffdirs, data, exif_tagmap); } else { encode_exif_entry (p, tag, exifdirs, data, exif_tagmap); } } } #if DEBUG_EXIF_WRITE std::cerr << "Blob header size " << blob.size() << "\n"; std::cerr << "tiff tags: " << tiffdirs.size() << "\n"; std::cerr << "exif tags: " << exifdirs.size() << "\n"; std::cerr << "gps tags: " << gpsdirs.size() << "\n"; #endif // If any legit Exif info was found... if (exifdirs.size()) { // Add some required Exif tags that wouldn't be in the spec append_dir_entry (exif_tagmap, exifdirs, data, EXIFTAG_EXIFVERSION, TIFF_UNDEFINED, 4, "0220"); append_dir_entry (exif_tagmap, exifdirs, data, EXIFTAG_FLASHPIXVERSION, TIFF_UNDEFINED, 4, "0100"); char componentsconfig[] = { 1, 2, 3, 0 }; append_dir_entry (exif_tagmap, exifdirs, data, EXIFTAG_COMPONENTSCONFIGURATION, TIFF_UNDEFINED, 4, componentsconfig); // Sort the exif tag directory std::sort (exifdirs.begin(), exifdirs.end(), tagcompare()); // If we had exif info, add one more main dir entry to point to // the private exif tag directory. unsigned int size = (unsigned int) data.size(); append_dir_entry (exif_tagmap, tiffdirs, data, TIFFTAG_EXIFIFD, TIFF_LONG, 1, &size); // Create interop directory boilerplate. // In all honesty, I have no idea what this is all about. append_dir_entry (exif_tagmap, interopdirs, data, 1, TIFF_ASCII, 4, "R98"); append_dir_entry (exif_tagmap, interopdirs, data, 2, TIFF_UNDEFINED, 4, "0100"); std::sort (interopdirs.begin(), interopdirs.end(), tagcompare()); #if 0 // FIXME -- is this necessary? If so, it's not completed. // Add the interop directory IFD entry to the main IFD size = (unsigned int) data.size(); append_dir_entry (exif_tagmap, tiffdirs, data, TIFFTAG_INTEROPERABILITYIFD, TIFF_LONG, 1, &size); std::sort (tiffdirs.begin(), tiffdirs.end(), tagcompare()); #endif } // If any GPS info was found... if (gpsdirs.size()) { // Add some required Exif tags that wouldn't be in the spec static char ver[] = { 2, 2, 0, 0 }; append_dir_entry (gps_tagmap, gpsdirs, data, GPSTAG_VERSIONID, TIFF_BYTE, 4, &ver); // Sort the gps tag directory std::sort (gpsdirs.begin(), gpsdirs.end(), tagcompare()); // If we had gps info, add one more main dir entry to point to // the private gps tag directory. unsigned int size = (unsigned int) data.size(); if (exifdirs.size()) size += sizeof(unsigned short) + exifdirs.size()*sizeof(TIFFDirEntry) + 4; append_dir_entry (exif_tagmap, tiffdirs, data, TIFFTAG_GPSIFD, TIFF_LONG, 1, &size); } // Where will the data begin (we need this to adjust the directory // offsets once we append data to the exif blob)? size_t datastart = blob.size() - tiffstart + tiffdirs.size() * sizeof(TIFFDirEntry) + 4 /* end marker */; // Adjust the TIFF offsets, add the TIFF directory entries to the main // Exif block, followed by 4 bytes of 0's. reoffset (tiffdirs, exif_tagmap, datastart); ndirs = tiffdirs.size(); if (ndirs) blob.insert (blob.end(), (char *)&tiffdirs[0], (char *)(&tiffdirs[0] + tiffdirs.size())); blob.insert (blob.end(), (char *)&endmarker, (char *)&endmarker + sizeof(int)); // If legit Exif metadata was found, adjust the Exif directory offsets, // append the Exif tag directory entries onto the main data block, // followed by 4 bytes of 0's. if (exifdirs.size()) { reoffset (exifdirs, exif_tagmap, datastart); unsigned short nd = exifdirs.size(); data.insert (data.end(), (char *)&nd, (char *)&nd + sizeof(nd)); data.insert (data.end(), (char *)&exifdirs[0], (char *)(&exifdirs[0] + exifdirs.size())); data.insert (data.end(), (char *)&endmarker, (char *)&endmarker + sizeof(int)); } // If legit GPS metadata was found, adjust the GPS directory offsets, // append the GPS tag directory entries onto the main data block, // followed by 4 bytes of 0's. if (gpsdirs.size()) { reoffset (gpsdirs, gps_tagmap, datastart); unsigned short nd = gpsdirs.size(); data.insert (data.end(), (char *)&nd, (char *)&nd + sizeof(nd)); data.insert (data.end(), (char *)&gpsdirs[0], (char *)(&gpsdirs[0] + gpsdirs.size())); data.insert (data.end(), (char *)&endmarker, (char *)&endmarker + sizeof(int)); } // Now append the data block onto the end of the main exif block that // we're returning to the caller. blob.insert (blob.end(), data.begin(), data.end()); #if DEBUG_EXIF_WRITE std::cerr << "resulting exif block is a total of " << blob.size() << "\n"; #if 0 std::cerr << "APP1 dump:\n"; BOOST_FOREACH (char c, blob) { if (c >= ' ') std::cerr << c << ' '; std::cerr << "(" << (int)c << ") "; } #endif #endif } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/formatspec.cpp0000644000175000017500000010330112271062644022540 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "strutil.h" #include "fmath.h" #include "imageio.h" #include OIIO_NAMESPACE_ENTER { // Generate the default quantization parameters, templated on the data // type. template static void set_default_quantize (int &quant_black, int &quant_white, int &quant_min, int &quant_max) { if (std::numeric_limits ::is_integer) { quant_black = 0; quant_white = (int) std::numeric_limits ::max(); quant_min = (int) std::numeric_limits ::min(); quant_max = (int) std::numeric_limits ::max(); } else { quant_black = 0; quant_white = 0; quant_min = 0; quant_max = 0; } } // Given the format, set the default quantization parameters. // Rely on the template version to make life easy. static void set_default_quantize (TypeDesc format, int &quant_black, int &quant_white, int &quant_min, int &quant_max) { switch (format.basetype) { case TypeDesc::INT8: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::UNKNOWN: case TypeDesc::UINT8: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::INT16: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::UINT16: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::INT: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::UINT: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::INT64: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::UINT64: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::HALF: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::FLOAT: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; case TypeDesc::DOUBLE: set_default_quantize (quant_black, quant_white, quant_min, quant_max); break; default: ASSERT(0); } } ImageSpec::ImageSpec (TypeDesc format) : x(0), y(0), z(0), width(0), height(0), depth(1), full_x(0), full_y(0), full_z(0), full_width(0), full_height(0), full_depth(0), tile_width(0), tile_height(0), tile_depth(1), nchannels(0), format(format), alpha_channel(-1), z_channel(-1), deep(false) { set_format (format); } ImageSpec::ImageSpec (int xres, int yres, int nchans, TypeDesc format) : x(0), y(0), z(0), width(xres), height(yres), depth(1), full_x(0), full_y(0), full_z(0), full_width(xres), full_height(yres), full_depth(1), tile_width(0), tile_height(0), tile_depth(1), nchannels(nchans), format(format), alpha_channel(-1), z_channel(-1), deep(false) { set_format (format); default_channel_names (); } void ImageSpec::set_format (TypeDesc fmt) { format = fmt; set_default_quantize (fmt, quant_black, quant_white, quant_min, quant_max); } TypeDesc ImageSpec::format_from_quantize (int quant_black, int quant_white, int quant_min, int quant_max) { if (quant_black == 0 && quant_white == 0 && quant_min == 0 && quant_max == 0) { // Per RenderMan and Gelato heuristics, if all quantization // values are zero, assume they want a float output. return TypeDesc::FLOAT; } else if (quant_min >= std::numeric_limits ::min() && quant_max <= std::numeric_limits ::max()) { return TypeDesc::UINT8; } else if (quant_min >= std::numeric_limits ::min() && quant_max <= std::numeric_limits ::max()) { return TypeDesc::INT8; } else if (quant_min >= std::numeric_limits ::min() && quant_max <= std::numeric_limits ::max()) { return TypeDesc::UINT16; } else if (quant_min >= std::numeric_limits ::min() && quant_max <= std::numeric_limits ::max()) { return TypeDesc::INT16; } else if (quant_min >= std::numeric_limits ::min() && quant_max <= std::numeric_limits ::max()) { return TypeDesc::INT; } else if (quant_min >= 0 && (unsigned int) quant_min >= std::numeric_limits ::min() && quant_max >= 0 && (unsigned int) quant_max <= std::numeric_limits ::max()) { return TypeDesc::UINT; } else { return TypeDesc::UNKNOWN; } } void ImageSpec::default_channel_names () { channelnames.clear(); alpha_channel = -1; z_channel = -1; switch (nchannels) { case 1: channelnames.push_back ("A"); break; case 2: channelnames.push_back ("I"); channelnames.push_back ("A"); alpha_channel = 1; break; case 3: channelnames.push_back ("R"); channelnames.push_back ("G"); channelnames.push_back ("B"); break; default: if (nchannels >= 1) channelnames.push_back ("R"); if (nchannels >= 2) channelnames.push_back ("G"); if (nchannels >= 3) channelnames.push_back ("B"); if (nchannels >= 4) { channelnames.push_back ("A"); alpha_channel = 3; } for (int c = 4; c < nchannels; ++c) channelnames.push_back (Strutil::format("channel%d", c)); break; } } size_t ImageSpec::channel_bytes (int chan, bool native) const { if (chan >= nchannels) return 0; if (!native || channelformats.empty()) return format.size(); else return channelformats[chan].size(); } size_t ImageSpec::pixel_bytes (bool native) const { if (nchannels < 0) return 0; if (!native || channelformats.empty()) return clamped_mult32 ((size_t)nchannels, channel_bytes()); else { size_t sum = 0; for (int i = 0; i < nchannels; ++i) sum += channelformats[i].size(); return sum; } } size_t ImageSpec::pixel_bytes (int chbegin, int chend, bool native) const { if (chbegin < 0) return 0; chend = std::max (chend, chbegin); if (!native || channelformats.empty()) return clamped_mult32 ((size_t)(chend-chbegin), channel_bytes()); else { size_t sum = 0; for (int i = chbegin; i < chend; ++i) sum += channelformats[i].size(); return sum; } } imagesize_t ImageSpec::scanline_bytes (bool native) const { if (width < 0) return 0; return clamped_mult64 ((imagesize_t)width, (imagesize_t)pixel_bytes(native)); } imagesize_t ImageSpec::tile_pixels () const { if (tile_width <= 0 || tile_height <= 0 || tile_depth <= 0) return 0; imagesize_t r = clamped_mult64 ((imagesize_t)tile_width, (imagesize_t)tile_height); if (tile_depth > 1) r = clamped_mult64 (r, (imagesize_t)tile_depth); return r; } imagesize_t ImageSpec::tile_bytes (bool native) const { return clamped_mult64 (tile_pixels(), (imagesize_t)pixel_bytes(native)); } imagesize_t ImageSpec::image_pixels () const { if (width < 0 || height < 0 || depth < 0) return 0; imagesize_t r = clamped_mult64 ((imagesize_t)width, (imagesize_t)height); if (depth > 1) r = clamped_mult64 (r, (imagesize_t)depth); return r; } imagesize_t ImageSpec::image_bytes (bool native) const { return clamped_mult64 (image_pixels(), (imagesize_t)pixel_bytes(native)); } void ImageSpec::attribute (const std::string &name, TypeDesc type, const void *value) { // Don't allow duplicates ImageIOParameter *f = find_attribute (name); if (! f) { extra_attribs.resize (extra_attribs.size() + 1); f = &extra_attribs.back(); } f->init (name, type, 1, value); } template static void parse_elements (const std::string &name, TypeDesc type, const std::string &type_code, const std::string &elements, int num_elements, ImageIOParameter ¶m) { void *data = new T[num_elements]; char *data_ptr = (char *) data; size_t element_size = type.elementtype().elementsize (); boost::char_separator sep (", "); boost::tokenizer > tokens (elements, sep); BOOST_FOREACH (std::string element, tokens) { sscanf (element.c_str (), type_code.c_str (), (T *)data_ptr); data_ptr += element_size; } param.init (name, type, num_elements/type.numelements (), data, true); delete [] (T *) data; } void ImageSpec::attribute (const std::string &name, TypeDesc type, const std::string &value) { ImageIOParameter param; size_t num_elements = std::count (value.begin (), value.end (), ',') + 1; TypeDesc elem_type = type.elementtype(); if (elem_type == TypeDesc::INT || elem_type == TypeDesc::INT16) { parse_elements (name, type, "%d", value, num_elements, param); } else if (elem_type == TypeDesc::UINT || elem_type == TypeDesc::UINT16) { parse_elements (name, type, "%d", value, num_elements, param); } else if (elem_type == TypeDesc::FLOAT) { parse_elements (name, type, "%g", value, num_elements, param); } else if (elem_type == TypeDesc::DOUBLE) { parse_elements (name, type, "%g", value, num_elements, param); } else if (elem_type == TypeDesc::INT64) { parse_elements (name, type, "%lld", value, num_elements, param); } else if (elem_type == TypeDesc::UINT64) { parse_elements (name, type, "%llu", value, num_elements, param); } else if (elem_type == TypeDesc::TypeMatrix) { ImageIOParameter tmp_param; num_elements = std::count (value.begin (), value.end (), ' ') + 1; TypeDesc tmp_type = TypeDesc (TypeDesc::FLOAT, 16); parse_elements (name, tmp_type, "%g", value, num_elements, tmp_param); param.init (name, TypeDesc::TypeMatrix, num_elements/16, tmp_param.data()); } else if (elem_type == TypeDesc::STRING) { // Remove quotation marks. std::string tmp_value = value.substr (1, value.length () - 2); const char *value_data = tmp_value.data (); param.init (name, TypeDesc::TypeString, 1, &value_data); } // Don't allow duplicates ImageIOParameter *f = find_attribute (name); if (f) { *f = param; } else { extra_attribs.push_back (param); } } namespace { ImageIOParameterList::iterator get_attribute_iterator (ImageIOParameterList & attribs, const std::string &name, TypeDesc searchtype, bool casesensitive) { if (casesensitive) { for(ImageIOParameterList::iterator iter = attribs.begin(); iter != attribs.end(); ++iter) { if (iter->name() == name && (searchtype == TypeDesc::UNKNOWN || searchtype == iter->type())) return iter; } } else { for(ImageIOParameterList::iterator iter = attribs.begin(); iter != attribs.end(); ++iter) { if (Strutil::iequals (iter->name().string(), name) && (searchtype == TypeDesc::UNKNOWN || searchtype == iter->type())) return iter; } } return attribs.end(); } ImageIOParameterList::const_iterator get_attribute_const_iterator (const ImageIOParameterList & attribs, const std::string &name, TypeDesc searchtype, bool casesensitive) { if (casesensitive) { for(ImageIOParameterList::const_iterator iter = attribs.begin(); iter != attribs.end(); ++iter) { if (iter->name() == name && (searchtype == TypeDesc::UNKNOWN || searchtype == iter->type())) return iter; } } else { for(ImageIOParameterList::const_iterator iter = attribs.begin(); iter != attribs.end(); ++iter) { if (Strutil::iequals (iter->name().string(), name) && (searchtype == TypeDesc::UNKNOWN || searchtype == iter->type())) return iter; } } return attribs.end(); } } void ImageSpec::erase_attribute (const std::string &name, TypeDesc searchtype, bool casesensitive) { ImageIOParameterList::iterator iter = get_attribute_iterator (extra_attribs, name, searchtype, casesensitive); if(iter != extra_attribs.end()) { extra_attribs.erase (iter); } } ImageIOParameter * ImageSpec::find_attribute (const std::string &name, TypeDesc searchtype, bool casesensitive) { ImageIOParameterList::iterator iter = get_attribute_iterator (extra_attribs, name, searchtype, casesensitive); if(iter != extra_attribs.end ()) { return &(*iter); } return NULL; } const ImageIOParameter * ImageSpec::find_attribute (const std::string &name, TypeDesc searchtype, bool casesensitive) const { ImageIOParameterList::const_iterator iter = \ get_attribute_const_iterator (extra_attribs, name, searchtype, casesensitive); if(iter != extra_attribs.end()) { return &(*iter); } return NULL; } int ImageSpec::get_int_attribute (const std::string &name, int val) const { const ImageIOParameter *p = find_attribute (name); if (p) { if (p->type() == TypeDesc::INT) val = *(const int *)p->data(); else if (p->type() == TypeDesc::UINT) val = (int) *(const unsigned int *)p->data(); else if (p->type() == TypeDesc::INT16) val = *(const short *)p->data(); else if (p->type() == TypeDesc::UINT16) val = *(const unsigned short *)p->data(); else if (p->type() == TypeDesc::INT8) val = *(const char *)p->data(); else if (p->type() == TypeDesc::UINT8) val = *(const unsigned char *)p->data(); else if (p->type() == TypeDesc::INT64) val = *(const long long *)p->data(); else if (p->type() == TypeDesc::UINT64) val = *(const unsigned long long *)p->data(); } return val; } float ImageSpec::get_float_attribute (const std::string &name, float val) const { const ImageIOParameter *p = find_attribute (name); if (p) { if (p->type() == TypeDesc::FLOAT) val = *(const float *)p->data(); else if (p->type() == TypeDesc::HALF) val = *(const half *)p->data(); else if (p->type() == TypeDesc::DOUBLE) val = (float) *(const double *)p->data(); } return val; } std::string ImageSpec::get_string_attribute (const std::string &name, const std::string &val) const { const ImageIOParameter *p = find_attribute (name, TypeDesc::STRING); if (p) return std::string (*(const char **)p->data()); else return val; } namespace { // make an anon namespace static std::string format_raw_metadata (const ImageIOParameter &p, int maxsize=16) { std::string out; TypeDesc element = p.type().elementtype(); int nfull = p.type().numelements() * p.nvalues(); int n = std::min (nfull, maxsize); if (element == TypeDesc::STRING) { for (int i = 0; i < n; ++i) { const char *s = ((const char **)p.data())[i]; out += Strutil::format ("%s\"%s\"", (i ? ", " : ""), s ? s : ""); } } else if (element.basetype == TypeDesc::FLOAT) { const float *f = (const float *)p.data(); for (int i = 0; i < n; ++i) { if (i) out += ", "; for (int c = 0; c < (int)element.aggregate; ++c, ++f) out += Strutil::format ("%s%g", (c ? " " : ""), f[0]); } } else if (element.basetype == TypeDesc::DOUBLE) { const double *f = (const double *)p.data(); for (int i = 0; i < n; ++i) { if (i) out += ", "; for (int c = 0; c < (int)element.aggregate; ++c, ++f) out += Strutil::format ("%s%g", (c ? " " : ""), f[0]); } } else if (element.basetype == TypeDesc::HALF) { const half *f = (const half *)p.data(); for (int i = 0; i < n; ++i) { if (i) out += ", "; for (int c = 0; c < (int)element.aggregate; ++c, ++f) out += Strutil::format ("%s%g", (c ? " " : ""), (float)f[0]); } } else if (element == TypeDesc::INT) { for (int i = 0; i < n; ++i) out += Strutil::format ("%s%d", (i ? ", " : ""), ((const int *)p.data())[i]); } else if (element == TypeDesc::UINT) { for (int i = 0; i < n; ++i) out += Strutil::format ("%s%d", (i ? ", " : ""), ((const unsigned int *)p.data())[i]); } else if (element == TypeDesc::UINT16) { for (int i = 0; i < n; ++i) out += Strutil::format ("%s%u", (i ? ", " : ""), ((const unsigned short *)p.data())[i]); } else if (element == TypeDesc::INT16) { for (int i = 0; i < n; ++i) out += Strutil::format ("%s%d", (i ? ", " : ""), ((const short *)p.data())[i]); } else if (element == TypeDesc::UINT64) { for (int i = 0; i < n; ++i) out += Strutil::format ("%s%llu", (i ? ", " : ""), ((const unsigned long long *)p.data())[i]); } else if (element == TypeDesc::INT64) { for (int i = 0; i < n; ++i) out += Strutil::format ("%s%lld", (i ? ", " : ""), ((const long long *)p.data())[i]); } else if (element == TypeDesc::UINT8) { for (int i = 0; i < n; ++i) out += Strutil::format ("%s%d", (i ? ", " : ""), int(((const unsigned char *)p.data())[i])); } else if (element == TypeDesc::INT8) { for (int i = 0; i < n; ++i) out += Strutil::format ("%s%d", (i ? ", " : ""), int(((const char *)p.data())[i])); } else { out += Strutil::format (" (base %d, agg %d vec %d)", p.type().basetype, p.type().aggregate, p.type().vecsemantics); } if (n < nfull) out += ", ..."; return out; } struct LabelTable { int value; const char *label; }; static std::string explain_justprint (const ImageIOParameter &p, const void *extradata) { return format_raw_metadata(p) + " " + std::string ((const char *)extradata); } static std::string explain_labeltable (const ImageIOParameter &p, const void *extradata) { int val; if (p.type() == TypeDesc::INT) val = *(const int *)p.data(); else if (p.type() == TypeDesc::UINT) val = (int) *(const unsigned int *)p.data(); else if (p.type() == TypeDesc::STRING) val = (int) **(const char **)p.data(); else return std::string(); for (const LabelTable *lt = (const LabelTable *)extradata; lt->label; ++lt) if (val == lt->value) return std::string (lt->label); return std::string(); // nothing } static std::string explain_shutterapex (const ImageIOParameter &p, const void *extradata) { if (p.type() == TypeDesc::FLOAT) { double val = pow (2.0, - (double)*(float *)p.data()); if (val > 1) return Strutil::format ("%g s", val); else return Strutil::format ("1/%g s", floor(1.0/val)); } return std::string(); } static std::string explain_apertureapex (const ImageIOParameter &p, const void *extradata) { if (p.type() == TypeDesc::FLOAT) return Strutil::format ("f/%g", powf (2.0f, *(float *)p.data()/2.0f)); return std::string(); } static std::string explain_ExifFlash (const ImageIOParameter &p, const void *extradata) { int val = 0; if (p.type() == TypeDesc::INT) val = *(int *)p.data(); else if (p.type() == TypeDesc::UINT) val = *(unsigned int *)p.data(); else return std::string(); return Strutil::format ("%s%s%s%s%s%s%s%s", (val&1) ? "flash fired" : "no flash", (val&6) == 4 ? ", no strobe return" : "", (val&6) == 6 ? ", strobe return" : "", (val&24) == 8 ? ", compulsary flash" : "", (val&24) == 16 ? ", flash supression" : "", (val&24) == 24 ? ", auto flash" : "", (val&32) ? ", no flash available" : "", (val&64) ? ", red-eye reduction" : ""); } static LabelTable ExifExposureProgram_table[] = { { 0, "" }, { 1, "manual" }, { 2, "normal program" }, { 3, "aperture priority" }, { 4, "shutter priority" }, { 5, "Creative program, biased toward DOF" }, { 6, "Action program, biased toward fast shutter" }, { 7, "Portrait mode, foreground in focus" }, { 8, "Landscape mode, background in focus" }, { 9, "bulb" }, { -1, NULL } }; static LabelTable ExifLightSource_table[] = { { 0, "unknown" }, { 1, "daylight" }, { 2, "tungsten/incandescent" }, { 4, "flash" }, { 9, "fine weather" }, { 10, "cloudy" }, { 11, "shade" }, { 12, "daylight fluorescent D 5700-7100K" }, { 13, "day white fluorescent N 4600-5400K" }, { 14, "cool white fluorescent W 3900-4500K" }, { 15, "white fluorescent WW 3200-3700K" }, { 17, "standard light A" }, { 18, "standard light B" }, { 19, "standard light C" }, { 20, "D55" }, { 21, "D65" }, { 22, "D75" }, { 23, "D50" }, { 24, "ISO studio tungsten" }, { 255, "other" }, { -1, NULL } }; static LabelTable ExifMeteringMode_table[] = { { 0, "" }, { 1, "average" }, { 2, "center-weighted average" }, { 3, "spot" }, { 4, "multi-spot" }, { 5, "pattern" }, { 6, "partial" }, { -1, NULL } }; static LabelTable ExifSubjectDistanceRange_table[] = { { 0, "unknown" }, { 1, "macro" }, { 2, "close" }, { 3, "distant" }, { -1, NULL } }; static LabelTable ExifSceneCaptureType_table[] = { { 0, "standard" }, { 1, "landscape" }, { 2, "portrait" }, { 3, "night scene" }, { -1, NULL } }; static LabelTable orientation_table[] = { { 1, "normal" }, { 2, "flipped horizontally" }, { 3, "rotated 180 deg" }, { 4, "flipped vertically" }, { 5, "transposed top<->left" }, { 6, "rotated 90 deg CW" }, { 7, "transverse top<->right" }, { 8, "rotated 90 deg CCW" }, { -1, NULL } }; static LabelTable resunit_table[] = { { 1, "none" }, { 2, "inches" }, { 3, "cm" }, { 4, "mm" }, { 5, "um" }, { -1, NULL } }; static LabelTable ExifSensingMethod_table[] = { { 1, "undefined" }, { 2, "1-chip color area" }, { 3, "2-chip color area" }, { 4, "3-chip color area" }, { 5, "color sequential area" }, { 7, "trilinear" }, { 8, "color trilinear" }, { -1, NULL } }; static LabelTable ExifFileSource_table[] = { { 1, "film scanner" }, { 2, "reflection print scanner" }, { 3, "digital camera" }, { -1, NULL } }; static LabelTable ExifSceneType_table[] = { { 1, "directly photographed" }, { -1, NULL } }; static LabelTable ExifExposureMode_table[] = { { 0, "auto" }, { 1, "manual" }, { 2, "auto-bracket" }, { -1, NULL } }; static LabelTable ExifWhiteBalance_table[] = { { 0, "auto" }, { 1, "manual" }, { -1, NULL } }; static LabelTable ExifGainControl_table[] = { { 0, "none" }, { 1, "low gain up" }, { 2, "high gain up" }, { 3, "low gain down" }, { 4, "high gain down" }, { -1, NULL } }; static LabelTable yesno_table[] = { { 0, "no" }, { 1, "yes" }, { -1, NULL } }; static LabelTable softhard_table[] = { { 0, "normal" }, { 1, "soft" }, { 2, "hard" }, { -1, NULL } }; static LabelTable lowhi_table[] = { { 0, "normal" }, { 1, "low" }, { 2, "high" }, { -1, NULL } }; static LabelTable GPSAltitudeRef_table[] = { { 0, "above sea level" }, { 1, "below sea level" }, { -1, NULL } }; static LabelTable GPSStatus_table[] = { { 'A', "measurement in progress" }, { 'V', "measurement interoperability" }, { -1, NULL } }; static LabelTable GPSMeasureMode_table[] = { { '2', "2-D" }, { '3', "3-D" }, { -1, NULL } }; static LabelTable GPSSpeedRef_table[] = { { 'K', "km/hour" }, { 'M', "miles/hour" }, { 'N', "knots" }, { -1, NULL } }; static LabelTable GPSDestDistanceRef_table[] = { { 'K', "km" }, { 'M', "miles" }, { 'N', "knots" }, { -1, NULL } }; static LabelTable magnetic_table[] = { { 'T', "true direction" }, { 'M', "magnetic direction" }, { -1, NULL } }; typedef std::string (*ExplainerFunc) (const ImageIOParameter &p, const void *extradata); struct ExplanationTableEntry { const char *oiioname; ExplainerFunc explainer; const void *extradata; }; static ExplanationTableEntry explanation[] = { { "ResolutionUnit", explain_labeltable, resunit_table }, { "Orientation", explain_labeltable, orientation_table }, { "Exif:ExposureProgram", explain_labeltable, ExifExposureProgram_table }, { "Exif:ShutterSpeedValue", explain_shutterapex, NULL }, { "Exif:ApertureValue", explain_apertureapex, NULL }, { "Exif:MaxApertureValue", explain_apertureapex, NULL }, { "Exif:SubjectDistance", explain_justprint, "m" }, { "Exif:MeteringMode", explain_labeltable, ExifMeteringMode_table }, { "Exif:LightSource", explain_labeltable, ExifLightSource_table }, { "Exif:Flash", explain_ExifFlash, NULL }, { "Exif:FocalLength", explain_justprint, "mm" }, { "Exif:FlashEnergy", explain_justprint, "BCPS" }, { "Exif:FocalPlaneResolutionUnit", explain_labeltable, resunit_table }, { "Exif:SensingMethod", explain_labeltable, ExifSensingMethod_table }, { "Exif:FileSource", explain_labeltable, ExifFileSource_table }, { "Exif:SceneType", explain_labeltable, ExifSceneType_table }, { "Exif:CustomRendered", explain_labeltable, yesno_table }, { "Exif:ExposureMode", explain_labeltable, ExifExposureMode_table }, { "Exif:WhiteBalance", explain_labeltable, ExifWhiteBalance_table }, { "Exif:SceneCaptureType", explain_labeltable, ExifSceneCaptureType_table }, { "Exif:GainControl", explain_labeltable, ExifGainControl_table }, { "Exif:Contrast", explain_labeltable, softhard_table }, { "Exif:Saturation", explain_labeltable, lowhi_table }, { "Exif:Sharpness", explain_labeltable, softhard_table }, { "Exif:SubjectDistanceRange", explain_labeltable, ExifSubjectDistanceRange_table }, { "GPS:AltitudeRef", explain_labeltable, GPSAltitudeRef_table }, { "GPS:Altitude", explain_justprint, "m" }, { "GPS:Status", explain_labeltable, GPSStatus_table }, { "GPS:MeasureMode", explain_labeltable, GPSMeasureMode_table }, { "GPS:SpeedRef", explain_labeltable, GPSSpeedRef_table }, { "GPS:TrackRef", explain_labeltable, magnetic_table }, { "GPS:ImgDirectionRef", explain_labeltable, magnetic_table }, { "GPS:DestBearingRef", explain_labeltable, magnetic_table }, { "GPS:DestDistanceRef", explain_labeltable, GPSDestDistanceRef_table }, { "GPS:Differential", explain_labeltable, yesno_table }, { NULL, NULL, NULL } }; } // end anon namespace std::string ImageSpec::metadata_val (const ImageIOParameter &p, bool human) const { std::string out = format_raw_metadata (p, human ? 16 : 1024); if (human) { std::string nice; for (int e = 0; explanation[e].oiioname; ++e) { if (! strcmp (explanation[e].oiioname, p.name().c_str()) && explanation[e].explainer) { nice = explanation[e].explainer (p, explanation[e].extradata); break; } } if (nice.length()) out = out + " (" + nice + ")"; } return out; } namespace { // Helper functions for from_xml () and to_xml () methods. using namespace pugi; static void add_node (xml_node &node, const std::string &node_name, const char *val) { xml_node newnode = node.append_child(); newnode.set_name (node_name.c_str ()); newnode.append_child (node_pcdata).set_value (val); } static void add_node (xml_node &node, const std::string &node_name, const int val) { char buf[64]; sprintf (buf, "%d", val); add_node (node, node_name, buf); } static void add_channelnames_node (xml_document &doc, const std::vector &channelnames) { xml_node channel_node = doc.child ("ImageSpec").append_child(); channel_node.set_name ("channelnames"); BOOST_FOREACH (std::string name, channelnames) { add_node (channel_node, "channelname", name.c_str ()); } } static void get_channelnames (const xml_node &n, std::vector &channelnames) { xml_node channel_node = n.child ("channelnames"); for (xml_node n = channel_node.child ("channelname"); n; n = n.next_sibling ("channelname")) { channelnames.push_back (n.child_value ()); } } } // end of anonymous namespace std::string ImageSpec::to_xml () const { xml_document doc; doc.append_child ().set_name ("ImageSpec"); doc.child ("ImageSpec").append_attribute ("version") = OIIO_PLUGIN_VERSION; xml_node node = doc.child ("ImageSpec"); add_node (node, "x", x); add_node (node, "y", y); add_node (node, "z", z); add_node (node, "width", width); add_node (node, "height", height); add_node (node, "depth", depth); add_node (node, "full_x", full_x); add_node (node, "full_y", full_y); add_node (node, "full_z", full_z); add_node (node, "full_width", full_width); add_node (node, "full_height", full_height); add_node (node, "full_depth", full_depth); add_node (node, "tile_width", tile_width); add_node (node, "tile_height", tile_height); add_node (node, "tile_depth", tile_depth); add_node (node, "format", format.c_str ()); add_node (node, "nchannels", nchannels); add_channelnames_node (doc, channelnames); add_node (node, "alpha_channel", alpha_channel); add_node (node, "z_channel", z_channel); add_node (node, "deep", int(deep)); // FIXME: What about extra attributes? std::ostringstream result; doc.print (result, ""); return result.str(); } void ImageSpec::from_xml (const char *xml) { xml_document doc; doc.load (xml); xml_node n = doc.child ("ImageSpec"); //int version = n.attribute ("version").as_int(); // Fields for version == 10 (current) x = atoi (n.child_value ("x")); y = atoi (n.child_value ("y")); z = atoi (n.child_value ("z")); width = atoi (n.child_value ("width")); height = atoi (n.child_value ("height")); depth = atoi (n.child_value ("depth")); full_x = atoi (n.child_value ("full_x")); full_y = atoi (n.child_value ("full_y")); full_z = atoi (n.child_value ("full_z")); full_width = atoi (n.child_value ("full_width")); full_height = atoi (n.child_value ("full_height")); full_depth = atoi (n.child_value ("full_depth")); tile_width = atoi (n.child_value ("tile_width")); tile_height = atoi (n.child_value ("tile_height")); tile_depth = atoi (n.child_value ("tile_depth")); format = TypeDesc (n.child_value ("format")); nchannels = atoi (n.child_value ("nchannels")); get_channelnames (n, channelnames); alpha_channel = atoi (n.child_value ("alpha_channel")); z_channel = atoi (n.child_value ("z_channel")); deep = atoi (n.child_value ("deep")); // FIXME: What about extra attributes? // If version == 11 {fill new fields} } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebuf.cpp0000644000175000017500000015210112271062644022156 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Implementation of ImageBuf class. #include #include #include #include #include #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #include "imagecache.h" #include "dassert.h" #include "strutil.h" #include "fmath.h" #include "thread.h" OIIO_NAMESPACE_ENTER { static atomic_ll IB_local_mem_current; ROI get_roi (const ImageSpec &spec) { return ROI (spec.x, spec.x + spec.width, spec.y, spec.y + spec.height, spec.z, spec.z + spec.depth, 0, spec.nchannels); } ROI get_roi_full (const ImageSpec &spec) { return ROI (spec.full_x, spec.full_x + spec.full_width, spec.full_y, spec.full_y + spec.full_height, spec.full_z, spec.full_z + spec.full_depth, 0, spec.nchannels); } void set_roi (ImageSpec &spec, const ROI &newroi) { spec.x = newroi.xbegin; spec.y = newroi.ybegin; spec.z = newroi.zbegin; spec.width = newroi.width(); spec.height = newroi.height(); spec.depth = newroi.depth(); } void set_roi_full (ImageSpec &spec, const ROI &newroi) { spec.full_x = newroi.xbegin; spec.full_y = newroi.ybegin; spec.full_z = newroi.zbegin; spec.full_width = newroi.width(); spec.full_height = newroi.height(); spec.full_depth = newroi.depth(); } ROI roi_union (const ROI &A, const ROI &B) { return ROI (std::min (A.xbegin, B.xbegin), std::max (A.xend, B.xend), std::min (A.ybegin, B.ybegin), std::max (A.yend, B.yend), std::min (A.zbegin, B.zbegin), std::max (A.zend, B.zend), std::min (A.chbegin, B.chbegin), std::max (A.chend, B.chend)); } ROI roi_intersection (const ROI &A, const ROI &B) { return ROI (std::max (A.xbegin, B.xbegin), std::min (A.xend, B.xend), std::max (A.ybegin, B.ybegin), std::min (A.yend, B.yend), std::max (A.zbegin, B.zbegin), std::min (A.zend, B.zend), std::max (A.chbegin, B.chbegin), std::min (A.chend, B.chend)); } // Expansion of the opaque type that hides all the ImageBuf implementation // detail. class ImageBufImpl { public: ImageBufImpl (const std::string &filename, int subimage, int miplevel, ImageCache *imagecache=NULL, const ImageSpec *spec=NULL, void *buffer=NULL); ImageBufImpl (const ImageBufImpl &src); ~ImageBufImpl (); void clear (); void reset (const std::string &name, int subimage, int miplevel, ImageCache *imagecache); void reset (const std::string &name, const ImageSpec &spec); void alloc (const ImageSpec &spec); void realloc (); bool init_spec (const std::string &filename, int subimage, int miplevel); bool read (int subimage=0, int miplevel=0, bool force=false, TypeDesc convert=TypeDesc::UNKNOWN, ProgressCallback progress_callback=NULL, void *progress_callback_data=NULL); void copy_metadata (const ImageBufImpl &src); // Error reporting for ImageBuf: call this with printf-like // arguments. Note however that this is fully typesafe! // void error (const char *format, ...) TINYFORMAT_WRAP_FORMAT (void, error, const, std::ostringstream msg;, msg, append_error(msg.str());) void append_error (const std::string& message) const; ImageBuf::IBStorage storage () const { return m_storage; } TypeDesc pixeltype () const { validate_spec (); return m_localpixels ? m_spec.format : m_cachedpixeltype; } DeepData *deepdata () { validate_pixels(); return m_spec.deep ? &m_deepdata : NULL; } const DeepData *deepdata () const { validate_pixels(); return m_spec.deep ? &m_deepdata : NULL; } bool initialized () const { return m_spec_valid && m_storage != ImageBuf::UNINITIALIZED; } bool cachedpixels () const { return m_storage == ImageBuf::IMAGECACHE; } const void *pixeladdr (int x, int y, int z) const; void *pixeladdr (int x, int y, int z); const void *retile (int x, int y, int z, ImageCache::Tile* &tile, int &tilexbegin, int &tileybegin, int &tilezbegin, int &tilexend, bool exists, ImageBuf::WrapMode wrap) const; bool do_wrap (int &x, int &y, int &z, ImageBuf::WrapMode wrap) const; const void *blackpixel () const { validate_spec (); return &m_blackpixel[0]; } bool validate_spec () const { if (m_spec_valid) return true; if (! m_name.size()) return false; spin_lock lock (m_valid_mutex); // prevent multiple init_spec if (m_spec_valid) return true; ImageBufImpl *imp = const_cast(this); if (imp->m_current_subimage < 0) imp->m_current_subimage = 0; if (imp->m_current_miplevel < 0) imp->m_current_miplevel = 0; return imp->init_spec(m_name.string(), m_current_subimage, m_current_miplevel); } bool validate_pixels () const { if (m_pixels_valid) return true; if (! m_name.size()) return true; spin_lock lock (m_valid_mutex); // prevent multiple read() if (m_pixels_valid) return true; ImageBufImpl *imp = const_cast(this); if (imp->m_current_subimage < 0) imp->m_current_subimage = 0; if (imp->m_current_miplevel < 0) imp->m_current_miplevel = 0; return imp->read (m_current_subimage, m_current_miplevel); } const ImageSpec & spec () const { validate_spec (); return m_spec; } const ImageSpec & nativespec () const { validate_spec (); return m_nativespec; } ImageSpec & specmod () { validate_spec (); return m_spec; } private: ImageBuf::IBStorage m_storage; ///< Pixel storage class ustring m_name; ///< Filename of the image ustring m_fileformat; ///< File format name int m_nsubimages; ///< How many subimages are there? int m_current_subimage; ///< Current subimage we're viewing int m_current_miplevel; ///< Current miplevel we're viewing int m_nmiplevels; ///< # of MIP levels in the current subimage ImageSpec m_spec; ///< Describes the image (size, etc) ImageSpec m_nativespec; ///< Describes the true native image boost::scoped_array m_pixels; ///< Pixel data, if local and we own it char *m_localpixels; ///< Pointer to local pixels mutable spin_mutex m_valid_mutex; mutable bool m_spec_valid; ///< Is the spec valid mutable bool m_pixels_valid; ///< Image is valid bool m_badfile; ///< File not found int m_orientation; ///< Orientation of the image float m_pixelaspect; ///< Pixel aspect ratio of the image size_t m_pixel_bytes; size_t m_scanline_bytes; size_t m_plane_bytes; ImageCache *m_imagecache; ///< ImageCache to use TypeDesc m_cachedpixeltype; ///< Data type stored in the cache DeepData m_deepdata; ///< Deep data size_t m_allocated_size; ///< How much memory we've allocated std::vector m_blackpixel; ///< Pixel-sized zero bytes TypeDesc m_write_format; /// Format to use for write() int m_write_tile_width; int m_write_tile_height; int m_write_tile_depth; mutable std::string m_err; ///< Last error message const ImageBufImpl operator= (const ImageBufImpl &src); // unimplemented friend class ImageBuf; }; ImageBufImpl::ImageBufImpl (const std::string &filename, int subimage, int miplevel, ImageCache *imagecache, const ImageSpec *spec, void *buffer) : m_storage(ImageBuf::UNINITIALIZED), m_name(filename), m_nsubimages(0), m_current_subimage(subimage), m_current_miplevel(miplevel), m_localpixels(NULL), m_spec_valid(false), m_pixels_valid(false), m_badfile(false), m_orientation(1), m_pixelaspect(1), m_pixel_bytes(0), m_scanline_bytes(0), m_plane_bytes(0), m_imagecache(imagecache), m_allocated_size(0), m_write_format(TypeDesc::UNKNOWN), m_write_tile_width(0), m_write_tile_height(0), m_write_tile_depth(1) { if (spec) { m_spec = *spec; m_nativespec = *spec; m_pixel_bytes = spec->pixel_bytes(); m_scanline_bytes = spec->scanline_bytes(); m_plane_bytes = clamped_mult64 (m_scanline_bytes, (imagesize_t)m_spec.height); m_blackpixel.resize (m_pixel_bytes, 0); if (buffer) { m_localpixels = (char *)buffer; m_storage = ImageBuf::APPBUFFER; m_pixels_valid = true; } else { m_storage = ImageBuf::LOCALBUFFER; } m_spec_valid = true; } else if (filename.length() > 0) { ASSERT (buffer == NULL); // If a filename was given, read the spec and set it up as an // ImageCache-backed image. Reallocate later if an explicit read() // is called to force read into a local buffer. read (subimage, miplevel); } else { ASSERT (buffer == NULL); } } ImageBufImpl::ImageBufImpl (const ImageBufImpl &src) : m_storage(src.m_storage), m_name(src.m_name), m_fileformat(src.m_fileformat), m_nsubimages(src.m_nsubimages), m_current_subimage(src.m_current_subimage), m_current_miplevel(src.m_current_miplevel), m_nmiplevels(src.m_nmiplevels), m_spec(src.m_spec), m_nativespec(src.m_nativespec), m_pixels(src.m_localpixels ? new char [src.m_spec.image_bytes()] : NULL), m_localpixels(m_pixels.get()), m_badfile(src.m_badfile), m_orientation(src.m_orientation), m_pixelaspect(src.m_pixelaspect), m_pixel_bytes(src.m_pixel_bytes), m_scanline_bytes(src.m_scanline_bytes), m_plane_bytes(src.m_plane_bytes), m_imagecache(src.m_imagecache), m_cachedpixeltype(src.m_cachedpixeltype), m_deepdata(src.m_deepdata), m_blackpixel(src.m_blackpixel), m_write_format(src.m_write_format), m_write_tile_width(src.m_write_tile_width), m_write_tile_height(src.m_write_tile_height), m_write_tile_depth(src.m_write_tile_depth) { m_spec_valid = src.m_spec_valid; m_pixels_valid = src.m_pixels_valid; m_allocated_size = src.m_localpixels ? src.spec().image_bytes() : 0; IB_local_mem_current += m_allocated_size; if (src.m_localpixels) { // Source had the image fully in memory (no cache) if (m_storage == ImageBuf::APPBUFFER) { // Source just wrapped the client app's pixels ASSERT (0 && "ImageBuf wrapping client buffer not yet supported"); } else { // We own our pixels -- copy from source memcpy (m_pixels.get(), src.m_pixels.get(), m_spec.image_bytes()); } } else { // Source was cache-based or deep // nothing else to do } } ImageBufImpl::~ImageBufImpl () { // Do NOT destroy m_imagecache here -- either it was created // externally and passed to the ImageBuf ctr or reset() method, or // else init_spec requested the system-wide shared cache, which // does not need to be destroyed. IB_local_mem_current -= m_allocated_size; } ImageBuf::ImageBuf () : m_impl (new ImageBufImpl (std::string(), -1, -1, NULL)) { } ImageBuf::ImageBuf (const std::string &filename, int subimage, int miplevel, ImageCache *imagecache) : m_impl (new ImageBufImpl (filename, subimage, miplevel, imagecache)) { } ImageBuf::ImageBuf (const std::string &filename, ImageCache *imagecache) : m_impl (new ImageBufImpl (filename, 0, 0, imagecache)) { } ImageBuf::ImageBuf (const ImageSpec &spec) : m_impl (new ImageBufImpl (std::string(), 0, 0, NULL, &spec)) { alloc (spec); } ImageBuf::ImageBuf (const std::string &filename, const ImageSpec &spec) : m_impl (new ImageBufImpl (filename, 0, 0, NULL, &spec)) { alloc (spec); } ImageBuf::ImageBuf (const std::string &filename, const ImageSpec &spec, void *buffer) : m_impl (new ImageBufImpl (filename, 0, 0, NULL, &spec, buffer)) { } ImageBuf::ImageBuf (const ImageSpec &spec, void *buffer) : m_impl (new ImageBufImpl (std::string(), 0, 0, NULL, &spec, buffer)) { } ImageBuf::ImageBuf (const ImageBuf &src) : m_impl (new ImageBufImpl (*src.impl())) { } ImageBuf::~ImageBuf () { delete m_impl; m_impl = NULL; } static spin_mutex err_mutex; ///< Protect m_err fields bool ImageBuf::has_error () const { spin_lock lock (err_mutex); return ! impl()->m_err.empty(); } std::string ImageBuf::geterror (void) const { spin_lock lock (err_mutex); std::string e = impl()->m_err; impl()->m_err.clear(); return e; } void ImageBufImpl::append_error (const std::string &message) const { spin_lock lock (err_mutex); ASSERT (m_err.size() < 1024*1024*16 && "Accumulated error messages > 16MB. Try checking return codes!"); if (m_err.size() && m_err[m_err.size()-1] != '\n') m_err += '\n'; m_err += message; } void ImageBuf::append_error (const std::string &message) const { impl()->append_error (message); } ImageBuf::IBStorage ImageBuf::storage () const { return impl()->storage (); } void ImageBufImpl::clear () { m_storage = ImageBuf::UNINITIALIZED; m_name.clear (); m_fileformat.clear (); m_nsubimages = 0; m_current_subimage = -1; m_current_miplevel = -1; m_spec = ImageSpec (); m_nativespec = ImageSpec (); m_pixels.reset (); m_localpixels = NULL; m_spec_valid = false; m_pixels_valid = false; m_badfile = false; m_orientation = 1; m_pixelaspect = 1; m_pixel_bytes = 0; m_scanline_bytes = 0; m_plane_bytes = 0; m_imagecache = NULL; m_deepdata.free (); m_blackpixel.clear (); m_write_format = TypeDesc::UNKNOWN; m_write_tile_width = 0; m_write_tile_height = 0; m_write_tile_depth = 0; } void ImageBuf::clear () { impl()->clear (); } void ImageBufImpl::reset (const std::string &filename, int subimage, int miplevel, ImageCache *imagecache) { clear (); m_name = ustring (filename); m_current_subimage = subimage; m_current_miplevel = miplevel; if (imagecache) m_imagecache = imagecache; if (m_name.length() > 0) { // If a filename was given, read the spec and set it up as an // ImageCache-backed image. Reallocate later if an explicit read() // is called to force read into a local buffer. read (subimage, miplevel); } } void ImageBuf::reset (const std::string &filename, int subimage, int miplevel, ImageCache *imagecache) { impl()->reset (filename, subimage, miplevel, imagecache); } void ImageBuf::reset (const std::string &filename, ImageCache *imagecache) { impl()->reset (filename, 0, 0, imagecache); } void ImageBufImpl::reset (const std::string &filename, const ImageSpec &spec) { clear (); m_name = ustring (filename); m_current_subimage = 0; m_current_miplevel = 0; alloc (spec); } void ImageBuf::reset (const std::string &filename, const ImageSpec &spec) { impl()->reset (filename, spec); } void ImageBuf::reset (const ImageSpec &spec) { impl()->reset (std::string(), spec); } void ImageBufImpl::realloc () { IB_local_mem_current -= m_allocated_size; m_allocated_size = m_spec.deep ? size_t(0) : m_spec.image_bytes (); IB_local_mem_current += m_allocated_size; m_pixels.reset (m_allocated_size ? new char [m_allocated_size] : NULL); m_localpixels = m_pixels.get(); m_storage = m_allocated_size ? ImageBuf::LOCALBUFFER : ImageBuf::UNINITIALIZED; m_pixel_bytes = m_spec.pixel_bytes(); m_scanline_bytes = m_spec.scanline_bytes(); m_plane_bytes = clamped_mult64 (m_scanline_bytes, (imagesize_t)m_spec.height); m_blackpixel.resize (m_pixel_bytes, 0); if (m_allocated_size) m_pixels_valid = true; #if 0 std::cerr << "ImageBuf " << m_name << " local allocation: " << m_allocated_size << "\n"; #endif } void ImageBufImpl::alloc (const ImageSpec &spec) { m_spec = spec; // Preclude a nonsensical size m_spec.width = std::max (1, m_spec.width); m_spec.height = std::max (1, m_spec.height); m_spec.depth = std::max (1, m_spec.depth); m_spec.nchannels = std::max (1, m_spec.nchannels); m_nativespec = spec; realloc (); m_spec_valid = true; } void ImageBuf::alloc (const ImageSpec &spec) { impl()->alloc (spec); } void ImageBuf::copy_from (const ImageBuf &src) { if (this == &src) return; const ImageBufImpl *srcimpl (src.impl()); srcimpl->validate_pixels (); const ImageSpec &srcspec (srcimpl->spec()); ImageBufImpl *impl (this->impl()); const ImageSpec &spec (impl->spec()); ASSERT (spec.width == srcspec.width && spec.height == srcspec.height && spec.depth == srcspec.depth && spec.nchannels == srcspec.nchannels); impl->realloc (); if (spec.deep) impl->m_deepdata = srcimpl->m_deepdata; else src.get_pixels (src.xbegin(), src.xend(), src.ybegin(), src.yend(), src.zbegin(), src.zend(), spec.format, impl->m_localpixels); } bool ImageBufImpl::init_spec (const std::string &filename, int subimage, int miplevel) { if (!m_badfile && m_spec_valid && m_current_subimage >= 0 && m_current_miplevel >= 0 && m_name == filename && m_current_subimage == subimage && m_current_miplevel == miplevel) return true; // Already done if (! m_imagecache) { m_imagecache = ImageCache::create (true /* shared cache */); } m_pixels_valid = false; m_name = filename; m_nsubimages = 0; m_nmiplevels = 0; static ustring s_subimages("subimages"), s_miplevels("miplevels"); static ustring s_fileformat("fileformat"); m_imagecache->get_image_info (m_name, subimage, miplevel, s_subimages, TypeDesc::TypeInt, &m_nsubimages); m_imagecache->get_image_info (m_name, subimage, miplevel, s_miplevels, TypeDesc::TypeInt, &m_nmiplevels); const char *fmt = NULL; m_imagecache->get_image_info (m_name, subimage, miplevel, s_fileformat, TypeDesc::TypeString, &fmt); m_fileformat = ustring(fmt); m_imagecache->get_imagespec (m_name, m_spec, subimage, miplevel); m_imagecache->get_imagespec (m_name, m_nativespec, subimage, miplevel, true); m_pixel_bytes = m_spec.pixel_bytes(); m_scanline_bytes = m_spec.scanline_bytes(); m_plane_bytes = clamped_mult64 (m_scanline_bytes, (imagesize_t)m_spec.height); m_blackpixel.resize (m_pixel_bytes, 0); // Subtlety: m_nativespec will have the true formats of the file, but // we rig m_spec to reflect what it will look like in the cache. // This may make m_spec appear to change if there's a subsequent read() // that forces a full read into local memory, but what else can we do? // It causes havoc for it to suddenly change in the other direction // when the file is lazily read. int peltype = TypeDesc::UNKNOWN; m_imagecache->get_image_info (m_name, subimage, miplevel, ustring("cachedpixeltype"), TypeDesc::TypeInt, &peltype); if (peltype != TypeDesc::UNKNOWN) { m_spec.format = (TypeDesc::BASETYPE)peltype; m_spec.channelformats.clear(); } if (m_nsubimages) { m_badfile = false; m_orientation = m_spec.get_int_attribute ("orientation", 1); m_pixelaspect = m_spec.get_float_attribute ("pixelaspectratio", 1.0f); m_current_subimage = subimage; m_current_miplevel = miplevel; m_spec_valid = true; } else { m_badfile = true; m_current_subimage = -1; m_current_miplevel = -1; m_err = m_imagecache->geterror (); m_spec_valid = false; // std::cerr << "ImageBuf ERROR: " << m_err << "\n"; } return !m_badfile; } bool ImageBuf::init_spec (const std::string &filename, int subimage, int miplevel) { return impl()->init_spec (filename, subimage, miplevel); } bool ImageBufImpl::read (int subimage, int miplevel, bool force, TypeDesc convert, ProgressCallback progress_callback, void *progress_callback_data) { if (! m_name.length()) return true; if (m_pixels_valid && !force && subimage == m_current_subimage && miplevel == m_current_miplevel) return true; if (! init_spec (m_name.string(), subimage, miplevel)) { m_badfile = true; m_spec_valid = false; return false; } m_current_subimage = subimage; m_current_miplevel = miplevel; if (m_spec.deep) { boost::scoped_ptr input (ImageInput::open (m_name.string())); if (! input) { error ("%s", OIIO::geterror()); return false; } ImageSpec dummyspec; if (! input->seek_subimage (subimage, miplevel, dummyspec)) { error ("%s", input->geterror()); return false; } if (! input->read_native_deep_image (m_deepdata)) { error ("%s", input->geterror()); return false; } m_spec = m_nativespec; // Deep images always use native data m_pixels_valid = true; m_storage = ImageBuf::LOCALBUFFER; return true; } // If we don't already have "local" pixels, and we aren't asking to // convert the pixels to a specific (and different) type, then take an // early out by relying on the cache. int peltype = TypeDesc::UNKNOWN; m_imagecache->get_image_info (m_name, subimage, miplevel, ustring("cachedpixeltype"), TypeDesc::TypeInt, &peltype); m_cachedpixeltype = TypeDesc ((TypeDesc::BASETYPE)peltype); if (! m_localpixels && ! force && (convert == m_cachedpixeltype || convert == TypeDesc::UNKNOWN)) { m_spec.format = m_cachedpixeltype; m_pixel_bytes = m_spec.pixel_bytes(); m_scanline_bytes = m_spec.scanline_bytes(); m_plane_bytes = clamped_mult64 (m_scanline_bytes, (imagesize_t)m_spec.height); m_blackpixel.resize (m_pixel_bytes, 0); m_pixels_valid = true; m_storage = ImageBuf::IMAGECACHE; #ifndef NDEBUG std::cerr << "read was not necessary -- using cache\n"; #endif return true; } else { #ifndef NDEBUG std::cerr << "going to have to read " << m_name << ": " << m_spec.format.c_str() << " vs " << convert.c_str() << "\n"; #endif // FIXME/N.B. - is it really best to go through the ImageCache // for forced IB reads? Are there circumstances in which we // should just to a straight read_image() to avoid the extra // copies or the memory use of having bytes both in the cache // and in the IB? } if (convert != TypeDesc::UNKNOWN) m_spec.format = convert; else m_spec.format = m_nativespec.format; m_orientation = m_spec.get_int_attribute ("orientation", 1); m_pixelaspect = m_spec.get_float_attribute ("pixelaspectratio", 1.0f); realloc (); if (m_imagecache->get_pixels (m_name, subimage, miplevel, m_spec.x, m_spec.x+m_spec.width, m_spec.y, m_spec.y+m_spec.height, m_spec.z, m_spec.z+m_spec.depth, m_spec.format, m_localpixels)) { m_pixels_valid = true; // If forcing a full read, make sure the spec reflects the // nativespec's tile sizes, rather than that imposed by the // ImageCache. m_spec.tile_width = m_nativespec.tile_width; m_spec.tile_height = m_nativespec.tile_height; m_spec.tile_depth = m_nativespec.tile_depth; } else { m_pixels_valid = false; error ("%s", m_imagecache->geterror ()); } return m_pixels_valid; } bool ImageBuf::read (int subimage, int miplevel, bool force, TypeDesc convert, ProgressCallback progress_callback, void *progress_callback_data) { return impl()->read (subimage, miplevel, force, convert, progress_callback, progress_callback_data); } void ImageBuf::set_write_format (TypeDesc format) { impl()->m_write_format = format; } void ImageBuf::set_write_tiles (int width, int height, int depth) { impl()->m_write_tile_width = width; impl()->m_write_tile_height = height; impl()->m_write_tile_depth = std::max (1, depth); } bool ImageBuf::write (ImageOutput *out, ProgressCallback progress_callback, void *progress_callback_data) const { stride_t as = AutoStride; bool ok = true; const ImageBufImpl *impl = this->impl(); impl->validate_pixels (); const ImageSpec &m_spec (impl->m_spec); if (impl->m_localpixels) { // In-core pixel buffer for the whole image ok = out->write_image (m_spec.format, impl->m_localpixels, as, as, as, progress_callback, progress_callback_data); } else if (deep()) { // Deep image record ok = out->write_deep_image (impl->m_deepdata); } else { // Backed by ImageCache boost::scoped_array tmp (new char [m_spec.image_bytes()]); get_pixels (xbegin(), xend(), ybegin(), yend(), zbegin(), zend(), m_spec.format, &tmp[0]); ok = out->write_image (m_spec.format, &tmp[0], as, as, as, progress_callback, progress_callback_data); // FIXME -- not good for huge images. Instead, we should read // little bits at a time (scanline or tile blocks). } if (! ok) error ("%s", out->geterror ()); return ok; } bool ImageBuf::save (const std::string &filename, const std::string &fileformat, ProgressCallback progress_callback, void *progress_callback_data) const { return write (filename, fileformat, progress_callback, progress_callback_data); } bool ImageBuf::write (const std::string &_filename, const std::string &_fileformat, ProgressCallback progress_callback, void *progress_callback_data) const { std::string filename = _filename.size() ? _filename : name(); std::string fileformat = _fileformat.size() ? _fileformat : filename; if (filename.size() == 0) { error ("ImageBuf::write() called with no filename"); return false; } impl()->validate_pixels (); boost::scoped_ptr out (ImageOutput::create (fileformat.c_str(), "" /* searchpath */)); if (! out) { error ("%s", geterror()); return false; } // Write scanline files by default, but if the file type allows tiles, // user can override via ImageBuf::set_write_tiles(), or by using the // variety of IB::write() that takes the open ImageOutput* directly. ImageSpec newspec = spec(); if (out->supports("tiles") && impl()->m_write_tile_width > 0) { newspec.tile_width = impl()->m_write_tile_width; newspec.tile_height = impl()->m_write_tile_height; newspec.tile_depth = std::max (1, impl()->m_write_tile_depth); } else { newspec.tile_width = 0; newspec.tile_height = 0; newspec.tile_depth = 0; } // Allow for format override via ImageBuf::set_write_format() if (impl()->m_write_format != TypeDesc::UNKNOWN) { newspec.set_format (impl()->m_write_format); newspec.channelformats.clear(); } else { newspec.set_format (nativespec().format); newspec.channelformats = nativespec().channelformats; } if (! out->open (filename.c_str(), newspec)) { error ("%s", out->geterror()); return false; } if (! write (out.get(), progress_callback, progress_callback_data)) return false; out->close (); if (progress_callback) progress_callback (progress_callback_data, 0); return true; } void ImageBufImpl::copy_metadata (const ImageBufImpl &src) { const ImageSpec &srcspec (src.spec()); ImageSpec &m_spec (this->specmod()); m_spec.full_x = srcspec.full_x; m_spec.full_y = srcspec.full_y; m_spec.full_z = srcspec.full_z; m_spec.full_width = srcspec.full_width; m_spec.full_height = srcspec.full_height; m_spec.full_depth = srcspec.full_depth; if (src.storage() == ImageBuf::IMAGECACHE) { // If we're copying metadata from a cached image, be sure to // get the file's tile size, not the cache's tile size. m_spec.tile_width = src.nativespec().tile_width; m_spec.tile_height = src.nativespec().tile_height; m_spec.tile_depth = src.nativespec().tile_depth; } else { m_spec.tile_width = srcspec.tile_width; m_spec.tile_height = srcspec.tile_height; m_spec.tile_depth = srcspec.tile_depth; } m_spec.extra_attribs = srcspec.extra_attribs; } void ImageBuf::copy_metadata (const ImageBuf &src) { impl()->copy_metadata (*src.impl()); } const ImageSpec & ImageBuf::spec () const { return impl()->spec(); } ImageSpec & ImageBuf::specmod () { return impl()->specmod(); } const ImageSpec & ImageBuf::nativespec () const { return impl()->nativespec(); } const std::string & ImageBuf::name (void) const { return impl()->m_name.string(); } const std::string & ImageBuf::file_format_name (void) const { impl()->validate_spec (); return impl()->m_fileformat.string(); } int ImageBuf::subimage () const { return impl()->m_current_subimage; } int ImageBuf::nsubimages () const { impl()->validate_spec(); return impl()->m_nsubimages; } int ImageBuf::miplevel () const { return impl()->m_current_miplevel; } int ImageBuf::nmiplevels () const { impl()->validate_spec(); return impl()->m_nmiplevels; } int ImageBuf::nchannels () const { return impl()->spec().nchannels; } int ImageBuf::orientation () const { impl()->validate_spec(); return impl()->m_orientation; } bool ImageBuf::pixels_valid (void) const { return impl()->m_pixels_valid; } TypeDesc ImageBuf::pixeltype () const { return impl()->pixeltype(); } void * ImageBuf::localpixels () { impl()->validate_pixels (); return impl()->m_localpixels; } const void * ImageBuf::localpixels () const { impl()->validate_pixels (); return impl()->m_localpixels; } bool ImageBuf::cachedpixels () const { return impl()->cachedpixels(); } ImageCache * ImageBuf::imagecache () const { return impl()->m_imagecache; } bool ImageBuf::deep () const { return spec().deep; } DeepData * ImageBuf::deepdata () { return impl()->deepdata (); } const DeepData * ImageBuf::deepdata () const { return impl()->deepdata (); } bool ImageBuf::initialized () const { return impl()->initialized (); } namespace { // Pixel-by-pixel copy fully templated by both data types. // The roi is guaranteed to exist in both images. template bool copy_pixels_2 (ImageBuf &dst, const ImageBuf &src, const ROI &roi) { int nchannels = roi.nchannels(); if (is_same::value) { // If both bufs are the same type, just directly copy the values ImageBuf::Iterator d (dst, roi); ImageBuf::ConstIterator s (src, roi); for ( ; ! d.done(); ++d, ++s) { for (int c = 0; c < nchannels; ++c) d[c] = s[c]; } } else { // If the two bufs are different types, convert through float ImageBuf::Iterator d (dst, roi); ImageBuf::ConstIterator s (src, roi); for ( ; ! d.done(); ++d, ++s) { for (int c = 0; c < nchannels; ++c) d[c] = s[c]; } } return true; } } // anon namespace bool ImageBuf::copy_pixels (const ImageBuf &src) { // compute overlap ROI myroi = get_roi(spec()); ROI roi = roi_intersection (myroi, get_roi(src.spec())); // If we aren't copying over all our pixels, zero out the pixels if (roi != myroi) ImageBufAlgo::zero (*this); OIIO_DISPATCH_TYPES2 ("copy_pixels", copy_pixels_2, spec().format, src.spec().format, *this, src, roi); return true; } bool ImageBuf::copy (const ImageBuf &src) { src.impl()->validate_pixels (); if (this == &src) // self-assignment return true; if (src.storage() == UNINITIALIZED) { // buf = uninitialized clear(); return true; } reset (src.name(), src.spec()); return this->copy_pixels (src); } template static inline float getchannel_ (const ImageBuf &buf, int x, int y, int z, int c, ImageBuf::WrapMode wrap) { ImageBuf::ConstIterator pixel (buf, x, y, z); return pixel[c]; } float ImageBuf::getchannel (int x, int y, int z, int c, WrapMode wrap) const { if (c < 0 || c >= spec().nchannels) return 0.0f; OIIO_DISPATCH_TYPES ("getchannel", getchannel_, spec().format, *this, x, y, z, c, wrap); } template static bool getpixel_ (const ImageBuf &buf, int x, int y, int z, float *result, int chans, ImageBuf::WrapMode wrap) { ImageBuf::ConstIterator pixel (buf, x, y, z, wrap); for (int i = 0; i < chans; ++i) result[i] = pixel[i]; return true; } inline bool getpixel_wrapper (int x, int y, int z, float *pixel, int nchans, ImageBuf::WrapMode wrap, const ImageBuf &ib) { OIIO_DISPATCH_TYPES ("getpixel", getpixel_, ib.spec().format, ib, x, y, z, pixel, nchans, wrap); } void ImageBuf::getpixel (int x, int y, int z, float *pixel, int maxchannels, WrapMode wrap) const { int nchans = std::min (spec().nchannels, maxchannels); getpixel_wrapper (x, y, z, pixel, nchans, wrap, *this); } template static bool interppixel_ (const ImageBuf &img, float x, float y, float *pixel, ImageBuf::WrapMode wrap) { int n = img.spec().nchannels; float *localpixel = ALLOCA (float, n*4); float *p[4] = { localpixel, localpixel+n, localpixel+2*n, localpixel+3*n }; x -= 0.5f; y -= 0.5f; int xtexel, ytexel; float xfrac, yfrac; xfrac = floorfrac (x, &xtexel); yfrac = floorfrac (y, &ytexel); ImageBuf::ConstIterator it (img, xtexel, xtexel+2, ytexel, ytexel+2, 0, 1, wrap); for (int i = 0; i < 4; ++i, ++it) for (int c = 0; c < n; ++c) p[i][c] = it[c]; bilerp (p[0], p[1], p[2], p[3], xfrac, yfrac, n, pixel); return true; } inline bool interppixel_wrapper (float x, float y, float *pixel, ImageBuf::WrapMode wrap, const ImageBuf &img) { OIIO_DISPATCH_TYPES ("interppixel", interppixel_, img.spec().format, img, x, y, pixel, wrap); } void ImageBuf::interppixel (float x, float y, float *pixel, WrapMode wrap) const { interppixel_wrapper (x, y, pixel, wrap, *this); } void ImageBuf::interppixel_NDC (float x, float y, float *pixel, WrapMode wrap) const { const ImageSpec &spec (impl()->spec()); interppixel (static_cast(spec.x) + x * static_cast(spec.width), static_cast(spec.y) + y * static_cast(spec.height), pixel, wrap); } void ImageBuf::interppixel_NDC_full (float x, float y, float *pixel, WrapMode wrap) const { const ImageSpec &spec (impl()->spec()); interppixel (static_cast(spec.full_x) + x * static_cast(spec.full_width), static_cast(spec.full_y) + y * static_cast(spec.full_height), pixel, wrap); } template inline void setpixel_ (ImageBuf &buf, int x, int y, int z, const float *data, int chans) { ImageBuf::Iterator pixel (buf, x, y, z); if (pixel.exists()) { for (int i = 0; i < chans; ++i) pixel[i] = data[i]; } } void ImageBuf::setpixel (int x, int y, int z, const float *pixel, int maxchannels) { int n = std::min (spec().nchannels, maxchannels); switch (spec().format.basetype) { case TypeDesc::FLOAT : setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::UINT8 : setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::INT8 : setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::UINT16: setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::INT16 : setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::UINT : setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::INT : setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::HALF : setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::DOUBLE: setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::UINT64: setpixel_ (*this, x, y, z, pixel, n); break; case TypeDesc::INT64 : setpixel_ (*this, x, y, z, pixel, n); break; default: ASSERT (0); } } void ImageBuf::setpixel (int i, const float *pixel, int maxchannels) { setpixel (spec().x + (i % spec().width), spec().y + (i / spec().width), pixel, maxchannels); } template static inline bool get_pixel_channels_ (const ImageBuf &buf, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, void *r_, stride_t xstride, stride_t ystride, stride_t zstride) { D *r = (D *)r_; int w = (xend-xbegin), h = (yend-ybegin); int nchans = chend - chbegin; ImageSpec::auto_stride (xstride, ystride, zstride, sizeof(D), nchans, w, h); for (ImageBuf::ConstIterator p (buf, xbegin, xend, ybegin, yend, zbegin, zend); !p.done(); ++p) { imagesize_t offset = (p.z()-zbegin)*zstride + (p.y()-ybegin)*ystride + (p.x()-xbegin)*xstride; D *rc = (D *)((char *)r + offset); for (int c = 0; c < nchans; ++c) rc[c] = p[c+chbegin]; } return true; } template bool ImageBuf::get_pixel_channels (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, D *r, stride_t xstride, stride_t ystride, stride_t zstride) const { OIIO_DISPATCH_TYPES2_HELP ("get_pixel_channels", get_pixel_channels_, D, spec().format, *this, xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend, r, xstride, ystride, zstride); } bool ImageBuf::get_pixel_channels (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *result, stride_t xstride, stride_t ystride, stride_t zstride) const { OIIO_DISPATCH_TYPES2 ("get_pixel_channels", get_pixel_channels_, format, spec().format, *this, xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend, result, xstride, ystride, zstride); } bool ImageBuf::get_pixels (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result, stride_t xstride, stride_t ystride, stride_t zstride) const { return get_pixel_channels (xbegin, xend, ybegin, yend, zbegin, zend, 0, nchannels(), format, result, xstride, ystride, zstride); } int ImageBuf::deep_samples (int x, int y, int z) const { impl()->validate_pixels(); if (! deep()) return 0; const ImageSpec &m_spec (spec()); if (x < m_spec.x || y < m_spec.y || z < m_spec.z) return 0; x -= m_spec.x; y -= m_spec.y; z -= m_spec.z; if (x >= m_spec.width || y >= m_spec.height || z >= m_spec.depth) return 0; int p = (z * m_spec.height + y) * m_spec.width + x; return deepdata()->nsamples[p]; } const void * ImageBuf::deep_pixel_ptr (int x, int y, int z, int c) const { impl()->validate_pixels(); if (! deep()) return NULL; const ImageSpec &m_spec (spec()); if (x < m_spec.x || y < m_spec.y || z < m_spec.z) return NULL; x -= m_spec.x; y -= m_spec.y; z -= m_spec.z; if (x >= m_spec.width || y >= m_spec.height || z >= m_spec.depth || c < 0 || c >= m_spec.nchannels) return NULL; int p = (z * m_spec.height + y) * m_spec.width + x; return deepdata()->nsamples[p] ? deepdata()->pointers[p*m_spec.nchannels] : NULL; } float ImageBuf::deep_value (int x, int y, int z, int c, int s) const { impl()->validate_pixels(); if (! deep()) return 0.0f; const ImageSpec &m_spec (spec()); if (x < m_spec.x || y < m_spec.y || z < m_spec.z) return 0.0f; x -= m_spec.x; y -= m_spec.y; z -= m_spec.z; if (x >= m_spec.width || y >= m_spec.height || z >= m_spec.depth || c < 0 || c >= m_spec.nchannels) return 0.0f; int p = (z * m_spec.height + y) * m_spec.width + x; int nsamps = impl()->m_deepdata.nsamples[p]; if (s >= nsamps) return 0.0f; const void *ptr = impl()->m_deepdata.pointers[p*m_spec.nchannels+c]; TypeDesc t = impl()->m_deepdata.channeltypes[c]; switch (t.basetype) { case TypeDesc::FLOAT : return ((const float *)ptr)[s]; case TypeDesc::HALF : return ((const half *)ptr)[s]; case TypeDesc::UINT8 : return ConstDataArrayProxy((const unsigned char *)ptr)[s]; case TypeDesc::INT8 : return ConstDataArrayProxy((const char *)ptr)[s]; case TypeDesc::UINT16: return ConstDataArrayProxy((const unsigned short *)ptr)[s]; case TypeDesc::INT16 : return ConstDataArrayProxy((const short *)ptr)[s]; case TypeDesc::UINT : return ConstDataArrayProxy((const unsigned int *)ptr)[s]; case TypeDesc::INT : return ConstDataArrayProxy((const int *)ptr)[s]; case TypeDesc::UINT64: return ConstDataArrayProxy((const unsigned long long *)ptr)[s]; case TypeDesc::INT64 : return ConstDataArrayProxy((const long long *)ptr)[s]; default: ASSERT (0); return 0.0f; } } int ImageBuf::xbegin () const { return spec().x; } int ImageBuf::xend () const { return spec().x + spec().width; } int ImageBuf::ybegin () const { return spec().y; } int ImageBuf::yend () const { return spec().y + spec().height; } int ImageBuf::zbegin () const { return spec().z; } int ImageBuf::zend () const { return spec().z + std::max(spec().depth,1); } int ImageBuf::xmin () const { return spec().x; } int ImageBuf::xmax () const { return spec().x + spec().width - 1; } int ImageBuf::ymin () const { return spec().y; } int ImageBuf::ymax () const { return spec().y + spec().height - 1; } int ImageBuf::zmin () const { return spec().z; } int ImageBuf::zmax () const { return spec().z + std::max(spec().depth,1) - 1; } int ImageBuf::oriented_width () const { const ImageBufImpl *impl (this->impl()); const ImageSpec &spec (impl->spec()); return impl->m_orientation <= 4 ? spec.width : spec.height; } int ImageBuf::oriented_height () const { const ImageBufImpl *impl (this->impl()); const ImageSpec &spec (impl->spec()); return impl->m_orientation <= 4 ? spec.height : spec.width; } int ImageBuf::oriented_x () const { const ImageBufImpl *impl (this->impl()); const ImageSpec &spec (impl->spec()); return impl->m_orientation <= 4 ? spec.x : spec.y; } int ImageBuf::oriented_y () const { const ImageBufImpl *impl (this->impl()); const ImageSpec &spec (impl->spec()); return impl->m_orientation <= 4 ? spec.y : spec.x; } int ImageBuf::oriented_full_width () const { const ImageBufImpl *impl (this->impl()); const ImageSpec &spec (impl->spec()); return impl->m_orientation <= 4 ? spec.full_width : spec.full_height; } int ImageBuf::oriented_full_height () const { const ImageBufImpl *impl (this->impl()); const ImageSpec &spec (impl->spec()); return impl->m_orientation <= 4 ? spec.full_height : spec.full_width; } int ImageBuf::oriented_full_x () const { const ImageBufImpl *impl (this->impl()); const ImageSpec &spec (impl->spec()); return impl->m_orientation <= 4 ? spec.full_x : spec.full_y; } int ImageBuf::oriented_full_y () const { const ImageBufImpl *impl (this->impl()); const ImageSpec &spec (impl->spec()); return impl->m_orientation <= 4 ? spec.full_y : spec.full_x; } void ImageBuf::set_full (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend) { ImageSpec &m_spec (impl()->specmod()); m_spec.full_x = xbegin; m_spec.full_y = ybegin; m_spec.full_z = zbegin; m_spec.full_width = xend - xbegin; m_spec.full_height = yend - ybegin; m_spec.full_depth = zend - zbegin; } void ImageBuf::set_full (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, const float *bordercolor) { ImageSpec &m_spec (impl()->specmod()); m_spec.full_x = xbegin; m_spec.full_y = ybegin; m_spec.full_z = zbegin; m_spec.full_width = xend - xbegin; m_spec.full_height = yend - ybegin; m_spec.full_depth = zend - zbegin; if (bordercolor) m_spec.attribute ("oiio:bordercolor", TypeDesc(TypeDesc::FLOAT,m_spec.nchannels), bordercolor); } ROI ImageBuf::roi () const { return get_roi(spec()); } ROI ImageBuf::roi_full () const { return get_roi_full(spec()); } void ImageBuf::set_roi_full (const ROI &newroi) { OIIO::set_roi_full (specmod(), newroi); } const void * ImageBufImpl::pixeladdr (int x, int y, int z) const { if (cachedpixels()) return NULL; validate_pixels (); x -= m_spec.x; y -= m_spec.y; z -= m_spec.z; size_t p = y * m_scanline_bytes + x * m_pixel_bytes + z * m_plane_bytes; return &(m_localpixels[p]); } void * ImageBufImpl::pixeladdr (int x, int y, int z) { validate_pixels (); if (cachedpixels()) return NULL; x -= m_spec.x; y -= m_spec.y; z -= m_spec.z; size_t p = y * m_scanline_bytes + x * m_pixel_bytes + z * m_plane_bytes; return &(m_localpixels[p]); } const void * ImageBuf::pixeladdr (int x, int y, int z) const { return impl()->pixeladdr (x, y, z); } void * ImageBuf::pixeladdr (int x, int y, int z) { return impl()->pixeladdr (x, y, z); } const void * ImageBuf::blackpixel () const { return impl()->blackpixel(); } bool ImageBufImpl::do_wrap (int &x, int &y, int &z, ImageBuf::WrapMode wrap) const { const ImageSpec &m_spec (this->spec()); // Double check that we're outside the data window -- supposedly a // precondition of calling this method. DASSERT (! (x >= m_spec.x && x < m_spec.x+m_spec.width && y >= m_spec.y && y < m_spec.y+m_spec.height && z >= m_spec.z && z < m_spec.z+m_spec.depth)); // Wrap based on the display window if (wrap == ImageBuf::WrapBlack) { // no remapping to do return false; // still outside the data window } else if (wrap == ImageBuf::WrapClamp) { x = OIIO::clamp (x, m_spec.full_x, m_spec.full_x+m_spec.full_width-1); y = OIIO::clamp (y, m_spec.full_y, m_spec.full_y+m_spec.full_height-1); z = OIIO::clamp (z, m_spec.full_z, m_spec.full_z+m_spec.full_depth-1); } else if (wrap == ImageBuf::WrapPeriodic) { wrap_periodic (x, m_spec.full_x, m_spec.full_width); wrap_periodic (y, m_spec.full_y, m_spec.full_height); wrap_periodic (z, m_spec.full_z, m_spec.full_depth); } else if (wrap == ImageBuf::WrapMirror) { wrap_mirror (x, m_spec.full_x, m_spec.full_width); wrap_mirror (y, m_spec.full_y, m_spec.full_height); wrap_mirror (z, m_spec.full_z, m_spec.full_depth); } else { ASSERT_MSG (0, "unknown wrap mode %d", (int)wrap); } // Now determine if the new position is within the data window return (x >= m_spec.x && x < m_spec.x+m_spec.width && y >= m_spec.y && y < m_spec.y+m_spec.height && z >= m_spec.z && z < m_spec.z+m_spec.depth); } bool ImageBuf::do_wrap (int &x, int &y, int &z, WrapMode wrap) const { return m_impl->do_wrap (x, y, z, wrap); } const void * ImageBufImpl::retile (int x, int y, int z, ImageCache::Tile* &tile, int &tilexbegin, int &tileybegin, int &tilezbegin, int &tilexend, bool exists, ImageBuf::WrapMode wrap) const { if (! exists) { // Special case -- (x,y,z) describes a location outside the data // window. Use the wrap mode to possibly give a meaningful data // proxy to point to. if (! do_wrap (x, y, z, wrap)) { // After wrapping, the new xyz point outside the data window. // So return the black pixel. return &m_blackpixel[0]; } // We've adjusted x,y,z, and know the wrapped coordinates are in the // pixel data window, so now fall through below to get the right // tile. } DASSERT (x >= m_spec.x && x < m_spec.x+m_spec.width && y >= m_spec.y && y < m_spec.y+m_spec.height && z >= m_spec.z && z < m_spec.z+m_spec.depth); int tw = m_spec.tile_width, th = m_spec.tile_height; int td = m_spec.tile_depth; DASSERT(m_spec.tile_depth >= 1); DASSERT (tile == NULL || tilexend == (tilexbegin+tw)); if (tile == NULL || x < tilexbegin || x >= tilexend || y < tileybegin || y >= (tileybegin+th) || z < tilezbegin || z >= (tilezbegin+td)) { // not the same tile as before if (tile) m_imagecache->release_tile (tile); int xtile = (x-m_spec.x) / tw; int ytile = (y-m_spec.y) / th; int ztile = (z-m_spec.z) / td; tilexbegin = m_spec.x + xtile*tw; tileybegin = m_spec.y + ytile*th; tilezbegin = m_spec.z + ztile*td; tilexend = tilexbegin + tw; tile = m_imagecache->get_tile (m_name, m_current_subimage, m_current_miplevel, x, y, z); if (! tile) return NULL; } size_t offset = ((z - tilezbegin) * (size_t) th + (y - tileybegin)) * (size_t) tw + (x - tilexbegin); offset *= m_spec.pixel_bytes(); DASSERTMSG (m_spec.pixel_bytes() == m_pixel_bytes, "%d vs %d", (int)m_spec.pixel_bytes(), (int)m_pixel_bytes); TypeDesc format; return (const char *)m_imagecache->tile_pixels (tile, format) + offset; } const void * ImageBuf::retile (int x, int y, int z, ImageCache::Tile* &tile, int &tilexbegin, int &tileybegin, int &tilezbegin, int &tilexend, bool exists, WrapMode wrap) const { return impl()->retile (x, y, z, tile, tilexbegin, tileybegin, tilezbegin, tilexend, exists, wrap); } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagespeed_test.cpp0000644000175000017500000005216512271062644023552 0ustar mfvmfv/* Copyright 2012 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "sysutil.h" #include "argparse.h" #include "ustring.h" #include "strutil.h" #include "timer.h" #include "unittest.h" #include #include #include #include OIIO_NAMESPACE_USING; static bool verbose = false; static int iterations = 1; static int ntrials = 1; static int numthreads = 0; static int autotile_size = 64; static bool iter_only = false; static std::vector input_filename; static std::string output_filename; static std::string output_format; static std::vector buffer; static ImageSpec bufspec, outspec; static ImageCache *imagecache = NULL; static imagesize_t total_image_pixels = 0; static int parse_files (int argc, const char *argv[]) { input_filename.push_back (ustring(argv[0])); return 0; } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap; ap.options ("imagespeed_test\n" OIIO_INTRO_STRING "\n" "Usage: imagespeed_test [options] filename...", "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose mode", "--threads %d", &numthreads, ustring::format("Number of threads (default: %d)", numthreads).c_str(), "--iters %d", &iterations, ustring::format("Number of iterations (default: %d)", iterations).c_str(), "--trials %d", &ntrials, "Number of trials", "--autotile %d", &autotile_size, ustring::format("Autotile size (when used; default: %d)", autotile_size).c_str(), "--iteronly", &iter_only, "Run iteration tests only (not read tests)", "-o %s", &output_filename, "Test output by writing to this file", "-od %s", &output_format, "Requested output format", NULL); if (ap.parse (argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } } static void time_read_image () { BOOST_FOREACH (ustring filename, input_filename) { ImageInput *in = ImageInput::open (filename.c_str()); ASSERT (in); in->read_image (TypeDesc::TypeFloat, &buffer[0]); in->close (); delete in; } } static void time_read_scanline_at_a_time () { BOOST_FOREACH (ustring filename, input_filename) { ImageInput *in = ImageInput::open (filename.c_str()); ASSERT (in); const ImageSpec &spec (in->spec()); size_t pixelsize = spec.nchannels * sizeof(float); imagesize_t scanlinesize = spec.width * pixelsize; for (int y = 0; y < spec.height; ++y) { in->read_scanline (y+spec.y, 0, TypeDesc::TypeFloat, &buffer[scanlinesize*y]); } in->close (); delete in; } } static void time_read_64_scanlines_at_a_time () { BOOST_FOREACH (ustring filename, input_filename) { ImageInput *in = ImageInput::open (filename.c_str()); ASSERT (in); const ImageSpec &spec (in->spec()); size_t pixelsize = spec.nchannels * sizeof(float); imagesize_t scanlinesize = spec.width * pixelsize; for (int y = 0; y < spec.height; y += 64) { in->read_scanlines (y+spec.y, std::min(y+spec.y+64, spec.y+spec.height), 0, TypeDesc::TypeFloat, &buffer[scanlinesize*y]); } in->close (); delete in; } } static void time_read_imagebuf () { imagecache->invalidate_all (true); BOOST_FOREACH (ustring filename, input_filename) { ImageBuf ib (filename.string(), imagecache); ib.read (0, 0, true, TypeDesc::TypeFloat); } } static void time_ic_get_pixels () { imagecache->invalidate_all (true); BOOST_FOREACH (ustring filename, input_filename) { const ImageSpec spec = (*imagecache->imagespec (filename)); imagecache->get_pixels (filename, 0, 0, spec.x, spec.x+spec.width, spec.y, spec.y+spec.height, spec.z, spec.z+spec.depth, TypeDesc::TypeFloat, &buffer[0]); } } static void test_read (const std::string &explanation, void (*func)(), int autotile=64, int autoscanline=1) { imagecache->invalidate_all (true); // Don't hold anything imagecache->attribute ("autotile", autotile); imagecache->attribute ("autoscanline", autoscanline); double t = time_trial (func, ntrials); double rate = double(total_image_pixels) / t; std::cout << " " << explanation << ": " << Strutil::timeintervalformat(t,2) << " = " << Strutil::format("%5.1f",rate/1.0e6) << " Mpel/s\n"; } static void time_write_image () { ImageOutput *out = ImageOutput::create (output_filename); ASSERT (out); bool ok = out->open (output_filename, outspec); ASSERT (ok); out->write_image (bufspec.format, &buffer[0]); out->close (); delete out; } static void time_write_scanline_at_a_time () { ImageOutput *out = ImageOutput::create (output_filename); ASSERT (out); bool ok = out->open (output_filename, outspec); ASSERT (ok); size_t pixelsize = outspec.nchannels * sizeof(float); imagesize_t scanlinesize = outspec.width * pixelsize; for (int y = 0; y < outspec.height; ++y) { out->write_scanline (y+outspec.y, outspec.z, bufspec.format, &buffer[scanlinesize*y]); } out->close (); delete out; } static void time_write_64_scanlines_at_a_time () { ImageOutput *out = ImageOutput::create (output_filename); ASSERT (out); bool ok = out->open (output_filename, outspec); ASSERT (ok); size_t pixelsize = outspec.nchannels * sizeof(float); imagesize_t scanlinesize = outspec.width * pixelsize; for (int y = 0; y < outspec.height; y += 64) { out->write_scanlines (y+outspec.y, std::min(y+outspec.y+64, outspec.y+outspec.height), outspec.z, bufspec.format, &buffer[scanlinesize*y]); } out->close (); delete out; } static void time_write_tile_at_a_time () { ImageOutput *out = ImageOutput::create (output_filename); ASSERT (out); bool ok = out->open (output_filename, outspec); ASSERT (ok); size_t pixelsize = outspec.nchannels * sizeof(float); imagesize_t scanlinesize = outspec.width * pixelsize; imagesize_t planesize = outspec.height * scanlinesize; for (int z = 0; z < outspec.depth; z += outspec.tile_depth) { for (int y = 0; y < outspec.height; y += outspec.tile_height) { for (int x = 0; x < outspec.width; x += outspec.tile_width) { out->write_tile (x+outspec.x, y+outspec.y, z+outspec.z, bufspec.format, &buffer[scanlinesize*y+pixelsize*x], pixelsize, scanlinesize, planesize); } } } out->close (); delete out; } static void time_write_tiles_row_at_a_time () { ImageOutput *out = ImageOutput::create (output_filename); ASSERT (out); bool ok = out->open (output_filename, outspec); ASSERT (ok); size_t pixelsize = outspec.nchannels * sizeof(float); imagesize_t scanlinesize = outspec.width * pixelsize; for (int z = 0; z < outspec.depth; z += outspec.tile_depth) { for (int y = 0; y < outspec.height; y += outspec.tile_height) { out->write_tiles (outspec.x, outspec.x+outspec.width, y+outspec.y, y+outspec.y+outspec.tile_height, z+outspec.z, z+outspec.z+outspec.tile_depth, bufspec.format, &buffer[scanlinesize*y], pixelsize /*xstride*/, scanlinesize /*ystride*/); } } out->close (); delete out; } static void time_write_imagebuf () { ImageBuf ib (output_filename, bufspec, &buffer[0]); // wrap the buffer ImageOutput *out = ImageOutput::create (output_filename); ASSERT (out); bool ok = out->open (output_filename, outspec); ASSERT (ok); ib.write (out); out->close (); delete out; } static void test_write (const std::string &explanation, void (*func)(), int tilesize = 0) { outspec.tile_width = tilesize; outspec.tile_height = tilesize; outspec.tile_depth = 1; double t = time_trial (func, ntrials); double rate = double(total_image_pixels) / t; std::cout << " " << explanation << ": " << Strutil::timeintervalformat(t,2) << " = " << Strutil::format("%5.1f",rate/1.0e6) << " Mpel/s\n"; } static float time_loop_pixels_1D (ImageBuf &ib, int iters) { ASSERT (ib.localpixels() && ib.pixeltype() == TypeDesc::TypeFloat); const ImageSpec &spec (ib.spec()); imagesize_t npixels = spec.image_pixels(); int nchannels = spec.nchannels; double sum = 0.0f; for (int i = 0; i < iters; ++i) { const float *f = (const float *) ib.pixeladdr (spec.x, spec.y, spec.z); ASSERT (f); for (imagesize_t p = 0; p < npixels; ++p) { sum += f[0]; f += nchannels; } } // std::cout << float(sum/npixels/iters) << "\n"; return float(sum/npixels/iters); } static float time_loop_pixels_3D (ImageBuf &ib, int iters) { ASSERT (ib.localpixels() && ib.pixeltype() == TypeDesc::TypeFloat); const ImageSpec &spec (ib.spec()); imagesize_t npixels = spec.image_pixels(); int nchannels = spec.nchannels; double sum = 0.0f; for (int i = 0; i < iters; ++i) { const float *f = (const float *) ib.pixeladdr (spec.x, spec.y, spec.z); ASSERT (f); for (int z = spec.z, ze = spec.z+spec.depth; z < ze; ++z) { for (int y = spec.y, ye = spec.y+spec.height; y < ye; ++y) { for (int x = spec.x, xe = spec.x+spec.width; x < xe; ++x) { sum += f[0]; f += nchannels; } } } } // std::cout << float(sum/npixels/iters) << "\n"; return float(sum/npixels/iters); } static float time_loop_pixels_3D_getchannel (ImageBuf &ib, int iters) { ASSERT (ib.pixeltype() == TypeDesc::TypeFloat); const ImageSpec &spec (ib.spec()); imagesize_t npixels = spec.image_pixels(); double sum = 0.0f; for (int i = 0; i < iters; ++i) { for (int z = spec.z, ze = spec.z+spec.depth; z < ze; ++z) { for (int y = spec.y, ye = spec.y+spec.height; y < ye; ++y) { for (int x = spec.x, xe = spec.x+spec.width; x < xe; ++x) { sum += ib.getchannel (x, y, 0, 0); } } } } // std::cout << float(sum/npixels/iters) << "\n"; return float(sum/npixels/iters); } static float time_iterate_pixels (ImageBuf &ib, int iters) { ASSERT (ib.pixeltype() == TypeDesc::TypeFloat); const ImageSpec &spec (ib.spec()); imagesize_t npixels = spec.image_pixels(); double sum = 0.0f; for (int i = 0; i < iters; ++i) { for (ImageBuf::ConstIterator p (ib); !p.done(); ++p) { sum += p[0]; } } // std::cout << float(sum/npixels/iters) << "\n"; return float(sum/npixels/iters); } static float time_iterate_pixels_slave_pos (ImageBuf &ib, int iters) { ASSERT (ib.pixeltype() == TypeDesc::TypeFloat); const ImageSpec &spec (ib.spec()); imagesize_t npixels = spec.image_pixels(); double sum = 0.0f; for (int i = 0; i < iters; ++i) { ImageBuf::ConstIterator slave (ib); for (ImageBuf::ConstIterator p (ib); !p.done(); ++p) { slave.pos (p.x(), p.y()); sum += p[0]; } } // std::cout << float(sum/npixels/iters) << "\n"; return float(sum/npixels/iters); } static float time_iterate_pixels_slave_incr (ImageBuf &ib, int iters) { ASSERT (ib.pixeltype() == TypeDesc::TypeFloat); const ImageSpec &spec (ib.spec()); imagesize_t npixels = spec.image_pixels(); double sum = 0.0f; for (int i = 0; i < iters; ++i) { ImageBuf::ConstIterator slave (ib); for (ImageBuf::ConstIterator p (ib); !p.done(); ++p) { sum += p[0]; ++slave; } } // std::cout << float(sum/npixels/iters) << "\n"; return float(sum/npixels/iters); } static void test_pixel_iteration (const std::string &explanation, float (*func)(ImageBuf&,int), bool preload, int iters=100, int autotile=64) { imagecache->invalidate_all (true); // Don't hold anything // Force the whole image to be read at once imagecache->attribute ("autotile", autotile); imagecache->attribute ("autoscanline", 1); ImageBuf ib (input_filename[0].string(), imagecache); ib.read (0, 0, preload, TypeDesc::TypeFloat); double t = time_trial (boost::bind(func,boost::ref(ib),iters), ntrials); double rate = double(ib.spec().image_pixels()) / (t/iters); std::cout << " " << explanation << ": " << Strutil::timeintervalformat(t/iters,3) << " = " << Strutil::format("%5.1f",rate/1.0e6) << " Mpel/s\n"; } static void set_dataformat (const std::string &output_format, ImageSpec &outspec) { if (output_format == "uint8") outspec.format = TypeDesc::UINT8; else if (output_format == "int8") outspec.format = TypeDesc::INT8; else if (output_format == "uint16") outspec.format = TypeDesc::UINT16; else if (output_format == "int16") outspec.format = TypeDesc::INT16; else if (output_format == "half") outspec.format = TypeDesc::HALF; else if (output_format == "float") outspec.format = TypeDesc::FLOAT; else if (output_format == "double") outspec.format = TypeDesc::DOUBLE; // Otherwise leave at the default } int main (int argc, char **argv) { getargs (argc, argv); if (input_filename.size() == 0) { std::cout << "Error: Must supply a filename.\n"; return -1; } OIIO::attribute ("threads", numthreads); imagecache = ImageCache::create (); imagecache->attribute ("forcefloat", 1); // Allocate a buffer big enough (for floats) bool all_scanline = true; total_image_pixels = 0; imagesize_t maxpelchans = 0; for (size_t i = 0; i < input_filename.size(); ++i) { ImageSpec spec; if (! imagecache->get_imagespec (input_filename[i], spec, 0, 0, true)) { std::cout << "File \"" << input_filename[i] << "\" could not be opened.\n"; return -1; } total_image_pixels += spec.image_pixels(); maxpelchans = std::max (maxpelchans, spec.image_pixels()*spec.nchannels); all_scanline &= (spec.tile_width == 0); } imagecache->invalidate_all (true); // Don't hold anything if (! iter_only) { std::cout << "Timing various ways of reading images:\n"; buffer.resize (maxpelchans*sizeof(float), 0); test_read ("read_image ", time_read_image, 0, 0); if (all_scanline) { test_read ("read_scanline (1 at a time) ", time_read_scanline_at_a_time, 0, 0); test_read ("read_scanlines (64 at a time) ", time_read_64_scanlines_at_a_time, 0, 0); } test_read ("ImageBuf read ", time_read_imagebuf, 0, 0); test_read ("ImageCache get_pixels ", time_ic_get_pixels, 0, 0); test_read ("ImageBuf read (autotile) ", time_read_imagebuf, autotile_size, 0); test_read ("ImageCache get_pixels (autotile) ", time_ic_get_pixels, autotile_size, 0); if (all_scanline) { // don't bother for tiled images test_read ("ImageBuf read (autotile+autoscanline) ", time_read_imagebuf, autotile_size, 1); test_read ("ImageCache get_pixels (autotile+autoscanline)", time_ic_get_pixels, autotile_size, 1); } if (verbose) std::cout << "\n" << imagecache->getstats(2) << "\n"; std::cout << "\n"; } if (output_filename.size()) { std::cout << "Timing ways of writing images:\n"; imagecache->get_imagespec (input_filename[0], bufspec, 0, 0, true); ImageOutput *out = ImageOutput::create (output_filename); ASSERT (out); bool supports_tiles = out->supports("tiles"); delete out; outspec = bufspec; bufspec.format = TypeDesc::FLOAT; set_dataformat (output_format, outspec); test_write ("write_image (scanline) ", time_write_image, 0); if (supports_tiles) test_write ("write_image (tiled) ", time_write_image, 64); test_write ("write_scanline (one at a time) ", time_write_scanline_at_a_time, 0); test_write ("write_scanlines (64 at a time) ", time_write_64_scanlines_at_a_time, 0); if (supports_tiles) { test_write ("write_tile (one at a time) ", time_write_tile_at_a_time, 64); test_write ("write_tiles (a whole row at a time) ", time_write_tiles_row_at_a_time, 64); } test_write ("ImageBuf::write (scanline) ", time_write_imagebuf, 0); if (supports_tiles) test_write ("ImageBuf::write (tiled) ", time_write_imagebuf, 64); std::cout << "\n"; } const int iters = 64; std::cout << "Timing ways of iterating over an image:\n"; test_pixel_iteration ("Loop pointers on loaded image (\"1D\") ", time_loop_pixels_1D, true, iters); test_pixel_iteration ("Loop pointers on loaded image (\"3D\") ", time_loop_pixels_3D, true, iters); test_pixel_iteration ("Loop + getchannel on loaded image (\"3D\")", time_loop_pixels_3D_getchannel, true, iters/32); test_pixel_iteration ("Loop + getchannel on cached image (\"3D\")", time_loop_pixels_3D_getchannel, false, iters/32); test_pixel_iteration ("Iterate over a loaded image ", time_iterate_pixels, true, iters); test_pixel_iteration ("Iterate over a cache image ", time_iterate_pixels, false, iters); test_pixel_iteration ("Iterate over a loaded image (pos slave) ", time_iterate_pixels_slave_pos, true, iters); test_pixel_iteration ("Iterate over a cache image (pos slave) ", time_iterate_pixels_slave_pos, false, iters); test_pixel_iteration ("Iterate over a loaded image (incr slave)", time_iterate_pixels_slave_incr, true, iters); test_pixel_iteration ("Iterate over a cache image (incr slave) ", time_iterate_pixels_slave_incr, false, iters); if (verbose) std::cout << "\n" << imagecache->getstats(2) << "\n"; ImageCache::destroy (imagecache); return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/spinlock_test.cpp0000644000175000017500000001235612271062644023267 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include "thread.h" #include "strutil.h" #include "timer.h" #include "argparse.h" #include "ustring.h" #include #include #include "unittest.h" OIIO_NAMESPACE_USING; // Test spin locks by creating a bunch of threads that all increment the // accumulator many times, protected by spin locks. If, at the end, the // accumulated value is equal to iterations*threads, then the spin locks // worked. static int iterations = 40000000; static int numthreads = 16; static int ntrials = 1; static bool verbose = false; static bool wedge = false; static spin_mutex print_mutex; // make the prints not clobber each other volatile long long accum = 0; float faccum = 0; spin_mutex mymutex; static void do_accum (int iterations) { if (verbose) { spin_lock lock(print_mutex); std::cout << "thread " << boost::this_thread::get_id() << ", accum = " << accum << "\n"; } #if 1 for (int i = 0; i < iterations; ++i) { spin_lock lock (mymutex); accum += 1; } #else // Alternate one that mixes in some math to make longer lock hold time, // and also more to do between locks. Interesting contrast in timings. float last = 0.0f; for (int i = 0; i < iterations; ++i) { last = fmodf (sinf(last), 1.0f); spin_lock lock (mymutex); accum += 1; faccum = fmod (sinf(faccum+last), 1.0f); } #endif } void test_spinlock (int numthreads, int iterations) { accum = 0; boost::thread_group threads; for (int i = 0; i < numthreads; ++i) { threads.create_thread (boost::bind(do_accum,iterations)); } ASSERT ((int)threads.size() == numthreads); threads.join_all (); OIIO_CHECK_EQUAL (accum, ((long long)iterations * (long long)numthreads)); } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap; ap.options ("spinlock_test\n" OIIO_INTRO_STRING "\n" "Usage: spinlock_test [options]", // "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose mode", "--threads %d", &numthreads, ustring::format("Number of threads (default: %d)", numthreads).c_str(), "--iters %d", &iterations, ustring::format("Number of iterations (default: %d)", iterations).c_str(), "--trials %d", &ntrials, "Number of trials", "--wedge", &wedge, "Do a wedge test", NULL); if (ap.parse (argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } } int main (int argc, char *argv[]) { getargs (argc, argv); std::cout << "hw threads = " << boost::thread::hardware_concurrency() << "\n"; std::cout << "threads\ttime (best of " << ntrials << ")\n"; std::cout << "-------\t----------\n"; static int threadcounts[] = { 1, 2, 4, 8, 12, 16, 20, 24, 28, 32, 64, 128, 1024, 1<<30 }; for (int i = 0; threadcounts[i] <= numthreads; ++i) { int nt = wedge ? threadcounts[i] : numthreads; int its = iterations/nt; double range; double t = time_trial (boost::bind(test_spinlock,nt,its), ntrials, &range); std::cout << Strutil::format ("%2d\t%5.1f range %.2f\t(%d iters/thread)\n", nt, t, range, its); if (! wedge) break; // don't loop if we're not wedging } return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebuf_test.cpp0000644000175000017500000002274612271062644023230 0ustar mfvmfv/* Copyright 2012 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "sysutil.h" #include "unittest.h" #include OIIO_NAMESPACE_USING; inline int test_wrap (wrap_impl wrap, int coord, int origin, int width) { wrap (coord, origin, width); return coord; } void test_wrapmodes () { const int ori = 0; const int w = 4; static int val[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -10}, cla[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3}, per[] = { 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1}, mir[] = { 1, 2, 3, 3, 2, 1, 0, 0, 1, 2, 3, 3, 2, 1, 0, 0, 1}; for (int i = 0; val[i] > -10; ++i) { OIIO_CHECK_EQUAL (test_wrap (wrap_clamp, val[i], ori, w), cla[i]); OIIO_CHECK_EQUAL (test_wrap (wrap_periodic, val[i], ori, w), per[i]); OIIO_CHECK_EQUAL (test_wrap (wrap_periodic_pow2, val[i], ori, w), per[i]); OIIO_CHECK_EQUAL (test_wrap (wrap_mirror, val[i], ori, w), mir[i]); } } // Test iterators template void iterator_read_test () { const int WIDTH = 4, HEIGHT = 4, CHANNELS = 3; static float buf[HEIGHT][WIDTH][CHANNELS] = { { {0,0,0}, {1,0,1}, {2,0,2}, {3,0,3} }, { {0,1,4}, {1,1,5}, {2,1,6}, {3,1,7} }, { {0,2,8}, {1,2,9}, {2,2,10}, {3,2,11} }, { {0,3,12}, {1,3,13}, {2,3,14}, {3,3,15} } }; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); ImageBuf A (spec, buf); ITERATOR p (A); OIIO_CHECK_EQUAL (p[0], 0.0f); OIIO_CHECK_EQUAL (p[1], 0.0f); OIIO_CHECK_EQUAL (p[2], 0.0f); // Explicit position p.pos (2, 1); OIIO_CHECK_EQUAL (p.x(), 2); OIIO_CHECK_EQUAL (p.y(), 1); OIIO_CHECK_EQUAL (p[0], 2.0f); OIIO_CHECK_EQUAL (p[1], 1.0f); OIIO_CHECK_EQUAL (p[2], 6.0f); // Iterate a few times ++p; OIIO_CHECK_EQUAL (p.x(), 3); OIIO_CHECK_EQUAL (p.y(), 1); OIIO_CHECK_EQUAL (p[0], 3.0f); OIIO_CHECK_EQUAL (p[1], 1.0f); OIIO_CHECK_EQUAL (p[2], 7.0f); ++p; OIIO_CHECK_EQUAL (p.x(), 0); OIIO_CHECK_EQUAL (p.y(), 2); OIIO_CHECK_EQUAL (p[0], 0.0f); OIIO_CHECK_EQUAL (p[1], 2.0f); OIIO_CHECK_EQUAL (p[2], 8.0f); std::cout << "iterator_read_test result:"; int i = 0; for (ITERATOR p (A); !p.done(); ++p, ++i) { if ((i % 4) == 0) std::cout << "\n "; std::cout << " " << p[0] << ' ' << p[1] << ' ' << p[2]; } std::cout << "\n"; } // Test iterators template void iterator_wrap_test (ImageBuf::WrapMode wrap, std::string wrapname) { const int WIDTH = 4, HEIGHT = 4, CHANNELS = 3; static float buf[HEIGHT][WIDTH][CHANNELS] = { { {0,0,0}, {1,0,1}, {2,0,2}, {3,0,3} }, { {0,1,4}, {1,1,5}, {2,1,6}, {3,1,7} }, { {0,2,8}, {1,2,9}, {2,2,10}, {3,2,11} }, { {0,3,12}, {1,3,13}, {2,3,14}, {3,3,15} } }; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); ImageBuf A (spec, buf); std::cout << "iterator_wrap_test " << wrapname << ":"; int i = 0; int noutside = 0; for (ITERATOR p (A, ROI(-2, WIDTH+2, -2, HEIGHT+2), wrap); !p.done(); ++p, ++i) { if ((i % 8) == 0) std::cout << "\n "; std::cout << " " << p[0] << ' ' << p[1] << ' ' << p[2]; // Check wraps if (! p.exists()) { ++noutside; if (wrap == ImageBuf::WrapBlack) { OIIO_CHECK_EQUAL (p[0], 0.0f); OIIO_CHECK_EQUAL (p[1], 0.0f); OIIO_CHECK_EQUAL (p[2], 0.0f); } else if (wrap == ImageBuf::WrapClamp) { ITERATOR q = p; q.pos (clamp (p.x(), 0, WIDTH-1), clamp (p.y(), 0, HEIGHT-1)); OIIO_CHECK_EQUAL (p[0], q[0]); OIIO_CHECK_EQUAL (p[1], q[1]); OIIO_CHECK_EQUAL (p[2], q[2]); } else if (wrap == ImageBuf::WrapPeriodic) { ITERATOR q = p; q.pos (p.x() % WIDTH, p.y() % HEIGHT); OIIO_CHECK_EQUAL (p[0], q[0]); OIIO_CHECK_EQUAL (p[1], q[1]); OIIO_CHECK_EQUAL (p[2], q[2]); } else if (wrap == ImageBuf::WrapMirror) { ITERATOR q = p; int x = p.x(), y = p.y(); wrap_mirror (x, 0, WIDTH); wrap_mirror (y, 0, HEIGHT); q.pos (x, y); OIIO_CHECK_EQUAL (p[0], q[0]); OIIO_CHECK_EQUAL (p[1], q[1]); OIIO_CHECK_EQUAL (p[2], q[2]); } } } std::cout << "\n"; OIIO_CHECK_EQUAL (noutside, 48); // Should be 48 wrapped pixels } // Tests ImageBuf construction from application buffer void ImageBuf_test_appbuffer () { const int WIDTH = 8; const int HEIGHT = 8; const int CHANNELS = 1; static float buf[HEIGHT][WIDTH] = { { 0, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0, 0, 1, 0 }, { 0, 1, 0, 0, 0, 0, 0, 1 }, { 0, 0, 1, 0, 0, 0, 1, 0 }, { 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } }; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); ImageBuf A (spec, buf); // Make sure A now points to the buffer OIIO_CHECK_EQUAL ((void *)A.pixeladdr (0, 0, 0), (void *)buf); // write it A.write ("A.tif"); // Read it back and make sure it matches the original ImageBuf B ("A.tif"); for (int y = 0; y < HEIGHT; ++y) for (int x = 0; x < WIDTH; ++x) OIIO_CHECK_EQUAL (A.getchannel (x, y, 0, 0), B.getchannel (x, y, 0, 0)); } // Tests histogram computation. void histogram_computation_test () { const int INPUT_WIDTH = 64; const int INPUT_HEIGHT = 64; const int INPUT_CHANNEL = 0; const int HISTOGRAM_BINS = 256; const int SPIKE1 = 51; // 0.2f in range 0->1 maps to 51 in range 0->255 const int SPIKE2 = 128; // 0.5f in range 0->1 maps to 128 in range 0->255 const int SPIKE3 = 204; // 0.8f in range 0->1 maps to 204 in range 0->255 const int SPIKE1_COUNT = INPUT_WIDTH * 8; const int SPIKE2_COUNT = INPUT_WIDTH * 16; const int SPIKE3_COUNT = INPUT_WIDTH * 40; // Create input image with three regions with different pixel values. ImageSpec spec (INPUT_WIDTH, INPUT_HEIGHT, 1, TypeDesc::FLOAT); ImageBuf A (spec); float value[] = {0.2f}; ImageBufAlgo::fill (A, value, ROI(0, INPUT_WIDTH, 0, 8)); value[0] = 0.5f; ImageBufAlgo::fill (A, value, ROI(0, INPUT_WIDTH, 8, 24)); value[0] = 0.8f; ImageBufAlgo::fill (A, value, ROI(0, INPUT_WIDTH, 24, 64)); // Compute A's histogram. std::vector hist; ImageBufAlgo::histogram (A, INPUT_CHANNEL, hist, HISTOGRAM_BINS); // Does the histogram size equal the number of bins? OIIO_CHECK_EQUAL (hist.size(), (imagesize_t)HISTOGRAM_BINS); // Are the histogram values as expected? OIIO_CHECK_EQUAL (hist[SPIKE1], (imagesize_t)SPIKE1_COUNT); OIIO_CHECK_EQUAL (hist[SPIKE2], (imagesize_t)SPIKE2_COUNT); OIIO_CHECK_EQUAL (hist[SPIKE3], (imagesize_t)SPIKE3_COUNT); for (int i = 0; i < HISTOGRAM_BINS; i++) if (i!=SPIKE1 && i!=SPIKE2 && i!=SPIKE3) OIIO_CHECK_EQUAL (hist[i], 0); } int main (int argc, char **argv) { test_wrapmodes (); // Lots of tests related to ImageBuf::Iterator iterator_read_test > (); iterator_read_test > (); iterator_wrap_test > (ImageBuf::WrapBlack, "black"); iterator_wrap_test > (ImageBuf::WrapClamp, "clamp"); iterator_wrap_test > (ImageBuf::WrapPeriodic, "periodic"); iterator_wrap_test > (ImageBuf::WrapMirror, "mirror"); ImageBuf_test_appbuffer (); histogram_computation_test (); return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/timer_test.cpp0000644000175000017500000001114612271062644022561 0ustar mfvmfv/* Copyright 2012 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "imageio.h" #include "sysutil.h" #include "argparse.h" #include "strutil.h" #include "timer.h" #include "unittest.h" #include OIIO_NAMESPACE_USING; static int parse_files (int argc, const char *argv[]) { // input_filename = ustring(argv[0]); return 0; } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap; ap.options ("timer_test\n" OIIO_INTRO_STRING "\n" "Usage: timer_test [options]", "%*", parse_files, "", "--help", &help, "Print help message", NULL); if (ap.parse (argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } } int main (int argc, char **argv) { getargs (argc, argv); // First, just compute and print how expensive a Timer begin/end is, // in cycles per second. { Timer timer; int n = 1000000; for (int i = 0; i < n; ++i) { Timer t; t(); // force getting the time } std::cout << "Timer begin/end cost is " << double(n)/timer() << " /sec\n"; } const int interval = 100000; // 1/10 sec const double eps = 1e-2; // slop we allow in our timings // Verify that Timer(false) doesn't start Timer all(true); Timer selective(false); Sysutil::usleep (interval); OIIO_CHECK_EQUAL_THRESH (selective(), 0.0, eps); OIIO_CHECK_EQUAL_THRESH (all(), 0.1, eps); // Make sure start/stop work selective.start (); Sysutil::usleep (interval); OIIO_CHECK_EQUAL_THRESH (selective(), 0.1, eps); OIIO_CHECK_EQUAL_THRESH (all(), 0.2, eps); selective.stop (); Sysutil::usleep (interval); OIIO_CHECK_EQUAL_THRESH (selective(), 0.1, eps); OIIO_CHECK_EQUAL_THRESH (all(), 0.3, eps); std::cout << "Checkpoint: All " << all() << " selective " << selective() << "\n"; // Test reset() -- should set selective to 0 and turn it off selective.reset(); Sysutil::usleep (interval); OIIO_CHECK_EQUAL_THRESH (selective(), 0.0, eps); OIIO_CHECK_EQUAL_THRESH (all(), 0.4, eps); selective.start(); Sysutil::usleep (interval); OIIO_CHECK_EQUAL_THRESH (selective(), 0.1, eps); OIIO_CHECK_EQUAL_THRESH (all(), 0.5, eps); // Test lap() double lap = selective.lap(); // lap=.1, select.time_since_start OIIO_CHECK_EQUAL_THRESH (lap, 0.1, eps); OIIO_CHECK_EQUAL_THRESH (selective(), 0.1, eps); OIIO_CHECK_EQUAL_THRESH (selective.time_since_start(), 0.0, eps); OIIO_CHECK_EQUAL_THRESH (all(), 0.5, eps); Sysutil::usleep (interval); OIIO_CHECK_EQUAL_THRESH (selective(), 0.2, eps); OIIO_CHECK_EQUAL_THRESH (selective.time_since_start(), 0.1, eps); OIIO_CHECK_EQUAL_THRESH (all(), 0.6, eps); std::cout << "Checkpoint2: All " << all() << " selective " << selective() << "\n"; return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/ustring_test.cpp0000644000175000017500000000541312271062644023134 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include "thread.h" #include "ustring.h" #include "strutil.h" #include "unittest.h" OIIO_NAMESPACE_USING; // Test ustring's internal locks by creating a bunch of strings in many // threads simultaneously. Hopefully something will crash if the // internal table is not being locked properly. static void create_lotso_ustrings () { std::cout << "thread " << boost::this_thread::get_id() << "\n"; char buf[20]; const int iterations = 1000000; for (int i = 0; i < iterations; ++i) { sprintf (buf, "%d", i); ustring s (buf); } } void test_ustring_lock () { std::cout << "hw threads = " << boost::thread::hardware_concurrency() << "\n"; const int numthreads = 16; boost::thread_group threads; for (int i = 0; i < numthreads; ++i) { threads.create_thread (&create_lotso_ustrings); } std::cout << "Created " << threads.size() << " threads\n"; threads.join_all (); std::cout << "\n" << ustring::getstats() << "\n"; OIIO_CHECK_ASSERT (true); // If we make it here without crashing, pass } int main (int argc, char *argv[]) { test_ustring_lock (); return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagespec_test.cpp0000644000175000017500000002020312271062644023370 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "imageio.h" #include "fmath.h" #include "unittest.h" OIIO_NAMESPACE_USING; void test_imagespec_pixels () { // images with dimensions > 2^16 (65536) on a side have > 2^32 pixels const long long WIDTH = 456789; const long long HEIGHT = 345678; const long long CHANNELS=3; const long long BYTES_IN_FLOAT = 4; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); std::cout << "sizeof (int) = " << sizeof (int) << std::endl; std::cout << "sizeof (long) = " << sizeof (long) << std::endl; std::cout << "sizeof (long long) = " << sizeof (long long) << std::endl; std::cout << "sizeof (size_t) = " << sizeof (size_t) << std::endl; std::cout << "sizeof (imagesize_t) = " << sizeof (imagesize_t) << std::endl; std::cout << "sizeof (stride_t) = " << sizeof (stride_t) << std::endl; std::cout << "sizeof (float) = " << sizeof (float) << std::endl; OIIO_CHECK_EQUAL ((size_t)BYTES_IN_FLOAT, sizeof (float)); OIIO_CHECK_EQUAL (CHANNELS, spec.nchannels); OIIO_CHECK_EQUAL (WIDTH, spec.width); OIIO_CHECK_EQUAL (HEIGHT, spec.height); OIIO_CHECK_EQUAL (1, spec.depth); OIIO_CHECK_EQUAL (WIDTH, spec.full_width); OIIO_CHECK_EQUAL (HEIGHT, spec.full_height); OIIO_CHECK_EQUAL (1, spec.full_depth); // FIXME(nemec): uncomment after figuring out linking // OIIO_CHECK_EQUAL (TypeDesc::UINT8, spec.format); OIIO_CHECK_EQUAL ((size_t)BYTES_IN_FLOAT, spec.channel_bytes ()); OIIO_CHECK_EQUAL ((size_t)(BYTES_IN_FLOAT*CHANNELS), spec.pixel_bytes ()); OIIO_CHECK_EQUAL ((imagesize_t)(BYTES_IN_FLOAT*CHANNELS*WIDTH), spec.scanline_bytes ()); OIIO_CHECK_EQUAL ((imagesize_t)(WIDTH*HEIGHT), spec.image_pixels ()); // check that the magnitude is right (not clamped) -- should be about > 2^40 long long expected_bytes = BYTES_IN_FLOAT*CHANNELS*WIDTH*HEIGHT; // log (x) / log (2) = log2 (x) // log (2^32) / log (2) = log2 (2^32) = 32 // log (2^32) * M_LOG2E = 32 double log2_result = log ((double)expected_bytes) * M_LOG2E; OIIO_CHECK_LT (40, log2_result); OIIO_CHECK_EQUAL ((imagesize_t)expected_bytes, spec.image_bytes ()); std::cout << "expected_bytes = " << expected_bytes << ", log " << log ((double)expected_bytes) << std::endl; } static void metadata_val_test (void *data, int num_elements, TypeDesc type, std::string& val) { static ImageSpec spec; ImageIOParameter p; p.init ("name", type, num_elements, data); val = spec.metadata_val (p); } void test_imagespec_metadata_val () { std::string ret; int imatrix[] = {100, 200, 300, 400}; metadata_val_test (&imatrix[0], 1, TypeDesc::TypeInt, ret); OIIO_CHECK_EQUAL (ret, "100"); metadata_val_test (imatrix, sizeof (imatrix)/sizeof(int), TypeDesc::TypeInt, ret); OIIO_CHECK_EQUAL (ret, "100, 200, 300, 400"); OIIO_CHECK_NE (ret, "100, 200, 300, 400,"); float fmatrix[] = {10.12, 200.34, 300.11, 400.9}; metadata_val_test (&fmatrix[0], 1, TypeDesc::TypeFloat, ret); OIIO_CHECK_EQUAL (ret, "10.12"); metadata_val_test (fmatrix, sizeof (fmatrix) / sizeof (float), TypeDesc::TypeFloat, ret); OIIO_CHECK_EQUAL (ret, "10.12, 200.34, 300.11, 400.9"); OIIO_CHECK_NE (ret, "10, 200, 300, 400"); OIIO_CHECK_NE (ret, "10.12, 200.34, 300.11, 400.9,"); unsigned long long ullmatrix[] = {0xffffffffffffffffLL, 0xffffffffffffffffLL}; metadata_val_test (&ullmatrix, 1, TypeDesc::UINT64, ret); OIIO_CHECK_EQUAL (ret, "18446744073709551615"); metadata_val_test (&ullmatrix, sizeof (ullmatrix) / sizeof (unsigned long long), TypeDesc::UINT64, ret); OIIO_CHECK_EQUAL (ret, "18446744073709551615, 18446744073709551615"); OIIO_CHECK_NE (ret, "-1, -1"); OIIO_CHECK_NE (ret, "18446744073709551615, 18446744073709551615,"); const char* smatrix[] = {"this is \"a test\"", "this is another test"}; metadata_val_test (smatrix, 1, TypeDesc::TypeString, ret); OIIO_CHECK_EQUAL (ret, "\"this is \"a test\"\""); OIIO_CHECK_NE (ret, smatrix[0]); OIIO_CHECK_NE (ret, "\"this is \"a test\"\","); metadata_val_test (smatrix, sizeof (smatrix) / sizeof (char *), TypeDesc::TypeString, ret); OIIO_CHECK_EQUAL (ret, "\"this is \"a test\"\", \"this is another test\""); float matrix16[2][16] = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}}; metadata_val_test (&matrix16[0], 1, TypeDesc::TypeMatrix, ret); OIIO_CHECK_EQUAL (ret, "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16"); OIIO_CHECK_NE (ret, "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16,"); metadata_val_test (matrix16, sizeof (matrix16) / (16 * sizeof (float)), TypeDesc::TypeMatrix, ret); OIIO_CHECK_EQUAL (ret, "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16, 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25"); } static void attribute_test (const std::string &data, TypeDesc type, std::string &ret) { ImageSpec spec; spec.attribute ("name", type, data); ret = spec.metadata_val (spec.extra_attribs[0]); } void test_imagespec_attribute_from_string () { TypeDesc type = TypeDesc::TypeInt; std::string ret, data, invalid_data; data = "1, 2, 3, 4, 5, 6"; attribute_test (data, type, ret); OIIO_CHECK_EQUAL (ret, data); type = TypeDesc::TypeFloat; data = "1.23, 34.23, 35.11, 99.99, 1999.99"; attribute_test (data, type, ret); OIIO_CHECK_EQUAL (ret, data); type = TypeDesc::UINT64; data = "18446744073709551615, 18446744073709551615"; attribute_test (data, type, ret); OIIO_CHECK_EQUAL (ret, data); invalid_data = "18446744073709551615"; OIIO_CHECK_NE (ret, invalid_data); invalid_data = "18446744073709551614, 18446744073709551615"; OIIO_CHECK_NE (ret, invalid_data); type = TypeDesc::INT64; data = "-1, 9223372036854775807"; attribute_test (data, type, ret); OIIO_CHECK_EQUAL (ret, data); invalid_data = "-1"; OIIO_CHECK_NE (ret, invalid_data); type = TypeDesc::TypeMatrix; data = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16, 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36"; attribute_test (data, type, ret); OIIO_CHECK_EQUAL (ret, data); invalid_data = data = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36"; OIIO_CHECK_NE (ret, invalid_data); type = TypeDesc::TypeString; data = "\"imageParameter:param\""; attribute_test (data, type, ret); OIIO_CHECK_EQUAL (ret, data); } int main (int argc, char *argv[]) { test_imagespec_pixels (); test_imagespec_metadata_val (); test_imagespec_attribute_from_string (); return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/maketexture.cpp0000644000175000017500000016423412271062644022747 0ustar mfvmfv/* Copyright 2013 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "argparse.h" #include "dassert.h" #include "filesystem.h" #include "fmath.h" #include "strutil.h" #include "sysutil.h" #include "timer.h" #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #include "thread.h" #include "filter.h" OIIO_NAMESPACE_USING static spin_mutex maketx_mutex; // for anything that needs locking static Filter2D * setup_filter (const ImageSpec &dstspec, const ImageSpec &srcspec, std::string filtername = std::string()) { // Resize ratio float wratio = float(dstspec.full_width) / float(srcspec.full_width); float hratio = float(dstspec.full_height) / float(srcspec.full_height); float w = std::max (1.0f, wratio); float h = std::max (1.0f, hratio); // Default filter, if none supplied if (filtername.empty()) { // No filter name supplied -- pick a good default if (wratio > 1.0f || hratio > 1.0f) filtername = "blackman-harris"; else filtername = "lanczos3"; } // Figure out the recommended filter width for the named filter for (int i = 0, e = Filter2D::num_filters(); i < e; ++i) { FilterDesc d; Filter2D::get_filterdesc (i, &d); if (filtername == d.name) return Filter2D::create (filtername, w*d.width, h*d.width); } return NULL; // couldn't find a matching name } static TypeDesc set_prman_options(TypeDesc out_dataformat, ImageSpec &configspec) { // Force separate planar image handling, and also emit prman metadata configspec.attribute ("planarconfig", "separate"); configspec.attribute ("maketx:prman_metadata", 1); // 8-bit : 64x64 if (out_dataformat == TypeDesc::UINT8 || out_dataformat == TypeDesc::INT8) { configspec.tile_width = 64; configspec.tile_height = 64; } // 16-bit : 64x32 // Force u16 -> s16 // In prman's txmake (last tested in 15.0) // specifying -short creates a signed int representation if (out_dataformat == TypeDesc::UINT16) out_dataformat = TypeDesc::INT16; if (out_dataformat == TypeDesc::INT16) { configspec.tile_width = 64; configspec.tile_height = 32; } // Float: 32x32 // In prman's txmake (last tested in 15.0) // specifying -half or -float make 32x32 tile size if (out_dataformat == TypeDesc::DOUBLE) out_dataformat = TypeDesc::FLOAT; if (out_dataformat == TypeDesc::HALF || out_dataformat == TypeDesc::FLOAT) { configspec.tile_width = 32; configspec.tile_height = 32; } return out_dataformat; } static TypeDesc set_oiio_options(TypeDesc out_dataformat, ImageSpec &configspec) { // Interleaved channels are faster to read configspec.attribute ("planarconfig", "contig"); // Force fixed tile-size across the board configspec.tile_width = 64; configspec.tile_height = 64; return out_dataformat; } static std::string datestring (time_t t) { struct tm mytm; Sysutil::get_local_time (&t, &mytm); return Strutil::format ("%4d:%02d:%02d %2d:%02d:%02d", mytm.tm_year+1900, mytm.tm_mon+1, mytm.tm_mday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec); } // Copy src into dst, but only for the range [x0,x1) x [y0,y1). template static bool copy_block_ (ImageBuf &dst, const ImageBuf &src, ROI roi=ROI()) { int nchannels = dst.spec().nchannels; ASSERT (src.spec().nchannels == nchannels); ROI image_roi = get_roi (dst.spec()); if (roi.defined()) image_roi = roi_intersection (image_roi, roi); ImageBuf::Iterator d (dst, image_roi); ImageBuf::ConstIterator s (src, image_roi, ImageBuf::WrapBlack); for ( ; ! d.done(); ++d, ++s) { for (int c = 0; c < nchannels; ++c) d[c] = s[c]; } return true; } // Copy src into dst, but only for the range [x0,x1) x [y0,y1). static bool copy_block (ImageBuf &dst, const ImageBuf &src, ROI roi) { ASSERT (dst.spec().format == TypeDesc::TypeFloat); OIIO_DISPATCH_TYPES ("copy_block", copy_block_, src.spec().format, dst, src, roi); } template static void interppixel_NDC_clamped (const ImageBuf &buf, float x, float y, float *pixel, bool envlatlmode) { int fx = buf.spec().full_x; int fy = buf.spec().full_y; int fw = buf.spec().full_width; int fh = buf.spec().full_height; x = static_cast(fx) + x * static_cast(fw); y = static_cast(fy) + y * static_cast(fh); int n = buf.spec().nchannels; float *p0 = ALLOCA(float, 4*n), *p1 = p0+n, *p2 = p1+n, *p3 = p2+n; x -= 0.5f; y -= 0.5f; int xtexel, ytexel; float xfrac, yfrac; xfrac = floorfrac (x, &xtexel); yfrac = floorfrac (y, &ytexel); // Get the four texels ImageBuf::ConstIterator it (buf, ROI(xtexel, xtexel+2, ytexel, ytexel+2), ImageBuf::WrapClamp); for (int c = 0; c < n; ++c) p0[c] = it[c]; ++it; for (int c = 0; c < n; ++c) p1[c] = it[c]; ++it; for (int c = 0; c < n; ++c) p2[c] = it[c]; ++it; for (int c = 0; c < n; ++c) p3[c] = it[c]; if (envlatlmode) { // For latlong environment maps, in order to conserve energy, we // must weight the pixels by sin(t*PI) because pixels closer to // the pole are actually less area on the sphere. Doing this // wrong will tend to over-represent the high latitudes in // low-res MIP levels. We fold the area weighting into our // linear interpolation by adjusting yfrac. int ynext = Imath::clamp (ytexel+1, buf.ymin(), buf.ymax()); ytexel = Imath::clamp (ytexel, buf.ymin(), buf.ymax()); float w0 = (1.0f - yfrac) * sinf ((float)M_PI * (ytexel+0.5f)/(float)fh); float w1 = yfrac * sinf ((float)M_PI * (ynext+0.5f)/(float)fh); yfrac = w1 / (w0 + w1); } // Bilinearly interpolate bilerp (p0, p1, p2, p3, xfrac, yfrac, n, pixel); } // Resize src into dst, relying on the linear interpolation of // interppixel_NDC_full or interppixel_NDC_clamped, for the pixel range. template static bool resize_block_ (ImageBuf &dst, const ImageBuf &src, ROI roi, bool envlatlmode) { int x0 = roi.xbegin, x1 = roi.xend, y0 = roi.ybegin, y1 = roi.yend; const ImageSpec &srcspec (src.spec()); bool src_is_crop = (srcspec.x > srcspec.full_x || srcspec.y > srcspec.full_y || srcspec.z > srcspec.full_z || srcspec.x+srcspec.width < srcspec.full_x+srcspec.full_width || srcspec.y+srcspec.height < srcspec.full_y+srcspec.full_height || srcspec.z+srcspec.depth < srcspec.full_z+srcspec.full_depth); const ImageSpec &dstspec (dst.spec()); float *pel = (float *) alloca (dstspec.pixel_bytes()); float xoffset = (float) dstspec.full_x; float yoffset = (float) dstspec.full_y; float xscale = 1.0f / (float)dstspec.full_width; float yscale = 1.0f / (float)dstspec.full_height; int nchannels = dst.nchannels(); ASSERT (dst.spec().format == TypeDesc::TypeFloat); ImageBuf::Iterator d (dst, roi); for (int y = y0; y < y1; ++y) { float t = (y+0.5f)*yscale + yoffset; for (int x = x0; x < x1; ++x, ++d) { float s = (x+0.5f)*xscale + xoffset; if (src_is_crop) src.interppixel_NDC_full (s, t, pel); else interppixel_NDC_clamped (src, s, t, pel, envlatlmode); for (int c = 0; c < nchannels; ++c) d[c] = pel[c]; } } return true; } // Helper function to compute the first bilerp pass into a scanline buffer template static void halve_scanline(const SRCTYPE *s, const int nchannels, size_t sw, float *dst) { for (size_t i = 0; i < sw; i += 2, s += nchannels) { for (int j = 0; j < nchannels; ++j, ++dst, ++s) *dst = 0.5f * (float) (*s + *(s + nchannels)); } } // Bilinear resize performed as a 2-pass filter. // Optimized to assume that the images are contiguous. template static bool resize_block_2pass (ImageBuf &dst, const ImageBuf &src, ROI roi, bool allow_shift) { // Two-pass filtering introduces a half-pixel shift for odd resolutions. // Revert to correct bilerp sampling unless shift is explicitly allowed. if (!allow_shift && (src.spec().width % 2 || src.spec().height % 2)) return resize_block_(dst, src, roi, false); DASSERT(roi.ybegin + roi.height() <= dst.spec().height); // Allocate two scanline buffers to hold the result of the first pass const int nchannels = dst.nchannels(); const size_t row_elem = roi.width() * nchannels; // # floats in scanline boost::scoped_array S0 (new float [row_elem]); boost::scoped_array S1 (new float [row_elem]); // We know that the buffers created for mipmapping are all contiguous, // so we can skip the iterators for a bilerp resize entirely along with // any NDC -> pixel math, and just directly traverse pixels. const SRCTYPE *s = (const SRCTYPE *)src.localpixels(); SRCTYPE *d = (SRCTYPE *)dst.localpixels(); ASSERT(s && d); // Assume contig bufs d += roi.ybegin * dst.spec().width * nchannels; // Top of dst ROI const size_t ystride = src.spec().width * nchannels;// Scanline offset s += 2 * roi.ybegin * ystride; // Top of src ROI // Run through destination rows, doing the two-pass bilerp filter const size_t dw = roi.width(), dh = roi.height(); // Loop invariants const size_t sw = dw * 2; // Handle odd res for (size_t y = 0; y < dh; ++y) { // For each dst ROI row halve_scanline(s, nchannels, sw, &S0[0]); s += ystride; halve_scanline(s, nchannels, sw, &S1[0]); s += ystride; const float *s0 = &S0[0], *s1 = &S1[0]; for (size_t x = 0; x < dw; ++x) { // For each dst ROI col for (int i = 0; i < nchannels; ++i, ++s0, ++s1, ++d) *d = (SRCTYPE) (0.5f * (*s0 + *s1)); // Average vertically } } return true; } static bool resize_block (ImageBuf &dst, const ImageBuf &src, ROI roi, bool envlatlmode, bool allow_shift) { const ImageSpec &srcspec (src.spec()); const ImageSpec &dstspec (dst.spec()); DASSERT (dstspec.nchannels == srcspec.nchannels); DASSERT (dst.localpixels()); if (src.localpixels() && // Not a cached image !envlatlmode && // not latlong wrap mode roi.xbegin == 0 && // Region x at origin dstspec.width == roi.width() && // Full width ROI dstspec.width == (srcspec.width / 2) && // Src is 2x resize dstspec.format == srcspec.format && // Same formats dstspec.x == 0 && dstspec.y == 0 && // Not a crop or overscan srcspec.x == 0 && srcspec.y == 0) { // If all these conditions are met, we have a special case that // can be more highly optimized. OIIO_DISPATCH_TYPES("resize_block_2pass", resize_block_2pass, srcspec.format, dst, src, roi, allow_shift); } ASSERT (dst.spec().format == TypeDesc::TypeFloat); OIIO_DISPATCH_TYPES ("resize_block", resize_block_, srcspec.format, dst, src, roi, envlatlmode); } // Copy src into dst, but only for the range [x0,x1) x [y0,y1). static void check_nan_block (const ImageBuf &src, ROI roi, int &found_nonfinite) { int x0 = roi.xbegin, x1 = roi.xend, y0 = roi.ybegin, y1 = roi.yend; const ImageSpec &spec (src.spec()); float *pel = (float *) alloca (spec.pixel_bytes()); for (int y = y0; y < y1; ++y) { for (int x = x0; x < x1; ++x) { src.getpixel (x, y, pel); for (int c = 0; c < spec.nchannels; ++c) { if (! isfinite(pel[c])) { spin_lock lock (maketx_mutex); if (found_nonfinite < 3) std::cerr << "maketx ERROR: Found " << pel[c] << " at (x=" << x << ", y=" << y << ")\n"; ++found_nonfinite; break; // skip other channels, there's no point } } } } } inline Imath::V3f latlong_to_dir (float s, float t, bool y_is_up=true) { float theta = 2.0f*M_PI * s; float phi = t * M_PI; float sinphi, cosphi; sincos (phi, &sinphi, &cosphi); if (y_is_up) return Imath::V3f (sinphi*sinf(theta), cosphi, -sinphi*cosf(theta)); else return Imath::V3f (-sinphi*cosf(theta), -sinphi*sinf(theta), cosphi); } static bool lightprobe_to_envlatl (ImageBuf &dst, const ImageBuf &src, bool y_is_up, ROI roi=ROI::All(), int nthreads=0) { ASSERT (dst.initialized() && src.nchannels() == dst.nchannels()); if (! roi.defined()) roi = get_roi (dst.spec()); roi.chend = std::min (roi.chend, dst.nchannels()); if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(lightprobe_to_envlatl, boost::ref(dst), boost::cref(src), y_is_up, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case const ImageSpec &dstspec (dst.spec()); int nchannels = dstspec.nchannels; ASSERT (dstspec.format == TypeDesc::FLOAT); float *pixel = ALLOCA (float, nchannels); float dw = dstspec.width, dh = dstspec.height; for (ImageBuf::Iterator d (dst, roi); ! d.done(); ++d) { Imath::V3f V = latlong_to_dir ((d.x()+0.5f)/dw, (dh-1.0f-d.y()+0.5f)/dh, y_is_up); float r = M_1_PI*acosf(V[2]) / hypotf(V[0],V[1]); float u = (V[0]*r + 1.0f) * 0.5f; float v = (V[1]*r + 1.0f) * 0.5f; interppixel_NDC_clamped (src, float(u), float(v), pixel, false); for (int c = roi.chbegin; c < roi.chend; ++c) d[c] = pixel[c]; } return true; } static void fix_latl_edges (ImageBuf &buf) { int n = buf.nchannels(); float *left = ALLOCA (float, n); float *right = ALLOCA (float, n); // Make the whole first and last row be solid, since they are exactly // on the pole float wscale = 1.0f / (buf.spec().width); for (int j = 0; j <= 1; ++j) { int y = (j==0) ? buf.ybegin() : buf.yend()-1; // use left for the sum, right for each new pixel for (int c = 0; c < n; ++c) left[c] = 0.0f; for (int x = buf.xbegin(); x < buf.xend(); ++x) { buf.getpixel (x, y, right); for (int c = 0; c < n; ++c) left[c] += right[c]; } for (int c = 0; c < n; ++c) left[c] *= wscale; for (int x = buf.xbegin(); x < buf.xend(); ++x) buf.setpixel (x, y, left); } // Make the left and right match, since they are both right on the // prime meridian. for (int y = buf.ybegin(); y < buf.yend(); ++y) { buf.getpixel (buf.xbegin(), y, left); buf.getpixel (buf.xend()-1, y, right); for (int c = 0; c < n; ++c) left[c] = 0.5f * left[c] + 0.5f * right[c]; buf.setpixel (buf.xbegin(), y, left); buf.setpixel (buf.xend()-1, y, left); } } static std::string formatres (const ImageSpec &spec, bool extended=false) { std::string s; s = Strutil::format("%dx%d", spec.width, spec.height); if (extended) { if (spec.x || spec.y) s += Strutil::format("%+d%+d", spec.x, spec.y); if (spec.width != spec.full_width || spec.height != spec.full_height || spec.x != spec.full_x || spec.y != spec.full_y) { s += " (full/display window is "; s += Strutil::format("%dx%d", spec.full_width, spec.full_height); if (spec.full_x || spec.full_y) s += Strutil::format("%+d%+d", spec.full_x, spec.full_y); s += ")"; } } return s; } static void maketx_merge_spec (ImageSpec &dstspec, const ImageSpec &srcspec) { for (size_t i = 0, e = srcspec.extra_attribs.size(); i < e; ++i) { const ImageIOParameter &p (srcspec.extra_attribs[i]); ustring name = p.name(); if (Strutil::istarts_with (name.string(), "maketx:")) { // Special instruction -- don't copy it to the destination spec } else { // just an attribute that should be set upon output dstspec.attribute (name.string(), p.type(), p.data()); } } } static bool write_mipmap (ImageBufAlgo::MakeTextureMode mode, boost::shared_ptr &img, const ImageSpec &outspec_template, std::string outputfilename, ImageOutput *out, TypeDesc outputdatatype, bool mipmap, const std::string &filtername, const ImageSpec &configspec, std::ostream &outstream, double &stat_writetime, double &stat_miptime, size_t &peak_mem) { bool envlatlmode = (mode == ImageBufAlgo::MakeTxEnvLatl); bool orig_was_overscan = (img->spec().x || img->spec().y || img->spec().z || img->spec().full_x || img->spec().full_y || img->spec().full_z); ImageSpec outspec = outspec_template; outspec.set_format (outputdatatype); if (mipmap && !out->supports ("multiimage") && !out->supports ("mipmap")) { outstream << "maketx ERROR: \"" << outputfilename << "\" format does not support multires images\n"; return false; } if (! mipmap && ! strcmp (out->format_name(), "openexr")) { // Send hint to OpenEXR driver that we won't specify a MIPmap outspec.attribute ("openexr:levelmode", 0 /* ONE_LEVEL */); } if (mipmap && ! strcmp (out->format_name(), "openexr")) { outspec.attribute ("openexr:roundingmode", 0 /* ROUND_DOWN */); } // OpenEXR always uses border sampling for environment maps bool src_samples_border; if (envlatlmode && !strcmp(out->format_name(), "openexr")) { src_samples_border = true; outspec.attribute ("oiio:updirection", "y"); outspec.attribute ("oiio:sampleborder", 1); } if (envlatlmode && src_samples_border) fix_latl_edges (*img); bool do_highlight_compensation = configspec.get_int_attribute ("maketx:highlightcomp", 0); Timer writetimer; if (! out->open (outputfilename.c_str(), outspec)) { outstream << "maketx ERROR: Could not open \"" << outputfilename << "\" : " << out->geterror() << "\n"; return false; } // Write out the image bool verbose = configspec.get_int_attribute ("maketx:verbose") != 0; if (verbose) { outstream << " Writing file: " << outputfilename << std::endl; outstream << " Filter \"" << filtername << "\n"; outstream << " Top level is " << formatres(outspec) << std::endl; } if (! img->write (out)) { // ImageBuf::write transfers any errors from the ImageOutput to // the ImageBuf. outstream << "maketx ERROR: Write failed \" : " << img->geterror() << "\n"; out->close (); return false; } stat_writetime += writetimer(); if (mipmap) { // Mipmap levels: if (verbose) outstream << " Mipmapping...\n" << std::flush; std::vector mipimages; std::string mipimages_unsplit = configspec.get_string_attribute ("maketx:mipimages"); if (mipimages_unsplit.length()) Strutil::split (mipimages_unsplit, mipimages, ";"); bool allow_shift = configspec.get_int_attribute("maketx:allow_pixel_shift") != 0; boost::shared_ptr small (new ImageBuf); while (outspec.width > 1 || outspec.height > 1) { Timer miptimer; ImageSpec smallspec; if (mipimages.size()) { // Special case -- the user specified a custom MIP level small->reset (mipimages[0]); small->read (0, 0, true, TypeDesc::FLOAT); smallspec = small->spec(); if (smallspec.nchannels != outspec.nchannels) { outstream << "WARNING: Custom mip level \"" << mipimages[0] << " had the wrong number of channels.\n"; boost::shared_ptr t (new ImageBuf (smallspec)); ImageBufAlgo::channels(*t, *small, outspec.nchannels, NULL, NULL, NULL, true); std::swap (t, small); } smallspec.tile_width = outspec.tile_width; smallspec.tile_height = outspec.tile_height; smallspec.tile_depth = outspec.tile_depth; mipimages.erase (mipimages.begin()); } else { // Resize a factor of two smaller smallspec = outspec; smallspec.width = img->spec().width; smallspec.height = img->spec().height; smallspec.depth = img->spec().depth; if (smallspec.width > 1) smallspec.width /= 2; if (smallspec.height > 1) smallspec.height /= 2; smallspec.full_width = smallspec.width; smallspec.full_height = smallspec.height; smallspec.full_depth = smallspec.depth; if (!allow_shift || configspec.get_int_attribute("maketx:forcefloat", 1)) smallspec.set_format (TypeDesc::FLOAT); // Trick: to get the resize working properly, we reset // both display and pixel windows to match, and have 0 // offset, AND doctor the big image to have its display // and pixel windows match. Don't worry, the texture // engine doesn't care what the upper MIP levels have // for the window sizes, it uses level 0 to determine // the relatinship between texture 0-1 space (display // window) and the pixels. smallspec.x = 0; smallspec.y = 0; smallspec.full_x = 0; smallspec.full_y = 0; small->alloc (smallspec); // Realocate with new size img->set_full (img->xbegin(), img->xend(), img->ybegin(), img->yend(), img->zbegin(), img->zend()); if (filtername == "box" && !orig_was_overscan) ImageBufAlgo::parallel_image (boost::bind(resize_block, boost::ref(*small), boost::cref(*img), _1, envlatlmode, allow_shift), OIIO::get_roi(small->spec())); else { Filter2D *filter = setup_filter (small->spec(), img->spec(), filtername); if (! filter) { outstream << "maketx ERROR: could not make filter '" << filtername << "\n"; return false; } if (verbose) { outstream << " Downsampling filter \"" << filter->name() << "\" width = " << filter->width() << "\n"; } if (do_highlight_compensation) ImageBufAlgo::rangecompress (*img); ImageBufAlgo::resize (*small, *img, filter); if (do_highlight_compensation) { ImageBufAlgo::rangeexpand (*small); ImageBufAlgo::clamp (*small, 0.0f, std::numeric_limits::max(), true); } Filter2D::destroy (filter); } } stat_miptime += miptimer(); outspec = smallspec; outspec.set_format (outputdatatype); if (envlatlmode && src_samples_border) fix_latl_edges (*small); Timer writetimer; // If the format explicitly supports MIP-maps, use that, // otherwise try to simulate MIP-mapping with multi-image. ImageOutput::OpenMode mode = out->supports ("mipmap") ? ImageOutput::AppendMIPLevel : ImageOutput::AppendSubimage; if (! out->open (outputfilename.c_str(), outspec, mode)) { outstream << "maketx ERROR: Could not append \"" << outputfilename << "\" : " << out->geterror() << "\n"; return false; } if (! small->write (out)) { // ImageBuf::write transfers any errors from the // ImageOutput to the ImageBuf. outstream << "maketx ERROR writing \"" << outputfilename << "\" : " << small->geterror() << "\n"; out->close (); return false; } stat_writetime += writetimer(); if (verbose) { size_t mem = Sysutil::memory_used(true); peak_mem = std::max (peak_mem, mem); outstream << Strutil::format (" %-15s (%s)", formatres(smallspec), Strutil::memformat(mem)) << std::endl; } std::swap (img, small); } } if (verbose) outstream << " Wrote file: " << outputfilename << " (" << Strutil::memformat(Sysutil::memory_used(true)) << ")\n"; writetimer.reset (); writetimer.start (); if (! out->close ()) { outstream << "maketx ERROR writing \"" << outputfilename << "\" : " << out->geterror() << "\n"; return false; } stat_writetime += writetimer (); return true; } static bool make_texture_impl (ImageBufAlgo::MakeTextureMode mode, const ImageBuf *input, std::string filename, std::string outputfilename, const ImageSpec &_configspec, std::ostream *outstream_ptr) { ASSERT (mode >= 0 && mode < ImageBufAlgo::_MakeTxLast); double stat_readtime = 0; double stat_writetime = 0; double stat_resizetime = 0; double stat_miptime = 0; double stat_colorconverttime = 0; size_t peak_mem = 0; Timer alltime; #define STATUS(task,timer) \ { \ size_t mem = Sysutil::memory_used(true); \ peak_mem = std::max (peak_mem, mem); \ if (verbose) \ outstream << Strutil::format (" %-25s %s (%s)\n", task, \ Strutil::timeintervalformat(timer,2), \ Strutil::memformat(mem)); \ } ImageSpec configspec = _configspec; std::stringstream localstream; // catch output when user doesn't want it std::ostream &outstream (outstream_ptr ? *outstream_ptr : localstream); bool from_filename = (input == NULL); if (from_filename && ! Filesystem::exists (filename)) { outstream << "maketx ERROR: \"" << filename << "\" does not exist\n"; return false; } boost::shared_ptr src; if (input == NULL) { // No buffer supplied -- create one to read the file src.reset (new ImageBuf(filename)); src->init_spec (filename, 0, 0); // force it to get the spec, not read } else if (input->cachedpixels()) { // Image buffer supplied that's backed by ImageCache -- create a // copy (very light weight, just another cache reference) src.reset (new ImageBuf(*input)); } else { // Image buffer supplied that has pixels -- wrap it src.reset (new ImageBuf(input->name(), input->spec(), (void *)input->localpixels())); } ASSERT (src.get()); if (! outputfilename.length()) { std::string fn = src->name(); if (fn.length()) { if (Filesystem::extension(fn).length() > 1) outputfilename = Filesystem::replace_extension (fn, ".tx"); else outputfilename = outputfilename + ".tx"; } else { outstream << "maketx: no output filename supplied\n"; return false; } } // When was the input file last modified? // This is only used when we're reading from a filename std::time_t in_time; time (&in_time); // make it look initialized bool updatemode = configspec.get_int_attribute ("maketx:updatemode") != 0; if (from_filename) { // When in update mode, skip making the texture if the output // already exists and has the same file modification time as the // input file. in_time = Filesystem::last_write_time (src->name()); if (updatemode && Filesystem::exists (outputfilename) && (in_time == Filesystem::last_write_time (outputfilename))) { outstream << "maketx: no update required for \"" << outputfilename << "\"\n"; return true; } } bool shadowmode = (mode == ImageBufAlgo::MakeTxShadow); bool envlatlmode = (mode == ImageBufAlgo::MakeTxEnvLatl || mode == ImageBufAlgo::MakeTxEnvLatlFromLightProbe); // Find an ImageIO plugin that can open the output file, and open it std::string outformat = configspec.get_string_attribute ("maketx:fileformatname", outputfilename); ImageOutput *out = ImageOutput::create (outformat.c_str()); if (! out) { outstream << "maketx ERROR: Could not find an ImageIO plugin to write " << outformat << " files:" << geterror() << "\n"; return false; } if (! out->supports ("tiles")) { outstream << "maketx ERROR: \"" << outputfilename << "\" format does not support tiled images\n"; return false; } // The cache might mess with the apparent data format, so make sure // it's the nativespec that we consult for data format of the file. TypeDesc out_dataformat = src->nativespec().format; if (configspec.format != TypeDesc::UNKNOWN) out_dataformat = configspec.format; // We cannot compute the prman / oiio options until after out_dataformat // has been determined, as it's required (and can potentially change // out_dataformat too!) if (configspec.get_int_attribute("maketx:prman_options")) out_dataformat = set_prman_options (out_dataformat, configspec); else if (configspec.get_int_attribute("maketx:oiio_options")) out_dataformat = set_oiio_options (out_dataformat, configspec); // Read the full file locally if it's less than 1 GB, otherwise // allow the ImageBuf to use ImageCache to manage memory. int local_mb_thresh = configspec.get_int_attribute("maketx:read_local_MB", 1024); bool read_local = (src->spec().image_bytes() < imagesize_t(local_mb_thresh * 1024*1024)); bool verbose = configspec.get_int_attribute ("maketx:verbose") != 0; double misc_time_1 = alltime.lap(); STATUS ("prep", misc_time_1); if (from_filename) { if (verbose) outstream << "Reading file: " << src->name() << std::endl; if (! src->read (0, 0, read_local)) { outstream << "maketx ERROR: Could not read \"" << src->name() << "\" : " << src->geterror() << "\n"; return false; } } stat_readtime += alltime.lap(); STATUS (Strutil::format("read \"%s\"", src->name()), stat_readtime); if (mode == ImageBufAlgo::MakeTxEnvLatlFromLightProbe) { ImageSpec newspec = src->spec(); newspec.width = newspec.full_width = src->spec().width; newspec.height = newspec.full_height = src->spec().height/2; newspec.tile_width = newspec.tile_height = 0; newspec.format = TypeDesc::FLOAT; boost::shared_ptr latlong (new ImageBuf(newspec)); // Now lightprobe holds the original lightprobe, src is a blank // image that will be the unwrapped latlong version of it. lightprobe_to_envlatl (*latlong, *src, true); // Carry on with the lat-long environment map from here on out mode = ImageBufAlgo::MakeTxEnvLatl; src = latlong; } // If requested - and we're a constant color - make a tiny texture instead // Only safe if the full/display window is the same as the data window. // Also note that this could affect the appearance when using "black" // wrap mode at runtime. std::vector constantColor(src->nchannels()); bool isConstantColor = false; if (configspec.get_int_attribute("maketx:constant_color_detect") && src->spec().x == 0 && src->spec().y == 0 && src->spec().z == 0 && src->spec().full_x == 0 && src->spec().full_y == 0 && src->spec().full_z == 0 && src->spec().full_width == src->spec().width && src->spec().full_height == src->spec().height && src->spec().full_depth == src->spec().depth) { isConstantColor = ImageBufAlgo::isConstantColor (*src, &constantColor[0]); if (isConstantColor) { // Reset the image, to a new image, at the tile size ImageSpec newspec = src->spec(); newspec.width = std::min (configspec.tile_width, src->spec().width); newspec.height = std::min (configspec.tile_height, src->spec().height); newspec.depth = std::min (configspec.tile_depth, src->spec().depth); newspec.full_width = newspec.width; newspec.full_height = newspec.height; newspec.full_depth = newspec.depth; std::string name = src->name() + ".constant_color"; src->reset(name, newspec); ImageBufAlgo::fill (*src, &constantColor[0]); if (verbose) { outstream << " Constant color image detected. "; outstream << "Creating " << newspec.width << "x" << newspec.height << " texture instead.\n"; } } } int nchannels = configspec.get_int_attribute ("maketx:nchannels", -1); // If requested -- and alpha is 1.0 everywhere -- drop it. if (configspec.get_int_attribute("maketx:opaque_detect") && src->spec().alpha_channel == src->nchannels()-1 && nchannels <= 0 && ImageBufAlgo::isConstantChannel(*src,src->spec().alpha_channel,1.0f)) { if (verbose) outstream << " Alpha==1 image detected. Dropping the alpha channel.\n"; boost::shared_ptr newsrc (new ImageBuf(src->spec())); ImageBufAlgo::channels (*newsrc, *src, src->nchannels()-1, NULL, NULL, NULL, true); std::swap (src, newsrc); // N.B. the old src will delete } // If requested - and we're a monochrome image - drop the extra channels if (configspec.get_int_attribute("maketx:monochrome_detect") && nchannels <= 0 && src->nchannels() == 3 && src->spec().alpha_channel < 0 && // RGB only ImageBufAlgo::isMonochrome(*src)) { if (verbose) outstream << " Monochrome image detected. Converting to single channel texture.\n"; boost::shared_ptr newsrc (new ImageBuf(src->spec())); ImageBufAlgo::channels (*newsrc, *src, 1, NULL, NULL, NULL, true); std::swap (src, newsrc); } // If we've otherwise explicitly requested to write out a // specific number of channels, do it. if ((nchannels > 0) && (nchannels != src->nchannels())) { if (verbose) outstream << " Overriding number of channels to " << nchannels << "\n"; boost::shared_ptr newsrc (new ImageBuf(src->spec())); ImageBufAlgo::channels (*newsrc, *src, nchannels, NULL, NULL, NULL, true); std::swap (src, newsrc); } std::string channelnames = configspec.get_string_attribute ("maketx:channelnames"); if (channelnames.size()) { std::vector newchannelnames; Strutil::split (channelnames, newchannelnames, ","); ImageSpec &spec (src->specmod()); // writeable version for (int c = 0; c < spec.nchannels; ++c) { if (c < (int)newchannelnames.size() && newchannelnames[c].size()) { std::string name = newchannelnames[c]; spec.channelnames[c] = name; if (Strutil::iequals(name,"A") || Strutil::iends_with(name,".A") || Strutil::iequals(name,"Alpha") || Strutil::iends_with(name,".Alpha")) spec.alpha_channel = c; if (Strutil::iequals(name,"Z") || Strutil::iends_with(name,".Z") || Strutil::iequals(name,"Depth") || Strutil::iends_with(name,".Depth")) spec.z_channel = c; } } } if (shadowmode) { // Some special checks for shadow maps if (src->spec().nchannels != 1) { outstream << "maketx ERROR: shadow maps require 1-channel images,\n" << "\t\"" << src->name() << "\" is " << src->spec().nchannels << " channels\n"; return false; } // Shadow maps only make sense for floating-point data. if (out_dataformat != TypeDesc::FLOAT && out_dataformat != TypeDesc::HALF && out_dataformat != TypeDesc::DOUBLE) out_dataformat = TypeDesc::FLOAT; } if (configspec.get_int_attribute("maketx:set_full_to_pixels")) { // User requested that we treat the image as uncropped or not // overscan ImageSpec &spec (src->specmod()); spec.full_x = spec.x = 0; spec.full_y = spec.y = 0; spec.full_z = spec.z = 0; spec.full_width = spec.width; spec.full_height = spec.height; spec.full_depth = spec.depth; } // Copy the input spec ImageSpec srcspec = src->spec(); ImageSpec dstspec = srcspec; bool do_resize = false; // If the pixel window is not a superset of the display window, pad it // with black. ROI roi = get_roi(dstspec); ROI roi_full = get_roi_full(dstspec); roi.xbegin = std::min (roi.xbegin, roi_full.xbegin); roi.ybegin = std::min (roi.ybegin, roi_full.ybegin); roi.zbegin = std::min (roi.zbegin, roi_full.zbegin); roi.xend = std::max (roi.xend, roi_full.xend); roi.yend = std::max (roi.yend, roi_full.yend); roi.zend = std::max (roi.zend, roi_full.zend); if (roi != get_roi(srcspec)) { do_resize = true; // do the resize if we were a cropped image set_roi (dstspec, roi); } bool orig_was_overscan = (roi != roi_full); if (orig_was_overscan) { configspec.attribute ("wrapmodes", "black,black"); } if ((dstspec.x < 0 || dstspec.y < 0 || dstspec.z < 0) && (out && !out->supports("negativeorigin"))) { // User passed negative origin but the output format doesn't // support it. Try to salvage the situation by shifting the // image into the positive range. if (dstspec.x < 0) { dstspec.full_x -= dstspec.x; dstspec.x = 0; } if (dstspec.y < 0) { dstspec.full_y -= dstspec.y; dstspec.y = 0; } if (dstspec.z < 0) { dstspec.full_z -= dstspec.z; dstspec.z = 0; } } // Make the output tiled, regardless of input dstspec.tile_width = configspec.tile_width ? configspec.tile_width : 64; dstspec.tile_height = configspec.tile_height ? configspec.tile_height : 64; dstspec.tile_depth = configspec.tile_depth ? configspec.tile_depth : 1; // Try to force zip (still can be overriden by configspec dstspec.attribute ("compression", "zip"); // Always prefer contiguous channels, unless overridden by configspec dstspec.attribute ("planarconfig", "contig"); // Default to black wrap mode, unless overridden by configspec dstspec.attribute ("wrapmodes", "black,black"); if (configspec.get_int_attribute ("maketx:ignore_unassoc")) dstspec.erase_attribute ("oiio:UnassociatedAlpha"); // Put a DateTime in the out file, either now, or matching the date // stamp of the input file (if update mode). time_t date; if (updatemode && from_filename) date = in_time; // update mode: use the time stamp of the input else time (&date); // not update: get the time now dstspec.attribute ("DateTime", datestring(date)); std::string cmdline = configspec.get_string_attribute ("maketx:full_command_line"); if (! cmdline.empty()) { // Append command to image history std::string history = dstspec.get_string_attribute ("Exif:ImageHistory"); if (history.length() && ! Strutil::iends_with (history, "\n")) history += std::string("\n"); history += cmdline; dstspec.attribute ("Exif:ImageHistory", history); } bool prman_metadata = configspec.get_int_attribute ("maketx:prman_metadata") != 0; if (shadowmode) { dstspec.attribute ("textureformat", "Shadow"); if (prman_metadata) dstspec.attribute ("PixarTextureFormat", "Shadow"); } else if (envlatlmode) { dstspec.attribute ("textureformat", "LatLong Environment"); configspec.attribute ("wrapmodes", "periodic,clamp"); if (prman_metadata) dstspec.attribute ("PixarTextureFormat", "Latlong Environment"); } else { dstspec.attribute ("textureformat", "Plain Texture"); if (prman_metadata) dstspec.attribute ("PixarTextureFormat", "Plain Texture"); } // FIXME -- should we allow tile sizes to reduce if the image is // smaller than the tile size? And when we do, should we also try // to make it bigger in the other direction to make the total tile // size more constant? // If --checknan was used and it's a floating point image, check for // nonfinite (NaN or Inf) values and abort if they are found. if (configspec.get_int_attribute("maketx:checknan") && (srcspec.format.basetype == TypeDesc::FLOAT || srcspec.format.basetype == TypeDesc::HALF || srcspec.format.basetype == TypeDesc::DOUBLE)) { int found_nonfinite = 0; ImageBufAlgo::parallel_image (boost::bind(check_nan_block, *src, _1, boost::ref(found_nonfinite)), OIIO::get_roi(srcspec)); if (found_nonfinite) { if (found_nonfinite > 3) outstream << "maketx ERROR: ...and Nan/Inf at " << (found_nonfinite-3) << " other pixels\n"; return false; } } // Fix nans/infs (if requested) std::string fixnan = configspec.get_string_attribute("maketx:fixnan"); ImageBufAlgo::NonFiniteFixMode fixmode = ImageBufAlgo::NONFINITE_NONE; if (fixnan.empty() || fixnan == "none") { } else if (fixnan == "black") { fixmode = ImageBufAlgo::NONFINITE_BLACK; } else if (fixnan == "box3") { fixmode = ImageBufAlgo::NONFINITE_BOX3; } else { outstream << "maketx ERROR: Unknown --fixnan mode " << " fixnan\n"; return false; } int pixelsFixed = 0; if (! ImageBufAlgo::fixNonFinite (*src, fixmode, &pixelsFixed)) { outstream << "maketx ERROR: Error fixing nans/infs.\n"; return false; } if (verbose && pixelsFixed) outstream << " Warning: " << pixelsFixed << " nan/inf pixels fixed.\n"; // FIXME -- we'd like to not call fixNonFinite if fixnan mode is // "none", or if we did the checknan and found no NaNs. But deep // inside fixNonFinite, it forces a full read into local mem of any // cached images, and that affects performance. Come back to this // and solve later. double misc_time_2 = alltime.lap(); STATUS ("misc2", misc_time_2); // Color convert the pixels, if needed, in place. If a color // conversion is required we will promote the src to floating point // (or there wont be enough precision potentially). Also, // independently color convert the constant color metadata std::string incolorspace = configspec.get_string_attribute ("maketx:incolorspace"); std::string outcolorspace = configspec.get_string_attribute ("maketx:outcolorspace"); if (!incolorspace.empty() && !outcolorspace.empty() && incolorspace != outcolorspace) { if (verbose) outstream << " Converting from colorspace " << incolorspace << " to colorspace " << outcolorspace << std::endl; // Buffer for the color-corrected version. Start by making it just // another pointer to the original source. boost::shared_ptr ccSrc (src); // color-corrected buffer if (src->spec().format != TypeDesc::FLOAT) { // If the original src buffer isn't float, make a scratch space // that is float. ImageSpec floatSpec = src->spec(); floatSpec.set_format (TypeDesc::FLOAT); ccSrc.reset (new ImageBuf (floatSpec)); } ColorConfig colorconfig; if (colorconfig.error()) { outstream << "Error Creating ColorConfig\n"; outstream << colorconfig.geterror() << std::endl; return false; } ColorProcessor * processor = colorconfig.createColorProcessor ( incolorspace.c_str(), outcolorspace.c_str()); if (!processor || colorconfig.error()) { outstream << "Error Creating Color Processor." << std::endl; outstream << colorconfig.geterror() << std::endl; return false; } bool unpremult = configspec.get_int_attribute ("maketx:unpremult") != 0; if (unpremult && verbose) outstream << " Unpremulting image..." << std::endl; if (!ImageBufAlgo::colorconvert (*ccSrc, *src, processor, unpremult)) { outstream << "Error applying color conversion to image.\n"; return false; } if (isConstantColor) { if (!ImageBufAlgo::colorconvert (&constantColor[0], static_cast(constantColor.size()), processor, unpremult)) { outstream << "Error applying color conversion to constant color.\n"; return false; } } ColorConfig::deleteColorProcessor(processor); processor = NULL; // swap the color-converted buffer and src (making src be the // working master that's color converted). std::swap (src, ccSrc); // N.B. at this point, ccSrc will go out of scope, freeing it if // it was a scratch buffer. stat_colorconverttime += alltime.lap(); STATUS ("color convert", stat_colorconverttime); } // Force float for the sake of the ImageBuf math. // Also force float if we do not allow for the pixel shift, // since resize_block_ requires floating point buffers. const int allow_shift = configspec.get_int_attribute("maketx:allow_pixel_shift"); if (configspec.get_int_attribute("maketx:forcefloat", 1) || !allow_shift) dstspec.set_format (TypeDesc::FLOAT); // Handle resize to power of two, if called for if (configspec.get_int_attribute("maketx:resize") && ! shadowmode) { dstspec.width = pow2roundup (dstspec.width); dstspec.height = pow2roundup (dstspec.height); dstspec.full_width = dstspec.width; dstspec.full_height = dstspec.height; } // Resize if we're up-resing for pow2 if (dstspec.width != srcspec.width || dstspec.height != srcspec.height || dstspec.full_depth != srcspec.full_depth) do_resize = true; // resize if we're converting from non-border sampling to border sampling // (converting TO an OpenEXR environment map). if (envlatlmode && (Strutil::iequals(configspec.get_string_attribute("maketx:fileformatname"),"openexr") || Strutil::iends_with(outputfilename,".exr"))) do_resize = true; if (do_resize && orig_was_overscan && out && !out->supports("displaywindow")) { outstream << "maketx ERROR: format " << out->format_name() << " does not support separate display windows,\n" << " which is necessary when combining resizing" << " and an input image with overscan."; return false; } std::string filtername = configspec.get_string_attribute ("maketx:filtername", "box"); double misc_time_3 = alltime.lap(); STATUS ("misc3", misc_time_3); boost::shared_ptr toplevel; // Ptr to top level of mipmap if (! do_resize && dstspec.format == src->spec().format) { // No resize needed, no format conversion needed -- just stick to // the image we've already got toplevel = src; } else if (! do_resize) { // Need format conversion, but no resize -- just copy the pixels toplevel.reset (new ImageBuf (dstspec)); ImageBufAlgo::parallel_image (boost::bind(copy_block,boost::ref(*toplevel),boost::cref(*src),_1), OIIO::get_roi(dstspec)); } else { // Resize if (verbose) outstream << " Resizing image to " << dstspec.width << " x " << dstspec.height << std::endl; toplevel.reset (new ImageBuf (dstspec)); if ((filtername == "box" || filtername == "triangle") && !orig_was_overscan) { ImageBufAlgo::parallel_image (boost::bind(resize_block, boost::ref(*toplevel), boost::cref(*src), _1, envlatlmode, allow_shift), OIIO::get_roi(dstspec)); } else { Filter2D *filter = setup_filter (toplevel->spec(), src->spec(), filtername); if (! filter) { outstream << "maketx ERROR: could not make filter '" << filtername << "\n"; return false; } ImageBufAlgo::resize (*toplevel, *src, filter); Filter2D::destroy (filter); } } stat_resizetime += alltime.lap(); STATUS ("resize & data convert", stat_resizetime); // toplevel now holds the color converted, format converted, resized // master copy. We can release src. src.reset (); // Update the toplevel ImageDescription with the sha1 pixel hash and // constant color std::string desc = dstspec.get_string_attribute ("ImageDescription"); bool updatedDesc = false; // Eliminate any SHA-1 or ConstantColor hints in the ImageDescription. if (desc.size()) { desc = boost::regex_replace (desc, boost::regex("SHA-1=[[:xdigit:]]*[ ]*"), ""); static const char *fp_number_pattern = "([+-]?((?:(?:[[:digit:]]*\\.)?[[:digit:]]+(?:[eE][+-]?[[:digit:]]+)?)))"; const std::string color_pattern = std::string ("ConstantColor=(\\[?") + fp_number_pattern + ",?)+\\]?[ ]*"; desc = boost::regex_replace (desc, boost::regex(color_pattern), ""); updatedDesc = true; } // The hash is only computed for the top mipmap level of pixel data. // Thus, any additional information that will effect the lower levels // (such as filtering information) needs to be manually added into the // hash. std::ostringstream addlHashData; addlHashData << filtername << " "; const int sha1_blocksize = 256; std::string hash_digest = configspec.get_int_attribute("maketx:hash", 1) ? ImageBufAlgo::computePixelHashSHA1 (*toplevel, addlHashData.str(), ROI::All(), sha1_blocksize) : ""; if (hash_digest.length()) { if (desc.length()) desc += " "; desc += "SHA-1="; desc += hash_digest; if (verbose) outstream << " SHA-1: " << hash_digest << std::endl; updatedDesc = true; dstspec.attribute ("oiio:SHA-1", hash_digest); } double stat_hashtime = alltime.lap(); STATUS ("SHA-1 hash", stat_hashtime); if (isConstantColor) { std::ostringstream os; // Emulate a JSON array os << "["; for (unsigned int i=0; i &filenames, const std::string &outputfilename, const ImageSpec &configspec, std::ostream *outstream_ptr) { return make_texture_impl (mode, NULL, filenames[0], outputfilename, configspec, outstream_ptr); } bool ImageBufAlgo::make_texture (ImageBufAlgo::MakeTextureMode mode, const ImageBuf &input, const std::string &outputfilename, const ImageSpec &configspec, std::ostream *outstream) { return make_texture_impl (mode, &input, "", outputfilename, configspec, outstream); } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebufalgo.cpp0000644000175000017500000013100112271062644023015 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Implementation of ImageBufAlgo algorithms. #include #include #include #include #include #include #include #include "imagebuf.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #include "dassert.h" #include "sysutil.h" #include "filter.h" #include "thread.h" #include "filesystem.h" #include "kissfft.hh" #ifdef USE_FREETYPE #include #include FT_FREETYPE_H #endif /////////////////////////////////////////////////////////////////////////// // Guidelines for ImageBufAlgo functions: // // * Signature will always be: // bool function (ImageBuf &R /* result */, // const ImageBuf &A, ...other input images..., // ...other parameters... // ROI roi = ROI::All(), // int nthreads = 0); // * The ROI should restrict the operation to those pixels (and channels) // specified. Default ROI::All() means perform the operation on all // pixel in R's data window. // * It's ok to omit ROI and threads from the few functions that // (a) can't possibly be parallelized, and (b) do not make sense to // apply to anything less than the entire image. // * Be sure to clamp the channel range to those actually used. // * If R is initialized, do not change any pixels outside the ROI. // If R is uninitialized, redefine ROI to be the union of the input // images' data windows and allocate R to be that size. // * Try to always do the "reasonable thing" rather than be too brittle. // * For errors (where there is no "reasonable thing"), set R's error // condition using R.error() with R.error() and return false. // * Always use IB::Iterators/ConstIterator, NEVER use getpixel/setpixel. // * Use the iterator Black or Clamp wrap modes to avoid lots of special // cases inside the pixel loops. // * Use OIIO_DISPATCH_* macros to call type-specialized templated // implemenations. It is permissible to use OIIO_DISPATCH_COMMON_TYPES_* // to tame the cross-product of types, especially for binary functions // (A,B inputs as well as R output). /////////////////////////////////////////////////////////////////////////// OIIO_NAMESPACE_ENTER { // Convenient helper struct to bundle a 3-int describing a block size. struct Dim3 { int x, y, z; Dim3 (int x, int y=1, int z=1) : x(x), y(y), z(z) { } }; bool ImageBufAlgo::IBAprep (ROI &roi, ImageBuf *dst, const ImageBuf *A, const ImageBuf *B, ImageSpec *force_spec, int prepflags) { if ((A && !A->initialized()) || (B && !B->initialized())) { if (dst) dst->error ("Uninitialized input image"); return false; } if (dst->initialized()) { // Valid destination image. Just need to worry about ROI. if (roi.defined()) { // Shrink-wrap ROI to the destination (including chend) roi = roi_intersection (roi, get_roi(dst->spec())); } else { // No ROI? Set it to all of dst's pixel window. roi = get_roi (dst->spec()); } // If the dst is initialized but is a cached image, we'll need // to fully read it into allocated memory so that we're able // to write to it subsequently. if (dst->storage() == ImageBuf::IMAGECACHE) { dst->read (dst->subimage(), dst->miplevel(), true /*force*/); ASSERT (dst->storage() == ImageBuf::LOCALBUFFER); } } else { // Not an initialized destination image! ASSERT ((A || roi.defined()) && "ImageBufAlgo without any guess about region of interest"); ROI full_roi; if (! roi.defined()) { // No ROI -- make it the union of the pixel regions of the inputs roi = get_roi (A->spec()); full_roi = get_roi_full (A->spec()); if (B) { roi = roi_union (roi, get_roi (B->spec())); full_roi = roi_union (full_roi, get_roi_full (B->spec())); } } else { if (A) roi.chend = std::min (roi.chend, A->nchannels()); full_roi = roi; } // Now we allocate space for dst. Give it A's spec, but adjust // the dimensions to match the ROI. ImageSpec spec; if (A) { // If there's an input image, give dst A's spec (with // modifications detailed below...) spec = force_spec ? (*force_spec) : A->spec(); // For two inputs, if they aren't the same data type, punt and // allocate a float buffer. If the user wanted something else, // they should have pre-allocated dst with their desired format. if (B && A->spec().format != B->spec().format) spec.set_format (TypeDesc::FLOAT); // No good can come from automatically polluting an ImageBuf // with some other ImageBuf's tile sizes. spec.tile_width = 0; spec.tile_height = 0; spec.tile_depth = 0; } else if (force_spec) { spec = *force_spec; } else { spec.set_format (TypeDesc::FLOAT); spec.nchannels = roi.chend; spec.default_channel_names (); } // Set the image dimensions based on ROI. set_roi (spec, roi); if (full_roi.defined()) set_roi_full (spec, full_roi); else set_roi_full (spec, roi); dst->alloc (spec); } if (prepflags & IBAprep_REQUIRE_ALPHA) { if (dst->spec().alpha_channel < 0 || (A && A->spec().alpha_channel < 0) || (B && B->spec().alpha_channel < 0)) { dst->error ("images must have alpha channels"); return false; } } if (prepflags & IBAprep_REQUIRE_Z) { if (dst->spec().z_channel < 0 || (A && A->spec().z_channel < 0) || (B && B->spec().z_channel < 0)) { dst->error ("images must have depth channels"); return false; } } if (prepflags & IBAprep_REQUIRE_SAME_NCHANNELS) { int n = dst->spec().nchannels; if ((A && A->spec().nchannels != n) || (B && B->spec().nchannels != n)) { dst->error ("images must have the same number of channels"); return false; } } return true; } template static bool fill_ (ImageBuf &dst, const float *values, ROI roi=ROI(), int nthreads=1) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(fill_, boost::ref(dst), values, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case for (ImageBuf::Iterator p (dst, roi); !p.done(); ++p) for (int c = roi.chbegin; c < roi.chend; ++c) p[c] = values[c]; return true; } bool ImageBufAlgo::fill (ImageBuf &dst, const float *pixel, ROI roi, int nthreads) { ASSERT (pixel && "fill must have a non-NULL pixel value pointer"); if (! IBAprep (roi, &dst)) return false; OIIO_DISPATCH_TYPES ("fill", fill_, dst.spec().format, dst, pixel, roi, nthreads); return true; } bool ImageBufAlgo::zero (ImageBuf &dst, ROI roi, int nthreads) { if (! IBAprep (roi, &dst)) return false; float *zero = ALLOCA(float,roi.chend); memset (zero, 0, roi.chend*sizeof(float)); return fill (dst, zero, roi, nthreads); } template static bool checker_ (ImageBuf &dst, Dim3 size, const float *color1, const float *color2, Dim3 offset, ROI roi, int nthreads=1) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(checker_, boost::ref(dst), size, color1, color2, offset, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case for (ImageBuf::Iterator p (dst, roi); !p.done(); ++p) { int xtile = (p.x()-offset.x)/size.x; xtile += (p.x() static bool resize_ (ImageBuf &dst, const ImageBuf &src, Filter2D *filter, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(resize_, boost::ref(dst), boost::cref(src), filter, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case const ImageSpec &srcspec (src.spec()); const ImageSpec &dstspec (dst.spec()); int nchannels = dstspec.nchannels; // Local copies of the source image window, converted to float float srcfx = srcspec.full_x; float srcfy = srcspec.full_y; float srcfw = srcspec.full_width; float srcfh = srcspec.full_height; // Ratios of dst/src size. Values larger than 1 indicate that we // are maximizing (enlarging the image), and thus want to smoothly // interpolate. Values less than 1 indicate that we are minimizing // (shrinking the image), and thus want to properly filter out the // high frequencies. float xratio = float(dstspec.full_width) / srcfw; // 2 upsize, 0.5 downsize float yratio = float(dstspec.full_height) / srcfh; float dstfx = dstspec.full_x; float dstfy = dstspec.full_y; float dstfw = dstspec.full_width; float dstfh = dstspec.full_height; float dstpixelwidth = 1.0f / dstfw; float dstpixelheight = 1.0f / dstfh; float *pel = ALLOCA (float, nchannels); float filterrad = filter->width() / 2.0f; // radi,radj is the filter radius, as an integer, in source pixels. We // will filter the source over [x-radi, x+radi] X [y-radj,y+radj]. int radi = (int) ceilf (filterrad/xratio); int radj = (int) ceilf (filterrad/yratio); bool separable = filter->separable(); float *column = NULL; if (separable) { // Allocate one column for the first horizontal filter pass column = ALLOCA (float, (2 * radj + 1) * nchannels); } #if 0 std::cerr << "Resizing " << srcspec.full_width << "x" << srcspec.full_height << " to " << dstspec.full_width << "x" << dstspec.full_height << "\n"; std::cerr << "ratios = " << xratio << ", " << yratio << "\n"; std::cerr << "examining src filter support radius of " << radi << " x " << radj << " pixels\n"; std::cerr << "dst range " << roi << "\n"; std::cerr << "separable filter\n"; #endif // We're going to loop over all output pixels we're interested in. // // (s,t) = NDC space coordinates of the output sample we are computing. // This is the "sample point". // (src_xf, src_xf) = source pixel space float coordinates of the // sample we're computing. We want to compute the weighted sum // of all the source image pixels that fall under the filter when // centered at that location. // (src_x, src_y) = image space integer coordinates of the floor, // i.e., the closest pixel in the source image. // src_xf_frac and src_yf_frac are the position within that pixel // of our sample. ImageBuf::Iterator out (dst, roi); for (int y = roi.ybegin; y < roi.yend; ++y) { float t = (y-dstfy+0.5f)*dstpixelheight; float src_yf = srcfy + t * srcfh; int src_y; float src_yf_frac = floorfrac (src_yf, &src_y); for (int x = roi.xbegin; x < roi.xend; ++x) { float s = (x-dstfx+0.5f)*dstpixelwidth; float src_xf = srcfx + s * srcfw; int src_x; float src_xf_frac = floorfrac (src_xf, &src_x); for (int c = 0; c < nchannels; ++c) pel[c] = 0.0f; float totalweight = 0.0f; if (separable) { // First, filter horizontally memset (column, 0, (2*radj+1)*nchannels*sizeof(float)); float *p = column; for (int j = -radj; j <= radj; ++j, p += nchannels) { totalweight = 0.0f; int yy = src_y+j; ImageBuf::ConstIterator srcpel (src, src_x-radi, src_x+radi+1, yy, yy+1, 0, 1, ImageBuf::WrapClamp); for (int i = -radi; i <= radi; ++i, ++srcpel) { float w = filter->xfilt (xratio * (i-(src_xf_frac-0.5f))); totalweight += w; if (w != 0.0f) { for (int c = 0; c < nchannels; ++c) p[c] += w * srcpel[c]; } } if (totalweight != 0.0f) { for (int c = 0; c < nchannels; ++c) p[c] /= totalweight; } } // Now filter vertically totalweight = 0.0f; p = column; for (int j = -radj; j <= radj; ++j, p += nchannels) { float w = filter->yfilt (yratio * (j-(src_yf_frac-0.5f))); totalweight += w; for (int c = 0; c < nchannels; ++c) pel[c] += w * p[c]; } } else { // Non-separable ImageBuf::ConstIterator srcpel (src, src_x-radi, src_x+radi+1, src_y-radi, src_y+radi+1, 0, 1, ImageBuf::WrapClamp); for (int j = -radj; j <= radj; ++j) { for (int i = -radi; i <= radi; ++i, ++srcpel) { float w = (*filter)(xratio * (i-(src_xf_frac-0.5f)), yratio * (j-(src_yf_frac-0.5f))); totalweight += w; if (w == 0.0f) continue; DASSERT (! srcpel.done()); for (int c = 0; c < nchannels; ++c) pel[c] += w * srcpel[c]; } } DASSERT (srcpel.done()); } // Rescale pel to normalize the filter, then write it to the // image. DASSERT (out.x() == x && out.y() == y); if (totalweight == 0.0f) { // zero it out for (int c = 0; c < nchannels; ++c) out[c] = 0.0f; } else { for (int c = 0; c < nchannels; ++c) out[c] = pel[c] / totalweight; } ++out; } } return true; } bool ImageBufAlgo::resize (ImageBuf &dst, const ImageBuf &src, Filter2D *filter, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &src)) return false; if (dst.nchannels() != src.nchannels()) { dst.error ("channel number mismatch: %d vs. %d", dst.spec().nchannels, src.spec().nchannels); return false; } if (dst.spec().depth > 1 || src.spec().depth > 1) { dst.error ("ImageBufAlgo::resize does not support volume images"); return false; } // Set up a shared pointer with custom deleter to make sure any // filter we allocate here is properly destroyed. boost::shared_ptr filterptr ((Filter2D*)NULL, Filter2D::destroy); bool allocfilter = (filter == NULL); if (allocfilter) { // If no filter was provided, punt and just linearly interpolate. const ImageSpec &srcspec (src.spec()); const ImageSpec &dstspec (dst.spec()); float wratio = float(dstspec.full_width) / float(srcspec.full_width); float hratio = float(dstspec.full_height) / float(srcspec.full_height); float w = 2.0f * std::max (1.0f, wratio); float h = 2.0f * std::max (1.0f, hratio); filter = Filter2D::create ("triangle", w, h); filterptr.reset (filter); } OIIO_DISPATCH_TYPES2 ("resize", resize_, dst.spec().format, src.spec().format, dst, src, filter, roi, nthreads); return false; } bool ImageBufAlgo::resize (ImageBuf &dst, const ImageBuf &src, const std::string &filtername_, float fwidth, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &src)) return false; const ImageSpec &srcspec (src.spec()); const ImageSpec &dstspec (dst.spec()); if (dstspec.nchannels != srcspec.nchannels) { dst.error ("channel number mismatch: %d vs. %d", dst.spec().nchannels, src.spec().nchannels); return false; } if (dstspec.depth > 1 || srcspec.depth > 1) { dst.error ("ImageBufAlgo::resize does not support volume images"); return false; } // Resize ratios float wratio = float(dstspec.full_width) / float(srcspec.full_width); float hratio = float(dstspec.full_height) / float(srcspec.full_height); // Set up a shared pointer with custom deleter to make sure any // filter we allocate here is properly destroyed. boost::shared_ptr filter ((Filter2D*)NULL, Filter2D::destroy); std::string filtername = filtername_; if (filtername.empty()) { // No filter name supplied -- pick a good default if (wratio > 1.0f || hratio > 1.0f) filtername = "blackman-harris"; else filtername = "lanczos3"; } for (int i = 0, e = Filter2D::num_filters(); i < e; ++i) { FilterDesc fd; Filter2D::get_filterdesc (i, &fd); if (fd.name == filtername) { float w = fwidth > 0.0f ? fwidth : fd.width * std::max (1.0f, wratio); float h = fwidth > 0.0f ? fwidth : fd.width * std::max (1.0f, hratio); filter.reset (Filter2D::create (filtername, w, h)); break; } } if (! filter) { dst.error ("Filter \"%s\" not recognized", filtername); return false; } OIIO_DISPATCH_TYPES2 ("resize", resize_, dstspec.format, srcspec.format, dst, src, filter.get(), roi, nthreads); return false; } template static bool resample_ (ImageBuf &dst, const ImageBuf &src, bool interpolate, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(resample_, boost::ref(dst), boost::cref(src), interpolate, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case const ImageSpec &srcspec (src.spec()); const ImageSpec &dstspec (dst.spec()); int nchannels = src.nchannels(); // Local copies of the source image window, converted to float float srcfx = srcspec.full_x; float srcfy = srcspec.full_y; float srcfw = srcspec.full_width; float srcfh = srcspec.full_height; float dstfx = dstspec.full_x; float dstfy = dstspec.full_y; float dstfw = dstspec.full_width; float dstfh = dstspec.full_height; float dstpixelwidth = 1.0f / dstfw; float dstpixelheight = 1.0f / dstfh; float *pel = ALLOCA (float, nchannels); ImageBuf::Iterator out (dst, roi); ImageBuf::ConstIterator srcpel (src); for (int y = roi.ybegin; y < roi.yend; ++y) { // s,t are NDC space float t = (y-dstfy+0.5f)*dstpixelheight; // src_xf, src_xf are image space float coordinates float src_yf = srcfy + t * srcfh - 0.5f; // src_x, src_y are image space integer coordinates of the floor int src_y; (void) floorfrac (src_yf, &src_y); for (int x = roi.xbegin; x < roi.xend; ++x) { float s = (x-dstfx+0.5f)*dstpixelwidth; float src_xf = srcfx + s * srcfw - 0.5f; int src_x; (void) floorfrac (src_xf, &src_x); if (interpolate) { src.interppixel (src_xf, src_yf, pel); for (int c = roi.chbegin; c < roi.chend; ++c) out[c] = pel[c]; } else { srcpel.pos (src_x, src_y, 0); for (int c = roi.chbegin; c < roi.chend; ++c) out[c] = srcpel[c]; } ++out; } } return true; } bool ImageBufAlgo::resample (ImageBuf &dst, const ImageBuf &src, bool interpolate, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &src)) return false; if (dst.nchannels() != src.nchannels()) { dst.error ("channel number mismatch: %d vs. %d", dst.spec().nchannels, src.spec().nchannels); return false; } if (dst.spec().depth > 1 || src.spec().depth > 1) { dst.error ("ImageBufAlgo::resample does not support volume images"); return false; } OIIO_DISPATCH_TYPES2 ("resample", resample_, dst.spec().format, src.spec().format, dst, src, interpolate, roi, nthreads); return false; } template static bool convolve_ (ImageBuf &dst, const ImageBuf &src, const ImageBuf &kernel, bool normalize, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(convolve_, boost::ref(dst), boost::cref(src), boost::cref(kernel), normalize, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case float scale = 1.0f; if (normalize) { scale = 0.0f; for (ImageBuf::ConstIterator k (kernel); ! k.done(); ++k) scale += k[0]; scale = 1.0f / scale; } float *sum = ALLOCA (float, roi.chend); ROI kroi = get_roi (kernel.spec()); ImageBuf::Iterator d (dst, roi); ImageBuf::ConstIterator s (src, roi, ImageBuf::WrapClamp); for ( ; ! d.done(); ++d) { for (int c = roi.chbegin; c < roi.chend; ++c) sum[c] = 0.0f; for (ImageBuf::ConstIterator k (kernel, kroi); !k.done(); ++k) { float kval = k[0]; s.pos (d.x() + k.x(), d.y() + k.y(), d.z() + k.z()); for (int c = roi.chbegin; c < roi.chend; ++c) sum[c] += kval * s[c]; } for (int c = roi.chbegin; c < roi.chend; ++c) d[c] = scale * sum[c]; } return true; } bool ImageBufAlgo::convolve (ImageBuf &dst, const ImageBuf &src, const ImageBuf &kernel, bool normalize, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &src)) return false; if (dst.nchannels() != src.nchannels()) { dst.error ("channel number mismatch: %d vs. %d", dst.spec().nchannels, src.spec().nchannels); return false; } OIIO_DISPATCH_TYPES2 ("convolve", convolve_, dst.spec().format, src.spec().format, dst, src, kernel, normalize, roi, nthreads); return false; } inline float binomial (int n, int k) { float p = 1; for (int i = 1; i <= k; ++i) p *= float(n - (k-i)) / i; return p; } bool ImageBufAlgo::make_kernel (ImageBuf &dst, const char *name, float width, float height, float depth, bool normalize) { int w = std::max (1, (int)ceilf(width)); int h = std::max (1, (int)ceilf(height)); int d = std::max (1, (int)ceilf(depth)); // Round up size to odd w |= 1; h |= 1; d |= 1; ImageSpec spec (w, h, 1 /*channels*/, TypeDesc::FLOAT); spec.depth = d; spec.x = -w/2; spec.y = -h/2; spec.z = -d/2; spec.full_x = spec.x; spec.full_y = spec.y; spec.full_z = spec.z; spec.full_width = spec.width; spec.full_height = spec.height; spec.full_depth = spec.depth; dst.alloc (spec); if (Filter2D *filter = Filter2D::create (name, width, height)) { // Named continuous filter from filter.h for (ImageBuf::Iterator p (dst); ! p.done(); ++p) p[0] = (*filter)((float)p.x(), (float)p.y()); delete filter; } else if (!strcmp (name, "binomial")) { // Binomial filter float *wfilter = ALLOCA (float, width); for (int i = 0; i < width; ++i) wfilter[i] = binomial (width-1, i); float *hfilter = (height == width) ? wfilter : ALLOCA (float, height); if (height != width) for (int i = 0; i < height; ++i) hfilter[i] = binomial (height-1, i); float *dfilter = ALLOCA (float, depth); if (depth == 1) dfilter[0] = 1; else for (int i = 0; i < depth; ++i) dfilter[i] = binomial (depth-1, i); for (ImageBuf::Iterator p (dst); ! p.done(); ++p) p[0] = wfilter[p.x()-spec.x] * hfilter[p.y()-spec.y] * dfilter[p.z()-spec.z]; } else { // No filter -- make a box float val = normalize ? 1.0f / ((w*h*d)) : 1.0f; for (ImageBuf::Iterator p (dst); ! p.done(); ++p) p[0] = val; dst.error ("Unknown kernel \"%s\"", name); return false; } if (normalize) { float sum = 0; for (ImageBuf::Iterator p (dst); ! p.done(); ++p) sum += p[0]; for (ImageBuf::Iterator p (dst); ! p.done(); ++p) p[0] = p[0] / sum; } return true; } // Helper function for unsharp mask to perform the thresholding static bool threshold_to_zero (ImageBuf &dst, float threshold, ROI roi, int nthreads) { ASSERT (dst.spec().format.basetype == TypeDesc::FLOAT); if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(threshold_to_zero, boost::ref(dst), threshold, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case for (ImageBuf::Iterator p (dst, roi); ! p.done(); ++p) for (int c = roi.chbegin; c < roi.chend; ++c) if (fabsf(p[c]) < threshold) p[c] = 0.0f; return true; } bool ImageBufAlgo::unsharp_mask (ImageBuf &dst, const ImageBuf &src, const char *kernel, float width, float contrast, float threshold, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &src)) return false; if (dst.nchannels() != src.nchannels()) { dst.error ("channel number mismatch: %d vs. %d", dst.spec().nchannels, src.spec().nchannels); return false; } if (dst.spec().depth > 1 || src.spec().depth > 1) { dst.error ("ImageBufAlgo::unsharp_mask does not support volume images"); return false; } // Blur the source image, store in Blurry ImageBuf K; if (! make_kernel (K, kernel, width, width)) { dst.error ("%s", K.geterror()); return false; } ImageSpec BlurrySpec = src.spec(); BlurrySpec.set_format (TypeDesc::FLOAT); // force float ImageBuf Blurry (BlurrySpec); if (! convolve (Blurry, src, K, true, roi, nthreads)) { dst.error ("%s", Blurry.geterror()); return false; } // Compute the difference between the source image and the blurry // version. (We store it in the same buffer we used for the difference // image.) ImageBuf &Diff (Blurry); bool ok = sub (Diff, src, Blurry, roi, nthreads); if (ok && threshold > 0.0f) ok = threshold_to_zero (Diff, threshold, roi, nthreads); // Scale the difference image by the contrast if (ok) ok = mul (Diff, contrast, roi, nthreads); if (! ok) { dst.error ("%s", Diff.geterror()); return false; } // Add the scaled difference to the original, to get the final answer ok = add (dst, src, Diff, roi, nthreads); return ok; } // Helper function: fft of the horizontal rows static bool hfft_ (ImageBuf &dst, const ImageBuf &src, bool inverse, bool unitary, ROI roi, int nthreads) { ASSERT (dst.spec().format.basetype == TypeDesc::FLOAT && src.spec().format.basetype == TypeDesc::FLOAT && dst.spec().nchannels == 2 && src.spec().nchannels == 2); if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind (hfft_, boost::ref(dst), boost::cref(src), inverse, unitary, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case int width = roi.width(); float rescale = sqrtf (1.0f / width); kissfft F (width, inverse); for (int z = roi.zbegin; z < roi.zend; ++z) { for (int y = roi.ybegin; y < roi.yend; ++y) { std::complex *s, *d; s = (std::complex *)src.pixeladdr(roi.xbegin, y, z); d = (std::complex *)dst.pixeladdr(roi.xbegin, y, z); F.transform (s, d); if (unitary) for (int x = 0; x < width; ++x) d[x] *= rescale; } } return true; } bool ImageBufAlgo::fft (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { if (src.spec().depth > 1) { dst.error ("ImageBufAlgo::fft does not support volume images"); return false; } if (! roi.defined()) roi = roi_union (get_roi (src.spec()), get_roi_full (src.spec())); roi.chend = roi.chbegin+1; // One channel only // Construct a spec that describes the result ImageSpec spec = src.spec(); spec.width = spec.full_width = roi.width(); spec.height = spec.full_height = roi.height(); spec.depth = spec.full_depth = 1; spec.x = spec.full_x = 0; spec.y = spec.full_y = 0; spec.z = spec.full_z = 0; spec.set_format (TypeDesc::FLOAT); spec.channelformats.clear(); spec.nchannels = 2; spec.channelnames.clear(); spec.channelnames.push_back ("real"); spec.channelnames.push_back ("imag"); // And a spec that describes the transposed intermediate ImageSpec specT = spec; std::swap (specT.width, specT.height); std::swap (specT.full_width, specT.full_height); // Resize dst dst.reset (dst.name(), spec); // Copy src to a 2-channel (for "complex") float buffer ImageBuf A (spec); // zeros it out automatically if (! ImageBufAlgo::paste (A, 0, 0, 0, 0, src, roi, nthreads)) { dst.error ("%s", A.geterror()); return false; } // FFT the rows (into temp buffer B). ImageBuf B (spec); hfft_ (B, A, false /*inverse*/, true /*unitary*/, get_roi(B.spec()), nthreads); // Transpose and shift back to A A.clear (); ImageBufAlgo::transpose (A, B, ROI::All(), nthreads); // FFT what was originally the columns (back to B) B.reset (specT); hfft_ (B, A, false /*inverse*/, true /*unitary*/, get_roi(A.spec()), nthreads); // Transpose again, into the dest ImageBufAlgo::transpose (dst, B, ROI::All(), nthreads); return true; } bool ImageBufAlgo::ifft (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { if (src.nchannels() != 2 || src.spec().format != TypeDesc::FLOAT) { dst.error ("ifft can only be done on 2-channel float images"); return false; } if (src.spec().depth > 1) { dst.error ("ImageBufAlgo::ifft does not support volume images"); return false; } if (! roi.defined()) roi = roi_union (get_roi (src.spec()), get_roi_full (src.spec())); roi.chbegin = 0; roi.chend = 2; // Construct a spec that describes the result ImageSpec spec = src.spec(); spec.width = spec.full_width = roi.width(); spec.height = spec.full_height = roi.height(); spec.depth = spec.full_depth = 1; spec.x = spec.full_x = 0; spec.y = spec.full_y = 0; spec.z = spec.full_z = 0; spec.set_format (TypeDesc::FLOAT); spec.channelformats.clear(); spec.nchannels = 2; spec.channelnames.clear(); spec.channelnames.push_back ("real"); spec.channelnames.push_back ("imag"); // Inverse FFT the rows (into temp buffer B). ImageBuf B (spec); hfft_ (B, src, true /*inverse*/, true /*unitary*/, get_roi(B.spec()), nthreads); // Transpose and shift back to A ImageBuf A; ImageBufAlgo::transpose (A, B, ROI::All(), nthreads); // Inverse FFT what was originally the columns (back to B) B.reset (A.spec()); hfft_ (B, A, true /*inverse*/, true /*unitary*/, get_roi(A.spec()), nthreads); // Transpose again, into the dst, in the process throw out the // imaginary part and go back to a single (real) channel. spec.nchannels = 1; spec.channelnames.clear (); spec.channelnames.push_back ("R"); dst.reset (dst.name(), spec); ROI Broi = get_roi(B.spec()); Broi.chend = 1; ImageBufAlgo::transpose (dst, B, Broi, nthreads); return true; } #ifdef USE_FREETYPE namespace { // anon static mutex ft_mutex; static FT_Library ft_library = NULL; static bool ft_broken = false; #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) const char *default_font_name = "cour"; #elif defined (__APPLE__) const char *default_font_name = "Courier New"; #elif defined (_WIN32) const char *default_font_name = "cour"; #else const char *default_font_name = "cour"; #endif } // anon namespace #endif bool ImageBufAlgo::render_text (ImageBuf &R, int x, int y, const std::string &text, int fontsize, const std::string &font_, const float *textcolor) { if (R.spec().depth > 1) { R.error ("ImageBufAlgo::render_text does not support volume images"); return false; } #ifdef USE_FREETYPE // If we know FT is broken, don't bother trying again if (ft_broken) return false; // Thread safety lock_guard ft_lock (ft_mutex); int error = 0; // If FT not yet initialized, do it now. if (! ft_library) { error = FT_Init_FreeType (&ft_library); if (error) { ft_broken = true; R.error ("Could not initialize FreeType for font rendering"); return false; } } // A set of likely directories for fonts to live, across several systems. std::vector search_dirs; const char *home = getenv ("HOME"); if (home && *home) { std::string h (home); search_dirs.push_back (h + "/fonts"); search_dirs.push_back (h + "/Fonts"); search_dirs.push_back (h + "/Library/Fonts"); } const char *systemRoot = getenv ("SystemRoot"); if (systemRoot && *systemRoot) { std::string sysroot (systemRoot); search_dirs.push_back (sysroot + "/Fonts"); } search_dirs.push_back ("/usr/share/fonts"); search_dirs.push_back ("/Library/Fonts"); search_dirs.push_back ("C:/Windows/Fonts"); search_dirs.push_back ("/opt/local/share/fonts"); // Try to find the font. Experiment with several extensions std::string font = font_; if (font.empty()) font = default_font_name; if (! Filesystem::is_regular (font)) { // Font specified is not a full path std::string f; static const char *extensions[] = { "", ".ttf", ".pfa", ".pfb", NULL }; for (int i = 0; f.empty() && extensions[i]; ++i) f = Filesystem::searchpath_find (font+extensions[i], search_dirs, true, true); if (! f.empty()) font = f; } FT_Face face; // handle to face object error = FT_New_Face (ft_library, font.c_str(), 0 /* face index */, &face); if (error) { R.error ("Could not set font face to \"%s\"", font); return false; // couldn't open the face } error = FT_Set_Pixel_Sizes (face, // handle to face object 0, // pixel_width fontsize); // pixel_heigh if (error) { FT_Done_Face (face); R.error ("Could not set font size to %d", fontsize); return false; // couldn't set the character size } FT_GlyphSlot slot = face->glyph; // a small shortcut int nchannels = R.spec().nchannels; float *pixelcolor = ALLOCA (float, nchannels); if (! textcolor) { float *localtextcolor = ALLOCA (float, nchannels); for (int c = 0; c < nchannels; ++c) localtextcolor[c] = 1.0f; textcolor = localtextcolor; } for (size_t n = 0, e = text.size(); n < e; ++n) { // load glyph image into the slot (erase previous one) error = FT_Load_Char (face, text[n], FT_LOAD_RENDER); if (error) continue; // ignore errors // now, draw to our target surface for (int j = 0; j < slot->bitmap.rows; ++j) { int ry = y + j - slot->bitmap_top; for (int i = 0; i < slot->bitmap.width; ++i) { int rx = x + i + slot->bitmap_left; float b = slot->bitmap.buffer[slot->bitmap.pitch*j+i] / 255.0f; R.getpixel (rx, ry, pixelcolor); for (int c = 0; c < nchannels; ++c) pixelcolor[c] = b*textcolor[c] + (1.0f-b) * pixelcolor[c]; R.setpixel (rx, ry, pixelcolor); } } // increment pen position x += slot->advance.x >> 6; } FT_Done_Face (face); return true; #else R.error ("OpenImageIO was not compiled with FreeType for font rendering"); return false; // Font rendering not supported #endif } // Helper for fillholes_pp: for any nonzero alpha pixels in dst, divide // all components by alpha. static bool divide_by_alpha (ImageBuf &dst, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(divide_by_alpha, boost::ref(dst), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case const ImageSpec &spec (dst.spec()); ASSERT (spec.format == TypeDesc::FLOAT); int nc = spec.nchannels; int ac = spec.alpha_channel; for (ImageBuf::Iterator d (dst, roi); ! d.done(); ++d) { float alpha = d[ac]; if (alpha != 0.0f) { for (int c = 0; c < nc; ++c) d[c] = d[c] / alpha; } } return true; } bool ImageBufAlgo::fillholes_pushpull (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &src)) return false; const ImageSpec &dstspec (dst.spec()); if (dstspec.nchannels != src.nchannels()) { dst.error ("channel number mismatch: %d vs. %d", dstspec.nchannels, src.spec().nchannels); return false; } if (dst.spec().depth > 1 || src.spec().depth > 1) { dst.error ("ImageBufAlgo::fillholes_pushpull does not support volume images"); return false; } if (dstspec.alpha_channel < 0 || dstspec.alpha_channel != src.spec().alpha_channel) { dst.error ("Must have alpha channels"); return false; } // We generate a bunch of temp images to form an image pyramid. // These give us a place to stash them and make sure they are // auto-deleted when the function exits. std::vector > pyramid; // First, make a writeable copy of the original image (converting // to float as a convenience) as the top level of the pyramid. ImageSpec topspec = src.spec(); topspec.set_format (TypeDesc::FLOAT); ImageBuf *top = new ImageBuf (topspec); paste (*top, topspec.x, topspec.y, topspec.z, 0, src); pyramid.push_back (boost::shared_ptr(top)); // Construct the rest of the pyramid by successive x/2 resizing and // then dividing nonzero alpha pixels by their alpha (this "spreads // out" the defined part of the image). int w = src.spec().width, h = src.spec().height; while (w > 1 || h > 1) { w = std::max (1, w/2); h = std::max (1, h/2); ImageSpec smallspec (w, h, src.nchannels(), TypeDesc::FLOAT); ImageBuf *small = new ImageBuf (smallspec); ImageBufAlgo::resize (*small, *pyramid.back(), "triangle"); divide_by_alpha (*small, get_roi(smallspec), nthreads); pyramid.push_back (boost::shared_ptr(small)); //debug small->save(); } // Now pull back up the pyramid by doing an alpha composite of level // i over a resized level i+1, thus filling in the alpha holes. By // time we get to the top, pixels whose original alpha are // unchanged, those with alpha < 1 are replaced by the blended // colors of the higher pyramid levels. for (int i = (int)pyramid.size()-2; i >= 0; --i) { ImageBuf &big(*pyramid[i]), &small(*pyramid[i+1]); ImageBuf blowup (big.spec()); ImageBufAlgo::resize (blowup, small, "triangle"); ImageBufAlgo::over (big, big, blowup); //debug big.save (Strutil::format ("after%d.exr", i)); } // Now copy the completed base layer of the pyramid back to the // original requested output. paste (dst, dstspec.x, dstspec.y, dstspec.z, 0, *pyramid[0]); return true; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebufalgo_opencv.cpp0000644000175000017500000001570112271062644024377 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Implementation of ImageBufAlgo algorithms related to OpenCV. /// These are nonfunctional if OpenCV is not found at build time. #ifdef USE_OPENCV #include #include #endif #include #include #include "imagebuf.h" #include "imagebufalgo.h" #include "dassert.h" #include "thread.h" #include "sysutil.h" OIIO_NAMESPACE_ENTER { bool ImageBufAlgo::from_IplImage (ImageBuf &dst, const IplImage *ipl, TypeDesc convert) { if (! ipl) { DASSERT (0 && "ImageBufAlgo::fromIplImage called with NULL ipl"); dst.error ("Passed NULL source IplImage"); return false; } #ifdef USE_OPENCV TypeDesc srcformat; switch (ipl->depth) { case IPL_DEPTH_8U : srcformat = TypeDesc::UINT8; break; case IPL_DEPTH_8S : srcformat = TypeDesc::INT8; break; case IPL_DEPTH_16U : srcformat = TypeDesc::UINT16; break; case IPL_DEPTH_16S : srcformat = TypeDesc::INT16; break; case IPL_DEPTH_32F : srcformat = TypeDesc::FLOAT; break; case IPL_DEPTH_64F : srcformat = TypeDesc::DOUBLE; break; default: DASSERT (0 && "unknown IplImage type"); dst.error ("Unsupported IplImage depth %d", (int)ipl->depth); return false; } TypeDesc dstformat = (convert != TypeDesc::UNKNOWN) ? convert : srcformat; ImageSpec spec (ipl->width, ipl->height, ipl->nChannels, dstformat); // N.B. The OpenCV headers say that ipl->alphaChannel, // ipl->colorModel, and ipl->channelSeq are ignored by OpenCV. if (ipl->dataOrder != IPL_DATA_ORDER_PIXEL) { // We don't handle separate color channels, and OpenCV doesn't either dst.error ("Unsupported IplImage data order %d", (int)ipl->dataOrder); return false; } dst.reset (dst.name(), spec); size_t pixelsize = srcformat.size()*spec.nchannels; // Account for the origin in the line step size, to end up with the // standard OIIO origin-at-upper-left: size_t linestep = ipl->origin ? -ipl->widthStep : ipl->widthStep; // Block copy and convert convert_image (spec.nchannels, spec.width, spec.height, 1, ipl->imageData, srcformat, pixelsize, linestep, 0, dst.pixeladdr(0,0), dstformat, spec.pixel_bytes(), spec.scanline_bytes(), 0); // FIXME - honor dataOrder. I'm not sure if it is ever used by // OpenCV. Fix when it becomes a problem. // OpenCV uses BGR ordering // FIXME: what do they do with alpha? if (spec.nchannels >= 3) { float pixel[4]; for (int y = 0; y < spec.height; ++y) { for (int x = 0; x < spec.width; ++x) { dst.getpixel (x, y, pixel, 4); float tmp = pixel[0]; pixel[0] = pixel[2]; pixel[2] = tmp; dst.setpixel (x, y, pixel, 4); } } } // FIXME -- the copy and channel swap should happen all as one loop, // probably templated by type. return true; #else dst.error ("fromIplImage not supported -- no OpenCV support at compile time"); return false; #endif } IplImage * ImageBufAlgo::to_IplImage (const ImageBuf &src) { #ifdef USE_OPENCV return NULL; #else return NULL; #endif } namespace { static mutex opencv_mutex; #ifdef USE_OPENCV class CameraHolder { public: CameraHolder () { } // Destructor frees all cameras ~CameraHolder () { for (camera_map::iterator i = m_cvcaps.begin(); i != m_cvcaps.end(); ++i) cvReleaseCapture (&(i->second)); } // Get the capture device, creating a new one if necessary. CvCapture * operator[] (int cameranum) { camera_map::iterator i = m_cvcaps.find (cameranum); if (i != m_cvcaps.end()) return i->second; CvCapture *cvcam = cvCreateCameraCapture (cameranum); m_cvcaps[cameranum] = cvcam; return cvcam; } private: typedef std::map camera_map; camera_map m_cvcaps; }; static CameraHolder cameras; #endif }; bool ImageBufAlgo::capture_image (ImageBuf &dst, int cameranum, TypeDesc convert) { #ifdef USE_OPENCV IplImage *frame = NULL; { // This block is mutex-protected lock_guard lock (opencv_mutex); CvCapture *cvcam = cameras[cameranum]; if (! cvcam) { dst.error ("Could not create a capture camera (OpenCV error)"); return false; // failed somehow } frame = cvQueryFrame (cvcam); if (! frame) { dst.error ("Could not cvQueryFrame (OpenCV error)"); return false; // failed somehow } } time_t now; time (&now); struct tm tmtime; Sysutil::get_local_time (&now, &tmtime); std::string datetime = Strutil::format ("%4d:%02d:%02d %02d:%02d:%02d", tmtime.tm_year+1900, tmtime.tm_mon+1, tmtime.tm_mday, tmtime.tm_hour, tmtime.tm_min, tmtime.tm_sec); bool ok = ImageBufAlgo::from_IplImage (dst, frame, convert); // cvReleaseImage (&frame); // unnecessary? if (ok) dst.specmod().attribute ("DateTime", datetime); return ok; #else dst.error ("capture_image not supported -- no OpenCV support at compile time"); return false; #endif } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/color_ocio.cpp0000644000175000017500000006712412271062644022540 0ustar mfvmfv/* Copyright 2012 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "strutil.h" #include "color.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #ifdef USE_OCIO #include namespace OCIO = OCIO_NAMESPACE; #endif OIIO_NAMESPACE_ENTER { bool ColorConfig::supportsOpenColorIO () { #ifdef USE_OCIO return true; #else return false; #endif } // Hidden implementation of ColorConfig class ColorConfig::Impl { public: #ifdef USE_OCIO OCIO::ConstConfigRcPtr config_; #endif mutable std::string error_; std::vector > colorspaces; std::string linear_alias; // Alias for a scene-linear color space Impl() { } ~Impl() { } void inventory (); void add (const std::string &name, int index) { colorspaces.push_back (std::pair (name, index)); } }; // ColorConfig utility to take inventory of the color spaces available. // It sets up knowledge of "linear", "sRGB", "Rec709", // even if the underlying OCIO configuration lacks them. void ColorConfig::Impl::inventory () { #ifdef USE_OCIO if (config_) { for (int i = 0, e = config_->getNumColorSpaces(); i < e; ++i) { std::string name = config_->getColorSpaceNameByIndex(i); add (name, i); } OCIO::ConstColorSpaceRcPtr lin = config_->getColorSpace ("scene_linear"); if (lin) linear_alias = lin->getName(); } if (colorspaces.size()) return; // If any were defined, we're done #endif // If there was no configuration, or we didn't compile with OCIO // support at all, register a few basic names we know about. add ("linear", 0); add ("sRGB", 1); add ("Rec709", 2); } ColorConfig::ColorConfig () : m_impl (new ColorConfig::Impl) { #ifdef USE_OCIO OCIO::SetLoggingLevel (OCIO::LOGGING_LEVEL_NONE); try { getImpl()->config_ = OCIO::GetCurrentConfig(); } catch(OCIO::Exception &e) { getImpl()->error_ = e.what(); } catch(...) { getImpl()->error_ = "An unknown error occurred in OpenColorIO, GetCurrentConfig"; } #endif getImpl()->inventory (); // If we populated our own, remove any errors. if (getNumColorSpaces() && !getImpl()->error_.empty()) getImpl()->error_.clear(); } ColorConfig::ColorConfig (const char * filename) : m_impl (new ColorConfig::Impl) { #ifdef USE_OCIO OCIO::SetLoggingLevel (OCIO::LOGGING_LEVEL_NONE); try { getImpl()->config_ = OCIO::Config::CreateFromFile (filename); } catch (OCIO::Exception &e) { getImpl()->error_ = e.what(); } catch (...) { getImpl()->error_ = "An unknown error occurred in OpenColorIO, CreateFromFile"; } #endif } ColorConfig::~ColorConfig() { delete m_impl; m_impl = NULL; } bool ColorConfig::error () const { return (!getImpl()->error_.empty()); } std::string ColorConfig::geterror () { std::string olderror = getImpl()->error_; getImpl()->error_ = ""; return olderror; } int ColorConfig::getNumColorSpaces () const { return (int) getImpl()->colorspaces.size(); } const char * ColorConfig::getColorSpaceNameByIndex (int index) const { return getImpl()->colorspaces[index].first.c_str(); } int ColorConfig::getNumLooks () const { #ifdef USE_OCIO if (getImpl()->config_) return getImpl()->config_->getNumLooks(); #endif return 0; } const char * ColorConfig::getLookNameByIndex (int index) const { #ifdef USE_OCIO if (getImpl()->config_) return getImpl()->config_->getLookNameByIndex (index); #endif return NULL; } const char * ColorConfig::getColorSpaceNameByRole (const char *role) const { #ifdef USE_OCIO if (getImpl()->config_) { OCIO::ConstColorSpaceRcPtr c = getImpl()->config_->getColorSpace (role); // Catch special case of obvious name synonyms if (!c && Strutil::iequals(role,"linear")) c = getImpl()->config_->getColorSpace ("scene_linear"); if (!c && Strutil::iequals(role,"scene_linear")) c = getImpl()->config_->getColorSpace ("linear"); if (c) return c->getName(); } #endif // No OCIO at build time, or no OCIO configuration at run time if (Strutil::iequals (role, "linear") || Strutil::iequals (role, "scene_linear")) return "linear"; return NULL; // Dunno what role } int ColorConfig::getNumDisplays() const { #ifdef USE_OCIO if (getImpl()->config_) return getImpl()->config_->getNumDisplays(); #endif return 0; } const char * ColorConfig::getDisplayNameByIndex(int index) const { #ifdef USE_OCIO if (getImpl()->config_) return getImpl()->config_->getDisplay(index); #endif return NULL; } int ColorConfig::getNumViews(const char * display) const { #ifdef USE_OCIO if (getImpl()->config_) return getImpl()->config_->getNumViews(display); #endif return 0; } const char * ColorConfig::getViewNameByIndex(const char * display, int index) const { #ifdef USE_OCIO if (getImpl()->config_) return getImpl()->config_->getView(display, index); #endif return NULL; } const char * ColorConfig::getDefaultDisplayName() const { #ifdef USE_OCIO if (getImpl()->config_) return getImpl()->config_->getDefaultDisplay(); #endif return NULL; } const char * ColorConfig::getDefaultViewName(const char * display) const { #ifdef USE_OCIO if (getImpl()->config_) return getImpl()->config_->getDefaultView(display); #endif return NULL; } // Abstract wrapper class for objects that will apply color transformations. class ColorProcessor { public: ColorProcessor () {}; virtual ~ColorProcessor (void) { }; virtual bool isNoOp() const { return false; } virtual bool hasChannelCrosstalk() const { return false; } virtual void apply (float *data, int width, int height, int channels, stride_t chanstride, stride_t xstride, stride_t ystride) const = 0; }; #ifdef USE_OCIO // Custom ColorProcessor that wraps an OpenColorIO Processor. class ColorProcessor_OCIO : public ColorProcessor { public: ColorProcessor_OCIO (OCIO::ConstProcessorRcPtr p) : m_p(p) {}; virtual ~ColorProcessor_OCIO (void) { }; virtual bool isNoOp() const { return m_p->isNoOp(); } virtual bool hasChannelCrosstalk() const { return m_p->hasChannelCrosstalk(); } virtual void apply (float *data, int width, int height, int channels, stride_t chanstride, stride_t xstride, stride_t ystride) const { OCIO::PackedImageDesc pid (data, width, height, channels, chanstride, xstride, ystride); m_p->apply (pid); } private: OCIO::ConstProcessorRcPtr m_p; }; #endif // ColorProcessor that hard-codes sRGB-to-linear class ColorProcessor_sRGB_to_linear : public ColorProcessor { public: ColorProcessor_sRGB_to_linear () : ColorProcessor() { }; ~ColorProcessor_sRGB_to_linear () { }; virtual void apply (float *data, int width, int height, int channels, stride_t chanstride, stride_t xstride, stride_t ystride) const { if (channels > 3) channels = 3; for (int y = 0; y < height; ++y) { char *d = (char *)data + y*ystride; for (int x = 0; x < width; ++x, d += xstride) for (int c = 0; c < channels; ++c) ((float *)d)[c] = sRGB_to_linear (((float *)d)[c]); } } }; // ColorProcessor that hard-codes linear-to-sRGB class ColorProcessor_linear_to_sRGB : public ColorProcessor { public: ColorProcessor_linear_to_sRGB () : ColorProcessor() { }; ~ColorProcessor_linear_to_sRGB () { }; virtual void apply (float *data, int width, int height, int channels, stride_t chanstride, stride_t xstride, stride_t ystride) const { if (channels > 3) channels = 3; for (int y = 0; y < height; ++y) { char *d = (char *)data + y*ystride; for (int x = 0; x < width; ++x, d += xstride) for (int c = 0; c < channels; ++c) ((float *)d)[c] = linear_to_sRGB (((float *)d)[c]); } } }; // ColorProcessor that hard-codes Rec709-to-linear class ColorProcessor_Rec709_to_linear : public ColorProcessor { public: ColorProcessor_Rec709_to_linear () : ColorProcessor() { }; ~ColorProcessor_Rec709_to_linear () { }; virtual void apply (float *data, int width, int height, int channels, stride_t chanstride, stride_t xstride, stride_t ystride) const { if (channels > 3) channels = 3; for (int y = 0; y < height; ++y) { char *d = (char *)data + y*ystride; for (int x = 0; x < width; ++x, d += xstride) for (int c = 0; c < channels; ++c) ((float *)d)[c] = Rec709_to_linear (((float *)d)[c]); } } }; // ColorProcessor that hard-codes linear-to-Rec709 class ColorProcessor_linear_to_Rec709 : public ColorProcessor { public: ColorProcessor_linear_to_Rec709 () : ColorProcessor() { }; ~ColorProcessor_linear_to_Rec709 () { }; virtual void apply (float *data, int width, int height, int channels, stride_t chanstride, stride_t xstride, stride_t ystride) const { if (channels > 3) channels = 3; for (int y = 0; y < height; ++y) { char *d = (char *)data + y*ystride; for (int x = 0; x < width; ++x, d += xstride) for (int c = 0; c < channels; ++c) ((float *)d)[c] = linear_to_Rec709 (((float *)d)[c]); } } }; ColorProcessor* ColorConfig::createColorProcessor (const char * inputColorSpace, const char * outputColorSpace) const { #ifdef USE_OCIO // Ask OCIO to make a Processor that can handle the requested // transformation. if (getImpl()->config_) { OCIO::ConstProcessorRcPtr p; try { // Get the processor corresponding to this transform. p = getImpl()->config_->getProcessor(inputColorSpace, outputColorSpace); } catch(OCIO::Exception &e) { getImpl()->error_ = e.what(); return NULL; } catch(...) { getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor"; return NULL; } getImpl()->error_ = ""; return new ColorProcessor_OCIO(p); } #endif // Either not compiled with OCIO support, or no OCIO configuration // was found at all. There are a few color conversions we know // about even in such dire conditions. if (Strutil::iequals(inputColorSpace,"linear") && Strutil::iequals(outputColorSpace,"sRGB")) { return new ColorProcessor_linear_to_sRGB; } if (Strutil::iequals(inputColorSpace,"sRGB") && Strutil::iequals(outputColorSpace,"linear")) { return new ColorProcessor_sRGB_to_linear; } if (Strutil::iequals(inputColorSpace,"linear") && Strutil::iequals(outputColorSpace,"Rec709")) { return new ColorProcessor_linear_to_Rec709; } if (Strutil::iequals(inputColorSpace,"Rec709") && Strutil::iequals(outputColorSpace,"linear")) { // No OCIO, or the OCIO config doesn't know linear->sRGB return new ColorProcessor_Rec709_to_linear; } return NULL; // if we get this far, we've failed } ColorProcessor* ColorConfig::createLookTransform (const char * looks, const char * inputColorSpace, const char * outputColorSpace, bool inverse, const char *context_key, const char *context_val) const { #ifdef USE_OCIO // Ask OCIO to make a Processor that can handle the requested // transformation. if (getImpl()->config_) { OCIO::ConstConfigRcPtr config = getImpl()->config_; OCIO::LookTransformRcPtr transform = OCIO::LookTransform::Create(); transform->setLooks (looks); OCIO::TransformDirection dir; if (inverse) { // The TRANSFORM_DIR_INVERSE applies an inverse for the // end-to-end transform, which would otherwise do dst->inv // look -> src. This is an unintuitive result for the // artist (who would expect in, out to remain unchanged), so // we account for that here by flipping src/dst transform->setSrc (outputColorSpace); transform->setDst (inputColorSpace); dir = OCIO::TRANSFORM_DIR_INVERSE; } else { // forward transform->setSrc (inputColorSpace); transform->setDst (outputColorSpace); dir = OCIO::TRANSFORM_DIR_FORWARD; } OCIO::ConstContextRcPtr context = config->getCurrentContext(); if (context_key && context_key[0] && context_val && context_val[0]) { OCIO::ContextRcPtr ctx = context->createEditableCopy(); ctx->setStringVar (context_key, context_val); context = ctx; } OCIO::ConstProcessorRcPtr p; try { // Get the processor corresponding to this transform. p = getImpl()->config_->getProcessor (context, transform, dir); } catch(OCIO::Exception &e) { getImpl()->error_ = e.what(); return NULL; } catch(...) { getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor"; return NULL; } getImpl()->error_ = ""; return new ColorProcessor_OCIO(p); } #endif return NULL; // if we get this far, we've failed } ColorProcessor* ColorConfig::createDisplayTransform (const char * display, const char * view, const char * inputColorSpace, const char * looks, const char * context_key, const char * context_value) const { #ifdef USE_OCIO // Ask OCIO to make a Processor that can handle the requested // transformation. if (getImpl()->config_) { OCIO::ConstConfigRcPtr config = getImpl()->config_; OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create(); transform->setInputColorSpaceName (inputColorSpace); transform->setDisplay(display); transform->setView(view); if (looks) { transform->setLooksOverride(looks); transform->setLooksOverrideEnabled(true); } else { transform->setLooksOverrideEnabled(false); } OCIO::ConstContextRcPtr context = config->getCurrentContext(); if (context_key && context_key[0] && context_value && context_value[0]) { OCIO::ContextRcPtr ctx = context->createEditableCopy(); ctx->setStringVar (context_key, context_value); context = ctx; } OCIO::ConstProcessorRcPtr p; try { // Get the processor corresponding to this transform. p = getImpl()->config_->getProcessor (context, transform, OCIO::TRANSFORM_DIR_FORWARD); } catch(OCIO::Exception &e) { getImpl()->error_ = e.what(); return NULL; } catch(...) { getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor"; return NULL; } getImpl()->error_ = ""; return new ColorProcessor_OCIO(p); } #endif return NULL; // if we get this far, we've failed } void ColorConfig::deleteColorProcessor (ColorProcessor * processor) { delete processor; } ////////////////////////////////////////////////////////////////////////// // // Image Processing Implementations static boost::shared_ptr default_colorconfig; // default color config static spin_mutex colorconfig_mutex; bool ImageBufAlgo::colorconvert (ImageBuf &dst, const ImageBuf &src, const char *from, const char *to, bool unpremult, ROI roi, int nthreads) { if (!from || !from[0] || !strcmp(from, "current")) { std::string s = src.spec().get_string_attribute ("oiio:Colorspace", "Linear"); from = ustring(s).c_str(); } if (!from || !to) { dst.error ("Unknown color space name"); return false; } ColorConfig *config = NULL; ColorProcessor *processor = NULL; { spin_lock lock (colorconfig_mutex); config = default_colorconfig.get(); if (! config) default_colorconfig.reset (config = new ColorConfig); processor = config->createColorProcessor (from, to); if (! processor) { if (config->error()) dst.error ("%s", config->geterror()); else dst.error ("Could not construct the color transform"); return false; } } bool ok = colorconvert (dst, src, processor, unpremult, roi, nthreads); if (ok) dst.specmod().attribute ("oiio:ColorSpace", to); config->deleteColorProcessor (processor); return ok; } bool ImageBufAlgo::colorconvert (ImageBuf &dst, const ImageBuf &src, const ColorProcessor* processor, bool unpremult, ROI roi, int nthreads) { // FIXME -- currently, we do not split across threads. // If the processor is NULL, return false (error) if (!processor) { dst.error ("Passed NULL ColorProcessor to colorconvert() [probable application bug]"); return false; } // If the processor is a no-op and the conversion is being done // in place, no work needs to be done. Early exit. if (processor->isNoOp() && (&dst == &src)) return true; IBAprep (roi, &dst, &src); // If the processor is a no-op (and it's not an in-place conversion), // use paste() to simplify the operation. if (processor->isNoOp()) { roi.chend = std::max (roi.chbegin+4, roi.chend); return ImageBufAlgo::paste (dst, roi.xbegin, roi.ybegin, roi.zbegin, roi.chbegin, src, roi, nthreads); } int width = roi.width(); // Temporary space to hold one RGBA scanline std::vector scanline(width*4, 0.0f); // Only process up to, and including, the first 4 channels. This // does let us process images with fewer than 4 channels, which is // the intent. // FIXME: Instead of loading the first 4 channels, obey // dstspec.alpha_channel index (but first validate that the // index is set properly for normal formats) int channelsToCopy = std::min (4, roi.nchannels()); // Walk through all data in our buffer. (i.e., crop or overscan) // FIXME: What about the display window? Should this actually promote // the datawindow to be union of data + display? This is useful if // the color of black moves. (In which case non-zero sections should // now be promoted). Consider the lin->log of a roto element, where // black now moves to non-black // // FIXME: Use the ImageBuf::ConstIterator s (src); s.isValid() // idiom for traversal instead, to allow for more efficient tile access // iteration order float * dstPtr = NULL; const float fltmin = std::numeric_limits::min(); // If the processor has crosstalk, and we'll be using it, we should // reset the channels to 0 before loading each scanline. bool clearScanline = (channelsToCopy<4 && (processor->hasChannelCrosstalk() || unpremult)); for (int k = roi.zbegin; k < roi.zend; ++k) { for (int j = roi.ybegin; j < roi.yend; ++j) { // Clear the scanline if (clearScanline) memset (&scanline[0], 0, sizeof(float)*scanline.size()); // Load the scanline src.get_pixel_channels (roi.xbegin, roi.xend, j, j+1, k, k+1, 0, channelsToCopy, TypeDesc::TypeFloat, &scanline[0], 4*sizeof(float)); // Optionally unpremult if ((channelsToCopy >= 4) && unpremult) { for (int i = 0; i < width; ++i) { float alpha = scanline[4*i+3]; if (alpha > fltmin) { scanline[4*i+0] /= alpha; scanline[4*i+1] /= alpha; scanline[4*i+2] /= alpha; } } } // Apply the color transformation in place processor->apply (&scanline[0], width, 1, 4, sizeof(float), 4*sizeof(float), width*4*sizeof(float)); // Optionally premult if ((channelsToCopy >= 4) && unpremult) { for (int i = 0; i < width; ++i) { float alpha = scanline[4*i+3]; if (alpha > fltmin) { scanline[4*i+0] *= alpha; scanline[4*i+1] *= alpha; scanline[4*i+2] *= alpha; } } } // Store the scanline dstPtr = &scanline[0]; for (int i = roi.xbegin; i < roi.xend ; i++) { dst.setpixel (i, j, k, dstPtr, channelsToCopy); dstPtr += 4; } } } return true; } bool ImageBufAlgo::ociolook (ImageBuf &dst, const ImageBuf &src, const char *looks, const char *from, const char *to, bool inverse, bool unpremult, const char *key, const char *value, ROI roi, int nthreads) { if (!from || !from[0] || !strcmp(from, "current")) { std::string s = src.spec().get_string_attribute ("oiio:Colorspace", "Linear"); from = ustring(s).c_str(); } if (!to || !to[0] || !strcmp(to, "current")) { std::string s = src.spec().get_string_attribute ("oiio:Colorspace", "Linear"); to = ustring(s).c_str(); } if (!from || !to) { dst.error ("Unknown color space name"); return false; } ColorConfig *config = NULL; ColorProcessor *processor = NULL; { spin_lock lock (colorconfig_mutex); config = default_colorconfig.get(); if (! config) default_colorconfig.reset (config = new ColorConfig); processor = config->createLookTransform (looks, from, to, inverse, key, value); if (! processor) { if (config->error()) dst.error ("%s", config->geterror()); else dst.error ("Could not construct the color transform"); return false; } } bool ok = colorconvert (dst, src, processor, unpremult, roi, nthreads); if (ok) dst.specmod().attribute ("oiio:ColorSpace", to); config->deleteColorProcessor (processor); return ok; } bool ImageBufAlgo::ociodisplay (ImageBuf &dst, const ImageBuf &src, const char *display, const char *view, const char *from, const char *looks, bool unpremult, const char *key, const char *value, ROI roi, int nthreads) { if (!from || !from[0] || !strcmp(from, "current")) { std::string s = src.spec().get_string_attribute ("oiio:Colorspace", "Linear"); from = ustring(s).c_str(); } if (!from) { dst.error ("Unknown color space name"); return false; } ColorConfig *config = NULL; ColorProcessor *processor = NULL; { spin_lock lock (colorconfig_mutex); config = default_colorconfig.get(); if (! config) default_colorconfig.reset (config = new ColorConfig); processor = config->createDisplayTransform (display, view, from, looks, key, value); if (! processor) { if (config->error()) dst.error ("%s", config->geterror()); else dst.error ("Could not construct the color transform"); return false; } } bool ok = colorconvert (dst, src, processor, unpremult, roi, nthreads); config->deleteColorProcessor (processor); return ok; } bool ImageBufAlgo::colorconvert (float * color, int nchannels, const ColorProcessor* processor, bool unpremult) { // If the processor is NULL, return false (error) if (!processor) { return false; } // If the processor is a no-op, no work needs to be done. Early exit. if (processor->isNoOp()) return true; // Load the pixel float rgba[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; int channelsToCopy = std::min (4, nchannels); memcpy(rgba, color, channelsToCopy*sizeof (float)); const float fltmin = std::numeric_limits::min(); // Optionally unpremult if ((channelsToCopy>=4) && unpremult) { float alpha = rgba[3]; if (alpha > fltmin) { rgba[0] /= alpha; rgba[1] /= alpha; rgba[2] /= alpha; } } // Apply the color transformation processor->apply (rgba, 1, 1, 4, sizeof(float), 4*sizeof(float), 4*sizeof(float)); // Optionally premult if ((channelsToCopy>=4) && unpremult) { float alpha = rgba[3]; if (alpha > fltmin) { rgba[0] *= alpha; rgba[1] *= alpha; rgba[2] *= alpha; } } // Store the scanline memcpy(color, rgba, channelsToCopy*sizeof(float)); return true; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/optparser_test.cpp0000644000175000017500000000654112271062644023463 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include "thread.h" #include #include "optparser.h" #include "unittest.h" OIIO_NAMESPACE_USING; class MySystem { public: MySystem() : i(0), f(0) { } bool attribute (const std::string &name, int value) { std::cout << "iattribute '" << name << "' = " << value << "\n"; if (name == "i") { i = value; return true; } return false; } bool attribute (const std::string &name, float value) { std::cout << "fattribute '" << name << "' = " << value << "\n"; if (name == "f") { f = value; return true; } return false; } bool attribute (const std::string &name, const std::string &value) { std::cout << "sattribute '" << name << "' = '" << value << "'\n"; if (name == "s") { s = value; return true; } return false; } int i; float f; std::string s; }; void test_optparser () { MySystem sys; optparser (sys, "i=14"); OIIO_CHECK_EQUAL (sys.i, 14); optparser (sys, "i=-28"); OIIO_CHECK_EQUAL (sys.i, -28); optparser (sys, "f=6.28"); OIIO_CHECK_EQUAL (sys.f, 6.28f); optparser (sys, "f=-56.0"); OIIO_CHECK_EQUAL (sys.f, -56.0f); optparser (sys, "f=-1."); OIIO_CHECK_EQUAL (sys.f, -1.0f); optparser (sys, "s=foo"); OIIO_CHECK_EQUAL (sys.s, "foo"); optparser (sys, "s=\"foo, bar\""); OIIO_CHECK_EQUAL (sys.s, "foo, bar"); optparser (sys, "f=256.29,s=\"phone call\",i=100"); OIIO_CHECK_EQUAL (sys.i, 100); OIIO_CHECK_EQUAL (sys.f, 256.29f); OIIO_CHECK_EQUAL (sys.s, "phone call"); } int main (int argc, char *argv[]) { test_optparser (); return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebufalgo_copy.cpp0000644000175000017500000004265312271062644024065 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Implementation of ImageBufAlgo algorithms that merely move pixels /// or channels between images without altering their values. #include #include #include #include #include "imagebuf.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #include "thread.h" OIIO_NAMESPACE_ENTER { template static bool paste_ (ImageBuf &dst, ROI dstroi, const ImageBuf &src, ROI srcroi, int nthreads) { // N.B. Punt on parallelizing because of the subtle interplay // between srcroi and dstroi, the parallel_image idiom doesn't // handle that especially well. And it's not worth customizing for // this function which is inexpensive and not commonly used, and so // would benefit little from parallelizing. We can always revisit // this later. But in the mean time, we maintain the 'nthreads' // parameter for uniformity with the rest of IBA. int src_nchans = src.nchannels (); int dst_nchans = dst.nchannels (); ImageBuf::ConstIterator s (src, srcroi); ImageBuf::Iterator d (dst, dstroi); for ( ; ! s.done(); ++s, ++d) { if (! d.exists()) continue; // Skip paste-into pixels that don't overlap dst's data for (int c = srcroi.chbegin, c_dst = dstroi.chbegin; c < srcroi.chend; ++c, ++c_dst) { if (c_dst >= 0 && c_dst < dst_nchans) d[c_dst] = c < src_nchans ? s[c] : D(0); } } return true; } bool ImageBufAlgo::paste (ImageBuf &dst, int xbegin, int ybegin, int zbegin, int chbegin, const ImageBuf &src, ROI srcroi, int nthreads) { if (! srcroi.defined()) srcroi = get_roi(src.spec()); ROI dstroi (xbegin, xbegin+srcroi.width(), ybegin, ybegin+srcroi.height(), zbegin, zbegin+srcroi.depth(), chbegin, chbegin+srcroi.nchannels()); ROI dstroi_save = dstroi; // save the original IBAprep (dstroi, &dst); // do the actual copying OIIO_DISPATCH_TYPES2 ("paste", paste_, dst.spec().format, src.spec().format, dst, dstroi_save, src, srcroi, nthreads); return false; } template static bool crop_ (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads=1) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(crop_, boost::ref(dst), boost::cref(src), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case ImageBuf::ConstIterator s (src, roi); ImageBuf::Iterator d (dst, roi); for ( ; ! d.done(); ++d, ++s) { for (int c = roi.chbegin; c < roi.chend; ++c) d[c] = s[c]; } return true; } bool ImageBufAlgo::crop (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { dst.clear (); roi.chend = std::min (roi.chend, src.nchannels()); IBAprep (roi, &dst, &src); OIIO_DISPATCH_TYPES2 ("crop", crop_, dst.spec().format, src.spec().format, dst, src, roi, nthreads); return false; } template static bool flip_ (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { ImageBuf::ConstIterator s (src, roi); ImageBuf::Iterator d (dst, roi); for ( ; ! d.done(); ++d) { s.pos (d.x(), roi.yend-1 - (d.y() - roi.ybegin), d.z()); for (int c = roi.chbegin; c < roi.chend; ++c) d[c] = s[c]; } return true; } bool ImageBufAlgo::flip(ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { IBAprep (roi, &dst, &src); OIIO_DISPATCH_TYPES2 ("flip", flip_, dst.spec().format, src.spec().format, dst, src, roi, nthreads); return false; } template static bool flop_ (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { ImageBuf::ConstIterator s (src, roi); ImageBuf::Iterator d (dst, roi); for ( ; ! d.done(); ++d) { s.pos (roi.xend-1 - (d.x() - roi.xbegin), d.y(), d.z()); for (int c = roi.chbegin; c < roi.chend; ++c) d[c] = s[c]; } return true; } bool ImageBufAlgo::flop (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { IBAprep (roi, &dst, &src); OIIO_DISPATCH_TYPES2 ("flop", flop_, dst.spec().format, src.spec().format, dst, src, roi, nthreads); return false; } template static bool flipflop_ (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { // Serial case ImageBuf::ConstIterator s (src, roi); ImageBuf::Iterator d (dst, roi); for ( ; !d.done(); ++d) { s.pos (roi.xend-1 - (d.x() - roi.xbegin), roi.yend-1 - (d.y() - roi.ybegin), d.z()); for (int c = roi.chbegin; c < roi.chend; ++c) d[c] = s[c]; } return true; } bool ImageBufAlgo::flipflop (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { IBAprep (roi, &dst, &src); OIIO_DISPATCH_TYPES2 ("flipflop", flipflop_, dst.spec().format, src.spec().format, dst, src, roi, nthreads); return false; } template static bool transpose_ (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(transpose_, boost::ref(dst), boost::cref(src), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case ImageBuf::ConstIterator s (src, roi); ImageBuf::Iterator d (dst); for ( ; ! s.done(); ++s) { d.pos (s.y(), s.x(), s.z()); if (! d.exists()) continue; for (int c = roi.chbegin; c < roi.chend; ++c) d[c] = s[c]; } return true; } bool ImageBufAlgo::transpose (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { if (! roi.defined()) roi = get_roi (src.spec()); roi.chend = std::min (roi.chend, src.nchannels()); ROI dst_roi (roi.ybegin, roi.yend, roi.xbegin, roi.xend, roi.zbegin, roi.zend, roi.chbegin, roi.chend); IBAprep (dst_roi, &dst); OIIO_DISPATCH_TYPES2 ("transpose", transpose_, dst.spec().format, src.spec().format, dst, src, roi, nthreads); return false; } template static bool circular_shift_ (ImageBuf &dst, const ImageBuf &src, int xshift, int yshift, int zshift, ROI dstroi, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(circular_shift_, boost::ref(dst), boost::cref(src), xshift, yshift, zshift, dstroi, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case int width = dstroi.width(), height = dstroi.height(), depth = dstroi.depth(); ImageBuf::ConstIterator s (src, roi); ImageBuf::Iterator d (dst); for ( ; ! s.done(); ++s) { int dx = dstroi.xbegin + ((s.x() - dstroi.xbegin + xshift) % width); int dy = dstroi.ybegin + ((s.y() - dstroi.ybegin + yshift) % height); int dz = dstroi.zbegin + ((s.z() - dstroi.zbegin + zshift) % depth); d.pos (dx, dy, dz); if (! d.exists()) continue; for (int c = roi.chbegin; c < roi.chend; ++c) d[c] = s[c]; } return true; } bool ImageBufAlgo::circular_shift (ImageBuf &dst, const ImageBuf &src, int xshift, int yshift, int zshift, ROI roi, int nthreads) { IBAprep (roi, &dst, &src); OIIO_DISPATCH_TYPES2 ("circular_shift", circular_shift_, dst.spec().format, src.spec().format, dst, src, xshift, yshift, zshift, roi, roi, nthreads); return false; } bool ImageBufAlgo::channels (ImageBuf &dst, const ImageBuf &src, int nchannels, const int *channelorder, const float *channelvalues, const std::string *newchannelnames, bool shuffle_channel_names) { // Not intended to create 0-channel images. if (nchannels <= 0) { dst.error ("%d-channel images not supported", nchannels); return false; } // If we dont have a single source channel, // hard to know how big to make the additional channels if (src.spec().nchannels == 0) { dst.error ("%d-channel images not supported", src.spec().nchannels); return false; } // If channelorder is NULL, it will be interpreted as // {0, 1, ..., nchannels-1}. int *local_channelorder = NULL; if (! channelorder) { local_channelorder = ALLOCA (int, nchannels); for (int c = 0; c < nchannels; ++c) local_channelorder[c] = c; channelorder = local_channelorder; } // If this is the identity transformation, just do a simple copy bool inorder = true; for (int c = 0; c < nchannels; ++c) inorder &= (channelorder[c] == c); if (nchannels == src.spec().nchannels && inorder) { return dst.copy (src); } // Construct a new ImageSpec that describes the desired channel ordering. ImageSpec newspec = src.spec(); newspec.nchannels = nchannels; newspec.default_channel_names (); newspec.alpha_channel = -1; newspec.z_channel = -1; for (int c = 0; c < nchannels; ++c) { int csrc = channelorder[c]; // If the user gave an explicit name for this channel, use it... if (newchannelnames && newchannelnames[c].size()) newspec.channelnames[c] = newchannelnames[c]; // otherwise, if shuffle_channel_names, use the channel name of // the src channel we're using (otherwise stick to the default name) else if (shuffle_channel_names && csrc >= 0 && csrc < src.spec().nchannels) newspec.channelnames[c] = src.spec().channelnames[csrc]; // otherwise, use the name of the source in that slot else if (csrc >= 0 && csrc < src.spec().nchannels) { newspec.channelnames[c] = src.spec().channelnames[csrc]; } // Use the names (or designation of the src image, if // shuffle_channel_names is true) to deduce the alpha and z channels. if ((shuffle_channel_names && csrc == src.spec().alpha_channel) || Strutil::iequals (newspec.channelnames[c], "A") || Strutil::iequals (newspec.channelnames[c], "alpha")) newspec.alpha_channel = c; if ((shuffle_channel_names && csrc == src.spec().z_channel) || Strutil::iequals (newspec.channelnames[c], "Z")) newspec.z_channel = c; } // Update the image (realloc with the new spec) dst.alloc (newspec); // Copy the channels individually stride_t dstxstride = AutoStride, dstystride = AutoStride, dstzstride = AutoStride; ImageSpec::auto_stride (dstxstride, dstystride, dstzstride, newspec.format.size(), newspec.nchannels, newspec.width, newspec.height); int channelsize = newspec.format.size(); char *pixels = (char *) dst.pixeladdr (dst.xbegin(), dst.ybegin(), dst.zbegin()); for (int c = 0; c < nchannels; ++c) { // Copy shuffled channels if (channelorder[c] >= 0 && channelorder[c] < src.spec().nchannels) { int csrc = channelorder[c]; src.get_pixel_channels (src.xbegin(), src.xend(), src.ybegin(), src.yend(), src.zbegin(), src.zend(), csrc, csrc+1, newspec.format, pixels, dstxstride, dstystride, dstzstride); } // Set channels that are literals if (channelorder[c] < 0 && channelvalues && channelvalues[c]) { ROI roi = get_roi (dst.spec()); roi.chbegin = c; roi.chend = c+1; ImageBufAlgo::fill (dst, &channelvalues[0], roi); } pixels += channelsize; } return true; } template static bool channel_append_impl (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (nthreads == 1 || roi.npixels() < 1000) { int na = A.nchannels(), nb = B.nchannels(); int n = std::min (dst.nchannels(), na+nb); ImageBuf::Iterator r (dst, roi); ImageBuf::ConstIterator a (A, roi); ImageBuf::ConstIterator b (B, roi); for (; !r.done(); ++r) { a.pos (r.x(), r.y(), r.z()); b.pos (r.x(), r.y(), r.z()); for (int c = 0; c < n; ++c) { if (c < na) r[c] = a.exists() ? a[c] : 0.0f; else r[c] = b.exists() ? b[c-na] : 0.0f; } } } else { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind (channel_append_impl, boost::ref(dst), boost::cref(A), boost::cref(B), _1, 1), roi, nthreads); } return true; } bool ImageBufAlgo::channel_append (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { // If the region is not defined, set it to the union of the valid // regions of the two source images. if (! roi.defined()) roi = roi_union (get_roi (A.spec()), get_roi (B.spec())); // If dst has not already been allocated, set it to the right size, // make it unconditinally float. if (! dst.pixels_valid()) { ImageSpec dstspec = A.spec(); dstspec.set_format (TypeDesc::TypeFloat); // Append the channel descriptions dstspec.nchannels = A.spec().nchannels + B.spec().nchannels; for (int c = 0; c < B.spec().nchannels; ++c) { std::string name = B.spec().channelnames[c]; // Eliminate duplicates if (std::find(dstspec.channelnames.begin(), dstspec.channelnames.end(), name) != dstspec.channelnames.end()) name = Strutil::format ("channel%d", A.spec().nchannels+c); dstspec.channelnames.push_back (name); } if (dstspec.alpha_channel < 0 && B.spec().alpha_channel >= 0) dstspec.alpha_channel = B.spec().alpha_channel + A.nchannels(); if (dstspec.z_channel < 0 && B.spec().z_channel >= 0) dstspec.z_channel = B.spec().z_channel + A.nchannels(); set_roi (dstspec, roi); dst.reset (dstspec); } // For now, only support float destination, and equivalent A and B // types. if (dst.spec().format != TypeDesc::FLOAT || A.spec().format != B.spec().format) { dst.error ("Unable to perform channel_append of %s, %s -> %s", A.spec().format, B.spec().format, dst.spec().format); return false; } OIIO_DISPATCH_TYPES ("channel_append", channel_append_impl, A.spec().format, dst, A, B, roi, nthreads); return true; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebufalgo_test.cpp0000644000175000017500000003337112271062644024067 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ // Based on the sample at: // http://code.google.com/p/googletest/wiki/GoogleTestPrimer#Writing_the_main()_Function #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "sysutil.h" #include "unittest.h" #include #include #include #include OIIO_NAMESPACE_USING; // Test ImageBuf::zero and ImageBuf::fill void test_zero_fill () { std::cout << "test zero_fill\n"; const int WIDTH = 8; const int HEIGHT = 6; const int CHANNELS = 4; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); spec.alpha_channel = 3; // Create a buffer -- pixels should be undefined ImageBuf A (spec); // Set a pixel to an odd value, make sure it takes const float arbitrary1[CHANNELS] = { 0.2, 0.3, 0.4, 0.5 }; A.setpixel (1, 1, arbitrary1); float pixel[CHANNELS]; // test pixel A.getpixel (1, 1, pixel); for (int c = 0; c < CHANNELS; ++c) OIIO_CHECK_EQUAL (pixel[c], arbitrary1[c]); // Zero out and test that it worked ImageBufAlgo::zero (A); for (int j = 0; j < HEIGHT; ++j) { for (int i = 0; i < WIDTH; ++i) { float pixel[CHANNELS]; A.getpixel (i, j, pixel); for (int c = 0; c < CHANNELS; ++c) OIIO_CHECK_EQUAL (pixel[c], 0.0f); } } // Test fill of whole image const float arbitrary2[CHANNELS] = { 0.6, 0.7, 0.3, 0.9 }; ImageBufAlgo::fill (A, arbitrary2); for (int j = 0; j < HEIGHT; ++j) { for (int i = 0; i < WIDTH; ++i) { float pixel[CHANNELS]; A.getpixel (i, j, pixel); for (int c = 0; c < CHANNELS; ++c) OIIO_CHECK_EQUAL (pixel[c], arbitrary2[c]); } } // Test fill of partial image const float arbitrary3[CHANNELS] = { 0.42, 0.43, 0.44, 0.45 }; { const int xbegin = 3, xend = 5, ybegin = 0, yend = 4; ImageBufAlgo::fill (A, arbitrary3, ROI(xbegin, xend, ybegin, yend)); for (int j = 0; j < HEIGHT; ++j) { for (int i = 0; i < WIDTH; ++i) { float pixel[CHANNELS]; A.getpixel (i, j, pixel); if (j >= ybegin && j < yend && i >= xbegin && i < xend) { for (int c = 0; c < CHANNELS; ++c) OIIO_CHECK_EQUAL (pixel[c], arbitrary3[c]); } else { for (int c = 0; c < CHANNELS; ++c) OIIO_CHECK_EQUAL (pixel[c], arbitrary2[c]); } } } } } // Test ImageBuf::crop void test_crop () { std::cout << "test crop\n"; int WIDTH = 8, HEIGHT = 6, CHANNELS = 4; // Crop region we'll work with int xbegin = 3, xend = 5, ybegin = 0, yend = 4; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); spec.alpha_channel = 3; ImageBuf A, B; A.reset (spec); B.reset (spec); float arbitrary1[4]; arbitrary1[0] = 0.2; arbitrary1[1] = 0.3; arbitrary1[2] = 0.4; arbitrary1[3] = 0.5; ImageBufAlgo::fill (A, arbitrary1); // Test CUT crop ImageBufAlgo::crop (B, A, ROI(xbegin, xend, ybegin, yend)); // Should have changed the data window (origin and width/height) OIIO_CHECK_EQUAL (B.spec().x, xbegin); OIIO_CHECK_EQUAL (B.spec().width, xend-xbegin); OIIO_CHECK_EQUAL (B.spec().y, ybegin); OIIO_CHECK_EQUAL (B.spec().height, yend-ybegin); float *pixel = ALLOCA(float, CHANNELS); for (int j = 0; j < B.spec().height; ++j) { for (int i = 0; i < B.spec().width; ++i) { B.getpixel (i+B.xbegin(), j+B.ybegin(), pixel); // Inside the crop region should match what it always was for (int c = 0; c < CHANNELS; ++c) OIIO_CHECK_EQUAL (pixel[c], arbitrary1[c]); } } } void test_paste () { std::cout << "test paste\n"; // Create the source image, make it a gradient ImageSpec Aspec (4, 4, 3, TypeDesc::FLOAT); ImageBuf A (Aspec); for (ImageBuf::Iterator it (A); !it.done(); ++it) { it[0] = float(it.x()) / float(Aspec.width-1); it[1] = float(it.y()) / float(Aspec.height-1); it[2] = 0.1f; } // Create destination image -- black it out ImageSpec Bspec (8, 8, 3, TypeDesc::FLOAT); ImageBuf B (Bspec); float gray[3] = { .1, .1, .1 }; ImageBufAlgo::fill (B, gray); // Paste a few pixels from A into B -- include offsets ImageBufAlgo::paste (B, 2, 2, 0, 1 /* chan offset */, A, ROI(1, 4, 1, 4)); // Spot check float a[3], b[3]; B.getpixel (1, 1, 0, b); OIIO_CHECK_EQUAL (b[0], gray[0]); OIIO_CHECK_EQUAL (b[1], gray[1]); OIIO_CHECK_EQUAL (b[2], gray[2]); B.getpixel (2, 2, 0, b); A.getpixel (1, 1, 0, a); OIIO_CHECK_EQUAL (b[0], gray[0]); OIIO_CHECK_EQUAL (b[1], a[0]); OIIO_CHECK_EQUAL (b[2], a[1]); B.getpixel (3, 4, 0, b); A.getpixel (2, 3, 0, a); OIIO_CHECK_EQUAL (b[0], gray[0]); OIIO_CHECK_EQUAL (b[1], a[0]); OIIO_CHECK_EQUAL (b[2], a[1]); } void test_channel_append () { std::cout << "test channel_append\n"; ImageSpec spec (2, 2, 1, TypeDesc::FLOAT); ImageBuf A (spec); ImageBuf B (spec); float Acolor = 0.1, Bcolor = 0.2; ImageBufAlgo::fill (A, &Acolor); ImageBufAlgo::fill (B, &Bcolor); ImageBuf R ("R"); ImageBufAlgo::channel_append (R, A, B); OIIO_CHECK_EQUAL (R.spec().width, spec.width); OIIO_CHECK_EQUAL (R.spec().height, spec.height); OIIO_CHECK_EQUAL (R.nchannels(), 2); for (ImageBuf::ConstIterator r(R); !r.done(); ++r) { OIIO_CHECK_EQUAL (r[0], Acolor); OIIO_CHECK_EQUAL (r[1], Bcolor); } } // Tests ImageBufAlgo::add void test_add () { std::cout << "test add\n"; const int WIDTH = 8; const int HEIGHT = 8; const int CHANNELS = 4; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); spec.alpha_channel = 3; // Create buffers ImageBuf A (spec); const float Aval[CHANNELS] = { 0.1, 0.2, 0.3, 0.4 }; ImageBufAlgo::fill (A, Aval); ImageBuf B (spec); const float Bval[CHANNELS] = { 0.01, 0.02, 0.03, 0.04 }; ImageBufAlgo::fill (B, Bval); ImageBuf C (spec); ImageBufAlgo::add (C, A, B); for (int j = 0; j < HEIGHT; ++j) { for (int i = 0; i < WIDTH; ++i) { float pixel[CHANNELS]; C.getpixel (i, j, pixel); for (int c = 0; c < CHANNELS; ++c) OIIO_CHECK_EQUAL (pixel[c], Aval[c]+Bval[c]); } } } // Tests ImageBufAlgo::compare void test_compare () { std::cout << "test compare\n"; // Construct two identical 50% grey images const int WIDTH = 10, HEIGHT = 10, CHANNELS = 3; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); ImageBuf A (spec); ImageBuf B (spec); const float grey[CHANNELS] = { 0.5, 0.5, 0.5 }; ImageBufAlgo::fill (A, grey); ImageBufAlgo::fill (B, grey); // Introduce some minor differences const int NDIFFS = 10; ImageBuf::Iterator a (A); for (int i = 0; i < NDIFFS && a.valid(); ++i, ++a) { for (int c = 0; c < CHANNELS; ++c) a[c] = a[c] + 0.01f * i; } // We expect the differences to be { 0, 0.01, 0.02, 0.03, 0.04, 0.05, // 0.06, 0.07, 0.08, 0.09, 0, 0, ...}. const float failthresh = 0.05; const float warnthresh = 0.025; ImageBufAlgo::CompareResults comp; ImageBufAlgo::compare (A, B, failthresh, warnthresh, comp); // We expect 5 pixels to exceed the fail threshold, 7 pixels to // exceed the warn threshold, the maximum difference to be 0.09, // and the maximally different pixel to be (9,0). // The total error should be 3 chans * sum{0.01,...,0.09} / (pixels*chans) // = 3 * 0.45 / (100*3) = 0.0045 std::cout << "Testing comparison: " << comp.nfail << " failed, " << comp.nwarn << " warned, max diff = " << comp.maxerror << " @ (" << comp.maxx << ',' << comp.maxy << ")\n"; std::cout << " mean err " << comp.meanerror << ", RMS err " << comp.rms_error << ", PSNR = " << comp.PSNR << "\n"; OIIO_CHECK_EQUAL (comp.nfail, 5); OIIO_CHECK_EQUAL (comp.nwarn, 7); OIIO_CHECK_EQUAL_THRESH (comp.maxerror, 0.09, 1e-6); OIIO_CHECK_EQUAL (comp.maxx, 9); OIIO_CHECK_EQUAL (comp.maxy, 0); OIIO_CHECK_EQUAL_THRESH (comp.meanerror, 0.0045, 1.0e-8); } // Tests ImageBufAlgo::isConstantColor void test_isConstantColor () { std::cout << "test isConstantColor\n"; const int WIDTH = 10, HEIGHT = 10, CHANNELS = 3; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); ImageBuf A (spec); const float col[CHANNELS] = { 0.25, 0.5, 0.75 }; ImageBufAlgo::fill (A, col); float thecolor[CHANNELS] = { 0, 0, 0 }; OIIO_CHECK_EQUAL (ImageBufAlgo::isConstantColor (A), true); OIIO_CHECK_EQUAL (ImageBufAlgo::isConstantColor (A, thecolor), true); OIIO_CHECK_EQUAL (col[0], thecolor[0]); OIIO_CHECK_EQUAL (col[1], thecolor[1]); OIIO_CHECK_EQUAL (col[2], thecolor[2]); // Now introduce a difference const float another[CHANNELS] = { 0, 1, 1 }; A.setpixel (2, 2, 0, another, 3); OIIO_CHECK_EQUAL (ImageBufAlgo::isConstantColor (A), false); OIIO_CHECK_EQUAL (ImageBufAlgo::isConstantColor (A, thecolor), false); // Make sure ROI works ROI roi (0, WIDTH, 0, 2, 0, 1, 0, CHANNELS); // should match for this ROI OIIO_CHECK_EQUAL (ImageBufAlgo::isConstantColor (A, NULL, roi), true); } // Tests ImageBufAlgo::isConstantChannel void test_isConstantChannel () { std::cout << "test isConstantChannel\n"; const int WIDTH = 10, HEIGHT = 10, CHANNELS = 3; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); ImageBuf A (spec); const float col[CHANNELS] = { 0.25, 0.5, 0.75 }; ImageBufAlgo::fill (A, col); OIIO_CHECK_EQUAL (ImageBufAlgo::isConstantChannel (A, 1, 0.5f), true); // Now introduce a difference const float another[CHANNELS] = { 0, 1, 1 }; A.setpixel (2, 2, 0, another, 3); OIIO_CHECK_EQUAL (ImageBufAlgo::isConstantChannel (A, 1, 0.5f), false); // Make sure ROI works ROI roi (0, WIDTH, 0, 2, 0, 1, 0, CHANNELS); // should match for this ROI OIIO_CHECK_EQUAL (ImageBufAlgo::isConstantChannel (A, 1, 0.5f, roi), true); } // Tests ImageBufAlgo::isMonochrome void test_isMonochrome () { std::cout << "test isMonochrome\n"; const int WIDTH = 10, HEIGHT = 10, CHANNELS = 3; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); ImageBuf A (spec); const float col[CHANNELS] = { 0.25, 0.25, 0.25 }; ImageBufAlgo::fill (A, col); OIIO_CHECK_EQUAL (ImageBufAlgo::isMonochrome (A), true); // Now introduce a difference const float another[CHANNELS] = { 0.25, 0.25, 1 }; A.setpixel (2, 2, 0, another, 3); OIIO_CHECK_EQUAL (ImageBufAlgo::isMonochrome (A), false); // Make sure ROI works ROI roi (0, WIDTH, 0, 2, 0, 1, 0, CHANNELS); // should match for this ROI OIIO_CHECK_EQUAL (ImageBufAlgo::isMonochrome (A, roi), true); } // Test ability to do a maketx directly from an ImageBuf void test_maketx_from_imagebuf() { std::cout << "test make_texture from ImageBuf\n"; // Make a checkerboard const int WIDTH = 16, HEIGHT = 16, CHANNELS = 3; ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); ImageBuf A (spec); float pink[] = { .5, .3, .3 }, green[] = { .1, .5, .1 }; ImageBufAlgo::checker (A, 4, 4, 4, pink, green); // Write it const char *pgname = "oiio-pgcheck.tx"; remove (pgname); // Remove it first ImageSpec configspec; ImageBufAlgo::make_texture (ImageBufAlgo::MakeTxTexture, A, pgname, configspec); // Read it back and compare it ImageBuf B (pgname); B.read (); ImageBufAlgo::CompareResults comparison; ImageBufAlgo::compare (A, B, 0, 0, comparison); OIIO_CHECK_EQUAL (comparison.nwarn, 0); OIIO_CHECK_EQUAL (comparison.nfail, 0); remove (pgname); // clean up } int main (int argc, char **argv) { test_zero_fill (); test_crop (); test_paste (); test_channel_append (); test_add (); test_compare (); test_isConstantColor (); test_isConstantChannel (); test_isMonochrome (); test_maketx_from_imagebuf (); return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imageio.cpp0000644000175000017500000006616212271062644022024 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "strutil.h" #include "fmath.h" #include "thread.h" #include "imageio.h" #include "imageio_pvt.h" OIIO_NAMESPACE_ENTER { // Global private data namespace pvt { recursive_mutex imageio_mutex; atomic_int oiio_threads; ustring plugin_searchpath; std::string format_list; // comma-separated list of all formats std::string extension_list; // list of all extensions for all formats // Trick to initialize the atomic_int -- TBB doesn't allow direct ctr struct atomic_int_initializer { atomic_int_initializer(atomic_int &a, int value) { a = value; } }; atomic_int_initializer oiio_threads_init(oiio_threads, int(boost::thread::hardware_concurrency())); }; using namespace pvt; namespace { // To avoid thread oddities, we have the storage area buffering error // messages for seterror()/geterror() be thread-specific. static thread_specific_ptr thread_error_msg; // Return a reference to the string for this thread's error messages, // creating it if none exists for this thread thus far. static std::string & error_msg () { std::string *e = thread_error_msg.get(); if (! e) { e = new std::string; thread_error_msg.reset (e); } return *e; } } // end anon namespace int openimageio_version () { return OIIO_VERSION; } /// Error reporting for the plugin implementation: call this with /// printf-like arguments. void pvt::seterror (const std::string& message) { recursive_lock_guard lock (pvt::imageio_mutex); error_msg() = message; } std::string geterror () { recursive_lock_guard lock (pvt::imageio_mutex); std::string e = error_msg(); error_msg().clear (); return e; } namespace { // Private global OIIO data. static spin_mutex attrib_mutex; static const int maxthreads = 64; // reasonable maximum for sanity check }; bool attribute (const std::string &name, TypeDesc type, const void *val) { if (name == "threads" && type == TypeDesc::TypeInt) { int ot = Imath::clamp (*(const int *)val, 0, maxthreads); if (ot == 0) ot = boost::thread::hardware_concurrency(); oiio_threads = ot; return true; } spin_lock lock (attrib_mutex); if (name == "plugin_searchpath" && type == TypeDesc::TypeString) { plugin_searchpath = ustring (*(const char **)val); return true; } return false; } bool getattribute (const std::string &name, TypeDesc type, void *val) { if (name == "threads" && type == TypeDesc::TypeInt) { *(int *)val = oiio_threads; return true; } spin_lock lock (attrib_mutex); if (name == "plugin_searchpath" && type == TypeDesc::TypeString) { *(ustring *)val = plugin_searchpath; return true; } if (name == "format_list" && type == TypeDesc::TypeString) { if (format_list.empty()) pvt::catalog_all_plugins (plugin_searchpath.string()); *(ustring *)val = ustring(format_list); return true; } if (name == "extension_list" && type == TypeDesc::TypeString) { if (extension_list.empty()) pvt::catalog_all_plugins (plugin_searchpath.string()); *(ustring *)val = ustring(extension_list); return true; } return false; } inline int quantize (float value, float quant_black, float quant_white, int quant_min, int quant_max) { value = Imath::lerp ((float)quant_black, (float)quant_white, value); return Imath::clamp ((int)(value + 0.5f), quant_min, quant_max); } namespace { /// Type-independent template for turning potentially /// non-contiguous-stride data (e.g. "RGB RGB ") into contiguous-stride /// ("RGBRGB"). Caller must pass in a dst pointing to enough memory to /// hold the contiguous rectangle. Return a ptr to where the contiguous /// data ended up, which is either dst or src (if the strides indicated /// that data were already contiguous). template const T * _contiguize (const T *src, int nchannels, stride_t xstride, stride_t ystride, stride_t zstride, T *dst, int width, int height, int depth) { int datasize = sizeof(T); if (xstride == nchannels*datasize && ystride == xstride*width && (zstride == ystride*height || !zstride)) return src; if (depth < 1) // Safeguard against volume-unaware clients depth = 1; T *dstsave = dst; if (xstride == nchannels*datasize) { // Optimize for contiguous scanlines, but not from scanline to scanline for (int z = 0; z < depth; ++z, src = (const T *)((char *)src + zstride)) { const T *scanline = src; for (int y = 0; y < height; ++y, dst += nchannels*width, scanline = (const T *)((char *)scanline + ystride)) memcpy(dst, scanline, xstride * width); } } else { for (int z = 0; z < depth; ++z, src = (const T *)((char *)src + zstride)) { const T *scanline = src; for (int y = 0; y < height; ++y, scanline = (const T *)((char *)scanline + ystride)) { const T *pixel = scanline; for (int x = 0; x < width; ++x, pixel = (const T *)((char *)pixel + xstride)) for (int c = 0; c < nchannels; ++c) *dst++ = pixel[c]; } } } return dstsave; } } const void * pvt::contiguize (const void *src, int nchannels, stride_t xstride, stride_t ystride, stride_t zstride, void *dst, int width, int height, int depth, TypeDesc format) { switch (format.basetype) { case TypeDesc::FLOAT : return _contiguize ((const float *)src, nchannels, xstride, ystride, zstride, (float *)dst, width, height, depth); case TypeDesc::INT8: case TypeDesc::UINT8 : return _contiguize ((const char *)src, nchannels, xstride, ystride, zstride, (char *)dst, width, height, depth); case TypeDesc::HALF : DASSERT (sizeof(half) == sizeof(short)); case TypeDesc::INT16 : case TypeDesc::UINT16 : return _contiguize ((const short *)src, nchannels, xstride, ystride, zstride, (short *)dst, width, height, depth); case TypeDesc::INT : case TypeDesc::UINT : return _contiguize ((const int *)src, nchannels, xstride, ystride, zstride, (int *)dst, width, height, depth); case TypeDesc::INT64 : case TypeDesc::UINT64 : return _contiguize ((const long long *)src, nchannels, xstride, ystride, zstride, (long long *)dst, width, height, depth); case TypeDesc::DOUBLE : return _contiguize ((const double *)src, nchannels, xstride, ystride, zstride, (double *)dst, width, height, depth); default: ASSERT (0 && "OpenImageIO::contiguize : bad format"); return NULL; } } const float * pvt::convert_to_float (const void *src, float *dst, int nvals, TypeDesc format) { switch (format.basetype) { case TypeDesc::FLOAT : return (float *)src; case TypeDesc::UINT8 : convert_type ((const unsigned char *)src, dst, nvals); break; case TypeDesc::HALF : convert_type ((const half *)src, dst, nvals); break; case TypeDesc::UINT16 : convert_type ((const unsigned short *)src, dst, nvals); break; case TypeDesc::INT8: convert_type ((const char *)src, dst, nvals); break; case TypeDesc::INT16 : convert_type ((const short *)src, dst, nvals); break; case TypeDesc::INT : convert_type ((const int *)src, dst, nvals); break; case TypeDesc::UINT : convert_type ((const unsigned int *)src, dst, nvals); break; case TypeDesc::INT64 : convert_type ((const long long *)src, dst, nvals); break; case TypeDesc::UINT64 : convert_type ((const unsigned long long *)src, dst, nvals); break; case TypeDesc::DOUBLE : convert_type ((const double *)src, dst, nvals); break; default: ASSERT (0 && "ERROR to_float: bad format"); return NULL; } return dst; } template const void * _from_float (const float *src, T *dst, size_t nvals, float quant_black, float quant_white, int quant_min, int quant_max) { if (! src) { // If no source pixels, assume zeroes memset (dst, 0, nvals * sizeof(T)); T z = (T) quantize (0, quant_black, quant_white, quant_min, quant_max); for (size_t p = 0; p < nvals; ++p) dst[p] = z; } else if (std::numeric_limits ::is_integer) { // Convert float to non-float native format, with quantization for (size_t p = 0; p < nvals; ++p) dst[p] = (T) quantize (src[p], quant_black, quant_white, quant_min, quant_max); } else { // It's a floating-point type of some kind -- we don't apply // quantization if (sizeof(T) == sizeof(float)) { // It's already float -- return the source itself return src; } // Otherwise, it's converting between two fp types for (size_t p = 0; p < nvals; ++p) dst[p] = (T) src[p]; } return dst; } const void * pvt::convert_from_float (const float *src, void *dst, size_t nvals, int quant_black, int quant_white, int quant_min, int quant_max, TypeDesc format) { switch (format.basetype) { case TypeDesc::FLOAT : return src; case TypeDesc::HALF : return _from_float (src, (half *)dst, nvals, quant_black, quant_white, quant_min, quant_max); case TypeDesc::DOUBLE : return _from_float (src, (double *)dst, nvals, quant_black, quant_white, quant_min, quant_max); case TypeDesc::INT8: return _from_float (src, (char *)dst, nvals, quant_black, quant_white, quant_min, quant_max); case TypeDesc::UINT8 : return _from_float (src, (unsigned char *)dst, nvals, quant_black, quant_white, quant_min, quant_max); case TypeDesc::INT16 : return _from_float (src, (short *)dst, nvals, quant_black, quant_white, quant_min, quant_max); case TypeDesc::UINT16 : return _from_float (src, (unsigned short *)dst, nvals, quant_black, quant_white, quant_min, quant_max); case TypeDesc::INT : return _from_float (src, (int *)dst, nvals, quant_black, quant_white, quant_min, quant_max); case TypeDesc::UINT : return _from_float (src, (unsigned int *)dst, nvals, quant_black, quant_white, quant_min, quant_max); case TypeDesc::INT64 : return _from_float (src, (long long *)dst, nvals, quant_black, quant_white, quant_min, quant_max); case TypeDesc::UINT64 : return _from_float (src, (unsigned long long *)dst, nvals, quant_black, quant_white, quant_min, quant_max); default: ASSERT (0 && "ERROR from_float: bad format"); return NULL; } } const void * pvt::parallel_convert_from_float (const float *src, void *dst, size_t nvals, int quant_black, int quant_white, int quant_min, int quant_max, TypeDesc format, int nthreads) { if (format.basetype == TypeDesc::FLOAT) return src; const size_t quanta = 30000; if (nvals < quanta) nthreads = 1; if (nthreads <= 0) nthreads = oiio_threads; if (nthreads <= 1) return convert_from_float (src, dst, nvals, quant_black, quant_white, quant_min, quant_max, format); boost::thread_group threads; size_t blocksize = std::max (quanta, size_t((nvals + nthreads - 1) / nthreads)); for (size_t i = 0; i < size_t(nthreads); i++) { size_t begin = i * blocksize; if (begin >= nvals) break; // no more work to divvy up size_t end = std::min (begin + blocksize, nvals); threads.add_thread (new boost::thread ( boost::bind (convert_from_float, src+begin, (char *)dst+begin*format.size(), end-begin, quant_black, quant_white, quant_min, quant_max, format))); } threads.join_all (); return dst; } bool convert_types (TypeDesc src_type, const void *src, TypeDesc dst_type, void *dst, int n) { // If no conversion is necessary, just memcpy if ((src_type == dst_type || dst_type.basetype == TypeDesc::UNKNOWN)) { memcpy (dst, src, n * src_type.size()); return true; } if (dst_type == TypeDesc::TypeFloat) { // Special case -- converting non-float to float pvt::convert_to_float (src, (float *)dst, n, src_type); return true; } // Conversion is to a non-float type boost::scoped_array tmp; // In case we need a lot of temp space float *buf = (float *)src; if (src_type != TypeDesc::TypeFloat) { // If src is also not float, convert through an intermediate buffer if (n <= 4096) // If < 16k, use the stack buf = ALLOCA (float, n); else { tmp.reset (new float[n]); // Freed when tmp exists its scope buf = tmp.get(); } pvt::convert_to_float (src, buf, n, src_type); } // Convert float to 'dst_type' switch (dst_type.basetype) { case TypeDesc::UINT8 : convert_type (buf, (unsigned char *)dst, n); break; case TypeDesc::UINT16 : convert_type (buf, (unsigned short *)dst, n); break; case TypeDesc::HALF : convert_type (buf, (half *)dst, n); break; case TypeDesc::INT8 : convert_type (buf, (char *)dst, n); break; case TypeDesc::INT16 : convert_type (buf, (short *)dst, n); break; case TypeDesc::INT : convert_type (buf, (int *)dst, n); break; case TypeDesc::UINT : convert_type (buf, (unsigned int *)dst, n); break; case TypeDesc::INT64 : convert_type (buf, (long long *)dst, n); break; case TypeDesc::UINT64 : convert_type (buf, (unsigned long long *)dst, n); break; case TypeDesc::DOUBLE : convert_type (buf, (double *)dst, n); break; default: return false; // unknown format } return true; } // Deprecated version -- keep for link compatibiity bool convert_types (TypeDesc src_type, const void *src, TypeDesc dst_type, void *dst, int n, int alpha_channel, int z_channel) { return convert_types (src_type, src, dst_type, dst, n); } bool convert_image (int nchannels, int width, int height, int depth, const void *src, TypeDesc src_type, stride_t src_xstride, stride_t src_ystride, stride_t src_zstride, void *dst, TypeDesc dst_type, stride_t dst_xstride, stride_t dst_ystride, stride_t dst_zstride, int alpha_channel, int z_channel) { // If no format conversion is taking place, use the simplified // copy_image. if (src_type == dst_type) return copy_image (nchannels, width, height, depth, src, src_type.size()*nchannels, src_xstride, src_ystride, src_zstride, dst, dst_xstride, dst_ystride, dst_zstride); ImageSpec::auto_stride (src_xstride, src_ystride, src_zstride, src_type, nchannels, width, height); ImageSpec::auto_stride (dst_xstride, dst_ystride, dst_zstride, dst_type, nchannels, width, height); bool result = true; bool contig = (src_xstride == dst_xstride && src_xstride == stride_t(nchannels*src_type.size())); for (int z = 0; z < depth; ++z) { for (int y = 0; y < height; ++y) { const char *f = (const char *)src + (z*src_zstride + y*src_ystride); char *t = (char *)dst + (z*dst_zstride + y*dst_ystride); if (contig) { // Special case: pixels within each row are contiguous // in both src and dst and we're copying all channels. // Be efficient by converting each scanline as a single // unit. (Note that within convert_types, a memcpy will // be used if the formats are identical.) result &= convert_types (src_type, f, dst_type, t, nchannels*width, alpha_channel, z_channel); } else { // General case -- anything goes with strides. for (int x = 0; x < width; ++x) { result &= convert_types (src_type, f, dst_type, t, nchannels, alpha_channel, z_channel); f += src_xstride; t += dst_xstride; } } } } return result; } namespace { // This nonsense is just to get around the 10-arg limits of boost::bind // for compilers that don't have variadic templates. struct convert_image_wrapper { convert_image_wrapper (int nchannels, int width, int height, int depth, const void *src, TypeDesc src_type, stride_t src_xstride, stride_t src_ystride, stride_t src_zstride, void *dst, TypeDesc dst_type, stride_t dst_xstride, stride_t dst_ystride, stride_t dst_zstride, int alpha_channel, int z_channel) : nchannels(nchannels), width(width), height(height), depth(depth), src(src), src_type(src_type), src_xstride(src_xstride), src_ystride(src_ystride), src_zstride(src_zstride), dst(dst), dst_type(dst_type), dst_xstride(dst_xstride), dst_ystride(dst_ystride), dst_zstride(dst_zstride), alpha_channel(alpha_channel), z_channel(z_channel) { } void operator() () { convert_image (nchannels, width, height, depth, src, src_type, src_xstride, src_ystride, src_zstride, dst, dst_type, dst_xstride, dst_ystride, dst_zstride, alpha_channel, z_channel); } private: int nchannels, width, height, depth; const void *src; TypeDesc src_type; stride_t src_xstride, src_ystride, src_zstride; void *dst; TypeDesc dst_type; stride_t dst_xstride, dst_ystride, dst_zstride; int alpha_channel, z_channel; }; } // anon namespace bool parallel_convert_image (int nchannels, int width, int height, int depth, const void *src, TypeDesc src_type, stride_t src_xstride, stride_t src_ystride, stride_t src_zstride, void *dst, TypeDesc dst_type, stride_t dst_xstride, stride_t dst_ystride, stride_t dst_zstride, int alpha_channel, int z_channel, int nthreads) { if (imagesize_t(width)*height*depth*nchannels < 30000) nthreads = 1; if (nthreads <= 0) nthreads = oiio_threads; if (nthreads <= 1) return convert_image (nchannels, width, height, depth, src, src_type, src_xstride, src_ystride, src_zstride, dst, dst_type, dst_xstride, dst_ystride, dst_zstride, alpha_channel, z_channel); ImageSpec::auto_stride (src_xstride, src_ystride, src_zstride, src_type, nchannels, width, height); ImageSpec::auto_stride (dst_xstride, dst_ystride, dst_zstride, dst_type, nchannels, width, height); boost::thread_group threads; int blocksize = std::max (1, (height + nthreads - 1) / nthreads); for (int i = 0; i < nthreads; i++) { int ybegin = i * blocksize; if (ybegin >= height) break; // no more work to divvy up int yend = std::min (ybegin + blocksize, height); convert_image_wrapper ciw (nchannels, width, yend-ybegin, depth, (const char *)src+src_ystride*ybegin, src_type, src_xstride, src_ystride, src_zstride, (char *)dst+dst_ystride*ybegin, dst_type, dst_xstride, dst_ystride, dst_zstride, alpha_channel, z_channel); threads.add_thread (new boost::thread (ciw)); } threads.join_all (); return true; } bool copy_image (int nchannels, int width, int height, int depth, const void *src, stride_t pixelsize, stride_t src_xstride, stride_t src_ystride, stride_t src_zstride, void *dst, stride_t dst_xstride, stride_t dst_ystride, stride_t dst_zstride) { stride_t channelsize = pixelsize / nchannels; ImageSpec::auto_stride (src_xstride, src_ystride, src_zstride, channelsize, nchannels, width, height); ImageSpec::auto_stride (dst_xstride, dst_ystride, dst_zstride, channelsize, nchannels, width, height); bool contig = (src_xstride == dst_xstride && src_xstride == (stride_t)pixelsize); for (int z = 0; z < depth; ++z) { for (int y = 0; y < height; ++y) { const char *f = (const char *)src + (z*src_zstride + y*src_ystride); char *t = (char *)dst + (z*dst_zstride + y*dst_ystride); if (contig) { // Special case: pixels within each row are contiguous // in both src and dst and we're copying all channels. // Be efficient by converting each scanline as a single // unit. memcpy (t, f, width*pixelsize); } else { // General case -- anything goes with strides. for (int x = 0; x < width; ++x) { memcpy (t, f, pixelsize); f += src_xstride; t += dst_xstride; } } } } return true; } void DeepData::init (int npix, int nchan, const TypeDesc *chbegin, const TypeDesc *chend) { clear (); npixels = npix; nchannels = nchan; channeltypes.assign (chbegin, chend); nsamples.resize (npixels, 0); pointers.resize (size_t(npixels)*size_t(nchannels), NULL); } void DeepData::alloc () { // Calculate the total size we need, align each channel to 4 byte boundary size_t totalsamples = 0, totalbytes = 0; for (int i = 0; i < npixels; ++i) { int s = nsamples[i]; totalsamples += s; for (int c = 0; c < nchannels; ++c) totalbytes += round_to_multiple (channeltypes[c].size() * s, 4); } // Set all the data pointers to the right offsets within the // data block. Leave the pointes NULL for pixels with no samples. data.resize (totalbytes); char *p = &data[0]; for (int i = 0; i < npixels; ++i) { if (nsamples[i]) { for (int c = 0; c < nchannels; ++c) { pointers[i*nchannels+c] = p; p += round_to_multiple (channeltypes[c].size()*nsamples[i], 4); } } } } void DeepData::clear () { npixels = 0; nchannels = 0; channeltypes.clear(); nsamples.clear(); pointers.clear(); data.clear(); } void DeepData::free () { std::vector().swap (nsamples); std::vector().swap (pointers); std::vector().swap (data); } bool wrap_black (int &coord, int origin, int width) { return (coord >= origin && coord < (width+origin)); } bool wrap_clamp (int &coord, int origin, int width) { if (coord < origin) coord = origin; else if (coord >= origin+width) coord = origin+width-1; return true; } bool wrap_periodic (int &coord, int origin, int width) { coord -= origin; coord %= width; if (coord < 0) // Fix negative values coord += width; coord += origin; return true; } bool wrap_periodic_pow2 (int &coord, int origin, int width) { DASSERT (ispow2(width)); coord -= origin; coord &= (width - 1); // Shortcut periodic if we're sure it's a pow of 2 coord += origin; return true; } bool wrap_mirror (int &coord, int origin, int width) { coord -= origin; if (coord < 0) coord = -coord - 1; int iter = coord / width; // Which iteration of the pattern? coord -= iter * width; if (iter & 1) // Odd iterations -- flip the sense coord = width - 1 - coord; DASSERT_MSG (coord >= 0 && coord < width, "width=%d, origin=%d, result=%d", width, origin, coord); coord += origin; return true; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/spin_rw_test.cpp0000644000175000017500000001272512271062644023126 0ustar mfvmfv/* Copyright 2012 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include "thread.h" #include "strutil.h" #include "timer.h" #include "argparse.h" #include "ustring.h" #include #include #include "unittest.h" OIIO_NAMESPACE_USING; // Test spin_rw_mutex by creating a bunch of threads usually just check // the accumulator value (requiring a read lock), but occasionally // (1/100 of the time) increment the accumulator, requiring a write // lock. If, at the end, the accumulated value is equal to // iterations/read_to_write_ratio*threads, then the locks worked. static int read_write_ratio = 99; static int iterations = 16000000; static int numthreads = 16; static int ntrials = 1; static bool verbose = false; static bool wedge = false; volatile long long accum = 0; spin_rw_mutex mymutex; static void do_accum (int iterations) { for (int i = 0; i < iterations; ++i) { if ((i % (read_write_ratio+1)) == read_write_ratio) { spin_rw_write_lock lock (mymutex); accum += 1; } else { spin_rw_read_lock lock (mymutex); // meaningless test to force examination of the variable if (accum < 0) break; } } } void test_spin_rw (int numthreads, int iterations) { accum = 0; boost::thread_group threads; for (int i = 0; i < numthreads; ++i) { threads.create_thread (boost::bind(do_accum,iterations)); } if (verbose) std::cout << "Created " << threads.size() << " threads\n"; threads.join_all (); OIIO_CHECK_EQUAL (accum, (((long long)iterations/(read_write_ratio+1)) * (long long)numthreads)); if (verbose) std::cout << "it " << iterations << ", r::w = " << read_write_ratio << ", accum = " << accum << "\n"; } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap; ap.options ("spin_rw_test\n" OIIO_INTRO_STRING "\n" "Usage: spin_rw_test [options]", // "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose mode", "--threads %d", &numthreads, ustring::format("Number of threads (default: %d)", numthreads).c_str(), "--iters %d", &iterations, ustring::format("Number of iterations (default: %d)", iterations).c_str(), "--trials %d", &ntrials, "Number of trials", "--rwratio %d", &read_write_ratio, ustring::format("Reader::writer ratio (default: %d)", read_write_ratio).c_str(), "--wedge", &wedge, "Do a wedge test", NULL); if (ap.parse (argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } } int main (int argc, char *argv[]) { getargs (argc, argv); std::cout << "hw threads = " << boost::thread::hardware_concurrency() << "\n"; std::cout << "reader:writer ratio = " << read_write_ratio << ":1\n"; std::cout << "threads\ttime (best of " << ntrials << ")\n"; std::cout << "-------\t----------\n"; static int threadcounts[] = { 1, 2, 4, 8, 12, 16, 20, 24, 28, 32, 64, 128, 1024, 1<<30 }; for (int i = 0; threadcounts[i] <= numthreads; ++i) { int nt = threadcounts[i]; int its = iterations/nt; double range; double t = time_trial (boost::bind(test_spin_rw,nt,its), ntrials, &range); std::cout << Strutil::format ("%2d\t%s\t%5.1fs, range %.1f\t(%d iters/thread)\n", nt, Strutil::timeintervalformat(t), t, range, its); if (! wedge) break; // don't loop if we're not wedging } return unit_test_failures; } openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/xmp.cpp0000644000175000017500000006221012271062644021204 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "thread.h" #include "strutil.h" #include "fmath.h" #include "imageio.h" #include #define DEBUG_XMP_READ 0 #define DEBUG_XMP_WRITE 0 #define MY_ENCODING "ISO-8859-1" OIIO_NAMESPACE_ENTER { namespace { // anonymous // Define special processing flags -- they're individual bits so can be // combined with '|' enum XMPspecial { NothingSpecial = 0, Rational = 1, // It needs to be expressed as A/B DateConversion = 2, // It's a date, may need conversion to canonical form TiffRedundant = 4, // It's something that's part of normal TIFF tags ExifRedundant = 8, // It's something included in Exif Suppress = 16, // Explicitly suppress it from XMP IsList = 32, // Make a semicolon-separated list out of it IsSeq = 64, // Like List, but order matters IsBool = 128 // Should be output as True/False }; struct XMPtag { const char *xmpname; // XMP name const char *oiioname; // Attribute name we use TypeDesc oiiotype; // Type we use int special; // Special handling }; static XMPtag xmptag [] = { { "photoshop:AuthorsPosition", "IPTC:AuthorsPosition", TypeDesc::STRING, 0 }, { "photoshop:CaptionWriter", "IPTC:CaptionWriter", TypeDesc::STRING, 0 }, { "photoshop:Category", "IPTC:Category", TypeDesc::STRING, 0 }, { "photoshop:City", "IPTC:City", TypeDesc::STRING, 0 }, { "photoshop:Country", "IPTC:Country", TypeDesc::STRING, 0 }, { "photoshop:Credit", "IPTC:Provider", TypeDesc::STRING, 0 }, { "photoshop:DateCreated", "DateTime", TypeDesc::STRING, DateConversion|TiffRedundant }, { "photoshop:Headline", "IPTC:Headline", TypeDesc::STRING, 0 }, { "photoshop:Instructions", "IPTC:Instructions", TypeDesc::STRING, 0 }, { "photoshop:Source", "IPTC:Source", TypeDesc::STRING, 0 }, { "photoshop:State", "IPTC:State", TypeDesc::STRING, 0 }, { "photoshop:SupplementalCategories", "IPTC:SupplementalCategories", TypeDesc::STRING, IsList|Suppress }, // FIXME -- un-suppress when we have it working { "photoshop:TransmissionReference", "IPTC:TransmissionReference", TypeDesc::STRING, 0 }, { "photoshop:Urgency", "photoshop:Urgency", TypeDesc::INT, 0 }, { "tiff:Compression", "tiff:Compression", TypeDesc::INT, TiffRedundant }, { "tiff:PlanarConfiguration", "tiff:PlanarConfiguration", TypeDesc::INT, TiffRedundant }, { "tiff:PhotometricInterpretation", "tiff:PhotometricInterpretation", TypeDesc::INT, TiffRedundant }, { "tiff:subfiletype", "tiff:subfiletype", TypeDesc::INT, TiffRedundant }, { "tiff:Orientation", "Orientation", TypeDesc::INT, TiffRedundant }, { "tiff:XResolution", "XResolution", TypeDesc::FLOAT, Rational|TiffRedundant }, { "tiff:YResolution", "YResolution", TypeDesc::FLOAT, Rational|TiffRedundant }, { "tiff:ResolutionUnit", "ResolutionUnit", TypeDesc::INT, TiffRedundant }, { "exif:ColorSpace", "Exif:ColorSpace", TypeDesc::INT, ExifRedundant }, { "exifEX:PhotographicSensitivity", "Exif:ISOSpeedRatings", TypeDesc::INT, ExifRedundant }, { "xmp:CreateDate", "DateTime", TypeDesc::STRING, DateConversion|TiffRedundant }, { "xmp:CreatorTool", "Software", TypeDesc::STRING, TiffRedundant }, { "xmp:Label", "IPTC:Label", TypeDesc::STRING, 0 }, { "xmp:MetadataDate", "IPTC:MetadataDate", TypeDesc::STRING, DateConversion }, { "xmp:ModifyDate", "IPTC:ModifyDate", TypeDesc::STRING, DateConversion }, { "xmp:Rating", "IPTC:Rating", TypeDesc::INT, 0 }, { "xmpMM:DocumentID", "IPTC:DocumentID", TypeDesc::STRING, 0 }, { "xmpMM:History", "ImageHistory", TypeDesc::STRING, IsSeq|Suppress }, { "xmpMM:InstanceID", "IPTC:InstanceID", TypeDesc::STRING, 0 }, { "xmpMM:OriginalDocumentID", "IPTC:OriginalDocumentID", TypeDesc::STRING, 0 }, { "xmpRights:Marked", "IPTC:CopyrightStatus", TypeDesc::INT, IsBool }, { "xmpRights:WebStatement", "IPTC:CopyrightInfoURL", TypeDesc::STRING, 0 }, { "xmpRights:UsageTerms", "IPTC:RightsUsageTerms", TypeDesc::STRING, 0 }, { "dc:format", "", TypeDesc::STRING, TiffRedundant|Suppress }, { "dc:Description", "ImageDescription", TypeDesc::STRING, TiffRedundant }, { "dc:Creator", "Artist", TypeDesc::STRING, TiffRedundant }, { "dc:Rights", "Copyright", TypeDesc::STRING, TiffRedundant }, { "dc:title", "IPTC:ObjectName", TypeDesc::STRING, 0 }, { "dc:subject", "Keywords", TypeDesc::STRING, IsList }, { "dc:keywords", "Keywords", TypeDesc::STRING, IsList }, { "Iptc4xmpCore:IntellectualGenre", "IPTC:IntellectualGenre", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CountryCode", "IPTC:CountryCode", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CreatorContactInfo", "IPTC:CreatorContactInfo", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:ContactInfoDetails", "IPTC:Contact", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CiAdrExtadr", "IPTC:ContactInfoAddress", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CiAdrCity", "IPTC:ContactInfoCity", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CiAdrRegion", "IPTC:ContactInfoState", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CiAdrPcode", "IPTC:ContactInfoPostalCode", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CiAdrCtry", "IPTC:ContactInfoCountry", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CiEmailWork", "IPTC:ContactInfoEmail", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CiTelWork", "IPTC:ContactInfoPhone", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:CiUrlWork", "IPTC:ContactInfoURL", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:Location", "IPTC:Sublocation", TypeDesc::STRING, 0 }, { "Iptc4xmpCore:SubjectCode", "IPTC:SubjectCode", TypeDesc::STRING, IsList }, { "Iptc4xmpCore:Scene", "IPTC:SceneCode", TypeDesc::STRING, IsList }, { "Iptc4xmpExt:PersonInImage", "IPTC:PersonInImage", TypeDesc::STRING, IsList }, { "rdf:li", "" }, // ignore these strays { NULL, NULL } }; // Utility: add an attribute to the spec with the given xml name and // value. Search for it in xmptag, and if found that will tell us what // the type is supposed to be, as well as any special handling. If not // found in the table, add it as a string and hope for the best. static void add_attrib (ImageSpec &spec, const char *xmlname, const char *xmlvalue) { #if DEBUG_XMP_READ std::cerr << "add_attrib " << xmlname << ": '" << xmlvalue << "'\n"; #endif for (int i = 0; xmptag[i].xmpname; ++i) { if (Strutil::iequals (xmptag[i].xmpname, xmlname)) { if (! xmptag[i].oiioname || ! xmptag[i].oiioname[0]) return; // ignore it purposefully if (xmptag[i].oiiotype == TypeDesc::STRING) { std::string val; if (xmptag[i].special & (IsList|IsSeq)) { // Special case -- append it to a list std::vector items; ImageIOParameter *p = spec.find_attribute (xmptag[i].oiioname, TypeDesc::STRING); bool dup = false; if (p) { Strutil::split (*(const char **)p->data(), items, ";"); for (size_t item = 0; item < items.size(); ++item) { items[item] = Strutil::strip (items[item]); dup |= (items[item] == xmlvalue); } dup |= (xmlvalue == std::string(*(const char **)p->data())); } if (! dup) items.push_back (xmlvalue); val = Strutil::join (items, "; "); } else { val = xmlvalue; } spec.attribute (xmptag[i].oiioname, val); return; } else if (xmptag[i].oiiotype == TypeDesc::INT) { if (xmptag[i].special & IsBool) spec.attribute (xmptag[i].oiioname, (int)Strutil::iequals(xmlvalue,"true")); else // ordinary int spec.attribute (xmptag[i].oiioname, (int)atoi(xmlvalue)); return; } else if (xmptag[i].oiiotype == TypeDesc::FLOAT) { float f = atoi (xmlvalue); const char *slash = strchr (xmlvalue, '/'); if (slash) // It's rational! f /= (float) atoi (slash+1); spec.attribute (xmptag[i].oiioname, f); return; } #if (!defined(NDEBUG) || DEBUG_XMP_READ) else { std::cerr << "iptc xml add_attrib unknown type " << xmlname << ' ' << xmptag[i].oiiotype.c_str() << "\n"; } #endif return; } } // Catch-all for unrecognized things -- just add them! spec.attribute (xmlname, xmlvalue); } // Utility: Search str for the first substring in str (starting from // position pos) that starts with startmarker and ends with endmarker. // If not found, return false. If found, return true, store the // beginning and ending indices in startpos and endpos. static bool extract_middle (const std::string &str, size_t pos, const char *startmarker, const char *endmarker, size_t &startpos, size_t &endpos) { startpos = str.find (startmarker, pos); if (startpos == std::string::npos) return false; // start marker not found endpos = str.find (endmarker, startpos); if (endpos == std::string::npos) return false; // end marker not found endpos += strlen (endmarker); return true; } static void decode_xmp_node (pugi::xml_node node, ImageSpec &spec, int level=1, const char *parentname=NULL, bool isList=false) { std::string mylist; // will accumulate for list items for ( ; node; node = node.next_sibling()) { #if DEBUG_XMP_READ std::cerr << "Level " << level << " " << node.name() << " = " << node.value() << "\n"; #endif // First, encode all attributes of this node for (pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute()) { #if DEBUG_XMP_READ std::cerr << " level " << level << " parent " << (parentname?parentname:"-") << " attr " << attr.name() << ' ' << attr.value() << "\n"; #endif if (Strutil::istarts_with(attr.name(), "xml:") || Strutil::istarts_with(attr.name(), "xmlns:")) continue; // xml attributes aren't image metadata if (attr.name()[0] && attr.value()[0]) add_attrib (spec, attr.name(), attr.value()); } if (Strutil::iequals(node.name(), "xmpMM::History")) { // FIXME -- image history is complicated. Come back to it. continue; } if (Strutil::iequals(node.name(), "rdf:Bag") || Strutil::iequals(node.name(), "rdf:Seq") || Strutil::iequals(node.name(), "rdf:Alt") || Strutil::iequals(node.name(), "rdf:li")) { // Various kinds of lists. Recuse, pass the parent name // down, and let the child know it's part of a list. decode_xmp_node (node.first_child(), spec, level+1, parentname, true); } else { // Not a list, but it's got children. Recurse. decode_xmp_node (node.first_child(), spec, level+1, node.name()); } // If this node has a value but no name, it's definitely part // of a list. Accumulate the list items, separated by semicolons. if (parentname && !node.name()[0] && node.value()[0]) { if (mylist.size()) mylist += ";"; mylist += node.value(); } } // If we have accumulated a list, turn it into an attribute if (parentname && mylist.size()) { add_attrib (spec, parentname, mylist.c_str()); } } } // anonymous namespace bool decode_xmp (const std::string &xml, ImageSpec &spec) { #if DEBUG_XMP_READ std::cerr << "XMP dump:\n---\n" << xml << "\n---\n"; #endif if (! xml.length()) return true; for (size_t startpos = 0, endpos = 0; extract_middle (xml, endpos, "", startpos, endpos); ) { // Turn that middle section into an XML document std::string rdf (xml, startpos, endpos-startpos); // scooch in #if DEBUG_XMP_READ std::cerr << "RDF is:\n---\n" << rdf << "\n---\n"; #endif pugi::xml_document doc; pugi::xml_parse_result parse_result = doc.load_buffer (&rdf[0], rdf.size()); if (! parse_result) { #if DEBUG_XMP_READ std::cerr << "Error parsing XML\n"; #endif return true; } // Decode the contents of the XML document (it will recurse) decode_xmp_node (doc.first_child(), spec); } return true; } // Turn one ImageIOParameter (whose xmp info we know) into a properly // serialized xmp string. static std::string stringize (const ImageIOParameterList::const_iterator &p, const XMPtag &xmptag) { if (p->type() == TypeDesc::STRING) { if (xmptag.special & DateConversion) { // FIXME -- convert to yyyy-mm-ddThh:mm:ss.sTZD // return std::string(); } return std::string(*(const char **)p->data()); } else if (p->type() == TypeDesc::INT) { if (xmptag.special & IsBool) return *(const int *)p->data() ? "True" : "False"; else // ordinary int return Strutil::format ("%d", *(const int *)p->data()); } else if (p->type() == TypeDesc::FLOAT) { if (xmptag.special & Rational) { unsigned int num, den; float_to_rational (*(const float *)p->data(), num, den); return Strutil::format ("%d/%d", num, den); } else { return Strutil::format ("%g", *(const float *)p->data()); } } return std::string(); } static void gather_xmp_attribs (const ImageSpec &spec, std::vector > &list) { // Loop over all params... for (ImageIOParameterList::const_iterator p = spec.extra_attribs.begin(); p != spec.extra_attribs.end(); ++p) { // For this param, see if there's a table entry with a matching // name, where the xmp name is in the right category. for (int i = 0; xmptag[i].xmpname; ++i) { if (! Strutil::iequals (p->name().c_str(), xmptag[i].oiioname)) continue; // Name doesn't match if (xmptag[i].special & Suppress) { break; // Purposely suppressing } std::string s = stringize (p,xmptag[i]); if (s.size()) { list.push_back (std::pair(i, s)); //std::cerr << " " << xmptag[i].xmpname << " = " << s << "\n"; } } } } enum XmpControl { XMP_suppress, XMP_nodes, XMP_attribs, XMP_SeqList, // sequential list XMP_BagList, // unordered list XMP_AltList // alternate list, WTF is that? }; // Turn an entire category of XMP items into a properly serialized // xml fragment. static std::string encode_xmp_category (std::vector > &list, const char *xmlnamespace, const char *pattern, const char *exclude_pattern, const char *nodename, const char *url, bool minimal, XmpControl control) { std::string category = std::string(xmlnamespace) + ':'; std::string xmp; std::string xmp_minimal; #if DEBUG_XMP_WRITE std::cerr << "Category " << xmlnamespace << ", pattern '" << pattern << "'\n"; #endif // Loop over all params... bool found = false; for (size_t li = 0; li < list.size(); ++li) { // For this param, see if there's a table entry with a matching // name, where the xmp name is in the right category. int i = list[li].first; const std::string &val (list[li].second); const char *xmpname (xmptag[i].xmpname); if (control == XMP_attribs && (xmptag[i].special & (IsList|IsSeq))) continue; // Skip lists for attrib output if (exclude_pattern && exclude_pattern[0] && Strutil::istarts_with (xmpname, exclude_pattern)) { continue; } if (Strutil::istarts_with (xmpname, pattern)) { std::string x; if (control == XMP_attribs) x = Strutil::format ("%s=\"%s\"", xmpname, val); else if (control == XMP_AltList || control == XMP_BagList) { std::vector vals; Strutil::split (val, vals, ";"); for (size_t i = 0; i < vals.size(); ++i) { vals[i] = Strutil::strip (vals[i]); x += Strutil::format ("%s", vals[i]); } } else x = Strutil::format ("<%s>%s", xmpname, val, xmpname); if (! x.empty() && control != XMP_suppress) { if (! found) { // if (nodename && nodename[0]) { // x = Strutil::format("<%s ", nodename); // } } if (minimal && (xmptag[i].special & (TiffRedundant|ExifRedundant))) { if (xmp_minimal.size()) xmp_minimal += ' '; xmp_minimal += x; } else { if (xmp.size()) xmp += ' '; xmp += x; } found = true; #if DEBUG_XMP_WRITE std::cerr << " going to output '" << x << "'\n"; #endif } #if DEBUG_XMP_WRITE else std::cerr << " NOT going to output '" << x << "'\n"; #endif list.erase (list.begin()+li); --li; } } if (xmp.length() && xmp_minimal.length()) xmp += ' ' + xmp_minimal; #if 1 if (xmp.length()) { if (control == XMP_BagList) xmp = Strutil::format ("<%s> %s ", nodename ? nodename : xmlnamespace, xmp, nodename ? nodename : xmlnamespace); else if (control == XMP_SeqList) xmp = Strutil::format ("<%s> %s ", nodename ? nodename : xmlnamespace, xmp, nodename ? nodename : xmlnamespace); else if (control == XMP_AltList) xmp = Strutil::format ("<%s> %s ", nodename ? nodename : xmlnamespace, xmp, nodename ? nodename : xmlnamespace); #if 0 else if (control == XMP_nodes) xmp = Strutil::format("<%s>%s", nodename ? nodename : xmlnamespace, xmp, nodename ? nodename : xmlnamespace); nodename); #endif std::string r; r += Strutil::format (""); r += xmp; if (control == XMP_attribs) r += "/> "; // end the > list; gather_xmp_attribs (spec, list); std::string xmp; #if 1 // This stuff seems to work xmp += encode_xmp_category (list, "photoshop", "photoshop:", NULL, NULL, "http://ns.adobe.com/photoshop/1.0/", minimal, XMP_attribs); xmp += encode_xmp_category (list, "xmp", "xmp:Rating", NULL, NULL, "http://ns.adobe.com/xap/1.0/", minimal, XMP_attribs); xmp += encode_xmp_category (list, "xmp", "xmp:CreateDate", NULL, NULL, "http://ns.adobe.com/xap/1.0/", false, XMP_attribs); xmp += encode_xmp_category (list, "xmp", "xmp:ModifyDate", NULL, NULL, "http://ns.adobe.com/xap/1.0/", false, XMP_attribs); xmp += encode_xmp_category (list, "xmp", "xmp:MetadataDate", NULL, NULL, "http://ns.adobe.com/xap/1.0/", false, XMP_attribs); xmp += encode_xmp_category (list, "xmpRights", "xmpRights:UsageTerms", NULL, "xmpRights:UsageTerms", "http://ns.adobe.com/xap/1.0/rights/", minimal, XMP_AltList); xmp += encode_xmp_category (list, "xmpRights", "xmpRights:", NULL, NULL, "http://ns.adobe.com/xap/1.0/rights/", minimal, XMP_attribs); xmp += encode_xmp_category (list, "dc", "dc:subject", NULL, "dc:subject", "http://purl.org/dc/elements/1.1/", minimal, XMP_BagList); xmp += encode_xmp_category (list, "Iptc4xmpCore", "Iptc4xmpCore:SubjectCode", NULL, "Iptc4xmpCore:SubjectCode", "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/", false, XMP_BagList); xmp += encode_xmp_category (list, "Iptc4xmpCore", "Iptc4xmpCore:", "Iptc4xmpCore:Ci", NULL, "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/", minimal, XMP_attribs); xmp += encode_xmp_category (list, "Iptc4xmpCore", "Iptc4xmpCore:Ci", NULL, "Iptc4xmpCore:CreatorContactInfo", "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/", minimal, XMP_attribs); xmp += encode_xmp_category (list, "Iptc4xmpCore", "Iptc4xmpCore:Scene", NULL, "Iptc4xmpCore:Scene", "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/", minimal, XMP_BagList); xmp += encode_xmp_category (list, "xmpMM", "xmpMM:", NULL, NULL, "http://ns.adobe.com/xap/1.0/mm/", minimal, XMP_attribs); #endif xmp += encode_xmp_category (list, "xmp", "xmp:", NULL, NULL, "http://ns.adobe.com/xap/1.0/", minimal, XMP_nodes); xmp += encode_xmp_category (list, "tiff", "tiff:", NULL, NULL, "http://ns.adobe.com/tiff/1.0/", minimal, XMP_attribs); #if 0 // Doesn't work yet xmp += encode_xmp_category (list, "xapRights", "xapRights:", NULL, NULL, "http://ns.adobe.com/xap/1.0/rights/", minimal, XMP_attribs); // xmp += encode_xmp_category (list, "dc", "dc:", NULL, NULL, // "http://purl.org/dc/elements/1.1/", minimal, XMP_attribs); #endif // FIXME exif xmp stRef stVer stJob xmpDM if (! xmp.empty()) { std::string head ( " " " " ); std::string foot (" "); xmp = head + xmp + foot; } #if DEBUG_XMP_WRITE std::cerr << "xmp to write = \n---\n" << xmp << "\n---\n"; std::cerr << "\n\nHere's what I still haven't output:\n"; for (size_t i = 0; i < list.size(); ++i) std::cerr << xmptag[list[i].first].xmpname << "\n"; #endif return xmp; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebufalgo_pixelmath.cpp0000644000175000017500000010621512271062644025101 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Implementation of ImageBufAlgo algorithms that do math on /// single pixels at a time. #include #include #include #include #include #include "imagebuf.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #include "dassert.h" #include "sysutil.h" #include "thread.h" OIIO_NAMESPACE_ENTER { template static bool clamp_ (ImageBuf &dst, const ImageBuf &src, const float *min, const float *max, bool clampalpha01, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(clamp_, boost::ref(dst), boost::cref(src), min, max, clampalpha01, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case ImageBuf::ConstIterator s (src, roi); for (ImageBuf::Iterator d (dst, roi); ! d.done(); ++d, ++s) { for (int c = roi.chbegin; c < roi.chend; ++c) d[c] = OIIO::clamp (s[c], min[c], max[c]); } int a = src.spec().alpha_channel; if (clampalpha01 && a >= roi.chbegin && a < roi.chend) { for (ImageBuf::Iterator d (dst, roi); ! d.done(); ++d) d[a] = OIIO::clamp (d[a], 0.0f, 1.0f); } return true; } bool ImageBufAlgo::clamp (ImageBuf &dst, const ImageBuf &src, const float *min, const float *max, bool clampalpha01, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &src)) return false; std::vector minvec, maxvec; if (! min) { minvec.resize (dst.nchannels(), -std::numeric_limits::max()); min = &minvec[0]; } if (! max) { maxvec.resize (dst.nchannels(), std::numeric_limits::max()); max = &maxvec[0]; } OIIO_DISPATCH_TYPES2 ("clamp", clamp_, dst.spec().format, src.spec().format, dst, src, min, max, clampalpha01, roi, nthreads); return false; } bool ImageBufAlgo::clamp (ImageBuf &dst, const float *min, const float *max, bool clampalpha01, ROI roi, int nthreads) { return clamp (dst, dst, min, max, clampalpha01, roi, nthreads); } bool ImageBufAlgo::clamp (ImageBuf &dst, const ImageBuf &src, float min, float max, bool clampalpha01, ROI roi, int nthreads) { std::vector minvec (src.nchannels(), min); std::vector maxvec (src.nchannels(), max); return clamp (dst, src, &minvec[0], &maxvec[0], clampalpha01, roi, nthreads); } bool ImageBufAlgo::clamp (ImageBuf &dst, float min, float max, bool clampalpha01, ROI roi, int nthreads) { return clamp (dst, dst, min, max, clampalpha01, roi, nthreads); } template static bool add_impl (ImageBuf &R, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(add_impl, boost::ref(R), boost::cref(A), boost::cref(B), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case ImageBuf::Iterator r (R, roi); ImageBuf::ConstIterator a (A, roi); ImageBuf::ConstIterator b (B, roi); for ( ; !r.done(); ++r, ++a, ++b) for (int c = roi.chbegin; c < roi.chend; ++c) r[c] = a[c] + b[c]; return true; } template static bool add_impl (ImageBuf &R, const ImageBuf &A, const float *b, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(add_impl, boost::ref(R), boost::cref(A), b, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case ImageBuf::Iterator r (R, roi); ImageBuf::ConstIterator a (A, roi); for ( ; !r.done(); ++r, ++a) for (int c = roi.chbegin; c < roi.chend; ++c) r[c] = a[c] + b[c]; return true; } bool ImageBufAlgo::add (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A, &B)) return false; OIIO_DISPATCH_COMMON_TYPES3 ("add", add_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); return true; } bool ImageBufAlgo::add (ImageBuf &dst, const ImageBuf &A, const float *b, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A)) return false; OIIO_DISPATCH_TYPES2 ("add", add_impl, dst.spec().format, A.spec().format, dst, A, b, roi, nthreads); return true; } bool ImageBufAlgo::add (ImageBuf &dst, const ImageBuf &A, float b, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A)) return false; int nc = A.nchannels(); float *vals = ALLOCA (float, nc); for (int c = 0; c < nc; ++c) vals[c] = b; OIIO_DISPATCH_TYPES2 ("add", add_impl, dst.spec().format, A.spec().format, dst, A, vals, roi, nthreads); } bool ImageBufAlgo::add (ImageBuf &dst, const float *val, ROI roi, int nthreads) { return add (dst, dst, val, roi, nthreads); } bool ImageBufAlgo::add (ImageBuf &R, float val, ROI roi, int nthreads) { return add (R, R, val, roi, nthreads); } template static bool sub_impl (ImageBuf &R, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(sub_impl, boost::ref(R), boost::cref(A), boost::cref(B), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case ImageBuf::Iterator r (R, roi); ImageBuf::ConstIterator a (A, roi); ImageBuf::ConstIterator b (B, roi); for ( ; !r.done(); ++r, ++a, ++b) for (int c = roi.chbegin; c < roi.chend; ++c) r[c] = a[c] - b[c]; return true; } bool ImageBufAlgo::sub (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A, &B)) return false; OIIO_DISPATCH_COMMON_TYPES3 ("sub", sub_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); return true; } bool ImageBufAlgo::sub (ImageBuf &dst, const ImageBuf &A, const float *b, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A)) return false; int nc = A.nchannels(); float *vals = ALLOCA (float, nc); for (int c = 0; c < nc; ++c) vals[c] = -b[c]; OIIO_DISPATCH_TYPES2 ("sub", add_impl, dst.spec().format, A.spec().format, dst, A, vals, roi, nthreads); return true; } bool ImageBufAlgo::sub (ImageBuf &dst, const ImageBuf &A, float b, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A)) return false; int nc = A.nchannels(); float *vals = ALLOCA (float, nc); for (int c = 0; c < nc; ++c) vals[c] = -b; OIIO_DISPATCH_TYPES2 ("sub", add_impl, dst.spec().format, A.spec().format, dst, A, vals, roi, nthreads); } template static bool mul_impl (ImageBuf &R, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(mul_impl, boost::ref(R), boost::cref(A), boost::cref(B), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case ImageBuf::Iterator r (R, roi); ImageBuf::ConstIterator a (A, roi); ImageBuf::ConstIterator b (B, roi); for ( ; !r.done(); ++r, ++a, ++b) for (int c = roi.chbegin; c < roi.chend; ++c) r[c] = a[c] * b[c]; return true; } bool ImageBufAlgo::mul (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A, &B)) return false; OIIO_DISPATCH_COMMON_TYPES3 ("mul", mul_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, roi, nthreads); return true; } template static bool mul_impl (ImageBuf &R, const ImageBuf &A, const float *b, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(mul_impl, boost::ref(R), boost::cref(A), b, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } ImageBuf::ConstIterator a (A, roi); for (ImageBuf::Iterator r (R, roi); !r.done(); ++r, ++a) for (int c = roi.chbegin; c < roi.chend; ++c) r[c] = a[c] * b[c]; return true; } bool ImageBufAlgo::mul (ImageBuf &dst, const ImageBuf &A, const float *b, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A)) return false; OIIO_DISPATCH_TYPES2 ("mul", mul_impl, dst.spec().format, A.spec().format, dst, A, b, roi, nthreads); return true; } bool ImageBufAlgo::mul (ImageBuf &dst, const ImageBuf &A, float b, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A)) return false; int nc = A.nchannels(); float *vals = ALLOCA (float, nc); for (int c = 0; c < nc; ++c) vals[c] = b; OIIO_DISPATCH_TYPES2 ("mul", mul_impl, dst.spec().format, A.spec().format, dst, A, vals, roi, nthreads); } bool ImageBufAlgo::mul (ImageBuf &dst, const float *val, ROI roi, int nthreads) { return mul (dst, dst, val, roi, nthreads); } bool ImageBufAlgo::mul (ImageBuf &dst, float val, ROI roi, int nthreads) { return mul (dst, dst, val, roi, nthreads); } template static bool channel_sum_ (ImageBuf &dst, const ImageBuf &src, const float *weights, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(channel_sum_, boost::ref(dst), boost::cref(src), weights, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } ImageBuf::Iterator d (dst, roi); ImageBuf::ConstIterator s (src, roi); for ( ; !d.done(); ++d, ++s) { float sum = 0.0f; for (int c = roi.chbegin; c < roi.chend; ++c) sum += s[c] * weights[c]; d[0] = sum; } return true; } bool ImageBufAlgo::channel_sum (ImageBuf &dst, const ImageBuf &src, const float *weights, ROI roi, int nthreads) { if (! roi.defined()) roi = get_roi(src.spec()); roi.chend = std::min (roi.chend, src.nchannels()); ROI dstroi = roi; dstroi.chbegin = 0; dstroi.chend = 1; if (! IBAprep (dstroi, &dst)) return false; if (! weights) { float *local_weights = ALLOCA (float, roi.chend); for (int c = 0; c < roi.chend; ++c) local_weights[c] = 1.0f; weights = &local_weights[0]; } OIIO_DISPATCH_TYPES2 ("channel_sum", channel_sum_, dst.spec().format, src.spec().format, dst, src, weights, roi, nthreads); return false; } inline float rangecompress (float x) { // Formula courtesy of Sony Pictures Imageworks #if 0 /* original coeffs -- identity transform for vals < 1 */ const float x1 = 1.0, a = 1.2607481479644775391; const float b = 0.28785100579261779785, c = -1.4042005538940429688; #else /* but received wisdom is that these work better */ const float x1 = 0.18, a = -0.54576885700225830078; const float b = 0.18351669609546661377, c = 284.3577880859375; #endif float absx = fabsf(x); if (absx <= x1) return x; return copysignf (a + b * logf(fabsf(c*absx + 1.0f)), x); } inline float rangeexpand (float y) { // Formula courtesy of Sony Pictures Imageworks #if 0 /* original coeffs -- identity transform for vals < 1 */ const float x1 = 1.0, a = 1.2607481479644775391; const float b = 0.28785100579261779785, c = -1.4042005538940429688; #else /* but received wisdom is that these work better */ const float x1 = 0.18, a = -0.54576885700225830078; const float b = 0.18351669609546661377, c = 284.3577880859375; #endif float absy = fabsf(y); if (absy <= x1) return y; float xIntermediate = expf ((absy - a)/b); // Since the compression step includes an absolute value, there are // two possible results here. If x < x1 it is the incorrect result, // so pick the other value. float x = (xIntermediate - 1.0f) / c; if (x < x1) x = (-xIntermediate - 1.0f) / c; return copysign (x, y); } template static bool rangecompress_ (ImageBuf &R, const ImageBuf &A, bool useluma, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(rangecompress_, boost::ref(R), boost::cref(A), useluma, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } const ImageSpec &Aspec (A.spec()); int alpha_channel = Aspec.alpha_channel; int z_channel = Aspec.z_channel; if (roi.nchannels() < 3 || (alpha_channel >= roi.chbegin && alpha_channel < roi.chbegin+3) || (z_channel >= roi.chbegin && z_channel < roi.chbegin+3)) { useluma = false; // No way to use luma } if (&R == &A) { // Special case: operate in-place for (ImageBuf::Iterator r (R, roi); !r.done(); ++r) { if (useluma) { float luma = 0.21264f * r[roi.chbegin] + 0.71517f * r[roi.chbegin+1] + 0.07219f * r[roi.chbegin+2]; float scale = rangecompress (luma) / luma; for (int c = roi.chbegin; c < roi.chend; ++c) { if (c == alpha_channel || c == z_channel) continue; r[c] = r[c] * scale; } } else { for (int c = roi.chbegin; c < roi.chend; ++c) { if (c == alpha_channel || c == z_channel) continue; r[c] = rangecompress (r[c]); } } } } else { ImageBuf::ConstIterator a (A, roi); for (ImageBuf::Iterator r (R, roi); !r.done(); ++r, ++a) { if (useluma) { float luma = 0.21264f * r[roi.chbegin] + 0.71517f * r[roi.chbegin+1] + 0.07219f * r[roi.chbegin+2]; float scale = rangecompress (luma) / luma; for (int c = roi.chbegin; c < roi.chend; ++c) { if (c == alpha_channel || c == z_channel) r[c] = a[c]; else r[c] = a[c] * scale; } } else { for (int c = roi.chbegin; c < roi.chend; ++c) { if (c == alpha_channel || c == z_channel) r[c] = a[c]; else r[c] = rangecompress (a[c]); } } } } return true; } template static bool rangeexpand_ (ImageBuf &R, const ImageBuf &A, bool useluma, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(rangeexpand_, boost::ref(R), boost::cref(A), useluma, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } const ImageSpec &Aspec (A.spec()); int alpha_channel = Aspec.alpha_channel; int z_channel = Aspec.z_channel; if (roi.nchannels() < 3 || (alpha_channel >= roi.chbegin && alpha_channel < roi.chbegin+3) || (z_channel >= roi.chbegin && z_channel < roi.chbegin+3)) { useluma = false; // No way to use luma } if (&R == &A) { // Special case: operate in-place for (ImageBuf::Iterator r (R, roi); !r.done(); ++r) { if (useluma) { float luma = 0.21264f * r[roi.chbegin] + 0.71517f * r[roi.chbegin+1] + 0.07219f * r[roi.chbegin+2]; float scale = rangeexpand (luma) / luma; for (int c = roi.chbegin; c < roi.chend; ++c) { if (c == alpha_channel || c == z_channel) continue; r[c] = r[c] * scale; } } else { for (int c = roi.chbegin; c < roi.chend; ++c) { if (c == alpha_channel || c == z_channel) continue; r[c] = rangeexpand (r[c]); } } } } else { ImageBuf::ConstIterator a (A, roi); for (ImageBuf::Iterator r (R, roi); !r.done(); ++r, ++a) { if (useluma) { float luma = 0.21264f * r[roi.chbegin] + 0.71517f * r[roi.chbegin+1] + 0.07219f * r[roi.chbegin+2]; float scale = rangeexpand (luma) / luma; for (int c = roi.chbegin; c < roi.chend; ++c) { if (c == alpha_channel || c == z_channel) r[c] = a[c]; else r[c] = a[c] * scale; } } else { for (int c = roi.chbegin; c < roi.chend; ++c) { if (c == alpha_channel || c == z_channel) r[c] = a[c]; else r[c] = rangeexpand (a[c]); } } } } return true; } bool ImageBufAlgo::rangecompress (ImageBuf &dst, const ImageBuf &src, bool useluma, ROI roi, int nthreads) { if (! dst.initialized()) { dst.error ("in-place rangecompress requires the ImageBuf to be initialized"); return false; } if (! IBAprep (roi, &dst, &src)) return false; OIIO_DISPATCH_TYPES2 ("rangecompress", rangecompress_, dst.spec().format, src.spec().format, dst, src, useluma, roi, nthreads); return true; } bool ImageBufAlgo::rangeexpand (ImageBuf &dst, const ImageBuf &src, bool useluma, ROI roi, int nthreads) { if (! dst.initialized()) { dst.error ("in-place rangeexpand requires the ImageBuf to be initialized"); return false; } if (! IBAprep (roi, &dst)) return false; OIIO_DISPATCH_TYPES2 ("rangeexpand", rangeexpand_, dst.spec().format, src.spec().format, dst, src, useluma, roi, nthreads); return true; } bool ImageBufAlgo::rangecompress (ImageBuf &dst, bool useluma, ROI roi, int nthreads) { return rangecompress (dst, dst, useluma, roi, nthreads); } bool ImageBufAlgo::rangeexpand (ImageBuf &dst, bool useluma, ROI roi, int nthreads) { return rangeexpand (dst, dst, useluma, roi, nthreads); } template static bool unpremult_ (ImageBuf &R, const ImageBuf &A, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(unpremult_, boost::ref(R), boost::cref(A), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } int alpha_channel = A.spec().alpha_channel; int z_channel = A.spec().z_channel; if (&R == &A) { for (ImageBuf::Iterator r (R, roi); !r.done(); ++r) { float alpha = r[alpha_channel]; if (alpha == 0.0f || alpha == 1.0f) continue; for (int c = roi.chbegin; c < roi.chend; ++c) if (c != alpha_channel && c != z_channel) r[c] = r[c] / alpha; } } else { ImageBuf::ConstIterator a (A, roi); for (ImageBuf::Iterator r (R, roi); !r.done(); ++r, ++a) { float alpha = a[alpha_channel]; if (alpha == 0.0f || alpha == 1.0f) { for (int c = roi.chbegin; c < roi.chend; ++c) r[c] = a[c]; continue; } for (int c = roi.chbegin; c < roi.chend; ++c) if (c != alpha_channel && c != z_channel) r[c] = a[c] / alpha; else r[c] = a[c]; } } return true; } bool ImageBufAlgo::unpremult (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &src)) return false; if (src.spec().alpha_channel < 0) { if (&dst != &src) return paste (dst, src.spec().x, src.spec().y, src.spec().z, roi.chbegin, src, roi, nthreads); return true; } OIIO_DISPATCH_TYPES2 ("unpremult", unpremult_, dst.spec().format, src.spec().format, dst, src, roi, nthreads); return true; } bool ImageBufAlgo::unpremult (ImageBuf &dst, ROI roi, int nthreads) { return unpremult (dst, dst, roi, nthreads); } template static bool premult_ (ImageBuf &R, const ImageBuf &A, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(premult_, boost::ref(R), boost::cref(A), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } int alpha_channel = A.spec().alpha_channel; int z_channel = A.spec().z_channel; if (&R == &A) { for (ImageBuf::Iterator r (R, roi); !r.done(); ++r) { float alpha = r[alpha_channel]; if (alpha == 1.0f) continue; for (int c = roi.chbegin; c < roi.chend; ++c) if (c != alpha_channel && c != z_channel) r[c] = r[c] * alpha; } } else { ImageBuf::ConstIterator a (A, roi); for (ImageBuf::Iterator r (R, roi); !r.done(); ++r, ++a) { float alpha = a[alpha_channel]; for (int c = roi.chbegin; c < roi.chend; ++c) if (c != alpha_channel && c != z_channel) r[c] = a[c] * alpha; else r[c] = a[c]; } } return true; } bool ImageBufAlgo::premult (ImageBuf &dst, const ImageBuf &src, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &src)) return false; if (src.spec().alpha_channel < 0) { if (&dst != &src) return paste (dst, src.spec().x, src.spec().y, src.spec().z, roi.chbegin, src, roi, nthreads); return true; } OIIO_DISPATCH_TYPES2 ("premult", premult_, dst.spec().format, src.spec().format, dst, src, roi, nthreads); return true; } bool ImageBufAlgo::premult (ImageBuf &dst, ROI roi, int nthreads) { return premult (dst, dst, roi, nthreads); } namespace { // Make sure isfinite is defined for 'half' inline bool isfinite (half h) { return h.isFinite(); } template bool fixNonFinite_ (ImageBuf &dst, ImageBufAlgo::NonFiniteFixMode mode, int *pixelsFixed, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Lots of pixels and request for multi threads? Parallelize. ImageBufAlgo::parallel_image ( boost::bind(fixNonFinite_, boost::ref(dst), mode, pixelsFixed, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case ROI dstroi = get_roi (dst.spec()); int count = 0; // Number of pixels with nonfinite values if (mode == ImageBufAlgo::NONFINITE_NONE) { // Just count the number of pixels with non-finite values for (ImageBuf::Iterator pixel (dst); ! pixel.done(); ++pixel) { for (int c = roi.chbegin; c < roi.chend; ++c) { T value = pixel[c]; if (! isfinite(value)) { ++count; break; // only count one per pixel } } } } else if (mode == ImageBufAlgo::NONFINITE_BLACK) { // Replace non-finite pixels with black for (ImageBuf::Iterator pixel (dst); ! pixel.done(); ++pixel) { bool fixed = false; for (int c = roi.chbegin; c < roi.chend; ++c) { T value = pixel[c]; if (! isfinite(value)) { pixel[c] = T(0.0); fixed = true; } } if (fixed) ++count; } } else if (mode == ImageBufAlgo::NONFINITE_BOX3) { // Replace non-finite pixels with a simple 3x3 window average // (the average excluding non-finite pixels, of course) for (ImageBuf::Iterator pixel (dst); ! pixel.done(); ++pixel) { bool fixed = false; for (int c = roi.chbegin; c < roi.chend; ++c) { T value = pixel[c]; if (! isfinite (value)) { int numvals = 0; T sum (0.0); ROI roi2 (pixel.x()-1, pixel.x()+2, pixel.y()-1, pixel.y()+2, pixel.z()-1, pixel.z()+2); roi2 = roi_intersection (roi2, dstroi); for (ImageBuf::Iterator i(dst,roi2); !i.done(); ++i) { T v = i[c]; if (isfinite (v)) { sum += v; ++numvals; } } pixel[c] = numvals ? T(sum / numvals) : T(0.0); fixed = true; } } if (fixed) ++count; } } if (pixelsFixed) { // Update pixelsFixed atomically -- that's what makes this whole // function thread-safe. *(atomic_int *)pixelsFixed += count; } return true; } } // anon namespace /// Fix all non-finite pixels (nan/inf) using the specified approach bool ImageBufAlgo::fixNonFinite (ImageBuf &dst, const ImageBuf &src, NonFiniteFixMode mode, int *pixelsFixed, ROI roi, int nthreads) { if (mode != ImageBufAlgo::NONFINITE_NONE && mode != ImageBufAlgo::NONFINITE_BLACK && mode != ImageBufAlgo::NONFINITE_BOX3) { // Something went wrong dst.error ("fixNonFinite: unknown repair mode"); return false; } if (! IBAprep (roi, &dst, &src)) return false; // Initialize if (pixelsFixed) *pixelsFixed = 0; // Start by copying dst to src, if they aren't the same image if (&dst != &src) ImageBufAlgo::paste (dst, roi.xbegin, roi.ybegin, roi.zbegin, 0, src, roi, nthreads); switch (src.spec().format.basetype) { case TypeDesc::FLOAT : return fixNonFinite_ (dst, mode, pixelsFixed, roi, nthreads); case TypeDesc::HALF : return fixNonFinite_ (dst, mode, pixelsFixed, roi, nthreads); case TypeDesc::DOUBLE: return fixNonFinite_ (dst, mode, pixelsFixed, roi, nthreads); default: // All other format types aren't capable of having nonfinite // pixel values, so the copy was enough. return true; } } // DEPRECATED (1.3) bool ImageBufAlgo::fixNonFinite (ImageBuf &dst, NonFiniteFixMode mode, int *pixelsFixed, ROI roi, int nthreads) { return fixNonFinite (dst, dst, mode, pixelsFixed, roi, nthreads); } static bool decode_over_channels (const ImageBuf &R, int &nchannels, int &alpha, int &z, int &colors) { if (! R.initialized()) { alpha = -1; z = -1; colors = 0; return false; } const ImageSpec &spec (R.spec()); alpha = spec.alpha_channel; bool has_alpha = (alpha >= 0); z = spec.z_channel; bool has_z = (z >= 0); nchannels = spec.nchannels; colors = nchannels - has_alpha - has_z; if (! has_alpha && colors == 4) { // No marked alpha channel, but suspiciously 4 channel -- assume // it's RGBA. has_alpha = true; colors -= 1; // Assume alpha is the highest channel that's not z alpha = nchannels - 1; if (alpha == z) --alpha; } return true; } // Fully type-specialized version of over. template static bool over_impl (ImageBuf &R, const ImageBuf &A, const ImageBuf &B, bool zcomp, bool z_zeroisinf, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image ( boost::bind(over_impl, boost::ref(R), boost::cref(A), boost::cref(B), zcomp, z_zeroisinf, _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case... // It's already guaranteed that R, A, and B have matching channel // ordering, and have an alpha channel. So just decode one. int nchannels = 0, alpha_channel = 0, z_channel = 0, ncolor_channels = 0; decode_over_channels (R, nchannels, alpha_channel, z_channel, ncolor_channels); bool has_z = (z_channel >= 0); ImageBuf::ConstIterator a (A, roi); ImageBuf::ConstIterator b (B, roi); ImageBuf::Iterator r (R, roi); for ( ; ! r.done(); ++r, ++a, ++b) { float az = 0.0f, bz = 0.0f; bool a_is_closer = true; // will remain true if !zcomp if (zcomp && has_z) { az = a[z_channel]; bz = b[z_channel]; if (z_zeroisinf) { if (az == 0.0f) az = std::numeric_limits::max(); if (bz == 0.0f) bz = std::numeric_limits::max(); } a_is_closer = (az <= bz); } if (a_is_closer) { // A over B float alpha = clamp (a[alpha_channel], 0.0f, 1.0f); float one_minus_alpha = 1.0f - alpha; for (int c = roi.chbegin; c < roi.chend; c++) r[c] = a[c] + one_minus_alpha * b[c]; if (has_z) r[z_channel] = (alpha != 0.0) ? a[z_channel] : b[z_channel]; } else { // B over A -- because we're doing a Z composite float alpha = clamp (b[alpha_channel], 0.0f, 1.0f); float one_minus_alpha = 1.0f - alpha; for (int c = roi.chbegin; c < roi.chend; c++) r[c] = b[c] + one_minus_alpha * a[c]; r[z_channel] = (alpha != 0.0) ? b[z_channel] : a[z_channel]; } } return true; } bool ImageBufAlgo::over (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A, &B, NULL, IBAprep_REQUIRE_ALPHA | IBAprep_REQUIRE_SAME_NCHANNELS)) return false; OIIO_DISPATCH_COMMON_TYPES3 ("over", over_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, false, false, roi, nthreads); return ! dst.has_error(); } bool ImageBufAlgo::zover (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, bool z_zeroisinf, ROI roi, int nthreads) { if (! IBAprep (roi, &dst, &A, &B, NULL, IBAprep_REQUIRE_ALPHA | IBAprep_REQUIRE_Z | IBAprep_REQUIRE_SAME_NCHANNELS)) return false; OIIO_DISPATCH_COMMON_TYPES3 ("zover", over_impl, dst.spec().format, A.spec().format, B.spec().format, dst, A, B, true, z_zeroisinf, roi, nthreads); return ! dst.has_error(); } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/CMakeLists.txt0000644000175000017500000003753712271062644022452 0ustar mfvmfvset (libOpenImageIO_hdrs ../include/argparse.h ../include/color.h ../include/dassert.h ../include/errorhandler.h ../include/filesystem.h ../include/filter.h ../include/fmath.h ../include/hash.h ../include/imagebuf.h ../include/imagecache.h ../include/imageio.h ../include/osdep.h ../include/paramlist.h ../include/plugin.h ../include/SHA1.h ../include/strutil.h ../include/sysutil.h ../include/texture.h ../include/thread.h ../include/timer.h ../include/typedesc.h ../include/ustring.h ../include/varyingref.h ) if (NOT USE_EXTERNAL_PUGIXML) list (APPEND libOpenImageIO_hdrs ../include/pugiconfig.hpp ../include/pugixml.hpp ../include/pugixml.cpp ) endif() set (libOpenImageIO_srcs exif.cpp formatspec.cpp imagebuf.cpp imageinput.cpp imageio.cpp imageioplugin.cpp imageoutput.cpp iptc.cpp xmp.cpp color_ocio.cpp imagebufalgo.cpp imagebufalgo_compare.cpp imagebufalgo_copy.cpp imagebufalgo_deep.cpp imagebufalgo_pixelmath.cpp imagebufalgo_yee.cpp imagebufalgo_opencv.cpp maketexture.cpp ../libutil/argparse.cpp ../libutil/errorhandler.cpp ../libutil/filesystem.cpp ../libutil/filter.cpp ../libutil/hashes.cpp ../libutil/paramlist.cpp ../libutil/plugin.cpp ../libutil/pystring.cpp ../libutil/SHA1.cpp ../libutil/strutil.cpp ../libutil/sysutil.cpp ../libutil/typedesc.cpp ../libutil/ustring.cpp ../libtexture/texturesys.cpp ../libtexture/texture3d.cpp ../libtexture/environment.cpp ../libtexture/texoptions.cpp ../libtexture/imagecache.cpp ${libOpenImageIO_hdrs} ) #if (NOT USE_EXTERNAL_PUGIXML) # list (APPEND libOpenImageIO_srcs ../libutil/pugixml.cpp) #endif () # Include our own TBB if using it if (USE_TBB AND USE_EXTERNAL_TBB) message (STATUS "System TBB library will be used.") find_package (TBB REQUIRED) include_directories (${TBB_INCLUDE_DIRS}) set (libOpenImageIO_srcs ${libOpenImageIO_srcs}) elseif (USE_TBB AND NOT USE_EXTERNAL_TBB) message (STATUS "Built-in TBB library will be used.") set (libOpenImageIO_srcs ${libOpenImageIO_srcs} ../libutil/tbb_misc.cpp) endif () # If the 'EMBEDPLUGINS' option is set, we want to compile the source for # all the plugins into libOpenImageIO. if (EMBEDPLUGINS) set (libOpenImageIO_srcs ${libOpenImageIO_srcs} ../bmp.imageio/bmpinput.cpp ../bmp.imageio/bmpoutput.cpp ../bmp.imageio/bmp_pvt.cpp ../cineon.imageio/cineoninput.cpp ../cineon.imageio/cineonoutput.cpp ../cineon.imageio/libcineon/Cineon.cpp ../cineon.imageio/libcineon/Codec.cpp ../cineon.imageio/libcineon/Reader.cpp ../cineon.imageio/libcineon/Writer.cpp ../cineon.imageio/libcineon/CineonHeader.cpp ../cineon.imageio/libcineon/ElementReadStream.cpp ../cineon.imageio/libcineon/InStream.cpp ../dds.imageio/ddsinput.cpp ../dds.imageio/ddsoutput.cpp ../dds.imageio/squish/alpha.cpp ../dds.imageio/squish/clusterfit.cpp ../dds.imageio/squish/colourblock.cpp ../dds.imageio/squish/colourfit.cpp ../dds.imageio/squish/colourset.cpp ../dds.imageio/squish/maths.cpp ../dds.imageio/squish/rangefit.cpp ../dds.imageio/squish/singlecolourfit.cpp ../dds.imageio/squish/squish.cpp ../dpx.imageio/dpxinput.cpp ../dpx.imageio/dpxoutput.cpp ../dpx.imageio/libdpx/DPX.cpp ../dpx.imageio/libdpx/OutStream.cpp ../dpx.imageio/libdpx/RunLengthEncoding.cpp ../dpx.imageio/libdpx/Codec.cpp ../dpx.imageio/libdpx/Reader.cpp ../dpx.imageio/libdpx/Writer.cpp ../dpx.imageio/libdpx/DPXHeader.cpp ../dpx.imageio/libdpx/ElementReadStream.cpp ../dpx.imageio/libdpx/InStream.cpp ../dpx.imageio/libdpx/DPXColorConverter.cpp ../fits.imageio/fitsinput.cpp ../fits.imageio/fitsoutput.cpp ../fits.imageio/fits_pvt.cpp ../hdr.imageio/hdrinput.cpp ../hdr.imageio/hdroutput.cpp ../hdr.imageio/rgbe.cpp ../ico.imageio/icoinput.cpp ../ico.imageio/icooutput.cpp ../iff.imageio/iffinput.cpp ../iff.imageio/iffoutput.cpp ../iff.imageio/iff_pvt.cpp ../jpeg.imageio/jpeginput.cpp ../jpeg.imageio/jpegoutput.cpp ../png.imageio/pnginput.cpp ../png.imageio/pngoutput.cpp ../pnm.imageio/pnminput.cpp ../pnm.imageio/pnmoutput.cpp ../psd.imageio/psdinput.cpp ../psd.imageio/psdoutput.cpp ../psd.imageio/jpeg_memory_src.cpp ../ptex.imageio/ptexinput.cpp ../ptex.imageio/ptexoutput.cpp ../ptex.imageio/ptex/PtexCache.cpp ../ptex.imageio/ptex/PtexFilters.cpp ../ptex.imageio/ptex/PtexHalf.cpp ../ptex.imageio/ptex/PtexReader.cpp ../ptex.imageio/ptex/PtexSeparableFilter.cpp ../ptex.imageio/ptex/PtexSeparableKernel.cpp ../ptex.imageio/ptex/PtexTriangleFilter.cpp ../ptex.imageio/ptex/PtexTriangleKernel.cpp ../ptex.imageio/ptex/PtexUtils.cpp ../ptex.imageio/ptex/PtexWriter.cpp ../openexr.imageio/exrinput.cpp ../openexr.imageio/exroutput.cpp ../rla.imageio/rlainput.cpp ../rla.imageio/rlaoutput.cpp ../sgi.imageio/sgiinput.cpp ../sgi.imageio/sgioutput.cpp ../softimage.imageio/softimageinput.cpp ../softimage.imageio/softimageoutput.cpp ../softimage.imageio/softimage_pvt.cpp ../targa.imageio/targainput.cpp ../targa.imageio/targaoutput.cpp ../tiff.imageio/tiffinput.cpp ../tiff.imageio/tiffoutput.cpp ../zfile.imageio/zfile.cpp ) if (NOT Boost_VERSION LESS "103500") # Boost < 1.35 is too old to support asio that socket needs set (libOpenImageIO_srcs ${libOpenImageIO_srcs} ../socket.imageio/socketinput.cpp ../socket.imageio/socketoutput.cpp ../socket.imageio/socket_pvt.cpp ) add_definitions ("-DUSE_BOOST_ASIO=1") endif () find_package (PNG REQUIRED) find_package (JPEG REQUIRED) find_package (TIFF REQUIRED) find_package (ZLIB REQUIRED) include_directories (${PNG_INCLUDE_DIR} ${JPEG_INCLUDE_DIR}) include_directories (${TIFF_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) add_definitions ("-DEMBED_PLUGINS=1") if (FIELD3D_FOUND AND USE_FIELD3D) set (libOpenImageIO_srcs ${libOpenImageIO_srcs} ../field3d.imageio/field3dinput.cpp ../field3d.imageio/field3doutput.cpp ) include_directories (${FIELD3D_INCLUDE_DIR}) else () message (STATUS "Field3D plugin will not be built") set (FIELD3D_LIBRARY "") set (HDF5_LIBRARY "") endif () if (GIF_FOUND AND USE_GIF) set (libOpenImageIO_srcs ${libOpenImageIO_srcs} ../gif.imageio/gifinput.cpp ../gif.imageio/gifoutput.cpp) include_directories (${GIF_INCLUDE_DIR}) add_definitions("-DUSE_GIF") else() message (STATUS "GIF plugin will not be built") endif() if (OPENJPEG_FOUND AND USE_OPENJPEG) set (libOpenImageIO_srcs ${libOpenImageIO_srcs} ../jpeg2000.imageio/jpeg2000input.cpp ../jpeg2000.imageio/jpeg2000output.cpp) include_directories (${OPENJPEG_INCLUDE_DIR}) add_definitions("-DUSE_OPENJPEG") else() message (STATUS "Jpeg-2000 plugin will not be built") endif() if (WEBP_FOUND) set (libOpenImageIO_srcs ${libOpenImageIO_srcs} ../webp.imageio/webpinput.cpp ../webp.imageio/webpoutput.cpp ) include_directories (${WEBP_INCLUDE_DIR}) add_definitions ("-DUSE_WEBP=1") else () message (STATUS "WebP plugin will not be built") set (WEBP_LIBRARY "") endif () # Organize the embedded plugins into source folders set (plugin_types "") foreach (src ${libOpenImageIO_srcs}) if (src MATCHES "^.+/([^/]+)\\.imageio/.+$") set (plugin_types ${plugin_types} ${CMAKE_MATCH_1}) endif () endforeach () list (REMOVE_DUPLICATES plugin_types) foreach (plugin ${plugin_types}) source_group ("Plugins\\${plugin}" REGULAR_EXPRESSION "^.+/${plugin}\\.imageio/.+$" ) endforeach () else() find_package (TIFF REQUIRED) include_directories (${TIFF_INCLUDE_DIR}) endif () # Source groups for libutil and libtexture source_group ("libutil" REGULAR_EXPRESSION ".+/libutil/.+") source_group ("libtexture" REGULAR_EXPRESSION ".+/libtexture/.+") if (BUILDSTATIC) add_library (OpenImageIO STATIC ${libOpenImageIO_srcs}) else () add_library (OpenImageIO SHARED ${libOpenImageIO_srcs}) endif () target_link_libraries (OpenImageIO ${VISIBILITY_COMMAND} ${VISIBILITY_MAP_COMMAND} ${Boost_LIBRARIES}) # Link against system TBB library if specified if (USE_TBB AND USE_EXTERNAL_TBB) message (STATUS "Linking TBB: ${TBB_LIBRARIES}") target_link_libraries (OpenImageIO ${TBB_LIBRARIES}) endif () # Include OpenColorIO if using it if (USE_OCIO AND OCIO_FOUND) message (STATUS "Linking OpenColorIO ${OCIO_LIBRARIES}") target_link_libraries (OpenImageIO ${OCIO_LIBRARIES}) endif () # Include OpenCV if using it if (OpenCV_FOUND) include_directories (${OpenCV_INCLUDE_DIR}) target_link_libraries (OpenImageIO opencv_core opencv_highgui) endif () # Include OpenSSL if using it if (OPENSSL_FOUND) include_directories (${OPENSSL_INCLUDE_DIR}) target_link_libraries (OpenImageIO ${OPENSSL_LIBRARIES}) endif () # Include Freetype if using it if (FREETYPE_FOUND) include_directories (${FREETYPE_INCLUDE_DIRS}) target_link_libraries (OpenImageIO ${FREETYPE_LIBRARIES}) endif () if (WIN32) target_link_libraries (OpenImageIO psapi.lib) endif () link_ilmbase (OpenImageIO) add_dependencies (OpenImageIO "${CMAKE_CURRENT_SOURCE_DIR}/libOpenImageIO.map") if (EMBEDPLUGINS) target_link_libraries (OpenImageIO ${PNG_LIBRARIES} ${TIFF_LIBRARIES} ${JPEG_LIBRARIES} ${ZLIB_LIBRARIES} ${FIELD3D_LIBRARY} ${HDF5_LIBRARY} ${OPENJPEG_LIBRARIES} ${WEBP_LIBRARY} ) link_openexr (OpenImageIO) if (USE_GIF AND GIF_FOUND) target_link_libraries (OpenImageIO ${GIF_LIBRARY}) endif () endif () if (USE_EXTERNAL_PUGIXML) target_link_libraries (OpenImageIO ${PUGIXML_LIBRARIES}) endif () message(STATUS "Setting SOVERSION to: ${SOVERSION}") set_target_properties(OpenImageIO PROPERTIES VERSION ${OIIO_VERSION_MAJOR}.${OIIO_VERSION_MINOR}.${OIIO_VERSION_PATCH} SOVERSION ${SOVERSION} ) # For consistency with the linux SpComp2s, create Mac OS X SpComp2s # with a .so suffix instead of a .dylib suffix. if(DEFINED OVERRIDE_SHARED_LIBRARY_SUFFIX) message(STATUS "Setting SUFFIX to: ${OVERRIDE_SHARED_LIBRARY_SUFFIX}") set_target_properties(OpenImageIO PROPERTIES SUFFIX ${OVERRIDE_SHARED_LIBRARY_SUFFIX} ) endif(DEFINED OVERRIDE_SHARED_LIBRARY_SUFFIX) oiio_install_targets (OpenImageIO) # Testing # Definition needed by boost_unit_test_framework library # and by PTEX DLL if (NOT LINKSTATIC) add_definitions (-DBOOST_TEST_DYN_LINK) add_definitions (-DPTEX_EXPORTS) endif () if (OIIO_BUILD_TESTS) add_executable (imagebuf_test imagebuf_test.cpp) link_ilmbase (imagebuf_test) set_target_properties (imagebuf_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (imagebuf_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_imagebuf imagebuf_test) add_executable (imagebufalgo_test imagebufalgo_test.cpp) link_ilmbase (imagebufalgo_test) set_target_properties (imagebufalgo_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (imagebufalgo_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_imagebufalgo imagebufalgo_test) add_executable (atomic_test atomic_test.cpp) set_target_properties (atomic_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (atomic_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_atomic atomic_test) add_executable (spinlock_test spinlock_test.cpp) set_target_properties (spinlock_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (spinlock_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_spinlock spinlock_test) add_executable (spin_rw_test spin_rw_test.cpp) set_target_properties (spin_rw_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (spin_rw_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_spin_rw spin_rw_test) add_executable (ustring_test ustring_test.cpp) set_target_properties (ustring_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (ustring_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_ustring ustring_test) add_executable (imagespec_test imagespec_test.cpp) set_target_properties (imagespec_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (imagespec_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_imagespec imagespec_test) add_executable (strutil_test strutil_test.cpp) set_target_properties (strutil_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (strutil_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_strutil strutil_test) add_executable (fmath_test fmath_test.cpp) set_target_properties (fmath_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (fmath_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_fmath fmath_test) add_executable (filesystem_test filesystem_test.cpp) set_target_properties (filesystem_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (filesystem_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_filesystem filesystem_test) add_executable (optparser_test optparser_test.cpp) set_target_properties (optparser_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (optparser_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_optparser optparser_test) add_executable (hash_test hash_test.cpp) set_target_properties (hash_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (hash_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (unit_hash hash_test) add_executable (imagespeed_test imagespeed_test.cpp) set_target_properties (imagespeed_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (imagespeed_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) #add_test (imagespeed_test imagespeed_test) add_executable (timer_test timer_test.cpp) set_target_properties (timer_test PROPERTIES FOLDER "Unit Tests") target_link_libraries (timer_test OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) add_test (timer_test timer_test) endif (OIIO_BUILD_TESTS) openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/imagebufalgo_yee.cpp0000644000175000017500000003034712271062644023672 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Implementation of ImageBufAlgo algorithms. #include #include #include #include using Imath::Color3f; #include "fmath.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #include "dassert.h" template inline Imath::Vec3 powf (const Imath::Vec3 &x, float y) { return Imath::Vec3 (powf (x[0], y), powf (x[1], y), powf (x[2], y)); } OIIO_NAMESPACE_ENTER { namespace { #define PYRAMID_MAX_LEVELS 8 class GaussianPyramid { public: GaussianPyramid (ImageBuf &image) { level[0].swap (image); // swallow the source as the top level ImageBuf kernel; ImageBufAlgo::make_kernel (kernel, "gaussian", 5, 5); for (int i = 1; i < PYRAMID_MAX_LEVELS; ++i) ImageBufAlgo::convolve (level[i], level[i-1], kernel); } ~GaussianPyramid () { } float value (int x, int y, int lev) const { if (lev >= PYRAMID_MAX_LEVELS) return 0.0f; else return level[lev].getchannel(x,y,0,1); } ImageBuf &operator[] (int lev) { DASSERT (lev < PYRAMID_MAX_LEVELS); return level[lev]; } float operator() (int x, int y, int lev) const { DASSERT (lev < PYRAMID_MAX_LEVELS); return level[lev].getchannel(x,y,0,1); } private: ImageBuf level[PYRAMID_MAX_LEVELS]; }; // Adobe RGB (1998) with reference white D65 -> XYZ // matrix is from http://www.brucelindbloom.com/ inline Color3f AdobeRGBToXYZ (const Color3f &rgb) { return Color3f (rgb[0] * 0.576700f + rgb[1] * 0.185556f + rgb[2] * 0.188212f, rgb[0] * 0.297361f + rgb[1] * 0.627355f + rgb[2] * 0.0752847f, rgb[0] * 0.0270328f + rgb[1] * 0.0706879f + rgb[2] * 0.991248f); } static bool AdobeRGBToXYZ (ImageBuf &A, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image (boost::bind(AdobeRGBToXYZ, boost::ref(A), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case for (ImageBuf::Iterator a (A, roi); !a.done(); ++a) { Color3f rgb (a[0], a[1], a[2]); Color3f XYZ = AdobeRGBToXYZ (rgb); a[0] = XYZ[0]; a[1] = XYZ[1]; a[2] = XYZ[2]; } return true; } /// Convert a color in XYZ space to LAB space. /// static Color3f XYZToLAB (const Color3f xyz) { // Reference white point static const Color3f white (0.576700f + 0.185556f + 0.188212f, 0.297361f + 0.627355f + 0.0752847f, 0.0270328f + 0.0706879f + 0.991248f); const float epsilon = 216.0f / 24389.0f; const float kappa = 24389.0f / 27.0f; Color3f r = xyz / white; Color3f f; for (int i = 0; i < 3; i++) { if (r[i] > epsilon) f[i] = powf (r[i], 1.0f / 3.0f); else f[i] = (kappa * r[i] + 16.0f) / 116.0f; } return Color3f (116.0f * f[1] - 16.0f, // L 500.0f * (f[0] - f[1]), // A 200.0f * (f[1] - f[2])); // B } static bool XYZToLAB (ImageBuf &A, ROI roi, int nthreads) { if (nthreads != 1 && roi.npixels() >= 1000) { // Possible multiple thread case -- recurse via parallel_image ImageBufAlgo::parallel_image (boost::bind(XYZToLAB, boost::ref(A), _1 /*roi*/, 1 /*nthreads*/), roi, nthreads); return true; } // Serial case for (ImageBuf::Iterator a (A, roi); !a.done(); ++a) { Color3f XYZ (a[0], a[1], a[2]); Color3f LAB = XYZToLAB (XYZ); a[0] = LAB[0]; a[1] = LAB[1]; a[2] = LAB[2]; } return true; } // Contrast sensitivity function (Barten SPIE 1989) static float contrast_sensitivity (float cyclesperdegree, float luminance) { float a = 440.0f * powf ((1.0f + 0.7f / luminance), -0.2f); float b = 0.3f * powf ((1.0f + 100.0f / luminance), 0.15f); return a * cyclesperdegree * expf(-b * cyclesperdegree) * sqrtf(1.0f + 0.06f * expf(b * cyclesperdegree)); } // Visual Masking Function from Daly 1993 inline float mask (float contrast) { float a = powf (392.498f * contrast, 0.7f); float b = powf (0.0153f * a, 4.0f); return powf (1.0f + b, 0.25f); } // Given the adaptation luminance, this function returns the // threshold of visibility in cd per m^2 // TVI means Threshold vs Intensity function // This version comes from Ward Larson Siggraph 1997 static float tvi (float adaptation_luminance) { // returns the threshold luminance given the adaptation luminance // units are candelas per meter squared float r; float log_a = log10f(adaptation_luminance); if (log_a < -3.94f) r = -2.86f; else if (log_a < -1.44f) r = powf(0.405f * log_a + 1.6f , 2.18f) - 2.86f; else if (log_a < -0.0184f) r = log_a - 0.395f; else if (log_a < 1.9f) r = powf(0.249f * log_a + 0.65f, 2.7f) - 0.72f; else r = log_a - 1.255f; return powf (10.0f, r); } } int ImageBufAlgo::compare_Yee (const ImageBuf &img0, const ImageBuf &img1, CompareResults &result, float luminance, float fov, ROI roi, int nthreads) { if (! roi.defined()) roi = roi_union (get_roi(img0.spec()), get_roi(img1.spec())); roi.chend = std::max (roi.chend, roi.chbegin+3); // max of 3 channels result.maxerror = 0; result.maxx=0, result.maxy=0, result.maxz=0, result.maxc=0; result.nfail = 0, result.nwarn = 0; int nscanlines = roi.height() * roi.depth(); bool luminanceOnly = false; // assuming colorspaces are in Adobe RGB (1998), convert to LAB // paste() to copy of up to 3 channels, converting to float, and // ending up with a 0-origin image. End up with an LAB image in // aLAB, and a luminance image in aLum. ImageSpec spec (roi.width(), roi.height(), 3 /*chans*/, TypeDesc::FLOAT); ImageBuf aLAB (spec); ImageBufAlgo::paste (aLAB, 0, 0, 0, 0, img0, roi, nthreads); AdobeRGBToXYZ (aLAB, ROI::All(), nthreads); // contains XYZ now ImageBuf aLum; int channelorder[] = { 1 }; // channel to copy ImageBufAlgo::channels (aLum, aLAB, 1, channelorder); ImageBufAlgo::mul (aLum, luminance, ROI::All(), nthreads); XYZToLAB (aLAB, ROI::All(), nthreads); // now it's LAB // Same thing for img1/bLAB/bLum ImageBuf bLAB (spec); ImageBufAlgo::paste (bLAB, 0, 0, 0, 0, img1, roi, nthreads); AdobeRGBToXYZ (bLAB, ROI::All(), nthreads); // contains XYZ now ImageBuf bLum; ImageBufAlgo::channels (bLum, bLAB, 1, channelorder); ImageBufAlgo::mul (bLum, luminance, ROI::All(), nthreads); XYZToLAB (bLAB, ROI::All(), nthreads); // now it's LAB // Construct Gaussian pyramids (not really pyramids, because they all // have the same resolution, but really just a bunch of successively // more blurred images). GaussianPyramid la (aLum); GaussianPyramid lb (bLum); float num_one_degree_pixels = (float) (2 * tan(fov * 0.5 * M_PI / 180) * 180 / M_PI); float pixels_per_degree = roi.width() / num_one_degree_pixels; unsigned int adaptation_level = 0; for (int i = 0, npixels = 1; i < PYRAMID_MAX_LEVELS && npixels <= num_one_degree_pixels; ++i, npixels *= 2) adaptation_level = i; float cpd[PYRAMID_MAX_LEVELS]; cpd[0] = 0.5f * pixels_per_degree; for (int i = 1; i < PYRAMID_MAX_LEVELS; ++i) cpd[i] = 0.5f * cpd[i - 1]; float csf_max = contrast_sensitivity (3.248f, 100.0f); float F_freq[PYRAMID_MAX_LEVELS - 2]; for (int i = 0; i < PYRAMID_MAX_LEVELS - 2; ++i) F_freq[i] = csf_max / contrast_sensitivity (cpd[i], 100.0f); for (int y = 0; y < nscanlines; ++y) { for (int x = 0; x < roi.width(); ++x) { float contrast[PYRAMID_MAX_LEVELS - 2]; float sum_contrast = 0; for (int i = 0; i < PYRAMID_MAX_LEVELS - 2; i++) { float n1 = fabsf (la.value(x,y,i) - la.value(x,y,i+1)); float n2 = fabsf (lb.value(x,y,i) - lb.value(x,y,i+1)); float numerator = std::max (n1, n2); float d1 = fabsf (la.value(x,y,i+2)); float d2 = fabsf (lb.value(x,y,i+2)); float denominator = std::max (std::max (d1, d2), 1.0e-5f); contrast[i] = numerator / denominator; sum_contrast += contrast[i]; } if (sum_contrast < 1e-5) sum_contrast = 1e-5f; float F_mask[PYRAMID_MAX_LEVELS - 2]; float adapt = la.value(x,y,adaptation_level) + lb.value(x,y,adaptation_level); adapt *= 0.5f; if (adapt < 1e-5) adapt = 1e-5f; for (int i = 0; i < PYRAMID_MAX_LEVELS - 2; i++) F_mask[i] = mask(contrast[i] * contrast_sensitivity(cpd[i], adapt)); float factor = 0; for (int i = 0; i < PYRAMID_MAX_LEVELS - 2; i++) factor += contrast[i] * F_freq[i] * F_mask[i] / sum_contrast; factor = Imath::clamp (factor, 1.0f, 10.0f); float delta = fabsf (la.value(x,y,0) - lb.value(x,y,0)); bool pass = true; // pure luminance test delta /= tvi(adapt); if (delta > factor) { pass = false; } else if (! luminanceOnly) { // CIE delta E test with modifications float color_scale = 1.0f; // ramp down the color test in scotopic regions if (adapt < 10.0f) { color_scale = 1.0f - (10.0f - color_scale) / 10.0f; color_scale = color_scale * color_scale; } float da = aLAB.getchannel(x,y,0,1) - bLAB.getchannel(x,y,0,1); // diff in A float db = aLAB.getchannel(x,y,0,2) - bLAB.getchannel(x,y,0,2); // diff in B da = da * da; db = db * db; delta = (da + db) * color_scale; if (delta > factor) pass = false; } if (!pass) { ++result.nfail; if (factor > result.maxerror) { result.maxerror = factor; result.maxx = x; result.maxy = y; // result.maxz = z; } } } } return result.nfail; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libOpenImageIO/iptc.cpp0000644000175000017500000002207412271062644021343 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include "imageio.h" #define DEBUG_IPTC_READ 0 #define DEBUG_IPTC_WRITE 0 OIIO_NAMESPACE_ENTER { namespace { struct IIMtag { int tag; // IIM code const char *name; // Attribute name we use const char *anothername; // Optional second name bool repeatable; // May repeat }; static IIMtag iimtag [] = { { 3, "IPTC:ObjectTypeReference", NULL, false }, { 4, "IPTC:ObjectAttributeReference", NULL, true }, { 5, "IPTC:ObjectName", NULL, false }, { 7, "IPTC:EditStatus", NULL, false }, { 10, "IPTC:Urgency", NULL, false }, // deprecated by IPTC { 12, "IPTC:SubjectReference", NULL, true }, { 15, "IPTC:Category", NULL, false }, { 20, "IPTC:SupplementalCategories", NULL, true }, // deprecated by IPTC { 22, "IPTC:FixtureIdentifier", NULL, false }, { 25, "Keywords", NULL, true }, { 26, "IPTC:ContentLocationCode", NULL, true }, { 27, "IPTC:ContentLocationName", NULL, true }, { 30, "IPTC:ReleaseDate", NULL, false }, { 35, "IPTC:ReleaseTime", NULL, false }, { 37, "IPTC:ExpirationDate", NULL, false }, { 38, "IPTC:ExpirationTime", NULL, false }, { 40, "IPTC:Instructions", NULL, false }, { 45, "IPTC:ReferenceService", NULL, true }, { 47, "IPTC:ReferenceDate", NULL, false }, { 50, "IPTC:ReferenceNumber", NULL, true }, { 55, "IPTC:DateCreated", NULL, false }, { 60, "IPTC:TimeCreated", NULL, false }, { 62, "IPTC:DigitalCreationDate", NULL, false }, { 63, "IPTC:DigitalCreationTime", NULL, false }, { 65, "IPTC:OriginatingProgram", "Software", false }, { 70, "IPTC:ProgramVersion", NULL, false }, { 80, "IPTC:Creator", "Artist", true }, // sometimes called "byline" { 85, "IPTC:AuthorsPosition", NULL, true }, // sometimes "byline title" { 90, "IPTC:City", NULL, false }, { 92, "IPTC:Sublocation", NULL, false }, { 95, "IPTC:State", NULL, false }, // sometimes "Province/State" { 100, "IPTC:CountryCode", NULL, false }, { 101, "IPTC:Country", NULL, false }, { 103, "IPTC:TransmissionReference", NULL, false }, { 105, "IPTC:Headline", NULL, false }, { 110, "IPTC:Provider", NULL, false }, // aka Credit { 115, "IPTC:Source", NULL, false }, { 116, "IPTC:CopyrightNotice", "Copyright", false }, { 118, "IPTC:Contact", NULL, false }, { 120, "IPTC:Caption", "ImageDescription", false}, { 121, "IPTC:LocalCaption", NULL, false}, { 122, "IPTC:CaptionWriter", NULL, false }, // aka Writer/Editor // Note: 150-154 is audio sampling stuff { 184, "IPTC:JobID", NULL, false }, { 185, "IPTC:MasterDocumentID", NULL, false }, { 186, "IPTC:ShortDocumentID", NULL, false }, { 187, "IPTC:UniqueDocumentID", NULL, false }, { 188, "IPTC:OwnerID", NULL, false }, { 221, "IPTC:Prefs", NULL, false }, { 225, "IPTC:ClassifyState", NULL, false }, { 228, "IPTC:SimilarityIndex", NULL, false }, { 230, "IPTC:DocumentNotes", NULL, false }, { 231, "IPTC:DocumentHistory", NULL, false }, { -1, NULL, NULL, false } }; // N.B. All "Date" fields are 8 digit strings: CCYYMMDD // All "Time" fields are 11 digit strings (what format?) } // anonymous namespace bool decode_iptc_iim (const void *iptc, int length, ImageSpec &spec) { const unsigned char *buf = (const unsigned char *) iptc; #if DEBUG_IPTC_READ std::cerr << "IPTC dump:\n"; for (int i = 0; i < 100; ++i) { if (buf[i] >= ' ') std::cerr << (char)buf[i] << ' '; std::cerr << "(" << (int)(unsigned char)buf[i] << ") "; } std::cerr << "\n"; #endif // Now there are a series of data blocks. Each one starts with 1C // 02, then a single byte indicating the tag type, then 2 byte (big // endian) giving the tag length, then the data itself. This // repeats until we've used up the whole segment buffer, or I guess // until we don't find another 1C 02 tag start. // N.B. I don't know why, but Picasa sometimes uses 1C 01 ! while (length > 0 && buf[0] == 0x1c && (buf[1] == 0x02 || buf[1] == 0x01)) { int secondbyte = buf[1]; int tagtype = buf[2]; int tagsize = (buf[3] << 8) + buf[4]; buf += 5; length -= 5; #if DEBUG_IPTC_READ std::cerr << "iptc tag " << tagtype << ":\n"; for (int i = 0; i < tagsize; ++i) { if (buf[i] >= ' ') std::cerr << (char)buf[i] << ' '; std::cerr << "(" << (int)(unsigned char)buf[i] << ") "; } std::cerr << "\n"; #endif if (secondbyte == 0x02) { std::string s ((const char *)buf, tagsize); for (int i = 0; iimtag[i].name; ++i) { if (tagtype == iimtag[i].tag) { if (iimtag[i].repeatable) { // For repeatable IIM tags, concatenate them // together separated by semicolons s = Strutil::strip (s); std::string old = spec.get_string_attribute (iimtag[i].name); if (old.size()) old += "; "; spec.attribute (iimtag[i].name, old+s); } else { spec.attribute (iimtag[i].name, s); } if (iimtag[i].anothername) spec.attribute (iimtag[i].anothername, s); break; } } } buf += tagsize; length -= tagsize; } return true; } static void encode_iptc_iim_one_tag (int tag, const char *name, TypeDesc type, const void *data, std::vector &iptc) { if (type == TypeDesc::STRING) { iptc.push_back ((char)0x1c); iptc.push_back ((char)0x02); iptc.push_back ((char)tag); const char *str = ((const char **)data)[0]; int tagsize = strlen(str); tagsize = std::min (tagsize, 0xffff - 1); // Prevent 16 bit overflow iptc.push_back ((char)(tagsize >> 8)); iptc.push_back ((char)(tagsize & 0xff)); iptc.insert (iptc.end(), str, str+tagsize); } } void encode_iptc_iim (const ImageSpec &spec, std::vector &iptc) { iptc.clear (); const ImageIOParameter *p; for (int i = 0; iimtag[i].name; ++i) { if ((p = spec.find_attribute (iimtag[i].name))) { if (iimtag[i].repeatable) { std::string allvals (*(const char **)p->data()); std::vector tokens; Strutil::split (allvals, tokens, ";"); for (size_t t = 0, e = tokens.size(); t < e; ++t) { tokens[t] = Strutil::strip (tokens[t]); if (tokens[t].size()) { const char *tok = &tokens[t][0]; encode_iptc_iim_one_tag (iimtag[i].tag, iimtag[i].name, p->type(), &tok, iptc); } } } else { // Regular, non-repeating encode_iptc_iim_one_tag (iimtag[i].tag, iimtag[i].name, p->type(), p->data(), iptc); } } if (iimtag[i].anothername) { if ((p = spec.find_attribute (iimtag[i].anothername))) encode_iptc_iim_one_tag (iimtag[i].tag, iimtag[i].anothername, p->type(), p->data(), iptc); } } } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/zfile.imageio/0000755000175000017500000000000012271062644017632 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/zfile.imageio/zfile.cpp0000644000175000017500000002510212271062644021447 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "zlib.h" #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "thread.h" #include "strutil.h" #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace { // anon namespace struct ZfileHeader { int magic; short width; short height; float worldtoscreen[16]; float worldtocamera[16]; }; static const int zfile_magic = 0x2f0867ab; static const int zfile_magic_endian = 0xab67082f; // other endianness } // end anon namespace class ZfileInput : public ImageInput { public: ZfileInput () { init(); } virtual ~ZfileInput () { close(); } virtual const char * format_name (void) const { return "zfile"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (); virtual bool read_native_scanline (int y, int z, void *data); private: std::string m_filename; ///< Stash the filename gzFile m_gz; ///< Handle for compressed files bool m_swab; ///< swap bytes for other endianness? int m_next_scanline; ///< Which scanline is the next to be read? // Reset everything to initial state void init () { m_gz = 0; m_swab = false; m_next_scanline = 0; } }; class ZfileOutput : public ImageOutput { public: ZfileOutput () { init(); } virtual ~ZfileOutput () { close(); } virtual const char * format_name (void) const { return "zfile"; } virtual bool supports (const std::string &feature) const { return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle for not compresed gzFile m_gz; ///< Handle for compressed files std::vector m_scratch; // Initialize private members to pre-opened state void init (void) { m_file = NULL; m_gz = 0; } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *zfile_input_imageio_create () { return new ZfileInput; } OIIO_EXPORT int zfile_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * zfile_input_extensions[] = { "zfile", NULL }; OIIO_EXPORT ImageOutput *zfile_output_imageio_create () { return new ZfileOutput; } OIIO_EXPORT const char * zfile_output_extensions[] = { "zfile", NULL }; OIIO_PLUGIN_EXPORTS_END bool ZfileInput::valid_file (const std::string &filename) const { FILE *fd = Filesystem::fopen (filename, "rb"); gzFile gz = (fd) ? gzdopen (fileno (fd), "rb") : NULL; if (! gz) { if (fd) fclose (fd); return false; } ZfileHeader header; gzread (gz, &header, sizeof(header)); bool ok = (header.magic == zfile_magic || header.magic == zfile_magic_endian); gzclose (gz); return ok; } bool ZfileInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; FILE *fd = Filesystem::fopen (name, "rb"); m_gz = (fd) ? gzdopen (fileno (fd), "rb") : NULL; if (! m_gz) { if (fd) fclose (fd); error ("Could not open file \"%s\"", name.c_str()); return false; } ZfileHeader header; ASSERT (sizeof(header) == 136); gzread (m_gz, &header, sizeof(header)); if (header.magic != zfile_magic && header.magic != zfile_magic_endian) { error ("Not a valid Zfile"); return false; } m_swab = (header.magic == zfile_magic_endian); if (m_swab) { swap_endian (&header.width); swap_endian (&header.height); swap_endian ((float *)&header.worldtoscreen, 16); swap_endian ((float *)&header.worldtocamera, 16); } m_spec = ImageSpec (header.width, header.height, 1, TypeDesc::FLOAT); if (m_spec.channelnames.size() == 0) m_spec.channelnames.push_back ("z"); else m_spec.channelnames[0] = "z"; m_spec.z_channel = 0; m_spec.attribute ("worldtoscreen", TypeDesc::TypeMatrix, (float *)&header.worldtoscreen); m_spec.attribute ("worldtocamera", TypeDesc::TypeMatrix, (float *)&header.worldtocamera); newspec = spec (); return true; } bool ZfileInput::close () { if (m_gz) { gzclose (m_gz); m_gz = 0; } init(); // Reset to initial state return true; } bool ZfileInput::read_native_scanline (int y, int z, void *data) { if (m_next_scanline > y) { // User is trying to read an earlier scanline than the one we're // up to. Easy fix: close the file and re-open. ImageSpec dummyspec; int subimage = current_subimage(); if (! close () || ! open (m_filename, dummyspec) || ! seek_subimage (subimage, dummyspec)) return false; // Somehow, the re-open failed ASSERT (m_next_scanline == 0 && current_subimage() == subimage); } while (m_next_scanline <= y) { // Keep reading until we're read the scanline we really need gzread (m_gz, data, m_spec.width*sizeof(float)); ++m_next_scanline; } if (m_swab) swap_endian ((float *)data, m_spec.width); return true; } bool ZfileOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } close (); // Close any already-opened file m_gz = 0; m_file = NULL; m_spec = userspec; // Stash the spec // Check for things this format doesn't support if (m_spec.width < 1 || m_spec.height < 1) { error ("Image resolution must be at least 1x1, you asked for %d x %d", m_spec.width, m_spec.height); return false; } if (m_spec.depth < 1) m_spec.depth = 1; if (m_spec.depth > 1) { error ("%s does not support volume images (depth > 1)", format_name()); return false; } if (m_spec.nchannels != 1) { error ("Zfile only supports 1-4 channels, not %d", m_spec.nchannels); return false; } // Force float if (m_spec.format != TypeDesc::FLOAT) m_spec.format = TypeDesc::FLOAT; ZfileHeader header; header.magic = zfile_magic; header.width = (int)m_spec.width; header.height = (int)m_spec.height; ImageIOParameter *p; static float ident[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; if ((p = m_spec.find_attribute ("worldtocamera", TypeDesc::TypeMatrix))) memcpy (header.worldtocamera, p->data(), 16*sizeof(float)); else memcpy (header.worldtocamera, ident, 16*sizeof(float)); if ((p = m_spec.find_attribute ("worldtoscreen", TypeDesc::TypeMatrix))) memcpy (header.worldtoscreen, p->data(), 16*sizeof(float)); else memcpy (header.worldtoscreen, ident, 16*sizeof(float)); if (m_spec.get_string_attribute ("compression", "none") != std::string("none")) { FILE *fd = Filesystem::fopen (name, "wb"); if (fd) { m_gz = gzdopen (fileno (fd), "wb"); if (!m_gz) fclose (fd); } } else m_file = Filesystem::fopen (name, "wb"); if (! m_file && ! m_gz) { error ("Could not open file \"%s\"", name.c_str()); return false; } if (m_gz) gzwrite (m_gz, &header, sizeof(header)); else { size_t b = fwrite (&header, sizeof(header), 1, m_file); if (b != 1) { error ("Failed write zfile::open (err: %d)", b); return false; } } return true; } bool ZfileOutput::close () { if (m_gz) { gzclose (m_gz); m_gz = 0; } if (m_file) { fclose (m_file); m_file = NULL; } init (); // re-initialize return true; // How can we fail? } bool ZfileOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { y -= m_spec.y; m_spec.auto_stride (xstride, format, spec().nchannels); const void *origdata = data; data = to_native_scanline (format, data, xstride, m_scratch); if (data == origdata) { m_scratch.assign ((unsigned char *)data, (unsigned char *)data+m_spec.scanline_bytes()); data = &m_scratch[0]; } if (m_gz) gzwrite (m_gz, data, m_spec.width*sizeof(float)); else { size_t b = fwrite (data, sizeof(float), m_spec.width, m_file); if (b != (size_t)m_spec.width) { error ("Failed write zfile::open (err: %d)", b); return false; } } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/zfile.imageio/CMakeLists.txt0000644000175000017500000000023512271062644022372 0ustar mfvmfvfind_package (ZLIB) if (ZLIB_FOUND) include_directories (${ZLIB_INCLUDE_DIR}) add_oiio_plugin (zfile.cpp LINK_LIBRARIES ${ZLIB_LIBRARIES}) endif () openimageio-1.3.12~dfsg0.orig/src/sgi.imageio/0000755000175000017500000000000012271062644017303 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/sgi.imageio/sgioutput.cpp0000644000175000017500000001517712271062644022065 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include using boost::algorithm::iequals; #include "sgi_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *sgi_output_imageio_create () { return new SgiOutput; } OIIO_EXPORT const char *sgi_output_extensions[] = { "sgi", "rgb", "rgba", "bw", "int", "inta", NULL }; OIIO_PLUGIN_EXPORTS_END bool SgiOutput::open (const std::string &name, const ImageSpec &spec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } close (); // Close any already-opened file // saving 'name' and 'spec' for later use m_filename = name; m_spec = spec; m_fd = Filesystem::fopen (m_filename, "wb"); if (!m_fd) { error ("Unable to open file \"%s\"", m_filename.c_str ()); return false; } // SGI image files only supports UINT8 and UINT16. If something // else was requested, revert to the one most likely to be readable // by any SGI reader: UINT8 if (m_spec.format != TypeDesc::UINT8 && m_spec.format != TypeDesc::UINT16) m_spec.set_format (TypeDesc::UINT8); return create_and_write_header(); } bool SgiOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { y = m_spec.height - y - 1; data = to_native_scanline (format, data, xstride, m_scratch); // In SGI format all channels are saved to file separately: firsty all // channel 1 scanlines are saved, then all channel2 scanlines are saved // and so on. // // Note that since SGI images are pretty archaic and most probably // people won't be too picky about full flexibility writing them, we // content ourselves with only writing uncompressed data, and don't // attempt to write with RLE encoding. int bpc = m_spec.format.size(); // bytes per channel std::vector channeldata (m_spec.width * bpc); for (int c = 0; c < m_spec.nchannels; ++c) { unsigned char *cdata = (unsigned char *)data + c*bpc; for (int x = 0; x < m_spec.width; ++x) { channeldata[x*bpc] = cdata[0]; if (bpc == 2) channeldata[x*bpc+1] = cdata[1]; cdata += m_spec.nchannels * bpc; // advance to next pixel } if (bpc == 2 && littleendian()) swap_endian ((unsigned short *)&channeldata[0], m_spec.width); long scanline_offset = sgi_pvt::SGI_HEADER_LEN + (c * m_spec.height + y) * m_spec.width * bpc; fseek (m_fd, scanline_offset, SEEK_SET); if (!fwrite (&channeldata[0], 1, m_spec.width * bpc)) { return false; } } return true; } bool SgiOutput::close () { if (m_fd) fclose (m_fd); init (); return true; } bool SgiOutput::create_and_write_header() { sgi_pvt::SgiHeader sgi_header; sgi_header.magic = sgi_pvt::SGI_MAGIC; sgi_header.storage = sgi_pvt::VERBATIM; sgi_header.bpc = m_spec.format.size(); if (m_spec.height == 1 && m_spec.nchannels == 1) sgi_header.dimension = sgi_pvt::ONE_SCANLINE_ONE_CHANNEL; else if (m_spec.nchannels == 1) sgi_header.dimension = sgi_pvt::MULTI_SCANLINE_ONE_CHANNEL; else sgi_header.dimension = sgi_pvt::MULTI_SCANLINE_MULTI_CHANNEL; sgi_header.xsize = m_spec.width; sgi_header.ysize = m_spec.height; sgi_header.zsize = m_spec.nchannels; sgi_header.pixmin = 0; sgi_header.pixmax = (sgi_header.bpc == 1) ? 255 : 65535; sgi_header.dummy = 0; ImageIOParameter *ip = m_spec.find_attribute ("ImageDescription", TypeDesc::STRING); if (ip && ip->data()) { const char** img_descr = (const char**)ip->data(); strncpy (sgi_header.imagename, *img_descr, 80); sgi_header.imagename[79] = 0; } sgi_header.colormap = sgi_pvt::NORMAL; if (littleendian()) { swap_endian(&sgi_header.magic); swap_endian(&sgi_header.dimension); swap_endian(&sgi_header.xsize); swap_endian(&sgi_header.ysize); swap_endian(&sgi_header.zsize); swap_endian(&sgi_header.pixmin); swap_endian(&sgi_header.pixmax); swap_endian(&sgi_header.colormap); } char dummy[404] = {0}; if (!fwrite(&sgi_header.magic) || !fwrite(&sgi_header.storage) || !fwrite(&sgi_header.bpc) || !fwrite(&sgi_header.dimension) || !fwrite(&sgi_header.xsize) || !fwrite(&sgi_header.ysize) || !fwrite(&sgi_header.zsize) || !fwrite(&sgi_header.pixmin) || !fwrite(&sgi_header.pixmax) || !fwrite(&sgi_header.dummy) || !fwrite(sgi_header.imagename, 1, 80) || !fwrite(&sgi_header.colormap) || !fwrite(dummy, 404, 1)) { error ("Error writing to \"%s\"", m_filename); return false; } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/sgi.imageio/sgiinput.cpp0000644000175000017500000002522112271062644021653 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "sgi_pvt.h" #include "dassert.h" OIIO_PLUGIN_NAMESPACE_BEGIN // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int sgi_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *sgi_input_imageio_create () { return new SgiInput; } OIIO_EXPORT const char *sgi_input_extensions[] = { "sgi", "rgb", "rgba", "bw", "int", "inta", NULL }; OIIO_PLUGIN_EXPORTS_END bool SgiInput::valid_file (const std::string &filename) const { FILE *fd = Filesystem::fopen (filename, "rb"); if (!fd) return false; int16_t magic; bool ok = (::fread (&magic, sizeof(magic), 1, fd) == 1) && (magic == sgi_pvt::SGI_MAGIC); fclose (fd); return ok; } bool SgiInput::open (const std::string &name, ImageSpec &spec) { // saving name for later use m_filename = name; m_fd = Filesystem::fopen (m_filename, "rb"); if (!m_fd) { error ("Could not open file \"%s\"", name.c_str()); return false; } if (! read_header ()) return false; if (m_sgi_header.magic != sgi_pvt::SGI_MAGIC) { error ("\"%s\" is not a SGI file, magic number doesn't match", m_filename.c_str()); close (); return false; } int height = 0; int nchannels = 0; switch (m_sgi_header.dimension) { case sgi_pvt::ONE_SCANLINE_ONE_CHANNEL: height = 1; nchannels = 1; break; case sgi_pvt::MULTI_SCANLINE_ONE_CHANNEL: height = m_sgi_header.ysize; nchannels = 1; break; case sgi_pvt::MULTI_SCANLINE_MULTI_CHANNEL: height = m_sgi_header.ysize; nchannels = m_sgi_header.zsize; break; default: error ("Bad dimension: %d", m_sgi_header.dimension); close (); return false; } if (m_sgi_header.colormap == sgi_pvt::COLORMAP || m_sgi_header.colormap == sgi_pvt::SCREEN) { error ("COLORMAP and SCREEN color map types aren't supported"); close (); return false; } m_spec = ImageSpec (m_sgi_header.xsize, height, nchannels, m_sgi_header.bpc == 1 ? TypeDesc::UINT8 : TypeDesc::UINT16); if (strlen (m_sgi_header.imagename)) m_spec.attribute("ImageDescription", m_sgi_header.imagename); if (m_sgi_header.storage == sgi_pvt::RLE) { m_spec.attribute("compression", "rle"); if (! read_offset_tables ()) return false; } spec = m_spec; return true; } bool SgiInput::read_native_scanline (int y, int z, void *data) { if (y < 0 || y > m_spec.height) return false; y = m_spec.height - y - 1; int bpc = m_sgi_header.bpc; std::vector > channeldata (m_spec.nchannels); if (m_sgi_header.storage == sgi_pvt::RLE) { // reading and uncompressing first channel (red in RGBA images) for (int c = 0; c < m_spec.nchannels; ++c) { int off = y + c*m_spec.height; // offset for this scanline/channel int scanline_offset = start_tab[off]; int scanline_length = length_tab[off]; channeldata[c].resize (m_spec.width * bpc); uncompress_rle_channel (scanline_offset, scanline_length, &(channeldata[c][0])); } } else { // non-RLE case -- just read directly into our channel data for (int c = 0; c < m_spec.nchannels; ++c) { int off = y + c*m_spec.height; // offset for this scanline/channel int scanline_offset = sgi_pvt::SGI_HEADER_LEN + off * m_spec.width * bpc; fseek (m_fd, scanline_offset, SEEK_SET); channeldata[c].resize (m_spec.width * bpc); if (! fread (&(channeldata[c][0]), 1, m_spec.width * bpc)) return false; } } if (m_spec.nchannels == 1) { // If just one channel, no interleaving is necessary, just memcpy memcpy (data, &(channeldata[0][0]), channeldata[0].size()); } else { unsigned char *cdata = (unsigned char *)data; for (int x = 0; x < m_spec.width; ++x) { for (int c = 0; c < m_spec.nchannels; ++c) { *cdata++ = channeldata[c][x*bpc]; if (bpc == 2) *cdata++ = channeldata[c][x*bpc+1]; } } } // Swap endianness if needed if (bpc == 2 && littleendian()) swap_endian ((unsigned short *)data, m_spec.width*m_spec.nchannels); return true; } bool SgiInput::uncompress_rle_channel(int scanline_off, int scanline_len, unsigned char *out) { int bpc = m_sgi_header.bpc; std::vector rle_scanline (scanline_len); fseek (m_fd, scanline_off, SEEK_SET); if (! fread (&rle_scanline[0], 1, scanline_len)) return false; int limit = m_spec.width; int i = 0; if (bpc == 1) { // 1 bit per channel while (i < scanline_len) { // Read a byte, it is the count. unsigned char value = rle_scanline[i++]; int count = value & 0x7F; // If the count is zero, we're done if (! count) break; // If the high bit is set, we just copy the next 'count' values if (value & 0x80) { while (count--) { DASSERT (i < scanline_len && limit > 0); *(out++) = rle_scanline[i++]; --limit; } } // If the high bit is zero, we copy the NEXT value, count times else { value = rle_scanline[i++]; while (count--) { DASSERT (limit > 0); *(out++) = value; --limit; } } } } else { // 2 bits per channel ASSERT (bpc == 2); while (i < scanline_len) { // Read a byte, it is the count. unsigned short value = (rle_scanline[i] << 8) | rle_scanline[i+1]; i += 2; int count = value & 0x7F; // If the count is zero, we're done if (! count) break; // If the high bit is set, we just copy the next 'count' values if (value & 0x80) { while (count--) { DASSERT (i+1 < scanline_len && limit > 0); *(out++) = rle_scanline[i++]; *(out++) = rle_scanline[i++]; --limit; } } // If the high bit is zero, we copy the NEXT value, count times else { while (count--) { DASSERT (limit > 0); *(out++) = rle_scanline[i]; *(out++) = rle_scanline[i+1]; --limit; } i += 2; } } } if (i != scanline_len || limit != 0) { error ("Corrupt RLE data"); return false; } return true; } bool SgiInput::close() { if (m_fd) fclose (m_fd); init (); return true; } bool SgiInput::read_header() { if (!fread(&m_sgi_header.magic, sizeof(m_sgi_header.magic), 1) || !fread(&m_sgi_header.storage, sizeof(m_sgi_header.storage), 1) || !fread(&m_sgi_header.bpc, sizeof(m_sgi_header.bpc), 1) || !fread(&m_sgi_header.dimension, sizeof(m_sgi_header.dimension), 1) || !fread(&m_sgi_header.xsize, sizeof(m_sgi_header.xsize), 1) || !fread(&m_sgi_header.ysize, sizeof(m_sgi_header.ysize), 1) || !fread(&m_sgi_header.zsize, sizeof(m_sgi_header.zsize), 1) || !fread(&m_sgi_header.pixmin, sizeof(m_sgi_header.pixmin), 1) || !fread(&m_sgi_header.pixmax, sizeof(m_sgi_header.pixmax), 1) || !fread(&m_sgi_header.dummy, sizeof(m_sgi_header.dummy), 1) || !fread(&m_sgi_header.imagename, sizeof(m_sgi_header.imagename), 1)) return false; m_sgi_header.imagename[79] = '\0'; if (! fread(&m_sgi_header.colormap, sizeof(m_sgi_header.colormap), 1)) return false; //don't read dummy bytes fseek (m_fd, 404, SEEK_CUR); if (littleendian()) { swap_endian(&m_sgi_header.magic); swap_endian(&m_sgi_header.dimension); swap_endian(&m_sgi_header.xsize); swap_endian(&m_sgi_header.ysize); swap_endian(&m_sgi_header.zsize); swap_endian(&m_sgi_header.pixmin); swap_endian(&m_sgi_header.pixmax); swap_endian(&m_sgi_header.colormap); } return true; } bool SgiInput::read_offset_tables () { int tables_size = m_sgi_header.ysize * m_sgi_header.zsize; start_tab.resize(tables_size); length_tab.resize(tables_size); if (!fread (&start_tab[0], sizeof(uint32_t), tables_size) || !fread (&length_tab[0], sizeof(uint32_t), tables_size)) return false; if (littleendian ()) { swap_endian (&length_tab[0], length_tab.size ()); swap_endian (&start_tab[0], start_tab.size()); } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/sgi.imageio/sgi_pvt.h0000644000175000017500000001452612271062644021137 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_SGI_H #define OPENIMAGEIO_SGI_H // Format reference: ftp://ftp.sgi.com/graphics/SGIIMAGESPEC #include #include "imageio.h" #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace sgi_pvt { // magic number identifying SGI file const short SGI_MAGIC = 0x01DA; // SGI file header - all fields are written in big-endian to file struct SgiHeader { int16_t magic; // must be 0xDA01 (big-endian) int8_t storage; // compression used, see StorageFormat enum int8_t bpc; // number of bytes per pixel channel uint16_t dimension; // dimension of he image, see Dimension uint16_t xsize; // width in pixels uint16_t ysize; // height in pixels uint16_t zsize; // number of channels: 1(B/W), 3(RGB) or 4(RGBA) int32_t pixmin; // minimum pixel value int32_t pixmax; // maximum pixel value int32_t dummy; // unused, should be set to 0 char imagename[80]; // null terminated ASCII string int32_t colormap; // how pixels should be interpreted // see ColorMap enum }; // size of the header with all dummy bytes const int SGI_HEADER_LEN = 512; enum StorageFormat { VERBATIM= 0, // uncompressed RLE // RLE compressed }; enum Dimension { ONE_SCANLINE_ONE_CHANNEL = 1, // single scanline and single channel MULTI_SCANLINE_ONE_CHANNEL, // multiscanline, single channel MULTI_SCANLINE_MULTI_CHANNEL // multiscanline, multichannel }; enum ColorMap { NORMAL = 0, // B/W image for 1 channel, RGB for 3 channels and RGBA for 4 DITHERED, // only one channel of data, RGB values are packed int one byte: // red and gree - 3 bits, blue - 2 bits; obsolete SCREEN, // obsolete COLORMAP // TODO: what is this? }; } // namespace sgi_pvt class SgiInput : public ImageInput { public: SgiInput () { init(); } virtual ~SgiInput () { close(); } virtual const char *format_name (void) const { return "sgi"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &spec); virtual bool close (void); virtual bool read_native_scanline (int y, int z, void *data); private: FILE *m_fd; std::string m_filename; sgi_pvt::SgiHeader m_sgi_header; std::vector start_tab; std::vector length_tab; void init() { m_fd = NULL; memset (&m_sgi_header, 0, sizeof(m_sgi_header)); } // reads SGI file header (512 bytes) into m_sgi_header // Return true if ok, false if there was a read error. bool read_header(); // reads RLE scanline start offset and RLE scanline length tables // RLE scanline start offset is stored in start_tab // RLE scanline length is stored in length_tab // Return true if ok, false if there was a read error. bool read_offset_tables(); // read channel scanline data from file, uncompress it and save the data to // 'out' buffer; 'out' should be allocate before call to this method. // Return true if ok, false if there was a read error. bool uncompress_rle_channel (int scanline_off, int scanline_len, unsigned char *out); /// Helper: read, with error detection /// bool fread (void *buf, size_t itemsize, size_t nitems) { size_t n = ::fread (buf, itemsize, nitems, m_fd); if (n != nitems) error ("Read error"); return n == nitems; } }; class SgiOutput : public ImageOutput { public: SgiOutput () : m_fd(NULL) { } virtual ~SgiOutput () { close(); } virtual const char *format_name (void) const { return "sgi"; } virtual bool supports (const std::string &feature) const { return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (void); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: FILE *m_fd; std::string m_filename; std::vector m_scratch; void init () { m_fd = NULL; } bool create_and_write_header(); /// Helper - write, with error detection template bool fwrite (const T *buf, size_t itemsize=sizeof(T), size_t nitems=1) { size_t n = std::fwrite (buf, itemsize, nitems, m_fd); if (n != nitems) error ("Error writing \"%s\" (wrote %d/%d records)", m_filename, (int)n, (int)nitems); return n == nitems; } }; OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_SGI_H openimageio-1.3.12~dfsg0.orig/src/sgi.imageio/CMakeLists.txt0000644000175000017500000000005512271062644022043 0ustar mfvmfvadd_oiio_plugin (sgiinput.cpp sgioutput.cpp) openimageio-1.3.12~dfsg0.orig/src/igrep/0000755000175000017500000000000012271062644016216 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/igrep/CMakeLists.txt0000644000175000017500000000037012271062644020756 0ustar mfvmfvset (igrep_srcs igrep.cpp) add_executable (igrep ${igrep_srcs}) set_target_properties (igrep PROPERTIES FOLDER "Tools") link_ilmbase (igrep) target_link_libraries (igrep OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) oiio_install_targets (igrep) openimageio-1.3.12~dfsg0.orig/src/igrep/igrep.cpp0000644000175000017500000001500612271062644020032 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include using namespace boost::filesystem; #include "argparse.h" #include "strutil.h" #include "filesystem.h" #include "imageio.h" OIIO_NAMESPACE_USING; static bool help = false; static bool invert_match = false; static bool ignore_case = false; static bool list_files = false; static bool recursive = false; static bool file_match = false; static bool print_dirs = false; static bool all_subimages = false; static bool extended_regex = false; static std::string pattern; static std::vector filenames; static bool grep_file (const std::string &filename, boost::regex &re, bool ignore_nonimage_files=false) { if (! Filesystem::exists (filename)) { std::cerr << "igrep: " << filename << ": No such file or directory\n"; return false; } if (Filesystem::is_directory (filename)) { if (! recursive) return false; if (print_dirs) { std::cout << "(" << filename << "/)\n"; std::cout.flush(); } bool r = false; boost::filesystem::path path (filename); boost::filesystem::directory_iterator end_itr; // default is past-end for (boost::filesystem::directory_iterator itr(path); itr != end_itr; ++itr) { // std::cout << " rec " << itr->path() << "\n"; r |= grep_file (itr->path().string(), re, true); } return r; } boost::scoped_ptr in (ImageInput::open (filename.c_str())); if (! in.get()) { if (! ignore_nonimage_files) std::cerr << geterror() << "\n"; return false; } ImageSpec spec = in->spec(); if (file_match) { bool match = boost::regex_search (filename, re); if (match && ! invert_match) { std::cout << filename << "\n"; return true; } } bool found = false; int subimage = 0; do { if (!all_subimages && subimage > 0) break; BOOST_FOREACH (const ImageIOParameter &p, spec.extra_attribs) { TypeDesc t = p.type(); if (t.elementtype() == TypeDesc::STRING) { int n = t.numelements(); for (int i = 0; i < n; ++i) { bool match = boost::regex_search (((const char **)p.data())[i], re); found |= match; if (match && ! invert_match) { if (list_files) { std::cout << filename << "\n"; return found; } std::cout << filename << ": " << p.name() << " = " << ((const char **)p.data())[i] << "\n"; } } } } } while (in->seek_subimage (++subimage, 0, spec)); if (invert_match) { found = !found; if (found) std::cout << filename << "\n"; } return found; } static int parse_files (int argc, const char *argv[]) { for (int i = 0; i < argc; i++) { if (pattern.empty()) pattern = argv[i]; else filenames.push_back (argv[i]); } return 0; } int main (int argc, const char *argv[]) { Filesystem::convert_native_arguments (argc, argv); ArgParse ap; ap.options ("igrep -- search images for matching metadata\n" OIIO_INTRO_STRING "\n" "Usage: igrep [options] pattern filename...", "%*", parse_files, "", "-i", &ignore_case, "Ignore upper/lower case distinctions", "-v", &invert_match, "Invert match (select non-matching files)", "-E", &extended_regex, "Pattern is an extended regular expression", "-f", &file_match, "Match against file name as well as metadata", "-l", &list_files, "List the matching files (no detail)", "-r", &recursive, "Recurse into directories", "-d", &print_dirs, "Print directories (when recursive)", "-a", &all_subimages, "Search all subimages of each file", "--help", &help, "Print help message", NULL); if (ap.parse(argc, argv) < 0 || pattern.empty() || filenames.empty()) { std::cerr << ap.geterror() << std::endl; ap.usage (); return EXIT_FAILURE; } if (help) { ap.usage (); exit (EXIT_FAILURE); } boost::regex_constants::syntax_option_type flag = boost::regex_constants::grep; if (extended_regex) flag = boost::regex::extended; if (ignore_case) flag |= boost::regex_constants::icase; boost::regex re (pattern, flag); BOOST_FOREACH (const std::string &s, filenames) { grep_file (s, re); } return 0; } openimageio-1.3.12~dfsg0.orig/src/bmp.imageio/0000755000175000017500000000000012271062644017277 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/bmp.imageio/bmpoutput.cpp0000644000175000017500000001306012271062644022042 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "strutil.h" #include "bmp_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace bmp_pvt; // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *bmp_output_imageio_create () { return new BmpOutput; } OIIO_EXPORT const char *bmp_output_extensions[] = { "bmp", NULL }; OIIO_PLUGIN_EXPORTS_END bool BmpOutput::open (const std::string &name, const ImageSpec &spec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } // saving 'name' and 'spec' for later use m_filename = name; m_spec = spec; // TODO: Figure out what to do with nchannels. m_fd = Filesystem::fopen (m_filename, "wb"); if (! m_fd) { error ("Unable to open file \"%s\"", m_filename.c_str ()); return false; } create_and_write_file_header (); create_and_write_bitmap_header (); // Scanline size is rounded up to align to 4-byte boundary m_scanline_size = ((m_spec.width * m_spec.nchannels) + 3) & ~3; fgetpos (m_fd, &m_image_start); // Only support 8 bit channels for now. m_spec.set_format (TypeDesc::UINT8); return true; } bool BmpOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { if (y > m_spec.height) { error ("Attempt to write too many scanlines to %s", m_filename.c_str()); close (); return false; } if (m_spec.width >= 0) y = (m_spec.height - y - 1); int scanline_off = y * m_scanline_size; fsetpos (m_fd, &m_image_start); fseek (m_fd, scanline_off, SEEK_CUR); std::vector scratch; data = to_native_scanline (format, data, xstride, scratch); std::vector buf (m_scanline_size); memcpy (&buf[0], data, m_scanline_size); // Swap RGB pixels into BGR format for (int i = 0, iend = buf.size() - 2; i < iend; i += m_spec.nchannels) std::swap (buf[i], buf[i+2]); size_t byte_count = fwrite (&buf[0], 1, buf.size (), m_fd); return byte_count == buf.size (); // true if wrote all bytes (no error) } bool BmpOutput::close (void) { if (m_fd) { fclose (m_fd); m_fd = NULL; } return true; } void BmpOutput::create_and_write_file_header (void) { m_bmp_header.magic = MAGIC_BM; const int data_size = m_spec.width * m_spec.height * m_spec.nchannels; const int file_size = data_size + BMP_HEADER_SIZE + WINDOWS_V3; m_bmp_header.fsize = file_size; m_bmp_header.res1 = 0; m_bmp_header.res2 = 0; m_bmp_header.offset = BMP_HEADER_SIZE + WINDOWS_V3; m_bmp_header.write_header (m_fd); } void BmpOutput::create_and_write_bitmap_header (void) { m_dib_header.size = WINDOWS_V3; m_dib_header.width = m_spec.width; m_dib_header.height = m_spec.height; m_dib_header.cplanes = 1; m_dib_header.compression = 0; m_dib_header.bpp = m_spec.nchannels << 3; m_dib_header.isize = m_spec.width * m_spec.height * m_spec.nchannels; m_dib_header.hres = 0; m_dib_header.vres = 0; m_dib_header.cpalete = 0; m_dib_header.important = 0; ImageIOParameter *p = NULL; p = m_spec.find_attribute ("ResolutionUnit", TypeDesc::STRING); if (p && p->data()) { std::string res_units = *(char**)p->data (); if (Strutil::iequals (res_units, "m") || Strutil::iequals (res_units, "pixel per meter")) { ImageIOParameter *resx = NULL, *resy = NULL; resx = m_spec.find_attribute ("XResolution", TypeDesc::INT32); if (resx && resx->data()) m_dib_header.hres = *(int*)resx->data (); resy = m_spec.find_attribute ("YResolution", TypeDesc::INT32); if (resy && resy->data()) m_dib_header.vres = *(int*)resy->data (); } } m_dib_header.write_header (m_fd); } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/bmp.imageio/bmp_pvt.cpp0000644000175000017500000001324112271062644021453 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "bmp_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace bmp_pvt { /// Helper - write, with error detection template bool fwrite (FILE *fd, const T *buf) { size_t n = std::fwrite (buf, sizeof(T), 1, fd); return n == 1; } /// Helper - read, with error detection template bool fread (FILE *fd, T *buf, size_t itemsize=sizeof(T)) { size_t n = std::fread (buf, itemsize, 1, fd); return n == 1; } bool BmpFileHeader::read_header (FILE *fd) { if (!fread(fd, &magic) || !fread(fd, &fsize) || !fread(fd, &res1) || !fread(fd, &res2) || !fread(fd, &offset)) { return false; } if (bigendian ()) swap_endian (); return true; } bool BmpFileHeader::write_header (FILE *fd) { if (bigendian ()) swap_endian (); if (!fwrite(fd, &magic) || !fwrite(fd, &fsize) || !fwrite(fd, &res1) || !fwrite(fd, &res2) || !fwrite(fd, &offset)) { return false; } return true; } bool BmpFileHeader::isBmp () const { switch (magic) { case MAGIC_BM: case MAGIC_BA: case MAGIC_CI: case MAGIC_CP: case MAGIC_PT: return true; } return false; } void BmpFileHeader::swap_endian (void) { OIIO::swap_endian (&magic); OIIO::swap_endian (&fsize); OIIO::swap_endian (&offset); } bool DibInformationHeader::read_header (FILE *fd) { if (!fread (fd, &size)) return false; if (size == WINDOWS_V3 || size == WINDOWS_V4) { if (!fread(fd, &width) || !fread(fd, &height) || !fread(fd, &cplanes) || !fread(fd, &bpp) || !fread(fd, &compression) || !fread(fd, &isize) || !fread(fd, &hres) || !fread(fd, &vres) || !fread(fd, &cpalete) || !fread(fd, &important)) { return false; } if (size == WINDOWS_V4) { int32_t dummy; if (!fread (fd, &red_mask) || !fread (fd, &blue_mask) || !fread (fd, &green_mask) || !fread (fd, &cs_type) || !fread (fd, &red_x) || !fread (fd, &red_y) || !fread (fd, &red_z) || !fread (fd, &green_x) || !fread (fd, &green_y) || !fread (fd, &green_z) || !fread (fd, &blue_x) || !fread (fd, &blue_y) || !fread (fd, &blue_z) || !fread (fd, &gamma_x) || !fread (fd, &gamma_y) || !fread (fd, &gamma_z) || !fread (fd, &dummy)) { return false; } } } else if (size == OS2_V1) { // some of theses fields are smaller then in WINDOWS_Vx headers, // so we use hardcoded counts width = 0; height = 0; if (!fread (fd, &width, 2) || !fread (fd, &height, 2) || !fread (fd, &cplanes) || !fread (fd, &bpp)) { return false; } } if (bigendian ()) swap_endian (); return true; } bool DibInformationHeader::write_header (FILE *fd) { if (bigendian ()) swap_endian (); if (!fwrite (fd, &size) || !fwrite (fd, &width) || !fwrite (fd, &height) || !fwrite (fd, &cplanes) || !fwrite (fd, &bpp) || !fwrite (fd, &compression) || !fwrite (fd, &isize) || !fwrite (fd, &hres) || !fwrite (fd, &vres) || !fwrite (fd, &cpalete) || !fwrite (fd, &important)) { return false; } return (true); } void DibInformationHeader::swap_endian () { OIIO::swap_endian (&size); OIIO::swap_endian (&width); OIIO::swap_endian (&height); OIIO::swap_endian (&cplanes); OIIO::swap_endian (&bpp); OIIO::swap_endian (&compression); OIIO::swap_endian (&isize); OIIO::swap_endian (&hres); OIIO::swap_endian (&vres); OIIO::swap_endian (&cpalete); OIIO::swap_endian (&important); } } // bmp_pvt namespace OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/bmp.imageio/bmpinput.cpp0000644000175000017500000002222312271062644021642 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "bmp_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace bmp_pvt; // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int bmp_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *bmp_input_imageio_create () { return new BmpInput; } OIIO_EXPORT const char *bmp_input_extensions[] = { "bmp", NULL }; OIIO_PLUGIN_EXPORTS_END bool BmpInput::valid_file (const std::string &filename) const { FILE *fd = Filesystem::fopen (filename, "rb"); if (!fd) return false; bmp_pvt::BmpFileHeader bmp_header; bool ok = bmp_header.read_header(fd) && bmp_header.isBmp(); fclose (fd); return ok; } bool BmpInput::open (const std::string &name, ImageSpec &spec) { // saving 'name' for later use m_filename = name; m_fd = Filesystem::fopen (m_filename, "rb"); if (!m_fd) { error ("Could not open file \"%s\"", name.c_str()); return false; } // we read header of the file that we think is BMP file if (! m_bmp_header.read_header (m_fd)) { error ("\"%s\": wrong bmp header size", m_filename.c_str()); close (); return false; } if (! m_bmp_header.isBmp ()) { error ("\"%s\" is not a BMP file, magic number doesn't match", m_filename.c_str()); close (); return false; } if (! m_dib_header.read_header (m_fd)) { error ("\"%s\": wrong bitmap header size", m_filename.c_str()); close (); return false; } const int nchannels = (m_dib_header.bpp == 32) ? 4 : 3; const int height = (m_dib_header.height >= 0) ? m_dib_header.height : -m_dib_header.height; m_spec = ImageSpec (m_dib_header.width, height, nchannels, TypeDesc::UINT8); m_spec.attribute ("XResolution", (int)m_dib_header.hres); m_spec.attribute ("YResolution", (int)m_dib_header.vres); m_spec.attribute ("ResolutionUnit", "m"); // comupting size of one scanline - this is the size of one scanline that // is stored in the file, not in the memory int swidth = 0; switch (m_dib_header.bpp) { case 32 : case 24 : m_scanline_size = ((m_spec.width * m_spec.nchannels) + 3) & ~3; break; case 16 : m_scanline_size = ((m_spec.width << 1) + 3) & ~3; m_spec.attribute ("oiio:BitsPerSample", 4); break; case 8 : m_scanline_size = (m_spec.width + 3) & ~3; if (! read_color_table ()) return false; break; case 4 : swidth = (m_spec.width + 1) / 2; m_scanline_size = (swidth + 3) & ~3; if (! read_color_table ()) return false; break; case 1 : swidth = (m_spec.width + 7) / 8; m_scanline_size = (swidth + 3) & ~3; if (! read_color_table ()) return false; break; } // file pointer is set to the beginning of image data // we save this position - it will be helpfull in read_native_scanline fgetpos (m_fd, &m_image_start); spec = m_spec; return true; } bool BmpInput::read_native_scanline (int y, int z, void *data) { if (y < 0 || y > m_spec.height) return false; // if the height is positive scanlines are stored bottom-up if (m_dib_header.width >= 0) y = m_spec.height - y - 1; const int scanline_off = y * m_scanline_size; std::vector fscanline (m_scanline_size); fsetpos (m_fd, &m_image_start); fseek (m_fd, scanline_off, SEEK_CUR); size_t n = fread (&fscanline[0], 1, m_scanline_size, m_fd); if (n != (size_t)m_scanline_size) { if (feof (m_fd)) error ("Hit end of file unexpectedly"); else error ("read error"); return false; // Read failed } // in each case we process only first m_spec.scanline_bytes () bytes // as only they contain information about pixels. The rest are just // because scanline size have to be 32-bit boundary if (m_dib_header.bpp == 24 || m_dib_header.bpp == 32) { for (unsigned int i = 0; i < m_spec.scanline_bytes (); i += m_spec.nchannels) std::swap (fscanline[i], fscanline[i+2]); memcpy (data, &fscanline[0], m_spec.scanline_bytes()); return true; } std::vector mscanline (m_spec.scanline_bytes()); if (m_dib_header.bpp == 16) { const uint16_t RED = 0x7C00; const uint16_t GREEN = 0x03E0; const uint16_t BLUE = 0x001F; for (unsigned int i = 0, j = 0; j < m_spec.scanline_bytes(); i+=2, j+=3) { uint16_t pixel = (uint16_t)*(&fscanline[i]); mscanline[j] = (uint8_t)((pixel & RED) >> 8); mscanline[j+1] = (uint8_t)((pixel & GREEN) >> 4); mscanline[j+2] = (uint8_t)(pixel & BLUE); } } if (m_dib_header.bpp == 8) { for (unsigned int i = 0, j = 0; j < m_spec.scanline_bytes(); ++i, j+=3) { mscanline[j] = m_colortable[fscanline[i]].r; mscanline[j+1] = m_colortable[fscanline[i]].g; mscanline[j+2] = m_colortable[fscanline[i]].b; } } if (m_dib_header.bpp == 4) { for (unsigned int i = 0, j = 0; j + 6 < m_spec.scanline_bytes(); ++i, j+=6) { uint8_t mask = 0xF0; mscanline[j] = m_colortable[(fscanline[i] & mask) >> 4].r; mscanline[j+1] = m_colortable[(fscanline[i] & mask) >> 4].g; mscanline[j+2] = m_colortable[(fscanline[i] & mask) >> 4].b; mask = 0x0F; mscanline[j+3] = m_colortable[fscanline[i] & mask].r; mscanline[j+4] = m_colortable[fscanline[i] & mask].g; mscanline[j+5] = m_colortable[fscanline[i] & mask].b; } } if (m_dib_header.bpp == 1) { for (unsigned int i = 0, k = 0; i < fscanline.size (); ++i) { for (int j = 7; j >= 0; --j, k+=3) { if (k + 2 >= mscanline.size()) break; int index = 0; if (fscanline[i] & (1 << j)) index = 1; mscanline[k] = m_colortable[index].r; mscanline[k+1] = m_colortable[index].g; mscanline[k+2] = m_colortable[index].b; } } } memcpy (data, &mscanline[0], m_spec.scanline_bytes()); return true; } bool inline BmpInput::close (void) { if (m_fd) { fclose (m_fd); m_fd = NULL; } init (); return true; } bool BmpInput::read_color_table (void) { // size of color table is defined by m_dib_header.cpalete // if this field is 0 - color table has max colors: // pow(2, m_dib_header.cpalete) otherwise color table have // m_dib_header.cpalete entries const int32_t colors = (m_dib_header.cpalete) ? m_dib_header.cpalete : 1 << m_dib_header.bpp; size_t entry_size = 4; // if the file is OS V2 bitmap color table entr has only 3 bytes, not four if (m_dib_header.size == OS2_V1) entry_size = 3; m_colortable.resize (colors); for (int i = 0; i < colors; i++) { size_t n = fread (&m_colortable[i], 1, entry_size, m_fd); if (n != entry_size) { if (feof (m_fd)) error ("Hit end of file unexpectedly while reading color table"); else error ("read error while reading color table"); return false; // Read failed } } return true; // ok } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/bmp.imageio/CMakeLists.txt0000644000175000017500000000007112271062644022035 0ustar mfvmfvadd_oiio_plugin (bmpinput.cpp bmpoutput.cpp bmp_pvt.cpp) openimageio-1.3.12~dfsg0.orig/src/bmp.imageio/bmp_pvt.h0000644000175000017500000001460012271062644021120 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_BMP_H #define OPENIMAGEIO_BMP_H #include #include "imageio.h" #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace bmp_pvt { // size of the BMP file header (the first header that occur in BMP file) const int BMP_HEADER_SIZE = 14; // sizes of various DIB haders const int OS2_V1 = 12; const int WINDOWS_V3 = 40; const int WINDOWS_V4 = 108; // bmp magic numbers const int16_t MAGIC_BM = 0x4D42; const int16_t MAGIC_BA = 0x4142; const int16_t MAGIC_CI = 0x4943; const int16_t MAGIC_CP = 0x5043; const int16_t MAGIC_PT = 0x5450; //const int32_t RLE4_COMPRESSION = 2; // store informations about BMP file class BmpFileHeader { public: // reads informations about BMP file bool read_header (FILE *fd); // writes information about bmp file to given file bool write_header (FILE *fd); // return true if given file is BMP file bool isBmp () const; int16_t magic; // used to identify BMP file int32_t fsize; // size of the BMP file int16_t res1; // reserved int16_t res2; // reserved int32_t offset; //offset of image data private: void swap_endian (void); }; // stores information about bitmap class DibInformationHeader { public: // reads informations about bitmap bool read_header (FILE *fd); // writes informations about bitmap bool write_header (FILE *fd); int32_t size; // size of the header int32_t width; // bitmap width in pixels int32_t height; // bitmap height in pixels int16_t cplanes; // number of color planes - always 1 int16_t bpp; // number of bits per pixel, image color depth int32_t compression; // compression used in file int32_t isize; // size of the raw image data int32_t hres; // horizontal resolution in pixels per meter int32_t vres; // vertical resolutions in pixels per meter int32_t cpalete; // number of entries in the color palete int32_t important; // number of importatn color used, // 0 - all colors are important, // in most cases ignored // added in Version 4 of the format int32_t red_mask; int32_t blue_mask; int32_t green_mask; int32_t alpha_mask; int32_t cs_type; //color space type int32_t red_x; int32_t red_y; int32_t red_z; int32_t green_x; int32_t green_y; int32_t green_z; int32_t blue_x; int32_t blue_y; int32_t blue_z; int32_t gamma_x; int32_t gamma_y; int32_t gamma_z; private: void swap_endian (void); }; struct color_table { uint8_t b; uint8_t g; uint8_t r; uint8_t unused; }; } //namespace bmp_pvt class BmpInput : public ImageInput { public: BmpInput () { init (); } virtual ~BmpInput () { close (); } virtual const char *format_name (void) const { return "bmp"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &spec); virtual bool close (void); virtual bool read_native_scanline (int y, int z, void *data); private: int m_scanline_size; int m_pad_size; FILE *m_fd; bmp_pvt::BmpFileHeader m_bmp_header; bmp_pvt::DibInformationHeader m_dib_header; std::string m_filename; std::vector m_colortable; fpos_t m_image_start; void init (void) { m_scanline_size = 0; m_pad_size = 0; m_fd = NULL; m_filename.clear (); m_colortable.clear (); } bool read_color_table (void); }; class BmpOutput : public ImageOutput { public: BmpOutput () { init (); } virtual ~BmpOutput () { close (); } virtual const char *format_name (void) const { return "bmp"; } virtual bool supports (const std::string &feature) const {return false;} virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode); virtual bool close (void); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: int m_scanline_size; FILE *m_fd; std::string m_filename; bmp_pvt::BmpFileHeader m_bmp_header; bmp_pvt::DibInformationHeader m_dib_header; fpos_t m_image_start; void init (void) { m_scanline_size = 0; m_fd = NULL; m_filename.clear (); } void create_and_write_file_header (void); void create_and_write_bitmap_header (void); }; OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_BMP_H openimageio-1.3.12~dfsg0.orig/src/cmake/0000755000175000017500000000000012271062644016170 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/cmake/modules/0000755000175000017500000000000012271062644017640 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/cmake/modules/FindOpenEXR.cmake0000644000175000017500000001505712271062644022733 0ustar mfvmfv# Module to find OpenEXR. # # This module will first look into the directories defined by the variables: # - OPENEXR_HOME, OPENEXR_VERSION, OPENEXR_LIB_AREA # # It also supports non-standard names for the library components. # # To use a custom OpenEXR # - Set the variable OPENEXR_CUSTOM to True # - Set the variable OPENEXR_CUSTOM_LIBRARY to the name of the library to # use, e.g. "SpiIlmImf" # - Optionally set the variable OPENEXR_CUSTOM_INCLUDE_DIR to any # particularly weird place that the OpenEXR/*.h files may be found # - Optionally set the variable OPENEXR_CUSTOM_LIB_DIR to any # particularly weird place that the libraries files may be found # # This module defines the following variables: # # OPENEXR_INCLUDE_DIR - where to find ImfRgbaFile.h, OpenEXRConfig, etc. # OPENEXR_LIBRARIES - list of libraries to link against when using OpenEXR. # This list does NOT include the IlmBase libraries. # These are defined by the FindIlmBase module. # OPENEXR_FOUND - True if OpenEXR was found. # Other standarnd issue macros include (FindPackageHandleStandardArgs) include (FindPackageMessage) # Macro to assemble a helper state variable macro (SET_STATE_VAR varname) set (tmp_lst ${OPENEXR_CUSTOM} | ${OPENEXR_CUSTOM_LIBRARY} | ${OPENEXR_HOME} | ${OPENEXR_VERSION} | ${OPENEXR_LIB_AREA} ) set (${varname} "${tmp_lst}") unset (tmp_lst) endmacro () # To enforce that find_* functions do not use inadvertently existing versions if (OPENEXR_CUSTOM) set (OPENEXR_FIND_OPTIONS "NO_DEFAULT_PATH") endif () # Macro to search for an include directory macro (PREFIX_FIND_INCLUDE_DIR prefix includefile libpath_var) string (TOUPPER ${prefix}_INCLUDE_DIR tmp_varname) find_path(${tmp_varname} ${includefile} HINTS ${${libpath_var}} PATH_SUFFIXES include ${OPENEXR_FIND_OPTIONS} ) if (${tmp_varname}) mark_as_advanced (${tmp_varname}) endif () unset (tmp_varname) endmacro () # Macro to search for the given library and adds the cached # variable names to the specified list macro (PREFIX_FIND_LIB prefix libname libpath_var liblist_var cachelist_var) string (TOUPPER ${prefix}_${libname} tmp_prefix) find_library(${tmp_prefix}_LIBRARY_RELEASE NAMES ${libname} HINTS ${${libpath_var}} PATH_SUFFIXES lib ${OPENEXR_FIND_OPTIONS} ) find_library(${tmp_prefix}_LIBRARY_DEBUG NAMES ${libname}d ${libname}_d ${libname}debug ${libname}_debug HINTS ${${libpath_var}} PATH_SUFFIXES lib ${OPENEXR_FIND_OPTIONS} ) # Properly define ${tmp_prefix}_LIBRARY (cached) and ${tmp_prefix}_LIBRARIES select_library_configurations (${tmp_prefix}) list (APPEND ${liblist_var} ${tmp_prefix}_LIBRARIES) # Add to the list of variables which should be reset list (APPEND ${cachelist_var} ${tmp_prefix}_LIBRARY ${tmp_prefix}_LIBRARY_RELEASE ${tmp_prefix}_LIBRARY_DEBUG) mark_as_advanced ( ${tmp_prefix}_LIBRARY ${tmp_prefix}_LIBRARY_RELEASE ${tmp_prefix}_LIBRARY_DEBUG) unset (tmp_prefix) endmacro () # Encode the current state of the external variables into a string SET_STATE_VAR (OPENEXR_CURRENT_STATE) # If the state has changed, clear the cached variables if (OPENEXR_CACHED_STATE AND NOT OPENEXR_CACHED_STATE STREQUAL OPENEXR_CURRENT_STATE) foreach (libvar ${OPENEXR_CACHED_VARS}) unset (${libvar} CACHE) endforeach () endif () if (OPENEXR_CUSTOM) if (NOT OPENEXR_CUSTOM_LIBRARY) message (FATAL_ERROR "Custom OpenEXR library requested but OPENEXR_CUSTOM_LIBRARY is not set.") endif() set (OpenEXR_Library ${OPENEXR_CUSTOM_LIBRARY}) else () set (OpenEXR_Library IlmImf) endif () # Generic search paths set (OpenEXR_generic_include_paths ${OPENEXR_CUSTOM_INCLUDE_DIR} /usr/include /usr/local/include /sw/include /opt/local/include) set (OpenEXR_generic_library_paths ${OPENEXR_CUSTOM_LIB_DIR} /usr/lib /usr/local/lib /sw/lib /opt/local/lib) # Search paths for the OpenEXR files if (OPENEXR_HOME) set (OpenEXR_library_paths ${OPENEXR_HOME}/lib ${OPENEXR_HOME}/lib64) if (OPENEXR_VERSION) set (OpenEXR_include_paths ${OPENEXR_HOME}/openexr-${OPENEXR_VERSION}/include ${OPENEXR_HOME}/include/openexr-${OPENEXR_VERSION}) list (APPEND OpenEXR_library_paths ${OPENEXR_HOME}/openexr-${OPENEXR_VERSION}/lib ${OPENEXR_HOME}/lib/openexr-${OPENEXR_VERSION}) endif() list (APPEND OpenEXR_include_paths ${OPENEXR_HOME}/include) if (OPENEXR_LIB_AREA) list (INSERT OpenEXR_library_paths 2 ${OPENEXR_LIB_AREA}) endif () endif () if (ILMBASE_HOME AND OPENEXR_VERSION) list (APPEND OpenEXR_include_paths ${ILMBASE_HOME}/include/openexr-${OPENEXR_VERSION}) endif() list (APPEND OpenEXR_include_paths ${OpenEXR_generic_include_paths}) list (APPEND OpenEXR_library_paths ${OpenEXR_generic_library_paths}) # Locate the header files PREFIX_FIND_INCLUDE_DIR (OpenEXR OpenEXR/ImfArray.h OpenEXR_include_paths) # If the headers were found, add its parent to the list of lib directories if (OPENEXR_INCLUDE_DIR) get_filename_component (tmp_extra_dir "${OPENEXR_INCLUDE_DIR}/../" ABSOLUTE) list (APPEND OpenEXR_library_paths ${tmp_extra_dir}) unset (tmp_extra_dir) endif () # Locate the OpenEXR library set (OpenEXR_libvars "") set (OpenEXR_cachevars "") PREFIX_FIND_LIB (OpenEXR ${OpenEXR_Library} OpenEXR_library_paths OpenEXR_libvars OpenEXR_cachevars) # Create the list of variables that might need to be cleared set (OPENEXR_CACHED_VARS OPENEXR_INCLUDE_DIR ${OpenEXR_cachevars} CACHE INTERNAL "Variables set by FindOpenEXR.cmake" FORCE) # Store the current state so that variables might be cleared if required set (OPENEXR_CACHED_STATE ${OPENEXR_CURRENT_STATE} CACHE INTERNAL "State last seen by FindOpenEXR.cmake" FORCE) # Always link explicitly with zlib set (OPENEXR_ZLIB ${ZLIB_LIBRARIES}) # Use the standard function to handle OPENEXR_FOUND FIND_PACKAGE_HANDLE_STANDARD_ARGS (OpenEXR DEFAULT_MSG OPENEXR_INCLUDE_DIR ${OpenEXR_libvars}) if (OPENEXR_FOUND) set (OPENEXR_LIBRARIES "") foreach (tmplib ${OpenEXR_libvars}) list (APPEND OPENEXR_LIBRARIES ${${tmplib}}) endforeach () list (APPEND OPENEXR_LIBRARIES ${ZLIB_LIBRARIES}) if (VERBOSE) FIND_PACKAGE_MESSAGE (OPENEXR "Found OpenEXR: ${OPENEXR_LIBRARIES}" "[${OPENEXR_INCLUDE_DIR}][${OPENEXR_LIBRARIES}][${OPENEXR_CURRENT_STATE}]" ) endif () endif () # Unset the helper variables to avoid pollution unset (OPENEXR_CURRENT_STATE) unset (OpenEXR_include_paths) unset (OpenEXR_library_paths) unset (OpenEXR_generic_include_paths) unset (OpenEXR_generic_library_paths) unset (OpenEXR_libvars) unset (OpenEXR_cachevars) openimageio-1.3.12~dfsg0.orig/src/cmake/modules/FindPugiXML.cmake0000644000175000017500000000173212271062644022733 0ustar mfvmfv# Find the pugixml XML parsing library. # # Sets the usual variables expected for find_package scripts: # # PUGIXML_INCLUDE_DIR - header location # PUGIXML_LIBRARIES - library to link against # PUGIXML_FOUND - true if pugixml was found. find_path (PUGIXML_INCLUDE_DIR NAMES pugixml.hpp PATHS ${PUGIXML_HOME}/include) find_library (PUGIXML_LIBRARY NAMES pugixml PATHS ${PUGIXML_HOME}/lib) # Support the REQUIRED and QUIET arguments, and set PUGIXML_FOUND if found. include (FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS (PugiXML DEFAULT_MSG PUGIXML_LIBRARY PUGIXML_INCLUDE_DIR) if (PUGIXML_FOUND) set (PUGIXML_LIBRARIES ${PUGIXML_LIBRARY}) message (STATUS "PugiXML include = ${PUGIXML_INCLUDE_DIR}") message (STATUS "PugiXML library = ${PUGIXML_LIBRARY}") else () message (STATUS "No PugiXML found") endif() mark_as_advanced (PUGIXML_LIBRARY PUGIXML_INCLUDE_DIR) openimageio-1.3.12~dfsg0.orig/src/cmake/modules/SelectLibraryConfigurations.cmake0000644000175000017500000000773112271062644026331 0ustar mfvmfv# select_library_configurations( basename ) # # This macro takes a library base name as an argument, and will choose good # values for basename_LIBRARY, basename_LIBRARIES, basename_LIBRARY_DEBUG, and # basename_LIBRARY_RELEASE depending on what has been found and set. If only # basename_LIBRARY_RELEASE is defined, basename_LIBRARY, basename_LIBRARY_DEBUG, # and basename_LIBRARY_RELEASE will be set to the release value. If only # basename_LIBRARY_DEBUG is defined, then basename_LIBRARY, # basename_LIBRARY_DEBUG and basename_LIBRARY_RELEASE will take the debug value. # # If the generator supports configuration types, then basename_LIBRARY and # basename_LIBRARIES will be set with debug and optimized flags specifying the # library to be used for the given configuration. If no build type has been set # or the generator in use does not support configuration types, then # basename_LIBRARY and basename_LIBRARIES will take only the release values. #============================================================================= # Copyright 2009 Kitware, Inc. # Copyright 2009 Will Dicharry # Copyright 2005-2009 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) # This macro was adapted from the FindQt4 CMake module and is maintained by Will # Dicharry . # Utility macro to check if one variable exists while another doesn't, and set # one that doesn't exist to the one that exists. macro( _set_library_name basename GOOD BAD ) if( ${basename}_LIBRARY_${GOOD} AND NOT ${basename}_LIBRARY_${BAD} ) set( ${basename}_LIBRARY_${BAD} ${${basename}_LIBRARY_${GOOD}} ) set( ${basename}_LIBRARY ${${basename}_LIBRARY_${GOOD}} ) set( ${basename}_LIBRARIES ${${basename}_LIBRARY_${GOOD}} ) endif( ${basename}_LIBRARY_${GOOD} AND NOT ${basename}_LIBRARY_${BAD} ) endmacro( _set_library_name ) macro( select_library_configurations basename ) # if only the release version was found, set the debug to be the release # version. _set_library_name( ${basename} RELEASE DEBUG ) # if only the debug version was found, set the release value to be the # debug value. _set_library_name( ${basename} DEBUG RELEASE ) if (${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE ) # if the generator supports configuration types or CMAKE_BUILD_TYPE # is set, then set optimized and debug options. if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) set( ${basename}_LIBRARY optimized ${${basename}_LIBRARY_RELEASE} debug ${${basename}_LIBRARY_DEBUG} ) set( ${basename}_LIBRARIES optimized ${${basename}_LIBRARY_RELEASE} debug ${${basename}_LIBRARY_DEBUG} ) else( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) # If there are no configuration types or build type, just use # the release version set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) set( ${basename}_LIBRARIES ${${basename}_LIBRARY_RELEASE} ) endif( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) endif( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE ) set( ${basename}_LIBRARY ${${basename}_LIBRARY} CACHE FILEPATH "The ${basename} library" ) if( ${basename}_LIBRARY ) set( ${basename}_FOUND TRUE ) endif( ${basename}_LIBRARY ) mark_as_advanced( ${basename}_LIBRARY ${basename}_LIBRARY_RELEASE ${basename}_LIBRARY_DEBUG ) endmacro( select_library_configurations ) openimageio-1.3.12~dfsg0.orig/src/cmake/modules/FindOpenColorIO.cmake0000644000175000017500000000353312271062644023577 0ustar mfvmfv# Module to find OpenColorIO # # This module will first look into the directories defined by the variables: # - OCIO_PATH, OCIO_INCLUDE_PATH, OCIO_LIBRARY_PATH # # This module defines the following variables: # # OCIO_FOUND - True if OpenColorIO was found. # OCIO_INCLUDES - where to find OpenColorIO.h # OCIO_LIBRARIES - list of libraries to link against when using OpenColorIO # Other standarnd issue macros include (FindPackageHandleStandardArgs) include (FindPackageMessage) MACRO(FindOpenColorIO) if (VERBOSE) if (OCIO_PATH) message(STATUS "OCIO path explicitly specified: ${OCIO_PATH}") endif() if (OCIO_INCLUDE_PATH) message(STATUS "OCIO INCLUDE_PATH explicitly specified: ${OCIO_INCLUDE_PATH}") endif() if (OCIO_LIBRARY_PATH) message(STATUS "OCIO LIBRARY_PATH explicitly specified: ${OCIO_LIBRARY_PATH}") endif() endif () FIND_PATH( OCIO_INCLUDES OpenColorIO/OpenColorIO.h ${OCIO_INCLUDE_PATH} ${OCIO_PATH}/include/ /usr/include /usr/local/include /sw/include /opt/local/include DOC "The directory where OpenColorIO/OpenColorIO.h resides") FIND_LIBRARY(OCIO_LIBRARIES NAMES OCIO OpenColorIO PATHS ${OCIO_LIBRARY_PATH} ${OCIO_PATH}/lib/ /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /sw/lib /opt/local/lib DOC "The OCIO library") if(OCIO_INCLUDES AND OCIO_LIBRARIES) set(OCIO_FOUND TRUE) if (VERBOSE) message(STATUS "Found OCIO library ${OCIO_LIBRARIES}") message(STATUS "Found OCIO includes ${OCIO_INCLUDES}") endif () else() set(OCIO_FOUND FALSE) message(STATUS "OCIO not found. Specify OCIO_PATH to locate it") endif() ENDMACRO() openimageio-1.3.12~dfsg0.orig/src/cmake/modules/FindOpenJpeg.cmake0000644000175000017500000000661612271062644023163 0ustar mfvmfv# Module to find OpenJpeg. # # This module will first look into the directories defined by the variables: # - OPENJPEG_HOME # # This module defines the following variables: # # OPENJPEG_INCLUDE_DIR - where to find openjpeg.h # OPENJPEG_LIBRARIES - list of libraries to link against when using OpenJpeg. # OPENJPEG_FOUND - True if OpenJpeg was found. include (FindPackageHandleStandardArgs) include (FindPackageMessage) macro (PREFIX_FIND_INCLUDE_DIR prefix includefile libpath_var) string (TOUPPER ${prefix}_INCLUDE_DIR tmp_varname) find_path(${tmp_varname} ${includefile} PATHS ${${libpath_var}} PATH_SUFFIXES include NO_DEFAULT_PATH ) if (${tmp_varname}) mark_as_advanced (${tmp_varname}) endif () unset (tmp_varname) endmacro () macro (PREFIX_FIND_LIB prefix libname libpath_var liblist_var cachelist_var) string (TOUPPER ${prefix}_${libname} tmp_prefix) find_library(${tmp_prefix}_LIBRARY_RELEASE NAMES ${libname} PATHS ${${libpath_var}} PATH_SUFFIXES lib NO_DEFAULT_PATH ) find_library(${tmp_prefix}_LIBRARY_DEBUG NAMES ${libname}d ${libname}_d ${libname}debug ${libname}_debug PATHS ${${libpath_var}} PATH_SUFFIXES lib NO_DEFAULT_PATH ) # Properly define ${tmp_prefix}_LIBRARY (cached) and ${tmp_prefix}_LIBRARIES select_library_configurations (${tmp_prefix}) list (APPEND ${liblist_var} ${tmp_prefix}_LIBRARIES) # Add to the list of variables which should be reset list (APPEND ${cachelist_var} ${tmp_prefix}_LIBRARY ${tmp_prefix}_LIBRARY_RELEASE ${tmp_prefix}_LIBRARY_DEBUG) mark_as_advanced ( ${tmp_prefix}_LIBRARY ${tmp_prefix}_LIBRARY_RELEASE ${tmp_prefix}_LIBRARY_DEBUG) unset (tmp_prefix) endmacro () # Generic search paths set (OpenJpeg_include_paths /usr/local/include/openjpeg /usr/local/include /usr/include/openjpeg /usr/include/openjpeg-1.5 /usr/local/include/openjpeg-1.5 /usr/include /opt/local/include) set (OpenJpeg_library_paths /usr/lib /usr/local/lib /sw/lib /opt/local/lib) if (OPENJPEG_HOME) set (OpenJpeg_library_paths ${OpenJpeg_library_paths} ${OPENJPEG_HOME}/lib ${OPENJPEG_HOME}/lib64) set (OpenJpeg_include_paths ${OpenJpeg_include_paths} ${OPENJPEG_HOME}/include) endif() # Locate the header files PREFIX_FIND_INCLUDE_DIR (OpenJpeg openjpeg.h OpenJpeg_include_paths) # If the headers were found, add its parent to the list of lib directories if (OPENJPEG_INCLUDE_DIR) get_filename_component (tmp_extra_dir "${OPENJPEG_INCLUDE_DIR}/../" ABSOLUTE) list (APPEND OpenJPEG_library_paths ${tmp_extra_dir}) unset (tmp_extra_dir) endif () # Locate the OpenEXR library set (OpenJpeg_libvars "") set (OpenJpeg_cachevars "") PREFIX_FIND_LIB (OpenJpeg openjpeg OpenJpeg_library_paths OpenJpeg_libvars OpenJpeg_cachevars) # Use the standard function to handle OPENEXR_FOUND FIND_PACKAGE_HANDLE_STANDARD_ARGS (OpenJpeg DEFAULT_MSG OPENJPEG_INCLUDE_DIR ${OpenJpeg_libvars}) if (OPENJPEG_FOUND) set (OPENJPEG_LIBRARIES "") foreach (tmplib ${OpenJpeg_libvars}) list (APPEND OPENJPEG_LIBRARIES ${${tmplib}}) endforeach () if (VERBOSE) FIND_PACKAGE_MESSAGE (OPENJPEG "Found OpenJPEG: ${OPENJPEG_LIBRARIES}" "[${OPENJPEG_INCLUDE_DIR}][${OPENJPEG_LIBRARIES}]" ) endif () endif () unset (OpenJpeg_include_paths) unset (OpenJpeg_library_paths) unset (OpenJpeg_libvars) unset (OpenJpeg_cachevars) openimageio-1.3.12~dfsg0.orig/src/cmake/modules/FindIlmBase.cmake0000644000175000017500000001563412271062644022770 0ustar mfvmfv# Module to find IlmBase # # This module will first look into the directories defined by the variables: # - ILMBASE_HOME, ILMBASE_VERSION, ILMBASE_LIB_AREA # # It also supports non-standard names for the library components. # # To use a custom IlmBase: # - Set the variable ILMBASE_CUSTOM to True # - Set the variable ILMBASE_CUSTOM_LIBRARIES to a list of the libraries to # use, e.g. "SpiImath SpiHalf SpiIlmThread SpiIex" # - Optionally set the variable ILMBASE_CUSTOM_INCLUDE_DIR to any # particularly weird place that the OpenEXR/*.h files may be found # - Optionally set the variable ILMBASE_CUSTOM_LIB_DIR to any # particularly weird place that the libraries files may be found # # This module defines the following variables: # # ILMBASE_INCLUDE_DIR - where to find half.h, IlmBaseConfig.h, etc. # ILMBASE_LIBRARIES - list of libraries to link against when using IlmBase. # ILMBASE_FOUND - True if IlmBase was found. # Other standarnd issue macros include (FindPackageHandleStandardArgs) include (FindPackageMessage) include (SelectLibraryConfigurations) # Macro to assemble a helper state variable macro (SET_STATE_VAR varname) set (tmp_ilmbaselibs ${ILMBASE_CUSTOM_LIBRARIES}) separate_arguments (tmp_ilmbaselibs) set (tmp_lst ${ILMBASE_CUSTOM} | ${tmp_ilmbaselibs} | ${ILMBASE_HOME} | ${ILMBASE_VERSION} | ${ILMBASE_LIB_AREA} ) set (${varname} "${tmp_lst}") unset (tmp_ilmbaselibs) unset (tmp_lst) endmacro () # To enforce that find_* functions do not use inadvertently existing versions if (ILMBASE_CUSTOM) set (ILMBASE_FIND_OPTIONS "NO_DEFAULT_PATH") endif () # Macro to search for an include directory macro (PREFIX_FIND_INCLUDE_DIR prefix includefile libpath_var) string (TOUPPER ${prefix}_INCLUDE_DIR tmp_varname) find_path(${tmp_varname} ${includefile} HINTS ${${libpath_var}} PATH_SUFFIXES include ${ILMBASE_FIND_OPTIONS} ) if (${tmp_varname}) mark_as_advanced (${tmp_varname}) endif () unset (tmp_varname) endmacro () # Macro to search for the given library and adds the cached # variable names to the specified list macro (PREFIX_FIND_LIB prefix libname libpath_var liblist_var cachelist_var) string (TOUPPER ${prefix}_${libname} tmp_prefix) find_library(${tmp_prefix}_LIBRARY_RELEASE NAMES ${libname} HINTS ${${libpath_var}} PATH_SUFFIXES lib ${ILMBASE_FIND_OPTIONS} ) find_library(${tmp_prefix}_LIBRARY_DEBUG NAMES ${libname}d ${libname}_d ${libname}debug ${libname}_debug HINTS ${${libpath_var}} PATH_SUFFIXES lib ${ILMBASE_FIND_OPTIONS} ) # Properly define ${tmp_prefix}_LIBRARY (cached) and ${tmp_prefix}_LIBRARIES select_library_configurations (${tmp_prefix}) list (APPEND ${liblist_var} ${tmp_prefix}_LIBRARIES) # Add to the list of variables which should be reset list (APPEND ${cachelist_var} ${tmp_prefix}_LIBRARY ${tmp_prefix}_LIBRARY_RELEASE ${tmp_prefix}_LIBRARY_DEBUG) mark_as_advanced ( ${tmp_prefix}_LIBRARY ${tmp_prefix}_LIBRARY_RELEASE ${tmp_prefix}_LIBRARY_DEBUG) unset (tmp_prefix) endmacro () # Encode the current state of the external variables into a string SET_STATE_VAR (ILMBASE_CURRENT_STATE) # If the state has changed, clear the cached variables if (ILMBASE_CACHED_STATE AND NOT ILMBASE_CACHED_STATE STREQUAL ILMBASE_CURRENT_STATE) foreach (libvar ${ILMBASE_CACHED_VARS}) unset (${libvar} CACHE) endforeach () endif () if (ILMBASE_CUSTOM) if (NOT ILMBASE_CUSTOM_LIBRARIES) message (FATAL_ERROR "Custom IlmBase libraries requested but ILMBASE_CUSTOM_LIBRARIES is not set.") endif() set (IlmBase_Libraries ${ILMBASE_CUSTOM_LIBRARIES}) separate_arguments(IlmBase_Libraries) else () set (IlmBase_Libraries Half Iex Imath IlmThread) endif () # Generic search paths set (IlmBase_generic_include_paths ${ILMBASE_CUSTOM_INCLUDE_DIR} /usr/include /usr/local/include /sw/include /opt/local/include) set (IlmBase_generic_library_paths ${ILMBASE_CUSTOM_LIB_DIR} /usr/lib /usr/local/lib /sw/lib /opt/local/lib) # Search paths for the IlmBase files if (ILMBASE_HOME) if (ILMBASE_VERSION) set (IlmBase_include_paths ${ILMBASE_HOME}/ilmbase-${ILMBASE_VERSION}/include ${ILMBASE_HOME}/include/ilmbase-${ILMBASE_VERSION}) set (IlmBase_library_paths ${ILMBASE_HOME}/ilmbase-${ILMBASE_VERSION}/lib ${ILMBASE_HOME}/lib/ilmbase-${ILMBASE_VERSION}) endif() list (APPEND IlmBase_include_paths ${ILMBASE_HOME}/include) set (IlmBase_library_paths ${ILMBASE_HOME}/lib ${ILMBASE_HOME}/lib64 ${ILMBASE_LIB_AREA} ${IlmBase_library_paths}) endif () list (APPEND IlmBase_include_paths ${IlmBase_generic_include_paths}) list (APPEND IlmBase_library_paths ${IlmBase_generic_library_paths}) # Locate the header files PREFIX_FIND_INCLUDE_DIR (IlmBase OpenEXR/IlmBaseConfig.h IlmBase_include_paths) # If the headers were found, add its parent to the list of lib directories if (ILMBASE_INCLUDE_DIR) get_filename_component (tmp_extra_dir "${ILMBASE_INCLUDE_DIR}/../" ABSOLUTE) list (APPEND IlmBase_library_paths ${tmp_extra_dir}) unset (tmp_extra_dir) endif () # Locate the IlmBase libraries set (IlmBase_libvars "") set (IlmBase_cachevars "") foreach (ilmbase_lib ${IlmBase_Libraries}) PREFIX_FIND_LIB (IlmBase ${ilmbase_lib} IlmBase_library_paths IlmBase_libvars IlmBase_cachevars) endforeach () # Create the list of variables that might need to be cleared set (ILMBASE_CACHED_VARS ILMBASE_INCLUDE_DIR ${IlmBase_cachevars} CACHE INTERNAL "Variables set by FindIlmBase.cmake" FORCE) # Store the current state so that variables might be cleared if required set (ILMBASE_CACHED_STATE ${ILMBASE_CURRENT_STATE} CACHE INTERNAL "State last seen by FindIlmBase.cmake" FORCE) # Link with pthreads if required if (NOT WIN32 AND EXISTS ${ILMBASE_INCLUDE_DIR}/OpenEXR/IlmBaseConfig.h) file (STRINGS ${ILMBASE_INCLUDE_DIR}/OpenEXR/IlmBaseConfig.h ILMBASE_HAVE_PTHREAD REGEX "^[ \\t]*#define[ \\t]+HAVE_PTHREAD[ \\t]1[ \\t]*\$" ) if (ILMBASE_HAVE_PTHREAD) find_package (Threads) if (CMAKE_USE_PTHREADS_INIT) set (ILMBASE_PTHREADS ${CMAKE_THREAD_LIBS_INIT}) endif () endif () endif () # Use the standard function to handle ILMBASE_FOUND FIND_PACKAGE_HANDLE_STANDARD_ARGS (IlmBase DEFAULT_MSG ILMBASE_INCLUDE_DIR ${IlmBase_libvars}) if (ILMBASE_FOUND) set (ILMBASE_LIBRARIES "") foreach (tmplib ${IlmBase_libvars}) list (APPEND ILMBASE_LIBRARIES ${${tmplib}}) endforeach () list (APPEND ILMBASE_LIBRARIES ${ILMBASE_PTHREADS}) if (VERBOSE) FIND_PACKAGE_MESSAGE (ILMBASE "Found IlmBase: ${ILMBASE_LIBRARIES}" "[${ILMBASE_INCLUDE_DIR}][${ILMBASE_LIBRARIES}][${ILMBASE_CURRENT_STATE}]" ) endif () endif () # Unset the helper variables to avoid pollution unset (ILMBASE_CURRENT_STATE) unset (IlmBase_include_paths) unset (IlmBase_library_paths) unset (IlmBase_generic_include_paths) unset (IlmBase_generic_library_paths) unset (IlmBase_libvars) unset (IlmBase_cachevars) unset (ILMBASE_PTHREADS) openimageio-1.3.12~dfsg0.orig/src/cmake/modules/FindTBB.cmake0000644000175000017500000003157312271062644022063 0ustar mfvmfv# Locate Intel Threading Building Blocks include paths and libraries # FindTBB.cmake can be found at https://code.google.com/p/findtbb/ # Written by Hannes Hofmann # Improvements by Gino van den Bergen , # Florian Uhlig , # Jiri Marsik # The MIT License # # Copyright (c) 2011 Hannes Hofmann # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # GvdB: This module uses the environment variable TBB_ARCH_PLATFORM which defines architecture and compiler. # e.g. "ia32/vc8" or "em64t/cc4.1.0_libc2.4_kernel2.6.16.21" # TBB_ARCH_PLATFORM is set by the build script tbbvars[.bat|.sh|.csh], which can be found # in the TBB installation directory (TBB_INSTALL_DIR). # # GvdB: Mac OS X distribution places libraries directly in lib directory. # # For backwards compatibility, you may explicitely set the CMake variables TBB_ARCHITECTURE and TBB_COMPILER. # TBB_ARCHITECTURE [ ia32 | em64t | itanium ] # which architecture to use # TBB_COMPILER e.g. vc9 or cc3.2.3_libc2.3.2_kernel2.4.21 or cc4.0.1_os10.4.9 # which compiler to use (detected automatically on Windows) # This module respects # TBB_INSTALL_DIR or $ENV{TBB21_INSTALL_DIR} or $ENV{TBB_INSTALL_DIR} # This module defines # TBB_INCLUDE_DIRS, where to find task_scheduler_init.h, etc. # TBB_LIBRARY_DIRS, where to find libtbb, libtbbmalloc # TBB_DEBUG_LIBRARY_DIRS, where to find libtbb_debug, libtbbmalloc_debug # TBB_INSTALL_DIR, the base TBB install directory # TBB_LIBRARIES, the libraries to link against to use TBB. # TBB_DEBUG_LIBRARIES, the libraries to link against to use TBB with debug symbols. # TBB_FOUND, If false, don't try to use TBB. # TBB_INTERFACE_VERSION, as defined in tbb/tbb_stddef.h if (WIN32) # has em64t/vc8 em64t/vc9 # has ia32/vc7.1 ia32/vc8 ia32/vc9 set(_TBB_DEFAULT_INSTALL_DIR "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB") set(_TBB_LIB_NAME "tbb") set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") if (MSVC71) set (_TBB_COMPILER "vc7.1") endif(MSVC71) if (MSVC80) set(_TBB_COMPILER "vc8") endif(MSVC80) if (MSVC90) set(_TBB_COMPILER "vc9") endif(MSVC90) if(MSVC10) set(_TBB_COMPILER "vc10") endif(MSVC10) # Todo: add other Windows compilers such as ICL. set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) endif (WIN32) if (UNIX) if (APPLE) # MAC set(_TBB_DEFAULT_INSTALL_DIR "/Library/Frameworks/Intel_TBB.framework/Versions") # libs: libtbb.dylib, libtbbmalloc.dylib, *_debug set(_TBB_LIB_NAME "tbb") set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") # default flavor on apple: ia32/cc4.0.1_os10.4.9 # Jiri: There is no reason to presume there is only one flavor and # that user's setting of variables should be ignored. if(NOT TBB_COMPILER) set(_TBB_COMPILER "cc4.0.1_os10.4.9") elseif (NOT TBB_COMPILER) set(_TBB_COMPILER ${TBB_COMPILER}) endif(NOT TBB_COMPILER) if(NOT TBB_ARCHITECTURE) set(_TBB_ARCHITECTURE "ia32") elseif(NOT TBB_ARCHITECTURE) set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) endif(NOT TBB_ARCHITECTURE) else (APPLE) # LINUX set(_TBB_DEFAULT_INSTALL_DIR "/opt/intel/tbb" "/usr/local/include" "/usr/include") set(_TBB_LIB_NAME "tbb") set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") # has em64t/cc3.2.3_libc2.3.2_kernel2.4.21 em64t/cc3.3.3_libc2.3.3_kernel2.6.5 em64t/cc3.4.3_libc2.3.4_kernel2.6.9 em64t/cc4.1.0_libc2.4_kernel2.6.16.21 # has ia32/* # has itanium/* set(_TBB_COMPILER ${TBB_COMPILER}) set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) endif (APPLE) endif (UNIX) if (CMAKE_SYSTEM MATCHES "SunOS.*") # SUN # not yet supported # has em64t/cc3.4.3_kernel5.10 # has ia32/* endif (CMAKE_SYSTEM MATCHES "SunOS.*") #-- Clear the public variables set (TBB_FOUND "NO") #-- Find TBB install dir and set ${_TBB_INSTALL_DIR} and cached ${TBB_INSTALL_DIR} # first: use CMake variable TBB_INSTALL_DIR if (TBB_INSTALL_DIR) set (_TBB_INSTALL_DIR ${TBB_INSTALL_DIR}) endif (TBB_INSTALL_DIR) # second: use environment variable if (NOT _TBB_INSTALL_DIR) if (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") set (_TBB_INSTALL_DIR $ENV{TBB_INSTALL_DIR}) endif (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") # Intel recommends setting TBB21_INSTALL_DIR if (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") set (_TBB_INSTALL_DIR $ENV{TBB21_INSTALL_DIR}) endif (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") if (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") set (_TBB_INSTALL_DIR $ENV{TBB22_INSTALL_DIR}) endif (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") if (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") set (_TBB_INSTALL_DIR $ENV{TBB30_INSTALL_DIR}) endif (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") endif (NOT _TBB_INSTALL_DIR) # third: try to find path automatically if (NOT _TBB_INSTALL_DIR) if (_TBB_DEFAULT_INSTALL_DIR) set (_TBB_INSTALL_DIR ${_TBB_DEFAULT_INSTALL_DIR}) endif (_TBB_DEFAULT_INSTALL_DIR) endif (NOT _TBB_INSTALL_DIR) # sanity check if (NOT _TBB_INSTALL_DIR) message ("ERROR: Unable to find Intel TBB install directory. ${_TBB_INSTALL_DIR}") else (NOT _TBB_INSTALL_DIR) # finally: set the cached CMake variable TBB_INSTALL_DIR if (NOT TBB_INSTALL_DIR) set (TBB_INSTALL_DIR ${_TBB_INSTALL_DIR} CACHE PATH "Intel TBB install directory") mark_as_advanced(TBB_INSTALL_DIR) endif (NOT TBB_INSTALL_DIR) #-- A macro to rewrite the paths of the library. This is necessary, because # find_library() always found the em64t/vc9 version of the TBB libs macro(TBB_CORRECT_LIB_DIR var_name) # if (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") string(REPLACE em64t "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) # endif (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") string(REPLACE ia32 "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) string(REPLACE vc7.1 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) string(REPLACE vc8 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) string(REPLACE vc9 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) string(REPLACE vc10 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) endmacro(TBB_CORRECT_LIB_DIR var_content) #-- Look for include directory and set ${TBB_INCLUDE_DIR} set (TBB_INC_SEARCH_DIR ${_TBB_INSTALL_DIR}/include) # Jiri: tbbvars now sets the CPATH environment variable to the directory # containing the headers. find_path(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${TBB_INC_SEARCH_DIR} ENV CPATH ) mark_as_advanced(TBB_INCLUDE_DIR) #-- Look for libraries # GvdB: $ENV{TBB_ARCH_PLATFORM} is set by the build script tbbvars[.bat|.sh|.csh] if (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") set (_TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib/$ENV{TBB_ARCH_PLATFORM} ${_TBB_INSTALL_DIR}/$ENV{TBB_ARCH_PLATFORM}/lib ) endif (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") # Jiri: This block isn't mutually exclusive with the previous one # (hence no else), instead I test if the user really specified # the variables in question. if ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) # HH: deprecated message(STATUS "[Warning] FindTBB.cmake: The use of TBB_ARCHITECTURE and TBB_COMPILER is deprecated and may not be supported in future versions. Please set \$ENV{TBB_ARCH_PLATFORM} (using tbbvars.[bat|csh|sh]).") # Jiri: It doesn't hurt to look in more places, so I store the hints from # ENV{TBB_ARCH_PLATFORM} and the TBB_ARCHITECTURE and TBB_COMPILER # variables and search them both. set (_TBB_LIBRARY_DIR "${_TBB_INSTALL_DIR}/${_TBB_ARCHITECTURE}/${_TBB_COMPILER}/lib" ${_TBB_LIBRARY_DIR}) endif ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) # GvdB: Mac OS X distribution places libraries directly in lib directory. list(APPEND _TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib) # Jiri: No reason not to check the default paths. From recent versions, # tbbvars has started exporting the LIBRARY_PATH and LD_LIBRARY_PATH # variables, which now point to the directories of the lib files. # It all makes more sense to use the ${_TBB_LIBRARY_DIR} as a HINTS # argument instead of the implicit PATHS as it isn't hard-coded # but computed by system introspection. Searching the LIBRARY_PATH # and LD_LIBRARY_PATH environment variables is now even more important # that tbbvars doesn't export TBB_ARCH_PLATFORM and it facilitates # the use of TBB built from sources. find_library(TBB_LIBRARY ${_TBB_LIB_NAME} HINTS ${_TBB_LIBRARY_DIR} PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) find_library(TBB_MALLOC_LIBRARY ${_TBB_LIB_MALLOC_NAME} HINTS ${_TBB_LIBRARY_DIR} PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) #Extract path from TBB_LIBRARY name get_filename_component(TBB_LIBRARY_DIR ${TBB_LIBRARY} PATH) #TBB_CORRECT_LIB_DIR(TBB_LIBRARY) #TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY) mark_as_advanced(TBB_LIBRARY TBB_MALLOC_LIBRARY) #-- Look for debug libraries # Jiri: Changed the same way as for the release libraries. find_library(TBB_LIBRARY_DEBUG ${_TBB_LIB_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) find_library(TBB_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_MALLOC_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) # Jiri: Self-built TBB stores the debug libraries in a separate directory. # Extract path from TBB_LIBRARY_DEBUG name get_filename_component(TBB_LIBRARY_DEBUG_DIR ${TBB_LIBRARY_DEBUG} PATH) #TBB_CORRECT_LIB_DIR(TBB_LIBRARY_DEBUG) #TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY_DEBUG) mark_as_advanced(TBB_LIBRARY_DEBUG TBB_MALLOC_LIBRARY_DEBUG) if (TBB_INCLUDE_DIR) if (TBB_LIBRARY) set (TBB_FOUND "YES") set (TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY} ${TBB_LIBRARIES}) set (TBB_DEBUG_LIBRARIES ${TBB_LIBRARY_DEBUG} ${TBB_MALLOC_LIBRARY_DEBUG} ${TBB_DEBUG_LIBRARIES}) set (TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR} CACHE PATH "TBB include directory" FORCE) set (TBB_LIBRARY_DIRS ${TBB_LIBRARY_DIR} CACHE PATH "TBB library directory" FORCE) # Jiri: Self-built TBB stores the debug libraries in a separate directory. set (TBB_DEBUG_LIBRARY_DIRS ${TBB_LIBRARY_DEBUG_DIR} CACHE PATH "TBB debug library directory" FORCE) mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARY_DIRS TBB_DEBUG_LIBRARY_DIRS TBB_LIBRARIES TBB_DEBUG_LIBRARIES) message(STATUS "Found Intel TBB") endif (TBB_LIBRARY) endif (TBB_INCLUDE_DIR) if (NOT TBB_FOUND) message("ERROR: Intel TBB NOT found!") message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}") # do only throw fatal, if this pkg is REQUIRED if (TBB_FIND_REQUIRED) message(FATAL_ERROR "Could NOT find TBB library.") endif (TBB_FIND_REQUIRED) endif (NOT TBB_FOUND) endif (NOT _TBB_INSTALL_DIR) if (TBB_FOUND) set(TBB_INTERFACE_VERSION 0) FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS) STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}") set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}") endif (TBB_FOUND) openimageio-1.3.12~dfsg0.orig/src/cmake/platform.cmake0000644000175000017500000000267212271062644021025 0ustar mfvmfv########################################################################### # Figure out what platform we're on, and set some variables appropriately if (VERBOSE) message (STATUS "CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}") message (STATUS "CMAKE_SYSTEM_VERSION = ${CMAKE_SYSTEM_VERSION}") message (STATUS "CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}") endif () if (UNIX) if (VERBOSE) message (STATUS "Unix! ${CMAKE_SYSTEM_NAME}") endif () if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set (platform "linux") set (CXXFLAGS "${CXXFLAGS} -DLINUX") if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64") set (platform "linux64") set (CXXFLAGS "${CXXFLAGS} -DLINUX64") endif () elseif (APPLE) set (platform "macosx") elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") set (platform "FreeBSD") set (CXXFLAGS "${CXXFLAGS} -DFREEBSD") if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386") # to use gcc atomics we need cpu instructions only available # with arch of i586 or higher set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i586") endif() else () string (TOLOWER ${CMAKE_SYSTEM_NAME} platform) endif () endif () if (WIN32) set (platform "windows") endif () if (platform) message (STATUS "platform = ${platform}") else () message (FATAL_ERROR "'platform' not defined") endif () openimageio-1.3.12~dfsg0.orig/src/cmake/externalpackages.cmake0000644000175000017500000003755612271062644022533 0ustar mfvmfv########################################################################### # Find libraries setup_path (THIRD_PARTY_TOOLS_HOME # "${PROJECT_SOURCE_DIR}/../external/dist/${platform}" "unknown" "Location of third party libraries in the external project") # Add all third party tool directories to the include and library paths so # that they'll be correctly found by the various FIND_PACKAGE() invocations. if (THIRD_PARTY_TOOLS_HOME AND EXISTS "${THIRD_PARTY_TOOLS_HOME}") set (CMAKE_INCLUDE_PATH "${THIRD_PARTY_TOOLS_HOME}/include" ${CMAKE_INCLUDE_PATH}) # Detect third party tools which have been successfully built using the # lock files which are placed there by the external project Makefile. file (GLOB _external_dir_lockfiles "${THIRD_PARTY_TOOLS_HOME}/*.d") foreach (_dir_lockfile ${_external_dir_lockfiles}) # Grab the tool directory_name.d get_filename_component (_ext_dirname ${_dir_lockfile} NAME) # Strip off the .d extension string (REGEX REPLACE "\\.d$" "" _ext_dirname ${_ext_dirname}) set (CMAKE_INCLUDE_PATH "${THIRD_PARTY_TOOLS_HOME}/include/${_ext_dirname}" ${CMAKE_INCLUDE_PATH}) set (CMAKE_LIBRARY_PATH "${THIRD_PARTY_TOOLS_HOME}/lib/${_ext_dirname}" ${CMAKE_LIBRARY_PATH}) endforeach () endif () setup_string (SPECIAL_COMPILE_FLAGS "" "Custom compilation flags") if (SPECIAL_COMPILE_FLAGS) add_definitions (${SPECIAL_COMPILE_FLAGS}) endif () ########################################################################### # IlmBase setup find_package (IlmBase REQUIRED) include_directories ("${ILMBASE_INCLUDE_DIR}") include_directories ("${ILMBASE_INCLUDE_DIR}/OpenEXR") macro (LINK_ILMBASE target) target_link_libraries (${target} ${ILMBASE_LIBRARIES}) endmacro () # end IlmBase setup ########################################################################### ########################################################################### # OpenEXR setup find_package (OpenEXR REQUIRED) if (EXISTS "${OPENEXR_INCLUDE_DIR}/OpenEXR/ImfMultiPartInputFile.h") add_definitions (-DUSE_OPENEXR_VERSION2=1) setup_string (OPENEXR_VERSION 2.0.0 "OpenEXR version number") if (VERBOSE) message (STATUS "OpenEXR version 2.x") endif () else () setup_string (OPENEXR_VERSION 1.6.1 "OpenEXR version number") if (VERBOSE) message (STATUS "OpenEXR version 1.x") endif () endif () mark_as_advanced (OPENEXR_VERSION) include_directories ("${OPENEXR_INCLUDE_DIR}") include_directories ("${OPENEXR_INCLUDE_DIR}/OpenEXR") macro (LINK_OPENEXR target) target_link_libraries (${target} ${OPENEXR_LIBRARIES}) endmacro () # OpenEXR setup ########################################################################### ########################################################################### # Boost setup message (STATUS "BOOST_ROOT ${BOOST_ROOT}") if (NOT DEFINED Boost_ADDITIONAL_VERSIONS) set (Boost_ADDITIONAL_VERSIONS "1.54" "1.53" "1.52" "1.51" "1.50" "1.49" "1.48" "1.47" "1.46" "1.45" "1.44" "1.43" "1.43.0" "1.42" "1.42.0") endif () if (LINKSTATIC) set (Boost_USE_STATIC_LIBS ON) endif () set (Boost_USE_MULTITHREADED ON) if (BOOST_CUSTOM) set (Boost_FOUND true) # N.B. For a custom version, the caller had better set up the variables # Boost_VERSION, Boost_INCLUDE_DIRS, Boost_LIBRARY_DIRS, Boost_LIBRARIES. else () set (Boost_COMPONENTS filesystem regex system thread) find_package (Boost 1.42 REQUIRED COMPONENTS ${Boost_COMPONENTS} ) # Try to figure out if this boost distro has Boost::python. If we # include python in the component list above, cmake will abort if # it's not found. So we resort to checking for the boost_python # library's existance to get a soft failure. find_library (oiio_boost_python_lib boost_python PATHS ${Boost_LIBRARY_DIRS} NO_DEFAULT_PATH) mark_as_advanced (oiio_boost_python_lib) if (NOT oiio_boost_python_lib AND Boost_SYSTEM_LIBRARY_RELEASE) get_filename_component (oiio_boost_PYTHON_rel ${Boost_SYSTEM_LIBRARY_RELEASE} NAME ) string (REGEX REPLACE "^(lib)?(.+)_system(.+)$" "\\2_python\\3" oiio_boost_PYTHON_rel ${oiio_boost_PYTHON_rel} ) find_library (oiio_boost_PYTHON_LIBRARY_RELEASE NAMES ${oiio_boost_PYTHON_rel} lib${oiio_boost_PYTHON_rel} HINTS ${Boost_LIBRARY_DIRS} NO_DEFAULT_PATH ) mark_as_advanced (oiio_boost_PYTHON_LIBRARY_RELEASE) endif () if (NOT oiio_boost_python_lib AND Boost_SYSTEM_LIBRARY_DEBUG) get_filename_component (oiio_boost_PYTHON_dbg ${Boost_SYSTEM_LIBRARY_DEBUG} NAME ) string (REGEX REPLACE "^(lib)?(.+)_system(.+)$" "\\2_python\\3" oiio_boost_PYTHON_dbg ${oiio_boost_PYTHON_dbg} ) find_library (oiio_boost_PYTHON_LIBRARY_DEBUG NAMES ${oiio_boost_PYTHON_dbg} lib${oiio_boost_PYTHON_dbg} HINTS ${Boost_LIBRARY_DIRS} NO_DEFAULT_PATH ) mark_as_advanced (oiio_boost_PYTHON_LIBRARY_DEBUG) endif () if (oiio_boost_python_lib OR oiio_boost_PYTHON_LIBRARY_RELEASE OR oiio_boost_PYTHON_LIBRARY_DEBUG) set (oiio_boost_PYTHON_FOUND ON) else () set (oiio_boost_PYTHON_FOUND OFF) endif () endif () if (VERBOSE) message (STATUS "BOOST_ROOT ${BOOST_ROOT}") message (STATUS "Boost found ${Boost_FOUND} ") message (STATUS "Boost version ${Boost_VERSION}") message (STATUS "Boost include dirs ${Boost_INCLUDE_DIRS}") message (STATUS "Boost library dirs ${Boost_LIBRARY_DIRS}") message (STATUS "Boost libraries ${Boost_LIBRARIES}") message (STATUS "Boost_python_FOUND ${oiio_boost_PYTHON_FOUND}") endif () if (NOT oiio_boost_PYTHON_FOUND) # If Boost python components were not found, turn off all python support. message (STATUS "Boost python support not found -- will not build python components!") if (APPLE AND USE_PYTHON) message (STATUS " If your Boost is from Macports, you need the +python26 variant to get Python support.") endif () set (USE_PYTHON OFF) set (PYTHONLIBS_FOUND OFF) endif () include_directories (SYSTEM "${Boost_INCLUDE_DIRS}") link_directories ("${Boost_LIBRARY_DIRS}") # end Boost setup ########################################################################### ########################################################################### # OpenGL setup if (USE_OPENGL) find_package (OpenGL) endif () message (STATUS "OPENGL_FOUND=${OPENGL_FOUND} USE_OPENGL=${USE_OPENGL}") # end OpenGL setup ########################################################################### ########################################################################### # OpenColorIO Setup if (USE_OCIO) # If 'OCIO_PATH' not set, use the env variable of that name if available if (NOT OCIO_PATH) if (NOT $ENV{OCIO_PATH} STREQUAL "") set (OCIO_PATH $ENV{OCIO_PATH}) endif () endif() find_package (OpenColorIO) FindOpenColorIO () if (OCIO_FOUND) message (STATUS "OpenColorIO enabled") if (VERBOSE) message(STATUS "OCIO_INCLUDES: ${OCIO_INCLUDES}") endif () include_directories (${OCIO_INCLUDES}) add_definitions ("-DUSE_OCIO=1") else () message (STATUS "Skipping OpenColorIO support") endif () else () message (STATUS "OpenColorIO disabled") endif () # end OpenColorIO setup ########################################################################### ########################################################################### # Qt setup if (USE_QT) if (USE_OPENGL) set (QT_USE_QTOPENGL true) endif () find_package (Qt4) endif () if (USE_QT AND QT4_FOUND) if (VERBOSE) message (STATUS "QT4_FOUND=${QT4_FOUND}") message (STATUS "QT_INCLUDES=${QT_INCLUDES}") message (STATUS "QT_LIBRARIES=${QT_LIBRARIES}") endif () else () message (STATUS "No Qt4 -- skipping components that need Qt4.") endif () # end Qt setup ########################################################################### ########################################################################### # GL Extension Wrangler library setup if (USE_OPENGL) set (GLEW_VERSION 1.5.1) find_library (GLEW_LIBRARIES NAMES GLEW glew32) find_path (GLEW_INCLUDES NAMES glew.h PATH_SUFFIXES GL) if (GLEW_INCLUDES AND GLEW_LIBRARIES) set (GLEW_FOUND TRUE) if (VERBOSE) message (STATUS "GLEW includes = ${GLEW_INCLUDES}") message (STATUS "GLEW library = ${GLEW_LIBRARIES}") endif () else () message (STATUS "GLEW not found") endif () else () message (STATUS "USE_OPENGL=0, skipping components that need OpenGL") endif (USE_OPENGL) # end GL Extension Wrangler library setup ########################################################################### ########################################################################### # Field3d if (USE_FIELD3D) if (HDF5_CUSTOM) if (VERBOSE) message (STATUS "Using custom HDF5") endif () set (HDF5_FOUND true) # N.B. For a custom version, the caller had better set up the # variables HDF5_INCLUDE_DIRS and HDF5_LIBRARIES. else () find_library (HDF5_LIBRARY NAMES hdf5 PATHS "${THIRD_PARTY_TOOLS_HOME}/lib/" /usr/local/lib /opt/local/lib ) if (HDF5_LIBRARY) set (HDF5_FOUND true) endif () endif () if (VERBOSE) message (STATUS "HDF5_FOUND=${HDF5_FOUND}") message (STATUS "HDF5_LIBRARY=${HDF5_LIBRARY}") endif () endif () if (USE_FIELD3D AND HDF5_FOUND) if (VERBOSE) message (STATUS "FIELD3D_HOME=${FIELD3D_HOME}") endif () if (FIELD3D_HOME) set (FIELD3D_INCLUDES "${FIELD3D_HOME}/include") else () find_path (FIELD3D_INCLUDES Field3D/Field.h "${THIRD_PARTY_TOOLS}/include" "${PROJECT_SOURCE_DIR}/src/include" "${FIELD3D_HOME}/include" ) endif () find_library (FIELD3D_LIBRARY NAMES Field3D PATHS "${THIRD_PARTY_TOOLS_HOME}/lib/" "${FIELD3D_HOME}/lib" ) if (FIELD3D_INCLUDES AND FIELD3D_LIBRARY) set (FIELD3D_FOUND TRUE) if (VERBOSE) message (STATUS "Field3D includes = ${FIELD3D_INCLUDES}") message (STATUS "Field3D library = ${FIELD3D_LIBRARY}") endif () add_definitions ("-DUSE_FIELD3D=1") include_directories ("${FIELD3D_INCLUDES}") else () message (STATUS "Field3D not found") add_definitions ("-UUSE_FIELD3D") set (FIELD3D_FOUND FALSE) endif () else () add_definitions ("-UUSE_FIELD3D") message (STATUS "Field3d will not be used") endif () # end Field3d setup ########################################################################### # OpenJpeg if (USE_OPENJPEG) find_package (OpenJpeg) endif() # end OpenJpeg setup_path ########################################################################### # WebP setup if (VERBOSE) message (STATUS "WEBP_HOME=${WEBP_HOME}") endif () find_path (WEBP_INCLUDE_DIR webp/encode.h "${THIRD_PARTY_TOOLS}/include" "${PROJECT_SOURCE_DIR}/src/include" "${WEBP_HOME}") find_library (WEBP_LIBRARY NAMES webp PATHS "${THIRD_PARTY_TOOLS_HOME}/lib/" "${WEBP_HOME}" ) if (WEBP_INCLUDE_DIR AND WEBP_LIBRARY) set (WEBP_FOUND TRUE) if (VERBOSE) message (STATUS "WEBP includes = ${WEBP_INCLUDE_DIR} ") message (STATUS "WEBP library = ${WEBP_LIBRARY} ") endif () else() set (WEBP_FOUND FALSE) message (STATUS "WebP library not found") endif() # end Webp setup ########################################################################### ########################################################################### # Pugixml setup. Normally we just use the version bundled with oiio, but # some linux distros are quite particular about having separate packages so we # allow this to be overridden to use the distro-provided package if desired. if (USE_EXTERNAL_PUGIXML) find_package (PugiXML REQUIRED) # insert include path to pugixml first, to ensure that the external # pugixml is found, and not the one in OIIO's include directory. include_directories (BEFORE ${PUGIXML_INCLUDE_DIR}) endif() ########################################################################### # OpenCV setup if (USE_OPENCV) find_path (OpenCV_INCLUDE_DIR opencv/cv.h "${THIRD_PARTY_TOOLS}/include" "${PROJECT_SOURCE_DIR}/include" "${OpenCV_HOME}/include" /usr/local/include /opt/local/include ) find_library (OpenCV_LIBS NAMES opencv_core PATHS "${THIRD_PARTY_TOOLS_HOME}/lib/" "${PROJECT_SOURCE_DIR}/lib" "${OpenCV_HOME}/lib" /usr/local/lib /opt/local/lib ) find_library (OpenCV_LIBS_highgui NAMES opencv_highgui PATHS "${THIRD_PARTY_TOOLS_HOME}/lib/" "${PROJECT_SOURCE_DIR}/lib" "${OpenCV_HOME}/lib" /usr/local/lib /opt/local/lib ) set (OpenCV_LIBS "${OpenCV_LIBS} ${OpenCV_LIBS_highgui}") if (OpenCV_INCLUDE_DIR AND OpenCV_LIBS) set (OpenCV_FOUND TRUE) add_definitions ("-DUSE_OPENCV") if (VERBOSE) message (STATUS "OpenCV includes = ${OpenCV_INCLUDE_DIR} ") message (STATUS "OpenCV libs = ${OpenCV_LIBS} ") endif () else () set (OpenCV_FOUND FALSE) message (STATUS "OpenCV library not found") endif () else () message (STATUS "Not using OpenCV") endif () # end OpenCV setup ########################################################################### ########################################################################### # Freetype setup if (USE_FREETYPE) find_package (Freetype) if (FREETYPE_FOUND) add_definitions ("-DUSE_FREETYPE") if (VERBOSE) message (STATUS "Freetype includes = ${FREETYPE_INCLUDE_DIRS} ") message (STATUS "Freetype libs = ${FREETYPE_LIBRARIES} ") endif () else () message (STATUS "Freetype library not found") endif () else () message (STATUS "Not using Freetype") endif () # end Freetype setup ########################################################################### ########################################################################### # OpenSSL Setup if (USE_OPENSSL) find_package (OpenSSL) if (OPENSSL_FOUND) message (STATUS "OpenSSL enabled") if (VERBOSE) message(STATUS "OPENSSL_INCLUDES: ${OPENSSL_INCLUDE_DIR}") endif () include_directories (${OPENSSL_INCLUDE_DIR}) add_definitions ("-DUSE_OPENSSL=1") else () message (STATUS "Skipping OpenSSL support") endif () else () message (STATUS "OpenSSL disabled") endif () # end OpenSSL setup ########################################################################### ########################################################################### # GIF if (USE_GIF) find_package (GIF) endif() # end GIF setup_path ########################################################################### openimageio-1.3.12~dfsg0.orig/src/cmake/util_macros.cmake0000644000175000017500000001002612271062644021512 0ustar mfvmfv# The PARSE_ARGUMENTS macro will take the arguments of another macro and define # several variables. The first argument to PARSE_ARGUMENTS is a prefix to put # on all variables it creates. The second argument is a list of names, and the # third argument is a list of options. Both of these lists should be quoted. # The rest of the PARSE_ARGUMENTS args are arguments from another macro to be # parsed. # # PARSE_ARGUMENTS(prefix arg_names options arg1 arg2...) # # For each item in options, PARSE_ARGUMENTS will create a variable with that # name, prefixed with prefix_. So, for example, if prefix is MY_MACRO and # options is OPTION1;OPTION2, then PARSE_ARGUMENTS will create the variables # MY_MACRO_OPTION1 and MY_MACRO_OPTION2. These variables will be set to true if # the option exists in the command line or false otherwise. # # For each item in arg_names, PARSE_ARGUMENTS will create a variable with that # name, prefixed with prefix_. Each variable will be filled with the arguments # that occur after the given arg_name is encountered up to the next arg_name or # the end of the arguments. All options are removed from these lists. # PARSE_ARGUMENTS also creates a prefix_DEFAULT_ARGS variable containing the # list of all arguments up to the first arg_name encountered. # # Downloaded from: http://www.itk.org/Wiki/CMakeMacroParseArguments # MACRO(PARSE_ARGUMENTS prefix arg_names option_names) SET(DEFAULT_ARGS) FOREACH(arg_name ${arg_names}) SET(${prefix}_${arg_name}) ENDFOREACH(arg_name) FOREACH(option ${option_names}) SET(${prefix}_${option} FALSE) ENDFOREACH(option) SET(current_arg_name DEFAULT_ARGS) SET(current_arg_list) FOREACH(arg ${ARGN}) SET(larg_names ${arg_names}) LIST(FIND larg_names "${arg}" is_arg_name) IF (is_arg_name GREATER -1) SET(${prefix}_${current_arg_name} ${current_arg_list}) SET(current_arg_name ${arg}) SET(current_arg_list) ELSE (is_arg_name GREATER -1) SET(loption_names ${option_names}) LIST(FIND loption_names "${arg}" is_option) IF (is_option GREATER -1) SET(${prefix}_${arg} TRUE) ELSE (is_option GREATER -1) SET(current_arg_list ${current_arg_list} ${arg}) ENDIF (is_option GREATER -1) ENDIF (is_arg_name GREATER -1) ENDFOREACH(arg) SET(${prefix}_${current_arg_name} ${current_arg_list}) ENDMACRO(PARSE_ARGUMENTS) # Macro to set a variable with our funny overrides: # If the variable is already set (by -D on the command line), leave it alone. # If an environment variable of the same name is set, use that value # (making it super easy for sites to override external tool locations). # If neither of those, then use the default passed. macro (setup_string name defaultval explanation) # If the named variable already has a value (was set by -D...), leave # it alone. But if it's not yet set... if ("${${name}}" STREQUAL "") # If there's an environment variable of the same name that's # nonempty, use the env variable. Otherwise, use the default. if (NOT $ENV{${name}} STREQUAL "") set (${name} $ENV{${name}} CACHE STRING ${explanation}) else () set (${name} ${defaultval} CACHE STRING ${explanation}) endif () endif () if (VERBOSE) message (STATUS "${name} = ${${name}}") endif () endmacro () macro (setup_path name defaultval explanation) # If the named variable already has a value (was set by -D...), leave # it alone. But if it's not yet set... if ("${${name}}" STREQUAL "") # If there's an environment variable of the same name that's # nonempty, use the env variable. Otherwise, use the default. if (NOT $ENV{${name}} STREQUAL "") set (${name} $ENV{${name}}) # CACHE PATH ${explanation}) else () set (${name} ${defaultval}) # CACHE PATH ${explanation}) endif () endif () if (VERBOSE) message (STATUS "${name} = ${${name}}") endif () endmacro () openimageio-1.3.12~dfsg0.orig/src/cmake/oiio_macros.cmake0000644000175000017500000001255412271062644021504 0ustar mfvmfv# Macro to install targets to the appropriate locations. Use this instead of # the install(TARGETS ...) signature. # # Usage: # # oiio_install_targets (target1 [target2 ...]) # macro (oiio_install_targets) install (TARGETS ${ARGN} RUNTIME DESTINATION "${BIN_INSTALL_DIR}" COMPONENT user LIBRARY DESTINATION "${LIB_INSTALL_DIR}" COMPONENT user ARCHIVE DESTINATION "${LIB_INSTALL_DIR}" COMPONENT developer) endmacro () # Macro to add a build target for an IO plugin. # # Usage: # # add_oiio_plugin ( source1 [source2 ...] # [LINK_LIBRARIES external_lib1 ...] ) # # The plugin name is deduced from the name of the current directory and the # source is automatically linked against OpenImageIO. Additional libraries # (for example, libpng) may be specified after the optionl LINK_LIBRARIES # keyword. # macro (add_oiio_plugin) parse_arguments (_plugin "LINK_LIBRARIES" "" ${ARGN}) set (_target_name ${CMAKE_CURRENT_SOURCE_DIR}) # Get the name of the current directory and use it as the target name. get_filename_component (_target_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) add_library (${_target_name} SHARED ${_plugin_DEFAULT_ARGS}) target_link_libraries (${_target_name} OpenImageIO ${_plugin_LINK_LIBRARIES}) set_target_properties (${_target_name} PROPERTIES PREFIX "" FOLDER "Plugins") oiio_install_targets (${_target_name}) endmacro () # Macro that adds DLL to the installer created by NSIS generator # # Usage: # # add_dll_fils () # macro (add_dll_files) install (FILES "${Boost_LIBRARY_DIRS}/boost_date_time-vc90-mt-1_38.dll" "${Boost_LIBRARY_DIRS}/boost_filesystem-vc90-mt-1_38.dll" "${Boost_LIBRARY_DIRS}/boost_regex-vc90-mt-1_38.dll" "${Boost_LIBRARY_DIRS}/boost_system-vc90-mt-1_38.dll" "${Boost_LIBRARY_DIRS}/boost_thread-vc90-mt-1_38.dll" "${QT_BINARY_DIR}/QtCore4.dll" "${QT_BINARY_DIR}/QtGui4.dll" "${QT_BINARY_DIR}/QtOpenGL4.dll" "${ILMBASE_HOME}/ilmbase-${ILMBASE_VERSION}/lib/Imath.dll" "${ILMBASE_HOME}/ilmbase-${ILMBASE_VERSION}/lib/Half.dll" "${ILMBASE_HOME}/ilmbase-${ILMBASE_VERSION}/lib/IlmThread.dll" "${ILMBASE_HOME}/ilmbase-${ILMBASE_VERSION}/lib/Iex.dll" "${OPENEXR_HOME}/openexr-${OPENEXR_VERSION}/lib/IlmImf.dll" "${ZLIB_INCLUDE_DIR}/../lib/zlib1.dll" "${PNG_PNG_INCLUDE_DIR}/../lib/libpng13.dll" "${TIFF_INCLUDE_DIR}/../lib/libtiff.dll" "${GLEW_INCLUDES}/../lib/glew32.dll" DESTINATION bin COMPONENT user) endmacro () # oiio_add_tests() - add a set of test cases. # # Usage: # oiio_add_tests ( test1 [ test2 ... ] # [ IMAGEDIR name_of_reference_image_directory ] # [ URL http://find.reference.cases.here.com ] ) # # The optional argument IMAGEDIR is used to check whether external test images # (not supplied with OIIO) are present, and to disable the test cases if # they're not. If IMAGEDIR is present, URL should also be included to tell # the user where to find such tests. # macro (oiio_add_tests) parse_arguments (_ats "URL;IMAGEDIR;LABEL;FOUNDVAR" "" ${ARGN}) set (_ats_testdir "${PROJECT_SOURCE_DIR}/../${_ats_IMAGEDIR}") # If there was a FOUNDVAR param specified and that variable name is # not defined, mark the test as broken. if (_ats_FOUNDVAR AND NOT ${_ats_FOUNDVAR}) set (_ats_LABEL "broken") endif () if (_ats_IMAGEDIR AND NOT EXISTS ${_ats_testdir}) # If the directory containig reference data (images) for the test # isn't found, point the user at the URL. message (STATUS "\n\nDid not find ${_ats_testdir}") message (STATUS " -> Will not run tests ${_ats_DEFAULT_ARGS}") message (STATUS " -> You can find it at ${_ats_URL}\n") else () # Add the tests if all is well. if (DEFINED CMAKE_VERSION AND NOT CMAKE_VERSION VERSION_LESS 2.8) set (_has_generator_expr TRUE) endif () foreach (_testname ${_ats_DEFAULT_ARGS}) set (_testdir "${CMAKE_BINARY_DIR}/testsuite/${_testname}") if (_ats_LABEL MATCHES "broken") set (_testname "${_testname}-broken") endif () if (_has_generator_expr) set (_add_test_args NAME ${_testname} # WORKING_DIRECTORY ${_testdir} COMMAND python) if (MSVC_IDE) set (_extra_test_args --devenv-config $ --solution-path "${PROJECT_BINARY_DIR}" ) else () set (_extra_test_args "") endif () else () set (_add_test_args ${_testname} python) set (_extra_test_args "") endif () if (VERBOSE) message (STATUS "TEST ${_testname}: ${CMAKE_BINARY_DIR}/testsuite/runtest.py ${_testdir} ${_extra_test_args}") endif () add_test (${_add_test_args} "${CMAKE_BINARY_DIR}/testsuite/runtest.py" ${_testdir} ${_extra_test_args}) endforeach () endif () endmacro () openimageio-1.3.12~dfsg0.orig/src/jpeg2000.imageio/0000755000175000017500000000000012271062644017750 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/jpeg2000.imageio/jpeg2000output.cpp0000644000175000017500000003250612271062644023172 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include "openjpeg.h" #include "filesystem.h" #include "fmath.h" #include "imageio.h" OIIO_PLUGIN_NAMESPACE_BEGIN static void openjpeg_dummy_callback(const char*, void*) {} class Jpeg2000Output : public ImageOutput { public: Jpeg2000Output () { init (); } virtual ~Jpeg2000Output () { close (); } virtual const char *format_name (void) const { return "jpeg2000"; } virtual bool supports (const std::string &feature) const { return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: std::string m_filename; FILE *m_file; opj_cparameters_t m_compression_parameters; opj_image_t *m_image; void init (void) { m_file = NULL; m_image = NULL; } opj_image_t* create_jpeg2000_image(); void init_components(opj_image_cmptparm_t *components, int precision); opj_cinfo_t* create_compressor(); bool save_image(); uint16_t write_pixel(int p_nativePrecision, int p_pixelData); template void write_scanline(int y, int z, const void *data); void setup_cinema_compression(OPJ_RSIZ_CAPABILITIES p_rsizCap); void setup_compression_params(); OPJ_PROG_ORDER get_progression_order(const std::string& progression_order); }; // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *jpeg2000_output_imageio_create () { return new Jpeg2000Output; } OIIO_EXPORT const char *jpeg2000_output_extensions[] = { "jp2", "j2k", NULL }; OIIO_PLUGIN_EXPORTS_END bool Jpeg2000Output::open (const std::string &name, const ImageSpec &spec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } m_filename = name; m_spec = spec; // If not uint8 or uint16, default to uint8 if (m_spec.format != TypeDesc::UINT8 && m_spec.format != TypeDesc::UINT16) m_spec.set_format (TypeDesc::UINT8); m_file = Filesystem::fopen (m_filename, "wb"); if (m_file == NULL) { error ("Unable to open file \"%s\"", m_filename.c_str()); return false; } m_image = create_jpeg2000_image(); return true; } bool Jpeg2000Output::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { if (y > m_spec.height) { error ("Attempt to write too many scanlines to %s", m_filename.c_str()); close (); return false; } std::vector scratch; data = to_native_scanline (format, data, xstride, scratch); if (m_spec.format == TypeDesc::UINT8) write_scanline(y, z, data); else write_scanline(y, z, data); if (y == m_spec.height - 1) save_image(); return true; } bool Jpeg2000Output::close () { if (m_file) { fclose(m_file); m_file = NULL; } if (m_image) { opj_image_destroy(m_image); m_image = NULL; } return true; } bool Jpeg2000Output::save_image() { opj_cinfo_t* compressor = create_compressor(); if (!compressor) return false; opj_event_mgr_t event_mgr; event_mgr.error_handler = openjpeg_dummy_callback; event_mgr.warning_handler = openjpeg_dummy_callback; event_mgr.info_handler = openjpeg_dummy_callback; opj_set_event_mgr((opj_common_ptr)compressor, &event_mgr, NULL); opj_setup_encoder(compressor, &m_compression_parameters, m_image); opj_cio_t *cio = opj_cio_open((opj_common_ptr)compressor, NULL, 0); opj_encode(compressor, cio, m_image, NULL); size_t wb = fwrite(cio->buffer, 1, cio_tell(cio), m_file); if (wb != (size_t)cio_tell(cio)) { error ("Failed write jpeg2000::save_image (err: %d)", wb); return false; } opj_destroy_compress(compressor); opj_cio_close(cio); return true; } opj_image_t* Jpeg2000Output::create_jpeg2000_image() { setup_compression_params(); OPJ_COLOR_SPACE color_space = CLRSPC_SRGB; if (m_spec.nchannels == 1) color_space = CLRSPC_GRAY; int precision = 16; const ImageIOParameter *prec = m_spec.find_attribute ("oiio:BitsPerSample", TypeDesc::INT); if (prec) precision = *(int*)prec->data(); else if (m_spec.format == TypeDesc::UINT8 || m_spec.format == TypeDesc::INT8) precision = 8; const int MAX_COMPONENTS = 4; opj_image_cmptparm_t component_params[MAX_COMPONENTS]; init_components(component_params, precision); m_image = opj_image_create(m_spec.nchannels, &component_params[0], color_space); m_image->x0 = m_compression_parameters.image_offset_x0; m_image->y0 = m_compression_parameters.image_offset_y0; m_image->x1 = m_compression_parameters.image_offset_x0 + (m_spec.width - 1) * m_compression_parameters.subsampling_dx + 1; m_image->y1 = m_compression_parameters.image_offset_y0 + (m_spec.height - 1) * m_compression_parameters.subsampling_dy + 1; return m_image; } inline void Jpeg2000Output::init_components(opj_image_cmptparm_t *components, int precision) { memset(components, 0x00, m_spec.nchannels * sizeof(opj_image_cmptparm_t)); for(int i = 0; i < m_spec.nchannels; i++) { components[i].dx = m_compression_parameters.subsampling_dx; components[i].dy = m_compression_parameters.subsampling_dy; components[i].w = m_spec.width; components[i].h = m_spec.height; components[i].prec = precision; components[i].bpp = precision; components[i].sgnd = 0; } } opj_cinfo_t* Jpeg2000Output::create_compressor() { std::string ext = Filesystem::extension(m_filename); opj_cinfo_t *compressor = NULL; if (ext == ".j2k") compressor = opj_create_compress(CODEC_J2K); else if (ext == ".jp2") compressor = opj_create_compress(CODEC_JP2); return compressor; } template void Jpeg2000Output::write_scanline(int y, int z, const void *data) { const T* scanline = static_cast(data); const size_t scanline_pos = y * m_spec.width; if (m_spec.nchannels == 1) { for (int i = 0; i < m_spec.width; i++) { m_image->comps[0].data[scanline_pos + i] = write_pixel(m_image->comps[0].prec, scanline[i]); } return; } for (int i = 0, j = 0; i < m_spec.width; i++) { m_image->comps[0].data[scanline_pos + i] = write_pixel(m_image->comps[0].prec, scanline[j++]); m_image->comps[1].data[scanline_pos + i] = write_pixel(m_image->comps[0].prec, scanline[j++]); m_image->comps[2].data[scanline_pos + i] = write_pixel(m_image->comps[0].prec, scanline[j++]); if (m_spec.nchannels < 4) continue; m_image->comps[3].data[scanline_pos + i] = write_pixel(m_image->comps[0].prec, scanline[j++]); } } inline uint16_t Jpeg2000Output::write_pixel(int p_nativePrecision, int p_pixelData) { if (p_nativePrecision == 10) return p_pixelData >> 6; if (p_nativePrecision == 12) return p_pixelData >> 4; return p_pixelData; } void Jpeg2000Output::setup_cinema_compression(OPJ_RSIZ_CAPABILITIES p_rsizCap) { m_compression_parameters.tile_size_on = false; m_compression_parameters.cp_tdx=1; m_compression_parameters.cp_tdy=1; m_compression_parameters.tp_flag = 'C'; m_compression_parameters.tp_on = 1; m_compression_parameters.cp_tx0 = 0; m_compression_parameters.cp_ty0 = 0; m_compression_parameters.image_offset_x0 = 0; m_compression_parameters.image_offset_y0 = 0; m_compression_parameters.cblockw_init = 32; m_compression_parameters.cblockh_init = 32; m_compression_parameters.csty |= 0x01; m_compression_parameters.prog_order = CPRL; m_compression_parameters.roi_compno = -1; m_compression_parameters.subsampling_dx = 1; m_compression_parameters.subsampling_dy = 1; m_compression_parameters.irreversible = 1; m_compression_parameters.cp_rsiz = p_rsizCap; if (p_rsizCap == CINEMA4K) { m_compression_parameters.cp_cinema = CINEMA4K_24; m_compression_parameters.POC[0].tile = 1; m_compression_parameters.POC[0].resno0 = 0; m_compression_parameters.POC[0].compno0 = 0; m_compression_parameters.POC[0].layno1 = 1; m_compression_parameters.POC[0].resno1 = m_compression_parameters.numresolution-1; m_compression_parameters.POC[0].compno1 = 3; m_compression_parameters.POC[0].prg1 = CPRL; m_compression_parameters.POC[1].tile = 1; m_compression_parameters.POC[1].resno0 = m_compression_parameters.numresolution-1; m_compression_parameters.POC[1].compno0 = 0; m_compression_parameters.POC[1].layno1 = 1; m_compression_parameters.POC[1].resno1 = m_compression_parameters.numresolution; m_compression_parameters.POC[1].compno1 = 3; m_compression_parameters.POC[1].prg1 = CPRL; } else if (p_rsizCap == CINEMA2K) { m_compression_parameters.cp_cinema = CINEMA2K_24; } } void Jpeg2000Output::setup_compression_params() { opj_set_default_encoder_parameters(&m_compression_parameters); m_compression_parameters.tcp_rates[0] = 0; m_compression_parameters.tcp_numlayers++; m_compression_parameters.cp_disto_alloc = 1; const ImageIOParameter *is_cinema2k = m_spec.find_attribute ("jpeg2000:Cinema2K", TypeDesc::UINT); if (is_cinema2k) setup_cinema_compression(CINEMA2K); const ImageIOParameter *is_cinema4k = m_spec.find_attribute ("jpeg2000:Cinema4K", TypeDesc::UINT); if (is_cinema4k) setup_cinema_compression(CINEMA4K); const ImageIOParameter *initial_cb_width = m_spec.find_attribute ("jpeg2000:InitialCodeBlockWidth", TypeDesc::UINT); if (initial_cb_width && initial_cb_width->data()) m_compression_parameters.cblockw_init = *(unsigned int*)initial_cb_width->data(); const ImageIOParameter *initial_cb_height = m_spec.find_attribute ("jpeg2000:InitialCodeBlockHeight", TypeDesc::UINT); if (initial_cb_height && initial_cb_height->data()) m_compression_parameters.cblockh_init = *(unsigned int*)initial_cb_height->data(); const ImageIOParameter *progression_order = m_spec.find_attribute ("jpeg2000:ProgressionOrder", TypeDesc::STRING); if (progression_order && progression_order->data()) { std::string prog_order((const char*)progression_order->data()); m_compression_parameters.prog_order = get_progression_order(prog_order); } const ImageIOParameter *compression_mode = m_spec.find_attribute ("jpeg2000:CompressionMode", TypeDesc::INT); if (compression_mode && compression_mode->data()) m_compression_parameters.mode = *(int*)compression_mode->data(); } OPJ_PROG_ORDER Jpeg2000Output::get_progression_order(const std::string &progression_order) { if (progression_order == "LRCP") return LRCP; else if (progression_order == "RLCP") return RLCP; else if (progression_order == "RPCL") return RPCL; else if (progression_order == "PCRL") return PCRL; else if (progression_order == "PCRL") return CPRL; return PROG_UNKNOWN; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/jpeg2000.imageio/CMakeLists.txt0000644000175000017500000000027712271062644022516 0ustar mfvmfvif (USE_OPENJPEG AND OPENJPEG_FOUND) include_directories (${OPENJPEG_INCLUDE_DIR}) add_oiio_plugin (jpeg2000input.cpp jpeg2000output.cpp LINK_LIBRARIES ${OPENJPEG_LIBRARIES}) endif() openimageio-1.3.12~dfsg0.orig/src/jpeg2000.imageio/jpeg2000input.cpp0000644000175000017500000002476412271062644023000 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "filesystem.h" #include "fmath.h" #include "imageio.h" OIIO_PLUGIN_NAMESPACE_BEGIN static void openjpeg_dummy_callback(const char*, void*) {} class Jpeg2000Input : public ImageInput { public: Jpeg2000Input () { init (); } virtual ~Jpeg2000Input () { close (); } virtual const char *format_name (void) const { return "jpeg2000"; } virtual bool open (const std::string &name, ImageSpec &spec); virtual bool close (void); virtual bool read_native_scanline (int y, int z, void *data); private: std::string m_filename; int m_maxPrecision; opj_image_t *m_image; FILE *m_file; void init (void); bool isJp2File(const int* const p_magicTable) const; opj_dinfo_t* create_decompressor(); template void read_scanline(int y, int z, void *data); uint16_t read_pixel(int p_precision, int p_PixelData); uint16_t baseTypeConvertU10ToU16(int src) { return (uint16_t)((src << 6) | (src >> 4)); } uint16_t baseTypeConvertU12ToU16(int src) { return (uint16_t)((src << 4) | (src >> 8)); } size_t get_file_length(FILE *p_file) { fseek(p_file, 0, SEEK_END); const size_t fileLength = ftell(p_file); rewind(m_file); return fileLength; } template void yuv_to_rgb(T *p_scanline) { const imagesize_t scanline_size = m_spec.scanline_bytes(); for (imagesize_t i = 0; i < scanline_size; i += 3) { T red = (T) (1.164f * (p_scanline[i+2] - 16.0f) + 1.596f * (p_scanline[i] - 128.0f)); T green = (T) (1.164f * (p_scanline[i+2] - 16.0f) - 0.813f * (p_scanline[i] - 128.0f) - 0.391f * (p_scanline[i+1] - 128.0f)); T blue = (T) (1.164f * (p_scanline[i+2] - 16.0f) + 2.018f * (p_scanline[i+1] - 128.0f)); p_scanline[i] = red; p_scanline[i+1] = green; p_scanline[i+2] = blue; } } void setup_event_mgr(opj_event_mgr_t& event_mgr, opj_dinfo_t* p_decompressor) { event_mgr.error_handler = openjpeg_dummy_callback; event_mgr.warning_handler = openjpeg_dummy_callback; event_mgr.info_handler = openjpeg_dummy_callback; opj_set_event_mgr((opj_common_ptr) p_decompressor, &event_mgr, NULL); } bool fread (void *p_buf, size_t p_itemSize, size_t p_nitems) { size_t n = ::fread (p_buf, p_itemSize, p_nitems, m_file); if (n != p_nitems) error ("Read error"); return n == p_nitems; } }; // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int jpeg2000_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *jpeg2000_input_imageio_create () { return new Jpeg2000Input; } OIIO_EXPORT const char *jpeg2000_input_extensions[] = { "jp2", "j2k", "j2c", NULL }; OIIO_PLUGIN_EXPORTS_END void Jpeg2000Input::init (void) { m_file = NULL; m_image = NULL; } bool Jpeg2000Input::open (const std::string &p_name, ImageSpec &p_spec) { m_filename = p_name; m_file = Filesystem::fopen(m_filename, "rb"); if (!m_file) { error ("Could not open file \"%s\"", m_filename.c_str()); return false; } opj_dinfo_t* decompressor = create_decompressor(); if (!decompressor) { error ("Could not create Jpeg2000 stream decompressor"); close(); return false; } opj_event_mgr_t event_mgr; setup_event_mgr(event_mgr, decompressor); opj_dparameters_t parameters; opj_set_default_decoder_parameters(¶meters); opj_setup_decoder(decompressor, ¶meters); const size_t fileLength = get_file_length(m_file); std::vector fileContent(fileLength+1, 0); fread(&fileContent[0], sizeof(uint8_t), fileLength); opj_cio_t *cio = opj_cio_open((opj_common_ptr)decompressor, &fileContent[0], (int) fileLength); if (!cio) { error ("Could not open Jpeg2000 stream"); opj_destroy_decompress(decompressor); close(); return false; } m_image = opj_decode(decompressor, cio); opj_cio_close(cio); opj_destroy_decompress(decompressor); if (!m_image) { error ("Could not decode Jpeg2000 stream"); close(); return false; } // we support only one, three or four components in image const int channelCount = m_image->numcomps; if (channelCount != 1 && channelCount != 3 && channelCount != 4) { error ("Only images with one, three or four components are supported"); close(); return false; } m_maxPrecision = 0; for(int i = 0; i < channelCount; i++) { m_maxPrecision = std::max(m_image->comps[i].prec, m_maxPrecision); } const TypeDesc format = (m_maxPrecision <= 8) ? TypeDesc::UINT8 : TypeDesc::UINT16; m_spec = ImageSpec(m_image->comps[0].w, m_image->comps[0].h, channelCount, format); m_spec.attribute ("oiio:BitsPerSample", (unsigned int)m_maxPrecision); m_spec.attribute ("oiio:Orientation", (unsigned int)1); p_spec = m_spec; return true; } bool Jpeg2000Input::read_native_scanline (int y, int z, void *data) { if (m_spec.format == TypeDesc::UINT8) read_scanline(y, z, data); else read_scanline(y, z, data); return true; } inline bool Jpeg2000Input::close (void) { if (m_file) { fclose(m_file); m_file = NULL; } if (m_image) { opj_image_destroy(m_image); m_image = NULL; } return true; } bool Jpeg2000Input::isJp2File(const int* const p_magicTable) const { const int32_t JP2_MAGIC = 0x0000000C, JP2_MAGIC2 = 0x0C000000; if (p_magicTable[0] == JP2_MAGIC || p_magicTable[0] == JP2_MAGIC2) { const int32_t JP2_SIG1_MAGIC = 0x6A502020, JP2_SIG1_MAGIC2 = 0x2020506A; const int32_t JP2_SIG2_MAGIC = 0x0D0A870A, JP2_SIG2_MAGIC2 = 0x0A870A0D; if ((p_magicTable[1] == JP2_SIG1_MAGIC || p_magicTable[1] == JP2_SIG1_MAGIC2) && (p_magicTable[2] == JP2_SIG2_MAGIC || p_magicTable[2] == JP2_SIG2_MAGIC2)) { return true; } } return false; } opj_dinfo_t* Jpeg2000Input::create_decompressor() { int magic[3]; if (::fread (&magic, 4, 3, m_file) != 3) { error ("Empty file \"%s\"", m_filename.c_str()); return NULL; } opj_dinfo_t* dinfo = NULL; if (isJp2File(magic)) dinfo = opj_create_decompress(CODEC_JP2); else dinfo = opj_create_decompress(CODEC_J2K); rewind(m_file); return dinfo; } inline uint16_t Jpeg2000Input::read_pixel(int p_nativePrecision, int p_pixelData) { if (p_nativePrecision == 10) return baseTypeConvertU10ToU16(p_pixelData); if (p_nativePrecision == 12) return baseTypeConvertU12ToU16(p_pixelData); return p_pixelData; } template void Jpeg2000Input::read_scanline(int y, int z, void *data) { T* scanline = static_cast(data); if (m_spec.nchannels == 1) { for (int i = 0; i < m_spec.width; i++) { scanline[i] = (T) read_pixel(m_image->comps[0].prec, m_image->comps[0].data[y*m_spec.width + i]); } return; } for (int i = 0, j = 0; i < m_spec.width; i++) { if (y % m_image->comps[0].dy == 0 && i % m_image->comps[0].dx == 0) { const size_t data_offset = y/m_image->comps[0].dy * m_spec.width/m_image->comps[0].dx + i/m_image->comps[0].dx; scanline[j++] = (T) read_pixel(m_image->comps[0].prec, m_image->comps[0].data[data_offset]); } else { scanline[j++] = 0; } if (y % m_image->comps[1].dy == 0 && i % m_image->comps[1].dx == 0) { const size_t data_offset = y/m_image->comps[1].dy * m_spec.width/m_image->comps[1].dx + i/m_image->comps[1].dx; scanline[j++] = (T) read_pixel(m_image->comps[1].prec, m_image->comps[1].data[data_offset]); } else { scanline[j++] = 0; } if (y % m_image->comps[2].dy == 0 && i % m_image->comps[2].dx == 0) { const size_t data_offset = y/m_image->comps[2].dy * m_spec.width/m_image->comps[2].dx + i/m_image->comps[2].dx; scanline[j++] = (T) read_pixel(m_image->comps[2].prec, m_image->comps[2].data[data_offset]); } else { scanline[j++] = 0; } if (m_spec.nchannels < 4) { continue; } if (y % m_image->comps[3].dy == 0 && i % m_image->comps[3].dx == 0) { const size_t data_offset = y/m_image->comps[3].dy * m_spec.width/m_image->comps[3].dx + i/m_image->comps[3].dx; scanline[j++] = (T) read_pixel(m_image->comps[3].prec, m_image->comps[3].data[data_offset]); } else { scanline[j++] = 0; } } if (m_image->color_space == CLRSPC_SYCC) yuv_to_rgb(scanline); } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/iinfo/0000755000175000017500000000000012271062644016214 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/iinfo/iinfo.cpp0000644000175000017500000005446312271062644020040 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include "argparse.h" #include "strutil.h" #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "hash.h" #include "filesystem.h" OIIO_NAMESPACE_USING; using namespace ImageBufAlgo; static bool verbose = false; static bool sum = false; static bool help = false; static std::vector filenames; static std::string metamatch; static bool filenameprefix = false; static boost::regex field_re; static bool subimages = false; static bool compute_sha1 = false; static bool compute_stats = false; static void print_sha1 (ImageInput *input) { SHA1 sha; const ImageSpec &spec (input->spec()); if (spec.deep) { // Special handling of deep data DeepData dd; if (! input->read_native_deep_image (dd)) { printf (" SHA-1: unable to compute, could not read image\n"); return; } // Hash both the sample counds and the data block sha.appendvec (dd.nsamples); sha.appendvec (dd.data); } else { imagesize_t size = input->spec().image_bytes (true /*native*/); if (size >= std::numeric_limits::max()) { printf (" SHA-1: unable to compute, image is too big\n"); return; } std::vector buf((size_t)size); if (! input->read_image (TypeDesc::UNKNOWN /*native*/, &buf[0])) { printf (" SHA-1: unable to compute, could not read image\n"); return; } sha.appendvec (buf); } printf (" SHA-1: %s\n", sha.digest().c_str()); } /////////////////////////////////////////////////////////////////////////////// // Stats static bool read_input (const std::string &filename, ImageBuf &img, int subimage=0, int miplevel=0) { if (img.subimage() >= 0 && img.subimage() == subimage) return true; if (img.init_spec (filename, subimage, miplevel) && img.read (subimage, miplevel, false, TypeDesc::FLOAT)) return true; std::cerr << "iinfo ERROR: Could not read " << filename << ":\n\t" << img.geterror() << "\n"; return false; } static void print_stats_num (float val, int maxval, bool round) { if (maxval == 0) { printf("%f",val); } else { float fval = val * static_cast(maxval); if (round) { int v = static_cast(roundf (fval)); printf ("%d", v); } else { printf ("%0.2f", fval); } } } // First check oiio:BitsPerSample int attribute. If not set, // fall back on the TypeDesc. return 0 for float types // or those that exceed the int range (long long, etc) static unsigned long long get_intsample_maxval (const ImageSpec &spec) { TypeDesc type = spec.format; int bits = spec.get_int_attribute ("oiio:BitsPerSample"); if (bits > 0) { if (type.basetype == TypeDesc::UINT8 || type.basetype == TypeDesc::UINT16 || type.basetype == TypeDesc::UINT32) return ((1LL) << bits) - 1; if (type.basetype == TypeDesc::INT8 || type.basetype == TypeDesc::INT16 || type.basetype == TypeDesc::INT32) return ((1LL) << (bits-1)) - 1; } // These correspond to all the int enums in typedesc.h <= int if (type.basetype == TypeDesc::UCHAR) return 0xff; if (type.basetype == TypeDesc::CHAR) return 0x7f; if (type.basetype == TypeDesc::USHORT) return 0xffff; if (type.basetype == TypeDesc::SHORT) return 0x7fff; if (type.basetype == TypeDesc::UINT) return 0xffffffff; if (type.basetype == TypeDesc::INT) return 0x7fffffff; return 0; } static void print_stats_footer (unsigned int maxval) { if (maxval==0) printf ("(float)"); else printf ("(of %u)", maxval); } static void print_stats (const std::string &filename, const ImageSpec &originalspec, int subimage=0, int miplevel=0, bool indentmip=false) { PixelStats stats; const char *indent = indentmip ? " " : " "; ImageBuf input; if (! read_input (filename, input, subimage, miplevel)) { std::cerr << "Stats: read error: " << input.geterror() << "\n"; return; } if (! computePixelStats (stats, input)) { printf ("%sStats: (unable to compute)\n", indent); return; } // The original spec is used, otherwise the bit depth will // be reported incorrectly (as FLOAT) unsigned int maxval = (unsigned int)get_intsample_maxval (originalspec); printf ("%sStats Min: ", indent); for (unsigned int i=0; insamples.size(); size_t totalsamples = 0, emptypixels = 0; size_t maxsamples = 0, minsamples = std::numeric_limits::max(); for (size_t p = 0; p < npixels; ++p) { size_t c = dd->nsamples[p]; totalsamples += c; if (c > maxsamples) maxsamples = c; if (c < minsamples) minsamples = c; if (c == 0) ++emptypixels; } printf ("%sMin deep samples in any pixel : %llu\n", indent, (unsigned long long)minsamples); printf ("%sMax deep samples in any pixel : %llu\n", indent, (unsigned long long)maxsamples); printf ("%sAverage deep samples per pixel: %.2f\n", indent, double(totalsamples)/double(npixels)); printf ("%sTotal deep samples in all pixels: %llu\n", indent, (unsigned long long)totalsamples); printf ("%sPixels with deep samples : %llu\n", indent, (unsigned long long)(npixels-emptypixels)); printf ("%sPixels with no deep samples: %llu\n", indent, (unsigned long long)emptypixels); } else { std::vector constantValues(input.spec().nchannels); if (isConstantColor(input, &constantValues[0])) { printf ("%sConstant: Yes\n", indent); printf ("%sConstant Color: ", indent); for (unsigned int i=0; i 1) printf (", z=%d", spec.z); printf ("\n"); printed = true; } } if (spec.full_x || spec.full_y || spec.full_z || (spec.full_width != spec.width && spec.full_width != 0) || (spec.full_height != spec.height && spec.full_height != 0) || (spec.full_depth != spec.depth && spec.full_depth != 0)) { if (metamatch.empty() || boost::regex_search ("full/display size", field_re)) { if (filenameprefix) printf ("%s : ", filename.c_str()); printf (" full/display size: %d x %d", spec.full_width, spec.full_height); if (spec.depth > 1) printf (" x %d", spec.full_depth); printf ("\n"); printed = true; } if (metamatch.empty() || boost::regex_search ("full/display origin", field_re)) { if (filenameprefix) printf ("%s : ", filename.c_str()); printf (" full/display origin: %d, %d", spec.full_x, spec.full_y); if (spec.depth > 1) printf (", %d", spec.full_z); printf ("\n"); printed = true; } } if (spec.tile_width) { if (metamatch.empty() || boost::regex_search ("tile", field_re)) { if (filenameprefix) printf ("%s : ", filename.c_str()); printf (" tile size: %d x %d", spec.tile_width, spec.tile_height); if (spec.depth > 1) printf (" x %d", spec.tile_depth); printf ("\n"); printed = true; } } BOOST_FOREACH (const ImageIOParameter &p, spec.extra_attribs) { if (! metamatch.empty() && ! boost::regex_search (p.name().c_str(), field_re)) continue; std::string s = spec.metadata_val (p, true); if (filenameprefix) printf ("%s : ", filename.c_str()); printf (" %s: ", p.name().c_str()); if (! strcmp (s.c_str(), "1.#INF")) printf ("inf"); else printf ("%s", s.c_str()); printf ("\n"); printed = true; } if (! printed && !metamatch.empty()) { if (filenameprefix) printf ("%s : ", filename.c_str()); printf (" %s: \n", metamatch.c_str()); } } static const char * extended_format_name (TypeDesc type, int bits) { if (bits && bits < (int)type.size()*8) { // The "oiio:BitsPerSample" betrays a different bit depth in the // file than the data type we are passing. if (type == TypeDesc::UINT8 || type == TypeDesc::UINT16 || type == TypeDesc::UINT32 || type == TypeDesc::UINT64) return ustring::format("uint%d", bits).c_str(); if (type == TypeDesc::INT8 || type == TypeDesc::INT16 || type == TypeDesc::INT32 || type == TypeDesc::INT64) return ustring::format("int%d", bits).c_str(); } return type.c_str(); // use the name implied by type } // prints basic info (resolution, width, height, depth, channels, data format, // and format name) about given subimage. static void print_info_subimage (int current_subimage, int max_subimages, ImageSpec &spec, ImageInput *input, const std::string &filename) { if ( ! input->seek_subimage (current_subimage, 0, spec) ) return; if (! metamatch.empty() && ! boost::regex_search ("resolution, width, height, depth, channels, sha-1, stats", field_re)) { // nothing to do here return; } int nmip = 1; bool printres = verbose && (metamatch.empty() || boost::regex_search ("resolution, width, height, depth, channels", field_re)); if (printres && max_subimages > 1 && subimages) { printf (" subimage %2d: ", current_subimage); printf ("%4d x %4d", spec.width, spec.height); if (spec.depth > 1) printf (" x %4d", spec.depth); int bits = spec.get_int_attribute ("oiio:BitsPerSample", 0); printf (", %d channel, %s%s%s", spec.nchannels, spec.deep ? "deep " : "", extended_format_name(spec.format, bits), spec.depth > 1 ? " volume" : ""); printf (" %s", input->format_name()); printf ("\n"); } // Count MIP levels ImageSpec mipspec; while (input->seek_subimage (current_subimage, nmip, mipspec)) { if (printres) { if (nmip == 1) printf (" MIP-map levels: %dx%d", spec.width, spec.height); printf (" %dx%d", mipspec.width, mipspec.height); } ++nmip; } if (printres && nmip > 1) printf ("\n"); if (compute_sha1 && (metamatch.empty() || boost::regex_search ("sha-1", field_re))) { if (filenameprefix) printf ("%s : ", filename.c_str()); // Before sha-1, be sure to point back to the highest-res MIP level ImageSpec tmpspec; input->seek_subimage (current_subimage, 0, tmpspec); print_sha1 (input); } if (verbose) print_metadata (spec, filename); if (compute_stats && (metamatch.empty() || boost::regex_search ("stats", field_re))) { for (int m = 0; m < nmip; ++m) { ImageSpec mipspec; input->seek_subimage (current_subimage, m, mipspec); if (filenameprefix) printf ("%s : ", filename.c_str()); if (nmip > 1 && (subimages || m == 0)) { printf (" MIP %d of %d (%d x %d):\n", m, nmip, mipspec.width, mipspec.height); } print_stats (filename, spec, current_subimage, m, nmip>1); } } if ( ! input->seek_subimage (current_subimage, 0, spec) ) return; } static void print_info (const std::string &filename, size_t namefieldlength, ImageInput *input, ImageSpec &spec, bool verbose, bool sum, long long &totalsize) { int padlen = std::max (0, (int)namefieldlength - (int)filename.length()); std::string padding (padlen, ' '); // checking how many subimages and mipmap levels are stored in the file int num_of_subimages = 1; bool any_mipmapping = false; std::vector num_of_miplevels; { int nmip = 1; while (input->seek_subimage (input->current_subimage(), nmip, spec)) { ++nmip; any_mipmapping = true; } num_of_miplevels.push_back (nmip); } while (input->seek_subimage (num_of_subimages, 0, spec)) { // maybe we should do this more gently? ++num_of_subimages; int nmip = 1; while (input->seek_subimage (input->current_subimage(), nmip, spec)) { ++nmip; any_mipmapping = true; } num_of_miplevels.push_back (nmip); } input->seek_subimage (0, 0, spec); // re-seek to the first if (metamatch.empty() || boost::regex_search ("resolution, width, height, depth, channels", field_re)) { printf ("%s%s : %4d x %4d", filename.c_str(), padding.c_str(), spec.width, spec.height); if (spec.depth > 1) printf (" x %4d", spec.depth); printf (", %d channel, ", spec.nchannels); if (spec.deep) printf ("deep "); if (spec.channelformats.size()) { for (size_t c = 0; c < spec.channelformats.size(); ++c) printf ("%s%s", c ? "/" : "", spec.channelformats[c].c_str()); } else { int bits = spec.get_int_attribute ("oiio:BitsPerSample", 0); printf ("%s", extended_format_name(spec.format, bits)); } if (spec.depth > 1) printf (" volume"); printf (" %s", input->format_name()); if (sum) { imagesize_t imagebytes = spec.image_bytes (true); totalsize += imagebytes; printf (" (%.2f MB)", (float)imagebytes / (1024.0*1024.0)); } // we print info about how many subimages are stored in file // only when we have more then one subimage if ( ! verbose && num_of_subimages != 1) printf (" (%d subimages%s)", num_of_subimages, any_mipmapping ? " +mipmap)" : ""); if (! verbose && num_of_subimages == 1 && any_mipmapping) printf (" (+mipmap)"); printf ("\n"); } if (verbose && num_of_subimages != 1) { // info about num of subimages and their resolutions printf (" %d subimages: ", num_of_subimages); for (int i = 0; i < num_of_subimages; ++i) { input->seek_subimage (i, 0, spec); if (spec.depth > 1) printf ("%dx%dx%d ", spec.width, spec.height, spec.depth); else printf ("%dx%d ", spec.width, spec.height); } printf ("\n"); } // if the '-a' flag is not set we print info // about first subimage only if ( ! subimages) num_of_subimages = 1; for (int i = 0; i < num_of_subimages; ++i) { print_info_subimage (i, num_of_subimages, spec, input, filename); } } static int parse_files (int argc, const char *argv[]) { for (int i = 0; i < argc; i++) filenames.push_back (argv[i]); return 0; } int main (int argc, const char *argv[]) { Filesystem::convert_native_arguments (argc, (const char **)argv); ArgParse ap; ap.options ("iinfo -- print information about images\n" OIIO_INTRO_STRING "\n" "Usage: iinfo [options] filename...", "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose output", "-m %s", &metamatch, "Metadata names to print (default: all)", "-f", &filenameprefix, "Prefix each line with the filename", "-s", &sum, "Sum the image sizes", "-a", &subimages, "Print info about all subimages", "--hash", &compute_sha1, "Print SHA-1 hash of pixel values", "--stats", &compute_stats, "Print image pixel statistics (data window)", NULL); if (ap.parse(argc, argv) < 0 || filenames.empty()) { std::cerr << ap.geterror() << std::endl; ap.usage (); return EXIT_FAILURE; } if (help) { ap.usage (); exit (EXIT_FAILURE); } if (! metamatch.empty()) field_re.assign (metamatch, boost::regex::extended | boost::regex_constants::icase); // Find the longest filename size_t longestname = 0; BOOST_FOREACH (const std::string &s, filenames) longestname = std::max (longestname, s.length()); longestname = std::min (longestname, (size_t)40); long long totalsize = 0; BOOST_FOREACH (const std::string &s, filenames) { ImageInput *in = ImageInput::open (s.c_str()); if (! in) { std::string err = geterror(); if (err.empty()) err = Strutil::format ("Could not open \"%s\"", s.c_str()); std::cerr << "iinfo: " << err << "\n"; continue; } ImageSpec spec = in->spec(); print_info (s, longestname, in, spec, verbose, sum, totalsize); in->close (); delete in; } if (sum) { double t = (double)totalsize / (1024.0*1024.0); if (t > 1024.0) printf ("Total size: %.2f GB\n", t/1024.0); else printf ("Total size: %.2f MB\n", t); } return 0; } openimageio-1.3.12~dfsg0.orig/src/iinfo/CMakeLists.txt0000644000175000017500000000052712271062644020760 0ustar mfvmfvset (iinfo_srcs iinfo.cpp) add_executable (iinfo ${iinfo_srcs}) set_target_properties (iinfo PROPERTIES FOLDER "Tools") if (MSVC) set_target_properties (OpenImageIO PROPERTIES LINK_FLAGS psapi.lib) endif (MSVC) link_ilmbase (iinfo) target_link_libraries (iinfo OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) oiio_install_targets (iinfo) openimageio-1.3.12~dfsg0.orig/src/fits.imageio/0000755000175000017500000000000012271062644017466 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/fits.imageio/fitsinput.cpp0000644000175000017500000003037412271062644022226 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include "fits_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int fits_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *fits_input_imageio_create () { return new FitsInput; } OIIO_EXPORT const char *fits_input_extensions[] = { "fits", NULL }; OIIO_PLUGIN_EXPORTS_END bool FitsInput::valid_file (const std::string &filename) const { FILE *fd = Filesystem::fopen (filename, "rb"); if (!fd) return false; char magic[6] = {0}; bool ok = (fread (magic, 1, 6, fd) == 6) && !strncmp (magic, "SIMPLE", 6); fclose (fd); return ok; } bool FitsInput::open (const std::string &name, ImageSpec &spec) { // saving 'name' for later use m_filename = name; // checking if the file exists and can be opened in READ mode m_fd = Filesystem::fopen (m_filename, "rb"); if (!m_fd) { error ("Could not open file \"%s\"", m_filename.c_str ()); return false; } // checking if the file is FITS file char magic[6] = {0}; if (fread (magic, 1, 6, m_fd) != 6) { error ("%s isn't a FITS file", m_filename.c_str ()); return false; // Read failed } if (strncmp (magic, "SIMPLE", 6)) { error ("%s isn't a FITS file", m_filename.c_str ()); close (); return false; } // moving back to the start of the file fseek (m_fd, 0, SEEK_SET); subimage_search (); if (! set_spec_info ()) return false; spec = m_spec; return true; }; bool FitsInput::read_native_scanline (int y, int z, void *data) { // we return true just to support 0x0 images if (!m_naxes) return true; std::vector data_tmp (m_spec.scanline_bytes ()); long scanline_off = (m_spec.height - y) * m_spec.scanline_bytes (); fseek (m_fd, scanline_off, SEEK_CUR); size_t n = fread (&data_tmp[0], 1, m_spec.scanline_bytes(), m_fd); if (n != m_spec.scanline_bytes()) { if (feof (m_fd)) error ("Hit end of file unexpectedly"); else error ("read error"); return false; // Read failed } // in FITS image data is stored in big-endian so we have to switch to // little-endian on little-endian machines if (littleendian ()) { if (m_spec.format == TypeDesc::USHORT) swap_endian ((unsigned short*)&data_tmp[0], data_tmp.size () / sizeof (unsigned short)); else if (m_spec.format == TypeDesc::UINT) swap_endian ((unsigned int*)&data_tmp[0], data_tmp.size () / sizeof (unsigned int)); else if (m_spec.format == TypeDesc::FLOAT) swap_endian ((float*)&data_tmp[0], data_tmp.size () / sizeof (float)); else if (m_spec.format == TypeDesc::DOUBLE) swap_endian ((double*)&data_tmp[0], data_tmp.size () / sizeof (double)); } memcpy (data, &data_tmp[0], data_tmp.size ()); // after reading scanline we set file pointer to the start of image data fsetpos (m_fd, &m_filepos); return true; }; bool FitsInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (miplevel != 0) return false; if (subimage < 0 || subimage >= (int)m_subimages.size ()) return false; if (subimage == m_cur_subimage) { newspec = m_spec; return true; } // setting file pointer to the beginning of IMAGE extension m_cur_subimage = subimage; fseek (m_fd, m_subimages[m_cur_subimage].offset, SEEK_SET); if (! set_spec_info ()) return false; newspec = m_spec; return true; } bool FitsInput::set_spec_info () { keys.clear (); // FITS spec doesn't say anything about color space or // number of channels, so we read all images as if they // all were one-channel images m_spec = ImageSpec(0, 0, 1, TypeDesc::UNKNOWN); // reading info about current subimage if (! read_fits_header ()) return false; // we don't deal with one dimension images // it's some kind of spectral data if (! m_spec.width || ! m_spec.height) { m_spec.width = m_spec.full_width = 0; m_spec.height = m_spec.full_height = 0; } // now we can get the current position in the file // this is the start of the image data // we will need it in the read_native_scanline method fgetpos(m_fd, &m_filepos); if (m_bitpix == 8) m_spec.set_format (TypeDesc::UCHAR); else if (m_bitpix == 16) m_spec.set_format (TypeDesc::USHORT); else if (m_bitpix == 32) m_spec.set_format (TypeDesc::UINT); else if (m_bitpix == -32) m_spec.set_format (TypeDesc::FLOAT); else if (m_bitpix == -64) m_spec.set_format (TypeDesc::DOUBLE); return true; } bool FitsInput::close (void) { if (m_fd) fclose (m_fd); init (); return true; } bool FitsInput::read_fits_header (void) { std::string fits_header (HEADER_SIZE, 0); // we read whole header at once if (fread (&fits_header[0], 1, HEADER_SIZE, m_fd) != HEADER_SIZE) { if (feof (m_fd)) error ("Hit end of file unexpectedly"); else error ("read error"); return false; // Read failed } for (int i = 0; i < CARDS_PER_HEADER; ++i) { std::string card (CARD_SIZE, 0); // reading card number i memcpy (&card[0], &fits_header[i*CARD_SIZE], CARD_SIZE); std::string keyname, value; fits_pvt::unpack_card (card, keyname, value); // END means that this is end of the FITS header // we can now add to the ImageSpec COMMENT, HISTORY and HIERARCH keys if (keyname == "END") { // removing white spaces that we use to separate lines of comments // from the end ot the string m_comment = m_comment.substr (0, m_comment.size() - m_sep.size ()); m_history = m_history.substr (0, m_history.size() - m_sep.size ()); m_hierarch = m_hierarch.substr (0, m_hierarch.size() - m_sep.size ()); add_to_spec ("Comment", m_comment); add_to_spec ("History", m_history); add_to_spec ("Hierarch", m_hierarch); return true; } if (keyname == "SIMPLE" || keyname == "XTENSION") continue; // setting up some important fields // m_bitpix - format of the data (eg. bpp) // m_naxes - number of axes // width, height and depth of the image if (keyname == "BITPIX") { m_bitpix = atoi (&card[10]); continue; } if (keyname == "NAXIS") { m_naxes = atoi (&card[10]); if (m_naxes == 1) // 1 axis is w x 1 image m_spec.height = m_spec.full_height = 1; continue; } if (keyname == "NAXIS1") { m_spec.width = atoi (&card[10]); m_spec.full_width = m_spec.width; continue; } if (keyname == "NAXIS2") { m_spec.height = atoi (&card[10]); m_spec.full_height = m_spec.height; continue; } // ignoring other axis if (keyname.substr (0,5) == "NAXIS") { continue; } if (keyname == "ORIENTAT") { add_to_spec ("Orientation", value); continue; } if (keyname == "DATE") { add_to_spec ("DateTime", convert_date (value)); continue; } if (keyname == "COMMENT") { m_comment += (value + m_sep); continue; } if (keyname == "HISTORY") { m_history += (value + m_sep); continue; } if (keyname == "HIERARCH") { m_hierarch += (value + m_sep); continue; } add_to_spec (pystring::capitalize(keyname), value); } // if we didn't found END keyword in current header, we read next one return read_fits_header (); } void FitsInput::add_to_spec (const std::string &keyname, const std::string &value) { // we don't add empty keys (or keys with empty values) to ImageSpec if (!keyname.size() || !value.size ()) return; // COMMENT, HISTORY, HIERARCH and DATE keywords we save AS-IS bool speckey = (keyname == "Comment" || keyname == "History" ||keyname == "Hierarch"); if (speckey || keyname == "DateTime") { m_spec.attribute (keyname, value); return; } // converting string to float or integer bool isNumSign = (value[0] == '+' || value[0] == '-' || value[0] == '.'); if (isdigit (value[0]) || isNumSign) { float val = atof (value.c_str ()); if (val == (int)val) m_spec.attribute (keyname, (int)val); else m_spec.attribute (keyname, val); } else m_spec.attribute (keyname, value); } void FitsInput::subimage_search () { // saving position of the file, just for safe) fpos_t fpos; fgetpos (m_fd, &fpos); // starting reading headers from the beginning of the file fseek (m_fd, 0, SEEK_SET); // we search for subimages by reading whole header and checking if it // starts by "SIMPLE" keyword (primary header is always image header) // or by "XTENSION= 'IMAGE '" (it is image extensions) std::string hdu (HEADER_SIZE, 0); size_t offset = 0; while (fread (&hdu[0], 1, HEADER_SIZE, m_fd) == HEADER_SIZE) { if (!strncmp (&hdu[0], "SIMPLE", 6) || !strncmp (&hdu[0], "XTENSION= 'IMAGE '", 20)) { fits_pvt::Subimage newSub; newSub.number = m_subimages.size (); newSub.offset = offset; m_subimages.push_back (newSub); } offset += HEADER_SIZE; } fsetpos (m_fd, &fpos); } std::string FitsInput::convert_date (const std::string &date) { std::string ndate; if (date[4] == '-') { // YYYY-MM-DDThh:mm:ss convention is used since 1 January 2000 ndate = Strutil::format ("%04u:%02u:%02u", atoi(&date[0]), atoi(&date[5]), atoi(&date[8])); if (date.size () >= 11 && date[10] == 'T') ndate += Strutil::format (" %02u:%02u:%02u", atoi (&date[11]), atoi (&date[14]), atoi (&date[17])); return ndate; } if (date[2] == '/') { // DD/MM/YY convention was used before 1 January 2000 ndate = Strutil::format ("19%02u:%02u:%02u 00:00:00", atoi(&date[6]), atoi(&date[3]), atoi(&date[0])); return ndate; } // unrecognized format return date; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/fits.imageio/fits_pvt.cpp0000644000175000017500000000746612271062644022045 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "fits_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace fits_pvt { std::string num2str (float val) { std::stringstream out ; out << val; std::string result (20 - out.str().size(), ' '); result += out.str (); return result; } std::string create_card (std::string keyname, std::string value) { keyname = pystring::upper (keyname); if (keyname.substr (0, 7) == "COMMENT" || keyname.substr (0, 7) == "HISTORY") keyname = keyname.substr (0, 7) + " "; else if (keyname.substr (0, 8) == "HIERARCH") keyname = "HIERARCH"; else { // other keynames are separated from values by "= " keyname.resize (8, ' '); keyname += "= "; } std::string card = keyname; // boolean values are placed on byte 30 of the card // (20 of the value field) if (value.size () == 1) { std::string tmp (19, ' '); value = tmp + value; } card += value; card.resize (80, ' '); return card; } void unpack_card (const std::string &card, std::string &keyname, std::string &value) { keyname.clear (); value.clear (); // extracting keyname - first 8 bytes of the keyword (always) // we strip spaces that are placed after keyword name keyname = pystring::strip (card.substr(0,8)); // the value starts at 10 byte of the card if "=" is present at 8 byte // or at 8 byte otherwise int start = 10; if (card[8] != '=') start = 8; // copy of the card with keyword name stripped (only value and comment) std::string card_cpy = card.substr (start, card.size ()); card_cpy = pystring::strip (card_cpy, ""); // retrieving value and get rid of the comment int begin = 0, end = 0; std::string sep ("/"); if (card_cpy[0] == '\'') { begin = 1; end = -1; sep = "'"; } end += pystring::find (card_cpy, sep, 1, card_cpy.size ()); // after creating substring we strip NULL chars from the end // without this some strings are broken: see HISTORY keywords // in ftt4b/file003.fits test image for example value = card_cpy.substr (begin, end).c_str(); if (value.size ()) value = pystring::strip(value, ""); } } // namespace fits_pvt OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/fits.imageio/fits_pvt.h0000644000175000017500000001514012271062644021476 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_FITS_PVT_H #define OPENIMAGEIO_FITS_PVT_H #include #include #include #include "imageio.h" #include "filesystem.h" #include "fmath.h" #include "pystring.h" // This represent the size of ONE header unit in FITS file. #define HEADER_SIZE 2880 // This represent the size of ONE card unit. Card consist of // keyname, value and optional comment #define CARD_SIZE 80 // This represent the size of max number of cards in one header #define CARDS_PER_HEADER 36 OIIO_PLUGIN_NAMESPACE_BEGIN namespace fits_pvt { // struct in which we store information about one subimage. This informations // allow us to set up pointer at the beginning of given subimage struct Subimage { int number; size_t offset; }; } // namespace fits_pvt class FitsInput : public ImageInput { public: FitsInput () { init (); } virtual ~FitsInput () { close (); } virtual const char *format_name (void) const { return "fits"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &spec); virtual bool close (void); virtual bool read_native_scanline (int y, int z, void *data); virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual int current_subimage () const { return m_cur_subimage; } private: FILE *m_fd; std::string m_filename; int m_cur_subimage; int m_bitpix; // number of bits that represents data value; int m_naxes; // number of axsis of the image (e.g dimensions) fpos_t m_filepos; // current position in the file // here we store informations how many times COMMENT, HISTORY, HIERARCH // keywords has occured std::map keys; // here we store informations about subimages, // eg. subimage number and subimage offset std::vector m_subimages; // here we stores content of COMMENT, HISTORY, HIERARCH keywords. Each line // of comment is separated by m_sep std::string m_comment, m_history, m_hierarch; std::string m_sep; void init (void) { m_fd = NULL; m_filename.clear (); m_cur_subimage = 0; m_bitpix = 0; m_naxes = 0; m_subimages.clear (); m_comment.clear (); m_history.clear (); m_hierarch.clear (); m_sep = '\n'; } // read keywords from FITS header and add them to the ImageSpec // sets some ImageSpec fields: width, height, depth. // Return true if all is ok, false if there was a read error. bool read_fits_header (void); // add keyword (with comment if exists) to the ImageSpec void add_to_spec (const std::string &keyname, const std::string &value); // search for subimages: in FITS subimage is a header with SIMPLE keyword // or with XTENSION keyword with value 'IMAGE '. Information about found // subimages are stored in m_subimages void subimage_search (); // set basic info (width, height) of subimage // add attributes to ImageSpec // return true if ok, false upon error reading the spec from the file. bool set_spec_info (); // converts date in FITS format (YYYY-MM-DD or DD/MM/YY) // to DateTime format std::string convert_date (const std::string &date); }; class FitsOutput : public ImageOutput { public: FitsOutput () { init (); } virtual ~FitsOutput () { close (); } virtual const char *format_name (void) const { return "fits"; } virtual bool supports (const std::string &feature) const; virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (void); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: FILE *m_fd; std::string m_filename; int m_bitpix; // number of bits that represents data value; fpos_t m_filepos; // current position in the file bool m_simple; // does the header with SIMPLE key was written? std::vector m_scratch; std::string m_sep; void init (void) { m_fd = NULL; m_filename.clear (); m_bitpix = 0; m_simple = true; m_scratch.clear (); m_sep = '\n'; } // save to FITS file all attributes from ImageSpace and after writing last // attribute writes END keyword void create_fits_header (void); // save to FITS file some mandatory keywords: SIMPLE, BITPIX, NAXIS, NAXIS1 // and NAXIS2 with their values. void create_basic_header (std::string &header); }; namespace fits_pvt { // converts given number to string std::string num2str (float val); // creates FITS card from given (keyname, value, comment) strings std::string create_card (std::string keyname, std::string value); // retrieving keyname, value and comment from the given card void unpack_card (const std::string &card, std::string &keyname, std::string &value); } // namespace fits_pvt OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_FITS_PVT_H openimageio-1.3.12~dfsg0.orig/src/fits.imageio/fitsoutput.cpp0000644000175000017500000002132212271062644022420 0ustar mfvmfv/* Copyright 2008-2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "fits_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace fits_pvt; // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *fits_output_imageio_create () { return new FitsOutput; } OIIO_EXPORT const char *fits_output_extensions[] = { "fits", NULL }; OIIO_PLUGIN_EXPORTS_END bool FitsOutput::open (const std::string &name, const ImageSpec &spec, OpenMode mode) { if (mode == AppendMIPLevel) { error ("%s does not support MIP levels", format_name()); return false; } // saving 'name' and 'spec' for later use m_filename = name; m_spec = spec; if (m_spec.format == TypeDesc::UNKNOWN) // if unknown, default to float m_spec.set_format (TypeDesc::FLOAT); // checking if the file exists and can be opened in WRITE mode m_fd = Filesystem::fopen (m_filename, mode == AppendSubimage ? "r+b" : "wb"); if (!m_fd) { error ("Unable to open file \"%s\"", m_filename.c_str()); return false; } create_fits_header (); // now we can get the current position in the file // we will need it int the write_native_scanline method fgetpos(m_fd, &m_filepos); return true; } bool FitsOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { if (m_spec.width == 0 && m_spec.height == 0) return true; if (y > m_spec.height) { error ("Attempt to write too many scanlines to %s", m_filename.c_str()); close (); return false; } data = to_native_scanline (format, data, xstride, m_scratch); std::vector data_tmp (m_spec.scanline_bytes (), 0); memcpy (&data_tmp[0], data, m_spec.scanline_bytes ()); // computing scanline offset long scanline_off = (m_spec.height - y) * m_spec.scanline_bytes (); fseek (m_fd, scanline_off, SEEK_CUR); // in FITS image data is stored in big-endian so we have to switch to // big-endian on little-endian machines if (littleendian ()) { if (m_bitpix == 16) swap_endian ((unsigned short*)&data_tmp[0], data_tmp.size () / sizeof (unsigned short)); else if (m_bitpix == 32) swap_endian ((unsigned int*)&data_tmp[0], data_tmp.size () / sizeof (unsigned int)); else if (m_bitpix == -32) swap_endian ((float*)&data_tmp[0], data_tmp.size () / sizeof (float)); else if (m_bitpix == -64) swap_endian ((double*)&data_tmp[0], data_tmp.size () / sizeof (double)); } size_t byte_count = fwrite (&data_tmp[0], 1, data_tmp.size (), m_fd); fsetpos (m_fd, &m_filepos); //byte_count == data.size --> all written return byte_count == data_tmp.size(); } bool FitsOutput::supports (const std::string &feature) const { // for now we only supports IMAGE extensions if (feature == "multiimage") return true; if (feature == "random_access") return true; return false; } bool FitsOutput::close (void) { if (m_fd) fclose (m_fd); init (); return true; } void FitsOutput::create_fits_header (void) { std::string header; create_basic_header (header); //we add all keywords stored in ImageSpec to the FITS file for (size_t i = 0; i < m_spec.extra_attribs.size (); ++i) { std::string keyname = m_spec.extra_attribs[i].name().string(); std::string value; TypeDesc attr_format = m_spec.extra_attribs[i].type(); if (attr_format == TypeDesc::STRING) { value = *(const char**)m_spec.extra_attribs[i].data(); } else if (attr_format == TypeDesc::INT) { int val = (*(int*)m_spec.extra_attribs[i].data()); value = num2str ((float)val); } else if (attr_format == TypeDesc::FLOAT) { float val = (*(float*)m_spec.extra_attribs[i].data()); value = num2str (val); } // Comment, History and Hierarch attributes contains multiple line of // COMMENT, HISTORY and HIERARCH keywords, so we have to split them before // adding to the file std::vector values; if (keyname == "Comment" || keyname == "History" || keyname == "Hierarch") { pystring::split (value, values, m_sep); for (size_t i = 0; i < values.size(); ++i) header += create_card (keyname, values[i]); continue; } // FITS use Date keyword for dates so we convert our DateTime attribute // to Date format before adding it to the FITS file if (keyname == "DateTime") { keyname = "Date"; value = Strutil::format ("%04u-%02u-%02uT%02u:%02u:%02u", atoi(&value[0]), atoi(&value[5]), atoi(&value[8]), atoi(&value[11]), atoi(&value[14]), atoi(&value[17])); } header += create_card (keyname, value); } header += "END"; // header size must be multiple of HEADER_SIZE const int hsize = HEADER_SIZE - header.size () % HEADER_SIZE; if (hsize) header.resize (header.size () + hsize, ' '); size_t byte_count = fwrite (&header[0], 1, header.size (), m_fd); if (byte_count != header.size ()) { // FIXME Bad Write error ("Bad header write (err %d)", byte_count); } } void FitsOutput::create_basic_header (std::string &header) { // the first word in the header is SIMPLE, that informs if given // file is standard FITS file (T) or isn't (F) // we always set this value for T std::string key; if (m_simple) { header += create_card ("SIMPLE", "T"); m_simple = false; } else header += create_card ("XTENSION", "IMAGE "); // next, we add BITPIX value that represent how many bpp we need switch (m_spec.format.basetype) { case TypeDesc::CHAR: case TypeDesc::UCHAR: m_bitpix = 8; break; case TypeDesc::SHORT: case TypeDesc::USHORT: m_bitpix = 16; break; case TypeDesc::INT: case TypeDesc::UINT: m_bitpix = 32; break; case TypeDesc::HALF: case TypeDesc::FLOAT: m_bitpix = -32; break; case TypeDesc::DOUBLE: m_bitpix = -64; break; default: m_bitpix = -32; // punt: default to 32 bit float break; } header += create_card ("BITPIX", num2str (m_bitpix)); // NAXIS inform how many dimension have the image. // we deal only with 2D images so this value is always set to 2 int axes = 0; if (m_spec.width != 0 || m_spec.height != 0) axes = 2; header += create_card ("NAXIS", num2str (axes)); // now we save NAXIS1 and NAXIS2 // this keywords represents width and height header += create_card ("NAXIS1", num2str (m_spec.width)); header += create_card ("NAXIS2", num2str (m_spec.height)); } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/fits.imageio/CMakeLists.txt0000644000175000017500000000014512271062644022226 0ustar mfvmfvadd_oiio_plugin (fitsinput.cpp fitsoutput.cpp fits_pvt.cpp ../libutil/pystring.cpp) openimageio-1.3.12~dfsg0.orig/src/testtex/0000755000175000017500000000000012271062644016610 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/testtex/testtex.cpp0000644000175000017500000011723112271062644021021 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #include #include "argparse.h" #include "imageio.h" #include "ustring.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "imagebufalgo_util.h" #include "texture.h" #include "fmath.h" #include "filesystem.h" #include "sysutil.h" #include "strutil.h" #include "timer.h" #include "../libtexture/imagecache_pvt.h" OIIO_NAMESPACE_USING static std::vector filenames; static std::string output_filename = "out.exr"; static bool verbose = false; static int nthreads = 0; static int threadtimes = 0; static int output_xres = 512, output_yres = 512; static std::string dataformatname = "half"; static float sscale = 1, tscale = 1; static float sblur = 0, tblur = -1; static float width = 1; static std::string wrapmodes ("periodic"); static int anisotropic = -1; static int iters = 1; static int autotile = 0; static bool automip = false; static bool dedup = true; static bool test_construction = false; static bool test_gettexels = false; static bool test_getimagespec = false; static bool filtertest = false; static TextureSystem *texsys = NULL; static std::string searchpath; static int blocksize = 1; static bool nowarp = false; static bool tube = false; static bool use_handle = false; static float cachesize = -1; static int maxfiles = -1; static float missing[4] = {-1, 0, 0, 1}; static float fill = -1; // -1 signifies unset static float scalefactor = 1.0f; static Imath::V3f offset (0,0,0); static bool nountiled = false; static bool nounmipped = false; static bool gray_to_rgb = false; static bool resetstats = false; static bool testhash = false; static bool wedge = false; static int ntrials = 1; static int testicwrite = 0; static Imath::M33f xform; void *dummyptr; typedef void (*Mapping2D)(int,int,float&,float&,float&,float&,float&,float&); typedef void (*Mapping3D)(int,int,Imath::V3f&,Imath::V3f&,Imath::V3f&,Imath::V3f &); static int parse_files (int argc, const char *argv[]) { for (int i = 0; i < argc; i++) filenames.push_back (ustring(argv[i])); return 0; } static void getargs (int argc, const char *argv[]) { TextureOptions opt; // to figure out defaults anisotropic = opt.anisotropic; bool help = false; ArgParse ap; ap.options ("Usage: testtex [options] inputfile", "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose status messages", "-o %s", &output_filename, "Output test image", "-d %s", &dataformatname, "Set the output data format to one of:" "uint8, sint8, uint10, uint12, uint16, sint16, half, float, double", "--res %d %d", &output_xres, &output_yres, "Resolution of output test image", "--iters %d", &iters, "Iterations for time trials", "--threads %d", &nthreads, "Number of threads (default 0 = #cores)", "--blur %f", &sblur, "Add blur to texture lookup", "--stblur %f %f", &sblur, &tblur, "Add blur (s, t) to texture lookup", "--width %f", &width, "Multiply filter width of texture lookup", "--fill %f", &fill, "Set fill value for missing channels", "--wrap %s", &wrapmodes, "Set wrap mode (default, black, clamp, periodic, mirror, overscan)", "--aniso %d", &anisotropic, Strutil::format("Set max anisotropy (default: %d)", anisotropic).c_str(), "--missing %f %f %f", &missing[0], &missing[1], &missing[2], "Specify missing texture color", "--autotile %d", &autotile, "Set auto-tile size for the image cache", "--automip", &automip, "Set auto-MIPmap for the image cache", "--blocksize %d", &blocksize, "Set blocksize (n x n) for batches", "--handle", &use_handle, "Use texture handle rather than name lookup", "--searchpath %s", &searchpath, "Search path for files", "--filtertest", &filtertest, "Test the filter sizes", "--nowarp", &nowarp, "Do not warp the image->texture mapping", "--tube", &tube, "Make a tube projection", "--ctr", &test_construction, "Test TextureOpt construction time", "--gettexels", &test_gettexels, "Test TextureSystem::get_texels", "--getimagespec", &test_getimagespec, "Test TextureSystem::get_imagespec", "--offset %f %f %f", &offset[0], &offset[1], &offset[2], "Offset texture coordinates", "--scalest %f %f", &sscale, &tscale, "Scale texture lookups (s, t)", "--cachesize %f", &cachesize, "Set cache size, in MB", "--nodedup %!", &dedup, "Turn off de-duplication", "--scale %f", &scalefactor, "Scale intensities", "--maxfiles %d", &maxfiles, "Set maximum open files", "--nountiled", &nountiled, "Reject untiled images", "--nounmipped", &nounmipped, "Reject unmipped images", "--graytorgb", &gray_to_rgb, "Convert gratscale textures to RGB", "--resetstats", &resetstats, "Print and reset statistics on each iteration", "--testhash", &testhash, "Test the tile hashing function", "--threadtimes %d", &threadtimes, "Do thread timings (arg = workload profile)", "--trials %d", &ntrials, "Number of trials for timings", "--wedge", &wedge, "Wedge test", "--testicwrite %d", &testicwrite, "Test ImageCache write ability (1=seeded, 2=generated)", NULL); if (ap.parse (argc, argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } if (filenames.size() < 1 && !test_construction && !test_getimagespec && !testhash) { std::cerr << "testtex: Must have at least one input file\n"; ap.usage(); exit (EXIT_FAILURE); } } static void initialize_opt (TextureOpt &opt, int nchannels) { opt.sblur = sblur; opt.tblur = tblur >= 0.0f ? tblur : sblur; opt.rblur = sblur; opt.swidth = width; opt.twidth = width; opt.rwidth = width; opt.nchannels = nchannels; opt.fill = (fill >= 0.0f) ? fill : 1.0f; if (missing[0] >= 0) opt.missingcolor = (float *)&missing; TextureOpt::parse_wrapmodes (wrapmodes.c_str(), opt.swrap, opt.twrap); opt.rwrap = opt.swrap; opt.anisotropic = anisotropic; } static void test_gettextureinfo (ustring filename) { bool ok; int res[2] = {0}; ok = texsys->get_texture_info (filename, 0, ustring("resolution"), TypeDesc(TypeDesc::INT,2), res); std::cerr << "Result of get_texture_info resolution = " << ok << ' ' << res[0] << 'x' << res[1] << "\n"; int chan = 0; ok = texsys->get_texture_info (filename, 0, ustring("channels"), TypeDesc::INT, &chan); std::cerr << "Result of get_texture_info channels = " << ok << ' ' << chan << "\n"; float fchan = 0; ok = texsys->get_texture_info (filename, 0, ustring("channels"), TypeDesc::FLOAT, &fchan); std::cerr << "Result of get_texture_info channels = " << ok << ' ' << fchan << "\n"; int dataformat = 0; ok = texsys->get_texture_info (filename, 0, ustring("format"), TypeDesc::INT, &dataformat); std::cerr << "Result of get_texture_info data format = " << ok << ' ' << TypeDesc((TypeDesc::BASETYPE)dataformat).c_str() << "\n"; const char *datetime = NULL; ok = texsys->get_texture_info (filename, 0, ustring("DateTime"), TypeDesc::STRING, &datetime); std::cerr << "Result of get_texture_info datetime = " << ok << ' ' << (datetime ? datetime : "") << "\n"; const char *texturetype = NULL; ok = texsys->get_texture_info (filename, 0, ustring("textureformat"), TypeDesc::STRING, &texturetype); std::cerr << "Texture type is " << ok << ' ' << (texturetype ? texturetype : "") << "\n"; std::cerr << "\n"; } static void adjust_spec (ImageSpec &outspec, const std::string &dataformatname) { if (! dataformatname.empty()) { if (dataformatname == "uint8") outspec.set_format (TypeDesc::UINT8); else if (dataformatname == "int8") outspec.set_format (TypeDesc::INT8); else if (dataformatname == "uint10") { outspec.attribute ("oiio:BitsPerSample", 10); outspec.set_format (TypeDesc::UINT16); } else if (dataformatname == "uint12") { outspec.attribute ("oiio:BitsPerSample", 12); outspec.set_format (TypeDesc::UINT16); } else if (dataformatname == "uint16") outspec.set_format (TypeDesc::UINT16); else if (dataformatname == "int16") outspec.set_format (TypeDesc::INT16); else if (dataformatname == "half") outspec.set_format (TypeDesc::HALF); else if (dataformatname == "float") outspec.set_format (TypeDesc::FLOAT); else if (dataformatname == "double") outspec.set_format (TypeDesc::DOUBLE); outspec.channelformats.clear (); } } inline Imath::V3f warp (float x, float y, const Imath::M33f &xform) { Imath::V3f coord (x, y, 1.0f); coord *= xform; coord[0] *= 1/(1+2*std::max (-0.5f, coord[1])); return coord; } inline Imath::V3f warp (float x, float y, float z, const Imath::M33f &xform) { Imath::V3f coord (x, y, z); coord *= xform; coord[0] *= 1/(1+2*std::max (-0.5f, coord[1])); return coord; } inline Imath::V2f warp_coord (float x, float y) { Imath::V3f coord = warp (x/output_xres, y/output_yres, xform); coord.x *= sscale; coord.y *= tscale; coord += offset; return Imath::V2f (coord.x, coord.y); } // Just map pixels to [0,1] st space static void map_default (int x, int y, float &s, float &t, float &dsdx, float &dtdx, float &dsdy, float &dtdy) { s = float(x+0.5f)/output_xres * sscale + offset[0]; t = float(y+0.5f)/output_yres * tscale + offset[1]; dsdx = 1.0f/output_xres * sscale; dtdx = 0.0f; dsdy = 0.0f; dtdy = 1.0f/output_yres * tscale; } static void map_warp (int x, int y, float &s, float &t, float &dsdx, float &dtdx, float &dsdy, float &dtdy) { const Imath::V2f coord = warp_coord (x+0.5f, y+0.5f); const Imath::V2f coordx = warp_coord (x+1.5f, y+0.5f); const Imath::V2f coordy = warp_coord (x+0.5f, y+1.5f); s = coord[0]; t = coord[1]; dsdx = coordx[0] - coord[0]; dtdx = coordx[1] - coord[1]; dsdy = coordy[0] - coord[0]; dtdy = coordy[1] - coord[1]; } static void map_tube (int x, int y, float &s, float &t, float &dsdx, float &dtdx, float &dsdy, float &dtdy) { float xt = float(x+0.5f)/output_xres - 0.5f; float dxt_dx = 1.0f/output_xres; float yt = float(y+0.5f)/output_yres - 0.5f; float dyt_dy = 1.0f/output_yres; float theta = atan2f (yt, xt); // See OSL's Dual2 for partial derivs of // atan2, hypot, and 1/x double denom = 1.0 / (xt*xt + yt*yt); double dtheta_dx = yt*dxt_dx * denom; double dtheta_dy = -xt*dyt_dy * denom; s = float(4.0 * theta / (2.0 * M_PI)); dsdx = float(4.0 * dtheta_dx / (2.0 * M_PI)); dsdy = float(4.0 * dtheta_dy / (2.0 * M_PI)); double h = hypot(xt,yt); double dh_dx = xt*dxt_dx / h; double dh_dy = yt*dyt_dy / h; h *= M_SQRT2; dh_dx *= M_SQRT2; dh_dy *= M_SQRT2; double hinv = 1.0 / h; t = float(hinv); dtdx = float(hinv * (-hinv * dh_dx)); dtdy = float(hinv * (-hinv * dh_dy)); } // To test filters, we always sample at the center of the image, and // keep the minor axis of the filter at 1/256, but we vary the // eccentricity (i.e. major axis length) as we go left (1) to right // (32), and vary the angle as we go top (0) to bottom (2pi). // // If filtering is correct, all pixels should sample from the same MIP // level because they have the same minor axis (1/256), regardless of // eccentricity or angle. If we specify a texture that has a // distinctive color at the 256-res level, and something totally // different at the 512 and 128 levels, it should be easy to verify that // we aren't over-filtering or under-filtering by selecting the wrong // MIP level. (Though of course, there are other kinds of mistakes we // could be making, such as computing the wrong eccentricity or angle.) static void map_filtertest (int x, int y, float &s, float &t, float &dsdx, float &dtdx, float &dsdy, float &dtdy) { float minoraxis = 1.0f/256; float majoraxis = minoraxis * lerp (1.0f, 32.0f, (float)x/(output_xres-1)); float angle = (float)(2.0 * M_PI * (double)y/(output_yres-1)); float sinangle, cosangle; sincos (angle, &sinangle, &cosangle); s = 0.5f; t = 0.5f; dsdx = minoraxis * cosangle; dtdx = minoraxis * sinangle; dsdy = -majoraxis * sinangle; dtdy = majoraxis * cosangle; } void map_default_3D (int x, int y, Imath::V3f &P, Imath::V3f &dPdx, Imath::V3f &dPdy, Imath::V3f &dPdz) { P[0] = (float)(x+0.5f)/output_xres * sscale; P[1] = (float)(y+0.5f)/output_yres * tscale; P[2] = 0.5f * sscale; P += offset; dPdx[0] = 1.0f/output_xres * sscale; dPdx[1] = 0; dPdx[2] = 0; dPdy[0] = 0; dPdy[1] = 1.0f/output_yres * tscale; dPdy[2] = 0; dPdz.setValue (0,0,0); } void map_warp_3D (int x, int y, Imath::V3f &P, Imath::V3f &dPdx, Imath::V3f &dPdy, Imath::V3f &dPdz) { Imath::V3f coord = warp ((float)x/output_xres, (float)y/output_yres, 0.5, xform); coord.x *= sscale; coord.y *= tscale; coord += offset; Imath::V3f coordx = warp ((float)(x+1)/output_xres, (float)y/output_yres, 0.5, xform); coordx.x *= sscale; coordx.y *= tscale; coordx += offset; Imath::V3f coordy = warp ((float)x/output_xres, (float)(y+1)/output_yres, 0.5, xform); coordy.x *= sscale; coordy.y *= tscale; coordy += offset; P = coord; dPdx = coordx - coord; dPdy = coordy - coord; dPdz.setValue (0,0,0); } void plain_tex_region (ImageBuf &image, ustring filename, Mapping2D mapping, ROI roi) { TextureSystem::Perthread *perthread_info = texsys->get_perthread_info (); TextureSystem::TextureHandle *texture_handle = texsys->get_texture_handle (filename); int nchannels = image.nchannels(); TextureOpt opt; initialize_opt (opt, nchannels); float *result = ALLOCA (float, nchannels); for (ImageBuf::Iterator p (image, roi); ! p.done(); ++p) { float s, t, dsdx, dtdx, dsdy, dtdy; mapping (p.x(), p.y(), s, t, dsdx, dtdx, dsdy, dtdy); // Call the texture system to do the filtering. bool ok; if (use_handle) ok = texsys->texture (texture_handle, perthread_info, opt, s, t, dsdx, dtdx, dsdy, dtdy, result); else ok = texsys->texture (filename, opt, s, t, dsdx, dtdx, dsdy, dtdy, result); if (! ok) { std::string e = texsys->geterror (); if (! e.empty()) std::cerr << "ERROR: " << e << "\n"; } // Save filtered pixels back to the image. for (int i = 0; i < nchannels; ++i) result[i] *= scalefactor; image.setpixel (p.x(), p.y(), result); } } void test_plain_texture (Mapping2D mapping) { std::cerr << "Testing 2d texture " << filenames[0] << ", output = " << output_filename << "\n"; const int nchannels = 4; ImageSpec outspec (output_xres, output_yres, nchannels, TypeDesc::HALF); adjust_spec (outspec, dataformatname); ImageBuf image (outspec); ImageBufAlgo::zero (image); ustring filename = filenames[0]; for (int iter = 0; iter < iters; ++iter) { if (iters > 1 && filenames.size() > 1) { // Use a different filename for each iteration int texid = std::min (iter, (int)filenames.size()-1); filename = (filenames[texid]); std::cerr << "iter " << iter << " file " << filename << "\n"; } ImageBufAlgo::parallel_image (boost::bind(plain_tex_region, boost::ref(image), filename, mapping, _1), get_roi(image.spec()), nthreads); if (resetstats) { std::cout << texsys->getstats(2) << "\n"; texsys->reset_stats (); } } if (! image.write (output_filename)) std::cerr << "Error writing " << output_filename << " : " << image.geterror() << "\n"; } void tex3d_region (ImageBuf &image, ustring filename, Mapping3D mapping, ROI roi) { TextureSystem::Perthread *perthread_info = texsys->get_perthread_info (); TextureSystem::TextureHandle *texture_handle = texsys->get_texture_handle (filename); int nchannels = image.nchannels(); TextureOpt opt; initialize_opt (opt, nchannels); opt.fill = (fill >= 0.0f) ? fill : 0.0f; // opt.swrap = opt.twrap = opt.rwrap = TextureOpt::WrapPeriodic; float *result = ALLOCA (float, nchannels); for (ImageBuf::Iterator p (image, roi); ! p.done(); ++p) { Imath::V3f P, dPdx, dPdy, dPdz; mapping (p.x(), p.y(), P, dPdx, dPdy, dPdz); // Call the texture system to do the filtering. bool ok = texsys->texture3d (texture_handle, perthread_info, opt, P, dPdx, dPdy, dPdz, result); if (! ok) { std::string e = texsys->geterror (); if (! e.empty()) std::cerr << "ERROR: " << e << "\n"; } // Save filtered pixels back to the image. for (int i = 0; i < nchannels; ++i) result[i] *= scalefactor; image.setpixel (p.x(), p.y(), result); } } void test_texture3d (ustring filename, Mapping3D mapping) { std::cerr << "Testing 3d texture " << filename << ", output = " << output_filename << "\n"; const int nchannels = 4; ImageSpec outspec (output_xres, output_yres, nchannels, TypeDesc::HALF); adjust_spec (outspec, dataformatname); ImageBuf image (outspec); ImageBufAlgo::zero (image); for (int iter = 0; iter < iters; ++iter) { // Trick: switch to second texture, if given, for second iteration if (iter && filenames.size() > 1) filename = filenames[1]; ImageBufAlgo::parallel_image (boost::bind(tex3d_region, boost::ref(image), filename, mapping, _1), get_roi(image.spec()), nthreads); } if (! image.write (output_filename)) std::cerr << "Error writing " << output_filename << " : " << image.geterror() << "\n"; } static void test_shadow (ustring filename) { } static void test_environment (ustring filename) { } static void test_getimagespec_gettexels (ustring filename) { ImageSpec spec; int miplevel = 0; if (! texsys->get_imagespec (filename, 0, spec)) { std::cerr << "Could not get spec for " << filename << "\n"; std::string e = texsys->geterror (); if (! e.empty()) std::cerr << "ERROR: " << e << "\n"; return; } if (! test_gettexels) return; int w = spec.width / std::max(1,2<= 0) opt.missingcolor.init ((float *)&missing, 0); std::vector tmp (w*h*spec.nchannels); bool ok = texsys->get_texels (filename, opt, miplevel, spec.x+w/2, spec.x+w/2+w, spec.y+h/2, spec.y+h/2+h, 0, 1, postagespec.format, &tmp[0]); if (! ok) std::cerr << texsys->geterror() << "\n"; for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) { imagesize_t offset = (y*w + x) * spec.nchannels; buf.setpixel (x, y, &tmp[offset]); } buf.write ("postage.exr"); } static void test_hash () { std::vector fourbits (1<<4, 0); std::vector eightbits (1<<8, 0); std::vector sixteenbits (1<<16, 0); std::vector highereightbits (1<<8, 0); const size_t iters = 1000000; const int res = 4*1024; // Simulate tiles from a 4k image const int tilesize = 64; const int nfiles = iters / ((res/tilesize)*(res/tilesize)); std::cout << "Testing hashing with " << nfiles << " files of " << res << 'x' << res << " with " << tilesize << 'x' << tilesize << " tiles:\n"; ImageCache *imagecache = ImageCache::create (); // Set up the ImageCacheFiles outside of the timing loop using OIIO::pvt::ImageCacheImpl; using OIIO::pvt::ImageCacheFile; using OIIO::pvt::ImageCacheFileRef; std::vector icf; for (int f = 0; f < nfiles; ++f) { ustring filename = ustring::format ("%06d.tif", f); icf.push_back (new ImageCacheFile(*(ImageCacheImpl *)imagecache, NULL, filename)); } // First, just try to do raw timings of the hash Timer timer; size_t i = 0, hh = 0; for (int f = 0; f < nfiles; ++f) { for (int y = 0; y < res; y += tilesize) { for (int x = 0; x < res; x += tilesize, ++i) { OIIO::pvt::TileID id (*icf[f], 0, 0, x, y, 0); size_t h = id.hash(); hh += h; } } } std::cout << "hh = " << hh << "\n"; double time = timer(); double rate = (i/1.0e6) / time; std::cout << "Hashing rate: " << Strutil::format ("%3.2f", rate) << " Mhashes/sec\n"; // Now, check the quality of the hash by looking at the low 4, 8, and // 16 bits and making sure that they divide into hash buckets fairly // evenly. i = 0; for (int f = 0; f < nfiles; ++f) { for (int y = 0; y < res; y += tilesize) { for (int x = 0; x < res; x += tilesize, ++i) { OIIO::pvt::TileID id (*icf[f], 0, 0, x, y, 0); size_t h = id.hash(); ++ fourbits[h & 0xf]; ++ eightbits[h & 0xff]; ++ highereightbits[(h>>24) & 0xff]; ++ sixteenbits[h & 0xffff]; // if (i < 16) std::cout << Strutil::format("%llx\n", h); } } } size_t min, max; min = std::numeric_limits::max(); max = 0; for (int i = 0; i < 16; ++i) { if (fourbits[i] < min) min = fourbits[i]; if (fourbits[i] > max) max = fourbits[i]; } std::cout << "4-bit hash buckets range from " << min << " to " << max << "\n"; min = std::numeric_limits::max(); max = 0; for (int i = 0; i < 256; ++i) { if (eightbits[i] < min) min = eightbits[i]; if (eightbits[i] > max) max = eightbits[i]; } std::cout << "8-bit hash buckets range from " << min << " to " << max << "\n"; min = std::numeric_limits::max(); max = 0; for (int i = 0; i < 256; ++i) { if (highereightbits[i] < min) min = highereightbits[i]; if (highereightbits[i] > max) max = highereightbits[i]; } std::cout << "higher 8-bit hash buckets range from " << min << " to " << max << "\n"; min = std::numeric_limits::max(); max = 0; for (int i = 0; i < (1<<16); ++i) { if (sixteenbits[i] < min) min = sixteenbits[i]; if (sixteenbits[i] > max) max = sixteenbits[i]; } std::cout << "16-bit hash buckets range from " << min << " to " << max << "\n"; std::cout << "\n"; ImageCache::destroy (imagecache); } static const char *workload_names[] = { /*0*/ "None", /*1*/ "Everybody accesses the same spot in one file (handles)", /*2*/ "Everybody accesses the same spot in one file", /*3*/ "Coherent access, one file, each thread in similar spots", /*4*/ "Coherent access, one file, each thread in different spots", /*5*/ "Coherent access, many files, each thread in similar spots", /*6*/ "Coherent access, many files, each thread in different spots", /*7*/ "Coherent access, many files, partially overlapping texture sets", NULL }; void do_tex_thread_workout (int iterations, int mythread) { int nfiles = (int) filenames.size(); float s = 0.1f, t = 0.1f; const int nchannels = 3; float result[nchannels]; TextureOpt opt; initialize_opt (opt, nchannels); TextureSystem::Perthread *perthread_info = texsys->get_perthread_info (); TextureSystem::TextureHandle *texture_handle = texsys->get_texture_handle (filenames[0]); int pixel, whichfile = 0; ImageSpec spec0; texsys->get_imagespec (filenames[0], 0, spec0); // Compute a filter size that's between the first and second MIP levels. float fw = (1.0f / spec0.width) * 1.5f; float fh = (1.0f / spec0.height) * 1.5f; float dsdx = fw, dtdx = 0.0f, dsdy = 0.0f, dtdy = fh; for (int i = 0; i < iterations; ++i) { pixel = i; bool ok = false; // Several different texture access patterns switch (threadtimes) { case 1: // Workload 1: Speed of light: Static texture access (same // texture coordinates all the time, one file), with handles // and per-thread data already queried only once rather than // per-call. ok = texsys->texture (texture_handle, perthread_info, opt, s, t, dsdx, dtdx, dsdy, dtdy, result); break; case 2: // Workload 2: Static texture access, with filenames. ok = texsys->texture (filenames[0], opt, s, t, dsdx, dtdx, dsdy, dtdy, result); break; case 3: case 4: // Workload 3: One file, coherent texture coordinates. // // Workload 4: Each thread starts with a different texture // coordinate offset, so likely are not simultaneously // accessing the very same tile as the other threads. if (threadtimes == 4) pixel += 57557*mythread; break; case 5: case 6: // Workload 5: Coherent texture coordinates, but access // a series of textures at each coordinate. // // Workload 6: Each thread starts with a different texture // coordinate offset, so likely are not simultaneously // accessing the very same tile as the other threads. whichfile = i % nfiles; pixel = i / nfiles; if (threadtimes == 6) pixel += 57557*mythread; break; case 7: // Workload 7: Coherent texture coordinates, but access // a series of textures at each coordinate, which partially // overlap with other threads. { int file = i % 8; if (file < 2) // everybody accesses the first 2 files whichfile = std::min (file, nfiles-1); else // and a slowly changing set of 6 others whichfile = (file+11*mythread+i/1000) % nfiles; pixel = i / nfiles; pixel += 57557*mythread; } break; default: ASSERT_MSG (0, "Unkonwn thread work pattern %d", threadtimes); } if (! ok) { s = (((2*pixel) % spec0.width) + 0.5f) / spec0.width; t = (((2*((2*pixel) / spec0.width)) % spec0.height) + 0.5f) / spec0.height; ok = texsys->texture (filenames[whichfile], opt, s, t, dsdx, dtdx, dsdy, dtdy, result); } if (! ok) { std::cerr << "Unexpected error: " << texsys->geterror() << "\n"; return; } // Do some pointless work, to simulate that in a real app, there // would be operations interspersed with texture accesses. for (int j = 0; j < 30; ++j) for (int c = 0; c < nchannels; ++c) result[c] = cosf (result[c]); } // Force the compiler to not optimize away the "other work" for (int c = 0; c < nchannels; ++c) ASSERT (! isnan(result[c])); } // Launch numthreads threads each of which performs a workout of texture // accesses. void launch_tex_threads (int numthreads, int iterations) { texsys->invalidate_all (true); boost::thread_group threads; for (int i = 0; i < numthreads; ++i) { threads.create_thread (boost::bind(do_tex_thread_workout,iterations,i)); } ASSERT ((int)threads.size() == numthreads); threads.join_all (); } class GridImageInput : public ImageInput { public: GridImageInput () : m_miplevel(-1) { } virtual ~GridImageInput () { close(); } virtual const char * format_name (void) const { return "grid"; } virtual bool valid_file (const std::string &filename) const { return true; } virtual bool open (const std::string &name, ImageSpec &newspec) { return seek_subimage (0, 0, newspec); } virtual bool close () { return true; } virtual int current_miplevel (void) const { return m_miplevel; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (subimage > 0) return false; if (miplevel > 0 && automip /* if automip is on, don't generate MIP */) return false; if (miplevel == m_miplevel) return true; int res = 512; res >>= miplevel; if (res == 0) return false; m_spec = ImageSpec (res, res, 3, TypeDesc::FLOAT); m_spec.tile_width = std::min (64, res); m_spec.tile_height = std::min (64, res); m_spec.tile_depth = 1; newspec = m_spec; m_miplevel = miplevel; return true; } virtual bool read_native_scanline (int y, int z, void *data) { return false; } virtual bool read_native_tile (int xbegin, int ybegin, int zbegin, void *data) { float *tile = (float *)data; for (int z = zbegin, zend = z+m_spec.tile_depth; z < zend; ++z) for (int y = ybegin, yend = y+m_spec.tile_height; y < yend; ++y) for (int x = xbegin, xend = x+m_spec.tile_width; x < xend; ++x) { tile[0] = float(x)/m_spec.width; tile[2] = float(y)/m_spec.height; tile[1] = (((x/16)&1) == ((y/16)&1)) ? 1.0f/(m_miplevel+1) : 0.05f; tile += m_spec.nchannels; } return true; } private: int m_miplevel; }; ImageInput *make_grid_input () { return new GridImageInput; } void test_icwrite (int testicwrite) { std::cout << "Testing IC write, mode " << testicwrite << "\n"; // The global "shared" ImageCache will be the same one the // TextureSystem uses. ImageCache *ic = ImageCache::create (); // Set up the fake file ane add it int tw = 64, th = 64; // tile width and height int nc = 3; // channels ImageSpec spec (512, 512, nc, TypeDesc::FLOAT); spec.depth = 1; spec.tile_width = tw; spec.tile_height = th; spec.tile_depth = 1; ustring filename (filenames[0]); bool ok = ic->add_file (filename, make_grid_input); if (! ok) std::cout << "ic->add_file error: " << ic->geterror() << "\n"; ASSERT (ok); // Now add all the tiles if it's a seeded map // testicwrite == 1 means to seed the first MIP level using add_tile. // testicwrite == 2 does not use add_tile, but instead will rely on // the make_grid_input custom ImageInput that constructs a pattern // procedurally. if (testicwrite == 1) { std::vector tile (spec.tile_pixels() * spec.nchannels); for (int ty = 0; ty < spec.height; ty += th) { for (int tx = 0; tx < spec.width; tx += tw) { // Construct a tile for (int y = 0; y < th; ++y) for (int x = 0; x < tw; ++x) { int index = (y*tw + x) * nc; int xx = x+tx, yy = y+ty; tile[index+0] = float(xx)/spec.width; tile[index+1] = float(yy)/spec.height; tile[index+2] = (!(xx%10) || !(yy%10)) ? 1.0f : 0.0f; } bool ok = ic->add_tile (filename, 0, 0, tx, ty, 0, TypeDesc::FLOAT, &tile[0]); if (! ok) std::cout << "ic->add_tile error: " << ic->geterror() << "\n"; ASSERT (ok); } } } } int main (int argc, const char *argv[]) { Filesystem::convert_native_arguments (argc, argv); getargs (argc, argv); OIIO::attribute ("threads", nthreads); texsys = TextureSystem::create (); std::cerr << "Created texture system\n"; texsys->attribute ("statistics:level", 2); texsys->attribute ("autotile", autotile); texsys->attribute ("automip", (int)automip); texsys->attribute ("deduplicate", (int)dedup); if (cachesize >= 0) texsys->attribute ("max_memory_MB", cachesize); else texsys->getattribute ("max_memory_MB", TypeDesc::TypeFloat, &cachesize); if (maxfiles >= 0) texsys->attribute ("max_open_files", maxfiles); if (searchpath.length()) texsys->attribute ("searchpath", searchpath); if (nountiled) texsys->attribute ("accept_untiled", 0); if (nounmipped) texsys->attribute ("accept_unmipped", 0); texsys->attribute ("gray_to_rgb", gray_to_rgb); if (test_construction) { Timer t; for (int i = 0; i < 1000000000; ++i) { TextureOpt opt; dummyptr = &opt; // This forces the optimizer to keep the loop } std::cout << "TextureOpt construction: " << t() << " ns\n"; TextureOpt canonical, copy; t.reset(); t.start(); for (int i = 0; i < 1000000000; ++i) { memcpy (©, &canonical, sizeof(TextureOpt)); dummyptr = © // This forces the optimizer to keep the loop } std::cout << "TextureOpt memcpy: " << t() << " ns\n"; } if (testicwrite && filenames.size()) { test_icwrite (testicwrite); } if (test_getimagespec) { Timer t; ImageSpec spec; for (int i = 0; i < iters; ++i) { texsys->get_imagespec (filenames[0], 0, spec); } iters = 0; } if (testhash) { test_hash (); } Imath::M33f scale; scale.scale (Imath::V2f (0.5, 0.5)); Imath::M33f rot; rot.rotate (radians(30.0f)); Imath::M33f trans; trans.translate (Imath::V2f (0.35f, 0.15f)); xform = scale * rot * trans; xform.invert(); if (threadtimes) { const int iterations = 2000000; std::cout << "Workload: " << workload_names[threadtimes] << "\n"; std::cout << "texture cache size = " << cachesize << " MB\n"; std::cout << "hw threads = " << boost::thread::hardware_concurrency() << "\n"; std::cout << "times are best of " << ntrials << " trials\n\n"; std::cout << "threads time (s) efficiency\n"; std::cout << "-------- -------- ----------\n"; if (nthreads == 0) nthreads = boost::thread::hardware_concurrency(); static int threadcounts[] = { 1, 2, 4, 6, 8, 10, 12, 16, 20, 24, 28, 32, 64, 128, 1024, 1<<30 }; float single_thread_time = 0.0f; for (int i = 0; threadcounts[i] <= nthreads; ++i) { int nt = wedge ? threadcounts[i] : nthreads; int its = iterations; // / nt; double range; double t = time_trial (boost::bind(launch_tex_threads,nt,its), ntrials, &range); if (nt == 1) single_thread_time = (float)t; float efficiency = (single_thread_time /*/nt*/) / (float)t; std::cout << Strutil::format ("%2d %8.2f %6.1f%% range %.2f\t(%d iters/thread)\n", nt, t, efficiency*100.0f, range, its); if (! wedge) break; // don't loop if we're not wedging } std::cout << "\n"; } else if (iters > 0 && filenames.size()) { ustring filename (filenames[0]); test_gettextureinfo (filenames[0]); const char *texturetype = "Plain Texture"; texsys->get_texture_info (filename, 0, ustring("texturetype"), TypeDesc::STRING, &texturetype); if (! strcmp (texturetype, "Plain Texture")) { if (nowarp) test_plain_texture (map_default); else if (tube) test_plain_texture (map_tube); else if (filtertest) test_plain_texture (map_filtertest); else test_plain_texture (map_warp); } if (! strcmp (texturetype, "Volume Texture")) { if (nowarp) test_texture3d (filename, map_default_3D); else test_texture3d (filename, map_warp_3D); } if (! strcmp (texturetype, "Shadow")) { test_shadow (filename); } if (! strcmp (texturetype, "Environment")) { test_environment (filename); } test_getimagespec_gettexels (filename); } std::cout << "Memory use: " << Strutil::memformat (Sysutil::memory_used(true)) << "\n"; TextureSystem::destroy (texsys); std::cout << "\nustrings: " << ustring::getstats(false) << "\n\n"; return 0; } openimageio-1.3.12~dfsg0.orig/src/testtex/CMakeLists.txt0000644000175000017500000000035112271062644021347 0ustar mfvmfvset (testtex_srcs testtex.cpp) add_executable (testtex ${testtex_srcs}) set_target_properties (testtex PROPERTIES FOLDER "Tools") link_ilmbase (testtex) target_link_libraries (testtex OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) openimageio-1.3.12~dfsg0.orig/src/png.imageio/0000755000175000017500000000000012271062644017305 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/png.imageio/pngoutput.cpp0000644000175000017500000002112712271062644022061 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include "png_pvt.h" #include "dassert.h" #include "imageio.h" #include "strutil.h" OIIO_PLUGIN_NAMESPACE_BEGIN class PNGOutput : public ImageOutput { public: PNGOutput (); virtual ~PNGOutput (); virtual const char * format_name (void) const { return "png"; } virtual bool supports (const std::string &feature) const { // Support nothing nonstandard return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle png_structp m_png; ///< PNG read structure pointer png_infop m_info; ///< PNG image info structure pointer int m_color_type; ///< PNG color model type bool m_convert_alpha; ///< Do we deassociate alpha? float m_gamma; ///< Gamma to use for alpha conversion std::vector m_scratch; std::vector m_pngtext; // Initialize private members to pre-opened state void init (void) { m_file = NULL; m_png = NULL; m_info = NULL; m_convert_alpha = true; m_gamma = 1.0; m_pngtext.clear (); } // Add a parameter to the output bool put_parameter (const std::string &name, TypeDesc type, const void *data); void finish_image (); }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *png_output_imageio_create () { return new PNGOutput; } // OIIO_EXPORT int png_imageio_version = OIIO_PLUGIN_VERSION; // it's in pnginput.cpp OIIO_EXPORT const char * png_output_extensions[] = { "png", NULL }; OIIO_PLUGIN_EXPORTS_END PNGOutput::PNGOutput () { init (); } PNGOutput::~PNGOutput () { // Close, if not already done. close (); } bool PNGOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } close (); // Close any already-opened file m_spec = userspec; // Stash the spec // If not uint8 or uint16, default to uint8 if (m_spec.format != TypeDesc::UINT8 && m_spec.format != TypeDesc::UINT16) m_spec.set_format (TypeDesc::UINT8); m_file = Filesystem::fopen (name, "wb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } std::string s = PNG_pvt::create_write_struct (m_png, m_info, m_color_type, m_spec); if (s.length ()) { close (); error ("%s", s.c_str ()); return false; } png_init_io (m_png, m_file); png_set_compression_level (m_png, std::max (std::min (m_spec.get_int_attribute ("png:compressionLevel", 6/* medium speed vs size tradeoff */), Z_BEST_COMPRESSION), Z_NO_COMPRESSION)); std::string compression = m_spec.get_string_attribute ("compression"); if (compression.empty ()) { png_set_compression_strategy(m_png, Z_DEFAULT_STRATEGY); } else if (Strutil::iequals (compression, "default")) { png_set_compression_strategy(m_png, Z_DEFAULT_STRATEGY); } else if (Strutil::iequals (compression, "filtered")) { png_set_compression_strategy(m_png, Z_FILTERED); } else if (Strutil::iequals (compression, "huffman")) { png_set_compression_strategy(m_png, Z_HUFFMAN_ONLY); } else if (Strutil::iequals (compression, "rle")) { png_set_compression_strategy(m_png, Z_RLE); } else if (Strutil::iequals (compression, "fixed")) { png_set_compression_strategy(m_png, Z_FIXED); } else { png_set_compression_strategy(m_png, Z_DEFAULT_STRATEGY); } PNG_pvt::write_info (m_png, m_info, m_color_type, m_spec, m_pngtext, m_convert_alpha, m_gamma); return true; } bool PNGOutput::close () { if (m_png) PNG_pvt::finish_image (m_png); PNG_pvt::destroy_write_struct (m_png, m_info); if (m_file) { fclose (m_file); m_file = NULL; } init (); // re-initialize return true; // How can we fail? } template static void deassociateAlpha (T * data, int size, int channels, int alpha_channel, float gamma) { unsigned int max = std::numeric_limits::max(); if (gamma == 1){ for (int x = 0; x < size; ++x, data += channels) if (data[alpha_channel]) for (int c = 0; c < channels; c++) if (c != alpha_channel) { unsigned int f = data[c]; f = (f * max) / data[alpha_channel]; data[c] = (T) std::min (max, f); } } else { for (int x = 0; x < size; ++x, data += channels) if (data[alpha_channel]) { // See associateAlpha() for an explanation. float alpha_deassociate = pow((float)max / data[alpha_channel], gamma); for (int c = 0; c < channels; c++) if (c != alpha_channel) data[c] = static_cast (std::min (max, (unsigned int)(data[c] * alpha_deassociate))); } } } bool PNGOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { y -= m_spec.y; m_spec.auto_stride (xstride, format, spec().nchannels); const void *origdata = data; data = to_native_scanline (format, data, xstride, m_scratch); if (data == origdata) { m_scratch.assign ((unsigned char *)data, (unsigned char *)data+m_spec.scanline_bytes()); data = &m_scratch[0]; } // PNG specifically dictates unassociated (un-"premultiplied") alpha if (m_convert_alpha) { if (m_spec.format == TypeDesc::UINT16) deassociateAlpha ((unsigned short *)data, m_spec.width, m_spec.nchannels, m_spec.alpha_channel, m_gamma); else deassociateAlpha ((unsigned char *)data, m_spec.width, m_spec.nchannels, m_spec.alpha_channel, m_gamma); } // PNG is always big endian if (littleendian() && m_spec.format == TypeDesc::UINT16) swap_endian ((unsigned short *)data, m_spec.width*m_spec.nchannels); if (!PNG_pvt::write_row (m_png, (png_byte *)data)) { error ("PNG library error"); return false; } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/png.imageio/pnginput.cpp0000644000175000017500000002303212271062644021655 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "png_pvt.h" #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "thread.h" #include "strutil.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN class PNGInput : public ImageInput { public: PNGInput () { init(); } virtual ~PNGInput () { close(); } virtual const char * format_name (void) const { return "png"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool open (const std::string &name, ImageSpec &newspec, const ImageSpec &config); virtual bool close (); virtual int current_subimage (void) const { return m_subimage; } virtual bool read_native_scanline (int y, int z, void *data); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle png_structp m_png; ///< PNG read structure pointer png_infop m_info; ///< PNG image info structure pointer int m_bit_depth; ///< PNG bit depth int m_color_type; ///< PNG color model type int m_interlace_type; ///< PNG interlace type std::vector m_buf; ///< Buffer the image pixels int m_subimage; ///< What subimage are we looking at? Imath::Color3f m_bg; ///< Background color int m_next_scanline; bool m_keep_unassociated_alpha; ///< Do not convert unassociated alpha /// Reset everything to initial state /// void init () { m_subimage = -1; m_file = NULL; m_png = NULL; m_info = NULL; m_buf.clear (); m_next_scanline = 0; m_keep_unassociated_alpha = false; } /// Helper function: read the image. /// bool readimg (); /// Extract the background color. /// bool get_background (float *red, float *green, float *blue); }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *png_input_imageio_create () { return new PNGInput; } OIIO_EXPORT int png_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * png_input_extensions[] = { "png", NULL }; OIIO_PLUGIN_EXPORTS_END bool PNGInput::valid_file (const std::string &filename) const { FILE *fd = Filesystem::fopen (filename, "rb"); if (! fd) return false; unsigned char sig[8]; bool ok = (fread (sig, 1, sizeof(sig), fd) == sizeof(sig) && png_sig_cmp (sig, 0, 7) == 0); fclose (fd); return ok; } bool PNGInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; m_subimage = 0; m_file = Filesystem::fopen (name, "rb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } unsigned char sig[8]; if (fread (sig, 1, sizeof(sig), m_file) != sizeof(sig)) { error ("Not a PNG file"); return false; // Read failed } if (png_sig_cmp (sig, 0, 7)) { error ("File failed PNG signature check"); return false; } std::string s = PNG_pvt::create_read_struct (m_png, m_info); if (s.length ()) { close (); error ("%s", s.c_str ()); return false; } png_init_io (m_png, m_file); png_set_sig_bytes (m_png, 8); // already read 8 bytes PNG_pvt::read_info (m_png, m_info, m_bit_depth, m_color_type, m_interlace_type, m_bg, m_spec, m_keep_unassociated_alpha); newspec = spec (); m_next_scanline = 0; return true; } bool PNGInput::open (const std::string &name, ImageSpec &newspec, const ImageSpec &config) { // Check 'config' for any special requests if (config.get_int_attribute("oiio:UnassociatedAlpha", 0) == 1) m_keep_unassociated_alpha = true; return open (name, newspec); } bool PNGInput::readimg () { std::string s = PNG_pvt::read_into_buffer (m_png, m_info, m_spec, m_bit_depth, m_color_type, m_buf); if (s.length ()) { close (); error ("%s", s.c_str ()); return false; } return true; } bool PNGInput::close () { PNG_pvt::destroy_read_struct (m_png, m_info); if (m_file) { fclose (m_file); m_file = NULL; } init(); // Reset to initial state return true; } template static void associateAlpha (T * data, int size, int channels, int alpha_channel, float gamma) { T max = std::numeric_limits::max(); if (gamma == 1) { for (int x = 0; x < size; ++x, data += channels) for (int c = 0; c < channels; c++) if (c != alpha_channel){ unsigned int f = data[c]; data[c] = (f * data[alpha_channel]) / max; } } else { //With gamma correction float inv_max = 1.0 / max; for (int x = 0; x < size; ++x, data += channels) { float alpha_associate = pow(data[alpha_channel]*inv_max, gamma); // We need to transform to linear space, associate the alpha, and // then transform back. That is, if D = data[c], we want // // D' = max * ( (D/max)^(1/gamma) * (alpha/max) ) ^ gamma // // This happens to simplify to something which looks like // multiplying by a nonlinear alpha: // // D' = D * (alpha/max)^gamma for (int c = 0; c < channels; c++) if (c != alpha_channel) data[c] = static_cast(data[c] * alpha_associate); } } } bool PNGInput::read_native_scanline (int y, int z, void *data) { y -= m_spec.y; if (y < 0 || y >= m_spec.height) // out of range scanline return false; if (m_interlace_type != 0) { // Interlaced. Punt and read the whole image if (m_buf.empty ()) readimg (); size_t size = spec().scanline_bytes(); memcpy (data, &m_buf[0] + y * size, size); } else { // Not an interlaced image -- read just one row if (m_next_scanline > y) { // User is trying to read an earlier scanline than the one we're // up to. Easy fix: close the file and re-open. ImageSpec dummyspec; int subimage = current_subimage(); if (! close () || ! open (m_filename, dummyspec) || ! seek_subimage (subimage, dummyspec)) return false; // Somehow, the re-open failed assert (m_next_scanline == 0 && current_subimage() == subimage); } while (m_next_scanline <= y) { // Keep reading until we're read the scanline we really need // std::cerr << "reading scanline " << m_next_scanline << "\n"; std::string s = PNG_pvt::read_next_scanline (m_png, data); if (s.length ()) { close (); error ("%s", s.c_str ()); return false; } ++m_next_scanline; } } // PNG specifically dictates unassociated (un-"premultiplied") alpha. // Convert to associated unless we were requested not to do so. if (m_spec.alpha_channel != -1 && !m_keep_unassociated_alpha) { float gamma = m_spec.get_float_attribute ("oiio:Gamma", 1.0f); if (m_spec.format == TypeDesc::UINT16) associateAlpha ((unsigned short *)data, m_spec.width, m_spec.nchannels, m_spec.alpha_channel, gamma); else associateAlpha ((unsigned char *)data, m_spec.width, m_spec.nchannels, m_spec.alpha_channel, gamma); } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/png.imageio/png_pvt.h0000644000175000017500000004355412271062644021146 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_PNG_PVT_H #define OPENIMAGEIO_PNG_PVT_H #include #include #include #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "strutil.h" #include "filesystem.h" #include "fmath.h" #include "sysutil.h" /* This code has been extracted from the PNG plugin so as to provide access to PNG images embedded within any container format, without redundant code duplication. It's been done in the course of development of the ICO plugin in order to allow reading and writing Vista-style PNG icons. For further information see the following mailing list threads: http://lists.openimageio.org/pipermail/oiio-dev-openimageio.org/2009-April/000586.html http://lists.openimageio.org/pipermail/oiio-dev-openimageio.org/2009-April/000656.html */ OIIO_PLUGIN_NAMESPACE_BEGIN namespace PNG_pvt { /// Initializes a PNG read struct. /// \return empty string on success, error message on failure. /// inline const std::string create_read_struct (png_structp& sp, png_infop& ip) { sp = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (! sp) return "Could not create PNG read structure"; ip = png_create_info_struct (sp); if (! ip) return "Could not create PNG info structure"; // Must call this setjmp in every function that does PNG reads if (setjmp (png_jmpbuf(sp))) return "PNG library error"; // success return ""; } /// Helper function - reads background colour. /// inline bool get_background (png_structp& sp, png_infop& ip, ImageSpec& spec, int& bit_depth, float *red, float *green, float *blue) { if (setjmp (png_jmpbuf (sp))) return false; if (! png_get_valid (sp, ip, PNG_INFO_bKGD)) return false; png_color_16p bg; png_get_bKGD (sp, ip, &bg); if (spec.format == TypeDesc::UINT16) { *red = bg->red / 65535.0; *green = bg->green / 65535.0; *blue = bg->blue / 65535.0; } else if (spec.nchannels < 3 && bit_depth < 8) { if (bit_depth == 1) *red = *green = *blue = (bg->gray ? 1 : 0); else if (bit_depth == 2) *red = *green = *blue = bg->gray / 3.0; else // 4 bits *red = *green = *blue = bg->gray / 15.0; } else { *red = bg->red / 255.0; *green = bg->green / 255.0; *blue = bg->blue / 255.0; } return true; } /// Read information from a PNG file and fill the ImageSpec accordingly. /// inline void read_info (png_structp& sp, png_infop& ip, int& bit_depth, int& color_type, int& interlace_type, Imath::Color3f& bg, ImageSpec& spec, bool keep_unassociated_alpha) { png_read_info (sp, ip); // Auto-convert 1-, 2-, and 4- bit images to 8 bits, palette to RGB, // and transparency to alpha. png_set_expand (sp); // PNG files are naturally big-endian if (littleendian()) png_set_swap (sp); png_read_update_info (sp, ip); png_uint_32 width, height; png_get_IHDR (sp, ip, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); spec = ImageSpec ((int)width, (int)height, png_get_channels (sp, ip), bit_depth == 16 ? TypeDesc::UINT16 : TypeDesc::UINT8); spec.default_channel_names (); int srgb_intent; if (png_get_sRGB (sp, ip, &srgb_intent)) { spec.attribute ("oiio:ColorSpace", "sRGB"); } else { double gamma; if (png_get_gAMA (sp, ip, &gamma)) { spec.attribute ("oiio:Gamma", (float)(1.0f/gamma)); spec.attribute ("oiio:ColorSpace", (gamma == 1) ? "Linear" : "GammaCorrected"); } } png_timep mod_time; if (png_get_tIME (sp, ip, &mod_time)) { std::string date = Strutil::format ("%4d:%02d:%02d %2d:%02d:%02d", mod_time->year, mod_time->month, mod_time->day, mod_time->hour, mod_time->minute, mod_time->second); spec.attribute ("DateTime", date); } png_textp text_ptr; int num_comments = png_get_text (sp, ip, &text_ptr, NULL); if (num_comments) { std::string comments; for (int i = 0; i < num_comments; ++i) { if (Strutil::iequals (text_ptr[i].key, "Description")) spec.attribute ("ImageDescription", text_ptr[i].text); else if (Strutil::iequals (text_ptr[i].key, "Author")) spec.attribute ("Artist", text_ptr[i].text); else if (Strutil::iequals (text_ptr[i].key, "Title")) spec.attribute ("DocumentName", text_ptr[i].text); else spec.attribute (text_ptr[i].key, text_ptr[i].text); } } spec.x = png_get_x_offset_pixels (sp, ip); spec.y = png_get_y_offset_pixels (sp, ip); int unit; png_uint_32 resx, resy; if (png_get_pHYs (sp, ip, &resx, &resy, &unit)) { float scale = 1; if (unit == PNG_RESOLUTION_METER) { // Convert to inches, to match most other formats scale = 2.54 / 100.0; spec.attribute ("ResolutionUnit", "inch"); } else spec.attribute ("ResolutionUnit", "none"); spec.attribute ("XResolution", (float)resx*scale); spec.attribute ("YResolution", (float)resy*scale); } float aspect = (float)png_get_pixel_aspect_ratio (sp, ip); if (aspect != 0 && aspect != 1) spec.attribute ("PixelAspectRatio", aspect); float r, g, b; if (get_background (sp, ip, spec, bit_depth, &r, &g, &b)) { bg = Imath::Color3f (r, g, b); // FIXME -- should we do anything with the background color? } interlace_type = png_get_interlace_type (sp, ip); // PNG files are always "unassociated alpha" but we convert to associated // unless requested otherwise if (keep_unassociated_alpha) spec.attribute ("oiio:UnassociatedAlpha", (int)1); // FIXME -- look for an XMP packet in an iTXt chunk. } /// Reads from an open PNG file into the indicated buffer. /// \return empty string on success, error message on failure. /// inline const std::string read_into_buffer (png_structp& sp, png_infop& ip, ImageSpec& spec, int& bit_depth, int& color_type, std::vector& buffer) { // Must call this setjmp in every function that does PNG reads if (setjmp (png_jmpbuf (sp))) return "PNG library error"; #if 0 // ?? This doesn't seem necessary, but I don't know why // Make the library handle fewer significant bits // png_color_8p sig_bit; // if (png_get_sBIT (sp, ip, &sig_bit)) { // png_set_shift (sp, sig_bit); // } #endif DASSERT (spec.scanline_bytes() == png_get_rowbytes(sp,ip)); buffer.resize (spec.image_bytes()); std::vector row_pointers (spec.height); for (int i = 0; i < spec.height; ++i) row_pointers[i] = &buffer[0] + i * spec.scanline_bytes(); png_read_image (sp, &row_pointers[0]); png_read_end (sp, NULL); // success return ""; } /// Reads the next scanline from an open PNG file into the indicated buffer. /// \return empty string on success, error message on failure. /// inline const std::string read_next_scanline (png_structp& sp, void *buffer) { // Must call this setjmp in every function that does PNG reads if (setjmp (png_jmpbuf (sp))) return "PNG library error"; png_read_row (sp, (png_bytep)buffer, NULL); // success return ""; } /// Destroys a PNG read struct. /// inline void destroy_read_struct (png_structp& sp, png_infop& ip) { if (sp && ip) { png_destroy_read_struct (&sp, &ip, NULL); sp = NULL; ip = NULL; } } /// Initializes a PNG write struct. /// \return empty string on success, C-string error message on failure. /// inline const std::string create_write_struct (png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec) { // Check for things this format doesn't support if (spec.width < 1 || spec.height < 1) return Strutil::format ("Image resolution must be at least 1x1, " "you asked for %d x %d", spec.width, spec.height); if (spec.depth < 1) spec.depth = 1; if (spec.depth > 1) return "PNG does not support volume images (depth > 1)"; switch (spec.nchannels) { case 1 : color_type = PNG_COLOR_TYPE_GRAY; break; case 2 : color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break; case 3 : color_type = PNG_COLOR_TYPE_RGB; break; case 4 : color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; default: return Strutil::format ("PNG only supports 1-4 channels, not %d", spec.nchannels); } sp = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (! sp) return "Could not create PNG write structure"; ip = png_create_info_struct (sp); if (! ip) return "Could not create PNG info structure"; // Must call this setjmp in every function that does PNG writes if (setjmp (png_jmpbuf(sp))) return "PNG library error"; // success return ""; } /// Helper function - writes a single parameter. /// inline bool put_parameter (png_structp& sp, png_infop& ip, const std::string &_name, TypeDesc type, const void *data, std::vector& text) { std::string name = _name; // Things to skip if (Strutil::iequals(name, "planarconfig")) // No choice for PNG files return false; if (Strutil::iequals(name, "compression")) return false; if (Strutil::iequals(name, "ResolutionUnit") || Strutil::iequals(name, "XResolution") || Strutil::iequals(name, "YResolution")) return false; // Remap some names to PNG conventions if (Strutil::iequals(name, "Artist") && type == TypeDesc::STRING) name = "Author"; if ((Strutil::iequals(name, "name") || Strutil::iequals(name, "DocumentName")) && type == TypeDesc::STRING) name = "Title"; if ((Strutil::iequals(name, "description") || Strutil::iequals(name, "ImageDescription")) && type == TypeDesc::STRING) name = "Description"; if (Strutil::iequals(name, "DateTime") && type == TypeDesc::STRING) { png_time mod_time; int year, month, day, hour, minute, second; if (sscanf (*(const char **)data, "%4d:%02d:%02d %2d:%02d:%02d", &year, &month, &day, &hour, &minute, &second) == 6) { mod_time.year = year; mod_time.month = month; mod_time.day = day; mod_time.hour = hour; mod_time.minute = minute; mod_time.second = second; png_set_tIME (sp, ip, &mod_time); return true; } else { return false; } } #if 0 if (Strutil::iequals(name, "ResolutionUnit") && type == TypeDesc::STRING) { const char *s = *(char**)data; bool ok = true; if (Strutil::iequals (s, "none")) PNGSetField (m_tif, PNGTAG_RESOLUTIONUNIT, RESUNIT_NONE); else if (Strutil::iequals (s, "in") || Strutil::iequals (s, "inch")) PNGSetField (m_tif, PNGTAG_RESOLUTIONUNIT, RESUNIT_INCH); else if (Strutil::iequals (s, "cm")) PNGSetField (m_tif, PNGTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER); else ok = false; return ok; } if (Strutil::iequals(name, "ResolutionUnit") && type == TypeDesc::UINT) { PNGSetField (m_tif, PNGTAG_RESOLUTIONUNIT, *(unsigned int *)data); return true; } if (Strutil::iequals(name, "XResolution") && type == TypeDesc::FLOAT) { PNGSetField (m_tif, PNGTAG_XRESOLUTION, *(float *)data); return true; } if (Strutil::iequals(name, "YResolution") && type == TypeDesc::FLOAT) { PNGSetField (m_tif, PNGTAG_YRESOLUTION, *(float *)data); return true; } #endif if (type == TypeDesc::STRING) { png_text t; t.compression = PNG_TEXT_COMPRESSION_NONE; t.key = (char *)ustring(name).c_str(); t.text = *(char **)data; // Already uniquified text.push_back (t); } return false; } /// Writes PNG header according to the ImageSpec. /// inline void write_info (png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec, std::vector& text, bool& convert_alpha, float& gamma) { // Force either 16 or 8 bit integers if (spec.format == TypeDesc::UINT8 || spec.format == TypeDesc::INT8) spec.set_format (TypeDesc::UINT8); else spec.set_format (TypeDesc::UINT16); // best precision available png_set_IHDR (sp, ip, spec.width, spec.height, spec.format.size()*8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_oFFs (sp, ip, spec.x, spec.y, PNG_OFFSET_PIXEL); // PNG specifically dictates unassociated (un-"premultiplied") alpha convert_alpha = spec.alpha_channel != -1 && !spec.get_int_attribute("oiio:UnassociatedAlpha", 0); gamma = spec.get_float_attribute ("oiio:Gamma", 1.0); std::string colorspace = spec.get_string_attribute ("oiio:ColorSpace"); if (Strutil::iequals (colorspace, "Linear")) { png_set_gAMA (sp, ip, 1.0); } else if (Strutil::iequals (colorspace, "GammaCorrected")) { png_set_gAMA (sp, ip, 1.0f/gamma); } else if (Strutil::iequals (colorspace, "sRGB")) { png_set_sRGB_gAMA_and_cHRM (sp, ip, PNG_sRGB_INTENT_ABSOLUTE); } if (false && ! spec.find_attribute("DateTime")) { time_t now; time (&now); struct tm mytm; Sysutil::get_local_time (&now, &mytm); std::string date = Strutil::format ("%4d:%02d:%02d %2d:%02d:%02d", mytm.tm_year+1900, mytm.tm_mon+1, mytm.tm_mday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec); spec.attribute ("DateTime", date); } ImageIOParameter *unit=NULL, *xres=NULL, *yres=NULL; if ((unit = spec.find_attribute("ResolutionUnit", TypeDesc::STRING)) && (xres = spec.find_attribute("XResolution", TypeDesc::FLOAT)) && (yres = spec.find_attribute("YResolution", TypeDesc::FLOAT))) { const char *unitname = *(const char **)unit->data(); const float x = *(const float *)xres->data(); const float y = *(const float *)yres->data(); int unittype = PNG_RESOLUTION_UNKNOWN; float scale = 1; if (Strutil::iequals (unitname, "meter") || Strutil::iequals (unitname, "m")) unittype = PNG_RESOLUTION_METER; else if (Strutil::iequals (unitname, "cm")) { unittype = PNG_RESOLUTION_METER; scale = 100; } else if (Strutil::iequals (unitname, "inch") || Strutil::iequals (unitname, "in")) { unittype = PNG_RESOLUTION_METER; scale = 100.0/2.54; } png_set_pHYs (sp, ip, (png_uint_32)(x*scale), (png_uint_32)(y*scale), unittype); } // Deal with all other params for (size_t p = 0; p < spec.extra_attribs.size(); ++p) put_parameter (sp, ip, spec.extra_attribs[p].name().string(), spec.extra_attribs[p].type(), spec.extra_attribs[p].data(), text); if (text.size()) png_set_text (sp, ip, &text[0], text.size()); png_write_info (sp, ip); png_set_packing (sp); // Pack 1, 2, 4 bit into bytes } /// Writes a scanline. /// inline bool write_row (png_structp& sp, png_byte *data) { if (setjmp (png_jmpbuf(sp))) { //error ("PNG library error"); return false; } png_write_row (sp, data); return true; } /// Helper function - finalizes writing the image. /// inline void finish_image (png_structp& sp) { // Must call this setjmp in every function that does PNG writes if (setjmp (png_jmpbuf(sp))) { //error ("PNG library error"); return; } png_write_end (sp, NULL); } /// Destroys a PNG write struct. /// inline void destroy_write_struct (png_structp& sp, png_infop& ip) { if (sp && ip) { finish_image (sp); png_destroy_write_struct (&sp, &ip); sp = NULL; ip = NULL; } } } // namespace PNG_pvt OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_PNG_PVT_H openimageio-1.3.12~dfsg0.orig/src/png.imageio/CMakeLists.txt0000644000175000017500000000025212271062644022044 0ustar mfvmfvfind_package (PNG) if (PNG_FOUND) include_directories (${PNG_INCLUDE_DIR}) add_oiio_plugin (pnginput.cpp pngoutput.cpp LINK_LIBRARIES ${PNG_LIBRARIES}) endif () openimageio-1.3.12~dfsg0.orig/src/psd.imageio/0000755000175000017500000000000012271062644017307 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/psd.imageio/jpeg_memory_src.cpp0000644000175000017500000000656712271062644023215 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include "version.h" extern "C" { #include #include } namespace { void init_memory_source (j_decompress_ptr cinfo) { } void term_memory_source (j_decompress_ptr cinfo) { } void skip_input (j_decompress_ptr cinfo, long num_bytes) { struct jpeg_source_mgr *src = cinfo->src; if (!num_bytes) return; while (num_bytes > (long)src->bytes_in_buffer) { num_bytes -= (long)src->bytes_in_buffer; (*src->fill_input_buffer)(cinfo); } src->next_input_byte += (size_t)num_bytes; src->bytes_in_buffer -= (size_t)num_bytes; } boolean fill_input (j_decompress_ptr cinfo) { static JOCTET mybuffer[4]; WARNMS(cinfo, JWRN_JPEG_EOF); /* Insert a fake EOI marker */ mybuffer[0] = (JOCTET) 0xFF; mybuffer[1] = (JOCTET) JPEG_EOI; cinfo->src->next_input_byte = mybuffer; cinfo->src->bytes_in_buffer = 2; return TRUE; } } // anon namespace OIIO_PLUGIN_NAMESPACE_BEGIN namespace psd_pvt { void jpeg_memory_src (j_decompress_ptr cinfo, unsigned char *inbuffer, unsigned long insize) { struct jpeg_source_mgr * src; if (inbuffer == NULL || insize == 0) ERREXIT(cinfo, JERR_INPUT_EMPTY); if (cinfo->src == NULL) { cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, (size_t)sizeof(struct jpeg_source_mgr)); } src = cinfo->src; src->init_source = init_memory_source; src->fill_input_buffer = fill_input; src->skip_input_data = skip_input; src->resync_to_restart = jpeg_resync_to_restart; src->term_source = term_memory_source; src->bytes_in_buffer = (size_t) insize; src->next_input_byte = (JOCTET *) inbuffer; } } // namespace psd_pvt OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/psd.imageio/psdoutput.cpp0000644000175000017500000000630212271062644022063 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include "imageio.h" OIIO_PLUGIN_NAMESPACE_BEGIN class PSDOutput : public ImageOutput { public: PSDOutput (); virtual ~PSDOutput (); virtual const char * format_name (void) const { return "psd"; } virtual bool supports (const std::string &feature) const { // Support nothing nonstandard return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: std::string m_filename; ///< Stash the filename std::ofstream m_file; ///< Open image handle // Initialize private members to pre-opened state void init (void) { } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *psd_output_imageio_create () { return new PSDOutput; } OIIO_EXPORT const char * psd_output_extensions[] = { "psd", NULL }; OIIO_PLUGIN_EXPORTS_END PSDOutput::PSDOutput () { init (); } PSDOutput::~PSDOutput () { // Close, if not already done. close (); } bool PSDOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { return false; } bool PSDOutput::close () { init (); return false; } bool PSDOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { return false; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/psd.imageio/jpeg_memory_src.h0000644000175000017500000000430112271062644022642 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_PSD_JPEG_MEMORY_SRC_H #define OPENIMAGEIO_PSD_JPEG_MEMORY_SRC_H extern "C" { #include "jpeglib.h" } OIIO_PLUGIN_NAMESPACE_BEGIN namespace psd_pvt { // This function allows you to read a JPEG from memory using libjpeg. // Newer versions of libjpeg have jpeg_mem_src which has the same functionality. // inbuffer is the buffer that holds the JPEG data // insize is the size of the buffer void jpeg_memory_src (j_decompress_ptr cinfo, unsigned char *inbuffer, unsigned long insize); } // end namespace psd_pvt OIIO_PLUGIN_NAMESPACE_END #endif /* OPENIMAGEIO_PSD_JPEG_MEMORY_SRC_H */ openimageio-1.3.12~dfsg0.orig/src/psd.imageio/psd_pvt.h0000644000175000017500000000445712271062644021151 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_PSD_PVT_H #define OPENIMAGEIO_PSD_PVT_H #include "imageio.h" #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace psd_pvt { struct FileHeader { char signature[4]; uint16_t version; uint16_t channel_count; uint32_t height; uint32_t width; uint16_t depth; uint16_t color_mode; }; struct ColorModeData { uint32_t length; std::string data; }; struct ImageResourceBlock { char signature[4]; uint16_t id; std::string name; uint32_t length; std::streampos pos; }; } // namespace psd_pvt OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_PSD_PVT_H openimageio-1.3.12~dfsg0.orig/src/psd.imageio/CMakeLists.txt0000644000175000017500000000031312271062644022044 0ustar mfvmfvfind_package (JPEG) if (JPEG_FOUND) include_directories (${JPEG_INCLUDE_DIR}) add_oiio_plugin (psdinput.cpp psdoutput.cpp jpeg_memory_src.cpp LINK_LIBRARIES ${JPEG_LIBRARIES}) endif () openimageio-1.3.12~dfsg0.orig/src/psd.imageio/psdinput.cpp0000644000175000017500000016001612271062644021665 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include "psd_pvt.h" #include "jpeg_memory_src.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace psd_pvt; class PSDInput : public ImageInput { public: PSDInput (); virtual ~PSDInput () { close(); } virtual const char * format_name (void) const { return "psd"; } virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool open (const std::string &name, ImageSpec &newspec, const ImageSpec &config); virtual bool close (); virtual int current_subimage () const { return m_subimage; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual bool read_native_scanline (int y, int z, void *data); private: enum ColorMode { ColorMode_Bitmap = 0, ColorMode_Grayscale = 1, ColorMode_Indexed = 2, ColorMode_RGB = 3, ColorMode_CMYK = 4, ColorMode_Multichannel = 7, ColorMode_Duotone = 8, ColorMode_Lab = 9 }; enum Compression { Compression_Raw = 0, Compression_RLE = 1, Compression_ZIP = 2, Compression_ZIP_Predict = 3 }; enum ChannelID { ChannelID_Transparency = -1, ChannelID_LayerMask = -2, ChannelID_UserMask = -3 }; // Image resource loaders to handle loading certain image resources // into ImageSpec struct ResourceLoader { uint16_t resource_id; boost::function load; }; // Map image resource ID to image resource block typedef std::map ImageResourceMap; struct ResolutionInfo { float hRes; int16_t hResUnit; int16_t widthUnit; float vRes; int16_t vResUnit; int16_t heightUnit; enum ResolutionUnit { PixelsPerInch = 1, PixelsPerCentimeter = 2 }; enum Unit { Inches = 1, Centimeters = 2, Points = 3, Picas = 4, Columns = 5 }; }; struct LayerMaskInfo { uint64_t length; std::streampos begin; std::streampos end; struct LayerInfo { uint64_t length; int16_t layer_count; std::streampos begin; std::streampos end; }; LayerInfo layer_info; }; struct ChannelInfo { uint32_t row_length; int16_t channel_id; uint64_t data_length; std::streampos data_pos; uint16_t compression; std::vector rle_lengths; std::vector row_pos; }; struct Layer { uint32_t top, left, bottom, right; uint32_t width, height; uint16_t channel_count; std::vector channel_info; std::map channel_id_map; char bm_key[4]; uint8_t opacity; uint8_t clipping; uint8_t flags; uint32_t extra_length; struct MaskData { uint32_t top, left, bottom, right; uint8_t default_color; uint8_t flags; }; MaskData mask_data; //TODO: layer blending ranges? std::string name; struct AdditionalInfo { char key[4]; uint64_t length; std::streampos pos; }; std::vector additional_info; }; struct GlobalMaskInfo { uint16_t overlay_color_space; uint16_t color_components[4]; uint16_t opacity; int8_t kind; }; struct ImageDataSection { std::vector channel_info; //When the layer count is negative, this is true and indicates that //the first alpha channel should be used as transparency (for the //merged image) bool transparency; }; std::string m_filename; std::ifstream m_file; //Current subimage int m_subimage; //Subimage count (1 + layer count) int m_subimage_count; std::vector m_specs; static const ResourceLoader resource_loaders[]; //This holds the attributes for the merged image (subimage 0) ImageSpec m_composite_attribs; //This holds common attributes that apply to all subimages ImageSpec m_common_attribs; //psd:RawData config option, indicates that the user wants the raw, //unconverted channel data bool m_WantRaw; TypeDesc m_type_desc; //This holds all the ChannelInfos for all subimages //Example: m_channels[subimg][channel] std::vector > m_channels; //Alpha Channel Names, not currently used std::vector m_alpha_names; //Buffers for channel data std::vector m_channel_buffers; //Buffer for RLE conversion std::string m_rle_buffer; //Index of the transparent color, if any (for Indexed color mode only) int16_t m_transparency_index; //Background color double m_background_color[4]; ///< Do not convert unassociated alpha bool m_keep_unassociated_alpha; FileHeader m_header; ColorModeData m_color_data; LayerMaskInfo m_layer_mask_info; std::vector m_layers; GlobalMaskInfo m_global_mask_info; ImageDataSection m_image_data; //Reset to initial state void init (); //File Header bool load_header (); bool read_header (); bool validate_header (); //Color Mode Data bool load_color_data (); bool validate_color_data (); //Image Resources bool load_resources (); bool read_resource (ImageResourceBlock &block); bool validate_resource (ImageResourceBlock &block); //Call the resource_loaders to load the resources into an ImageSpec //m_specs should be resized to m_subimage_count first bool handle_resources (ImageResourceMap &resources); //ResolutionInfo bool load_resource_1005 (uint32_t length); //Alpha Channel Names bool load_resource_1006 (uint32_t length); //Background Color bool load_resource_1010 (uint32_t length); //JPEG thumbnail (Photoshop 4.0) bool load_resource_1033 (uint32_t length); //JPEG thumbnail (Photoshop 5.0) bool load_resource_1036 (uint32_t length); //Transparency index (Indexed color mode) bool load_resource_1047 (uint32_t length); //Exif data 1 bool load_resource_1058 (uint32_t length); //Exif data 3 bool load_resource_1059 (uint32_t length); //XMP metadata bool load_resource_1060 (uint32_t length); //Pixel Aspect Ratio bool load_resource_1064 (uint32_t length); //Load thumbnail resource, used for resources 1033 and 1036 bool load_resource_thumbnail (uint32_t length, bool isBGR); //For thumbnail loading struct thumbnail_error_mgr { jpeg_error_mgr pub; jmp_buf setjmp_buffer; }; METHODDEF (void) thumbnail_error_exit (j_common_ptr cinfo); //Layers bool load_layers (); bool load_layer (Layer &layer); bool load_layer_channels (Layer &layer); bool load_layer_channel (Layer &layer, ChannelInfo &channel_info); bool read_rle_lengths (uint32_t height, std::vector &rle_lengths); //Global Mask Info bool load_global_mask_info (); //Global Additional Layer Info bool load_global_additional (); //Image Data Section bool load_image_data (); void set_type_desc (); //Setup m_specs and m_channels void setup (); void fill_channel_names (ImageSpec &spec, bool transparency); //Read a row of channel data bool read_channel_row (const ChannelInfo &channel_info, uint32_t row, char *data); //Interleave channels (RRRGGGBBB -> RGBRGBRGB). void interleave_row (char *dst); //Convert the channel data to RGB bool convert_to_rgb (char *dst); bool indexed_to_rgb (char *dst); bool bitmap_to_rgb (char *dst); //To add support for other color modes (to be converted to RGB): //-Add a function _to_rgb (char *dst) that uses the raw channel // data in m_channel_buffers[m_subimage] (size is m_spec.nchannels) and // store the RGB data in dst //-Modify validate_header function to not reject that color mode //-Modify convert_to_rgb function to call _to_rgb // Convert from photoshop native alpha to // associated/premultiplied template void removeBackground (T *data, int size, int nchannels, int alpha_channel, double *background) { // RGB = CompRGB - (1 - alpha) * Background; double scale = std::numeric_limits::is_integer ? 1.0/std::numeric_limits::max() : 1.0; for ( ; size; --size, data += nchannels) for (int c = 0; c < nchannels; c++) if (c != alpha_channel) { double alpha = data[alpha_channel] * scale; double f = data[c]; data[c] = T (f - (((1.0 - alpha) * background[c]) / scale)); } } template void unassociateAlpha (T *data, int size, int nchannels, int alpha_channel, double *background) { // RGB = (CompRGB - (1 - alpha) * Background) / alpha double scale = std::numeric_limits::is_integer ? 1.0/std::numeric_limits::max() : 1.0; for ( ; size; --size, data += nchannels) for (int c = 0; c < nchannels; c++) if (c != alpha_channel) { double alpha = data[alpha_channel] * scale; double f = data[c]; if (alpha > 0.0) data[c] = T ((f - (((1.0 - alpha) * background[c]) / scale)) / alpha) ; else data[c] = 0; } } template void associateAlpha (T *data, int size, int nchannels, int alpha_channel) { double scale = std::numeric_limits::is_integer ? 1.0/std::numeric_limits::max() : 1.0; for ( ; size; --size, data += nchannels) for (int c = 0; c < nchannels; c++) if (c != alpha_channel) { double f = data[c]; data[c] = T (f * (data[alpha_channel] * scale)); } } void background_to_assocalpha (int n, void *data); void background_to_unassalpha (int n, void *data); void unassalpha_to_assocalpha (int n, void *data); //Check if m_file is good. If not, set error message and return false. bool check_io (); //This may be a bit inefficient but I think it's worth the convenience. //This takes care of things like reading a 32-bit BE into a 64-bit LE. template bool read_bige (TVariable &value) { TStorage buffer; m_file.read ((char *)&buffer, sizeof(buffer)); if (!bigendian ()) swap_endian (&buffer); // For debugging, numeric_cast will throw if precision is lost: // value = boost::numeric_cast(buffer); value = buffer; return m_file; } int read_pascal_string (std::string &s, uint16_t mod_padding); bool decompress_packbits (const char *src, char *dst, uint16_t packed_length, uint16_t unpacked_length); // These are AdditionalInfo entries that, for PSBs, have an 8-byte length static const char *additional_info_psb[]; static const unsigned int additional_info_psb_count; bool is_additional_info_psb (const char *key); // Channel names and counts for each color mode static const char *mode_channel_names[][4]; static const unsigned int mode_channel_count[]; // Some attributes may apply to only the merged composite. // Others may apply to all subimages. // These functions are intended to be used by image resource loaders. // // Add an attribute to the composite image spec template void composite_attribute (const std::string &name, const T &value) { m_composite_attribs.attribute (name, value); } // Add an attribute to the composite image spec template void composite_attribute (const std::string &name, const TypeDesc &type, const T &value) { m_composite_attribs.attribute (name, type, value); } // Add an attribute to the composite image spec and common image spec template void common_attribute (const std::string &name, const T &value) { m_composite_attribs.attribute (name, value); m_common_attribs.attribute (name, value); } // Add an attribute to the composite image spec and common image spec template void common_attribute (const std::string &name, const TypeDesc &type, const T &value) { m_composite_attribs.attribute (name, type, value); m_common_attribs.attribute (name, type, value); } }; // Image resource loaders // To add an image resource loader, do the following: // 1) Add ADD_LOADER() below // 2) Add a method in PSDInput: // bool load_resource_ (uint32_t length); #define ADD_LOADER(id) {id, boost::bind (&PSDInput::load_resource_##id, _1, _2)} const PSDInput::ResourceLoader PSDInput::resource_loaders[] = { ADD_LOADER(1005), ADD_LOADER(1006), ADD_LOADER(1010), ADD_LOADER(1033), ADD_LOADER(1036), ADD_LOADER(1047), ADD_LOADER(1058), ADD_LOADER(1059), ADD_LOADER(1060), ADD_LOADER(1064) }; #undef ADD_LOADER const char * PSDInput::additional_info_psb[] = { "LMsk", "Lr16", "Lr32", "Layr", "Mt16", "Mt32", "Mtrn", "Alph", "FMsk", "Ink2", "FEid", "FXid", "PxSD" }; const unsigned int PSDInput::additional_info_psb_count = sizeof(additional_info_psb) / sizeof(additional_info_psb[0]); const char * PSDInput::mode_channel_names[][4] = { {"A"}, {"I"}, {"I"}, {"R", "G", "B"}, {"C", "M", "Y", "K"}, {}, {}, {}, {}, {"L", "a", "b"} }; const unsigned int PSDInput::mode_channel_count[] = { 1, 1, 1, 3, 4, 0, 0, 0, 0, 3 }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *psd_input_imageio_create () { return new PSDInput; } OIIO_EXPORT int psd_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * psd_input_extensions[] = { "psd", "pdd", "psb", NULL }; OIIO_PLUGIN_EXPORTS_END PSDInput::PSDInput () { init(); } bool PSDInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; Filesystem::open (m_file, name, std::ios::binary); if (!m_file.is_open ()) { error ("\"%s\": failed to open file", name.c_str()); return false; } // File Header if (!load_header ()) return false; // Color Mode Data if (!load_color_data ()) return false; // Image Resources if (!load_resources ()) return false; // Layers if (!load_layers ()) return false; // Global Mask Info if (!load_global_mask_info ()) return false; // Global Additional Layer Info if (!load_global_additional ()) return false; // Image Data if (!load_image_data ()) return false; // Layer count + 1 for merged composite (Image Data Section) m_subimage_count = m_layers.size () + 1; // Set m_type_desc to the appropriate TypeDesc set_type_desc (); // Setup ImageSpecs and m_channels setup (); if (!seek_subimage (0, 0, newspec)) return false; return true; } bool PSDInput::open (const std::string &name, ImageSpec &newspec, const ImageSpec &config) { m_WantRaw = config.get_int_attribute ("psd:RawData", 0) != 0; if (config.get_int_attribute("oiio:UnassociatedAlpha", 0) == 1) m_keep_unassociated_alpha = true; return open (name, newspec); } bool PSDInput::close () { init(); return true; } bool PSDInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (miplevel != 0) return false; if (subimage < 0 || subimage >= m_subimage_count) return false; m_subimage = subimage; newspec = m_spec = m_specs[subimage]; return true; } void PSDInput::background_to_assocalpha (int n, void *data) { switch (m_spec.format.basetype) { case TypeDesc::UINT8: removeBackground ((unsigned char *)data, n, m_spec.nchannels, m_spec.alpha_channel, m_background_color); break; case TypeDesc::UINT16: removeBackground ((unsigned short *)data, n, m_spec.nchannels, m_spec.alpha_channel, m_background_color); break; case TypeDesc::UINT32: removeBackground ((unsigned long *)data, n, m_spec.nchannels, m_spec.alpha_channel, m_background_color); break; default: break; } } void PSDInput::background_to_unassalpha (int n, void *data) { switch (m_spec.format.basetype) { case TypeDesc::UINT8: unassociateAlpha ((unsigned char *)data, n, m_spec.nchannels, m_spec.alpha_channel, m_background_color); break; case TypeDesc::UINT16: unassociateAlpha ((unsigned short *)data, n, m_spec.nchannels, m_spec.alpha_channel, m_background_color); break; case TypeDesc::UINT32: unassociateAlpha ((unsigned long *)data, n, m_spec.nchannels, m_spec.alpha_channel, m_background_color); break; default: break; } } void PSDInput::unassalpha_to_assocalpha (int n, void *data) { switch (m_spec.format.basetype) { case TypeDesc::UINT8: associateAlpha ((unsigned char *)data, n, m_spec.nchannels, m_spec.alpha_channel); break; case TypeDesc::UINT16: associateAlpha ((unsigned short *)data, n, m_spec.nchannels, m_spec.alpha_channel); break; case TypeDesc::UINT32: associateAlpha ((unsigned long *)data, n, m_spec.nchannels, m_spec.alpha_channel); break; default: break; } } bool PSDInput::read_native_scanline (int y, int z, void *data) { if (y < 0 || y > m_spec.height) return false; if (m_channel_buffers.size () < m_channels[m_subimage].size ()) m_channel_buffers.resize (m_channels[m_subimage].size ()); std::vector &channels = m_channels[m_subimage]; int channel_count = (int)channels.size (); for (int c = 0; c < channel_count; ++c) { std::string &buffer = m_channel_buffers[c]; ChannelInfo &channel_info = *channels[c]; if (buffer.size () < channel_info.row_length) buffer.resize (channel_info.row_length); if (!read_channel_row (channel_info, y, &buffer[0])) return false; } char *dst = (char *)data; if (m_WantRaw || m_header.color_mode == ColorMode_RGB) interleave_row (dst); else { if (!convert_to_rgb (dst)) return false; } // PSD specifically dictates unassociated (un-"premultiplied") alpha. // Convert to associated unless we were requested not to do so. // // Composite layer (subimage 0) is mixed with background, which // affects the alpha (aka white borders if background not removed). // // Composite: // m_keep_unassociated_alpha true: remove background and convert to unassociated // m_keep_unassociated_alpha false: remove background only // // Other Layers: // m_keep_unassociated_alpha true: do nothing // m_keep_unassociated_alpha false: convert to associated // // if (m_spec.alpha_channel != -1) { if (m_subimage == 0) { if (m_keep_unassociated_alpha) { background_to_unassalpha (m_spec.width, data); } else { background_to_assocalpha (m_spec.width, data); } } else { if (m_keep_unassociated_alpha) { // do nothing - leave as it is } else { unassalpha_to_assocalpha (m_spec.width, data); } } } return true; } void PSDInput::init () { m_filename.clear (); m_file.close (); m_subimage = -1; m_subimage_count = 0; m_specs.clear (); m_WantRaw = false; m_layers.clear (); m_image_data.channel_info.clear (); m_image_data.transparency = false; m_channels.clear (); m_alpha_names.clear (); m_channel_buffers.clear (); m_rle_buffer.clear (); m_transparency_index = -1; m_keep_unassociated_alpha = false; m_background_color[0] = 1.0; m_background_color[1] = 1.0; m_background_color[2] = 1.0; m_background_color[3] = 1.0; } bool PSDInput::load_header () { if (!read_header () || !validate_header ()) return false; return true; } bool PSDInput::read_header () { m_file.read (m_header.signature, 4); read_bige (m_header.version); m_file.seekg(6, std::ios::cur); read_bige (m_header.channel_count); read_bige (m_header.height); read_bige (m_header.width); read_bige (m_header.depth); read_bige (m_header.color_mode); return check_io (); } bool PSDInput::validate_header () { if (std::memcmp (m_header.signature, "8BPS", 4) != 0) { error ("[Header] invalid signature"); return false; } if (m_header.version != 1 && m_header.version != 2) { error ("[Header] invalid version"); return false; } if (m_header.channel_count < 1 || m_header.channel_count > 56) { error ("[Header] invalid channel count"); return false; } switch (m_header.version) { case 1: // PSD // width/height range: [1,30000] if (m_header.height < 1 || m_header.height > 30000) { error ("[Header] invalid image height"); return false; } if (m_header.width < 1 || m_header.width > 30000) { error ("[Header] invalid image width"); return false; } break; case 2: // PSB (Large Document Format) // width/height range: [1,300000] if (m_header.height < 1 || m_header.height > 300000) { error ("[Header] invalid image height"); return false; } if (m_header.width < 1 || m_header.width > 300000) { error ("[Header] invalid image width"); return false; } break; } // Valid depths are 1,8,16,32 if (m_header.depth != 1 && m_header.depth != 8 && m_header.depth != 16 && m_header.depth != 32) { error ("[Header] invalid depth"); return false; } if (m_WantRaw) return true; //There are other (undocumented) color modes not listed here switch (m_header.color_mode) { case ColorMode_Bitmap : case ColorMode_Indexed : case ColorMode_RGB : break; case ColorMode_Grayscale : case ColorMode_CMYK : case ColorMode_Multichannel : case ColorMode_Duotone : case ColorMode_Lab : error ("[Header] unsupported color mode"); return false; default: error ("[Header] unrecognized color mode"); return false; } return true; } bool PSDInput::load_color_data () { read_bige (m_color_data.length); if (!check_io ()) return false; if (!validate_color_data ()) return false; if (m_color_data.length) { m_color_data.data.resize (m_color_data.length); m_file.read (&m_color_data.data[0], m_color_data.length); } return check_io (); } bool PSDInput::validate_color_data () { if (m_header.color_mode == ColorMode_Duotone && m_color_data.length == 0) { error ("[Color Mode Data] color mode data should be present for duotone image"); return false; } if (m_header.color_mode == ColorMode_Indexed && m_color_data.length != 768) { error ("[Color Mode Data] length should be 768 for indexed color mode"); return false; } return true; } bool PSDInput::load_resources () { uint32_t length; read_bige (length); if (!check_io ()) return false; ImageResourceBlock block; ImageResourceMap resources; std::streampos begin = m_file.tellg (); std::streampos end = begin + (std::streampos)length; while (m_file && m_file.tellg () < end) { if (!read_resource (block) || !validate_resource (block)) return false; resources.insert (std::make_pair (block.id, block)); } if (!check_io ()) return false; if (!handle_resources (resources)) return false; m_file.seekg (end); return check_io (); } bool PSDInput::read_resource (ImageResourceBlock &block) { m_file.read (block.signature, 4); read_bige (block.id); read_pascal_string (block.name, 2); read_bige (block.length); // Save the file position of the image resource data block.pos = m_file.tellg(); // Skip the image resource data m_file.seekg (block.length, std::ios::cur); // Image resource blocks are supposed to be padded to an even size. // I'm not sure if the padding is included in the length field if (block.length % 2 != 0) m_file.seekg(1, std::ios::cur); return check_io (); } bool PSDInput::validate_resource (ImageResourceBlock &block) { if (std::memcmp (block.signature, "8BIM", 4) != 0) { error ("[Image Resource] invalid signature"); return false; } return true; } bool PSDInput::handle_resources (ImageResourceMap &resources) { // Loop through each of our resource loaders const ImageResourceMap::const_iterator end (resources.end ()); BOOST_FOREACH (const ResourceLoader &loader, resource_loaders) { ImageResourceMap::const_iterator it (resources.find (loader.resource_id)); // If a resource with that ID exists in the file, call the loader if (it != end) { m_file.seekg (it->second.pos); if (!check_io ()) return false; loader.load (this, it->second.length); if (!check_io ()) return false; } } return true; } bool PSDInput::load_resource_1005 (uint32_t length) { ResolutionInfo resinfo; // Fixed 16.16 read_bige (resinfo.hRes); resinfo.hRes /= 65536.0f; read_bige (resinfo.hResUnit); read_bige (resinfo.widthUnit); // Fixed 16.16 read_bige (resinfo.vRes); resinfo.vRes /= 65536.0f; read_bige (resinfo.vResUnit); read_bige (resinfo.heightUnit); if (!m_file) return false; // Make sure the same unit is used both horizontally and vertically // FIXME(dewyatt): I don't know for sure that the unit can differ. However, // if it can, perhaps we should be using ResolutionUnitH/ResolutionUnitV or // something similar. if (resinfo.hResUnit != resinfo.vResUnit) { error ("[Image Resource] [ResolutionInfo] Resolutions must have the same unit"); return false; } // Make sure the unit is supported // Note: This relies on the above check that the units are the same. if (resinfo.hResUnit != ResolutionInfo::PixelsPerInch && resinfo.hResUnit != ResolutionInfo::PixelsPerCentimeter) { error ("[Image Resource] [ResolutionInfo] Unrecognized resolution unit"); return false; } common_attribute ("XResolution", resinfo.hRes); common_attribute ("XResolution", resinfo.hRes); common_attribute ("YResolution", resinfo.vRes); switch (resinfo.hResUnit) { case ResolutionInfo::PixelsPerInch: common_attribute ("ResolutionUnit", "in"); break; case ResolutionInfo::PixelsPerCentimeter: common_attribute ("ResolutionUnit", "cm"); break; }; return true; } bool PSDInput::load_resource_1006 (uint32_t length) { int32_t bytes_remaining = length; std::string name; while (m_file && bytes_remaining >= 2) { bytes_remaining -= read_pascal_string (name, 1); m_alpha_names.push_back (name); } return check_io (); } bool PSDInput::load_resource_1010 (uint32_t length) { const double int8_to_dbl = 1.0 / 0xFF; int8_t color_id; int32_t color; read_bige (color_id); read_bige (color); m_background_color[0] = ((color) & 0xFF) * int8_to_dbl; m_background_color[1] = ((color >> 8) & 0xFF) * int8_to_dbl; m_background_color[2] = ((color >> 16) & 0xFF) * int8_to_dbl; m_background_color[3] = ((color >> 24) & 0xFF) * int8_to_dbl; return true; } bool PSDInput::load_resource_1033 (uint32_t length) { return load_resource_thumbnail (length, true); } bool PSDInput::load_resource_1036 (uint32_t length) { return load_resource_thumbnail (length, false); } bool PSDInput::load_resource_1047 (uint32_t length) { read_bige (m_transparency_index); if (m_transparency_index < 0 || m_transparency_index >= 768) { error ("[Image Resource] [Transparency Index] index is out of range"); return false; } return true; } bool PSDInput::load_resource_1058 (uint32_t length) { std::string data (length, 0); if (!m_file.read (&data[0], length)) return false; if (!decode_exif (&data[0], length, m_composite_attribs) || !decode_exif (&data[0], length, m_common_attribs)) { error ("Failed to decode Exif data"); return false; } return true; } bool PSDInput::load_resource_1059 (uint32_t length) { //FIXME(dewyatt): untested, I don't have any images with this resource return load_resource_1058 (length); } bool PSDInput::load_resource_1060 (uint32_t length) { std::string data (length, 0); if (!m_file.read (&data[0], length)) return false; // Store the XMP data for the composite and all other subimages if (!decode_xmp (data, m_composite_attribs) || !decode_xmp (data, m_common_attribs)) { error ("Failed to decode XMP data"); return false; } return true; } bool PSDInput::load_resource_1064 (uint32_t length) { uint32_t version; if (!read_bige (version)) return false; if (version != 1 && version != 2) { error ("[Image Resource] [Pixel Aspect Ratio] Unrecognized version"); return false; } double aspect_ratio; if (!read_bige (aspect_ratio)) return false; // FIXME(dewyatt): loss of precision? common_attribute ("PixelAspectRatio", (float)aspect_ratio); return true; } bool PSDInput::load_resource_thumbnail (uint32_t length, bool isBGR) { enum ThumbnailFormat { kJpegRGB = 1, kRawRGB = 0 }; uint32_t format; uint32_t width, height; uint32_t widthbytes; uint32_t total_size; uint32_t compressed_size; uint16_t bpp; uint16_t planes; int stride; jpeg_decompress_struct cinfo; thumbnail_error_mgr jerr; uint32_t jpeg_length = length - 28; read_bige (format); read_bige (width); read_bige (height); read_bige (widthbytes); read_bige (total_size); read_bige (compressed_size); read_bige (bpp); read_bige (planes); if (!m_file) return false; // We only support kJpegRGB since I don't have any test images with // kRawRGB if (format != kJpegRGB || bpp != 24 || planes != 1) { error ("[Image Resource] [JPEG Thumbnail] invalid or unsupported format"); return false; } cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = thumbnail_error_exit; if (setjmp (jerr.setjmp_buffer)) { jpeg_destroy_decompress (&cinfo); error ("[Image Resource] [JPEG Thumbnail] libjpeg error"); return false; } std::string jpeg_data (jpeg_length, '\0'); if (!m_file.read (&jpeg_data[0], jpeg_length)) return false; jpeg_create_decompress (&cinfo); jpeg_memory_src (&cinfo, (unsigned char *)&jpeg_data[0], jpeg_length); jpeg_read_header (&cinfo, TRUE); jpeg_start_decompress (&cinfo); stride = cinfo.output_width * cinfo.output_components; unsigned int thumbnail_bytes = cinfo.output_width * cinfo.output_height * cinfo.output_components; std::string thumbnail_image (thumbnail_bytes, '\0'); // jpeg_destroy_decompress will deallocate this JSAMPLE **buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, stride, 1); while (cinfo.output_scanline < cinfo.output_height) { if (jpeg_read_scanlines (&cinfo, buffer, 1) != 1) { jpeg_finish_decompress (&cinfo); jpeg_destroy_decompress (&cinfo); error ("[Image Resource] [JPEG Thumbnail] libjpeg error"); return false; } std::memcpy (&thumbnail_image[(cinfo.output_scanline - 1) * stride], (char *)buffer[0], stride); } jpeg_finish_decompress (&cinfo); jpeg_destroy_decompress (&cinfo); // Set these attributes for the merged composite only (subimage 0) composite_attribute ("thumbnail_width", (int)width); composite_attribute ("thumbnail_height", (int)height); composite_attribute ("thumbnail_nchannels", 3); if (isBGR) { for (unsigned int i = 0; i < thumbnail_bytes - 2; i += 3) std::swap (thumbnail_image[i], thumbnail_image[i + 2]); } composite_attribute ("thumbnail_image", TypeDesc (TypeDesc::UINT8, thumbnail_image.size ()), &thumbnail_image[0]); return true; } void PSDInput::thumbnail_error_exit (j_common_ptr cinfo) { thumbnail_error_mgr *mgr = (thumbnail_error_mgr *)cinfo->err; longjmp (mgr->setjmp_buffer, 1); } bool PSDInput::load_layers () { if (m_header.version == 1) read_bige (m_layer_mask_info.length); else read_bige (m_layer_mask_info.length); m_layer_mask_info.begin = m_file.tellg (); m_layer_mask_info.end = m_layer_mask_info.begin + (std::streampos)m_layer_mask_info.length; if (!check_io ()) return false; if (!m_layer_mask_info.length) return true; LayerMaskInfo::LayerInfo &layer_info = m_layer_mask_info.layer_info; if (m_header.version == 1) read_bige (layer_info.length); else read_bige (layer_info.length); layer_info.begin = m_file.tellg (); layer_info.end = layer_info.begin + (std::streampos)layer_info.length; if (!check_io ()) return false; if (!layer_info.length) return true; read_bige (layer_info.layer_count); if (layer_info.layer_count < 0) { m_image_data.transparency = true; layer_info.layer_count = -layer_info.layer_count; } m_layers.resize (layer_info.layer_count); for (int16_t layer_nbr = 0; layer_nbr < layer_info.layer_count; ++layer_nbr) { Layer &layer = m_layers[layer_nbr]; if (!load_layer (layer)) return false; } for (int16_t layer_nbr = 0; layer_nbr < layer_info.layer_count; ++layer_nbr) { Layer &layer = m_layers[layer_nbr]; if (!load_layer_channels (layer)) return false; } return true; } bool PSDInput::load_layer (Layer &layer) { read_bige (layer.top); read_bige (layer.left); read_bige (layer.bottom); read_bige (layer.right); read_bige (layer.channel_count); if (!check_io ()) return false; layer.width = std::abs((int)layer.right - (int)layer.left); layer.height = std::abs((int)layer.bottom - (int)layer.top); layer.channel_info.resize (layer.channel_count); for(uint16_t channel = 0; channel < layer.channel_count; channel++) { ChannelInfo &channel_info = layer.channel_info[channel]; read_bige (channel_info.channel_id); if (m_header.version == 1) read_bige (channel_info.data_length); else read_bige (channel_info.data_length); layer.channel_id_map[channel_info.channel_id] = &channel_info; } char bm_signature[4]; m_file.read (bm_signature, 4); if (!check_io ()) return false; if (std::memcmp (bm_signature, "8BIM", 4) != 0) { error ("[Layer Record] Invalid blend mode signature"); return false; } m_file.read (layer.bm_key, 4); read_bige (layer.opacity); read_bige (layer.clipping); read_bige (layer.flags); // skip filler m_file.seekg(1, std::ios::cur); read_bige (layer.extra_length); uint32_t extra_remaining = layer.extra_length; // layer mask data length uint32_t lmd_length; read_bige (lmd_length); if (!check_io ()) return false; switch (lmd_length) { case 0: break; case 20: read_bige (layer.mask_data.top); read_bige (layer.mask_data.left); read_bige (layer.mask_data.bottom); read_bige (layer.mask_data.right); read_bige (layer.mask_data.default_color); read_bige (layer.mask_data.flags); // skip padding m_file.seekg(2, std::ios::cur); break; case 36: // In this case, we skip the above (lmd_length == 20) fields // to read the "real" fields. m_file.seekg (18, std::ios::cur); read_bige (layer.mask_data.flags); read_bige (layer.mask_data.default_color); read_bige (layer.mask_data.top); read_bige (layer.mask_data.left); read_bige (layer.mask_data.bottom); read_bige (layer.mask_data.right); break; default: // The size should always be 0,20, or 36 error ("[Layer Mask Data] invalid size"); return false; break; }; extra_remaining -= (lmd_length + 4); // layer blending ranges length uint32_t lbr_length; read_bige (lbr_length); // skip block m_file.seekg (lbr_length, std::ios::cur); extra_remaining -= (lbr_length + 4); if (!check_io ()) return false; extra_remaining -= read_pascal_string(layer.name, 4); while (m_file && extra_remaining >= 12) { layer.additional_info.push_back (Layer::AdditionalInfo()); Layer::AdditionalInfo &info = layer.additional_info.back(); char signature[4]; m_file.read (signature, 4); m_file.read (info.key, 4); if (std::memcmp (signature, "8BIM", 4) != 0 && std::memcmp (signature, "8B64", 4) != 0) { error ("[Additional Layer Info] invalid signature"); return false; } extra_remaining -= 8; if (m_header.version == 2 && is_additional_info_psb (info.key)) { read_bige (info.length); extra_remaining -= 8; } else { read_bige (info.length); extra_remaining -= 4; } m_file.seekg (info.length, std::ios::cur); extra_remaining -= info.length; } return check_io (); } bool PSDInput::load_layer_channels (Layer &layer) { for (uint16_t channel = 0; channel < layer.channel_count; ++channel) { ChannelInfo &channel_info = layer.channel_info[channel]; if (!load_layer_channel (layer, channel_info)) return false; } return true; } bool PSDInput::load_layer_channel (Layer &layer, ChannelInfo &channel_info) { std::streampos start_pos = m_file.tellg (); if (channel_info.data_length >= 2) { read_bige (channel_info.compression); if (!check_io ()) return false; } // No data at all or just compression if (channel_info.data_length <= 2) return true; channel_info.data_pos = m_file.tellg (); channel_info.row_pos.resize (layer.height); channel_info.row_length = (layer.width * m_header.depth + 7) / 8; switch (channel_info.compression) { case Compression_Raw: if (layer.height) { channel_info.row_pos[0] = channel_info.data_pos; for (uint32_t i = 1; i < layer.height; ++i) channel_info.row_pos[i] = channel_info.row_pos[i - 1] + (std::streampos)channel_info.row_length; } channel_info.data_length = channel_info.row_length * layer.height; break; case Compression_RLE: // RLE lengths are stored before the channel data if (!read_rle_lengths (layer.height, channel_info.rle_lengths)) return false; // channel data is located after the RLE lengths channel_info.data_pos = m_file.tellg (); // subtract the RLE lengths read above channel_info.data_length = channel_info.data_length - (channel_info.data_pos - start_pos); if (layer.height) { channel_info.row_pos[0] = channel_info.data_pos; for (uint32_t i = 1; i < layer.height; ++i) channel_info.row_pos[i] = channel_info.row_pos[i - 1] + (std::streampos)channel_info.rle_lengths[i - 1]; } break; // These two aren't currently supported. They would likely // require large changes in the code as they probably don't // support random access like the other modes. I doubt these are // used much and I haven't found any test images. case Compression_ZIP: case Compression_ZIP_Predict: default: error ("[Layer Channel] unsupported compression"); return false; ; } m_file.seekg (channel_info.data_length, std::ios::cur); return check_io (); } bool PSDInput::read_rle_lengths (uint32_t height, std::vector &rle_lengths) { rle_lengths.resize (height); for (uint32_t row = 0; row < height && m_file; ++row) { if (m_header.version == 1) read_bige (rle_lengths[row]); else read_bige (rle_lengths[row]); } return check_io (); } bool PSDInput::load_global_mask_info () { m_file.seekg (m_layer_mask_info.layer_info.end); uint32_t length; read_bige (length); std::streampos start = m_file.tellg (); std::streampos end = start + (std::streampos)length; if (!check_io ()) return false; // this can be empty if (!length) return true; read_bige (m_global_mask_info.overlay_color_space); for (int i = 0; i < 4; ++i) read_bige (m_global_mask_info.color_components[i]); read_bige (m_global_mask_info.opacity); read_bige (m_global_mask_info.kind); m_file.seekg (end); return check_io (); } bool PSDInput::load_global_additional () { char signature[4]; char key[4]; uint64_t length; uint64_t remaining = m_layer_mask_info.length - (m_file.tellg() - m_layer_mask_info.begin); while (m_file && remaining >= 12) { m_file.read (signature, 4); if (!check_io ()) return false; if (std::memcmp (signature, "8BIM", 4) != 0) { error ("[Global Additional Layer Info] invalid signature"); return false; } m_file.read (key, 4); if (!check_io ()) return false; remaining -= 8; if (m_header.version == 2 && is_additional_info_psb (key)) { read_bige (length); remaining -= 8; } else { read_bige (length); remaining -= 4; } // Long story short these are aligned to 4 bytes but that is not // included in the stored length and the specs do not mention it. // round up to multiple of 4 length = (length + 3) & ~3; remaining -= length; // skip it for now m_file.seekg (length, std::ios::cur); } return check_io (); } bool PSDInput::load_image_data () { uint16_t compression; uint32_t row_length = (m_header.width * m_header.depth + 7) / 8; int16_t id = 0; read_bige (compression); if (!check_io ()) return false; if (compression != Compression_Raw && compression != Compression_RLE) { error ("[Image Data Section] unsupported compression"); return false; } m_image_data.channel_info.resize (m_header.channel_count); // setup some generic properties and read any RLE lengths // Image Data Section has RLE lengths for all channels stored first BOOST_FOREACH (ChannelInfo &channel_info, m_image_data.channel_info) { channel_info.compression = compression; channel_info.channel_id = id++; channel_info.data_length = row_length * m_header.height; if (compression == Compression_RLE) { if (!read_rle_lengths (m_header.height, channel_info.rle_lengths)) return false; } } BOOST_FOREACH (ChannelInfo &channel_info, m_image_data.channel_info) { channel_info.row_pos.resize (m_header.height); channel_info.data_pos = m_file.tellg (); channel_info.row_length = (m_header.width * m_header.depth + 7) / 8; switch (compression) { case Compression_Raw: channel_info.row_pos[0] = channel_info.data_pos; for (uint32_t i = 1; i < m_header.height; ++i) channel_info.row_pos[i] = channel_info.row_pos[i - 1] + (std::streampos)row_length; m_file.seekg (channel_info.row_pos.back () + (std::streampos)row_length); break; case Compression_RLE: channel_info.row_pos[0] = channel_info.data_pos; for (uint32_t i = 1; i < m_header.height; ++i) channel_info.row_pos[i] = channel_info.row_pos[i - 1] + (std::streampos)channel_info.rle_lengths[i - 1]; m_file.seekg (channel_info.row_pos.back () + (std::streampos)channel_info.rle_lengths.back ()); break; } } return check_io (); } void PSDInput::setup () { int spec_channel_count = m_WantRaw ? mode_channel_count[m_header.color_mode] : 3; int raw_channel_count = mode_channel_count[m_header.color_mode]; if (m_image_data.transparency) { spec_channel_count++; raw_channel_count++; } else if (m_header.color_mode == ColorMode_Indexed && m_transparency_index) spec_channel_count++; // Composite spec m_specs.push_back (ImageSpec (m_header.width, m_header.height, spec_channel_count, m_type_desc)); ImageSpec &composite_spec = m_specs.back (); composite_spec.extra_attribs = m_composite_attribs.extra_attribs; if (m_WantRaw) fill_channel_names (composite_spec, m_image_data.transparency); // Composite channels m_channels.reserve (m_subimage_count); m_channels.resize (1); m_channels[0].reserve (raw_channel_count); for (int i = 0; i < raw_channel_count; ++i) m_channels[0].push_back (&m_image_data.channel_info[i]); BOOST_FOREACH (Layer &layer, m_layers) { spec_channel_count = m_WantRaw ? mode_channel_count[m_header.color_mode] : 3; raw_channel_count = mode_channel_count[m_header.color_mode]; bool transparency = (bool)layer.channel_id_map.count (ChannelID_Transparency); if (transparency) { spec_channel_count++; raw_channel_count++; } m_specs.push_back (ImageSpec (layer.width, layer.height, spec_channel_count, m_type_desc)); ImageSpec &spec = m_specs.back (); spec.extra_attribs = m_common_attribs.extra_attribs; if (m_WantRaw) fill_channel_names (spec, transparency); m_channels.resize (m_channels.size () + 1); std::vector &channels = m_channels.back (); channels.reserve (raw_channel_count); for (unsigned int i = 0; i < mode_channel_count[m_header.color_mode]; ++i) channels.push_back (layer.channel_id_map[i]); if (transparency) channels.push_back (layer.channel_id_map[ChannelID_Transparency]); } if (m_spec.alpha_channel != -1) if (m_keep_unassociated_alpha) m_spec.attribute ("oiio:UnassociatedAlpha", 1); } void PSDInput::fill_channel_names (ImageSpec &spec, bool transparency) { spec.channelnames.clear (); for (unsigned int i = 0; i < mode_channel_count[m_header.color_mode]; ++i) spec.channelnames.push_back (mode_channel_names[m_header.color_mode][i]); if (transparency) spec.channelnames.push_back ("A"); } bool PSDInput::read_channel_row (const ChannelInfo &channel_info, uint32_t row, char *data) { if (row >= channel_info.row_pos.size ()) return false; uint32_t rle_length; channel_info.row_pos[row]; m_file.seekg (channel_info.row_pos[row]); switch (channel_info.compression) { case Compression_Raw: m_file.read (data, channel_info.row_length); break; case Compression_RLE: rle_length = channel_info.rle_lengths[row]; if (m_rle_buffer.size () < rle_length) m_rle_buffer.resize (rle_length); m_file.read (&m_rle_buffer[0], rle_length); if (!check_io ()) return false; if (!decompress_packbits (&m_rle_buffer[0], data, rle_length, channel_info.row_length)) return false; break; } if (!check_io ()) return false; if (!bigendian ()) { switch (m_header.depth) { case 16: swap_endian ((uint16_t *)data, m_spec.width); break; case 32: swap_endian ((uint32_t *)data, m_spec.width); break; } } return true; } void PSDInput::interleave_row (char *dst) { //bytes per sample int bps = (m_header.depth + 7) / 8; int width = m_spec.width; std::size_t channel_count = m_channels[m_subimage].size (); for (int x = 0; x < width; ++x) { for (unsigned int c = 0; c < channel_count; ++c) { std::string &buffer = m_channel_buffers[c]; std::memcpy (dst, &buffer[x * bps], bps); dst += bps; } } } bool PSDInput::convert_to_rgb (char *dst) { switch (m_header.color_mode) { case ColorMode_Indexed: return indexed_to_rgb (dst); case ColorMode_Bitmap: return bitmap_to_rgb (dst); } return false; } bool PSDInput::indexed_to_rgb (char *dst) { char *src = &m_channel_buffers[m_subimage][0]; // The color table is 768 bytes which is 256 * 3 channels (always RGB) char *table = &m_color_data.data[0]; if (m_transparency_index >= 0) { for (int i = 0; i < m_spec.width; ++i) { unsigned char index = *src++; if (index == m_transparency_index) { std::memset (dst, 0, 4); dst += 4; continue; } *dst++ = table[index]; // R *dst++ = table[index + 256]; // G *dst++ = table[index + 512]; // B *dst++ = 0xff; // A } } else { for (int i = 0; i < m_spec.width; ++i) { unsigned char index = *src++; *dst++ = table[index]; // R *dst++ = table[index + 256]; // G *dst++ = table[index + 512]; // B } } return true; } bool PSDInput::bitmap_to_rgb (char *dst) { for (int i = 0; i < m_spec.width; ++i) { int byte = i / 8; int bit = 7 - i % 8; char result; char *src = &m_channel_buffers[m_subimage][byte]; if (*src & (1 << bit)) result = 0; else result = 0xff; std::memset (dst, result, 3); dst += 3; } return true; } void PSDInput::set_type_desc () { switch (m_header.depth) { case 1: case 8: m_type_desc = TypeDesc::UINT8; break; case 16: m_type_desc = TypeDesc::UINT16; break; case 32: m_type_desc = TypeDesc::UINT32; break; }; } bool PSDInput::check_io () { if (!m_file) { error ("\"%s\": I/O error", m_filename.c_str ()); return false; } return true; } int PSDInput::read_pascal_string (std::string &s, uint16_t mod_padding) { s.clear(); uint8_t length; int bytes = 0; if (m_file.read ((char *)&length, 1)) { bytes = 1; if (length == 0) { if (m_file.seekg (mod_padding - 1, std::ios::cur)) bytes += mod_padding - 1; } else { s.resize (length); if (m_file.read (&s[0], length)) { bytes += length; if (mod_padding > 0) { for (int padded_length = length + 1; padded_length % mod_padding != 0; padded_length++) { if (!m_file.seekg(1, std::ios::cur)) break; bytes++; } } } } } return bytes; } bool PSDInput::decompress_packbits (const char *src, char *dst, uint16_t packed_length, uint16_t unpacked_length) { int32_t src_remaining = packed_length; int32_t dst_remaining = unpacked_length; int16_t header; int length; while (src_remaining > 0 && dst_remaining > 0) { header = *src++; src_remaining--; if (header == 128) continue; else if (header >= 0) { // (1 + n) literal bytes length = 1 + header; src_remaining -= length; dst_remaining -= length; if (src_remaining < 0 || dst_remaining < 0) return false; std::memcpy (dst, src, length); src += length; dst += length; } else { // repeat byte (1 - n) times length = 1 - header; src_remaining--; dst_remaining -= length; if (src_remaining < 0 || dst_remaining < 0) return false; std::memset (dst, *src, length); src++; dst += length; } } return true; } bool PSDInput::is_additional_info_psb (const char *key) { for (unsigned int i = 0; i < additional_info_psb_count; ++i) if (std::memcmp (additional_info_psb[i], key, 4) == 0) return true; return false; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/targa.imageio/0000755000175000017500000000000012271062644017617 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/targa.imageio/targainput.cpp0000644000175000017500000007056212271062644022513 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "targa_pvt.h" #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace TGA_pvt; class TGAInput : public ImageInput { public: TGAInput () { init(); } virtual ~TGAInput () { close(); } virtual const char * format_name (void) const { return "targa"; } virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool open (const std::string &name, ImageSpec &newspec, const ImageSpec &config); virtual bool close (); virtual bool read_native_scanline (int y, int z, void *data); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle tga_header m_tga; ///< Targa header tga_footer m_foot; ///< Targa 2.0 footer unsigned int m_ofs_colcorr_tbl; ///< Offset to colour correction table tga_alpha_type m_alpha; ///< Alpha type bool m_keep_unassociated_alpha; ///< Do not convert unassociated alpha std::vector m_buf; ///< Buffer the image pixels /// Reset everything to initial state /// void init () { m_file = NULL; m_buf.clear (); m_ofs_colcorr_tbl = 0; m_alpha = TGA_ALPHA_NONE; m_keep_unassociated_alpha = false; } /// Helper function: read the image. /// bool readimg (); /// Helper function: decode a pixel. inline void decode_pixel (unsigned char *in, unsigned char *out, unsigned char *palette, int& bytespp, int& palbytespp, int& alphabits); /// Helper: read, with error detection /// bool fread (void *buf, size_t itemsize, size_t nitems) { size_t n = ::fread (buf, itemsize, nitems, m_file); if (n != nitems) error ("Read error"); return n == nitems; } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *targa_input_imageio_create () { return new TGAInput; } OIIO_EXPORT int targa_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * targa_input_extensions[] = { "tga", "tpic", NULL }; OIIO_PLUGIN_EXPORTS_END bool TGAInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; m_file = Filesystem::fopen (name, "rb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } // due to struct packing, we may get a corrupt header if we just load the // struct from file; to adress that, read every member individually // save some typing #define RH(memb) if (! fread (&m_tga.memb, sizeof (m_tga.memb), 1)) \ return false RH(idlen); RH(cmap_type); RH(type); RH(cmap_first); RH(cmap_length); RH(cmap_size); RH(x_origin); RH(y_origin); RH(width); RH(height); RH(bpp); RH(attr); #undef RH if (bigendian()) { // TGAs are little-endian swap_endian (&m_tga.idlen); swap_endian (&m_tga.cmap_type); swap_endian (&m_tga.type); swap_endian (&m_tga.cmap_first); swap_endian (&m_tga.cmap_length); swap_endian (&m_tga.cmap_size); swap_endian (&m_tga.x_origin); swap_endian (&m_tga.y_origin); swap_endian (&m_tga.width); swap_endian (&m_tga.height); swap_endian (&m_tga.bpp); swap_endian (&m_tga.attr); } if (m_tga.bpp != 8 && m_tga.bpp != 15 && m_tga.bpp != 16 && m_tga.bpp != 24 && m_tga.bpp != 32) { error ("Illegal pixel size: %d bits per pixel", m_tga.bpp); return false; } if (m_tga.type == TYPE_NODATA) { error ("Image with no data"); return false; } if (m_tga.type != TYPE_PALETTED && m_tga.type != TYPE_RGB && m_tga.type != TYPE_GRAY && m_tga.type != TYPE_PALETTED_RLE && m_tga.type != TYPE_RGB_RLE && m_tga.type != TYPE_GRAY_RLE) { error ("Illegal image type: %d", m_tga.type); return false; } if (m_tga.cmap_type && (m_tga.type == TYPE_GRAY || m_tga.type == TYPE_GRAY_RLE)) { // it should be an error for TYPE_RGB* as well, but apparently some // *very* old TGAs can be this way, so we'll hack around it error ("Palette defined for grayscale image"); return false; } if (m_tga.cmap_type && (m_tga.cmap_size != 15 && m_tga.cmap_size != 16 && m_tga.cmap_size != 24 && m_tga.cmap_size != 32)) { error ("Illegal palette entry size: %d bits", m_tga.cmap_size); return false; } m_alpha = TGA_ALPHA_NONE; if (((m_tga.type == TYPE_RGB || m_tga.type == TYPE_RGB_RLE) && m_tga.bpp == 32) || ((m_tga.type == TYPE_GRAY || m_tga.type == TYPE_GRAY_RLE) && m_tga.bpp > 8)) { m_alpha = (m_tga.attr & 0x08) > 0 ? TGA_ALPHA_USEFUL : TGA_ALPHA_NONE; } m_spec = ImageSpec ((int)m_tga.width, (int)m_tga.height, // colour channels ((m_tga.type == TYPE_GRAY || m_tga.type == TYPE_GRAY_RLE) ? 1 : 3) // have we got alpha? + (m_tga.bpp == 32 || m_alpha >= TGA_ALPHA_UNDEFINED_RETAIN), TypeDesc::UINT8); m_spec.attribute ("oiio:BitsPerSample", m_tga.bpp/m_spec.nchannels); m_spec.default_channel_names (); #if 0 // no one seems to adhere to this part of the spec... if (m_tga.attr & FLAG_X_FLIP) m_spec.x = m_spec.width - m_tga.x_origin - 1; else m_spec.x = m_tga.x_origin; if (m_tga.attr & FLAG_Y_FLIP) m_spec.y = m_tga.y_origin; else m_spec.y = m_spec.width - m_tga.y_origin - 1; #endif if (m_tga.type >= TYPE_PALETTED_RLE) m_spec.attribute ("compression", "rle"); /*std::cerr << "[tga] " << m_tga.width << "x" << m_tga.height << "@" << (int)m_tga.bpp << " (" << m_spec.nchannels << ") type " << (int)m_tga.type << "\n";*/ // load image ID if (m_tga.idlen) { // TGA comments can be at most 255 bytes long, but we add 1 extra byte // in case the comment lacks null termination char id[256]; memset (id, 0, sizeof (id)); if (! fread (id, m_tga.idlen, 1)) return false; m_spec.attribute ("targa:ImageID", id); } int ofs = ftell (m_file); // now try and see if it's a TGA 2.0 image // TGA 2.0 files are identified by a nifty "TRUEVISION-XFILE.\0" signature fseek (m_file, -26, SEEK_END); if (fread (&m_foot.ofs_ext, sizeof (m_foot.ofs_ext), 1) && fread (&m_foot.ofs_dev, sizeof (m_foot.ofs_dev), 1) && fread (&m_foot.signature, sizeof (m_foot.signature), 1) && !strncmp (m_foot.signature, "TRUEVISION-XFILE.", 17)) { //std::cerr << "[tga] this is a TGA 2.0 file\n"; if (bigendian()) { swap_endian (&m_foot.ofs_ext); swap_endian (&m_foot.ofs_dev); } // read the extension area fseek (m_file, m_foot.ofs_ext, SEEK_SET); // check if this is a TGA 2.0 extension area // according to the 2.0 spec, the size for valid 2.0 files is exactly // 495 bytes, and the reader should only read as much as it understands // for < 495, we ignore this section of the file altogether // for > 495, we only read what we know uint16_t s; if (! fread (&s, 2, 1)) return false; if (bigendian()) swap_endian (&s); //std::cerr << "[tga] extension area size: " << s << "\n"; if (s >= 495) { union { unsigned char c[324]; // so as to accomodate the comments uint16_t s[6]; uint32_t l; } buf; // load image author if (! fread (buf.c, 41, 1)) return false; if (buf.c[0]) m_spec.attribute ("Artist", (char *)buf.c); // load image comments if (! fread (buf.c, 324, 1)) return false; // concatenate the lines into a single string std::string tmpstr ((const char *)buf.c); if (buf.c[81]) { tmpstr += "\n"; tmpstr += (const char *)&buf.c[81]; } if (buf.c[162]) { tmpstr += "\n"; tmpstr += (const char *)&buf.c[162]; } if (buf.c[243]) { tmpstr += "\n"; tmpstr += (const char *)&buf.c[243]; } if (tmpstr.length () > 0) m_spec.attribute ("ImageDescription", tmpstr); // timestamp if (! fread (buf.s, 2, 6)) return false; if (buf.s[0] || buf.s[1] || buf.s[2] || buf.s[3] || buf.s[4] || buf.s[5]) { if (bigendian()) swap_endian (&buf.s[0], 6); sprintf ((char *)&buf.c[12], "%04u:%02u:%02u %02u:%02u:%02u", buf.s[2], buf.s[0], buf.s[1], buf.s[3], buf.s[4], buf.s[5]); m_spec.attribute ("DateTime", (char *)&buf.c[12]); } // job name/ID if (! fread (buf.c, 41, 1)) return false; if (buf.c[0]) m_spec.attribute ("DocumentName", (char *)buf.c); // job time if (! fread (buf.s, 2, 3)) return false; if (buf.s[0] || buf.s[1] || buf.s[2]) { if (bigendian()) swap_endian (&buf.s[0], 3); sprintf ((char *)&buf.c[6], "%u:%02u:%02u", buf.s[0], buf.s[1], buf.s[2]); m_spec.attribute ("targa:JobTime", (char *)&buf.c[6]); } // software if (! fread (buf.c, 41, 1)) return false; if (buf.c[0]) { // tack on the version number and letter uint16_t n; char l; if (! fread (&n, 2, 1) || ! fread (&l, 1, 1)) return false; sprintf ((char *)&buf.c[strlen ((char *)buf.c)], " %u.%u%c", n / 100, n % 100, l != ' ' ? l : 0); m_spec.attribute ("Software", (char *)buf.c); } // background (key) colour if (! fread (buf.c, 4, 1)) return false; // FIXME: what do we do with it? // aspect ratio if (! fread (buf.s, 2, 2)) return false; // if the denominator is zero, it's unused if (buf.s[1]) { if (bigendian()) swap_endian (&buf.s[0], 2); m_spec.attribute ("PixelAspectRatio", (float)buf.s[0] / (float)buf.s[1]); } // gamma if (! fread (buf.s, 2, 2)) return false; // if the denominator is zero, it's unused if (buf.s[1]) { if (bigendian()) swap_endian (&buf.s[0], 2); float gamma = (float)buf.s[0] / (float)buf.s[1]; if (gamma == 1.f) { m_spec.attribute ("oiio:ColorSpace", "Linear"); } else { m_spec.attribute ("oiio:ColorSpace", "GammaCorrected"); m_spec.attribute ("oiio:Gamma", gamma); } } // offset to colour correction table if (! fread (&buf.l, 4, 1)) return false; if (bigendian()) swap_endian (&buf.l); m_ofs_colcorr_tbl = buf.l; /*std::cerr << "[tga] colour correction table offset: " << (int)m_ofs_colcorr_tbl << "\n";*/ // offset to thumbnail if (! fread (&buf.l, 4, 1)) return false; if (bigendian()) swap_endian (&buf.l); unsigned int ofs_thumb = buf.l; // offset to scan-line table if (! fread (&buf.l, 4, 1)) return false; // TODO: can we find any use for this? we can't advertise random // access anyway, because not all RLE-compressed files will have // this table // alpha type if (! fread (buf.c, 1, 1)) return false; m_alpha = (tga_alpha_type)buf.c[0]; // now load the thumbnail if (ofs_thumb) { fseek (m_file, ofs_thumb, SEEK_SET); // most of this code is a dupe of readimg(); according to the // spec, the thumbnail is in the same format as the main image // but uncompressed // thumbnail dimensions if (! fread (&buf.c, 2, 1)) return false; m_spec.attribute ("thumbnail_width", (int)buf.c[0]); m_spec.attribute ("thumbnail_height", (int)buf.c[1]); m_spec.attribute ("thumbnail_nchannels", m_spec.nchannels); // load image data // reuse the image buffer m_buf.resize (buf.c[0] * buf.c[1] * m_spec.nchannels); int bytespp = (m_tga.bpp == 15) ? 2 : (m_tga.bpp / 8); int palbytespp = (m_tga.cmap_size == 15) ? 2 : (m_tga.cmap_size / 8); int alphabits = m_tga.attr & 0x0F; if (alphabits == 0 && m_tga.bpp == 32) alphabits = 8; // read palette, if there is any unsigned char *palette = NULL; if (m_tga.cmap_type) { fseek (m_file, ofs, SEEK_SET); palette = new unsigned char[palbytespp * m_tga.cmap_length]; if (! fread (palette, palbytespp, m_tga.cmap_length)) return false; fseek (m_file, ofs_thumb + 2, SEEK_SET); } unsigned char pixel[4]; unsigned char in[4]; for (int y = buf.c[1] - 1; y >= 0; y--) { for (int x = 0; x < buf.c[0]; x++) { if (! fread (in, bytespp, 1)) return false; decode_pixel (in, pixel, palette, bytespp, palbytespp, alphabits); memcpy (&m_buf[y * buf.c[0] * m_spec.nchannels + x * m_spec.nchannels], pixel, m_spec.nchannels); } } //std::cerr << "[tga] buffer size: " << m_buf.size() << "\n"; // finally, add the thumbnail to attributes m_spec.attribute ("thumbnail_image", TypeDesc (TypeDesc::UINT8, m_buf.size()), &m_buf[0]); m_buf.clear(); } } // FIXME: provide access to the developer area; according to Larry, // it's probably safe to ignore it altogether until someone complains // that it's missing :) } if (m_spec.alpha_channel != -1 && m_alpha != TGA_ALPHA_PREMULTIPLIED) if (m_keep_unassociated_alpha) m_spec.attribute ("oiio:UnassociatedAlpha", 1); fseek (m_file, ofs, SEEK_SET); newspec = spec (); return true; } bool TGAInput::open (const std::string &name, ImageSpec &newspec, const ImageSpec &config) { // Check 'config' for any special requests if (config.get_int_attribute("oiio:UnassociatedAlpha", 0) == 1) m_keep_unassociated_alpha = true; return open (name, newspec); } inline void TGAInput::decode_pixel (unsigned char *in, unsigned char *out, unsigned char *palette, int& bytespp, int& palbytespp, int& alphabits) { unsigned int k = 0; // I hate nested switches... switch (m_tga.type) { case TYPE_PALETTED: case TYPE_PALETTED_RLE: for (int i = 0; i < bytespp; ++i) k |= in[i] << (8*i); // Assemble it in little endian order k = (m_tga.cmap_first + k) * palbytespp; switch (palbytespp) { case 2: // see the comment for 16bpp RGB below for an explanation of this out[0] = bit_range_convert<5, 8> ((palette[k + 1] & 0x7C) >> 2); out[1] = bit_range_convert<5, 8> (((palette[k + 0] & 0xE0) >> 5) | ((palette[k + 1] & 0x03) << 3)); out[2] = bit_range_convert<5, 8> (palette[k + 0] & 0x1F); break; case 3: out[0] = palette[k + 2]; out[1] = palette[k + 1]; out[2] = palette[k + 0]; break; case 4: out[0] = palette[k + 2]; out[1] = palette[k + 1]; out[2] = palette[k + 0]; out[3] = palette[k + 3]; break; } break; case TYPE_RGB: case TYPE_RGB_RLE: switch (bytespp) { case 2: // This format is pretty funky. It's a 1A-5R-5G-5B layout, // with the first bit alpha (or unused if only 3 channels), // but thanks to the little-endianness, the order is pretty // bizarre. The bits are non-contiguous, so we have to // extract the relevant ones and synthesize the colour // values from the two bytes. // NOTE: This way of handling the pixel as two independent bytes // (as opposed to a single short int) makes it independent from // endianness. // Here's what the layout looks like: // MSb unused LSb // v v v // GGGBBBBB RRRRRGG // [||||||||] [||||||||] // While red and blue channels are quite self-explanatory, the // green one needs a few words. The 5 bits are composed of the // 2 from the second byte as the more significant and the 3 from // the first one as the less significant ones. // extract the bits to valid 5-bit integers and expand to full range out[0] = bit_range_convert<5, 8> ((in[1] & 0x7C) >> 2); out[1] = bit_range_convert<5, 8> (((in[0] & 0xE0) >> 5) | ((in[1] & 0x03) << 3)); out[2] = bit_range_convert<5, 8> (in[0] & 0x1F); if (m_spec.nchannels > 3) out[3] = (in[0] & 0x80) ? 255 : 0; break; case 3: out[0] = in[2]; out[1] = in[1]; out[2] = in[0]; break; case 4: out[0] = in[2]; out[1] = in[1]; out[2] = in[0]; out[3] = in[3]; break; } break; case TYPE_GRAY: case TYPE_GRAY_RLE: if (bigendian ()) { for (int i = bytespp - 1; i >= 0; i--) out[i] = in[bytespp - i - 1]; } else memcpy (out, in, bytespp); break; } } template static void associateAlpha (T * data, int size, int channels, int alpha_channel, float gamma) { T max = std::numeric_limits::max(); if (gamma == 1) { for (int x = 0; x < size; ++x, data += channels) for (int c = 0; c < channels; c++) if (c != alpha_channel){ unsigned int f = data[c]; data[c] = (f * data[alpha_channel]) / max; } } else { //With gamma correction float inv_max = 1.0 / max; for (int x = 0; x < size; ++x, data += channels) { float alpha_associate = pow(data[alpha_channel]*inv_max, gamma); // We need to transform to linear space, associate the alpha, and // then transform back. That is, if D = data[c], we want // // D' = max * ( (D/max)^(1/gamma) * (alpha/max) ) ^ gamma // // This happens to simplify to something which looks like // multiplying by a nonlinear alpha: // // D' = D * (alpha/max)^gamma for (int c = 0; c < channels; c++) if (c != alpha_channel) data[c] = static_cast(data[c] * alpha_associate); } } } bool TGAInput::readimg () { // how many bytes we actually read // for 15-bit read 2 bytes and ignore the 16th bit int bytespp = (m_tga.bpp == 15) ? 2 : (m_tga.bpp / 8); int palbytespp = (m_tga.cmap_size == 15) ? 2 : (m_tga.cmap_size / 8); int alphabits = m_tga.attr & 0x0F; if (alphabits == 0 && m_tga.bpp == 32) alphabits = 8; /*std::cerr << "[tga] bytespp = " << bytespp << " palbytespp = " << palbytespp << " alphabits = " << alphabits << "\n";*/ m_buf.resize (m_spec.image_bytes()); // read palette, if there is any unsigned char *palette = NULL; if (m_tga.cmap_type) { palette = new unsigned char[palbytespp * m_tga.cmap_length]; if (! fread (palette, palbytespp, m_tga.cmap_length)) return false; } unsigned char pixel[4]; if (m_tga.type < TYPE_PALETTED_RLE) { // uncompressed image data unsigned char in[4]; for (int y = m_spec.height - 1; y >= 0; y--) { for (int x = 0; x < m_spec.width; x++) { if (! fread (in, bytespp, 1)) return false; decode_pixel (in, pixel, palette, bytespp, palbytespp, alphabits); memcpy (&m_buf[y * m_spec.width * m_spec.nchannels + x * m_spec.nchannels], pixel, m_spec.nchannels); } } } else { // Run Length Encoded image unsigned char in[5]; int packet_size; for (int y = m_spec.height - 1; y >= 0; y--) { for (int x = 0; x < m_spec.width; x++) { if (! fread (in, 1 + bytespp, 1)) return false; packet_size = 1 + (in[0] & 0x7f); decode_pixel (&in[1], pixel, palette, bytespp, palbytespp, alphabits); if (in[0] & 0x80) { // run length packet /*std::cerr << "[tga] run length packet " << packet_size << "\n";*/ for (int i = 0; i < packet_size; i++) { memcpy (&m_buf[y * m_spec.width * m_spec.nchannels + x * m_spec.nchannels], pixel, m_spec.nchannels); if (i < packet_size - 1) { x++; if (x >= m_spec.width) { // run spans across multiple scanlines x = 0; if (y > 0) y--; else goto loop_break; } } } } else { // non-rle packet /*std::cerr << "[tga] non-run length packet " << packet_size << "\n";*/ for (int i = 0; i < packet_size; i++) { memcpy (&m_buf[y * m_spec.width * m_spec.nchannels + x * m_spec.nchannels], pixel, m_spec.nchannels); if (i < packet_size - 1) { x++; if (x >= m_spec.width) { // run spans across multiple scanlines x = 0; if (y > 0) y--; else goto loop_break; } // skip the packet header byte if (! fread (&in[1], bytespp, 1)) return false; decode_pixel(&in[1], pixel, palette, bytespp, palbytespp, alphabits); } } } } loop_break:; } } delete [] palette; // flip the image, if necessary if (m_tga.cmap_type) bytespp = palbytespp; // Y-flipping is now done in read_native_scanline instead /*if (m_tga.attr & FLAG_Y_FLIP) { //std::cerr << "[tga] y flipping\n"; std::vector flip (m_spec.width * bytespp); unsigned char *src, *dst, *tmp = &flip[0]; for (int y = 0; y < m_spec.height / 2; y++) { src = &m_buf[(m_spec.height - y - 1) * m_spec.width * bytespp]; dst = &m_buf[y * m_spec.width * bytespp]; memcpy(tmp, src, m_spec.width * bytespp); memcpy(src, dst, m_spec.width * bytespp); memcpy(dst, tmp, m_spec.width * bytespp); } }*/ if (m_tga.attr & FLAG_X_FLIP) { //std::cerr << "[tga] x flipping\n"; std::vector flip (bytespp * m_spec.width / 2); unsigned char *src, *dst, *tmp = &flip[0]; for (int y = 0; y < m_spec.height; y++) { src = &m_buf[y * m_spec.width * bytespp]; dst = &m_buf[(y * m_spec.width + m_spec.width / 2) * bytespp]; memcpy(tmp, src, bytespp * m_spec.width / 2); memcpy(src, dst, bytespp * m_spec.width / 2); memcpy(dst, tmp, bytespp * m_spec.width / 2); } } if (m_alpha != TGA_ALPHA_PREMULTIPLIED) { // Convert to associated unless we were requested not to do so if (m_spec.alpha_channel != -1 && !m_keep_unassociated_alpha) { int size = m_spec.width * m_spec.height; float gamma = m_spec.get_float_attribute ("oiio:Gamma", 1.0f); associateAlpha ((unsigned char *)&m_buf[0], size, m_spec.nchannels, m_spec.alpha_channel, gamma); } } return true; } bool TGAInput::close () { if (m_file) { fclose (m_file); m_file = NULL; } init(); // Reset to initial state return true; } bool TGAInput::read_native_scanline (int y, int z, void *data) { if (m_buf.empty ()) readimg (); if (m_tga.attr & FLAG_Y_FLIP) y = m_spec.height - y - 1; size_t size = spec().scanline_bytes(); memcpy (data, &m_buf[0] + y * size, size); return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/targa.imageio/targaoutput.cpp0000644000175000017500000005564712271062644022723 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "targa_pvt.h" #include "dassert.h" #include "typedesc.h" #include "strutil.h" #include "imageio.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace TGA_pvt; class TGAOutput : public ImageOutput { public: TGAOutput (); virtual ~TGAOutput (); virtual const char * format_name (void) const { return "targa"; } virtual bool supports (const std::string &feature) const { // Support nothing nonstandard return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle bool m_want_rle; ///< Whether the client asked for RLE bool m_convert_alpha; ///< Do we deassociate alpha? float m_gamma; ///< Gamma to use for alpha conversion std::vector m_scratch; int m_idlen; ///< Length of the TGA ID block // Initialize private members to pre-opened state void init (void) { m_file = NULL; m_convert_alpha = true; m_gamma = 1.0; } // Helper function to write the TGA 2.0 data fields, called by close() bool write_tga20_data_fields (); /// Helper function to flush a non-run-length packet /// inline void flush_rawp (unsigned char *& src, int size, int start); /// Helper function to flush a run-length packet /// inline void flush_rlp (unsigned char *buf, int size); /// Helper - write, with error detection (no byte swapping!) template bool fwrite (const T *buf, size_t itemsize=sizeof(T), size_t nitems=1) { if (itemsize*nitems == 0) return true; size_t n = std::fwrite (buf, itemsize, nitems, m_file); if (n != nitems) error ("Write error: wrote %d records of %d", (int)n, (int)nitems); return n == nitems; } /// Helper -- write a 'short' with byte swapping if necessary bool fwrite (uint16_t s) { if (bigendian()) swap_endian (&s); return fwrite (&s, sizeof(s), 1); } bool fwrite (uint32_t i) { if (bigendian()) swap_endian (&i); return fwrite (&i, sizeof(i), 1); } /// Helper -- pad with zeroes bool pad (size_t n=1) { while (n--) if (fputc (0, m_file)) return false; return true; } /// Helper -- write string, with padding and/or truncation bool fwrite_padded (const std::string &s, size_t len) { size_t slen = std::min (s.length(), len-1); return fwrite (s.c_str(), slen) && pad(len-slen); } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *targa_output_imageio_create () { return new TGAOutput; } // OIIO_EXPORT int tga_imageio_version = OIIO_PLUGIN_VERSION; // it's in tgainput.cpp OIIO_EXPORT const char * targa_output_extensions[] = { "tga", "tpic", NULL }; OIIO_PLUGIN_EXPORTS_END TGAOutput::TGAOutput () { init (); } TGAOutput::~TGAOutput () { // Close, if not already done. close (); } bool TGAOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } close (); // Close any already-opened file m_spec = userspec; // Stash the spec m_spec.set_format (TypeDesc::UINT8); // TARGA only supports 8 bits // Check for things this format doesn't support if (m_spec.width < 1 || m_spec.height < 1) { error ("Image resolution must be at least 1x1, you asked for %d x %d", m_spec.width, m_spec.height); return false; } if (m_spec.depth < 1) m_spec.depth = 1; else if (m_spec.depth > 1) { error ("TGA does not support volume images (depth > 1)"); return false; } if (m_spec.nchannels < 1 || m_spec.nchannels > 4) { error ("TGA only supports 1-4 channels, not %d", m_spec.nchannels); return false; } m_file = Filesystem::fopen (name, "wb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } // Force 8 bit integers m_spec.set_format (TypeDesc::UINT8); // check if the client wants the image to be run length encoded // currently only RGB RLE is supported m_want_rle = (m_spec.get_string_attribute ("compression", "none") != std::string("none")) && m_spec.nchannels >= 3; // TGA does not dictate unassociated (un-"premultiplied") alpha but many // implementations assume it even if we set TGA_ALPHA_PREMULTIPLIED, so // always write unassociated alpha m_convert_alpha = m_spec.alpha_channel != -1 && !m_spec.get_int_attribute("oiio:UnassociatedAlpha", 0); m_gamma = m_spec.get_float_attribute ("oiio:Gamma", 1.0); // prepare and write Targa header tga_header tga; memset (&tga, 0, sizeof (tga)); tga.type = m_spec.nchannels <= 2 ? TYPE_GRAY : (m_want_rle ? TYPE_RGB_RLE : TYPE_RGB); tga.bpp = m_spec.nchannels * 8; tga.width = m_spec.width; tga.height = m_spec.height; #if 0 // no one seems to adhere to this part of the spec... tga.x_origin = m_spec.x; tga.y_origin = m_spec.y; #endif // handle image ID; save it to disk later on std::string id = m_spec.get_string_attribute ("targa:ImageID", ""); // the format only allows for 255 bytes tga.idlen = std::min(id.length(), (size_t)255); m_idlen = tga.idlen; if (m_spec.nchannels % 2 == 0) // if we have alpha tga.attr = 8; // 8 bits of alpha // force Y flip when using RLE // for raw (non-RLE) images we can use random access, so we can dump the // image in the default top-bottom scanline order for maximum // compatibility (not all software supports the Y flip flag); however, // once RLE kicks in, we lose the ability to predict the byte offsets of // scanlines, so we just dump the data in the order it comes in and use // this flag instead if (m_want_rle) tga.attr |= FLAG_Y_FLIP; if (bigendian()) { // TGAs are little-endian swap_endian (&tga.cmap_type); swap_endian (&tga.type); swap_endian (&tga.cmap_first); swap_endian (&tga.cmap_length); swap_endian (&tga.cmap_size); swap_endian (&tga.x_origin); swap_endian (&tga.y_origin); swap_endian (&tga.width); swap_endian (&tga.height); swap_endian (&tga.bpp); swap_endian (&tga.attr); } // due to struct packing, we may get a corrupt header if we just dump the // struct to the file; to adress that, write every member individually // save some typing if (!fwrite(&tga.idlen) || !fwrite(&tga.cmap_type) || !fwrite(&tga.type) || !fwrite(&tga.cmap_first) || !fwrite(&tga.cmap_length) || !fwrite(&tga.cmap_size) || !fwrite(&tga.x_origin) || !fwrite(&tga.y_origin) || !fwrite(&tga.width) || !fwrite(&tga.height) || !fwrite(&tga.bpp) || !fwrite(&tga.attr)) { fclose (m_file); m_file = NULL; return false; } // dump comment to file, don't bother about null termination if (tga.idlen) { if (!fwrite(id.c_str(), tga.idlen)) { fclose (m_file); m_file = NULL; return false; } } return true; } bool TGAOutput::write_tga20_data_fields () { if (m_file) { // write out the TGA 2.0 data fields // FIXME: write out the developer area; according to Larry, // it's probably safe to ignore it altogether until someone complains // that it's missing :) fseek (m_file, 0, SEEK_END); // write out the thumbnail, if there is one uint32_t ofs_thumb = 0; unsigned char tw = m_spec.get_int_attribute ("thumbnail_width", 0); unsigned char th = m_spec.get_int_attribute ("thumbnail_width", 0); int tc = m_spec.get_int_attribute ("thumbnail_nchannels", 0); if (tw && th && tc == m_spec.nchannels) { ImageIOParameter *p = m_spec.find_attribute ("thumbnail_image"); if (p) { ofs_thumb = (uint32_t) ftell (m_file); // dump thumbnail size if (!fwrite (&tw) || !fwrite (&th) || !fwrite (p->data(), p->datasize())) { return false; } } } // prepare the footer tga_footer foot = {(uint32_t)ftell (m_file), 0, "TRUEVISION-XFILE."}; // write out the extension area // ext area size -- 2 bytes, always short(495) fwrite (uint16_t(495)); // author - 41 bytes fwrite_padded (m_spec.get_string_attribute("Artist"), 41); // image comment - 324 bytes fwrite_padded (m_spec.get_string_attribute("ImageDescription"), 324); // timestamp - 6 shorts (month, day, year, hour, minute, second) { std::string dt = m_spec.get_string_attribute ("DateTime", ""); uint16_t y, m, d, h, i, s; if (dt.length() > 0) sscanf (dt.c_str(), "%04hu:%02hu:%02hu %02hu:%02hu:%02hu", &y, &m, &d, &h, &i, &s); else y = m = d = h = i = s = 0; if (!fwrite(m) || !fwrite(d) || !fwrite(y) || !fwrite(h) || !fwrite(i) || !fwrite(s)) { return false; } } // job ID - 41 bytes fwrite_padded (m_spec.get_string_attribute("DocumentName"), 41); // job time - 3 shorts (hours, minutes, seconds) { std::string jt = m_spec.get_string_attribute ("targa:JobTime", ""); uint16_t h, m, s; if (jt.length() > 0) sscanf (jt.c_str(), "%hu:%02hu:%02hu", &h, &m, &s); else h = m = s = 0; if (!fwrite(h) || !fwrite(m) || !fwrite(s)) return false; } // software ID -- 41 bytes fwrite_padded (m_spec.get_string_attribute("Software"), 41); // software version - 3 bytes (first 2 bytes: version*100) if (!fwrite(uint16_t(OIIO_VERSION))) return false; pad (1); // key colour (ARGB) -- punt and write 0 pad (4); // pixel aspect ratio -- two shorts, giving a ratio { float ratio = m_spec.get_float_attribute ("PixelAspectRatio", 1.f); float EPS = 1E-5f; if (ratio >= (0.f+EPS) && ((ratio <= (1.f-EPS))||(ratio >= (1.f+EPS)))) { // FIXME: invent a smarter way to convert to a vulgar fraction? // numerator fwrite (uint16_t(ratio * 10000.f)); // numerator fwrite (uint16_t(10000)); // denominator } else { // just dump two zeros in there fwrite (uint16_t(0)); fwrite (uint16_t(0)); } } // gamma -- two shorts, giving a ratio if (Strutil::iequals (m_spec.get_string_attribute("oiio:ColorSpace"), "GammaCorrected")) { // FIXME: invent a smarter way to convert to a vulgar fraction? // NOTE: the spec states that only 1 decimal place of precision // is needed, thus the expansion by 10 // numerator fwrite (uint16_t(m_gamma*10.0f)); fwrite (uint16_t(10)); } else { // just dump two zeros in there fwrite (uint16_t(0)); fwrite (uint16_t(0)); } // offset to colour correction table - 4 bytes // FIXME: support this once it becomes clear how it's actually supposed // to be used... the spec is very unclear about this // for the time being just dump four NULL bytes pad (4); // offset to thumbnail - 4 bytes if (!fwrite(ofs_thumb)) return false; // offset to scanline table - 4 bytes // not used very widely, don't bother unless someone complains pad (4); // alpha type - one byte unsigned char at = (m_spec.nchannels % 2 == 0) ? TGA_ALPHA_USEFUL : TGA_ALPHA_NONE; if (!fwrite(&at)) return false; // write out the TGA footer if (!fwrite(foot.ofs_ext) || !fwrite(foot.ofs_dev) || !fwrite(&foot.signature, 1, sizeof(foot.signature))) { return false; } } return true; } bool TGAOutput::close () { bool ok = true; if (m_file) { ok &= write_tga20_data_fields (); // close the stream fclose (m_file); m_file = NULL; } init (); // re-initialize return ok; } inline void TGAOutput::flush_rlp (unsigned char *buf, int size) { // early out if (size < 1) return; // write packet header unsigned char h = (size - 1) | 0x80; // write packet pixel if (!fwrite(&h) || !fwrite (buf, m_spec.nchannels)) { // do something intelligent? return; } } inline void TGAOutput::flush_rawp (unsigned char *& src, int size, int start) { // early out if (size < 1) return; // write packet header unsigned char h = (size - 1) & ~0x80; if (!fwrite (&h)) return; // rewind the scanline and flush packet pixels unsigned char buf[4]; int n = m_spec.nchannels; for (int i = 0; i < size; i++) { if (n <= 2) { // 1- and 2-channels can write directly if (!fwrite (src+start, n)) { return; } } else { // 3- and 4-channel must swap red and blue buf[0] = src[(start + i) * n + 2]; buf[1] = src[(start + i) * n + 1]; buf[2] = src[(start + i) * n + 0]; if (n > 3) buf[3] = src[(start + i) * n + 3]; if (!fwrite (buf, n)) { return; } } } } template static void deassociateAlpha (T * data, int size, int channels, int alpha_channel, float gamma) { unsigned int max = std::numeric_limits::max(); if (gamma == 1){ for (int x = 0; x < size; ++x, data += channels) if (data[alpha_channel]) for (int c = 0; c < channels; c++) if (c != alpha_channel) { unsigned int f = data[c]; f = (f * max) / data[alpha_channel]; data[c] = (T) std::min (max, f); } } else { for (int x = 0; x < size; ++x, data += channels) if (data[alpha_channel]) { // See associateAlpha() for an explanation. float alpha_deassociate = pow((float)max / data[alpha_channel], gamma); for (int c = 0; c < channels; c++) if (c != alpha_channel) data[c] = static_cast (std::min (max, (unsigned int)(data[c] * alpha_deassociate))); } } } bool TGAOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { y -= m_spec.y; m_spec.auto_stride (xstride, format, spec().nchannels); data = to_native_scanline (format, data, xstride, m_scratch); if (m_scratch.empty() || data != &m_scratch[0]) { m_scratch.assign ((unsigned char *)data, (unsigned char *)data+m_spec.scanline_bytes()); data = &m_scratch[0]; } if (m_convert_alpha) { deassociateAlpha ((unsigned char *)data, m_spec.width, m_spec.nchannels, m_spec.alpha_channel, m_gamma); } unsigned char *bdata = (unsigned char *)data; if (m_want_rle) { // Run Length Encoding // it's only profitable if n * b > 1 + b, where: // n is the number of pixels in a run // b is the pixel size in bytes // FIXME: optimize runs spanning across multiple scanlines? unsigned char buf[4] = { 0, 0, 0, 0 }; unsigned char buf2[4] = { 0, 0, 0, 0 }; bool rlp = false; int rlcount = 0, rawcount = 0; for (int x = 0; x < m_spec.width; x++) { // save off previous pixel memcpy (buf2, buf, sizeof (buf2)); // read the new one switch (m_spec.nchannels) { #if 0 case 1: buf[0] = bdata[x ]; break; case 2: buf[0] = bdata[(x * 2 + 0)]; buf[1] = bdata[(x * 2 + 1)]; break; #endif case 3: buf[0] = bdata[(x * 3 + 2)]; buf[1] = bdata[(x * 3 + 1)]; buf[2] = bdata[(x * 3 + 0)]; break; case 4: buf[0] = bdata[(x * 4 + 2)]; buf[1] = bdata[(x * 4 + 1)]; buf[2] = bdata[(x * 4 + 0)]; buf[3] = bdata[(x * 4 + 3)]; break; } //std::cerr << "[tga] x = " << x << "\n"; if (x == 0) { // initial encoder state rlp = false; rlcount = 0; rawcount = 1; continue; // nothing to work with yet (need 2 pixels) } if (rlp) { // in the middle of a run-length packet // flush the packet if the run ends or max packet size is hit if (rlcount < 0x80 && buf[0] == buf2[0] && buf[1] == buf2[1] && buf[2] == buf2[2] && buf[3] == buf2[3]) rlcount++; else { // run broken or max size hit, flush RL packet and start // a new raw one flush_rlp (&buf2[0], rlcount); // count raw pixel rawcount++; // reset state rlcount -= 0x80; if (rlcount < 0) rlcount = 0; rlp = false; } } else { // in the middle of a raw data packet if (rawcount > 0 // make sure we have material to check && buf[0] == buf2[0] && buf[1] == buf2[1] && buf[2] == buf2[2] && buf[3] == buf2[3]) { // run continues, possibly material for RLE if (rlcount == 0) { // join the previous pixel into the run rawcount--; rlcount++; } rlcount++; } else { // run broken // apart from the pixel we've just read, add any remaining // ones we may have considered for RLE rawcount += 1 + rlcount; rlcount = 0; // flush the packet if max packet size is hit if (rawcount >= 0x80) { // subtract 128 instead of setting to 0 because there // is a chance that rawcount is now > 128; if so, we'll // catch the remainder in the next iteration rawcount -= 0x80; flush_rawp (bdata, 0x80, x - 0x80 + 1); } } // check the encoding profitability condition //if (rlcount * m_spec.nchannels > 1 + m_spec.nchannels) { // NOTE: the condition below is valid, nchannels can be 1 if (rlcount > 1 + 1 / m_spec.nchannels) { // flush a packet of what we had so far flush_rawp (bdata, rawcount, x - rawcount - rlcount + 1); // reset state rawcount = 0; // mark this as a run-length packet rlp = true; } } } // flush anything that may be left if (rlp) flush_rlp (&buf2[0], rlcount); else { rawcount += rlcount; flush_rawp (bdata, rawcount, m_spec.width - rawcount); } } else { // raw, non-compressed data // seek to the correct scanline int n = m_spec.nchannels; int w = m_spec.width; fseek(m_file, 18 + m_idlen + (m_spec.height - y - 1) * w * n, SEEK_SET); if (n <= 2) { // 1- and 2-channels can write directly if (!fwrite (bdata, n, w)) { return false; } } else { // 3- and 4-channels must swap R and B std::vector buf; buf.assign (bdata, bdata + n*w); for (int x = 0; x < m_spec.width; x++) std::swap (buf[x*n], buf[x*n+2]); if (!fwrite (&buf[0], n, w)) { return false; } } } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/targa.imageio/CMakeLists.txt0000644000175000017500000000006112271062644022354 0ustar mfvmfvadd_oiio_plugin (targainput.cpp targaoutput.cpp) openimageio-1.3.12~dfsg0.orig/src/targa.imageio/targa_pvt.h0000644000175000017500000001010312271062644021752 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_TARGA_PVT_H #define OPENIMAGEIO_TARGA_PVT_H #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace TGA_pvt { // IneQuation was here enum tga_image_type { TYPE_NODATA = 0, ///< image with no data (why even spec it?) TYPE_PALETTED = 1, ///< paletted RGB TYPE_RGB = 2, ///< can include alpha TYPE_GRAY = 3, ///< can include alpha TYPE_PALETTED_RLE = 9, ///< same as PALETTED but run-length encoded TYPE_RGB_RLE = 10, ///< same as RGB but run-length encoded TYPE_GRAY_RLE = 11 ///< same as GRAY but run-length encoded }; enum tga_flags { FLAG_X_FLIP = 0x10, ///< right-left image FLAG_Y_FLIP = 0x20 ///< top-down image }; /// Targa file header. /// typedef struct { uint8_t idlen; ///< image comment length uint8_t cmap_type; ///< palette type uint8_t type; ///< image type (see tga_image_type) uint16_t cmap_first; ///< offset to first entry uint16_t cmap_length; ///< uint8_t cmap_size; ///< palette size uint16_t x_origin; ///< uint16_t y_origin; ///< uint16_t width; ///< image width uint16_t height; ///< image height uint8_t bpp; ///< bits per pixel uint8_t attr; ///< attribs (alpha bits and \ref tga_flags) } tga_header; /// TGA 2.0 file footer. /// typedef struct { uint32_t ofs_ext; ///< offset to the extension area uint32_t ofs_dev; ///< offset to the developer directory char signature[18]; ///< file signature string } tga_footer; /// TGA 2.0 developer directory entry typedef struct { uint16_t tag; ///< tag uint32_t ofs; ///< byte offset to the tag data uint32_t size; ///< tag data length } tga_devdir_tag; // this is used in the extension area enum tga_alpha_type { TGA_ALPHA_NONE = 0, ///< no alpha data included TGA_ALPHA_UNDEFINED_IGNORE = 1, ///< can ignore alpha TGA_ALPHA_UNDEFINED_RETAIN = 2, ///< undefined, but should be retained TGA_ALPHA_USEFUL = 3, ///< useful alpha data is present TGA_ALPHA_PREMULTIPLIED = 4 ///< alpha is pre-multiplied (arrrgh!) // values 5-127 are reserved // values 128-255 are unassigned }; } // namespace TGA_pvt OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_TARGA_PVT_H openimageio-1.3.12~dfsg0.orig/src/make/0000755000175000017500000000000012271062644016025 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/make/detectplatform.mk0000644000175000017500000000411112271062644021370 0ustar mfvmfv# License and copyright goes here ######################################################################### # detectplatform.mk # # Figure out which platform we are building on/for, set ${platform} and # ${hw}. # # This is called from master.mk ######################################################################### ######################################################################### # Figure out which platform we are building on/for # Start with unknown platform platform ?= unknown # Use 'uname -m' to determine the hardware architecture. This should # return "x86" or "x86_64" hw := ${shell uname -m} #$(info hardware = ${hw}) ifneq (${hw},x86) ifneq (${hw},x86_64) ifneq (${hw},i386) ifneq (${hw},i686) $(error "ERROR: Unknown hardware architecture") endif endif endif endif # Use 'uname', lowercased and stripped of pesky stuff, and the hardware # architecture in ${hw} to determine the platform that we're building # for, and store its name in ${platform}. uname := ${shell uname | sed 's/_NT-.*//' | tr '[:upper:]' '[:lower:]'} #$(info uname = ${uname}) ifeq (${platform},unknown) # Linux ifeq (${uname},linux) platform := linux ifeq (${hw},x86_64) platform := linux64 endif endif # Windows ifeq (${uname},cygwin) platform := windows ifeq (${hw},x86_64) platform := windows64 endif endif # Mac OS X ifeq (${uname},darwin) platform := macosx endif # If we haven't been able to determine the platform from uname, use # whatever is in $ARCH, if it's set. ifeq (${platform},unknown) ifneq (${ARCH},) platform := ${ARCH} endif endif # Manual override: if there's an environment variable $BUILDARCH, use that # no matter what ifneq (${BUILDARCH},) platform := ${BUILDARCH} endif endif # Throw an error if nothing worked ifeq (${platform},unknown) $(error "ERROR: Could not determine the platform") endif $(info platform=${platform}, hw=${hw}) # end of section where we figure out the platform ######################################################################### openimageio-1.3.12~dfsg0.orig/src/include/0000755000175000017500000000000012271062644016533 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/include/sysutil.h0000644000175000017500000001251212271062644020421 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////// /// @file sysutil.h /// /// @brief Platform-independent utilities for various OS, hardware, and /// system resource functionality, all in namespace Sysutil. ///////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_SYSUTIL_H #define OPENIMAGEIO_SYSUTIL_H #include #include #ifdef __MINGW32__ #include // for alloca #endif #include "export.h" #include "version.h" /// allocates memory, equivalent of C99 type var_name[size] #define ALLOCA(type, size) ((type*)alloca((size) * sizeof (type))) // Define a macro that can be used for memory alignment. // I think that in a future world of C++1x compatibility, all these can // be replaced with [[ align(size) ]]. #if defined (_MSC_VER) # define OIIO_ALIGN(size) __declspec(align(size)) #elif defined (__GNUC__) # define OIIO_ALIGN(size) __attribute__((aligned(size))) #elif defined (__INTEL_COMPILER) # define OIIO_ALIGN(size) __declspec(align((size))) #else # error "Don't know how to define OIIO_ALIGN" #endif // Cache line size is 64 on all modern x86 CPUs. If this changes or we // anticipate ports to other architectures, we'll need to change this. #define OIIO_CACHE_LINE_SIZE 64 // Align the next declaration to be on its own cache line #define OIIO_CACHE_ALIGN OIIO_ALIGN(OIIO_CACHE_LINE_SIZE) // gcc defines a special intrinsic to use in conditionals that can speed // up extremely performance-critical spots if the conditional usually // (or rarely) is true. You use it by replacing // if (x) ... // with // if (OIIO_LIKELY(x)) ... // if you think x will usually be true // or // if (OIIO_UNLIKELY(x)) ... // if you think x will rarely be true // Caveat: Programmers are notoriously bad at guessing this, so it // should be used only with thorough benchmarking. #ifdef __GNUC__ #define OIIO_LIKELY(x) (__builtin_expect((x), 1)) #define OIIO_UNLIKELY(x) (__builtin_expect((x), 0)) #else #define OIIO_LIKELY(x) (x) #define OIIO_UNLIKELY(x) (x) #endif OIIO_NAMESPACE_ENTER { /// @namespace Sysutil /// /// @brief Platform-independent utilities for various OS, hardware, and /// system resource functionality. namespace Sysutil { /// The amount of memory currently being used by this process, in bytes. /// If resident==true (the default), it will report just the resident /// set in RAM; if resident==false, it returns the full virtual arena /// (which can be misleading because gcc allocates quite a bit of /// virtual, but not actually resident until malloced, memory per /// thread). OIIO_API size_t memory_used (bool resident=true); /// The amount of physical RAM on this machine, in bytes. /// If it can't figure it out, it will return 0. OIIO_API size_t physical_memory (); /// Convert calendar time pointed by 'time' into local time and save it in /// 'converted_time' variable OIIO_API void get_local_time (const time_t *time, struct tm *converted_time); /// Return the full path of the currently-running executable program. /// OIIO_API std::string this_program_path (); /// Sleep for the given number of microseconds. /// OIIO_API void usleep (unsigned long useconds); /// Try to figure out how many columns wide the terminal window is. /// May not be correct all all systems, will default to 80 if it can't /// figure it out. OIIO_API int terminal_columns (); /// Try to put the process into the background so it doesn't continue to /// tie up any shell that it was launched from. The arguments are the /// argc/argv that describe the program and its command line arguments. /// Return true if successful, false if it was unable to do so. OIIO_API bool put_in_background (int argc, char* argv[]); } // namespace Sysutils } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_SYSUTIL_H openimageio-1.3.12~dfsg0.orig/src/include/typedesc.h0000644000175000017500000003422012271062644020525 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// The TypeDesc class is used to describe simple data types. #ifndef OPENIMAGEIO_TYPEDESC_H #define OPENIMAGEIO_TYPEDESC_H #if defined(_MSC_VER) // Ignore warnings about conditional expressions that always evaluate true // on a given platform but may evaluate differently on another. There's // nothing wrong with such conditionals. # pragma warning (disable : 4127) #endif #ifndef NULL #define NULL 0 #endif #include #include #include #include #include "export.h" #include "version.h" OIIO_NAMESPACE_ENTER { ///////////////////////////////////////////////////////////////////////////// /// A TypeDesc describes simple data types. /// /// It frequently comes up (in my experience, with renderers and image /// handling programs) that you want a way to describe data that is passed /// through APIs through blind pointers. These are some simple classes /// that provide a simple type descriptor system. This is not meant to /// be comprehensive -- for example, there is no provision for structs, /// unions, pointers, const, or 'nested' type definitions. Just simple /// integer and floating point, *common* aggregates such as 3-points, /// and reasonably-lengthed arrays thereof. /// ///////////////////////////////////////////////////////////////////////////// struct OIIO_API TypeDesc { /// BASETYPE is a simple enum for the C/C++ built-in types. /// enum BASETYPE { UNKNOWN, NONE, UCHAR, UINT8=UCHAR, CHAR, INT8=CHAR, USHORT, UINT16=USHORT, SHORT, INT16=SHORT, UINT, UINT32=UINT, INT, INT32=INT, ULONGLONG, UINT64=ULONGLONG, LONGLONG, INT64=LONGLONG, HALF, FLOAT, DOUBLE, STRING, PTR, LASTBASE }; /// AGGREGATE describes whether our type is a simple scalar of /// one of the BASETYPE's, or one of several simple aggregates. enum AGGREGATE { SCALAR=1, VEC2=2, VEC3=3, VEC4=4, MATRIX44=16 }; /// VECSEMANTICS gives hints about what the data represent (for /// example, if a spatial vector, whether it should transform as /// a point, direction vector, or surface normal). enum VECSEMANTICS { NOXFORM=0, NOSEMANTICS=0, // no semantic hints COLOR, // color POINT, // spatial location VECTOR, // spatial direction NORMAL, // surface normal TIMECODE, // SMPTE timecode (should be int[2]) KEYCODE // SMPTE keycode (should be int[7]) }; unsigned char basetype; ///< C data type at the heart of our type unsigned char aggregate; ///< What kind of AGGREGATE is it? unsigned char vecsemantics; ///< What does the vec represent? unsigned char reserved; ///< Reserved for future expansion int arraylen; ///< Array length, 0 = not array, -1 = unsized /// Construct from a BASETYPE and optional aggregateness and /// transformation rules. TypeDesc (BASETYPE btype=UNKNOWN, AGGREGATE agg=SCALAR, VECSEMANTICS xform=NOXFORM) : basetype(static_cast(btype)), aggregate(static_cast(agg)), vecsemantics(static_cast(xform)), reserved(0), arraylen(0) { } /// Construct an array of a non-aggregate BASETYPE. /// TypeDesc (BASETYPE btype, int arraylength) : basetype(static_cast(btype)), aggregate(SCALAR), vecsemantics(NOXFORM), reserved(0), arraylen(arraylength) { } /// Construct an array from BASETYPE, AGGREGATE, and array length, /// with unspecified (or moot) vector transformation semantics. TypeDesc (BASETYPE btype, AGGREGATE agg, int arraylength) : basetype(static_cast(btype)), aggregate(static_cast(agg)), vecsemantics(NOXFORM), reserved(0), arraylen(arraylength) { } /// Construct an array from BASETYPE, AGGREGATE, VECSEMANTICS, and /// array length. TypeDesc (BASETYPE btype, AGGREGATE agg, VECSEMANTICS xform, int arraylength) : basetype(static_cast(btype)), aggregate(static_cast(agg)), vecsemantics(static_cast(xform)), reserved(0), arraylen(arraylength) { } /// Construct from a string (e.g., "float[3]"). If no valid /// type could be assembled, set base to UNKNOWN. TypeDesc (const char *typestring); /// Copy constructor. TypeDesc (const TypeDesc &t) : basetype(t.basetype), aggregate(t.aggregate), vecsemantics(t.vecsemantics), reserved(0), arraylen(t.arraylen) { } /// Return the name, for printing and whatnot. For example, /// "float", "int[5]", "normal" const char *c_str() const; friend std::ostream& operator<< (std::ostream& o, TypeDesc t) { o << t.c_str(); return o; } /// Return the number of elements: 1 if not an array, or the array /// length. size_t numelements () const { return (arraylen >= 1 ? arraylen : 1); } /// Return the size, in bytes, of this type. /// size_t size () const { size_t a = (size_t) (arraylen > 0 ? arraylen : 1); if (sizeof(size_t) > sizeof(int)) { // size_t has plenty of room for this multiplication return a * elementsize(); } else { // need overflow protection unsigned long long s = (unsigned long long) a * elementsize(); const size_t toobig = std::numeric_limits::max(); return s < toobig ? (size_t)s : toobig; } } /// Return the type of one element, i.e., strip out the array-ness. /// TypeDesc elementtype () const { TypeDesc t (*this); t.arraylen = 0; return t; } /// Return the size, in bytes, of one element of this type (that is, /// ignoring whether it's an array). size_t elementsize () const { return aggregate * basesize(); } // /// Return just the underlying C scalar type, i.e., strip out the // /// array-ness and the aggregateness. // BASETYPE basetype () const { return TypeDesc(base); } /// Return the base type size, i.e., stripped of both array-ness /// and aggregateness. size_t basesize () const; /// Set *this to the type described in the string. Return the /// length of the part of the string that describes the type. If /// no valid type could be assembled, return 0 and do not modify /// *this. size_t fromstring (const char *typestring); /// Compare two TypeDesc values for equality. /// bool operator== (const TypeDesc &t) const { return basetype == t.basetype && aggregate == t.aggregate && vecsemantics == t.vecsemantics && arraylen == t.arraylen; } /// Compare two TypeDesc values for inequality. /// bool operator!= (const TypeDesc &t) const { return ! (*this == t); } /// Compare a TypeDesc to a basetype (it's the same if it has the /// same base type and is not an aggregate or an array). friend bool operator== (const TypeDesc &t, BASETYPE b) { return (BASETYPE)t.basetype == b && (AGGREGATE)t.aggregate == SCALAR && t.arraylen == 0; } friend bool operator== (BASETYPE b, const TypeDesc &t) { return (BASETYPE)t.basetype == b && (AGGREGATE)t.aggregate == SCALAR && t.arraylen == 0; } /// Compare a TypeDesc to a basetype (it's the same if it has the /// same base type and is not an aggregate or an array). friend bool operator!= (const TypeDesc &t, BASETYPE b) { return (BASETYPE)t.basetype != b || (AGGREGATE)t.aggregate != SCALAR || t.arraylen != 0; } friend bool operator!= (BASETYPE b, const TypeDesc &t) { return (BASETYPE)t.basetype != b || (AGGREGATE)t.aggregate != SCALAR || t.arraylen != 0; } /// TypeDesc's are equivalent if they are equal, or if their only /// inequality is differing vector semantics. friend bool equivalent (TypeDesc a, TypeDesc b) { return a.basetype == b.basetype && a.aggregate == b.aggregate && a.arraylen == b.arraylen; } /// Member version of equivalent bool equivalent (TypeDesc b) const { return this->basetype == b.basetype && this->aggregate == b.aggregate && this->arraylen == b.arraylen; } /// Demote the type to a non-array /// void unarray (void) { arraylen = 0; } static const TypeDesc TypeFloat; static const TypeDesc TypeColor; static const TypeDesc TypeString; static const TypeDesc TypeInt; static const TypeDesc TypePoint; static const TypeDesc TypeVector; static const TypeDesc TypeNormal; static const TypeDesc TypeMatrix; static const TypeDesc TypeTimeCode; static const TypeDesc TypeKeyCode; }; /// Return a string containing the data values formatted according /// to the type and the optional formatting arguments. std::string tostring (TypeDesc type, const void *data, const char *float_fmt = "%f", // E.g. "%g" const char *string_fmt = "%s", // E.g. "\"%s\"" const char aggregate_delim[2] = "()", // Both sides of vector const char *aggregate_sep = ",", // E.g. ", " const char array_delim[2] = "{}", // Both sides of array const char *array_sep = ","); // E.g. "; " /// A template mechanism for getting the a base type from C type /// template struct BaseTypeFromC {}; template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::UINT8; }; template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::INT8; }; template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::UINT16; }; template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::INT16; }; template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::UINT; }; template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::INT; }; template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::UINT64; }; template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::INT64; }; #ifdef _HALF_H_ template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::HALF; }; #endif template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::FLOAT; }; template<> struct BaseTypeFromC { static const TypeDesc::BASETYPE value = TypeDesc::DOUBLE; }; /// A template mechanism for getting C type of TypeDesc::BASETYPE. /// template struct CType {}; template<> struct CType<(int)TypeDesc::UINT8> { typedef unsigned char type; }; template<> struct CType<(int)TypeDesc::INT8> { typedef char type; }; template<> struct CType<(int)TypeDesc::UINT16> { typedef unsigned short type; }; template<> struct CType<(int)TypeDesc::INT16> { typedef short type; }; template<> struct CType<(int)TypeDesc::UINT> { typedef unsigned int type; }; template<> struct CType<(int)TypeDesc::INT> { typedef int type; }; template<> struct CType<(int)TypeDesc::UINT64> { typedef unsigned long long type; }; template<> struct CType<(int)TypeDesc::INT64> { typedef long long type; }; #ifdef _HALF_H_ template<> struct CType<(int)TypeDesc::HALF> { typedef half type; }; #endif template<> struct CType<(int)TypeDesc::FLOAT> { typedef float type; }; template<> struct CType<(int)TypeDesc::DOUBLE> { typedef double type; }; // Deprecated! Some back-compatibility with Gelato typedef TypeDesc ParamType; typedef TypeDesc ParamBaseType; #define PT_FLOAT TypeDesc::FLOAT #define PT_UINT8 TypeDesc::UCHAR #define PT_INT8 TypeDesc::CHAR #define PT_UINT16 TypeDesc::USHORT #define PT_INT16 TypeDesc::SHORT #define PT_UINT TypeDesc::UINT #define PT_INT TypeDesc::INT #define PT_FLOAT TypeDesc::FLOAT #define PT_DOUBLE TypeDesc::DOUBLE #define PT_HALF TypeDesc::HALF #define PT_MATRIX TypeDesc(TypeDesc::FLOAT,TypeDesc::MATRIX44) #define PT_STRING TypeDesc::STRING #define PT_UNKNOWN TypeDesc::UNKNOWN #define PT_COLOR TypeDesc(TypeDesc::FLOAT,TypeDesc::VEC3,TypeDesc::COLOR) #define PT_POINT TypeDesc(TypeDesc::FLOAT,TypeDesc::VEC3,TypeDesc::POINT) #define PT_VECTOR TypeDesc(TypeDesc::FLOAT,TypeDesc::VEC3,TypeDesc::VECTOR) #define PT_NORMAL TypeDesc(TypeDesc::FLOAT,TypeDesc::VEC3,TypeDesc::NORMAL) } OIIO_NAMESPACE_EXIT #endif /* !defined(OPENIMAGEIO_TYPEDESC_H) */ openimageio-1.3.12~dfsg0.orig/src/include/SHA1.h0000644000175000017500000001531112271062644017401 0ustar mfvmfv/* 100% free public domain implementation of the SHA-1 algorithm by Dominik Reichl Web: http://www.dominik-reichl.de/ Version 1.8 - 2008-03-16 - Converted project files to Visual Studio 2008 format. - Added Unicode support for HashFile utility method. - Added support for hashing files using the HashFile method that are larger than 2 GB. - HashFile now returns an error code instead of copying an error message into the output buffer. - GetHash now returns an error code and validates the input parameter. - Added ReportHashStl STL utility method. - Added REPORT_HEX_SHORT reporting mode. - Improved Linux compatibility of test program. Version 1.7 - 2006-12-21 - Fixed buffer underrun warning that appeared when compiling with Borland C Builder (thanks to Rex Bloom and Tim Gallagher for the patch). - Breaking change: ReportHash writes the final hash to the start of the buffer, i.e. it's not appending it to the string anymore. - Made some function parameters const. - Added Visual Studio 2005 project files to demo project. Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches) - You can set the endianness in your files, no need to modify the header file of the CSHA1 class anymore. - Aligned data support. - Made support/compilation of the utility functions (ReportHash and HashFile) optional (useful when bytes count, for example in embedded environments). Version 1.5 - 2005-01-01 - 64-bit compiler compatibility added. - Made variable wiping optional (define SHA1_WIPE_VARIABLES). - Removed unnecessary variable initializations. - ROL32 improvement for the Microsoft compiler (using _rotl). Version 1.4 - 2004-07-22 - CSHA1 now compiles fine with GCC 3.3 under MacOS X (thanks to Larry Hastings). Version 1.3 - 2003-08-17 - Fixed a small memory bug and made a buffer array a class member to ensure correct working when using multiple CSHA1 class instances at one time. Version 1.2 - 2002-11-16 - Borlands C++ compiler seems to have problems with string addition using sprintf. Fixed the bug which caused the digest report function not to work properly. CSHA1 is now Borland compatible. Version 1.1 - 2002-10-11 - Removed two unnecessary header file includes and changed BOOL to bool. Fixed some minor bugs in the web page contents. Version 1.0 - 2002-06-20 - First official release. ======== Test Vectors (from FIPS PUB 180-1) ======== SHA1("abc") = A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 SHA1(A million repetitions of "a") = 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F */ #ifndef ___SHA1_HDR___ #define ___SHA1_HDR___ #include "export.h" #include "version.h" #if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS) #define SHA1_UTILITY_FUNCTIONS #endif #if !defined(SHA1_STL_FUNCTIONS) && !defined(SHA1_NO_STL_FUNCTIONS) #define SHA1_STL_FUNCTIONS #if !defined(SHA1_UTILITY_FUNCTIONS) #error STL functions require SHA1_UTILITY_FUNCTIONS. #endif #endif #include #ifdef SHA1_UTILITY_FUNCTIONS #include #include #endif #ifdef SHA1_STL_FUNCTIONS #include #endif #ifdef _MSC_VER #include #endif // You can define the endian mode in your files without modifying the SHA-1 // source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN // in your files, before including the SHA1.h header file. If you don't // define anything, the class defaults to little endian. #if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN) #define SHA1_LITTLE_ENDIAN #endif // If you want variable wiping, #define SHA1_WIPE_VARIABLES, if not, // #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it // defaults to wiping. #if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES) #define SHA1_WIPE_VARIABLES #endif #if defined(SHA1_HAS_TCHAR) #include #else #ifdef _MSC_VER #include #else #ifndef TCHAR #define TCHAR char #endif #ifndef _T #define _T(__x) (__x) #define _tmain main #define _tprintf printf #define _getts gets #define _tcslen strlen #define _tfopen fopen #define _tcscpy strcpy #define _tcscat strcat #define _sntprintf snprintf #endif #endif #endif // Fallback, if no 64-bit support #ifndef _fseeki64 #define _fseeki64 fseek #endif #ifndef _ftelli64 #define _ftelli64 ftell #endif /////////////////////////////////////////////////////////////////////////// // Define variable types #ifndef UINT_8 #ifdef _MSC_VER // Compiling with Microsoft compiler #define UINT_8 unsigned __int8 #else // !_MSC_VER #define UINT_8 unsigned char #endif // _MSC_VER #endif #ifndef UINT_32 #ifdef _MSC_VER // Compiling with Microsoft compiler #define UINT_32 unsigned __int32 #else // !_MSC_VER #if (ULONG_MAX == 0xFFFFFFFF) #define UINT_32 unsigned long #else #define UINT_32 unsigned int #endif #endif // _MSC_VER #endif // UINT_32 #ifndef INT_64 #ifdef _MSC_VER // Compiling with Microsoft compiler #define INT_64 __int64 #else // !_MSC_VER #define INT_64 long long #endif // _MSC_VER #endif // INT_64 #ifndef UINT_64 #ifdef _MSC_VER // Compiling with Microsoft compiler #define UINT_64 unsigned __int64 #else // !_MSC_VER #define UINT_64 unsigned long long #endif // _MSC_VER #endif // UINT_64 /////////////////////////////////////////////////////////////////////////// // Declare SHA-1 workspace OIIO_NAMESPACE_ENTER { typedef union { UINT_8 c[64]; UINT_32 l[16]; } SHA1_WORKSPACE_BLOCK; class CSHA1 { public: #ifdef SHA1_UTILITY_FUNCTIONS // Different formats for ReportHash enum REPORT_TYPE { REPORT_HEX = 0, REPORT_DIGIT = 1, REPORT_HEX_SHORT = 2 }; #endif // Constructor and destructor CSHA1(); ~CSHA1(); UINT_32 m_state[5]; UINT_32 m_count[2]; UINT_32 m_reserved0[1]; // Memory alignment padding UINT_8 m_buffer[64]; UINT_8 m_digest[20]; UINT_32 m_reserved1[3]; // Memory alignment padding void Reset(); // Update the hash value void Update(const UINT_8* pbData, UINT_32 uLen); #ifdef SHA1_UTILITY_FUNCTIONS // Hash in file contents bool HashFile(const TCHAR* tszFileName); #endif // Finalize hash, call before using ReportHash(Stl) void Final(); #ifdef SHA1_UTILITY_FUNCTIONS bool ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType = REPORT_HEX) const; #endif #ifdef SHA1_STL_FUNCTIONS bool ReportHashStl(std::basic_string& strOut, REPORT_TYPE rtReportType = REPORT_HEX) const; #endif bool GetHash(UINT_8* pbDest) const; private: // Private SHA-1 transformation void Transform(UINT_32* pState, const UINT_8* pBuffer); // Member variables UINT_8 m_workspace[64]; SHA1_WORKSPACE_BLOCK* m_block; // SHA1 pointer to the byte array above }; } OIIO_NAMESPACE_EXIT #endif // ___SHA1_HDR___ openimageio-1.3.12~dfsg0.orig/src/include/tbb/0000755000175000017500000000000012271062644017302 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/include/tbb/tbb_stddef.h0000644000175000017500000002355012271062644021560 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tbb_stddef_H #define __TBB_tbb_stddef_H // Marketing-driven product version #define TBB_VERSION_MAJOR 2 #define TBB_VERSION_MINOR 2 // Engineering-focused interface version #define TBB_INTERFACE_VERSION 4000 #define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000 // The oldest major interface version still supported // To be used in SONAME, manifests, etc. #define TBB_COMPATIBLE_INTERFACE_VERSION 2 #define __TBB_STRING_AUX(x) #x #define __TBB_STRING(x) __TBB_STRING_AUX(x) // We do not need defines below for resource processing on windows #if !defined RC_INVOKED // Define groups for Doxygen documentation /** * @defgroup algorithms Algorithms * @defgroup containers Containers * @defgroup memory_allocation Memory Allocation * @defgroup synchronization Synchronization * @defgroup timing Timing * @defgroup task_scheduling Task Scheduling */ // Simple text that is displayed on the main page of Doxygen documentation. /** * \mainpage Main Page * * Click the tabs above for information about the * - Modules (groups of functionality) implemented by the library * - Classes provided by the library * - Files constituting the library. * . * Please note that significant part of TBB functionality is implemented in the form of * template functions, descriptions of which are not accessible on the Classes * tab. Use Modules or Namespace/Namespace Members * tabs to find them. * * Additional pieces of information can be found here * - \subpage concepts * . */ /** \page concepts TBB concepts A concept is a set of requirements to a type, which are necessary and sufficient for the type to model a particular behavior or a set of behaviors. Some concepts are specific to a particular algorithm (e.g. algorithm body), while other ones are common to several algorithms (e.g. range concept). All TBB algorithms make use of different classes implementing various concepts. Implementation classes are supplied by the user as type arguments of template parameters and/or as objects passed as function call arguments. The library provides predefined implementations of some concepts (e.g. several kinds of \ref range_req "ranges"), while other ones must always be implemented by the user. TBB defines a set of minimal requirements each concept must conform to. Here is the list of different concepts hyperlinked to the corresponding requirements specifications: - \subpage range_req - \subpage parallel_do_body_req - \subpage parallel_for_body_req - \subpage parallel_reduce_body_req - \subpage parallel_scan_body_req - \subpage parallel_sort_iter_req **/ // Define preprocessor symbols used to determine architecture #if _WIN32||_WIN64 # if defined(_M_AMD64) # define __TBB_x86_64 1 # elif defined(_M_IA64) # define __TBB_ipf 1 # elif defined(_M_IX86)||defined(__i386__) // the latter for MinGW support # define __TBB_x86_32 1 # endif #else /* Assume generic Unix */ # if !__linux__ && !__APPLE__ # define __TBB_generic_os 1 # endif # if __x86_64__ # define __TBB_x86_64 1 # elif __ia64__ # define __TBB_ipf 1 # elif __i386__||__i386 // __i386 is for Sun OS # define __TBB_x86_32 1 # else # define __TBB_generic_arch 1 # endif #endif #if _MSC_VER // define the parts of stdint.h that are needed, but put them inside tbb::internal namespace tbb { namespace internal { typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; } // namespace internal } // namespace tbb #else #include #endif /* _MSC_VER */ #if _MSC_VER >=1400 #define __TBB_EXPORTED_FUNC __cdecl #define __TBB_EXPORTED_METHOD __thiscall #else #define __TBB_EXPORTED_FUNC #define __TBB_EXPORTED_METHOD #endif #include /* Need size_t and ptrdiff_t (the latter on Windows only) from here. */ #if _MSC_VER #define __TBB_tbb_windef_H #include "_tbb_windef.h" #undef __TBB_tbb_windef_H #endif #include "tbb_config.h" namespace tbb { //! Type for an assertion handler typedef void(*assertion_handler_type)( const char* filename, int line, const char* expression, const char * comment ); } #if TBB_USE_ASSERT //! Assert that x is true. /** If x is false, print assertion failure message. If the comment argument is not NULL, it is printed as part of the failure message. The comment argument has no other effect. */ #define __TBB_ASSERT(predicate,message) ((predicate)?((void)0):tbb::assertion_failure(__FILE__,__LINE__,#predicate,message)) #define __TBB_ASSERT_EX __TBB_ASSERT namespace tbb { //! Set assertion handler and return previous value of it. assertion_handler_type __TBB_EXPORTED_FUNC set_assertion_handler( assertion_handler_type new_handler ); //! Process an assertion failure. /** Normally called from __TBB_ASSERT macro. If assertion handler is null, print message for assertion failure and abort. Otherwise call the assertion handler. */ void __TBB_EXPORTED_FUNC assertion_failure( const char* filename, int line, const char* expression, const char* comment ); } // namespace tbb #else //! No-op version of __TBB_ASSERT. #define __TBB_ASSERT(predicate,comment) ((void)0) //! "Extended" version is useful to suppress warnings if a variable is only used with an assert #define __TBB_ASSERT_EX(predicate,comment) ((void)(1 && (predicate))) #endif /* TBB_USE_ASSERT */ //! The namespace tbb contains all components of the library. namespace tbb { //! The function returns the interface version of the TBB shared library being used. /** * The version it returns is determined at runtime, not at compile/link time. * So it can be different than the value of TBB_INTERFACE_VERSION obtained at compile time. */ extern "C" int __TBB_EXPORTED_FUNC TBB_runtime_interface_version(); //! Dummy type that distinguishes splitting constructor from copy constructor. /** * See description of parallel_for and parallel_reduce for example usages. * @ingroup algorithms */ class split { }; /** * @cond INTERNAL * @brief Identifiers declared inside namespace internal should never be used directly by client code. */ namespace internal { using std::size_t; //! An unsigned integral type big enough to hold a pointer. /** There's no guarantee by the C++ standard that a size_t is really big enough, but it happens to be for all platforms of interest. */ typedef size_t uintptr; //! A signed integral type big enough to hold a pointer. /** There's no guarantee by the C++ standard that a ptrdiff_t is really big enough, but it happens to be for all platforms of interest. */ typedef std::ptrdiff_t intptr; //! Report a runtime warning. void __TBB_EXPORTED_FUNC runtime_warning( const char* format, ... ); #if TBB_USE_ASSERT //! Set p to invalid pointer value. template inline void poison_pointer( T* & p ) { p = reinterpret_cast(-1); } #else template inline void poison_pointer( T* ) {/*do nothing*/} #endif /* TBB_USE_ASSERT */ //! Base class for types that should not be assigned. class no_assign { // Deny assignment void operator=( const no_assign& ); public: #if __GNUC__ //! Explicitly define default construction, because otherwise gcc issues gratuitous warning. no_assign() {} #endif /* __GNUC__ */ }; //! Base class for types that should not be copied or assigned. class no_copy: no_assign { //! Deny copy construction no_copy( const no_copy& ); public: //! Allow default construction no_copy() {} }; //! Class for determining type of std::allocator::value_type. template struct allocator_type { typedef T value_type; }; #if _MSC_VER //! Microsoft std::allocator has non-standard extension that strips const from a type. template struct allocator_type { typedef T value_type; }; #endif // Struct to be used as a version tag for inline functions. /** Version tag can be necessary to prevent loader on Linux from using the wrong symbol in debug builds (when inline functions are compiled as out-of-line). **/ struct version_tag_v3 {}; typedef version_tag_v3 version_tag; } // internal //! @endcond } // tbb #endif /* RC_INVOKED */ #endif /* __TBB_tbb_stddef_H */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/atomic.h0000644000175000017500000003373012271062644020735 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_atomic_H #define __TBB_atomic_H #include #include "tbb_stddef.h" #if _MSC_VER #define __TBB_LONG_LONG __int64 #else #define __TBB_LONG_LONG long long #endif /* _MSC_VER */ #include "tbb_machine.h" #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings #pragma warning (push) #pragma warning (disable: 4244 4267) #endif namespace tbb { //! Specifies memory fencing. enum memory_semantics { //! For internal use only. __TBB_full_fence, //! Acquire fence acquire, //! Release fence release }; //! @cond INTERNAL namespace internal { #if __GNUC__ || __SUNPRO_CC #define __TBB_DECL_ATOMIC_FIELD(t,f,a) t f __attribute__ ((aligned(a))); #elif defined(__INTEL_COMPILER)||_MSC_VER >= 1300 #define __TBB_DECL_ATOMIC_FIELD(t,f,a) __declspec(align(a)) t f; #else #error Do not know syntax for forcing alignment. #endif /* __GNUC__ */ template struct atomic_rep; // Primary template declared, but never defined. template<> struct atomic_rep<1> { // Specialization typedef int8_t word; int8_t value; }; template<> struct atomic_rep<2> { // Specialization typedef int16_t word; __TBB_DECL_ATOMIC_FIELD(int16_t,value,2) }; template<> struct atomic_rep<4> { // Specialization #if _MSC_VER && __TBB_WORDSIZE==4 // Work-around that avoids spurious /Wp64 warnings typedef intptr_t word; #else typedef int32_t word; #endif __TBB_DECL_ATOMIC_FIELD(int32_t,value,4) }; template<> struct atomic_rep<8> { // Specialization typedef int64_t word; __TBB_DECL_ATOMIC_FIELD(int64_t,value,8) }; template struct atomic_traits; // Primary template declared, but not defined. #define __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(S,M) \ template<> struct atomic_traits { \ typedef atomic_rep::word word; \ inline static word compare_and_swap( volatile void* location, word new_value, word comparand ) {\ return __TBB_CompareAndSwap##S##M(location,new_value,comparand); \ } \ inline static word fetch_and_add( volatile void* location, word addend ) { \ return __TBB_FetchAndAdd##S##M(location,addend); \ } \ inline static word fetch_and_store( volatile void* location, word value ) {\ return __TBB_FetchAndStore##S##M(location,value); \ } \ }; #define __TBB_DECL_ATOMIC_PRIMITIVES(S) \ template \ struct atomic_traits { \ typedef atomic_rep::word word; \ inline static word compare_and_swap( volatile void* location, word new_value, word comparand ) {\ return __TBB_CompareAndSwap##S(location,new_value,comparand); \ } \ inline static word fetch_and_add( volatile void* location, word addend ) { \ return __TBB_FetchAndAdd##S(location,addend); \ } \ inline static word fetch_and_store( volatile void* location, word value ) {\ return __TBB_FetchAndStore##S(location,value); \ } \ }; #if __TBB_DECL_FENCED_ATOMICS __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,__TBB_full_fence) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,__TBB_full_fence) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,__TBB_full_fence) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,__TBB_full_fence) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,acquire) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,acquire) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,acquire) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,acquire) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,release) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,release) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,release) __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,release) #else __TBB_DECL_ATOMIC_PRIMITIVES(1) __TBB_DECL_ATOMIC_PRIMITIVES(2) __TBB_DECL_ATOMIC_PRIMITIVES(4) __TBB_DECL_ATOMIC_PRIMITIVES(8) #endif //! Additive inverse of 1 for type T. /** Various compilers issue various warnings if -1 is used with various integer types. The baroque expression below avoids all the warnings (we hope). */ #define __TBB_MINUS_ONE(T) (T(T(0)-T(1))) //! Base class that provides basic functionality for atomic without fetch_and_add. /** Works for any type T that has the same size as an integral type, has a trivial constructor/destructor, and can be copied/compared by memcpy/memcmp. */ template struct atomic_impl { protected: atomic_rep rep; private: //! Union type used to convert type T to underlying integral type. union converter { T value; typename atomic_rep::word bits; }; public: typedef T value_type; template value_type fetch_and_store( value_type value ) { converter u, w; u.value = value; w.bits = internal::atomic_traits::fetch_and_store(&rep.value,u.bits); return w.value; } value_type fetch_and_store( value_type value ) { return fetch_and_store<__TBB_full_fence>(value); } template value_type compare_and_swap( value_type value, value_type comparand ) { converter u, v, w; u.value = value; v.value = comparand; w.bits = internal::atomic_traits::compare_and_swap(&rep.value,u.bits,v.bits); return w.value; } value_type compare_and_swap( value_type value, value_type comparand ) { return compare_and_swap<__TBB_full_fence>(value,comparand); } operator value_type() const volatile { // volatile qualifier here for backwards compatibility converter w; w.bits = __TBB_load_with_acquire( rep.value ); return w.value; } protected: value_type store_with_release( value_type rhs ) { converter u; u.value = rhs; __TBB_store_with_release(rep.value,u.bits); return rhs; } }; //! Base class that provides basic functionality for atomic with fetch_and_add. /** I is the underlying type. D is the difference type. StepType should be char if I is an integral type, and T if I is a T*. */ template struct atomic_impl_with_arithmetic: atomic_impl { public: typedef I value_type; template value_type fetch_and_add( D addend ) { return value_type(internal::atomic_traits::fetch_and_add( &this->rep.value, addend*sizeof(StepType) )); } value_type fetch_and_add( D addend ) { return fetch_and_add<__TBB_full_fence>(addend); } template value_type fetch_and_increment() { return fetch_and_add(1); } value_type fetch_and_increment() { return fetch_and_add(1); } template value_type fetch_and_decrement() { return fetch_and_add(__TBB_MINUS_ONE(D)); } value_type fetch_and_decrement() { return fetch_and_add(__TBB_MINUS_ONE(D)); } public: value_type operator+=( D addend ) { return fetch_and_add(addend)+addend; } value_type operator-=( D addend ) { // Additive inverse of addend computed using binary minus, // instead of unary minus, for sake of avoiding compiler warnings. return operator+=(D(0)-addend); } value_type operator++() { return fetch_and_add(1)+1; } value_type operator--() { return fetch_and_add(__TBB_MINUS_ONE(D))-1; } value_type operator++(int) { return fetch_and_add(1); } value_type operator--(int) { return fetch_and_add(__TBB_MINUS_ONE(D)); } }; #if __TBB_WORDSIZE == 4 // Plaforms with 32-bit hardware require special effort for 64-bit loads and stores. #if defined(__INTEL_COMPILER)||!defined(_MSC_VER)||_MSC_VER>=1400 template<> inline atomic_impl<__TBB_LONG_LONG>::operator atomic_impl<__TBB_LONG_LONG>::value_type() const volatile { return __TBB_Load8(&rep.value); } template<> inline atomic_impl::operator atomic_impl::value_type() const volatile { return __TBB_Load8(&rep.value); } template<> inline atomic_impl<__TBB_LONG_LONG>::value_type atomic_impl<__TBB_LONG_LONG>::store_with_release( value_type rhs ) { __TBB_Store8(&rep.value,rhs); return rhs; } template<> inline atomic_impl::value_type atomic_impl::store_with_release( value_type rhs ) { __TBB_Store8(&rep.value,rhs); return rhs; } #endif /* defined(__INTEL_COMPILER)||!defined(_MSC_VER)||_MSC_VER>=1400 */ #endif /* __TBB_WORDSIZE==4 */ } /* Internal */ //! @endcond //! Primary template for atomic. /** See the Reference for details. @ingroup synchronization */ template struct atomic: internal::atomic_impl { T operator=( T rhs ) { // "this" required here in strict ISO C++ because store_with_release is a dependent name return this->store_with_release(rhs); } atomic& operator=( const atomic& rhs ) {this->store_with_release(rhs); return *this;} }; #define __TBB_DECL_ATOMIC(T) \ template<> struct atomic: internal::atomic_impl_with_arithmetic { \ T operator=( T rhs ) {return store_with_release(rhs);} \ atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ }; #if defined(__INTEL_COMPILER)||!defined(_MSC_VER)||_MSC_VER>=1400 __TBB_DECL_ATOMIC(__TBB_LONG_LONG) __TBB_DECL_ATOMIC(unsigned __TBB_LONG_LONG) #else // Some old versions of MVSC cannot correctly compile templates with "long long". #endif /* defined(__INTEL_COMPILER)||!defined(_MSC_VER)||_MSC_VER>=1400 */ __TBB_DECL_ATOMIC(long) __TBB_DECL_ATOMIC(unsigned long) #if defined(_MSC_VER) && __TBB_WORDSIZE==4 /* Special version of __TBB_DECL_ATOMIC that avoids gratuitous warnings from cl /Wp64 option. It is identical to __TBB_DECL_ATOMIC(unsigned) except that it replaces operator=(T) with an operator=(U) that explicitly converts the U to a T. Types T and U should be type synonyms on the platform. Type U should be the wider variant of T from the perspective of /Wp64. */ #define __TBB_DECL_ATOMIC_ALT(T,U) \ template<> struct atomic: internal::atomic_impl_with_arithmetic { \ T operator=( U rhs ) {return store_with_release(T(rhs));} \ atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ }; __TBB_DECL_ATOMIC_ALT(unsigned,size_t) __TBB_DECL_ATOMIC_ALT(int,ptrdiff_t) #else __TBB_DECL_ATOMIC(unsigned) __TBB_DECL_ATOMIC(int) #endif /* defined(_MSC_VER) && __TBB_WORDSIZE==4 */ __TBB_DECL_ATOMIC(unsigned short) __TBB_DECL_ATOMIC(short) __TBB_DECL_ATOMIC(char) __TBB_DECL_ATOMIC(signed char) __TBB_DECL_ATOMIC(unsigned char) #if !defined(_MSC_VER)||defined(_NATIVE_WCHAR_T_DEFINED) __TBB_DECL_ATOMIC(wchar_t) #endif /* _MSC_VER||!defined(_NATIVE_WCHAR_T_DEFINED) */ //! Specialization for atomic with arithmetic and operator->. template struct atomic: internal::atomic_impl_with_arithmetic { T* operator=( T* rhs ) { // "this" required here in strict ISO C++ because store_with_release is a dependent name return this->store_with_release(rhs); } atomic& operator=( const atomic& rhs ) { this->store_with_release(rhs); return *this; } T* operator->() const { return (*this); } }; //! Specialization for atomic, for sake of not allowing arithmetic or operator->. template<> struct atomic: internal::atomic_impl { void* operator=( void* rhs ) { // "this" required here in strict ISO C++ because store_with_release is a dependent name return this->store_with_release(rhs); } atomic& operator=( const atomic& rhs ) { this->store_with_release(rhs); return *this; } }; } // namespace tbb #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warnings 4244, 4267 are back #endif /* __TBB_atomic_H */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/tbb_machine.h0000644000175000017500000004576312271062644021725 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #define __TBB_machine_H #include "tbb_stddef.h" #if _WIN32||_WIN64 #ifdef _MANAGED #pragma managed(push, off) #endif #if __MINGW32__ #include "machine/linux_ia32.h" extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); #define __TBB_Yield() SwitchToThread() #elif defined(_M_IX86) #include "machine/windows_ia32.h" #elif defined(_M_AMD64) #include "machine/windows_intel64.h" #else #error Unsupported platform #endif #ifdef _MANAGED #pragma managed(pop) #endif #elif __linux__ || __FreeBSD__ #if __i386__ #include "machine/linux_ia32.h" #elif __x86_64__ #include "machine/linux_intel64.h" #elif __ia64__ #include "machine/linux_ia64.h" #endif #elif __APPLE__ #if __i386__ #include "machine/linux_ia32.h" #elif __x86_64__ #include "machine/linux_intel64.h" #elif __POWERPC__ #include "machine/mac_ppc.h" #endif #elif _AIX #include "machine/ibm_aix51.h" #elif __sun || __SUNPRO_CC #define __asm__ asm #define __volatile__ volatile #if __i386 || __i386__ #include "machine/linux_ia32.h" #elif __x86_64__ #include "machine/linux_intel64.h" #endif #endif #if !defined(__TBB_CompareAndSwap4) \ || !defined(__TBB_CompareAndSwap8) \ || !defined(__TBB_Yield) \ || !defined(__TBB_release_consistency_helper) #error Minimal requirements for tbb_machine.h not satisfied #endif #ifndef __TBB_load_with_acquire //! Load with acquire semantics; i.e., no following memory operation can move above the load. template inline T __TBB_load_with_acquire(const volatile T& location) { T temp = location; __TBB_release_consistency_helper(); return temp; } #endif #ifndef __TBB_store_with_release //! Store with release semantics; i.e., no prior memory operation can move below the store. template inline void __TBB_store_with_release(volatile T& location, V value) { __TBB_release_consistency_helper(); location = T(value); } #endif #ifndef __TBB_Pause inline void __TBB_Pause(int32_t) { __TBB_Yield(); } #endif namespace tbb { namespace internal { //! Class that implements exponential backoff. /** See implementation of spin_wait_while_eq for an example. */ class atomic_backoff { //! Time delay, in units of "pause" instructions. /** Should be equal to approximately the number of "pause" instructions that take the same time as an context switch. */ static const int32_t LOOPS_BEFORE_YIELD = 16; int32_t count; public: atomic_backoff() : count(1) {} //! Pause for a while. void pause() { if( count<=LOOPS_BEFORE_YIELD ) { __TBB_Pause(count); // Pause twice as long the next time. count*=2; } else { // Pause is so long that we might as well yield CPU to scheduler. __TBB_Yield(); } } // pause for a few times and then return false immediately. bool bounded_pause() { if( count<=LOOPS_BEFORE_YIELD ) { __TBB_Pause(count); // Pause twice as long the next time. count*=2; return true; } else { return false; } } void reset() { count = 1; } }; //! Spin WHILE the value of the variable is equal to a given value /** T and U should be comparable types. */ template void spin_wait_while_eq( const volatile T& location, U value ) { atomic_backoff backoff; while( location==value ) backoff.pause(); } //! Spin UNTIL the value of the variable is equal to a given value /** T and U should be comparable types. */ template void spin_wait_until_eq( const volatile T& location, const U value ) { atomic_backoff backoff; while( location!=value ) backoff.pause(); } // T should be unsigned, otherwise sign propagation will break correctness of bit manipulations. // S should be either 1 or 2, for the mask calculation to work correctly. // Together, these rules limit applicability of Masked CAS to unsigned char and unsigned short. template inline T __TBB_MaskedCompareAndSwap (volatile T *ptr, T value, T comparand ) { volatile uint32_t * base = (uint32_t*)( (uintptr_t)ptr & ~(uintptr_t)0x3 ); #if __TBB_BIG_ENDIAN const uint8_t bitoffset = uint8_t( 8*( 4-S - (uintptr_t(ptr) & 0x3) ) ); #else const uint8_t bitoffset = uint8_t( 8*((uintptr_t)ptr & 0x3) ); #endif const uint32_t mask = ( (1<<(S*8)) - 1 )<> bitoffset); } template inline T __TBB_CompareAndSwapGeneric (volatile void *ptr, T value, T comparand ) { return __TBB_CompareAndSwapW((T *)ptr,value,comparand); } template<> inline uint8_t __TBB_CompareAndSwapGeneric <1,uint8_t> (volatile void *ptr, uint8_t value, uint8_t comparand ) { #ifdef __TBB_CompareAndSwap1 return __TBB_CompareAndSwap1(ptr,value,comparand); #else return __TBB_MaskedCompareAndSwap<1,uint8_t>((volatile uint8_t *)ptr,value,comparand); #endif } template<> inline uint16_t __TBB_CompareAndSwapGeneric <2,uint16_t> (volatile void *ptr, uint16_t value, uint16_t comparand ) { #ifdef __TBB_CompareAndSwap2 return __TBB_CompareAndSwap2(ptr,value,comparand); #else return __TBB_MaskedCompareAndSwap<2,uint16_t>((volatile uint16_t *)ptr,value,comparand); #endif } template<> inline uint32_t __TBB_CompareAndSwapGeneric <4,uint32_t> (volatile void *ptr, uint32_t value, uint32_t comparand ) { return __TBB_CompareAndSwap4(ptr,value,comparand); } template<> inline uint64_t __TBB_CompareAndSwapGeneric <8,uint64_t> (volatile void *ptr, uint64_t value, uint64_t comparand ) { return __TBB_CompareAndSwap8(ptr,value,comparand); } template inline T __TBB_FetchAndAddGeneric (volatile void *ptr, T addend) { atomic_backoff b; T result; for(;;) { result = *reinterpret_cast(ptr); // __TBB_CompareAndSwapGeneric presumed to have full fence. if( __TBB_CompareAndSwapGeneric ( ptr, result+addend, result )==result ) break; b.pause(); } return result; } template inline T __TBB_FetchAndStoreGeneric (volatile void *ptr, T value) { atomic_backoff b; T result; for(;;) { result = *reinterpret_cast(ptr); // __TBB_CompareAndSwapGeneric presumed to have full fence. if( __TBB_CompareAndSwapGeneric ( ptr, value, result )==result ) break; b.pause(); } return result; } // Macro __TBB_TypeWithAlignmentAtLeastAsStrict(T) should be a type with alignment at least as // strict as type T. Type type should have a trivial default constructor and destructor, so that // arrays of that type can be declared without initializers. // It is correct (but perhaps a waste of space) if __TBB_TypeWithAlignmentAtLeastAsStrict(T) expands // to a type bigger than T. // The default definition here works on machines where integers are naturally aligned and the // strictest alignment is 16. #ifndef __TBB_TypeWithAlignmentAtLeastAsStrict #if __GNUC__ || __SUNPRO_CC struct __TBB_machine_type_with_strictest_alignment { int member[4]; } __attribute__((aligned(16))); #elif _MSC_VER __declspec(align(16)) struct __TBB_machine_type_with_strictest_alignment { int member[4]; }; #else #error Must define __TBB_TypeWithAlignmentAtLeastAsStrict(T) or __TBB_machine_type_with_strictest_alignment #endif template struct type_with_alignment {__TBB_machine_type_with_strictest_alignment member;}; template<> struct type_with_alignment<1> { char member; }; template<> struct type_with_alignment<2> { uint16_t member; }; template<> struct type_with_alignment<4> { uint32_t member; }; template<> struct type_with_alignment<8> { uint64_t member; }; #if _MSC_VER||defined(__GNUC__)&&__GNUC__==3 && __GNUC_MINOR__<=2 //! Work around for bug in GNU 3.2 and MSVC compilers. /** Bug is that compiler sometimes returns 0 for __alignof(T) when T has not yet been instantiated. The work-around forces instantiation by forcing computation of sizeof(T) before __alignof(T). */ template struct work_around_alignment_bug { #if _MSC_VER static const size_t alignment = __alignof(T); #else static const size_t alignment = __alignof__(T); #endif }; #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment::alignment> #elif __GNUC__ || __SUNPRO_CC #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<__alignof__(T)> #else #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) __TBB_machine_type_with_strictest_alignment #endif #endif /* ____TBB_TypeWithAlignmentAtLeastAsStrict */ } // namespace internal } // namespace tbb #ifndef __TBB_CompareAndSwap1 #define __TBB_CompareAndSwap1 tbb::internal::__TBB_CompareAndSwapGeneric<1,uint8_t> #endif #ifndef __TBB_CompareAndSwap2 #define __TBB_CompareAndSwap2 tbb::internal::__TBB_CompareAndSwapGeneric<2,uint16_t> #endif #ifndef __TBB_CompareAndSwapW #define __TBB_CompareAndSwapW tbb::internal::__TBB_CompareAndSwapGeneric #endif #ifndef __TBB_FetchAndAdd1 #define __TBB_FetchAndAdd1 tbb::internal::__TBB_FetchAndAddGeneric<1,uint8_t> #endif #ifndef __TBB_FetchAndAdd2 #define __TBB_FetchAndAdd2 tbb::internal::__TBB_FetchAndAddGeneric<2,uint16_t> #endif #ifndef __TBB_FetchAndAdd4 #define __TBB_FetchAndAdd4 tbb::internal::__TBB_FetchAndAddGeneric<4,uint32_t> #endif #ifndef __TBB_FetchAndAdd8 #define __TBB_FetchAndAdd8 tbb::internal::__TBB_FetchAndAddGeneric<8,uint64_t> #endif #ifndef __TBB_FetchAndAddW #define __TBB_FetchAndAddW tbb::internal::__TBB_FetchAndAddGeneric #endif #ifndef __TBB_FetchAndStore1 #define __TBB_FetchAndStore1 tbb::internal::__TBB_FetchAndStoreGeneric<1,uint8_t> #endif #ifndef __TBB_FetchAndStore2 #define __TBB_FetchAndStore2 tbb::internal::__TBB_FetchAndStoreGeneric<2,uint16_t> #endif #ifndef __TBB_FetchAndStore4 #define __TBB_FetchAndStore4 tbb::internal::__TBB_FetchAndStoreGeneric<4,uint32_t> #endif #ifndef __TBB_FetchAndStore8 #define __TBB_FetchAndStore8 tbb::internal::__TBB_FetchAndStoreGeneric<8,uint64_t> #endif #ifndef __TBB_FetchAndStoreW #define __TBB_FetchAndStoreW tbb::internal::__TBB_FetchAndStoreGeneric #endif #if __TBB_DECL_FENCED_ATOMICS #ifndef __TBB_CompareAndSwap1__TBB_full_fence #define __TBB_CompareAndSwap1__TBB_full_fence __TBB_CompareAndSwap1 #endif #ifndef __TBB_CompareAndSwap1acquire #define __TBB_CompareAndSwap1acquire __TBB_CompareAndSwap1__TBB_full_fence #endif #ifndef __TBB_CompareAndSwap1release #define __TBB_CompareAndSwap1release __TBB_CompareAndSwap1__TBB_full_fence #endif #ifndef __TBB_CompareAndSwap2__TBB_full_fence #define __TBB_CompareAndSwap2__TBB_full_fence __TBB_CompareAndSwap2 #endif #ifndef __TBB_CompareAndSwap2acquire #define __TBB_CompareAndSwap2acquire __TBB_CompareAndSwap2__TBB_full_fence #endif #ifndef __TBB_CompareAndSwap2release #define __TBB_CompareAndSwap2release __TBB_CompareAndSwap2__TBB_full_fence #endif #ifndef __TBB_CompareAndSwap4__TBB_full_fence #define __TBB_CompareAndSwap4__TBB_full_fence __TBB_CompareAndSwap4 #endif #ifndef __TBB_CompareAndSwap4acquire #define __TBB_CompareAndSwap4acquire __TBB_CompareAndSwap4__TBB_full_fence #endif #ifndef __TBB_CompareAndSwap4release #define __TBB_CompareAndSwap4release __TBB_CompareAndSwap4__TBB_full_fence #endif #ifndef __TBB_CompareAndSwap8__TBB_full_fence #define __TBB_CompareAndSwap8__TBB_full_fence __TBB_CompareAndSwap8 #endif #ifndef __TBB_CompareAndSwap8acquire #define __TBB_CompareAndSwap8acquire __TBB_CompareAndSwap8__TBB_full_fence #endif #ifndef __TBB_CompareAndSwap8release #define __TBB_CompareAndSwap8release __TBB_CompareAndSwap8__TBB_full_fence #endif #ifndef __TBB_FetchAndAdd1__TBB_full_fence #define __TBB_FetchAndAdd1__TBB_full_fence __TBB_FetchAndAdd1 #endif #ifndef __TBB_FetchAndAdd1acquire #define __TBB_FetchAndAdd1acquire __TBB_FetchAndAdd1__TBB_full_fence #endif #ifndef __TBB_FetchAndAdd1release #define __TBB_FetchAndAdd1release __TBB_FetchAndAdd1__TBB_full_fence #endif #ifndef __TBB_FetchAndAdd2__TBB_full_fence #define __TBB_FetchAndAdd2__TBB_full_fence __TBB_FetchAndAdd2 #endif #ifndef __TBB_FetchAndAdd2acquire #define __TBB_FetchAndAdd2acquire __TBB_FetchAndAdd2__TBB_full_fence #endif #ifndef __TBB_FetchAndAdd2release #define __TBB_FetchAndAdd2release __TBB_FetchAndAdd2__TBB_full_fence #endif #ifndef __TBB_FetchAndAdd4__TBB_full_fence #define __TBB_FetchAndAdd4__TBB_full_fence __TBB_FetchAndAdd4 #endif #ifndef __TBB_FetchAndAdd4acquire #define __TBB_FetchAndAdd4acquire __TBB_FetchAndAdd4__TBB_full_fence #endif #ifndef __TBB_FetchAndAdd4release #define __TBB_FetchAndAdd4release __TBB_FetchAndAdd4__TBB_full_fence #endif #ifndef __TBB_FetchAndAdd8__TBB_full_fence #define __TBB_FetchAndAdd8__TBB_full_fence __TBB_FetchAndAdd8 #endif #ifndef __TBB_FetchAndAdd8acquire #define __TBB_FetchAndAdd8acquire __TBB_FetchAndAdd8__TBB_full_fence #endif #ifndef __TBB_FetchAndAdd8release #define __TBB_FetchAndAdd8release __TBB_FetchAndAdd8__TBB_full_fence #endif #ifndef __TBB_FetchAndStore1__TBB_full_fence #define __TBB_FetchAndStore1__TBB_full_fence __TBB_FetchAndStore1 #endif #ifndef __TBB_FetchAndStore1acquire #define __TBB_FetchAndStore1acquire __TBB_FetchAndStore1__TBB_full_fence #endif #ifndef __TBB_FetchAndStore1release #define __TBB_FetchAndStore1release __TBB_FetchAndStore1__TBB_full_fence #endif #ifndef __TBB_FetchAndStore2__TBB_full_fence #define __TBB_FetchAndStore2__TBB_full_fence __TBB_FetchAndStore2 #endif #ifndef __TBB_FetchAndStore2acquire #define __TBB_FetchAndStore2acquire __TBB_FetchAndStore2__TBB_full_fence #endif #ifndef __TBB_FetchAndStore2release #define __TBB_FetchAndStore2release __TBB_FetchAndStore2__TBB_full_fence #endif #ifndef __TBB_FetchAndStore4__TBB_full_fence #define __TBB_FetchAndStore4__TBB_full_fence __TBB_FetchAndStore4 #endif #ifndef __TBB_FetchAndStore4acquire #define __TBB_FetchAndStore4acquire __TBB_FetchAndStore4__TBB_full_fence #endif #ifndef __TBB_FetchAndStore4release #define __TBB_FetchAndStore4release __TBB_FetchAndStore4__TBB_full_fence #endif #ifndef __TBB_FetchAndStore8__TBB_full_fence #define __TBB_FetchAndStore8__TBB_full_fence __TBB_FetchAndStore8 #endif #ifndef __TBB_FetchAndStore8acquire #define __TBB_FetchAndStore8acquire __TBB_FetchAndStore8__TBB_full_fence #endif #ifndef __TBB_FetchAndStore8release #define __TBB_FetchAndStore8release __TBB_FetchAndStore8__TBB_full_fence #endif #endif // __TBB_DECL_FENCED_ATOMICS // Special atomic functions #ifndef __TBB_FetchAndAddWrelease #define __TBB_FetchAndAddWrelease __TBB_FetchAndAddW #endif #ifndef __TBB_FetchAndIncrementWacquire #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1) #endif #ifndef __TBB_FetchAndDecrementWrelease #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,(-1)) #endif #if __TBB_WORDSIZE==4 // On 32-bit platforms, "atomic.h" requires definition of __TBB_Store8 and __TBB_Load8 #ifndef __TBB_Store8 inline void __TBB_Store8 (volatile void *ptr, int64_t value) { tbb::internal::atomic_backoff b; for(;;) { int64_t result = *(int64_t *)ptr; if( __TBB_CompareAndSwap8(ptr,value,result)==result ) break; b.pause(); } } #endif #ifndef __TBB_Load8 inline int64_t __TBB_Load8 (const volatile void *ptr) { int64_t result = *(int64_t *)ptr; result = __TBB_CompareAndSwap8((volatile void *)ptr,result,result); return result; } #endif #endif /* __TBB_WORDSIZE==4 */ #ifndef __TBB_Log2 inline intptr_t __TBB_Log2( uintptr_t x ) { if( x==0 ) return -1; intptr_t result = 0; uintptr_t tmp; #if __TBB_WORDSIZE>=8 if( (tmp = x>>32) ) { x=tmp; result += 32; } #endif if( (tmp = x>>16) ) { x=tmp; result += 16; } if( (tmp = x>>8) ) { x=tmp; result += 8; } if( (tmp = x>>4) ) { x=tmp; result += 4; } if( (tmp = x>>2) ) { x=tmp; result += 2; } return (x&2)? result+1: result; } #endif #ifndef __TBB_AtomicOR inline void __TBB_AtomicOR( volatile void *operand, uintptr_t addend ) { tbb::internal::atomic_backoff b; for(;;) { uintptr_t tmp = *(volatile uintptr_t *)operand; uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp); if( result==tmp ) break; b.pause(); } } #endif #ifndef __TBB_AtomicAND inline void __TBB_AtomicAND( volatile void *operand, uintptr_t addend ) { tbb::internal::atomic_backoff b; for(;;) { uintptr_t tmp = *(volatile uintptr_t *)operand; uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp); if( result==tmp ) break; b.pause(); } } #endif #ifndef __TBB_TryLockByte inline bool __TBB_TryLockByte( unsigned char &flag ) { return __TBB_CompareAndSwap1(&flag,1,0)==0; } #endif #ifndef __TBB_LockByte inline uintptr_t __TBB_LockByte( unsigned char& flag ) { if ( !__TBB_TryLockByte(flag) ) { tbb::internal::atomic_backoff b; do { b.pause(); } while ( !__TBB_TryLockByte(flag) ); } return 0; } #endif #endif /* __TBB_machine_H */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/tbb_config.h0000644000175000017500000001320312271062644021546 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tbb_config_H #define __TBB_tbb_config_H /** This header is supposed to contain macro definitions and C style comments only. The macros defined here are intended to control such aspects of TBB build as - compilation modes - feature sets - workarounds presence **/ /** Compilation modes **/ #ifndef TBB_USE_DEBUG #ifdef TBB_DO_ASSERT #define TBB_USE_DEBUG TBB_DO_ASSERT #else #define TBB_USE_DEBUG 0 #endif /* TBB_DO_ASSERT */ #else #define TBB_DO_ASSERT TBB_USE_DEBUG #endif /* TBB_USE_DEBUG */ #ifndef TBB_USE_ASSERT #ifdef TBB_DO_ASSERT #define TBB_USE_ASSERT TBB_DO_ASSERT #else #define TBB_USE_ASSERT TBB_USE_DEBUG #endif /* TBB_DO_ASSERT */ #endif /* TBB_USE_ASSERT */ #ifndef TBB_USE_THREADING_TOOLS #ifdef TBB_DO_THREADING_TOOLS #define TBB_USE_THREADING_TOOLS TBB_DO_THREADING_TOOLS #else #define TBB_USE_THREADING_TOOLS TBB_USE_DEBUG #endif /* TBB_DO_THREADING_TOOLS */ #endif /* TBB_USE_THREADING_TOOLS */ #ifndef TBB_USE_PERFORMANCE_WARNINGS #ifdef TBB_PERFORMANCE_WARNINGS #define TBB_USE_PERFORMANCE_WARNINGS TBB_PERFORMANCE_WARNINGS #else #define TBB_USE_PERFORMANCE_WARNINGS TBB_USE_DEBUG #endif /* TBB_PEFORMANCE_WARNINGS */ #endif /* TBB_USE_PERFORMANCE_WARNINGS */ /** Feature sets **/ #ifndef __TBB_EXCEPTIONS #define __TBB_EXCEPTIONS 1 #endif /* __TBB_EXCEPTIONS */ #ifndef __TBB_SCHEDULER_OBSERVER #define __TBB_SCHEDULER_OBSERVER 1 #endif /* __TBB_SCHEDULER_OBSERVER */ #ifndef __TBB_TASK_SCHEDULER_AUTO_INIT #define __TBB_TASK_SCHEDULER_AUTO_INIT 1 #endif /* __TBB_TASK_SCHEDULER_AUTO_INIT */ #ifndef __TBB_TASK_DEQUE #define __TBB_TASK_DEQUE 1 #endif /* !__TBB_TASK_DEQUE */ #if __TBB_TASK_DEQUE #ifndef __TBB_RELAXED_OWNERSHIP #define __TBB_RELAXED_OWNERSHIP 1 #endif /* !__TBB_RELAXED_OWNERSHIP */ #else #ifdef __TBB_RELAXED_OWNERSHIP #undef __TBB_RELAXED_OWNERSHIP #endif /* __TBB_RELAXED_OWNERSHIP */ #endif /* !__TBB_TASK_DEQUE */ #ifndef __TBB_NEW_ITT_NOTIFY #define __TBB_NEW_ITT_NOTIFY 1 #endif /* !__TBB_NEW_ITT_NOTIFY */ /* TODO: The following condition should be extended as soon as new compilers/runtimes with std::exception_ptr support appear. */ #define __TBB_EXCEPTION_PTR_PRESENT ( _MSC_VER >= 1600 ) #ifndef TBB_USE_CAPTURED_EXCEPTION #if __TBB_EXCEPTION_PTR_PRESENT #define TBB_USE_CAPTURED_EXCEPTION 0 #else #define TBB_USE_CAPTURED_EXCEPTION 1 #endif #else /* defined TBB_USE_CAPTURED_EXCEPTION */ #if !TBB_USE_CAPTURED_EXCEPTION && !__TBB_EXCEPTION_PTR_PRESENT #error Current runtime does not support std::exception_ptr. Set TBB_USE_CAPTURED_EXCEPTION and make sure that your code is ready to catch tbb::captured_exception. #endif #endif /* defined TBB_USE_CAPTURED_EXCEPTION */ #ifndef __TBB_DEFAULT_PARTITIONER #if TBB_DEPRECATED /** Default partitioner for parallel loop templates in TBB 1.0-2.1 */ #define __TBB_DEFAULT_PARTITIONER tbb::simple_partitioner #else /** Default partitioner for parallel loop templates in TBB 2.2 */ #define __TBB_DEFAULT_PARTITIONER tbb::auto_partitioner #endif /* TBB_DEFAULT_PARTITIONER */ #endif /* !defined(__TBB_DEFAULT_PARTITIONER */ /** Workarounds presence **/ /** Macros of the form __TBB_XXX_BROKEN denote known issues that are caused by the bugs in compilers, standard or OS specific libraries. They should be removed as soon as the corresponding bugs are fixed or the buggy OS/compiler versions go out of the support list. **/ #if defined(_MSC_VER) && _MSC_VER < 0x1500 && !defined(__INTEL_COMPILER) /** VS2005 and earlier does not allow to declare a template class as a friend of classes defined in other namespaces. **/ #define __TBB_TEMPLATE_FRIENDS_BROKEN 1 #endif #if __GLIBC__==2 && __GLIBC_MINOR__==3 || __MINGW32__ /** Some older versions of glibc crash when exception handling happens concurrently. **/ #define __TBB_EXCEPTION_HANDLING_BROKEN 1 #endif #if __FreeBSD__ /** The bug in FreeBSD 8.0 results in kernel panic when there is contention on a mutex created with this attribute. **/ #define __TBB_PRIO_INHERIT_BROKEN 1 /** A bug in FreeBSD 8.0 results in test hanging when an exception occurs during (concurrent?) object construction by means of placement new operator. **/ #define __TBB_PLACEMENT_NEW_EXCEPTION_SAFETY_BROKEN 1 #endif /* __FreeBSD__ */ #endif /* __TBB_tbb_config_H */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/tbb_version.h0000644000175000017500000000737412271062644022002 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // Please define version number in the file: #include "tbb/tbb_stddef.h" // And don't touch anything below #ifndef ENDL #define ENDL "\n" #endif //#include "version_string.tmp" #ifndef __TBB_VERSION_STRINGS // here is an example of macros value: #define __TBB_VERSION_STRINGS \ "TBB: BUILD_HOST\tUnknown\n" \ "TBB: BUILD_ARCH\tUnknown\n" \ "TBB: BUILD_OS\t\tUnknown\n" \ "TBB: BUILD_CL\t\tUnknown\n" \ "TBB: BUILD_COMPILER\tUnknown\n" \ "TBB: BUILD_COMMAND\tUnknown\n" #endif #ifndef __TBB_DATETIME #ifdef RC_INVOKED #define __TBB_DATETIME "Unknown" #else #define __TBB_DATETIME __DATE__ __TIME__ #endif #endif #define __TBB_VERSION_NUMBER "TBB: VERSION\t\t" __TBB_STRING(TBB_VERSION_MAJOR.TBB_VERSION_MINOR) ENDL #define __TBB_INTERFACE_VERSION_NUMBER "TBB: INTERFACE VERSION\t" __TBB_STRING(TBB_INTERFACE_VERSION) ENDL #define __TBB_VERSION_DATETIME "TBB: BUILD_DATE\t\t" __TBB_DATETIME ENDL #ifndef TBB_USE_DEBUG #define __TBB_VERSION_USE_DEBUG "TBB: TBB_USE_DEBUG\tundefined" ENDL #elif TBB_USE_DEBUG==0 #define __TBB_VERSION_USE_DEBUG "TBB: TBB_USE_DEBUG\t0" ENDL #elif TBB_USE_DEBUG==1 #define __TBB_VERSION_USE_DEBUG "TBB: TBB_USE_DEBUG\t1" ENDL #elif TBB_USE_DEBUG==2 #define __TBB_VERSION_USE_DEBUG "TBB: TBB_USE_DEBUG\t2" ENDL #else #error Unexpected value for TBB_USE_DEBUG #endif #ifndef TBB_USE_ASSERT #define __TBB_VERSION_USE_ASSERT "TBB: TBB_USE_ASSERT\tundefined" ENDL #elif TBB_USE_ASSERT==0 #define __TBB_VERSION_USE_ASSERT "TBB: TBB_USE_ASSERT\t0" ENDL #elif TBB_USE_ASSERT==1 #define __TBB_VERSION_USE_ASSERT "TBB: TBB_USE_ASSERT\t1" ENDL #elif TBB_USE_ASSERT==2 #define __TBB_VERSION_USE_ASSERT "TBB: TBB_USE_ASSERT\t2" ENDL #else #error Unexpected value for TBB_USE_ASSERT #endif #ifndef DO_ITT_NOTIFY #define __TBB_VERSION_DO_NOTIFY "TBB: DO_ITT_NOTIFY\tundefined" ENDL #elif DO_ITT_NOTIFY==1 #define __TBB_VERSION_DO_NOTIFY "TBB: DO_ITT_NOTIFY\t1" ENDL #elif DO_ITT_NOTIFY==0 #define __TBB_VERSION_DO_NOTIFY #else #error Unexpected value for DO_ITT_NOTIFY #endif #define TBB_VERSION_STRINGS __TBB_VERSION_NUMBER __TBB_INTERFACE_VERSION_NUMBER __TBB_VERSION_DATETIME __TBB_VERSION_STRINGS __TBB_VERSION_USE_DEBUG __TBB_VERSION_USE_ASSERT __TBB_VERSION_DO_NOTIFY // numbers #ifndef __TBB_VERSION_YMD #define __TBB_VERSION_YMD 0, 0 #endif #define TBB_VERNUMBERS TBB_VERSION_MAJOR, TBB_VERSION_MINOR, __TBB_VERSION_YMD #define TBB_VERSION __TBB_STRING(TBB_VERNUMBERS) openimageio-1.3.12~dfsg0.orig/src/include/tbb/machine/0000755000175000017500000000000012271062644020706 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/include/tbb/machine/linux_common.h0000644000175000017500000000567712271062644023605 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #error Do not include this file directly; include tbb_machine.h instead #endif #include #include #include // Definition of __TBB_Yield() #define __TBB_Yield() sched_yield() /* Futex definitions */ #include #if defined(SYS_futex) #define __TBB_USE_FUTEX 1 #include #include // Unfortunately, some versions of Linux do not have a header that defines FUTEX_WAIT and FUTEX_WAKE. #ifdef FUTEX_WAIT #define __TBB_FUTEX_WAIT FUTEX_WAIT #else #define __TBB_FUTEX_WAIT 0 #endif #ifdef FUTEX_WAKE #define __TBB_FUTEX_WAKE FUTEX_WAKE #else #define __TBB_FUTEX_WAKE 1 #endif #ifndef __TBB_ASSERT #error machine specific headers must be included after tbb_stddef.h #endif namespace tbb { namespace internal { inline int futex_wait( void *futex, int comparand ) { int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAIT,comparand,NULL,NULL,0 ); #if TBB_USE_ASSERT int e = errno; __TBB_ASSERT( r==0||r==EWOULDBLOCK||(r==-1&&(e==EAGAIN||e==EINTR)), "futex_wait failed." ); #endif /* TBB_USE_ASSERT */ return r; } inline int futex_wakeup_one( void *futex ) { int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,1,NULL,NULL,0 ); __TBB_ASSERT( r==0||r==1, "futex_wakeup_one: more than one thread woken up?" ); return r; } inline int futex_wakeup_all( void *futex ) { int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,INT_MAX,NULL,NULL,0 ); __TBB_ASSERT( r>=0, "futex_wakeup_all: error in waking up threads" ); return r; } } /* namespace internal */ } /* namespace tbb */ #endif /* SYS_futex */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/machine/ibm_aix51.h0000644000175000017500000000412612271062644022640 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #error Do not include this file directly; include tbb_machine.h instead #endif #define __TBB_WORDSIZE 8 #define __TBB_BIG_ENDIAN 1 #include #include #include extern "C" { int32_t __TBB_machine_cas_32 (volatile void* ptr, int32_t value, int32_t comparand); int64_t __TBB_machine_cas_64 (volatile void* ptr, int64_t value, int64_t comparand); #define __TBB_fence_for_acquire() __TBB_machine_flush () #define __TBB_fence_for_release() __TBB_machine_flush () } #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cas_32(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cas_64(P,V,C) #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cas_64(P,V,C) #define __TBB_Yield() sched_yield() openimageio-1.3.12~dfsg0.orig/src/include/tbb/machine/linux_ia64.h0000644000175000017500000002216412271062644023046 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #error Do not include this file directly; include tbb_machine.h instead #endif #include "linux_common.h" #include #define __TBB_WORDSIZE 8 #define __TBB_BIG_ENDIAN 0 #define __TBB_DECL_FENCED_ATOMICS 1 // Most of the functions will be in a .s file extern "C" { int8_t __TBB_machine_cmpswp1__TBB_full_fence (volatile void *ptr, int8_t value, int8_t comparand); int8_t __TBB_machine_fetchadd1__TBB_full_fence (volatile void *ptr, int8_t addend); int8_t __TBB_machine_fetchadd1acquire(volatile void *ptr, int8_t addend); int8_t __TBB_machine_fetchadd1release(volatile void *ptr, int8_t addend); int8_t __TBB_machine_fetchstore1acquire(volatile void *ptr, int8_t value); int8_t __TBB_machine_fetchstore1release(volatile void *ptr, int8_t value); int16_t __TBB_machine_cmpswp2__TBB_full_fence (volatile void *ptr, int16_t value, int16_t comparand); int16_t __TBB_machine_fetchadd2__TBB_full_fence (volatile void *ptr, int16_t addend); int16_t __TBB_machine_fetchadd2acquire(volatile void *ptr, int16_t addend); int16_t __TBB_machine_fetchadd2release(volatile void *ptr, int16_t addend); int16_t __TBB_machine_fetchstore2acquire(volatile void *ptr, int16_t value); int16_t __TBB_machine_fetchstore2release(volatile void *ptr, int16_t value); int32_t __TBB_machine_fetchstore4__TBB_full_fence (volatile void *ptr, int32_t value); int32_t __TBB_machine_fetchstore4acquire(volatile void *ptr, int32_t value); int32_t __TBB_machine_fetchstore4release(volatile void *ptr, int32_t value); int32_t __TBB_machine_fetchadd4acquire(volatile void *ptr, int32_t addend); int32_t __TBB_machine_fetchadd4release(volatile void *ptr, int32_t addend); int64_t __TBB_machine_cmpswp8__TBB_full_fence (volatile void *ptr, int64_t value, int64_t comparand); int64_t __TBB_machine_fetchstore8__TBB_full_fence (volatile void *ptr, int64_t value); int64_t __TBB_machine_fetchstore8acquire(volatile void *ptr, int64_t value); int64_t __TBB_machine_fetchstore8release(volatile void *ptr, int64_t value); int64_t __TBB_machine_fetchadd8acquire(volatile void *ptr, int64_t addend); int64_t __TBB_machine_fetchadd8release(volatile void *ptr, int64_t addend); int8_t __TBB_machine_cmpswp1acquire(volatile void *ptr, int8_t value, int8_t comparand); int8_t __TBB_machine_cmpswp1release(volatile void *ptr, int8_t value, int8_t comparand); int8_t __TBB_machine_fetchstore1__TBB_full_fence (volatile void *ptr, int8_t value); int16_t __TBB_machine_cmpswp2acquire(volatile void *ptr, int16_t value, int16_t comparand); int16_t __TBB_machine_cmpswp2release(volatile void *ptr, int16_t value, int16_t comparand); int16_t __TBB_machine_fetchstore2__TBB_full_fence (volatile void *ptr, int16_t value); int32_t __TBB_machine_cmpswp4__TBB_full_fence (volatile void *ptr, int32_t value, int32_t comparand); int32_t __TBB_machine_cmpswp4acquire(volatile void *ptr, int32_t value, int32_t comparand); int32_t __TBB_machine_cmpswp4release(volatile void *ptr, int32_t value, int32_t comparand); int32_t __TBB_machine_fetchadd4__TBB_full_fence (volatile void *ptr, int32_t value); int64_t __TBB_machine_cmpswp8acquire(volatile void *ptr, int64_t value, int64_t comparand); int64_t __TBB_machine_cmpswp8release(volatile void *ptr, int64_t value, int64_t comparand); int64_t __TBB_machine_fetchadd8__TBB_full_fence (volatile void *ptr, int64_t value); int64_t __TBB_machine_lg(uint64_t value); void __TBB_machine_pause(int32_t delay); bool __TBB_machine_trylockbyte( volatile unsigned char &ptr ); int64_t __TBB_machine_lockbyte( volatile unsigned char &ptr ); //! Retrieves the current RSE backing store pointer. IA64 specific. void* __TBB_get_bsp(); } #define __TBB_CompareAndSwap1(P,V,C) __TBB_machine_cmpswp1__TBB_full_fence(P,V,C) #define __TBB_CompareAndSwap2(P,V,C) __TBB_machine_cmpswp2__TBB_full_fence(P,V,C) #define __TBB_FetchAndAdd1(P,V) __TBB_machine_fetchadd1__TBB_full_fence(P,V) #define __TBB_FetchAndAdd1acquire(P,V) __TBB_machine_fetchadd1acquire(P,V) #define __TBB_FetchAndAdd1release(P,V) __TBB_machine_fetchadd1release(P,V) #define __TBB_FetchAndAdd2(P,V) __TBB_machine_fetchadd2__TBB_full_fence(P,V) #define __TBB_FetchAndAdd2acquire(P,V) __TBB_machine_fetchadd2acquire(P,V) #define __TBB_FetchAndAdd2release(P,V) __TBB_machine_fetchadd2release(P,V) #define __TBB_FetchAndAdd4acquire(P,V) __TBB_machine_fetchadd4acquire(P,V) #define __TBB_FetchAndAdd4release(P,V) __TBB_machine_fetchadd4release(P,V) #define __TBB_FetchAndAdd8acquire(P,V) __TBB_machine_fetchadd8acquire(P,V) #define __TBB_FetchAndAdd8release(P,V) __TBB_machine_fetchadd8release(P,V) #define __TBB_FetchAndStore1acquire(P,V) __TBB_machine_fetchstore1acquire(P,V) #define __TBB_FetchAndStore1release(P,V) __TBB_machine_fetchstore1release(P,V) #define __TBB_FetchAndStore2acquire(P,V) __TBB_machine_fetchstore2acquire(P,V) #define __TBB_FetchAndStore2release(P,V) __TBB_machine_fetchstore2release(P,V) #define __TBB_FetchAndStore4acquire(P,V) __TBB_machine_fetchstore4acquire(P,V) #define __TBB_FetchAndStore4release(P,V) __TBB_machine_fetchstore4release(P,V) #define __TBB_FetchAndStore8acquire(P,V) __TBB_machine_fetchstore8acquire(P,V) #define __TBB_FetchAndStore8release(P,V) __TBB_machine_fetchstore8release(P,V) #define __TBB_CompareAndSwap1acquire(P,V,C) __TBB_machine_cmpswp1acquire(P,V,C) #define __TBB_CompareAndSwap1release(P,V,C) __TBB_machine_cmpswp1release(P,V,C) #define __TBB_CompareAndSwap2acquire(P,V,C) __TBB_machine_cmpswp2acquire(P,V,C) #define __TBB_CompareAndSwap2release(P,V,C) __TBB_machine_cmpswp2release(P,V,C) #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4__TBB_full_fence(P,V,C) #define __TBB_CompareAndSwap4acquire(P,V,C) __TBB_machine_cmpswp4acquire(P,V,C) #define __TBB_CompareAndSwap4release(P,V,C) __TBB_machine_cmpswp4release(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8__TBB_full_fence(P,V,C) #define __TBB_CompareAndSwap8acquire(P,V,C) __TBB_machine_cmpswp8acquire(P,V,C) #define __TBB_CompareAndSwap8release(P,V,C) __TBB_machine_cmpswp8release(P,V,C) #define __TBB_FetchAndAdd4(P,V) __TBB_machine_fetchadd4__TBB_full_fence(P,V) #define __TBB_FetchAndAdd8(P,V) __TBB_machine_fetchadd8__TBB_full_fence(P,V) #define __TBB_FetchAndStore1(P,V) __TBB_machine_fetchstore1__TBB_full_fence(P,V) #define __TBB_FetchAndStore2(P,V) __TBB_machine_fetchstore2__TBB_full_fence(P,V) #define __TBB_FetchAndStore4(P,V) __TBB_machine_fetchstore4__TBB_full_fence(P,V) #define __TBB_FetchAndStore8(P,V) __TBB_machine_fetchstore8__TBB_full_fence(P,V) #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAdd8acquire(P,1) #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAdd8release(P,-1) #ifndef __INTEL_COMPILER /* Even though GCC imbues volatile loads with acquire semantics, it sometimes moves loads over the acquire fence. The fences defined here stop such incorrect code motion. */ #define __TBB_release_consistency_helper() __asm__ __volatile__("": : :"memory") #define __TBB_rel_acq_fence() __asm__ __volatile__("mf": : :"memory") #else #define __TBB_release_consistency_helper() #define __TBB_rel_acq_fence() __mf() #endif /* __INTEL_COMPILER */ // Special atomic functions #define __TBB_CompareAndSwapW(P,V,C) __TBB_CompareAndSwap8(P,V,C) #define __TBB_FetchAndStoreW(P,V) __TBB_FetchAndStore8(P,V) #define __TBB_FetchAndAddW(P,V) __TBB_FetchAndAdd8(P,V) #define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAdd8release(P,V) // Not needed #undef __TBB_Store8 #undef __TBB_Load8 // Definition of Lock functions #define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) #define __TBB_LockByte(P) __TBB_machine_lockbyte(P) // Definition of other utility functions #define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Log2(V) __TBB_machine_lg(V) openimageio-1.3.12~dfsg0.orig/src/include/tbb/machine/mac_ppc.h0000644000175000017500000000730112271062644022462 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #error Do not include this file directly; include tbb_machine.h instead #endif #include #include #include // sched_yield inline int32_t __TBB_machine_cmpswp4 (volatile void *ptr, int32_t value, int32_t comparand ) { int32_t result; __asm__ __volatile__("sync\n" "0: lwarx %0,0,%2\n\t" /* load w/ reservation */ "cmpw %0,%4\n\t" /* compare against comparand */ "bne- 1f\n\t" /* exit if not same */ "stwcx. %3,0,%2\n\t" /* store new_value */ "bne- 0b\n" /* retry if reservation lost */ "1: sync" /* the exit */ : "=&r"(result), "=m"(* (int32_t*) ptr) : "r"(ptr), "r"(value), "r"(comparand), "m"(* (int32_t*) ptr) : "cr0"); return result; } inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) { int64_t result; __asm__ __volatile__("sync\n" "0: ldarx %0,0,%2\n\t" /* load w/ reservation */ "cmpd %0,%4\n\t" /* compare against comparand */ "bne- 1f\n\t" /* exit if not same */ "stdcx. %3,0,%2\n\t" /* store new_value */ "bne- 0b\n" /* retry if reservation lost */ "1: sync" /* the exit */ : "=&b"(result), "=m"(* (int64_t*) ptr) : "r"(ptr), "r"(value), "r"(comparand), "m"(* (int64_t*) ptr) : "cr0"); return result; } #define __TBB_BIG_ENDIAN 1 #if defined(powerpc64) || defined(__powerpc64__) || defined(__ppc64__) #define __TBB_WORDSIZE 8 #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp8(P,V,C) #else #define __TBB_WORDSIZE 4 #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp4(P,V,C) #endif #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_Yield() sched_yield() #define __TBB_rel_acq_fence() __asm__ __volatile__("lwsync": : :"memory") #define __TBB_release_consistency_helper() __TBB_rel_acq_fence() openimageio-1.3.12~dfsg0.orig/src/include/tbb/machine/windows_ia32.h0000644000175000017500000001761712271062644023403 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #error Do not include this file directly; include tbb_machine.h instead #endif #if defined(__INTEL_COMPILER) #define __TBB_release_consistency_helper() __asm { __asm nop } #elif _MSC_VER >= 1300 extern "C" void _ReadWriteBarrier(); #pragma intrinsic(_ReadWriteBarrier) #define __TBB_release_consistency_helper() _ReadWriteBarrier() #else #error Unsupported compiler - need to define __TBB_release_consistency_helper to support it #endif inline void __TBB_rel_acq_fence() { __asm { __asm mfence } } #define __TBB_WORDSIZE 4 #define __TBB_BIG_ENDIAN 0 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // Workaround for overzealous compiler warnings in /Wp64 mode #pragma warning (push) #pragma warning (disable: 4244 4267) #endif extern "C" { __int64 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp8 (volatile void *ptr, __int64 value, __int64 comparand ); __int64 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd8 (volatile void *ptr, __int64 addend ); __int64 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore8 (volatile void *ptr, __int64 value ); void __TBB_EXPORTED_FUNC __TBB_machine_store8 (volatile void *ptr, __int64 value ); __int64 __TBB_EXPORTED_FUNC __TBB_machine_load8 (const volatile void *ptr); } template struct __TBB_machine_load_store { static inline T load_with_acquire(const volatile T& location) { T to_return = location; __TBB_release_consistency_helper(); return to_return; } static inline void store_with_release(volatile T &location, T value) { __TBB_release_consistency_helper(); location = value; } }; template struct __TBB_machine_load_store { static inline T load_with_acquire(const volatile T& location) { return __TBB_machine_load8((volatile void *)&location); } static inline void store_with_release(T &location, T value) { __TBB_machine_store8((volatile void *)&location,(__int64)value); } }; template inline T __TBB_machine_load_with_acquire(const volatile T &location) { return __TBB_machine_load_store::load_with_acquire(location); } template inline void __TBB_machine_store_with_release(T& location, V value) { __TBB_machine_load_store::store_with_release(location,value); } //! Overload that exists solely to avoid /Wp64 warnings. inline void __TBB_machine_store_with_release(size_t& location, size_t value) { __TBB_machine_load_store::store_with_release(location,value); } #define __TBB_load_with_acquire(L) __TBB_machine_load_with_acquire((L)) #define __TBB_store_with_release(L,V) __TBB_machine_store_with_release((L),(V)) #define __TBB_DEFINE_ATOMICS(S,T,U,A,C) \ static inline T __TBB_machine_cmpswp##S ( volatile void * ptr, U value, U comparand ) { \ T result; \ volatile T *p = (T *)ptr; \ __TBB_release_consistency_helper(); \ __asm \ { \ __asm mov edx, p \ __asm mov C , value \ __asm mov A , comparand \ __asm lock cmpxchg [edx], C \ __asm mov result, A \ } \ __TBB_release_consistency_helper(); \ return result; \ } \ \ static inline T __TBB_machine_fetchadd##S ( volatile void * ptr, U addend ) { \ T result; \ volatile T *p = (T *)ptr; \ __TBB_release_consistency_helper(); \ __asm \ { \ __asm mov edx, p \ __asm mov A, addend \ __asm lock xadd [edx], A \ __asm mov result, A \ } \ __TBB_release_consistency_helper(); \ return result; \ }\ \ static inline T __TBB_machine_fetchstore##S ( volatile void * ptr, U value ) { \ T result; \ volatile T *p = (T *)ptr; \ __TBB_release_consistency_helper(); \ __asm \ { \ __asm mov edx, p \ __asm mov A, value \ __asm lock xchg [edx], A \ __asm mov result, A \ } \ __TBB_release_consistency_helper(); \ return result; \ } __TBB_DEFINE_ATOMICS(1, __int8, __int8, al, cl) __TBB_DEFINE_ATOMICS(2, __int16, __int16, ax, cx) __TBB_DEFINE_ATOMICS(4, __int32, ptrdiff_t, eax, ecx) static inline __int32 __TBB_machine_lg( unsigned __int64 i ) { unsigned __int32 j; __asm { bsr eax, i mov j, eax } return j; } static inline void __TBB_machine_OR( volatile void *operand, __int32 addend ) { __asm { mov eax, addend mov edx, [operand] lock or [edx], eax } } static inline void __TBB_machine_AND( volatile void *operand, __int32 addend ) { __asm { mov eax, addend mov edx, [operand] lock and [edx], eax } } static inline void __TBB_machine_pause (__int32 delay ) { _asm { mov eax, delay L1: pause add eax, -1 jne L1 } return; } #define __TBB_CompareAndSwap1(P,V,C) __TBB_machine_cmpswp1(P,V,C) #define __TBB_CompareAndSwap2(P,V,C) __TBB_machine_cmpswp2(P,V,C) #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_FetchAndAdd1(P,V) __TBB_machine_fetchadd1(P,V) #define __TBB_FetchAndAdd2(P,V) __TBB_machine_fetchadd2(P,V) #define __TBB_FetchAndAdd4(P,V) __TBB_machine_fetchadd4(P,V) #define __TBB_FetchAndAdd8(P,V) __TBB_machine_fetchadd8(P,V) #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd4(P,V) #define __TBB_FetchAndStore1(P,V) __TBB_machine_fetchstore1(P,V) #define __TBB_FetchAndStore2(P,V) __TBB_machine_fetchstore2(P,V) #define __TBB_FetchAndStore4(P,V) __TBB_machine_fetchstore4(P,V) #define __TBB_FetchAndStore8(P,V) __TBB_machine_fetchstore8(P,V) #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore4(P,V) // Should define this: #define __TBB_Store8(P,V) __TBB_machine_store8(P,V) #define __TBB_Load8(P) __TBB_machine_load8(P) #define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V) // Definition of other functions extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); #define __TBB_Yield() SwitchToThread() #define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Log2(V) __TBB_machine_lg(V) // Use generic definitions from tbb_machine.h #undef __TBB_TryLockByte #undef __TBB_LockByte #if defined(_MSC_VER)&&_MSC_VER<1400 static inline void* __TBB_machine_get_current_teb () { void* pteb; __asm mov eax, fs:[0x18] __asm mov pteb, eax return pteb; } #endif #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warnings 4244, 4267 are back openimageio-1.3.12~dfsg0.orig/src/include/tbb/machine/linux_ia32.h0000644000175000017500000002520212271062644023035 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #error Do not include this file directly; include tbb_machine.h instead #endif #if !__MINGW32__ #include "linux_common.h" #endif #define __TBB_WORDSIZE 4 #define __TBB_BIG_ENDIAN 0 #define __TBB_release_consistency_helper() __asm__ __volatile__("": : :"memory") inline void __TBB_rel_acq_fence() { __asm__ __volatile__("mfence": : :"memory"); } #define __MACHINE_DECL_ATOMICS(S,T,X) \ static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand ) \ { \ T result; \ \ __asm__ __volatile__("lock\ncmpxchg" X " %2,%1" \ : "=a"(result), "=m"(*(T *)ptr) \ : "q"(value), "0"(comparand), "m"(*(T *)ptr) \ : "memory"); \ return result; \ } \ \ static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend) \ { \ T result; \ __asm__ __volatile__("lock\nxadd" X " %0,%1" \ : "=r"(result), "=m"(*(T *)ptr) \ : "0"(addend), "m"(*(T *)ptr) \ : "memory"); \ return result; \ } \ \ static inline T __TBB_machine_fetchstore##S(volatile void *ptr, T value) \ { \ T result; \ __asm__ __volatile__("lock\nxchg" X " %0,%1" \ : "=r"(result), "=m"(*(T *)ptr) \ : "0"(value), "m"(*(T *)ptr) \ : "memory"); \ return result; \ } \ __MACHINE_DECL_ATOMICS(1,int8_t,"") __MACHINE_DECL_ATOMICS(2,int16_t,"") __MACHINE_DECL_ATOMICS(4,int32_t,"l") static inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) { int64_t result; #if __PIC__ /* compiling position-independent code */ // EBX register preserved for compliancy with position-independent code rules on IA32 __asm__ __volatile__ ( "pushl %%ebx\n\t" "movl (%%ecx),%%ebx\n\t" "movl 4(%%ecx),%%ecx\n\t" "lock\n\t cmpxchg8b %1\n\t" "popl %%ebx" : "=A"(result), "=m"(*(int64_t *)ptr) : "m"(*(int64_t *)ptr) , "0"(comparand) , "c"(&value) : "memory", "esp" #if __INTEL_COMPILER ,"ebx" #endif ); #else /* !__PIC__ */ union { int64_t i64; int32_t i32[2]; }; i64 = value; __asm__ __volatile__ ( "lock\n\t cmpxchg8b %1\n\t" : "=A"(result), "=m"(*(int64_t *)ptr) : "m"(*(int64_t *)ptr) , "0"(comparand) , "b"(i32[0]), "c"(i32[1]) : "memory" ); #endif /* __PIC__ */ return result; } static inline int32_t __TBB_machine_lg( uint32_t x ) { int32_t j; __asm__ ("bsr %1,%0" : "=r"(j) : "r"(x)); return j; } static inline void __TBB_machine_or( volatile void *ptr, uint32_t addend ) { __asm__ __volatile__("lock\norl %1,%0" : "=m"(*(uint32_t *)ptr) : "r"(addend), "m"(*(uint32_t *)ptr) : "memory"); } static inline void __TBB_machine_and( volatile void *ptr, uint32_t addend ) { __asm__ __volatile__("lock\nandl %1,%0" : "=m"(*(uint32_t *)ptr) : "r"(addend), "m"(*(uint32_t *)ptr) : "memory"); } static inline void __TBB_machine_pause( int32_t delay ) { for (int32_t i = 0; i < delay; i++) { __asm__ __volatile__("pause;"); } return; } static inline int64_t __TBB_machine_load8 (const volatile void *ptr) { int64_t result; if( ((uint32_t)ptr&7u)==0 ) { // Aligned load __asm__ __volatile__ ( "fildq %1\n\t" "fistpq %0" : "=m"(result) : "m"(*(uint64_t *)ptr) : "memory" ); } else { // Unaligned load result = __TBB_machine_cmpswp8((void*)ptr,0,0); } return result; } //! Handles misaligned 8-byte store /** Defined in tbb_misc.cpp */ extern "C" void __TBB_machine_store8_slow( volatile void *ptr, int64_t value ); extern "C" void __TBB_machine_store8_slow_perf_warning( volatile void *ptr ); static inline void __TBB_machine_store8(volatile void *ptr, int64_t value) { if( ((uint32_t)ptr&7u)==0 ) { // Aligned store __asm__ __volatile__ ( "fildq %1\n\t" "fistpq %0" : "=m"(*(int64_t *)ptr) : "m"(value) : "memory" ); } else { // Unaligned store #if TBB_USE_PERFORMANCE_WARNINGS __TBB_machine_store8_slow_perf_warning(ptr); #endif /* TBB_USE_PERFORMANCE_WARNINGS */ __TBB_machine_store8_slow(ptr,value); } } template struct __TBB_machine_load_store { static inline T load_with_acquire(const volatile T& location) { T to_return = location; __asm__ __volatile__("" : : : "memory" ); // Compiler fence to keep operations from migrating upwards return to_return; } static inline void store_with_release(volatile T &location, T value) { __asm__ __volatile__("" : : : "memory" ); // Compiler fence to keep operations from migrating upwards location = value; } }; template struct __TBB_machine_load_store { static inline T load_with_acquire(const volatile T& location) { T to_return = __TBB_machine_load8((volatile void *)&location); __asm__ __volatile__("" : : : "memory" ); // Compiler fence to keep operations from migrating upwards return to_return; } static inline void store_with_release(volatile T &location, T value) { __asm__ __volatile__("" : : : "memory" ); // Compiler fence to keep operations from migrating downwards __TBB_machine_store8((volatile void *)&location,(int64_t)value); } }; template inline T __TBB_machine_load_with_acquire(const volatile T &location) { return __TBB_machine_load_store::load_with_acquire(location); } template inline void __TBB_machine_store_with_release(volatile T &location, V value) { __TBB_machine_load_store::store_with_release(location,value); } #define __TBB_load_with_acquire(L) __TBB_machine_load_with_acquire((L)) #define __TBB_store_with_release(L,V) __TBB_machine_store_with_release((L),(V)) // Machine specific atomic operations #define __TBB_CompareAndSwap1(P,V,C) __TBB_machine_cmpswp1(P,V,C) #define __TBB_CompareAndSwap2(P,V,C) __TBB_machine_cmpswp2(P,V,C) #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_FetchAndAdd1(P,V) __TBB_machine_fetchadd1(P,V) #define __TBB_FetchAndAdd2(P,V) __TBB_machine_fetchadd2(P,V) #define __TBB_FetchAndAdd4(P,V) __TBB_machine_fetchadd4(P,V) #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd4(P,V) #define __TBB_FetchAndStore1(P,V) __TBB_machine_fetchstore1(P,V) #define __TBB_FetchAndStore2(P,V) __TBB_machine_fetchstore2(P,V) #define __TBB_FetchAndStore4(P,V) __TBB_machine_fetchstore4(P,V) #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore4(P,V) #define __TBB_Store8(P,V) __TBB_machine_store8(P,V) #define __TBB_Load8(P) __TBB_machine_load8(P) #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) // Those we chose not to implement (they will be implemented generically using CMPSWP8) #undef __TBB_FetchAndAdd8 #undef __TBB_FetchAndStore8 // Definition of other functions #define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Log2(V) __TBB_machine_lg(V) // Special atomic functions #define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAddW(P,V) #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1) #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,-1) // Use generic definitions from tbb_machine.h #undef __TBB_TryLockByte #undef __TBB_LockByte openimageio-1.3.12~dfsg0.orig/src/include/tbb/machine/windows_intel64.h0000644000175000017500000001246712271062644024130 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #error Do not include this file directly; include tbb_machine.h instead #endif #include #if !defined(__INTEL_COMPILER) #pragma intrinsic(_InterlockedOr64) #pragma intrinsic(_InterlockedAnd64) #pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedCompareExchange64) #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedExchangeAdd64) #pragma intrinsic(_InterlockedExchange) #pragma intrinsic(_InterlockedExchange64) #endif /* !defined(__INTEL_COMPILER) */ #if defined(__INTEL_COMPILER) #define __TBB_release_consistency_helper() __asm { __asm nop } inline void __TBB_rel_acq_fence() { __asm { __asm mfence } } #elif _MSC_VER >= 1300 extern "C" void _ReadWriteBarrier(); #pragma intrinsic(_ReadWriteBarrier) #define __TBB_release_consistency_helper() _ReadWriteBarrier() #pragma intrinsic(_mm_mfence) inline void __TBB_rel_acq_fence() { _mm_mfence(); } #endif #define __TBB_WORDSIZE 8 #define __TBB_BIG_ENDIAN 0 // ATTENTION: if you ever change argument types in machine-specific primitives, // please take care of atomic_word<> specializations in tbb/atomic.h extern "C" { __int8 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp1 (volatile void *ptr, __int8 value, __int8 comparand ); __int8 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd1 (volatile void *ptr, __int8 addend ); __int8 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore1 (volatile void *ptr, __int8 value ); __int16 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp2 (volatile void *ptr, __int16 value, __int16 comparand ); __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd2 (volatile void *ptr, __int16 addend ); __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore2 (volatile void *ptr, __int16 value ); void __TBB_EXPORTED_FUNC __TBB_machine_pause (__int32 delay ); } #if !__INTEL_COMPILER extern "C" unsigned char _BitScanReverse64( unsigned long* i, unsigned __int64 w ); #pragma intrinsic(_BitScanReverse64) #endif inline __int64 __TBB_machine_lg( unsigned __int64 i ) { #if __INTEL_COMPILER unsigned __int64 j; __asm { bsr rax, i mov j, rax } #else unsigned long j; _BitScanReverse64( &j, i ); #endif return j; } inline void __TBB_machine_OR( volatile void *operand, intptr_t addend ) { _InterlockedOr64((__int64*)operand, addend); } inline void __TBB_machine_AND( volatile void *operand, intptr_t addend ) { _InterlockedAnd64((__int64*)operand, addend); } #define __TBB_CompareAndSwap1(P,V,C) __TBB_machine_cmpswp1(P,V,C) #define __TBB_CompareAndSwap2(P,V,C) __TBB_machine_cmpswp2(P,V,C) #define __TBB_CompareAndSwap4(P,V,C) _InterlockedCompareExchange( (long*) P , V , C ) #define __TBB_CompareAndSwap8(P,V,C) _InterlockedCompareExchange64( (__int64*) P , V , C ) #define __TBB_CompareAndSwapW(P,V,C) _InterlockedCompareExchange64( (__int64*) P , V , C ) #define __TBB_FetchAndAdd1(P,V) __TBB_machine_fetchadd1(P,V) #define __TBB_FetchAndAdd2(P,V) __TBB_machine_fetchadd2(P,V) #define __TBB_FetchAndAdd4(P,V) _InterlockedExchangeAdd((long*) P , V ) #define __TBB_FetchAndAdd8(P,V) _InterlockedExchangeAdd64((__int64*) P , V ) #define __TBB_FetchAndAddW(P,V) _InterlockedExchangeAdd64((__int64*) P , V ) #define __TBB_FetchAndStore1(P,V) __TBB_machine_fetchstore1(P,V) #define __TBB_FetchAndStore2(P,V) __TBB_machine_fetchstore2(P,V) #define __TBB_FetchAndStore4(P,V) _InterlockedExchange((long*) P , V ) #define __TBB_FetchAndStore8(P,V) _InterlockedExchange64((__int64*) P , V ) #define __TBB_FetchAndStoreW(P,V) _InterlockedExchange64((__int64*) P , V ) // Not used if wordsize == 8 #undef __TBB_Store8 #undef __TBB_Load8 #define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V) extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); #define __TBB_Yield() SwitchToThread() #define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Log2(V) __TBB_machine_lg(V) // Use generic definitions from tbb_machine.h #undef __TBB_TryLockByte #undef __TBB_LockByte openimageio-1.3.12~dfsg0.orig/src/include/tbb/machine/linux_intel64.h0000644000175000017500000001542612271062644023573 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_machine_H #error Do not include this file directly; include tbb_machine.h instead #endif #include "linux_common.h" #define __TBB_WORDSIZE 8 #define __TBB_BIG_ENDIAN 0 #define __TBB_release_consistency_helper() __asm__ __volatile__("": : :"memory") inline void __TBB_rel_acq_fence() { __asm__ __volatile__("mfence": : :"memory"); } #define __MACHINE_DECL_ATOMICS(S,T,X) \ static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand ) \ { \ T result; \ \ __asm__ __volatile__("lock\ncmpxchg" X " %2,%1" \ : "=a"(result), "=m"(*(T *)ptr) \ : "q"(value), "0"(comparand), "m"(*(T *)ptr) \ : "memory"); \ return result; \ } \ \ static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend) \ { \ T result; \ __asm__ __volatile__("lock\nxadd" X " %0,%1" \ : "=r"(result),"=m"(*(T *)ptr) \ : "0"(addend), "m"(*(T *)ptr) \ : "memory"); \ return result; \ } \ \ static inline T __TBB_machine_fetchstore##S(volatile void *ptr, T value) \ { \ T result; \ __asm__ __volatile__("lock\nxchg" X " %0,%1" \ : "=r"(result),"=m"(*(T *)ptr) \ : "0"(value), "m"(*(T *)ptr) \ : "memory"); \ return result; \ } \ __MACHINE_DECL_ATOMICS(1,int8_t,"") __MACHINE_DECL_ATOMICS(2,int16_t,"") __MACHINE_DECL_ATOMICS(4,int32_t,"") __MACHINE_DECL_ATOMICS(8,int64_t,"q") static inline int64_t __TBB_machine_lg( uint64_t x ) { int64_t j; __asm__ ("bsr %1,%0" : "=r"(j) : "r"(x)); return j; } static inline void __TBB_machine_or( volatile void *ptr, uint64_t addend ) { __asm__ __volatile__("lock\norq %1,%0" : "=m"(*(uint64_t *)ptr) : "r"(addend), "m"(*(uint64_t *)ptr) : "memory"); } static inline void __TBB_machine_and( volatile void *ptr, uint64_t addend ) { __asm__ __volatile__("lock\nandq %1,%0" : "=m"(*(uint64_t *)ptr) : "r"(addend), "m"(*(uint64_t *)ptr) : "memory"); } static inline void __TBB_machine_pause( int32_t delay ) { for (int32_t i = 0; i < delay; i++) { __asm__ __volatile__("pause;"); } return; } // Machine specific atomic operations #define __TBB_CompareAndSwap1(P,V,C) __TBB_machine_cmpswp1(P,V,C) #define __TBB_CompareAndSwap2(P,V,C) __TBB_machine_cmpswp2(P,V,C) #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_FetchAndAdd1(P,V) __TBB_machine_fetchadd1(P,V) #define __TBB_FetchAndAdd2(P,V) __TBB_machine_fetchadd2(P,V) #define __TBB_FetchAndAdd4(P,V) __TBB_machine_fetchadd4(P,V) #define __TBB_FetchAndAdd8(P,V) __TBB_machine_fetchadd8(P,V) #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd8(P,V) #define __TBB_FetchAndStore1(P,V) __TBB_machine_fetchstore1(P,V) #define __TBB_FetchAndStore2(P,V) __TBB_machine_fetchstore2(P,V) #define __TBB_FetchAndStore4(P,V) __TBB_machine_fetchstore4(P,V) #define __TBB_FetchAndStore8(P,V) __TBB_machine_fetchstore8(P,V) #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore8(P,V) #define __TBB_Store8(P,V) (*P = V) #define __TBB_Load8(P) (*P) #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) // Definition of other functions #define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Log2(V) __TBB_machine_lg(V) // Special atomic functions #define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAddW(P,V) #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1) #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,-1) // Use generic definitions from tbb_machine.h #undef __TBB_TryLockByte #undef __TBB_LockByte openimageio-1.3.12~dfsg0.orig/src/include/tbb/tbb_exception.h0000644000175000017500000002373112271062644022306 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_exception_H #define __TBB_exception_H #include "tbb_stddef.h" #include #include #if __TBB_EXCEPTIONS && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) && !defined(__SUNPRO_CC) #error The current compilation environment does not support exception handling. Please set __TBB_EXCEPTIONS to 0 in tbb_config.h #endif namespace tbb { //! Exception for concurrent containers class bad_last_alloc : public std::bad_alloc { public: virtual const char* what() const throw() { return "bad allocation in previous or concurrent attempt"; } virtual ~bad_last_alloc() throw() {} }; namespace internal { void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4() ; } // namespace internal } // namespace tbb #if __TBB_EXCEPTIONS #include "tbb_allocator.h" #include #include #include namespace tbb { //! Interface to be implemented by all exceptions TBB recognizes and propagates across the threads. /** If an unhandled exception of the type derived from tbb::tbb_exception is intercepted by the TBB scheduler in one of the worker threads, it is delivered to and re-thrown in the root thread. The root thread is the thread that has started the outermost algorithm or root task sharing the same task_group_context with the guilty algorithm/task (the one that threw the exception first). Note: when documentation mentions workers with respect to exception handling, masters are implied as well, because they are completely equivalent in this context. Consequently a root thread can be master or worker thread. NOTE: In case of nested algorithms or complex task hierarchies when the nested levels share (explicitly or by means of implicit inheritance) the task group context of the outermost level, the exception may be (re-)thrown multiple times (ultimately - in each worker on each nesting level) before reaching the root thread at the outermost level. IMPORTANT: if you intercept an exception derived from this class on a nested level, you must re-throw it in the catch block by means of the "throw;" operator. TBB provides two implementations of this interface: tbb::captured_exception and template class tbb::movable_exception. See their declarations for more info. **/ class tbb_exception : public std::exception { public: //! Creates and returns pointer to the deep copy of this exception object. /** Move semantics is allowed. **/ virtual tbb_exception* move () throw() = 0; //! Destroys objects created by the move() method. /** Frees memory and calls destructor for this exception object. Can and must be used only on objects created by the move method. **/ virtual void destroy () throw() = 0; //! Throws this exception object. /** Make sure that if you have several levels of derivation from this interface you implement or override this method on the most derived level. The implementation is as simple as "throw *this;". Failure to do this will result in exception of a base class type being thrown. **/ virtual void throw_self () = 0; //! Returns RTTI name of the originally intercepted exception virtual const char* name() const throw() = 0; //! Returns the result of originally intercepted exception's what() method. virtual const char* what() const throw() = 0; }; //! This class is used by TBB to propagate information about unhandled exceptions into the root thread. /** Exception of this type is thrown by TBB in the root thread (thread that started a parallel algorithm ) if an unhandled exception was intercepted during the algorithm execution in one of the workers. \sa tbb::tbb_exception **/ class captured_exception : public tbb_exception { public: captured_exception ( const captured_exception& src ) : my_dynamic(false) { set(src.my_exception_name, src.my_exception_info); } captured_exception ( const char* name, const char* info ) : my_dynamic(false) { set(name, info); } __TBB_EXPORTED_METHOD ~captured_exception () throw() { clear(); } captured_exception& operator= ( const captured_exception& src ) { if ( this != &src ) { clear(); set(src.my_exception_name, src.my_exception_info); } return *this; } /*override*/ captured_exception* move () throw(); /*override*/ void destroy () throw(); /*override*/ void throw_self () { throw *this; } /*override*/ const char* __TBB_EXPORTED_METHOD name() const throw(); /*override*/ const char* __TBB_EXPORTED_METHOD what() const throw(); private: //! Used only by method clone(). captured_exception() {} //! Functionally equivalent to {captured_exception e(name,info); return c.clone();} static captured_exception* allocate ( const char* name, const char* info ); void set ( const char* name, const char* info ) throw(); void clear () throw(); bool my_dynamic; const char* my_exception_name; const char* my_exception_info; }; //! Template that can be used to implement exception that transfers arbitrary ExceptionData to the root thread /** Code using TBB can instantiate this template with an arbitrary ExceptionData type and throw this exception object. Such exceptions are intercepted by the TBB scheduler and delivered to the root thread (). \sa tbb::tbb_exception **/ template class movable_exception : public tbb_exception { typedef movable_exception self_type; public: movable_exception ( const ExceptionData& data ) : my_exception_data(data) , my_dynamic(false) , my_exception_name(typeid(self_type).name()) {} movable_exception ( const movable_exception& src ) throw () : my_exception_data(src.my_exception_data) , my_dynamic(false) , my_exception_name(src.my_exception_name) {} ~movable_exception () throw() {} const movable_exception& operator= ( const movable_exception& src ) { if ( this != &src ) { my_exception_data = src.my_exception_data; my_exception_name = src.my_exception_name; } return *this; } ExceptionData& data () throw() { return my_exception_data; } const ExceptionData& data () const throw() { return my_exception_data; } /*override*/ const char* name () const throw() { return my_exception_name; } /*override*/ const char* what () const throw() { return "tbb::movable_exception"; } /*override*/ movable_exception* move () throw() { void* e = internal::allocate_via_handler_v3(sizeof(movable_exception)); if ( e ) { new (e) movable_exception(*this); ((movable_exception*)e)->my_dynamic = true; } return (movable_exception*)e; } /*override*/ void destroy () throw() { __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" ); if ( my_dynamic ) { this->~movable_exception(); internal::deallocate_via_handler_v3(this); } } /*override*/ void throw_self () { throw *this; } protected: //! User data ExceptionData my_exception_data; private: //! Flag specifying whether this object has been dynamically allocated (by the move method) bool my_dynamic; //! RTTI name of this class /** We rely on the fact that RTTI names are static string constants. **/ const char* my_exception_name; }; #if !TBB_USE_CAPTURED_EXCEPTION namespace internal { //! Exception container that preserves the exact copy of the original exception /** This class can be used only when the appropriate runtime support (mandated by C++0x) is present **/ class tbb_exception_ptr { std::exception_ptr my_ptr; public: static tbb_exception_ptr* allocate (); static tbb_exception_ptr* allocate ( const tbb_exception& ); static tbb_exception_ptr* allocate ( const captured_exception& ); //! Destroys this objects /** Note that objects of this type can be created only by the allocate() method. **/ void destroy () throw(); //! Throws the contained exception . void throw_self () { std::rethrow_exception(my_ptr); } private: tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {} tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {} }; // class tbb::internal::tbb_exception_ptr } // namespace internal #endif /* !TBB_USE_CAPTURED_EXCEPTION */ } // namespace tbb #endif /* __TBB_EXCEPTIONS */ #endif /* __TBB_exception_H */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/_tbb_windef.h0000644000175000017500000000635012271062644021721 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tbb_windef_H #error Do not #include this file directly. Use "#include tbb/tbb_stddef.h" instead. #endif /* __TBB_tbb_windef_H */ // Check that the target Windows version has all API calls requried for TBB. // Do not increase the version in condition beyond 0x0500 without prior discussion! #if defined(_WIN32_WINNT) && _WIN32_WINNT<0x0400 #error TBB is unable to run on old Windows versions; _WIN32_WINNT must be 0x0400 or greater. #endif #if !defined(_MT) #error TBB requires linkage with multithreaded C/C++ runtime library. \ Choose multithreaded DLL runtime in project settings, or use /MD[d] compiler switch. #elif !defined(_DLL) #pragma message("Warning: Using TBB together with static C/C++ runtime library is not recommended. " \ "Consider switching your project to multithreaded DLL runtime used by TBB.") #endif // Workaround for the problem with MVSC headers failing to define namespace std namespace std { using ::size_t; using ::ptrdiff_t; } #define __TBB_STRING_AUX(x) #x #define __TBB_STRING(x) __TBB_STRING_AUX(x) // Default setting of TBB_USE_DEBUG #ifdef TBB_USE_DEBUG # if TBB_USE_DEBUG # if !defined(_DEBUG) # pragma message(__FILE__ "(" __TBB_STRING(__LINE__) ") : Warning: Recommend using /MDd if compiling with TBB_USE_DEBUG!=0") # endif # else # if defined(_DEBUG) # pragma message(__FILE__ "(" __TBB_STRING(__LINE__) ") : Warning: Recommend using /MD if compiling with TBB_USE_DEBUG==0") # endif # endif #else # ifdef _DEBUG # define TBB_USE_DEBUG 1 # endif #endif #if __TBB_BUILD && !defined(__TBB_NO_IMPLICIT_LINKAGE) #define __TBB_NO_IMPLICIT_LINKAGE 1 #endif #if _MSC_VER #if !__TBB_NO_IMPLICIT_LINKAGE #ifdef _DEBUG #pragma comment(lib, "tbb_debug.lib") #else #pragma comment(lib, "tbb.lib") #endif #endif #endif openimageio-1.3.12~dfsg0.orig/src/include/tbb/tbb_misc.h0000644000175000017500000001032312271062644021234 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef _TBB_tbb_misc_H #define _TBB_tbb_misc_H #include "tbb/tbb_stddef.h" #include "tbb/tbb_machine.h" #if _WIN32||_WIN64 #include #elif defined(__linux__) #include #elif defined(__sun) #include #include #elif defined(__APPLE__) #include #include #elif defined(__FreeBSD__) #include #endif namespace tbb { namespace internal { #if defined(__TBB_DetectNumberOfWorkers) static inline int DetectNumberOfWorkers() { return __TBB_DetectNumberOfWorkers(); } #else #if _WIN32||_WIN64 static inline int DetectNumberOfWorkers() { SYSTEM_INFO si; GetSystemInfo(&si); return static_cast(si.dwNumberOfProcessors); } #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun) static inline int DetectNumberOfWorkers() { long number_of_workers; #if (defined(__FreeBSD__) || defined(__sun)) && defined(_SC_NPROCESSORS_ONLN) number_of_workers = sysconf(_SC_NPROCESSORS_ONLN); // In theory, sysconf should work everywhere. // But in practice, system-specific methods are more reliable #elif defined(__linux__) number_of_workers = get_nprocs(); #elif defined(__APPLE__) int name[2] = {CTL_HW, HW_AVAILCPU}; int ncpu; size_t size = sizeof(ncpu); sysctl( name, 2, &ncpu, &size, NULL, 0 ); number_of_workers = ncpu; #else #error DetectNumberOfWorkers: Method to detect the number of online CPUs is unknown #endif // Fail-safety strap if ( number_of_workers < 1 ) { number_of_workers = 1; } return number_of_workers; } #else #error DetectNumberOfWorkers: OS detection method is unknown #endif /* os kind */ #endif // assertion_failure is declared in tbb/tbb_stddef.h because it user code // needs to see its declaration. //! Throw std::runtime_error of form "(what): (strerror of error_code)" /* The "what" should be fairly short, not more than about 64 characters. Because we control all the call sites to handle_perror, it is pointless to bullet-proof it for very long strings. Design note: ADR put this routine off to the side in tbb_misc.cpp instead of Task.cpp because the throw generates a pathetic lot of code, and ADR wanted this large chunk of code to be placed on a cold page. */ void __TBB_EXPORTED_FUNC handle_perror( int error_code, const char* what ); //! True if environment variable with given name is set and not 0; otherwise false. bool GetBoolEnvironmentVariable( const char * name ); //! Print TBB version information on stderr void PrintVersion(); //! Print extra TBB version information on stderr void PrintExtraVersionInfo( const char* category, const char* description ); //! A callback routine to print RML version information on stderr void PrintRMLVersionInfo( void* arg, const char* server_info ); } // namespace internal } // namespace tbb #endif /* _TBB_tbb_misc_H */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/aligned_space.h0000644000175000017500000000414312271062644022233 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_aligned_space_H #define __TBB_aligned_space_H #include "tbb_stddef.h" #include "tbb_machine.h" namespace tbb { //! Block of space aligned sufficiently to construct an array T with N elements. /** The elements are not constructed or destroyed by this class. @ingroup memory_allocation */ template class aligned_space { private: typedef __TBB_TypeWithAlignmentAtLeastAsStrict(T) element_type; element_type array[(sizeof(T)*N+sizeof(element_type)-1)/sizeof(element_type)]; public: //! Pointer to beginning of array T* begin() {return reinterpret_cast(this);} //! Pointer to one past last element in array. T* end() {return begin()+N;} }; } // namespace tbb #endif /* __TBB_aligned_space_H */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/tbb_profiling.h0000644000175000017500000001136012271062644022274 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_profiling_H #define __TBB_profiling_H // Check if the tools support is enabled #if (_WIN32||_WIN64||__linux__) && TBB_USE_THREADING_TOOLS #if _WIN32||_WIN64 #include /* mbstowcs_s */ #endif #include "tbb_stddef.h" namespace tbb { namespace internal { #if _WIN32||_WIN64 void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const wchar_t* name ); inline size_t multibyte_to_widechar( wchar_t* wcs, const char* mbs, size_t bufsize) { #if _MSC_VER>=1400 size_t len; mbstowcs_s( &len, wcs, bufsize, mbs, _TRUNCATE ); return len; // mbstowcs_s counts null terminator #else size_t len = mbstowcs( wcs, mbs, bufsize ); if(wcs && len!=size_t(-1) ) wcs[len #include #include #include #if _MSC_VER #include #define __TBB_USE_DBGBREAK_DLG TBB_USE_DEBUG #endif #if _MSC_VER >= 1400 #define __TBB_EXPORTED_FUNC __cdecl #else #define __TBB_EXPORTED_FUNC #endif using namespace std; namespace tbb { //! Type for an assertion handler typedef void(*assertion_handler_type)( const char* filename, int line, const char* expression, const char * comment ); static assertion_handler_type assertion_handler; assertion_handler_type __TBB_EXPORTED_FUNC set_assertion_handler( assertion_handler_type new_handler ) { assertion_handler_type old_handler = assertion_handler; assertion_handler = new_handler; return old_handler; } void __TBB_EXPORTED_FUNC assertion_failure( const char* filename, int line, const char* expression, const char* comment ) { if( assertion_handler_type a = assertion_handler ) { (*a)(filename,line,expression,comment); } else { static bool already_failed; if( !already_failed ) { already_failed = true; fprintf( stderr, "Assertion %s failed on line %d of file %s\n", expression, line, filename ); if( comment ) fprintf( stderr, "Detailed description: %s\n", comment ); #if __TBB_USE_DBGBREAK_DLG if(1 == _CrtDbgReport(_CRT_ASSERT, filename, line, "tbb_debug.dll", "%s\r\n%s", expression, comment?comment:"")) _CrtDbgBreak(); #else fflush(stderr); abort(); #endif } } } #if defined(_MSC_VER)&&_MSC_VER<1400 # define vsnprintf _vsnprintf #endif namespace internal { //! Report a runtime warning. void __TBB_EXPORTED_FUNC runtime_warning( const char* format, ... ) { char str[1024]; memset(str, 0, 1024); va_list args; va_start(args, format); vsnprintf( str, 1024-1, format, args); fprintf( stderr, "TBB Warning: %s\n", str); } } // namespace internal } /* namespace tbb */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/spin_rw_mutex.h0000644000175000017500000002025612271062644022363 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_spin_rw_mutex_H #define __TBB_spin_rw_mutex_H #include "tbb_stddef.h" #include "tbb_machine.h" #include "tbb_profiling.h" namespace tbb { class spin_rw_mutex_v3; typedef spin_rw_mutex_v3 spin_rw_mutex; //! Fast, unfair, spinning reader-writer lock with backoff and writer-preference /** @ingroup synchronization */ class spin_rw_mutex_v3 { //! @cond INTERNAL //! Internal acquire write lock. bool __TBB_EXPORTED_METHOD internal_acquire_writer(); //! Out of line code for releasing a write lock. /** This code is has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ void __TBB_EXPORTED_METHOD internal_release_writer(); //! Internal acquire read lock. void __TBB_EXPORTED_METHOD internal_acquire_reader(); //! Internal upgrade reader to become a writer. bool __TBB_EXPORTED_METHOD internal_upgrade(); //! Out of line code for downgrading a writer to a reader. /** This code is has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ void __TBB_EXPORTED_METHOD internal_downgrade(); //! Internal release read lock. void __TBB_EXPORTED_METHOD internal_release_reader(); //! Internal try_acquire write lock. bool __TBB_EXPORTED_METHOD internal_try_acquire_writer(); //! Internal try_acquire read lock. bool __TBB_EXPORTED_METHOD internal_try_acquire_reader(); //! @endcond public: //! Construct unacquired mutex. spin_rw_mutex_v3() : state(0) { #if TBB_USE_THREADING_TOOLS internal_construct(); #endif } #if TBB_USE_ASSERT //! Destructor asserts if the mutex is acquired, i.e. state is zero. ~spin_rw_mutex_v3() { __TBB_ASSERT( !state, "destruction of an acquired mutex"); }; #endif /* TBB_USE_ASSERT */ //! The scoped locking pattern /** It helps to avoid the common problem of forgetting to release lock. It also nicely provides the "node" for queuing locks. */ class scoped_lock : internal::no_copy { public: //! Construct lock that has not acquired a mutex. /** Equivalent to zero-initialization of *this. */ scoped_lock() : mutex(NULL) {} //! Acquire lock on given mutex. /** Upon entry, *this should not be in the "have acquired a mutex" state. */ scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) { acquire(m, write); } //! Release lock (if lock is held). ~scoped_lock() { if( mutex ) release(); } //! Acquire lock on given mutex. void acquire( spin_rw_mutex& m, bool write = true ) { __TBB_ASSERT( !mutex, "holding mutex already" ); is_writer = write; mutex = &m; if( write ) mutex->internal_acquire_writer(); else mutex->internal_acquire_reader(); } //! Upgrade reader to become a writer. /** Returns true if the upgrade happened without re-acquiring the lock and false if opposite */ bool upgrade_to_writer() { __TBB_ASSERT( mutex, "lock is not acquired" ); __TBB_ASSERT( !is_writer, "not a reader" ); is_writer = true; return mutex->internal_upgrade(); } //! Release lock. void release() { __TBB_ASSERT( mutex, "lock is not acquired" ); spin_rw_mutex *m = mutex; mutex = NULL; #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT if( is_writer ) m->internal_release_writer(); else m->internal_release_reader(); #else if( is_writer ) __TBB_AtomicAND( &m->state, READERS ); else __TBB_FetchAndAddWrelease( &m->state, -(intptr_t)ONE_READER); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } //! Downgrade writer to become a reader. bool downgrade_to_reader() { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT __TBB_ASSERT( mutex, "lock is not acquired" ); __TBB_ASSERT( is_writer, "not a writer" ); mutex->internal_downgrade(); #else __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER)); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ is_writer = false; return true; } //! Try acquire lock on given mutex. bool try_acquire( spin_rw_mutex& m, bool write = true ) { __TBB_ASSERT( !mutex, "holding mutex already" ); bool result; is_writer = write; result = write? m.internal_try_acquire_writer() : m.internal_try_acquire_reader(); if( result ) mutex = &m; return result; } private: //! The pointer to the current mutex that is held, or NULL if no mutex is held. spin_rw_mutex* mutex; //! If mutex!=NULL, then is_writer is true if holding a writer lock, false if holding a reader lock. /** Not defined if not holding a lock. */ bool is_writer; }; // Mutex traits static const bool is_rw_mutex = true; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = false; // ISO C++0x compatibility methods //! Acquire writer lock void lock() {internal_acquire_writer();} //! Try acquiring writer lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_lock() {return internal_try_acquire_writer();} //! Release lock void unlock() { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT if( state&WRITER ) internal_release_writer(); else internal_release_reader(); #else if( state&WRITER ) __TBB_AtomicAND( &state, READERS ); else __TBB_FetchAndAddWrelease( &state, -(intptr_t)ONE_READER); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } // Methods for reader locks that resemble ISO C++0x compatibility methods. //! Acquire reader lock void lock_read() {internal_acquire_reader();} //! Try acquiring reader lock (non-blocking) /** Return true if reader lock acquired; false otherwise. */ bool try_lock_read() {return internal_try_acquire_reader();} private: typedef intptr_t state_t; static const state_t WRITER = 1; static const state_t WRITER_PENDING = 2; static const state_t READERS = ~(WRITER | WRITER_PENDING); static const state_t ONE_READER = 4; static const state_t BUSY = WRITER | READERS; //! State of lock /** Bit 0 = writer is holding lock Bit 1 = request by a writer to acquire lock (hint to readers to wait) Bit 2..N = number of readers holding lock */ state_t state; void __TBB_EXPORTED_METHOD internal_construct(); }; __TBB_DEFINE_PROFILING_SET_NAME(spin_rw_mutex) } // namespace tbb #endif /* __TBB_spin_rw_mutex_H */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/spin_mutex.h0000644000175000017500000001412412271062644021650 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_spin_mutex_H #define __TBB_spin_mutex_H #include #include #include "aligned_space.h" #include "tbb_stddef.h" #include "tbb_machine.h" #include "tbb_profiling.h" namespace tbb { //! A lock that occupies a single byte. /** A spin_mutex is a spin mutex that fits in a single byte. It should be used only for locking short critical sections (typically <20 instructions) when fairness is not an issue. If zero-initialized, the mutex is considered unheld. @ingroup synchronization */ class spin_mutex { //! 0 if lock is released, 1 if lock is acquired. unsigned char flag; public: //! Construct unacquired lock. /** Equivalent to zero-initialization of *this. */ spin_mutex() : flag(0) { #if TBB_USE_THREADING_TOOLS internal_construct(); #endif } //! Represents acquisition of a mutex. class scoped_lock : internal::no_copy { private: //! Points to currently held mutex, or NULL if no lock is held. spin_mutex* my_mutex; //! Value to store into spin_mutex::flag to unlock the mutex. internal::uintptr my_unlock_value; //! Like acquire, but with ITT instrumentation. void __TBB_EXPORTED_METHOD internal_acquire( spin_mutex& m ); //! Like try_acquire, but with ITT instrumentation. bool __TBB_EXPORTED_METHOD internal_try_acquire( spin_mutex& m ); //! Like release, but with ITT instrumentation. void __TBB_EXPORTED_METHOD internal_release(); friend class spin_mutex; public: //! Construct without acquiring a mutex. scoped_lock() : my_mutex(NULL), my_unlock_value(0) {} //! Construct and acquire lock on a mutex. scoped_lock( spin_mutex& m ) { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT my_mutex=NULL; internal_acquire(m); #else my_unlock_value = __TBB_LockByte(m.flag); my_mutex=&m; #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ } //! Acquire lock. void acquire( spin_mutex& m ) { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT internal_acquire(m); #else my_unlock_value = __TBB_LockByte(m.flag); my_mutex = &m; #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ } //! Try acquiring lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_acquire( spin_mutex& m ) { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT return internal_try_acquire(m); #else bool result = __TBB_TryLockByte(m.flag); if( result ) { my_unlock_value = 0; my_mutex = &m; } return result; #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ } //! Release lock void release() { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT internal_release(); #else __TBB_store_with_release(my_mutex->flag, static_cast(my_unlock_value)); my_mutex = NULL; #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } //! Destroy lock. If holding a lock, releases the lock first. ~scoped_lock() { if( my_mutex ) { #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT internal_release(); #else __TBB_store_with_release(my_mutex->flag, static_cast(my_unlock_value)); #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ } } }; void __TBB_EXPORTED_METHOD internal_construct(); // Mutex traits static const bool is_rw_mutex = false; static const bool is_recursive_mutex = false; static const bool is_fair_mutex = false; // ISO C++0x compatibility methods //! Acquire lock void lock() { #if TBB_USE_THREADING_TOOLS aligned_space tmp; new(tmp.begin()) scoped_lock(*this); #else __TBB_LockByte(flag); #endif /* TBB_USE_THREADING_TOOLS*/ } //! Try acquiring lock (non-blocking) /** Return true if lock acquired; false otherwise. */ bool try_lock() { #if TBB_USE_THREADING_TOOLS aligned_space tmp; return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this); #else return __TBB_TryLockByte(flag); #endif /* TBB_USE_THREADING_TOOLS*/ } //! Release lock void unlock() { #if TBB_USE_THREADING_TOOLS aligned_space tmp; scoped_lock& s = *tmp.begin(); s.my_mutex = this; s.my_unlock_value = 0; s.internal_release(); #else __TBB_store_with_release(flag, 0); #endif /* TBB_USE_THREADING_TOOLS */ } friend class scoped_lock; }; __TBB_DEFINE_PROFILING_SET_NAME(spin_mutex) } // namespace tbb #endif /* __TBB_spin_mutex_H */ openimageio-1.3.12~dfsg0.orig/src/include/tbb/tbb_allocator.h0000644000175000017500000001730112271062644022264 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #ifndef __TBB_tbb_allocator_H #define __TBB_tbb_allocator_H #include #include #include "tbb_stddef.h" namespace tbb { //! @cond INTERNAL namespace internal { //! Deallocates memory using FreeHandler /** The function uses scalable_free if scalable allocator is available and free if not*/ void __TBB_EXPORTED_FUNC deallocate_via_handler_v3( void *p ); //! Allocates memory using MallocHandler /** The function uses scalable_malloc if scalable allocator is available and malloc if not*/ void* __TBB_EXPORTED_FUNC allocate_via_handler_v3( size_t n ); //! Returns true if standard malloc/free are used to work with memory. bool __TBB_EXPORTED_FUNC is_malloc_used_v3(); } //! @endcond #if _MSC_VER && !defined(__INTEL_COMPILER) // Workaround for erroneous "unreferenced parameter" warning in method destroy. #pragma warning (push) #pragma warning (disable: 4100) #endif //! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 /** The class selects the best memory allocation mechanism available from scalable_malloc and standard malloc. The members are ordered the same way they are in section 20.4.1 of the ISO C++ standard. @ingroup memory_allocation */ template class tbb_allocator { public: typedef typename internal::allocator_type::value_type value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { typedef tbb_allocator other; }; //! Specifies current allocator enum malloc_type { scalable, standard }; tbb_allocator() throw() {} tbb_allocator( const tbb_allocator& ) throw() {} template tbb_allocator(const tbb_allocator&) throw() {} pointer address(reference x) const {return &x;} const_pointer address(const_reference x) const {return &x;} //! Allocate space for n objects. pointer allocate( size_type n, const void* /*hint*/ = 0) { return pointer(internal::allocate_via_handler_v3( n * sizeof(value_type) )); } //! Free previously allocated block of memory. void deallocate( pointer p, size_type ) { internal::deallocate_via_handler_v3(p); } //! Largest value for which method allocate might succeed. size_type max_size() const throw() { size_type max = static_cast(-1) / sizeof (value_type); return (max > 0 ? max : 1); } //! Copy-construct value at location pointed to by p. void construct( pointer p, const value_type& value ) {new(static_cast(p)) value_type(value);} //! Destroy value at location pointed to by p. void destroy( pointer p ) {p->~value_type();} //! Returns current allocator static malloc_type allocator_type() { return internal::is_malloc_used_v3() ? standard : scalable; } }; #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning (pop) #endif // warning 4100 is back //! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 /** @ingroup memory_allocation */ template<> class tbb_allocator { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef tbb_allocator other; }; }; template inline bool operator==( const tbb_allocator&, const tbb_allocator& ) {return true;} template inline bool operator!=( const tbb_allocator&, const tbb_allocator& ) {return false;} //! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 /** The class is an adapter over an actual allocator that fills the allocation using memset function with template argument C as the value. The members are ordered the same way they are in section 20.4.1 of the ISO C++ standard. @ingroup memory_allocation */ template class Allocator = tbb_allocator> class zero_allocator : public Allocator { public: typedef Allocator base_allocator_type; typedef typename base_allocator_type::value_type value_type; typedef typename base_allocator_type::pointer pointer; typedef typename base_allocator_type::const_pointer const_pointer; typedef typename base_allocator_type::reference reference; typedef typename base_allocator_type::const_reference const_reference; typedef typename base_allocator_type::size_type size_type; typedef typename base_allocator_type::difference_type difference_type; template struct rebind { typedef zero_allocator other; }; zero_allocator() throw() { } zero_allocator(const zero_allocator &a) throw() : base_allocator_type( a ) { } template zero_allocator(const zero_allocator &a) throw() : base_allocator_type( Allocator( a ) ) { } pointer allocate(const size_type n, const void *hint = 0 ) { pointer ptr = base_allocator_type::allocate( n, hint ); std::memset( ptr, 0, n * sizeof(value_type) ); return ptr; } }; //! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 /** @ingroup memory_allocation */ template class Allocator> class zero_allocator : public Allocator { public: typedef Allocator base_allocator_type; typedef typename base_allocator_type::value_type value_type; typedef typename base_allocator_type::pointer pointer; typedef typename base_allocator_type::const_pointer const_pointer; template struct rebind { typedef zero_allocator other; }; }; template class B1, typename T2, template class B2> inline bool operator==( const zero_allocator &a, const zero_allocator &b) { return static_cast< B1 >(a) == static_cast< B2 >(b); } template class B1, typename T2, template class B2> inline bool operator!=( const zero_allocator &a, const zero_allocator &b) { return static_cast< B1 >(a) != static_cast< B2 >(b); } } // namespace tbb #endif /* __TBB_tbb_allocator_H */ openimageio-1.3.12~dfsg0.orig/src/include/version.h.in0000644000175000017500000001133712271062644021003 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_VERSION_H #define OPENIMAGEIO_VERSION_H // Versioning of the OpenImageIO software #define OIIO_NAMESPACE @OIIO_NAMESPACE@ #define OIIO_VERSION_MAJOR @OIIO_VERSION_MAJOR@ #define OIIO_VERSION_MINOR @OIIO_VERSION_MINOR@ #define OIIO_VERSION_PATCH @OIIO_VERSION_PATCH@ #define OIIO_VERSION_RELEASE_TYPE @OIIO_VERSION_RELEASE_TYPE@ #define OIIO_VERSION_NS @OIIO_VERSION_NS@ #define OIIO_VERSION (10000 * OIIO_VERSION_MAJOR + \ 100 * OIIO_VERSION_MINOR + \ OIIO_VERSION_PATCH) // We also define the old name for backwards compatibility purposes. #define OPENIMAGEIO_VERSION OIIO_VERSION // Magic macros to make OPENIMAGEIO_VERSION_STRING that looks like "1.2.3" #define OIIO_MAKE_VERSION_STRING2(a,b,c,d) #a "." #b "." #c #d #define OIIO_MAKE_VERSION_STRING(a,b,c,d) OIIO_MAKE_VERSION_STRING2(a,b,c,d) #define OIIO_VERSION_STRING \ OIIO_MAKE_VERSION_STRING(OIIO_VERSION_MAJOR, \ OIIO_VERSION_MINOR, OIIO_VERSION_PATCH, \ OIIO_VERSION_RELEASE_TYPE) #define OIIO_INTRO_STRING "OpenImageIO " OIIO_VERSION_STRING " http://www.openimageio.org" // Macros to use in each file to enter and exit the right name spaces. #define OIIO_NAMESPACE_ENTER namespace OIIO_NAMESPACE { namespace OIIO_VERSION_NS #define OIIO_NAMESPACE_EXIT using namespace OIIO_VERSION_NS; } #define OIIO_NAMESPACE_USING using namespace OIIO_NAMESPACE; // Establish the name spaces and make an alias 'OIIO' that gives us what // everybody really wants. namespace OIIO_NAMESPACE { namespace OIIO_VERSION_NS { } } namespace OIIO = OIIO_NAMESPACE::OIIO_VERSION_NS; /// Each imageio DSO/DLL should include this statement: /// DLLPUBLIC int FORMAT_imageio_version = OPENIMAGEIO_PLUGIN_VERSION; /// libOpenImageIO will check for compatibility this way. /// This should get bumped any time we change the API in any way that /// will make previously-compiled plugins break. /// /// History: /// Version 3 added supports_rectangles() and write_rectangle() to /// ImageOutput, and added stride parameters to the ImageInput read /// routines. /// Version 10 represents forking from NVIDIA's open source version, /// with which we break backwards compatibility. /// Version 11 teased apart subimage versus miplevel specification in /// the APIs and per-channel formats (introduced in OIIO 0.9). /// Version 12 added read_scanlines(), write_scanlines(), read_tiles(), /// write_tiles(), and ImageInput::supports(). (OIIO 1.0) /// Version 13 added ImageInput::valid_file(). (OIIO 1.1) /// Version 14 added ImageOutput::open() variety for multiple subimages. /// Version 15 added support for "deep" images (changing ImageSpec, /// ImageInput, ImageOutput). /// Version 16 changed the ImageInput functions taking channel ranges /// from firstchan,nchans to chbegin,chend. #define OIIO_PLUGIN_VERSION 16 #define OIIO_PLUGIN_NAMESPACE_BEGIN OIIO_NAMESPACE_ENTER { #define OIIO_PLUGIN_NAMESPACE_END } OIIO_NAMESPACE_EXIT #ifdef EMBED_PLUGINS #define OIIO_PLUGIN_EXPORTS_BEGIN #define OIIO_PLUGIN_EXPORTS_END #else #define OIIO_PLUGIN_EXPORTS_BEGIN extern "C" { #define OIIO_PLUGIN_EXPORTS_END } #endif #endif openimageio-1.3.12~dfsg0.orig/src/include/argparse.h0000644000175000017500000001677512271062644020530 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// \brief Simple parsing of program command-line arguments. #ifndef OPENIMAGEIO_ARGPARSE_H #define OPENIMAGEIO_ARGPARSE_H #if defined(_MSC_VER) // Ignore warnings about DLL exported classes with member variables that are template classes. // This happens with the std::string m_errmessage member of ArgParse below. # pragma warning (disable : 4251) #endif #include #include "export.h" #include "version.h" #include "tinyformat.h" OIIO_NAMESPACE_ENTER { class ArgOption; // Forward declaration ///////////////////////////////////////////////////////////////////////////// /// /// \class ArgParse /// /// Argument Parsing /// /// The parse function takes a list of options and variables or functions /// for storing option values and return <0 on failure: /// /// \code /// static int parse_files (int argc, const char *argv[]) /// { /// for (int i = 0; i < argc; i++) /// filenames.push_back (argv[i]); /// return 0; /// } /// /// static int blah_callback (int argc, const char *argv[]) /// { /// std::cout << "blah argument was " << argv[1] << "\n"; /// return 0; /// } /// /// ... /// /// ArgParse ap; /// /// ap.options ("Usage: myapp [options] filename...", /// "%*", parse_objects, "", /// "-camera %f %f %f", &camera[0], &camera[1], &camera[2], /// "set the camera position", /// "-lookat %f %f %f", &lx, &ly, &lz, /// "set the position of interest", /// "-oversampling %d", &oversampling, "oversamping rate", /// "-passes %d", &passes, "number of passes", /// "-lens %f %f %f", &aperture, &focalDistance, &focalLength, /// "set aperture, focal distance, focal length", /// "-format %d %d %f", &width, &height, &aspect, /// "set width, height, aspect ratio", /// "-v", &verbose, "verbose output", /// "-q %!", &verbose, "quiet mode", /// "--blah %@ %s", blahcallback, "Make the callback", /// NULL); /// /// if (ap.parse (argc, argv) < 0) { /// std::cerr << ap.geterror() << std::endl; /// ap.usage (); /// return EXIT_FAILURE; /// } /// \endcode /// /// The available argument types are: /// - no \% argument - bool flag /// - \%! - a bool flag, but set it to false if the option is set /// - \%d - 32bit integer /// - \%f - 32bit float /// - \%F - 64bit float (double) /// - \%s - std::string /// - \%L - std::vector (takes 1 arg, appends to list) /// - \%@ - a function pointer for a callback function will be invoked /// immediately. The prototype for the callback is /// int callback (int argc, char *argv[]) /// - \%* - catch all non-options and pass individually as an (argc,argv) /// sublist to a callback, each immediately after it's found /// /// There are several special format tokens: /// - "" - not an option at all, just a description to print /// in the usage output. /// /// Notes: /// - If an option doesn't have any arguments, a bool flag argument is /// assumed. /// - No argument destinations are initialized. /// - The empty string, "", is used as a global sublist (ie. "%*"). /// - Sublist functions are all of the form "int func(int argc, char **argv)". /// - If a sublist function returns -1, parse() will terminate early. /// - It is perfectly legal for the user to append ':' and more characters /// to the end of an option name, it will match only the portion before /// the semicolon (but a callback can detect the full string, this is /// useful for making arguments: myprog --flag:myopt=1 foobar /// ///////////////////////////////////////////////////////////////////////////// class OIIO_API ArgParse { public: ArgParse (int argc=0, const char **argv=NULL); ~ArgParse (); /// Declare the command line options. After the introductory /// message, parameters are a set of format strings and variable /// pointers. Each string contains an option name and a scanf-like /// format string to enumerate the arguments of that option /// (eg. "-option %d %f %s"). The format string is followed by a /// list of pointers to the argument variables, just like scanf. A /// NULL terminates the list. Multiple calls to options() will /// append additional options. int options (const char *intro, ...); /// With the options already set up, parse the command line. /// Return 0 if ok, -1 if it's a malformed command line. int parse (int argc, const char **argv); /// Return any error messages generated during the course of parse() /// (and clear any error flags). If no error has occurred since the /// last time geterror() was called, it will return an empty string. std::string geterror () const; /// Print the usage message to stdout. The usage message is /// generated and formatted automatically based on the command and /// description arguments passed to parse(). void usage () const; /// Return the entire command-line as one string. /// std::string command_line () const; private: int m_argc; // a copy of the command line argc const char **m_argv; // a copy of the command line argv mutable std::string m_errmessage; // error message ArgOption *m_global; // option for extra cmd line arguments std::string m_intro; std::vector m_option; ArgOption *find_option(const char *name); // void error (const char *format, ...) TINYFORMAT_WRAP_FORMAT (void, error, /**/, std::ostringstream msg;, msg, m_errmessage = msg.str();) int found (const char *option); // number of times option was parsed }; } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_ARGPARSE_H openimageio-1.3.12~dfsg0.orig/src/include/plugin.h0000644000175000017500000000753312271062644020212 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////// /// \file /// /// Helper routines for managing runtime-loadable "plugins", implemented /// variously as DSO's (traditional Unix/Linux), dynamic libraries (Mac /// OS X), DLL's (Windows). ///////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_PLUGIN_H #define OPENIMAGEIO_PLUGIN_H #include #include "export.h" #include "version.h" OIIO_NAMESPACE_ENTER { namespace Plugin { typedef void * Handle; /// Return the platform-dependent suffix for plug-ins ("dll" on /// Windows, "so" on Linux, "dylib" on Mac OS X. OIIO_API const char *plugin_extension (void); /// Open the named plugin, return its handle. If it could not be /// opened, return 0 and the next call to geterror() will contain /// an explanatory message. If the 'global' parameter is true, all /// symbols from the plugin will be available to the app (on Unix-like /// platforms; this has no effect on Windows). OIIO_API Handle open (const char *plugin_filename, bool global=true); inline Handle open (const std::string &plugin_filename, bool global=true) { return open (plugin_filename.c_str(), global); } /// Close the open plugin with the given handle and return true upon /// success. If some error occurred, return false and the next call to /// geterror() will contain an explanatory message. OIIO_API bool close (Handle plugin_handle); /// Get the address of the named symbol from the open plugin handle. If /// some error occurred, return NULL and the next call to /// geterror() will contain an explanatory message. OIIO_API void * getsym (Handle plugin_handle, const char *symbol_name); inline void * getsym (Handle plugin_handle, const std::string &symbol_name) { return getsym (plugin_handle, symbol_name.c_str()); } /// Return any error messages associated with the last call to any of /// open, close, or getsym. Note that in a multithreaded environment, /// it's up to the caller to properly mutex to ensure that no other /// thread has called open, close, or getsym (all of which clear or /// overwrite the error message) between the error-generating call and /// geterror. OIIO_API std::string geterror (void); } // namespace Plugin } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_PLUGIN_H openimageio-1.3.12~dfsg0.orig/src/include/texture.h0000644000175000017500000007200112271062644020404 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// An API for accessing filtered texture lookups via a system that /// automatically manages a cache of resident texture. #ifndef OPENIMAGEIO_TEXTURE_H #define OPENIMAGEIO_TEXTURE_H #include "varyingref.h" #include "ustring.h" #include "imageio.h" #include /* because we need V3f */ OIIO_NAMESPACE_ENTER { // Forward declaration namespace pvt { class TextureSystemImpl; // Used internally by TextureSystem. Unfortunately, this is the only // clean place to store it. Sorry, users, this isn't really for you. enum TexFormat { TexFormatUnknown, TexFormatTexture, TexFormatTexture3d, TexFormatShadow, TexFormatCubeFaceShadow, TexFormatVolumeShadow, TexFormatLatLongEnv, TexFormatCubeFaceEnv, TexFormatLast }; enum EnvLayout { LayoutTexture=0 /* ordinary texture - no special env wrap */, LayoutLatLong, LayoutCubeThreeByTwo, LayoutCubeOneBySix, EnvLayoutLast }; } // pvt namespace /// Data type for flags that indicate on a point-by-point basis whether /// we want computations to be performed. typedef unsigned char Runflag; /// Pre-defined values for Runflag's. /// enum RunFlagVal { RunFlagOff = 0, RunFlagOn = 255 }; class TextureOptions; // forward declaration /// Encapsulate all the options needed for texture lookups. Making /// these options all separate parameters to the texture API routines is /// very ugly and also a big pain whenever we think of new options to /// add. So instead we collect all those little options into one /// structure that can just be passed by reference to the texture API /// routines. class OIIO_API TextureOpt { public: /// Wrap mode describes what happens when texture coordinates describe /// a value outside the usual [0,1] range where a texture is defined. enum Wrap { WrapDefault, ///< Use the default found in the file WrapBlack, ///< Black outside [0..1] WrapClamp, ///< Clamp to [0..1] WrapPeriodic, ///< Periodic mod 1 WrapMirror, ///< Mirror the image WrapLast ///< Mark the end -- don't use this! }; /// Mip mode determines if/how we use mipmaps /// enum MipMode { MipModeDefault, ///< Default high-quality lookup MipModeNoMIP, ///< Just use highest-res image, no MIP mapping MipModeOneLevel, ///< Use just one mipmap level MipModeTrilinear, ///< Use two MIPmap levels (trilinear) MipModeAniso ///< Use two MIPmap levels w/ anisotropic }; /// Interp mode determines how we sample within a mipmap level /// enum InterpMode { InterpClosest, ///< Force closest texel InterpBilinear, ///< Force bilinear lookup within a mip level InterpBicubic, ///< Force cubic lookup within a mip level InterpSmartBicubic ///< Bicubic when maxifying, else bilinear }; /// Create a TextureOpt with all fields initialized to reasonable /// defaults. TextureOpt () : nchannels(1), firstchannel(0), subimage(0), swrap(WrapDefault), twrap(WrapDefault), mipmode(MipModeDefault), interpmode(InterpSmartBicubic), anisotropic(32), conservative_filter(true), sblur(0.0f), tblur(0.0f), swidth(1.0f), twidth(1.0f), fill(0.0f), missingcolor(NULL), dresultds(NULL), dresultdt(NULL), time(0.0f), bias(0.0f), samples(1), rwrap(WrapDefault), rblur(0.0f), rwidth(1.0f), dresultdr(NULL), actualchannels(0), swrap_func(NULL), twrap_func(NULL), rwrap_func(NULL), envlayout(0) { } /// Convert a TextureOptions for one index into a TextureOpt. /// TextureOpt (const TextureOptions &opt, int index); int nchannels; ///< Number of channels to look up int firstchannel; ///< First channel of the lookup int subimage; ///< Subimage or face ID ustring subimagename; ///< Subimage name Wrap swrap; ///< Wrap mode in the s direction Wrap twrap; ///< Wrap mode in the t direction MipMode mipmode; ///< Mip mode InterpMode interpmode; ///< Interpolation mode int anisotropic; ///< Maximum anisotropic ratio bool conservative_filter; ///< True == over-blur rather than alias float sblur, tblur; ///< Blur amount float swidth, twidth; ///< Multiplier for derivatives float fill; ///< Fill value for missing channels const float *missingcolor;///< Color for missing texture float *dresultds; ///< Deriv of the result along s (if not NULL) float *dresultdt; ///< Deriv of the result along t (if not NULL) float time; ///< Time (for time-dependent texture lookups) float bias; ///< Bias for shadows int samples; ///< Number of samples for shadows // For 3D volume texture lookups only: Wrap rwrap; ///< Wrap mode in the r direction float rblur; ///< Blur amount in the r direction float rwidth; ///< Multiplier for derivatives in r direction float *dresultdr; ///< Deriv of the result along r (if not NULL) /// Utility: Return the Wrap enum corresponding to a wrap name: /// "default", "black", "clamp", "periodic", "mirror". static Wrap decode_wrapmode (const char *name); static Wrap decode_wrapmode (ustring name); /// Utility: Parse a single wrap mode (e.g., "periodic") or a /// comma-separated wrap modes string (e.g., "black,clamp") into /// separate Wrap enums for s and t. static void parse_wrapmodes (const char *wrapmodes, TextureOpt::Wrap &swrapcode, TextureOpt::Wrap &twrapcode); private: // Options set INTERNALLY by libtexture after the options are passed // by the user. Users should not attempt to alter these! int actualchannels; // True number of channels read typedef bool (*wrap_impl) (int &coord, int origin, int width); wrap_impl swrap_func, twrap_func, rwrap_func; int envlayout; // Layout for environment wrap friend class pvt::TextureSystemImpl; }; /// Encapsulate all the options needed for texture lookups. Making /// these options all separate parameters to the texture API routines is /// very ugly and also a big pain whenever we think of new options to /// add. So instead we collect all those little options into one /// structure that can just be passed by reference to the texture API /// routines. class OIIO_API TextureOptions { public: /// Wrap mode describes what happens when texture coordinates describe /// a value outside the usual [0,1] range where a texture is defined. enum Wrap { WrapDefault, ///< Use the default found in the file WrapBlack, ///< Black outside [0..1] WrapClamp, ///< Clamp to [0..1] WrapPeriodic, ///< Periodic mod 1 WrapMirror, ///< Mirror the image WrapLast ///< Mark the end -- don't use this! }; /// Mip mode determines if/how we use mipmaps /// enum MipMode { MipModeDefault, ///< Default high-quality lookup MipModeNoMIP, ///< Just use highest-res image, no MIP mapping MipModeOneLevel, ///< Use just one mipmap level MipModeTrilinear, ///< Use two MIPmap levels (trilinear) MipModeAniso ///< Use two MIPmap levels w/ anisotropic }; /// Interp mode determines how we sample within a mipmap level /// enum InterpMode { InterpClosest, ///< Force closest texel InterpBilinear, ///< Force bilinear lookup within a mip level InterpBicubic, ///< Force cubic lookup within a mip level InterpSmartBicubic ///< Bicubic when maxifying, else bilinear }; /// Create a TextureOptions with all fields initialized to reasonable /// defaults. TextureOptions (); /// Convert a TextureOpt for one point into a TextureOptions with /// uninform values. TextureOptions (const TextureOpt &opt); // Options that must be the same for all points we're texturing at once int firstchannel; ///< First channel of the lookup int nchannels; ///< Number of channels to look up int subimage; ///< Subimage or face ID ustring subimagename; ///< Subimage name Wrap swrap; ///< Wrap mode in the s direction Wrap twrap; ///< Wrap mode in the t direction MipMode mipmode; ///< Mip mode InterpMode interpmode; ///< Interpolation mode int anisotropic; ///< Maximum anisotropic ratio bool conservative_filter; ///< True == over-blur rather than alias // Options that may be different for each point we're texturing VaryingRef sblur, tblur; ///< Blur amount VaryingRef swidth, twidth; ///< Multiplier for derivatives VaryingRef time; ///< Time VaryingRef bias; ///< Bias VaryingRef fill; ///< Fill value for missing channels VaryingRef missingcolor; ///< Color for missing texture VaryingRef samples; ///< Number of samples float *dresultds; ///< Deriv of the result along s (if not NULL) float *dresultdt; ///< Deriv of the result along t (if not NULL) // For 3D volume texture lookups only: Wrap rwrap; ///< Wrap mode in the r direction VaryingRef rblur; ///< Blur amount in the r direction VaryingRef rwidth; ///< Multiplier for derivatives in r direction float *dresultdr; ///< Deriv of the result along r (if not NULL) /// Utility: Return the Wrap enum corresponding to a wrap name: /// "default", "black", "clamp", "periodic", "mirror". static Wrap decode_wrapmode (const char *name) { return (Wrap)TextureOpt::decode_wrapmode (name); } static Wrap decode_wrapmode (ustring name) { return (Wrap)TextureOpt::decode_wrapmode (name); } /// Utility: Parse a single wrap mode (e.g., "periodic") or a /// comma-separated wrap modes string (e.g., "black,clamp") into /// separate Wrap enums for s and t. static void parse_wrapmodes (const char *wrapmodes, TextureOptions::Wrap &swrapcode, TextureOptions::Wrap &twrapcode) { TextureOpt::parse_wrapmodes (wrapmodes, *(TextureOpt::Wrap *)&swrapcode, *(TextureOpt::Wrap *)&twrapcode); } private: // Options set INTERNALLY by libtexture after the options are passed // by the user. Users should not attempt to alter these! int actualchannels; // True number of channels read typedef bool (*wrap_impl) (int &coord, int origin, int width); wrap_impl swrap_func, twrap_func, rwrap_func; friend class pvt::TextureSystemImpl; friend class TextureOpt; }; /// Define an API to an abstract class that that manages texture files, /// caches of open file handles as well as tiles of texels so that truly /// huge amounts of texture may be accessed by an application with low /// memory footprint, and ways to perform antialiased texture, shadow /// map, and environment map lookups. class OIIO_API TextureSystem { public: /// Create a TextureSystem and return a pointer. This should only be /// freed by passing it to TextureSystem::destroy()! /// /// If shared==true, it's intended to be shared with other like-minded /// owners in the same process who also ask for a shared cache. If /// false, a private image cache will be created. static TextureSystem *create (bool shared=true); /// Destroy a TextureSystem that was created using /// TextureSystem::create(). For the variety that takes a /// teardown_imagecache parameter, if set to true it will cause the /// underlying ImageCache to be fully destroyed, even if it's the /// "shared" ImageCache. static void destroy (TextureSystem *x); static void destroy (TextureSystem *x, bool teardown_imagecache); TextureSystem (void) { } virtual ~TextureSystem () { } /// Close everything, free resources, start from scratch. /// virtual void clear () = 0; /// Set an attribute controlling the texture system. Return true /// if the name and type were recognized and the attrib was set. /// Documented attributes: /// int max_open_files : maximum number of file handles held open /// float max_memory_MB : maximum tile cache size, in MB /// string searchpath : colon-separated search path for texture files /// string plugin_searchpath : colon-separated search path for plugins /// matrix44 worldtocommon : the world-to-common transformation /// matrix44 commontoworld : the common-to-world transformation /// int autotile : if >0, tile size to emulate for non-tiled images /// int autoscanline : autotile using full width tiles /// int automip : if nonzero, emulate mipmap on the fly /// int accept_untiled : if nonzero, accept untiled images /// int accept_unmipped : if nonzero, accept unmipped images /// int failure_retries : how many times to retry a read failure /// int deduplicate : if nonzero, detect duplicate textures (default=1) /// int gray_to_rgb : make 1-channel images fill RGB lookups /// string latlong_up : default "up" direction for latlong ("y") /// virtual bool attribute (const std::string &name, TypeDesc type, const void *val) = 0; // Shortcuts for common types virtual bool attribute (const std::string &name, int val) = 0; virtual bool attribute (const std::string &name, float val) = 0; virtual bool attribute (const std::string &name, double val) = 0; virtual bool attribute (const std::string &name, const char *val) = 0; virtual bool attribute (const std::string &name, const std::string &val) = 0; /// Get the named attribute, store it in value. virtual bool getattribute (const std::string &name, TypeDesc type, void *val) = 0; // Shortcuts for common types virtual bool getattribute (const std::string &name, int &val) = 0; virtual bool getattribute (const std::string &name, float &val) = 0; virtual bool getattribute (const std::string &name, double &val) = 0; virtual bool getattribute (const std::string &name, char **val) = 0; virtual bool getattribute (const std::string &name, std::string &val) = 0; /// Define an opaque data type that allows us to have a pointer /// to certain per-thread information that the TextureSystem maintains. class Perthread; /// Retrieve an opaque handle for per-thread info, to be used for /// get_texture_handle and the texture routines that take handles /// directly. virtual Perthread * get_perthread_info () = 0; /// Define an opaque data type that allows us to have a handle to a /// texture (already having its name resolved) but without exposing /// any internals. class TextureHandle; /// Retrieve an opaque handle for fast texture lookups. The opaque /// point thread_info is thread-specific information returned by /// get_perthread_info(). Return NULL if something has gone /// horribly wrong. virtual TextureHandle * get_texture_handle (ustring filename, Perthread *thread_info=NULL) = 0; /// Filtered 2D texture lookup for a single point. /// /// s,t are the texture coordinates; dsdx, dtdx, dsdy, and dtdy are /// the differentials of s and t change in some canonical directions /// x and y. The choice of x and y are not important to the /// implementation; it can be any imposed 2D coordinates, such as /// pixels in screen space, adjacent samples in parameter space on a /// surface, etc. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool texture (ustring filename, TextureOpt &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) = 0; /// Slightly faster version of 2D texture() lookup if the app already /// has a texture handle and per-thread info. virtual bool texture (TextureHandle *texture_handle, Perthread *thread_info, TextureOpt &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) = 0; /// Deprecated version that uses old TextureOptions for a single-point /// lookup. virtual bool texture (ustring filename, TextureOptions &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) = 0; /// Retrieve filtered (possibly anisotropic) texture lookups for /// several points at once. /// /// All of the VaryingRef parameters (and fields in options) /// describe texture lookup parameters at an array of positions. /// But this routine only computes them from indices i where /// beginactive <= i < endactive, and ONLY when runflags[i] is /// nonzero. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool texture (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef s, VaryingRef t, VaryingRef dsdx, VaryingRef dtdx, VaryingRef dsdy, VaryingRef dtdy, float *result) = 0; /// Retrieve a 3D texture lookup at a single point. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool texture3d (ustring filename, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, const Imath::V3f &dPdz, float *result) = 0; /// Slightly faster version of texture3d() lookup if the app already /// has a texture handle and per-thread info. virtual bool texture3d (TextureHandle *texture_handle, Perthread *thread_info, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, const Imath::V3f &dPdz, float *result) = 0; /// Deprecated /// virtual bool texture3d (ustring filename, TextureOptions &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, const Imath::V3f &dPdz, float *result) { TextureOpt opt (options, 0); return texture3d (filename, opt, P, dPdx, dPdy, dPdz, result); } /// Retrieve a 3D texture lookup at many points at once. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool texture3d (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef P, VaryingRef dPdx, VaryingRef dPdy, VaryingRef dPdz, float *result) = 0; /// Retrieve a shadow lookup for a single position P. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool shadow (ustring filename, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, float *result) = 0; /// Slightly faster version of shadow() lookup if the app already /// has a texture handle and per-thread info. virtual bool shadow (TextureHandle *texture_handle, Perthread *thread_info, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, float *result) = 0; /// Retrieve a shadow lookup for position P at many points at once. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool shadow (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef P, VaryingRef dPdx, VaryingRef dPdy, float *result) = 0; /// Retrieve an environment map lookup for direction R. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool environment (ustring filename, TextureOpt &options, const Imath::V3f &R, const Imath::V3f &dRdx, const Imath::V3f &dRdy, float *result) = 0; /// Slightly faster version of environment() lookup if the app already /// has a texture handle and per-thread info. virtual bool environment (TextureHandle *texture_handle, Perthread *thread_info, TextureOpt &options, const Imath::V3f &R, const Imath::V3f &dRdx, const Imath::V3f &dRdy, float *result) = 0; /// Retrieve an environment map lookup for direction R, for many /// points at once. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool environment (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef R, VaryingRef dRdx, VaryingRef dRdy, float *result) = 0; /// Given possibly-relative 'filename', resolve it using the search /// path rules and return the full resolved filename. virtual std::string resolve_filename (const std::string &filename) const=0; /// Get information about the given texture. Return true if found /// and the data has been put in *data. Return false if the texture /// doesn't exist, doesn't have the requested data, if the data /// doesn't match the type requested. or some other failure. virtual bool get_texture_info (ustring filename, int subimage, ustring dataname, TypeDesc datatype, void *data) = 0; /// Get the ImageSpec associated with the named texture /// (specifically, the first MIP-map level). If the file is found /// and is an image format that can be read, store a copy of its /// specification in spec and return true. Return false if the file /// was not found or could not be opened as an image file by any /// available ImageIO plugin. virtual bool get_imagespec (ustring filename, int subimage, ImageSpec &spec) = 0; /// Return a pointer to an ImageSpec associated with the named /// texture (specifically, the first MIP-map level) if the file is /// found and is an image format that can be read, otherwise return /// NULL. /// /// This method is much more efficient than get_imagespec(), since /// it just returns a pointer to the spec held internally by the /// underlying ImageCache (rather than copying the spec to the /// user's memory). However, the caller must beware that the /// pointer is only valid as long as nobody (even other threads) /// calls invalidate() on the file, or invalidate_all(), or destroys /// the TextureSystem. virtual const ImageSpec *imagespec (ustring filename, int subimage=0) = 0; /// Retrieve the rectangle of raw unfiltered texels spanning /// [xbegin..xend) X [ybegin..yend) X [zbegin..zend), with /// "exclusive end" a la STL, specified as integer pixel coordinates /// in the designated MIP-map level, storing the texel values /// beginning at the address specified by result. /// The texel values will be converted to the type specified by /// format. It is up to the caller to ensure that result points to /// an area of memory big enough to accommodate the requested /// rectangle (taking into consideration its dimensions, number of /// channels, and data format). Requested pixels outside /// the valid pixel data region will be filled in with 0 values. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool get_texels (ustring filename, TextureOpt &options, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result) = 0; /// Deprecated /// virtual bool get_texels (ustring filename, TextureOptions &options, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result) { TextureOpt opt (options, 0); return get_texels (filename, opt, miplevel, xbegin, xend, ybegin, yend, zbegin, zend, format, result); } /// If any of the API routines returned false indicating an error, /// this routine will return the error string (and clear any error /// flags). If no error has occurred since the last time geterror() /// was called, it will return an empty string. virtual std::string geterror () const = 0; /// Return the statistics output as a huge string. /// virtual std::string getstats (int level=1, bool icstats=true) const = 0; /// Invalidate any cached information about the named file. A client /// might do this if, for example, they are aware that an image /// being held in the cache has been updated on disk. virtual void invalidate (ustring filename) = 0; /// Invalidate all cached data for all textures. If force is true, /// everything will be invalidated, no matter how wasteful it is, /// but if force is false, in actuality files will only be /// invalidated if their modification times have been changed since /// they were first opened. virtual void invalidate_all (bool force=false) = 0; /// Reset most statistics to be as they were with a fresh /// TextureSystem. Caveat emptor: this does not flush the cache /// itelf, so the resulting statistics from the next set of texture /// requests will not match the number of tile reads, etc., that /// would have resulted from a new TextureSystem. virtual void reset_stats () = 0; private: // Make delete private and unimplemented in order to prevent apps // from calling it. Instead, they should call TextureSystem::destroy(). void operator delete (void * /*todel*/) { } }; } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_TEXTURE_H openimageio-1.3.12~dfsg0.orig/src/include/imagebuf.h0000644000175000017500000013703312271062644020472 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Classes for in-memory storage and simple manipulation of whole images, /// which uses ImageInput and ImageOutput underneath for the file access. #ifndef OPENIMAGEIO_IMAGEBUF_H #define OPENIMAGEIO_IMAGEBUF_H #if defined(_MSC_VER) // Ignore warnings about DLL exported classes with member variables that are template classes. // This happens with the std::vector and std::string protected members of ImageBuf below. # pragma warning (disable : 4251) #endif #include "imageio.h" #include "fmath.h" #include "imagecache.h" #include "dassert.h" #include OIIO_NAMESPACE_ENTER { class ImageBuf; /// Helper struct describing a region of interest in an image. /// The region is [xbegin,xend) x [begin,yend) x [zbegin,zend), /// with the "end" designators signifying one past the last pixel, /// a la STL style. struct ROI { int xbegin, xend, ybegin, yend, zbegin, zend; int chbegin, chend; /// Default constructor is an undefined region. /// ROI () : xbegin(std::numeric_limits::min()), xend(0), ybegin(0), yend(0), zbegin(0), zend(0), chbegin(0), chend(0) { } /// Constructor with an explicitly defined region. /// ROI (int xbegin, int xend, int ybegin, int yend, int zbegin=0, int zend=1, int chbegin=0, int chend=10000) : xbegin(xbegin), xend(xend), ybegin(ybegin), yend(yend), zbegin(zbegin), zend(zend), chbegin(chbegin), chend(chend) { } /// Is a region defined? bool defined () const { return (xbegin != std::numeric_limits::min()); } // Region dimensions. int width () const { return xend - xbegin; } int height () const { return yend - ybegin; } int depth () const { return zend - zbegin; } /// Number of channels in the region. Beware -- this defaults to a /// huge number, and to be meaningful you must consider /// std::min (imagebuf.nchannels(), roi.nchannels()). int nchannels () const { return chend - chbegin; } /// Total number of pixels in the region. imagesize_t npixels () const { if (! defined()) return 0; imagesize_t w = width(), h = height(), d = depth(); return w*h*d; } /// Documentary sugar -- although the static ROI::All() function /// simply returns the results of the default ROI constructor, it /// makes it very clear when using as a default function argument /// that it means "all" of the image. For example, /// float myfunc (ImageBuf &buf, ROI roi = ROI::All()); /// Doesn't that make it abundantly clear? static ROI All () { return ROI(); } /// Test equality of two ROIs friend bool operator== (const ROI &a, const ROI &b) { return (a.xbegin == b.xbegin && a.xend == b.xend && a.ybegin == b.ybegin && a.yend == b.yend && a.zbegin == b.zbegin && a.zend == b.zend && a.chbegin == b.chbegin && a.chend == b.chend); } /// Test inequality of two ROIs friend bool operator!= (const ROI &a, const ROI &b) { return (a.xbegin != b.xbegin || a.xend != b.xend || a.ybegin != b.ybegin || a.yend != b.yend || a.zbegin != b.zbegin || a.zend != b.zend || a.chbegin != b.chbegin || a.chend != b.chend); } /// Stream output of the range friend std::ostream & operator<< (std::ostream &out, const ROI &roi) { out << roi.xbegin << ' ' << roi.xend << ' ' << roi.ybegin << ' ' << roi.yend << ' ' << roi.zbegin << ' ' << roi.zend << ' ' << roi.chbegin << ' ' << roi.chend; return out; } }; /// Union of two regions, the smallest region containing both. OIIO_API ROI roi_union (const ROI &A, const ROI &B); /// Intersection of two regions. OIIO_API ROI roi_intersection (const ROI &A, const ROI &B); /// Return pixel data window for this ImageSpec as a ROI. OIIO_API ROI get_roi (const ImageSpec &spec); /// Return full/display window for this ImageSpec as a ROI. OIIO_API ROI get_roi_full (const ImageSpec &spec); /// Set pixel data window for this ImageSpec to a ROI. /// Does NOT change the channels of the spec, regardless of newroi. OIIO_API void set_roi (ImageSpec &spec, const ROI &newroi); /// Set full/display window for this ImageSpec to a ROI. /// Does NOT change the channels of the spec, regardless of newroi. OIIO_API void set_roi_full (ImageSpec &spec, const ROI &newroi); class ImageBufImpl; // Opaque pointer /// An ImageBuf is a simple in-memory representation of a 2D image. It /// uses ImageInput and ImageOutput underneath for its file I/O, and has /// simple routines for setting and getting individual pixels, that /// hides most of the details of memory layout and data representation /// (translating to/from float automatically). class OIIO_API ImageBuf { public: /// Construct an empty/uninitialized ImageBuf. This is relatively /// useless until you call reset(). ImageBuf (); /// Construct an ImageBuf to read the named image (at the designated /// subimage/MIPlevel -- but don't actually read it yet! The image /// will actually be read when other methods need to access the spec /// and/or pixels, or when an explicit call to init_spec() or read() is /// made, whichever comes first. If a non-NULL imagecache is supplied, /// it will specifiy a custom ImageCache to use; if otherwise, the /// global/shared ImageCache will be used. ImageBuf (const std::string &name, int subimage=0, int miplevel=0, ImageCache *imagecache = NULL); /// Construct an ImageBuf to read the named image -- but don't actually /// read it yet! The image will actually be read when other methods /// need to access the spec and/or pixels, or when an explicit call to /// init_spec() or read() is made, whichever comes first. If a non-NULL /// imagecache is supplied, it will specifiy a custom ImageCache to use; /// if otherwise, the global/shared ImageCache will be used. ImageBuf (const std::string &name, ImageCache *imagecache); /// Construct an Imagebuf given a proposed spec describing the image /// size and type, and allocate storage for the pixels of the image /// (whose values will be uninitialized). ImageBuf (const ImageSpec &spec); /// Construct an Imagebuf given both a name and a proposed spec /// describing the image size and type, and allocate storage for /// the pixels of the image (whose values will be undefined). ImageBuf (const std::string &name, const ImageSpec &spec); /// Construct an ImageBuf that "wraps" a memory buffer owned by the /// calling application. It can write pixels to this buffer, but /// can't change its resolution or data type. ImageBuf (const ImageSpec &spec, void *buffer); /// Construct an ImageBuf that "wraps" a memory buffer owned by the /// calling application. It can write pixels to this buffer, but /// can't change its resolution or data type. ImageBuf (const std::string &name, const ImageSpec &spec, void *buffer); /// Construct a copy of an ImageBuf. /// ImageBuf (const ImageBuf &src); /// Destructor for an ImageBuf. /// ~ImageBuf (); /// Description of where the pixels live for this ImageBuf. enum IBStorage { UNINITIALIZED, // no pixel memory LOCALBUFFER, // The IB owns the memory APPBUFFER, // The IB wraps app's memory IMAGECACHE // Backed by ImageCache }; /// Restore the ImageBuf to an uninitialized state. /// void clear (); /// Forget all previous info, reset this ImageBuf to a new image /// that is uninitialized (no pixel values, no size or spec). void reset (const std::string &name, int subimage, int miplevel, ImageCache *imagecache = NULL); /// Forget all previous info, reset this ImageBuf to a new image /// that is uninitialized (no pixel values, no size or spec). void reset (const std::string &name, ImageCache *imagecache=NULL); /// Forget all previous info, reset this ImageBuf to a blank /// image of the given dimensions. void reset (const ImageSpec &spec); /// Forget all previous info, reset this ImageBuf to a blank /// image of the given name and dimensions. void reset (const std::string &name, const ImageSpec &spec); /// Copy spec to *this, and then allocate enough space the right /// size for an image described by the format spec. If the ImageBuf /// already has allocated pixels, their values will not be preserved /// if the new spec does not describe an image of the same size and /// data type as it used to be. /// DEPRECATED (1.3) -- I don't see any reason why this should be /// favored over reset(spec). void alloc (const ImageSpec &spec); /// Which type of storage is being used for the pixels? IBStorage storage () const; /// Is this ImageBuf object initialized? bool initialized () const; /// Read the file from disk. Generally will skip the read if we've /// already got a current version of the image in memory, unless /// force==true. This uses ImageInput underneath, so will read any /// file format for which an appropriate imageio plugin can be found. /// Return value is true if all is ok, otherwise false. bool read (int subimage=0, int miplevel=0, bool force=false, TypeDesc convert=TypeDesc::UNKNOWN, ProgressCallback progress_callback=NULL, void *progress_callback_data=NULL); /// Initialize this ImageBuf with the named image file, and read its /// header to fill out the spec correctly. Return true if this /// succeeded, false if the file could not be read. But don't /// allocate or read the pixels. bool init_spec (const std::string &filename, int subimage, int miplevel); /// Write the image to the named file and file format ("" means to infer /// the type from the filename extension). Return true if all went ok, /// false if there were errors writing. bool write (const std::string &filename, const std::string &fileformat = std::string(), ProgressCallback progress_callback=NULL, void *progress_callback_data=NULL) const; /// Inform the ImageBuf what data format you'd like for any subsequent /// write(). void set_write_format (TypeDesc format); /// Inform the ImageBuf what tile size (or no tiling, for 0) for /// any subsequent write(). void set_write_tiles (int width=0, int height=0, int depth=0); /// DEPRECATED (1.3) synonym for write(). Kept for now for backward /// compatibility. bool save (const std::string &filename = std::string(), const std::string &fileformat = std::string(), ProgressCallback progress_callback=NULL, void *progress_callback_data=NULL) const; /// Write the image to the open ImageOutput 'out'. Return true if /// all went ok, false if there were errors writing. It does NOT /// close the file when it's done (and so may be called in a loop to /// write a multi-image file). bool write (ImageOutput *out, ProgressCallback progress_callback=NULL, void *progress_callback_data=NULL) const; /// Copy all the metadata from src to *this (except for pixel data /// resolution, channel information, and data format). void copy_metadata (const ImageBuf &src); /// Copy the pixel data from src to *this, automatically converting /// to the existing data format of *this. It only copies pixels in /// the overlap regions (and channels) of the two images; pixel data /// in *this that do exist in src will be set to 0, and pixel data /// in src that do not exist in *this will not be copied. bool copy_pixels (const ImageBuf &src); /// Try to copy the pixels and metadata from src to *this, returning /// true upon success and false upon error/failure. /// /// If the previous state of *this was uninitialized, owning its own /// local pixel memory, or referring to a read-only image backed by /// ImageCache, then local pixel memory will be allocated to hold /// the new pixels and the call always succeeds unless the memory /// cannot be allocated. /// /// If *this previously referred to an app-owned memory buffer, the /// memory cannot be re-allocated, so the call will only succeed if /// the app-owned buffer is already the correct resolution and /// number of channels. The data type of the pixels will be /// converted automatically to the data type of the app buffer. bool copy (const ImageBuf &src); /// Swap with another ImageBuf void swap (ImageBuf &other) { std::swap (m_impl, other.m_impl); } /// Error reporting for ImageBuf: call this with printf-like /// arguments. Note however that this is fully typesafe! /// void error (const char *format, ...) TINYFORMAT_WRAP_FORMAT (void, error, const, std::ostringstream msg;, msg, append_error(msg.str());) /// Return true if the IB has had an error and has an error message /// to retrieve via geterror(). bool has_error (void) const; /// Return the text of all error messages issued since geterror() /// was called (or an empty string if no errors are pending). This /// also clears the error message for next time. std::string geterror (void) const; /// Return a read-only (const) reference to the image spec that /// describes the buffer. const ImageSpec & spec () const; /// Return a writable reference to the image spec that describes the /// buffer. Use with extreme caution! If you use this for anything /// other than adding attribute metadata, you are really taking your /// chances! ImageSpec & specmod (); /// Return a read-only (const) reference to the "native" image spec /// (that describes the file, which may be slightly different than /// the spec of the ImageBuf, particularly if the IB is backed by an /// ImageCache that is imposing some particular data format or tile /// size). const ImageSpec & nativespec () const; /// Return the name of this image. /// const std::string & name (void) const; /// Return the name of the image file format of the disk file we /// read into this image. Returns an empty string if this image /// was not the result of a read(). const std::string & file_format_name (void) const; /// Return the index of the subimage are we currently viewing /// int subimage () const; /// Return the number of subimages in the file. /// int nsubimages () const; /// Return the index of the miplevel are we currently viewing /// int miplevel () const; /// Return the number of miplevels of the current subimage. /// int nmiplevels () const; /// Return the number of color channels in the image. /// int nchannels () const; /// Wrap mode describes what happens when an iterator points to /// a value outside the usual data range of an image. enum WrapMode { WrapDefault, WrapBlack, WrapClamp, WrapPeriodic, WrapMirror, _WrapLast }; /// Retrieve a single channel of one pixel. /// float getchannel (int x, int y, int z, int c, WrapMode wrap=WrapBlack) const; /// Retrieve the pixel value by x and y coordintes (on [0,res-1]), /// storing the floating point version in pixel[]. Retrieve at most /// maxchannels (will be clamped to the actual number of channels). void getpixel (int x, int y, float *pixel, int maxchannels=1000) const { getpixel (x, y, 0, pixel, maxchannels); } /// Retrieve the pixel value by x, y, z coordintes (on [0,res-1]), /// storing the floating point version in pixel[]. Retrieve at most /// maxchannels (will be clamped to the actual number of channels). void getpixel (int x, int y, int z, float *pixel, int maxchannels=1000, WrapMode wrap=WrapBlack) const; /// Linearly interpolate at pixel coordinates (x,y), where (0,0) is /// the upper left corner, (xres,yres) the lower right corner of /// the pixel data. void interppixel (float x, float y, float *pixel, WrapMode wrap=WrapBlack) const; /// Linearly interpolate at image data NDC coordinates (s,t), where /// (0,0) is the upper left corner of the pixel data window, (1,1) /// the lower right corner of the pixel data. /// FIXME -- lg thinks that this is stupid, and the only useful NDC /// space is the one used by interppixel_NDC_full. We should deprecate /// this in the future. void interppixel_NDC (float s, float t, float *pixel, WrapMode wrap=WrapBlack) const; /// Linearly interpolate at space coordinates (s,t), where (0,0) is /// the upper left corner of the display window, (1,1) the lower /// right corner of the display window. void interppixel_NDC_full (float s, float t, float *pixel, WrapMode wrap=WrapBlack) const; /// Set the pixel with coordinates (x,y,0) to have the values in /// pixel[0..n-1]. The number of channels copied, n, is the minimum /// of maxchannels and the actual number of channels in the image. void setpixel (int x, int y, const float *pixel, int maxchannels=1000) { setpixel (x, y, 0, pixel, maxchannels); } /// Set the pixel with coordinates (x,y,z) to have the values in /// pixel[0..n-1]. The number of channels copied, n, is the minimum /// of maxchannels and the actual number of channels in the image. void setpixel (int x, int y, int z, const float *pixel, int maxchannels=1000); /// Set the i-th pixel value of the image (out of width*height*depth), /// from floating-point values in pixel[]. Set at most /// maxchannels (will be clamped to the actual number of channels). void setpixel (int i, const float *pixel, int maxchannels=1000); /// Retrieve the rectangle of pixels spanning [xbegin..xend) X /// [ybegin..yend) X [zbegin..zend), channels [chbegin,chend) (all /// with exclusive 'end'), specified as integer pixel coordinates, /// at the current subimage and MIP-map level, storing the pixel /// values beginning at the address specified by result and with the /// given strides (by default, AutoStride means the usual contiguous /// packing of pixels) and converting into the data type described /// by 'format'. It is up to the caller to ensure that result /// points to an area of memory big enough to accommodate the /// requested rectangle. Return true if the operation could be /// completed, otherwise return false. bool get_pixel_channels (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *result, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride) const; /// Retrieve the rectangle of pixels spanning [xbegin..xend) X /// [ybegin..yend) X [zbegin..zend) (with exclusive 'end'), /// specified as integer pixel coordinates, at the current MIP-map /// level, storing the pixel values beginning at the address /// specified by result and with the given strides (by default, /// AutoStride means the usual contiguous packing of pixels) and /// converting into the data type described by 'format'. It is up /// to the caller to ensure that result points to an area of memory /// big enough to accommodate the requested rectangle. Return true /// if the operation could be completed, otherwise return false. bool get_pixels (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride) const; /// Retrieve the rectangle of pixels spanning [xbegin..xend) X /// [ybegin..yend) (with exclusive 'end'), specified as integer /// pixel coordinates, at the current MIP-map level, storing the /// pixel values beginning at the address specified by result and /// with the given strides (by default, AutoStride means the usual /// contiguous packing of pixels), converting to the type in the /// process. It is up to the caller to ensure that result points to /// an area of memory big enough to accommodate the requested /// rectangle. Return true if the operation could be completed, /// otherwise return false. template bool get_pixel_channels (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, T *result, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride) const; template bool get_pixels (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, T *result, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride) const { return get_pixel_channels (xbegin, xend, ybegin, yend, zbegin, zend, 0, nchannels(), result, xstride, ystride, zstride); } /// Even safer version of get_pixels: Retrieve the rectangle of /// pixels spanning [xbegin..xend) X [ybegin..yend) (with exclusive /// 'end'), specified as integer pixel coordinates, at the current /// MIP-map level, storing the pixel values in the 'result' vector /// (even allocating the right size). Return true if the operation /// could be completed, otherwise return false. template bool get_pixels (int xbegin_, int xend_, int ybegin_, int yend_, int zbegin_, int zend_, std::vector &result) const { result.resize (nchannels() * ((zend_-zbegin_)*(yend_-ybegin_)*(xend_-xbegin_))); return get_pixels (xbegin_, xend_, ybegin_, yend_, zbegin_, zend_, &result[0]); } int orientation () const; int oriented_width () const; int oriented_height () const; int oriented_x () const; int oriented_y () const; int oriented_full_width () const; int oriented_full_height () const; int oriented_full_x () const; int oriented_full_y () const; /// Return the beginning (minimum) x coordinate of the defined image. int xbegin () const; /// Return the end (one past maximum) x coordinate of the defined image. int xend () const; /// Return the beginning (minimum) y coordinate of the defined image. int ybegin () const; /// Return the end (one past maximum) y coordinate of the defined image. int yend () const; /// Return the beginning (minimum) z coordinate of the defined image. int zbegin () const; /// Return the end (one past maximum) z coordinate of the defined image. int zend () const; /// Return the minimum x coordinate of the defined image. int xmin () const; /// Return the maximum x coordinate of the defined image. int xmax () const; /// Return the minimum y coordinate of the defined image. int ymin () const; /// Return the maximum y coordinate of the defined image. int ymax () const; /// Return the minimum z coordinate of the defined image. int zmin () const; /// Return the maximum z coordinate of the defined image. int zmax () const; /// Set the "full" (a.k.a. display) window to [xbegin,xend) x /// [ybegin,yend) x [zbegin,zend). void set_full (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend); /// Set the "full" (a.k.a. display) window to [xbegin,xend) x /// [ybegin,yend) x [zbegin,zend). If bordercolor is not NULL, also /// set the spec's "oiio:bordercolor" attribute. /// DEPRECATED (1.3) -- we don't use the 'bordercolor' parameter, and /// it seems strange, so let's phase it out. void set_full (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, const float *bordercolor); /// Return pixel data window for this ImageBuf as a ROI. ROI roi () const; /// Return full/display window for this ImageBuf as a ROI. ROI roi_full () const; /// Set full/display window for this ImageBuf to a ROI. /// Does NOT change the channels of the spec, regardless of newroi. void set_roi_full (const ROI &newroi); bool pixels_valid (void) const; TypeDesc pixeltype () const; /// A raw pointer to "local" pixel memory, if they are fully in RAM /// and not backed by an ImageCache, or NULL otherwise. You can /// also test it like a bool to find out if pixels are local. void *localpixels (); const void *localpixels () const; /// Are the pixels backed by an ImageCache, rather than the whole /// image being in RAM somewhere? bool cachedpixels () const; ImageCache *imagecache () const; /// Return the address where pixel (x,y,z) is stored in the image buffer. /// Use with extreme caution! Will return NULL if the pixel values /// aren't local. const void *pixeladdr (int x, int y, int z=0) const; /// Return the address where pixel (x,y) is stored in the image buffer. /// Use with extreme caution! Will return NULL if the pixel values /// aren't local. void *pixeladdr (int x, int y) { return pixeladdr (x, y, 0); } /// Return the address where pixel (x,y,z) is stored in the image buffer. /// Use with extreme caution! Will return NULL if the pixel values /// aren't local. void *pixeladdr (int x, int y, int z); /// Does this ImageBuf store deep data? bool deep () const; /// Retrieve the number of deep data samples corresponding to pixel /// (x,y,z). Return 0 if not a deep image or if the pixel is out of /// range or has no deep samples. int deep_samples (int x, int y, int z=0) const; /// Return a pointer to the raw array of deep data samples for /// channel c of pixel (x,y,z). Return NULL if the pixel /// coordinates or channel number are out of range, if the /// pixel/channel has no deep samples, or if the image is not deep. const void *deep_pixel_ptr (int x, int y, int z, int c) const; /// Return the value (as a float) of sample s of channel c of pixel /// (x,y,z). Return 0.0 if not a deep image or if the pixel /// coordinates or channel number are out of range or if it has no /// deep samples. float deep_value (int x, int y, int z, int c, int s) const; /// Retrieve the "deep" data. DeepData *deepdata (); const DeepData *deepdata () const; friend class IteratorBase; class IteratorBase { public: IteratorBase (const ImageBuf &ib, WrapMode wrap) : m_ib(&ib), m_tile(NULL), m_proxydata(NULL) { init_ib (wrap); range_is_image (); } /// Construct valid iteration region from ImageBuf and ROI. IteratorBase (const ImageBuf &ib, const ROI &roi, WrapMode wrap) : m_ib(&ib), m_tile(NULL), m_proxydata(NULL) { init_ib (wrap); if (roi.defined()) { m_rng_xbegin = roi.xbegin; m_rng_xend = roi.xend; m_rng_ybegin = roi.ybegin; m_rng_yend = roi.yend; m_rng_zbegin = roi.zbegin; m_rng_zend = roi.zend; } else { range_is_image (); } } /// Construct from an ImageBuf and designated region -- iterate /// over region, starting with the upper left pixel. IteratorBase (const ImageBuf &ib, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, WrapMode wrap) : m_ib(&ib), m_tile(NULL), m_proxydata(NULL) { init_ib (wrap); m_rng_xbegin = xbegin; m_rng_xend = xend; m_rng_ybegin = ybegin; m_rng_yend = yend; m_rng_zbegin = zbegin; m_rng_zend = zend; } IteratorBase (const IteratorBase &i) : m_ib (i.m_ib), m_rng_xbegin(i.m_rng_xbegin), m_rng_xend(i.m_rng_xend), m_rng_ybegin(i.m_rng_ybegin), m_rng_yend(i.m_rng_yend), m_rng_zbegin(i.m_rng_zbegin), m_rng_zend(i.m_rng_zend), m_tile(NULL), m_proxydata(i.m_proxydata) { init_ib (i.m_wrap); } ~IteratorBase () { if (m_tile) m_ib->imagecache()->release_tile (m_tile); } /// Assign one IteratorBase to another /// const IteratorBase & assign_base (const IteratorBase &i) { if (m_tile) m_ib->imagecache()->release_tile (m_tile); m_tile = NULL; m_proxydata = i.m_proxydata; m_ib = i.m_ib; init_ib (i.m_wrap); m_rng_xbegin = i.m_rng_xbegin; m_rng_xend = i.m_rng_xend; m_rng_ybegin = i.m_rng_ybegin; m_rng_yend = i.m_rng_yend; m_rng_zbegin = i.m_rng_zbegin; m_rng_zend = i.m_rng_zend; return *this; } /// Retrieve the current x location of the iterator. /// int x () const { return m_x; } /// Retrieve the current y location of the iterator. /// int y () const { return m_y; } /// Retrieve the current z location of the iterator. /// int z () const { return m_z; } /// Is the current location within the designated iteration range? bool valid () const { return m_valid; } /// Is the location (x,y[,z]) within the designated iteration /// range? bool valid (int x_, int y_, int z_=0) const { return (x_ >= m_rng_xbegin && x_ < m_rng_xend && y_ >= m_rng_ybegin && y_ < m_rng_yend && z_ >= m_rng_zbegin && z_ < m_rng_zend); } /// Is the location (x,y[,z]) within the region of the ImageBuf /// that contains pixel values (sometimes called the "data window")? bool exists (int x_, int y_, int z_=0) const { return (x_ >= m_img_xbegin && x_ < m_img_xend && y_ >= m_img_ybegin && y_ < m_img_yend && z_ >= m_img_zbegin && z_ < m_img_zend); } /// Does the current location exist within the ImageBuf's /// data window? bool exists () const { return m_exists; } /// Are we finished iterating over the region? // bool done () const { // We're "done" if we are both invalid and in exactly the // spot that we would end up after iterating off of the last // pixel in the range. (The m_valid test is just a quick // early-out for when we're in the correct pixel range.) return (m_valid == false && m_x == m_rng_xbegin && m_y == m_rng_ybegin && m_z == m_rng_zend); } /// Retrieve the number of deep data samples at this pixel. int deep_samples () { return m_ib->deep_samples (m_x, m_y, m_z); } /// Return the wrap mode WrapMode wrap () const { return m_wrap; } /// Explicitly point the iterator. This results in an invalid /// iterator if outside the previously-designated region. void pos (int x_, int y_, int z_=0) { if (x_ == m_x+1 && x_ < m_rng_xend && y_ == m_y && z_ == m_z && m_valid && m_exists) { // Special case for what is in effect just incrementing x // within the iteration region. m_x = x_; pos_xincr (); // Not necessary? m_exists = (x_ < m_img_xend); DASSERT ((x_ < m_img_xend) == m_exists); return; } bool v = valid(x_,y_,z_); bool e = exists(x_,y_,z_); if (m_localpixels) { if (e) m_proxydata = (char *)m_ib->pixeladdr (x_, y_, z_); else { // pixel not in data window m_x = x_; m_y = y_; m_z = z_; if (m_wrap == WrapBlack) { m_proxydata = (char *)m_ib->blackpixel(); } else { if (m_ib->do_wrap (x_, y_, z_, m_wrap)) m_proxydata = (char *)m_ib->pixeladdr (x_, y_, z_); else m_proxydata = (char *)m_ib->blackpixel(); } m_valid = v; m_exists = e; return; } } else if (! m_deep) m_proxydata = (char *)m_ib->retile (x_, y_, z_, m_tile, m_tilexbegin, m_tileybegin, m_tilezbegin, m_tilexend, e, m_wrap); m_x = x_; m_y = y_; m_z = z_; m_valid = v; m_exists = e; } /// Increment to the next pixel in the region. /// void operator++ () { if (++m_x < m_rng_xend) { // Special case: we only incremented x, didn't change y // or z, and the previous position was within the data // window. Call a shortcut version of pos. if (m_exists) { pos_xincr (); return; } } else { // Wrap to the next scanline m_x = m_rng_xbegin; if (++m_y >= m_rng_yend) { m_y = m_rng_ybegin; if (++m_z >= m_rng_zend) { m_valid = false; // shortcut -- finished iterating return; } } } pos (m_x, m_y, m_z); } /// Increment to the next pixel in the region. /// void operator++ (int) { ++(*this); } /// Return the iteration range ROI range () const { return ROI (m_rng_xbegin, m_rng_xend, m_rng_ybegin, m_rng_yend, m_rng_zbegin, m_rng_zend, 0, m_ib->nchannels()); } protected: friend class ImageBuf; friend class ImageBufImpl; const ImageBuf *m_ib; bool m_valid, m_exists; bool m_deep; bool m_localpixels; // Image boundaries int m_img_xbegin, m_img_xend, m_img_ybegin, m_img_yend, m_img_zbegin, m_img_zend; // Iteration range int m_rng_xbegin, m_rng_xend, m_rng_ybegin, m_rng_yend, m_rng_zbegin, m_rng_zend; int m_x, m_y, m_z; ImageCache::Tile *m_tile; int m_tilexbegin, m_tileybegin, m_tilezbegin; int m_tilexend; int m_nchannels; size_t m_pixel_bytes; char *m_proxydata; WrapMode m_wrap; // Helper called by ctrs -- set up some locally cached values // that are copied or derived from the ImageBuf. void init_ib (WrapMode wrap) { const ImageSpec &spec (m_ib->spec()); m_deep = spec.deep; m_localpixels = (m_ib->localpixels() != NULL); m_img_xbegin = spec.x; m_img_xend = spec.x+spec.width; m_img_ybegin = spec.y; m_img_yend = spec.y+spec.height; m_img_zbegin = spec.z; m_img_zend = spec.z+spec.depth; m_nchannels = spec.nchannels; // m_tilewidth = spec.tile_width; m_pixel_bytes = spec.pixel_bytes(); m_x = 0xffffffff; m_y = 0xffffffff; m_z = 0xffffffff; m_wrap = (wrap == WrapDefault ? WrapBlack : wrap); } // Helper called by ctrs -- make the iteration range the full // image data window. void range_is_image () { m_rng_xbegin = m_img_xbegin; m_rng_xend = m_img_xend; m_rng_ybegin = m_img_ybegin; m_rng_yend = m_img_yend; m_rng_zbegin = m_img_zbegin; m_rng_zend = m_img_zend; } // Helper called by pos(), but ONLY for the case where we are // moving from an existing pixel to the next spot in +x. // Note: called *after* m_x was incremented! void pos_xincr () { DASSERT (m_exists && m_valid); // precondition DASSERT (valid(m_x,m_y,m_z)); // should be true by definition bool e = (m_x < m_img_xend); if (m_localpixels) { if (e) // Haven't run off the end, just increment m_proxydata += m_pixel_bytes; else { m_exists = false; if (m_wrap == WrapBlack) { m_proxydata = (char *)m_ib->blackpixel(); } else { int x = m_x, y = m_y, z = m_z; if (m_ib->do_wrap (x, y, z, m_wrap)) m_proxydata = (char *)m_ib->pixeladdr (x, y, z); else m_proxydata = (char *)m_ib->blackpixel(); } } } else if (m_deep) { m_proxydata = NULL; } else { // Cached image if (e && m_x < m_tilexend) // Haven't crossed a tile boundary, don't retile! m_proxydata += m_pixel_bytes; else { m_proxydata = (char *)m_ib->retile (m_x, m_y, m_z, m_tile, m_tilexbegin, m_tileybegin, m_tilezbegin, m_tilexend, e, m_wrap); m_exists = e; } } } }; /// Templated class for referring to an individual pixel in an /// ImageBuf, iterating over the pixels of an ImageBuf, or iterating /// over the pixels of a specified region of the ImageBuf /// [xbegin..xend) X [ybegin..yend). It is templated on BUFT, the /// type known to be in the internal representation of the ImageBuf, /// and USERT, the type that the user wants to retrieve or set the /// data (defaulting to float). the whole idea is to allow this: /// \code /// ImageBuf img (...); /// ImageBuf::Iterator pixel (img, 0, 512, 0, 512); /// for ( ; ! pixel.done(); ++pixel) { /// for (int c = 0; c < img.nchannels(); ++c) { /// float x = pixel[c]; /// pixel[c] = ...; /// } /// } /// \endcode /// template class Iterator : public IteratorBase { public: /// Construct from just an ImageBuf -- iterate over the whole /// region, starting with the upper left pixel of the region. Iterator (ImageBuf &ib, WrapMode wrap=WrapDefault) : IteratorBase(ib,wrap) { pos (m_rng_xbegin,m_rng_ybegin,m_rng_zbegin); } /// Construct from an ImageBuf and a specific pixel index. /// The iteration range is the full image. Iterator (ImageBuf &ib, int x, int y, int z=0, WrapMode wrap=WrapDefault) : IteratorBase(ib,wrap) { pos (x, y, z); } /// Construct read-write iteration region from ImageBuf and ROI. Iterator (ImageBuf &ib, const ROI &roi, WrapMode wrap=WrapDefault) : IteratorBase (ib, roi, wrap) { pos (m_rng_xbegin, m_rng_ybegin, m_rng_zbegin); } /// Construct from an ImageBuf and designated region -- iterate /// over region, starting with the upper left pixel. Iterator (ImageBuf &ib, int xbegin, int xend, int ybegin, int yend, int zbegin=0, int zend=1, WrapMode wrap=WrapDefault) : IteratorBase(ib, xbegin, xend, ybegin, yend, zbegin, zend, wrap) { pos (m_rng_xbegin, m_rng_ybegin, m_rng_zbegin); } /// Copy constructor. /// Iterator (Iterator &i) : IteratorBase (i.m_ib, i.m_wrap) { pos (i.m_x, i.m_y, i.m_z); } ~Iterator () { } /// Assign one Iterator to another /// const Iterator & operator= (const Iterator &i) { assign_base (i); pos (i.m_x, i.m_y, i.m_z); return *this; } /// Dereferencing the iterator gives us a proxy for the pixel, /// which we can index for reading or assignment. DataArrayProxy& operator* () { return *(DataArrayProxy *)(void *)&m_proxydata; } /// Array indexing retrieves the value of the i-th channel of /// the current pixel. USERT operator[] (int i) const { DataArrayProxy proxy((BUFT*)m_proxydata); return proxy[i]; } /// Array referencing retrieve a proxy (which may be "assigned /// to") of i-th channel of the current pixel, so that this /// works: me[i] = val; DataProxy operator[] (int i) { DataArrayProxy proxy((BUFT*)m_proxydata); return proxy[i]; } void * rawptr () const { return m_proxydata; } /// Retrieve the deep data value of sample s of channel c. USERT deep_value (int c, int s) const { return convert_type(m_ib->deep_value (m_x, m_y, m_z, c, s)); } }; /// Just like an ImageBuf::Iterator, except that it refers to a /// const ImageBuf. template class ConstIterator : public IteratorBase { public: /// Construct from just an ImageBuf -- iterate over the whole /// region, starting with the upper left pixel of the region. ConstIterator (const ImageBuf &ib, WrapMode wrap=WrapDefault) : IteratorBase(ib,wrap) { pos (m_rng_xbegin,m_rng_ybegin,m_rng_zbegin); } /// Construct from an ImageBuf and a specific pixel index. /// The iteration range is the full image. ConstIterator (const ImageBuf &ib, int x_, int y_, int z_=0, WrapMode wrap=WrapDefault) : IteratorBase(ib,wrap) { pos (x_, y_, z_); } /// Construct read-only iteration region from ImageBuf and ROI. ConstIterator (const ImageBuf &ib, const ROI &roi, WrapMode wrap=WrapDefault) : IteratorBase (ib, roi, wrap) { pos (m_rng_xbegin, m_rng_ybegin, m_rng_zbegin); } /// Construct from an ImageBuf and designated region -- iterate /// over region, starting with the upper left pixel. ConstIterator (const ImageBuf &ib, int xbegin, int xend, int ybegin, int yend, int zbegin=0, int zend=1, WrapMode wrap=WrapDefault) : IteratorBase(ib, xbegin, xend, ybegin, yend, zbegin, zend, wrap) { pos (m_rng_xbegin, m_rng_ybegin, m_rng_zbegin); } /// Copy constructor. /// ConstIterator (const ConstIterator &i) : IteratorBase (i) { pos (i.m_x, i.m_y, i.m_z); } ~ConstIterator () { } /// Assign one ConstIterator to another /// const ConstIterator & operator= (const ConstIterator &i) { assign_base (i); pos (i.m_x, i.m_y, i.m_z); return *this; } /// Dereferencing the iterator gives us a proxy for the pixel, /// which we can index for reading or assignment. ConstDataArrayProxy& operator* () const { return *(ConstDataArrayProxy *)&m_proxydata; } /// Array indexing retrieves the value of the i-th channel of /// the current pixel. USERT operator[] (int i) const { ConstDataArrayProxy proxy ((BUFT*)m_proxydata); return proxy[i]; } const void * rawptr () const { return m_proxydata; } /// Retrieve the deep data value of sample s of channel c. USERT deep_value (int c, int s) const { return convert_type(m_ib->deep_value (m_x, m_y, m_z, c, s)); } }; protected: ImageBufImpl *m_impl; //< PIMPL idiom ImageBufImpl * impl () { return m_impl; } const ImageBufImpl * impl () const { return m_impl; } // Copy src's pixels into *this. Pixels must already be local // (either owned or wrapped) and the resolution and number of // channels must match src. Data type is allowed to be different, // however, with automatic conversion upon copy. void copy_from (const ImageBuf &src); // Reset the ImageCache::Tile * to reserve and point to the correct // tile for the given pixel, and return the ptr to the actual pixel // within the tile. const void * retile (int x, int y, int z, ImageCache::Tile* &tile, int &tilexbegin, int &tileybegin, int &tilezbegin, int &tilexend, bool exists, WrapMode wrap=WrapDefault) const; const void *blackpixel () const; // Given x,y,z known to be outside the pixel data range, and a wrap // mode, alter xyz to implement the wrap. Return true if the resulting // x,y,z is within the valid pixel data window, false if it still is // not. bool do_wrap (int &x, int &y, int &z, WrapMode wrap) const; /// Private and unimplemented. const ImageBuf& operator= (const ImageBuf &src); /// Add to the error message list for this IB. void append_error (const std::string& message) const; }; } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_IMAGEBUF_H openimageio-1.3.12~dfsg0.orig/src/include/imageio.h0000644000175000017500000020264312271062644020325 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////////// /// \file /// /// Provides a simple API that abstracts the reading and writing of /// images. Subclasses, which may be found in DSO/DLL's, implement /// particular formats. /// ///////////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_IMAGEIO_H #define OPENIMAGEIO_IMAGEIO_H #if defined(_MSC_VER) // Ignore warnings about DLL exported classes with member variables that are template classes. // This happens with the std::vector and std::string members of the classes below. # pragma warning (disable : 4251) #endif #include #include #include #include #include "export.h" #include "typedesc.h" /* Needed for TypeDesc definition */ #include "paramlist.h" #include "version.h" OIIO_NAMESPACE_ENTER { /// Type we use for stride lengths. This is only used to designate /// pixel, scanline, tile, or image plane sizes in user-allocated memory, /// so it doesn't need to represent sizes larger than can be malloced, /// therefore ptrdiff_t seemed right. typedef ptrdiff_t stride_t; /// Type we use to express how many pixels (or bytes) constitute an image, /// tile, or scanline. Needs to be large enough to handle very big images /// (which we presume could be > 4GB). #if defined(LINUX64) || defined(_WIN64) /* add others if we know for sure size_t is ok */ typedef size_t imagesize_t; #else typedef unsigned long long imagesize_t; #endif /// Special value to indicate a stride length that should be /// auto-computed. const stride_t AutoStride = std::numeric_limits::min(); /// Pointer to a function called periodically by read_image and /// write_image. This can be used to implement progress feedback, etc. /// It takes an opaque data pointer (passed to read_image/write_image) /// and a float giving the portion of work done so far. It returns a /// bool, which if 'true' will STOP the read or write. typedef bool (*ProgressCallback)(void *opaque_data, float portion_done); typedef ParamValue ImageIOParameter; typedef ParamValueList ImageIOParameterList; /// ImageSpec describes the data format of an image -- /// dimensions, layout, number and meanings of image channels. class OIIO_API ImageSpec { public: int x, y, z; ///< origin (upper left corner) of pixel data int width; ///< width of the pixel data window int height; ///< height of the pixel data window int depth; ///< depth of pixel data, >1 indicates a "volume" int full_x; ///< origin of the full (display) window int full_y; ///< origin of the full (display) window int full_z; ///< origin of the full (display) window int full_width; ///< width of the full (display) window int full_height; ///< height of the full (display) window int full_depth; ///< depth of the full (display) window int tile_width; ///< tile width (0 for a non-tiled image) int tile_height; ///< tile height (0 for a non-tiled image) int tile_depth; ///< tile depth (0 for a non-tiled image, ///< 1 for a non-volume image) int nchannels; ///< number of image channels, e.g., 4 for RGBA TypeDesc format; ///< data format of the channels std::vector channelformats; ///< Optional per-channel formats std::vector channelnames; ///< Names for each channel, ///< e.g., {"R","G","B","A"} int alpha_channel; ///< Index of alpha channel, or -1 if not known int z_channel; ///< Index of depth channel, or -1 if not known bool deep; ///< Contains deep data // quantize is used for ImageOutput int quant_black; ///< quantization of black (0.0) level int quant_white; ///< quantization of white (1.0) level int quant_min; ///< quantization minimum clamp value int quant_max; ///< quantization maximum clamp value /// The above contains all the information that is likely needed for /// every image file, and common to all formats. Rather than bloat /// this structure, customize it for new formats, or break back /// compatibility as we think of new things, we provide extra_attribs /// as a holder for any other properties of the image. The public /// functions attribute and find_attribute may be used to access /// these data. Note, however, that the names and semantics of such /// extra attributes are plugin-dependent and are not enforced by /// the imageio library itself. ImageIOParameterList extra_attribs; ///< Additional attributes /// Constructor: given just the data format, set the default quantize /// and set all other channels to something reasonable. ImageSpec (TypeDesc format = TypeDesc::UNKNOWN); /// Constructor for simple 2D scanline image with nothing special. /// If fmt is not supplied, default to unsigned 8-bit data. ImageSpec (int xres, int yres, int nchans, TypeDesc fmt = TypeDesc::UINT8); /// Set the data format, and as a side effect set quantize /// to good defaults for that format void set_format (TypeDesc fmt); /// Set the channelnames to reasonable defaults ("R", "G", "B", "A"), /// and alpha_channel, based on the number of channels. void default_channel_names (); /// Given quantization parameters, deduce a TypeDesc that can /// be used without unacceptable loss of significant bits. static TypeDesc format_from_quantize (int quant_black, int quant_white, int quant_min, int quant_max); /// Return the number of bytes for each channel datum, assuming they /// are all stored using the data format given by this->format. size_t channel_bytes() const { return format.size(); } /// Return the number of bytes needed for the single specified /// channel. If native is false (default), compute the size of one /// channel of this->format, but if native is true, compute the size /// of the channel in terms of the "native" data format of that /// channel as stored in the file. size_t channel_bytes (int chan, bool native=false) const; /// Return the number of bytes for each pixel (counting all channels). /// If native is false (default), assume all channels are in /// this->format, but if native is true, compute the size of a pixel /// in the "native" data format of the file (these may differ in /// the case of per-channel formats). /// This will return std::numeric_limits::max() in the /// event of an overflow where it's not representable in a size_t. size_t pixel_bytes (bool native=false) const; /// Return the number of bytes for just the subset of channels in /// each pixel described by [chbegin,chend). /// If native is false (default), assume all channels are in /// this->format, but if native is true, compute the size of a pixel /// in the "native" data format of the file (these may differ in /// the case of per-channel formats). /// This will return std::numeric_limits::max() in the /// event of an overflow where it's not representable in a size_t. size_t pixel_bytes (int chbegin, int chend, bool native=false) const; /// Return the number of bytes for each scanline. This will return /// std::numeric_limits::max() in the event of an /// overflow where it's not representable in an imagesize_t. /// If native is false (default), assume all channels are in /// this->format, but if native is true, compute the size of a pixel /// in the "native" data format of the file (these may differ in /// the case of per-channel formats). imagesize_t scanline_bytes (bool native=false) const; /// Return the number of pixels for a tile. This will return /// std::numeric_limits::max() in the event of an /// overflow where it's not representable in an imagesize_t. imagesize_t tile_pixels () const; /// Return the number of bytes for each a tile of the image. This /// will return std::numeric_limits::max() in the event /// of an overflow where it's not representable in an imagesize_t. /// If native is false (default), assume all channels are in /// this->format, but if native is true, compute the size of a pixel /// in the "native" data format of the file (these may differ in /// the case of per-channel formats). imagesize_t tile_bytes (bool native=false) const; /// Return the number of pixels for an entire image. This will /// return std::numeric_limits::max() in the event of /// an overflow where it's not representable in an imagesize_t. imagesize_t image_pixels () const; /// Return the number of bytes for an entire image. This will /// return std::numeric_limits::max() in the event of /// an overflow where it's not representable in an imagesize_t. /// If native is false (default), assume all channels are in /// this->format, but if native is true, compute the size of a pixel /// in the "native" data format of the file (these may differ in /// the case of per-channel formats). imagesize_t image_bytes (bool native=false) const; /// Verify that on this platform, a size_t is big enough to hold the /// number of bytes (and pixels) in a scanline, a tile, and the /// whole image. If this returns false, the image is much too big /// to allocate and read all at once, so client apps beware and check /// these routines for overflows! bool size_t_safe() const { const imagesize_t big = std::numeric_limits::max(); return image_bytes() < big && scanline_bytes() < big && tile_bytes() < big; } /// Adjust the stride values, if set to AutoStride, to be the right /// sizes for contiguous data with the given format, channels, /// width, height. static void auto_stride (stride_t &xstride, stride_t &ystride, stride_t &zstride, stride_t channelsize, int nchannels, int width, int height) { if (xstride == AutoStride) xstride = nchannels * channelsize; if (ystride == AutoStride) ystride = xstride * width; if (zstride == AutoStride) zstride = ystride * height; } /// Adjust the stride values, if set to AutoStride, to be the right /// sizes for contiguous data with the given format, channels, /// width, height. static void auto_stride (stride_t &xstride, stride_t &ystride, stride_t &zstride, TypeDesc format, int nchannels, int width, int height) { auto_stride (xstride, ystride, zstride, format.size(), nchannels, width, height); } /// Adjust xstride, if set to AutoStride, to be the right size for /// contiguous data with the given format and channels. static void auto_stride (stride_t &xstride, TypeDesc format, int nchannels) { if (xstride == AutoStride) xstride = nchannels * format.size(); } /// Add an optional attribute to the extra attribute list /// void attribute (const std::string &name, TypeDesc type, const void *value); /// Add an optional attribute to the extra attribute list. /// void attribute (const std::string &name, TypeDesc type, const std::string &value); /// Add an unsigned int attribute /// void attribute (const std::string &name, unsigned int value) { attribute (name, TypeDesc::UINT, &value); } /// Add an int attribute /// void attribute (const std::string &name, int value) { attribute (name, TypeDesc::INT, &value); } /// Add a float attribute /// void attribute (const std::string &name, float value) { attribute (name, TypeDesc::FLOAT, &value); } /// Add a string attribute /// void attribute (const std::string &name, const char *value) { attribute (name, TypeDesc::STRING, &value); } /// Add a string attribute /// void attribute (const std::string &name, const std::string &value) { attribute (name, value.c_str()); } /// Remove the specified attribute from the list of extra /// attributes. If not found, do nothing. void erase_attribute (const std::string &name, TypeDesc searchtype=TypeDesc::UNKNOWN, bool casesensitive=false); /// Search for a attribute of the given name in the list of extra /// attributes. ImageIOParameter * find_attribute (const std::string &name, TypeDesc searchtype=TypeDesc::UNKNOWN, bool casesensitive=false); const ImageIOParameter *find_attribute (const std::string &name, TypeDesc searchtype=TypeDesc::UNKNOWN, bool casesensitive=false) const; /// Simple way to get an integer attribute, with default provided. /// Automatically will return an int even if the data is really /// unsigned, short, or byte. int get_int_attribute (const std::string &name, int defaultval=0) const; /// Simple way to get a float attribute, with default provided. /// Automatically will return a float even if the data is really /// double or half. float get_float_attribute (const std::string &name, float defaultval=0) const; /// Simple way to get a string attribute, with default provided. /// std::string get_string_attribute (const std::string &name, const std::string &defaultval = std::string()) const; /// For a given parameter (in this ImageSpec's extra_attribs), /// format the value nicely as a string. If 'human' is true, use /// especially human-readable explanations (units, or decoding of /// values) for certain known metadata. std::string metadata_val (const ImageIOParameter &p, bool human=false) const; /// Convert ImageSpec class into XML string. /// std::string to_xml () const; /// Get an ImageSpec class from XML string. /// void from_xml (const char *xml); /// Helper function to verify that the given pixel range exactly covers /// a set of tiles. Also returns false if the spec indicates that the /// image isn't tiled at all. bool valid_tile_range (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend) { return (tile_width && ((xbegin-x) % tile_width) == 0 && ((ybegin-y) % tile_height) == 0 && ((zbegin-z) % tile_depth) == 0 && (((xend-x) % tile_width) == 0 || (xend-x) == width) && (((yend-y) % tile_height) == 0 || (yend-y) == height) && (((zend-z) % tile_depth) == 0 || (zend-z) == depth)); } /// Return teh channelformat of the given channel. TypeDesc channelformat (int chan) const { return chan >= (int)channelformats.size() ? format : channelformats[chan]; } /// Fill in an array of channel formats describing all channels in /// the image. (Note that this differs slightly from the member /// data channelformats, which is empty if there are not separate /// per-channel formats.) void get_channelformats (std::vector &formats) const { formats = channelformats; if ((int)formats.size() < nchannels) formats.resize (nchannels, format); } }; /// Structure to hold "deep" data -- multiple samples per pixel. struct OIIO_API DeepData { public: int npixels, nchannels; std::vector channeltypes; // for each channel [c] std::vector nsamples;// for each pixel [z][y][x] std::vector pointers; // for each channel per pixel [z][y][x][c] std::vector data; // for each sample [z][y][x][c][s] DeepData () : npixels(0), nchannels(0) { } /// Initialize size and allocate nsamples, pointers void init (int npix, int nchan, const TypeDesc *chbegin, const TypeDesc *chend); /// After nsamples[] has been filled in, allocate enough scratch space /// for data and set up all the pointers. void alloc (); /// Clear the vectors and reset size to 0. void clear (); /// Deallocate all space in the vectors void free (); }; /// ImageInput abstracts the reading of an image file in a file /// format-agnostic manner. class OIIO_API ImageInput { public: /// Create an ImageInput subclass instance that is able to read /// the given file and open it, returning the opened ImageInput if /// successful. If it fails, return NULL and set an error that can /// be retrieved by OpenImageIO::geterror(). /// /// The 'config', if not NULL, points to an ImageSpec giving /// requests or special instructions. ImageInput implementations /// are free to not respond to any such requests, so the default /// implementation is just to ignore config. /// /// open() will first try to make an ImageInput corresponding to /// the format implied by the file extension (for example, "foo.tif" /// will try the TIFF plugin), but if one is not found or if the /// inferred one does not open the file, every known ImageInput type /// will be tried until one is found that will open the file. static ImageInput *open (const std::string &filename, const ImageSpec *config = NULL); /// Create and return an ImageInput implementation that is willing /// to read the given file. The plugin_searchpath parameter is a /// colon-separated list of directories to search for ImageIO plugin /// DSO/DLL's (not a searchpath for the image itself!). This will /// actually just try every imageio plugin it can locate, until it /// finds one that's able to open the file without error. This just /// creates the ImageInput, it does not open the file. /// /// If the caller intends to immediately open the file, then it is /// simpler to call static ImageInput::open(). static ImageInput *create (const std::string &filename, const std::string &plugin_searchpath=""); ImageInput () { } virtual ~ImageInput () { } /// Return the name of the format implemented by this class. /// virtual const char *format_name (void) const = 0; /// Return true if the named file is file of the type for this /// ImageInput. The implementation will try to determine this as /// efficiently as possible, in most cases much less expensively /// than doing a full open(). Note that a file can appear to be of /// the right type (i.e., valid_file() returning true) but still /// fail a subsequent call to open(), such as if the contents of the /// file are truncated, nonsensical, or otherwise corrupted. virtual bool valid_file (const std::string &filename) const; /// Open file with given name. Various file attributes are put in /// newspec and a copy is also saved in this->spec. From these /// attributes, you can discern the resolution, if it's tiled, /// number of channels, and native data format. Return true if the /// file was found and opened okay. virtual bool open (const std::string &name, ImageSpec &newspec) = 0; /// Open file with given name, similar to open(name,newspec). The /// 'config' is an ImageSpec giving requests or special /// instructions. ImageInput implementations are free to not /// respond to any such requests, so the default implementation is /// just to ignore config and call regular open(name,newspec). virtual bool open (const std::string &name, ImageSpec &newspec, const ImageSpec & /*config*/) { return open(name,newspec); } /// Return a reference to the image format specification of the /// current subimage/MIPlevel. Note that the contents of the spec /// are invalid before open() or after close(), and may change with /// a call to seek_subimage(). const ImageSpec &spec (void) const { return m_spec; } /// Given the name of a 'feature', return whether this ImageInput /// supports input of images with the given properties. /// Feature names that ImageIO plugins are expected to recognize /// include: /// none at this time /// /// Note that main advantage of this approach, versus having /// separate individual supports_foo() methods, is that this allows /// future expansion of the set of possible queries without changing /// the API, adding new entry points, or breaking linkage /// compatibility. virtual bool supports (const std::string & /*feature*/) const { return false; } /// Close an image that we are totally done with. /// virtual bool close () = 0; /// Returns the index of the subimage that is currently being read. /// The first subimage (or the only subimage, if there is just one) /// is number 0. virtual int current_subimage (void) const { return 0; } /// Returns the index of the MIPmap image that is currently being read. /// The highest-res MIP level (or the only level, if there is just /// one) is number 0. virtual int current_miplevel (void) const { return 0; } /// Seek to the given subimage and MIP-map level within the open /// image file. The first subimage of the file has index 0, the /// highest-resolution MIP level has index 0. Return true on /// success, false on failure (including that there is not a /// subimage or MIP level with the specified index). The new /// subimage's vital statistics are put in newspec (and also saved /// in this->spec). The reader is expected to give the appearance /// of random access to subimages and MIP levels -- in other words, /// if it can't randomly seek to the given subimage/level, it should /// transparently close, reopen, and sequentially read through prior /// subimages and levels. virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (subimage == current_subimage() && miplevel == current_miplevel()) { newspec = spec(); return true; } return false; } /// Seek to the given subimage -- backwards-compatible call that /// doesn't worry about MIP-map levels at all. bool seek_subimage (int subimage, ImageSpec &newspec) { return seek_subimage (subimage, 0 /* miplevel */, newspec); } /// Read the scanline that includes pixels (*,y,z) into data, /// converting if necessary from the native data format of the file /// into the 'format' specified (z==0 for non-volume images). The /// stride value gives the data spacing of adjacent pixels (in /// bytes). Strides set to AutoStride imply 'contiguous' data, i.e., /// xstride == spec.nchannels*format.size() /// If format is TypeDesc::UNKNOWN, then rather than converting to /// format, it will just copy pixels in the file's native data layout /// (including, possibly, per-channel data formats). /// The reader is expected to give the appearance of random access -- /// in other words, if it can't randomly seek to the given scanline, /// it should transparently close, reopen, and sequentially read /// through prior scanlines. The base ImageInput class has a /// default implementation that calls read_native_scanline and then /// does appropriate format conversion, so there's no reason for /// each format plugin to override this method. virtual bool read_scanline (int y, int z, TypeDesc format, void *data, stride_t xstride=AutoStride); /// /// Simple read_scanline reads to contiguous float pixels. bool read_scanline (int y, int z, float *data) { return read_scanline (y, z, TypeDesc::FLOAT, data); } /// Read multiple scanlines that include pixels (*,y,z) for all /// ybegin <= y < yend, into data, using the strides given and /// converting to the requested data format (unless format is /// TypeDesc::UNKNOWN, in which case pixels will be copied in the /// native data layout, including per-channel data formats). This /// is analogous to read_scanline except that it may be used to read /// more than one scanline at a time (which, for some formats, may /// be able to be done much more efficiently or in parallel). virtual bool read_scanlines (int ybegin, int yend, int z, TypeDesc format, void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride); /// Read multiple scanlines that include pixels (*,y,z) for all /// ybegin <= y < yend, into data, using the strides given and /// converting to the requested data format (unless format is /// TypeDesc::UNKNOWN, in which case pixels will be copied in the /// native data layout, including per-channel data formats). Only /// channels [chbegin,chend) will be read/copied (chbegin=0, /// chend=spec.nchannels reads all channels, yielding equivalent /// behavior to the simpler variant of read_scanlines). virtual bool read_scanlines (int ybegin, int yend, int z, int chbegin, int chend, TypeDesc format, void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride); /// Read the tile whose upper-left origin is (x,y,z) into data, /// converting if necessary from the native data format of the file /// into the 'format' specified. (z==0 for non-volume images.) The /// stride values give the data spacing of adjacent pixels, /// scanlines, and volumetric slices (measured in bytes). Strides /// set to AutoStride imply 'contiguous' data, i.e., /// xstride == spec.nchannels*format.size() /// ystride == xstride*spec.tile_width /// zstride == ystride*spec.tile_height /// If format is TypeDesc::UNKNOWN, then rather than converting to /// format, it will just copy pixels in the file's native data layout /// (including, possibly, per-channel data formats). /// The reader is expected to give the appearance of random access /// -- in other words, if it can't randomly seek to the given tile, /// it should transparently close, reopen, and sequentially read /// through prior tiles. The base ImageInput class has a default /// implementation that calls read_native_tile and then does /// appropriate format conversion, so there's no reason for each /// format plugin to override this method. virtual bool read_tile (int x, int y, int z, TypeDesc format, void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); /// /// Simple read_tile reads to contiguous float pixels. bool read_tile (int x, int y, int z, float *data) { return read_tile (x, y, z, TypeDesc::FLOAT, data, AutoStride, AutoStride, AutoStride); } /// Read the block of multiple tiles that include all pixels in /// [xbegin,xend) X [ybegin,yend) X [zbegin,zend), into data, using /// the strides given and converting to the requested data format /// (unless format is TypeDesc::UNKNOWN, in which case pixels will /// be copied in the native data layout, including per-channel data /// formats). This is analogous to read_tile except that it may be /// used to read more than one tile at a time (which, for some /// formats, may be able to be done much more efficiently or in /// parallel). The begin/end pairs must correctly delineate tile /// boundaries, with the exception that it may also be the end of /// the image data if the image resolution is not a whole multiple /// of the tile size. virtual bool read_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); /// Read the block of multiple tiles that include all pixels in /// [xbegin,xend) X [ybegin,yend) X [zbegin,zend), into data, using /// the strides given and converting to the requested data format /// (unless format is TypeDesc::UNKNOWN, in which case pixels will /// be copied in the native data layout, including per-channel data /// formats). Only channels [chbegin,chend) will be read/copied /// (chbegin=0, chend=spec.nchannels reads all channels, yielding /// equivalent behavior to the simpler variant of read_tiles). virtual bool read_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); /// Read the entire image of spec.width x spec.height x spec.depth /// pixels into data (which must already be sized large enough for /// the entire image) with the given strides and in the desired /// format. Read tiles or scanlines automatically. Strides set to /// AutoStride imply 'contiguous' data, i.e., /// xstride == spec.nchannels*format.size() /// ystride == xstride*spec.width /// zstride == ystride*spec.height /// If format is TypeDesc::UNKNOWN, then rather than converting to /// format, it will just copy pixels in the file's native data layout /// (including, possibly, per-channel data formats). /// Because this may be an expensive operation, a progress callback /// may be passed. Periodically, it will be called as follows: /// progress_callback (progress_callback_data, float done) /// where 'done' gives the portion of the image virtual bool read_image (TypeDesc format, void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride, ProgressCallback progress_callback=NULL, void *progress_callback_data=NULL); /// /// Simple read_image reads to contiguous float pixels. bool read_image (float *data) { return read_image (TypeDesc::FLOAT, data); } /// read_native_scanline is just like read_scanline, except that it /// keeps the data in the native format of the disk file and always /// reads into contiguous memory (no strides). It's up to the user to /// have enough space allocated and know what to do with the data. /// IT IS EXPECTED THAT EACH FORMAT PLUGIN WILL OVERRIDE THIS METHOD. virtual bool read_native_scanline (int y, int z, void *data) = 0; /// read_native_scanlines is just like read_scanlines, except that /// it keeps the data in the native format of the disk file and /// always reads into contiguous memory (no strides). It's up to /// the user to have enough space allocated and know what to do with /// the data. If a format reader subclass does not override this /// method, the default implementation it will simply be a loop /// calling read_native_scanline for each scanline. virtual bool read_native_scanlines (int ybegin, int yend, int z, void *data); /// A variant of read_native_scanlines that reads only channels /// [chbegin,chend). If a format reader subclass does /// not override this method, the default implementation will simply /// call the all-channel version of read_native_scanlines into a /// temporary buffer and copy the subset of channels. virtual bool read_native_scanlines (int ybegin, int yend, int z, int chbegin, int chend, void *data); /// read_native_tile is just like read_tile, except that it /// keeps the data in the native format of the disk file and always /// read into contiguous memory (no strides). It's up to the user to /// have enough space allocated and know what to do with the data. /// IT IS EXPECTED THAT EACH FORMAT PLUGIN WILL OVERRIDE THIS METHOD /// IF IT SUPPORTS TILED IMAGES. virtual bool read_native_tile (int x, int y, int z, void *data); /// read_native_tiles is just like read_tiles, except that it keeps /// the data in the native format of the disk file and always reads /// into contiguous memory (no strides). It's up to the caller to /// have enough space allocated and know what to do with the data. /// If a format reader does not override this method, the default /// implementation it will simply be a loop calling read_native_tile /// for each tile in the block. virtual bool read_native_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, void *data); /// A variant of read_native_tiles that reads only channels /// [chbegin,chend). If a format reader subclass does /// not override this method, the default implementation will simply /// call the all-channel version of read_native_tiles into a /// temporary buffer and copy the subset of channels. virtual bool read_native_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, void *data); /// Read native deep data from multiple scanlines that include /// pixels (*,y,z) for all ybegin <= y < yend, into deepdata. Only /// channels [chbegin, chend) will be read (chbegin=0, /// chend=spec.nchannels reads all channels). virtual bool read_native_deep_scanlines (int ybegin, int yend, int z, int chbegin, int chend, DeepData &deepdata); /// Read the block of multiple native deep data tiles that include /// all pixels in [xbegin,xend) X [ybegin,yend) X [zbegin,zend), /// into deepdata. Only channels [chbegin,chend) will /// be read (chbegin=0, chend=spec.nchannels reads all channels). virtual bool read_native_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, DeepData &deepdata); /// Read the entire deep data image of spec.width x spec.height x /// spec.depth pixels, all channels, into deepdata. virtual bool read_native_deep_image (DeepData &deepdata); /// General message passing between client and image input server /// virtual int send_to_input (const char *format, ...); int send_to_client (const char *format, ...); /// If any of the API routines returned false indicating an error, /// this routine will return the error string (and clear any error /// flags). If no error has occurred since the last time geterror() /// was called, it will return an empty string. std::string geterror () const { std::string e = m_errmessage; m_errmessage.clear (); return e; } /// An ImageInput::Creator is a function that creates and returns an /// ImageInput. Once invoked, the resulting ImageInput is owned by /// the caller, who is responsible for deleting it when done with it. typedef ImageInput* (*Creator)(); protected: /// Error reporting for the plugin implementation: call this with /// printf-like arguments. Note however that this is fully typesafe! // void error (const char *format, ...) const; TINYFORMAT_WRAP_FORMAT (void, error, const, std::ostringstream msg;, msg, append_error(msg.str());) protected: ImageSpec m_spec; // format spec of the current open subimage/MIPlevel private: mutable std::string m_errmessage; // private storage of error message void append_error (const std::string& message) const; // add to m_errmessage static ImageInput *create (const std::string &filename, bool do_open, const std::string &plugin_searchpath); }; /// ImageOutput abstracts the writing of an image file in a file /// format-agnostic manner. class OIIO_API ImageOutput { public: /// Create an ImageOutput that will write to a file, with the format /// inferred from the extension of the name. The plugin_searchpath /// parameter is a colon-separated list of directories to search for /// ImageIO plugin DSO/DLL's. This just creates the ImageOutput, it /// does not open the file. static ImageOutput *create (const std::string &filename, const std::string &plugin_searchpath=""); ImageOutput () { } virtual ~ImageOutput () { } /// Return the name of the format implemented by this class. /// virtual const char *format_name (void) const = 0; // Overrride these functions in your derived output class // to inform the client which formats are supported /// Given the name of a 'feature', return whether this ImageOutput /// supports output of images with the given properties. /// Feature names that ImageIO plugins are expected to recognize /// include: /// "tiles" Is this format able to write tiled images? /// "rectangles" Does this plugin accept arbitrary rectangular /// pixel regions, not necessarily aligned to /// scanlines or tiles? /// "random_access" May tiles or scanlines be written in /// any order (false indicates that they MUST /// be in successive order). /// "multiimage" Does this format support multiple subimages /// within a file? /// "appendsubimage" Does this format support adding subimages one at /// a time through open(name,spec,AppendSubimage)? /// If not, then open(name,subimages,specs) must /// be used instead. /// "mipmap" Does this format support multiple resolutions /// for an image/subimage? /// "volumes" Does this format support "3D" pixel arrays? /// "rewrite" May the same scanline or tile be sent more than /// once? (Generally, this will be true for /// plugins that implement interactive display.) /// "empty" Does this plugin support passing a NULL data /// pointer to write_scanline or write_tile to /// indicate that the entire data block is zero? /// "channelformats" Does the plugin/format support per-channel /// data formats? /// "displaywindow" Does the format support display ("full") windows /// distinct from the pixel data window? /// "origin" Does the format support a nonzero x,y,z /// origin of the pixel data window? /// "negativeorigin" Does the format support negative x,y,z /// and full_{x,y,z} origin values? /// "deepdata" Deep (multi-sample per pixel) data /// /// Note that main advantage of this approach, versus having /// separate individual supports_foo() methods, is that this allows /// future expansion of the set of possible queries without changing /// the API, adding new entry points, or breaking linkage /// compatibility. virtual bool supports (const std::string & /*feature*/) const { return false; } enum OpenMode { Create, AppendSubimage, AppendMIPLevel }; /// Open the file with given name, with resolution and other format /// data as given in newspec. Open returns true for success, false /// for failure. Note that it is legal to call open multiple times /// on the same file without a call to close(), if it supports /// multiimage and mode is AppendSubimage, or if it supports /// MIP-maps and mode is AppendMIPLevel -- this is interpreted as /// appending a subimage, or a MIP level to the current subimage, /// respectively. virtual bool open (const std::string &name, const ImageSpec &newspec, OpenMode mode=Create) = 0; /// Open the file with given name, expecting to have a given total /// number of subimages, described by specs[0..subimages-1]. /// Return true for success, false for failure. Upon success, the /// first subimage will be open and ready for transmission of /// pixels. Subsequent subimages will be denoted with the usual /// call of open(name,spec,AppendSubimage) (and MIP levels by /// open(name,spec,AppendMIPLevel)). /// /// The purpose of this call is to accommodate format-writing /// libraries that fmust know the number and specifications of the /// subimages upon first opening the file; such formats can be /// detected by /// supports("multiimage") && !supports("appendsubimage") /// The individual specs passed to the appending open() calls for /// subsequent subimages MUST match the ones originally passed. virtual bool open (const std::string &name, int subimages, const ImageSpec *specs) { // Default implementation: just a regular open, assume that // appending will work. return open (name, specs[0]); } /// Return a reference to the image format specification of the /// current subimage. Note that the contents of the spec are /// invalid before open() or after close(). const ImageSpec &spec (void) const { return m_spec; } /// Close an image that we are totally done with. This should leave /// the plugin in a state where it could open a new file safely, /// without having to destroy the writer. virtual bool close () = 0; /// Write a full scanline that includes pixels (*,y,z). (z is /// ignored for 2D non-volume images.) The stride value gives the /// distance between successive pixels (in bytes). Strides set to /// AutoStride imply 'contiguous' data, i.e., /// xstride == spec.nchannels*format.size() /// The data are automatically converted from 'format' to the actual /// output format (as specified to open()) by this method. /// If format is TypeDesc::UNKNOWN, then rather than converting from /// format, it will just copy pixels in the file's native data layout /// (including, possibly, per-channel data formats). /// Return true for success, false for failure. It is a failure to /// call write_scanline with an out-of-order scanline if this format /// driver does not support random access. virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride=AutoStride); /// Write multiple scanlines that include pixels (*,y,z) for all /// ybegin <= y < yend, from data. This is analogous to /// write_scanline except that it may be used to write more than one /// scanline at a time (which, for some formats, may be able to be /// done much more efficiently or in parallel). virtual bool write_scanlines (int ybegin, int yend, int z, TypeDesc format, const void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride); /// Write the tile with (x,y,z) as the upper left corner. (z is /// ignored for 2D non-volume images.) The three stride values give /// the distance (in bytes) between successive pixels, scanlines, /// and volumetric slices, respectively. Strides set to AutoStride /// imply 'contiguous' data, i.e., /// xstride == spec.nchannels*format.size() /// ystride == xstride*spec.tile_width /// zstride == ystride*spec.tile_height /// The data are automatically converted from 'format' to the actual /// output format (as specified to open()) by this method. /// If format is TypeDesc::UNKNOWN, then rather than converting from /// format, it will just copy pixels in the file's native data layout /// (including, possibly, per-channel data formats). /// Return true for success, false for failure. It is a failure to /// call write_tile with an out-of-order tile if this format driver /// does not support random access. virtual bool write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); /// Write the block of multiple tiles that include all pixels in /// [xbegin,xend) X [ybegin,yend) X [zbegin,zend). This is /// analogous to write_tile except that it may be used to write more /// than one tile at a time (which, for some formats, may be able to /// be done much more efficiently or in parallel). /// The begin/end pairs must correctly delineate tile boundaries, /// with the exception that it may also be the end of the image data /// if the image resolution is not a whole multiple of the tile size. virtual bool write_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, const void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); /// Write a rectangle of pixels given by the range /// [xbegin,xend) X [ybegin,yend) X [zbegin,zend) /// The three stride values give the distance (in bytes) between /// successive pixels, scanlines, and volumetric slices, /// respectively. Strides set to AutoStride imply 'contiguous' /// data, i.e., /// xstride == spec.nchannels*format.size() /// ystride == xstride * (xmax-xmin+1) /// zstride == ystride * (ymax-ymin+1) /// The data are automatically converted from 'format' to the actual /// output format (as specified to open()) by this method. If /// format is TypeDesc::UNKNOWN, it will just copy pixels assuming /// they are already in the file's native data layout (including, /// possibly, per-channel data formats). /// /// Return true for success, false for failure. It is a failure to /// call write_rectangle for a format plugin that does not return /// true for supports("rectangles"). virtual bool write_rectangle (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, const void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); /// Write the entire image of spec.width x spec.height x spec.depth /// pixels, with the given strides and in the desired format. /// Strides set to AutoStride imply 'contiguous' data, i.e., /// xstride == spec.nchannels*format.size() /// ystride == xstride*spec.width /// zstride == ystride*spec.height /// Depending on spec, write either all tiles or all scanlines. /// Assume that data points to a layout in row-major order. /// If format is TypeDesc::UNKNOWN, then rather than converting from /// format, it will just copy pixels in the file's native data layout /// (including, possibly, per-channel data formats). /// Because this may be an expensive operation, a progress callback /// may be passed. Periodically, it will be called as follows: /// progress_callback (progress_callback_data, float done) /// where 'done' gives the portion of the image virtual bool write_image (TypeDesc format, const void *data, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride, ProgressCallback progress_callback=NULL, void *progress_callback_data=NULL); /// Write deep scanlines containing pixels (*,y,z), for all y in /// [ybegin,yend), to a deep file. virtual bool write_deep_scanlines (int ybegin, int yend, int z, const DeepData &deepdata); /// Write the block of deep tiles that include all pixels in /// [xbegin,xend) X [ybegin,yend) X [zbegin,zend). /// The begin/end pairs must correctly delineate tile boundaries, /// with the exception that it may also be the end of the image data /// if the image resolution is not a whole multiple of the tile size. virtual bool write_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, const DeepData &deepdata); /// Write the entire deep image denoted by data. virtual bool write_deep_image (const DeepData &deepdata); /// Read the current subimage of 'in', and write it as the next /// subimage of *this, in a way that is efficient and does not alter /// pixel values, if at all possible. Both in and this must be a /// properly-opened ImageInput and ImageOutput, respectively, and /// their current images must match in size and number of channels. /// Return true if it works ok, false if for some reason the /// operation wasn't possible. /// /// If a particular ImageOutput implementation does not supply a /// copy_image method, it will inherit the default implementation, /// which is to simply read scanlines or tiles from 'in' and write /// them to *this. However, some ImageIO implementations may have a /// special technique for directly copying raw pixel data from the /// input to the output, when both input and output are the SAME /// file type and the same data format. This can be more efficient /// than in->read_image followed by out->write_image, and avoids any /// unintended pixel alterations, especially for formats that use /// lossy compression. virtual bool copy_image (ImageInput *in); /// General message passing between client and image output server /// virtual int send_to_output (const char *format, ...); int send_to_client (const char *format, ...); /// If any of the API routines returned false indicating an error, /// this routine will return the error string (and clear any error /// flags). If no error has occurred since the last time geterror() /// was called, it will return an empty string. std::string geterror () const { std::string e = m_errmessage; m_errmessage.clear (); return e; } /// An ImageOutput::Creator is a function that creates and returns an /// ImageOutput. Once invoked, the resulting ImageOutput is owned by /// the caller, who is responsible for deleting it when done with it. typedef ImageOutput* (*Creator)(); protected: /// Error reporting for the plugin implementation: call this with /// printf-like arguments. Note however that this is fully typesafe! /// void error (const char *format, ...) TINYFORMAT_WRAP_FORMAT (void, error, const, std::ostringstream msg;, msg, append_error(msg.str());) /// Helper routines used by write_* implementations: convert data (in /// the given format and stride) to the "native" format of the file /// (described by the 'spec' member variable), in contiguous order. /// This requires a scratch space to be passed in so that there are /// no memory leaks. Returns a pointer to the native data, which may /// be the original data if it was already in native format and /// contiguous, or it may point to the scratch space if it needed to /// make a copy or do conversions. const void *to_native_scanline (TypeDesc format, const void *data, stride_t xstride, std::vector &scratch); const void *to_native_tile (TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride, std::vector &scratch); const void *to_native_rectangle (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride, std::vector &scratch); protected: ImageSpec m_spec; ///< format spec of the currently open image private: void append_error (const std::string& message) const; // add to m_errmessage mutable std::string m_errmessage; ///< private storage of error message }; // Utility functions /// Retrieve the version of OpenImageIO for the library. This is so /// plugins can query to be sure they are linked against an adequate /// version of the library. OIIO_API int openimageio_version (); /// Special geterror() called after ImageInput::create or /// ImageOutput::create, since if create fails, there's no object on /// which call obj->geterror(). This function returns the last error /// for this particular thread; separate threads will not clobber each /// other's global error messages. OIIO_API std::string geterror (); /// Set a global attribute controlling OpenImageIO. Return true /// if the name and type were recognized and the attribute was set. /// /// Documented attributes: /// int threads /// How many threads to use for operations that can be sped /// by spawning threads (default=1; note that 0 means "as /// many threads as cores"). /// string plugin_searchpath /// Colon-separated list of directories to search for /// dynamically-loaded format plugins. /// string format_list (for 'getattribute' only, cannot set) /// Comma-separated list of all format names supported /// or for which plugins could be found. /// string extension_list (for 'getattribute' only, cannot set) /// For each format, the format name followed by a colon, /// followed by comma-separated list of all extensions that /// are presumed to be used for that format. Semicolons /// separate the lists for formats. For example, /// "tiff:tif;jpeg:jpg,jpeg;openexr:exr" OIIO_API bool attribute (const std::string &name, TypeDesc type, const void *val); // Shortcuts for common types inline bool attribute (const std::string &name, int val) { return attribute (name, TypeDesc::TypeInt, &val); } inline bool attribute (const std::string &name, float val) { return attribute (name, TypeDesc::TypeFloat, &val); } inline bool attribute (const std::string &name, const char *val) { return attribute (name, TypeDesc::TypeString, &val); } inline bool attribute (const std::string &name, const std::string &val) { const char *s = val.c_str(); return attribute (name, TypeDesc::TypeString, &s); } /// Get the named global attribute of OpenImageIO, store it in *val. /// Return true if found and it was compatible with the type specified, /// otherwise return false and do not modify the contents of *val. It /// is up to the caller to ensure that val points to the right kind and /// size of storage for the given type. OIIO_API bool getattribute (const std::string &name, TypeDesc type, void *val); // Shortcuts for common types inline bool getattribute (const std::string &name, int &val) { return getattribute (name, TypeDesc::TypeInt, &val); } inline bool getattribute (const std::string &name, float &val) { return getattribute (name, TypeDesc::TypeFloat, &val); } inline bool getattribute (const std::string &name, char **val) { return getattribute (name, TypeDesc::TypeString, val); } inline bool getattribute (const std::string &name, std::string &val) { const char *s = NULL; bool ok = getattribute (name, TypeDesc::TypeString, &s); if (ok) val = s ? s : ""; return ok; } /// Register the input and output 'create' routines and list of file /// extensions for a particular format. OIIO_API void declare_imageio_format (const std::string &format_name, ImageInput::Creator input_creator, const char **input_extensions, ImageOutput::Creator output_creator, const char **output_extensions); /// Helper routine: quantize a value to an integer given the /// quantization parameters. OIIO_API int quantize (float value, int quant_black, int quant_white, int quant_min, int quant_max); /// Helper function: convert contiguous arbitrary data between two /// arbitrary types (specified by TypeDesc's) /// Return true if ok, false if it didn't know how to do the /// conversion. If dst_type is UNKNWON, it will be assumed to be the /// same as src_type. OIIO_API bool convert_types (TypeDesc src_type, const void *src, TypeDesc dst_type, void *dst, int n); /// DEPRECATED -- for some reason we had a convert_types that took /// alpha_channel and z_channel parameters, but never did anything /// with them. OIIO_API bool convert_types (TypeDesc src_type, const void *src, TypeDesc dst_type, void *dst, int n, int alpha_channel, int z_channel = -1); /// Helper routine for data conversion: Convert an image of nchannels x /// width x height x depth from src to dst. The src and dst may have /// different data formats and layouts. Clever use of this function can /// not only exchange data among different formats (e.g., half to 8-bit /// unsigned), but also can copy selective channels, copy subimages, /// etc. If you're lazy, it's ok to pass AutoStride for any of the /// stride values, and they will be auto-computed assuming contiguous /// data. Return true if ok, false if it didn't know how to do the /// conversion. OIIO_API bool convert_image (int nchannels, int width, int height, int depth, const void *src, TypeDesc src_type, stride_t src_xstride, stride_t src_ystride, stride_t src_zstride, void *dst, TypeDesc dst_type, stride_t dst_xstride, stride_t dst_ystride, stride_t dst_zstride, int alpha_channel = -1, int z_channel = -1); /// A version of convert_image that will break up big jobs into multiple /// threads. OIIO_API bool parallel_convert_image ( int nchannels, int width, int height, int depth, const void *src, TypeDesc src_type, stride_t src_xstride, stride_t src_ystride, stride_t src_zstride, void *dst, TypeDesc dst_type, stride_t dst_xstride, stride_t dst_ystride, stride_t dst_zstride, int alpha_channel=-1, int z_channel=-1, int nthreads=0); /// Helper routine for data conversion: Copy an image of nchannels x /// width x height x depth from src to dst. The src and dst may have /// different data layouts, but must have the same data type. Clever /// use of this function can change layouts or strides, copy selective /// channels, copy subimages, etc. If you're lazy, it's ok to pass /// AutoStride for any of the stride values, and they will be /// auto-computed assuming contiguous data. Return true if ok, false if /// it didn't know how to do the conversion. OIIO_API bool copy_image (int nchannels, int width, int height, int depth, const void *src, stride_t pixelsize, stride_t src_xstride, stride_t src_ystride, stride_t src_zstride, void *dst, stride_t dst_xstride, stride_t dst_ystride, stride_t dst_zstride); /// Decode a raw Exif data block and save all the metadata in an /// ImageSpec. Return true if all is ok, false if the exif block was /// somehow malformed. The binary data pointed to by 'exif' should /// start with a TIFF directory header. OIIO_API bool decode_exif (const void *exif, int length, ImageSpec &spec); /// Construct an Exif data block from the ImageSpec, appending the Exif /// data as a big blob to the char vector. OIIO_API void encode_exif (const ImageSpec &spec, std::vector &blob); /// Add metadata to spec based on raw IPTC (International Press /// Telecommunications Council) metadata in the form of an IIM /// (Information Interchange Model). Return true if all is ok, false if /// the iptc block was somehow malformed. This is a utility function to /// make it easy for multiple format plugins to support embedding IPTC /// metadata without having to duplicate functionality within each /// plugin. Note that IIM is actually considered obsolete and is /// replaced by an XML scheme called XMP. OIIO_API bool decode_iptc_iim (const void *iptc, int length, ImageSpec &spec); /// Find all the IPTC-amenable metadata in spec and assemble it into an /// IIM data block in iptc. This is a utility function to make it easy /// for multiple format plugins to support embedding IPTC metadata /// without having to duplicate functionality within each plugin. Note /// that IIM is actually considered obsolete and is replaced by an XML /// scheme called XMP. OIIO_API void encode_iptc_iim (const ImageSpec &spec, std::vector &iptc); /// Add metadata to spec based on XMP data in an XML block. Return true /// if all is ok, false if the xml was somehow malformed. This is a /// utility function to make it easy for multiple format plugins to /// support embedding XMP metadata without having to duplicate /// functionality within each plugin. OIIO_API bool decode_xmp (const std::string &xml, ImageSpec &spec); /// Find all the relavant metadata (IPTC, Exif, etc.) in spec and /// assemble it into an XMP XML string. This is a utility function to /// make it easy for multiple format plugins to support embedding XMP /// metadata without having to duplicate functionality within each /// plugin. If 'minimal' is true, then don't encode things that would /// be part of ordinary TIFF or exif tags. OIIO_API std::string encode_xmp (const ImageSpec &spec, bool minimal=false); // All the wrap_foo functions implement a wrap mode, wherein coord is // altered to be origin <= coord < origin+width. The return value // indicates if the resulting wrapped value is valid (example, for // wrap_black, values outside the region are invalid and do not modify // the coord parameter). OIIO_API bool wrap_black (int &coord, int origin, int width); OIIO_API bool wrap_clamp (int &coord, int origin, int width); OIIO_API bool wrap_periodic (int &coord, int origin, int width); OIIO_API bool wrap_periodic_pow2 (int &coord, int origin, int width); OIIO_API bool wrap_mirror (int &coord, int origin, int width); // Typedef for the function signature of a wrap implementation. typedef bool (*wrap_impl) (int &coord, int origin, int width); // to force correct linkage on some systems OIIO_API void _ImageIO_force_link (); } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_IMAGEIO_H openimageio-1.3.12~dfsg0.orig/src/include/varyingref.h0000644000175000017500000002143112271062644021061 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// @file varyingref.h /// @Brief Define the VaryingRef class. #ifndef OPENIMAGEIO_VARYINGREF_H #define OPENIMAGEIO_VARYINGREF_H #include "version.h" OIIO_NAMESPACE_ENTER { /// VaryingRef is a templated class (on class T) that holds either a /// pointer to a single T value, or an "array" of T values, each /// separated by a certain number of bytes. For those versed in the /// lingo of SIMD shading, this encapsulates 'uniform' and 'varying' /// references. /// /// Suppose you have a computation 'kernel' that is performing an /// operation while looping over several computation 'points.' Each of /// the several operands of the kernel may either be a 'uniform' value /// (identical for each point), or 'varying' (having a potentially /// different value for each point). /// /// Here is a concrete example. Suppose you have the following function: /// \code /// void add (int n, float *a, float *b, float *result) { /// for (int i = 0; i < n; ++i) /// result[i] = a[i] + b[i]; /// } /// \endcode /// /// But if the caller of this function has only a single b value (let's /// say, you always want to add 3 to every a[i]), you would be forced /// to replicate an entire array full of 3's in order to call the function. /// /// Instead, we may wish to generalize the function so that each operand /// may rever to EITHER a single value or an array of values, without /// making the code more complicated. We can do this with VaryingRef: /// \code /// void add (int n, VaryingRef a, VaryingRef b, /// float *result) { /// for (int i = 0; i < n; ++i) /// result[i] = a[i] + b[i]; /// } /// \endcode /// /// VaryingRef overloads operator [] to properly decode whether it is /// uniform (point to the one value) or varying (index the right array /// element). It also overloads the increment operator ++ and the pointer /// indirection operator '*', so you could also write the function /// equivalently as: /// \code /// void add (int n, VaryingRef a, VaryingRef b, /// float *result) { /// for (int i = 0; i < n; ++i, ++a, ++b) // note increments /// result[i] = (*a) + (*b); /// } /// \endcode /// /// An example of calling this function would be: /// \code /// float a[n]; /// float b; // just 1 value /// float result[n]; /// add (n, VaryingRef(a,sizeof(a[0])), /// VaryingRef(b), result); /// \endcode /// /// In this example, we're passing a truly varying 'a' (signified by /// giving a step size from element to element), but a uniform 'b' (signified /// by no step size, or a step size of zero). /// /// There are Varying() and Uniform() templated functions that provide /// a helpful shorthand: /// \code /// add (n, Varying(a), Uniform(b), result); /// \endcode /// /// Now let's take it a step further and fully optimize the 'add' function /// for when both operands are uniform: /// \code /// void add (int n, VaryingRef a, VaryingRef b, /// VaryingRef result) { /// if (a.is_uniform() && b.is_uniform()) { /// float r = (*a) + (*b); /// for (int i = 0; i < n; ++i) /// result[i] = r; /// } else { /// // One or both are varying /// for (int i = 0; i < n; ++i, ++a, ++b) /// result[i] = (*a) + (*b); /// } /// } /// \endcode /// This is the basis for handling uniform and varying values efficiently /// inside a SIMD shading system. template class VaryingRef { public: VaryingRef () { init (0, 0); } /// Construct a VaryingRef either of a single value pointed to by ptr /// (if step == 0 or no step is provided), or of a varying set of /// values beginning with ptr and with successive values every 'step' /// bytes. VaryingRef (void *ptr_, int step_=0) { init ((T *)ptr_,step_); } /// Construct a uniform VaryingRef from a single value. /// VaryingRef (T &ptr_) { init (&ptr_, 0); } /// Initialize this VaryingRef to either of a single value pointed /// to by ptr (if step == 0 or no step is provided), or of a varying /// set of values beginning with ptr and with successive values /// every 'step' bytes. void init (T *ptr_, int step_=0) { m_ptr = ptr_; m_step = step_; } /// Initialize this VaryingRef to be uniform and point to a particular /// value reference. const VaryingRef & operator= (T &ptr_) { init (&ptr_); return *this; } /// Is this reference pointing nowhere? /// bool is_null () const { return (m_ptr == 0); } /// Cast to void* returns the pointer, but the real purpose is so /// you can use a VaryingRef as if it were a 'bool' value in a test. operator void*() const { return m_ptr; } /// Is this VaryingRef referring to a varying value, signified by /// having a nonzero step size between elements? bool is_varying () const { return (m_step != 0); } /// Is this VaryingRef referring to a uniform value, signified by /// having a step size of zero between elements? bool is_uniform () const { return (m_step == 0); } /// Pre-increment: If this VaryingRef is varying, increment its /// pointer to the next element in the series, but don't change /// anything if it's uniform. In either case, return a reference to /// its new state. VaryingRef & operator++ () { // Prefix form ++i char *p = (char *)m_ptr; p += m_step; m_ptr = (T *) p; return *this; } /// Post-increment: If this VaryingRef is varying, increment its /// pointer to the next element in the series, but don't change /// anything if it's uniform. No value is returned, so it's not /// legal to do 'bar = foo++' if foo and bar are VaryingRef's. void operator++ (int) { // Postfix form i++ : return nothing to avoid copy // VaryingRef tmp = *this; char *p = (char *)m_ptr; p += m_step; m_ptr = (T *) p; // return tmp; } /// Pointer indirection will return the first value currently /// pointed to by this VaryingRef. T & operator* () const { return *m_ptr; } /// Array indexing operator will return a reference to the single /// element if *this is uniform, or to the i-th element of the /// series if *this is varying. T & operator[] (int i) const { return *(T *) ((char *)m_ptr + i*m_step); } /// Return the raw pointer underneath. /// T * ptr () const { return m_ptr; } /// Return the raw step underneath. /// int step () const { return m_step; } private: T *m_ptr; ///< Pointer to value int m_step; ///< Distance between successive values -- in BYTES! }; /// Helper function wraps a varying reference with default step size. /// template VaryingRef Varying (T *x) { return VaryingRef (x, sizeof(T)); } /// Helper function wraps a uniform reference. /// template VaryingRef Uniform (T *x) { return VaryingRef (x, 0); } /// Helper function wraps a uniform reference. /// template VaryingRef Uniform (T &x) { return VaryingRef (&x, 0); } } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_VARYINGREF_H openimageio-1.3.12~dfsg0.orig/src/include/osdep.h0000644000175000017500000000342412271062644020021 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_OSDEP_H #define OPENIMAGEIO_OSDEP_H #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # define VC_EXTRALEAN # define NOMINMAX # include #endif #endif // OPENIMAGEIO_OSDEP_H openimageio-1.3.12~dfsg0.orig/src/include/filesystem.h0000644000175000017500000002253512271062644021077 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// @file filesystem.h /// /// @brief Utilities for dealing with file names and files. We use /// boost::filesystem anywhere we can, but that doesn't cover everything /// we want to do. /// /// Some helpful nomenclature: /// - "filename" - a file or directory name, relative or absolute /// - "searchpath" - a list of directories separated by ':' or ';'. /// #ifndef OPENIMAGEIO_FILESYSTEM_H #define OPENIMAGEIO_FILESYSTEM_H #include #include #include #include #include #include "export.h" #include "version.h" OIIO_NAMESPACE_ENTER { /// @namespace Filesystem /// /// @brief Platform-independent utilities for manipulating file names, /// files, directories, and other file system miscellany. namespace Filesystem { /// Return the filename (excluding any directories, but including the /// file extension, if any) of a filepath. OIIO_API std::string filename (const std::string &filepath); /// Return the file extension (including the last '.' if /// include_dot=true) of a filename or filepath. OIIO_API std::string extension (const std::string &filepath, bool include_dot=true); /// DEPRECATED. inline std::string file_extension (const std::string &filepath) { return extension (filepath, false); } /// Return all but the last part of the path, for example, /// parent_path("foo/bar") returns "foo", and parent_path("foo") /// returns "". OIIO_API std::string parent_path (const std::string &filepath); /// Replace the file extension of a filename or filepath. Does not alter /// filepath, just returns a new string. Note that the new_extension /// should contain a leading '.' dot. OIIO_API std::string replace_extension (const std::string &filepath, const std::string &new_extension); /// Turn a searchpath (multiple directory paths separated by ':' or ';') /// into a vector containing each individual directory. If /// validonly is true, only existing and readable directories will end /// up in the list. N.B., the directory names will not have trailing /// slashes. OIIO_API void searchpath_split (const std::string &searchpath, std::vector &dirs, bool validonly = false); /// Find the first instance of a filename existing in a vector of /// directories, returning the full path as a string. If the file is /// not found in any of the listed directories, return an empty string. /// If the filename is absolute, the directory list will not be used. /// If testcwd is true, "." will be tested before the searchpath; /// otherwise, "." will only be tested if it's explicitly in dirs. If /// recursive is true, the directories will be searched recursively, /// finding a matching file in any subdirectory of the directories /// listed in dirs; otherwise. OIIO_API std::string searchpath_find (const std::string &filename, const std::vector &dirs, bool testcwd = true, bool recursive = false); /// Fill a vector-of-strings with the names of all files contained by /// directory dirname. If recursive is true, it will return all files /// below the directory (even in subdirectories), but if recursive is /// false (the default)If filter_regex is supplied and non-empty, only /// filenames matching the regular expression will be returned. Return /// true if ok, false if there was an error (such as dirname not being /// found or not actually being a directory). OIIO_API bool get_directory_entries (const std::string &dirname, std::vector &filenames, bool recursive = false, const std::string &filter_regex=std::string()); /// Return true if the path is an "absolute" (not relative) path. /// If 'dot_is_absolute' is true, consider "./foo" absolute. OIIO_API bool path_is_absolute (const std::string &path, bool dot_is_absolute=false); /// Return true if the file exists. /// OIIO_API bool exists (const std::string &path); /// Return true if the file exists and is a directory. /// OIIO_API bool is_directory (const std::string &path); /// Return true if the file exists and is a regular file. /// OIIO_API bool is_regular (const std::string &path); /// Version of fopen that can handle UTF-8 paths even on Windows /// OIIO_API FILE *fopen (const std::string &path, const std::string &mode); /// Version of std::ifstream.open that can handle UTF-8 paths /// OIIO_API void open (std::ifstream &stream, const std::string &path, std::ios_base::openmode mode = std::ios_base::in); /// Version of std::ofstream.open that can handle UTF-8 paths /// OIIO_API void open (std::ofstream &stream, const std::string &path, std::ios_base::openmode mode = std::ios_base::out); /// Get last modified time of file /// OIIO_API std::time_t last_write_time (const std::string& path); /// Set last modified time on file /// OIIO_API void last_write_time (const std::string& path, std::time_t time); /// Ensure command line arguments are UTF-8 everywhere /// OIIO_API void convert_native_arguments (int argc, const char *argv[]); /// Turn a sequence description string into a vector of integers. /// The sequence description can be any of the following /// * A value (e.g., "3") /// * A value range ("1-10", "10-1", "1-10x3", "1-10y3"): /// START-FINISH A range, inclusive of start & finish /// START-FINISHxSTEP A range with step size /// START-FINISHySTEP The complement of a stepped range, that is, /// all numbers within the range that would /// NOT have been selected by 'x'. /// Note that START may be > FINISH, or STEP may be negative. /// * Multiple values or ranges, separated by a comma (e.g., "3,4,10-20x2") /// Retrn true upon success, false if the description was too malformed /// to generate a sequence. OIIO_API bool enumerate_sequence (const char *desc, std::vector &numbers); /// Given a pattern (such as "foo.#.tif" or "bar.1-10#.exr"), return a /// normalized pattern in printf format (such as "foo.%04d.tif") and a /// framespec (such as "1-10"). /// /// If framepadding_override is > 0, it overrides any specific padding amount /// in the original pattern. /// /// Return true upon success, false if the description was too malformed /// to generate a sequence. OIIO_API bool parse_pattern (const char *pattern, int framepadding_override, std::string &normalized_pattern, std::string &framespec); /// Given a normalized pattern (such as "foo.%04d.tif") and a list of frame /// numbers, generate a list of filenames. /// /// Return true upon success, false if the description was too malformed /// to generate a sequence. OIIO_API bool enumerate_file_sequence (const std::string &pattern, const std::vector &numbers, std::vector &filenames); /// Given a normalized pattern (such as "/path/to/foo.%04d.tif") scan the /// containing directory (/path/to) for matching frame numbers and files. /// /// Return true upon success, false if the directory doesn't exist or the /// pattern can't be parsed. OIIO_API bool scan_for_matching_filenames (const std::string &pattern, std::vector &numbers, std::vector &filenames); }; // namespace Filesystem } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_FILESYSTEM_H openimageio-1.3.12~dfsg0.orig/src/include/filter.h0000644000175000017500000001273212271062644020176 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_FILTER_H #define OPENIMAGEIO_FILTER_H #include "version.h" #include "export.h" OIIO_NAMESPACE_ENTER { /// Quick structure that describes a filter. /// class OIIO_API FilterDesc { public: const char *name; ///< name of the filter int dim; ///< dimensionality: 1 or 2 float width; ///< Recommended width or window bool fixedwidth; ///< Is the width the only one that makes sense? bool scalable; ///< Is it scalable (otherwise, the width is a window)? bool separable; ///< Is it separable? (only matters if dim==2) }; /// Filter1D is the abstract data type for a 1D filter. /// The filters are NOT expected to have their results normalized. class OIIO_API Filter1D { public: Filter1D (float width) : m_w(width) { } virtual ~Filter1D (void) { }; /// Get the width of the filter float width (void) const { return m_w; } /// Evalutate the filter at an x position (relative to filter center) virtual float operator() (float x) const = 0; /// Return the name of the filter, e.g., "box", "gaussian" virtual const std::string name (void) const = 0; /// This static function allocates and returns an instance of the /// specific filter implementation for the name you provide. /// Example use: /// Filter1D *myfilt = Filter1::create ("box", 1); /// The caller is responsible for deleting it when it's done. /// If the name is not recognized, return NULL. static Filter1D *create (const std::string &filtername, float width); /// Destroy a filter that was created with create(). static void destroy (Filter1D *filt); /// Get the number of filters supported. static int num_filters (); /// Get the info for a particular index (0..num_filters()-1). static void get_filterdesc (int filternum, FilterDesc *filterdesc); protected: float m_w; }; /// Filter2D is the abstract data type for a 2D filter. /// The filters are NOT expected to have their results normalized. class OIIO_API Filter2D { public: Filter2D (float width, float height) : m_w(width), m_h(height) { } virtual ~Filter2D (void) { }; /// Get the width of the filter float width (void) const { return m_w; } /// Get the height of the filter float height (void) const { return m_h; } /// Is the filter separable? /// virtual bool separable () const { return false; } /// Evalutate the filter at an x and y position (relative to filter /// center). virtual float operator() (float x, float y) const = 0; /// Evaluate just the horizontal filter (if separable; for non-separable /// it just evaluates at (x,0). virtual float xfilt (float x) const { return (*this)(x,0.0f); } /// Evaluate just the vertical filter (if separable; for non-separable /// it just evaluates at (0,y). virtual float yfilt (float y) const { return (*this)(0.0f,y); } /// Return the name of the filter, e.g., "box", "gaussian" virtual const std::string name (void) const = 0; /// This static function allocates and returns an instance of the /// specific filter implementation for the name you provide. /// Example use: /// Filter2D *myfilt = Filter2::create ("box", 1, 1); /// The caller is responsible for deleting it when it's done. /// If the name is not recognized, return NULL. static Filter2D *create (const std::string &filtername, float width, float height); /// Destroy a filter that was created with create(). static void destroy (Filter2D *filt); /// Get the number of filters supported. static int num_filters (); /// Get the info for a particular index (0..num_filters()-1). static void get_filterdesc (int filternum, FilterDesc *filterdesc); protected: float m_w, m_h; }; } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_FILTER_H openimageio-1.3.12~dfsg0.orig/src/include/string_ref.h0000644000175000017500000002544112271062644021054 0ustar mfvmfv/* Copyright 2014 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #pragma once #include #include #include #include #include #include "version.h" #include "export.h" OIIO_NAMESPACE_ENTER { /// Provides a string_ref class that is a non-owning reference to a string /// or substring. class string_ref { public: typedef char charT; typedef charT value_type; typedef const charT* pointer; typedef const charT* const_pointer; typedef const charT& reference; typedef const charT& const_reference; typedef const_pointer const_iterator; typedef const_iterator iterator; typedef std::reverse_iterator const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef std::char_traits traits; static const size_type npos = ~size_type(0); /// Default ctr string_ref () { init(NULL,0); } /// Copy ctr string_ref (const string_ref ©) { init (copy.m_chars, copy.m_len); } /// Construct from char* and length. string_ref (const charT *chars, size_t len) { init (chars, len); } /// Construct from char*, use strlen to determine length. string_ref (const charT *chars) { init (chars, chars ? strlen(chars) : 0); } /// Construct from std::string. string_ref (const std::string &str) { init (str.data(), str.size()); } std::string str() const { return (m_chars ? std::string(m_chars,m_len) : std::string()); } /// Explicitly request a 0-terminated string. USUALLY, this turns out to /// be just data(), with no significant added expense. But in the more /// rare case that the string_ref represetns a non-0-terminated /// substring, it will force an allocation and copy underneath. const char * c_str() const; // assignments string_ref& operator= (const string_ref ©) { init (copy.data(), copy.length()); return *this; } operator std::string() const { return str(); } // iterators const_iterator begin() const { return m_chars; } const_iterator end() const { return m_chars + m_len; } const_iterator cbegin() const { return m_chars; } const_iterator cend() const { return m_chars + m_len; } const_reverse_iterator rbegin() const { return const_reverse_iterator (end()); } const_reverse_iterator rend() const { return const_reverse_iterator (begin()); } const_reverse_iterator crbegin() const { return const_reverse_iterator (end()); } const_reverse_iterator crend() const { return const_reverse_iterator (begin()); } // capacity size_type size() const { return m_len; } size_type length() const { return m_len; } size_type max_size() const { return m_len; } bool empty() const { return m_len == 0; } // element access const charT& operator[] (size_type pos) const { return m_chars[pos]; } const charT& at (size_t pos) const { if (pos >= m_len) throw (std::out_of_range ("OpenImageIO::string_ref::at")); return m_chars[pos]; } const charT& front() const { return m_chars[0]; } const charT& back() const { return m_chars[m_len-1]; } const charT* data() const { return m_chars; } // modifiers void clear() { init(NULL,0); } void remove_prefix(size_type n) { if (n > m_len) n = m_len; m_chars += n; m_len -= n; } void remove_suffix(size_type n) { if (n > m_len) n = m_len; m_len -= n; } string_ref substr (size_type pos, size_type n=npos) const { if (pos > size()) throw (std::out_of_range ("OIIO::string_ref::substr")); if (n == npos || pos + n > size()) n = size() - pos; return string_ref (data() + pos, n); } int compare (string_ref x) const { const int cmp = std::char_traits::compare (m_chars, x.m_chars, (std::min)(m_len, x.m_len)); return cmp != 0 ? cmp : int(m_len - x.m_len); // Equivalent to: // cmp != 0 ? cmp : (m_len == x.m_len ? 0 : (m_len < x.m_len ? -1 : 1)); } #if 0 // Do these later if anybody needs them bool starts_with(string_ref x) const; bool ends_with(string_ref x) const; #endif /// Find the first occurrence of substring s in *this, starting at /// position pos. size_type find (string_ref s, size_t pos=0) const { if (pos > size()) pos = size(); const_iterator i = std::search (this->cbegin()+pos, this->cend(), s.cbegin(), s.cend(), traits::eq); return i == this->cend() ? npos : std::distance (this->cbegin(), i); } /// Find the first occurrence of character c in *this, starting at /// position pos. size_type find (charT c, size_t pos=0) const { if (pos > size()) pos = size(); const_iterator i = std::find_if (this->cbegin()+pos, this->cend(), traits_eq(c)); return i == this->cend() ? npos : std::distance (this->cbegin(), i); } /// Find the last occurrence of substring s *this, but only those /// occurrences earlier than position pos. size_type rfind (string_ref s, size_t pos=npos) const { if (pos > size()) pos = size(); const_reverse_iterator b = this->crbegin()+(size()-pos); const_reverse_iterator e = this->crend(); const_reverse_iterator i = std::search (b, e, s.crbegin(), s.crend(), traits::eq); return i == e ? npos : (reverse_distance(this->crbegin(),i) - s.size() + 1); } /// Find the last occurrence of character c in *this, but only those /// occurrences earlier than position pos. size_type rfind (charT c, size_t pos=npos) const { if (pos > size()) pos = size(); const_reverse_iterator b = this->crbegin()+(size()-pos); const_reverse_iterator e = this->crend(); const_reverse_iterator i = std::find_if (b, e, traits_eq(c)); return i == e ? npos : reverse_distance (this->crbegin(),i); } size_type find_first_of (charT c, size_t pos=0) const { return find (c, pos); } size_type find_last_of (charT c, size_t pos=npos) const { return rfind (c, pos); } size_type find_first_of (string_ref s) const { const_iterator i = std::find_first_of (this->cbegin(), this->cend(), s.cbegin(), s.cend(), traits::eq); return i == this->cend() ? npos : std::distance (this->cbegin(), i); } size_type find_last_of (string_ref s) const { const_reverse_iterator i = std::find_first_of (this->crbegin(), this->crend(), s.cbegin(), s.cend(), traits::eq); return i == this->crend() ? npos : reverse_distance (this->crbegin(), i); } size_type find_first_not_of (string_ref s) const { const_iterator i = find_not_of (this->cbegin(), this->cend(), s); return i == this->cend() ? npos : std::distance (this->cbegin(), i); } size_type find_first_not_of (charT c) const { for (const_iterator i = this->cbegin(); i != this->cend(); ++i) if (! traits::eq (c, *i)) return std::distance (this->cbegin(), i); return npos; } size_type find_last_not_of (string_ref s) const { const_reverse_iterator i = find_not_of (this->crbegin(), this->crend(), s); return i == this->crend() ? npos : reverse_distance (this->crbegin(), i); } size_type find_last_not_of (charT c) const { for (const_reverse_iterator i = this->crbegin(); i != this->crend(); ++i) if (! traits::eq (c, *i)) return reverse_distance (this->crbegin(), i); return npos; } private: const charT * m_chars; size_t m_len; void init (const charT *chars, size_t len) { m_chars = chars; m_len = len; } template size_type reverse_distance (r_iter first, r_iter last) const { return m_len - 1 - std::distance (first, last); } template iter find_not_of (iter first, iter last, string_ref s) const { for ( ; first != last ; ++first) if (! traits::find (s.data(), s.length(), *first)) return first; return last; } class traits_eq { public: traits_eq (charT ch) : ch(ch) {} bool operator () (charT val) const { return traits::eq (ch, val); } charT ch; }; }; inline bool operator== (string_ref x, string_ref y) { return x.size() == y.size() ? (x.compare (y) == 0) : false; } inline bool operator!= (string_ref x, string_ref y) { return x.size() == y.size() ? (x.compare (y) != 0) : true; } inline bool operator< (string_ref x, string_ref y) { return x.compare(y) < 0; } inline bool operator> (string_ref x, string_ref y) { return x.compare(y) > 0; } inline bool operator<= (string_ref x, string_ref y) { return x.compare(y) <= 0; } inline bool operator>= (string_ref x, string_ref y) { return x.compare(y) >= 0; } // Inserter inline std::ostream& operator<< (std::ostream& out, const string_ref& str) { if (out.good()) out.write (str.data(), str.size()); return out; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/include/fmath.h0000644000175000017500000010055712271062644020013 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) A few bits here are based upon code from NVIDIA that was also released under the same modified BSD license, and marked as: Copyright 2004 NVIDIA Corporation. All Rights Reserved. */ /// \file /// /// A variety of floating-point math helper routines (and, slight /// misnomer, some int stuff as well). /// #ifndef OPENIMAGEIO_FMATH_H #define OPENIMAGEIO_FMATH_H #include #include #include #include #if defined(_MSC_VER) && _MSC_VER < 1600 typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; # ifndef _UINT64_T typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; # define _UINT32_T # define _UINT64_T # endif #else # include #endif #if defined(__FreeBSD__) #include #endif #include "version.h" OIIO_NAMESPACE_ENTER { #ifndef M_PI /// PI /// # define M_PI 3.1415926535897932 #endif #ifndef M_PI_2 /// PI / 2 /// # define M_PI_2 1.5707963267948966 #endif #ifndef M_TWO_PI /// PI * 2 /// # define M_TWO_PI (M_PI * 2.0) #endif #ifndef M_1_PI /// 1/PI /// # define M_1_PI 0.318309886183790671538 #endif #ifndef M_2_PI /// 2/PI /// # define M_2_PI 0.63661977236758134 #endif #ifndef M_SQRT2 /// sqrt(2) /// # define M_SQRT2 1.414135623730950 #endif #ifndef M_SQRT1_2 /// 1/sqrt(2) /// # define M_SQRT1_2 0.7071067811865475 #endif #ifndef M_LN2 /// ln(2) /// # define M_LN2 0.6931471805599453 #endif #ifndef M_LN10 /// ln(10) /// # define M_LN10 2.3025850929940457 #endif // Some stuff we know easily if we're running on an Intel chip #if (defined(_WIN32) || defined(__i386__) || defined(__x86_64__)) # define USE_INTEL_MATH_SHORTCUTS 1 # ifndef __LITTLE_ENDIAN__ # define __LITTLE_ENDIAN__ 1 # undef __BIG_ENDIAN__ # endif #endif /// Large constant that we use to indicate a really large float /// #define HUGE_FLOAT ((float)1.0e38) /// Test a float for whether it's huge. To account for awful fp roundoff, /// consider it large if within a factor of 2 of HUGE_FLOAT. inline bool huge (float f) { return (f >= HUGE_FLOAT/2); } /// Special value we can use for an uninitialized float. /// #define UNINITIALIZED_FLOAT (- std::numeric_limits::max()) /// Quick test for whether an integer is a power of 2. /// inline bool ispow2 (int x) { // Numerous references for this bit trick are on the web. The // principle is that x is a power of 2 <=> x == 1< x-1 is // all 1 bits for bits < b. return (x & (x-1)) == 0 && (x >= 0); } /// Quick test for whether an unsigned integer is a power of 2. /// inline bool ispow2 (unsigned int x) { // Numerous references for this bit trick are on the web. The // principle is that x is a power of 2 <=> x == 1< x-1 is // all 1 bits for bits < b. return (x & (x-1)) == 0; } /// Round up to next higher power of 2 (return x if it's already a power /// of 2). inline int pow2roundup (int x) { // Here's a version with no loops. if (x < 0) return 0; // Subtract 1, then round up to a power of 2, that way if we are // already a power of 2, we end up with the same number. --x; // Make all bits past the first 1 also be 1, i.e. 0001xxxx -> 00011111 x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; // Now we have 2^n-1, by adding 1, we make it a power of 2 again return x+1; } /// Round down to next lower power of 2 (return x if it's already a power /// of 2). inline int pow2rounddown (int x) { // Make all bits past the first 1 also be 1, i.e. 0001xxxx -> 00011111 x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; // Strip off all but the high bit, i.e. 00011111 -> 00010000 // That's the power of two <= the original x return x & ~(x >> 1); } /// Round up to the next even multiple of m. /// inline int round_to_multiple (int x, int m) { return ((x + m - 1) / m) * m; } /// Return true if the architecture we are running on is little endian /// inline bool littleendian (void) { #if defined(__BIG_ENDIAN__) return false; #elif defined(__LITTLE_ENDIAN__) return true; #else // Otherwise, do something quick to compute it int i = 1; return *((char *) &i); #endif } /// Return true if the architecture we are running on is big endian /// inline bool bigendian (void) { return ! littleendian(); } /// Change endian-ness of one or more data items that are each 2, 4, /// or 8 bytes. This should work for any of short, unsigned short, int, /// unsigned int, float, long long, pointers. template inline void swap_endian (T *f, int len=1) { for (char *c = (char *) f; len--; c += sizeof(T)) { if (sizeof(T) == 2) { std::swap (c[0], c[1]); } else if (sizeof(T) == 4) { std::swap (c[0], c[3]); std::swap (c[1], c[2]); } else if (sizeof(T) == 8) { std::swap (c[0], c[7]); std::swap (c[1], c[6]); std::swap (c[2], c[5]); std::swap (c[3], c[4]); } } } /// Fast table-based conversion of 8-bit to other types. Declare this /// as static to avoid the expensive ctr being called all the time. template class EightBitConverter { public: EightBitConverter () { init(); } T operator() (unsigned char c) const { return val[c]; } private: T val[256]; void init () { float scale = 1.0f / 255.0f; if (std::numeric_limits::is_integer) scale *= (float)std::numeric_limits::max(); for (int i = 0; i < 256; ++i) val[i] = (T)(i * scale); } }; /// clamp a to bounds [l,h]. /// template inline T clamp (T a, T l, T h) { return (a < l)? l : ((a > h)? h : a); } /// Multiply two unsigned 32-bit ints safely, carefully checking for /// overflow, and clamping to uint32_t's maximum value. inline uint32_t clamped_mult32 (uint32_t a, uint32_t b) { const uint32_t Err = std::numeric_limits::max(); uint64_t r = (uint64_t)a * (uint64_t)b; // Multiply into a bigger int return r < Err ? (uint32_t)r : Err; } /// Multiply two unsigned 64-bit ints safely, carefully checking for /// overflow, and clamping to uint64_t's maximum value. inline uint64_t clamped_mult64 (uint64_t a, uint64_t b) { uint64_t ab = a*b; if (b && ab/b != a) return std::numeric_limits::max(); else return ab; } // Helper template to let us tell if two types are the same. template struct is_same { static const bool value = false; }; template struct is_same { static const bool value = true; }; /// Multiply src by scale, clamp to [min,max], and round to the nearest D /// (presumed to be integer). This is just a helper for the convert_type /// templates, it probably has no other use. template D scaled_conversion (const S &src, F scale, F min, F max) { if (std::numeric_limits::is_signed) { F s = src * scale; s += (s < 0 ? (F)-0.5 : (F)0.5); return (D) clamp (s, min, max); } else { return (D) clamp ((F)src * scale + (F)0.5, min, max); } } /// Convert n consecutive values from the type of S to the type of D. /// The conversion is not a simple cast, but correctly remaps the /// 0.0->1.0 range from and to the full positive range of integral /// types. Take a memcpy shortcut if both types are the same and no /// conversion is necessary. Optional arguments can give nonstandard /// quantizations. // // FIXME: make table-based specializations for common types with only a // few possible src values (like unsigned char -> float). template void convert_type (const S *src, D *dst, size_t n, D _zero=0, D _one=1, D _min=std::numeric_limits::min(), D _max=std::numeric_limits::max()) { if (is_same::value) { // They must be the same type. Just memcpy. memcpy (dst, src, n*sizeof(D)); return; } typedef double F; F scale = std::numeric_limits::is_integer ? ((F)1.0)/std::numeric_limits::max() : (F)1.0; if (std::numeric_limits::is_integer) { // Converting to an integer-like type. F min = (F)_min; // std::numeric_limits::min(); F max = (F)_max; // std::numeric_limits::max(); scale *= _max; // Unroll loop for speed for ( ; n >= 16; n -= 16) { *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); *dst++ = scaled_conversion (*src++, scale, min, max); } while (n--) *dst++ = scaled_conversion (*src++, scale, min, max); } else { // Converting to a float-like type, so we don't need to remap // the range // Unroll loop for speed for ( ; n >= 16; n -= 16) { *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); *dst++ = (D)((*src++) * scale); } while (n--) *dst++ = (D)((*src++) * scale); } } /// Convert a single value from the type of S to the type of D. /// The conversion is not a simple cast, but correctly remaps the /// 0.0->1.0 range from and to the full positive range of integral /// types. Take a copy shortcut if both types are the same and no /// conversion is necessary. template D convert_type (const S &src) { if (is_same::value) { // They must be the same type. Just return it. return (D)src; } typedef double F; F scale = std::numeric_limits::is_integer ? ((F)1.0)/std::numeric_limits::max() : (F)1.0; if (std::numeric_limits::is_integer) { // Converting to an integer-like type. typedef double F; F min = (F) std::numeric_limits::min(); F max = (F) std::numeric_limits::max(); scale *= max; return scaled_conversion (src, scale, min, max); } else { // Converting to a float-like type, so we don't need to remap // the range return (D)((F)src * scale); } } /// Helper function to convert channel values between different bit depths. /// Roughly equivalent to: /// /// out = round (in * (pow (2, TO_BITS) - 1) / (pow (2, FROM_BITS) - 1)); /// /// but utilizes an integer math trick for speed. It can be proven that the /// absolute error of this method is less or equal to 1, with an average error /// (with respect to the entire domain) below 0.2. /// /// It is assumed that the original value is a valid FROM_BITS integer, i.e. /// shifted fully to the right. template inline unsigned int bit_range_convert(unsigned int in) { unsigned int out = 0; int shift = TO_BITS - FROM_BITS; for (; shift > 0; shift -= FROM_BITS) out |= in << shift; out |= in >> -shift; return out; } // non-templated version. Slow but general inline unsigned int bit_range_convert(unsigned int in, unsigned int FROM_BITS, unsigned int TO_BITS) { unsigned int out = 0; int shift = TO_BITS - FROM_BITS; for (; shift > 0; shift -= FROM_BITS) out |= in << shift; out |= in >> -shift; return out; } /// A DataProxy looks like an (E &), but it really holds an (I &) /// and does conversions (via convert_type) as it reads in and out. /// (I and E are for INTERNAL and EXTERNAL data types, respectively). template struct DataProxy { DataProxy (I &data) : m_data(data) { } E operator= (E newval) { m_data = convert_type(newval); return newval; } operator E () const { return convert_type(m_data); } private: DataProxy& operator = (const DataProxy&); // Do not implement I &m_data; }; /// A ConstDataProxy looks like a (const E &), but it really holds /// a (const I &) and does conversions (via convert_type) as it reads. /// (I and E are for INTERNAL and EXTERNAL data types, respectively). template struct ConstDataProxy { ConstDataProxy (const I &data) : m_data(data) { } operator E () const { return convert_type(*m_data); } private: const I &m_data; }; /// A DataArrayProxy looks like an (E *), but it really holds an (I *) /// and does conversions (via convert_type) as it reads in and out. /// (I and E are for INTERNAL and EXTERNAL data types, respectively). template struct DataArrayProxy { DataArrayProxy (I *data=NULL) : m_data(data) { } E operator* () const { return convert_type(*m_data); } E operator[] (int i) const { return convert_type(m_data[i]); } DataProxy operator[] (int i) { return DataProxy (m_data[i]); } void set (I *data) { m_data = data; } I * get () const { return m_data; } const DataArrayProxy & operator+= (int i) { m_data += i; return *this; } private: I *m_data; }; /// A ConstDataArrayProxy looks like an (E *), but it really holds an /// (I *) and does conversions (via convert_type) as it reads in and out. /// (I and E are for INTERNAL and EXTERNAL data types, respectively). template struct ConstDataArrayProxy { ConstDataArrayProxy (const I *data=NULL) : m_data(data) { } E operator* () const { return convert_type(*m_data); } E operator[] (int i) const { return convert_type(m_data[i]); } void set (const I *data) { m_data = data; } const I * get () const { return m_data; } const ConstDataArrayProxy & operator+= (int i) { m_data += i; return *this; } private: const I *m_data; }; /// Linearly interpolate values v0-v1 at x: v0*(1-x) + v1*x. /// This is a template, and so should work for any types. template inline T lerp (T v0, T v1, Q x) { // NOTE: a*(1-x) + b*x is much more numerically stable than a+x*(b-a) return v0*(Q(1)-x) + v1*x; } /// Bilinearly interoplate values v0-v3 (v0 upper left, v1 upper right, /// v2 lower left, v3 lower right) at coordinates (s,t) and return the /// result. This is a template, and so should work for any types. template inline T bilerp (T v0, T v1, T v2, T v3, Q s, Q t) { // NOTE: a*(t-1) + b*t is much more numerically stable than a+t*(b-a) Q s1 = (Q)1 - s; return (T) (((Q)1-t)*(v0*s1 + v1*s) + t*(v2*s1 + v3*s)); } /// Bilinearly interoplate arrays of values v0-v3 (v0 upper left, v1 /// upper right, v2 lower left, v3 lower right) at coordinates (s,t), /// storing the results in 'result'. These are all vectors, so do it /// for each of 'n' contiguous values (using the same s,t interpolants). template inline void bilerp (const T *v0, const T *v1, const T *v2, const T *v3, Q s, Q t, int n, T *result) { Q s1 = (Q)1 - s; Q t1 = (Q)1 - t; for (int i = 0; i < n; ++i) result[i] = (T) (t1*(v0[i]*s1 + v1[i]*s) + t*(v2[i]*s1 + v3[i]*s)); } /// Bilinearly interoplate arrays of values v0-v3 (v0 upper left, v1 /// upper right, v2 lower left, v3 lower right) at coordinates (s,t), /// SCALING the interpolated value by 'scale' and then ADDING to /// 'result'. These are all vectors, so do it for each of 'n' /// contiguous values (using the same s,t interpolants). template inline void bilerp_mad (const T *v0, const T *v1, const T *v2, const T *v3, Q s, Q t, Q scale, int n, T *result) { Q s1 = (Q)1 - s; Q t1 = (Q)1 - t; for (int i = 0; i < n; ++i) result[i] += (T) (scale * (t1*(v0[i]*s1 + v1[i]*s) + t*(v2[i]*s1 + v3[i]*s))); } /// Trilinearly interoplate arrays of values v0-v7 (v0 upper left top, v1 /// upper right top, ...) at coordinates (s,t,r), and return the /// result. This is a template, and so should work for any types. template inline T trilerp (T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, Q s, Q t, Q r) { // NOTE: a*(t-1) + b*t is much more numerically stable than a+t*(b-a) Q s1 = (Q)1 - s; Q t1 = (Q)1 - t; Q r1 = (Q)1 - r; return (T) (r1*(t1*(v0*s1 + v1*s) + t*(v2*s1 + v3*s)) + r*(t1*(v4*s1 + v5*s) + t*(v6*s1 + v7*s))); } /// Trilinearly interoplate arrays of values v0-v7 (v0 upper left top, v1 /// upper right top, ...) at coordinates (s,t,r), /// storing the results in 'result'. These are all vectors, so do it /// for each of 'n' contiguous values (using the same s,t,r interpolants). template inline void trilerp (const T *v0, const T *v1, const T *v2, const T *v3, const T *v4, const T *v5, const T *v6, const T *v7, Q s, Q t, Q r, int n, T *result) { Q s1 = (Q)1 - s; Q t1 = (Q)1 - t; Q r1 = (Q)1 - r; for (int i = 0; i < n; ++i) result[i] = (T) (r1*(t1*(v0[i]*s1 + v1[i]*s) + t*(v2[i]*s1 + v3[i]*s)) + r*(t1*(v4[i]*s1 + v5[i]*s) + t*(v6[i]*s1 + v7[i]*s))); } /// Trilinearly interoplate arrays of values v0-v7 (v0 upper left top, v1 /// upper right top, ...) at coordinates (s,t,r), /// SCALING the interpolated value by 'scale' and then ADDING to /// 'result'. These are all vectors, so do it for each of 'n' /// contiguous values (using the same s,t,r interpolants). template inline void trilerp_mad (const T *v0, const T *v1, const T *v2, const T *v3, const T *v4, const T *v5, const T *v6, const T *v7, Q s, Q t, Q r, Q scale, int n, T *result) { Q r1 = (Q)1 - r; bilerp_mad (v0, v1, v2, v3, s, t, scale*r1, n, result); bilerp_mad (v4, v5, v6, v7, s, t, scale*r, n, result); } /// Fast rounding to nearest integer. /// See Michael Herf's "Know Your FPU" page: /// http://www.stereopsis.com/sree/fpu2006.html inline int RoundToInt (double val) { #ifdef USE_INTEL_MATH_SHORTCUTS union { int i; double d; } myunion; myunion.d = val; const double doublemagic = double (6755399441055744.0); // 2^52 * 1.5, uses limited precisicion to floor myunion.d += doublemagic; return myunion.i; #else return round (val); #endif } inline int RoundToInt (float val) { #ifdef USE_INTEL_MATH_SHORTCUTS return RoundToInt (double(val)); #else return roundf (val); #endif } /// Fast (int)floor(val) /// See Michael Herf's "Know Your FPU" page: /// http://www.stereopsis.com/sree/fpu2006.html inline int FloorToInt (double val) { #ifdef USE_INTEL_MATH_SHORTCUTS const double doublemagicdelta = (1.5e-8); // almost .5f = .5f + 1e^(number of exp bit) const double doublemagicroundeps = (0.5f-doublemagicdelta); // almost .5f = .5f - 1e^(number of exp bit) return RoundToInt (val - doublemagicroundeps); #else return (int) floor (val); #endif } inline int FloorToInt (float val) { #ifdef USE_INTEL_MATH_SHORTCUTS return FloorToInt (double(val)); #else return (int) floorf (val); #endif } /// Fast (int)ceil(val) /// See Michael Herf's "Know Your FPU" page: /// http://www.stereopsis.com/sree/fpu2006.html inline int CeilToInt (double val) { #ifdef USE_INTEL_MATH_SHORTCUTS const double doublemagicdelta = (1.5e-8); // almost .5f = .5f + 1e^(number of exp bit) const double doublemagicroundeps = (0.5f-doublemagicdelta); // almost .5f = .5f - 1e^(number of exp bit) return RoundToInt (val + doublemagicroundeps); #else return (int) ceil (val); #endif } inline int CeilToInt (float val) { #ifdef USE_INTEL_MATH_SHORTCUTS return CeilToInt (double(val)); #else return (int) ceilf (val); #endif } /// Fast (int)val /// See Michael Herf's "Know Your FPU" page: /// http://www.stereopsis.com/sree/fpu2006.html inline int FloatToInt (double val) { #ifdef USE_INTEL_MATH_SHORTCUTS return (val<0) ? CeilToInt(val) : FloorToInt(val); #else return (int) val; #endif } inline int FloatToInt (float val) { #ifdef USE_INTEL_MATH_SHORTCUTS return FloatToInt (double(val)); #else return (int) val; #endif } /// Return (x-floor(x)) and put (int)floor(x) in *xint. This is similar /// to the built-in modf, but returns a true int, always rounds down /// (compared to modf which rounds toward 0), and always returns /// frac >= 0 (comapred to modf which can return <0 if x<0). inline float floorfrac (float x, int *xint) { // Find the greatest whole number <= x. This cast is faster than // calling floorf. #if 1 int i = (int) x - (x < 0.0f ? 1 : 0); #else // Why isn't this faster than the cast? int i = FloorToInt (x); #endif *xint = i; return x - static_cast(i); // Return the fraction left over } /// Convert degrees to radians. /// inline float radians (float deg) { return deg * (float)(M_PI / 180.0); } /// Convert radians to degrees /// inline float degrees (float rad) { return rad * (float)(180.0 / M_PI); } /// Fast float exp inline float fast_expf(float x) { #if defined(__x86_64__) && defined(__GNU_LIBRARY__) && defined(__GLIBC__ ) && defined(__GLIBC_MINOR__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 16 // On x86_64, versions of glibc < 2.16 have an issue where expf is // much slower than the double version. This was fixed in glibc 2.16. return static_cast(std::exp(static_cast(x))); #else return std::exp(x); #endif } #ifdef _WIN32 // Windows doesn't define these functions from math.h #define hypotf _hypotf #define copysign(x,y) _copysign(x,y) #define copysignf(x,y) copysign(x,y) #ifdef _MSC_VER #define isnan(x) _isnan(x) #define isfinite(x) _finite(x) #endif #define M_E 2.71828182845904523536 #define M_LOG2E 1.44269504088896340736 //#define M_LOG10E 0.434294481903251827651 //#define M_LN2 0.693147180559945309417 //#define M_LN10 2.30258509299404568402 //#define M_PI 3.14159265358979323846 //#define M_PI_2 1.57079632679489661923 #define M_PI_4 0.785398163397448309616 //#define M_1_PI 0.318309886183790671538 //#define M_2_PI 0.636619772367581343076 //#define M_2_SQRTPI 1.12837916709551257390 //#define M_SQRT2 1.41421356237309504880 //#define M_SQRT1_2 0.707106781186547524401 inline double round (float val) { return floor (val + 0.5); } inline float roundf (float val) { return static_cast(round (val)); } #ifdef _MSC_VER template inline int isinf (T x) { return (isfinite(x)||isnan(x)) ? 0 : static_cast(copysign(T(1.0), x)); } #endif inline float log2f (float val) { return logf (val)/static_cast(M_LN2); } inline float logbf(float val) { // please see http://www.kernel.org/doc/man-pages/online/pages/man3/logb.3.html return logf(val)/logf(FLT_RADIX); } inline float exp2f(float val) { // 2^val = e^(val*ln(2)) return exp( val*log(2.0f) ); } // from http://www.johndcook.com/cpp_expm1.html inline double expm1(double val) { // exp(x) - 1 without loss of precision for small values of x. if (fabs(val) < 1e-5) return val + 0.5*val*val; else return exp(val) - 1.0; } inline float expm1f(float val) { return (float)expm1(val); } // from http://www.johndcook.com/cpp_erf.html inline double erf(double x) { // constants double a1 = 0.254829592; double a2 = -0.284496736; double a3 = 1.421413741; double a4 = -1.453152027; double a5 = 1.061405429; double p = 0.3275911; // Save the sign of x int sign = 1; if (x < 0) sign = -1; x = fabs(x); // A&S formula 7.1.26 double t = 1.0/(1.0 + p*x); double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x); return sign*y; } inline float erff(float val) { return (float)erf(val); } inline double erfc(double val) { return 1.0 - erf(val); } inline float erfcf(float val) { return (float)erfc(val); } inline float truncf(float val) { return (float)(int)val; } using OIIO::roundf; using OIIO::truncf; using OIIO::expm1f; using OIIO::erff; using OIIO::erfcf; using OIIO::log2f; using OIIO::logbf; using OIIO::exp2f; #endif /* _WIN32 */ // Some systems have isnan, isinf and isfinite in the std namespace. #ifndef _MSC_VER using std::isnan; using std::isinf; using std::isfinite; #endif // Functions missing from FreeBSD #if (defined(__FreeBSD__) && (__FreeBSD_version < 803000)) inline float log2f (float val) { return logf (val)/static_cast(M_LN2); } using OIIO::log2f; #endif /// Simple conversion of a (presumably non-negative) float into a /// rational. This does not attempt to find the simplest fraction /// that approximates the float, for example 52.83 will simply /// return 5283/100. This does not attempt to gracefully handle /// floats that are out of range that could be easily int/int. inline void float_to_rational (float f, unsigned int &num, unsigned int &den) { if (f <= 0) { // Trivial case of zero, and handle all negative values num = 0; den = 1; } else if ((int)(1.0/f) == (1.0/f)) { // Exact results for perfect inverses num = 1; den = (int)f; } else { num = (int)f; den = 1; while (fabsf(f-static_cast(num)) > 0.00001f && den < 1000000) { den *= 10; f *= 10; num = (int)f; } } } /// Simple conversion of a float into a rational. This does not attempt /// to find the simplest fraction that approximates the float, for /// example 52.83 will simply return 5283/100. This does not attempt to /// gracefully handle floats that are out of range that could be easily /// int/int. inline void float_to_rational (float f, int &num, int &den) { unsigned int n, d; float_to_rational (fabsf(f), n, d); num = (f >= 0) ? (int)n : -(int)n; den = (int) d; } inline void sincos(float x, float* sine, float* cosine) { #if defined(__GNUC__) && defined(__linux__) && !defined(__clang__) __builtin_sincosf(x, sine, cosine); #else *sine = std::sin(x); *cosine = std::cos(x); #endif } inline void sincos(double x, double* sine, double* cosine) { #if defined(__GNUC__) && defined(__linux__) && !defined(__clang__) __builtin_sincos(x, sine, cosine); #else *sine = std::sin(x); *cosine = std::cos(x); #endif } /// Safe (clamping) arcsine. /// inline float safe_asinf (float x) { if (x >= 1.0f) return static_cast(M_PI)/2; if (x <= -1.0f) return -static_cast(M_PI)/2; return std::asin (x); } /// Safe (clamping) arccosine. /// inline float safe_acosf (float x) { if (x >= 1.0f) return 0.0f; if (x <= -1.0f) return static_cast(M_PI); return std::acos (x); } /// Safe (clamping) sqrt. /// inline double safe_sqrt (double x) { return (x > 0.0) ? sqrt(x) : 0.0; } inline float safe_sqrtf (float x) { return (x > 0.0f) ? sqrtf(x) : 0.0f; } /// Safe (clamping) inverse sqrt inline float safe_inversesqrt (float x) { return (x > 0.0f) ? 1.0f/std::sqrt(x) : 0.0f; } inline float safe_log (float x) { return (x > 0.0f) ? logf(x) : -std::numeric_limits::max(); } inline float safe_log2(float x) { return (x > 0.0f) ? log2f(x) : -std::numeric_limits::max(); } inline float safe_log10(float x) { return (x > 0.0f) ? log10f(x) : -std::numeric_limits::max(); } inline float safe_logb (float x) { return (x != 0.0f) ? logbf(x) : -std::numeric_limits::max(); } /// Solve for the x for which func(x) == y on the interval [xmin,xmax]. /// Use a maximum of maxiter iterations, and stop any time the remaining /// search interval or the function evaluations <= eps. If brack is /// non-NULL, set it to true if y is in [f(xmin), f(xmax)], otherwise /// false (in which case the caller should know that the results may be /// unreliable. Results are undefined if the function is not monotonic /// on that interval or if there are multiple roots in the interval (it /// may not converge, or may converge to any of the roots without /// telling you that there are more than one). template T invert (Func &func, T y, T xmin=0.0, T xmax=1.0, int maxiters=32, T eps=1.0e-6, bool *brack=0) { // Use the Regula Falsi method, falling back to bisection if it // hasn't converged after 3/4 of the maximum number of iterations. // See, e.g., Numerical Recipes for the basic ideas behind both // methods. T v0 = func(xmin), v1 = func(xmax); T x = xmin, v = v0; bool increasing = (v0 < v1); T vmin = increasing ? v0 : v1; T vmax = increasing ? v1 : v0; bool bracketed = (y >= vmin && y <= vmax); if (brack) *brack = bracketed; if (! bracketed) { // If our bounds don't bracket the zero, just give up, and // return the approprate "edge" of the interval return ((y < vmin) == increasing) ? xmin : xmax; } if (fabs(v0-v1) < eps) // already close enough return x; int rfiters = (3*maxiters)/4; // how many times to try regula falsi for (int iters = 0; iters < maxiters; ++iters) { T t; // interpolation factor if (iters < rfiters) { // Regula falsi t = (y-v0)/(v1-v0); if (t <= T(0) || t >= T(1)) t = T(0.5); // RF convergence failure -- bisect instead } else { t = T(0.5); // bisection } x = lerp (xmin, xmax, t); v = func(x); if ((v < y) == increasing) { xmin = x; v0 = v; } else { xmax = x; v1 = v; } if (fabs(xmax-xmin) < eps || fabs(v-y) < eps) return x; // converged } return x; } } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_FMATH_H openimageio-1.3.12~dfsg0.orig/src/include/color.h0000644000175000017500000002415512271062644020031 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_COLOR_H #define OPENIMAGEIO_COLOR_H #include "export.h" #include "version.h" OIIO_NAMESPACE_ENTER { /// The ColorProcessor encapsulates a baked color transformation, suitable for /// application to raw pixels, or ImageBuf(s). These are generated using /// ColorConfig::createColorProcessor, and referenced in ImageBufAlgo /// (amongst other places) class OIIO_API ColorProcessor; /// Represents the set of all color transformations that are allowed. /// If OpenColorIO is enabled at build time, this configuration is loaded /// at runtime, allowing the user to have complete control of all color /// transformation math. ($OCIO) (See opencolorio.org for details). /// If OpenColorIO is not enabled at build time, a generic color configuration /// is provided for minimal color support. /// /// NOTE: ColorConfig(s) and ColorProcessor(s) are potentially heavy-weight. /// Their construction / destruction should be kept to a minimum. class OIIO_API ColorConfig { public: /// If OpenColorIO is enabled at build time, initialize with the current /// color configuration. ($OCIO) /// If OpenColorIO is not enabled, this does nothing. /// /// Multiple calls to this are inexpensive. ColorConfig(); /// If OpenColorIO is enabled at build time, initialize with the /// specified color configuration (.ocio) file /// If OpenColorIO is not enabled, this will result in an error. /// /// Multiple calls to this are potentially expensive. ColorConfig(const char * filename); ~ColorConfig(); /// Has an error string occurred? /// (This will not affect the error state.) bool error () const; /// This routine will return the error string (and clear any error /// flags). If no error has occurred since the last time geterror() /// was called, it will return an empty string. std::string geterror (); /// Get the number of ColorSpace(s) defined in this configuration int getNumColorSpaces() const; /// Query the name of the specified ColorSpace. const char * getColorSpaceNameByIndex(int index) const; /// Get the name of the color space representing the named role, /// or NULL if none could be identified. const char * getColorSpaceNameByRole (const char *role) const; /// Get the number of Looks defined in this configuration int getNumLooks() const; /// Query the name of the specified Look. const char * getLookNameByIndex(int index) const; /// Given the specified input and output ColorSpace, construct the /// processor. It is possible that this will return NULL, if the /// inputColorSpace doesnt exist, the outputColorSpace doesn't /// exist, or if the specified transformation is illegal (for /// example, it may require the inversion of a 3D-LUT, etc). When /// the user is finished with a ColorProcess, deleteColorProcessor /// should be called. ColorProcessor(s) remain valid even if the /// ColorConfig that created them no longer exists. /// /// Multiple calls to this are potentially expensive, so you should /// call once to create a ColorProcessor to use on an entire image /// (or multiple images), NOT for every scanline or pixel /// separately! ColorProcessor* createColorProcessor(const char * inputColorSpace, const char * outputColorSpace) const; /// Given the named look(s), input and output color spaces, /// construct a color processor that applies an OCIO look /// transformation. If inverse==true, construct the inverse /// transformation. The context_key and context_value can /// optionally be used to establish an extra token/value pair in the /// OCIO context. /// /// It is possible that this will return NULL, if one of the color /// spaces or the look itself doesnt exist or is not allowed. When /// the user is finished with a ColorProcess, deleteColorProcessor /// should be called. ColorProcessor(s) remain valid even if the /// ColorConfig that created them no longer exists. /// /// Multiple calls to this are potentially expensive, so you should /// call once to create a ColorProcessor to use on an entire image /// (or multiple images), NOT for every scanline or pixel /// separately! ColorProcessor* createLookTransform (const char * looks, const char * inputColorSpace, const char * outputColorSpace, bool inverse=false, const char *context_key=NULL, const char *context_value=NULL) const; /// Get the number of displays defined in this configuration int getNumDisplays() const; /// Query the name of the specified display. const char * getDisplayNameByIndex(int index) const; /// Get the number of views for a given display defined in this configuration int getNumViews(const char * display) const; /// Query the name of the specified view for the specified display const char * getViewNameByIndex(const char * display, int index) const; /// Query the name of the default display const char * getDefaultDisplayName() const; /// Query the name of the default view for the specified display const char * getDefaultViewName(const char * display) const; /// Construct a processor to transform from the given color space /// to the color space of the given display and view. You may optionally /// override the looks that are, by default, used with the display/view /// combination. Looks is a potentially comma (or colon) delimited list /// of lookNames, where +/- prefixes are optionally allowed to denote /// forward/inverse transformation (and forward is assumed in the /// absence of either). It is possible to remove all looks from the /// display by passing an empty string. The context_key and context_value /// can optionally be used to establish an extra token/value pair in the /// OCIO context. /// /// It is possible that this will return NULL, if one of the color /// spaces or the display or view doesn't exist or is not allowed. When /// the user is finished with a ColorProcess, deleteColorProcessor /// should be called. ColorProcessor(s) remain valid even if the /// ColorConfig that created them no longer exists. /// /// Multiple calls to this are potentially expensive, so you should /// call once to create a ColorProcessor to use on an entire image /// (or multiple images), NOT for every scanline or pixel /// separately! ColorProcessor* createDisplayTransform (const char * display, const char * view, const char * inputColorSpace, const char * looks=NULL, const char * context_key=NULL, const char * context_value=NULL) const; /// Delete the specified ColorProcessor static void deleteColorProcessor(ColorProcessor * processor); /// Return if OpenImageIO was built with OCIO support static bool supportsOpenColorIO(); private: ColorConfig(const ColorConfig &); ColorConfig& operator= (const ColorConfig &); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; /// Utility -- convert sRGB value to linear /// http://en.wikipedia.org/wiki/SRGB inline float sRGB_to_linear (float x) { return (x <= 0.04045f) ? (x / 12.92f) : powf ((x + 0.055f) / 1.055f, 2.4f); } /// Utility -- convert linear value to sRGB inline float linear_to_sRGB (float x) { if (x < 0.0f) return 0.0f; return (x <= 0.0031308f) ? (12.92f * x) : (1.055f * powf (x, 1.f/2.4f) - 0.055f); } /// Utility -- convert Rec709 value to linear /// http://en.wikipedia.org/wiki/Rec._709 inline float Rec709_to_linear (float x) { if (x < 0.081f) return (x < 0.0f) ? 0.0f : x * (1.0f/4.5f); else return powf ((x + 0.099f) * (1.0f/1.099f), (1.0f/0.45f)); } /// Utility -- convert linear value to Rec709 inline float linear_to_Rec709 (float x) { if (x < 0.018f) return (x < 0.0f)? 0.0f : x * 4.5f; else return 1.099f * powf(x, 0.45f) - 0.099f; } } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_COLOR_H openimageio-1.3.12~dfsg0.orig/src/include/paramlist.h0000644000175000017500000001761412271062644020711 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// /// Define the ParamValue and ParamValueList classes, which are used to /// store lists of arbitrary name/data pairs for internal storage of /// parameter lists, attributes, geometric primitive data, etc. #ifndef OPENIMAGEIO_PARAMLIST_H #define OPENIMAGEIO_PARAMLIST_H #if defined(_MSC_VER) // Ignore warnings about DLL exported classes with member variables that are template classes. // This happens with the Rep m_vals member variable of ParamValueList below, which is a std::vector. # pragma warning (disable : 4251) #endif #include #include "export.h" #include "typedesc.h" #include "ustring.h" OIIO_NAMESPACE_ENTER { /// ParamValue holds a parameter and a pointer to its value(s) /// /// Nomenclature: if you have an array of 4 colors for each of 15 points... /// - There are 15 VALUES /// - Each value has an array of 4 ELEMENTS, ecah of which is a color /// - A color has 3 COMPONENTS (R, G, B) /// class OIIO_API ParamValue { public: /// Interpolation types /// enum Interp { INTERP_CONSTANT = 0, ///< Constant for all pieces/faces INTERP_PERPIECE = 1, ///< Piecewise constant per piece/face INTERP_LINEAR = 2, ///< Linearly interpolated across each piece/face INTERP_VERTEX = 3 ///< Interpolated like vertices }; ParamValue () : m_type(TypeDesc::UNKNOWN), m_nvalues(0), m_interp(INTERP_CONSTANT), m_copy(false), m_nonlocal(false) { m_data.ptr = NULL; } ParamValue (const ustring &_name, TypeDesc _type, int _nvalues, const void *_value, bool _copy=true) { init_noclear (_name, _type, _nvalues, _value, _copy); } ParamValue (const std::string &_name, TypeDesc _type, int _nvalues, const void *_value, bool _copy=true) { init_noclear (ustring(_name.c_str()), _type, _nvalues, _value, _copy); } ParamValue (const char *_name, TypeDesc _type, int _nvalues, const void *_value, bool _copy=true) { init_noclear (ustring(_name), _type, _nvalues, _value, _copy); } ParamValue (const ParamValue &p, bool _copy=true) { init_noclear (p.name(), p.type(), p.nvalues(), p.data(), _copy); } ~ParamValue () { clear_value(); } void init (ustring _name, TypeDesc _type, int _nvalues, const void *_value, bool _copy=true) { clear_value (); init_noclear (_name, _type, _nvalues, _value, _copy); } void init (std::string _name, TypeDesc _type, int _nvalues, const void *_value, bool _copy=true) { init (ustring(_name), _type, _nvalues, _value, _copy); } const ParamValue& operator= (const ParamValue &p) { init (p.name(), p.type(), p.nvalues(), p.data(), p.m_copy); return *this; } const ustring &name () const { return m_name; } TypeDesc type () const { return m_type; } int nvalues () const { return m_nvalues; } const void *data () const { return m_nonlocal ? m_data.ptr : &m_data; } int datasize () const { return m_nvalues * static_cast(m_type.size()); } Interp interp () const { return (Interp)m_interp; } void interp (Interp i) { m_interp = (unsigned char )i; } friend void swap (ParamValue &a, ParamValue &b) { std::swap (a.m_name, b.m_name); std::swap (a.m_type, b.m_type); std::swap (a.m_nvalues, b.m_nvalues); std::swap (a.m_data.ptr, b.m_data.ptr); std::swap (a.m_copy, b.m_copy); std::swap (a.m_nonlocal, b.m_nonlocal); } private: ustring m_name; ///< data name TypeDesc m_type; ///< data type, which may itself be an array int m_nvalues; ///< number of values of the given type unsigned char m_interp; ///< Interpolation type bool m_copy, m_nonlocal; union { ptrdiff_t localval; const void *ptr; } m_data; ///< Our data, either a pointer or small local value void init_noclear (ustring _name, TypeDesc _type, int _nvalues, const void *_value, bool _copy=true); void clear_value(); }; /// A list of ParamValue entries, that can be iterated over or searched. /// class OIIO_API ParamValueList { typedef std::vector Rep; public: ParamValueList () { } typedef Rep::iterator iterator; typedef Rep::const_iterator const_iterator; typedef ParamValue value_type; typedef value_type & reference; typedef const value_type & const_reference; typedef value_type * pointer; typedef const value_type * const_pointer; iterator begin () { return m_vals.begin(); } iterator end () { return m_vals.end(); } const_iterator begin () const { return m_vals.begin(); } const_iterator end () const { return m_vals.end(); } reference front () { return m_vals.front(); } reference back () { return m_vals.back(); } const_reference front () const { return m_vals.front(); } const_reference back () const { return m_vals.back(); } reference operator[] (int i) { return m_vals[i]; } const_reference operator[] (int i) const { return m_vals[i]; } reference operator[] (size_t i) { return m_vals[i]; } const_reference operator[] (size_t i) const { return m_vals[i]; } void resize (size_t newsize) { m_vals.resize (newsize); } size_t size () const { return m_vals.size(); } /// Add space for one more ParamValue to the list, and return a /// reference to its slot. reference grow () { resize (size()+1); return back (); } /// Add a ParamValue to the end of the list. /// void push_back (const ParamValue &p) { m_vals.push_back (p); } /// Removes from the ParamValueList container a single element. /// iterator erase (iterator position) { return m_vals.erase (position); } /// Removes from the ParamValueList container a range of elements ([first,last)). /// iterator erase (iterator first, iterator last) { return m_vals.erase (first, last); } /// Remove all the values in the list. /// void clear () { m_vals.clear(); } /// Even more radical than clear, free ALL memory associated with the /// list itself. void free () { Rep tmp; std::swap (m_vals, tmp); } private: Rep m_vals; }; } OIIO_NAMESPACE_EXIT #endif /* !defined(OPENIMAGEIO_PARAMLIST_H) */ openimageio-1.3.12~dfsg0.orig/src/include/tinyformat.h0000644000175000017500000012607712271062644021115 0ustar mfvmfv// tinyformat.h // Copyright (C) 2011, Chris Foster [chris42f (at) gmail (d0t) com] // // Boost Software License - Version 1.0 // // Permission is hereby granted, free of charge, to any person or organization // obtaining a copy of the software and accompanying documentation covered by // this license (the "Software") to use, reproduce, display, distribute, // execute, and transmit the Software, and to prepare derivative works of the // Software, and to permit third-parties to whom the Software is furnished to // do so, all subject to the following: // // The copyright notices in the Software and this entire statement, including // the above license grant, this restriction and the following disclaimer, // must be included in all copies of the Software, in whole or in part, and // all derivative works of the Software, unless such copies or derivative // works are solely in the form of machine-executable object code generated by // a source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //------------------------------------------------------------------------------ // Tinyformat: A minimal type safe printf replacement // // tinyformat.h is a type safe printf replacement library in a single C++ // header file. Design goals include: // // * Type safety and extensibility for user defined types. // * C99 printf() compatibility, to the extent possible using std::ostream // * Simplicity and minimalism. A single header file to include and distribute // with your projects. // * Augment rather than replace the standard stream formatting mechanism // * C++98 support, with optional C++11 niceties // // // Main interface example usage // ---------------------------- // // To print a date to std::cout: // // std::string weekday = "Wednesday"; // const char* month = "July"; // size_t day = 27; // long hour = 14; // int min = 44; // // tfm::printf("%s, %s %d, %.2d:%.2d\n", weekday, month, day, hour, min); // // The strange types here emphasize the type safety of the interface; it is // possible to print a std::string using the "%s" conversion, and a // size_t using the "%d" conversion. A similar result could be achieved // using either of the tfm::format() functions. One prints on a user provided // stream: // // tfm::format(std::cerr, "%s, %s %d, %.2d:%.2d\n", // weekday, month, day, hour, min); // // The other returns a std::string: // // std::string date = tfm::format("%s, %s %d, %.2d:%.2d\n", // weekday, month, day, hour, min); // std::cout << date; // // These are the three primary interface functions. // // // User defined format functions // ----------------------------- // // Simulating variadic templates in C++98 is pretty painful since it requires // writing out the same function for each desired number of arguments. To make // this bearable tinyformat comes with a set of macros which are used // internally to generate the API, but which may also be used in user code. // // The three macros TINYFORMAT_ARGTYPES(n), TINYFORMAT_VARARGS(n) and // TINYFORMAT_PASSARGS(n) will generate a list of n argument types, // type/name pairs and argument names respectively when called with an integer // n between 1 and 16. We can use these to define a macro which generates the // desired user defined function with n arguments. To generate all 16 user // defined function bodies, use the macro TINYFORMAT_FOREACH_ARGNUM. For an // example, see the implementation of printf() at the end of the source file. // // // Additional API information // -------------------------- // // Error handling: Define TINYFORMAT_ERROR to customize the error handling for // format strings which are unsupported or have the wrong number of format // specifiers (calls assert() by default). // // User defined types: Uses operator<< for user defined types by default. // Overload formatValue() for more control. #ifndef TINYFORMAT_H_INCLUDED #define TINYFORMAT_H_INCLUDED namespace tinyformat {} //------------------------------------------------------------------------------ // Config section. Customize to your liking! // Namespace alias to encourage brevity namespace tfm = tinyformat; // Error handling; calls assert() by default. // #define TINYFORMAT_ERROR(reasonString) your_error_handler(reasonString) // Define for C++11 variadic templates which make the code shorter & more // general. If you don't define this, C++11 support is autodetected below. // #define TINYFORMAT_USE_VARIADIC_TEMPLATES //------------------------------------------------------------------------------ // Implementation details. #include #include #include #ifndef TINYFORMAT_ERROR # define TINYFORMAT_ERROR(reason) assert(0 && reason) #endif #if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES) # ifdef __GXX_EXPERIMENTAL_CXX0X__ # define TINYFORMAT_USE_VARIADIC_TEMPLATES # endif #endif #ifdef __GNUC__ # define TINYFORMAT_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) # define TINYFORMAT_NOINLINE __declspec(noinline) #else # define TINYFORMAT_NOINLINE #endif #if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201 // std::showpos is broken on old libstdc++ as provided with OSX. See // http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html # define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND #endif namespace tinyformat { //------------------------------------------------------------------------------ namespace detail { // Test whether type T1 is convertible to type T2 template struct is_convertible { private: // two types of different size struct fail { char dummy[2]; }; struct succeed { char dummy; }; // Try to convert a T1 to a T2 by plugging into tryConvert static fail tryConvert(...); static succeed tryConvert(const T2&); static const T1& makeT1(); public: # ifdef _MSC_VER // Disable spurious loss of precision warnings in tryConvert(makeT1()) # pragma warning(push) # pragma warning(disable:4244) # pragma warning(disable:4267) # endif // Standard trick: the (...) version of tryConvert will be chosen from // the overload set only if the version taking a T2 doesn't match. // Then we compare the sizes of the return types to check which // function matched. Very neat, in a disgusting kind of way :) static const bool value = sizeof(tryConvert(makeT1())) == sizeof(succeed); # ifdef _MSC_VER # pragma warning(pop) # endif }; // Detect when a type is not a wchar_t string template struct is_wchar { typedef int tinyformat_wchar_is_not_supported; }; template<> struct is_wchar {}; template<> struct is_wchar {}; template struct is_wchar {}; template struct is_wchar {}; // Format the value by casting to type fmtT. This default implementation // should never be called. template::value> struct formatValueAsType { static void invoke(std::ostream& /*out*/, const T& /*value*/) { assert(0); } }; // Specialized version for types that can actually be converted to fmtT, as // indicated by the "convertible" template parameter. template struct formatValueAsType { static void invoke(std::ostream& out, const T& value) { out << static_cast(value); } }; #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND template::value> struct formatZeroIntegerWorkaround { static bool invoke(std::ostream& /**/, const T& /**/) { return false; } }; template struct formatZeroIntegerWorkaround { static bool invoke(std::ostream& out, const T& value) { if (static_cast(value) == 0 && out.flags() & std::ios::showpos) { out << "+0"; return true; } return false; } }; #endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND // Convert an arbitrary type to integer. The version with convertible=false // throws an error. template::value> struct convertToInt { static int invoke(const T& /*value*/) { TINYFORMAT_ERROR("tinyformat: Cannot convert from argument type to " "integer for use as variable width or precision"); return 0; } }; // Specialization for convertToInt when conversion is possible template struct convertToInt { static int invoke(const T& value) { return static_cast(value); } }; } // namespace detail //------------------------------------------------------------------------------ // Variable formatting functions. May be overridden for user-defined types if // desired. // Format a value into a stream. Called from format() for all types by default. // // Users may override this for their own types. When this function is called, // the stream flags will have been modified according to the format string. // The format specification is provided in the range [fmtBegin, fmtEnd). // // By default, formatValue() uses the usual stream insertion operator // operator<< to format the type T, with special cases for the %c and %p // conversions. template inline void formatValue(std::ostream& out, const char* /*fmtBegin*/, const char* fmtEnd, const T& value) { #ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS // Since we don't support printing of wchar_t using "%ls", make it fail at // compile time in preference to printing as a void* at runtime. typedef typename detail::is_wchar::tinyformat_wchar_is_not_supported DummyType; (void) DummyType(); // avoid unused type warning with gcc-4.8 #endif // The mess here is to support the %c and %p conversions: if these // conversions are active we try to convert the type to a char or const // void* respectively and format that instead of the value itself. For the // %p conversion it's important to avoid dereferencing the pointer, which // could otherwise lead to a crash when printing a dangling (const char*). const bool canConvertToChar = detail::is_convertible::value; const bool canConvertToVoidPtr = detail::is_convertible::value; if(canConvertToChar && *(fmtEnd-1) == 'c') detail::formatValueAsType::invoke(out, value); else if(canConvertToVoidPtr && *(fmtEnd-1) == 'p') detail::formatValueAsType::invoke(out, value); #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND else if(detail::formatZeroIntegerWorkaround::invoke(out, value)) /**/; #endif else out << value; } // Overloaded version for char types to support printing as an integer #define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \ inline void formatValue(std::ostream& out, const char* /*fmtBegin*/, \ const char* fmtEnd, charType value) \ { \ switch(*(fmtEnd-1)) \ { \ case 'u': case 'd': case 'i': case 'o': case 'X': case 'x': \ out << static_cast(value); break; \ default: \ out << value; break; \ } \ } // per 3.9.1: char, signed char and unsigned char are all distinct types TINYFORMAT_DEFINE_FORMATVALUE_CHAR(char) TINYFORMAT_DEFINE_FORMATVALUE_CHAR(signed char) TINYFORMAT_DEFINE_FORMATVALUE_CHAR(unsigned char) #undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR //------------------------------------------------------------------------------ // Tools for emulating variadic templates in C++98. The basic idea here is // stolen from the boost preprocessor metaprogramming library and cut down to // be just general enough for what we need. #define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_ ## n #define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_ ## n #define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_ ## n #define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_ ## n // To keep it as transparent as possible, the macros below have been generated // using python via the excellent cog.py code generation script. This avoids // the need for a bunch of complex (but more general) preprocessor tricks as // used in boost.preprocessor. // // To rerun the code generation in place, use `cog.py -r tinyformat.h` // (see http://nedbatchelder.com/code/cog). Alternatively you can just create // extra versions by hand. /*[[[cog maxParams = 16 def makeCommaSepLists(lineTemplate, elemTemplate, startInd=1): for j in range(startInd,maxParams+1): list = ', '.join([elemTemplate % {'i':i} for i in range(startInd,j+1)]) cog.outl(lineTemplate % {'j':j, 'list':list}) makeCommaSepLists('#define TINYFORMAT_ARGTYPES_%(j)d %(list)s', 'class T%(i)d') cog.outl() makeCommaSepLists('#define TINYFORMAT_VARARGS_%(j)d %(list)s', 'const T%(i)d& v%(i)d') cog.outl() makeCommaSepLists('#define TINYFORMAT_PASSARGS_%(j)d %(list)s', 'v%(i)d') cog.outl() cog.outl('#define TINYFORMAT_PASSARGS_TAIL_1') makeCommaSepLists('#define TINYFORMAT_PASSARGS_TAIL_%(j)d , %(list)s', 'v%(i)d', startInd = 2) cog.outl() cog.outl('#define TINYFORMAT_FOREACH_ARGNUM(m) \\\n ' + ' '.join(['m(%d)' % (j,) for j in range(1,maxParams+1)])) ]]]*/ #define TINYFORMAT_ARGTYPES_1 class T1 #define TINYFORMAT_ARGTYPES_2 class T1, class T2 #define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3 #define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4 #define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5 #define TINYFORMAT_ARGTYPES_6 class T1, class T2, class T3, class T4, class T5, class T6 #define TINYFORMAT_ARGTYPES_7 class T1, class T2, class T3, class T4, class T5, class T6, class T7 #define TINYFORMAT_ARGTYPES_8 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8 #define TINYFORMAT_ARGTYPES_9 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9 #define TINYFORMAT_ARGTYPES_10 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10 #define TINYFORMAT_ARGTYPES_11 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11 #define TINYFORMAT_ARGTYPES_12 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12 #define TINYFORMAT_ARGTYPES_13 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13 #define TINYFORMAT_ARGTYPES_14 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14 #define TINYFORMAT_ARGTYPES_15 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 #define TINYFORMAT_ARGTYPES_16 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class T16 #define TINYFORMAT_VARARGS_1 const T1& v1 #define TINYFORMAT_VARARGS_2 const T1& v1, const T2& v2 #define TINYFORMAT_VARARGS_3 const T1& v1, const T2& v2, const T3& v3 #define TINYFORMAT_VARARGS_4 const T1& v1, const T2& v2, const T3& v3, const T4& v4 #define TINYFORMAT_VARARGS_5 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5 #define TINYFORMAT_VARARGS_6 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6 #define TINYFORMAT_VARARGS_7 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7 #define TINYFORMAT_VARARGS_8 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8 #define TINYFORMAT_VARARGS_9 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9 #define TINYFORMAT_VARARGS_10 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10 #define TINYFORMAT_VARARGS_11 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11 #define TINYFORMAT_VARARGS_12 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12 #define TINYFORMAT_VARARGS_13 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13 #define TINYFORMAT_VARARGS_14 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14 #define TINYFORMAT_VARARGS_15 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15 #define TINYFORMAT_VARARGS_16 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15, const T16& v16 #define TINYFORMAT_PASSARGS_1 v1 #define TINYFORMAT_PASSARGS_2 v1, v2 #define TINYFORMAT_PASSARGS_3 v1, v2, v3 #define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4 #define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5 #define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6 #define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7 #define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8 #define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9 #define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 #define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 #define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 #define TINYFORMAT_PASSARGS_13 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 #define TINYFORMAT_PASSARGS_14 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 #define TINYFORMAT_PASSARGS_15 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 #define TINYFORMAT_PASSARGS_16 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 #define TINYFORMAT_PASSARGS_TAIL_1 #define TINYFORMAT_PASSARGS_TAIL_2 , v2 #define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3 #define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4 #define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5 #define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6 #define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7 #define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8 #define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9 #define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10 #define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 #define TINYFORMAT_PASSARGS_TAIL_12 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 #define TINYFORMAT_PASSARGS_TAIL_13 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 #define TINYFORMAT_PASSARGS_TAIL_14 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 #define TINYFORMAT_PASSARGS_TAIL_15 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 #define TINYFORMAT_PASSARGS_TAIL_16 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 #define TINYFORMAT_FOREACH_ARGNUM(m) \ m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8) m(9) m(10) m(11) m(12) m(13) m(14) m(15) m(16) //[[[end]]] namespace detail { // Class holding current position in format string and an output stream into // which arguments are formatted. class FormatIterator { public: // Flags for features not representable with standard stream state enum ExtraFormatFlags { Flag_None = 0, Flag_TruncateToPrecision = 1<<0, // truncate length to stream precision() Flag_SpacePadPositive = 1<<1, // pad positive values with spaces Flag_VariableWidth = 1<<2, // variable field width in arg list Flag_VariablePrecision = 1<<3 // variable field precision in arg list }; // out is the output stream, fmt is the full format string FormatIterator(std::ostream& out, const char* fmt) : m_out(out), m_fmt(fmt), m_extraFlags(Flag_None), m_wantWidth(false), m_wantPrecision(false), m_variableWidth(0), m_variablePrecision(0), m_origWidth(out.width()), m_origPrecision(out.precision()), m_origFlags(out.flags()), m_origFill(out.fill()) { } // Print remaining part of format string. void finish() { // It would be nice if we could do this from the destructor, but we // can't if TINFORMAT_ERROR is used to throw an exception! m_fmt = printFormatStringLiteral(m_out, m_fmt); if(*m_fmt != '\0') TINYFORMAT_ERROR("tinyformat: Too many conversion specifiers in format string"); } ~FormatIterator() { // Restore stream state m_out.width(m_origWidth); m_out.precision(m_origPrecision); m_out.flags(m_origFlags); m_out.fill(m_origFill); } template void accept(const T& value); private: // Parse and return an integer from the string c, as atoi() // On return, c is set to one past the end of the integer. static int parseIntAndAdvance(const char*& c) { int i = 0; for(;*c >= '0' && *c <= '9'; ++c) i = 10*i + (*c - '0'); return i; } // Format at most truncLen characters of a C string to the given // stream. Return true if formatting proceeded (generic version always // returns false) template static bool formatCStringTruncate(std::ostream& /*out*/, const T& /*value*/, std::streamsize /*truncLen*/) { return false; } # define TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(type) \ static bool formatCStringTruncate(std::ostream& out, type* value, \ std::streamsize truncLen) \ { \ std::streamsize len = 0; \ while(len < truncLen && value[len] != 0) \ ++len; \ out.write(value, len); \ return true; \ } // Overload for const char* and char*. Could overload for signed & // unsigned char too, but these are technically unneeded for printf // compatibility. TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(const char) TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(char) # undef TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE // Print literal part of format string and return next format spec // position. // // Skips over any occurrences of '%%', printing a literal '%' to the // output. The position of the first % character of the next // nontrivial format spec is returned, or the end of string. static const char* printFormatStringLiteral(std::ostream& out, const char* fmt) { const char* c = fmt; for(; true; ++c) { switch(*c) { case '\0': out.write(fmt, static_cast(c - fmt)); return c; case '%': out.write(fmt, static_cast(c - fmt)); if(*(c+1) != '%') return c; // for "%%", tack trailing % onto next literal section. fmt = ++c; break; } } } static const char* streamStateFromFormat(std::ostream& out, unsigned int& extraFlags, const char* fmtStart, int variableWidth, int variablePrecision); // Private copy & assign: Kill gcc warnings with -Weffc++ FormatIterator(const FormatIterator&); FormatIterator& operator=(const FormatIterator&); // Stream, current format string & state std::ostream& m_out; const char* m_fmt; unsigned int m_extraFlags; // State machine info for handling of variable width & precision bool m_wantWidth; bool m_wantPrecision; int m_variableWidth; int m_variablePrecision; // Saved stream state std::streamsize m_origWidth; std::streamsize m_origPrecision; std::ios::fmtflags m_origFlags; char m_origFill; }; // Accept a value for formatting into the internal stream. template TINYFORMAT_NOINLINE // < greatly reduces bloat in optimized builds void FormatIterator::accept(const T& value) { // Parse the format string const char* fmtEnd = 0; if(m_extraFlags == Flag_None && !m_wantWidth && !m_wantPrecision) { m_fmt = printFormatStringLiteral(m_out, m_fmt); fmtEnd = streamStateFromFormat(m_out, m_extraFlags, m_fmt, 0, 0); m_wantWidth = (m_extraFlags & Flag_VariableWidth) != 0; m_wantPrecision = (m_extraFlags & Flag_VariablePrecision) != 0; } // Consume value as variable width and precision specifier if necessary if(m_extraFlags & (Flag_VariableWidth | Flag_VariablePrecision)) { if(m_wantWidth || m_wantPrecision) { int v = convertToInt::invoke(value); if(m_wantWidth) { m_variableWidth = v; m_wantWidth = false; } else if(m_wantPrecision) { m_variablePrecision = v; m_wantPrecision = false; } return; } // If we get here, we've set both the variable precision and width as // required and we need to rerun the stream state setup to insert these. fmtEnd = streamStateFromFormat(m_out, m_extraFlags, m_fmt, m_variableWidth, m_variablePrecision); } // Format the value into the stream. if(!(m_extraFlags & (Flag_SpacePadPositive | Flag_TruncateToPrecision))) formatValue(m_out, m_fmt, fmtEnd, value); else { // The following are special cases where there's no direct // correspondence between stream formatting and the printf() behaviour. // Instead, we simulate the behaviour crudely by formatting into a // temporary string stream and munging the resulting string. std::ostringstream tmpStream; tmpStream.copyfmt(m_out); if(m_extraFlags & Flag_SpacePadPositive) tmpStream.setf(std::ios::showpos); // formatCStringTruncate is required for truncating conversions like // "%.4s" where at most 4 characters of the c-string should be read. // If we didn't include this special case, we might read off the end. if(!( (m_extraFlags & Flag_TruncateToPrecision) && formatCStringTruncate(tmpStream, value, m_out.precision()) )) { // Not a truncated c-string; just format normally. formatValue(tmpStream, m_fmt, fmtEnd, value); } std::string result = tmpStream.str(); // allocates... yuck. if(m_extraFlags & Flag_SpacePadPositive) { for(size_t i = 0, iend = result.size(); i < iend; ++i) if(result[i] == '+') result[i] = ' '; } if((m_extraFlags & Flag_TruncateToPrecision) && (int)result.size() > (int)m_out.precision()) m_out.write(result.c_str(), m_out.precision()); else m_out << result; } m_extraFlags = Flag_None; m_fmt = fmtEnd; } // Parse a format string and set the stream state accordingly. // // The format mini-language recognized here is meant to be the one from C99, // with the form "%[flags][width][.precision][length]type". // // Formatting options which can't be natively represented using the ostream // state are returned in the extraFlags parameter which is a bitwise // combination of values from the ExtraFormatFlags enum. inline const char* FormatIterator::streamStateFromFormat(std::ostream& out, unsigned int& extraFlags, const char* fmtStart, int variableWidth, int variablePrecision) { if(*fmtStart != '%') { TINYFORMAT_ERROR("tinyformat: Not enough conversion specifiers in format string"); return fmtStart; } // Reset stream state to defaults. out.width(0); out.precision(6); out.fill(' '); // Reset most flags; ignore irrelevant unitbuf & skipws. out.unsetf(std::ios::adjustfield | std::ios::basefield | std::ios::floatfield | std::ios::showbase | std::ios::boolalpha | std::ios::showpoint | std::ios::showpos | std::ios::uppercase); extraFlags = Flag_None; bool precisionSet = false; bool widthSet = false; const char* c = fmtStart + 1; // 1) Parse flags for(;; ++c) { switch(*c) { case '#': out.setf(std::ios::showpoint | std::ios::showbase); continue; case '0': // overridden by left alignment ('-' flag) if(!(out.flags() & std::ios::left)) { // Use internal padding so that numeric values are // formatted correctly, eg -00010 rather than 000-10 out.fill('0'); out.setf(std::ios::internal, std::ios::adjustfield); } continue; case '-': out.fill(' '); out.setf(std::ios::left, std::ios::adjustfield); continue; case ' ': // overridden by show positive sign, '+' flag. if(!(out.flags() & std::ios::showpos)) extraFlags |= Flag_SpacePadPositive; continue; case '+': out.setf(std::ios::showpos); extraFlags &= ~Flag_SpacePadPositive; continue; } break; } // 2) Parse width if(*c >= '0' && *c <= '9') { widthSet = true; out.width(parseIntAndAdvance(c)); } if(*c == '*') { widthSet = true; if(variableWidth < 0) { // negative widths correspond to '-' flag set out.fill(' '); out.setf(std::ios::left, std::ios::adjustfield); variableWidth = -variableWidth; } out.width(variableWidth); extraFlags |= Flag_VariableWidth; ++c; } // 3) Parse precision if(*c == '.') { ++c; int precision = 0; if(*c == '*') { ++c; extraFlags |= Flag_VariablePrecision; precision = variablePrecision; } else { if(*c >= '0' && *c <= '9') precision = parseIntAndAdvance(c); else if(*c == '-') // negative precisions ignored, treated as zero. parseIntAndAdvance(++c); } out.precision(precision); precisionSet = true; } // 4) Ignore any C99 length modifier while(*c == 'l' || *c == 'h' || *c == 'L' || *c == 'j' || *c == 'z' || *c == 't') ++c; // 5) We're up to the conversion specifier character. // Set stream flags based on conversion specifier (thanks to the // boost::format class for forging the way here). bool intConversion = false; switch(*c) { case 'u': case 'd': case 'i': out.setf(std::ios::dec, std::ios::basefield); intConversion = true; break; case 'o': out.setf(std::ios::oct, std::ios::basefield); intConversion = true; break; case 'X': out.setf(std::ios::uppercase); case 'x': case 'p': out.setf(std::ios::hex, std::ios::basefield); intConversion = true; break; case 'E': out.setf(std::ios::uppercase); case 'e': out.setf(std::ios::scientific, std::ios::floatfield); out.setf(std::ios::dec, std::ios::basefield); break; case 'F': out.setf(std::ios::uppercase); case 'f': out.setf(std::ios::fixed, std::ios::floatfield); break; case 'G': out.setf(std::ios::uppercase); case 'g': out.setf(std::ios::dec, std::ios::basefield); // As in boost::format, let stream decide float format. out.flags(out.flags() & ~std::ios::floatfield); break; case 'a': case 'A': TINYFORMAT_ERROR("tinyformat: the %a and %A conversion specs " "are not supported"); break; case 'c': // Handled as special case inside formatValue() break; case 's': if(precisionSet) extraFlags |= Flag_TruncateToPrecision; // Make %s print booleans as "true" and "false" out.setf(std::ios::boolalpha); break; case 'n': // Not supported - will cause problems! TINYFORMAT_ERROR("tinyformat: %n conversion spec not supported"); break; case '\0': TINYFORMAT_ERROR("tinyformat: Conversion spec incorrectly " "terminated by end of string"); return c; } if(intConversion && precisionSet && !widthSet) { // "precision" for integers gives the minimum number of digits (to be // padded with zeros on the left). This isn't really supported by the // iostreams, but we can approximately simulate it with the width if // the width isn't otherwise used. out.width(out.precision()); out.setf(std::ios::internal, std::ios::adjustfield); out.fill('0'); } return c+1; } //------------------------------------------------------------------------------ // Private format function on top of which the public interface is implemented. // We enforce a mimimum of one value to be formatted to prevent bugs looking like // // const char* myStr = "100% broken"; // printf(myStr); // Parses % as a format specifier #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES template void format(FormatIterator& fmtIter, const T1& value1) { fmtIter.accept(value1); fmtIter.finish(); } // General version for C++11 template void format(FormatIterator& fmtIter, const T1& value1, const Args&... args) { fmtIter.accept(value1); format(fmtIter, args...); } #else inline void format(FormatIterator& fmtIter) { fmtIter.finish(); } // General version for C++98 #define TINYFORMAT_MAKE_FORMAT_DETAIL(n) \ template \ void format(detail::FormatIterator& fmtIter, TINYFORMAT_VARARGS(n)) \ { \ fmtIter.accept(v1); \ format(fmtIter TINYFORMAT_PASSARGS_TAIL(n)); \ } TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_DETAIL) #undef TINYFORMAT_MAKE_FORMAT_DETAIL #endif // End C++98 variadic template emulation for format() } // namespace detail //------------------------------------------------------------------------------ // Implement all the main interface functions here in terms of detail::format() #ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES // C++11 - the simple case template void format(std::ostream& out, const char* fmt, const T1& v1, const Args&... args) { detail::FormatIterator fmtIter(out, fmt); format(fmtIter, v1, args...); } template std::string format(const char* fmt, const T1& v1, const Args&... args) { std::ostringstream oss; format(oss, fmt, v1, args...); return oss.str(); } template void printf(const char* fmt, const T1& v1, const Args&... args) { format(std::cout, fmt, v1, args...); } #else // C++98 - define the interface functions using the wrapping macros #define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \ \ template \ void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n)) \ { \ tinyformat::detail::FormatIterator fmtIter(out, fmt); \ tinyformat::detail::format(fmtIter, TINYFORMAT_PASSARGS(n)); \ } \ \ template \ std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \ { \ std::ostringstream oss; \ tinyformat::format(oss, fmt, TINYFORMAT_PASSARGS(n)); \ return oss.str(); \ } \ \ template \ void printf(const char* fmt, TINYFORMAT_VARARGS(n)) \ { \ tinyformat::format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \ } TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_FUNCS) #undef TINYFORMAT_MAKE_FORMAT_FUNCS #endif //------------------------------------------------------------------------------ // Define deprecated wrapping macro for backward compatibility in tinyformat // 1.x. Will be removed in version 2! #define TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS #define TINYFORMAT_WRAP_FORMAT_N(n, returnType, funcName, funcDeclSuffix, \ bodyPrefix, streamName, bodySuffix) \ template \ returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char* fmt, \ TINYFORMAT_VARARGS(n)) funcDeclSuffix \ { \ bodyPrefix \ tinyformat::format(streamName, fmt, TINYFORMAT_PASSARGS(n)); \ bodySuffix \ } \ #define TINYFORMAT_WRAP_FORMAT(returnType, funcName, funcDeclSuffix, \ bodyPrefix, streamName, bodySuffix) \ inline \ returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char* fmt \ ) funcDeclSuffix \ { \ bodyPrefix \ tinyformat::detail::FormatIterator(streamName, fmt).finish(); \ bodySuffix \ } \ TINYFORMAT_WRAP_FORMAT_N(1 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(2 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(3 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(4 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(5 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(6 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(7 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(8 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(9 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(10, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(11, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(12, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(13, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(14, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(15, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ TINYFORMAT_WRAP_FORMAT_N(16, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \ } // namespace tinyformat #endif // TINYFORMAT_H_INCLUDED openimageio-1.3.12~dfsg0.orig/src/include/errorhandler.h0000644000175000017500000001516312271062644021401 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_ERRORMANAGER_H #define OPENIMAGEIO_ERRORMANAGER_H #include #include "export.h" #include "version.h" #include "strutil.h" OIIO_NAMESPACE_ENTER { /// ErrorHandler is a simple class that accepts error messages /// (classified as errors, severe errors, warnings, info, messages, or /// debug output) and handles them somehow. By default it just prints /// the messages to stdout and/or stderr (and supresses some based on a /// "verbosity" level). /// /// The basic idea is that your library code has no idea whether some /// application that will use it someday will want errors or other /// output to be sent to the console, go to a log file, be intercepted /// by the calling application, or something else. So you punt, by /// having your library take a pointer to an ErrorHandler, passed in /// from the calling app (and possibly subclassed to have arbitrarily /// different behavior from the default console output) and make all /// error-like output via the ErrorHandler*. /// class OIIO_API ErrorHandler { public: /// Error categories. We use broad categories in the high order bits. /// A library may just use these categories, or may create individual /// error codes as long as they have the right high bits to designate /// their category (file not found = ERROR + 1, etc.). enum ErrCode { EH_NO_ERROR = 0, // never sent to handler EH_MESSAGE = 0 << 16, EH_INFO = 1 << 16, EH_WARNING = 2 << 16, EH_ERROR = 3 << 16, EH_SEVERE = 4 << 16, EH_DEBUG = 5 << 16 }; /// VerbosityLevel controls how much detail the calling app wants. /// enum VerbosityLevel { QUIET = 0, ///< Show MESSAGE, SEVERE, ERROR only NORMAL = 1, ///< Show MESSAGE, SEVERE, ERROR, WARNING VERBOSE = 2 ///< Like NORMAL, but also show INFO }; ErrorHandler () : m_verbosity(NORMAL) { } virtual ~ErrorHandler () { } /// The main (or "full detail") method -- takes a code (with high /// bits being an ErrCode) and writes the message, with a prefix /// indicating the error category (no prefix for "MESSAGE") and /// error string. virtual void operator () (int errcode, const std::string &msg); /// Info message with printf-like formatted error message. /// Will not print unless verbosity >= VERBOSE. void info (const char *format, ...) OPENIMAGEIO_PRINTF_ARGS(2,3); /// Warning message with printf-like formatted error message. /// Will not print unless verbosity >= NORMAL (i.e. will suppress /// for QUIET). void warning (const char *format, ...) OPENIMAGEIO_PRINTF_ARGS(2,3); /// Error message with printf-like formatted error message. /// Will print regardless of verbosity. void error (const char *format, ...) OPENIMAGEIO_PRINTF_ARGS(2,3); /// Severe error message with printf-like formatted error message. /// Will print regardless of verbosity. void severe (const char *format, ...) OPENIMAGEIO_PRINTF_ARGS(2,3); /// Prefix-less message with printf-like formatted error message. /// Will not print if verbosity is QUIET. Also note that unlike /// the other routines, message() will NOT append a newline. void message (const char *format, ...) OPENIMAGEIO_PRINTF_ARGS(2,3); /// Debugging message with printf-like formatted error message. /// This will not produce any output if not in DEBUG mode, or /// if verbosity is QUIET. #ifndef NDEBUG void debug (const char *format, ...) OPENIMAGEIO_PRINTF_ARGS(2,3); #else void debug (const char * /*format*/, ...) OPENIMAGEIO_PRINTF_ARGS(2,3) { } #endif void vInfo (const char *format, va_list argptr); void vWarning (const char *format, va_list argptr); void vError (const char *format, va_list argptr); void vSevere (const char *format, va_list argptr); void vMessage (const char *format, va_list argptr); #ifndef NDEBUG void vDebug (const char *format, va_list argptr); #else void vDebug (const char *, va_list) { } #endif void info (const std::string &msg) { (*this)(EH_INFO, msg); } void warning (const std::string &msg) { (*this)(EH_WARNING, msg); } void error (const std::string &msg) { (*this)(EH_ERROR, msg); } void severe (const std::string &msg) { (*this)(EH_SEVERE, msg); } void message (const std::string &msg) { (*this)(EH_MESSAGE, msg); } #ifndef NDEBUG void debug (const std::string &msg) { (*this)(EH_DEBUG, msg); } #else void debug (const std::string &) { } #endif /// Set desired verbosity level. /// void verbosity (int v) { m_verbosity = v; } /// Return the current verbosity level. /// int verbosity () const { return m_verbosity; } /// One built-in handler that can always be counted on to be present /// and just echoes the error messages to the console (stdout or /// stderr, depending on the error category). static ErrorHandler & default_handler (); private: int m_verbosity; }; } OIIO_NAMESPACE_EXIT #endif /* !defined(OPENIMAGEIO_ERRORMANAGER_H) */ openimageio-1.3.12~dfsg0.orig/src/include/thread.h0000644000175000017500000005026712271062644020165 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////// /// @file thread.h /// /// @brief Wrappers and utilities for multithreading. ///////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_THREAD_H #define OPENIMAGEIO_THREAD_H #include "version.h" #include "sysutil.h" // defining NOMINMAX to prevent problems with std::min/std::max // and std::numeric_limits::min()/std::numeric_limits::max() // when boost include windows.h #ifdef _MSC_VER # define WIN32_LEAN_AND_MEAN # define VC_EXTRALEAN # ifndef NOMINMAX # define NOMINMAX # endif #endif #include #if defined(__GNUC__) && (BOOST_VERSION == 104500) // gcc reports errors inside some of the boost headers with boost 1.45 // See: https://svn.boost.org/trac/boost/ticket/4818 #pragma GCC diagnostic ignored "-Wunused-variable" #endif #include #include #include #if defined(__GNUC__) && (BOOST_VERSION == 104500) // can't restore via push/pop in all versions of gcc (warning push/pop implemented for 4.6+ only) #pragma GCC diagnostic error "-Wunused-variable" #endif #ifndef USE_TBB # define USE_TBB 0 #endif // Include files we need for atomic counters. // Some day, we hope this is all replaced by use of std::atomic<>. #if USE_TBB # include # include # define USE_TBB_ATOMIC 1 # define USE_TBB_SPINLOCK 1 #else # define USE_TBB_ATOMIC 0 # define USE_TBB_SPINLOCK 0 #endif #if defined(_MSC_VER) && !USE_TBB # include # include # pragma intrinsic (_InterlockedExchangeAdd) # pragma intrinsic (_InterlockedCompareExchange) # pragma intrinsic (_InterlockedCompareExchange64) # pragma intrinsic (_ReadWriteBarrier) # if defined(_WIN64) # pragma intrinsic(_InterlockedExchangeAdd64) # endif // InterlockedExchangeAdd64 is not available for XP # if defined(_WIN32_WINNT) && _WIN32_WINNT <= 0x0501 inline long long InterlockedExchangeAdd64 (volatile long long *Addend, long long Value) { long long Old; do { Old = *Addend; } while (_InterlockedCompareExchange64(Addend, Old + Value, Old) != Old); return Old; } # endif #endif #if defined(__GNUC__) && (defined(_GLIBCXX_ATOMIC_BUILTINS) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 401)) #define USE_GCC_ATOMICS #endif OIIO_NAMESPACE_ENTER { /// Null mutex that can be substituted for a real one to test how much /// overhead is associated with a particular mutex. class null_mutex { public: null_mutex () { } ~null_mutex () { } void lock () { } void unlock () { } void lock_shared () { } void unlock_shared () { } bool try_lock () { return true; } }; /// Null lock that can be substituted for a real one to test how much /// overhead is associated with a particular lock. template class null_lock { public: null_lock (T &m) { } }; // Null thread-specific ptr that just wraps a single ordinary pointer // template class null_thread_specific_ptr { public: typedef void (*destructor_t)(T *); null_thread_specific_ptr (destructor_t dest=NULL) : m_ptr(NULL), m_dest(dest) { } ~null_thread_specific_ptr () { reset (NULL); } T * get () { return m_ptr; } void reset (T *newptr=NULL) { if (m_ptr) { if (m_dest) (*m_dest) (m_ptr); else delete m_ptr; } m_ptr = newptr; } private: T *m_ptr; destructor_t m_dest; }; #ifdef NOTHREADS // Definitions that we use for debugging to turn off all mutexes, locks, // and atomics in order to test the performance hit of our thread safety. // Null thread-specific ptr that just wraps a single ordinary pointer // template class thread_specific_ptr { public: typedef void (*destructor_t)(T *); thread_specific_ptr (destructor_t dest=NULL) : m_ptr(NULL), m_dest(dest) { } ~thread_specific_ptr () { reset (NULL); } T * get () { return m_ptr; } void reset (T *newptr=NULL) { if (m_ptr) { if (m_dest) (*m_dest) (m_ptr); else delete m_ptr; } m_ptr = newptr; } private: T *m_ptr; destructor_t m_dest; }; typedef null_mutex mutex; typedef null_mutex recursive_mutex; typedef null_lock lock_guard; typedef null_lock recursive_lock_guard; #else // Fairly modern Boost has all the mutex and lock types we need. typedef boost::mutex mutex; typedef boost::recursive_mutex recursive_mutex; typedef boost::lock_guard< boost::mutex > lock_guard; typedef boost::lock_guard< boost::recursive_mutex > recursive_lock_guard; using boost::thread_specific_ptr; #endif /// Atomic version of: r = *at, *at += x, return r /// For each of several architectures. inline int atomic_exchange_and_add (volatile int *at, int x) { #ifdef NOTHREADS int r = *at; *at += x; return r; #elif defined(USE_GCC_ATOMICS) return __sync_fetch_and_add ((int *)at, x); #elif USE_TBB atomic *a = (atomic *)at; return a->fetch_and_add (x); #elif defined(_MSC_VER) // Windows return _InterlockedExchangeAdd ((volatile LONG *)at, x); #else # error No atomics on this platform. #endif } inline long long atomic_exchange_and_add (volatile long long *at, long long x) { #ifdef NOTHREADS long long r = *at; *at += x; return r; #elif defined(USE_GCC_ATOMICS) return __sync_fetch_and_add (at, x); #elif USE_TBB atomic *a = (atomic *)at; return a->fetch_and_add (x); #elif defined(_MSC_VER) // Windows # if defined(_WIN64) return _InterlockedExchangeAdd64 ((volatile LONGLONG *)at, x); # else return InterlockedExchangeAdd64 ((volatile LONGLONG *)at, x); # endif #else # error No atomics on this platform. #endif } /// Atomic version of: /// if (*at == compareval) { /// *at = newval; return true; /// } else { /// return false; /// } inline bool atomic_compare_and_exchange (volatile int *at, int compareval, int newval) { #ifdef NOTHREADS if (*at == compareval) { *at = newval; return true; } else { return false; } #elif defined(USE_GCC_ATOMICS) return __sync_bool_compare_and_swap (at, compareval, newval); #elif USE_TBB atomic *a = (atomic *)at; return a->compare_and_swap (newval, compareval) == newval; #elif defined(_MSC_VER) return (_InterlockedCompareExchange ((volatile LONG *)at, newval, compareval) == compareval); #else # error No atomics on this platform. #endif } inline bool atomic_compare_and_exchange (volatile long long *at, long long compareval, long long newval) { #ifdef NOTHREADS if (*at == compareval) { *at = newval; return true; } else { return false; } #elif defined(USE_GCC_ATOMICS) return __sync_bool_compare_and_swap (at, compareval, newval); #elif USE_TBB atomic *a = (atomic *)at; return a->compare_and_swap (newval, compareval) == newval; #elif defined(_MSC_VER) return (_InterlockedCompareExchange64 ((volatile LONGLONG *)at, newval, compareval) == compareval); #else # error No atomics on this platform. #endif } /// Yield the processor for the rest of the timeslice. /// inline void yield () { #if defined(__GNUC__) sched_yield (); #elif defined(_MSC_VER) SwitchToThread (); #else # error No yield on this platform. #endif } // Slight pause inline void pause (int delay) { #if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) for (int i = 0; i < delay; ++i) __asm__ __volatile__("pause;"); #elif defined(__GNUC__) && (defined(__arm__) || defined(__s390__)) for (int i = 0; i < delay; ++i) __asm__ __volatile__("NOP;"); #elif USE_TBB __TBB_Pause(delay); #elif defined(_MSC_VER) for (int i = 0; i < delay; ++i) { #if defined (_WIN64) YieldProcessor(); #else _asm pause #endif /* _WIN64 */ } #else // No pause on this platform, just punt for (int i = 0; i < delay; ++i) ; #endif } // Helper class to deliver ever longer pauses until we yield our timeslice. class atomic_backoff { public: atomic_backoff () : m_count(1) { } void operator() () { if (m_count <= 16) { pause (m_count); m_count *= 2; } else { yield(); } } private: int m_count; }; #if USE_TBB_ATOMIC using tbb::atomic; #else // If we're not using TBB's atomic, we need to define our own atomic<>. /// Atomic integer. Increment, decrement, add, and subtract in a /// totally thread-safe manner. template class atomic { public: /// Construct with initial value. /// atomic (T val=0) : m_val(val) { } ~atomic () { } /// Retrieve value /// T operator() () const { return atomic_exchange_and_add (&m_val, 0); } /// Retrieve value /// operator T() const { return atomic_exchange_and_add (&m_val, 0); } /// Fast retrieval of value, no interchange, don't care about memory /// fences. T fast_value () const { return m_val; } /// Assign new value. /// T operator= (T x) { //incorrect? return (m_val = x); while (1) { T result = m_val; if (atomic_compare_and_exchange (&m_val, result, x)) break; } return x; } /// Pre-increment: ++foo /// T operator++ () { return atomic_exchange_and_add (&m_val, 1) + 1; } /// Post-increment: foo++ /// T operator++ (int) { return atomic_exchange_and_add (&m_val, 1); } /// Pre-decrement: --foo /// T operator-- () { return atomic_exchange_and_add (&m_val, -1) - 1; } /// Post-decrement: foo-- /// T operator-- (int) { return atomic_exchange_and_add (&m_val, -1); } /// Add to the value, return the new result /// T operator+= (T x) { return atomic_exchange_and_add (&m_val, x) + x; } /// Subtract from the value, return the new result /// T operator-= (T x) { return atomic_exchange_and_add (&m_val, -x) - x; } bool bool_compare_and_swap (T compareval, T newval) { return atomic_compare_and_exchange (&m_val, compareval, newval); } T operator= (const atomic &x) { T r = x(); *this = r; return r; } private: #ifdef __arm__ OIIO_ALIGN(8) #endif volatile mutable T m_val; // Disallow copy construction by making private and unimplemented. atomic (atomic const &); }; #endif /* ! USE_TBB_ATOMIC */ #ifdef NOTHREADS typedef int atomic_int; typedef long long atomic_ll; #else typedef atomic atomic_int; typedef atomic atomic_ll; #endif #ifdef NOTHREADS typedef null_mutex spin_mutex; typedef null_lock spin_lock; #elif USE_TBB_SPINLOCK // Use TBB's spin locks typedef tbb::spin_mutex spin_mutex; typedef tbb::spin_mutex::scoped_lock spin_lock; #else // Define our own spin locks. Do we trust them? /// A spin_mutex is semantically equivalent to a regular mutex, except /// for the following: /// - A spin_mutex is just 4 bytes, whereas a regular mutex is quite /// large (44 bytes for pthread). /// - A spin_mutex is extremely fast to lock and unlock, whereas a regular /// mutex is surprisingly expensive just to acquire a lock. /// - A spin_mutex takes CPU while it waits, so this can be very /// wasteful compared to a regular mutex that blocks (gives up its /// CPU slices until it acquires the lock). /// /// The bottom line is that mutex is the usual choice, but in cases where /// you need to acquire locks very frequently, but only need to hold the /// lock for a very short period of time, you may save runtime by using /// a spin_mutex, even though it's non-blocking. /// /// N.B. A spin_mutex is only the size of an int. To avoid "false /// sharing", be careful not to put two spin_mutex objects on the same /// cache line (within 128 bytes of each other), or the two mutexes may /// effectively (and wastefully) lock against each other. /// class spin_mutex { public: /// Default constructor -- initialize to unlocked. /// spin_mutex (void) { m_locked = 0; } ~spin_mutex (void) { } /// Copy constructor -- initialize to unlocked. /// spin_mutex (const spin_mutex &) { m_locked = 0; } /// Assignment does not do anything, since lockedness should not /// transfer. const spin_mutex& operator= (const spin_mutex&) { return *this; } /// Acquire the lock, spin until we have it. /// void lock () { // To avoid spinning too tightly, we use the atomic_backoff to // provide increasingly longer pauses, and if the lock is under // lots of contention, eventually yield the timeslice. atomic_backoff backoff; // Try to get ownership of the lock. Though experimentation, we // found that OIIO_UNLIKELY makes this just a bit faster on // gcc x86/x86_64 systems. while (! OIIO_UNLIKELY(try_lock())) { do { backoff(); } while (m_locked); // The full try_lock() involves a compare_and_swap, which // writes memory, and that will lock the bus. But a normal // read of m_locked will let us spin until the value // changes, without locking the bus. So it's faster to // check in this manner until the mutex appears to be free. } } /// Release the lock that we hold. /// void unlock () { #if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) // Fastest way to do it is with a store with "release" semantics __asm__ __volatile__("": : :"memory"); m_locked = 0; // N.B. GCC gives us an intrinsic that is even better, an atomic // assignment of 0 with "release" barrier semantics: // __sync_lock_release (&m_locked); // But empirically we found it not as performant as the above. #elif defined(_MSC_VER) _ReadWriteBarrier(); m_locked = 0; #else // Otherwise, just assign zero to the atomic (but that's a full // memory barrier). *(atomic_int *)&m_locked = 0; #endif } /// Try to acquire the lock. Return true if we have it, false if /// somebody else is holding the lock. bool try_lock () { #if USE_TBB_ATOMIC // TBB's compare_and_swap returns the original value return (*(atomic_int *)&m_locked).compare_and_swap (0, 1) == 0; #elif defined(__GNUC__) // GCC gives us an intrinsic that is even better -- an atomic // exchange with "acquire" barrier semantics. return __sync_lock_test_and_set (&m_locked, 1) == 0; #else // Our compare_and_swap returns true if it swapped return atomic_compare_and_exchange (&m_locked, 0, 1); #endif } /// Helper class: scoped lock for a spin_mutex -- grabs the lock upon /// construction, releases the lock when it exits scope. class lock_guard { public: lock_guard (spin_mutex &fm) : m_fm(fm) { m_fm.lock(); } ~lock_guard () { m_fm.unlock(); } private: lock_guard(); // Do not implement (even though TBB does) lock_guard(const lock_guard& other); // Do not implement lock_guard& operator = (const lock_guard& other); // Do not implement spin_mutex & m_fm; }; private: volatile int m_locked; ///< Atomic counter is zero if nobody holds the lock }; typedef spin_mutex::lock_guard spin_lock; #endif /// Spinning reader/writer mutex. This is just like spin_mutex, except /// that there are separate locking mechanisms for "writers" (exclusive /// holders of the lock, presumably because they are modifying whatever /// the lock is protecting) and "readers" (non-exclusive, non-modifying /// tasks that may access the protectee simultaneously). class spin_rw_mutex { public: /// Default constructor -- initialize to unlocked. /// spin_rw_mutex (void) { m_readers = 0; } ~spin_rw_mutex (void) { } /// Copy constructor -- initialize to unlocked. /// spin_rw_mutex (const spin_rw_mutex &) { m_readers = 0; } /// Assignment does not do anything, since lockedness should not /// transfer. const spin_rw_mutex& operator= (const spin_rw_mutex&) { return *this; } /// Acquire the reader lock. /// void read_lock () { // Spin until there are no writers active m_locked.lock(); // Register ourself as a reader ++m_readers; // Release the lock, to let other readers work m_locked.unlock(); } /// Release the reader lock. /// void read_unlock () { --m_readers; // it's atomic, no need to lock to release } /// Acquire the writer lock. /// void write_lock () { // Make sure no new readers (or writers) can start m_locked.lock(); // Spin until the last reader is done, at which point we will be // the sole owners and nobody else (reader or writer) can acquire // the resource until we release it. while (*(volatile int *)&m_readers > 0) ; } /// Release the writer lock. /// void write_unlock () { // Let other readers or writers get the lock m_locked.unlock (); } /// Helper class: scoped read lock for a spin_rw_mutex -- grabs the /// read lock upon construction, releases the lock when it exits scope. class read_lock_guard { public: read_lock_guard (spin_rw_mutex &fm) : m_fm(fm) { m_fm.read_lock(); } ~read_lock_guard () { m_fm.read_unlock(); } private: read_lock_guard(); // Do not implement read_lock_guard(const read_lock_guard& other); // Do not implement read_lock_guard& operator = (const read_lock_guard& other); // Do not implement spin_rw_mutex & m_fm; }; /// Helper class: scoped write lock for a spin_rw_mutex -- grabs the /// read lock upon construction, releases the lock when it exits scope. class write_lock_guard { public: write_lock_guard (spin_rw_mutex &fm) : m_fm(fm) { m_fm.write_lock(); } ~write_lock_guard () { m_fm.write_unlock(); } private: write_lock_guard(); // Do not implement write_lock_guard(const write_lock_guard& other); // Do not implement write_lock_guard& operator = (const write_lock_guard& other); // Do not implement spin_rw_mutex & m_fm; }; private: OIIO_CACHE_ALIGN spin_mutex m_locked; // write lock char pad1_[OIIO_CACHE_LINE_SIZE-sizeof(spin_mutex)]; OIIO_CACHE_ALIGN atomic_int m_readers; // number of readers char pad2_[OIIO_CACHE_LINE_SIZE-sizeof(atomic_int)]; }; typedef spin_rw_mutex::read_lock_guard spin_rw_read_lock; typedef spin_rw_mutex::write_lock_guard spin_rw_write_lock; } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_THREAD_H openimageio-1.3.12~dfsg0.orig/src/include/pystring.h0000644000175000017500000003750512271062644020575 0ustar mfvmfv/////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2008, Sony Pictures Imageworks // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // Neither the name of the organization Sony Pictures Imageworks nor the // names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /////////////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_PYSTRING_H #define OPENIMAGEIO_PYSTRING_H #include #include #include "version.h" OIIO_NAMESPACE_ENTER { namespace pystring { ////////////////////////////////////////////////////////////////////////////////////////////// /// @mainpage pystring /// /// This is a set of functions matching the interface and behaviors of python string methods /// (as of python 2.3) using std::string. /// /// Overlapping functionality ( such as index and slice/substr ) of std::string is included /// to match python interfaces. /// ////////////////////////////////////////////////////////////////////////////////////////////// /// @defgroup functions pystring /// @{ #define MAX_32BIT_INT 2147483647 ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with only its first character capitalized. /// std::string capitalize( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return centered in a string of length width. Padding is done using spaces. /// std::string center( const std::string & str, int width ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the number of occurrences of substring sub in string S[start:end]. Optional /// arguments start and end are interpreted as in slice notation. /// int count( const std::string & str, const std::string & substr, int start = 0, int end = MAX_32BIT_INT); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return True if the string ends with the specified suffix, otherwise return False. With /// optional start, test beginning at that position. With optional end, stop comparing at that position. /// bool endswith( const std::string & str, const std::string & suffix, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string where all tab characters are expanded using spaces. If tabsize /// is not given, a tab size of 8 characters is assumed. /// std::string expandtabs( const std::string & str, int tabsize = 8); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the lowest index in the string where substring sub is found, such that sub is /// contained in the range [start, end). Optional arguments start and end are interpreted as /// in slice notation. Return -1 if sub is not found. /// int find( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Synonym of find right now. Python version throws exceptions. This one currently doesn't /// int index( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all characters in the string are alphanumeric and there is at least one /// character, false otherwise. /// bool isalnum( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all characters in the string are alphabetic and there is at least one /// character, false otherwise /// bool isalpha( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all characters in the string are digits and there is at least one /// character, false otherwise. /// bool isdigit( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all cased characters in the string are lowercase and there is at least one /// cased character, false otherwise. /// bool islower( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if there are only whitespace characters in the string and there is at least /// one character, false otherwise. /// bool isspace( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if the string is a titlecased string and there is at least one character, /// i.e. uppercase characters may only follow uncased characters and lowercase characters only /// cased ones. Return false otherwise. /// bool istitle( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all cased characters in the string are uppercase and there is at least one /// cased character, false otherwise. /// bool isupper( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a string which is the concatenation of the strings in the sequence seq. /// The separator between elements is the str argument /// std::string join( const std::string & str, const std::vector< std::string > & seq ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the string left justified in a string of length width. Padding is done using /// spaces. The original string is returned if width is less than str.size(). /// std::string ljust( const std::string & str, int width ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string converted to lowercase. /// std::string lower( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with leading characters removed. If chars is omitted or None, /// whitespace characters are removed. If given and not "", chars must be a string; the /// characters in the string will be stripped from the beginning of the string this method /// is called on (argument "str" ). /// std::string lstrip( const std::string & str, const std::string & chars = "" ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the string around first occurance of sep. /// Three strings will always placed into result. If sep is found, the strings will /// be the text before sep, sep itself, and the remaining text. If sep is /// not found, the original string will be returned with two empty strings. /// void partition( const std::string & str, const std::string & sep, std::vector< std::string > & result ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with all occurrences of substring old replaced by new. If /// the optional argument count is given, only the first count occurrences are replaced. /// std::string replace( const std::string & str, const std::string & oldstr, const std::string & newstr, int count = -1); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the highest index in the string where substring sub is found, such that sub is /// contained within s[start,end]. Optional arguments start and end are interpreted as in /// slice notation. Return -1 on failure. /// int rfind( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Currently a synonym of rfind. The python version raises exceptions. This one currently /// does not /// int rindex( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the string right justified in a string of length width. Padding is done using /// spaces. The original string is returned if width is less than str.size(). /// std::string rjust( const std::string & str, int width); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the string around last occurance of sep. /// Three strings will always placed into result. If sep is found, the strings will /// be the text before sep, sep itself, and the remaining text. If sep is /// not found, the original string will be returned with two empty strings. /// void rpartition( const std::string & str, const std::string & sep, std::vector< std::string > & result ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with trailing characters removed. If chars is "", whitespace /// characters are removed. If not "", the characters in the string will be stripped from the /// end of the string this method is called on. /// std::string rstrip( const std::string & str, const std::string & chars = "" ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Fills the "result" list with the words in the string, using sep as the delimiter string. /// If maxsplit is > -1, at most maxsplit splits are done. If sep is "", /// any whitespace string is a separator. /// void split( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Fills the "result" list with the words in the string, using sep as the delimiter string. /// Does a number of splits starting at the end of the string, the result still has the /// split strings in their original order. /// If maxsplit is > -1, at most maxsplit splits are done. If sep is "", /// any whitespace string is a separator. /// void rsplit( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a list of the lines in the string, breaking at line boundaries. Line breaks /// are not included in the resulting list unless keepends is given and true. /// void splitlines( const std::string & str, std::vector< std::string > & result, bool keepends = false ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return True if string starts with the prefix, otherwise return False. With optional start, /// test string beginning at that position. With optional end, stop comparing string at that /// position /// bool startswith( const std::string & str, const std::string & prefix, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with leading and trailing characters removed. If chars is "", /// whitespace characters are removed. If given not "", the characters in the string will be /// stripped from the both ends of the string this method is called on. /// std::string strip( const std::string & str, const std::string & chars = "" ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with uppercase characters converted to lowercase and vice versa. /// std::string swapcase( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a titlecased version of the string: words start with uppercase characters, /// all remaining cased characters are lowercase. /// std::string title( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string where all characters occurring in the optional argument /// deletechars are removed, and the remaining characters have been mapped through the given /// translation table, which must be a string of length 256. /// std::string translate( const std::string & str, const std::string & table, const std::string & deletechars = ""); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string converted to uppercase. /// std::string upper( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the numeric string left filled with zeros in a string of length width. The original /// string is returned if width is less than str.size(). /// std::string zfill( const std::string & str, int width ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief function matching python's slice functionality. /// std::string slice( const std::string & str, int start = 0, int end = MAX_32BIT_INT); /// /// @ } /// } // pystring namespace } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_PYSTRING_H openimageio-1.3.12~dfsg0.orig/src/include/optparser.h0000644000175000017500000001100712271062644020722 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////// /// @file optparser.h /// /// @brief Option parser template ///////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_OPTPARSER_H #define OPENIMAGEIO_OPTPARSER_H #include OIIO_NAMESPACE_ENTER { /// Parse a string of the form "name=value" and then call /// system.attribute (name, value), with appropriate type conversions. template inline bool optparse1 (C &system, const std::string &opt) { std::string::size_type eq_pos = opt.find_first_of ("="); if (eq_pos == std::string::npos) { // malformed option return false; } std::string name (opt, 0, eq_pos); // trim the name while (name.size() && name[0] == ' ') name.erase (0); while (name.size() && name[name.size()-1] == ' ') name.erase (name.size()-1); std::string value (opt, eq_pos+1, std::string::npos); if (name.empty()) return false; char v = value.size() ? value[0] : ' '; if ((v >= '0' && v <= '9') || v == '+' || v == '-') { // numeric if (strchr (value.c_str(), '.')) // float return system.attribute (name.c_str(), (float)atof(value.c_str())); else // int return system.attribute (name.c_str(), (int)atoi(value.c_str())); } // otherwise treat it as a string // trim surrounding double quotes if (value.size() >= 2 && value[0] == '\"' && value[value.size()-1] == '\"') value = std::string (value, 1, value.size()-2); return system.attribute (name.c_str(), value.c_str()); } /// Parse a string with comma-separated name=value directives, calling /// system.attribute(name,value) for each one, with appropriate type /// conversions. Examples: /// optparser(texturesystem, "verbose=1"); /// optparser(texturesystem, "max_memory_MB=32.0"); /// optparser(texturesystem, "a=1,b=2,c=3.14,d=\"a string\""); template inline bool optparser (C &system, const std::string &optstring) { bool ok = true; size_t len = optstring.length(); size_t pos = 0; while (pos < len) { std::string opt; bool inquote = false; while (pos < len) { unsigned char c = optstring[pos]; if (c == '\"') { // Hit a double quote -- toggle "inquote" and add the quote inquote = !inquote; opt += c; ++pos; } else if (c == ',' && !inquote) { // Hit a comma and not inside a quote -- we have an option ++pos; // skip the comma break; // done with option } else { // Anything else: add to the option opt += c; ++pos; } } // At this point, opt holds an option ok &= optparse1 (system, opt); } return ok; } } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_OPTPARSER_H openimageio-1.3.12~dfsg0.orig/src/include/export.h0000644000175000017500000001010712271062644020224 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_EXPORT_H #define OPENIMAGEIO_EXPORT_H /// \file /// Macros necessary for proper symbol export from dynamic libraries. /// /// On Windows, when compiling code that will end up in a DLL, symbols /// must be marked as 'exported' (i.e. __declspec(dllexport)) or they /// won't be visible to programs linking against the DLL. /// /// In addition, when compiling the application code that calls the DLL, /// if a routine is marked as 'imported' (i.e. __declspec(dllimport)), /// the compiler can be smart about eliminating a level of calling /// indirection. But you DON'T want to use __declspec(dllimport) when /// calling a function from within its own DLL (it will still compile /// correctly, just not with maximal efficiency). Which is quite the /// dilemma since the same header file is used by both the library and /// its clients. Sheesh! /// /// But on Linux/OSX as well, we want to only have the DSO export the /// symbols we designate as the public interface. So we link with /// -fvisibility=hidden to default to hiding the symbols. See /// http://gcc.gnu.org/wiki/Visibility /// /// We solve this awful mess by defining these macros: /// /// OIIO_API - used for the OpenImageIO public API. Normally, assumes /// that it's being seen by a client of the library, and /// therefore declare as 'imported'. But if /// OpenImageIO_EXPORT is defined (as is done by CMake /// when compiling the library itself), change the /// declaration to 'exported'. /// OIIO_EXPORT - explicitly exports a symbol that isn't part of the /// public API but still needs to be visible. /// OIIO_LOCAL - explicitly hides a symbol that might otherwise be /// exported /// /// #if defined(_MSC_VER) || defined(__CYGWIN__) #define OIIO_IMPORT __declspec(dllimport) #define OIIO_EXPORT __declspec(dllexport) #define OIIO_LOCAL #else #if (10000*__GNUC__ + 100*__GNUC_MINOR__ + __GNUC_PATCHLEVEL__) > 40102 #define OIIO_IMPORT __attribute__ ((visibility ("default"))) #define OIIO_EXPORT __attribute__ ((visibility ("default"))) #define OIIO_LOCAL __attribute__ ((visibility ("hidden"))) #else #define OIIO_IMPORT #define OIIO_EXPORT #define OIIO_LOCAL #endif #endif #if defined(OpenImageIO_EXPORTS) # define OIIO_API OIIO_EXPORT #else # define OIIO_API OIIO_IMPORT #endif // Back compatibility macros (DEPRECATED) #define DLLPUBLIC OIIO_API #define DLLEXPORT OIIO_EXPORT #endif // OPENIMAGEIO_EXPORT_H openimageio-1.3.12~dfsg0.orig/src/include/unittest.h0000644000175000017500000001227412271062644020571 0ustar mfvmfv /* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_UNITTEST_H #define OPENIMAGEIO_UNITTEST_H #include static int unit_test_failures = 0; /// OIIO_CHECK_* macros checks if the conditions is met, and if not, /// prints an error message indicating the module and line where the /// error occurred, but does NOT abort. This is helpful for unit tests /// where we do not want one failure. #define OIIO_CHECK_ASSERT(x) \ ((x) ? ((void)0) \ : ((std::cout << __FILE__ << ":" << __LINE__ << ":\n" \ << "FAILED: " << #x << "\n"), \ (void)++unit_test_failures)) #define OIIO_CHECK_EQUAL(x,y) \ (((x) == (y)) ? ((void)0) \ : ((std::cout << __FILE__ << ":" << __LINE__ << ":\n" \ << "FAILED: " << #x << " == " << #y << "\n" \ << "\tvalues were '" << (x) << "' and '" << (y) << "'\n"), \ (void)++unit_test_failures)) #define OIIO_CHECK_EQUAL_THRESH(x,y,eps) \ ((std::abs((x)-(y)) <= eps) ? ((void)0) \ : ((std::cout << __FILE__ << ":" << __LINE__ << ":\n" \ << "FAILED: " << #x << " == " << #y << "\n" \ << "\tvalues were '" << (x) << "' and '" << (y) << "'" \ << ", diff was " << std::abs((x)-(y)) << "\n"), \ (void)++unit_test_failures)) #define OIIO_CHECK_NE(x,y) \ (((x) != (y)) ? ((void)0) \ : ((std::cout << __FILE__ << ":" << __LINE__ << ":\n" \ << "FAILED: " << #x << " != " << #y << "\n" \ << "\tvalues were '" << (x) << "' and '" << (y) << "'\n"), \ (void)++unit_test_failures)) #define OIIO_CHECK_LT(x,y) \ (((x) < (y)) ? ((void)0) \ : ((std::cout << __FILE__ << ":" << __LINE__ << ":\n" \ << "FAILED: " << #x << " < " << #y << "\n" \ << "\tvalues were '" << (x) << "' and '" << (y) << "'\n"), \ (void)++unit_test_failures)) #define OIIO_CHECK_GT(x,y) \ (((x) > (y)) ? ((void)0) \ : ((std::cout << __FILE__ << ":" << __LINE__ << ":\n" \ << "FAILED: " << #x << " > " << #y << "\n" \ << "\tvalues were '" << (x) << "' and '" << (y) << "'\n"), \ (void)++unit_test_failures)) #define OIIO_CHECK_LE(x,y) \ (((x) <= (y)) ? ((void)0) \ : ((std::cout << __FILE__ << ":" << __LINE__ << ":\n" \ << "FAILED: " << #x << " <= " << #y << "\n" \ << "\tvalues were '" << (x) << "' and '" << (y) << "'\n"), \ (void)++unit_test_failures)) #define OIIO_CHECK_GE(x,y) \ (((x) >= (y)) ? ((void)0) \ : ((std::cout << __FILE__ << ":" << __LINE__ << ":\n" \ << "FAILED: " << #x << " >= " << #y << "\n" \ << "\tvalues were '" << (x) << "' and '" << (y) << "'\n"), \ (void)++unit_test_failures)) #endif /* OPENIMAGEIO_UNITTEST_H */ openimageio-1.3.12~dfsg0.orig/src/include/hash.h0000644000175000017500000001531112271062644017630 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// /// Wrapper so that hash_map and hash_set mean what we want regardless /// of the compiler. /// #ifndef OPENIMAGEIO_HASH_H #define OPENIMAGEIO_HASH_H #include #include #define OIIO_HAVE_BOOST_UNORDERED_MAP #include #include #include "export.h" #include "version.h" #include "fmath.h" /* for endian */ OIIO_NAMESPACE_ENTER { namespace xxhash { // xxhash: http://code.google.com/p/xxhash/ // It's BSD licensed. // Calculate the 32-bits hash of "input", of length "len" // "seed" can be used to alter the result unsigned int OIIO_API XXH_fast32 (const void* input, int len, unsigned int seed=1771); // Same as XXH_fast(), but the resulting hash has stronger properties unsigned int OIIO_API XXH_strong32 (const void* input, int len, unsigned int seed=1771); } // end namespace xxhash namespace bjhash { // Bob Jenkins "lookup3" hashes: http://burtleburtle.net/bob/c/lookup3.c // It's in the public domain. inline uint32_t rotl32 (uint32_t x, int k) { return (x<>(32-k)); } inline uint64_t rotl64 (uint64_t x, int k) { return (x<>(64-k)); } // Mix up the bits of a, b, and c (changing their values in place). inline void bjmix (uint32_t &a, uint32_t &b, uint32_t &c) { a -= c; a ^= rotl32(c, 4); c += b; b -= a; b ^= rotl32(a, 6); a += c; c -= b; c ^= rotl32(b, 8); b += a; a -= c; a ^= rotl32(c,16); c += b; b -= a; b ^= rotl32(a,19); a += c; c -= b; c ^= rotl32(b, 4); b += a; } // Mix up and combine the bits of a, b, and c (doesn't change them, but // returns a hash of those three original values). 21 ops inline uint32_t bjfinal (uint32_t a, uint32_t b, uint32_t c=0xdeadbeef) { c ^= b; c -= rotl32(b,14); a ^= c; a -= rotl32(c,11); b ^= a; b -= rotl32(a,25); c ^= b; c -= rotl32(b,16); a ^= c; a -= rotl32(c,4); b ^= a; b -= rotl32(a,14); c ^= b; c -= rotl32(b,24); return c; } // Mix up 4 64-bit inputs (non-destructively), and return a 64 bit hash. // Adapted from http://burtleburtle.net/bob/c/SpookyV2.h 33 ops inline uint64_t bjfinal64 (uint64_t h0, uint64_t h1, uint64_t h2, uint64_t h3) { h3 ^= h2; h2 = rotl64(h2,15); h3 += h2; h0 ^= h3; h3 = rotl64(h3,52); h0 += h3; h1 ^= h0; h0 = rotl64(h0,26); h1 += h0; h2 ^= h1; h1 = rotl64(h1,51); h2 += h1; h3 ^= h2; h2 = rotl64(h2,28); h3 += h2; h0 ^= h3; h3 = rotl64(h3,9); h0 += h3; h1 ^= h0; h0 = rotl64(h0,47); h1 += h0; h2 ^= h1; h1 = rotl64(h1,54); h2 += h1; h3 ^= h2; h2 = rotl64(h2,32); h3 += h2; h0 ^= h3; h3 = rotl64(h3,25); h0 += h3; h1 ^= h0; h0 = rotl64(h0,63); h1 += h0; return h1; } // Standard "lookup3" hash, arbitrary length in bytes. uint32_t OIIO_API hashlittle (const void *key, size_t length, uint32_t seed=1771); // Hash an array of 32 bit words -- faster than hashlittle if you know // it's a whole number of 4-byte words. uint32_t OIIO_API hashword (const uint32_t *key, size_t nwords, uint32_t seed=1771); } // end namespace bjhash namespace murmur { // These functions were lifted from the public domain Murmurhash3. We // don't bother using Murmurhash -- in my tests, it was slower than // xxhash in all cases, and comparable to bjhash. But these two fmix // functions are useful for scrambling the bits of a single 32 or 64 bit // value. inline uint32_t fmix (uint32_t h) { h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; h ^= h >> 16; return h; } inline uint64_t fmix (uint64_t k) { k ^= k >> 33; k *= 0xff51afd7ed558ccdULL; k ^= k >> 33; k *= 0xc4ceb9fe1a85ec53ULL; k ^= k >> 33; return k; } } // end namespace murmur class CSHA1; // opaque forward declaration /// Class that encapsulates SHA-1 hashing, a crypticographic-strength /// 160-bit hash function. It's not as fast as our other hashing /// methods, but has an extremely low chance of having collisions. class OIIO_API SHA1 { public: /// Create SHA1, optionally read data SHA1 (const void *data=NULL, size_t size=0); ~SHA1 (); /// Append more data void append (const void *data, size_t size); /// Append more data from a vector, without thinking about sizes. template void appendvec (const std::vector &v) { append (&v[0], v.size()*sizeof(T)); } /// Type for storing the raw bits of the hash struct Hash { unsigned char hash[20]; }; /// Get the digest and store it in Hash h. void gethash (Hash &h); /// Get the digest and store it in h (must point to enough storage /// to accommodate 20 bytes). void gethash (void *h) { gethash (*(Hash *)h); } /// Return the digest as a hex string std::string digest (); /// Roll the whole thing into one functor, return the string digest. static std::string digest (const void *data, size_t size) { SHA1 s (data, size); return s.digest(); } private: CSHA1 *m_csha1; bool m_final; }; } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_HASH_H openimageio-1.3.12~dfsg0.orig/src/include/imagebufalgo.h0000644000175000017500000022537612271062644021345 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_IMAGEBUFALGO_H #define OPENIMAGEIO_IMAGEBUFALGO_H #if defined(_MSC_VER) // Ignore warnings about DLL exported classes with member variables that are template classes. // This happens with the std::vector members of PixelStats below. # pragma warning (disable : 4251) #endif #include "imageio.h" #include "imagebuf.h" #include "fmath.h" #include "color.h" #include "thread.h" #include #ifndef __OPENCV_CORE_TYPES_H__ struct IplImage; // Forward declaration; used by Intel Image lib & OpenCV #endif OIIO_NAMESPACE_ENTER { class Filter2D; // forward declaration /// Some generalities about ImageBufAlgo functions: /// /// All IBA functions take a ROI. Only the pixels (and channels) in dst /// that are specified by the ROI will be altered; the default ROI is to /// alter all the pixels in dst. Exceptions will be noted, including /// functions that do not honor their channel range. /// /// In general, IBA functions that are passed an initialized 'dst' or /// 'result' image do not reallocate it or alter its existing pixels /// that lie outside the ROI (exceptions will be noted). If passed an /// uninitialized result image, it will be reallocatd to be the size of /// the ROI (and with float pixels). If the result image passed is /// uninitialized and also the ROI is undefined, the ROI will be the /// union of the pixel data regions of any input images. (A small /// number of IBA functions, such as fill(), have only a result image /// and no input image; in such cases, it's an error to have both an /// uninitiailized result image and an undefined ROI.) /// /// IBA functions that have an 'nthreads' parameter use it to specify /// how many threads (potentially) may be used, but it's not a /// guarantee. If nthreads == 0, it will use the global OIIO attribute /// "nthreads". If nthreads == 1, it guarantees that it will not launch /// any new threads. /// /// All IBA functions return true on success, false on error (with an /// appropriate error message set in dst). namespace ImageBufAlgo { /// Zero out (set to 0, black) the image region. /// /// Only the pixels (and channels) in dst that are specified by roi will /// be altered; the default roi is to alter all the pixels in dst. /// /// If dst is uninitialized, it will be resized to be a float ImageBuf /// large enough to hold the region specified by roi. It is an error to /// pass both an uninitialied dst and an undefined roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API zero (ImageBuf &dst, ROI roi=ROI::All(), int nthreads=0); /// Fill the image region with given channel values. Note that the /// values pointer starts with channel 0, even if the ROI indicates that /// a later channel is the first to be changed. /// /// Only the pixels (and channels) in dst that are specified by roi will /// be altered; the default roi is to alter all the pixels in dst. /// /// If dst is uninitialized, it will be resized to be a float ImageBuf /// large enough to hold the region specified by roi. It is an error to /// pass both an uninitialied dst and an undefined roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API fill (ImageBuf &dst, const float *values, ROI roi=ROI::All(), int nthreads=0); /// Fill a subregion of the volume with a checkerboard with origin /// (xoffset,yoffset,zoffset) and that alternates between color1[] and /// color2[] every width pixels in x, every height pixels in y, and /// every depth pixels in z. The pattern is definied in abstract "image /// space" independently of the pixel data window of dst or the ROI. /// /// Only the pixels (and channels) in dst that are specified by roi will /// be altered; the default roi is to alter all the pixels in dst. /// /// If dst is uninitialized, it will be resized to be a float ImageBuf /// large enough to hold the region specified by roi. It is an error /// to pass both an uninitialied dst and an undefined roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API checker (ImageBuf &dst, int width, int height, int depth, const float *color1, const float *color2, int xoffset=0, int yoffset=0, int zoffset=0, ROI roi=ROI::All(), int nthreads=0); /// Generic channel shuffling -- copy src to dst, but with channels in /// the order channelorder[0..nchannels-1]. Does not support in-place /// operation. For any channel in which channelorder[i] < 0, it will /// just make dst channel i a constant color -- set to channelvalues[i] /// (if channelvalues != NULL) or 0.0 (if channelvalues == NULL). /// /// If channelorder is NULL, it will be interpreted as /// {0, 1, ..., nchannels-1}, meaning that it's only renaming channels, /// not reordering them. /// /// If newchannelnames is not NULL, it points to an array of new channel /// names. Channels for which newchannelnames[i] is the empty string (or /// all channels, if newchannelnames == NULL) will be named as follows: /// If shuffle_channel_names is false, the resulting dst image will have /// default channel names in the usual order ("R", "G", etc.), but if /// shuffle_channel_names is true, the names will be taken from the /// corresponding channels of the source image -- be careful with this, /// shuffling both channel ordering and their names could result in no /// semantic change at all, if you catch the drift. /// /// N.B. If you are merely interested in extending the number of channels /// or truncating channels at the end (but leaving the other channels /// intact), then you should call this as: /// channels (dst, src, nchannels, NULL, NULL, NULL, true); bool OIIO_API channels (ImageBuf &dst, const ImageBuf &src, int nchannels, const int *channelorder, const float *channelvalues=NULL, const std::string *newchannelnames=NULL, bool shuffle_channel_names=false); /// Append the channels of A and B together into dst over the region of /// interest. If the region passed is uninitialized (the default), it /// will be interpreted as being the union of the pixel windows of A and /// B (and all channels of both images). If dst is not already /// initialized, it will be resized to be big enough for the region. bool OIIO_API channel_append (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi=ROI::All(), int nthreads=0); /// Set dst to the ``flattened'' composite of deep image src. That is, it /// converts a deep image to a simple flat image by front-to-back /// compositing the samples within each pixel. If src is already a non- /// deep/flat image, it will just copy pixel values from src to dst. If dst /// is not already an initialized ImageBuf, it will be sized to match src /// (but made non-deep). /// /// 'roi' specifies the region of dst's pixels which will be computed; /// existing pixels outside this range will not be altered. If not /// specified, the default ROI value will be the pixel data window of src. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. bool OIIO_API flatten (ImageBuf &dst, const ImageBuf &src, ROI roi = ROI::All(), int nthreads = 0); /// Reset dst to be the specified region of src. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API crop (ImageBuf &dst, const ImageBuf &src, ROI roi = ROI::All(), int nthreads = 0); /// Copy into dst, beginning at (xbegin,ybegin,zbegin), the pixels of /// src described by srcroi. If srcroi is ROI::All(), the entirety of src /// will be used. It will copy into channels [chbegin...], as many /// channels as are described by srcroi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API paste (ImageBuf &dst, int xbegin, int ybegin, int zbegin, int chbegin, const ImageBuf &src, ROI srcroi=ROI::All(), int nthreads = 0); /// Copy a subregion of src to the corresponding pixels of dst, /// but with the scanlines exchanged vertically. /// /// Only the pixels (and channels) in dst that are specified by roi will /// be altered; the default roi is to alter all the pixels in dst. /// If dst is uninitialized, it will be resized to be a float ImageBuf /// large enough to hold the region specified by roi. It is an error /// to pass both an uninitialied dst and an undefined roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API flip (ImageBuf &dst, const ImageBuf &src, ROI roi=ROI::All(), int nthreads=0); /// Copy a subregion of src to the corresponding pixels of dst, /// but with the columns exchanged horizontally. /// /// Only the pixels (and channels) in dst that are specified by roi will /// be altered; the default roi is to alter all the pixels in dst. /// If dst is uninitialized, it will be resized to be a float ImageBuf /// large enough to hold the region specified by roi. It is an error /// to pass both an uninitialied dst and an undefined roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API flop (ImageBuf &dst, const ImageBuf &src, ROI roi=ROI::All(), int nthreads=0); /// Copy a subregion of src to the corresponding pixels of dst, but with /// both the rows exchanged vertically and the columns exchanged /// horizontally (this is equivalent to a 180 degree rotation). /// /// Only the pixels (and channels) in dst that are specified by roi will /// be altered; the default roi is to alter all the pixels in dst. /// If dst is uninitialized, it will be resized to be a float ImageBuf /// large enough to hold the region specified by roi. It is an error /// to pass both an uninitialied dst and an undefined roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API flipflop (ImageBuf &dst, const ImageBuf &src, ROI roi=ROI::All(), int nthreads=0); /// Copy a subregion of src to the corresponding transposed (x<->y) /// pixels of dst. In other words, for all (x,y) within the ROI, set /// dst[y,x] = src[x,y]. /// /// Only the pixels (and channels) of src that are specified by roi will /// be copied to dst; the default roi is to alter all the pixels in dst. /// If dst is uninitialized, it will be resized to be an ImageBuf large /// enough to hold the region specified by the transposed roi. It is an /// error to pass both an uninitialied dst and an undefined roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API transpose (ImageBuf &dst, const ImageBuf &src, ROI roi=ROI::All(), int nthreads=0); /// Copy a subregion of src to the pixels of dst, but circularly /// shifting by the given amount. To clarify, the circular shift /// of [0,1,2,3,4,5] by +2 is [4,5,0,1,2,3]. /// /// Only the pixels (and channels) of src that are specified by roi will /// be copied to dst; the default roi is to alter all the pixels in dst. /// If dst is uninitialized, it will be resized to be an ImageBuf large /// enough to hold the region specified by the transposed roi. It is an /// error to pass both an uninitialied dst and an undefined roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API circular_shift (ImageBuf &dst, const ImageBuf &src, int xshift, int yshift, int zshift=0, ROI roi=ROI::All(), int nthreads=0); /// Copy pixels from src to dst (within the ROI), clamping the values /// as follows: /// min[0..nchans-1] specifies the minimum clamp value for each channel /// (if min is NULL, no minimum clamping is performed). /// max[0..nchans-1] specifies the maximum clamp value for each channel /// (if max is NULL, no maximum clamping is performed). /// If clampalpha01 is true, then additionally any alpha channel is /// clamped to the 0-1 range. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API clamp (ImageBuf &dst, const ImageBuf &src, const float *min=NULL, const float *max=NULL, bool clampalpha01 = false, ROI roi = ROI::All(), int nthreads = 0); /// Copy pixels from src to dst (within the ROI), clamping the values of /// as follows: /// All channels are clamped to [min,max]. /// If clampalpha01 is true, then additionally any alpha channel is /// clamped to the 0-1 range. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API clamp (ImageBuf &dst, const ImageBuf &src, float min=-std::numeric_limits::max(), float max=std::numeric_limits::max(), bool clampalpha01 = false, ROI roi = ROI::All(), int nthreads = 0); /// DEPRECATED (1.3) in-place version bool OIIO_API clamp (ImageBuf &dst, const float *min=NULL, const float *max=NULL, bool clampalpha01 = false, ROI roi = ROI::All(), int nthreads = 0); /// DEPRECATED (1.3) in-place version bool OIIO_API clamp (ImageBuf &dst, float min=-std::numeric_limits::max(), float max=std::numeric_limits::max(), bool clampalpha01 = false, ROI roi = ROI::All(), int nthreads = 0); /// For all pixels within the designated region, set dst = A + B. /// All three images must have the same number of channels. /// /// If roi is not initialized, it will be set to the union of the pixel /// regions of A and B. If dst is not initialized, it will be sized /// based on roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works only for pixel types float, half, uint8, uint16. /// It is permitted for dst and A to be the same image. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API add (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi=ROI::All(), int nthreads=0); /// For all pixels and channels of dst within the designated region, set /// dst = A + B. (B must point to nchannels floats.) /// /// If roi is not initialized, it will be set to the pixel region of A. /// If dst is not initialized, it will be sized based on roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. It is permitted for dst and A to be the /// same image. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API add (ImageBuf &dst, const ImageBuf &A, const float *B, ROI roi=ROI::All(), int nthreads=0); /// For all pixels and channels of dst within the designated region, set /// dst = A + B. (B is a single float that is added to all channels.) /// /// If roi is not initialized, it will be set to the pixel region of A. /// If dst is not initialized, it will be sized based on roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. It is permitted for dst and A to be the /// same image. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API add (ImageBuf &dst, const ImageBuf &A, float B, ROI roi=ROI::All(), int nthreads=0); /// DEPRECATED as of 1.3 -- in-place add bool OIIO_API add (ImageBuf &dst, float val, ROI roi=ROI::All(), int nthreads=0); /// DEPRECATED as of 1.3 -- in-place add bool OIIO_API add (ImageBuf &dst, const float *val, ROI roi=ROI::All(), int nthreads=0); /// For all pixels within the designated ROI, compute dst = A - B. /// All three images must have the same number of channels. /// /// If roi is not initialized, it will be set to the union of the pixel /// regions of A and B. If dst is not initialized, it will be sized /// based on roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works only for pixel types float, half, uint8, uint16. /// It is permitted for dst and A to be the same image. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API sub (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi=ROI::All(), int nthreads=0); /// For all pixels and channels of dst within the designated region, set /// dst = A - B. (B must point to nchannels floats.) /// /// If roi is not initialized, it will be set to the pixel region of A. /// If dst is not initialized, it will be sized based on roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. It is permitted for dst and A to be the /// same image. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API sub (ImageBuf &dst, const ImageBuf &A, const float *B, ROI roi=ROI::All(), int nthreads=0); /// For all pixels and channels of dst within the designated region, set /// dst = A - B. (B is a single float that is added to all channels.) /// /// If roi is not initialized, it will be set to the pixel region of A. /// If dst is not initialized, it will be sized based on roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. It is permitted for dst and A to be the /// same image. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API sub (ImageBuf &dst, const ImageBuf &A, float B, ROI roi=ROI::All(), int nthreads=0); /// For all pixels within the designated ROI, compute dst = A * B. /// All three images must have the same number of channels. /// /// If roi is not initialized, it will be set to the union of the pixel /// regions of A and B. If dst is not initialized, it will be sized /// based on roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works only for pixel types float, half, uint8, uint16. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API mul (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi=ROI::All(), int nthreads=0); /// For all pixels and channels of dst within region roi (defaulting to /// all the defined pixels of R), set R = A * B. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. It is permissible for dst and A to be /// the same image. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API mul (ImageBuf &dst, const ImageBuf &A, float B, ROI roi=ROI::All(), int nthreads=0); /// DEPRECATED in-place version. (1.3) bool OIIO_API mul (ImageBuf &dst, float val, ROI roi=ROI::All(), int nthreads=0); /// For all pixels and channels of dst within region roi (defaulting to /// all the defined pixels of R), set R = A * B. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API mul (ImageBuf &dst, const ImageBuf &A, const float *B, ROI roi=ROI::All(), int nthreads=0); /// DEPRECATED in-place version. (1.3) bool OIIO_API mul (ImageBuf &dst, const float *val, ROI roi=ROI::All(), int nthreads=0); /// Converts a multi-channel image into a 1-channel image via a weighted /// sum of channels. For each pixel of src within the designated ROI /// (defaulting to all of src, if not defined), sum the channels /// designated by roi and store the result in channel 0 of dst. If /// weights is not NULL, weight[i] will provide a per-channel weight /// (rather than defaulting to 1.0 for each channel). /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API channel_sum (ImageBuf &dst, const ImageBuf &src, const float *weights=NULL, ROI roi=ROI::All(), int nthreads=0); /// For all pixels and color channels within region roi (defaulting to all /// the defined pixels of dst), copy pixels from src to dst, rescaling their /// range with a logarithmic transformation. Alpha and z channels are not /// transformed. If dst is not already defined and allocated, it will be /// sized based on src and roi. /// /// If useluma is true, the luma of channels [roi.chbegin..roi.chbegin+2] /// (presumed to be R, G, and B) are used to compute a single scale /// factor for all color channels, rather than scaling all channels /// individually (which could result in a color shift). /// /// Some image operations (such as resizing with a "good" filter that /// contains negative lobes) can have objectionable artifacts when applied /// to images with very high-contrast regions involving extra bright pixels /// (such as highlights in HDR captured or rendered images). By compressing /// the range pixel values, then performing the operation, then expanding /// the range of the result again, the result can be much more pleasing /// (even if not exactly correct). /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API rangecompress (ImageBuf &dst, const ImageBuf &src, bool useluma = false, ROI roi = ROI::All(), int nthreads=0); /// rangeexpand is the opposite operation of rangecompress -- rescales /// the logarithmic color channel values back to a linear response. bool OIIO_API rangeexpand (ImageBuf &dst, const ImageBuf &src, bool useluma = false, ROI roi = ROI::All(), int nthreads=0); /// DEPRECATED in-place version (1.3) bool OIIO_API rangecompress (ImageBuf &dst, bool useluma = false, ROI roi = ROI::All(), int nthreads=0); /// DEPRECATED in-place version (1.3) bool OIIO_API rangeexpand (ImageBuf &dst, bool useluma = false, ROI roi = ROI::All(), int nthreads=0); /// Copy pixels within the ROI from src to dst, applying a color transform. /// /// If dst is not yet initialized, it will be allocated to the same /// size as specified by roi. If roi is not defined it will be all /// of dst, if dst is defined, or all of src, if dst is not yet defined. /// /// In-place operations (dst == src) are supported. /// /// If unpremult is true, unpremultiply before color conversion, then /// premultiply after the color conversion. You may want to use this /// flag if your image contains an alpha channel. /// /// Works with all data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API colorconvert (ImageBuf &dst, const ImageBuf &src, const char *from, const char *to, bool unpremult=false, ROI roi=ROI::All(), int nthreads=0); /// Copy pixels within the ROI from src to dst, applying an OpenColorIO /// "look" transform. /// /// If dst is not yet initialized, it will be allocated to the same /// size as specified by roi. If roi is not defined it will be all /// of dst, if dst is defined, or all of src, if dst is not yet defined. /// /// In-place operations (dst == src) are supported. /// /// If unpremult is true, unpremultiply before color conversion, then /// premultiply after the color conversion. You may want to use this /// flag if your image contains an alpha channel. /// /// Works with all data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API ociolook (ImageBuf &dst, const ImageBuf &src, const char *looks, const char *from, const char *to, bool unpremult=false, bool inverse=false, const char *key=NULL, const char *value=NULL, ROI roi=ROI::All(), int nthreads=0); /// Copy pixels within the ROI from src to dst, applying an OpenColorIO /// "display" transform. If from or looks are NULL, it will not /// override the look or source color space (subtly different than /// passing "", the empty string, which means to use no look or source /// space). /// /// If dst is not yet initialized, it will be allocated to the same /// size as specified by roi. If roi is not defined it will be all /// of dst, if dst is defined, or all of src, if dst is not yet defined. /// In-place operations (dst == src) are supported. /// /// If unpremult is true, unpremultiply before color conversion, then /// premultiply after the color conversion. You may want to use this /// flag if your image contains an alpha channel. /// /// Works with all data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API ociodisplay (ImageBuf &dst, const ImageBuf &src, const char *display, const char *view, const char *from=NULL, const char *looks=NULL, bool unpremult=false, const char *key=NULL, const char *value=NULL, ROI roi=ROI::All(), int nthreads=0); /// Copy pixels within the ROI from src to dst, applying a color transform. /// /// If dst is not yet initialized, it will be allocated to the same /// size as specified by roi. If roi is not defined it will be all /// of dst, if dst is defined, or all of src, if dst is not yet defined. /// /// In-place operations (dst == src) are supported. /// /// If unpremult is true, unpremultiply before color conversion, then /// premultiply after the color conversion. You may want to use this /// flag if your image contains an alpha channel. /// /// Works with all data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API colorconvert (ImageBuf &dst, const ImageBuf &src, const ColorProcessor *processor, bool unpremult, ROI roi=ROI::All(), int nthreads=0); /// Apply a color transform in-place to just one color: /// color[0..nchannels-1]. nchannels should either be 3 or 4 (if 4, the /// last channel is alpha). /// /// If unpremult is true, unpremultiply before color conversion, then /// premultiply after the color conversion. You'll may want to use this /// flag if your image contains an alpha channel. bool OIIO_API colorconvert (float *color, int nchannels, const ColorProcessor *processor, bool unpremult); /// Copy pixels from dst to src, and in the process divide all color /// channels (those not alpha or z) by the alpha value, to "un-premultiply" /// them. This presumes that the image starts of as "associated alpha" /// a.k.a. "premultipled." The alterations are restricted to the pixels and /// channels of the supplied ROI (which defaults to all of src). Pixels in /// which the alpha channel is 0 will not be modified (since the operation /// is undefined in that case). This is just a copy if there is no /// identified alpha channel (and a no-op if dst and src are the same /// image). /// /// Works with all data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API unpremult (ImageBuf &dst, const ImageBuf &src, ROI roi = ROI::All(), int nthreads = 0); /// DEPRECATED (1.3) in-place version bool OIIO_API unpremult (ImageBuf &dst, ROI roi = ROI::All(), int nthreads = 0); /// Copy pixels from dst to src, and in the process multiply all color /// channels (those not alpha or z) by the alpha value, to "-premultiply" /// them. This presumes that the image starts off as "unassociated alpha" /// a.k.a. "non-premultiplied." The alterations are restricted to the /// pixels and channels of the supplied ROI (which defaults to all of src). /// Pixels in which the alpha channel is 0 will not be modified (since the /// operation is undefined in that case). This is just a copy if there is /// no identified alpha channel (and a no-op if dst and src are the same /// image). /// /// For all dst pixels and channels within the ROI, divide all color /// channels (those not alpha or z) by the alpha, to "un-premultiply" /// them. /// /// Works with all data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API premult (ImageBuf &dst, const ImageBuf &src, ROI roi = ROI::All(), int nthreads = 0); /// DEPRECATED (1.3) in-place version bool OIIO_API premult (ImageBuf &dst, ROI roi = ROI::All(), int nthreads = 0); struct OIIO_API PixelStats { std::vector min; std::vector max; std::vector avg; std::vector stddev; std::vector nancount; std::vector infcount; std::vector finitecount; std::vector sum, sum2; // for intermediate calculation }; /// Compute statistics about the ROI of the specified image. Upon success, /// the returned vectors will have size == src.nchannels(). /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API computePixelStats (PixelStats &stats, const ImageBuf &src, ROI roi=ROI::All(), int nthreads=0); /// Struct holding all the results computed by ImageBufAlgo::compare(). /// (maxx,maxy,maxz,maxc) gives the pixel coordintes (x,y,z) and color /// channel of the pixel that differed maximally between the two images. /// nwarn and nfail are the number of "warnings" and "failures", /// respectively. struct CompareResults { double meanerror, rms_error, PSNR, maxerror; int maxx, maxy, maxz, maxc; imagesize_t nwarn, nfail; }; /// Numerically compare two images. The difference threshold (for any /// individual color channel in any pixel) for a "failure" is /// failthresh, and for a "warning" is warnthresh. The results are /// stored in result. If roi is defined, pixels will be compared for /// the pixel and channel range that is specified. If roi is not /// defined, the comparison will be for all channels, on the union of /// the defined pixel windows of the two images (for either image, /// undefined pixels will be assumed to be black). /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. /// /// Return true on success, false on error. bool OIIO_API compare (const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, CompareResults &result, ROI roi = ROI::All(), int nthreads=0); /// Compare two images using Hector Yee's perceptual metric, returning /// the number of pixels that fail the comparison. Only the first three /// channels (or first three channels specified by roi) are compared. /// Free parameters are the ambient luminance in the room and the field /// of view of the image display; our defaults are probably reasonable /// guesses for an office environment. The 'result' structure will /// store the maxerror, and the maxx, maxy, maxz of the pixel that /// failed most severely. (The other fields of the CompareResults /// are not used for Yee comparison.) /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. But it's basically meaningless if the /// first three channels aren't RGB in a linear color space that sort /// of resembles AdobeRGB. /// /// Return true on success, false on error. int OIIO_API compare_Yee (const ImageBuf &A, const ImageBuf &B, CompareResults &result, float luminance = 100, float fov = 45, ROI roi = ROI::All(), int nthreads = 0); /// Do all pixels within the ROI have the same values for channels /// [roi.chbegin..roi.chend-1]? If so, return true and store that color /// in color[chbegin...chend-1] (if color != NULL); otherwise return /// false. If roi is not defined (the default), it will be understood /// to be all of the defined pixels and channels of source. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. bool OIIO_API isConstantColor (const ImageBuf &src, float *color = NULL, ROI roi = ROI::All(), int nthreads=0); /// Does the requested channel have a given value over the ROI? (For /// this function, the ROI's chbegin/chend are ignored.) Return true if /// so, otherwise return false. If roi is not defined (the default), it /// will be understood to be all of the defined pixels and channels of /// source. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. bool OIIO_API isConstantChannel (const ImageBuf &src, int channel, float val, ROI roi = ROI::All(), int nthreads = 0); /// Is the image monochrome within the ROI, i.e., for all pixels within /// the region, do all channels [roi.chbegin, roi.chend) have the same /// value? If roi is not defined (the default), it will be understood /// to be all of the defined pixels and channels of source. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. bool OIIO_API isMonochrome (const ImageBuf &src, ROI roi = ROI::All(), int nthreads = 0); /// Count how many pixels in the ROI match a list of colors. /// /// The colors to match are in colors[0..nchans-1], /// colors[nchans..2*nchans-1], and so on, a total of ncolors /// consecutive colors of nchans each. /// /// eps[0..nchans-1] are the error tolerances for a match, for each /// channel. Setting eps[c] = numeric_limits::max() will /// effectively make it ignore the channel. Passing eps == NULL will be /// interpreted as a tolerance of 0.001 for all channels (requires exact /// matches for 8 bit images, but allows a wee bit of imprecision for /// float images. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. /// /// Upon success, return true and store the number of pixels that /// matched each color count[..ncolors-1]. If there is an error, /// returns false and sets an appropriate error message set in src. bool OIIO_API color_count (const ImageBuf &src, imagesize_t *count, int ncolors, const float *color, const float *eps=NULL, ROI roi=ROI::All(), int nthreads=0); /// Count how many pixels in the ROI are outside the value range. /// low[0..nchans-1] and high[0..nchans-1] are the low and high /// acceptable values for each color channel. /// /// The number of pixels containing values that fall below the lower /// bound will be stored in *lowcount, the number of pixels containing /// values that fall above the upper bound will be stored in *highcount, /// and the number of pixels for which all channels fell within the /// bounds will be stored in *inrangecount. Any of these may be NULL, /// which simply means that the counts need not be collected or stored. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. /// /// Return true if the operation can be performed, false if there is /// some sort of error (and sets an appropriate error message in src). bool OIIO_API color_range_check (const ImageBuf &src, imagesize_t *lowcount, imagesize_t *highcount, imagesize_t *inrangecount, const float *low, const float *high, ROI roi=ROI::All(), int nthreads=0); /// Find the minimal rectangular region within roi (which defaults to /// the entire pixel data window of src) that consists of nonzero pixel /// values. In other words, gives the region that is a "shrink-wraps" /// of src to exclude black border pixels. Note that if the entire /// image was black, the ROI returned will contain no pixels. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works for all pixel types. OIIO_API ROI nonzero_region (const ImageBuf &src, ROI roi=ROI::All(), int nthreads=0); /// Compute the SHA-1 byte hash for all the pixels in the specifed /// region of the image. If blocksize > 0, the function will compute /// separate SHA-1 hashes of each 'blocksize' batch of scanlines, then /// return a hash of the individual hashes. This is just as strong a /// hash, but will NOT match a single hash of the entire image /// (blocksize==0). But by breaking up the hash into independent /// blocks, we can parallelize across multiple threads, given by /// nthreads (if nthreads is 0, it will use the global OIIO thread /// count). The 'extrainfo' provides additional text that will be /// incorporated into the hash. std::string OIIO_API computePixelHashSHA1 (const ImageBuf &src, const std::string &extrainfo = "", ROI roi = ROI::All(), int blocksize = 0, int nthreads=0); /// Set dst, over the region of interest, to be a resized version of the /// corresponding portion of src (mapping such that the "full" image /// window of each correspond to each other, regardless of resolution). /// /// The filter is used to weight the src pixels falling underneath it for /// each dst pixel. The caller may specify a reconstruction filter by name /// and width (expressed in pixels unts of the dst image), or resize() will /// choose a reasonable default high-quality default filter (blackman-harris /// when upsizing, lanczos3 when downsizing) if the empty string is passed /// or if filterwidth is 0. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API resize (ImageBuf &dst, const ImageBuf &src, const std::string &filtername = "", float filterwidth = 0.0f, ROI roi = ROI::All(), int nthreads = 0); /// Set dst, over the region of interest, to be a resized version of the /// corresponding portion of src (mapping such that the "full" image /// window of each correspond to each other, regardless of resolution). /// /// The caller may explicitly pass a reconstruction filter, or resize() /// will choose a reasonable default if NULL is passed. The filter is /// used to weight the src pixels falling underneath it for each dst /// pixel; the filter's size is expressed in pixel units of the dst /// image. If no filter is supplied, a default medium-quality /// (triangle) filter will be used. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API resize (ImageBuf &dst, const ImageBuf &src, Filter2D *filter, ROI roi = ROI::All(), int nthreads = 0); /// Set dst, over the region of interest, to be a resampled version of the /// corresponding portion of src (mapping such that the "full" image /// window of each correspond to each other, regardless of resolution). /// /// Unlike ImageBufAlgo::resize(), resample does not take a filter; it /// just samples either with a bilinear interpolation (if interpolate is /// true, the default) or uses the single "closest" pixel (if /// interpolate is false). This makes it a lot faster than a proper /// resize(), though obviously with lower quality (aliasing when /// downsizing, pixel replication when upsizing). /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API resample (ImageBuf &dst, const ImageBuf &src, bool interpolate = true, ROI roi = ROI::All(), int nthreads = 0); /// Replace the given ROI of dst with the convolution of src and /// a kernel. If roi is not defined, it defaults to the full size /// of dst (or src, if dst was uninitialized). If dst is uninitialized, /// it will be allocated to be the size specified by roi. If /// normalized is true, the kernel will be normalized for the /// convolution, otherwise the original values will be used. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on any pixel data type for dst and src, but kernel MUST be /// a float image. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API convolve (ImageBuf &dst, const ImageBuf &src, const ImageBuf &kernel, bool normalize = true, ROI roi = ROI::All(), int nthreads = 0); /// Initialize dst to be a 1-channel FLOAT image of the named kernel. /// The size of the dst image will be big enough to contain the kernel /// given its size (width x height) and rounded up to odd resolution so /// that the center of the kernel can be at the center of the middle /// pixel. The kernel image will be offset so that its center is at the /// (0,0) coordinate. If normalize is true, the values will be /// normalized so that they sum to 1.0. /// /// If depth > 1, a volumetric kernel will be created. Use with caution! /// /// Kernel names can be: "gaussian", "sharp-gaussian", "box", /// "triangle", "blackman-harris", "mitchell", "b-spline", "catmull-rom", /// "lanczos3", "disk", "binomial." /// /// Note that "catmull-rom" and "lanczos3" are fixed-size kernels that /// don't scale with the width, and are therefore probably less useful /// in most cases. /// bool OIIO_API make_kernel (ImageBuf &dst, const char *name, float width, float height, float depth = 1.0f, bool normalize = true); /// Replace the given ROI of dst with a sharpened version of the /// corresponding region of src using the ``unsharp mask'' technique. /// Unsharp masking basically works by first blurring the image (low /// pass filter), subtracting this from the original image, then /// adding the residual back to the original to emphasize the edges. /// Roughly speaking, /// dst = src + contrast * thresh(src - blur(src)) /// /// The specific blur can be selected by kernel name and width. The /// contrast is a multiplier on the overall sharpening effect. The /// thresholding step causes all differences less than 'threshold' to be /// squashed to zero, which can be useful for suppressing sharpening of /// low-contrast details (like noise) but allow sharpening of /// higher-contrast edges. /// /// If roi is not defined, it defaults to the full size of dst (or src, /// if dst was undefined). If dst is uninitialized, it will be /// allocated to be the size specified by roi. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API unsharp_mask (ImageBuf &dst, const ImageBuf &src, const char *kernel="gaussian", float width = 3.0f, float contrast = 1.0f, float threshold = 0.0f, ROI roi = ROI::All(), int nthreads = 0); /// Take the discrete Fourier transform (DFT) of the section of src /// denoted by roi, store it in dst. If roi is not defined, it will be /// all of src's pixels. Only one channel of src may be FFT'd at a /// time, so it will be the first channel described by roi (or, again, /// channel 0 if roi is undefined). If not already in the correct /// format, dst will be re-allocated to be a 2-channel float buffer of /// size width x height, with channel 0 being the "real" part and /// channel 1 being the the "imaginary" part. The values returned are /// actually the unitary DFT, meaning that it is scaled by 1/sqrt(npixels). /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data type for src; dst will always be reallocated /// as FLOAT. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API fft (ImageBuf &dst, const ImageBuf &src, ROI roi = ROI::All(), int nthreads = 0); /// Take the inverse discrete Fourier transform of the section of src /// denoted by roi, store it in dst. If roi is not defined, it will be /// all of src's pixels. /// /// Src MUST be a 2-channel float image, and is assumed to be a complex /// frequency-domain signal with the "real" component in channel 0 and /// the "imaginary" component in channel 1. Dst will end up being a /// float image of one channel (the real component is kept, the /// imaginary component of the spatial-domain will be discarded). /// Just as with fft(), the ifft() function is dealing with the unitary /// DFT, so it is scaled by 1/sqrt(npixels). /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API ifft (ImageBuf &dst, const ImageBuf &src, ROI roi = ROI::All(), int nthreads = 0); enum OIIO_API NonFiniteFixMode { NONFINITE_NONE = 0, ///< Do nothing NONFINITE_BLACK = 1, ///< Replace nonfinite pixels with black NONFINITE_BOX3 = 2, ///< Replace nonfinite pixels with 3x3 finite average }; /// Copy the values of src (within the ROI) to dst, while repairing any /// non-finite (NaN/Inf) pixels. If pixelsFound is not NULL, store in it the /// number of pixels that contained non-finite value. It is permissible /// to operate in-place (with src and dst referring to the same image). /// /// How the non-finite values are repaired is specified by one of the /// following modes: /// NONFINITE_NONE do not alter the pixels (but do count the number /// of nonfinite pixels in *pixelsFixed, if non-NULL). /// NONFINITE_BLACK change non-finite values to 0. /// NONFINITE_BOX3 replace non-finite values by the average of any /// finite pixels within a 3x3 window. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types, though it's just a copy for images with /// pixel data types that cannot represent NaN or Inf values. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API fixNonFinite (ImageBuf &dst, const ImageBuf &src, NonFiniteFixMode mode=NONFINITE_BOX3, int *pixelsFixed = NULL, ROI roi = ROI::All(), int nthreads = 0); /// DEPRECATED (1.3) in-place version bool OIIO_API fixNonFinite (ImageBuf &dst, NonFiniteFixMode mode=NONFINITE_BOX3, int *pixelsFixed = NULL, ROI roi = ROI::All(), int nthreads = 0); /// Fill the holes using a push-pull technique. The src image must have /// an alpha channel. The dst image will end up with a copy of src, but /// will have an alpha of 1.0 everywhere, and any place where the alpha /// of src was < 1, dst will have a pixel color that is a plausible /// "filling" of the original alpha hole. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. /// /// Return true on success, false on error (with an appropriate error /// message set in dst). bool OIIO_API fillholes_pushpull (ImageBuf &dst, const ImageBuf &src, ROI roi = ROI::All(), int nthreads = 0); /// Convert an IplImage, used by OpenCV and Intel's Image Libray, and /// set ImageBuf dst to be the same image (copying the pixels). If /// convert is not set to UNKNOWN, try to establish dst as holding that /// data type and convert the IplImage data. Return true if ok, false /// if it couldn't figure out how to make the conversion from IplImage /// to ImageBuf. If OpenImageIO was compiled without OpenCV support, /// this function will return false without modifying dst. bool OIIO_API from_IplImage (ImageBuf &dst, const IplImage *ipl, TypeDesc convert=TypeDesc::UNKNOWN); /// Construct an IplImage*, used by OpenCV and Intel's Image Library, /// that is equivalent to the ImageBuf src. If it is not possible, or /// if OpenImageIO was compiled without OpenCV support, then return /// NULL. The ownership of the IplImage is fully transferred to the /// calling application. OIIO_API IplImage* to_IplImage (const ImageBuf &src); /// Capture a still image from a designated camera. If able to do so, /// store the image in dst and return true. If there is no such device, /// or support for camera capture is not available (such as if OpenCV /// support was not enabled at compile time), return false and do not /// alter dst. bool OIIO_API capture_image (ImageBuf &dst, int cameranum = 0, TypeDesc convert=TypeDesc::UNKNOWN); /// Set dst to the composite of A over B using the Porter/Duff definition /// of "over", returning true upon success and false for any of a /// variety of failures (as described below). /// /// A and B (and dst, if already defined/allocated) must have valid alpha /// channels identified by their ImageSpec alpha_channel field. If A or /// B do not have alpha channels (as determined by those rules) or if /// the number of non-alpha channels do not match between A and B, /// over() will fail, returning false. /// /// If dst is not already an initialized ImageBuf, it will be sized to /// encompass the minimal rectangular pixel region containing the union /// of the defined pixels of A and B, and with a number of channels /// equal to the number of non-alpha channels of A and B, plus an alpha /// channel. However, if dst is already initialized, it will not be /// resized, and the "over" operation will apply to its existing pixel /// data window. In this case, dst must have an alpha channel designated /// and must have the same number of non-alpha channels as A and B, /// otherwise it will fail, returning false. /// /// 'roi' specifies the region of dst's pixels which will be computed; /// existing pixels outside this range will not be altered. If not /// specified, the default ROI value will be interpreted as a request to /// apply "A over B" to the entire region of dst's pixel data. /// /// A, B, and dst need not perfectly overlap in their pixel data windows; /// pixel values of A or B that are outside their respective pixel data /// window will be treated as having "zero" (0,0,0...) value. /// /// The nthreads parameter specifies how many threads (potentially) may /// be used, but it's not a guarantee. If nthreads == 0, it will use /// the global OIIO attribute "nthreads". If nthreads == 1, it /// guarantees that it will not launch any new threads. /// /// Works on all pixel data types. bool OIIO_API over (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi = ROI::All(), int nthreads = 0); /// Just like ImageBufAlgo::over(), but inputs A and B must have /// designated 'z' channels, and on a pixel-by-pixel basis, the z values /// will determine which of A or B will be considered the foreground or /// background (lower z is foreground). If z_zeroisinf is true, then /// z=0 values will be treated as if they are infinitely far away. bool OIIO_API zover (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, bool z_zeroisinf = false, ROI roi = ROI::All(), int nthreads = 0); /// Render a text string into image dst, essentially doing an "over" of /// the character into the existing pixel data. The baseline of the /// first character will start at position (x,y). The font is given by /// fontname as a full pathname to the font file (defaulting to some /// reasonable system font if not supplied at all), and with a nominal /// height of fontsize (in pixels). The characters will be drawn in /// opaque white (1.0,1.0,...) in all channels, unless textcolor is /// supplied (and is expected to point to a float array of length at /// least equal to R.spec().nchannels). bool OIIO_API render_text (ImageBuf &dst, int x, int y, const std::string &text, int fontsize=16, const std::string &fontname="", const float *textcolor = NULL); /// ImageBufAlgo::histogram -------------------------------------------------- /// Parameters: /// src - Input image that contains the one channel to be histogramed. /// src must contain float pixel data and have at least 1 channel, /// but it can have more. /// channel - Only this channel in src will be histogramed. It must satisfy /// 0 <= channel < src.nchannels(). /// histogram - Clear old content and store the histogram here. /// bins - Number of bins must be at least 1. /// min, max - Pixel values outside of the min->max range are not used for /// computing the histogram. If min max. /// roi - Only pixels in this region of the image are histogramed. If /// roi is not defined then the full size image will be /// histogramed. /// -------------------------------------------------------------------------- bool OIIO_API histogram (const ImageBuf &src, int channel, std::vector &histogram, int bins=256, float min=0, float max=1, imagesize_t *submin=NULL, imagesize_t *supermax=NULL, ROI roi=ROI::All()); /// ImageBufAlgo::histogram_draw --------------------------------------------- /// Parameters: /// dst - The histogram will be drawn in the image dst. which must /// have only 1 channel with float pixel data, and width equal /// to the number of bins, that is elements in histogram. /// histogram - The histogram to be drawn, must have at least 1 bin. /// -------------------------------------------------------------------------- bool OIIO_API histogram_draw (ImageBuf &dst, const std::vector &histogram); enum OIIO_API MakeTextureMode { MakeTxTexture, MakeTxShadow, MakeTxEnvLatl, MakeTxEnvLatlFromLightProbe, _MakeTxLast }; /// Turn an image into a tiled, MIP-mapped, texture file and write it to /// disk (outputfilename). The 'mode' describes what type of texture /// file we are creating and may be one of: /// MakeTxTexture Ordinary 2D texture /// MakeTxEnvLatl Latitude-longitude environment map /// MakeTxEnvLatlFromLightProbe Latitude-longitude environment map /// constructed from a "light probe" image. /// /// If the outstream pointer is not NULL, it should point to a stream /// (for example, &std::out, or a pointer to a local std::stringstream /// to capture output), which is where console output and error messages /// will be deposited. /// /// The 'config' is an ImageSpec that contains all the information and /// special instructions for making the texture. Anything set in config /// (format, tile size, or named metadata) will take precedence over /// whatever is specified by the input file itself. Additionally, named /// metadata that starts with "maketx:" will not be output to the file /// itself, but may contain instructions controlling how the texture is /// created. The full list of supported configuration options is: /// /// Named fields: /// format Data format of the texture file (default: UNKNOWN = /// same format as the input) /// tile_width Preferred tile size (default: 64x64x1) /// tile_height /// tile_depth /// Metadata in config.extra_attribs: /// compression (string) Default: "zip" /// fovcot (float) Default: aspect ratio of the image resolution /// planarconfig (string) Default: "separate" /// worldtocamera (matrix) World-to-camera matrix of the view. /// worldtoscreen (matrix) World-to-screen space matrix of the view. /// wrapmodes (string) Default: "black,black" /// maketx:verbose (int) How much detail should go to outstream (0). /// maketx:stats (int) If nonzero, print stats to outstream (0). /// maketx:resize (int) If nonzero, resize to power of 2. (0) /// maketx:nomipmap (int) If nonzero, only output the top MIP level (0). /// maketx:updatemode (int) If nonzero, write new output only if the /// output file doesn't already exist, or is /// older than the input file. (0) /// maketx:constant_color_detect (int) /// If nonzero, detect images that are entirely /// one color, and change them to be low /// resolution (default: 0). /// maketx:monochrome_detect (int) /// If nonzero, change RGB images which have /// R==G==B everywhere to single-channel /// grayscale (default: 0). /// maketx:opaquedetect (int) /// If nonzero, drop the alpha channel if alpha /// is 1.0 in all pixels (default: 0). /// maketx:unpremult (int) If nonzero, unpremultiply color by alpha before /// color conversion, then multiply by alpha /// after color conversion (default: 0). /// maketx:incolorspace (string) /// maketx:outcolorspace (string) /// These two together will apply a color conversion /// (with OpenColorIO, if compiled). Default: "" /// maketx:checknan (int) If nonzero, will consider it an error if the /// input image has any NaN pixels. (0) /// maketx:fixnan (string) If set to "black" or "box3", will attempt /// to repair any NaN pixels found in the /// input image (default: "none"). /// maketx:set_full_to_pixels (int) /// If nonzero, doctors the full/display window /// of the texture to be identical to the /// pixel/data window and reset the origin /// to 0,0 (default: 0). /// maketx:filtername (string) /// If set, will specify the name of a high-quality /// filter to use when resampling for MIPmap /// levels. Default: "", use bilinear resampling. /// maketx:highlightcomp (int) /// If nonzero, performs highlight compensation -- /// range compression and expansion around /// the resize, plus clamping negative plxel /// values to zero. This reduces ringing when /// using filters with negative lobes on HDR /// images. /// maketx:nchannels (int) If nonzero, will specify how many channels /// the output texture should have, padding with /// 0 values or dropping channels, if it doesn't /// the number of channels in the input. /// (default: 0, meaning keep all input channels) /// maketx:channelnames (string) /// If set, overrides the channel names of the /// output image (comma-separated). /// maketx:fileformatname (string) /// If set, will specify the output file format. /// (default: "", meaning infer the format from /// the output filename) /// maketx:prman_metadata (int) /// If set, output some metadata that PRMan will /// need for its textures. (0) /// maketx:oiio_options (int) /// (Deprecated; all are handled by default) /// maketx:prman_options (int) /// If nonzero, override a whole bunch of settings /// as needed to make textures that are /// compatible with PRMan. (0) /// maketx:mipimages (string) /// Semicolon-separated list of alternate images /// to be used for individual MIPmap levels, /// rather than simply downsizing. (default: "") /// maketx:full_command_line (string) /// The command or program used to generate this /// call, will be embedded in the metadata. /// (default: "") /// maketx:ignore_unassoc (int) /// If nonzero, will disbelieve any evidence that /// the input image is unassociated alpha. (0) /// maketx:read_local_MB (int) /// If nonzero, will read the full input file locally /// if it is smaller than this threshold. Zero /// causes the system to make a good guess at /// a reasonable threshold (e.g. 1 GB). (0) /// maketx:forcefloat (int) /// Forces a conversion through float data for /// the sake of ImageBuf math. (1) /// maketx:hash (int) /// Compute the sha1 hash of the file in parallel. (1) /// maketx:allow_pixel_shift (int) /// Allow up to a half pixel shift per mipmap level. /// The fastest path may result in a slight shift /// in the image, accumulated for each mip level /// with an odd resolution. (0) /// bool OIIO_API make_texture (MakeTextureMode mode, const ImageBuf &input, const std::string &outputfilename, const ImageSpec &config, std::ostream *outstream = NULL); /// Version of make_texture that starts with a filename and reads the input /// from that file, rather than being given an ImageBuf directly. bool OIIO_API make_texture (MakeTextureMode mode, const std::string &filename, const std::string &outputfilename, const ImageSpec &config, std::ostream *outstream = NULL); /// Version of make_texture that takes multiple filenames (reserved for /// future expansion, such as assembling several faces into a cube map). bool OIIO_API make_texture (MakeTextureMode mode, const std::vector &filenames, const std::string &outputfilename, const ImageSpec &config, std::ostream *outstream = NULL); } // end namespace ImageBufAlgo } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_IMAGEBUFALGO_H openimageio-1.3.12~dfsg0.orig/src/include/ustring.h0000644000175000017500000005727412271062644020416 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Define the ustring class, unique strings with efficient storage and /// very fast copy and comparison. ///////////////////////////////////////////////////////////////////////////// /// \class ustring /// /// A ustring is an alternative to char* or std::string for storing /// strings, in which the character sequence is unique (allowing many /// speed advantages for assignment, equality testing, and inequality /// testing). /// /// The implementation is that behind the scenes there is a hash set of /// allocated strings, so the characters of each string are unique. A /// ustring itself is a pointer to the characters of one of these canonical /// strings. Therefore, assignment and equality testing is just a single /// 32- or 64-bit int operation, the only mutex is when a ustring is /// created from raw characters, and the only malloc is the first time /// each canonical ustring is created. /// /// The internal table also contains a std::string version and the length /// of the string, so converting a ustring to a std::string (via /// ustring::string()) or querying the number of characters (via /// ustring::size() or ustring::length()) is extremely inexpensive, and does /// not involve creation/allocation of a new std::string or a call to /// strlen. /// /// We try very hard to completely mimic the API of std::string, /// including all the constructors, comparisons, iterations, etc. Of /// course, the charaters of a ustring are non-modifiable, so we do not /// replicate any of the non-const methods of std::string. But in most /// other ways it looks and acts like a std::string and so most templated /// algorthms that would work on a "const std::string &" will also work /// on a ustring. /// /// Usage guidelines: /// /// Compared to standard strings, ustrings have several advantages: /// /// - Each individual ustring is very small -- in fact, we guarantee that /// a ustring is the same size and memory layout as an ordinary char*. /// - Storage is frugal, since there is only one allocated copy of each /// unique character sequence, throughout the lifetime of the program. /// - Assignment from one ustring to another is just copy of the pointer; /// no allocation, no character copying, no reference counting. /// - Equality testing (do the strings contain the same characters) is /// a single operation, the comparison of the pointer. /// - Memory allocation only occurs when a new ustring is construted from /// raw characters the FIRST time -- subsequent constructions of the /// same string just finds it in the canonial string set, but doesn't /// need to allocate new storage. Destruction of a ustring is trivial, /// there is no de-allocation because the canonical version stays in /// the set. Also, therefore, no user code mistake can lead to /// memory leaks. /// /// But there are some problems, too. Canonical strings are never freed /// from the table. So in some sense all the strings "leak", but they /// only leak one copy for each unique string that the program ever comes /// across. Also, creation of unique strings from raw characters is more /// expensive than for standard strings, due to hashing, table queries, /// and other overhead. /// /// On the whole, ustrings are a really great string representation /// - if you tend to have (relatively) few unique strings, but many /// copies of those strings; /// - if the creation of strings from raw characters is relatively /// rare compared to copying or comparing to existing strings; /// - if you tend to make the same strings over and over again, and /// if it's relatively rare that a single unique character sequence /// is used only once in the entire lifetime of the program; /// - if your most common string operations are assignment and equality /// testing and you want them to be as fast as possible; /// - if you are doing relatively little character-by-character assembly /// of strings, string concatenation, or other "string manipulation" /// (other than equality testing). /// /// ustrings are not so hot /// - if your program tends to have very few copies of each character /// sequence over the entire lifetime of the program; /// - if your program tends to generate a huge variety of unique /// strings over its lifetime, each of which is used only a short /// time and then discarded, never to be needed again; /// - if you don't need to do a lot of string assignment or equality /// testing, but lots of more complex string manipulation. /// ///////////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_USTRING_H #define OPENIMAGEIO_USTRING_H #if defined(_MSC_VER) // Ignore warnings about DLL exported classes with member variables that are template classes. // This happens with the std::string empty_std_string static member variable of ustring below. // Also remove a warning about the strncpy function not being safe and deprecated in MSVC. // There is no equivalent safe and portable function and trying to fix this is more trouble than // its worth. (see http://stackoverflow.com/questions/858252/alternatives-to-ms-strncpy-s) # pragma warning (disable : 4251 4996) #endif #include #include #include #include "export.h" #include "strutil.h" #include "dassert.h" #include "version.h" #ifndef NULL #define NULL 0 #endif OIIO_NAMESPACE_ENTER { class OIIO_API ustring { public: typedef char value_type; typedef value_type * pointer; typedef value_type & reference; typedef const value_type & const_reference; typedef size_t size_type; static const size_type npos = static_cast(-1); typedef std::string::const_iterator const_iterator; typedef std::string::const_reverse_iterator const_reverse_iterator; /// Default ctr for ustring -- make an empty string. /// ustring (void) : m_chars(NULL) { } /// Construct a ustring from a null-terminated C string (char *). /// explicit ustring (const char *str) { m_chars = str ? make_unique(str) : NULL; } /// Construct a ustring from at most n characters of str, starting at /// position pos. ustring (const char *str, size_type pos, size_type n) : m_chars (make_unique(std::string(str,pos,n).c_str())) { } /// Construct a ustring from the first n characters of str. /// ustring (const char *str, size_type n) : m_chars (make_unique(std::string(str,n).c_str())) { } /// Construct a ustring from n copies of character c. /// ustring (size_type n, char c) : m_chars (make_unique(std::string(n,c).c_str())) { } /// Construct a ustring from a C++ std::string. /// explicit ustring (const std::string &str) { *this = ustring(str.c_str()); } /// Construct a ustring from an indexed substring of a std::string. /// ustring (const std::string &str, size_type pos, size_type n=npos) : m_chars (make_unique(std::string(str, pos, n).c_str())) { } /// Copy construct a ustring from another ustring. /// ustring (const ustring &str) : m_chars(str.m_chars) { } /// Construct a ustring from an indexed substring of a ustring. /// ustring (const ustring &str, size_type pos, size_type n=npos) : m_chars (make_unique(std::string(str.c_str(),pos,n).c_str())) { } /// ustring destructor. /// ~ustring () { } /// Assign a ustring to *this. /// const ustring & assign (const ustring &str) { m_chars = str.m_chars; return *this; } /// Assign a substring of a ustring to *this. /// const ustring & assign (const ustring &str, size_type pos, size_type n=npos) { *this = ustring(str,pos,n); return *this; } /// Assign a std::string to *this. /// const ustring & assign (const std::string &str) { assign (str.c_str()); return *this; } /// Assign a substring of a std::string to *this. /// const ustring & assign (const std::string &str, size_type pos, size_type n=npos) { *this = ustring(str,pos,n); return *this; } /// Assign a null-terminated C string (char*) to *this. /// const ustring & assign (const char *str) { m_chars = str ? make_unique(str) : NULL; return *this; } /// Assign the first n characters of str to *this. /// const ustring & assign (const char *str, size_type n) { *this = ustring(str,n); return *this; } /// Assign n copies of c to *this. /// const ustring & assign (size_type n, char c) { *this = ustring(n,c); return *this; } /// Assign a ustring to another ustring. /// const ustring & operator= (const ustring &str) { return assign(str); } /// Assign a null-terminated C string (char *) to a ustring. /// const ustring & operator= (const char *str) { return assign(str); } /// Assign a C++ std::string to a ustring. /// const ustring & operator= (const std::string &str) { return assign(str); } /// Assign a single char to a ustring. /// const ustring & operator= (char c) { char s[2]; s[0] = c; s[1] = 0; *this = ustring (s); return *this; } /// Return a C string representation of a ustring. /// const char *c_str () const { return m_chars; } /// Return a C string representation of a ustring. /// const char *data () const { return c_str(); } /// Return a C++ std::string representation of a ustring. /// const std::string & string () const { if (m_chars) { const TableRep *rep = (const TableRep *)m_chars - 1; return rep->str; } else return empty_std_string; } /// Reset to an empty string. /// void clear (void) { m_chars = NULL; } /// Return the number of characters in the string. /// size_t length (void) const { if (! m_chars) return 0; const TableRep *rep = ((const TableRep *)m_chars) - 1; return rep->length; } /// Return a hashed version of the string /// size_t hash (void) const { if (! m_chars) return 0; const TableRep *rep = ((const TableRep *)m_chars) - 1; return rep->hashed; } /// Return the number of characters in the string. /// size_t size (void) const { return length(); } /// Is the string empty -- i.e., is it the NULL pointer or does it /// point to an empty string? bool empty (void) const { return (size() == 0); } /// Cast to int, which is interpreted as testing whether it's not an /// empty string. This allows you to write "if (t)" with the same /// semantics as if it were a char*. operator int (void) const { return !empty(); } /// Return a const_iterator that references the first character of /// the string. const_iterator begin () const { return string().begin(); } /// Return a const_iterator that references the end of a traversal /// of the characters of the string. const_iterator end () const { return string().end(); } /// Return a const_reverse_iterator that references the last /// character of the string. const_reverse_iterator rbegin () const { return string().rbegin(); } /// Return a const_reverse_iterator that references the end of /// a reverse traversal of the characters of the string. const_reverse_iterator rend () const { return string().rend(); } /// Return a reference to the character at the given position. /// Note that it's up to the caller to be sure pos is within the /// size of the string. const_reference operator[] (size_type pos) const { return c_str()[pos]; } /// Dump into character array s the characters of this ustring, /// beginning with position pos and copying at most n characters. size_type copy (char* s, size_type n, size_type pos = 0) const { if (m_chars == NULL) { s[0] = 0; return 0; } char *c = strncpy (s, c_str()+pos, n); return (size_type)(c-s); } /// Returns a substring of the ustring object consisting of n /// characters starting at position pos. ustring substr (size_type pos = 0, size_type n = npos) const { return ustring (*this, pos, n); } // FIXME: implement compare. size_type find(const ustring &str, size_type pos = 0) const { return string().find(str.string(), pos); } size_type find(const std::string &str, size_type pos = 0) const { return string().find(str, pos); } size_type find(const char *s, size_type pos, size_type n) const { return string().find(s, pos, n); } size_type find(const char *s, size_type pos = 0) const { return string().find(s, pos); } size_type find(char c, size_type pos = 0) const { return string().find(c, pos); } size_type rfind(const ustring &str, size_type pos = npos) const { return string().rfind(str.string(), pos); } size_type rfind(const std::string &str, size_type pos = npos) const { return string().rfind(str, pos); } size_type rfind(const char *s, size_type pos, size_type n) const { return string().rfind(s, pos, n); } size_type rfind(const char *s, size_type pos = npos) const { return string().rfind(s, pos); } size_type rfind(char c, size_type pos = npos) const { return string().rfind(c, pos); } size_type find_first_of(const ustring &str, size_type pos = 0) const { return string().find_first_of(str.string(), pos); } size_type find_first_of(const std::string &str, size_type pos = 0) const { return string().find_first_of(str, pos); } size_type find_first_of(const char *s, size_type pos, size_type n) const { return string().find_first_of(s, pos, n); } size_type find_first_of(const char *s, size_type pos = 0) const { return string().find_first_of(s, pos); } size_type find_first_of(char c, size_type pos = 0) const { return string().find_first_of(c, pos); } size_type find_last_of(const ustring &str, size_type pos = npos) const { return string().find_last_of(str.string(), pos); } size_type find_last_of(const std::string &str, size_type pos = npos) const { return string().find_last_of(str, pos); } size_type find_last_of(const char *s, size_type pos, size_type n) const { return string().find_last_of(s, pos, n); } size_type find_last_of(const char *s, size_type pos = npos) const { return string().find_last_of(s, pos); } size_type find_last_of(char c, size_type pos = npos) const { return string().find_last_of(c, pos); } size_type find_first_not_of(const ustring &str, size_type pos = 0) const { return string().find_first_not_of(str.string(), pos); } size_type find_first_not_of(const std::string &str, size_type pos = 0) const { return string().find_first_not_of(str, pos); } size_type find_first_not_of(const char *s, size_type pos, size_type n) const { return string().find_first_not_of(s, pos, n); } size_type find_first_not_of(const char *s, size_type pos = 0) const { return string().find_first_not_of(s, pos); } size_type find_first_not_of(char c, size_type pos = 0) const { return string().find_first_not_of(c, pos); } size_type find_last_not_of(const ustring &str, size_type pos = npos) const { return string().find_last_not_of(str.string(), pos); } size_type find_last_not_of(const std::string &str, size_type pos = npos) const { return string().find_last_not_of(str, pos); } size_type find_last_not_of(const char *s, size_type pos, size_type n) const { return string().find_last_not_of(s, pos, n); } size_type find_last_not_of(const char *s, size_type pos = npos) const { return string().find_last_not_of(s, pos); } size_type find_last_not_of(char c, size_type pos = npos) const { return string().find_last_not_of(c, pos); } /// Return 0 if *this is lexicographically equal to str, -1 if /// *this is lexicographically earlier than str, 1 if *this is /// lexicographically after str. int compare (const ustring& str) const { return (c_str() == str.c_str()) ? 0 : strcmp (c_str() ? c_str() : "", str.c_str() ? str.c_str() : ""); } /// Return 0 if *this is lexicographically equal to str, -1 if /// *this is lexicographically earlier than str, 1 if *this is /// lexicographically after str. int compare (const std::string& str) const { return strcmp (c_str() ? c_str() : "", str.c_str()); } /// Return 0 if a is lexicographically equal to b, -1 if a is /// lexicographically earlier than b, 1 if a is lexicographically /// after b. friend int compare (const std::string& a, const ustring &b) { return strcmp (a.c_str(), b.c_str() ? b.c_str() : ""); } /// Test two ustrings for equality -- are they comprised of the same /// sequence of characters. Note that because ustrings are unique, /// this is a trivial pointer comparison, not a char-by-char loop as /// would be the case with a char* or a std::string. bool operator== (const ustring &str) const { return c_str() == str.c_str(); } /// Test two ustrings for inequality -- are they comprised of different /// sequences of characters. Note that because ustrings are unique, /// this is a trivial pointer comparison, not a char-by-char loop as /// would be the case with a char* or a std::string. bool operator!= (const ustring &str) const { return c_str() != str.c_str(); } /// Test a ustring (*this) for lexicographic equality with std::string /// x. bool operator== (const std::string &x) const { return compare(x) == 0; } /// Test for lexicographic equality between std::string a and ustring /// b. friend bool operator== (const std::string &a, const ustring &b) { return b.compare(a) == 0; } /// Test a ustring (*this) for lexicographic inequality with /// std::string x. bool operator!= (const std::string &x) const { return compare(x) != 0; } /// Test for lexicographic inequality between std::string a and /// ustring b. friend bool operator!= (const std::string &a, const ustring &b) { return b.compare(a) != 0; } /// Test for lexicographic 'less', comes in handy for lots of STL /// containers and algorithms. bool operator< (const ustring &x) const { return compare(x) < 0; } /// Construct a ustring in a printf-like fashion. In other words, /// something like: /// ustring s = ustring::format ("blah %d %g", (int)foo, (float)bar); /// /// The printf argument list is fully typesafe via tinyformat; format /// conceptually has the signature /// /// static ustring format (const char *fmt, ...); TINYFORMAT_WRAP_FORMAT (static ustring, format, /**/, std::ostringstream msg;, msg, return ustring(msg.str());) /// Generic stream output of a ustring. /// friend std::ostream & operator<< (std::ostream &out, const ustring &str) { if (str.c_str()) out << str.c_str(); return out; } /// Return the statistics output as a string. /// static std::string getstats (bool verbose = true); /// Return the amount of memory consumed by the ustring table. /// static size_t memory (); /// Given a null-terminated string, return a pointer to the unique /// version kept in the internal table (creating a new table entry /// if we haven't seen this sequence of characters before). /// N.B.: this is equivalent to ustring(str).c_str(). It's also the /// routine that is used directly by ustring's internals to generate /// the canonical unique copy of the characters. static const char * make_unique (const char *str); /// Is this character pointer a unique ustring representation of /// those characters? Useful for diagnostics and debugging. static bool is_unique (const char *str) { return str == NULL || make_unique(str) == str; } /// Create a ustring from characters guaranteed to already be /// ustring-clean, without having to run through the hash yet /// again. Use with extreme caution!!! static ustring from_unique (const char *unique) { DASSERT (is_unique(unique)); // DEBUG builds -- check it! ustring u; u.m_chars = unique; return u; } private: // Individual ustring internal representation -- the unique characters. // const char *m_chars; public: // Representation within the hidden string table -- DON'T EVER CREATE // ONE OF THESE YOURSELF! // The characters are found directly after the rep. So that means that // if you know the rep, the chars are at (char *)(rep+1), and if you // know the chars, the rep is at ((TableRep *)chars - 1). struct TableRep { size_t hashed; // precomputed Hash value std::string str; // String representation size_t length; // Length of the string; must be right before cap size_t dummy_capacity; // Dummy field! must be right before refcount int dummy_refcount; // Dummy field! must be right before chars TableRep (const char *s, size_t len); ~TableRep (); const char *c_str () const { return (const char *)(this + 1); } }; private: static std::string empty_std_string; }; /// Functor class to use as a hasher when you want to make a hash_map or /// hash_set using ustring as a key. class ustringHash { public: size_t operator() (const ustring &s) const { return s.hash(); } }; /// Case-insensitive comparison of ustrings. For speed, this always /// uses a static locale that doesn't require a mutex lock. inline bool iequals (ustring a, ustring b) { return a==b || Strutil::iequals(a.string(), b.string()); } inline bool iequals (ustring a, const std::string &b) { return Strutil::iequals(a.string(), b); } inline bool iequals (const std::string &a, ustring b) { return Strutil::iequals(a, b.string()); } } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_USTRING_H openimageio-1.3.12~dfsg0.orig/src/include/pugixml.hpp0000644000175000017500000012670612271062644020745 0ustar mfvmfv/** * pugixml parser - version 1.2 * -------------------------------------------------------- * Copyright (C) 2006-2012, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end * of this file. * * This work is based on the pugxml parser, which is: * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) */ #ifndef PUGIXML_VERSION // Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons # define PUGIXML_VERSION 120 #endif // Include user configuration file (this can define various configuration macros) #include "pugiconfig.hpp" #ifndef HEADER_PUGIXML_HPP #define HEADER_PUGIXML_HPP #include "version.h" #define USING_OIIO_PUGI 1 // Include stddef.h for size_t and ptrdiff_t #include // Include exception header for XPath #if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS) # include #endif // Include STL headers #ifndef PUGIXML_NO_STL # include # include # include #endif // Macro for deprecated features #ifndef PUGIXML_DEPRECATED # if defined(__GNUC__) # define PUGIXML_DEPRECATED __attribute__((deprecated)) # elif defined(_MSC_VER) && _MSC_VER >= 1300 # define PUGIXML_DEPRECATED __declspec(deprecated) # else # define PUGIXML_DEPRECATED # endif #endif // If no API is defined, assume default #ifndef PUGIXML_API # define PUGIXML_API #endif // If no API for classes is defined, assume default #ifndef PUGIXML_CLASS # define PUGIXML_CLASS PUGIXML_API #endif // If no API for functions is defined, assume default #ifndef PUGIXML_FUNCTION # define PUGIXML_FUNCTION PUGIXML_API #endif // Character interface macros #ifdef PUGIXML_WCHAR_MODE # define PUGIXML_TEXT(t) L ## t # define PUGIXML_CHAR wchar_t #else # define PUGIXML_TEXT(t) t # define PUGIXML_CHAR char #endif OIIO_NAMESPACE_ENTER { namespace pugi { // Character type used for all internal storage and operations; depends on PUGIXML_WCHAR_MODE typedef PUGIXML_CHAR char_t; #ifndef PUGIXML_NO_STL // String type used for operations that work with STL string; depends on PUGIXML_WCHAR_MODE typedef std::basic_string, std::allocator > string_t; #endif } // The PugiXML namespace namespace pugi { // Tree node types enum xml_node_type { node_null, // Empty (null) node handle node_document, // A document tree's absolute root node_element, // Element tag, i.e. '' node_pcdata, // Plain character data, i.e. 'text' node_cdata, // Character data, i.e. '' node_comment, // Comment tag, i.e. '' node_pi, // Processing instruction, i.e. '' node_declaration, // Document declaration, i.e. '' node_doctype // Document type declaration, i.e. '' }; // Parsing options // Minimal parsing mode (equivalent to turning all other flags off). // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed. const unsigned int parse_minimal = 0x0000; // This flag determines if processing instructions (node_pi) are added to the DOM tree. This flag is off by default. const unsigned int parse_pi = 0x0001; // This flag determines if comments (node_comment) are added to the DOM tree. This flag is off by default. const unsigned int parse_comments = 0x0002; // This flag determines if CDATA sections (node_cdata) are added to the DOM tree. This flag is on by default. const unsigned int parse_cdata = 0x0004; // This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree. // This flag is off by default; turning it on usually results in slower parsing and more memory consumption. const unsigned int parse_ws_pcdata = 0x0008; // This flag determines if character and entity references are expanded during parsing. This flag is on by default. const unsigned int parse_escapes = 0x0010; // This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default. const unsigned int parse_eol = 0x0020; // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default. const unsigned int parse_wconv_attribute = 0x0040; // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default. const unsigned int parse_wnorm_attribute = 0x0080; // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default. const unsigned int parse_declaration = 0x0100; // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default. const unsigned int parse_doctype = 0x0200; // This flag determines if plain character data (node_pcdata) that is the only child of the parent node and that consists only // of whitespace is added to the DOM tree. // This flag is off by default; turning it on may result in slower parsing and more memory consumption. const unsigned int parse_ws_pcdata_single = 0x0400; // The default parsing mode. // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded, // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol; // The full parsing mode. // Nodes of all types are added to the DOM tree, character/reference entities are expanded, // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype; // These flags determine the encoding of input data for XML document enum xml_encoding { encoding_auto, // Auto-detect input encoding using BOM or < / class xml_object_range { public: typedef It const_iterator; xml_object_range(It b, It e): _begin(b), _end(e) { } It begin() const { return _begin; } It end() const { return _end; } private: It _begin, _end; }; // Writer interface for node printing (see xml_node::print) class PUGIXML_CLASS xml_writer { public: virtual ~xml_writer() {} // Write memory chunk into stream/file/whatever virtual void write(const void* data, size_t size) = 0; }; // xml_writer implementation for FILE* class PUGIXML_CLASS xml_writer_file: public xml_writer { public: // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio xml_writer_file(void* file); virtual void write(const void* data, size_t size); private: void* file; }; #ifndef PUGIXML_NO_STL // xml_writer implementation for streams class PUGIXML_CLASS xml_writer_stream: public xml_writer { public: // Construct writer from an output stream object xml_writer_stream(std::basic_ostream >& stream); xml_writer_stream(std::basic_ostream >& stream); virtual void write(const void* data, size_t size); private: std::basic_ostream >* narrow_stream; std::basic_ostream >* wide_stream; }; #endif // A light-weight handle for manipulating attributes in DOM tree class PUGIXML_CLASS xml_attribute { friend class xml_attribute_iterator; friend class xml_node; private: xml_attribute_struct* _attr; typedef void (*unspecified_bool_type)(xml_attribute***); public: // Default constructor. Constructs an empty attribute. xml_attribute(); // Constructs attribute from internal pointer explicit xml_attribute(xml_attribute_struct* attr); // Safe bool conversion operator operator unspecified_bool_type() const; // Borland C++ workaround bool operator!() const; // Comparison operators (compares wrapped attribute pointers) bool operator==(const xml_attribute& r) const; bool operator!=(const xml_attribute& r) const; bool operator<(const xml_attribute& r) const; bool operator>(const xml_attribute& r) const; bool operator<=(const xml_attribute& r) const; bool operator>=(const xml_attribute& r) const; // Check if attribute is empty bool empty() const; // Get attribute name/value, or "" if attribute is empty const char_t* name() const; const char_t* value() const; // Get attribute value, or the default value if attribute is empty const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; // Get attribute value as a number, or the default value if conversion did not succeed or attribute is empty int as_int(int def = 0) const; unsigned int as_uint(unsigned int def = 0) const; double as_double(double def = 0) const; float as_float(float def = 0) const; // Get attribute value as bool (returns true if first character is in '1tTyY' set), or the default value if attribute is empty bool as_bool(bool def = false) const; // Set attribute name/value (returns false if attribute is empty or there is not enough memory) bool set_name(const char_t* rhs); bool set_value(const char_t* rhs); // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") bool set_value(int rhs); bool set_value(unsigned int rhs); bool set_value(double rhs); bool set_value(bool rhs); // Set attribute value (equivalent to set_value without error checking) xml_attribute& operator=(const char_t* rhs); xml_attribute& operator=(int rhs); xml_attribute& operator=(unsigned int rhs); xml_attribute& operator=(double rhs); xml_attribute& operator=(bool rhs); // Get next/previous attribute in the attribute list of the parent node xml_attribute next_attribute() const; xml_attribute previous_attribute() const; // Get hash value (unique for handles to the same object) size_t hash_value() const; // Get internal pointer xml_attribute_struct* internal_object() const; }; #ifdef __BORLANDC__ // Borland C++ workaround bool PUGIXML_FUNCTION operator&&(const xml_attribute& lhs, bool rhs); bool PUGIXML_FUNCTION operator||(const xml_attribute& lhs, bool rhs); #endif // A light-weight handle for manipulating nodes in DOM tree class PUGIXML_CLASS xml_node { friend class xml_attribute_iterator; friend class xml_node_iterator; friend class xml_named_node_iterator; protected: xml_node_struct* _root; typedef void (*unspecified_bool_type)(xml_node***); public: // Default constructor. Constructs an empty node. xml_node(); // Constructs node from internal pointer explicit xml_node(xml_node_struct* p); // Safe bool conversion operator operator unspecified_bool_type() const; // Borland C++ workaround bool operator!() const; // Comparison operators (compares wrapped node pointers) bool operator==(const xml_node& r) const; bool operator!=(const xml_node& r) const; bool operator<(const xml_node& r) const; bool operator>(const xml_node& r) const; bool operator<=(const xml_node& r) const; bool operator>=(const xml_node& r) const; // Check if node is empty. bool empty() const; // Get node type xml_node_type type() const; // Get node name/value, or "" if node is empty or it has no name/value const char_t* name() const; const char_t* value() const; // Get attribute list xml_attribute first_attribute() const; xml_attribute last_attribute() const; // Get children list xml_node first_child() const; xml_node last_child() const; // Get next/previous sibling in the children list of the parent node xml_node next_sibling() const; xml_node previous_sibling() const; // Get parent node xml_node parent() const; // Get root of DOM tree this node belongs to xml_node root() const; // Get text object for the current node xml_text text() const; // Get child, attribute or next/previous sibling with the specified name xml_node child(const char_t* name) const; xml_attribute attribute(const char_t* name) const; xml_node next_sibling(const char_t* name) const; xml_node previous_sibling(const char_t* name) const; // Get child value of current node; that is, value of the first child node of type PCDATA/CDATA const char_t* child_value() const; // Get child value of child with specified name. Equivalent to child(name).child_value(). const char_t* child_value(const char_t* name) const; // Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value) bool set_name(const char_t* rhs); bool set_value(const char_t* rhs); // Add attribute with specified name. Returns added attribute, or empty attribute on errors. xml_attribute append_attribute(const char_t* name); xml_attribute prepend_attribute(const char_t* name); xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr); xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr); // Add a copy of the specified attribute. Returns added attribute, or empty attribute on errors. xml_attribute append_copy(const xml_attribute& proto); xml_attribute prepend_copy(const xml_attribute& proto); xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr); xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr); // Add child node with specified type. Returns added node, or empty node on errors. xml_node append_child(xml_node_type type = node_element); xml_node prepend_child(xml_node_type type = node_element); xml_node insert_child_after(xml_node_type type, const xml_node& node); xml_node insert_child_before(xml_node_type type, const xml_node& node); // Add child element with specified name. Returns added node, or empty node on errors. xml_node append_child(const char_t* name); xml_node prepend_child(const char_t* name); xml_node insert_child_after(const char_t* name, const xml_node& node); xml_node insert_child_before(const char_t* name, const xml_node& node); // Add a copy of the specified node as a child. Returns added node, or empty node on errors. xml_node append_copy(const xml_node& proto); xml_node prepend_copy(const xml_node& proto); xml_node insert_copy_after(const xml_node& proto, const xml_node& node); xml_node insert_copy_before(const xml_node& proto, const xml_node& node); // Remove specified attribute bool remove_attribute(const xml_attribute& a); bool remove_attribute(const char_t* name); // Remove specified child bool remove_child(const xml_node& n); bool remove_child(const char_t* name); // Find attribute using predicate. Returns first attribute for which predicate returned true. template xml_attribute find_attribute(Predicate pred) const { if (!_root) return xml_attribute(); for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute()) if (pred(attrib)) return attrib; return xml_attribute(); } // Find child node using predicate. Returns first child for which predicate returned true. template xml_node find_child(Predicate pred) const { if (!_root) return xml_node(); for (xml_node node = first_child(); node; node = node.next_sibling()) if (pred(node)) return node; return xml_node(); } // Find node from subtree using predicate. Returns first node from subtree (depth-first), for which predicate returned true. template xml_node find_node(Predicate pred) const { if (!_root) return xml_node(); xml_node cur = first_child(); while (cur._root && cur._root != _root) { if (pred(cur)) return cur; if (cur.first_child()) cur = cur.first_child(); else if (cur.next_sibling()) cur = cur.next_sibling(); else { while (!cur.next_sibling() && cur._root != _root) cur = cur.parent(); if (cur._root != _root) cur = cur.next_sibling(); } } return xml_node(); } // Find child node by attribute name/value xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const; xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const; #ifndef PUGIXML_NO_STL // Get the absolute node path from root as a text string. string_t path(char_t delimiter = '/') const; #endif // Search for a node by path consisting of node names and . or .. elements. xml_node first_element_by_path(const char_t* path, char_t delimiter = '/') const; // Recursively traverse subtree with xml_tree_walker bool traverse(xml_tree_walker& walker); #ifndef PUGIXML_NO_XPATH // Select single node by evaluating XPath query. Returns first node from the resulting node set. xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const; xpath_node select_single_node(const xpath_query& query) const; // Select node set by evaluating XPath query xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const; xpath_node_set select_nodes(const xpath_query& query) const; #endif // Print subtree using a writer object void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; #ifndef PUGIXML_NO_STL // Print subtree to stream void print(std::basic_ostream >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; void print(std::basic_ostream >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const; #endif // Child nodes iterators typedef xml_node_iterator iterator; iterator begin() const; iterator end() const; // Attribute iterators typedef xml_attribute_iterator attribute_iterator; attribute_iterator attributes_begin() const; attribute_iterator attributes_end() const; // Range-based for support xml_object_range children() const; xml_object_range children(const char_t* name) const; xml_object_range attributes() const; // Get node offset in parsed file/string (in char_t units) for debugging purposes ptrdiff_t offset_debug() const; // Get hash value (unique for handles to the same object) size_t hash_value() const; // Get internal pointer xml_node_struct* internal_object() const; }; #ifdef __BORLANDC__ // Borland C++ workaround bool PUGIXML_FUNCTION operator&&(const xml_node& lhs, bool rhs); bool PUGIXML_FUNCTION operator||(const xml_node& lhs, bool rhs); #endif // A helper for working with text inside PCDATA nodes class PUGIXML_CLASS xml_text { friend class xml_node; xml_node_struct* _root; typedef void (*unspecified_bool_type)(xml_text***); explicit xml_text(xml_node_struct* root); xml_node_struct* _data_new(); xml_node_struct* _data() const; public: // Default constructor. Constructs an empty object. xml_text(); // Safe bool conversion operator operator unspecified_bool_type() const; // Borland C++ workaround bool operator!() const; // Check if text object is empty bool empty() const; // Get text, or "" if object is empty const char_t* get() const; // Get text, or the default value if object is empty const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; // Get text as a number, or the default value if conversion did not succeed or object is empty int as_int(int def = 0) const; unsigned int as_uint(unsigned int def = 0) const; double as_double(double def = 0) const; float as_float(float def = 0) const; // Get text as bool (returns true if first character is in '1tTyY' set), or the default value if object is empty bool as_bool(bool def = false) const; // Set text (returns false if object is empty or there is not enough memory) bool set(const char_t* rhs); // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") bool set(int rhs); bool set(unsigned int rhs); bool set(double rhs); bool set(bool rhs); // Set text (equivalent to set without error checking) xml_text& operator=(const char_t* rhs); xml_text& operator=(int rhs); xml_text& operator=(unsigned int rhs); xml_text& operator=(double rhs); xml_text& operator=(bool rhs); // Get the data node (node_pcdata or node_cdata) for this object xml_node data() const; }; #ifdef __BORLANDC__ // Borland C++ workaround bool PUGIXML_FUNCTION operator&&(const xml_text& lhs, bool rhs); bool PUGIXML_FUNCTION operator||(const xml_text& lhs, bool rhs); #endif // Child node iterator (a bidirectional iterator over a collection of xml_node) class PUGIXML_CLASS xml_node_iterator { friend class xml_node; private: mutable xml_node _wrap; xml_node _parent; xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent); public: // Iterator traits typedef ptrdiff_t difference_type; typedef xml_node value_type; typedef xml_node* pointer; typedef xml_node& reference; #ifndef PUGIXML_NO_STL typedef std::bidirectional_iterator_tag iterator_category; #endif // Default constructor xml_node_iterator(); // Construct an iterator which points to the specified node xml_node_iterator(const xml_node& node); // Iterator operators bool operator==(const xml_node_iterator& rhs) const; bool operator!=(const xml_node_iterator& rhs) const; xml_node& operator*() const; xml_node* operator->() const; const xml_node_iterator& operator++(); xml_node_iterator operator++(int); const xml_node_iterator& operator--(); xml_node_iterator operator--(int); }; // Attribute iterator (a bidirectional iterator over a collection of xml_attribute) class PUGIXML_CLASS xml_attribute_iterator { friend class xml_node; private: mutable xml_attribute _wrap; xml_node _parent; xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent); public: // Iterator traits typedef ptrdiff_t difference_type; typedef xml_attribute value_type; typedef xml_attribute* pointer; typedef xml_attribute& reference; #ifndef PUGIXML_NO_STL typedef std::bidirectional_iterator_tag iterator_category; #endif // Default constructor xml_attribute_iterator(); // Construct an iterator which points to the specified attribute xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent); // Iterator operators bool operator==(const xml_attribute_iterator& rhs) const; bool operator!=(const xml_attribute_iterator& rhs) const; xml_attribute& operator*() const; xml_attribute* operator->() const; const xml_attribute_iterator& operator++(); xml_attribute_iterator operator++(int); const xml_attribute_iterator& operator--(); xml_attribute_iterator operator--(int); }; // Named node range helper class xml_named_node_iterator { public: // Iterator traits typedef ptrdiff_t difference_type; typedef xml_node value_type; typedef xml_node* pointer; typedef xml_node& reference; #ifndef PUGIXML_NO_STL typedef std::forward_iterator_tag iterator_category; #endif // Default constructor xml_named_node_iterator(); // Construct an iterator which points to the specified node xml_named_node_iterator(const xml_node& node, const char_t* name); // Iterator operators bool operator==(const xml_named_node_iterator& rhs) const; bool operator!=(const xml_named_node_iterator& rhs) const; xml_node& operator*() const; xml_node* operator->() const; const xml_named_node_iterator& operator++(); xml_named_node_iterator operator++(int); private: mutable xml_node _node; const char_t* _name; }; // Abstract tree walker class (see xml_node::traverse) class PUGIXML_CLASS xml_tree_walker { friend class xml_node; private: int _depth; protected: // Get current traversal depth int depth() const; public: xml_tree_walker(); virtual ~xml_tree_walker(); // Callback that is called when traversal begins virtual bool begin(xml_node& node); // Callback that is called for each node traversed virtual bool for_each(xml_node& node) = 0; // Callback that is called when traversal ends virtual bool end(xml_node& node); }; // Parsing status, returned as part of xml_parse_result object enum xml_parse_status { status_ok = 0, // No error status_file_not_found, // File was not found during load_file() status_io_error, // Error reading from file/stream status_out_of_memory, // Could not allocate memory status_internal_error, // Internal error occurred status_unrecognized_tag, // Parser could not determine tag type status_bad_pi, // Parsing error occurred while parsing document declaration/processing instruction status_bad_comment, // Parsing error occurred while parsing comment status_bad_cdata, // Parsing error occurred while parsing CDATA section status_bad_doctype, // Parsing error occurred while parsing document type declaration status_bad_pcdata, // Parsing error occurred while parsing PCDATA section status_bad_start_element, // Parsing error occurred while parsing start element tag status_bad_attribute, // Parsing error occurred while parsing element attribute status_bad_end_element, // Parsing error occurred while parsing end element tag status_end_element_mismatch // There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag) }; // Parsing result struct PUGIXML_CLASS xml_parse_result { // Parsing status (see xml_parse_status) xml_parse_status status; // Last parsed offset (in char_t units from start of input data) ptrdiff_t offset; // Source document encoding xml_encoding encoding; // Default constructor, initializes object to failed state xml_parse_result(); // Cast to bool operator operator bool() const; // Get error description const char* description() const; }; // Document class (DOM tree root) class PUGIXML_CLASS xml_document: public xml_node { private: char_t* _buffer; char _memory[192]; // Non-copyable semantics xml_document(const xml_document&); const xml_document& operator=(const xml_document&); void create(); void destroy(); xml_parse_result load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own); public: // Default constructor, makes empty document xml_document(); // Destructor, invalidates all node/attribute handles to this document ~xml_document(); // Removes all nodes, leaving the empty document void reset(); // Removes all nodes, then copies the entire contents of the specified document void reset(const xml_document& proto); #ifndef PUGIXML_NO_STL // Load document from stream. xml_parse_result load(std::basic_istream >& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); xml_parse_result load(std::basic_istream >& stream, unsigned int options = parse_default); #endif // Load document from zero-terminated string. No encoding conversions are applied. xml_parse_result load(const char_t* contents, unsigned int options = parse_default); // Load document from file xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); // Load document from buffer. Copies/converts the buffer, so it may be deleted or changed after the function returns. xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed. xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore). xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); // Save XML document to writer (semantics is slightly different from xml_node::print, see documentation for details). void save(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; #ifndef PUGIXML_NO_STL // Save XML document to stream (semantics is slightly different from xml_node::print, see documentation for details). void save(std::basic_ostream >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; void save(std::basic_ostream >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const; #endif // Save XML to file bool save_file(const char* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; bool save_file(const wchar_t* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; // Get document element xml_node document_element() const; }; #ifndef PUGIXML_NO_XPATH // XPath query return type enum xpath_value_type { xpath_type_none, // Unknown type (query failed to compile) xpath_type_node_set, // Node set (xpath_node_set) xpath_type_number, // Number xpath_type_string, // String xpath_type_boolean // Boolean }; // XPath parsing result struct PUGIXML_CLASS xpath_parse_result { // Error message (0 if no error) const char* error; // Last parsed offset (in char_t units from string start) ptrdiff_t offset; // Default constructor, initializes object to failed state xpath_parse_result(); // Cast to bool operator operator bool() const; // Get error description const char* description() const; }; // A single XPath variable class PUGIXML_CLASS xpath_variable { friend class xpath_variable_set; protected: xpath_value_type _type; xpath_variable* _next; xpath_variable(); // Non-copyable semantics xpath_variable(const xpath_variable&); xpath_variable& operator=(const xpath_variable&); public: // Get variable name const char_t* name() const; // Get variable type xpath_value_type type() const; // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error bool get_boolean() const; double get_number() const; const char_t* get_string() const; const xpath_node_set& get_node_set() const; // Set variable value; no type conversion is performed, false is returned on type mismatch error bool set(bool value); bool set(double value); bool set(const char_t* value); bool set(const xpath_node_set& value); }; // A set of XPath variables class PUGIXML_CLASS xpath_variable_set { private: xpath_variable* _data[64]; // Non-copyable semantics xpath_variable_set(const xpath_variable_set&); xpath_variable_set& operator=(const xpath_variable_set&); xpath_variable* find(const char_t* name) const; public: // Default constructor/destructor xpath_variable_set(); ~xpath_variable_set(); // Add a new variable or get the existing one, if the types match xpath_variable* add(const char_t* name, xpath_value_type type); // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch bool set(const char_t* name, bool value); bool set(const char_t* name, double value); bool set(const char_t* name, const char_t* value); bool set(const char_t* name, const xpath_node_set& value); // Get existing variable by name xpath_variable* get(const char_t* name); const xpath_variable* get(const char_t* name) const; }; // A compiled XPath query object class PUGIXML_CLASS xpath_query { private: void* _impl; xpath_parse_result _result; typedef void (*unspecified_bool_type)(xpath_query***); // Non-copyable semantics xpath_query(const xpath_query&); xpath_query& operator=(const xpath_query&); public: // Construct a compiled object from XPath expression. // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors. explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0); // Destructor ~xpath_query(); // Get query expression return type xpath_value_type return_type() const; // Evaluate expression as boolean value in the specified context; performs type conversion if necessary. // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. bool evaluate_boolean(const xpath_node& n) const; // Evaluate expression as double value in the specified context; performs type conversion if necessary. // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. double evaluate_number(const xpath_node& n) const; #ifndef PUGIXML_NO_STL // Evaluate expression as string value in the specified context; performs type conversion if necessary. // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. string_t evaluate_string(const xpath_node& n) const; #endif // Evaluate expression as string value in the specified context; performs type conversion if necessary. // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero). // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. // If PUGIXML_NO_EXCEPTIONS is defined, returns empty set instead. size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const; // Evaluate expression as node set in the specified context. // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead. xpath_node_set evaluate_node_set(const xpath_node& n) const; // Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode) const xpath_parse_result& result() const; // Safe bool conversion operator operator unspecified_bool_type() const; // Borland C++ workaround bool operator!() const; }; #ifndef PUGIXML_NO_EXCEPTIONS // XPath exception class class PUGIXML_CLASS xpath_exception: public std::exception { private: xpath_parse_result _result; public: // Construct exception from parse result explicit xpath_exception(const xpath_parse_result& result); // Get error message virtual const char* what() const throw(); // Get parse result const xpath_parse_result& result() const; }; #endif // XPath node class (either xml_node or xml_attribute) class PUGIXML_CLASS xpath_node { private: xml_node _node; xml_attribute _attribute; typedef void (*unspecified_bool_type)(xpath_node***); public: // Default constructor; constructs empty XPath node xpath_node(); // Construct XPath node from XML node/attribute xpath_node(const xml_node& node); xpath_node(const xml_attribute& attribute, const xml_node& parent); // Get node/attribute, if any xml_node node() const; xml_attribute attribute() const; // Get parent of contained node/attribute xml_node parent() const; // Safe bool conversion operator operator unspecified_bool_type() const; // Borland C++ workaround bool operator!() const; // Comparison operators bool operator==(const xpath_node& n) const; bool operator!=(const xpath_node& n) const; }; #ifdef __BORLANDC__ // Borland C++ workaround bool PUGIXML_FUNCTION operator&&(const xpath_node& lhs, bool rhs); bool PUGIXML_FUNCTION operator||(const xpath_node& lhs, bool rhs); #endif // A fixed-size collection of XPath nodes class PUGIXML_CLASS xpath_node_set { public: // Collection type enum type_t { type_unsorted, // Not ordered type_sorted, // Sorted by document order (ascending) type_sorted_reverse // Sorted by document order (descending) }; // Constant iterator type typedef const xpath_node* const_iterator; // Default constructor. Constructs empty set. xpath_node_set(); // Constructs a set from iterator range; data is not checked for duplicates and is not sorted according to provided type, so be careful xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted); // Destructor ~xpath_node_set(); // Copy constructor/assignment operator xpath_node_set(const xpath_node_set& ns); xpath_node_set& operator=(const xpath_node_set& ns); // Get collection type type_t type() const; // Get collection size size_t size() const; // Indexing operator const xpath_node& operator[](size_t index) const; // Collection iterators const_iterator begin() const; const_iterator end() const; // Sort the collection in ascending/descending order by document order void sort(bool reverse = false); // Get first node in the collection by document order xpath_node first() const; // Check if collection is empty bool empty() const; private: type_t _type; xpath_node _storage; xpath_node* _begin; xpath_node* _end; void _assign(const_iterator begin, const_iterator end); }; #endif #ifndef PUGIXML_NO_STL // Convert wide string to UTF8 std::basic_string, std::allocator > PUGIXML_FUNCTION as_utf8(const wchar_t* str); std::basic_string, std::allocator > PUGIXML_FUNCTION as_utf8(const std::basic_string, std::allocator >& str); // Convert UTF8 to wide string std::basic_string, std::allocator > PUGIXML_FUNCTION as_wide(const char* str); std::basic_string, std::allocator > PUGIXML_FUNCTION as_wide(const std::basic_string, std::allocator >& str); #endif // Memory allocation function interface; returns pointer to allocated memory or NULL on failure typedef void* (*allocation_function)(size_t size); // Memory deallocation function interface typedef void (*deallocation_function)(void* ptr); // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); // Get current memory management functions allocation_function PUGIXML_FUNCTION get_memory_allocation_function(); deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function(); } } OIIO_NAMESPACE_EXIT #if !defined(PUGIXML_NO_STL) && ((defined(_MSC_VER) && _MSC_VER < 1400) || defined(__ICC)) namespace std { // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const OpenImageIO::pugi::xml_node_iterator&); std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const OpenImageIO::pugi::xml_attribute_iterator&); std::forward_iterator_tag PUGIXML_FUNCTION _Iter_cat(const OpenImageIO::pugi::xml_named_node_iterator&); } #endif #if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) namespace std { // Workarounds for (non-standard) iterator category detection std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const OpenImageIO::pugi::xml_node_iterator&); std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const OpenImageIO::pugi::xml_attribute_iterator&); std::forward_iterator_tag PUGIXML_FUNCTION __iterator_category(const OpenImageIO::pugi::xml_named_node_iterator&); } #endif #endif /** * Copyright (c) 2006-2012 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ openimageio-1.3.12~dfsg0.orig/src/include/refcnt.h0000644000175000017500000001006312271062644020165 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////// /// \file /// /// Wrappers and utilities for reference counting. ///////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_REFCNT_H #define OPENIMAGEIO_REFCNT_H #include "thread.h" #include "version.h" // Use Boost for shared pointers #include #include OIIO_NAMESPACE_ENTER { using boost::shared_ptr; using boost::intrusive_ptr; /// Mix-in class that adds a reference count, implemented as an atomic /// counter. class RefCnt { protected: // Declare RefCnt constructors and destructors protected because they // should only be called implicitly from within child class constructors or // destructors. In particular, this prevents users from deleting a RefCnt* // which is important because the destructor is non-virtual. RefCnt () { m_refcnt = 0; } /// Define copy constructor to NOT COPY reference counts! Copying a /// struct doesn't change how many other things point to it. RefCnt (RefCnt&) { m_refcnt = 0; } ~RefCnt () {} public: /// Add a reference /// void _incref () const { ++m_refcnt; } /// Delete a reference, return true if that was the last reference. /// bool _decref () const { return (--m_refcnt) == 0; } /// Define operator= to NOT COPY reference counts! Assigning a struct /// doesn't change how many other things point to it. const RefCnt & operator= (const RefCnt&) const { return *this; } private: mutable atomic_int m_refcnt; }; /// Implementation of intrusive_ptr_add_ref, which is needed for /// any class that you use with Boost's intrusive_ptr. template inline void intrusive_ptr_add_ref (T *x) { x->_incref (); } /// Implementation of intrusive_ptr_release, which is needed for /// any class that you use with Boost's intrusive_ptr. template inline void intrusive_ptr_release (T *x) { if (x->_decref ()) delete x; } // Note that intrusive_ptr_add_ref and intrusive_ptr_release MUST be a // templated on the full type, so that they pass the right address to // 'delete' and destroy the right type. If you try to just // 'inline void intrusive_ptr_release (RefCnt *x)', that might seem // clever, but it will end up getting the address of (and destroying) // just the inherited RefCnt sub-object, not the full subclass you // meant to delete and destroy. } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_REFCNT_H openimageio-1.3.12~dfsg0.orig/src/include/imagecache.h0000644000175000017500000003643612271062644020766 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// An API for accessing images via a system that /// automatically manages a cache of resident image data. #ifndef OPENIMAGEIO_IMAGECACHE_H #define OPENIMAGEIO_IMAGECACHE_H #include "ustring.h" #include "imageio.h" #include "version.h" OIIO_NAMESPACE_ENTER { namespace pvt { // Forward declaration class ImageCacheImpl; }; /// Define an API to an abstract class that manages image files, /// caches of open file handles as well as tiles of pixels so that truly /// huge amounts of image data may be accessed by an application with low /// memory footprint. class OIIO_API ImageCache { public: /// Create a ImageCache and return a pointer. This should only be /// freed by passing it to ImageCache::destroy()! /// /// If shared==true, it's intended to be shared with other like-minded /// owners in the same process who also ask for a shared cache. If /// false, a private image cache will be created. static ImageCache *create (bool shared=true); /// Destroy a ImageCache that was created using ImageCache::create(). /// The variety that takes a 'teardown' parameter, when set to true, /// will fully destroy even a "shared" ImageCache. static void destroy (ImageCache * x); static void destroy (ImageCache * x, bool teardown); ImageCache (void) { } virtual ~ImageCache () { } /// Close everything, free resources, start from scratch. /// virtual void clear () = 0; /// Set an attribute controlling the image cache. Return true /// if the name and type were recognized and the attrib was set. /// Documented attributes: /// int max_open_files : maximum number of file handles held open /// float max_memory_MB : maximum tile cache size, in MB /// string searchpath : colon-separated search path for images /// string plugin_searchpath : colon-separated search path for plugins /// int autotile : if >0, tile size to emulate for non-tiled images /// int autoscanline : autotile using full width tiles /// int automip : if nonzero, emulate mipmap on the fly /// int accept_untiled : if nonzero, accept untiled images, but /// if zero, reject untiled images (default=1) /// int accept_unmipped : if nonzero, accept unmipped images (def=1) /// int statistics:level : verbosity of statistics auto-printed. /// int forcefloat : if nonzero, convert all to float. /// int failure_retries : number of times to retry a read before fail. /// int deduplicate : if nonzero, detect duplicate textures (default=1) /// string substitute_image : uses the named image in place of all /// texture and image references. /// int unassociatedalpha : if nonzero, keep unassociated alpha images /// virtual bool attribute (const std::string &name, TypeDesc type, const void *val) = 0; // Shortcuts for common types virtual bool attribute (const std::string &name, int val) = 0; virtual bool attribute (const std::string &name, float val) = 0; virtual bool attribute (const std::string &name, double val) = 0; virtual bool attribute (const std::string &name, const char *val) = 0; virtual bool attribute (const std::string &name, const std::string &val) = 0; /// Get the named attribute, store it in value. virtual bool getattribute (const std::string &name, TypeDesc type, void *val) = 0; // Shortcuts for common types virtual bool getattribute (const std::string &name, int &val) = 0; virtual bool getattribute (const std::string &name, float &val) = 0; virtual bool getattribute (const std::string &name, double &val) = 0; virtual bool getattribute (const std::string &name, char **val) = 0; virtual bool getattribute (const std::string &name, std::string &val) = 0; /// Given possibly-relative 'filename', resolve it using the search /// path rules and return the full resolved filename. virtual std::string resolve_filename (const std::string &filename) const=0; /// Get information about the named image. Return true if found /// and the data has been put in *data. Return false if the image /// doesn't exist, doesn't have the requested data, if the data /// doesn't match the type requested. or some other failure. virtual bool get_image_info (ustring filename, int subimage, int miplevel, ustring dataname, TypeDesc datatype, void *data) = 0; /// Back-compatible version of get_image_info -- DEPRECATED bool get_image_info (ustring filename, ustring dataname, TypeDesc datatype, void *data) { return get_image_info (filename, 0, 0, dataname, datatype, data); } /// Get the ImageSpec associated with the named image (the first /// subimage & miplevel by default, or as set by 'subimage' and /// 'miplevel'). If the file is found and is an image format that /// can be read, store a copy of its specification in spec and /// return true. Return false if the file was not found or could /// not be opened as an image file by any available ImageIO plugin. virtual bool get_imagespec (ustring filename, ImageSpec &spec, int subimage=0, int miplevel=0, bool native=false) = 0; /// Return a pointer to an ImageSpec associated with the named image /// (the first subimage & miplevel by default, or as set by /// 'subimage' and 'miplevel') if the file is found and is an image /// format that can be read, otherwise return NULL. /// /// This method is much more efficient than get_imagespec(), since /// it just returns a pointer to the spec held internally by the /// ImageCache (rather than copying the spec to the user's memory). /// However, the caller must beware that the pointer is only valid /// as long as nobody (even other threads) calls invalidate() on the /// file, or invalidate_all(), or destroys the ImageCache. virtual const ImageSpec *imagespec (ustring filename, int subimage=0, int miplevel=0, bool native=false) = 0; /// Retrieve the rectangle of pixels spanning [xbegin..xend) X /// [ybegin..yend) X [zbegin..zend), with "exclusive end" a la STL, /// specified as integer pixel coordinates in the designated /// subimage & miplevel, storing the pixel values beginning at the /// address specified by result. The pixel values will be converted /// to the type specified by format. It is up to the caller to /// ensure that result points to an area of memory big enough to /// accommodate the requested rectangle (taking into consideration /// its dimensions, number of channels, and data format). Requested /// pixels outside the valid pixel data region will be filled in /// with 0 values. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool get_pixels (ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result) = 0; /// Retrieve the rectangle of pixels spanning [xbegin..xend) X /// [ybegin..yend) X [zbegin..zend), channels [chbegin..chend), /// with "exclusive end" a la STL, specified as integer pixel /// coordinates in the designated subimage & miplevel, storing the /// pixel values beginning at the address specified by result and /// with the given x, y, and z strides (in bytes). The pixel values /// will be converted to the type specified by format. If the /// strides are set to AutoStride, they will be automatically /// computed assuming a contiguous data layout. It is up to the /// caller to ensure that result points to an area of memory big /// enough to accommodate the requested rectangle (taking into /// consideration its dimensions, number of channels, and data /// format). Requested pixels outside the valid pixel data region /// will be filled in with 0 values. /// /// Return true if the file is found and could be opened by an /// available ImageIO plugin, otherwise return false. virtual bool get_pixels (ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *result, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride) = 0; /// Define an opaque data type that allows us to have a pointer /// to a tile but without exposing any internals. class Tile; /// Find a tile given by an image filename, subimage & miplevel, and /// pixel coordinates. An opaque pointer to the tile will be /// returned, or NULL if no such file (or tile within the file) /// exists or can be read. The tile will not be purged from the /// cache until after release_tile() is called on the tile pointer /// the same number of times that get_tile() was called (refcnt). /// This is thread-safe! virtual Tile * get_tile (ustring filename, int subimage, int miplevel, int x, int y, int z) = 0; /// After finishing with a tile, release_tile will allow it to /// once again be purged from the tile cache if required. virtual void release_tile (Tile *tile) const = 0; /// For a tile retrived by get_tile(), return a pointer to the /// pixel data itself, and also store in 'format' the data type that /// the pixels are internally stored in (which may be different than /// the data type of the pixels in the disk file). virtual const void * tile_pixels (Tile *tile, TypeDesc &format) const = 0; /// This creates a file entry in the cache that, instead of reading /// from disk, uses a custom ImageInput to generate the image (note /// that it will have no effect if there's already an image by the /// same name in the cache). The 'creator' is a factory that /// creates the custom ImageInput and will be called like this: /// ImageInput *in = creator(); Once created, the ImageCache owns /// the ImageInput and is responsible for destroying it when done. /// Custom ImageInputs allow "procedural" images, among other /// things. Also, this is the method you use to set up a /// "writeable" ImageCache images (perhaps with a type of ImageInput /// that's just a stub that does as little as possible). virtual bool add_file (ustring filename, ImageInput::Creator creator) = 0; /// Preemptively add a tile corresponding to the named image, at the /// given subimage and MIP level. The tile added is the one whose /// corner is (x,y,z), and buffer points to the pixels (in the given /// format, with supplied strides) which will be copied and inserted /// into the cache and made available for future lookups. virtual bool add_tile (ustring filename, int subimage, int miplevel, int x, int y, int z, TypeDesc format, const void *buffer, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride) = 0; /// If any of the API routines returned false indicating an error, /// this routine will return the error string (and clear any error /// flags). If no error has occurred since the last time geterror() /// was called, it will return an empty string. virtual std::string geterror () const = 0; /// Return the statistics output as a huge string. /// virtual std::string getstats (int level=1) const = 0; /// Reset most statistics to be as they were with a fresh /// ImageCache. Caveat emptor: this does not flush the cache itelf, /// so the resulting statistics from the next set of texture /// requests will not match the number of tile reads, etc., that /// would have resulted from a new ImageCache. virtual void reset_stats () = 0; /// Invalidate any loaded tiles or open file handles associated with /// the filename, so that any subsequent queries will be forced to /// re-open the file or re-load any tiles (even those that were /// previously loaded and would ordinarily be reused). A client /// might do this if, for example, they are aware that an image /// being held in the cache has been updated on disk. This is safe /// to do even if other procedures are currently holding /// reference-counted tile pointers from the named image, but those /// procedures will not get updated pixels until they release the /// tiles they are holding. virtual void invalidate (ustring filename) = 0; /// Invalidate all loaded tiles and open file handles. This is safe /// to do even if other procedures are currently holding /// reference-counted tile pointers from the named image, but those /// procedures will not get updated pixels until they release the /// tiles they are holding. If force is true, everything will be /// invalidated, no matter how wasteful it is, but if force is /// false, in actuality files will only be invalidated if their /// modification times have been changed since they were first /// opened. virtual void invalidate_all (bool force=false) = 0; private: // Make delete private and unimplemented in order to prevent apps // from calling it. Instead, they should call ImageCache::destroy(). void operator delete (void * /*todel*/) { } }; } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_IMAGECACHE_H openimageio-1.3.12~dfsg0.orig/src/include/CMakeLists.txt0000644000175000017500000000235012271062644021273 0ustar mfvmfvset (public_headers argparse.h color.h dassert.h errorhandler.h export.h filesystem.h filter.h fmath.h hash.h imagebuf.h imagebufalgo.h imagebufalgo_util.h imagecache.h imageio.h optparser.h osdep.h paramlist.h plugin.h refcnt.h string_ref.h strutil.h sysutil.h texture.h thread.h timer.h tinyformat.h typedesc.h ustring.h varyingref.h ) if (NOT USE_EXTERNAL_PUGIXML) list (APPEND public_headers pugixml.hpp pugiconfig.hpp pugixml.cpp) endif() message(STATUS "Create version.h from version.h.in") # Mangle the SOVERSION so that it's a valid C++ identifier for the versioning # namespace defined in version.h string (REGEX REPLACE "\\." "_" MANGLED_SOVERSION ${SOVERSION}) set (OIIO_VERSION_NS "v${MANGLED_SOVERSION}") configure_file(version.h.in "${CMAKE_BINARY_DIR}/include/version.h" @ONLY) list(APPEND public_headers "${CMAKE_BINARY_DIR}/include/version.h") install (FILES ${public_headers} DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT developer) if (USE_TBB AND NOT USE_EXTERNAL_TBB) install (DIRECTORY tbb DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT developer) endif () openimageio-1.3.12~dfsg0.orig/src/include/pugixml.cpp0000644000175000017500000100146212271062644020730 0ustar mfvmfv/** * pugixml parser - version 1.2 * -------------------------------------------------------- * Copyright (C) 2006-2012, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end * of this file. * * This work is based on the pugxml parser, which is: * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) */ #ifndef SOURCE_PUGIXML_CPP #define SOURCE_PUGIXML_CPP #include "pugixml.hpp" #include #include #include #include #include #ifndef PUGIXML_NO_XPATH # include # include # ifdef PUGIXML_NO_EXCEPTIONS # include # endif #endif #ifndef PUGIXML_NO_STL # include # include # include #endif // For placement new #include #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4127) // conditional expression is constant # pragma warning(disable: 4324) // structure was padded due to __declspec(align()) # pragma warning(disable: 4611) // interaction between '_setjmp' and C++ object destruction is non-portable # pragma warning(disable: 4702) // unreachable code # pragma warning(disable: 4996) // this function or variable may be unsafe # pragma warning(disable: 4793) // function compiled as native: presence of '_setjmp' makes a function unmanaged #endif #ifdef __INTEL_COMPILER # pragma warning(disable: 177) // function was declared but never referenced # pragma warning(disable: 279) // controlling expression is constant # pragma warning(disable: 1478 1786) // function was declared "deprecated" # pragma warning(disable: 1684) // conversion from pointer to same-sized integral type #endif #if defined(__BORLANDC__) && defined(PUGIXML_HEADER_ONLY) # pragma warn -8080 // symbol is declared but never used; disabling this inside push/pop bracket does not make the warning go away #endif #ifdef __BORLANDC__ # pragma option push # pragma warn -8008 // condition is always false # pragma warn -8066 // unreachable code #endif #ifdef __SNC__ // Using diag_push/diag_pop does not disable the warnings inside templates due to a compiler bug # pragma diag_suppress=178 // function was declared but never referenced # pragma diag_suppress=237 // controlling expression is constant #endif // Inlining controls #if defined(_MSC_VER) && _MSC_VER >= 1300 # define PUGI__NO_INLINE __declspec(noinline) #elif defined(__GNUC__) # define PUGI__NO_INLINE __attribute__((noinline)) #else # define PUGI__NO_INLINE #endif // Simple static assertion #define PUGI__STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; } // Digital Mars C++ bug workaround for passing char loaded from memory via stack #ifdef __DMC__ # define PUGI__DMC_VOLATILE volatile #else # define PUGI__DMC_VOLATILE #endif // Borland C++ bug workaround for not defining ::memcpy depending on header include order (can't always use std::memcpy because some compilers don't have it at all) #if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST) using std::memcpy; using std::memmove; #endif // In some environments MSVC is a compiler but the CRT lacks certain MSVC-specific features #if defined(_MSC_VER) && !defined(__S3E__) # define PUGI__MSVC_CRT_VERSION _MSC_VER #endif #ifdef PUGIXML_HEADER_ONLY # define PUGI__NS_BEGIN OIIO_NAMESPACE_ENTER { namespace pugi { namespace impl { # define PUGI__NS_END } } } OIIO_NAMESPACE_EXIT # define PUGI__FN inline # define PUGI__FN_NO_INLINE inline #else # if defined(_MSC_VER) && _MSC_VER < 1300 // MSVC6 seems to have an amusing bug with anonymous namespaces inside namespaces # define PUGI__NS_BEGIN OIIO_NAMESPACE_ENTER { namespace pugi { namespace impl { # define PUGI__NS_END } } } OIIO_NAMESPACE_EXIT # else # define PUGI__NS_BEGIN OIIO_NAMESPACE_ENTER { namespace pugi { namespace impl { namespace { # define PUGI__NS_END } } } } OIIO_NAMESPACE_EXIT # endif # define PUGI__FN # define PUGI__FN_NO_INLINE PUGI__NO_INLINE #endif // uintptr_t #if !defined(_MSC_VER) || _MSC_VER >= 1600 # include #else # ifndef _UINTPTR_T_DEFINED // No native uintptr_t in MSVC6 and in some WinCE versions typedef size_t uintptr_t; #define _UINTPTR_T_DEFINED # endif PUGI__NS_BEGIN typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; PUGI__NS_END #endif // Memory allocation PUGI__NS_BEGIN PUGI__FN void* default_allocate(size_t size) { return malloc(size); } PUGI__FN void default_deallocate(void* ptr) { free(ptr); } template struct xml_memory_management_function_storage { static allocation_function allocate; static deallocation_function deallocate; }; template allocation_function xml_memory_management_function_storage::allocate = default_allocate; template deallocation_function xml_memory_management_function_storage::deallocate = default_deallocate; typedef xml_memory_management_function_storage xml_memory; PUGI__NS_END // String utilities PUGI__NS_BEGIN // Get string length PUGI__FN size_t strlength(const char_t* s) { assert(s); #ifdef PUGIXML_WCHAR_MODE return wcslen(s); #else return strlen(s); #endif } // Compare two strings PUGI__FN bool strequal(const char_t* src, const char_t* dst) { assert(src && dst); #ifdef PUGIXML_WCHAR_MODE return wcscmp(src, dst) == 0; #else return strcmp(src, dst) == 0; #endif } // Compare lhs with [rhs_begin, rhs_end) PUGI__FN bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count) { for (size_t i = 0; i < count; ++i) if (lhs[i] != rhs[i]) return false; return lhs[count] == 0; } #ifdef PUGIXML_WCHAR_MODE // Convert string to wide string, assuming all symbols are ASCII PUGI__FN void widen_ascii(wchar_t* dest, const char* source) { for (const char* i = source; *i; ++i) *dest++ = *i; *dest = 0; } #endif PUGI__NS_END #if !defined(PUGIXML_NO_STL) || !defined(PUGIXML_NO_XPATH) // auto_ptr-like buffer holder for exception recovery PUGI__NS_BEGIN struct buffer_holder { void* data; void (*deleter)(void*); buffer_holder(void* data_, void (*deleter_)(void*)): data(data_), deleter(deleter_) { } ~buffer_holder() { if (data) deleter(data); } void* release() { void* result = data; data = 0; return result; } }; PUGI__NS_END #endif PUGI__NS_BEGIN static const size_t xml_memory_page_size = #ifdef PUGIXML_MEMORY_PAGE_SIZE PUGIXML_MEMORY_PAGE_SIZE #else 32768 #endif ; static const uintptr_t xml_memory_page_alignment = 32; static const uintptr_t xml_memory_page_pointer_mask = ~(xml_memory_page_alignment - 1); static const uintptr_t xml_memory_page_name_allocated_mask = 16; static const uintptr_t xml_memory_page_value_allocated_mask = 8; static const uintptr_t xml_memory_page_type_mask = 7; struct xml_allocator; struct xml_memory_page { static xml_memory_page* construct(void* memory) { if (!memory) return 0; //$ redundant, left for performance xml_memory_page* result = static_cast(memory); result->allocator = 0; result->memory = 0; result->prev = 0; result->next = 0; result->busy_size = 0; result->freed_size = 0; return result; } xml_allocator* allocator; void* memory; xml_memory_page* prev; xml_memory_page* next; size_t busy_size; size_t freed_size; char data[1]; }; struct xml_memory_string_header { uint16_t page_offset; // offset from page->data uint16_t full_size; // 0 if string occupies whole page }; struct xml_allocator { xml_allocator(xml_memory_page* root): _root(root), _busy_size(root->busy_size) { } xml_memory_page* allocate_page(size_t data_size) { size_t size = offsetof(xml_memory_page, data) + data_size; // allocate block with some alignment, leaving memory for worst-case padding void* memory = xml_memory::allocate(size + xml_memory_page_alignment); if (!memory) return 0; // align upwards to page boundary void* page_memory = reinterpret_cast((reinterpret_cast(memory) + (xml_memory_page_alignment - 1)) & ~(xml_memory_page_alignment - 1)); // prepare page structure xml_memory_page* page = xml_memory_page::construct(page_memory); page->memory = memory; page->allocator = _root->allocator; return page; } static void deallocate_page(xml_memory_page* page) { xml_memory::deallocate(page->memory); } void* allocate_memory_oob(size_t size, xml_memory_page*& out_page); void* allocate_memory(size_t size, xml_memory_page*& out_page) { if (_busy_size + size > xml_memory_page_size) return allocate_memory_oob(size, out_page); void* buf = _root->data + _busy_size; _busy_size += size; out_page = _root; return buf; } void deallocate_memory(void* ptr, size_t size, xml_memory_page* page) { if (page == _root) page->busy_size = _busy_size; assert(ptr >= page->data && ptr < page->data + page->busy_size); (void)!ptr; page->freed_size += size; assert(page->freed_size <= page->busy_size); if (page->freed_size == page->busy_size) { if (page->next == 0) { assert(_root == page); // top page freed, just reset sizes page->busy_size = page->freed_size = 0; _busy_size = 0; } else { assert(_root != page); assert(page->prev); // remove from the list page->prev->next = page->next; page->next->prev = page->prev; // deallocate deallocate_page(page); } } } char_t* allocate_string(size_t length) { // allocate memory for string and header block size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t); // round size up to pointer alignment boundary size_t full_size = (size + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1); xml_memory_page* page; xml_memory_string_header* header = static_cast(allocate_memory(full_size, page)); if (!header) return 0; // setup header ptrdiff_t page_offset = reinterpret_cast(header) - page->data; assert(page_offset >= 0 && page_offset < (1 << 16)); header->page_offset = static_cast(page_offset); // full_size == 0 for large strings that occupy the whole page assert(full_size < (1 << 16) || (page->busy_size == full_size && page_offset == 0)); header->full_size = static_cast(full_size < (1 << 16) ? full_size : 0); // round-trip through void* to avoid 'cast increases required alignment of target type' warning // header is guaranteed a pointer-sized alignment, which should be enough for char_t return static_cast(static_cast(header + 1)); } void deallocate_string(char_t* string) { // this function casts pointers through void* to avoid 'cast increases required alignment of target type' warnings // we're guaranteed the proper (pointer-sized) alignment on the input string if it was allocated via allocate_string // get header xml_memory_string_header* header = static_cast(static_cast(string)) - 1; // deallocate size_t page_offset = offsetof(xml_memory_page, data) + header->page_offset; xml_memory_page* page = reinterpret_cast(static_cast(reinterpret_cast(header) - page_offset)); // if full_size == 0 then this string occupies the whole page size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size; deallocate_memory(header, full_size, page); } xml_memory_page* _root; size_t _busy_size; }; PUGI__FN_NO_INLINE void* xml_allocator::allocate_memory_oob(size_t size, xml_memory_page*& out_page) { const size_t large_allocation_threshold = xml_memory_page_size / 4; xml_memory_page* page = allocate_page(size <= large_allocation_threshold ? xml_memory_page_size : size); out_page = page; if (!page) return 0; if (size <= large_allocation_threshold) { _root->busy_size = _busy_size; // insert page at the end of linked list page->prev = _root; _root->next = page; _root = page; _busy_size = size; } else { // insert page before the end of linked list, so that it is deleted as soon as possible // the last page is not deleted even if it's empty (see deallocate_memory) assert(_root->prev); page->prev = _root->prev; page->next = _root; _root->prev->next = page; _root->prev = page; } // allocate inside page page->busy_size = size; return page->data; } PUGI__NS_END OIIO_NAMESPACE_ENTER { namespace pugi { /// A 'name=value' XML attribute structure. struct xml_attribute_struct { /// Default ctor xml_attribute_struct(impl::xml_memory_page* page): header(reinterpret_cast(page)), name(0), value(0), prev_attribute_c(0), next_attribute(0) { } uintptr_t header; char_t* name; ///< Pointer to attribute name. char_t* value; ///< Pointer to attribute value. xml_attribute_struct* prev_attribute_c; ///< Previous attribute (cyclic list) xml_attribute_struct* next_attribute; ///< Next attribute }; /// An XML document tree node. struct xml_node_struct { /// Default ctor /// \param type - node type xml_node_struct(impl::xml_memory_page* page, xml_node_type type): header(reinterpret_cast(page) | (type - 1)), parent(0), name(0), value(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0) { } uintptr_t header; xml_node_struct* parent; ///< Pointer to parent char_t* name; ///< Pointer to element name. char_t* value; ///< Pointer to any associated string data. xml_node_struct* first_child; ///< First child xml_node_struct* prev_sibling_c; ///< Left brother (cyclic list) xml_node_struct* next_sibling; ///< Right brother xml_attribute_struct* first_attribute; ///< First attribute }; } } OIIO_NAMESPACE_EXIT PUGI__NS_BEGIN struct xml_document_struct: public xml_node_struct, public xml_allocator { xml_document_struct(xml_memory_page* page): xml_node_struct(page, node_document), xml_allocator(page), buffer(0) { } const char_t* buffer; }; inline xml_allocator& get_allocator(const xml_node_struct* node) { assert(node); return *reinterpret_cast(node->header & xml_memory_page_pointer_mask)->allocator; } PUGI__NS_END // Low-level DOM operations PUGI__NS_BEGIN inline xml_attribute_struct* allocate_attribute(xml_allocator& alloc) { xml_memory_page* page; void* memory = alloc.allocate_memory(sizeof(xml_attribute_struct), page); return new (memory) xml_attribute_struct(page); } inline xml_node_struct* allocate_node(xml_allocator& alloc, xml_node_type type) { xml_memory_page* page; void* memory = alloc.allocate_memory(sizeof(xml_node_struct), page); return new (memory) xml_node_struct(page, type); } inline void destroy_attribute(xml_attribute_struct* a, xml_allocator& alloc) { uintptr_t header = a->header; if (header & impl::xml_memory_page_name_allocated_mask) alloc.deallocate_string(a->name); if (header & impl::xml_memory_page_value_allocated_mask) alloc.deallocate_string(a->value); alloc.deallocate_memory(a, sizeof(xml_attribute_struct), reinterpret_cast(header & xml_memory_page_pointer_mask)); } inline void destroy_node(xml_node_struct* n, xml_allocator& alloc) { uintptr_t header = n->header; if (header & impl::xml_memory_page_name_allocated_mask) alloc.deallocate_string(n->name); if (header & impl::xml_memory_page_value_allocated_mask) alloc.deallocate_string(n->value); for (xml_attribute_struct* attr = n->first_attribute; attr; ) { xml_attribute_struct* next = attr->next_attribute; destroy_attribute(attr, alloc); attr = next; } for (xml_node_struct* child = n->first_child; child; ) { xml_node_struct* next = child->next_sibling; destroy_node(child, alloc); child = next; } alloc.deallocate_memory(n, sizeof(xml_node_struct), reinterpret_cast(header & xml_memory_page_pointer_mask)); } PUGI__FN_NO_INLINE xml_node_struct* append_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element) { xml_node_struct* child = allocate_node(alloc, type); if (!child) return 0; child->parent = node; xml_node_struct* first_child = node->first_child; if (first_child) { xml_node_struct* last_child = first_child->prev_sibling_c; last_child->next_sibling = child; child->prev_sibling_c = last_child; first_child->prev_sibling_c = child; } else { node->first_child = child; child->prev_sibling_c = child; } return child; } PUGI__FN_NO_INLINE xml_attribute_struct* append_attribute_ll(xml_node_struct* node, xml_allocator& alloc) { xml_attribute_struct* a = allocate_attribute(alloc); if (!a) return 0; xml_attribute_struct* first_attribute = node->first_attribute; if (first_attribute) { xml_attribute_struct* last_attribute = first_attribute->prev_attribute_c; last_attribute->next_attribute = a; a->prev_attribute_c = last_attribute; first_attribute->prev_attribute_c = a; } else { node->first_attribute = a; a->prev_attribute_c = a; } return a; } PUGI__NS_END // Helper classes for code generation PUGI__NS_BEGIN struct opt_false { enum { value = 0 }; }; struct opt_true { enum { value = 1 }; }; PUGI__NS_END // Unicode utilities PUGI__NS_BEGIN inline uint16_t endian_swap(uint16_t value) { return static_cast(((value & 0xff) << 8) | (value >> 8)); } inline uint32_t endian_swap(uint32_t value) { return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (value >> 24); } struct utf8_counter { typedef size_t value_type; static value_type low(value_type result, uint32_t ch) { // U+0000..U+007F if (ch < 0x80) return result + 1; // U+0080..U+07FF else if (ch < 0x800) return result + 2; // U+0800..U+FFFF else return result + 3; } static value_type high(value_type result, uint32_t) { // U+10000..U+10FFFF return result + 4; } }; struct utf8_writer { typedef uint8_t* value_type; static value_type low(value_type result, uint32_t ch) { // U+0000..U+007F if (ch < 0x80) { *result = static_cast(ch); return result + 1; } // U+0080..U+07FF else if (ch < 0x800) { result[0] = static_cast(0xC0 | (ch >> 6)); result[1] = static_cast(0x80 | (ch & 0x3F)); return result + 2; } // U+0800..U+FFFF else { result[0] = static_cast(0xE0 | (ch >> 12)); result[1] = static_cast(0x80 | ((ch >> 6) & 0x3F)); result[2] = static_cast(0x80 | (ch & 0x3F)); return result + 3; } } static value_type high(value_type result, uint32_t ch) { // U+10000..U+10FFFF result[0] = static_cast(0xF0 | (ch >> 18)); result[1] = static_cast(0x80 | ((ch >> 12) & 0x3F)); result[2] = static_cast(0x80 | ((ch >> 6) & 0x3F)); result[3] = static_cast(0x80 | (ch & 0x3F)); return result + 4; } static value_type any(value_type result, uint32_t ch) { return (ch < 0x10000) ? low(result, ch) : high(result, ch); } }; struct utf16_counter { typedef size_t value_type; static value_type low(value_type result, uint32_t) { return result + 1; } static value_type high(value_type result, uint32_t) { return result + 2; } }; struct utf16_writer { typedef uint16_t* value_type; static value_type low(value_type result, uint32_t ch) { *result = static_cast(ch); return result + 1; } static value_type high(value_type result, uint32_t ch) { uint32_t msh = static_cast(ch - 0x10000) >> 10; uint32_t lsh = static_cast(ch - 0x10000) & 0x3ff; result[0] = static_cast(0xD800 + msh); result[1] = static_cast(0xDC00 + lsh); return result + 2; } static value_type any(value_type result, uint32_t ch) { return (ch < 0x10000) ? low(result, ch) : high(result, ch); } }; struct utf32_counter { typedef size_t value_type; static value_type low(value_type result, uint32_t) { return result + 1; } static value_type high(value_type result, uint32_t) { return result + 1; } }; struct utf32_writer { typedef uint32_t* value_type; static value_type low(value_type result, uint32_t ch) { *result = ch; return result + 1; } static value_type high(value_type result, uint32_t ch) { *result = ch; return result + 1; } static value_type any(value_type result, uint32_t ch) { *result = ch; return result + 1; } }; struct latin1_writer { typedef uint8_t* value_type; static value_type low(value_type result, uint32_t ch) { *result = static_cast(ch > 255 ? '?' : ch); return result + 1; } static value_type high(value_type result, uint32_t ch) { (void)ch; *result = '?'; return result + 1; } }; template struct wchar_selector; template <> struct wchar_selector<2> { typedef uint16_t type; typedef utf16_counter counter; typedef utf16_writer writer; }; template <> struct wchar_selector<4> { typedef uint32_t type; typedef utf32_counter counter; typedef utf32_writer writer; }; typedef wchar_selector::counter wchar_counter; typedef wchar_selector::writer wchar_writer; template struct utf_decoder { static inline typename Traits::value_type decode_utf8_block(const uint8_t* data, size_t size, typename Traits::value_type result) { const uint8_t utf8_byte_mask = 0x3f; while (size) { uint8_t lead = *data; // 0xxxxxxx -> U+0000..U+007F if (lead < 0x80) { result = Traits::low(result, lead); data += 1; size -= 1; // process aligned single-byte (ascii) blocks if ((reinterpret_cast(data) & 3) == 0) { // round-trip through void* to silence 'cast increases required alignment of target type' warnings while (size >= 4 && (*static_cast(static_cast(data)) & 0x80808080) == 0) { result = Traits::low(result, data[0]); result = Traits::low(result, data[1]); result = Traits::low(result, data[2]); result = Traits::low(result, data[3]); data += 4; size -= 4; } } } // 110xxxxx -> U+0080..U+07FF else if (static_cast(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80) { result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask)); data += 2; size -= 2; } // 1110xxxx -> U+0800-U+FFFF else if (static_cast(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80) { result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask)); data += 3; size -= 3; } // 11110xxx -> U+10000..U+10FFFF else if (static_cast(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80) { result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask)); data += 4; size -= 4; } // 10xxxxxx or 11111xxx -> invalid else { data += 1; size -= 1; } } return result; } static inline typename Traits::value_type decode_utf16_block(const uint16_t* data, size_t size, typename Traits::value_type result) { const uint16_t* end = data + size; while (data < end) { uint16_t lead = opt_swap::value ? endian_swap(*data) : *data; // U+0000..U+D7FF if (lead < 0xD800) { result = Traits::low(result, lead); data += 1; } // U+E000..U+FFFF else if (static_cast(lead - 0xE000) < 0x2000) { result = Traits::low(result, lead); data += 1; } // surrogate pair lead else if (static_cast(lead - 0xD800) < 0x400 && data + 1 < end) { uint16_t next = opt_swap::value ? endian_swap(data[1]) : data[1]; if (static_cast(next - 0xDC00) < 0x400) { result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff)); data += 2; } else { data += 1; } } else { data += 1; } } return result; } static inline typename Traits::value_type decode_utf32_block(const uint32_t* data, size_t size, typename Traits::value_type result) { const uint32_t* end = data + size; while (data < end) { uint32_t lead = opt_swap::value ? endian_swap(*data) : *data; // U+0000..U+FFFF if (lead < 0x10000) { result = Traits::low(result, lead); data += 1; } // U+10000..U+10FFFF else { result = Traits::high(result, lead); data += 1; } } return result; } static inline typename Traits::value_type decode_latin1_block(const uint8_t* data, size_t size, typename Traits::value_type result) { for (size_t i = 0; i < size; ++i) { result = Traits::low(result, data[i]); } return result; } static inline typename Traits::value_type decode_wchar_block_impl(const uint16_t* data, size_t size, typename Traits::value_type result) { return decode_utf16_block(data, size, result); } static inline typename Traits::value_type decode_wchar_block_impl(const uint32_t* data, size_t size, typename Traits::value_type result) { return decode_utf32_block(data, size, result); } static inline typename Traits::value_type decode_wchar_block(const wchar_t* data, size_t size, typename Traits::value_type result) { return decode_wchar_block_impl(reinterpret_cast::type*>(data), size, result); } }; template PUGI__FN void convert_utf_endian_swap(T* result, const T* data, size_t length) { for (size_t i = 0; i < length; ++i) result[i] = endian_swap(data[i]); } #ifdef PUGIXML_WCHAR_MODE PUGI__FN void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length) { for (size_t i = 0; i < length; ++i) result[i] = static_cast(endian_swap(static_cast::type>(data[i]))); } #endif PUGI__NS_END PUGI__NS_BEGIN enum chartype_t { ct_parse_pcdata = 1, // \0, &, \r, < ct_parse_attr = 2, // \0, &, \r, ', " ct_parse_attr_ws = 4, // \0, &, \r, ', ", \n, tab ct_space = 8, // \r, \n, space, tab ct_parse_cdata = 16, // \0, ], >, \r ct_parse_comment = 32, // \0, -, >, \r ct_symbol = 64, // Any symbol > 127, a-z, A-Z, 0-9, _, :, -, . ct_start_symbol = 128 // Any symbol > 127, a-z, A-Z, _, : }; static const unsigned char chartype_table[256] = { 55, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 63, 0, 0, // 0-15 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 8, 0, 6, 0, 0, 0, 7, 6, 0, 0, 0, 0, 0, 96, 64, 0, // 32-47 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 0, 1, 0, 48, 0, // 48-63 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 64-79 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 16, 0, 192, // 80-95 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 96-111 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 0, // 112-127 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 128+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192 }; enum chartypex_t { ctx_special_pcdata = 1, // Any symbol >= 0 and < 32 (except \t, \r, \n), &, <, > ctx_special_attr = 2, // Any symbol >= 0 and < 32 (except \t), &, <, >, " ctx_start_symbol = 4, // Any symbol > 127, a-z, A-Z, _ ctx_digit = 8, // 0-9 ctx_symbol = 16 // Any symbol > 127, a-z, A-Z, 0-9, _, -, . }; static const unsigned char chartypex_table[256] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 2, 3, 3, // 0-15 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 16-31 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 16, 16, 0, // 32-47 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 3, 0, 3, 0, // 48-63 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 64-79 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 20, // 80-95 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 96-111 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, // 112-127 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 128+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 }; #ifdef PUGIXML_WCHAR_MODE #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) ((static_cast(c) < 128 ? table[static_cast(c)] : table[128]) & (ct)) #else #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast(c)] & (ct)) #endif #define PUGI__IS_CHARTYPE(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartype_table) #define PUGI__IS_CHARTYPEX(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartypex_table) PUGI__FN bool is_little_endian() { unsigned int ui = 1; return *reinterpret_cast(&ui) == 1; } PUGI__FN xml_encoding get_wchar_encoding() { PUGI__STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); if (sizeof(wchar_t) == 2) return is_little_endian() ? encoding_utf16_le : encoding_utf16_be; else return is_little_endian() ? encoding_utf32_le : encoding_utf32_be; } PUGI__FN xml_encoding guess_buffer_encoding(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) { // look for BOM in first few bytes if (d0 == 0 && d1 == 0 && d2 == 0xfe && d3 == 0xff) return encoding_utf32_be; if (d0 == 0xff && d1 == 0xfe && d2 == 0 && d3 == 0) return encoding_utf32_le; if (d0 == 0xfe && d1 == 0xff) return encoding_utf16_be; if (d0 == 0xff && d1 == 0xfe) return encoding_utf16_le; if (d0 == 0xef && d1 == 0xbb && d2 == 0xbf) return encoding_utf8; // look for <, (contents); PUGI__DMC_VOLATILE uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3]; return guess_buffer_encoding(d0, d1, d2, d3); } PUGI__FN bool get_mutable_buffer(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) { if (is_mutable) { out_buffer = static_cast(const_cast(contents)); } else { void* buffer = xml_memory::allocate(size > 0 ? size : 1); if (!buffer) return false; memcpy(buffer, contents, size); out_buffer = static_cast(buffer); } out_length = size / sizeof(char_t); return true; } #ifdef PUGIXML_WCHAR_MODE PUGI__FN bool need_endian_swap_utf(xml_encoding le, xml_encoding re) { return (le == encoding_utf16_be && re == encoding_utf16_le) || (le == encoding_utf16_le && re == encoding_utf16_be) || (le == encoding_utf32_be && re == encoding_utf32_le) || (le == encoding_utf32_le && re == encoding_utf32_be); } PUGI__FN bool convert_buffer_endian_swap(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) { const char_t* data = static_cast(contents); if (is_mutable) { out_buffer = const_cast(data); } else { out_buffer = static_cast(xml_memory::allocate(size > 0 ? size : 1)); if (!out_buffer) return false; } out_length = size / sizeof(char_t); convert_wchar_endian_swap(out_buffer, data, out_length); return true; } PUGI__FN bool convert_buffer_utf8(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) { const uint8_t* data = static_cast(contents); // first pass: get length in wchar_t units out_length = utf_decoder::decode_utf8_block(data, size, 0); // allocate buffer of suitable length out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); if (!out_buffer) return false; // second pass: convert utf8 input to wchar_t wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); wchar_writer::value_type out_end = utf_decoder::decode_utf8_block(data, size, out_begin); assert(out_end == out_begin + out_length); (void)!out_end; return true; } template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) { const uint16_t* data = static_cast(contents); size_t length = size / sizeof(uint16_t); // first pass: get length in wchar_t units out_length = utf_decoder::decode_utf16_block(data, length, 0); // allocate buffer of suitable length out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); if (!out_buffer) return false; // second pass: convert utf16 input to wchar_t wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); wchar_writer::value_type out_end = utf_decoder::decode_utf16_block(data, length, out_begin); assert(out_end == out_begin + out_length); (void)!out_end; return true; } template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) { const uint32_t* data = static_cast(contents); size_t length = size / sizeof(uint32_t); // first pass: get length in wchar_t units out_length = utf_decoder::decode_utf32_block(data, length, 0); // allocate buffer of suitable length out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); if (!out_buffer) return false; // second pass: convert utf32 input to wchar_t wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); wchar_writer::value_type out_end = utf_decoder::decode_utf32_block(data, length, out_begin); assert(out_end == out_begin + out_length); (void)!out_end; return true; } PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) { const uint8_t* data = static_cast(contents); // get length in wchar_t units out_length = size; // allocate buffer of suitable length out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); if (!out_buffer) return false; // convert latin1 input to wchar_t wchar_writer::value_type out_begin = reinterpret_cast(out_buffer); wchar_writer::value_type out_end = utf_decoder::decode_latin1_block(data, size, out_begin); assert(out_end == out_begin + out_length); (void)!out_end; return true; } PUGI__FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) { // get native encoding xml_encoding wchar_encoding = get_wchar_encoding(); // fast path: no conversion required if (encoding == wchar_encoding) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); // only endian-swapping is required if (need_endian_swap_utf(encoding, wchar_encoding)) return convert_buffer_endian_swap(out_buffer, out_length, contents, size, is_mutable); // source encoding is utf8 if (encoding == encoding_utf8) return convert_buffer_utf8(out_buffer, out_length, contents, size); // source encoding is utf16 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) { xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; return (native_encoding == encoding) ? convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) : convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true()); } // source encoding is utf32 if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) { xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; return (native_encoding == encoding) ? convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) : convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); } // source encoding is latin1 if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size); assert(!"Invalid encoding"); return false; } #else template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) { const uint16_t* data = static_cast(contents); size_t length = size / sizeof(uint16_t); // first pass: get length in utf8 units out_length = utf_decoder::decode_utf16_block(data, length, 0); // allocate buffer of suitable length out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); if (!out_buffer) return false; // second pass: convert utf16 input to utf8 uint8_t* out_begin = reinterpret_cast(out_buffer); uint8_t* out_end = utf_decoder::decode_utf16_block(data, length, out_begin); assert(out_end == out_begin + out_length); (void)!out_end; return true; } template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) { const uint32_t* data = static_cast(contents); size_t length = size / sizeof(uint32_t); // first pass: get length in utf8 units out_length = utf_decoder::decode_utf32_block(data, length, 0); // allocate buffer of suitable length out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); if (!out_buffer) return false; // second pass: convert utf32 input to utf8 uint8_t* out_begin = reinterpret_cast(out_buffer); uint8_t* out_end = utf_decoder::decode_utf32_block(data, length, out_begin); assert(out_end == out_begin + out_length); (void)!out_end; return true; } PUGI__FN size_t get_latin1_7bit_prefix_length(const uint8_t* data, size_t size) { for (size_t i = 0; i < size; ++i) if (data[i] > 127) return i; return size; } PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) { const uint8_t* data = static_cast(contents); // get size of prefix that does not need utf8 conversion size_t prefix_length = get_latin1_7bit_prefix_length(data, size); assert(prefix_length <= size); const uint8_t* postfix = data + prefix_length; size_t postfix_length = size - prefix_length; // if no conversion is needed, just return the original buffer if (postfix_length == 0) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); // first pass: get length in utf8 units out_length = prefix_length + utf_decoder::decode_latin1_block(postfix, postfix_length, 0); // allocate buffer of suitable length out_buffer = static_cast(xml_memory::allocate((out_length > 0 ? out_length : 1) * sizeof(char_t))); if (!out_buffer) return false; // second pass: convert latin1 input to utf8 memcpy(out_buffer, data, prefix_length); uint8_t* out_begin = reinterpret_cast(out_buffer); uint8_t* out_end = utf_decoder::decode_latin1_block(postfix, postfix_length, out_begin + prefix_length); assert(out_end == out_begin + out_length); (void)!out_end; return true; } PUGI__FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) { // fast path: no conversion required if (encoding == encoding_utf8) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); // source encoding is utf16 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) { xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; return (native_encoding == encoding) ? convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) : convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true()); } // source encoding is utf32 if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) { xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; return (native_encoding == encoding) ? convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) : convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); } // source encoding is latin1 if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size, is_mutable); assert(!"Invalid encoding"); return false; } #endif PUGI__FN size_t as_utf8_begin(const wchar_t* str, size_t length) { // get length in utf8 characters return utf_decoder::decode_wchar_block(str, length, 0); } PUGI__FN void as_utf8_end(char* buffer, size_t size, const wchar_t* str, size_t length) { // convert to utf8 uint8_t* begin = reinterpret_cast(buffer); uint8_t* end = utf_decoder::decode_wchar_block(str, length, begin); assert(begin + size == end); (void)!end; // zero-terminate buffer[size] = 0; } #ifndef PUGIXML_NO_STL PUGI__FN std::string as_utf8_impl(const wchar_t* str, size_t length) { // first pass: get length in utf8 characters size_t size = as_utf8_begin(str, length); // allocate resulting string std::string result; result.resize(size); // second pass: convert to utf8 if (size > 0) as_utf8_end(&result[0], size, str, length); return result; } PUGI__FN std::basic_string as_wide_impl(const char* str, size_t size) { const uint8_t* data = reinterpret_cast(str); // first pass: get length in wchar_t units size_t length = utf_decoder::decode_utf8_block(data, size, 0); // allocate resulting string std::basic_string result; result.resize(length); // second pass: convert to wchar_t if (length > 0) { wchar_writer::value_type begin = reinterpret_cast(&result[0]); wchar_writer::value_type end = utf_decoder::decode_utf8_block(data, size, begin); assert(begin + length == end); (void)!end; } return result; } #endif inline bool strcpy_insitu_allow(size_t length, uintptr_t allocated, char_t* target) { assert(target); size_t target_length = strlength(target); // always reuse document buffer memory if possible if (!allocated) return target_length >= length; // reuse heap memory if waste is not too great const size_t reuse_threshold = 32; return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2); } PUGI__FN bool strcpy_insitu(char_t*& dest, uintptr_t& header, uintptr_t header_mask, const char_t* source) { size_t source_length = strlength(source); if (source_length == 0) { // empty string and null pointer are equivalent, so just deallocate old memory xml_allocator* alloc = reinterpret_cast(header & xml_memory_page_pointer_mask)->allocator; if (header & header_mask) alloc->deallocate_string(dest); // mark the string as not allocated dest = 0; header &= ~header_mask; return true; } else if (dest && strcpy_insitu_allow(source_length, header & header_mask, dest)) { // we can reuse old buffer, so just copy the new data (including zero terminator) memcpy(dest, source, (source_length + 1) * sizeof(char_t)); return true; } else { xml_allocator* alloc = reinterpret_cast(header & xml_memory_page_pointer_mask)->allocator; // allocate new buffer char_t* buf = alloc->allocate_string(source_length + 1); if (!buf) return false; // copy the string (including zero terminator) memcpy(buf, source, (source_length + 1) * sizeof(char_t)); // deallocate old buffer (*after* the above to protect against overlapping memory and/or allocation failures) if (header & header_mask) alloc->deallocate_string(dest); // the string is now allocated, so set the flag dest = buf; header |= header_mask; return true; } } struct gap { char_t* end; size_t size; gap(): end(0), size(0) { } // Push new gap, move s count bytes further (skipping the gap). // Collapse previous gap. void push(char_t*& s, size_t count) { if (end) // there was a gap already; collapse it { // Move [old_gap_end, new_gap_start) to [old_gap_start, ...) assert(s >= end); memmove(end - size, end, reinterpret_cast(s) - reinterpret_cast(end)); } s += count; // end of current gap // "merge" two gaps end = s; size += count; } // Collapse all gaps, return past-the-end pointer char_t* flush(char_t* s) { if (end) { // Move [old_gap_end, current_pos) to [old_gap_start, ...) assert(s >= end); memmove(end - size, end, reinterpret_cast(s) - reinterpret_cast(end)); return s - size; } else return s; } }; PUGI__FN char_t* strconv_escape(char_t* s, gap& g) { char_t* stre = s + 1; switch (*stre) { case '#': // &#... { unsigned int ucsc = 0; if (stre[1] == 'x') // &#x... (hex code) { stre += 2; char_t ch = *stre; if (ch == ';') return stre; for (;;) { if (static_cast(ch - '0') <= 9) ucsc = 16 * ucsc + (ch - '0'); else if (static_cast((ch | ' ') - 'a') <= 5) ucsc = 16 * ucsc + ((ch | ' ') - 'a' + 10); else if (ch == ';') break; else // cancel return stre; ch = *++stre; } ++stre; } else // &#... (dec code) { char_t ch = *++stre; if (ch == ';') return stre; for (;;) { if (static_cast(ch - '0') <= 9) ucsc = 10 * ucsc + (ch - '0'); else if (ch == ';') break; else // cancel return stre; ch = *++stre; } ++stre; } #ifdef PUGIXML_WCHAR_MODE s = reinterpret_cast(wchar_writer::any(reinterpret_cast(s), ucsc)); #else s = reinterpret_cast(utf8_writer::any(reinterpret_cast(s), ucsc)); #endif g.push(s, stre - s); return stre; } case 'a': // &a { ++stre; if (*stre == 'm') // &am { if (*++stre == 'p' && *++stre == ';') // & { *s++ = '&'; ++stre; g.push(s, stre - s); return stre; } } else if (*stre == 'p') // &ap { if (*++stre == 'o' && *++stre == 's' && *++stre == ';') // ' { *s++ = '\''; ++stre; g.push(s, stre - s); return stre; } } break; } case 'g': // &g { if (*++stre == 't' && *++stre == ';') // > { *s++ = '>'; ++stre; g.push(s, stre - s); return stre; } break; } case 'l': // &l { if (*++stre == 't' && *++stre == ';') // < { *s++ = '<'; ++stre; g.push(s, stre - s); return stre; } break; } case 'q': // &q { if (*++stre == 'u' && *++stre == 'o' && *++stre == 't' && *++stre == ';') // " { *s++ = '"'; ++stre; g.push(s, stre - s); return stre; } break; } default: break; } return stre; } // Utility macro for last character handling #define ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e))) PUGI__FN char_t* strconv_comment(char_t* s, char_t endch) { gap g; while (true) { while (!PUGI__IS_CHARTYPE(*s, ct_parse_comment)) ++s; if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair { *s++ = '\n'; // replace first one with 0x0a if (*s == '\n') g.push(s, 1); } else if (s[0] == '-' && s[1] == '-' && ENDSWITH(s[2], '>')) // comment ends here { *g.flush(s) = 0; return s + (s[2] == '>' ? 3 : 2); } else if (*s == 0) { return 0; } else ++s; } } PUGI__FN char_t* strconv_cdata(char_t* s, char_t endch) { gap g; while (true) { while (!PUGI__IS_CHARTYPE(*s, ct_parse_cdata)) ++s; if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair { *s++ = '\n'; // replace first one with 0x0a if (*s == '\n') g.push(s, 1); } else if (s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')) // CDATA ends here { *g.flush(s) = 0; return s + 1; } else if (*s == 0) { return 0; } else ++s; } } typedef char_t* (*strconv_pcdata_t)(char_t*); template struct strconv_pcdata_impl { static char_t* parse(char_t* s) { gap g; while (true) { while (!PUGI__IS_CHARTYPE(*s, ct_parse_pcdata)) ++s; if (*s == '<') // PCDATA ends here { *g.flush(s) = 0; return s + 1; } else if (opt_eol::value && *s == '\r') // Either a single 0x0d or 0x0d 0x0a pair { *s++ = '\n'; // replace first one with 0x0a if (*s == '\n') g.push(s, 1); } else if (opt_escape::value && *s == '&') { s = strconv_escape(s, g); } else if (*s == 0) { return s; } else ++s; } } }; PUGI__FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask) { PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20); switch ((optmask >> 4) & 3) // get bitmask for flags (eol escapes) { case 0: return strconv_pcdata_impl::parse; case 1: return strconv_pcdata_impl::parse; case 2: return strconv_pcdata_impl::parse; case 3: return strconv_pcdata_impl::parse; default: return 0; // should not get here } } typedef char_t* (*strconv_attribute_t)(char_t*, char_t); template struct strconv_attribute_impl { static char_t* parse_wnorm(char_t* s, char_t end_quote) { gap g; // trim leading whitespaces if (PUGI__IS_CHARTYPE(*s, ct_space)) { char_t* str = s; do ++str; while (PUGI__IS_CHARTYPE(*str, ct_space)); g.push(s, str - s); } while (true) { while (!PUGI__IS_CHARTYPE(*s, ct_parse_attr_ws | ct_space)) ++s; if (*s == end_quote) { char_t* str = g.flush(s); do *str-- = 0; while (PUGI__IS_CHARTYPE(*str, ct_space)); return s + 1; } else if (PUGI__IS_CHARTYPE(*s, ct_space)) { *s++ = ' '; if (PUGI__IS_CHARTYPE(*s, ct_space)) { char_t* str = s + 1; while (PUGI__IS_CHARTYPE(*str, ct_space)) ++str; g.push(s, str - s); } } else if (opt_escape::value && *s == '&') { s = strconv_escape(s, g); } else if (!*s) { return 0; } else ++s; } } static char_t* parse_wconv(char_t* s, char_t end_quote) { gap g; while (true) { while (!PUGI__IS_CHARTYPE(*s, ct_parse_attr_ws)) ++s; if (*s == end_quote) { *g.flush(s) = 0; return s + 1; } else if (PUGI__IS_CHARTYPE(*s, ct_space)) { if (*s == '\r') { *s++ = ' '; if (*s == '\n') g.push(s, 1); } else *s++ = ' '; } else if (opt_escape::value && *s == '&') { s = strconv_escape(s, g); } else if (!*s) { return 0; } else ++s; } } static char_t* parse_eol(char_t* s, char_t end_quote) { gap g; while (true) { while (!PUGI__IS_CHARTYPE(*s, ct_parse_attr)) ++s; if (*s == end_quote) { *g.flush(s) = 0; return s + 1; } else if (*s == '\r') { *s++ = '\n'; if (*s == '\n') g.push(s, 1); } else if (opt_escape::value && *s == '&') { s = strconv_escape(s, g); } else if (!*s) { return 0; } else ++s; } } static char_t* parse_simple(char_t* s, char_t end_quote) { gap g; while (true) { while (!PUGI__IS_CHARTYPE(*s, ct_parse_attr)) ++s; if (*s == end_quote) { *g.flush(s) = 0; return s + 1; } else if (opt_escape::value && *s == '&') { s = strconv_escape(s, g); } else if (!*s) { return 0; } else ++s; } } }; PUGI__FN strconv_attribute_t get_strconv_attribute(unsigned int optmask) { PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80); switch ((optmask >> 4) & 15) // get bitmask for flags (wconv wnorm eol escapes) { case 0: return strconv_attribute_impl::parse_simple; case 1: return strconv_attribute_impl::parse_simple; case 2: return strconv_attribute_impl::parse_eol; case 3: return strconv_attribute_impl::parse_eol; case 4: return strconv_attribute_impl::parse_wconv; case 5: return strconv_attribute_impl::parse_wconv; case 6: return strconv_attribute_impl::parse_wconv; case 7: return strconv_attribute_impl::parse_wconv; case 8: return strconv_attribute_impl::parse_wnorm; case 9: return strconv_attribute_impl::parse_wnorm; case 10: return strconv_attribute_impl::parse_wnorm; case 11: return strconv_attribute_impl::parse_wnorm; case 12: return strconv_attribute_impl::parse_wnorm; case 13: return strconv_attribute_impl::parse_wnorm; case 14: return strconv_attribute_impl::parse_wnorm; case 15: return strconv_attribute_impl::parse_wnorm; default: return 0; // should not get here } } inline xml_parse_result make_parse_result(xml_parse_status status, ptrdiff_t offset = 0) { xml_parse_result result; result.status = status; result.offset = offset; return result; } struct xml_parser { xml_allocator alloc; char_t* error_offset; xml_parse_status error_status; // Parser utilities. #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; } #define PUGI__OPTSET(OPT) ( optmsk & (OPT) ) #define PUGI__PUSHNODE(TYPE) { cursor = append_node(cursor, alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } #define PUGI__POPNODE() { cursor = cursor->parent; } #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; } #define PUGI__SCANWHILE(X) { while ((X)) ++s; } #define PUGI__ENDSEG() { ch = *s; *s = 0; ++s; } #define PUGI__THROW_ERROR(err, m) return error_offset = m, error_status = err, static_cast(0) #define PUGI__CHECK_ERROR(err, m) { if (*s == 0) PUGI__THROW_ERROR(err, m); } xml_parser(const xml_allocator& alloc_): alloc(alloc_), error_offset(0), error_status(status_ok) { } // DOCTYPE consists of nested sections of the following possible types: // , , "...", '...' // // // First group can not contain nested groups // Second group can contain nested groups of the same type // Third group can contain all other groups char_t* parse_doctype_primitive(char_t* s) { if (*s == '"' || *s == '\'') { // quoted string char_t ch = *s++; PUGI__SCANFOR(*s == ch); if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); s++; } else if (s[0] == '<' && s[1] == '?') { // s += 2; PUGI__SCANFOR(s[0] == '?' && s[1] == '>'); // no need for ENDSWITH because ?> can't terminate proper doctype if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); s += 2; } else if (s[0] == '<' && s[1] == '!' && s[2] == '-' && s[3] == '-') { s += 4; PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && s[2] == '>'); // no need for ENDSWITH because --> can't terminate proper doctype if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); s += 4; } else PUGI__THROW_ERROR(status_bad_doctype, s); return s; } char_t* parse_doctype_ignore(char_t* s) { assert(s[0] == '<' && s[1] == '!' && s[2] == '['); s++; while (*s) { if (s[0] == '<' && s[1] == '!' && s[2] == '[') { // nested ignore section s = parse_doctype_ignore(s); if (!s) return s; } else if (s[0] == ']' && s[1] == ']' && s[2] == '>') { // ignore section end s += 3; return s; } else s++; } PUGI__THROW_ERROR(status_bad_doctype, s); } char_t* parse_doctype_group(char_t* s, char_t endch, bool toplevel) { assert(s[0] == '<' && s[1] == '!'); s++; while (*s) { if (s[0] == '<' && s[1] == '!' && s[2] != '-') { if (s[2] == '[') { // ignore s = parse_doctype_ignore(s); if (!s) return s; } else { // some control group s = parse_doctype_group(s, endch, false); if (!s) return s; } } else if (s[0] == '<' || s[0] == '"' || s[0] == '\'') { // unknown tag (forbidden), or some primitive group s = parse_doctype_primitive(s); if (!s) return s; } else if (*s == '>') { s++; return s; } else s++; } if (!toplevel || endch != '>') PUGI__THROW_ERROR(status_bad_doctype, s); return s; } char_t* parse_exclamation(char_t* s, xml_node_struct* cursor, unsigned int optmsk, char_t endch) { // parse node contents, starting with exclamation mark ++s; if (*s == '-') // 'value = s; // Save the offset. } if (PUGI__OPTSET(parse_eol) && PUGI__OPTSET(parse_comments)) { s = strconv_comment(s, endch); if (!s) PUGI__THROW_ERROR(status_bad_comment, cursor->value); } else { // Scan for terminating '-->'. PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && ENDSWITH(s[2], '>')); PUGI__CHECK_ERROR(status_bad_comment, s); if (PUGI__OPTSET(parse_comments)) *s = 0; // Zero-terminate this segment at the first terminating '-'. s += (s[2] == '>' ? 3 : 2); // Step over the '\0->'. } } else PUGI__THROW_ERROR(status_bad_comment, s); } else if (*s == '[') { // 'value = s; // Save the offset. if (PUGI__OPTSET(parse_eol)) { s = strconv_cdata(s, endch); if (!s) PUGI__THROW_ERROR(status_bad_cdata, cursor->value); } else { // Scan for terminating ']]>'. PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')); PUGI__CHECK_ERROR(status_bad_cdata, s); *s++ = 0; // Zero-terminate this segment. } } else // Flagged for discard, but we still have to scan for the terminator. { // Scan for terminating ']]>'. PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')); PUGI__CHECK_ERROR(status_bad_cdata, s); ++s; } s += (s[1] == '>' ? 2 : 1); // Step over the last ']>'. } else PUGI__THROW_ERROR(status_bad_cdata, s); } else if (s[0] == 'D' && s[1] == 'O' && s[2] == 'C' && s[3] == 'T' && s[4] == 'Y' && s[5] == 'P' && ENDSWITH(s[6], 'E')) { s -= 2; if (cursor->parent) PUGI__THROW_ERROR(status_bad_doctype, s); char_t* mark = s + 9; s = parse_doctype_group(s, endch, true); if (!s) return s; if (PUGI__OPTSET(parse_doctype)) { while (PUGI__IS_CHARTYPE(*mark, ct_space)) ++mark; PUGI__PUSHNODE(node_doctype); cursor->value = mark; assert((s[0] == 0 && endch == '>') || s[-1] == '>'); s[*s == 0 ? 0 : -1] = 0; PUGI__POPNODE(); } } else if (*s == 0 && endch == '-') PUGI__THROW_ERROR(status_bad_comment, s); else if (*s == 0 && endch == '[') PUGI__THROW_ERROR(status_bad_cdata, s); else PUGI__THROW_ERROR(status_unrecognized_tag, s); return s; } char_t* parse_question(char_t* s, xml_node_struct*& ref_cursor, unsigned int optmsk, char_t endch) { // load into registers xml_node_struct* cursor = ref_cursor; char_t ch = 0; // parse node contents, starting with question mark ++s; // read PI target char_t* target = s; if (!PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_pi, s); PUGI__SCANWHILE(PUGI__IS_CHARTYPE(*s, ct_symbol)); PUGI__CHECK_ERROR(status_bad_pi, s); // determine node type; stricmp / strcasecmp is not portable bool declaration = (target[0] | ' ') == 'x' && (target[1] | ' ') == 'm' && (target[2] | ' ') == 'l' && target + 3 == s; if (declaration ? PUGI__OPTSET(parse_declaration) : PUGI__OPTSET(parse_pi)) { if (declaration) { // disallow non top-level declarations if (cursor->parent) PUGI__THROW_ERROR(status_bad_pi, s); PUGI__PUSHNODE(node_declaration); } else { PUGI__PUSHNODE(node_pi); } cursor->name = target; PUGI__ENDSEG(); // parse value/attributes if (ch == '?') { // empty node if (!ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_pi, s); s += (*s == '>'); PUGI__POPNODE(); } else if (PUGI__IS_CHARTYPE(ch, ct_space)) { PUGI__SKIPWS(); // scan for tag end char_t* value = s; PUGI__SCANFOR(s[0] == '?' && ENDSWITH(s[1], '>')); PUGI__CHECK_ERROR(status_bad_pi, s); if (declaration) { // replace ending ? with / so that 'element' terminates properly *s = '/'; // we exit from this function with cursor at node_declaration, which is a signal to parse() to go to LOC_ATTRIBUTES s = value; } else { // store value and step over > cursor->value = value; PUGI__POPNODE(); PUGI__ENDSEG(); s += (*s == '>'); } } else PUGI__THROW_ERROR(status_bad_pi, s); } else { // scan for tag end PUGI__SCANFOR(s[0] == '?' && ENDSWITH(s[1], '>')); PUGI__CHECK_ERROR(status_bad_pi, s); s += (s[1] == '>' ? 2 : 1); } // store from registers ref_cursor = cursor; return s; } char_t* parse(char_t* s, xml_node_struct* xmldoc, unsigned int optmsk, char_t endch) { strconv_attribute_t strconv_attribute = get_strconv_attribute(optmsk); strconv_pcdata_t strconv_pcdata = get_strconv_pcdata(optmsk); char_t ch = 0; xml_node_struct* cursor = xmldoc; char_t* mark = s; while (*s != 0) { if (*s == '<') { ++s; LOC_TAG: if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // '<#...' { PUGI__PUSHNODE(node_element); // Append a new node to the tree. cursor->name = s; PUGI__SCANWHILE(PUGI__IS_CHARTYPE(*s, ct_symbol)); // Scan for a terminator. PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. if (ch == '>') { // end of tag } else if (PUGI__IS_CHARTYPE(ch, ct_space)) { LOC_ATTRIBUTES: while (true) { PUGI__SKIPWS(); // Eat any whitespace. if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // <... #... { xml_attribute_struct* a = append_attribute_ll(cursor, alloc); // Make space for this attribute. if (!a) PUGI__THROW_ERROR(status_out_of_memory, s); a->name = s; // Save the offset. PUGI__SCANWHILE(PUGI__IS_CHARTYPE(*s, ct_symbol)); // Scan for a terminator. PUGI__CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. PUGI__CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance if (PUGI__IS_CHARTYPE(ch, ct_space)) { PUGI__SKIPWS(); // Eat any whitespace. PUGI__CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance ch = *s; ++s; } if (ch == '=') // '<... #=...' { PUGI__SKIPWS(); // Eat any whitespace. if (*s == '"' || *s == '\'') // '<... #="...' { ch = *s; // Save quote char to avoid breaking on "''" -or- '""'. ++s; // Step over the quote. a->value = s; // Save the offset. s = strconv_attribute(s, ch); if (!s) PUGI__THROW_ERROR(status_bad_attribute, a->value); // After this line the loop continues from the start; // Whitespaces, / and > are ok, symbols and EOF are wrong, // everything else will be detected if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_attribute, s); } else PUGI__THROW_ERROR(status_bad_attribute, s); } else PUGI__THROW_ERROR(status_bad_attribute, s); } else if (*s == '/') { ++s; if (*s == '>') { PUGI__POPNODE(); s++; break; } else if (*s == 0 && endch == '>') { PUGI__POPNODE(); break; } else PUGI__THROW_ERROR(status_bad_start_element, s); } else if (*s == '>') { ++s; break; } else if (*s == 0 && endch == '>') { break; } else PUGI__THROW_ERROR(status_bad_start_element, s); } // !!! } else if (ch == '/') // '<#.../' { if (!ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_start_element, s); PUGI__POPNODE(); // Pop. s += (*s == '>'); } else if (ch == 0) { // we stepped over null terminator, backtrack & handle closing tag --s; if (endch != '>') PUGI__THROW_ERROR(status_bad_start_element, s); } else PUGI__THROW_ERROR(status_bad_start_element, s); } else if (*s == '/') { ++s; char_t* name = cursor->name; if (!name) PUGI__THROW_ERROR(status_end_element_mismatch, s); while (PUGI__IS_CHARTYPE(*s, ct_symbol)) { if (*s++ != *name++) PUGI__THROW_ERROR(status_end_element_mismatch, s); } if (*name) { if (*s == 0 && name[0] == endch && name[1] == 0) PUGI__THROW_ERROR(status_bad_end_element, s); else PUGI__THROW_ERROR(status_end_element_mismatch, s); } PUGI__POPNODE(); // Pop. PUGI__SKIPWS(); if (*s == 0) { if (endch != '>') PUGI__THROW_ERROR(status_bad_end_element, s); } else { if (*s != '>') PUGI__THROW_ERROR(status_bad_end_element, s); ++s; } } else if (*s == '?') // 'header & xml_memory_page_type_mask) + 1 == node_declaration) goto LOC_ATTRIBUTES; } else if (*s == '!') // 'first_child) continue; } } s = mark; if (cursor->parent) { PUGI__PUSHNODE(node_pcdata); // Append a new node on the tree. cursor->value = s; // Save the offset. s = strconv_pcdata(s); PUGI__POPNODE(); // Pop since this is a standalone. if (!*s) break; } else { PUGI__SCANFOR(*s == '<'); // '...<' if (!*s) break; ++s; } // We're after '<' goto LOC_TAG; } } // check that last tag is closed if (cursor != xmldoc) PUGI__THROW_ERROR(status_end_element_mismatch, s); return s; } static xml_parse_result parse(char_t* buffer, size_t length, xml_node_struct* root, unsigned int optmsk) { xml_document_struct* xmldoc = static_cast(root); // store buffer for offset_debug xmldoc->buffer = buffer; // early-out for empty documents if (length == 0) return make_parse_result(status_ok); // create parser on stack xml_parser parser(*xmldoc); // save last character and make buffer zero-terminated (speeds up parsing) char_t endch = buffer[length - 1]; buffer[length - 1] = 0; // perform actual parsing parser.parse(buffer, xmldoc, optmsk, endch); xml_parse_result result = make_parse_result(parser.error_status, parser.error_offset ? parser.error_offset - buffer : 0); assert(result.offset >= 0 && static_cast(result.offset) <= length); // update allocator state *static_cast(xmldoc) = parser.alloc; // since we removed last character, we have to handle the only possible false positive if (result && endch == '<') { // there's no possible well-formed document with < at the end return make_parse_result(status_unrecognized_tag, length); } return result; } }; // Output facilities PUGI__FN xml_encoding get_write_native_encoding() { #ifdef PUGIXML_WCHAR_MODE return get_wchar_encoding(); #else return encoding_utf8; #endif } PUGI__FN xml_encoding get_write_encoding(xml_encoding encoding) { // replace wchar encoding with utf implementation if (encoding == encoding_wchar) return get_wchar_encoding(); // replace utf16 encoding with utf16 with specific endianness if (encoding == encoding_utf16) return is_little_endian() ? encoding_utf16_le : encoding_utf16_be; // replace utf32 encoding with utf32 with specific endianness if (encoding == encoding_utf32) return is_little_endian() ? encoding_utf32_le : encoding_utf32_be; // only do autodetection if no explicit encoding is requested if (encoding != encoding_auto) return encoding; // assume utf8 encoding return encoding_utf8; } #ifdef PUGIXML_WCHAR_MODE PUGI__FN size_t get_valid_length(const char_t* data, size_t length) { assert(length > 0); // discard last character if it's the lead of a surrogate pair return (sizeof(wchar_t) == 2 && static_cast(static_cast(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length; } PUGI__FN size_t convert_buffer(char_t* r_char, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) { // only endian-swapping is required if (need_endian_swap_utf(encoding, get_wchar_encoding())) { convert_wchar_endian_swap(r_char, data, length); return length * sizeof(char_t); } // convert to utf8 if (encoding == encoding_utf8) { uint8_t* dest = r_u8; uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); return static_cast(end - dest); } // convert to utf16 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) { uint16_t* dest = r_u16; // convert to native utf16 uint16_t* end = utf_decoder::decode_wchar_block(data, length, dest); // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); return static_cast(end - dest) * sizeof(uint16_t); } // convert to utf32 if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) { uint32_t* dest = r_u32; // convert to native utf32 uint32_t* end = utf_decoder::decode_wchar_block(data, length, dest); // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); return static_cast(end - dest) * sizeof(uint32_t); } // convert to latin1 if (encoding == encoding_latin1) { uint8_t* dest = r_u8; uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); return static_cast(end - dest); } assert(!"Invalid encoding"); return 0; } #else PUGI__FN size_t get_valid_length(const char_t* data, size_t length) { assert(length > 4); for (size_t i = 1; i <= 4; ++i) { uint8_t ch = static_cast(data[length - i]); // either a standalone character or a leading one if ((ch & 0xc0) != 0x80) return length - i; } // there are four non-leading characters at the end, sequence tail is broken so might as well process the whole chunk return length; } PUGI__FN size_t convert_buffer(char_t* /* r_char */, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) { if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) { uint16_t* dest = r_u16; // convert to native utf16 uint16_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); return static_cast(end - dest) * sizeof(uint16_t); } if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) { uint32_t* dest = r_u32; // convert to native utf32 uint32_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); return static_cast(end - dest) * sizeof(uint32_t); } if (encoding == encoding_latin1) { uint8_t* dest = r_u8; uint8_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); return static_cast(end - dest); } assert(!"Invalid encoding"); return 0; } #endif class xml_buffered_writer { xml_buffered_writer(const xml_buffered_writer&); xml_buffered_writer& operator=(const xml_buffered_writer&); public: xml_buffered_writer(xml_writer& writer_, xml_encoding user_encoding): writer(writer_), bufsize(0), encoding(get_write_encoding(user_encoding)) { PUGI__STATIC_ASSERT(bufcapacity >= 8); } ~xml_buffered_writer() { flush(); } void flush() { flush(buffer, bufsize); bufsize = 0; } void flush(const char_t* data, size_t size) { if (size == 0) return; // fast path, just write data if (encoding == get_write_native_encoding()) writer.write(data, size * sizeof(char_t)); else { // convert chunk size_t result = convert_buffer(scratch.data_char, scratch.data_u8, scratch.data_u16, scratch.data_u32, data, size, encoding); assert(result <= sizeof(scratch)); // write data writer.write(scratch.data_u8, result); } } void write(const char_t* data, size_t length) { if (bufsize + length > bufcapacity) { // flush the remaining buffer contents flush(); // handle large chunks if (length > bufcapacity) { if (encoding == get_write_native_encoding()) { // fast path, can just write data chunk writer.write(data, length * sizeof(char_t)); return; } // need to convert in suitable chunks while (length > bufcapacity) { // get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer // and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary) size_t chunk_size = get_valid_length(data, bufcapacity); // convert chunk and write flush(data, chunk_size); // iterate data += chunk_size; length -= chunk_size; } // small tail is copied below bufsize = 0; } } memcpy(buffer + bufsize, data, length * sizeof(char_t)); bufsize += length; } void write(const char_t* data) { write(data, strlength(data)); } void write(char_t d0) { if (bufsize + 1 > bufcapacity) flush(); buffer[bufsize + 0] = d0; bufsize += 1; } void write(char_t d0, char_t d1) { if (bufsize + 2 > bufcapacity) flush(); buffer[bufsize + 0] = d0; buffer[bufsize + 1] = d1; bufsize += 2; } void write(char_t d0, char_t d1, char_t d2) { if (bufsize + 3 > bufcapacity) flush(); buffer[bufsize + 0] = d0; buffer[bufsize + 1] = d1; buffer[bufsize + 2] = d2; bufsize += 3; } void write(char_t d0, char_t d1, char_t d2, char_t d3) { if (bufsize + 4 > bufcapacity) flush(); buffer[bufsize + 0] = d0; buffer[bufsize + 1] = d1; buffer[bufsize + 2] = d2; buffer[bufsize + 3] = d3; bufsize += 4; } void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4) { if (bufsize + 5 > bufcapacity) flush(); buffer[bufsize + 0] = d0; buffer[bufsize + 1] = d1; buffer[bufsize + 2] = d2; buffer[bufsize + 3] = d3; buffer[bufsize + 4] = d4; bufsize += 5; } void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5) { if (bufsize + 6 > bufcapacity) flush(); buffer[bufsize + 0] = d0; buffer[bufsize + 1] = d1; buffer[bufsize + 2] = d2; buffer[bufsize + 3] = d3; buffer[bufsize + 4] = d4; buffer[bufsize + 5] = d5; bufsize += 6; } // utf8 maximum expansion: x4 (-> utf32) // utf16 maximum expansion: x2 (-> utf32) // utf32 maximum expansion: x1 enum { bufcapacitybytes = #ifdef PUGIXML_MEMORY_OUTPUT_STACK PUGIXML_MEMORY_OUTPUT_STACK #else 10240 #endif , bufcapacity = bufcapacitybytes / (sizeof(char_t) + 4) }; char_t buffer[bufcapacity]; union { uint8_t data_u8[4 * bufcapacity]; uint16_t data_u16[2 * bufcapacity]; uint32_t data_u32[bufcapacity]; char_t data_char[bufcapacity]; } scratch; xml_writer& writer; size_t bufsize; xml_encoding encoding; }; PUGI__FN void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type) { while (*s) { const char_t* prev = s; // While *s is a usual symbol while (!PUGI__IS_CHARTYPEX(*s, type)) ++s; writer.write(prev, static_cast(s - prev)); switch (*s) { case 0: break; case '&': writer.write('&', 'a', 'm', 'p', ';'); ++s; break; case '<': writer.write('&', 'l', 't', ';'); ++s; break; case '>': writer.write('&', 'g', 't', ';'); ++s; break; case '"': writer.write('&', 'q', 'u', 'o', 't', ';'); ++s; break; default: // s is not a usual symbol { unsigned int ch = static_cast(*s++); assert(ch < 32); writer.write('&', '#', static_cast((ch / 10) + '0'), static_cast((ch % 10) + '0'), ';'); } } } } PUGI__FN void text_output(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags) { if (flags & format_no_escapes) writer.write(s); else text_output_escaped(writer, s, type); } PUGI__FN void text_output_cdata(xml_buffered_writer& writer, const char_t* s) { do { writer.write('<', '!', '[', 'C', 'D'); writer.write('A', 'T', 'A', '['); const char_t* prev = s; // look for ]]> sequence - we can't output it as is since it terminates CDATA while (*s && !(s[0] == ']' && s[1] == ']' && s[2] == '>')) ++s; // skip ]] if we stopped at ]]>, > will go to the next CDATA section if (*s) s += 2; writer.write(prev, static_cast(s - prev)); writer.write(']', ']', '>'); } while (*s); } PUGI__FN void node_output_attributes(xml_buffered_writer& writer, const xml_node& node, unsigned int flags) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); for (xml_attribute a = node.first_attribute(); a; a = a.next_attribute()) { writer.write(' '); writer.write(a.name()[0] ? a.name() : default_name); writer.write('=', '"'); text_output(writer, a.value(), ctx_special_attr, flags); writer.write('"'); } } PUGI__FN void node_output(xml_buffered_writer& writer, const xml_node& node, const char_t* indent, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); if ((flags & format_indent) != 0 && (flags & format_raw) == 0) for (unsigned int i = 0; i < depth; ++i) writer.write(indent); switch (node.type()) { case node_document: { for (xml_node n = node.first_child(); n; n = n.next_sibling()) node_output(writer, n, indent, flags, depth); break; } case node_element: { const char_t* name = node.name()[0] ? node.name() : default_name; writer.write('<'); writer.write(name); node_output_attributes(writer, node, flags); if (flags & format_raw) { if (!node.first_child()) writer.write(' ', '/', '>'); else { writer.write('>'); for (xml_node n = node.first_child(); n; n = n.next_sibling()) node_output(writer, n, indent, flags, depth + 1); writer.write('<', '/'); writer.write(name); writer.write('>'); } } else if (!node.first_child()) writer.write(' ', '/', '>', '\n'); else if (node.first_child() == node.last_child() && (node.first_child().type() == node_pcdata || node.first_child().type() == node_cdata)) { writer.write('>'); if (node.first_child().type() == node_pcdata) text_output(writer, node.first_child().value(), ctx_special_pcdata, flags); else text_output_cdata(writer, node.first_child().value()); writer.write('<', '/'); writer.write(name); writer.write('>', '\n'); } else { writer.write('>', '\n'); for (xml_node n = node.first_child(); n; n = n.next_sibling()) node_output(writer, n, indent, flags, depth + 1); if ((flags & format_indent) != 0 && (flags & format_raw) == 0) for (unsigned int i = 0; i < depth; ++i) writer.write(indent); writer.write('<', '/'); writer.write(name); writer.write('>', '\n'); } break; } case node_pcdata: text_output(writer, node.value(), ctx_special_pcdata, flags); if ((flags & format_raw) == 0) writer.write('\n'); break; case node_cdata: text_output_cdata(writer, node.value()); if ((flags & format_raw) == 0) writer.write('\n'); break; case node_comment: writer.write('<', '!', '-', '-'); writer.write(node.value()); writer.write('-', '-', '>'); if ((flags & format_raw) == 0) writer.write('\n'); break; case node_pi: case node_declaration: writer.write('<', '?'); writer.write(node.name()[0] ? node.name() : default_name); if (node.type() == node_declaration) { node_output_attributes(writer, node, flags); } else if (node.value()[0]) { writer.write(' '); writer.write(node.value()); } writer.write('?', '>'); if ((flags & format_raw) == 0) writer.write('\n'); break; case node_doctype: writer.write('<', '!', 'D', 'O', 'C'); writer.write('T', 'Y', 'P', 'E'); if (node.value()[0]) { writer.write(' '); writer.write(node.value()); } writer.write('>'); if ((flags & format_raw) == 0) writer.write('\n'); break; default: assert(!"Invalid node type"); } } inline bool has_declaration(const xml_node& node) { for (xml_node child = node.first_child(); child; child = child.next_sibling()) { xml_node_type type = child.type(); if (type == node_declaration) return true; if (type == node_element) return false; } return false; } inline bool allow_insert_child(xml_node_type parent, xml_node_type child) { if (parent != node_document && parent != node_element) return false; if (child == node_document || child == node_null) return false; if (parent != node_document && (child == node_declaration || child == node_doctype)) return false; return true; } PUGI__FN void recursive_copy_skip(xml_node& dest, const xml_node& source, const xml_node& skip) { assert(dest.type() == source.type()); switch (source.type()) { case node_element: { dest.set_name(source.name()); for (xml_attribute a = source.first_attribute(); a; a = a.next_attribute()) dest.append_attribute(a.name()).set_value(a.value()); for (xml_node c = source.first_child(); c; c = c.next_sibling()) { if (c == skip) continue; xml_node cc = dest.append_child(c.type()); assert(cc); recursive_copy_skip(cc, c, skip); } break; } case node_pcdata: case node_cdata: case node_comment: case node_doctype: dest.set_value(source.value()); break; case node_pi: dest.set_name(source.name()); dest.set_value(source.value()); break; case node_declaration: { dest.set_name(source.name()); for (xml_attribute a = source.first_attribute(); a; a = a.next_attribute()) dest.append_attribute(a.name()).set_value(a.value()); break; } default: assert(!"Invalid node type"); } } inline bool is_text_node(xml_node_struct* node) { xml_node_type type = static_cast((node->header & impl::xml_memory_page_type_mask) + 1); return type == node_pcdata || type == node_cdata; } // get value with conversion functions PUGI__FN int get_value_int(const char_t* value, int def) { if (!value) return def; #ifdef PUGIXML_WCHAR_MODE return static_cast(wcstol(value, 0, 10)); #else return static_cast(strtol(value, 0, 10)); #endif } PUGI__FN unsigned int get_value_uint(const char_t* value, unsigned int def) { if (!value) return def; #ifdef PUGIXML_WCHAR_MODE return static_cast(wcstoul(value, 0, 10)); #else return static_cast(strtoul(value, 0, 10)); #endif } PUGI__FN double get_value_double(const char_t* value, double def) { if (!value) return def; #ifdef PUGIXML_WCHAR_MODE return wcstod(value, 0); #else return strtod(value, 0); #endif } PUGI__FN float get_value_float(const char_t* value, float def) { if (!value) return def; #ifdef PUGIXML_WCHAR_MODE return static_cast(wcstod(value, 0)); #else return static_cast(strtod(value, 0)); #endif } PUGI__FN bool get_value_bool(const char_t* value, bool def) { if (!value) return def; // only look at first char char_t first = *value; // 1*, t* (true), T* (True), y* (yes), Y* (YES) return (first == '1' || first == 't' || first == 'T' || first == 'y' || first == 'Y'); } // set value with conversion functions PUGI__FN bool set_value_buffer(char_t*& dest, uintptr_t& header, uintptr_t header_mask, char (&buf)[128]) { #ifdef PUGIXML_WCHAR_MODE char_t wbuf[128]; impl::widen_ascii(wbuf, buf); return strcpy_insitu(dest, header, header_mask, wbuf); #else return strcpy_insitu(dest, header, header_mask, buf); #endif } PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, int value) { char buf[128]; sprintf(buf, "%d", value); return set_value_buffer(dest, header, header_mask, buf); } PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, unsigned int value) { char buf[128]; sprintf(buf, "%u", value); return set_value_buffer(dest, header, header_mask, buf); } PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, double value) { char buf[128]; sprintf(buf, "%g", value); return set_value_buffer(dest, header, header_mask, buf); } PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, bool value) { return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); } // we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick PUGI__FN xml_parse_status get_file_size(FILE* file, size_t& out_result) { #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) // there are 64-bit versions of fseek/ftell, let's use them typedef __int64 length_type; _fseeki64(file, 0, SEEK_END); length_type length = _ftelli64(file); _fseeki64(file, 0, SEEK_SET); #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && !defined(__STRICT_ANSI__) // there are 64-bit versions of fseek/ftell, let's use them typedef off64_t length_type; fseeko64(file, 0, SEEK_END); length_type length = ftello64(file); fseeko64(file, 0, SEEK_SET); #else // if this is a 32-bit OS, long is enough; if this is a unix system, long is 64-bit, which is enough; otherwise we can't do anything anyway. typedef long length_type; fseek(file, 0, SEEK_END); length_type length = ftell(file); fseek(file, 0, SEEK_SET); #endif // check for I/O errors if (length < 0) return status_io_error; // check for overflow size_t result = static_cast(length); if (static_cast(result) != length) return status_out_of_memory; // finalize out_result = result; return status_ok; } PUGI__FN xml_parse_result load_file_impl(xml_document& doc, FILE* file, unsigned int options, xml_encoding encoding) { if (!file) return make_parse_result(status_file_not_found); // get file size (can result in I/O errors) size_t size = 0; xml_parse_status size_status = get_file_size(file, size); if (size_status != status_ok) { fclose(file); return make_parse_result(size_status); } // allocate buffer for the whole file char* contents = static_cast(xml_memory::allocate(size > 0 ? size : 1)); if (!contents) { fclose(file); return make_parse_result(status_out_of_memory); } // read file in memory size_t read_size = fread(contents, 1, size, file); fclose(file); if (read_size != size) { xml_memory::deallocate(contents); return make_parse_result(status_io_error); } return doc.load_buffer_inplace_own(contents, size, options, encoding); } #ifndef PUGIXML_NO_STL template struct xml_stream_chunk { static xml_stream_chunk* create() { void* memory = xml_memory::allocate(sizeof(xml_stream_chunk)); return new (memory) xml_stream_chunk(); } static void destroy(void* ptr) { xml_stream_chunk* chunk = static_cast(ptr); // free chunk chain while (chunk) { xml_stream_chunk* next = chunk->next; xml_memory::deallocate(chunk); chunk = next; } } xml_stream_chunk(): next(0), size(0) { } xml_stream_chunk* next; size_t size; T data[xml_memory_page_size / sizeof(T)]; }; template PUGI__FN xml_parse_status load_stream_data_noseek(std::basic_istream& stream, void** out_buffer, size_t* out_size) { buffer_holder chunks(0, xml_stream_chunk::destroy); // read file to a chunk list size_t total = 0; xml_stream_chunk* last = 0; while (!stream.eof()) { // allocate new chunk xml_stream_chunk* chunk = xml_stream_chunk::create(); if (!chunk) return status_out_of_memory; // append chunk to list if (last) last = last->next = chunk; else chunks.data = last = chunk; // read data to chunk stream.read(chunk->data, static_cast(sizeof(chunk->data) / sizeof(T))); chunk->size = static_cast(stream.gcount()) * sizeof(T); // read may set failbit | eofbit in case gcount() is less than read length, so check for other I/O errors if (stream.bad() || (!stream.eof() && stream.fail())) return status_io_error; // guard against huge files (chunk size is small enough to make this overflow check work) if (total + chunk->size < total) return status_out_of_memory; total += chunk->size; } // copy chunk list to a contiguous buffer char* buffer = static_cast(xml_memory::allocate(total)); if (!buffer) return status_out_of_memory; char* write = buffer; for (xml_stream_chunk* chunk = static_cast*>(chunks.data); chunk; chunk = chunk->next) { assert(write + chunk->size <= buffer + total); memcpy(write, chunk->data, chunk->size); write += chunk->size; } assert(write == buffer + total); // return buffer *out_buffer = buffer; *out_size = total; return status_ok; } template PUGI__FN xml_parse_status load_stream_data_seek(std::basic_istream& stream, void** out_buffer, size_t* out_size) { // get length of remaining data in stream typename std::basic_istream::pos_type pos = stream.tellg(); stream.seekg(0, std::ios::end); std::streamoff length = stream.tellg() - pos; stream.seekg(pos); if (stream.fail() || pos < 0) return status_io_error; // guard against huge files size_t read_length = static_cast(length); if (static_cast(read_length) != length || length < 0) return status_out_of_memory; // read stream data into memory (guard against stream exceptions with buffer holder) buffer_holder buffer(xml_memory::allocate((read_length > 0 ? read_length : 1) * sizeof(T)), xml_memory::deallocate); if (!buffer.data) return status_out_of_memory; stream.read(static_cast(buffer.data), static_cast(read_length)); // read may set failbit | eofbit in case gcount() is less than read_length (i.e. line ending conversion), so check for other I/O errors if (stream.bad() || (!stream.eof() && stream.fail())) return status_io_error; // return buffer size_t actual_length = static_cast(stream.gcount()); assert(actual_length <= read_length); *out_buffer = buffer.release(); *out_size = actual_length * sizeof(T); return status_ok; } template PUGI__FN xml_parse_result load_stream_impl(xml_document& doc, std::basic_istream& stream, unsigned int options, xml_encoding encoding) { void* buffer = 0; size_t size = 0; // load stream to memory (using seek-based implementation if possible, since it's faster and takes less memory) xml_parse_status status = (stream.tellg() < 0) ? load_stream_data_noseek(stream, &buffer, &size) : load_stream_data_seek(stream, &buffer, &size); if (status != status_ok) return make_parse_result(status); return doc.load_buffer_inplace_own(buffer, size, options, encoding); } #endif #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && !defined(__STRICT_ANSI__)) PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) { return _wfopen(path, mode); } #else PUGI__FN char* convert_path_heap(const wchar_t* str) { assert(str); // first pass: get length in utf8 characters size_t length = wcslen(str); size_t size = as_utf8_begin(str, length); // allocate resulting string char* result = static_cast(xml_memory::allocate(size + 1)); if (!result) return 0; // second pass: convert to utf8 as_utf8_end(result, size, str, length); return result; } PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) { // there is no standard function to open wide paths, so our best bet is to try utf8 path char* path_utf8 = convert_path_heap(path); if (!path_utf8) return 0; // convert mode to ASCII (we mirror _wfopen interface) char mode_ascii[4] = {0}; for (size_t i = 0; mode[i]; ++i) mode_ascii[i] = static_cast(mode[i]); // try to open the utf8 path FILE* result = fopen(path_utf8, mode_ascii); // free dummy buffer xml_memory::deallocate(path_utf8); return result; } #endif PUGI__FN bool save_file_impl(const xml_document& doc, FILE* file, const char_t* indent, unsigned int flags, xml_encoding encoding) { if (!file) return false; xml_writer_file writer(file); doc.save(writer, indent, flags, encoding); int result = ferror(file); fclose(file); return result == 0; } PUGI__NS_END OIIO_NAMESPACE_ENTER { namespace pugi { PUGI__FN xml_writer_file::xml_writer_file(void* file_): file(file_) { } PUGI__FN void xml_writer_file::write(const void* data, size_t size) { size_t result = fwrite(data, 1, size, static_cast(file)); (void)!result; // unfortunately we can't do proper error handling here } #ifndef PUGIXML_NO_STL PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(&stream), wide_stream(0) { } PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(0), wide_stream(&stream) { } PUGI__FN void xml_writer_stream::write(const void* data, size_t size) { if (narrow_stream) { assert(!wide_stream); narrow_stream->write(reinterpret_cast(data), static_cast(size)); } else { assert(wide_stream); assert(size % sizeof(wchar_t) == 0); wide_stream->write(reinterpret_cast(data), static_cast(size / sizeof(wchar_t))); } } #endif PUGI__FN xml_tree_walker::xml_tree_walker(): _depth(0) { } PUGI__FN xml_tree_walker::~xml_tree_walker() { } PUGI__FN int xml_tree_walker::depth() const { return _depth; } PUGI__FN bool xml_tree_walker::begin(xml_node&) { return true; } PUGI__FN bool xml_tree_walker::end(xml_node&) { return true; } PUGI__FN xml_attribute::xml_attribute(): _attr(0) { } PUGI__FN xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr) { } PUGI__FN static void unspecified_bool_xml_attribute(xml_attribute***) { } PUGI__FN xml_attribute::operator xml_attribute::unspecified_bool_type() const { return _attr ? unspecified_bool_xml_attribute : 0; } PUGI__FN bool xml_attribute::operator!() const { return !_attr; } PUGI__FN bool xml_attribute::operator==(const xml_attribute& r) const { return (_attr == r._attr); } PUGI__FN bool xml_attribute::operator!=(const xml_attribute& r) const { return (_attr != r._attr); } PUGI__FN bool xml_attribute::operator<(const xml_attribute& r) const { return (_attr < r._attr); } PUGI__FN bool xml_attribute::operator>(const xml_attribute& r) const { return (_attr > r._attr); } PUGI__FN bool xml_attribute::operator<=(const xml_attribute& r) const { return (_attr <= r._attr); } PUGI__FN bool xml_attribute::operator>=(const xml_attribute& r) const { return (_attr >= r._attr); } PUGI__FN xml_attribute xml_attribute::next_attribute() const { return _attr ? xml_attribute(_attr->next_attribute) : xml_attribute(); } PUGI__FN xml_attribute xml_attribute::previous_attribute() const { return _attr && _attr->prev_attribute_c->next_attribute ? xml_attribute(_attr->prev_attribute_c) : xml_attribute(); } PUGI__FN const char_t* xml_attribute::as_string(const char_t* def) const { return (_attr && _attr->value) ? _attr->value : def; } PUGI__FN int xml_attribute::as_int(int def) const { return impl::get_value_int(_attr ? _attr->value : 0, def); } PUGI__FN unsigned int xml_attribute::as_uint(unsigned int def) const { return impl::get_value_uint(_attr ? _attr->value : 0, def); } PUGI__FN double xml_attribute::as_double(double def) const { return impl::get_value_double(_attr ? _attr->value : 0, def); } PUGI__FN float xml_attribute::as_float(float def) const { return impl::get_value_float(_attr ? _attr->value : 0, def); } PUGI__FN bool xml_attribute::as_bool(bool def) const { return impl::get_value_bool(_attr ? _attr->value : 0, def); } PUGI__FN bool xml_attribute::empty() const { return !_attr; } PUGI__FN const char_t* xml_attribute::name() const { return (_attr && _attr->name) ? _attr->name : PUGIXML_TEXT(""); } PUGI__FN const char_t* xml_attribute::value() const { return (_attr && _attr->value) ? _attr->value : PUGIXML_TEXT(""); } PUGI__FN size_t xml_attribute::hash_value() const { return static_cast(reinterpret_cast(_attr) / sizeof(xml_attribute_struct)); } PUGI__FN xml_attribute_struct* xml_attribute::internal_object() const { return _attr; } PUGI__FN xml_attribute& xml_attribute::operator=(const char_t* rhs) { set_value(rhs); return *this; } PUGI__FN xml_attribute& xml_attribute::operator=(int rhs) { set_value(rhs); return *this; } PUGI__FN xml_attribute& xml_attribute::operator=(unsigned int rhs) { set_value(rhs); return *this; } PUGI__FN xml_attribute& xml_attribute::operator=(double rhs) { set_value(rhs); return *this; } PUGI__FN xml_attribute& xml_attribute::operator=(bool rhs) { set_value(rhs); return *this; } PUGI__FN bool xml_attribute::set_name(const char_t* rhs) { if (!_attr) return false; return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs); } PUGI__FN bool xml_attribute::set_value(const char_t* rhs) { if (!_attr) return false; return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } PUGI__FN bool xml_attribute::set_value(int rhs) { if (!_attr) return false; return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } PUGI__FN bool xml_attribute::set_value(unsigned int rhs) { if (!_attr) return false; return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } PUGI__FN bool xml_attribute::set_value(double rhs) { if (!_attr) return false; return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } PUGI__FN bool xml_attribute::set_value(bool rhs) { if (!_attr) return false; return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } #ifdef __BORLANDC__ PUGI__FN bool operator&&(const xml_attribute& lhs, bool rhs) { return (bool)lhs && rhs; } PUGI__FN bool operator||(const xml_attribute& lhs, bool rhs) { return (bool)lhs || rhs; } #endif PUGI__FN xml_node::xml_node(): _root(0) { } PUGI__FN xml_node::xml_node(xml_node_struct* p): _root(p) { } PUGI__FN static void unspecified_bool_xml_node(xml_node***) { } PUGI__FN xml_node::operator xml_node::unspecified_bool_type() const { return _root ? unspecified_bool_xml_node : 0; } PUGI__FN bool xml_node::operator!() const { return !_root; } PUGI__FN xml_node::iterator xml_node::begin() const { return iterator(_root ? _root->first_child : 0, _root); } PUGI__FN xml_node::iterator xml_node::end() const { return iterator(0, _root); } PUGI__FN xml_node::attribute_iterator xml_node::attributes_begin() const { return attribute_iterator(_root ? _root->first_attribute : 0, _root); } PUGI__FN xml_node::attribute_iterator xml_node::attributes_end() const { return attribute_iterator(0, _root); } PUGI__FN xml_object_range xml_node::children() const { return xml_object_range(begin(), end()); } PUGI__FN xml_object_range xml_node::children(const char_t* name_) const { return xml_object_range(xml_named_node_iterator(child(name_), name_), xml_named_node_iterator()); } PUGI__FN xml_object_range xml_node::attributes() const { return xml_object_range(attributes_begin(), attributes_end()); } PUGI__FN bool xml_node::operator==(const xml_node& r) const { return (_root == r._root); } PUGI__FN bool xml_node::operator!=(const xml_node& r) const { return (_root != r._root); } PUGI__FN bool xml_node::operator<(const xml_node& r) const { return (_root < r._root); } PUGI__FN bool xml_node::operator>(const xml_node& r) const { return (_root > r._root); } PUGI__FN bool xml_node::operator<=(const xml_node& r) const { return (_root <= r._root); } PUGI__FN bool xml_node::operator>=(const xml_node& r) const { return (_root >= r._root); } PUGI__FN bool xml_node::empty() const { return !_root; } PUGI__FN const char_t* xml_node::name() const { return (_root && _root->name) ? _root->name : PUGIXML_TEXT(""); } PUGI__FN xml_node_type xml_node::type() const { return _root ? static_cast((_root->header & impl::xml_memory_page_type_mask) + 1) : node_null; } PUGI__FN const char_t* xml_node::value() const { return (_root && _root->value) ? _root->value : PUGIXML_TEXT(""); } PUGI__FN xml_node xml_node::child(const char_t* name_) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) if (i->name && impl::strequal(name_, i->name)) return xml_node(i); return xml_node(); } PUGI__FN xml_attribute xml_node::attribute(const char_t* name_) const { if (!_root) return xml_attribute(); for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute) if (i->name && impl::strequal(name_, i->name)) return xml_attribute(i); return xml_attribute(); } PUGI__FN xml_node xml_node::next_sibling(const char_t* name_) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling) if (i->name && impl::strequal(name_, i->name)) return xml_node(i); return xml_node(); } PUGI__FN xml_node xml_node::next_sibling() const { if (!_root) return xml_node(); if (_root->next_sibling) return xml_node(_root->next_sibling); else return xml_node(); } PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->prev_sibling_c; i->next_sibling; i = i->prev_sibling_c) if (i->name && impl::strequal(name_, i->name)) return xml_node(i); return xml_node(); } PUGI__FN xml_node xml_node::previous_sibling() const { if (!_root) return xml_node(); if (_root->prev_sibling_c->next_sibling) return xml_node(_root->prev_sibling_c); else return xml_node(); } PUGI__FN xml_node xml_node::parent() const { return _root ? xml_node(_root->parent) : xml_node(); } PUGI__FN xml_node xml_node::root() const { if (!_root) return xml_node(); impl::xml_memory_page* page = reinterpret_cast(_root->header & impl::xml_memory_page_pointer_mask); return xml_node(static_cast(page->allocator)); } PUGI__FN xml_text xml_node::text() const { return xml_text(_root); } PUGI__FN const char_t* xml_node::child_value() const { if (!_root) return PUGIXML_TEXT(""); for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) if (i->value && impl::is_text_node(i)) return i->value; return PUGIXML_TEXT(""); } PUGI__FN const char_t* xml_node::child_value(const char_t* name_) const { return child(name_).child_value(); } PUGI__FN xml_attribute xml_node::first_attribute() const { return _root ? xml_attribute(_root->first_attribute) : xml_attribute(); } PUGI__FN xml_attribute xml_node::last_attribute() const { return _root && _root->first_attribute ? xml_attribute(_root->first_attribute->prev_attribute_c) : xml_attribute(); } PUGI__FN xml_node xml_node::first_child() const { return _root ? xml_node(_root->first_child) : xml_node(); } PUGI__FN xml_node xml_node::last_child() const { return _root && _root->first_child ? xml_node(_root->first_child->prev_sibling_c) : xml_node(); } PUGI__FN bool xml_node::set_name(const char_t* rhs) { switch (type()) { case node_pi: case node_declaration: case node_element: return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs); default: return false; } } PUGI__FN bool xml_node::set_value(const char_t* rhs) { switch (type()) { case node_pi: case node_cdata: case node_pcdata: case node_comment: case node_doctype: return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs); default: return false; } } PUGI__FN xml_attribute xml_node::append_attribute(const char_t* name_) { if (type() != node_element && type() != node_declaration) return xml_attribute(); xml_attribute a(impl::append_attribute_ll(_root, impl::get_allocator(_root))); a.set_name(name_); return a; } PUGI__FN xml_attribute xml_node::prepend_attribute(const char_t* name_) { if (type() != node_element && type() != node_declaration) return xml_attribute(); xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); if (!a) return xml_attribute(); a.set_name(name_); xml_attribute_struct* head = _root->first_attribute; if (head) { a._attr->prev_attribute_c = head->prev_attribute_c; head->prev_attribute_c = a._attr; } else a._attr->prev_attribute_c = a._attr; a._attr->next_attribute = head; _root->first_attribute = a._attr; return a; } PUGI__FN xml_attribute xml_node::insert_attribute_before(const char_t* name_, const xml_attribute& attr) { if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute(); // check that attribute belongs to *this xml_attribute_struct* cur = attr._attr; while (cur->prev_attribute_c->next_attribute) cur = cur->prev_attribute_c; if (cur != _root->first_attribute) return xml_attribute(); xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); if (!a) return xml_attribute(); a.set_name(name_); if (attr._attr->prev_attribute_c->next_attribute) attr._attr->prev_attribute_c->next_attribute = a._attr; else _root->first_attribute = a._attr; a._attr->prev_attribute_c = attr._attr->prev_attribute_c; a._attr->next_attribute = attr._attr; attr._attr->prev_attribute_c = a._attr; return a; } PUGI__FN xml_attribute xml_node::insert_attribute_after(const char_t* name_, const xml_attribute& attr) { if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute(); // check that attribute belongs to *this xml_attribute_struct* cur = attr._attr; while (cur->prev_attribute_c->next_attribute) cur = cur->prev_attribute_c; if (cur != _root->first_attribute) return xml_attribute(); xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); if (!a) return xml_attribute(); a.set_name(name_); if (attr._attr->next_attribute) attr._attr->next_attribute->prev_attribute_c = a._attr; else _root->first_attribute->prev_attribute_c = a._attr; a._attr->next_attribute = attr._attr->next_attribute; a._attr->prev_attribute_c = attr._attr; attr._attr->next_attribute = a._attr; return a; } PUGI__FN xml_attribute xml_node::append_copy(const xml_attribute& proto) { if (!proto) return xml_attribute(); xml_attribute result = append_attribute(proto.name()); result.set_value(proto.value()); return result; } PUGI__FN xml_attribute xml_node::prepend_copy(const xml_attribute& proto) { if (!proto) return xml_attribute(); xml_attribute result = prepend_attribute(proto.name()); result.set_value(proto.value()); return result; } PUGI__FN xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr) { if (!proto) return xml_attribute(); xml_attribute result = insert_attribute_after(proto.name(), attr); result.set_value(proto.value()); return result; } PUGI__FN xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr) { if (!proto) return xml_attribute(); xml_attribute result = insert_attribute_before(proto.name(), attr); result.set_value(proto.value()); return result; } PUGI__FN xml_node xml_node::append_child(xml_node_type type_) { if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); xml_node n(impl::append_node(_root, impl::get_allocator(_root), type_)); if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); return n; } PUGI__FN xml_node xml_node::prepend_child(xml_node_type type_) { if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); n._root->parent = _root; xml_node_struct* head = _root->first_child; if (head) { n._root->prev_sibling_c = head->prev_sibling_c; head->prev_sibling_c = n._root; } else n._root->prev_sibling_c = n._root; n._root->next_sibling = head; _root->first_child = n._root; if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); return n; } PUGI__FN xml_node xml_node::insert_child_before(xml_node_type type_, const xml_node& node) { if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); if (!node._root || node._root->parent != _root) return xml_node(); xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); n._root->parent = _root; if (node._root->prev_sibling_c->next_sibling) node._root->prev_sibling_c->next_sibling = n._root; else _root->first_child = n._root; n._root->prev_sibling_c = node._root->prev_sibling_c; n._root->next_sibling = node._root; node._root->prev_sibling_c = n._root; if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); return n; } PUGI__FN xml_node xml_node::insert_child_after(xml_node_type type_, const xml_node& node) { if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); if (!node._root || node._root->parent != _root) return xml_node(); xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); n._root->parent = _root; if (node._root->next_sibling) node._root->next_sibling->prev_sibling_c = n._root; else _root->first_child->prev_sibling_c = n._root; n._root->next_sibling = node._root->next_sibling; n._root->prev_sibling_c = node._root; node._root->next_sibling = n._root; if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); return n; } PUGI__FN xml_node xml_node::append_child(const char_t* name_) { xml_node result = append_child(node_element); result.set_name(name_); return result; } PUGI__FN xml_node xml_node::prepend_child(const char_t* name_) { xml_node result = prepend_child(node_element); result.set_name(name_); return result; } PUGI__FN xml_node xml_node::insert_child_after(const char_t* name_, const xml_node& node) { xml_node result = insert_child_after(node_element, node); result.set_name(name_); return result; } PUGI__FN xml_node xml_node::insert_child_before(const char_t* name_, const xml_node& node) { xml_node result = insert_child_before(node_element, node); result.set_name(name_); return result; } PUGI__FN xml_node xml_node::append_copy(const xml_node& proto) { xml_node result = append_child(proto.type()); if (result) impl::recursive_copy_skip(result, proto, result); return result; } PUGI__FN xml_node xml_node::prepend_copy(const xml_node& proto) { xml_node result = prepend_child(proto.type()); if (result) impl::recursive_copy_skip(result, proto, result); return result; } PUGI__FN xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node) { xml_node result = insert_child_after(proto.type(), node); if (result) impl::recursive_copy_skip(result, proto, result); return result; } PUGI__FN xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node) { xml_node result = insert_child_before(proto.type(), node); if (result) impl::recursive_copy_skip(result, proto, result); return result; } PUGI__FN bool xml_node::remove_attribute(const char_t* name_) { return remove_attribute(attribute(name_)); } PUGI__FN bool xml_node::remove_attribute(const xml_attribute& a) { if (!_root || !a._attr) return false; // check that attribute belongs to *this xml_attribute_struct* attr = a._attr; while (attr->prev_attribute_c->next_attribute) attr = attr->prev_attribute_c; if (attr != _root->first_attribute) return false; if (a._attr->next_attribute) a._attr->next_attribute->prev_attribute_c = a._attr->prev_attribute_c; else if (_root->first_attribute) _root->first_attribute->prev_attribute_c = a._attr->prev_attribute_c; if (a._attr->prev_attribute_c->next_attribute) a._attr->prev_attribute_c->next_attribute = a._attr->next_attribute; else _root->first_attribute = a._attr->next_attribute; impl::destroy_attribute(a._attr, impl::get_allocator(_root)); return true; } PUGI__FN bool xml_node::remove_child(const char_t* name_) { return remove_child(child(name_)); } PUGI__FN bool xml_node::remove_child(const xml_node& n) { if (!_root || !n._root || n._root->parent != _root) return false; if (n._root->next_sibling) n._root->next_sibling->prev_sibling_c = n._root->prev_sibling_c; else if (_root->first_child) _root->first_child->prev_sibling_c = n._root->prev_sibling_c; if (n._root->prev_sibling_c->next_sibling) n._root->prev_sibling_c->next_sibling = n._root->next_sibling; else _root->first_child = n._root->next_sibling; impl::destroy_node(n._root, impl::get_allocator(_root)); return true; } PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* name_, const char_t* attr_name, const char_t* attr_value) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) if (i->name && impl::strequal(name_, i->name)) { for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) if (impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value)) return xml_node(i); } return xml_node(); } PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const { if (!_root) return xml_node(); for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) if (impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value)) return xml_node(i); return xml_node(); } #ifndef PUGIXML_NO_STL PUGI__FN string_t xml_node::path(char_t delimiter) const { xml_node cursor = *this; // Make a copy. string_t result = cursor.name(); while (cursor.parent()) { cursor = cursor.parent(); string_t temp = cursor.name(); temp += delimiter; temp += result; result.swap(temp); } return result; } #endif PUGI__FN xml_node xml_node::first_element_by_path(const char_t* path_, char_t delimiter) const { xml_node found = *this; // Current search context. if (!_root || !path_ || !path_[0]) return found; if (path_[0] == delimiter) { // Absolute path; e.g. '/foo/bar' found = found.root(); ++path_; } const char_t* path_segment = path_; while (*path_segment == delimiter) ++path_segment; const char_t* path_segment_end = path_segment; while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end; if (path_segment == path_segment_end) return found; const char_t* next_segment = path_segment_end; while (*next_segment == delimiter) ++next_segment; if (*path_segment == '.' && path_segment + 1 == path_segment_end) return found.first_element_by_path(next_segment, delimiter); else if (*path_segment == '.' && *(path_segment+1) == '.' && path_segment + 2 == path_segment_end) return found.parent().first_element_by_path(next_segment, delimiter); else { for (xml_node_struct* j = found._root->first_child; j; j = j->next_sibling) { if (j->name && impl::strequalrange(j->name, path_segment, static_cast(path_segment_end - path_segment))) { xml_node subsearch = xml_node(j).first_element_by_path(next_segment, delimiter); if (subsearch) return subsearch; } } return xml_node(); } } PUGI__FN bool xml_node::traverse(xml_tree_walker& walker) { walker._depth = -1; xml_node arg_begin = *this; if (!walker.begin(arg_begin)) return false; xml_node cur = first_child(); if (cur) { ++walker._depth; do { xml_node arg_for_each = cur; if (!walker.for_each(arg_for_each)) return false; if (cur.first_child()) { ++walker._depth; cur = cur.first_child(); } else if (cur.next_sibling()) cur = cur.next_sibling(); else { // Borland C++ workaround while (!cur.next_sibling() && cur != *this && !cur.parent().empty()) { --walker._depth; cur = cur.parent(); } if (cur != *this) cur = cur.next_sibling(); } } while (cur && cur != *this); } assert(walker._depth == -1); xml_node arg_end = *this; return walker.end(arg_end); } PUGI__FN size_t xml_node::hash_value() const { return static_cast(reinterpret_cast(_root) / sizeof(xml_node_struct)); } PUGI__FN xml_node_struct* xml_node::internal_object() const { return _root; } PUGI__FN void xml_node::print(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const { if (!_root) return; impl::xml_buffered_writer buffered_writer(writer, encoding); impl::node_output(buffered_writer, *this, indent, flags, depth); } #ifndef PUGIXML_NO_STL PUGI__FN void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const { xml_writer_stream writer(stream); print(writer, indent, flags, encoding, depth); } PUGI__FN void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, unsigned int depth) const { xml_writer_stream writer(stream); print(writer, indent, flags, encoding_wchar, depth); } #endif PUGI__FN ptrdiff_t xml_node::offset_debug() const { xml_node_struct* r = root()._root; if (!r) return -1; const char_t* buffer = static_cast(r)->buffer; if (!buffer) return -1; switch (type()) { case node_document: return 0; case node_element: case node_declaration: case node_pi: return (_root->header & impl::xml_memory_page_name_allocated_mask) ? -1 : _root->name - buffer; case node_pcdata: case node_cdata: case node_comment: case node_doctype: return (_root->header & impl::xml_memory_page_value_allocated_mask) ? -1 : _root->value - buffer; default: return -1; } } #ifdef __BORLANDC__ PUGI__FN bool operator&&(const xml_node& lhs, bool rhs) { return (bool)lhs && rhs; } PUGI__FN bool operator||(const xml_node& lhs, bool rhs) { return (bool)lhs || rhs; } #endif PUGI__FN xml_text::xml_text(xml_node_struct* root): _root(root) { } PUGI__FN xml_node_struct* xml_text::_data() const { if (!_root || impl::is_text_node(_root)) return _root; for (xml_node_struct* node = _root->first_child; node; node = node->next_sibling) if (impl::is_text_node(node)) return node; return 0; } PUGI__FN xml_node_struct* xml_text::_data_new() { xml_node_struct* d = _data(); if (d) return d; return xml_node(_root).append_child(node_pcdata).internal_object(); } PUGI__FN xml_text::xml_text(): _root(0) { } PUGI__FN static void unspecified_bool_xml_text(xml_text***) { } PUGI__FN xml_text::operator xml_text::unspecified_bool_type() const { return _data() ? unspecified_bool_xml_text : 0; } PUGI__FN bool xml_text::operator!() const { return !_data(); } PUGI__FN bool xml_text::empty() const { return _data() == 0; } PUGI__FN const char_t* xml_text::get() const { xml_node_struct* d = _data(); return (d && d->value) ? d->value : PUGIXML_TEXT(""); } PUGI__FN const char_t* xml_text::as_string(const char_t* def) const { xml_node_struct* d = _data(); return (d && d->value) ? d->value : def; } PUGI__FN int xml_text::as_int(int def) const { xml_node_struct* d = _data(); return impl::get_value_int(d ? d->value : 0, def); } PUGI__FN unsigned int xml_text::as_uint(unsigned int def) const { xml_node_struct* d = _data(); return impl::get_value_uint(d ? d->value : 0, def); } PUGI__FN double xml_text::as_double(double def) const { xml_node_struct* d = _data(); return impl::get_value_double(d ? d->value : 0, def); } PUGI__FN float xml_text::as_float(float def) const { xml_node_struct* d = _data(); return impl::get_value_float(d ? d->value : 0, def); } PUGI__FN bool xml_text::as_bool(bool def) const { xml_node_struct* d = _data(); return impl::get_value_bool(d ? d->value : 0, def); } PUGI__FN bool xml_text::set(const char_t* rhs) { xml_node_struct* dn = _data_new(); return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } PUGI__FN bool xml_text::set(int rhs) { xml_node_struct* dn = _data_new(); return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } PUGI__FN bool xml_text::set(unsigned int rhs) { xml_node_struct* dn = _data_new(); return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } PUGI__FN bool xml_text::set(double rhs) { xml_node_struct* dn = _data_new(); return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } PUGI__FN bool xml_text::set(bool rhs) { xml_node_struct* dn = _data_new(); return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } PUGI__FN xml_text& xml_text::operator=(const char_t* rhs) { set(rhs); return *this; } PUGI__FN xml_text& xml_text::operator=(int rhs) { set(rhs); return *this; } PUGI__FN xml_text& xml_text::operator=(unsigned int rhs) { set(rhs); return *this; } PUGI__FN xml_text& xml_text::operator=(double rhs) { set(rhs); return *this; } PUGI__FN xml_text& xml_text::operator=(bool rhs) { set(rhs); return *this; } PUGI__FN xml_node xml_text::data() const { return xml_node(_data()); } #ifdef __BORLANDC__ PUGI__FN bool operator&&(const xml_text& lhs, bool rhs) { return (bool)lhs && rhs; } PUGI__FN bool operator||(const xml_text& lhs, bool rhs) { return (bool)lhs || rhs; } #endif PUGI__FN xml_node_iterator::xml_node_iterator() { } PUGI__FN xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node), _parent(node.parent()) { } PUGI__FN xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) { } PUGI__FN bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const { return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; } PUGI__FN bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const { return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; } PUGI__FN xml_node& xml_node_iterator::operator*() const { assert(_wrap._root); return _wrap; } PUGI__FN xml_node* xml_node_iterator::operator->() const { assert(_wrap._root); return const_cast(&_wrap); // BCC32 workaround } PUGI__FN const xml_node_iterator& xml_node_iterator::operator++() { assert(_wrap._root); _wrap._root = _wrap._root->next_sibling; return *this; } PUGI__FN xml_node_iterator xml_node_iterator::operator++(int) { xml_node_iterator temp = *this; ++*this; return temp; } PUGI__FN const xml_node_iterator& xml_node_iterator::operator--() { _wrap = _wrap._root ? _wrap.previous_sibling() : _parent.last_child(); return *this; } PUGI__FN xml_node_iterator xml_node_iterator::operator--(int) { xml_node_iterator temp = *this; --*this; return temp; } PUGI__FN xml_attribute_iterator::xml_attribute_iterator() { } PUGI__FN xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent): _wrap(attr), _parent(parent) { } PUGI__FN xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) { } PUGI__FN bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const { return _wrap._attr == rhs._wrap._attr && _parent._root == rhs._parent._root; } PUGI__FN bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const { return _wrap._attr != rhs._wrap._attr || _parent._root != rhs._parent._root; } PUGI__FN xml_attribute& xml_attribute_iterator::operator*() const { assert(_wrap._attr); return _wrap; } PUGI__FN xml_attribute* xml_attribute_iterator::operator->() const { assert(_wrap._attr); return const_cast(&_wrap); // BCC32 workaround } PUGI__FN const xml_attribute_iterator& xml_attribute_iterator::operator++() { assert(_wrap._attr); _wrap._attr = _wrap._attr->next_attribute; return *this; } PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator++(int) { xml_attribute_iterator temp = *this; ++*this; return temp; } PUGI__FN const xml_attribute_iterator& xml_attribute_iterator::operator--() { _wrap = _wrap._attr ? _wrap.previous_attribute() : _parent.last_attribute(); return *this; } PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator--(int) { xml_attribute_iterator temp = *this; --*this; return temp; } PUGI__FN xml_named_node_iterator::xml_named_node_iterator(): _name(0) { } PUGI__FN xml_named_node_iterator::xml_named_node_iterator(const xml_node& node, const char_t* name): _node(node), _name(name) { } PUGI__FN bool xml_named_node_iterator::operator==(const xml_named_node_iterator& rhs) const { return _node == rhs._node; } PUGI__FN bool xml_named_node_iterator::operator!=(const xml_named_node_iterator& rhs) const { return _node != rhs._node; } PUGI__FN xml_node& xml_named_node_iterator::operator*() const { assert(_node._root); return _node; } PUGI__FN xml_node* xml_named_node_iterator::operator->() const { assert(_node._root); return const_cast(&_node); // BCC32 workaround } PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator++() { assert(_node._root); _node = _node.next_sibling(_name); return *this; } PUGI__FN xml_named_node_iterator xml_named_node_iterator::operator++(int) { xml_named_node_iterator temp = *this; ++*this; return temp; } PUGI__FN xml_parse_result::xml_parse_result(): status(status_internal_error), offset(0), encoding(encoding_auto) { } PUGI__FN xml_parse_result::operator bool() const { return status == status_ok; } PUGI__FN const char* xml_parse_result::description() const { switch (status) { case status_ok: return "No error"; case status_file_not_found: return "File was not found"; case status_io_error: return "Error reading from file/stream"; case status_out_of_memory: return "Could not allocate memory"; case status_internal_error: return "Internal error occurred"; case status_unrecognized_tag: return "Could not determine tag type"; case status_bad_pi: return "Error parsing document declaration/processing instruction"; case status_bad_comment: return "Error parsing comment"; case status_bad_cdata: return "Error parsing CDATA section"; case status_bad_doctype: return "Error parsing document type declaration"; case status_bad_pcdata: return "Error parsing PCDATA section"; case status_bad_start_element: return "Error parsing start element tag"; case status_bad_attribute: return "Error parsing element attribute"; case status_bad_end_element: return "Error parsing end element tag"; case status_end_element_mismatch: return "Start-end tags mismatch"; default: return "Unknown error"; } } PUGI__FN xml_document::xml_document(): _buffer(0) { create(); } PUGI__FN xml_document::~xml_document() { destroy(); } PUGI__FN void xml_document::reset() { destroy(); create(); } PUGI__FN void xml_document::reset(const xml_document& proto) { reset(); for (xml_node cur = proto.first_child(); cur; cur = cur.next_sibling()) append_copy(cur); } PUGI__FN void xml_document::create() { // initialize sentinel page PUGI__STATIC_ASSERT(offsetof(impl::xml_memory_page, data) + sizeof(impl::xml_document_struct) + impl::xml_memory_page_alignment <= sizeof(_memory)); // align upwards to page boundary void* page_memory = reinterpret_cast((reinterpret_cast(_memory) + (impl::xml_memory_page_alignment - 1)) & ~(impl::xml_memory_page_alignment - 1)); // prepare page structure impl::xml_memory_page* page = impl::xml_memory_page::construct(page_memory); page->busy_size = impl::xml_memory_page_size; // allocate new root _root = new (page->data) impl::xml_document_struct(page); _root->prev_sibling_c = _root; // setup sentinel page page->allocator = static_cast(_root); } PUGI__FN void xml_document::destroy() { // destroy static storage if (_buffer) { impl::xml_memory::deallocate(_buffer); _buffer = 0; } // destroy dynamic storage, leave sentinel page (it's in static memory) if (_root) { impl::xml_memory_page* root_page = reinterpret_cast(_root->header & impl::xml_memory_page_pointer_mask); assert(root_page && !root_page->prev && !root_page->memory); // destroy all pages for (impl::xml_memory_page* page = root_page->next; page; ) { impl::xml_memory_page* next = page->next; impl::xml_allocator::deallocate_page(page); page = next; } // cleanup root page root_page->allocator = 0; root_page->next = 0; root_page->busy_size = root_page->freed_size = 0; _root = 0; } } #ifndef PUGIXML_NO_STL PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options, xml_encoding encoding) { reset(); return impl::load_stream_impl(*this, stream, options, encoding); } PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options) { reset(); return impl::load_stream_impl(*this, stream, options, encoding_wchar); } #endif PUGI__FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options) { // Force native encoding (skip autodetection) #ifdef PUGIXML_WCHAR_MODE xml_encoding encoding = encoding_wchar; #else xml_encoding encoding = encoding_utf8; #endif return load_buffer(contents, impl::strlength(contents) * sizeof(char_t), options, encoding); } PUGI__FN xml_parse_result xml_document::load_file(const char* path_, unsigned int options, xml_encoding encoding) { reset(); FILE* file = fopen(path_, "rb"); return impl::load_file_impl(*this, file, options, encoding); } PUGI__FN xml_parse_result xml_document::load_file(const wchar_t* path_, unsigned int options, xml_encoding encoding) { reset(); FILE* file = impl::open_file_wide(path_, L"rb"); return impl::load_file_impl(*this, file, options, encoding); } PUGI__FN xml_parse_result xml_document::load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own) { reset(); // check input buffer assert(contents || size == 0); // get actual encoding xml_encoding buffer_encoding = impl::get_buffer_encoding(encoding, contents, size); // get private buffer char_t* buffer = 0; size_t length = 0; if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return impl::make_parse_result(status_out_of_memory); // delete original buffer if we performed a conversion if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents); // parse xml_parse_result res = impl::xml_parser::parse(buffer, length, _root, options); // remember encoding res.encoding = buffer_encoding; // grab onto buffer if it's our buffer, user is responsible for deallocating contens himself if (own || buffer != contents) _buffer = buffer; return res; } PUGI__FN xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) { return load_buffer_impl(const_cast(contents), size, options, encoding, false, false); } PUGI__FN xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options, xml_encoding encoding) { return load_buffer_impl(contents, size, options, encoding, true, false); } PUGI__FN xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options, xml_encoding encoding) { return load_buffer_impl(contents, size, options, encoding, true, true); } PUGI__FN void xml_document::save(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding) const { impl::xml_buffered_writer buffered_writer(writer, encoding); if ((flags & format_write_bom) && encoding != encoding_latin1) { // BOM always represents the codepoint U+FEFF, so just write it in native encoding #ifdef PUGIXML_WCHAR_MODE unsigned int bom = 0xfeff; buffered_writer.write(static_cast(bom)); #else buffered_writer.write('\xef', '\xbb', '\xbf'); #endif } if (!(flags & format_no_declaration) && !impl::has_declaration(*this)) { buffered_writer.write(PUGIXML_TEXT("'); if (!(flags & format_raw)) buffered_writer.write('\n'); } impl::node_output(buffered_writer, *this, indent, flags, 0); } #ifndef PUGIXML_NO_STL PUGI__FN void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding) const { xml_writer_stream writer(stream); save(writer, indent, flags, encoding); } PUGI__FN void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags) const { xml_writer_stream writer(stream); save(writer, indent, flags, encoding_wchar); } #endif PUGI__FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const { FILE* file = fopen(path_, (flags & format_save_file_text) ? "w" : "wb"); return impl::save_file_impl(*this, file, indent, flags, encoding); } PUGI__FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const { FILE* file = impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb"); return impl::save_file_impl(*this, file, indent, flags, encoding); } PUGI__FN xml_node xml_document::document_element() const { for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) if ((i->header & impl::xml_memory_page_type_mask) + 1 == node_element) return xml_node(i); return xml_node(); } #ifndef PUGIXML_NO_STL PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const wchar_t* str) { assert(str); return impl::as_utf8_impl(str, wcslen(str)); } PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const std::basic_string& str) { return impl::as_utf8_impl(str.c_str(), str.size()); } PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const char* str) { assert(str); return impl::as_wide_impl(str, strlen(str)); } PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const std::string& str) { return impl::as_wide_impl(str.c_str(), str.size()); } #endif PUGI__FN void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate) { impl::xml_memory::allocate = allocate; impl::xml_memory::deallocate = deallocate; } PUGI__FN allocation_function PUGIXML_FUNCTION get_memory_allocation_function() { return impl::xml_memory::allocate; } PUGI__FN deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function() { return impl::xml_memory::deallocate; } } } OIIO_NAMESPACE_EXIT #if !defined(PUGIXML_NO_STL) && ((defined(_MSC_VER) && _MSC_VER < 1400) || defined(__ICC)) namespace std { // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const OpenImageIO::pugi::xml_node_iterator&) { return std::bidirectional_iterator_tag(); } PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const OpenImageIO::pugi::xml_attribute_iterator&) { return std::bidirectional_iterator_tag(); } PUGI__FN std::forward_iterator_tag _Iter_cat(const OpenImageIO::pugi::xml_named_node_iterator&) { return std::forward_iterator_tag(); } } #endif #if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) namespace std { // Workarounds for (non-standard) iterator category detection PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_node_iterator&) { return std::bidirectional_iterator_tag(); } PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_attribute_iterator&) { return std::bidirectional_iterator_tag(); } PUGI__FN std::forward_iterator_tag __iterator_category(const pugi::xml_named_node_iterator&) { return std::forward_iterator_tag(); } } #endif #ifndef PUGIXML_NO_XPATH // STL replacements PUGI__NS_BEGIN struct equal_to { template bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; } }; struct not_equal_to { template bool operator()(const T& lhs, const T& rhs) const { return lhs != rhs; } }; struct less { template bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } }; struct less_equal { template bool operator()(const T& lhs, const T& rhs) const { return lhs <= rhs; } }; template void swap(T& lhs, T& rhs) { T temp = lhs; lhs = rhs; rhs = temp; } template I min_element(I begin, I end, const Pred& pred) { I result = begin; for (I it = begin + 1; it != end; ++it) if (pred(*it, *result)) result = it; return result; } template void reverse(I begin, I end) { while (begin + 1 < end) swap(*begin++, *--end); } template I unique(I begin, I end) { // fast skip head while (begin + 1 < end && *begin != *(begin + 1)) begin++; if (begin == end) return begin; // last written element I write = begin++; // merge unique elements while (begin != end) { if (*begin != *write) *++write = *begin++; else begin++; } // past-the-end (write points to live element) return write + 1; } template void copy_backwards(I begin, I end, I target) { while (begin != end) *--target = *--end; } template void insertion_sort(I begin, I end, const Pred& pred, T*) { assert(begin != end); for (I it = begin + 1; it != end; ++it) { T val = *it; if (pred(val, *begin)) { // move to front copy_backwards(begin, it, it + 1); *begin = val; } else { I hole = it; // move hole backwards while (pred(val, *(hole - 1))) { *hole = *(hole - 1); hole--; } // fill hole with element *hole = val; } } } // std variant for elements with == template void partition(I begin, I middle, I end, const Pred& pred, I* out_eqbeg, I* out_eqend) { I eqbeg = middle, eqend = middle + 1; // expand equal range while (eqbeg != begin && *(eqbeg - 1) == *eqbeg) --eqbeg; while (eqend != end && *eqend == *eqbeg) ++eqend; // process outer elements I ltend = eqbeg, gtbeg = eqend; for (;;) { // find the element from the right side that belongs to the left one for (; gtbeg != end; ++gtbeg) if (!pred(*eqbeg, *gtbeg)) { if (*gtbeg == *eqbeg) swap(*gtbeg, *eqend++); else break; } // find the element from the left side that belongs to the right one for (; ltend != begin; --ltend) if (!pred(*(ltend - 1), *eqbeg)) { if (*eqbeg == *(ltend - 1)) swap(*(ltend - 1), *--eqbeg); else break; } // scanned all elements if (gtbeg == end && ltend == begin) { *out_eqbeg = eqbeg; *out_eqend = eqend; return; } // make room for elements by moving equal area if (gtbeg == end) { if (--ltend != --eqbeg) swap(*ltend, *eqbeg); swap(*eqbeg, *--eqend); } else if (ltend == begin) { if (eqend != gtbeg) swap(*eqbeg, *eqend); ++eqend; swap(*gtbeg++, *eqbeg++); } else swap(*gtbeg++, *--ltend); } } template void median3(I first, I middle, I last, const Pred& pred) { if (pred(*middle, *first)) swap(*middle, *first); if (pred(*last, *middle)) swap(*last, *middle); if (pred(*middle, *first)) swap(*middle, *first); } template void median(I first, I middle, I last, const Pred& pred) { if (last - first <= 40) { // median of three for small chunks median3(first, middle, last, pred); } else { // median of nine size_t step = (last - first + 1) / 8; median3(first, first + step, first + 2 * step, pred); median3(middle - step, middle, middle + step, pred); median3(last - 2 * step, last - step, last, pred); median3(first + step, middle, last - step, pred); } } template void sort(I begin, I end, const Pred& pred) { // sort large chunks while (end - begin > 32) { // find median element I middle = begin + (end - begin) / 2; median(begin, middle, end - 1, pred); // partition in three chunks (< = >) I eqbeg, eqend; partition(begin, middle, end, pred, &eqbeg, &eqend); // loop on larger half if (eqbeg - begin > end - eqend) { sort(eqend, end, pred); end = eqbeg; } else { sort(begin, eqbeg, pred); begin = eqend; } } // insertion sort small chunk if (begin != end) insertion_sort(begin, end, pred, &*begin); } PUGI__NS_END // Allocator used for AST and evaluation stacks PUGI__NS_BEGIN struct xpath_memory_block { xpath_memory_block* next; char data[ #ifdef PUGIXML_MEMORY_XPATH_PAGE_SIZE PUGIXML_MEMORY_XPATH_PAGE_SIZE #else 4096 #endif ]; }; class xpath_allocator { xpath_memory_block* _root; size_t _root_size; public: #ifdef PUGIXML_NO_EXCEPTIONS jmp_buf* error_handler; #endif xpath_allocator(xpath_memory_block* root, size_t root_size = 0): _root(root), _root_size(root_size) { #ifdef PUGIXML_NO_EXCEPTIONS error_handler = 0; #endif } void* allocate_nothrow(size_t size) { const size_t block_capacity = sizeof(_root->data); // align size so that we're able to store pointers in subsequent blocks size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); if (_root_size + size <= block_capacity) { void* buf = _root->data + _root_size; _root_size += size; return buf; } else { size_t block_data_size = (size > block_capacity) ? size : block_capacity; size_t block_size = block_data_size + offsetof(xpath_memory_block, data); xpath_memory_block* block = static_cast(xml_memory::allocate(block_size)); if (!block) return 0; block->next = _root; _root = block; _root_size = size; return block->data; } } void* allocate(size_t size) { void* result = allocate_nothrow(size); if (!result) { #ifdef PUGIXML_NO_EXCEPTIONS assert(error_handler); longjmp(*error_handler, 1); #else throw std::bad_alloc(); #endif } return result; } void* reallocate(void* ptr, size_t old_size, size_t new_size) { // align size so that we're able to store pointers in subsequent blocks old_size = (old_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); new_size = (new_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); // we can only reallocate the last object assert(ptr == 0 || static_cast(ptr) + old_size == _root->data + _root_size); // adjust root size so that we have not allocated the object at all bool only_object = (_root_size == old_size); if (ptr) _root_size -= old_size; // allocate a new version (this will obviously reuse the memory if possible) void* result = allocate(new_size); assert(result); // we have a new block if (result != ptr && ptr) { // copy old data assert(new_size > old_size); memcpy(result, ptr, old_size); // free the previous page if it had no other objects if (only_object) { assert(_root->data == result); assert(_root->next); xpath_memory_block* next = _root->next->next; if (next) { // deallocate the whole page, unless it was the first one xml_memory::deallocate(_root->next); _root->next = next; } } } return result; } void revert(const xpath_allocator& state) { // free all new pages xpath_memory_block* cur = _root; while (cur != state._root) { xpath_memory_block* next = cur->next; xml_memory::deallocate(cur); cur = next; } // restore state _root = state._root; _root_size = state._root_size; } void release() { xpath_memory_block* cur = _root; assert(cur); while (cur->next) { xpath_memory_block* next = cur->next; xml_memory::deallocate(cur); cur = next; } } }; struct xpath_allocator_capture { xpath_allocator_capture(xpath_allocator* alloc): _target(alloc), _state(*alloc) { } ~xpath_allocator_capture() { _target->revert(_state); } xpath_allocator* _target; xpath_allocator _state; }; struct xpath_stack { xpath_allocator* result; xpath_allocator* temp; }; struct xpath_stack_data { xpath_memory_block blocks[2]; xpath_allocator result; xpath_allocator temp; xpath_stack stack; #ifdef PUGIXML_NO_EXCEPTIONS jmp_buf error_handler; #endif xpath_stack_data(): result(blocks + 0), temp(blocks + 1) { blocks[0].next = blocks[1].next = 0; stack.result = &result; stack.temp = &temp; #ifdef PUGIXML_NO_EXCEPTIONS result.error_handler = temp.error_handler = &error_handler; #endif } ~xpath_stack_data() { result.release(); temp.release(); } }; PUGI__NS_END // String class PUGI__NS_BEGIN class xpath_string { const char_t* _buffer; bool _uses_heap; static char_t* duplicate_string(const char_t* string, size_t length, xpath_allocator* alloc) { char_t* result = static_cast(alloc->allocate((length + 1) * sizeof(char_t))); assert(result); memcpy(result, string, length * sizeof(char_t)); result[length] = 0; return result; } static char_t* duplicate_string(const char_t* string, xpath_allocator* alloc) { return duplicate_string(string, strlength(string), alloc); } public: xpath_string(): _buffer(PUGIXML_TEXT("")), _uses_heap(false) { } explicit xpath_string(const char_t* str, xpath_allocator* alloc) { bool empty_ = (*str == 0); _buffer = empty_ ? PUGIXML_TEXT("") : duplicate_string(str, alloc); _uses_heap = !empty_; } explicit xpath_string(const char_t* str, bool use_heap): _buffer(str), _uses_heap(use_heap) { } xpath_string(const char_t* begin, const char_t* end, xpath_allocator* alloc) { assert(begin <= end); bool empty_ = (begin == end); _buffer = empty_ ? PUGIXML_TEXT("") : duplicate_string(begin, static_cast(end - begin), alloc); _uses_heap = !empty_; } void append(const xpath_string& o, xpath_allocator* alloc) { // skip empty sources if (!*o._buffer) return; // fast append for constant empty target and constant source if (!*_buffer && !_uses_heap && !o._uses_heap) { _buffer = o._buffer; } else { // need to make heap copy size_t target_length = strlength(_buffer); size_t source_length = strlength(o._buffer); size_t result_length = target_length + source_length; // allocate new buffer char_t* result = static_cast(alloc->reallocate(_uses_heap ? const_cast(_buffer) : 0, (target_length + 1) * sizeof(char_t), (result_length + 1) * sizeof(char_t))); assert(result); // append first string to the new buffer in case there was no reallocation if (!_uses_heap) memcpy(result, _buffer, target_length * sizeof(char_t)); // append second string to the new buffer memcpy(result + target_length, o._buffer, source_length * sizeof(char_t)); result[result_length] = 0; // finalize _buffer = result; _uses_heap = true; } } const char_t* c_str() const { return _buffer; } size_t length() const { return strlength(_buffer); } char_t* data(xpath_allocator* alloc) { // make private heap copy if (!_uses_heap) { _buffer = duplicate_string(_buffer, alloc); _uses_heap = true; } return const_cast(_buffer); } bool empty() const { return *_buffer == 0; } bool operator==(const xpath_string& o) const { return strequal(_buffer, o._buffer); } bool operator!=(const xpath_string& o) const { return !strequal(_buffer, o._buffer); } bool uses_heap() const { return _uses_heap; } }; PUGI__FN xpath_string xpath_string_const(const char_t* str) { return xpath_string(str, false); } PUGI__NS_END PUGI__NS_BEGIN PUGI__FN bool starts_with(const char_t* string, const char_t* pattern) { while (*pattern && *string == *pattern) { string++; pattern++; } return *pattern == 0; } PUGI__FN const char_t* find_char(const char_t* s, char_t c) { #ifdef PUGIXML_WCHAR_MODE return wcschr(s, c); #else return strchr(s, c); #endif } PUGI__FN const char_t* find_substring(const char_t* s, const char_t* p) { #ifdef PUGIXML_WCHAR_MODE // MSVC6 wcsstr bug workaround (if s is empty it always returns 0) return (*p == 0) ? s : wcsstr(s, p); #else return strstr(s, p); #endif } // Converts symbol to lower case, if it is an ASCII one PUGI__FN char_t tolower_ascii(char_t ch) { return static_cast(ch - 'A') < 26 ? static_cast(ch | ' ') : ch; } PUGI__FN xpath_string string_value(const xpath_node& na, xpath_allocator* alloc) { if (na.attribute()) return xpath_string_const(na.attribute().value()); else { const xml_node& n = na.node(); switch (n.type()) { case node_pcdata: case node_cdata: case node_comment: case node_pi: return xpath_string_const(n.value()); case node_document: case node_element: { xpath_string result; xml_node cur = n.first_child(); while (cur && cur != n) { if (cur.type() == node_pcdata || cur.type() == node_cdata) result.append(xpath_string_const(cur.value()), alloc); if (cur.first_child()) cur = cur.first_child(); else if (cur.next_sibling()) cur = cur.next_sibling(); else { while (!cur.next_sibling() && cur != n) cur = cur.parent(); if (cur != n) cur = cur.next_sibling(); } } return result; } default: return xpath_string(); } } } PUGI__FN unsigned int node_height(xml_node n) { unsigned int result = 0; while (n) { ++result; n = n.parent(); } return result; } PUGI__FN bool node_is_before(xml_node ln, unsigned int lh, xml_node rn, unsigned int rh) { // normalize heights for (unsigned int i = rh; i < lh; i++) ln = ln.parent(); for (unsigned int j = lh; j < rh; j++) rn = rn.parent(); // one node is the ancestor of the other if (ln == rn) return lh < rh; // find common ancestor while (ln.parent() != rn.parent()) { ln = ln.parent(); rn = rn.parent(); } // there is no common ancestor (the shared parent is null), nodes are from different documents if (!ln.parent()) return ln < rn; // determine sibling order for (; ln; ln = ln.next_sibling()) if (ln == rn) return true; return false; } PUGI__FN bool node_is_ancestor(xml_node parent, xml_node node) { while (node && node != parent) node = node.parent(); return parent && node == parent; } PUGI__FN const void* document_order(const xpath_node& xnode) { xml_node_struct* node = xnode.node().internal_object(); if (node) { if (node->name && (node->header & xml_memory_page_name_allocated_mask) == 0) return node->name; if (node->value && (node->header & xml_memory_page_value_allocated_mask) == 0) return node->value; return 0; } xml_attribute_struct* attr = xnode.attribute().internal_object(); if (attr) { if ((attr->header & xml_memory_page_name_allocated_mask) == 0) return attr->name; if ((attr->header & xml_memory_page_value_allocated_mask) == 0) return attr->value; return 0; } return 0; } struct document_order_comparator { bool operator()(const xpath_node& lhs, const xpath_node& rhs) const { // optimized document order based check const void* lo = document_order(lhs); const void* ro = document_order(rhs); if (lo && ro) return lo < ro; // slow comparison xml_node ln = lhs.node(), rn = rhs.node(); // compare attributes if (lhs.attribute() && rhs.attribute()) { // shared parent if (lhs.parent() == rhs.parent()) { // determine sibling order for (xml_attribute a = lhs.attribute(); a; a = a.next_attribute()) if (a == rhs.attribute()) return true; return false; } // compare attribute parents ln = lhs.parent(); rn = rhs.parent(); } else if (lhs.attribute()) { // attributes go after the parent element if (lhs.parent() == rhs.node()) return false; ln = lhs.parent(); } else if (rhs.attribute()) { // attributes go after the parent element if (rhs.parent() == lhs.node()) return true; rn = rhs.parent(); } if (ln == rn) return false; unsigned int lh = node_height(ln); unsigned int rh = node_height(rn); return node_is_before(ln, lh, rn, rh); } }; struct duplicate_comparator { bool operator()(const xpath_node& lhs, const xpath_node& rhs) const { if (lhs.attribute()) return rhs.attribute() ? lhs.attribute() < rhs.attribute() : true; else return rhs.attribute() ? false : lhs.node() < rhs.node(); } }; PUGI__FN double gen_nan() { #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24)) union { float f; uint32_t i; } u[sizeof(float) == sizeof(uint32_t) ? 1 : -1]; u[0].i = 0x7fc00000; return u[0].f; #else // fallback const volatile double zero = 0.0; return zero / zero; #endif } PUGI__FN bool is_nan(double value) { #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) return !!_isnan(value); #elif defined(fpclassify) && defined(FP_NAN) return fpclassify(value) == FP_NAN; #else // fallback const volatile double v = value; return v != v; #endif } PUGI__FN const char_t* convert_number_to_string_special(double value) { #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) if (_finite(value)) return (value == 0) ? PUGIXML_TEXT("0") : 0; if (_isnan(value)) return PUGIXML_TEXT("NaN"); return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); #elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) switch (fpclassify(value)) { case FP_NAN: return PUGIXML_TEXT("NaN"); case FP_INFINITE: return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); case FP_ZERO: return PUGIXML_TEXT("0"); default: return 0; } #else // fallback const volatile double v = value; if (v == 0) return PUGIXML_TEXT("0"); if (v != v) return PUGIXML_TEXT("NaN"); if (v * 2 == v) return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); return 0; #endif } PUGI__FN bool convert_number_to_boolean(double value) { return (value != 0 && !is_nan(value)); } PUGI__FN void truncate_zeros(char* begin, char* end) { while (begin != end && end[-1] == '0') end--; *end = 0; } // gets mantissa digits in the form of 0.xxxxx with 0. implied and the exponent #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) { // get base values int sign, exponent; _ecvt_s(buffer, buffer_size, value, DBL_DIG + 1, &exponent, &sign); // truncate redundant zeros truncate_zeros(buffer, buffer + strlen(buffer)); // fill results *out_mantissa = buffer; *out_exponent = exponent; } #else PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) { // get a scientific notation value with IEEE DBL_DIG decimals sprintf(buffer, "%.*e", DBL_DIG, value); assert(strlen(buffer) < buffer_size); (void)!buffer_size; // get the exponent (possibly negative) char* exponent_string = strchr(buffer, 'e'); assert(exponent_string); int exponent = atoi(exponent_string + 1); // extract mantissa string: skip sign char* mantissa = buffer[0] == '-' ? buffer + 1 : buffer; assert(mantissa[0] != '0' && mantissa[1] == '.'); // divide mantissa by 10 to eliminate integer part mantissa[1] = mantissa[0]; mantissa++; exponent++; // remove extra mantissa digits and zero-terminate mantissa truncate_zeros(mantissa, exponent_string); // fill results *out_mantissa = mantissa; *out_exponent = exponent; } #endif PUGI__FN xpath_string convert_number_to_string(double value, xpath_allocator* alloc) { // try special number conversion const char_t* special = convert_number_to_string_special(value); if (special) return xpath_string_const(special); // get mantissa + exponent form char mantissa_buffer[64]; char* mantissa; int exponent; convert_number_to_mantissa_exponent(value, mantissa_buffer, sizeof(mantissa_buffer), &mantissa, &exponent); // make the number! char_t result[512]; char_t* s = result; // sign if (value < 0) *s++ = '-'; // integer part if (exponent <= 0) { *s++ = '0'; } else { while (exponent > 0) { assert(*mantissa == 0 || static_cast(*mantissa - '0') <= 9); *s++ = *mantissa ? *mantissa++ : '0'; exponent--; } } // fractional part if (*mantissa) { // decimal point *s++ = '.'; // extra zeroes from negative exponent while (exponent < 0) { *s++ = '0'; exponent++; } // extra mantissa digits while (*mantissa) { assert(static_cast(*mantissa - '0') <= 9); *s++ = *mantissa++; } } // zero-terminate assert(s < result + sizeof(result) / sizeof(result[0])); *s = 0; return xpath_string(result, alloc); } PUGI__FN bool check_string_to_number_format(const char_t* string) { // parse leading whitespace while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; // parse sign if (*string == '-') ++string; if (!*string) return false; // if there is no integer part, there should be a decimal part with at least one digit if (!PUGI__IS_CHARTYPEX(string[0], ctx_digit) && (string[0] != '.' || !PUGI__IS_CHARTYPEX(string[1], ctx_digit))) return false; // parse integer part while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; // parse decimal part if (*string == '.') { ++string; while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; } // parse trailing whitespace while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; return *string == 0; } PUGI__FN double convert_string_to_number(const char_t* string) { // check string format if (!check_string_to_number_format(string)) return gen_nan(); // parse string #ifdef PUGIXML_WCHAR_MODE return wcstod(string, 0); #else return atof(string); #endif } PUGI__FN bool convert_string_to_number(const char_t* begin, const char_t* end, double* out_result) { char_t buffer[32]; size_t length = static_cast(end - begin); char_t* scratch = buffer; if (length >= sizeof(buffer) / sizeof(buffer[0])) { // need to make dummy on-heap copy scratch = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); if (!scratch) return false; } // copy string to zero-terminated buffer and perform conversion memcpy(scratch, begin, length * sizeof(char_t)); scratch[length] = 0; *out_result = convert_string_to_number(scratch); // free dummy buffer if (scratch != buffer) xml_memory::deallocate(scratch); return true; } PUGI__FN double round_nearest(double value) { return floor(value + 0.5); } PUGI__FN double round_nearest_nzero(double value) { // same as round_nearest, but returns -0 for [-0.5, -0] // ceil is used to differentiate between +0 and -0 (we return -0 for [-0.5, -0] and +0 for +0) return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5); } PUGI__FN const char_t* qualified_name(const xpath_node& node) { return node.attribute() ? node.attribute().name() : node.node().name(); } PUGI__FN const char_t* local_name(const xpath_node& node) { const char_t* name = qualified_name(node); const char_t* p = find_char(name, ':'); return p ? p + 1 : name; } struct namespace_uri_predicate { const char_t* prefix; size_t prefix_length; namespace_uri_predicate(const char_t* name) { const char_t* pos = find_char(name, ':'); prefix = pos ? name : 0; prefix_length = pos ? static_cast(pos - name) : 0; } bool operator()(const xml_attribute& a) const { const char_t* name = a.name(); if (!starts_with(name, PUGIXML_TEXT("xmlns"))) return false; return prefix ? name[5] == ':' && strequalrange(name + 6, prefix, prefix_length) : name[5] == 0; } }; PUGI__FN const char_t* namespace_uri(const xml_node& node) { namespace_uri_predicate pred = node.name(); xml_node p = node; while (p) { xml_attribute a = p.find_attribute(pred); if (a) return a.value(); p = p.parent(); } return PUGIXML_TEXT(""); } PUGI__FN const char_t* namespace_uri(const xml_attribute& attr, const xml_node& parent) { namespace_uri_predicate pred = attr.name(); // Default namespace does not apply to attributes if (!pred.prefix) return PUGIXML_TEXT(""); xml_node p = parent; while (p) { xml_attribute a = p.find_attribute(pred); if (a) return a.value(); p = p.parent(); } return PUGIXML_TEXT(""); } PUGI__FN const char_t* namespace_uri(const xpath_node& node) { return node.attribute() ? namespace_uri(node.attribute(), node.parent()) : namespace_uri(node.node()); } PUGI__FN void normalize_space(char_t* buffer) { char_t* write = buffer; for (char_t* it = buffer; *it; ) { char_t ch = *it++; if (PUGI__IS_CHARTYPE(ch, ct_space)) { // replace whitespace sequence with single space while (PUGI__IS_CHARTYPE(*it, ct_space)) it++; // avoid leading spaces if (write != buffer) *write++ = ' '; } else *write++ = ch; } // remove trailing space if (write != buffer && PUGI__IS_CHARTYPE(write[-1], ct_space)) write--; // zero-terminate *write = 0; } PUGI__FN void translate(char_t* buffer, const char_t* from, const char_t* to) { size_t to_length = strlength(to); char_t* write = buffer; while (*buffer) { PUGI__DMC_VOLATILE char_t ch = *buffer++; const char_t* pos = find_char(from, ch); if (!pos) *write++ = ch; // do not process else if (static_cast(pos - from) < to_length) *write++ = to[pos - from]; // replace } // zero-terminate *write = 0; } struct xpath_variable_boolean: xpath_variable { xpath_variable_boolean(): value(false) { } bool value; char_t name[1]; }; struct xpath_variable_number: xpath_variable { xpath_variable_number(): value(0) { } double value; char_t name[1]; }; struct xpath_variable_string: xpath_variable { xpath_variable_string(): value(0) { } ~xpath_variable_string() { if (value) xml_memory::deallocate(value); } char_t* value; char_t name[1]; }; struct xpath_variable_node_set: xpath_variable { xpath_node_set value; char_t name[1]; }; static const xpath_node_set dummy_node_set; PUGI__FN unsigned int hash_string(const char_t* str) { // Jenkins one-at-a-time hash (http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time) unsigned int result = 0; while (*str) { result += static_cast(*str++); result += result << 10; result ^= result >> 6; } result += result << 3; result ^= result >> 11; result += result << 15; return result; } template PUGI__FN T* new_xpath_variable(const char_t* name) { size_t length = strlength(name); if (length == 0) return 0; // empty variable names are invalid // $$ we can't use offsetof(T, name) because T is non-POD, so we just allocate additional length characters void* memory = xml_memory::allocate(sizeof(T) + length * sizeof(char_t)); if (!memory) return 0; T* result = new (memory) T(); memcpy(result->name, name, (length + 1) * sizeof(char_t)); return result; } PUGI__FN xpath_variable* new_xpath_variable(xpath_value_type type, const char_t* name) { switch (type) { case xpath_type_node_set: return new_xpath_variable(name); case xpath_type_number: return new_xpath_variable(name); case xpath_type_string: return new_xpath_variable(name); case xpath_type_boolean: return new_xpath_variable(name); default: return 0; } } template PUGI__FN void delete_xpath_variable(T* var) { var->~T(); xml_memory::deallocate(var); } PUGI__FN void delete_xpath_variable(xpath_value_type type, xpath_variable* var) { switch (type) { case xpath_type_node_set: delete_xpath_variable(static_cast(var)); break; case xpath_type_number: delete_xpath_variable(static_cast(var)); break; case xpath_type_string: delete_xpath_variable(static_cast(var)); break; case xpath_type_boolean: delete_xpath_variable(static_cast(var)); break; default: assert(!"Invalid variable type"); } } PUGI__FN xpath_variable* get_variable(xpath_variable_set* set, const char_t* begin, const char_t* end) { char_t buffer[32]; size_t length = static_cast(end - begin); char_t* scratch = buffer; if (length >= sizeof(buffer) / sizeof(buffer[0])) { // need to make dummy on-heap copy scratch = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); if (!scratch) return 0; } // copy string to zero-terminated buffer and perform lookup memcpy(scratch, begin, length * sizeof(char_t)); scratch[length] = 0; xpath_variable* result = set->get(scratch); // free dummy buffer if (scratch != buffer) xml_memory::deallocate(scratch); return result; } PUGI__NS_END // Internal node set class PUGI__NS_BEGIN PUGI__FN xpath_node_set::type_t xpath_sort(xpath_node* begin, xpath_node* end, xpath_node_set::type_t type, bool rev) { xpath_node_set::type_t order = rev ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; if (type == xpath_node_set::type_unsorted) { sort(begin, end, document_order_comparator()); type = xpath_node_set::type_sorted; } if (type != order) reverse(begin, end); return order; } PUGI__FN xpath_node xpath_first(const xpath_node* begin, const xpath_node* end, xpath_node_set::type_t type) { if (begin == end) return xpath_node(); switch (type) { case xpath_node_set::type_sorted: return *begin; case xpath_node_set::type_sorted_reverse: return *(end - 1); case xpath_node_set::type_unsorted: return *min_element(begin, end, document_order_comparator()); default: assert(!"Invalid node set type"); return xpath_node(); } } class xpath_node_set_raw { xpath_node_set::type_t _type; xpath_node* _begin; xpath_node* _end; xpath_node* _eos; public: xpath_node_set_raw(): _type(xpath_node_set::type_unsorted), _begin(0), _end(0), _eos(0) { } xpath_node* begin() const { return _begin; } xpath_node* end() const { return _end; } bool empty() const { return _begin == _end; } size_t size() const { return static_cast(_end - _begin); } xpath_node first() const { return xpath_first(_begin, _end, _type); } void push_back(const xpath_node& node, xpath_allocator* alloc) { if (_end == _eos) { size_t capacity = static_cast(_eos - _begin); // get new capacity (1.5x rule) size_t new_capacity = capacity + capacity / 2 + 1; // reallocate the old array or allocate a new one xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node))); assert(data); // finalize _begin = data; _end = data + capacity; _eos = data + new_capacity; } *_end++ = node; } void append(const xpath_node* begin_, const xpath_node* end_, xpath_allocator* alloc) { size_t size_ = static_cast(_end - _begin); size_t capacity = static_cast(_eos - _begin); size_t count = static_cast(end_ - begin_); if (size_ + count > capacity) { // reallocate the old array or allocate a new one xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), (size_ + count) * sizeof(xpath_node))); assert(data); // finalize _begin = data; _end = data + size_; _eos = data + size_ + count; } memcpy(_end, begin_, count * sizeof(xpath_node)); _end += count; } void sort_do() { _type = xpath_sort(_begin, _end, _type, false); } void truncate(xpath_node* pos) { assert(_begin <= pos && pos <= _end); _end = pos; } void remove_duplicates() { if (_type == xpath_node_set::type_unsorted) sort(_begin, _end, duplicate_comparator()); _end = unique(_begin, _end); } xpath_node_set::type_t type() const { return _type; } void set_type(xpath_node_set::type_t value) { _type = value; } }; PUGI__NS_END PUGI__NS_BEGIN struct xpath_context { xpath_node n; size_t position, size; xpath_context(const xpath_node& n_, size_t position_, size_t size_): n(n_), position(position_), size(size_) { } }; enum lexeme_t { lex_none = 0, lex_equal, lex_not_equal, lex_less, lex_greater, lex_less_or_equal, lex_greater_or_equal, lex_plus, lex_minus, lex_multiply, lex_union, lex_var_ref, lex_open_brace, lex_close_brace, lex_quoted_string, lex_number, lex_slash, lex_double_slash, lex_open_square_brace, lex_close_square_brace, lex_string, lex_comma, lex_axis_attribute, lex_dot, lex_double_dot, lex_double_colon, lex_eof }; struct xpath_lexer_string { const char_t* begin; const char_t* end; xpath_lexer_string(): begin(0), end(0) { } bool operator==(const char_t* other) const { size_t length = static_cast(end - begin); return strequalrange(other, begin, length); } }; class xpath_lexer { const char_t* _cur; const char_t* _cur_lexeme_pos; xpath_lexer_string _cur_lexeme_contents; lexeme_t _cur_lexeme; public: explicit xpath_lexer(const char_t* query): _cur(query) { next(); } const char_t* state() const { return _cur; } void next() { const char_t* cur = _cur; while (PUGI__IS_CHARTYPE(*cur, ct_space)) ++cur; // save lexeme position for error reporting _cur_lexeme_pos = cur; switch (*cur) { case 0: _cur_lexeme = lex_eof; break; case '>': if (*(cur+1) == '=') { cur += 2; _cur_lexeme = lex_greater_or_equal; } else { cur += 1; _cur_lexeme = lex_greater; } break; case '<': if (*(cur+1) == '=') { cur += 2; _cur_lexeme = lex_less_or_equal; } else { cur += 1; _cur_lexeme = lex_less; } break; case '!': if (*(cur+1) == '=') { cur += 2; _cur_lexeme = lex_not_equal; } else { _cur_lexeme = lex_none; } break; case '=': cur += 1; _cur_lexeme = lex_equal; break; case '+': cur += 1; _cur_lexeme = lex_plus; break; case '-': cur += 1; _cur_lexeme = lex_minus; break; case '*': cur += 1; _cur_lexeme = lex_multiply; break; case '|': cur += 1; _cur_lexeme = lex_union; break; case '$': cur += 1; if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) { _cur_lexeme_contents.begin = cur; while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; if (cur[0] == ':' && PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // qname { cur++; // : while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; } _cur_lexeme_contents.end = cur; _cur_lexeme = lex_var_ref; } else { _cur_lexeme = lex_none; } break; case '(': cur += 1; _cur_lexeme = lex_open_brace; break; case ')': cur += 1; _cur_lexeme = lex_close_brace; break; case '[': cur += 1; _cur_lexeme = lex_open_square_brace; break; case ']': cur += 1; _cur_lexeme = lex_close_square_brace; break; case ',': cur += 1; _cur_lexeme = lex_comma; break; case '/': if (*(cur+1) == '/') { cur += 2; _cur_lexeme = lex_double_slash; } else { cur += 1; _cur_lexeme = lex_slash; } break; case '.': if (*(cur+1) == '.') { cur += 2; _cur_lexeme = lex_double_dot; } else if (PUGI__IS_CHARTYPEX(*(cur+1), ctx_digit)) { _cur_lexeme_contents.begin = cur; // . ++cur; while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; _cur_lexeme_contents.end = cur; _cur_lexeme = lex_number; } else { cur += 1; _cur_lexeme = lex_dot; } break; case '@': cur += 1; _cur_lexeme = lex_axis_attribute; break; case '"': case '\'': { char_t terminator = *cur; ++cur; _cur_lexeme_contents.begin = cur; while (*cur && *cur != terminator) cur++; _cur_lexeme_contents.end = cur; if (!*cur) _cur_lexeme = lex_none; else { cur += 1; _cur_lexeme = lex_quoted_string; } break; } case ':': if (*(cur+1) == ':') { cur += 2; _cur_lexeme = lex_double_colon; } else { _cur_lexeme = lex_none; } break; default: if (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) { _cur_lexeme_contents.begin = cur; while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; if (*cur == '.') { cur++; while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; } _cur_lexeme_contents.end = cur; _cur_lexeme = lex_number; } else if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) { _cur_lexeme_contents.begin = cur; while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; if (cur[0] == ':') { if (cur[1] == '*') // namespace test ncname:* { cur += 2; // :* } else if (PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // namespace test qname { cur++; // : while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; } } _cur_lexeme_contents.end = cur; _cur_lexeme = lex_string; } else { _cur_lexeme = lex_none; } } _cur = cur; } lexeme_t current() const { return _cur_lexeme; } const char_t* current_pos() const { return _cur_lexeme_pos; } const xpath_lexer_string& contents() const { assert(_cur_lexeme == lex_var_ref || _cur_lexeme == lex_number || _cur_lexeme == lex_string || _cur_lexeme == lex_quoted_string); return _cur_lexeme_contents; } }; enum ast_type_t { ast_op_or, // left or right ast_op_and, // left and right ast_op_equal, // left = right ast_op_not_equal, // left != right ast_op_less, // left < right ast_op_greater, // left > right ast_op_less_or_equal, // left <= right ast_op_greater_or_equal, // left >= right ast_op_add, // left + right ast_op_subtract, // left - right ast_op_multiply, // left * right ast_op_divide, // left / right ast_op_mod, // left % right ast_op_negate, // left - right ast_op_union, // left | right ast_predicate, // apply predicate to set; next points to next predicate ast_filter, // select * from left where right ast_filter_posinv, // select * from left where right; proximity position invariant ast_string_constant, // string constant ast_number_constant, // number constant ast_variable, // variable ast_func_last, // last() ast_func_position, // position() ast_func_count, // count(left) ast_func_id, // id(left) ast_func_local_name_0, // local-name() ast_func_local_name_1, // local-name(left) ast_func_namespace_uri_0, // namespace-uri() ast_func_namespace_uri_1, // namespace-uri(left) ast_func_name_0, // name() ast_func_name_1, // name(left) ast_func_string_0, // string() ast_func_string_1, // string(left) ast_func_concat, // concat(left, right, siblings) ast_func_starts_with, // starts_with(left, right) ast_func_contains, // contains(left, right) ast_func_substring_before, // substring-before(left, right) ast_func_substring_after, // substring-after(left, right) ast_func_substring_2, // substring(left, right) ast_func_substring_3, // substring(left, right, third) ast_func_string_length_0, // string-length() ast_func_string_length_1, // string-length(left) ast_func_normalize_space_0, // normalize-space() ast_func_normalize_space_1, // normalize-space(left) ast_func_translate, // translate(left, right, third) ast_func_boolean, // boolean(left) ast_func_not, // not(left) ast_func_true, // true() ast_func_false, // false() ast_func_lang, // lang(left) ast_func_number_0, // number() ast_func_number_1, // number(left) ast_func_sum, // sum(left) ast_func_floor, // floor(left) ast_func_ceiling, // ceiling(left) ast_func_round, // round(left) ast_step, // process set left with step ast_step_root // select root node }; enum axis_t { axis_ancestor, axis_ancestor_or_self, axis_attribute, axis_child, axis_descendant, axis_descendant_or_self, axis_following, axis_following_sibling, axis_namespace, axis_parent, axis_preceding, axis_preceding_sibling, axis_self }; enum nodetest_t { nodetest_none, nodetest_name, nodetest_type_node, nodetest_type_comment, nodetest_type_pi, nodetest_type_text, nodetest_pi, nodetest_all, nodetest_all_in_namespace }; template struct axis_to_type { static const axis_t axis; }; template const axis_t axis_to_type::axis = N; class xpath_ast_node { private: // node type char _type; char _rettype; // for ast_step / ast_predicate char _axis; char _test; // tree node structure xpath_ast_node* _left; xpath_ast_node* _right; xpath_ast_node* _next; union { // value for ast_string_constant const char_t* string; // value for ast_number_constant double number; // variable for ast_variable xpath_variable* variable; // node test for ast_step (node name/namespace/node type/pi target) const char_t* nodetest; } _data; xpath_ast_node(const xpath_ast_node&); xpath_ast_node& operator=(const xpath_ast_node&); template static bool compare_eq(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp) { xpath_value_type lt = lhs->rettype(), rt = rhs->rettype(); if (lt != xpath_type_node_set && rt != xpath_type_node_set) { if (lt == xpath_type_boolean || rt == xpath_type_boolean) return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack)); else if (lt == xpath_type_number || rt == xpath_type_number) return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack)); else if (lt == xpath_type_string || rt == xpath_type_string) { xpath_allocator_capture cr(stack.result); xpath_string ls = lhs->eval_string(c, stack); xpath_string rs = rhs->eval_string(c, stack); return comp(ls, rs); } } else if (lt == xpath_type_node_set && rt == xpath_type_node_set) { xpath_allocator_capture cr(stack.result); xpath_node_set_raw ls = lhs->eval_node_set(c, stack); xpath_node_set_raw rs = rhs->eval_node_set(c, stack); for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) { xpath_allocator_capture cri(stack.result); if (comp(string_value(*li, stack.result), string_value(*ri, stack.result))) return true; } return false; } else { if (lt == xpath_type_node_set) { swap(lhs, rhs); swap(lt, rt); } if (lt == xpath_type_boolean) return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack)); else if (lt == xpath_type_number) { xpath_allocator_capture cr(stack.result); double l = lhs->eval_number(c, stack); xpath_node_set_raw rs = rhs->eval_node_set(c, stack); for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) { xpath_allocator_capture cri(stack.result); if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str()))) return true; } return false; } else if (lt == xpath_type_string) { xpath_allocator_capture cr(stack.result); xpath_string l = lhs->eval_string(c, stack); xpath_node_set_raw rs = rhs->eval_node_set(c, stack); for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) { xpath_allocator_capture cri(stack.result); if (comp(l, string_value(*ri, stack.result))) return true; } return false; } } assert(!"Wrong types"); return false; } template static bool compare_rel(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp) { xpath_value_type lt = lhs->rettype(), rt = rhs->rettype(); if (lt != xpath_type_node_set && rt != xpath_type_node_set) return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack)); else if (lt == xpath_type_node_set && rt == xpath_type_node_set) { xpath_allocator_capture cr(stack.result); xpath_node_set_raw ls = lhs->eval_node_set(c, stack); xpath_node_set_raw rs = rhs->eval_node_set(c, stack); for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) { xpath_allocator_capture cri(stack.result); double l = convert_string_to_number(string_value(*li, stack.result).c_str()); for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) { xpath_allocator_capture crii(stack.result); if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str()))) return true; } } return false; } else if (lt != xpath_type_node_set && rt == xpath_type_node_set) { xpath_allocator_capture cr(stack.result); double l = lhs->eval_number(c, stack); xpath_node_set_raw rs = rhs->eval_node_set(c, stack); for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) { xpath_allocator_capture cri(stack.result); if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str()))) return true; } return false; } else if (lt == xpath_type_node_set && rt != xpath_type_node_set) { xpath_allocator_capture cr(stack.result); xpath_node_set_raw ls = lhs->eval_node_set(c, stack); double r = rhs->eval_number(c, stack); for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) { xpath_allocator_capture cri(stack.result); if (comp(convert_string_to_number(string_value(*li, stack.result).c_str()), r)) return true; } return false; } else { assert(!"Wrong types"); return false; } } void apply_predicate(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack) { assert(ns.size() >= first); size_t i = 1; size_t size = ns.size() - first; xpath_node* last = ns.begin() + first; // remove_if... or well, sort of for (xpath_node* it = last; it != ns.end(); ++it, ++i) { xpath_context c(*it, i, size); if (expr->rettype() == xpath_type_number) { if (expr->eval_number(c, stack) == i) *last++ = *it; } else if (expr->eval_boolean(c, stack)) *last++ = *it; } ns.truncate(last); } void apply_predicates(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack) { if (ns.size() == first) return; for (xpath_ast_node* pred = _right; pred; pred = pred->_next) { apply_predicate(ns, first, pred->_left, stack); } } void step_push(xpath_node_set_raw& ns, const xml_attribute& a, const xml_node& parent, xpath_allocator* alloc) { if (!a) return; const char_t* name = a.name(); // There are no attribute nodes corresponding to attributes that declare namespaces // That is, "xmlns:..." or "xmlns" if (starts_with(name, PUGIXML_TEXT("xmlns")) && (name[5] == 0 || name[5] == ':')) return; switch (_test) { case nodetest_name: if (strequal(name, _data.nodetest)) ns.push_back(xpath_node(a, parent), alloc); break; case nodetest_type_node: case nodetest_all: ns.push_back(xpath_node(a, parent), alloc); break; case nodetest_all_in_namespace: if (starts_with(name, _data.nodetest)) ns.push_back(xpath_node(a, parent), alloc); break; default: ; } } void step_push(xpath_node_set_raw& ns, const xml_node& n, xpath_allocator* alloc) { if (!n) return; switch (_test) { case nodetest_name: if (n.type() == node_element && strequal(n.name(), _data.nodetest)) ns.push_back(n, alloc); break; case nodetest_type_node: ns.push_back(n, alloc); break; case nodetest_type_comment: if (n.type() == node_comment) ns.push_back(n, alloc); break; case nodetest_type_text: if (n.type() == node_pcdata || n.type() == node_cdata) ns.push_back(n, alloc); break; case nodetest_type_pi: if (n.type() == node_pi) ns.push_back(n, alloc); break; case nodetest_pi: if (n.type() == node_pi && strequal(n.name(), _data.nodetest)) ns.push_back(n, alloc); break; case nodetest_all: if (n.type() == node_element) ns.push_back(n, alloc); break; case nodetest_all_in_namespace: if (n.type() == node_element && starts_with(n.name(), _data.nodetest)) ns.push_back(n, alloc); break; default: assert(!"Unknown axis"); } } template void step_fill(xpath_node_set_raw& ns, const xml_node& n, xpath_allocator* alloc, T) { const axis_t axis = T::axis; switch (axis) { case axis_attribute: { for (xml_attribute a = n.first_attribute(); a; a = a.next_attribute()) step_push(ns, a, n, alloc); break; } case axis_child: { for (xml_node c = n.first_child(); c; c = c.next_sibling()) step_push(ns, c, alloc); break; } case axis_descendant: case axis_descendant_or_self: { if (axis == axis_descendant_or_self) step_push(ns, n, alloc); xml_node cur = n.first_child(); while (cur && cur != n) { step_push(ns, cur, alloc); if (cur.first_child()) cur = cur.first_child(); else if (cur.next_sibling()) cur = cur.next_sibling(); else { while (!cur.next_sibling() && cur != n) cur = cur.parent(); if (cur != n) cur = cur.next_sibling(); } } break; } case axis_following_sibling: { for (xml_node c = n.next_sibling(); c; c = c.next_sibling()) step_push(ns, c, alloc); break; } case axis_preceding_sibling: { for (xml_node c = n.previous_sibling(); c; c = c.previous_sibling()) step_push(ns, c, alloc); break; } case axis_following: { xml_node cur = n; // exit from this node so that we don't include descendants while (cur && !cur.next_sibling()) cur = cur.parent(); cur = cur.next_sibling(); for (;;) { step_push(ns, cur, alloc); if (cur.first_child()) cur = cur.first_child(); else if (cur.next_sibling()) cur = cur.next_sibling(); else { while (cur && !cur.next_sibling()) cur = cur.parent(); cur = cur.next_sibling(); if (!cur) break; } } break; } case axis_preceding: { xml_node cur = n; while (cur && !cur.previous_sibling()) cur = cur.parent(); cur = cur.previous_sibling(); for (;;) { if (cur.last_child()) cur = cur.last_child(); else { // leaf node, can't be ancestor step_push(ns, cur, alloc); if (cur.previous_sibling()) cur = cur.previous_sibling(); else { do { cur = cur.parent(); if (!cur) break; if (!node_is_ancestor(cur, n)) step_push(ns, cur, alloc); } while (!cur.previous_sibling()); cur = cur.previous_sibling(); if (!cur) break; } } } break; } case axis_ancestor: case axis_ancestor_or_self: { if (axis == axis_ancestor_or_self) step_push(ns, n, alloc); xml_node cur = n.parent(); while (cur) { step_push(ns, cur, alloc); cur = cur.parent(); } break; } case axis_self: { step_push(ns, n, alloc); break; } case axis_parent: { if (n.parent()) step_push(ns, n.parent(), alloc); break; } default: assert(!"Unimplemented axis"); } } template void step_fill(xpath_node_set_raw& ns, const xml_attribute& a, const xml_node& p, xpath_allocator* alloc, T v) { const axis_t axis = T::axis; switch (axis) { case axis_ancestor: case axis_ancestor_or_self: { if (axis == axis_ancestor_or_self && _test == nodetest_type_node) // reject attributes based on principal node type test step_push(ns, a, p, alloc); xml_node cur = p; while (cur) { step_push(ns, cur, alloc); cur = cur.parent(); } break; } case axis_descendant_or_self: case axis_self: { if (_test == nodetest_type_node) // reject attributes based on principal node type test step_push(ns, a, p, alloc); break; } case axis_following: { xml_node cur = p; for (;;) { if (cur.first_child()) cur = cur.first_child(); else if (cur.next_sibling()) cur = cur.next_sibling(); else { while (cur && !cur.next_sibling()) cur = cur.parent(); cur = cur.next_sibling(); if (!cur) break; } step_push(ns, cur, alloc); } break; } case axis_parent: { step_push(ns, p, alloc); break; } case axis_preceding: { // preceding:: axis does not include attribute nodes and attribute ancestors (they are the same as parent's ancestors), so we can reuse node preceding step_fill(ns, p, alloc, v); break; } default: assert(!"Unimplemented axis"); } } template xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, T v) { const axis_t axis = T::axis; bool attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); xpath_node_set_raw ns; ns.set_type((axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling) ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted); if (_left) { xpath_node_set_raw s = _left->eval_node_set(c, stack); // self axis preserves the original order if (axis == axis_self) ns.set_type(s.type()); for (const xpath_node* it = s.begin(); it != s.end(); ++it) { size_t size = ns.size(); // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); if (it->node()) step_fill(ns, it->node(), stack.result, v); else if (attributes) step_fill(ns, it->attribute(), it->parent(), stack.result, v); apply_predicates(ns, size, stack); } } else { if (c.n.node()) step_fill(ns, c.n.node(), stack.result, v); else if (attributes) step_fill(ns, c.n.attribute(), c.n.parent(), stack.result, v); apply_predicates(ns, 0, stack); } // child, attribute and self axes always generate unique set of nodes // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted) ns.remove_duplicates(); return ns; } public: xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t* value): _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) { assert(type == ast_string_constant); _data.string = value; } xpath_ast_node(ast_type_t type, xpath_value_type rettype_, double value): _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) { assert(type == ast_number_constant); _data.number = value; } xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_variable* value): _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) { assert(type == ast_variable); _data.variable = value; } xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_ast_node* left = 0, xpath_ast_node* right = 0): _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(left), _right(right), _next(0) { } xpath_ast_node(ast_type_t type, xpath_ast_node* left, axis_t axis, nodetest_t test, const char_t* contents): _type(static_cast(type)), _rettype(xpath_type_node_set), _axis(static_cast(axis)), _test(static_cast(test)), _left(left), _right(0), _next(0) { _data.nodetest = contents; } void set_next(xpath_ast_node* value) { _next = value; } void set_right(xpath_ast_node* value) { _right = value; } bool eval_boolean(const xpath_context& c, const xpath_stack& stack) { switch (_type) { case ast_op_or: return _left->eval_boolean(c, stack) || _right->eval_boolean(c, stack); case ast_op_and: return _left->eval_boolean(c, stack) && _right->eval_boolean(c, stack); case ast_op_equal: return compare_eq(_left, _right, c, stack, equal_to()); case ast_op_not_equal: return compare_eq(_left, _right, c, stack, not_equal_to()); case ast_op_less: return compare_rel(_left, _right, c, stack, less()); case ast_op_greater: return compare_rel(_right, _left, c, stack, less()); case ast_op_less_or_equal: return compare_rel(_left, _right, c, stack, less_equal()); case ast_op_greater_or_equal: return compare_rel(_right, _left, c, stack, less_equal()); case ast_func_starts_with: { xpath_allocator_capture cr(stack.result); xpath_string lr = _left->eval_string(c, stack); xpath_string rr = _right->eval_string(c, stack); return starts_with(lr.c_str(), rr.c_str()); } case ast_func_contains: { xpath_allocator_capture cr(stack.result); xpath_string lr = _left->eval_string(c, stack); xpath_string rr = _right->eval_string(c, stack); return find_substring(lr.c_str(), rr.c_str()) != 0; } case ast_func_boolean: return _left->eval_boolean(c, stack); case ast_func_not: return !_left->eval_boolean(c, stack); case ast_func_true: return true; case ast_func_false: return false; case ast_func_lang: { if (c.n.attribute()) return false; xpath_allocator_capture cr(stack.result); xpath_string lang = _left->eval_string(c, stack); for (xml_node n = c.n.node(); n; n = n.parent()) { xml_attribute a = n.attribute(PUGIXML_TEXT("xml:lang")); if (a) { const char_t* value = a.value(); // strnicmp / strncasecmp is not portable for (const char_t* lit = lang.c_str(); *lit; ++lit) { if (tolower_ascii(*lit) != tolower_ascii(*value)) return false; ++value; } return *value == 0 || *value == '-'; } } return false; } case ast_variable: { assert(_rettype == _data.variable->type()); if (_rettype == xpath_type_boolean) return _data.variable->get_boolean(); // fallthrough to type conversion } default: { switch (_rettype) { case xpath_type_number: return convert_number_to_boolean(eval_number(c, stack)); case xpath_type_string: { xpath_allocator_capture cr(stack.result); return !eval_string(c, stack).empty(); } case xpath_type_node_set: { xpath_allocator_capture cr(stack.result); return !eval_node_set(c, stack).empty(); } default: assert(!"Wrong expression for return type boolean"); return false; } } } } double eval_number(const xpath_context& c, const xpath_stack& stack) { switch (_type) { case ast_op_add: return _left->eval_number(c, stack) + _right->eval_number(c, stack); case ast_op_subtract: return _left->eval_number(c, stack) - _right->eval_number(c, stack); case ast_op_multiply: return _left->eval_number(c, stack) * _right->eval_number(c, stack); case ast_op_divide: return _left->eval_number(c, stack) / _right->eval_number(c, stack); case ast_op_mod: return fmod(_left->eval_number(c, stack), _right->eval_number(c, stack)); case ast_op_negate: return -_left->eval_number(c, stack); case ast_number_constant: return _data.number; case ast_func_last: return static_cast(c.size); case ast_func_position: return static_cast(c.position); case ast_func_count: { xpath_allocator_capture cr(stack.result); return static_cast(_left->eval_node_set(c, stack).size()); } case ast_func_string_length_0: { xpath_allocator_capture cr(stack.result); return static_cast(string_value(c.n, stack.result).length()); } case ast_func_string_length_1: { xpath_allocator_capture cr(stack.result); return static_cast(_left->eval_string(c, stack).length()); } case ast_func_number_0: { xpath_allocator_capture cr(stack.result); return convert_string_to_number(string_value(c.n, stack.result).c_str()); } case ast_func_number_1: return _left->eval_number(c, stack); case ast_func_sum: { xpath_allocator_capture cr(stack.result); double r = 0; xpath_node_set_raw ns = _left->eval_node_set(c, stack); for (const xpath_node* it = ns.begin(); it != ns.end(); ++it) { xpath_allocator_capture cri(stack.result); r += convert_string_to_number(string_value(*it, stack.result).c_str()); } return r; } case ast_func_floor: { double r = _left->eval_number(c, stack); return r == r ? floor(r) : r; } case ast_func_ceiling: { double r = _left->eval_number(c, stack); return r == r ? ceil(r) : r; } case ast_func_round: return round_nearest_nzero(_left->eval_number(c, stack)); case ast_variable: { assert(_rettype == _data.variable->type()); if (_rettype == xpath_type_number) return _data.variable->get_number(); // fallthrough to type conversion } default: { switch (_rettype) { case xpath_type_boolean: return eval_boolean(c, stack) ? 1 : 0; case xpath_type_string: { xpath_allocator_capture cr(stack.result); return convert_string_to_number(eval_string(c, stack).c_str()); } case xpath_type_node_set: { xpath_allocator_capture cr(stack.result); return convert_string_to_number(eval_string(c, stack).c_str()); } default: assert(!"Wrong expression for return type number"); return 0; } } } } xpath_string eval_string_concat(const xpath_context& c, const xpath_stack& stack) { assert(_type == ast_func_concat); xpath_allocator_capture ct(stack.temp); // count the string number size_t count = 1; for (xpath_ast_node* nc = _right; nc; nc = nc->_next) count++; // gather all strings xpath_string static_buffer[4]; xpath_string* buffer = static_buffer; // allocate on-heap for large concats if (count > sizeof(static_buffer) / sizeof(static_buffer[0])) { buffer = static_cast(stack.temp->allocate(count * sizeof(xpath_string))); assert(buffer); } // evaluate all strings to temporary stack xpath_stack swapped_stack = {stack.temp, stack.result}; buffer[0] = _left->eval_string(c, swapped_stack); size_t pos = 1; for (xpath_ast_node* n = _right; n; n = n->_next, ++pos) buffer[pos] = n->eval_string(c, swapped_stack); assert(pos == count); // get total length size_t length = 0; for (size_t i = 0; i < count; ++i) length += buffer[i].length(); // create final string char_t* result = static_cast(stack.result->allocate((length + 1) * sizeof(char_t))); assert(result); char_t* ri = result; for (size_t j = 0; j < count; ++j) for (const char_t* bi = buffer[j].c_str(); *bi; ++bi) *ri++ = *bi; *ri = 0; return xpath_string(result, true); } xpath_string eval_string(const xpath_context& c, const xpath_stack& stack) { switch (_type) { case ast_string_constant: return xpath_string_const(_data.string); case ast_func_local_name_0: { xpath_node na = c.n; return xpath_string_const(local_name(na)); } case ast_func_local_name_1: { xpath_allocator_capture cr(stack.result); xpath_node_set_raw ns = _left->eval_node_set(c, stack); xpath_node na = ns.first(); return xpath_string_const(local_name(na)); } case ast_func_name_0: { xpath_node na = c.n; return xpath_string_const(qualified_name(na)); } case ast_func_name_1: { xpath_allocator_capture cr(stack.result); xpath_node_set_raw ns = _left->eval_node_set(c, stack); xpath_node na = ns.first(); return xpath_string_const(qualified_name(na)); } case ast_func_namespace_uri_0: { xpath_node na = c.n; return xpath_string_const(namespace_uri(na)); } case ast_func_namespace_uri_1: { xpath_allocator_capture cr(stack.result); xpath_node_set_raw ns = _left->eval_node_set(c, stack); xpath_node na = ns.first(); return xpath_string_const(namespace_uri(na)); } case ast_func_string_0: return string_value(c.n, stack.result); case ast_func_string_1: return _left->eval_string(c, stack); case ast_func_concat: return eval_string_concat(c, stack); case ast_func_substring_before: { xpath_allocator_capture cr(stack.temp); xpath_stack swapped_stack = {stack.temp, stack.result}; xpath_string s = _left->eval_string(c, swapped_stack); xpath_string p = _right->eval_string(c, swapped_stack); const char_t* pos = find_substring(s.c_str(), p.c_str()); return pos ? xpath_string(s.c_str(), pos, stack.result) : xpath_string(); } case ast_func_substring_after: { xpath_allocator_capture cr(stack.temp); xpath_stack swapped_stack = {stack.temp, stack.result}; xpath_string s = _left->eval_string(c, swapped_stack); xpath_string p = _right->eval_string(c, swapped_stack); const char_t* pos = find_substring(s.c_str(), p.c_str()); if (!pos) return xpath_string(); const char_t* result = pos + p.length(); return s.uses_heap() ? xpath_string(result, stack.result) : xpath_string_const(result); } case ast_func_substring_2: { xpath_allocator_capture cr(stack.temp); xpath_stack swapped_stack = {stack.temp, stack.result}; xpath_string s = _left->eval_string(c, swapped_stack); size_t s_length = s.length(); double first = round_nearest(_right->eval_number(c, stack)); if (is_nan(first)) return xpath_string(); // NaN else if (first >= s_length + 1) return xpath_string(); size_t pos = first < 1 ? 1 : static_cast(first); assert(1 <= pos && pos <= s_length + 1); const char_t* rbegin = s.c_str() + (pos - 1); return s.uses_heap() ? xpath_string(rbegin, stack.result) : xpath_string_const(rbegin); } case ast_func_substring_3: { xpath_allocator_capture cr(stack.temp); xpath_stack swapped_stack = {stack.temp, stack.result}; xpath_string s = _left->eval_string(c, swapped_stack); size_t s_length = s.length(); double first = round_nearest(_right->eval_number(c, stack)); double last = first + round_nearest(_right->_next->eval_number(c, stack)); if (is_nan(first) || is_nan(last)) return xpath_string(); else if (first >= s_length + 1) return xpath_string(); else if (first >= last) return xpath_string(); else if (last < 1) return xpath_string(); size_t pos = first < 1 ? 1 : static_cast(first); size_t end = last >= s_length + 1 ? s_length + 1 : static_cast(last); assert(1 <= pos && pos <= end && end <= s_length + 1); const char_t* rbegin = s.c_str() + (pos - 1); const char_t* rend = s.c_str() + (end - 1); return (end == s_length + 1 && !s.uses_heap()) ? xpath_string_const(rbegin) : xpath_string(rbegin, rend, stack.result); } case ast_func_normalize_space_0: { xpath_string s = string_value(c.n, stack.result); normalize_space(s.data(stack.result)); return s; } case ast_func_normalize_space_1: { xpath_string s = _left->eval_string(c, stack); normalize_space(s.data(stack.result)); return s; } case ast_func_translate: { xpath_allocator_capture cr(stack.temp); xpath_stack swapped_stack = {stack.temp, stack.result}; xpath_string s = _left->eval_string(c, stack); xpath_string from = _right->eval_string(c, swapped_stack); xpath_string to = _right->_next->eval_string(c, swapped_stack); translate(s.data(stack.result), from.c_str(), to.c_str()); return s; } case ast_variable: { assert(_rettype == _data.variable->type()); if (_rettype == xpath_type_string) return xpath_string_const(_data.variable->get_string()); // fallthrough to type conversion } default: { switch (_rettype) { case xpath_type_boolean: return xpath_string_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); case xpath_type_number: return convert_number_to_string(eval_number(c, stack), stack.result); case xpath_type_node_set: { xpath_allocator_capture cr(stack.temp); xpath_stack swapped_stack = {stack.temp, stack.result}; xpath_node_set_raw ns = eval_node_set(c, swapped_stack); return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result); } default: assert(!"Wrong expression for return type string"); return xpath_string(); } } } } xpath_node_set_raw eval_node_set(const xpath_context& c, const xpath_stack& stack) { switch (_type) { case ast_op_union: { xpath_allocator_capture cr(stack.temp); xpath_stack swapped_stack = {stack.temp, stack.result}; xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack); xpath_node_set_raw rs = _right->eval_node_set(c, stack); // we can optimize merging two sorted sets, but this is a very rare operation, so don't bother rs.set_type(xpath_node_set::type_unsorted); rs.append(ls.begin(), ls.end(), stack.result); rs.remove_duplicates(); return rs; } case ast_filter: case ast_filter_posinv: { xpath_node_set_raw set = _left->eval_node_set(c, stack); // either expression is a number or it contains position() call; sort by document order if (_type == ast_filter) set.sort_do(); apply_predicate(set, 0, _right, stack); return set; } case ast_func_id: return xpath_node_set_raw(); case ast_step: { switch (_axis) { case axis_ancestor: return step_do(c, stack, axis_to_type()); case axis_ancestor_or_self: return step_do(c, stack, axis_to_type()); case axis_attribute: return step_do(c, stack, axis_to_type()); case axis_child: return step_do(c, stack, axis_to_type()); case axis_descendant: return step_do(c, stack, axis_to_type()); case axis_descendant_or_self: return step_do(c, stack, axis_to_type()); case axis_following: return step_do(c, stack, axis_to_type()); case axis_following_sibling: return step_do(c, stack, axis_to_type()); case axis_namespace: // namespaced axis is not supported return xpath_node_set_raw(); case axis_parent: return step_do(c, stack, axis_to_type()); case axis_preceding: return step_do(c, stack, axis_to_type()); case axis_preceding_sibling: return step_do(c, stack, axis_to_type()); case axis_self: return step_do(c, stack, axis_to_type()); default: assert(!"Unknown axis"); return xpath_node_set_raw(); } } case ast_step_root: { assert(!_right); // root step can't have any predicates xpath_node_set_raw ns; ns.set_type(xpath_node_set::type_sorted); if (c.n.node()) ns.push_back(c.n.node().root(), stack.result); else if (c.n.attribute()) ns.push_back(c.n.parent().root(), stack.result); return ns; } case ast_variable: { assert(_rettype == _data.variable->type()); if (_rettype == xpath_type_node_set) { const xpath_node_set& s = _data.variable->get_node_set(); xpath_node_set_raw ns; ns.set_type(s.type()); ns.append(s.begin(), s.end(), stack.result); return ns; } // fallthrough to type conversion } default: assert(!"Wrong expression for return type node set"); return xpath_node_set_raw(); } } bool is_posinv() { switch (_type) { case ast_func_position: return false; case ast_string_constant: case ast_number_constant: case ast_variable: return true; case ast_step: case ast_step_root: return true; case ast_predicate: case ast_filter: case ast_filter_posinv: return true; default: if (_left && !_left->is_posinv()) return false; for (xpath_ast_node* n = _right; n; n = n->_next) if (!n->is_posinv()) return false; return true; } } xpath_value_type rettype() const { return static_cast(_rettype); } }; struct xpath_parser { xpath_allocator* _alloc; xpath_lexer _lexer; const char_t* _query; xpath_variable_set* _variables; xpath_parse_result* _result; #ifdef PUGIXML_NO_EXCEPTIONS jmp_buf _error_handler; #endif void throw_error(const char* message) { _result->error = message; _result->offset = _lexer.current_pos() - _query; #ifdef PUGIXML_NO_EXCEPTIONS longjmp(_error_handler, 1); #else throw xpath_exception(*_result); #endif } void throw_error_oom() { #ifdef PUGIXML_NO_EXCEPTIONS throw_error("Out of memory"); #else throw std::bad_alloc(); #endif } void* alloc_node() { void* result = _alloc->allocate_nothrow(sizeof(xpath_ast_node)); if (!result) throw_error_oom(); return result; } const char_t* alloc_string(const xpath_lexer_string& value) { if (value.begin) { size_t length = static_cast(value.end - value.begin); char_t* c = static_cast(_alloc->allocate_nothrow((length + 1) * sizeof(char_t))); if (!c) throw_error_oom(); memcpy(c, value.begin, length * sizeof(char_t)); c[length] = 0; return c; } else return 0; } xpath_ast_node* parse_function_helper(ast_type_t type0, ast_type_t type1, size_t argc, xpath_ast_node* args[2]) { assert(argc <= 1); if (argc == 1 && args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); return new (alloc_node()) xpath_ast_node(argc == 0 ? type0 : type1, xpath_type_string, args[0]); } xpath_ast_node* parse_function(const xpath_lexer_string& name, size_t argc, xpath_ast_node* args[2]) { switch (name.begin[0]) { case 'b': if (name == PUGIXML_TEXT("boolean") && argc == 1) return new (alloc_node()) xpath_ast_node(ast_func_boolean, xpath_type_boolean, args[0]); break; case 'c': if (name == PUGIXML_TEXT("count") && argc == 1) { if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); return new (alloc_node()) xpath_ast_node(ast_func_count, xpath_type_number, args[0]); } else if (name == PUGIXML_TEXT("contains") && argc == 2) return new (alloc_node()) xpath_ast_node(ast_func_contains, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("concat") && argc >= 2) return new (alloc_node()) xpath_ast_node(ast_func_concat, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("ceiling") && argc == 1) return new (alloc_node()) xpath_ast_node(ast_func_ceiling, xpath_type_number, args[0]); break; case 'f': if (name == PUGIXML_TEXT("false") && argc == 0) return new (alloc_node()) xpath_ast_node(ast_func_false, xpath_type_boolean); else if (name == PUGIXML_TEXT("floor") && argc == 1) return new (alloc_node()) xpath_ast_node(ast_func_floor, xpath_type_number, args[0]); break; case 'i': if (name == PUGIXML_TEXT("id") && argc == 1) return new (alloc_node()) xpath_ast_node(ast_func_id, xpath_type_node_set, args[0]); break; case 'l': if (name == PUGIXML_TEXT("last") && argc == 0) return new (alloc_node()) xpath_ast_node(ast_func_last, xpath_type_number); else if (name == PUGIXML_TEXT("lang") && argc == 1) return new (alloc_node()) xpath_ast_node(ast_func_lang, xpath_type_boolean, args[0]); else if (name == PUGIXML_TEXT("local-name") && argc <= 1) return parse_function_helper(ast_func_local_name_0, ast_func_local_name_1, argc, args); break; case 'n': if (name == PUGIXML_TEXT("name") && argc <= 1) return parse_function_helper(ast_func_name_0, ast_func_name_1, argc, args); else if (name == PUGIXML_TEXT("namespace-uri") && argc <= 1) return parse_function_helper(ast_func_namespace_uri_0, ast_func_namespace_uri_1, argc, args); else if (name == PUGIXML_TEXT("normalize-space") && argc <= 1) return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_normalize_space_0 : ast_func_normalize_space_1, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("not") && argc == 1) return new (alloc_node()) xpath_ast_node(ast_func_not, xpath_type_boolean, args[0]); else if (name == PUGIXML_TEXT("number") && argc <= 1) return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_number_0 : ast_func_number_1, xpath_type_number, args[0]); break; case 'p': if (name == PUGIXML_TEXT("position") && argc == 0) return new (alloc_node()) xpath_ast_node(ast_func_position, xpath_type_number); break; case 'r': if (name == PUGIXML_TEXT("round") && argc == 1) return new (alloc_node()) xpath_ast_node(ast_func_round, xpath_type_number, args[0]); break; case 's': if (name == PUGIXML_TEXT("string") && argc <= 1) return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_0 : ast_func_string_1, xpath_type_string, args[0]); else if (name == PUGIXML_TEXT("string-length") && argc <= 1) return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_length_0 : ast_func_string_length_1, xpath_type_string, args[0]); else if (name == PUGIXML_TEXT("starts-with") && argc == 2) return new (alloc_node()) xpath_ast_node(ast_func_starts_with, xpath_type_boolean, args[0], args[1]); else if (name == PUGIXML_TEXT("substring-before") && argc == 2) return new (alloc_node()) xpath_ast_node(ast_func_substring_before, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("substring-after") && argc == 2) return new (alloc_node()) xpath_ast_node(ast_func_substring_after, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("substring") && (argc == 2 || argc == 3)) return new (alloc_node()) xpath_ast_node(argc == 2 ? ast_func_substring_2 : ast_func_substring_3, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("sum") && argc == 1) { if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); return new (alloc_node()) xpath_ast_node(ast_func_sum, xpath_type_number, args[0]); } break; case 't': if (name == PUGIXML_TEXT("translate") && argc == 3) return new (alloc_node()) xpath_ast_node(ast_func_translate, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("true") && argc == 0) return new (alloc_node()) xpath_ast_node(ast_func_true, xpath_type_boolean); break; default: break; } throw_error("Unrecognized function or wrong parameter count"); return 0; } axis_t parse_axis_name(const xpath_lexer_string& name, bool& specified) { specified = true; switch (name.begin[0]) { case 'a': if (name == PUGIXML_TEXT("ancestor")) return axis_ancestor; else if (name == PUGIXML_TEXT("ancestor-or-self")) return axis_ancestor_or_self; else if (name == PUGIXML_TEXT("attribute")) return axis_attribute; break; case 'c': if (name == PUGIXML_TEXT("child")) return axis_child; break; case 'd': if (name == PUGIXML_TEXT("descendant")) return axis_descendant; else if (name == PUGIXML_TEXT("descendant-or-self")) return axis_descendant_or_self; break; case 'f': if (name == PUGIXML_TEXT("following")) return axis_following; else if (name == PUGIXML_TEXT("following-sibling")) return axis_following_sibling; break; case 'n': if (name == PUGIXML_TEXT("namespace")) return axis_namespace; break; case 'p': if (name == PUGIXML_TEXT("parent")) return axis_parent; else if (name == PUGIXML_TEXT("preceding")) return axis_preceding; else if (name == PUGIXML_TEXT("preceding-sibling")) return axis_preceding_sibling; break; case 's': if (name == PUGIXML_TEXT("self")) return axis_self; break; default: break; } specified = false; return axis_child; } nodetest_t parse_node_test_type(const xpath_lexer_string& name) { switch (name.begin[0]) { case 'c': if (name == PUGIXML_TEXT("comment")) return nodetest_type_comment; break; case 'n': if (name == PUGIXML_TEXT("node")) return nodetest_type_node; break; case 'p': if (name == PUGIXML_TEXT("processing-instruction")) return nodetest_type_pi; break; case 't': if (name == PUGIXML_TEXT("text")) return nodetest_type_text; break; default: break; } return nodetest_none; } // PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall xpath_ast_node* parse_primary_expression() { switch (_lexer.current()) { case lex_var_ref: { xpath_lexer_string name = _lexer.contents(); if (!_variables) throw_error("Unknown variable: variable set is not provided"); xpath_variable* var = get_variable(_variables, name.begin, name.end); if (!var) throw_error("Unknown variable: variable set does not contain the given name"); _lexer.next(); return new (alloc_node()) xpath_ast_node(ast_variable, var->type(), var); } case lex_open_brace: { _lexer.next(); xpath_ast_node* n = parse_expression(); if (_lexer.current() != lex_close_brace) throw_error("Unmatched braces"); _lexer.next(); return n; } case lex_quoted_string: { const char_t* value = alloc_string(_lexer.contents()); xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_string_constant, xpath_type_string, value); _lexer.next(); return n; } case lex_number: { double value = 0; if (!convert_string_to_number(_lexer.contents().begin, _lexer.contents().end, &value)) throw_error_oom(); xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_number_constant, xpath_type_number, value); _lexer.next(); return n; } case lex_string: { xpath_ast_node* args[2] = {0}; size_t argc = 0; xpath_lexer_string function = _lexer.contents(); _lexer.next(); xpath_ast_node* last_arg = 0; if (_lexer.current() != lex_open_brace) throw_error("Unrecognized function call"); _lexer.next(); if (_lexer.current() != lex_close_brace) args[argc++] = parse_expression(); while (_lexer.current() != lex_close_brace) { if (_lexer.current() != lex_comma) throw_error("No comma between function arguments"); _lexer.next(); xpath_ast_node* n = parse_expression(); if (argc < 2) args[argc] = n; else last_arg->set_next(n); argc++; last_arg = n; } _lexer.next(); return parse_function(function, argc, args); } default: throw_error("Unrecognizable primary expression"); return 0; } } // FilterExpr ::= PrimaryExpr | FilterExpr Predicate // Predicate ::= '[' PredicateExpr ']' // PredicateExpr ::= Expr xpath_ast_node* parse_filter_expression() { xpath_ast_node* n = parse_primary_expression(); while (_lexer.current() == lex_open_square_brace) { _lexer.next(); xpath_ast_node* expr = parse_expression(); if (n->rettype() != xpath_type_node_set) throw_error("Predicate has to be applied to node set"); bool posinv = expr->rettype() != xpath_type_number && expr->is_posinv(); n = new (alloc_node()) xpath_ast_node(posinv ? ast_filter_posinv : ast_filter, xpath_type_node_set, n, expr); if (_lexer.current() != lex_close_square_brace) throw_error("Unmatched square brace"); _lexer.next(); } return n; } // Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep // AxisSpecifier ::= AxisName '::' | '@'? // NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' // NameTest ::= '*' | NCName ':' '*' | QName // AbbreviatedStep ::= '.' | '..' xpath_ast_node* parse_step(xpath_ast_node* set) { if (set && set->rettype() != xpath_type_node_set) throw_error("Step has to be applied to node set"); bool axis_specified = false; axis_t axis = axis_child; // implied child axis if (_lexer.current() == lex_axis_attribute) { axis = axis_attribute; axis_specified = true; _lexer.next(); } else if (_lexer.current() == lex_dot) { _lexer.next(); return new (alloc_node()) xpath_ast_node(ast_step, set, axis_self, nodetest_type_node, 0); } else if (_lexer.current() == lex_double_dot) { _lexer.next(); return new (alloc_node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0); } nodetest_t nt_type = nodetest_none; xpath_lexer_string nt_name; if (_lexer.current() == lex_string) { // node name test nt_name = _lexer.contents(); _lexer.next(); // was it an axis name? if (_lexer.current() == lex_double_colon) { // parse axis name if (axis_specified) throw_error("Two axis specifiers in one step"); axis = parse_axis_name(nt_name, axis_specified); if (!axis_specified) throw_error("Unknown axis"); // read actual node test _lexer.next(); if (_lexer.current() == lex_multiply) { nt_type = nodetest_all; nt_name = xpath_lexer_string(); _lexer.next(); } else if (_lexer.current() == lex_string) { nt_name = _lexer.contents(); _lexer.next(); } else throw_error("Unrecognized node test"); } if (nt_type == nodetest_none) { // node type test or processing-instruction if (_lexer.current() == lex_open_brace) { _lexer.next(); if (_lexer.current() == lex_close_brace) { _lexer.next(); nt_type = parse_node_test_type(nt_name); if (nt_type == nodetest_none) throw_error("Unrecognized node type"); nt_name = xpath_lexer_string(); } else if (nt_name == PUGIXML_TEXT("processing-instruction")) { if (_lexer.current() != lex_quoted_string) throw_error("Only literals are allowed as arguments to processing-instruction()"); nt_type = nodetest_pi; nt_name = _lexer.contents(); _lexer.next(); if (_lexer.current() != lex_close_brace) throw_error("Unmatched brace near processing-instruction()"); _lexer.next(); } else throw_error("Unmatched brace near node type test"); } // QName or NCName:* else { if (nt_name.end - nt_name.begin > 2 && nt_name.end[-2] == ':' && nt_name.end[-1] == '*') // NCName:* { nt_name.end--; // erase * nt_type = nodetest_all_in_namespace; } else nt_type = nodetest_name; } } } else if (_lexer.current() == lex_multiply) { nt_type = nodetest_all; _lexer.next(); } else throw_error("Unrecognized node test"); xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step, set, axis, nt_type, alloc_string(nt_name)); xpath_ast_node* last = 0; while (_lexer.current() == lex_open_square_brace) { _lexer.next(); xpath_ast_node* expr = parse_expression(); xpath_ast_node* pred = new (alloc_node()) xpath_ast_node(ast_predicate, xpath_type_node_set, expr); if (_lexer.current() != lex_close_square_brace) throw_error("Unmatched square brace"); _lexer.next(); if (last) last->set_next(pred); else n->set_right(pred); last = pred; } return n; } // RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step xpath_ast_node* parse_relative_location_path(xpath_ast_node* set) { xpath_ast_node* n = parse_step(set); while (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) { lexeme_t l = _lexer.current(); _lexer.next(); if (l == lex_double_slash) n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); n = parse_step(n); } return n; } // LocationPath ::= RelativeLocationPath | AbsoluteLocationPath // AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath xpath_ast_node* parse_location_path() { if (_lexer.current() == lex_slash) { _lexer.next(); xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set); // relative location path can start from axis_attribute, dot, double_dot, multiply and string lexemes; any other lexeme means standalone root path lexeme_t l = _lexer.current(); if (l == lex_string || l == lex_axis_attribute || l == lex_dot || l == lex_double_dot || l == lex_multiply) return parse_relative_location_path(n); else return n; } else if (_lexer.current() == lex_double_slash) { _lexer.next(); xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set); n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); return parse_relative_location_path(n); } // else clause moved outside of if because of bogus warning 'control may reach end of non-void function being inlined' in gcc 4.0.1 return parse_relative_location_path(0); } // PathExpr ::= LocationPath // | FilterExpr // | FilterExpr '/' RelativeLocationPath // | FilterExpr '//' RelativeLocationPath xpath_ast_node* parse_path_expression() { // Clarification. // PathExpr begins with either LocationPath or FilterExpr. // FilterExpr begins with PrimaryExpr // PrimaryExpr begins with '$' in case of it being a variable reference, // '(' in case of it being an expression, string literal, number constant or // function call. if (_lexer.current() == lex_var_ref || _lexer.current() == lex_open_brace || _lexer.current() == lex_quoted_string || _lexer.current() == lex_number || _lexer.current() == lex_string) { if (_lexer.current() == lex_string) { // This is either a function call, or not - if not, we shall proceed with location path const char_t* state = _lexer.state(); while (PUGI__IS_CHARTYPE(*state, ct_space)) ++state; if (*state != '(') return parse_location_path(); // This looks like a function call; however this still can be a node-test. Check it. if (parse_node_test_type(_lexer.contents()) != nodetest_none) return parse_location_path(); } xpath_ast_node* n = parse_filter_expression(); if (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) { lexeme_t l = _lexer.current(); _lexer.next(); if (l == lex_double_slash) { if (n->rettype() != xpath_type_node_set) throw_error("Step has to be applied to node set"); n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); } // select from location path return parse_relative_location_path(n); } return n; } else return parse_location_path(); } // UnionExpr ::= PathExpr | UnionExpr '|' PathExpr xpath_ast_node* parse_union_expression() { xpath_ast_node* n = parse_path_expression(); while (_lexer.current() == lex_union) { _lexer.next(); xpath_ast_node* expr = parse_union_expression(); if (n->rettype() != xpath_type_node_set || expr->rettype() != xpath_type_node_set) throw_error("Union operator has to be applied to node sets"); n = new (alloc_node()) xpath_ast_node(ast_op_union, xpath_type_node_set, n, expr); } return n; } // UnaryExpr ::= UnionExpr | '-' UnaryExpr xpath_ast_node* parse_unary_expression() { if (_lexer.current() == lex_minus) { _lexer.next(); xpath_ast_node* expr = parse_unary_expression(); return new (alloc_node()) xpath_ast_node(ast_op_negate, xpath_type_number, expr); } else return parse_union_expression(); } // MultiplicativeExpr ::= UnaryExpr // | MultiplicativeExpr '*' UnaryExpr // | MultiplicativeExpr 'div' UnaryExpr // | MultiplicativeExpr 'mod' UnaryExpr xpath_ast_node* parse_multiplicative_expression() { xpath_ast_node* n = parse_unary_expression(); while (_lexer.current() == lex_multiply || (_lexer.current() == lex_string && (_lexer.contents() == PUGIXML_TEXT("mod") || _lexer.contents() == PUGIXML_TEXT("div")))) { ast_type_t op = _lexer.current() == lex_multiply ? ast_op_multiply : _lexer.contents().begin[0] == 'd' ? ast_op_divide : ast_op_mod; _lexer.next(); xpath_ast_node* expr = parse_unary_expression(); n = new (alloc_node()) xpath_ast_node(op, xpath_type_number, n, expr); } return n; } // AdditiveExpr ::= MultiplicativeExpr // | AdditiveExpr '+' MultiplicativeExpr // | AdditiveExpr '-' MultiplicativeExpr xpath_ast_node* parse_additive_expression() { xpath_ast_node* n = parse_multiplicative_expression(); while (_lexer.current() == lex_plus || _lexer.current() == lex_minus) { lexeme_t l = _lexer.current(); _lexer.next(); xpath_ast_node* expr = parse_multiplicative_expression(); n = new (alloc_node()) xpath_ast_node(l == lex_plus ? ast_op_add : ast_op_subtract, xpath_type_number, n, expr); } return n; } // RelationalExpr ::= AdditiveExpr // | RelationalExpr '<' AdditiveExpr // | RelationalExpr '>' AdditiveExpr // | RelationalExpr '<=' AdditiveExpr // | RelationalExpr '>=' AdditiveExpr xpath_ast_node* parse_relational_expression() { xpath_ast_node* n = parse_additive_expression(); while (_lexer.current() == lex_less || _lexer.current() == lex_less_or_equal || _lexer.current() == lex_greater || _lexer.current() == lex_greater_or_equal) { lexeme_t l = _lexer.current(); _lexer.next(); xpath_ast_node* expr = parse_additive_expression(); n = new (alloc_node()) xpath_ast_node(l == lex_less ? ast_op_less : l == lex_greater ? ast_op_greater : l == lex_less_or_equal ? ast_op_less_or_equal : ast_op_greater_or_equal, xpath_type_boolean, n, expr); } return n; } // EqualityExpr ::= RelationalExpr // | EqualityExpr '=' RelationalExpr // | EqualityExpr '!=' RelationalExpr xpath_ast_node* parse_equality_expression() { xpath_ast_node* n = parse_relational_expression(); while (_lexer.current() == lex_equal || _lexer.current() == lex_not_equal) { lexeme_t l = _lexer.current(); _lexer.next(); xpath_ast_node* expr = parse_relational_expression(); n = new (alloc_node()) xpath_ast_node(l == lex_equal ? ast_op_equal : ast_op_not_equal, xpath_type_boolean, n, expr); } return n; } // AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr xpath_ast_node* parse_and_expression() { xpath_ast_node* n = parse_equality_expression(); while (_lexer.current() == lex_string && _lexer.contents() == PUGIXML_TEXT("and")) { _lexer.next(); xpath_ast_node* expr = parse_equality_expression(); n = new (alloc_node()) xpath_ast_node(ast_op_and, xpath_type_boolean, n, expr); } return n; } // OrExpr ::= AndExpr | OrExpr 'or' AndExpr xpath_ast_node* parse_or_expression() { xpath_ast_node* n = parse_and_expression(); while (_lexer.current() == lex_string && _lexer.contents() == PUGIXML_TEXT("or")) { _lexer.next(); xpath_ast_node* expr = parse_and_expression(); n = new (alloc_node()) xpath_ast_node(ast_op_or, xpath_type_boolean, n, expr); } return n; } // Expr ::= OrExpr xpath_ast_node* parse_expression() { return parse_or_expression(); } xpath_parser(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result): _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result) { } xpath_ast_node* parse() { xpath_ast_node* result = parse_expression(); if (_lexer.current() != lex_eof) { // there are still unparsed tokens left, error throw_error("Incorrect query"); } return result; } static xpath_ast_node* parse(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result) { xpath_parser parser(query, variables, alloc, result); #ifdef PUGIXML_NO_EXCEPTIONS int error = setjmp(parser._error_handler); return (error == 0) ? parser.parse() : 0; #else return parser.parse(); #endif } }; struct xpath_query_impl { static xpath_query_impl* create() { void* memory = xml_memory::allocate(sizeof(xpath_query_impl)); return new (memory) xpath_query_impl(); } static void destroy(void* ptr) { if (!ptr) return; // free all allocated pages static_cast(ptr)->alloc.release(); // free allocator memory (with the first page) xml_memory::deallocate(ptr); } xpath_query_impl(): root(0), alloc(&block) { block.next = 0; } xpath_ast_node* root; xpath_allocator alloc; xpath_memory_block block; }; PUGI__FN xpath_string evaluate_string_impl(xpath_query_impl* impl, const xpath_node& n, xpath_stack_data& sd) { if (!impl) return xpath_string(); #ifdef PUGIXML_NO_EXCEPTIONS if (setjmp(sd.error_handler)) return xpath_string(); #endif xpath_context c(n, 1, 1); return impl->root->eval_string(c, sd.stack); } PUGI__NS_END OIIO_NAMESPACE_ENTER { namespace pugi { #ifndef PUGIXML_NO_EXCEPTIONS PUGI__FN xpath_exception::xpath_exception(const xpath_parse_result& result_): _result(result_) { assert(_result.error); } PUGI__FN const char* xpath_exception::what() const throw() { return _result.error; } PUGI__FN const xpath_parse_result& xpath_exception::result() const { return _result; } #endif PUGI__FN xpath_node::xpath_node() { } PUGI__FN xpath_node::xpath_node(const xml_node& node_): _node(node_) { } PUGI__FN xpath_node::xpath_node(const xml_attribute& attribute_, const xml_node& parent_): _node(attribute_ ? parent_ : xml_node()), _attribute(attribute_) { } PUGI__FN xml_node xpath_node::node() const { return _attribute ? xml_node() : _node; } PUGI__FN xml_attribute xpath_node::attribute() const { return _attribute; } PUGI__FN xml_node xpath_node::parent() const { return _attribute ? _node : _node.parent(); } PUGI__FN static void unspecified_bool_xpath_node(xpath_node***) { } PUGI__FN xpath_node::operator xpath_node::unspecified_bool_type() const { return (_node || _attribute) ? unspecified_bool_xpath_node : 0; } PUGI__FN bool xpath_node::operator!() const { return !(_node || _attribute); } PUGI__FN bool xpath_node::operator==(const xpath_node& n) const { return _node == n._node && _attribute == n._attribute; } PUGI__FN bool xpath_node::operator!=(const xpath_node& n) const { return _node != n._node || _attribute != n._attribute; } #ifdef __BORLANDC__ PUGI__FN bool operator&&(const xpath_node& lhs, bool rhs) { return (bool)lhs && rhs; } PUGI__FN bool operator||(const xpath_node& lhs, bool rhs) { return (bool)lhs || rhs; } #endif PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_) { assert(begin_ <= end_); size_t size_ = static_cast(end_ - begin_); if (size_ <= 1) { // deallocate old buffer if (_begin != &_storage) impl::xml_memory::deallocate(_begin); // use internal buffer if (begin_ != end_) _storage = *begin_; _begin = &_storage; _end = &_storage + size_; } else { // make heap copy xpath_node* storage = static_cast(impl::xml_memory::allocate(size_ * sizeof(xpath_node))); if (!storage) { #ifdef PUGIXML_NO_EXCEPTIONS return; #else throw std::bad_alloc(); #endif } memcpy(storage, begin_, size_ * sizeof(xpath_node)); // deallocate old buffer if (_begin != &_storage) impl::xml_memory::deallocate(_begin); // finalize _begin = storage; _end = storage + size_; } } PUGI__FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(&_storage), _end(&_storage) { } PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_), _begin(&_storage), _end(&_storage) { _assign(begin_, end_); } PUGI__FN xpath_node_set::~xpath_node_set() { if (_begin != &_storage) impl::xml_memory::deallocate(_begin); } PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(ns._type), _begin(&_storage), _end(&_storage) { _assign(ns._begin, ns._end); } PUGI__FN xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns) { if (this == &ns) return *this; _type = ns._type; _assign(ns._begin, ns._end); return *this; } PUGI__FN xpath_node_set::type_t xpath_node_set::type() const { return _type; } PUGI__FN size_t xpath_node_set::size() const { return _end - _begin; } PUGI__FN bool xpath_node_set::empty() const { return _begin == _end; } PUGI__FN const xpath_node& xpath_node_set::operator[](size_t index) const { assert(index < size()); return _begin[index]; } PUGI__FN xpath_node_set::const_iterator xpath_node_set::begin() const { return _begin; } PUGI__FN xpath_node_set::const_iterator xpath_node_set::end() const { return _end; } PUGI__FN void xpath_node_set::sort(bool reverse) { _type = impl::xpath_sort(_begin, _end, _type, reverse); } PUGI__FN xpath_node xpath_node_set::first() const { return impl::xpath_first(_begin, _end, _type); } PUGI__FN xpath_parse_result::xpath_parse_result(): error("Internal error"), offset(0) { } PUGI__FN xpath_parse_result::operator bool() const { return error == 0; } PUGI__FN const char* xpath_parse_result::description() const { return error ? error : "No error"; } PUGI__FN xpath_variable::xpath_variable() { } PUGI__FN const char_t* xpath_variable::name() const { switch (_type) { case xpath_type_node_set: return static_cast(this)->name; case xpath_type_number: return static_cast(this)->name; case xpath_type_string: return static_cast(this)->name; case xpath_type_boolean: return static_cast(this)->name; default: assert(!"Invalid variable type"); return 0; } } PUGI__FN xpath_value_type xpath_variable::type() const { return _type; } PUGI__FN bool xpath_variable::get_boolean() const { return (_type == xpath_type_boolean) ? static_cast(this)->value : false; } PUGI__FN double xpath_variable::get_number() const { return (_type == xpath_type_number) ? static_cast(this)->value : impl::gen_nan(); } PUGI__FN const char_t* xpath_variable::get_string() const { const char_t* value = (_type == xpath_type_string) ? static_cast(this)->value : 0; return value ? value : PUGIXML_TEXT(""); } PUGI__FN const xpath_node_set& xpath_variable::get_node_set() const { return (_type == xpath_type_node_set) ? static_cast(this)->value : impl::dummy_node_set; } PUGI__FN bool xpath_variable::set(bool value) { if (_type != xpath_type_boolean) return false; static_cast(this)->value = value; return true; } PUGI__FN bool xpath_variable::set(double value) { if (_type != xpath_type_number) return false; static_cast(this)->value = value; return true; } PUGI__FN bool xpath_variable::set(const char_t* value) { if (_type != xpath_type_string) return false; impl::xpath_variable_string* var = static_cast(this); // duplicate string size_t size = (impl::strlength(value) + 1) * sizeof(char_t); char_t* copy = static_cast(impl::xml_memory::allocate(size)); if (!copy) return false; memcpy(copy, value, size); // replace old string if (var->value) impl::xml_memory::deallocate(var->value); var->value = copy; return true; } PUGI__FN bool xpath_variable::set(const xpath_node_set& value) { if (_type != xpath_type_node_set) return false; static_cast(this)->value = value; return true; } PUGI__FN xpath_variable_set::xpath_variable_set() { for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) _data[i] = 0; } PUGI__FN xpath_variable_set::~xpath_variable_set() { for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) { xpath_variable* var = _data[i]; while (var) { xpath_variable* next = var->_next; impl::delete_xpath_variable(var->_type, var); var = next; } } } PUGI__FN xpath_variable* xpath_variable_set::find(const char_t* name) const { const size_t hash_size = sizeof(_data) / sizeof(_data[0]); size_t hash = impl::hash_string(name) % hash_size; // look for existing variable for (xpath_variable* var = _data[hash]; var; var = var->_next) if (impl::strequal(var->name(), name)) return var; return 0; } PUGI__FN xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type) { const size_t hash_size = sizeof(_data) / sizeof(_data[0]); size_t hash = impl::hash_string(name) % hash_size; // look for existing variable for (xpath_variable* var = _data[hash]; var; var = var->_next) if (impl::strequal(var->name(), name)) return var->type() == type ? var : 0; // add new variable xpath_variable* result = impl::new_xpath_variable(type, name); if (result) { result->_type = type; result->_next = _data[hash]; _data[hash] = result; } return result; } PUGI__FN bool xpath_variable_set::set(const char_t* name, bool value) { xpath_variable* var = add(name, xpath_type_boolean); return var ? var->set(value) : false; } PUGI__FN bool xpath_variable_set::set(const char_t* name, double value) { xpath_variable* var = add(name, xpath_type_number); return var ? var->set(value) : false; } PUGI__FN bool xpath_variable_set::set(const char_t* name, const char_t* value) { xpath_variable* var = add(name, xpath_type_string); return var ? var->set(value) : false; } PUGI__FN bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value) { xpath_variable* var = add(name, xpath_type_node_set); return var ? var->set(value) : false; } PUGI__FN xpath_variable* xpath_variable_set::get(const char_t* name) { return find(name); } PUGI__FN const xpath_variable* xpath_variable_set::get(const char_t* name) const { return find(name); } PUGI__FN xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables): _impl(0) { impl::xpath_query_impl* qimpl = impl::xpath_query_impl::create(); if (!qimpl) { #ifdef PUGIXML_NO_EXCEPTIONS _result.error = "Out of memory"; #else throw std::bad_alloc(); #endif } else { impl::buffer_holder impl_holder(qimpl, impl::xpath_query_impl::destroy); qimpl->root = impl::xpath_parser::parse(query, variables, &qimpl->alloc, &_result); if (qimpl->root) { _impl = static_cast(impl_holder.release()); _result.error = 0; } } } PUGI__FN xpath_query::~xpath_query() { impl::xpath_query_impl::destroy(_impl); } PUGI__FN xpath_value_type xpath_query::return_type() const { if (!_impl) return xpath_type_none; return static_cast(_impl)->root->rettype(); } PUGI__FN bool xpath_query::evaluate_boolean(const xpath_node& n) const { if (!_impl) return false; impl::xpath_context c(n, 1, 1); impl::xpath_stack_data sd; #ifdef PUGIXML_NO_EXCEPTIONS if (setjmp(sd.error_handler)) return false; #endif return static_cast(_impl)->root->eval_boolean(c, sd.stack); } PUGI__FN double xpath_query::evaluate_number(const xpath_node& n) const { if (!_impl) return impl::gen_nan(); impl::xpath_context c(n, 1, 1); impl::xpath_stack_data sd; #ifdef PUGIXML_NO_EXCEPTIONS if (setjmp(sd.error_handler)) return impl::gen_nan(); #endif return static_cast(_impl)->root->eval_number(c, sd.stack); } #ifndef PUGIXML_NO_STL PUGI__FN string_t xpath_query::evaluate_string(const xpath_node& n) const { impl::xpath_stack_data sd; return impl::evaluate_string_impl(static_cast(_impl), n, sd).c_str(); } #endif PUGI__FN size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const { impl::xpath_stack_data sd; impl::xpath_string r = impl::evaluate_string_impl(static_cast(_impl), n, sd); size_t full_size = r.length() + 1; if (capacity > 0) { size_t size = (full_size < capacity) ? full_size : capacity; assert(size > 0); memcpy(buffer, r.c_str(), (size - 1) * sizeof(char_t)); buffer[size - 1] = 0; } return full_size; } PUGI__FN xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const { if (!_impl) return xpath_node_set(); impl::xpath_ast_node* root = static_cast(_impl)->root; if (root->rettype() != xpath_type_node_set) { #ifdef PUGIXML_NO_EXCEPTIONS return xpath_node_set(); #else xpath_parse_result res; res.error = "Expression does not evaluate to node set"; throw xpath_exception(res); #endif } impl::xpath_context c(n, 1, 1); impl::xpath_stack_data sd; #ifdef PUGIXML_NO_EXCEPTIONS if (setjmp(sd.error_handler)) return xpath_node_set(); #endif impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack); return xpath_node_set(r.begin(), r.end(), r.type()); } PUGI__FN const xpath_parse_result& xpath_query::result() const { return _result; } PUGI__FN static void unspecified_bool_xpath_query(xpath_query***) { } PUGI__FN xpath_query::operator xpath_query::unspecified_bool_type() const { return _impl ? unspecified_bool_xpath_query : 0; } PUGI__FN bool xpath_query::operator!() const { return !_impl; } PUGI__FN xpath_node xml_node::select_single_node(const char_t* query, xpath_variable_set* variables) const { xpath_query q(query, variables); return select_single_node(q); } PUGI__FN xpath_node xml_node::select_single_node(const xpath_query& query) const { xpath_node_set s = query.evaluate_node_set(*this); return s.empty() ? xpath_node() : s.first(); } PUGI__FN xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const { xpath_query q(query, variables); return select_nodes(q); } PUGI__FN xpath_node_set xml_node::select_nodes(const xpath_query& query) const { return query.evaluate_node_set(*this); } } } OIIO_NAMESPACE_EXIT #endif #ifdef __BORLANDC__ # pragma option pop #endif // Intel C++ does not properly keep warning state for function templates, // so popping warning state at the end of translation unit leads to warnings in the middle. #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) # pragma warning(pop) #endif // Undefine all local macros (makes sure we're not leaking macros in header-only mode) #undef PUGI__NO_INLINE #undef PUGI__STATIC_ASSERT #undef PUGI__DMC_VOLATILE #undef PUGI__MSVC_CRT_VERSION #undef PUGI__NS_BEGIN #undef PUGI__NS_END #undef PUGI__FN #undef PUGI__FN_NO_INLINE #undef PUGI__IS_CHARTYPE_IMPL #undef PUGI__IS_CHARTYPE #undef PUGI__IS_CHARTYPEX #undef PUGI__SKIPWS #undef PUGI__OPTSET #undef PUGI__PUSHNODE #undef PUGI__POPNODE #undef PUGI__SCANFOR #undef PUGI__SCANWHILE #undef PUGI__ENDSEG #undef PUGI__THROW_ERROR #undef PUGI__CHECK_ERROR #endif /** * Copyright (c) 2006-2012 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ openimageio-1.3.12~dfsg0.orig/src/include/unordered_map_concurrent.h0000644000175000017500000003453512271062644024004 0ustar mfvmfv/* Copyright 2012 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #pragma once #ifndef OPENIMAGEIO_UNORDERED_MAP_CONCURRENT_H #define OPENIMAGEIO_UNORDERED_MAP_CONCURRENT_H #include #include "sysutil.h" // from OIIO #include "thread.h" // from OIIO #include "hash.h" // from OIIO #include "dassert.h" // from OIIO OIIO_NAMESPACE_ENTER { /// unordered_map_concurrent provides an unordered_map replacement that /// is optimized for concurrent access. Its principle of operation is /// similar to Java's ConcurrentHashMap. /// /// With naive use of an unordered_map, multiple threads would have to /// lock a mutex of some kind to control access to the map, either with /// a unique full lock, or with a reader/writer lock. But as the number /// of threads contending for this shared resource rises, they end up /// locking each other out and the map becomes a thread bottleneck. /// /// unordered_map_concurrent solves this problem by internally splitting /// the hash map into several disjoint bins, each of which is a standard /// unordered_map. For any given map item, the hash of its key /// determines both the bin as well as its hashing within the bin (i.e., /// we break a big hash map into lots of little hash maps, /// deterministically determined by the key). Thus, we should expect /// map entries to be spread more or less evenly among the bins. There /// is no mutex that locks the map as a whole; instead, each bin is /// locked individually. If the number of bins is larger than the /// typical number of threads, most of the time two (or more) threads /// accessing the map simultaneously will not be accessing the same bin, /// and therefore will not be contending for the same lock. /// /// unordered_map_concurrent provides an iterator which points to an /// entry in the map and also knows which bin it is in and implicitly /// holds a lock on the bin. When the iterator is destroyed, the lock /// on that bin is released. When the iterator is incremented in such a /// way that it transitions from the last entry of its current bin to /// the first entry of the next bin, it will also release its current /// lock and obtain a lock on the next bin. /// template, class PRED=std::equal_to, size_t BINS=16> class unordered_map_concurrent { public: typedef boost::unordered_map BinMap_t; typedef typename boost::unordered_map::iterator BinMap_iterator_t; public: unordered_map_concurrent () { m_size = 0; } ~unordered_map_concurrent () { // for (size_t i = 0; i < BINS; ++i) // std::cout << "Bin " << i << ": " << m_bins[i].map.size() << "\n"; } /// An unordered_map_concurrent::iterator points to a specific entry /// in the umc, and holds a lock to the bin the entry is in. class iterator { public: friend class unordered_map_concurrent; public: /// Construct an unordered_map_concurrent iterator that points /// to nothing. iterator (unordered_map_concurrent *umc = NULL) : m_umc(umc), m_bin(-1), m_locked(false) { } /// Copy constructor of an unordered_map_concurrent iterator /// transfers the lock (if held) to this. Caveat: the copied /// iterator no longer holds the lock! iterator (const iterator &src) { m_umc = src.m_umc; m_bin = src.m_bin; m_biniterator = src.m_biniterator; m_locked = src.m_locked; // assignment transfers lock ownership *(const_cast(&src.m_locked)) = false; } /// Destroying an unordered_map_concurrent iterator releases any /// bin locks it held. ~iterator () { clear(); } /// Totally invalidate this iterator -- point it to nothing /// (releasing any locks it may have had). void clear () { if (m_umc) { unbin (); m_umc = NULL; } } // Dereferencing returns a reference to the hash table entry the // iterator refers to. typename BinMap_t::value_type & operator* () { return *m_biniterator; } /// Dereferencing returns a reference to the hash table entry the /// iterator refers to. typename BinMap_t::value_type * operator-> () { return &(*m_biniterator); } /// Treating an iterator as a bool yields true if it points to a /// valid element of one of the bins of the map, false if it's /// equivalent to the end() iterator. operator bool() { return m_umc && m_bin >= 0 && m_biniterator != m_umc->m_bins[m_bin].map.end(); } /// Iterator assignment transfers ownership of any bin locks /// held by the operand. iterator& operator= (const iterator &src) { unbin(); m_umc = src.m_umc; m_bin = src.m_bin; m_biniterator = src.m_biniterator; m_locked = src.m_locked; // assignment transfers lock ownership *(const_cast(&src.m_locked)) = false; return *this; } bool operator== (const iterator &other) const { if (m_umc != other.m_umc) return false; if (m_bin == -1 && other.m_bin == -1) return true; return m_bin == other.m_bin && m_biniterator == other.m_biniterator; } bool operator!= (const iterator &other) { return ! (*this == other); } /// Increment to the next entry in the map. If we finish the /// bin we're in, move on to the next bin (releasing our lock on /// the old bin and acquiring a lock on the new bin). If we /// finish the last bin of the map, return the end() iterator. void operator++ () { DASSERT (m_umc); DASSERT (m_bin >= 0); ++m_biniterator; while (m_biniterator == m_umc->m_bins[m_bin].map.end()) { if (m_bin == BINS-1) { // ran off the end unbin(); return; } rebin (m_bin+1); } } void operator++ (int) { ++(*this); } /// Lock the bin we point to, if not already locked. void lock () { if (m_bin >= 0 && !m_locked) { m_umc->m_bins[m_bin].lock(); m_locked = true; } } /// Unlock the bin we point to, if locked. void unlock () { if (m_bin >= 0 && m_locked) { m_umc->m_bins[m_bin].unlock(); m_locked = false; } } /// Without changing the lock status (i.e., the caller already /// holds the lock on the iterator's bin), increment to the next /// element within the bin. Return true if it's pointing to a /// valid element afterwards, false if it ran off the end of the /// bin contents. bool incr_no_lock () { ++m_biniterator; return (m_biniterator != m_umc->m_bins[m_bin].map.end()); } private: // No longer refer to a particular bin, release lock on the bin // it had (if any). void unbin () { if (m_bin >= 0) { if (m_locked) unlock (); m_bin = -1; } } // Point this iterator to a different bin, releasing locks on // the bin it previously referred to. void rebin (int newbin) { DASSERT (m_umc); unbin (); m_bin = newbin; lock (); m_biniterator = m_umc->m_bins[m_bin].map.begin(); } unordered_map_concurrent *m_umc; // which umc this iterator refers to int m_bin; // which bin within the umc BinMap_iterator_t m_biniterator; // which entry within the bin bool m_locked; // do we own the lock on the bin? }; /// Return an interator pointing to the first entry in the map. iterator begin () { iterator i (this); i.rebin (0); while (i.m_biniterator == m_bins[i.m_bin].map.end()) { if (i.m_bin == BINS-1) { // ran off the end i.unbin(); return i; } i.rebin (i.m_bin+1); } return i; } /// Return an iterator signifying the end of the map (no valid /// entry pointed to). iterator end () { iterator i (this); return i; } /// Search for key. If found, return an iterator referring to the /// element, otherwise, return an iterator that is equivalent to /// this->end(). If do_lock is true, lock the bin that we're /// searching and return the iterator in a locked state, and unlock /// the bin again if not found; however, if do_lock is false, assume /// that the caller already has the bin locked, so do no locking or /// unlocking and return an iterator that is unaware that it holds a /// lock. iterator find (const KEY &key, bool do_lock = true) { size_t b = whichbin(key); Bin &bin (m_bins[b]); if (do_lock) bin.lock (); typename BinMap_t::iterator it = bin.map.find (key); if (it == bin.map.end()) { // not found -- return the 'end' iterator if (do_lock) bin.unlock(); return end(); } // Found iterator i (this); i.m_bin = (unsigned) b; i.m_biniterator = it; i.m_locked = do_lock; return i; } /// Insert into the hash map if it's not already there. /// Return true if added, false if it was already present. /// If do_lock is true, lock the bin containing key while doing this /// operation; if do_lock is false, assume that the caller already /// has the bin locked, so do no locking or unlocking. bool insert (const KEY &key, const VALUE &value, bool do_lock = true) { size_t b = whichbin(key); Bin &bin (m_bins[b]); if (do_lock) bin.lock (); bool add = (bin.map.find (key) == bin.map.end()); if (add) { // not found -- add it! bin.map[key] = value; ++m_size; } if (do_lock) bin.unlock(); return add; } /// If the key is in the map, safely erase it. /// If do_lock is true, lock the bin containing key while doing this /// operation; if do_lock is false, assume that the caller already /// has the bin locked, so do no locking or unlocking. void erase (const KEY &key, bool do_lock = true) { size_t b = whichbin(key); Bin &bin (m_bins[b]); if (do_lock) bin.lock (); typename BinMap_t::iterator it = bin.map.find (key); if (it != bin.map.end()) { bin.map.erase (it); } if (do_lock) bin.unlock(); } /// Return true if the entire map is empty. bool empty() { return m_size == 0; } /// Expliticly lock the bin that will contain the key (regardless of /// whether there is such an entry in the map), and return its bin /// number. size_t lock_bin (const KEY &key) { size_t b = whichbin(key); m_bins[b].lock (); return b; } /// Explicitly unlock the specified bin (this assumes that the caller /// holds the lock). void unlock_bin (size_t bin) { m_bins[bin].unlock (); } private: struct Bin { // OIIO_CACHE_ALIGN // align to cache line -- doesn't seem to help mutable spin_mutex mutex; // mutex for this bin BinMap_t map; // hash map for this bin #ifndef NDEBUG mutable atomic_int m_nlocks; // for debugging #endif Bin () { #ifndef NDEBUG m_nlocks = 0; #endif } ~Bin () { #ifndef NDEBUG DASSERT (m_nlocks == 0); #endif } void lock () const { mutex.lock(); #ifndef NDEBUG ++m_nlocks; DASSERT_MSG (m_nlocks == 1, "oops, m_nlocks = %d", (int)m_nlocks); #endif } void unlock () const { #ifndef NDEBUG DASSERT_MSG (m_nlocks == 1, "oops, m_nlocks = %d", (int)m_nlocks); --m_nlocks; #endif mutex.unlock(); } }; HASH m_hash; // hashing function atomic_int m_size; // total entries in all bins Bin m_bins[BINS]; // the bins // Which bin will this key always appear in? size_t whichbin (const KEY &key) { size_t h = m_hash(key); h = (size_t) murmur::fmix (uint64_t(h)); // scramble again return h % BINS; } }; } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_UNORDERED_MAP_CONCURRENT_H openimageio-1.3.12~dfsg0.orig/src/include/dassert.h0000644000175000017500000001066612271062644020362 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_DASSERT_H #define OPENIMAGEIO_DASSERT_H #include #include /// \file /// /// Handy macros for debugging assertions. /// /// - ASSERT (if not already defined) is defined to check if a condition /// is met, and if not, calls ABORT with an error message /// indicating the module and line where it occurred. /// - ASSERT_MSG: like ASSERT, but takes printf-like extra arguments /// - DASSERT is the same as ASSERT when NDEBUG is not defined but a /// no-op when not in debug mode. /// - DASSERT_MSG: like DASSERT, but takes printf-like extra arguments /// /// The presumed usage is that you want ASSERT for dire conditions that /// must be checked at runtime even in an optimized build. DASSERT is /// for checks we should do for debugging, but that we don't want to /// bother with in a shipping optimized build. /// /// In both cases, these are NOT a substitute for actual error checking /// and recovery! Never ASSERT or DASSERT to check invalid user input, /// for example. They should be used only to verify that there aren't /// errors in the *code* that are so severe that there is no point even /// trying to recover gracefully. /// ASSERT(condition) checks if the condition is met, and if not, prints /// an error message indicating the module and line where the error /// occurred and then aborts. #ifndef ASSERT # define ASSERT(x) \ ((x) ? ((void)0) \ : (fprintf (stderr, "%s:%u: failed assertion '%s'\n", \ __FILE__, __LINE__, #x), abort())) #endif /// ASSERT_MSG(condition,msg,...) is like ASSERT, but lets you add /// formatted output (a la printf) to the failure message. #ifndef ASSERT_MSG # define ASSERT_MSG(x,msg,...) \ ((x) ? ((void)0) \ : (fprintf (stderr, "%s:%u: failed assertion '%s': " msg "\n", \ __FILE__, __LINE__, #x, __VA_ARGS__), abort())) #endif #ifndef ASSERTMSG #define ASSERTMSG ASSERT_MSG #endif /// DASSERT(condition) is just like ASSERT, except that it only is /// functional in DEBUG mode, but does nothing when in a non-DEBUG /// (optimized, shipping) build. #ifndef NDEBUG # define DASSERT(x) ASSERT(x) #else /* DASSERT does nothing when not debugging; sizeof trick prevents warnings */ # define DASSERT(x) ((void)sizeof(x)) #endif /// DASSERT_MSG(condition,msg,...) is just like ASSERT_MSG, except that it /// only is functional in DEBUG mode, but does nothing when in a /// non-DEBUG (optimized, shipping) build. #ifndef NDEBUG # define DASSERT_MSG ASSERT_MSG #else # define DASSERT_MSG(x,...) ((void)sizeof(x)) /* does nothing when not debugging */ #endif #ifndef DASSERTMSG #define DASSERTMSG DASSERT_MSG #endif #endif // OPENIMAGEIO_DASSERT_H openimageio-1.3.12~dfsg0.orig/src/include/timer.h0000644000175000017500000002114712271062644020031 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// @file timer.h /// @brief Simple timer class. #ifndef OPENIMAGEIO_TIMER_H #define OPENIMAGEIO_TIMER_H #include "version.h" #ifdef _WIN32 # include "osdep.h" #elif defined(__APPLE__) # include #else #include #include // Just for NULL definition #endif OIIO_NAMESPACE_ENTER { /// Simple timer class. /// /// This class allows you to time things, for runtime statistics and the /// like. The simplest usage pattern is illustrated by the following /// example: /// /// \code /// Timer mytimer; // automatically starts upon construction /// ...do stuff /// float t = mytimer(); // seconds elapsed since start /// /// Timer another (false); // false means don't start ticking yet /// another.start (); // start ticking now /// another.stop (); // stop ticking /// another.start (); // start again where we left off /// another.stop (); /// another.reset (); // reset to zero time again /// \endcode /// /// These are not very high-resolution timers. A Timer begin/end pair /// takes somewhere in the neighborhood of 0.1 - 0.3 us (microseconds), /// and can vary by OS. This means that (a) it's not useful for timing /// individual events near or below that resolution (things that would /// take only tens or hundreds of processor cycles, for example), and /// (b) calling it millions of times could make your program appreciably /// more expensive due to the timers themselves. /// class Timer { public: #ifdef _WIN32 typedef LARGE_INTEGER value_t; // Sheesh, why can't they use a standard type like stdint's int64_t? #elif defined(__APPLE__) typedef unsigned long long value_t; #else typedef struct timeval value_t; #endif /// Constructor -- reset at zero, and start timing unless optional /// 'startnow' argument is false. Timer (bool startnow=true) : m_ticking(false), m_elapsed(0) { if (startnow) start(); else { // Initialize m_starttime to avoid warnings #ifdef _WIN32 m_starttime.QuadPart = 0; #elif defined(__APPLE__) m_starttime = 0; #else m_starttime.tv_sec = 0; m_starttime.tv_usec = 0; #endif } } /// Destructor. /// ~Timer () { } /// Start ticking, or restart if we have stopped. /// void start () { if (! m_ticking) { m_starttime = now(); m_ticking = true; } } /// Stop ticking, return the total amount of time that has ticked /// (both this round as well as previous laps). Current ticks will /// be added to previous elapsed time. double stop () { if (m_ticking) { value_t n = now(); m_elapsed += diff (m_starttime, n); m_ticking = false; } return m_elapsed; } /// Reset at zero and stop ticking. /// void reset (void) { m_elapsed = 0; m_ticking = false; } /// Return just the time of the current lap (since the last call to /// start() or lap()), add that to the previous elapsed time, reset /// current start time to now, keep the timer going (if it was). double lap () { value_t n = now(); double r = m_ticking ? diff (m_starttime, n) : 0.0; m_elapsed += r; m_starttime = n; m_ticking = true; return r; } /// Operator () returns the elapsed time so far, including both the /// currently-ticking clock as well as any previously elapsed time. double operator() (void) const { return m_elapsed + time_since_start(); } /// Return just the time since we called start(), not any elapsed /// time in previous start-stop segments. double time_since_start (void) const { if (m_ticking) { value_t n = now(); return diff (m_starttime, n); } else { return 0; } } private: bool m_ticking; ///< Are we currently ticking? value_t m_starttime; ///< Time since last call to start() double m_elapsed; ///< Time elapsed BEFORE the current start(). /// Platform-dependent grab of current time, expressed as value_t. /// value_t now (void) const { value_t n; #ifdef _WIN32 QueryPerformanceCounter (&n); // From MSDN web site #elif defined(__APPLE__) n = mach_absolute_time(); #else gettimeofday (&n, NULL); #endif return n; } /// Platform-dependent difference between two times, expressed in /// seconds. static double diff (const value_t &then, const value_t &now) { #ifdef _WIN32 // From MSDN web site value_t freq; QueryPerformanceFrequency (&freq); return (double)(now.QuadPart - then.QuadPart) / (double)freq.QuadPart; #elif defined(__APPLE__) // NOTE(boulos): Both this value and that of the windows // counterpart above only need to be calculated once. In // Manta, we stored this on the side as a scaling factor but // that would require a .cpp file (meaning timer.h can't just // be used as a header). It is also claimed that since // Leopard, Apple returns 1 for both numer and denom. mach_timebase_info_data_t time_info; mach_timebase_info(&time_info); double seconds_per_tick = (1e-9*static_cast(time_info.numer))/ static_cast(time_info.denom); value_t d = (now>then) ? now-then : then-now; return d * seconds_per_tick; #else return fabs (static_cast(now.tv_sec - then.tv_sec) + static_cast(now.tv_usec - then.tv_usec) / 1e6); #endif } }; /// Helper class that starts and stops a timer when the ScopedTimer goes /// in and out of scope. template class ScopedTimer { public: /// Given a reference to a timer, start it when this constructor /// occurs. ScopedTimer (TIMER &t) : m_timer(t) { start(); } /// Stop the timer from ticking when this object is destroyed (i.e. /// it leaves scope). ~ScopedTimer () { stop(); } /// Explicit start of the timer. /// void start () { m_timer.start(); } /// Explicit stop of the timer. /// void stop () { m_timer.stop(); } /// Explicit reset of the timer. /// void reset () { m_timer.reset(); } private: TIMER &m_timer; }; /// Helper template that runs a function (or functor) n times, using a /// Timer to benchmark the results, and returning the fastest trial. If /// 'range' is non-NULL, the range (max-min) of the various time trials /// will be stored there. template double time_trial (FUNC func, int n=1, double *range=NULL) { double mintime = 1.0e30, maxtime = 0.0; while (n-- > 0) { Timer timer; func (); double t = timer(); if (t < mintime) mintime = t; if (t > maxtime) maxtime = t; } if (range) *range = maxtime-mintime; return mintime; } } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_TIMER_H openimageio-1.3.12~dfsg0.orig/src/include/imagebufalgo_util.h0000644000175000017500000004106312271062644022367 0ustar mfvmfv/* Copyright 2013 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_IMAGEBUFALGO_UTIL_H #define OPENIMAGEIO_IMAGEBUFALGO_UTIL_H #include "imagebufalgo.h" OIIO_NAMESPACE_ENTER { namespace ImageBufAlgo { /// Helper template for generalized multithreading for image processing /// functions. Some function/functor f is applied to every pixel the /// region of interest roi, dividing the region into multiple threads if /// threads != 1. Note that threads == 0 indicates that the number of /// threads should be as set by the global OIIO "threads" attribute. /// /// Most image operations will require additional arguments, including /// additional input and output images or other parameters. The /// parallel_image template can still be used by employing the /// boost::bind (or std::bind, for C++11). For example, suppose you /// have an image operation defined as: /// void my_image_op (ImageBuf &out, const ImageBuf &in, /// float scale, ROI roi); /// Then you can parallelize it as follows: /// ImageBuf R /*result*/, A /*input*/; /// ROI roi = get_roi (R.spec()); /// parallel_image (boost::bind(my_image_op,boost::ref(R), /// boost::cref(A),3.14,_1), roi); /// template void parallel_image (Func f, ROI roi, int nthreads=0) { // Special case: threads <= 0 means to use the "threads" attribute if (nthreads <= 0) OIIO::getattribute ("threads", nthreads); if (nthreads <= 1 || roi.npixels() < 1000) { // Just one thread, or a small image region: use this thread only f (roi); } else { // Spawn threads by dividing the region into y bands. boost::thread_group threads; int blocksize = std::max (1, (roi.height() + nthreads - 1) / nthreads); int roi_ybegin = roi.ybegin; int roi_yend = roi.yend; for (int i = 0; i < nthreads; i++) { roi.ybegin = roi_ybegin + i * blocksize; roi.yend = std::min (roi.ybegin + blocksize, roi_yend); if (roi.ybegin >= roi.yend) break; // no more work to dole out threads.add_thread (new boost::thread (f, roi)); } threads.join_all (); } } /// Common preparation for IBA functions: Given an ROI (which may or may not /// be the default ROI::All()), destination image (which may or may not yet /// be allocated), and optional input images, adjust roi if necessary and /// allocate pixels for dst if necessary. If dst is already initialized, it /// will keep its "full" (aka display) window, otherwise its full/display /// window will be set to the union of A's and B's full/display windows. If /// dst is uninitialized and force_spec is not NULL, use *force_spec as /// dst's new spec rather than using A's. Also, if A or B inputs are /// specified but not initialized or broken, it's an error so return false. /// If all is ok, return true. Some additional checks and behaviors may be /// specified by the 'prepflags', which is a bit field defined by /// IBAprep_flags. bool OIIO_API IBAprep (ROI &roi, ImageBuf *dst, const ImageBuf *A=NULL, const ImageBuf *B=NULL, ImageSpec *force_spec=NULL, int prepflags=0); enum IBAprep_flags { IBAprep_DEFAULT = 0, IBAprep_REQUIRE_ALPHA = 1, IBAprep_REQUIRE_Z = 2, IBAprep_REQUIRE_SAME_NCHANNELS = 4 }; // Macro to call a type-specialzed version func(R,...) #define OIIO_DISPATCH_TYPES(name,func,type,R,...) \ switch (type.basetype) { \ case TypeDesc::FLOAT : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT8 : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::HALF : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT16: \ return func (R, __VA_ARGS__); break; \ case TypeDesc::INT8 : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::INT16 : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::INT : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::DOUBLE: \ return func (R, __VA_ARGS__); break; \ default: \ (R).error ("%s: Unsupported pixel data format '%s'", name, type); \ return false; \ } // Helper, do not call from the outside world. #define OIIO_DISPATCH_TYPES2_HELP(name,func,Atype,Btype,R,...) \ switch (Btype.basetype) { \ case TypeDesc::FLOAT : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT8 : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::HALF : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT16: \ return func (R, __VA_ARGS__); break; \ case TypeDesc::INT8 : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::INT16 : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::INT : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::DOUBLE : \ return func (R, __VA_ARGS__); break; \ default: \ (R).error ("%s: Unsupported pixel data format '%s'", name, Btype); \ return false; \ } // Macro to call a type-specialzed version func(R,...). #define OIIO_DISPATCH_TYPES2(name,func,Atype,Btype,R,...) \ switch (Atype.basetype) { \ case TypeDesc::FLOAT : \ OIIO_DISPATCH_TYPES2_HELP(name,func,float,Btype,R,__VA_ARGS__); \ case TypeDesc::UINT8 : \ OIIO_DISPATCH_TYPES2_HELP(name,func,unsigned char,Btype,R,__VA_ARGS__); \ case TypeDesc::HALF : \ OIIO_DISPATCH_TYPES2_HELP(name,func,half,Btype,R,__VA_ARGS__); \ case TypeDesc::UINT16: \ OIIO_DISPATCH_TYPES2_HELP(name,func,unsigned short,Btype,R,__VA_ARGS__); \ case TypeDesc::INT8: \ OIIO_DISPATCH_TYPES2_HELP(name,func,char,Btype,R,__VA_ARGS__); \ case TypeDesc::INT16: \ OIIO_DISPATCH_TYPES2_HELP(name,func,short,Btype,R,__VA_ARGS__); \ case TypeDesc::UINT: \ OIIO_DISPATCH_TYPES2_HELP(name,func,unsigned int,Btype,R,__VA_ARGS__); \ case TypeDesc::INT: \ OIIO_DISPATCH_TYPES2_HELP(name,func,int,Btype,R,__VA_ARGS__); \ case TypeDesc::DOUBLE: \ OIIO_DISPATCH_TYPES2_HELP(name,func,double,Btype,R,__VA_ARGS__);\ default: \ (R).error ("%s: Unsupported pixel data format '%s'", name, Atype); \ return false; \ } // Macro to call a type-specialzed version func(R,...) for // the most common types, fail for anything else. #define OIIO_DISPATCH_COMMON_TYPES(name,func,type,R,...) \ switch (type.basetype) { \ case TypeDesc::FLOAT : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT8 : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::HALF : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT16: \ return func (R, __VA_ARGS__); break; \ default: \ (R).error ("%s: Unsupported pixel data format '%s'", name, type); \ return false; \ } // Helper, do not call from the outside world. #define OIIO_DISPATCH_COMMON_TYPES2_HELP(name,func,Atype,Btype,R,...) \ switch (Btype.basetype) { \ case TypeDesc::FLOAT : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT8 : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::HALF : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT16: \ return func (R, __VA_ARGS__); break; \ default: \ (R).error ("%s: Unsupported pixel data format '%s'", name, Btype); \ return false; \ } // Macro to call a type-specialzed version func(R,...) for // the most common types, fail for anything else. #define OIIO_DISPATCH_COMMON_TYPES2(name,func,Atype,Btype,R,...) \ switch (Atype.basetype) { \ case TypeDesc::FLOAT : \ OIIO_DISPATCH_COMMON_TYPES2_HELP(name,func,float,Btype,R,__VA_ARGS__); \ case TypeDesc::UINT8 : \ OIIO_DISPATCH_COMMON_TYPES2_HELP(name,func,unsigned char,Btype,R,__VA_ARGS__); \ case TypeDesc::HALF : \ OIIO_DISPATCH_COMMON_TYPES2_HELP(name,func,half,Btype,R,__VA_ARGS__); \ case TypeDesc::UINT16: \ OIIO_DISPATCH_COMMON_TYPES2_HELP(name,func,unsigned short,Btype,R,__VA_ARGS__); \ default: \ (R).error ("%s: Unsupported pixel data format '%s'", name, Atype); \ return false; \ } // Helper, do not call from the outside world. #define OIIO_DISPATCH_COMMON_TYPES3_HELP2(name,func,Rtype,Atype,Btype,R,...) \ switch (Rtype.basetype) { \ case TypeDesc::FLOAT : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT8 : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::HALF : \ return func (R, __VA_ARGS__); break; \ case TypeDesc::UINT16: \ return func (R, __VA_ARGS__); break; \ default: \ (R).error ("%s: Unsupported pixel data format '%s'", name, Rtype); \ return false; \ } // Helper, do not call from the outside world. #define OIIO_DISPATCH_COMMON_TYPES3_HELP(name,func,Rtype,Atype,Btype,R,...) \ switch (Btype.basetype) { \ case TypeDesc::FLOAT : \ OIIO_DISPATCH_COMMON_TYPES3_HELP2(name,func,Rtype,Atype,float,R,__VA_ARGS__); \ case TypeDesc::UINT8 : \ OIIO_DISPATCH_COMMON_TYPES3_HELP2(name,func,Rtype,Atype,unsigned char,R,__VA_ARGS__); \ case TypeDesc::HALF : \ OIIO_DISPATCH_COMMON_TYPES3_HELP2(name,func,Rtype,Atype,half,R,__VA_ARGS__); \ case TypeDesc::UINT16 : \ OIIO_DISPATCH_COMMON_TYPES3_HELP2(name,func,Rtype,Atype,unsigned short,R,__VA_ARGS__); \ default: \ (R).error ("%s: Unsupported pixel data format '%s'", name, Btype); \ return false; \ } // Macro to call a type-specialzed version func(R,...) // for the most common types, fail for anything else. #define OIIO_DISPATCH_COMMON_TYPES3(name,func,Rtype,Atype,Btype,R,...) \ switch (Atype.basetype) { \ case TypeDesc::FLOAT : \ OIIO_DISPATCH_COMMON_TYPES3_HELP(name,func,Rtype,float,Btype,R,__VA_ARGS__); \ case TypeDesc::UINT8 : \ OIIO_DISPATCH_COMMON_TYPES3_HELP(name,func,Rtype,unsigned char,Btype,R,__VA_ARGS__); \ case TypeDesc::HALF : \ OIIO_DISPATCH_COMMON_TYPES3_HELP(name,func,Rtype,half,Btype,R,__VA_ARGS__); \ case TypeDesc::UINT16: \ OIIO_DISPATCH_COMMON_TYPES3_HELP(name,func,Rtype,unsigned short,Btype,R,__VA_ARGS__); \ default: \ (R).error ("%s: Unsupported pixel data format '%s'", name, Atype); \ return false; \ } } // end namespace ImageBufAlgo } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_IMAGEBUFALGO_UTIL_H openimageio-1.3.12~dfsg0.orig/src/include/strutil.h0000644000175000017500000003410512271062644020415 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////// /// @file strutil.h /// /// @brief String-related utilities, all in namespace Strutil. ///////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_STRUTIL_H #define OPENIMAGEIO_STRUTIL_H #include #include #include #include #include #include #include "export.h" #include "version.h" #include "tinyformat.h" #ifndef OPENIMAGEIO_PRINTF_ARGS # ifndef __GNUC__ # define __attribute__(x) # endif // Enable printf-like warnings with gcc by attaching // OPENIMAGEIO_PRINTF_ARGS to printf-like functions. Eg: // // void foo (const char* fmt, ...) OPENIMAGEIO_PRINTF_ARGS(1,2); // // The arguments specify the positions of the format string and the the // beginning of the varargs parameter list respectively. // // For member functions with arguments like the example above, you need // OPENIMAGEIO_PRINTF_ARGS(2,3) instead. (gcc includes the implicit this // pointer when it counts member function arguments.) # define OPENIMAGEIO_PRINTF_ARGS(fmtarg_pos, vararg_pos) \ __attribute__ ((format (printf, fmtarg_pos, vararg_pos) )) #endif OIIO_NAMESPACE_ENTER { /// @namespace Strutil /// /// @brief String-related utilities. namespace Strutil { /// Construct a std::string in a printf-like fashion. In other words, /// something like: /// std::string s = Strutil::format ("blah %d %g", (int)foo, (float)bar); /// /// The printf argument list is fully typesafe via tinyformat; format /// conceptually has the signature /// /// std::string Strutil::format (const char *fmt, ...); TINYFORMAT_WRAP_FORMAT (std::string, format, /**/, std::ostringstream msg;, msg, return msg.str();) /// Return a std::string formatted from printf-like arguments. Like the /// real sprintf, this is not guaranteed type-safe and is not extensible /// like format(). You would only want to use this instead of the safe /// format() in rare situations where you really need to use obscure /// printf features that aren't supported by tinyformat. std::string OIIO_API format_raw (const char *fmt, ...) OPENIMAGEIO_PRINTF_ARGS(1,2); /// Return a std::string formatted from printf-like arguments -- passed /// already as a va_list. Like vsprintf, this is not guaranteed /// type-safe and is not extensible like format(). std::string OIIO_API vformat (const char *fmt, va_list ap) OPENIMAGEIO_PRINTF_ARGS(1,0); /// Return a string expressing a number of bytes, in human readable form. /// - memformat(153) -> "153 B" /// - memformat(15300) -> "14.9 KB" /// - memformat(15300000) -> "14.6 MB" /// - memformat(15300000000LL) -> "14.2 GB" std::string OIIO_API memformat (long long bytes, int digits=1); /// Return a string expressing an elapsed time, in human readable form. /// e.g. "0:35.2" std::string OIIO_API timeintervalformat (double secs, int digits=1); /// Get a map with RESTful arguments extracted from the given string 'str'. /// Add it into the 'result' argument (Warning: the 'result' argument may /// be changed even if 'get_rest_arguments ()' return an error!). /// Return true on success, false on error. /// Acceptable forms: /// - text?arg1=val1&arg2=val2... /// - ?arg1=val1&arg2=val2... /// Everything before question mark will be saved into the 'base' argument. bool OIIO_API get_rest_arguments (const std::string &str, std::string &base, std::map &result); /// Take a string that may have embedded newlines, tabs, etc., and turn /// those characters into escape sequences like \n, \t, \v, \b, \r, \f, /// \a, \\, \". std::string OIIO_API escape_chars (const std::string &unescaped); /// Take a string that has embedded escape sequences (\\, \", \n, etc.) /// and collapse them into the 'real' characters. std::string OIIO_API unescape_chars (const std::string &escaped); /// Word-wrap string 'src' to no more than columns width, splitting at /// space characters. It assumes that 'prefix' characters are already /// printed, and furthermore, if it should need to wrap, it prefixes that /// number of spaces in front of subsequent lines. By illustration, /// wordwrap("0 1 2 3 4 5 6 7 8", 4, 10) should return: /// "0 1 2\n 3 4 5\n 6 7 8" std::string OIIO_API wordwrap (std::string src, int columns=80, int prefix=0); /// Hash a string without pre-known length. We use the Jenkins /// one-at-a-time hash (http://en.wikipedia.org/wiki/Jenkins_hash_function), /// which seems to be a good speed/quality/requirements compromise. inline size_t strhash (const char *s) { if (! s) return 0; unsigned int h = 0; while (*s) { h += (unsigned char)(*s); h += h << 10; h ^= h >> 6; ++s; } h += h << 3; h ^= h >> 11; h += h << 15; return h; } /// Case-insensitive comparison of strings. For speed, this always uses /// a static locale that doesn't require a mutex. bool OIIO_API iequals (const std::string &a, const std::string &b); bool OIIO_API iequals (const char *a, const char *b); /// Does 'a' start with the string 'b', with a case-insensitive comparison? /// For speed, this always uses a static locale that doesn't require a mutex. bool OIIO_API istarts_with (const std::string &a, const std::string &b); bool OIIO_API istarts_with (const char *a, const char *b); /// Does 'a' end with the string 'b', with a case-insensitive comparison? /// For speed, this always uses a static locale that doesn't require a mutex. bool OIIO_API iends_with (const std::string &a, const std::string &b); bool OIIO_API iends_with (const char *a, const char *b); /// Does 'a' end with the string 'b', with a case-insensitive comparison? /// For speed, this always uses a static locale that doesn't require a mutex. bool OIIO_API iends_with (const std::string &a, const std::string &b); bool OIIO_API iends_with (const char *a, const char *b); /// Does 'a' contain the string 'b' within it? bool OIIO_API contains (const std::string &a, const std::string &b); bool OIIO_API contains (const char *a, const char *b); /// Does 'a' contain the string 'b' within it, using a case-insensitive /// comparison? bool OIIO_API icontains (const std::string &a, const std::string &b); bool OIIO_API icontains (const char *a, const char *b); /// Convert to upper case, faster than std::toupper because we use /// a static locale that doesn't require a mutex lock. void OIIO_API to_lower (std::string &a); /// Convert to upper case, faster than std::toupper because we use /// a static locale that doesn't require a mutex lock. void OIIO_API to_upper (std::string &a); /// Return a copy of str with all consecutive characters in chars /// removed from the beginning and ending. If chars is empty, it will /// be interpreted as " \t\n\r\f\v" (whitespace). std::string OIIO_API strip (const std::string &str, const std::string &chars=std::string()); /// Fills the "result" list with the words in the string, using sep as /// the delimiter string. If maxsplit is > -1, at most maxsplit splits /// are done. If sep is "", any whitespace string is a separator. void OIIO_API split (const std::string &str, std::vector &result, const std::string &sep = "", int maxsplit = -1); /// Join all the strings in 'seq' into one big string, separated by the /// 'sep' string. std::string OIIO_API join (const std::vector &seq, const std::string &sep=""); // Helper template to convert from generic type to string template inline T from_string (const std::string &s) { return T(s); // Generic: assume there is an explicit converter } // Special case for int template<> inline int from_string (const std::string &s) { return strtol (s.c_str(), NULL, 10); } // Special case for float template<> inline float from_string (const std::string &s) { return (float)strtod (s.c_str(), NULL); } /// Given a string containing float values separated by a comma (or /// optionally another separator), extract the individual values, /// placing them into vals[] which is presumed to already contain /// defaults. If only a single value was in the list, replace all /// elements of vals[] with the value. Otherwise, replace them in the /// same order. A missing value will simply not be replaced. /// /// For example, if T=float, suppose initially, vals[] = {0, 1, 2}, then /// "3.14" results in vals[] = {3.14, 3.14, 3.14} /// "3.14,,-2.0" results in vals[] = {3.14, 1, -2.0} /// /// This can work for type T = int, float, or any type for that has /// an explicit constructor from a std::string. template void extract_from_list_string (std::vector &vals, const std::string &list, const std::string &sep = ",") { size_t nvals = vals.size(); std::vector valuestrings; Strutil::split (list, valuestrings, sep); for (size_t i = 0, e = valuestrings.size(); i < e; ++i) { if (valuestrings[i].size()) vals[i] = from_string (valuestrings[i]); } if (valuestrings.size() == 1) { vals.resize (1); vals.resize (nvals, vals[0]); } } /// C++ functor wrapper class for using strhash for unordered_map or /// unordered_set. The way this is used, in conjunction with /// StringEqual, to build an efficient hash map for char*'s or /// std::string's is as follows: /// \code /// boost::unordered_map /// \endcode class StringHash { public: size_t operator() (const char *s) const { return (size_t)Strutil::strhash(s); } size_t operator() (const std::string &s) const { return (size_t)Strutil::strhash(s.c_str()); } }; /// C++ functor class for comparing two char*'s or std::string's for /// equality of their strings. class StringEqual { public: bool operator() (const char *a, const char *b) const { return strcmp (a, b) == 0; } }; #ifdef _WIN32 /// Conversion functions between UTF-8 and UTF-16 for windows. /// /// For historical reasons, the standard encoding for strings on windows is /// UTF-16, whereas the unix world seems to have settled on UTF-8. These two /// encodings can be stored in std::string and std::wstring respectively, with /// the caveat that they're both variable-width encodings, so not all the /// standard string methods will make sense (for example std::string::size() /// won't return the number of glyphs in a UTF-8 string, unless it happens to /// be made up of only the 7-bit ASCII subset). /// /// The standard windows API functions usually have two versions, a UTF-16 /// version with a 'W' suffix (using wchar_t* strings), and an ANSI version /// with a 'A' suffix (using char* strings) which uses the current windows /// code page to define the encoding. (To make matters more confusing there is /// also a further "TCHAR" version which is #defined to the UTF-16 or ANSI /// version, depending on whether UNICODE is defined during compilation. /// This is meant to make it possible to support compiling libraries in /// either unicode or ansi mode from the same codebase.) /// /// Using std::string as the string container (as in OIIO) implies that we /// can't use UTF-16. It also means we need a variable-width encoding to /// represent characters in non-Latin alphabets in an unambiguous way; the /// obvious candidate is UTF-8. File paths in OIIO are considered to be /// represented in UTF-8, and must be converted to UTF-16 before passing to /// windows API file opening functions. /// On the other hand, the encoding used for the ANSI versions of the windows /// API is the current windows code page. This is more compatible with the /// default setup of the standard windows command prompt, and may be more /// appropriate for error messages. // Conversion to wide char // std::wstring OIIO_API utf8_to_utf16(const std::string& utf8str); // Conversion from wide char // std::string OIIO_API utf16_to_utf8(const std::wstring& utf16str); #endif /// Safe C string copy. Basically strncpy but ensuring that there's a /// terminating 0 character at the end of the resulting string. OIIO_API char * safe_strcpy (char *dst, const char *src, size_t size); inline char * safe_strcpy (char *dst, const std::string &src, size_t size) { return safe_strcpy (dst, src.length() ? src.c_str() : NULL, size); } } // namespace Strutil } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_STRUTIL_H openimageio-1.3.12~dfsg0.orig/src/include/pugiconfig.hpp0000644000175000017500000000527512271062644021407 0ustar mfvmfv/** * pugixml parser - version 1.2 * -------------------------------------------------------- * Copyright (C) 2006-2012, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end * of this file. * * This work is based on the pugxml parser, which is: * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) */ #ifndef HEADER_PUGICONFIG_HPP #define HEADER_PUGICONFIG_HPP // Uncomment this to enable wchar_t mode // #define PUGIXML_WCHAR_MODE // Uncomment this to disable XPath // #define PUGIXML_NO_XPATH // Uncomment this to disable STL // #define PUGIXML_NO_STL // Uncomment this to disable exceptions // #define PUGIXML_NO_EXCEPTIONS // Set this to control attributes for public classes/functions, i.e.: // #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL // #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL // #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall // In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead // OIIO: use already defined OIIO_API #include "export.h" #define PUGIXML_API OIIO_API // Uncomment this to switch to header-only version #define PUGIXML_HEADER_ONLY #include "pugixml.cpp" // Tune these constants to adjust memory-related behavior // #define PUGIXML_MEMORY_PAGE_SIZE 32768 // #define PUGIXML_MEMORY_OUTPUT_STACK 10240 // #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096 #endif /** * Copyright (c) 2006-2012 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ openimageio-1.3.12~dfsg0.orig/src/jpeg.imageio/0000755000175000017500000000000012271062644017446 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/jpeg.imageio/jpeginput.cpp0000644000175000017500000002430112271062644022157 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include extern "C" { #include "jpeglib.h" } #include "imageio.h" #include "filesystem.h" #include "fmath.h" #include "jpeg_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN // N.B. The class definition for JpgInput is in jpeg_pvt.h. // Export version number and create function symbols OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int jpeg_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *jpeg_input_imageio_create () { return new JpgInput; } OIIO_EXPORT const char *jpeg_input_extensions[] = { "jpg", "jpe", "jpeg", "jif", "jfif", ".jfi", NULL }; OIIO_PLUGIN_EXPORTS_END static const uint8_t JPEG_MAGIC1 = 0xff; static const uint8_t JPEG_MAGIC2 = 0xd8; // For explanations of the error handling, see the "example.c" in the // libjpeg distribution. static void my_error_exit (j_common_ptr cinfo) { /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ JpgInput::my_error_ptr myerr = (JpgInput::my_error_ptr) cinfo->err; /* Always display the message. */ /* We could postpone this until after returning, if we chose. */ // (*cinfo->err->output_message) (cinfo); myerr->jpginput->jpegerror (myerr, true); /* Return control to the setjmp point */ longjmp(myerr->setjmp_buffer, 1); } static void my_output_message (j_common_ptr cinfo) { JpgInput::my_error_ptr myerr = (JpgInput::my_error_ptr) cinfo->err; myerr->jpginput->jpegerror (myerr, true); } void JpgInput::jpegerror (my_error_ptr myerr, bool fatal) { // Send the error message to the ImageInput char errbuf[JMSG_LENGTH_MAX]; (*m_cinfo.err->format_message) ((j_common_ptr)&m_cinfo, errbuf); error ("JPEG error: %s (\"%s\")", errbuf, filename().c_str()); // Shut it down and clean it up if (fatal) { m_fatalerr = true; close (); m_fatalerr = true; // because close() will reset it } } bool JpgInput::valid_file (const std::string &filename) const { FILE *fd = Filesystem::fopen (filename, "rb"); if (! fd) return false; // Check magic number to assure this is a JPEG file uint8_t magic[2] = {0, 0}; bool ok = (fread (magic, sizeof(magic), 1, fd) == 1); fclose (fd); if (magic[0] != JPEG_MAGIC1 || magic[1] != JPEG_MAGIC2) { ok = false; } return ok; } bool JpgInput::open (const std::string &name, ImageSpec &newspec, const ImageSpec &config) { const ImageIOParameter *p = config.find_attribute ("_jpeg:raw", TypeDesc::TypeInt); m_raw = p && *(int *)p->data(); return open (name, newspec); } bool JpgInput::open (const std::string &name, ImageSpec &newspec) { // Check that file exists and can be opened m_filename = name; m_fd = Filesystem::fopen (name, "rb"); if (m_fd == NULL) { error ("Could not open file \"%s\"", name.c_str()); return false; } // Check magic number to assure this is a JPEG file uint8_t magic[2] = {0, 0}; if (fread (magic, sizeof(magic), 1, m_fd) != 1) { error ("Empty file \"%s\"", name.c_str()); close_file (); return false; } rewind (m_fd); if (magic[0] != JPEG_MAGIC1 || magic[1] != JPEG_MAGIC2) { close_file (); error ("\"%s\" is not a JPEG file, magic number doesn't match (was 0x%x)", name.c_str(), magic); return false; } // Set up the normal JPEG error routines, then override error_exit and // output_message so we intercept all the errors. m_cinfo.err = jpeg_std_error ((jpeg_error_mgr *)&m_jerr); m_jerr.pub.error_exit = my_error_exit; m_jerr.pub.output_message = my_output_message; if (setjmp (m_jerr.setjmp_buffer)) { // Jump to here if there's a libjpeg internal error // Prevent memory leaks, see example.c in jpeg distribution jpeg_destroy_decompress (&m_cinfo); close_file (); return false; } jpeg_create_decompress (&m_cinfo); // initialize decompressor jpeg_stdio_src (&m_cinfo, m_fd); // specify the data source // Request saving of EXIF and other special tags for later spelunking for (int mark = 0; mark < 16; ++mark) jpeg_save_markers (&m_cinfo, JPEG_APP0+mark, 0xffff); jpeg_save_markers (&m_cinfo, JPEG_COM, 0xffff); // comment marker // read the file parameters if (jpeg_read_header (&m_cinfo, FALSE) != JPEG_HEADER_OK || m_fatalerr) { error ("Bad JPEG header for \"%s\"", filename().c_str()); return false; } if (m_raw) m_coeffs = jpeg_read_coefficients (&m_cinfo); else jpeg_start_decompress (&m_cinfo); // start working if (m_fatalerr) return false; m_next_scanline = 0; // next scanline we'll read m_spec = ImageSpec (m_cinfo.output_width, m_cinfo.output_height, m_cinfo.output_components, TypeDesc::UINT8); // Assume JPEG is in sRGB unless the Exif or XMP tags say otherwise. m_spec.attribute ("oiio:ColorSpace", "sRGB"); for (jpeg_saved_marker_ptr m = m_cinfo.marker_list; m; m = m->next) { if (m->marker == (JPEG_APP0+1) && ! strcmp ((const char *)m->data, "Exif")) { // The block starts with "Exif\0\0", so skip 6 bytes to get // to the start of the actual Exif data TIFF directory decode_exif ((unsigned char *)m->data+6, m->data_length-6, m_spec); } else if (m->marker == (JPEG_APP0+1) && ! strcmp ((const char *)m->data, "http://ns.adobe.com/xap/1.0/")) { #ifndef NDEBUG std::cerr << "Found APP1 XMP! length " << m->data_length << "\n"; #endif std::string xml ((const char *)m->data, m->data_length); decode_xmp (xml, m_spec); } else if (m->marker == (JPEG_APP0+13) && ! strcmp ((const char *)m->data, "Photoshop 3.0")) jpeg_decode_iptc ((unsigned char *)m->data); else if (m->marker == JPEG_COM) { if (! m_spec.find_attribute ("ImageDescription", TypeDesc::STRING)) m_spec.attribute ("ImageDescription", std::string ((const char *)m->data)); } } newspec = m_spec; return true; } bool JpgInput::read_native_scanline (int y, int z, void *data) { if (m_raw) return false; if (y < 0 || y >= (int)m_cinfo.output_height) // out of range scanline return false; if (m_next_scanline > y) { // User is trying to read an earlier scanline than the one we're // up to. Easy fix: close the file and re-open. ImageSpec dummyspec; int subimage = current_subimage(); if (! close () || ! open (m_filename, dummyspec) || ! seek_subimage (subimage, 0, dummyspec)) return false; // Somehow, the re-open failed assert (m_next_scanline == 0 && current_subimage() == subimage); } // Set up our custom error handler if (setjmp (m_jerr.setjmp_buffer)) { // Jump to here if there's a libjpeg internal error return false; } for ( ; m_next_scanline <= y; ++m_next_scanline) { // Keep reading until we've read the scanline we really need if (jpeg_read_scanlines (&m_cinfo, (JSAMPLE **)&data, 1) != 1 || m_fatalerr) { error ("JPEG failed scanline read (\"%s\")", filename().c_str()); return false; } } return true; } bool JpgInput::close () { if (m_fd != NULL) { // unnecessary? jpeg_abort_decompress (&m_cinfo); jpeg_destroy_decompress (&m_cinfo); close_file (); } init (); // Reset to initial state return true; } void JpgInput::jpeg_decode_iptc (const unsigned char *buf) { // APP13 blob doesn't have to be IPTC info. Look for the IPTC marker, // which is the string "Photoshop 3.0" followed by a null character. if (strcmp ((const char *)buf, "Photoshop 3.0")) return; buf += strlen("Photoshop 3.0") + 1; // Next are the 4 bytes "8BIM" if (strncmp ((const char *)buf, "8BIM", 4)) return; buf += 4; // Next two bytes are the segment type, in big endian. // We expect 1028 to indicate IPTC data block. if (((buf[0] << 8) + buf[1]) != 1028) return; buf += 2; // Next are 4 bytes of 0 padding, just skip it. buf += 4; // Next is 2 byte (big endian) giving the size of the segment int segmentsize = (buf[0] << 8) + buf[1]; buf += 2; decode_iptc_iim (buf, segmentsize, m_spec); } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/jpeg.imageio/jpegoutput.cpp0000644000175000017500000003111212271062644022356 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include extern "C" { #include "jpeglib.h" } #include "imageio.h" #include "filesystem.h" #include "fmath.h" #include "jpeg_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN #define DBG if(0) // See JPEG library documentation in /usr/share/doc/libjpeg-devel-6b class JpgOutput : public ImageOutput { public: JpgOutput () { init(); } virtual ~JpgOutput () { close(); } virtual const char * format_name (void) const { return "jpeg"; } virtual bool supports (const std::string &property) const { return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); virtual bool close (); virtual bool copy_image (ImageInput *in); private: FILE *m_fd; std::string m_filename; int m_next_scanline; // Which scanline is the next to write? std::vector m_scratch; struct jpeg_compress_struct m_cinfo; struct jpeg_error_mgr c_jerr; jvirt_barray_ptr *m_copy_coeffs; struct jpeg_decompress_struct *m_copy_decompressor; void init (void) { m_fd = NULL; m_copy_coeffs = NULL; m_copy_decompressor = NULL; } }; OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *jpeg_output_imageio_create () { return new JpgOutput; } OIIO_EXPORT const char *jpeg_output_extensions[] = { "jpg", "jpe", "jpeg", "jif", "jfif", "jfi", NULL }; OIIO_PLUGIN_EXPORTS_END bool JpgOutput::open (const std::string &name, const ImageSpec &newspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; } // Save name and spec for later use m_filename = name; m_spec = newspec; // Check for things this format doesn't support if (m_spec.width < 1 || m_spec.height < 1) { error ("Image resolution must be at least 1x1, you asked for %d x %d", m_spec.width, m_spec.height); return false; } if (m_spec.depth < 1) m_spec.depth = 1; if (m_spec.depth > 1) { error ("%s does not support volume images (depth > 1)", format_name()); return false; } if (m_spec.nchannels != 1 && m_spec.nchannels != 3 && m_spec.nchannels != 4) { error ("%s does not support %d-channel images\n", format_name(), m_spec.nchannels); return false; } m_fd = Filesystem::fopen (name, "wb"); if (m_fd == NULL) { error ("Unable to open file \"%s\"", name.c_str()); return false; } int quality = 98; const ImageIOParameter *qual = newspec.find_attribute ("CompressionQuality", TypeDesc::INT); if (qual) quality = * (const int *)qual->data(); m_cinfo.err = jpeg_std_error (&c_jerr); // set error handler jpeg_create_compress (&m_cinfo); // create compressor jpeg_stdio_dest (&m_cinfo, m_fd); // set output stream // Set image and compression parameters m_cinfo.image_width = m_spec.width; m_cinfo.image_height = m_spec.height; if (m_spec.nchannels == 3 || m_spec.nchannels == 4) { m_cinfo.input_components = 3; m_cinfo.in_color_space = JCS_RGB; } else if (m_spec.nchannels == 1) { m_cinfo.input_components = 1; m_cinfo.in_color_space = JCS_GRAYSCALE; } m_cinfo.density_unit = 2; // RESUNIT_INCH; m_cinfo.X_density = 72; m_cinfo.Y_density = 72; m_cinfo.write_JFIF_header = TRUE; if (m_copy_coeffs) { // Back door for copy() jpeg_copy_critical_parameters (m_copy_decompressor, &m_cinfo); DBG std::cout << "out open: copy_critical_parameters\n"; jpeg_write_coefficients (&m_cinfo, m_copy_coeffs); DBG std::cout << "out open: write_coefficients\n"; } else { // normal write of scanlines jpeg_set_defaults (&m_cinfo); // default compression DBG std::cout << "out open: set_defaults\n"; jpeg_set_quality (&m_cinfo, quality, TRUE); // baseline values DBG std::cout << "out open: set_quality\n"; jpeg_start_compress (&m_cinfo, TRUE); // start working DBG std::cout << "out open: start_compress\n"; } m_next_scanline = 0; // next scanline we'll write // Write JPEG comment, if sent an 'ImageDescription' ImageIOParameter *comment = m_spec.find_attribute ("ImageDescription", TypeDesc::STRING); if (comment && comment->data()) { const char **c = (const char **) comment->data(); jpeg_write_marker (&m_cinfo, JPEG_COM, (JOCTET*)*c, strlen(*c) + 1); } if (Strutil::iequals (m_spec.get_string_attribute ("oiio:ColorSpace"), "sRGB")) m_spec.attribute ("Exif:ColorSpace", 1); // Write EXIF info std::vector exif; // Start the blob with "Exif" and two nulls. That's how it // always is in the JPEG files I've examined. exif.push_back ('E'); exif.push_back ('x'); exif.push_back ('i'); exif.push_back ('f'); exif.push_back (0); exif.push_back (0); encode_exif (m_spec, exif); jpeg_write_marker (&m_cinfo, JPEG_APP0+1, (JOCTET*)&exif[0], exif.size()); // Write IPTC IIM metadata tags, if we have anything std::vector iptc; encode_iptc_iim (m_spec, iptc); if (iptc.size()) { static char photoshop[] = "Photoshop 3.0"; std::vector head (photoshop, photoshop+strlen(photoshop)+1); static char _8BIM[] = "8BIM"; head.insert (head.end(), _8BIM, _8BIM+4); head.push_back (4); // 0x0404 head.push_back (4); head.push_back (0); // four bytes of zeroes head.push_back (0); head.push_back (0); head.push_back (0); head.push_back ((char)(iptc.size() >> 8)); // size of block head.push_back ((char)(iptc.size() & 0xff)); iptc.insert (iptc.begin(), head.begin(), head.end()); jpeg_write_marker (&m_cinfo, JPEG_APP0+13, (JOCTET*)&iptc[0], iptc.size()); } // Write XMP packet, if we have anything std::string xmp = encode_xmp (m_spec, true); if (! xmp.empty()) { static char prefix[] = "http://ns.adobe.com/xap/1.0/"; std::vector block (prefix, prefix+strlen(prefix)+1); block.insert (block.end(), xmp.c_str(), xmp.c_str()+xmp.length()); jpeg_write_marker (&m_cinfo, JPEG_APP0+1, (JOCTET*)&block[0], block.size()); } m_spec.set_format (TypeDesc::UINT8); // JPG is only 8 bit return true; } bool JpgOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { y -= m_spec.y; if (y != m_next_scanline) { error ("Attempt to write scanlines out of order to %s", m_filename.c_str()); return false; } if (y >= (int)m_cinfo.image_height) { error ("Attempt to write too many scanlines to %s", m_filename.c_str()); return false; } assert (y == (int)m_cinfo.next_scanline); // It's so common to want to write RGBA data out as JPEG (which only // supports RGB) than it would be too frustrating to reject it. // Instead, we just silently drop the alpha. Here's where we do the // dirty work, temporarily doctoring the spec so that // to_native_scanline properly contiguizes the first three channels, // then we restore it. The call to to_native_scanline below needs // m_spec.nchannels to be set to the true number of channels we're // writing, or it won't arrange the data properly. But if we // doctored m_spec.nchannels = 3 permanently, then subsequent calls // to write_scanline (including any surrounding call to write_image) // with stride=AutoStride would screw up the strides since the // user's stride is actually not 3 channels. int save_nchannels = m_spec.nchannels; m_spec.nchannels = m_cinfo.input_components; data = to_native_scanline (format, data, xstride, m_scratch); m_spec.nchannels = save_nchannels; jpeg_write_scanlines (&m_cinfo, (JSAMPLE**)&data, 1); ++m_next_scanline; return true; } bool JpgOutput::close () { if (! m_fd) // Already closed return true; if (m_next_scanline < spec().height && m_copy_coeffs == NULL) { // But if we've only written some scanlines, write the rest to avoid // errors std::vector buf (spec().scanline_bytes(), 0); char *data = &buf[0]; while (m_next_scanline < spec().height) { jpeg_write_scanlines (&m_cinfo, (JSAMPLE **)&data, 1); // DBG std::cout << "out close: write_scanlines\n"; ++m_next_scanline; } } if (m_next_scanline >= spec().height || m_copy_coeffs) { DBG std::cout << "out close: about to finish_compress\n"; jpeg_finish_compress (&m_cinfo); DBG std::cout << "out close: finish_compress\n"; } else { DBG std::cout << "out close: about to abort_compress\n"; jpeg_abort_compress (&m_cinfo); DBG std::cout << "out close: abort_compress\n"; } DBG std::cout << "out close: about to destroy_compress\n"; jpeg_destroy_compress (&m_cinfo); fclose (m_fd); m_fd = NULL; init(); return true; } bool JpgOutput::copy_image (ImageInput *in) { if (in && !strcmp(in->format_name(), "jpeg")) { JpgInput *jpg_in = dynamic_cast (in); std::string in_name = jpg_in->filename (); DBG std::cout << "JPG copy_image from " << in_name << "\n"; // Save the original input spec and close it ImageSpec orig_in_spec = in->spec(); in->close (); DBG std::cout << "Closed old file\n"; // Re-open the input spec, with special request that the JpgInput // will recognize as a request to merely open, but not start the // decompressor. ImageSpec in_spec; ImageSpec config_spec; config_spec.attribute ("_jpeg:raw", 1); in->open (in_name, in_spec, config_spec); // Re-open the output std::string out_name = m_filename; ImageSpec orig_out_spec = spec(); close (); m_copy_coeffs = (jvirt_barray_ptr *)jpg_in->coeffs(); m_copy_decompressor = &jpg_in->m_cinfo; open (out_name, orig_out_spec); // Strangeness -- the write_coefficients somehow sets things up // so that certain writes only happen in close(), which MUST // happen while the input file is still open. So we go ahead // and close() now, so that the caller of copy_image() doesn't // close the input file first and then wonder why they crashed. close (); return true; } return ImageOutput::copy_image (in); } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/jpeg.imageio/jpeg_pvt.h0000644000175000017500000001032412271062644021435 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////////// // Private definitions internal to the jpeg.imageio plugin ///////////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_JPEG_PVT_H #define OPENIMAGEIO_JPEG_PVT_H #include extern "C" { #include "jpeglib.h" } OIIO_PLUGIN_NAMESPACE_BEGIN class JpgInput : public ImageInput { public: JpgInput () { init(); } virtual ~JpgInput () { close(); } virtual const char * format_name (void) const { return "jpeg"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &spec); virtual bool open (const std::string &name, ImageSpec &spec, const ImageSpec &config); virtual bool seek_subimage (int index, int miplevel, ImageSpec &newspec) { return (index == 0 && miplevel == 0); // JPEG has only one subimage } virtual bool read_native_scanline (int y, int z, void *data); virtual bool close (); const std::string &filename () const { return m_filename; } void * coeffs () const { return m_coeffs; } struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ JpgInput *jpginput; /* back pointer to *this */ }; typedef struct my_error_mgr * my_error_ptr; // Called by my_error_exit void jpegerror (my_error_ptr myerr, bool fatal=false); private: FILE *m_fd; std::string m_filename; int m_next_scanline; // Which scanline is the next to read? bool m_raw; // Read raw coefficients, not scanlines bool m_fatalerr; // JPEG reader hit a fatal error struct jpeg_decompress_struct m_cinfo; my_error_mgr m_jerr; jvirt_barray_ptr *m_coeffs; void init () { m_fd = NULL; m_raw = false; m_fatalerr = false; m_coeffs = NULL; m_jerr.jpginput = this; } // Rummage through the JPEG "APP1" marker pointed to by buf, decoding // IPTC (International Press Telecommunications Council) metadata // information and adding attributes to spec. This assumes it's in // the form of an IIM (Information Interchange Model), which is actually // considered obsolete and is replaced by an XML scheme called XMP. void jpeg_decode_iptc (const unsigned char *buf); void close_file () { if (m_fd) fclose (m_fd); // N.B. the init() will set m_fd to NULL init (); } friend class JpgOutput; }; OIIO_PLUGIN_NAMESPACE_END #endif /* OPENIMAGEIO_JPEG_PVT_H */ openimageio-1.3.12~dfsg0.orig/src/jpeg.imageio/CMakeLists.txt0000644000175000017500000000041112271062644022202 0ustar mfvmfvfind_package (JPEG) find_package (TIFF) if (JPEG_FOUND AND TIFF_FOUND) include_directories (${TIFF_INCLUDE_DIR}) include_directories (${JPEG_INCLUDE_DIR}) add_oiio_plugin (jpeginput.cpp jpegoutput.cpp LINK_LIBRARIES ${JPEG_LIBRARIES}) endif () openimageio-1.3.12~dfsg0.orig/src/idiff/0000755000175000017500000000000012271062644016171 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/idiff/idiff.cpp0000644000175000017500000003454012271062644017764 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include "dassert.h" #include "argparse.h" #include "imageio.h" #include "imagecache.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "filesystem.h" #ifdef __APPLE__ using std::isinf; using std::isnan; #endif OIIO_NAMESPACE_USING enum idiffErrors { ErrOK = 0, ///< No errors, the images match exactly ErrWarn, ///< Warning: the errors differ a little ErrFail, ///< Failure: the errors differ a lot ErrDifferentSize, ///< Images aren't even the same size ErrFile, ///< Could not find or open input files, etc. ErrLast }; static bool verbose = false; static bool outdiffonly = false; static std::string diffimage; static float diffscale = 1.0; static bool diffabs = false; static float warnthresh = 1.0e-6f; static float warnpercent = 0; static float hardwarn = std::numeric_limits::max(); static float failthresh = 1.0e-6f; static float failpercent = 0; static bool perceptual = false; static float hardfail = std::numeric_limits::max(); static std::vector filenames; //static bool comparemeta = false; static bool compareall = false; static int parse_files (int argc, const char *argv[]) { for (int i = 0; i < argc; i++) filenames.push_back (argv[i]); return 0; } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap; ap.options ("idiff -- compare two images\n" OIIO_INTRO_STRING "\n" "Usage: idiff [options] image1 image2", "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose status messages", "-a", &compareall, "Compare all subimages/miplevels", "", "Thresholding and comparison options", "-fail %g", &failthresh, "Failure threshold difference (0.000001)", "-failpercent %g", &failpercent, "Allow this percentage of failures (0)", "-hardfail %g", &hardfail, "Fail if any one pixel exceeds this error (infinity)", "-warn %g", &warnthresh, "Warning threshold difference (0.00001)", "-warnpercent %g", &warnpercent, "Allow this percentage of warnings (0)", "-hardwarn %g", &hardwarn, "Warn if any one pixel exceeds this error (infinity)", "-p", &perceptual, "Perform perceptual (rather than numeric) comparison", "", "Difference image options", "-o %s", &diffimage, "Output difference image", "-od", &outdiffonly, "Output image only if nonzero difference", "-abs", &diffabs, "Output image of absolute value, not signed difference", "-scale %g", &diffscale, "Scale the output image by this factor", // "-meta", &comparemeta, "Compare metadata", NULL); if (ap.parse(argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } if (filenames.size() != 2) { std::cerr << "idiff: Must have two input filenames.\n"; ap.usage(); exit (EXIT_FAILURE); } } static bool read_input (const std::string &filename, ImageBuf &img, ImageCache *cache, int subimage=0, int miplevel=0) { if (img.subimage() >= 0 && img.subimage() == subimage && img.miplevel() == miplevel) return true; img.reset (filename, cache); if (img.read (subimage, miplevel, false, TypeDesc::TypeFloat)) return true; std::cerr << "idiff ERROR: Could not read " << filename << ":\n\t" << img.geterror() << "\n"; return false; } // function that standarize printing NaN and Inf values on // Windows (where they are in 1.#INF, 1.#NAN format) and all // others platform inline void safe_double_print (double val) { if (isnan (val)) std::cout << "nan"; else if (isinf (val)) std::cout << "inf"; else std::cout << val; std::cout << '\n'; } inline void print_subimage (ImageBuf &img0, int subimage, int miplevel) { if (img0.nsubimages() > 1) std::cout << "Subimage " << subimage << ' '; if (img0.nmiplevels() > 1) std::cout << " MIP level " << miplevel << ' '; if (img0.nsubimages() > 1 || img0.nmiplevels() > 1) std::cout << ": "; std::cout << img0.spec().width << " x " << img0.spec().height; if (img0.spec().depth > 1) std::cout << " x " << img0.spec().depth; std::cout << ", " << img0.spec().nchannels << " channel\n"; } int main (int argc, char *argv[]) { Filesystem::convert_native_arguments (argc, (const char **)argv); getargs (argc, argv); std::cout << "Comparing \"" << filenames[0] << "\" and \"" << filenames[1] << "\"\n"; // Create a private ImageCache so we can customize its cache size // and instruct it store everything internally as floats. ImageCache *imagecache = ImageCache::create (true); imagecache->attribute ("forcefloat", 1); if (sizeof(void *) == 4) // 32 bit or 64? imagecache->attribute ("max_memory_MB", 512.0); else imagecache->attribute ("max_memory_MB", 2048.0); imagecache->attribute ("autotile", 256); // force a full diff, even for files tagged with the same // fingerprint, just in case some mistake has been made. imagecache->attribute ("deduplicate", 0); ImageBuf img0, img1; if (! read_input (filenames[0], img0, imagecache) || ! read_input (filenames[1], img1, imagecache)) return ErrFile; // ImageSpec spec0 = img0.spec(); // stash it int ret = ErrOK; for (int subimage = 0; subimage < img0.nsubimages(); ++subimage) { if (subimage > 0 && !compareall) break; if (subimage >= img1.nsubimages()) break; if (! read_input (filenames[0], img0, imagecache, subimage) || ! read_input (filenames[1], img1, imagecache, subimage)) { std::cout << "Failed to read subimage " << subimage << "\n"; return ErrFile; } if (img0.nmiplevels() != img1.nmiplevels()) { std::cout << "Files do not match in their number of MIPmap levels\n"; } for (int m = 0; m < img0.nmiplevels(); ++m) { if (m > 0 && !compareall) break; if (m > 0 && img0.nmiplevels() != img1.nmiplevels()) { std::cout << "Files do not match in their number of MIPmap levels\n"; ret = ErrDifferentSize; break; } if (! read_input (filenames[0], img0, imagecache, subimage, m) || ! read_input (filenames[1], img1, imagecache, subimage, m)) return ErrFile; if (img0.deep() != img1.deep()) { std::cout << "One image contains deep data, the other does not\n"; ret = ErrDifferentSize; break; } int npels = img0.spec().width * img0.spec().height * img0.spec().depth; if (npels == 0) npels = 1; // Avoid divide by zero for 0x0 images ASSERT (img0.spec().format == TypeDesc::FLOAT); // Compare the two images. // ImageBufAlgo::CompareResults cr; ImageBufAlgo::compare (img0, img1, failthresh, warnthresh, cr); int yee_failures = 0; if (perceptual && ! img0.deep()) { ImageBufAlgo::CompareResults cr; yee_failures = ImageBufAlgo::compare_Yee (img0, img1, cr); } if (cr.nfail > (failpercent/100.0 * npels) || cr.maxerror > hardfail || yee_failures > (failpercent/100.0 * npels)) { ret = ErrFail; } else if (cr.nwarn > (warnpercent/100.0 * npels) || cr.maxerror > hardwarn) { if (ret != ErrFail) ret = ErrWarn; } // Print the report // if (verbose || ret != ErrOK) { if (compareall) print_subimage (img0, subimage, m); std::cout << " Mean error = "; safe_double_print (cr.meanerror); std::cout << " RMS error = "; safe_double_print (cr.rms_error); std::cout << " Peak SNR = "; safe_double_print (cr.PSNR); std::cout << " Max error = " << cr.maxerror; if (cr.maxerror != 0) { std::cout << " @ (" << cr.maxx << ", " << cr.maxy; if (img0.spec().depth > 1) std::cout << ", " << cr.maxz; if (cr.maxc < (int)img0.spec().channelnames.size()) std::cout << ", " << img0.spec().channelnames[cr.maxc] << ')'; else if (cr.maxc < (int)img1.spec().channelnames.size()) std::cout << ", " << img1.spec().channelnames[cr.maxc] << ')'; else std::cout << ", channel " << cr.maxc << ')'; } std::cout << "\n"; // when Visual Studio is used float values in scientific foramt are // printed with three digit exponent. We change this behaviour to fit // Linux way #ifdef _MSC_VER _set_output_format(_TWO_DIGIT_EXPONENT); #endif std::streamsize precis = std::cout.precision(); std::cout << " " << cr.nwarn << " pixels (" << std::setprecision(3) << (100.0*cr.nwarn / npels) << std::setprecision(precis) << "%) over " << warnthresh << "\n"; std::cout << " " << cr.nfail << " pixels (" << std::setprecision(3) << (100.0*cr.nfail / npels) << std::setprecision(precis) << "%) over " << failthresh << "\n"; if (perceptual) std::cout << " " << yee_failures << " pixels (" << std::setprecision(3) << (100.0*yee_failures / npels) << std::setprecision(precis) << "%) failed the perceptual test\n"; } // If the user requested that a difference image be output, // do that. N.B. we only do this for the first subimage // right now, because ImageBuf doesn't really know how to // write subimages. if (diffimage.size() && (cr.maxerror != 0 || !outdiffonly)) { ImageBuf diff (img0.spec()); ImageBuf::ConstIterator pix0 (img0); ImageBuf::ConstIterator pix1 (img1); ImageBuf::Iterator pixdiff (diff); // Subtract the second image from the first. At which // time we no longer need the second image, so free it. if (diffabs) { for ( ; pix0.valid(); ++pix0) { pix1.pos (pix0.x(), pix0.y()); // ensure alignment pixdiff.pos (pix0.x(), pix0.y()); for (int c = 0; c < img0.nchannels(); ++c) pixdiff[c] = diffscale * fabsf (pix0[c] - pix1[c]); } } else { for ( ; pix0.valid(); ++pix0) { pix1.pos (pix0.x(), pix0.y()); // ensure alignment pixdiff.pos (pix0.x(), pix0.y()); for (int c = 0; c < img0.spec().nchannels; ++c) pixdiff[c] = diffscale * (pix0[c] - pix1[c]); } } diff.write (diffimage); // Clear diff image name so we only save the first // non-matching subimage. diffimage = ""; } } } if (compareall && img0.nsubimages() != img1.nsubimages()) { std::cout << "Images had differing numbers of subimages (" << img0.nsubimages() << " vs " << img1.nsubimages() << ")\n"; ret = ErrFail; } if (!compareall && (img0.nsubimages() > 1 || img1.nsubimages() > 1)) { std::cout << "Only compared the first subimage (of " << img0.nsubimages() << " and " << img1.nsubimages() << ", respectively)\n"; } if (ret == ErrOK) std::cout << "PASS\n"; else if (ret == ErrWarn) std::cout << "WARNING\n"; else std::cout << "FAILURE\n"; imagecache->invalidate_all (true); ImageCache::destroy (imagecache); return ret; } openimageio-1.3.12~dfsg0.orig/src/idiff/CMakeLists.txt0000644000175000017500000000037012271062644020731 0ustar mfvmfvset (idiff_srcs idiff.cpp) add_executable (idiff ${idiff_srcs}) set_target_properties (idiff PROPERTIES FOLDER "Tools") link_ilmbase (idiff) target_link_libraries (idiff OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) oiio_install_targets (idiff) openimageio-1.3.12~dfsg0.orig/src/libtexture/0000755000175000017500000000000012271062644017277 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/libtexture/texturesys.cpp0000644000175000017500000022734512271062644022257 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "varyingref.h" #include "ustring.h" #include "strutil.h" #include "sysutil.h" #include "thread.h" #include "fmath.h" #include "filter.h" #include "optparser.h" #include "imageio.h" #include "texture.h" #include "imagecache.h" #include "imagecache_pvt.h" #include "texture_pvt.h" #include "imagebuf.h" #include "imagebufalgo.h" #include OIIO_NAMESPACE_ENTER { using namespace pvt; namespace { // anonymous static EightBitConverter uchar2float; } // end anonymous namespace TextureSystem * TextureSystem::create (bool shared) { ImageCache *ic = ImageCache::create (shared); return new TextureSystemImpl (ic); } void TextureSystem::destroy (TextureSystem *x, bool teardown_imagecache) { if (! x) return; TextureSystemImpl *impl = (TextureSystemImpl *) x; if (teardown_imagecache) { ImageCache::destroy (impl->m_imagecache, true); impl->m_imagecache = NULL; } delete (TextureSystemImpl *) impl; } void TextureSystem::destroy (TextureSystem *x) { destroy (x, false); } namespace pvt { // namespace pvt // Wrap functions wrap 'coord' around 'width', and return true if the // result is a valid pixel coordinate, false if black should be used // instead. bool TextureSystemImpl::wrap_periodic_sharedborder (int &coord, int origin, int width) { // Like periodic, but knowing that the first column and last are // actually the same position, so we essentially skip the last // column in the next cycle. if (width <= 2) { coord = origin; // special case -- just 1 pixel wide } else { coord -= origin; coord %= (width-1); if (coord < 0) // Fix negative values coord += width; coord += origin; } return true; } const wrap_impl TextureSystemImpl::wrap_functions[] = { // Must be in same order as Wrap enum wrap_black, wrap_black, wrap_clamp, wrap_periodic, wrap_mirror }; const char * texture_format_name (TexFormat f) { static const char * texture_format_names[] = { // MUST match the order of TexFormat "unknown", "Plain Texture", "Volume Texture", "Shadow", "CubeFace Shadow", "Volume Shadow", "LatLong Environment", "CubeFace Environment", "" }; return texture_format_names[(int)f]; } const char * texture_type_name (TexFormat f) { static const char * texture_type_names[] = { // MUST match the order of TexFormat "unknown", "Plain Texture", "Volume Texture", "Shadow", "Shadow", "Shadow", "Environment", "Environment", "" }; return texture_type_names[(int)f]; } TextureSystemImpl::TextureSystemImpl (ImageCache *imagecache) : hq_filter(NULL) { m_imagecache = (ImageCacheImpl *) imagecache; init (); } void TextureSystemImpl::init () { m_Mw2c.makeIdentity(); m_gray_to_rgb = false; delete hq_filter; hq_filter = Filter1D::create ("b-spline", 4); m_statslevel = 0; // Allow environment variable to override default options const char *options = getenv ("OPENIMAGEIO_TEXTURE_OPTIONS"); if (options) attribute ("options", options); #if 0 unit_test_texture (); #endif } TextureSystemImpl::~TextureSystemImpl () { printstats (); ImageCache::destroy (m_imagecache); m_imagecache = NULL; delete hq_filter; } std::string TextureSystemImpl::getstats (int level, bool icstats) const { // Merge all the threads ImageCacheStatistics stats; m_imagecache->mergestats (stats); std::ostringstream out; bool anytexture = (stats.texture_queries + stats.texture3d_queries + stats.shadow_queries + stats.environment_queries); if (level > 0 && anytexture) { out << "OpenImageIO Texture statistics\n"; out << " Queries/batches : \n"; out << " texture : " << stats.texture_queries << " queries in " << stats.texture_batches << " batches\n"; out << " texture 3d : " << stats.texture3d_queries << " queries in " << stats.texture3d_batches << " batches\n"; out << " shadow : " << stats.shadow_queries << " queries in " << stats.shadow_batches << " batches\n"; out << " environment : " << stats.environment_queries << " queries in " << stats.environment_batches << " batches\n"; out << " Interpolations :\n"; out << " closest : " << stats.closest_interps << "\n"; out << " bilinear : " << stats.bilinear_interps << "\n"; out << " bicubic : " << stats.cubic_interps << "\n"; if (stats.aniso_queries) out << Strutil::format (" Average anisotropic probes : %.3g\n", (double)stats.aniso_probes/(double)stats.aniso_queries); else out << Strutil::format (" Average anisotropic probes : 0\n"); out << Strutil::format (" Max anisotropy in the wild : %.3g\n", stats.max_aniso); if (icstats) out << "\n"; } if (icstats) out << m_imagecache->getstats (level); return out.str(); } void TextureSystemImpl::printstats () const { if (m_statslevel == 0) return; std::cout << getstats (m_statslevel, false) << "\n\n"; } void TextureSystemImpl::reset_stats () { ASSERT (m_imagecache); m_imagecache->reset_stats (); } bool TextureSystemImpl::attribute (const std::string &name, TypeDesc type, const void *val) { if (name == "options" && type == TypeDesc::STRING) { return optparser (*this, *(const char **)val); } if (name == "worldtocommon" && (type == TypeDesc::TypeMatrix || type == TypeDesc(TypeDesc::FLOAT,16))) { m_Mw2c = *(const Imath::M44f *)val; m_Mc2w = m_Mw2c.inverse(); return true; } if (name == "commontoworld" && (type == TypeDesc::TypeMatrix || type == TypeDesc(TypeDesc::FLOAT,16))) { m_Mc2w = *(const Imath::M44f *)val; m_Mw2c = m_Mc2w.inverse(); return true; } if ((name == "gray_to_rgb" || name == "grey_to_rgb") && (type == TypeDesc::TypeInt)) { m_gray_to_rgb = *(const int *)val; return true; } if (name == "statistics:level" && type == TypeDesc::TypeInt) { m_statslevel = *(const int *)val; // DO NOT RETURN! pass the same message to the image cache } // Maybe it's meant for the cache? return m_imagecache->attribute (name, type, val); } bool TextureSystemImpl::getattribute (const std::string &name, TypeDesc type, void *val) { if (name == "worldtocommon" && (type == TypeDesc::TypeMatrix || type == TypeDesc(TypeDesc::FLOAT,16))) { *(Imath::M44f *)val = m_Mw2c; return true; } if (name == "commontoworld" && (type == TypeDesc::TypeMatrix || type == TypeDesc(TypeDesc::FLOAT,16))) { *(Imath::M44f *)val = m_Mc2w; return true; } if ((name == "gray_to_rgb" || name == "grey_to_rgb") && (type == TypeDesc::TypeInt)) { *(int *)val = m_gray_to_rgb; return true; } // If not one of these, maybe it's an attribute meant for the image cache? return m_imagecache->getattribute (name, type, val); return false; } std::string TextureSystemImpl::resolve_filename (const std::string &filename) const { return m_imagecache->resolve_filename (filename); } bool TextureSystemImpl::get_texture_info (ustring filename, int subimage, ustring dataname, TypeDesc datatype, void *data) { bool ok = m_imagecache->get_image_info (filename, subimage, 0, dataname, datatype, data); if (! ok) error ("%s", m_imagecache->geterror().c_str()); return ok; } bool TextureSystemImpl::get_imagespec (ustring filename, int subimage, ImageSpec &spec) { bool ok = m_imagecache->get_imagespec (filename, spec, subimage); if (! ok) error ("%s", m_imagecache->geterror().c_str()); return ok; } const ImageSpec * TextureSystemImpl::imagespec (ustring filename, int subimage) { const ImageSpec *spec = m_imagecache->imagespec (filename, subimage); if (! spec) error ("%s", m_imagecache->geterror().c_str()); return spec; } bool TextureSystemImpl::get_texels (ustring filename, TextureOpt &options, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result) { PerThreadInfo *thread_info = m_imagecache->get_perthread_info (); TextureFile *texfile = find_texturefile (filename, thread_info); if (! texfile) { error ("Texture file \"%s\" not found", filename.c_str()); return false; } if (texfile->broken()) { error ("Invalid texture file \"%s\"", filename.c_str()); return false; } int subimage = options.subimage; if (subimage < 0 || subimage >= texfile->subimages()) { error ("get_texel asked for nonexistant subimage %d of \"%s\"", subimage, filename.c_str()); return false; } if (miplevel < 0 || miplevel >= texfile->miplevels(subimage)) { error ("get_texel asked for nonexistant MIP level %d of \"%s\"", miplevel, filename.c_str()); return false; } const ImageSpec &spec (texfile->spec(subimage, miplevel)); // FIXME -- this could be WAY more efficient than starting from // scratch for each pixel within the rectangle. Instead, we should // grab a whole tile at a time and memcpy it rapidly. But no point // doing anything more complicated (not to mention bug-prone) until // somebody reports this routine as being a bottleneck. int actualchannels = Imath::clamp (spec.nchannels - options.firstchannel, 0, options.nchannels); int nc = spec.nchannels; size_t formatpixelsize = nc * format.size(); size_t scanlinesize = (xend-xbegin) * formatpixelsize; size_t zplanesize = (yend-ybegin) * scanlinesize; bool ok = true; for (int z = zbegin; z < zend; ++z) { if (z < spec.z || z >= (spec.z+std::max(spec.depth,1))) { // nonexistant planes memset (result, 0, zplanesize); result = (void *) ((char *) result + zplanesize); continue; } int tz = z - ((z - spec.z) % std::max (1, spec.tile_depth)); for (int y = ybegin; y < yend; ++y) { if (y < spec.y || y >= (spec.y+spec.height)) { // nonexistant scanlines memset (result, 0, scanlinesize); result = (void *) ((char *) result + scanlinesize); continue; } int ty = y - ((y - spec.y) % spec.tile_height); for (int x = xbegin; x < xend; ++x) { if (x < spec.x || x >= (spec.x+spec.width)) { // nonexistant columns memset (result, 0, formatpixelsize); result = (void *) ((char *) result + formatpixelsize); continue; } int tx = x - ((x - spec.x) % spec.tile_width); TileID tileid (*texfile, subimage, miplevel, tx, ty, tz); ok &= find_tile (tileid, thread_info); TileRef &tile (thread_info->tile); const char *data; if (tile && (data = (const char *)tile->data (x, y, z))) { data += options.firstchannel * texfile->datatype(subimage).size(); convert_types (texfile->datatype(subimage), data, format, result, actualchannels); for (int c = actualchannels; c < options.nchannels; ++c) convert_types (TypeDesc::FLOAT, &options.fill, format, result, 1); } else { memset (result, 0, formatpixelsize); } result = (void *) ((char *) result + formatpixelsize); } } } if (! ok) error ("%s", m_imagecache->geterror().c_str()); return ok; } std::string TextureSystemImpl::geterror () const { std::string e; std::string *errptr = m_errormessage.get (); if (errptr) { e = *errptr; errptr->clear (); } return e; } void TextureSystemImpl::append_error (const std::string& message) const { std::string *errptr = m_errormessage.get (); if (! errptr) { errptr = new std::string; m_errormessage.reset (errptr); } ASSERT (errptr != NULL); ASSERT (errptr->size() < 1024*1024*16 && "Accumulated error messages > 16MB. Try checking return codes!"); if (errptr->size()) *errptr += '\n'; *errptr += message; } // Implementation of invalidate -- just invalidate the image cache. void TextureSystemImpl::invalidate (ustring filename) { m_imagecache->invalidate (filename); } // Implementation of invalidate -- just invalidate the image cache. void TextureSystemImpl::invalidate_all (bool force) { m_imagecache->invalidate_all (force); } bool TextureSystemImpl::missing_texture (TextureOpt &options, float *result) { for (int c = 0; c < options.nchannels; ++c) { if (options.missingcolor) result[c] = options.missingcolor[c]; else result[c] = options.fill; if (options.dresultds) options.dresultds[c] = 0; if (options.dresultdt) options.dresultdt[c] = 0; if (options.dresultdr) options.dresultdr[c] = 0; } if (options.missingcolor) { // don't treat it as an error if missingcolor was supplied (void) geterror (); // eat the error return true; } else { return false; } } void TextureSystemImpl::fill_gray_channels (const ImageSpec &spec, TextureOpt &options, float *result) { if (! m_gray_to_rgb || options.firstchannel != 0) return; // never mind // Multi-channel texture reads from single channel files will // propagate their grayscale value to G and B (no alpha) bool propagate = (spec.nchannels == 1 && options.nchannels >= 3); // When reading monochrome images with alpha into a 4 // channel result, move the alpha to the last position (CCCA) if (spec.nchannels == 2 && spec.alpha_channel == 1 && options.nchannels == 4) { result[3] = result[1]; if (options.dresultds) options.dresultds[3] = options.dresultds[1]; if (options.dresultdt) options.dresultdt[3] = options.dresultdt[1]; if (options.dresultdr) options.dresultdr[3] = options.dresultdr[1]; // And we will propagate monochrome to G and B propagate = true; } // Propagate to G and B if needed if (propagate) { result[1] = result[0]; result[2] = result[0]; if (options.dresultds) { options.dresultds[1] = options.dresultds[0]; options.dresultds[2] = options.dresultds[0]; } if (options.dresultdt) { options.dresultdt[1] = options.dresultdt[0]; options.dresultdt[2] = options.dresultdt[0]; } if (options.dresultdr) { options.dresultdr[1] = options.dresultdr[0]; options.dresultdr[2] = options.dresultdr[0]; } } } bool TextureSystemImpl::texture (ustring filename, TextureOpt &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) { PerThreadInfo *thread_info = m_imagecache->get_perthread_info (); TextureFile *texturefile = find_texturefile (filename, thread_info); return texture ((TextureHandle *)texturefile, (Perthread *)thread_info, options, s, t, dsdx, dtdx, dsdy, dtdy, result); } bool TextureSystemImpl::texture (TextureHandle *texture_handle_, Perthread *thread_info_, TextureOpt &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) { static const texture_lookup_prototype lookup_functions[] = { // Must be in the same order as Mipmode enum &TextureSystemImpl::texture_lookup, &TextureSystemImpl::texture_lookup_nomip, &TextureSystemImpl::texture_lookup_trilinear_mipmap, &TextureSystemImpl::texture_lookup_trilinear_mipmap, &TextureSystemImpl::texture_lookup }; texture_lookup_prototype lookup = lookup_functions[(int)options.mipmode]; PerThreadInfo *thread_info = (PerThreadInfo *)thread_info_; TextureFile *texturefile = (TextureFile *)texture_handle_; ImageCacheStatistics &stats (thread_info->m_stats); ++stats.texture_batches; ++stats.texture_queries; if (! texturefile || texturefile->broken()) return missing_texture (options, result); if (options.subimagename) { // If subimage was specified by name, figure out its index. int s = m_imagecache->subimage_from_name (texturefile, options.subimagename); if (s < 0) { error ("Unknown subimage \"%s\" in texture \"%s\"", options.subimagename.c_str(), texturefile->filename().c_str()); return false; } options.subimage = s; options.subimagename.clear(); } const ImageCacheFile::SubimageInfo &subinfo (texturefile->subimageinfo(options.subimage)); const ImageSpec &spec (texturefile->spec(options.subimage, 0)); if (! subinfo.full_pixel_range) { // remap st for overscan or crop s = s * subinfo.sscale + subinfo.soffset; dsdx *= subinfo.sscale; dsdy *= subinfo.sscale; t = t * subinfo.tscale + subinfo.toffset; dtdx *= subinfo.tscale; dtdy *= subinfo.tscale; } // Figure out the wrap functions if (options.swrap == TextureOpt::WrapDefault) options.swrap = (TextureOpt::Wrap)texturefile->swrap(); if (options.swrap == TextureOpt::WrapPeriodic && ispow2(spec.width)) options.swrap_func = wrap_periodic_pow2; else options.swrap_func = wrap_functions[(int)options.swrap]; if (options.twrap == TextureOpt::WrapDefault) options.twrap = (TextureOpt::Wrap)texturefile->twrap(); if (options.twrap == TextureOpt::WrapPeriodic && ispow2(spec.height)) options.twrap_func = wrap_periodic_pow2; else options.twrap_func = wrap_functions[(int)options.twrap]; int actualchannels = Imath::clamp (spec.nchannels - options.firstchannel, 0, options.nchannels); options.actualchannels = actualchannels; bool ok = (this->*lookup) (*texturefile, thread_info, options, s, t, dsdx, dtdx, dsdy, dtdy, result); if (actualchannels < options.nchannels) fill_gray_channels (spec, options, result); return ok; } bool TextureSystemImpl::texture (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef s, VaryingRef t, VaryingRef dsdx, VaryingRef dtdx, VaryingRef dsdy, VaryingRef dtdy, float *result) { Perthread *thread_info = get_perthread_info(); TextureHandle *texture_handle = get_texture_handle (filename, thread_info); if (! texture_handle) return false; bool ok = true; for (int i = beginactive; i < endactive; ++i) { if (runflags[i]) { TextureOpt opt (options, i); ok &= texture (texture_handle, thread_info, opt, s[i], t[i], dsdx[i], dtdx[i], dsdy[i], dtdy[i], result+i*options.nchannels); } } return ok; } bool TextureSystemImpl::texture_lookup_nomip (TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) { // Initialize results to 0. We'll add from here on as we sample. for (int c = 0; c < options.nchannels; ++c) result[c] = 0; float* dresultds = options.dresultds; float* dresultdt = options.dresultdt; if (dresultds) for (int c = 0; c < options.nchannels; ++c) dresultds[c] = 0; if (dresultdt) for (int c = 0; c < options.nchannels; ++c) dresultdt[c] = 0; // If the user only provided us with one pointer, clear both to simplify // the rest of the code, but only after we zero out the data for them so // they know something went wrong. if (!(dresultds && dresultdt)) dresultds = dresultdt = NULL; static const accum_prototype accum_functions[] = { // Must be in the same order as InterpMode enum &TextureSystemImpl::accum_sample_closest, &TextureSystemImpl::accum_sample_bilinear, &TextureSystemImpl::accum_sample_bicubic, &TextureSystemImpl::accum_sample_bilinear, }; accum_prototype accumer = accum_functions[(int)options.interpmode]; bool ok = (this->*accumer) (s, t, 0, texturefile, thread_info, options, 1.0f, result, dresultds, dresultdt); // Update stats ImageCacheStatistics &stats (thread_info->m_stats); ++stats.aniso_queries; ++stats.aniso_probes; switch (options.interpmode) { case TextureOpt::InterpClosest : ++stats.closest_interps; break; case TextureOpt::InterpBilinear : ++stats.bilinear_interps; break; case TextureOpt::InterpBicubic : ++stats.cubic_interps; break; case TextureOpt::InterpSmartBicubic : ++stats.bilinear_interps; break; } return ok; } // Scale the derivs as dictated by 'width' and 'blur', and also make sure // they are all some minimum value to make the subsequent math clean. inline void adjust_width (float &dsdx, float &dtdx, float &dsdy, float &dtdy, float swidth, float twidth) { // Trust user not to use nonsensical width<0 dsdx *= swidth; dtdx *= twidth; dsdy *= swidth; dtdy *= twidth; // Clamp degenerate derivatives so they don't cause mathematical problems static const float eps = 1.0e-8f, eps2 = eps*eps; float dxlen2 = dsdx*dsdx + dtdx*dtdx; float dylen2 = dsdy*dsdy + dtdy*dtdy; if (dxlen2 < eps2) { // Tiny dx if (dylen2 < eps2) { // Tiny dx and dy: Essentially point sampling. Substitute a // tiny but finite filter. dsdx = eps; dsdy = 0; dtdx = 0; dtdy = eps; dxlen2 = dylen2 = eps2; } else { // Tiny dx, sane dy -- pick a small dx orthogonal to dy, but // of length eps. float scale = eps / sqrtf(dylen2); dsdx = dtdy * scale; dtdx = -dsdy * scale; dxlen2 = eps2; } } else if (dylen2 < eps2) { // Tiny dy, sane dx -- pick a small dy orthogonal to dx, but of // length eps. float scale = eps / sqrtf(dxlen2); dsdy = -dtdx * scale; dtdy = dsdx * scale; dylen2 = eps2; } } // Adjust the ellipse major and minor axes based on the blur, if nonzero. // Trust user not to use nonsensical blur<0 inline void adjust_blur (float &majorlength, float &minorlength, float theta, float sblur, float tblur) { if (sblur+tblur != 0.0f /* avoid the work when blur is zero */) { // Carefully add blur to the right derivative components in the // right proportions -- merely adding the same amount of blur // to all four derivatives blurs too much at some angles. // FIXME -- we should benchmark whether a fast approximate rsqrt // here could have any detectable performance improvement. DASSERT (majorlength > 0.0f && minorlength > 0.0f); float sintheta, costheta; sincos (theta, &sintheta, &costheta); sintheta = fabsf(sintheta); costheta = fabsf(costheta); majorlength += sblur * costheta + tblur * sintheta; minorlength += sblur * sintheta + tblur * costheta; } } // For the given texture file, options, and ellipse major and minor // lengths and aspect ratio, compute the two MIPmap levels and // respective weights to use for a texture lookup. The general strategy // is that we choose the MIPmap level so that the minor axis length is // pixel-sized (and then we will sample several times along the major // axis in order to handle anisotropy), but we make adjustments in // corner cases where the ideal sampling is too high or too low resolution // given the MIPmap levels we have available. inline void compute_miplevels (TextureSystemImpl::TextureFile &texturefile, TextureOpt &options, float majorlength, float minorlength, float &aspect, int *miplevel, float *levelweight) { ImageCacheFile::SubimageInfo &subinfo (texturefile.subimageinfo(options.subimage)); float levelblend = 0.0f; int nmiplevels = (int)subinfo.levels.size(); for (int m = 0; m < nmiplevels; ++m) { // Compute the filter size (minor axis) in raster space at this // MIP level. We use the smaller of the two texture resolutions, // which is better than just using one, but a more principled // approach is desired but remains elusive. FIXME. float filtwidth_ras = minorlength * std::min (subinfo.spec(m).width, subinfo.spec(m).height); // Once the filter width is smaller than one texel at this level, // we've gone too far, so we know that we want to interpolate the // previous level and the current level. Note that filtwidth_ras // is expected to be >= 0.5, or would have stopped one level ago. if (filtwidth_ras <= 1.0f) { miplevel[0] = m-1; miplevel[1] = m; levelblend = Imath::clamp (2.0f - 1.0f/filtwidth_ras, 0.0f, 1.0f); break; } } if (miplevel[1] < 0) { // We'd like to blur even more, but make due with the coarsest // MIP level. miplevel[0] = nmiplevels - 1; miplevel[1] = miplevel[0]; levelblend = 0; } else if (miplevel[0] < 0) { // We wish we had even more resolution than the finest MIP level, // but tough for us. miplevel[0] = 0; miplevel[1] = 0; levelblend = 0; // It's possible that minorlength is degenerate, giving an aspect // ratio that implies a huge nsamples, which is pointless if those // samples are too close. So if minorlength is less than 1/2 texel // at the finest resolution, clamp it and recalculate aspect. int r = std::max (subinfo.spec(0).full_width, subinfo.spec(0).full_height); if (minorlength*r < 0.5f) { aspect = Imath::clamp (majorlength * r * 2.0f, 1.0f, float(options.anisotropic)); } } if (options.mipmode == TextureOpt::MipModeOneLevel) { miplevel[0] = miplevel[1]; levelblend = 0; } levelweight[0] = 1.0f - levelblend; levelweight[1] = levelblend; } bool TextureSystemImpl::texture_lookup_trilinear_mipmap (TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float _s, float _t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) { // Initialize results to 0. We'll add from here on as we sample. for (int c = 0; c < options.nchannels; ++c) result[c] = 0; float* dresultds = options.dresultds; float* dresultdt = options.dresultdt; if (dresultds) for (int c = 0; c < options.nchannels; ++c) dresultds[c] = 0; if (dresultdt) for (int c = 0; c < options.nchannels; ++c) dresultdt[c] = 0; // If the user only provided us with one pointer, clear both to simplify // the rest of the code, but only after we zero out the data for them so // they know something went wrong. if (!(dresultds && dresultdt)) dresultds = dresultdt = NULL; adjust_width (dsdx, dtdx, dsdy, dtdy, options.swidth, options.twidth); // Determine the MIP-map level(s) we need: we will blend // data(miplevel[0]) * (1-levelblend) + data(miplevel[1]) * levelblend int miplevel[2] = { -1, -1 }; float levelweight[2] = { 0, 0 }; float sfilt = std::max (fabsf(dsdx), fabsf(dsdy)); float tfilt = std::max (fabsf(dtdx), fabsf(dtdy)); float filtwidth = options.conservative_filter ? std::max (sfilt, tfilt) : std::min (sfilt, tfilt); // account for blur filtwidth += std::max (options.sblur, options.tblur); float aspect = 1.0f; compute_miplevels (texturefile, options, filtwidth, filtwidth, aspect, miplevel, levelweight); static const accum_prototype accum_functions[] = { // Must be in the same order as InterpMode enum &TextureSystemImpl::accum_sample_closest, &TextureSystemImpl::accum_sample_bilinear, &TextureSystemImpl::accum_sample_bicubic, &TextureSystemImpl::accum_sample_bilinear, }; accum_prototype accumer = accum_functions[(int)options.interpmode]; // if (level == 0 || texturefile.spec(lev).height < naturalres/2) // accumer = &TextureSystemImpl::accum_sample_bicubic; // FIXME -- support for smart cubic? bool ok = true; int npointson = 0; for (int level = 0; level < 2; ++level) { if (! levelweight[level]) // No contribution from this level, skip it continue; ok &= (this->*accumer) (_s, _t, miplevel[level], texturefile, thread_info, options, levelweight[level], result, dresultds, dresultdt); ++npointson; } // Update stats ImageCacheStatistics &stats (thread_info->m_stats); stats.aniso_queries += npointson; stats.aniso_probes += npointson; switch (options.interpmode) { case TextureOpt::InterpClosest : stats.closest_interps += npointson; break; case TextureOpt::InterpBilinear : stats.bilinear_interps += npointson; break; case TextureOpt::InterpBicubic : stats.cubic_interps += npointson; break; case TextureOpt::InterpSmartBicubic : stats.bilinear_interps += npointson; break; } return ok; } // Given pixel derivatives, calculate major and minor axis lengths and // major axis orientation angle of the ellipse. See Greene's EWA paper // or Mavridis (2011). If ABCF is non-NULL, it should point to space // for 4 floats, which will be used to store the ellipse parameters A, // B, C, F. inline void ellipse_axes (float dsdx, float dtdx, float dsdy, float dtdy, float &majorlength, float &minorlength, float &theta, float *ABCF = NULL) { float dsdx2 = dsdx*dsdx; float dtdx2 = dtdx*dtdx; float dsdy2 = dsdy*dsdy; float dtdy2 = dtdy*dtdy; double A = dtdx2 + dtdy2; double B = -2.0 * (dsdx * dtdx + dsdy * dtdy); double C = dsdx2 + dsdy2; double root = hypot (A-C, B); // equivalent: sqrt (A*A - 2AC + C*C + B*B) double Aprime = (A + C - root) * 0.5; double Cprime = (A + C + root) * 0.5; #if 0 double F = A*C - B*B*0.25; majorlength = std::min(safe_sqrtf (F / Aprime), 1000.0f); minorlength = std::min(safe_sqrtf (F / Cprime), 1000.0f); #else // Wolfram says that this is equivalent to: majorlength = std::min (safe_sqrtf(Cprime), 1000.0f); minorlength = std::min (safe_sqrtf(Aprime), 1000.0f); #endif theta = atan2 (B, A-C) * 0.5 + M_PI_2; if (ABCF) { // Optionally store the ellipse equation parameters, the ellipse // is given by: A*u^2 + B*u*v + C*v^2 < 1 double F = A*C - B*B*0.25; double Finv = 1.0f / F; ABCF[0] = A * Finv; ABCF[1] = B * Finv; ABCF[2] = C * Finv; ABCF[3] = F; } // N.B. If the derivs passed in are the full pixel-to-pixel // derivatives, then majorlength/minorlength are the (diameter) axes // of the ellipse; if the derivs are the "to edge of pixel" 1/2 // length derivs, then majorlength/minorlength are the major and // minur radii of the elipse. We do the former! So it's important // to consider that factor of 2 in compute_ellipse_sampling. } // Given the aspect ratio, major axis orientation angle, and axis lengths, // calculate the smajor & tmajor values that give the orientation of the // line on which samples should be distributed. If there are n samples, // they should be positioned as: // p_i = 2*(i+0.5)/n - 1.0; // sample_i = (s + p_i*smajor, t + p_i*tmajor) inline int compute_ellipse_sampling (float aspect, float theta, float majorlength, float minorlength, float &smajor, float &tmajor, float &invsamples, float *weights=NULL) { // Compute the sin and cos of the sampling direction, given major // axis angle sincos (theta, &tmajor, &smajor); float L = 2.0f * (majorlength - minorlength); smajor *= L; tmajor *= L; #if 1 // This is the theoretically correct number of samples. int nsamples = std::max (1, int(2.0f*aspect-1.0f)); #else int nsamples = std::max (1, (int) ceilf (aspect - 0.3f)); // This approach does fewer samples for high aspect ratios, but I see // artifacts. #endif invsamples = 1.0f / nsamples; if (weights) { if (nsamples == 1) { weights[0] = 1.0f; } else if (nsamples == 2) { weights[0] = 0.5f; weights[1] = 0.5f; } else { float scale = majorlength / L; // 1/(L/major) for (int i = 0, e = (nsamples+1)/2; i < e; ++i) { float x = (2.0f*(i+0.5f)*invsamples - 1.0f) * scale; float w = expf(-2.0f*x*x); weights[nsamples-i-1] = weights[i] = w; } } } return nsamples; } bool TextureSystemImpl::texture_lookup (TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) { // Initialize results to 0. We'll add from here on as we sample. for (int c = 0; c < options.nchannels; ++c) result[c] = 0; float* dresultds = options.dresultds; float* dresultdt = options.dresultdt; if (dresultds) for (int c = 0; c < options.nchannels; ++c) dresultds[c] = 0; if (dresultdt) for (int c = 0; c < options.nchannels; ++c) dresultdt[c] = 0; // If the user only provided us with one pointer, clear both to simplify // the rest of the code, but only after we zero out the data for them so // they know something went wrong. if (!(dresultds && dresultdt)) dresultds = dresultdt = NULL; // Compute the natural resolution we want for the bare derivs, this // will be the threshold for knowing we're maxifying (and therefore // wanting cubic interpolation). float sfilt_noblur = std::max (std::max (fabsf(dsdx), fabsf(dsdy)), 1e-8f); float tfilt_noblur = std::max (std::max (fabsf(dtdx), fabsf(dtdy)), 1e-8f); int naturalsres = (int) (1.0f / sfilt_noblur); int naturaltres = (int) (1.0f / tfilt_noblur); // Scale by 'width' adjust_width (dsdx, dtdx, dsdy, dtdy, options.swidth, options.twidth); // Determine the MIP-map level(s) we need: we will blend // data(miplevel[0]) * (1-levelblend) + data(miplevel[1]) * levelblend float smajor, tmajor; float majorlength, minorlength; float theta; // Do a bit more math and get the exact ellipse axis lengths, and // therefore a more accurate aspect ratio as well. Looks much MUCH // better, but for scenes with lots of grazing angles, it can greatly // increase the average anisotropy, therefore the number of bilinear // or bicubic texture probes, and therefore runtime! // FIXME -- come back and improve performance to compensate. ellipse_axes (dsdx, dtdx, dsdy, dtdy, majorlength, minorlength, theta); adjust_blur (majorlength, minorlength, theta, options.sblur, options.tblur); float aspect, trueaspect; aspect = anisotropic_aspect (majorlength, minorlength, options, trueaspect); int miplevel[2] = { -1, -1 }; float levelweight[2] = { 0, 0 }; compute_miplevels (texturefile, options, majorlength, minorlength, aspect, miplevel, levelweight); float *lineweight = ALLOCA (float, 2*options.anisotropic); float invsamples; int nsamples = compute_ellipse_sampling (aspect, theta, majorlength, minorlength, smajor, tmajor, invsamples, lineweight); // All the computations were done assuming full diametric axes of // the ellipse, but our derivatives are pixel-to-pixel, yielding // semi-major and semi-minor lengths, so we need to scale everything // by 1/2. smajor *= 0.5f; tmajor *= 0.5f; bool ok = true; int npointson = 0; int closestprobes = 0, bilinearprobes = 0, bicubicprobes = 0; float sumw = 0; for (int level = 0; level < 2; ++level) { if (! levelweight[level]) // No contribution from this level, skip it continue; ++npointson; int lev = miplevel[level]; accum_prototype accumer = &TextureSystemImpl::accum_sample_bilinear; switch (options.interpmode) { case TextureOpt::InterpClosest : accumer = &TextureSystemImpl::accum_sample_closest; ++closestprobes; break; case TextureOpt::InterpBilinear : accumer = &TextureSystemImpl::accum_sample_bilinear; ++bilinearprobes; break; case TextureOpt::InterpBicubic : accumer = &TextureSystemImpl::accum_sample_bicubic; ++bicubicprobes; break; case TextureOpt::InterpSmartBicubic : if (lev == 0 || (texturefile.spec(options.subimage,lev).width < naturalsres/2) || (texturefile.spec(options.subimage,lev).height < naturaltres/2)) { accumer = &TextureSystemImpl::accum_sample_bicubic; ++bicubicprobes; } else { accumer = &TextureSystemImpl::accum_sample_bilinear; ++bilinearprobes; } break; } for (int sample = 0; sample < nsamples; ++sample) { float pos = 2.0f * ((sample + 0.5f) * invsamples - 0.5f); float w = levelweight[level] * lineweight[sample]; ok &= (this->*accumer) (s + pos * smajor, t + pos * tmajor, lev, texturefile, thread_info, options, w, result, dresultds, dresultdt); sumw += w; } } if (sumw > 0) { for (int c = 0; c < options.nchannels; ++c) { result[c] /= sumw; if (dresultds) dresultds[c] /= sumw; if (dresultdt) dresultdt[c] /= sumw; } } // Update stats ImageCacheStatistics &stats (thread_info->m_stats); stats.aniso_queries += npointson; stats.aniso_probes += npointson * nsamples; if (trueaspect > stats.max_aniso) stats.max_aniso = trueaspect; // FIXME? stats.closest_interps += closestprobes * nsamples; stats.bilinear_interps += bilinearprobes * nsamples; stats.cubic_interps += bicubicprobes * nsamples; return ok; } const float * TextureSystemImpl::pole_color (TextureFile &texturefile, PerThreadInfo *thread_info, const ImageCacheFile::LevelInfo &levelinfo, TileRef &tile, int subimage, int miplevel, int pole) { if (! levelinfo.onetile) return NULL; // Only compute color for one-tile MIP levels const ImageSpec &spec (levelinfo.spec); size_t pixelsize = texturefile.pixelsize(subimage); bool eightbit = texturefile.eightbit(subimage); if (! levelinfo.polecolorcomputed) { static spin_mutex mutex; // Protect everybody's polecolor spin_lock lock (mutex); if (! levelinfo.polecolorcomputed) { DASSERT (levelinfo.polecolor.size() == 0); levelinfo.polecolor.resize (2*spec.nchannels); // We store north and south poles adjacently in polecolor float *p = &(levelinfo.polecolor[0]); size_t width = spec.width; float scale = 1.0f / width; for (int pole = 0; pole <= 1; ++pole, p += spec.nchannels) { int y = pole * (spec.height-1); // 0 or height-1 for (int c = 0; c < spec.nchannels; ++c) p[c] = 0.0f; const unsigned char *texel = tile->bytedata() + y*spec.tile_width*pixelsize; for (size_t i = 0; i < width; ++i, texel += pixelsize) for (int c = 0; c < spec.nchannels; ++c) if (eightbit) p[c] += uchar2float(texel[c]); else p[c] += ((const float *)texel)[c]; for (int c = 0; c < spec.nchannels; ++c) p[c] *= scale; } levelinfo.polecolorcomputed = true; } } return &(levelinfo.polecolor[pole*spec.nchannels]); } void TextureSystemImpl::fade_to_pole (float t, float *accum, float &weight, TextureFile &texturefile, PerThreadInfo *thread_info, const ImageCacheFile::LevelInfo &levelinfo, TextureOpt &options, int miplevel, int nchannels) { // N.B. We want to fade to pole colors right at texture // boundaries t==0 and t==height, but at the very top of this // function, we subtracted another 0.5 from t, so we need to // undo that here. float pole; const float *polecolor; if (t < 1.0f) { pole = (1.0f - t); polecolor = pole_color (texturefile, thread_info, levelinfo, thread_info->tile, options.subimage, miplevel, 0); } else { pole = t - floorf(t); polecolor = pole_color (texturefile, thread_info, levelinfo, thread_info->tile, options.subimage, miplevel, 1); } pole = Imath::clamp (pole, 0.0f, 1.0f); pole *= pole; // squaring makes more pleasing appearance polecolor += options.firstchannel; for (int c = 0; c < nchannels; ++c) accum[c] += weight * pole * polecolor[c]; weight *= 1.0f - pole; } bool TextureSystemImpl::accum_sample_closest (float s, float t, int miplevel, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt) { const ImageSpec &spec (texturefile.spec (options.subimage, miplevel)); const ImageCacheFile::LevelInfo &levelinfo (texturefile.levelinfo(options.subimage,miplevel)); int stex, ttex; // Texel coordintes float sfrac, tfrac; st_to_texel (s, t, texturefile, spec, stex, ttex, sfrac, tfrac); if (sfrac > 0.5f) ++stex; if (tfrac > 0.5f) ++ttex; // Wrap DASSERT (options.swrap_func != NULL && options.twrap_func != NULL); bool svalid, tvalid; // Valid texels? false means black border svalid = options.swrap_func (stex, spec.x, spec.width); tvalid = options.twrap_func (ttex, spec.y, spec.height); if (! levelinfo.full_pixel_range) { svalid &= (stex >= spec.x && stex < (spec.x+spec.width)); // data window tvalid &= (ttex >= spec.y && ttex < (spec.y+spec.height)); } if (! (svalid & tvalid)) { // All texels we need were out of range and using 'black' wrap. return true; } int tile_s = (stex - spec.x) % spec.tile_width; int tile_t = (ttex - spec.y) % spec.tile_height; TileID id (texturefile, options.subimage, miplevel, stex - tile_s, ttex - tile_t, 0); bool ok = find_tile (id, thread_info); if (! ok) error ("%s", m_imagecache->geterror().c_str()); TileRef &tile (thread_info->tile); if (! tile || ! ok) return false; size_t channelsize = texturefile.channelsize(options.subimage); int offset = spec.nchannels * (tile_t * spec.tile_width + tile_s) + options.firstchannel; DASSERT ((size_t)offset < spec.nchannels*spec.tile_pixels()); if (channelsize == 1) { // special case for 8-bit tiles const unsigned char *texel = tile->bytedata() + offset; for (int c = 0; c < options.actualchannels; ++c) accum[c] += weight * uchar2float(texel[c]); } else { // General case for float tiles const float *texel = tile->data() + offset; for (int c = 0; c < options.actualchannels; ++c) accum[c] += weight * texel[c]; } // Add appropriate amount of "fill" color to extra channels in // non-"black"-wrapped regions. if (options.nchannels > options.actualchannels && options.fill) { float f = weight * options.fill; for (int c = options.actualchannels; c < options.nchannels; ++c) accum[c] += f; } return true; } bool TextureSystemImpl::accum_sample_bilinear (float s, float t, int miplevel, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt) { const ImageSpec &spec (texturefile.spec (options.subimage, miplevel)); const ImageCacheFile::LevelInfo &levelinfo (texturefile.levelinfo(options.subimage,miplevel)); int sint, tint; float sfrac, tfrac; st_to_texel (s, t, texturefile, spec, sint, tint, sfrac, tfrac); // Wrap DASSERT (options.swrap_func != NULL && options.twrap_func != NULL); int stex[2], ttex[2]; // Texel coords stex[0] = sint; stex[1] = sint+1; ttex[0] = tint; ttex[1] = tint+1; // bool svalid[2], tvalid[2]; // Valid texels? false means black border union { bool bvalid[4]; unsigned int ivalid; } valid_storage; valid_storage.ivalid = 0; DASSERT (sizeof(valid_storage) == 4*sizeof(bool)); const unsigned int none_valid = 0; const unsigned int all_valid = 0x01010101; bool *svalid = valid_storage.bvalid; bool *tvalid = valid_storage.bvalid + 2; svalid[0] = options.swrap_func (stex[0], spec.x, spec.width); svalid[1] = options.swrap_func (stex[1], spec.x, spec.width); tvalid[0] = options.twrap_func (ttex[0], spec.y, spec.height); tvalid[1] = options.twrap_func (ttex[1], spec.y, spec.height); // FIXME -- we've got crop windows all wrong // Account for crop windows if (! levelinfo.full_pixel_range) { svalid[0] &= (stex[0] >= spec.x && stex[0] < spec.x+spec.width); svalid[1] &= (stex[1] >= spec.x && stex[1] < spec.x+spec.width); tvalid[0] &= (ttex[0] >= spec.y && ttex[0] < spec.y+spec.height); tvalid[1] &= (ttex[1] >= spec.y && ttex[1] < spec.y+spec.height); } // if (! (svalid[0] | svalid[1] | tvalid[0] | tvalid[1])) if (valid_storage.ivalid == none_valid) return true; // All texels we need were out of range and using 'black' wrap int tilewidthmask = spec.tile_width - 1; // e.g. 63 int tileheightmask = spec.tile_height - 1; const unsigned char *texel[2][2]; TileRef savetile[2][2]; static float black[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int tile_s = (stex[0] - spec.x) % spec.tile_width; int tile_t = (ttex[0] - spec.y) % spec.tile_height; bool s_onetile = (tile_s != tilewidthmask) & (stex[0]+1 == stex[1]); bool t_onetile = (tile_t != tileheightmask) & (ttex[0]+1 == ttex[1]); bool onetile = (s_onetile & t_onetile); size_t channelsize = texturefile.channelsize(options.subimage); size_t pixelsize = texturefile.pixelsize(options.subimage); if (onetile && // (svalid[0] & svalid[1] & tvalid[0] & tvalid[1])) { valid_storage.ivalid == all_valid) { // Shortcut if all the texels we need are on the same tile TileID id (texturefile, options.subimage, miplevel, stex[0] - tile_s, ttex[0] - tile_t, 0); bool ok = find_tile (id, thread_info); if (! ok) error ("%s", m_imagecache->geterror().c_str()); TileRef &tile (thread_info->tile); if (! tile->valid()) { #if 0 std::cerr << "found it\n"; std::cerr << "\trequested " << miplevel << ' ' << id.x() << ' ' << id.y() << ", res is " << texturefile.spec(miplevel).width << ' ' << texturefile.spec(miplevel).height << "\n"; std::cerr << "\tstex = " << stex[0] << ", tile_s = " << tile_s << ", ttex = " << ttex[0] << ", tile_t = " << tile_t << "\n"; std::cerr << "\torig " << orig_s << ' ' << orig_t << "\n"; std::cerr << "\ts,t = " << s << ' ' << t << "\n"; std::cerr << "\tsint,tint = " << sint << ' ' << tint << "\n"; std::cerr << "\tstfrac = " << sfrac << ' ' << tfrac << "\n"; std::cerr << "\tspec full size = " << texturefile.spec(miplevel).full_width << ' ' << texturefile.spec(miplevel).full_height << "\n"; #endif return false; } // N.B. thread_info->tile will keep holding a ref-counted pointer // to the tile for the duration that we're using the tile data. int offset = pixelsize * (tile_t * spec.tile_width + tile_s); texel[0][0] = tile->bytedata() + offset + channelsize * options.firstchannel; texel[0][1] = texel[0][0] + pixelsize; texel[1][0] = texel[0][0] + pixelsize * spec.tile_width; texel[1][1] = texel[1][0] + pixelsize; } else { for (int j = 0; j < 2; ++j) { for (int i = 0; i < 2; ++i) { if (! (svalid[i] && tvalid[j])) { texel[j][i] = (unsigned char *)black; continue; } tile_s = (stex[i] - spec.x) % spec.tile_width; tile_t = (ttex[j] - spec.y) % spec.tile_height; TileID id (texturefile, options.subimage, miplevel, stex[i] - tile_s, ttex[j] - tile_t, 0); bool ok = find_tile (id, thread_info); if (! ok) error ("%s", m_imagecache->geterror().c_str()); TileRef &tile (thread_info->tile); if (! tile->valid()) return false; savetile[j][i] = tile; int offset = pixelsize * (tile_t * spec.tile_width + tile_s); DASSERT ((size_t)offset < spec.tile_width*spec.tile_height*spec.tile_depth*pixelsize); texel[j][i] = tile->bytedata() + offset + channelsize * options.firstchannel; DASSERT (tile->id() == id); } } } // FIXME -- optimize the above loop by unrolling int nc = options.actualchannels; // When we're on the lowest res mipmap levels, it's more pleasing if // we converge to a single pole color right at the pole. Fade to // the average color over the texel height right next to the pole. if (options.envlayout == LayoutLatLong && levelinfo.onetile) { float height = spec.height; if (texturefile.m_sample_border) height -= 1.0f; float tt = t * height; if (tt < 1.0f || tt > (height-1.0f)) fade_to_pole (tt, accum, weight, texturefile, thread_info, levelinfo, options, miplevel, nc); } if (channelsize == 1) { // special case for 8-bit tiles int c; for (c = 0; c < nc; ++c) accum[c] += weight * bilerp (uchar2float(texel[0][0][c]), uchar2float(texel[0][1][c]), uchar2float(texel[1][0][c]), uchar2float(texel[1][1][c]), sfrac, tfrac); if (daccumds) { float scalex = weight * spec.width; float scaley = weight * spec.height; for (c = 0; c < nc; ++c) { daccumds[c] += scalex * Imath::lerp( uchar2float(texel[0][1][c]) - uchar2float(texel[0][0][c]), uchar2float(texel[1][1][c]) - uchar2float(texel[1][0][c]), tfrac ); daccumdt[c] += scaley * Imath::lerp( uchar2float(texel[1][0][c]) - uchar2float(texel[0][0][c]), uchar2float(texel[1][1][c]) - uchar2float(texel[0][1][c]), sfrac ); } } } else { // General case for float tiles bilerp_mad ((const float *)texel[0][0], (const float *)texel[0][1], (const float *)texel[1][0], (const float *)texel[1][1], sfrac, tfrac, weight, nc, accum); if (daccumds) { float scalex = weight * spec.width; float scaley = weight * spec.height; for (int c = 0; c < nc; ++c) { daccumds[c] += scalex * Imath::lerp( ((const float *) texel[0][1])[c] - ((const float *) texel[0][0])[c], ((const float *) texel[1][1])[c] - ((const float *) texel[1][0])[c], tfrac ); daccumdt[c] += scaley * Imath::lerp( ((const float *) texel[1][0])[c] - ((const float *) texel[0][0])[c], ((const float *) texel[1][1])[c] - ((const float *) texel[0][1])[c], sfrac ); } } } // Add appropriate amount of "fill" color to extra channels in // non-"black"-wrapped regions. if (options.nchannels > options.actualchannels && options.fill) { float f = bilerp (1.0f*svalid[0]*tvalid[0], 1.0f*svalid[1]*tvalid[0], 1.0f*svalid[0]*tvalid[1], 1.0f*svalid[1]*tvalid[1], sfrac, tfrac); f *= weight * options.fill; for (int c = options.actualchannels; c < options.nchannels; ++c) accum[c] += f; } return true; } namespace { template inline void evalBSplineWeights (T w[4], T fraction) { T one_frac = 1 - fraction; w[0] = T(1.0 / 6.0) * one_frac * one_frac * one_frac; w[1] = T(2.0 / 3.0) - T(0.5) * fraction * fraction * (2 - fraction); w[2] = T(2.0 / 3.0) - T(0.5) * one_frac * one_frac * (2 - one_frac); w[3] = T(1.0 / 6.0) * fraction * fraction * fraction; } template inline void evalBSplineWeightDerivs (T dw[4], T fraction) { T one_frac = 1 - fraction; dw[0] = -T(0.5) * one_frac * one_frac; dw[1] = T(0.5) * fraction * (3 * fraction - 4); dw[2] = -T(0.5) * one_frac * (3 * one_frac - 4); dw[3] = T(0.5) * fraction * fraction; } } // anonymous namesace bool TextureSystemImpl::accum_sample_bicubic (float s, float t, int miplevel, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt) { const ImageSpec &spec (texturefile.spec (options.subimage, miplevel)); const ImageCacheFile::LevelInfo &levelinfo (texturefile.levelinfo(options.subimage,miplevel)); int sint, tint; float sfrac, tfrac; st_to_texel (s, t, texturefile, spec, sint, tint, sfrac, tfrac); // We're gathering 4x4 samples and 4x weights. Indices: texels 0, // 1, 2, 3. The sample lies between samples 1 and 2. // Wrap DASSERT (options.swrap_func != NULL && options.twrap_func != NULL); bool svalid[4], tvalid[4]; // Valid texels? false means black border int stex[4], ttex[4]; // Texel coords bool allvalid = true; bool anyvalid = false; for (int i = 0; i < 4; ++i) { bool v; stex[i] = sint + i - 1; v = options.swrap_func (stex[i], spec.x, spec.width); svalid[i] = v; allvalid &= v; anyvalid |= v; ttex[i] = tint + i - 1; v = options.twrap_func (ttex[i], spec.y, spec.height); tvalid[i] = v; allvalid &= v; anyvalid |= v; } if (anyvalid && ! levelinfo.full_pixel_range) { // Handle case of crop windows or overscan anyvalid = false; for (int i = 0; i < 4; ++i) { bool v; v = (stex[i] >= spec.x && stex[i] < (spec.x+spec.width)); svalid[i] &= v; allvalid &= v; anyvalid |= v; v = (ttex[i] >= spec.y && ttex[i] < (spec.y+spec.height)); tvalid[i] &= v; allvalid &= v; anyvalid |= v; } } if (! anyvalid) { // All texels we need were out of range and using 'black' wrap. return true; } const unsigned char *texel[4][4] = { {NULL, NULL, NULL, NULL}, {NULL, NULL, NULL, NULL}, {NULL, NULL, NULL, NULL}, {NULL, NULL, NULL, NULL} }; TileRef savetile[4][4]; static float black[4] = { 0, 0, 0, 0 }; int tilewidthmask = spec.tile_width - 1; // e.g. 63 int tileheightmask = spec.tile_height - 1; int tile_s = (stex[0] - spec.x) % spec.tile_width; int tile_t = (ttex[0] - spec.y) % spec.tile_height; bool s_onetile = (tile_s <= tilewidthmask-3); bool t_onetile = (tile_t <= tileheightmask-3); if (s_onetile && t_onetile) { for (int i = 1; i < 4; ++i) { s_onetile &= (stex[i] == stex[0]+i); t_onetile &= (ttex[i] == ttex[0]+i); } } bool onetile = (s_onetile & t_onetile); size_t channelsize = texturefile.channelsize(options.subimage); size_t pixelsize = texturefile.pixelsize(options.subimage); if (onetile & allvalid) { // Shortcut if all the texels we need are on the same tile TileID id (texturefile, options.subimage, miplevel, stex[0] - tile_s, ttex[0] - tile_t, 0); bool ok = find_tile (id, thread_info); if (! ok) error ("%s", m_imagecache->geterror().c_str()); TileRef &tile (thread_info->tile); if (! tile) { return false; } // N.B. thread_info->tile will keep holding a ref-counted pointer // to the tile for the duration that we're using the tile data. int offset = pixelsize * (tile_t * spec.tile_width + tile_s); const unsigned char *base = tile->bytedata() + offset + channelsize * options.firstchannel; DASSERT (tile->data()); for (int j = 0; j < 4; ++j) for (int i = 0; i < 4; ++i) texel[j][i] = base + pixelsize * (i + j*spec.tile_width); } else { for (int j = 0; j < 4; ++j) { for (int i = 0; i < 4; ++i) { if (! (svalid[i] && tvalid[j])) { texel[j][i] = (unsigned char *) black; continue; } int stex_i = stex[i]; tile_s = (stex_i - spec.x) % spec.tile_width; tile_t = (ttex[j] - spec.y) % spec.tile_height; TileID id (texturefile, options.subimage, miplevel, stex_i - tile_s, ttex[j] - tile_t, 0); bool ok = find_tile (id, thread_info); if (! ok) error ("%s", m_imagecache->geterror().c_str()); TileRef &tile (thread_info->tile); if (! tile->valid()) return false; savetile[j][i] = tile; DASSERT (tile->id() == id); int offset = pixelsize * (tile_t * spec.tile_width + tile_s); DASSERT (tile->data()); texel[j][i] = tile->bytedata() + offset + channelsize * options.firstchannel; } } } int nc = options.actualchannels; // When we're on the lowest res mipmap levels, it's more pleasing if // we converge to a single pole color right at the pole. Fade to // the average color over the texel height right next to the pole. if (options.envlayout == LayoutLatLong && levelinfo.onetile) { float height = spec.height; if (texturefile.m_sample_border) height -= 1.0f; float tt = t * height; if (tt < 1.0f || tt > (height-1.0f)) fade_to_pole (tt, accum, weight, texturefile, thread_info, levelinfo, options, miplevel, nc); } // We use a formulation of cubic B-spline evaluation that reduces to // lerps. It's tricky to follow, but the references are: // * Ruijters, Daniel et al, "Efficient GPU-Based Texture // Interpolation using Uniform B-Splines", Journal of Graphics // Tools 13(4), pp. 61-69, 2008. // http://jgt.akpeters.com/papers/RuijtersEtAl08/ // * Sigg, Christian and Markus Hadwiger, "Fast Third-Order Texture // Filtering", in GPU Gems 2 (Chapter 20), Pharr and Fernando, ed. // http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter20.html // We like this formulation because it's slightly faster than any of // the other B-spline evaluation routines we tried, and also the lerp // guarantees that the filtered results will be non-negative for // non-negative texel values (which we had trouble with before due to // numerical imprecision). float wx[4]; evalBSplineWeights (wx, sfrac); float wy[4]; evalBSplineWeights (wy, tfrac); // figure out lerp weights so we can turn the filter into a sequence of lerp's float g0x = wx[0] + wx[1]; float h0x = (wx[1] / g0x); float g1x = wx[2] + wx[3]; float h1x = (wx[3] / g1x); float g0y = wy[0] + wy[1]; float h0y = (wy[1] / g0y); float g1y = wy[2] + wy[3]; float h1y = (wy[3] / g1y); if (texturefile.eightbit(options.subimage)) { for (int c = 0; c < nc; ++c) { float col[4]; for (int j = 0; j < 4; ++j) { float lx = Imath::lerp (uchar2float(texel[j][0][c]), uchar2float(texel[j][1][c]), h0x); float rx = Imath::lerp (uchar2float(texel[j][2][c]), uchar2float(texel[j][3][c]), h1x); col[j] = Imath::lerp (lx, rx, g1x); } float ly = Imath::lerp (col[0], col[1], h0y); float ry = Imath::lerp (col[2], col[3], h1y); accum[c] += weight * Imath::lerp (ly, ry, g1y); } if (daccumds) { float dwx[4]; evalBSplineWeightDerivs (dwx, sfrac); float dwy[4]; evalBSplineWeightDerivs (dwy, tfrac); float scalex = weight * spec.width; float scaley = weight * spec.height; for (int c = 0; c < nc; ++c) { daccumds[c] += scalex * ( dwx[0] * (wy[0] * uchar2float(texel[0][0][c]) + wy[1] * uchar2float(texel[1][0][c]) + wy[2] * uchar2float(texel[2][0][c]) + wy[3] * uchar2float(texel[3][0][c])) + dwx[1] * (wy[0] * uchar2float(texel[0][1][c]) + wy[1] * uchar2float(texel[1][1][c]) + wy[2] * uchar2float(texel[2][1][c]) + wy[3] * uchar2float(texel[3][1][c])) + dwx[2] * (wy[0] * uchar2float(texel[0][2][c]) + wy[1] * uchar2float(texel[1][2][c]) + wy[2] * uchar2float(texel[2][2][c]) + wy[3] * uchar2float(texel[3][2][c])) + dwx[3] * (wy[0] * uchar2float(texel[0][3][c]) + wy[1] * uchar2float(texel[1][3][c]) + wy[2] * uchar2float(texel[2][3][c]) + wy[3] * uchar2float(texel[3][3][c])) ); daccumdt[c] += scaley * ( dwy[0] * (wx[0] * uchar2float(texel[0][0][c]) + wx[1] * uchar2float(texel[0][1][c]) + wx[2] * uchar2float(texel[0][2][c]) + wx[3] * uchar2float(texel[0][3][c])) + dwy[1] * (wx[0] * uchar2float(texel[1][0][c]) + wx[1] * uchar2float(texel[1][1][c]) + wx[2] * uchar2float(texel[1][2][c]) + wx[3] * uchar2float(texel[1][3][c])) + dwy[2] * (wx[0] * uchar2float(texel[2][0][c]) + wx[1] * uchar2float(texel[2][1][c]) + wx[2] * uchar2float(texel[2][2][c]) + wx[3] * uchar2float(texel[2][3][c])) + dwy[3] * (wx[0] * uchar2float(texel[3][0][c]) + wx[1] * uchar2float(texel[3][1][c]) + wx[2] * uchar2float(texel[3][2][c]) + wx[3] * uchar2float(texel[3][3][c])) ); } } } else { // float texels for (int c = 0; c < nc; ++c) { float col[4]; for (int j = 0; j < 4; ++j) { float lx = Imath::lerp (((const float*)(texel[j][0]))[c], ((const float*)(texel[j][1]))[c], h0x); float rx = Imath::lerp (((const float*)(texel[j][2]))[c], ((const float*)(texel[j][3]))[c], h1x); col[j] = Imath::lerp (lx, rx, g1x); } float ly = Imath::lerp (col[0], col[1], h0y); float ry = Imath::lerp (col[2], col[3], h1y); accum[c] += weight * Imath::lerp (ly, ry, g1y); } if (daccumds) { float dwx[4]; evalBSplineWeightDerivs (dwx, sfrac); float dwy[4]; evalBSplineWeightDerivs (dwy, tfrac); float scalex = weight * spec.width; float scaley = weight * spec.height; for (int c = 0; c < nc; ++c) { daccumds[c] += scalex * ( dwx[0] * (wy[0] * ((const float*)(texel[0][0]))[c] + wy[1] * ((const float*)(texel[1][0]))[c] + wy[2] * ((const float*)(texel[2][0]))[c] + wy[3] * ((const float*)(texel[3][0]))[c]) + dwx[1] * (wy[0] * ((const float*)(texel[0][1]))[c] + wy[1] * ((const float*)(texel[1][1]))[c] + wy[2] * ((const float*)(texel[2][1]))[c] + wy[3] * ((const float*)(texel[3][1]))[c]) + dwx[2] * (wy[0] * ((const float*)(texel[0][2]))[c] + wy[1] * ((const float*)(texel[1][2]))[c] + wy[2] * ((const float*)(texel[2][2]))[c] + wy[3] * ((const float*)(texel[3][2]))[c]) + dwx[3] * (wy[0] * ((const float*)(texel[0][3]))[c] + wy[1] * ((const float*)(texel[1][3]))[c] + wy[2] * ((const float*)(texel[2][3]))[c] + wy[3] * ((const float*)(texel[3][3]))[c]) ); daccumdt[c] += scaley * ( dwy[0] * (wx[0] * ((const float*)(texel[0][0]))[c] + wx[1] * ((const float*)(texel[0][1]))[c] + wx[2] * ((const float*)(texel[0][2]))[c] + wx[3] * ((const float*)(texel[0][3]))[c]) + dwy[1] * (wx[0] * ((const float*)(texel[1][0]))[c] + wx[1] * ((const float*)(texel[1][1]))[c] + wx[2] * ((const float*)(texel[1][2]))[c] + wx[3] * ((const float*)(texel[1][3]))[c]) + dwy[2] * (wx[0] * ((const float*)(texel[2][0]))[c] + wx[1] * ((const float*)(texel[2][1]))[c] + wx[2] * ((const float*)(texel[2][2]))[c] + wx[3] * ((const float*)(texel[2][3]))[c]) + dwy[3] * (wx[0] * ((const float*)(texel[3][0]))[c] + wx[1] * ((const float*)(texel[3][1]))[c] + wx[2] * ((const float*)(texel[3][2]))[c] + wx[3] * ((const float*)(texel[3][3]))[c]) ); } } } // Add appropriate amount of "fill" color to extra channels in // non-"black"-wrapped regions. if (options.nchannels > options.actualchannels && options.fill) { float col[4]; for (int j = 0; j < 4; ++j) { float lx = Imath::lerp (1.0f*tvalid[j]*svalid[0], 1.0f*tvalid[j]*svalid[1], h0x); float rx = Imath::lerp (1.0f*tvalid[j]*svalid[2], 1.0f*tvalid[j]*svalid[3], h1x); col[j] = Imath::lerp (lx, rx, g1x); } float ly = Imath::lerp (col[0], col[1], h0y); float ry = Imath::lerp (col[2], col[3], h1y); float f = weight * Imath::lerp (ly, ry, g1y) * options.fill; for (int c = options.actualchannels; c < options.nchannels; ++c) accum[c] += f; } return true; } void TextureSystemImpl::visualize_ellipse (const std::string &name, float dsdx, float dtdx, float dsdy, float dtdy, float sblur, float tblur) { std::cout << name << " derivs dx " << dsdx << ' ' << dtdx << ", dt " << dtdx << ' ' << dtdy << "\n"; adjust_width (dsdx, dtdx, dsdy, dtdy, 1.0f, 1.0f); float majorlength, minorlength, theta; float ABCF[4]; ellipse_axes (dsdx, dtdx, dsdy, dtdy, majorlength, minorlength, theta, ABCF); std::cout << " ellipse major " << majorlength << ", minor " << minorlength << ", theta " << theta << "\n"; adjust_blur (majorlength, minorlength, theta, sblur, tblur); std::cout << " post " << sblur << ' ' << tblur << " blur: major " << majorlength << ", minor " << minorlength << "\n\n"; TextureOpt options; float trueaspect; float aspect = TextureSystemImpl::anisotropic_aspect (majorlength, minorlength, options, trueaspect); float *lineweight = ALLOCA (float, 2*options.anisotropic); float smajor, tmajor, invsamples; int nsamples = compute_ellipse_sampling (aspect, theta, majorlength, minorlength, smajor, tmajor, invsamples, lineweight); // Make an ImageBuf to hold our visualization image, set it to grey float scale = 100; int w = 256, h = 256; ImageSpec spec (w, h, 3); ImageBuf ib (spec); static float dark[3] = { 0.2, 0.2, 0.2 }; static float white[3] = { 1, 1, 1 }; static float grey[3] = { 0.5, 0.5, 0.5 }; static float red[3] = { 1, 0, 0 }; static float green[3] = { 0, 1, 0 }; ImageBufAlgo::fill (ib, grey); // scan all the pixels, darken the ellipse interior for (int j = 0; j < h; ++j) { float y = (j-h/2)/scale; for (int i = 0; i < w; ++i) { float x = (i-w/2)/scale; float d2 = ABCF[0]*x*x + ABCF[1]*x*y + ABCF[2]*y*y; if (d2 < 1.0f) ib.setpixel (i, h-1-j, dark); } } // Draw red and green axes for the dx and dy derivatives, respectively for (int i = 0, e = std::max(fabsf(dsdx),fabsf(dtdx))*scale; i < e; ++i) ib.setpixel (w/2+int(float(i)/e*dsdx*scale), h/2-int(float(i)/e*dtdx*scale), red); for (int i = 0, e = std::max(fabsf(dsdy),fabsf(dtdy))*scale; i < e; ++i) ib.setpixel (w/2+int(float(i)/e*dsdy*scale), h/2-int(float(i)/e*dtdy*scale), green); float bigweight = 0; for (int i = 0; i < nsamples; ++i) bigweight = std::max(lineweight[i],bigweight); // Plop white dots at the sample positions for (int sample = 0; sample < nsamples; ++sample) { float pos = 1.0f * (sample + 0.5f) * invsamples - 0.5f; float x = pos*smajor, y = pos*tmajor; int xx = w/2+int(x*scale), yy = h/2-int(y*scale); int size = int (5 * lineweight[sample]/bigweight); ImageBufAlgo::fill (ib, white, ROI(xx-size/2, xx+size/2+1, yy-size/2, yy+size/2+1)); } ib.write (name); } void TextureSystemImpl::unit_test_texture () { float blur = 0; float dsdx, dtdx, dsdy, dtdy; dsdx = 0.4; dtdx = 0.0; dsdy = 0.0; dtdy = 0.2; visualize_ellipse ("0.tif", dsdx, dtdx, dsdy, dtdy, blur, blur); dsdx = 0.2; dtdx = 0.0; dsdy = 0.0; dtdy = 0.4; visualize_ellipse ("1.tif", dsdx, dtdx, dsdy, dtdy, blur, blur); dsdx = 0.2; dtdx = 0.2; dsdy = -0.2; dtdy = 0.2; visualize_ellipse ("2.tif", dsdx, dtdx, dsdy, dtdy, blur, blur); dsdx = 0.35; dtdx = 0.27; dsdy = 0.1; dtdy = 0.35; visualize_ellipse ("3.tif", dsdx, dtdx, dsdy, dtdy, blur, blur); dsdx = 0.35; dtdx = 0.27; dsdy = 0.1; dtdy = -0.35; visualize_ellipse ("4.tif", dsdx, dtdx, dsdy, dtdy, blur, blur); boost::mt19937 rndgen; boost::uniform_01 rnd(rndgen); for (int i = 0; i < 100; ++i) { dsdx = 1.5f*(rnd() - 0.5f); dtdx = 1.5f*(rnd() - 0.5f); dsdy = 1.5f*(rnd() - 0.5f); dtdy = 1.5f*(rnd() - 0.5f); visualize_ellipse (Strutil::format("%d.tif", 100+i), dsdx, dtdx, dsdy, dtdy, blur, blur); } } } // end namespace pvt } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libtexture/texture3d.cpp0000644000175000017500000006336212271062644021744 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "varyingref.h" #include "ustring.h" #include "strutil.h" #include "thread.h" #include "fmath.h" #include "filter.h" #include "imageio.h" #include "texture.h" #include "imagecache.h" #include "imagecache_pvt.h" #include "texture_pvt.h" #include "../field3d.imageio/field3d_backdoor.h" OIIO_NAMESPACE_ENTER { using namespace pvt; using namespace f3dpvt; namespace { // anonymous static EightBitConverter uchar2float; static ustring s_field3d ("field3d"); } // end anonymous namespace namespace pvt { // namespace pvt bool TextureSystemImpl::texture3d (ustring filename, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, const Imath::V3f &dPdz, float *result) { PerThreadInfo *thread_info = m_imagecache->get_perthread_info (); TextureFile *texturefile = find_texturefile (filename, thread_info); return texture3d ((TextureHandle *)texturefile, (Perthread *)thread_info, options, P, dPdx, dPdy, dPdz, result); } bool TextureSystemImpl::texture3d (TextureHandle *texture_handle_, Perthread *thread_info_, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, const Imath::V3f &dPdz, float *result) { #if 0 // FIXME: currently, no support of actual MIPmapping. No rush, // since the only volume format we currently support, Field3D, // doens't support MIPmapping. static const texture3d_lookup_prototype lookup_functions[] = { // Must be in the same order as Mipmode enum &TextureSystemImpl::texture3d_lookup, &TextureSystemImpl::texture3d_lookup_nomip, &TextureSystemImpl::texture3d_lookup_trilinear_mipmap, &TextureSystemImpl::texture3d_lookup_trilinear_mipmap, &TextureSystemImpl::texture3d_lookup }; texture3d_lookup_prototype lookup = lookup_functions[(int)options.mipmode]; #else texture3d_lookup_prototype lookup = &TextureSystemImpl::texture3d_lookup_nomip; #endif PerThreadInfo *thread_info = (PerThreadInfo *)thread_info_; TextureFile *texturefile = (TextureFile *)texture_handle_; ImageCacheStatistics &stats (thread_info->m_stats); ++stats.texture3d_batches; ++stats.texture3d_queries; if (! texturefile || texturefile->broken()) return missing_texture (options, result); if (options.subimagename) { // If subimage was specified by name, figure out its index. int s = m_imagecache->subimage_from_name (texturefile, options.subimagename); if (s < 0) { error ("Unknown subimage \"%s\" in texture \"%s\"", options.subimagename.c_str(), texturefile->filename().c_str()); return false; } options.subimage = s; options.subimagename.clear(); } const ImageSpec &spec (texturefile->spec(options.subimage, 0)); // Figure out the wrap functions if (options.swrap == TextureOpt::WrapDefault) options.swrap = texturefile->swrap(); if (options.swrap == TextureOpt::WrapPeriodic && ispow2(spec.full_width)) options.swrap_func = wrap_periodic_pow2; else options.swrap_func = wrap_functions[(int)options.swrap]; if (options.twrap == TextureOpt::WrapDefault) options.twrap = texturefile->twrap(); if (options.twrap == TextureOpt::WrapPeriodic && ispow2(spec.full_height)) options.twrap_func = wrap_periodic_pow2; else options.twrap_func = wrap_functions[(int)options.twrap]; if (options.rwrap == TextureOpt::WrapDefault) options.rwrap = texturefile->rwrap(); if (options.rwrap == TextureOpt::WrapPeriodic && ispow2(spec.full_depth)) options.rwrap_func = wrap_periodic_pow2; else options.rwrap_func = wrap_functions[(int)options.rwrap]; int actualchannels = Imath::clamp (spec.nchannels - options.firstchannel, 0, options.nchannels); options.actualchannels = actualchannels; // Do the volume lookup in local space. There's not actually a way // to ask for point transforms via the ImageInput interface, so use // knowledge of the few volume reader internals to the back doors. Imath::V3f Plocal; if (texturefile->fileformat() == s_field3d) { if (! texturefile->opened()) { // We need a valid ImageInput pointer below. If the handle // has been invalidated, force it open again. texturefile->forceopen (thread_info); } Field3DInput_Interface *f3di = (Field3DInput_Interface *)texturefile->imageinput(); ASSERT (f3di); f3di->worldToLocal (P, Plocal, options.time); } else { Plocal = P; } // FIXME: we don't bother with this for dPdx, dPdy, and dPdz only // because we know that we don't currently filter volume lookups and // therefore don't actually use the derivs. If/when we do, we'll // need to transform them into local space as well. bool ok = (this->*lookup) (*texturefile, thread_info, options, Plocal, dPdx, dPdy, dPdz, result); if (actualchannels < options.nchannels) fill_gray_channels (spec, options, result); return ok; } bool TextureSystemImpl::texture3d (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef P, VaryingRef dPdx, VaryingRef dPdy, VaryingRef dPdz, float *result) { bool ok = true; for (int i = beginactive; i < endactive; ++i) { if (runflags[i]) { TextureOpt opt (options, i); ok &= texture3d (filename, opt, P[i], dPdx[i], dPdy[i], dPdz[i], result + i*options.nchannels); } } return ok; } bool TextureSystemImpl::texture3d_lookup_nomip (TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, const Imath::V3f &_P, const Imath::V3f &_dPdx, const Imath::V3f &_dPdy, const Imath::V3f &_dPdz, float *result) { // Initialize results to 0. We'll add from here on as we sample. for (int c = 0; c < options.nchannels; ++c) result[c] = 0; float* dresultds = options.dresultds; float* dresultdt = options.dresultdt; float* dresultdr = options.dresultdr; if (dresultds) { DASSERT (dresultdt && dresultdr); for (int c = 0; c < options.nchannels; ++c) dresultds[c] = 0; for (int c = 0; c < options.nchannels; ++c) dresultdt[c] = 0; for (int c = 0; c < options.nchannels; ++c) dresultdr[c] = 0; } // If the user only provided us with one pointer, clear all to simplify // the rest of the code, but only after we zero out the data for them so // they know something went wrong. if (!(dresultds && dresultdt && dresultdr)) dresultds = dresultdt = dresultdr = NULL; static const accum3d_prototype accum_functions[] = { // Must be in the same order as InterpMode enum &TextureSystemImpl::accum3d_sample_closest, &TextureSystemImpl::accum3d_sample_bilinear, &TextureSystemImpl::accum3d_sample_bilinear, // FIXME: bicubic, &TextureSystemImpl::accum3d_sample_bilinear, }; accum3d_prototype accumer = accum_functions[(int)options.interpmode]; bool ok = (this->*accumer) (_P, 0, texturefile, thread_info, options, 1.0f, result, dresultds, dresultdt, dresultdr); // Update stats ImageCacheStatistics &stats (thread_info->m_stats); ++stats.aniso_queries; ++stats.aniso_probes; switch (options.interpmode) { case TextureOpt::InterpClosest : ++stats.closest_interps; break; case TextureOpt::InterpBilinear : ++stats.bilinear_interps; break; case TextureOpt::InterpBicubic : ++stats.cubic_interps; break; case TextureOpt::InterpSmartBicubic : ++stats.bilinear_interps; break; } return ok; } bool TextureSystemImpl::accum3d_sample_closest (const Imath::V3f &P, int miplevel, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt, float *daccumdr) { const ImageSpec &spec (texturefile.spec (options.subimage, miplevel)); const ImageCacheFile::LevelInfo &levelinfo (texturefile.levelinfo(options.subimage,miplevel)); // As passed in, (s,t) map the texture to (0,1). Remap to texel coords. float s = P[0] * spec.full_width + spec.full_x; float t = P[1] * spec.full_height + spec.full_y; float r = P[2] * spec.full_depth + spec.full_z; int stex, ttex, rtex; // Texel coordintes (void) floorfrac (s, &stex); // don't need fractional result (void) floorfrac (t, &ttex); (void) floorfrac (r, &rtex); // Wrap DASSERT (options.swrap_func != NULL && options.twrap_func != NULL && options.rwrap_func != NULL); bool svalid, tvalid, rvalid; // Valid texels? false means black border svalid = options.swrap_func (stex, spec.x, spec.width); tvalid = options.twrap_func (ttex, spec.y, spec.height); rvalid = options.rwrap_func (rtex, spec.z, spec.depth); if (! levelinfo.full_pixel_range) { svalid &= (stex >= spec.x && stex < (spec.x+spec.width)); // data window tvalid &= (ttex >= spec.y && ttex < (spec.y+spec.height)); rvalid &= (rtex >= spec.z && rtex < (spec.z+spec.depth)); } if (! (svalid & tvalid & rvalid)) { // All texels we need were out of range and using 'black' wrap. return true; } int tile_s = (stex - spec.x) % spec.tile_width; int tile_t = (ttex - spec.y) % spec.tile_height; int tile_r = (rtex - spec.z) % spec.tile_depth; TileID id (texturefile, options.subimage, miplevel, stex - tile_s, ttex - tile_t, rtex - tile_r); bool ok = find_tile (id, thread_info); if (! ok) error ("%s", m_imagecache->geterror().c_str()); TileRef &tile (thread_info->tile); if (! tile || ! ok) return false; size_t channelsize = texturefile.channelsize(options.subimage); int tilepel = (tile_r * spec.tile_height + tile_t) * spec.tile_width + tile_s; int offset = spec.nchannels * tilepel + options.firstchannel; DASSERT ((size_t)offset < spec.nchannels*spec.tile_pixels()); if (channelsize == 1) { // special case for 8-bit tiles const unsigned char *texel = tile->bytedata() + offset; for (int c = 0; c < options.actualchannels; ++c) accum[c] += weight * uchar2float(texel[c]); } else { // General case for float tiles const float *texel = tile->data() + offset; for (int c = 0; c < options.actualchannels; ++c) accum[c] += weight * texel[c]; } // Add appropriate amount of "fill" color to extra channels in // non-"black"-wrapped regions. if (options.nchannels > options.actualchannels && options.fill) { float f = weight * options.fill; for (int c = options.actualchannels; c < options.nchannels; ++c) accum[c] += f; } return true; } bool TextureSystemImpl::accum3d_sample_bilinear (const Imath::V3f &P, int miplevel, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt, float *daccumdr) { const ImageSpec &spec (texturefile.spec (options.subimage, miplevel)); const ImageCacheFile::LevelInfo &levelinfo (texturefile.levelinfo(options.subimage,miplevel)); // As passed in, (s,t) map the texture to (0,1). Remap to texel coords // and subtract 0.5 because samples are at texel centers. float s = P[0] * spec.full_width + spec.full_x - 0.5f; float t = P[1] * spec.full_height + spec.full_y - 0.5f; float r = P[2] * spec.full_depth + spec.full_z - 0.5f; int sint, tint, rint; float sfrac = floorfrac (s, &sint); float tfrac = floorfrac (t, &tint); float rfrac = floorfrac (r, &rint); // Now (sint,tint,rint) are the integer coordinates of the texel to the // immediate "upper left" of the lookup point, and (sfrac,tfrac,rfrac) are // the amount that the lookup point is actually offset from the // texel center (with (1,1) being all the way to the next texel down // and to the right). // Wrap DASSERT (options.swrap_func != NULL && options.twrap_func != NULL && options.rwrap_func != NULL); int stex[2], ttex[2], rtex[2]; // Texel coords stex[0] = sint; stex[1] = sint+1; ttex[0] = tint; ttex[1] = tint+1; rtex[0] = rint; rtex[1] = rint+1; // bool svalid[2], tvalid[2], rvalid[2]; // Valid texels? false means black border union { bool bvalid[6]; unsigned long long ivalid; } valid_storage; valid_storage.ivalid = 0; DASSERT (sizeof(valid_storage) == 8); const unsigned long long none_valid = 0; const unsigned long long all_valid = littleendian() ? 0x010101010101LL : 0x01010101010100LL; bool *svalid = valid_storage.bvalid; bool *tvalid = valid_storage.bvalid + 2; bool *rvalid = valid_storage.bvalid + 4; svalid[0] = options.swrap_func (stex[0], spec.x, spec.width); svalid[1] = options.swrap_func (stex[1], spec.x, spec.width); tvalid[0] = options.twrap_func (ttex[0], spec.y, spec.height); tvalid[1] = options.twrap_func (ttex[1], spec.y, spec.height); rvalid[0] = options.rwrap_func (rtex[0], spec.z, spec.depth); rvalid[1] = options.rwrap_func (rtex[1], spec.z, spec.depth); // Account for crop windows if (! levelinfo.full_pixel_range) { svalid[0] &= (stex[0] >= spec.x && stex[0] < spec.x+spec.width); svalid[1] &= (stex[1] >= spec.x && stex[1] < spec.x+spec.width); tvalid[0] &= (ttex[0] >= spec.y && ttex[0] < spec.y+spec.height); tvalid[1] &= (ttex[1] >= spec.y && ttex[1] < spec.y+spec.height); rvalid[0] &= (rtex[0] >= spec.z && rtex[0] < spec.z+spec.depth); rvalid[1] &= (rtex[1] >= spec.z && rtex[1] < spec.z+spec.depth); } // if (! (svalid[0] | svalid[1] | tvalid[0] | tvalid[1] | rvalid[0] | rvalid[1])) if (valid_storage.ivalid == none_valid) return true; // All texels we need were out of range and using 'black' wrap int tilewidthmask = spec.tile_width - 1; // e.g. 63 int tileheightmask = spec.tile_height - 1; int tiledepthmask = spec.tile_depth - 1; const unsigned char *texel[2][2][2]; TileRef savetile[2][2][2]; static float black[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int tile_s = (stex[0] - spec.x) % spec.tile_width; int tile_t = (ttex[0] - spec.y) % spec.tile_height; int tile_r = (rtex[0] - spec.z) % spec.tile_depth; bool s_onetile = (tile_s != tilewidthmask) & (stex[0]+1 == stex[1]); bool t_onetile = (tile_t != tileheightmask) & (ttex[0]+1 == ttex[1]); bool r_onetile = (tile_r != tiledepthmask) & (rtex[0]+1 == rtex[1]); bool onetile = (s_onetile & t_onetile & r_onetile); size_t channelsize = texturefile.channelsize(options.subimage); size_t pixelsize = texturefile.pixelsize(options.subimage); if (onetile && valid_storage.ivalid == all_valid) { // Shortcut if all the texels we need are on the same tile TileID id (texturefile, options.subimage, miplevel, stex[0] - tile_s, ttex[0] - tile_t, rtex[0] - tile_r); bool ok = find_tile (id, thread_info); if (! ok) error ("%s", m_imagecache->geterror().c_str()); TileRef &tile (thread_info->tile); if (! tile->valid()) return false; size_t tilepel = (tile_r * spec.tile_height + tile_t) * spec.tile_width + tile_s; size_t offset = (spec.nchannels * tilepel + options.firstchannel) * channelsize; DASSERT ((size_t)offset < spec.tile_width*spec.tile_height*spec.tile_depth*pixelsize); const unsigned char *b = tile->bytedata() + offset; texel[0][0][0] = b; texel[0][0][1] = b + pixelsize; texel[0][1][0] = b + pixelsize * spec.tile_width; texel[0][1][1] = b + pixelsize * spec.tile_width + pixelsize; b += pixelsize * spec.tile_width * spec.tile_height; texel[1][0][0] = b; texel[1][0][1] = b + pixelsize; texel[1][1][0] = b + pixelsize * spec.tile_width; texel[1][1][1] = b + pixelsize * spec.tile_width + pixelsize; } else { for (int k = 0; k < 2; ++k) { for (int j = 0; j < 2; ++j) { for (int i = 0; i < 2; ++i) { if (! (svalid[i] && tvalid[j] && rvalid[k])) { texel[k][j][i] = (unsigned char *)black; continue; } tile_s = (stex[i] - spec.x) % spec.tile_width; tile_t = (ttex[j] - spec.y) % spec.tile_height; tile_r = (rtex[k] - spec.z) % spec.tile_depth; TileID id (texturefile, options.subimage, miplevel, stex[i] - tile_s, ttex[j] - tile_t, rtex[k] - tile_r); bool ok = find_tile (id, thread_info); if (! ok) error ("%s", m_imagecache->geterror().c_str()); TileRef &tile (thread_info->tile); if (! tile->valid()) return false; savetile[k][j][i] = tile; size_t tilepel = (tile_r * spec.tile_height + tile_t) * spec.tile_width + tile_s; size_t offset = (spec.nchannels * tilepel + options.firstchannel) * channelsize; #ifndef NDEBUG if ((size_t)offset >= spec.tile_width*spec.tile_height*spec.tile_depth*pixelsize) std::cerr << "offset=" << offset << ", whd " << spec.tile_width << ' ' << spec.tile_height << ' ' << spec.tile_depth << " pixsize " << pixelsize << "\n"; #endif DASSERT ((size_t)offset < spec.tile_width*spec.tile_height*spec.tile_depth*pixelsize); texel[k][j][i] = tile->bytedata() + offset; DASSERT (tile->id() == id); } } } } // FIXME -- optimize the above loop by unrolling if (channelsize == 1) { // special case for 8-bit tiles int c; for (c = 0; c < options.actualchannels; ++c) accum[c] += weight * trilerp (uchar2float(texel[0][0][0][c]), uchar2float(texel[0][0][1][c]), uchar2float(texel[0][1][0][c]), uchar2float(texel[0][1][1][c]), uchar2float(texel[1][0][0][c]), uchar2float(texel[1][0][1][c]), uchar2float(texel[1][1][0][c]), uchar2float(texel[1][1][1][c]), sfrac, tfrac, rfrac); if (daccumds) { float scalex = weight * spec.full_width; float scaley = weight * spec.full_height; float scalez = weight * spec.full_depth; for (c = 0; c < options.actualchannels; ++c) { daccumds[c] += scalex * bilerp( uchar2float(texel[0][0][1][c]) - uchar2float(texel[0][0][0][c]), uchar2float(texel[0][1][1][c]) - uchar2float(texel[0][1][0][c]), uchar2float(texel[1][0][1][c]) - uchar2float(texel[1][0][0][c]), uchar2float(texel[1][1][1][c]) - uchar2float(texel[1][1][0][c]), tfrac, rfrac ); daccumdt[c] += scaley * bilerp( uchar2float(texel[0][1][0][c]) - uchar2float(texel[0][0][0][c]), uchar2float(texel[0][1][1][c]) - uchar2float(texel[0][0][1][c]), uchar2float(texel[1][1][0][c]) - uchar2float(texel[1][0][0][c]), uchar2float(texel[1][1][1][c]) - uchar2float(texel[1][0][1][c]), sfrac, rfrac ); daccumdr[c] += scalez * bilerp( uchar2float(texel[0][1][0][c]) - uchar2float(texel[1][1][0][c]), uchar2float(texel[0][1][1][c]) - uchar2float(texel[1][1][1][c]), uchar2float(texel[0][0][1][c]) - uchar2float(texel[1][0][0][c]), uchar2float(texel[0][1][1][c]) - uchar2float(texel[1][1][1][c]), sfrac, tfrac ); } } } else { // General case for float tiles trilerp_mad ((const float *)texel[0][0][0], (const float *)texel[0][0][1], (const float *)texel[0][1][0], (const float *)texel[0][1][1], (const float *)texel[1][0][0], (const float *)texel[1][0][1], (const float *)texel[1][1][0], (const float *)texel[1][1][1], sfrac, tfrac, rfrac, weight, options.actualchannels, accum); if (daccumds) { float scalex = weight * spec.full_width; float scaley = weight * spec.full_height; float scalez = weight * spec.full_depth; for (int c = 0; c < options.actualchannels; ++c) { daccumds[c] += scalex * bilerp( ((const float *) texel[0][0][1])[c] - ((const float *) texel[0][0][0])[c], ((const float *) texel[0][1][1])[c] - ((const float *) texel[0][1][0])[c], ((const float *) texel[1][0][1])[c] - ((const float *) texel[1][0][0])[c], ((const float *) texel[1][1][1])[c] - ((const float *) texel[1][1][0])[c], tfrac, rfrac ); daccumdt[c] += scaley * bilerp( ((const float *) texel[0][1][0])[c] - ((const float *) texel[0][0][0])[c], ((const float *) texel[0][1][1])[c] - ((const float *) texel[0][0][1])[c], ((const float *) texel[1][1][0])[c] - ((const float *) texel[1][0][0])[c], ((const float *) texel[1][1][1])[c] - ((const float *) texel[1][0][1])[c], sfrac, rfrac ); daccumdr[c] += scalez * bilerp( ((const float *) texel[0][1][0])[c] - ((const float *) texel[1][1][0])[c], ((const float *) texel[0][1][1])[c] - ((const float *) texel[1][1][1])[c], ((const float *) texel[0][0][1])[c] - ((const float *) texel[1][0][0])[c], ((const float *) texel[0][1][1])[c] - ((const float *) texel[1][1][1])[c], sfrac, tfrac ); } } } // Add appropriate amount of "fill" color to extra channels in // non-"black"-wrapped regions. if (options.nchannels > options.actualchannels && options.fill) { float f = trilerp (1.0f*(rvalid[0]*tvalid[0]*svalid[0]), 1.0f*(rvalid[0]*tvalid[0]*svalid[1]), 1.0f*(rvalid[0]*tvalid[1]*svalid[0]), 1.0f*(rvalid[0]*tvalid[1]*svalid[1]), 1.0f*(rvalid[1]*tvalid[0]*svalid[0]), 1.0f*(rvalid[1]*tvalid[0]*svalid[1]), 1.0f*(rvalid[1]*tvalid[1]*svalid[0]), 1.0f*(rvalid[1]*tvalid[1]*svalid[1]), sfrac, tfrac, rfrac); f *= weight * options.fill; for (int c = options.actualchannels; c < options.nchannels; ++c) accum[c] += f; } return true; } } // end namespace pvt } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libtexture/texture_pvt.h0000644000175000017500000005516012271062644022050 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Non-public classes used internally by TextureSystemImpl. #ifndef OPENIMAGEIO_TEXTURE_PVT_H #define OPENIMAGEIO_TEXTURE_PVT_H #include "version.h" OIIO_NAMESPACE_ENTER { class ImageCache; class Filter1D; namespace pvt { class TextureSystemImpl; #ifndef OPENIMAGEIO_IMAGECACHE_PVT_H class ImageCacheImpl; class ImageCacheFile; class ImageCacheTile; class ImageCacheTileRef; #endif /// Working implementation of the abstract TextureSystem class. /// class TextureSystemImpl : public TextureSystem { public: typedef ImageCacheFile TextureFile; TextureSystemImpl (ImageCache *imagecache); virtual ~TextureSystemImpl (); virtual bool attribute (const std::string &name, TypeDesc type, const void *val); virtual bool attribute (const std::string &name, int val) { return attribute (name, TypeDesc::INT, &val); } virtual bool attribute (const std::string &name, float val) { return attribute (name, TypeDesc::FLOAT, &val); } virtual bool attribute (const std::string &name, double val) { float f = (float) val; return attribute (name, TypeDesc::FLOAT, &f); } virtual bool attribute (const std::string &name, const char *val) { return attribute (name, TypeDesc::STRING, &val); } virtual bool attribute (const std::string &name, const std::string &val) { const char *s = val.c_str(); return attribute (name, TypeDesc::STRING, &s); } virtual bool getattribute (const std::string &name, TypeDesc type, void *val); virtual bool getattribute (const std::string &name, int &val) { return getattribute (name, TypeDesc::INT, &val); } virtual bool getattribute (const std::string &name, float &val) { return getattribute (name, TypeDesc::FLOAT, &val); } virtual bool getattribute (const std::string &name, double &val) { float f; bool ok = getattribute (name, TypeDesc::FLOAT, &f); if (ok) val = f; return ok; } virtual bool getattribute (const std::string &name, char **val) { return getattribute (name, TypeDesc::STRING, val); } virtual bool getattribute (const std::string &name, std::string &val) { const char *s; bool ok = getattribute (name, TypeDesc::STRING, &s); if (ok) val = s; return ok; } /// Close everything, free resources, start from scratch. /// virtual void clear () { } // Retrieve options void get_commontoworld (Imath::M44f &result) const { result = m_Mc2w; } virtual Perthread *get_perthread_info (void) { return (Perthread *)m_imagecache->get_perthread_info (); } virtual TextureHandle *get_texture_handle (ustring filename, Perthread *thread) { PerThreadInfo *thread_info = thread ? (PerThreadInfo *)thread : m_imagecache->get_perthread_info (); return (TextureHandle *) find_texturefile (filename, thread_info); } /// Filtered 2D texture lookup for a single point, no runflags. /// virtual bool texture (TextureHandle *texture_handle, Perthread *thread_info, TextureOpt &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result); /// Filtered 2D texture lookup for a single point, no runflags. /// virtual bool texture (ustring filename, TextureOpt &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result); /// Filtered 2D texture lookup for a single point, no runflags. /// virtual bool texture (ustring filename, TextureOptions &options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) { Runflag rf = RunFlagOn; return texture (filename, options, &rf, 0, 1, s, t, dsdx, dtdx, dsdy, dtdy, result); } /// Retrieve a 2D texture lookup at many points at once. /// virtual bool texture (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef s, VaryingRef t, VaryingRef dsdx, VaryingRef dtdx, VaryingRef dsdy, VaryingRef dtdy, float *result); /// Retrieve a 3D texture lookup at a single point. /// virtual bool texture3d (ustring filename, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, const Imath::V3f &dPdz, float *result); virtual bool texture3d (TextureHandle *texture_handle, Perthread *thread_info, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, const Imath::V3f &dPdz, float *result); virtual bool texture3d (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef P, VaryingRef dPdx, VaryingRef dPdy, VaryingRef dPdz, float *result); /// Retrieve a shadow lookup for a single position P. /// virtual bool shadow (ustring filename, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, float *result) { return false; } virtual bool shadow (TextureHandle *texture_handle, Perthread *thread_info, TextureOpt &options, const Imath::V3f &P, const Imath::V3f &dPdx, const Imath::V3f &dPdy, float *result) { return false; } /// Retrieve a shadow lookup for position P at many points at once. /// virtual bool shadow (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef P, VaryingRef dPdx, VaryingRef dPdy, float *result) { return false; } /// Retrieve an environment map lookup for direction R. /// virtual bool environment (ustring filename, TextureOpt &opt, const Imath::V3f &R, const Imath::V3f &dRdx, const Imath::V3f &dRdy, float *result); virtual bool environment (TextureHandle *texture_handle, Perthread *thread_info, TextureOpt &options, const Imath::V3f &R, const Imath::V3f &dRdx, const Imath::V3f &dRdy, float *result); /// Retrieve an environment map lookup for direction R, for many /// points at once. virtual bool environment (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef R, VaryingRef dRdx, VaryingRef dRdy, float *result); /// Given possibly-relative 'filename', resolve it using the search /// path rules and return the full resolved filename. virtual std::string resolve_filename (const std::string &filename) const; /// Get information about the given texture. /// virtual bool get_texture_info (ustring filename, int subimage, ustring dataname, TypeDesc datatype, void *data); virtual bool get_imagespec (ustring filename, int subimage, ImageSpec &spec); virtual const ImageSpec *imagespec (ustring filename, int subimage=0); /// Retrieve a rectangle of raw unfiltered texels. /// virtual bool get_texels (ustring filename, TextureOpt &options, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result); virtual std::string geterror () const; virtual std::string getstats (int level=1, bool icstats=true) const; virtual void reset_stats (); virtual void invalidate (ustring filename); virtual void invalidate_all (bool force=false); void operator delete (void *todel) { ::delete ((char *)todel); } private: typedef ImageCacheTileRef TileRef; typedef ImageCachePerThreadInfo PerThreadInfo; void init (); /// Find the TextureFile record for the named texture, or NULL if no /// such file can be found. TextureFile *find_texturefile (ustring filename, PerThreadInfo *thread_info) { TextureFile *texturefile = m_imagecache->find_file (filename, thread_info); if (!texturefile || texturefile->broken()) error ("%s", m_imagecache->geterror().c_str()); return texturefile; } /// Find the tile specified by id. If found, return true and place /// the tile ref in thread_info->tile; if not found, return false. /// This is more efficient than find_tile_main_cache() because it /// avoids looking to the big cache (and locking) most of the time /// for fairly coherent tile access patterns, by using the /// per-thread microcache to boost our hit rate over the big cache. /// Inlined for speed. bool find_tile (const TileID &id, PerThreadInfo *thread_info) { return m_imagecache->find_tile (id, thread_info); } // Define a prototype of a member function pointer for texture // lookups. typedef bool (TextureSystemImpl::*texture_lookup_prototype) (TextureFile &texfile, PerThreadInfo *thread_info, TextureOpt &options, float _s, float _t, float _dsdx, float _dtdx, float _dsdy, float _dtdy, float *result); /// Look up texture from just ONE point /// bool texture_lookup (TextureFile &texfile, PerThreadInfo *thread_info, TextureOpt &options, float _s, float _t, float _dsdx, float _dtdx, float _dsdy, float _dtdy, float *result); bool texture_lookup_nomip (TextureFile &texfile, PerThreadInfo *thread_info, TextureOpt &options, float _s, float _t, float _dsdx, float _dtdx, float _dsdy, float _dtdy, float *result); bool texture_lookup_trilinear_mipmap (TextureFile &texfile, PerThreadInfo *thread_info, TextureOpt &options, float _s, float _t, float _dsdx, float _dtdx, float _dsdy, float _dtdy, float *result); typedef bool (TextureSystemImpl::*accum_prototype) (float s, float t, int level, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt); bool accum_sample_closest (float s, float t, int level, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt); bool accum_sample_bilinear (float s, float t, int level, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt); bool accum_sample_bicubic (float s, float t, int level, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt); // Define a prototype of a member function pointer for texture3d // lookups. typedef bool (TextureSystemImpl::*texture3d_lookup_prototype) (TextureFile &texfile, PerThreadInfo *thread_info, TextureOpt &options, const Imath::V3f &_P, const Imath::V3f &_dPdx, const Imath::V3f &_dPdy, const Imath::V3f &_dPdz, float *result); bool texture3d_lookup_nomip (TextureFile &texfile, PerThreadInfo *thread_info, TextureOpt &options, const Imath::V3f &_P, const Imath::V3f &_dPdx, const Imath::V3f &_dPdy, const Imath::V3f &_dPdz, float *result); typedef bool (TextureSystemImpl::*accum3d_prototype) (const Imath::V3f &P, int level, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt, float *daccumdr); bool accum3d_sample_closest (const Imath::V3f &P, int level, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt, float *daccumdr); bool accum3d_sample_bilinear (const Imath::V3f &P, int level, TextureFile &texturefile, PerThreadInfo *thread_info, TextureOpt &options, float weight, float *accum, float *daccumds, float *daccumdt, float *daccumdr); /// Helper function to calculate the anisotropic aspect ratio from /// the major and minor ellipse axis lengths. The "clamped" aspect /// ratio is returned (possibly adjusting major and minorlength to /// conform to the aniso limits) but the true aspect is stored in /// 'trueaspect'. static float anisotropic_aspect (float &majorlength, float &minorlength, TextureOpt& options, float &trueaspect); /// Convert texture coordinates (s,t), which range on 0-1 for the /// "full" image boundary, to texel coordinates (i+ifrac,j+jfrac) /// where (i,j) is the texel to the immediate upper left of the /// sample position, and ifrac and jfrac are the fractional (0-1) /// portion of the way to the next texel to the right or down, /// respectively. void st_to_texel (float s, float t, TextureFile &texturefile, const ImageSpec &spec, int &i, int &j, float &ifrac, float &jfrac); /// Called when the requested texture is missing, fills in the /// results. bool missing_texture (TextureOpt &options, float *result); /// Handle gray-to-RGB promotion. void fill_gray_channels (const ImageSpec &spec, TextureOpt &options, float *result); static bool wrap_periodic_sharedborder (int &coord, int origin, int width); static const wrap_impl wrap_functions[]; /// Helper function for lat-long environment maps: compute a "pole" /// pixel that's the average of all of row y. This will only be /// called for levels where the whole mipmap level fits on one tile. const float *pole_color (TextureFile &texturefile, PerThreadInfo *thread_info, const ImageCacheFile::LevelInfo &levelinfo, TileRef &tile, int subimage, int miplevel, int pole); /// Helper function for lat-long environment maps: called near pole /// regions, this figures out the average pole color and fades to it /// right at the pole, and also adjusts weight so that the regular /// interpolated texture color will be added in correctly. /// This should only be called on the edge texels. void fade_to_pole (float t, float *accum, float &weight, TextureFile &texturefile, PerThreadInfo *thread_info, const ImageCacheFile::LevelInfo &levelinfo, TextureOpt &options, int miplevel, int nchannels); /// Perform short unit tests. void unit_test_texture (); /// Internal error reporting routine, with printf-like arguments. /// /// void error (const char *message, ...) const TINYFORMAT_WRAP_FORMAT (void, error, const, std::ostringstream msg;, msg, append_error(msg.str());) /// Append a string to the current error message void append_error (const std::string& message) const; void printstats () const; // Debugging aid void visualize_ellipse (const std::string &name, float dsdx, float dtdx, float dsdy, float dtdy, float sblur, float tblur); ImageCacheImpl *m_imagecache; Imath::M44f m_Mw2c; ///< world-to-"common" matrix Imath::M44f m_Mc2w; ///< common-to-world matrix bool m_gray_to_rgb; ///< automatically copy gray to rgb channels? /// Saved error string, per-thread /// mutable thread_specific_ptr< std::string > m_errormessage; Filter1D *hq_filter; ///< Better filter for magnification int m_statslevel; friend class TextureSystem; }; inline float TextureSystemImpl::anisotropic_aspect (float &majorlength, float &minorlength, TextureOpt& options, float &trueaspect) { float aspect = Imath::clamp (majorlength / minorlength, 1.0f, 1.0e6f); trueaspect = aspect; if (aspect > options.anisotropic) { aspect = options.anisotropic; // We have to clamp the ellipse to the maximum amount of anisotropy // that we allow. How do we do it? // a. Widen the short axis so we never alias along the major // axis, but we over-blur along the minor axis. I've never // been happy with this, it visibly overblurs. // b. Clamp the long axis so we don't blur, but might alias. // c. Split the difference, take the geometric mean, this makes // it slightly too blurry along the minor axis, slightly // aliasing along the major axis. You can't please everybody. if (options.conservative_filter) { #if 0 // Soltion (a) -- never alias by blurring more along minor axis minorlength = majorlength / options.anisotropic; #else // Solution (c) -- this is our default, usually a nice balance. // We used to take the geometric mean... // majorlength = sqrtf ((majorlength) * // (minorlength * options.anisotropic)); // ...but frankly I find the average to be a little more // visually pleasing. majorlength = 0.5f * ((majorlength) + (minorlength * options.anisotropic)); minorlength = majorlength / options.anisotropic; #endif } else { // Solution (b) -- alias slightly, never overblur majorlength = minorlength * options.anisotropic; } } return aspect; } inline void TextureSystemImpl::st_to_texel (float s, float t, TextureFile &texturefile, const ImageSpec &spec, int &i, int &j, float &ifrac, float &jfrac) { // As passed in, (s,t) map the texture to (0,1). Remap to texel coords. // Note that we have two modes, depending on the m_sample_border. if (texturefile.m_sample_border == 0) { // texel samples are at 0.5/res, 1.5/res, ..., (res-0.5)/res, s = s * spec.width + spec.x - 0.5f; t = t * spec.height + spec.y - 0.5f; } else { // first and last rows/columns are *exactly* on the boundary, // so samples are at 0, 1/(res-1), ..., 1. s = s * (spec.width-1) + spec.x; t = t * (spec.height-1) + spec.y; } ifrac = floorfrac (s, &i); jfrac = floorfrac (t, &j); // Now (i,j) are the integer coordinates of the texel to the // immediate "upper left" of the lookup point, and (ifrac,jfrac) are // the amount that the lookup point is actually offset from the // texel center (with (1,1) being all the way to the next texel down // and to the right). } } // end namespace pvt } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_TEXTURE_PVT_H openimageio-1.3.12~dfsg0.orig/src/libtexture/texoptions.cpp0000644000175000017500000001413512271062644022223 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include "dassert.h" #include "typedesc.h" #include "varyingref.h" #include "ustring.h" #include "thread.h" #include "fmath.h" #include "imageio.h" #include "texture.h" OIIO_NAMESPACE_ENTER { namespace { // anonymous static float default_blur = 0; static float default_width = 1; static float default_time = 0; static float default_bias = 0; static float default_fill = 0; static int default_samples = 1; static const ustring wrap_type_name[] = { // MUST match the order of TextureOptions::Wrap ustring("default"), ustring("black"), ustring("clamp"), ustring("periodic"), ustring("mirror"), ustring() }; } // end anonymous namespace /// Special private ctr that makes a canonical default TextureOptions. /// For use internal to libtexture. Users, don't call this! TextureOptions::TextureOptions () : firstchannel(0), nchannels(1), subimage(0), swrap(TextureOptions::WrapDefault), twrap(TextureOptions::WrapDefault), mipmode(TextureOptions::MipModeDefault), interpmode(TextureOptions::InterpSmartBicubic), anisotropic(32), conservative_filter(true), sblur(default_blur), tblur(default_blur), swidth(default_width), twidth(default_width), time(default_time), bias(default_bias), fill(default_fill), missingcolor(NULL), samples(default_samples), dresultds(NULL), dresultdt(NULL), rwrap(TextureOptions::WrapDefault), rblur(default_blur), rwidth(default_width), dresultdr(NULL), swrap_func(NULL), twrap_func(NULL), rwrap_func(NULL) { } TextureOptions::TextureOptions (const TextureOpt &opt) : firstchannel(opt.firstchannel), nchannels(opt.nchannels), subimage(opt.subimage), subimagename(opt.subimagename), swrap((Wrap)opt.swrap), twrap((Wrap)opt.twrap), mipmode((MipMode)opt.mipmode), interpmode((InterpMode)opt.interpmode), anisotropic(opt.anisotropic), conservative_filter(opt.conservative_filter), sblur((float *)&opt.sblur), tblur((float *)&opt.tblur), swidth((float *)&opt.swidth), twidth((float *)&opt.twidth), time((float *)&opt.time), bias((float *)&opt.bias), fill((float *)&opt.fill), missingcolor((void *)opt.missingcolor), samples((int *)&opt.samples), dresultds((float *)opt.dresultds), dresultdt((float *)opt.dresultdt), rwrap((Wrap)opt.rwrap), rblur((float *)&opt.rblur), rwidth((float *)&opt.rwidth), dresultdr((float *)opt.dresultdr), swrap_func(NULL), twrap_func(NULL), rwrap_func(NULL) { } TextureOpt::TextureOpt (const TextureOptions &opt, int index) : nchannels(opt.nchannels), firstchannel(opt.firstchannel), subimage(opt.subimage), subimagename(opt.subimagename), swrap((Wrap)opt.swrap), twrap((Wrap)opt.twrap), mipmode((MipMode)opt.mipmode), interpmode((InterpMode)opt.interpmode), anisotropic(opt.anisotropic), conservative_filter(opt.conservative_filter), sblur(opt.sblur[index]), tblur(opt.tblur[index]), swidth(opt.swidth[index]), twidth(opt.twidth[index]), fill(opt.fill[index]), missingcolor(opt.missingcolor.ptr() ? &opt.missingcolor[index] : NULL), dresultds(opt.dresultds), dresultdt(opt.dresultdt), time(opt.time[index]), bias(opt.bias[index]), samples(opt.samples[index]), rwrap((Wrap)opt.rwrap), rblur(opt.rblur[index]), rwidth(opt.rwidth[index]), dresultdr(opt.dresultdr), swrap_func(NULL), twrap_func(NULL), rwrap_func(NULL), envlayout(0) { } TextureOpt::Wrap TextureOpt::decode_wrapmode (const char *name) { for (int i = 0; i < (int)WrapLast; ++i) if (! strcmp (name, wrap_type_name[i].c_str())) return (Wrap) i; return TextureOpt::WrapDefault; } TextureOpt::Wrap TextureOpt::decode_wrapmode (ustring name) { for (int i = 0; i < (int)WrapLast; ++i) if (name == wrap_type_name[i]) return (Wrap) i; return TextureOpt::WrapDefault; } void TextureOpt::parse_wrapmodes (const char *wrapmodes, TextureOpt::Wrap &swrapcode, TextureOpt::Wrap &twrapcode) { char *swrap = (char *) alloca (strlen(wrapmodes)+1); const char *twrap; int i; for (i = 0; wrapmodes[i] && wrapmodes[i] != ','; ++i) swrap[i] = wrapmodes[i]; swrap[i] = 0; if (wrapmodes[i] == ',') twrap = wrapmodes + i+1; else twrap = swrap; swrapcode = decode_wrapmode (swrap); twrapcode = decode_wrapmode (twrap); } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libtexture/imagecache.cpp0000644000175000017500000031235712271062644022064 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "varyingref.h" #include "ustring.h" #include "filesystem.h" #include "thread.h" #include "fmath.h" #include "strutil.h" #include "sysutil.h" #include "timer.h" #include "optparser.h" #include "imageio.h" #include "imagebuf.h" #include "imagecache.h" #include "texture.h" #include "imagecache_pvt.h" #include #include #include OIIO_NAMESPACE_ENTER { using namespace pvt; namespace pvt { // The static perthread mutex needs to outlive the shared_image_cache // instance, so must be declared first in this file to avoid static // initialization order problems. mutex ImageCacheImpl::m_perthread_info_mutex; } namespace { // anonymous static shared_ptr shared_image_cache; static spin_mutex shared_image_cache_mutex; // Make some static ustring constants to avoid strcmp's static ustring s_resolution ("resolution"), s_texturetype ("texturetype"); static ustring s_textureformat ("textureformat"), s_fileformat ("fileformat"); static ustring s_format ("format"), s_cachedformat ("cachedformat"); static ustring s_channels ("channels"), s_cachedpixeltype ("cachedpixeltype"); static ustring s_exists ("exists"); static ustring s_subimages ("subimages"), s_miplevels ("miplevels"); static ustring s_datawindow ("datawindow"), s_displaywindow ("displaywindow"); // Functor to compare filenames static bool filename_compare (const ImageCacheFileRef &a, const ImageCacheFileRef &b) { return a->filename() < b->filename(); } // Functor to compare read bytes, sort in descending order static bool bytesread_compare (const ImageCacheFileRef &a, const ImageCacheFileRef &b) { return a->bytesread() > b->bytesread(); } // Functor to compare read times, sort in descending order static bool iotime_compare (const ImageCacheFileRef &a, const ImageCacheFileRef &b) { return a->iotime() > b->iotime(); } // Functor to compare read rate (MB/s), sort in ascending order static bool iorate_compare (const ImageCacheFileRef &a, const ImageCacheFileRef &b) { double arate = a->bytesread()/(1024.0*1024.0) / a->iotime(); double brate = b->bytesread()/(1024.0*1024.0) / b->iotime(); return arate < brate; } }; // end anonymous namespace namespace pvt { // namespace pvt void ImageCacheStatistics::init () { // ImageCache stats: find_tile_calls = 0; find_tile_microcache_misses = 0; find_tile_cache_misses = 0; // tiles_created = 0; // tiles_current = 0; // tiles_peak = 0; files_totalsize = 0; bytes_read = 0; // open_files_created = 0; // open_files_current = 0; // open_files_peak = 0; unique_files = 0; fileio_time = 0; fileopen_time = 0; file_locking_time = 0; tile_locking_time = 0; find_file_time = 0; find_tile_time = 0; // TextureSystem stats: texture_queries = 0; texture_batches = 0; texture3d_queries = 0; texture3d_batches = 0; shadow_queries = 0; shadow_batches = 0; environment_queries = 0; environment_batches = 0; aniso_queries = 0; aniso_probes = 0; max_aniso = 1; closest_interps = 0; bilinear_interps = 0; cubic_interps = 0; file_retry_success = 0; tile_retry_success = 0; } void ImageCacheStatistics::merge (const ImageCacheStatistics &s) { // ImageCache stats: find_tile_calls += s.find_tile_calls; find_tile_microcache_misses += s.find_tile_microcache_misses; find_tile_cache_misses += s.find_tile_cache_misses; // tiles_created += s.tiles_created; // tiles_current += s.tiles_current; // tiles_peak += s.tiles_peak; files_totalsize += s.files_totalsize; bytes_read += s.bytes_read; // open_files_created += s.open_files_created; // open_files_current += s.open_files_current; // open_files_peak += s.open_files_peak; unique_files += s.unique_files; fileio_time += s.fileio_time; fileopen_time += s.fileopen_time; file_locking_time += s.file_locking_time; tile_locking_time += s.tile_locking_time; find_file_time += s.find_file_time; find_tile_time += s.find_tile_time; // TextureSystem stats: texture_queries += s.texture_queries; texture_batches += s.texture_batches; texture3d_queries += s.texture3d_queries; texture3d_batches += s.texture3d_batches; shadow_queries += s.shadow_queries; shadow_batches += s.shadow_batches; environment_queries += s.environment_queries; environment_batches += s.environment_batches; aniso_queries += s.aniso_queries; aniso_probes += s.aniso_probes; max_aniso = std::max (max_aniso, s.max_aniso); closest_interps += s.closest_interps; bilinear_interps += s.bilinear_interps; cubic_interps += s.cubic_interps; file_retry_success += s.file_retry_success; tile_retry_success += s.tile_retry_success; } ImageCacheFile::LevelInfo::LevelInfo (const ImageSpec &spec_, const ImageSpec &nativespec_) : spec(spec_), nativespec(nativespec_) { full_pixel_range = (spec.x == spec.full_x && spec.y == spec.full_y && spec.z == spec.full_z && spec.width == spec.full_width && spec.height == spec.full_height && spec.depth == spec.full_depth); onetile = (spec.width <= spec.tile_width && spec.height <= spec.tile_height && spec.depth <= spec.tile_depth); polecolorcomputed = false; } ImageCacheFile::ImageCacheFile (ImageCacheImpl &imagecache, ImageCachePerThreadInfo *thread_info, ustring filename, ImageInput::Creator creator) : m_filename(filename), m_used(true), m_broken(false), m_texformat(TexFormatTexture), m_swrap(TextureOpt::WrapBlack), m_twrap(TextureOpt::WrapBlack), m_rwrap(TextureOpt::WrapBlack), m_envlayout(LayoutTexture), m_y_up(false), m_sample_border(false), m_tilesread(0), m_bytesread(0), m_timesopened(0), m_iotime(0), m_mipused(false), m_validspec(false), m_imagecache(imagecache), m_duplicate(NULL), m_total_imagesize(0), m_inputcreator(creator) { m_filename = imagecache.resolve_filename (m_filename.string()); // N.B. the file is not opened, the ImageInput is NULL. This is // reflected by the fact that m_validspec is false. m_Mlocal.makeIdentity(); m_Mproj.makeIdentity(); m_Mtex.makeIdentity(); m_Mras.makeIdentity(); } ImageCacheFile::~ImageCacheFile () { close (); } void ImageCacheFile::SubimageInfo::init (const ImageSpec &spec, bool forcefloat) { volume = (spec.depth > 1 || spec.full_depth > 1); full_pixel_range = (spec.x == spec.full_x && spec.y == spec.full_y && spec.z == spec.full_z && spec.width == spec.full_width && spec.height == spec.full_height && spec.depth == spec.full_depth); if (! full_pixel_range) { sscale = float(spec.full_width) / spec.width; soffset = float(spec.full_x-spec.x) / spec.width; tscale = float(spec.full_height) / spec.height; toffset = float(spec.full_y-spec.y) / spec.height; } else { sscale = tscale = 1.0f; soffset = toffset = 0.0f; } subimagename = ustring (spec.get_string_attribute("oiio:subimagename")); datatype = TypeDesc::FLOAT; if (! forcefloat) { // If we aren't forcing everything to be float internally, then // there are a few other types we allow. // But at present, it's only UINT8 and FLOAT. if (spec.format == TypeDesc::UINT8 /* future expansion: || spec.format == AnotherFormat ... */) datatype = spec.format; } channelsize = datatype.size(); pixelsize = channelsize * spec.nchannels; eightbit = (datatype == TypeDesc::UINT8); } bool ImageCacheFile::open (ImageCachePerThreadInfo *thread_info) { // N.B. open() does not need to lock the m_input_mutex, because open() // itself is only called by routines that hold the lock. // recursive_lock_guard_t guard (m_input_mutex); if (m_input) // Already opened return !m_broken; if (m_broken) // Already failed an open -- it's broken return false; if (m_inputcreator) m_input.reset (m_inputcreator()); else m_input.reset (ImageInput::create (m_filename.c_str(), m_imagecache.plugin_searchpath().c_str())); if (! m_input) { imagecache().error ("%s", OIIO::geterror().c_str()); m_broken = true; invalidate_spec (); return false; } ImageSpec configspec; if (imagecache().unassociatedalpha()) configspec.attribute ("oiio:UnassociatedAlpha", 1); ImageSpec nativespec, tempspec; m_broken = false; bool ok = true; for (int tries = 0; tries <= imagecache().failure_retries(); ++tries) { ok = m_input->open (m_filename.c_str(), nativespec, configspec); if (ok) { tempspec = nativespec; if (tries) // succeeded, but only after a failure! ++thread_info->m_stats.file_retry_success; (void) m_input->geterror (); // Eat the errors break; } // We failed. Wait a bit and try again. Sysutil::usleep (1000 * 100); // 100 ms } if (! ok) { imagecache().error ("%s", m_input->geterror().c_str()); m_broken = true; m_input.reset (); return false; } m_fileformat = ustring (m_input->format_name()); ++m_timesopened; m_imagecache.incr_open_files (); use (); // If we are simply re-opening a closed file, and the spec is still // valid, we're done, no need to reread the subimage and mip headers. if (validspec()) return true; // From here on, we know that we've opened this file for the very // first time. So read all the subimages, fill out all the fields // of the ImageCacheFile. m_subimages.clear (); int nsubimages = 0; // Since each subimage can potentially have its own mipmap levels, // keep track of the highest level discovered imagesize_t old_total_imagesize = m_total_imagesize; m_total_imagesize = 0; do { m_subimages.resize (nsubimages+1); SubimageInfo &si (subimageinfo(nsubimages)); int nmip = 0; do { tempspec = nativespec; if (nmip == 0) { // Things to do on MIP level 0, i.e. once per subimage si.init (tempspec, imagecache().forcefloat()); } if (tempspec.tile_width == 0 || tempspec.tile_height == 0) { si.untiled = true; int autotile = imagecache().autotile(); if (autotile) { // Automatically make it appear as if it's tiled if (imagecache().autoscanline()) { tempspec.tile_width = tempspec.width; } else { tempspec.tile_width = std::min (tempspec.width, autotile); } tempspec.tile_height = std::min (tempspec.height, autotile); tempspec.tile_depth = std::min (std::max(tempspec.depth,1), autotile); } else { // Don't auto-tile -- which really means, make it look like // a single tile that's as big as the whole image. // We round to a power of 2 because the texture system // currently requires power of 2 tile sizes. tempspec.tile_width = tempspec.width; tempspec.tile_height = tempspec.height; tempspec.tile_depth = tempspec.depth; } } // thread_info->m_stats.files_totalsize += tempspec.image_bytes(); m_total_imagesize += tempspec.image_bytes(); // All MIP levels need the same number of channels if (nmip > 0 && tempspec.nchannels != spec(nsubimages,0).nchannels) { // No idea what to do with a subimage that doesn't have the // same number of channels as the others, so just skip it. close (); m_broken = true; invalidate_spec (); return false; } // ImageCache can't store differing formats per channel tempspec.channelformats.clear(); LevelInfo levelinfo (tempspec, nativespec); si.levels.push_back (levelinfo); ++nmip; } while (m_input->seek_subimage (nsubimages, nmip, nativespec)); // Special work for non-MIPmapped images -- but only if "automip" // is on, it's a non-mipmapped image, and it doesn't have a // "textureformat" attribute (because that would indicate somebody // constructed it as texture and specifically wants it un-mipmapped). // But not volume textures -- don't auto MIP them for now. if (nmip == 1 && !si.volume && (tempspec.width > 1 || tempspec.height > 1 || tempspec.depth > 1)) si.unmipped = true; if (si.unmipped && imagecache().automip() && ! tempspec.find_attribute ("textureformat", TypeDesc::TypeString)) { int w = tempspec.full_width; int h = tempspec.full_height; int d = tempspec.full_depth; while (w > 1 || h > 1 || d > 1) { w = std::max (1, w/2); h = std::max (1, h/2); d = std::max (1, d/2); ImageSpec s = tempspec; s.width = w; s.height = h; s.depth = d; s.full_width = w; s.full_height = h; s.full_depth = d; if (imagecache().autotile()) { if (imagecache().autoscanline()) { s.tile_width = w; } else { s.tile_width = std::min (imagecache().autotile(), w); } s.tile_height = std::min (imagecache().autotile(), h); s.tile_depth = std::min (imagecache().autotile(), d); } else { s.tile_width = w; s.tile_height = h; s.tile_depth = d; } ++nmip; LevelInfo levelinfo (s, s); si.levels.push_back (levelinfo); } } if (si.untiled && ! imagecache().accept_untiled()) { imagecache().error ("%s was untiled, rejecting", m_filename.c_str()); m_broken = true; invalidate_spec (); m_input.reset (); return false; } if (si.unmipped && ! imagecache().accept_unmipped()) { imagecache().error ("%s was not MIP-mapped, rejecting", m_filename.c_str()); m_broken = true; invalidate_spec (); m_input.reset (); return false; } ++nsubimages; } while (m_input->seek_subimage (nsubimages, 0, nativespec)); ASSERT ((size_t)nsubimages == m_subimages.size()); thread_info->m_stats.files_totalsize -= old_total_imagesize; thread_info->m_stats.files_totalsize += m_total_imagesize; init_from_spec (); // Fill in the rest of the fields return true; } void ImageCacheFile::init_from_spec () { const ImageSpec &spec (this->spec(0,0)); const ImageIOParameter *p; // FIXME -- this should really be per-subimage if (spec.depth <= 1 && spec.full_depth <= 1) m_texformat = TexFormatTexture; else m_texformat = TexFormatTexture3d; if ((p = spec.find_attribute ("textureformat", TypeDesc::STRING))) { const char *textureformat = *(const char **)p->data(); for (int i = 0; i < TexFormatLast; ++i) if (! strcmp (textureformat, texture_format_name((TexFormat)i))) { m_texformat = (TexFormat) i; break; } // For textures marked as such, doctor the full_width/full_height to // not be non-sensical. if (m_texformat == TexFormatTexture) { for (int s = 0; s < subimages(); ++s) { for (int m = 0; m < miplevels(s); ++m) { ImageSpec &spec (this->spec(s,m)); if (spec.full_width > spec.width) spec.full_width = spec.width; if (spec.full_height > spec.height) spec.full_height = spec.height; if (spec.full_depth > spec.depth) spec.full_depth = spec.depth; } } } } if ((p = spec.find_attribute ("wrapmodes", TypeDesc::STRING))) { const char *wrapmodes = *(const char **)p->data(); TextureOpt::parse_wrapmodes (wrapmodes, m_swrap, m_twrap); m_rwrap = m_swrap; // FIXME(volume) -- rwrap } m_y_up = m_imagecache.latlong_y_up_default(); m_sample_border = false; if (m_texformat == TexFormatLatLongEnv || m_texformat == TexFormatCubeFaceEnv || m_texformat == TexFormatCubeFaceShadow) { if (spec.get_string_attribute ("oiio:updirection") == "y") m_y_up = true; else if (spec.get_string_attribute ("oiio:updirection") == "z") m_y_up = false; if (spec.get_int_attribute ("oiio:sampleborder") != 0) m_sample_border = true; } if (m_texformat == TexFormatCubeFaceEnv || m_texformat == TexFormatCubeFaceShadow) { int w = std::max (spec.full_width, spec.tile_width); int h = std::max (spec.full_height, spec.tile_height); if (spec.width == 3*w && spec.height == 2*h) m_envlayout = LayoutCubeThreeByTwo; else if (spec.width == w && spec.height == 6*h) m_envlayout = LayoutCubeOneBySix; else m_envlayout = LayoutTexture; } Imath::M44f c2w; m_imagecache.get_commontoworld (c2w); if ((p = spec.find_attribute ("worldtocamera", TypeDesc::TypeMatrix))) { const Imath::M44f *m = (const Imath::M44f *)p->data(); m_Mlocal = c2w * (*m); } if ((p = spec.find_attribute ("worldtoscreen", TypeDesc::TypeMatrix))) { const Imath::M44f *m = (const Imath::M44f *)p->data(); m_Mproj = c2w * (*m); } // FIXME -- compute Mtex, Mras // See if there's a SHA-1 hash in the image description std::string fing = spec.get_string_attribute ("oiio:SHA-1"); if (fing.length()) { m_fingerprint = ustring(fing); } else { // If there was no "oiio:SHA-1" attribute, search for it as // part of the ImageDescription. std::string desc = spec.get_string_attribute ("ImageDescription"); const char *prefix = "SHA-1="; size_t found = desc.rfind (prefix); if (found != std::string::npos) m_fingerprint = ustring (desc, found+strlen(prefix), 40); } m_mod_time = Filesystem::last_write_time (m_filename.string()); // Set all mipmap level read counts to zero int maxmip = 1; for (int s = 0, nsubimages = subimages(); s < nsubimages; ++s) maxmip = std::max (maxmip, miplevels(s)); m_mipreadcount.clear (); m_mipreadcount.resize(maxmip, 0); DASSERT (! m_broken); m_validspec = true; } bool ImageCacheFile::read_tile (ImageCachePerThreadInfo *thread_info, int subimage, int miplevel, int x, int y, int z, TypeDesc format, void *data) { recursive_lock_guard guard (m_input_mutex); if (! m_input && !m_broken) { // The file is already in the file cache, but the handle is // closed. We will need to re-open, so we must make sure there // will be enough file handles. // But wait, it's possible that somebody else is waiting on our // m_input_mutex, which we locked above. To avoid deadlock, we // need to release m_input_mutex while we close files. m_input_mutex.unlock (); imagecache().check_max_files (thread_info); // Now we're back, whew! Grab the lock again. m_input_mutex.lock (); } bool ok = open (thread_info); if (! ok) return false; // Mark if we ever use a mip level that's not the first if (miplevel > 0) m_mipused = true; // count how many times this mipmap level was read m_mipreadcount[miplevel]++; SubimageInfo &subinfo (subimageinfo(subimage)); // Special case for un-MIP-mapped if (subinfo.unmipped && miplevel != 0) { // For a non-base mip level of an unmipped file, release the // mutex on the ImageInput since upper levels don't need to // directly perform I/O. This prevents the deadlock that could // occur if another thread has one of the lower-level tiles and // itself blocks on the mutex (it's waiting for our mutex, we're // waiting on its tile to get filled with pixels). unlock_input_mutex (); bool ok = read_unmipped (thread_info, subimage, miplevel, x, y, z, format, data); // The lock_guard at the very top will try to unlock upon // destruction, to to make things right, we need to re-lock. lock_input_mutex (); return ok; } // Special case for untiled images -- need to do tile emulation if (subinfo.untiled) return read_untiled (thread_info, subimage, miplevel, x, y, z, format, data); // Ordinary tiled ImageSpec tmp; if (m_input->current_subimage() != subimage || m_input->current_miplevel() != miplevel) ok = m_input->seek_subimage (subimage, miplevel, tmp); if (ok) { for (int tries = 0; tries <= imagecache().failure_retries(); ++tries) { ok = m_input->read_tile (x, y, z, format, data); if (ok) { if (tries) // succeeded, but only after a failure! ++thread_info->m_stats.tile_retry_success; (void) m_input->geterror (); // Eat the errors break; } // We failed. Wait a bit and try again. Sysutil::usleep (1000 * 100); // 100 ms // TODO: should we attempt to close and re-open the file? } if (! ok) imagecache().error ("%s", m_input->geterror().c_str()); } if (ok) { size_t b = spec(subimage,miplevel).tile_bytes(); thread_info->m_stats.bytes_read += b; m_bytesread += b; ++m_tilesread; } return ok; } bool ImageCacheFile::read_unmipped (ImageCachePerThreadInfo *thread_info, int subimage, int miplevel, int x, int y, int z, TypeDesc format, void *data) { // We need a tile from an unmipmapped file, and it doesn't really // exist. So generate it out of thin air by interpolating pixels // from the next higher-res level. Of course, that may also not // exist, but it will be generated recursively, since we call // imagecache->get_pixels(), and it will ask for other tiles, which // will again call read_unmipped... eventually it will hit a subimage 0 // tile that actually exists. // N.B. No need to lock the mutex, since this is only called // from read_tile, which already holds the lock. // Figure out the size and strides for a single tile, make an ImageBuf // to hold it temporarily. const ImageSpec &spec (this->spec(subimage,miplevel)); int tw = spec.tile_width; int th = spec.tile_height; stride_t xstride=AutoStride, ystride=AutoStride, zstride=AutoStride; spec.auto_stride(xstride, ystride, zstride, format, spec.nchannels, tw, th); ImageSpec lospec (tw, th, spec.nchannels, TypeDesc::FLOAT); ImageBuf lores (lospec); // Figure out the range of texels we need for this tile x -= spec.x; y -= spec.y; z -= spec.z; int x0 = x - (x % spec.tile_width); int x1 = std::min (x0+spec.tile_width-1, spec.full_width-1); int y0 = y - (y % spec.tile_height); int y1 = std::min (y0+spec.tile_height-1, spec.full_height-1); // int z0 = z - (z % spec.tile_depth); // int z1 = std::min (z0+spec.tile_depth-1, spec.full_depth-1); // Save the contents of the per-thread microcache. This is because // a caller several levels up may be retaining a reference to // thread_info->tile and expecting it not to suddenly point to a // different tile id! It's a very reasonable assumption that if you // ask to read the last-found tile, it will still be the last-found // tile after the pixels are read. Well, except that below our call // to get_pixels may recursively trigger more tiles to be read, and // totally change the microcache. Simple solution: save & restore it. ImageCacheTileRef oldtile = thread_info->tile; ImageCacheTileRef oldlasttile = thread_info->lasttile; // Auto-mipping will totally thrash the cache if the user unwisely // sets it to be too small compared to the image file that needs to // automipped. So we simply override bad decisions by adjusting the // cache size to be a minimum of twice as big as any image we automip. imagecache().set_min_cache_size (2 * (long long)this->spec(subimage,0).image_bytes()); // Texel by texel, generate the values by interpolating filtered // lookups form the next finer subimage. const ImageSpec &upspec (this->spec(subimage,miplevel-1)); // next higher level float *bilerppels = (float *) alloca (4 * spec.nchannels * sizeof(float)); float *resultpel = (float *) alloca (spec.nchannels * sizeof(float)); bool ok = true; // FIXME(volume) -- loop over z, too for (int j = y0; j <= y1; ++j) { float yf = (j+0.5f) / spec.full_height; int ylow; float yfrac = floorfrac (yf * upspec.full_height - 0.5, &ylow); for (int i = x0; i <= x1; ++i) { float xf = (i+0.5f) / spec.full_width; int xlow; float xfrac = floorfrac (xf * upspec.full_width - 0.5, &xlow); ok &= imagecache().get_pixels (this, thread_info, subimage, miplevel-1, xlow, xlow+2, ylow, ylow+2, 0, 1, 0, spec.nchannels, TypeDesc::FLOAT, bilerppels); bilerp (bilerppels+0, bilerppels+spec.nchannels, bilerppels+2*spec.nchannels, bilerppels+3*spec.nchannels, xfrac, yfrac, spec.nchannels, resultpel); lores.setpixel (i-x0, j-y0, resultpel); } } // Now convert and copy those values out to the caller's buffer lores.get_pixels (0, tw, 0, th, 0, 1, format, data); // Restore the microcache to the way it was before. thread_info->tile = oldtile; thread_info->lasttile = oldlasttile; return ok; } // Helper routine for read_tile that handles the rare (but tricky) case // of reading a "tile" from a file that's scanline-oriented. bool ImageCacheFile::read_untiled (ImageCachePerThreadInfo *thread_info, int subimage, int miplevel, int x, int y, int z, TypeDesc format, void *data) { // N.B. No need to lock the input mutex, since this is only called // from read_tile, which already holds the lock. if (m_input->current_subimage() != subimage || m_input->current_miplevel() != miplevel) { ImageSpec tmp; if (! m_input->seek_subimage (subimage, miplevel, tmp)) { imagecache().error ("%s", m_input->geterror().c_str()); return false; } } // Strides for a single tile ImageSpec &spec (this->spec(subimage,miplevel)); int tw = spec.tile_width; int th = spec.tile_height; stride_t xstride=AutoStride, ystride=AutoStride, zstride=AutoStride; spec.auto_stride (xstride, ystride, zstride, format, spec.nchannels, tw, th); bool ok = true; if (imagecache().autotile()) { // Auto-tile is on, with a tile size that isn't the whole image. // We're only being asked for one tile, but since it's a // scanline image, we are forced to read (at the very least) a // whole row of tiles. So we add all those tiles to the cache, // if not already present, on the assumption that it's highly // likely that they will also soon be requested. // FIXME -- I don't think this works properly for 3D images size_t pixelsize = size_t (spec.nchannels * format.size()); // Because of the way we copy below, we need to allocate the // buffer to be an even multiple of the tile width, so round up. stride_t scanlinesize = tw * ((spec.width+tw-1)/tw); scanlinesize *= pixelsize; boost::scoped_array buf (new char [scanlinesize * th]); // a whole tile-row size int yy = y - spec.y; // counting from top scanline // [y0,y1] is the range of scanlines to read for a tile-row int y0 = yy - (yy % th); int y1 = std::min (y0 + th - 1, spec.height - 1); y0 += spec.y; y1 += spec.y; // Read the whole tile-row worth of scanlines ok = m_input->read_scanlines (y0, y1+1, z, format, (void *)&buf[0], pixelsize, scanlinesize); if (! ok) imagecache().error ("%s", m_input->geterror().c_str()); size_t b = (y1-y0+1) * spec.scanline_bytes(); thread_info->m_stats.bytes_read += b; m_bytesread += b; ++m_tilesread; // At this point, we aren't reading from the file any longer, // and to avoid deadlock, we MUST release the input lock prior // to any attempt to add_tile_to_cache, lest another thread add // the same tile to the cache before us but need the input mutex // to actually read the texels before marking it as pixels_ready. unlock_input_mutex (); // For all tiles in the tile-row, enter them into the cache if not // already there. Special case for the tile we're actually being // asked for -- save it in 'data' rather than adding a tile. int xx = x - spec.x; // counting from left row int x0 = xx - (xx % tw); // start of the tile we are retrieving for (int i = 0; i < spec.width; i += tw) { if (i == xx) { // This is the tile we've been asked for convert_image (spec.nchannels, tw, th, 1, &buf[x0 * pixelsize], format, pixelsize, scanlinesize, scanlinesize*th, data, format, xstride, ystride, zstride); } else { // Not the tile we asked for, but it's in the same // tile-row, so let's put it in the cache anyway so // it'll be there when asked for. TileID id (*this, subimage, miplevel, i+spec.x, y0, z); if (! imagecache().tile_in_cache (id, thread_info)) { ImageCacheTileRef tile; tile = new ImageCacheTile (id, &buf[i*pixelsize], format, pixelsize, scanlinesize, scanlinesize*th); ok &= tile->valid (); imagecache().add_tile_to_cache (tile, thread_info); } } } // The lock_guard inside the calling function, read_tile, passed // us the input_mutex locked, and expects to get it back the // same way, so we need to re-lock. lock_input_mutex (); } else { // No auto-tile -- the tile is the whole image ok = m_input->read_image (format, data, xstride, ystride, zstride); if (! ok) imagecache().error ("%s", m_input->geterror().c_str()); size_t b = spec.image_bytes(); thread_info->m_stats.bytes_read += b; m_bytesread += b; ++m_tilesread; // If we read the whole image, presumably we're done, so release // the file handle. close (); } return ok; } void ImageCacheFile::close () { // N.B. close() does not need to lock the m_input_mutex, because close() // itself is only called by routines that hold the lock. if (opened()) { m_input->close (); m_input.reset (); m_imagecache.decr_open_files (); } } void ImageCacheFile::release () { recursive_lock_guard guard (m_input_mutex); if (m_used) m_used = false; else close (); } void ImageCacheFile::invalidate () { recursive_lock_guard guard (m_input_mutex); close (); invalidate_spec (); m_broken = false; m_fingerprint.clear (); duplicate (NULL); // Eat any errors that occurred in the open/close while (! imagecache().geterror().empty()) ; } ImageCacheFile * ImageCacheImpl::find_file (ustring filename, ImageCachePerThreadInfo *thread_info, ImageInput::Creator creator, bool header_only) { // Debugging aid: attribute "substitute_image" forces all image // references to be to one named file. if (m_substitute_image) filename = m_substitute_image; // Shortcut - check the per-thread microcache before grabbing a more // expensive lock on the shared file cache. ImageCacheFile *tf = thread_info->find_file (filename); // Part 1 - make sure the ImageCacheFile entry exists and is in the // file cache. For this part, we need to lock the file cache. bool newfile = false; if (! tf) { // was not found in microcache #if IMAGECACHE_TIME_STATS Timer timer; #endif size_t bin = m_files.lock_bin (filename); FilenameMap::iterator found = m_files.find (filename, false); if (found) { tf = found->second.get(); } else { // No such entry in the file cache. Add it, but don't open yet. tf = new ImageCacheFile (*this, thread_info, filename, creator); m_files.insert (filename, tf, false); newfile = true; } m_files.unlock_bin (bin); if (newfile) check_max_files (thread_info); thread_info->filename (filename, tf); // add to the microcache #if IMAGECACHE_TIME_STATS thread_info->m_stats.find_file_time += timer(); #endif } // Part 2 - open tihe file if it's never been opened before. // No need to have the file cache locked for this, though we lock // the tf->m_input_mutex if we need to open it. if (! tf->validspec()) { Timer timer; recursive_lock_guard guard (tf->m_input_mutex); if (! tf->validspec()) { tf->open (thread_info); DASSERT (tf->m_broken || tf->validspec()); double createtime = timer(); ImageCacheStatistics &stats (thread_info->m_stats); stats.fileio_time += createtime; stats.fileopen_time += createtime; tf->iotime() += createtime; // What if we've opened another file, with a different name, // but the SAME pixels? It can happen! Bad user, bad! But // let's save them from their own foolishness. if (tf->fingerprint() && m_deduplicate) { // std::cerr << filename << " hash=" << tf->fingerprint() << "\n"; ImageCacheFile *dup = find_fingerprint (tf->fingerprint(), tf); if (dup != tf) { // Already in fingerprints -- mark this one as a // duplicate, but ONLY if we don't have other // reasons not to consider them true duplicates (the // fingerprint only considers source image pixel values. // FIXME -- be sure to add extra tests // here if more metadata have significance later! bool match = (tf->subimages() == dup->subimages()); match &= (tf->m_swrap == dup->m_swrap && tf->m_twrap == dup->m_twrap && tf->m_rwrap == dup->m_rwrap && tf->m_envlayout == dup->m_envlayout && tf->m_y_up == dup->m_y_up && tf->m_sample_border == dup->m_sample_border); for (int s = 0, e = tf->subimages(); match && s < e; ++s) { match &= (tf->datatype(s) == dup->datatype(s)); } if (match) { tf->duplicate (dup); tf->close (); // std::cerr << " duplicates " // << fingerfound->second.get()->filename() << "\n"; } } } #if IMAGECACHE_TIME_STATS stats.find_file_time += timer()-createtime; #endif } } // if this is a duplicate texture, switch to the canonical copy if (tf->duplicate()) { if (! header_only) tf = tf->duplicate(); // N.B. If looking up header info (i.e., get_image_info, rather // than getting pixels, use the original not the duplicate, since // metadata may differ even if pixels are identical). } else { // not a duplicate -- if opening the first time, count as unique if (newfile) ++thread_info->m_stats.unique_files; } if (! header_only) tf->use (); // Mark it as recently used return tf; } ImageCacheFile * ImageCacheImpl::find_fingerprint (ustring finger, ImageCacheFile *file) { spin_lock lock (m_fingerprints_mutex); FingerprintMap::iterator found = m_fingerprints.find (finger); if (found == m_fingerprints.end()) { // Not already in the fingerprint list -- add it m_fingerprints[finger] = file; } else { // In the list -- return its mapping file = found->second.get(); } return file; } void ImageCacheImpl::clear_fingerprints () { spin_lock lock (m_fingerprints_mutex); m_fingerprints.clear (); } void ImageCacheImpl::check_max_files (ImageCachePerThreadInfo *thread_info) { #if 0 if (! (m_stat_open_files_created % 16) || m_stat_open_files_current >= m_max_open_files) { std::cerr << "open files " << m_stat_open_files_current << ", max = " << m_max_open_files << "\n"; std::cout << " ImageInputs : " << m_stat_open_files_created << " created, " << m_stat_open_files_current << " current, " << m_stat_open_files_peak << " peak\n"; } #endif // Early out if we aren't exceeding the open file handle limit if (m_stat_open_files_current < m_max_open_files) return; // Try to grab the file_sweep_mutex lock. If somebody else holds it, // just return -- leave the handle limit enforcement to whomever is // already in this function, no need for two threads to do it at // once. If this means we may ephemerally be over the handle limit, // so be it. if (! m_file_sweep_mutex.try_lock()) return; // Now, what we want to do is have a "clock hand" that sweeps across // the cache, releasing files that haven't been used for a long // time. Because of multi-thread, rather than keep an iterator // around for this (which could be invalidated since the last time // we used it), we just remember the filename of the next file to // check, then look it up fresh. That is m_file_sweep_name. // If we don't have a valid file_sweep_name, establish it by just // looking up the filename of the first entry in the file cache. if (! m_file_sweep_name) { FilenameMap::iterator sweep = m_files.begin(); ASSERT (sweep != m_files.end() && "no way m_files can be empty and have too many files open"); m_file_sweep_name = sweep->first; } // Get a (locked) iterator for the next file to be examined. FilenameMap::iterator sweep = m_files.find (m_file_sweep_name); // Loop while we still have too many files open. Also, be careful // of looping for too long, exit the loop if we just keep spinning // uncontrollably. int full_loops = 0; FilenameMap::iterator end = m_files.end(); while (m_stat_open_files_current >= m_max_open_files && full_loops <= 100) { // If we have fallen off the end of the cache, loop back to the // beginning and increment our full_loops count. if (sweep == end) { sweep = m_files.begin(); ++full_loops; } // If we're STILL at the end, it must be that somehow the entire // cache is empty. So just declare ourselves done. if (sweep == end) break; DASSERT (sweep->second); sweep->second->release (); // May reduce open files ++sweep; } // OK, by this point we have either closed enough files to be below // the limit again, or the cache is empty, or we've looped over the // cache too many times and are giving up. // Now we must save the filename for next time. Just set it to an // empty string if we don't have a valid iterator at this point. m_file_sweep_name = (sweep == end ? ustring() : sweep->first); m_file_sweep_mutex.unlock (); // N.B. As we exit, the iterators will go out of scope and we will // retain no locks on the cache. } void ImageCacheImpl::set_min_cache_size (long long newsize) { long long oldsize = m_max_memory_bytes; while (newsize > oldsize) { if (atomic_compare_and_exchange ((long long *)&m_max_memory_bytes, oldsize, newsize)) return; oldsize = m_max_memory_bytes; } } ImageCacheTile::ImageCacheTile (const TileID &id, ImageCachePerThreadInfo *thread_info, bool read_now) : m_id (id), m_valid(true) // , m_used(true) { m_used = true; m_pixels_ready = false; m_pixels_size = 0; if (read_now) { read (thread_info); } id.file().imagecache().incr_tiles (0); // mem counted separately in read } ImageCacheTile::ImageCacheTile (const TileID &id, const void *pels, TypeDesc format, stride_t xstride, stride_t ystride, stride_t zstride) : m_id (id) // , m_used(true) { m_used = true; m_pixels_size = 0; ImageCacheFile &file (m_id.file ()); const ImageSpec &spec (file.spec(id.subimage(), id.miplevel())); size_t size = memsize_needed (); ASSERT_MSG (size > 0 && memsize() == 0, "size was %llu, memsize = %llu", (unsigned long long)size, (unsigned long long)memsize()); m_pixels.reset (new char [m_pixels_size = size]); size_t dst_pelsize = file.pixelsize(id.subimage()); m_valid = convert_image (spec.nchannels, spec.tile_width, spec.tile_height, spec.tile_depth, pels, format, xstride, ystride, zstride, &m_pixels[0], file.datatype(id.subimage()), dst_pelsize, dst_pelsize * spec.tile_width, dst_pelsize * spec.tile_width * spec.tile_height); id.file().imagecache().incr_tiles (size); m_pixels_ready = true; // Caller sent us the pixels, no read necessary // FIXME -- for shadow, fill in mindepth, maxdepth } ImageCacheTile::~ImageCacheTile () { m_id.file().imagecache().decr_tiles (memsize ()); } void ImageCacheTile::read (ImageCachePerThreadInfo *thread_info) { size_t size = memsize_needed (); ASSERT (memsize() == 0 && size > 0); m_pixels.reset (new char [m_pixels_size = size]); ImageCacheFile &file (m_id.file()); m_valid = file.read_tile (thread_info, m_id.subimage(), m_id.miplevel(), m_id.x(), m_id.y(), m_id.z(), file.datatype(m_id.subimage()), &m_pixels[0]); m_id.file().imagecache().incr_mem (size); if (! m_valid) { m_used = false; // Don't let it hold mem if invalid #if 0 std::cerr << "(1) error reading tile " << m_id.x() << ' ' << m_id.y() << ' ' << m_id.z() << " subimg=" << m_id.subimage() << " mip=" << m_id.miplevel() << " from " << file.filename() << "\n"; #endif } m_pixels_ready = true; // FIXME -- for shadow, fill in mindepth, maxdepth } void ImageCacheTile::wait_pixels_ready () const { atomic_backoff backoff; while (! m_pixels_ready) { backoff(); } } const void * ImageCacheTile::data (int x, int y, int z) const { const ImageSpec &spec = m_id.file().spec (m_id.subimage(), m_id.miplevel()); size_t w = spec.tile_width; size_t h = spec.tile_height; size_t d = spec.tile_depth; DASSERT (d >= 1); x -= m_id.x(); y -= m_id.y(); z -= m_id.z(); if (x < 0 || x >= (int)w || y < 0 || y >= (int)h || z < 0 || z >= (int)d) return NULL; size_t offset = ((z * h + y) * w + x) * m_id.file().pixelsize(m_id.subimage()); return (const void *)&m_pixels[offset]; } ImageCacheImpl::ImageCacheImpl () : m_perthread_info (&cleanup_perthread_info) { init (); } void ImageCacheImpl::init () { m_max_open_files = 100; m_max_memory_bytes = 256 * 1024 * 1024; // 256 MB default cache size m_autotile = 0; m_autoscanline = false; m_automip = false; m_forcefloat = false; m_accept_untiled = true; m_accept_unmipped = true; m_read_before_insert = false; m_deduplicate = true; m_unassociatedalpha = false; m_failure_retries = 0; m_latlong_y_up_default = true; m_Mw2c.makeIdentity(); m_mem_used = 0; m_statslevel = 0; m_stat_tiles_created = 0; m_stat_tiles_current = 0; m_stat_tiles_peak = 0; m_stat_open_files_created = 0; m_stat_open_files_current = 0; m_stat_open_files_peak = 0; // Allow environment variable to override default options const char *options = getenv ("OPENIMAGEIO_IMAGECACHE_OPTIONS"); if (options) attribute ("options", options); } ImageCacheImpl::~ImageCacheImpl () { printstats (); erase_perthread_info (); } void ImageCacheImpl::mergestats (ImageCacheStatistics &stats) const { stats.init (); lock_guard lock (m_perthread_info_mutex); for (size_t i = 0; i < m_all_perthread_info.size(); ++i) stats.merge (m_all_perthread_info[i]->m_stats); } std::string ImageCacheImpl::onefile_stat_line (const ImageCacheFileRef &file, int i, bool includestats) const { // FIXME -- make meaningful stat printouts for multi-image textures std::ostringstream out; const ImageSpec &spec (file->spec(0,0)); const char *formatcode = "u8"; switch (spec.format.basetype) { case TypeDesc::UINT8 : formatcode = "u8 "; break; case TypeDesc::INT8 : formatcode = "i8 "; break; case TypeDesc::UINT16 : formatcode = "u16"; break; case TypeDesc::INT16 : formatcode = "i16"; break; case TypeDesc::UINT : formatcode = "u32"; break; case TypeDesc::INT : formatcode = "i32"; break; case TypeDesc::UINT64 : formatcode = "i64"; break; case TypeDesc::INT64 : formatcode = "u64"; break; case TypeDesc::HALF : formatcode = "f16"; break; case TypeDesc::FLOAT : formatcode = "f32"; break; case TypeDesc::DOUBLE : formatcode = "f64"; break; default: break; } if (i >= 0) out << Strutil::format ("%7d ", i); if (includestats) out << Strutil::format ("%4llu %5llu %6.1f %9s ", (unsigned long long) file->timesopened(), (unsigned long long) file->tilesread(), file->bytesread()/1024.0/1024.0, Strutil::timeintervalformat(file->iotime()).c_str()); if (file->subimages() > 1) out << Strutil::format ("%3d face x%d.%s", file->subimages(), spec.nchannels, formatcode); else out << Strutil::format ("%4dx%4dx%d.%s", spec.width, spec.height, spec.nchannels, formatcode); out << " " << file->filename(); if (file->duplicate()) { out << " DUPLICATES " << file->duplicate()->filename(); return out.str(); } for (int s = 0; s < file->subimages(); ++s) if (file->subimageinfo(s).untiled) { out << " UNTILED"; break; } if (automip()) { // FIXME -- we should directly measure whether we ever automipped // this file. This is a little inexact. for (int s = 0; s < file->subimages(); ++s) if (file->subimageinfo(s).unmipped) { out << " UNMIPPED"; break; } } if (! file->mipused()) { for (int s = 0; s < file->subimages(); ++s) if (! file->subimageinfo(s).unmipped) { out << " MIP-UNUSED"; break; } } if (file->mipreadcount().size() > 1) { out << " MIP-COUNT ["; int nmip = (int) file->mipreadcount().size(); for (int c = 0; c < nmip; c++) out << (c ? "," : "") << file->mipreadcount()[c]; out << "]"; } return out.str (); } std::string ImageCacheImpl::getstats (int level) const { // Merge all the threads ImageCacheStatistics stats; mergestats (stats); std::ostringstream out; if (level > 0) { out << "OpenImageIO ImageCache statistics ("; { spin_lock guard (shared_image_cache_mutex); if ((void *)this == (void *)shared_image_cache.get()) out << "shared"; else out << (void *)this; } out << ") ver " << OIIO_VERSION_STRING << "\n"; if (stats.unique_files) { out << " Images : " << stats.unique_files << " unique\n"; out << " ImageInputs : " << m_stat_open_files_created << " created, " << m_stat_open_files_current << " current, " << m_stat_open_files_peak << " peak\n"; out << " Total size of all images referenced : " << Strutil::memformat (stats.files_totalsize) << "\n"; out << " Read from disk : " << Strutil::memformat (stats.bytes_read) << "\n"; } else { out << " No images opened\n"; } if (stats.find_file_time > 0.001) out << " Find file time : " << Strutil::timeintervalformat (stats.find_file_time) << "\n"; if (stats.fileio_time > 0.001) { out << " File I/O time : " << Strutil::timeintervalformat (stats.fileio_time); { lock_guard lock (m_perthread_info_mutex); size_t nthreads = m_all_perthread_info.size(); if (nthreads > 1) { double perthreadtime = stats.fileio_time / (float)nthreads; out << " (" << Strutil::timeintervalformat (perthreadtime) << " average per thread)"; } } out << "\n"; out << " File open time only : " << Strutil::timeintervalformat (stats.fileopen_time) << "\n"; } if (stats.file_locking_time > 0.001) out << " File mutex locking time : " << Strutil::timeintervalformat (stats.file_locking_time) << "\n"; if (m_stat_tiles_created > 0) { out << " Tiles: " << m_stat_tiles_created << " created, " << m_stat_tiles_current << " current, " << m_stat_tiles_peak << " peak\n"; out << " total tile requests : " << stats.find_tile_calls << "\n"; out << " micro-cache misses : " << stats.find_tile_microcache_misses << " (" << 100.0*(double)stats.find_tile_microcache_misses/(double)stats.find_tile_calls << "%)\n"; out << " main cache misses : " << stats.find_tile_cache_misses << " (" << 100.0*(double)stats.find_tile_cache_misses/(double)stats.find_tile_calls << "%)\n"; } out << " Peak cache memory : " << Strutil::memformat (m_mem_used) << "\n"; if (stats.tile_locking_time > 0.001) out << " Tile mutex locking time : " << Strutil::timeintervalformat (stats.tile_locking_time) << "\n"; if (stats.find_tile_time > 0.001) out << " Find tile time : " << Strutil::timeintervalformat (stats.find_tile_time) << "\n"; if (stats.file_retry_success || stats.tile_retry_success) out << " Failure reads followed by unexplained success: " << stats.file_retry_success << " files, " << stats.tile_retry_success << " tiles\n"; } // Gather file list and statistics size_t total_opens = 0, total_tiles = 0; imagesize_t total_bytes = 0; size_t total_untiled = 0, total_unmipped = 0, total_duplicates = 0; double total_iotime = 0; std::vector files; { for (FilenameMap::iterator f = m_files.begin(); f != m_files.end(); ++f) { const ImageCacheFileRef &file (f->second); files.push_back (file); total_opens += file->timesopened(); total_tiles += file->tilesread(); total_bytes += file->bytesread(); total_iotime += file->iotime(); if (file->duplicate()) { ++total_duplicates; continue; } bool found_untiled = false, found_unmipped = false; for (int s = 0; s < file->subimages(); ++s) { found_untiled |= file->subimageinfo(s).untiled; found_unmipped |= file->subimageinfo(s).unmipped; } if (found_untiled) ++total_untiled; if (found_unmipped) ++total_unmipped; } } if (level >= 2 && files.size()) { out << " Image file statistics:\n"; out << " opens tiles MB read I/O time res File\n"; std::sort (files.begin(), files.end(), filename_compare); for (size_t i = 0; i < files.size(); ++i) { const ImageCacheFileRef &file (files[i]); ASSERT (file); if (file->broken() || file->subimages() == 0) { out << " BROKEN " << file->filename() << "\n"; continue; } out << onefile_stat_line (file, i+1) << "\n"; } out << Strutil::format ("\n Tot: %4llu %5llu %6.1f %9s\n", (unsigned long long) total_opens, (unsigned long long) total_tiles, total_bytes/1024.0/1024.0, Strutil::timeintervalformat(total_iotime).c_str()); } // Try to point out hot spots if (level > 0) { if (total_duplicates) out << " " << total_duplicates << " were exact duplicates of other images\n"; if (total_untiled || (total_unmipped && automip())) { out << " " << total_untiled << " not tiled, " << total_unmipped << " not MIP-mapped\n"; #if 0 if (files.size() >= 50) { out << " Untiled/unmipped files were:\n"; for (size_t i = 0; i < files.size(); ++i) { const ImageCacheFileRef &file (files[i]); if (file->untiled() || (file->unmipped() && automip())) out << onefile_stat_line (file, -1) << "\n"; } } #endif } if (files.size() >= 50) { const int topN = 3; std::sort (files.begin(), files.end(), bytesread_compare); out << " Top files by bytes read:\n"; for (int i = 0; i < std::min (topN, files.size()); ++i) { if (files[i]->broken() || !files[i]->validspec()) continue; out << Strutil::format (" %d %6.1f MB (%4.1f%%) ", i+1, files[i]->bytesread()/1024.0/1024.0, 100.0 * (files[i]->bytesread() / (double)total_bytes)); out << onefile_stat_line (files[i], -1, false) << "\n"; } std::sort (files.begin(), files.end(), iotime_compare); out << " Top files by I/O time:\n"; for (int i = 0; i < std::min (topN, files.size()); ++i) { if (files[i]->broken() || !files[i]->validspec()) continue; out << Strutil::format (" %d %9s (%4.1f%%) ", i+1, Strutil::timeintervalformat (files[i]->iotime()).c_str(), 100.0 * files[i]->iotime() / total_iotime); out << onefile_stat_line (files[i], -1, false) << "\n"; } std::sort (files.begin(), files.end(), iorate_compare); out << " Files with slowest I/O rates:\n"; int n = 0; BOOST_FOREACH (const ImageCacheFileRef &file, files) { if (file->broken() || !file->validspec()) continue; if (file->iotime() < 0.25) continue; double mb = file->bytesread()/(1024.0*1024.0); double r = mb / file->iotime(); out << Strutil::format (" %d %6.2f MB/s (%.2fMB/%.2fs) ", n+1, r, mb, file->iotime()); out << onefile_stat_line (file, -1, false) << "\n"; if (++n >= topN) break; } if (n == 0) out << " (nothing took more than 0.25s)\n"; double fast = files.back()->bytesread()/(1024.0*1024.0) / files.back()->iotime(); out << Strutil::format (" (fastest was %.1f MB/s)\n", fast); } } return out.str(); } void ImageCacheImpl::printstats () const { if (m_statslevel == 0) return; std::cout << getstats (m_statslevel) << "\n\n"; } void ImageCacheImpl::reset_stats () { { lock_guard lock (m_perthread_info_mutex); for (size_t i = 0; i < m_all_perthread_info.size(); ++i) m_all_perthread_info[i]->m_stats.init (); } { for (FilenameMap::iterator f = m_files.begin(); f != m_files.end(); ++f) { const ImageCacheFileRef &file (f->second); file->m_timesopened = 0; file->m_tilesread = 0; file->m_bytesread = 0; file->m_iotime = 0; } } } bool ImageCacheImpl::attribute (const std::string &name, TypeDesc type, const void *val) { bool do_invalidate = false; bool force_invalidate = false; if (name == "options" && type == TypeDesc::STRING) { return optparser (*this, *(const char **)val); } if (name == "max_open_files" && type == TypeDesc::INT) { m_max_open_files = *(const int *)val; } else if (name == "max_memory_MB" && type == TypeDesc::FLOAT) { float size = *(const float *)val; #ifdef NDEBUG size = std::max (size, 10.0f); // Don't let users choose < 10 MB #else size = std::max (size, 1.0f); // But let developers debugging do it #endif m_max_memory_bytes = size_t(size * 1024 * 1024); } else if (name == "max_memory_MB" && type == TypeDesc::INT) { float size = *(const int *)val; #ifdef NDEBUG size = std::max (size, 10.0f); // Don't let users choose < 10 MB #else size = std::max (size, 1.0f); // But let developers debugging do it #endif m_max_memory_bytes = size_t(size) * 1024 * 1024; } else if (name == "searchpath" && type == TypeDesc::STRING) { std::string s = std::string (*(const char **)val); if (s != m_searchpath) { m_searchpath = s; Filesystem::searchpath_split (m_searchpath, m_searchdirs, true); do_invalidate = true; // in case file can be found with new path force_invalidate = true; } } else if (name == "plugin_searchpath" && type == TypeDesc::STRING) { m_plugin_searchpath = std::string (*(const char **)val); } else if (name == "statistics:level" && type == TypeDesc::INT) { m_statslevel = *(const int *)val; } else if (name == "autotile" && type == TypeDesc::INT) { int a = pow2roundup (*(const int *)val); // guarantee pow2 // Clamp to minimum 8x8 tiles to protect against stupid user who // think this is a boolean rather than the tile size. Unless // we're in DEBUG mode, then allow developers to play with fire. #ifdef NDEBUG if (a > 0 && a < 8) a = 8; #endif if (a != m_autotile) { m_autotile = a; do_invalidate = true; } } else if (name == "autoscanline" && type == TypeDesc::INT) { int a = *(const int *)val; if (a != m_autoscanline) { m_autoscanline = a; do_invalidate = true; } } else if (name == "automip" && type == TypeDesc::INT) { int a = *(const int *)val; if (a != m_automip) { m_automip = a; do_invalidate = true; } } else if (name == "forcefloat" && type == TypeDesc::INT) { int a = *(const int *)val; if (a != m_forcefloat) { m_forcefloat = a; do_invalidate = true; } } else if (name == "accept_untiled" && type == TypeDesc::INT) { int a = *(const int *)val; if (a != m_accept_untiled) { m_accept_untiled = a; do_invalidate = true; } } else if (name == "accept_unmipped" && type == TypeDesc::INT) { int a = *(const int *)val; if (a != m_accept_unmipped) { m_accept_unmipped = a; do_invalidate = true; } } else if (name == "read_before_insert" && type == TypeDesc::INT) { int r = *(const int *)val; if (r != m_read_before_insert) { m_read_before_insert = r; do_invalidate = true; } } else if (name == "deduplicate" && type == TypeDesc::INT) { int r = *(const int *)val; if (r != m_deduplicate) { m_deduplicate = r; do_invalidate = true; } } else if (name == "unassociatedalpha" && type == TypeDesc::INT) { int r = *(const int *)val; if (r != m_unassociatedalpha) { m_unassociatedalpha = r; do_invalidate = true; } } else if (name == "failure_retries" && type == TypeDesc::INT) { m_failure_retries = *(const int *)val; } else if (name == "latlong_up" && type == TypeDesc::STRING) { bool y_up = ! strcmp ("y", *(const char **)val); if (y_up != m_latlong_y_up_default) { m_latlong_y_up_default = y_up; do_invalidate = true; } } else if (name == "substitute_image" && type == TypeDesc::STRING) { m_substitute_image = ustring (*(const char **)val); do_invalidate = true; } else { // Otherwise, unknown name return false; } if (do_invalidate) invalidate_all (force_invalidate); return true; } bool ImageCacheImpl::getattribute (const std::string &name, TypeDesc type, void *val) { #define ATTR_DECODE(_name,_ctype,_src) \ if (name == _name && type == BaseTypeFromC<_ctype>::value) { \ *(_ctype *)(val) = (_ctype)(_src); \ return true; \ } ATTR_DECODE ("max_open_files", int, m_max_open_files); ATTR_DECODE ("max_memory_MB", float, m_max_memory_bytes/(1024.0*1024.0)); ATTR_DECODE ("max_memory_MB", int, m_max_memory_bytes/(1024*1024)); ATTR_DECODE ("statistics:level", int, m_statslevel); ATTR_DECODE ("autotile", int, m_autotile); ATTR_DECODE ("autoscanline", int, m_autoscanline); ATTR_DECODE ("automip", int, m_automip); ATTR_DECODE ("forcefloat", int, m_forcefloat); ATTR_DECODE ("accept_untiled", int, m_accept_untiled); ATTR_DECODE ("accept_unmipped", int, m_accept_unmipped); ATTR_DECODE ("read_before_insert", int, m_read_before_insert); ATTR_DECODE ("deduplicate", int, m_deduplicate); ATTR_DECODE ("unassociatedalpha", int, m_unassociatedalpha); ATTR_DECODE ("failure_retries", int, m_failure_retries); // The cases that don't fit in the simple ATTR_DECODE scheme if (name == "searchpath" && type == TypeDesc::STRING) { *(ustring *)val = m_searchpath; return true; } if (name == "plugin_searchpath" && type == TypeDesc::STRING) { *(ustring *)val = m_plugin_searchpath; return true; } if (name == "worldtocommon" && (type == TypeDesc::TypeMatrix || type == TypeDesc(TypeDesc::FLOAT,16))) { *(Imath::M44f *)val = m_Mw2c; return true; } if (name == "commontoworld" && (type == TypeDesc::TypeMatrix || type == TypeDesc(TypeDesc::FLOAT,16))) { *(Imath::M44f *)val = m_Mc2w; return true; } if (name == "latlong_up" && type == TypeDesc::STRING) { *(const char **)val = ustring (m_latlong_y_up_default ? "y" : "z").c_str(); return true; } if (name == "substitute_image" && type == TypeDesc::STRING) { *(const char **)val = m_substitute_image.c_str(); return true; } // Stats we can just grab ATTR_DECODE ("stat:cache_memory_used", long long, m_mem_used); ATTR_DECODE ("stat:tiles_created", int, m_stat_tiles_created); ATTR_DECODE ("stat:tiles_current", int, m_stat_tiles_current); ATTR_DECODE ("stat:tiles_peak", int, m_stat_tiles_peak); ATTR_DECODE ("stat:open_files_created", int, m_stat_open_files_created); ATTR_DECODE ("stat:open_files_current", int, m_stat_open_files_current); ATTR_DECODE ("stat:open_files_peak", int, m_stat_open_files_peak); if (boost::algorithm::starts_with(name, "stat:")) { // All the other stats are those that need to be summed from all // the threads. ImageCacheStatistics stats; mergestats (stats); ATTR_DECODE ("stat:find_tile_calls", long long, stats.find_tile_calls); ATTR_DECODE ("stat:find_tile_microcache_misses", long long, stats.find_tile_microcache_misses); ATTR_DECODE ("stat:find_tile_cache_misses", int, stats.find_tile_cache_misses); ATTR_DECODE ("stat:files_totalsize", long long, stats.files_totalsize); ATTR_DECODE ("stat:bytes_read", long long, stats.bytes_read); ATTR_DECODE ("stat:unique_files", int, stats.unique_files); ATTR_DECODE ("stat:fileio_time", float, stats.fileio_time); ATTR_DECODE ("stat:fileopen_time", float, stats.fileopen_time); ATTR_DECODE ("stat:file_locking_time", float, stats.file_locking_time); ATTR_DECODE ("stat:tile_locking_time", float, stats.tile_locking_time); ATTR_DECODE ("stat:find_file_time", float, stats.find_file_time); ATTR_DECODE ("stat:find_tile_time", float, stats.find_tile_time); } return false; #undef ATTR_DECODE } bool ImageCacheImpl::find_tile_main_cache (const TileID &id, ImageCacheTileRef &tile, ImageCachePerThreadInfo *thread_info) { DASSERT (! id.file().broken()); ImageCacheStatistics &stats (thread_info->m_stats); ++stats.find_tile_microcache_misses; { #if IMAGECACHE_TIME_STATS Timer timer1; #endif TileCache::iterator found = m_tilecache.find (id); #if IMAGECACHE_TIME_STATS stats.find_tile_time += timer1(); #endif if (found) { tile = (*found).second; found.unlock(); // release the lock // We found the tile in the cache, but we need to make sure we // wait until the pixels are ready to read. We purposely have // released the lock (above) before calling wait_pixels_ready, // otherwise we could deadlock if another thread reading the // pixels needs to lock the cache because it's doing automip. tile->wait_pixels_ready (); tile->use (); DASSERT (id == tile->id()); DASSERT (tile); return true; } } // The tile was not found in cache. ++stats.find_tile_cache_misses; // Yes, we're creating and reading a tile with no lock -- this is to // prevent all the other threads from blocking because of our // expensive disk read. We believe this is safe, since underneath // the ImageCacheFile will lock itself for the read_tile and there are // no other non-threadsafe side effects. Timer timer; tile = new ImageCacheTile (id, thread_info, m_read_before_insert); // N.B. the ImageCacheTile ctr starts the tile out as 'used' DASSERT (tile); DASSERT (id == tile->id()); double readtime = timer(); stats.fileio_time += readtime; id.file().iotime() += readtime; add_tile_to_cache (tile, thread_info); DASSERT (id == tile->id()); return tile->valid(); } void ImageCacheImpl::add_tile_to_cache (ImageCacheTileRef &tile, ImageCachePerThreadInfo *thread_info) { bool ourtile = true; { // Protect us from using too much memory if another thread added the // same tile just before us TileCache::iterator found = m_tilecache.find (tile->id()); if (found != m_tilecache.end ()) { // Already added! Use the other one, discard ours. tile = (*found).second; found.unlock (); ourtile = false; // Don't need to add it } else { // Still not in cache, add ours to the cache. // N.B. at this time, we do not hold any locks. check_max_mem (thread_info); m_tilecache.insert (tile->id(), tile); } } // At this point, we no longer have the write lock, and we are no // longer modifying the cache itself. However, if we added a new // tile to the cache, we may still need to read the pixels; and if // we found the tile in cache, we may need to wait for somebody else // to read the pixels. if (ourtile) { if (! tile->pixels_ready ()) { Timer timer; tile->read (thread_info); double readtime = timer(); thread_info->m_stats.fileio_time += readtime; tile->id().file().iotime() += readtime; } } else { tile->wait_pixels_ready (); } } void ImageCacheImpl::check_max_mem (ImageCachePerThreadInfo *thread_info) { DASSERT (m_mem_used < (long long)m_max_memory_bytes*10); // sanity #if 0 static atomic_int n; if (! (n++ % 64) || m_mem_used >= (long long)m_max_memory_bytes) std::cerr << "mem used: " << m_mem_used << ", max = " << m_max_memory_bytes << "\n"; #endif // Early out if the cache is empty if (m_tilecache.empty()) return; // Early out if we aren't exceeding the tile memory limit if (m_mem_used < (long long)m_max_memory_bytes) return; // Try to grab the tile_sweep_mutex lock. If somebody else holds it, // just return -- leave the memory limit enforcement to whomever is // already in this function, no need for two threads to do it at // once. If this means we may ephemerally be over the memory limit // (because another thread adds a tile before we have freed enough // here), so be it. if (! m_tile_sweep_mutex.try_lock()) return; // Now, what we want to do is have a "clock hand" that sweeps across // the cache, releasing tiles that haven't been used for a long // time. Because of multi-thread, rather than keep an iterator // around for this (which could be invalidated since the last time // we used it), we just remember the tileID of the next tile to // check, then look it up fresh. That is m_tile_sweep_id. // If we don't have a valid tile_sweep_id, establish it by just // looking up the first entry in the tile cache. if (m_tile_sweep_id.empty()) { TileCache::iterator sweep = m_tilecache.begin(); ASSERT (sweep != m_tilecache.end() && "no way m_tilecache can be empty and use too much memory"); m_tile_sweep_id = (*sweep).first; } // Get a (locked) iterator for the next tile to be examined. TileCache::iterator sweep = m_tilecache.find (m_tile_sweep_id); // Loop while we still use too much tile memory. Also, be careful // of looping for too long, exit the loop if we just keep spinning // uncontrollably. int full_loops = 0; TileCache::iterator end = m_tilecache.end(); while (m_mem_used >= (long long)m_max_memory_bytes && full_loops < 100) { // If we have fallen off the end of the cache, loop back to the // beginning and increment our full_loops count. if (sweep == end) { sweep = m_tilecache.begin(); ++full_loops; } // If we're STILL at the end, it must be that somehow the entire // cache is empty. So just declare ourselves done. if (sweep == end) break; DASSERT (sweep->second); if (! sweep->second->release ()) { // This is a tile we should delete. To keep iterating // safely, we have a good trick: // 1. remember the TileID of the tile to delete TileID todelete = sweep->first; size_t size = sweep->second->memsize(); ASSERT (m_mem_used >= (long long)size); // 2. Increment the iterator to the next item to be visited // in the cache and then unlock it (since it can't be locked // for the subsequent erase() call). ++sweep; sweep.unlock (); // 3. Erase the tile we wish to delete m_tilecache.erase (todelete); // std::cerr << " Freed tile, recovering " << size << "\n"; // 4. Re-lock the iterator, which now points to the next // item the from the cache to examine. sweep.lock (); } else { ++sweep; } } // OK, by this point we have either freed enough tiles to be below // the limit again, or the cache is empty, or we've looped over the // cache too many times and are giving up. // Now we must save the tileid for next time. Just set it to an // empty ID if we don't have a valid iterator at this point. m_tile_sweep_id = (sweep == end ? TileID() : sweep->first); m_tile_sweep_mutex.unlock (); // N.B. As we exit, the iterators will go out of scope and we will // retain no locks on the cache. } std::string ImageCacheImpl::resolve_filename (const std::string &filename) const { std::string s = Filesystem::searchpath_find (filename, m_searchdirs, true); return s.empty() ? filename : s; } bool ImageCacheImpl::get_image_info (ustring filename, int subimage, int miplevel, ustring dataname, TypeDesc datatype, void *data) { ImageCachePerThreadInfo *thread_info = get_perthread_info (); ImageCacheFile *file = find_file (filename, thread_info, NULL, true); if (dataname == s_exists && datatype == TypeDesc::TypeInt) { // Just check for existence. Need to do this before the invalid // file error below, since in this one case, it's not an error // for the file to be nonexistant or broken! *(int *)data = (file && !file->broken()); (void) geterror(); // eat any error generated by find_file return true; } if (!file || file->broken()) { error ("Invalid image file \"%s\"", filename.c_str()); return false; } if (dataname == s_subimages && datatype == TypeDesc::TypeInt) { *(int *)data = file->subimages(); return true; } const ImageSpec &spec (file->spec(subimage,miplevel)); if (dataname == s_resolution && datatype==TypeDesc(TypeDesc::INT,2)) { int *d = (int *)data; d[0] = spec.width; d[1] = spec.height; return true; } if (dataname == s_resolution && datatype==TypeDesc(TypeDesc::INT,3)) { int *d = (int *)data; d[0] = spec.width; d[1] = spec.height; d[2] = spec.depth; return true; } if (dataname == s_texturetype && datatype == TypeDesc::TypeString) { ustring s (texture_type_name (file->textureformat())); *(const char **)data = s.c_str(); return true; } if (dataname == s_textureformat && datatype == TypeDesc::TypeString) { ustring s (texture_format_name (file->textureformat())); *(const char **)data = s.c_str(); return true; } if (dataname == s_fileformat && datatype == TypeDesc::TypeString) { *(const char **)data = file->fileformat().c_str(); return true; } if (dataname == s_channels && datatype == TypeDesc::TypeInt) { *(int *)data = spec.nchannels; return true; } if (dataname == s_channels && datatype == TypeDesc::TypeFloat) { *(float *)data = spec.nchannels; return true; } if (dataname == s_format && datatype == TypeDesc::TypeInt) { *(int *)data = (int) spec.format.basetype; return true; } if ((dataname == s_cachedformat || dataname == s_cachedpixeltype) && datatype == TypeDesc::TypeInt) { *(int *)data = (int) file->datatype(subimage).basetype; return true; } if (dataname == s_miplevels && datatype == TypeDesc::TypeInt) { *(int *)data = file->miplevels(subimage); return true; } if (dataname == s_datawindow && datatype.basetype == TypeDesc::INT && (datatype == TypeDesc(TypeDesc::INT,4) || datatype == TypeDesc(TypeDesc::INT,6))) { int *d = (int *)data; if (datatype.arraylen == 4) { d[0] = spec.x; d[1] = spec.y; d[2] = spec.x + spec.width - 1; d[3] = spec.y + spec.height - 1; } else { d[0] = spec.x; d[1] = spec.y; d[2] = spec.z; d[3] = spec.x + spec.width - 1; d[4] = spec.y + spec.height - 1; d[5] = spec.z + spec.depth - 1; } } if (dataname == s_displaywindow && datatype.basetype == TypeDesc::INT && (datatype == TypeDesc(TypeDesc::INT,4) || datatype == TypeDesc(TypeDesc::INT,6))) { int *d = (int *)data; if (datatype.arraylen == 4) { d[0] = spec.full_x; d[1] = spec.full_y; d[2] = spec.full_x + spec.full_width - 1; d[3] = spec.full_y + spec.full_height - 1; } else { d[0] = spec.full_x; d[1] = spec.full_y; d[2] = spec.full_z; d[3] = spec.full_x + spec.full_width - 1; d[4] = spec.full_y + spec.full_height - 1; d[5] = spec.full_z + spec.full_depth - 1; } } // general case -- handle anything else that's able to be found by // spec.find_attribute(). const ImageIOParameter *p = spec.find_attribute (dataname.string()); if (p && p->type().arraylen == datatype.arraylen) { // First test for exact type match if (p->type() == datatype) { memcpy (data, p->data(), datatype.size()); return true; } // If the real data is int but user asks for float, translate it if (p->type().basetype == TypeDesc::FLOAT && datatype.basetype == TypeDesc::INT) { for (int i = 0; i < p->type().arraylen; ++i) ((float *)data)[i] = ((int *)p->data())[i]; return true; } } return false; } bool ImageCacheImpl::get_imagespec (ustring filename, ImageSpec &spec, int subimage, int miplevel, bool native) { const ImageSpec *specptr = imagespec (filename, subimage, miplevel, native); if (specptr) { spec = *specptr; return true; } else { return false; // imagespec() already handled the errors } } const ImageSpec * ImageCacheImpl::imagespec (ustring filename, int subimage, int miplevel, bool native) { ImageCachePerThreadInfo *thread_info = get_perthread_info (); ImageCacheFile *file = find_file (filename, thread_info, NULL, true); if (! file) { error ("Image file \"%s\" not found", filename.c_str()); return NULL; } if (file->broken()) { error ("Invalid image file \"%s\"", filename.c_str()); return NULL; } if (subimage < 0 || subimage >= file->subimages()) { error ("Unknown subimage %d (out of %d)", subimage, file->subimages()); return NULL; } if (miplevel < 0 || miplevel >= file->miplevels(subimage)) { error ("Unknown mip level %d (out of %d)", miplevel, file->miplevels(subimage)); return NULL; } const ImageSpec *spec = native ? &file->nativespec (subimage,miplevel) : &file->spec (subimage, miplevel); return spec; } int ImageCacheImpl::subimage_from_name (ImageCacheFile *file, ustring subimagename) { for (int s = 0, send = file->subimages(); s < send; ++s) { if (file->subimageinfo(s).subimagename == subimagename) return s; } return -1; // No matching subimage name } bool ImageCacheImpl::get_pixels (ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result) { return get_pixels (filename, subimage, miplevel, xbegin, xend, ybegin, yend, zbegin, zend, 0, -1, format, result); } bool ImageCacheImpl::get_pixels (ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *result, stride_t xstride, stride_t ystride, stride_t zstride) { ImageCachePerThreadInfo *thread_info = get_perthread_info (); ImageCacheFile *file = find_file (filename, thread_info); if (! file) { error ("Image file \"%s\" not found", filename.c_str()); return false; } if (file->broken()) { error ("Invalid image file \"%s\"", filename.c_str()); return false; } if (subimage < 0 || subimage >= file->subimages()) { error ("get_pixels asked for nonexistant subimage %d of \"%s\"", subimage, filename.c_str()); return false; } if (miplevel < 0 || miplevel >= file->miplevels(subimage)) { error ("get_pixels asked for nonexistant MIP level %d of \"%s\"", miplevel, filename.c_str()); return false; } return get_pixels (file, thread_info, subimage, miplevel, xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend, format, result, xstride, ystride, zstride); } bool ImageCacheImpl::get_pixels (ImageCacheFile *file, ImageCachePerThreadInfo *thread_info, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *result, stride_t xstride, stride_t ystride, stride_t zstride) { const ImageSpec &spec (file->spec(subimage, miplevel)); bool ok = true; // Compute channels and stride if not given (assume all channels, // contiguous data layout for strides). if (chbegin < 0 || chend < 0) { chbegin = 0; chend = spec.nchannels; } int nchans = chend - chbegin; ImageSpec::auto_stride (xstride, ystride, zstride, format, nchans, xend-xbegin, yend-ybegin); // formatpixelsize, scanlinesize, and zplanesize assume contiguous // layout. This may or may not be the same as the strides passed by // the caller. TypeDesc cachetype = file->datatype(subimage); const size_t cachesize = cachetype.size(); const stride_t cache_stride = cachesize * spec.nchannels; size_t formatsize = format.size(); stride_t formatpixelsize = nchans * formatsize; bool xcontig = (formatpixelsize == xstride && nchans == spec.nchannels); stride_t scanlinesize = (xend-xbegin) * formatpixelsize; stride_t zplanesize = (yend-ybegin) * scanlinesize; DASSERT (spec.depth >= 1 && spec.tile_depth >= 1); char *zptr = (char *)result; for (int z = zbegin; z < zend; ++z, zptr += zstride) { if (z < spec.z || z >= (spec.z+spec.depth)) { // nonexistant planes if (xstride == formatpixelsize && ystride == scanlinesize) { // Can zero out the plane in one shot memset (zptr, 0, zplanesize); } else { // Non-contiguous strides -- zero out individual pixels char *yptr = zptr; for (int y = ybegin; y < yend; ++y, yptr += ystride) { char *xptr = yptr; for (int x = xbegin; x < xend; ++x, xptr += xstride) memset (xptr, 0, formatpixelsize); } } continue; } int old_tx = -100000, old_ty = -100000, old_tz = -100000; int tz = z - ((z - spec.z) % spec.tile_depth); char *yptr = zptr; int ty = ybegin - ((ybegin - spec.y) % spec.tile_height); int tyend = ty + spec.tile_height; for (int y = ybegin; y < yend; ++y, yptr += ystride) { if (y == tyend) { ty = tyend; tyend += spec.tile_height; } if (y < spec.y || y >= (spec.y+spec.height)) { // nonexistant scanlines if (xstride == formatpixelsize) { // Can zero out the scanline in one shot memset (yptr, 0, scanlinesize); } else { // Non-contiguous strides -- zero out individual pixels char *xptr = yptr; for (int x = xbegin; x < xend; ++x, xptr += xstride) memset (xptr, 0, formatpixelsize); } continue; } // int ty = y - ((y - spec.y) % spec.tile_height); char *xptr = yptr; const char *data = NULL; for (int x = xbegin; x < xend; ++x, xptr += xstride) { if (x < spec.x || x >= (spec.x+spec.width)) { // nonexistant columns memset (xptr, 0, formatpixelsize); continue; } int tx = x - ((x - spec.x) % spec.tile_width); if (old_tx != tx || old_ty != ty || old_tz != tz) { // Only do a find_tile and re-setup of the data // pointer when we move across a tile boundary. TileID tileid (*file, subimage, miplevel, tx, ty, tz); ok &= find_tile (tileid, thread_info); if (! ok) return false; // Just stop if file read failed old_tx = tx; old_ty = ty; old_tz = tz; data = NULL; } if (! data) { ImageCacheTileRef &tile (thread_info->tile); ASSERT (tile); data = (const char *)tile->data (x, y, z); ASSERT (data); data += chbegin*cachesize; } if (xcontig) { // Special case for a contiguous span within one tile int spanend = std::min (tx + spec.tile_width, xend); stride_t span = spanend - x; convert_types (cachetype, data, format, xptr, nchans*span); x += (span-1); xptr += xstride * (span-1); // no need to increment data, since next read will // be from a different tile } else { convert_types (cachetype, data, format, xptr, nchans); data += cache_stride; } } } } return ok; } ImageCache::Tile * ImageCacheImpl::get_tile (ustring filename, int subimage, int miplevel, int x, int y, int z) { ImageCachePerThreadInfo *thread_info = get_perthread_info (); ImageCacheFile *file = find_file (filename, thread_info); if (! file || file->broken()) return NULL; const ImageSpec &spec (file->spec(subimage,miplevel)); // Snap x,y,z to the corner of the tile int xtile = (x-spec.x) / spec.tile_width; int ytile = (y-spec.y) / spec.tile_height; int ztile = (z-spec.z) / spec.tile_depth; x = spec.x + xtile * spec.tile_width; y = spec.y + ytile * spec.tile_height; z = spec.z + ztile * spec.tile_depth; TileID id (*file, subimage, miplevel, x, y, z); if (find_tile(id, thread_info)) { ImageCacheTileRef tile(thread_info->tile); tile->_incref(); // Fake an extra reference count return (ImageCache::Tile *) tile.get(); } else { return NULL; } } void ImageCacheImpl::release_tile (ImageCache::Tile *tile) const { if (! tile) return; ImageCacheTileRef tileref((ImageCacheTile *)tile); tileref->use (); tileref->_decref(); // Reduce ref count that we bumped in get_tile // when we exit scope, tileref will do the final dereference } const void * ImageCacheImpl::tile_pixels (ImageCache::Tile *tile, TypeDesc &format) const { if (! tile) return NULL; ImageCacheTile * t = (ImageCacheTile *)tile; format = t->file().datatype(t->id().subimage()); return t->data (); } bool ImageCacheImpl::add_file (ustring filename, ImageInput::Creator creator) { if (! creator) { error ("ImageCache::add_file must be given an ImageInput::Creator"); return false; } ImageCachePerThreadInfo *thread_info = get_perthread_info (); ImageCacheFile *file = find_file (filename, thread_info, creator); if (!file || file->broken()) return false; return true; } bool ImageCacheImpl::add_tile (ustring filename, int subimage, int miplevel, int x, int y, int z, TypeDesc format, const void *buffer, stride_t xstride, stride_t ystride, stride_t zstride) { ImageCachePerThreadInfo *thread_info = get_perthread_info (); ImageCacheFile *file = find_file (filename, thread_info); if (! file || file->broken()) { error ("Cannot add_tile for an image file that was not set up with add_file()"); return false; } TileID tileid (*file, subimage, miplevel, x, y, z); ImageCacheTileRef tile = new ImageCacheTile (tileid, buffer, format, xstride, ystride, zstride); if (! tile || ! tile->valid()) { error ("Could not construct the tile; unknown reasons."); return false; } add_tile_to_cache (tile, thread_info); return true; } void ImageCacheImpl::invalidate (ustring filename) { ImageCacheFile *file = NULL; { FilenameMap::iterator fileit = m_files.find (filename); if (fileit != m_files.end()) file = fileit->second.get(); else return; // no such file } // Iterate over the entire tilecache, record the TileID's of all // tiles that are from the file we are invalidating. std::vector tiles_to_delete; for (TileCache::iterator tci = m_tilecache.begin(), e = m_tilecache.end(); tci != e; ++tci) { if (&(*tci).second->file() == file) tiles_to_delete.push_back ((*tci).second->id()); } // N.B. at this point, we hold no locks! // Safely erase all the tiles we found BOOST_FOREACH (const TileID &id, tiles_to_delete) { m_tilecache.erase (id); } // Invalidate the file itself (close it and clear its spec) file->invalidate (); // Remove the fingerprint corresponding to this file { spin_lock lock (m_fingerprints_mutex); FingerprintMap::iterator f = m_fingerprints.find (filename); if (f != m_fingerprints.end()) m_fingerprints.erase (f); } purge_perthread_microcaches (); } void ImageCacheImpl::invalidate_all (bool force) { // Special case: invalidate EVERYTHING -- we can take some shortcuts // to do it all in one shot. if (force) { // Clear the whole tile cache std::vector tiles_to_delete; for (TileCache::iterator t = m_tilecache.begin(), e = m_tilecache.end(); t != e; ++t) { tiles_to_delete.push_back (t->second->id()); } BOOST_FOREACH (const TileID &id, tiles_to_delete) { m_tilecache.erase (id); } // Invalidate (close and clear spec) all individual files for (FilenameMap::iterator fileit = m_files.begin(), e = m_files.end(); fileit != e; ++fileit) { fileit->second->invalidate (); } // Clear fingerprints list clear_fingerprints (); // Mark the per-thread microcaches as invalid purge_perthread_microcaches (); return; } // Not forced... we need to look for particular files that seem // to need invalidation. // Make a list of all files that need to be invalidated std::vector all_files; for (FilenameMap::iterator fileit = m_files.begin(), e = m_files.end(); fileit != e; ++fileit) { ImageCacheFileRef &f (fileit->second); ustring name = f->filename(); recursive_lock_guard guard (f->m_input_mutex); // If the file was broken when we opened it, or if it no longer // exists, definitely invalidate it. if (f->broken() || ! Filesystem::exists(name.string())) { all_files.push_back (name); continue; } // Invalidate the file if it has been modified since it was // last opened. std::time_t t = Filesystem::last_write_time (name.string()); if (t != f->mod_time()) { all_files.push_back (name); continue; } // Invalidate if any unmipped subimage... // ... didn't automip, but automip is now on // ... did automip, but automip is now off for (int s = 0; s < f->subimages(); ++s) { ImageCacheFile::SubimageInfo &sub (f->subimageinfo(s)); if (sub.unmipped && ((m_automip && f->miplevels(s) <= 1) || (!m_automip && f->miplevels(s) > 1))) { all_files.push_back (name); break; } } } // Now, invalidate all the files in our "needs invalidation" list BOOST_FOREACH (ustring f, all_files) { // fprintf (stderr, "Invalidating %s\n", f.c_str()); invalidate (f); } // Mark the per-thread microcaches as invalid purge_perthread_microcaches (); } ImageCachePerThreadInfo * ImageCacheImpl::get_perthread_info () { ImageCachePerThreadInfo *p = m_perthread_info.get(); if (! p) { p = new ImageCachePerThreadInfo; m_perthread_info.reset (p); // printf ("New perthread %p\n", (void *)p); lock_guard lock (m_perthread_info_mutex); m_all_perthread_info.push_back (p); p->shared = true; // both the IC and the thread point to it } if (p->purge) { // has somebody requested a tile purge? // This is safe, because it's our thread. lock_guard lock (m_perthread_info_mutex); p->tile = NULL; p->lasttile = NULL; p->purge = 0; for (int i = 0; i < ImageCachePerThreadInfo::nlastfile; ++i) { p->last_filename[i] = ustring(); p->last_file[i] = NULL; } } return p; } void ImageCacheImpl::erase_perthread_info () { lock_guard lock (m_perthread_info_mutex); for (size_t i = 0; i < m_all_perthread_info.size(); ++i) { ImageCachePerThreadInfo *p = m_all_perthread_info[i]; if (p) { // Clear the microcache. p->tile = NULL; p->lasttile = NULL; if (p->shared) { // Pointed to by both thread-specific-ptr and our list. // Just remove from out list, then ownership is only // by the thread-specific-ptr. p->shared = false; } else { // Only pointed to by us -- delete it! delete p; } m_all_perthread_info[i] = NULL; } } } void ImageCacheImpl::cleanup_perthread_info (ImageCachePerThreadInfo *p) { lock_guard lock (m_perthread_info_mutex); if (p) { // Clear the microcache. p->tile = NULL; p->lasttile = NULL; if (! p->shared) // If we own it, delete it delete p; else p->shared = false; // thread disappearing, no longer shared } } void ImageCacheImpl::purge_perthread_microcaches () { // Mark the per-thread microcaches as invalid lock_guard lock (m_perthread_info_mutex); for (size_t i = 0, e = m_all_perthread_info.size(); i < e; ++i) if (m_all_perthread_info[i]) m_all_perthread_info[i]->purge = 1; } std::string ImageCacheImpl::geterror () const { std::string e; std::string *errptr = m_errormessage.get (); if (errptr) { e = *errptr; errptr->clear (); } return e; } void ImageCacheImpl::append_error (const std::string& message) const { std::string *errptr = m_errormessage.get (); if (! errptr) { errptr = new std::string; m_errormessage.reset (errptr); } ASSERT (errptr != NULL); ASSERT (errptr->size() < 1024*1024*16 && "Accumulated error messages > 16MB. Try checking return codes!"); if (errptr->size()) *errptr += '\n'; *errptr += message; } } // end namespace pvt ImageCache * ImageCache::create (bool shared) { if (shared) { // They requested a shared cache. If a shared cache already // exists, just return it, otherwise record the new cache. spin_lock guard (shared_image_cache_mutex); if (! shared_image_cache.get()) shared_image_cache.reset (new ImageCacheImpl); else shared_image_cache->invalidate_all (); #if 0 std::cerr << " shared ImageCache is " << (void *)shared_image_cache.get() << "\n"; #endif return shared_image_cache.get (); } // Doesn't need a shared cache ImageCacheImpl *ic = new ImageCacheImpl; #if 0 std::cerr << "creating new ImageCache " << (void *)ic << "\n"; #endif return ic; } void ImageCache::destroy (ImageCache *x, bool teardown) { if (! x) return; spin_lock guard (shared_image_cache_mutex); if (x == shared_image_cache.get()) { // This is the shared cache, so don't really delete it. Invalidate // it fully, closing the files and throwing out any tiles that // nobody is currently holding references to. But only delete the // IC fully if 'teardown' is true, and even then, it won't destroy // until nobody else is still holding a shared_ptr to it. ((ImageCacheImpl *)x)->invalidate_all (teardown); if (teardown) shared_image_cache.reset (); } else { // Not a shared cache, we are the only owner, so truly destroy it. delete (ImageCacheImpl *) x; } } void ImageCache::destroy (ImageCache *x) { destroy (x, false); } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libtexture/environment.cpp0000644000175000017500000004554612271062644022365 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "varyingref.h" #include "ustring.h" #include "strutil.h" #include "thread.h" #include "fmath.h" #include "filter.h" #include "imageio.h" #include "texture.h" #include "imagecache.h" #include "imagecache_pvt.h" #include "texture_pvt.h" /* Discussion about environment map issues and conventions: Latlong maps (spherical parameterization) come in two varieties that OIIO supports: (a) Our default follows the RenderMan convention of "z is up" and left-handed, with the north pole (t=0) pointing toward +z and the "center" (0.5,0.5) pointing toward +y: --s--> (0,0,1) (0,0) +---------------------------------------+ (1,0) | | | | | t |(-1,0,0) (1,0,0) | | + + + + | V | (0,-1,0) (0,1,0) | | | | | (0,1) +---------------------------------------+ (1,1) (0,0,-1) (b) If the metadata "oiio:updirection" is "y", the map is assumed to use the OpenEXR convention where the +y axis is "up", and the coordinate system is right-handed, and the center pixel points toward the +x axis: --s--> (0,1,0) (0,0) +---------------------------------------+ (1,0) | | | | | t |(0,0,-1) (0,0,1) | | + + + + | V | (1,0,0) (0,-1,0) | | | | | (0,1) +---------------------------------------+ (1,1) (0,-1,0) By default, we assume the conversion between pixel coordinates and texture coordinates is the same as for 2D textures; that is, pixel (i,j) is located at s,t = ( (i+0.5)/xres, (j+0.5)/yres ). We believe that this is the usual interpretation of latlong maps. However, if the metadata "oiio:sampleborder" is present and nonzero, we assume instead that pixel (i,j) has st coordinates ( i/(xres-1), j/(yres-1) ), in other words, that the edge texels correspond exactly to the pole or median seam, and therefore that pixel (0,j) and (xres-1,j) should be identical for all j, pixel (i,0) should be identical for all i, and pixel (i,yres-1) should be identical for all i. This latter convention is dictated by OpenEXR. Cubeface environment maps are composed of six orthogonal faces (that we name px, nx, py, ny, pz, nz). major +s dir +t dir Face axis (right) (down) ---- ----- ------- ------ px +x -z -y nx -x +z -y py +y +x +z ny -y +x -z pz +z +x -y nz -z -x -y The cubeface layout is easily visualized by "unwrapping": +-------------+ |py | | | | +y->+x | | | | | V | | +z | +-------------|-------------|-------------+-------------+ |nx |pz |px |nz | | | | | | | -x->+z | +z->+x | +x->-z | -z->-x | | | | | | | | | | | V | V | V | V | | -y | -y | -y | -y | +-------------+-------------+-------------+-------------+ |ny | | | | -y->+x | | | | | V | | -z | +-------------+ But that's just for visualization. The way it's actually stored in a file varies by convention of the file format. Here are the two conventions that we support natively: (a) "2x3" (a.k.a. the RenderMan/BMRT convention) wherein all six faces are arranged within a single image: +-------------+-------------+-------------+ |px |py |pz | | | | | | +x->-z | +y->+x | +z->+x | | | | | | | | | V | V | V | | -y | +z | -y | |-------------|-------------|-------------| |nx |ny |nz | | | | | | -x->+z | -y->+x | -z->-x | | | | | | | | | V | V | V | | -y | -z | -y | +-------------+-------------+-------------+ The space for each "face" is an integer multiple of the tile size, padded by black pixels if necessary (i.e. if the face res is not a full multiple of the tile size). For example, +--------+--------+--------+ |px| |py| |pz| | |--+ |--+ |--+ | | (black)| | | |--------+--------+--------| |nx| |ny| |nz| | |--+ |--+ |--+ | | | | | +--------+--------+--------+ This might happen on low-res MIP levels if the tile size is 64x64 but each face is only 8x8, say. The way we signal these things is for the ImageSpec width,height to be the true data window size (3 x res, 2 x res), but for full_width,full_height to be the size of the valid area of each face. (b) "6x1" (the OpenEXR convention) wherein the six faces are arranged in a vertical stack like this: +--+ |px| +--+ |nx| +--+ |py| +--+ |ny| +--+ |pz| +--+ |nz| +--+ Which of these conventions is being followed in a particular cubeface environment map file should be obvious merely by looking at the aspect ratio -- 3:2 or 1:6. As with latlong maps, by default we assume the conversion between pixel coordinates and texture coordinates within a face is the same as for 2D textures; that is, pixel (i,j) is located at s,t = ( (i+0.5)/faceres, (j+0.5)/faceres ). However, if the metadata "oiio:sampleborder" is present and nonzero, we assume instead that pixel (i,j) has st coordinates ( i/(faceres-1), j/(faceres-1) ), in other words, that the edge texels correspond exactly to the cube edge itself, and therefore that each cube face's edge texels are identical to the bordering face, and that any corner pixel values are identical for all three faces that share the corner. This convention is dictated by OpenEXR. */ OIIO_NAMESPACE_ENTER { using namespace pvt; namespace { // anonymous static EightBitConverter uchar2float; } // end anonymous namespace namespace pvt { // namespace pvt bool TextureSystemImpl::environment (ustring filename, TextureOptions &options, Runflag *runflags, int beginactive, int endactive, VaryingRef R, VaryingRef dRdx, VaryingRef dRdy, float *result) { Perthread *thread_info = get_perthread_info(); TextureHandle *texture_handle = get_texture_handle (filename, thread_info); if (! texture_handle) return false; bool ok = true; for (int i = beginactive; i < endactive; ++i) { if (runflags[i]) { TextureOpt opt (options, i); ok &= environment (texture_handle, thread_info, opt, R[i], dRdx[i], dRdy[i], result+i*options.nchannels); } } return ok; } /// Convert a direction vector to latlong st coordinates /// inline void vector_to_latlong (const Imath::V3f& R, bool y_is_up, float &s, float &t) { if (y_is_up) { s = atan2f (-R[0], R[2]) / (2.0f*(float)M_PI) + 0.5f; t = 0.5f - atan2f(R[1], hypotf(R[2],-R[0])) / (float)M_PI; } else { s = atan2f (R[1], R[0]) / (2.0f*(float)M_PI) + 0.5f; t = 0.5f - atan2f(R[2], hypotf(R[0],R[1])) / (float)M_PI; } // learned from experience, beware NaNs if (isnan(s)) s = 0.0f; if (isnan(t)) t = 0.0f; } bool TextureSystemImpl::environment (ustring filename, TextureOpt &options, const Imath::V3f &R, const Imath::V3f &dRdx, const Imath::V3f &dRdy, float *result) { PerThreadInfo *thread_info = m_imagecache->get_perthread_info (); TextureFile *texturefile = find_texturefile (filename, thread_info); return environment ((TextureHandle *)texturefile, (Perthread *)thread_info, options, R, dRdx, dRdy, result); } bool TextureSystemImpl::environment (TextureHandle *texture_handle_, Perthread *thread_info_, TextureOpt &options, const Imath::V3f &_R, const Imath::V3f &_dRdx, const Imath::V3f &_dRdy, float *result) { PerThreadInfo *thread_info = (PerThreadInfo *)thread_info_; TextureFile *texturefile = (TextureFile *)texture_handle_; ImageCacheStatistics &stats (thread_info->m_stats); ++stats.environment_batches; ++stats.environment_queries; if (! texturefile || texturefile->broken()) return missing_texture (options, result); const ImageSpec &spec (texturefile->spec(options.subimage, 0)); options.swrap_func = texturefile->m_sample_border ? wrap_periodic_sharedborder : wrap_periodic; options.twrap_func = wrap_clamp; options.envlayout = LayoutLatLong; int actualchannels = Imath::clamp (spec.nchannels - options.firstchannel, 0, options.nchannels); options.actualchannels = actualchannels; // Initialize results to 0. We'll add from here on as we sample. for (int c = 0; c < options.nchannels; ++c) result[c] = 0; float* dresultds = options.dresultds; float* dresultdt = options.dresultdt; if (dresultds) for (int c = 0; c < options.nchannels; ++c) dresultds[c] = 0; if (dresultdt) for (int c = 0; c < options.nchannels; ++c) dresultdt[c] = 0; // If the user only provided us with one pointer, clear both to simplify // the rest of the code, but only after we zero out the data for them so // they know something went wrong. if (!(dresultds && dresultdt)) dresultds = dresultdt = NULL; // Calculate unit-length vectors in the direction of R, R+dRdx, R+dRdy. // These define the ellipse we're filtering over. Imath::V3f R = _R; R.normalize(); // center Imath::V3f Rx = _R + _dRdx; Rx.normalize(); // x axis of the ellipse Imath::V3f Ry = _R + _dRdy; Ry.normalize(); // y axis of the ellipse // angles formed by the ellipse axes. float xfilt_noblur = std::max (safe_acosf(R.dot(Rx)), 1e-8f); float yfilt_noblur = std::max (safe_acosf(R.dot(Ry)), 1e-8f); int naturalres = int((float)M_PI / std::min (xfilt_noblur, yfilt_noblur)); // FIXME -- figure naturalres sepearately for s and t // FIXME -- ick, why is it x and y at all, shouldn't it be s and t? // N.B. naturalres formulated for latlong // Account for width and blur float xfilt = xfilt_noblur * options.swidth + options.sblur; float yfilt = yfilt_noblur * options.twidth + options.tblur; // Figure out major versus minor, and aspect ratio Imath::V3f Rmajor; // major axis float majorlength, minorlength; bool x_is_majoraxis = (xfilt >= yfilt); if (x_is_majoraxis) { Rmajor = Rx; majorlength = xfilt; minorlength = yfilt; } else { Rmajor = Ry; majorlength = yfilt; minorlength = xfilt; } accum_prototype accumer; long long *probecount; switch (options.interpmode) { case TextureOpt::InterpClosest : accumer = &TextureSystemImpl::accum_sample_closest; probecount = &stats.closest_interps; break; case TextureOpt::InterpBilinear : accumer = &TextureSystemImpl::accum_sample_bilinear; probecount = &stats.bilinear_interps; break; case TextureOpt::InterpBicubic : accumer = &TextureSystemImpl::accum_sample_bicubic; probecount = &stats.cubic_interps; break; default: accumer = NULL; probecount = NULL; break; } TextureOpt::MipMode mipmode = options.mipmode; bool aniso = (mipmode == TextureOpt::MipModeDefault || mipmode == TextureOpt::MipModeAniso); float aspect, trueaspect, filtwidth; int nsamples; float invsamples; if (aniso) { aspect = anisotropic_aspect (majorlength, minorlength, options, trueaspect); filtwidth = minorlength; if (trueaspect > stats.max_aniso) stats.max_aniso = trueaspect; nsamples = std::max (1, (int) ceilf (aspect - 0.25f)); invsamples = 1.0f / nsamples; } else { filtwidth = options.conservative_filter ? majorlength : minorlength; nsamples = 1; invsamples = 1.0f; } ImageCacheFile::SubimageInfo &subinfo (texturefile->subimageinfo(options.subimage)); // FIXME -- assuming latlong bool ok = true; float pos = -0.5f + 0.5f * invsamples; for (int sample = 0; sample < nsamples; ++sample, pos += invsamples) { Imath::V3f Rsamp = R + pos*Rmajor; float s, t; vector_to_latlong (Rsamp, texturefile->m_y_up, s, t); // Determine the MIP-map level(s) we need: we will blend // data(miplevel[0]) * (1-levelblend) + data(miplevel[1]) * levelblend int miplevel[2] = { -1, -1 }; float levelblend = 0; int nmiplevels = (int)subinfo.levels.size(); for (int m = 0; m < nmiplevels; ++m) { // Compute the filter size in raster space at this MIP level. // Filters are in radians, and the vertical resolution of a // latlong map is PI radians. So to compute the raster size of // our filter width... float filtwidth_ras = subinfo.spec(m).full_height * filtwidth * M_1_PI; // Once the filter width is smaller than one texel at this level, // we've gone too far, so we know that we want to interpolate the // previous level and the current level. Note that filtwidth_ras // is expected to be >= 0.5, or would have stopped one level ago. if (filtwidth_ras <= 1) { miplevel[0] = m-1; miplevel[1] = m; levelblend = Imath::clamp (2.0f - 1.0f/filtwidth_ras, 0.0f, 1.0f); break; } } if (miplevel[1] < 0) { // We'd like to blur even more, but make due with the coarsest // MIP level. miplevel[0] = nmiplevels - 1; miplevel[1] = miplevel[0]; levelblend = 0; } else if (miplevel[0] < 0) { // We wish we had even more resolution than the finest MIP level, // but tough for us. miplevel[0] = 0; miplevel[1] = 0; levelblend = 0; } if (options.mipmode == TextureOpt::MipModeOneLevel) { // Force use of just one mipmap level miplevel[1] = miplevel[0]; levelblend = 0; } else if (mipmode == TextureOpt::MipModeNoMIP) { // Just sample from lowest level miplevel[0] = 0; miplevel[1] = 0; levelblend = 0; } float levelweight[2] = { 1.0f - levelblend, levelblend }; int npointson = 0; for (int level = 0; level < 2; ++level) { if (! levelweight[level]) continue; ++npointson; int lev = miplevel[level]; if (options.interpmode == TextureOpt::InterpSmartBicubic) { if (lev == 0 || (texturefile->spec(options.subimage,lev).full_height < naturalres/2)) { accumer = &TextureSystemImpl::accum_sample_bicubic; ++stats.cubic_interps; } else { accumer = &TextureSystemImpl::accum_sample_bilinear; ++stats.bilinear_interps; } } else { *probecount += 1; } ok &= (this->*accumer) (s, t, miplevel[level], *texturefile, thread_info, options, levelweight[level]*invsamples, result, dresultds, dresultdt); } } stats.aniso_probes += nsamples; ++stats.aniso_queries; if (actualchannels < options.nchannels) fill_gray_channels (spec, options, result); return ok; } } // end namespace pvt } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libtexture/imagecache_pvt.h0000644000175000017500000011646012271062644022417 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ /// \file /// Non-public classes used internally by ImgeCacheImpl. #ifndef OPENIMAGEIO_IMAGECACHE_PVT_H #define OPENIMAGEIO_IMAGECACHE_PVT_H #include #include #include "export.h" #include "texture.h" #include "refcnt.h" #include "hash.h" #include "imagebuf.h" #include "unordered_map_concurrent.h" OIIO_NAMESPACE_ENTER { namespace pvt { #ifndef NDEBUG # define IMAGECACHE_TIME_STATS 1 #else // Change the following to 1 to get timing statistics even for // optimized runs. Note that this has some performance penalty. # define IMAGECACHE_TIME_STATS 0 #endif #define IMAGECACHE_USE_RW_MUTEX 1 class ImageCacheImpl; struct ImageCachePerThreadInfo; const char * texture_format_name (TexFormat f); const char * texture_type_name (TexFormat f); /// Structure to hold IC and TS statistics. We combine into a single /// structure to minimize the number of costly thread_specific_ptr /// retrievals. If somebody is using the ImageCache without a /// TextureSystem, a few extra stats come along for the ride, but this /// has no performance penalty. struct ImageCacheStatistics { // First, the ImageCache-specific fields: long long find_tile_calls; long long find_tile_microcache_misses; int find_tile_cache_misses; long long files_totalsize; long long bytes_read; // These stats are hard to deal with on a per-thread basis, so for // now, they are still atomics shared by the whole IC. // int tiles_created; // int tiles_current; // int tiles_peak; // int open_files_created; // int open_files_current; // int open_files_peak; int unique_files; double fileio_time; double fileopen_time; double file_locking_time; double tile_locking_time; double find_file_time; double find_tile_time; // TextureSystem-specific fields below: long long texture_queries; long long texture_batches; long long texture3d_queries; long long texture3d_batches; long long shadow_queries; long long shadow_batches; long long environment_queries; long long environment_batches; long long aniso_queries; long long aniso_probes; float max_aniso; long long closest_interps; long long bilinear_interps; long long cubic_interps; int file_retry_success; int tile_retry_success; ImageCacheStatistics () { init (); } void init (); void merge (const ImageCacheStatistics &s); }; /// Unique in-memory record for each image file on disk. Note that /// this class is not in and of itself thread-safe. It's critical that /// any calling routine use a mutex any time a ImageCacheFile's methods are /// being called, including constructing a new ImageCacheFile. /// /// The public routines of ImageCacheFile are thread-safe! In /// particular, callers do not need to lock around calls to read_tile. /// However, a few of them require passing in a pointer to the /// thread-specific IC data including microcache and statistics. /// class OIIO_API ImageCacheFile : public RefCnt { public: ImageCacheFile (ImageCacheImpl &imagecache, ImageCachePerThreadInfo *thread_info, ustring filename, ImageInput::Creator creator=NULL); ~ImageCacheFile (); bool broken () const { return m_broken; } int subimages () const { return (int)m_subimages.size(); } int miplevels (int subimage) const { return (int)m_subimages[subimage].levels.size(); } const ImageSpec & spec (int subimage, int miplevel) const { return levelinfo(subimage,miplevel).spec; } ImageSpec & spec (int subimage, int miplevel) { return levelinfo(subimage,miplevel).spec; } const ImageSpec & nativespec (int subimage, int miplevel) const { return levelinfo(subimage,miplevel).nativespec; } ustring filename (void) const { return m_filename; } ustring fileformat (void) const { return m_fileformat; } TexFormat textureformat () const { return m_texformat; } TextureOpt::Wrap swrap () const { return m_swrap; } TextureOpt::Wrap twrap () const { return m_twrap; } TextureOpt::Wrap rwrap () const { return m_rwrap; } TypeDesc datatype (int subimage) const { return m_subimages[subimage].datatype; } ImageCacheImpl &imagecache () const { return m_imagecache; } ImageInput *imageinput () const { return m_input.get(); } ImageInput::Creator creator () const { return m_inputcreator; } /// Load new data tile /// bool read_tile (ImageCachePerThreadInfo *thread_info, int subimage, int miplevel, int x, int y, int z, TypeDesc format, void *data); /// Mark the file as recently used. /// void use (void) { m_used = true; } /// Try to release resources for this file -- if recently used, mark /// as not recently used; if already not recently used, close the /// file and return true. void release (void); size_t channelsize (int subimage) const { return m_subimages[subimage].channelsize; } size_t pixelsize (int subimage) const { return m_subimages[subimage].pixelsize; } bool eightbit (int subimage) const { return m_subimages[subimage].eightbit; } bool mipused (void) const { return m_mipused; } const std::vector &mipreadcount (void) const { return m_mipreadcount; } void invalidate (); size_t timesopened () const { return m_timesopened; } size_t tilesread () const { return m_tilesread; } imagesize_t bytesread () const { return m_bytesread; } double & iotime () { return m_iotime; } std::time_t mod_time () const { return m_mod_time; } ustring fingerprint () const { return m_fingerprint; } void duplicate (ImageCacheFile *dup) { m_duplicate = dup;} ImageCacheFile *duplicate () const { return m_duplicate; } /// Info for each MIP level that isn't in the ImageSpec, or that we /// precompute. struct LevelInfo { ImageSpec spec; ///< ImageSpec for the mip level ImageSpec nativespec; ///< Native ImageSpec for the mip level bool full_pixel_range; ///< pixel data window matches image window bool onetile; ///< Whole level fits on one tile mutable bool polecolorcomputed; ///< Pole color was computed mutable std::vector polecolor;///< Pole colors LevelInfo (const ImageSpec &spec, const ImageSpec &nativespec); ///< Initialize based on spec }; /// Info for each subimage /// struct SubimageInfo { std::vector levels; ///< Extra per-level info TypeDesc datatype; ///< Type of pixels we store internally unsigned int channelsize; ///< Channel size, in bytes unsigned int pixelsize; ///< Pixel size, in bytes bool untiled; ///< Not tiled bool unmipped; ///< Not really MIP-mapped bool volume; ///< It's a volume image bool full_pixel_range; ///< pixel data window matches image window bool eightbit; ///< Eight bit? (or float) // The scale/offset accounts for crops or overscans, converting // 0-1 texture space relative to the "display/full window" into // 0-1 relative to the "pixel window". float sscale, soffset, tscale, toffset; ustring subimagename; SubimageInfo () : datatype(TypeDesc::UNKNOWN), channelsize(0), pixelsize(0), untiled(false), unmipped(false), volume(false), full_pixel_range(false), eightbit(false), sscale(1.0f), soffset(0.0f), tscale(1.0f), toffset(0.0f) { } void init (const ImageSpec &spec, bool forcefloat); ImageSpec &spec (int m) { return levels[m].spec; } const ImageSpec &spec (int m) const { return levels[m].spec; } const ImageSpec &nativespec (int m) const { return levels[m].nativespec; } }; const SubimageInfo &subimageinfo (int subimage) const { return m_subimages[subimage]; } SubimageInfo &subimageinfo (int subimage) { return m_subimages[subimage]; } const LevelInfo &levelinfo (int subimage, int miplevel) const { DASSERT ((int)m_subimages.size() > subimage); DASSERT ((int)m_subimages[subimage].levels.size() > miplevel); return m_subimages[subimage].levels[miplevel]; } LevelInfo &levelinfo (int subimage, int miplevel) { DASSERT ((int)m_subimages.size() > subimage); DASSERT ((int)m_subimages[subimage].levels.size() > miplevel); return m_subimages[subimage].levels[miplevel]; } /// Do we currently have a valid spec? bool validspec () const { DASSERT ((m_validspec == false || m_subimages.size() > 0) && "validspec is true, but subimages are empty"); return m_validspec; } /// Forget the specs we know void invalidate_spec () { m_validspec = false; m_subimages.clear (); } private: ustring m_filename; ///< Filename bool m_used; ///< Recently used (in the LRU sense) bool m_broken; ///< has errors; can't be used properly shared_ptr m_input; ///< Open ImageInput, NULL if closed std::vector m_subimages; ///< Info on each subimage TexFormat m_texformat; ///< Which texture format TextureOpt::Wrap m_swrap; ///< Default wrap modes TextureOpt::Wrap m_twrap; ///< Default wrap modes TextureOpt::Wrap m_rwrap; ///< Default wrap modes Imath::M44f m_Mlocal; ///< shadows: world-to-local (light) matrix Imath::M44f m_Mproj; ///< shadows: world-to-pseudo-NDC Imath::M44f m_Mtex; ///< shadows: world-to-pNDC with camera z Imath::M44f m_Mras; ///< shadows: world-to-raster with camera z EnvLayout m_envlayout; ///< env map: which layout? bool m_y_up; ///< latlong: is y "up"? (else z is up) bool m_sample_border; ///< are edge samples exactly on the border? ustring m_fileformat; ///< File format name size_t m_tilesread; ///< Tiles read from this file imagesize_t m_bytesread; ///< Bytes read from this file size_t m_timesopened; ///< Separate times we opened this file double m_iotime; ///< I/O time for this file bool m_mipused; ///< MIP level >0 accessed std::vector m_mipreadcount; ///< Tile reads per mip level volatile bool m_validspec; ///< If false, reread spec upon open ImageCacheImpl &m_imagecache; ///< Back pointer for ImageCache mutable recursive_mutex m_input_mutex; ///< Mutex protecting the ImageInput std::time_t m_mod_time; ///< Time file was last updated ustring m_fingerprint; ///< Optional cryptographic fingerprint ImageCacheFile *m_duplicate; ///< Is this a duplicate? imagesize_t m_total_imagesize; ///< Total size, uncompressed ImageInput::Creator m_inputcreator; ///< Custom ImageInput-creator /// We will need to read pixels from the file, so be sure it's /// currently opened. Return true if ok, false if error. bool open (ImageCachePerThreadInfo *thread_info); bool opened () const { return m_input.get() != NULL; } /// Force the file to open, thread-safe. bool forceopen (ImageCachePerThreadInfo *thread_info) { recursive_lock_guard guard (m_input_mutex); return open (thread_info); } /// Close and delete the ImageInput, if currently open /// void close (void); /// Load the requested tile, from a file that's not really tiled. /// Preconditions: the ImageInput is already opened, and we already did /// a seek_subimage to the right subimage and MIP level. bool read_untiled (ImageCachePerThreadInfo *thread_info, int subimage, int miplevel, int x, int y, int z, TypeDesc format, void *data); /// Load the requested tile, from a file that's not really MIPmapped. /// Preconditions: the ImageInput is already opened, and we already did /// a seek_subimage to the right subimage. bool read_unmipped (ImageCachePerThreadInfo *thread_info, int subimage, int miplevel, int x, int y, int z, TypeDesc format, void *data); void lock_input_mutex () { m_input_mutex.lock (); } void unlock_input_mutex () { m_input_mutex.unlock (); } // Initialize a bunch of fields based on the ImageSpec. // FIXME -- this is actually deeply flawed, many of these things only // make sense if they are per subimage, not one value for the whole // file. But it will require a bigger refactor to fix that. void init_from_spec (); friend class ImageCacheImpl; friend class TextureSystemImpl; }; /// Reference-counted pointer to a ImageCacheFile /// typedef intrusive_ptr ImageCacheFileRef; /// Map file names to file references /// typedef unordered_map_concurrent, 8> FilenameMap; typedef boost::unordered_map FingerprintMap; /// Compact identifier for a particular tile of a particular image /// class TileID { public: /// Default constructor /// TileID () : m_file(NULL) { } /// Initialize a TileID based on full elaboration of image file, /// subimage, and tile x,y,z indices. TileID (ImageCacheFile &file, int subimage, int miplevel, int x, int y, int z=0) : m_x(x), m_y(y), m_z(z), m_subimage(subimage), m_miplevel(miplevel), m_file(&file) { } /// Destructor is trivial, because we don't hold any resources /// of our own. This is by design. ~TileID () { } ImageCacheFile &file (void) const { return *m_file; } ImageCacheFile *file_ptr (void) const { return m_file; } int subimage (void) const { return m_subimage; } int miplevel (void) const { return m_miplevel; } int x (void) const { return m_x; } int y (void) const { return m_y; } int z (void) const { return m_z; } void x (int v) { m_x = v; } void y (int v) { m_y = v; } void z (int v) { m_z = v; } /// Is this an uninitialized tileID? bool empty () const { return m_file == NULL; } /// Do the two ID's refer to the same tile? /// friend bool equal (const TileID &a, const TileID &b) { // Try to speed up by comparing field by field in order of most // probable rejection if they really are unequal. return (a.m_x == b.m_x && a.m_y == b.m_y && a.m_z == b.m_z && a.m_subimage == b.m_subimage && a.m_miplevel == b.m_miplevel && (a.m_file == b.m_file)); } /// Do the two ID's refer to the same tile, given that the /// caller *guarantees* that the two tiles point to the same /// file, subimage, and miplevel (so it only has to compare xyz)? friend bool equal_same_subimage (const TileID &a, const TileID &b) { DASSERT ((a.m_file == b.m_file) && a.m_subimage == b.m_subimage && a.m_miplevel == b.m_miplevel); return (a.m_x == b.m_x && a.m_y == b.m_y && a.m_z == b.m_z); } /// Do the two ID's refer to the same tile? /// bool operator== (const TileID &b) const { return equal (*this, b); } /// Digest the TileID into a size_t to use as a hash key. size_t hash () const { #if 0 // original -- turned out not to fill hash buckets evenly return m_x * 53 + m_y * 97 + m_z * 193 + m_subimage * 389 + m_miplevel * 1543 + m_file->filename().hash() * 769; #else // Good compromise! return bjhash::bjfinal (m_x+1543, m_y + 6151 + m_z*769, m_miplevel + (m_subimage<<8)) + m_file->filename().hash(); #endif } /// Functor that hashes a TileID class Hasher { public: size_t operator() (const TileID &a) const { return a.hash(); } }; private: int m_x, m_y, m_z; ///< x,y,z tile index within the subimage int m_subimage; ///< subimage int m_miplevel; ///< MIP-map level ImageCacheFile *m_file; ///< Which ImageCacheFile we refer to }; /// Record for a single image tile. /// class ImageCacheTile : public RefCnt { public: /// Construct a new tile, read the pixels from disk if read_now is true. /// Requires a pointer to the thread-specific IC data including /// microcache and statistics. ImageCacheTile (const TileID &id, ImageCachePerThreadInfo *thread_info, bool read_now=true); /// Construct a new tile out of the pixels supplied. /// ImageCacheTile (const TileID &id, const void *pels, TypeDesc format, stride_t xstride, stride_t ystride, stride_t zstride); ~ImageCacheTile (); /// Actually read the pixels. The caller had better be the thread /// that constructed the tile. void read (ImageCachePerThreadInfo *thread_info); /// Return pointer to the floating-point pixel data /// const float *data (void) const { return (const float *)&m_pixels[0]; } /// Return pointer to the floating-point pixel data for a particular /// pixel. Be extremely sure the pixel is within this tile! const void *data (int x, int y, int z=0) const; /// Return a pointer to the character data /// const unsigned char *bytedata (void) const { return (unsigned char *) &m_pixels[0]; } /// Return the id for this tile. /// const TileID& id (void) const { return m_id; } const ImageCacheFile & file () const { return m_id.file(); } /// Return the actual allocated memory size for this tile's pixels. /// size_t memsize () const { return m_pixels_size; } /// Return the space that will be needed for this tile's pixels. /// size_t memsize_needed () const { const ImageSpec &spec (file().spec(m_id.subimage(),m_id.miplevel())); TypeDesc datatype = file().datatype(id().subimage()); return spec.tile_pixels() * spec.nchannels * datatype.size(); } /// Mark the tile as recently used. /// void use () { m_used = 1; } /// Mark the tile as not recently used, return its previous value. /// bool release () { if (! pixels_ready() || ! valid()) return true; // Don't really release invalid or unready tiles // If m_used is 1, set it to zero and return true. If it was already // zero, it's fine and return false. return atomic_compare_and_exchange ((volatile int *)&m_used, 1, 0); } /// Has this tile been recently used? /// int used (void) const { return m_used; } bool valid (void) const { return m_valid; } /// Are the pixels ready for use? If false, they're still being /// read from disk. bool pixels_ready () const { return m_pixels_ready; } /// Spin until the pixels have been read and are ready for use. /// void wait_pixels_ready () const; private: TileID m_id; ///< ID of this tile boost::scoped_array m_pixels; ///< The pixel data size_t m_pixels_size; ///< How much m_pixels has allocated bool m_valid; ///< Valid pixels volatile bool m_pixels_ready; ///< The pixels have been read from disk atomic_int m_used; ///< Used recently }; /// Reference-counted pointer to a ImageCacheTile /// typedef intrusive_ptr ImageCacheTileRef; /// Hash table that maps TileID to ImageCacheTileRef -- this is the type of the /// main tile cache. typedef unordered_map_concurrent, 32> TileCache; /// A very small amount of per-thread data that saves us from locking /// the mutex quite as often. We store things here used by both /// ImageCache and TextureSystem, so they don't each need a costly /// thread_specific_ptr retrieval. There's no real penalty for this, /// even if you are using only ImageCache but not TextureSystem. struct ImageCachePerThreadInfo { // Store just a few filename/fileptr pairs static const int nlastfile = 4; ustring last_filename[nlastfile]; ImageCacheFile *last_file[nlastfile]; int next_last_file; // We have a two-tile "microcache", storing the last two tiles needed. ImageCacheTileRef tile, lasttile; atomic_int purge; // If set, tile ptrs need purging! ImageCacheStatistics m_stats; bool shared; // Pointed to both by the IC and the thread_specific_ptr ImageCachePerThreadInfo () : next_last_file(0), shared(false) { for (int i = 0; i < nlastfile; ++i) last_file[i] = NULL; purge = 0; } // Add a new filename/fileptr pair to our microcache void filename (ustring n, ImageCacheFile *f) { last_filename[next_last_file] = n; last_file[next_last_file] = f; ++next_last_file; next_last_file %= nlastfile; } // See if a filename has a fileptr in the microcache ImageCacheFile *find_file (ustring n) const { for (int i = 0; i < nlastfile; ++i) if (last_filename[i] == n) return last_file[i]; return NULL; } }; /// Working implementation of the abstract ImageCache class. /// /// Some of the methods require a pointer to the thread-specific IC data /// including microcache and statistics. /// class ImageCacheImpl : public ImageCache { public: ImageCacheImpl (); virtual ~ImageCacheImpl (); virtual bool attribute (const std::string &name, TypeDesc type, const void *val); virtual bool attribute (const std::string &name, int val) { return attribute (name, TypeDesc::INT, &val); } virtual bool attribute (const std::string &name, float val) { return attribute (name, TypeDesc::FLOAT, &val); } virtual bool attribute (const std::string &name, double val) { float f = (float) val; return attribute (name, TypeDesc::FLOAT, &f); } virtual bool attribute (const std::string &name, const char *val) { return attribute (name, TypeDesc::STRING, &val); } virtual bool attribute (const std::string &name, const std::string &val) { const char *s = val.c_str(); return attribute (name, TypeDesc::STRING, &s); } virtual bool getattribute (const std::string &name, TypeDesc type, void *val); virtual bool getattribute (const std::string &name, int &val) { return getattribute (name, TypeDesc::INT, &val); } virtual bool getattribute (const std::string &name, float &val) { return getattribute (name, TypeDesc::FLOAT, &val); } virtual bool getattribute (const std::string &name, double &val) { float f; bool ok = getattribute (name, TypeDesc::FLOAT, &f); if (ok) val = f; return ok; } virtual bool getattribute (const std::string &name, char **val) { return getattribute (name, TypeDesc::STRING, val); } virtual bool getattribute (const std::string &name, std::string &val) { const char *s = NULL; bool ok = getattribute (name, TypeDesc::STRING, &s); if (ok) val = s; return ok; } /// Close everything, free resources, start from scratch. /// virtual void clear () { } // Retrieve options int max_open_files () const { return m_max_open_files; } const std::string &searchpath () const { return m_searchpath; } const std::string &plugin_searchpath () const { return m_plugin_searchpath; } int autotile () const { return m_autotile; } bool autoscanline () const { return m_autoscanline; } bool automip () const { return m_automip; } bool forcefloat () const { return m_forcefloat; } bool accept_untiled () const { return m_accept_untiled; } bool accept_unmipped () const { return m_accept_unmipped; } bool unassociatedalpha () const { return m_unassociatedalpha; } int failure_retries () const { return m_failure_retries; } bool latlong_y_up_default () const { return m_latlong_y_up_default; } void get_commontoworld (Imath::M44f &result) const { result = m_Mc2w; } virtual std::string resolve_filename (const std::string &filename) const; /// Get information about the given image. /// virtual bool get_image_info (ustring filename, int subimage, int miplevel, ustring dataname, TypeDesc datatype, void *data); /// Get the ImageSpec associated with the named image. If the file /// is found and is an image format that can be read, store a copy /// of its specification in spec and return true. Return false if /// the file was not found or could not be opened as an image file /// by any available ImageIO plugin. virtual bool get_imagespec (ustring filename, ImageSpec &spec, int subimage=0, int miplevel=0, bool native=false); virtual const ImageSpec *imagespec (ustring filename, int subimage=0, int miplevel=0, bool native=false); // Retrieve a rectangle of raw unfiltered pixels. virtual bool get_pixels (ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result); virtual bool get_pixels (ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *result, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); /// Retrieve a rectangle of raw unfiltered pixels, from an open valid /// ImageCacheFile. bool get_pixels (ImageCacheFile *file, ImageCachePerThreadInfo *thread_info, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *result, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); /// Find the ImageCacheFile record for the named image, or NULL if /// no such file can be found. This returns a plain old pointer, /// which is ok because the file hash table has ref-counted pointers /// and those won't be freed until the texture system is destroyed. /// If header_only is true, we are finding the file only for the sake /// of header information (e.g., called by get_image_info). ImageCacheFile *find_file (ustring filename, ImageCachePerThreadInfo *thread_info, ImageInput::Creator creator=NULL, bool header_only=false); /// Is the tile specified by the TileID already in the cache? bool tile_in_cache (const TileID &id, ImageCachePerThreadInfo *thread_info) { TileCache::iterator found = m_tilecache.find (id); return (found != m_tilecache.end()); } /// Add the tile to the cache. This will also enforce cache memory /// limits. void add_tile_to_cache (ImageCacheTileRef &tile, ImageCachePerThreadInfo *thread_info); /// Find the tile specified by id. If found, return true and place /// the tile ref in thread_info->tile; if not found, return false. /// Try to avoid looking to the big cache (and locking) most of the /// time for fairly coherent tile access patterns, by using the /// per-thread microcache to boost our hit rate over the big cache. /// Inlined for speed. The tile is marked as 'used'. bool find_tile (const TileID &id, ImageCachePerThreadInfo *thread_info) { ++thread_info->m_stats.find_tile_calls; ImageCacheTileRef &tile (thread_info->tile); if (tile) { if (tile->id() == id) { tile->use (); return true; // already have the tile we want } // Tile didn't match, maybe lasttile will? Swap tile // and last tile. Then the new one will either match, // or we'll fall through and replace tile. tile.swap (thread_info->lasttile); if (tile && tile->id() == id) { tile->use (); return true; } } return find_tile_main_cache (id, tile, thread_info); // N.B. find_tile_main_cache marks the tile as used } virtual Tile *get_tile (ustring filename, int subimage, int miplevel, int x, int y, int z); virtual void release_tile (Tile *tile) const; virtual const void * tile_pixels (Tile *tile, TypeDesc &format) const; virtual bool add_file (ustring filename, ImageInput::Creator creator); virtual bool add_tile (ustring filename, int subimage, int miplevel, int x, int y, int z, TypeDesc format, const void *buffer, stride_t xstride, stride_t ystride, stride_t zstride); /// Return the numerical subimage index for the given subimage name, /// as stored in the "oiio:subimagename" metadata. Return -1 if no /// subimage matches its name. int subimage_from_name (ImageCacheFile *file, ustring subimagename); virtual std::string geterror () const; virtual std::string getstats (int level=1) const; virtual void reset_stats (); virtual void invalidate (ustring filename); virtual void invalidate_all (bool force=false); /// Merge all the per-thread statistics into one set of stats. /// void mergestats (ImageCacheStatistics &merged) const; void operator delete (void *todel) { ::delete ((char *)todel); } /// Called when a new file is opened, so that the system can track /// the number of simultaneously-opened files. void incr_open_files (void) { ++m_stat_open_files_created; ++m_stat_open_files_current; if (m_stat_open_files_current > m_stat_open_files_peak) m_stat_open_files_peak = m_stat_open_files_current; // FIXME -- can we make an atomic_max? } /// Called when a file is closed, so that the system can track /// the number of simultyaneously-opened files. void decr_open_files (void) { --m_stat_open_files_current; } /// Called when a new tile is created, to update all the stats. /// void incr_tiles (size_t size) { ++m_stat_tiles_created; ++m_stat_tiles_current; if (m_stat_tiles_current > m_stat_tiles_peak) m_stat_tiles_peak = m_stat_tiles_current; m_mem_used += size; } /// Called when a tile's pixel memory is allocated, but a new tile /// is not created. void incr_mem (size_t size) { m_mem_used += size; } /// Called when a tile is destroyed, to update all the stats. /// void decr_tiles (size_t size) { --m_stat_tiles_current; m_mem_used -= size; DASSERT (m_mem_used >= 0); } /// Internal error reporting routine, with printf-like arguments. /// /// void error (const char *message, ...); TINYFORMAT_WRAP_FORMAT (void, error, const, std::ostringstream msg;, msg, append_error(msg.str());) /// Append a string to the current error message void append_error (const std::string& message) const; /// Get a pointer to the caller's thread's per-thread info, or create /// one in the first place if there isn't one already. ImageCachePerThreadInfo *get_perthread_info (); /// Called when the IC is destroyed. We have a list of all the /// perthread pointers -- go through and delete the ones for which we /// hold the only remaining pointer. void erase_perthread_info (); /// This is called when the thread terminates. If p->m_imagecache /// is non-NULL, there's still an imagecache alive that might want /// the per-thread info (say, for statistics, though it's safe to /// clear its tile microcache), so don't delete the perthread info /// (it will be owned thereafter by the IC). If there is no IC still /// depending on it (signalled by m_imagecache == NULL), delete it. static void cleanup_perthread_info (ImageCachePerThreadInfo *p); /// Ensure that the max_memory_bytes is at least newsize bytes. /// Override the previous value if necessary, with thread-safety. void set_min_cache_size (long long newsize); /// Enforce the max number of open files. void check_max_files (ImageCachePerThreadInfo *thread_info); private: void init (); /// Find a tile identified by 'id' in the tile cache, paging it in if /// needed, and store a reference to the tile. Return true if ok, /// false if no such tile exists in the file or could not be read. bool find_tile_main_cache (const TileID &id, ImageCacheTileRef &tile, ImageCachePerThreadInfo *thread_info); /// Enforce the max memory for tile data. void check_max_mem (ImageCachePerThreadInfo *thread_info); /// Internal statistics printing routine /// void printstats () const; // Helper function for printstats() std::string onefile_stat_line (const ImageCacheFileRef &file, int i, bool includestats=true) const; /// Search the fingerprint table for the given fingerprint. If it /// doesn't already have an entry in the fingerprint map, then add /// one, mapping the it to file. In either case, return the file it /// maps to (the caller can tell if it was newly added to the table /// by whether the return value is the same as the passed-in file). /// All the while, properly maintain thread safety on the /// fingerprint table. ImageCacheFile *find_fingerprint (ustring finger, ImageCacheFile *file); /// Clear all the per-thread microcaches. void purge_perthread_microcaches (); /// Clear the fingerprint list, thread-safe. void clear_fingerprints (); thread_specific_ptr< ImageCachePerThreadInfo > m_perthread_info; std::vector m_all_perthread_info; static mutex m_perthread_info_mutex; ///< Thread safety for perthread int m_max_open_files; atomic_ll m_max_memory_bytes; std::string m_searchpath; ///< Colon-separated image directory list std::vector m_searchdirs; ///< Searchpath split into dirs std::string m_plugin_searchpath; ///< Colon-separated plugin directory list int m_autotile; ///< if nonzero, pretend tiles of this size bool m_autoscanline; ///< autotile using full width tiles bool m_automip; ///< auto-mipmap on demand? bool m_forcefloat; ///< force all cache tiles to be float bool m_accept_untiled; ///< Accept untiled images? bool m_accept_unmipped; ///< Accept unmipped images? bool m_read_before_insert; ///< Read tiles before adding to cache? bool m_deduplicate; ///< Detect duplicate files? bool m_unassociatedalpha; ///< Keep unassociated alpha files as they are? int m_failure_retries; ///< Times to re-try disk failures bool m_latlong_y_up_default; ///< Is +y the default "up" for latlong? Imath::M44f m_Mw2c; ///< world-to-"common" matrix Imath::M44f m_Mc2w; ///< common-to-world matrix ustring m_substitute_image; ///< Substitute this image for all others mutable FilenameMap m_files; ///< Map file names to ImageCacheFile's ustring m_file_sweep_name; ///< Sweeper for "clock" paging algorithm spin_mutex m_file_sweep_mutex; ///< Ensure only one in check_max_files spin_mutex m_fingerprints_mutex; ///< Protect m_fingerprints FingerprintMap m_fingerprints; ///< Map fingerprints to files TileCache m_tilecache; ///< Our in-memory tile cache TileID m_tile_sweep_id; ///< Sweeper for "clock" paging algorithm spin_mutex m_tile_sweep_mutex; ///< Ensure only one in check_max_mem atomic_ll m_mem_used; ///< Memory being used for tiles int m_statslevel; ///< Statistics level /// Saved error string, per-thread /// mutable thread_specific_ptr< std::string > m_errormessage; // For debugging -- keep track of who holds the tile and file mutex private: // Statistics that are really hard to track per-thread atomic_int m_stat_tiles_created; atomic_int m_stat_tiles_current; atomic_int m_stat_tiles_peak; atomic_int m_stat_open_files_created; atomic_int m_stat_open_files_current; atomic_int m_stat_open_files_peak; // Simulate an atomic double with a long long! void incr_time_stat (double &stat, double incr) { stat += incr; return; #ifdef NOTHREADS stat += incr; #else DASSERT (sizeof (atomic_ll) == sizeof(double)); double oldval, newval; long long *lloldval = (long long *)&oldval; long long *llnewval = (long long *)&newval; atomic_ll *llstat = (atomic_ll *)&stat; // Make long long and atomic_ll pointers to the doubles in question. do { // Grab the double bits, shove into a long long *lloldval = *llstat; // increment newval = oldval + incr; // Now try to atomically swap it, and repeat until we've // done it with nobody else interfering. # if USE_TBB_ATOMIC } while (llstat->compare_and_swap (*llnewval,*lloldval) != *lloldval); # else } while (llstat->bool_compare_and_swap (*llnewval,*lloldval)); # endif #endif } }; } // end namespace pvt } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_IMAGECACHE_PVT_H openimageio-1.3.12~dfsg0.orig/src/iv/0000755000175000017500000000000012271062644015526 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/iv/ivgl.h0000644000175000017500000002142712271062644016646 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_IVGL_H #define OPENIMAGEIO_IVGL_H #if defined (_MSC_VER) // Ignore warnings about conditional expressions that always evaluate true // on a given platform but may evaluate differently on another. There's // nothing wrong with such conditionals. // Also ignore warnings about not being able to generate default assignment // operators for some Qt classes included in headers below. # pragma warning (disable : 4127 4512) #endif // included to remove std::min/std::max errors #include "osdep.h" #include // This needs to be included before GL.h #include #include #include "imageio.h" #include "imagebuf.h" OIIO_NAMESPACE_USING; class IvImage; class ImageViewer; class IvGL : public QGLWidget { Q_OBJECT public: IvGL (QWidget *parent, ImageViewer &viewer); virtual ~IvGL (); /// Update the image texture. /// virtual void update (); /// Update the view -- center (in pixel coordinates) and zoom level. /// virtual void view (float centerx, float centery, float zoom, bool redraw=true); /// Update just the zoom, keep the old center /// void zoom (float newzoom, bool redraw=true); /// Update just the center (in pixel coordinates), keep the old zoom. /// void center (float x, float y, bool redraw=true); /// Get the center of the view, in pixel coordinates. /// void get_center (float &x, float &y) { x = m_centerx; y = m_centery; } void pan (float dx, float dy); /// Let the widget know which pixel the mouse is over /// void remember_mouse (const QPoint &pos); /// Which image pixel is the mouse over? /// void get_focus_image_pixel (int &x, int &y); /// Which display window pixel is the mouse over? (Relative to /// widget boundaries) void get_focus_window_pixel (int &x, int &y); void trigger_redraw (void) { glDraw(); } /// Returns true if OpenGL is capable of loading textures in the sRGB color /// space. bool is_srgb_capable (void) const { return m_use_srgb; } /// Returns true if OpenGL can use GLSL, either with extensions or as /// implementation of version 2.0 bool is_glsl_capable (void) const { return m_use_shaders; } /// Is OpenGL capable of reading half-float textures? /// bool is_half_capable (void) const { return m_use_halffloat; } /// Returns true if the image is too big to fit within allocated textures /// (i.e., it's recommended to use lower resolution versions when zoomed out). bool is_too_big (float width, float height); void typespec_to_opengl (const ImageSpec& spec, int nchannels, GLenum &gltype, GLenum &glformat, GLenum &glinternal) const; protected: ImageViewer &m_viewer; ///< Backpointer to viewer bool m_shaders_created; ///< Have the shaders been created? GLuint m_vertex_shader; ///< Vertex shader id GLuint m_fragment_shader; ///< Fragment shader id GLuint m_shader_program; ///< GL shader program id bool m_tex_created; ///< Have the textures been created? float m_zoom; ///< Zoom ratio float m_centerx, m_centery; ///< Center of view, in pixel coords bool m_dragging; ///< Are we dragging? int m_mousex, m_mousey; ///< Last mouse position Qt::MouseButton m_drag_button; ///< Button on when dragging bool m_use_shaders; ///< Are shaders supported? bool m_shaders_using_extensions; ///< Are we using ARB_*_shader? bool m_use_halffloat; ///< Are half-float textures supported? bool m_use_float; ///< Are float textures supported? bool m_use_srgb; ///< Are sRGB-space textures supported? bool m_use_npot_texture; ///< Can we handle NPOT textures? bool m_use_pbo; ///< Can we use PBO to upload the texture? GLint m_max_texture_size; ///< Maximum allowed texture dimension. GLsizei m_texture_width; GLsizei m_texture_height; GLuint m_pbo_objects[2]; ///< Pixel buffer objects int m_last_pbo_used; ///< Last used pixel buffer object. IvImage *m_current_image; ///< Image to show on screen. GLuint m_pixelview_tex; ///< Pixelview's own texture. bool m_pixelview_left_corner; ///< Draw pixelview in upper left or right /// Buffer passed to IvImage::copy_image when not using PBO. /// std::vector m_tex_buffer; /// Represents a texture object being used as a buffer. /// struct TexBuffer { GLuint tex_object; int x; int y; int width; int height; }; std::vector m_texbufs; int m_last_texbuf_used; bool m_mouse_activation; ///< Can we expect the window to be activated by mouse? virtual void initializeGL (); virtual void resizeGL (int w, int h); virtual void paintGL (); virtual void mousePressEvent (QMouseEvent *event); virtual void mouseReleaseEvent (QMouseEvent *event); virtual void mouseMoveEvent (QMouseEvent *event); virtual void wheelEvent (QWheelEvent *event); virtual void focusOutEvent (QFocusEvent *event); void paint_pixelview (); void glSquare (float xmin, float ymin, float xmax, float ymax, float z=0); virtual void create_shaders (void); virtual void create_textures (void); virtual void useshader (int tex_width, int tex_height, bool pixelview=false); void shadowed_text (float x, float y, float z, const std::string &s, const QFont &font); private: typedef QGLWidget parent_t; /// ncloseuppixels is the number of big pixels (in each direction) /// visible in our closeup window. const static int ncloseuppixels = 9; /// closeuppixelzoom is the zoom factor we use for closeup pixels -- /// i.e. one image pixel will appear in the closeup window as a /// closeuppixelzoom x closeuppixelzoom square. const static int closeuppixelzoom = 24; /// closeupsize is the size, in pixels, of the closeup window itself -- /// just the number of pixels times the width of each closeup pixel. const static int closeupsize = ncloseuppixels * closeuppixelzoom; /// closeuptexsize is the size of the texture used to upload the pixelview /// to OpenGL. const static int closeuptexsize = 16; void clamp_view_to_window (); // Small wrappers to handle ARB shaders. void gl_use_program (int program); GLint gl_get_uniform_location (const char*); void gl_uniform (GLint location, float value); void gl_uniform (GLint location, int value); /// checks what OpenGL extensions we have /// void check_gl_extensions (void); /// print shader info to out stream /// void print_shader_log (std::ostream& out, const GLuint shader_id) const; /// Loads the given patch of the image, but first figures if it's already /// been loaded. void load_texture (int x, int y, int width, int height, float percent); /// Destroys shaders and selects fixed-function pipeline void create_shaders_abort (void); }; #endif // OPENIMAGEIO_IVGL_H openimageio-1.3.12~dfsg0.orig/src/iv/ivutils.h0000644000175000017500000000164212271062644017401 0ustar mfvmfv#ifndef OPENIMAGEIO_IV_UTILS_H #define OPENIMAGEIO_IV_UTILS_H #include "fmath.h" OIIO_NAMESPACE_ENTER { /// Round up to the next power of 2 /// TODO: This should be optimized to use bit arithmetic on the ieee float /// representation. Once optimized and tested, move to fmath.h inline float pow2roundupf (float f) { float logval = logf (f) / logf (2.0f); logval += 1e-6f; // add floating point slop. this supports [0.00012207,8192] return powf (2.0f, ceilf (logval)); } /// Round down to the next power of 2 /// TODO: This should be optimized to use bit arithmetic on the ieee float /// representation. Once optimized and tested, move to fmath.h inline float pow2rounddownf (float f) { float logval = logf (f) / logf (2.0f); logval -= 1e-6f; // add floating point slop. this supports [0.00012207,8192] return powf (2.0f, floorf (logval)); } } OIIO_NAMESPACE_EXIT #endif // OPENIMAGEIO_IV_UTILS_H openimageio-1.3.12~dfsg0.orig/src/iv/ivpref.cpp0000644000175000017500000000643012271062644017530 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include "imageviewer.h" #include "dassert.h" #include "strutil.h" IvPreferenceWindow::IvPreferenceWindow (ImageViewer &viewer) : QDialog(&viewer), m_viewer(viewer) { closeButton = new QPushButton (tr("Close")); closeButton->setShortcut (tr("Ctrl+W")); connect (closeButton, SIGNAL(clicked()), this, SLOT(hide())); layout = new QVBoxLayout; layout->addWidget (viewer.pixelviewFollowsMouseBox); layout->addWidget (viewer.linearInterpolationBox); layout->addWidget (viewer.darkPaletteBox); layout->addWidget (viewer.autoMipmap); QLayout *inner_layout = new QHBoxLayout; inner_layout->addWidget (viewer.maxMemoryICLabel); inner_layout->addWidget (viewer.maxMemoryIC); QLayout *slideShowLayout = new QHBoxLayout; slideShowLayout->addWidget (viewer.slideShowDurationLabel); slideShowLayout->addWidget (viewer.slideShowDuration); layout->addLayout (inner_layout); layout->addLayout (slideShowLayout); layout->addWidget (closeButton); setLayout (layout); setWindowTitle (tr("iv Preferences")); } void IvPreferenceWindow::keyPressEvent (QKeyEvent *event) { // if (event->key() == 'w' && (event->modifiers() & Qt::ControlModifier)) { if (event->key() == Qt::Key_W) { std::cerr << "found w\n"; if ((event->modifiers() & Qt::ControlModifier)) { std::cerr << "think we did ctrl-w\n"; event->accept(); hide(); } else std::cerr << "modifier " << (int)event->modifiers() << "\n"; } else { event->ignore(); } } openimageio-1.3.12~dfsg0.orig/src/iv/ivimage.cpp0000644000175000017500000003416012271062644017657 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "imageviewer.h" #include "strutil.h" #include "fmath.h" IvImage::IvImage (const std::string &filename) : ImageBuf(filename), m_thumbnail(NULL), m_thumbnail_valid(false), m_gamma(1), m_exposure(0), m_file_dataformat(TypeDesc::UNKNOWN), m_image_valid(false), m_auto_subimage(false) { } IvImage::~IvImage () { delete [] m_thumbnail; } bool IvImage::init_spec_iv (const std::string &filename, int subimage, int miplevel) { // invalidate info strings m_shortinfo.clear (); m_longinfo.clear (); // If we're changing mip levels or subimages, the pixels will no // longer be valid. if (subimage != this->subimage() || miplevel != this->miplevel()) m_image_valid = false; bool ok = ImageBuf::init_spec (filename, subimage, miplevel); if (ok && m_file_dataformat.basetype == TypeDesc::UNKNOWN) { m_file_dataformat = spec().format; } return ok; } bool IvImage::read_iv (int subimage, int miplevel, bool force, TypeDesc format, ProgressCallback progress_callback, void *progress_callback_data, bool secondary_data) { // Don't read if we already have it in memory, unless force is true. // FIXME: should we also check the time on the file to see if it's // been updated since we last loaded? if (m_image_valid && !force && subimage == this->subimage() && miplevel != this->miplevel()) return true; m_image_valid = init_spec_iv (name(), subimage, miplevel); if (m_image_valid) m_image_valid = ImageBuf::read (subimage, miplevel, force, format, progress_callback, progress_callback_data); if (m_image_valid && secondary_data && spec().format == TypeDesc::UINT8) { m_corrected_image.reset ("", ImageSpec (spec().width, spec().height, std::min(spec().nchannels, 4), spec().format)); } else { m_corrected_image.clear (); } return m_image_valid; } std::string IvImage::shortinfo () const { if (m_shortinfo.empty()) { m_shortinfo = Strutil::format ("%d x %d", spec().width, spec().height); if (spec().depth > 1) m_shortinfo += Strutil::format (" x %d", spec().depth); m_shortinfo += Strutil::format (" x %d channel %s (%.2f MB)", spec().nchannels, m_file_dataformat.c_str(), (float)spec().image_bytes() / (1024.0*1024.0)); } return m_shortinfo; } // Format name/value pairs as HTML table entries. std::string html_table_row (const char *name, const std::string &value) { std::string line = Strutil::format ("%s :   ", name); line += Strutil::format ("%s\n", value.c_str()); return line; } std::string html_table_row (const char *name, int value) { return html_table_row (name, Strutil::format ("%d", value)); } std::string html_table_row (const char *name, float value) { return html_table_row (name, Strutil::format ("%g", value)); } std::string IvImage::longinfo () const { using Strutil::format; // shorthand if (m_longinfo.empty()) { const ImageSpec &m_spec (nativespec()); m_longinfo += ""; // m_longinfo += html_table_row (format("%s", m_name.c_str()).c_str(), // std::string()); if (m_spec.depth <= 1) m_longinfo += html_table_row ("Dimensions", format ("%d x %d pixels", m_spec.width, m_spec.height)); else m_longinfo += html_table_row ("Dimensions", format ("%d x %d x %d pixels", m_spec.width, m_spec.height, m_spec.depth)); m_longinfo += html_table_row ("Channels", m_spec.nchannels); std::string chanlist; for (int i = 0; i < m_spec.nchannels; ++i) { chanlist += m_spec.channelnames[i].c_str(); if (i != m_spec.nchannels-1) chanlist += ", "; } m_longinfo += html_table_row ("Channel list", chanlist); m_longinfo += html_table_row ("File format", file_format_name()); m_longinfo += html_table_row ("Data format", m_file_dataformat.c_str()); m_longinfo += html_table_row ("Data size", format("%.2f MB", (float)m_spec.image_bytes() / (1024.0*1024.0))); m_longinfo += html_table_row ("Image origin", format ("%d, %d, %d", m_spec.x, m_spec.y, m_spec.z)); m_longinfo += html_table_row ("Full/display size", format ("%d x %d x %d", m_spec.full_width, m_spec.full_height, m_spec.full_depth)); m_longinfo += html_table_row ("Full/display origin", format ("%d, %d, %d", m_spec.full_x, m_spec.full_y, m_spec.full_z)); if (m_spec.tile_width) m_longinfo += html_table_row ("Scanline/tile", format ("tiled %d x %d x %d", m_spec.tile_width, m_spec.tile_height, m_spec.tile_depth)); else m_longinfo += html_table_row ("Scanline/tile", "scanline"); if (m_spec.alpha_channel >= 0) m_longinfo += html_table_row ("Alpha channel", m_spec.alpha_channel); if (m_spec.z_channel >= 0) m_longinfo += html_table_row ("Depth (z) channel", m_spec.z_channel); BOOST_FOREACH (const ImageIOParameter &p, m_spec.extra_attribs) { std::string s = m_spec.metadata_val (p, true); m_longinfo += html_table_row (p.name().c_str(), s); } m_longinfo += "
"; } return m_longinfo; } // Used by pixel_transform to convert from UINT8 to float. static EightBitConverter converter; /// Helper routine: compute (gain*value)^invgamma /// namespace { inline float calc_exposure (float value, float gain, float invgamma) { if (invgamma != 1 && value >= 0) return powf (gain * value, invgamma); // Simple case - skip the expensive pow; also fall back to this // case for negative values, for which gamma makes no sense. return gain * value; } } void IvImage::pixel_transform(bool srgb_to_linear, int color_mode, int select_channel) { /// This table obeys the following function: /// /// unsigned char srgb2linear(unsigned char x) /// { /// float x_f = x/255.0; /// float x_l = 0.0; /// if (x_f <= 0.04045) /// x_l = x_f/12.92; /// else /// x_l = powf((x_f+0.055)/1.055,2.4); /// return (unsigned char)(x_l * 255 + 0.5) /// } /// /// It's used to transform from sRGB color space to linear color space. static const unsigned char srgb_to_linear_lut[256] = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 37, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 130, 131, 133, 134, 136, 138, 139, 141, 142, 144, 146, 147, 149, 151, 152, 154, 156, 157, 159, 161, 163, 164, 166, 168, 170, 171, 173, 175, 177, 179, 181, 183, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 229, 231, 233, 235, 237, 239, 242, 244, 246, 248, 250, 253, 255 }; unsigned char correction_table[256]; int total_channels = spec().nchannels; int color_channels = spec().nchannels; int max_channels = m_corrected_image.nchannels(); // FIXME: Now with the iterator and data proxy in place, it should be // trivial to apply the transformations to any kind of data, not just // UINT8. if (spec().format != TypeDesc::UINT8 || ! m_corrected_image.localpixels()) { return; } if (color_channels > 3) { color_channels = 3; } else if (color_channels == 2) { color_channels = 1; } // This image is Luminance or Luminance + Alpha, and we are asked to show // luminance. if (color_channels == 1 && color_mode == 3) { color_mode = 0; // Just copy as usual. } // Happy path: if (! srgb_to_linear && color_mode <= 1 && m_gamma == 1.0 && m_exposure == 0.0) { ImageBuf::ConstIterator src (*this); ImageBuf::Iterator dst (m_corrected_image); for ( ; src.valid (); ++src) { dst.pos (src.x(), src.y()); for (int i = 0; i < max_channels; i++) dst[i] = src[i]; } return; } // fill the correction_table if (gamma() == 1.0 && exposure() == 0.0) { for (int pixelvalue = 0; pixelvalue < 256; ++pixelvalue) { correction_table[pixelvalue] = pixelvalue; } } else { float inv_gamma = 1.0/gamma(); float gain = powf (2.0f, exposure()); for (int pixelvalue = 0; pixelvalue < 256; ++pixelvalue) { float pv_f = converter (pixelvalue); pv_f = clamp (calc_exposure (pv_f, gain, inv_gamma), 0.0f, 1.0f); correction_table[pixelvalue] = (unsigned char) (pv_f*255 + 0.5); } } ImageBuf::ConstIterator src (*this); ImageBuf::Iterator dst (m_corrected_image); for ( ; src.valid(); ++src) { dst.pos (src.x(), src.y()); if (color_mode == 0 || color_mode == 1) { // RGBA, RGB modes. int ch = 0; for (ch = 0; ch < color_channels; ch++) { if (srgb_to_linear) dst[ch] = correction_table[srgb_to_linear_lut[src[ch]]]; else dst[ch] = correction_table[src[ch]]; } for (; ch < max_channels; ch++) { dst[ch] = src[ch]; } } else if (color_mode == 3) { // Convert RGB to luminance, (Rec. 709 luma coefficients). float luminance; if (srgb_to_linear) { luminance = converter (srgb_to_linear_lut[src[0]])*0.2126f + converter (srgb_to_linear_lut[src[1]])*0.7152f + converter (srgb_to_linear_lut[src[2]])*0.0722f; } else { luminance = converter (src[0])*0.2126f + converter (src[1])*0.7152f + converter (src[2])*0.0722f; } unsigned char val = (unsigned char) (clamp (luminance, 0.0f, 1.0f) * 255.0 + 0.5); val = correction_table[val]; dst[0] = val; dst[1] = val; dst[2] = val; // Handle the rest of the channels for (int ch = 3; ch < total_channels; ++ch) { dst[ch] = src[ch]; } } else { // Single channel, heatmap. unsigned char v = 0; if (select_channel < color_channels) { if (srgb_to_linear) v = correction_table[srgb_to_linear_lut[src[select_channel]]]; else v = correction_table[src[select_channel]]; } else if (select_channel < total_channels) { v = src[select_channel]; } int ch = 0; for (; ch < color_channels; ++ch) { dst[ch] = v; } for (; ch < max_channels; ++ch) { dst[ch] = src[ch]; } } } } void IvImage::invalidate () { ustring filename (name()); reset (filename.string()); m_thumbnail_valid = false; m_image_valid = false; if (imagecache()) imagecache()->invalidate (filename); } openimageio-1.3.12~dfsg0.orig/src/iv/ivgl.cpp0000644000175000017500000015732212271062644017205 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "imageviewer.h" #include "ivgl.h" #include // This needs to be included before GL.h // (which is included by QtOpenGL and QGLFormat) #include #include #include #include #include #include #include #include #include using boost::algorithm::iequals; #include #include #include #include #include "ivutils.h" #include "strutil.h" #include "fmath.h" #include "timer.h" static const char * gl_err_to_string (GLenum err) { // Thanks, Dan Wexler, for this function switch (err) { case GL_NO_ERROR: return "No error"; case GL_INVALID_ENUM: return "Invalid enum"; case GL_INVALID_OPERATION: return "Invalid operation"; case GL_INVALID_VALUE: return "Invalid value"; case GL_OUT_OF_MEMORY: return "Out of memory"; case GL_INVALID_FRAMEBUFFER_OPERATION: return "Invalid framebuffer operation"; default: return "Unknown"; } } #define GLERRPRINT(msg) \ for (GLenum err = glGetError(); err != GL_NO_ERROR; err = glGetError()) \ std::cerr << "GL error " << msg << " " << (int)err << " - " << gl_err_to_string(err) << "\n"; \ IvGL::IvGL (QWidget *parent, ImageViewer &viewer) : QGLWidget(parent), m_viewer(viewer), m_shaders_created(false), m_tex_created(false), m_zoom(1.0), m_centerx(0), m_centery(0), m_dragging(false), m_use_shaders(false), m_shaders_using_extensions(false), m_use_halffloat(false), m_use_float(false), m_use_srgb(false), m_use_pbo(false), m_texture_width(1), m_texture_height(1), m_last_pbo_used(0), m_current_image(NULL), m_pixelview_left_corner(true), m_last_texbuf_used(0) { #if 0 QGLFormat format; format.setRedBufferSize (32); format.setGreenBufferSize (32); format.setBlueBufferSize (32); format.setAlphaBufferSize (32); format.setDepth (true); setFormat (format); #endif m_mouse_activation = false; this->setFocusPolicy (Qt::StrongFocus); setMouseTracking (true); } IvGL::~IvGL () { } void IvGL::initializeGL () { GLenum glew_error = glewInit (); if (glew_error != GLEW_OK) { std::cerr << "GLEW init error " << glewGetErrorString (glew_error) << "\n"; } glClearColor (0.05f, 0.05f, 0.05f, 1.0f); glShadeModel (GL_FLAT); glEnable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glEnable (GL_BLEND); glEnable (GL_TEXTURE_2D); // glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Make sure initial matrix is identity (returning to this stack level loads // back this matrix). glLoadIdentity(); // There's this small detail in the OpenGL 2.1 (probably earlier versions // too) spec: // // (For TexImage3D, TexImage2D and TexImage1D): // The values of UNPACK ROW LENGTH and UNPACK ALIGNMENT control the row-to- // row spacing in these images in the same manner as DrawPixels. // // UNPACK_ALIGNMENT has a default value of 4 according to the spec. Which // means that it was expecting images to be Aligned to 4-bytes, and making // several odd "skew-like effects" in the displayed images. Setting the // alignment to 1 byte fixes this problems. glPixelStorei (GL_UNPACK_ALIGNMENT, 1); // here we check what OpenGL extensions are available, and take action // if needed check_gl_extensions (); create_textures (); create_shaders (); } void IvGL::create_textures (void) { if (m_tex_created) return; // FIXME: Determine this dynamically. const int total_texbufs = 4; GLuint textures[total_texbufs]; glGenTextures (total_texbufs, textures); // Initialize texture objects for (int i = 0; i < total_texbufs; i++) { m_texbufs.push_back (TexBuffer()); glBindTexture (GL_TEXTURE_2D, textures[i]); GLERRPRINT ("bind tex"); glTexImage2D (GL_TEXTURE_2D, 0 /*mip level*/, 4 /*internal format - color components */, 1 /*width*/, 1 /*height*/, 0 /*border width*/, GL_RGBA /*type - GL_RGB, GL_RGBA, GL_LUMINANCE */, GL_FLOAT /*format - GL_FLOAT */, NULL /*data*/); GLERRPRINT ("tex image 2d"); // Initialize tex parameters. glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); GLERRPRINT ("After tex parameters"); m_texbufs.back().tex_object = textures[i]; m_texbufs.back().x = 0; m_texbufs.back().y = 0; m_texbufs.back().width = 0; m_texbufs.back().height = 0; } // Create another texture for the pixelview. glGenTextures (1, &m_pixelview_tex); glBindTexture (GL_TEXTURE_2D, m_pixelview_tex); glTexImage2D (GL_TEXTURE_2D, 0, 4, closeuptexsize, closeuptexsize, 0, GL_RGBA, GL_FLOAT, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (m_use_pbo) { glGenBuffersARB(2, m_pbo_objects); glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo_objects[0]); glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo_objects[1]); glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); } m_tex_created = true; } void IvGL::create_shaders (void) { static const GLchar *vertex_source = "varying vec2 vTexCoord;\n" "void main ()\n" "{\n" " vTexCoord = gl_MultiTexCoord0.xy;\n" " gl_Position = ftransform();\n" "}\n"; static const GLchar *fragment_source = "uniform sampler2D imgtex;\n" "varying vec2 vTexCoord;\n" "uniform float gain;\n" "uniform float gamma;\n" "uniform int startchannel;\n" "uniform int colormode;\n" // Remember, if imgchannels == 2, second channel would be channel 4 (a). "uniform int imgchannels;\n" "uniform int pixelview;\n" "uniform int linearinterp;\n" "uniform int width;\n" "uniform int height;\n" "vec4 rgba_mode (vec4 C)\n" "{\n" " if (imgchannels <= 2) {\n" " if (startchannel == 1)\n" " return vec4(C.aaa, 1.0);\n" " return C.rrra;\n" " }\n" " return C;\n" "}\n" "vec4 rgb_mode (vec4 C)\n" "{\n" " if (imgchannels <= 2) {\n" " if (startchannel == 1)\n" " return vec4(C.aaa, 1.0);\n" " return vec4 (C.rrr, 1.0);\n" " }\n" " float C2[4];\n" " C2[0]=C.x; C2[1]=C.y; C2[2]=C.z; C2[3]=C.w;\n" " return vec4 (C2[startchannel], C2[startchannel+1], C2[startchannel+2], 1.0);\n" "}\n" "vec4 singlechannel_mode (vec4 C)\n" "{\n" " float C2[4];\n" " C2[0]=C.x; C2[1]=C.y; C2[2]=C.z; C2[3]=C.w;\n" " if (startchannel > imgchannels)\n" " return vec4 (0.0,0.0,0.0,1.0);\n" " return vec4 (C2[startchannel], C2[startchannel], C2[startchannel], 1.0);\n" "}\n" "vec4 luminance_mode (vec4 C)\n" "{\n" " if (imgchannels <= 2)\n" " return vec4 (C.rrr, C.a);\n" " float lum = dot (C.rgb, vec3(0.2126, 0.7152, 0.0722));\n" " return vec4 (lum, lum, lum, C.a);\n" "}\n" "float heat_red(float x)\n" "{\n" " return clamp (mix(0.0, 1.0, (x-0.35)/(0.66-0.35)), 0.0, 1.0) -\n" " clamp (mix(0.0, 0.5, (x-0.89)/(1.0-0.89)), 0.0, 1.0);\n" "}\n" "float heat_green(float x)\n" "{\n" " return clamp (mix(0.0, 1.0, (x-0.125)/(0.375-0.125)), 0.0, 1.0) -\n" " clamp (mix(0.0, 1.0, (x-0.64)/(0.91-0.64)), 0.0, 1.0);\n" "}\n" "vec4 heatmap_mode (vec4 C)\n" "{\n" " float C2[4];\n" " C2[0]=C.x; C2[1]=C.y; C2[2]=C.z; C2[3]=C.w;\n" " return vec4(heat_red(C2[startchannel]),\n" " heat_green(C2[startchannel]),\n" " heat_red(1.0-C2[startchannel]),\n" " 1.0);\n" "}\n" "void main ()\n" "{\n" " vec2 st = vTexCoord;\n" " float black = 0.0;\n" " if (pixelview != 0 || linearinterp == 0) {\n" " vec2 wh = vec2(width,height);\n" " vec2 onehalf = vec2(0.5,0.5);\n" " vec2 st_res = st * wh /* + onehalf */ ;\n" " vec2 st_pix = floor (st_res);\n" " vec2 st_rem = st_res - st_pix;\n" " st = (st_pix + onehalf) / wh;\n" " if (pixelview != 0) {\n" " if (st.x < 0.0 || st.x >= 1.0 || \n" " st.y < 0.0 || st.y >= 1.0 || \n" " st_rem.x < 0.05 || st_rem.x >= 0.95 || \n" " st_rem.y < 0.05 || st_rem.y >= 0.95)\n" " black = 1.0;\n" " }\n" " }\n" " vec4 C = texture2D (imgtex, st);\n" " C = mix (C, vec4(0.05,0.05,0.05,1.0), black);\n" " if (startchannel < 0)\n" " C = vec4(0.0,0.0,0.0,1.0);\n" " else if (colormode == 0)\n" // RGBA " C = rgba_mode (C);\n" " else if (colormode == 1)\n" // RGB (i.e., ignore alpha). " C = rgb_mode (C);\n" " else if (colormode == 2)\n" // Single channel. " C = singlechannel_mode (C);\n" " else if (colormode == 3)\n" // Luminance. " C = luminance_mode (C);\n" " else if (colormode == 4)\n" // Heatmap. " C = heatmap_mode (C);\n" " if (pixelview != 0)\n" " C.a = 1.0;\n" " C.xyz *= gain;\n" " float invgamma = 1.0/gamma;\n" " C.xyz = pow (C.xyz, vec3 (invgamma, invgamma, invgamma));\n" " gl_FragColor = C;\n" "}\n"; if (!m_use_shaders) { std::cerr << "Not using shaders!\n"; return; } if (m_shaders_created) return; //initialize shader object handles for abort function m_shader_program = 0; m_vertex_shader = 0; m_fragment_shader = 0; // When using extensions to support shaders, we need to load the function // entry points (which is actually done by GLEW) and then call them. So // we have to get the functions through the right symbols otherwise // extension-based shaders won't work. if (m_shaders_using_extensions) { m_shader_program = glCreateProgramObjectARB (); } else { m_shader_program = glCreateProgram (); } GLERRPRINT ("create progam"); // This holds the compilation status GLint status; if (m_shaders_using_extensions) { m_vertex_shader = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB); glShaderSourceARB (m_vertex_shader, 1, &vertex_source, NULL); glCompileShaderARB (m_vertex_shader); glGetObjectParameterivARB (m_vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &status); } else { m_vertex_shader = glCreateShader (GL_VERTEX_SHADER); glShaderSource (m_vertex_shader, 1, &vertex_source, NULL); glCompileShader (m_vertex_shader); glGetShaderiv (m_vertex_shader, GL_COMPILE_STATUS, &status); } if (! status) { std::cerr << "vertex shader compile status: " << status << "\n"; print_shader_log (std::cerr, m_vertex_shader); create_shaders_abort (); return; } if (m_shaders_using_extensions) { glAttachObjectARB (m_shader_program, m_vertex_shader); } else { glAttachShader (m_shader_program, m_vertex_shader); } GLERRPRINT ("After attach vertex shader."); if (m_shaders_using_extensions) { m_fragment_shader = glCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB); glShaderSourceARB (m_fragment_shader, 1, &fragment_source, NULL); glCompileShaderARB (m_fragment_shader); glGetObjectParameterivARB (m_fragment_shader, GL_OBJECT_COMPILE_STATUS_ARB, &status); } else { m_fragment_shader = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (m_fragment_shader, 1, &fragment_source, NULL); glCompileShader (m_fragment_shader); glGetShaderiv (m_fragment_shader, GL_COMPILE_STATUS, &status); } if (! status) { std::cerr << "fragment shader compile status: " << status << "\n"; print_shader_log(std::cerr, m_fragment_shader); create_shaders_abort (); return; } if (m_shaders_using_extensions) { glAttachObjectARB (m_shader_program, m_fragment_shader); } else { glAttachShader (m_shader_program, m_fragment_shader); } GLERRPRINT ("After attach fragment shader"); if (m_shaders_using_extensions) { glLinkProgramARB (m_shader_program); } else { glLinkProgram (m_shader_program); } GLERRPRINT ("link"); GLint linked; if (m_shaders_using_extensions) { glGetObjectParameterivARB (m_shader_program, GL_OBJECT_LINK_STATUS_ARB, &linked); } else { glGetProgramiv (m_shader_program, GL_LINK_STATUS, &linked); } if (! linked) { std::cerr << "NOT LINKED\n"; char buf[10000]; buf[0] = 0; GLsizei len; if (m_shaders_using_extensions) { glGetInfoLogARB (m_shader_program, sizeof(buf), &len, buf); } else { glGetProgramInfoLog (m_shader_program, sizeof(buf), &len, buf); } std::cerr << "link log:\n" << buf << "---\n"; create_shaders_abort (); return; } m_shaders_created = true; } void IvGL::create_shaders_abort (void) { if (m_shaders_using_extensions) { glUseProgramObjectARB (0); if (m_shader_program) //this will also detach related shaders glDeleteObjectARB (m_shader_program); if (m_vertex_shader) glDeleteObjectARB (m_vertex_shader); if (m_fragment_shader) glDeleteObjectARB (m_fragment_shader); } else { glUseProgram (0); if (m_shader_program) glDeleteProgram (m_shader_program); if (m_vertex_shader) glDeleteShader (m_vertex_shader); if (m_fragment_shader) glDeleteShader (m_fragment_shader); } GLERRPRINT ("After delete shaders"); m_use_shaders = false; } void IvGL::resizeGL (int w, int h) { GLERRPRINT ("resizeGL entry"); glViewport (0, 0, w, h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (-w/2.0, w/2.0, -h/2.0, h/2.0, 0, 10); // Main GL viewport is set up for orthographic view centered at // (0,0) and with width and height equal to the window dimensions IN // PIXEL UNITS. glMatrixMode (GL_MODELVIEW); clamp_view_to_window (); GLERRPRINT ("resizeGL exit"); } static void gl_rect (float xmin, float ymin, float xmax, float ymax, float z = 0, float smin = 0, float tmin = 0, float smax = 1, float tmax = 1, int rotate = 0) { float tex[] = { smin, tmin, smax, tmin, smax, tmax, smin, tmax }; glBegin (GL_POLYGON); glTexCoord2f (tex[(0+2*rotate)&7], tex[(1+2*rotate)&7]); glVertex3f (xmin, ymin, z); glTexCoord2f (tex[(2+2*rotate)&7], tex[(3+2*rotate)&7]); glVertex3f (xmax, ymin, z); glTexCoord2f (tex[(4+2*rotate)&7], tex[(5+2*rotate)&7]); glVertex3f (xmax, ymax, z); glTexCoord2f (tex[(6+2*rotate)&7], tex[(7+2*rotate)&7]); glVertex3f (xmin, ymax, z); glEnd (); } static void handle_orientation (int orientation, int width, int height, float &scale_x, float &scale_y, float &rotate_z, float &point_x, float &point_y, bool pixel=false) { switch (orientation) { case 2: // flipped horizontally scale_x = -1; point_x = width - point_x; if (pixel) // We want to access the pixel at (point_x,pointy), so we have to // substract 1 to get the right index. --point_x; break; case 3: // bottom up, rigth to left (rotated 180). scale_x = -1; scale_y = -1; point_x = width - point_x; point_y = height - point_y; if (pixel) { --point_x; --point_y; } break; case 4: // flipped vertically. scale_y = -1; point_y = height - point_y; if (pixel) --point_y; break; case 5: // transposed (flip horizontal & rotated 90 ccw). scale_x = -1; rotate_z = 90.0; std::swap (point_x, point_y); break; case 6: // rotated 90 cw. rotate_z = -270.0; std::swap (point_x, point_y); point_y = height - point_y; if (pixel) --point_y; break; case 7: // transverse, (flip horizontal & rotated 90 cw, r-to-l, b-to-t) scale_x = -1; rotate_z= -90.0; std::swap (point_x, point_y); point_x = width - point_x; point_y = height - point_y; if (pixel) { --point_x; --point_y; } break; case 8: // rotated 90 ccw. rotate_z = -90.0; std::swap (point_x, point_y); point_x = width - point_x; if (pixel) --point_x; break; case 1: // horizontal case 0: // unknown default: break; } } void IvGL::paintGL () { #ifndef NDEBUG Timer paint_image_time; paint_image_time.start(); #endif //std::cerr << "paintGL " << m_viewer.current_image() << " with zoom " << m_zoom << "\n"; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); IvImage *img = m_current_image; if (! img || ! img->image_valid()) return; const ImageSpec &spec (img->spec()); float z = m_zoom; glPushMatrix (); // Transform is now same as the main GL viewport -- window pixels as // units, with (0,0) at the center of the visible unit. glTranslatef (0, 0, -5); // Pushed away from the camera 5 units. glScalef (1, -1, 1); // Flip y, because OGL's y runs from bottom to top. glScalef (z, z, 1); // Scaled by zoom level. So now xy units are image pixels as // displayed at the current zoom level, with the origin at the // center of the visible window. // Handle the orientation with OpenGL *before* translating our center. float scale_x = 1; float scale_y = 1; float rotate_z= 0; float real_centerx = m_centerx; float real_centery = m_centery; handle_orientation (img->orientation(), spec.width, spec.height, scale_x, scale_y, rotate_z, real_centerx, real_centery); glScalef (scale_x, scale_y, 1); glRotatef (rotate_z, 0, 0, 1); glTranslatef (-real_centerx, -real_centery, 0.0f); // Recentered so that the pixel space (m_centerx,m_centery) position is // at the center of the visible window. useshader (m_texture_width, m_texture_height); float smin = 0, smax = 1.0; float tmin = 0, tmax = 1.0; // Image pixels shown from the center to the edge of the window. int wincenterx = (int) ceil (width()/(2*m_zoom)); int wincentery = (int) ceil (height()/(2*m_zoom)); if (img->orientation() > 4) { std::swap (wincenterx, wincentery); } int xbegin = (int) floor (real_centerx) - wincenterx; xbegin = std::max (spec.x, xbegin - (xbegin % m_texture_width)); int ybegin = (int) floor (real_centery) - wincentery; ybegin = std::max (spec.y, ybegin - (ybegin % m_texture_height)); int xend = (int) floor (real_centerx) + wincenterx; xend = std::min (spec.x + spec.width, xend + m_texture_width - (xend % m_texture_width)); int yend = (int) floor (real_centery) + wincentery; yend = std::min (spec.y + spec.height, yend + m_texture_height - (yend % m_texture_height)); //std::cerr << "(" << xbegin << ',' << ybegin << ") - (" << xend << ',' << yend << ")\n"; // Provide some feedback int total_tiles = (int) (ceilf(float(xend-xbegin)/m_texture_width) * ceilf(float(yend-ybegin)/m_texture_height)); float tile_advance = 1.0f/total_tiles; float percent = tile_advance; m_viewer.statusViewInfo->hide (); m_viewer.statusProgress->show (); // FIXME: change the code path so we can take full advantage of async DMA // when using PBO. for (int ystart = ybegin ; ystart < yend; ystart += m_texture_height) { for (int xstart = xbegin ; xstart < xend; xstart += m_texture_width) { int tile_width = std::min (xend - xstart, m_texture_width); int tile_height = std::min (yend - ystart, m_texture_height); smax = tile_width/float (m_texture_width); tmax = tile_height/float (m_texture_height); //std::cerr << "xstart: " << xstart << ". ystart: " << ystart << "\n"; //std::cerr << "tile_width: " << tile_width << ". tile_height: " << tile_height << "\n"; // FIXME: This can get too slow. Some ideas: avoid sending the tex // images more than necessary, figure an optimum texture size, use // multiple texture objects. load_texture (xstart, ystart, tile_width, tile_height, percent); gl_rect (xstart, ystart, xstart+tile_width, ystart+tile_height, 0, smin, tmin, smax, tmax); percent += tile_advance; } } glPopMatrix (); if (m_viewer.pixelviewOn()) { paint_pixelview (); } // Show the status info again. m_viewer.statusProgress->hide (); m_viewer.statusViewInfo->show (); unsetCursor (); #ifndef NDEBUG std::cerr << "paintGL elapsed time: " << paint_image_time() << " seconds\n"; #endif } void IvGL::shadowed_text (float x, float y, float z, const std::string &s, const QFont &font) { QString q (s.c_str()); #if 0 glColor4f (0, 0, 0, 1); const int b = 2; // blur size for (int i = -b; i <= b; ++i) for (int j = -b; j <= b; ++j) renderText (x+i, y+j, q, font); #endif glColor4f (1, 1, 1, 1); renderText (x, y, z, q, font); } static int num_channels (int current_channel, int nchannels, ImageViewer::COLOR_MODE color_mode) { switch (color_mode) { case ImageViewer::RGBA: return clamp (nchannels-current_channel, 0, 4); case ImageViewer::RGB: case ImageViewer::LUMINANCE: return clamp (nchannels-current_channel, 0, 3); break; case ImageViewer::SINGLE_CHANNEL: case ImageViewer::HEATMAP: return 1; default: return nchannels; } } void IvGL::paint_pixelview () { IvImage *img = m_current_image; const ImageSpec &spec (img->spec()); // (xw,yw) are the window coordinates of the mouse. int xw, yw; get_focus_window_pixel (xw, yw); // (xp,yp) are the image-space [0..res-1] position of the mouse. int xp, yp; get_focus_image_pixel (xp, yp); glPushMatrix (); // Transform is now same as the main GL viewport -- window pixels as // units, with (0,0) at the center of the visible window. glTranslatef (0, 0, -1); // Pushed away from the camera 1 unit. This makes the pixel view // elements closer to the camera than the main view. if (m_viewer.pixelviewFollowsMouse()) { // Display closeup overtop mouse -- translate the coordinate system // so that it is centered at the mouse position. glTranslatef (xw - width()/2, -yw + height()/2, 0); } else { // Display closeup in corner -- translate the coordinate system so that // it is centered near the corner of the window. if (m_pixelview_left_corner) { glTranslatef (closeupsize * 0.5f + 5 - width () / 2, -closeupsize * 0.5f - 5 + height () / 2, 0); // If the mouse cursor is over the pixelview closeup when it's on // the upper left, switch to the upper right if ((xw < closeupsize + 5) && yw < (closeupsize + 5)) m_pixelview_left_corner = false; } else { glTranslatef (-closeupsize * 0.5f - 5 + width () / 2, -closeupsize * 0.5f + 5 + height () / 2, 0); // If the mouse cursor is over the pixelview closeup when it's on // the upper right, switch to the upper left if (xw > (width() - closeupsize - 5) && yw < (closeupsize + 5)) m_pixelview_left_corner = true; } } // In either case, the GL coordinate system is now scaled to window // pixel units, and centered on the middle of where the closeup // window is going to appear. All other coordinates from here on // (in this procedure) should be relative to the closeup window center. glPushAttrib (GL_ENABLE_BIT | GL_TEXTURE_BIT); useshader (closeuptexsize, closeuptexsize, true); float scale_x = 1.0f; float scale_y = 1.0f; float rotate_z= 0.0f; float real_xp = xp; float real_yp = yp; handle_orientation (img->orientation(), spec.width, spec.height, scale_x, scale_y, rotate_z, real_xp, real_yp, true); float smin = 0; float tmin = 0; float smax = 1.0f; float tmax = 1.0f; if (xp >= 0 && xp < img->oriented_width() && yp >= 0 && yp < img->oriented_height()) { // Keep the view within ncloseuppixels pixels. int xpp = clamp (real_xp, ncloseuppixels/2, spec.width - ncloseuppixels/2 - 1); int ypp = clamp (real_yp, ncloseuppixels/2, spec.height - ncloseuppixels/2 - 1); // Calculate patch of the image to use for the pixelview. int xbegin = std::max (xpp - ncloseuppixels/2, 0); int ybegin = std::max (ypp - ncloseuppixels/2, 0); int xend = std::min (xpp + ncloseuppixels/2+1, spec.width); int yend = std::min (ypp + ncloseuppixels/2+1, spec.height); smin = 0; tmin = 0; smax = float (xend-xbegin)/closeuptexsize; tmax = float (yend-ybegin)/closeuptexsize; //std::cerr << "img (" << xbegin << "," << ybegin << ") - (" << xend << "," << yend << ")\n"; //std::cerr << "tex (" << smin << "," << tmin << ") - (" << smax << "," << tmax << ")\n"; //std::cerr << "center mouse (" << xp << "," << yp << "), real (" << real_xp << "," << real_yp << ")\n"; int nchannels = img->nchannels(); // For simplicity, we don't support more than 4 channels without shaders // (yet). if (m_use_shaders) { nchannels = num_channels(m_viewer.current_channel(), nchannels, m_viewer.current_color_mode()); } void *zoombuffer = alloca ((xend-xbegin)*(yend-ybegin)*nchannels*spec.channel_bytes()); if (! m_use_shaders) { img->get_pixels (spec.x + xbegin, spec.x + xend, spec.y + ybegin, spec.y + yend, spec.format, zoombuffer); } else { img->get_pixel_channels (spec.x + xbegin, spec.x + xend, spec.y + ybegin, spec.y + yend, 0, 1, m_viewer.current_channel(), m_viewer.current_channel()+nchannels, spec.format, zoombuffer); } GLenum glformat, gltype, glinternalformat; typespec_to_opengl (spec, nchannels, gltype, glformat, glinternalformat); // Use pixelview's own texture, and upload the corresponding image patch. if (m_use_pbo) { glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB, 0); } glBindTexture (GL_TEXTURE_2D, m_pixelview_tex); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, xend-xbegin, yend-ybegin, glformat, gltype, zoombuffer); GLERRPRINT ("After tsi2d"); } else { smin = -1; smax = -1; glDisable (GL_TEXTURE_2D); glColor3f (0.1f,0.1f,0.1f); } if (! m_use_shaders) { glDisable (GL_BLEND); } glPushMatrix (); glScalef (1, -1, 1); // Run y from top to bottom. glScalef (scale_x, scale_y, 1); glRotatef (rotate_z, 0, 0, 1); // This square is the closeup window itself gl_rect (-0.5f*closeupsize, -0.5f*closeupsize, 0.5f*closeupsize, 0.5f*closeupsize, 0, smin, tmin, smax, tmax); glPopMatrix (); glPopAttrib (); // Draw a second window, slightly behind the closeup window, as a // backdrop. It's partially transparent, having the effect of // darkening the main image view beneath the closeup window. It // extends slightly out from the closeup window (making it more // clearly visible), and also all the way down to cover the area // where the text will be printed, so it is very readable. const int yspacing = 18; glPushAttrib (GL_ENABLE_BIT | GL_CURRENT_BIT); glDisable (GL_TEXTURE_2D); if (m_use_shaders) { // Disable shaders for this. gl_use_program (0); } float extraspace = yspacing * (1 + spec.nchannels) + 4; glColor4f (0.1f, 0.1f, 0.1f, 0.5f); gl_rect (-0.5f*closeupsize-2, 0.5f*closeupsize+2, 0.5f*closeupsize+2, -0.5f*closeupsize - extraspace, -0.1f); if (1 /*xp >= 0 && xp < img->oriented_width() && yp >= 0 && yp < img->oriented_height()*/) { // Now we print text giving the mouse coordinates and the numerical // values of the pixel that the mouse is over. QFont font; font.setFixedPitch (true); float *fpixel = (float *) alloca (spec.nchannels*sizeof(float)); int textx = - closeupsize/2 + 4; int texty = - closeupsize/2 - yspacing; std::string s = Strutil::format ("(%d, %d)", (int) real_xp+spec.x, (int) real_yp+spec.y); shadowed_text (textx, texty, 0.0f, s, font); texty -= yspacing; img->getpixel ((int) real_xp+spec.x, (int) real_yp+spec.y, fpixel); for (int i = 0; i < spec.nchannels; ++i) { switch (spec.format.basetype) { case TypeDesc::UINT8 : { ImageBuf::ConstIterator p (*img, (int) real_xp+spec.x, (int) real_yp+spec.y); s = Strutil::format ("%s: %3d (%5.3f)", spec.channelnames[i].c_str(), (int)(p[i]), fpixel[i]); } break; case TypeDesc::UINT16 : { ImageBuf::ConstIterator p (*img, (int) real_xp+spec.x, (int) real_yp+spec.y); s = Strutil::format ("%s: %3d (%5.3f)", spec.channelnames[i].c_str(), (int)(p[i]), fpixel[i]); } break; default: // everything else, treat as float s = Strutil::format ("%s: %5.3f", spec.channelnames[i].c_str(), fpixel[i]); } shadowed_text (textx, texty, 0.0f, s, font); texty -= yspacing; } } glPopAttrib (); glPopMatrix (); } void IvGL::useshader (int tex_width, int tex_height, bool pixelview) { IvImage *img = m_viewer.cur(); if (! img) return; if (!m_use_shaders) { glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); BOOST_FOREACH (TexBuffer &tb, m_texbufs) { glBindTexture (GL_TEXTURE_2D, tb.tex_object); if (m_viewer.linearInterpolation ()) { glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } return; } const ImageSpec &spec (img->spec()); gl_use_program (m_shader_program); GLERRPRINT ("After use program"); GLint loc; loc = gl_get_uniform_location ("startchannel"); if (m_viewer.current_channel()>=spec.nchannels) { gl_uniform (loc, -1); return; } gl_uniform (loc, 0); loc = gl_get_uniform_location ("imgtex"); // This is the texture unit, not the texture object gl_uniform (loc, 0); loc = gl_get_uniform_location ("gain"); float gain = powf (2.0, img->exposure ()); gl_uniform (loc, gain); loc = gl_get_uniform_location ("gamma"); gl_uniform (loc, img->gamma ()); loc = gl_get_uniform_location ("colormode"); gl_uniform (loc, m_viewer.current_color_mode()); loc = gl_get_uniform_location ("imgchannels"); gl_uniform (loc, spec.nchannels); loc = gl_get_uniform_location ("pixelview"); gl_uniform (loc, pixelview); loc = gl_get_uniform_location ("linearinterp"); gl_uniform (loc, m_viewer.linearInterpolation ()); loc = gl_get_uniform_location ("width"); gl_uniform (loc, tex_width); loc = gl_get_uniform_location ("height"); gl_uniform (loc, tex_height); GLERRPRINT ("After settting uniforms"); } void IvGL::update () { //std::cerr << "update image\n"; IvImage* img = m_viewer.cur(); if (! img) { m_current_image = NULL; return; } const ImageSpec &spec (img->spec()); int nchannels = img->nchannels(); // For simplicity, we don't support more than 4 channels without shaders // (yet). if (m_use_shaders) { nchannels = num_channels(m_viewer.current_channel(), nchannels, m_viewer.current_color_mode()); } if (! nchannels) return; // Don't bother, the shader will show blackness for us. GLenum gltype = GL_UNSIGNED_BYTE; GLenum glformat = GL_RGB; GLenum glinternalformat = GL_RGB; typespec_to_opengl (spec, nchannels, gltype, glformat, glinternalformat); m_texture_width = clamp (pow2roundup(spec.width), 1, m_max_texture_size); m_texture_height= clamp (pow2roundup(spec.height), 1, m_max_texture_size); if (m_use_pbo) { // Otherwise OpenGL will confuse the NULL with an index into one of // the PBOs. glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB, 0); } BOOST_FOREACH (TexBuffer &tb, m_texbufs) { tb.width = 0; tb.height= 0; glBindTexture (GL_TEXTURE_2D, tb.tex_object); glTexImage2D (GL_TEXTURE_2D, 0 /*mip level*/, glinternalformat, m_texture_width, m_texture_height, 0 /*border width*/, glformat, gltype, NULL /*data*/); GLERRPRINT ("Setting up texture"); } // Set the right type for the texture used for pixelview. glBindTexture (GL_TEXTURE_2D, m_pixelview_tex); glTexImage2D (GL_TEXTURE_2D, 0, glinternalformat, closeuptexsize, closeuptexsize, 0, glformat, gltype, NULL); GLERRPRINT ("Setting up pixelview texture"); // Resize the buffer at once, rather than create one each drawing. m_tex_buffer.resize (m_texture_width * m_texture_height * nchannels * spec.channel_bytes()); m_current_image = img; } void IvGL::view (float xcenter, float ycenter, float zoom, bool redraw) { m_centerx = xcenter; m_centery = ycenter; m_zoom = zoom; if (redraw) trigger_redraw (); } void IvGL::zoom (float newzoom, bool redraw) { view (m_centerx, m_centery, newzoom, redraw); } void IvGL::center (float x, float y, bool redraw) { view (x, y, m_viewer.zoom(), redraw); } void IvGL::pan (float dx, float dy) { center (m_centerx + dx, m_centery + dy); } void IvGL::remember_mouse (const QPoint &pos) { m_mousex = pos.x(); m_mousey = pos.y(); } void IvGL::clamp_view_to_window () { IvImage *img = m_current_image; if (! img) return; int w = width(), h = height(); float zoomedwidth = m_zoom * img->oriented_full_width(); float zoomedheight = m_zoom * img->oriented_full_height(); #if 0 float left = m_centerx - 0.5 * ((float)w / m_zoom); float top = m_centery - 0.5 * ((float)h / m_zoom); float right = m_centerx + 0.5 * ((float)w / m_zoom); float bottom = m_centery + 0.5 * ((float)h / m_zoom); std::cerr << "Window size is " << w << " x " << h << "\n"; std::cerr << "Center (pixel coords) is " << m_centerx << ", " << m_centery << "\n"; std::cerr << "Top left (pixel coords) is " << left << ", " << top << "\n"; std::cerr << "Bottom right (pixel coords) is " << right << ", " << bottom << "\n"; #endif int xmin = std::min (img->oriented_x(), img->oriented_full_x()); int xmax = std::max (img->oriented_x()+img->oriented_width(), img->oriented_full_x()+img->oriented_full_width()); int ymin = std::min (img->oriented_y(), img->oriented_full_y()); int ymax = std::max (img->oriented_y()+img->oriented_height(), img->oriented_full_y()+img->oriented_full_height()); // Don't let us scroll off the edges if (zoomedwidth >= w) { m_centerx = Imath::clamp (m_centerx, xmin + 0.5f*w/m_zoom, xmax - 0.5f*w/m_zoom); } else { m_centerx = img->oriented_full_x() + img->oriented_full_width()/2; } if (zoomedheight >= h) { m_centery = Imath::clamp (m_centery, ymin + 0.5f*h/m_zoom, ymax - 0.5f*h/m_zoom); } else { m_centery = img->oriented_full_y() + img->oriented_full_height()/2; } } void IvGL::mousePressEvent (QMouseEvent *event) { remember_mouse (event->pos()); int mousemode = m_viewer.mouseModeComboBox->currentIndex (); bool Alt = (event->modifiers() & Qt::AltModifier); m_drag_button = event->button(); if (! m_mouse_activation) { switch (event->button()) { case Qt::LeftButton : if (mousemode == ImageViewer::MouseModeZoom && !Alt) m_viewer.zoomIn(); else m_dragging = true; return; case Qt::RightButton : if (mousemode == ImageViewer::MouseModeZoom && !Alt) m_viewer.zoomOut(); else m_dragging = true; return; case Qt::MidButton : m_dragging = true; // FIXME: should this be return rather than break? break; default: break; } } else m_mouse_activation = false; parent_t::mousePressEvent (event); } void IvGL::mouseReleaseEvent (QMouseEvent *event) { remember_mouse (event->pos()); m_drag_button = Qt::NoButton; m_dragging = false; parent_t::mouseReleaseEvent (event); } void IvGL::mouseMoveEvent (QMouseEvent *event) { QPoint pos = event->pos(); // FIXME - there's probably a better Qt way than tracking the button // myself. bool Alt = (event->modifiers() & Qt::AltModifier); int mousemode = m_viewer.mouseModeComboBox->currentIndex (); bool do_pan = false, do_zoom = false, do_wipe = false; bool do_select = false, do_annotate = false; switch (mousemode) { case ImageViewer::MouseModeZoom : if ((m_drag_button == Qt::MidButton) || (m_drag_button == Qt::LeftButton && Alt)) { do_pan = true; } else if (m_drag_button == Qt::RightButton && Alt) { do_zoom = true; } break; case ImageViewer::MouseModePan : if (m_drag_button != Qt::NoButton) do_pan = true; break; case ImageViewer::MouseModeWipe : if (m_drag_button != Qt::NoButton) do_wipe = true; break; case ImageViewer::MouseModeSelect : if (m_drag_button != Qt::NoButton) do_select = true; break; case ImageViewer::MouseModeAnnotate : if (m_drag_button != Qt::NoButton) do_annotate = true; break; } if (do_pan) { float dx = (pos.x() - m_mousex) / m_zoom; float dy = (pos.y() - m_mousey) / m_zoom; pan (-dx, -dy); } else if (do_zoom) { float dx = (pos.x() - m_mousex); float dy = (pos.y() - m_mousey); float z = m_viewer.zoom() * (1.0 + 0.005 * (dx + dy)); z = Imath::clamp (z, 0.01f, 256.0f); m_viewer.zoom (z); m_viewer.fitImageToWindowAct->setChecked (false); } else if (do_wipe) { // FIXME -- unimplemented } else if (do_select) { // FIXME -- unimplemented } else if (do_annotate) { // FIXME -- unimplemented } remember_mouse (pos); if (m_viewer.pixelviewOn()) trigger_redraw (); parent_t::mouseMoveEvent (event); } void IvGL::wheelEvent (QWheelEvent *event) { m_mouse_activation = false; if (event->orientation() == Qt::Vertical) { // TODO: Update this to keep the zoom centered on the event .x, .y float oldzoom = m_viewer.zoom(); float newzoom = (event->delta()>0) ? \ pow2roundupf (oldzoom) : pow2rounddownf (oldzoom); m_viewer.zoom (newzoom); event->accept(); } } void IvGL::focusOutEvent (QFocusEvent*) { m_mouse_activation = true; } void IvGL::get_focus_window_pixel (int &x, int &y) { x = m_mousex; y = m_mousey; } void IvGL::get_focus_image_pixel (int &x, int &y) { // w,h are the dimensions of the visible window, in pixels int w = width(), h = height(); float z = m_zoom; // left,top,right,bottom are the borders of the visible window, in // pixel coordinates float left = m_centerx - 0.5 * w / z; float top = m_centery - 0.5 * h / z; float right = m_centerx + 0.5 * w / z; float bottom = m_centery + 0.5 * h / z; // normx,normy are the position of the mouse, in normalized (i.e. [0..1]) // visible window coordinates. float normx = (float)(m_mousex + 0.5f) / w; float normy = (float)(m_mousey + 0.5f) / h; // imgx,imgy are the position of the mouse, in pixel coordinates float imgx = Imath::lerp (left, right, normx); float imgy = Imath::lerp (top, bottom, normy); // So finally x,y are the coordinates of the image pixel (on [0,res-1]) // underneath the mouse cursor. //FIXME: Shouldn't this take image rotation into account? x = (int) floorf (imgx); y = (int) floorf (imgy); #if 0 std::cerr << "get_focus_pixel\n"; std::cerr << " mouse window pixel coords " << m_mousex << ' ' << m_mousey << "\n"; std::cerr << " mouse window NDC coords " << normx << ' ' << normy << '\n'; std::cerr << " center image coords " << m_centerx << ' ' << m_centery << "\n"; std::cerr << " left,top = " << left << ' ' << top << "\n"; std::cerr << " right,bottom = " << right << ' ' << bottom << "\n"; std::cerr << " mouse image coords " << imgx << ' ' << imgy << "\n"; std::cerr << " mouse pixel image coords " << x << ' ' << y << "\n"; #endif } inline void IvGL::gl_use_program (int program) { if (m_shaders_using_extensions) glUseProgramObjectARB (program); else glUseProgram (program); } inline GLint IvGL::gl_get_uniform_location (const char *uniform) { if (m_shaders_using_extensions) return glGetUniformLocationARB (m_shader_program, uniform); else return glGetUniformLocation (m_shader_program, uniform); } inline void IvGL::gl_uniform (GLint location, float value) { if (m_shaders_using_extensions) glUniform1fARB (location, value); else glUniform1f (location, value); } inline void IvGL::gl_uniform (GLint location, int value) { if (m_shaders_using_extensions) glUniform1iARB (location, value); else glUniform1i (location, value); } void IvGL::print_shader_log (std::ostream& out, const GLuint shader_id) const { GLint size = 0; glGetShaderiv (shader_id, GL_INFO_LOG_LENGTH, &size); if (size > 0) { GLchar* log = new GLchar[size]; if (m_shaders_using_extensions) { glGetInfoLogARB (shader_id, size, NULL, log); } else { glGetShaderInfoLog (shader_id, size, NULL, log); } out << "compile log:\n" << log << "---\n"; delete[] log; } } void IvGL::check_gl_extensions (void) { #ifndef FORCE_OPENGL_1 m_use_shaders = glewIsSupported("GL_VERSION_2_0"); if (!m_use_shaders && glewIsSupported("GL_ARB_shader_objects " "GL_ARB_vertex_shader " "GL_ARB_fragment_shader")) { m_use_shaders = true; m_shaders_using_extensions = true; } m_use_srgb = glewIsSupported("GL_VERSION_2_1") || glewIsSupported("GL_EXT_texture_sRGB"); m_use_halffloat = glewIsSupported("GL_VERSION_3_0") || glewIsSupported("GL_ARB_half_float_pixel") || glewIsSupported("GL_NV_half_float_pixel"); m_use_float = glewIsSupported("GL_VERSION_3_0") || glewIsSupported("GL_ARB_texture_float") || glewIsSupported("GL_ATI_texture_float"); m_use_pbo = glewIsSupported("GL_VERSION_1_5") || glewIsSupported("GL_ARB_pixel_buffer_object"); #else std::cerr << "Not checking GL extensions\n"; #endif m_max_texture_size = 0; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size); // FIXME: Need a smarter way to handle (video) memory. // Don't assume that systems capable of using 8k^2 textures have enough // resources to use more than one of those at the same time. m_max_texture_size = std::min(m_max_texture_size, 4096); #ifndef NDEBUG // Report back... std::cerr << "OpenGL Shading Language supported: " << m_use_shaders << "\n"; if (m_shaders_using_extensions) { std::cerr << "\t(with extensions)\n"; } std::cerr << "OpenGL sRGB color space textures supported: " << m_use_srgb << "\n"; std::cerr << "OpenGL half-float pixels supported: " << m_use_halffloat << "\n"; std::cerr << "OpenGL float texture storage supported: " << m_use_float << "\n"; std::cerr << "OpenGL pixel buffer object supported: " << m_use_pbo << "\n"; std::cerr << "OpenGL max texture dimension: " << m_max_texture_size << "\n"; #endif } void IvGL::typespec_to_opengl (const ImageSpec &spec, int nchannels, GLenum &gltype, GLenum &glformat, GLenum &glinternalformat) const { switch (spec.format.basetype) { case TypeDesc::FLOAT : gltype = GL_FLOAT; break; case TypeDesc::HALF : if (m_use_halffloat) { gltype = GL_HALF_FLOAT_ARB; } else { // If we reach here then something really wrong // happened: When half-float is not supported, // the image should be loaded as UINT8 (no GLSL // support) or FLOAT (GLSL support). // See IvImage::loadCurrentImage() std::cerr << "Tried to load an unsupported half-float image.\n"; gltype = GL_INVALID_ENUM; } break; case TypeDesc::INT : gltype = GL_INT; break; case TypeDesc::UINT : gltype = GL_UNSIGNED_INT; break; case TypeDesc::INT16 : gltype = GL_SHORT; break; case TypeDesc::UINT16 : gltype = GL_UNSIGNED_SHORT; break; case TypeDesc::INT8 : gltype = GL_BYTE; break; case TypeDesc::UINT8 : gltype = GL_UNSIGNED_BYTE; break; default: gltype = GL_UNSIGNED_BYTE; // punt break; } bool issrgb = iequals (spec.get_string_attribute ("oiio:ColorSpace"), "sRGB"); glinternalformat = nchannels; if (nchannels == 1) { glformat = GL_LUMINANCE; if (m_use_srgb && issrgb) { if (spec.format.basetype == TypeDesc::UINT8) { glinternalformat = GL_SLUMINANCE8; } else { glinternalformat = GL_SLUMINANCE; } } else if (spec.format.basetype == TypeDesc::UINT8) { glinternalformat = GL_LUMINANCE8; } else if (spec.format.basetype == TypeDesc::UINT16) { glinternalformat = GL_LUMINANCE16; } else if (m_use_float && spec.format.basetype == TypeDesc::FLOAT) { glinternalformat = GL_LUMINANCE32F_ARB; } else if (m_use_float && spec.format.basetype == TypeDesc::HALF) { glinternalformat = GL_LUMINANCE16F_ARB; } } else if (nchannels == 2) { glformat = GL_LUMINANCE_ALPHA; if (m_use_srgb && issrgb) { if (spec.format.basetype == TypeDesc::UINT8) { glinternalformat = GL_SLUMINANCE8_ALPHA8; } else { glinternalformat = GL_SLUMINANCE_ALPHA; } } else if (spec.format.basetype == TypeDesc::UINT8) { glinternalformat = GL_LUMINANCE8_ALPHA8; } else if (spec.format.basetype == TypeDesc::UINT16) { glinternalformat = GL_LUMINANCE16_ALPHA16; } else if (m_use_float && spec.format.basetype == TypeDesc::FLOAT) { glinternalformat = GL_LUMINANCE_ALPHA32F_ARB; } else if (m_use_float && spec.format.basetype == TypeDesc::HALF) { glinternalformat = GL_LUMINANCE_ALPHA16F_ARB; } } else if (nchannels == 3) { glformat = GL_RGB; if (m_use_srgb && issrgb) { if (spec.format.basetype == TypeDesc::UINT8) { glinternalformat = GL_SRGB8; } else { glinternalformat = GL_SRGB; } } else if (spec.format.basetype == TypeDesc::UINT8) { glinternalformat = GL_RGB8; } else if (spec.format.basetype == TypeDesc::UINT16) { glinternalformat = GL_RGB16; } else if (m_use_float && spec.format.basetype == TypeDesc::FLOAT) { glinternalformat = GL_RGB32F_ARB; } else if (m_use_float && spec.format.basetype == TypeDesc::HALF) { glinternalformat = GL_RGB16F_ARB; } } else if (nchannels == 4) { glformat = GL_RGBA; if (m_use_srgb && issrgb) { if (spec.format.basetype == TypeDesc::UINT8) { glinternalformat = GL_SRGB8_ALPHA8; } else { glinternalformat = GL_SRGB_ALPHA; } } else if (spec.format.basetype == TypeDesc::UINT8) { glinternalformat = GL_RGBA8; } else if (spec.format.basetype == TypeDesc::UINT16) { glinternalformat = GL_RGBA16; } else if (m_use_float && spec.format.basetype == TypeDesc::FLOAT) { glinternalformat = GL_RGBA32F_ARB; } else if (m_use_float && spec.format.basetype == TypeDesc::HALF) { glinternalformat = GL_RGBA16F_ARB; } } else { glformat = GL_INVALID_ENUM; glinternalformat = GL_INVALID_ENUM; } } void IvGL::load_texture (int x, int y, int width, int height, float percent) { const ImageSpec &spec = m_current_image->spec (); // Find if this has already been loaded. BOOST_FOREACH (TexBuffer &tb, m_texbufs) { if (tb.x == x && tb.y == y && tb.width >= width && tb.height >= height) { glBindTexture (GL_TEXTURE_2D, tb.tex_object); return; } } // Make it somewhat obvious to the user that some progress is happening // here. m_viewer.statusProgress->setValue ((int)(percent*100)); // FIXME: Check whether this works ok (ie, no 'recursive repaint' messages) // on all platforms. m_viewer.statusProgress->repaint (); setCursor (Qt::WaitCursor); int nchannels = spec.nchannels; // For simplicity, we don't support more than 4 channels without shaders // (yet). if (m_use_shaders) { nchannels = num_channels(m_viewer.current_channel(), nchannels, m_viewer.current_color_mode()); } GLenum gltype, glformat, glinternalformat; typespec_to_opengl (spec, nchannels, gltype, glformat, glinternalformat); TexBuffer &tb = m_texbufs[m_last_texbuf_used]; tb.x = x; tb.y = y; tb.width = width; tb.height = height; // Copy the imagebuf pixels we need, that's the only way we can do // it safely since ImageBuf has a cache underneath and the whole image // may not be resident at once. if (! m_use_shaders) { m_current_image->get_pixels (x, x + width, y, y + height, spec.format, &m_tex_buffer[0]); } else { m_current_image->get_pixel_channels (x, x+width, y, y+height, 0, 1, m_viewer.current_channel(), m_viewer.current_channel() + nchannels, spec.format, &m_tex_buffer[0]); } if (m_use_pbo) { glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo_objects[m_last_pbo_used]); glBufferDataARB (GL_PIXEL_UNPACK_BUFFER_ARB, width * height * spec.pixel_bytes(), &m_tex_buffer[0], GL_STREAM_DRAW_ARB); GLERRPRINT ("After buffer data"); m_last_pbo_used = (m_last_pbo_used + 1) & 1; } // When using PBO this is the offset within the buffer. void *data = 0; if (! m_use_pbo) data = &m_tex_buffer[0]; glBindTexture (GL_TEXTURE_2D, tb.tex_object); GLERRPRINT ("After bind texture"); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, glformat, gltype, data); GLERRPRINT ("After loading sub image"); m_last_texbuf_used = (m_last_texbuf_used + 1) % m_texbufs.size(); } bool IvGL::is_too_big (float width, float height) { unsigned int tiles = (unsigned int) (ceilf(width/m_max_texture_size) * ceilf(height/m_max_texture_size)); return tiles > m_texbufs.size(); } openimageio-1.3.12~dfsg0.orig/src/iv/imageviewer.cpp0000644000175000017500000017604012271062644020546 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "imageviewer.h" #include "ivgl.h" #include #include #ifndef WIN32 #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dassert.h" #include "strutil.h" #include "timer.h" #include "fmath.h" #include "ivutils.h" #include "sysutil.h" #include "filesystem.h" namespace { bool IsSpecSrgb(const ImageSpec & spec) { return (Strutil::iequals (spec.get_string_attribute ("oiio:ColorSpace"), "sRGB")); } } static const char *s_file_filters = "" "Image Files (*.bmp *.cin *.dds *.dpx *.f3d *.fits *.gif *.hdr *.ico *.iff " "*.jpg *.jpe *.jpeg *.jif *.jfif *.jfi *.jp2 *.j2k *.exr *.png *.pbm *.pgm " "*.ppm *.ptex *.rla *.sgi *.rgb *.rgba *.bw *.int *.inta *.pic *.tga " "*.tpic *.tif *.tiff *.tx *.env *.sm *.vsm *.zfile);;" "BMP (*.bmp);;" "Cineon (*.cin);;" "Direct Draw Surface (*.dds);;" "DPX (*.dpx);;" "Field3D (*.f3d);;" "FITS (*.fits);;" "GIF (*.gif);;" "HDR/RGBE (*.hdr);;" "Icon (*.ico);;" "IFF (*.iff);;" "JPEG (*.jpg *.jpe *.jpeg *.jif *.jfif *.jfi);;" "JPEG-2000 (*.jp2 *.j2k);;" "OpenEXR (*.exr);;" "Portable Network Graphics (*.png);;" "PNM / Netpbm (*.pbm *.pgm *.ppm);;" "Ptex (*.ptex);;" "RLA (*.rla);;" "SGI (*.sgi *.rgb *.rgba *.bw *.int *.inta);;" "Softimage PIC (*.pic);;" "Targa (*.tga *.tpic);;" "TIFF (*.tif *.tiff *.tx *.env *.sm *.vsm);;" "Zfile (*.zfile);;" "All Files (*)"; ImageViewer::ImageViewer () : infoWindow(NULL), preferenceWindow(NULL), darkPaletteBox(NULL), m_current_image(-1), m_current_channel(0), m_color_mode(RGBA), m_last_image(-1), m_zoom(1), m_fullscreen(false), m_default_gamma(1), m_darkPalette(false) { readSettings (false); const char *gamenv = getenv ("GAMMA"); if (gamenv) { float g = atof (gamenv); if (g >= 0.1 && g <= 5) m_default_gamma = g; } // FIXME -- would be nice to have a more nuanced approach to display // color space, in particular knowing whether the display is sRGB. // Also, some time in the future we may want a real 3D LUT for // "film look", etc. if (darkPalette()) m_palette = QPalette (Qt::darkGray); // darkGray? else m_palette = QPalette (); QApplication::setPalette (m_palette); // FIXME -- why not work? this->setPalette (m_palette); slideTimer = new QTimer(); slideDuration_ms = 5000; slide_loop = true; glwin = new IvGL (this, *this); glwin->setPalette (m_palette); glwin->resize (m_default_width, m_default_height); setCentralWidget (glwin); createActions(); createMenus(); createToolBars(); createStatusBar(); readSettings(); setWindowTitle (tr("Image Viewer")); resize (m_default_width, m_default_height); // setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Ignored); } ImageViewer::~ImageViewer () { BOOST_FOREACH (IvImage *i, m_images) delete i; } void ImageViewer::closeEvent (QCloseEvent*) { writeSettings (); } void ImageViewer::createActions() { openAct = new QAction(tr("&Open..."), this); openAct->setShortcut(tr("Ctrl+O")); connect(openAct, SIGNAL(triggered()), this, SLOT(open())); for (size_t i = 0; i < MaxRecentFiles; ++i) { openRecentAct[i] = new QAction (this); openRecentAct[i]->setVisible (false); connect (openRecentAct[i], SIGNAL(triggered()), this, SLOT(openRecentFile())); } reloadAct = new QAction(tr("&Reload image"), this); reloadAct->setShortcut(tr("Ctrl+R")); connect(reloadAct, SIGNAL(triggered()), this, SLOT(reload())); closeImgAct = new QAction(tr("&Close Image"), this); closeImgAct->setShortcut(tr("Ctrl+W")); connect(closeImgAct, SIGNAL(triggered()), this, SLOT(closeImg())); saveAsAct = new QAction(tr("&Save As..."), this); saveAsAct->setShortcut(tr("Ctrl+S")); connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); saveWindowAsAct = new QAction(tr("Save Window As..."), this); connect(saveWindowAsAct, SIGNAL(triggered()), this, SLOT(saveWindowAs())); saveSelectionAsAct = new QAction(tr("Save Selection As..."), this); connect(saveSelectionAsAct, SIGNAL(triggered()), this, SLOT(saveSelectionAs())); printAct = new QAction(tr("&Print..."), this); printAct->setShortcut(tr("Ctrl+P")); printAct->setEnabled(false); connect(printAct, SIGNAL(triggered()), this, SLOT(print())); deleteCurrentImageAct = new QAction(tr("&Delete from disk"), this); deleteCurrentImageAct->setShortcut(tr("Delete")); connect(deleteCurrentImageAct, SIGNAL(triggered()), this, SLOT(deleteCurrentImage())); editPreferencesAct = new QAction(tr("&Preferences..."), this); editPreferencesAct->setShortcut(tr("Ctrl+,")); editPreferencesAct->setEnabled (true); connect (editPreferencesAct, SIGNAL(triggered()), this, SLOT(editPreferences())); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcut(tr("Ctrl+Q")); connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); exposurePlusOneTenthStopAct = new QAction(tr("Exposure +1/10 stop"), this); exposurePlusOneTenthStopAct->setShortcut(tr("]")); connect(exposurePlusOneTenthStopAct, SIGNAL(triggered()), this, SLOT(exposurePlusOneTenthStop())); exposurePlusOneHalfStopAct = new QAction(tr("Exposure +1/2 stop"), this); exposurePlusOneHalfStopAct->setShortcut(tr("}")); connect(exposurePlusOneHalfStopAct, SIGNAL(triggered()), this, SLOT(exposurePlusOneHalfStop())); exposureMinusOneTenthStopAct = new QAction(tr("Exposure -1/10 stop"), this); exposureMinusOneTenthStopAct->setShortcut(tr("[")); connect(exposureMinusOneTenthStopAct, SIGNAL(triggered()), this, SLOT(exposureMinusOneTenthStop())); exposureMinusOneHalfStopAct = new QAction(tr("Exposure -1/2 stop"), this); exposureMinusOneHalfStopAct->setShortcut(tr("{")); connect(exposureMinusOneHalfStopAct, SIGNAL(triggered()), this, SLOT(exposureMinusOneHalfStop())); gammaPlusAct = new QAction(tr("Gamma +0.1"), this); gammaPlusAct->setShortcut(tr(")")); connect(gammaPlusAct, SIGNAL(triggered()), this, SLOT(gammaPlus())); gammaMinusAct = new QAction(tr("Gamma -0.1"), this); gammaMinusAct->setShortcut(tr("(")); connect(gammaMinusAct, SIGNAL(triggered()), this, SLOT(gammaMinus())); viewChannelFullAct = new QAction(tr("Full Color"), this); viewChannelFullAct->setShortcut(tr("c")); viewChannelFullAct->setCheckable (true); viewChannelFullAct->setChecked (true); connect(viewChannelFullAct, SIGNAL(triggered()), this, SLOT(viewChannelFull())); viewChannelRedAct = new QAction(tr("Red"), this); viewChannelRedAct->setShortcut(tr("r")); viewChannelRedAct->setCheckable (true); connect(viewChannelRedAct, SIGNAL(triggered()), this, SLOT(viewChannelRed())); viewChannelGreenAct = new QAction(tr("Green"), this); viewChannelGreenAct->setShortcut(tr("g")); viewChannelGreenAct->setCheckable (true); connect(viewChannelGreenAct, SIGNAL(triggered()), this, SLOT(viewChannelGreen())); viewChannelBlueAct = new QAction(tr("Blue"), this); viewChannelBlueAct->setShortcut(tr("b")); viewChannelBlueAct->setCheckable (true); connect(viewChannelBlueAct, SIGNAL(triggered()), this, SLOT(viewChannelBlue())); viewChannelAlphaAct = new QAction(tr("Alpha"), this); viewChannelAlphaAct->setShortcut(tr("a")); viewChannelAlphaAct->setCheckable (true); connect(viewChannelAlphaAct, SIGNAL(triggered()), this, SLOT(viewChannelAlpha())); viewColorLumAct = new QAction (tr("Luminance"), this); viewColorLumAct->setShortcut (tr("l")); viewColorLumAct->setCheckable (true); connect(viewColorLumAct, SIGNAL(triggered()), this, SLOT(viewChannelLuminance())); viewColorRGBAAct = new QAction (tr("RGBA"), this); //viewColorRGBAAct->setShortcut (tr("Ctrl+c")); viewColorRGBAAct->setCheckable (true); viewColorRGBAAct->setChecked (true); connect(viewColorRGBAAct, SIGNAL(triggered()), this, SLOT(viewColorRGBA())); viewColorRGBAct = new QAction (tr("RGB"), this); //viewColorRGBAct->setShortcut (tr("Ctrl+a")); viewColorRGBAct->setCheckable (true); connect(viewColorRGBAct, SIGNAL(triggered()), this, SLOT(viewColorRGB())); viewColor1ChAct = new QAction (tr("Single channel"), this); viewColor1ChAct->setShortcut (tr("1")); viewColor1ChAct->setCheckable (true); connect(viewColor1ChAct, SIGNAL(triggered()), this, SLOT(viewColor1Ch())); viewColorHeatmapAct = new QAction (tr("Single channel (Heatmap)"), this); viewColorHeatmapAct->setShortcut (tr("h")); viewColorHeatmapAct->setCheckable (true); connect(viewColorHeatmapAct, SIGNAL(triggered()), this, SLOT(viewColorHeatmap())); viewChannelPrevAct = new QAction(tr("Prev Channel"), this); viewChannelPrevAct->setShortcut(tr(",")); connect(viewChannelPrevAct, SIGNAL(triggered()), this, SLOT(viewChannelPrev())); viewChannelNextAct = new QAction(tr("Next Channel"), this); viewChannelNextAct->setShortcut(tr(".")); connect(viewChannelNextAct, SIGNAL(triggered()), this, SLOT(viewChannelNext())); viewSubimagePrevAct = new QAction(tr("Prev Subimage"), this); viewSubimagePrevAct->setShortcut(tr("<")); connect(viewSubimagePrevAct, SIGNAL(triggered()), this, SLOT(viewSubimagePrev())); viewSubimageNextAct = new QAction(tr("Next Subimage"), this); viewSubimageNextAct->setShortcut(tr(">")); connect(viewSubimageNextAct, SIGNAL(triggered()), this, SLOT(viewSubimageNext())); zoomInAct = new QAction(tr("Zoom &In"), this); zoomInAct->setShortcut(tr("Ctrl++")); connect(zoomInAct, SIGNAL(triggered()), this, SLOT(zoomIn())); zoomOutAct = new QAction(tr("Zoom &Out"), this); zoomOutAct->setShortcut(tr("Ctrl+-")); connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(zoomOut())); normalSizeAct = new QAction(tr("&Normal Size (1:1)"), this); normalSizeAct->setShortcut(tr("Ctrl+0")); connect(normalSizeAct, SIGNAL(triggered()), this, SLOT(normalSize())); fitWindowToImageAct = new QAction(tr("&Fit Window to Image"), this); fitWindowToImageAct->setShortcut(tr("f")); connect(fitWindowToImageAct, SIGNAL(triggered()), this, SLOT(fitWindowToImage())); fitImageToWindowAct = new QAction(tr("Fit Image to Window"), this); // fitImageToWindowAct->setEnabled(false); fitImageToWindowAct->setCheckable(true); fitImageToWindowAct->setShortcut(tr("Alt+f")); connect(fitImageToWindowAct, SIGNAL(triggered()), this, SLOT(fitImageToWindow())); fullScreenAct = new QAction(tr("Full screen"), this); // fullScreenAct->setEnabled(false); // fullScreenAct->setCheckable(true); fullScreenAct->setShortcut(tr("Ctrl+f")); connect(fullScreenAct, SIGNAL(triggered()), this, SLOT(fullScreenToggle())); aboutAct = new QAction(tr("&About"), this); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); prevImageAct = new QAction(tr("Previous Image"), this); prevImageAct->setShortcut(tr("PgUp")); // prevImageAct->setEnabled(true); connect (prevImageAct, SIGNAL(triggered()), this, SLOT(prevImage())); nextImageAct = new QAction(tr("Next Image"), this); nextImageAct->setShortcut(tr("PgDown")); // nextImageAct->setEnabled(true); connect (nextImageAct, SIGNAL(triggered()), this, SLOT(nextImage())); toggleImageAct = new QAction(tr("Toggle image"), this); toggleImageAct->setShortcut(tr("T")); // toggleImageAct->setEnabled(true); connect (toggleImageAct, SIGNAL(triggered()), this, SLOT(toggleImage())); slideShowAct = new QAction(tr("Start Slide Show"), this); connect(slideShowAct, SIGNAL(triggered()), this, SLOT(slideShow())); slideLoopAct = new QAction(tr("Loop slide show"), this); slideLoopAct->setCheckable (true); slideLoopAct->setChecked (true); connect(slideLoopAct, SIGNAL(triggered()), this, SLOT(slideLoop())); slideNoLoopAct = new QAction(tr("Stop at end"), this); slideNoLoopAct->setCheckable (true); connect(slideNoLoopAct, SIGNAL(triggered()), this, SLOT(slideNoLoop())); sortByNameAct = new QAction(tr("By Name"), this); connect(sortByNameAct, SIGNAL(triggered()), this, SLOT(sortByName())); sortByPathAct = new QAction(tr("By File Path"), this); connect(sortByPathAct, SIGNAL(triggered()), this, SLOT(sortByPath())); sortByImageDateAct = new QAction(tr("By Image Date"), this); connect(sortByImageDateAct, SIGNAL(triggered()), this, SLOT(sortByImageDate())); sortByFileDateAct = new QAction(tr("By File Date"), this); connect(sortByFileDateAct, SIGNAL(triggered()), this, SLOT(sortByFileDate())); sortReverseAct = new QAction(tr("Reverse current order"), this); connect(sortReverseAct, SIGNAL(triggered()), this, SLOT(sortReverse())); showInfoWindowAct = new QAction(tr("&Image info..."), this); showInfoWindowAct->setShortcut(tr("Ctrl+I")); // showInfoWindowAct->setEnabled(true); connect (showInfoWindowAct, SIGNAL(triggered()), this, SLOT(showInfoWindow())); showPixelviewWindowAct = new QAction(tr("&Pixel closeup view..."), this); showPixelviewWindowAct->setCheckable (true); showPixelviewWindowAct->setShortcut(tr("P")); connect (showPixelviewWindowAct, SIGNAL(triggered()), this, SLOT(showPixelviewWindow())); pixelviewFollowsMouseBox = new QCheckBox (tr("Pixel view follows mouse")); pixelviewFollowsMouseBox->setChecked (false); linearInterpolationBox = new QCheckBox (tr("Linear interpolation")); linearInterpolationBox->setChecked (true); darkPaletteBox = new QCheckBox (tr("Dark palette")); darkPaletteBox->setChecked (true); autoMipmap = new QCheckBox (tr("Generate mipmaps (requires restart)")); autoMipmap->setChecked (false); maxMemoryICLabel = new QLabel (tr("Image Cache max memory (requires restart)")); maxMemoryIC = new QSpinBox (); if (sizeof (void *) == 4) maxMemoryIC->setRange (128, 2048); //2GB is enough for 32 bit machines else maxMemoryIC->setRange (128, 8192); //8GB probably ok for 64 bit maxMemoryIC->setSingleStep (64); maxMemoryIC->setSuffix (" MB"); slideShowDurationLabel = new QLabel (tr("Slide Show delay")); slideShowDuration = new QSpinBox (); slideShowDuration->setRange (1, 3600); slideShowDuration->setSingleStep (1); slideShowDuration->setSuffix (" s"); slideShowDuration->setAccelerated (true); connect(slideShowDuration, SIGNAL(valueChanged(int)), this, SLOT(setSlideShowDuration(int))); } void ImageViewer::createMenus() { openRecentMenu = new QMenu(tr("Open recent..."), this); for (size_t i = 0; i < MaxRecentFiles; ++i) openRecentMenu->addAction (openRecentAct[i]); fileMenu = new QMenu(tr("&File"), this); fileMenu->addAction (openAct); fileMenu->addMenu (openRecentMenu); fileMenu->addAction (reloadAct); fileMenu->addAction (closeImgAct); fileMenu->addSeparator (); fileMenu->addAction (saveAsAct); fileMenu->addAction (saveWindowAsAct); fileMenu->addAction (saveSelectionAsAct); fileMenu->addSeparator (); fileMenu->addAction (printAct); fileMenu->addAction (deleteCurrentImageAct); fileMenu->addSeparator (); fileMenu->addAction (editPreferencesAct); fileMenu->addAction (exitAct); menuBar()->addMenu (fileMenu); // Copy // Paste // Clear selection // radio: prioritize selection, crop selection expgamMenu = new QMenu(tr("Exposure/gamma")); // submenu expgamMenu->addAction (exposureMinusOneHalfStopAct); expgamMenu->addAction (exposureMinusOneTenthStopAct); expgamMenu->addAction (exposurePlusOneHalfStopAct); expgamMenu->addAction (exposurePlusOneTenthStopAct); expgamMenu->addAction (gammaMinusAct); expgamMenu->addAction (gammaPlusAct); // imageMenu = new QMenu(tr("&Image"), this); // menuBar()->addMenu (imageMenu); slideMenu = new QMenu(tr("Slide Show")); slideMenu->addAction (slideShowAct); slideMenu->addAction (slideLoopAct); slideMenu->addAction (slideNoLoopAct); sortMenu = new QMenu(tr("Sort")); sortMenu->addAction (sortByNameAct); sortMenu->addAction (sortByPathAct); sortMenu->addAction (sortByImageDateAct); sortMenu->addAction (sortByFileDateAct); sortMenu->addAction (sortReverseAct); channelMenu = new QMenu(tr("Channels")); // Color mode: true, random, falsegrgbacCrgR channelMenu->addAction (viewChannelFullAct); channelMenu->addAction (viewChannelRedAct); channelMenu->addAction (viewChannelGreenAct); channelMenu->addAction (viewChannelBlueAct); channelMenu->addAction (viewChannelAlphaAct); channelMenu->addAction (viewChannelPrevAct); channelMenu->addAction (viewChannelNextAct); colormodeMenu = new QMenu(tr("Color mode")); colormodeMenu->addAction (viewColorRGBAAct); colormodeMenu->addAction (viewColorRGBAct); colormodeMenu->addAction (viewColor1ChAct); colormodeMenu->addAction (viewColorLumAct); colormodeMenu->addAction (viewColorHeatmapAct); viewMenu = new QMenu(tr("&View"), this); viewMenu->addAction (prevImageAct); viewMenu->addAction (nextImageAct); viewMenu->addAction (toggleImageAct); viewMenu->addSeparator (); viewMenu->addAction (zoomInAct); viewMenu->addAction (zoomOutAct); viewMenu->addAction (normalSizeAct); viewMenu->addAction (fitWindowToImageAct); viewMenu->addAction (fitImageToWindowAct); viewMenu->addAction (fullScreenAct); viewMenu->addSeparator (); viewMenu->addAction (viewSubimagePrevAct); viewMenu->addAction (viewSubimageNextAct); viewMenu->addMenu (channelMenu); viewMenu->addMenu (colormodeMenu); viewMenu->addMenu (expgamMenu); menuBar()->addMenu (viewMenu); // Full screen mode // prev subimage <, next subimage > // fg/bg image... toolsMenu = new QMenu(tr("&Tools"), this); // Mode: select, zoom, pan, wipe toolsMenu->addAction (showInfoWindowAct); toolsMenu->addAction (showPixelviewWindowAct); toolsMenu->addMenu (slideMenu); toolsMenu->addMenu (sortMenu); // Menus, toolbars, & status // Annotate // [check] overwrite render // connect renderer // kill renderer // store render // Playback: forward, reverse, faster, slower, loop/pingpong menuBar()->addMenu (toolsMenu); helpMenu = new QMenu(tr("&Help"), this); helpMenu->addAction (aboutAct); menuBar()->addMenu (helpMenu); // Bring up user's guide } void ImageViewer::createToolBars() { #if 0 fileToolBar = addToolBar(tr("File")); fileToolBar->addAction(newAct); fileToolBar->addAction(openAct); fileToolBar->addAction(saveAct); editToolBar = addToolBar(tr("Edit")); editToolBar->addAction(cutAct); editToolBar->addAction(copyAct); editToolBar->addAction(pasteAct); #endif } void ImageViewer::createStatusBar() { statusImgInfo = new QLabel; statusBar()->addWidget (statusImgInfo); statusViewInfo = new QLabel; statusBar()->addWidget (statusViewInfo); statusProgress = new QProgressBar; statusProgress->setRange (0, 100); statusProgress->reset (); statusBar()->addWidget (statusProgress); mouseModeComboBox = new QComboBox; mouseModeComboBox->addItem (tr("Zoom")); mouseModeComboBox->addItem (tr("Pan")); mouseModeComboBox->addItem (tr("Wipe")); mouseModeComboBox->addItem (tr("Select")); mouseModeComboBox->addItem (tr("Annotate")); // Note: the order of the above MUST match the order of enum MouseMode statusBar()->addWidget (mouseModeComboBox); mouseModeComboBox->hide (); } void ImageViewer::readSettings (bool ui_is_set_up) { QSettings settings("OpenImageIO", "iv"); m_darkPalette = settings.value ("darkPalette").toBool(); if (! ui_is_set_up) return; pixelviewFollowsMouseBox->setChecked (settings.value ("pixelviewFollowsMouse").toBool()); linearInterpolationBox->setChecked (settings.value ("linearInterpolation").toBool()); darkPaletteBox->setChecked (settings.value ("darkPalette").toBool()); QStringList recent = settings.value ("RecentFiles").toStringList(); BOOST_FOREACH (const QString &s, recent) addRecentFile (s.toStdString()); updateRecentFilesMenu (); // only safe because it's called after menu setup autoMipmap->setChecked (settings.value ("autoMipmap", false).toBool()); if (sizeof(void *) == 4) // 32 bit or 64? maxMemoryIC->setValue (settings.value ("maxMemoryIC", 512).toInt()); else maxMemoryIC->setValue (settings.value ("maxMemoryIC", 2048).toInt()); slideShowDuration->setValue (settings.value ("slideShowDuration", 10).toInt()); ImageCache *imagecache = ImageCache::create (true); imagecache->attribute ("automip", autoMipmap->isChecked()); imagecache->attribute ("max_memory_MB", (float) maxMemoryIC->value ()); } void ImageViewer::writeSettings() { QSettings settings("OpenImageIO", "iv"); settings.setValue ("pixelviewFollowsMouse", pixelviewFollowsMouseBox->isChecked()); settings.setValue ("linearInterpolation", linearInterpolationBox->isChecked()); settings.setValue ("darkPalette", darkPaletteBox->isChecked()); settings.setValue ("autoMipmap", autoMipmap->isChecked()); settings.setValue ("maxMemoryIC", maxMemoryIC->value()); settings.setValue ("slideShowDuration", slideShowDuration->value()); QStringList recent; BOOST_FOREACH (const std::string &s, m_recent_files) recent.push_front (QString(s.c_str())); settings.setValue ("RecentFiles", recent); } bool image_progress_callback (void *opaque, float done) { ImageViewer *viewer = (ImageViewer *) opaque; viewer->statusProgress->setValue ((int)(done*100)); QApplication::processEvents(); return false; } void ImageViewer::open() { static QString openPath = QDir::currentPath(); QFileDialog dialog(NULL, tr("Open File(s)"), openPath, tr(s_file_filters)); dialog.setAcceptMode (QFileDialog::AcceptOpen); dialog.setFileMode (QFileDialog::ExistingFiles); if (!dialog.exec()) return; openPath = dialog.directory().path(); QStringList names = dialog.selectedFiles(); int old_lastimage = m_images.size()-1; for (QStringList::Iterator it = names.begin(); it != names.end(); ++it) { std::string filename = it->toUtf8().data(); if (filename.empty()) continue; add_image (filename); // int n = m_images.size()-1; // IvImage *newimage = m_images[n]; // newimage->read_iv (0, false, image_progress_callback, this); } if (old_lastimage >= 0) { // Otherwise, add_image already did this for us. current_image (old_lastimage + 1); fitWindowToImage (true, true); } } void ImageViewer::openRecentFile () { QAction *action = qobject_cast(sender()); if (action) { std::string filename = action->data().toString().toStdString(); // If it's an image we already have loaded, just switch to it // (and reload) rather than loading a second copy. for (size_t i = 0; i < m_images.size(); ++i) { if (m_images[i]->name() == filename) { current_image (i); reload (); return; } } // It's not an image we already have loaded add_image (filename); if (m_images.size() > 1) { // Otherwise, add_image already did this for us. current_image (m_images.size() - 1); fitWindowToImage (true, true); } } } void ImageViewer::addRecentFile (const std::string &name) { removeRecentFile (name); m_recent_files.insert (m_recent_files.begin(), name); if (m_recent_files.size() > MaxRecentFiles) m_recent_files.resize (MaxRecentFiles); } void ImageViewer::removeRecentFile (const std::string &name) { for (size_t i = 0; i < m_recent_files.size(); ++i) { if (m_recent_files[i] == name) { m_recent_files.erase (m_recent_files.begin()+i); --i; } } } void ImageViewer::updateRecentFilesMenu () { for (size_t i = 0; i < MaxRecentFiles; ++i) { if (i < m_recent_files.size()) { std::string name = Filesystem::filename (m_recent_files[i]); openRecentAct[i]->setText (QString::fromStdString (name)); openRecentAct[i]->setData (m_recent_files[i].c_str()); openRecentAct[i]->setVisible (true); } else { openRecentAct[i]->setVisible (false); } } } void ImageViewer::reload() { if (m_images.empty()) return; IvImage *newimage = m_images[m_current_image]; newimage->invalidate (); //glwin->trigger_redraw (); displayCurrentImage (); } void ImageViewer::add_image (const std::string &filename) { if (filename.empty()) return; IvImage *newimage = new IvImage(filename); newimage->gamma (m_default_gamma); ASSERT (newimage); m_images.push_back (newimage); addRecentFile (filename); updateRecentFilesMenu (); #if 0 if (getspec) { if (! newimage->init_spec (filename)) { QMessageBox::information (this, tr("iv Image Viewer"), tr("%1").arg(newimage->geterror().c_str())); } else { std::cerr << "Added image " << filename << ": " << newimage->spec().width << " x " << newimage->spec().height << "\n"; } return; } #endif if (m_images.size() == 1) { // If this is the first image, resize to fit it displayCurrentImage (); fitWindowToImage (true, true); } } void ImageViewer::saveAs() { IvImage *img = cur(); if (! img) return; QString name; name = QFileDialog::getSaveFileName (this, tr("Save Image"), QString(img->name().c_str()), tr(s_file_filters)); if (name.isEmpty()) return; bool ok = img->write (name.toStdString(), "", image_progress_callback, this); if (! ok) { std::cerr << "Save failed: " << img->geterror() << "\n"; } } void ImageViewer::saveWindowAs() { IvImage *img = cur(); if (! img) return; QString name; name = QFileDialog::getSaveFileName (this, tr("Save Window"), QString(img->name().c_str())); if (name.isEmpty()) return; img->write (name.toStdString(), "", image_progress_callback, this); // FIXME } void ImageViewer::saveSelectionAs() { IvImage *img = cur(); if (! img) return; QString name; name = QFileDialog::getSaveFileName (this, tr("Save Selection"), QString(img->name().c_str())); if (name.isEmpty()) return; img->write (name.toStdString(), "", image_progress_callback, this); // FIXME } void ImageViewer::updateTitle () { IvImage *img = cur(); if (! img) { setWindowTitle (tr("iv Image Viewer (no image loaded)")); return; } std::string message; message = Strutil::format ("%s - iv Image Viewer", img->name().c_str()); setWindowTitle (QString::fromLocal8Bit(message.c_str())); } void ImageViewer::updateStatusBar () { const ImageSpec *spec = curspec(); if (! spec) { statusImgInfo->setText (tr("No image loaded")); statusViewInfo->setText (tr("")); return; } std::string message; message = Strutil::format ("(%d/%d) : ", m_current_image+1, (int) m_images.size()); message += cur()->shortinfo(); statusImgInfo->setText (message.c_str()); message.clear(); switch (m_color_mode) { case RGBA: message = Strutil::format ("RGBA (%d-%d)", m_current_channel, m_current_channel+3); break; case RGB: message = Strutil::format ("RGB (%d-%d)", m_current_channel, m_current_channel+2); break; case LUMINANCE: message = Strutil::format ("Lum (%d-%d)", m_current_channel, m_current_channel+2); break; case HEATMAP: message = "Heat "; case SINGLE_CHANNEL: if ((int)spec->channelnames.size() > m_current_channel && spec->channelnames[m_current_channel].size()) message += spec->channelnames[m_current_channel]; else if (m_color_mode == HEATMAP) { message += Strutil::format ("%d", m_current_channel); } else { message = Strutil::format ("chan %d", m_current_channel); } break; } message += Strutil::format (" %g:%g exp %+.1f gam %.2f", zoom() >= 1 ? zoom() : 1.0f, zoom() >= 1 ? 1.0f : 1.0f/zoom(), cur()->exposure(), cur()->gamma()); if (cur()->nsubimages() > 1) { if (cur()->auto_subimage()) { message += Strutil::format (" subimg AUTO (%d/%d)", cur()->subimage()+1, cur()->nsubimages()); } else { message += Strutil::format (" subimg %d/%d", cur()->subimage()+1, cur()->nsubimages()); } } if (cur()->nmiplevels() > 1) { message += Strutil::format (" MIP %d/%d", cur()->miplevel()+1, cur()->nmiplevels()); } statusViewInfo->setText(message.c_str()); // tr("iv status")); } bool ImageViewer::loadCurrentImage (int subimage, int miplevel) { if (m_current_image < 0 || m_current_image >= (int)m_images.size()) { m_current_image = 0; } IvImage *img = cur (); if (img) { // We need the spec available to compare the image format with // opengl's capabilities. if (! img->init_spec (img->name(), subimage, miplevel)) { statusImgInfo->setText (tr ("Could not display image: %1.").arg (img->name().c_str())); statusViewInfo->setText (tr("")); return false; } // Used to check whether we'll need to do adjustments in the // CPU. If true, images should be loaded as UINT8. bool allow_transforms = false; bool srgb_transform = false; // By default, we try to load into OpenGL with the same format, TypeDesc read_format = TypeDesc::UNKNOWN; const ImageSpec &image_spec = img->spec(); if (image_spec.format.basetype == TypeDesc::DOUBLE) { // AFAIK, OpenGL doesn't support 64-bit floats as pixel size. read_format = TypeDesc::FLOAT; } if (glwin->is_glsl_capable ()) { if (image_spec.format.basetype == TypeDesc::HALF && ! glwin->is_half_capable ()) { //std::cerr << "Loading HALF-FLOAT as FLOAT\n"; read_format = TypeDesc::FLOAT; } if (IsSpecSrgb(image_spec) && !glwin->is_srgb_capable ()) { // If the image is in sRGB, but OpenGL can't load sRGB textures then // we'll need to do the transformation on the CPU after loading the // image. We (so far) can only do this with UINT8 images, so make // sure that it gets loaded in this format. //std::cerr << "Loading as UINT8 to do sRGB\n"; read_format = TypeDesc::UINT8; srgb_transform = true; allow_transforms = true; } } else { //std::cerr << "Loading as UINT8\n"; read_format = TypeDesc::UINT8; allow_transforms = true; if (IsSpecSrgb(image_spec) && !glwin->is_srgb_capable ()) srgb_transform = true; } // FIXME: This actually won't work since the ImageCacheFile has already // been created when we did the init_spec. // Check whether IvGL recommends generating mipmaps for this image. //ImageCache *imagecache = ImageCache::create (true); //if (glwin->is_too_big (img) && autoMipmap->isChecked ()) { // imagecache->attribute ("automip", 1); //} else { // imagecache->attribute ("automip", 0); //} // Read the image from disk or from the ImageCache if available. if (img->read_iv (subimage, miplevel, false, read_format, image_progress_callback, this, allow_transforms)) { // The image was read succesfully. // Check if we've got to do sRGB to linear (ie, when not supported // by OpenGL). // Do the first pixel transform to fill-in the secondary image // buffer. if (allow_transforms) { img->pixel_transform (srgb_transform, (int) current_color_mode(), current_channel()); } return true; } else { statusImgInfo->setText (tr ("Could not display image: %1.").arg (img->name().c_str())); statusViewInfo->setText (tr("")); return false; } } return false; } void ImageViewer::displayCurrentImage (bool update) { if (m_current_image < 0 || m_current_image >= (int)m_images.size()) m_current_image = 0; IvImage *img = cur(); if (img) { if (! img->image_valid()) { bool load_result = false; statusViewInfo->hide (); statusProgress->show (); load_result = loadCurrentImage (std::max (0, img->subimage()), std::max (0, img->miplevel())); statusProgress->hide (); statusViewInfo->show (); if (load_result) { update = true; } else { return; } } } else { m_current_image = m_last_image = -1; repaint(); // add repaint event to Qt queue glwin->trigger_redraw(); // then make sure GL canvas is cleared } if (update) { glwin->update (); } float z = zoom(); if (fitImageToWindowAct->isChecked ()) z = zoom_needed_to_fit (glwin->width(), glwin->height()); zoom (z); // glwin->trigger_redraw (); updateTitle(); updateStatusBar(); if (infoWindow) infoWindow->update (img); // printAct->setEnabled(true); // fitImageToWindowAct->setEnabled(true); // fullScreenAct->setEnabled(true); updateActions(); } void ImageViewer::deleteCurrentImage() { IvImage *img = cur(); if (img) { const char *filename = img->name().c_str(); QString message ("Are you sure you want to remove "); message = message + QString(filename) + QString(" file from disk?"); QMessageBox::StandardButton button; button = QMessageBox::question (this, "", message, QMessageBox::Yes | QMessageBox::No); if (button == QMessageBox::Yes) { closeImg(); int r = remove (filename); if (r) QMessageBox::information (this, "", "Unable to delete file"); } } } void ImageViewer::current_image (int newimage) { #ifndef NDEBUG Timer swap_image_time; swap_image_time.start(); #endif if (m_images.empty() || newimage < 0 || newimage >= (int)m_images.size()) m_current_image = 0; if (m_current_image != newimage) { m_last_image = (m_current_image >= 0) ? m_current_image : newimage; m_current_image = newimage; displayCurrentImage (); } else { displayCurrentImage (false); } #ifndef NDEBUG swap_image_time.stop(); std::cerr << "Current Image change elapsed time: " << swap_image_time() << " seconds \n"; #endif } void ImageViewer::prevImage () { if (m_images.empty()) return; if (m_current_image == 0) current_image ((int)m_images.size() - 1); else current_image (current_image() - 1); } void ImageViewer::nextImage () { if (m_images.empty()) return; if (m_current_image >= (int)m_images.size()-1) current_image (0); else current_image (current_image() + 1); } void ImageViewer::toggleImage () { current_image (m_last_image); } void ImageViewer::exposureMinusOneTenthStop () { if (m_images.empty()) return; IvImage *img = m_images[m_current_image]; img->exposure (img->exposure() - 0.1); if (! glwin->is_glsl_capable ()) { bool srgb_transform = (! glwin->is_srgb_capable () && IsSpecSrgb(img->spec())); img->pixel_transform (srgb_transform, (int) current_color_mode(), current_channel()); displayCurrentImage (); } else { displayCurrentImage (false); } } void ImageViewer::exposureMinusOneHalfStop () { if (m_images.empty()) return; IvImage *img = m_images[m_current_image]; img->exposure (img->exposure() - 0.5); if (! glwin->is_glsl_capable ()) { bool srgb_transform = (! glwin->is_srgb_capable () && IsSpecSrgb(img->spec())); img->pixel_transform (srgb_transform, (int) current_color_mode(), current_channel()); displayCurrentImage (); } else { displayCurrentImage (false); } } void ImageViewer::exposurePlusOneTenthStop () { if (m_images.empty()) return; IvImage *img = m_images[m_current_image]; img->exposure (img->exposure() + 0.1); if (! glwin->is_glsl_capable ()) { bool srgb_transform = (! glwin->is_srgb_capable () && IsSpecSrgb(img->spec())); img->pixel_transform (srgb_transform, (int) current_color_mode(), current_channel()); displayCurrentImage (); } else { displayCurrentImage (false); } } void ImageViewer::exposurePlusOneHalfStop () { if (m_images.empty()) return; IvImage *img = m_images[m_current_image]; img->exposure (img->exposure() + 0.5); if (! glwin->is_glsl_capable ()) { bool srgb_transform = (! glwin->is_srgb_capable () && IsSpecSrgb(img->spec())); img->pixel_transform (srgb_transform, (int) current_color_mode(), current_channel()); displayCurrentImage (); } else { displayCurrentImage (false); } } void ImageViewer::gammaMinus () { if (m_images.empty()) return; IvImage *img = m_images[m_current_image]; img->gamma (img->gamma() - 0.05); if (! glwin->is_glsl_capable ()) { bool srgb_transform = (! glwin->is_srgb_capable () && IsSpecSrgb(img->spec())); img->pixel_transform (srgb_transform, (int) current_color_mode(), current_channel()); displayCurrentImage (); } else { displayCurrentImage (false); } } void ImageViewer::gammaPlus () { if (m_images.empty()) return; IvImage *img = m_images[m_current_image]; img->gamma (img->gamma() + 0.05); if (! glwin->is_glsl_capable ()) { bool srgb_transform = (! glwin->is_srgb_capable () && IsSpecSrgb(img->spec())); img->pixel_transform (srgb_transform, (int) current_color_mode(), current_channel()); displayCurrentImage (); } else { displayCurrentImage (false); } } void ImageViewer::slide (long t, bool b) { slideLoopAct->setChecked (b == true); slideNoLoopAct->setChecked (b == false); } void ImageViewer::viewChannel (int c, COLOR_MODE colormode) { #ifndef NDEBUG Timer change_channel_time; change_channel_time.start(); #endif if (m_current_channel != c || colormode != m_color_mode) { bool update = true; if (! glwin->is_glsl_capable ()) { IvImage *img = cur (); if (img) { bool srgb_transform = (! glwin->is_srgb_capable () && IsSpecSrgb(img->spec())); img->pixel_transform (srgb_transform, (int)colormode, c); } } else { // FIXME: There are even more chances to avoid updating the textures // if we can keep trac of which channels are in the texture. if (m_current_channel == c) { if (m_color_mode == SINGLE_CHANNEL || m_color_mode == HEATMAP) { if (colormode == HEATMAP || colormode == SINGLE_CHANNEL) update = false; } else if (m_color_mode == RGB || m_color_mode == LUMINANCE) { if (colormode == RGB || colormode == LUMINANCE) update = false; } } } m_current_channel = c; m_color_mode = colormode; displayCurrentImage (update); viewChannelFullAct->setChecked (c == 0 && m_color_mode == RGBA); viewChannelRedAct->setChecked (c == 0 && m_color_mode == SINGLE_CHANNEL); viewChannelGreenAct->setChecked (c == 1 && m_color_mode == SINGLE_CHANNEL); viewChannelBlueAct->setChecked (c == 2 && m_color_mode == SINGLE_CHANNEL); viewChannelAlphaAct->setChecked (c == 3 && m_color_mode == SINGLE_CHANNEL); viewColorLumAct->setChecked (m_color_mode == LUMINANCE); viewColorRGBAAct->setChecked (m_color_mode == RGBA); viewColorRGBAct->setChecked (m_color_mode == RGB); viewColor1ChAct->setChecked (m_color_mode == SINGLE_CHANNEL); viewColorHeatmapAct->setChecked (m_color_mode == HEATMAP); } #ifndef NDEBUG change_channel_time.stop(); std::cerr << "Change channel elapsed time: " << change_channel_time() << " seconds \n"; #endif } void ImageViewer::slideImages() { if (m_images.empty()) return; if (m_current_image >= (int)m_images.size()-1) { if (slide_loop == true) current_image (0); else { slideTimer->stop(); disconnect(slideTimer,0,0,0); } } else current_image (current_image() + 1); } void ImageViewer::slideShow () { fullScreenToggle(); connect(slideTimer,SIGNAL(timeout()),this,SLOT(slideImages())); slideTimer->start(slideDuration_ms); updateActions(); } void ImageViewer::slideLoop () { slide_loop = true; slide(slideDuration_ms, slide_loop); } void ImageViewer::slideNoLoop () { slide_loop = false; slide(slideDuration_ms, slide_loop); } void ImageViewer::setSlideShowDuration (int seconds) { slideDuration_ms = seconds * 1000; } static bool compName (IvImage *first, IvImage *second) { std::string firstFile = Filesystem::filename (first->name()); std::string secondFile = Filesystem::filename (second->name()); return (firstFile.compare(secondFile) < 0); } void ImageViewer::sortByName () { int numImg = m_images.size(); if (numImg < 2) return; std::sort (m_images.begin(), m_images.end(), &compName); current_image (0); displayCurrentImage(); // updateActions(); } static bool compPath (IvImage *first, IvImage *second) { std::string firstFile = first->name (); std::string secondFile = second->name (); return (firstFile.compare(secondFile) < 0); } void ImageViewer::sortByPath () { int numImg = m_images.size(); if (numImg < 2) return; std::sort (m_images.begin(), m_images.end(), &compPath); current_image(0); displayCurrentImage(); // updateActions(); } static bool DateTime_to_time_t (const char *datetime, time_t &timet) { int year, month, day, hour, min, sec; int r = sscanf (datetime, "%d:%d:%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec); // printf ("%d %d:%d:%d %d:%d:%d\n", r, year, month, day, hour, min, sec); if (r != 6) return false; struct tm tmtime; time_t now; Sysutil::get_local_time (&now, &tmtime); // fill in defaults tmtime.tm_sec = sec; tmtime.tm_min = min; tmtime.tm_hour = hour; tmtime.tm_mday = day; tmtime.tm_mon = month-1; tmtime.tm_year = year-1900; timet = mktime (&tmtime); return true; } static bool compImageDate (IvImage *first, IvImage *second) { std::time_t firstFile = time(NULL); std::time_t secondFile = time(NULL); double diff; std::string metadatatime = first->spec ().get_string_attribute ("DateTime"); if (metadatatime.empty()) { if (first->init_spec (first->name(), 0, 0)) { metadatatime = first->spec ().get_string_attribute ("DateTime"); if (metadatatime.empty()){ if (! Filesystem::exists (first->name ())) return false; firstFile = boost::filesystem::last_write_time (first->name ()); } } else return false; } DateTime_to_time_t (metadatatime.c_str(), firstFile); metadatatime = second->spec().get_string_attribute ("DateTime"); if (metadatatime.empty()) { if (second->init_spec(second->name(), 0, 0)) { metadatatime = second->spec ().get_string_attribute ("DateTime"); if (metadatatime.empty()){ if (! Filesystem::exists (second->name ())) return true; secondFile = boost::filesystem::last_write_time (second->name()); } } else return true; } DateTime_to_time_t (metadatatime.c_str(), secondFile); diff = difftime(firstFile, secondFile); if (diff == 0) return compName(first,second); return (diff < 0); } void ImageViewer::sortByImageDate () { int numImg = m_images.size(); if (numImg < 2) return; std::sort( m_images.begin(), m_images.end(), &compImageDate); current_image(0); displayCurrentImage(); // updateActions(); } static bool compFileDate (IvImage *first, IvImage *second) { std::time_t firstFile, secondFile; double diff; if (! Filesystem::exists (first->name ())) return false; firstFile = boost::filesystem::last_write_time (first->name ()); if (! Filesystem::exists (second->name ())) return true; secondFile = boost::filesystem::last_write_time (second->name ()); diff = difftime(firstFile, secondFile); if (diff == 0) return compName(first, second); return (diff < 0); } void ImageViewer::sortByFileDate () { int numImg = m_images.size(); if (numImg<2) return; std::sort( m_images.begin(), m_images.end(), &compFileDate); current_image(0); displayCurrentImage(); // updateActions(); } void ImageViewer::sortReverse () { int numImg = m_images.size(); if (numImg < 2) return; std::reverse( m_images.begin(), m_images.end()); current_image(0); displayCurrentImage(); // updateActions(); } void ImageViewer::viewChannelFull () { viewChannel (0, RGBA); } void ImageViewer::viewChannelRed () { viewChannel (0, SINGLE_CHANNEL); } void ImageViewer::viewChannelGreen () { viewChannel (1, SINGLE_CHANNEL); } void ImageViewer::viewChannelBlue () { viewChannel (2, SINGLE_CHANNEL); } void ImageViewer::viewChannelAlpha () { viewChannel (3, SINGLE_CHANNEL); } void ImageViewer::viewChannelLuminance () { viewChannel (m_current_channel, LUMINANCE); } void ImageViewer::viewColorRGBA () { viewChannel (m_current_channel, RGBA); } void ImageViewer::viewColorRGB () { viewChannel (m_current_channel, RGB); } void ImageViewer::viewColor1Ch () { viewChannel (m_current_channel, SINGLE_CHANNEL); } void ImageViewer::viewColorHeatmap () { viewChannel (m_current_channel, HEATMAP); } void ImageViewer::viewChannelPrev () { if (glwin->is_glsl_capable()) { if (m_current_channel > 0) viewChannel (m_current_channel-1, m_color_mode); } else { // Simulate old behavior. if (m_color_mode == RGBA || m_color_mode == RGB) { viewChannel (m_current_channel, LUMINANCE); } else if (m_color_mode == SINGLE_CHANNEL) { if (m_current_channel == 0) viewChannelFull(); else viewChannel (m_current_channel-1, SINGLE_CHANNEL); } } } void ImageViewer::viewChannelNext () { if (glwin->is_glsl_capable()) { viewChannel (m_current_channel+1, m_color_mode); } else { // Simulate old behavior. if (m_color_mode == LUMINANCE) { viewChannelFull(); } else if (m_color_mode == RGBA || m_color_mode == RGB) { viewChannelRed(); } else if (m_color_mode == SINGLE_CHANNEL) { viewChannel (m_current_channel+1, SINGLE_CHANNEL); } } } void ImageViewer::viewSubimagePrev () { IvImage *img = cur(); if (! img) return; bool ok = false; if (img->miplevel() > 0) { ok = loadCurrentImage (img->subimage(), img->miplevel()-1); } else if (img->subimage() > 0) { ok = loadCurrentImage (img->subimage()-1); } else if (img->nsubimages() > 0) { img->auto_subimage (true); ok = loadCurrentImage (0); } if (ok) { if (fitImageToWindowAct->isChecked ()) fitImageToWindow (); displayCurrentImage (); } } void ImageViewer::viewSubimageNext () { IvImage *img = cur(); if (! img) return; bool ok = false; if (img->auto_subimage()) { img->auto_subimage(false); ok = loadCurrentImage (0); } else if (img->miplevel() < img->nmiplevels()-1) { ok = loadCurrentImage (img->subimage(), img->miplevel()+1); } else if (img->subimage() < img->nsubimages()-1) { ok = loadCurrentImage (img->subimage()+1); } if (ok) { if (fitImageToWindowAct->isChecked ()) fitImageToWindow (); displayCurrentImage (); } } void ImageViewer::keyPressEvent (QKeyEvent *event) { switch (event->key()) { case Qt::Key_Left : case Qt::Key_Up : case Qt::Key_PageUp : prevImage(); return; //break; case Qt::Key_Right : // std::cerr << "Modifier is " << (int)event->modifiers() << '\n'; // fprintf (stderr, "%x\n", (int)event->modifiers()); // if (event->modifiers() & Qt::ShiftModifier) // std::cerr << "hey, ctrl right\n"; case Qt::Key_Down : case Qt::Key_PageDown : nextImage(); return; //break; case Qt::Key_Escape : if (m_fullscreen) fullScreenToggle(); return; case Qt::Key_Minus : case Qt::Key_Underscore : zoomOut(); break; case Qt::Key_Plus : case Qt::Key_Equal : zoomIn(); break; default: // std::cerr << "ImageViewer key " << (int)event->key() << '\n'; QMainWindow::keyPressEvent (event); } } void ImageViewer::resizeEvent (QResizeEvent *event) { if (fitImageToWindowAct->isChecked ()) fitImageToWindow (); QMainWindow::resizeEvent (event); } void ImageViewer::closeImg() { if (m_images.empty()) return; delete m_images[m_current_image]; m_images[m_current_image] = NULL; m_images.erase (m_images.begin()+m_current_image); // Update image indices // This should be done for all image indices we may be storing if (m_last_image == m_current_image) { if (!m_images.empty() && m_last_image > 0) m_last_image = 0; else m_last_image = -1; } if (m_last_image > m_current_image) m_last_image --; m_current_image = m_current_image < (int)m_images.size() ? m_current_image : 0; displayCurrentImage (); } void ImageViewer::print() { #if 0 Q_ASSERT(imageLabel->pixmap()); QPrintDialog dialog(&printer, this); if (dialog.exec()) { QPainter painter(&printer); QRect rect = painter.viewport(); QSize size = imageLabel->pixmap()->size(); size.scale(rect.size(), Qt::KeepAspectRatio); painter.setViewport(rect.x(), rect.y(), size.width(), size.height()); painter.setWindow(imageLabel->pixmap()->rect()); painter.drawPixmap(0, 0, *imageLabel->pixmap()); } #endif } void ImageViewer::zoomIn() { IvImage *img = cur(); if (! img) return; if (zoom() >= 64) return; float oldzoom = zoom (); float newzoom = pow2roundupf (oldzoom); float xc, yc; // Center view position glwin->get_center (xc, yc); int xm, ym; // Mouse position glwin->get_focus_image_pixel (xm, ym); float xoffset = xc - xm; float yoffset = yc - ym; float maxzoomratio = std::max (oldzoom/newzoom, newzoom/oldzoom); int nsteps = (int) Imath::clamp (20 * (maxzoomratio - 1), 2.0f, 10.0f); for (int i = 1; i <= nsteps; ++i) { float a = (float)i/(float)nsteps; // Interpolation amount float z = Imath::lerp (oldzoom, newzoom, a); float zoomratio = z / oldzoom; view (xm + xoffset/zoomratio, ym + yoffset/zoomratio, z, false); if (i != nsteps) Sysutil::usleep (1000000 / 4 / nsteps); } fitImageToWindowAct->setChecked (false); } void ImageViewer::zoomOut() { IvImage *img = cur(); if (! img) return; if (zoom() <= 1.0f/64) return; float oldzoom = zoom (); float newzoom = pow2rounddownf (oldzoom); float xcpel, ycpel; // Center view position glwin->get_center (xcpel, ycpel); int xmpel, ympel; // Mouse position glwin->get_focus_image_pixel (xmpel, ympel); float xoffset = xcpel - xmpel; float yoffset = ycpel - ympel; float maxzoomratio = std::max (oldzoom/newzoom, newzoom/oldzoom); int nsteps = (int) Imath::clamp (20 * (maxzoomratio - 1), 2.0f, 10.0f); for (int i = 1; i <= nsteps; ++i) { float a = (float)i/(float)nsteps; // Interpolation amount float z = Imath::lerp (oldzoom, newzoom, a); float zoomratio = z / oldzoom; view (xmpel + xoffset/zoomratio, ympel + yoffset/zoomratio, z, false); if (i != nsteps) Sysutil::usleep (1000000 / 4 / nsteps); } fitImageToWindowAct->setChecked (false); } void ImageViewer::normalSize() { IvImage *img = cur(); if (! img) return; fitImageToWindowAct->setChecked (false); float xcenter = img->oriented_full_x() + 0.5 * img->oriented_full_width(); float ycenter = img->oriented_full_y() + 0.5 * img->oriented_full_height(); view (xcenter, ycenter, 1.0, true); fitWindowToImage (false); } float ImageViewer::zoom_needed_to_fit (int w, int h) { IvImage *img = cur(); if (! img) return 1; float zw = (float) w / img->oriented_width (); float zh = (float) h / img->oriented_height (); return std::min (zw, zh); } void ImageViewer::fitImageToWindow() { IvImage *img = cur(); if (! img) return; fitImageToWindowAct->setChecked (true); zoom (zoom_needed_to_fit (glwin->width(), glwin->height())); } void ImageViewer::fitWindowToImage (bool zoomok, bool minsize) { IvImage *img = cur(); // Don't resize when there's no image or the image hasn't been opened yet // (or we failed to open it). if (! img || ! img->image_valid ()) return; // FIXME -- figure out a way to make it exactly right, even for the // main window border, etc. #ifdef __APPLE__ int extraw = 0; //12; // width() - minimumWidth(); int extrah = statusBar()->height() + 0; //40; // height() - minimumHeight(); #else int extraw = 4; //12; // width() - minimumWidth(); int extrah = statusBar()->height() + 4; //40; // height() - minimumHeight(); #endif // std::cerr << "extra wh = " << extraw << ' ' << extrah << '\n'; float z = zoom(); int w = (int)(img->oriented_full_width() * z)+extraw; int h = (int)(img->oriented_full_height() * z)+extrah; if (minsize) { if (w < m_default_width) { w = m_default_width; } if (h < m_default_height) { h = m_default_height; } } if (! m_fullscreen) { QDesktopWidget *desktop = QApplication::desktop (); QRect availgeom = desktop->availableGeometry (this); int availwidth = availgeom.width() - extraw - 20; int availheight = availgeom.height() - extrah - menuBar()->height() - 20; #if 0 QRect screengeom = desktop->screenGeometry (this); std::cerr << "available desktop geom " << availgeom.x() << ' ' << availgeom.y() << ' ' << availgeom.width() << "x" << availgeom.height() << "\n"; std::cerr << "screen desktop geom " << screengeom.x() << ' ' << screengeom.y() << ' ' << screengeom.width() << "x" << screengeom.height() << "\n"; #endif if (w > availwidth || h > availheight) { w = std::min (w, availwidth); h = std::min (h, availheight); if (zoomok) { z = zoom_needed_to_fit (w, h); w = (int)(img->oriented_full_width() * z) + extraw; h = (int)(img->oriented_full_height() * z) + extrah; // std::cerr << "must rezoom to " << z << " to fit\n"; } // std::cerr << "New window geom " << w << "x" << h << "\n"; int posx = x(), posy = y(); if (posx + w > availwidth || posy + h > availheight) { if (posx + w > availwidth) posx = std::max (0, availwidth - w) + availgeom.x(); if (posy + h > availheight) posy = std::max (0, availheight - h) + availgeom.y(); // std::cerr << "New position " << posx << ' ' << posy << "\n"; move (QPoint (posx, posy)); } } } float midx = img->oriented_full_x() + 0.5 * img->oriented_full_width(); float midy = img->oriented_full_y() + 0.5 * img->oriented_full_height(); view (midx, midy, z, false, false); resize (w, h); // Resize will trigger a repaint. #if 0 QRect g = geometry(); std::cerr << "geom " << g.x() << ' ' << g.y() << ' ' << g.width() << "x" << g.height() << "\n"; g = frameGeometry(); std::cerr << "frame geom " << g.x() << ' ' << g.y() << ' ' << g.width() << "x" << g.height() << "\n"; g = glwin->geometry(); std::cerr << "ogl geom " << g.x() << ' ' << g.y() << ' ' << g.width() << "x" << g.height() << "\n"; std::cerr << "Status bar height = " << statusBar()->height() << "\n"; #endif #if 0 bool fit = fitWindowToImageAct->isChecked(); if (!fit) { normalSize(); } #endif updateActions(); } void ImageViewer::fullScreenToggle() { if (m_fullscreen) { menuBar()->show (); statusBar()->show (); showNormal (); m_fullscreen = false; slideTimer->stop(); disconnect(slideTimer,0,0,0); } else { menuBar()->hide (); statusBar()->hide (); showFullScreen (); m_fullscreen = true; fitImageToWindow (); } } void ImageViewer::about() { QMessageBox::about(this, tr("About iv"), tr("

iv is the image viewer for OpenImageIO.

" "

(c) Copyright 2008 Larry Gritz et al. All Rights Reserved.

" "

See http://openimageio.org for details.

")); } void ImageViewer::updateActions() { // zoomInAct->setEnabled(!fitImageToWindowAct->isChecked()); // zoomOutAct->setEnabled(!fitImageToWindowAct->isChecked()); // normalSizeAct->setEnabled(!fitImageToWindowAct->isChecked()); } static inline void calc_subimage_from_zoom (const IvImage *img, int &subimage, float &zoom, float &xcenter, float &ycenter) { int rel_subimage = Imath::trunc (log2f (1/zoom)); subimage = clamp (img->subimage() + rel_subimage, 0, img->nsubimages()-1); if (! (img->subimage() == 0 && zoom > 1) && ! (img->subimage() == img->nsubimages()-1 && zoom < 1)) { float pow_zoom = powf (2.0f, (float) rel_subimage); zoom *= pow_zoom; xcenter /= pow_zoom; ycenter /= pow_zoom; } } void ImageViewer::view (float xcenter, float ycenter, float newzoom, bool smooth, bool redraw) { IvImage *img = cur(); if (! img) return; float oldzoom = m_zoom; float oldxcenter, oldycenter; glwin->get_center (oldxcenter, oldycenter); float zoomratio = std::max (oldzoom/newzoom, newzoom/oldzoom); int nsteps = (int) Imath::clamp (20 * (zoomratio - 1), 2.0f, 10.0f); if (! smooth || ! redraw) nsteps = 1; for (int i = 1; i <= nsteps; ++i) { float a = (float)i/(float)nsteps; // Interpolation amount float xc = Imath::lerp (oldxcenter, xcenter, a); float yc = Imath::lerp (oldycenter, ycenter, a); m_zoom = Imath::lerp (oldzoom, newzoom, a); glwin->view (xc, yc, m_zoom, redraw); // Triggers redraw automatically if (i != nsteps) Sysutil::usleep (1000000 / 4 / nsteps); } if (img->auto_subimage ()) { int subimage = 0; calc_subimage_from_zoom (img, subimage, m_zoom, xcenter, ycenter); if (subimage != img->subimage ()) { //std::cerr << "Changing to subimage " << subimage; //std::cerr << " With zoom: " << m_zoom << '\n'; loadCurrentImage (subimage); glwin->update (); glwin->view (xcenter, ycenter, m_zoom, redraw); } } // zoomInAct->setEnabled (zoom() < 64.0); // zoomOutAct->setEnabled (zoom() > 1.0/64); updateStatusBar (); } void ImageViewer::zoom (float newzoom, bool smooth) { float xcenter, ycenter; glwin->get_center (xcenter, ycenter); view (xcenter, ycenter, newzoom, smooth); } void ImageViewer::showInfoWindow () { if (! infoWindow) { infoWindow = new IvInfoWindow (*this, true); infoWindow->setPalette (m_palette); } infoWindow->update (cur()); if (infoWindow->isHidden ()) infoWindow->show (); else infoWindow->hide (); } void ImageViewer::showPixelviewWindow () { glwin->trigger_redraw (); } void ImageViewer::editPreferences () { if (! preferenceWindow) { preferenceWindow = new IvPreferenceWindow (*this); preferenceWindow->setPalette (m_palette); } preferenceWindow->show (); } openimageio-1.3.12~dfsg0.orig/src/iv/imageviewer.h0000644000175000017500000004212012271062644020202 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_IMAGEVIEWER_H #define OPENIMAGEIO_IMAGEVIEWER_H #if defined (_MSC_VER) // Ignore warnings about conditional expressions that always evaluate true // on a given platform but may evaluate differently on another. There's // nothing wrong with such conditionals. // Also ignore warnings about not being able to generate default assignment // operators for some Qt classes included in headers below. # pragma warning (disable : 4127 4512) #endif // included to remove std::min/std::max errors #include "osdep.h" #include // This needs to be included before GL.h #include #include #include #include #include #ifndef QT_NO_PRINTER #include #endif #include "imageio.h" #include "imagebuf.h" OIIO_NAMESPACE_USING; class QComboBox; class QLabel; class QMenu; class QMenuBar; class QProgressBar; class QPushButton; class QSpinBox; class QScrollArea; class QStatusBar; class QVBoxLayout; class IvMainWindow; class IvInfoWindow; class IvPreferenceWindow; class IvCanvas; class IvGL; class IvImage; class IvImage : public ImageBuf { public: IvImage (const std::string &filename); virtual ~IvImage (); /// Read the image into ram. /// If secondary buffer is true, and the format is UINT8, then a secondary /// buffer will be created and the apply_corrections(), and /// select_channel() methods will work. /// Also, scanline will return a pointer to that buffer instead of the read /// buffer. bool read_iv (int subimage=0, int miplevel=0, bool force=false, TypeDesc format = TypeDesc::UNKNOWN, ProgressCallback progress_callback=NULL, void *progress_callback_data=NULL, bool secondary_buffer=false); bool init_spec_iv (const std::string &filename, int subimage, int miplevel); float gamma (void) const { return m_gamma; } void gamma (float e) { m_gamma = e; } float exposure (void) const { return m_exposure; } void exposure (float e) { m_exposure = e; } int nchannels () const { if (m_corrected_image.localpixels()) { return m_corrected_image.nchannels(); } return spec().nchannels; } std::string shortinfo () const; std::string longinfo () const; void invalidate (); /// Can we read the pixels of this image already? /// bool image_valid () const { return m_image_valid; } /// Copies data from the read buffer to the secondary buffer, selecting the /// given channel: /// -2 = luminance /// -1 = all channels /// 0 = red /// 1 = green /// 2 = blue /// 3 = alpha /// Then applies gamma/exposure correction (if any). This only works when /// the image is UINT8 (for now at least). It also performs sRGB to linear /// color space correction when indicated. void pixel_transform (bool srgb_to_linear, int color_mode, int channel); bool get_pixels (int xbegin, int xend, int ybegin, int yend, TypeDesc format, void *result) { if (m_corrected_image.localpixels ()) { return m_corrected_image.get_pixels (xbegin, xend, ybegin, yend, 0, 1, format, result); } return ImageBuf::get_pixels (xbegin, xend, ybegin, yend, 0, 1, format, result); } bool auto_subimage (void) const { return m_auto_subimage; } void auto_subimage (bool v) { m_auto_subimage = v; } private: ImageBuf m_corrected_image; ///< Colorspace/gamma/exposure corrected image. char *m_thumbnail; ///< Thumbnail image bool m_thumbnail_valid; ///< Thumbnail is valid float m_gamma; ///< Gamma correction of this image float m_exposure; ///< Exposure gain of this image, in stops TypeDesc m_file_dataformat; ///< TypeDesc of the image on disk (not in ram) mutable std::string m_shortinfo; mutable std::string m_longinfo; bool m_image_valid; ///< Image is valid and pixels can be read. bool m_auto_subimage; ///< Automatically use subimages when zooming-in/out. }; class ImageViewer : public QMainWindow { Q_OBJECT public: ImageViewer(); ~ImageViewer(); enum COLOR_MODE { RGBA = 0, RGB = 1, SINGLE_CHANNEL = 2, LUMINANCE = 3, HEATMAP = 4 }; /// Tell the viewer about an image, but don't load it yet. void add_image (const std::string &filename); /// View this image. /// void current_image (int newimage); /// Which image index are we viewing? /// int current_image (void) const { return m_current_image; } /// View slide show (cycle through images with timed interval) /// void slide (long t, bool b); /// View a particular channel /// void viewChannel (int channel, COLOR_MODE colormode); /// Which channel are we viewing? /// int current_channel (void) const { return m_current_channel; } /// In what color mode are we? /// COLOR_MODE current_color_mode (void) const { return m_color_mode; } /// Return the current zoom level. 1.0 == 1:1 pixel ratio. Positive /// is a "zoom in" (closer/maxify), negative is zoom out (farther/minify). float zoom (void) const { return m_zoom; } /// Set a new view (zoom level and center position). If smooth is /// true, switch to the new view smoothly over many gradual steps, /// otherwise do it all in one step. The center position is measured /// in pixel coordinates. void view (float xcenter, float ycenter, float zoom, bool smooth=false, bool redraw=true); /// Set a new zoom level, keeping the center of view. If smooth is /// true, switch to the new zoom level smoothly over many gradual /// steps, otherwise do it all in one step. void zoom (float newzoom, bool smooth=false); /// Return a ptr to the current image, or NULL if there is no /// current image. IvImage *cur (void) const { if (m_images.empty()) return NULL; return m_current_image >= 0 ? m_images[m_current_image] : NULL; } /// Return a ref to the current image spec, or NULL if there is no /// current image. const ImageSpec *curspec (void) const { IvImage *img = cur(); return img ? &img->spec() : NULL; } bool pixelviewOn (void) const { return showPixelviewWindowAct && showPixelviewWindowAct->isChecked(); } bool pixelviewFollowsMouse (void) const { return pixelviewFollowsMouseBox && pixelviewFollowsMouseBox->isChecked(); } bool linearInterpolation (void) const { return linearInterpolationBox && linearInterpolationBox->isChecked(); } bool darkPalette (void) const { return darkPaletteBox ? darkPaletteBox->isChecked() : m_darkPalette; } QPalette palette (void) const { return m_palette; } private slots: void open(); ///< Dialog to open new image from file void reload(); ///< Reread current image from disk void openRecentFile(); ///< Open a recent file void closeImg(); ///< Close the current image void saveAs(); ///< Save As... functionality void saveWindowAs(); ///< Save As... functionality void saveSelectionAs(); ///< Save As... functionality void print(); ///< Print current image void deleteCurrentImage(); ///< Deleting displayed image void zoomIn(); ///< Zoom in to next power of 2 void zoomOut(); ///< Zoom out to next power of 2 void normalSize(); ///< Adjust zoom to 1:1 void fitImageToWindow(); ///< Adjust zoom to fit window exactly /// Resize window to fit image exactly. If zoomok is false, do not /// change the zoom, even to fit on screen. If minsize is true, do not /// resize smaller than default_width x default_height. void fitWindowToImage(bool zoomok=true, bool minsize=false); void fullScreenToggle(); ///< Toggle full screen mode void about(); ///< Show "about iv" dialog void prevImage(); ///< View previous image in sequence void nextImage(); ///< View next image in sequence void toggleImage(); ///< View most recently viewed image void exposureMinusOneTenthStop(); ///< Decrease exposure 1/10 stop void exposureMinusOneHalfStop(); ///< Decrease exposure 1/2 stop void exposurePlusOneTenthStop(); ///< Increase exposure 1/10 stop void exposurePlusOneHalfStop(); ///< Increase exposure 1/2 stop void gammaMinus(); ///< Decrease gamma 0.05 void gammaPlus(); ///< Increase gamma 0.05 void viewChannelFull(); ///< View RGB void viewChannelRed(); ///< View just red as gray void viewChannelGreen(); ///< View just green as gray void viewChannelBlue(); ///< View just blue as gray void viewChannelAlpha(); ///< View alpha as gray void viewChannelLuminance(); ///< View current 3 channels as luminance void viewChannelPrev(); ///< View just prev channel as gray void viewChannelNext(); ///< View just next channel as gray void viewColorRGBA(); ///< View current 4 channels as RGBA void viewColorRGB(); ///< View current 3 channels as RGB void viewColor1Ch(); ///< View current channel as gray void viewColorHeatmap(); ///< View current channel as heatmap. void viewSubimagePrev(); ///< View prev subimage void viewSubimageNext(); ///< View next subimage void sortByName(); ///< Sort images by Name. void sortByPath(); ///< Sort images based on full file path void sortByImageDate(); ///< Sort images by metadata date void sortByFileDate(); ///< Sort images by file Date Stamp. void sortReverse(); ///< Reverse the current order of images void slideShow(); ///< Starts slide show void slideLoop(); ///< Slide show in a loop void slideNoLoop(); ///< Slide show without loop void setSlideShowDuration(int seconds); ///< Set the slide show duration in seconds void slideImages(); ///< Slide show - move to next image void showInfoWindow(); ///< View extended info on image void showPixelviewWindow(); ///< View closeup pixel view void editPreferences(); ///< Edit viewer preferences private: void createActions (); void createMenus (); void createToolBars (); void createStatusBar (); void readSettings (bool ui_is_set_up=true); void writeSettings (); void updateActions (); void addRecentFile (const std::string &name); void removeRecentFile (const std::string &name); void updateRecentFilesMenu (); bool loadCurrentImage (int subimage = 0, int miplevel = 0); void displayCurrentImage (bool update = true); void updateTitle (); void updateStatusBar (); void keyPressEvent (QKeyEvent *event); void resizeEvent (QResizeEvent *event); void closeEvent (QCloseEvent *event); QTimer *slideTimer; ///< Timer to use for slide show mode long slideDuration_ms; ///< Slide show mode duration (in ms) bool slide_loop; ///< Do we loop when in slide mode? IvGL *glwin; IvInfoWindow *infoWindow; IvPreferenceWindow *preferenceWindow; #ifndef QT_NO_PRINTER QPrinter printer; #endif QAction *openAct, *reloadAct, *closeImgAct; static const unsigned int MaxRecentFiles = 10; QAction *openRecentAct[MaxRecentFiles]; QAction *saveAsAct, *saveWindowAsAct, *saveSelectionAsAct; QAction *printAct; QAction *deleteCurrentImageAct; QAction *exitAct; QAction *gammaPlusAct, *gammaMinusAct; QAction *exposurePlusOneTenthStopAct, *exposurePlusOneHalfStopAct; QAction *exposureMinusOneTenthStopAct, *exposureMinusOneHalfStopAct; QAction *viewChannelFullAct, *viewChannelRedAct, *viewChannelGreenAct; QAction *viewChannelBlueAct, *viewChannelAlphaAct; QAction *viewChannelPrevAct, *viewChannelNextAct; QAction *viewColorRGBAAct, *viewColorRGBAct, *viewColor1ChAct; QAction *viewColorLumAct, *viewColorHeatmapAct; QAction *viewSubimagePrevAct, *viewSubimageNextAct; QAction *zoomInAct; QAction *zoomOutAct; QAction *normalSizeAct; QAction *fitWindowToImageAct, *fitImageToWindowAct; QAction *fullScreenAct; QAction *aboutAct; QAction *nextImageAct, *prevImageAct, *toggleImageAct; QAction *sortByNameAct, *sortByPathAct, *sortReverseAct; QAction *sortByImageDateAct, *sortByFileDateAct; QAction *slideShowAct, *slideLoopAct, *slideNoLoopAct; QAction *showInfoWindowAct; QAction *editPreferencesAct; QAction *showPixelviewWindowAct; QMenu *fileMenu, *editMenu, /**imageMenu,*/ *viewMenu, *toolsMenu, *helpMenu; QMenu *openRecentMenu; QMenu *expgamMenu, *channelMenu, *colormodeMenu, *slideMenu, *sortMenu; QLabel *statusImgInfo, *statusViewInfo; QProgressBar *statusProgress; QComboBox *mouseModeComboBox; enum MouseMode { MouseModeZoom, MouseModePan, MouseModeWipe, MouseModeSelect, MouseModeAnnotate }; QCheckBox *pixelviewFollowsMouseBox; QCheckBox *linearInterpolationBox; QCheckBox *darkPaletteBox; QCheckBox *autoMipmap; QLabel *maxMemoryICLabel; QSpinBox *maxMemoryIC; QLabel *slideShowDurationLabel; QSpinBox *slideShowDuration; std::vector m_images; ///< List of images int m_current_image; ///< Index of current image, -1 if none int m_current_channel; ///< Channel we're viewing. COLOR_MODE m_color_mode; ///< How to show the current channel(s). int m_last_image; ///< Last image we viewed float m_zoom; ///< Zoom amount (positive maxifies) bool m_fullscreen; ///< Full screen mode std::vector m_recent_files; ///< Recently opened files float m_default_gamma; ///< Default gamma of the display QPalette m_palette; ///< Custom palette bool m_darkPalette; ///< Use dark palette? static const int m_default_width = 640; ///< The default width of the window. static const int m_default_height = 480; ///< The default height of the window. // What zoom do we need to fit these window dimensions? float zoom_needed_to_fit (int w, int h); friend class IvCanvas; friend class IvGL; friend class IvInfoWindow; friend class IvPreferenceWindow; friend bool image_progress_callback (void *opaque, float done); }; class IvInfoWindow : public QDialog { Q_OBJECT public: IvInfoWindow (ImageViewer &viewer, bool visible=true); void update (IvImage *img); protected: void keyPressEvent (QKeyEvent *event); private: QPushButton *closeButton; QScrollArea *scrollArea; QLabel *infoLabel; ImageViewer &m_viewer; bool m_visible; }; class IvPreferenceWindow : public QDialog { Q_OBJECT public: IvPreferenceWindow (ImageViewer &viewer); protected: void keyPressEvent (QKeyEvent *event); private: QVBoxLayout *layout; QPushButton *closeButton; ImageViewer &m_viewer; }; #endif // OPENIMAGEIO_IMAGEVIEWER_H openimageio-1.3.12~dfsg0.orig/src/iv/ivinfowin.cpp0000644000175000017500000000661312271062644020250 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include "imageviewer.h" #include "dassert.h" #include "strutil.h" IvInfoWindow::IvInfoWindow (ImageViewer &viewer, bool visible) : QDialog(&viewer), m_viewer(viewer), m_visible (visible) { infoLabel = new QLabel; infoLabel->setPalette (viewer.palette()); scrollArea = new QScrollArea; scrollArea->setPalette (viewer.palette()); scrollArea->setWidgetResizable (true); scrollArea->setWidget (infoLabel); scrollArea->setSizePolicy (QSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding, QSizePolicy::Label)); scrollArea->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); scrollArea->setFrameStyle (QFrame::NoFrame); scrollArea->setAlignment (Qt::AlignTop); closeButton = new QPushButton (tr("Close")); connect (closeButton, SIGNAL(clicked()), this, SLOT(hide())); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget (scrollArea); mainLayout->addWidget (closeButton); setLayout (mainLayout); infoLabel->show(); scrollArea->show(); setWindowTitle (tr("Image Info")); } void IvInfoWindow::update (IvImage *img) { std::string newtitle; if (img) { newtitle = Strutil::format ("%s - iv Info", img->name().c_str()); infoLabel->setText (img->longinfo().c_str()); } else { newtitle = Strutil::format ("iv Info"); infoLabel->setText (tr("No image loaded.")); } setWindowTitle (newtitle.c_str()); } void IvInfoWindow::keyPressEvent (QKeyEvent *event) { if (event->key() == Qt::Key_W && (event->modifiers() & Qt::ControlModifier)) { event->accept(); hide(); } else { event->ignore(); } } openimageio-1.3.12~dfsg0.orig/src/iv/ivmain.cpp0000644000175000017500000001131112271062644017512 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #if defined(_MSC_VER) // Ignore warnings about conditional expressions that always evaluate true // on a given platform but may evaluate differently on another. There's // nothing wrong with such conditionals. // Also ignore warnings about not being able to generate default assignment // operators for some Qt classes included in headers below. # pragma warning (disable : 4127 4512) #endif #include #include #include #include #include #include #include #include #include "imageio.h" #include "imageviewer.h" #include "timer.h" #include "argparse.h" #include "sysutil.h" #include "strutil.h" #include "imagecache.h" #include "filesystem.h" OIIO_NAMESPACE_USING; static bool verbose = false; static bool foreground_mode = false; static std::vector filenames; static int parse_files (int argc, const char *argv[]) { for (int i = 0; i < argc; i++) filenames.push_back (argv[i]); return 0; } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap; ap.options ("iv -- image viewer\n" OIIO_INTRO_STRING "\n" "Usage: iv [options] [filename...]", "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose status messages", "-F", &foreground_mode, "Foreground mode", NULL); if (ap.parse (argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } } #ifdef WIN32 // if we are not in DEBUG mode this code switch the app to // full windowed mode (no console and no need to define WinMain) // FIXME: this should be done in CMakeLists.txt but first we have to // fix Windows Debug build # ifdef NDEBUG # pragma comment(linker, "/subsystem:windows /entry:mainCRTStartup") # endif #endif int main (int argc, char *argv[]) { Filesystem::convert_native_arguments (argc, (const char **)argv); getargs (argc, argv); if (! foreground_mode) Sysutil::put_in_background (argc, argv); // LG // Q_INIT_RESOURCE(iv); QApplication app(argc, argv); ImageViewer *mainWin = new ImageViewer; mainWin->show(); // Set up the imagecache with parameters that make sense for iv ImageCache *imagecache = ImageCache::create (true); imagecache->attribute ("autotile", 256); // Make sure we are the top window with the focus. mainWin->raise (); mainWin->activateWindow (); // Add the images BOOST_FOREACH (const std::string &s, filenames) { mainWin->add_image (s); } mainWin->current_image (0); int r = app.exec(); // OK to clean up here #ifdef NDEBUG if (verbose) #endif { size_t mem = Sysutil::memory_used (true); std::cout << "iv total memory used: " << Strutil::memformat (mem) << "\n"; std::cout << "\n"; std::cout << imagecache->getstats (1+verbose) << "\n"; } return r; } openimageio-1.3.12~dfsg0.orig/src/iv/CMakeLists.txt0000644000175000017500000000276612271062644020301 0ustar mfvmfvif (QT4_FOUND AND OPENGL_FOUND AND GLEW_FOUND) include (${QT_USE_FILE}) include_directories (${QT_INCLUDES} ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDES}) add_custom_command (OUTPUT "${CMAKE_BINARY_DIR}/src/iv/moc_imageviewer.cpp" DEPENDS imageviewer.h imageviewer.cpp COMMAND ${QT_MOC_EXECUTABLE} ARGS "${PROJECT_SOURCE_DIR}/src/iv/imageviewer.h" -o "${CMAKE_BINARY_DIR}/src/iv/moc_imageviewer.cpp" ) add_custom_command (OUTPUT ${CMAKE_BINARY_DIR}/src/iv/moc_ivgl.cpp DEPENDS ivgl.h ivgl.cpp COMMAND ${QT_MOC_EXECUTABLE} ARGS "${PROJECT_SOURCE_DIR}/src/iv/ivgl.h" -o "${CMAKE_BINARY_DIR}/src/iv/moc_ivgl.cpp" ) set (iv_srcs imageviewer.cpp ivimage.cpp ivgl.cpp ivinfowin.cpp ivpref.cpp ivmain.cpp moc_imageviewer.cpp moc_ivgl.cpp) if (FORCE_OPENGL_1) add_definitions(-DFORCE_OPENGL_1) endif() add_executable (iv ${iv_srcs}) set_target_properties (iv PROPERTIES FOLDER "Tools") link_ilmbase (iv) target_link_libraries (iv OpenImageIO ${QT_LIBRARIES} ${OPENGL_LIBRARIES} ${Boost_LIBRARIES} ${CMAKE_DL_LIBS} ${GLEW_LIBRARIES}) oiio_install_targets (iv) else () message (STATUS "\n\n WARNING: No QT/OpenGL -- 'iv' will not be built!\n") endif () openimageio-1.3.12~dfsg0.orig/src/oiiotool/0000755000175000017500000000000012271062644016745 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/oiiotool/imagerec.cpp0000644000175000017500000002442712271062644021236 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #include #include using boost::algorithm::iequals; #include "argparse.h" #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "sysutil.h" #include "filesystem.h" #include "filter.h" #include "oiiotool.h" OIIO_NAMESPACE_USING using namespace OiioTool; using namespace ImageBufAlgo; ImageRec::ImageRec (const std::string &name, int nsubimages, const int *miplevels, const ImageSpec *specs) : m_name(name), m_elaborated(true), m_metadata_modified(false), m_pixels_modified(true), m_imagecache(NULL) { int specnum = 0; m_subimages.resize (nsubimages); for (int s = 0; s < nsubimages; ++s) { int nmips = miplevels ? miplevels[s] : 1; m_subimages[s].m_miplevels.resize (nmips); m_subimages[s].m_specs.resize (nmips); for (int m = 0; m < nmips; ++m) { ImageBuf *ib = specs ? new ImageBuf (specs[specnum]) : new ImageBuf (); m_subimages[s].m_miplevels[m].reset (ib); if (specs) m_subimages[s].m_specs[m] = specs[specnum]; ++specnum; } } } ImageRec::ImageRec (ImageRec &img, int subimage_to_copy, int miplevel_to_copy, bool writable, bool copy_pixels) : m_name(img.name()), m_elaborated(true), m_metadata_modified(false), m_pixels_modified(false), m_imagecache(img.m_imagecache) { img.read (); int first_subimage = std::max (0, subimage_to_copy); int subimages = (subimage_to_copy < 0) ? img.subimages() : 1; m_subimages.resize (subimages); for (int s = 0; s < subimages; ++s) { int srcsub = s + first_subimage; int first_miplevel = std::max (0, miplevel_to_copy); int miplevels = (miplevel_to_copy < 0) ? img.miplevels(srcsub) : 1; m_subimages[s].m_miplevels.resize (miplevels); m_subimages[s].m_specs.resize (miplevels); for (int m = 0; m < miplevels; ++m) { int srcmip = m + first_miplevel; const ImageBuf &srcib (img(srcsub,srcmip)); const ImageSpec &srcspec (*img.spec(srcsub,srcmip)); ImageBuf *ib = NULL; if (writable || img.pixels_modified() || !copy_pixels) { // Make our own copy of the pixels ib = new ImageBuf (srcspec); if (copy_pixels) ib->copy_pixels (srcib); } else { // The other image is not modified, and we don't need to be // writable, either. ib = new ImageBuf (img.name(), srcib.imagecache()); bool ok = ib->read (srcsub, srcmip); ASSERT (ok); } m_subimages[s].m_miplevels[m].reset (ib); m_subimages[s].m_specs[m] = srcspec; } } } ImageRec::ImageRec (ImageRec &A, ImageRec &B, int subimage_to_copy, WinMerge pixwin, WinMerge fullwin, TypeDesc pixeltype) : m_name(A.name()), m_elaborated(true), m_metadata_modified(false), m_pixels_modified(false), m_imagecache(A.m_imagecache) { A.read (); B.read (); int subimages = (subimage_to_copy < 0) ? std::min(A.subimages(), B.subimages()) : 1; int first_subimage = clamp (subimage_to_copy, 0, subimages-1); m_subimages.resize (subimages); for (int s = 0; s < subimages; ++s) { int srcsub = s + first_subimage; m_subimages[s].m_miplevels.resize (1); m_subimages[s].m_specs.resize (1); const ImageBuf &Aib (A(srcsub)); const ImageBuf &Bib (B(srcsub)); const ImageSpec &Aspec (Aib.spec()); const ImageSpec &Bspec (Bib.spec()); ImageSpec spec = Aspec; ROI Aroi = get_roi (Aspec), Aroi_full = get_roi_full (Aspec); ROI Broi = get_roi (Bspec), Broi_full = get_roi_full (Bspec); switch (pixwin) { case WinMergeUnion : set_roi (spec, roi_union (Aroi, Broi)); break; case WinMergeIntersection : set_roi (spec, roi_intersection (Aroi, Broi)); break; case WinMergeA : set_roi (spec, Aroi); break; case WinMergeB : set_roi (spec, Broi); break; } switch (fullwin) { case WinMergeUnion : set_roi_full (spec, roi_union (Aroi_full, Broi_full)); break; case WinMergeIntersection : set_roi_full (spec, roi_intersection (Aroi_full, Broi_full)); break; case WinMergeA : set_roi_full (spec, Aroi_full); break; case WinMergeB : set_roi_full (spec, Broi_full); break; } if (pixeltype != TypeDesc::UNKNOWN) spec.set_format (pixeltype); spec.nchannels = std::min (Aspec.nchannels, Bspec.nchannels); spec.channelnames.resize (spec.nchannels); spec.channelformats.clear (); ImageBuf *ib = new ImageBuf (spec); m_subimages[s].m_miplevels[0].reset (ib); m_subimages[s].m_specs[0] = spec; } } ImageRec::ImageRec (ImageBufRef img, bool copy_pixels) : m_name(img->name()), m_elaborated(true), m_metadata_modified(false), m_pixels_modified(false), m_imagecache(img->imagecache()) { m_subimages.resize (1); m_subimages[0].m_miplevels.resize (1); m_subimages[0].m_specs.push_back (img->spec()); if (copy_pixels) { m_subimages[0].m_miplevels[0].reset (new ImageBuf (*img)); } else { m_subimages[0].m_miplevels[0] = img; } } ImageRec::ImageRec (const std::string &name, const ImageSpec &spec, ImageCache *imagecache) : m_name(name), m_elaborated(true), m_metadata_modified(false), m_pixels_modified(true), m_imagecache(imagecache) { int subimages = 1; m_subimages.resize (subimages); for (int s = 0; s < subimages; ++s) { int miplevels = 1; m_subimages[s].m_miplevels.resize (miplevels); m_subimages[s].m_specs.resize (miplevels); for (int m = 0; m < miplevels; ++m) { ImageBuf *ib = new ImageBuf (spec); m_subimages[s].m_miplevels[m].reset (ib); m_subimages[s].m_specs[m] = spec; } } } bool ImageRec::read () { if (elaborated()) return true; static ustring u_subimages("subimages"), u_miplevels("miplevels"); int subimages = 0; ustring uname (name()); if (! m_imagecache->get_image_info (uname, 0, 0, u_subimages, TypeDesc::TypeInt, &subimages)) { std::cerr << "ERROR: file \"" << name() << "\" not found.\n"; return false; // Image not found } m_subimages.resize (subimages); bool allok = true; for (int s = 0; s < subimages; ++s) { int miplevels = 0; m_imagecache->get_image_info (uname, s, 0, u_miplevels, TypeDesc::TypeInt, &miplevels); m_subimages[s].m_miplevels.resize (miplevels); m_subimages[s].m_specs.resize (miplevels); for (int m = 0; m < miplevels; ++m) { // Force a read now for reasonable-sized first images in the // file. This can greatly speed up the multithread case for // tiled images by not having multiple threads working on the // same image lock against each other on the file handle. // We guess that "reasonable size" is 50 MB, that's enough to // hold a 2048x1536 RGBA float image. Larger things will // simply fall back on ImageCache. bool forceread = (s == 0 && m == 0 && m_imagecache->imagespec(uname,s,m)->image_bytes() < 50*1024*1024); ImageBuf *ib = new ImageBuf (name(), m_imagecache); bool ok = ib->read (s, m, forceread, TypeDesc::FLOAT /* force float */); allok &= ok; m_subimages[s].m_miplevels[m].reset (ib); m_subimages[s].m_specs[m] = ib->spec(); // For ImageRec purposes, we need to restore a few of the // native settings. const ImageSpec &nativespec (ib->nativespec()); // m_subimages[s].m_specs[m].format = nativespec.format; m_subimages[s].m_specs[m].tile_width = nativespec.tile_width; m_subimages[s].m_specs[m].tile_height = nativespec.tile_height; m_subimages[s].m_specs[m].tile_depth = nativespec.tile_depth; } } m_time = Filesystem::last_write_time (name()); m_elaborated = true; return allok; } openimageio-1.3.12~dfsg0.orig/src/oiiotool/printinfo.cpp0000644000175000017500000006136612271062644021475 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include "argparse.h" #include "strutil.h" #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "hash.h" #include "oiiotool.h" #include "fmath.h" OIIO_NAMESPACE_USING; using namespace OiioTool; using namespace ImageBufAlgo; static void print_sha1 (ImageInput *input) { SHA1 sha; const ImageSpec &spec (input->spec()); if (spec.deep) { // Special handling of deep data DeepData dd; if (! input->read_native_deep_image (dd)) { printf (" SHA-1: unable to compute, could not read image\n"); return; } // Hash both the sample counts and the data block sha.appendvec (dd.nsamples); sha.appendvec (dd.data); } else { imagesize_t size = input->spec().image_bytes (true /*native*/); if (size >= std::numeric_limits::max()) { printf (" SHA-1: unable to compute, image is too big\n"); return; } else if (size != 0) { std::vector buf((size_t)size); if (! input->read_image (TypeDesc::UNKNOWN /*native*/, &buf[0])) { printf (" SHA-1: unable to compute, could not read image\n"); return; } sha.appendvec (buf); } } printf (" SHA-1: %s\n", sha.digest().c_str()); } static void dump_data (ImageInput *input) { const ImageSpec &spec (input->spec()); if (spec.deep) { // Special handling of deep data DeepData dd; if (! input->read_native_deep_image (dd)) { printf (" dump data: could not read image\n"); return; } int nc = spec.nchannels; TypeDesc *types = &dd.channeltypes[0]; for (int z = 0, pixel = 0; z < spec.depth; ++z) { for (int y = 0; y < spec.height; ++y) { for (int x = 0; x < spec.width; ++x, ++pixel) { int nsamples = dd.nsamples[pixel]; std::cout << " Pixel ("; if (spec.depth > 1 || spec.z != 0) std::cout << Strutil::format("%d, %d, %d", x+spec.x, y+spec.y, z+spec.z); else std::cout << Strutil::format("%d, %d", x+spec.x, y+spec.y); std::cout << "): " << nsamples << " samples" << (nsamples ? ":" : ""); for (int s = 0; s < nsamples; ++s) { if (s) std::cout << " / "; for (int c = 0; c < nc; ++c) { std::cout << " " << spec.channelnames[c] << "="; const char *ptr = (const char *)dd.pointers[pixel*nc+c]; TypeDesc t = types[c]; ptr += s * t.size(); if (t.basetype == TypeDesc::FLOAT) { std::cout << *(const float *)ptr; } else if (t.basetype == TypeDesc::HALF) { std::cout << *(const half *)ptr; } else if (t.basetype == TypeDesc::UINT) { std::cout << *(const unsigned int *)ptr; } } } std::cout << "\n"; } } } } else { std::vector buf(spec.image_pixels() * spec.nchannels); if (! input->read_image (TypeDesc::UNKNOWN /*native*/, &buf[0])) { printf (" dump data: could not read image\n"); return; } const float *ptr = &buf[0]; for (int z = 0; z < spec.depth; ++z) { for (int y = 0; y < spec.height; ++y) { for (int x = 0; x < spec.width; ++x) { if (spec.depth > 1 || spec.z != 0) std::cout << Strutil::format(" Pixel (%d, %d, %d):", x+spec.x, y+spec.y, z+spec.z); else std::cout << Strutil::format(" Pixel (%d, %d):", x+spec.x, y+spec.y); for (int c = 0; c < spec.nchannels; ++c, ++ptr) { std::cout << ' ' << (*ptr); } std::cout << "\n"; } } } } } /////////////////////////////////////////////////////////////////////////////// // Stats static bool read_input (const std::string &filename, ImageBuf &img, int subimage=0, int miplevel=0) { if (img.subimage() >= 0 && img.subimage() == subimage) return true; if (img.init_spec (filename, subimage, miplevel) && img.read (subimage, miplevel, false, TypeDesc::FLOAT)) return true; std::cerr << "oiiotool ERROR: Could not read " << filename << ":\n\t" << img.geterror() << "\n"; return false; } static void print_stats_num (float val, int maxval, bool round) { // Ensure uniform printing of NaN and Inf on all platforms if (isnan(val)) printf ("nan"); else if (isinf(val)) printf ("inf"); else if (maxval == 0) { printf("%f",val); } else { float fval = val * static_cast(maxval); if (round) { int v = static_cast(roundf (fval)); printf ("%d", v); } else { printf ("%0.2f", fval); } } } // First check oiio:BitsPerSample int attribute. If not set, // fall back on the TypeDesc. return 0 for float types // or those that exceed the int range (long long, etc) static unsigned long long get_intsample_maxval (const ImageSpec &spec) { TypeDesc type = spec.format; int bits = spec.get_int_attribute ("oiio:BitsPerSample"); if (bits > 0) { if (type.basetype == TypeDesc::UINT8 || type.basetype == TypeDesc::UINT16 || type.basetype == TypeDesc::UINT32) return ((1LL) << bits) - 1; if (type.basetype == TypeDesc::INT8 || type.basetype == TypeDesc::INT16 || type.basetype == TypeDesc::INT32) return ((1LL) << (bits-1)) - 1; } // These correspond to all the int enums in typedesc.h <= int if (type.basetype == TypeDesc::UCHAR) return 0xff; if (type.basetype == TypeDesc::CHAR) return 0x7f; if (type.basetype == TypeDesc::USHORT) return 0xffff; if (type.basetype == TypeDesc::SHORT) return 0x7fff; if (type.basetype == TypeDesc::UINT) return 0xffffffff; if (type.basetype == TypeDesc::INT) return 0x7fffffff; return 0; } static void print_stats_footer (unsigned int maxval) { if (maxval==0) printf ("(float)"); else printf ("(of %u)", maxval); } static void print_stats (const std::string &filename, const ImageSpec &originalspec, int subimage=0, int miplevel=0, bool indentmip=false) { const char *indent = indentmip ? " " : " "; ImageBuf input; if (! read_input (filename, input, subimage, miplevel)) { std::cerr << "Stats: read error: " << input.geterror() << "\n"; return; } PixelStats stats; if (! computePixelStats (stats, input)) { printf ("%sStats: (unable to compute)\n", indent); return; } // The original spec is used, otherwise the bit depth will // be reported incorrectly (as FLOAT) unsigned int maxval = (unsigned int)get_intsample_maxval (originalspec); printf ("%sStats Min: ", indent); for (unsigned int i=0; insamples.size(); size_t totalsamples = 0, emptypixels = 0; size_t maxsamples = 0, minsamples = std::numeric_limits::max(); for (size_t p = 0; p < npixels; ++p) { size_t c = size_t(dd->nsamples[p]); totalsamples += c; if (c > maxsamples) maxsamples = c; if (c < minsamples) minsamples = c; if (c == 0) ++emptypixels; } printf ("%sMin deep samples in any pixel : %llu\n", indent, (unsigned long long)minsamples); printf ("%sMax deep samples in any pixel : %llu\n", indent, (unsigned long long)maxsamples); printf ("%sAverage deep samples per pixel: %.2f\n", indent, double(totalsamples)/double(npixels)); printf ("%sTotal deep samples in all pixels: %llu\n", indent, (unsigned long long)totalsamples); printf ("%sPixels with deep samples : %llu\n", indent, (unsigned long long)(npixels-emptypixels)); printf ("%sPixels with no deep samples: %llu\n", indent, (unsigned long long)emptypixels); } else { std::vector constantValues(input.spec().nchannels); if (isConstantColor(input, &constantValues[0])) { printf ("%sConstant: Yes\n", indent); printf ("%sConstant Color: ", indent); for (unsigned int i=0; i 1) printf (", z=%d", spec.z); printf ("\n"); printed = true; } } if (spec.full_x || spec.full_y || spec.full_z || (spec.full_width != spec.width && spec.full_width != 0) || (spec.full_height != spec.height && spec.full_height != 0) || (spec.full_depth != spec.depth && spec.full_depth != 0)) { if (opt.metamatch.empty() || boost::regex_search ("full/display size", field_re)) { if (opt.filenameprefix) printf ("%s : ", filename.c_str()); printf (" full/display size: %d x %d", spec.full_width, spec.full_height); if (spec.depth > 1) printf (" x %d", spec.full_depth); printf ("\n"); printed = true; } if (opt.metamatch.empty() || boost::regex_search ("full/display origin", field_re)) { if (opt.filenameprefix) printf ("%s : ", filename.c_str()); printf (" full/display origin: %d, %d", spec.full_x, spec.full_y); if (spec.depth > 1) printf (", %d", spec.full_z); printf ("\n"); printed = true; } } if (spec.tile_width) { if (opt.metamatch.empty() || boost::regex_search ("tile", field_re)) { if (opt.filenameprefix) printf ("%s : ", filename.c_str()); printf (" tile size: %d x %d", spec.tile_width, spec.tile_height); if (spec.depth > 1) printf (" x %d", spec.tile_depth); printf ("\n"); printed = true; } } BOOST_FOREACH (const ImageIOParameter &p, spec.extra_attribs) { if (! opt.metamatch.empty() && ! boost::regex_search (p.name().c_str(), field_re)) continue; if (! opt.nometamatch.empty() && boost::regex_search (p.name().c_str(), field_exclude_re)) continue; std::string s = spec.metadata_val (p, true); if (opt.filenameprefix) printf ("%s : ", filename.c_str()); printf (" %s: ", p.name().c_str()); if (! strcmp (s.c_str(), "1.#INF")) printf ("inf"); else printf ("%s", s.c_str()); printf ("\n"); printed = true; } if (! printed && !opt.metamatch.empty()) { if (opt.filenameprefix) printf ("%s : ", filename.c_str()); printf (" %s: \n", opt.metamatch.c_str()); } } static const char * extended_format_name (TypeDesc type, int bits) { if (bits && bits < (int)type.size()*8) { // The "oiio:BitsPerSample" betrays a different bit depth in the // file than the data type we are passing. if (type == TypeDesc::UINT8 || type == TypeDesc::UINT16 || type == TypeDesc::UINT32 || type == TypeDesc::UINT64) return ustring::format("uint%d", bits).c_str(); if (type == TypeDesc::INT8 || type == TypeDesc::INT16 || type == TypeDesc::INT32 || type == TypeDesc::INT64) return ustring::format("int%d", bits).c_str(); } return type.c_str(); // use the name implied by type } // prints basic info (resolution, width, height, depth, channels, data format, // and format name) about given subimage. static void print_info_subimage (int current_subimage, int max_subimages, ImageSpec &spec, ImageInput *input, const std::string &filename, const print_info_options &opt, boost::regex &field_re, boost::regex &field_exclude_re) { if ( ! input->seek_subimage (current_subimage, 0, spec) ) return; int nmip = 1; bool printres = opt.verbose && (opt.metamatch.empty() || boost::regex_search ("resolution, width, height, depth, channels", field_re)); if (printres && max_subimages > 1 && opt.subimages) { printf (" subimage %2d: ", current_subimage); printf ("%4d x %4d", spec.width, spec.height); if (spec.depth > 1) printf (" x %4d", spec.depth); int bits = spec.get_int_attribute ("oiio:BitsPerSample", 0); printf (", %d channel, %s%s", spec.nchannels, extended_format_name(spec.format, bits), spec.depth > 1 ? " volume" : ""); printf (" %s", input->format_name()); printf ("\n"); } // Count MIP levels ImageSpec mipspec; while (input->seek_subimage (current_subimage, nmip, mipspec)) { if (printres) { if (nmip == 1) printf (" MIP-map levels: %dx%d", spec.width, spec.height); printf (" %dx%d", mipspec.width, mipspec.height); } ++nmip; } if (printres && nmip > 1) printf ("\n"); if (opt.compute_sha1 && (opt.metamatch.empty() || boost::regex_search ("sha-1", field_re))) { if (opt.filenameprefix) printf ("%s : ", filename.c_str()); // Before sha-1, be sure to point back to the highest-res MIP level ImageSpec tmpspec; input->seek_subimage (current_subimage, 0, tmpspec); print_sha1 (input); } if (opt.verbose) print_metadata (spec, filename, opt, field_re, field_exclude_re); if (opt.dumpdata) { ImageSpec tmp; input->seek_subimage (current_subimage, 0, tmp); dump_data (input); } if (opt.compute_stats && (opt.metamatch.empty() || boost::regex_search ("stats", field_re))) { for (int m = 0; m < nmip; ++m) { ImageSpec mipspec; input->seek_subimage (current_subimage, m, mipspec); if (opt.filenameprefix) printf ("%s : ", filename.c_str()); if (nmip > 1) { printf (" MIP %d of %d (%d x %d):\n", m, nmip, mipspec.width, mipspec.height); } print_stats (filename, spec, current_subimage, m, nmip>1); } } if ( ! input->seek_subimage (current_subimage, 0, spec) ) return; } bool OiioTool::print_info (const std::string &filename, const print_info_options &opt, long long &totalsize, std::string &error) { error.clear(); ImageInput *input = ImageInput::open (filename.c_str()); if (! input) { error = geterror(); if (error.empty()) error = Strutil::format ("Could not open \"%s\"", filename.c_str()); return false; } ImageSpec spec = input->spec(); boost::regex field_re; boost::regex field_exclude_re; if (! opt.metamatch.empty()) { try { field_re.assign (opt.metamatch, boost::regex::extended | boost::regex_constants::icase); } catch (const std::exception &e) { error = Strutil::format ("Regex error '%s' on metamatch regex \"%s\"", e.what(), opt.metamatch); return false; } } if (! opt.nometamatch.empty()) { try { field_exclude_re.assign (opt.nometamatch, boost::regex::extended | boost::regex_constants::icase); } catch (const std::exception &e) { error = Strutil::format ("Regex error '%s' on metamatch regex \"%s\"", e.what(), opt.nometamatch); return false; } } int padlen = std::max (0, (int)opt.namefieldlength - (int)filename.length()); std::string padding (padlen, ' '); // checking how many subimages and mipmap levels are stored in the file int num_of_subimages = 1; bool any_mipmapping = false; std::vector num_of_miplevels; { int nmip = 1; while (input->seek_subimage (input->current_subimage(), nmip, spec)) { ++nmip; any_mipmapping = true; } num_of_miplevels.push_back (nmip); } while (input->seek_subimage (num_of_subimages, 0, spec)) { // maybe we should do this more gently? ++num_of_subimages; int nmip = 1; while (input->seek_subimage (input->current_subimage(), nmip, spec)) { ++nmip; any_mipmapping = true; } num_of_miplevels.push_back (nmip); } input->seek_subimage (0, 0, spec); // re-seek to the first if (opt.metamatch.empty() || boost::regex_search ("resolution, width, height, depth, channels", field_re)) { printf ("%s%s : %4d x %4d", filename.c_str(), padding.c_str(), spec.width, spec.height); if (spec.depth > 1) printf (" x %4d", spec.depth); printf (", %d channel, ", spec.nchannels); if (spec.channelformats.size()) { for (size_t c = 0; c < spec.channelformats.size(); ++c) printf ("%s%s", c ? "/" : "", spec.channelformats[c].c_str()); } else { int bits = spec.get_int_attribute ("oiio:BitsPerSample", 0); printf ("%s", extended_format_name(spec.format, bits)); } if (spec.depth > 1) printf (" volume"); printf (" %s", input->format_name()); if (opt.sum) { imagesize_t imagebytes = spec.image_bytes (true); totalsize += imagebytes; printf (" (%.2f MB)", (float)imagebytes / (1024.0*1024.0)); } // we print info about how many subimages are stored in file // only when we have more then one subimage if ( ! opt.verbose && num_of_subimages != 1) printf (" (%d subimages%s)", num_of_subimages, any_mipmapping ? " +mipmap)" : ""); if (! opt.verbose && num_of_subimages == 1 && any_mipmapping) printf (" (+mipmap)"); printf ("\n"); } if (opt.verbose && num_of_subimages != 1) { // info about num of subimages and their resolutions printf (" %d subimages: ", num_of_subimages); for (int i = 0; i < num_of_subimages; ++i) { input->seek_subimage (i, 0, spec); if (spec.depth > 1) printf ("%dx%dx%d ", spec.width, spec.height, spec.depth); else printf ("%dx%d ", spec.width, spec.height); } printf ("\n"); } // if the '-a' flag is not set we print info // about first subimage only if ( ! opt.subimages) num_of_subimages = 1; for (int i = 0; i < num_of_subimages; ++i) { print_info_subimage (i, num_of_subimages, spec, input, filename, opt, field_re, field_exclude_re); } input->close (); delete input; return true; } openimageio-1.3.12~dfsg0.orig/src/oiiotool/CMakeLists.txt0000644000175000017500000000046412271062644021511 0ustar mfvmfvset (oiiotool_srcs oiiotool.cpp diff.cpp imagerec.cpp printinfo.cpp) add_executable (oiiotool ${oiiotool_srcs}) set_target_properties (oiiotool PROPERTIES FOLDER "Tools") link_ilmbase (oiiotool) target_link_libraries (oiiotool OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) oiio_install_targets (oiiotool) openimageio-1.3.12~dfsg0.orig/src/oiiotool/diff.cpp0000644000175000017500000002274012271062644020366 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #include #include using boost::algorithm::iequals; #include "argparse.h" #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "sysutil.h" #include "filter.h" #include "oiiotool.h" OIIO_NAMESPACE_USING using namespace OiioTool; using namespace ImageBufAlgo; // function that standarize printing NaN and Inf values on // Windows (where they are in 1.#INF, 1.#NAN format) and all // others platform inline void safe_double_print (double val) { if (isnan (val)) std::cout << "nan"; else if (isinf (val)) std::cout << "inf"; else std::cout << val; std::cout << '\n'; } inline void print_subimage (ImageRec &img0, int subimage, int miplevel) { if (img0.subimages() > 1) std::cout << "Subimage " << subimage << ' '; if (img0.miplevels(subimage) > 1) std::cout << " MIP level " << miplevel << ' '; if (img0.subimages() > 1 || img0.miplevels(subimage) > 1) std::cout << ": "; const ImageSpec &spec (*img0.spec(subimage)); std::cout << spec.width << " x " << spec.height; if (spec.depth > 1) std::cout << " x " << spec.depth; std::cout << ", " << spec.nchannels << " channel\n"; } int OiioTool::do_action_diff (ImageRec &ir0, ImageRec &ir1, Oiiotool &ot) { std::cout << "Computing diff of \"" << ir0.name() << "\" vs \"" << ir1.name() << "\"\n"; ir0.read (); ir1.read (); int ret = DiffErrOK; for (int subimage = 0; subimage < ir0.subimages(); ++subimage) { if (subimage > 0 && !ot.allsubimages) break; if (subimage >= ir1.subimages()) break; if (ir0.miplevels(subimage) != ir1.miplevels(subimage)) { std::cout << "Files do not match in their number of MIPmap levels\n"; } for (int m = 0; m < ir0.miplevels(subimage); ++m) { if (m > 0 && !ot.allsubimages) break; if (m > 0 && ir0.miplevels(subimage) != ir1.miplevels(subimage)) { std::cout << "Files do not match in their number of MIPmap levels\n"; ret = DiffErrDifferentSize; break; } ImageBuf &img0 (ir0(subimage,m)); ImageBuf &img1 (ir1(subimage,m)); int npels = img0.spec().width * img0.spec().height * img0.spec().depth; if (npels == 0) npels = 1; // Avoid divide by zero for 0x0 images ASSERT (img0.spec().format == TypeDesc::FLOAT); // Compare the two images. // ImageBufAlgo::CompareResults cr; ImageBufAlgo::compare (img0, img1, ot.diff_failthresh, ot.diff_warnthresh, cr); int yee_failures = 0; #if 0 if (perceptual) yee_failures = ImageBufAlgo::compare_Yee (img0, img1); #endif if (cr.nfail > (ot.diff_failpercent/100.0 * npels) || cr.maxerror > ot.diff_hardfail || yee_failures > (ot.diff_failpercent/100.0 * npels)) { ret = DiffErrFail; } else if (cr.nwarn > (ot.diff_warnpercent/100.0 * npels) || cr.maxerror > ot.diff_hardwarn) { if (ret != DiffErrFail) ret = DiffErrWarn; } // Print the report // if (ot.verbose || ret != DiffErrOK) { if (ot.allsubimages) print_subimage (ir0, subimage, m); std::cout << " Mean error = "; safe_double_print (cr.meanerror); std::cout << " RMS error = "; safe_double_print (cr.rms_error); std::cout << " Peak SNR = "; safe_double_print (cr.PSNR); std::cout << " Max error = " << cr.maxerror; if (cr.maxerror != 0) { std::cout << " @ (" << cr.maxx << ", " << cr.maxy; if (img0.spec().depth > 1) std::cout << ", " << cr.maxz; if (cr.maxc < (int)img0.spec().channelnames.size()) std::cout << ", " << img0.spec().channelnames[cr.maxc] << ')'; else if (cr.maxc < (int)img1.spec().channelnames.size()) std::cout << ", " << img1.spec().channelnames[cr.maxc] << ')'; else std::cout << ", channel " << cr.maxc << ')'; } std::cout << "\n"; std::streamsize precis = std::cout.precision(); std::cout << " " << cr.nwarn << " pixels (" << std::setprecision(3) << (100.0*cr.nwarn / npels) << std::setprecision(precis) << "%) over " << ot.diff_warnthresh << "\n"; std::cout << " " << cr.nfail << " pixels (" << std::setprecision(3) << (100.0*cr.nfail / npels) << std::setprecision(precis) << "%) over " << ot.diff_failthresh << "\n"; #if 0 if (perceptual) std::cout << " " << yee_failures << " pixels (" << std::setprecision(3) << (100.0*yee_failures / npels) << std::setprecision(precis) << "%) failed the perceptual test\n"; #endif } #if 0 // If the user requested that a difference image be output, // do that. N.B. we only do this for the first subimage // right now, because ImageBuf doesn't really know how to // write subimages. if (diffimage.size() && (cr.maxerror != 0 || !outdiffonly)) { ImageBuf diff (diffimage, img0.spec()); ImageBuf::ConstIterator pix0 (img0); ImageBuf::ConstIterator pix1 (img1); ImageBuf::Iterator pixdiff (diff); // Subtract the second image from the first. At which // time we no longer need the second image, so free it. if (diffabs) { for ( ; pix0.valid(); ++pix0) { pix1.pos (pix0.x(), pix0.y()); // ensure alignment pixdiff.pos (pix0.x(), pix0.y()); for (int c = 0; c < img0.nchannels(); ++c) pixdiff[c] = diffscale * fabsf (pix0[c] - pix1[c]); } } else { for ( ; pix0.valid(); ++pix0) { pix1.pos (pix0.x(), pix0.y()); // ensure alignment pixdiff.pos (pix0.x(), pix0.y()); for (int c = 0; c < img0.spec().nchannels; ++c) pixdiff[c] = diffscale * (pix0[c] - pix1[c]); } } diff.save (diffimage); // Clear diff image name so we only save the first // non-matching subimage. diffimage = ""; } #endif } } if (ot.allsubimages && ir0.subimages() != ir1.subimages()) { std::cout << "Images had differing numbers of subimages (" << ir0.subimages() << " vs " << ir1.subimages() << ")\n"; ret = DiffErrFail; } if (!ot.allsubimages && (ir0.subimages() > 1 || ir1.subimages() > 1)) { std::cout << "Only compared the first subimage (of " << ir0.subimages() << " and " << ir1.subimages() << ", respectively)\n"; } if (ret == DiffErrOK) std::cout << "PASS\n"; else if (ret == DiffErrWarn) std::cout << "WARNING\n"; else { std::cout << "FAILURE\n"; } return ret; } openimageio-1.3.12~dfsg0.orig/src/oiiotool/oiiotool.cpp0000644000175000017500000036150012271062644021313 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "argparse.h" #include "imageio.h" #include "imagebuf.h" #include "imagebufalgo.h" #include "sysutil.h" #include "filesystem.h" #include "filter.h" #include "color.h" #include "timer.h" #include "oiiotool.h" OIIO_NAMESPACE_USING using namespace OiioTool; using namespace ImageBufAlgo; static Oiiotool ot; Oiiotool::Oiiotool () : imagecache(NULL), return_value (EXIT_SUCCESS), total_readtime (false /*don't start timer*/), total_writetime (false /*don't start timer*/), total_imagecache_readtime (0.0), enable_function_timing(true) { clear_options (); } void Oiiotool::clear_options () { verbose = false; runstats = false; noclobber = false; allsubimages = false; printinfo = false; printstats = false; dumpdata = false; hash = false; updatemode = false; threads = 0; full_command_line.clear (); printinfo_metamatch.clear (); printinfo_nometamatch.clear (); output_dataformat = TypeDesc::UNKNOWN; output_channelformats.clear (); output_bitspersample = 0; output_scanline = false; output_tilewidth = 0; output_tileheight = 0; output_compression = ""; output_quality = -1; output_planarconfig = "default"; output_adjust_time = false; output_autocrop = true; output_autotrim = false; diff_warnthresh = 1.0e-6f; diff_warnpercent = 0; diff_hardwarn = std::numeric_limits::max(); diff_failthresh = 1.0e-6f; diff_failpercent = 0; diff_hardfail = std::numeric_limits::max(); m_pending_callback = NULL; m_pending_argc = 0; } std::string format_resolution (int w, int h, int x, int y) { return Strutil::format ("%dx%d%+d%+d", w, h, x, y); } std::string format_resolution (int w, int h, int d, int x, int y, int z) { return Strutil::format ("%dx%dx%d%+d%+d%+d", w, h, d, x, y, z); } // FIXME -- lots of things we skimped on so far: // FIXME: check binary ops for compatible image dimensions // FIXME: handle missing image // FIXME: reject volume images? // FIXME: do all ops respect -a (or lack thereof?) void Oiiotool::read (ImageRecRef img) { // If the image is already elaborated, take an early out, both to // save time, but also because we only want to do the format and // tile adjustments below as images are read in fresh from disk. if (img->elaborated()) return; // Cause the ImageRec to get read. Try to compute how long it took. // Subtract out ImageCache time, to avoid double-accounting it later. float pre_ic_time, post_ic_time; imagecache->getattribute ("stat:fileio_time", pre_ic_time); total_readtime.start (); img->read (); total_readtime.stop (); imagecache->getattribute ("stat:fileio_time", post_ic_time); total_imagecache_readtime += post_ic_time - pre_ic_time; // If this is the first tiled image we have come across, use it to // set our tile size (unless the user explicitly set a tile size, or // explicitly instructed scanline output). const ImageSpec &nspec ((*img)().nativespec()); if (nspec.tile_width && ! output_tilewidth && ! ot.output_scanline) { output_tilewidth = nspec.tile_width; output_tileheight = nspec.tile_height; } // If we do not yet have an expected output format, set it based on // this image (presumably the first one read. if (output_dataformat == TypeDesc::UNKNOWN) { output_dataformat = nspec.format; if (! output_bitspersample) output_bitspersample = nspec.get_int_attribute ("oiio:BitsPerSample"); } } bool Oiiotool::postpone_callback (int required_images, CallbackFunction func, int argc, const char *argv[]) { if (((curimg ? 1 : 0) + (int)image_stack.size()) < required_images) { // Not enough have inputs been specified so far, so put this // function on the "pending" list. m_pending_callback = func; m_pending_argc = argc; for (int i = 0; i < argc; ++i) m_pending_argv[i] = ustring(argv[i]).c_str(); return true; } return false; } void Oiiotool::process_pending () { // Process any pending command -- this is a case where the // command line had prefix 'oiiotool --action file1 file2' // instead of infix 'oiiotool file1 --action file2'. if (m_pending_callback) { int argc = m_pending_argc; const char *argv[4]; for (int i = 0; i < argc; ++i) argv[i] = m_pending_argv[i]; CallbackFunction callback = m_pending_callback; m_pending_callback = NULL; m_pending_argc = 0; (*callback) (argc, argv); } } void Oiiotool::error (const std::string &command, const std::string &explanation) { std::cerr << "ERROR: " << command; if (explanation.length()) std::cerr << " (" << explanation << ")"; std::cerr << "\n"; exit (-1); } static int extract_options (std::map &options, std::string command) { // std::cout << "extract_options '" << command << "'\n"; int noptions = 0; size_t pos; while ((pos = command.find_first_of(":")) != std::string::npos) { command = command.substr (pos+1, std::string::npos); size_t e = command.find_first_of("="); if (e != std::string::npos) { std::string name = command.substr(0,e); std::string value = command.substr(e+1,command.find_first_of(":")-(e+1)); options[name] = value; ++noptions; // std::cout << "'" << name << "' -> '" << value << "'\n"; } } return noptions; } static int set_threads (int argc, const char *argv[]) { ASSERT (argc == 2); OIIO::attribute ("threads", atoi(argv[1])); return 0; } static int input_file (int argc, const char *argv[]) { Timer timer (ot.enable_function_timing); for (int i = 0; i < argc; i++) { int exists = 1; if (! ot.imagecache->get_image_info (ustring(argv[0]), 0, 0, ustring("exists"), TypeDesc::TypeInt, &exists) || !exists) { std::cerr << "oiiotool ERROR: Could not open file \"" << argv[0] << "\"\n"; exit (1); } if (ot.verbose) std::cout << "Reading " << argv[0] << "\n"; ot.push (ImageRecRef (new ImageRec (argv[i], ot.imagecache))); if (ot.printinfo || ot.printstats || ot.dumpdata || ot.hash) { OiioTool::print_info_options pio; pio.verbose = ot.verbose; pio.subimages = ot.allsubimages; pio.compute_stats = ot.printstats; pio.dumpdata = ot.dumpdata; pio.compute_sha1 = ot.hash; pio.metamatch = ot.printinfo_metamatch; pio.nometamatch = ot.printinfo_nometamatch; long long totalsize = 0; std::string error; bool ok = OiioTool::print_info (argv[i], pio, totalsize, error); if (! ok) std::cerr << "oiiotool ERROR: " << error << "\n"; } ot.process_pending (); } ot.function_times["input"] += timer(); return 0; } static void string_to_dataformat (const std::string &s, TypeDesc &dataformat, int &bits) { if (s == "uint8") { dataformat = TypeDesc::UINT8; bits = 0; } else if (s == "int8") { dataformat = TypeDesc::INT8; bits = 0; } else if (s == "uint10") { dataformat = TypeDesc::UINT16; bits = 10; } else if (s == "uint12") { dataformat = TypeDesc::UINT16; bits = 12; } else if (s == "uint16") { dataformat = TypeDesc::UINT16; bits = 0; } else if (s == "int16") { dataformat = TypeDesc::INT16; bits = 0; } else if (s == "half") { dataformat = TypeDesc::HALF; bits = 0; } else if (s == "float") { dataformat = TypeDesc::FLOAT; bits = 0; } else if (s == "double") { dataformat = TypeDesc::DOUBLE; bits = 0; } } static void adjust_output_options (ImageSpec &spec, const Oiiotool &ot, bool format_supports_tiles) { if (ot.output_dataformat != TypeDesc::UNKNOWN) { spec.set_format (ot.output_dataformat); if (ot.output_bitspersample != 0) spec.attribute ("oiio:BitsPerSample", ot.output_bitspersample); else spec.erase_attribute ("oiio:BitsPerSample"); } if (ot.output_channelformats.size()) { spec.channelformats.clear (); spec.channelformats.resize (spec.nchannels, spec.format); for (int c = 0; c < spec.nchannels; ++c) { if (c >= (int)spec.channelnames.size()) break; std::map::const_iterator i = ot.output_channelformats.find (spec.channelnames[c]); if (i != ot.output_channelformats.end()) { int bits = 0; string_to_dataformat (i->second, spec.channelformats[c], bits); } } bool allsame = true; if (spec.channelnames.size()) for (int c = 1; c < spec.nchannels; ++c) allsame &= (spec.channelformats[c] == spec.channelformats[0]); if (allsame) { spec.format = spec.channelformats[0]; spec.channelformats.clear(); } } else { spec.channelformats.clear (); } // If we've had tiled input and scanline was not explicitly // requested, we'll try tiled output. if (ot.output_tilewidth && !ot.output_scanline && format_supports_tiles) { spec.tile_width = ot.output_tilewidth; spec.tile_height = ot.output_tileheight; spec.tile_depth = 1; } else { spec.tile_width = spec.tile_height = spec.tile_depth = 0; } if (! ot.output_compression.empty()) spec.attribute ("compression", ot.output_compression); if (ot.output_quality > 0) spec.attribute ("CompressionQuality", ot.output_quality); if (ot.output_planarconfig == "contig" || ot.output_planarconfig == "separate") spec.attribute ("planarconfig", ot.output_planarconfig); // Append command to image history std::string history = spec.get_string_attribute ("Exif:ImageHistory"); if (! Strutil::iends_with (history, ot.full_command_line)) { // don't add twice if (history.length() && ! Strutil::iends_with (history, "\n")) history += std::string("\n"); history += ot.full_command_line; spec.attribute ("Exif:ImageHistory", history); } std::string software = Strutil::format ("OpenImageIO %s : %s", OIIO_VERSION_STRING, ot.full_command_line); spec.attribute ("Software", software); } static bool DateTime_to_time_t (const char *datetime, time_t &timet) { int year, month, day, hour, min, sec; int r = sscanf (datetime, "%d:%d:%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec); // printf ("%d %d:%d:%d %d:%d:%d\n", r, year, month, day, hour, min, sec); if (r != 6) return false; struct tm tmtime; time_t now; Sysutil::get_local_time (&now, &tmtime); // fill in defaults tmtime.tm_sec = sec; tmtime.tm_min = min; tmtime.tm_hour = hour; tmtime.tm_mday = day; tmtime.tm_mon = month-1; tmtime.tm_year = year-1900; timet = mktime (&tmtime); return true; } static int output_file (int argc, const char *argv[]) { ASSERT (argc == 2 && !strcmp(argv[0],"-o")); Timer timer (ot.enable_function_timing); ot.total_writetime.start(); std::string filename = argv[1]; if (! ot.curimg.get()) { std::cerr << "oiiotool ERROR: -o " << filename << " did not have any current image to output.\n"; return 0; } if (ot.noclobber && Filesystem::exists(filename)) { std::cerr << "oiiotool ERROR: Output file \"" << filename << "\" already exists, not overwriting.\n"; return 0; } if (ot.verbose) std::cout << "Writing " << argv[1] << "\n"; ImageOutput *out = ImageOutput::create (filename.c_str()); if (! out) { std::cerr << "oiiotool ERROR: " << geterror() << "\n"; return 0; } bool supports_displaywindow = out->supports ("displaywindow"); bool supports_tiles = out->supports ("tiles"); ot.read (); ImageRecRef saveimg = ot.curimg; ImageRecRef ir (ot.curimg); // Handle --autotrim if (supports_displaywindow && ot.output_autotrim) { ROI origroi = get_roi(*ir->spec(0,0)); ROI roi = ImageBufAlgo::nonzero_region ((*ir)(0,0), origroi); if (roi.npixels() == 0) { // Special case -- all zero; but doctor to make it 1 zero pixel roi = origroi; roi.xend = roi.xbegin+1; roi.yend = roi.ybegin+1; roi.zend = roi.zbegin+1; } std::string crop = (ir->spec(0,0)->depth == 1) ? format_resolution (roi.width(), roi.height(), roi.xbegin, roi.ybegin) : format_resolution (roi.width(), roi.height(), roi.depth(), roi.xbegin, roi.ybegin, roi.zbegin); const char *argv[] = { "crop", crop.c_str() }; int action_crop (int argc, const char *argv[]); // forward decl action_crop (2, argv); ir = ot.curimg; } // Automatically crop/pad if outputting to a format that doesn't // support display windows, unless autocrop is disabled. if (! supports_displaywindow && ot.output_autocrop && (ir->spec()->x != ir->spec()->full_x || ir->spec()->y != ir->spec()->full_y || ir->spec()->width != ir->spec()->full_width || ir->spec()->height != ir->spec()->full_height)) { const char *argv[] = { "croptofull" }; int action_croptofull (int argc, const char *argv[]); // forward decl action_croptofull (1, argv); ir = ot.curimg; } // FIXME -- both autotrim and autocrop above neglect to handle // MIPmaps or subimages with full generality. std::vector subimagespecs (ir->subimages()); for (int s = 0; s < ir->subimages(); ++s) { ImageSpec spec = *ir->spec(s,0); adjust_output_options (spec, ot, supports_tiles); // For deep files, must copy the native deep channelformats if (spec.deep) spec.channelformats = (*ir)(s,0).nativespec().channelformats; subimagespecs[s] = spec; } // Do the initial open ImageOutput::OpenMode mode = ImageOutput::Create; if (ir->subimages() > 1 && out->supports("multiimage")) { if (! out->open (filename, ir->subimages(), &subimagespecs[0])) { std::cerr << "oiiotool ERROR: " << out->geterror() << "\n"; return 0; } } else { if (! out->open (filename, subimagespecs[0], mode)) { std::cerr << "oiiotool ERROR: " << out->geterror() << "\n"; return 0; } } // Output all the subimages and MIP levels for (int s = 0, send = ir->subimages(); s < send; ++s) { for (int m = 0, mend = ir->miplevels(s); m < mend; ++m) { ImageSpec spec = *ir->spec(s,m); adjust_output_options (spec, ot, supports_tiles); if (s > 0 || m > 0) { // already opened first subimage/level if (! out->open (filename, spec, mode)) { std::cerr << "oiiotool ERROR: " << out->geterror() << "\n"; return 0; } } if (! (*ir)(s,m).write (out)) { std::cerr << "oiiotool ERROR: " << (*ir)(s,m).geterror() << "\n"; return 0; } if (mend > 1) { if (out->supports("mipmap")) { mode = ImageOutput::AppendMIPLevel; // for next level } else if (out->supports("multiimage")) { mode = ImageOutput::AppendSubimage; } else { std::cout << "oiiotool WARNING: " << out->format_name() << " does not support MIP-maps for " << filename << "\n"; break; } } } mode = ImageOutput::AppendSubimage; // for next subimage if (send > 1 && ! out->supports("multiimage")) { std::cout << "oiiotool WARNING: " << out->format_name() << " does not support multiple subimages for " << filename << "\n"; break; } } out->close (); delete out; if (ot.output_adjust_time) { std::string metadatatime = ir->spec(0,0)->get_string_attribute ("DateTime"); std::time_t in_time = ir->time(); if (! metadatatime.empty()) DateTime_to_time_t (metadatatime.c_str(), in_time); Filesystem::last_write_time (filename, in_time); } ot.curimg = saveimg; ot.total_writetime.stop(); ot.function_times["output"] += timer(); return 0; } static int set_dataformat (int argc, const char *argv[]) { ASSERT (argc == 2); std::vector chans; Strutil::split (argv[1], chans, ","); if (chans.size() == 0) { return 0; // Nothing to do } if (chans.size() == 1 && !strchr(chans[0].c_str(),'=')) { // Of the form: -d uint8 (for example) // Just one default format designated, apply to all channels ot.output_dataformat = TypeDesc::UNKNOWN; ot.output_bitspersample = 0; string_to_dataformat (chans[0], ot.output_dataformat, ot.output_bitspersample); ot.output_channelformats.clear (); return 0; // we're done } // If we make it here, the format designator was of the form // name0=type0,name1=type1,... for (size_t i = 0; i < chans.size(); ++i) { const char *eq = strchr(chans[i].c_str(),'='); if (eq) { std::string channame (chans[i], 0, eq - chans[i].c_str()); ot.output_channelformats[channame] = std::string (eq+1); } else { ot.error (argv[0], Strutil::format ("Malformed format designator \"%s\"", chans[i])); } } return 0; } static int set_string_attribute (int argc, const char *argv[]) { ASSERT (argc == 3); if (! ot.curimg.get()) { std::cerr << "oiiotool ERROR: " << argv[0] << " had no current image.\n"; return 0; } set_attribute (ot.curimg, argv[1], TypeDesc::TypeString, argv[2]); return 0; } static int set_any_attribute (int argc, const char *argv[]) { ASSERT (argc == 3); if (! ot.curimg.get()) { std::cerr << "oiiotool ERROR: " << argv[0] << " had no current image.\n"; return 0; } set_attribute (ot.curimg, argv[1], TypeDesc(TypeDesc::UNKNOWN), argv[2]); return 0; } static bool do_erase_attribute (ImageSpec &spec, const std::string &attribname) { spec.erase_attribute (attribname); return true; } template static bool do_set_any_attribute (ImageSpec &spec, const std::pair &x) { spec.attribute (x.first, x.second); return true; } bool OiioTool::adjust_geometry (int &w, int &h, int &x, int &y, const char *geom, bool allow_scaling) { size_t geomlen = strlen(geom); float scale = 1.0f; int ww = w, hh = h; int xx = x, yy = y; int xmax, ymax; if (sscanf (geom, "%d,%d,%d,%d", &xx, &yy, &xmax, &ymax) == 4) { x = xx; y = yy; w = std::max (0, xmax-xx+1); h = std::max (0, ymax-yy+1); } else if (sscanf (geom, "%dx%d%d%d", &ww, &hh, &xx, &yy) == 4) { w = ww; h = hh; x = xx; y = yy; } else if (sscanf (geom, "%dx%d", &ww, &hh) == 2) { w = ww; h = hh; } else if (sscanf (geom, "%d%d", &xx, &yy) == 2) { x = xx; y = yy; } else if (allow_scaling && sscanf (geom, "%f", &scale) == 1 && geom[geomlen-1] == '%') { scale *= 0.01f; w = (int)(w * scale + 0.5f); h = (int)(h * scale + 0.5f); } else if (allow_scaling && sscanf (geom, "%f", &scale) == 1) { w = (int)(w * scale + 0.5f); h = (int)(h * scale + 0.5f); } else { std::cerr << "oiiotool ERROR: Unrecognized geometry \"" << geom << "\"\n"; return false; } // printf ("geom %dx%d, %+d%+d\n", w, h, x, y); return true; } bool OiioTool::set_attribute (ImageRecRef img, const std::string &attribname, TypeDesc type, const std::string &value) { ot.read (img); img->metadata_modified (true); if (! value.length()) { // If the value is the empty string, clear the attribute return apply_spec_mod (*img, do_erase_attribute, attribname, ot.allsubimages); } // Does it seem to be an int, or did the caller explicitly request // that it be set as an int? char *p = NULL; int i = strtol (value.c_str(), &p, 10); while (*p && isspace(*p)) ++p; if ((! *p && type == TypeDesc::UNKNOWN) || type == TypeDesc::INT) { // int conversion succeeded and accounted for the whole string -- // so set an int attribute. return apply_spec_mod (*img, do_set_any_attribute, std::pair(attribname,i), ot.allsubimages); } // Does it seem to be a float, or did the caller explicitly request // that it be set as a float? p = NULL; float f = (float)strtod (value.c_str(), &p); while (*p && isspace(*p)) ++p; if ((! *p && type == TypeDesc::UNKNOWN) || type == TypeDesc::FLOAT) { // float conversion succeeded and accounted for the whole string -- // so set a float attribute. return apply_spec_mod (*img, do_set_any_attribute, std::pair(attribname,f), ot.allsubimages); } // Otherwise, set it as a string attribute return apply_spec_mod (*img, do_set_any_attribute, std::pair(attribname,value), ot.allsubimages); } static int set_caption (int argc, const char *argv[]) { ASSERT (argc == 2); const char *newargs[3]; newargs[0] = argv[0]; newargs[1] = "ImageDescription"; newargs[2] = argv[1]; return set_string_attribute (3, newargs); } static bool do_set_keyword (ImageSpec &spec, const std::string &keyword) { std::string oldkw = spec.get_string_attribute ("Keywords"); std::vector oldkwlist; if (! oldkw.empty()) Strutil::split (oldkw, oldkwlist, ";"); bool dup = false; BOOST_FOREACH (std::string &ok, oldkwlist) { ok = Strutil::strip (ok); dup |= (ok == keyword); } if (! dup) { oldkwlist.push_back (keyword); spec.attribute ("Keywords", Strutil::join (oldkwlist, "; ")); } return true; } static int set_keyword (int argc, const char *argv[]) { ASSERT (argc == 2); if (! ot.curimg.get()) { std::cerr << "oiiotool ERROR: " << argv[0] << " had no current image.\n"; return 0; } std::string keyword (argv[1]); if (keyword.size()) apply_spec_mod (*ot.curimg, do_set_keyword, keyword, ot.allsubimages); return 0; } static int clear_keywords (int argc, const char *argv[]) { ASSERT (argc == 1); const char *newargs[3]; newargs[0] = argv[0]; newargs[1] = "Keywords"; newargs[2] = ""; return set_string_attribute (3, newargs); } static int set_orientation (int argc, const char *argv[]) { ASSERT (argc == 2); if (! ot.curimg.get()) { std::cerr << "oiiotool ERROR: " << argv[0] << " had no current image.\n"; return 0; } return set_attribute (ot.curimg, argv[0], TypeDesc::INT, argv[1]); } static bool do_rotate_orientation (ImageSpec &spec, const std::string &cmd) { bool rotcw = cmd == "--rotcw" || cmd == "-rotcw"; bool rotccw = cmd == "--rotccw" || cmd == "-rotccw"; bool rot180 = cmd == "--rot180" || cmd == "-rot180"; int orientation = spec.get_int_attribute ("Orientation", 1); if (orientation >= 1 && orientation <= 8) { static int cw[] = { 0, 6, 7, 8, 5, 2, 3, 4, 1 }; if (rotcw || rotccw || rot180) orientation = cw[orientation]; if (rotccw || rot180) orientation = cw[orientation]; if (rotccw) orientation = cw[orientation]; spec.attribute ("Orientation", orientation); } return true; } static int rotate_orientation (int argc, const char *argv[]) { ASSERT (argc == 1); if (! ot.curimg.get()) { std::cerr << "oiiotool ERROR: " << argv[0] << " had no current image.\n"; return 0; } apply_spec_mod (*ot.curimg, do_rotate_orientation, std::string(argv[0]), ot.allsubimages); return 0; } static int set_origin (int argc, const char *argv[]) { if (ot.postpone_callback (1, set_origin, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.curimg; ImageSpec &spec (*A->spec(0,0)); int x = spec.x, y = spec.y, z = spec.z; int w = spec.width, h = spec.height, d = spec.depth; adjust_geometry (w, h, x, y, argv[1]); if (spec.width != w || spec.height != h || spec.depth != d) std::cerr << argv[0] << " can't be used to change the size, only the origin\n"; if (spec.x != x || spec.y != y) { ImageBuf &ib = (*A)(0,0); if (ib.storage() == ImageBuf::IMAGECACHE) { // If the image is cached, we will totally screw up the IB/IC // operations if we try to change the origin in place, so in // that case force a full read to convert to a local buffer, // which is safe to diddle the origin. ib.read (0, 0, true /*force*/, spec.format); } spec.x = x; spec.y = y; spec.z = z; // That updated the private spec of the ImageRec. In this case // we really need to update the underlying IB as well. ImageSpec &ibspec = ib.specmod(); ibspec.x = x; ibspec.y = y; ibspec.z = z; A->metadata_modified (true); } ot.function_times["origin"] += timer(); return 0; } static int set_fullsize (int argc, const char *argv[]) { if (ot.postpone_callback (1, set_fullsize, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.curimg; ImageSpec &spec (*A->spec(0,0)); int x = spec.full_x, y = spec.full_y; int w = spec.full_width, h = spec.full_height; adjust_geometry (w, h, x, y, argv[1]); if (spec.full_x != x || spec.full_y != y || spec.full_width != w || spec.full_height != h) { spec.full_x = x; spec.full_y = y; spec.full_width = w; spec.full_height = h; A->metadata_modified (true); } ot.function_times["fullsize"] += timer(); return 0; } static int set_full_to_pixels (int argc, const char *argv[]) { if (ot.postpone_callback (1, set_full_to_pixels, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.curimg; for (int s = 0, send = A->subimages(); s < send; ++s) { for (int m = 0, mend = A->miplevels(s); m < mend; ++m) { ImageSpec &spec = *A->spec(s,m); spec.full_x = spec.x; spec.full_y = spec.y; spec.full_z = spec.z; spec.full_width = spec.width; spec.full_height = spec.height; spec.full_depth = spec.depth; // That updated the private spec of the ImageRec. In this case // we really need to update the underlying IB as well. ImageSpec &ibspec = (*A)(s,m).specmod(); ibspec.full_x = spec.x; ibspec.full_y = spec.y; ibspec.full_z = spec.z; ibspec.full_width = spec.width; ibspec.full_height = spec.height; ibspec.full_depth = spec.depth; } } A->metadata_modified (true); ot.function_times["fullpixels"] += timer(); return 0; } static int set_colorspace (int argc, const char *argv[]) { ASSERT (argc == 2); const char *args[3] = { argv[0], "oiio:ColorSpace", argv[1] }; return set_string_attribute (3, args); } static int action_colorconvert (int argc, const char *argv[]) { ASSERT (argc == 3); if (ot.postpone_callback (1, action_colorconvert, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::string fromspace = argv[1]; std::string tospace = argv[2]; ot.read (); bool need_transform = false; ImageRecRef A = ot.curimg; ot.read (A); for (int s = 0, send = A->subimages(); s < send; ++s) { for (int m = 0, mend = A->miplevels(s); m < mend; ++m) { const ImageSpec *spec = A->spec(s,m); need_transform |= spec->get_string_attribute("oiio:ColorSpace") != tospace; } } if (! need_transform) return 1; // no need to do anything ot.pop (); ot.push (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true, false)); for (int s = 0, send = A->subimages(); s < send; ++s) { for (int m = 0, mend = A->miplevels(s); m < mend; ++m) { bool ok = ImageBufAlgo::colorconvert ((*ot.curimg)(s,m), (*A)(s,m), fromspace.c_str(), tospace.c_str(), false); if (! ok) ot.error (argv[0], (*ot.curimg)(s,m).geterror()); } } ot.function_times["colorconvert"] += timer(); return 1; } static int action_tocolorspace (int argc, const char *argv[]) { // Don't time -- let it get accounted by colorconvert ASSERT (argc == 2); if (! ot.curimg.get()) { std::cerr << "oiiotool ERROR: " << argv[0] << " had no current image.\n"; return 0; } const char *args[3] = { argv[0], "current", argv[1] }; return action_colorconvert (3, args); } static int action_ociolook (int argc, const char *argv[]) { ASSERT (argc == 2); if (ot.postpone_callback (1, action_ociolook, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::string lookname = argv[1]; std::map options; options["inverse"] = "0"; options["from"] = "current"; options["to"] = "current"; options["key"] = ""; options["value"] = ""; extract_options (options, argv[0]); std::string fromspace = options["from"]; std::string tospace = options["to"]; std::string contextkey = options["key"]; std::string contextvalue = options["value"]; bool inverse = Strutil::from_string (options["inverse"]) != 0; ImageRecRef A = ot.curimg; ot.read (A); ot.pop (); ot.push (new ImageRec (*A, ot.allsubimages ? -1 : 0, 0, true, true|false)); if (fromspace == "current" || fromspace == "") fromspace = A->spec(0,0)->get_string_attribute ("oiio:Colorspace", "Linear"); if (tospace == "current" || tospace == "") tospace = A->spec(0,0)->get_string_attribute ("oiio:Colorspace", "Linear"); for (int s = 0, send = A->subimages(); s < send; ++s) { for (int m = 0, mend = A->miplevels(s); m < mend; ++m) { bool ok = ImageBufAlgo::ociolook ( (*ot.curimg)(s,m), (*A)(s,m), lookname.c_str(), fromspace.c_str(), tospace.c_str(), false, inverse, contextkey.c_str(), contextvalue.c_str()); if (! ok) ot.error (argv[0], (*ot.curimg)(s,m).geterror()); } } ot.function_times["ociolook"] += timer(); return 1; } static int action_ociodisplay (int argc, const char *argv[]) { ASSERT (argc == 3); if (ot.postpone_callback (1, action_ociodisplay, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::string displayname = argv[1]; std::string viewname = argv[2]; // TODO: this would be useful, but I don't like the syntax // if (displayname == "") // displayname = ot.colorconfig.getDefaultDisplayName(); // if (viewname == "") // viewname = ot.colorconfig.getDefaultViewName(); std::map options; options["from"] = "current"; options["key"] = ""; options["value"] = ""; extract_options (options, argv[0]); std::string fromspace = options["from"]; std::string contextkey = options["key"]; std::string contextvalue = options["value"]; bool override_looks = options.find("looks") != options.end(); ImageRecRef A = ot.curimg; ot.read (A); ot.pop (); ot.push (new ImageRec (*A, ot.allsubimages ? -1 : 0, 0, true, true|false)); if (fromspace == "current" || fromspace == "") fromspace = A->spec(0,0)->get_string_attribute ("oiio:Colorspace", "Linear"); for (int s = 0, send = A->subimages(); s < send; ++s) { for (int m = 0, mend = A->miplevels(s); m < mend; ++m) { bool ok = ImageBufAlgo::ociodisplay ( (*ot.curimg)(s,m), (*A)(s,m), displayname.c_str(), viewname.c_str(), fromspace.c_str(), override_looks ? options["looks"].c_str() : 0, false, contextkey.c_str(), contextvalue.c_str()); if (! ok) ot.error (argv[0], (*ot.curimg)(s,m).geterror()); } } ot.function_times["ociodisplay"] += timer(); return 1; } static int action_unpremult (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_unpremult, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A = ot.pop(); A->read (); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true /*writable*/, true /*copy_pixels*/)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) for (int m = 0, miplevels = R->miplevels(s); m < miplevels; ++m) ImageBufAlgo::unpremult ((*R)(s,m)); ot.function_times["unpremult"] += timer(); return 0; } static int action_premult (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_premult, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A = ot.pop(); A->read (); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true /*writable*/, true /*copy_pixels*/)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) for (int m = 0, miplevels = R->miplevels(s); m < miplevels; ++m) ImageBufAlgo::premult ((*R)(s,m)); ot.function_times["premult"] += timer(); return 0; } static int output_tiles (int /*argc*/, const char *argv[]) { // the ArgParse will have set the tile size, but we need this routine // to clear the scanline flag ot.output_scanline = false; return 0; } static int action_unmip (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_unmip, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); bool mipmapped = false; for (int s = 0, send = ot.curimg->subimages(); s < send; ++s) mipmapped |= (ot.curimg->miplevels(s) > 1); if (! mipmapped) { return 0; // --unmip on an unmipped image is a no-op } ImageRecRef newimg (new ImageRec (*ot.curimg, -1, 0, true, true)); ot.curimg = newimg; ot.function_times["unmip"] += timer(); return 0; } static int set_channelnames (int argc, const char *argv[]) { if (ot.postpone_callback (1, set_channelnames, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A = ot.curimg; ot.read (A); std::vector newchannelnames; Strutil::split (argv[1], newchannelnames, ","); for (int s = 0; s < A->subimages(); ++s) { int miplevels = A->miplevels(s); for (int m = 0; m < miplevels; ++m) { ImageSpec *spec = A->spec(s,m); spec->channelnames.resize (spec->nchannels); for (int c = 0; c < spec->nchannels; ++c) { if (c < (int)newchannelnames.size() && newchannelnames[c].size()) { std::string name = newchannelnames[c]; spec->channelnames[c] = name; if (Strutil::iequals(name,"A") || Strutil::iends_with(name,".A") || Strutil::iequals(name,"Alpha") || Strutil::iends_with(name,".Alpha")) spec->alpha_channel = c; if (Strutil::iequals(name,"Z") || Strutil::iends_with(name,".Z") || Strutil::iequals(name,"Depth") || Strutil::iends_with(name,".Depth")) spec->z_channel = c; } } } } ot.function_times["chnames"] += timer(); return 0; } // For a given spec (which contains the channel names for an image), and // a comma separated list of channels (e.g., "B,G,R,A"), compute the // vector of integer indices for those channels (e.g., {2,1,0,3}). // A channel may be a literal assignment (e.g., "=0.5"), or a literal // assignment with channel naming (e.g., "Z=0.5"). // Return true for success, false for failure, including if any of the // channels were not present in the image. Upon return, channels // will be the indices of the source image channels to copy (-1 for // channels that are not filled with source data), values will hold // the value to fill un-sourced channels (defaulting to zero), and // newchannelnames will be the name of renamed or non-default-named // channels (defaulting to "" if no special name is needed). static bool decode_channel_set (const ImageSpec &spec, std::string chanlist, std::vector &newchannelnames, std::vector &channels, std::vector &values) { channels.clear (); while (chanlist.length()) { // Extract the next channel name size_t pos = chanlist.find_first_of(","); std::string onechan (chanlist, 0, pos); onechan = Strutil::strip (onechan); if (pos == std::string::npos) chanlist.clear(); else chanlist = chanlist.substr (pos+1, std::string::npos); // Find the index corresponding to that channel newchannelnames.push_back (std::string()); float value = 0.0f; int ch = -1; for (int i = 0; i < spec.nchannels; ++i) if (spec.channelnames[i] == onechan) { // name of a known channel? ch = i; break; } if (ch < 0 && onechan.length() && (isdigit(onechan[0]) || onechan[0] == '-')) ch = atoi (onechan.c_str()); // numeric channel index if (ch < 0 && onechan.length()) { // Look for Either =val or name=val size_t equal_pos = onechan.find ('='); if (equal_pos != std::string::npos) { value = (float) atof (onechan.c_str()+equal_pos+1); onechan.erase (equal_pos); newchannelnames.back() = onechan; } } channels.push_back (ch); values.push_back (value); } return true; } static int action_channels (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_channels, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A (ot.pop()); ot.read (A); std::string chanlist = argv[1]; if (chanlist == "RGB") // Fix common synonyms/mistakes chanlist = "R,G,B"; else if (chanlist == "RGBA") chanlist = "R,G,B,A"; // Decode the channel set, make the full list of ImageSpec's we'll // need to describe the new ImageRec with the altered channels. std::vector allmiplevels; std::vector allspecs; for (int s = 0, subimages = ot.allsubimages ? A->subimages() : 1; s < subimages; ++s) { std::vector newchannelnames; std::vector channels; std::vector values; bool ok = decode_channel_set (*A->spec(s,0), chanlist, newchannelnames, channels, values); if (! ok) { ot.error (argv[0], Strutil::format("Invalid or unknown channel selection \"%s\"", chanlist)); ot.push (A); return 0; } int miplevels = ot.allsubimages ? A->miplevels(s) : 1; allmiplevels.push_back (miplevels); for (int m = 0; m < miplevels; ++m) { ImageSpec spec = *A->spec(s,m); spec.nchannels = (int)newchannelnames.size(); spec.channelformats.clear(); spec.default_channel_names (); allspecs.push_back (spec); } } // Create the replacement ImageRec ImageRecRef R (new ImageRec(A->name(), (int)allmiplevels.size(), &allmiplevels[0], &allspecs[0])); ot.push (R); // Subimage by subimage, MIP level by MIP level, copy/shuffle the // channels individually from the source image into the result. for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { std::vector newchannelnames; std::vector channels; std::vector values; decode_channel_set (*A->spec(s,0), chanlist, newchannelnames, channels, values); for (int m = 0, miplevels = R->miplevels(s); m < miplevels; ++m) { // Shuffle the indexed/named channels bool ok = ImageBufAlgo::channels ((*R)(s,m), (*A)(s,m), (int)channels.size(), &channels[0], &values[0], &newchannelnames[0], false); if (! ok) ot.error ("channels", (*R)(s,m).geterror()); // Tricky subtlety: IBA::channels changed the underlying IB, // we may need to update the IRR's copy of the spec. R->update_spec_from_imagebuf(s,m); } } ot.function_times["channels"] += timer(); return 0; } static int action_chappend (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_chappend, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef B (ot.pop()); ImageRecRef A (ot.pop()); ot.read (A); ot.read (B); std::vector allmiplevels; for (int s = 0, subimages = ot.allsubimages ? A->subimages() : 1; s < subimages; ++s) { int miplevels = ot.allsubimages ? A->miplevels(s) : 1; allmiplevels.push_back (miplevels); } // Create the replacement ImageRec ImageRecRef R (new ImageRec(A->name(), (int)allmiplevels.size(), &allmiplevels[0])); ot.push (R); // Subimage by subimage, MIP level by MIP level, channel_append the // two images. for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { for (int m = 0, miplevels = R->miplevels(s); m < miplevels; ++m) { // Shuffle the indexed/named channels bool ok = ImageBufAlgo::channel_append ((*R)(s,m), (*A)(s,m), (*B)(s,m)); if (! ok) ot.error ("chappend", (*R)(s,m).geterror()); // Tricky subtlety: IBA::channels changed the underlying IB, // we may need to update the IRR's copy of the spec. R->update_spec_from_imagebuf(s,m); } } ot.function_times["chappend"] += timer(); return 0; } static int action_selectmip (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_selectmip, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); bool mipmapped = false; for (int s = 0, send = ot.curimg->subimages(); s < send; ++s) mipmapped |= (ot.curimg->miplevels(s) > 1); if (! mipmapped) { return 0; // --selectmip on an unmipped image is a no-op } ImageRecRef newimg (new ImageRec (*ot.curimg, -1, atoi(argv[1]), true, true)); ot.curimg = newimg; ot.function_times["selectmip"] += timer(); return 0; } static int action_select_subimage (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_select_subimage, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); if (ot.curimg->subimages() == 1) return 0; // --subimage on a single-image file is a no-op int subimage = std::min (atoi(argv[1]), ot.curimg->subimages()); ImageRecRef A = ot.pop(); ot.push (new ImageRec (*A, subimage)); ot.function_times["subimage"] += timer(); return 0; } static int action_subimage_append (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_subimage_append, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef B (ot.pop()); ImageRecRef A (ot.pop()); ot.read (A); ot.read (B); // Find the MIP levels in all the subimages of both A and B std::vector allmiplevels; for (int s = 0; s < A->subimages(); ++s) { int miplevels = ot.allsubimages ? A->miplevels(s) : 1; allmiplevels.push_back (miplevels); } for (int s = 0; s < B->subimages(); ++s) { int miplevels = ot.allsubimages ? B->miplevels(s) : 1; allmiplevels.push_back (miplevels); } // Create the replacement ImageRec ImageRecRef R (new ImageRec(A->name(), (int)allmiplevels.size(), &allmiplevels[0])); ot.push (R); // Subimage by subimage, MIP level by MIP level, copy int sub = 0; for (int s = 0; s < A->subimages(); ++s, ++sub) { for (int m = 0; m < A->miplevels(s); ++m) { bool ok = (*R)(sub,m).copy ((*A)(s,m)); if (! ok) ot.error ("siappend", (*R)(sub,m).geterror()); // Tricky subtlety: IBA::channels changed the underlying IB, // we may need to update the IRR's copy of the spec. R->update_spec_from_imagebuf(sub,m); } } for (int s = 0; s < B->subimages(); ++s, ++sub) { for (int m = 0; m < B->miplevels(s); ++m) { bool ok = (*R)(sub,m).copy ((*B)(s,m)); if (! ok) ot.error ("siappend", (*R)(sub,m).geterror()); // Tricky subtlety: IBA::channels changed the underlying IB, // we may need to update the IRR's copy of the spec. R->update_spec_from_imagebuf(sub,m); } } ot.function_times["siappend"] += timer(); return 0; } static int action_colorcount (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_colorcount, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageBuf &Aib ((*ot.curimg)(0,0)); int nchannels = Aib.nchannels(); // We assume ';' to split, but for the sake of some command shells, // that use ';' as a command separator, also accept ":". std::vector colorvalues; std::vector colorstrings; if (strchr (argv[1], ':')) Strutil::split (argv[1], colorstrings, ":"); else Strutil::split (argv[1], colorstrings, ";"); int ncolors = (int) colorstrings.size(); for (int col = 0; col < ncolors; ++col) { std::vector color (nchannels, 0.0f); Strutil::extract_from_list_string (color, colorstrings[col], ","); for (int c = 0; c < nchannels; ++c) colorvalues.push_back (c < (int)color.size() ? color[c] : 0.0f); } std::vector eps (nchannels, 0.001f); std::map options; extract_options (options, argv[0]); Strutil::extract_from_list_string (eps, options["eps"]); imagesize_t *count = ALLOCA (imagesize_t, ncolors); bool ok = ImageBufAlgo::color_count ((*ot.curimg)(0,0), count, ncolors, &colorvalues[0], &eps[0]); if (ok) { for (int col = 0; col < ncolors; ++col) std::cout << Strutil::format("%8d %s\n", count[col], colorstrings[col]); } else { ot.error ("colorcount", (*ot.curimg)(0,0).geterror()); } ot.function_times["colorcount"] += timer(); return 0; } static int action_rangecheck (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_rangecheck, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageBuf &Aib ((*ot.curimg)(0,0)); int nchannels = Aib.nchannels(); std::vector low(nchannels,0.0f), high(nchannels,1.0f); Strutil::extract_from_list_string (low, argv[1], ","); Strutil::extract_from_list_string (high, argv[2], ","); imagesize_t lowcount = 0, highcount = 0, inrangecount = 0; bool ok = ImageBufAlgo::color_range_check ((*ot.curimg)(0,0), &lowcount, &highcount, &inrangecount, &low[0], &high[0]); if (ok) { std::cout << Strutil::format("%8d < %s\n", lowcount, argv[1]); std::cout << Strutil::format("%8d > %s\n", highcount, argv[2]); std::cout << Strutil::format("%8d within range\n", inrangecount); } else { ot.error ("rangecheck", (*ot.curimg)(0,0).geterror()); } ot.function_times["rangecheck"] += timer(); return 0; } static int action_diff (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_diff, argc, argv)) return 0; Timer timer (ot.enable_function_timing); int ret = do_action_diff (*ot.image_stack.back(), *ot.curimg, ot); if (ret != DiffErrOK && ret != DiffErrWarn) ot.return_value = EXIT_FAILURE; if (ret != DiffErrOK && ret != DiffErrWarn && ret != DiffErrFail) ot.error ("Error doing --diff"); ot.function_times["diff"] += timer(); return 0; } static int action_add (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_add, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef B (ot.pop()); ImageRecRef A (ot.pop()); ot.read (A); ot.read (B); ImageRecRef R (new ImageRec (*A, *B, ot.allsubimages ? -1 : 0, ImageRec::WinMergeUnion, ImageRec::WinMergeUnion, TypeDesc::FLOAT)); ot.push (R); int subimages = R->subimages(); for (int s = 0; s < subimages; ++s) { ImageBuf &Rib ((*R)(s)); const ImageBuf &Aib ((*A)(s)); const ImageBuf &Bib ((*B)(s)); bool ok = ImageBufAlgo::add (Rib, Aib, Bib); if (! ok) ot.error (argv[0], Rib.geterror()); } ot.function_times["add"] += timer(); return 0; } static int action_sub (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_sub, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef B (ot.pop()); ImageRecRef A (ot.pop()); ot.read (A); ot.read (B); ImageRecRef R (new ImageRec (*A, *B, ot.allsubimages ? -1 : 0, ImageRec::WinMergeUnion, ImageRec::WinMergeUnion, TypeDesc::FLOAT)); ot.push (R); int subimages = R->subimages(); for (int s = 0; s < subimages; ++s) { ImageBuf &Rib ((*R)(s)); const ImageBuf &Aib ((*A)(s)); const ImageBuf &Bib ((*B)(s)); bool ok = ImageBufAlgo::sub (Rib, Aib, Bib); if (! ok) ot.error (argv[0], Rib.geterror()); } ot.function_times["sub"] += timer(); return 0; } static int action_mul (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_mul, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef B (ot.pop()); ImageRecRef A (ot.pop()); ot.read (A); ot.read (B); ImageRecRef R (new ImageRec (*A, *B, ot.allsubimages ? -1 : 0, ImageRec::WinMergeUnion, ImageRec::WinMergeUnion, TypeDesc::FLOAT)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { ImageBuf &Rib ((*R)(s)); const ImageBuf &Aib ((*A)(s)); const ImageBuf &Bib ((*B)(s)); bool ok = ImageBufAlgo::mul (Rib, Aib, Bib); if (! ok) ot.error (argv[0], Rib.geterror()); } ot.function_times["mul"] += timer(); return 0; } static int action_abs (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_abs, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.pop(); ot.push (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true, false)); int subimages = ot.curimg->subimages(); for (int s = 0; s < subimages; ++s) { int miplevels = ot.curimg->miplevels(s); for (int m = 0; m < miplevels; ++m) { const ImageBuf &Aib ((*A)(s,m)); ImageBuf &Rib ((*ot.curimg)(s,m)); ImageBuf::ConstIterator a (Aib); ImageBuf::Iterator r (Rib); int nchans = Rib.nchannels(); for ( ; ! r.done(); ++r) { a.pos (r.x(), r.y()); for (int c = 0; c < nchans; ++c) r[c] = fabsf(a[c]); } } } ot.function_times["abs"] += timer(); return 0; } static int action_cmul (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_cmul, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::vector scalestrings; Strutil::split (std::string(argv[1]), scalestrings, ","); if (scalestrings.size() < 1) return 0; // Implicit multiplication by 1 if we can't figure it out ImageRecRef A = ot.pop(); A->read (); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true /*writable*/, true /*copy_pixels*/)); ot.push (R); std::vector scale; int subimages = ot.curimg->subimages(); for (int s = 0; s < subimages; ++s) { int nchans = R->spec(s,0)->nchannels; scale.clear (); scale.resize (nchans, (float) atof(scalestrings[0].c_str())); if (scalestrings.size() > 1) { for (int c = 0; c < nchans; ++c) { if (c < (int)scalestrings.size()) scale[c] = (float) atof(scalestrings[c].c_str()); else scale[c] = 1.0f; } } for (int m = 0, miplevels = ot.curimg->miplevels(s); m < miplevels; ++m) { bool ok = ImageBufAlgo::mul ((*R)(s,m), (*R)(s,m), &scale[0]); if (! ok) ot.error ("cmul", (*R)(s,m).geterror()); } } ot.function_times["cmul"] += timer(); return 0; } static int action_cadd (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_cadd, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::vector addstrings; Strutil::split (std::string(argv[1]), addstrings, ","); if (addstrings.size() < 1) return 0; // Implicit addition by 0 if we can't figure it out ImageRecRef A = ot.pop(); A->read (); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true /*writable*/, true /*copy_pixels*/)); ot.push (R); std::vector val; int subimages = ot.curimg->subimages(); for (int s = 0; s < subimages; ++s) { int nchans = R->spec(s,0)->nchannels; val.clear (); val.resize (nchans, (float) atof(addstrings[0].c_str())); if (addstrings.size() > 1) { for (int c = 0; c < nchans; ++c) { if (c < (int)addstrings.size()) val[c] = (float) atof(addstrings[c].c_str()); else val[c] = 0.0f; } } for (int m = 0, miplevels = ot.curimg->miplevels(s); m < miplevels; ++m) { bool ok = ImageBufAlgo::add ((*R)(s,m), (*R)(s,m), &val[0]); if (! ok) ot.error ("cadd", (*R)(s,m).geterror()); } } ot.function_times["cadd"] += timer(); return 0; } static int action_chsum (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_chsum, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A (ot.pop()); ot.read (A); ImageRecRef R (new ImageRec ("chsum", ot.allsubimages ? A->subimages() : 1)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { std::vector weight ((*A)(s).nchannels(), 1.0f); std::map options; extract_options (options, argv[0]); Strutil::extract_from_list_string (weight, options["weight"]); ImageBuf &Rib ((*R)(s)); const ImageBuf &Aib ((*A)(s)); bool ok = ImageBufAlgo::channel_sum (Rib, Aib, &weight[0]); if (! ok) ot.error ("chsum", Rib.geterror()); R->update_spec_from_imagebuf (s); } ot.function_times["chsum"] += timer(); return 0; } static int action_flip (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_flip, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.pop(); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true, false)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) for (int m = 0, miplevels = R->miplevels(s); m < miplevels; ++m) { bool ok = ImageBufAlgo::flip ((*R)(s,m), (*A)(s,m)); if (! ok) ot.error ("flip", (*R)(s,m).geterror()); } ot.function_times["flip"] += timer(); return 0; } static int action_flop (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_flop, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.pop(); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true, false)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) for (int m = 0, miplevels = R->miplevels(s); m < miplevels; ++m) { bool ok = ImageBufAlgo::flop ((*R)(s,m), (*A)(s,m)); if (! ok) ot.error ("flop", (*R)(s,m).geterror()); } ot.function_times["flop"] += timer(); return 0; } static int action_flipflop (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_flipflop, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.pop(); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true, false)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) for (int m = 0, miplevels = R->miplevels(s); m < miplevels; ++m) { bool ok = ImageBufAlgo::flipflop ((*R)(s,m), (*A)(s,m)); if (! ok) ot.error ("flipflop", (*R)(s,m).geterror()); } ot.function_times["flipflop"] += timer(); return 0; } static int action_transpose (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_transpose, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A (ot.pop()); ot.read (A); ImageRecRef R (new ImageRec ("transpose", ot.allsubimages ? A->subimages() : 1)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { bool ok = ImageBufAlgo::transpose ((*R)(s), (*A)(s)); if (! ok) ot.error ("transpose", (*R)(s).geterror()); R->update_spec_from_imagebuf (s); } ot.function_times["transpose"] += timer(); return 0; } static int action_cshift (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_cshift, argc, argv)) return 0; Timer timer (ot.enable_function_timing); int x = 0, y = 0, z = 0; if (sscanf (argv[1], "%d%d%d", &x, &y, &z) < 2) { ot.error ("cshift", Strutil::format ("Invalid shift offset '%s'", argv[1])); return 0; } ImageRecRef A (ot.pop()); ot.read (A); ImageRecRef R (new ImageRec ("cshift", ot.allsubimages ? A->subimages() : 1)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { bool ok = ImageBufAlgo::circular_shift ((*R)(s), (*A)(s), x, y, z); if (! ok) ot.error ("cshift", (*R)(s).geterror()); R->update_spec_from_imagebuf (s); } ot.function_times["cshift"] += timer(); return 0; } static int action_pop (int argc, const char *argv[]) { ASSERT (argc == 1); ot.pop (); return 0; } static int action_dup (int argc, const char *argv[]) { ASSERT (argc == 1); ot.push (ot.curimg); return 0; } static int action_swap (int argc, const char *argv[]) { ASSERT (argc == 1); if (ot.image_stack.size() < 1) { ot.error (argv[0], "requires at least two loaded images"); return 0; } ImageRecRef B (ot.pop()); ImageRecRef A (ot.pop()); ot.push (B); ot.push (A); return 0; } static int action_create (int argc, const char *argv[]) { ASSERT (argc == 3); Timer timer (ot.enable_function_timing); int nchans = atoi (argv[2]); if (nchans < 1 || nchans > 1024) { std::cout << "Invalid number of channels: " << nchans << "\n"; nchans = 3; } ImageSpec spec (64, 64, nchans, TypeDesc::FLOAT); adjust_geometry (spec.width, spec.height, spec.x, spec.y, argv[1]); spec.full_x = spec.x; spec.full_y = spec.y; spec.full_z = spec.z; spec.full_width = spec.width; spec.full_height = spec.height; spec.full_depth = spec.depth; ImageRecRef img (new ImageRec ("new", spec, ot.imagecache)); bool ok = ImageBufAlgo::zero ((*img)()); if (! ok) ot.error (argv[0], (*img)().geterror()); if (ot.curimg) ot.image_stack.push_back (ot.curimg); ot.curimg = img; ot.function_times["create"] += timer(); return 0; } static int action_pattern (int argc, const char *argv[]) { ASSERT (argc == 4); Timer timer (ot.enable_function_timing); int nchans = atoi (argv[3]); if (nchans < 1 || nchans > 1024) { std::cout << "Invalid number of channels: " << nchans << "\n"; nchans = 3; } ImageSpec spec (64, 64, nchans, TypeDesc::FLOAT); adjust_geometry (spec.width, spec.height, spec.x, spec.y, argv[2]); spec.full_x = spec.x; spec.full_y = spec.y; spec.full_z = spec.z; spec.full_width = spec.width; spec.full_height = spec.height; spec.full_depth = spec.depth; ImageRecRef img (new ImageRec ("new", spec, ot.imagecache)); ImageBuf &ib ((*img)()); std::string pattern = argv[1]; if (Strutil::iequals(pattern,"black")) { bool ok = ImageBufAlgo::zero (ib); if (! ok) ot.error (argv[0], ib.geterror()); } else if (Strutil::istarts_with(pattern,"constant")) { std::vector fill (nchans, 1.0f); std::map options; extract_options (options, pattern); Strutil::extract_from_list_string (fill, options["color"]); bool ok = ImageBufAlgo::fill (ib, &fill[0]); if (! ok) ot.error (argv[0], ib.geterror()); } else if (Strutil::istarts_with(pattern,"checker")) { std::map options; options["width"] = "8"; options["height"] = "8"; options["depth"] = "8"; extract_options (options, pattern); int width = Strutil::from_string (options["width"]); int height = Strutil::from_string (options["height"]); int depth = Strutil::from_string (options["depth"]); std::vector color1 (nchans, 0.0f); std::vector color2 (nchans, 1.0f); Strutil::extract_from_list_string (color1, options["color1"]); Strutil::extract_from_list_string (color2, options["color2"]); bool ok = ImageBufAlgo::checker (ib, width, height, depth, &color1[0], &color2[0], 0, 0, 0); if (! ok) ot.error (argv[0], ib.geterror()); } else { bool ok = ImageBufAlgo::zero (ib); if (! ok) ot.error (argv[0], ib.geterror()); } ot.push (img); ot.function_times["pattern"] += timer(); return 0; } static int action_kernel (int argc, const char *argv[]) { ASSERT (argc == 3); Timer timer (ot.enable_function_timing); int nchans = 1; if (nchans < 1 || nchans > 1024) { std::cout << "Invalid number of channels: " << nchans << "\n"; nchans = 3; } float w = 1.0f, h = 1.0f; if (sscanf (argv[2], "%fx%f", &w, &h) != 2) ot.error ("kernel", Strutil::format ("Unknown size %s", argv[2])); ImageSpec spec (1, 1, nchans, TypeDesc::FLOAT); ImageRecRef img (new ImageRec ("kernel", spec, ot.imagecache)); ImageBuf &ib ((*img)()); int ok = ImageBufAlgo::make_kernel (ib, argv[1], w, h); if (! ok) ot.error (argv[0], ib.geterror()); img->update_spec_from_imagebuf (0, 0); ot.push (img); ot.function_times["kernel"] += timer(); return 0; } static int action_capture (int argc, const char *argv[]) { ASSERT (argc == 1); Timer timer (ot.enable_function_timing); int camera = 0; std::string cmd = argv[0]; size_t pos; while ((pos = cmd.find_first_of(":")) != std::string::npos) { cmd = cmd.substr (pos+1, std::string::npos); if (Strutil::istarts_with(cmd,"camera=")) camera = atoi(cmd.c_str()+7); } ImageBuf ib; bool ok = ImageBufAlgo::capture_image (ib, camera, TypeDesc::FLOAT); if (! ok) ot.error (argv[0], ib.geterror()); ImageRecRef img (new ImageRec ("capture", ib.spec(), ot.imagecache)); (*img)().copy (ib); ot.push (img); ot.function_times["capture"] += timer(); return 0; } int action_crop (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_crop, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.curimg; ImageSpec &Aspec (*A->spec(0,0)); ImageSpec newspec = Aspec; adjust_geometry (newspec.width, newspec.height, newspec.x, newspec.y, argv[1]); if (newspec.width != Aspec.width || newspec.height != Aspec.height) { // resolution changed -- we need to do a full crop ot.pop(); ot.push (new ImageRec (A->name(), newspec, ot.imagecache)); const ImageBuf &Aib ((*A)(0,0)); ImageBuf &Rib ((*ot.curimg)(0,0)); bool ok = ImageBufAlgo::crop (Rib, Aib, get_roi(newspec)); if (! ok) ot.error (argv[0], Rib.geterror()); } else if (newspec.x != Aspec.x || newspec.y != Aspec.y) { // only offset changed; don't copy the image or crop, simply // adjust the origins. Aspec.x = newspec.x; Aspec.y = newspec.y; A->metadata_modified (true); } ot.function_times["crop"] += timer(); return 0; } int action_croptofull (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_croptofull, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.curimg; const ImageSpec &Aspec (*A->spec(0,0)); // Implement by calling action_crop with a geometry specifier built // from the current full image size. std::string size = format_resolution (Aspec.full_width, Aspec.full_height, Aspec.full_x, Aspec.full_y); const char *newargv[2] = { "crop", size.c_str() }; bool old_enable_function_timing = ot.enable_function_timing; ot.enable_function_timing = false; int result = action_crop (2, newargv); ot.function_times["croptofull"] += timer(); ot.enable_function_timing = old_enable_function_timing; return result; } static int action_resample (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_resample, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ot.read (); ImageRecRef A = ot.pop(); const ImageSpec &Aspec (*A->spec(0,0)); ImageSpec newspec = Aspec; adjust_geometry (newspec.width, newspec.height, newspec.x, newspec.y, argv[1], true); if (newspec.width == Aspec.width && newspec.height == Aspec.height) { ot.push (A); // Restore the original image return 0; // nothing to do } // Shrink-wrap full to match actual pixels; I'm not sure what else // is appropriate, need to think it over. newspec.full_x = newspec.x; newspec.full_y = newspec.y; newspec.full_width = newspec.width; newspec.full_height = newspec.height; ot.push (new ImageRec (A->name(), newspec, ot.imagecache)); const ImageBuf &Aib ((*A)(0,0)); ImageBuf &Rib ((*ot.curimg)(0,0)); bool ok = ImageBufAlgo::resample (Rib, Aib); if (! ok) ot.error (argv[0], Rib.geterror()); ot.function_times["resample"] += timer(); return 0; } static int action_resize (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_resize, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::string filtername; std::string cmd = argv[0]; size_t pos; while ((pos = cmd.find_first_of(":")) != std::string::npos) { cmd = cmd.substr (pos+1, std::string::npos); if (! strncmp (cmd.c_str(), "filter=", 7)) { filtername = cmd.substr (7, std::string::npos); } } ot.read (); ImageRecRef A = ot.pop(); const ImageSpec &Aspec (*A->spec(0,0)); ImageSpec newspec = Aspec; adjust_geometry (newspec.width, newspec.height, newspec.x, newspec.y, argv[1], true); if (newspec.width == Aspec.width && newspec.height == Aspec.height) { ot.push (A); // Restore the original image return 0; // nothing to do } // Shrink-wrap full to match actual pixels; I'm not sure what else // is appropriate, need to think it over. newspec.full_x = newspec.x; newspec.full_y = newspec.y; newspec.full_width = newspec.width; newspec.full_height = newspec.height; ot.push (new ImageRec (A->name(), newspec, ot.imagecache)); if (ot.verbose) { std::cout << "Resizing " << Aspec.width << "x" << Aspec.height << " to " << newspec.width << "x" << newspec.height << " using " << (filtername.size() ? filtername.c_str() : "default") << " filter\n"; } const ImageBuf &Aib ((*A)(0,0)); ImageBuf &Rib ((*ot.curimg)(0,0)); bool ok = ImageBufAlgo::resize (Rib, Aib, filtername, 0.0f, get_roi(Rib.spec())); ot.function_times["resize"] += timer(); if (! ok) ot.error (argv[0], Rib.geterror()); return 0; } static int action_fit (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_fit, argc, argv)) return 0; Timer timer (ot.enable_function_timing); bool old_enable_function_timing = ot.enable_function_timing; ot.enable_function_timing = false; // Examine the top of stack ImageRecRef A = ot.top(); ot.read (); const ImageSpec *Aspec = A->spec(0,0); // Parse the user request for resolution to fit int fit_full_width = Aspec->full_width; int fit_full_height = Aspec->full_height; int fit_full_x = Aspec->full_x; int fit_full_y = Aspec->full_y; adjust_geometry (fit_full_width, fit_full_height, fit_full_x, fit_full_y, argv[1], false); std::map options; extract_options (options, argv[0]); std::string padopt = options["pad"]; bool pad = padopt.size() && atoi(padopt.c_str()); std::string filtername = options["filter"]; // Compute scaling factors and use action_resize to do the heavy lifting float oldaspect = float(Aspec->full_width) / Aspec->full_height; float newaspect = float(fit_full_width) / fit_full_height; int resize_full_width = fit_full_width; int resize_full_height = fit_full_height; int xoffset = 0, yoffset = 0; if (newaspect >= oldaspect) { // same or wider than original resize_full_width = int(resize_full_height * oldaspect + 0.5f); xoffset = (fit_full_width - resize_full_width) / 2; } else { // narrower than original resize_full_height = int(resize_full_width / oldaspect + 0.5f); yoffset = (fit_full_height - resize_full_height) / 2; } if (ot.verbose) { std::cout << "Fitting " << format_resolution(Aspec->full_width, Aspec->full_height, Aspec->full_x, Aspec->full_y) << " into " << format_resolution(fit_full_width, fit_full_height, fit_full_x, fit_full_y) << "\n"; std::cout << " Resizing to " << format_resolution(resize_full_width, resize_full_height, fit_full_x, fit_full_y) << "\n"; } if (resize_full_width != Aspec->full_width || resize_full_height != Aspec->full_height || fit_full_x != Aspec->full_x || fit_full_y != Aspec->full_y) { std::string resize = format_resolution (resize_full_width, resize_full_height, 0, 0); std::string command = "resize"; if (filtername.size()) command += Strutil::format (":filter=%s", filtername); const char *newargv[2] = { command.c_str(), resize.c_str() }; action_resize (2, newargv); A = ot.top (); Aspec = A->spec(0,0); A->spec(0,0)->full_width = (*A)(0,0).specmod().full_width = fit_full_width; A->spec(0,0)->full_height = (*A)(0,0).specmod().full_height = fit_full_height; A->spec(0,0)->full_x = (*A)(0,0).specmod().full_x = fit_full_x; A->spec(0,0)->full_y = (*A)(0,0).specmod().full_y = fit_full_y; A->spec(0,0)->x = (*A)(0,0).specmod().x = xoffset; A->spec(0,0)->y = (*A)(0,0).specmod().y = yoffset; // Now A,Aspec are for the NEW resized top of stack } if (pad && (fit_full_width != Aspec->width || fit_full_height != Aspec->height)) { // Needs padding const char *argv[] = { "croptofull" }; action_croptofull (1, argv); } ot.function_times["fit"] += timer(); ot.enable_function_timing = old_enable_function_timing; return 0; } static int action_convolve (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_convolve, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef K = ot.pop(); // kernel ImageRecRef A = ot.pop(); A->read(); K->read(); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, 0, true /*writable*/, false /*copy_pixels*/)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { ImageBuf &Rib ((*R)(s)); bool ok = ImageBufAlgo::convolve (Rib, (*A)(s), (*K)(0)); if (! ok) ot.error ("convolve", Rib.geterror()); } ot.function_times["convolve"] += timer(); return 0; } static int action_blur (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_blur, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::map options; options["kernel"] = "gaussian"; extract_options (options, argv[0]); std::string kernopt = options["kernel"]; float w = 1.0f, h = 1.0f; if (sscanf (argv[1], "%fx%f", &w, &h) != 2) ot.error ("blur", Strutil::format ("Unknown size %s", argv[1])); ImageBuf Kernel ("kernel"); if (! ImageBufAlgo::make_kernel (Kernel, kernopt.c_str(), w, h)) ot.error ("blur", Kernel.geterror()); ImageRecRef A = ot.pop(); A->read(); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, 0, true /*writable*/, false /*copy_pixels*/)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { ImageBuf &Rib ((*R)(s)); bool ok = ImageBufAlgo::convolve (Rib, (*A)(s), Kernel); if (! ok) ot.error ("blur", Rib.geterror()); } ot.function_times["blur"] += timer(); return 0; } static int action_unsharp (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_unsharp, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::map options; options["kernel"] = "gaussian"; options["width"] = "3"; options["contrast"] = "1"; options["threshold"] = "0"; extract_options (options, argv[0]); std::string kernel = options["kernel"]; float width = (float) strtod (options["width"].c_str(), NULL); float contrast = (float) strtod (options["contrast"].c_str(), NULL); float threshold = (float) strtod (options["threshold"].c_str(), NULL); ImageRecRef A = ot.pop(); A->read(); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, 0, true /*writable*/, false /*copy_pixels*/)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { ImageBuf &Rib ((*R)(s)); bool ok = ImageBufAlgo::unsharp_mask (Rib, (*A)(s), kernel.c_str(), width, contrast, threshold); if (! ok) ot.error ("unsharp", Rib.geterror()); } ot.function_times["unsharp"] += timer(); return 0; } static int action_fft (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_fft, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A = ot.pop(); A->read(); ImageRecRef R (new ImageRec ("fft", ot.allsubimages ? A->subimages() : 1)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { ImageBuf &Rib ((*R)(s)); bool ok = ImageBufAlgo::fft (Rib, (*A)(s)); R->update_spec_from_imagebuf (s); if (! ok) ot.error ("fft", Rib.geterror()); } ot.function_times["fft"] += timer(); return 0; } static int action_ifft (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_ifft, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A = ot.pop(); A->read(); ImageRecRef R (new ImageRec ("ifft", ot.allsubimages ? A->subimages() : 1)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { ImageBuf &Rib ((*R)(s)); bool ok = ImageBufAlgo::ifft (Rib, (*A)(s)); R->update_spec_from_imagebuf (s); if (! ok) ot.error ("ifft", Rib.geterror()); } ot.function_times["ifft"] += timer(); return 0; } int action_fixnan (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_fixnan, argc, argv)) return 0; Timer timer (ot.enable_function_timing); NonFiniteFixMode mode = NONFINITE_BOX3; if (!strcmp(argv[1], "black")) mode = NONFINITE_BLACK; else if (!strcmp(argv[1], "box3")) mode = NONFINITE_BOX3; else { std::cerr << "--fixnan argument \"" << argv[1] << "\" not recognized. Valid choices: black, box3\n"; } ot.read (); ImageRecRef A = ot.pop(); ot.push (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true, false)); int subimages = ot.curimg->subimages(); for (int s = 0; s < subimages; ++s) { int miplevels = ot.curimg->miplevels(s); for (int m = 0; m < miplevels; ++m) { const ImageBuf &Aib ((*A)(s,m)); ImageBuf &Rib ((*ot.curimg)(s,m)); bool ok = ImageBufAlgo::fixNonFinite (Rib, Aib, mode); if (! ok) ot.error (argv[0], Rib.geterror()); } } ot.function_times["fixnan"] += timer(); return 0; } static int action_fillholes (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_fillholes, argc, argv)) return 0; Timer timer (ot.enable_function_timing); // Read and copy the top-of-stack image ImageRecRef A (ot.pop()); ot.read (A); ImageSpec spec = (*A)(0,0).spec(); set_roi (spec, roi_union (get_roi(spec), get_roi_full(spec))); ImageRecRef B (new ImageRec("filled", spec, ot.imagecache)); ot.push (B); ImageBuf &Rib ((*B)(0,0)); bool ok = ImageBufAlgo::fillholes_pushpull (Rib, (*A)(0,0)); if (! ok) ot.error (argv[0], Rib.geterror()); ot.function_times["fillholes"] += timer(); return 0; } static int action_paste (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_paste, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef BG (ot.pop()); ImageRecRef FG (ot.pop()); ot.read (BG); ot.read (FG); int x = 0, y = 0; if (sscanf (argv[1], "%d%d", &x, &y) != 2) { ot.error ("paste", Strutil::format ("Invalid offset '%s'", argv[1])); return 0; } ImageRecRef R (new ImageRec (*BG, 0, 0, true /* writable*/, true /* copy */)); ot.push (R); bool ok = ImageBufAlgo::paste ((*R)(), x, y, 0, 0, (*FG)()); if (! ok) ot.error (argv[0], (*R)().geterror()); ot.function_times["paste"] += timer(); return 0; } static int action_mosaic (int argc, const char *argv[]) { // Mosaic is tricky. We have to parse the argument before we know // how many images it wants to pull off the stack. int ximages = 0, yimages = 0; if (sscanf (argv[1], "%dx%d", &ximages, &yimages) != 2 || ximages < 1 || yimages < 1) { ot.error ("mosaic", Strutil::format ("Invalid size '%s'", argv[1])); return 0; } int nimages = ximages * yimages; if (ot.postpone_callback (nimages, action_paste, argc, argv)) return 0; Timer timer (ot.enable_function_timing); int widest = 0, highest = 0, nchannels = 0; std::vector images (nimages); for (int i = nimages-1; i >= 0; --i) { ImageRecRef img = ot.pop(); images[i] = img; ot.read (img); widest = std::max (widest, img->spec()->full_width); highest = std::max (highest, img->spec()->full_height); nchannels = std::max (nchannels, img->spec()->nchannels); } std::map options; options["pad"] = "0"; extract_options (options, argv[0]); int pad = strtol (options["pad"].c_str(), NULL, 10); ImageSpec Rspec (ximages*widest + (ximages-1)*pad, yimages*highest + (yimages-1)*pad, nchannels, TypeDesc::FLOAT); ImageRecRef R (new ImageRec ("mosaic", Rspec, ot.imagecache)); ot.push (R); ImageBufAlgo::zero ((*R)()); for (int j = 0; j < yimages; ++j) { int y = j * (highest + pad); for (int i = 0; i < ximages; ++i) { int x = i * (widest + pad); bool ok = ImageBufAlgo::paste ((*R)(), x, y, 0, 0, (*images[j*ximages+i])(0)); if (! ok) ot.error (argv[0], (*R)().geterror()); } } ot.function_times["mosaic"] += timer(); return 0; } static int action_over (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_over, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef B (ot.pop()); ImageRecRef A (ot.pop()); ot.read (A); ot.read (B); const ImageBuf &Aib ((*A)()); const ImageBuf &Bib ((*B)()); const ImageSpec &specA = Aib.spec(); const ImageSpec &specB = Bib.spec(); // Create output image specification. ImageSpec specR = specA; set_roi (specR, roi_union (get_roi(specA), get_roi(specB))); ot.push (new ImageRec ("over", specR, ot.imagecache)); ImageBuf &Rib ((*ot.curimg)()); bool ok = ImageBufAlgo::over (Rib, Aib, Bib); if (! ok) ot.error (argv[0], Rib.geterror()); ot.function_times["over"] += timer(); return 0; } static int action_zover (int argc, const char *argv[]) { if (ot.postpone_callback (2, action_zover, argc, argv)) return 0; Timer timer (ot.enable_function_timing); // Get optional flags bool z_zeroisinf = false; std::string cmd = argv[0]; size_t pos; while ((pos = cmd.find_first_of(":")) != std::string::npos) { cmd = cmd.substr (pos+1, std::string::npos); if (Strutil::istarts_with(cmd,"zeroisinf=")) z_zeroisinf = (atoi(cmd.c_str()+10) != 0); } ImageRecRef B (ot.pop()); ImageRecRef A (ot.pop()); ot.read (A); ot.read (B); const ImageBuf &Aib ((*A)()); const ImageBuf &Bib ((*B)()); const ImageSpec &specA = Aib.spec(); const ImageSpec &specB = Bib.spec(); // Create output image specification. ImageSpec specR = specA; set_roi (specR, roi_union (get_roi(specA), get_roi(specB))); ot.push (new ImageRec ("zover", specR, ot.imagecache)); ImageBuf &Rib ((*ot.curimg)()); bool ok = ImageBufAlgo::zover (Rib, Aib, Bib, z_zeroisinf); if (! ok) ot.error (argv[0], Rib.geterror()); ot.function_times["zover"] += timer(); return 0; } static int action_flatten (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_flatten, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A (ot.pop()); ot.read (A); const ImageBuf &Aib ((*A)()); const ImageSpec &specA = Aib.spec(); // Create output image specification. ImageSpec specR = specA; specR.deep = false; ot.push (new ImageRec ("flatten", specR, ot.imagecache)); ImageBuf &Rib ((*ot.curimg)()); bool ok = ImageBufAlgo::flatten (Rib, Aib); if (! ok) ot.error (argv[0], Rib.geterror()); ot.function_times["flatten"] += timer(); return 0; } static int action_fill (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_fill, argc, argv)) return 0; Timer timer (ot.enable_function_timing); // Read and copy the top-of-stack image ImageRecRef A (ot.pop()); ot.read (A); ot.push (new ImageRec (*A, 0, 0, true, true /*copy_pixels*/)); ImageBuf &Rib ((*ot.curimg)(0,0)); const ImageSpec &Rspec = Rib.spec(); int w = Rib.spec().width, h = Rib.spec().height; int x = Rib.spec().x, y = Rib.spec().y; if (! adjust_geometry (w, h, x, y, argv[1], true)) { return 0; } float *color = ALLOCA (float, Rspec.nchannels); for (int c = 0; c < Rspec.nchannels; ++c) color[c] = 1.0f; // Parse optional arguments for overrides std::string command = argv[0]; size_t pos; while ((pos = command.find_first_of(":")) != std::string::npos) { command = command.substr (pos+1, std::string::npos); if (Strutil::istarts_with(command,"color=")) { // Parse comma-separated color list size_t numpos = 6; for (int c = 0; c < Rspec.nchannels && numpos < command.size() && command[numpos] != ':'; ++c) { color[c] = (float) atof (command.c_str()+numpos); while (numpos < command.size() && command[numpos] != ':' && command[numpos] != ',') ++numpos; if (numpos < command.size()) ++numpos; } } } bool ok = ImageBufAlgo::fill (Rib, color, ROI(x, x+w, y, y+h)); if (! ok) ot.error (argv[0], Rib.geterror()); ot.function_times["fill"] += timer(); return 0; } static int action_clamp (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_clamp, argc, argv)) return 0; Timer timer (ot.enable_function_timing); ImageRecRef A = ot.pop(); A->read (); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true /*writeable*/, false /*copy_pixels*/)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { int nchans = (*R)(s,0).nchannels(); const float big = std::numeric_limits::max(); std::vector min (nchans, -big); std::vector max (nchans, big); std::map options; options["clampalpha"] = "0"; // initialize extract_options (options, argv[0]); Strutil::extract_from_list_string (min, options["min"]); Strutil::extract_from_list_string (max, options["max"]); bool clampalpha01 = strtol (options["clampalpha"].c_str(), NULL, 10) != 0; for (int m = 0, miplevels=R->miplevels(s); m < miplevels; ++m) { ImageBuf &Rib ((*R)(s,m)); ImageBuf &Aib ((*A)(s,m)); bool ok = ImageBufAlgo::clamp (Rib, Aib, &min[0], &max[0], clampalpha01); if (! ok) ot.error (argv[0], Rib.geterror()); } } ot.function_times["clamp"] += timer(); return 0; } static int action_rangecompress (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_rangecompress, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::map options; extract_options (options, argv[0]); std::string useluma_str = options["luma"]; bool useluma = useluma_str.size() && atoi(useluma_str.c_str()) != 0; ImageRecRef A = ot.pop(); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true /*writable*/, false /*copy_pixels*/)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { for (int m = 0, miplevels = R->miplevels(s); m < miplevels; ++m) { bool ok = ImageBufAlgo::rangecompress ((*R)(s,m), (*A)(s,m), useluma); if (! ok) ot.error (argv[0], (*R)(s,m).geterror()); } } ot.function_times["rangecompress"] += timer(); return 0; } static int action_rangeexpand (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_rangeexpand, argc, argv)) return 0; Timer timer (ot.enable_function_timing); std::map options; extract_options (options, argv[0]); std::string useluma_str = options["luma"]; bool useluma = useluma_str.size() && atoi(useluma_str.c_str()) != 0; ImageRecRef A = ot.pop(); ImageRecRef R (new ImageRec (*A, ot.allsubimages ? -1 : 0, ot.allsubimages ? -1 : 0, true /*writable*/, false /*copy_pixels*/)); ot.push (R); for (int s = 0, subimages = R->subimages(); s < subimages; ++s) { for (int m = 0, miplevels = R->miplevels(s); m < miplevels; ++m) { bool ok = ImageBufAlgo::rangeexpand ((*R)(s,m), (*A)(s,m), useluma); if (! ok) ot.error (argv[0], (*R)(s,m).geterror()); } } ot.function_times["rangeexpand"] += timer(); return 0; } static int action_text (int argc, const char *argv[]) { if (ot.postpone_callback (1, action_text, argc, argv)) return 0; Timer timer (ot.enable_function_timing); // Read and copy the top-of-stack image ImageRecRef A (ot.pop()); ot.read (A); ot.push (new ImageRec (*A, 0, 0, true, true /*copy_pixels*/)); ImageBuf &Rib ((*ot.curimg)(0,0)); const ImageSpec &Rspec = Rib.spec(); // Set up defaults for text placement, size, font, color std::map options; extract_options (options, argv[0]); int x = options["x"].size() ? Strutil::from_string(options["x"]) : (Rspec.x + Rspec.width/2); int y = options["y"].size() ? Strutil::from_string(options["y"]) : (Rspec.y + Rspec.height/2); int fontsize = options["size"].size() ? Strutil::from_string(options["size"]) : 16; std::string font = options["font"]; std::vector textcolor (Rspec.nchannels, 1.0f); Strutil::extract_from_list_string (textcolor, options["color"]); bool ok = ImageBufAlgo::render_text (Rib, x, y, argv[1] /* the text */, fontsize, font, &textcolor[0]); if (! ok) ot.error (argv[0], Rib.geterror()); ot.function_times["text"] += timer(); return 0; } /// action_histogram --------------------------------------------------------- /// Usage: /// ./oiiotool in --histogram:cumulative=int 'bins'x'height' /// channel -o out /// /// in - Input image that contains the channel to be histogramed. /// cumulative - Optional argument that can take values 0 or 1. If 0, /// then each bin will contain the count of pixels having /// values in the range for that bin. If 1, then each bin /// will contain not only its count, but also the counts of /// all preceding bins. /// 'bins'x'height' - Width and height of the histogram, where width equals /// the number of bins. /// channel - The channel in the input image to be histogramed. /// out - Output image. /// /// Examples: /// - ./oiiotool in --histogram 256x256 0 -o out /// /// Save the non-cumulative histogram of channel 0 in image /// 'in', as an image with size 256x256. /// /// - ./oiiotool in --histogram:cumulative=1 256x256 0 -o out /// /// Same as the previous example, but now a cumulative /// histogram is created, instead of a regular one. /// -------------------------------------------------------------------------- static int action_histogram (int argc, const char *argv[]) { ASSERT (argc == 3); if (ot.postpone_callback (1, action_histogram, argc, argv)) return 0; Timer timer (ot.enable_function_timing); // Input image. ot.read (); ImageRecRef A (ot.pop()); const ImageBuf &Aib ((*A)()); // Get arguments from command line. const char *size = argv[1]; int channel = atoi (argv[2]); int cumulative = 0; std::string cmd = argv[0]; size_t pos; while ((pos = cmd.find_first_of(":")) != std::string::npos) { cmd = cmd.substr (pos+1, std::string::npos); if (Strutil::istarts_with(cmd,"cumulative=")) cumulative = atoi(cmd.c_str()+11); } // Extract bins and height from size. int bins = 0, height = 0; if (sscanf (size, "%dx%d", &bins, &height) != 2) { std::cerr << "Invalid size" << "\n"; return -1; } // Compute regular histogram. std::vector hist; bool ok = ImageBufAlgo::histogram (Aib, channel, hist, bins); if (! ok) { ot.error (argv[0], Aib.geterror()); return 0; } // Compute cumulative histogram if specified. if (cumulative == 1) for (int i = 1; i < bins; i++) hist[i] += hist[i-1]; // Output image. ImageSpec specR (bins, height, 1, TypeDesc::FLOAT); ot.push (new ImageRec ("irec", specR, ot.imagecache)); ImageBuf &Rib ((*ot.curimg)()); ok = ImageBufAlgo::histogram_draw (Rib, hist); if (! ok) ot.error (argv[0], Rib.geterror()); ot.function_times["histogram"] += timer(); return 0; } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap (argc, (const char **)argv); ot.full_command_line = ap.command_line(); ap.options ("oiiotool -- simple image processing operations\n" OIIO_INTRO_STRING "\n" "Usage: oiiotool [filename,option,action]...\n", "%*", input_file, "", "", "Options (general):", "--help", &help, "Print help message", "-v", &ot.verbose, "Verbose status messages", "-q %!", &ot.verbose, "Quiet mode (turn verbose off)", "--runstats", &ot.runstats, "Print runtime statistics", "-a", &ot.allsubimages, "Do operations on all subimages/miplevels", "--info", &ot.printinfo, "Print resolution and metadata on all inputs", "--metamatch %s", &ot.printinfo_metamatch, "Regex: which metadata is printed with -info -v", "--no-metamatch %s", &ot.printinfo_nometamatch, "Regex: which metadata is excluded with -info -v", "--stats", &ot.printstats, "Print pixel statistics on all inputs", "--dumpdata", &ot.dumpdata, "Print all pixel data values", "--hash", &ot.hash, "Print SHA-1 hash of each input image", "--colorcount %@ %s", action_colorcount, NULL, "Count of how many pixels have the given color (argument: color;color;...) (optional args: eps=color)", "--rangecheck %@ %s %s", action_rangecheck, NULL, NULL, "Count of how many pixels are outside the low and high color arguments (each is a comma-separated color value list)", // "-u", &ot.updatemode, "Update mode: skip outputs when the file exists and is newer than all inputs", "--no-clobber", &ot.noclobber, "Do not overwrite existing files", "--noclobber", &ot.noclobber, "", // synonym "--threads %@ %d", set_threads, &ot.threads, "Number of threads (default 0 == #cores)", "--frames %s", NULL, "Frame range for '#' or printf-style wildcards", "--framepadding %d", NULL, "Frame number padding digits (ignored when using printf-style wildcards)", "", "Commands that write images:", "-o %@ %s", output_file, NULL, "Output the current image to the named file", "", "Options that affect subsequent image output:", "-d %@ %s", set_dataformat, NULL, "'-d TYPE' sets the output data format of all channels, " "'-d CHAN=TYPE' overrides a single named channel (multiple -d args are allowed). " "Data types include: uint8, sint8, uint10, uint12, uint16, sint16, half, float, double", "--scanline", &ot.output_scanline, "Output scanline images", "--tile %@ %d %d", output_tiles, &ot.output_tilewidth, &ot.output_tileheight, "Output tiled images (tilewidth, tileheight)", "--compression %s", &ot.output_compression, "Set the compression method", "--quality %d", &ot.output_quality, "Set the compression quality, 1-100", "--planarconfig %s", &ot.output_planarconfig, "Force planarconfig (contig, separate, default)", "--adjust-time", &ot.output_adjust_time, "Adjust file times to match DateTime metadata", "--noautocrop %!", &ot.output_autocrop, "Do not automatically crop images whose formats don't support separate pixel data and full/display windows", "--autotrim", &ot.output_autotrim, "Automatically trim black borders upon output to file formats that support separate pixel data and full/display windows", "", "Options that change current image metadata (but not pixel values):", "--attrib %@ %s %s", set_any_attribute, NULL, NULL, "Sets metadata attribute (name, value)", "--sattrib %@ %s %s", set_string_attribute, NULL, NULL, "Sets string metadata attribute (name, value)", "--caption %@ %s", set_caption, NULL, "Sets caption (ImageDescription metadata)", "--keyword %@ %s", set_keyword, NULL, "Add a keyword", "--clear-keywords %@", clear_keywords, NULL, "Clear all keywords", "--orientation %@ %d", set_orientation, NULL, "Set the assumed orientation", "--rotcw %@", rotate_orientation, NULL, "Rotate orientation 90 deg clockwise", "--rotccw %@", rotate_orientation, NULL, "Rotate orientation 90 deg counter-clockwise", "--rot180 %@", rotate_orientation, NULL, "Rotate orientation 180 deg", "--origin %@ %s", set_origin, NULL, "Set the pixel data window origin (e.g. +20+10)", "--fullsize %@ %s", set_fullsize, NULL, "Set the display window (e.g., 1920x1080, 1024x768+100+0, -20-30)", "--fullpixels %@", set_full_to_pixels, NULL, "Set the 'full' image range to be the pixel data window", "--chnames %@ %s", set_channelnames, NULL, "Set the channel names (comma-separated)", "", "Options that affect subsequent actions:", "--fail %g", &ot.diff_failthresh, "Failure threshold difference (0.000001)", "--failpercent %g", &ot.diff_failpercent, "Allow this percentage of failures in diff (0)", "--hardfail %g", &ot.diff_hardfail, "Fail diff if any one pixel exceeds this error (infinity)", "--warn %g", &ot.diff_warnthresh, "Warning threshold difference (0.00001)", "--warnpercent %g", &ot.diff_warnpercent, "Allow this percentage of warnings in diff (0)", "--hardwarn %g", &ot.diff_hardwarn, "Warn if any one pixel difference exceeds this error (infinity)", "", "Actions:", "--create %@ %s %d", action_create, NULL, NULL, "Create a blank image (args: geom, channels)", "--pattern %@ %s %s %d", action_pattern, NULL, NULL, NULL, "Create a patterned image (args: pattern, geom, channels)", "--kernel %@ %s %s", action_kernel, NULL, NULL, "Create a centered convolution kernel (args: name, geom)", "--capture %@", action_capture, NULL, "Capture an image (options: camera=%d)", "--diff %@", action_diff, NULL, "Print report on the difference of two images (modified by --fail, --failpercent, --hardfail, --warn, --warnpercent --hardwarn)", "--add %@", action_add, NULL, "Add two images", "--sub %@", action_sub, NULL, "Subtract two images", "--abs %@", action_abs, NULL, "Take the absolute value of the image pixels", "--mul %@", action_mul, NULL, "Multiply two images", "--cmul %s %@", action_cmul, NULL, "Multiply the image values by a scalar or per-channel constants (e.g.: 0.5 or 1,1.25,0.5)", "--cadd %s %@", action_cadd, NULL, "Add to all channels a scalar or per-channel constants (e.g.: 0.5 or 1,1.25,0.5)", "--chsum %@", action_chsum, NULL, "Turn into 1-channel image by summing channels (options: weight=r,g,...)", "--paste %@ %s", action_paste, NULL, "Paste fg over bg at the given position (e.g., +100+50)", "--mosaic %@ %s", action_mosaic, NULL, "Assemble images into a mosaic (arg: WxH; options: pad=0)", "--over %@", action_over, NULL, "'Over' composite of two images", "--zover %@", action_zover, NULL, "Depth composite two images with Z channels (options: zeroisinf=%d)", "--histogram %@ %s %d", action_histogram, NULL, NULL, "Histogram one channel (options: cumulative=0)", "--flip %@", action_flip, NULL, "Flip the image vertically (top<->bottom)", "--flop %@", action_flop, NULL, "Flop the image horizontally (left<->right)", "--flipflop %@", action_flipflop, NULL, "Flip and flop the image (180 degree rotation)", "--transpose %@", action_transpose, NULL, "Transpose the image", "--cshift %@ %s", action_cshift, NULL, "Circular shift the image (e.g.: +20-10)", "--crop %@ %s", action_crop, NULL, "Set pixel data resolution and offset, cropping or padding if necessary (WxH+X+Y or xmin,ymin,xmax,ymax)", "--croptofull %@", action_croptofull, NULL, "Crop or pad to make pixel data region match the \"full\" region", "--resample %@ %s", action_resample, NULL, "Resample (640x480, 50%)", "--resize %@ %s", action_resize, NULL, "Resize (640x480, 50%) (optional args: filter=%s)", "--fit %@ %s", action_fit, NULL, "Resize to fit within a window size (optional args: filter=%s, pad=%d)", "--convolve %@", action_convolve, NULL, "Convolve with a kernel", "--blur %@ %s", action_blur, NULL, "Blur the image (arg: WxH; options: kernel=name)", "--unsharp %@", action_unsharp, NULL, "Unsharp mask (options: kernel=gaussian, width=3, contrast=1, threshold=0)", "--fft %@", action_fft, NULL, "Take the FFT of the image", "--ifft %@", action_ifft, NULL, "Take the inverse FFT of the image", "--fixnan %@ %s", action_fixnan, NULL, "Fix NaN/Inf values in the image (options: none, black, box3)", "--fillholes %@", action_fillholes, NULL, "Fill in holes (where alpha is not 1)", "--fill %@ %s", action_fill, NULL, "Fill a region (options: color=)", "--clamp %@", action_clamp, NULL, "Clamp values (options: min=..., max=..., clampalpha=0)", "--rangecompress %@", action_rangecompress, NULL, "Compress the range of pixel values > 1 with a log scale (options: luma=0|1)", "--rangeexpand %@", action_rangeexpand, NULL, "Un-rangecompress pixel values > 1 (options: luma=0|1)", "--text %@ %s", action_text, NULL, "Render text into the current image (options: x=, y=, size=, color=)", "", "Image stack manipulation:", "--ch %@ %s", action_channels, NULL, "Select or shuffle channels (e.g., \"R,G,B\", \"B,G,R\", \"2,3,4\")", "--chappend %@", action_chappend, NULL, "Append the channels of the last two images", "--flatten %@", action_flatten, NULL, "Flatten deep image to non-deep", "--unmip %@", action_unmip, NULL, "Discard all but the top level of a MIPmap", "--selectmip %@ %d", action_selectmip, NULL, "Select just one MIP level (0 = highest res)", "--subimage %@ %d", action_select_subimage, NULL, "Select just one subimage", "--siappend %@", action_subimage_append, NULL, "Append the last two images into one multi-subimage image", "--pop %@", action_pop, NULL, "Throw away the current image", "--dup %@", action_dup, NULL, "Duplicate the current image (push a copy onto the stack)", "--swap %@", action_swap, NULL, "Swap the top two images on the stack.", "", "Color management:", "--iscolorspace %@ %s", set_colorspace, NULL, "Set the assumed color space (without altering pixels)", "--tocolorspace %@ %s", action_tocolorspace, NULL, "Convert the current image's pixels to a named color space", "--colorconvert %@ %s %s", action_colorconvert, NULL, NULL, "Convert pixels from 'src' to 'dst' color space (without regard to its previous interpretation)", "--ociolook %@ %s", action_ociolook, NULL, "Apply the named OCIO look (optional args: from=, to=, inverse=, key=, value=)", "--ociodisplay %@ %s %s", action_ociodisplay, NULL, NULL, "Apply the named OCIO display and view (optional args: from=, looks=, key=, value=)", "--unpremult %@", action_unpremult, NULL, "Divide all color channels of the current image by the alpha to \"un-premultiply\"", "--premult %@", action_premult, NULL, "Multiply all color channels of the current image by the alpha", NULL); if (ap.parse(argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_SUCCESS); } if (help || argc <= 1) { ap.usage (); // debugging color space names std::stringstream s; s << "Known color spaces: "; const char *linear = ot.colorconfig.getColorSpaceNameByRole("linear"); for (int i = 0, e = ot.colorconfig.getNumColorSpaces(); i < e; ++i) { const char *n = ot.colorconfig.getColorSpaceNameByIndex(i); s << "\"" << n << "\""; if (linear && !Strutil::iequals(n,"linear") && Strutil::iequals (n, linear)) s << " (linear)"; if (i < e-1) s << ", "; } int columns = Sysutil::terminal_columns() - 2; std::cout << Strutil::wordwrap(s.str(), columns, 4) << "\n"; int nlooks = ot.colorconfig.getNumLooks(); if (nlooks) { std::stringstream s; s << "Known looks: "; for (int i = 0; i < nlooks; ++i) { const char *n = ot.colorconfig.getLookNameByIndex(i); s << "\"" << n << "\""; if (i < nlooks-1) s << ", "; } std::cout << Strutil::wordwrap(s.str(), columns, 4) << "\n"; } const char *default_display = ot.colorconfig.getDefaultDisplayName(); int ndisplays = ot.colorconfig.getNumDisplays(); if (ndisplays) { std::stringstream s; s << "Known displays: "; for (int i = 0; i < ndisplays; ++i) { const char *d = ot.colorconfig.getDisplayNameByIndex(i); s << "\"" << d << "\""; if (! strcmp(d, default_display)) s << "*"; const char *default_view = ot.colorconfig.getDefaultViewName(d); int nviews = ot.colorconfig.getNumViews(d); if (nviews) { s << " (views: "; for (int i = 0; i < nviews; ++i) { const char *v = ot.colorconfig.getViewNameByIndex(d, i); s << "\"" << v << "\""; if (! strcmp(v, default_view)) s << "*"; if (i < nviews-1) s << ", "; } s << ")"; } if (i < ndisplays-1) s << ", "; } s << " (* = default)"; std::cout << Strutil::wordwrap(s.str(), columns, 4) << "\n"; } exit (EXIT_SUCCESS); } } // Check if any of the command line arguments contains numeric ranges or // wildcards. If not, just return 'false'. But if they do, the // remainder of processing will happen here (and return 'true'). static bool handle_sequence (int argc, const char **argv) { Timer totaltime; // First, scan the original command line arguments for '#', '@' or '%0Nd' // characters. Any found indicate that there are numeric range or // wildcards to deal with. Also look for --frames and --framepadding // options. #define ONERANGE_SPEC "[0-9]+(-[0-9]+((x|y)-?[0-9]+)?)?" #define MANYRANGE_SPEC ONERANGE_SPEC "(," ONERANGE_SPEC ")*" #define SEQUENCE_SPEC "(" MANYRANGE_SPEC ")?" "((#|@)+|(%[0-9]*d))" static boost::regex sequence_re (SEQUENCE_SPEC); std::string framespec = ""; int framepadding = 0; std::vector sequence_args; // Args with sequence numbers std::vector sequence_is_output; bool is_sequence = false; for (int a = 1; a < argc; ++a) { bool is_output = false; if (! strcmp (argv[a], "-o") && a < argc-1) { is_output = true; a++; } std::string strarg (argv[a]); boost::match_results range_match; if (boost::regex_search (strarg, range_match, sequence_re)) { is_sequence = true; sequence_args.push_back (a); sequence_is_output.push_back (is_output); } if (! strcmp (argv[a], "--frames") && a < argc-1) { framespec = argv[++a]; } else if (! strcmp (argv[a], "--framepadding") && a < argc-1) { int f = atoi (argv[++a]); if (f >= 1 && f < 10) framepadding = f; } } // No ranges or wildcards? if (! is_sequence) return false; // For each of the arguments that contains a wildcard, get a normalized // pattern in printf style (e.g. "foo.%04d.exr"). Next, either expand the // frame pattern to a list of frame numbers and use enumerate_file_sequence // to fully elaborate all the filenames in the sequence, or if no frame // range was specified, scan the filesystem for matching frames. Output // sequences without explicit frame ranges inherit the frame numbers of // the first input sequence. It's an error if the sequences are not all // of the same length. std::vector< std::vector > filenames (argc+1); std::vector< std::vector > frame_numbers (argc+1); std::string normalized_pattern, sequence_framespec; size_t nfilenames = 0; bool result; for (size_t i = 0; i < sequence_args.size(); ++i) { int a = sequence_args[i]; result = Filesystem::parse_pattern (argv[a], framepadding, normalized_pattern, sequence_framespec); if (! result) { ot.error (Strutil::format("Could not parse pattern: %s", argv[a]), ""); return true; } // --frames overrides sequence framespec if (! framespec.empty()) sequence_framespec = framespec; if (! sequence_framespec.empty()) { Filesystem::enumerate_sequence (sequence_framespec.c_str(), frame_numbers[a]); Filesystem::enumerate_file_sequence (normalized_pattern, frame_numbers[a], filenames[a]); } else if (sequence_is_output[i]) { // use frame numbers from first sequence Filesystem::enumerate_file_sequence (normalized_pattern, frame_numbers[sequence_args[0]], filenames[a]); } else if (! sequence_is_output[i]) { result = Filesystem::scan_for_matching_filenames (normalized_pattern, frame_numbers[a], filenames[a]); if (! result) { ot.error (Strutil::format("No filenames found matching pattern: %s", argv[a]), ""); return true; } } if (i == 0) { nfilenames = filenames[a].size(); } else if (nfilenames != filenames[a].size()) { ot.error (Strutil::format("Not all sequence specifications matched: %s (%d frames) vs. %s (%d frames)", argv[sequence_args[0]], nfilenames, argv[a], filenames[a].size()), ""); return true; } } // OK, now we just call getargs once for each item in the sequences, // substituting the i-th sequence entry for its respective argument // every time. std::vector seq_argv (argv, argv+argc+1); for (size_t i = 0; i < nfilenames; ++i) { for (size_t j = 0; j < sequence_args.size(); ++j) { size_t a = sequence_args[j]; seq_argv[a] = filenames[a][i].c_str(); } ot.clear_options (); // Careful to reset all command line options! getargs (argc, (char **)&seq_argv[0]); ot.process_pending (); if (ot.pending_callback()) { std::cout << "oiiotool WARNING: pending '" << ot.pending_callback_name() << "' command never executed.\n"; } // Clear the stack at the end of each iteration ot.curimg.reset (); ot.image_stack.clear(); if (ot.runstats) std::cout << "End iteration " << i << ": " << Strutil::timeintervalformat(totaltime(),2) << " " << Strutil::memformat(Sysutil::memory_used()) << "\n"; } return true; } int main (int argc, char *argv[]) { // When Visual Studio is used float values in scientific format are printed // with three digit exponent. We change this behavior to fit the Linux way. #ifdef _MSC_VER _set_output_format (_TWO_DIGIT_EXPONENT); #endif Timer totaltime; ot.imagecache = ImageCache::create (false); ASSERT (ot.imagecache); ot.imagecache->attribute ("forcefloat", 1); ot.imagecache->attribute ("m_max_memory_MB", 4096.0); // ot.imagecache->attribute ("autotile", 1024); Filesystem::convert_native_arguments (argc, (const char **)argv); if (handle_sequence (argc, (const char **)argv)) { // Deal with sequence } else { // Not a sequence getargs (argc, argv); ot.process_pending (); if (ot.pending_callback()) { std::cout << "oiiotool WARNING: pending '" << ot.pending_callback_name() << "' command never executed.\n"; } } if (ot.runstats) { double total_time = totaltime(); double unaccounted = total_time; std::cout << "\n"; int threads = -1; OIIO::getattribute ("threads", threads); std::cout << "Threads: " << threads << "\n"; std::cout << "oiiotool runtime statistics:\n"; std::cout << " Total time: " << Strutil::timeintervalformat(total_time,2) << "\n"; static const char *timeformat = " %-12s : %5.2f\n"; for (Oiiotool::TimingMap::const_iterator func = ot.function_times.begin(); func != ot.function_times.end(); ++func) { double t = func->second; std::cout << Strutil::format (timeformat, func->first, t); unaccounted -= t; } std::cout << Strutil::format (timeformat, "unaccounted", std::max(unaccounted, 0.0)); std::cout << ot.imagecache->getstats() << "\n"; } return ot.return_value; } openimageio-1.3.12~dfsg0.orig/src/oiiotool/oiiotool.h0000644000175000017500000003365512271062644020767 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OIIOTOOL_H #include "imagebuf.h" #include "refcnt.h" #include "timer.h" OIIO_NAMESPACE_ENTER { namespace OiioTool { typedef int (*CallbackFunction)(int argc,const char*argv[]); class ImageRec; typedef shared_ptr ImageRecRef; class Oiiotool { public: // General options bool verbose; bool runstats; bool noclobber; bool allsubimages; bool printinfo; bool printstats; bool dumpdata; bool hash; bool updatemode; int threads; std::string full_command_line; std::string printinfo_metamatch; std::string printinfo_nometamatch; // Output options TypeDesc output_dataformat; std::map output_channelformats; int output_bitspersample; bool output_scanline; int output_tilewidth, output_tileheight; std::string output_compression; int output_quality; std::string output_planarconfig; bool output_adjust_time; bool output_autocrop; bool output_autotrim; // Options for --diff float diff_warnthresh; float diff_warnpercent; float diff_hardwarn; float diff_failthresh; float diff_failpercent; float diff_hardfail; // Internal state ImageRecRef curimg; // current image std::vector image_stack; // stack of previous images ImageCache *imagecache; // back ptr to ImageCache int return_value; // oiiotool command return code ColorConfig colorconfig; // OCIO color config Timer total_readtime; Timer total_writetime; double total_imagecache_readtime; typedef std::map TimingMap; TimingMap function_times; bool enable_function_timing; Oiiotool (); void clear_options (); // Force img to be read at this point. void read (ImageRecRef img); // Read the current image void read () { if (curimg) read (curimg); } // If required_images are not yet on the stack, then postpone this // call by putting it on the 'pending' list and return true. // Otherwise (if enough images are on the stack), return false. bool postpone_callback (int required_images, CallbackFunction func, int argc, const char *argv[]); // Process any pending commands. void process_pending (); CallbackFunction pending_callback () const { return m_pending_callback; } const char *pending_callback_name () const { return m_pending_argv[0]; } void push (const ImageRecRef &img) { if (img) { if (curimg) image_stack.push_back (curimg); curimg = img; } } void push (ImageRec *newir) { push (ImageRecRef(newir)); } ImageRecRef pop () { ImageRecRef r = curimg; if (image_stack.size()) { // There are images on the full stack -- pop it curimg = image_stack.back (); image_stack.resize (image_stack.size()-1); } else { // Nothing on the stack, so get rid of the current image curimg = ImageRecRef(); } return r; } ImageRecRef top () { return curimg; } void error (const std::string &command, const std::string &explanation=""); private: CallbackFunction m_pending_callback; int m_pending_argc; const char *m_pending_argv[4]; }; typedef shared_ptr ImageBufRef; class SubimageRec { public: int miplevels() const { return (int) m_miplevels.size(); } ImageBuf * operator() () { return miplevels() ? m_miplevels[0].get() : NULL; } ImageBuf * operator[] (int i) { return i < miplevels() ? m_miplevels[i].get() : NULL; } const ImageBuf * operator[] (int i) const { return i < miplevels() ? m_miplevels[i].get() : NULL; } ImageSpec * spec (int i) { return i < miplevels() ? &m_specs[i] : NULL; } const ImageSpec * spec (int i) const { return i < miplevels() ? &m_specs[i] : NULL; } private: std::vector m_miplevels; std::vector m_specs; friend class ImageRec; }; class ImageRec { public: ImageRec (const std::string &name, ImageCache *imagecache) : m_name(name), m_elaborated(false), m_metadata_modified(false), m_pixels_modified(false), m_imagecache(imagecache) { } // Initialize an ImageRec with a collection of prepared ImageSpec's. // The number of subimages is nsubimages, the number of MIP levels // for each subimages is in miplevels[0..nsubimages-1] (if miplevels // is NULL, allocate just one MIP level per subimage), and specs[] // contains the specs for all the MIP levels of subimage 0, followed // by all the specs for the MIP levels of subimage 1, and so on. // If spec == NULL, the IB's will not be fully allocated/initialized. ImageRec (const std::string &name, int nsubimages = 1, const int *miplevels = NULL, const ImageSpec *specs=NULL); // Copy an existing ImageRec. Copy just the single subimage_to_copy // if >= 0, or all subimages if <0. Copy just the single // miplevel_to_copy if >= 0, or all MIP levels if <0. If writable // is true, we expect to need to alter the pixels of the resulting // ImageRec. If copy_pixels is false, just make the new image big // enough, no need to initialize the pixel values. ImageRec (ImageRec &img, int subimage_to_copy = -1, int miplevel_to_copy = -1, bool writable = true, bool copy_pixels = true); // Create an ImageRef that consists of the ImageBuf img. Copy img // if copy_pixels==true, otherwise just take ownership of img (it's // a shared pointer). ImageRec (ImageBufRef img, bool copy_pixels = true); // Initialize an ImageRec with the given spec. ImageRec (const std::string &name, const ImageSpec &spec, ImageCache *imagecache); enum WinMerge { WinMergeUnion, WinMergeIntersection, WinMergeA, WinMergeB }; // Initialize a new ImageRec based on two exemplars. Initialize // just the single subimage_to_copy if >= 0, or all subimages if <0. // The two WinMerge parameters pixwin and fullwin, dictate the // policy for setting up the pixel data and full (display) windows, // respectively. If pixeltype not UNKNOWN, use that rather than // A's pixel type (the default behavior). ImageRec (ImageRec &imgA, ImageRec &imgB, int subimage_to_copy = -1, WinMerge pixwin = WinMergeUnion, WinMerge fullwin = WinMergeUnion, TypeDesc pixeltype = TypeDesc::UNKNOWN); // Number of subimages int subimages() const { return (int) m_subimages.size(); } // Number of MIP levels of the given subimage int miplevels (int subimage=0) const { if (subimage >= subimages()) return 0; return m_subimages[subimage].miplevels(); } // Subimage reference accessors. SubimageRec& subimage (int i) { return m_subimages[i]; } const SubimageRec& subimage (int i) const { return m_subimages[i]; } // Accessing it like an array returns a specific subimage SubimageRec& operator[] (int i) { return m_subimages[i]; } const SubimageRec& operator[] (int i) const { return m_subimages[i]; } std::string name () const { return m_name; } // Has the ImageRec been actually read or evaluated? (Until needed, // it's lazily kept as name only, without reading the file.) bool elaborated () const { return m_elaborated; } bool read (); // ir(subimg,mip) references a specific MIP level of a subimage // ir(subimg) references the first MIP level of a subimage // ir() references the first MIP level of the first subimage ImageBuf& operator() (int subimg=0, int mip=0) { return *m_subimages[subimg][mip]; } const ImageBuf& operator() (int subimg=0, int mip=0) const { return *m_subimages[subimg][mip]; } ImageSpec * spec (int subimg=0, int mip=0) { return subimg < subimages() ? m_subimages[subimg].spec(mip) : NULL; } const ImageSpec * spec (int subimg=0, int mip=0) const { return subimg < subimages() ? m_subimages[subimg].spec(mip) : NULL; } bool metadata_modified () const { return m_metadata_modified; } void metadata_modified (bool mod) { m_metadata_modified = mod; } bool pixels_modified () const { return m_pixels_modified; } void pixels_modified (bool mod) { m_pixels_modified = mod; } std::time_t time() const { return m_time; } // This should be called if for some reason the underlying // ImageBuf's spec may have been modified in place. We need to // update the outer copy held by the SubimageRec. void update_spec_from_imagebuf (int subimg=0, int mip=0) { *m_subimages[subimg].spec(mip) = m_subimages[subimg][mip]->spec(); metadata_modified(); } private: std::string m_name; bool m_elaborated; bool m_metadata_modified; bool m_pixels_modified; std::vector m_subimages; std::time_t m_time; //< Modification time of the input file ImageCache *m_imagecache; }; struct print_info_options { bool verbose; bool filenameprefix; bool sum; bool subimages; bool compute_sha1; bool compute_stats; bool dumpdata; std::string metamatch; std::string nometamatch; size_t namefieldlength; print_info_options () : verbose(false), filenameprefix(false), sum(false), subimages(false), compute_sha1(false), compute_stats(false), dumpdata(false), namefieldlength(20) {} }; // Print info about the named file to stdout, using print_info_options // opt for guidance on what to print and how to do it. The total size // of the uncompressed pixels in the file is returned in totalsize. The // return value will be true if everything is ok, or false if there is // an error (in which case the error message will be stored in 'error'). bool print_info (const std::string &filename, const print_info_options &opt, long long &totalsize, std::string &error); // Modify the resolution and/or offset according to what's in geom. // Valid geometries are WxH (resolution), +X+Y (offsets), WxH+X+Y // (resolution and offset). If 'allow_scaling' is true, geometries of // S% (e.g. "50%") or just S (e.g., "1.2") will be accepted to scale the // existing width and height (rounding to the nearest whole number of // pixels. bool adjust_geometry (int &w, int &h, int &x, int &y, const char *geom, bool allow_scaling=false); // Set an attribute of the given image. The type should be one of // TypeDesc::INT (decode the value as an int), FLOAT, STRING, or UNKNOWN // (look at the string and try to discern whether it's an int, float, or // string). If the 'value' string is empty, it will delete the // attribute. bool set_attribute (ImageRecRef img, const std::string &attribname, TypeDesc type, const std::string &value); inline bool same_size (const ImageBuf &A, const ImageBuf &B) { const ImageSpec &a (A.spec()), &b (B.spec()); return (a.width == b.width && a.height == b.height && a.depth == b.depth && a.nchannels == b.nchannels); } enum DiffErrors { DiffErrOK = 0, ///< No errors, the images match exactly DiffErrWarn, ///< Warning: the errors differ a little DiffErrFail, ///< Failure: the errors differ a lot DiffErrDifferentSize, ///< Images aren't even the same size DiffErrFile, ///< Could not find or open input files, etc. DiffErrLast }; int do_action_diff (ImageRec &ir0, ImageRec &ir1, Oiiotool &options); // Helper template -- perform the action on each spec in the ImageRec. // The action needs a signature like: // bool action(ImageSpec &spec, const T& t)) template bool apply_spec_mod (ImageRec &img, Action act, const Type &t, bool allsubimages) { bool ok = true; img.read (); img.metadata_modified (true); for (int s = 0, send = img.subimages(); s < send; ++s) { for (int m = 0, mend = img.miplevels(s); m < mend; ++m) { ok &= act (*img.spec(s,m), t); if (! allsubimages) break; } if (! allsubimages) break; } return ok; } } // OiioTool namespace } OIIO_NAMESPACE_EXIT; #endif // OIIOTOOL_H openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/0000755000175000017500000000000012271062644017501 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptexoutput.cpp0000644000175000017500000000717412271062644022457 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "ptex/PtexWriter.h" #include "typedesc.h" #include "imageio.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN class PtexOutput : public ImageOutput { public: PtexOutput (); virtual ~PtexOutput (); virtual const char * format_name (void) const { return "ptex"; } virtual bool supports (const std::string &feature) const; virtual bool open (const std::string &name, const ImageSpec &spec, ImageOutput::OpenMode mode); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: // Initialize private members to pre-opened state void init (void) { } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *ptex_output_imageio_create () { return new PtexOutput; } // OIIO_EXPORT int ptex_imageio_version = OIIO_PLUGIN_VERSION; // it's in ptexinput.cpp OIIO_EXPORT const char * ptex_output_extensions[] = { "ptex", "ptx", NULL }; OIIO_PLUGIN_EXPORTS_END PtexOutput::PtexOutput () { init (); } PtexOutput::~PtexOutput () { // Close, if not already done. close (); } bool PtexOutput::supports (const std::string &feature) const { // Support nothing nonstandard if (feature == "tiles") return true; if (feature == "multiimage") return true; if (feature == "mipmap") return false; // N.B. because PtexWriters mipmaps automatically! return false; } bool PtexOutput::open (const std::string &name, const ImageSpec &userspec, ImageOutput::OpenMode mode) { error ("Ptex writer is not implemented yet, please poke Larry."); return false; } bool PtexOutput::close () { init(); return true; } bool PtexOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { error ("Ptex writer is not implemented yet, please poke Larry."); return false; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/0000755000175000017500000000000012271062644020461 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexUtils.cpp0000644000175000017500000005322712271062644023137 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "PtexPlatform.h" #include #include #include #include #include "PtexHalf.h" #include "PtexUtils.h" const char* Ptex::MeshTypeName(MeshType mt) { static const char* names[] = { "triangle", "quad" }; if (mt < 0 /* || mt >= int(sizeof(names)/sizeof(const char*))*/) return "(invalid mesh type)"; return names[mt]; } const char* Ptex::DataTypeName(DataType dt) { static const char* names[] = { "uint8", "uint16", "float16", "float32" }; if (dt < 0 /* || dt >= int(sizeof(names)/sizeof(const char*))*/) return "(invalid data type)"; return names[dt]; } const char* Ptex::BorderModeName(BorderMode m) { static const char* names[] = { "clamp", "black", "periodic" }; if (m < 0 || m >= int(sizeof(names)/sizeof(const char*))) return "(invalid border mode)"; return names[m]; } const char* Ptex::EdgeIdName(EdgeId eid) { static const char* names[] = { "bottom", "right", "top", "left" }; if (eid < 0 /* || eid >= int(sizeof(names)/sizeof(const char*)) */) return "(invalid edge id)"; return names[eid]; } const char* Ptex::MetaDataTypeName(MetaDataType mdt) { static const char* names[] = { "string", "int8", "int16", "int32", "float", "double" }; if (mdt < 0 || mdt >= int(sizeof(names)/sizeof(const char*))) return "(invalid meta data type)"; return names[mdt]; } namespace { template void ConvertArrayClamped(DST* dst, SRC* src, int numChannels, double scale, double round=0) { for (int i = 0; i < numChannels; i++) dst[i] = DST(PtexUtils::clamp(src[i], 0.0f, 1.0f) * scale + round); } template void ConvertArray(DST* dst, SRC* src, int numChannels, double scale, double round=0) { for (int i = 0; i < numChannels; i++) dst[i] = DST(src[i] * scale + round); } } void Ptex::ConvertToFloat(float* dst, const void* src, Ptex::DataType dt, int numChannels) { switch (dt) { case dt_uint8: ConvertArray(dst, (uint8_t*)src, numChannels, 1/255.0); break; case dt_uint16: ConvertArray(dst, (uint16_t*)src, numChannels, 1/65535.0); break; case dt_half: ConvertArray(dst, (PtexHalf*)src, numChannels, 1.0); break; case dt_float: memcpy(dst, src, sizeof(float)*numChannels); break; } } void Ptex::ConvertFromFloat(void* dst, const float* src, Ptex::DataType dt, int numChannels) { switch (dt) { case dt_uint8: ConvertArrayClamped((uint8_t*)dst, src, numChannels, 255.0, 0.5); break; case dt_uint16: ConvertArrayClamped((uint16_t*)dst, src, numChannels, 65535.0, 0.5); break; case dt_half: ConvertArray((PtexHalf*)dst, src, numChannels, 1.0); break; case dt_float: memcpy(dst, src, sizeof(float)*numChannels); break; } } bool PtexUtils::isConstant(const void* data, int stride, int ures, int vres, int pixelSize) { int rowlen = pixelSize * ures; const char* p = (const char*) data + stride; // compare each row with the first for (int i = 1; i < vres; i++, p += stride) if (0 != memcmp(data, p, rowlen)) return 0; // make sure first row is constant p = (const char*) data + pixelSize; for (int i = 1; i < ures; i++, p += pixelSize) if (0 != memcmp(data, p, pixelSize)) return 0; return 1; } namespace { template inline void interleave(const T* src, int sstride, int uw, int vw, T* dst, int dstride, int nchan) { sstride /= sizeof(T); dstride /= sizeof(T); // for each channel for (T* dstend = dst + nchan; dst != dstend; dst++) { // for each row T* drow = dst; for (const T* rowend = src + sstride*vw; src != rowend; src += sstride, drow += dstride) { // copy each pixel across the row T* dp = drow; for (const T* sp = src, * end = sp + uw; sp != end; dp += nchan) *dp = *sp++; } } } } void PtexUtils::interleave(const void* src, int sstride, int uw, int vw, void* dst, int dstride, DataType dt, int nchan) { switch (dt) { case dt_uint8: ::interleave((const uint8_t*) src, sstride, uw, vw, (uint8_t*) dst, dstride, nchan); break; case dt_half: case dt_uint16: ::interleave((const uint16_t*) src, sstride, uw, vw, (uint16_t*) dst, dstride, nchan); break; case dt_float: ::interleave((const float*) src, sstride, uw, vw, (float*) dst, dstride, nchan); break; } } namespace { template inline void deinterleave(const T* src, int sstride, int uw, int vw, T* dst, int dstride, int nchan) { sstride /= sizeof(T); dstride /= sizeof(T); // for each channel for (const T* srcend = src + nchan; src != srcend; src++) { // for each row const T* srow = src; for (const T* rowend = srow + sstride*vw; srow != rowend; srow += sstride, dst += dstride) { // copy each pixel across the row const T* sp = srow; for (T* dp = dst, * end = dp + uw; dp != end; sp += nchan) *dp++ = *sp; } } } } void PtexUtils::deinterleave(const void* src, int sstride, int uw, int vw, void* dst, int dstride, DataType dt, int nchan) { switch (dt) { case dt_uint8: ::deinterleave((const uint8_t*) src, sstride, uw, vw, (uint8_t*) dst, dstride, nchan); break; case dt_half: case dt_uint16: ::deinterleave((const uint16_t*) src, sstride, uw, vw, (uint16_t*) dst, dstride, nchan); break; case dt_float: ::deinterleave((const float*) src, sstride, uw, vw, (float*) dst, dstride, nchan); break; } } namespace { template void encodeDifference(T* data, int size) { size /= sizeof(T); T* p = (T*) data, * end = p + size, tmp, prev = 0; while (p != end) { tmp = prev; prev = *p; *p++ -= tmp; } } } void PtexUtils::encodeDifference(void* data, int size, DataType dt) { switch (dt) { case dt_uint8: ::encodeDifference((uint8_t*) data, size); break; case dt_uint16: ::encodeDifference((uint16_t*) data, size); break; default: break; // skip other types } } namespace { template void decodeDifference(T* data, int size) { size /= sizeof(T); T* p = (T*) data, * end = p + size, prev = 0; while (p != end) { *p += prev; prev = *p++; } } } void PtexUtils::decodeDifference(void* data, int size, DataType dt) { switch (dt) { case dt_uint8: ::decodeDifference((uint8_t*) data, size); break; case dt_uint16: ::decodeDifference((uint16_t*) data, size); break; default: break; // skip other types } } namespace { template inline void reduce(const T* src, int sstride, int uw, int vw, T* dst, int dstride, int nchan) { sstride /= sizeof(T); dstride /= sizeof(T); int rowlen = uw*nchan; int srowskip = 2*sstride - rowlen; int drowskip = dstride - rowlen/2; for (const T* end = src + vw*sstride; src != end; src += srowskip, dst += drowskip) for (const T* rowend = src + rowlen; src != rowend; src += nchan) for (const T* pixend = src+nchan; src != pixend; src++) *dst++ = T(0.25 * (src[0] + src[nchan] + src[sstride] + src[sstride+nchan])); } } void PtexUtils::reduce(const void* src, int sstride, int uw, int vw, void* dst, int dstride, DataType dt, int nchan) { switch (dt) { case dt_uint8: ::reduce((const uint8_t*) src, sstride, uw, vw, (uint8_t*) dst, dstride, nchan); break; case dt_half: ::reduce((const PtexHalf*) src, sstride, uw, vw, (PtexHalf*) dst, dstride, nchan); break; case dt_uint16: ::reduce((const uint16_t*) src, sstride, uw, vw, (uint16_t*) dst, dstride, nchan); break; case dt_float: ::reduce((const float*) src, sstride, uw, vw, (float*) dst, dstride, nchan); break; } } namespace { template inline void reduceu(const T* src, int sstride, int uw, int vw, T* dst, int dstride, int nchan) { sstride /= sizeof(T); dstride /= sizeof(T); int rowlen = uw*nchan; int srowskip = sstride - rowlen; int drowskip = dstride - rowlen/2; for (const T* end = src + vw*sstride; src != end; src += srowskip, dst += drowskip) for (const T* rowend = src + rowlen; src != rowend; src += nchan) for (const T* pixend = src+nchan; src != pixend; src++) *dst++ = T(0.5 * (src[0] + src[nchan])); } } void PtexUtils::reduceu(const void* src, int sstride, int uw, int vw, void* dst, int dstride, DataType dt, int nchan) { switch (dt) { case dt_uint8: ::reduceu((const uint8_t*) src, sstride, uw, vw, (uint8_t*) dst, dstride, nchan); break; case dt_half: ::reduceu((const PtexHalf*) src, sstride, uw, vw, (PtexHalf*) dst, dstride, nchan); break; case dt_uint16: ::reduceu((const uint16_t*) src, sstride, uw, vw, (uint16_t*) dst, dstride, nchan); break; case dt_float: ::reduceu((const float*) src, sstride, uw, vw, (float*) dst, dstride, nchan); break; } } namespace { template inline void reducev(const T* src, int sstride, int uw, int vw, T* dst, int dstride, int nchan) { sstride /= sizeof(T); dstride /= sizeof(T); int rowlen = uw*nchan; int srowskip = 2*sstride - rowlen; int drowskip = dstride - rowlen; for (const T* end = src + vw*sstride; src != end; src += srowskip, dst += drowskip) for (const T* rowend = src + rowlen; src != rowend; src++) *dst++ = T(0.5 * (src[0] + src[sstride])); } } void PtexUtils::reducev(const void* src, int sstride, int uw, int vw, void* dst, int dstride, DataType dt, int nchan) { switch (dt) { case dt_uint8: ::reducev((const uint8_t*) src, sstride, uw, vw, (uint8_t*) dst, dstride, nchan); break; case dt_half: ::reducev((const PtexHalf*) src, sstride, uw, vw, (PtexHalf*) dst, dstride, nchan); break; case dt_uint16: ::reducev((const uint16_t*) src, sstride, uw, vw, (uint16_t*) dst, dstride, nchan); break; case dt_float: ::reducev((const float*) src, sstride, uw, vw, (float*) dst, dstride, nchan); break; } } namespace { // generate a reduction of a packed-triangle texture // note: this method won't work for tiled textures template inline void reduceTri(const T* src, int sstride, int w, int /*vw*/, T* dst, int dstride, int nchan) { sstride /= sizeof(T); dstride /= sizeof(T); int rowlen = w*nchan; const T* src2 = src + (w-1) * sstride + rowlen - nchan; int srowinc2 = -2*sstride - nchan; int srowskip = 2*sstride - rowlen; int srowskip2 = w*sstride - 2 * nchan; int drowskip = dstride - rowlen/2; for (const T* end = src + w*sstride; src != end; src += srowskip, src2 += srowskip2, dst += drowskip) for (const T* rowend = src + rowlen; src != rowend; src += nchan, src2 += srowinc2) for (const T* pixend = src+nchan; src != pixend; src++, src2++) *dst++ = T(0.25 * (src[0] + src[nchan] + src[sstride] + src2[0])); } } void PtexUtils::reduceTri(const void* src, int sstride, int w, int /*vw*/, void* dst, int dstride, DataType dt, int nchan) { switch (dt) { case dt_uint8: ::reduceTri((const uint8_t*) src, sstride, w, 0, (uint8_t*) dst, dstride, nchan); break; case dt_half: ::reduceTri((const PtexHalf*) src, sstride, w, 0, (PtexHalf*) dst, dstride, nchan); break; case dt_uint16: ::reduceTri((const uint16_t*) src, sstride, w, 0, (uint16_t*) dst, dstride, nchan); break; case dt_float: ::reduceTri((const float*) src, sstride, w, 0, (float*) dst, dstride, nchan); break; } } void PtexUtils::fill(const void* src, void* dst, int dstride, int ures, int vres, int pixelsize) { // fill first row int rowlen = ures*pixelsize; char* ptr = (char*) dst; char* end = ptr + rowlen; for (; ptr != end; ptr += pixelsize) memcpy(ptr, src, pixelsize); // fill remaining rows from first row ptr = (char*) dst + dstride; end = (char*) dst + vres*dstride; for (; ptr != end; ptr += dstride) memcpy(ptr, dst, rowlen); } void PtexUtils::copy(const void* src, int sstride, void* dst, int dstride, int vres, int rowlen) { // regular non-tiled case if (sstride == rowlen && dstride == rowlen) { // packed case - copy in single block memcpy(dst, src, vres*rowlen); } else { // copy a row at a time char* sptr = (char*) src; char* dptr = (char*) dst; for (char* end = sptr + vres*sstride; sptr != end;) { memcpy(dptr, sptr, rowlen); dptr += dstride; sptr += sstride; } } } namespace { template inline void blend(const T* src, float weight, T* dst, int rowlen, int nchan) { for (const T* end = src + rowlen * nchan; src != end; dst++) *dst = *dst + T(weight * *src++); } template inline void blendflip(const T* src, float weight, T* dst, int rowlen, int nchan) { dst += (rowlen-1) * nchan; for (const T* end = src + rowlen * nchan; src != end;) { for (int i = 0; i < nchan; i++, dst++) *dst = *dst + T(weight * *src++); dst -= nchan*2; } } } void PtexUtils::blend(const void* src, float weight, void* dst, bool flip, int rowlen, DataType dt, int nchan) { switch ((dt<<1) | int(flip)) { case (dt_uint8<<1): ::blend((const uint8_t*) src, weight, (uint8_t*) dst, rowlen, nchan); break; case (dt_uint8<<1 | 1): ::blendflip((const uint8_t*) src, weight, (uint8_t*) dst, rowlen, nchan); break; case (dt_half<<1): ::blend((const PtexHalf*) src, weight, (PtexHalf*) dst, rowlen, nchan); break; case (dt_half<<1 | 1): ::blendflip((const PtexHalf*) src, weight, (PtexHalf*) dst, rowlen, nchan); break; case (dt_uint16<<1): ::blend((const uint16_t*) src, weight, (uint16_t*) dst, rowlen, nchan); break; case (dt_uint16<<1 | 1): ::blendflip((const uint16_t*) src, weight, (uint16_t*) dst, rowlen, nchan); break; case (dt_float<<1): ::blend((const float*) src, weight, (float*) dst, rowlen, nchan); break; case (dt_float<<1 | 1): ::blendflip((const float*) src, weight, (float*) dst, rowlen, nchan); break; } } namespace { template inline void average(const T* src, int sstride, int uw, int vw, T* dst, int nchan) { float* buff = (float*) alloca(nchan*sizeof(float)); memset(buff, 0, nchan*sizeof(float)); sstride /= sizeof(T); int rowlen = uw*nchan; int rowskip = sstride - rowlen; for (const T* end = src + vw*sstride; src != end; src += rowskip) for (const T* rowend = src + rowlen; src != rowend;) for (int i = 0; i < nchan; i++) buff[i] += *src++; double scale = 1.0/(uw*vw); for (int i = 0; i < nchan; i++) dst[i] = T(buff[i]*scale); } } void PtexUtils::average(const void* src, int sstride, int uw, int vw, void* dst, DataType dt, int nchan) { switch (dt) { case dt_uint8: ::average((const uint8_t*) src, sstride, uw, vw, (uint8_t*) dst, nchan); break; case dt_half: ::average((const PtexHalf*) src, sstride, uw, vw, (PtexHalf*) dst, nchan); break; case dt_uint16: ::average((const uint16_t*) src, sstride, uw, vw, (uint16_t*) dst, nchan); break; case dt_float: ::average((const float*) src, sstride, uw, vw, (float*) dst, nchan); break; } } namespace { struct CompareRfaceIds { const Ptex::FaceInfo* faces; CompareRfaceIds(const Ptex::FaceInfo* faces) : faces(faces) {} bool operator() (uint32_t faceid1, uint32_t faceid2) { const Ptex::FaceInfo& f1 = faces[faceid1]; const Ptex::FaceInfo& f2 = faces[faceid2]; int min1 = f1.isConstant() ? 1 : PtexUtils::min(f1.res.ulog2, f1.res.vlog2); int min2 = f2.isConstant() ? 1 : PtexUtils::min(f2.res.ulog2, f2.res.vlog2); return min1 > min2; } }; } namespace { template inline void multalpha(T* data, int npixels, int nchannels, int alphachan, double scale) { int alphaoffset; // offset to alpha chan from data ptr int nchanmult; // number of channels to alpha-multiply if (alphachan == 0) { // first channel is alpha chan: mult the rest of the channels data++; alphaoffset = -1; nchanmult = nchannels - 1; } else { // mult all channels up to alpha chan alphaoffset = alphachan; nchanmult = alphachan; } for (T* end = data + npixels*nchannels; data != end; data += nchannels) { double aval = scale * data[alphaoffset]; for (int i = 0; i < nchanmult; i++) data[i] = T(data[i] * aval); } } } void PtexUtils::multalpha(void* data, int npixels, DataType dt, int nchannels, int alphachan) { double scale = OneValueInv(dt); switch(dt) { case dt_uint8: ::multalpha((uint8_t*) data, npixels, nchannels, alphachan, scale); break; case dt_uint16: ::multalpha((uint16_t*) data, npixels, nchannels, alphachan, scale); break; case dt_half: ::multalpha((PtexHalf*) data, npixels, nchannels, alphachan, scale); break; case dt_float: ::multalpha((float*) data, npixels, nchannels, alphachan, scale); break; } } namespace { template inline void divalpha(T* data, int npixels, int nchannels, int alphachan, double scale) { int alphaoffset; // offset to alpha chan from data ptr int nchandiv; // number of channels to alpha-divide if (alphachan == 0) { // first channel is alpha chan: div the rest of the channels data++; alphaoffset = -1; nchandiv = nchannels - 1; } else { // div all channels up to alpha chan alphaoffset = alphachan; nchandiv = alphachan; } for (T* end = data + npixels*nchannels; data != end; data += nchannels) { T alpha = data[alphaoffset]; if (!alpha) continue; // don't divide by zero! double aval = scale / alpha; for (int i = 0; i < nchandiv; i++) data[i] = T(data[i] * aval); } } } void PtexUtils::divalpha(void* data, int npixels, DataType dt, int nchannels, int alphachan) { double scale = OneValue(dt); switch(dt) { case dt_uint8: ::divalpha((uint8_t*) data, npixels, nchannels, alphachan, scale); break; case dt_uint16: ::divalpha((uint16_t*) data, npixels, nchannels, alphachan, scale); break; case dt_half: ::divalpha((PtexHalf*) data, npixels, nchannels, alphachan, scale); break; case dt_float: ::divalpha((float*) data, npixels, nchannels, alphachan, scale); break; } } void PtexUtils::genRfaceids(const FaceInfo* faces, int nfaces, uint32_t* rfaceids, uint32_t* faceids) { // stable_sort faceids by smaller dimension (u or v) in descending order // treat const faces as having res of 1 // init faceids for (int i = 0; i < nfaces; i++) faceids[i] = i; // sort faceids by rfaceid std::stable_sort(faceids, faceids + nfaces, CompareRfaceIds(faces)); // generate mapping from faceid to rfaceid for (int i = 0; i < nfaces; i++) { // note: i is the rfaceid rfaceids[faceids[i]] = i; } } namespace { // apply to 1..4 channels, unrolled template void ApplyConst(double weight, double* dst, void* data, int /*nChan*/) { // dst[i] += data[i] * weight for i in {0..n-1} PtexUtils::VecAccum()(dst, (T*) data, weight); } // apply to N channels (general case) template void ApplyConstN(double weight, double* dst, void* data, int nChan) { // dst[i] += data[i] * weight for i in {0..n-1} PtexUtils::VecAccumN()(dst, (T*) data, nChan, weight); } } PtexUtils::ApplyConstFn PtexUtils::applyConstFunctions[20] = { ApplyConstN, ApplyConstN, ApplyConstN, ApplyConstN, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, ApplyConst, }; #ifndef PTEX_USE_STDSTRING Ptex::String::~String() { if (_str) free(_str); } Ptex::String& Ptex::String::operator=(const char* str) { if (_str) free(_str); _str = str ? strdup(str) : 0; return *this; } std::ostream& operator << (std::ostream& stream, const Ptex::String& str) { stream << str.c_str(); return stream; } #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexTriangleKernel.cpp0000644000175000017500000001405312271062644024737 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "PtexPlatform.h" #include "PtexUtils.h" #include "PtexHalf.h" #include "PtexTriangleKernel.h" namespace { inline double gaussian(double x_squared) { static const double scale = -0.5 * (PtexTriangleKernelWidth * PtexTriangleKernelWidth); return exp(scale * x_squared); } } namespace { // apply to 1..4 channels (unrolled channel loop) of packed data (nTxChan==nChan) // the ellipse equation, Q, is calculated via finite differences (Heckbert '89 pg 57) template void Apply(PtexTriangleKernelIter& k, double* result, void* data, int /*nChan*/, int /*nTxChan*/) { int nTxChan = nChan; double DDQ = 2*k.A; for (int vi = k.v1; vi != k.v2; vi++) { int xw = k.rowlen - vi; int x1 = PtexUtils::max(k.u1, xw-k.w2); int x2 = PtexUtils::min(k.u2, xw-k.w1); double U = x1 - k.u; double V = vi - k.v; double DQ = k.A*(2*U+1)+k.B*V; double Q = k.A*U*U + (k.B*U + k.C*V)*V; T* p = (T*)data + (vi * k.rowlen + x1) * nTxChan; T* pEnd = p + (x2-x1)*nTxChan; for (; p < pEnd; p += nTxChan) { if (Q < 1) { double weight = gaussian(Q)*k.wscale; k.weight += weight; PtexUtils::VecAccum()(result, p, weight); } Q += DQ; DQ += DDQ; } } } // apply to 1..4 channels (unrolled channel loop) w/ pixel stride template void ApplyS(PtexTriangleKernelIter& k, double* result, void* data, int /*nChan*/, int nTxChan) { double DDQ = 2*k.A; for (int vi = k.v1; vi != k.v2; vi++) { int xw = k.rowlen - vi; int x1 = PtexUtils::max(k.u1, xw-k.w2); int x2 = PtexUtils::min(k.u2, xw-k.w1); double U = x1 - k.u; double V = vi - k.v; double DQ = k.A*(2*U+1)+k.B*V; double Q = k.A*U*U + (k.B*U + k.C*V)*V; T* p = (T*)data + (vi * k.rowlen + x1) * nTxChan; T* pEnd = p + (x2-x1)*nTxChan; for (; p < pEnd; p += nTxChan) { if (Q < 1) { double weight = gaussian(Q)*k.wscale; k.weight += weight; PtexUtils::VecAccum()(result, p, weight); } Q += DQ; DQ += DDQ; } } } // apply to N channels (general case) template void ApplyN(PtexTriangleKernelIter& k, double* result, void* data, int nChan, int nTxChan) { double DDQ = 2*k.A; for (int vi = k.v1; vi != k.v2; vi++) { int xw = k.rowlen - vi; int x1 = PtexUtils::max(k.u1, xw-k.w2); int x2 = PtexUtils::min(k.u2, xw-k.w1); double U = x1 - k.u; double V = vi - k.v; double DQ = k.A*(2*U+1)+k.B*V; double Q = k.A*U*U + (k.B*U + k.C*V)*V; T* p = (T*)data + (vi * k.rowlen + x1) * nTxChan; T* pEnd = p + (x2-x1)*nTxChan; for (; p < pEnd; p += nTxChan) { if (Q < 1) { double weight = gaussian(Q)*k.wscale; k.weight += weight; PtexUtils::VecAccumN()(result, p, nChan, weight); } Q += DQ; DQ += DDQ; } } } } PtexTriangleKernelIter::ApplyFn PtexTriangleKernelIter::applyFunctions[] = { // nChan == nTxChan ApplyN, ApplyN, ApplyN, ApplyN, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, // nChan != nTxChan (need pixel stride) ApplyN, ApplyN, ApplyN, ApplyN, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, }; void PtexTriangleKernelIter::applyConst(double* dst, void* data, DataType dt, int nChan) { // iterate over texel locations and calculate weight as if texture weren't const double DDQ = 2*A; for (int vi = v1; vi != v2; vi++) { int xw = rowlen - vi; int x1 = PtexUtils::max(u1, xw-w2); int x2 = PtexUtils::min(u2, xw-w1); double U = x1 - u; double V = vi - v; double DQ = A*(2*U+1)+B*V; double Q = A*U*U + (B*U + C*V)*V; for (int x = x1; x < x2; x++) { if (Q < 1) { weight += gaussian(Q)*wscale; } Q += DQ; DQ += DDQ; } } // apply weight to single texel value PtexUtils::applyConst(weight, dst, data, dt, nChan); } openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexTriangleFilter.cpp0000644000175000017500000002040712271062644024744 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "PtexPlatform.h" #include #include #include "PtexTriangleFilter.h" #include "PtexTriangleKernel.h" #include "PtexUtils.h" namespace { inline double squared(double x) { return x*x; } } void PtexTriangleFilter::eval(float* result, int firstChan, int nChannels, int faceid, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur) { // init if (!_tx || nChannels <= 0) return; if (faceid < 0 || faceid >= _tx->numFaces()) return; _ntxchan = _tx->numChannels(); _dt = _tx->dataType(); _firstChanOffset = firstChan*DataSize(_dt); _nchan = PtexUtils::min(nChannels, _ntxchan-firstChan); // get face info const FaceInfo& f = _tx->getFaceInfo(faceid); // if neighborhood is constant, just return constant value of face if (f.isNeighborhoodConstant()) { PtexPtr data ( _tx->getData(faceid, 0) ); if (data) { char* d = (char*) data->getData() + _firstChanOffset; Ptex::ConvertToFloat(result, d, _dt, _nchan); } return; } // clamp u and v u = PtexUtils::clamp(u, 0.0f, 1.0f); v = PtexUtils::clamp(v, 0.0f, 1.0f); // build kernel PtexTriangleKernel k; buildKernel(k, u, v, uw1, vw1, uw2, vw2, width, blur, f.res); // accumulate the weight as we apply _weight = 0; // allocate temporary double-precision result _result = (double*) alloca(sizeof(double)*_nchan); memset(_result, 0, sizeof(double)*_nchan); // apply to faces splitAndApply(k, faceid, f); // normalize (both for data type and cumulative kernel weight applied) // and output result double scale = 1.0 / (_weight * OneValue(_dt)); for (int i = 0; i < _nchan; i++) result[i] = float(_result[i] * scale); // clear temp result _result = 0; } void PtexTriangleFilter::buildKernel(PtexTriangleKernel& k, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur, Res faceRes) { const double sqrt3 = 1.7320508075688772; // compute ellipse coefficients, A*u^2 + B*u*v + C*v^2 == AC - B^2/4 double scaleAC = 0.25 * width*width; double scaleB = -2 * scaleAC; double A = (vw1*vw1 + vw2*vw2) * scaleAC; double B = (uw1*vw1 + uw2*vw2) * scaleB; double C = (uw1*uw1 + uw2*uw2) * scaleAC; // convert to cartesian domain double Ac = 0.75 * A; double Bc = (sqrt3/2) * (B-A); double Cc = 0.25 * A - 0.5 * B + C; // compute min blur for eccentricity clamping const double maxEcc = 15; // max eccentricity const double eccRatio = (maxEcc*maxEcc + 1) / (maxEcc*maxEcc - 1); double X = sqrt(squared(Ac - Cc) + squared(Bc)); double b_e = 0.5 * (eccRatio * X - (Ac + Cc)); // compute min blur for texel clamping // (ensure that ellipse is no smaller than a texel) double b_t = squared(0.5 / faceRes.u()); // add blur double b_b = 0.25 * blur * blur; double b = PtexUtils::max(b_b, PtexUtils::max(b_e, b_t)); Ac += b; Cc += b; // compute minor radius double m = sqrt(2*(Ac*Cc - 0.25*Bc*Bc) / (Ac + Cc + X)); // choose desired resolution int reslog2 = PtexUtils::max(0, int(ceil(log2(0.5/m)))); // convert back to triangular domain A = (4/3.0) * Ac; B = (2/sqrt3) * Bc + A; C = -0.25 * A + 0.5 * B + Cc; // scale by kernel width double scale = PtexTriangleKernelWidth * PtexTriangleKernelWidth; A *= scale; B *= scale; C *= scale; // find u,v,w extents double uw = PtexUtils::min(sqrt(C), 1.0); double vw = PtexUtils::min(sqrt(A), 1.0); double ww = PtexUtils::min(sqrt(A-B+C), 1.0); // init kernel double w = 1 - u - v; k.set(Res(reslog2, reslog2), u, v, u-uw, v-vw, w-ww, u+uw, v+vw, w+ww, A, B, C); } void PtexTriangleFilter::splitAndApply(PtexTriangleKernel& k, int faceid, const Ptex::FaceInfo& f) { // do we need to split? if so, split kernel and apply across edge(s) if (k.u1 < 0 && f.adjface(2) >= 0) { PtexTriangleKernel ka; k.splitU(ka); applyAcrossEdge(ka, f, 2); } if (k.v1 < 0 && f.adjface(0) >= 0) { PtexTriangleKernel ka; k.splitV(ka); applyAcrossEdge(ka, f, 0); } if (k.w1 < 0 && f.adjface(1) >= 0) { PtexTriangleKernel ka; k.splitW(ka); applyAcrossEdge(ka, f, 1); } // apply to local face apply(k, faceid, f); } void PtexTriangleFilter::applyAcrossEdge(PtexTriangleKernel& k, const Ptex::FaceInfo& f, int eid) { int afid = f.adjface(eid), aeid = f.adjedge(eid); const Ptex::FaceInfo& af = _tx->getFaceInfo(afid); k.reorient(eid, aeid); splitAndApply(k, afid, af); } void PtexTriangleFilter::apply(PtexTriangleKernel& k, int faceid, const Ptex::FaceInfo& f) { // clamp kernel face (resolution and extent) k.clampRes(f.res); k.clampExtent(); // build kernel iterators PtexTriangleKernelIter keven, kodd; k.getIterators(keven, kodd); if (!keven.valid && !kodd.valid) return; // get face data, and apply PtexPtr dh ( _tx->getData(faceid, k.res) ); if (!dh) return; if (keven.valid) applyIter(keven, dh); if (kodd.valid) applyIter(kodd, dh); } void PtexTriangleFilter::applyIter(PtexTriangleKernelIter& k, PtexFaceData* dh) { if (dh->isConstant()) { k.applyConst(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan); _weight += k.weight; } else if (dh->isTiled()) { Ptex::Res tileres = dh->tileRes(); PtexTriangleKernelIter kt = k; int tileresu = tileres.u(); int tileresv = tileres.v(); kt.rowlen = tileresu; int ntilesu = k.rowlen / kt.rowlen; int wOffsetBase = k.rowlen - tileresu; for (int tilev = k.v1 / tileresv, tilevEnd = (k.v2-1) / tileresv; tilev <= tilevEnd; tilev++) { int vOffset = tilev * tileresv; kt.v = k.v - vOffset; kt.v1 = PtexUtils::max(0, k.v1 - vOffset); kt.v2 = PtexUtils::min(k.v2 - vOffset, tileresv); for (int tileu = k.u1 / tileresu, tileuEnd = (k.u2-1) / tileresu; tileu <= tileuEnd; tileu++) { int uOffset = tileu * tileresu; int wOffset = wOffsetBase - uOffset - vOffset; kt.u = k.u - uOffset; kt.u1 = PtexUtils::max(0, k.u1 - uOffset); kt.u2 = PtexUtils::min(k.u2 - uOffset, tileresu); kt.w1 = k.w1 - wOffset; kt.w2 = k.w2 - wOffset; PtexPtr th ( dh->getTile(tilev * ntilesu + tileu) ); if (th) { kt.weight = 0; if (th->isConstant()) kt.applyConst(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan); else kt.apply(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan, _ntxchan); _weight += kt.weight; } } } } else { k.apply(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan, _ntxchan); _weight += k.weight; } } openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexInt.h0000644000175000017500000000413612271062644022231 0ustar mfvmfv#ifndef PtexInt_h #define PtexInt_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ /** @file PtexInt.h @brief Portable fixed-width integer types */ #if defined(_MSC_VER) && _MSC_VER < 1600 typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #else #include #endif #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/Ptexture.h0000644000175000017500000011002212271062644022446 0ustar mfvmfv#ifndef Ptexture_h #define Ptexture_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ /** @file Ptexture.h @brief Public API classes for reading, writing, caching, and filtering Ptex files. */ #include #if defined(__FreeBSD__) #include #endif #if (defined(__FreeBSD__) && (__FreeBSD_version < 803000)) inline double log2(double x) {return log(x)*(double)1.4426950408889634;} #endif /* log2 */ #if defined(_WIN32) || defined(_WINDOWS) || defined(_MSC_VER) # ifndef PTEXAPI # ifndef PTEX_STATIC # ifdef PTEX_EXPORTS # define PTEXAPI __declspec(dllexport) # else # define PTEXAPI __declspec(dllimport) # endif # else # define PTEXAPI # endif # endif #else # ifndef PTEXAPI # define PTEXAPI # endif # ifndef DOXYGEN # define PTEX_USE_STDSTRING # endif #endif #include "PtexInt.h" #include #define PtexAPIVersion 2 #define PtexFileMajorVersion 1 #define PtexFileMinorVersion 3 /** Common data structures and enums used throughout the API. */ struct Ptex { /** Type of base mesh for which the textures are defined. A mesh can be triangle-based (with triangular textures) or quad-based (with rectangular textures). */ enum MeshType { mt_triangle, ///< Mesh is triangle-based. mt_quad ///< Mesh is quad-based. }; /** Type of data stored in texture file. */ enum DataType { dt_uint8, ///< Unsigned, 8-bit integer. dt_uint16, ///< Unsigned, 16-bit integer. dt_half, ///< Half-precision (16-bit) floating point. dt_float ///< Single-precision (32-bit) floating point. }; /** How to handle mesh border when filtering. */ enum BorderMode { m_clamp, ///< texel access is clamped to border m_black, ///< texel beyond border are assumed to be black m_periodic ///< texel access wraps to other side of face }; /** Edge IDs used in adjacency data in the Ptex::FaceInfo struct. Edge ID usage for triangle meshes is TBD. */ enum EdgeId { e_bottom, ///< Bottom edge, from UV (0,0) to (1,0) e_right, ///< Right edge, from UV (1,0) to (1,1) e_top, ///< Top edge, from UV (1,1) to (0,1) e_left ///< Left edge, from UV (0,1) to (0,0) }; /** Type of meta data entry. */ enum MetaDataType { mdt_string, ///< Null-terminated string. mdt_int8, ///< Signed 8-bit integer. mdt_int16, ///< Signed 16-bit integer. mdt_int32, ///< Signed 32-bit integer. mdt_float, ///< Single-precision (32-bit) floating point. mdt_double ///< Double-precision (32-bit) floating point. }; /** Look up name of given mesh type. */ PTEXAPI static const char* MeshTypeName(MeshType mt); /** Look up name of given data type. */ PTEXAPI static const char* DataTypeName(DataType dt); /** Look up name of given border mode. */ PTEXAPI static const char* BorderModeName(BorderMode m); /** Look up name of given edge ID. */ PTEXAPI static const char* EdgeIdName(EdgeId eid); /** Look up name of given meta data type. */ PTEXAPI static const char* MetaDataTypeName(MetaDataType mdt); /** Look up size of given data type (in bytes). */ static int DataSize(DataType dt) { static const int sizes[] = { 1,2,2,4 }; return sizes[dt]; } /** Look up value of given data type that corresponds to the normalized value of 1.0. */ static double OneValue(DataType dt) { static const double one[] = { 255.0, 65535.0, 1.0, 1.0 }; return one[dt]; } /** Lookup up inverse value of given data type that corresponds to the normalized value of 1.0. */ static double OneValueInv(DataType dt) { static const double one[] = { 1.0/255.0, 1.0/65535.0, 1.0, 1.0 }; return one[dt]; } /** Convert a number of data values from the given data type to float. */ PTEXAPI static void ConvertToFloat(float* dst, const void* src, Ptex::DataType dt, int numChannels); /** Convert a number of data values from float to the given data type. */ PTEXAPI static void ConvertFromFloat(void* dst, const float* src, Ptex::DataType dt, int numChannels); /** Pixel resolution of a given texture. The resolution is stored in log form: ulog2 = log2(ures), vlog2 = log2(vres)). Note: negative ulog2 or vlog2 values are reserved for internal use. */ struct Res { int8_t ulog2; ///< log base 2 of u resolution, in texels int8_t vlog2; ///< log base 2 of v resolution, in texels /// Default constructor, sets res to 0 (1x1 texel). Res() : ulog2(0), vlog2(0) {} /// Constructor. Res(int8_t ulog2, int8_t vlog2) : ulog2(ulog2), vlog2(vlog2) {} /// Constructor from 16-bit integer Res(uint16_t value) { ulog2 = *(uint8_t *)&value; vlog2 = *((uint8_t *)&value + 1); } /// U resolution in texels. int u() const { return 1<<(unsigned)ulog2; } /// V resolution in texels. int v() const { return 1<<(unsigned)vlog2; } /// Resolution as a single 16-bit integer value. uint16_t& val() { return *(uint16_t*)this; } /// Resolution as a single 16-bit integer value. const uint16_t& val() const { return *(uint16_t*)this; } /// Total size of specified texture in texels (u * v). int size() const { return u() * v(); } /// Comparison operator. bool operator==(const Res& r) const { return val() == r.val(); } /// Comparison operator. bool operator!=(const Res& r) const { return val() != r.val(); } /// True if res is >= given res in both u and v directions. bool operator>=(const Res& r) const { return ulog2 >= r.ulog2 && vlog2 >= r.vlog2; } /// Get value of resolution with u and v swapped. Res swappeduv() const { return Res(vlog2, ulog2); } /// Swap the u and v resolution values in place. void swapuv() { *this = swappeduv(); } /// Clamp the resolution value against the given value. void clamp(const Res& r) { if (ulog2 > r.ulog2) ulog2 = r.ulog2; if (vlog2 > r.vlog2) vlog2 = r.vlog2; } /// Determine the number of tiles in the u direction for the given tile res. int ntilesu(Res tileres) const { return 1<<(ulog2-tileres.ulog2); } /// Determine the number of tiles in the v direction for the given tile res. int ntilesv(Res tileres) const { return 1<<(vlog2-tileres.vlog2); } /// Determine the total number of tiles for the given tile res. int ntiles(Res tileres) const { return ntilesu(tileres) * ntilesv(tileres); } }; /** Information about a face, as stored in the Ptex file header. The FaceInfo data contains the face resolution and neighboring face adjacency information as well as a set of flags describing the face. The adjfaces data member contains the face ids of the four neighboring faces. The neighbors are accessed in EdgeId order, CCW, starting with the bottom edge. The adjedges data member contains the corresponding edge id for each neighboring face. If a face has no neighbor for a given edge, the adjface id should be -1, and the adjedge id doesn't matter (but is typically zero). If an adjacent face is a pair of subfaces, the id of the first subface as encountered in a CCW traversal should be stored as the adjface id. */ struct FaceInfo { Res res; ///< Resolution of face. uint8_t adjedges; ///< Adjacent edges, 2 bits per edge. uint8_t flags; ///< Flags. int32_t adjfaces[4]; ///< Adjacent faces (-1 == no adjacent face). /// Default constructor, sets all members to zero. FaceInfo() : res(), adjedges(0), flags(0) { adjfaces[0] = adjfaces[1] = adjfaces[2] = adjfaces[3] = -1; } /// Constructor. FaceInfo(Res res) : res(res), adjedges(0), flags(0) { adjfaces[0] = adjfaces[1] = adjfaces[2] = adjfaces[3] = -1; } /// Constructor. FaceInfo(Res res, int adjfaces[4], int adjedges[4], bool isSubface=false) : res(res), flags(isSubface ? flag_subface : 0) { setadjfaces(adjfaces[0], adjfaces[1], adjfaces[2], adjfaces[3]); setadjedges(adjedges[0], adjedges[1], adjedges[2], adjedges[3]); } /// Access an adjacent edge id. The eid value must be 0..3. EdgeId adjedge(int eid) const { return EdgeId((adjedges >> (2*eid)) & 3); } /// Access an adjacent face id. The eid value must be 0..3. int adjface(int eid) const { return adjfaces[eid]; } /// Determine if face is constant (by checking a flag). bool isConstant() const { return (flags & flag_constant) != 0; } /// Determine if neighborhood of face is constant (by checking a flag). bool isNeighborhoodConstant() const { return (flags & flag_nbconstant) != 0; } /// Determine if face has edits in the file (by checking a flag). bool hasEdits() const { return (flags & flag_hasedits) != 0; } /// Determine if face is a subface (by checking a flag). bool isSubface() const { return (flags & flag_subface) != 0; } /// Set the adjfaces data. void setadjfaces(int f0, int f1, int f2, int f3) { adjfaces[0] = f0, adjfaces[1] = f1, adjfaces[2] = f2; adjfaces[3] = f3; } /// Set the adjedges data. void setadjedges(int e0, int e1, int e2, int e3) { adjedges = (e0&3) | ((e1&3)<<2) | ((e2&3)<<4) | ((e3&3)<<6); } /// Flag bit values (for internal use). enum { flag_constant = 1, flag_hasedits = 2, flag_nbconstant = 4, flag_subface = 8 }; }; /** Memory-managed string. Used for returning error messages from API functions. On most platforms, this is a typedef to std::string. For Windows, this is a custom class that implements a subset of std::string. (Note: std::string cannot be passed through a Windows DLL interface). */ #ifdef PTEX_USE_STDSTRING typedef std::string String; #else class String { public: String() : _str(0) {} String(const String& str) : _str(0) { *this = str; } PTEXAPI ~String(); PTEXAPI String& operator=(const char* str); String& operator=(const String& str) { *this = str._str; return *this; } const char* c_str() const { return _str ? _str : ""; } bool empty() const { return _str == 0; } private: char* _str; }; #endif } #ifndef DOXYGEN ; #endif /// std::stream output operator. \relates Ptex::String #ifndef PTEX_USE_STDSTRING std::ostream& operator << (std::ostream& stream, const Ptex::String& str); #endif /** @class PtexMetaData @brief Meta data accessor Meta data is acquired from PtexTexture and accessed through this interface. */ class PtexMetaData { protected: /// Destructor not for public use. Use release() instead. virtual ~PtexMetaData() {} public: /// Release resources held by this pointer (pointer becomes invalid). virtual void release() = 0; /// Query number of meta data entries stored in file. virtual int numKeys() = 0; /// Query the name and type of a meta data entry. virtual void getKey(int n, const char*& key, Ptex::MetaDataType& type) = 0; /** Query the value of a given meta data entry. If the key doesn't exist or the type doesn't match, value is set to null */ virtual void getValue(const char* key, const char*& value) = 0; /** Query the value of a given meta data entry. If the key doesn't exist or the type doesn't match, value is set to null */ virtual void getValue(const char* key, const int8_t*& value, int& count) = 0; /** Query the value of a given meta data entry. If the key doesn't exist or the type doesn't match, value is set to null */ virtual void getValue(const char* key, const int16_t*& value, int& count) = 0; /** Query the value of a given meta data entry. If the key doesn't exist or the type doesn't match, value is set to null */ virtual void getValue(const char* key, const int32_t*& value, int& count) = 0; /** Query the value of a given meta data entry. If the key doesn't exist or the type doesn't match, value is set to null */ virtual void getValue(const char* key, const float*& value, int& count) = 0; /** Query the value of a given meta data entry. If the key doesn't exist or the type doesn't match, value is set to null */ virtual void getValue(const char* key, const double*& value, int& count) = 0; }; /** @class PtexFaceData @brief Per-face texture data accessor Per-face texture data is acquired from PtexTexture and accessed through this interface. This interface provides low-level access to the data as stored on disk for maximum efficiency. If this isn't needed, face data can be more conveniently read directly from PtexTexture. */ class PtexFaceData { protected: /// Destructor not for public use. Use release() instead. virtual ~PtexFaceData() {} public: /// Release resources held by this pointer (pointer becomes invalid). virtual void release() = 0; /** True if this data block is constant. */ virtual bool isConstant() = 0; /** Resolution of the texture held by this data block. Note: the indicated texture res may be larger than 1x1 even if the texture data is constant. */ virtual Ptex::Res res() = 0; /** Read a single texel from the data block. The texel coordinates, u and v, have a range of [0..ures-1, 0..vres-1]. Note: this method will work correctly even if the face is constant or tiled. */ virtual void getPixel(int u, int v, void* result) = 0; /** Access the data from this data block. If the data block is constant, getData will return a pointer to a single texel's data value. If the data block is tiled, then getData will return null and the data must be accessed per-tile via the getTile() function. */ virtual void* getData() = 0; /** True if this data block is tiled. If tiled, the data must be access per-tile via getTile(). */ virtual bool isTiled() = 0; /** Resolution of each tile in this data block. */ virtual Ptex::Res tileRes() = 0; /** Access a tile from the data block. Tiles are accessed in v-major order. */ virtual PtexFaceData* getTile(int tile) = 0; }; /** @class PtexTexture @brief Interface for reading data from a ptex file PtexTexture instances can be acquired via the static open() method, or via the PtexCache interface. Data access through this interface is returned in v-major order with all data channels interleaved per texel. */ class PtexTexture { protected: /// Destructor not for public use. Use release() instead. virtual ~PtexTexture() {} public: /** Open a ptex file for reading. If an error occurs, an error message will be stored in the error string param and the a pointer will be returned. If the premultiply param is set to true and the texture file has a specified alpha channel, then all data stored in the file will be multiplied by alpha when read from disk. If premultiply is false, then the full-resolution textures will be returned as stored on disk which is assumed to be unmultiplied. Reductions (both stored mip-maps and dynamically generated reductions) are always premultiplied with alpha. See PtexWriter for more information about alpha channels. */ PTEXAPI static PtexTexture* open(const char* path, Ptex::String& error, bool premultiply=0); /// Release resources held by this pointer (pointer becomes invalid). virtual void release() = 0; /** Path that file was opened with. If the file was opened using a search path (via PtexCache), the the path will be the path as found in the search path. Otherwise, the path will be the path as supplied to open. */ virtual const char* path() = 0; /** Type of mesh for which texture data is defined. */ virtual Ptex::MeshType meshType() = 0; /** Type of data stored in file. */ virtual Ptex::DataType dataType() = 0; /** Mode for filtering texture access beyond mesh border. */ virtual Ptex::BorderMode uBorderMode() = 0; /** Mode for filtering texture access beyond mesh border. */ virtual Ptex::BorderMode vBorderMode() = 0; /** Index of alpha channel (if any). One channel in the file can be flagged to be the alpha channel. If no channel is acting as the alpha channel, -1 is returned. See PtexWriter for more details. */ virtual int alphaChannel() = 0; /** Number of channels stored in file. */ virtual int numChannels() = 0; /** Number of faces stored in file. */ virtual int numFaces() = 0; /** True if the file has edit blocks. See PtexWriter for more details. */ virtual bool hasEdits() = 0; /** True if the file has mipmaps. See PtexWriter for more details. */ virtual bool hasMipMaps() = 0; /** Access meta data. */ virtual PtexMetaData* getMetaData() = 0; /** Access resolution and adjacency information about a face. */ virtual const Ptex::FaceInfo& getFaceInfo(int faceid) = 0; /** Access texture data for a face at highest-resolution. The texture data is copied into the user-supplied buffer. The buffer must be at least this size (in bytes): DataSize(dataType()) * numChannels() * getFaceInfo(faceid).res.size(). If a stride is given, then (stride-row_length) bytes will be skipped after each row. If stride is zero, then no bytes will be skipped. Note: the image can be flipped vertically by using an appropriate negative stride value. @param faceid Face index [0..numFaces-1] @param buffer User-supplied buffer @param stride Size of each row in user buffer (in bytes) */ virtual void getData(int faceid, void* buffer, int stride) = 0; /** Access texture data for a face at a specific resolution. The specified resolution may be lower than the full resolution for the face. If it is lower, then the texture data is accessed from the stored mip-maps. If the requested resolution doesn't match a stored resolution, the desired resolution will be generated from the nearest available resolution. See previous getData() method for interface details. */ virtual void getData(int faceid, void* buffer, int stride, Ptex::Res res) = 0; /** Access texture data for a face at highest-resolution as stored on disk. */ virtual PtexFaceData* getData(int faceid) = 0; /** Access texture data for a face at a specific resolution as stored on disk. The specified resolution may be lower (but not higher) than the full resolution for the face. If it is lower, then the texture data is accessed from the stored mip-maps. If the requested resolution doesn't match a stored resolution, the desired resolution will be generated from the nearest available resolution. */ virtual PtexFaceData* getData(int faceid, Ptex::Res res) = 0; /** Access a single texel from the highest resolution texture . The texel data is converted to floating point (integer types are normalized 0.0 to 1.0). A subset of the available channels may be accessed. @param faceid Face index [0..numFaces-1] @param u U coordinate [0..ures-1] @param v V coordinate [0..vres-1] @param result Result data @param firstchan First channel to access [0..numChannels-1] @param nchannels Number of channels to access. */ virtual void getPixel(int faceid, int u, int v, float* result, int firstchan, int nchannels) = 0; /** Access a single texel for a face at a particular resolution. The specified resolution may be lower (but not higher) than the full resolution for the face. If it is lower, then the texture data is accessed from the stored mip-maps. If the requested resolution doesn't match a stored resolution, the desired resolution will be generated from the nearest available resolution. See previous getPixel() method for details. */ virtual void getPixel(int faceid, int u, int v, float* result, int firstchan, int nchannels, Ptex::Res res) = 0; }; /** @class PtexInputHandler @brief Custom handler interface for intercepting and redirecting Ptex input stream calls A custom instance of this class can be defined and supplied to the PtexCache class. Files accessed through the cache will have their input streams redirected through this interface. */ class PtexInputHandler { protected: virtual ~PtexInputHandler() {} public: typedef void* Handle; /** Open a file in read mode. Returns null if there was an error. If an error occurs, the error string is available via lastError(). */ virtual Handle open(const char* path) = 0; /** Seek to an absolute byte position in the input stream. */ virtual void seek(Handle handle, int64_t pos) = 0; /** Read a number of bytes from the file. Returns the number of bytes successfully read. If less than the requested number of bytes is read, the error string is available via lastError(). */ virtual size_t read(void* buffer, size_t size, Handle handle) = 0; /** Close a file. Returns false if an error occurs, and the error string is available via lastError(). */ virtual bool close(Handle handle) = 0; /** Return the last error message encountered. */ virtual const char* lastError() = 0; }; /** @class PtexCache @brief File-handle and memory cache for reading ptex files The PtexCache class allows cached read access to multiple ptex files while constraining the open file count and memory usage to specified limits. File and data objects accessed via the cache are added back to the cache when their release method is called. Released objects are maintained in an LRU list and only destroyed when the specified resource limits are exceeded. The cache is fully multi-threaded. Cached data will be shared among all threads that have access to the cache, and the data are protected with internal locks. See PtexCache.cpp for details about the caching and locking implementation. */ class PtexCache { protected: /// Destructor not for public use. Use release() instead. virtual ~PtexCache() {} public: /** Create a cache with the specified limits. @param maxFiles Maximum open file handles. If unspecified, limit is set to 100 open files. @param maxMem Maximum allocated memory, in bytes. If unspecified, limit is set to 100MB. @param premultiply If true, textures will be premultiplied by the alpha channel (if any) when read from disk. See PtexTexture and PtexWriter for more details. @param handler If specified, all input calls made through this cache will be directed through the handler. */ PTEXAPI static PtexCache* create(int maxFiles=0, int maxMem=0, bool premultiply=false, PtexInputHandler* handler=0); /// Release resources held by this pointer (pointer becomes invalid). virtual void release() = 0; /** Set a search path for finding textures. Note: if an input handler is installed the search path will be ignored. @param path colon-delimited search path. */ virtual void setSearchPath(const char* path) = 0; /** Query the search path. Returns string set via setSearchPath. */ virtual const char* getSearchPath() = 0; /** Open a texture. If the specified path was previously opened, and the open file limit hasn't been exceeded, then a pointer to the already open file will be returned. If the specified path hasn't been opened yet or was closed, either to maintain the open file limit or because the file was explicitly purged from the cache, then the file will be newly opened. If the path is relative (i.e. doesn't begin with a '/') then the search path will be used to locate the file. The texture file will stay open until the PtexTexture::release method is called, at which point the texture will be returned to the cache. Once released, the file will be closed when either the file handle limit is reached, the cached is released, or when the texture is purged (see purge methods below). If texture could not be opened, null will be returned and an error string will be set. @param path File path. If path is relative, search path will be used to find the file. @param error Error string set if texture could not be opened. */ virtual PtexTexture* get(const char* path, Ptex::String& error) = 0; /** Remove a texture file from the cache. The texture file will remain open and accessible until the file handle is released, but any future cache accesses for that file will open the file anew. */ virtual void purge(PtexTexture* texture) = 0; /** Remove a texture file from the cache by pathname. The path must match the full path as opened. This function will not search for the file, but if a search path was used, the path must match the path as found by the search path. */ virtual void purge(const char* path) = 0; /** Remove all texture files from the cache. Open files with active PtexTexture* handles remain open until released. */ virtual void purgeAll() = 0; }; /** @class PtexWriter @brief Interface for writing data to a ptex file. Note: if an alpha channel is specified, then the textures being written to the file are expected to have unmultiplied-alpha data. Generated mipmaps will be premultiplied by the Ptex library. On read, PtexTexture will (if requested) premultiply all textures by alpha when getData is called; by default only reductions are premultiplied. If the source textures are already premultiplied, then alphachan can be set to -1 and the library will just leave all the data as-is. The only reason to store unmultiplied-alpha textures in the file is to preserve the original texture data for later editing. */ class PtexWriter { protected: /// Destructor not for public use. Use release() instead. virtual ~PtexWriter() {} public: /** Open a new texture file for writing. @param path Path to file. @param mt Type of mesh for which the textures are defined. @param dt Type of data stored within file. @param nchannels Number of data channels. @param alphachan Index of alpha channel, [0..nchannels-1] or -1 if no alpha channel is present. @param nfaces Number of faces in mesh. @param error String containing error message if open failed. @param genmipmaps Specify true if mipmaps should be generated. */ PTEXAPI static PtexWriter* open(const char* path, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces, Ptex::String& error, bool genmipmaps=true); /** Open an existing texture file for writing. If the incremental param is specified as true, then data values written to the file are appended to the file as "edit blocks". This is the fastest way to write data to the file, but edit blocks are slower to read back, and they have no mipmaps so filtering can be inefficient. If incremental is false, then the edits are applied to the file and the entire file is regenerated on close as if it were written all at once with open(). If the file doesn't exist it will be created and written as if open() were used. If the file exists, the mesh type, data type, number of channels, alpha channel, and number of faces must agree with those stored in the file. */ PTEXAPI static PtexWriter* edit(const char* path, bool incremental, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces, Ptex::String& error, bool genmipmaps=true); /** Apply edits to a file. If a file has pending edits, the edits will be applied and the file will be regenerated with no edits. This is equivalent to calling edit() with incremental set to false. The advantage is that the file attributes such as mesh type, data type, etc., don't need to be known in advance. */ PTEXAPI static bool applyEdits(const char* path, Ptex::String& error); /** Release resources held by this pointer (pointer becomes invalid). */ virtual void release() = 0; /** Set border modes */ virtual void setBorderModes(Ptex::BorderMode uBorderMode, Ptex::BorderMode vBorderMode) = 0; /** Write a string as meta data. Both the key and string params must be null-terminated strings. */ virtual void writeMeta(const char* key, const char* string) = 0; /** Write an array of signed 8-bit integers as meta data. The key must be a null-terminated string. */ virtual void writeMeta(const char* key, const int8_t* value, int count) = 0; /** Write an array of signed 16-bit integers as meta data. The key must be a null-terminated string. */ virtual void writeMeta(const char* key, const int16_t* value, int count) = 0; /** Write an array of signed 32-bit integers as meta data. The key must be a null-terminated string. */ virtual void writeMeta(const char* key, const int32_t* value, int count) = 0; /** Write an array of signed 32-bit floats as meta data. The key must be a null-terminated string. */ virtual void writeMeta(const char* key, const float* value, int count) = 0; /** Write an array of signed 32-bit doubles as meta data. The key must be a null-terminated string. */ virtual void writeMeta(const char* key, const double* value, int count) = 0; /** Copy meta data from an existing meta data block. */ virtual void writeMeta(PtexMetaData* data) = 0; /** Write texture data for a face. The data is assumed to be channel-interleaved per texel and stored in v-major order. @param faceid Face index [0..nfaces-1]. @param info Face resolution and adjacency information. @param data Texel data. @param stride Distance between rows, in bytes (if zero, data is assumed packed). If an error is encountered while writing, false is returned and an error message can be when close is called. */ virtual bool writeFace(int faceid, const Ptex::FaceInfo& info, const void* data, int stride=0) = 0; /** Write constant texture data for a face. The data is written as a single constant texel value. Note: the resolution specified in the info param may indicate a resolution greater than 1x1 and the value will be preserved when reading. This is useful to indicate a texture's logical resolution even when the data is constant. */ virtual bool writeConstantFace(int faceid, const Ptex::FaceInfo& info, const void* data) = 0; /** Close the file. This operation can take some time if mipmaps are being generated or if there are many edit blocks. If an error occurs while writing, false is returned and an error string is written into the error parameter. */ virtual bool close(Ptex::String& error) = 0; #if NEW_API virtual bool writeFaceReduction(int faceid, const Ptex::Res& res, const void* data, int stride=0) = 0; virtual bool writeConstantFaceReduction(int faceid, const Ptex::Res& res, const void* data) = 0; #endif }; /** @class PtexFilter @brief Interface for filtered sampling of ptex data files. PtexFilter instances are obtained by calling one of the particular static methods. When finished using the filter, it must be returned to the library using release(). To apply the filter to a ptex data file, use the eval() method. */ class PtexFilter { protected: /// Destructor not for public use. Use release() instead. virtual ~PtexFilter() {} public: /// Filter types enum FilterType { f_point, ///< Point-sampled (no filtering) f_bilinear, ///< Bi-linear interpolation f_box, ///< Box filter f_gaussian, ///< Gaussian filter f_bicubic, ///< General bi-cubic filter (uses sharpness option) f_bspline, ///< BSpline (equivalent to bi-cubic w/ sharpness=0) f_catmullrom, ///< Catmull-Rom (equivalent to bi-cubic w/ sharpness=1) f_mitchell ///< Mitchell (equivalent to bi-cubic w/ sharpness=2/3) }; /// Choose filter options struct Options { int __structSize; ///< (for internal use only) FilterType filter; ///< Filter type. bool lerp; ///< Interpolate between mipmap levels. float sharpness; ///< Filter sharpness, 0..1 (for general bi-cubic filter only). /// Constructor - sets defaults Options(FilterType filter=f_box, bool lerp=0, float sharpness=0) : __structSize(sizeof(Options)), filter(filter), lerp(lerp), sharpness(sharpness) {} }; /* Construct a filter for the given texture. */ PTEXAPI static PtexFilter* getFilter(PtexTexture* tx, const Options& opts); /** Release resources held by this pointer (pointer becomes invalid). */ virtual void release() = 0; /** Apply filter to a ptex data file. The filter region is a parallelogram centered at the given (u,v) coordinate with sides defined by two vectors [uw1, vw1] and [uw2, vw2]. For an axis-aligned rectangle, the vectors are [uw, 0] and [0, vw]. See \link filterfootprint Filter Footprint \endlink for details. @param result Buffer to hold filter result. Must be large enough to hold nchannels worth of data. @param firstchan First channel to evaluate [0..tx->numChannels()-1] @param nchannels Number of channels to evaluate @param faceid Face index [0..tx->numFaces()-1] @param u U coordinate, normalized [0..1] @param v V coordinate, normalized [0..1] @param uw1 U filter width 1, normalized [0..1] @param vw1 V filter width 1, normalized [0..1] @param uw2 U filter width 2, normalized [0..1] @param vw2 V filter width 2, normalized [0..1] @param width scale factor for filter width @param blur amount to add to filter width [0..1] */ virtual void eval(float* result, int firstchan, int nchannels, int faceid, float u, float v, float uw1, float vw1, float uw2, float vw2, float width=1, float blur=0) = 0; }; /** @class PtexPtr @brief Smart-pointer for acquiring and releasing API objects All public API objects must be released back to the Ptex library via the release() method. This smart-pointer class can wrap any of the Ptex API objects and will automatically release the object when the pointer goes out of scope. Usage of PtexPtr is optional, but recommended. Note: for efficiency and safety, PtexPtr is noncopyable. However, ownership can be transferred between PtexPtr instances via the PtexPtr::swap member function. Example: \code { Ptex::String error; PtexPtr inptx(PtexTexture::open(inptxname, error)); if (!inptx) { std::cerr << error << std::endl; } else { // read some data inptx->getData(faceid, buffer, stride); } } \endcode */ template class PtexPtr { T* _ptr; public: /// Constructor. PtexPtr(T* ptr=0) : _ptr(ptr) {} /// Destructor, calls ptr->release(). ~PtexPtr() { if (_ptr) _ptr->release(); } /// Use as pointer value. operator T* () { return _ptr; } /// Access members of pointer. T* operator-> () { return _ptr; } /// Get pointer value. T* get() { return _ptr; } /// Swap pointer values. void swap(PtexPtr& p) { T* tmp = p._ptr; p._ptr = _ptr; _ptr = tmp; } private: /// Copying prohibited PtexPtr(const PtexPtr& p); /// Assignment prohibited void operator= (PtexPtr& p); }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexWriter.h0000644000175000017500000001705012271062644022752 0ustar mfvmfv#ifndef PtexWriter_h #define PtexWriter_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "PtexPlatform.h" #include #include #include #include #include "Ptexture.h" #include "PtexIO.h" #include "PtexReader.h" class PtexWriterBase : public PtexWriter, public PtexIO { public: virtual void setBorderModes(Ptex::BorderMode uBorderMode, Ptex::BorderMode vBorderMode) { _extheader.ubordermode = uBorderMode; _extheader.vbordermode = vBorderMode; } virtual void writeMeta(const char* key, const char* value); virtual void writeMeta(const char* key, const int8_t* value, int count); virtual void writeMeta(const char* key, const int16_t* value, int count); virtual void writeMeta(const char* key, const int32_t* value, int count); virtual void writeMeta(const char* key, const float* value, int count); virtual void writeMeta(const char* key, const double* value, int count); virtual void writeMeta(PtexMetaData* data); virtual bool close(Ptex::String& error); virtual void release(); bool ok(Ptex::String& error) { if (!_ok) getError(error); return _ok; } void getError(Ptex::String& error) { error = (_error + "\nPtex file: " + _path).c_str(); } protected: struct MetaEntry { std::string key; MetaDataType datatype; std::vector data; MetaEntry() : datatype(MetaDataType(0)), data() {} }; virtual void finish() = 0; PtexWriterBase(const char* path, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces, bool compress); virtual ~PtexWriterBase(); int writeBlank(FILE* fp, int size); int writeBlock(FILE* fp, const void* data, int size); int writeZipBlock(FILE* fp, const void* data, int size, bool finish=true); int readBlock(FILE* fp, void* data, int size); int copyBlock(FILE* dst, FILE* src, FilePos pos, int size); Res calcTileRes(Res faceres); virtual void addMetaData(const char* key, MetaDataType t, const void* value, int size); void writeConstFaceBlock(FILE* fp, const void* data, FaceDataHeader& fdh); void writeFaceBlock(FILE* fp, const void* data, int stride, Res res, FaceDataHeader& fdh); void writeFaceData(FILE* fp, const void* data, int stride, Res res, FaceDataHeader& fdh); void writeReduction(FILE* fp, const void* data, int stride, Res res); int writeMetaDataBlock(FILE* fp, MetaEntry& val); void setError(const std::string& error) { _error = error; _ok = false; } bool storeFaceInfo(int faceid, FaceInfo& dest, const FaceInfo& src, int flags=0); bool _ok; // true if no error has occurred std::string _error; // the error text (if any) std::string _path; // file path std::string _tilepath; // temp tile file path (".tiles.tmp") FILE* _tilefp; // temp tile file handle Header _header; // the file header ExtHeader _extheader; // extended header int _pixelSize; // size of a pixel in bytes std::vector _metadata; // meta data waiting to be written std::map _metamap; // for preventing duplicate keys z_stream_s _zstream; // libzip compression stream PtexUtils::ReduceFn* _reduceFn; }; class PtexMainWriter : public PtexWriterBase { public: PtexMainWriter(const char* path, PtexTexture* tex, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces, bool genmipmaps); virtual bool close(Ptex::String& error); virtual bool writeFace(int faceid, const FaceInfo& f, const void* data, int stride); virtual bool writeConstantFace(int faceid, const FaceInfo& f, const void* data); protected: virtual ~PtexMainWriter(); virtual void addMetaData(const char* key, MetaDataType t, const void* value, int size) { PtexWriterBase::addMetaData(key, t, value, size); _hasNewData = true; } private: virtual void finish(); void generateReductions(); void flagConstantNeighorhoods(); void storeConstValue(int faceid, const void* data, int stride, Res res); void writeMetaData(FILE* fp); std::string _newpath; // path to ".new" file std::string _tmppath; // temp file path (".tmp") FILE* _tmpfp; // temp file handle bool _hasNewData; // true if data has been written bool _genmipmaps; // true if mipmaps should be generated std::vector _faceinfo; // info about each face std::vector _constdata; // constant data for each face std::vector _rfaceids; // faceid reordering for reduction levels std::vector _faceids_r; // faceid indexed by rfaceid static const int MinReductionLog2 =2; // log2(minimum reduction size) - can tune struct LevelRec { // note: level 0 is ordered by faceid // levels 1+ are reduction levels (half res in both u and v) and // are ordered by rfaceid[faceid]. Also, faces with a minimum // dimension (the smaller of u or v) smaller than MinReductionLog2 // are omitted from subsequent levels. std::vector pos; // position of data blocks within _tmp file std::vector fdh; // face data headers }; std::vector _levels; // info about each level std::vector _rpos; // reduction file positions PtexReader* _reader; // reader for accessing existing data in file }; class PtexIncrWriter : public PtexWriterBase { public: PtexIncrWriter(const char* path, FILE* fp, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces); virtual bool close(Ptex::String& error); virtual bool writeFace(int faceid, const FaceInfo& f, const void* data, int stride); virtual bool writeConstantFace(int faceid, const FaceInfo& f, const void* data); protected: void writeMetaDataEdit(); virtual void finish(); virtual ~PtexIncrWriter(); private: FILE* _fp; // the file being edited }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexReader.cpp0000644000175000017500000011735112271062644023240 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "PtexPlatform.h" #include #include #include #include #include "filesystem.h" #include "Ptexture.h" #include "PtexUtils.h" #include "PtexReader.h" namespace { class DefaultInputHandler : public PtexInputHandler { public: virtual Handle open(const char* path) { return (Handle) OIIO::Filesystem::fopen(path, "rb"); } virtual void seek(Handle handle, int64_t pos) { fseeko((FILE*)handle, pos, SEEK_SET); } virtual size_t read(void* buffer, size_t size, Handle handle) { return fread(buffer, size, 1, (FILE*)handle) == 1 ? size : 0; } virtual bool close(Handle handle) { return fclose((FILE*)handle); } virtual const char* lastError() { return strerror(errno); } } defaultInputHandler; } PtexTexture* PtexTexture::open(const char* path, Ptex::String& error, bool premultiply) { // create a private cache and use it to open the file PtexCache* cache = PtexCache::create(1, 1024*1024, premultiply); PtexTexture* file = cache->get(path, error); // make reader own the cache (so it will delete it later) PtexReader* reader = dynamic_cast (file); if (reader) reader->setOwnsCache(); // and purge cache so cache doesn't try to hold reader open cache->purgeAll(); return file; } bool PtexReader::open(const char* path, Ptex::String& error) { if (!LittleEndian()) { error = "Ptex library doesn't currently support big-endian cpu's"; return 0; } _path = path; _fp = _io->open(path); if (!_fp) { std::string errstr = "Can't open ptex file: "; errstr += path; errstr += "\n"; errstr += _io->lastError(); error = errstr.c_str(); return 0; } readBlock(&_header, HeaderSize); if (_header.magic != Magic) { std::string errstr = "Not a ptex file: "; errstr += path; error = errstr.c_str(); return 0; } if (_header.version != 1) { char ver[21]; snprintf(ver, 20, "%d", _header.version); std::string errstr = "Unsupported ptex file version ("; errstr += ver; errstr += "): "; errstr += path; error = errstr.c_str(); return 0; } _pixelsize = _header.pixelSize(); // read extended header memset(&_extheader, 0, sizeof(_extheader)); readBlock(&_extheader, PtexUtils::min(uint32_t(ExtHeaderSize), _header.extheadersize)); // compute offsets of various blocks FilePos pos = tell(); _faceinfopos = pos; pos += _header.faceinfosize; _constdatapos = pos; pos += _header.constdatasize; _levelinfopos = pos; pos += _header.levelinfosize; _leveldatapos = pos; pos += _header.leveldatasize; _metadatapos = pos; pos += _header.metadatazipsize; pos += sizeof(uint64_t); // compatibility barrier _lmdheaderpos = pos; pos += _extheader.lmdheaderzipsize; _lmddatapos = pos; pos += _extheader.lmddatasize; // edit data may not start immediately if additional sections have been added // use value from extheader if present (and > pos) _editdatapos = PtexUtils::max(FilePos(_extheader.editdatapos), pos); // read basic file info readFaceInfo(); readConstData(); readLevelInfo(); readEditData(); // an error occurred while reading the file if (!_ok) { error = _error.c_str(); return 0; } return 1; } PtexReader::PtexReader(void** parent, PtexCacheImpl* cache, bool premultiply, PtexInputHandler* io) : PtexCachedFile(parent, cache), _io(io ? io : &defaultInputHandler), _premultiply(premultiply), _ownsCache(false), _ok(true), _fp(0), _pos(0), _pixelsize(0), _constdata(0), _metadata(0), _hasEdits(false) { memset(&_header, 0, sizeof(_header)); memset(&_zstream, 0, sizeof(_zstream)); inflateInit(&_zstream); } PtexReader::~PtexReader() { if (_fp) _io->close(_fp); // we can free the const data directly since we own it (it doesn't go through the cache) if (_constdata) free(_constdata); // the rest must be orphaned since there may still be references outstanding orphanList(_levels); for (ReductionMap::iterator i = _reductions.begin(); i != _reductions.end(); i++) { FaceData* f = i->second; if (f) f->orphan(); } if (_metadata) { _metadata->orphan(); _metadata = 0; } inflateEnd(&_zstream); if (_ownsCache) _cache->setPendingDelete(); } void PtexReader::release() { PtexCacheImpl* cache = _cache; { // create local scope for cache lock AutoLockCache lock(cache->cachelock); unref(); } // If this reader owns the cache, then releasing it may cause deletion of the // reader and thus flag the cache for pending deletion. Call the cache // to handle the pending deletion. cache->handlePendingDelete(); } const Ptex::FaceInfo& PtexReader::getFaceInfo(int faceid) { if (faceid >= 0 && uint32_t(faceid) < _faceinfo.size()) return _faceinfo[faceid]; static Ptex::FaceInfo dummy; return dummy; } void PtexReader::readFaceInfo() { if (_faceinfo.empty()) { // read compressed face info block seek(_faceinfopos); int nfaces = _header.nfaces; _faceinfo.resize(nfaces); readZipBlock(&_faceinfo[0], _header.faceinfosize, sizeof(FaceInfo)*nfaces); // generate rfaceids _rfaceids.resize(nfaces); std::vector faceids_r(nfaces); PtexUtils::genRfaceids(&_faceinfo[0], nfaces, &_rfaceids[0], &faceids_r[0]); // store face res values indexed by rfaceid _res_r.resize(nfaces); for (int i = 0; i < nfaces; i++) _res_r[i] = _faceinfo[faceids_r[i]].res; } } void PtexReader::readLevelInfo() { if (_levelinfo.empty()) { // read level info block seek(_levelinfopos); _levelinfo.resize(_header.nlevels); readBlock(&_levelinfo[0], LevelInfoSize*_header.nlevels); // initialize related data _levels.resize(_header.nlevels); _levelpos.resize(_header.nlevels); FilePos pos = _leveldatapos; for (int i = 0; i < _header.nlevels; i++) { _levelpos[i] = pos; pos += _levelinfo[i].leveldatasize; } } } void PtexReader::readConstData() { if (!_constdata) { // read compressed constant data block seek(_constdatapos); int size = _pixelsize * _header.nfaces; _constdata = (uint8_t*) malloc(size); readZipBlock(_constdata, _header.constdatasize, size); if (_premultiply && _header.hasAlpha()) PtexUtils::multalpha(_constdata, _header.nfaces, _header.datatype, _header.nchannels, _header.alphachan); } } PtexMetaData* PtexReader::getMetaData() { AutoLockCache locker(_cache->cachelock); if (_metadata) _metadata->ref(); else readMetaData(); return _metadata; } PtexReader::MetaData::Entry* PtexReader::MetaData::getEntry(const char* key) { MetaMap::iterator iter = _map.find(key); if (iter == _map.end()) { // not found return 0; } Entry* e = &iter->second; if (!e->isLmd) { // normal (small) meta data - just return directly return e; } // large meta data - may not be read in yet AutoLockCache lock(_cache->cachelock); if (e->lmdData) { // already in memory, add a ref e->lmdData->ref(); _lmdRefs.push_back(e->lmdData); return e; } else { // not present, must read from file // temporarily release cache lock so other threads can proceed _cache->cachelock.unlock(); // get read lock and make sure we still need to read AutoMutex locker(_reader->readlock); if (e->lmdData) { // another thread must have read it while we were waiting _cache->cachelock.lock(); // make sure it's still there now that we have the lock if (e->lmdData) { e->data = e->lmdData->data(); _lmdRefs.push_back(e->lmdData); e->lmdData->ref(); return e; } } // go ahead and read, keep local until finished LargeMetaData*& parent = e->lmdData; LargeMetaData* volatile lmdData = new LargeMetaData((void**)&parent, _cache, e->datasize); e->data = lmdData->data(); _reader->seek(e->lmdPos); _reader->readZipBlock(e->data, e->lmdZipSize, e->datasize); // reacquire cache lock and update entry _cache->cachelock.lock(); e->lmdData = lmdData; return e; } } void PtexReader::readMetaData() { // temporarily release cache lock so other threads can proceed _cache->cachelock.unlock(); // get read lock and make sure we still need to read AutoMutex locker(readlock); if (_metadata) { // another thread must have read it while we were waiting _cache->cachelock.lock(); // make sure it's still there now that we have the lock if (_metadata) { _metadata->ref(); return; } _cache->cachelock.unlock(); } // compute total size (including edit blocks) for cache tracking int totalsize = _header.metadatamemsize; for (size_t i = 0, size = _metaedits.size(); i < size; i++) totalsize += _metaedits[i].memsize; // allocate new meta data (keep local until fully initialized) MetaData* volatile newmeta = new MetaData(&_metadata, _cache, totalsize, this); // read primary meta data blocks if (_header.metadatamemsize) readMetaDataBlock(newmeta, _metadatapos, _header.metadatazipsize, _header.metadatamemsize); // read large meta data headers if (_extheader.lmdheadermemsize) readLargeMetaDataHeaders(newmeta, _lmdheaderpos, _extheader.lmdheaderzipsize, _extheader.lmdheadermemsize); // read meta data edits for (size_t i = 0, size = _metaedits.size(); i < size; i++) readMetaDataBlock(newmeta, _metaedits[i].pos, _metaedits[i].zipsize, _metaedits[i].memsize); // store meta data _cache->cachelock.lock(); _metadata = newmeta; // clean up unused data _cache->purgeData(); } void PtexReader::readMetaDataBlock(MetaData* metadata, FilePos pos, int zipsize, int memsize) { seek(pos); // read from file bool useMalloc = memsize > AllocaMax; char* buff = useMalloc ? (char*) malloc(memsize) : (char*)alloca(memsize); if (readZipBlock(buff, zipsize, memsize)) { // unpack data entries char* ptr = buff; char* end = ptr + memsize; while (ptr < end) { uint8_t keysize = *ptr++; char* key = (char*)ptr; ptr += keysize; key[keysize-1] = '\0'; uint8_t datatype = *ptr++; uint32_t datasize; memcpy(&datasize, ptr, sizeof(datasize)); ptr += sizeof(datasize); char* data = ptr; ptr += datasize; metadata->addEntry(keysize-1, key, datatype, datasize, data); } } if (useMalloc) free(buff); } void PtexReader::readLargeMetaDataHeaders(MetaData* metadata, FilePos pos, int zipsize, int memsize) { seek(pos); // read from file bool useMalloc = memsize > AllocaMax; char* buff = useMalloc ? (char*) malloc(memsize) : (char*)alloca(memsize); if (readZipBlock(buff, zipsize, memsize)) { pos += zipsize; // unpack data entries char* ptr = buff; char* end = ptr + memsize; while (ptr < end) { uint8_t keysize = *ptr++; char* key = (char*)ptr; ptr += keysize; uint8_t datatype = *ptr++; uint32_t datasize; memcpy(&datasize, ptr, sizeof(datasize)); ptr += sizeof(datasize); uint32_t zipsize; memcpy(&zipsize, ptr, sizeof(zipsize)); ptr += sizeof(zipsize); metadata->addLmdEntry(keysize-1, key, datatype, datasize, pos, zipsize); pos += zipsize; } } if (useMalloc) free(buff); } void PtexReader::readEditData() { // determine file range to scan for edits FilePos pos = FilePos(_editdatapos), endpos; if (_extheader.editdatapos > 0) { // newer files record the edit data position and size in the extheader // note: position will be non-zero even if size is zero endpos = FilePos(pos + _extheader.editdatasize); } else { // must have an older file, just read until EOF endpos = FilePos((uint64_t)-1); } while (pos < endpos) { seek(pos); // read the edit data header uint8_t edittype = et_editmetadata; uint32_t editsize; if (!readBlock(&edittype, sizeof(edittype), /*reporterror*/ false)) break; if (!readBlock(&editsize, sizeof(editsize), /*reporterror*/ false)) break; if (!editsize) break; _hasEdits = true; pos = tell() + editsize; switch (edittype) { case et_editfacedata: readEditFaceData(); break; case et_editmetadata: readEditMetaData(); break; } } } void PtexReader::readEditFaceData() { // read header EditFaceDataHeader efdh; if (!readBlock(&efdh, EditFaceDataHeaderSize)) return; // update face info int faceid = efdh.faceid; if (faceid < 0 || size_t(faceid) >= _header.nfaces) return; FaceInfo& f = _faceinfo[faceid]; f = efdh.faceinfo; f.flags |= FaceInfo::flag_hasedits; // read const value now uint8_t* constdata = _constdata + _pixelsize * faceid; if (!readBlock(constdata, _pixelsize)) return; if (_premultiply && _header.hasAlpha()) PtexUtils::multalpha(constdata, 1, _header.datatype, _header.nchannels, _header.alphachan); // update header info for remaining data if (!f.isConstant()) { _faceedits.push_back(FaceEdit()); FaceEdit& e = _faceedits.back(); e.pos = tell(); e.faceid = faceid; e.fdh = efdh.fdh; } } void PtexReader::readEditMetaData() { // read header EditMetaDataHeader emdh; if (!readBlock(&emdh, EditMetaDataHeaderSize)) return; // record header info for later _metaedits.push_back(MetaEdit()); MetaEdit& e = _metaedits.back(); e.pos = tell(); e.zipsize = emdh.metadatazipsize; e.memsize = emdh.metadatamemsize; } bool PtexReader::readBlock(void* data, int size, bool reporterror) { int result = _io->read(data, size, _fp); if (result == size) { _pos += size; STATS_INC(nblocksRead); STATS_ADD(nbytesRead, size); return 1; } if (reporterror) setError("PtexReader error: read failed (EOF)"); return 0; } bool PtexReader::readZipBlock(void* data, int zipsize, int unzipsize) { void* buff = alloca(BlockSize); _zstream.next_out = (Bytef*) data; _zstream.avail_out = unzipsize; while (1) { int size = (zipsize < BlockSize) ? zipsize : BlockSize; zipsize -= size; if (!readBlock(buff, size)) break; _zstream.next_in = (Bytef*) buff; _zstream.avail_in = size; int zresult = inflate(&_zstream, zipsize ? Z_NO_FLUSH : Z_FINISH); if (zresult == Z_STREAM_END) break; if (zresult != Z_OK) { setError("PtexReader error: unzip failed, file corrupt"); inflateReset(&_zstream); return 0; } } int total = _zstream.total_out; inflateReset(&_zstream); return total == unzipsize; } void PtexReader::readLevel(int levelid, Level*& level) { // temporarily release cache lock so other threads can proceed _cache->cachelock.unlock(); // get read lock and make sure we still need to read AutoMutex locker(readlock); if (level) { // another thread must have read it while we were waiting _cache->cachelock.lock(); // make sure it's still there now that we have the lock if (level) { level->ref(); return; } _cache->cachelock.unlock(); } // go ahead and read the level LevelInfo& l = _levelinfo[levelid]; // keep new level local until finished Level* volatile newlevel = new Level((void**)&level, _cache, l.nfaces); seek(_levelpos[levelid]); readZipBlock(&newlevel->fdh[0], l.levelheadersize, FaceDataHeaderSize * l.nfaces); computeOffsets(tell(), l.nfaces, &newlevel->fdh[0], &newlevel->offsets[0]); // apply edits (if any) to level 0 if (levelid == 0) { for (size_t i = 0, size = _faceedits.size(); i < size; i++) { FaceEdit& e = _faceedits[i]; newlevel->fdh[e.faceid] = e.fdh; newlevel->offsets[e.faceid] = e.pos; } } // don't assign to result until level data is fully initialized _cache->cachelock.lock(); level = newlevel; // clean up unused data _cache->purgeData(); } void PtexReader::readFace(int levelid, Level* level, int faceid) { // temporarily release cache lock so other threads can proceed _cache->cachelock.unlock(); // get read lock and make sure we still need to read FaceData*& face = level->faces[faceid]; AutoMutex locker(readlock); if (face) { // another thread must have read it while we were waiting _cache->cachelock.lock(); // make sure it's still there now that we have the lock if (face) { face->ref(); return; } _cache->cachelock.unlock(); } // Go ahead and read the face, and read nearby faces if // possible. The goal is to coalesce small faces into single // runs of consecutive reads to minimize seeking and take // advantage of read-ahead buffering. // Try to read as many faces as will fit in BlockSize. Use the // in-memory size rather than the on-disk size to prevent flooding // the memory cache. And don't coalesce w/ tiled faces as these // are meant to be read individually. // scan both backwards and forwards looking for unread faces int first = faceid, last = faceid; int totalsize = 0; FaceDataHeader fdh = level->fdh[faceid]; if (fdh.encoding() != enc_tiled) { totalsize += unpackedSize(fdh, levelid, faceid); int nfaces = int(level->fdh.size()); while (1) { int f = first-1; if (f < 0 || level->faces[f]) break; fdh = level->fdh[f]; if (fdh.encoding() == enc_tiled) break; int size = totalsize + unpackedSize(fdh, levelid, f); if (size > BlockSize) break; first = f; totalsize = size; } while (1) { int f = last+1; if (f >= nfaces || level->faces[f]) break; fdh = level->fdh[f]; if (fdh.encoding() == enc_tiled) break; int size = totalsize + unpackedSize(fdh, levelid, f); if (size > BlockSize) break; last = f; totalsize = size; } } // read all faces in range // keep track of extra faces we read so we can add them to the cache later std::vector extraFaces; extraFaces.reserve(last-first); for (int i = first; i <= last; i++) { fdh = level->fdh[i]; // skip faces with zero size (which is true for level-0 constant faces) if (fdh.blocksize()) { FaceData*& face = level->faces[i]; readFaceData(level->offsets[i], fdh, getRes(levelid, i), levelid, face); if (i != faceid) extraFaces.push_back(face); } } // reacquire cache lock, then unref extra faces to add them to the cache _cache->cachelock.lock(); for (size_t i = 0, size = extraFaces.size(); i < size; i++) extraFaces[i]->unref(); } void PtexReader::TiledFace::readTile(int tile, FaceData*& data) { // temporarily release cache lock so other threads can proceed _cache->cachelock.unlock(); // get read lock and make sure we still need to read AutoMutex locker(_reader->readlock); if (data) { // another thread must have read it while we were waiting _cache->cachelock.lock(); // make sure it's still there now that we have the lock if (data) { data->ref(); return; } _cache->cachelock.unlock(); } // go ahead and read the face data _reader->readFaceData(_offsets[tile], _fdh[tile], _tileres, _levelid, data); _cache->cachelock.lock(); // clean up unused data _cache->purgeData(); } void PtexReader::readFaceData(FilePos pos, FaceDataHeader fdh, Res res, int levelid, FaceData*& face) { // keep new face local until fully initialized FaceData* volatile newface = 0; seek(pos); switch (fdh.encoding()) { case enc_constant: { ConstantFace* pf = new ConstantFace((void**)&face, _cache, _pixelsize); readBlock(pf->data(), _pixelsize); if (levelid==0 && _premultiply && _header.hasAlpha()) PtexUtils::multalpha(pf->data(), 1, _header.datatype, _header.nchannels, _header.alphachan); newface = pf; } break; case enc_tiled: { Res tileres; readBlock(&tileres, sizeof(tileres)); uint32_t tileheadersize; readBlock(&tileheadersize, sizeof(tileheadersize)); TiledFace* tf = new TiledFace((void**)&face, _cache, res, tileres, levelid, this); readZipBlock(&tf->_fdh[0], tileheadersize, FaceDataHeaderSize * tf->_ntiles); computeOffsets(tell(), tf->_ntiles, &tf->_fdh[0], &tf->_offsets[0]); newface = tf; } break; case enc_zipped: case enc_diffzipped: { int uw = res.u(), vw = res.v(); int npixels = uw * vw; int unpackedSize = _pixelsize * npixels; PackedFace* pf = new PackedFace((void**)&face, _cache, res, _pixelsize, unpackedSize); void* tmp = alloca(unpackedSize); readZipBlock(tmp, fdh.blocksize(), unpackedSize); if (fdh.encoding() == enc_diffzipped) PtexUtils::decodeDifference(tmp, unpackedSize, _header.datatype); PtexUtils::interleave(tmp, uw * DataSize(_header.datatype), uw, vw, pf->data(), uw * _pixelsize, _header.datatype, _header.nchannels); if (levelid==0 && _premultiply && _header.hasAlpha()) PtexUtils::multalpha(pf->data(), npixels, _header.datatype, _header.nchannels, _header.alphachan); newface = pf; } break; } face = newface; } void PtexReader::getData(int faceid, void* buffer, int stride) { if (!_ok) return; FaceInfo& f = _faceinfo[faceid]; getData(faceid, buffer, stride, f.res); } void PtexReader::getData(int faceid, void* buffer, int stride, Res res) { if (!_ok) return; // note - all locking is handled in called getData methods int resu = res.u(), resv = res.v(); int rowlen = _pixelsize * resu; if (stride == 0) stride = rowlen; PtexPtr d ( getData(faceid, res) ); if (!d) return; if (d->isConstant()) { // fill dest buffer with pixel value PtexUtils::fill(d->getData(), buffer, stride, resu, resv, _pixelsize); } else if (d->isTiled()) { // loop over tiles Res tileres = d->tileRes(); int ntilesu = res.ntilesu(tileres); int ntilesv = res.ntilesv(tileres); int tileures = tileres.u(); int tilevres = tileres.v(); int tilerowlen = _pixelsize * tileures; int tile = 0; char* dsttilerow = (char*) buffer; for (int i = 0; i < ntilesv; i++) { char* dsttile = dsttilerow; for (int j = 0; j < ntilesu; j++) { PtexPtr t ( d->getTile(tile++) ); if (!t) { i = ntilesv; break; } if (t->isConstant()) PtexUtils::fill(t->getData(), dsttile, stride, tileures, tilevres, _pixelsize); else PtexUtils::copy(t->getData(), tilerowlen, dsttile, stride, tilevres, tilerowlen); dsttile += tilerowlen; } dsttilerow += stride * tilevres; } } else { PtexUtils::copy(d->getData(), rowlen, buffer, stride, resv, rowlen); } } PtexFaceData* PtexReader::getData(int faceid) { if (faceid < 0 || size_t(faceid) >= _header.nfaces) return 0; if (!_ok) return 0; FaceInfo& fi = _faceinfo[faceid]; if (fi.isConstant() || fi.res == 0) { return new ConstDataPtr(getConstData() + faceid * _pixelsize, _pixelsize); } // get level zero (full) res face AutoLockCache locker(_cache->cachelock); Level* level = getLevel(0); FaceData* face = getFace(0, level, faceid); level->unref(); return face; } PtexFaceData* PtexReader::getData(int faceid, Res res) { if (!_ok) return 0; if (faceid < 0 || size_t(faceid) >= _header.nfaces) return 0; FaceInfo& fi = _faceinfo[faceid]; if ((fi.isConstant() && res >= 0) || res == 0) { return new ConstDataPtr(getConstData() + faceid * _pixelsize, _pixelsize); } // lock cache (can't autolock since we might need to unlock early) _cache->cachelock.lock(); // determine how many reduction levels are needed int redu = fi.res.ulog2 - res.ulog2, redv = fi.res.vlog2 - res.vlog2; if (redu == 0 && redv == 0) { // no reduction - get level zero (full) res face Level* level = getLevel(0); FaceData* face = getFace(0, level, faceid); level->unref(); _cache->cachelock.unlock(); return face; } if (redu == redv && !fi.hasEdits() && res >= 0) { // reduction is symmetric and non-negative // and face has no edits => access data from reduction level (if present) int levelid = redu; if (size_t(levelid) < _levels.size()) { Level* level = getLevel(levelid); // get reduction face id int rfaceid = _rfaceids[faceid]; // get the face data (if present) FaceData* face = 0; if (size_t(rfaceid) < level->faces.size()) face = getFace(levelid, level, rfaceid); level->unref(); if (face) { _cache->cachelock.unlock(); return face; } } } // dynamic reduction required - look in dynamic reduction cache FaceData*& face = _reductions[ReductionKey(faceid, res)]; if (face) { face->ref(); _cache->cachelock.unlock(); return face; } // not found, generate new reduction // unlock cache - getData and reduce will handle their own locking _cache->cachelock.unlock(); if (res.ulog2 < 0 || res.vlog2 < 0) { std::cerr << "PtexReader::getData - reductions below 1 pixel not supported" << std::endl; return 0; } if (redu < 0 || redv < 0) { std::cerr << "PtexReader::getData - enlargements not supported" << std::endl; return 0; } if (_header.meshtype == mt_triangle) { if (redu != redv) { std::cerr << "PtexReader::getData - anisotropic reductions not supported for triangle mesh" << std::endl; return 0; } PtexPtr psrc ( getData(faceid, Res(res.ulog2+1, res.vlog2+1)) ); FaceData* src = dynamic_cast(psrc.get()); assert(src); if (src) src->reduce(face, this, res, PtexUtils::reduceTri); return face; } // determine which direction to blend bool blendu; if (redu == redv) { // for symmetric face blends, alternate u and v blending blendu = (res.ulog2 & 1); } else blendu = redu > redv; if (blendu) { // get next-higher u-res and reduce in u PtexPtr psrc ( getData(faceid, Res(res.ulog2+1, res.vlog2)) ); FaceData* src = dynamic_cast(psrc.get()); assert(src); if (src) src->reduce(face, this, res, PtexUtils::reduceu); } else { // get next-higher v-res and reduce in v PtexPtr psrc ( getData(faceid, Res(res.ulog2, res.vlog2+1)) ); FaceData* src = dynamic_cast(psrc.get()); assert(src); if (src) src->reduce(face, this, res, PtexUtils::reducev); } return face; } void PtexReader::blendFaces(FaceData*& face, int faceid, Res res, bool blendu) { Res pres; // parent res, 1 higher in blend direction int length; // length of blend edge (1xN or Nx1) int e1, e2; // neighboring edge ids if (blendu) { assert(res.ulog2 < 0); // res >= 0 requires reduction, not blending length = (res.vlog2 <= 0 ? 1 : res.v()); e1 = e_bottom; e2 = e_top; pres = Res(res.ulog2+1, res.vlog2); } else { assert(res.vlog2 < 0); length = (res.ulog2 <= 0 ? 1 : res.u()); e1 = e_right; e2 = e_left; pres = Res(res.ulog2, res.vlog2+1); } // get neighbor face ids FaceInfo& f = _faceinfo[faceid]; int nf1 = f.adjfaces[e1], nf2 = f.adjfaces[e2]; // compute rotation of faces relative to current int r1 = (f.adjedge(e1)-e1+2)&3; int r2 = (f.adjedge(e2)-e2+2)&3; // swap u and v res for faces rotated +/- 90 degrees Res pres1 = pres, pres2 = pres; if (r1 & 1) pres1.swapuv(); if (r2 & 1) pres2.swapuv(); // ignore faces that have insufficient res (unlikely, but possible) if (nf1 >= 0 && !(_faceinfo[nf1].res >= pres)) nf1 = -1; if (nf2 >= 0 && !(_faceinfo[nf2].res >= pres)) nf2 = -1; // get parent face data int nf = 1; // number of faces to blend (1 to 3) bool flip[3]; // true if long dimension needs to be flipped PtexFaceData* psrc[3]; // the face data psrc[0] = getData(faceid, pres); flip[0] = 0; // don't flip main face if (nf1 >= 0) { // face must be flipped if rot is 1 or 2 for blendu, or 2 or 3 for blendv // thus, just add the blendu bool val to align the ranges and check bit 1 // also, no need to flip if length is zero flip[nf] = length ? (r1 + blendu) & 1 : 0; psrc[nf++] = getData(nf1, pres1); } if (nf2 >= 0) { flip[nf] = length ? (r2 + blendu) & 1 : 0; psrc[nf++] = getData(nf2, pres2); } // get reduce lock and make sure we still need to reduce AutoMutex rlocker(reducelock); if (face) { // another thread must have generated it while we were waiting AutoLockCache locker(_cache->cachelock); // make sure it's still there now that we have the lock if (face) { face->ref(); // release parent data for (int i = 0; i < nf; i++) psrc[i]->release(); return; } } // allocate a new face data (1 x N or N x 1) DataType dt = datatype(); int nchan = nchannels(); int size = _pixelsize * length; PackedFace* pf = new PackedFace((void**)&face, _cache, res, _pixelsize, size); void* data = pf->getData(); if (nf == 1) { // no neighbors - just copy face memcpy(data, psrc[0]->getData(), size); } else { float weight = 1.0f / nf; memset(data, 0, size); for (int i = 0; i < nf; i++) PtexUtils::blend(psrc[i]->getData(), weight, data, flip[i], length, dt, nchan); } { AutoLockCache clocker(_cache->cachelock); face = pf; // clean up unused data _cache->purgeData(); } // release parent data for (int i = 0; i < nf; i++) psrc[i]->release(); } void PtexReader::getPixel(int faceid, int u, int v, float* result, int firstchan, int nchannels) { memset(result, 0, nchannels); // clip nchannels against actual number available nchannels = PtexUtils::min(nchannels, _header.nchannels-firstchan); if (nchannels <= 0) return; // get raw pixel data PtexPtr data ( getData(faceid) ); if (!data) return; void* pixel = alloca(_pixelsize); data->getPixel(u, v, pixel); // adjust for firstchan offset int datasize = DataSize(_header.datatype); if (firstchan) pixel = (char*) pixel + datasize * firstchan; // convert/copy to result as needed if (_header.datatype == dt_float) memcpy(result, pixel, datasize * nchannels); else ConvertToFloat(result, pixel, _header.datatype, nchannels); } void PtexReader::getPixel(int faceid, int u, int v, float* result, int firstchan, int nchannels, Ptex::Res res) { memset(result, 0, nchannels); // clip nchannels against actual number available nchannels = PtexUtils::min(nchannels, _header.nchannels-firstchan); if (nchannels <= 0) return; // get raw pixel data PtexPtr data ( getData(faceid, res) ); if (!data) return; void* pixel = alloca(_pixelsize); data->getPixel(u, v, pixel); // adjust for firstchan offset int datasize = DataSize(_header.datatype); if (firstchan) pixel = (char*) pixel + datasize * firstchan; // convert/copy to result as needed if (_header.datatype == dt_float) memcpy(result, pixel, datasize * nchannels); else ConvertToFloat(result, pixel, _header.datatype, nchannels); } void PtexReader::PackedFace::reduce(FaceData*& face, PtexReader* r, Res newres, PtexUtils::ReduceFn reducefn) { // get reduce lock and make sure we still need to reduce AutoMutex rlocker(r->reducelock); if (face) { // another thread must have generated it while we were waiting AutoLockCache clocker(_cache->cachelock); // make sure it's still there now that we have the lock if (face) { face->ref(); return; } } // allocate a new face and reduce image DataType dt = r->datatype(); int nchan = r->nchannels(); PackedFace* pf = new PackedFace((void**)&face, _cache, newres, _pixelsize, _pixelsize * newres.size()); // reduce and copy into new face reducefn(_data, _pixelsize * _res.u(), _res.u(), _res.v(), pf->_data, _pixelsize * newres.u(), dt, nchan); AutoLockCache clocker(_cache->cachelock); face = pf; // clean up unused data _cache->purgeData(); } void PtexReader::ConstantFace::reduce(FaceData*& face, PtexReader*, Res, PtexUtils::ReduceFn) { // get cache lock (just to protect the ref count) AutoLockCache locker(_cache->cachelock); // must make a new constant face (even though it's identical to this one) // because it will be owned by a different reduction level // and will therefore have a different parent ConstantFace* pf = new ConstantFace((void**)&face, _cache, _pixelsize); memcpy(pf->_data, _data, _pixelsize); face = pf; } void PtexReader::TiledFaceBase::reduce(FaceData*& face, PtexReader* r, Res newres, PtexUtils::ReduceFn reducefn) { // get reduce lock and make sure we still need to reduce AutoMutex rlocker(r->reducelock); if (face) { // another thread must have generated it while we were waiting AutoLockCache clocker(_cache->cachelock); // make sure it's still there now that we have the lock if (face) { face->ref(); return; } } /* Tiled reductions should generally only be anisotropic (just u or v, not both) since isotropic reductions are precomputed and stored on disk. (This function should still work for isotropic reductions though.) In the anisotropic case, the number of tiles should be kept the same along the direction not being reduced in order to preserve the laziness of the file access. In contrast, if reductions were not tiled, then any reduction would read all the tiles and defeat the purpose of tiling. */ // keep new face local until fully initialized FaceData* volatile newface = 0; // don't tile if either dimension is 1 (rare, would complicate blendFaces too much) Res newtileres; if (newres.ulog2 == 1 || newres.vlog2 == 1) { newtileres = newres; } else { // propagate the tile res to the reduction newtileres = _tileres; // but make sure tile isn't larger than the new face! if (newtileres.ulog2 > newres.ulog2) newtileres.ulog2 = newres.ulog2; if (newtileres.vlog2 > newres.vlog2) newtileres.vlog2 = newres.vlog2; } // determine how many tiles we will have on the reduction int newntiles = newres.ntiles(newtileres); if (newntiles == 1) { // no need to keep tiling, reduce tiles into a single face // first, get all tiles and check if they are constant (with the same value) PtexFaceData** tiles = (PtexFaceData**) alloca(_ntiles * sizeof(PtexFaceData*)); bool allConstant = true; for (int i = 0; i < _ntiles; i++) { PtexFaceData* tile = tiles[i] = getTile(i); allConstant = (allConstant && tile->isConstant() && (i == 0 || (0 == memcmp(tiles[0]->getData(), tile->getData(), _pixelsize)))); } if (allConstant) { // allocate a new constant face newface = new ConstantFace((void**)&face, _cache, _pixelsize); memcpy(newface->getData(), tiles[0]->getData(), _pixelsize); } else { // allocate a new packed face newface = new PackedFace((void**)&face, _cache, newres, _pixelsize, _pixelsize*newres.size()); int tileures = _tileres.u(); int tilevres = _tileres.v(); int sstride = _pixelsize * tileures; int dstride = _pixelsize * newres.u(); int dstepu = dstride/_ntilesu; int dstepv = dstride*newres.v()/_ntilesv - dstepu*(_ntilesu-1); char* dst = (char*) newface->getData(); for (int i = 0; i < _ntiles;) { PtexFaceData* tile = tiles[i]; if (tile->isConstant()) PtexUtils::fill(tile->getData(), dst, dstride, newres.u()/_ntilesu, newres.v()/_ntilesv, _pixelsize); else reducefn(tile->getData(), sstride, tileures, tilevres, dst, dstride, _dt, _nchan); i++; dst += i%_ntilesu ? dstepu : dstepv; } } // release the tiles for (int i = 0; i < _ntiles; i++) tiles[i]->release(); } else { // otherwise, tile the reduced face newface = new TiledReducedFace((void**)&face, _cache, newres, newtileres, _dt, _nchan, this, reducefn); } AutoLockCache clocker(_cache->cachelock); face = newface; // clean up unused data _cache->purgeData(); } void PtexReader::TiledFaceBase::getPixel(int ui, int vi, void* result) { int tileu = ui >> _tileres.ulog2; int tilev = vi >> _tileres.vlog2; PtexPtr tile ( getTile(tilev * _ntilesu + tileu) ); tile->getPixel(ui - (tileu<<_tileres.ulog2), vi - (tilev<<_tileres.vlog2), result); } PtexFaceData* PtexReader::TiledReducedFace::getTile(int tile) { _cache->cachelock.lock(); FaceData*& face = _tiles[tile]; if (face) { face->ref(); _cache->cachelock.unlock(); return face; } // first, get all parent tiles for this tile // and check if they are constant (with the same value) int pntilesu = _parentface->ntilesu(); int pntilesv = _parentface->ntilesv(); int nu = pntilesu / _ntilesu; // num parent tiles for this tile in u dir int nv = pntilesv / _ntilesv; // num parent tiles for this tile in v dir int ntiles = nu*nv; // num parent tiles for this tile PtexFaceData** tiles = (PtexFaceData**) alloca(ntiles * sizeof(PtexFaceData*)); bool allConstant = true; int ptile = (tile/_ntilesu) * nv * pntilesu + (tile%_ntilesu) * nu; for (int i = 0; i < ntiles;) { // temporarily release cache lock while we get parent tile _cache->cachelock.unlock(); PtexFaceData* tile = tiles[i] = _parentface->getTile(ptile); _cache->cachelock.lock(); allConstant = (allConstant && tile->isConstant() && (i==0 || (0 == memcmp(tiles[0]->getData(), tile->getData(), _pixelsize)))); i++; ptile += i%nu? 1 : pntilesu - nu + 1; } // make sure another thread didn't make the tile while we were checking if (face) { face->ref(); _cache->cachelock.unlock(); // release the tiles for (int i = 0; i < ntiles; i++) tiles[i]->release(); return face; } if (allConstant) { // allocate a new constant face face = new ConstantFace((void**)&face, _cache, _pixelsize); memcpy(face->getData(), tiles[0]->getData(), _pixelsize); } else { // allocate a new packed face for the tile face = new PackedFace((void**)&face, _cache, _tileres, _pixelsize, _pixelsize*_tileres.size()); // generate reduction from parent tiles int ptileures = _parentface->tileres().u(); int ptilevres = _parentface->tileres().v(); int sstride = ptileures * _pixelsize; int dstride = _tileres.u() * _pixelsize; int dstepu = dstride/nu; int dstepv = dstride*_tileres.v()/nv - dstepu*(nu-1); char* dst = (char*) face->getData(); for (int i = 0; i < ntiles;) { PtexFaceData* tile = tiles[i]; if (tile->isConstant()) PtexUtils::fill(tile->getData(), dst, dstride, _tileres.u()/nu, _tileres.v()/nv, _pixelsize); else _reducefn(tile->getData(), sstride, ptileures, ptilevres, dst, dstride, _dt, _nchan); i++; dst += i%nu ? dstepu : dstepv; } } _cache->cachelock.unlock(); // release the tiles for (int i = 0; i < ntiles; i++) tiles[i]->release(); return face; } openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexIO.h0000644000175000017500000001044612271062644022007 0ustar mfvmfv#ifndef PtexIO_h #define PtexIO_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "Ptexture.h" struct PtexIO : public Ptex { struct Header { uint32_t magic; uint32_t version; MeshType meshtype:32; DataType datatype:32; int32_t alphachan; uint16_t nchannels; uint16_t nlevels; uint32_t nfaces; uint32_t extheadersize; uint32_t faceinfosize; uint32_t constdatasize; uint32_t levelinfosize; uint32_t minorversion; uint64_t leveldatasize; uint32_t metadatazipsize; uint32_t metadatamemsize; int pixelSize() const { return DataSize(datatype) * nchannels; } bool hasAlpha() const { return alphachan >= 0 && alphachan < nchannels; } }; struct ExtHeader { BorderMode ubordermode:32; BorderMode vbordermode:32; uint32_t lmdheaderzipsize; uint32_t lmdheadermemsize; uint64_t lmddatasize; uint64_t editdatasize; uint64_t editdatapos; }; struct LevelInfo { uint64_t leveldatasize; uint32_t levelheadersize; uint32_t nfaces; LevelInfo() : leveldatasize(0), levelheadersize(0), nfaces(0) {} }; enum Encoding { enc_constant, enc_zipped, enc_diffzipped, enc_tiled }; struct FaceDataHeader { uint32_t data; // bits 0..29 = blocksize, bits 30..31 = encoding uint32_t blocksize() const { return data & 0x3fffffff; } Encoding encoding() const { return Encoding((data >> 30) & 0x3); } uint32_t& val() { return *(uint32_t*) this; } const uint32_t& val() const { return *(uint32_t*) this; } void set(uint32_t blocksize, Encoding encoding) { data = (blocksize & 0x3fffffff) | ((encoding & 0x3) << 30); } FaceDataHeader() : data(0) {} }; enum EditType { et_editfacedata, et_editmetadata }; struct EditFaceDataHeader { uint32_t faceid; FaceInfo faceinfo; FaceDataHeader fdh; }; struct EditMetaDataHeader { uint32_t metadatazipsize; uint32_t metadatamemsize; }; static const uint32_t Magic = 'P' | ('t'<<8) | ('e'<<16) | ('x'<<24); static const int HeaderSize = sizeof(Header); static const int ExtHeaderSize = sizeof(ExtHeader); static const int LevelInfoSize = sizeof(LevelInfo); static const int FaceDataHeaderSize = sizeof(FaceDataHeader); static const int EditFaceDataHeaderSize = sizeof(EditFaceDataHeader); static const int EditMetaDataHeaderSize = sizeof(EditMetaDataHeader); // these constants can be tuned for performance static const int BlockSize = 16384; // target block size for file I/O static const int TileSize = 65536; // target tile size (uncompressed) static const int AllocaMax = 16384; // max size for using alloca static const int MetaDataThreshold = 1024; // cutoff for large meta data static bool LittleEndian() { short word = 0x0201; return *(char*)&word == 1; } }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexMutex.h0000644000175000017500000000511712271062644022601 0ustar mfvmfv#ifndef PtexMutex_h #define PtexMutex_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ // #define DEBUG_THREADING /** For internal use only */ namespace PtexInternal { #ifndef NDEBUG template class DebugLock : public T { public: DebugLock() : _locked(0) {} void lock() { T::lock(); _locked = 1; } void unlock() { assert(_locked); _locked = 0; T::unlock(); } bool locked() { return _locked != 0; } private: int _locked; }; #endif /** Automatically acquire and release lock within enclosing scope. */ template class AutoLock { public: AutoLock(T& m) : _m(m) { _m.lock(); } ~AutoLock() { _m.unlock(); } private: T& _m; }; #ifndef NDEBUG // add debug wrappers to mutex and spinlock typedef DebugLock<_Mutex> Mutex; typedef DebugLock<_SpinLock> SpinLock; #else typedef _Mutex Mutex; typedef _SpinLock SpinLock; #endif typedef AutoLock AutoMutex; typedef AutoLock AutoSpin; } #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexTriangleKernel.h0000644000175000017500000001621312271062644024404 0ustar mfvmfv#ifndef PtexTriangleKernel_h #define PtexTriangleKernel_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include #include #include "Ptexture.h" #include "PtexUtils.h" // kernel width as a multiple of filter width (should be between 3 and 4) // for values below 3, the gaussian is not close to zero and a contour will be formed // larger values are more expensive (proportional to width-squared) static const float PtexTriangleKernelWidth = 3.5; /// Triangle filter kernel iterator (in texel coords) class PtexTriangleKernelIter : public Ptex { public: int rowlen; // row length (in u) double u, v; // uv center in texels int u1, v1, w1; // uvw lower bounds int u2, v2, w2; // uvw upper bounds double A,B,C; // ellipse coefficients (F = 1) bool valid; // footprint is valid (non-empty) double wscale; // amount to scale weights by (proportional to texel area) double weight; // accumulated weight void apply(double* dst, void* data, DataType dt, int nChan, int nTxChan) { // dispatch specialized apply function ApplyFn fn = applyFunctions[(nChan!=nTxChan)*20 + ((unsigned)nChan<=4)*nChan*4 + dt]; fn(*this, dst, data, nChan, nTxChan); } void applyConst(double* dst, void* data, DataType dt, int nChan); private: typedef void (*ApplyFn)(PtexTriangleKernelIter& k, double* dst, void* data, int nChan, int nTxChan); static ApplyFn applyFunctions[40]; }; /// Triangle filter kernel (in normalized triangle coords) class PtexTriangleKernel : public Ptex { public: Res res; // desired resolution double u, v; // uv filter center double u1, v1, w1; // uvw lower bounds double u2, v2, w2; // uvw upper bounds double A,B,C; // ellipse coefficients (F = A*C-B*B/4) void set(Res resVal, double uVal, double vVal, double u1Val, double v1Val, double w1Val, double u2Val, double v2Val, double w2Val, double AVal, double BVal, double CVal) { res = resVal; u = uVal; v = vVal; u1 = u1Val; v1 = v1Val; w1 = w1Val; u2 = u2Val; v2 = v2Val; w2 = w2Val; A = AVal; B = BVal; C = CVal; } void set(double uVal, double vVal, double u1Val, double v1Val, double w1Val, double u2Val, double v2Val, double w2Val) { u = uVal; v = vVal; u1 = u1Val; v1 = v1Val; w1 = w1Val; u2 = u2Val; v2 = v2Val; w2 = w2Val; } void setABC(double AVal, double BVal, double CVal) { A = AVal; B = BVal; C = CVal; } void splitU(PtexTriangleKernel& ka) { ka = *this; u1 = 0; ka.u2 = 0; } void splitV(PtexTriangleKernel& ka) { ka = *this; v1 = 0; ka.v2 = 0; } void splitW(PtexTriangleKernel& ka) { ka = *this; w1 = 0; ka.w2 = 0; } void rotate1() { // rotate ellipse where u'=w, v'=u, w'=v // (derived by converting to Barycentric form, rotating, and converting back) setABC(C, 2*C-B, A+C-B); } void rotate2() { // rotate ellipse where u'=v, v'=w, w'=u // (derived by converting to Barycentric form, rotating, and converting back) setABC(A+C-B, 2*A-B, A); } void reorient(int eid, int aeid) { double w = 1-u-v; #define C(eid, aeid) (eid*3 + aeid) switch (C(eid, aeid)) { case C(0, 0): set(1-u, -v, 1-u2, -v2, 1-w2, 1-u1, -v1, 1-w1); break; case C(0, 1): set(1-w, 1-u, 1-w2, 1-u2, -v2, 1-w1, 1-u1, -v1); rotate1(); break; case C(0, 2): set( -v, 1-w, -v2, 1-w2, 1-u2, -v1, 1-w1, 1-u1); rotate2(); break; case C(1, 0): set(1-v, -w, 1-v2, -w2, 1-u2, 1-v1, -w1, 1-u1); rotate2(); break; case C(1, 1): set(1-u, 1-v, 1-u2, 1-v2, -w2, 1-u1, 1-v1, -w1); break; case C(1, 2): set( -w, 1-u, -w2, 1-u2, 1-v2, -w1, 1-u1, 1-v1); rotate1(); break; case C(2, 0): set(1-w, -u, 1-w2, -u2, 1-v2, 1-w1, -u1, 1-v1); rotate1(); break; case C(2, 1): set(1-v, 1-w, 1-v2, 1-w2, -u2, 1-v1, 1-w1, -u1); rotate2(); break; case C(2, 2): set( -u, 1-v, -u2, 1-v2, 1-w2, -u1, 1-v1, 1-w1); break; #undef C } } void clampRes(Res fres) { res.ulog2 = PtexUtils::min(res.ulog2, fres.ulog2); res.vlog2 = res.ulog2; } void clampExtent() { u1 = PtexUtils::max(u1, 0.0); v1 = PtexUtils::max(v1, 0.0); w1 = PtexUtils::max(w1, 0.0); u2 = PtexUtils::min(u2, 1-(v1+w1)); v2 = PtexUtils::min(v2, 1-(w1+u1)); w2 = PtexUtils::min(w2, 1-(u1+v1)); } void getIterators(PtexTriangleKernelIter& ke, PtexTriangleKernelIter& ko) { int resu = res.u(); // normalize coefficients for texel units double Finv = 1.0/(resu*resu*(A*C - 0.25 * B * B)); double Ak = A*Finv, Bk = B*Finv, Ck = C*Finv; // build even iterator ke.rowlen = resu; ke.wscale = 1.0/(resu*resu); double scale = ke.rowlen; ke.u = u * scale - 1/3.0; ke.v = v * scale - 1/3.0; ke.u1 = int(ceil(u1 * scale - 1/3.0)); ke.v1 = int(ceil(v1 * scale - 1/3.0)); ke.w1 = int(ceil(w1 * scale - 1/3.0)); ke.u2 = int(ceil(u2 * scale - 1/3.0)); ke.v2 = int(ceil(v2 * scale - 1/3.0)); ke.w2 = int(ceil(w2 * scale - 1/3.0)); ke.A = Ak; ke.B = Bk; ke.C = Ck; ke.valid = (ke.u2 > ke.u1 && ke.v2 > ke.v1 && ke.w2 > ke.w1); ke.weight = 0; // build odd iterator: flip kernel across diagonal (u = 1-v, v = 1-u, w = -w) ko.rowlen = ke.rowlen; ko.wscale = ke.wscale; ko.u = (1-v) * scale - 1/3.0; ko.v = (1-u) * scale - 1/3.0; ko.u1 = int(ceil((1-v2) * scale - 1/3.0)); ko.v1 = int(ceil((1-u2) * scale - 1/3.0)); ko.w1 = int(ceil(( -w2) * scale - 1/3.0)); ko.u2 = int(ceil((1-v1) * scale - 1/3.0)); ko.v2 = int(ceil((1-u1) * scale - 1/3.0)); ko.w2 = int(ceil(( -w1) * scale - 1/3.0)); ko.A = Ck; ko.B = Bk; ko.C = Ak; ko.valid = (ko.u2 > ko.u1 && ko.v2 > ko.v1 && ko.w2 > ko.w1); ko.weight = 0; } }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexTriangleFilter.h0000644000175000017500000000625012271062644024411 0ustar mfvmfv#ifndef PtexTriangleFilter_h #define PtexTriangleFilter_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "Ptexture.h" class PtexTriangleKernel; class PtexTriangleKernelIter; class PtexTriangleFilter : public PtexFilter, public Ptex { public: PtexTriangleFilter(PtexTexture* tx, const PtexFilter::Options& opts ) : _tx(tx), _options(opts), _result(0), _weight(0), _firstChanOffset(0), _nchan(0), _ntxchan(0), _dt((DataType)0) {} virtual void release() { delete this; } virtual void eval(float* result, int firstchan, int nchannels, int faceid, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur); protected: void buildKernel(PtexTriangleKernel& k, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur, Res faceRes); void splitAndApply(PtexTriangleKernel& k, int faceid, const Ptex::FaceInfo& f); void applyAcrossEdge(PtexTriangleKernel& k, const Ptex::FaceInfo& f, int eid); void apply(PtexTriangleKernel& k, int faceid, const Ptex::FaceInfo& f); void applyIter(PtexTriangleKernelIter& k, PtexFaceData* dh); virtual ~PtexTriangleFilter() {} PtexTexture* _tx; // texture being evaluated Options _options; // options double* _result; // temp result double _weight; // accumulated weight of data in _result int _firstChanOffset; // byte offset of first channel to eval int _nchan; // number of channels to eval int _ntxchan; // number of channels in texture DataType _dt; // data type of texture }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexUtils.h0000644000175000017500000001567112271062644022605 0ustar mfvmfv#ifndef PtexUtils_h #define PtexUtils_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "Ptexture.h" struct PtexUtils : public Ptex { static bool isPowerOfTwo(int x) { return !(x&(x-1)); } static uint32_t ones(uint32_t x) { // count number of ones x = (x & 0x55555555) + ((x >> 1) & 0x55555555); // add pairs of bits x = (x & 0x33333333) + ((x >> 2) & 0x33333333); // add bit pairs x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f); // add nybbles x += (x >> 8); // add bytes x += (x >> 16); // add words return(x & 0xff); } static uint32_t floor_log2(uint32_t x) { // floor(log2(n)) x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return ones(x>>1); } static uint32_t ceil_log2(uint32_t x) { // ceil(log2(n)) bool isPow2 = isPowerOfTwo(x); x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return ones(x>>1) + !isPow2; } static double smoothstep(double x, double a, double b) { if ( x < a ) return 0; if ( x >= b ) return 1; x = (x - a)/(b - a); return x*x * (3 - 2*x); } static double qsmoothstep(double x, double a, double b) { // quintic smoothstep (cubic is only C1) if ( x < a ) return 0; if ( x >= b ) return 1; x = (x - a)/(b - a); return x*x*x * (10 + x * (-15 + x*6)); } template static T cond(bool c, T a, T b) { return c * a + (!c)*b; } template static T min(T a, T b) { return cond(a < b, a, b); } template static T max(T a, T b) { return cond(a >= b, a, b); } template static T clamp(T x, T lo, T hi) { return cond(x < lo, lo, cond(x > hi, hi, x)); } static bool isConstant(const void* data, int stride, int ures, int vres, int pixelSize); static void interleave(const void* src, int sstride, int ures, int vres, void* dst, int dstride, DataType dt, int nchannels); static void deinterleave(const void* src, int sstride, int ures, int vres, void* dst, int dstride, DataType dt, int nchannels); static void encodeDifference(void* data, int size, DataType dt); static void decodeDifference(void* data, int size, DataType dt); typedef void ReduceFn(const void* src, int sstride, int ures, int vres, void* dst, int dstride, DataType dt, int nchannels); static void reduce(const void* src, int sstride, int ures, int vres, void* dst, int dstride, DataType dt, int nchannels); static void reduceu(const void* src, int sstride, int ures, int vres, void* dst, int dstride, DataType dt, int nchannels); static void reducev(const void* src, int sstride, int ures, int vres, void* dst, int dstride, DataType dt, int nchannels); static void reduceTri(const void* src, int sstride, int ures, int vres, void* dst, int dstride, DataType dt, int nchannels); static void average(const void* src, int sstride, int ures, int vres, void* dst, DataType dt, int nchannels); static void fill(const void* src, void* dst, int dstride, int ures, int vres, int pixelsize); static void copy(const void* src, int sstride, void* dst, int dstride, int nrows, int rowlen); static void blend(const void* src, float weight, void* dst, bool flip, int rowlen, DataType dt, int nchannels); static void multalpha(void* data, int npixels, DataType dt, int nchannels, int alphachan); static void divalpha(void* data, int npixels, DataType dt, int nchannels, int alphachan); static void genRfaceids(const FaceInfo* faces, int nfaces, uint32_t* rfaceids, uint32_t* faceids); // fixed length vector accumulator: dst[i] += val[i] * weight template struct VecAccum { VecAccum() {} void operator()(double* dst, const T* val, double weight) { *dst += *val * weight; // use template to unroll loop VecAccum()(dst+1, val+1, weight); } }; template struct VecAccum { void operator()(double*, const T*, double) {} }; // variable length vector accumulator: dst[i] += val[i] * weight template struct VecAccumN { void operator()(double* dst, const T* val, int nchan, double weight) { for (int i = 0; i < nchan; i++) dst[i] += val[i] * weight; } }; // fixed length vector multiplier: dst[i] += val[i] * weight template struct VecMult { VecMult() {} void operator()(double* dst, const T* val, double weight) { *dst = *val * weight; // use template to unroll loop VecMult()(dst+1, val+1, weight); } }; template struct VecMult { void operator()(double*, const T*, double) {} }; // variable length vector multiplier: dst[i] = val[i] * weight template struct VecMultN { void operator()(double* dst, const T* val, int nchan, double weight) { for (int i = 0; i < nchan; i++) dst[i] = val[i] * weight; } }; typedef void (*ApplyConstFn)(double weight, double* dst, void* data, int nChan); static ApplyConstFn applyConstFunctions[20]; static void applyConst(double weight, double* dst, void* data, Ptex::DataType dt, int nChan) { // dispatch specialized apply function ApplyConstFn fn = applyConstFunctions[((unsigned)nChan<=4)*nChan*4 + dt]; fn(weight, dst, data, nChan); } }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexDict.h0000644000175000017500000004576112271062644022373 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ /** @file PtexDict.h @brief Contains PtexDict, a string-keyed hash table. */ #ifndef PtexDict_h #define PtexDict_h /** @class PtexDict @brief A string-keyed dictionary template, using a hash table.

An efficient string dictionary template. A hash table is used that automatically doubles in size when it is more than 50% full. It is hard-coded to use string keys for efficiency.

The interface is compatible with std::hash_map<>, though not all methods are provided. Methods provided:

  • iterator begin();
  • const_iterator begin() const;
  • iterator end();
  • const_iterator end() const;
  • T& operator[] (const char*);
  • iterator find(const char* key);
  • const_iterator find(const char* key) const;
  • bool erase(const char* key);
  • iterator erase(iterator);
  • void clear();
  • int size() const;

Unlike std::hash_map<>, PtexDict doesn't have to construct a string object to do a lookup. As a result, it is about 4-10 times faster depending on the length of the keys. And when compiling non-optimized, it is 6-10 times faster.

We have decided NOT to follow the coding standard's naming comvention for this class, since it needed to remain generic, and compatible with the STL std::hash_map<> class. @author brentb @author longson @version 1.0 brentb 11/01/2000: Initial version @version 1.1 longson 06/26/2001: Added file and class comment headers @version 2.0 longson 01/16/2002: Updated to support most of the coding standards, except for the naming conventions. Added const_iterator to provide const-safe access. Fixed problem with iterators and not allowing modification. */ /** @struct PtexDict::value_type @brief Internal class used to provide a return value for the value type All data members and member functions are declared public by design Default Copy and Assignment operators are sufficient..

We have decided NOT to follow the coding standard's naming comvention for this class, since it needed to remain compatible with the STL std::pair<> class. @author brentb @author longson @version 1.0 brentb 11/01/2000: Initial version @version 1.1 longson 06/26/2001: Added file and class comment headers */ template class PtexDict { class Entry; ///< forward declared private class public: // Public Types class iterator; ///< forward declared class class const_iterator; ///< forward declared class friend class iterator; friend class const_iterator; typedef const char* key_type; ///< This is the lookup type typedef T mapped_type; ///< The data type stored struct value_type { public: /// Default constructor references default_value, with a 0 for first value_type(): first(0), second() {} /// Creation constructor value_type(key_type f, const T& s): first(f), second(s) {} const key_type first; ///< Reference to the key type T second; ///< Reference to the data }; public: // Public Member Interfce /// Default contructor initializes the dictionary. PtexDict() : _numEntries(0), _numBuckets(0), _bucketMask(0), _buckets(0) {} /// clears the entries in the dictionary virtual ~PtexDict() { clear(); } /// Locates an entry, creating a new one if necessary. /** operator[] will look up an entry and return the value. A new entry will be created (using the default ctor for T) if one doesn't exist. */ T& operator[](const char* key); /// Returns an iterator referencing the beginning of the table iterator begin() { iterator iter; iter._d = this; for (iter._b = 0; iter._b < _numBuckets; iter._b++) { iter._e = &_buckets[iter._b]; if (*iter._e) return iter; } iter._e = 0; return iter; } /// Returns an iterator referencing the end of the table. inline iterator end() { return iterator( 0, this, 0 ); } /// Const access to the beginning of the list const_iterator begin() const { const_iterator iter; iter._d = this; for (iter._b = 0; iter._b < _numBuckets; iter._b++) { iter._e = &_buckets[iter._b]; if (*iter._e) return iter; } iter._e = 0; return iter; } /// Const access to the end of the list inline const_iterator end() const { return const_iterator( 0, this, 0 ); } /// Locates an entry, without creating a new one. /** find will locate an entry, but won't create a new one. The result is returned as a pair of key and value. The returned key points to the internal key string and will remain valid until the entry is deleted. If the key is not found, the returned iterator will be equal to the value returned by end(), and the iterator will be equal to false. O(1) */ iterator find(const char* key); /// works the same as find above, but returns a constant iterator. const_iterator find(const char* key) const; /// Will remove an entry. It will return TRUE if an entry was found. bool erase(const char* key); /// Removes the entry referenced by the iterator, from the dictionary. /** It will return a iterator to the next element, or will equal the return value of end() if there is nothing else to erase. O(1) */ iterator erase(iterator iter); /// clear will remove all entries from the dictionary. O(n) void clear(); /// Returns the number of entries in the dictionary. O(1) time to call. int size() const { return _numEntries; } private: // Private Member Interface /// @brief This internal structure is used to store the dictionary elements class Entry { public: // Public Member Interface /// Default constructor initiaizes val with the defaul value Entry() : _next(0), _hashval(0), _keylen(0), _val(_u._key,T()) { _u._pad = 0; } ~Entry() {} private: // Private Member Interface /// Copy constructor prohibited by design. Entry(const Entry&); /// Assignment operator prohibited by design. Entry& operator=(const Entry&); public: Entry* _next; ///< Pointer to the next element in the structure int _hashval; ///< cached hashval of key int _keylen; ///< cached length of key value_type _val; ///< The stored value of the hash table union { int _pad; ///< for integer align of _key, for fast compares char _key[1];///< 1 is dummy length - actual size will be allocated } _u; }; /// Copy constructor prohibited by design. PtexDict(const PtexDict&); /// Assignment operator prohibited by design. PtexDict& operator=(const PtexDict&); /// Returns the integer hash index for the key and length of the key. int hash(const char* key, int& keylen) const { // this is similar to perl's hash function int hashval = 0; const char* cp = key; char c; while ((c = *cp++)) hashval = hashval * 33 + c; keylen = int(cp-key)-1; return hashval; } /// Returns a pointer to the desired entry, based on the key. Entry** locate(const char* key, int& keylen, int& hashval) const { hashval = hash(key, keylen); if (!_buckets) return 0; for (Entry** e = &_buckets[hashval & _bucketMask]; *e; e=&(*e)->_next) if ((*e)->_hashval == hashval && (*e)->_keylen == keylen && streq(key, (*e)->_u._key, keylen)) return e; return 0; } /// Used for string compares, much faster then strcmp /** This is MUCH faster than strcmp and even memcmp, partly because it is inline and partly because it can do 4 chars at a time */ static inline bool streq(const char* s1, const char* s2, int len) { // first make sure s1 is quad-aligned (s2 is always aligned) if (((intptr_t)s1 & 3) == 0) { int len4 = len >> 2; while (len4--) { if (*(int*)s1 != *(int*)s2) return 0; s1 += 4; s2 += 4; } len &= 3; } while (len--) if (*s1++ != *s2++) return 0; return 1; } /// Used to increase the size of the table if necessary void grow(); private: // Private Member data int _numEntries; ///< The number of entries in the dictionary int _numBuckets; ///< The number of buckets in use int _bucketMask; ///< The mask for the buckets Entry** _buckets; ///< The pointer to the bucket structure }; /** @class PtexDict::iterator @brief Internal class used to provide iteration through the dictionary This works on non-const types, and provides type safe modification access @author brentb @author longson @version 1.0 brentb 11/01/2000: Initial version @version 1.1 longson 06/26/2001: Added file and class comment headers @version 1.2 longson 01/16/2002: Made const-safe with const_iterator */ template class PtexDict::iterator { public: /// Default Constructor iterator() : _d(0), _e(0), _b(0) {} /// Proper copy constructor implementation iterator(const iterator& iter) : _d(iter._d), _e(iter._e), _b(iter._b) {} /// Proper assignment operator inline iterator& operator=(const iterator& iter) { _e = iter._e; _d = iter._d; _b = iter._b; return *this; } /// Operator for obtaining the value that the iterator references inline value_type& operator*() const { return getValue(); } /// Pointer reference operator inline value_type* operator->() const { return &getValue(); } /// For determining whether or not an iterator is valid inline operator bool() { return _e != 0; } /// For comparing equality of iterators inline bool operator==(const iterator& iter) const { return iter._e == _e; } /// For comparing inequality of iterators inline bool operator!=(const iterator& iter) const { return iter._e != _e; } /// For comparing equality of iterators inline bool operator==(const const_iterator& iter) const { return iter._e == _e; } /// For comparing inequality of iterators inline bool operator!=(const const_iterator& iter) const { return iter._e != _e; } /// For advancing the iterator to the next element iterator& operator++(int); private: // Private interface /// Constructor Helper for inline creation. iterator( Entry** e, const PtexDict* d, int b): _d(d), _e(e), _b(b) {} /// simple helper function for retrieving the value from the Entry inline value_type& getValue() const{ if (_e) return (*_e)->_val; else return _defaultVal; } friend class PtexDict; friend class const_iterator; const PtexDict* _d; ///< dictionary back reference Entry** _e; ///< pointer to entry in table this iterator refs int _b; ///< bucket number this references static value_type _defaultVal; ///< Default value }; // define the static type for the iterator template typename PtexDict::value_type PtexDict::iterator::_defaultVal; /** @class PtexDict::const_iterator @brief Internal class used to provide iteration through the dictionary This works on const data types, and provides const safe access. This class can also be created from a PtexDict::iterator class instance. @author longson @version 1.2 longson 01/16/2002: Initial version based on iterator */ template class PtexDict::const_iterator { public: /// Default Constructor const_iterator() : _d(0), _e(0), _b(0) {} /// Proper copy constructor implementation for const_iterator const_iterator(const const_iterator& iter) : _d(iter._d), _e(iter._e), _b(iter._b) {} /// Conversion constructor for iterator const_iterator(const iterator& iter) : _d(iter._d), _e(iter._e), _b(iter._b) {} /// Proper assignment operator for const_iterator inline const_iterator& operator=(const const_iterator& iter) { _e = iter._e; _d = iter._d; _b = iter._b; return *this; } /// Proper assignment operator for iterator inline const_iterator& operator=(iterator& iter) { _e = iter._e; _d = iter._d; _b = iter._b; return *this; } /// Operator for obtaining the value that the const_iterator references inline const value_type& operator*() const { return getValue(); } /// Pointer reference operator inline const value_type* operator->() const { return &getValue(); } /// For determining whether or not an iterator is valid inline operator bool() { return _e != 0; } /// For comparing equality of iterators inline bool operator==(const iterator& iter) const { return iter._e == _e; } /// For comparing inequality of iterators inline bool operator!=(const iterator& iter) const { return iter._e != _e; } /// For comparing equality of const_iterators inline bool operator==(const const_iterator& iter) const { return iter._e == _e; } /// For comparing inequality of iterators inline bool operator!=(const const_iterator& iter) const { return iter._e != _e; } /// For advancing the iterator to the next element const_iterator& operator++(int); private: // Private interface /// Constructor Helper for inline creation. const_iterator( Entry** e, const PtexDict* d, int b): _d(d),_e(e),_b(b) {} /// simple helper function for retrieving the value from the Entry inline const value_type& getValue() const{ if (_e) return (*_e)->_val; else return _defaultVal; } friend class PtexDict; friend class iterator; const PtexDict* _d; ///< dictionary back reference Entry** _e; ///< pointer to entry in table this iterator refs int _b; ///< bucket number this references static value_type _defaultVal; ///< Default value }; // define the static type for the iterator template typename PtexDict::value_type PtexDict::const_iterator::_defaultVal; template typename PtexDict::iterator& PtexDict::iterator::operator++(int) { if (_e) { // move to next entry _e = &(*_e)->_next; if (!*_e) { // move to next non-empty bucket for (_b++; _b < _d->_numBuckets; _b++) { _e = &_d->_buckets[_b]; if (*_e) return *this; } _e = 0; } } return *this; } template typename PtexDict::const_iterator& PtexDict::const_iterator::operator++(int) { if (_e) { // move to next entry _e = &(*_e)->_next; if (!*_e) { // move to next non-empty bucket for (_b++; _b < _d->_numBuckets; _b++) { _e = &_d->_buckets[_b]; if (*_e) return *this; } _e = 0; } } return *this; } template typename PtexDict::iterator PtexDict::find(const char* key) { int keylen, hashval; Entry** e = locate(key, keylen, hashval); /// return a valid iterator if we found an entry, else return end() if (e) return iterator( e, this, hashval & _bucketMask ); else return end(); } template typename PtexDict::const_iterator PtexDict::find(const char* key) const { int keylen, hashval; Entry** e = locate(key, keylen, hashval); /// return a valid iterator if we found an entry, else return end() if (e) return const_iterator( e, this, hashval & _bucketMask ); else return end(); } template T& PtexDict::operator[](const char* key) { int keylen, hashval; Entry** e = locate(key, keylen, hashval); if (e) return (*e)->_val.second; // create a new entry _numEntries++; if (_numEntries*2 >= _numBuckets) grow(); // allocate a buffer big enough to hold Entry + (the key length ) // Note: the NULL character is already accounted for by Entry::_key's size void* ebuf = malloc( sizeof(Entry) + (keylen) * sizeof(char) ); Entry* ne = new(ebuf) Entry; // note: placement new // Store the values in the Entry structure Entry** slot = &_buckets[hashval & _bucketMask]; ne->_next = *slot; *slot = ne; ne->_hashval = hashval; ne->_keylen = keylen; // copy the string given into the new location memcpy(ne->_u._key, key, keylen); ne->_u._key[keylen] = '\0'; return ne->_val.second; } template void PtexDict::grow() { if (!_buckets) { _numBuckets = 16; _bucketMask = _numBuckets - 1; _buckets = (Entry**) calloc(_numBuckets, sizeof(Entry*)); } else { int newsize = _numBuckets * 2; _bucketMask = newsize - 1; Entry** newbuckets = (Entry**) calloc(newsize, sizeof(Entry*)); for (int i = 0; i < _numBuckets; i++) { for (Entry* e = _buckets[i]; e;) { Entry* _next = e->_next; Entry** slot = &newbuckets[e->_hashval & _bucketMask]; e->_next = *slot; *slot = e; e = _next; } } free(_buckets); _buckets = newbuckets; _numBuckets = newsize; } } template bool PtexDict::erase(const char* key) { iterator iter = find(key); if (!iter) return false; erase(iter); return true; // valid entry to remove } template typename PtexDict::iterator PtexDict::erase(iterator iter) { Entry** eptr = iter._e; if (!eptr) return iter; // patch around deleted entry Entry* e = *eptr; Entry* next = e->_next; if (!next) iter++; // advance iterator if at end of chain *eptr = next; // destroy entry. This is a strange destroy but is necessary because of // the way Entry() is allocated by using malloc above. e->~Entry(); // note: explicit dtor call free(e); // free memory allocated. _numEntries--; return iter; } template void PtexDict::clear() { for (iterator i=begin(); i != end(); ) i = erase(i); free(_buckets); _buckets = 0; _numEntries = 0; _numBuckets = 0; } #endif //PtexDict_h openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexPlatform.h0000644000175000017500000001046512271062644023265 0ustar mfvmfv#ifndef PtexPlatform_h #define PtexPlatform_h #define PtexPlatform_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ /** @file PtexPlatform.h @brief Platform-specific classes, functions, and includes. */ // platform-specific includes #if defined(_WIN32) || defined(_WINDOWS) || defined(_MSC_VER) #ifndef WINDOWS #define WINDOWS #endif #define _CRT_NONSTDC_NO_DEPRECATE 1 #define _CRT_SECURE_NO_DEPRECATE 1 #define NOMINMAX 1 // windows - defined for both Win32 and Win64 #include #include #include #include #include #else // linux/unix/posix #include #ifndef __FreeBSD__ #include #endif #include #include // OS for spinlock #ifdef __APPLE__ #include #include #endif #endif // general includes #include #include #include // missing functions on Windows #ifdef WINDOWS #define snprintf sprintf_s #define strtok_r strtok_s typedef __int64 FilePos; #define fseeko _fseeki64 #define ftello _ftelli64 inline double log2(double x) { return log(x) * 1.4426950408889634; } #else typedef off_t FilePos; #endif namespace PtexInternal { /* * Mutex/SpinLock classes */ #ifdef WINDOWS class _Mutex { public: _Mutex() { _mutex = CreateMutex(NULL, FALSE, NULL); } ~_Mutex() { CloseHandle(_mutex); } void lock() { WaitForSingleObject(_mutex, INFINITE); } void unlock() { ReleaseMutex(_mutex); } private: HANDLE _mutex; }; class _SpinLock { public: _SpinLock() { InitializeCriticalSection(&_spinlock); } ~_SpinLock() { DeleteCriticalSection(&_spinlock); } void lock() { EnterCriticalSection(&_spinlock); } void unlock() { LeaveCriticalSection(&_spinlock); } private: CRITICAL_SECTION _spinlock; }; #else // assume linux/unix/posix class _Mutex { public: _Mutex() { pthread_mutex_init(&_mutex, 0); } ~_Mutex() { pthread_mutex_destroy(&_mutex); } void lock() { pthread_mutex_lock(&_mutex); } void unlock() { pthread_mutex_unlock(&_mutex); } private: pthread_mutex_t _mutex; }; #ifdef __APPLE__ class _SpinLock { public: _SpinLock() { _spinlock = 0; } ~_SpinLock() { } void lock() { OSSpinLockLock(&_spinlock); } void unlock() { OSSpinLockUnlock(&_spinlock); } private: OSSpinLock _spinlock; }; #else class _SpinLock { public: _SpinLock() { pthread_spin_init(&_spinlock, PTHREAD_PROCESS_PRIVATE); } ~_SpinLock() { pthread_spin_destroy(&_spinlock); } void lock() { pthread_spin_lock(&_spinlock); } void unlock() { pthread_spin_unlock(&_spinlock); } private: pthread_spinlock_t _spinlock; }; #endif // __APPLE__ #endif } #endif // PtexPlatform_h openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexReader.h0000644000175000017500000004563412271062644022711 0ustar mfvmfv#ifndef PtexReader_h #define PtexReader_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include #include #include #include #include "Ptexture.h" #include "PtexIO.h" #include "PtexCache.h" #include "PtexUtils.h" #include "PtexHashMap.h" using namespace PtexInternal; #ifndef NDEBUG #include template class safevector : public std::vector { public: safevector() : std::vector() {} safevector(size_t n, const T& val = T()) : std::vector(n, val) {} const T& operator[] (size_t n) const { assert(n < std::vector::size()); return std::vector::operator[](n); } T& operator[] (size_t n) { assert(n < std::vector::size()); return std::vector::operator[](n); } }; #else #define safevector std::vector #endif class PtexReader : public PtexCachedFile, public PtexTexture, public PtexIO { public: PtexReader(void** parent, PtexCacheImpl* cache, bool premultiply, PtexInputHandler* handler); bool open(const char* path, Ptex::String& error); void setOwnsCache() { _ownsCache = true; } virtual void release(); virtual const char* path() { return _path.c_str(); } virtual Ptex::MeshType meshType() { return MeshType(_header.meshtype); } virtual Ptex::DataType dataType() { return DataType(_header.datatype); } virtual Ptex::BorderMode uBorderMode() { return BorderMode(_extheader.ubordermode); } virtual Ptex::BorderMode vBorderMode() { return BorderMode(_extheader.vbordermode); } virtual int alphaChannel() { return _header.alphachan; } virtual int numChannels() { return _header.nchannels; } virtual int numFaces() { return _header.nfaces; } virtual bool hasEdits() { return _hasEdits; } virtual bool hasMipMaps() { return _header.nlevels > 1; } virtual PtexMetaData* getMetaData(); virtual const Ptex::FaceInfo& getFaceInfo(int faceid); virtual void getData(int faceid, void* buffer, int stride); virtual void getData(int faceid, void* buffer, int stride, Res res); virtual PtexFaceData* getData(int faceid); virtual PtexFaceData* getData(int faceid, Res res); virtual void getPixel(int faceid, int u, int v, float* result, int firstchan, int nchannels); virtual void getPixel(int faceid, int u, int v, float* result, int firstchan, int nchannels, Ptex::Res res); DataType datatype() const { return _header.datatype; } int nchannels() const { return _header.nchannels; } int pixelsize() const { return _pixelsize; } const Header& header() const { return _header; } const ExtHeader& extheader() const { return _extheader; } const LevelInfo& levelinfo(int level) const { return _levelinfo[level]; } class MetaData : public PtexCachedData, public PtexMetaData { public: MetaData(MetaData** parent, PtexCacheImpl* cache, int size, PtexReader* reader) : PtexCachedData((void**)parent, cache, sizeof(*this) + size), _reader(reader) {} virtual void release() { AutoLockCache lock(_cache->cachelock); // first, unref all lmdData refs for (int i = 0, n = _lmdRefs.size(); i < n; i++) _lmdRefs[i]->unref(); _lmdRefs.resize(0); // finally, unref self unref(); } virtual int numKeys() { return int(_entries.size()); } virtual void getKey(int n, const char*& key, MetaDataType& type) { Entry* e = _entries[n]; key = e->key; type = e->type; } virtual void getValue(const char* key, const char*& value) { Entry* e = getEntry(key); if (e) value = (const char*) e->data; else value = 0; } virtual void getValue(const char* key, const int8_t*& value, int& count) { Entry* e = getEntry(key); if (e) { value = (const int8_t*) e->data; count = e->datasize; } else { value = 0; count = 0; } } virtual void getValue(const char* key, const int16_t*& value, int& count) { Entry* e = getEntry(key); if (e) { value = (const int16_t*) e->data; count = int(e->datasize/sizeof(int16_t)); } else { value = 0; count = 0; } } virtual void getValue(const char* key, const int32_t*& value, int& count) { Entry* e = getEntry(key); if (e) { value = (const int32_t*) e->data; count = int(e->datasize/sizeof(int32_t)); } else { value = 0; count = 0; } } virtual void getValue(const char* key, const float*& value, int& count) { Entry* e = getEntry(key); if (e) { value = (const float*) e->data; count = int(e->datasize/sizeof(float)); } else { value = 0; count = 0; } } virtual void getValue(const char* key, const double*& value, int& count) { Entry* e = getEntry(key); if (e) { value = (const double*) e->data; count = int(e->datasize/sizeof(double)); } else { value = 0; count = 0; } } void addEntry(uint8_t keysize, const char* key, uint8_t datatype, uint32_t datasize, void* data) { Entry* e = newEntry(keysize, key, datatype, datasize); e->data = malloc(datasize); memcpy(e->data, data, datasize); } void addLmdEntry(uint8_t keysize, const char* key, uint8_t datatype, uint32_t datasize, FilePos filepos, uint32_t zipsize) { Entry* e = newEntry(keysize, key, datatype, datasize); e->isLmd = true; e->lmdData = 0; e->lmdPos = filepos; e->lmdZipSize = zipsize; } protected: class LargeMetaData : public PtexCachedData { public: LargeMetaData(void** parent, PtexCacheImpl* cache, int size) : PtexCachedData(parent, cache, size), _data(malloc(size)) {} void* data() { return _data; } private: virtual ~LargeMetaData() { free(_data); } void* _data; }; struct Entry { const char* key; // ptr to map key string MetaDataType type; // meta data type uint32_t datasize; // size of data in bytes void* data; // if lmd, data only valid when lmd is loaded and ref'ed bool isLmd; // true if data is a large meta data block LargeMetaData* lmdData; // large meta data (lazy-loaded, lru-cached) FilePos lmdPos; // large meta data file position uint32_t lmdZipSize; // large meta data size on disk Entry() : key(0), type(MetaDataType(0)), datasize(0), data(0), isLmd(0), lmdData(0), lmdPos(0), lmdZipSize(0) {} ~Entry() { clear(); } void clear() { if (isLmd) { isLmd = 0; if (lmdData) { lmdData->orphan(); lmdData = 0; } lmdPos = 0; lmdZipSize = 0; } else { free(data); } data = 0; } }; Entry* newEntry(uint8_t keysize, const char* key, uint8_t datatype, uint32_t datasize) { std::pair result = _map.insert(std::make_pair(std::string(key, keysize), Entry())); Entry* e = &result.first->second; bool newEntry = result.second; if (newEntry) _entries.push_back(e); else e->clear(); e->key = result.first->first.c_str(); e->type = MetaDataType(datatype); e->datasize = datasize; return e; } Entry* getEntry(const char* key); PtexReader* _reader; typedef std::map MetaMap; MetaMap _map; safevector _entries; std::vector _lmdRefs; }; class ConstDataPtr : public PtexFaceData { public: ConstDataPtr(void* data, int pixelsize) : _data(data), _pixelsize(pixelsize) {} virtual void release() { delete this; } virtual Ptex::Res res() { return 0; } virtual bool isConstant() { return true; } virtual void getPixel(int, int, void* result) { memcpy(result, _data, _pixelsize); } virtual void* getData() { return _data; } virtual bool isTiled() { return false; } virtual Ptex::Res tileRes() { return 0; } virtual PtexFaceData* getTile(int) { return 0; } protected: void* _data; int _pixelsize; }; class FaceData : public PtexCachedData, public PtexFaceData { public: FaceData(void** parent, PtexCacheImpl* cache, Res res, int size) : PtexCachedData(parent, cache, size), _res(res) {} virtual void release() { AutoLockCache lock(_cache->cachelock); unref(); } virtual Ptex::Res res() { return _res; } virtual void reduce(FaceData*&, PtexReader*, Res newres, PtexUtils::ReduceFn) = 0; protected: Res _res; }; class PackedFace : public FaceData { public: PackedFace(void** parent, PtexCacheImpl* cache, Res res, int pixelsize, int size) : FaceData(parent, cache, res, sizeof(*this)+size), _pixelsize(pixelsize), _data(malloc(size)) {} void* data() { return _data; } virtual bool isConstant() { return false; } virtual void getPixel(int u, int v, void* result) { memcpy(result, (char*)_data + (v*_res.u() + u) * _pixelsize, _pixelsize); } virtual void* getData() { return _data; } virtual bool isTiled() { return false; } virtual Ptex::Res tileRes() { return _res; } virtual PtexFaceData* getTile(int) { return 0; } virtual void reduce(FaceData*&, PtexReader*, Res newres, PtexUtils::ReduceFn); protected: virtual ~PackedFace() { free(_data); } int _pixelsize; void* _data; }; class ConstantFace : public PackedFace { public: ConstantFace(void** parent, PtexCacheImpl* cache, int pixelsize) : PackedFace(parent, cache, 0, pixelsize, pixelsize) {} virtual bool isConstant() { return true; } virtual void getPixel(int, int, void* result) { memcpy(result, _data, _pixelsize); } virtual void reduce(FaceData*&, PtexReader*, Res newres, PtexUtils::ReduceFn); }; class TiledFaceBase : public FaceData { public: TiledFaceBase(void** parent, PtexCacheImpl* cache, Res res, Res tileres, DataType dt, int nchan) : FaceData(parent, cache, res, sizeof(*this)), _tileres(tileres), _dt(dt), _nchan(nchan), _pixelsize(DataSize(dt)*nchan) { _ntilesu = _res.ntilesu(tileres); _ntilesv = _res.ntilesv(tileres); _ntiles = _ntilesu*_ntilesv; _tiles.resize(_ntiles); incSize(sizeof(FaceData*)*_ntiles); } virtual void release() { // Tiled faces ref the reader (directly or indirectly) and // thus may trigger cache deletion on release. Call cache // to check for pending delete. // Note: release() may delete "this", so save _cache in // local var. PtexCacheImpl* cache = _cache; FaceData::release(); cache->handlePendingDelete(); } virtual bool isConstant() { return false; } virtual void getPixel(int u, int v, void* result); virtual void* getData() { return 0; } virtual bool isTiled() { return true; } virtual Ptex::Res tileRes() { return _tileres; } virtual void reduce(FaceData*&, PtexReader*, Res newres, PtexUtils::ReduceFn); Res tileres() const { return _tileres; } int ntilesu() const { return _ntilesu; } int ntilesv() const { return _ntilesv; } int ntiles() const { return _ntiles; } protected: virtual ~TiledFaceBase() { orphanList(_tiles); } Res _tileres; DataType _dt; int _nchan; int _ntilesu; int _ntilesv; int _ntiles; int _pixelsize; safevector _tiles; }; class TiledFace : public TiledFaceBase { public: TiledFace(void** parent, PtexCacheImpl* cache, Res res, Res tileres, int levelid, PtexReader* reader) : TiledFaceBase(parent, cache, res, tileres, reader->datatype(), reader->nchannels()), _reader(reader), _levelid(levelid) { _fdh.resize(_ntiles), _offsets.resize(_ntiles); incSize((sizeof(FaceDataHeader)+sizeof(FilePos))*_ntiles); } virtual PtexFaceData* getTile(int tile) { AutoLockCache locker(_cache->cachelock); FaceData*& f = _tiles[tile]; if (!f) readTile(tile, f); else f->ref(); return f; } void readTile(int tile, FaceData*& data); protected: friend class PtexReader; PtexReader* _reader; int _levelid; safevector _fdh; safevector _offsets; }; class TiledReducedFace : public TiledFaceBase { public: TiledReducedFace(void** parent, PtexCacheImpl* cache, Res res, Res tileres, DataType dt, int nchan, TiledFaceBase* parentface, PtexUtils::ReduceFn reducefn) : TiledFaceBase(parent, cache, res, tileres, dt, nchan), _parentface(parentface), _reducefn(reducefn) { AutoLockCache locker(_cache->cachelock); _parentface->ref(); } ~TiledReducedFace() { _parentface->unref(); } virtual PtexFaceData* getTile(int tile); protected: TiledFaceBase* _parentface; PtexUtils::ReduceFn* _reducefn; }; class Level : public PtexCachedData { public: safevector fdh; safevector offsets; safevector faces; Level(void** parent, PtexCacheImpl* cache, int nfaces) : PtexCachedData(parent, cache, sizeof(*this) + nfaces * (sizeof(FaceDataHeader) + sizeof(FilePos) + sizeof(FaceData*))), fdh(nfaces), offsets(nfaces), faces(nfaces) {} protected: virtual ~Level() { orphanList(faces); } }; Mutex readlock; Mutex reducelock; protected: virtual ~PtexReader(); void setError(const char* error) { _error = error; _error += " PtexFile: "; _error += _path; _ok = 0; } FilePos tell() { return _pos; } void seek(FilePos pos) { if (pos != _pos) { _io->seek(_fp, pos); _pos = pos; STATS_INC(nseeks); } } bool readBlock(void* data, int size, bool reportError=true); bool readZipBlock(void* data, int zipsize, int unzipsize); Level* getLevel(int levelid) { Level*& level = _levels[levelid]; if (!level) readLevel(levelid, level); else level->ref(); return level; } uint8_t* getConstData() { if (!_constdata) readConstData(); return _constdata; } FaceData* getFace(int levelid, Level* level, int faceid) { FaceData*& face = level->faces[faceid]; if (!face) readFace(levelid, level, faceid); else face->ref(); return face; } Res getRes(int levelid, int faceid) { if (levelid == 0) return _faceinfo[faceid].res; else { // for reduction level, look up res via rfaceid Res res = _res_r[faceid]; // and adjust for number of reductions return Res(res.ulog2 - levelid, res.vlog2 - levelid); } } int unpackedSize(FaceDataHeader fdh, int levelid, int faceid) { if (fdh.encoding() == enc_constant) // level 0 constant faces are not stored return levelid == 0 ? 0 : _pixelsize; else return getRes(levelid, faceid).size() * _pixelsize; } void readFaceInfo(); void readLevelInfo(); void readConstData(); void readLevel(int levelid, Level*& level); void readFace(int levelid, Level* level, int faceid); void readFaceData(FilePos pos, FaceDataHeader fdh, Res res, int levelid, FaceData*& face); void readMetaData(); void readMetaDataBlock(MetaData* metadata, FilePos pos, int zipsize, int memsize); void readLargeMetaDataHeaders(MetaData* metadata, FilePos pos, int zipsize, int memsize); void readEditData(); void readEditFaceData(); void readEditMetaData(); void computeOffsets(FilePos pos, int noffsets, const FaceDataHeader* fdh, FilePos* offsets) { FilePos* end = offsets + noffsets; while (offsets != end) { *offsets++ = pos; pos += fdh->blocksize(); fdh++; } } void blendFaces(FaceData*& face, int faceid, Res res, bool blendu); PtexInputHandler* _io; // IO handler bool _premultiply; // true if reader should premultiply the alpha chan bool _ownsCache; // true if reader owns the cache bool _ok; // flag set if read error occurred) std::string _error; // error string (if !_ok) PtexInputHandler::Handle _fp; // file pointer FilePos _pos; // current seek position std::string _path; // current file path Header _header; // the header ExtHeader _extheader; // extended header FilePos _faceinfopos; // file positions of data sections FilePos _constdatapos; // ... FilePos _levelinfopos; FilePos _leveldatapos; FilePos _metadatapos; FilePos _lmdheaderpos; FilePos _lmddatapos; FilePos _editdatapos; int _pixelsize; // size of a pixel in bytes uint8_t* _constdata; // constant pixel value per face MetaData* _metadata; // meta data (read on demand) bool _hasEdits; // has edit blocks safevector _faceinfo; // per-face header info safevector _rfaceids; // faceids sorted in reduction order safevector _res_r; // face res indexed by rfaceid safevector _levelinfo; // per-level header info safevector _levelpos; // file position of each level's data safevector _levels; // level data (read on demand) struct MetaEdit { FilePos pos; int zipsize; int memsize; }; safevector _metaedits; struct FaceEdit { FilePos pos; int faceid; FaceDataHeader fdh; }; safevector _faceedits; struct ReductionKey { int faceid; Res res; ReductionKey() : faceid(0), res(0,0) {} ReductionKey(uint32_t faceid, Res res) : faceid(faceid), res(res) {} bool operator==(const ReductionKey& k) const { return k.faceid == faceid && k.res == res; } struct Hasher { uint32_t operator() (const ReductionKey& key) const { // constants from Knuth static uint32_t M = 1664525, C = 1013904223; uint32_t val = (key.res.ulog2 * M + key.res.vlog2 + C) * M + key.faceid; return val; } }; }; typedef PtexHashMap ReductionMap; ReductionMap _reductions; z_stream_s _zstream; }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexCache.cpp0000644000175000017500000003123512271062644023035 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ /** @file PtexCache.cpp @brief LRU Cache Implementation Ownership. The cache owns all files and data. If an object is in use, the cache will not delete it. When it is no longer in use, it may be kept or may be deleted to keep resource usage under the set limits. Deletions are done in lru order. Resource Tracking. All objects are created as part of the cache and have a ptr back to the cache. Each object updates the cache's resource total when it is created or deleted. Unused objects are kept in an lru list in the cache. Only objects in the lru list can be deleted. Reference Counting. Every object has a ref count to track whether it is being used. But objects don't generally ref their parent or children (otherwise nothing would get freed). A data handle must hold onto (and ref) all the objects it is using or may need in the future. E.g. For a non-tiled face, this is just the single face data block. For a tiled face, the file, the tiled face, and the current tile must all be ref'd. Parents, Children, and Orphans. Every object must be reachable by some other object, generally the object that created it, i.e. it's parent. Even though the parent doesn't own it's children (the cache does), it must still track them. Parentless objects (i.e. orphans) are not reachable and are not retained in the cache. When any object is deleted (file, tiled face, etc.), it must orphan its children. If an orphaned child is not in use, then it is immediately deleted. Otherwise, the child's parent ptr is set to null and the child is deleted when it is no longer in use. A parent may also orphan a child that it no longer needs; the behavior is the same. Each object stores a ptr to its own entry within its parent. When the object is deleted by the cache, it clears this pointer so that the parent no longer sees it. Cache LifeTime. When a cache is released from its owner, it will delete itself but only after all objects it owns are no longer in use. To do this, a ref count on the cache is used. The owner holds 1 ref (only one owner allowed), and each object holds a ref (maintained internally). Threading. To fully support multi-threading, the following data structures must be protected with a mutex: the cache lru lists, ref counts, and parent/child ptrs. This is done with a single mutex per cache. To avoid the need for recursive locks and to minimize the number of lock points, this mutex is locked and unlocked primarily at the external api boundary for methods that affect the cache state: (e.g. getMetaData, getData, getTile, release, purge, and purgeAll). Care must be taken to release the cache lock when calling any external api from within the library. Also, in order to prevent thread starvation, the cache lock is released during file reads and significant computation such as generating an image data reduction. Additional mutexes are used to prevent contention in these cases: - 1 mutex per cache to prevent concurrent file opens - 1 mutex per file to prevent concurrent file reads - 1 mutex per file to prevent concurrent (and possibly redundant) reductions. */ #include "PtexPlatform.h" #include #include #include #include #include #include "Ptexture.h" #include "PtexReader.h" #include "PtexCache.h" #ifdef GATHER_STATS namespace PtexInternal { CacheStats::~CacheStats() { if (getenv("PTEX_STATS")) print(); } void CacheStats::print() { if (nfilesOpened || ndataAllocated || nblocksRead) { printf("Ptex Stats:\n"); printf(" nfilesOpened: %6d\n", nfilesOpened); printf(" nfilesClosed: %6d\n", nfilesClosed); printf(" ndataAllocated: %6d\n", ndataAllocated); printf(" ndataFreed: %6d\n", ndataFreed); printf(" nblocksRead: %6d\n", nblocksRead); printf(" nseeks: %6d\n", nseeks); if (nblocksRead) printf(" avgReadSize: %6d\n", int(nbytesRead/nblocksRead)); if (nseeks) printf(" avgSeqReadSize: %6d\n", int(nbytesRead/nseeks)); printf(" MbytesRead: %6.2f\n", nbytesRead/(1024.0*1024.0)); } } CacheStats stats; } #endif PtexCacheImpl::~PtexCacheImpl() { // explicitly pop all unused items so that they are // destroyed while cache is still valid AutoLockCache locker(cachelock); while (_unusedData.pop()) continue; while (_unusedFiles.pop()) continue; } void PtexCacheImpl::setFileInUse(PtexLruItem* file) { assert(cachelock.locked()); _unusedFiles.extract(file); _unusedFileCount--; } void PtexCacheImpl::setFileUnused(PtexLruItem* file) { assert(cachelock.locked()); _unusedFiles.push(file); _unusedFileCount++; } void PtexCacheImpl::removeFile() { // cachelock should be locked, but might not be if cache is being deleted _unusedFileCount--; STATS_INC(nfilesClosed); } void PtexCacheImpl::setDataInUse(PtexLruItem* data, int size) { assert(cachelock.locked()); _unusedData.extract(data); _unusedDataCount--; _unusedDataSize -= size; } void PtexCacheImpl::setDataUnused(PtexLruItem* data, int size) { assert(cachelock.locked()); _unusedData.push(data); _unusedDataCount++; _unusedDataSize += size; } void PtexCacheImpl::removeData(int size) { // cachelock should be locked, but might not be if cache is being deleted _unusedDataCount--; _unusedDataSize -= size; STATS_INC(ndataFreed); } /** Cache for reading Ptex texture files */ class PtexReaderCache : public PtexCacheImpl { public: PtexReaderCache(int maxFiles, int maxMem, bool premultiply, PtexInputHandler* handler) : PtexCacheImpl(maxFiles, maxMem), _io(handler), _cleanupCount(0), _premultiply(premultiply) {} ~PtexReaderCache() { // orphan all files since we're about to delete the file table // and we don't want the base dtor to try to access it purgeAll(); } virtual void setSearchPath(const char* path) { // get the open lock since the path is used during open operations AutoMutex locker(openlock); // record path _searchpath = path ? path : ""; // split into dirs _searchdirs.clear(); char* buff = strdup(path); char* pos = 0; char* token = strtok_r(buff, ":", &pos); while (token) { if (token[0]) _searchdirs.push_back(token); token = strtok_r(0, ":", &pos); } free(buff); } virtual const char* getSearchPath() { // get the open lock since the path is used during open operations AutoMutex locker(openlock); return _searchpath.c_str(); } virtual PtexTexture* get(const char* path, Ptex::String& error); virtual void purge(PtexTexture* texture) { PtexReader* reader = dynamic_cast(texture); if (!reader) return; purge(reader->path()); } virtual void purge(const char* filename) { AutoLockCache locker(cachelock); FileMap::iterator iter = _files.find(filename); if (iter != _files.end()) { PtexReader* reader = iter->second; if (reader && intptr_t(reader) != -1) { reader->orphan(); iter->second = 0; } _files.erase(iter); } } virtual void purgeAll() { AutoLockCache locker(cachelock); FileMap::iterator iter = _files.begin(); while (iter != _files.end()) { PtexReader* reader = iter->second; if (reader && intptr_t(reader) != -1) { reader->orphan(); iter->second = 0; } iter = _files.erase(iter); } } void removeBlankEntries() { // remove blank file entries to keep map size in check for (FileMap::iterator i = _files.begin(); i != _files.end();) { if (i->second == 0) i = _files.erase(i); else i++; } } private: PtexInputHandler* _io; std::string _searchpath; std::vector _searchdirs; typedef PtexDict FileMap; FileMap _files; int _cleanupCount; bool _premultiply; }; PtexTexture* PtexReaderCache::get(const char* filename, Ptex::String& error) { AutoLockCache locker(cachelock); // lookup reader in map PtexReader* reader = _files[filename]; if (reader) { // -1 means previous open attempt failed if (intptr_t(reader) == -1) return 0; reader->ref(); return reader; } else { bool ok = true; // get open lock and make sure we still need to open // temporarily release cache lock while we open acquire open lock cachelock.unlock(); AutoMutex openlocker(openlock); cachelock.lock(); // lookup entry again (it might have changed in another thread) PtexReader** entry = &_files[filename]; if (*entry) { // another thread opened it while we were waiting if (intptr_t(*entry) == -1) return 0; (*entry)->ref(); return *entry; } // make a new reader reader = new PtexReader((void**)entry, this, _premultiply, _io); // temporarily release cache lock while we open the file cachelock.unlock(); std::string tmppath; const char* pathToOpen = filename; if (!_io) { bool isAbsolute = (filename[0] == '/' #ifdef WINDOWS || filename[0] == '\\' || (isalpha(filename[0]) && filename[1] == ':') #endif ); if (!isAbsolute && !_searchdirs.empty()) { // file is relative, search in searchpath tmppath.reserve(256); // minimize reallocs (will grow automatically) bool found = false; struct stat statbuf; for (size_t i = 0, size = _searchdirs.size(); i < size; i++) { tmppath = _searchdirs[i]; tmppath += "/"; tmppath += filename; if (stat(tmppath.c_str(), &statbuf) == 0) { found = true; pathToOpen = tmppath.c_str(); break; } } if (!found) { std::string errstr = "Can't find ptex file: "; errstr += filename; error = errstr.c_str(); ok = false; } } } if (ok) ok = reader->open(pathToOpen, error); // reacquire cache lock cachelock.lock(); if (!ok) { // open failed, clear parent ptr and unref to delete *entry = reader; // to pass parent check in orphan() reader->orphan(); reader->unref(); *entry = (PtexReader*)-1; // flag for future lookups return 0; } // successful open, record in _files map entry *entry = reader; // clean up unused files purgeFiles(); // Cleanup map every so often so it doesn't get HUGE // from being filled with blank entries from dead files. // Note: this must be done while we still have the open lock! if (++_cleanupCount >= 1000) { _cleanupCount = 0; removeBlankEntries(); } } return reader; } PtexCache* PtexCache::create(int maxFiles, int maxMem, bool premultiply, PtexInputHandler* handler) { // set default files to 100 if (maxFiles <= 0) maxFiles = 100; // set default memory to 100 MB const int MB = 1024*1024; if (maxMem <= 0) maxMem = 100 * MB; // if memory is < 1 MB, warn if (maxMem < 1 * MB) { std::cerr << "Warning, PtexCache created with < 1 MB" << std::endl; } return new PtexReaderCache(maxFiles, maxMem, premultiply, handler); } openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexHalf.h0000644000175000017500000000747212271062644022357 0ustar mfvmfv#ifndef PtexHalf_h #define PtexHalf_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ /** @file PtexHalf.h @brief Half-precision floating-point type. */ #ifndef PTEXAPI # if defined(_WIN32) || defined(_WINDOWS) || defined(_MSC_VER) # ifndef PTEX_STATIC # ifdef PTEX_EXPORTS # define PTEXAPI __declspec(dllexport) # else # define PTEXAPI __declspec(dllimport) # endif # else # define PTEXAPI # endif # else # define PTEXAPI # endif #endif #include "PtexInt.h" /** @class PtexHalf @brief Half-precision (16-bit) floating-point type. This type should be compatible with opengl, openexr, and IEEE 754r. The range is [-65504.0, 65504.0] and the precision is about 1 part in 2000 (3.3 decimal places). From OpenGL spec 2.1.2: A 16-bit floating-point number has a 1-bit sign (S), a 5-bit exponent (E), and a 10-bit mantissa (M). The value of a 16-bit floating-point number is determined by the following: \verbatim (-1)^S * 0.0, if E == 0 and M == 0, (-1)^S * 2^-14 * (M/2^10), if E == 0 and M != 0, (-1)^S * 2^(E-15) * (1 + M/2^10), if 0 < E < 31, (-1)^S * INF, if E == 31 and M == 0, or NaN, if E == 31 and M != 0 \endverbatim */ struct PtexHalf { uint16_t bits; /// Default constructor, value is undefined PtexHalf() {} PtexHalf(float val) : bits(fromFloat(val)) {} PtexHalf(double val) : bits(fromFloat(float(val))) {} operator float() const { return toFloat(bits); } PtexHalf& operator=(float val) { bits = fromFloat(val); return *this; } static float toFloat(uint16_t h) { union { uint32_t i; float f; } u; u.i = h2fTable[h]; return u.f; } static uint16_t fromFloat(float val) { if (val==0) return 0; union { uint32_t i; float f; } u; u.f = val; int e = f2hTable[(u.i>>23)&0x1ff]; if (e) return e + (((u.i&0x7fffff) + 0x1000) >> 13); return fromFloat_except(u.i); } private: PTEXAPI static uint16_t fromFloat_except(uint32_t val); #ifndef DOXYGEN /* internal */ public: #endif PTEXAPI static uint32_t h2fTable[65536]; PTEXAPI static uint16_t f2hTable[512]; }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexCache.h0000644000175000017500000002066512271062644022507 0ustar mfvmfv#ifndef PtexCache_h #define PtexCache_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "PtexPlatform.h" #include #include "PtexMutex.h" #include "Ptexture.h" #include "PtexDict.h" #define USE_SPIN // use spinlocks instead of mutex for main cache lock namespace PtexInternal { #ifdef USE_SPIN typedef SpinLock CacheLock; #else typedef Mutex CacheLock; #endif typedef AutoLock AutoLockCache; #ifndef NDEBUG #define GATHER_STATS #endif #ifdef GATHER_STATS struct CacheStats{ int nfilesOpened; int nfilesClosed; int ndataAllocated; int ndataFreed; int nblocksRead; long int nbytesRead; int nseeks; CacheStats() : nfilesOpened(0), nfilesClosed(0), ndataAllocated(0), ndataFreed(0), nblocksRead(0), nbytesRead(0), nseeks(0) {} ~CacheStats(); void print(); static void inc(int& val) { static SpinLock spinlock; AutoSpin lock(spinlock); val++; } static void add(long int& val, int inc) { static SpinLock spinlock; AutoSpin lock(spinlock); val+=inc; } }; extern CacheStats stats; #define STATS_INC(x) stats.inc(stats.x); #define STATS_ADD(x, y) stats.add(stats.x, y); #else #define STATS_INC(x) #define STATS_ADD(x, y) #endif } using namespace PtexInternal; /** One item in a cache, typically an open file or a block of memory */ class PtexLruItem { public: bool inuse() { return _prev == 0; } void orphan() { // parent no longer wants me void** p = _parent; _parent = 0; assert(p && *p == this); if (!inuse()) delete this; *p = 0; } template static void orphanList(T& list) { for (typename T::iterator i=list.begin(); i != list.end(); i++) { PtexLruItem* obj = *i; if (obj) { assert(obj->_parent == (void**)&*i); obj->orphan(); } } } protected: PtexLruItem(void** parent=0) : _parent(parent), _prev(0), _next(0) {} virtual ~PtexLruItem() { // detach from parent (if any) if (_parent) { assert(*_parent == this); *_parent = 0; } // unlink from lru list (if in list) if (_prev) { _prev->_next = _next; _next->_prev = _prev; } } private: friend class PtexLruList; // maintains prev/next, deletes void** _parent; // pointer to this item within parent PtexLruItem* _prev; // prev in lru list (0 if in-use) PtexLruItem* _next; // next in lru list (0 if in-use) }; /** A list of items kept in least-recently-used (LRU) order. Only items not in use are kept in the list. */ class PtexLruList { public: PtexLruList() { _end._prev = _end._next = &_end; } ~PtexLruList() { while (pop()) continue; } void extract(PtexLruItem* node) { // remove from list node->_prev->_next = node->_next; node->_next->_prev = node->_prev; node->_next = node->_prev = 0; } void push(PtexLruItem* node) { // delete node if orphaned if (!node->_parent) delete node; else { // add to end of list node->_next = &_end; node->_prev = _end._prev; _end._prev->_next = node; _end._prev = node; } } bool pop() { if (_end._next == &_end) return 0; delete _end._next; // item will unlink itself return 1; } private: PtexLruItem _end; }; /** Ptex cache implementation. Maintains a file and memory cache within set limits */ class PtexCacheImpl : public PtexCache { public: PtexCacheImpl(int maxFiles, int maxMem) : _pendingDelete(false), _maxFiles(maxFiles), _unusedFileCount(0), _maxDataSize(maxMem), _unusedDataSize(0), _unusedDataCount(0) { /* Allow for a minimum number of data blocks so cache doesn't thrash too much if there are any really big items in the cache pushing over the limit. It's better to go over the limit in this case and make sure there's room for at least a modest number of objects in the cache. */ // try to allow for at least 10 objects per file (up to 100 files) _minDataCount = 10 * maxFiles; // but no more than 1000 if (_minDataCount > 1000) _minDataCount = 1000; } virtual void release() { delete this; } Mutex openlock; CacheLock cachelock; // internal use - only call from reader classes for deferred deletion void setPendingDelete() { _pendingDelete = true; } void handlePendingDelete() { if (_pendingDelete) delete this; } // internal use - only call from PtexCachedFile, PtexCachedData static void addFile() { STATS_INC(nfilesOpened); } void setFileInUse(PtexLruItem* file); void setFileUnused(PtexLruItem* file); void removeFile(); static void addData() { STATS_INC(ndataAllocated); } void setDataInUse(PtexLruItem* data, int size); void setDataUnused(PtexLruItem* data, int size); void removeData(int size); void purgeFiles() { while (_unusedFileCount > _maxFiles) { if (!_unusedFiles.pop()) break; // note: pop will destroy item and item destructor will // call removeFile which will decrement _unusedFileCount } } void purgeData() { while ((_unusedDataSize > _maxDataSize) && (_unusedDataCount > _minDataCount)) { if (!_unusedData.pop()) break; // note: pop will destroy item and item destructor will // call removeData which will decrement _unusedDataSize // and _unusedDataCount } } protected: ~PtexCacheImpl(); private: bool _pendingDelete; // flag set if delete is pending int _maxFiles, _unusedFileCount; // file limit, current unused file count long int _maxDataSize, _unusedDataSize; // data limit (bytes), current size int _minDataCount, _unusedDataCount; // min, current # of unused data blocks PtexLruList _unusedFiles, _unusedData; // lists of unused items }; /** Cache entry for open file handle */ class PtexCachedFile : public PtexLruItem { public: PtexCachedFile(void** parent, PtexCacheImpl* cache) : PtexLruItem(parent), _cache(cache), _refcount(1) { _cache->addFile(); } void ref() { assert(_cache->cachelock.locked()); if (!_refcount++) _cache->setFileInUse(this); } void unref() { assert(_cache->cachelock.locked()); if (!--_refcount) _cache->setFileUnused(this); } protected: virtual ~PtexCachedFile() { _cache->removeFile(); } PtexCacheImpl* _cache; private: int _refcount; }; /** Cache entry for allocated memory block */ class PtexCachedData : public PtexLruItem { public: PtexCachedData(void** parent, PtexCacheImpl* cache, int size) : PtexLruItem(parent), _cache(cache), _refcount(1), _size(size) { _cache->addData(); } void ref() { assert(_cache->cachelock.locked()); if (!_refcount++) _cache->setDataInUse(this, _size); } void unref() { assert(_cache->cachelock.locked()); if (!--_refcount) _cache->setDataUnused(this, _size); } protected: void incSize(int size) { _size += size; } virtual ~PtexCachedData() { _cache->removeData(_size); } PtexCacheImpl* _cache; private: int _refcount; int _size; }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexHashMap.h0000644000175000017500000002341212271062644023016 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ /** @file PtexHashMap.h @brief Contains PtexHashMap, a lightweight hash table. */ #ifndef PtexHashMap_h #define PtexHashMap_h /** @class PtexHashMap @brief A lightweight hash table.

The hash table automatically doubles in size when it is more than 50% full.

The interface is mostely compatible with std::hash_map<>, though not all methods are provided. Methods provided:

  • iterator begin();
  • iterator end();
  • DataType& operator[] (KeyType key);
  • iterator find(KeyType key) const;
  • bool erase(KeyType key);
  • iterator erase(iterator);
  • void clear();
  • int size() const;
@author brentb @version 1.0 brentb 11/01/2000: Initial version @version 1.1 longson 06/26/2001: Added file and class comment headers @version 1.2 brentb 105/2006: Generalized IntDict into general hash map */ /** @class PtexHashMap::iterator @brief Internal class used to provide iteration through the hash table @author brentb @version 1.0 brentb 11/01/2000: Initial version @version 1.1 longson 06/26/2001: Added file and class comment headers */ template class PtexHashMap { struct Entry; // forward decl public: typedef KeyType key_type; typedef DataType data_type; typedef HashFn hash_fn; struct value_type { key_type first; data_type second; value_type() : first(), second() {} value_type(const KeyType& first, const DataType& second) : first(first), second(second) {} }; class iterator { public: /// Default Constructor iterator() : e(0), h(0), b(0) {} /// Proper copy constructor implementation iterator(const iterator& iter) : e(iter.e), h(iter.h), b(iter.b) {} /// Operator for obtaining the value that the iterator references value_type operator*() const { if (e) return value_type((*e)->key, (*e)->val); return value_type(); } /// Pointer reference operator value_type* operator->() const { static value_type v; v = operator*(); return &v; } /// Proper assignment operator iterator& operator=(const iterator& iter) { e = iter.e; h = iter.h; b = iter.b; return *this; } /// For comparing equality of iterators bool operator==(const iterator& iter) const { return iter.e == e; } /// For comparing inequality of iterators bool operator!=(const iterator& iter) const { return iter.e != e; } /// For advancing the iterator to the next element iterator& operator++(int); private: friend class PtexHashMap; Entry** e; // pointer to prev entry or hash entry const PtexHashMap* h; int b; // bucket number }; /// Returns an iterator referencing the beginning of the table iterator begin() const { iterator iter; iter.h = this; for (iter.b = 0; iter.b < _numBuckets; iter.b++) { iter.e = &_buckets[iter.b]; if (*iter.e) return iter; } iter.e = 0; return iter; } /// Returns an iteraot referencing the location just beyond the table. iterator end() const { iterator iter; iter.h = this; iter.b = 0; iter.e = 0; return iter; } /// Default contructor initializes the hash table. PtexHashMap() : _numEntries(0), _numBuckets(0), _bucketMask(0), _buckets(0) {} /// Non-Virtual destructor by design, clears the entries in the hash table ~PtexHashMap() { clear(); } /// Locates an entry, creating a new one if necessary. /** operator[] will look up an entry and return the value. A new entry will be created (using the default ctor for DataType) if one doesn't exist. */ DataType& operator[](const KeyType& key); /// Locates an entry, without creating a new one. /** find will locate an entry, but won't create a new one. The result is returned as a pair of key and value. The returned key points to the internal key string and will remain valid until the entry is deleted. If the key is not found, both the returned key and value pointers will be NULL. */ iterator find(const KeyType& key) const; /// Will remove an entry. It will return TRUE if an entry was found. bool erase(const KeyType& key); /// Will remove an entry. It will return a iterator to the next element iterator erase(iterator iter); /// clear will remove all entries and free the table void clear(); /// number of entries in the hash int size() const { return _numEntries; } private: /// Copy constructor prohibited by design. PtexHashMap(const PtexHashMap&); // disallow /// Assignment operator prohibited by design. bool operator=(const PtexHashMap&); // disallow friend class iterator; struct Entry { Entry() : val() {} Entry* next; KeyType key; DataType val; }; /// Returns a pointer to the desired entry, based on the key. Entry** locate(const KeyType& key) const { if (!_buckets) return 0; for (Entry** e = &_buckets[hash(key) & _bucketMask]; *e; e = &(*e)->next) if ((*e)->key == key) return e; return 0; } /// Used to increase the size of the table if necessary void grow(); int _numEntries; int _numBuckets; int _bucketMask; Entry** _buckets; HashFn hash; }; template typename PtexHashMap::iterator& PtexHashMap::iterator::operator++(int) { if (e) { // move to next entry e = &(*e)->next; if (!*e) { // move to next non-empty bucket for (b++; b < h->_numBuckets; b++) { e = &h->_buckets[b]; if (*e) return *this; } e = 0; } } return *this; } template typename PtexHashMap::iterator PtexHashMap::find(const KeyType& key) const { iterator iter; Entry** e = locate(key); if (e) { iter.h = this; iter.e = e; iter.b = hash(key) & _bucketMask; } else iter = end(); return iter; } template DataType& PtexHashMap::operator[](const KeyType& key) { Entry** e = locate(key); if (e) return (*e)->val; // create a new entry _numEntries++; if (_numEntries*2 >= _numBuckets) grow(); void* ebuf = malloc(sizeof(Entry)); Entry* ne = new(ebuf) Entry; // note: placement new Entry** slot = &_buckets[hash(key) & _bucketMask]; ne->next = *slot; *slot = ne; ne->key = key; return ne->val; } template void PtexHashMap::grow() { if (!_buckets) { _numBuckets = 16; _bucketMask = _numBuckets - 1; _buckets = (Entry**) calloc(_numBuckets, sizeof(Entry*)); } else { int newsize = _numBuckets * 2; _bucketMask = newsize - 1; Entry** newbuckets = (Entry**) calloc(newsize, sizeof(Entry*)); for (int i = 0; i < _numBuckets; i++) { for (Entry* e = _buckets[i]; e;) { Entry* next = e->next; Entry** slot = &newbuckets[hash(e->key) & _bucketMask]; e->next = *slot; *slot = e; e = next; } } free(_buckets); _buckets = newbuckets; _numBuckets = newsize; } } template bool PtexHashMap::erase(const KeyType& key) { iterator iter = find(key); if (iter == end()) return 0; erase(iter); return 1; } template typename PtexHashMap::iterator PtexHashMap::erase(iterator iter) { Entry** eptr = iter.e; if (!eptr) return iter; // patch around deleted entry Entry* e = *eptr; Entry* next = e->next; if (!next) iter++; // advance iterator if at end of chain *eptr = next; // destroy entry e->~Entry(); // note: explicit dtor call free(e); _numEntries--; return iter; } template void PtexHashMap::clear() { for (iterator i = begin(); i != end(); ) i = erase(i); free(_buckets); _buckets = 0; _numEntries = 0; _numBuckets = 0; } #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexSeparableKernel.h0000644000175000017500000002645112271062644024542 0ustar mfvmfv#ifndef PtexSeparableKernel_h #define PtexSeparableKernel_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include #include #include "Ptexture.h" #include "PtexUtils.h" // Separable convolution kernel class PtexSeparableKernel : public Ptex { public: Res res; // resolution that kernel was built for int u, v; // uv offset within face data int uw, vw; // kernel width double* ku; // kernel weights in u double* kv; // kernel weights in v static const int kmax = 10; // max kernel width double kubuff[kmax]; double kvbuff[kmax]; PtexSeparableKernel() : res(0), u(0), v(0), uw(0), vw(0), ku(kubuff), kv(kvbuff) {} PtexSeparableKernel(const PtexSeparableKernel& k) { set(k.res, k.u, k.v, k.uw, k.vw, k.ku, k.kv); } PtexSeparableKernel& operator= (const PtexSeparableKernel& k) { set(k.res, k.u, k.v, k.uw, k.vw, k.ku, k.kv); return *this; } void set(Res resVal, int uVal, int vVal, int uwVal, int vwVal, const double* kuVal, const double* kvVal) { assert(uwVal <= kmax && vwVal <= kmax); res = resVal; u = uVal; v = vVal; uw = uwVal; vw = vwVal; memcpy(kubuff, kuVal, sizeof(*ku)*uw); memcpy(kvbuff, kvVal, sizeof(*kv)*vw); ku = kubuff; kv = kvbuff; } void stripZeros() { while (ku[0] == 0) { ku++; u++; uw--; } while (ku[uw-1] == 0) { uw--; } while (kv[0] == 0) { kv++; v++; vw--; } while (kv[vw-1] == 0) { vw--; } assert(uw > 0 && vw > 0); } double weight() const { return accumulate(ku, uw) * accumulate(kv, vw); } void mergeL(BorderMode mode) { int w = -u; if (mode != m_black) ku[w] += accumulate(ku, w); ku += w; uw -= w; u = 0; } void mergeR(BorderMode mode) { int w = uw + u - res.u(); double* kp = ku + uw - w; if (mode != m_black) kp[-1] += accumulate(kp, w); uw -= w; } void mergeB(BorderMode mode) { int w = -v; if (mode != m_black) kv[w] += accumulate(kv, w); kv += w; vw -= w; v = 0; } void mergeT(BorderMode mode) { int w = vw + v - res.v(); double* kp = kv + vw - w; if (mode != m_black) kp[-1] += accumulate(kp, w); vw -= w; } void splitL(PtexSeparableKernel& k) { // split off left piece of width w into k int w = -u; if (w < uw) { // normal case - split off a portion // res u v uw vw ku kv k.set(res, res.u()-w, v, w, vw, ku, kv); // update local u = 0; uw -= w; ku += w; } else { // entire kernel is split off k = *this; k.u += res.u(); u = 0; uw = 0; } } void splitR(PtexSeparableKernel& k) { // split off right piece of width w into k int w = u + uw - res.u(); if (w < uw) { // normal case - split off a portion // res u v uw vw ku kv k.set(res, 0, v, w, vw, ku + uw - w, kv); // update local uw -= w; } else { // entire kernel is split off k = *this; k.u -= res.u(); u = 0; uw = 0; } } void splitB(PtexSeparableKernel& k) { // split off bottom piece of width w into k int w = -v; if (w < vw) { // normal case - split off a portion // res u v uw vw ku kv k.set(res, u, res.v()-w, uw, w, ku, kv); // update local v = 0; vw -= w; kv += w; } else { // entire kernel is split off k = *this; k.v += res.v(); v = 0; vw = 0; } } void splitT(PtexSeparableKernel& k) { // split off top piece of width w into k int w = v + vw - res.v(); if (w < vw) { // normal case - split off a portion // res u v uw vw ku kv k.set(res, u, 0, uw, w, ku, kv + vw - w); // update local vw -= w; } else { // entire kernel is split off k = *this; k.v -= res.v(); v = 0; vw = 0; } } void flipU() { u = res.u() - u - uw; std::reverse(ku, ku+uw); } void flipV() { v = res.v() - v - vw; std::reverse(kv, kv+vw); } void swapUV() { res.swapuv(); std::swap(u, v); std::swap(uw, vw); std::swap(ku, kv); } void rotate(int rot) { // rotate kernel 'rot' steps ccw switch (rot & 3) { default: return; case 1: flipU(); swapUV(); break; case 2: flipU(); flipV(); break; case 3: flipV(); swapUV(); break; } } bool adjustMainToSubface(int eid) { // to adjust the kernel for the subface, we must adjust the res down and offset the uv coords // however, if the res is already zero, we must upres the kernel first if (res.ulog2 == 0) upresU(); if (res.vlog2 == 0) upresV(); if (res.ulog2 > 0) res.ulog2--; if (res.vlog2 > 0) res.vlog2--; // offset uv coords and determine whether target subface is the primary one bool primary = 0; int resu = res.u(), resv = res.v(); switch (eid&3) { case e_bottom: primary = (u < resu); v -= resv; if (!primary) u -= resu; break; case e_right: primary = (v < resv); if (!primary) v -= resv; break; case e_top: primary = (u >= resu); if (primary) u -= resu; break; case e_left: primary = (v >= resv); u -= resu; if (primary) v -= resv; break; } return primary; } void adjustSubfaceToMain(int eid) { switch (eid&3) { case e_bottom: v += res.v(); break; case e_right: break; case e_top: u += res.u(); break; case e_left: u += res.u(); v += res.v(); break; } res.ulog2++; res.vlog2++; } void downresU() { double* src = ku; double* dst = ku; // skip odd leading sample (if any) if (u & 1) { dst++; src++; uw--; } // combine even pairs for (int i = uw/2; i > 0; i--) { *dst++ = src[0] + src[1]; src += 2; } // copy odd trailing sample (if any) if (uw & 1) { *dst++ = *src++; } // update state u /= 2; uw = int(dst - ku); res.ulog2--; } void downresV() { double* src = kv; double* dst = kv; // skip odd leading sample (if any) if (v & 1) { dst++; src++; vw--; } // combine even pairs for (int i = vw/2; i > 0; i--) { *dst++ = src[0] + src[1]; src += 2; } // copy odd trailing sample (if any) if (vw & 1) { *dst++ = *src++; } // update state v /= 2; vw = int(dst - kv); res.vlog2--; } void upresU() { double* src = ku + uw-1; double* dst = ku + uw*2-2; for (int i = uw; i > 0; i--) { dst[0] = dst[1] = *src-- / 2; dst -=2; } uw *= 2; u *= 2; res.ulog2++; } void upresV() { double* src = kv + vw-1; double* dst = kv + vw*2-2; for (int i = vw; i > 0; i--) { dst[0] = dst[1] = *src-- / 2; dst -=2; } vw *= 2; v *= 2; res.vlog2++; } double makeSymmetric(double initialWeight) { assert(u == 0 && v == 0); // downres higher-res dimension until equal if (res.ulog2 > res.vlog2) { do { downresU(); } while(res.ulog2 > res.vlog2); } else if (res.vlog2 > res.ulog2) { do { downresV(); } while (res.vlog2 > res.ulog2); } // truncate excess samples in longer dimension uw = vw = PtexUtils::min(uw, vw); // combine corresponding u and v samples and compute new kernel weight double newWeight = 0; for (int i = 0; i < uw; i++) { double sum = ku[i] + kv[i]; ku[i] = kv[i] = sum; newWeight += sum; } newWeight *= newWeight; // equivalent to k.weight() ( = sum(ku)*sum(kv) ) // compute scale factor to compensate for weight change double scale = newWeight == 0 ? 1.0 : initialWeight / newWeight; // Note: a sharpening kernel (like Mitchell) can produce // negative weights which may cancel out when adding the two // kernel axes together, and this can cause the compensation // scale factor to spike up. We expect the scale factor to be // less than one in "normal" cases (i.e. ku*kv <= (ku+kv)^2 if ku // and kv are both positive), so clamping to -1..1 will have // no effect on positive kernels. If there are negative // weights, the clamping will just limit the amount of // sharpening happening at the corners, and the result will // still be smooth. // clamp scale factor to -1..1 range if (scale >= 1) { // scale by 1 (i.e. do nothing) } else { if (scale < -1) { // a negative scale means the original kernel had an overall negative weight // after making symmetric, the kernel will always be positive // scale ku by -1 // note: choice of u is arbitrary; we could have scaled u or v (but not both) for (int i = 0; i < uw; i++) ku[i] *= -1; newWeight = -newWeight; } else { // scale ku to restore initialWeight (again, choice of u instead of v is arbitrary) for (int i = 0; i < uw; i++) ku[i] *= scale; newWeight = initialWeight; } } return newWeight; } void apply(double* dst, void* data, DataType dt, int nChan, int nTxChan) { // dispatch specialized apply function ApplyFn fn = applyFunctions[(nChan!=nTxChan)*20 + ((unsigned)nChan<=4)*nChan*4 + dt]; fn(*this, dst, data, nChan, nTxChan); } void applyConst(double* dst, void* data, DataType dt, int nChan) { PtexUtils::applyConst(weight(), dst, data, dt, nChan); } private: typedef void (*ApplyFn)(PtexSeparableKernel& k, double* dst, void* data, int nChan, int nTxChan); typedef void (*ApplyConstFn)(double weight, double* dst, void* data, int nChan); static ApplyFn applyFunctions[40]; static ApplyConstFn applyConstFunctions[20]; static inline double accumulate(const double* p, int n) { double result = 0; for (const double* e = p + n; p != e; p++) result += *p; return result; } }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexHalf.cpp0000644000175000017500000000626212271062644022706 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include "PtexHalf.h" uint16_t PtexHalf::f2hTable[512]; uint32_t PtexHalf::h2fTable[65536]; /** Table initializations. */ static bool PtexHalfInit() { union { int i; float f; } u; for (int h = 0; h < 65536; h++) { int s = (h & 0x8000)<<16; int m = h & 0x03ff; int e = h&0x7c00; if (unsigned(e-1) < ((31<<10)-1)) { // normal case u.i = s|(((e+0x1c000)|m)<<13); } else if (e == 0) { // denormalized if (!(h&0x8000)) u.f = float(5.9604644775390625e-08*m); else u.f = float(-5.9604644775390625e-08*m); } else { // inf/nan, preserve low bits of m for nan code u.i = s|0x7f800000|(m<<13); } PtexHalf::h2fTable[h] = u.i; } for (int i = 0; i < 512; i++) { int f = i << 23; int e = (f & 0x7f800000) - 0x38000000; // normalized iff (0 < e < 31) if (unsigned(e-1) < ((31<<23)-1)) { int s = ((f>>16) & 0x8000); int m = f & 0x7fe000; // add bit 12 to round PtexHalf::f2hTable[i] = (s|((e|m)>>13))+((f>>12)&1); } } return 1; } static bool PtexHalfInitialized = PtexHalfInit(); /** Handle exceptional cases for half-to-float conversion */ uint16_t PtexHalf::fromFloat_except(uint32_t i) { uint32_t s = ((i>>16) & 0x8000); int32_t e = ((i>>13) & 0x3fc00) - 0x1c000; if (e <= 0) { // denormalized union { uint32_t i; float f; } u; u.i = i; return s | int(fabs(u.f)*1.6777216e7 + .5); } if (e == 0x23c00) // inf/nan, preserve msb bits of m for nan code return s|0x7c00|((i&0x7fffff)>>13); else // overflow - convert to inf return s|0x7c00; } openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexWriter.cpp0000644000175000017500000012012012271062644023276 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ /* Ptex writer classes: PtexIncrWriter implements "incremental" mode and simply appends "edit" blocks to the end of the file. PtexMainWriter implements both writing from scratch and updating an existing file, either to add data or to "roll up" previous incremental edits. Because the various headers (faceinfo, levelinfo, etc.) are variable-length and precede the data, and because the data size is not known until it is compressed and written, all data are written to a temp file and then copied at the end to the final location. This happens during the "finish" phase. Each time a texture is written to the file, a reduction of the texture is also generated and stored. These reductions are stored in a temporary form and recalled later as the resolution levels are generated. The final reduction for each face is averaged and stored in the const data block. */ #include "PtexPlatform.h" #include #include #include #include #include #include #include #include #if defined (__FreeBSD__) #include #endif #include "filesystem.h" #include "Ptexture.h" #include "PtexUtils.h" #include "PtexWriter.h" namespace { FILE* OpenTempFile(std::string& tmppath) { static Mutex lock; AutoMutex locker(lock); // choose temp dir static std::string tmpdir; static int initialized = 0; if (!initialized) { initialized = 1; #ifdef WINDOWS // use GetTempPath API (first call determines length of result) DWORD result = ::GetTempPath(0, (LPTSTR) L""); if (result > 0) { std::vector tempPath(result + 1); result = ::GetTempPath(static_cast(tempPath.size()), &tempPath[0]); if (result > 0 && result <= tempPath.size()) tmpdir = std::string(tempPath.begin(), tempPath.begin() + static_cast(result)); else tmpdir = "."; } #else // try $TEMP or $TMP, use /tmp as last resort const char* t = getenv("TEMP"); if (!t) t = getenv("TMP"); if (!t) t = "/tmp"; tmpdir = t; #endif } // build temp path #ifdef WINDOWS // use process id and counter to make unique filename std::stringstream s; static int count = 0; s << tmpdir << "/" << "PtexTmp" << _getpid() << "_" << ++count; tmppath = s.str(); return fopen((char*) tmppath.c_str(), "wb+"); #else // use mkstemp to open unique file tmppath = tmpdir + "/PtexTmpXXXXXX"; int fd = mkstemp((char*) tmppath.c_str()); return fdopen(fd, "w+"); #endif } std::string fileError(const char* message, const char* path) { std::stringstream str; str << message << path << "\n" << strerror(errno); return str.str(); } bool checkFormat(Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, Ptex::String& error) { // check to see if given file attributes are valid if (!PtexIO::LittleEndian()) { error = "PtexWriter doesn't currently support big-endian cpu's"; return 0; } if (mt < Ptex::mt_triangle || mt > Ptex::mt_quad) { error = "PtexWriter error: Invalid mesh type"; return 0; } if (dt < Ptex::dt_uint8 || dt > Ptex::dt_float) { error = "PtexWriter error: Invalid data type"; return 0; } if (nchannels <= 0) { error = "PtexWriter error: Invalid number of channels"; return 0; } if (alphachan != -1 && (alphachan < 0 || alphachan >= nchannels)) { error = "PtexWriter error: Invalid alpha channel"; return 0; } return 1; } } PtexWriter* PtexWriter::open(const char* path, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces, Ptex::String& error, bool genmipmaps) { if (!checkFormat(mt, dt, nchannels, alphachan, error)) return 0; PtexMainWriter* w = new PtexMainWriter(path, 0, mt, dt, nchannels, alphachan, nfaces, genmipmaps); std::string errstr; if (!w->ok(error)) { w->release(); return 0; } return w; } PtexWriter* PtexWriter::edit(const char* path, bool incremental, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces, Ptex::String& error, bool genmipmaps) { if (!checkFormat(mt, dt, nchannels, alphachan, error)) return 0; // try to open existing file (it might not exist) FILE* fp = OIIO::Filesystem::fopen(path, "rb+"); if (!fp && errno != ENOENT) { error = fileError("Can't open ptex file for update: ", path).c_str(); } PtexWriterBase* w = 0; // use incremental writer iff incremental mode requested and file exists if (incremental && fp) { w = new PtexIncrWriter(path, fp, mt, dt, nchannels, alphachan, nfaces); } // otherwise use main writer else { PtexTexture* tex = 0; if (fp) { // got an existing file, close and reopen with PtexReader fclose(fp); // open reader for existing file tex = PtexTexture::open(path, error); if (!tex) return 0; // make sure header matches bool headerMatch = (mt == tex->meshType() && dt == tex->dataType() && nchannels == tex->numChannels() && alphachan == tex->alphaChannel() && nfaces == tex->numFaces()); if (!headerMatch) { std::stringstream str; str << "PtexWriter::edit error: header doesn't match existing file, " << "conversions not currently supported"; error = str.str().c_str(); return 0; } } w = new PtexMainWriter(path, tex, mt, dt, nchannels, alphachan, nfaces, genmipmaps); } if (!w->ok(error)) { w->release(); return 0; } return w; } bool PtexWriter::applyEdits(const char* path, Ptex::String& error) { // open reader for existing file PtexTexture* tex = PtexTexture::open(path, error); if (!tex) return 0; // see if we have any edits to apply if (tex->hasEdits()) { // create non-incremental writer PtexWriter* w = new PtexMainWriter(path, tex, tex->meshType(), tex->dataType(), tex->numChannels(), tex->alphaChannel(), tex->numFaces(), tex->hasMipMaps()); // close to rebuild file if (!w->close(error)) return 0; w->release(); } return 1; } PtexWriterBase::PtexWriterBase(const char* path, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces, bool compress) : _ok(true), _path(path), _tilefp(0) { memset(&_header, 0, sizeof(_header)); _header.magic = Magic; _header.version = PtexFileMajorVersion; _header.minorversion = PtexFileMinorVersion; _header.meshtype = mt; _header.datatype = dt; _header.alphachan = alphachan; _header.nchannels = nchannels; _header.nfaces = nfaces; _header.nlevels = 0; _header.extheadersize = sizeof(_extheader); _pixelSize = _header.pixelSize(); memset(&_extheader, 0, sizeof(_extheader)); if (mt == mt_triangle) _reduceFn = &PtexUtils::reduceTri; else _reduceFn = &PtexUtils::reduce; memset(&_zstream, 0, sizeof(_zstream)); deflateInit(&_zstream, compress ? Z_DEFAULT_COMPRESSION : 0); // create temp file for writing tiles // (must compress each tile before assembling a tiled face) std::string error; _tilefp = OpenTempFile(_tilepath); if (!_tilefp) { setError(fileError("Error creating temp file: ", _tilepath.c_str())); } } void PtexWriterBase::release() { Ptex::String error; // close writer if app didn't, and report error if any if (_tilefp && !close(error)) std::cerr << error.c_str() << std::endl; delete this; } PtexWriterBase::~PtexWriterBase() { deflateEnd(&_zstream); } bool PtexWriterBase::close(Ptex::String& error) { if (_ok) finish(); if (!_ok) getError(error); if (_tilefp) { fclose(_tilefp); unlink(_tilepath.c_str()); _tilefp = 0; } return _ok; } bool PtexWriterBase::storeFaceInfo(int faceid, FaceInfo& f, const FaceInfo& src, int flags) { if (faceid < 0 || size_t(faceid) >= _header.nfaces) { setError("PtexWriter error: faceid out of range"); return 0; } if (_header.meshtype == mt_triangle && (f.res.ulog2 != f.res.vlog2)) { setError("PtexWriter error: asymmetric face res not supported for triangle textures"); return 0; } // copy all values f = src; // and clear extraneous ones if (_header.meshtype == mt_triangle) { f.flags = 0; // no user-settable flags on triangles f.adjfaces[3] = -1; f.adjedges &= 0x3f; // clear all but bottom six bits } else { // clear non-user-settable flags f.flags &= FaceInfo::flag_subface; } // set new flags f.flags |= flags; return 1; } void PtexWriterBase::writeMeta(const char* key, const char* value) { addMetaData(key, mdt_string, value, int(strlen(value)+1)); } void PtexWriterBase::writeMeta(const char* key, const int8_t* value, int count) { addMetaData(key, mdt_int8, value, count); } void PtexWriterBase::writeMeta(const char* key, const int16_t* value, int count) { addMetaData(key, mdt_int16, value, count*sizeof(int16_t)); } void PtexWriterBase::writeMeta(const char* key, const int32_t* value, int count) { addMetaData(key, mdt_int32, value, count*sizeof(int32_t)); } void PtexWriterBase::writeMeta(const char* key, const float* value, int count) { addMetaData(key, mdt_float, value, count*sizeof(float)); } void PtexWriterBase::writeMeta(const char* key, const double* value, int count) { addMetaData(key, mdt_double, value, count*sizeof(double)); } void PtexWriterBase::writeMeta(PtexMetaData* data) { int nkeys = data->numKeys(); for (int i = 0; i < nkeys; i++) { const char* key = 0; MetaDataType type; data->getKey(i, key, type); int count; switch (type) { case mdt_string: { const char* val=0; data->getValue(key, val); writeMeta(key, val); } break; case mdt_int8: { const int8_t* val=0; data->getValue(key, val, count); writeMeta(key, val, count); } break; case mdt_int16: { const int16_t* val=0; data->getValue(key, val, count); writeMeta(key, val, count); } break; case mdt_int32: { const int32_t* val=0; data->getValue(key, val, count); writeMeta(key, val, count); } break; case mdt_float: { const float* val=0; data->getValue(key, val, count); writeMeta(key, val, count); } break; case mdt_double: { const double* val=0; data->getValue(key, val, count); writeMeta(key, val, count); } break; } } } void PtexWriterBase::addMetaData(const char* key, MetaDataType t, const void* value, int size) { if (strlen(key) > 255) { std::stringstream str; str << "PtexWriter error: meta data key too long (max=255) \"" << key << "\""; setError(str.str()); return; } if (size <= 0) { std::stringstream str; str << "PtexWriter error: meta data size <= 0 for \"" << key << "\""; setError(str.str()); } std::map::iterator iter = _metamap.find(key); int index; if (iter != _metamap.end()) { // see if we already have this entry - if so, overwrite it index = iter->second; } else { // allocate a new entry index = _metadata.size(); _metadata.resize(index+1); _metamap[key] = index; } MetaEntry& m = _metadata[index]; m.key = key; m.datatype = t; m.data.resize(size); memcpy(&m.data[0], value, size); } int PtexWriterBase::writeBlank(FILE* fp, int size) { if (!_ok) return 0; static char zeros[BlockSize] = {0}; int remain = size; while (remain > 0) { remain -= writeBlock(fp, zeros, remain < BlockSize ? remain : BlockSize); } return size; } int PtexWriterBase::writeBlock(FILE* fp, const void* data, int size) { if (!_ok) return 0; if (!fwrite(data, size, 1, fp)) { setError("PtexWriter error: file write failed"); return 0; } return size; } int PtexWriterBase::writeZipBlock(FILE* fp, const void* data, int size, bool finish) { if (!_ok) return 0; void* buff = alloca(BlockSize); _zstream.next_in = (Bytef*)data; _zstream.avail_in = size; while (1) { _zstream.next_out = (Bytef*)buff; _zstream.avail_out = BlockSize; int zresult = deflate(&_zstream, finish ? Z_FINISH : Z_NO_FLUSH); int size = BlockSize - _zstream.avail_out; if (size > 0) writeBlock(fp, buff, size); if (zresult == Z_STREAM_END) break; if (zresult != Z_OK) { setError("PtexWriter error: data compression internal error"); break; } if (!finish && _zstream.avail_out != 0) // waiting for more input break; } if (!finish) return 0; int total = _zstream.total_out; deflateReset(&_zstream); return total; } int PtexWriterBase::readBlock(FILE* fp, void* data, int size) { if (!fread(data, size, 1, fp)) { setError("PtexWriter error: temp file read failed"); return 0; } return size; } int PtexWriterBase::copyBlock(FILE* dst, FILE* src, FilePos pos, int size) { if (size <= 0) return 0; fseeko(src, pos, SEEK_SET); int remain = size; void* buff = alloca(BlockSize); while (remain) { int nbytes = remain < BlockSize ? remain : BlockSize; if (!fread(buff, nbytes, 1, src)) { setError("PtexWriter error: temp file read failed"); return 0; } if (!writeBlock(dst, buff, nbytes)) break; remain -= nbytes; } return size; } Ptex::Res PtexWriterBase::calcTileRes(Res faceres) { // desired number of tiles = floor(log2(facesize / tilesize)) int facesize = faceres.size() * _pixelSize; int ntileslog2 = PtexUtils::floor_log2(facesize/TileSize); if (ntileslog2 == 0) return faceres; // number of tiles is defined as: // ntileslog2 = ureslog2 + vreslog2 - (tile_ureslog2 + tile_vreslog2) // rearranging to solve for the tile res: // tile_ureslog2 + tile_vreslog2 = ureslog2 + vreslog2 - ntileslog2 int n = faceres.ulog2 + faceres.vlog2 - ntileslog2; // choose u and v sizes for roughly square result (u ~= v ~= n/2) // and make sure tile isn't larger than face Res tileres; tileres.ulog2 = PtexUtils::min((n+1)/2, int(faceres.ulog2)); tileres.vlog2 = PtexUtils::min(n - tileres.ulog2, int(faceres.vlog2)); return tileres; } void PtexWriterBase::writeConstFaceBlock(FILE* fp, const void* data, FaceDataHeader& fdh) { // write a single const face data block // record level data for face and output the one pixel value fdh.set(_pixelSize, enc_constant); writeBlock(fp, data, _pixelSize); } void PtexWriterBase::writeFaceBlock(FILE* fp, const void* data, int stride, Res res, FaceDataHeader& fdh) { // write a single face data block // copy to temp buffer, and deinterleave int ures = res.u(), vres = res.v(); int blockSize = ures*vres*_pixelSize; bool useMalloc = blockSize > AllocaMax; char* buff = useMalloc ? (char*) malloc(blockSize) : (char*)alloca(blockSize); PtexUtils::deinterleave(data, stride, ures, vres, buff, ures*DataSize(_header.datatype), _header.datatype, _header.nchannels); // difference if needed bool diff = (_header.datatype == dt_uint8 || _header.datatype == dt_uint16); if (diff) PtexUtils::encodeDifference(buff, blockSize, _header.datatype); // compress and stream data to file, and record size in header int zippedsize = writeZipBlock(fp, buff, blockSize); // record compressed size and encoding in data header fdh.set(zippedsize, diff ? enc_diffzipped : enc_zipped); if (useMalloc) free(buff); } void PtexWriterBase::writeFaceData(FILE* fp, const void* data, int stride, Res res, FaceDataHeader& fdh) { // determine whether to break into tiles Res tileres = calcTileRes(res); int ntilesu = res.ntilesu(tileres); int ntilesv = res.ntilesv(tileres); int ntiles = ntilesu * ntilesv; if (ntiles == 1) { // write single block writeFaceBlock(fp, data, stride, res, fdh); } else { // write tiles to tilefp temp file rewind(_tilefp); // alloc tile header std::vector tileHeader(ntiles); int tileures = tileres.u(); int tilevres = tileres.v(); int tileustride = tileures*_pixelSize; int tilevstride = tilevres*stride; // output tiles FaceDataHeader* tdh = &tileHeader[0]; int datasize = 0; const char* rowp = (const char*) data; const char* rowpend = rowp + ntilesv * tilevstride; for (; rowp != rowpend; rowp += tilevstride) { const char* p = rowp; const char* pend = p + ntilesu * tileustride; for (; p != pend; tdh++, p += tileustride) { // determine if tile is constant if (PtexUtils::isConstant(p, stride, tileures, tilevres, _pixelSize)) writeConstFaceBlock(_tilefp, p, *tdh); else writeFaceBlock(_tilefp, p, stride, tileres, *tdh); datasize += tdh->blocksize(); } } // output compressed tile header uint32_t tileheadersize = writeZipBlock(_tilefp, &tileHeader[0], int(sizeof(FaceDataHeader)*tileHeader.size())); // output tile data pre-header int totalsize = 0; totalsize += writeBlock(fp, &tileres, sizeof(Res)); totalsize += writeBlock(fp, &tileheadersize, sizeof(tileheadersize)); // copy compressed tile header from temp file totalsize += copyBlock(fp, _tilefp, datasize, tileheadersize); // copy tile data from temp file totalsize += copyBlock(fp, _tilefp, 0, datasize); fdh.set(totalsize, enc_tiled); } } void PtexWriterBase::writeReduction(FILE* fp, const void* data, int stride, Res res) { // reduce and write to file Ptex::Res newres(res.ulog2-1, res.vlog2-1); int buffsize = newres.size() * _pixelSize; bool useMalloc = buffsize > AllocaMax; char* buff = useMalloc ? (char*) malloc(buffsize) : (char*)alloca(buffsize); int dstride = newres.u() * _pixelSize; _reduceFn(data, stride, res.u(), res.v(), buff, dstride, _header.datatype, _header.nchannels); writeBlock(fp, buff, buffsize); if (useMalloc) free(buff); } int PtexWriterBase::writeMetaDataBlock(FILE* fp, MetaEntry& val) { uint8_t keysize = uint8_t(val.key.size()+1); uint8_t datatype = val.datatype; uint32_t datasize = uint32_t(val.data.size()); writeZipBlock(fp, &keysize, sizeof(keysize), false); writeZipBlock(fp, val.key.c_str(), keysize, false); writeZipBlock(fp, &datatype, sizeof(datatype), false); writeZipBlock(fp, &datasize, sizeof(datasize), false); writeZipBlock(fp, &val.data[0], datasize, false); int memsize = (sizeof(keysize) + keysize + sizeof(datatype) + sizeof(datasize) + datasize); return memsize; } PtexMainWriter::PtexMainWriter(const char* path, PtexTexture* tex, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces, bool genmipmaps) : PtexWriterBase(path, mt, dt, nchannels, alphachan, nfaces, /* compress */ true), _hasNewData(false), _genmipmaps(genmipmaps), _reader(0) { _tmpfp = OpenTempFile(_tmppath); if (!_tmpfp) { setError(fileError("Error creating temp file: ", _tmppath.c_str())); return; } // data will be written to a ".new" path and then renamed to final location _newpath = path; _newpath += ".new"; _levels.reserve(20); _levels.resize(1); // init faceinfo and set flags to -1 to mark as uninitialized _faceinfo.resize(nfaces); for (int i = 0; i < nfaces; i++) _faceinfo[i].flags = uint8_t(-1); _levels.front().pos.resize(nfaces); _levels.front().fdh.resize(nfaces); _rpos.resize(nfaces); _constdata.resize(nfaces*_pixelSize); if (tex) { // access reader implementation _reader = dynamic_cast(tex); if (!_reader) { setError("Internal error: dynamic_cast failed"); tex->release(); return; } // copy border modes setBorderModes(tex->uBorderMode(), tex->vBorderMode()); // copy meta data from existing file PtexPtr meta ( _reader->getMetaData() ); writeMeta(meta); // see if we have any edits _hasNewData = _reader->hasEdits(); } } PtexMainWriter::~PtexMainWriter() { if (_reader) _reader->release(); } bool PtexMainWriter::close(Ptex::String& error) { // closing base writer will write all pending data via finish() method // and will close _fp (which in this case is on the temp disk) bool result = PtexWriterBase::close(error); if (_reader) { _reader->release(); _reader = 0; } if (_tmpfp) { fclose(_tmpfp); unlink(_tmppath.c_str()); _tmpfp = 0; } if (result && _hasNewData) { // rename temppath into final location unlink(_path.c_str()); if (rename(_newpath.c_str(), _path.c_str()) == -1) { error = fileError("Can't write to ptex file: ", _path.c_str()).c_str(); unlink(_newpath.c_str()); result = false; } } return result; } bool PtexMainWriter::writeFace(int faceid, const FaceInfo& f, const void* data, int stride) { if (!_ok) return 0; // auto-compute stride if (stride == 0) stride = f.res.u()*_pixelSize; // handle constant case if (PtexUtils::isConstant(data, stride, f.res.u(), f.res.v(), _pixelSize)) return writeConstantFace(faceid, f, data); // non-constant case, ... // check and store face info if (!storeFaceInfo(faceid, _faceinfo[faceid], f)) return 0; // record position of current face _levels.front().pos[faceid] = ftello(_tmpfp); // write face data writeFaceData(_tmpfp, data, stride, f.res, _levels.front().fdh[faceid]); if (!_ok) return 0; // premultiply (if needed) before making reductions; use temp copy of data uint8_t* temp = 0; if (_header.hasAlpha()) { // first copy to temp buffer int rowlen = f.res.u() * _pixelSize, nrows = f.res.v(); temp = (uint8_t*) malloc(rowlen * nrows); PtexUtils::copy(data, stride, temp, rowlen, nrows, rowlen); // multiply alpha PtexUtils::multalpha(temp, f.res.size(), _header.datatype, _header.nchannels, _header.alphachan); // override source buffer data = temp; stride = rowlen; } // generate first reduction (if needed) if (_genmipmaps && (f.res.ulog2 > MinReductionLog2 && f.res.vlog2 > MinReductionLog2)) { _rpos[faceid] = ftello(_tmpfp); writeReduction(_tmpfp, data, stride, f.res); } else { storeConstValue(faceid, data, stride, f.res); } if (temp) free(temp); _hasNewData = true; return 1; } bool PtexMainWriter::writeConstantFace(int faceid, const FaceInfo& f, const void* data) { if (!_ok) return 0; // check and store face info if (!storeFaceInfo(faceid, _faceinfo[faceid], f, FaceInfo::flag_constant)) return 0; // store face value in constant block memcpy(&_constdata[faceid*_pixelSize], data, _pixelSize); _hasNewData = true; return 1; } void PtexMainWriter::storeConstValue(int faceid, const void* data, int stride, Res res) { // compute average value and store in _constdata block uint8_t* constdata = &_constdata[faceid*_pixelSize]; PtexUtils::average(data, stride, res.u(), res.v(), constdata, _header.datatype, _header.nchannels); if (_header.hasAlpha()) PtexUtils::divalpha(constdata, 1, _header.datatype, _header.nchannels, _header.alphachan); } void PtexMainWriter::finish() { // do nothing if there's no new data to write if (!_hasNewData) return; // copy missing faces from _reader if (_reader) { for (int i = 0, nfaces = _header.nfaces; i < nfaces; i++) { if (_faceinfo[i].flags == uint8_t(-1)) { // copy face data const Ptex::FaceInfo& info = _reader->getFaceInfo(i); int size = _pixelSize * info.res.size(); if (info.isConstant()) { PtexPtr data ( _reader->getData(i) ); if (data) { writeConstantFace(i, info, data->getData()); } } else { void* data = malloc(size); _reader->getData(i, data, 0); writeFace(i, info, data, 0); free(data); } } } } else { // just flag missing faces as constant (black) for (int i = 0, nfaces = _header.nfaces; i < nfaces; i++) { if (_faceinfo[i].flags == uint8_t(-1)) _faceinfo[i].flags = FaceInfo::flag_constant; } } // write reductions to tmp file if (_genmipmaps) generateReductions(); // flag faces w/ constant neighborhoods flagConstantNeighorhoods(); // update header _header.nlevels = uint16_t(_levels.size()); _header.nfaces = uint32_t(_faceinfo.size()); // create new file FILE* newfp = fopen(_newpath.c_str(), "wb+"); if (!newfp) { setError(fileError("Can't write to ptex file: ", _newpath.c_str())); return; } // write blank header (to fill in later) writeBlank(newfp, HeaderSize); writeBlank(newfp, ExtHeaderSize); // write compressed face info block _header.faceinfosize = writeZipBlock(newfp, &_faceinfo[0], sizeof(FaceInfo)*_header.nfaces); // write compressed const data block _header.constdatasize = writeZipBlock(newfp, &_constdata[0], int(_constdata.size())); // write blank level info block (to fill in later) FilePos levelInfoPos = ftello(newfp); writeBlank(newfp, LevelInfoSize * _header.nlevels); // write level data blocks (and record level info) std::vector levelinfo(_header.nlevels); for (int li = 0; li < _header.nlevels; li++) { LevelInfo& info = levelinfo[li]; LevelRec& level = _levels[li]; int nfaces = int(level.fdh.size()); info.nfaces = nfaces; // output compressed level data header info.levelheadersize = writeZipBlock(newfp, &level.fdh[0], sizeof(FaceDataHeader)*nfaces); info.leveldatasize = info.levelheadersize; // copy level data from tmp file for (int fi = 0; fi < nfaces; fi++) info.leveldatasize += copyBlock(newfp, _tmpfp, level.pos[fi], level.fdh[fi].blocksize()); _header.leveldatasize += info.leveldatasize; } rewind(_tmpfp); // write meta data (if any) if (!_metadata.empty()) writeMetaData(newfp); // update extheader for edit data position _extheader.editdatapos = ftello(newfp); // rewrite level info block fseeko(newfp, levelInfoPos, SEEK_SET); _header.levelinfosize = writeBlock(newfp, &levelinfo[0], LevelInfoSize*_header.nlevels); // rewrite header fseeko(newfp, 0, SEEK_SET); writeBlock(newfp, &_header, HeaderSize); writeBlock(newfp, &_extheader, ExtHeaderSize); fclose(newfp); } void PtexMainWriter::flagConstantNeighorhoods() { // for each constant face for (int faceid = 0, n = int(_faceinfo.size()); faceid < n; faceid++) { FaceInfo& f = _faceinfo[faceid]; if (!f.isConstant()) continue; uint8_t* constdata = &_constdata[faceid*_pixelSize]; // check to see if neighborhood is constant bool isConst = true; bool isTriangle = _header.meshtype == mt_triangle; int nedges = isTriangle ? 3 : 4; for (int eid = 0; eid < nedges; eid++) { bool prevWasSubface = f.isSubface(); int prevFid = faceid; // traverse across edge int afid = f.adjface(eid); int aeid = f.adjedge(eid); int count = 0; const int maxcount = 10; // max valence (as safety valve) while (afid != faceid) { // if we hit a boundary, assume non-const (not worth // the trouble to redo traversal from CCW direction; // also, boundary might want to be "black") // assume const if we hit max valence too if (afid < 0 || ++count == maxcount) { isConst = false; break; } // check if neighor is constant, and has the same value as face FaceInfo& af = _faceinfo[afid]; if (!af.isConstant() || 0 != memcmp(constdata, &_constdata[afid*_pixelSize], _pixelSize)) { isConst = false; break; } // traverse around vertex in CW direction // handle T junction between subfaces and main face bool isSubface = af.isSubface(); bool isT = !isTriangle && prevWasSubface && !isSubface && af.adjface(aeid) == prevFid; std::swap(prevFid, afid); prevWasSubface = isSubface; if (isT) { // traverse to secondary subface across T junction FaceInfo& pf = _faceinfo[afid]; int peid = af.adjedge(aeid); peid = (peid + 3) % 4; afid = pf.adjface(peid); aeid = pf.adjedge(peid); aeid = (aeid + 3) % 4; } else { // traverse around vertex aeid = (aeid + 1) % nedges; afid = af.adjface(aeid); aeid = af.adjedge(aeid); } } if (!isConst) break; } if (isConst) f.flags |= FaceInfo::flag_nbconstant; } } void PtexMainWriter::generateReductions() { // first generate "rfaceids", reduction faceids, // which are faceids reordered by decreasing smaller dimension int nfaces = _header.nfaces; _rfaceids.resize(nfaces); _faceids_r.resize(nfaces); PtexUtils::genRfaceids(&_faceinfo[0], nfaces, &_rfaceids[0], &_faceids_r[0]); // determine how many faces in each level, and resize _levels // traverse in reverse rfaceid order to find number of faces // larger than cutoff size of each level for (int rfaceid = nfaces-1, cutoffres = MinReductionLog2; rfaceid >= 0; rfaceid--) { int faceid = _faceids_r[rfaceid]; FaceInfo& face = _faceinfo[faceid]; Res res = face.res; int min = face.isConstant() ? 1 : PtexUtils::min(res.ulog2, res.vlog2); while (min > cutoffres) { // i == last face for current level int size = rfaceid+1; _levels.push_back(LevelRec()); LevelRec& level = _levels.back(); level.pos.resize(size); level.fdh.resize(size); cutoffres++; } } // generate and cache reductions (including const data) // first, find largest face and allocate tmp buffer int buffsize = 0; for (int i = 0; i < nfaces; i++) buffsize = PtexUtils::max(buffsize, _faceinfo[i].res.size()); buffsize *= _pixelSize; char* buff = (char*) malloc(buffsize); int nlevels = int(_levels.size()); for (int i = 1; i < nlevels; i++) { LevelRec& level = _levels[i]; int nextsize = (i+1 < nlevels)? int(_levels[i+1].fdh.size()) : 0; for (int rfaceid = 0, size = int(level.fdh.size()); rfaceid < size; rfaceid++) { // output current reduction for face (previously generated) int faceid = _faceids_r[rfaceid]; Res res = _faceinfo[faceid].res; res.ulog2 -= i; res.vlog2 -= i; int stride = res.u() * _pixelSize; int blocksize = res.size() * _pixelSize; fseeko(_tmpfp, _rpos[faceid], SEEK_SET); readBlock(_tmpfp, buff, blocksize); fseeko(_tmpfp, 0, SEEK_END); level.pos[rfaceid] = ftello(_tmpfp); writeFaceData(_tmpfp, buff, stride, res, level.fdh[rfaceid]); if (!_ok) return; // write a new reduction if needed for next level if (rfaceid < nextsize) { fseeko(_tmpfp, _rpos[faceid], SEEK_SET); writeReduction(_tmpfp, buff, stride, res); } else { // the last reduction for each face is its constant value storeConstValue(faceid, buff, stride, res); } } } fseeko(_tmpfp, 0, SEEK_END); free(buff); } void PtexMainWriter::writeMetaData(FILE* fp) { std::vector lmdEntries; // large meta data items // write small meta data items in a single zip block for (int i = 0, n = _metadata.size(); i < n; i++) { MetaEntry& e = _metadata[i]; #ifndef PTEX_NO_LARGE_METADATA_BLOCKS if (int(e.data.size()) > MetaDataThreshold) { // skip large items, but record for later lmdEntries.push_back(&e); } else #endif { // add small item to zip block _header.metadatamemsize += writeMetaDataBlock(fp, e); } } if (_header.metadatamemsize) { // finish zip block _header.metadatazipsize = writeZipBlock(fp, 0, 0, /*finish*/ true); } // write compatibility barrier writeBlank(fp, sizeof(uint64_t)); // write large items as separate blocks int nLmd = lmdEntries.size(); if (nLmd > 0) { // write data records to tmp file and accumulate zip sizes for lmd header std::vector lmdoffset(nLmd); std::vector lmdzipsize(nLmd); for (int i = 0; i < nLmd; i++) { MetaEntry* e= lmdEntries[i]; lmdoffset[i] = ftello(_tmpfp); lmdzipsize[i] = writeZipBlock(_tmpfp, &e->data[0], e->data.size()); } // write lmd header records as single zip block for (int i = 0; i < nLmd; i++) { MetaEntry* e = lmdEntries[i]; uint8_t keysize = uint8_t(e->key.size()+1); uint8_t datatype = e->datatype; uint32_t datasize = e->data.size(); uint32_t zipsize = lmdzipsize[i]; writeZipBlock(fp, &keysize, sizeof(keysize), false); writeZipBlock(fp, e->key.c_str(), keysize, false); writeZipBlock(fp, &datatype, sizeof(datatype), false); writeZipBlock(fp, &datasize, sizeof(datasize), false); writeZipBlock(fp, &zipsize, sizeof(zipsize), false); _extheader.lmdheadermemsize += sizeof(keysize) + keysize + sizeof(datatype) + sizeof(datasize) + sizeof(zipsize); } _extheader.lmdheaderzipsize = writeZipBlock(fp, 0, 0, /*finish*/ true); // copy data records for (int i = 0; i < nLmd; i++) { _extheader.lmddatasize += copyBlock(fp, _tmpfp, lmdoffset[i], lmdzipsize[i]); } } } PtexIncrWriter::PtexIncrWriter(const char* path, FILE* fp, Ptex::MeshType mt, Ptex::DataType dt, int nchannels, int alphachan, int nfaces) : PtexWriterBase(path, mt, dt, nchannels, alphachan, nfaces, /* compress */ false), _fp(fp) { // note: incremental saves are not compressed (see compress flag above) // to improve save time in the case where in incremental save is followed by // a full save (which ultimately it always should be). With a compressed // incremental save, the data would be compressed twice and decompressed once // on every save vs. just compressing once. // make sure existing header matches if (!fread(&_header, PtexIO::HeaderSize, 1, fp) || _header.magic != Magic) { std::stringstream str; str << "Not a ptex file: " << path; setError(str.str()); return; } bool headerMatch = (mt == _header.meshtype && dt == _header.datatype && nchannels == _header.nchannels && alphachan == int(_header.alphachan) && nfaces == int(_header.nfaces)); if (!headerMatch) { std::stringstream str; str << "PtexWriter::edit error: header doesn't match existing file, " << "conversions not currently supported"; setError(str.str()); return; } // read extended header memset(&_extheader, 0, sizeof(_extheader)); if (!fread(&_extheader, PtexUtils::min(uint32_t(ExtHeaderSize), _header.extheadersize), 1, fp)) { std::stringstream str; str << "Error reading extended header: " << path; setError(str.str()); return; } // seek to end of file to append fseeko(_fp, 0, SEEK_END); } PtexIncrWriter::~PtexIncrWriter() { } bool PtexIncrWriter::writeFace(int faceid, const FaceInfo& f, const void* data, int stride) { if (stride == 0) stride = f.res.u()*_pixelSize; // handle constant case if (PtexUtils::isConstant(data, stride, f.res.u(), f.res.v(), _pixelSize)) return writeConstantFace(faceid, f, data); // init headers uint8_t edittype = et_editfacedata; uint32_t editsize; EditFaceDataHeader efdh; efdh.faceid = faceid; // check and store face info if (!storeFaceInfo(faceid, efdh.faceinfo, f)) return 0; // record position and skip headers FilePos pos = ftello(_fp); writeBlank(_fp, sizeof(edittype) + sizeof(editsize) + sizeof(efdh)); // must compute constant (average) val first uint8_t* constval = (uint8_t*) malloc(_pixelSize); if (_header.hasAlpha()) { // must premult alpha before averaging // first copy to temp buffer int rowlen = f.res.u() * _pixelSize, nrows = f.res.v(); uint8_t* temp = (uint8_t*) malloc(rowlen * nrows); PtexUtils::copy(data, stride, temp, rowlen, nrows, rowlen); // multiply alpha PtexUtils::multalpha(temp, f.res.size(), _header.datatype, _header.nchannels, _header.alphachan); // average PtexUtils::average(temp, rowlen, f.res.u(), f.res.v(), constval, _header.datatype, _header.nchannels); // unmult alpha PtexUtils::divalpha(constval, 1, _header.datatype, _header.nchannels, _header.alphachan); free(temp); } else { // average PtexUtils::average(data, stride, f.res.u(), f.res.v(), constval, _header.datatype, _header.nchannels); } // write const val writeBlock(_fp, constval, _pixelSize); free(constval); // write face data writeFaceData(_fp, data, stride, f.res, efdh.fdh); // update editsize in header editsize = sizeof(efdh) + _pixelSize + efdh.fdh.blocksize(); // rewind and write headers fseeko(_fp, pos, SEEK_SET); writeBlock(_fp, &edittype, sizeof(edittype)); writeBlock(_fp, &editsize, sizeof(editsize)); writeBlock(_fp, &efdh, sizeof(efdh)); fseeko(_fp, 0, SEEK_END); return 1; } bool PtexIncrWriter::writeConstantFace(int faceid, const FaceInfo& f, const void* data) { // init headers uint8_t edittype = et_editfacedata; uint32_t editsize; EditFaceDataHeader efdh; efdh.faceid = faceid; efdh.fdh.set(0, enc_constant); editsize = sizeof(efdh) + _pixelSize; // check and store face info if (!storeFaceInfo(faceid, efdh.faceinfo, f, FaceInfo::flag_constant)) return 0; // write headers writeBlock(_fp, &edittype, sizeof(edittype)); writeBlock(_fp, &editsize, sizeof(editsize)); writeBlock(_fp, &efdh, sizeof(efdh)); // write data writeBlock(_fp, data, _pixelSize); return 1; } void PtexIncrWriter::writeMetaDataEdit() { // init headers uint8_t edittype = et_editmetadata; uint32_t editsize; EditMetaDataHeader emdh; emdh.metadatazipsize = 0; emdh.metadatamemsize = 0; // record position and skip headers FilePos pos = ftello(_fp); writeBlank(_fp, sizeof(edittype) + sizeof(editsize) + sizeof(emdh)); // write meta data for (int i = 0, n = _metadata.size(); i < n; i++) { MetaEntry& e = _metadata[i]; emdh.metadatamemsize += writeMetaDataBlock(_fp, e); } // finish zip block emdh.metadatazipsize = writeZipBlock(_fp, 0, 0, /*finish*/ true); // update headers editsize = sizeof(emdh) + emdh.metadatazipsize; // rewind and write headers fseeko(_fp, pos, SEEK_SET); writeBlock(_fp, &edittype, sizeof(edittype)); writeBlock(_fp, &editsize, sizeof(editsize)); writeBlock(_fp, &emdh, sizeof(emdh)); fseeko(_fp, 0, SEEK_END); } bool PtexIncrWriter::close(Ptex::String& error) { // closing base writer will write all pending data via finish() method bool result = PtexWriterBase::close(error); if (_fp) { fclose(_fp); _fp = 0; } return result; } void PtexIncrWriter::finish() { // write meta data edit block (if any) if (!_metadata.empty()) writeMetaDataEdit(); // rewrite extheader for updated editdatasize if (_extheader.editdatapos) { _extheader.editdatasize = uint64_t(ftello(_fp)) - _extheader.editdatapos; fseeko(_fp, HeaderSize, SEEK_SET); if (!fwrite(&_extheader, PtexUtils::min(uint32_t(ExtHeaderSize), _header.extheadersize), 1, _fp)) { // FIXME Bad Write //error ("Bad write PtexIncrWriter::finish (err %d)", byte_count); } } } openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexFilters.cpp0000644000175000017500000003400512271062644023440 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "PtexPlatform.h" #include "Ptexture.h" #include "PtexSeparableFilter.h" #include "PtexSeparableKernel.h" #include "PtexTriangleFilter.h" namespace { /** Point-sampling filter for rectangular textures */ class PtexPointFilter : public PtexFilter, public Ptex { public: PtexPointFilter(PtexTexture* tx) : _tx(tx) {} virtual void release() { delete this; } virtual void eval(float* result, int firstchan, int nchannels, int faceid, float u, float v, float /*uw1*/, float /*vw1*/, float /*uw2*/, float /*vw2*/, float /*width*/, float /*blur*/) { if (!_tx || nchannels <= 0) return; if (faceid < 0 || faceid >= _tx->numFaces()) return; const FaceInfo& f = _tx->getFaceInfo(faceid); int resu = f.res.u(), resv = f.res.v(); int ui = PtexUtils::clamp(int(u*resu), 0, resu-1); int vi = PtexUtils::clamp(int(v*resv), 0, resv-1); _tx->getPixel(faceid, ui, vi, result, firstchan, nchannels); } private: PtexTexture* _tx; }; /** Point-sampling filter for triangular textures */ class PtexPointFilterTri : public PtexFilter, public Ptex { public: PtexPointFilterTri(PtexTexture* tx) : _tx(tx) {} virtual void release() { delete this; } virtual void eval(float* result, int firstchan, int nchannels, int faceid, float u, float v, float /*uw1*/, float /*vw1*/, float /*uw2*/, float /*vw2*/, float /*width*/, float /*blur*/) { if (!_tx || nchannels <= 0) return; if (faceid < 0 || faceid >= _tx->numFaces()) return; const FaceInfo& f = _tx->getFaceInfo(faceid); int res = f.res.u(); int resm1 = res - 1; float ut = u * res, vt = v * res; int ui = PtexUtils::clamp(int(ut), 0, resm1); int vi = PtexUtils::clamp(int(vt), 0, resm1); float uf = ut - ui, vf = vt - vi; if (uf + vf <= 1.0) { // "even" triangles are stored in lower-left half-texture _tx->getPixel(faceid, ui, vi, result, firstchan, nchannels); } else { // "odd" triangles are stored in upper-right half-texture _tx->getPixel(faceid, resm1-vi, resm1-ui, result, firstchan, nchannels); } } private: PtexTexture* _tx; }; /** Separable filter with width=4 support. The kernel width is calculated as a multiple of 4 times the filter width and the texture resolution is chosen such that each kernel axis has between 4 and 8. For kernel widths too large to handle (because the kernel would extend significantly beyond both sides of the face), a special Hermite smoothstep is used to interpolate the two nearest 2 samples along the affected axis (or axes). */ class PtexWidth4Filter : public PtexSeparableFilter { public: typedef double KernelFn(double x, const double* c); PtexWidth4Filter(PtexTexture* tx, const PtexFilter::Options& opts, KernelFn k, const double* c = 0) : PtexSeparableFilter(tx, opts), _k(k), _c(c) {} virtual void buildKernel(PtexSeparableKernel& k, float u, float v, float uw, float vw, Res faceRes) { buildKernelAxis(k.res.ulog2, k.u, k.uw, k.ku, u, uw, faceRes.ulog2); buildKernelAxis(k.res.vlog2, k.v, k.vw, k.kv, v, vw, faceRes.vlog2); } private: double blur(double x) { // 2-unit (x in -1..1) cubic hermite kernel // this produces a blur roughly 1.5 times that of the 4-unit b-spline kernel x = fabs(x); return x < 1 ? (2*x-3)*x*x+1 : 0; } void buildKernelAxis(int8_t& k_ureslog2, int& k_u, int& k_uw, double* ku, float u, float uw, int f_ureslog2) { // build 1 axis (note: "u" labels may repesent either u or v axis) // clamp filter width to no smaller than a texel uw = PtexUtils::max(uw, 1.0f/(1<= .25) { if (uw < .5) { k_ureslog2 = 2; double upix = u * 4 - 0.5; int u1 = int(ceil(upix - 2)), u2 = int(ceil(upix + 2)); u1 = u1 & ~1; // round down to even pair u2 = (u2 + 1) & ~1; // round up to even pair k_u = u1; k_uw = u2-u1; double x1 = u1-upix; for (int i = 0; i < k_uw; i+=2) { double xa = x1 + i, xb = xa + 1, xc = (xa+xb)*0.25; // spread the filter gradually to approach the next-lower-res width // at uw = .5, s = 1.0; at uw = 1, s = 0.8 double s = 1.0/(uw + .75); double ka = _k(xa, _c), kb = _k(xb, _c), kc = blur(xc*s); ku[i] = ka * lerp1 + kc * lerp2; ku[i+1] = kb * lerp1 + kc * lerp2; } return; } else if (uw < 1) { k_ureslog2 = 1; double upix = u * 2 - 0.5; k_u = int(floor(u - .5))*2; k_uw = 4; double x1 = k_u-upix; for (int i = 0; i < k_uw; i+=2) { double xa = x1 + i, xb = xa + 1, xc = (xa+xb)*0.5; // spread the filter gradually to approach the next-lower-res width // at uw = .5, s = .8; at uw = 1, s = 0.5 double s = 1.0/(uw*1.5 + .5); double ka = blur(xa*s), kb = blur(xb*s), kc = blur(xc*s); ku[i] = ka * lerp1 + kc * lerp2; ku[i+1] = kb * lerp1 + kc * lerp2; } return; } else { // use res 0 (1 texel per face) w/ no lerping // (future: use face-blended values for filter > 2) k_ureslog2 = 0; double upix = u - .5; k_uw = 2; double ui = floor(upix); k_u = int(ui); ku[0] = blur(upix-ui); ku[1] = 1-ku[0]; return; } } // convert from normalized coords to pixel coords double upix = u * resu - 0.5; double uwpix = uw * resu; // find integer pixel extent: [u,v] +/- [2*uw,2*vw] // (kernel width is 4 times filter width) double dupix = 2*uwpix; int u1 = int(ceil(upix - dupix)), u2 = int(ceil(upix + dupix)); if (lerp2) { // lerp kernel weights towards next-lower res // extend kernel width to cover even pairs u1 = u1 & ~1; u2 = (u2 + 1) & ~1; k_u = u1; k_uw = u2-u1; // compute kernel weights double step = 1.0/uwpix, x1 = (u1-upix)*step; for (int i = 0; i < k_uw; i+=2) { double xa = x1 + i*step, xb = xa + step, xc = (xa+xb)*0.5; double ka = _k(xa, _c), kb = _k(xb, _c), kc = _k(xc, _c); ku[i] = ka * lerp1 + kc * lerp2; ku[i+1] = kb * lerp1 + kc * lerp2; } } else { k_u = u1; k_uw = u2-u1; // compute kernel weights double x1 = (u1-upix)/uwpix, step = 1.0/uwpix; for (int i = 0; i < k_uw; i++) ku[i] = _k(x1 + i*step, _c); } } KernelFn* _k; // kernel function const double* _c; // kernel coefficients (if any) }; /** Separable bicubic filter */ class PtexBicubicFilter : public PtexWidth4Filter { public: PtexBicubicFilter(PtexTexture* tx, const PtexFilter::Options& opts, float sharpness) : PtexWidth4Filter(tx, opts, kernelFn, _coeffs) { // compute Cubic filter coefficients: // abs(x) < 1: // 1/6 * ((12 - 9*B - 6*C)*x^3 + (-18 + 12*B + 6*C)*x^2 + (6 - 2*B)) // == c[0]*x^3 + c[1]*x^2 + c[2] // abs(x) < 2: // 1/6 * ((-B - 6*C)*x^3 + (6*B + 30*C)*x^2 + (-12*B - 48*C)*x + (8*B + 24*C)) // == c[3]*x^3 + c[4]*x^2 + c[5]*x + c[6] // else: 0 float B = 1 - sharpness; // choose C = (1-B)/2 _coeffs[0] = 1.5 - B; _coeffs[1] = 1.5 * B - 2.5; _coeffs[2] = 1 - (1./3) * B; _coeffs[3] = (1./3) * B - 0.5; _coeffs[4] = 2.5 - 1.5 * B; _coeffs[5] = 2 * B - 4; _coeffs[6] = 2 - (2./3) * B; } private: static double kernelFn(double x, const double* c) { x = fabs(x); if (x < 1) return (c[0]*x + c[1])*x*x + c[2]; else if (x < 2) return ((c[3]*x + c[4])*x + c[5])*x + c[6]; else return 0; } double _coeffs[7]; // filter coefficients for current sharpness }; /** Separable gaussian filter */ class PtexGaussianFilter : public PtexWidth4Filter { public: PtexGaussianFilter(PtexTexture* tx, const PtexFilter::Options& opts) : PtexWidth4Filter(tx, opts, kernelFn) {} private: static double kernelFn(double x, const double*) { return exp(-2*x*x); } }; /** Rectangular box filter. The box is convolved with the texels as area samples and thus the kernel function is actually trapezoidally shaped. */ class PtexBoxFilter : public PtexSeparableFilter { public: PtexBoxFilter(PtexTexture* tx, const PtexFilter::Options& opts) : PtexSeparableFilter(tx, opts) {} protected: virtual void buildKernel(PtexSeparableKernel& k, float u, float v, float uw, float vw, Res faceRes) { // clamp filter width to no larger than 1.0 uw = PtexUtils::min(uw, 1.0f); vw = PtexUtils::min(vw, 1.0f); // clamp filter width to no smaller than a texel uw = PtexUtils::max(uw, 1.0f/(faceRes.u())); vw = PtexUtils::max(vw, 1.0f/(faceRes.v())); // compute desired texture res based on filter width int ureslog2 = int(ceil(log2(1.0/uw))), vreslog2 = int(ceil(log2(1.0/vw))); Res res(ureslog2, vreslog2); k.res = res; // convert from normalized coords to pixel coords u = u * k.res.u(); v = v * k.res.v(); uw *= k.res.u(); vw *= k.res.v(); // find integer pixel extent: [u,v] +/- [uw/2,vw/2] // (box is 1 unit wide for a 1 unit filter period) double u1 = u - 0.5*uw, u2 = u + 0.5*uw; double v1 = v - 0.5*vw, v2 = v + 0.5*vw; double u1floor = floor(u1), u2ceil = ceil(u2); double v1floor = floor(v1), v2ceil = ceil(v2); k.u = int(u1floor); k.v = int(v1floor); k.uw = int(u2ceil)-k.u; k.vw = int(v2ceil)-k.v; // compute kernel weights along u and v directions computeWeights(k.ku, k.uw, 1-(u1-u1floor), 1-(u2ceil-u2)); computeWeights(k.kv, k.vw, 1-(v1-v1floor), 1-(v2ceil-v2)); } private: void computeWeights(double* kernel, int size, double f1, double f2) { assert(size >= 1 && size <= 3); if (size == 1) { kernel[0] = f1 + f2 - 1; } else { kernel[0] = f1; for (int i = 1; i < size-1; i++) kernel[i] = 1.0; kernel[size-1] = f2; } } }; /** Bilinear filter (for rectangular textures) */ class PtexBilinearFilter : public PtexSeparableFilter { public: PtexBilinearFilter(PtexTexture* tx, const PtexFilter::Options& opts) : PtexSeparableFilter(tx, opts) {} protected: virtual void buildKernel(PtexSeparableKernel& k, float u, float v, float uw, float vw, Res faceRes) { // clamp filter width to no larger than 1.0 uw = PtexUtils::min(uw, 1.0f); vw = PtexUtils::min(vw, 1.0f); // clamp filter width to no smaller than a texel uw = PtexUtils::max(uw, 1.0f/(faceRes.u())); vw = PtexUtils::max(vw, 1.0f/(faceRes.v())); // choose resolution closest to filter res // there are three choices of "closest" that come to mind: // 1) closest in terms of filter width, i.e. period of signal // 2) closest in terms of texel resolution, (1 / filter width), i.e. freq of signal // 3) closest in terms of resolution level (log2(1/filter width)) // Choice (1) probably makes the most sense. In log2 terms, that means you should // use the next higher level when the fractional part of the log2 res is > log2(1/.75), // and you should add 1-log2(1/.75) to round up. const double roundWidth = 0.5849625007211563; // 1-log2(1/.75) int ureslog2 = int(log2(1.0/uw) + roundWidth); int vreslog2 = int(log2(1.0/vw) + roundWidth); Res res(ureslog2, vreslog2); k.res = res; // convert from normalized coords to pixel coords double upix = u * k.res.u() - 0.5; double vpix = v * k.res.v() - 0.5; float ufloor = floor(upix); float vfloor = floor(vpix); k.u = int(ufloor); k.v = int(vfloor); k.uw = 2; k.vw = 2; // compute kernel weights float ufrac = upix-ufloor, vfrac = vpix-vfloor; k.ku[0] = 1 - ufrac; k.ku[1] = ufrac; k.kv[0] = 1 - vfrac; k.kv[1] = vfrac; } }; } // end local namespace PtexFilter* PtexFilter::getFilter(PtexTexture* tex, const PtexFilter::Options& opts) { switch (tex->meshType()) { case Ptex::mt_quad: switch (opts.filter) { case f_point: return new PtexPointFilter(tex); case f_bilinear: return new PtexBilinearFilter(tex, opts); default: case f_box: return new PtexBoxFilter(tex, opts); case f_gaussian: return new PtexGaussianFilter(tex, opts); case f_bicubic: return new PtexBicubicFilter(tex, opts, opts.sharpness); case f_bspline: return new PtexBicubicFilter(tex, opts, 0.0); case f_catmullrom: return new PtexBicubicFilter(tex, opts, 1.0); case f_mitchell: return new PtexBicubicFilter(tex, opts, 2.0/3.0); } break; case Ptex::mt_triangle: switch (opts.filter) { case f_point: return new PtexPointFilterTri(tex); default: return new PtexTriangleFilter(tex, opts); } break; } return 0; } openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexSeparableFilter.cpp0000644000175000017500000002755212271062644025105 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "PtexPlatform.h" #include #include #include "PtexSeparableFilter.h" #include "PtexSeparableKernel.h" #include "PtexUtils.h" //#define NOEDGEBLEND // uncomment to disable filtering across edges (for debugging) void PtexSeparableFilter::eval(float* result, int firstChan, int nChannels, int faceid, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur) { // init if (!_tx || nChannels <= 0) return; if (faceid < 0 || faceid >= _tx->numFaces()) return; _ntxchan = _tx->numChannels(); _dt = _tx->dataType(); _firstChanOffset = firstChan*DataSize(_dt); _nchan = PtexUtils::min(nChannels, _ntxchan-firstChan); // get face info const FaceInfo& f = _tx->getFaceInfo(faceid); // if neighborhood is constant, just return constant value of face if (f.isNeighborhoodConstant()) { PtexPtr data ( _tx->getData(faceid, 0) ); if (data) { char* d = (char*) data->getData() + _firstChanOffset; Ptex::ConvertToFloat(result, d, _dt, _nchan); } return; } // find filter width as bounding box of vectors w1 and w2 float uw = fabs(uw1) + fabs(uw2), vw = fabs(vw1) + fabs(vw2); // handle border modes switch (_uMode) { case m_clamp: u = PtexUtils::clamp(u, 0.0f, 1.0f); break; case m_periodic: u = u-floor(u); break; case m_black: break; // do nothing } switch (_vMode) { case m_clamp: v = PtexUtils::clamp(v, 0.0f, 1.0f); break; case m_periodic: v = v-floor(v); case m_black: break; // do nothing } // build kernel PtexSeparableKernel k; if (f.isSubface()) { // for a subface, build the kernel as if it were on a main face and then downres uw = uw * width + blur * 2; vw = vw * width + blur * 2; buildKernel(k, u*.5, v*.5, uw*.5, vw*.5, f.res); if (k.res.ulog2 == 0) k.upresU(); if (k.res.vlog2 == 0) k.upresV(); k.res.ulog2--; k.res.vlog2--; } else { uw = uw * width + blur; vw = vw * width + blur; buildKernel(k, u, v, uw, vw, f.res); } k.stripZeros(); // check kernel (debug only) assert(k.uw > 0 && k.vw > 0); assert(k.uw <= PtexSeparableKernel::kmax && k.vw <= PtexSeparableKernel::kmax); _weight = k.weight(); // allocate temporary double-precision result _result = (double*) alloca(sizeof(double)*_nchan); memset(_result, 0, sizeof(double)*_nchan); // apply to faces splitAndApply(k, faceid, f); // normalize (both for data type and cumulative kernel weight applied) // and output result double scale = 1.0 / (_weight * OneValue(_dt)); for (int i = 0; i < _nchan; i++) result[i] = float(_result[i] * scale); // clear temp result _result = 0; } void PtexSeparableFilter::splitAndApply(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f) { // do we need to split? (i.e. does kernel span an edge?) bool splitR = (k.u+k.uw > k.res.u()), splitL = (k.u < 0); bool splitT = (k.v+k.vw > k.res.v()), splitB = (k.v < 0); #ifdef NOEDGEBLEND // for debugging only if (splitR) k.mergeR(_uMode); if (splitL) k.mergeL(_uMode); if (splitT) k.mergeT(_vMode); if (splitB) k.mergeB(_vMode); #else if (splitR || splitL || splitT || splitB) { PtexSeparableKernel ka, kc; if (splitR) { if (f.adjface(e_right) >= 0) { k.splitR(ka); if (splitT) { if (f.adjface(e_top) >= 0) { ka.splitT(kc); applyToCorner(kc, faceid, f, e_top); } else ka.mergeT(_vMode); } if (splitB) { if (f.adjface(e_bottom) >= 0) { ka.splitB(kc); applyToCorner(kc, faceid, f, e_right); } else ka.mergeB(_vMode); } applyAcrossEdge(ka, faceid, f, e_right); } else k.mergeR(_uMode); } if (splitL) { if (f.adjface(e_left) >= 0) { k.splitL(ka); if (splitT) { if (f.adjface(e_top) >= 0) { ka.splitT(kc); applyToCorner(kc, faceid, f, e_left); } else ka.mergeT(_vMode); } if (splitB) { if (f.adjface(e_bottom) >= 0) { ka.splitB(kc); applyToCorner(kc, faceid, f, e_bottom); } else ka.mergeB(_vMode); } applyAcrossEdge(ka, faceid, f, e_left); } else k.mergeL(_uMode); } if (splitT) { if (f.adjface(e_top) >= 0) { k.splitT(ka); applyAcrossEdge(ka, faceid, f, e_top); } else k.mergeT(_vMode); } if (splitB) { if (f.adjface(e_bottom) >= 0) { k.splitB(ka); applyAcrossEdge(ka, faceid, f, e_bottom); } else k.mergeB(_vMode); } } #endif // do local face apply(k, faceid, f); } void PtexSeparableFilter::applyAcrossEdge(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f, int eid) { int afid = f.adjface(eid), aeid = f.adjedge(eid); const Ptex::FaceInfo* af = &_tx->getFaceInfo(afid); int rot = eid - aeid + 2; // adjust uv coord and res for face/subface boundary bool fIsSubface = f.isSubface(), afIsSubface = af->isSubface(); if (fIsSubface != afIsSubface) { if (afIsSubface) { // main face to subface transition // adjust res and offset uv coord for primary subface bool primary = k.adjustMainToSubface(eid); if (!primary) { // advance ajacent face and edge id to secondary subface int neid = (aeid + 3) % 4; afid = af->adjface(neid); aeid = af->adjedge(neid); af = &_tx->getFaceInfo(afid); rot += neid - aeid + 2; } } else { // subface to main face transition // Note: the transform depends on which subface the kernel is // coming from. The "primary" subface is the one the main // face is pointing at. The secondary subface adjustment // happens to be the same as for the primary subface for the // next edge, so the cases can be combined. bool primary = (af->adjface(aeid) == faceid); k.adjustSubfaceToMain(eid - primary); } } // rotate and apply (resplit if going to a subface) k.rotate(rot); if (afIsSubface) splitAndApply(k, afid, *af); else apply(k, afid, *af); } void PtexSeparableFilter::applyToCorner(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f, int eid) { // traverse clockwise around corner vertex and gather corner faces int afid = faceid, aeid = eid; const FaceInfo* af = &f; bool prevIsSubface = af->isSubface(); const int MaxValence = 10; int cfaceId[MaxValence]; int cedgeId[MaxValence]; const FaceInfo* cface[MaxValence]; int numCorners = 0; for (int i = 0; i < MaxValence; i++) { // advance to next face int prevFace = afid; afid = af->adjface(aeid); aeid = (af->adjedge(aeid) + 1) % 4; // we hit a boundary or reached starting face // note: we need to check edge id too because we might have // a periodic texture (w/ toroidal topology) where all 4 corners // are from the same face if (afid < 0 || (afid == faceid && aeid == eid)) { numCorners = i - 2; break; } // record face info af = &_tx->getFaceInfo(afid); cfaceId[i] = afid; cedgeId[i] = aeid; cface[i] = af; // check to see if corner is a subface "tee" bool isSubface = af->isSubface(); if (prevIsSubface && !isSubface && af->adjface((aeid+3)%4) == prevFace) { // adjust the eid depending on whether we started from // the primary or secondary subface. bool primary = (i==1); k.adjustSubfaceToMain(eid + primary * 2); k.rotate(eid - aeid + 3 - primary); splitAndApply(k, afid, *af); return; } prevIsSubface = isSubface; } if (numCorners == 1) { // regular case (valence 4) applyToCornerFace(k, f, eid, cfaceId[1], *cface[1], cedgeId[1]); } else if (numCorners > 1) { // valence 5+, make kernel symmetric and apply equally to each face // first, rotate to standard orientation, u=v=0 k.rotate(eid + 2); double initialWeight = k.weight(); double newWeight = k.makeSymmetric(initialWeight); for (int i = 1; i <= numCorners; i++) { PtexSeparableKernel kc = k; applyToCornerFace(kc, f, 2, cfaceId[i], *cface[i], cedgeId[i]); } // adjust weight for symmetrification and for additional corners _weight += newWeight * numCorners - initialWeight; } else { // valence 2 or 3, ignore corner face (just adjust weight) _weight -= k.weight(); } } void PtexSeparableFilter::applyToCornerFace(PtexSeparableKernel& k, const Ptex::FaceInfo& f, int eid, int cfid, const Ptex::FaceInfo& cf, int ceid) { // adjust uv coord and res for face/subface boundary bool fIsSubface = f.isSubface(), cfIsSubface = cf.isSubface(); if (fIsSubface != cfIsSubface) { if (cfIsSubface) k.adjustMainToSubface(eid + 3); else k.adjustSubfaceToMain(eid + 3); } // rotate and apply (resplit if going to a subface) k.rotate(eid - ceid + 2); if (cfIsSubface) splitAndApply(k, cfid, cf); else apply(k, cfid, cf); } void PtexSeparableFilter::apply(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f) { assert(k.u >= 0 && k.u + k.uw <= k.res.u()); assert(k.v >= 0 && k.v + k.vw <= k.res.v()); if (k.uw <= 0 || k.vw <= 0) return; // downres kernel if needed while (k.res.u() > f.res.u()) k.downresU(); while (k.res.v() > f.res.v()) k.downresV(); // get face data, and apply PtexPtr dh ( _tx->getData(faceid, k.res) ); if (!dh) return; if (dh->isConstant()) { k.applyConst(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan); } else if (dh->isTiled()) { Ptex::Res tileres = dh->tileRes(); PtexSeparableKernel kt; kt.res = tileres; int tileresu = tileres.u(); int tileresv = tileres.v(); int ntilesu = k.res.u() / tileresu; for (int v = k.v, vw = k.vw; vw > 0; vw -= kt.vw, v += kt.vw) { int tilev = v / tileresv; kt.v = v % tileresv; kt.vw = PtexUtils::min(vw, tileresv - kt.v); kt.kv = k.kv + v - k.v; for (int u = k.u, uw = k.uw; uw > 0; uw -= kt.uw, u += kt.uw) { int tileu = u / tileresu; kt.u = u % tileresu; kt.uw = PtexUtils::min(uw, tileresu - kt.u); kt.ku = k.ku + u - k.u; PtexPtr th ( dh->getTile(tilev * ntilesu + tileu) ); if (th) { if (th->isConstant()) kt.applyConst(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan); else kt.apply(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan, _ntxchan); } } } } else { k.apply(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan, _ntxchan); } } openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexSeparableKernel.cpp0000644000175000017500000001315712271062644025074 0ustar mfvmfv/* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "PtexPlatform.h" #include "PtexUtils.h" #include "PtexHalf.h" #include "PtexSeparableKernel.h" namespace { // apply to 1..4 channels (unrolled channel loop) of packed data (nTxChan==nChan) template void Apply(PtexSeparableKernel& k, double* result, void* data, int /*nChan*/, int /*nTxChan*/) { double* rowResult = (double*) alloca(nChan*sizeof(double)); int rowlen = k.res.u() * nChan; int datalen = k.uw * nChan; int rowskip = rowlen - datalen; double* kvp = k.kv; T* p = (T*)data + (k.v * k.res.u() + k.u) * nChan; T* pEnd = p + k.vw * rowlen; while (p != pEnd) { double* kup = k.ku; T* pRowEnd = p + datalen; // just mult and copy first element PtexUtils::VecMult()(rowResult, p, *kup++); p += nChan; // accumulate remaining elements while (p != pRowEnd) { // rowResult[i] = p[i] * ku[u] for i in {0..n-1} PtexUtils::VecAccum()(rowResult, p, *kup++); p += nChan; } // result[i] += rowResult[i] * kv[v] for i in {0..n-1} PtexUtils::VecAccum()(result, rowResult, *kvp++); p += rowskip; } } // apply to 1..4 channels (unrolled channel loop) w/ pixel stride template void ApplyS(PtexSeparableKernel& k, double* result, void* data, int /*nChan*/, int nTxChan) { double* rowResult = (double*) alloca(nChan*sizeof(double)); int rowlen = k.res.u() * nTxChan; int datalen = k.uw * nTxChan; int rowskip = rowlen - datalen; double* kvp = k.kv; T* p = (T*)data + (k.v * k.res.u() + k.u) * nTxChan; T* pEnd = p + k.vw * rowlen; while (p != pEnd) { double* kup = k.ku; T* pRowEnd = p + datalen; // just mult and copy first element PtexUtils::VecMult()(rowResult, p, *kup++); p += nTxChan; // accumulate remaining elements while (p != pRowEnd) { // rowResult[i] = p[i] * ku[u] for i in {0..n-1} PtexUtils::VecAccum()(rowResult, p, *kup++); p += nTxChan; } // result[i] += rowResult[i] * kv[v] for i in {0..n-1} PtexUtils::VecAccum()(result, rowResult, *kvp++); p += rowskip; } } // apply to N channels (general case) template void ApplyN(PtexSeparableKernel& k, double* result, void* data, int nChan, int nTxChan) { double* rowResult = (double*) alloca(nChan*sizeof(double)); int rowlen = k.res.u() * nTxChan; int datalen = k.uw * nTxChan; int rowskip = rowlen - datalen; double* kvp = k.kv; T* p = (T*)data + (k.v * k.res.u() + k.u) * nTxChan; T* pEnd = p + k.vw * rowlen; while (p != pEnd) { double* kup = k.ku; T* pRowEnd = p + datalen; // just mult and copy first element PtexUtils::VecMultN()(rowResult, p, nChan, *kup++); p += nTxChan; // accumulate remaining elements while (p != pRowEnd) { // rowResult[i] = p[i] * ku[u] for i in {0..n-1} PtexUtils::VecAccumN()(rowResult, p, nChan, *kup++); p += nTxChan; } // result[i] += rowResult[i] * kv[v] for i in {0..n-1} PtexUtils::VecAccumN()(result, rowResult, nChan, *kvp++); p += rowskip; } } } PtexSeparableKernel::ApplyFn PtexSeparableKernel::applyFunctions[] = { // nChan == nTxChan ApplyN, ApplyN, ApplyN, ApplyN, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, Apply, // nChan != nTxChan (need pixel stride) ApplyN, ApplyN, ApplyN, ApplyN, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, ApplyS, }; openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptex/PtexSeparableFilter.h0000644000175000017500000000662612271062644024551 0ustar mfvmfv#ifndef PtexSeparableFilter_h #define PtexSeparableFilter_h /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "Ptexture.h" class PtexSeparableKernel; class PtexSeparableFilter : public PtexFilter, public Ptex { public: virtual void release() { delete this; } virtual void eval(float* result, int firstchan, int nchannels, int faceid, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur); protected: PtexSeparableFilter(PtexTexture* tx, const PtexFilter::Options& opts ) : _tx(tx), _options(opts), _result(0), _weight(0), _firstChanOffset(0), _nchan(0), _ntxchan(0), _dt((DataType)0), _uMode(tx->uBorderMode()), _vMode(tx->vBorderMode()) {} virtual ~PtexSeparableFilter() {} virtual void buildKernel(PtexSeparableKernel& k, float u, float v, float uw, float vw, Res faceRes) = 0; void splitAndApply(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f); void applyAcrossEdge(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f, int eid); void applyToCorner(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f, int eid); void applyToCornerFace(PtexSeparableKernel& k, const Ptex::FaceInfo& f, int eid, int cfaceid, const Ptex::FaceInfo& cf, int ceid); void apply(PtexSeparableKernel& k, int faceid, const Ptex::FaceInfo& f); PtexTexture* _tx; // texture being evaluated Options _options; // options double* _result; // temp result double _weight; // accumulated weight of data in _result int _firstChanOffset; // byte offset of first channel to eval int _nchan; // number of channels to eval int _ntxchan; // number of channels in texture DataType _dt; // data type of texture BorderMode _uMode, _vMode; // border modes (clamp,black,periodic) }; #endif openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/ptexinput.cpp0000644000175000017500000002164712271062644022257 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "ptex/Ptexture.h" #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN class PtexInput : public ImageInput { public: PtexInput () : m_ptex(NULL) { init(); } virtual ~PtexInput () { close(); } virtual const char * format_name (void) const { return "ptex"; } virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (); virtual int current_subimage (void) const { return m_subimage; } virtual int current_miplevel (void) const { return m_miplevel; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual bool read_native_scanline (int y, int z, void *data); virtual bool read_native_tile (int x, int y, int z, void *data); private: PtexTexture *m_ptex; int m_subimage; int m_miplevel; int m_numFaces; Ptex::Res m_faceres; Ptex::Res m_mipfaceres; Ptex::Res m_tileres; bool m_isTiled; bool m_hasMipMaps; int m_ntilesu; /// Reset everything to initial state /// void init () { if (m_ptex) m_ptex->release(); m_ptex = NULL; m_subimage = -1; m_miplevel = -1; } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *ptex_input_imageio_create () { return new PtexInput; } OIIO_EXPORT int ptex_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * ptex_input_extensions[] = { "ptex", "ptx", NULL }; OIIO_PLUGIN_EXPORTS_END bool PtexInput::open (const std::string &name, ImageSpec &newspec) { Ptex::String perr; m_ptex = PtexTexture::open (name.c_str(), perr, true /*premultiply*/); if (! perr.empty()) { if (m_ptex) { m_ptex->release (); m_ptex = NULL; } error ("%s", perr.c_str()); return false; } m_numFaces = m_ptex->numFaces(); m_hasMipMaps = m_ptex->hasMipMaps(); bool ok = seek_subimage (0, 0, newspec); newspec = spec (); return ok; } bool PtexInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (m_subimage == subimage && m_miplevel == miplevel) return true; // Already fine if (subimage < 0 || subimage >= m_numFaces) return false; m_subimage = subimage; const Ptex::FaceInfo &pface = m_ptex->getFaceInfo (subimage); m_faceres = pface.res; int nmiplevels = std::max(m_faceres.ulog2,m_faceres.vlog2) + 1; if (miplevel < 0 || miplevel > nmiplevels-1) return false; m_miplevel = miplevel; m_mipfaceres = Ptex::Res (std::max(0,m_faceres.ulog2-miplevel), std::max(0,m_faceres.vlog2-miplevel)); TypeDesc format = TypeDesc::UNKNOWN; switch (m_ptex->dataType()) { case Ptex::dt_uint8 : format = TypeDesc::UINT8; break; case Ptex::dt_uint16 : format = TypeDesc::UINT16; break; case Ptex::dt_half : format = TypeDesc::HALF; break; case Ptex::dt_float : format = TypeDesc::FLOAT; break; default: error ("Ptex with unknown data format"); return false; } m_spec = ImageSpec (std::max (1, m_faceres.u() >> miplevel), std::max (1, m_faceres.v() >> miplevel), m_ptex->numChannels(), format); m_spec.alpha_channel = m_ptex->alphaChannel(); if (m_ptex->meshType() == Ptex::mt_triangle) m_spec.attribute ("ptex:meshType", "triangle"); else m_spec.attribute ("ptex:meshType", "quad"); if (m_ptex->hasEdits()) m_spec.attribute ("ptex:hasEdits", (int)1); PtexFaceData *facedata = m_ptex->getData (m_subimage, m_faceres); m_isTiled = facedata->isTiled(); if (m_isTiled) { m_tileres = facedata->tileRes(); m_spec.tile_width = m_tileres.u(); m_spec.tile_height = m_tileres.v(); m_ntilesu = m_faceres.ntilesu (m_tileres); } else { // Always make it look tiled m_spec.tile_width = m_spec.width; m_spec.tile_height = m_spec.height; } std::string wrapmode; if (m_ptex->uBorderMode() == Ptex::m_clamp) wrapmode = "clamp"; else if (m_ptex->uBorderMode() == Ptex::m_black) wrapmode = "black"; else // if (m_ptex->uBorderMode() == Ptex::m_periodic) wrapmode = "periodic"; wrapmode += ","; if (m_ptex->uBorderMode() == Ptex::m_clamp) wrapmode += "clamp"; else if (m_ptex->uBorderMode() == Ptex::m_black) wrapmode += "black"; else // if (m_ptex->uBorderMode() == Ptex::m_periodic) wrapmode += "periodic"; m_spec.attribute ("wrapmode", wrapmode); #define GETMETA(pmeta,key,ptype,basetype,typedesc,value) \ { \ const ptype *v; \ int count; \ pmeta->getValue (key, v, count); \ typedesc = TypeDesc (basetype, count); \ value = (const void *) v; \ } PtexMetaData *pmeta = m_ptex->getMetaData(); if (pmeta) { int n = pmeta->numKeys(); for (int i = 0; i < n; ++i) { const char *key = NULL; Ptex::MetaDataType ptype; pmeta->getKey (i, key, ptype); ASSERT (key); const char *vchar; const void *value; TypeDesc typedesc; switch (ptype) { case Ptex::mdt_string: pmeta->getValue (key, vchar); value = &vchar; typedesc = TypeDesc::STRING; break; case Ptex::mdt_int8: GETMETA (pmeta, key, int8_t, TypeDesc::INT8, typedesc, value); break; case Ptex::mdt_int16: GETMETA (pmeta, key, int16_t, TypeDesc::INT16, typedesc, value); break; case Ptex::mdt_int32: GETMETA (pmeta, key, int32_t, TypeDesc::INT32, typedesc, value); break; case Ptex::mdt_float: GETMETA (pmeta, key, float, TypeDesc::FLOAT, typedesc, value); break; case Ptex::mdt_double: GETMETA (pmeta, key, double, TypeDesc::DOUBLE, typedesc, value); break; default: continue; } m_spec.attribute (key, typedesc, value); } pmeta->release(); } facedata->release(); newspec = m_spec; return true; } bool PtexInput::close () { init(); // Reset to initial state, including closing any open files return true; } bool PtexInput::read_native_scanline (int y, int z, void *data) { return false; // Not scanline oriented } bool PtexInput::read_native_tile (int x, int y, int z, void *data) { PtexFaceData *facedata = m_ptex->getData (m_subimage, m_mipfaceres); PtexFaceData *f = facedata; if (m_isTiled) { int tileno = y/m_spec.tile_height * m_ntilesu + x/m_spec.tile_width; f = facedata->getTile (tileno); } bool ok = true; void *tiledata = f->getData(); if (tiledata) { memcpy (data, tiledata, m_spec.tile_bytes()); } else { ok = false; } if (m_isTiled) f->release(); facedata->release(); return ok; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/ptex.imageio/CMakeLists.txt0000644000175000017500000000123212271062644022237 0ustar mfvmfvfind_package (ZLIB) if (ZLIB_FOUND) if (WIN32) add_definitions ("-DPTEX_EXPORTS") endif() include_directories (${ZLIB_INCLUDE_DIR}) add_oiio_plugin (ptexinput.cpp ptexoutput.cpp ptex/PtexCache.cpp ptex/PtexFilters.cpp ptex/PtexHalf.cpp ptex/PtexReader.cpp ptex/PtexSeparableFilter.cpp ptex/PtexSeparableKernel.cpp ptex/PtexTriangleFilter.cpp ptex/PtexTriangleKernel.cpp ptex/PtexUtils.cpp ptex/PtexWriter.cpp LINK_LIBRARIES ${ZLIB_LIBRARIES} ) endif () openimageio-1.3.12~dfsg0.orig/src/gif.imageio/0000755000175000017500000000000012271062644017266 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/gif.imageio/gifinput.cpp0000644000175000017500000003744612271062644021635 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "imageio.h" #include "thread.h" // GIFLIB: // http://giflib.sourceforge.net/ // Format description: // http://giflib.sourceforge.net/whatsinagif/index.html // for older giflib versions #ifndef GIFLIB_MAJOR #define GIFLIB_MAJOR 4 #endif OIIO_PLUGIN_NAMESPACE_BEGIN class GIFInput : public ImageInput { public: GIFInput () { init (); } virtual ~GIFInput () { close (); } virtual const char *format_name (void) const { return "gif"; } virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (void); virtual bool read_native_scanline (int y, int z, void *data); virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual int current_subimage (void) const { return m_subimage; } virtual int current_miplevel (void) const { // No mipmap support return 0; } private: std::string m_filename; ///< Stash the filename GifFileType *m_gif_file; ///< GIFLIB handle GifColorType *m_global_colormap; ///< Global colormap. Used if there's /// no local colormap provided. GifColorType *m_local_colormap; ///< Colormap for current subimage int m_background_color; ///< Background (transparent) color index int m_subimage; ///< Current subimage index int m_next_scanline; ///< Next scanline to read std::vector m_cached_data; ///< Cached scanlines in native /// format /// Reset everything to initial state /// void init (void); /// Read current subimage metadata. /// bool read_subimage_metadata (ImageSpec &newspec, GifColorType **local_colormap); /// Helper: read gif extension. /// void read_gif_extension (int ext_code, GifByteType *ext, ImageSpec &spec); /// Decode and return a real scanline index in the interlaced image. /// int decode_line_number (int line_number); /// Translate scanline data from a native format. /// void translate_scanline (unsigned char *gif_scanline, void *data); /// Print error message. /// void report_last_error (void); }; // Obligatory material to make this a recognizeable imageio plugin OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int gif_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *gif_input_imageio_create () { return new GIFInput; } OIIO_EXPORT const char *gif_input_extensions[] = { "gif", NULL }; OIIO_PLUGIN_EXPORTS_END void GIFInput::init (void) { m_gif_file = NULL; } bool GIFInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; m_subimage = -1; m_next_scanline = -1; m_cached_data.clear (); return seek_subimage (0, 0, newspec); } inline int GIFInput::decode_line_number (int line_number) { if ((line_number + 1) % 2 == 0) // 4th tile 1/2 sized return (m_spec.height + line_number) / 2; if ((line_number + 2) % 4 == 0) // 3rd tile 1/4 sized return (m_spec.height + line_number - 2) / 4; if ((line_number + 4) % 8 == 0) // 2nd tile 1/8 sized return (m_spec.height + line_number) / 8; // line_number % 8 == 0 (1st tile 1/8 sized) return line_number / 8; } void GIFInput::translate_scanline (unsigned char *gif_scanline, void *data) { unsigned char *outscanline = (unsigned char *)data; GifColorType *colormap = m_local_colormap != NULL ? m_local_colormap : m_global_colormap; if (m_spec.nchannels == 3) { for (int i = 0; i < m_spec.width; i++) { outscanline[3 * i] = (unsigned char)colormap[gif_scanline[i]].Red; outscanline[3 * i + 1] = (unsigned char)colormap[gif_scanline[i]].Green; outscanline[3 * i + 2] = (unsigned char)colormap[gif_scanline[i]].Blue; } } else { for (int i = 0; i < m_spec.width; i++) { outscanline[4 * i] = (unsigned char)colormap[gif_scanline[i]].Red; outscanline[4 * i + 1] = (unsigned char)colormap[gif_scanline[i]].Green; outscanline[4 * i + 2] = (unsigned char)colormap[gif_scanline[i]].Blue; outscanline[4 * i + 3] = (m_background_color == gif_scanline[i] ? 0x00 : 0xff); } } } bool GIFInput::read_native_scanline (int _y, int z, void *data) { if (_y < 0 || _y > m_spec.height) return false; bool interlacing = m_spec.get_int_attribute ("gif:Interlacing") != 0; // decode scanline index if image is interlaced int gif_y = interlacing ? decode_line_number (_y) : _y; if (interlacing) { // gif is interlaced so cache the scanlines int scanlines_cached = m_cached_data.size() / m_spec.width; if (gif_y >= scanlines_cached) { // scanline is not cached yet, read the scanline and preceding ones m_cached_data.resize (m_spec.width * (gif_y + 1)); int delta_size = m_spec.width * (gif_y - scanlines_cached + 1); if (DGifGetLine (m_gif_file, &m_cached_data[scanlines_cached * m_spec.width], delta_size) == GIF_ERROR) { report_last_error (); return false; } } translate_scanline (&m_cached_data[gif_y * m_spec.width], data); } else { // no interlacing, thus no scanlines caching if (m_next_scanline > gif_y) { // requested scanline is located before the one to read next // random access is not supported, so reopen the file, find // current subimage and skip preceding image data ImageSpec dummyspec; if (! close () || ! open (m_filename, dummyspec) || ! seek_subimage (m_subimage, 0, dummyspec)) { return false; } int remaining_size = m_spec.width * gif_y; boost::scoped_array buffer (new unsigned char[remaining_size]); if (DGifGetLine (m_gif_file, buffer.get(), remaining_size) == GIF_ERROR) { report_last_error (); return false; } } else if (m_next_scanline < gif_y) { // requested scanline is located after the one to read next // skip the lines in between int delta_size = m_spec.width * (gif_y - m_next_scanline); boost::scoped_array buffer (new unsigned char[delta_size]); if (DGifGetLine (m_gif_file, buffer.get(), delta_size) == GIF_ERROR) { report_last_error (); return false; } } // read the requested scanline boost::scoped_array fscanline (new unsigned char[m_spec.width]); if (DGifGetLine (m_gif_file, fscanline.get(), m_spec.width) == GIF_ERROR) { report_last_error (); return false; } translate_scanline (fscanline.get(), data); } m_next_scanline = gif_y + 1; return true; } void GIFInput::read_gif_extension (int ext_code, GifByteType *ext, ImageSpec &newspec) { if (ext_code == GRAPHICS_EXT_FUNC_CODE) { // read background color index and delay time between frames // http://giflib.sourceforge.net/whatsinagif/bits_and_bytes.html#graphics_control_extension_block if (ext[1] & 0x01) { newspec.nchannels = 4; m_background_color = (int) ext[4]; } int delay = (ext[3] << 8) | ext[2]; if (delay) { newspec.attribute ("gif:DelayMs", delay * 10); } } else if (ext_code == COMMENT_EXT_FUNC_CODE) { // read comment data // http://giflib.sourceforge.net/whatsinagif/bits_and_bytes.html#comment_extension_block std::string comment = std::string ((const char *)&ext[1], int (ext[0])); newspec.attribute("ImageDescription", comment); } } bool GIFInput::read_subimage_metadata (ImageSpec &newspec, GifColorType **local_colormap) { newspec = ImageSpec (TypeDesc::UINT8); newspec.nchannels = 3; GifRecordType m_gif_rec_type; do { if (DGifGetRecordType (m_gif_file, &m_gif_rec_type) == GIF_ERROR) { report_last_error (); return false; } switch (m_gif_rec_type) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc (m_gif_file) == GIF_ERROR) { report_last_error (); return false; } newspec.width = m_gif_file->Image.Width; newspec.height = m_gif_file->Image.Height; // read local colormap if (m_gif_file->Image.ColorMap != NULL) { *local_colormap = m_gif_file->Image.ColorMap->Colors; } else { *local_colormap = NULL; } break; case EXTENSION_RECORD_TYPE: int ext_code; GifByteType *ext; if (DGifGetExtension(m_gif_file, &ext_code, &ext) == GIF_ERROR) { report_last_error (); return false; } read_gif_extension (ext_code, ext, newspec); while (ext != NULL) { if (DGifGetExtensionNext(m_gif_file, &ext) == GIF_ERROR) { report_last_error (); return false; } if (ext != NULL) { read_gif_extension (ext_code, ext, newspec); } } break; case TERMINATE_RECORD_TYPE: return false; break; default: break; } } while (m_gif_rec_type != IMAGE_DESC_RECORD_TYPE); newspec.attribute ("gif:Interlacing", m_gif_file->Image.Interlace); newspec.default_channel_names (); if (newspec.nchannels == 4) { newspec.alpha_channel = 4; } return true; } bool GIFInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { GifColorType *local_colormap = NULL; if (subimage < 0 || miplevel != 0) return false; if (m_subimage == subimage) { // We're already pointing to the right subimage newspec = m_spec; return true; } if (m_subimage > subimage) { // requested subimage is located before the current one // file needs to be reopened if (m_gif_file && ! close()) { return false; } } if (! m_gif_file) { #if GIFLIB_MAJOR >= 5 int giflib_error; if (! (m_gif_file = DGifOpenFileName (m_filename.c_str(), &giflib_error))) { error (GifErrorString (giflib_error)); return false; } #else if (! (m_gif_file = DGifOpenFileName (m_filename.c_str()))) { error ("Error trying to open the file."); return false; } #endif m_subimage = -1; // read global color table if (m_gif_file->SColorMap) { m_global_colormap = m_gif_file->SColorMap->Colors; } else { m_global_colormap = NULL; } } if (m_subimage < subimage) { // requested subimage is located after the current one // skip the preceding part of current image.. if (m_subimage != -1 && m_next_scanline < m_spec.height) { int remaining_size = m_spec.width * (m_spec.height - m_next_scanline); boost::scoped_array buffer (new unsigned char[remaining_size]); if (DGifGetLine (m_gif_file, buffer.get(), remaining_size) == GIF_ERROR) { report_last_error (); return false; } } // ..and skip the rest of preceding subimages for (m_subimage += 1; m_subimage < subimage; m_subimage ++) { if (! read_subimage_metadata (newspec, &local_colormap)) { return false; } int image_size = newspec.width * newspec.height; boost::scoped_array buffer (new unsigned char[image_size]); if (DGifGetLine (m_gif_file, buffer.get(), image_size) == GIF_ERROR) { report_last_error (); return false; } } } // read metadata of current subimage if (! read_subimage_metadata (newspec, &local_colormap)) { return false; } m_spec = newspec; m_subimage = subimage; m_next_scanline = 0; m_cached_data.clear (); m_local_colormap = local_colormap; return true; } static spin_mutex gif_error_mutex; void GIFInput::report_last_error (void) { // N.B. Only GIFLIB_MAJOR >= 5 looks properly thread-safe, in that the // error is guaranteed to be specific to this open file. We use a spin // mutex to prevent a thread clash for older versions, but it still // appears to be a global call, so we can't be absolutely sure that the // error was for *this* file. So if you're using giflib prior to // version 5, beware. #if GIFLIB_MAJOR >= 5 error ("%s", GifErrorString (m_gif_file->Error)); #elif GIFLIB_MAJOR == 4 && GIFLIB_MINOR >= 2 spin_lock lock (gif_error_mutex); error ("%s", GifErrorString()); #else spin_lock lock (gif_error_mutex); error ("GIF error %d", GifLastError()); #endif } inline bool GIFInput::close (void) { if (m_gif_file) { if (DGifCloseFile (m_gif_file) == GIF_ERROR) { error ("Error trying to close the file."); return false; } m_gif_file = NULL; } m_cached_data.clear (); return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/gif.imageio/gifoutput.cpp0000644000175000017500000000362212271062644022023 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "imageio.h" OIIO_PLUGIN_NAMESPACE_BEGIN // FIXME(mszczepanczyk@gmail.com): Not implemented yet. OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *gif_output_imageio_create () { return NULL; } OIIO_EXPORT const char *gif_output_extensions[] = { "gif", NULL }; OIIO_PLUGIN_EXPORTS_END OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/gif.imageio/CMakeLists.txt0000644000175000017500000000024112271062644022023 0ustar mfvmfvif (USE_GIF AND GIF_FOUND) include_directories (${GIF_INCLUDE_DIR}) add_oiio_plugin (gifinput.cpp gifoutput.cpp LINK_LIBRARIES ${GIF_LIBRARIES}) endif() openimageio-1.3.12~dfsg0.orig/src/ico.imageio/0000755000175000017500000000000012271062644017273 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/ico.imageio/ico.h0000644000175000017500000000726012271062644020223 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_ICO_H #define OPENIMAGEIO_ICO_H #include "filesystem.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN namespace ICO_pvt { // IneQuation was here // Win32 (pre-Vista) ICO format as described in these documents: // http://msdn.microsoft.com/en-us/library/ms997538.aspx // http://en.wikipedia.org/wiki/ICO_(icon_image_file_format) // http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx // ...plus some of my own magic. /// Win32 DIB (Device-Independent Bitmap) header. /// According to MSDN, only size, width, height, planes, bpp and len are /// valid for ICOs. struct ico_bitmapinfo { int32_t size; ///< structure size in bytes (how about a sizeof?) int32_t width; int32_t height; int16_t planes; ///< # of colour planes int16_t bpp; ///< bits per pixel int32_t compression; ///< unused: compression type int32_t len; ///< image size in bytes; may be 0 for uncompressed bitmaps int32_t x_res; ///< unused: resolution of target device in pixels per metre int32_t y_res; ///< unused: resolution of target device in pixels per metre int32_t clrs_used; ///< # of colours used (if using a palette) int32_t clrs_required; ///< # of colours required to display the bitmap; 0 = all of them }; /// Icon palette entry. Attached at each struct ico_palette_entry { int8_t b, g, r; int8_t reserved; // unused }; struct ico_subimage { uint8_t width; ///< 0 means 256 pixels uint8_t height; ///< 0 means 256 pixels uint8_t numColours; ///< 0 means >= 256 uint8_t reserved; ///< should always be 0 uint16_t planes; ///< # of colour planes uint16_t bpp; ///< bits per pixel uint32_t len; ///< size (in bytes) of bitmap data uint32_t ofs; ///< offset to bitmap data }; struct ico_header { int16_t reserved; ///< should always be 0 int16_t type; ///< 1 is icon, 2 is cursor int16_t count; ///< number of subimages in the file }; } // namespace ICO_pvt OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_ICO_H openimageio-1.3.12~dfsg0.orig/src/ico.imageio/icoinput.cpp0000644000175000017500000003504612271062644021641 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "ico.h" #include "../png.imageio/png_pvt.h" #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "thread.h" #include "strutil.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace ICO_pvt; class ICOInput : public ImageInput { public: ICOInput () { init(); } virtual ~ICOInput () { close(); } virtual const char * format_name (void) const { return "ico"; } virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (); virtual int current_subimage (void) const { return m_subimage; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual bool read_native_scanline (int y, int z, void *data); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle ico_header m_ico; ///< ICO header std::vector m_buf; ///< Buffer the image pixels int m_subimage; ///< What subimage are we looking at? int m_bpp; ///< Bits per pixel int m_offset; ///< Offset to image data int m_subimage_size; ///< Length (in bytes) of image data int m_palette_size; ///< Number of colours in palette (0 means 256) png_structp m_png; ///< PNG read structure pointer png_infop m_info; ///< PNG image info structure pointer int m_color_type; ///< PNG color model type int m_interlace_type; ///< PNG interlace type Imath::Color3f m_bg; ///< PNG background color /// Reset everything to initial state /// void init () { m_subimage = -1; m_file = NULL; m_png = NULL; m_info = NULL; memset (&m_ico, 0, sizeof (m_ico)); m_buf.clear (); } /// Helper function: read the image. /// bool readimg (); /// Helper: read, with error detection /// bool fread (void *buf, size_t itemsize, size_t nitems) { size_t n = ::fread (buf, itemsize, nitems, m_file); if (n != nitems) error ("Read error"); return n == nitems; } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *ico_input_imageio_create () { return new ICOInput; } OIIO_EXPORT int ico_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * ico_input_extensions[] = { "ico", NULL }; OIIO_PLUGIN_EXPORTS_END bool ICOInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; m_file = Filesystem::fopen (name, "rb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } if (! fread (&m_ico, 1, sizeof(m_ico))) return false; if (bigendian()) { // ICOs are little endian //swap_endian (&m_ico.reserved); // no use flipping, it's 0 anyway swap_endian (&m_ico.type); swap_endian (&m_ico.count); } if (m_ico.reserved != 0 || m_ico.type != 1) { error ("File failed ICO header check"); return false; } // default to subimage #0, according to convention seek_subimage (0, 0, m_spec); newspec = spec (); return true; } bool ICOInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { /*std::cerr << "[ico] seeking subimage " << index << " (current " << m_subimage << ") out of " << m_ico.count << "\n";*/ if (miplevel != 0) return false; if (subimage == m_subimage) { newspec = spec(); return true; } if (subimage < 0 || subimage >= m_ico.count) return false; // clear the buffer of previous data m_buf.clear (); // deinitialize PNG structs, in case they were used if (m_png && m_info) PNG_pvt::destroy_read_struct (m_png, m_info); m_subimage = subimage; // read subimage header fseek (m_file, sizeof(ico_header) + m_subimage * sizeof(ico_subimage), SEEK_SET); ico_subimage subimg; if (! fread (&subimg, 1, sizeof(subimg))) return false; if (bigendian()) { // ICOs are little endian swap_endian (&subimg.bpp); swap_endian (&subimg.width); swap_endian (&subimg.height); swap_endian (&subimg.len); swap_endian (&subimg.ofs); swap_endian (&subimg.numColours); } fseek (m_file, subimg.ofs, SEEK_SET); // test for a PNG icon char temp[8]; if (! fread (temp, 1, sizeof(temp))) return false; if (temp[1] == 'P' && temp[2] == 'N' && temp[3] == 'G') { // standard PNG initalization if (png_sig_cmp ((png_bytep)temp, 0, 7)) { error ("Subimage failed PNG signature check"); return false; } //std::cerr << "[ico] creating PNG read struct\n"; std::string s = PNG_pvt::create_read_struct (m_png, m_info); if (s.length ()) { error ("%s", s.c_str ()); return false; } //std::cerr << "[ico] reading PNG info\n"; png_init_io (m_png, m_file); png_set_sig_bytes (m_png, 8); // already read 8 bytes PNG_pvt::read_info (m_png, m_info, m_bpp, m_color_type, m_interlace_type, m_bg, m_spec, true); m_spec.attribute ("oiio:BitsPerSample", m_bpp / m_spec.nchannels); newspec = spec (); return true; } // otherwise it's a plain, ol' windoze DIB (device-independent bitmap) // roll back to where we began and read in the DIB header fseek (m_file, subimg.ofs, SEEK_SET); ico_bitmapinfo bmi; if (! fread (&bmi, 1, sizeof(bmi))) return false; if (bigendian()) { // ICOs are little endian // according to MSDN, only these are valid in an ICO DIB header swap_endian (&bmi.size); swap_endian (&bmi.bpp); swap_endian (&bmi.width); swap_endian (&bmi.height); swap_endian (&bmi.len); } /*std::cerr << "[ico] " << (int)subimg.width << "x" << (int)subimg.height << "@" << (int)bmi.bpp << " (subimg len=" << (int)subimg.len << ", bm len=" << (int)bmi.len << ", ofs=" << (int)subimg.ofs << "), c#" << (int)subimg.numColours << ", p#" << (int)subimg.planes << ":" << (int)bmi.planes << "\n";*/ // copy off values for later use m_bpp = bmi.bpp; // some sanity checking if (m_bpp != 1 && m_bpp != 4 && m_bpp != 8 /*&& m_bpp != 16*/ && m_bpp != 24 && m_bpp != 32) { error ("Unsupported image color depth, probably corrupt file"); return false; } m_offset = subimg.ofs; m_subimage_size = subimg.len; // palette size of 0 actually indicates 256 colours m_palette_size = (subimg.numColours == 0 && m_bpp < 16) ? 256 : (int)subimg.numColours; m_spec = ImageSpec ((int)subimg.width, (int)subimg.height, 4, // always RGBA TypeDesc::UINT8); // 4- and 16-bit are expanded to 8bpp m_spec.default_channel_names (); // add 1 bit for < 32bpp images due to the 1-bit alpha mask m_spec.attribute ("oiio:BitsPerSample", m_bpp/m_spec.nchannels + (m_bpp == 32 ? 0 : 1)); /*std::cerr << "[ico] expected bytes: scanline " << m_spec.scanline_bytes() << ", image " << m_spec.image_bytes() << "\n";*/ newspec = spec (); return true; } bool ICOInput::readimg () { if (m_png) { // subimage is a PNG std::string s = PNG_pvt::read_into_buffer (m_png, m_info, m_spec, m_bpp, m_color_type, m_buf); //std::cerr << "[ico] PNG buffer size = " << m_buf.size () << "\n"; if (s.length ()) { error ("%s", s.c_str ()); return false; } return true; } // otherwise we're dealing with a DIB DASSERT (m_spec.scanline_bytes() == ((size_t)m_spec.width * 4)); m_buf.resize (m_spec.image_bytes()); //std::cerr << "[ico] DIB buffer size = " << m_buf.size () << "\n"; // icons < 16bpp are colour-indexed, so load the palette // a palette consists of 4-byte BGR quads, with the last byte unused (reserved) std::vector palette (m_palette_size); if (m_bpp < 16) { // >= 16-bit icons are unpaletted for (int i = 0; i < m_palette_size; i++) if (! fread (&palette[i], 1, sizeof (ico_palette_entry))) return false; } // read the colour data (the 1-bit transparency is added later on) // scanline length in bytes (aligned to a multiple of 32 bits) int slb = (m_spec.width * m_bpp + 7) / 8 // real data bytes + (4 - ((m_spec.width * m_bpp + 7) / 8) % 4) % 4; // padding std::vector scanline (slb); ico_palette_entry *pe; int k; for (int y = m_spec.height - 1; y >= 0; y--) { if (! fread (&scanline[0], 1, slb)) return false; for (int x = 0; x < m_spec.width; x++) { k = y * m_spec.width * 4 + x * 4; // fill the buffer switch (m_bpp) { case 1: pe = &palette[(scanline[x / 8] & (1 << (7 - x % 8))) != 0]; m_buf[k + 0] = pe->r; m_buf[k + 1] = pe->g; m_buf[k + 2] = pe->b; break; case 4: pe = &palette[(scanline[x / 2] & 0xF0) >> 4]; m_buf[k + 0] = pe->r; m_buf[k + 1] = pe->g; m_buf[k + 2] = pe->b; // 2 pixels per byte pe = &palette[scanline[x / 2] & 0x0F]; if (x == m_spec.width - 1) break; // avoid buffer overflows x++; m_buf[k + 4] = pe->r; m_buf[k + 5] = pe->g; m_buf[k + 6] = pe->b; /*std::cerr << "[ico] " << y << " 2*4bit pixel: " << ((int)scanline[x / 2]) << " -> " << ((int)(scanline[x / 2] & 0xF0) >> 4) << " & " << ((int)(scanline[x / 2]) & 0x0F) << "\n";*/ break; case 8: pe = &palette[scanline[x]]; m_buf[k + 0] = pe->r; m_buf[k + 1] = pe->g; m_buf[k + 2] = pe->b; break; // bpp values > 8 mean non-indexed BGR(A) images #if 0 // doesn't seem like ICOs can really be 16-bit, where did I even get // this notion from? case 16: // FIXME: find out exactly which channel gets the 1 extra // bit; currently I assume it's green: 5B, 6G, 5R // extract and shift the bits m_buf[k + 0] = (scanline[x * 2 + 1] & 0x1F) << 3; m_buf[k + 1] = ((scanline[x * 2 + 1] & 0xE0) >> 3) | ((scanline[x * 2 + 0] & 0x07) << 5); m_buf[k + 2] = scanline[x * 2 + 0] & 0xF8; break; #endif case 24: m_buf[k + 0] = scanline[x * 3 + 2]; m_buf[k + 1] = scanline[x * 3 + 1]; m_buf[k + 2] = scanline[x * 3 + 0]; break; case 32: m_buf[k + 0] = scanline[x * 4 + 2]; m_buf[k + 1] = scanline[x * 4 + 1]; m_buf[k + 2] = scanline[x * 4 + 0]; m_buf[k + 3] = scanline[x * 4 + 3]; break; } } } // read the 1-bit transparency for < 32-bit icons if (m_bpp < 32) { // also aligned to a multiple of 32 bits slb = (m_spec.width + 7) / 8 // real data bytes + (4 - ((m_spec.width + 7) / 8) % 4) % 4; // padding scanline.resize (slb); for (int y = m_spec.height -1; y >= 0; y--) { if (! fread (&scanline[0], 1, slb)) return false; for (int x = 0; x < m_spec.width; x += 8) { for (int b = 0; b < 8; b++) { // bit k = y * m_spec.width * 4 + (x + 7 - b) * 4; if (scanline[x / 8] & (1 << b)) m_buf[k + 3] = 0; else m_buf[k + 3] = 255; } } } } return true; } bool ICOInput::close () { if (m_png && m_info) PNG_pvt::destroy_read_struct (m_png, m_info); if (m_file) { fclose (m_file); m_file = NULL; } init(); // Reset to initial state return true; } bool ICOInput::read_native_scanline (int y, int z, void *data) { if (m_buf.empty ()) { if (!readimg ()) return false; } size_t size = spec().scanline_bytes(); //std::cerr << "[ico] reading scanline " << y << " (" << size << " bytes)\n"; memcpy (data, &m_buf[y * size], size); return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/ico.imageio/icooutput.cpp0000644000175000017500000004267612271062644022051 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "ico.h" #include "../png.imageio/png_pvt.h" #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "thread.h" #include "strutil.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace ICO_pvt; class ICOOutput : public ImageOutput { public: ICOOutput (); virtual ~ICOOutput (); virtual const char * format_name (void) const { return "ico"; } virtual bool supports (const std::string &feature) const; virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle int m_color_type; ///< Requested colour type bool m_want_png; ///< Whether the client requested PNG std::vector m_scratch; ///< Scratch buffer int m_offset; ///< Offset to subimage data chunk int m_xor_slb; ///< XOR mask scanline length in bytes int m_and_slb; ///< AND mask scanline length in bytes int m_bpp; ///< Bits per pixel png_structp m_png; ///< PNG read structure pointer png_infop m_info; ///< PNG image info structure pointer std::vector m_pngtext; /// Initialize private members to pre-opened state void init (void) { m_file = NULL; m_png = NULL; m_info = NULL; m_pngtext.clear (); } /// Add a parameter to the output bool put_parameter (const std::string &name, TypeDesc type, const void *data); /// Finish the writing of a PNG subimage void finish_png_image (); /// Helper: read, with error detection /// template bool fwrite (const T *buf, size_t itemsize=sizeof(T), size_t nitems=1) { size_t n = ::fwrite (buf, itemsize, nitems, m_file); if (n != nitems) error ("Write error"); return n == nitems; } /// Helper: read, with error detection /// template bool fread (T *buf, size_t itemsize=sizeof(T), size_t nitems=1) { size_t n = ::fread (buf, itemsize, nitems, m_file); if (n != nitems) error ("Read error"); return n == nitems; } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *ico_output_imageio_create () { return new ICOOutput; } // OIIO_EXPORT int ico_imageio_version = OIIO_PLUGIN_VERSION; // it's in icoinput.cpp OIIO_EXPORT const char * ico_output_extensions[] = { "ico", NULL }; OIIO_PLUGIN_EXPORTS_END ICOOutput::ICOOutput () { init (); } ICOOutput::~ICOOutput () { // Close, if not already done. close (); } bool ICOOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode == AppendMIPLevel) { error ("%s does not support MIP levels", format_name()); return false; } close (); // Close any already-opened file m_spec = userspec; // Stash the spec if (m_spec.format == TypeDesc::UNKNOWN) // if unknown, default to 8 bits m_spec.set_format (TypeDesc::UINT8); // Check for things this format doesn't support if (m_spec.width < 1 || m_spec.height < 1) { error ("Image resolution must be at least 1x1, you asked for %d x %d", m_spec.width, m_spec.height); return false; } else if (m_spec.width > 256 || m_spec.height > 256) { error ("Image resolution must be at most 256x256, you asked for %d x %d", m_spec.width, m_spec.height); return false; } if (m_spec.depth < 1) m_spec.depth = 1; if (m_spec.depth > 1) { error ("%s does not support volume images (depth > 1)", format_name()); return false; } // check if the client wants this subimage written as PNG // also force PNG if image size is 256 because ico_header->width and height // are 8-bit const ImageIOParameter *p = m_spec.find_attribute ("ico:PNG", TypeDesc::TypeInt); m_want_png = (p && *(int *)p->data()) || m_spec.width == 256 || m_spec.height == 256; if (m_want_png) { std::string s = PNG_pvt::create_write_struct (m_png, m_info, m_color_type, m_spec); if (s.length ()) { error ("%s", s.c_str ()); return false; } } else { // reuse PNG constants for DIBs as well switch (m_spec.nchannels) { case 1 : m_color_type = PNG_COLOR_TYPE_GRAY; break; case 2 : m_color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break; case 3 : m_color_type = PNG_COLOR_TYPE_RGB; break; case 4 : m_color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; default: error ("ICO only supports 1-4 channels, not %d", m_spec.nchannels); return false; } m_bpp = (m_color_type == PNG_COLOR_TYPE_GRAY_ALPHA || m_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ? 32 : 24; m_xor_slb = (m_spec.width * m_bpp + 7) / 8 // real data bytes + (4 - ((m_spec.width * m_bpp + 7) / 8) % 4) % 4; // padding m_and_slb = (m_spec.width + 7) / 8 // real data bytes + (4 - ((m_spec.width + 7) / 8) % 4) % 4; // padding // Force 8 bit integers if (m_spec.format != TypeDesc::UINT8) m_spec.set_format (TypeDesc::UINT8); } //std::cerr << "[ico] writing at " << m_bpp << "bpp\n"; m_file = Filesystem::fopen (name, mode == AppendSubimage ? "r+b" : "wb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } ico_header ico; if (mode == Create) { // creating new file, write ICO header memset (&ico, 0, sizeof(ico)); ico.type = 1; ico.count = 1; if (bigendian()) { // ICOs are little endian swap_endian (&ico.type); swap_endian (&ico.count); } if (!fwrite(&ico)) { return false; } m_offset = sizeof(ico_header) + sizeof(ico_subimage); } else { // we'll be appending data, so see what's already in the file if (! fread (&ico)) return false; if (bigendian()) { // ICOs are little endian swap_endian (&ico.type); swap_endian (&ico.count); } /*std::cerr << "[ico] reserved = " << ico.reserved << " type = " << ico.type << " count = " << ico.count << "\n";*/ if (ico.reserved != 0 || ico.type != 1) { error ("File failed ICO header check"); return false; } // need to move stuff around to make room for another subimage header int subimage = ico.count++; fseek (m_file, 0, SEEK_END); int len = ftell (m_file); unsigned char buf[512]; // append null data at the end of file so that we don't seek beyond eof if (!fwrite (buf, sizeof(ico_subimage))) { return false; } // do the actual moving, 0.5kB per iteration int amount, skip = sizeof (ico_header) + sizeof (ico_subimage) * (subimage - 1); for (int left = len - skip; left > 0; left -= sizeof (buf)) { amount = std::min (left, (int)sizeof (buf)); /*std::cerr << "[ico] moving " << amount << " bytes (" << left << " vs " << sizeof (buf) << ")\n";*/ fseek (m_file, skip + left - amount, SEEK_SET); if (! fread (buf, 1, amount)) return false; fseek (m_file, skip + left - amount + sizeof (ico_subimage), SEEK_SET); if (!fwrite (buf, 1, amount)) { return false; } } // update header fseek (m_file, 0, SEEK_SET); // swap these back to little endian, if needed if (bigendian()) { swap_endian (&ico.type); swap_endian (&ico.count); } if (!fwrite(&ico)) { return false; } // and finally, update the offsets in subimage headers to point to // their data correctly uint32_t temp; fseek (m_file, offsetof (ico_subimage, ofs), SEEK_CUR); for (int i = 0; i < subimage; i++) { if (! fread (&temp)) return false; if (bigendian()) swap_endian (&temp); temp += sizeof (ico_subimage); if (bigendian()) swap_endian (&temp); // roll back 4 bytes, we need to rewrite the value we just read fseek (m_file, -4, SEEK_CUR); if (!fwrite(&temp)) { return false; } // skip to the next subimage; subtract 4 bytes because that's how // much we've just written fseek (m_file, sizeof (ico_subimage) - 4, SEEK_CUR); } // offset at which we'll be writing new image data m_offset = len + sizeof (ico_subimage); // next part of code expects the file pointer to be where the new // subimage header is to be written fseek (m_file, sizeof (ico_header) + subimage * sizeof (ico_subimage), SEEK_SET); } // write subimage header ico_subimage subimg; memset (&subimg, 0, sizeof(subimg)); subimg.width = m_spec.width; subimg.height = m_spec.height; subimg.bpp = m_bpp; if (!m_want_png) subimg.len = sizeof (ico_bitmapinfo) // for PNG images this is zero + (m_xor_slb + m_and_slb) * m_spec.height; subimg.ofs = m_offset; if (bigendian()) { swap_endian (&subimg.width); swap_endian (&subimg.height); swap_endian (&subimg.planes); swap_endian (&subimg.bpp); swap_endian (&subimg.len); swap_endian (&subimg.ofs); } if (!fwrite(&subimg)) { return false; } fseek (m_file, m_offset, SEEK_SET); if (m_want_png) { // unused still, should do conversion to unassociated bool convert_alpha; float gamma; png_init_io (m_png, m_file); png_set_compression_level (m_png, Z_BEST_COMPRESSION); PNG_pvt::write_info (m_png, m_info, m_color_type, m_spec, m_pngtext, convert_alpha, gamma); } else { // write DIB header ico_bitmapinfo bmi; memset (&bmi, 0, sizeof (bmi)); bmi.size = sizeof (bmi); bmi.width = m_spec.width; // this value is sum of heights of both XOR and AND masks bmi.height = m_spec.height * 2; bmi.bpp = m_bpp; bmi.planes = 1; bmi.len = subimg.len - sizeof (ico_bitmapinfo); if (bigendian()) { // ICOs are little endian swap_endian (&bmi.size); swap_endian (&bmi.bpp); swap_endian (&bmi.width); swap_endian (&bmi.height); swap_endian (&bmi.len); } if (!fwrite(&bmi)) { return false; } // append null data so that we don't seek beyond eof in write_scanline char buf[512]; memset (buf, 0, sizeof (buf)); for (int left = bmi.len; left > 0; left -= sizeof (buf)) { if (! fwrite (buf, 1, std::min (left, (int)sizeof (buf)))) { return false; } } fseek (m_file, m_offset + sizeof (bmi), SEEK_SET); } return true; } bool ICOOutput::supports (const std::string &feature) const { // advertise our support for subimages if (Strutil::iequals (feature, "multiimage")) return true; return false; } bool ICOOutput::close () { //std::cerr << "[ico] closing\n"; if (m_png && m_info) { PNG_pvt::finish_image (m_png); PNG_pvt::destroy_write_struct (m_png, m_info); } if (m_file) { fclose (m_file); m_file = NULL; } init (); // re-initialize return true; // How can we fail? // Epicly. -- IneQuation } bool ICOOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { m_spec.auto_stride (xstride, format, spec().nchannels); const void *origdata = data; data = to_native_scanline (format, data, xstride, m_scratch); if (data == origdata) { m_scratch.assign ((unsigned char *)data, (unsigned char *)data + m_spec.scanline_bytes()); data = &m_scratch[0]; } if (m_want_png) { if (!PNG_pvt::write_row (m_png, (png_byte *)data)) { error ("PNG library error"); return false; } } else { unsigned char *bdata = (unsigned char *)data; unsigned char buf[4]; fseek (m_file, m_offset + sizeof (ico_bitmapinfo) + (m_spec.height - y - 1) * m_xor_slb, SEEK_SET); // write the XOR mask size_t buff_size = 0; for (int x = 0; x < m_spec.width; x++) { switch (m_color_type) { // reuse PNG constants case PNG_COLOR_TYPE_GRAY: buf[0] = buf[1] = buf[2] = bdata[x]; buff_size = 3; break; case PNG_COLOR_TYPE_GRAY_ALPHA: buf[0] = buf[1] = buf[2] = bdata[x * 2 + 0]; buf[3] = bdata[x * 2 + 1]; buff_size = 4; break; case PNG_COLOR_TYPE_RGB: buf[0] = bdata[x * 3 + 2]; buf[1] = bdata[x * 3 + 1]; buf[2] = bdata[x * 3 + 0]; buff_size = 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: buf[0] = bdata[x * 4 + 2]; buf[1] = bdata[x * 4 + 1]; buf[2] = bdata[x * 4 + 0]; buf[3] = bdata[x * 4 + 3]; buff_size = 4; break; } if (!fwrite (buf, 1, buff_size)) { return false; } } fseek (m_file, m_offset + sizeof (ico_bitmapinfo) + m_spec.height * m_xor_slb + (m_spec.height - y - 1) * m_and_slb, SEEK_SET); // write the AND mask // It's required even for 32-bit images because it can be used when // drawing at colour depths lower than 24-bit. If it's not present, // Windows will read out-of-bounds, treating any data that it // encounters as the AND mask, resulting in ugly transparency effects. // Only need to do this for images with alpha, becasue 0 is opaque, // and we've already filled the file with zeros. if (m_color_type != PNG_COLOR_TYPE_GRAY && m_color_type != PNG_COLOR_TYPE_RGB) { for (int x = 0; x < m_spec.width; x += 8) { buf[0] = 0; for (int b = 0; b < 8 && x + b < m_spec.width; b++) { switch (m_color_type) { case PNG_COLOR_TYPE_GRAY_ALPHA: buf[0] |= bdata[(x + b) * 2 + 1] <= 127 ? (1 << (7 - b)) : 0; break; case PNG_COLOR_TYPE_RGB_ALPHA: buf[0] |= bdata[(x + b) * 4 + 3] <= 127 ? (1 << (7 - b)) : 0; break; } } if (!fwrite(&buf[0], 1, 1)) { return false; } } } } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/ico.imageio/CMakeLists.txt0000644000175000017500000000025212271062644022032 0ustar mfvmfvfind_package (PNG) if (PNG_FOUND) include_directories (${PNG_INCLUDE_DIR}) add_oiio_plugin (icoinput.cpp icooutput.cpp LINK_LIBRARIES ${PNG_LIBRARIES}) endif () openimageio-1.3.12~dfsg0.orig/src/openexr.imageio/0000755000175000017500000000000012271062644020201 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/openexr.imageio/exroutput.cpp0000644000175000017500000015614412271062644022777 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #include // The way that OpenEXR uses dynamic casting for attributes requires // temporarily suspending "hidden" symbol visibility mode. #ifdef __GNUC__ #pragma GCC visibility push(default) #endif #include #include #include #include #include #include #include #include #include #include #include // JUST to get symbols to figure out version! #include #include #ifdef __GNUC__ #pragma GCC visibility pop #endif #ifdef IMF_B44_COMPRESSION #define OPENEXR_VERSION_IS_1_6_OR_LATER #endif #ifdef USE_OPENEXR_VERSION2 #include #include #include #include #include #include #include #endif #include "dassert.h" #include "imageio.h" #include "filesystem.h" #include "thread.h" #include "strutil.h" #include "sysutil.h" #include "fmath.h" OIIO_PLUGIN_NAMESPACE_BEGIN // Custom file output stream, copying code from the class StdOFStream in // OpenEXR, which would have been used if we just provided a // filename. The difference is that this can handle UTF-8 file paths on // all platforms. class OpenEXROutputStream : public Imf::OStream { public: OpenEXROutputStream (const char *filename) : Imf::OStream(filename) { // The reason we have this class is for this line, so that we // can correctly handle UTF-8 file paths on Windows Filesystem::open (ofs, filename, std::ios_base::binary); if (!ofs) Iex::throwErrnoExc (); } virtual void write (const char c[], int n) { errno = 0; ofs.write (c, n); check_error (); } virtual Imath::Int64 tellp () { return std::streamoff (ofs.tellp ()); } virtual void seekp (Imath::Int64 pos) { ofs.seekp (pos); check_error (); } private: void check_error () { if (!ofs) { if (errno) Iex::throwErrnoExc (); throw Iex::ErrnoExc ("File output failed."); } } std::ofstream ofs; }; class OpenEXROutput : public ImageOutput { public: OpenEXROutput (); virtual ~OpenEXROutput (); virtual const char * format_name (void) const { return "openexr"; } virtual bool supports (const std::string &feature) const; virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool open (const std::string &name, int subimages, const ImageSpec *specs); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); virtual bool write_scanlines (int ybegin, int yend, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride); virtual bool write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride); virtual bool write_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride); virtual bool write_deep_scanlines (int ybegin, int yend, int z, const DeepData &deepdata); virtual bool write_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, const DeepData &deepdata); private: OpenEXROutputStream *m_output_stream; ///< Stream for output file Imf::OutputFile *m_output_scanline; ///< Input for scanline files Imf::TiledOutputFile *m_output_tiled; ///< Input for tiled files #ifdef USE_OPENEXR_VERSION2 Imf::MultiPartOutputFile *m_output_multipart; Imf::OutputPart *m_scanline_output_part; Imf::TiledOutputPart *m_tiled_output_part; Imf::DeepScanLineOutputPart *m_deep_scanline_output_part; Imf::DeepTiledOutputPart *m_deep_tiled_output_part; #else char *m_output_multipart; char *m_scanline_output_part; char *m_tiled_output_part; char *m_deep_scanline_output_part; char *m_deep_tiled_output_part; #endif int m_levelmode; ///< The level mode of the file int m_roundingmode; ///< Rounding mode of the file int m_subimage; ///< What subimage we're writing now int m_nsubimages; ///< How many subimages are there? int m_miplevel; ///< What miplevel we're writing now int m_nmiplevels; ///< How many mip levels are there? std::vector m_pixeltype; ///< Imf pixel type for each chan std::vector m_scratch; ///< Scratch space for us to use std::vector m_subimagespecs; ///< Saved subimage specs std::vector m_headers; // Initialize private members to pre-opened state void init (void) { m_output_stream = NULL; m_output_scanline = NULL; m_output_tiled = NULL; m_output_multipart = NULL; m_scanline_output_part = NULL; m_tiled_output_part = NULL; m_deep_scanline_output_part = NULL; m_deep_tiled_output_part = NULL; m_subimage = -1; m_miplevel = -1; std::vector().swap (m_subimagespecs); // clear and free std::vector().swap (m_headers); } // Set up the header based on the given spec. Also may doctor the // spec a bit. bool spec_to_header (ImageSpec &spec, int subimage, Imf::Header &header); // Add a parameter to the output static bool put_parameter (const std::string &name, TypeDesc type, const void *data, Imf::Header &header); // Decode the IlmImf MIP parameters from the spec. static void figure_mip (const ImageSpec &spec, int &nmiplevels, int &levelmode, int &roundingmode); }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput * openexr_output_imageio_create () { return new OpenEXROutput; } OIIO_EXPORT int openexr_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * openexr_output_extensions[] = { "exr", "sxr", "mxr", NULL }; OIIO_PLUGIN_EXPORTS_END static std::string format_string ("openexr"); static std::string format_prefix ("openexr_"); namespace pvt { void set_exr_threads (); // format-specific metadata prefixes static std::vector format_prefixes; static atomic_int format_prefixes_initialized; static spin_mutex format_prefixes_mutex; // guard } OpenEXROutput::OpenEXROutput () { pvt::set_exr_threads (); init (); } OpenEXROutput::~OpenEXROutput () { // Close, if not already done. close (); delete m_output_scanline; m_output_scanline = NULL; delete m_output_tiled; m_output_tiled = NULL; delete m_scanline_output_part; m_scanline_output_part = NULL; delete m_tiled_output_part; m_tiled_output_part = NULL; delete m_deep_scanline_output_part; m_deep_scanline_output_part = NULL; delete m_deep_tiled_output_part; m_deep_tiled_output_part = NULL; delete m_output_multipart; m_output_multipart = NULL; delete m_output_stream; m_output_stream = NULL; } bool OpenEXROutput::supports (const std::string &feature) const { if (feature == "tiles") return true; if (feature == "mipmap") return true; if (feature == "channelformats") return true; if (feature == "displaywindow") return true; if (feature == "origin") return true; if (feature == "negativeorigin") return true; #ifdef USE_OPENEXR_VERSION2 if (feature == "multiimage") return true; // N.B. But OpenEXR does not support "appendsubimage" #endif // EXR supports random write order iff lineOrder is set to 'random Y' if (feature == "random_access") { const ImageIOParameter *param = m_spec.find_attribute("openexr:lineOrder"); const char *lineorder = param ? *(char **)param->data() : NULL; return (lineorder && Strutil::iequals (lineorder, "randomY")); } // FIXME: we could support "empty" // Everything else, we either don't support or don't know about return false; } bool OpenEXROutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode == Create) { if (userspec.deep) // Fall back on multi-part OpenEXR for deep files return open (name, 1, &userspec); m_nsubimages = 1; m_subimage = 0; m_nmiplevels = 1; m_miplevel = 0; m_headers.resize (1); m_spec = userspec; // Stash the spec if (! spec_to_header (m_spec, m_subimage, m_headers[m_subimage])) return false; try { m_output_stream = new OpenEXROutputStream (name.c_str()); if (m_spec.tile_width) { m_output_tiled = new Imf::TiledOutputFile (*m_output_stream, m_headers[m_subimage]); } else { m_output_scanline = new Imf::OutputFile (*m_output_stream, m_headers[m_subimage]); } } catch (const std::exception &e) { error ("OpenEXR exception: %s", e.what()); m_output_scanline = NULL; m_output_tiled = NULL; return false; } if (! m_output_scanline && ! m_output_tiled) { error ("Unknown error opening EXR file"); return false; } return true; } if (mode == AppendSubimage) { #ifdef USE_OPENEXR_VERSION2 // OpenEXR 2.x supports subimages, but we only allow it to use the // open(name,subimages,specs[]) variety. if (m_subimagespecs.size() == 0 || ! m_output_multipart) { error ("%s not opened properly for subimages", format_name()); return false; } // Move on to next subimage ++m_subimage; if (m_subimage >= m_nsubimages) { error ("More subimages than originally declared."); return false; } // Close the current subimage, open the next one try { if (m_tiled_output_part) { delete m_tiled_output_part; m_tiled_output_part = new Imf::TiledOutputPart (*m_output_multipart, m_subimage); } else if (m_scanline_output_part) { delete m_scanline_output_part; m_scanline_output_part = new Imf::OutputPart (*m_output_multipart, m_subimage); } else if (m_deep_tiled_output_part) { delete m_deep_tiled_output_part; m_deep_tiled_output_part = new Imf::DeepTiledOutputPart (*m_output_multipart, m_subimage); } else if (m_deep_scanline_output_part) { delete m_deep_scanline_output_part; m_deep_scanline_output_part = new Imf::DeepScanLineOutputPart (*m_output_multipart, m_subimage); } else { ASSERT (0); } } catch (const std::exception &e) { error ("OpenEXR exception: %s", e.what()); m_scanline_output_part = NULL; m_tiled_output_part = NULL; m_deep_scanline_output_part = NULL; m_deep_tiled_output_part = NULL; return false; } m_spec = m_subimagespecs[m_subimage]; return true; #else // OpenEXR 1.x does not support subimages (multi-part) error ("%s does not support subimages", format_name()); return false; #endif } if (mode == AppendMIPLevel) { if (! m_output_scanline && ! m_output_tiled) { error ("Cannot append a MIP level if no file has been opened"); return false; } if (m_spec.tile_width && m_levelmode != Imf::ONE_LEVEL) { // OpenEXR does not support differing tile sizes on different // MIP-map levels. Reject the open() if not using the original // tile sizes. if (userspec.tile_width != m_spec.tile_width || userspec.tile_height != m_spec.tile_height) { error ("OpenEXR tiles must have the same size on all MIPmap levels"); return false; } // Copy the new mip level size. Keep everything else from the // original level. m_spec.width = userspec.width; m_spec.height = userspec.height; // N.B. do we need to copy anything else from userspec? ++m_miplevel; return true; } else { error ("Cannot add MIP level to a non-MIPmapped file"); return false; } } ASSERTMSG (0, "Unknown open mode %d", int(mode)); return false; } bool OpenEXROutput::open (const std::string &name, int subimages, const ImageSpec *specs) { if (subimages < 1) { error ("OpenEXR does not support %d subimages.", subimages); return false; } #ifdef USE_OPENEXR_VERSION2 // Only one part and not deep? Write an OpenEXR 1.x file if (subimages == 1 && ! specs[0].deep) return open (name, specs[0], Create); // Copy the passed-in subimages and turn into OpenEXR headers m_nsubimages = subimages; m_subimage = 0; m_nmiplevels = 1; m_miplevel = 0; m_subimagespecs.assign (specs, specs+subimages); m_headers.resize (subimages); std::string filetype; if (specs[0].deep) filetype = specs[0].tile_width ? "tiledimage" : "deepscanlineimage"; else filetype = specs[0].tile_width ? "tiledimage" : "scanlineimage"; bool deep = false; for (int s = 0; s < subimages; ++s) { if (! spec_to_header (m_subimagespecs[s], s, m_headers[s])) return false; deep |= m_subimagespecs[s].deep; if (m_subimagespecs[s].deep != m_subimagespecs[0].deep) { error ("OpenEXR does not support mixed deep/nondeep multi-part image files"); return false; } if (subimages > 1 || deep) { bool tiled = m_subimagespecs[s].tile_width; m_headers[s].setType (deep ? (tiled ? Imf::DEEPTILE : Imf::DEEPSCANLINE) : (tiled ? Imf::TILEDIMAGE : Imf::SCANLINEIMAGE)); } } m_spec = m_subimagespecs[0]; // Create an ImfMultiPartOutputFile try { // m_output_stream = new OpenEXROutputStream (name.c_str()); // m_output_multipart = new Imf::MultiPartOutputFile (*m_output_stream, // &m_headers[0], subimages); // FIXME: Oops, looks like OpenEXR 2.0 currently lacks a // MultiPartOutputFile ctr that takes an OStream, so we can't // do this quite yet. m_output_multipart = new Imf::MultiPartOutputFile (name.c_str(), &m_headers[0], subimages); } catch (const std::exception &e) { delete m_output_stream; m_output_stream = NULL; error ("OpenEXR exception: %s", e.what()); return false; } try { if (deep) { if (m_spec.tile_width) { m_deep_tiled_output_part = new Imf::DeepTiledOutputPart (*m_output_multipart, 0); } else { m_deep_scanline_output_part = new Imf::DeepScanLineOutputPart (*m_output_multipart, 0); } } else { if (m_spec.tile_width) { m_tiled_output_part = new Imf::TiledOutputPart (*m_output_multipart, 0); } else { m_scanline_output_part = new Imf::OutputPart (*m_output_multipart, 0); } } } catch (const std::exception &e) { error ("OpenEXR exception: %s", e.what()); delete m_output_stream; m_output_stream = NULL; m_scanline_output_part = NULL; m_tiled_output_part = NULL; m_deep_scanline_output_part = NULL; m_deep_tiled_output_part = NULL; return false; } return true; #else // No support for OpenEXR 2.x -- one subimage only if (subimages != 1) { error ("OpenEXR 1.x does not support multiple subimages."); return false; } if (specs[0].deep) { error ("OpenEXR 1.x does not support deep data."); return false; } return open (name, specs[0], Create); #endif } bool OpenEXROutput::spec_to_header (ImageSpec &spec, int subimage, Imf::Header &header) { if (spec.width < 1 || spec.height < 1) { error ("Image resolution must be at least 1x1, you asked for %d x %d", spec.width, spec.height); return false; } if (spec.depth < 1) spec.depth = 1; if (spec.depth > 1) { error ("%s does not support volume images (depth > 1)", format_name()); return false; } if (spec.full_width <= 0) spec.full_width = spec.width; if (spec.full_height <= 0) spec.full_height = spec.height; // Force use of one of the three data types that OpenEXR supports switch (spec.format.basetype) { case TypeDesc::UINT: spec.format = TypeDesc::UINT; break; case TypeDesc::FLOAT: case TypeDesc::DOUBLE: spec.format = TypeDesc::FLOAT; break; default: // Everything else defaults to half spec.format = TypeDesc::HALF; } Imath::Box2i dataWindow (Imath::V2i (spec.x, spec.y), Imath::V2i (spec.width + spec.x - 1, spec.height + spec.y - 1)); Imath::Box2i displayWindow (Imath::V2i (spec.full_x, spec.full_y), Imath::V2i (spec.full_width+spec.full_x-1, spec.full_height+spec.full_y-1)); header = Imf::Header (displayWindow, dataWindow); // Insert channels into the header. Also give the channels names if // the user botched it. m_pixeltype.clear (); static const char *default_chan_names[] = { "R", "G", "B", "A" }; spec.channelnames.resize (spec.nchannels); for (int c = 0; c < spec.nchannels; ++c) { if (spec.channelnames[c].empty()) spec.channelnames[c] = (c<4) ? default_chan_names[c] : Strutil::format ("unknown %d", c); TypeDesc format = spec.channelformat(c); Imf::PixelType ptype; switch (format.basetype) { case TypeDesc::UINT: ptype = Imf::UINT; format = TypeDesc::UINT; break; case TypeDesc::FLOAT: case TypeDesc::DOUBLE: ptype = Imf::FLOAT; format = TypeDesc::FLOAT; break; default: // Everything else defaults to half ptype = Imf::HALF; format = TypeDesc::HALF; } #ifdef OPENEXR_VERSION_IS_1_6_OR_LATER // Hint to lossy compression methods that indicates whether // human perception of the quantity represented by this channel // is closer to linear or closer to logarithmic. Compression // methods may optimize image quality by adjusting pixel data // quantization acording to this hint. bool pLinear = Strutil::iequals (spec.get_string_attribute ("oiio:ColorSpace", "Linear"), "Linear"); #endif m_pixeltype.push_back (ptype); if (spec.channelformats.size()) spec.channelformats[c] = format; header.channels().insert (spec.channelnames[c].c_str(), Imf::Channel(ptype, 1, 1 #ifdef OPENEXR_VERSION_IS_1_6_OR_LATER , pLinear #endif )); } ASSERT (m_pixeltype.size() == (size_t)spec.nchannels); // Default to ZIP compression if no request came with the user spec. if (! spec.find_attribute("compression")) spec.attribute ("compression", "zip"); // It seems that zips is the only compression that can reliably work // on deep files. if (spec.deep) spec.attribute ("compression", "zips"); // Default to increasingY line order, same as EXR. if (! spec.find_attribute("openexr:lineOrder")) spec.attribute ("openexr:lineOrder", "increasingY"); // Automatically set date field if the client didn't supply it. if (! spec.find_attribute("DateTime")) { time_t now; time (&now); struct tm mytm; Sysutil::get_local_time (&now, &mytm); std::string date = Strutil::format ("%4d:%02d:%02d %2d:%02d:%02d", mytm.tm_year+1900, mytm.tm_mon+1, mytm.tm_mday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec); spec.attribute ("DateTime", date); } figure_mip (spec, m_nmiplevels, m_levelmode, m_roundingmode); std::string textureformat = spec.get_string_attribute ("textureformat", ""); if (Strutil::iequals (textureformat, "CubeFace Environment")) { header.insert ("envmap", Imf::EnvmapAttribute(Imf::ENVMAP_CUBE)); } else if (Strutil::iequals (textureformat, "LatLong Environment")) { header.insert ("envmap", Imf::EnvmapAttribute(Imf::ENVMAP_LATLONG)); } if (spec.tile_width) header.setTileDescription ( Imf::TileDescription (spec.tile_width, spec.tile_height, Imf::LevelMode(m_levelmode), Imf::LevelRoundingMode(m_roundingmode))); // Deal with all other params for (size_t p = 0; p < spec.extra_attribs.size(); ++p) put_parameter (spec.extra_attribs[p].name().string(), spec.extra_attribs[p].type(), spec.extra_attribs[p].data(), header); #ifdef USE_OPENEXR_VERSION2 // Multi-part EXR files required to have a name. Make one up if not // supplied. if (m_nsubimages > 1 && ! header.hasName()) { std::string n = Strutil::format ("subimage%02d", subimage); header.insert ("name", Imf::StringAttribute (n)); } #endif return true; } void OpenEXROutput::figure_mip (const ImageSpec &spec, int &nmiplevels, int &levelmode, int &roundingmode) { nmiplevels = 1; levelmode = Imf::ONE_LEVEL; // Default to no MIP-mapping roundingmode = spec.get_int_attribute ("openexr:roundingmode", Imf::ROUND_DOWN); std::string textureformat = spec.get_string_attribute ("textureformat", ""); if (Strutil::iequals (textureformat, "Plain Texture")) { levelmode = spec.get_int_attribute ("openexr:levelmode", Imf::MIPMAP_LEVELS); } else if (Strutil::iequals (textureformat, "CubeFace Environment")) { levelmode = spec.get_int_attribute ("openexr:levelmode", Imf::MIPMAP_LEVELS); } else if (Strutil::iequals (textureformat, "LatLong Environment")) { levelmode = spec.get_int_attribute ("openexr:levelmode", Imf::MIPMAP_LEVELS); } else if (Strutil::iequals (textureformat, "Shadow")) { levelmode = Imf::ONE_LEVEL; // Force one level for shadow maps } if (levelmode == Imf::MIPMAP_LEVELS) { // Compute how many mip levels there will be int w = spec.width; int h = spec.height; while (w > 1 && h > 1) { if (roundingmode == Imf::ROUND_DOWN) { w = w / 2; h = h / 2; } else { w = (w + 1) / 2; h = (h + 1) / 2; } w = std::max (1, w); h = std::max (1, h); ++nmiplevels; } } } bool OpenEXROutput::put_parameter (const std::string &name, TypeDesc type, const void *data, Imf::Header &header) { // Translate std::string xname = name; if (Strutil::iequals(xname, "worldtocamera")) xname = "worldToCamera"; else if (Strutil::iequals(xname, "worldtoscreen")) xname = "worldToNDC"; else if (Strutil::iequals(xname, "DateTime")) xname = "capDate"; else if (Strutil::iequals(xname, "description") || Strutil::iequals(xname, "ImageDescription")) xname = "comments"; else if (Strutil::iequals(xname, "Copyright")) xname = "owner"; else if (Strutil::iequals(xname, "PixelAspectRatio")) xname = "pixelAspectRatio"; else if (Strutil::iequals(xname, "ExposureTime")) xname = "expTime"; else if (Strutil::iequals(xname, "FNumber")) xname = "aperture"; else if (Strutil::iequals(xname, "name")) xname = "oiio::subimagename"; else if (Strutil::istarts_with (xname, format_prefix)) xname = std::string (xname.begin()+format_prefix.size(), xname.end()); // std::cerr << "exr put '" << name << "' -> '" << xname << "'\n"; // Special cases if (Strutil::iequals(xname, "Compression") && type == TypeDesc::STRING) { const char *str = *(char **)data; header.compression() = Imf::ZIP_COMPRESSION; // Default if (str) { if (Strutil::iequals (str, "none")) header.compression() = Imf::NO_COMPRESSION; else if (Strutil::iequals (str, "deflate") || Strutil::iequals (str, "zip")) header.compression() = Imf::ZIP_COMPRESSION; else if (Strutil::iequals (str, "rle")) header.compression() = Imf::RLE_COMPRESSION; else if (Strutil::iequals (str, "zips")) header.compression() = Imf::ZIPS_COMPRESSION; else if (Strutil::iequals (str, "piz")) header.compression() = Imf::PIZ_COMPRESSION; else if (Strutil::iequals (str, "pxr24")) header.compression() = Imf::PXR24_COMPRESSION; #ifdef IMF_B44_COMPRESSION // The enum Imf::B44_COMPRESSION is not defined in older versions // of OpenEXR, and there are no explicit version numbers in the // headers. BUT this other related #define is present only in // the newer version. else if (Strutil::iequals (str, "b44")) header.compression() = Imf::B44_COMPRESSION; else if (Strutil::iequals (str, "b44a")) header.compression() = Imf::B44A_COMPRESSION; #endif } return true; } if (Strutil::iequals (xname, "openexr:lineOrder") && type == TypeDesc::STRING) { const char *str = *(char **)data; header.lineOrder() = Imf::INCREASING_Y; // Default if (str) { if (Strutil::iequals (str, "randomY")) header.lineOrder() = Imf::RANDOM_Y; else if (Strutil::iequals (str, "decreasingY")) header.lineOrder() = Imf::DECREASING_Y; } return true; } // SMPTE types if (Strutil::iequals (xname, "smpte:TimeCode")) xname = "timeCode"; if (Strutil::iequals (xname, "smpte:KeyCode")) xname = "keyCode"; // Supress planarconfig! if (Strutil::iequals (xname, "planarconfig") || Strutil::iequals (xname, "tiff:planarconfig")) return true; // Special handling of any remaining "oiio:*" metadata. if (Strutil::istarts_with (xname, "oiio:")) { // None currently supported return false; } // Before handling general named metadata, suppress non-openexr // format-specific metadata. if (const char *colon = strchr (xname.c_str(), ':')) { std::string prefix (xname.c_str(), colon); if (! Strutil::iequals (prefix, "openexr")) { if (! pvt::format_prefixes_initialized) { // Retrieve and split the list, only the first time spin_lock lock (pvt::format_prefixes_mutex); std::string format_list; OIIO::getattribute ("format_list", format_list); Strutil::split (format_list, pvt::format_prefixes, ","); pvt::format_prefixes_initialized = true; } for (size_t i = 0, e = pvt::format_prefixes.size(); i < e; ++i) if (Strutil::iequals (prefix, pvt::format_prefixes[i])) return false; } } // A few EXR things to suppress -- they should be added automatically by // the library, don't mess it up by inadvertently copying it wrong from // the user or from a file we read. if (Strutil::iequals(xname, "type") || Strutil::iequals(xname, "version") || Strutil::iequals(xname, "chunkCount") || Strutil::iequals(xname, "maxSamplesPerPixel")) { return false; } // General handling of attributes // Scalar if (type.arraylen == 0) { if (type.aggregate == TypeDesc::SCALAR) { if (type == TypeDesc::INT || type == TypeDesc::UINT) { header.insert (xname.c_str(), Imf::IntAttribute (*(int*)data)); return true; } if (type == TypeDesc::INT16) { header.insert (xname.c_str(), Imf::IntAttribute (*(short*)data)); return true; } if (type == TypeDesc::UINT16) { header.insert (xname.c_str(), Imf::IntAttribute (*(unsigned short*)data)); return true; } if (type == TypeDesc::FLOAT) { header.insert (xname.c_str(), Imf::FloatAttribute (*(float*)data)); return true; } if (type == TypeDesc::HALF) { header.insert (xname.c_str(), Imf::FloatAttribute ((float)*(half*)data)); return true; } if (type == TypeDesc::TypeString) { header.insert (xname.c_str(), Imf::StringAttribute (*(char**)data)); return true; } } // Single instance of aggregate type if (type.aggregate == TypeDesc::VEC2) { switch (type.basetype) { case TypeDesc::UINT: case TypeDesc::INT: // TODO could probably handle U/INT16 here too header.insert (xname.c_str(), Imf::V2iAttribute (*(Imath::V2i*)data)); return true; case TypeDesc::FLOAT: header.insert (xname.c_str(), Imf::V2fAttribute (*(Imath::V2f*)data)); return true; #ifdef USE_OPENEXR_VERSION2 case TypeDesc::DOUBLE: header.insert (xname.c_str(), Imf::V2dAttribute (*(Imath::V2d*)data)); return true; case TypeDesc::STRING: Imf::StringVector v; v.push_back(((std::string*)data)[0]); v.push_back(((std::string*)data)[1]); header.insert (xname.c_str(), Imf::StringVectorAttribute (v)); return true; #endif } } if (type.aggregate == TypeDesc::VEC3) { switch (type.basetype) { case TypeDesc::UINT: case TypeDesc::INT: // TODO could probably handle U/INT16 here too header.insert (xname.c_str(), Imf::V3iAttribute (*(Imath::V3i*)data)); return true; case TypeDesc::FLOAT: header.insert (xname.c_str(), Imf::V3fAttribute (*(Imath::V3f*)data)); return true; #ifdef USE_OPENEXR_VERSION2 case TypeDesc::DOUBLE: header.insert (xname.c_str(), Imf::V3dAttribute (*(Imath::V3d*)data)); return true; case TypeDesc::STRING: Imf::StringVector v; v.push_back(((std::string*)data)[0]); v.push_back(((std::string*)data)[1]); v.push_back(((std::string*)data)[2]); header.insert (xname.c_str(), Imf::StringVectorAttribute (v)); return true; #endif } } if (type.aggregate == TypeDesc::MATRIX44) { switch (type.basetype) { case TypeDesc::FLOAT: header.insert (xname.c_str(), Imf::M44fAttribute (*(Imath::M44f*)data)); return true; #ifdef USE_OPENEXR_VERSION2 case TypeDesc::DOUBLE: header.insert (xname.c_str(), Imf::M44dAttribute (*(Imath::M44d*)data)); return true; #endif } } } // Unknown length arrays (Don't know how to handle these yet) else if (type.arraylen < 0) { return false; } // Arrays else { // TimeCode if (type == TypeDesc::TypeTimeCode ) { header.insert(xname.c_str(), Imf::TimeCodeAttribute (*(Imf::TimeCode*)data)); return true; } // KeyCode else if (type == TypeDesc::TypeKeyCode ) { header.insert(xname.c_str(), Imf::KeyCodeAttribute (*(Imf::KeyCode*)data)); return true; } // 2 Vec2's are treated as a Box if (type.arraylen == 2 && type.aggregate == TypeDesc::VEC2) { switch (type.basetype) { case TypeDesc::UINT: case TypeDesc::INT: { int *a = (int*)data; header.insert(xname.c_str(), Imf::Box2iAttribute(Imath::Box2i(Imath::V2i(a[0],a[1]), Imath::V2i(a[2],a[3]) ))); return true; } case TypeDesc::FLOAT: { float *a = (float*)data; header.insert(xname.c_str(), Imf::Box2fAttribute(Imath::Box2f(Imath::V2f(a[0],a[1]), Imath::V2f(a[2],a[3]) ))); return true; } } } // Vec 2 else if (type.arraylen == 2 && type.aggregate == TypeDesc::SCALAR) { switch (type.basetype) { case TypeDesc::UINT: case TypeDesc::INT: // TODO could probably handle U/INT16 here too header.insert (xname.c_str(), Imf::V2iAttribute (*(Imath::V2i*)data)); return true; case TypeDesc::FLOAT: header.insert (xname.c_str(), Imf::V2fAttribute (*(Imath::V2f*)data)); return true; #ifdef USE_OPENEXR_VERSION2 case TypeDesc::DOUBLE: header.insert (xname.c_str(), Imf::V2dAttribute (*(Imath::V2d*)data)); return true; case TypeDesc::STRING: Imf::StringVector v; v.push_back(((std::string*)data)[0]); v.push_back(((std::string*)data)[1]); header.insert (xname.c_str(), Imf::StringVectorAttribute (v)); return true; #endif } } // Vec3 else if (type.arraylen == 3 && type.aggregate == TypeDesc::SCALAR) { switch (type.basetype) { case TypeDesc::UINT: case TypeDesc::INT: // TODO could probably handle U/INT16 here too header.insert (xname.c_str(), Imf::V3iAttribute (*(Imath::V3i*)data)); return true; case TypeDesc::FLOAT: header.insert (xname.c_str(), Imf::V3fAttribute (*(Imath::V3f*)data)); return true; #ifdef USE_OPENEXR_VERSION2 case TypeDesc::DOUBLE: header.insert (xname.c_str(), Imf::V3dAttribute (*(Imath::V3d*)data)); return true; case TypeDesc::STRING: Imf::StringVector v; v.push_back(((std::string*)data)[0]); v.push_back(((std::string*)data)[1]); v.push_back(((std::string*)data)[2]); header.insert (xname.c_str(), Imf::StringVectorAttribute (v)); return true; #endif } } // Matrix else if (type.arraylen == 16 && type.aggregate == TypeDesc::SCALAR) { switch (type.basetype) { case TypeDesc::FLOAT: header.insert (xname.c_str(), Imf::M44fAttribute (*(Imath::M44f*)data)); return true; #ifdef USE_OPENEXR_VERSION2 case TypeDesc::DOUBLE: header.insert (xname.c_str(), Imf::M44dAttribute (*(Imath::M44d*)data)); return true; #endif } } #ifdef USE_OPENEXR_VERSION2 // String Vector else if (type.basetype == TypeDesc::STRING) { Imf::StringVector v; for (int i=0; isetFrameBuffer (frameBuffer); m_output_scanline->writePixels (1); #ifdef USE_OPENEXR_VERSION2 } else if (m_scanline_output_part) { m_scanline_output_part->setFrameBuffer (frameBuffer); m_scanline_output_part->writePixels (1); #endif } else { ASSERT (0); } } catch (const std::exception &e) { error ("Failed OpenEXR write: %s", e.what()); return false; } // FIXME -- can we checkpoint the file? return true; } bool OpenEXROutput::write_scanlines (int ybegin, int yend, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride) { if (! (m_output_scanline || m_scanline_output_part)) { error ("called OpenEXROutput::write_scanlines without an open file"); return false; } yend = std::min (yend, spec().y+spec().height); bool native = (format == TypeDesc::UNKNOWN); imagesize_t scanlinebytes = spec().scanline_bytes(true); size_t pixel_bytes = m_spec.pixel_bytes (true); if (native && xstride == AutoStride) xstride = (stride_t) pixel_bytes; stride_t zstride = AutoStride; m_spec.auto_stride (xstride, ystride, zstride, format, m_spec.nchannels, m_spec.width, m_spec.height); const imagesize_t limit = 16*1024*1024; // Allocate 16 MB, or 1 scanline int chunk = std::max (1, int(limit / scanlinebytes)); bool ok = true; for ( ; ok && ybegin < yend; ybegin += chunk) { int y1 = std::min (ybegin+chunk, yend); int nscanlines = y1 - ybegin; const void *d = to_native_rectangle (m_spec.x, m_spec.x+m_spec.width, ybegin, y1, z, z+1, format, data, xstride, ystride, zstride, m_scratch); // Compute where OpenEXR needs to think the full buffers starts. // OpenImageIO requires that 'data' points to where client stored // the bytes to be written, but OpenEXR's frameBuffer.insert() wants // where the address of the "virtual framebuffer" for the whole // image. char *buf = (char *)d - m_spec.x * pixel_bytes - ybegin * scanlinebytes; try { Imf::FrameBuffer frameBuffer; size_t chanoffset = 0; for (int c = 0; c < m_spec.nchannels; ++c) { size_t chanbytes = m_spec.channelformat(c).size(); frameBuffer.insert (m_spec.channelnames[c].c_str(), Imf::Slice (m_pixeltype[c], buf + chanoffset, pixel_bytes, scanlinebytes)); chanoffset += chanbytes; } if (m_output_scanline) { m_output_scanline->setFrameBuffer (frameBuffer); m_output_scanline->writePixels (nscanlines); #ifdef USE_OPENEXR_VERSION2 } else if (m_scanline_output_part) { m_scanline_output_part->setFrameBuffer (frameBuffer); m_scanline_output_part->writePixels (nscanlines); #endif } else { ASSERT (0); } } catch (const std::exception &e) { error ("Failed OpenEXR write: %s", e.what()); return false; } data = (const char *)data + ystride*nscanlines; } // If we allocated more than 1M, free the memory. It's not wasteful, // because it means we're writing big chunks at a time, and therefore // there will be few allocations and deletions. if (m_scratch.size() > 1*1024*1024) { std::vector dummy; std::swap (m_scratch, dummy); } return true; } bool OpenEXROutput::write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride) { return write_tiles (x, std::min (x+m_spec.tile_width, m_spec.x+m_spec.width), y, std::min (y+m_spec.tile_height, m_spec.y+m_spec.height), z, std::min (z+m_spec.tile_depth, m_spec.z+m_spec.depth), format, data, xstride, ystride, zstride); } bool OpenEXROutput::write_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride) { // std::cerr << "exr::write_tiles " << xbegin << ' ' << xend // << ' ' << ybegin << ' ' << yend << "\n"; if (! (m_output_tiled || m_tiled_output_part)) { error ("called OpenEXROutput::write_tiles without an open file"); return false; } if (! m_spec.valid_tile_range (xbegin, xend, ybegin, yend, zbegin, zend)) { error ("called OpenEXROutput::write_tiles with an invalid tile range"); return false; } // Compute where OpenEXR needs to think the full buffers starts. // OpenImageIO requires that 'data' points to where the client wants // to put the pixels being read, but OpenEXR's frameBuffer.insert() // wants where the address of the "virtual framebuffer" for the // whole image. bool native = (format == TypeDesc::UNKNOWN); size_t user_pixelbytes = m_spec.pixel_bytes (native); size_t pixelbytes = m_spec.pixel_bytes (true); if (native && xstride == AutoStride) xstride = (stride_t) user_pixelbytes; m_spec.auto_stride (xstride, ystride, zstride, format, spec().nchannels, (xend-xbegin), (yend-ybegin)); data = to_native_rectangle (xbegin, xend, ybegin, yend, zbegin, zend, format, data, xstride, ystride, zstride, m_scratch); // clamp to the image edge xend = std::min (xend, m_spec.x+m_spec.width); yend = std::min (yend, m_spec.y+m_spec.height); zend = std::min (zend, m_spec.z+m_spec.depth); int firstxtile = (xbegin-m_spec.x) / m_spec.tile_width; int firstytile = (ybegin-m_spec.y) / m_spec.tile_height; int nxtiles = (xend - xbegin + m_spec.tile_width - 1) / m_spec.tile_width; int nytiles = (yend - ybegin + m_spec.tile_height - 1) / m_spec.tile_height; std::vector padded; int width = nxtiles*m_spec.tile_width; int height = nytiles*m_spec.tile_height; stride_t widthbytes = width * pixelbytes; if (width != (xend-xbegin) || height != (yend-ybegin)) { // If the image region is not an even multiple of the tile size, // we need to copy and add padding. padded.resize (pixelbytes * width * height, 0); OIIO::copy_image (m_spec.nchannels, xend-xbegin, yend-ybegin, 1, data, pixelbytes, pixelbytes, (xend-xbegin)*pixelbytes, (xend-xbegin)*(yend-ybegin)*pixelbytes, &padded[0], pixelbytes, widthbytes, height*widthbytes); data = &padded[0]; } char *buf = (char *)data - xbegin * pixelbytes - ybegin * widthbytes; try { Imf::FrameBuffer frameBuffer; size_t chanoffset = 0; for (int c = 0; c < m_spec.nchannels; ++c) { size_t chanbytes = m_spec.channelformat(c).size(); frameBuffer.insert (m_spec.channelnames[c].c_str(), Imf::Slice (m_pixeltype[c], buf + chanoffset, pixelbytes, widthbytes)); chanoffset += chanbytes; } if (m_output_tiled) { m_output_tiled->setFrameBuffer (frameBuffer); m_output_tiled->writeTiles (firstxtile, firstxtile+nxtiles-1, firstytile, firstytile+nytiles-1, m_miplevel, m_miplevel); #ifdef USE_OPENEXR_VERSION2 } else if (m_tiled_output_part) { m_tiled_output_part->setFrameBuffer (frameBuffer); m_tiled_output_part->writeTiles (firstxtile, firstxtile+nxtiles-1, firstytile, firstytile+nytiles-1, m_miplevel, m_miplevel); #endif } else { ASSERT (0); } } catch (const std::exception &e) { error ("Failed OpenEXR write: %s", e.what()); return false; } return true; } bool OpenEXROutput::write_deep_scanlines (int ybegin, int yend, int z, const DeepData &deepdata) { if (m_deep_scanline_output_part == NULL) { error ("called OpenEXROutput::write_deep_scanlines without an open file"); return false; } if (m_spec.width*(yend-ybegin) != deepdata.npixels || m_spec.nchannels != deepdata.nchannels) { error ("called OpenEXROutput::write_deep_scanlines with non-matching DeepData size"); return false; } #ifdef USE_OPENEXR_VERSION2 int nchans = m_spec.nchannels; try { // Set up the count and pointers arrays and the Imf framebuffer Imf::DeepFrameBuffer frameBuffer; Imf::Slice countslice (Imf::UINT, (char *)(&deepdata.nsamples[0] - m_spec.x - ybegin*m_spec.width), sizeof(unsigned int), sizeof(unsigned int) * m_spec.width); frameBuffer.insertSampleCountSlice (countslice); for (int c = 0; c < nchans; ++c) { size_t chanbytes = deepdata.channeltypes[c].size(); Imf::DeepSlice slice (m_pixeltype[c], (char *)(&deepdata.pointers[c] - m_spec.x * nchans - ybegin*m_spec.width*nchans), sizeof(void*) * nchans, // xstride of pointer array sizeof(void*) * nchans*m_spec.width, // ystride of pointer array chanbytes); // stride of data sample frameBuffer.insert (m_spec.channelnames[c].c_str(), slice); } m_deep_scanline_output_part->setFrameBuffer (frameBuffer); // Write the pixels m_deep_scanline_output_part->writePixels (yend-ybegin); } catch (const std::exception &e) { error ("Failed OpenEXR write: %s", e.what()); return false; } return true; #else error ("deep data not supported with OpenEXR 1.x"); return false; #endif } bool OpenEXROutput::write_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, const DeepData &deepdata) { if (m_deep_tiled_output_part == NULL) { error ("called OpenEXROutput::write_deep_tiles without an open file"); return false; } if ((xend-xbegin)*(yend-ybegin)*(zend-zbegin) != deepdata.npixels || m_spec.nchannels != deepdata.nchannels) { error ("called OpenEXROutput::write_deep_tiles with non-matching DeepData size"); return false; } #ifdef USE_OPENEXR_VERSION2 int nchans = m_spec.nchannels; try { size_t width = (xend - xbegin); // Set up the count and pointers arrays and the Imf framebuffer Imf::DeepFrameBuffer frameBuffer; Imf::Slice countslice (Imf::UINT, (char *)(&deepdata.nsamples[0] - xbegin - ybegin*width), sizeof(unsigned int), sizeof(unsigned int) * width); frameBuffer.insertSampleCountSlice (countslice); for (int c = 0; c < nchans; ++c) { size_t chanbytes = m_spec.channelformat(c).size(); Imf::DeepSlice slice (m_pixeltype[c], (char *)(&deepdata.pointers[c] - xbegin*nchans - ybegin*width*nchans), sizeof(void*) * nchans, // xstride of pointer array sizeof(void*) * nchans*width, // ystride of pointer array chanbytes); // stride of data sample frameBuffer.insert (m_spec.channelnames[c].c_str(), slice); } m_deep_tiled_output_part->setFrameBuffer (frameBuffer); int firstxtile = (xbegin-m_spec.x) / m_spec.tile_width; int firstytile = (ybegin-m_spec.y) / m_spec.tile_height; int xtiles = round_to_multiple (xend-xbegin, m_spec.tile_width) / m_spec.tile_width; int ytiles = round_to_multiple (yend-ybegin, m_spec.tile_height) / m_spec.tile_height; // Write the pixels m_deep_tiled_output_part->writeTiles (firstxtile, firstxtile+xtiles-1, firstytile, firstytile+ytiles-1, m_miplevel, m_miplevel); } catch (const std::exception &e) { error ("Failed OpenEXR write: %s", e.what()); return false; } return true; #else error ("deep data not supported with OpenEXR 1.x"); return false; #endif } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/openexr.imageio/exrinput.cpp0000644000175000017500000012636312271062644022576 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #include #include // The way that OpenEXR uses dynamic casting for attributes requires // temporarily suspending "hidden" symbol visibility mode. #ifdef __GNUC__ #pragma GCC visibility push(default) #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef USE_OPENEXR_VERSION2 #include #include #include #include #include #include #include #include #endif #ifdef __GNUC__ #pragma GCC visibility pop #endif #include #include "dassert.h" #include "imageio.h" #include "thread.h" #include "strutil.h" #include "fmath.h" #include "filesystem.h" #include OIIO_PLUGIN_NAMESPACE_BEGIN // Custom file input stream, copying code from the class StdIFStream in OpenEXR, // which would have been used if we just provided a filename. The difference is // that this can handle UTF-8 file paths on all platforms. class OpenEXRInputStream : public Imf::IStream { public: OpenEXRInputStream (const char *filename) : Imf::IStream (filename) { // The reason we have this class is for this line, so that we // can correctly handle UTF-8 file paths on Windows Filesystem::open (ifs, filename, std::ios_base::binary); if (!ifs) Iex::throwErrnoExc (); } virtual bool read (char c[], int n) { if (!ifs) throw Iex::InputExc ("Unexpected end of file."); errno = 0; ifs.read (c, n); return check_error (); } virtual Imath::Int64 tellg () { return std::streamoff (ifs.tellg ()); } virtual void seekg (Imath::Int64 pos) { ifs.seekg (pos); check_error (); } virtual void clear () { ifs.clear (); } private: bool check_error () { if (!ifs) { if (errno) Iex::throwErrnoExc (); return false; } return true; } std::ifstream ifs; }; class OpenEXRInput : public ImageInput { public: OpenEXRInput (); virtual ~OpenEXRInput () { close(); } virtual const char * format_name (void) const { return "openexr"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (); virtual int current_subimage (void) const { return m_subimage; } virtual int current_miplevel (void) const { return m_miplevel; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual bool read_native_scanline (int y, int z, void *data); virtual bool read_native_scanlines (int ybegin, int yend, int z, void *data); virtual bool read_native_scanlines (int ybegin, int yend, int z, int chbegin, int chend, void *data); virtual bool read_native_tile (int x, int y, int z, void *data); virtual bool read_native_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, void *data); virtual bool read_native_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, void *data); virtual bool read_native_deep_scanlines (int ybegin, int yend, int z, int chbegin, int chend, DeepData &deepdata); virtual bool read_native_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, DeepData &deepdata); private: struct PartInfo { bool initialized; ImageSpec spec; int topwidth; ///< Width of top mip level int topheight; ///< Height of top mip level int levelmode; ///< The level mode int roundingmode; ///< Rounding mode bool cubeface; ///< It's a cubeface environment map int nmiplevels; ///< How many MIP levels are there? Imath::Box2i top_datawindow; Imath::Box2i top_displaywindow; std::vector pixeltype; ///< Imf pixel type for each chan std::vector chanbytes; ///< Size (in bytes) of each channel PartInfo () : initialized(false) { } ~PartInfo () { } void parse_header (const Imf::Header *header); void query_channels (const Imf::Header *header); }; std::vector m_parts; ///< Image parts OpenEXRInputStream *m_input_stream; ///< Stream for input file #ifdef USE_OPENEXR_VERSION2 Imf::MultiPartInputFile *m_input_multipart; ///< Multipart input Imf::InputPart *m_scanline_input_part; Imf::TiledInputPart *m_tiled_input_part; Imf::DeepScanLineInputPart *m_deep_scanline_input_part; Imf::DeepTiledInputPart *m_deep_tiled_input_part; #else char *m_input_multipart; ///< Multipart input char *m_scanline_input_part; char *m_tiled_input_part; char *m_deep_scanline_input_part; char *m_deep_tiled_input_part; #endif Imf::InputFile *m_input_scanline; ///< Input for scanline files Imf::TiledInputFile *m_input_tiled; ///< Input for tiled files int m_subimage; ///< What subimage are we looking at? int m_nsubimages; ///< How many subimages are there? int m_miplevel; ///< What MIP level are we looking at? std::vector m_scratch; ///< Scratch space for us to use void init () { m_input_stream = NULL; m_input_multipart = NULL; m_scanline_input_part = NULL; m_tiled_input_part = NULL; m_deep_scanline_input_part = NULL; m_deep_tiled_input_part = NULL; m_input_scanline = NULL; m_input_tiled = NULL; m_subimage = -1; m_miplevel = -1; } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput * openexr_input_imageio_create () { return new OpenEXRInput; } // OIIO_EXPORT int openexr_imageio_version = OIIO_PLUGIN_VERSION; // it's in exroutput.cpp OIIO_EXPORT const char * openexr_input_extensions[] = { "exr", "sxr", "mxr", NULL }; OIIO_PLUGIN_EXPORTS_END class StringMap { typedef std::map map_t; public: StringMap (void) { init(); } const std::string & operator[] (const std::string &s) const { map_t::const_iterator i; i = m_map.find (s); return i == m_map.end() ? s : i->second; } private: map_t m_map; void init (void) { // Ones whose name we change to our convention m_map["cameraTransform"] = "worldtocamera"; m_map["worldToCamera"] = "worldtocamera"; m_map["worldToNDC"] = "worldtoscreen"; m_map["capDate"] = "DateTime"; m_map["comments"] = "ImageDescription"; m_map["owner"] = "Copyright"; m_map["pixelAspectRatio"] = "PixelAspectRatio"; m_map["expTime"] = "ExposureTime"; // Ones we don't rename -- OpenEXR convention matches ours m_map["wrapmodes"] = "wrapmodes"; m_map["aperture"] = "FNumber"; // Ones to prefix with openexr: m_map["version"] = "openexr:version"; m_map["chunkCount"] = "openexr:chunkCount"; m_map["maxSamplesPerPixel"] = "openexr:maxSamplesPerPixel"; // Ones to skip because we handle specially m_map["channels"] = ""; m_map["compression"] = ""; m_map["dataWindow"] = ""; m_map["displayWindow"] = ""; m_map["envmap"] = ""; m_map["tiledesc"] = ""; m_map["openexr:lineOrder"] = ""; m_map["type"] = ""; // Ones to skip because we consider them irrelevant // m_map[""] = ""; // FIXME: Things to consider in the future: // preview // screenWindowCenter // chromaticities whiteLuminance adoptedNeutral // renderingTransform, lookModTransform // xDensity // utcOffset // longitude latitude altitude // focus isoSpeed // keyCode timeCode framesPerSecond } }; static StringMap exr_tag_to_ooio_std; namespace pvt { void set_exr_threads () { static int exr_threads = 0; // lives in exrinput.cpp static spin_mutex exr_threads_mutex; int oiio_threads = 1; OIIO::getattribute ("threads", oiio_threads); spin_lock lock (exr_threads_mutex); if (exr_threads != oiio_threads) { exr_threads = oiio_threads; Imf::setGlobalThreadCount (exr_threads == 1 ? 0 : exr_threads); } } } // namespace pvt OpenEXRInput::OpenEXRInput () { init (); } bool OpenEXRInput::valid_file (const std::string &filename) const { return Imf::isOpenExrFile (filename.c_str()); } bool OpenEXRInput::open (const std::string &name, ImageSpec &newspec) { // Quick check to reject non-exr files if (! Filesystem::is_regular (name)) { error ("Could not open file \"%s\"", name.c_str()); return false; } bool tiled; if (! Imf::isOpenExrFile (name.c_str(), tiled)) { error ("\"%s\" is not an OpenEXR file", name.c_str()); return false; } pvt::set_exr_threads (); m_spec = ImageSpec(); // Clear everything with default constructor try { m_input_stream = new OpenEXRInputStream (name.c_str()); } catch (const std::exception &e) { m_input_stream = NULL; error ("OpenEXR exception: %s", e.what()); return false; } #ifdef USE_OPENEXR_VERSION2 try { m_input_multipart = new Imf::MultiPartInputFile (*m_input_stream); } catch (const std::exception &e) { delete m_input_stream; m_input_stream = NULL; error ("OpenEXR exception: %s", e.what()); return false; } m_nsubimages = m_input_multipart->parts(); #else try { if (tiled) { m_input_tiled = new Imf::TiledInputFile (*m_input_stream); } else { m_input_scanline = new Imf::InputFile (*m_input_stream); } } catch (const std::exception &e) { delete m_input_stream; m_input_stream = NULL; error ("OpenEXR exception: %s", e.what()); return false; } if (! m_input_scanline && ! m_input_tiled) { error ("Unknown error opening EXR file"); return false; } m_nsubimages = 1; // OpenEXR 1.x did not have multipart #endif m_parts.resize (m_nsubimages); m_subimage = -1; m_miplevel = -1; bool ok = seek_subimage (0, 0, newspec); if (! ok) close (); return ok; } // Count number of MIPmap levels inline int numlevels (int width, int roundingmode) { int nlevels = 1; for ( ; width > 1; ++nlevels) { if (roundingmode == Imf::ROUND_DOWN) width = width / 2; else width = (width + 1) / 2; } return nlevels; } void OpenEXRInput::PartInfo::parse_header (const Imf::Header *header) { if (initialized) return; ASSERT (header); spec = ImageSpec(); top_datawindow = header->dataWindow(); top_displaywindow = header->displayWindow(); spec.x = top_datawindow.min.x; spec.y = top_datawindow.min.y; spec.z = 0; spec.width = top_datawindow.max.x - top_datawindow.min.x + 1; spec.height = top_datawindow.max.y - top_datawindow.min.y + 1; spec.depth = 1; topwidth = spec.width; // Save top-level mipmap dimensions topheight = spec.height; spec.full_x = top_displaywindow.min.x; spec.full_y = top_displaywindow.min.y; spec.full_z = 0; spec.full_width = top_displaywindow.max.x - top_displaywindow.min.x + 1; spec.full_height = top_displaywindow.max.y - top_displaywindow.min.y + 1; spec.full_depth = 1; spec.tile_depth = 1; if (header->hasTileDescription()) { const Imf::TileDescription &td (header->tileDescription()); spec.tile_width = td.xSize; spec.tile_height = td.ySize; levelmode = td.mode; roundingmode = td.roundingMode; if (levelmode == Imf::MIPMAP_LEVELS) nmiplevels = numlevels (std::max(topwidth,topheight), roundingmode); else if (levelmode == Imf::RIPMAP_LEVELS) nmiplevels = numlevels (std::max(topwidth,topheight), roundingmode); else nmiplevels = 1; } else { spec.tile_width = 0; spec.tile_height = 0; levelmode = Imf::ONE_LEVEL; nmiplevels = 1; } query_channels (header); // also sets format #ifdef USE_OPENEXR_VERSION2 spec.deep = Imf::isDeepData (header->type()); #endif // Unless otherwise specified, exr files are assumed to be linear. spec.attribute ("oiio:ColorSpace", "Linear"); if (levelmode != Imf::ONE_LEVEL) spec.attribute ("openexr:roundingmode", roundingmode); const Imf::EnvmapAttribute *envmap; envmap = header->findTypedAttribute("envmap"); if (envmap) { cubeface = (envmap->value() == Imf::ENVMAP_CUBE); spec.attribute ("textureformat", cubeface ? "CubeFace Environment" : "LatLong Environment"); // OpenEXR conventions for env maps if (! cubeface) spec.attribute ("oiio:updirection", "y"); spec.attribute ("oiio:sampleborder", 1); // FIXME - detect CubeFace Shadow? } else { cubeface = false; if (spec.tile_width && levelmode == Imf::MIPMAP_LEVELS) spec.attribute ("textureformat", "Plain Texture"); // FIXME - detect Shadow } const Imf::CompressionAttribute *compressattr; compressattr = header->findTypedAttribute("compression"); if (compressattr) { const char *comp = NULL; switch (compressattr->value()) { case Imf::NO_COMPRESSION : comp = "none"; break; case Imf::RLE_COMPRESSION : comp = "rle"; break; case Imf::ZIPS_COMPRESSION : comp = "zips"; break; case Imf::ZIP_COMPRESSION : comp = "zip"; break; case Imf::PIZ_COMPRESSION : comp = "piz"; break; case Imf::PXR24_COMPRESSION : comp = "pxr24"; break; #ifdef IMF_B44_COMPRESSION // The enum Imf::B44_COMPRESSION is not defined in older versions // of OpenEXR, and there are no explicit version numbers in the // headers. BUT this other related #define is present only in // the newer version. case Imf::B44_COMPRESSION : comp = "b44"; break; case Imf::B44A_COMPRESSION : comp = "b44a"; break; #endif default: break; } if (comp) spec.attribute ("compression", comp); } for (Imf::Header::ConstIterator hit = header->begin(); hit != header->end(); ++hit) { const Imf::IntAttribute *iattr; const Imf::FloatAttribute *fattr; const Imf::StringAttribute *sattr; const Imf::M44fAttribute *mattr; const Imf::V3fAttribute *v3fattr; const Imf::V3iAttribute *v3iattr; const Imf::V2fAttribute *v2fattr; const Imf::V2iAttribute *v2iattr; const Imf::Box2iAttribute *b2iattr; const Imf::Box2fAttribute *b2fattr; const Imf::TimeCodeAttribute *tattr; const Imf::KeyCodeAttribute *kcattr; #ifdef USE_OPENEXR_VERSION2 const Imf::StringVectorAttribute *svattr; #endif const char *name = hit.name(); std::string oname = exr_tag_to_ooio_std[name]; if (oname.empty()) // Empty string means skip this attrib continue; // if (oname == name) // oname = std::string(format_name()) + "_" + oname; const Imf::Attribute &attrib = hit.attribute(); std::string type = attrib.typeName(); if (type == "string" && (sattr = header->findTypedAttribute (name))) spec.attribute (oname, sattr->value().c_str()); else if (type == "int" && (iattr = header->findTypedAttribute (name))) spec.attribute (oname, iattr->value()); else if (type == "float" && (fattr = header->findTypedAttribute (name))) spec.attribute (oname, fattr->value()); else if (type == "m44f" && (mattr = header->findTypedAttribute (name))) spec.attribute (oname, TypeDesc::TypeMatrix, &(mattr->value())); else if (type == "v3f" && (v3fattr = header->findTypedAttribute (name))) spec.attribute (oname, TypeDesc::TypeVector, &(v3fattr->value())); else if (type == "v3i" && (v3iattr = header->findTypedAttribute (name))) { TypeDesc v3 (TypeDesc::INT, TypeDesc::VEC3, TypeDesc::VECTOR); spec.attribute (oname, v3, &(v3iattr->value())); } else if (type == "v2f" && (v2fattr = header->findTypedAttribute (name))) { TypeDesc v2 (TypeDesc::FLOAT,TypeDesc::VEC2); spec.attribute (oname, v2, &(v2fattr->value())); } else if (type == "v2i" && (v2iattr = header->findTypedAttribute (name))) { TypeDesc v2 (TypeDesc::INT,TypeDesc::VEC2); spec.attribute (oname, v2, &(v2iattr->value())); } #ifdef USE_OPENEXR_VERSION2 else if (type == "stringvector" && (svattr = header->findTypedAttribute (name))) { std::vector strvec = svattr->value(); std::vector ustrvec (strvec.size()); for (size_t i = 0, e = strvec.size(); i < e; ++i) ustrvec[i] = strvec[i]; TypeDesc sv (TypeDesc::STRING, ustrvec.size()); spec.attribute(oname, sv, &ustrvec[0]); } #endif else if (type == "box2i" && (b2iattr = header->findTypedAttribute (name))) { TypeDesc bx (TypeDesc::INT, TypeDesc::VEC2, 2); spec.attribute (oname, bx, &b2iattr->value()); } else if (type == "box2f" && (b2fattr = header->findTypedAttribute (name))) { TypeDesc bx (TypeDesc::FLOAT, TypeDesc::VEC2, 2); spec.attribute (oname, bx, &b2fattr->value()); } else if (type == "timecode" && (tattr = header->findTypedAttribute (name))) { unsigned int timecode[2]; timecode[0] = tattr->value().timeAndFlags(Imf::TimeCode::TV60_PACKING); //TV60 returns unchanged _time timecode[1] = tattr->value().userData(); // Elevate "timeCode" to smpte:TimeCode if (oname == "timeCode") oname = "smpte:TimeCode"; spec.attribute(oname, TypeDesc::TypeTimeCode, timecode); } else if (type == "keycode" && (kcattr = header->findTypedAttribute (name))) { const Imf::KeyCode *k = &kcattr->value(); unsigned int keycode[7]; keycode[0] = k->filmMfcCode(); keycode[1] = k->filmType(); keycode[2] = k->prefix(); keycode[3] = k->count(); keycode[4] = k->perfOffset(); keycode[5] = k->perfsPerFrame(); keycode[6] = k->perfsPerCount(); // Elevate "keyCode" to smpte:KeyCode if (oname == "keyCode") oname = "smpte:KeyCode"; spec.attribute(oname, TypeDesc::TypeKeyCode, keycode); } else { #if 0 std::cerr << " unknown attribute " << type << ' ' << name << "\n"; #endif } } #ifdef USE_OPENEXR_VERSION2 // EXR "name" also gets passed along as "oiio:subimagename". if (header->hasName()) spec.attribute ("oiio:subimagename", header->name()); #endif initialized = true; } void OpenEXRInput::PartInfo::query_channels (const Imf::Header *header) { ASSERT (! initialized); spec.nchannels = 0; const Imf::ChannelList &channels (header->channels()); std::vector channelnames; // Order of channels in file std::vector userchannels; // Map file chans to user chans Imf::ChannelList::ConstIterator ci; int c; int red = -1, green = -1, blue = -1, alpha = -1, zee = -1; for (c = 0, ci = channels.begin(); ci != channels.end(); ++c, ++ci) { const char* name = ci.name(); channelnames.push_back (name); if (red < 0 && (Strutil::iequals(name, "R") || Strutil::iequals(name, "Red") || Strutil::iends_with(name,".R") || Strutil::iends_with(name,".Red") || Strutil::iequals(name, "real"))) red = c; if (green < 0 && (Strutil::iequals(name, "G") || Strutil::iequals(name, "Green") || Strutil::iends_with(name,".G") || Strutil::iends_with(name,".Green") || Strutil::iequals(name, "imag"))) green = c; if (blue < 0 && (Strutil::iequals(name, "B") || Strutil::iequals(name, "Blue") || Strutil::iends_with(name,".B") || Strutil::iends_with(name,".Blue"))) blue = c; if (alpha < 0 && (Strutil::iequals(name, "A") || Strutil::iequals(name, "Alpha") || Strutil::iends_with(name,".A") || Strutil::iends_with(name,".Alpha"))) alpha = c; if (zee < 0 && (Strutil::iequals(name, "Z") || Strutil::iequals(name, "Depth") || Strutil::iends_with(name,".Z") || Strutil::iends_with(name,".Depth"))) zee = c; } spec.nchannels = (int)channelnames.size(); userchannels.resize (spec.nchannels); int nc = 0; if (red >= 0) { spec.channelnames.push_back (channelnames[red]); userchannels[red] = nc++; } if (green >= 0) { spec.channelnames.push_back (channelnames[green]); userchannels[green] = nc++; } if (blue >= 0) { spec.channelnames.push_back (channelnames[blue]); userchannels[blue] = nc++; } if (alpha >= 0) { spec.channelnames.push_back (channelnames[alpha]); spec.alpha_channel = nc; userchannels[alpha] = nc++; } if (zee >= 0) { spec.channelnames.push_back (channelnames[zee]); spec.z_channel = nc; userchannels[zee] = nc++; } for (c = 0, ci = channels.begin(); ci != channels.end(); ++c, ++ci) { if (red == c || green == c || blue == c || alpha == c || zee == c) continue; // Already accounted for this channel userchannels[c] = nc; spec.channelnames.push_back (ci.name()); ++nc; } ASSERT ((int)spec.channelnames.size() == spec.nchannels); // FIXME: should we also figure out the layers? // Figure out data types -- choose the highest range spec.format = TypeDesc::UNKNOWN; std::vector chanformat; for (c = 0, ci = channels.begin(); ci != channels.end(); ++c, ++ci) { Imf::PixelType ptype = ci.channel().type; TypeDesc fmt = TypeDesc::HALF; switch (ptype) { case Imf::UINT : fmt = TypeDesc::UINT; if (spec.format == TypeDesc::UNKNOWN) spec.format = TypeDesc::UINT; break; case Imf::HALF : fmt = TypeDesc::HALF; if (spec.format != TypeDesc::FLOAT) spec.format = TypeDesc::HALF; break; case Imf::FLOAT : fmt = TypeDesc::FLOAT; spec.format = TypeDesc::FLOAT; break; default: ASSERT (0); } pixeltype.push_back (ptype); chanbytes.push_back (fmt.size()); if (chanformat.size() == 0) chanformat.resize (spec.nchannels, fmt); for (int i = 0; i < spec.nchannels; ++i) { ASSERT ((int)spec.channelnames.size() > i); if (spec.channelnames[i] == ci.name()) { chanformat[i] = fmt; break; } } } ASSERT (spec.format != TypeDesc::UNKNOWN); bool differing_chanformats = false; for (int c = 1; c < spec.nchannels; ++c) differing_chanformats |= (chanformat[c] != chanformat[0]); if (differing_chanformats) spec.channelformats = chanformat; } bool OpenEXRInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (subimage < 0 || subimage >= m_nsubimages) // out of range return false; if (subimage == m_subimage && miplevel == m_miplevel) { // no change newspec = m_spec; return true; } PartInfo &part (m_parts[subimage]); if (! part.initialized) { const Imf::Header *header = NULL; #ifdef USE_OPENEXR_VERSION2 if (m_input_multipart) header = &(m_input_multipart->header(subimage)); #else if (m_input_tiled) header = &(m_input_tiled->header()); if (m_input_scanline) header = &(m_input_scanline->header()); #endif part.parse_header (header); part.initialized = true; } #ifdef USE_OPENEXR_VERSION2 if (subimage != m_subimage) { delete m_scanline_input_part; m_scanline_input_part = NULL; delete m_tiled_input_part; m_tiled_input_part = NULL; delete m_deep_scanline_input_part; m_deep_scanline_input_part = NULL; delete m_deep_tiled_input_part; m_deep_tiled_input_part = NULL; try { if (part.spec.deep) { if (part.spec.tile_width) m_deep_tiled_input_part = new Imf::DeepTiledInputPart (*m_input_multipart, subimage); else m_deep_scanline_input_part = new Imf::DeepScanLineInputPart (*m_input_multipart, subimage); } else { if (part.spec.tile_width) m_tiled_input_part = new Imf::TiledInputPart (*m_input_multipart, subimage); else m_scanline_input_part = new Imf::InputPart (*m_input_multipart, subimage); } } catch (const std::exception &e) { error ("OpenEXR exception: %s", e.what()); m_scanline_input_part = NULL; m_tiled_input_part = NULL; m_deep_scanline_input_part = NULL; m_deep_tiled_input_part = NULL; ASSERT(0); return false; } } #endif m_subimage = subimage; if (miplevel < 0 || miplevel >= part.nmiplevels) // out of range return false; m_miplevel = miplevel; m_spec = part.spec; if (miplevel == 0 && part.levelmode == Imf::ONE_LEVEL) { newspec = m_spec; return true; } // Compute the resolution of the requested mip level. int w = part.topwidth, h = part.topheight; if (part.levelmode == Imf::MIPMAP_LEVELS) { while (miplevel--) { if (part.roundingmode == Imf::ROUND_DOWN) { w = w / 2; h = h / 2; } else { w = (w + 1) / 2; h = (h + 1) / 2; } w = std::max (1, w); h = std::max (1, h); } } else if (part.levelmode == Imf::RIPMAP_LEVELS) { // FIXME } else { ASSERT(0); } m_spec.width = w; m_spec.height = h; // N.B. OpenEXR doesn't support data and display windows per MIPmap // level. So always take from the top level. Imath::Box2i datawindow = part.top_datawindow; Imath::Box2i displaywindow = part.top_displaywindow; m_spec.x = datawindow.min.x; m_spec.y = datawindow.min.y; if (m_miplevel == 0) { m_spec.full_x = displaywindow.min.x; m_spec.full_y = displaywindow.min.y; m_spec.full_width = displaywindow.max.x - displaywindow.min.x + 1; m_spec.full_height = displaywindow.max.y - displaywindow.min.y + 1; } else { m_spec.full_x = m_spec.x; m_spec.full_y = m_spec.y; m_spec.full_width = m_spec.width; m_spec.full_height = m_spec.height; } if (part.cubeface) { m_spec.full_width = w; m_spec.full_height = w; } newspec = m_spec; return true; } bool OpenEXRInput::close () { delete m_input_multipart; delete m_scanline_input_part; delete m_tiled_input_part; delete m_deep_scanline_input_part; delete m_deep_tiled_input_part; delete m_input_scanline; delete m_input_tiled; delete m_input_stream; init (); // Reset to initial state return true; } bool OpenEXRInput::read_native_scanline (int y, int z, void *data) { return read_native_scanlines (y, y+1, z, 0, m_spec.nchannels, data); } bool OpenEXRInput::read_native_scanlines (int ybegin, int yend, int z, void *data) { return read_native_scanlines (ybegin, yend, z, 0, m_spec.nchannels, data); } bool OpenEXRInput::read_native_scanlines (int ybegin, int yend, int z, int chbegin, int chend, void *data) { chend = clamp (chend, chbegin+1, m_spec.nchannels); // std::cerr << "openexr rns " << ybegin << ' ' << yend << ", channels " // << chbegin << "-" << (chend-1) << "\n"; if (m_input_scanline == NULL && m_scanline_input_part == NULL) { error ("called OpenEXRInput::read_native_scanlines without an open file"); return false; } // Compute where OpenEXR needs to think the full buffers starts. // OpenImageIO requires that 'data' points to where the client wants // to put the pixels being read, but OpenEXR's frameBuffer.insert() // wants where the address of the "virtual framebuffer" for the // whole image. const PartInfo &part (m_parts[m_subimage]); size_t pixelbytes = m_spec.pixel_bytes (chbegin, chend, true); size_t scanlinebytes = (size_t)m_spec.width * pixelbytes; char *buf = (char *)data - m_spec.x * pixelbytes - ybegin * scanlinebytes; try { Imf::FrameBuffer frameBuffer; size_t chanoffset = 0; for (int c = chbegin; c < chend; ++c) { size_t chanbytes = m_spec.channelformat(c).size(); frameBuffer.insert (m_spec.channelnames[c].c_str(), Imf::Slice (part.pixeltype[c], buf + chanoffset, pixelbytes, scanlinebytes)); chanoffset += chanbytes; } if (m_input_scanline) { m_input_scanline->setFrameBuffer (frameBuffer); m_input_scanline->readPixels (ybegin, yend-1); #ifdef USE_OPENEXR_VERSION2 } else if (m_scanline_input_part) { m_scanline_input_part->setFrameBuffer (frameBuffer); m_scanline_input_part->readPixels (ybegin, yend-1); #endif } else { ASSERT (0); } } catch (const std::exception &e) { error ("Failed OpenEXR read: %s", e.what()); return false; } return true; } bool OpenEXRInput::read_native_tile (int x, int y, int z, void *data) { return read_native_tiles (x, x+m_spec.tile_width, y, y+m_spec.tile_height, z, z+m_spec.tile_depth, 0, m_spec.nchannels, data); } bool OpenEXRInput::read_native_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, void *data) { return read_native_tiles (xbegin, xend, ybegin, yend, zbegin, zend, 0, m_spec.nchannels, data); } bool OpenEXRInput::read_native_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, void *data) { chend = clamp (chend, chbegin+1, m_spec.nchannels); #if 0 std::cerr << "openexr rnt " << xbegin << ' ' << xend << ' ' << ybegin << ' ' << yend << ", chans " << chbegin << "-" << (chend-1) << "\n"; #endif if (! (m_input_tiled || m_tiled_input_part) || ! m_spec.valid_tile_range (xbegin, xend, ybegin, yend, zbegin, zend)) { error ("called OpenEXRInput::read_native_tiles without an open file"); return false; } // Compute where OpenEXR needs to think the full buffers starts. // OpenImageIO requires that 'data' points to where the client wants // to put the pixels being read, but OpenEXR's frameBuffer.insert() // wants where the address of the "virtual framebuffer" for the // whole image. const PartInfo &part (m_parts[m_subimage]); size_t pixelbytes = m_spec.pixel_bytes (chbegin, chend, true); int firstxtile = (xbegin-m_spec.x) / m_spec.tile_width; int firstytile = (ybegin-m_spec.y) / m_spec.tile_height; // clamp to the image edge xend = std::min (xend, m_spec.x+m_spec.width); yend = std::min (yend, m_spec.y+m_spec.height); zend = std::min (zend, m_spec.z+m_spec.depth); // figure out how many tiles we need int nxtiles = (xend - xbegin + m_spec.tile_width - 1) / m_spec.tile_width; int nytiles = (yend - ybegin + m_spec.tile_height - 1) / m_spec.tile_height; int whole_width = nxtiles * m_spec.tile_width; int whole_height = nytiles * m_spec.tile_height; boost::scoped_array tmpbuf; void *origdata = data; if (whole_width != (xend-xbegin) || whole_height != (yend-ybegin)) { // Deal with the case of reading not a whole number of tiles -- // OpenEXR will happily overwrite user memory in this case. tmpbuf.reset (new char [nxtiles * nytiles * m_spec.tile_bytes(true)]); data = &tmpbuf[0]; } char *buf = (char *)data - xbegin * pixelbytes - ybegin * pixelbytes * m_spec.tile_width * nxtiles; try { Imf::FrameBuffer frameBuffer; size_t chanoffset = 0; for (int c = chbegin; c < chend; ++c) { size_t chanbytes = m_spec.channelformat(c).size(); frameBuffer.insert (m_spec.channelnames[c].c_str(), Imf::Slice (part.pixeltype[c], buf + chanoffset, pixelbytes, pixelbytes*m_spec.tile_width*nxtiles)); chanoffset += chanbytes; } if (m_input_tiled) { m_input_tiled->setFrameBuffer (frameBuffer); m_input_tiled->readTiles (firstxtile, firstxtile+nxtiles-1, firstytile, firstytile+nytiles-1, m_miplevel, m_miplevel); #ifdef USE_OPENEXR_VERSION2 } else if (m_tiled_input_part) { m_tiled_input_part->setFrameBuffer (frameBuffer); m_tiled_input_part->readTiles (firstxtile, firstxtile+nxtiles-1, firstytile, firstytile+nytiles-1, m_miplevel, m_miplevel); #endif } else { ASSERT (0); } if (data != origdata) { stride_t user_scanline_bytes = (xend-xbegin) * pixelbytes; stride_t scanline_stride = nxtiles*m_spec.tile_width*pixelbytes; for (int y = ybegin; y < yend; ++y) memcpy ((char *)origdata+(y-ybegin)*scanline_stride, (char *)data+(y-ybegin)*scanline_stride, user_scanline_bytes); } } catch (const std::exception &e) { error ("Failed OpenEXR read: %s", e.what()); return false; } return true; } bool OpenEXRInput::read_native_deep_scanlines (int ybegin, int yend, int z, int chbegin, int chend, DeepData &deepdata) { if (m_deep_scanline_input_part == NULL) { error ("called OpenEXRInput::read_native_deep_scanlines without an open file"); return false; } #ifdef USE_OPENEXR_VERSION2 try { const PartInfo &part (m_parts[m_subimage]); size_t npixels = (yend - ybegin) * m_spec.width; chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; // Set up the count and pointers arrays and the Imf framebuffer std::vector channeltypes; m_spec.get_channelformats (channeltypes); deepdata.init (npixels, nchans, &channeltypes[chbegin], &channeltypes[chend]); Imf::DeepFrameBuffer frameBuffer; Imf::Slice countslice (Imf::UINT, (char *)(&deepdata.nsamples[0] - m_spec.x - ybegin*m_spec.width), sizeof(unsigned int), sizeof(unsigned int) * m_spec.width); frameBuffer.insertSampleCountSlice (countslice); for (int c = chbegin; c < chend; ++c) { Imf::DeepSlice slice (part.pixeltype[c], (char *)(&deepdata.pointers[c-chbegin] - m_spec.x * nchans - ybegin*m_spec.width*nchans), sizeof(void*) * nchans, // xstride of pointer array sizeof(void*) * nchans*m_spec.width, // ystride of pointer array part.chanbytes[c]); // stride of data sample frameBuffer.insert (m_spec.channelnames[c].c_str(), slice); } m_deep_scanline_input_part->setFrameBuffer (frameBuffer); // Get the sample counts for each pixel and compute the total // number of samples and resize the data area appropriately. m_deep_scanline_input_part->readPixelSampleCounts (ybegin, yend-1); deepdata.alloc (); // Read the pixels m_deep_scanline_input_part->readPixels (ybegin, yend-1); } catch (const std::exception &e) { error ("Failed OpenEXR read: %s", e.what()); return false; } return true; #else return false; #endif } bool OpenEXRInput::read_native_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, DeepData &deepdata) { if (m_deep_tiled_input_part == NULL) { error ("called OpenEXRInput::read_native_deep_tiles without an open file"); return false; } #ifdef USE_OPENEXR_VERSION2 try { const PartInfo &part (m_parts[m_subimage]); size_t width = (xend - xbegin); size_t npixels = width * (yend - ybegin) * (zend - zbegin); chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; // Set up the count and pointers arrays and the Imf framebuffer std::vector channeltypes; m_spec.get_channelformats (channeltypes); deepdata.init (npixels, nchans, &channeltypes[chbegin], &channeltypes[chend]); Imf::DeepFrameBuffer frameBuffer; Imf::Slice countslice (Imf::UINT, (char *)(&deepdata.nsamples[0] - xbegin - ybegin*width), sizeof(unsigned int), sizeof(unsigned int) * width); frameBuffer.insertSampleCountSlice (countslice); for (int c = chbegin; c < chend; ++c) { Imf::DeepSlice slice (part.pixeltype[c], (char *)(&deepdata.pointers[c-chbegin] - xbegin*nchans - ybegin*width*nchans), sizeof(void*) * nchans, // xstride of pointer array sizeof(void*) * nchans*width, // ystride of pointer array part.chanbytes[c]); // stride of data sample frameBuffer.insert (m_spec.channelnames[c].c_str(), slice); } m_deep_tiled_input_part->setFrameBuffer (frameBuffer); int xtiles = round_to_multiple (xend-xbegin, m_spec.tile_width) / m_spec.tile_width; int ytiles = round_to_multiple (yend-ybegin, m_spec.tile_height) / m_spec.tile_height; // Get the sample counts for each pixel and compute the total // number of samples and resize the data area appropriately. m_deep_tiled_input_part->readPixelSampleCounts (0, xtiles-1, 0, ytiles-1); deepdata.alloc (); // Read the pixels m_deep_tiled_input_part->readTiles (0, xtiles-1, 0, ytiles-1, m_miplevel, m_miplevel); } catch (const std::exception &e) { error ("Failed OpenEXR read: %s", e.what()); return false; } return true; #else return false; #endif } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/openexr.imageio/CMakeLists.txt0000644000175000017500000000031512271062644022740 0ustar mfvmfv# FIXME to use OPENEXR_FOUND, OPENEXR_INCLUDE_DIR, OPENEXR_LIBRARIES when # these are defined. add_oiio_plugin (exrinput.cpp exroutput.cpp) link_ilmbase (openexr.imageio) link_openexr (openexr.imageio) openimageio-1.3.12~dfsg0.orig/src/socket.imageio/0000755000175000017500000000000012271062644020011 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/socket.imageio/socketinput.cpp0000644000175000017500000001242312271062644023067 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "imageio.h" #include "socket_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN // Export version number and create function symbols OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT int socket_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT ImageInput *socket_input_imageio_create () { return new SocketInput; } OIIO_EXPORT const char *socket_input_extensions[] = { "socket", NULL }; OIIO_PLUGIN_EXPORTS_END SocketInput::SocketInput() : socket (io) { } bool SocketInput::valid_file (const std::string &filename) const { // Pass it a configuration request that includes a "nowait" option // so that it returns immediately rather than waiting for a socket // connection that doesn't yet exist. ImageSpec config; config.attribute ("nowait", (int)1); ImageSpec tmpspec; bool ok = const_cast(this)->open (filename, tmpspec, config); if (ok) const_cast(this)->close (); return ok; } bool SocketInput::open (const std::string &name, ImageSpec &newspec) { return open (name, newspec, ImageSpec()); } bool SocketInput::open (const std::string &name, ImageSpec &newspec, const ImageSpec &config) { // If there is a nonzero "nowait" request in the configuration, just // return immediately. if (config.get_int_attribute ("nowait", 0)) { return false; } if (! (accept_connection (name) && get_spec_from_client (newspec))) { return false; } // Also send information about endianess etc. m_spec = newspec; return true; } bool SocketInput::read_native_scanline (int y, int z, void *data) { try { boost::asio::read (socket, buffer (reinterpret_cast (data), m_spec.scanline_bytes ())); } catch (boost::system::system_error &err) { error ("Error while reading: %s", err.what ()); return false; } return true; } bool SocketInput::read_native_tile (int x, int y, int z, void *data) { try { boost::asio::read (socket, buffer (reinterpret_cast (data), m_spec.tile_bytes ())); } catch (boost::system::system_error &err) { error ("Error while reading: %s", err.what ()); return false; } return true; } bool SocketInput::close () { socket.close(); return true; } bool SocketInput::accept_connection(const std::string &name) { std::map rest_args; std::string baseurl; rest_args["port"] = socket_pvt::default_port; rest_args["host"] = socket_pvt::default_host; if (! Strutil::get_rest_arguments (name, baseurl, rest_args)) { error ("Invalid 'open ()' argument: %s", name.c_str ()); return false; } int port = atoi (rest_args["port"].c_str ()); try { acceptor = boost::shared_ptr (new ip::tcp::acceptor (io, ip::tcp::endpoint (ip::tcp::v4(), port))); acceptor->accept (socket); } catch (boost::system::system_error &err) { error ("Error while accepting: %s", err.what ()); return false; } return true; } bool SocketInput::get_spec_from_client (ImageSpec &spec) { try { int spec_length; boost::asio::read (socket, buffer (reinterpret_cast (&spec_length), sizeof (boost::uint32_t))); char *spec_xml = new char[spec_length + 1]; boost::asio::read (socket, buffer (spec_xml, spec_length)); spec.from_xml (spec_xml); delete [] spec_xml; } catch (boost::system::system_error &err) { error ("Error while reading: %s", err.what ()); return false; } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/socket.imageio/socket_pvt.cpp0000644000175000017500000000444212271062644022702 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////////// // Private definitions internal to the socket.imageio plugin ///////////////////////////////////////////////////////////////////////////// #include #include #include #include "socket_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace boost; using namespace boost::asio; namespace socket_pvt { std::size_t socket_write (ip::tcp::socket &s, TypeDesc &type, const void *data, int size) { std::size_t bytes; // TODO: Translate data to correct endianesss. bytes = write (s, buffer (reinterpret_cast (data), size)); return bytes; } } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/socket.imageio/socketoutput.cpp0000644000175000017500000001230412271062644023266 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include "imageio.h" #include "socket_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *socket_output_imageio_create () { return new SocketOutput; } OIIO_EXPORT const char *socket_output_extensions[] = { "socket", NULL }; OIIO_PLUGIN_EXPORTS_END SocketOutput::SocketOutput() : socket (io) { } bool SocketOutput::open (const std::string &name, const ImageSpec &newspec, OpenMode mode) { if (! (connect_to_server (name) && send_spec_to_server (newspec))) { return false; } m_next_scanline = 0; m_spec = newspec; if (m_spec.format == TypeDesc::UNKNOWN) m_spec.set_format (TypeDesc::UINT8); // Default to 8 bit channels return true; } bool SocketOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { data = to_native_scanline (format, data, xstride, m_scratch); try { socket_pvt::socket_write (socket, format, data, m_spec.scanline_bytes ()); } catch (boost::system::system_error &err) { error ("Error while reading: %s", err.what ()); return false; } ++m_next_scanline; return true; } bool SocketOutput::write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride) { data = to_native_tile (format, data, xstride, ystride, zstride, m_scratch); try { socket_pvt::socket_write (socket, format, data, m_spec.tile_bytes ()); } catch (boost::system::system_error &err) { error ("Error while reading: %s", err.what ()); return false; } return true; } bool SocketOutput::close () { socket.close(); return true; } bool SocketOutput::copy_image (ImageInput *in) { return true; } bool SocketOutput::send_spec_to_server(const ImageSpec& spec) { std::string spec_xml = spec.to_xml(); int xml_length = spec_xml.length (); try { boost::asio::write (socket, buffer (reinterpret_cast (&xml_length), sizeof (boost::uint32_t))); boost::asio::write (socket, buffer (spec_xml.c_str (), spec_xml.length ())); } catch (boost::system::system_error &err) { error ("Error while writing: %s", err.what ()); return false; } return true; } bool SocketOutput::connect_to_server (const std::string &name) { std::map rest_args; std::string baseurl; rest_args["port"] = socket_pvt::default_port; rest_args["host"] = socket_pvt::default_host; if (! Strutil::get_rest_arguments (name, baseurl, rest_args)) { error ("Invalid 'open ()' argument: %s", name.c_str ()); return false; } try { ip::tcp::resolver resolver (io); ip::tcp::resolver::query query (rest_args["host"].c_str (), rest_args["port"].c_str ()); ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve (query); ip::tcp::resolver::iterator end; boost::system::error_code err = error::host_not_found; while (err && endpoint_iterator != end) { socket.close (); socket.connect (*endpoint_iterator++, err); } if (err) { error ("Host \"%s\" not found", rest_args["host"].c_str ()); return false; } } catch (boost::system::system_error &err) { error ("Error while connecting: %s", err.what ()); return false; } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/socket.imageio/CMakeLists.txt0000644000175000017500000000026512271062644022554 0ustar mfvmfvif (NOT Boost_VERSION LESS "103500") # Boost < 1.35 is too old to support asio that socket needs add_oiio_plugin (socketinput.cpp socketoutput.cpp socket_pvt.cpp) endif () openimageio-1.3.12~dfsg0.orig/src/socket.imageio/socket_pvt.h0000644000175000017500000001115312271062644022344 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////////// // Private definitions internal to the socket.imageio plugin ///////////////////////////////////////////////////////////////////////////// #ifndef OPENIMAGEIO_SOCKET_PVT_H #define OPENIMAGEIO_SOCKET_PVT_H #include "imageio.h" #include // The boost::asio library uses functionality only available since Windows XP, // thus _WIN32_WINNT must be set to _WIN32_WINNT_WINXP (0x0501) or greater. // If _WIN32_WINNT is not defined before including the asio headers, they issue // a message warning that _WIN32_WINNT was explicitly set to _WIN32_WINNT_WINXP. #if defined(_WIN32) && !defined(_WIN32_WINNT) # define _WIN32_WINNT 0x0501 #endif #include #include OIIO_PLUGIN_NAMESPACE_BEGIN using namespace boost::asio; class SocketOutput : public ImageOutput { public: SocketOutput (); virtual ~SocketOutput () { close(); } virtual const char * format_name (void) const { return "socket"; } virtual bool supports (const std::string &property) const { return false; } virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); virtual bool write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride); virtual bool close (); virtual bool copy_image (ImageInput *in); private: int m_next_scanline; // Which scanline is the next to write? io_service io; ip::tcp::socket socket; std::vector m_scratch; bool connect_to_server (const std::string &name); bool send_spec_to_server (const ImageSpec &spec); }; class SocketInput : public ImageInput { public: SocketInput (); virtual ~SocketInput () { close(); } virtual const char * format_name (void) const { return "socket"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &spec); virtual bool open (const std::string &name, ImageSpec &spec, const ImageSpec &config); virtual bool read_native_scanline (int y, int z, void *data); virtual bool read_native_tile (int x, int y, int z, void *data); virtual bool close (); private: int m_next_scanline; // Which scanline is the next to read? io_service io; ip::tcp::socket socket; boost::shared_ptr acceptor; bool accept_connection (const std::string &name); bool get_spec_from_client (ImageSpec &spec); friend class SocketOutput; }; namespace socket_pvt { const char default_port[] = "10110"; const char default_host[] = "127.0.0.1"; std::size_t socket_write (ip::tcp::socket &s, TypeDesc &type, const void *data, int size); } OIIO_PLUGIN_NAMESPACE_END #endif /* OPENIMAGEIO_SOCKET_PVT_H */ openimageio-1.3.12~dfsg0.orig/src/libutil/0000755000175000017500000000000012271062644016554 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/libutil/plugin.cpp0000644000175000017500000000735512271062644020570 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #ifdef _WIN32 # include "osdep.h" #else # include #endif #include "thread.h" #include "plugin.h" OIIO_NAMESPACE_ENTER { using namespace Plugin; namespace { static mutex plugin_mutex; static std::string last_error; } const char * Plugin::plugin_extension (void) { #if defined(_WIN32) return "dll"; #elif defined(__APPLE__) return "dylib"; #else return "so"; #endif } #if defined(_WIN32) // Dummy values #define RTLD_LAZY 0 #define RTLD_GLOBAL 0 Handle dlopen (const char *plugin_filename, int) { return LoadLibrary (plugin_filename); } bool dlclose (Handle plugin_handle) { return FreeLibrary ((HMODULE)plugin_handle) != 0; } void * dlsym (Handle plugin_handle, const char *symbol_name) { return GetProcAddress ((HMODULE)plugin_handle, symbol_name); } std::string dlerror () { LPVOID lpMsgBuf; std::string win32Error; if (FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &lpMsgBuf, 0, NULL)) win32Error = (LPSTR)lpMsgBuf; LocalFree(lpMsgBuf); return win32Error; } #endif Handle Plugin::open (const char *plugin_filename, bool global) { lock_guard guard (plugin_mutex); last_error.clear (); int mode = RTLD_LAZY; if (global) mode |= RTLD_GLOBAL; Handle h = dlopen (plugin_filename, mode); if (!h) last_error = dlerror(); return h; } bool Plugin::close (Handle plugin_handle) { lock_guard guard (plugin_mutex); last_error.clear (); if (dlclose (plugin_handle)) { last_error = dlerror(); return false; } return true; } void * Plugin::getsym (Handle plugin_handle, const char *symbol_name) { lock_guard guard (plugin_mutex); last_error.clear (); void *s = dlsym (plugin_handle, symbol_name); if (!s) last_error = dlerror(); return s; } std::string Plugin::geterror (void) { lock_guard guard (plugin_mutex); std::string e = last_error; last_error.clear (); return e; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/pystring.cpp0000644000175000017500000006747212271062644021157 0ustar mfvmfv/////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2008, Sony Pictures Imageworks // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // Neither the name of the organization Sony Pictures Imageworks nor the // names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "pystring.h" OIIO_NAMESPACE_ENTER { namespace pystring { namespace { ////////////////////////////////////////////////////////////////////////////////////////////// /// why doesn't the std::reverse work? /// void reverse_strings( std::vector< std::string > & result) { for (std::vector< std::string >::size_type i = 0; i < result.size() / 2; i++ ) { std::swap(result[i], result[result.size() - 1 - i]); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void split_whitespace( const std::string & str, std::vector< std::string > & result, int maxsplit ) { std::string::size_type i, j, len = str.size(); for (i = j = 0; i < len; ) { while ( i < len && ::isspace( str[i] ) ) i++; j = i; while ( i < len && ! ::isspace( str[i]) ) i++; if (j < i) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( j, i - j )); while ( i < len && ::isspace( str[i])) i++; j = i; } } if (j < len) { result.push_back( str.substr( j, len - j )); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void rsplit_whitespace( const std::string & str, std::vector< std::string > & result, int maxsplit ) { std::string::size_type len = str.size(); std::string::size_type i, j; for (i = j = len; i > 0; ) { while ( i > 0 && ::isspace( str[i - 1] ) ) i--; j = i; while ( i > 0 && ! ::isspace( str[i - 1]) ) i--; if (j > i) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( i, j - i )); while ( i > 0 && ::isspace( str[i - 1])) i--; j = i; } } if (j > 0) { result.push_back( str.substr( 0, j )); } //std::reverse( result, result.begin(), result.end() ); reverse_strings( result ); } } //anonymous namespace ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void split( const std::string & str, std::vector< std::string > & result, const std::string & sep, int maxsplit ) { result.clear(); if ( maxsplit < 0 ) maxsplit = MAX_32BIT_INT;//result.max_size(); if ( sep.size() == 0 ) { split_whitespace( str, result, maxsplit ); return; } std::string::size_type i,j, len = str.size(), n = sep.size(); i = j = 0; while ( i+n <= len ) { if ( str[i] == sep[0] && str.substr( i, n ) == sep ) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( j, i - j ) ); i = j = i + n; } else { i++; } } result.push_back( str.substr( j, len-j ) ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void rsplit( const std::string & str, std::vector< std::string > & result, const std::string & sep, int maxsplit ) { if ( maxsplit < 0 ) { split( str, result, sep, 0 ); return; } result.clear(); if ( sep.size() == 0 ) { rsplit_whitespace( str, result, maxsplit ); return; } std::string::size_type i,j, len = str.size(), n = sep.size(); i = j = len; while ( i > n ) { if ( str[i - 1] == sep[n - 1] && str.substr( i - n, n ) == sep ) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( i, j - i ) ); i = j = i - n; } else { i--; } } result.push_back( str.substr( 0, j ) ); reverse_strings( result ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// #define LEFTSTRIP 0 #define RIGHTSTRIP 1 #define BOTHSTRIP 2 ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool __substrcmp( const std::string & str, const std::string & str2, std::string::size_type pos ) { std::string::size_type len = str.size(), len2 = str2.size(); if ( pos + len2 > len ) { return false; } for ( std::string::size_type i = 0; i < len2; ++i ) { if ( str[pos + i] != str2[i] ) { return false; } } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string do_strip( const std::string & str, int striptype, const std::string & chars ) { std::string::size_type len = str.size(), i, j, charslen = chars.size(); if ( charslen == 0 ) { i = 0; if ( striptype != RIGHTSTRIP ) { while ( i < len && ::isspace( str[i] ) ) { i++; } } j = len; if ( striptype != LEFTSTRIP ) { do { j--; } while (j >= i && ::isspace(str[j])); j++; } } else { const char * sep = chars.c_str(); i = 0; if ( striptype != RIGHTSTRIP ) { while ( i < len && memchr(sep, str[i], charslen) ) { i++; } } j = len; if (striptype != LEFTSTRIP) { do { j--; } while (j >= i && memchr(sep, str[j], charslen) ); j++; } } if ( i == 0 && j == len ) { return str; } else { return str.substr( i, j - i ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void partition( const std::string & str, const std::string & sep, std::vector< std::string > & result ) { result.resize(3); int index = find( str, sep ); if ( index < 0 ) { result[0] = str; result[1] = ""; result[2] = ""; } else { result[0] = str.substr( 0, index ); result[1] = sep; result[2] = str.substr( index + sep.size(), str.size() ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void rpartition( const std::string & str, const std::string & sep, std::vector< std::string > & result ) { result.resize(3); int index = rfind( str, sep ); if ( index < 0 ) { result[0] = ""; result[1] = ""; result[2] = str; } else { result[0] = str.substr( 0, index ); result[1] = sep; result[2] = str.substr( index + sep.size(), str.size() ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string strip( const std::string & str, const std::string & chars ) { return do_strip( str, BOTHSTRIP, chars ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string lstrip( const std::string & str, const std::string & chars ) { return do_strip( str, LEFTSTRIP, chars ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string rstrip( const std::string & str, const std::string & chars ) { return do_strip( str, RIGHTSTRIP, chars ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string join( const std::string & str, const std::vector< std::string > & seq ) { std::vector< std::string >::size_type seqlen = seq.size(), i; if ( seqlen == 0 ) return ""; if ( seqlen == 1 ) return seq[0]; std::string result( seq[0] ); for ( i = 1; i < seqlen; ++i ) { result += str + seq[i]; } return result; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int __adjustslicepos( std::string::size_type len, int pos ) { int intlen = len, value; if ( pos < 0 ) { value = intlen + pos; } else { value = pos; } if ( value < 0 ) { value = 0; } else if ( value > ( int ) len ) { value = len; } return value; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool startswith( const std::string & str, const std::string & prefix, int start, int end ) { std::string::size_type startp, endp; startp = __adjustslicepos( str.size(), start ); endp = __adjustslicepos( str.size(), end ); if ( start > (int) str.size() ) return false; if ( endp - startp < prefix.size() ) return false; return __substrcmp( str, prefix, startp ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool endswith( const std::string & str, const std::string & suffix, int start, int end ) { std::string::size_type startp, endp; startp = __adjustslicepos( str.size(), start ); endp = __adjustslicepos( str.size(), end ); int upper = endp; int lower = ( upper - suffix.size() ) > startp ? ( upper - suffix.size() ) : startp; if ( start > (int) str.size() ) return false; if ( upper - lower < ( int ) suffix.size() ) { return false; } return __substrcmp(str, suffix, lower ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isalnum( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isalnum( str[0] ); } for ( i = 0; i < len; ++i ) { if ( !::isalnum( str[i] ) ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isalpha( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) return ::isalpha( (int) str[0] ); for ( i = 0; i < len; ++i ) { if ( !::isalpha( (int) str[i] ) ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isdigit( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) return ::isdigit( str[0] ); for ( i = 0; i < len; ++i ) { if ( ! ::isdigit( str[i] ) ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool islower( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) return ::islower( str[0] ); for ( i = 0; i < len; ++i ) { if ( !::islower( str[i] ) ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isspace( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) return ::isspace( str[0] ); for ( i = 0; i < len; ++i ) { if ( !::isspace( str[i] ) ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool istitle( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if ( len == 1 ) return ::isupper( str[0] ); bool cased = false, previous_is_cased = false; for ( i = 0; i < len; ++i ) { if ( ::isupper( str[i] ) ) { if ( previous_is_cased ) { return false; } previous_is_cased = true; cased = true; } else if ( ::islower( str[i] ) ) { if (!previous_is_cased) { return false; } previous_is_cased = true; cased = true; } else { previous_is_cased = false; } } return cased; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isupper( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) return ::isupper( str[0] ); for ( i = 0; i < len; ++i ) { if ( !::isupper( str[i] ) ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string capitalize( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; if ( len > 0) { if (::islower(s[0])) s[0] = ::toupper( s[0] ); } for ( i = 1; i < len; ++i ) { if (::isupper(s[i])) s[i] = ::tolower( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string lower( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; for ( i = 0; i < len; ++i ) { if ( ::isupper( s[i] ) ) s[i] = ::tolower( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string upper( const std::string & str ) { std::string s( str ) ; std::string::size_type len = s.size(), i; for ( i = 0; i < len; ++i ) { if ( ::islower( s[i] ) ) s[i] = ::toupper( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string swapcase( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; for ( i = 0; i < len; ++i ) { if ( ::islower( s[i] ) ) s[i] = ::toupper( s[i] ); else if (::isupper( s[i] ) ) s[i] = ::tolower( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string title( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; bool previous_is_cased = false; for ( i = 0; i < len; ++i ) { int c = s[i]; if ( ::islower(c) ) { if ( !previous_is_cased ) { s[i] = ::toupper(c); } previous_is_cased = true; } else if ( ::isupper(c) ) { if ( previous_is_cased ) { s[i] = ::tolower(c); } previous_is_cased = true; } else { previous_is_cased = false; } } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string translate( const std::string & str, const std::string & table, const std::string & deletechars ) { std::string s; std::string::size_type len = str.size(), dellen = deletechars.size(); if ( table.size() != 256 ) { //raise exception instead return str; } //if nothing is deleted, use faster code if ( dellen == 0 ) { s = str; for ( std::string::size_type i = 0; i < len; ++i ) { s[i] = table[ s[i] ]; } return s; } int trans_table[256]; for ( int i = 0; i < 256; i++) { trans_table[i] = table[i]; } for ( std::string::size_type i = 0; i < dellen; i++) { trans_table[(int) deletechars[i] ] = -1; } for ( std::string::size_type i = 0; i < len; ++i ) { if ( trans_table[ (int) str[i] ] != -1 ) { s += table[ s[i] ]; } } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string zfill( const std::string & str, int width ) { std::string::size_type len = str.size(); if ( ( int ) len >= width ) { return str; } std::string s( str ); int fill = width - len; s = std::string( fill, '0' ) + s; if ( s[fill] == '+' || s[fill] == '-' ) { s[0] = s[fill]; s[fill] = '0'; } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string ljust( const std::string & str, int width ) { std::string::size_type len = str.size(); if ( (( int ) len ) >= width ) return str; return str + std::string( width - len, ' ' ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string rjust( const std::string & str, int width ) { std::string::size_type len = str.size(); if ( (( int ) len ) >= width ) return str; return std::string( width - len, ' ' ) + str; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string center( const std::string & str, int width ) { std::string::size_type len = str.size(); int marg, left; if ( (( int ) len ) >= width ) return str; marg = width - len; left = marg / 2 + (marg & width & 1); return std::string( left, ' ' ) + str + std::string( marg - left, ' ' ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int find( const std::string & str, const std::string & sub, int start, int end ) { std::string::size_type startp, endp; startp = __adjustslicepos( str.size(), start ); endp = __adjustslicepos( str.size(), end ); std::string::size_type result; result = str.find( sub, startp ); if( result == std::string::npos || result >= endp) { return -1; } return result; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int index( const std::string & str, const std::string & sub, int start, int end ) { return find( str, sub, start, end ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int rfind( const std::string & str, const std::string & sub, int start, int end ) { std::string::size_type startp, endp; startp = __adjustslicepos( str.size(), start ); endp = __adjustslicepos( str.size(), end ); std::string::size_type result; result = str.rfind( sub, endp ); if( result == std::string::npos || result < startp ) return -1; return result; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int rindex( const std::string & str, const std::string & sub, int start, int end ) { return rfind( str, sub, start, end ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string expandtabs( const std::string & str, int tabsize ) { std::string s( str ); std::string::size_type len = str.size(), i = 0; int offset = 0; int j = 0; for ( i = 0; i < len; ++i ) { if ( str[i] == '\t' ) { if ( tabsize > 0 ) { int fillsize = tabsize - (j % tabsize); j += fillsize; s.replace( i + offset, 1, std::string( fillsize, ' ' )); offset += fillsize - 1; } else { s.replace( i + offset, 1, "" ); offset -= 1; } } else { j++; if (str[i] == '\n' || str[i] == '\r') { j = 0; } } } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int count( const std::string & str, const std::string & substr, int start, int end ) { int nummatches = 0; int cursor = start; while ( 1 ) { cursor = find( str, substr, cursor, end ); if ( cursor < 0 ) break; cursor += substr.size(); nummatches += 1; } return nummatches; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string replace( const std::string & str, const std::string & oldstr, const std::string & newstr, int count ) { int sofar = 0; int cursor = 0; std::string s( str ); std::string::size_type oldlen = oldstr.size(), newlen = newstr.size(); while ( ( cursor = find( s, oldstr, cursor ) ) != -1 ) { if ( count > -1 && sofar >= count ) { break; } s.replace( cursor, oldlen, newstr ); cursor += newlen; ++sofar; } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void splitlines( const std::string & str, std::vector< std::string > & result, bool keepends ) { result.clear(); std::string::size_type len = str.size(), i, j, eol; for (i = j = 0; i < len; ) { while (i < len && str[i] != '\n' && str[i] != '\r') i++; eol = i; if (i < len) { if (str[i] == '\r' && i + 1 < len && str[i+1] == '\n') { i += 2; } else { i++; } if (keepends) eol = i; } result.push_back( str.substr( j, eol - j ) ); j = i; } if (j < len) { result.push_back( str.substr( j, len - j ) ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string slice( const std::string & str, int start, int end ) { std::string::size_type startp, endp; startp = __adjustslicepos( str.size(), start ); endp = __adjustslicepos( str.size(), end ); if ( startp >= endp ) return ""; return str.substr( startp, endp - startp ); } }//namespace pystring } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/hashes.cpp0000644000175000017500000010304212271062644020533 0ustar mfvmfv#include /* defines printf for tests */ #include /* defines time_t for timings in the test */ #if defined(__linux__) || defined(__APPLE__) # include /* attempt to define endianness */ #endif #ifdef __linux__ # include /* attempt to define endianness */ #endif #include "fmath.h" #include "hash.h" OIIO_NAMESPACE_ENTER { namespace xxhash { /* xxHash - Fast Hash algorithm Copyright (C) 2012, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - xxHash source repository : http://code.google.com/p/xxhash/ */ //************************************** // Includes //************************************** //************************************** // Compiler Options //************************************** #ifdef _MSC_VER // Visual Studio #define inline __forceinline // Visual is not C99, but supports some kind of inline #endif // GCC does not support _rotl outside of Windows #if !defined(_WIN32) #define _rotl(x,r) ((x << r) | (x >> (32 - r))) #endif //************************************** // Constants //************************************** #define PRIME1 2654435761U #define PRIME2 2246822519U #define PRIME3 3266489917U #define PRIME4 668265263U #define PRIME5 0x165667b1 //**************************** // Private functions //**************************** // This version is for very small inputs (< 16 bytes) inline unsigned int XXH_small(const void* key, int len, unsigned int seed) { const unsigned char* p = (unsigned char*)key; const unsigned char* const bEnd = p + len; unsigned int idx = seed + PRIME1; unsigned int crc = PRIME5; const unsigned char* const limit = bEnd - 4; while (p> 15; crc *= PRIME2; crc ^= crc >> 13; crc *= PRIME3; crc ^= crc >> 16; return crc; } //****************************** // Hash functions //****************************** unsigned int XXH_fast32(const void* input, int len, unsigned int seed) { // Special case, for small inputs if (len < 16) return XXH_small(input, len, seed); { const unsigned char* p = (const unsigned char*)input; const unsigned char* const bEnd = p + len; unsigned int v1 = seed + PRIME1; unsigned int v2 = v1 * PRIME2 + len; unsigned int v3 = v2 * PRIME3; unsigned int v4 = v3 * PRIME4; const unsigned char* const limit = bEnd - 16; unsigned int crc; while (p> 11; crc += (PRIME4+len) * PRIME1; crc ^= crc >> 15; crc *= PRIME2; crc ^= crc >> 13; return crc; } } unsigned int XXH_strong32(const void* input, int len, unsigned int seed) { // Special case, for small inputs if (len < 16) return XXH_small(input, len, seed); { const unsigned char* p = (const unsigned char*)input; const unsigned char* const bEnd = p + len; unsigned int v1 = seed + PRIME1; unsigned int v2 = v1 * PRIME2 + len; unsigned int v3 = v2 * PRIME3; unsigned int v4 = v3 * PRIME4; const unsigned char* const limit = bEnd - 16; unsigned int crc; while (p> 11; crc += (PRIME4+len) * PRIME1; crc ^= crc >> 15; crc *= PRIME2; crc ^= crc >> 13; return crc; } } } // end namespace xxhash namespace bjhash { /* ------------------------------------------------------------------------------- lookup3.c, by Bob Jenkins, May 2006, Public Domain. These are functions for producing 32-bit hashes for hash table lookup. hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() are externally useful functions. Routines to test the hash are included if SELF_TEST is defined. You can use this free for any purpose. It's in the public domain. It has no warranty. You probably want to use hashlittle(). hashlittle() and hashbig() hash byte arrays. hashlittle() is is faster than hashbig() on little-endian machines. Intel and AMD are little-endian machines. On second thought, you probably want hashlittle2(), which is identical to hashlittle() except it returns two 32-bit hashes for the price of one. You could implement hashbig2() if you wanted but I haven't bothered here. If you want to find a hash of, say, exactly 7 integers, do a = i1; b = i2; c = i3; mix(a,b,c); a += i4; b += i5; c += i6; mix(a,b,c); a += i7; final(a,b,c); then use c as the hash value. If you have a variable length array of 4-byte integers to hash, use hashword(). If you have a byte array (like a character string), use hashlittle(). If you have several byte arrays, or a mix of things, see the comments above hashlittle(). Why is this so big? I read 12 bytes at a time into 3 4-byte integers, then mix those integers. This is fast (you can do a lot more thorough mixing with 12*3 instructions on 3 integers than you can with 3 instructions on 1 byte), but shoehorning those bytes into integers efficiently is messy. ------------------------------------------------------------------------------- */ /* * My best guess at if you are big-endian or little-endian. This may * need adjustment. */ #if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ __BYTE_ORDER == __LITTLE_ENDIAN) || \ (defined(i386) || defined(__i386__) || defined(__i486__) || \ defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) # define HASH_LITTLE_ENDIAN 1 # define HASH_BIG_ENDIAN 0 #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ __BYTE_ORDER == __BIG_ENDIAN) || \ (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) # define HASH_LITTLE_ENDIAN 0 # define HASH_BIG_ENDIAN 1 #else # define HASH_LITTLE_ENDIAN 0 # define HASH_BIG_ENDIAN 0 #endif #define hashsize(n) ((uint32_t)1<<(n)) #define hashmask(n) (hashsize(n)-1) #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) /* ------------------------------------------------------------------------------- mix -- mix 3 32-bit values reversibly. This is reversible, so any information in (a,b,c) before mix() is still in (a,b,c) after mix(). If four pairs of (a,b,c) inputs are run through mix(), or through mix() in reverse, there are at least 32 bits of the output that are sometimes the same for one pair and different for another pair. This was tested for: * pairs that differed by one bit, by two bits, in any combination of top bits of (a,b,c), or in any combination of bottom bits of (a,b,c). * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed the output delta to a Gray code (a^(a>>1)) so a string of 1's (as is commonly produced by subtraction) look like a single 1-bit difference. * the base values were pseudorandom, all zero but one bit set, or all zero plus a counter that starts at zero. Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that satisfy this are 4 6 8 16 19 4 9 15 3 18 27 15 14 9 3 7 17 3 Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing for "differ" defined as + with a one-bit base and a two-bit delta. I used http://burtleburtle.net/bob/hash/avalanche.html to choose the operations, constants, and arrangements of the variables. This does not achieve avalanche. There are input bits of (a,b,c) that fail to affect some output bits of (a,b,c), especially of a. The most thoroughly mixed value is c, but it doesn't really even achieve avalanche in c. This allows some parallelism. Read-after-writes are good at doubling the number of bits affected, so the goal of mixing pulls in the opposite direction as the goal of parallelism. I did what I could. Rotates seem to cost as much as shifts on every machine I could lay my hands on, and rotates are much kinder to the top and bottom bits, so I used rotates. ------------------------------------------------------------------------------- */ #define mix(a,b,c) \ { \ a -= c; a ^= rot(c, 4); c += b; \ b -= a; b ^= rot(a, 6); a += c; \ c -= b; c ^= rot(b, 8); b += a; \ a -= c; a ^= rot(c,16); c += b; \ b -= a; b ^= rot(a,19); a += c; \ c -= b; c ^= rot(b, 4); b += a; \ } /* ------------------------------------------------------------------------------- final -- final mixing of 3 32-bit values (a,b,c) into c Pairs of (a,b,c) values differing in only a few bits will usually produce values of c that look totally different. This was tested for * pairs that differed by one bit, by two bits, in any combination of top bits of (a,b,c), or in any combination of bottom bits of (a,b,c). * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed the output delta to a Gray code (a^(a>>1)) so a string of 1's (as is commonly produced by subtraction) look like a single 1-bit difference. * the base values were pseudorandom, all zero but one bit set, or all zero plus a counter that starts at zero. These constants passed: 14 11 25 16 4 14 24 12 14 25 16 4 14 24 and these came close: 4 8 15 26 3 22 24 10 8 15 26 3 22 24 11 8 15 26 3 22 24 ------------------------------------------------------------------------------- */ #define final(a,b,c) \ { \ c ^= b; c -= rot(b,14); \ a ^= c; a -= rot(c,11); \ b ^= a; b -= rot(a,25); \ c ^= b; c -= rot(b,16); \ a ^= c; a -= rot(c,4); \ b ^= a; b -= rot(a,14); \ c ^= b; c -= rot(b,24); \ } /* -------------------------------------------------------------------- This works on all machines. To be useful, it requires -- that the key be an array of uint32_t's, and -- that the length be the number of uint32_t's in the key The function hashword() is identical to hashlittle() on little-endian machines, and identical to hashbig() on big-endian machines, except that the length has to be measured in uint32_ts rather than in bytes. hashlittle() is more complicated than hashword() only because hashlittle() has to dance around fitting the key bytes into registers. -------------------------------------------------------------------- */ uint32_t hashword( const uint32_t *k, /* the key, an array of uint32_t values */ size_t length, /* the length of the key, in uint32_ts */ uint32_t initval) /* the previous hash, or an arbitrary value */ { uint32_t a,b,c; /* Set up the internal state */ a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; /*------------------------------------------------- handle most of the key */ while (length > 3) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 3; k += 3; } /*------------------------------------------- handle the last 3 uint32_t's */ switch(length) /* all the case statements fall through */ { case 3 : c+=k[2]; case 2 : b+=k[1]; case 1 : a+=k[0]; final(a,b,c); case 0: /* case 0: nothing left to add */ break; } /*------------------------------------------------------ report the result */ return c; } /* -------------------------------------------------------------------- hashword2() -- same as hashword(), but take two seeds and return two 32-bit values. pc and pb must both be nonnull, and *pc and *pb must both be initialized with seeds. If you pass in (*pb)==0, the output (*pc) will be the same as the return value from hashword(). -------------------------------------------------------------------- */ void hashword2 ( const uint32_t *k, /* the key, an array of uint32_t values */ size_t length, /* the length of the key, in uint32_ts */ uint32_t *pc, /* IN: seed OUT: primary hash value */ uint32_t *pb) /* IN: more seed OUT: secondary hash value */ { uint32_t a,b,c; /* Set up the internal state */ a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; c += *pb; /*------------------------------------------------- handle most of the key */ while (length > 3) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 3; k += 3; } /*------------------------------------------- handle the last 3 uint32_t's */ switch(length) /* all the case statements fall through */ { case 3 : c+=k[2]; case 2 : b+=k[1]; case 1 : a+=k[0]; final(a,b,c); case 0: /* case 0: nothing left to add */ break; } /*------------------------------------------------------ report the result */ *pc=c; *pb=b; } /* ------------------------------------------------------------------------------- hashlittle() -- hash a variable-length key into a 32-bit value k : the key (the unaligned variable-length array of bytes) length : the length of the key, counting by bytes initval : can be any 4-byte value Returns a 32-bit value. Every bit of the key affects every bit of the return value. Two keys differing by one or two bits will have totally different hash values. The best hash table sizes are powers of 2. There is no need to do mod a prime (mod is sooo slow!). If you need less than 32 bits, use a bitmask. For example, if you need only 10 bits, do h = (h & hashmask(10)); In which case, the hash table should have hashsize(10) elements. If you are hashing n strings (uint8_t **)k, do it like this: for (i=0, h=0; i 12) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 12; k += 3; } /*----------------------------- handle the last (probably partial) block */ /* * "k[2]&0xffffff" actually reads beyond the end of the string, but * then masks off the part it's not allowed to read. Because the * string is aligned, the masked-off tail is in the same word as the * rest of the string. Every machine with memory protection I've seen * does it on word boundaries, so is OK with this. But VALGRIND will * still catch it and complain. The masking trick does make the hash * noticably faster for short strings (like English words). */ #ifndef VALGRIND switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=k[1]&0xffffff; a+=k[0]; break; case 6 : b+=k[1]&0xffff; a+=k[0]; break; case 5 : b+=k[1]&0xff; a+=k[0]; break; case 4 : a+=k[0]; break; case 3 : a+=k[0]&0xffffff; break; case 2 : a+=k[0]&0xffff; break; case 1 : a+=k[0]&0xff; break; case 0 : return c; /* zero length strings require no mixing */ } #else /* make valgrind happy */ const uint8_t *k8; k8 = (const uint8_t *)k; switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ case 9 : c+=k8[8]; /* fall through */ case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ case 5 : b+=k8[4]; /* fall through */ case 4 : a+=k[0]; break; case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ case 1 : a+=k8[0]; break; case 0 : return c; } #endif /* !valgrind */ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ const uint8_t *k8; /*--------------- all but last block: aligned reads and different mixing */ while (length > 12) { a += k[0] + (((uint32_t)k[1])<<16); b += k[2] + (((uint32_t)k[3])<<16); c += k[4] + (((uint32_t)k[5])<<16); mix(a,b,c); length -= 12; k += 6; } /*----------------------------- handle the last (probably partial) block */ k8 = (const uint8_t *)k; switch(length) { case 12: c+=k[4]+(((uint32_t)k[5])<<16); b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ case 10: c+=k[4]; b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 9 : c+=k8[8]; /* fall through */ case 8 : b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ case 6 : b+=k[2]; a+=k[0]+(((uint32_t)k[1])<<16); break; case 5 : b+=k8[4]; /* fall through */ case 4 : a+=k[0]+(((uint32_t)k[1])<<16); break; case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ case 2 : a+=k[0]; break; case 1 : a+=k8[0]; break; case 0 : return c; /* zero length requires no mixing */ } } else { /* need to read the key one byte at a time */ const uint8_t *k = (const uint8_t *)key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ while (length > 12) { a += k[0]; a += ((uint32_t)k[1])<<8; a += ((uint32_t)k[2])<<16; a += ((uint32_t)k[3])<<24; b += k[4]; b += ((uint32_t)k[5])<<8; b += ((uint32_t)k[6])<<16; b += ((uint32_t)k[7])<<24; c += k[8]; c += ((uint32_t)k[9])<<8; c += ((uint32_t)k[10])<<16; c += ((uint32_t)k[11])<<24; mix(a,b,c); length -= 12; k += 12; } /*-------------------------------- last block: affect all 32 bits of (c) */ switch(length) /* all the case statements fall through */ { case 12: c+=((uint32_t)k[11])<<24; case 11: c+=((uint32_t)k[10])<<16; case 10: c+=((uint32_t)k[9])<<8; case 9 : c+=k[8]; case 8 : b+=((uint32_t)k[7])<<24; case 7 : b+=((uint32_t)k[6])<<16; case 6 : b+=((uint32_t)k[5])<<8; case 5 : b+=k[4]; case 4 : a+=((uint32_t)k[3])<<24; case 3 : a+=((uint32_t)k[2])<<16; case 2 : a+=((uint32_t)k[1])<<8; case 1 : a+=k[0]; break; case 0 : return c; } } final(a,b,c); return c; } /* * hashlittle2: return 2 32-bit hash values * * This is identical to hashlittle(), except it returns two 32-bit hash * values instead of just one. This is good enough for hash table * lookup with 2^^64 buckets, or if you want a second hash if you're not * happy with the first, or if you want a probably-unique 64-bit ID for * the key. *pc is better mixed than *pb, so use *pc first. If you want * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". */ void hashlittle2( const void *key, /* the key to hash */ size_t length, /* length of the key */ uint32_t *pc, /* IN: primary initval, OUT: primary hash */ uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ { uint32_t a,b,c; /* internal state */ union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ /* Set up the internal state */ a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; c += *pb; u.ptr = key; if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ while (length > 12) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 12; k += 3; } /*----------------------------- handle the last (probably partial) block */ /* * "k[2]&0xffffff" actually reads beyond the end of the string, but * then masks off the part it's not allowed to read. Because the * string is aligned, the masked-off tail is in the same word as the * rest of the string. Every machine with memory protection I've seen * does it on word boundaries, so is OK with this. But VALGRIND will * still catch it and complain. The masking trick does make the hash * noticably faster for short strings (like English words). */ #ifndef VALGRIND switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=k[1]&0xffffff; a+=k[0]; break; case 6 : b+=k[1]&0xffff; a+=k[0]; break; case 5 : b+=k[1]&0xff; a+=k[0]; break; case 4 : a+=k[0]; break; case 3 : a+=k[0]&0xffffff; break; case 2 : a+=k[0]&0xffff; break; case 1 : a+=k[0]&0xff; break; case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ } #else /* make valgrind happy */ const uint8_t *k8; k8 = (const uint8_t *)k; switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ case 9 : c+=k8[8]; /* fall through */ case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ case 5 : b+=k8[4]; /* fall through */ case 4 : a+=k[0]; break; case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ case 1 : a+=k8[0]; break; case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ } #endif /* !valgrind */ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ const uint8_t *k8; /*--------------- all but last block: aligned reads and different mixing */ while (length > 12) { a += k[0] + (((uint32_t)k[1])<<16); b += k[2] + (((uint32_t)k[3])<<16); c += k[4] + (((uint32_t)k[5])<<16); mix(a,b,c); length -= 12; k += 6; } /*----------------------------- handle the last (probably partial) block */ k8 = (const uint8_t *)k; switch(length) { case 12: c+=k[4]+(((uint32_t)k[5])<<16); b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ case 10: c+=k[4]; b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 9 : c+=k8[8]; /* fall through */ case 8 : b+=k[2]+(((uint32_t)k[3])<<16); a+=k[0]+(((uint32_t)k[1])<<16); break; case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ case 6 : b+=k[2]; a+=k[0]+(((uint32_t)k[1])<<16); break; case 5 : b+=k8[4]; /* fall through */ case 4 : a+=k[0]+(((uint32_t)k[1])<<16); break; case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ case 2 : a+=k[0]; break; case 1 : a+=k8[0]; break; case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ } } else { /* need to read the key one byte at a time */ const uint8_t *k = (const uint8_t *)key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ while (length > 12) { a += k[0]; a += ((uint32_t)k[1])<<8; a += ((uint32_t)k[2])<<16; a += ((uint32_t)k[3])<<24; b += k[4]; b += ((uint32_t)k[5])<<8; b += ((uint32_t)k[6])<<16; b += ((uint32_t)k[7])<<24; c += k[8]; c += ((uint32_t)k[9])<<8; c += ((uint32_t)k[10])<<16; c += ((uint32_t)k[11])<<24; mix(a,b,c); length -= 12; k += 12; } /*-------------------------------- last block: affect all 32 bits of (c) */ switch(length) /* all the case statements fall through */ { case 12: c+=((uint32_t)k[11])<<24; case 11: c+=((uint32_t)k[10])<<16; case 10: c+=((uint32_t)k[9])<<8; case 9 : c+=k[8]; case 8 : b+=((uint32_t)k[7])<<24; case 7 : b+=((uint32_t)k[6])<<16; case 6 : b+=((uint32_t)k[5])<<8; case 5 : b+=k[4]; case 4 : a+=((uint32_t)k[3])<<24; case 3 : a+=((uint32_t)k[2])<<16; case 2 : a+=((uint32_t)k[1])<<8; case 1 : a+=k[0]; break; case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ } } final(a,b,c); *pc=c; *pb=b; } /* * hashbig(): * This is the same as hashword() on big-endian machines. It is different * from hashlittle() on all machines. hashbig() takes advantage of * big-endian byte ordering. */ uint32_t hashbig( const void *key, size_t length, uint32_t initval) { uint32_t a,b,c; union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ /* Set up the internal state */ a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; u.ptr = key; if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ while (length > 12) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); length -= 12; k += 3; } /*----------------------------- handle the last (probably partial) block */ /* * "k[2]<<8" actually reads beyond the end of the string, but * then shifts out the part it's not allowed to read. Because the * string is aligned, the illegal read is in the same word as the * rest of the string. Every machine with memory protection I've seen * does it on word boundaries, so is OK with this. But VALGRIND will * still catch it and complain. The masking trick does make the hash * noticably faster for short strings (like English words). */ #ifndef VALGRIND switch(length) { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; case 5 : b+=k[1]&0xff000000; a+=k[0]; break; case 4 : a+=k[0]; break; case 3 : a+=k[0]&0xffffff00; break; case 2 : a+=k[0]&0xffff0000; break; case 1 : a+=k[0]&0xff000000; break; case 0 : return c; /* zero length strings require no mixing */ } #else /* make valgrind happy */ const uint8_t *k8; k8 = (const uint8_t *)k; switch(length) /* all the case statements fall through */ { case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ case 8 : b+=k[1]; a+=k[0]; break; case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ case 4 : a+=k[0]; break; case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ case 1 : a+=((uint32_t)k8[0])<<24; break; case 0 : return c; } #endif /* !VALGRIND */ } else { /* need to read the key one byte at a time */ const uint8_t *k = (const uint8_t *)key; /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ while (length > 12) { a += ((uint32_t)k[0])<<24; a += ((uint32_t)k[1])<<16; a += ((uint32_t)k[2])<<8; a += ((uint32_t)k[3]); b += ((uint32_t)k[4])<<24; b += ((uint32_t)k[5])<<16; b += ((uint32_t)k[6])<<8; b += ((uint32_t)k[7]); c += ((uint32_t)k[8])<<24; c += ((uint32_t)k[9])<<16; c += ((uint32_t)k[10])<<8; c += ((uint32_t)k[11]); mix(a,b,c); length -= 12; k += 12; } /*-------------------------------- last block: affect all 32 bits of (c) */ switch(length) /* all the case statements fall through */ { case 12: c+=k[11]; case 11: c+=((uint32_t)k[10])<<8; case 10: c+=((uint32_t)k[9])<<16; case 9 : c+=((uint32_t)k[8])<<24; case 8 : b+=k[7]; case 7 : b+=((uint32_t)k[6])<<8; case 6 : b+=((uint32_t)k[5])<<16; case 5 : b+=((uint32_t)k[4])<<24; case 4 : a+=k[3]; case 3 : a+=((uint32_t)k[2])<<8; case 2 : a+=((uint32_t)k[1])<<16; case 1 : a+=((uint32_t)k[0])<<24; break; case 0 : return c; } } final(a,b,c); return c; } } // end namespace bjhash } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/ustring.cpp0000644000175000017500000003171512271062644020762 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "export.h" #include "thread.h" #include "strutil.h" #include "dassert.h" #include "ustring.h" #include OIIO_NAMESPACE_ENTER { #if 0 // Use regular mutex typedef mutex ustring_mutex_t; typedef lock_guard ustring_read_lock_t; typedef lock_guard ustring_write_lock_t; #elif 0 // Use spin locks typedef spin_mutex ustring_mutex_t; typedef spin_lock ustring_read_lock_t; typedef spin_lock ustring_write_lock_t; #elif 1 // Use rw spin locks typedef spin_rw_mutex ustring_mutex_t; typedef spin_rw_read_lock ustring_read_lock_t; typedef spin_rw_write_lock ustring_write_lock_t; #else // Use null locks typedef null_mutex ustring_mutex_t; typedef null_lock ustring_read_lock_t; typedef null_lock ustring_write_lock_t; #endif typedef boost::unordered_map UstringTable; std::string ustring::empty_std_string (""); namespace { // anonymous static long long ustring_stats_memory = 0; static long long ustring_stats_constructed = 0; static long long ustring_stats_unique = 0; // Wrap our static mutex in a function to guarantee it exists when we // need it, regardless of module initialization order. static ustring_mutex_t & ustring_mutex () { static ustring_mutex_t the_real_mutex; return the_real_mutex; } static UstringTable & ustring_table () { static UstringTable table; return table; } }; // end anonymous namespace // Put a ustring in the global scope to force at least one call to // make_unique to happen before main(), i.e. before threads are launched, // in order to eliminate any possible thread collosion on construction of // the ustring_table statically declared within make_unique. namespace pvt { static ustring ustring_force_make_unique_call(""); }; namespace { // Definitions to let us access libc++ string internals. // See libc++ file for details. #ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT struct libcpp_string__long { std::string::pointer __data_; std::string::size_type __size_; std::string::size_type __cap_; }; #if _LIBCPP_BIG_ENDIAN enum {libcpp_string__long_mask = 0x1ul}; #else // _LIBCPP_BIG_ENDIAN enum {libcpp_string__long_mask = ~(std::string::size_type(~0) >> 1)}; #endif // _LIBCPP_BIG_ENDIAN #else struct libcpp_string__long { std::string::size_type __cap_; std::string::size_type __size_; std::string::pointer __data_; }; #if _LIBCPP_BIG_ENDIAN enum {libcpp_string__long_mask = ~(std::string::size_type(~0) >> 1)}; #else // _LIBCPP_BIG_ENDIAN enum {libcpp_string__long_mask = 0x1ul}; #endif // _LIBCPP_BIG_ENDIAN #endif enum {libcpp_string__min_cap = (sizeof(libcpp_string__long) - 1)/sizeof(std::string::value_type) > 2 ? (sizeof(libcpp_string__long) - 1)/sizeof(std::string::value_type) : 2}; }; ustring::TableRep::TableRep (const char *s, size_t len) : hashed(Strutil::strhash(s)) { strcpy ((char *)c_str(), s); length = len; // We don't want the internal 'std::string str' to redundantly store the // chars, along with our own allocation. So we use our knowledge of the // internal structure of std::string (for certain compilers) to force // the std::string to make it point to our chars! In such a case, the // destructor will be careful not to allow a deallocation. #if defined(__GNUC__) && !defined(_LIBCPP_VERSION) // It turns out that the first field of a gcc std::string is a pointer // to the characters within the basic_string::_Rep. We merely redirect // that pointer, though for std::string to function properly, the chars // must be preceeded immediately in memory by the rest of // basic_string::_Rep, consisting of length, capacity and refcount // fields. And we have designed our TableRep to do just that! So now // we redirect the std::string's pointer to our own characters and its // mocked-up _Rep. // // See /usr/include/c++/VERSION/bits/basic_string.h for the details of // gcc's std::string implementation. dummy_capacity = len; dummy_refcount = 1; // so it never frees *(const char **)&str = c_str(); DASSERT (str.c_str() == c_str() && str.size() == len); return; #elif defined(_LIBCPP_VERSION) // libc++ uses a different std::string representation than gcc. For // long char sequences, it's two size_t's (capacity & length) followed // by the pointer to allocated characters. (Gory detail: see the // definitions above for how it varies slightly with endianness and // _LIBCPP_ALTERNATE_STRING_LAYOUT.) For short enough sequences, it's a // single byte length followed immediately by the chars (the total being // the same size as the long string). There's no savings of space or // allocations to be had for short strings, so we just let those behave // as normal. But if it's going to make a long string (we can tell from // the length), we construct it ourselves, forcing the pointer to point // to the charcters in the TableRep we allocated. if (len >= libcpp_string__min_cap /* it'll be a "long string" */) { ((libcpp_string__long *)&str)->__cap_ = libcpp_string__long_mask | (len+1); ((libcpp_string__long *)&str)->__size_ = len; ((libcpp_string__long *)&str)->__data_ = (char *)c_str(); DASSERT (str.c_str() == c_str() && str.size() == len); return; } #endif // Remaining cases - just assign the internal string. This may result // in double allocation for the chars. If you care about that, do // something special for your platform, much like we did for gcc and // libc++ above. (Windows users, I'm talking to you.) str = s; } ustring::TableRep::~TableRep () { if (str.c_str() == c_str()) { // This is one of those cases where we've carefully doctored the // string to point to our allocated characters. To make a safe // string destroy, now force it to look like an empty string. std::string empty; memcpy (&str, &empty, sizeof(std::string)); } } const char * ustring::make_unique (const char *str) { UstringTable &table (ustring_table()); // Eliminate NULLs if (! str) str = ""; // Check the ustring table to see if this string already exists. If so, // construct from its canonical representation. { // Grab a read lock on the table. Hopefully, the string will // already be present, and we can immediately return its rep. // Lots of threads may do this simultaneously, as long as they // are all in the table. const char *result = NULL; // only non-NULL if it was found { ustring_read_lock_t read_lock (ustring_mutex()); UstringTable::const_iterator found = table.find (str); if (found != table.end()) result = found->second->c_str(); } // atomically increment the stat, since we're outside the lock atomic_exchange_and_add (&ustring_stats_constructed, 1); if (result) return result; } // This string is not yet in the ustring table. Create a new entry. // Note that we are speculatively releasing the lock and building the // string locally. Then we'll lock again to put it in the table. size_t len = strlen(str); size_t size = sizeof(ustring::TableRep) + len + 1; ustring::TableRep *rep = (ustring::TableRep *) malloc (size); new (rep) ustring::TableRep (str, len); const char *result = rep->c_str(); // start assuming new one { // Now grab a write lock on the table. This will prevent other // threads from even reading. Just in case another thread has // already entered this thread while we were unlocked and // constructing its rep, check the table one more time. If it's // still empty, add it. ustring_write_lock_t write_lock (ustring_mutex()); UstringTable::const_iterator found = table.find (str); if (found == table.end()) { // add the one we just created to the table table[result] = rep; ++ustring_stats_unique; ustring_stats_memory += size; if (rep->c_str() != rep->str.c_str()) ustring_stats_memory += len+1; // chars are replicated return result; } else { // use the one in the table, and we'll delete the new one we // created at the end of the function result = found->second->c_str(); } } // Somebody else added this string to the table in that interval // when we were unlocked and constructing the rep. Don't use the // new one! Use the one in the table and disregard the one we // speculatively built. Note that we've already released the lock // on the table at this point. rep->~TableRep (); // destructor free (rep); // because it was malloced return result; } std::string ustring::getstats (bool verbose) { ustring_read_lock_t read_lock (ustring_mutex()); std::ostringstream out; if (verbose) { out << "ustring statistics:\n"; out << " ustring requests: " << ustring_stats_constructed << ", unique " << ustring_stats_unique << "\n"; out << " ustring memory: " << Strutil::memformat(ustring_stats_memory) << "\n"; } else { out << "requests: " << ustring_stats_constructed << ", unique " << ustring_stats_unique << ", " << Strutil::memformat(ustring_stats_memory); } #ifndef NDEBUG // See if our hashing is pathological by checking if there are multiple // strings that ended up with the same hash. UstringTable &table (ustring_table()); std::map hashes; int collisions = 0; int collision_max = 0; size_t most_common_hash = 0; for (UstringTable::const_iterator s = table.begin(), e = table.end(); s != e; ++s) { // Pretend the (const char *) in the string table is a ustring (it is!) const ustring &us = *((ustring *)(&s->first)); bool init = (hashes.find(us.hash()) == hashes.end()); int &c (hashes[us.hash()]); // Find/create the count for this hash if (init) c = 0; if (++c > 1) { // Increment it, and if it's shared... ++collisions; // register a collision if (c > collision_max) { // figure out the largest number collision_max = c; // of shared collisions most_common_hash = us.hash(); } } } out << (verbose ? " " : ", ") << collisions << " hash collisions (max " << collision_max << (verbose ? ")\n" : ")"); // DEBUG renders only -- reveal the strings sharing the most common hash if (collision_max > 2) { out << (verbose ? "" : "\n") << " Most common hash " << most_common_hash << " was shared by:\n"; for (UstringTable::const_iterator s = table.begin(), e = table.end(); s != e; ++s) { const ustring &us = *((ustring *)(&s->first)); if (us.hash() == most_common_hash) out << " \"" << us << "\"\n"; } } #endif return out.str(); } size_t ustring::memory () { ustring_read_lock_t read_lock (ustring_mutex()); return ustring_stats_memory; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/argparse.cpp0000644000175000017500000004110712271062644021067 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include "strutil.h" #include "sysutil.h" #include "argparse.h" #include "dassert.h" #include "filesystem.h" OIIO_NAMESPACE_ENTER { class ArgOption { public: typedef int (*callback_t) (int, const char**); ArgOption (const char *str); ~ArgOption () { } int initialize (); int parameter_count () const { return m_count; } const std::string & name() const { return m_flag; } const std::string & fmt() const { return m_format; } bool is_flag () const { return m_type == Flag; } bool is_reverse_flag () const { return m_type == ReverseFlag; } bool is_sublist () const { return m_type == Sublist; } bool is_regular () const { return m_type == Regular; } bool has_callback () const { return m_has_callback; } void add_parameter (int i, void *p); void set_parameter (int i, const char *argv); void add_argument (const char *argv); int invoke_callback () const; int invoke_callback (int argc, const char **argv) const { return m_callback ? m_callback (argc, argv) : 0; } void set_callback (callback_t cb) { m_callback = cb; } void found_on_command_line () { m_repetitions++; } int parsed_count () const { return m_repetitions; } void description (const char *d) { m_descript = d; } const std::string & description() const { return m_descript; } private: enum OptionType { None, Regular, Flag, ReverseFlag, Sublist }; std::string m_format; // original format string std::string m_flag; // just the -flag_foo part std::string m_code; // paramter types, eg "df" std::string m_descript; OptionType m_type; int m_count; // number of parameters std::vector m_param; // pointers to app data vars callback_t m_callback; int m_repetitions; // number of times on cmd line bool m_has_callback; // needs a callback? std::vector m_argv; }; // Constructor. Does not do any parsing or error checking. // Make sure to call initialize() right after construction. ArgOption::ArgOption (const char *str) : m_format(str), m_type(None), m_count(0), m_callback(NULL), m_repetitions(0), m_has_callback(false) { } // Parses the format string ("-option %s %d %f") to extract the // flag ("-option") and create a code string ("sdf"). After the // code string is created, the param list of void* pointers is // allocated to hold the argument variable pointers. int ArgOption::initialize() { size_t n; const char *s; if (m_format.empty() || m_format == "%*") { m_type = Sublist; m_count = 1; // sublist callback function pointer m_code = "*"; m_flag = ""; } else if (m_format == "") { } else { // extract the flag name s = &m_format[0]; assert(*s == '-'); assert(isalpha(s[1]) || (s[1] == '-' && isalpha(s[2]))); s++; if (*s == '-') s++; while (isalnum(*s) || *s == '_' || *s == '-') s++; if (! *s) { m_flag = m_format; m_type = Flag; m_count = 1; m_code = "b"; } else { n = s - (&m_format[0]); m_flag.assign (m_format.begin(), m_format.begin()+n); // Parse the scanf-like parameters m_type = Regular; n = (m_format.length() - n) / 2; // conservative estimate m_code.clear (); while (*s != '\0') { if (*s == '%') { s++; assert(*s != '\0'); m_count++; // adding another parameter switch (*s) { case 'd': // 32bit int case 'g': // float case 'f': // float case 'F': // double case 's': // string case 'L': // vector assert (m_type == Regular); m_code += *s; break; case '!': m_type = ReverseFlag; m_code += *s; break; case '*': assert(m_count == 1); m_type = Sublist; break; case '@': m_has_callback = true; --m_count; break; default: std::cerr << "Programmer error: Unknown option "; std::cerr << "type string \"" << *s << "\"" << "\n"; abort(); } } s++; } // Catch the case where only a callback was given, it's still // a bool. if (! *s && m_count == 0 && m_has_callback) { m_type = Flag; m_count = 1; m_code = "b"; } } } // A few replacements to tidy up the format string for printing size_t loc; while ((loc = m_format.find("%L")) != std::string::npos) m_format.replace (loc, 2, "%s"); while ((loc = m_format.find("%!")) != std::string::npos) m_format.replace (loc, 2, ""); while ((loc = m_format.find("%@")) != std::string::npos) m_format.replace (loc, 2, ""); // Allocate space for the parameter pointers and initialize to NULL m_param.resize (m_count, NULL); return 0; } // Stores the pointer to an argument in the param list and // initializes flag options to FALSE. // FIXME -- there is no such initialization. Bug? void ArgOption::add_parameter (int i, void *p) { assert (i >= 0 && i < m_count); m_param[i] = p; } // Given a string from argv, set the associated option parameter // at index i using the format conversion code in the code string. void ArgOption::set_parameter (int i, const char *argv) { assert(i < m_count); if (! m_param[i]) // If they passed NULL as the address, return; // don't write anything. switch (m_code[i]) { case 'd': *(int *)m_param[i] = atoi(argv); break; case 'f': case 'g': *(float *)m_param[i] = (float)atof(argv); break; case 'F': *(double *)m_param[i] = atof(argv); break; case 's': *(std::string *)m_param[i] = argv; break; case 'S': *(std::string *)m_param[i] = argv; break; case 'L': ((std::vector *)m_param[i])->push_back (argv); break; case 'b': *(bool *)m_param[i] = true; break; case '!': *(bool *)m_param[i] = false; break; case '*': default: abort(); } } // Call the sublist callback if any arguments have been parsed int ArgOption::invoke_callback () const { assert (m_count == 1); int argc = (int) m_argv.size(); if (argc == 0) return 0; // Convert the argv's to char*[] const char **myargv = (const char **) alloca (argc * sizeof(const char *)); for (int i = 0; i < argc; ++i) myargv[i] = m_argv[i].c_str(); return invoke_callback (argc, myargv); } // Add an argument to this sublist option void ArgOption::add_argument (const char *argv) { m_argv.push_back (argv); } ArgParse::ArgParse (int argc, const char **argv) : m_argc(argc), m_argv(argv), m_global(NULL) { } ArgParse::~ArgParse() { for (unsigned int i=0; ifound_on_command_line(); if (option->is_flag() || option->is_reverse_flag()) { option->set_parameter(0, NULL); if (option->has_callback()) option->invoke_callback (1, m_argv+i); } else { ASSERT (option->is_regular()); for (int j = 0; j < option->parameter_count(); j++) { if (j+i+1 >= m_argc) { error ("Missing parameter %d from option " "\"%s\"", j+1, option->name().c_str()); return -1; } option->set_parameter (j, m_argv[i+j+1]); } if (option->has_callback()) option->invoke_callback (1+option->parameter_count(), m_argv+i); i += option->parameter_count(); } } else { // not an option nor an option parameter, glob onto global list if (m_global) m_global->invoke_callback (1, m_argv+i); else { error ("Argument \"%s\" does not have an associated " "option", m_argv[i]); return -1; } } } return 0; } // Primary entry point. This function accepts a set of format strings // and variable pointers. Each string contains an option name and a // scanf-like format string to enumerate the arguments of that option // (eg. "-option %d %f %s"). The format string is followed by a list // of pointers to the argument variables, just like scanf. All format // strings and arguments are parsed to create a list of ArgOption objects. // After all ArgOptions are created, the command line is parsed and // the sublist option callbacks are invoked. int ArgParse::options (const char *intro, ...) { va_list ap; va_start (ap, intro); m_intro += intro; for (const char *cur = va_arg(ap, char *); cur; cur = va_arg(ap, char *)) { if (find_option (cur) && strcmp(cur, "")) { error ("Option \"%s\" is multiply defined", cur); return -1; } // Build a new option and then parse the values ArgOption *option = new ArgOption (cur); if (option->initialize() < 0) { return -1; } if (cur[0] == '\0' || (cur[0] == '%' && cur[1] == '*' && cur[2] == '\0')) { // set default global option m_global = option; } if (option->has_callback()) option->set_callback ((ArgOption::callback_t)va_arg(ap,void*)); // Grab any parameters and store them with this option for (int i = 0; i < option->parameter_count(); i++) { void *p = va_arg (ap, void *); option->add_parameter (i, p); if (option == m_global) option->set_callback ((ArgOption::callback_t)p); } // Last argument is description option->description ((const char *) va_arg (ap, const char *)); m_option.push_back(option); } va_end (ap); return 0; } // Find an option by name in the option vector ArgOption * ArgParse::find_option (const char *name) { for (std::vector::const_iterator i = m_option.begin(); i != m_option.end(); i++) { const char *opt = (*i)->name().c_str(); if (! strcmp(name, opt)) return *i; // Match even if the user mixes up one dash or two if (name[0] == '-' && name[1] == '-' && opt[0] == '-' && opt[1] != '-') if (! strcmp (name+1, opt)) return *i; if (name[0] == '-' && name[1] != '-' && opt[0] == '-' && opt[1] == '-') if (! strcmp (name, opt+1)) return *i; } return NULL; } int ArgParse::found (const char *option_name) { ArgOption *option = find_option(option_name); if (option == NULL) return 0; return option->parsed_count(); } std::string ArgParse::geterror () const { std::string e = m_errmessage; m_errmessage.clear (); return e; } void ArgParse::usage () const { const size_t longline = 35; std::cout << m_intro << '\n'; size_t maxlen = 0; for (unsigned int i=0; ifmt().length(); // Option lists > 40 chars will be split into multiple lines if (fmtlen < longline) maxlen = std::max (maxlen, fmtlen); } // Try to figure out how wide the terminal is, so we can word wrap. int columns = Sysutil::terminal_columns (); for (unsigned int i=0; idescription().length()) { size_t fmtlen = opt->fmt().length(); if (opt->fmt() == "") { std::cout << Strutil::wordwrap(opt->description(), columns-2, 0) << '\n'; } else { std::cout << " " << opt->fmt(); if (fmtlen < longline) std::cout << std::string (maxlen + 2 - fmtlen, ' '); else std::cout << "\n " << std::string (maxlen + 2, ' '); std::cout << Strutil::wordwrap(opt->description(), columns-2, (int)maxlen+2+4+2) << '\n'; } } } } std::string ArgParse::command_line () const { std::string s; for (int i = 0; i < m_argc; ++i) { if (strchr (m_argv[i], ' ')) { s += '\"'; s += m_argv[i]; s += '\"'; } else { s += m_argv[i]; } if (i < m_argc-1) s += ' '; } return s; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/filesystem.cpp0000644000175000017500000004335412271062644021455 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #include #endif #include "dassert.h" #include "ustring.h" #include "filesystem.h" OIIO_NAMESPACE_ENTER { std::string Filesystem::filename (const std::string &filepath) { // To simplify dealing with platform-specific separators and whatnot, // just use the Boost routines: #if BOOST_FILESYSTEM_VERSION == 3 return boost::filesystem::path(filepath).filename().string(); #else return boost::filesystem::path(filepath).filename(); #endif } std::string Filesystem::extension (const std::string &filepath, bool include_dot) { std::string s; #if BOOST_FILESYSTEM_VERSION == 3 s = boost::filesystem::path(filepath).extension().string(); #else s = boost::filesystem::path(filepath).extension(); #endif if (! include_dot && !s.empty() && s[0] == '.') s.erase (0, 1); // erase the first character return s; } std::string Filesystem::parent_path (const std::string &filepath) { return boost::filesystem::path(filepath).parent_path().string(); } std::string Filesystem::replace_extension (const std::string &filepath, const std::string &new_extension) { return boost::filesystem::path(filepath).replace_extension(new_extension).string(); } void Filesystem::searchpath_split (const std::string &searchpath, std::vector &dirs, bool validonly) { dirs.clear(); std::string path_copy = searchpath; std::string last_token; typedef boost::tokenizer > tokenizer; boost::char_separator sep(":;"); tokenizer tokens (searchpath, sep); for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); last_token = *tok_iter, ++tok_iter) { std::string path = *tok_iter; #ifdef _WIN32 // On Windows, we might see something like "a:foo" and any human // would know that it means drive/directory 'a:foo', NOT // separate directories 'a' and 'foo'. Implement the obvious // heuristic here. Note that this means that we simply don't // correctly support searching in *relative* directories that // consist of a single letter. if (last_token.length() == 1 && last_token[0] != '.') { // If the last token was a single letter, try prepending it path = last_token + ":" + (*tok_iter); } else #endif path = *tok_iter; // Kill trailing slashes (but not simple "/") size_t len = path.length(); while (len > 1 && (path[len-1] == '/' || path[len-1] == '\\')) path.erase (--len); // If it's a valid directory, or if validonly is false, add it // to the list if (!validonly || Filesystem::is_directory (path)) dirs.push_back (path); } #if 0 std::cerr << "Searchpath = '" << searchpath << "'\n"; BOOST_FOREACH (std::string &d, dirs) std::cerr << "\tPath = '" << d << "'\n"; std::cerr << "\n"; #endif } std::string Filesystem::searchpath_find (const std::string &filename, const std::vector &dirs, bool testcwd, bool recursive) { bool abs = Filesystem::path_is_absolute (filename); // If it's an absolute filename, or if we want to check "." first, // then start by checking filename outright. if (testcwd || abs) { if (Filesystem::is_regular (filename)) return filename; } // Relative filename, not yet found -- try each directory in turn BOOST_FOREACH (const std::string &d, dirs) { // std::cerr << "\tPath = '" << d << "'\n"; boost::filesystem::path f = d; f /= filename; // std::cerr << "\tTesting '" << f << "'\n"; if (Filesystem::is_regular (f.string())) { // std::cerr << "Found '" << f << "'\n"; return f.string(); } if (recursive && Filesystem::is_directory (d)) { std::vector subdirs; for (boost::filesystem::directory_iterator s(d); s != boost::filesystem::directory_iterator(); ++s) if (Filesystem::is_directory(s->path().string())) subdirs.push_back (s->path().string()); std::string found = searchpath_find (filename, subdirs, false, true); if (found.size()) return found; } } return std::string(); } bool Filesystem::get_directory_entries (const std::string &dirname, std::vector &filenames, bool recursive, const std::string &filter_regex) { filenames.clear (); if (dirname.size() && ! is_directory(dirname)) return false; boost::filesystem::path dirpath (dirname.size() ? dirname : std::string(".")); boost::regex re (filter_regex); if (recursive) { for (boost::filesystem::recursive_directory_iterator s (dirpath); s != boost::filesystem::recursive_directory_iterator(); ++s) { std::string file = s->path().string(); if (!filter_regex.size() || boost::regex_search (file, re)) filenames.push_back (file); } } else { for (boost::filesystem::directory_iterator s (dirpath); s != boost::filesystem::directory_iterator(); ++s) { std::string file = s->path().string(); if (!filter_regex.size() || boost::regex_search (file, re)) filenames.push_back (file); } } return true; } bool Filesystem::path_is_absolute (const std::string &path, bool dot_is_absolute) { // "./foo" is considered absolute if dot_is_absolute is true. // Don't get confused by ".foo", which is not absolute! size_t len = path.length(); if (!len) return false; return (path[0] == '/') || (dot_is_absolute && path[0] == '.' && path[1] == '/') || (dot_is_absolute && path[0] == '.' && path[1] == '.' && path[2] == '/') #ifdef _WIN32 || path[0] == '\\' || (dot_is_absolute && path[0] == '.' && path[1] == '\\') || (dot_is_absolute && path[0] == '.' && path[1] == '.' && path[2] == '\\') || (isalpha(path[0]) && path[1] == ':') #endif ; } bool Filesystem::exists (const std::string &path) { bool r = false; try { r = boost::filesystem::exists (path); } catch (const std::exception &) { r = false; } return r; } bool Filesystem::is_directory (const std::string &path) { bool r = false; try { r = boost::filesystem::is_directory (path); } catch (const std::exception &) { r = false; } return r; } bool Filesystem::is_regular (const std::string &path) { bool r = false; try { r = boost::filesystem::is_regular_file (path); } catch (const std::exception &) { r = false; } return r; } FILE* Filesystem::fopen (const std::string &path, const std::string &mode) { #ifdef _WIN32 // on Windows fopen does not accept UTF-8 paths, so we convert to wide char std::wstring wpath = Strutil::utf8_to_utf16 (path); std::wstring wmode = Strutil::utf8_to_utf16 (mode); return ::_wfopen (wpath.c_str(), wmode.c_str()); #else // on Unix platforms passing in UTF-8 works return ::fopen (path.c_str(), mode.c_str()); #endif } void Filesystem::open (std::ifstream &stream, const std::string &path, std::ios_base::openmode mode) { #ifdef _WIN32 // Windows std::ifstream accepts non-standard wchar_t* std::wstring wpath = Strutil::utf8_to_utf16(path); stream.open (wpath.c_str(), mode); stream.seekg (0, std::ios_base::beg); // force seek, otherwise broken #else stream.open (path.c_str(), mode); #endif } void Filesystem::open (std::ofstream &stream, const std::string &path, std::ios_base::openmode mode) { #ifdef _WIN32 // Windows std::ofstream accepts non-standard wchar_t* std::wstring wpath = Strutil::utf8_to_utf16 (path); stream.open (wpath.c_str(), mode); #else stream.open (path.c_str(), mode); #endif } std::time_t Filesystem::last_write_time (const std::string& path) { try { #ifdef _WIN32 std::wstring wpath = Strutil::utf8_to_utf16 (path); return boost::filesystem::last_write_time (wpath); #else return boost::filesystem::last_write_time (path); #endif } catch (const std::exception &) { // File doesn't exist return 0; } } void Filesystem::last_write_time (const std::string& path, std::time_t time) { try { #ifdef _WIN32 std::wstring wpath = Strutil::utf8_to_utf16 (path); boost::filesystem::last_write_time (wpath, time); #else boost::filesystem::last_write_time (path, time); #endif } catch (const std::exception &) { // File doesn't exist } } void Filesystem::convert_native_arguments (int argc, const char *argv[]) { #ifdef _WIN32 // Windows only, standard main() entry point does not accept unicode file // paths, here we retrieve wide char arguments and convert them to utf8 if (argc == 0) return; int native_argc; wchar_t **native_argv = CommandLineToArgvW (GetCommandLineW (), &native_argc); if (!native_argv || native_argc != argc) return; for (int i = 0; i < argc; i++) { std::string utf8_arg = Strutil::utf16_to_utf8 (native_argv[i]); argv[i] = ustring (utf8_arg).c_str(); } #endif } bool Filesystem::enumerate_sequence (const char *desc, std::vector &numbers) { numbers.clear (); // Split the sequence description into comma-separated subranges. std::vector ranges; Strutil::split (desc, ranges, ","); // For each subrange... BOOST_FOREACH (const std::string &s, ranges) { // It's START, START-FINISH, or START-FINISHxSTEP, or START-FINISHySTEP // If START>FINISH or if STEP<0, then count down. // If 'y' is used, generate the complement. std::vector range; Strutil::split (s, range, "-", 2); int first = strtol (range[0].c_str(), NULL, 10); int last = first; int step = 1; bool complement = false; if (range.size() > 1) { last = strtol (range[1].c_str(), NULL, 10); if (const char *x = strchr (range[1].c_str(), 'x')) step = (int) strtol (x+1, NULL, 10); else if (const char *x = strchr (range[1].c_str(), 'y')) { step = (int) strtol (x+1, NULL, 10); complement = true; } if (step == 0) step = 1; if (step < 0 && first < last) std::swap (first, last); if (first > last && step > 0) step = -step; } int end = last + (step > 0 ? 1 : -1); int itstep = step > 0 ? 1 : -1; for (int i = first; i != end; i += itstep) { if ((abs(i-first) % abs(step) == 0) != complement) numbers.push_back (i); } } return true; } bool Filesystem::parse_pattern (const char *pattern_, int framepadding_override, std::string &normalized_pattern, std::string &framespec) { std::string pattern (pattern_); // The pattern is either a range (e.g., "1-15#"), a // set of hash marks (e.g. "####"), or a printf-style format // string (e.g. "%04d"). #define ONERANGE_SPEC "[0-9]+(-[0-9]+((x|y)-?[0-9]+)?)?" #define MANYRANGE_SPEC ONERANGE_SPEC "(," ONERANGE_SPEC ")*" #define SEQUENCE_SPEC "(" MANYRANGE_SPEC ")?" "((#|@)+|(%[0-9]*d))" static boost::regex sequence_re (SEQUENCE_SPEC); // std::cout << "pattern >" << (SEQUENCE_SPEC) << "<\n"; boost::match_results range_match; if (! boost::regex_search (pattern, range_match, sequence_re)) { // Not a range return false; } // It's a range. Generate the names by iterating through the numbers. std::string thematch (range_match[0].first, range_match[0].second); std::string thesequence (range_match[1].first, range_match[1].second); std::string thehashes (range_match[9].first, range_match[9].second); std::string theformat (range_match[11].first, range_match[11].second); std::string prefix (range_match.prefix().first, range_match.prefix().second); std::string suffix (range_match.suffix().first, range_match.suffix().second); // std::cout << "theformat: " << theformat << "\n"; std::string fmt; if (theformat.length() > 0) { fmt = theformat; } else { // Compute the amount of padding desired int padding = 0; for (int i = (int)thematch.length()-1; i >= 0; --i) { if (thematch[i] == '#') padding += 4; else if (thematch[i] == '@') padding += 1; } if (framepadding_override > 0) padding = framepadding_override; fmt = Strutil::format ("%%0%dd", padding); } // std::cout << "Format: '" << fmt << "'\n"; normalized_pattern = prefix + fmt + suffix; framespec = thesequence; return true; } bool Filesystem::enumerate_file_sequence (const std::string &pattern, const std::vector &numbers, std::vector &filenames) { for (size_t i = 0, e = numbers.size(); i < e; ++i) { std::string f = Strutil::format (pattern.c_str(), numbers[i]); filenames.push_back (f); } return true; } bool Filesystem::scan_for_matching_filenames(const std::string &pattern_, std::vector &numbers, std::vector &filenames) { std::string pattern = pattern_; // Isolate the directory name (or '.' if none was specified) std::string directory = Filesystem::parent_path (pattern); if (directory.size() == 0) { directory = "."; #ifdef _WIN32 pattern = ".\\\\" + pattern; #else pattern = "./" + pattern; #endif } if (! boost::filesystem::exists(directory)) return false; // build a regex that matches the pattern boost::regex format_re ("%0([0-9]+)d"); boost::match_results format_match; if (! boost::regex_search (pattern, format_match, format_re)) return false; std::string thepadding (format_match[1].first, format_match[1].second); std::string prefix (format_match.prefix().first, format_match.prefix().second); std::string suffix (format_match.suffix().first, format_match.suffix().second); std::string pattern_re_str = prefix + "([0-9]{" + thepadding + "})" + suffix; boost::regex pattern_re (pattern_re_str); std::vector< std::pair< int, std::string > > matches; boost::filesystem::directory_iterator end_it; #ifdef _WIN32 std::wstring wdirectory = Strutil::utf8_to_utf16 (directory); for (boost::filesystem::directory_iterator it(wdirectory); it != end_it; ++it) { #else for (boost::filesystem::directory_iterator it(directory); it != end_it; ++it) { #endif if (boost::filesystem::is_regular_file(it->status())) { const std::string f = it->path().string(); boost::match_results frame_match; if (boost::regex_match (f, frame_match, pattern_re)) { std::string thenumber (frame_match[1].first, frame_match[1].second); int frame = (int)strtol (thenumber.c_str(), NULL, 10); matches.push_back (std::make_pair (frame, f)); } } } // filesystem order is undefined, so return sorted sequences std::sort (matches.begin(), matches.end()); for (size_t i = 0; i < matches.size(); ++i) { numbers.push_back (matches[i].first); filenames.push_back (matches[i].second); } return true; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/errorhandler.cpp0000644000175000017500000001204112271062644021745 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include "strutil.h" #include "errorhandler.h" #include "thread.h" OIIO_NAMESPACE_ENTER { namespace { static ErrorHandler default_handler_instance; static mutex err_mutex; }; ErrorHandler & ErrorHandler::default_handler () { return default_handler_instance; } void ErrorHandler::vInfo (const char *format, va_list argptr) { if (verbosity() >= VERBOSE) { std::string msg = Strutil::vformat (format, argptr); (*this) (EH_INFO, msg); } } void ErrorHandler::vWarning (const char *format, va_list argptr) { if (verbosity() >= NORMAL) { std::string msg = Strutil::vformat (format, argptr); (*this) (EH_WARNING, msg); } } void ErrorHandler::vError (const char *format, va_list argptr) { std::string msg = Strutil::vformat (format, argptr); (*this) (EH_ERROR, msg); } void ErrorHandler::vSevere (const char *format, va_list argptr) { std::string msg = Strutil::vformat (format, argptr); (*this) (EH_SEVERE, msg); } void ErrorHandler::vMessage (const char *format, va_list argptr) { if (verbosity() > QUIET) { std::string msg = Strutil::vformat (format, argptr); (*this) (EH_MESSAGE, msg); } } #ifndef NDEBUG void ErrorHandler::vDebug (const char *format, va_list argptr) { if (verbosity() > QUIET) { std::string msg = Strutil::vformat (format, argptr); (*this) (EH_MESSAGE, msg); } } #endif void ErrorHandler::info (const char *format, ...) { if (verbosity() >= VERBOSE) { va_list argptr; va_start (argptr, format); vInfo (format, argptr); va_end (argptr); } } void ErrorHandler::warning (const char *format, ...) { if (verbosity() >= NORMAL) { va_list argptr; va_start (argptr, format); vWarning (format, argptr); va_end (argptr); } } void ErrorHandler::error (const char *format, ...) { va_list argptr; va_start (argptr, format); vError (format, argptr); va_end (argptr); } void ErrorHandler::severe (const char *format, ...) { va_list argptr; va_start (argptr, format); vSevere (format, argptr); va_end (argptr); } void ErrorHandler::message (const char *format, ...) { if (verbosity() > QUIET) { va_list argptr; va_start (argptr, format); vMessage (format, argptr); va_end (argptr); } } #ifndef NDEBUG void ErrorHandler::debug (const char *format, ...) { if (verbosity() > QUIET) { va_list argptr; va_start (argptr, format); vDebug (format, argptr); va_end (argptr); } } #endif void ErrorHandler::operator() (int errcode, const std::string &msg) { lock_guard guard (err_mutex); switch (errcode & 0xffff0000) { case EH_INFO : if (verbosity() >= VERBOSE) fprintf (stdout, "INFO: %s\n", msg.c_str()); break; case EH_WARNING : if (verbosity() >= NORMAL) fprintf (stderr, "WARNING: %s\n", msg.c_str()); break; case EH_ERROR : fprintf (stderr, "ERROR: %s\n", msg.c_str()); break; case EH_SEVERE : fprintf (stderr, "SEVERE ERROR: %s\n", msg.c_str()); break; case EH_DEBUG : #ifdef NDEBUG break; #endif default : if (verbosity() > QUIET) fprintf (stdout, "%s", msg.c_str()); break; } fflush (stdout); fflush (stderr); } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/filter.cpp0000644000175000017500000005316512271062644020557 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ // Filter results comparison // pow2 downres (4K -> 128 tested) // - katana 2.7.12 // - ImageMagick 6.3.6 // - prman 16.0 txmake // // box: oiio, prman, katana, imagemagick match // lanczos3: oiio, katana, imagemagick match. prman is far sharper (perhaps lanczos2?) // sinc: oiio, prman match. Katana is slighly softer. imagemagick is much softer // blackman harris: all differ. In order of decreasing sharpness... imagemagick, oiio, prman // catrom: oiio, imagemagick, prman match // gaussian: prman, katana match (gaussian3). imgmagick, oiio are sharper (gaussian2) #include #include #include #include "fmath.h" #include "filter.h" #include "dassert.h" OIIO_NAMESPACE_ENTER { // Below are the implementations of several 2D filters. They all // inherit their interface from Filter2D. Each must redefine two // virtual functions: // char *name() Return the filter name // float operator(float,float) Evaluate the filter // class FilterBox1D : public Filter1D { public: FilterBox1D (float width) : Filter1D(width) { } ~FilterBox1D (void) { } float operator() (float x) const { return (fabsf(x) <= m_w*0.5f) ? 1.0f : 0.0f; } const std::string name (void) const { return "box"; } }; class FilterBox2D : public Filter2D { public: FilterBox2D (float width, float height) : Filter2D(width,height) { } ~FilterBox2D (void) { } float operator() (float x, float y) const { return (fabsf(x) <= m_w*0.5f && fabsf(y) <= m_h*0.5f) ? 1.0f : 0.0f; } bool separable (void) const { return true; } float xfilt (float x) const { return fabsf(x) <= m_w*0.5f ? 1.0f : 0.0f; } float yfilt (float y) const { return fabsf(y) <= m_h*0.5f ? 1.0f : 0.0f; } const std::string name (void) const { return "box"; } }; class FilterTriangle1D : public Filter1D { public: FilterTriangle1D (float width) : Filter1D(width), m_rad_inv(2.0f/width) { } ~FilterTriangle1D (void) { } float operator() (float x) const { return tri1d (x * m_rad_inv); } const std::string name (void) const { return "triangle"; } static float tri1d (float x) { x = fabsf(x); return (x < 1.0f) ? (1.0f - x) : 0.0f; } private: float m_rad_inv; }; class FilterTriangle2D : public Filter2D { public: FilterTriangle2D (float width, float height) : Filter2D(width,height), m_wrad_inv(2.0f/width), m_hrad_inv(2.0f/height) { } ~FilterTriangle2D (void) { } float operator() (float x, float y) const { return FilterTriangle1D::tri1d (x * m_wrad_inv) * FilterTriangle1D::tri1d (y * m_hrad_inv); } bool separable (void) const { return true; } float xfilt (float x) const { return FilterTriangle1D::tri1d (x * m_wrad_inv); } float yfilt (float y) const { return FilterTriangle1D::tri1d (y * m_hrad_inv); } const std::string name (void) const { return "triangle"; } private: float m_wrad_inv, m_hrad_inv; }; class FilterGaussian1D : public Filter1D { public: FilterGaussian1D (float width) : Filter1D(width), m_rad_inv(2.0f/width) { } ~FilterGaussian1D (void) { } float operator() (float x) const { return gauss1d (x * m_rad_inv); } static float gauss1d (float x) { x = fabsf(x); return (x < 1.0f) ? fast_expf (-2.0f * (x*x)) : 0.0f; } const std::string name (void) const { return "gaussian"; } private: float m_rad_inv; }; class FilterGaussian2D : public Filter2D { public: FilterGaussian2D (float width, float height) : Filter2D(width,height), m_wrad_inv(2.0f/width), m_hrad_inv(2.0f/height) { } ~FilterGaussian2D (void) { } float operator() (float x, float y) const { return FilterGaussian1D::gauss1d (x * m_wrad_inv) * FilterGaussian1D::gauss1d (y * m_hrad_inv); } bool separable (void) const { return true; } float xfilt (float x) const { return FilterGaussian1D::gauss1d (x * m_wrad_inv); } float yfilt (float y) const { return FilterGaussian1D::gauss1d (y * m_hrad_inv); } const std::string name (void) const { return "gaussian"; } private: float m_wrad_inv, m_hrad_inv; }; class FilterSharpGaussian1D : public Filter1D { public: FilterSharpGaussian1D (float width) : Filter1D(width), m_rad_inv(2.0f/width) { } ~FilterSharpGaussian1D (void) { } float operator() (float x) const { return gauss1d (x * m_rad_inv); } static float gauss1d (float x) { x = fabsf(x); return (x < 1.0f) ? fast_expf (-4.0f * (x*x)) : 0.0f; } const std::string name (void) const { return "gaussian"; } private: float m_rad_inv; }; class FilterSharpGaussian2D : public Filter2D { public: FilterSharpGaussian2D (float width, float height) : Filter2D(width,height), m_wrad_inv(2.0f/width), m_hrad_inv(2.0f/height) { } ~FilterSharpGaussian2D (void) { } float operator() (float x, float y) const { return FilterSharpGaussian1D::gauss1d (x * m_wrad_inv) * FilterSharpGaussian1D::gauss1d (y * m_hrad_inv); } bool separable (void) const { return true; } float xfilt (float x) const { return FilterSharpGaussian1D::gauss1d (x * m_wrad_inv); } float yfilt (float y) const { return FilterSharpGaussian1D::gauss1d (y * m_hrad_inv); } const std::string name (void) const { return "gaussian"; } private: float m_wrad_inv, m_hrad_inv; }; class FilterCatmullRom1D : public Filter1D { public: FilterCatmullRom1D (float width) : Filter1D(4.0f) { } ~FilterCatmullRom1D (void) { } float operator() (float x) const { return catrom1d(x); } const std::string name (void) const { return "catmull-rom"; } static float catrom1d (float x) { x = fabsf(x); float x2 = x * x; float x3 = x * x2; return (x >= 2.0f) ? 0.0f : ((x < 1.0f) ? (3.0f * x3 - 5.0f * x2 + 2.0f) : (-x3 + 5.0f * x2 - 8.0f * x + 4.0f) ); } }; class FilterCatmullRom2D : public Filter2D { public: FilterCatmullRom2D (float width, float height) : Filter2D(4.0f,4.0f) { } ~FilterCatmullRom2D (void) { } float operator() (float x, float y) const { return FilterCatmullRom1D::catrom1d(x) * FilterCatmullRom1D::catrom1d(y); } bool separable (void) const { return true; } float xfilt (float x) const { return FilterCatmullRom1D::catrom1d(x); } float yfilt (float y) const { return FilterCatmullRom1D::catrom1d(y); } const std::string name (void) const { return "catmull-rom"; } private : static float catrom1d (float x) { x = fabsf(x); float x2 = x * x; float x3 = x * x2; return (x >= 2.0f) ? 0.0f : ((x < 1.0f) ? (3.0f * x3 - 5.0f * x2 + 2.0f) : (-x3 + 5.0f * x2 - 8.0f * x + 4.0f) ); } }; class FilterBlackmanHarris1D : public Filter1D { public: FilterBlackmanHarris1D (float width) : Filter1D(width), m_rad_inv(2.0f/width) { } ~FilterBlackmanHarris1D (void) { } float operator() (float x) const { return bh1d (x * m_rad_inv); } const std::string name (void) const { return "blackman-harris"; } static float bh1d (float x) { if (x < -1.0f || x > 1.0f) // Early out if outside filter range return 0.0f; // Compute BH. Straight from classic BH paper, but the usual // formula assumes that the filter is centered at 0.5, so scale: x = (x + 1.0f) * 0.5f; const float A0 = 0.35875f; const float A1 = -0.48829f; const float A2 = 0.14128f; const float A3 = -0.01168f; const float m_pi = float (M_PI); return A0 + A1 * cosf(2.f * m_pi * x) + A2 * cosf(4.f * m_pi * x) + A3 * cosf(6.f * m_pi * x); } private: float m_rad_inv; }; class FilterBlackmanHarris2D : public Filter2D { public: FilterBlackmanHarris2D (float width, float height) : Filter2D(width,height), m_wrad_inv(2.0f/width), m_hrad_inv(2.0f/height) { } ~FilterBlackmanHarris2D (void) { } float operator() (float x, float y) const { return FilterBlackmanHarris1D::bh1d (x*m_wrad_inv) * FilterBlackmanHarris1D::bh1d (y*m_hrad_inv); } bool separable (void) const { return true; } float xfilt (float x) const { return FilterBlackmanHarris1D::bh1d(x*m_wrad_inv); } float yfilt (float y) const { return FilterBlackmanHarris1D::bh1d(y*m_hrad_inv); } const std::string name (void) const { return "blackman-harris"; } private: float m_wrad_inv, m_hrad_inv; }; class FilterSinc1D : public Filter1D { public: FilterSinc1D (float width) : Filter1D(width), m_rad(width/2.0f) { } ~FilterSinc1D (void) { } float operator() (float x) const { return sinc1d (x, m_rad); } const std::string name (void) const { return "sinc"; } static float sinc1d (float x, float rad) { x = fabsf(x); if (x > rad) return 0.0f; const float m_pi = float (M_PI); return (x < 0.0001f) ? 1.0f : sinf (m_pi*x)/(m_pi*x); } private: float m_rad; }; class FilterSinc2D : public Filter2D { public: FilterSinc2D (float width, float height) : Filter2D(width,height), m_wrad(width/2.0f), m_hrad(height/2.0f) { } ~FilterSinc2D (void) { } float operator() (float x, float y) const { return FilterSinc1D::sinc1d(x,m_wrad) * FilterSinc1D::sinc1d(y,m_hrad); } bool separable (void) const { return true; } float xfilt (float x) const { return FilterSinc1D::sinc1d(x,m_wrad); } float yfilt (float y) const { return FilterSinc1D::sinc1d(y,m_hrad); } const std::string name (void) const { return "sinc"; } private: float m_wrad, m_hrad; }; class FilterLanczos3_1D : public Filter1D { public: FilterLanczos3_1D (float /*width*/) : Filter1D(6.0f) { } ~FilterLanczos3_1D (void) { } float operator() (float x) const { return lanczos3 (x); } const std::string name (void) const { return "lanczos3"; } static float lanczos3 (float x) { const float a = 3.0f; // Lanczos 3 lobe x = fabsf(x); if (x > a) return 0.0f; if (x < 0.0001f) return 1.0f; const float m_pi = float (M_PI); const float m_piinv = 1.0f / m_pi; const float ainv = 1.0f/a; float pix = m_pi * x; return (a*m_piinv*m_piinv)/(x*x) * sinf(pix)*sinf(pix*ainv); } }; class FilterLanczos3_2D : public Filter2D { public: FilterLanczos3_2D (float /*width*/, float /*height*/) : Filter2D(6.0f,6.0f) { } ~FilterLanczos3_2D (void) { } float operator() (float x, float y) const { return FilterLanczos3_1D::lanczos3(x) * FilterLanczos3_1D::lanczos3(y); } bool separable (void) const { return true; } float xfilt (float x) const { return FilterLanczos3_1D::lanczos3(x); } float yfilt (float y) const { return FilterLanczos3_1D::lanczos3(y); } const std::string name (void) const { return "lanczos3"; } }; class FilterRadialLanczos3_2D : public FilterLanczos3_2D { public: FilterRadialLanczos3_2D (float /*width*/, float /*height*/) : FilterLanczos3_2D(6.0f,6.0f) { } float operator() (float x, float y) const { return FilterLanczos3_1D::lanczos3(sqrtf(x*x + y*y)); } bool separable (void) const { return false; } const std::string name (void) const { return "radial-lanczos3"; } }; class FilterMitchell1D : public Filter1D { public: FilterMitchell1D (float width) : Filter1D(width) { } ~FilterMitchell1D (void) { } float operator() (float x) const { return mitchell1d (x * m_rad_inv); } const std::string name (void) const { return "mitchell"; } static float mitchell1d (float x) { x = fabsf (x); if (x > 1.0f) return 0.0f; // Computation stright out of the classic Mitchell paper. // In the paper, the range is -2 to 2, so we rescale: x *= 2.0f; float x2 = x*x; const float B = 1.0f/3.0f; const float C = 1.0f/3.0f; const float SIXTH = 1.0f/6.0f; if (x >= 1.0f) return ((-B - 6.0f*C)*x*x2 + (6.0f*B + 30.0f*C)*x2 + (-12.0f*B - 48.0f*C)*x + (8.0f*B + 24.0f*C)) * SIXTH; else return ((12.0f - 9.0f*B - 6.0f*C)*x*x2 + (-18.0f + 12.0f*B + 6.0f*C)*x2 + (6.0f - 2.0f*B)) * SIXTH; } private: float m_rad_inv; }; class FilterMitchell2D : public Filter2D { public: FilterMitchell2D (float width, float height) : Filter2D(width,height), m_wrad_inv(2.0f/width), m_hrad_inv(2.0f/height) { } ~FilterMitchell2D (void) { } float operator() (float x, float y) const { return FilterMitchell1D::mitchell1d (x * m_wrad_inv) * FilterMitchell1D::mitchell1d (y * m_hrad_inv); } bool separable (void) const { return true; } float xfilt (float x) const { return FilterMitchell1D::mitchell1d (x * m_wrad_inv); } float yfilt (float y) const { return FilterMitchell1D::mitchell1d (y * m_hrad_inv); } const std::string name (void) const { return "mitchell"; } private: float m_wrad_inv, m_hrad_inv; }; // B-spline filter from Stark et al, JGT 10(1) class FilterBSpline1D : public Filter1D { public: FilterBSpline1D (float width) : Filter1D(width), m_wscale(4.0f/width) { } ~FilterBSpline1D (void) { } float operator() (float x) const { return bspline1d (x*m_wscale); } const std::string name (void) const { return "b-spline"; } static float bspline1d (float x) { x = fabsf (x); if (x <= 1.0f) return b1 (1.0f-x); else if (x < 2.0f) return b0 (2.0f-x); else return 0.0f; } private: float m_wscale; // width scale factor static float b0 (float t) { return t*t*t / 6.0f; } static float b1 (float t) { return 0.5f * t * (t * (1.0f - t) + 1.0f) + 1.0f/6.0f; } }; class FilterBSpline2D : public Filter2D { public: FilterBSpline2D (float width, float height) : Filter2D(width,height), m_wscale(4.0f/width), m_hscale(4.0f/height) { } ~FilterBSpline2D (void) { } float operator() (float x, float y) const { return FilterBSpline1D::bspline1d (x * m_wscale) * FilterBSpline1D::bspline1d (y * m_hscale); } bool separable (void) const { return true; } float xfilt (float x) const { return FilterBSpline1D::bspline1d(x*m_wscale); } float yfilt (float y) const { return FilterBSpline1D::bspline1d(y*m_hscale); } const std::string name (void) const { return "b-spline"; } private: float m_wscale, m_hscale; }; class FilterDisk2D : public Filter2D { public: FilterDisk2D (float width, float height) : Filter2D(width,height) { } ~FilterDisk2D (void) { } float operator() (float x, float y) const { x /= (m_w*0.5f); y /= (m_h*0.5f); return ((x*x+y*y) < 1.0f) ? 1.0f : 0.0f; } const std::string name (void) const { return "disk"; } }; namespace { FilterDesc filter1d_list[] = { // name dim width fixedwidth scalable separable { "box", 1, 1, false, true, true }, { "triangle", 1, 2, false, true, true }, { "gaussian", 1, 2, false, true, true }, { "sharp-gaussian", 1, 2, false, true, true }, { "catrom", 1, 4, true, false, true }, { "blackman-harris", 1, 3, false, true, true }, { "sinc", 1, 4, false, true, true }, { "lanczos3", 1, 6, true, false, true }, { "mitchell", 1, 3, false, true, true }, { "bspline", 1, 4, false, true, true } }; } int Filter1D::num_filters () { return sizeof(filter1d_list)/sizeof(filter1d_list[0]); } void Filter1D::get_filterdesc (int filternum, FilterDesc *filterdesc) { ASSERT (filternum >= 0 && filternum < num_filters()); *filterdesc = filter1d_list[filternum]; } // Filter1D::create is the static method that, given a filter name, // width, and height, returns an allocated and instantiated filter of // the correct implementation. If the name is not recognized, return // NULL. Filter1D * Filter1D::create (const std::string &filtername, float width) { if (filtername == "box") return new FilterBox1D (width); if (filtername == "triangle") return new FilterTriangle1D (width); if (filtername == "gaussian") return new FilterGaussian1D (width); if (filtername == "sharp-gaussian") return new FilterSharpGaussian1D (width); if (filtername == "catmull-rom" || filtername == "catrom") return new FilterCatmullRom1D (width); if (filtername == "blackman-harris") return new FilterBlackmanHarris1D (width); if (filtername == "sinc") return new FilterSinc1D (width); if (filtername == "lanczos3" || filtername == "lanczos") return new FilterLanczos3_1D (width); if (filtername == "mitchell") return new FilterMitchell1D (width); if (filtername == "b-spline" || filtername == "bspline") return new FilterBSpline1D (width); return NULL; } void Filter1D::destroy (Filter1D *filt) { delete filt; } static FilterDesc filter2d_list[] = { // name dim width fixedwidth scalable separable { "box", 2, 1, false, true, true }, { "triangle", 2, 2, false, true, true }, { "gaussian", 2, 2, false, true, true }, { "sharp-gaussian", 2, 2, false, true, true }, { "catrom", 2, 4, true, false, true }, { "blackman-harris", 2, 3, false, true, true }, { "sinc", 2, 4, false, true, true }, { "lanczos3", 2, 6, true, false, true }, { "radial-lanczos3", 2, 6, true, false, false }, { "mitchell", 2, 3, false, true, true }, { "bspline", 2, 4, false, true, true }, { "disk", 2, 1, false, true, false } }; int Filter2D::num_filters () { return sizeof(filter2d_list)/sizeof(filter2d_list[0]); } void Filter2D::get_filterdesc (int filternum, FilterDesc *filterdesc) { ASSERT (filternum >= 0 && filternum < num_filters()); *filterdesc = filter2d_list[filternum]; } // Filter2D::create is the static method that, given a filter name, // width, and height, returns an allocated and instantiated filter of // the correct implementation. If the name is not recognized, return // NULL. Filter2D * Filter2D::create (const std::string &filtername, float width, float height) { if (filtername == "box") return new FilterBox2D (width, height); if (filtername == "triangle") return new FilterTriangle2D (width, height); if (filtername == "gaussian") return new FilterGaussian2D (width, height); if (filtername == "sharp-gaussian") return new FilterSharpGaussian2D (width, height); if (filtername == "catmull-rom" || filtername == "catrom") return new FilterCatmullRom2D (width, height); if (filtername == "blackman-harris") return new FilterBlackmanHarris2D (width, height); if (filtername == "sinc") return new FilterSinc2D (width, height); if (filtername == "lanczos3" || filtername == "lanczos") return new FilterLanczos3_2D (width, height); if (filtername == "radial-lanczos3" || filtername == "radial-lanczos") return new FilterRadialLanczos3_2D (width, height); if (filtername == "mitchell") return new FilterMitchell2D (width, height); if (filtername == "b-spline" || filtername == "bspline") return new FilterBSpline2D (width, height); if (filtername == "disk") return new FilterDisk2D (width, height); return NULL; } void Filter2D::destroy (Filter2D *filt) { delete filt; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/strutil.cpp0000644000175000017500000003352012271062644020771 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 // defining NOMINMAX to prevent problems with std::min/std::max // and std::numeric_limits::min()/std::numeric_limits::max() // when including windows.h #ifdef _MSC_VER # define WIN32_LEAN_AND_MEAN # define VC_EXTRALEAN # ifndef NOMINMAX # define NOMINMAX # endif #endif #include #include #endif #include "dassert.h" #include "strutil.h" #include "ustring.h" #include "string_ref.h" OIIO_NAMESPACE_ENTER { const char * string_ref::c_str() const { // Usual case: either empty, or null-terminated if (m_len == 0) // empty string return ""; else if (m_chars[m_len-1] == 0) // 0-terminated return m_chars; // Rare case: may not be 0-terminated. Bite the bullet and construct a // 0-terminated string. We use ustring as a way to avoid any issues of // who cleans up the allocation, though it means that it will stay in // the ustring table forever. Punt on this for now, it's an edge case // that we need to handle, but is not likely to ever be an issue. return ustring(m_chars, 0, m_len).c_str(); } std::string Strutil::format_raw (const char *fmt, ...) { va_list ap; va_start (ap, fmt); std::string buf = vformat (fmt, ap); va_end (ap); return buf; } std::string Strutil::vformat (const char *fmt, va_list ap) { // Allocate a buffer on the stack that's big enough for us almost // all the time. Be prepared to allocate dynamically if it doesn't fit. size_t size = 1024; char stackbuf[1024]; std::vector dynamicbuf; char *buf = &stackbuf[0]; while (1) { // Try to vsnprintf into our buffer. va_list apsave; #ifdef va_copy va_copy (apsave, ap); #else apsave = ap; #endif int needed = vsnprintf (buf, size, fmt, ap); va_end (ap); // NB. C99 (which modern Linux and OS X follow) says vsnprintf // failure returns the length it would have needed. But older // glibc and current Windows return -1 for failure, i.e., not // telling us how much was needed. if (needed < (int)size && needed >= 0) { // It fit fine so we're done. return std::string (buf, (size_t) needed); } // vsnprintf reported that it wanted to write more characters // than we allotted. So try again using a dynamic buffer. This // doesn't happen very often if we chose our initial size well. size = (needed > 0) ? (needed+1) : (size*2); dynamicbuf.resize (size); buf = &dynamicbuf[0]; #ifdef va_copy va_copy (ap, apsave); #else ap = apsave; #endif } } std::string Strutil::memformat (long long bytes, int digits) { const long long KB = (1<<10); const long long MB = (1<<20); const long long GB = (1<<30); const char *units = "B"; double d = (double)bytes; if (bytes >= GB) { units = "GB"; d = (double)bytes / GB; } else if (bytes >= MB) { units = "MB"; d = (double)bytes / MB; } else if (bytes >= KB) { // Just KB, don't bother with decimalization return format ("%lld KB", (long long)bytes/KB); } else { // Just bytes, don't bother with decimalization return format ("%lld B", (long long)bytes); } return format ("%1.*f %s", digits, d, units); } std::string Strutil::timeintervalformat (double secs, int digits) { const double mins = 60; const double hours = mins * 60; const double days = hours * 24; std::string out; int d = (int) floor (secs / days); secs = fmod (secs, days); int h = (int) floor (secs / hours); secs = fmod (secs, hours); int m = (int) floor (secs / mins); secs = fmod (secs, mins); if (d) out += format ("%dd %dh ", d, h); else if (h) out += format ("%dh ", h); if (m || h || d) out += format ("%dm %1.*fs", m, digits, secs); else out += format ("%1.*fs", digits, secs); return out; } bool Strutil::get_rest_arguments (const std::string &str, std::string &base, std::map &result) { std::string::size_type mark_pos = str.find_first_of ("?"); if (mark_pos == std::string::npos) { base = str; return true; } base = str.substr (0, mark_pos); boost::char_separator sep ("&"); std::string rest = str.substr (mark_pos + 1); boost::tokenizer > rest_tokens (rest, sep); BOOST_FOREACH (std::string keyval, rest_tokens) { mark_pos = keyval.find_first_of ("="); if (mark_pos == std::string::npos) return false; result[keyval.substr (0, mark_pos)] = keyval.substr (mark_pos + 1); } return true; } std::string Strutil::escape_chars (const std::string &unescaped) { std::string s = unescaped; for (size_t i = 0; i < s.length(); ++i) { char c = s[i]; if (c == '\n' || c == '\t' || c == '\v' || c == '\b' || c == '\r' || c == '\f' || c == '\a' || c == '\\' || c == '\"') { s[i] = '\\'; ++i; switch (c) { case '\n' : c = 'n'; break; case '\t' : c = 't'; break; case '\v' : c = 'v'; break; case '\b' : c = 'b'; break; case '\r' : c = 'r'; break; case '\f' : c = 'f'; break; case '\a' : c = 'a'; break; } s.insert (i, &c, 1); } } return s; } std::string Strutil::unescape_chars (const std::string &escaped) { std::string s = escaped; for (size_t i = 0, len = s.length(); i < len; ++i) { if (s[i] == '\\') { char c = s[i+1]; if (c == 'n' || c == 't' || c == 'v' || c == 'b' || c == 'r' || c == 'f' || c == 'a' || c == '\\' || c == '\"') { s.erase (i, 1); --len; switch (c) { case 'n' : s[i] = '\n'; break; case 't' : s[i] = '\t'; break; case 'v' : s[i] = '\v'; break; case 'b' : s[i] = '\b'; break; case 'r' : s[i] = '\r'; break; case 'f' : s[i] = '\f'; break; case 'a' : s[i] = '\a'; break; // default case: the deletion is enough (backslash and quote) } } else if (c >= '0' && c < '8') { // up to 3 octal digits int octalChar = 0; for (int j = 0; j < 3 && c >= '0' && c <= '7'; ++j) { octalChar = 8*octalChar + (c - '0'); s.erase (i, 1); --len; c = i+1 < len ? s[i+1] : '\0'; } s[i] = (char) octalChar; } } } return s; } std::string Strutil::wordwrap (std::string src, int columns, int prefix) { std::ostringstream out; if (columns < prefix+20) return src; // give up, no way to make it wrap columns -= prefix; // now columns is the real width we have to work with while ((int)src.length() > columns) { // break the string in two size_t breakpoint = src.find_last_of (' ', columns); if (breakpoint == std::string::npos) breakpoint = columns; out << src.substr(0, breakpoint) << "\n" << std::string (prefix, ' '); src = src.substr (breakpoint); while (src[0] == ' ') src.erase (0, 1); } out << src; return out.str(); } namespace { static std::locale loc = std::locale::classic(); } bool Strutil::iequals (const std::string &a, const std::string &b) { return boost::algorithm::iequals (a, b, loc); } bool Strutil::iequals (const char *a, const char *b) { return boost::algorithm::iequals (a, b, loc); } bool Strutil::istarts_with (const std::string &a, const std::string &b) { return boost::algorithm::istarts_with (a, b, loc); } bool Strutil::istarts_with (const char *a, const char *b) { return boost::algorithm::istarts_with (a, b, loc); } bool Strutil::iends_with (const std::string &a, const std::string &b) { return boost::algorithm::iends_with (a, b, loc); } bool Strutil::iends_with (const char *a, const char *b) { return boost::algorithm::iends_with (a, b, loc); } bool Strutil::contains (const std::string &a, const std::string &b) { return boost::algorithm::contains (a, b); } bool Strutil::contains (const char *a, const char *b) { return boost::algorithm::contains (a, b); } bool Strutil::icontains (const std::string &a, const std::string &b) { return boost::algorithm::icontains (a, b, loc); } bool Strutil::icontains (const char *a, const char *b) { return boost::algorithm::icontains (a, b, loc); } void Strutil::to_lower (std::string &a) { boost::algorithm::to_lower (a, loc); } void Strutil::to_upper (std::string &a) { boost::algorithm::to_upper (a, loc); } std::string Strutil::strip (const std::string &str, const std::string &chars) { const char *stripchars = (chars.empty() ? " \t\n\r\f\v" : chars.c_str()); size_t b = str.find_first_not_of (stripchars); if (b == std::string::npos) return std::string(""); size_t e = str.find_last_not_of (stripchars); DASSERT (e != std::string::npos); return std::string (str, b, e-b+1); } static void split_whitespace (const std::string &str, std::vector &result, int maxsplit) { // Implementation inspired by Pystring std::string::size_type i, j, len = str.size(); for (i = j = 0; i < len; ) { while (i < len && ::isspace(str[i])) i++; j = i; while (i < len && ! ::isspace(str[i])) i++; if (j < i) { if (--maxsplit <= 0) break; result.push_back (str.substr(j, i - j)); while (i < len && ::isspace(str[i])) i++; j = i; } } if (j < len) result.push_back (str.substr(j, len - j)); } void Strutil::split (const std::string &str, std::vector &result, const std::string &sep, int maxsplit) { // Implementation inspired by Pystring result.clear(); if (maxsplit < 0) maxsplit = std::numeric_limits::max(); if (sep.size() == 0) { split_whitespace (str, result, maxsplit); return; } size_t i = 0, j = 0, len = str.size(), n = sep.size(); while (i+n <= len) { if (str[i] == sep[0] && str.substr(i, n) == sep) { if (--maxsplit <= 0) break; result.push_back (str.substr(j, i - j)); i = j = i + n; } else { i++; } } result.push_back (str.substr(j, len-j)); } std::string Strutil::join (const std::vector &seq, const std::string & str) { // Implementation inspired by Pystring size_t seqlen = seq.size(); if (seqlen == 0) return ""; std::string result (seq[0]); for (size_t i = 1; i < seqlen; ++i) result += str + seq[i]; return result; } #ifdef _WIN32 std::wstring Strutil::utf8_to_utf16 (const std::string& str) { std::wstring native; native.resize(MultiByteToWideChar (CP_UTF8, 0, str.c_str(), -1, NULL, 0)); MultiByteToWideChar (CP_UTF8, 0, str.c_str(), -1, &native[0], (int)native.size()); return native; } std::string Strutil::utf16_to_utf8 (const std::wstring& str) { std::string utf8; utf8.resize(WideCharToMultiByte (CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL)); WideCharToMultiByte (CP_UTF8, 0, str.c_str(), -1, &utf8[0], (int)utf8.size(), NULL, NULL); return utf8; } #endif char * Strutil::safe_strcpy (char *dst, const char *src, size_t size) { if (src) { for (size_t i = 0; i < size; ++i) { if (! (dst[i] = src[i])) return dst; // finished, and copied the 0 character } // If we got here, we have gotten to the maximum length, and still // no terminating 0, so add it! dst[size-1] = 0; } else { dst[0] = 0; } return dst; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/typedesc.cpp0000644000175000017500000003050312271062644021101 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "dassert.h" #include "half.h" #include "ustring.h" #include "strutil.h" #include "typedesc.h" OIIO_NAMESPACE_ENTER { TypeDesc::TypeDesc (const char *typestring) : basetype(UNKNOWN), aggregate(SCALAR), vecsemantics(NOXFORM), reserved(0), arraylen(0) { fromstring (typestring); } namespace { static int basetype_size[] = { 0, // UNKNOWN 0, // VOID sizeof(unsigned char), // UCHAR sizeof(char), // CHAR sizeof(unsigned short), // USHORT sizeof(short), // SHORT sizeof(unsigned int), // UINT sizeof(int), // INT sizeof(unsigned long long), // ULONGLONG sizeof(long long), // LONGLONG sizeof(float)/2, // HALF sizeof(float), // FLOAT sizeof(double), // DOUBLE sizeof(char *), // STRING sizeof(void *) // PTR }; } size_t TypeDesc::basesize () const { DASSERT (sizeof(basetype_size)/sizeof(basetype_size[0]) == TypeDesc::LASTBASE); DASSERT (basetype < TypeDesc::LASTBASE); return basetype_size[basetype]; } namespace { static const char * basetype_name[] = { "unknown", // UNKNOWN "void", // VOID/NONE "uint8", // UCHAR "int8", // CHAR "uint16", // USHORT "int16", // SHORT "uint", // UINT "int", // INT "uint64", // ULONGLONG "int64", // LONGLONG "half", // HALF "float", // FLOAT "double", // DOUBLE "string", // STRING "pointer" // PTR }; static const char * basetype_code[] = { "unknown", // UNKNOWN "void", // VOID/NONE "uc", // UCHAR "c", // CHAR "us", // USHORT "s", // SHORT "ui", // UINT "i", // INT "ull", // ULONGLONG "ll", // LONGLONG "h", // HALF "f", // FLOAT "d", // DOUBLE "str", // STRING "ptr" // PTR }; } const char * TypeDesc::c_str () const { // FIXME : how about a per-thread cache of the last one or two, so // we don't have to re-assemble strings all the time? // Timecode and Keycode are hard coded if (basetype == UINT && vecsemantics == TIMECODE && arraylen == 2) return ustring("timecode").c_str(); else if (basetype == INT && vecsemantics == KEYCODE && arraylen == 7) return ustring("keycode").c_str(); std::string result; if (aggregate == SCALAR) result = basetype_name[basetype]; else if (aggregate == MATRIX44 && basetype == FLOAT) result = "matrix"; else if (vecsemantics == NOXFORM) { const char *agg = ""; switch (aggregate) { case VEC2 : agg = "vec2"; break; case VEC3 : agg = "vec3"; break; case VEC4 : agg = "vec4"; break; case MATRIX44 : agg = "matrix44"; break; } result = std::string (agg) + basetype_code[basetype]; } else { // Special names for vector semantics const char *vec = ""; switch (vecsemantics) { case COLOR : vec = "color"; break; case POINT : vec = "point"; break; case VECTOR : vec = "vector"; break; case NORMAL : vec = "normal"; break; default: ASSERT (0 && "Invalid vector semantics"); } const char *agg = ""; switch (aggregate) { case VEC2 : agg = "2"; break; case VEC4 : agg = "4"; break; case MATRIX44 : agg = "matrix"; break; } result = std::string (vec) + std::string (agg); if (basetype != FLOAT) result += basetype_code[basetype]; } if (arraylen > 0) result += Strutil::format ("[%d]", arraylen); else if (arraylen < 0) result += "[]"; return ustring(result).c_str(); } // Copy src into dst until you hit the end, find a delimiter charcter, // or have copied maxlen-1 characters, whichever comes first. Add a // terminating null charcter. Return the number of characters copied. inline size_t copy_until (const char *src, const char *delim, char *dst, size_t maxlen) { size_t i = 0; while (src[i] && i < maxlen-1) { bool found_delim = false; for (int d = 0; delim[d]; ++d) if (src[i] == delim[d]) found_delim = true; if (found_delim) break; dst[i] = src[i]; ++i; } dst[i] = 0; return i; } size_t TypeDesc::fromstring (const char *typestring) { TypeDesc t; size_t len = 0; if (! typestring) return 0; // The first "word" should be a type name. char type[16]; len = copy_until (typestring, " [", type, sizeof(type)); // Check the scalar types in our table above for (int i = 0; i < LASTBASE; ++i) { if (! strcmp (type, basetype_name[i])) { t.basetype = i; break; } } // Some special case names for aggregates if (t.basetype != UNKNOWN) { // already solved } else if (! strcmp (type, "color")) t = TypeColor; else if (! strcmp (type, "point")) t = TypePoint; else if (! strcmp (type, "vector")) t = TypeVector; else if (! strcmp (type, "normal")) t = TypeNormal; else if (! strcmp (type, "matrix")) t = TypeMatrix; else { return 0; // unknown } // Is there an array length following the type name? while (typestring[len] == ' ') ++len; if (typestring[len] == '[') { ++len; while (typestring[len] == ' ') ++len; if (typestring[len] == ']') { // '[]' indicates array of unknown len t.arraylen = -1; } else { t.arraylen = atoi (typestring+len); while ((typestring[len] >= '0' && typestring[len] <= '9') || typestring[len] == ' ') ++len; } if (typestring[len] == ']') ++len; else return 0; } *this = t; return len; } template inline std::string sprintt (TypeDesc type, const char *format, const char *aggregate_delim, const char *aggregate_sep, const char *array_delim, const char *array_sep, T *v) { std::string val; if (type.arraylen) val += array_delim[0]; const size_t n = type.arraylen ? type.arraylen : 1; for (size_t i = 0; i < n; ++i) { if (type.aggregate > 1) val += aggregate_delim[0]; for (int j = 0; j < (int)type.aggregate; ++j, ++v) { val += Strutil::format (format, *v); if (type.aggregate > 1 && j < type.aggregate - 1) val += aggregate_sep; } if (type.aggregate > 1) val += aggregate_delim[1]; if (i < n - 1) val += array_sep; } if (type.arraylen) val += array_delim[1]; return val; } std::string tostring (TypeDesc type, const void *data, const char *float_fmt, const char *string_fmt, const char *aggregate_delim, const char *aggregate_sep, const char *array_delim, const char *array_sep) { // Perhaps there is a way to use CType<> with a dynamic argument? switch (type.basetype) { case TypeDesc::UNKNOWN: return sprintt (type, "%p", aggregate_delim, aggregate_sep, array_delim, array_sep, (void **)data); case TypeDesc::NONE: return sprintt (type, "None", aggregate_delim, aggregate_sep, array_delim, array_sep, (void **)data); case TypeDesc::UCHAR: return sprintt (type, "%uhh", aggregate_delim, aggregate_sep, array_delim, array_sep, (unsigned char *)data); case TypeDesc::CHAR: return sprintt (type, "%dhh", aggregate_delim, aggregate_sep, array_delim, array_sep, (char *)data); case TypeDesc::USHORT: return sprintt (type, "%uh", aggregate_delim, aggregate_sep, array_delim, array_sep, (unsigned short *)data); case TypeDesc::SHORT: return sprintt (type, "%dh", aggregate_delim, aggregate_sep, array_delim, array_sep, (short *)data); case TypeDesc::UINT: return sprintt (type, "%u", aggregate_delim, aggregate_sep, array_delim, array_sep, (unsigned int *)data); case TypeDesc::INT: return sprintt (type, "%d", aggregate_delim, aggregate_sep, array_delim, array_sep, (int *)data); case TypeDesc::ULONGLONG: return sprintt (type, "%ull", aggregate_delim, aggregate_sep, array_delim, array_sep, (unsigned long long *)data); case TypeDesc::LONGLONG: return sprintt (type, "%dll", aggregate_delim, aggregate_sep, array_delim, array_sep, (long long *)data); case TypeDesc::HALF: return sprintt (type, float_fmt, aggregate_delim, aggregate_sep, array_delim, array_sep, (half *) data); case TypeDesc::FLOAT: return sprintt (type, float_fmt, aggregate_delim, aggregate_sep, array_delim, array_sep, (float *)data); case TypeDesc::DOUBLE: return sprintt (type, float_fmt, aggregate_delim, aggregate_sep, array_delim, array_sep, (double *)data); case TypeDesc::STRING: return sprintt (type, string_fmt, aggregate_delim, aggregate_sep, array_delim, array_sep, (char **)data); case TypeDesc::PTR: return sprintt (type, "%p", aggregate_delim, aggregate_sep, array_delim, array_sep, (void **)data); default: return ""; } } const TypeDesc TypeDesc::TypeFloat (TypeDesc::FLOAT); const TypeDesc TypeDesc::TypeColor (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::COLOR); const TypeDesc TypeDesc::TypePoint (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::POINT); const TypeDesc TypeDesc::TypeVector (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::VECTOR); const TypeDesc TypeDesc::TypeNormal (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::NORMAL); const TypeDesc TypeDesc::TypeMatrix (TypeDesc::FLOAT,TypeDesc::MATRIX44); const TypeDesc TypeDesc::TypeString (TypeDesc::STRING); const TypeDesc TypeDesc::TypeInt (TypeDesc::INT); const TypeDesc TypeDesc::TypeTimeCode (TypeDesc::UINT, TypeDesc::SCALAR, TypeDesc::TIMECODE, 2); const TypeDesc TypeDesc::TypeKeyCode (TypeDesc::INT, TypeDesc::SCALAR, TypeDesc::KEYCODE, 7); } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/tbb_misc.cpp0000644000175000017500000001156512271062644021052 0ustar mfvmfv/* Copyright 2005-2009 Intel Corporation. All Rights Reserved. This file is part of Threading Building Blocks. Threading Building Blocks is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Threading Building Blocks 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 for more details. You should have received a copy of the GNU General Public License along with Threading Building Blocks; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ // Source file for miscellaneous entities that are infrequently referenced by // an executing program. #include "tbb/tbb_stddef.h" #include "tbb/tbb_machine.h" #include "tbb/tbb_assert_impl.h" #include "tbb/tbb_misc.h" #include #include #include #if defined(__EXCEPTIONS) || defined(_CPPUNWIND) || defined(__SUNPRO_CC) #include "tbb/tbb_exception.h" #include // std::string is used to construct runtime_error #include #endif using namespace std; #include "tbb/tbb_machine.h" namespace tbb { namespace internal { #if defined(__EXCEPTIONS) || defined(_CPPUNWIND) || defined(__SUNPRO_CC) // The above preprocessor symbols are defined by compilers when exception handling is enabled. // However, in some cases it could be disabled for this file. void handle_perror( int error_code, const char* what ) { char buf[128]; sprintf(buf,"%s: ",what); char* end = strchr(buf,0); size_t n = buf+sizeof(buf)-end; strncpy( end, strerror( error_code ), n ); // Ensure that buffer ends in terminator. buf[sizeof(buf)-1] = 0; throw runtime_error(buf); } void throw_bad_last_alloc_exception_v4() { throw bad_last_alloc(); } #endif //__EXCEPTIONS || _CPPUNWIND bool GetBoolEnvironmentVariable( const char * name ) { if( const char* s = getenv(name) ) return strcmp(s,"0") != 0; return false; } #include "tbb/tbb_version.h" /** The leading "\0" is here so that applying "strings" to the binary delivers a clean result. */ static const char VersionString[] = "\0" TBB_VERSION_STRINGS; static bool PrintVersionFlag = false; void PrintVersion() { PrintVersionFlag = true; fputs(VersionString+1,stderr); } void PrintExtraVersionInfo( const char* category, const char* description ) { if( PrintVersionFlag ) fprintf(stderr, "%s: %s\t%s\n", "TBB", category, description ); } void PrintRMLVersionInfo( void* arg, const char* server_info ) { PrintExtraVersionInfo( server_info, (const char *)arg ); } } // namespace internal extern "C" int TBB_runtime_interface_version() { return TBB_INTERFACE_VERSION; } } // namespace tbb #if !__TBB_RML_STATIC #if __TBB_x86_32 #include "tbb/atomic.h" // in MSVC environment, int64_t defined in tbb::internal namespace only (see tbb_stddef.h) #if _MSC_VER using tbb::internal::int64_t; #endif //! Warn about 8-byte store that crosses a cache line. extern "C" void __TBB_machine_store8_slow_perf_warning( volatile void *ptr ) { // Report run-time warning unless we have already recently reported warning for that address. const unsigned n = 4; static tbb::atomic cache[n]; static tbb::atomic k; for( unsigned i=0; i(ptr); tbb::internal::runtime_warning( "atomic store on misaligned 8-byte location %p is slow", ptr ); done:; } //! Handle 8-byte store that crosses a cache line. extern "C" void __TBB_machine_store8_slow( volatile void *ptr, int64_t value ) { for( tbb::internal::atomic_backoff b;; b.pause() ) { int64_t tmp = *(int64_t*)ptr; if( __TBB_machine_cmpswp8(ptr,value,tmp)==tmp ) break; } } #endif /* __TBB_x86_32 */ #endif /* !__TBB_RML_STATIC */ #if __TBB_ipf extern "C" intptr_t __TBB_machine_lockbyte( volatile unsigned char& flag ) { if ( !__TBB_TryLockByte(flag) ) { tbb::internal::atomic_backoff b; do { b.pause(); } while ( !__TBB_TryLockByte(flag) ); } return 0; } #endif openimageio-1.3.12~dfsg0.orig/src/libutil/sysutil.cpp0000644000175000017500000002400212271062644020772 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #ifdef __linux__ # include # include # include #endif #if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) # include # include # include # include # include # include #endif #ifdef __APPLE__ # include # include # include # include # include # include #endif #ifdef _WIN32 # include "osdep.h" # include #else # include #endif #ifdef __GNU__ # include # include #endif #include "dassert.h" #include "sysutil.h" OIIO_NAMESPACE_ENTER { using namespace Sysutil; size_t Sysutil::memory_used (bool resident) { #if defined(__linux__) #if 0 // doesn't seem to work? struct rusage ru; int ret = getrusage (RUSAGE_SELF, &ru); return (size_t)ru.ru_maxrss * (size_t)1024; #else // Ugh, getrusage doesn't work well on Linux. Try grabbing info // directly from the /proc pseudo-filesystem. Reading from // /proc/self/statm gives info on your own process, as one line of // numbers that are: virtual mem program size, resident set size, // shared pages, text/code, data/stack, library, dirty pages. The // mem sizes should all be multiplied by the page size. size_t size = 0; FILE *file = fopen("/proc/self/statm", "r"); if (file) { unsigned long vm = 0, rss = 0; int n = fscanf (file, "%lu %lu", &vm, &rss); if (n == 2) size = size_t(resident ? rss : vm); size *= getpagesize(); fclose (file); } return size; #endif #elif defined(__APPLE__) // Inspired by: // http://miknight.blogspot.com/2005/11/resident-set-size-in-mac-os-x.html struct task_basic_info t_info; mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; task_info(current_task(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count); size_t size = (resident ? t_info.resident_size : t_info.virtual_size); return size; #elif defined(_WIN32) // According to MSDN... PROCESS_MEMORY_COUNTERS counters; if (GetProcessMemoryInfo (GetCurrentProcess(), &counters, sizeof (counters))) return counters.PagefileUsage; else return 0; #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) // FIXME -- does somebody know a good method for figuring this out for // FreeBSD? return 0; // Punt #else // No idea what platform this is ASSERT (0 && "Need to implement Sysutil::memory_used on this platform"); return 0; // Punt #endif } size_t Sysutil::physical_memory () { #if defined(__linux__) size_t size = 0; FILE *file = fopen ("/proc/meminfo", "r"); if (file) { char buf[1024]; while (fgets (buf, sizeof(buf), file)) { if (! strncmp (buf, "MemTotal:", 9)) { size = 1024 * (size_t) strtol (buf+9, NULL, 10); break; } } fclose (file); } return size; #elif defined(__APPLE__) // man 3 sysctl ...or... // https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/sysctl.3.html // http://stackoverflow.com/questions/583736/determine-physical-mem-size-programmatically-on-osx int mib[2] = { CTL_HW, HW_MEMSIZE }; int64_t physical_memory; size_t length = sizeof(physical_memory); sysctl (mib, 2, &physical_memory, &length, NULL, 0); return size_t(physical_memory); #elif defined(_WIN32) // According to MSDN // (http://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx MEMORYSTATUSEX statex; statex.dwLength = sizeof (statex); GlobalMemoryStatusEx (&statex); return size_t (statex.ullTotalPhys); // Total physical memory // N.B. Other fields nice to know (in bytes, except for dwMemoryLoad): // statex.dwMemoryLoad Percent of memory in use // statex.ullAvailPhys Free physical memory // statex.ullTotalPageFile Total size of paging file // statex.ullAvailPageFile Free mem in paging file // statex.ullTotalVirtual Total virtual memory // statex.ullAvailVirtual Free virtual memory #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) // man 3 sysctl ...or... // http://www.freebsd.org/cgi/man.cgi?query=sysctl&sektion=3 // FIXME -- Does this accept a size_t? Or only an int? I can't // seem to find an online resource that indicates that FreeBSD has a // HW_MEMESIZE like Linux and OSX have, or a HW_PHYSMEM64 like // OpenBSD has. int mib[2] = { CTL_HW, HW_PHYSMEM }; size_t physical_memory; size_t length = sizeof(physical_memory); sysctl (mib, 2, &physical_memory, &length, NULL, 0); return physical_memory; #else // No idea what platform this is ASSERT (0 && "Need to implement Sysutil::physical_memory on this platform"); return 0; // Punt #endif } void Sysutil::get_local_time (const time_t *time, struct tm *converted_time) { #ifdef _MSC_VER localtime_s (converted_time, time); #else localtime_r (time, converted_time); #endif } std::string Sysutil::this_program_path () { char filename[10240]; filename[0] = 0; #if defined(__linux__) unsigned int size = sizeof(filename); int r = readlink ("/proc/self/exe", filename, size); ASSERT(r < int(size)); // user won't get the right answer if the filename is too long to store if (r > 0) filename[r] = 0; // readlink does not fill in the 0 byte #elif defined(__APPLE__) // For info: 'man 3 dyld' unsigned int size = sizeof(filename); int r = _NSGetExecutablePath (filename, &size); if (r == 0) r = size; #elif defined(_WIN32) // According to MSDN... unsigned int size = sizeof(filename); int r = GetModuleFileName (NULL, filename, size); #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) int mib[4]; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1; size_t cb = sizeof(filename); int r=1; sysctl(mib, 4, filename, &cb, NULL, 0); #elif defined(__GNU__) int r = 0; #else // No idea what platform this is ASSERT (0); #endif if (r > 0) return std::string (filename); return std::string(); // Couldn't figure it out } void Sysutil::usleep (unsigned long useconds) { #ifdef _WIN32 Sleep (useconds/1000); // Win32 Sleep() is milliseconds, not micro #else ::usleep (useconds); // *nix usleep() is in microseconds #endif } int Sysutil::terminal_columns () { int columns = 80; // a decent guess, if we have nothing more to go on #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__) struct winsize w; ioctl (0, TIOCGWINSZ, &w); columns = w.ws_col; #elif defined(_WIN32) // FIXME: is there a Windows equivalent? #endif return columns; } bool #if !defined(_MSC_VER) Sysutil::put_in_background (int argc, char* argv[]) #else Sysutil::put_in_background (int, char* []) #endif { // You would think that this would be sufficient: // pid_t pid = fork (); // if (pid < 0) // Some kind of error, we were unable to background // return false; // if (pid == 0) // return true; // This is the child process, so continue with life // // Otherwise, this is the parent process, so terminate // exit (0); // But it's not. On OS X, it's not safe to fork() if your app is linked // against certain libraries or frameworks. So the only thing that I // think is safe is to exec a new process. // Another solution is this: // daemon (1, 1); // But it suffers from the same problem on OS X, and seems to just be // a wrapper for fork. #if defined(__linux__) || defined(__GLIBC__) // Simplest case: // daemon returns 0 if successful, thus return true if successful return daemon (1, 1) == 0; #endif #ifdef __APPLE__ std::string newcmd = std::string(argv[0]) + " -F"; for (int i = 1; i < argc; ++i) { newcmd += " \""; newcmd += argv[i]; newcmd += "\""; } newcmd += " &"; if (system (newcmd.c_str()) != -1) exit (0); return true; #endif #ifdef WIN32 return true; #endif // Otherwise, we don't know what to do return false; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/CMakeLists.txt0000644000175000017500000000052012271062644021311 0ustar mfvmfvset (libutil_srcs argparse.cpp errorhandler.cpp filesystem.cpp filter.cpp hashes.cpp paramlist.cpp plugin.cpp SHA1.cpp strutil.cpp sysutil.cpp typedesc.cpp ustring.cpp pystring.cpp) add_library (util SHARED ${libutil_srcs}) target_link_libraries (util ${Boost_LIBRARIES}) oiio_install_targets (util) openimageio-1.3.12~dfsg0.orig/src/libutil/SHA1.cpp0000644000175000017500000001717112271062644017763 0ustar mfvmfv/* 100% free public domain implementation of the SHA-1 algorithm by Dominik Reichl Web: http://www.dominik-reichl.de/ See header file for version history. */ // If compiling with MFC, you might want to add #include "StdAfx.h" #include "SHA1.h" #include "hash.h" #include "dassert.h" #ifdef SHA1_UTILITY_FUNCTIONS #define SHA1_MAX_FILE_BUFFER 8000 #endif // Rotate x bits to the left #ifndef ROL32 #ifdef _MSC_VER #define ROL32(_val32,_nBits) _rotl(_val32,_nBits) #else #define ROL32(_val32,_nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits)))) #endif #endif #ifdef SHA1_LITTLE_ENDIAN #define SHABLK0(i) (m_block->l[i] = \ (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF)) #else #define SHABLK0(i) (m_block->l[i]) #endif #define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \ ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1)) // SHA-1 rounds #define _R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);} #define _R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);} #define _R2(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5);w=ROL32(w,30);} #define _R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5);w=ROL32(w,30);} #define _R4(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5);w=ROL32(w,30);} OIIO_NAMESPACE_ENTER { SHA1::SHA1 (const void *data, size_t size) { m_csha1 = new CSHA1; m_final = false; append (data, size); } SHA1::~SHA1 () { delete m_csha1; } void SHA1::append (const void *data, size_t size) { ASSERT (!m_final && "Called SHA1() after already getting digest"); if (data && size) m_csha1->Update ((const unsigned char *)data, (unsigned int)size); } void SHA1::gethash (Hash &h) { if (! m_final) { m_csha1->Final (); m_final = true; } m_csha1->GetHash (h.hash); } std::string SHA1::digest () { if (! m_final) { m_csha1->Final (); m_final = true; } std::string d; m_csha1->ReportHashStl (d, CSHA1::REPORT_HEX_SHORT); return d; } CSHA1::CSHA1() { m_block = (SHA1_WORKSPACE_BLOCK*)m_workspace; Reset(); } CSHA1::~CSHA1() { Reset(); } void CSHA1::Reset() { // SHA1 initialization constants m_state[0] = 0x67452301; m_state[1] = 0xEFCDAB89; m_state[2] = 0x98BADCFE; m_state[3] = 0x10325476; m_state[4] = 0xC3D2E1F0; m_count[0] = 0; m_count[1] = 0; } void CSHA1::Transform(UINT_32* pState, const UINT_8* pBuffer) { UINT_32 a = pState[0], b = pState[1], c = pState[2], d = pState[3], e = pState[4]; memcpy(m_block, pBuffer, 64); // 4 rounds of 20 operations each. Loop unrolled. _R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3); _R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7); _R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11); _R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15); _R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19); _R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23); _R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27); _R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31); _R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35); _R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39); _R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43); _R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47); _R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51); _R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55); _R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59); _R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63); _R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67); _R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71); _R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75); _R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79); // Add the working vars back into state pState[0] += a; pState[1] += b; pState[2] += c; pState[3] += d; pState[4] += e; // Wipe variables #ifdef SHA1_WIPE_VARIABLES a = b = c = d = e = 0; #endif } // Use this function to hash in binary data and strings void CSHA1::Update(const UINT_8* pbData, UINT_32 uLen) { UINT_32 j = ((m_count[0] >> 3) & 0x3F); if((m_count[0] += (uLen << 3)) < (uLen << 3)) ++m_count[1]; // Overflow m_count[1] += (uLen >> 29); UINT_32 i; if((j + uLen) > 63) { i = 64 - j; memcpy(&m_buffer[j], pbData, i); Transform(m_state, m_buffer); for( ; (i + 63) < uLen; i += 64) Transform(m_state, &pbData[i]); j = 0; } else i = 0; if((uLen - i) != 0) memcpy(&m_buffer[j], &pbData[i], uLen - i); } #ifdef SHA1_UTILITY_FUNCTIONS // Hash in file contents bool CSHA1::HashFile(const TCHAR* tszFileName) { if(tszFileName == NULL) return false; FILE* fpIn = _tfopen(tszFileName, _T("rb")); if(fpIn == NULL) return false; _fseeki64(fpIn, 0, SEEK_END); const INT_64 lFileSize = _ftelli64(fpIn); _fseeki64(fpIn, 0, SEEK_SET); const INT_64 lMaxBuf = SHA1_MAX_FILE_BUFFER; UINT_8 vData[SHA1_MAX_FILE_BUFFER]; INT_64 lRemaining = lFileSize; while(lRemaining > 0) { const size_t uMaxRead = static_cast((lRemaining > lMaxBuf) ? lMaxBuf : lRemaining); const size_t uRead = fread(vData, 1, uMaxRead, fpIn); if(uRead == 0) { fclose(fpIn); return false; } Update(vData, static_cast(uRead)); lRemaining -= static_cast(uRead); } fclose(fpIn); return (lRemaining == 0); } #endif void CSHA1::Final() { UINT_32 i; UINT_8 finalcount[8]; for(i = 0; i < 8; ++i) finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)] >> ((3 - (i & 3)) * 8) ) & 255); // Endian independent Update((UINT_8*)"\200", 1); while ((m_count[0] & 504) != 448) Update((UINT_8*)"\0", 1); Update(finalcount, 8); // Cause a SHA1Transform() for(i = 0; i < 20; ++i) m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 0xFF); // Wipe variables for security reasons #ifdef SHA1_WIPE_VARIABLES memset(m_buffer, 0, 64); memset(m_state, 0, 20); memset(m_count, 0, 8); memset(finalcount, 0, 8); Transform(m_state, m_buffer); #endif } #ifdef SHA1_UTILITY_FUNCTIONS // Get the final hash as a pre-formatted string bool CSHA1::ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType) const { if(tszReport == NULL) return false; TCHAR tszTemp[16]; if((rtReportType == REPORT_HEX) || (rtReportType == REPORT_HEX_SHORT)) { _sntprintf(tszTemp, 15, _T("%02X"), m_digest[0]); _tcscpy(tszReport, tszTemp); const TCHAR* lpFmt = ((rtReportType == REPORT_HEX) ? _T(" %02X") : _T("%02X")); for(size_t i = 1; i < 20; ++i) { _sntprintf(tszTemp, 15, lpFmt, m_digest[i]); _tcscat(tszReport, tszTemp); } } else if(rtReportType == REPORT_DIGIT) { _sntprintf(tszTemp, 15, _T("%u"), m_digest[0]); _tcscpy(tszReport, tszTemp); for(size_t i = 1; i < 20; ++i) { _sntprintf(tszTemp, 15, _T(" %u"), m_digest[i]); _tcscat(tszReport, tszTemp); } } else return false; return true; } #endif #ifdef SHA1_STL_FUNCTIONS bool CSHA1::ReportHashStl(std::basic_string& strOut, REPORT_TYPE rtReportType) const { TCHAR tszOut[84]; const bool bResult = ReportHash(tszOut, rtReportType); if(bResult) strOut = tszOut; return bResult; } #endif // Get the raw message digest bool CSHA1::GetHash(UINT_8* pbDest) const { if(pbDest == NULL) return false; memcpy(pbDest, m_digest, 20); return true; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/libutil/paramlist.cpp0000644000175000017500000000626012271062644021260 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include "dassert.h" #include "ustring.h" #include "paramlist.h" OIIO_NAMESPACE_ENTER { void ParamValue::init_noclear (ustring _name, TypeDesc _type, int _nvalues, const void *_value, bool _copy) { m_name = _name; m_type = _type; m_nvalues = _nvalues; m_interp = INTERP_CONSTANT; size_t n = (size_t) (m_nvalues * m_type.numelements()); size_t size = (size_t) (m_nvalues * m_type.size()); bool small = (size <= sizeof(m_data)); if (_copy || small) { if (small) { if (_value) memcpy (&m_data, _value, size); else m_data.localval = 0; m_copy = false; m_nonlocal = false; } else { m_data.ptr = malloc (size); if (_value) memcpy ((char *)m_data.ptr, _value, size); else memset ((char *)m_data.ptr, 0, size); m_copy = true; m_nonlocal = true; } if (m_type.basetype == TypeDesc::STRING) { ustring *u = (ustring *) data(); for (size_t i = 0; i < n; ++i) u[i] = ustring(u[i].c_str()); } } else { // Big enough to warrant a malloc, but the caller said don't // make a copy m_data.ptr = _value; m_copy = false; m_nonlocal = true; } } void ParamValue::clear_value () { if (m_copy && m_nonlocal && m_data.ptr) free ((void *)m_data.ptr); m_data.ptr = NULL; m_copy = false; m_nonlocal = false; } } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/python/0000755000175000017500000000000012271062644016431 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/python/py_imagespec.cpp0000644000175000017500000003501612271062644021607 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "py_oiio.h" namespace PyOpenImageIO { using namespace boost::python; // Accessor for channelnames, converts a vector to a tuple static object ImageSpec_get_channelnames(const ImageSpec& spec) { size_t size = spec.channelnames.size(); PyObject* result = PyTuple_New(size); for (size_t i = 0; i < size; ++i) { #if PY_MAJOR_VERSION >= 3 PyObject* name = PyUnicode_FromString(spec.channelnames[i].c_str()); #else PyObject* name = PyString_FromString(spec.channelnames[i].c_str()); #endif PyTuple_SetItem(result, i, name); } return object(handle<>(result)); } // Mutator for channelnames, sets a vector using a tuple static void ImageSpec_set_channelnames(ImageSpec& spec, const tuple& channelnames) { const size_t length = len(channelnames); spec.channelnames.resize(length); for (size_t i = 0; i < length; ++i) { extract e (channelnames[i]); spec.channelnames[i] = e.check() ? e() : std::string(); } } // Accessor for channelformats, converts a vector to a tuple // of ints holding the BASETYPE. static object ImageSpec_get_channelformats(const ImageSpec& spec) { size_t size = spec.channelformats.size(); PyObject* result = PyTuple_New(size); for (size_t i = 0; i < size; ++i) PyTuple_SetItem(result, i, PyInt_FromLong((long)spec.channelformats[i].basetype)); return object(handle<>(result)); } // Mutator for channelformats, initialized using a tuple whose int entries // give the BASETYPE values. static void ImageSpec_set_channelformats(ImageSpec& spec, const tuple& channelformats) { const size_t length = len(channelformats); spec.channelformats.resize(length); for (size_t i = 0; i < length; ++i) { extract e (channelformats[i]); int base = e.check() ? e() : 0; spec.channelformats[i] = (TypeDesc::BASETYPE)base; } } #if 0 // In this version we lose some functionality - all the inputs are // assumed to have been autostride. static object ImageSpec_auto_stride_1(const TypeDesc& format, int nchannels, int width, int height) { stride_t x = AutoStride, y = AutoStride, z = AutoStride; ImageSpec::auto_stride(x, y, z, format, nchannels, width, height); return object(handle<>(Py_BuildValue("(iii)", x, y, z))); } // xstride is assumed to have been AutoStride. static stride_t ImageSpec_auto_stride_2(const TypeDesc& format, int nchannels) { stride_t x = AutoStride; ImageSpec::auto_stride(x, format, nchannels); return x; } #endif static stride_t ImageSpec_channel_bytes_1(ImageSpec& spec) { return spec.channel_bytes (); } static stride_t ImageSpec_channel_bytes_2(ImageSpec& spec, int chan) { return spec.channel_bytes (chan); } static stride_t ImageSpec_channel_bytes_3(ImageSpec& spec, int chan, bool native) { return spec.channel_bytes (chan, native); } static stride_t ImageSpec_pixel_bytes_0(ImageSpec& spec) { return spec.pixel_bytes (); } static stride_t ImageSpec_pixel_bytes_1(ImageSpec& spec, bool native) { return spec.pixel_bytes (native); } static stride_t ImageSpec_pixel_bytes_2(ImageSpec& spec, int chbegin, int chend) { return spec.pixel_bytes (chbegin, chend); } static stride_t ImageSpec_pixel_bytes_3(ImageSpec& spec, int chbegin, int chend, bool native) { return spec.pixel_bytes (chbegin, chend, native); } BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageSpec_scanline_bytes_overloads, scanline_bytes, 0, 1) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageSpec_tile_bytes_overloads, tile_bytes, 0, 1) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageSpec_image_bytes_overloads, image_bytes, 0, 1) static void ImageSpec_set_format_2(ImageSpec& spec, TypeDesc::BASETYPE basetype) { spec.set_format (basetype); } static void ImageSpec_attribute_int (ImageSpec& spec, const std::string &name, int val) { spec.attribute (name, val); } static void ImageSpec_attribute_float (ImageSpec& spec, const std::string &name, float val) { spec.attribute (name, val); } static void ImageSpec_attribute_string (ImageSpec& spec, const std::string &name, const std::string &val) { spec.attribute (name, val); } static void ImageSpec_attribute_typed (ImageSpec& spec, const std::string &name, TypeDesc type, object &obj) { if (type.basetype == TypeDesc::INT) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) spec.attribute (name, type, &vals[0]); return; } if (type.basetype == TypeDesc::FLOAT) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) spec.attribute (name, type, &vals[0]); return; } if (type.basetype == TypeDesc::STRING) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) { std::vector u; for (size_t i = 0, e = vals.size(); i < e; ++i) u.push_back (ustring(vals[i])); spec.attribute (name, type, &u[0]); } return; } } static void ImageSpec_attribute_tuple_typed (ImageSpec& spec, const std::string &name, TypeDesc type, tuple &obj) { if (type.basetype == TypeDesc::INT) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) spec.attribute (name, type, &vals[0]); return; } if (type.basetype == TypeDesc::FLOAT) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) spec.attribute (name, type, &vals[0]); return; } if (type.basetype == TypeDesc::STRING) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) { std::vector u; for (size_t i = 0, e = vals.size(); i < e; ++i) u.push_back (ustring(vals[i])); spec.attribute (name, type, &u[0]); } return; } } static object ImageSpec_get_attribute_typed (const ImageSpec& spec, const std::string &name, TypeDesc type) { const ImageIOParameter *p = spec.find_attribute (name, type); if (!p) return object(); // None type = p->type(); if (type.basetype == TypeDesc::INT) { return C_to_val_or_tuple ((const int *)p->data(), type, PyInt_FromLong); } if (type.basetype == TypeDesc::FLOAT) { return C_to_val_or_tuple ((const float *)p->data(), type, PyFloat_FromDouble); } if (type.basetype == TypeDesc::STRING) { return C_to_val_or_tuple ((const char **)p->data(), type, PyString_FromString); } return object(); } static object ImageSpec_get_attribute_untyped (const ImageSpec& spec, const std::string &name) { return ImageSpec_get_attribute_typed (spec, name, TypeDesc::UNKNOWN); } static int ImageSpec_get_int_attribute (const ImageSpec& spec, const char *name) { return spec.get_int_attribute (name); } static int ImageSpec_get_int_attribute_d (const ImageSpec& spec, const char *name, int defaultval) { return spec.get_int_attribute (name, defaultval); } static float ImageSpec_get_float_attribute (const ImageSpec& spec, const char *name) { return spec.get_float_attribute (name); } static float ImageSpec_get_float_attribute_d (const ImageSpec& spec, const char *name, float defaultval) { return spec.get_float_attribute (name, defaultval); } static std::string ImageSpec_get_string_attribute (const ImageSpec& spec, const char *name) { return spec.get_string_attribute (name); } static std::string ImageSpec_get_string_attribute_d (const ImageSpec& spec, const char *name, const char *defaultval) { return spec.get_string_attribute (name, defaultval); } void declare_imagespec() { class_("ImageSpec") .def_readwrite("x", &ImageSpec::x) .def_readwrite("y", &ImageSpec::y) .def_readwrite("z", &ImageSpec::z) .def_readwrite("width", &ImageSpec::width) .def_readwrite("height", &ImageSpec::height) .def_readwrite("depth", &ImageSpec::depth) .def_readwrite("full_x", &ImageSpec::full_x) .def_readwrite("full_y", &ImageSpec::full_y) .def_readwrite("full_z", &ImageSpec::full_z) .def_readwrite("full_width", &ImageSpec::full_width) .def_readwrite("full_height", &ImageSpec::full_height) .def_readwrite("full_depth", &ImageSpec::full_depth) .def_readwrite("tile_width", &ImageSpec::tile_width) .def_readwrite("tile_height", &ImageSpec::tile_height) .def_readwrite("tile_depth", &ImageSpec::tile_depth) .def_readwrite("format", &ImageSpec::format) //TypeDesc .def_readwrite("nchannels", &ImageSpec::nchannels) .add_property("channelnames", &ImageSpec_get_channelnames, &ImageSpec_set_channelnames) .add_property("channelformats", &ImageSpec_get_channelformats, &ImageSpec_set_channelformats) .def_readwrite("alpha_channel", &ImageSpec::alpha_channel) .def_readwrite("z_channel", &ImageSpec::z_channel) .def_readwrite("deep", &ImageSpec::deep) .def_readwrite("quant_black", &ImageSpec::quant_black) .def_readwrite("quant_white", &ImageSpec::quant_white) .def_readwrite("quant_min", &ImageSpec::quant_min) .def_readwrite("quant_max", &ImageSpec::quant_max) .add_property("extra_attribs", make_getter(&ImageSpec::extra_attribs))//ImageIOParameterList .def(init()) .def(init()) .def(init()) .def(init()) .def(init()) .def("set_format", &ImageSpec::set_format) .def("set_format", &ImageSpec_set_format_2) .def("default_channel_names", &ImageSpec::default_channel_names) .def("format_from_quantize", &ImageSpec::format_from_quantize) .staticmethod("format_from_quantize") .def("channel_bytes", &ImageSpec_channel_bytes_1) .def("channel_bytes", &ImageSpec_channel_bytes_2) .def("channel_bytes", &ImageSpec_channel_bytes_3) .def("pixel_bytes", &ImageSpec_pixel_bytes_0) .def("pixel_bytes", &ImageSpec_pixel_bytes_1) .def("pixel_bytes", &ImageSpec_pixel_bytes_2) .def("pixel_bytes", &ImageSpec_pixel_bytes_3) .def("scanline_bytes", &ImageSpec::scanline_bytes, ImageSpec_scanline_bytes_overloads(args("native"))) .def("tile_bytes", &ImageSpec::tile_bytes, ImageSpec_tile_bytes_overloads(args("native"))) .def("image_bytes", &ImageSpec::image_bytes, ImageSpec_image_bytes_overloads(args("native"))) .def("tile_pixels", &ImageSpec::tile_pixels) .def("image_pixels", &ImageSpec::image_pixels) .def("size_t_safe", &ImageSpec::size_t_safe) // For now, do not expose auto_stride. It's not obvious that // anybody will want to do pointer work and strides from Python. // // auto_stride is overloaded so needs explicit function casts // .def("auto_stride", &ImageSpec_auto_stride_1) // .def("auto_stride", &ImageSpec_auto_stride_2) // .staticmethod("auto_stride") .def("attribute", &ImageSpec_attribute_float) .def("attribute", &ImageSpec_attribute_int) .def("attribute", &ImageSpec_attribute_string) .def("attribute", &ImageSpec_attribute_typed) .def("attribute", &ImageSpec_attribute_tuple_typed) .def("get_int_attribute", &ImageSpec_get_int_attribute) .def("get_int_attribute", &ImageSpec_get_int_attribute_d) .def("get_float_attribute", &ImageSpec_get_float_attribute) .def("get_float_attribute", &ImageSpec_get_float_attribute_d) .def("get_string_attribute", &ImageSpec_get_string_attribute) .def("get_string_attribute", &ImageSpec_get_string_attribute_d) .def("get_attribute", &ImageSpec_get_attribute_typed) .def("get_attribute", &ImageSpec_get_attribute_untyped) .def("metadata_val", &ImageSpec::metadata_val) ; } } // namespace PyOpenImageIO openimageio-1.3.12~dfsg0.orig/src/python/icrypt.py0000644000175000017500000000646112271062644020324 0ustar mfvmfvdef crypt(): import OpenImageIO as o import array import random import pickle path = raw_input("Enter OIIO plugin path: ") in_file = raw_input("Enter the name of the file for encryption: ") out_file = raw_input("Enter the name of the resulting file: ") key_path = raw_input("Enter the name of the file in which to store the key: ") # open the input file spec = o.ImageSpec() pic = o.ImageInput.create(in_file, path) pic.open(in_file, spec) desc = spec.format # Create a couple of arrays where we'll store the data. # They all need to be the same size, and we'll fill them with dummy data for now. # We'll read the original pixel values in arr arr = array.array("B", "\0" * spec.image_bytes()) # the values we'll write to the encrypted file new_values = arr[:] length = range(len(new_values)) print "Working, please wait..." pic.read_image(desc, arr) # save the state of the random number generator so we can use it # to decode the image state = random.getstate() # generate random values, add them to the original values. # Do % 256 so nothing overflows for i in length: rand_val = random.randint(0, 255) new_values[i] = (arr[i] + rand_val) % 256 # write new values to the output file, close everything out = o.ImageOutput.create(out_file, path) out.open(out_file, spec, False) out.write_image(desc, new_values) out.close() # save the state of the RNG - that's the key for decryption f = open(key_path, "w") pickle.dump(state, f) f.close() return True def decrypt(): import OpenImageIO as o import array import pickle import random path = raw_input("Enter OIIO plugin path: ") key_path = raw_input("Name of the file with the key: ") in_file = raw_input("Name of the encrypted file: ") # Open the input files, read the RNG state and store it in "key" f = open(key_path, "r") key = pickle.load(f) spec_cr = o.ImageSpec() pic_cr = o.ImageInput.create(in_file, path) pic_cr.open(in_file, spec_cr) desc_cr = spec_cr.format # The encrypted pixel values will be stored here. # The decoding will be done inplace, so that will also be # the output buffer once the decryption is done. arr_cr = array.array("B", "\0" * spec_cr.image_bytes()) length = range(len(arr_cr)) print "Working, please wait..." # Let's read the encrypted image pic_cr.read_image(desc_cr, arr_cr) # Set the state of the RNG to match the state of the RNG which coded # the image. After this, we can generate the same random sequence # used to code the image. random.setstate(key) # Decryption! for i in length: rand_val = random.randint(0, 255) # This is the inverse of the encryption. restored_pixel = arr_cr[i] - rand_val if restored_pixel < 0: arr_dec[i] = 256 + restored_pixel else: arr_dec[i] = restored_pixel print "Decryption completed!" image = raw_input("Enter the name under which to store the result: ") print "Working, please wait..." out_dec = o.ImageOutput.create(image, path) out_dec.open(image, spec_cr, False) out_dec.write_image(desc_cr, arr_dec) out_dec.close() return True openimageio-1.3.12~dfsg0.orig/src/python/py_roi.cpp0000644000175000017500000000645412271062644020447 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "py_oiio.h" namespace PyOpenImageIO { using namespace boost::python; using self_ns::str; static ROI ROI_All; // Declare the OIIO ROI class to Python void declare_roi() { class_("ROI") .def_readwrite("xbegin", &ROI::xbegin) .def_readwrite("xend", &ROI::xend) .def_readwrite("ybegin", &ROI::ybegin) .def_readwrite("yend", &ROI::yend) .def_readwrite("zbegin", &ROI::zbegin) .def_readwrite("zend", &ROI::zend) .def_readwrite("chbegin", &ROI::chbegin) .def_readwrite("chend", &ROI::chend) .def(init()) .def(init()) .def(init()) .def(init()) .add_property("defined", &ROI::defined) .add_property("width", &ROI::width) .add_property("height", &ROI::height) .add_property("depth", &ROI::depth) .add_property("nchannels", &ROI::nchannels) .add_property("npixels", &ROI::npixels) .def_readonly("All", &ROI_All) // Define Python str(ROI), it automatically uses '<<' .def(str(self)) // __str__ // roi_union, roi_intersection, get_roi(spec), get_roi_full(spec) // set_roi(spec,newroi), set_roi_full(newroi) // overloaded operators .def(self == other()) // operator== .def(self != other()) // operator!= ; def("union", &roi_union); def("intersection", &roi_intersection); def("get_roi", &get_roi); def("get_roi_full", &get_roi_full); def("set_roi", &set_roi); def("set_roi_full", &set_roi_full); } } // namespace PyOpenImageIO openimageio-1.3.12~dfsg0.orig/src/python/py_imagecache.cpp0000644000175000017500000001603512271062644021720 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "py_oiio.h" #include "ustring.h" namespace PyOpenImageIO { using namespace boost::python; ImageCacheWrap* ImageCacheWrap::create (bool shared=true) { ImageCacheWrap *icw = new ImageCacheWrap; icw->m_cache = ImageCache::create(shared); return icw; } void ImageCacheWrap::destroy (ImageCacheWrap *x) { ImageCache::destroy(x->m_cache); } void ImageCacheWrap::clear () { m_cache->clear(); } bool ImageCacheWrap::attribute (const std::string &name, TypeDesc type, const void *val) { return m_cache->attribute(name, type, val); } //Shortcuts for common types bool ImageCacheWrap::attribute_int (const std::string &name, int val) { return m_cache->attribute(name, val); } bool ImageCacheWrap::attribute_float (const std::string &name, float val) { return m_cache->attribute(name, val); } bool ImageCacheWrap::attribute_double (const std::string &name, double val) { return m_cache->attribute(name, val); } bool ImageCacheWrap::attribute_char (const std::string &name, const char *val) { return m_cache->attribute(name, val); } bool ImageCacheWrap::attribute_string (const std::string &name, const std::string &val) { return m_cache->attribute(name, val); } bool ImageCacheWrap::getattribute(const std::string &name, TypeDesc type, void *val) { return m_cache->getattribute(name, type, val); } //Shortcuts for common types bool ImageCacheWrap::getattribute_int(const std::string &name, int &val) { return m_cache->getattribute(name, val); } bool ImageCacheWrap::getattribute_float(const std::string &name, float &val) { return m_cache->getattribute(name, val); } bool ImageCacheWrap::getattribute_double(const std::string &name, double &val) { return m_cache->getattribute(name, val); } bool ImageCacheWrap::getattribute_char(const std::string &name, char **val) { return m_cache->getattribute(name, val); } bool ImageCacheWrap::getattribute_string(const std::string &name, std::string &val) { return m_cache->getattribute(name, val); } std::string ImageCacheWrap::resolve_filename (const std::string &val) { return m_cache->resolve_filename(val); } bool ImageCacheWrap::get_image_info (ustring filename, ustring dataname, TypeDesc datatype, void *data) { return m_cache->get_image_info(filename, dataname, datatype, data); } bool ImageCacheWrap::get_imagespec(ustring filename, ImageSpec &spec, int subimage=0) { return m_cache->get_imagespec(filename, spec, subimage); } bool ImageCacheWrap::get_pixels (ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result) { return m_cache->get_pixels(filename, subimage, miplevel, xbegin, xend, ybegin, yend, zbegin, zend, format, result); } //Not sure how to expose this to Python. /* Tile *get_tile (ustring filename, int subimage, int x, int y, int z) { return m_cache->get_tile(filename, subimage, x, y, z); } void release_tile (Tile *tile) const { m_cache->release-tile(tile); } const void *tile_pixels (Tile *tile, TypeDesc &format) const { m_cache->tile_pixels(tile, format); } */ std::string ImageCacheWrap::geterror () const { return m_cache->geterror(); } std::string ImageCacheWrap::getstats (int level=1) const { return m_cache->getstats(level); } void ImageCacheWrap::invalidate (ustring filename) { return m_cache->invalidate(filename); } void ImageCacheWrap::invalidate_all (bool force=false) { return m_cache->invalidate_all(force); } void declare_imagecache() { class_("ImageCache", no_init) .def("create", &ImageCacheWrap::create, (arg("shared")), return_value_policy()) .staticmethod("create") .def("destroy", &ImageCacheWrap::destroy) .staticmethod("destroy") .def("clear", &ImageCacheWrap::clear) .def("attribute", &ImageCacheWrap::attribute) .def("attribute", &ImageCacheWrap::attribute_int) .def("attribute", &ImageCacheWrap::attribute_float) .def("attribute", &ImageCacheWrap::attribute_double) .def("attribute", &ImageCacheWrap::attribute_char) .def("attribute", &ImageCacheWrap::attribute_string) .def("getattribute", &ImageCacheWrap::attribute) .def("getattribute", &ImageCacheWrap::getattribute_int) .def("getattribute", &ImageCacheWrap::getattribute_float) .def("getattribute", &ImageCacheWrap::getattribute_double) .def("getattribute", &ImageCacheWrap::getattribute_char) .def("getattribute", &ImageCacheWrap::getattribute_string) .def("resolve_filename", &ImageCacheWrap::resolve_filename) .def("get_image_info", &ImageCacheWrap::get_image_info) .def("get_imagespec", &ImageCacheWrap::get_imagespec) .def("get_pixels", &ImageCacheWrap::get_pixels) // .def("get_tile", &ImageCacheWrap::get_tile) // .def("release_tile", &ImageCacheWrap::release_tile) // .def("tile_pixels", &ImageCacheWrap::tile_pixels) //added _ to the method names for consistency .def("geterror", &ImageCacheWrap::geterror) .def("getstats", &ImageCacheWrap::getstats) .def("invalidate", &ImageCacheWrap::invalidate) .def("invalidate_all", &ImageCacheWrap::invalidate_all) ; } } // namespace PyOpenImageIO openimageio-1.3.12~dfsg0.orig/src/python/py_imagebufalgo.cpp0000644000175000017500000006547012271062644022303 0ustar mfvmfv/* Copyright 2013 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "imagebufalgo.h" #include "py_oiio.h" namespace PyOpenImageIO { using namespace boost::python; class IBA_dummy { }; // dummy class to establish a scope bool IBA_fill (ImageBuf &dst, tuple values_tuple, ROI roi=ROI::All(), int nthreads=0) { std::vector values; py_to_stdvector (values, values_tuple); if (dst.initialized()) values.resize (dst.nchannels(), 0.0f); else if (roi.defined()) values.resize (roi.nchannels(), 0.0f); else return false; ASSERT (values.size() > 0); return ImageBufAlgo::fill (dst, &values[0], roi, nthreads); } bool IBA_checker (ImageBuf &dst, int width, int height, int depth, tuple color1_tuple, tuple color2_tuple, int xoffset, int yoffset, int zoffset, ROI roi, int nthreads) { std::vector color1, color2; py_to_stdvector (color1, color1_tuple); py_to_stdvector (color2, color2_tuple); if (dst.initialized()) color1.resize (dst.nchannels(), 0.0f); else if (roi.defined()) color1.resize (roi.nchannels(), 0.0f); else return false; if (dst.initialized()) color2.resize (dst.nchannels(), 0.0f); else if (roi.defined()) color2.resize (roi.nchannels(), 0.0f); else return false; return ImageBufAlgo::checker (dst, width, height, depth, &color1[0], &color2[0], xoffset, yoffset, zoffset, roi, nthreads); } bool IBA_channels (ImageBuf &dst, const ImageBuf &src, tuple channelorder_, tuple newchannelnames_, bool shuffle_channel_names) { size_t nchannels = (size_t) len(channelorder_); if (nchannels < 1) { dst.error ("No channels selected"); return false; } std::vector channelorder (nchannels, -1); std::vector channelvalues (nchannels, 0.0f); for (size_t i = 0; i < nchannels; ++i) { extract chnum (channelorder_[i]); if (chnum.check()) { channelorder[i] = chnum(); continue; } extract chval (channelorder_[i]); if (chval.check()) { channelvalues[i] = chval(); continue; } extract chname (channelorder_[i]); if (chname.check()) { for (int c = 0; c < src.nchannels(); ++c) { if (src.spec().channelnames[c] == chname()) channelorder[i] = c; } continue; } } std::vector newchannelnames; py_to_stdvector (newchannelnames, newchannelnames_); if (newchannelnames.size() != 0 && newchannelnames.size() != nchannels) { dst.error ("Inconsistent number of channel arguments"); return false; } return ImageBufAlgo::channels (dst, src, (int)nchannels, &channelorder[0], channelvalues.size() ? &channelvalues[0] : NULL, newchannelnames.size() ? &newchannelnames[0] : NULL, shuffle_channel_names); } bool IBA_add_color (ImageBuf &dst, const ImageBuf &A, tuple values_tuple, ROI roi=ROI::All(), int nthreads=0) { std::vector values; py_to_stdvector (values, values_tuple); if (roi.defined()) values.resize (roi.nchannels(), 0.0f); else if (A.initialized()) values.resize (A.nchannels(), 0.0f); else return false; ASSERT (values.size() > 0); return ImageBufAlgo::add (dst, A, &values[0], roi, nthreads); } bool IBA_add_float (ImageBuf &dst, const ImageBuf &A, float val, ROI roi=ROI::All(), int nthreads=0) { return ImageBufAlgo::add (dst, A, val, roi, nthreads); } bool IBA_add_images (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi=ROI::All(), int nthreads=0) { return ImageBufAlgo::add (dst, A, B, roi, nthreads); } bool IBA_sub_color (ImageBuf &dst, const ImageBuf &A, tuple values_tuple, ROI roi=ROI::All(), int nthreads=0) { std::vector values; py_to_stdvector (values, values_tuple); if (roi.defined()) values.resize (roi.nchannels(), 0.0f); else if (A.initialized()) values.resize (A.nchannels(), 0.0f); else return false; ASSERT (values.size() > 0); return ImageBufAlgo::sub (dst, A, &values[0], roi, nthreads); } bool IBA_sub_float (ImageBuf &dst, const ImageBuf &A, float val, ROI roi=ROI::All(), int nthreads=0) { return ImageBufAlgo::sub (dst, A, val, roi, nthreads); } bool IBA_sub_images (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi=ROI::All(), int nthreads=0) { return ImageBufAlgo::sub (dst, A, B, roi, nthreads); } bool IBA_mul_color (ImageBuf &dst, const ImageBuf &A, tuple values_tuple, ROI roi=ROI::All(), int nthreads=0) { std::vector values; py_to_stdvector (values, values_tuple); if (roi.defined()) values.resize (roi.nchannels(), 0.0f); else if (A.initialized()) values.resize (A.nchannels(), 0.0f); else return false; ASSERT (values.size() > 0); return ImageBufAlgo::mul (dst, A, &values[0], roi, nthreads); } bool IBA_mul_float (ImageBuf &dst, const ImageBuf &A, float B, ROI roi=ROI::All(), int nthreads=0) { return ImageBufAlgo::mul (dst, A, B, roi, nthreads); } bool IBA_mul_images (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, ROI roi=ROI::All(), int nthreads=0) { return ImageBufAlgo::mul (dst, A, B, roi, nthreads); } bool IBA_clamp (ImageBuf &dst, const ImageBuf &src, tuple min_, tuple max_, bool clampalpha01 = false, ROI roi = ROI::All(), int nthreads=0) { if (! src.initialized()) return false; std::vector min, max; py_to_stdvector (min, min_); py_to_stdvector (max, max_); min.resize (src.nchannels(), -std::numeric_limits::max()); max.resize (src.nchannels(), std::numeric_limits::max()); return ImageBufAlgo::clamp (dst, src, &min[0], &max[0], clampalpha01, roi, nthreads); } bool IBA_clamp_float (ImageBuf &dst, const ImageBuf &src, float min_, float max_, bool clampalpha01 = false, ROI roi = ROI::All(), int nthreads=0) { if (! src.initialized()) return false; std::vector min, max; min.resize (src.nchannels(), min_); max.resize (src.nchannels(), max_); return ImageBufAlgo::clamp (dst, src, &min[0], &max[0], clampalpha01, roi, nthreads); } bool IBA_channel_sum_weight (ImageBuf &dst, const ImageBuf &src, tuple weight_tuple, ROI roi=ROI::All(), int nthreads=0) { std::vector weight; py_to_stdvector (weight, weight_tuple); if (! src.initialized()) { dst.error ("Uninitialized source image for channel_sum"); return false; } if (weight.size() == 0) weight.resize (src.nchannels(), 1.0f); // no weights -> uniform else weight.resize (src.nchannels(), 0.0f); // missing weights -> 0 return ImageBufAlgo::channel_sum (dst, src, &weight[0], roi, nthreads); } bool IBA_channel_sum (ImageBuf &dst, const ImageBuf &src, ROI roi=ROI::All(), int nthreads=0) { return ImageBufAlgo::channel_sum (dst, src, NULL, roi, nthreads); } bool IBA_rangeexpand (ImageBuf &dst, const ImageBuf &src, bool useluma = false, ROI roi = ROI::All(), int nthreads=0) { return ImageBufAlgo::rangeexpand (dst, src, useluma, roi, nthreads); } bool IBA_rangecompress (ImageBuf &dst, const ImageBuf &src, bool useluma = false, ROI roi = ROI::All(), int nthreads=0) { return ImageBufAlgo::rangecompress (dst, src, useluma, roi, nthreads); } bool IBA_premult (ImageBuf &dst, const ImageBuf &src, ROI roi = ROI::All(), int nthreads=0) { return ImageBufAlgo::premult (dst, src, roi, nthreads); } bool IBA_unpremult (ImageBuf &dst, const ImageBuf &src, ROI roi = ROI::All(), int nthreads=0) { return ImageBufAlgo::unpremult (dst, src, roi, nthreads); } bool IBA_resize (ImageBuf &dst, const ImageBuf &src, const std::string &filter = "", float filterwidth = 0.0f, ROI roi=ROI::All(), int nthreads=0) { return ImageBufAlgo::resize (dst, src, filter, filterwidth, roi, nthreads); } bool IBA_zover (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, bool z_zeroisinf = false, ROI roi = ROI::All(), int nthreads = 0) { return ImageBufAlgo::zover (dst, A, B, z_zeroisinf, roi, nthreads); } bool IBA_colorconvert (ImageBuf &dst, const ImageBuf &src, const std::string &from, const std::string &to, bool unpremult = false, ROI roi = ROI::All(), int nthreads = 0) { return ImageBufAlgo::colorconvert (dst, src, from.c_str(), to.c_str(), unpremult, roi, nthreads); } bool IBA_ociolook (ImageBuf &dst, const ImageBuf &src, const std::string &looks, const std::string &from, const std::string &to, bool inverse, bool unpremult, const std::string &context_key, const std::string &context_value, ROI roi = ROI::All(), int nthreads = 0) { return ImageBufAlgo::ociolook (dst, src, looks.c_str(), from.c_str(), to.c_str(), inverse, unpremult, context_key.c_str(), context_value.c_str(), roi, nthreads); } bool IBA_ociodisplay (ImageBuf &dst, const ImageBuf &src, const std::string &display, const std::string &view, const object &from, const object &looks, bool unpremult, const std::string &context_key, const std::string &context_value, ROI roi = ROI::All(), int nthreads = 0) { std::string from_str, looks_str; if (from != object()) from_str = extract(from); if (looks != object()) looks_str = extract(looks); return ImageBufAlgo::ociodisplay (dst, src, display.c_str(), view.c_str(), from == object() ? NULL : from_str.c_str(), looks == object() ? NULL : looks_str.c_str(), unpremult, context_key.c_str(), context_value.c_str(), roi, nthreads); } object IBA_isConstantColor (const ImageBuf &src, ROI roi = ROI::All(), int nthreads = 0) { std::vector constcolor (src.nchannels()); bool r = ImageBufAlgo::isConstantColor (src, &constcolor[0], roi, nthreads); if (r) { return C_to_tuple (&constcolor[0], (int)constcolor.size(), PyFloat_FromDouble); } else { return object(); } } bool IBA_fixNonFinite (ImageBuf &dst, const ImageBuf &src, ImageBufAlgo::NonFiniteFixMode mode=ImageBufAlgo::NONFINITE_BOX3, ROI roi = ROI::All(), int nthreads = 0) { return ImageBufAlgo::fixNonFinite (dst, src, mode, NULL, roi, nthreads); } bool IBA_render_text (ImageBuf &dst, int x, int y, const std::string &text, int fontsize=16, const std::string &fontname="", tuple textcolor_ = tuple()) { std::vector textcolor; py_to_stdvector (textcolor, textcolor_); textcolor.resize (dst.nchannels(), 1.0f); return ImageBufAlgo::render_text (dst, x, y, text, fontsize, fontname, &textcolor[0]); } bool IBA_capture_image (ImageBuf &dst, int cameranum, TypeDesc::BASETYPE convert = TypeDesc::UNKNOWN) { return ImageBufAlgo::capture_image (dst, cameranum, convert); } bool IBA_make_texture_ib (ImageBufAlgo::MakeTextureMode mode, const ImageBuf &buf, const std::string &outputfilename, const ImageSpec &config) { return ImageBufAlgo::make_texture (mode, buf, outputfilename, config); } bool IBA_make_texture_filename (ImageBufAlgo::MakeTextureMode mode, const std::string &filename, const std::string &outputfilename, const ImageSpec &config) { return ImageBufAlgo::make_texture (mode, filename, outputfilename, config); } void declare_imagebufalgo() { enum_("NonFiniteFixMode") .value("NONFINITE_NONE", ImageBufAlgo::NONFINITE_NONE) .value("NONFINITE_BLACK", ImageBufAlgo::NONFINITE_BLACK) .value("NONFINITE_BOX3", ImageBufAlgo::NONFINITE_BOX3) .export_values() ; enum_("MakeTextureMode") .value("MakeTxTexture", ImageBufAlgo::MakeTxTexture) .value("MakeTxShadow", ImageBufAlgo::MakeTxShadow) .value("MakeTxEnvLatl", ImageBufAlgo::MakeTxEnvLatl) .value("MakeTxEnvLatlFromLightProbe", ImageBufAlgo::MakeTxEnvLatlFromLightProbe) .export_values() ; class_("CompareResults") .def_readwrite("meanerror", &ImageBufAlgo::CompareResults::meanerror) .def_readwrite("rms_error", &ImageBufAlgo::CompareResults::rms_error) .def_readwrite("PSNR", &ImageBufAlgo::CompareResults::PSNR) .def_readwrite("maxerror", &ImageBufAlgo::CompareResults::maxerror) .def_readwrite("maxx", &ImageBufAlgo::CompareResults::maxx) .def_readwrite("maxy", &ImageBufAlgo::CompareResults::maxy) .def_readwrite("maxz", &ImageBufAlgo::CompareResults::maxz) .def_readwrite("maxc", &ImageBufAlgo::CompareResults::maxc) .def_readwrite("nwarn", &ImageBufAlgo::CompareResults::nwarn) .def_readwrite("nfail", &ImageBufAlgo::CompareResults::nfail) ; // Use a boost::python::scope to put this all inside "ImageBufAlgo" boost::python::scope IBA = class_("ImageBufAlgo") .def("zero", &ImageBufAlgo::zero, (arg("dst"), arg("roi")=ROI::All(), arg("nthreads")=0) ) .staticmethod("zero") .def("fill", &IBA_fill, (arg("dst"), arg("values"), arg("roi")=ROI::All(), arg("nthreads")=0) ) .staticmethod("fill") .def("checker", &IBA_checker, (arg("dst"), arg("width"), arg("height"), arg("depth"), arg("color1"), arg("color2"), arg("xoffset")=0, arg("yoffset")=0, arg("zoffset")=0, arg("roi")=ROI::All(), arg("nthreads")=0) ) .staticmethod("checker") .def("channels", &IBA_channels, (arg("dst"), arg("src"), arg("channelorder"), arg("newchannelnames")=tuple(), arg("shuffle_channel_names")=false)) .staticmethod("channels") .def("channel_append", &ImageBufAlgo::channel_append, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("channel_append") .def("flatten", &ImageBufAlgo::flatten, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("flatten") .def("crop", &ImageBufAlgo::crop, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("crop") .def("paste", &ImageBufAlgo::paste, (arg("dst"), arg("xbegin"), arg("ybegin"), arg("zbegin"), arg("chbegin"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("paste") .def("flip", &ImageBufAlgo::flip, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("flip") .def("flop", &ImageBufAlgo::flop, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("flop") .def("flipflop", &ImageBufAlgo::flipflop, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("flipflop") .def("transpose", &ImageBufAlgo::transpose, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("transpose") .def("circular_shift", &ImageBufAlgo::circular_shift, (arg("dst"), arg("src"), arg("xshift"), arg("yshift"), arg("zshift")=0, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("circular_shift") .def("add", &IBA_add_images, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .def("add", &IBA_add_float, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .def("add", IBA_add_color, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("add") .def("sub", &IBA_sub_images, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .def("sub", &IBA_sub_float, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .def("sub", IBA_sub_color, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("sub") .def("mul", &IBA_mul_images, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .def("mul", &IBA_mul_float, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .def("mul", &IBA_mul_color, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("mul") .def("channel_sum", &IBA_channel_sum, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .def("channel_sum", &IBA_channel_sum_weight, (arg("dst"), arg("src"), arg("weight"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("channel_sum") .def("rangecompress", &IBA_rangecompress, (arg("dst"), arg("src"), arg("useluma")=false, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("rangecompress") .def("rangeexpand", &IBA_rangeexpand, (arg("dst"), arg("src"), arg("useluma")=false, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("rangeexpand") .def("premult", &IBA_premult, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("premult") .def("unpremult", &IBA_unpremult, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("unpremult") .def("clamp", &IBA_clamp, (arg("dst"), arg("src"), arg("min")=tuple(), arg("max")=tuple(), arg("clampalpha01")=false, arg("roi")=ROI::All(), arg("nthreads")=0)) .def("clamp", &IBA_clamp_float, (arg("dst"), arg("src"), arg("min")=-std::numeric_limits::max(), arg("max")=std::numeric_limits::max(), arg("clampalpha01")=false, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("clamp") .def("colorconvert", &IBA_colorconvert, (arg("dst"), arg("src"), arg("from"), arg("to"), arg("unpremult")=false, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("colorconvert") .def("ociolook", &IBA_ociolook, (arg("dst"), arg("src"), arg("looks"), arg("from"), arg("to"), arg("unpremult")=false, arg("invert")=false, arg("context_key")="", arg("context_value")="", arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("ociolook") .def("ociodisplay", &IBA_ociodisplay, (arg("dst"), arg("src"), arg("display"), arg("view"), arg("from")=object(), arg("looks")=object(), arg("unpremult")=false, arg("context_key")="", arg("context_value")="", arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("ociodisplay") // computePixelStats, .def("compare", &ImageBufAlgo::compare, (arg("A"), arg("B"), arg("failthresh"), arg("warnthresh"), arg("result"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("compare") .def("compare_Yee", &ImageBufAlgo::compare_Yee, (arg("A"), arg("B"), arg("result"), arg("luminance")=100, arg("fov")=45, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("compare_Yee") .def("isConstantColor", &IBA_isConstantColor, (arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("isConstantColor") .def("isConstantChannel", &ImageBufAlgo::isConstantChannel, (arg("src"), arg("channel"), arg("val"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("isConstantChannel") .def("isMonochrome", &ImageBufAlgo::isMonochrome, (arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("isMonochrome") // color_count, color_range_check .def("nonzero_region", &ImageBufAlgo::nonzero_region, (arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("nonzero_region") .def("computePixelHashSHA1", &ImageBufAlgo::computePixelHashSHA1, (arg("src"), arg("extrainfo")="", arg("roi")=ROI::All(), arg("blocksize")=0, arg("nthreads")=0)) .staticmethod("computePixelHashSHA1") .def("resize", &IBA_resize, (arg("dst"), arg("src"), arg("filername")="", arg("filterwidth")=0.0f, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("resize") .def("resample", &ImageBufAlgo::resample, (arg("dst"), arg("src"), arg("interpolate")=true, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("resample") .def("make_kernel", &ImageBufAlgo::make_kernel, (arg("dst"), arg("name"), arg("width"), arg("height"), arg("depth")=1.0f, arg("normalize")=true)) .staticmethod("make_kernel") .def("convolve", &ImageBufAlgo::convolve, (arg("dst"), arg("src"), arg("kernel"), arg("normalze")=true, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("convolve") .def("unsharp_mask", &ImageBufAlgo::unsharp_mask, (arg("dst"), arg("src"), arg("kernel")="gaussian", arg("width")=3.0f, arg("contrast")=1.0f, arg("threshold")=0.0f, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("unsharp_mask") .def("fft", &ImageBufAlgo::fft, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("fft") .def("ifft", &ImageBufAlgo::ifft, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("ifft") .def("fixNonFinite", &IBA_fixNonFinite, (arg("dst"), arg("src"), arg("mode")=ImageBufAlgo::NONFINITE_BOX3, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("fixNonFinite") .def("fillholes_pushpull", &ImageBufAlgo::fillholes_pushpull, (arg("dst"), arg("src"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("fillholes_pushpull") .def("capture_image", &IBA_capture_image, (arg("dst"), arg("cameranum")=0, arg("convert")=TypeDesc::UNKNOWN)) .staticmethod("capture_image") .def("over", &ImageBufAlgo::over, (arg("dst"), arg("A"), arg("B"), arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("over") .def("zover", &IBA_zover, (arg("dst"), arg("A"), arg("B"), arg("z_zeroisinf")=false, arg("roi")=ROI::All(), arg("nthreads")=0)) .staticmethod("zover") .def("render_text", &IBA_render_text, (arg("dst"), arg("x"), arg("y"), arg("text"), arg("fontsize")=16, arg("fontname")="", arg("textcolor")=tuple())) .staticmethod("render_text") // histogram, histogram_draw, .def("make_texture", &IBA_make_texture_filename, (arg("mode"), arg("filename"), arg("outputfilename"), arg("config")=ImageSpec())) .def("make_texture", &IBA_make_texture_ib, (arg("mode"), arg("buf"), arg("outputfilename"), arg("config")=ImageSpec())) .staticmethod("make_texture") ; } } // namespace PyOpenImageIO openimageio-1.3.12~dfsg0.orig/src/python/istitch.py0000755000175000017500000003243012271062644020457 0ustar mfvmfv#!/usr/bin/env python # Parse the options the user provided from the command line # -i takes three arguments: x and y coordinates and filename; # -o takes one argument (the name of to file where the stitched image will be written) # -p takes one argument (path to the oiio plugin library) def option_parser(): parser = OptionParser() parser.add_option("-i", nargs=3, action="append", dest="arguments") parser.add_option("-o", dest="output_file") parser.add_option("-p", dest="plugin_path", help="OIIO plugin path") (options, args) = parser.parse_args() coordinates = [] images = [] for i in options.arguments: xy = (int(i[0]), int(i[1])) filepath = i[2] coordinates.append(xy) images.append(filepath) plugin_path = options.plugin_path if not plugin_path: plugin_path = "" filename = options.output_file return (coordinates, images, plugin_path, filename) # If the user didn't provide any arguments from the command line, or he ran # the script as a module from Python, an interactive mode will be used to # get the needed information. # The function stops when the user enters an empty path to the image (just hits enter) def user_prompt(): coordinates = [] images = [] filepath = raw_input("Enter the path to the image: ") while filepath != "": if not os.path.exists(filepath): return False xy = raw_input("Specify position of image inside the stitched image (x y): ") xy = (int(xy[0]), int(xy[2])) images.append(filepath) coordinates.append(xy) filepath = raw_input("Enter the path to the image: ") return (coordinates, images) # Check if the coordinates our user provided make sense. This means that there # can't be any "holes" in the provided coordinates. Examples of wrong coordinates: # 0 0, 2 0 (needs 1 0) # 0 0, 1 0, 0 1, 0 3 (needs 0 2) def validate_coordinates(images_info): coordinates = images_info[0] zipped = zip(*coordinates) xmax = max(zipped[0]) ymax = max(zipped[1]) for x in range(xmax): if list(zipped[0]).count(x) == 0: return False for y in range(ymax): if list(zipped[1]).count(y) == 0: return False return True # Open every image in the list of filepaths, return a list of opened # ImageInput instances. # TODO: A function which would close (or delete?) all the instances def open_images(filepaths): images = [] for i in filepaths: inp = o.ImageInput.create(i, path) spec = o.ImageSpec() if inp.open(i, spec): images.append(inp) else: return False return images # Takes a list consisting of two sublists: [0] is a list of coordinates (which # are stored as tuples), [1] is a list of opened ImageInput instances; and puts # them in a dictionary (coordinates as keys). The dictionary makes using coordinates # very easy, since grid((x,y)) returns a matching image. def convert_to_grid(images_data): grid = {} for i in range(len(images_data[0])): grid[images_data[0][i]] = images_data[1][i] return grid # Check if all the images which should form a row have the same heights. # Returns False (if they don't) or the width of the row they would form. # This isn't used in this example, but might be useful. # TODO: check_constraints() actually does this, since it can check both a single row # and the whole grid. Is there any reason to keep check_row()? # def check_row(images): spec_0 = images[0].spec() row_width = spec_0.width for i in images[1:]: spec_i = i.spec() if spec_i.height != spec_0.height: return False row_width += spec_i.width return row_width # It uses check_row() to check if the whole grid can be merged (images in a row # must have matching heights, rows should have matching widths) # TODO: Also not used anywhere. It uses multiple calls to check_row() to achieve # what the more powerful check_constraints() can do by itself. Delete it? def can_stitch(images_table): width = check_row(images_table[0]) if width: for row in images_table[1:]: row_width = check_row(row) if row_width != width: return False return True else: return False # stitch the images which make a row to each other. # it takes a list of opened ImageInput instances def stitch_row(images): arr = array.array("B") row_width = check_row(images) if row_width: spec_0 = images[0].spec() for row in range(spec_0.height): for i in images: spec_i = i.spec() arr_i = array.array("B", "\0" * spec_i.scanline_bytes()) if i.read_scanline(row, 0, spec_i.format, arr_i): arr += arr_i else: return False return arr else: return False # it takes a list of rows. Each row is actually an array, so the joining # is trivial. def join_rows(rows): arr = array.array("B") for i in rows: arr += i return arr # This function takes a dictionary of opened # ImageInputs and checks can they be stitched together according to the # coordinates provided (as dictionary keys). def check_constraints(images): # Extract the number of rows and the number of images in the row with # the most images. Rows can have different number of images as long # as their widths add up to the same number. # Add +1 to both so we can properly use range() in for loops which iterate # over rows and columns. coordinates = images.keys() zipped = zip(*coordinates) n_columns_max = int(max(zipped[0])) + 1 n_rows = int(max(zipped[1])) + 1 # this will be the height of the final, stitched image height = 0 for y in range(n_rows): row_height = images[(0,y)].spec().height row_width = 0 for x in range(n_columns_max): if row_height == images[(x,y)].spec().height: row_width += images[(x,y)].spec().width else: return False # if the current row has less images than n_columns_max, # break the inner for loop when you reach the end if not images.get((x+1,y)): break height += row_height if y == 0: base_width = row_width else: if base_width != row_width: return False return (row_width, height) # Given a dictionary of opened ImageInput instances, # the function stitches them and returns a single # array.array which can then be written to a file. def stitch_images(images, name): # Let us first call check_constraints() in case the user forgot # to do so. Also, we'll get the resolution of the image. xy = check_constraints(images) if not xy: return False # Extract the number of rows and the number of images in the row with # the most images. Rows can have different number of images as long # as their widths add up to the same number. coordinates = images.keys() zipped = zip(*coordinates) n_columns_max = max(zipped[0]) + 1 n_rows = max(zipped[1]) + 1 # Form a row from the images with the same y coordinate. # Stitch the images in a row by calling stitch_row(row), which returns # an array representing the data of what is now a single image. # rows = [] for y in range(n_rows): row = [] for x in range(n_columns_max): row.append(images[(x,y)]) if images.get((x+1,y)) == None: break stitched_row = stitch_row(row) rows.append(stitched_row) data = join_rows(rows) if data: desc = images[(0,0)].spec().format spec = o.ImageSpec(xy[0], xy[1], images[(0,0)].spec().nchannels, desc) out = o.ImageOutput.create(name, path) out.open(name, spec, False) out.write_image(desc, data) out.close() else: return False ################################### # TODO: A function which would check if the user gave the proper xy coordinates, # i.e. an image at 1 1 is not possible without images at 0 0 and 1 0. Be careful # to give proper coordinates for now (though the order in which the images are # given does not matter). # TODO: Currently, the coordinates should be entered as "x y", without the "". # So, 0 0 works for now, and inputs like (0,0) or "0, 0" (with the "") will # be supported. # main() if __name__ == "__main__": import OpenImageIO as o import array import os import sys from optparse import OptionParser if len(sys.argv) > 1: parsed = option_parser() filename = parsed[3] path = parsed[2] images_info = (parsed[0], parsed[1]) else: filename = raw_input("Enter the desired name of the final stitched image: ") path = raw_input("Enter the path to the oiio plugin dir: ") images_info = user_prompt() if not validate_coordinates(images_info): print "Coordinates not valid" else: ii_instances = open_images(images_info[1]) if not ii_instances: print "Can't open given images" else: images_info = (images_info[0], ii_instances) grid = convert_to_grid(images_info) # the main part of the stitcher. Check if the images can be stitched, and # stitch them if so. print "Checking whether the images can be merged..." if check_constraints(grid): print "Check ok, merging images..." stitch_images(grid, filename) print "The merging is complete." else: print "Can't stitch the images" ################################### # this was for testing only def stitch_halves(left, right): spec_left = o.ImageSpec() spec_right = o.ImageSpec() inp_left = o.ImageInput.create("jpg", "/home/dgaletic/code/oiio-trunk/dist/linux/lib") inp_right = o.ImageInput.create("jpg", "/home/dgaletic/code/oiio-trunk/dist/linux/lib") inp_left.open(left, spec_left) inp_right.open(right, spec_right) if spec_right.height == spec_left.height: xres = spec_left.width + spec_right.width yres = spec_left.height desc = spec_left.format spec_new = o.ImageSpec(xres, yres, spec_left.nchannels, desc) out = o.ImageOutput.create("jpg", "/home/dgaletic/code/oiio-trunk/dist/linux/lib") out.open("test-join.jpg", spec_new, False) for scanline in range(0, spec_left.height): arr_l = array.array("B", "\0" * spec_left.scanline_bytes()) arr_r = array.array("B", "\0" * spec_right.scanline_bytes()) arr_new = array.array("B") inp_left.read_scanline(scanline, 0, spec_left.format, arr_l) inp_right.read_scanline(scanline, 0, spec_right.format, arr_r) arr_new = arr_l + arr_r out.write_scanline(scanline, 0, spec_new.format, arr_new) out.close() else: print "Heights do not match" # stitches together an image split into three parts # this was also for testing only def test_stitch_thirds(): pic_third1 = "/home/dgaletic/code/oiio-testimages/stitch_me/tahoe-0.jpg" pic_third2 = "/home/dgaletic/code/oiio-testimages/stitch_me/tahoe-1.jpg" pic_third3 = "/home/dgaletic/code/oiio-testimages/stitch_me/tahoe-2.jpg" path = "/home/dgaletic/code/oiio-trunk/dist/linux/lib" spec1 = o.ImageSpec() spec2 = o.ImageSpec() spec3 = o.ImageSpec() pic1 = o.ImageInput.create("jpg", path) pic2 = o.ImageInput.create("jpg", path) pic3 = o.ImageInput.create("jpg", path) pic1.open(pic_third1, spec1) pic2.open(pic_third2, spec2) pic3.open(pic_third3, spec3) spec_stitched = o.ImageSpec(spec1.width + spec2.width + spec3.width, spec1.height, spec1.nchannels, spec1.format) # create a list of opened ImageInput instances images = [pic1, pic2, pic3] # stitch the images next to each other, return the resulting array arr = stitch_row(images) if arr: out = o.ImageOutput.create("jpg", path) out.open("/home/dgaletic/code/branch/src/python/thirds.jpg", spec_stitched, False) out.write_image(spec_stitched.format, arr) out.close() #return True #else: #return False """ inp00 = o.ImageInput.create("jpg", path) spec00 = o.ImageSpec() inp00.open("/home/dgaletic/code/oiio-testimages/stitch_me/tahoe00.jpg", spec00) inp10 = o.ImageInput.create("jpg", path) spec10 = o.ImageSpec() inp10.open("/home/dgaletic/code/oiio-testimages/stitch_me/tahoe10.jpg", spec10) inp20 = o.ImageInput.create("jpg", path) spec20 = o.ImageSpec() inp20.open("/home/dgaletic/code/oiio-testimages/stitch_me/tahoe20.jpg", spec20) inp01 = o.ImageInput.create("jpg", path) spec01 = o.ImageSpec() inp01.open("/home/dgaletic/code/oiio-testimages/stitch_me/tahoe01.jpg", spec01) inp11 = o.ImageInput.create("jpg", path) spec11 = o.ImageSpec() inp11.open("/home/dgaletic/code/oiio-testimages/stitch_me/tahoe11.jpg", spec11) inp02 = o.ImageInput.create("jpg", path) spec02 = o.ImageSpec() inp02.open("/home/dgaletic/code/oiio-testimages/stitch_me/tahoe02.jpg", spec02) images = {(0,0):inp00, (1,0):inp10, (2,0):inp20, (0,1):inp01, (1,1):inp11, (0,2):inp02} """ openimageio-1.3.12~dfsg0.orig/src/python/py_imagebuf.cpp0000644000175000017500000002613112271062644021427 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "py_oiio.h" #include "sysutil.h" namespace PyOpenImageIO { using namespace boost::python; std::string ImageBuf_name (const ImageBuf &buf) { return buf.name(); } std::string ImageBuf_file_format_name (const ImageBuf &buf) { return buf.file_format_name(); } void ImageBuf_reset_name (ImageBuf &buf, const std::string &name) { buf.reset (name); } void ImageBuf_reset_name2 (ImageBuf &buf, const std::string &name, int subimage, int miplevel) { buf.reset (name, subimage, miplevel); } void ImageBuf_reset_spec (ImageBuf &buf, const ImageSpec &spec) { buf.reset (spec); } bool ImageBuf_read (ImageBuf &buf, int subimage=0, int miplevel=0, bool force=false, TypeDesc convert=TypeDesc::UNKNOWN) { return buf.read (subimage, miplevel, force, convert); } bool ImageBuf_read2 (ImageBuf &buf, int subimage=0, int miplevel=0, bool force=false, TypeDesc::BASETYPE convert=TypeDesc::UNKNOWN) { return buf.read (subimage, miplevel, force, convert); } BOOST_PYTHON_FUNCTION_OVERLOADS(ImageBuf_read_overloads, ImageBuf_read, 1, 5) BOOST_PYTHON_FUNCTION_OVERLOADS(ImageBuf_read2_overloads, ImageBuf_read2, 1, 5) bool ImageBuf_write (const ImageBuf &buf, const std::string &filename, const std::string &fileformat="") { return buf.write (filename, fileformat); } BOOST_PYTHON_FUNCTION_OVERLOADS(ImageBuf_write_overloads, ImageBuf_write, 2, 3) void ImageBuf_set_write_format (ImageBuf &buf, TypeDesc::BASETYPE format) { buf.set_write_format (format); } void ImageBuf_set_full (ImageBuf &buf, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend) { buf.set_full (xbegin, xend, ybegin, yend, zbegin, zend); } float ImageBuf_getchannel (const ImageBuf &buf, int x, int y, int z, int c, ImageBuf::WrapMode wrap = ImageBuf::WrapBlack) { return buf.getchannel(x, y, z, c, wrap); } BOOST_PYTHON_FUNCTION_OVERLOADS(ImageBuf_getchannel_overloads, ImageBuf_getchannel, 5, 6) object ImageBuf_getpixel (const ImageBuf &buf, int x, int y, int z=0, ImageBuf::WrapMode wrap = ImageBuf::WrapBlack) { int nchans = buf.nchannels(); float *pixel = ALLOCA (float, nchans); buf.getpixel (x, y, z, pixel, nchans, wrap); PyObject *result = PyTuple_New (nchans); for (int i = 0; i < nchans; ++i) PyTuple_SetItem (result, i, PyFloat_FromDouble(pixel[i])); return object(handle<>(result)); } BOOST_PYTHON_FUNCTION_OVERLOADS(ImageBuf_getpixel_overloads, ImageBuf_getpixel, 3, 5) object ImageBuf_interppixel (const ImageBuf &buf, float x, float y, ImageBuf::WrapMode wrap = ImageBuf::WrapBlack) { int nchans = buf.nchannels(); float *pixel = ALLOCA (float, nchans); buf.interppixel (x, y, pixel, wrap); PyObject *result = PyTuple_New (nchans); for (int i = 0; i < nchans; ++i) PyTuple_SetItem (result, i, PyFloat_FromDouble(pixel[i])); return object(handle<>(result)); } BOOST_PYTHON_FUNCTION_OVERLOADS(ImageBuf_interppixel_overloads, ImageBuf_interppixel, 3, 4) object ImageBuf_interppixel_NDC (const ImageBuf &buf, float x, float y, ImageBuf::WrapMode wrap = ImageBuf::WrapBlack) { int nchans = buf.nchannels(); float *pixel = ALLOCA (float, nchans); buf.interppixel_NDC (x, y, pixel, wrap); return C_to_val_or_tuple (pixel, TypeDesc(TypeDesc::FLOAT,nchans), PyFloat_FromDouble); } BOOST_PYTHON_FUNCTION_OVERLOADS(ImageBuf_interppixel_NDC_overloads, ImageBuf_interppixel_NDC, 3, 4) object ImageBuf_interppixel_NDC_full (const ImageBuf &buf, float x, float y, ImageBuf::WrapMode wrap = ImageBuf::WrapBlack) { int nchans = buf.nchannels(); float *pixel = ALLOCA (float, nchans); buf.interppixel_NDC_full (x, y, pixel, wrap); PyObject *result = PyTuple_New (nchans); for (int i = 0; i < nchans; ++i) PyTuple_SetItem (result, i, PyFloat_FromDouble(pixel[i])); return object(handle<>(result)); } BOOST_PYTHON_FUNCTION_OVERLOADS(ImageBuf_interppixel_NDC_full_overloads, ImageBuf_interppixel_NDC_full, 3, 4) void ImageBuf_setpixel (ImageBuf &buf, int x, int y, int z, tuple p) { std::vector pixel; py_to_stdvector (pixel, p); if (pixel.size()) buf.setpixel (x, y, z, &pixel[0], pixel.size()); } void ImageBuf_setpixel2 (ImageBuf &buf, int x, int y, tuple p) { ImageBuf_setpixel (buf, x, y, 0, p); } void ImageBuf_setpixel1 (ImageBuf &buf, int i, tuple p) { std::vector pixel; py_to_stdvector (pixel, p); if (pixel.size()) buf.setpixel (i, &pixel[0], pixel.size()); } void declare_imagebuf() { enum_("WrapMode") .value("WrapDefault", ImageBuf::WrapDefault ) .value("WrapBlack", ImageBuf::WrapBlack ) .value("WrapClamp", ImageBuf::WrapClamp ) .value("WrapPeriodic", ImageBuf::WrapPeriodic ) .value("WrapMirror", ImageBuf::WrapMirror ) .export_values(); class_ ("ImageBuf") .def(init()) .def(init()) .def(init()) .def("clear", &ImageBuf::clear) .def("reset", &ImageBuf_reset_name) .def("reset", &ImageBuf_reset_name2) .def("reset", &ImageBuf_reset_spec) .add_property ("initialized", &ImageBuf::initialized) .def("init_spec", &ImageBuf::init_spec) .def("read", &ImageBuf_read, ImageBuf_read_overloads()) .def("read", &ImageBuf_read2, ImageBuf_read2_overloads()) .def("write", &ImageBuf_write, ImageBuf_write_overloads()) // FIXME -- write(ImageOut&) // .def("set_write_format", &ImageBuf::set_write_format) .def("set_write_format", &ImageBuf_set_write_format) .def("set_write_tiles", &ImageBuf::set_write_tiles, (arg("width")=0, arg("height")=0, arg("depth")=0)) .def("spec", &ImageBuf::spec, return_value_policy()) .def("nativespec", &ImageBuf::nativespec, return_value_policy()) .def("specmod", &ImageBuf::specmod, return_value_policy()) .add_property("name", &ImageBuf_name) .add_property("file_format_name", &ImageBuf_file_format_name) .add_property("subimage", &ImageBuf::subimage) .add_property("nsubimages", &ImageBuf::nsubimages) .add_property("miplevel", &ImageBuf::miplevel) .add_property("nmiplevels", &ImageBuf::nmiplevels) .add_property("nchannels", &ImageBuf::nchannels) .add_property("orientation", &ImageBuf::orientation) .add_property("oriented_width", &ImageBuf::oriented_width) .add_property("oriented_height", &ImageBuf::oriented_height) .add_property("oriented_x", &ImageBuf::oriented_x) .add_property("oriented_y", &ImageBuf::oriented_y) .add_property("oriented_full_width", &ImageBuf::oriented_full_width) .add_property("oriented_full_height", &ImageBuf::oriented_full_height) .add_property("oriented_full_x", &ImageBuf::oriented_full_x) .add_property("oriented_full_y", &ImageBuf::oriented_full_y) .add_property("xbegin", &ImageBuf::xbegin) .add_property("xend", &ImageBuf::xend) .add_property("ybegin", &ImageBuf::ybegin) .add_property("yend", &ImageBuf::yend) .add_property("zbegin", &ImageBuf::zbegin) .add_property("zend", &ImageBuf::zend) .add_property("xmin", &ImageBuf::xmin) .add_property("xmax", &ImageBuf::xmax) .add_property("ymin", &ImageBuf::ymin) .add_property("ymax", &ImageBuf::ymax) .add_property("zmin", &ImageBuf::zmin) .add_property("zmax", &ImageBuf::zmax) .add_property("roi", &ImageBuf::roi) .add_property("roi_full", &ImageBuf::roi_full, &ImageBuf::set_roi_full) .def("set_full", &ImageBuf_set_full) .add_property("pixels_valid", &ImageBuf::pixels_valid) .add_property("pixeltype", &ImageBuf::pixeltype) .add_property("deep", &ImageBuf::deep) .add_property("has_error", &ImageBuf::has_error) .def("geterror", &ImageBuf::geterror) .def("copy_metadata", &ImageBuf::copy_metadata) .def("copy_pixels", &ImageBuf::copy_pixels) .def("copy", &ImageBuf::copy) .def("swap", &ImageBuf::swap) .def("getchannel", &ImageBuf_getchannel, ImageBuf_getchannel_overloads()) .def("getpixel", &ImageBuf_getpixel, ImageBuf_getpixel_overloads()) .def("interppixel", &ImageBuf_interppixel, ImageBuf_interppixel_overloads()) .def("interppixel_NDC", &ImageBuf_interppixel_NDC, ImageBuf_interppixel_NDC_overloads()) .def("interppixel_NDC_full", &ImageBuf_interppixel_NDC_full, ImageBuf_interppixel_NDC_full_overloads()) .def("setpixel", &ImageBuf_setpixel) .def("setpixel", &ImageBuf_setpixel2) .def("setpixel", &ImageBuf_setpixel1) // FIXME - get_pixels, get_pixel_channels // FIXME -- do we want to provide pixel iterators? ; } } // namespace PyOpenImageIO openimageio-1.3.12~dfsg0.orig/src/python/py_imageoutput.cpp0000644000175000017500000002600312271062644022211 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ // Avoid a compiler warning from a duplication in tiffconf.h/pyconfig.h #undef SIZEOF_LONG #include #include "imageio.h" #include "py_oiio.h" namespace PyOpenImageIO { using namespace boost::python; object ImageOutputWrap::create (const std::string &filename, const std::string& plugin_searchpath="") { ImageOutputWrap *iow = new ImageOutputWrap; iow->m_output = ImageOutput::create(filename, plugin_searchpath); if (iow->m_output == NULL) { delete iow; return object(handle<>(Py_None)); } else { return object(iow); } } ImageOutputWrap::~ImageOutputWrap() { delete m_output; } const ImageSpec& ImageOutputWrap::spec () const { return m_output->spec(); } bool ImageOutputWrap::open (const std::string &name, const ImageSpec &newspec, ImageOutput::OpenMode mode=ImageOutput::Create) { return m_output->open(name, newspec, mode); } bool ImageOutputWrap::open_specs (const std::string &name, tuple &specs) { const size_t length = len(specs); if (length == 0) return false; std::vector Cspecs (length); for (size_t i = 0; i < length; ++i) { extract s (specs[i]); if (! s.check()) { // Tuple item was not an ImageSpec return false; } Cspecs[i] = s(); } return m_output->open (name, int(length), &Cspecs[0]); } bool ImageOutputWrap::close() { return m_output->close(); } // this function creates a read buffer from PyObject which will be used // for all write_ functions. const void * ImageOutputWrap::make_read_buffer (object &buffer, imagesize_t size) { const void *buf = NULL; Py_ssize_t len = 0; int success = PyObject_AsReadBuffer(buffer.ptr(), &buf, &len); if (success != 0 || imagesize_t(len) < size) { throw_error_already_set(); } return buf; } bool ImageOutputWrap::write_scanline (int y, int z, TypeDesc format, object &buffer, stride_t xstride) { const void *array = make_read_buffer (buffer, m_output->spec().scanline_bytes()); return m_output->write_scanline(y, z, format, array, xstride); } bool ImageOutputWrap::write_scanline_bt (int y, int z, TypeDesc::BASETYPE format, object &buffer, stride_t xstride) { return write_scanline (y, z, format, buffer, xstride); } bool ImageOutputWrap::write_scanlines (int ybegin, int yend, int z, TypeDesc format, object &buffer, stride_t xstride) { const void *array = make_read_buffer (buffer, m_output->spec().scanline_bytes()); return m_output->write_scanlines(ybegin, yend, z, format, array, xstride); } bool ImageOutputWrap::write_scanlines_bt (int ybegin, int yend, int z, TypeDesc::BASETYPE format, object &buffer, stride_t xstride) { return write_scanlines (ybegin, yend, z, format, buffer, xstride); } bool ImageOutputWrap::write_tile (int x, int y, int z, TypeDesc format, object &buffer, stride_t xstride, stride_t ystride, stride_t zstride) { imagesize_t size = m_output->spec().tile_bytes(); const void *array = make_read_buffer(buffer, size); return m_output->write_tile(x, y, z, format, array, xstride, ystride, zstride); } bool ImageOutputWrap::write_tile_bt (int x, int y, int z, TypeDesc::BASETYPE format, object &buffer, stride_t xstride, stride_t ystride, stride_t zstride) { return write_tile(x, y, z, format, buffer, xstride, ystride, zstride); } bool ImageOutputWrap::write_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, object &buffer, stride_t xstride, stride_t ystride, stride_t zstride) { imagesize_t size = m_output->spec().tile_bytes(); const void *array = make_read_buffer(buffer, size); return m_output->write_tiles (xbegin, xend, ybegin, yend, zbegin, zend, format, array, xstride, ystride, zstride); } bool ImageOutputWrap::write_tiles_bt (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc::BASETYPE format, object &buffer, stride_t xstride, stride_t ystride, stride_t zstride) { return write_tiles (xbegin, xend, ybegin, yend, zbegin, zend, format, buffer, xstride, ystride, zstride); } bool ImageOutputWrap::write_image (TypeDesc format, object &buffer, stride_t xstride, stride_t ystride, stride_t zstride) { imagesize_t size = m_output->spec().image_bytes(); const void *array = make_read_buffer (buffer, size); if (array) return m_output->write_image (format, array, xstride, ystride, zstride); return false; } bool ImageOutputWrap::write_image_bt (TypeDesc::BASETYPE format, object &data, stride_t xstride, stride_t ystride, stride_t zstride) { return write_image (format, data, xstride, ystride, zstride); } BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_image_overloads, write_image, 2, 5) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_image_bt_overloads, write_image_bt, 2, 5) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_scanline_overloads, write_scanline, 4, 5) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_scanline_bt_overloads, write_scanline_bt, 4, 5) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_scanlines_overloads, write_scanlines, 5, 6) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_scanlines_bt_overloads, write_scanlines_bt, 5, 6) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_tile_overloads, write_tile, 5, 8) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_tile_bt_overloads, write_tile_bt, 5, 8) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_tiles_overloads, write_tiles, 8, 11) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ImageOutputWrap_write_tiles_bt_overloads, write_tiles_bt, 8, 11) bool ImageOutputWrap::copy_image (ImageInputWrap *iiw) { return m_output->copy_image(iiw->m_input); } const char* ImageOutputWrap::format_name (void) const { return m_output->format_name(); } bool ImageOutputWrap::supports (const std::string &feature) const { return m_output->supports(feature); } std::string ImageOutputWrap::geterror()const { return m_output->geterror(); } void declare_imageoutput() { class_("ImageOutput", no_init) .def("create", &ImageOutputWrap::create, (arg("filename"), arg("plugin_searchpath")="")) .staticmethod("create") .def("format_name", &ImageOutputWrap::format_name) .def("supports", &ImageOutputWrap::supports) .def("spec", &ImageOutputWrap::spec, return_value_policy()) .def("open", &ImageOutputWrap::open) .def("open", &ImageOutputWrap::open_specs) .def("close", &ImageOutputWrap::close) .def("write_image", &ImageOutputWrap::write_image, ImageOutputWrap_write_image_overloads()) .def("write_image", &ImageOutputWrap::write_image_bt, ImageOutputWrap_write_image_bt_overloads()) .def("write_scanline", &ImageOutputWrap::write_scanline, ImageOutputWrap_write_scanline_overloads()) .def("write_scanline", &ImageOutputWrap::write_scanline_bt, ImageOutputWrap_write_scanline_bt_overloads()) .def("write_scanlines", &ImageOutputWrap::write_scanlines, ImageOutputWrap_write_scanlines_overloads()) .def("write_scanlines", &ImageOutputWrap::write_scanlines_bt, ImageOutputWrap_write_scanlines_bt_overloads()) .def("write_tile", &ImageOutputWrap::write_tile, ImageOutputWrap_write_tile_overloads()) .def("write_tile", &ImageOutputWrap::write_tile_bt, ImageOutputWrap_write_tile_bt_overloads()) .def("write_tiles", &ImageOutputWrap::write_tiles, ImageOutputWrap_write_tiles_overloads()) .def("write_tiles", &ImageOutputWrap::write_tiles_bt, ImageOutputWrap_write_tiles_bt_overloads()) // FIXME - write_deep_{image,scanlines,tiles} .def("copy_image", &ImageOutputWrap::copy_image) .def("geterror", &ImageOutputWrap::geterror) ; enum_("ImageOutputOpenMode") .value("Create", ImageOutput::Create ) .value("AppendSubimage", ImageOutput::AppendSubimage) .value("AppendMIPLevel", ImageOutput::AppendMIPLevel) .export_values(); } } // namespace PyOpenImageIO openimageio-1.3.12~dfsg0.orig/src/python/iconvert.py0000755000175000017500000002225612271062644020646 0ustar mfvmfv#!/usr/bin/env python # Parse the options the user provided from the command line def option_parser(): parser = OptionParser() parser.add_option("-v", action="store_true", dest="verbose", default=False) parser.add_option("--inplace", action="store_true", dest="inplace", default=False) parser.add_option("-d", dest="data_format_name", default="") parser.add_option("--sRGB", action="store_true", dest="sRGB", default=False) parser.add_option("--tile", nargs=3, dest="tile") parser.add_option("--scanline", action="store_true", dest="scanline", default=False) parser.add_option("--separate", action="store_true", dest="separate", default=False) parser.add_option("--contig", action="store_true", dest="contig", default=False) parser.add_option("--compression", dest="compression") parser.add_option("--quality", type="int", dest="quality", default = -1) parser.add_option("--no-copy-image", action="store_true", dest="no_copy", default=False) parser.add_option("--adjust-time", action="store_true", dest="adjust_time", default=False) parser.add_option("--caption", dest="caption", default=None) parser.add_option("-k", "--keyword", action="append", dest="keywords") parser.add_option("--clear-keywords", action="store_true", default=False) parser.add_option("--attrib", nargs=2, action="append", dest="attribs") parser.add_option("--orientation", type="int", dest="orientation", default = 0) parser.add_option("--rotcw", action="store_true", dest="rotcw", default=False) parser.add_option("--rotccw", action="store_true", dest="rotccw", default=False) parser.add_option("--rot180", action="store_true", dest="rot180", default=False) parser.add_option("--plugin-path", dest="path", default="") # FIXME: I suppose there should be a way to enter input/output files without # having to specify an option, like "python iconvert.py -g 0.9 input.jpg output.jpg" # However, I could not find it in the docs so I've set it that the user has # to put -i and -o before input/output. parser.add_option("-i", action="append", dest="input_files", default=[]) parser.add_option("-o", action="append", dest="output_files", default=[]) (options, args) = parser.parse_args() if len(options.input_files) > len(options.output_files) and not options.inplace: print "Must have both an input and output filename specified" return False if len(options.input_files) == 0 and options.inplace: print "Must have at least one filename specified" return False if (int(options.rotcw) + int(options.rotccw) + int(options.rot180) + \ (options.orientation>0)) > 1: print "iconvert: more than one of --rotcw, --rotccw, --rot180, --orientation" return False if options.path == "": print "OIIO plugin path not provided, assuming \"\"" return parser.parse_args() def convert_files(in_file, out_file): nocopy = options.no_copy tempname = out_file # Check whether the conversion is inplace. if tempname == in_file: try: ext = out_file.rfind(".") tempname += ".tmp" + out_file[ext:] except: print "Error: Output file does not have an extension" # image input inp = oiio.ImageInput.create(in_file, options.path) if not inp: msg = "Could not crete ImageInput for " + in_file sys.exit(msg) inspec = oiio.ImageSpec() inp.open(in_file, inspec) # image output out = oiio.ImageOutput.create(tempname, options.path) if not out: msg = "Unable to create ImageOutput for " + out_file sys.exit(msg) # adjust spec outspec = inspec nocopy = adjust_spec(inp, inspec, outspec) out.open(tempname, outspec, oiio.ImageOutputOpenMode.Create) # convert if nocopy == False: ok = out.copy_image(inp) if not ok: print "Error" else: arr = array.array("B", "\0" * inspec.image_bytes()) ok = inp.read_image(outspec.format, arr) if not ok: print "Error reading" else: ok = out.write_image(outspec.format, arr) if not ok: print "Error writing" out.close() inp.close() # if the conversion was --inplace, this will result to True if out_file != tempname: if ok: # since it was inplace, in_file == out_file # so we need to replace the original file with tempfile os.remove(out_file) os.rename(tempname, out_file) else: os.remove(tempname) def adjust_spec(inp, inspec, outspec): nocopy = options.no_copy # the following line is from the original iconvert, but I'm not sure # it is needed. It's already outspec = inspec, right? #outspec.set_format(inspec.format) if options.data_format_name != "": if data_format_name == "uint8": outspec.set_format(oiio.BASETYPE.UINT8) elif data_format_name == "int8": outspec.set_format(oiio.BASETYPE.INT8) elif data_format_name == "uint16": outspec.set_format(oiio.BASETYPE.UINT16) elif data_format_name == "int16": outspec.set_format(oiio.BASETYPE.INT16) elif data_format_name == "half": outspec.set_format(oiio.BASETYPE.HALF) elif data_format_name == "float": outspec.set_format(oiio.BASETYPE.FLOAT) elif data_format_name == "double": outspec.set_format(oiio.BASETYPE.DOUBLE) if outspec.format != inspec.format: nocopy = True if options.sRGB: outspec.linearity = oiio.sRGB #ImageSpec.find_attribute() is not exposed to Python #if inp.format_name() != "jpeg" or outspec.find_attribute("Exif:ColorSpace"): #outspec.attribute("Exif:ColorSpace", 1) # handling tiles is not exposed to Python if options.tile: outspec.tile_width = options.tile[0] outspec.tile_height = options.tile[1] outspec.tile_depth = options.tile[2] if options.scanline: outspec.tile_width = 0 outspec.tile_height = 0 outspec.tile_depth = 0 if outspec.tile_width != inspec.tile_width or \ outspec.tile_height != inspec.tile_height or \ outspec.tile_depth != inspec.tile_depth: nocopy = True if options.compression: outspec.attribute("compression", options.compression) # 2nd argument should be exposed as default if options.compression != inspec.get_string_attribute("compression", ""): nocopy = True # FIXME: If quality is provided, the resultig image is larger than the # input image, and it is always the same no matter what quality (1-100). # (I suppose it uses the maximum possible value) # Should a --compression method be provided if --quality is used? if options.quality > 0: outspec.attribute("CompressionQuality", options.quality) # the 2nd argument should be exposed as default (in ImageSpec wrapper) # FIXME: The default arg is supposed to be 0, and get_int_attribute always # returns whatever is provided as the 2nd argument - 0 in this case. # I can't find out what's wrong in the binding. if options.quality != inspec.get_int_attribute("CompressionQuality", 0): nocopy = True if options.contig: outspec.attribute("planarconfig", "contig") if options.separate: outspec.attribute("planarconfig", "separate") if options.orientation >= 1: outspec.attribute("Orientation", options.orientation) else: orientation = outspec.get_int_attribute("Orientation", 1) if orientation >= 1 and orientation <= 8: cw = [0, 6, 7, 8, 5, 2, 3, 4, 1] if options.rotcw or options.rotccw or options.rot180: orientation = cw[orientation] if options.rotcw or options.rot180: orientation = cw[orientation] if options.rotccw: orientation = cw[orientation] outspec.attribute("Orientation", orientation) if options.caption != None: outspec.attribute("ImageDescription", options.caption) if options.clear_keywords == True: outspec.attribute("Keywords", "") # this looks a lot simpler than in c++ :) if options.keywords != None: oldkw = outspec.get_string_attribute("Keywords", "") newkw = oldkw for keyword in options.keywords: newkw += "; " + keyword outspec.attribute("Keywords", newkw) if options.attribs: for i in options.attribs: outspec.attribute(i[0], i[1]) return nocopy # main import OpenImageIO as oiio import array from optparse import OptionParser import os import sys (options, args) = option_parser() if options.inplace: for image in options.input_files: if convert_files(image, image) == False: sys.exit("Conversion failed") else: for i in range(len(options.input_files)): if convert_files(options.input_files[i], options.output_files[i]) == False: sys.exit("Conversion failed") openimageio-1.3.12~dfsg0.orig/src/python/python_tests0000644000175000017500000000572012271062644021123 0ustar mfvmfvI just copy-paste these bits of code to the Python console. read-image: import OpenImageIO as o import array spec = o.ImageSpec() pic = o.ImageInput.create("test.jpg", "/home/dgaletic/code/oiio-trunk/dist/linux/lib") pic.open("test.jpg", spec) desc = spec.format arr = array.array("B", "\0" * spec.image_bytes()) pic.read_image(desc, arr) read-image-simple (reads to continuous float pixels): import OpenImageIO as o spec = o.ImageSpec() pic = o.ImageInput.create("test.jpg", "/home/dgaletic/code/oiio-trunk/dist/linux/lib") pic.open("test.jpg", spec) desc = spec.format arr = pic.read_image() read and write file scanline by scanline: import OpenImageIO as o import array spec = o.ImageSpec() pic = o.ImageInput.create("test.jpg", "/home/dgaletic/code/oiio-trunk/dist/linux/lib") pic.open("test.jpg", spec) out = o.ImageOutput.create("test-scanline.jpg", "/home/dgaletic/code/oiio-trunk/dist/linux/lib") out.open("test-scanline.jpg", spec, False) desc = spec.format for i in range(spec.height): arr = array.array("B", "\0" * spec.width * spec.nchannels) pic.read_scanline(i, 0, desc, arr) out.write_scanline(i, 0, desc, arr) out.close() write-image: out = o.ImageOutput.create("test.jpg", "/home/dgaletic/code/oiio-trunk/dist/linux/lib") out.open("test-scanline.jpg", spec, False) out.write_image(desc, arr) out.close() brighter: for channel in range (len(arr)): if arr[channel] <= 240: arr[channel] += 15 else: arr[channel] = 255 darken only the very bright areas of the picture (please don't consider this a serious algorithm): for channel in range (0, len(arr), 3): if arr[channel] + arr[channel+1] + arr[channel+2] > 600: arr[channel] += -60 arr[channel+1] += -60 arr[channel+2] += -60 To alter which color gets changed, simply change the start value in range() function. If there are three channels (RGB) and the step is set to 3, a start value of 0 will change all the red pixel values, 1 green, and 2 blue. red: for channel in range (0, len(arr), 3): if arr[channel] <= 200: arr[channel] += 55 else: arr[channel] = 255 The step is set to 4 here because the test was performed on a four channel image (RGBA). only red: for channel in range (0, len(arr), 4): arr[channel+1] = 0 arr[channel+2] = 0 high red: for channel in range (0, len(arr), 4): arr[channel] = 255 gamma: for channel in range (len(arr)): value = arr[channel]**0.98 arr[channel] = int(value) random (this one does nothing useful, just changes the RGB values of each pixel by +-50, to a maximum of 0/255 ): import random for channel in range (len(arr)): value = random.randrange(arr[channel]-50, arr[channel]+50) if value > 255: arr[channel] = 255 elif value < 0: arr[channel] = 0 else: arr[channel] = value grayscale: for channel in range(0, len(arr), 3): arr[channel] = arr[channel+1] = arr[channel+2] = (arr[channel] + arr[channel+1] + arr[channel+2]) / 3 openimageio-1.3.12~dfsg0.orig/src/python/py_imageinput.cpp0000644000175000017500000003245212271062644022015 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "py_oiio.h" namespace PyOpenImageIO { using namespace boost::python; object ImageInputWrap::open_static_regular (const std::string &filename) { ImageInputWrap* iiw = new ImageInputWrap; iiw->m_input = ImageInput::open(filename); if (iiw->m_input == NULL) { delete iiw; return object(handle<>(Py_None)); } else { return object(iiw); } } object ImageInputWrap::open_static_with_config (const std::string &filename, const ImageSpec &config) { ImageInputWrap* iiw = new ImageInputWrap; iiw->m_input = ImageInput::open(filename, &config); if (iiw->m_input == NULL) { delete iiw; return object(handle<>(Py_None)); } else { return object(iiw); } } object ImageInputWrap::create(const std::string &filename, const std::string &plugin_searchpath) { ImageInputWrap* iiw = new ImageInputWrap; iiw->m_input = ImageInput::create(filename, plugin_searchpath); if (iiw->m_input == NULL) { delete iiw; return object(handle<>(Py_None)); } else { return object(iiw); } } ImageInputWrap::~ImageInputWrap() { delete m_input; } const char* ImageInputWrap::format_name() const { return m_input->format_name(); } bool ImageInputWrap::valid_file (const std::string &filename) const { return m_input->valid_file (filename); } bool ImageInputWrap::open_regular (const std::string &name) { ImageSpec newspec; return m_input->open(name, newspec); } bool ImageInputWrap::open_with_config (const std::string &name, const ImageSpec &config) { ImageSpec newspec; return m_input->open(name, newspec, config); } const ImageSpec& ImageInputWrap::spec() const { return m_input->spec(); } bool ImageInputWrap::supports (const std::string &feature) const { return m_input->supports (feature); } bool ImageInputWrap::close() { return m_input->close(); } int ImageInputWrap::current_subimage() const { return m_input->current_subimage(); } int ImageInputWrap::current_miplevel() const { return m_input->current_miplevel(); } bool ImageInputWrap::seek_subimage(int subimage, int miplevel) { ImageSpec dummyspec; return m_input->seek_subimage (subimage, miplevel, dummyspec); } const char * python_array_code (TypeDesc format) { switch (format.basetype) { case TypeDesc::UINT8 : return "B"; case TypeDesc::INT8 : return "b"; case TypeDesc::UINT16 : return "H"; case TypeDesc::INT16 : return "h"; case TypeDesc::UINT32 : return "I"; case TypeDesc::INT32 : return "i"; case TypeDesc::FLOAT : return "f"; case TypeDesc::DOUBLE : return "d"; default : return "f"; // Punt -- return float } } object C_array_to_Python_array (const char *data, TypeDesc type, size_t size) { // Construct a Python array, convert the buffer we read into a string // and then into the array. object arr_module(handle<>(PyImport_ImportModule("array"))); object array = arr_module.attr("array")(python_array_code(type)); #if PY_MAJOR_VERSION >= 3 object string_py(handle<>(PyBytes_FromStringAndSize(data, size))); #else object string_py(handle<>(PyString_FromStringAndSize(data, size))); #endif #if (PY_MAJOR_VERSION < 3) || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 2) array.attr("fromstring")(string_py); #else array.attr("frombytes")(string_py); #endif return array; } // The read_image method is a bit different from the c++ interface. // "function" is a function which takes a float, and the // PyProgressCallback function is called automatically. object ImageInputWrap::read_image (TypeDesc format) { // Allocate our own temp buffer and try to read the image into it. // If the read fails, return None. const ImageSpec &spec = m_input->spec(); size_t size = (size_t) spec.image_pixels() * spec.nchannels * format.size(); char *data = new char[size]; if (!m_input->read_image(format, data)) { delete [] data; // never mind return object(handle<>(Py_None)); } object array = C_array_to_Python_array (data, format, size); // clean up and return the array handle delete [] data; return array; } object ImageInputWrap_read_image_bt (ImageInputWrap& in, TypeDesc::BASETYPE format) { return in.read_image (format); } object ImageInputWrap_read_image_default (ImageInputWrap& in) { return in.read_image (TypeDesc::UNKNOWN); } object ImageInputWrap::read_scanline (int y, int z, TypeDesc format) { // Allocate our own temp buffer and try to read the scanline into it. // If the read fails, return None. const ImageSpec &spec = m_input->spec(); size_t size = (size_t) spec.width * spec.nchannels * format.size(); char *data = new char[size]; if (!m_input->read_scanline (y, z, format, data)) { delete [] data; // never mind return object(handle<>(Py_None)); } object array = C_array_to_Python_array (data, format, size); // clean up and return the array handle delete [] data; return array; } object ImageInputWrap_read_scanline_bt (ImageInputWrap& in, int y, int z, TypeDesc::BASETYPE format) { return in.read_scanline (y, z, format); } object ImageInputWrap_read_scanline_default (ImageInputWrap& in, int y, int z) { return in.read_scanline (y, z, TypeDesc::UNKNOWN); } object ImageInputWrap::read_scanlines (int ybegin, int yend, int z, int chbegin, int chend, TypeDesc format) { // Allocate our own temp buffer and try to read the scanline into it. // If the read fails, return None. ASSERT (m_input); const ImageSpec &spec = m_input->spec(); chend = clamp (chend, chbegin+1, spec.nchannels); int nchans = chend - chbegin; size_t size = (size_t) spec.width * (yend-ybegin) * nchans * format.size(); char *data = new char[size]; if (!m_input->read_scanlines (ybegin, yend, z, format, data)) { delete [] data; // never mind return object(handle<>(Py_None)); } object array = C_array_to_Python_array (data, format, size); // clean up and return the array handle delete [] data; return array; } object ImageInputWrap_read_scanlines_bt (ImageInputWrap& in, int ybegin, int yend, int z, int chbegin, int chend, TypeDesc::BASETYPE format) { return in.read_scanlines (ybegin, yend, z, chbegin, chend, format); } object ImageInputWrap_read_scanlines_default (ImageInputWrap& in, int ybegin, int yend, int z, int chbegin, int chend) { return in.read_scanlines (ybegin, yend, z, chbegin, chend, TypeDesc::UNKNOWN); } object ImageInputWrap::read_tile (int x, int y, int z, TypeDesc format) { // Allocate our own temp buffer and try to read the scanline into it. // If the read fails, return None. const ImageSpec &spec = m_input->spec(); size_t size = (size_t) spec.tile_pixels() * spec.nchannels * format.size(); char *data = new char[size]; if (!m_input->read_tile (x, y, z, format, data)) { delete [] data; // never mind return object(handle<>(Py_None)); } object array = C_array_to_Python_array (data, format, size); // clean up and return the array handle delete [] data; return array; } object ImageInputWrap_read_tile_bt (ImageInputWrap& in, int x, int y, int z, TypeDesc::BASETYPE format) { return in.read_tile (x, y, z, format); } object ImageInputWrap_read_tile_default (ImageInputWrap& in, int x, int y, int z) { return in.read_tile (x, y, z, TypeDesc::UNKNOWN); } object ImageInputWrap::read_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format) { // Allocate our own temp buffer and try to read the scanline into it. // If the read fails, return None. const ImageSpec &spec = m_input->spec(); chend = clamp (chend, chbegin+1, spec.nchannels); int nchans = chend - chbegin; size_t size = (size_t) ((xend-xbegin) * (yend-ybegin) * (zend-zbegin) * nchans * format.size()); char *data = new char[size]; if (!m_input->read_tiles (xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend, format, data)) { delete [] data; // never mind return object(handle<>(Py_None)); } object array = C_array_to_Python_array (data, format, size); // clean up and return the array handle delete [] data; return array; } object ImageInputWrap_read_tiles_bt (ImageInputWrap& in, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc::BASETYPE format) { return in.read_tiles (xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend, format); } object ImageInputWrap_read_tiles_default (ImageInputWrap& in, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend) { return in.read_tiles (xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend, TypeDesc::UNKNOWN); } std::string ImageInputWrap::geterror() const { return m_input->geterror(); } void declare_imageinput() { class_("ImageInput", no_init) .def("create", &ImageInputWrap::create, (arg("filename"), arg("plugin_searchpath")="")) .staticmethod("create") .def("open", &ImageInputWrap::open_static_regular, (arg("filename"))) .def("open", &ImageInputWrap::open_static_with_config, (arg("filename"))) .staticmethod("open") .def("format_name", &ImageInputWrap::format_name) .def("valid_file", &ImageInputWrap::valid_file) // .def("open", &ImageInputWrap::open_regular) // .def("open", &ImageInputWrap::open_with_config) .def("spec", &ImageInputWrap::spec, return_value_policy()) .def("supports", &ImageInputWrap::supports) .def("close", &ImageInputWrap::close) .def("current_subimage", &ImageInputWrap::current_subimage) .def("current_miplevel", &ImageInputWrap::current_miplevel) .def("seek_subimage", &ImageInputWrap::seek_subimage) .def("read_scanline", &ImageInputWrap::read_scanline) .def("read_scanline", &ImageInputWrap_read_scanline_bt) .def("read_scanline", &ImageInputWrap_read_scanline_default) .def("read_scanlines", &ImageInputWrap::read_scanlines) .def("read_scanlines", &ImageInputWrap_read_scanlines_bt) .def("read_scanlines", &ImageInputWrap_read_scanlines_default) .def("read_tile", &ImageInputWrap::read_tile) .def("read_tile", &ImageInputWrap_read_tile_bt) .def("read_tile", &ImageInputWrap_read_tile_default) .def("read_tiles", &ImageInputWrap::read_tiles) .def("read_tiles", &ImageInputWrap_read_tiles_bt) .def("read_tiles", &ImageInputWrap_read_tiles_default) .def("read_image", &ImageInputWrap::read_image) .def("read_image", &ImageInputWrap_read_image_bt) .def("read_image", &ImageInputWrap_read_image_default) //FIXME: read_native_deep_{scanlines,tiles,image} .def("geterror", &ImageInputWrap::geterror) ; } } // namespace PyOpenImageIO openimageio-1.3.12~dfsg0.orig/src/python/py_paramvalue.cpp0000644000175000017500000001270312271062644022005 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "py_oiio.h" namespace PyOpenImageIO { using namespace boost::python; using namespace std; template object ParamValue_convert(const TypeDesc& t, int n, const BaseType* data) { switch (t.aggregate) { case TypeDesc::SCALAR: return object(data[n]); case TypeDesc::VEC2: return make_tuple(data[n*2], data[n*2+1]); case TypeDesc::VEC3: return make_tuple(data[n*3], data[n*3+1], data[n*3+2]); case TypeDesc::VEC4: return make_tuple(data[n*4], data[n*4+1], data[n*4+2], data[n*4+3]); // Bypass the make_tuple argument list size limit by making two // tuples and adding them. Inefficient, but not likely to be a bottleneck. // If it turns out we need efficient access to this stuff we should look // at an array/ctypes interface. case TypeDesc::MATRIX44: return make_tuple( data[n*16+0], data[n*16+1], data[n*16+2], data[n*16+3], data[n*16+4], data[n*16+5], data[n*16+6], data[n*16+7]) + make_tuple(data[n*16+8], data[n*16+9], data[n*16+10], data[n*16+11], data[n*16+12], data[n*16+13], data[n*16+14], data[n*16+15]); default: PyErr_SetString(PyExc_TypeError, "Unable to convert ParamValue with unknown TypeDesc"); throw_error_already_set(); } return object(); } object ParamValue_getitem(const ParamValue& self, int n) { if (n >= self.nvalues()) { PyErr_SetString(PyExc_IndexError, "ParamValue index out of range"); throw_error_already_set(); } TypeDesc t = self.type(); #define ParamValue_convert_dispatch(TYPE) \ case TypeDesc::TYPE: \ return ParamValue_convert(t,n,(CType::type*)self.data()); switch (t.basetype) { ParamValue_convert_dispatch(UCHAR) ParamValue_convert_dispatch(CHAR) ParamValue_convert_dispatch(USHORT) ParamValue_convert_dispatch(SHORT) ParamValue_convert_dispatch(UINT) ParamValue_convert_dispatch(INT) ParamValue_convert_dispatch(ULONGLONG) ParamValue_convert_dispatch(LONGLONG) #ifdef _HALF_H_ ParamValue_convert_dispatch(HALF) #endif ParamValue_convert_dispatch(FLOAT) ParamValue_convert_dispatch(DOUBLE) case TypeDesc::STRING: return ParamValue_convert(t, n, (ustring*)self.data()); default: return object(); } #undef ParamValue_convert_dispatch } static std::string ParamValue_name(const ParamValue& self) { return self.name().string(); } static object ParamValue_value (const ParamValue& self) { return ParamValue_getitem (self, 0); } ParamValue& ParamValueList_getitem(ParamValueList& self, int i) { return self[i]; } void declare_paramvalue() { enum_("Interp") .value("INTERP_CONSTANT", ParamValue::INTERP_CONSTANT) .value("INTERP_PERPIECE", ParamValue::INTERP_PERPIECE) .value("INTERP_LINEAR", ParamValue::INTERP_LINEAR) .value("INTERP_VERTEX", ParamValue::INTERP_VERTEX) ; class_("ParamValue") .add_property("name", &ParamValue_name) .add_property("type", &ParamValue::type) .add_property("value", &ParamValue_value) .def("__getitem__", &ParamValue_getitem) .def("__len__", &ParamValue::nvalues) ; class_("ParamValueList") .def("__getitem__", &ParamValueList_getitem, return_internal_reference<>()) .def("__iter__", boost::python::iterator()) .def("__len__", &ParamValueList::size) .def("grow", &ParamValueList::grow, return_internal_reference<>()) .def("append", &ParamValueList::push_back) .def("clear", &ParamValueList::clear) .def("free", &ParamValueList::free) .def("resize", &ParamValueList::resize) ; } } openimageio-1.3.12~dfsg0.orig/src/python/py_oiio.h0000644000175000017500000002322312271062644020253 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef PYOPENIMAGEIO_PY_OIIO_H #define PYOPENIMAGEIO_PY_OIIO_H // Avoid a compiler warning from a duplication in tiffconf.h/pyconfig.h #undef SIZEOF_LONG #include #include "imageio.h" #include "typedesc.h" #include "imagecache.h" #include "imagebuf.h" #if PY_MAJOR_VERSION < 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5) #define Py_ssize_t int #endif namespace PyOpenImageIO { using namespace boost::python; OIIO_NAMESPACE_USING void declare_imagespec(); void declare_imageinput(); void declare_imageoutput(); void declare_typedesc(); void declare_roi(); void declare_imagecache(); void declare_imagebuf(); void declare_imagebufalgo(); void declare_paramvalue(); void declare_global(); bool PyProgressCallback(void*, float); // Suck up one or more presumed T values into a vector template void py_to_stdvector (std::vector &vals, const object &obj) { extract tup (obj); if (tup.check()) { // tuple case: recurse for (int i = 0, e = len(tup()); i < e; ++i) py_to_stdvector (vals, tup()[i]); } else { // non-tuple case extract t (obj); vals.push_back (t.check() ? t() : T()); } } // Suck up a tuple of presumed T values into a vector template void py_to_stdvector (std::vector &vals, const tuple &tup) { for (int i = 0, e = len(tup); i < e; ++i) py_to_stdvector (vals, tup[i]); } // Convert an array of T values into either tuple. FUNC is a conversion // function such as PyInt_FromLong, PyFloat_FromDouble, or // PyString_FromString. template object C_to_tuple (const T *vals, int size, FUNC f) { PyObject* result = PyTuple_New (size); for (int i = 0; i < size; ++i) PyTuple_SetItem(result, i, f(vals[i])); return object(handle<>(result)); } // Convert an array of T values (described by type) into either a simple // Python object (if it's an int, float, or string and a SCALAR) or a // Python tuple. FUNC is a conversion function such as PyInt_FromLong, // PyFloat_FromDouble, or PyString_FromString. template object C_to_val_or_tuple (const T *vals, TypeDesc type, FUNC f) { if (type.arraylen == 0 && type.aggregate == TypeDesc::SCALAR) { // scalar case return object (vals[0]); } // Array/aggregate case -- return a tuple int size = type.numelements() * type.aggregate; return C_to_tuple (vals, size, f); } class ImageInputWrap { private: /// Friend declaration for ImageOutputWrap::copy_image friend class ImageOutputWrap; ImageInput *m_input; public: virtual ~ImageInputWrap(); static object create(const std::string&, const std::string&); static object open_static_regular(const std::string&); static object open_static_with_config(const std::string&,const ImageSpec&); const char *format_name () const; bool valid_file (const std::string &name) const; bool open_regular (const std::string &name); bool open_with_config(const std::string &name, const ImageSpec &config); const ImageSpec &spec() const; bool supports (const std::string &feature) const; bool close(); int current_subimage() const; int current_miplevel() const; bool seek_subimage (int, int); object read_image (TypeDesc); object read_scanline (int y, int z, TypeDesc format); object read_scanlines (int ybegin, int yend, int z, int chbegin, int chend, TypeDesc format); object read_tile (int x, int y, int z, TypeDesc format); object read_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format); std::string geterror() const; }; class ImageOutputWrap { private: friend class ImageBufWrap; ImageOutput *m_output; const void *make_read_buffer (object &buffer, imagesize_t size); public: virtual ~ImageOutputWrap(); static boost::python::object create(const std::string&, const std::string&); const ImageSpec &spec() const; bool open (const std::string&, const ImageSpec&, ImageOutput::OpenMode); bool open_specs (const std::string&, tuple &specs); bool close(); bool write_scanline (int, int, TypeDesc, boost::python::object&, stride_t xstride=AutoStride); bool write_scanline_bt (int, int, TypeDesc::BASETYPE, boost::python::object&, stride_t xstride=AutoStride); bool write_scanlines (int, int, int, TypeDesc, boost::python::object&, stride_t xstride=AutoStride); bool write_scanlines_bt (int, int, int, TypeDesc::BASETYPE, boost::python::object&, stride_t xstride=AutoStride); bool write_tile (int, int, int, TypeDesc, boost::python::object&, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); bool write_tile_bt (int, int, int, TypeDesc::BASETYPE, boost::python::object&, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); bool write_tiles (int, int, int, int, int, int, TypeDesc, boost::python::object&, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); bool write_tiles_bt (int, int, int, int, int, int, TypeDesc::BASETYPE, boost::python::object&, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); bool write_image (TypeDesc format, object &buffer, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); bool write_image_bt (TypeDesc::BASETYPE basetype, object &buffer, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); bool copy_image (ImageInputWrap *iiw); const char *format_name () const; bool supports (const std::string&) const; std::string geterror()const; }; class ImageCacheWrap { private: friend class ImageBufWrap; ImageCache *m_cache; public: static ImageCacheWrap *create (bool); static void destroy (ImageCacheWrap*); void clear (); bool attribute (const std::string&, TypeDesc, const void*); bool attribute_int (const std::string&, int ); bool attribute_float (const std::string&, float); bool attribute_double (const std::string&, double); bool attribute_char (const std::string&, const char*); bool attribute_string (const std::string&, const std::string&); bool getattribute(const std::string&, TypeDesc, void*); bool getattribute_int (const std::string&, int&); bool getattribute_float(const std::string&, float&); bool getattribute_double(const std::string&, double&); bool getattribute_char(const std::string&, char**); bool getattribute_string(const std::string&, std::string&); std::string resolve_filename (const std::string&); bool get_image_info (ustring, ustring, TypeDesc, void*); bool get_imagespec(ustring, ImageSpec&, int); bool get_pixels (ustring, int, int, int, int, int, int, int, int, TypeDesc, void*); //First needs to be exposed to python in imagecache.cpp /* Tile *get_tile (ustring filename, int subimage, int x, int y, int z) { return m_cache->get_tile(filename, subimage, x, y, z); } void release_tile (Tile *tile) const { m_cache->release-tile(tile); } const void *tile_pixels (Tile *tile, TypeDesc &format) const { m_cache->tile_pixels(tile, format); } */ std::string geterror () const; std::string getstats (int) const; void invalidate (ustring); void invalidate_all (bool); }; } // namespace PyOpenImageIO #endif // PYOPENIMAGEIO_PY_OIIO_H openimageio-1.3.12~dfsg0.orig/src/python/py_typedesc.cpp0000644000175000017500000001637512271062644021501 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "py_oiio.h" namespace PyOpenImageIO { using namespace boost::python; using self_ns::str; static TypeDesc::BASETYPE TypeDesc_get_basetype (const TypeDesc &t) { return (TypeDesc::BASETYPE)t.basetype; } static TypeDesc::AGGREGATE TypeDesc_get_aggregate (const TypeDesc &t) { return (TypeDesc::AGGREGATE)t.aggregate; } static TypeDesc::VECSEMANTICS TypeDesc_get_vecsemantics (const TypeDesc &t) { return (TypeDesc::VECSEMANTICS)t.vecsemantics; } static void TypeDesc_set_basetype (TypeDesc &t, TypeDesc::BASETYPE val) { t.basetype = val; } static void TypeDesc_set_aggregate (TypeDesc &t, TypeDesc::AGGREGATE val) { t.aggregate = val; } static void TypeDesc_set_vecsemantics (TypeDesc &t, TypeDesc::VECSEMANTICS val) { t.vecsemantics = val; } // Declare the OIIO TypeDesc type to Python void declare_typedesc() { enum_("BASETYPE") .value("UNKNOWN", TypeDesc::UNKNOWN) .value("NONE", TypeDesc::NONE) .value("UCHAR", TypeDesc::UCHAR) .value("UINT8", TypeDesc::UINT8) .value("CHAR", TypeDesc::CHAR) .value("INT8", TypeDesc::INT8) .value("USHORT", TypeDesc::USHORT) .value("UINT16", TypeDesc::UINT16) .value("SHORT", TypeDesc::SHORT) .value("INT16", TypeDesc::INT16) .value("UINT", TypeDesc::UINT) .value("UINT32", TypeDesc::UINT32) .value("INT", TypeDesc::INT) .value("INT32", TypeDesc::INT32) .value("ULONGLONG", TypeDesc::ULONGLONG) .value("UINT64", TypeDesc::UINT64) .value("LONGLONG", TypeDesc::LONGLONG) .value("INT64", TypeDesc::INT64) .value("HALF", TypeDesc::HALF) .value("FLOAT", TypeDesc::FLOAT) .value("DOUBLE", TypeDesc::DOUBLE) .value("STRING", TypeDesc::STRING) .value("PTR", TypeDesc::PTR) .value("LASTBASE", TypeDesc::LASTBASE) .export_values() ; enum_("AGGREGATE") .value("SCALAR", TypeDesc::SCALAR) .value("VEC2", TypeDesc::VEC2) .value("VEC3", TypeDesc::VEC3) .value("VEC4", TypeDesc::VEC4) .value("MATRIX44", TypeDesc::MATRIX44) .export_values() ; enum_("VECSEMANTICS") .value("NOXFORM", TypeDesc::NOXFORM) .value("NOSEMANTICS", TypeDesc::NOSEMANTICS) .value("COLOR", TypeDesc::COLOR) .value("POINT", TypeDesc::POINT) .value("VECTOR", TypeDesc::VECTOR) .value("NORMAL", TypeDesc::NORMAL) .value("TIMECODE", TypeDesc::TIMECODE) .value("KEYCODE", TypeDesc::KEYCODE) .export_values() ; class_("TypeDesc") // basetype, aggregate, and vecsemantics should look like BASETYPE, // AGGREGATE, VECSEMANTICS, but since they are stored as unsigned // char, def_readwrite() doesn't do the right thing. Instead, we // use set_foo/get_foo wrappers, but from Python it looks like // regular member access. .add_property("basetype", &TypeDesc_get_basetype, &TypeDesc_set_basetype) .add_property("aggregate", &TypeDesc_get_aggregate, &TypeDesc_set_aggregate) .add_property("vecsemantics", &TypeDesc_get_vecsemantics, &TypeDesc_set_vecsemantics) .def_readwrite("arraylen", &TypeDesc::arraylen) // Constructors: () [defined implicitly], (base), (base, agg), // (base,agg,vecsem), (base,agg,vecsem,arraylen), string. .def(init()) .def(init()) .def(init()) .def(init()) .def(init()) // Unfortunately, overloading the int varieties, as we do in C++, // doesn't seem to work properly, it can't distinguish between an // int and an AGGREGATE, for example. Maybe in C++11 with strong // enum typing, it will work. But for now, we must forego these // variants of the constructors: // .def(init()) // .def(init()) .def("c_str", &TypeDesc::c_str) .def("numelements", &TypeDesc::numelements) .def("size", &TypeDesc::size) .def("elementtype", &TypeDesc::elementtype) .def("elementsize", &TypeDesc::elementsize) .def("basesize", &TypeDesc::basesize) .def("fromstring", &TypeDesc::fromstring) .def("equivalent", &TypeDesc::equivalent) .def("unarray", &TypeDesc::unarray) // overloaded operators .def(self == other()) // operator== .def(self != other()) // operator!= // Define Python str(TypeDesc), it automatically uses '<<' .def(str(self)) // __str__ // Static members of pre-constructed types .def_readonly("TypeFloat", &TypeDesc::TypeFloat) .def_readonly("TypeColor", &TypeDesc::TypeColor) .def_readonly("TypeString", &TypeDesc::TypeString) .def_readonly("TypeInt", &TypeDesc::TypeInt) .def_readonly("TypePoint", &TypeDesc::TypePoint) .def_readonly("TypeVector", &TypeDesc::TypeVector) .def_readonly("TypeNormal", &TypeDesc::TypeNormal) .def_readonly("TypeMatrix", &TypeDesc::TypeMatrix) .def_readonly("TypeTimeCode", &TypeDesc::TypeTimeCode) .def_readonly("TypeKeyCode", &TypeDesc::TypeKeyCode) ; } } // namespace PyOpenImageIO openimageio-1.3.12~dfsg0.orig/src/python/py_oiio.cpp0000644000175000017500000001560312271062644020611 0ustar mfvmfv/* Copyright 2009 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "py_oiio.h" namespace PyOpenImageIO { using namespace boost::python; struct ustring_to_python_str { static PyObject* convert(ustring const& s) { return boost::python::incref(boost::python::object(s.string()).ptr()); } }; struct ustring_from_python_str { ustring_from_python_str() { boost::python::converter::registry::push_back( &convertible, &construct, boost::python::type_id()); } static void* convertible(PyObject* obj_ptr) { #if PY_MAJOR_VERSION >= 3 if (!PyUnicode_Check(obj_ptr)) return 0; #else if (!PyString_Check(obj_ptr)) return 0; #endif return obj_ptr; } static void construct( PyObject* obj_ptr, boost::python::converter::rvalue_from_python_stage1_data* data) { #if PY_MAJOR_VERSION >= 3 PyObject* pyStr = PyUnicode_AsUTF8String(obj_ptr); const char* value = PyBytes_AsString(pyStr); #else const char* value = PyString_AsString(obj_ptr); #endif if (value == 0) boost::python::throw_error_already_set(); void* storage = ( (boost::python::converter::rvalue_from_python_storage*) data)->storage.bytes; new (storage) ustring(value); data->convertible = storage; } }; bool oiio_attribute_int (const std::string &name, int val) { return OIIO::attribute (name, val); } bool oiio_attribute_float (const std::string &name, float val) { return OIIO::attribute (name, val); } bool oiio_attribute_string (const std::string &name, const std::string &val) { return OIIO::attribute (name, val); } bool oiio_attribute_typed (const std::string &name, TypeDesc type, object &obj) { if (type.basetype == TypeDesc::INT) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) return OIIO::attribute (name, type, &vals[0]); return false; } if (type.basetype == TypeDesc::FLOAT) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) return OIIO::attribute (name, type, &vals[0]); return false; } if (type.basetype == TypeDesc::STRING) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) { std::vector u; for (size_t i = 0, e = vals.size(); i < e; ++i) u.push_back (ustring(vals[i])); return OIIO::attribute (name, type, &u[0]); } return false; } return false; } bool oiio_attribute_tuple_typed (const std::string &name, TypeDesc type, tuple &obj) { if (type.basetype == TypeDesc::INT) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) return OIIO::attribute (name, type, &vals[0]); return false; } if (type.basetype == TypeDesc::FLOAT) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) return OIIO::attribute (name, type, &vals[0]); return false; } if (type.basetype == TypeDesc::STRING) { std::vector vals; py_to_stdvector (vals, obj); if (vals.size() == type.numelements()*type.aggregate) { std::vector u; for (size_t i = 0, e = vals.size(); i < e; ++i) u.push_back (ustring(vals[i])); return OIIO::attribute (name, type, &u[0]); } return false; } return false; } // This OIIO_DECLARE_PYMODULE mojo is necessary if we want to pass in the // MODULE name as a #define. Google for Argument-Prescan for additional // info on why this is necessary #define OIIO_DECLARE_PYMODULE(x) BOOST_PYTHON_MODULE(x) OIIO_DECLARE_PYMODULE(OIIO_PYMODULE_NAME) { // Conversion back and forth to ustring boost::python::to_python_converter< ustring, ustring_to_python_str>(); ustring_from_python_str(); // Basic helper classes declare_typedesc(); declare_paramvalue(); declare_imagespec(); declare_roi(); // Main OIIO I/O classes declare_imageinput(); declare_imageoutput(); declare_imagebuf(); declare_imagecache(); declare_imagebufalgo(); // Global (OpenImageIO scope) functiona and symbols def("attribute", &oiio_attribute_float); def("attribute", &oiio_attribute_int); def("attribute", &oiio_attribute_string); def("attribute", &oiio_attribute_typed); def("attribute", &oiio_attribute_tuple_typed); def("geterror", &OIIO::geterror); scope().attr("AutoStride") = AutoStride; scope().attr("openimageio_version") = OIIO_VERSION; scope().attr("VERSION") = OIIO_VERSION; scope().attr("VERSION_STRING") = OIIO_VERSION_STRING; scope().attr("VERSION_MAJOR") = OIIO_VERSION_MAJOR; scope().attr("VERSION_MINOR") = OIIO_VERSION_MINOR; scope().attr("VERSION_PATCH") = OIIO_VERSION_PATCH; scope().attr("INTRO_STRING") = OIIO_INTRO_STRING; boost::python::numeric::array::set_module_and_type("array", "array"); } } // namespace PyOpenImageIO openimageio-1.3.12~dfsg0.orig/src/python/CMakeLists.txt0000644000175000017500000000517112271062644021175 0ustar mfvmfvif (NOT BOOST_CUSTOM) find_package (PythonLibs ${PYTHON_VERSION} REQUIRED) find_package (Boost 1.42 REQUIRED COMPONENTS python) else () find_package (PythonLibs ${PYTHON_VERSION} REQUIRED) endif () if (APPLE) # set (PYTHON_LIBRARIES /opt/local/lib) endif () # Disable some warnings for Clang, it's a little too picky with boost if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_definitions ("-Wno-array-bounds") endif () if (BOOST_CUSTOM OR Boost_FOUND AND PYTHONLIBS_FOUND) set (python_srcs py_imageinput.cpp py_imageoutput.cpp py_imagecache.cpp py_imagespec.cpp py_roi.cpp py_imagebuf.cpp py_imagebufalgo.cpp py_typedesc.cpp py_paramvalue.cpp py_oiio.cpp) message (STATUS "Python found ${PYTHONLIBS_FOUND} ") message (STATUS "Python include dirs ${PYTHON_INCLUDE_PATH}") message (STATUS "Python libraries ${PYTHON_LIBRARIES}") message (STATUS "Python to include 'lib' prefix: ${PYLIB_LIB_PREFIX}") message (STATUS "Python to include SO version: ${PYLIB_INCLUDE_SONAME}") include_directories (${PYTHON_INCLUDE_PATH} ${Boost_INCLUDE_DIRS}) add_library (PyOpenImageIO SHARED ${python_srcs}) target_link_libraries (PyOpenImageIO OpenImageIO ${Boost_LIBRARIES} ${Boost_Python_LIBRARIES} ${PYTHON_LIBRARIES} ${CMAKE_DL_LIBS}) # Exclude the 'lib' prefix from the name if(NOT PYLIB_LIB_PREFIX) add_definitions("-DOIIO_PYMODULE_NAME=OpenImageIO") set_target_properties (PyOpenImageIO PROPERTIES OUTPUT_NAME OpenImageIO PREFIX "") else() add_definitions("-DOIIO_PYMODULE_NAME=PyOpenImageIO") set_target_properties (PyOpenImageIO PROPERTIES OUTPUT_NAME PyOpenImageIO PREFIX lib) endif () if(PYLIB_INCLUDE_SONAME) message(STATUS "Setting PyOIIO SOVERSION to: ${SOVERSION}") set_target_properties(PyOpenImageIO PROPERTIES VERSION ${OIIO_VERSION_MAJOR}.${OIIO_VERSION_MINOR} SOVERSION ${SOVERSION} ) endif() if (APPLE) # Python seems to only look for plugins that end in .so, not .dylib set_target_properties (PyOpenImageIO PROPERTIES SUFFIX ".so") endif () if (WIN32) set_target_properties (PyOpenImageIO PROPERTIES DEBUG_POSTFIX "_d" SUFFIX ".pyd") endif() install (TARGETS PyOpenImageIO RUNTIME DESTINATION ${PYLIB_INSTALL_DIR} COMPONENT user LIBRARY DESTINATION ${PYLIB_INSTALL_DIR} COMPONENT user) endif () openimageio-1.3.12~dfsg0.orig/src/python/unit_tests_imagecache.py0000644000175000017500000002737212271062644023345 0ustar mfvmfv# unit tests for ImageCache def ic_create_test(): print "Starting ImageCache.create() tests..." print "Every other test requires these tests to pass." # test 1 try: cache = None cache = oiio.ImageCache.create() if cache != None: print "Test 1 passed" else: print "Test 1 failed" except: print "Test 1 failed" # test 2 try: cache = None cache = oiio.ImageCache.create(False) if cache != None: print "Test 2 passed" else: print "Test 2 failed" except: print "Test 2 failed" # test 3 try: cache = None cache = oiio.ImageCache.create(True) if cache != None: print "Test 3 passed" else: print "Test 3 failed" except: print "Test 3 failed" # test 4 try: cache = None cache = oiio.ImageCache.create("not a proper argument") if cache != None: print "Test 4 passed" else: print "Test 4 failed" except: print "Test 4 failed" print def ic_clear_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() print "Starting ImageCache.clear() tests..." # test 1 try: cache.clear("not a proper argument") print "Test 1 failed" except: print "Test 1 passed" # test 2 try: cache.clear() print "Test 2 passed" except: print "Test 2 failed" print def ic_attribute_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() print "Starting ImageCache.attribute() tests..." # test 1 try: cache.attribute("max_open_files", 2) print "Test 1 passed" except: print "Test 1 failed" # test 2 try: cache.attribute("max_memory_MB", 3.14) print "Test 2 passed" except: print "Test 2 failed" # test 3 try: cache.attribute("searchpath", "") print "Test 3 passed" except: print "Test 3 failed" # test 4 try: att_name = "a_string_attribute" att_value = "should return false" cache.attribute(att_name, att_value) print "Test 4 passed" except: print "Test 4 failed" print def ic_getattribute_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() print "Starting ImageCache.getattribute() tests..." # test 1 try: val = None cache.getattribute("max_open_tiles", val) print "Test 1 passed" except: print "Test 1 failed" # test 2 try: val = None cache.getattribute("max_memory_mb", val) print "Test 2 passed" except: print "Test 2 failed" # test 3 try: val = None cache.getattribute("searchpath", val) print "Test 3 passed" except: print "Test 3 failed" # test 4 try: val = None cache.getattribute("autotile", val) print "Test 4 passed" except: print "Test 4 failed" # test 5 try: val = None cache.getattribute("automip", val) print "Test 5 passed" except: print "Test 5 failed" # test 6 try: val = None cache.getattribute("some_attribute", val) print "Test 6 passed" except: print "Test 6 failed" print def ic_resolve_filename_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() print "Starting ImageCache.resolve_filename() tests..." # test 1 pic_path = "../../../oiio-images/tahoe-gps.jpg" try: cache.resolve_filename(pic_path) print "Test 1 passed" except: print "Test 1 failed" # test 2 try: cache.resolve_filename("nonexisting_pic.jpg") print "Test 2 passed" except: print "Test 2 failed" print def ic_get_image_info_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() print "Starting ImageCache.get_image_info() tests..." print "Needs more tests!" desc = oiio.TypeDesc() # test 1 data = None # not sure what filename and dataname are supposed so we test # only if get_image_info() returns False when given dummy data # TODO: expand the tests with proper data, so we can see when # get_image_info() actually does what it's supposed to. filename = "filename" dataname = "dataname" try: cache.get_image_info(filename, dataname, desc, data) print "Test 1 passed" except: print "Test 1 failed" # test 2 print def ic_get_imagespec_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() print "Starting ImageCache.get_imagespec() tests..." filename = "filename" spec = oiio.ImageSpec() # test 1 try: cache.get_imagespec(filename, spec, 0) print "Test 1 passed" except: print "Test 1 failed" # test 2 try: # third argument is 0 by default cache.get_imagespec(filename, spec) print "Test 2 passed" except: print "Test 2 failed" # test 3 try: cache.get_imagespec(filename, spec, 2) print "Test 3 passed" except: print "Test 3 failed" print def ic_get_pixels_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() print "Starting ImageCache.get_pixels() tests..." filename = "filename" desc = oiio.TypeDesc() subimage = 0 xbegin = ybegin = 0 xend = yend = 1 zbegin = zend = 0 # test 1 try: # this array will have to be modified to be an appropriate # buffer once it's determined how the buffers are to be passed # from Python result = array.array("B") cache.get_pixels(filename, subimage, xbegin, xend, ybegin, yend, \ zbegin, zend, desc, result) print "Test 1 passed" except: print "Test 1 failed" # test 2 - pass an impossible pixel location as xbegin (-1) # Not sure if get_pixels() is supposed to return False or raise # an exception if given an impossible xbegin (or any other arg). # Currently, I supposed it should return False. try: # this array will have to be modified to be an appropriate # buffer once it's determined how the buffers are to be passed # from Python result = array.array("B") cache.get_pixels(filename, subimage, -1, xend, ybegin, yend, \ zbegin, zend, desc, result) print "Test 2 passed (check the comments!)" except: print "Test 2 failed (check the comments!)" print def ic_get_tile_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() print "Starting ImageCache.get_tile() tests..." print "These tests are required to pass before we can test release_tile() and tile_pixels()" filename = "filename" subimage = 0 x = y = z = 0 # test 1 try: tile = None tile = cache.get_tile(filename, subimage, x, y, z) if tile != None: print "Test 1 passed" else: print "Test 1 failed" except: print "Test 1 failed" # test 2 - pass an impossible value for x (-1) # same issue as with get_pixels_test() #1 try: tile = None tile = cache.get_tile(filename, subimage, -1, y, z) if tile != None: print "Test 2 passed (check the comments!)" else: print "Test 2 failed (check the comments!)" except: print "Test 2 failed (check the comments!)" print def ic_release_tile_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() # run get_tile() so we have something to release filename = "filename" subimage = 0 x = y = z = 0 tile = cache.get_tile(filename, subimage, x, y, z) print "Starting ImageCache.get_tile() tests..." # test 1 try: cache.release_tile(tile) print "Test 1 passed" except: print "Test 1 failed" print def ic_tile_pixels_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() # run get_tile() so we have something to fetch filename = "filename" subimage = 0 x = y = z = 0 tile = cache.get_tile(filename, subimage, x, y, z) # the format of fetched pixels, currently set to "Unknown" desc = TypeDesc() # test 1 try: pixels = None pixels = cache.tile_pixels(tile, desc) if pixels != None: print "Test 1 passed" else: print "Test 1 failed (nothing returned)" # OTH, the data given is very likely to be wrong so that # can be the reason for failing except: print "Test 1 failed (exception raised)" print def ic_geterror_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() # test 1 try: error_message = None error_message = cache.geterror() if len(error_message) >= 0: print "Test 1 passed" except: print "Test 1 failed" print def ic_getstats_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() # test 1 try: stats = None stats = cache.getstats() #default arg is 1 if type(stats) == str: print "Test 1 passed" else: print "Test 1 failed (nothing returned)" except: print "Test 1 failed (exception raised)" print def ic_invalidate_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() filename = "filename" # test 1 try: cache.invalidate(filename) print "Test 1 passed" except: print "Test 1 failed" print def ic_invalidate_all_test(): # create an instance on which we can test # if ic_create_test() failed, this can't be done cache = oiio.ImageCache.create() # test 1 try: cache.invalidate_all() # default arg is force=False print "Test 1 passed" except: print "Test 1 failed" # test 2 try: cache.invalidate_all(True) print "Test 2 passed" except: print "Test 2 failed" print ### def run_tests(): ic_create_test() ic_clear_test() ic_attribute_test() ic_getattribute_test() ic_resolve_filename_test() ic_get_image_info_test() ic_get_imagespec_test() ic_get_pixels_test() ic_get_tile_test() ic_release_tile_test() ic_tile_pixels_test() ic_geterror_test() ic_getstats_test() ic_invalidate_test() ic_invalidate_all_test() ### import OpenImageIO as oiio import array plugin_path = raw_input("Enter the oiio plugin search path (probably /dist/ARCH/lib) :\n ") run_tests() openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/0000755000175000017500000000000012271062644017774 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/cineon.imageio/cineonoutput.cpp0000644000175000017500000000712112271062644023235 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "libcineon/Cineon.h" #include "typedesc.h" #include "imageio.h" #include "fmath.h" using namespace cineon; OIIO_PLUGIN_NAMESPACE_BEGIN class CineonOutput : public ImageOutput { public: CineonOutput (); virtual ~CineonOutput (); virtual const char * format_name (void) const { return "cineon"; } virtual bool supports (const std::string &feature) const { // Support nothing nonstandard return false; } virtual bool open (const std::string &name, const ImageSpec &spec, ImageOutput::OpenMode mode); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: // Initialize private members to pre-opened state void init (void) { } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *cineon_output_imageio_create () { return new CineonOutput; } // OIIO_EXPORT int cineon_imageio_version = OIIO_PLUGIN_VERSION; // it's in cineoninput.cpp OIIO_EXPORT const char * cineon_output_extensions[] = { "cin", NULL }; OIIO_PLUGIN_EXPORTS_END CineonOutput::CineonOutput () { init (); } CineonOutput::~CineonOutput () { // Close, if not already done. close (); } bool CineonOutput::open (const std::string &name, const ImageSpec &userspec, ImageOutput::OpenMode mode) { error ("Cineon writer is not implemented yet, please poke Leszek in the " "mailing list"); return false; } bool CineonOutput::close () { init(); // Reset to initial state return true; // How can we fail? // Epicly. -- IneQuation } bool CineonOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { error ("Cineon writer is not implemented yet, please poke Leszek in the " "mailing list"); return false; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/0000755000175000017500000000000012271062644021736 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/ElementReadStream.h0000644000175000017500000000427212271062644025455 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _CINEON_ELEMENTREADSTREAM_H #define _CINEON_ELEMENTREADSTREAM_H 1 #include "CineonStream.h" namespace cineon { class ElementReadStream { public: ElementReadStream(InStream *); virtual ~ElementReadStream(); virtual void Reset(); virtual bool Read(const cineon::Header &, const long offset, void * buf, const size_t size); virtual bool ReadDirect(const cineon::Header &, const long offset, void * buf, const size_t size); protected: void EndianDataCheck(const cineon::Header &, void *, const size_t size); InStream *fd; }; } #endif openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/InStream.cpp0000644000175000017500000000527112271062644024171 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include "filesystem.h" #include "CineonStream.h" namespace cineon { InStream::InStream() : fp(0) { } InStream::~InStream() { } bool InStream::Open(const char *f) { if (this->fp) this->Close(); if ((this->fp = OIIO::Filesystem::fopen(f, "rb")) == 0) return false; return true; } void InStream::Close() { if (this->fp) { ::fclose(this->fp); this->fp = 0; } } void InStream::Rewind() { if (this->fp) ::rewind(fp); } bool InStream::Seek(long offset, Origin origin) { int o = 0; switch (origin) { case kCurrent: o = SEEK_CUR; break; case kEnd: o = SEEK_END; break; case kStart: o = SEEK_SET; break; } if (this->fp == 0) return -1; return (::fseek(this->fp, offset, o) == 0); } size_t InStream::Read(void *buf, const size_t size) { if (this->fp == 0) return 0; return ::fread(buf, 1, size, this->fp); } size_t InStream::ReadDirect(void *buf, const size_t size) { return this->Read(buf, size); } bool InStream::EndOfFile() const { if (this->fp == 0) return true; return ::feof(this->fp); } } openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/Cineon.h0000644000175000017500000002516212271062644023330 0ustar mfvmfv// vi: ts=4 /*! \file Cineon.h */ /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _CINEON_H #define _CINEON_H 1 #include #include "CineonHeader.h" #include "CineonStream.h" /*! * \def LIBCINEON_VERSION * \brief LIBCINEON Version */ #define LIBCINEON_VERSION "0.1" /*! * \namespace cineon * \brief libcineon namespace */ namespace cineon { // forward definitions class Codec; class ElementReadStream; /*! * \enum Endian * \brief DPX files can be stored in big- or little-endian byte order */ enum Endian { kLittleEndian, //!< increasing numeric significance with increasing memory kBigEndian //!< big end first }; /*! \struct Block * \brief Rectangle block definition defined by two points */ struct Block { int x1, y1, x2, y2; /*! * \brief Constructor */ inline Block(); /*! * \brief Constructor * * \param x1 upper left x coordinate * \param y1 upper left y coordinate * \param x2 lower right x coordinate * \param y2 lower right y coordinate */ Block(const int x1, const int y1, const int x2, const int y2); /*! * \brief Set the block coordinates * * \param x1 upper left x coordinate * \param y1 upper left y coordinate * \param x2 lower right x coordinate * \param y2 lower right y coordinate */ void Set(const int x1, const int y1, const int x2, const int y2); /*! * \brief Check to see if a point is within the block * * \param x x coordinate * \param y y coordinate * \return true/false if coordinates within block */ inline bool Inside(const int x, const int y) const; /*! * \brief Rearrange coordinates if necessary so the first coordinate is upper left and the second is lower right */ inline void Check(); }; // Current platform endian byte order extern Endian systemByteOrder; // namespace functions /*! * \brief determine if the image file is DPX * * \param file buffer to read and search * \return true/false if identified as DPX */ bool IdentifyFile(InStream *file); /*! * \brief determine if the image file is DPX * * \param data memory to search * \return true/false if identified as DPX */ bool IdentifyFile(const void *data); /*! * \brief returns a char * of the default DPX file extension * * \return .dpx file extenion */ inline const char *DefaultExtension(); /*! * returns a string of the highest SMPTE DPX version supported by this library * * \return SMPTE DPX version */ inline const char *Version(); /*! * \brief returns the version string for this library * * \return OpenDPX version */ inline const char *LibraryVersion(); /*! * \class Reader * \brief DPX Image Reader class */ class Reader { public: /*! * \brief DPX header */ Header header; /*! * \brief Constructor */ Reader(); /*! * \brief Destructor */ virtual ~Reader(); /*! * \brief Set the InStream object to be used to read images * * \param stream Object to use for low level reads */ void SetInStream(InStream *stream); /*! * \brief clear any caching or memory allocated specific to an image */ void Reset(); /*! * \brief Read the dpx header into the header member * * \return success true/false */ bool ReadHeader(); /*! * \brief Read an image element into a buffer that matches the image description type * * The DataSize allows the user to specific the buffer DataSize which can differ * from the image element. It is possible, for example, to read an 8-bit per * component (3 components per pixel for RGB) into 16-bits. * * \param data buffer * \param size size of the buffer component * \param desc element description type * \return success true/false */ bool ReadImage(void *data, const DataSize size = kWord); /*! * \brief Read a rectangular image block into a buffer from the image element * specified by the Descriptor type * * \param data buffer * \param size size of the buffer component * \param block image area to read * \param desc element description type * \return success true/false */ bool ReadBlock(void *data, const DataSize size, Block &block); /*! * \brief Read the user data into a buffer. * * Buffer must be large enough to hold the user data. * * \param data buffer * \return success true/false */ bool ReadUserData(unsigned char *data); protected: InStream *fd; Codec *codec; ElementReadStream *rio; }; /*! * \class Writer * \brief DPX Image Writer class */ class Writer { public: /*! * \brief DPX Header */ Header header; /*! * \brief Constructor */ Writer(); /*! * \brief Destructor */ virtual ~Writer(); /*! * \brief Start defining the header and writing the images */ void Start(); /*! * \brief Set the basic file information about DPX * * \param fileName name of this created file (100 characters max) * \param creationTimeDate creation time and date - format is "YYYY:MM:DD:HH:MM:SSLTZ" * where HH is 24 hour time, LTZ is local time zone using either * three character notation (i.e., -04) or five character notation * representing hours and minutes offset from Greenwich Mean time * (i.e., -0700) (24 characters max) * \param creator creator (100 characters max) * \param project project name (200 characters max) * \param copyright copyright statement (200 characters max) * \param encryptKey encryption key */ void SetFileInfo(const char *fileName, const char *creationDate = 0, const char *creationTime = 0); /*! * \brief Set the Width and Height of the images * * \param width width of the image * \param height height of the image */ void SetImageInfo(const U32 width, const U32 height); /*! * \brief Get the next available element * \return next available */ int NextAvailElement() const; /*! * \brief Set the parameters on an element * * There are 8 elements maximum in an single DPX and each element used must be set before writing the header * * \param element element number (0-7) * \param desc image descriptor * \param bitDepth bit depth of image, valid values are [8,10,12,16,32,64] * \param transfer transfer characteristic * \param colorimetric colorimetric specification * \param packing packing type * \param encoding encoding type * \param dataSign * \param lowData * \param lowQuantity * \param highData * \param highQuantity * \param eolnPadding end of line padding (in bytes) * \param eoimPadding end of image padding (in bytes) */ void SetElement(const int element = 0, const Descriptor desc = kGrayscale, const U8 bitDepth = 10, const U32 pixelsPerLine = 1, const U32 linesPerElement = 1, const R32 lowData = ~0, const R32 lowQuantity = ~0, const R32 highData = ~0, const R32 highQuantity = ~0); /*! * \brief Set the OutStream object will use to write the files * * \param stream OutStream object */ void SetOutStream(OutStream *stream); /*! * \brief Set the size of the user data area * * \param size size of user data */ void SetUserData(const long size); /*! * \brief Write the header * * \return success true/false */ bool WriteHeader(); /*! * \brief Write the user data * * \param data buffer - must match size set in Writer::SetUserData() * \return success true/false */ bool WriteUserData(void *data); /*! * \brief Write the entire element to the dpx file * * \param element element number (0-7) * \param data buffer * \return success true/false */ bool WriteElement(const int element, void *data); bool WriteElement(const int element, void *data, const DataSize size); bool WriteElement(const int element, void *data, const long count); /** * \brief Finish up writing image * * \return success true/false */ bool Finish(); protected: long fileLoc; OutStream *fd; bool WriteThrough(void *, const U32, const U32, const int, const int, const U32, const U32, char *); }; } inline const char *cineon::DefaultExtension() { return "cin"; } inline const char *cineon::Version() { return SPEC_VERSION; } inline const char *cineon::LibraryVersion() { return LIBCINEON_VERSION; } inline cineon::Block::Block() : x1(0), y1(0), x2(0), y2(0) { } inline cineon::Block::Block(const int x1, const int y1, const int x2, const int y2) : x1(x1), y1(y1), x2(x2), y2(y2) { this->Check(); } inline void cineon::Block::Set(const int x1, const int y1, const int x2, const int y2) { this->x1 = x1; this->y1 = y1; this->x2 = x2; this->y2 = y2; } // check the coordinates that x1 < x2 and y1 < y2 inline void cineon::Block::Check() { if (this->x1 > this->x2) { int t = x1; this->x1 = this->x2; this->x2 = t; } if (this->y1 > this->y2) { int t = y1; this->y1 = this->y2; this->y2 = t; } } inline bool cineon::Block::Inside(const int x, const int y) const { if (x >= this->x1 && x <= this->x2 && y >= this->y1 && y <= this->y2) return true; return false; } #endif openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/Writer.cpp0000644000175000017500000002265012271062644023723 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "Cineon.h" #include "CineonStream.h" #include "EndianSwap.h" #include "WriterInternal.h" cineon::Writer::Writer() : fileLoc(0) { } cineon::Writer::~Writer() { } void cineon::Writer::Start() { } void cineon::Writer::SetFileInfo(const char *fileName, const char *creationDate, const char *creationTime) { if (fileName) this->header.SetFileName(fileName); if (creationDate && creationTime) { this->header.SetCreationDate(creationDate); this->header.SetCreationTime(creationTime); } else { time_t seconds = time(0); this->header.SetCreationTimeDate(seconds); } } void cineon::Writer::SetImageInfo(const U32 width, const U32 height) { this->header.SetImageOrientation(kLeftToRightTopToBottom); } // returns next available or MAX_ELEMENTS if full int cineon::Writer::NextAvailElement() const { unsigned int i; for (i = 0; i < MAX_ELEMENTS; i++) { if (this->header.ImageDescriptor(i) == kUndefinedDescriptor) break; } return i; } void cineon::Writer::SetOutStream(OutStream *fd) { this->fd = fd; } bool cineon::Writer::WriteHeader() { // calculate any header info this->header.CalculateOffsets(); // seek to the beginning of the file if (!this->fd->Seek(0, OutStream::kStart)) return false; // writing the header count this->fileLoc = this->header.Size(); return this->header.Write(fd); } void cineon::Writer::SetUserData(const long size) { // TODO } bool cineon::Writer::WriteUserData(void *data) { // XXX TODO return false; } void cineon::Writer::SetElement(const int num, const Descriptor desc, const U8 bitDepth, const U32 pixelsPerLine, const U32 linesPerElement, const R32 lowData, const R32 lowQuantity, const R32 highData, const R32 highQuantity) { // make sure the range is good if (num < 0 || num >= MAX_ELEMENTS) return; // set values this->header.SetLowData(num, lowData); this->header.SetLowQuantity(num, lowQuantity); this->header.SetHighData(num, highData); this->header.SetHighQuantity(num, highQuantity); this->header.SetImageDescriptor(num, desc); this->header.SetBitDepth(num, bitDepth); // determine if increases element count this->header.CalculateNumberOfElements(); } // the data is processed so write it straight through // argument count is total size in bytes of the passed data bool cineon::Writer::WriteElement(const int element, void *data, const long count) { // make sure the range is good if (element < 0 || element >= MAX_ELEMENTS) return false; // make sure the entry is valid if (this->header.ImageDescriptor(element) == kUndefinedDescriptor) return false; // update file ptr //this->header.SetDataOffset(element, this->fileLoc); this->fileLoc += count; // write return (this->fd->Write(data, count) > 0); } bool cineon::Writer::WriteElement(const int element, void *data) { // make sure the range is good if (element < 0 || element >= MAX_ELEMENTS) return false; // make sure the entry is valid if (this->header.ImageDescriptor(element) == kUndefinedDescriptor) return false; return this->WriteElement(element, data, this->header.ComponentDataSize(element)); } bool cineon::Writer::WriteElement(const int element, void *data, const DataSize size) { bool status = true; // make sure the range is good if (element < 0 || element >= MAX_ELEMENTS) return false; // make sure the entry is valid if (this->header.ImageDescriptor(element) == kUndefinedDescriptor) return false; // mark location in headers if (element == 0) this->header.SetImageOffset(this->fileLoc); //this->header.SetDataOffset(element, this->fileLoc); // reverse the order of the components bool reverse = false; // image parameters const U32 eolnPad = this->header.EndOfLinePadding(); const U32 eoimPad = this->header.EndOfImagePadding(); const U8 bitDepth = this->header.BitDepth(element); const U32 width = this->header.Width(); const U32 height = this->header.Height(); const int noc = this->header.NumberOfElements(); const Packing packing = this->header.ImagePacking(); // check width & height, just in case if (width == 0 || height == 0) return false; // sizeof a component in an image const int bytes = (bitDepth + 7) / 8; // allocate memory for use to write blank space char *blank = 0; if (eolnPad || eoimPad) { int bsize = eolnPad > eoimPad ? eolnPad : eoimPad; blank = new char[bsize]; memset(blank, bsize, sizeof(char)); } // can we write the entire memory chunk at once without any additional processing if ((bitDepth == 8 && size == cineon::kByte) || (bitDepth == 12 && size == cineon::kWord /*&& packing == kFilledMethodA*/) || (bitDepth == 16 && size == cineon::kWord)) { status = this->WriteThrough(data, width, height, noc, bytes, eolnPad, eoimPad, blank); if (blank) delete [] blank; return status; } else { switch (bitDepth) { case 8: if (size == cineon::kByte) this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, reverse, eolnPad, blank, status); else this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, reverse, eolnPad, blank, status); break; case 10: // are the channels stored in reverse /*if (this->header.ImageDescriptor(element) == kRGB && this->header.DatumSwap(element) && bitDepth == 10) reverse = true;*/ if (size == cineon::kWord) this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, reverse, eolnPad, blank, status); else this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, reverse, eolnPad, blank, status); break; case 12: if (size == cineon::kWord) this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, reverse, eolnPad, blank, status); else this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, reverse, eolnPad, blank, status); break; case 16: if (size == cineon::kWord) this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, reverse, eolnPad, blank, status); else this->fileLoc += WriteBuffer(this->fd, size, data, width, height, noc, packing, reverse, eolnPad, blank, status); break; default: return false; } } // if successful if (status && eoimPad) { // end of image padding this->fileLoc += eoimPad; status = (this->fd->Write(blank, eoimPad) > 0); } // rid of memory if (blank) delete [] blank; return status; } // the passed in image buffer is written to the file untouched bool cineon::Writer::WriteThrough(void *data, const U32 width, const U32 height, const int noc, const int bytes, const U32 eolnPad, const U32 eoimPad, char *blank) { bool status = true; const int count = width * height * noc; unsigned int i; unsigned char *imageBuf = reinterpret_cast(data); // file pointer location after write this->fileLoc += bytes * count + (eolnPad * height); // write data if (eolnPad) { // loop if have end of line padding for (i = 0; i < height; i++) { // write one line if (this->fd->Write(imageBuf+(width*bytes*i), bytes * width) == false) { status = false; break; } // write end of line padding if (this->fd->Write(blank, eoimPad) == false) { status = false; break; } } } else { // write data as one chunk if (this->fd->Write(imageBuf, bytes * count) == false) { status = false; } } // end of image padding if (status && eoimPad) { this->fileLoc += eoimPad; status = (this->fd->Write(blank, eoimPad) > 0); } return status; } bool cineon::Writer::Finish() { // write the file size in the header this->header.SetFileSize(this->fileLoc); // rewrite all of the offsets in the header return this->header.WriteOffsetData(this->fd); } openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/Codec.cpp0000644000175000017500000000541312271062644023462 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "Cineon.h" #include "Codec.h" #include "ElementReadStream.h" #include "ReaderInternal.h" cineon::Codec::Codec() : scanline(0) { } cineon::Codec::~Codec() { if (this->scanline) delete [] scanline; } void cineon::Codec::Reset() { if (this->scanline) { delete [] scanline; this->scanline = 0; } } bool cineon::Codec::Read(const Header &dpxHeader, ElementReadStream *fd, const Block &block, void *data, const DataSize size) { // scanline buffer if (this->scanline == 0) { // FIXME: make this flexible enough to change per-channel differences! // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.NumberOfElements(); // bit depth of the image element const int bitDepth = dpxHeader.BitDepth(0); // size of the scanline buffer is image width * number of components * bytes per component int slsize = ((numberOfComponents * dpxHeader.Width() * (bitDepth / 8 + (bitDepth % 8 ? 1 : 0))) / sizeof(U32))+1; this->scanline = new U32[slsize]; } // read the image block return ReadImageBlock(dpxHeader, this->scanline, fd, block, data, size); } openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/CineonStream.h0000644000175000017500000001044512271062644024502 0ustar mfvmfv/// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /*! \file CineonStream.h */ /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _CINEON_CINEONSTREAM_H #define _CINEON_CINEONSTREAM_H 1 #include namespace cineon { /*! * \class InStream * \brief Input Stream for reading files */ class InStream { public: /*! * \enum Origin * \brief file pointing positioning offset */ enum Origin { kStart, //!< beginning of the file kCurrent, //!< current file pointer kEnd //!< end of the file }; /*! * \brief Constructor */ InStream(); /*! * \brief Destructor */ virtual ~InStream(); /*! * \brief Open file * \param fn File name * \return success true/false */ virtual bool Open(const char * fn); /*! * \brief Close file */ virtual void Close(); /*! * \brief Rewind file pointer to beginning of file */ virtual void Rewind(); /*! * \brief Read data from file * \param buf data buffer * \param size bytes to read * \return number of bytes read */ virtual size_t Read(void * buf, const size_t size); /*! * \brief Read data from file without any buffering as fast as possible * \param buf data buffer * \param size bytes to read * \return number of bytes read */ virtual size_t ReadDirect(void * buf, const size_t size); /*! * \brief Query if end of file has been reached * \return end of file true/false */ virtual bool EndOfFile() const; /*! * \brief Seek to a position in the file * \param offset offset from originating position * \param origin originating position * \return success true/false */ virtual bool Seek(long offset, Origin origin); protected: FILE *fp; }; /*! * \class OutStream * \brief Output Stream for writing files */ class OutStream { public: /*! * \enum Origin * \brief file pointing positioning offset */ enum Origin { kStart, //!< beginning of the file kCurrent, //!< current file pointer kEnd //!< end of the file }; /*! * \brief Constructor */ OutStream(); /*! * \brief Destructor */ virtual ~OutStream(); /*! * \brief Open file * \param fn File name * \return success true/false */ virtual bool Open(const char *fn); /*! * \brief Close file */ virtual void Close(); /*! * \brief Write data to file * \param buf data buffer * \param size bytes to write * \return number of bytes written */ virtual size_t Write(void * buf, const size_t size); /*! * \brief Seek to a position in the file * \param offset offset from originating position * \param origin originating position * \return success true/false */ virtual bool Seek(long offset, Origin origin); /*! * \brief Flush any buffers */ virtual void Flush(); protected: FILE *fp; }; } #endif openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/WriterInternal.h0000644000175000017500000002465312271062644025072 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _CINEON_WRITERINTERNAL_H #define _CINEON_WRITERINTERNAL_H 1 #include "BaseTypeConverter.h" namespace cineon { template void MultiTypeBufferCopy(T1 *dst, T2 *src, const int len) { for (int i = 0; i < len; i++) BaseTypeConverter(src[i], dst[i]); } template void CopyWriteBuffer(DataSize src_size, unsigned char *src, IB * dst, const int len) { if (src_size == kByte) MultiTypeBufferCopy(dst, reinterpret_cast(src), len); else if (src_size == kWord) MultiTypeBufferCopy(dst, reinterpret_cast(src), len); else if (src_size == kInt) MultiTypeBufferCopy(dst, reinterpret_cast(src), len); else if (src_size == kLongLong) MultiTypeBufferCopy(dst, reinterpret_cast(src), len); } // access modifications to the buffer based on compression and packing struct BufferAccess { int offset; int length; BufferAccess() : offset(0), length(0) { } }; // \todo NOT DONE template void RleCompress(IB *src, IB *dst, const int bufsize, const int len, BufferAccess &access) { IB ch; int count; int i; int index = bufsize - 1; bool start = true; //bool match = true; // for each data type, have maximum length of rle datum // subtract one so it the LSBit can be used to state int maxCount; if (BITDEPTH == 8) maxCount = 0xff - 1; else if (BITDEPTH == 10) maxCount = 0x3ff - 1; else if (BITDEPTH == 12) maxCount = 0xfff - 1; else if (BITDEPTH == 16) maxCount = 0xffff - 1; else maxCount = 1000000; // high number for floats, doubles for (i = len - 1; i >= 0; i--) { if (start) { count = 1; start = false; ch = src[i]; dst[index--] = ch; } } access.offset = index; access.length = bufsize - index; } template void WritePackedMethod(IB *src, IB *dst, const int len, const bool reverse, BufferAccess &access) { // pack into the same memory space U32 *dst_u32 = reinterpret_cast(dst); // bit shift count for U16 source const int shift = 16 - BITDEPTH; // bit mask U32 mask = 0; if (BITDEPTH == 10) mask = 0x03ff; else if (BITDEPTH == 12) mask = 0x0fff; else if (BITDEPTH == 8) return; int i, entry; for (i = 0; i < len; i++) { // read value and determine write location U32 value = static_cast(src[i+access.offset]) >> shift; // if reverse the order /*** XXX TODO REVERSE if (reverse) // reverse the triplets so entry would be 2,1,0,5,4,3,8,7,6,... entry = ((i / 3) * 3) + (2 - (i % 3)); else ***/ entry = i; int div = (entry * BITDEPTH) / 32; // 32 bits in a U32 int rem = (entry * BITDEPTH) % 32; // write the bits that belong in the first U32 // calculate the masked bits for the added value U32 shift_mask = mask << rem; // mask sure to mask the bits to save as part of the src_buf // so if writing bits 8-18, save the bits of the source material dst_u32[div] = (dst_u32[div] & ~shift_mask) | ((value << rem) & shift_mask); // write across multiple U16? count the carry bits int carry = BITDEPTH - (32 - rem); if (carry > 0) { U32 save = BITDEPTH - carry; dst_u32[div+1] = (dst_u32[div+1] & ~(mask >> save)) | ((value >> save) & (mask >> save)); } } // adjust offset/length access.offset = 0; access.length = (((len * BITDEPTH) / 32) + ((len * BITDEPTH) % 32 ? 1 : 0)) * 2; } // this routine expects a type of U16 template void WritePackedMethodAB_10bit(IB *src, IB *dst, const int len, const bool reverse, BufferAccess &access) { // pack into the same memory space U32 *dst_u32 = reinterpret_cast(dst); // bit shift count const U32 shift = 6; // (16 - BITDEPTH) const U32 bitdepth = 10; const U32 bitmask = 0x03ff; // shift bits over 2 if Method A const int method_shift = 0;//(METHOD == kFilledMethodA ? 2 : 0); // loop through the buffer int i; U32 value = 0; for (i = 0; i < len; i++) { int div = i / 3; // 3 10-bit values in a U32 int rem = i % 3; // write previously calculated value if (i && rem == 0) { dst_u32[div-1] = value; value = 0; } // if reverse the order if (reverse) rem = 2 - rem; // place the 10 bits in the proper place with mask U32 comp = ((static_cast(src[i+access.offset]) >> shift) << (bitdepth * rem)) << method_shift; U32 mask = (bitmask << (bitdepth * rem)) << method_shift ; // overwrite only the proper 10 bits value = (value & ~mask) | (comp & mask); } // write last dst_u32[(len+2)/3-1] = value; // adjust offset/length // multiply * 2 because it takes two U16 = U32 and this func packs into a U32 access.offset = 0; access.length = ((len / 3) + (len % 3 ? 1 : 0)) * 2; } template int WriteBuffer(OutStream *fd, DataSize src_size, void *src_buf, const U32 width, const U32 height, const int noc, const Packing packing, const bool reverse, const int eolnPad, char *blank, bool &status) { int fileOffset = 0; // buffer access parameters BufferAccess bufaccess; bufaccess.offset = 0; bufaccess.length = width * noc; // allocate one line IB *src; IB *dst = new IB[(width * noc) + 1]; // each line in the buffer for (U32 h = 0; h < height; h++) { // image buffer unsigned char *imageBuf = reinterpret_cast(src_buf); const int bytes = Header::DataSizeByteCount(src_size); // copy buffer if need to promote data types from src to destination if (!SAMEBUFTYPE) { src = dst; CopyWriteBuffer(src_size, (imageBuf+(h*width*noc*bytes)+(h*eolnPad)), dst, (width*noc)); } else // not a copy, access source src = reinterpret_cast(imageBuf + (h * width * noc * bytes) + (h*eolnPad)); // if 10 or 12 bit, pack if (BITDEPTH == 10) { if (packing == cineon::kPacked) { WritePackedMethod(src, dst, (width*noc), reverse, bufaccess); } /*else if (packing == kFilledMethodA) { WritePackedMethodAB_10bit(src, dst, (width*noc), reverse, bufaccess); } else // if (packing == cineon::kFilledMethodB) { WritePackedMethodAB_10bit(src, dst, (width*noc), reverse, bufaccess); }*/ } else if (BITDEPTH == 12) { if (packing == cineon::kPacked) { WritePackedMethod(src, dst, (width*noc), reverse, bufaccess); } /*else if (packing == cineon::kFilledMethodB) { // shift 4 MSB down, so 0x0f00 would become 0x00f0 for (int w = 0; w < bufaccess.length; w++) dst[w] = src[bufaccess.offset+w] >> 4; bufaccess.offset = 0; }*/ // a bitdepth of 12 by default is packed with cineon::kFilledMethodA // assumes that either a copy or rle was required // otherwise this routine should not be called with: // 12-bit Method A with the source buffer data type is kWord } // write line fileOffset += (bufaccess.length * sizeof(IB)); if (fd->Write(dst+bufaccess.offset, (bufaccess.length * sizeof(IB))) == false) { status = false; break; } // end of line padding if (eolnPad) { fileOffset += eolnPad; if (fd->Write(blank, eolnPad) == false) { status = false; break; } } } // done with buffer delete [] dst; return fileOffset; } template int WriteFloatBuffer(OutStream *fd, DataSize src_size, void *src_buf, const U32 width, const U32 height, const int noc, const Packing packing, const int eolnPad, char *blank, bool &status) { int fileOffset = 0; // buffer access parameters BufferAccess bufaccess; bufaccess.offset = 0; bufaccess.length = width * noc; // allocate one line IB *src; IB *dst = new IB[(width * noc)]; // each line in the buffer for (U32 h = 0; h < height; h++) { // image buffer unsigned char *imageBuf = reinterpret_cast(src_buf); const int bytes = Header::DataSizeByteCount(src_size); // copy buffer if need to promote data types from src to destination if (!SAMEBUFTYPE) { src = dst; CopyWriteBuffer(src_size, (imageBuf+(h*width*noc*bytes)+(h*eolnPad)), dst, (width*noc)); } else // not a copy, access source src = reinterpret_cast(imageBuf + (h * width * noc * bytes) + (h*eolnPad)); // write line fileOffset += (bufaccess.length * sizeof(IB)); if (fd->Write(dst+bufaccess.offset, (bufaccess.length * sizeof(IB))) == false) { status = false; break; } // end of line padding if (eolnPad) { fileOffset += eolnPad; if (fd->Write(blank, eolnPad) == false) { status = false; break; } } } // done with buffer delete [] dst; return fileOffset; } } #endif openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/Codec.h0000644000175000017500000000471412271062644023132 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _CINEON_CODEC_H #define _CINEON_CODEC_H 1 #include "Cineon.h" namespace cineon { /*! * \brief compress / decompress data segments * base class defaults to None */ class Codec { public: /*! * \brief constructor */ Codec(); /*! * \brief destructor */ virtual ~Codec(); /*! * \brief reset instance */ virtual void Reset(); /*! * \brief read data * \param dpxHeader dpx header information * \param fd field descriptor * \param block image area to read * \param data buffer * \param size size of the buffer component * \return success */ virtual bool Read(const Header &dpxHeader, ElementReadStream *fd, const Block &block, void *data, const DataSize size); protected: U32 *scanline; //!< single scanline }; } #endif openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/EndianSwap.h0000644000175000017500000000643012271062644024143 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _CINEON_ENDIANSWAP_H #define _CINEON_ENDIANSWAP_H 1 namespace cineon { template T SwapBytes(T& value) { register unsigned char *pe, *ps = reinterpret_cast(&value); register unsigned char c; register size_t s = (sizeof(T)); pe = ps + s - 1; for (size_t i = s/2; i > 0; i--) { c = *ps; *ps = *pe; *pe = c; ps++; pe--; } return value; } template <> inline unsigned short SwapBytes( unsigned short& value ) { register unsigned char *p = reinterpret_cast(&value); register unsigned char c = p[0]; p[0] = p[1]; p[1] = c; return value; } template <> inline unsigned char SwapBytes( unsigned char& value ) { return value; } template <> inline char SwapBytes( char& value ) { return value; } template void SwapBuffer(T *buf, unsigned int len) { for (unsigned int i = 0; i < len; i++) SwapBytes(buf[i]); } template void EndianSwapImageBuffer(void *data, int length) { switch (SIZE) { case cineon::kByte: break; case cineon::kWord: SwapBuffer(reinterpret_cast(data), length); break; case cineon::kInt: SwapBuffer(reinterpret_cast(data), length); break; case cineon::kLongLong: SwapBuffer(reinterpret_cast(data), length); break; } } inline void EndianSwapImageBuffer(DataSize size, void *data, int length) { switch (size) { case cineon::kByte: break; case cineon::kWord: SwapBuffer(reinterpret_cast(data), length); break; case cineon::kInt: SwapBuffer(reinterpret_cast(data), length); break; case cineon::kLongLong: SwapBuffer(reinterpret_cast(data), length); break; } } } #endif openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/ElementReadStream.cpp0000644000175000017500000000701712271062644026010 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "Cineon.h" #include "EndianSwap.h" #include "ElementReadStream.h" #include cineon::ElementReadStream::ElementReadStream(InStream *fd) : fd(fd) { } cineon::ElementReadStream::~ElementReadStream() { } void cineon::ElementReadStream::Reset() { } bool cineon::ElementReadStream::Read(const cineon::Header &dpxHeader, const long offset, void * buf, const size_t size) { long position = dpxHeader.ImageOffset() + offset; // seek to the memory position if (this->fd->Seek(position, InStream::kStart) == false) return false; // read in the data, calculate buffer offset if (this->fd->Read(buf, size) != size) return false; // swap the bytes if different byte order this->EndianDataCheck(dpxHeader, buf, size); return true; } bool cineon::ElementReadStream::ReadDirect(const cineon::Header &dpxHeader, const long offset, void * buf, const size_t size) { long position = dpxHeader.ImageOffset() + offset; // seek to the memory position if (this->fd->Seek(position, InStream::kStart) == false) return false; // read in the data, calculate buffer offset if (this->fd->ReadDirect(buf, size) != size) return false; // swap the bytes if different byte order this->EndianDataCheck(dpxHeader, buf, size); return true; } void cineon::ElementReadStream::EndianDataCheck(const cineon::Header &dpxHeader, void *buf, const size_t size) { if (dpxHeader.RequiresByteSwap()) { // FIXME!!! switch (dpxHeader.BitDepth(0)) { case 8: break; case 12: if (dpxHeader.ImagePacking() == cineon::kPacked) cineon::EndianSwapImageBuffer(buf, size / sizeof(U32)); else cineon::EndianSwapImageBuffer(buf, size / sizeof(U16)); break; case 16: cineon::EndianSwapImageBuffer(buf, size / sizeof(U16)); break; default: // 10-bit, 32-bit, 64-bit cineon::EndianSwapImageBuffer(buf, size / sizeof(U32)); } } } openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/CineonHeader.cpp0000644000175000017500000003344112271062644024773 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include "strutil.h" #include "CineonHeader.h" #include "EndianSwap.h" // shortcut macros #define EmptyString(x) memset(x, 0, sizeof(x)) #define EmptyFloat(x) x = std::numeric_limits::infinity() #define EmptyVector(x) (EmptyFloat((x)[0]), \ EmptyFloat((x)[1])) namespace cineon { char Hex(char x) { if (x >= 10) return (x-10+'A'); else return (x+'0'); } cineon::Header::Header() : GenericHeader(), IndustryHeader() { } cineon::GenericHeader::GenericHeader() { this->Reset(); } void cineon::GenericHeader::Reset() { // File Information this->magicNumber = MAGIC_COOKIE; this->imageOffset = ~0; EmptyString(this->version); OIIO::Strutil::safe_strcpy(this->version, SPEC_VERSION, sizeof(this->version)); fileSize = sizeof(cineon::Header); // genericSize is the size of the file/image/orientation headers // sizeof(cineon::GenericHeader) won't give the correct results because // of compiler padding this->genericSize = 1024; // industrySize is the size of the motion picture/television headers this->industrySize = 1024; this->userSize = 0; EmptyString(this->fileName); EmptyString(this->creationDate); EmptyString(this->creationTime); EmptyString(this->reserved1); // Image Information this->imageOrientation = kUndefinedOrientation; this->numberOfElements = 0xff; this->unused1[0] = this->unused1[1] = 0xff; EmptyVector(this->whitePoint); EmptyVector(this->redPrimary); EmptyVector(this->greenPrimary); EmptyVector(this->bluePrimary); EmptyString(this->labelText); EmptyString(this->reserved2); this->interleave = 0xff; this->packing = 0xff; this->dataSign = 0xff; this->imageSense = 0xff; this->endOfLinePadding = 0xffffffff; this->endOfImagePadding = 0xffffffff; // Image Orientation this->xOffset = this->yOffset = 0xffffffff; EmptyString(this->sourceImageFileName); EmptyString(this->sourceDate); EmptyString(this->sourceTime); EmptyString(this->inputDevice); EmptyString(this->inputDeviceModelNumber); EmptyString(this->inputDeviceSerialNumber); EmptyFloat(this->xDevicePitch); EmptyFloat(this->yDevicePitch); EmptyFloat(this->gamma); EmptyString(this->reserved3); EmptyString(this->reserved4); } cineon::IndustryHeader::IndustryHeader() { this->Reset(); } void cineon::IndustryHeader::Reset() { // Motion Picture Industry Specific this->filmManufacturingIdCode = 0xFF; this->filmType = 0xFF; this->perfsOffset = 0xFF; this->prefix = 0xFFFFFFFF; this->count = 0xFFFFFFFF; EmptyString(this->format); this->framePosition = 0xffffffff; EmptyFloat(this->frameRate); EmptyString(this->frameId); EmptyString(this->slateInfo); EmptyString(this->reserved1); } cineon::ImageElement::ImageElement() { this->lowData = 0xffffffff; this->lowQuantity = 0xffffffff; this->highData = 0xffffffff; this->highQuantity = 0xffffffff; this->bitDepth = 0xff; } bool cineon::Header::Read(InStream *io) { // rewind file io->Rewind(); // read in the header from the file size_t r = sizeof(GenericHeader) + sizeof(IndustryHeader); if (io->Read(&(this->magicNumber), r) != r) return false; // validate return this->Validate(); } // Check to see if the compiler placed the data members in the expected memory offsets bool cineon::Header::Check() { // genericSize is the size of the file/image/orientation headers // sizeof(cineon::GenericHeader) won't give the correct results because // of compiler padding // file header is 768 bytes // image header is 640 bytes // orientation header 256 bytes if (sizeof(GenericHeader) != (768 + 640 + 256)) return false; // industrySize is the size of the motion picture/television headers // motion picture header is 256 bytes // television header is 128 bytes if (sizeof(IndustryHeader) != (256 + 128)) return false; // data size checks if (sizeof(U8) != 1 || sizeof(U16) != 2 || sizeof(U32) != 4 || sizeof(R32) != 4 || sizeof(R64) != 8) return false; return true; } bool cineon::Header::Write(OutStream *io) { // write the header to the file size_t r = sizeof(GenericHeader) + sizeof(IndustryHeader); if (io->Write(&(this->magicNumber), r) != r) return false; return true; } bool cineon::Header::WriteOffsetData(OutStream *io) { // calculate the number of elements this->CalculateNumberOfElements(); // write the image offset const long FIELD2 = 4; // offset to image in header if (io->Seek(FIELD2, OutStream::kStart) == false) return false; if (io->Write(&this->imageOffset, sizeof(U32)) == false) return false; // write the file size const long FIELD4 = 16; // offset to total image file size in header if (io->Seek(FIELD4, OutStream::kStart) == false) return false; if (io->Write(&this->fileSize, sizeof(U32)) == false) return false; // write the number of elements const long FIELD19 = 770; // offset to number of image elements in header if (io->Seek(FIELD19, OutStream::kStart) == false) return false; if (io->Write(&this->numberOfElements, sizeof(U16)) == false) return false; // write the image offsets //const long FIELD21_12 = 808; // offset to image offset in image element data structure //const long IMAGE_STRUCTURE = 72; // sizeof the image data structure /*int i; for (i = 0; i < MAX_ELEMENTS; i++) { // only write if there is a defined image description if (this->chan[i].descriptor == kUndefinedDescriptor) continue; // seek to the image offset entry in each image element if (io->Seek((FIELD21_12 + (IMAGE_STRUCTURE * i)), OutStream::kStart) == false) return false; // write if (io->Write(&this->chan[i].dataOffset, sizeof(U32)) == false) return false; }*/ return true; } bool cineon::Header::ValidMagicCookie(const U32 magic) { U32 mc = MAGIC_COOKIE; if (magic == mc) return true; else if (magic == SwapBytes(mc)) return true; else return false; } bool cineon::Header::DetermineByteSwap(const U32 magic) const { U32 mc = MAGIC_COOKIE; bool byteSwap = false; if (magic != mc) byteSwap = true; return byteSwap; } bool cineon::Header::Validate() { // check magic cookie if (!this->ValidMagicCookie(this->magicNumber)) return false; // determine if bytes needs to be swapped around if (this->DetermineByteSwap(this->magicNumber)) { // File information SwapBytes(this->imageOffset); SwapBytes(this->genericSize); SwapBytes(this->industrySize); SwapBytes(this->userSize); SwapBytes(this->fileSize); // Image information for (int i = 0; i < MAX_ELEMENTS; i++) { SwapBytes(this->chan[i].pixelsPerLine); SwapBytes(this->chan[i].linesPerElement); SwapBytes(this->chan[i].lowData); SwapBytes(this->chan[i].lowQuantity); SwapBytes(this->chan[i].highData); SwapBytes(this->chan[i].highQuantity); SwapBytes(this->chan[i].bitDepth); } SwapBytes(this->whitePoint[0]); SwapBytes(this->whitePoint[1]); SwapBytes(this->redPrimary[0]); SwapBytes(this->redPrimary[1]); SwapBytes(this->greenPrimary[0]); SwapBytes(this->greenPrimary[1]); SwapBytes(this->bluePrimary[0]); SwapBytes(this->bluePrimary[1]); SwapBytes(this->endOfLinePadding); SwapBytes(this->endOfImagePadding); // Image Origination information SwapBytes(this->xOffset); SwapBytes(this->yOffset); SwapBytes(this->xDevicePitch); SwapBytes(this->yDevicePitch); SwapBytes(this->gamma); // Motion Picture Industry Specific SwapBytes(this->prefix); SwapBytes(this->count); SwapBytes(this->framePosition); SwapBytes(this->frameRate); } return true; } void cineon::Header::Reset() { GenericHeader::Reset(); IndustryHeader::Reset(); } int cineon::GenericHeader::ImageElementCount() const { int i = 0; while (i < MAX_ELEMENTS ) { if (this->ImageDescriptor(i) == kUndefinedDescriptor) break; i++; } return i; } void cineon::GenericHeader::CalculateNumberOfElements() { int i = this->ImageElementCount(); if (i == 0) this->numberOfElements = 0xff; else this->numberOfElements = U8(i); } void cineon::Header::CalculateOffsets() { int i; for (i = 0; i < MAX_ELEMENTS; i++) { // only write if there is a defined image description if (this->chan[i].designator[1] == kUndefinedDescriptor) continue; } } cineon::DataSize cineon::GenericHeader::ComponentDataSize(const int element) const { if (element < 0 || element >= MAX_ELEMENTS) return kByte; cineon::DataSize ret; switch (this->chan[element].bitDepth) { case 8: ret = kByte; break; case 10: case 12: case 16: ret = kWord; break; case 32: ret = kInt; break; case 64: ret = kLongLong; break; default: assert(0 && "Unknown bit depth"); ret = kLongLong; break; } return ret; } int cineon::GenericHeader::ComponentByteCount(const int element) const { if (element < 0 || element >= MAX_ELEMENTS) return kByte; int ret; switch (this->chan[element].bitDepth) { case 8: ret = sizeof(U8); break; case 10: case 12: case 16: ret = sizeof(U16); break; case 32: ret = sizeof(R32); break; case 64: ret = sizeof(R64); break; default: assert(0 && "Unknown bit depth"); ret = sizeof(R64); break; } return ret; } int cineon::GenericHeader::DataSizeByteCount(const DataSize ds) { int ret = 0; switch (ds) { case kByte: ret = sizeof(U8); break; case kWord: ret = sizeof(U16); break; case kInt: ret = sizeof(U32); break; case kLongLong: ret = sizeof(U64); break; } return ret; } void cineon::IndustryHeader::FilmEdgeCode(char *edge) const { if (this->filmManufacturingIdCode == 0xff && this->filmType == 0xff && this->perfsOffset == 0xff && this->prefix == 0xffffffff && this->count == 0xffffffff) *edge = 0; else sprintf(edge, "%02u%02u%02u%06u%04u", (unsigned int)this->filmManufacturingIdCode, (unsigned int)this->filmType, (unsigned int)this->perfsOffset, this->prefix, this->count); } void cineon::IndustryHeader::SetFilmEdgeCode(const char *edge) { char buf[7]; strncpy(buf, edge, 2); this->filmManufacturingIdCode = atoi(buf); strncpy(buf, edge + 2, 2); this->filmType = atoi(buf); strncpy(buf, edge + 4, 2); this->perfsOffset = atoi(buf); strncpy(buf, edge + 6, 6); this->prefix = atoi(buf); strncpy(buf, edge + 12, 4); this->count = atoi(buf); } void cineon::GenericHeader::SetCreationTimeDate(const long sec) { struct tm *tm_time; char str[32]; #ifdef WIN32 _tzset(); #endif const time_t t = time_t(sec); tm_time = ::localtime(&t); ::strftime(str, 32, "%Y:%m:%d:%H:%M:%S%Z", tm_time); ::strncpy(this->creationDate, str, 10); ::strncpy(this->creationTime, str + 11, 12); } void cineon::GenericHeader::SetSourceTimeDate(const long sec) { struct tm *tm_time; char str[32]; #ifdef WIN32 _tzset(); #endif const time_t t = time_t(sec); tm_time = ::localtime(&t); ::strftime(str, 32, "%Y:%m:%d:%H:%M:%S%Z", tm_time); ::strncpy(this->sourceDate, str, 10); ::strncpy(this->sourceTime, str + 11, 12); } // Height() // this function determines the height of the image taking in account for the image orientation // if an image is 1920x1080 but is oriented top to bottom, left to right then the height stored // in the image is 1920 rather than 1080 cineon::U32 cineon::Header::Height() const { U32 h = 0; for (int i = 0; i < this->NumberOfElements(); i++) { switch (this->ImageOrientation()) { case kTopToBottomLeftToRight: case kTopToBottomRightToLeft: case kBottomToTopLeftToRight: case kBottomToTopRightToLeft: if (this->PixelsPerLine(i) > h) h = this->PixelsPerLine(i); break; default: if (this->LinesPerElement(i) > h) h = this->LinesPerElement(i); break; } } return h; } // Width() // this function determines the width of the image taking in account for the image orientation // if an image is 1920x1080 but is oriented top to bottom, left to right then the width stored // in the image is 1920 rather than 1080 cineon::U32 cineon::Header::Width() const { U32 w = 0; for (int i = 0; i < this->NumberOfElements(); i++) { switch (this->ImageOrientation()) { case kTopToBottomLeftToRight: case kTopToBottomRightToLeft: case kBottomToTopLeftToRight: case kBottomToTopRightToLeft: if (this->LinesPerElement(i) > w) w = this->LinesPerElement(i); break; default: if (this->PixelsPerLine(i) > w) w = this->PixelsPerLine(i); break; } } return w; } } openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/Cineon.cpp0000644000175000017500000000441212271062644023656 0ustar mfvmfv// vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "Cineon.h" // determine byte order for current system // Intel processors are Little Endian // Power PC, MIPS and Ultra Sparc are Big Endian static unsigned long lValue = 0x12345678; static unsigned long *lPtr = &lValue; cineon::Endian cineon::systemByteOrder = (*(unsigned char*)lPtr == 0x78 ? cineon::kLittleEndian : cineon::kBigEndian); bool cineon::IdentifyFile(InStream *fp) { U32 magic; fp->Rewind(); if (fp->Read(&magic, sizeof(magic)) != sizeof(magic)) return false; return cineon::Header::ValidMagicCookie(magic); } bool cineon::IdentifyFile(const void *p) { U32 magic = *((U32 *) p); return cineon::Header::ValidMagicCookie(magic); } openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/BaseTypeConverter.h0000644000175000017500000001121212271062644025510 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _CINEON_BASETYPECONVERTER_H #define _CINEON_BASETYPECONVERTER_H 1 namespace cineon { // convert between all of the DPX base types in a controllable way inline void BaseTypeConverter(U8 &src, U8 &dst) { dst = src; } inline void BaseTypeConverter(U8 &src, U16 &dst) { dst = (src << 8) | src; } inline void BaseTypeConverter(U8 &src, U32 &dst) { dst = (src << 24) | (src << 16) | (src << 8) | src; } inline void BaseTypeConverter(U8 &src, U64 &dst) { dst = static_cast(src) << 56; } inline void BaseTypeConverter(U8 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(U8 &src, R64 &dst) { dst = src; } inline void BaseTypeConverter(U16 &src, U8 &dst) { dst = src >> 8; } inline void BaseTypeConverter(U16 &src, U16 &dst) { dst = src; } inline void BaseTypeConverter(U16 &src, U32 &dst) { dst = src << 16; } inline void BaseTypeConverter(U16 &src, U64 &dst) { dst = static_cast(src) << 48; } inline void BaseTypeConverter(U16 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(U16 &src, R64 &dst) { dst = src; } inline void BaseTypeConverter(U32 &src, U8 &dst) { dst = src >> 24; } inline void BaseTypeConverter(U32 &src, U16 &dst) { dst = src >> 16; } inline void BaseTypeConverter(U32 &src, U32 &dst) { dst = src; } inline void BaseTypeConverter(U32 &src, U64 &dst) { dst = static_cast(src) << 32; } inline void BaseTypeConverter(U32 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(U32 &src, R64 &dst) { dst = src; } inline void BaseTypeConverter(U64 &src, U8 &dst) { dst = src >> 56; } inline void BaseTypeConverter(U64 &src, U16 &dst) { dst = src >> 48; } inline void BaseTypeConverter(U64 &src, U32 &dst) { dst = src >> 32; } inline void BaseTypeConverter(U64 &src, U64 &dst) { dst = src; } inline void BaseTypeConverter(U64 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(U64 &src, R64 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, U8 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, U16 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, U32 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, U64 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(R32 &src, R64 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, U8 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, U16 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, U32 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, U64 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, R32 &dst) { dst = src; } inline void BaseTypeConverter(R64 &src, R64 &dst) { dst = src; } inline void BaseTypeConvertU10ToU16(U16 &src, U16 &dst) { dst = (src << 6) | (src >> 4); } inline void BaseTypeConvertU12ToU16(U16 &src, U16 &dst) { dst = (src << 4) | (src >> 8); } } #endif openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/CineonHeader.h0000644000175000017500000011472612271062644024446 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /*! \file CineonHeader.h */ /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ // Cineon graphic file format v4.5 #ifndef _CINEON_CINEONHEADER_H #define _CINEON_CINEONHEADER_H 1 #include #include #if defined(_MSC_VER) && _MSC_VER < 1600 typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #else # include #endif #include "CineonStream.h" /*! * \def SPEC_VERSION * \brief Cineon format version */ #define SPEC_VERSION "V4.5" /*! * \def MAX_ELEMENTS * \brief Maximum number of image elements */ #define MAX_ELEMENTS 8 /*! * \def MAX_COMPONENTS * \brief Maximum number of components per image element */ #define MAX_COMPONENTS 8 /*! * \def MAGIC_COOKIE * \brief HEX value of 0x802A5FD7 */ #define MAGIC_COOKIE 0x802A5FD7 namespace cineon { // DPX data types /*! * \typedef unsigned char U8 * \brief Unsigned 8 bit integer */ typedef unsigned char U8; /*! * \typedef unsigned short U16 * \brief Unsigned 16 bit integer */ typedef unsigned short U16; /*! * \typedef unsigned int U32 * \brief Unsigned 32 bit integer */ typedef unsigned int U32; /*! * \typedef signed char U32 * \brief Signed 32 bit integer */ typedef signed int S32; /*! * \typedef unsigned long long U64 * \brief Unsigned 64 bit integer */ typedef uint64_t U64; /*! * \typedef float R32 * \brief 32 bit floating point number */ typedef float R32; /*! * \typedef float R64 * \brief 64 bit floating point number */ typedef double R64; /*! * \typedef char ASCII * \brief ASCII character */ typedef char ASCII; /*! * \enum DataSize * \brief Component Data Storage Data Type */ enum DataSize { kByte, //!< 8-bit size component kWord, //!< kInt, //!< kLongLong //!< 64-bit integer }; /*! * \enum Orientation * \brief Image Orientation Code */ enum Orientation { kLeftToRightTopToBottom = 0, //!< Oriented left to right, top to bottom kRightToLeftTopToBottom = 1, //!< Oriented right to left, top to bottom kLeftToRightBottomToTop = 2, //!< Oriented left to right, bottom to top kRightToLeftBottomToTop = 3, //!< Oriented right to left, bottom to top kTopToBottomLeftToRight = 4, //!< Oriented top to bottom, left to right kTopToBottomRightToLeft = 5, //!< Oriented top to bottom, right to left kBottomToTopLeftToRight = 6, //!< Oriented bottom to top, left to right kBottomToTopRightToLeft = 7, //!< Oriented bottom to top, right to left kUndefinedOrientation = 0xff //!< Undefined orientation }; /*! * \enum Descriptor * \brief Image element Descriptor (second byte) */ enum Descriptor { kGrayscale = 0, //!< Grayscale kPrintingDensityRed = 1, //!< Red kPrintingDensityGreen = 2, //!< Green kPrintingDensityBlue = 3, //!< Blue kRec709Red = 4, //!< Red kRec709Green = 5, //!< Green kRec709Blue = 6, //!< Blue kUndefinedDescriptor = 0xff //!< Undefined descriptor }; /*! * \enum Interleave * \brief Component interleaving method */ enum Interleave { kPixel = 0, //!< Pixel interleave (rgbrgbrgb...) kLine = 1, //!< Line interleave (rrr.ggg.bbb.rrr.ggg.bbb.) kChannel = 2 //!< Channel interleave (rrr..ggg..bbb..) }; /*! * \enum Packing * \brief Component data packing method */ enum Packing { kPacked = 0, //!< Use all bits (tight packing) kByteLeft = 1, //!< Byte (8-bit) boundary, left justified kByteRight = 2, //!< Byte (8-bit) boundary, right justified kWordLeft = 3, //!< Word (16-bit) boundary, left justified kWordRight = 4, //!< Word (16-bit) boundary, right justified kLongWordLeft = 5, //!< Longword (32-bit) boundary, left justified kLongWordRight = 6, //!< Longword (32-bit) boundary, right justified kPackAsManyAsPossible = 0x80 //!< Bitflag - if present, pack as many fields as possible per cell, only one otherwise }; /*! * \struct ImageElement * \brief Data Structure for Image Element */ struct ImageElement { U8 designator[2]; //!< Channel descriptor \see Descriptor U8 bitDepth; //!< Bits per pixel U8 unused1; //!< Unused U32 pixelsPerLine; //!< Pixels per line U32 linesPerElement; //!< Lines per element R32 lowData; //!< Reference low data code value R32 lowQuantity; //!< Reference low quantity represented R32 highData; //!< Reference high data code value R32 highQuantity; //!< Reference high quantity represented /*! * \brief Constructor */ ImageElement(); }; /*! * \struct GenericHeader * \brief Generic File and Image Header Information */ struct GenericHeader { /*! * \name File Information Members */ //@{ U32 magicNumber; //!< Indicates start of DPX image file and is used to determine byte order. U32 imageOffset; //!< Offset to image data (in bytes) U32 genericSize; //!< Generic Header length (in bytes) U32 industrySize; //!< Industry Header length (in bytes) U32 userSize; //!< User defined header length (in bytes) U32 fileSize; //!< Total file size (in bytes) ASCII version[8]; //!< Version number of header format ASCII fileName[100]; //!< File name ASCII creationDate[12]; //!< Create date /see DateTimeFormat ASCII creationTime[12]; //!< Create time /see DateTimeFormat ASCII reserved1[36]; //!< Reserved /* end of group */ //@} /*! * \name Image Information Members */ //@{ U8 imageOrientation; //!< Image orientation \see Orientation U8 numberOfElements; //!< Number of elements (1-8) U8 unused1[2]; //!< Unused (word alignment) ImageElement chan[MAX_ELEMENTS]; //!< Image element data structures R32 whitePoint[2]; //!< White point (x, y pair) R32 redPrimary[2]; //!< Red primary chromaticity (x, y pair) R32 greenPrimary[2]; //!< Green primary chromaticity (x, y pair) R32 bluePrimary[2]; //!< Blue primary chromaticity (x, y pair) ASCII labelText[200]; //!< Label text ASCII reserved2[28]; //!< Reserved U8 interleave; //!< Data interleave \see Interleave U8 packing; //!< Packing \see Packing U8 dataSign; //!< Data sign (0 = unsigned, 1 = signed) U8 imageSense; //!< Image sense (0 = positive image, 1 = negative image) U32 endOfLinePadding; //!< End-of-Line Padding U32 endOfImagePadding; //!< End-of-Image Padding ASCII reserved3[20]; /* end of group */ //@} /*! * \name Image Origination Members */ //@{ S32 xOffset; //!< X offset S32 yOffset; //!< Y offset ASCII sourceImageFileName[100]; //!< Source image file name ASCII sourceDate[12]; //!< Source date /see DateTimeFormat ASCII sourceTime[12]; //!< Source time /see DateTimeFormat ASCII inputDevice[64]; //!< Input device name ASCII inputDeviceModelNumber[32]; //!< Input device model number ASCII inputDeviceSerialNumber[32]; //!< Input device serial number R32 xDevicePitch; //!< X device pitch (samples/mm) R32 yDevicePitch; //!< Y device pitch (samples/mm) R32 gamma; //!< Gamma ASCII reserved4[40]; //!< Reserved /* end of group */ //@} /*! * \brief Constructor */ GenericHeader(); /*! * \brief Reset class to initial state */ void Reset(); /*! * \name File Information Methods */ //@{ /*! * \brief Get magic number, used for byte ordering identification * \return magic number */ inline U32 MagicNumber() const; /*! * \brief Get the offset in bytes to the start of the first image element * \return offset */ inline U32 ImageOffset() const; /*! * \brief Set the offset in bytes to the start of the first image element * \param offset offset in bytes */ inline void SetImageOffset(const U32 offset); /*! * \brief Get the size of the generic section within the header * \return generic header size in bytes */ inline U32 GenericSize() const; /*! * \brief Get the size of the industry section within the header * \return industry header size in bytes */ inline U32 IndustrySize() const; /*! * \brief Get the size of the user data * \return user data size in bytes */ inline U32 UserSize() const; /*! * \brief Set the size of the user data * \param size user data size in bytes */ inline void SetUserSize(const U32 size); /*! * \brief Get the size of the entire file * \return file size in bytes */ inline U32 FileSize() const; /*! * \brief Set the size of the entire file * \param fs file size in bytes */ inline void SetFileSize(const U32 fs); /*! * \brief Get current version string of header * \param v buffer to place string, needs to be at least 8+1 bytes long */ inline void Version(char *v) const; /*! * \brief Set the version string * \param v version string */ inline void SetVersion(const char *v); /*! * \brief Get the file name * \param fn buffer to store filename (100+1 chars) */ inline void FileName(char *fn) const; /*! * \brief Set the file name * \param fn buffer with filename */ inline void SetFileName(const char *fn); /*! * \brief Get the creation time/date * \param ct buffer to store creation time/date (24+1 chars) */ inline void CreationDate(char *ct) const; /*! * \brief Set the creation time/date * \param ct buffer with creation time/date */ inline void SetCreationDate(const char *ct); /*! * \brief Get the creation time/date * \param ct buffer to store creation time/date (24+1 chars) */ inline void CreationTime(char *ct) const; /*! * \brief Set the creation time/date * \param ct buffer with creation time/date */ inline void SetCreationTime(const char *ct); /*! * \brief Set the creation time/date * \param secs number of seconds since January 1, 1970 00:00 */ void SetCreationTimeDate(const long secs); /* end of group */ //@} /*! * \name Image Information Methods */ //@{ /*! * \brief Get the image orientation * \return orientation enum */ inline Orientation ImageOrientation() const; /*! * \brief Set the image orientation * \param orient orientation */ inline void SetImageOrientation(const Orientation orient); /*! * \brief Get the number of elements * \return element count */ inline U8 NumberOfElements() const; /*! * \brief Set the number of elements * \param num element count */ inline void SetNumberOfElements(const U8 num); /*! * \brief Get the first byte of the channel designator - metric info * \param i element index (0-7) * \return 0 = universal metric, 1-254 = vendor-specific */ inline U8 Metric(const int i) const; /*! * \brief Set the first byte of the channel designator - metric info * \param i element index (0-7) * \param ppl metric */ inline void SetMetric(const int i, const U8 m); /*! * \brief Get the second byte of the channel designator * \param i element index (0-7) * \return channel descriptor */ inline Descriptor ImageDescriptor(const int i) const; /*! * \brief Set the second byte of the channel designator * \param i element index (0-7) * \param d channel descriptor */ inline void SetImageDescriptor(const int i, const Descriptor d); /*! * \brief Get the bits per pixel * \param i element index (0-7) * \return bit count */ inline U8 BitDepth(const int i) const; /*! * \brief Set the bits per pixel * \param i element index (0-7) * \param bpp bit count */ inline void SetBitDepth(const int i, const U8 bpp); /*! * \brief Get the pixels per line * \param i element index (0-7) * \return pixel count */ inline U32 PixelsPerLine(const int i) const; /*! * \brief Set the pixels per line * \param i element index (0-7) * \param ppl pixel count */ inline void SetPixelsPerLine(const int i, const U32 ppl); /*! * \brief Get the lines per element * \param i element index (0-7) * \return lines count */ inline U32 LinesPerElement(const int i) const; /*! * \brief Set the lines per element * \param i element index (0-7) * \param lpe lines count */ inline void SetLinesPerElement(const int i, const U32 lpe); /*! * \brief Get the minimum data value * \param i element index (0-7) * \return minimum value */ inline R32 LowData(const int i) const; /*! * \brief Set the minimum data value * \param i element index (0-7) * \param data minimum value */ inline void SetLowData(const int i, const R32 data); /*! * \brief Get the quantity of minimum data value * \param i element index (0-7) * \return quantity */ inline R32 LowQuantity(const int i) const; /*! * \brief Set the quantity of minimum data value * \param i element index (0-7) * \param quant quantity */ inline void SetLowQuantity(const int i, const R32 quant); /*! * \brief Get the maximum data value * \param i element index (0-7) * \return maximum value */ inline R32 HighData(const int i) const; /*! * \brief Set the maximum data value * \param i element index (0-7) * \param data maximum value */ inline void SetHighData(const int i, const R32 data); /*! * \brief Get the quantity of maximum data value * \param i element index (0-7) * \return quantity */ inline R32 HighQuantity(const int i) const; /*! * \brief Set the quantity of maximum data value * \param i element index (0-7) * \param quant quantity */ inline void SetHighQuantity(const int i, const R32 quant); /*! * \brief Get the white point primary x, y pair * \param xy buffer to store the x, y pair (2 32-bit floats) */ inline void WhitePoint(R32 xy[2]) const; /*! * \brief Set the white point primary x, y pair * \param xy the x, y pair (2 32-bit floats) */ inline void SetWhitePoint(const R32 xy[2]); /*! * \brief Get the red primary x, y pair * \param xy buffer to store the x, y pair (2 32-bit floats) */ inline void RedPrimary(R32 xy[2]) const; /*! * \brief Set the red primary x, y pair * \param xy the x, y pair (2 32-bit floats) */ inline void SetRedPrimary(const R32 xy[2]); /*! * \brief Get the green primary x, y pair * \param xy buffer to store the x, y pair (2 32-bit floats) */ inline void GreenPrimary(R32 xy[2]) const; /*! * \brief Set the green primary x, y pair * \param xy the x, y pair (2 32-bit floats) */ inline void SetGreenPrimary(const R32 xy[2]); /*! * \brief Get the blue primary x, y pair * \param xy buffer to store the x, y pair (2 32-bit floats) */ inline void BluePrimary(R32 xy[2]) const; /*! * \brief Set the blue primary x, y pair * \param xy the x, y pair (2 32-bit floats) */ inline void SetBluePrimary(const R32 xy[2]); /*! * \brief Get the label text * \param ct buffer to store label text (200 chars) */ inline void LabelText(char *ct) const; /*! * \brief Set the label text * \param ct buffer with label text */ inline void SetLabelText(const char *ct); /*! * \brief Get the data interleave mode * \return interleave method */ inline Interleave ImageInterleave() const; /*! * \brief Set the data intearleave mode * \param inter intearleave method */ inline void SetImageInterleave(const Interleave inter); /*! * \brief Get the data packing mode * \return packing method */ inline Packing ImagePacking() const; /*! * \brief Set the data packing mode * \param pack packing method */ inline void SetImagePacking(const Packing pack); /*! * \brief Get the data sign (0 = unsigned, 1 = signed) * \return data sign */ inline U8 DataSign() const; /*! * \brief Set the data sign (0 = unsigned, 1 = signed) * \param sign data sign */ inline void SetDataSign(const U8 sign); /*! * \brief Get the image sense (0 = positive, 1 = negative) * \return image sense */ inline U8 ImageSense() const; /*! * \brief Set the image sense (0 = positive, 1 = negative) * \param sense image sense */ inline void SetImageSense(const U8 sense); /*! * \brief Get the number of bytes padding the end of each line * \param i element index (0-7) * \return count */ inline U32 EndOfLinePadding() const; /*! * \brief Set the number of bytes padding the end of each line * \param i element index (0-7) * \param eolp count */ inline void SetEndOfLinePadding(const U32 eolp); /*! * \brief Get the number of bytes padding the end of the image element * \param i element index (0-7) * \return count */ inline U32 EndOfImagePadding() const; /*! * \brief Set the number of bytes padding the end of the image element * \param i element index (0-7) * \param eoip count */ inline void SetEndOfImagePadding(const U32 eoip); /* end of group */ //@} /*! * \name Image Origination Methods */ //@{ /*! * \brief Get the line offset (in pixels) from the first pixel in original image * \return offset count */ inline S32 XOffset() const; /*! * \brief Set the line offset (in pixels) from the first pixel in original image * \param offset offset count */ inline void SetXOffset(const S32 offset); /*! * \brief Get the frame offset (in lines) from the first line in original image * \return offset count */ inline S32 YOffset() const; /*! * \brief Set the frame offset (in lines) from the first line in original image * \param offset offset count */ inline void SetYOffset(const S32 offset); /*! * \brief Get the source image file name that this image was extracted * \param fn buffer to write source file name (100+1) */ inline void SourceImageFileName(char *fn) const; /*! * \brief Set the source image file name that this image was extracted * \param fn buffer with source file name */ inline void SetSourceImageFileName(const char *fn); /*! * \brief Get the source image time and date that this image was extracted * \param td buffer to write time/date string (24+1) */ inline void SourceDate(char *td) const; /*! * \brief Set the source image time and date that this image was extracted * \param td buffer with time/date string */ inline void SetSourceDate(const char *td); /*! * \brief Get the source image time and date that this image was extracted * \param td buffer to write time/date string (24+1) */ inline void SourceTime(char *td) const; /*! * \brief Set the source image time and date that this image was extracted * \param td buffer with time/date string */ inline void SetSourceTime(const char *td); /*! * \brief Set the source image time and date that this image was extracted * \param secs number of seconds since January 1, 1970 00:00 */ void SetSourceTimeDate(const long secs); /*! * \brief Get the input device name * \param dev buffer to write device (64+1) */ inline void InputDevice(char *dev) const; /*! * \brief Set the input device name * \param dev buffer with device name */ inline void SetInputDevice(const char *dev); /*! * \brief Get the input device model number * \param sn buffer to write device model number (32+1) */ inline void InputDeviceModelNumber(char *sn) const; /*! * \brief Set the input device model number * \param sn buffer with device model number */ inline void SetInputDeviceModelNumber(const char *sn); /*! * \brief Get the input device serial number * \param sn buffer to write device serial number (32+1) */ inline void InputDeviceSerialNumber(char *sn) const; /*! * \brief Set the input device serial number * \param sn buffer with device serial number */ inline void SetInputDeviceSerialNumber(const char *sn); /*! * \brief Get the horizontal pitch of the device * \return pitch in samples/mm */ inline R32 XDevicePitch() const; /*! * \brief Set the horizontal pitch of the device * \param size pitch in samples/mm */ inline void SetXDevicePitch(const R32 size); /*! * \brief Get the veritcal pitch of the device * \return pitch in samples/mm */ inline R32 YDevicePitch() const; /*! * \brief Set the vertical pitch of the device * \param size pitch in samples/mm */ inline void SetYDevicePitch(const R32 size); /*! * \brief Get the gamma correction exponent * \return gamma exponent */ inline R32 Gamma() const; /*! * \brief Set the gamma correction exponent * \param gamma gamma exponent */ inline void SetGamma(const R32 gamma); /* end of group */ //@} /*! * \brief Number of Active Elements in the Image * \return element count */ int ImageElementCount() const; /*! * \brief Set member numberOfElements based on channel structure */ void CalculateNumberOfElements(); /*! * \brief DataSize required for individual image element components * \return datasize of element */ DataSize ComponentDataSize(const int element) const; /*! * \brief Byte count of data element components * \return byte count */ int ComponentByteCount(const int element) const; /* * \brief Byte size for each DataSize * \return byte count */ static int DataSizeByteCount(const DataSize ds); }; /*! * \struct IndustryHeader * \brief Motion Picture and Television Industry Specific Information */ struct IndustryHeader { /*! * \name Motion Picture Industry Specific Members */ //@{ U8 filmManufacturingIdCode; //!< Film edge code manufacturing ID code U8 filmType; //!< Film edge code type U8 perfsOffset; //!< Film edge code offset in perfs U8 unused1; //!< Unused (word alignment) U32 prefix; //!< Film edge code prefix U32 count; //!< Film edge code count ASCII format[32]; //!< Format string, e.g. Academy U32 framePosition; //!< Frame position in sequence R32 frameRate; //!< Frame rate of original (frame / sec) ASCII frameId[32]; //!< Frame identification, e.g. keyframe ASCII slateInfo[200]; //!< Slate information ASCII reserved1[740]; //!< Reserved /* end of group */ //@} /*! * \brief Constructor */ IndustryHeader(); /*! * \brief Reset class to initial state */ void Reset(); // set/get functions for the data methods /*! * \name Motion Picture Industry Specific Methods */ //@{ /*! * \brief Get the film edge code information that is machine readable * \param edge buffer to write film edge code information (16+1 chars) */ void FilmEdgeCode(char *edge) const; /*! * \brief Set the film edge code information that is machine readable * \param edge buffer with film edge code information */ void SetFilmEdgeCode(const char *edge); /*! * \brief Get the format (e.g., Academy) * \param fmt buffer to write format information (32+1 chars) */ inline void Format(char *fmt) const; /*! * \brief Set the format (e.g., Academy) * \param fmt buffer with format information */ inline void SetFormat(const char *fmt); /*! * \brief Get the frame position in sequence * \return position */ inline U32 FramePosition() const; /*! * \brief Set the frame position in sequence * \param pos position */ inline void SetFramePosition(const U32 pos); /*! * \brief Get the frame rate (frames / second) * \return rate */ inline R32 FrameRate() const; /*! * \brief Set the frame rate (frames / second) * \param rate rate */ inline void SetFrameRate(const R32 rate); /*! * \brief Get the user-defined frame identification * \param id buffer to write frame identification (32+1 chars) */ inline void FrameId(char *id) const; /*! * \brief Set the user-defined frame identification * \param id buffer with frame identification */ inline void SetFrameId(const char *id); /*! * \brief Get the production information from the camera slate * \param slate buffer to write slate information (200+1 chars) */ inline void SlateInfo(char *slate) const; /*! * \brief Set the production information from the camera slate * \param slate buffer with slate information */ inline void SetSlateInfo(const char *slate); /* end of group */ //@} protected: U32 TCFromString(const char *str) const; }; /*! * \brief Complete DPX Header */ struct Header : public GenericHeader, public IndustryHeader { Header(); /*! * \brief Set the header data to a known start state */ void Reset(); /*! * \brief Set the Input Stream object to read header from */ bool Read(InStream *); /*! * \brief Set the Output Stream object to write header to */ bool Write(OutStream *); // write the offset within the header bool WriteOffsetData(OutStream *); /*! * \brief Validate the header */ bool Validate(); /*! * \brief Does header require endian byte swap * \return swap required true/false */ inline bool RequiresByteSwap() const; /*! * \brief Check magic cookie * \return valid true/false */ static bool ValidMagicCookie(const U32 magic); /*! * \brief Returns the size of the header * \return 2048 as defined by the standard */ const U32 Size() const; /*! * \brief Calculate all of the offset members in the header */ void CalculateOffsets(); /*! * \brief Set whether reader/writer should swap component ordering * \param swap allow swapping true/false */ void SetDatumSwap(const bool swap); // system check, used only during platform port bool Check(); /*! * \brief Height of the image (maximum of all elements' heights) adjusted for orientation * \return height */ U32 Height() const; /*! * \brief Width of the image (maximum of all elements' widths) adjusted for orientation * \param element image element * \return width */ U32 Width() const; protected: bool DetermineByteSwap(const U32 magic) const; }; inline bool Header::RequiresByteSwap() const { return this->DetermineByteSwap(this->magicNumber); } inline const U32 Header::Size() const { return 2048; } inline U32 GenericHeader::MagicNumber() const { return this->magicNumber; } inline U32 GenericHeader::ImageOffset() const { return this->imageOffset; } inline void GenericHeader::SetImageOffset(const U32 offset) { this->imageOffset = offset; } inline void GenericHeader::Version(char *v) const { ::strncpy(v, this->version, 8); v[8] = '\0'; } inline void GenericHeader::SetVersion(const char * v) { ::strncpy(this->version, v, 8); } inline U32 GenericHeader::FileSize() const { return this->fileSize; } inline void GenericHeader::SetFileSize(const U32 fs) { this->fileSize = fs; } inline U32 GenericHeader::GenericSize() const { return this->genericSize; } inline U32 GenericHeader::IndustrySize() const { return this->industrySize; } inline U32 GenericHeader::UserSize() const { return this->userSize; } inline void GenericHeader::SetUserSize(const U32 size) { this->userSize = size; } inline void GenericHeader::FileName(char *fn) const { ::strncpy(fn, this->fileName, 100); fn[100] = '\0'; } inline void GenericHeader::SetFileName(const char *fn) { ::strncpy(this->fileName, fn, 100); } inline void GenericHeader::CreationDate(char *ct) const { ::strncpy(ct, this->creationDate, 12); ct[24] = '\0'; } inline void GenericHeader::SetCreationDate(const char *ct) { ::strncpy(this->creationDate, ct, 12); } inline void GenericHeader::CreationTime(char *ct) const { ::strncpy(ct, this->creationTime, 12); ct[24] = '\0'; } inline void GenericHeader::SetCreationTime(const char *ct) { ::strncpy(this->creationTime, ct, 12); } inline Orientation GenericHeader::ImageOrientation() const { return Orientation(this->imageOrientation); } inline void GenericHeader::SetImageOrientation(const Orientation orient) { this->imageOrientation = orient; } inline U8 GenericHeader::NumberOfElements() const { return this->numberOfElements; } inline void GenericHeader::SetNumberOfElements(const U8 num) { this->numberOfElements = num; } inline U32 GenericHeader::PixelsPerLine(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; return this->chan[i].pixelsPerLine; } inline void GenericHeader::SetPixelsPerLine(const int i, const U32 ppl) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].pixelsPerLine = ppl; } inline U32 GenericHeader::LinesPerElement(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xffffffff; return this->chan[i].linesPerElement; } inline void GenericHeader::SetLinesPerElement(const int i, const U32 lpe) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].linesPerElement = lpe; } inline U8 GenericHeader::DataSign() const { return this->dataSign; } inline void GenericHeader::SetDataSign(const U8 sign) { this->dataSign = sign; } inline R32 GenericHeader::LowData(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return std::numeric_limits::infinity(); return this->chan[i].lowData; } inline void GenericHeader::SetLowData(const int i, const R32 data) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].lowData = data; } inline R32 GenericHeader::LowQuantity(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return std::numeric_limits::max(); return this->chan[i].lowQuantity; } inline void GenericHeader::SetLowQuantity(const int i, const R32 quant) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].lowQuantity = quant; } inline R32 GenericHeader::HighData(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return std::numeric_limits::max(); return this->chan[i].highData; } inline void GenericHeader::SetHighData(const int i, const R32 data) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].highData = data; } inline R32 GenericHeader::HighQuantity(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return std::numeric_limits::max(); return this->chan[i].highQuantity; } inline void GenericHeader::SetHighQuantity(const int i, const R32 quant) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].highQuantity = quant; } inline U8 GenericHeader::Metric(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xff; return this->chan[i].designator[0]; } inline void GenericHeader::SetMetric(const int i, const U8 m) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].designator[0] = m; } inline Descriptor GenericHeader::ImageDescriptor(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return Descriptor(0xff); return Descriptor(this->chan[i].designator[1]); } inline void GenericHeader::SetImageDescriptor(const int i, const Descriptor desc) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].designator[1] = (U8)desc; } inline U8 GenericHeader::BitDepth(const int i) const { if (i < 0 || i >= MAX_ELEMENTS) return 0xff; return this->chan[i].bitDepth; } inline void GenericHeader::SetBitDepth(const int i, const U8 depth) { if (i < 0 || i >= MAX_ELEMENTS) return; this->chan[i].bitDepth = depth; } inline Interleave GenericHeader::ImageInterleave() const { return Interleave(this->interleave); } inline void GenericHeader::SetImageInterleave(const Interleave inter) { this->interleave = (U8)inter; } inline Packing GenericHeader::ImagePacking() const { return Packing(this->packing); } inline void GenericHeader::SetImagePacking(const Packing pack) { this->packing = (U8)pack; } inline U32 GenericHeader::EndOfLinePadding() const { if (this->endOfLinePadding == 0xffffffff) return 0; return this->endOfLinePadding; } inline void GenericHeader::SetEndOfLinePadding(const U32 eolp) { this->endOfLinePadding = eolp; } inline U32 GenericHeader::EndOfImagePadding() const { if (this->endOfImagePadding == 0xffffffff) return 0; return this->endOfImagePadding; } inline void GenericHeader::SetEndOfImagePadding(const U32 eoip) { this->endOfImagePadding = eoip; } inline void GenericHeader::LabelText(char *desc) const { strncpy(desc, this->labelText, 200); } inline void GenericHeader::SetLabelText(const char *desc) { ::strncpy(this->labelText, desc, 200); } inline S32 GenericHeader::XOffset() const { return this->xOffset; } inline void GenericHeader::SetXOffset(const S32 offset) { this->xOffset = offset; } inline S32 GenericHeader::YOffset() const { return this->yOffset; } inline void GenericHeader::SetYOffset(const S32 offset) { this->yOffset = offset; } inline void GenericHeader::WhitePoint(R32 xy[2]) const { memcpy(xy, this->whitePoint, sizeof(xy[0]) * 2); } inline void GenericHeader::SetWhitePoint(const R32 xy[2]) { memcpy(this->whitePoint, xy, sizeof(this->whitePoint[0]) * 2); } inline void GenericHeader::RedPrimary(R32 xy[2]) const { memcpy(xy, this->redPrimary, sizeof(xy[0]) * 2); } inline void GenericHeader::SetRedPrimary(const R32 xy[2]) { memcpy(this->redPrimary, xy, sizeof(this->redPrimary[0]) * 2); } inline void GenericHeader::GreenPrimary(R32 xy[2]) const { memcpy(xy, this->greenPrimary, sizeof(xy[0]) * 2); } inline void GenericHeader::SetGreenPrimary(const R32 xy[2]) { memcpy(this->greenPrimary, xy, sizeof(this->greenPrimary[0]) * 2); } inline void GenericHeader::BluePrimary(R32 xy[2]) const { memcpy(xy, this->bluePrimary, sizeof(xy[0]) * 2); } inline void GenericHeader::SetBluePrimary(const R32 xy[2]) { memcpy(this->bluePrimary, xy, sizeof(this->bluePrimary[0]) * 2); } inline void GenericHeader::SourceImageFileName(char *fn) const { ::strncpy(fn, this->sourceImageFileName, 100); fn[100] = '\0'; } inline void GenericHeader::SetSourceImageFileName(const char *fn) { ::strncpy(this->sourceImageFileName, fn, 100); } inline void GenericHeader::SourceDate(char *td) const { ::strncpy(td, this->sourceDate, 12); td[12] = '\0'; } inline void GenericHeader::SetSourceDate(const char *td) { ::strncpy(this->sourceDate, td, 12); } inline void GenericHeader::SourceTime(char *td) const { ::strncpy(td, this->sourceTime, 12); td[12] = '\0'; } inline void GenericHeader::SetSourceTime(const char *td) { ::strncpy(this->sourceTime, td, 12); } inline void GenericHeader::InputDevice(char *dev) const { ::strncpy(dev, this->inputDevice, 32); dev[32] = '\0'; } inline void GenericHeader::SetInputDevice(const char *dev) { ::strncpy(this->inputDevice, dev, 32); } inline void GenericHeader::InputDeviceModelNumber(char *sn) const { ::strncpy(sn, this->inputDeviceModelNumber, 32); sn[32] = '\0'; } inline void GenericHeader::SetInputDeviceModelNumber(const char *sn) { ::strncpy(this->inputDeviceModelNumber, sn, 32); } inline void GenericHeader::InputDeviceSerialNumber(char *sn) const { ::strncpy(sn, this->inputDeviceSerialNumber, 32); sn[32] = '\0'; } inline void GenericHeader::SetInputDeviceSerialNumber(const char *sn) { ::strncpy(this->inputDeviceSerialNumber, sn, 32); } inline R32 GenericHeader::XDevicePitch() const { return this->xDevicePitch; } inline void GenericHeader::SetXDevicePitch(const R32 size) { this->xDevicePitch = size; } inline R32 GenericHeader::YDevicePitch() const { return this->yDevicePitch; } inline void GenericHeader::SetYDevicePitch(const R32 size) { this->yDevicePitch = size; } inline void IndustryHeader::Format(char *fmt) const { ::strncpy(fmt, this->format, 32); fmt[32] = '\0'; } inline void IndustryHeader::SetFormat(const char *fmt) { ::strncpy(this->format, fmt, 32); } inline U32 IndustryHeader::FramePosition() const { return this->framePosition; } inline void IndustryHeader::SetFramePosition(const U32 pos) { this->framePosition = pos; } inline R32 IndustryHeader::FrameRate() const { return this->frameRate; } inline void IndustryHeader::SetFrameRate(const R32 rate) { this->frameRate = rate; } inline void IndustryHeader::FrameId(char *id) const { ::strncpy(id, this->frameId, 32); id[32] = '\0'; } inline void IndustryHeader::SetFrameId(const char *id) { ::strncpy(this->frameId, id, 32); } inline void IndustryHeader::SlateInfo(char *slate) const { ::strncpy(slate, this->slateInfo, 100); slate[100] = '\0'; } inline void IndustryHeader::SetSlateInfo(const char *slate) { ::strncpy(this->slateInfo, slate, 100); } inline R32 GenericHeader::Gamma() const { return this->gamma; } inline void GenericHeader::SetGamma(const R32 g) { this->gamma = g; } } #endif openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/OutStream.cpp0000644000175000017500000000501412271062644024365 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include "filesystem.h" #include "CineonStream.h" namespace cineon { OutStream::OutStream() : fp(0) { } OutStream::~OutStream() { } bool OutStream::Open(const char *f) { if (this->fp) this->Close(); if ((this->fp = OIIO::Filesystem::fopen(f, "wb")) == 0) return false; return true; } void OutStream::Close() { if (this->fp) { ::fclose(this->fp); this->fp = 0; } } size_t OutStream::Write(void *buf, const size_t size) { if (this->fp == 0) return false; return ::fwrite(buf, 1, size, this->fp); } bool OutStream::Seek(long offset, Origin origin) { int o = 0; switch (origin) { case kCurrent: o = SEEK_CUR; break; case kEnd: o = SEEK_END; break; case kStart: o = SEEK_SET; break; } if (this->fp == 0) return -1; return (::fseek(this->fp, offset, o) == 0); } void OutStream::Flush() { if (this->fp) ::fflush(this->fp); } } openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/ReaderInternal.h0000644000175000017500000003340612271062644025014 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _CINEON_READERINTERNAL_H #define _CINEON_READERINTERNAL_H 1 #include #include "BaseTypeConverter.h" #define PADDINGBITS_10BITFILLEDMETHODA 2 #define PADDINGBITS_10BITFILLEDMETHODB 0 #define MASK_10BITPACKED 0xffc0 #define MULTIPLIER_10BITPACKED 2 #define REMAIN_10BITPACKED 4 #define REVERSE_10BITPACKED 6 #define MASK_12BITPACKED 0xfff0 #define MULTIPLIER_12BITPACKED 4 #define REMAIN_12BITPACKED 2 #define REVERSE_12BITPACKED 4 namespace cineon { template bool Read10bitFilled(const Header &dpxHeader, U32 *readBuf, IR *fd, const Block &block, BUF *data) { // image height to read const int height = block.y2 - block.y1 + 1; // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.NumberOfElements(); // end of line padding int eolnPad = dpxHeader.EndOfLinePadding(); // number of datums in one row int datums = dpxHeader.Width() * numberOfComponents; // Line length in bytes rounded to 32 bits boundary int lineLength = ((datums - 1) / 3 + 1) * 4; // read in each line at a time directly into the user memory space for (int line = 0; line < height; line++) { // determine offset into image element int actline = line + block.y1; // first get line offset long offset = actline * lineLength; // add in eoln padding offset += line * eolnPad; // add in offset within the current line, rounding down so to catch any components within the word offset += block.x1 * numberOfComponents / 3 * 4; // get the read count in bytes, round to the 32-bit boundry int readSize = (block.x2 - block.x1 + 1) * numberOfComponents; readSize += readSize % 3; readSize = readSize / 3 * 4; // determine buffer offset int bufoff = line * dpxHeader.Width() * numberOfComponents; fd->Read(dpxHeader, offset, readBuf, readSize); // unpack the words in the buffer BUF *obuf = data + bufoff; int index = (block.x1 * sizeof(U32)) % numberOfComponents; for (int count = (block.x2 - block.x1 + 1) * numberOfComponents - 1; count >= 0; count--) { // unpacking the buffer backwords U16 d1 = U16(readBuf[(count + index) / 3] >> ((2 - (count + index) % 3) * 10 + PADDINGBITS) & 0x3ff); BaseTypeConvertU10ToU16(d1, d1); BaseTypeConverter(d1, obuf[count]); } } return true; } template bool Read10bitFilledMethodA(const Header &dpx, U32 *readBuf, IR *fd, const Block &block, BUF *data) { // padding bits for PackedMethodA is 2 return Read10bitFilled(dpx, readBuf, fd, block, data); } template bool Read10bitFilledMethodB(const Header &dpx, U32 *readBuf, IR *fd, const Block &block, BUF *data) { return Read10bitFilled(dpx, readBuf, fd, block, data); } // 10 bit, packed data // 12 bit, packed data template void UnPackPacked(U32 *readBuf, const int bitDepth, BUF *data, int count, int bufoff) { // unpack the words in the buffer BUF *obuf = data + bufoff; for (int i = count - 1; i >= 0; i--) { // unpacking the buffer backwords // find the byte that the data starts in, read in as a 16 bits then shift and mask // the pattern with byte offset is: // 10 bits datasize rotates every 4 data elements // element 0 -> 6 bit shift to normalize at MSB (10 LSB shifted 6 bits) // element 1 -> 4 bit shift to normalize at MSB // element 2 -> 2 bit shift to normalize at MSB // element 3 -> 0 bit shift to normalize at MSB // 10 bit algorithm: (6-((count % 4)*2)) // the pattern repeats every 160 bits // 12 bits datasize rotates every 2 data elements // element 0 -> 4 bit shift to normalize at MSB // element 1 -> 0 bit shift to normalize at MSB // 12 bit algorithm: (4-((count % 2)*4)) // the pattern repeats every 96 bits // first determine the word that the data element completely resides in U16 *d1 = reinterpret_cast(reinterpret_cast(readBuf)+((i * bitDepth) / 8 /*bits*/)); // place the component in the MSB and mask it for both 10-bit and 12-bit U16 d2 = (*d1 << (REVERSE - ((i % REMAIN) * MULTIPLIER))) & MASK; // For the 10/12 bit cases, specialize the 16-bit conversion by // repacking into the LSB and using a specialized conversion if(bitDepth == 10) { d2 = d2 >> REVERSE; BaseTypeConvertU10ToU16(d2, d2); } else if(bitDepth == 12) { d2 = d2 >> REVERSE; BaseTypeConvertU12ToU16(d2, d2); } BaseTypeConverter(d2, obuf[i]); } } template bool ReadPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const Block &block, BUF *data) { // image height to read const int height = block.y2 - block.y1 + 1; // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.NumberOfElements(); // end of line padding int eolnPad = dpxHeader.EndOfLinePadding(); // data size in bits // FIXME!!! const int dataSize = dpxHeader.BitDepth(0); // number of bytes const int lineSize = (dpxHeader.Width() * numberOfComponents * dataSize + 31) / 32; // read in each line at a time directly into the user memory space for (int line = 0; line < height; line++) { // determine offset into image element long offset = (line + block.y1) * (lineSize * sizeof(U32)) + (block.x1 * numberOfComponents * dataSize / 32 * sizeof(U32)) + (line * eolnPad); // calculate read size int readSize = ((block.x2 - block.x1 + 1) * numberOfComponents * dataSize); readSize += (block.x1 * numberOfComponents * dataSize % 32); // add the bits left over from the beginning of the line readSize = ((readSize + 31) / 32) * sizeof(U32); // calculate buffer offset int bufoff = line * dpxHeader.Width() * numberOfComponents; fd->Read(dpxHeader, offset, readBuf, readSize); // unpack the words in the buffer int count = (block.x2 - block.x1 + 1) * numberOfComponents; UnPackPacked(readBuf, dataSize, data, count, bufoff); } return true; } template bool Read10bitPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const Block &block, BUF *data) { return ReadPacked(dpxHeader, readBuf, fd, block, data); } template bool Read12bitPacked(const Header &dpxHeader, U32 *readBuf, IR *fd, const Block &block, BUF *data) { return ReadPacked(dpxHeader, readBuf, fd, block, data); } template bool ReadBlockTypes(const Header &dpxHeader, SRC *readBuf, IR *fd, const Block &block, BUF *data) { // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.NumberOfElements(); // byte count component type // FIXME!!! const int bytes = dpxHeader.ComponentByteCount(0); // image image/height to read const int width = (block.x2 - block.x1 + 1) * numberOfComponents; const int height = block.y2 - block.y1 + 1; // end of line padding int eolnPad = dpxHeader.EndOfLinePadding(); if (eolnPad == ~0) eolnPad = 0; // image width const int imageWidth = dpxHeader.Width(); // read in each line at a time directly into the user memory space for (int line = 0; line < height; line++) { // determine offset into image element long offset = (line + block.y1) * imageWidth * numberOfComponents * bytes + block.x1 * numberOfComponents * bytes + (line * eolnPad); if (BUFTYPE == SRCTYPE) { fd->ReadDirect(dpxHeader, offset, reinterpret_cast(data + (width*line)), width*bytes); } else { fd->Read(dpxHeader, offset, readBuf, width*bytes); // convert data for (int i = 0; i < width; i++) BaseTypeConverter(readBuf[i], data[width*line+i]); } } return true; } template bool Read12bitFilledMethodB(const Header &dpxHeader, U16 *readBuf, IR *fd, const Block &block, BUF *data) { // get the number of components for this element descriptor const int numberOfComponents = dpxHeader.NumberOfElements(); // image width & height to read const int width = (block.x2 - block.x1 + 1) * numberOfComponents; const int height = block.y2 - block.y1 + 1; // width of image const int imageWidth = dpxHeader.Width(); // end of line padding (not a required data element so check for ~0) int eolnPad = dpxHeader.EndOfLinePadding(); if (eolnPad == ~0) eolnPad = 0; // read in each line at a time directly into the user memory space for (int line = 0; line < height; line++) { // determine offset into image element long offset = (line + block.y1) * imageWidth * numberOfComponents * 2 + block.x1 * numberOfComponents * 2 + (line * eolnPad); fd->Read(dpxHeader, offset, readBuf, width*2); // convert data for (int i = 0; i < width; i++) { U16 d1 = readBuf[i] << 4; BaseTypeConverter(d1, data[width*line+i]); } } return true; } template bool ReadImageBlock(const Header &dpxHeader, U32 *readBuf, IR *fd, const Block &block, BUF *data) { // FIXME!!! const int bitDepth = dpxHeader.BitDepth(0); const DataSize size = dpxHeader.ComponentDataSize(0); const Packing packing = dpxHeader.ImagePacking(); if (bitDepth == 10) { if (packing == kLongWordLeft) return Read10bitFilledMethodA(dpxHeader, readBuf, fd, block, reinterpret_cast(data)); else if (packing == kLongWordRight) return Read10bitFilledMethodB(dpxHeader, readBuf, fd, block, reinterpret_cast(data)); else if (packing == kPacked) return Read10bitPacked(dpxHeader, readBuf, fd, block, reinterpret_cast(data)); } else if (bitDepth == 12) { if (packing == kPacked) return Read12bitPacked(dpxHeader, readBuf, fd, block, reinterpret_cast(data)); /*else if (packing == kFilledMethodB) // filled method B // 12 bits fill LSB of 16 bits return Read12bitFilledMethodB(dpxHeader, reinterpret_cast(readBuf), fd, block, reinterpret_cast(data)); else // filled method A // 12 bits fill MSB of 16 bits return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, block, reinterpret_cast(data));*/ } else if (size == cineon::kByte) return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, block, reinterpret_cast(data)); else if (size == cineon::kWord) return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, block, reinterpret_cast(data)); else if (size == cineon::kInt) return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, block, reinterpret_cast(data)); else if (size == cineon::kLongLong) return ReadBlockTypes(dpxHeader, reinterpret_cast(readBuf), fd, block, reinterpret_cast(data)); // should not reach here return false; } template bool ReadImageBlock(const Header &dpxHeader, U32 *readBuf, IR *fd, const Block &block, void *data, const DataSize size) { if (size == cineon::kByte) return ReadImageBlock(dpxHeader, readBuf, fd, block, reinterpret_cast(data)); else if (size == cineon::kWord) return ReadImageBlock(dpxHeader, readBuf, fd, block, reinterpret_cast(data)); else if (size == cineon::kInt) return ReadImageBlock(dpxHeader, readBuf, fd, block, reinterpret_cast(data)); else if (size == cineon::kLongLong) return ReadImageBlock(dpxHeader, readBuf, fd, block, reinterpret_cast(data)); // should not reach here return false; } } #endif openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/libcineon/Reader.cpp0000644000175000017500000001262412271062644023651 0ustar mfvmfv// -*- mode: C++; tab-width: 4 -*- // vi: ts=4 /* * Copyright (c) 2010, Patrick A. Palmer and Leszek Godlewski. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Patrick A. Palmer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "Cineon.h" #include "EndianSwap.h" #include "ReaderInternal.h" #include "ElementReadStream.h" #include "Codec.h" cineon::Reader::Reader() : fd(0), rio(0) { // initialize all of the Codec* to NULL this->codec = 0; } cineon::Reader::~Reader() { this->Reset(); } void cineon::Reader::Reset() { // delete all of the Codec * entries delete this->codec; this->codec = 0; // Element Reader if (this->rio) { delete rio; this->rio = 0; } if (this->fd) this->rio = new ElementReadStream(this->fd); } void cineon::Reader::SetInStream(InStream *fd) { this->fd = fd; this->Reset(); } bool cineon::Reader::ReadHeader() { return this->header.Read(this->fd); } bool cineon::Reader::ReadImage(void *data, const DataSize size) { Block block(0, 0, this->header.Width()-1, this->header.Height()-1); return this->ReadBlock(data, size, block); } /* implementation notes: cineon::readBlock reads in the image starting from the beginning of the channel. This can be optimized if the image isn't encoded; we can skip forward in the file to close to the start of (block.x1, block.y1) and determine exactly which bit will be the start. This certainly will save some time for cases where we are only reading ROIs (regions of interest). */ bool cineon::Reader::ReadBlock(void *data, const DataSize size, Block &block) { int i; // check the block coordinates block.Check(); // get the number of components for this element descriptor const int numberOfComponents = this->header.NumberOfElements(); // check the widths and bit depths of the image elements bool consistentDepth = true; bool consistentWidth = true; const int bitDepth = this->header.BitDepth(0); const int width = this->header.PixelsPerLine(0); for (i = 1; i < numberOfComponents; i++) { if (this->header.BitDepth(i) != bitDepth) { consistentDepth = false; if (!consistentWidth) break; } if ((int)this->header.PixelsPerLine(i) != width) { consistentWidth = false; if (!consistentDepth) break; } } // lets see if this can be done in a single fast read if (consistentDepth && consistentWidth && this->header.EndOfLinePadding() == 0 && ((bitDepth == 8 && size == cineon::kByte) || (bitDepth == 16 && size == cineon::kWord) || (bitDepth == 32 && size == cineon::kInt) || (bitDepth == 64 && size == cineon::kLongLong)) && block.x1 == 0 && block.x2 == (int)(this->header.Width()-1)) { // seek to the beginning of the image block if (this->fd->Seek((this->header.ImageOffset() + (block.y1 * this->header.Width() * (bitDepth / 8) * numberOfComponents)), InStream::kStart) == false) return false; // size of the image const size_t imageSize = this->header.Width() * (block.y2 - block.y1 + 1) * numberOfComponents; const size_t imageByteSize = imageSize * bitDepth / 8; size_t rs = this->fd->ReadDirect(data, imageByteSize); if (rs != imageByteSize) return false; // swap the bytes if different byte order if (this->header.RequiresByteSwap()) cineon::EndianSwapImageBuffer(size, data, imageSize); return true; } // determine if the encoding system is loaded if (this->codec == 0) // this element reader has not been used this->codec = new Codec; // read the image block return this->codec->Read(this->header, this->rio, block, data, size); } bool cineon::Reader::ReadUserData(unsigned char *data) { // check to make sure there is some user data if (this->header.UserSize() == 0) return true; // seek to the beginning of the user data block if (this->fd->Seek(sizeof(GenericHeader) + sizeof(IndustryHeader), InStream::kStart) == false) return false; size_t rs = this->fd->ReadDirect(data, this->header.UserSize()); if (rs != this->header.UserSize()) return false; return true; } openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/cineoninput.cpp0000644000175000017500000004057612271062644023047 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include "libcineon/Cineon.h" #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "fmath.h" #include "strutil.h" using namespace cineon; OIIO_PLUGIN_NAMESPACE_BEGIN class CineonInput : public ImageInput { public: CineonInput () : m_stream(NULL) { init(); } virtual ~CineonInput () { close(); } virtual const char * format_name (void) const { return "cineon"; } virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (); virtual bool read_native_scanline (int y, int z, void *data); private: InStream *m_stream; cineon::Reader m_cin; std::vector m_userBuf; /// Reset everything to initial state /// void init () { if (m_stream) { m_stream->Close (); delete m_stream; m_stream = NULL; } m_userBuf.clear (); } /// Helper function - retrieve string for libcineon descriptor /// char *get_descriptor_string (cineon::Descriptor c); }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *cineon_input_imageio_create () { return new CineonInput; } OIIO_EXPORT int cineon_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * cineon_input_extensions[] = { "cin", NULL }; OIIO_PLUGIN_EXPORTS_END bool CineonInput::open (const std::string &name, ImageSpec &newspec) { // open the image m_stream = new InStream(); if (! m_stream->Open(name.c_str())) { error ("Could not open file \"%s\"", name.c_str()); return false; } m_cin.SetInStream(m_stream); if (! m_cin.ReadHeader()) { error ("Could not read header"); return false; } // create imagespec TypeDesc typedesc; int maxbits = 0; for (int i = 0; i < m_cin.header.NumberOfElements (); i++) { if (maxbits < m_cin.header.BitDepth (i)) maxbits = m_cin.header.BitDepth (i); } switch ((maxbits + 7) / 8) { case 1: typedesc = TypeDesc::UINT8; break; case 2: typedesc = TypeDesc::UINT16; break; case 3: case 4: typedesc = TypeDesc::UINT32; break; default: error ("Unsupported bit depth %d", maxbits); return false; } m_spec = ImageSpec (m_cin.header.Width(), m_cin.header.Height(), m_cin.header.NumberOfElements (), typedesc); // fill channel names m_spec.channelnames.clear (); int gscount = 0, rcount = 0, gcount = 0, bcount = 0; char buf[3]; for (int i = 0; i < m_cin.header.NumberOfElements (); i++) { switch (m_cin.header.ImageDescriptor (i)) { case cineon::kGrayscale: if (++gscount > 1) { std::string ch = Strutil::format ("I%d", gscount); m_spec.channelnames.push_back (ch); } else m_spec.channelnames.push_back ("I"); break; case cineon::kPrintingDensityRed: case cineon::kRec709Red: if (++gscount > 1) { std::string ch = Strutil::format ("R%d", rcount); m_spec.channelnames.push_back (ch); } else m_spec.channelnames.push_back ("R"); break; case cineon::kPrintingDensityGreen: case cineon::kRec709Green: if (++gcount > 1) { std::string ch = Strutil::format ("G%d", gcount); m_spec.channelnames.push_back (ch); } else m_spec.channelnames.push_back ("G"); break; case cineon::kPrintingDensityBlue: case cineon::kRec709Blue: if (++bcount > 1) { std::string ch = Strutil::format ("B%d", bcount); m_spec.channelnames.push_back (ch); } else m_spec.channelnames.push_back ("B"); break; default: std::string ch = Strutil::format ("channel%d", (int)m_spec.channelnames.size()); m_spec.channelnames.push_back (ch); break; } } // bits per sample m_spec.attribute ("oiio:BitsPerSample", maxbits); // image orientation - see appendix B.2 of the OIIO documentation int orientation; switch (m_cin.header.ImageOrientation ()) { case cineon::kLeftToRightTopToBottom: orientation = 1; break; case cineon::kRightToLeftTopToBottom: orientation = 2; break; case cineon::kLeftToRightBottomToTop: orientation = 4; break; case cineon::kRightToLeftBottomToTop: orientation = 3; break; case cineon::kTopToBottomLeftToRight: orientation = 5; break; case cineon::kTopToBottomRightToLeft: orientation = 6; break; case cineon::kBottomToTopLeftToRight: orientation = 8; break; case cineon::kBottomToTopRightToLeft: orientation = 7; break; default: orientation = 0; break; } m_spec.attribute ("Orientation", orientation); // image linearity // FIXME: making this more robust would require the per-channel transfer // function functionality which isn't yet in OIIO switch (m_cin.header.ImageDescriptor (0)) { case cineon::kRec709Red: case cineon::kRec709Green: case cineon::kRec709Blue: m_spec.attribute ("oiio:ColorSpace", "Rec709"); default: // either grayscale or printing density if (!isinf (m_cin.header.Gamma ())) // actual gamma value is read later on m_spec.attribute ("oiio:ColorSpace", "GammaCorrected"); break; } // gamma exponent if (!isinf (m_cin.header.Gamma ())) m_spec.attribute ("oiio:Gamma", (float) m_cin.header.Gamma ()); // general metadata // some non-compliant writers will dump a field filled with 0xFF rather // than a NULL string termination on the first character, so take that // into account, too if (m_cin.header.creationDate[0] && m_cin.header.creationTime[0]) { // libcineon's date/time format is pretty close to OIIO's (libcineon // uses %Y:%m:%d:%H:%M:%S%Z) m_spec.attribute ("DateTime", Strutil::format ("%s %s", m_cin.header.creationDate, m_cin.header.creationTime)); // FIXME: do something about the time zone } // cineon-specific metadata char *strings[8]; int ints[8]; float floats[8]; // image descriptor for (int i = 0; i < m_cin.header.NumberOfElements (); i++) strings[i] = get_descriptor_string (m_cin.header.ImageDescriptor (i)); m_spec.attribute ("cineon:ImageDescriptor", TypeDesc (TypeDesc::STRING, m_cin.header.NumberOfElements ()), &strings); // save some typing by using macros // "internal" macros // per-file attribs #define CINEON_SET_ATTRIB_S(x, n, s) m_spec.attribute (s, \ m_cin.header.x (n)) #define CINEON_SET_ATTRIB(x, n) CINEON_SET_ATTRIB_S(x, n, \ "cineon:" #x) #define CINEON_SET_ATTRIB_BYTE(x) if (m_cin.header.x () != 0xFF) \ CINEON_SET_ATTRIB(x, ) #define CINEON_SET_ATTRIB_INT(x) if (static_cast \ (m_cin.header.x ()) \ != 0xFFFFFFFF) \ CINEON_SET_ATTRIB(x, ) #define CINEON_SET_ATTRIB_FLOAT(x) if (! isinf(m_cin.header.x ())) \ CINEON_SET_ATTRIB(x, ) #define CINEON_SET_ATTRIB_COORDS(x) m_cin.header.x (floats); \ if (!isinf (floats[0]) \ && !isinf (floats[1])) \ m_spec.attribute ("cineon:" #x, \ TypeDesc (TypeDesc::FLOAT, \ 2), &floats[0]) #define CINEON_SET_ATTRIB_STR(X, x) if (m_cin.header.x[0] \ && m_cin.header.x[0] != -1) \ m_spec.attribute ("cineon:" #X, \ m_cin.header.x) // per-element attribs #define CINEON_SET_ATTRIB_N(x, a, t, c) for (int i = 0; i < m_cin.header. \ NumberOfElements (); i++) { \ c(x) \ a[i] = m_cin.header.x (i); \ } \ m_spec.attribute ("cineon:" #x, \ TypeDesc (TypeDesc::t, \ m_cin.header.NumberOfElements()),\ &a) #define CINEON_CHECK_ATTRIB_FLOAT(x) if (!isinf (m_cin.header.x (i))) #define CINEON_SET_ATTRIB_FLOAT_N(x) CINEON_SET_ATTRIB_N(x, floats, \ FLOAT, CINEON_CHECK_ATTRIB_FLOAT) #define CINEON_CHECK_ATTRIB_INT(x) if (m_cin.header.x (i) != 0xFFFFFFFF) #define CINEON_SET_ATTRIB_INT_N(x) CINEON_SET_ATTRIB_N(x, ints, \ UINT32, CINEON_CHECK_ATTRIB_INT) #define CINEON_CHECK_ATTRIB_BYTE(x) if (m_cin.header.x (i) != 0xFF) #define CINEON_SET_ATTRIB_BYTE_N(x) CINEON_SET_ATTRIB_N(x, ints, \ UINT32, CINEON_CHECK_ATTRIB_BYTE) CINEON_SET_ATTRIB_STR(Version, version); // per-element data CINEON_SET_ATTRIB_BYTE_N(Metric); CINEON_SET_ATTRIB_BYTE_N(BitDepth); CINEON_SET_ATTRIB_INT_N(PixelsPerLine); CINEON_SET_ATTRIB_INT_N(LinesPerElement); CINEON_SET_ATTRIB_FLOAT_N(LowData); CINEON_SET_ATTRIB_FLOAT_N(LowQuantity); CINEON_SET_ATTRIB_FLOAT_N(HighData); CINEON_SET_ATTRIB_FLOAT_N(HighQuantity); CINEON_SET_ATTRIB_COORDS(WhitePoint); CINEON_SET_ATTRIB_COORDS(RedPrimary); CINEON_SET_ATTRIB_COORDS(GreenPrimary); CINEON_SET_ATTRIB_COORDS(BluePrimary); CINEON_SET_ATTRIB_STR(LabelText, labelText); CINEON_SET_ATTRIB_INT(XOffset); CINEON_SET_ATTRIB_INT(YOffset); CINEON_SET_ATTRIB_STR(SourceImageFileName, sourceImageFileName); CINEON_SET_ATTRIB_STR(InputDevice, inputDevice); CINEON_SET_ATTRIB_STR(InputDeviceModelNumber, inputDeviceModelNumber); CINEON_SET_ATTRIB_STR(InputDeviceSerialNumber, inputDeviceSerialNumber); CINEON_SET_ATTRIB_FLOAT(XDevicePitch); CINEON_SET_ATTRIB_FLOAT(YDevicePitch); CINEON_SET_ATTRIB_INT(FramePosition); CINEON_SET_ATTRIB_FLOAT(FrameRate); CINEON_SET_ATTRIB_STR(Format, format); CINEON_SET_ATTRIB_STR(FrameId, frameId); CINEON_SET_ATTRIB_STR(SlateInfo, slateInfo); #undef CINEON_SET_ATTRIB_BYTE_N #undef CINEON_CHECK_ATTRIB_BYTE #undef CINEON_SET_ATTRIB_INT_N #undef CINEON_CHECK_ATTRIB_INT #undef CINEON_SET_ATTRIB_FLOAT_N #undef CINEON_CHECK_ATTRIB_FLOAT #undef CINEON_SET_ATTRIB_N #undef CINEON_SET_ATTRIB_STR #undef CINEON_SET_ATTRIB_COORDS #undef CINEON_SET_ATTRIB_FLOAT #undef CINEON_SET_ATTRIB_INT #undef CINEON_SET_ATTRIB #undef CINEON_SET_ATTRIB_S std::string tmpstr; switch (m_cin.header.ImagePacking () & ~cineon::kPackAsManyAsPossible) { case cineon::kPacked: tmpstr = "Packed"; break; case cineon::kByteLeft: tmpstr = "8-bit boundary, left justified"; break; case cineon::kByteRight: tmpstr = "8-bit boundary, right justified"; break; case cineon::kWordLeft: tmpstr = "16-bit boundary, left justified"; break; case cineon::kWordRight: tmpstr = "16-bit boundary, right justified"; break; case cineon::kLongWordLeft: tmpstr = "32-bit boundary, left justified"; break; case cineon::kLongWordRight: tmpstr = "32-bit boundary, right justified"; break; } if (m_cin.header.ImagePacking () & cineon::kPackAsManyAsPossible) tmpstr += ", as many fields as possible per cell"; else tmpstr += ", at most one pixel per cell"; if (!tmpstr.empty ()) m_spec.attribute ("cineon:Packing", tmpstr); if (m_cin.header.sourceDate[0] && m_cin.header.sourceTime[0]) { // libcineon's date/time format is pretty close to OIIO's (libcineon // uses %Y:%m:%d:%H:%M:%S%Z) m_spec.attribute ("DateTime", Strutil::format ("%s %s", m_cin.header.sourceDate, m_cin.header.sourceTime)); // FIXME: do something about the time zone } m_cin.header.FilmEdgeCode(buf); if (buf[0]) m_spec.attribute ("cineon:FilmEdgeCode", buf); // read in user data if (m_cin.header.UserSize () != 0 && m_cin.header.UserSize () != 0xFFFFFFFF) { m_userBuf.resize (m_cin.header.UserSize ()); m_cin.ReadUserData (&m_userBuf[0]); } if (!m_userBuf.empty ()) m_spec.attribute ("cineon:UserData", TypeDesc (TypeDesc::UCHAR, m_cin.header.UserSize ()), &m_userBuf[0]); newspec = spec (); return true; } bool CineonInput::close () { init(); // Reset to initial state return true; } bool CineonInput::read_native_scanline (int y, int z, void *data) { cineon::Block block(0, y, m_cin.header.Width () - 1, y); // FIXME: un-hardcode the channel from 0 if (!m_cin.ReadBlock (data, m_cin.header.ComponentDataSize (0), block)) return false; return true; } char * CineonInput::get_descriptor_string (cineon::Descriptor c) { switch (c) { case cineon::kGrayscale: return (char *)"Grayscale"; case cineon::kPrintingDensityRed: return (char *)"Red, printing density"; case cineon::kRec709Red: return (char *)"Red, Rec709"; case cineon::kPrintingDensityGreen: return (char *)"Green, printing density"; case cineon::kRec709Green: return (char *)"Green, Rec709"; case cineon::kPrintingDensityBlue: return (char *)"Blue, printing density"; case cineon::kRec709Blue: return (char *)"Blue, Rec709"; //case cineon::kUndefinedDescriptor: default: return (char *)"Undefined"; } } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/cineon.imageio/CMakeLists.txt0000644000175000017500000000036612271062644022541 0ustar mfvmfvadd_oiio_plugin (cineoninput.cpp cineonoutput.cpp libcineon/Cineon.cpp libcineon/OutStream.cpp libcineon/Codec.cpp libcineon/Reader.cpp libcineon/Writer.cpp libcineon/CineonHeader.cpp libcineon/ElementReadStream.cpp libcineon/InStream.cpp) openimageio-1.3.12~dfsg0.orig/src/iconvert/0000755000175000017500000000000012271062644016741 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/iconvert/iconvert.cpp0000644000175000017500000005041312271062644021301 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include #include #include "argparse.h" #include "imageio.h" #include "sysutil.h" #include "filesystem.h" #include "imagecache.h" OIIO_NAMESPACE_USING; static std::string uninitialized = "uninitialized \001 HHRU dfvAS: efjl"; static std::string dataformatname = ""; static float gammaval = 1.0f; //static bool depth = false; static bool verbose = false; static int nthreads = 0; // default: use #cores threads if available static std::vector filenames; static int tile[3] = { 0, 0, 1 }; static bool scanline = false; //static bool zfile = false; //static std::string channellist; static std::string compression; static bool no_copy_image = false; static int quality = -1; static bool adjust_time = false; static std::string caption = uninitialized; static std::vector keywords; static bool clear_keywords = false; static std::vector attribnames, attribvals; static bool inplace = false; static int orientation = 0; static bool rotcw = false, rotccw = false, rot180 = false; static bool sRGB = false; static bool separate = false, contig = false; static bool noclobber = false; static int parse_files (int argc, const char *argv[]) { for (int i = 0; i < argc; i++) filenames.push_back (argv[i]); return 0; } static void getargs (int argc, char *argv[]) { bool help = false; ArgParse ap; ap.options ("iconvert -- copy images with format conversions and other alterations\n" OIIO_INTRO_STRING "\n" "Usage: iconvert [options] inputfile outputfile\n" " or: iconvert --inplace [options] file...\n", "%*", parse_files, "", "--help", &help, "Print help message", "-v", &verbose, "Verbose status messages", "--threads %d", &nthreads, "Number of threads (default 0 = #cores)", "-d %s", &dataformatname, "Set the output data format to one of:" "uint8, sint8, uint10, uint12, uint16, sint16, half, float, double", "-g %f", &gammaval, "Set gamma correction (default = 1)", "--tile %d %d", &tile[0], &tile[1], "Output as a tiled image", "--scanline", &scanline, "Output as a scanline image", "--compression %s", &compression, "Set the compression method (default = same as input)", "--quality %d", &quality, "Set the compression quality, 1-100", "--no-copy-image", &no_copy_image, "Do not use ImageOutput copy_image functionality (dbg)", "--adjust-time", &adjust_time, "Adjust file times to match DateTime metadata", "--caption %s", &caption, "Set caption (ImageDescription)", "--keyword %L", &keywords, "Add a keyword", "--clear-keywords", &clear_keywords, "Clear keywords", "--attrib %L %L", &attribnames, &attribvals, "Set a string attribute (name, value)", "--orientation %d", &orientation, "Set the orientation", "--rotcw", &rotcw, "Rotate 90 deg clockwise", "--rotccw", &rotccw, "Rotate 90 deg counter-clockwise", "--rot180", &rot180, "Rotate 180 deg", "--inplace", &inplace, "Do operations in place on images", "--sRGB", &sRGB, "This file is in sRGB color space", "--separate", &separate, "Force planarconfig separate", "--contig", &contig, "Force planarconfig contig", "--no-clobber", &noclobber, "Do no overwrite existing files", //FIXME "-z", &zfile, "Treat input as a depth file", //FIXME "-c %s", &channellist, "Restrict/shuffle channels", NULL); if (ap.parse(argc, (const char**)argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit (EXIT_FAILURE); } if (help) { ap.usage (); exit (EXIT_FAILURE); } if (filenames.size() != 2 && ! inplace) { std::cerr << "iconvert: Must have both an input and output filename specified.\n"; ap.usage(); exit (EXIT_FAILURE); } if (filenames.size() == 0 && inplace) { std::cerr << "iconvert: Must have at least one filename\n"; ap.usage(); exit (EXIT_FAILURE); } if (((int)rotcw + (int)rotccw + (int)rot180 + (orientation>0)) > 1) { std::cerr << "iconvert: more than one of --rotcw, --rotccw, --rot180, --orientation\n"; ap.usage(); exit (EXIT_FAILURE); } } static bool DateTime_to_time_t (const char *datetime, time_t &timet) { int year, month, day, hour, min, sec; int r = sscanf (datetime, "%d:%d:%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec); // printf ("%d %d:%d:%d %d:%d:%d\n", r, year, month, day, hour, min, sec); if (r != 6) return false; struct tm tmtime; time_t now; Sysutil::get_local_time (&now, &tmtime); // fill in defaults tmtime.tm_sec = sec; tmtime.tm_min = min; tmtime.tm_hour = hour; tmtime.tm_mday = day; tmtime.tm_mon = month-1; tmtime.tm_year = year-1900; timet = mktime (&tmtime); return true; } // Utility: split semicolon-separated list static void split_list (const std::string &list, std::vector &items) { typedef boost::tokenizer > tokenizer; boost::char_separator sep(";"); tokenizer tokens (list, sep); for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) { std::string t = *tok_iter; while (t.length() && t[0] == ' ') t.erase (t.begin()); if (t.length()) items.push_back (t); } } // Utility: join list into a single semicolon-separated string static std::string join_list (const std::vector &items) { std::string s; for (size_t i = 0; i < items.size(); ++i) { if (i > 0) s += "; "; s += items[i]; } return s; } // Adjust the output spec based on the command-line arguments. // Return whether the specifics preclude using copy_image. static bool adjust_spec (ImageInput *in, ImageOutput *out, const ImageSpec &inspec, ImageSpec &outspec) { bool nocopy = no_copy_image; // Copy the spec, with possible change in format outspec.set_format (inspec.format); if (inspec.channelformats.size()) { // Input file has mixed channels if (out->supports("channelformats")) { // Output supports mixed formats -- so request it outspec.set_format (TypeDesc::UNKNOWN); } else { // Input had mixed formats, output did not, so just use a fixed // format and forget the per-channel formats for output. outspec.channelformats.clear (); } } if (! dataformatname.empty()) { // make sure there isn't a stray BPS that will screw us up outspec.erase_attribute ("oiio:BitsPerSample"); if (dataformatname == "uint8") outspec.set_format (TypeDesc::UINT8); else if (dataformatname == "int8") outspec.set_format (TypeDesc::INT8); else if (dataformatname == "uint10") { outspec.attribute ("oiio:BitsPerSample", 10); outspec.set_format (TypeDesc::UINT16); } else if (dataformatname == "uint12") { outspec.attribute ("oiio:BitsPerSample", 12); outspec.set_format (TypeDesc::UINT16); } else if (dataformatname == "uint16") outspec.set_format (TypeDesc::UINT16); else if (dataformatname == "int16") outspec.set_format (TypeDesc::INT16); else if (dataformatname == "uint32" || dataformatname == "uint") outspec.set_format (TypeDesc::UINT32); else if (dataformatname == "int32" || dataformatname == "int") outspec.set_format (TypeDesc::INT32); else if (dataformatname == "half") outspec.set_format (TypeDesc::HALF); else if (dataformatname == "float") outspec.set_format (TypeDesc::FLOAT); else if (dataformatname == "double") outspec.set_format (TypeDesc::DOUBLE); outspec.channelformats.clear (); } if (outspec.format != inspec.format || inspec.channelformats.size()) nocopy = true; outspec.attribute ("oiio:Gamma", gammaval); if (sRGB) { outspec.attribute ("oiio:ColorSpace", "sRGB"); if (!strcmp (in->format_name(), "jpeg") || outspec.find_attribute ("Exif:ColorSpace")) outspec.attribute ("Exif:ColorSpace", 1); } if (tile[0]) { outspec.tile_width = tile[0]; outspec.tile_height = tile[1]; outspec.tile_depth = tile[2]; } if (scanline) { outspec.tile_width = 0; outspec.tile_height = 0; outspec.tile_depth = 0; } if (outspec.tile_width != inspec.tile_width || outspec.tile_height != inspec.tile_height || outspec.tile_depth != inspec.tile_depth) nocopy = true; if (! compression.empty()) { outspec.attribute ("compression", compression); if (compression != inspec.get_string_attribute ("compression")) nocopy = true; } if (quality > 0) { outspec.attribute ("CompressionQuality", quality); if (quality != inspec.get_int_attribute ("CompressionQuality")) nocopy = true; } if (contig) outspec.attribute ("planarconfig", "contig"); if (separate) outspec.attribute ("planarconfig", "separate"); if (orientation >= 1) outspec.attribute ("Orientation", orientation); else { orientation = outspec.get_int_attribute ("Orientation", 1); if (orientation >= 1 && orientation <= 8) { static int cw[] = { 0, 6, 7, 8, 5, 2, 3, 4, 1 }; if (rotcw || rotccw || rot180) orientation = cw[orientation]; if (rotccw || rot180) orientation = cw[orientation]; if (rotccw) orientation = cw[orientation]; outspec.attribute ("Orientation", orientation); } } if (caption != uninitialized) outspec.attribute ("ImageDescription", caption); if (clear_keywords) outspec.attribute ("Keywords", ""); if (keywords.size()) { std::string oldkw = outspec.get_string_attribute ("Keywords"); std::vector oldkwlist; if (! oldkw.empty()) split_list (oldkw, oldkwlist); BOOST_FOREACH (const std::string &nk, keywords) { bool dup = false; BOOST_FOREACH (const std::string &ok, oldkwlist) dup |= (ok == nk); if (! dup) oldkwlist.push_back (nk); } outspec.attribute ("Keywords", join_list (oldkwlist)); } for (size_t i = 0; i < attribnames.size(); ++i) { outspec.attribute (attribnames[i].c_str(), attribvals[i].c_str()); } return nocopy; } static bool convert_file (const std::string &in_filename, const std::string &out_filename) { if (noclobber && Filesystem::exists(out_filename)) { std::cerr << "iconvert ERROR: Output file already exists \"" << out_filename << "\"\n"; return false; } if (verbose) std::cout << "Converting " << in_filename << " to " << out_filename << "\n"; std::string tempname = out_filename; if (tempname == in_filename) { tempname = out_filename + ".tmp" + Filesystem::extension (out_filename); } // Find an ImageIO plugin that can open the input file, and open it. ImageInput *in = ImageInput::open (in_filename.c_str()); if (! in) { std::string err = geterror(); std::cerr << "iconvert ERROR: " << (err.length() ? err : Strutil::format("Could not open \"%s\"", in_filename)) << "\n"; delete in; return false; } ImageSpec inspec = in->spec(); std::string metadatatime = inspec.get_string_attribute ("DateTime"); // Find an ImageIO plugin that can open the output file, and open it ImageOutput *out = ImageOutput::create (tempname.c_str()); if (! out) { std::cerr << "iconvert ERROR: Could not find an ImageIO plugin to write \"" << out_filename << "\" :" << geterror() << "\n"; delete in; return false; } // In order to deal with formats that support subimages, but not // subimage appending, we gather them all first. std::vector subimagespecs; if (out->supports("multiimage") && !out->supports("appendsubimage")) { ImageCache *imagecache = ImageCache::create (); int nsubimages = 0; ustring ufilename (in_filename); imagecache->get_image_info (ufilename, ustring("subimages"), TypeDesc::TypeInt, &nsubimages); if (nsubimages > 1) { subimagespecs.resize (nsubimages); for (int i = 0; i < nsubimages; ++i) { ImageSpec inspec = *imagecache->imagespec (ufilename, i, 0, true /*native*/); subimagespecs[i] = inspec; adjust_spec (in, out, inspec, subimagespecs[i]); } } ImageCache::destroy (imagecache); } bool ok = true; bool mip_to_subimage_warning = false; for (int subimage = 0; ok && in->seek_subimage(subimage,0,inspec); ++subimage) { if (subimage > 0 && !out->supports ("multiimage")) { std::cerr << "iconvert WARNING: " << out->format_name() << " does not support multiple subimages.\n"; std::cerr << "\tOnly the first subimage has been copied.\n"; break; // we're done } int miplevel = 0; do { // Copy the spec, with possible change in format ImageSpec outspec = inspec; bool nocopy = adjust_spec (in, out, inspec, outspec); if (miplevel > 0) { // Moving to next MIP level ImageOutput::OpenMode mode; if (out->supports ("mipmap")) mode = ImageOutput::AppendMIPLevel; else if (out->supports ("multiimage") && out->supports ("appendsubimage")) { mode = ImageOutput::AppendSubimage; // use if we must if (! mip_to_subimage_warning && strcmp(out->format_name(),"tiff")) { std::cerr << "iconvert WARNING: " << out->format_name() << " does not support MIPmaps.\n"; std::cerr << "\tStoring the MIPmap levels in subimages.\n"; } mip_to_subimage_warning = true; } else { std::cerr << "iconvert WARNING: " << out->format_name() << " does not support MIPmaps.\n"; std::cerr << "\tOnly the first level has been copied.\n"; break; // on to the next subimage } ok = out->open (tempname.c_str(), outspec, mode); } else if (subimage > 0) { // Moving to next subimage ok = out->open (tempname.c_str(), outspec, ImageOutput::AppendSubimage); } else { // First time opening if (subimagespecs.size()) ok = out->open (tempname.c_str(), int(subimagespecs.size()), &subimagespecs[0]); else ok = out->open (tempname.c_str(), outspec, ImageOutput::Create); } if (! ok) { std::string err = out->geterror(); std::cerr << "iconvert ERROR: " << (err.length() ? err : Strutil::format("Could not open \"%s\"", out_filename)) << "\n"; ok = false; break; } if (! nocopy) { ok = out->copy_image (in); if (! ok) std::cerr << "iconvert ERROR copying \"" << in_filename << "\" to \"" << out_filename << "\" :\n\t" << out->geterror() << "\n"; } else { // Need to do it by hand for some reason. Future expansion in which // only a subset of channels are copied, or some such. std::vector pixels ((size_t)outspec.image_bytes(true)); ok = in->read_image (outspec.format, &pixels[0]); if (! ok) { std::cerr << "iconvert ERROR reading \"" << in_filename << "\" : " << in->geterror() << "\n"; } else { ok = out->write_image (outspec.format, &pixels[0]); if (! ok) std::cerr << "iconvert ERROR writing \"" << out_filename << "\" : " << out->geterror() << "\n"; } } ++miplevel; } while (ok && in->seek_subimage(subimage,miplevel,inspec)); } out->close (); delete out; in->close (); delete in; // Figure out a time for the input file -- either one supplied by // the metadata, or the actual time stamp of the input file. std::time_t in_time; if (metadatatime.empty() || ! DateTime_to_time_t (metadatatime.c_str(), in_time)) in_time = Filesystem::last_write_time (in_filename); if (out_filename != tempname) { if (ok) { boost::filesystem::remove (out_filename); boost::filesystem::rename (tempname, out_filename); } else boost::filesystem::remove (tempname); } // If user requested, try to adjust the file's modification time to // the creation time indicated by the file's DateTime metadata. if (ok && adjust_time) Filesystem::last_write_time (out_filename, in_time); return ok; } int main (int argc, char *argv[]) { Filesystem::convert_native_arguments (argc, (const char **)argv); getargs (argc, argv); OIIO::attribute ("threads", nthreads); bool ok = true; if (inplace) { BOOST_FOREACH (const std::string &s, filenames) ok &= convert_file (s, s); } else { ok = convert_file (filenames[0], filenames[1]); } return ok ? EXIT_SUCCESS : EXIT_FAILURE; } openimageio-1.3.12~dfsg0.orig/src/iconvert/CMakeLists.txt0000644000175000017500000000042012271062644021475 0ustar mfvmfvset (iconvert_srcs iconvert.cpp) add_executable (iconvert ${iconvert_srcs}) set_target_properties (iconvert PROPERTIES FOLDER "Tools") link_ilmbase (iconvert) target_link_libraries (iconvert OpenImageIO ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) oiio_install_targets (iconvert) openimageio-1.3.12~dfsg0.orig/src/rla.imageio/0000755000175000017500000000000012271062644017277 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/rla.imageio/rlainput.cpp0000644000175000017500000006217612271062644021655 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "filesystem.h" #include "fmath.h" #include "rla_pvt.h" OIIO_PLUGIN_NAMESPACE_BEGIN using namespace RLA_pvt; class RLAInput : public ImageInput { public: RLAInput () { init(); } virtual ~RLAInput () { close(); } virtual const char * format_name (void) const { return "rla"; } virtual bool open (const std::string &name, ImageSpec &newspec); virtual int current_subimage (void) const { return m_subimage; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual bool close (); virtual bool read_native_scanline (int y, int z, void *data); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle RLAHeader m_rla; ///< Wavefront RLA header std::vector m_buf; ///< Buffer the image pixels int m_subimage; ///< Current subimage index std::vector m_sot; ///< Scanline offsets table int m_stride; ///< Number of bytes a contig pixel takes /// Reset everything to initial state /// void init () { m_file = NULL; m_buf.clear (); } /// Helper: raw read, with error detection /// bool fread (void *buf, size_t itemsize, size_t nitems) { size_t n = ::fread (buf, itemsize, nitems, m_file); if (n != nitems) error ("Read error: read %d records but %d expected %s", (int)n, (int)nitems, feof(m_file) ? " (hit EOF)" : ""); return n == nitems; } /// Helper: read buf[0..nitems-1], swap endianness if necessary template bool read (T *buf, size_t nitems=1) { if (! fread (buf, sizeof(T), nitems)) return false; if (littleendian() && (is_same::value || is_same::value || is_same::value || is_same::value)) { swap_endian (buf, nitems); } return true; } /// Helper function: translate 3-letter month abbreviation to number. /// inline int get_month_number (const char *s); /// Helper: read the RLA header and scanline offset table. /// inline bool read_header (); /// Helper: read and decode a single channel group consisting of /// channels [first_channel .. first_channel+num_channels-1], which /// all share the same number of significant bits. bool decode_channel_group (int first_channel, short num_channels, short num_bits, int y); /// Helper: decode a span of n RLE-encoded bytes from encoded[0..elen-1] /// into buf[0],buf[stride],buf[2*stride]...buf[(n-1)*stride]. /// Return the number of encoded bytes we ate to fill buf. size_t decode_rle_span (unsigned char *buf, int n, int stride, const char *encoded, size_t elen); /// Helper: determine channel TypeDesc inline TypeDesc get_channel_typedesc (short chan_type, short chan_bits); // debugging aid void preview (std::ostream &out) { ASSERT (!feof(m_file)); long pos = ftell (m_file); out << "@" << pos << ", next 4 bytes are "; union { // trickery to avoid punned pointer warnings unsigned char c[4]; uint16_t s[2]; uint32_t i; } u; read (&u.c, 4); // because it's char, it didn't swap endian uint16_t s[2] = { u.s[0], u.s[1] }; uint32_t i = u.i; if (littleendian()) { swap_endian (s, 2); swap_endian (&i); } out << Strutil::format ("%d/%u %d/%u %d/%u %d/%u (%d %d) (%u)\n", u.c[0], ((char *)u.c)[0], u.c[1], ((char *)u.c)[1], u.c[2], ((char *)u.c)[2], u.c[3], ((char *)u.c)[3], s[0], s[1], i); fseek (m_file, pos, SEEK_SET); } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput *rla_input_imageio_create () { return new RLAInput; } OIIO_EXPORT int rla_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * rla_input_extensions[] = { "rla", NULL }; OIIO_PLUGIN_EXPORTS_END bool RLAInput::open (const std::string &name, ImageSpec &newspec) { m_filename = name; m_file = Filesystem::fopen (name, "rb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } // set a bogus subimage index so that seek_subimage actually seeks m_subimage = 1; return seek_subimage (0, 0, newspec); } inline bool RLAInput::read_header () { // Read the image header, which should have the same exact layout as // the m_rla structure (except for endianness issues). ASSERT (sizeof(m_rla) == 740 && "Bad RLA struct size"); if (! read (&m_rla)) { error ("RLA could not read the image header"); return false; } m_rla.rla_swap_endian (); // fix endianness if (m_rla.Revision != (int16_t)0xFFFE && m_rla.Revision != 0 /* for some reason, this can happen */) { error ("RLA header Revision number unrecognized: %d", m_rla.Revision); return false; // unknown file revision } if (m_rla.NumOfChannelBits == 0) m_rla.NumOfChannelBits = 8; // apparently, this can happen // Immediately following the header is the scanline offset table -- // one uint32_t for each scanline, giving absolute offsets (from the // beginning of the file) where the RLE records start for each // scanline of this subimage. m_sot.resize (std::abs (m_rla.ActiveBottom - m_rla.ActiveTop) + 1, 0); if (! read (&m_sot[0], m_sot.size())) { error ("RLA could not read the scanline offset table"); return false; } return true; } bool RLAInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (miplevel != 0 || subimage < 0) return false; if (subimage == current_subimage()) return true; // already on the right level // RLA images allow multiple subimages; they are simply concatenated // together, wth image N's header field NextOffset giving the // absolute offset of the start of image N+1. int diff = subimage - current_subimage (); if (subimage - current_subimage () < 0) { // If we are requesting an image earlier than the current one, // reset to the first subimage. fseek (m_file, 0, SEEK_SET); if (!read_header ()) return false; // read_header always calls error() diff = subimage; } // forward scrolling -- skip subimages until we're at the right place while (diff > 0 && m_rla.NextOffset != 0) { fseek (m_file, m_rla.NextOffset, SEEK_SET); if (!read_header ()) return false; // read_header always calls error() --diff; } if (diff > 0 && m_rla.NextOffset == 0) { // no more subimages to read error ("Unknown subimage"); return false; } // Now m_rla holds the header of the requested subimage. Examine it // to fill out our ImageSpec. if (m_rla.ColorChannelType > CT_FLOAT) { error ("Illegal color channel type: %d", m_rla.ColorChannelType); return false; } if (m_rla.MatteChannelType > CT_FLOAT) { error ("Illegal matte channel type: %d", m_rla.MatteChannelType); return false; } if (m_rla.AuxChannelType > CT_FLOAT) { error ("Illegal auxiliary channel type: %d", m_rla.AuxChannelType); return false; } // pick maximum precision for the time being int maxbytes = (std::max (m_rla.NumOfChannelBits * (m_rla.NumOfColorChannels > 0 ? 1 : 0), std::max (m_rla.NumOfMatteBits * (m_rla.NumOfMatteChannels > 0 ? 1 : 0), m_rla.NumOfAuxBits * (m_rla.NumOfAuxChannels > 0 ? 1 : 0))) + 7) / 8; int nchannels = m_rla.NumOfColorChannels + m_rla.NumOfMatteChannels + m_rla.NumOfAuxChannels; TypeDesc maxtype = (maxbytes == 4) ? TypeDesc::UINT32 : (maxbytes == 2 ? TypeDesc::UINT16 : TypeDesc::UINT8); if (nchannels < 1 || nchannels > 16 || (maxbytes != 1 && maxbytes != 2 && maxbytes != 4)) { error ("Failed channel bytes sanity check"); return false; // failed sanity check } m_spec = ImageSpec (m_rla.ActiveRight - m_rla.ActiveLeft + 1, (m_rla.ActiveTop - m_rla.ActiveBottom + 1) / (m_rla.FieldRendered ? 2 : 1), // interlaced image? m_rla.NumOfColorChannels + m_rla.NumOfMatteChannels + m_rla.NumOfAuxChannels, maxtype); // set window dimensions etc. m_spec.x = m_rla.ActiveLeft; m_spec.y = m_spec.height - m_rla.ActiveTop - 1; m_spec.full_width = m_rla.WindowRight - m_rla.WindowLeft + 1; m_spec.full_height = m_rla.WindowTop - m_rla.WindowBottom + 1; m_spec.full_depth = 1; m_spec.full_x = m_rla.WindowLeft; m_spec.full_y = m_spec.full_height - m_rla.WindowTop - 1; // set channel formats and stride int z_channel = -1; m_stride = 0; TypeDesc t = get_channel_typedesc (m_rla.ColorChannelType, m_rla.NumOfChannelBits); for (int i = 0; i < m_rla.NumOfColorChannels; ++i) m_spec.channelformats.push_back (t); m_stride += m_rla.NumOfColorChannels * t.size (); t = get_channel_typedesc (m_rla.MatteChannelType, m_rla.NumOfMatteBits); for (int i = 0; i < m_rla.NumOfMatteChannels; ++i) m_spec.channelformats.push_back (t); m_stride += m_rla.NumOfMatteChannels * t.size (); t = get_channel_typedesc (m_rla.AuxChannelType, m_rla.NumOfAuxBits); for (int i = 0; i < m_rla.NumOfAuxChannels; ++i) { m_spec.channelformats.push_back (t); // assume first float aux or 32 bit int channel is z if (z_channel < 0 && (t == TypeDesc::FLOAT || t == TypeDesc::INT32 || t == TypeDesc::UINT32)) z_channel = m_rla.NumOfColorChannels + m_rla.NumOfMatteChannels; } m_stride += m_rla.NumOfAuxChannels * t.size (); // But if all channels turned out the same, just use 'format' and don't // bother sending back channelformats at all. bool allsame = true; for (int c = 1; c < m_spec.nchannels; ++c) allsame &= (m_spec.channelformats[c] == m_spec.channelformats[0]); if (allsame) { m_spec.format = m_spec.channelformats[0]; m_spec.channelformats.clear(); m_spec.attribute ("oiio:BitsPerSample", m_rla.NumOfChannelBits); // N.B. don't set bps for mixed formats, it isn't well defined } // make a guess at channel names for the time being m_spec.default_channel_names (); if (z_channel >= 0) { m_spec.z_channel = z_channel; m_spec.channelnames[z_channel] = "Z"; } // this is always true m_spec.attribute ("compression", "rle"); if (m_rla.DateCreated[0]) { char month[4] = {0, 0, 0, 0}; int d, h, M, m, y; if (sscanf (m_rla.DateCreated, "%c%c%c %d %d:%d %d", month + 0, month + 1, month + 2, &d, &h, &m, &y) == 7) { M = get_month_number (month); if (M > 0) { // construct a date/time marker in OIIO convention m_spec.attribute ("DateTime", Strutil::format("%4d:%02d:%02d %02d:%02d:00", y, M, d, h, m)); } } } // save some typing by using macros #define FIELD(x,name) if (m_rla.x > 0) \ m_spec.attribute (name, m_rla.x) #define STRING_FIELD(x,name) if (m_rla.x[0]) \ m_spec.attribute (name, m_rla.x) STRING_FIELD (Description, "ImageDescription"); FIELD (FrameNumber, "rla:FrameNumber"); FIELD (Revision, "rla:Revision"); FIELD (JobNumber, "rla:JobNumber"); FIELD (FieldRendered, "rla:FieldRendered"); STRING_FIELD (FileName, "rla:FileName"); STRING_FIELD (ProgramName, "Software"); STRING_FIELD (MachineName, "HostComputer"); STRING_FIELD (UserName, "Artist"); STRING_FIELD (Aspect, "rla:Aspect"); STRING_FIELD (ColorChannel, "rla:ColorChannel"); STRING_FIELD (Time, "rla:Time"); STRING_FIELD (Filter, "rla:Filter"); STRING_FIELD (AuxData, "rla:AuxData"); #undef STRING_FIELD #undef FIELD float f[3]; // variable will be reused for chroma, thus the array f[0] = atof (m_rla.Gamma); if (f[0] > 0.f) { if (f[0] == 1.f) m_spec.attribute ("oiio:ColorSpace", "Linear"); else { m_spec.attribute ("oiio:ColorSpace", "GammaCorrected"); m_spec.attribute ("oiio:Gamma", f[0]); } } f[0] = atof (m_rla.AspectRatio); if (f[0] > 0.f) m_spec.attribute ("PixelAspectRatio", f[0]); // read chromaticity points if (m_rla.RedChroma[0]) { int num = sscanf(m_rla.RedChroma, "%f %f %f", f + 0, f + 1, f + 2); if (num >= 2) m_spec.attribute ("rla:RedChroma", TypeDesc(TypeDesc::FLOAT, num == 2 ? TypeDesc::VEC2 : TypeDesc::VEC3, TypeDesc::POINT), f); } if (m_rla.GreenChroma[0]) { int num = sscanf(m_rla.GreenChroma, "%f %f %f", f + 0, f + 1, f + 2); if (num >= 2) m_spec.attribute ("rla:GreenChroma", TypeDesc(TypeDesc::FLOAT, num == 2 ? TypeDesc::VEC2 : TypeDesc::VEC3, TypeDesc::POINT), f); } if (m_rla.BlueChroma[0]) { int num = sscanf(m_rla.BlueChroma, "%f %f %f", f + 0, f + 1, f + 2); if (num >= 2) m_spec.attribute ("rla:BlueChroma", TypeDesc(TypeDesc::FLOAT, num == 2 ? TypeDesc::VEC2 : TypeDesc::VEC3, TypeDesc::POINT), f); } if (m_rla.WhitePoint[0]) { int num = sscanf(m_rla.WhitePoint, "%f %f %f", f + 0, f + 1, f + 2); if (num >= 2) m_spec.attribute ("rla:WhitePoint", TypeDesc(TypeDesc::FLOAT, num == 2 ? TypeDesc::VEC2 : TypeDesc::VEC3, TypeDesc::POINT), f); } newspec = spec (); m_subimage = subimage; // N.B. the file pointer is now immediately after the scanline // offset table for this subimage. return true; } bool RLAInput::close () { if (m_file) { fclose (m_file); m_file = NULL; } init(); // Reset to initial state return true; } size_t RLAInput::decode_rle_span (unsigned char *buf, int n, int stride, const char *encoded, size_t elen) { size_t e = 0; while (n > 0 && e < elen) { char count = encoded[e++]; if (count >= 0) { // run count positive: value repeated count+1 times for (int i = 0; i <= count && n; ++i, buf += stride, --n) *buf = encoded[e]; ++e; } else { // run count negative: repeat bytes literally count = -count; // make it positive for ( ; count && n > 0 && e < elen; --count, buf += stride, --n) *buf = encoded[e++]; } } if (n != 0) { error ("Read error: malformed RLE record"); return 0; } return e; } bool RLAInput::decode_channel_group (int first_channel, short num_channels, short num_bits, int y) { // Some preliminaries -- figure out various sizes and offsets int chsize; // size of the channels in this group, in bytes int offset; // buffer offset to first channel int pixelsize; // spacing between pixels (in bytes) in the output TypeDesc chantype; // data type for the channel if (! m_spec.channelformats.size()) { // No per-channel formats, they are all the same, so it's easy chantype = m_spec.format; chsize = chantype.size (); offset = first_channel * chsize; pixelsize = chsize * m_spec.nchannels; } else { // Per-channel formats differ, need to sum them up chantype = m_spec.channelformats[first_channel]; chsize = chantype.size (); offset = 0; pixelsize = m_spec.pixel_bytes (true); for (int i = 0; i < first_channel; ++i) offset += m_spec.channelformats[i].size (); } // Read the big-endian values into the buffer. // The channels are simply contatenated together in order. // Each channel starts with a length, from which we know how many // bytes of encoded RLE data to read. Then there are RLE // spans for each 8-bit slice of the channel. std::vector encoded; for (int c = 0; c < num_channels; ++c) { // Read the length uint16_t length; // number of encoded bytes if (!read (&length)) { error ("Read error: couldn't read RLE record length"); return false; } // Read the encoded RLE record encoded.resize (length); if (!read (&encoded[0], length)) { error ("Read error: couldn't read RLE data span"); return false; } if (chantype == TypeDesc::FLOAT) { // Special case -- float data is just dumped raw, no RLE for (int x = 0; x < m_spec.width; ++x) *((float *)&m_buf[offset+c*chsize+x*pixelsize]) = ((float *)&encoded[0])[x]; continue; } // Decode RLE -- one pass for each significant byte of the file, // which we re-interleave properly by passing the right offsets // and strides to decode_rle_span. size_t eoffset = 0; for (int bytes = 0; bytes < chsize; ++bytes) { size_t e = decode_rle_span (&m_buf[offset+c*chsize+bytes], m_spec.width, pixelsize, &encoded[eoffset], length); if (! e) return false; eoffset += e; } } // If we're little endian, swap endianness in place for 2- and // 4-byte pixel data. if (littleendian()) { if (chsize == 2) { if (num_channels == m_spec.nchannels) swap_endian ((uint16_t *)&m_buf[0], num_channels*m_spec.width); else for (int x = 0; x < m_spec.width; ++x) swap_endian ((uint16_t *)&m_buf[offset+x*pixelsize], num_channels); } else if (chsize == 4 && chantype != TypeDesc::FLOAT) { if (num_channels == m_spec.nchannels) swap_endian ((uint32_t *)&m_buf[0], num_channels*m_spec.width); else for (int x = 0; x < m_spec.width; ++x) swap_endian ((uint32_t *)&m_buf[offset+x*pixelsize], num_channels); } } // If not 8*2^n bits, need to rescale. For example, if num_bits is // 10, the data values run 0-1023, but are stored in uint16. So we // now rescale to the full range of the output buffer range, per // OIIO conventions. if (num_bits == 8 || num_bits == 16 || num_bits == 32) { // ok -- no rescaling needed } else if (num_bits == 10) { // fast, common case -- use templated hard-code for (int x = 0; x < m_spec.width; ++x) { uint16_t *b = (uint16_t *)(&m_buf[offset+x*pixelsize]); for (int c = 0; c < num_channels; ++c) b[c] = bit_range_convert<10,16> (b[c]); } } else if (num_bits < 8) { // rare case, use slow code to make this clause short and simple for (int x = 0; x < m_spec.width; ++x) { uint8_t *b = (uint8_t *)&m_buf[offset+x*pixelsize]; for (int c = 0; c < num_channels; ++c) b[c] = bit_range_convert (b[c], num_bits, 8); } } else if (num_bits > 8 && num_bits < 16) { // rare case, use slow code to make this clause short and simple for (int x = 0; x < m_spec.width; ++x) { uint16_t *b = (uint16_t *)&m_buf[offset+x*pixelsize]; for (int c = 0; c < num_channels; ++c) b[c] = bit_range_convert (b[c], num_bits, 16); } } else if (num_bits > 16 && num_bits < 32) { // rare case, use slow code to make this clause short and simple for (int x = 0; x < m_spec.width; ++x) { uint32_t *b = (uint32_t *)&m_buf[offset+x*pixelsize]; for (int c = 0; c < num_channels; ++c) b[c] = bit_range_convert (b[c], num_bits, 32); } } return true; } bool RLAInput::read_native_scanline (int y, int z, void *data) { // By convention, RLA images store their images bottom-to-top. y = m_spec.height - y - 1; // Seek to scanline start, based on the scanline offset table fseek (m_file, m_sot[y], SEEK_SET); // Now decode and interleave the channels. // The channels are non-interleaved (i.e. rrrrrgggggbbbbb...). // Color first, then matte, then auxiliary channels. We can't // decode all in one shot, though, because the data type and number // of significant bits may be may be different for each class of // channels, so we deal with them separately and interleave into // our buffer as we go. size_t size = m_spec.scanline_bytes(true); m_buf.resize (size); if (m_rla.NumOfColorChannels > 0) if (!decode_channel_group(0, m_rla.NumOfColorChannels, m_rla.NumOfChannelBits, y)) return false; if (m_rla.NumOfMatteChannels > 0) if (!decode_channel_group(m_rla.NumOfColorChannels, m_rla.NumOfMatteChannels, m_rla.NumOfMatteBits, y)) return false; if (m_rla.NumOfAuxChannels > 0) if (!decode_channel_group(m_rla.NumOfColorChannels + m_rla.NumOfMatteChannels, m_rla.NumOfAuxChannels, m_rla.NumOfAuxBits, y)) return false; memcpy (data, &m_buf[0], size); return true; } inline int RLAInput::get_month_number (const char *s) { static const char *months[] = { "", "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" }; for (int i = 1; i <= 12; ++i) if (Strutil::iequals (s, months[i])) return i; return -1; } inline TypeDesc RLAInput::get_channel_typedesc (short chan_type, short chan_bits) { switch (chan_type) { case CT_BYTE: // some non-spec-compliant images > 8bpc will have it set to // byte anyway, so try guessing by bit depth instead if (chan_bits > 8) { switch ((chan_bits + 7) / 8) { case 2: return TypeDesc::UINT16; case 3: case 4: return TypeDesc::UINT32; default: ASSERT(!"Invalid colour channel type"); } } else return TypeDesc::UINT8; case CT_WORD: return TypeDesc::UINT16; case CT_DWORD: return TypeDesc::UINT32; case CT_FLOAT: return TypeDesc::FLOAT; default: ASSERT(!"Invalid colour channel type"); } // shut up compiler return TypeDesc::UINT8; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/rla.imageio/rla_pvt.h0000644000175000017500000001756512271062644021135 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #ifndef OPENIMAGEIO_RLA_PVT_H #define OPENIMAGEIO_RLA_PVT_H /* Brief documentation about the RLA format: * The file consists of multiple subimages, merely contatenated together. Each subimage starts with a RLAHeader, and within the header is a NextOffset field that gives the absolute offset (relative to the start of the file) of the beginning of the next subimage, or 0 if there is no next subimage. * Immediately following the header is the scanline offset table, which is one uint32 for each scanline, giving the absolute offset for the beginning of that scanline record. By convention, RLA scanline 0 is displayed at the bottom of the image (the opposite of OIIO convention). * Each scanline consists of up to three channel groups, concatenated together: color, then matte, then auxiliary. Each group may have a different data type and bit depth. * A channel group consists of its channels (separate, non-interleaved) concatenated together. * A channel is stored in an RLE record, which consists of a uint16 given the length of encoded data, then the encoded data run. * The encoded data run consists of a signed "count" byte. If the count >= 0, the next byte is the pixel value, which is be repeated count+1 times as output. If count < 0, then the next abs(count) bytes should be copied directly to as output. * For SHORT (16 bit), LONG (32 bit), or FLOAT pixel data types, the most significant 8 bits of each pixel come first, then the next less significant 8 bits, and so on. For example, for 16 bit data (HL), the sequence will be H0 H1 H2 ... L0 L1 L2 ... Therefore, the bytes will need to be re-interleaved to form contiguous 16 or 32 bit values in the output buffer. * But float data is not RLE compressed, instead just dumped raw after the RLE length. Well, at least according to old code at SPI. We have no original RLA specification that stipulates this to be the case. * RLA files are "big endian" for all 16 and 32 bit data: header fields, offsets, and pixel data. */ OIIO_PLUGIN_NAMESPACE_BEGIN namespace RLA_pvt { // code below adapted from // http://www.fileformat.info/format/wavefrontrla/egff.htm struct RLAHeader { int16_t WindowLeft; // Left side of the full image int16_t WindowRight; // Right side of the full image int16_t WindowBottom; // Bottom of the full image int16_t WindowTop; // Top of the full image int16_t ActiveLeft; // Left side of the viewable image int16_t ActiveRight; // Right side of viewable image int16_t ActiveBottom; // Bottom of the viewable image int16_t ActiveTop; // Top of the viewable image int16_t FrameNumber; // Frame sequence number int16_t ColorChannelType; // Data format of the image channels int16_t NumOfColorChannels; // Number of color channels in image int16_t NumOfMatteChannels; // Number of matte channels in image int16_t NumOfAuxChannels; // Number of auxiliary channels in image int16_t Revision; // File format revision number char Gamma[16]; // Gamma setting of image char RedChroma[24]; // Red chromaticity char GreenChroma[24]; // Green chromaticity char BlueChroma[24]; // Blue chromaticity char WhitePoint[24]; // White point chromaticity*/ int32_t JobNumber; // Job number ID of the file char FileName[128]; // Image file name char Description[128]; // Description of the file contents char ProgramName[64]; // Name of the program that created the file char MachineName[32]; // Name of machine used to create the file char UserName[32]; // Name of user who created the file char DateCreated[20]; // Date the file was created char Aspect[24]; // Aspect format of the image char AspectRatio[8]; // Aspect ratio of the image char ColorChannel[32]; // Format of color channel data int16_t FieldRendered; // Image contains field-rendered data char Time[12]; // Length of time used to create the image file char Filter[32]; // Name of post-processing filter int16_t NumOfChannelBits; // Number of bits in each color channel pixel int16_t MatteChannelType; // Data format of the matte channels int16_t NumOfMatteBits; // Number of bits in each matte channel pixel int16_t AuxChannelType; // Data format of the auxiliary channels int16_t NumOfAuxBits; // Number of bits in each auxiliary channel pixel char AuxData[32]; // Auxiliary channel data description char Reserved[36]; // Unused int32_t NextOffset; // Location of the next image header in the file void rla_swap_endian () { if (littleendian()) { // RLAs are big-endian swap_endian (&WindowLeft); swap_endian (&WindowRight); swap_endian (&WindowBottom); swap_endian (&WindowTop); swap_endian (&ActiveLeft); swap_endian (&ActiveRight); swap_endian (&ActiveBottom); swap_endian (&ActiveTop); swap_endian (&FrameNumber); swap_endian (&ColorChannelType); swap_endian (&NumOfColorChannels); swap_endian (&NumOfMatteChannels); swap_endian (&NumOfAuxChannels); swap_endian (&Revision); swap_endian (&JobNumber); swap_endian (&FieldRendered); swap_endian (&NumOfChannelBits); swap_endian (&MatteChannelType); swap_endian (&NumOfMatteBits); swap_endian (&AuxChannelType); swap_endian (&NumOfAuxBits); swap_endian (&NextOffset); } } }; /// format of data enum rla_channel_type { CT_BYTE = 0, CT_WORD = 1, CT_DWORD = 2, CT_FLOAT = 4 }; } // namespace RLA_pvt OIIO_PLUGIN_NAMESPACE_END #endif // OPENIMAGEIO_RLA_PVT_H openimageio-1.3.12~dfsg0.orig/src/rla.imageio/CMakeLists.txt0000644000175000017500000000005512271062644022037 0ustar mfvmfvadd_oiio_plugin (rlainput.cpp rlaoutput.cpp) openimageio-1.3.12~dfsg0.orig/src/rla.imageio/rlaoutput.cpp0000644000175000017500000004722612271062644022055 0ustar mfvmfv/* Copyright 2011 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "dassert.h" #include "typedesc.h" #include "imageio.h" #include "filesystem.h" #include "fmath.h" #include "strutil.h" #include "sysutil.h" #include "rla_pvt.h" #ifdef WIN32 # define snprintf _snprintf #endif OIIO_PLUGIN_NAMESPACE_BEGIN using namespace RLA_pvt; class RLAOutput : public ImageOutput { public: RLAOutput (); virtual ~RLAOutput (); virtual const char * format_name (void) const { return "rla"; } virtual bool supports (const std::string &feature) const; virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode=Create); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); private: std::string m_filename; ///< Stash the filename FILE *m_file; ///< Open image handle std::vector m_scratch; RLAHeader m_rla; ///< Wavefront RLA header std::vector m_sot; ///< Scanline offset table std::vector m_rle; ///< Run record buffer for RLE // Initialize private members to pre-opened state void init (void) { m_file = NULL; m_sot.clear (); } /// Helper - sets a chromaticity from attribute inline void set_chromaticity (const ImageIOParameter *p, char *dst, size_t field_size, const char *default_val); /// Helper - handles the repetitive work of encoding and writing a channel bool encode_channel (const unsigned char *data, stride_t xstride, TypeDesc chantype, int bits); /// Helper - write, with error detection bool fwrite (const void *buf, size_t itemsize, size_t nitems) { size_t n = ::fwrite (buf, itemsize, nitems, m_file); if (n != nitems) error ("Write error: wrote %d records of %d", (int)n, (int)nitems); return n == nitems; } /// Helper: write buf[0..nitems-1], swap endianness if necessary template bool write (const T *buf, size_t nitems=1) { if (littleendian() && (is_same::value || is_same::value || is_same::value || is_same::value)) { T *newbuf = ALLOCA(T,nitems); memcpy (newbuf, buf, nitems*sizeof(T)); swap_endian (newbuf, nitems); buf = newbuf; } return fwrite (buf, sizeof(T), nitems); } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput *rla_output_imageio_create () { return new RLAOutput; } // OIIO_EXPORT int rla_imageio_version = OIIO_PLUGIN_VERSION; // it's in rlainput.cpp OIIO_EXPORT const char * rla_output_extensions[] = { "rla", NULL }; OIIO_PLUGIN_EXPORTS_END RLAOutput::RLAOutput () { init (); } RLAOutput::~RLAOutput () { // Close, if not already done. close (); } bool RLAOutput::supports (const std::string &feature) const { if (feature == "random_access") return true; if (feature == "displaywindow") return true; if (feature == "origin") return true; if (feature == "negativeorigin") return true; // Support nothing else nonstandard return false; } bool RLAOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { if (mode != Create) { error ("%s does not support subimages or MIP levels", format_name()); return false; // FIXME -- the RLA format supports subimages, but our writer // doesn't. I'm not sure if it's worth worrying about for an // old format that is so rarely used. We'll come back to it if // anybody actually encounters a multi-subimage RLA in the wild. } close (); // Close any already-opened file m_spec = userspec; // Stash the spec if (m_spec.format == TypeDesc::UNKNOWN) m_spec.format = TypeDesc::UINT8; // Default to uint8 if unknown m_file = Filesystem::fopen (name, "wb"); if (! m_file) { error ("Could not open file \"%s\"", name.c_str()); return false; } // Check for things this format doesn't support if (m_spec.width < 1 || m_spec.height < 1) { error ("Image resolution must be at least 1x1, you asked for %d x %d", m_spec.width, m_spec.height); return false; } if (m_spec.width > 65535 || m_spec.height > 65535) { error ("Image resolution %d x %d too large for RLA (maxiumum 65535x65535)", m_spec.width, m_spec.height); return false; } if (m_spec.depth < 1) m_spec.depth = 1; else if (m_spec.depth > 1) { error ("%s does not support volume images (depth > 1)", format_name()); return false; } // prepare and write the RLA header memset (&m_rla, 0, sizeof (m_rla)); // frame and window coordinates m_rla.WindowLeft = m_spec.full_x; m_rla.WindowRight = m_spec.full_x + m_spec.full_width - 1; m_rla.WindowBottom = -m_spec.full_y; m_rla.WindowTop = m_spec.full_height - m_spec.full_y - 1; m_rla.ActiveLeft = m_spec.x; m_rla.ActiveRight = m_spec.x + m_spec.width - 1; m_rla.ActiveBottom = -m_spec.y; m_rla.ActiveTop = m_spec.height - m_spec.y - 1; m_rla.FrameNumber = m_spec.get_int_attribute ("rla:FrameNumber", 0); // figure out what's going on with the channels int remaining = m_spec.nchannels; if (m_spec.channelformats.size ()) { int streak; // accomodate first 3 channels of the same type as colour ones for (streak = 1; streak <= 3 && remaining > 0; ++streak, --remaining) if (m_spec.channelformats[streak] != m_spec.channelformats[0]) break; m_rla.ColorChannelType = m_spec.channelformats[0] == TypeDesc::FLOAT ? CT_FLOAT : CT_BYTE; int bits = m_spec.get_int_attribute ("oiio:BitsPerSample", 0); m_rla.NumOfChannelBits = bits ? bits : m_spec.channelformats[0].size () * 8; // limit to 3 in case the loop went further m_rla.NumOfColorChannels = std::min (streak, 3); // if we have anything left, treat it as alpha if (remaining) { for (streak = 1; remaining > 0; ++streak, --remaining) if (m_spec.channelformats[m_rla.NumOfColorChannels + streak] != m_spec.channelformats[m_rla.NumOfColorChannels]) break; m_rla.MatteChannelType = m_spec.channelformats[m_rla.NumOfColorChannels] == TypeDesc::FLOAT ? CT_FLOAT : CT_BYTE; m_rla.NumOfMatteBits = bits ? bits : m_spec.channelformats[m_rla.NumOfColorChannels].size () * 8; m_rla.NumOfMatteChannels = streak; } // and if there's something more left, put it in auxiliary if (remaining) { for (streak = 1; remaining > 0; ++streak, --remaining) if (m_spec.channelformats[m_rla.NumOfColorChannels + m_rla.NumOfMatteChannels + streak] != m_spec.channelformats[m_rla.NumOfColorChannels + m_rla.NumOfMatteChannels]) break; m_rla.MatteChannelType = m_spec.channelformats[m_rla.NumOfColorChannels + m_rla.NumOfMatteChannels] == TypeDesc::FLOAT ? CT_FLOAT : CT_BYTE; m_rla.NumOfAuxBits = m_spec.channelformats[m_rla.NumOfColorChannels + m_rla.NumOfMatteChannels].size () * 8; m_rla.NumOfAuxChannels = streak; } } else { m_rla.ColorChannelType = m_rla.MatteChannelType = m_rla.AuxChannelType = m_spec.format == TypeDesc::FLOAT ? CT_FLOAT : CT_BYTE; m_rla.NumOfChannelBits = m_rla.NumOfMatteBits = m_rla.NumOfAuxBits = m_spec.format.size () * 8; if (remaining >= 3) { // if we have at least 3 channels, treat them as colour m_rla.NumOfColorChannels = 3; remaining -= 3; } else { // otherwise let's say it's luminosity m_rla.NumOfColorChannels = 1; --remaining; } // if there's at least 1 more channel, it's alpha if (remaining-- > 0) ++m_rla.NumOfMatteChannels; // anything left is auxiliary if (remaining > 0) m_rla.NumOfAuxChannels = remaining; } m_rla.Revision = 0xFFFE; std::string s = m_spec.get_string_attribute ("oiio:ColorSpace", "Unknown"); if (Strutil::iequals(s, "Linear")) Strutil::safe_strcpy (m_rla.Gamma, "1.0", sizeof(m_rla.Gamma)); else if (Strutil::iequals(s, "GammaCorrected")) snprintf (m_rla.Gamma, sizeof(m_rla.Gamma), "%.10f", m_spec.get_float_attribute ("oiio:Gamma", 1.f)); const ImageIOParameter *p; // default NTSC chromaticities p = m_spec.find_attribute ("rla:RedChroma"); set_chromaticity (p, m_rla.RedChroma, sizeof (m_rla.RedChroma), "0.67 0.08"); p = m_spec.find_attribute ("rla:GreenChroma"); set_chromaticity (p, m_rla.GreenChroma, sizeof (m_rla.GreenChroma), "0.21 0.71"); p = m_spec.find_attribute ("rla:BlueChroma"); set_chromaticity (p, m_rla.BlueChroma, sizeof (m_rla.BlueChroma), "0.14 0.33"); p = m_spec.find_attribute ("rla:WhitePoint"); set_chromaticity (p, m_rla.WhitePoint, sizeof (m_rla.WhitePoint), "0.31 0.316"); #define STRING_FIELD(rlafield,name) \ { \ std::string s = m_spec.get_string_attribute (name); \ if (s.length()) { \ strncpy (m_rla.rlafield, s.c_str(), sizeof(m_rla.rlafield));\ m_rla.rlafield[sizeof(m_rla.rlafield)-1] = 0; \ } else { \ m_rla.rlafield[0] = 0; \ } \ } m_rla.JobNumber = m_spec.get_int_attribute ("rla:JobNumber", 0); STRING_FIELD (FileName, "rla:FileName"); STRING_FIELD (Description, "ImageDescription"); STRING_FIELD (ProgramName, "Software"); STRING_FIELD (MachineName, "HostComputer"); STRING_FIELD (UserName, "Artist"); // the month number will be replaced with the 3-letter abbreviation time_t t = time (NULL); strftime (m_rla.DateCreated, sizeof (m_rla.DateCreated), "%m %d %H:%M %Y", localtime (&t)); // nice little trick - atoi() will convert the month number to integer, // which we then use to index this array of constants, and copy the // abbreviation back into the date string static const char months[12][4] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; memcpy(m_rla.DateCreated, months[atoi (m_rla.DateCreated) - 1], 3); // FIXME: it appears that Wavefront have defined a set of aspect names; // I think it's safe not to care until someone complains STRING_FIELD (Aspect, "rla:Aspect"); snprintf (m_rla.AspectRatio, sizeof(m_rla.AspectRatio), "%.10f", m_spec.get_float_attribute ("PixelAspectRatio", 1.f)); Strutil::safe_strcpy (m_rla.ColorChannel, m_spec.get_string_attribute ("rla:ColorChannel", "rgb"), sizeof(m_rla.ColorChannel)); m_rla.FieldRendered = m_spec.get_int_attribute ("rla:FieldRendered", 0); STRING_FIELD (Time, "rla:Time"); STRING_FIELD (Filter, "rla:Filter"); STRING_FIELD (AuxData, "rla:AuxData"); m_rla.rla_swap_endian (); // RLAs are big-endian write (&m_rla); m_rla.rla_swap_endian (); // flip back the endianness to native // write placeholder values - not all systems may expand the file with // zeroes upon seek m_sot.resize (m_spec.height, (int32_t)0); write (&m_sot[0], m_sot.size()); return true; } inline void RLAOutput::set_chromaticity (const ImageIOParameter *p, char *dst, size_t field_size, const char *default_val) { if (p && p->type().basetype == TypeDesc::FLOAT) { switch (p->type().aggregate) { case TypeDesc::VEC2: snprintf (dst, field_size, "%.4f %.4f", ((float *)p->data ())[0], ((float *)p->data ())[1]); break; case TypeDesc::VEC3: snprintf (dst, field_size, "%.4f %.4f %.4f", ((float *)p->data ())[0], ((float *)p->data ())[1], ((float *)p->data ())[2]); break; } } else Strutil::safe_strcpy (dst, default_val, field_size); } bool RLAOutput::close () { if (m_file) { // Now that all scanlines ahve been output, return to write the // correct scanline offset table to file. fseek (m_file, sizeof(RLAHeader), SEEK_SET); write (&m_sot[0], m_sot.size()); // close the stream fclose (m_file); m_file = NULL; } init (); // re-initialize return true; // How can we fail? // Epicly. -- IneQuation } bool RLAOutput::encode_channel (const unsigned char *data, stride_t xstride, TypeDesc chantype, int bits) { if (chantype == TypeDesc::FLOAT) { // Special case -- float data is just dumped raw, no RLE uint16_t size = m_spec.width * sizeof(float); write (&size); for (int x = 0; x < m_spec.width; ++x) write ((const float *)&data[x*xstride]); return true; } m_rle.resize (2); // reserve t bytes for the encoded size // multi-byte data types are sliced to MSB, nextSB, ..., LSB int chsize = (int)chantype.size(); for (int byte = 0; byte < chsize; ++byte) { int lastval = -1; // last value int count = 0; // count of raw or repeats bool repeat = false; // if true, we're repeating int runbegin = 0; // where did the run begin int byteoffset = bigendian() ? byte : (chsize-byte-1); for (int x = 0; x < m_spec.width; ++x) { int newval = data[x*xstride+byteoffset]; if (count == 0) { // beginning of a run. count = 1; repeat = true; // presumptive runbegin = x; } else if (repeat) { // We've seen one or more repeating characters if (newval == lastval) { // another repeating value ++count; } else { // We stopped repeating. if (count < 3) { // If we didn't even have 3 in a row, just // retroactively treat it as a raw run. ++count; repeat = false; } else { // We are ending a 3+ repetition m_rle.push_back (count-1); m_rle.push_back (lastval); count = 1; runbegin = x; } } } else { // Have not been repeating if (newval == lastval) { // starting a repetition? Output previous ASSERT (count > 1); // write everything but the last char --count; m_rle.push_back (-count); for (int i = 0; i < count; ++i) m_rle.push_back (data[(runbegin+i)*xstride+byteoffset]); count = 2; runbegin = x - 1; repeat = true; } else { ++count; // another non-repeat } } // If the run is too long or we're at the scanline end, write if (count == 127 || x == m_spec.width-1) { if (repeat) { m_rle.push_back (count-1); m_rle.push_back (lastval); } else { m_rle.push_back (-count); for (int i = 0; i < count; ++i) m_rle.push_back (data[(runbegin+i)*xstride+byteoffset]); } count = 0; } lastval = newval; } ASSERT (count == 0); } // Now that we know the size of the encoded buffer, save it at the // beginning uint16_t size = uint16_t (m_rle.size() - 2); m_rle[0] = size >> 8; m_rle[1] = size & 255; // And write the channel to the file return write (&m_rle[0], m_rle.size()); } bool RLAOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { m_spec.auto_stride (xstride, format, spec().nchannels); const void *origdata = data; data = to_native_scanline (format, data, xstride, m_scratch); if (data == origdata) { m_scratch.assign ((unsigned char *)data, (unsigned char *)data+m_spec.scanline_bytes()); data = &m_scratch[0]; } // store the offset to the scanline. We'll swap_endian if necessary // when we go to actually write it. m_sot[m_spec.height - y - 1] = (uint32_t)ftell (m_file); size_t pixelsize = m_spec.pixel_bytes (true /*native*/); int offset = 0; for (int c = 0; c < m_spec.nchannels; ++c) { TypeDesc chantype = m_spec.channelformats.size() ? m_spec.channelformats[c] : m_spec.format; int bits = (c < m_rla.NumOfColorChannels) ? m_rla.NumOfChannelBits : (c < (m_rla.NumOfColorChannels+m_rla.NumOfMatteBits)) ? m_rla.NumOfMatteBits : m_rla.NumOfAuxBits; if (!encode_channel ((unsigned char *)data + offset, pixelsize, chantype, bits)) return false; offset += chantype.size(); } return true; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/field3d.imageio/0000755000175000017500000000000012271062644020033 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/src/field3d.imageio/field3d_backdoor.h0000644000175000017500000000404212271062644023362 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ OIIO_NAMESPACE_ENTER { namespace f3dpvt { // Define an abstract interface that allows us to get special information // from the Field3DInput. class Field3DInput_Interface : public ImageInput { public: Field3DInput_Interface () { } // Transform world space P to local space P. virtual void worldToLocal (const Imath::V3f &wsP, Imath::V3f &lsP, float time) const = 0; }; } // end namespace f3dpvt } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/field3d.imageio/field3d_pvt.h0000644000175000017500000000560412271062644022414 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #ifndef FIELD3D_NS #define FIELD3D_NS Field3D #endif using namespace FIELD3D_NS; OIIO_NAMESPACE_ENTER { namespace f3dpvt { enum FieldType { Dense, Sparse, MAC }; struct layerrecord { std::string name; std::string attribute; std::string unique_name; TypeDesc datatype; FieldType fieldtype; bool vecfield; // true=vector, false=scalar Box3i extents; Box3i dataWindow; ImageSpec spec; FieldRes::Ptr field; layerrecord () : vecfield(false) { } }; // Define an abstract interface that allows us to get special information // from the Field3DInput. class Field3DInput_Interface : public ImageInput { public: Field3DInput_Interface () { } // Transform world space P to local space P. virtual void worldToLocal (const Imath::V3f &wsP, Imath::V3f &lsP, float time) const = 0; }; // Return a reference to the mutex that allows us to use f3d with multiple // threads. spin_mutex &field3d_mutex (); void oiio_field3d_initialize (); } // end namespace f3dpvt } OIIO_NAMESPACE_EXIT openimageio-1.3.12~dfsg0.orig/src/field3d.imageio/field3doutput.cpp0000644000175000017500000004642012271062644023340 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include #include "dassert.h" #include "imageio.h" #include "thread.h" #include "field3d_pvt.h" using namespace OIIO_NAMESPACE::f3dpvt; OIIO_PLUGIN_NAMESPACE_BEGIN class Field3DOutput : public ImageOutput { public: Field3DOutput (); virtual ~Field3DOutput (); virtual const char * format_name (void) const { return "field3d"; } virtual bool supports (const std::string &feature) const; virtual bool open (const std::string &name, const ImageSpec &spec, OpenMode mode); virtual bool open (const std::string &name, int subimages, const ImageSpec *specs); virtual bool close (); virtual bool write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride); virtual bool write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride); private: std::string m_name; Field3DOutputFile *m_output; int m_subimage; ///< What subimage/field are we writing now int m_nsubimages; ///< How many subimages will be in the file? bool m_writepending; ///< Is there an unwritten current layer? std::vector Xm_layers; std::vector m_specs; std::vector m_scratch; ///< Scratch space for us to use FieldRes::Ptr m_field; // Initialize private members to pre-opened state void init (void) { m_name.clear (); m_output = NULL; m_subimage = -1; m_nsubimages = 0; // m_layers.clear (); m_specs.clear (); m_writepending = false; } // Add a parameter to the output bool put_parameter (const std::string &name, TypeDesc type, const void *data); bool prep_subimage (); bool write_current_subimage (); template bool prep_subimage_specialized (); template bool write_current_subimage_specialized (); template bool write_current_subimage_specialized_vec (); template bool write_scanline_specialized (int y, int z, const T *data); template bool write_tile_specialized (int x, int y, int z, const T *data); }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageOutput * field3d_output_imageio_create () { return new Field3DOutput; } OIIO_EXPORT int field3d_imageio_version = OIIO_PLUGIN_VERSION; OIIO_EXPORT const char * field3d_output_extensions[] = { "f3d", NULL }; OIIO_PLUGIN_EXPORTS_END namespace { // anon namespace // format-specific metadata prefixes static std::vector format_prefixes; static atomic_int format_prefixes_initialized; static spin_mutex format_prefixes_mutex; // guard } Field3DOutput::Field3DOutput () { init (); } Field3DOutput::~Field3DOutput () { // Close, if not already done. close (); } bool Field3DOutput::supports (const std::string &feature) const { if (feature == "tiles") return true; if (feature == "multiimage") return true; if (feature == "random_access") return true; // FIXME: we could support "empty" // Everything else, we either don't support or don't know about return false; } bool Field3DOutput::open (const std::string &name, const ImageSpec &userspec, OpenMode mode) { // If called the old-fashioned way, for one subimage, just turn it into // a call to the multi-subimage open() with a single subimage. if (mode == Create) return open (name, 1, &userspec); if (mode == AppendMIPLevel) { error ("%s does not support MIP-mapping", format_name()); return false; } ASSERT (mode == AppendSubimage && "invalid open() mode"); write_current_subimage (); ++m_subimage; if (m_subimage >= m_nsubimages) { error ("Appending past the pre-declared number of subimages (%d)", m_nsubimages); return false; } if (! prep_subimage ()) return false; return true; } bool Field3DOutput::open (const std::string &name, int subimages, const ImageSpec *specs) { if (m_output) close(); if (subimages < 1) { error ("%s does not support %d subimages.", format_name(), subimages); return false; } oiio_field3d_initialize (); m_nsubimages = subimages; m_subimage = 0; { spin_lock lock (field3d_mutex()); m_output = new Field3DOutputFile; bool ok = false; try { ok = m_output->create (name); } catch (...) { ok = false; } if (! ok) { delete m_output; m_output = NULL; m_name.clear (); return false; } m_name = name; } m_specs.assign (specs, specs+subimages); for (int s = 0; s < m_nsubimages; ++s) { ImageSpec &spec (m_specs[s]); if (spec.format != TypeDesc::HALF && spec.format != TypeDesc::DOUBLE) { spec.format = TypeDesc::FLOAT; } if (spec.nchannels != 1 && spec.nchannels != 3) { error ("%s does not allow %d channels in a field (subimage %d)", format_name(), spec.nchannels, s); return false; } } if (! prep_subimage ()) // get ready for first subimage return false; return true; } bool Field3DOutput::put_parameter (const std::string &name, TypeDesc type, const void *data) { if (Strutil::istarts_with (name, "field3d:") || Strutil::istarts_with (name, "oiio:")) return false; // skip these; handled separately or not at all // Before handling general named metadata, suppress non-openexr // format-specific metadata. if (const char *colon = strchr (name.c_str(), ':')) { std::string prefix (name.c_str(), colon); if (! Strutil::iequals (prefix, "openexr")) { if (! format_prefixes_initialized) { // Retrieve and split the list, only the first time spin_lock lock (format_prefixes_mutex); std::string format_list; OIIO::getattribute ("format_list", format_list); Strutil::split (format_list, format_prefixes, ","); format_prefixes_initialized = true; } for (size_t i = 0, e = format_prefixes.size(); i < e; ++i) if (Strutil::iequals (prefix, format_prefixes[i])) return false; } } if (type == TypeDesc::TypeString) m_field->metadata().setStrMetadata (name, *(const char **)data); else if (type == TypeDesc::TypeInt) m_field->metadata().setIntMetadata (name, *(const int *)data); else if (type == TypeDesc::TypeFloat) m_field->metadata().setFloatMetadata (name, *(const float *)data); else if (type.basetype == TypeDesc::FLOAT && type.aggregate == 3) m_field->metadata().setVecFloatMetadata (name, *(const FIELD3D_NS::V3f *)data); else if (type.basetype == TypeDesc::INT && type.aggregate == 3) m_field->metadata().setVecIntMetadata (name, *(const FIELD3D_NS::V3i *)data); else return false; return true; } bool Field3DOutput::close () { spin_lock lock (field3d_mutex()); if (m_output) { write_current_subimage (); m_output->close (); delete m_output; // implicity closes m_output = NULL; } init (); // re-initialize return true; // How can we fail? } template bool Field3DOutput::write_scanline_specialized (int y, int z, const T *data) { int xend = m_spec.x + m_spec.width; if (typename DenseField::Ptr f = field_dynamic_cast >(m_field)) { for (int x = m_spec.x; x < xend; ++x) f->lvalue(x, y, z) = *data++; return true; } if (typename SparseField::Ptr f = field_dynamic_cast >(m_field)) { for (int x = m_spec.x; x < xend; ++x) f->lvalue(x, y, z) = *data++; return true; } error ("Unknown field type"); return false; } bool Field3DOutput::write_scanline (int y, int z, TypeDesc format, const void *data, stride_t xstride) { m_spec.auto_stride (xstride, format, spec().nchannels); data = to_native_scanline (format, data, xstride, m_scratch); if (m_spec.format == TypeDesc::FLOAT) { if (m_spec.nchannels == 1) return write_scanline_specialized(y, z, (const float *)data); else return write_scanline_specialized(y, z, (const FIELD3D_VEC3_T *)data); } else if (m_spec.format == TypeDesc::DOUBLE) { if (m_spec.nchannels == 1) return write_scanline_specialized(y, z, (const double *)data); else return write_scanline_specialized(y, z, (const FIELD3D_VEC3_T *)data); } else if (m_spec.format == TypeDesc::HALF) { if (m_spec.nchannels == 1) return write_scanline_specialized(y, z, (const FIELD3D_NS::half *)data); else return write_scanline_specialized(y, z, (const FIELD3D_VEC3_T *)data); } else { ASSERT (0); } return false; } template bool Field3DOutput::write_tile_specialized (int x, int y, int z, const T *data) { int xend = std::min (x + m_spec.tile_width, m_spec.x + m_spec.width); int yend = std::min (y + m_spec.tile_height, m_spec.y + m_spec.height); int zend = std::min (z + m_spec.tile_depth, m_spec.z + m_spec.depth); if (typename DenseField::Ptr f = field_dynamic_cast >(m_field)) { for (int k = z; k < zend; ++k) { for (int j = y; j < yend; ++j) { const T *d = data + (k-z)*(m_spec.tile_width*m_spec.tile_height) + (j-y)*m_spec.tile_width; for (int i = x; i < xend; ++i) f->lvalue (i, j, k) = *d++; } } return true; } if (typename SparseField::Ptr f = field_dynamic_cast >(m_field)) { for (int k = z; k < zend; ++k) { for (int j = y; j < yend; ++j) { const T *d = data + (k-z)*(m_spec.tile_width*m_spec.tile_height) + (j-y)*m_spec.tile_width; for (int i = x; i < xend; ++i) f->lvalue (i, j, k) = *d++; } } return true; } error ("Unknown field type"); return false; } bool Field3DOutput::write_tile (int x, int y, int z, TypeDesc format, const void *data, stride_t xstride, stride_t ystride, stride_t zstride) { m_spec.auto_stride (xstride, ystride, zstride, format, spec().nchannels, spec().tile_width, spec().tile_height); data = to_native_tile (format, data, xstride, ystride, zstride, m_scratch); if (m_spec.format == TypeDesc::FLOAT) { if (m_spec.nchannels == 1) return write_tile_specialized (x, y, z, (const float *)data); else return write_tile_specialized (x, y, z, (const FIELD3D_VEC3_T *)data); } else if (m_spec.format == TypeDesc::DOUBLE) { if (m_spec.nchannels == 1) return write_tile_specialized (x, y, z, (const double *)data); else return write_tile_specialized (x, y, z, (const FIELD3D_VEC3_T *)data); } else if (m_spec.format == TypeDesc::HALF) { if (m_spec.nchannels == 1) return write_tile_specialized (x, y, z, (const FIELD3D_NS::half *)data); else return write_tile_specialized (x, y, z, (const FIELD3D_VEC3_T *)data); } else { ASSERT (0); } return false; } template bool Field3DOutput::prep_subimage_specialized () { m_spec = m_specs[m_subimage]; ASSERT (m_spec.nchannels == 1 || m_spec.nchannels == 3); Box3i extents (V3i (m_spec.full_x, m_spec.full_y, m_spec.full_z), V3i (m_spec.full_x+m_spec.full_width-1, m_spec.full_y+m_spec.full_height-1, m_spec.full_z+m_spec.full_depth-1)); Box3i datawin (V3i (m_spec.x, m_spec.y, m_spec.z), V3i (m_spec.x+m_spec.width-1, m_spec.y+m_spec.height-1, m_spec.z+m_spec.depth-1)); std::string fieldtype = m_spec.get_string_attribute ("field3d:fieldtype"); if (Strutil::iequals (fieldtype, "SparseField")) { // Sparse SparseField *f (new SparseField); f->setSize (extents, datawin); m_field.reset (f); } else if (Strutil::iequals (fieldtype, "MAC")) { // FIXME ASSERT (0 && "MAC fields not yet supported"); } else { // Dense DenseField *f (new DenseField); f->setSize (extents, datawin); m_field.reset (f); } std::string name = m_spec.get_string_attribute ("field3d:partition"); std::string attribute = m_spec.get_string_attribute ("field3d:layer"); if (! name.size() && ! attribute.size()) { // Try to extract from the subimagename or if that fails, // ImageDescription std::string unique_name = m_spec.get_string_attribute ("oiio:subimagename"); if (unique_name.size() == 0) unique_name = m_spec.get_string_attribute ("ImageDescription"); if (unique_name.size() == 0) unique_name = "name:attribute"; // punt std::vector pieces; Strutil::split (unique_name, pieces); if (pieces.size() > 0) name = pieces[0]; if (pieces.size() > 1) attribute = pieces[1]; } m_field->name = name; m_field->attribute = attribute; // Mapping matrix TypeDesc TypeMatrixD (TypeDesc::DOUBLE, TypeDesc::MATRIX44); if (ImageIOParameter *mx = m_spec.find_attribute ("field3d:localtoworld", TypeMatrixD)) { MatrixFieldMapping::Ptr mapping (new MatrixFieldMapping); mapping->setLocalToWorld (*((FIELD3D_NS::M44d*)mx->data())); m_field->setMapping (mapping); } else if (ImageIOParameter *mx = m_spec.find_attribute ("worldtocamera", TypeDesc::TypeMatrix)) { Imath::M44f m = *((Imath::M44f*)mx->data()); m = m.inverse(); FIELD3D_NS::M44d md (m[0][0], m[0][1], m[0][1], m[0][3], m[1][0], m[1][1], m[1][1], m[1][3], m[2][0], m[2][1], m[2][1], m[2][3], m[3][0], m[3][1], m[3][1], m[3][3]); MatrixFieldMapping::Ptr mapping (new MatrixFieldMapping); mapping->setLocalToWorld (md); m_field->setMapping (mapping); } // Miscellaneous metadata for (size_t p = 0; p < spec().extra_attribs.size(); ++p) put_parameter (spec().extra_attribs[p].name().string(), spec().extra_attribs[p].type(), spec().extra_attribs[p].data()); return true; } bool Field3DOutput::prep_subimage () { m_spec = m_specs[m_subimage]; ASSERT (m_spec.nchannels == 1 || m_spec.nchannels == 3); if (m_spec.format == TypeDesc::FLOAT) { if (m_spec.nchannels == 1) prep_subimage_specialized(); else prep_subimage_specialized >(); } else if (m_spec.format == TypeDesc::DOUBLE) { if (m_spec.nchannels == 1) prep_subimage_specialized(); else prep_subimage_specialized >(); } else if (m_spec.format == TypeDesc::HALF) { if (m_spec.nchannels == 1) prep_subimage_specialized(); else prep_subimage_specialized >(); } else { ASSERT (0); } m_writepending = true; return true; } template bool Field3DOutput::write_current_subimage_specialized () { if (typename DenseField::Ptr df = field_dynamic_cast >(m_field)) { m_output->writeScalarLayer (df); return true; } if (typename SparseField::Ptr sf = field_dynamic_cast >(m_field)) { m_output->writeScalarLayer (sf); return true; } return false; } template bool Field3DOutput::write_current_subimage_specialized_vec () { typedef FIELD3D_VEC3_T V; if (typename DenseField::Ptr df = field_dynamic_cast >(m_field)) { m_output->writeVectorLayer (df); return true; } if (typename SparseField::Ptr sf = field_dynamic_cast >(m_field)) { m_output->writeVectorLayer (sf); return true; } return false; } bool Field3DOutput::write_current_subimage () { if (! m_writepending) return true; bool ok = false; if (m_spec.format == TypeDesc::FLOAT) { if (m_spec.nchannels == 1) ok = write_current_subimage_specialized (); else ok = write_current_subimage_specialized_vec (); } else if (m_spec.format == TypeDesc::DOUBLE) { if (m_spec.nchannels == 1) ok = write_current_subimage_specialized (); else ok = write_current_subimage_specialized_vec (); } else if (m_spec.format == TypeDesc::HALF) { if (m_spec.nchannels == 1) ok = write_current_subimage_specialized (); else ok = write_current_subimage_specialized_vec (); } m_writepending = false; m_field.reset (); return ok; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/field3d.imageio/field3dinput.cpp0000644000175000017500000004323612271062644023141 0ustar mfvmfv/* Copyright 2010 Larry Gritz and the other authors and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software's owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (This is the Modified BSD License) */ #include #include #include #include "dassert.h" #include "imageio.h" #include "thread.h" #include "filesystem.h" #include #include #include "field3d_pvt.h" using namespace OIIO_NAMESPACE::f3dpvt; OIIO_PLUGIN_NAMESPACE_BEGIN spin_mutex & f3dpvt::field3d_mutex () { static spin_mutex m; return m; } class Field3DInput : public Field3DInput_Interface { public: Field3DInput () { init(); } virtual ~Field3DInput () { close(); } virtual const char * format_name (void) const { return "field3d"; } virtual bool valid_file (const std::string &filename) const; virtual bool open (const std::string &name, ImageSpec &newspec); virtual bool close (); virtual int current_subimage (void) const { return m_subimage; } virtual bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec); virtual bool read_native_scanline (int y, int z, void *data); virtual bool read_native_tile (int x, int y, int z, void *data); /// Transform a world space position to local coordinates, using the /// mapping of the current subimage. virtual void worldToLocal (const Imath::V3f &wsP, Imath::V3f &lsP, float time) const; private: std::string m_name; Field3DInputFile *m_input; int m_subimage; ///< What subimage/field are we looking at? int m_nsubimages; ///< How many fields in the file? std::vector m_layers; std::vector m_scratch; ///< Scratch space for us to use template void read_layers (TypeDesc datatype); void read_one_layer (FieldRes::Ptr field, layerrecord &lay, TypeDesc datatype, size_t layernum); template bool readtile (int x, int y, int z, T *data); void init () { m_name.clear (); m_input = NULL; m_subimage = -1; m_nsubimages = 0; m_layers.clear (); } }; // Obligatory material to make this a recognizeable imageio plugin: OIIO_PLUGIN_EXPORTS_BEGIN OIIO_EXPORT ImageInput * field3d_input_imageio_create () { return new Field3DInput; } // OIIO_EXPORT int field3d_imageio_version = OIIO_PLUGIN_VERSION; // it's in field3doutput.cpp OIIO_EXPORT const char * field3d_input_extensions[] = { "f3d", NULL }; OIIO_PLUGIN_EXPORTS_END void f3dpvt::oiio_field3d_initialize () { static volatile bool initialized = false; if (! initialized) { spin_lock lock (field3d_mutex()); if (! initialized) { initIO (); // Minimize Field3D's own internal caching SparseFileManager::singleton().setLimitMemUse(true); // Enables cache SparseFileManager::singleton().setMaxMemUse(20.0f); // In MB #if (100*FIELD3D_MAJOR_VER + FIELD3D_MINOR_VER) >= 104 Msg::setVerbosity (0); // Turn off console messages from F3D #endif initialized = true; } } } template inline int blocksize (FieldRes::Ptr &f) { ASSERT (f && "taking blocksize of null ptr"); typename SparseField::Ptr sf (field_dynamic_cast >(f)); if (sf) return sf->blockSize(); typename SparseField::Ptr vsf (field_dynamic_cast >(f)); if (vsf) return vsf->blockSize(); return 0; } template static void read_metadata (const M &meta, ImageSpec &spec) { for (typename M::StrMetadata::const_iterator i = meta.strMetadata().begin(), e = meta.strMetadata().end(); i != e; ++i) spec.attribute (i->first, i->second); for (typename M::IntMetadata::const_iterator i = meta.intMetadata().begin(), e = meta.intMetadata().end(); i != e; ++i) spec.attribute (i->first, i->second); for (typename M::FloatMetadata::const_iterator i = meta.floatMetadata().begin(), e = meta.floatMetadata().end(); i != e; ++i) spec.attribute (i->first, i->second); for (typename M::VecIntMetadata::const_iterator i = meta.vecIntMetadata().begin(), e = meta.vecIntMetadata().end(); i != e; ++i) { spec.attribute (i->first, TypeDesc(TypeDesc::INT,3), &(i->second)); } for (typename M::VecFloatMetadata::const_iterator i = meta.vecFloatMetadata().begin(), e = meta.vecFloatMetadata().end(); i != e; ++i) { spec.attribute (i->first, TypeDesc::TypeVector, &(i->second)); } } void Field3DInput::read_one_layer (FieldRes::Ptr field, layerrecord &lay, TypeDesc datatype, size_t layernum) { lay.name = field->name; lay.attribute = field->attribute; lay.datatype = datatype; lay.extents = field->extents(); lay.dataWindow = field->dataWindow(); lay.field = field; // Generate a unique name for the layer. Field3D files can have // multiple partitions (aka fields) with the same name, and // different partitions can each have attributes (aka layers) with // identical names. The convention is that if there are duplicates, // insert a number to disambiguate. int duplicates = 0; for (int i = 0; i < (int)layernum; ++i) if (m_layers[i].name == lay.name && m_layers[i].attribute == lay.attribute) ++duplicates; if (! duplicates && lay.name == lay.attribute) lay.unique_name = lay.name; else lay.unique_name = duplicates ? Strutil::format ("%s.%u:%s", lay.name, duplicates+1, lay.attribute) : Strutil::format ("%s:%s", lay.name, lay.attribute); lay.spec = ImageSpec(); // Clear everything with default constructor lay.spec.format = lay.datatype; if (lay.vecfield) { lay.spec.nchannels = 3; lay.spec.channelnames.push_back (lay.attribute + ".x"); lay.spec.channelnames.push_back (lay.attribute + ".y"); lay.spec.channelnames.push_back (lay.attribute + ".z"); } else { lay.spec.channelnames.push_back (lay.attribute); lay.spec.nchannels = 1; } lay.spec.x = lay.dataWindow.min.x; lay.spec.y = lay.dataWindow.min.y; lay.spec.z = lay.dataWindow.min.z; lay.spec.width = lay.dataWindow.max.x - lay.dataWindow.min.x + 1; lay.spec.height = lay.dataWindow.max.y - lay.dataWindow.min.y + 1; lay.spec.depth = lay.dataWindow.max.z - lay.dataWindow.min.z + 1; lay.spec.full_x = lay.extents.min.x; lay.spec.full_y = lay.extents.min.y; lay.spec.full_z = lay.extents.min.z; lay.spec.full_width = lay.extents.max.x - lay.extents.min.x + 1; lay.spec.full_height = lay.extents.max.y - lay.extents.min.y + 1; lay.spec.full_depth = lay.extents.max.z - lay.extents.min.z + 1; // Always appear tiled int b = 0; if (lay.fieldtype == f3dpvt::Sparse) { if (datatype == TypeDesc::FLOAT) b = blocksize(field); else if (datatype == TypeDesc::HALF) b = blocksize(field); else if (datatype == TypeDesc::DOUBLE) b = blocksize(field); } if (b) { // There was a block size found lay.spec.tile_width = b; lay.spec.tile_height = b; lay.spec.tile_depth = b; } else { // Make the tiles be the volume size lay.spec.tile_width = lay.spec.width; lay.spec.tile_height = lay.spec.height; lay.spec.tile_depth = lay.spec.depth; } ASSERT (lay.spec.tile_width > 0 && lay.spec.tile_height > 0 && lay.spec.tile_depth > 0); lay.spec.attribute ("ImageDescription", lay.unique_name); lay.spec.attribute ("oiio:subimagename", lay.unique_name); lay.spec.attribute ("field3d:partition", lay.name); lay.spec.attribute ("field3d:layer", lay.attribute); lay.spec.attribute ("field3d:fieldtype", field->className()); FieldMapping::Ptr mapping = field->mapping(); lay.spec.attribute ("field3d:mapping", mapping->className()); MatrixFieldMapping::Ptr matrixMapping = boost::dynamic_pointer_cast(mapping); if (matrixMapping) { Imath::M44d md = matrixMapping->localToWorld(); lay.spec.attribute ("field3d:localtoworld", TypeDesc(TypeDesc::DOUBLE, TypeDesc::MATRIX44), &md); Imath::M44f m ((float)md[0][0], (float)md[0][1], (float)md[0][2], (float)md[0][3], (float)md[1][0], (float)md[1][1], (float)md[1][2], (float)md[1][3], (float)md[2][0], (float)md[2][1], (float)md[2][2], (float)md[2][3], (float)md[3][0], (float)md[3][1], (float)md[3][2], (float)md[3][3]); m = m.inverse(); lay.spec.attribute ("worldtocamera", TypeDesc::TypeMatrix, &m); } // Other metadata read_metadata (m_input->metadata(), lay.spec); // global read_metadata (field->metadata(), lay.spec); // specific to this field } /// Read all layers from the open file that match the data type. /// Find the list of scalar and vector fields. template void Field3DInput::read_layers (TypeDesc datatype) { typedef typename Field::Vec SFieldList; SFieldList sFields = m_input->readScalarLayers(); if (sFields.size() > 0) { for (typename SFieldList::const_iterator i = sFields.begin(); i != sFields.end(); ++i) { size_t layernum = m_layers.size(); m_layers.resize (layernum+1); layerrecord &lay (m_layers.back()); if (field_dynamic_cast >(*i)) lay.fieldtype = f3dpvt::Dense; else if (field_dynamic_cast >(*i)) lay.fieldtype = f3dpvt::Sparse; else ASSERT (0 && "unknown field type"); read_one_layer (*i, lay, datatype, layernum); } } // Note that both scalar and vector calls take the scalar type as argument typedef typename Field >::Vec VFieldList; VFieldList vFields = m_input->readVectorLayers(); if (vFields.size() > 0) { for (typename VFieldList::const_iterator i = vFields.begin(); i != vFields.end(); ++i) { size_t layernum = m_layers.size(); m_layers.resize (layernum+1); layerrecord &lay (m_layers.back()); typedef FIELD3D_VEC3_T VecData_T; if (field_dynamic_cast >(*i)) lay.fieldtype = f3dpvt::Dense; else if (field_dynamic_cast >(*i)) lay.fieldtype = f3dpvt::Sparse; else if (field_dynamic_cast >(*i)) lay.fieldtype = f3dpvt::MAC; else ASSERT (0 && "unknown field type"); lay.vecfield = true; read_one_layer (*i, lay, datatype, layernum); } } } bool Field3DInput::valid_file (const std::string &filename) const { if (! Filesystem::is_regular (filename)) return false; oiio_field3d_initialize (); bool ok = false; Field3DInputFile *input = NULL; { spin_lock lock (field3d_mutex()); input = new Field3DInputFile; try { ok = input->open (filename); } catch (...) { ok = false; } delete input; } return ok; } bool Field3DInput::open (const std::string &name, ImageSpec &newspec) { if (m_input) close(); if (! Filesystem::is_regular (name)) return false; oiio_field3d_initialize (); { spin_lock lock (field3d_mutex()); m_input = new Field3DInputFile; bool ok = false; try { ok = m_input->open (name); } catch (...) { ok = false; } if (! ok) { delete m_input; m_input = NULL; m_name.clear (); return false; } m_name = name; std::vector partitions; m_input->getPartitionNames (partitions); // There's no apparent way to loop over all fields and layers -- the // Field3D library is templated so that it's most natural to have // the "outer loop" be the data type. So for each type, we augment // our list of layers with the matching ones in the file. read_layers (TypeDesc::HALF); read_layers (TypeDesc::FLOAT); read_layers (TypeDesc::DOUBLE); } m_nsubimages = (int) m_layers.size(); return seek_subimage (0, 0, newspec); } bool Field3DInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec) { if (subimage < 0 || subimage >= m_nsubimages) // out of range return false; if (miplevel != 0) return false; m_subimage = subimage; m_spec = m_layers[subimage].spec; newspec = m_spec; return true; } bool Field3DInput::close () { spin_lock lock (field3d_mutex()); if (m_input) { m_input->close (); delete m_input; // implicity closes m_input = NULL; m_name.clear (); } init (); // Reset to initial state return true; } bool Field3DInput::read_native_scanline (int y, int z, void *data) { // scanlines not supported return false; } template bool Field3DInput::readtile (int x, int y, int z, T *data) { layerrecord &lay (m_layers[m_subimage]); int xend = std::min (x+lay.spec.tile_width, lay.spec.x+lay.spec.width); int yend = std::min (y+lay.spec.tile_height, lay.spec.y+lay.spec.height); int zend = std::min (z+lay.spec.tile_depth, lay.spec.z+lay.spec.depth); { typename DenseField::Ptr f = field_dynamic_cast > (lay.field); if (f) { //std::cerr << "readtile dense " << x << '-' << xend << " x " // << y << '-' << yend << " x " << z << '-' << zend << "\n"; for (int k = z; k < zend; ++k) { for (int j = y; j < yend; ++j) { T *d = data + (k-z)*(lay.spec.tile_width*lay.spec.tile_height) + (j-y)*lay.spec.tile_width; for (int i = x; i < xend; ++i, ++d) { *d = f->fastValue (i, j, k); } } } return true; } } { typename SparseField::Ptr f = field_dynamic_cast > (lay.field); if (f) { //std::cerr << "readtile sparse " << x << '-' << xend << " x " // << y << '-' << yend << " x " << z << '-' << zend << "\n"; for (int k = z; k < zend; ++k) { for (int j = y; j < yend; ++j) { T *d = data + (k-z)*(lay.spec.tile_width*lay.spec.tile_height) + (j-y)*lay.spec.tile_width; for (int i = x; i < xend; ++i, ++d) { *d = f->fastValue (i, j, k); } } } return true; } } return false; } bool Field3DInput::read_native_tile (int x, int y, int z, void *data) { spin_lock lock (field3d_mutex()); layerrecord &lay (m_layers[m_subimage]); if (lay.datatype == TypeDesc::FLOAT) { if (lay.vecfield) return readtile (x, y, z, (FIELD3D_VEC3_T *)data); else return readtile (x, y, z, (float *)data); } else if (lay.datatype == TypeDesc::HALF) { if (lay.vecfield) return readtile (x, y, z, (FIELD3D_VEC3_T *)data); else return readtile (x, y, z, (FIELD3D_NS::half *)data); } else if (lay.datatype == TypeDesc::DOUBLE) { if (lay.vecfield) return readtile (x, y, z, (FIELD3D_VEC3_T *)data); else return readtile (x, y, z, (double *)data); } return false; } void Field3DInput::worldToLocal (const Imath::V3f &wsP, Imath::V3f &lsP, float time) const { spin_lock lock (field3d_mutex()); const layerrecord &lay (m_layers[m_subimage]); V3d Pw (wsP[0], wsP[1], wsP[2]); V3d Pl; lay.field->mapping()->worldToLocal(Pw, Pl, time); lsP[0] = (float) Pl[0]; lsP[1] = (float) Pl[1]; lsP[2] = (float) Pl[2]; } OIIO_PLUGIN_NAMESPACE_END openimageio-1.3.12~dfsg0.orig/src/field3d.imageio/CMakeLists.txt0000644000175000017500000000060312271062644022572 0ustar mfvmfvif (USE_FIELD3D) if (FIELD3D_FOUND and HDF5_FOUND) include_directories (${FIELD3D_INCLUDES}) add_oiio_plugin (field3dinput.cpp field3doutput.cpp LINK_LIBRARIES ${FIELD3D_LIBRARY} ${HDF5_LIBRARY} ) else() message (STATUS "Field3D not found: field3d plugin will not be built") endif() endif() openimageio-1.3.12~dfsg0.orig/testsuite/0000755000175000017500000000000012271062644016352 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/psd/0000755000175000017500000000000012271062644017140 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/psd/ref/0000755000175000017500000000000012271062644017714 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/psd/ref/out.txt0000644000175000017500000015461512271062644021300 0ustar mfvmfvReading ../../../../../oiio-images/psd_123.psd ../../../../../oiio-images/psd_123.psd : 257 x 126, 4 channel, uint8 psd 4 subimages: 257x126 33x98 63x100 61x102 subimage 0: 257 x 126, 4 channel, uint8 psd SHA-1: B845142E503E5D91A6C022099C6B897EEEF72259 channel list: R, G, B, A XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) thumbnail_width: 160 thumbnail_height: 78 thumbnail_nchannels: 3 thumbnail_image: (base 2, agg 1 vec 0) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:14:43-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 257 Exif:PixelYDimension: 126 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-22T22:14:43-04:00" xmp:ModifyDate: "2011-08-22T22:14:43-04:00" photoshop:TextLayers: " 1 1 2 2 3 3 " photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" xmpMM:InstanceID: "xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:DocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:14:43-04:00 Adobe Photoshop CS5.1 Windows " PixelAspectRatio: 1 subimage 1: 33 x 98, 4 channel, uint8 psd SHA-1: E99937CC4768F96DC58D9B4F11ED3083818E4D51 channel list: R, G, B, A XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:14:43-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 257 Exif:PixelYDimension: 126 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-22T22:14:43-04:00" xmp:ModifyDate: "2011-08-22T22:14:43-04:00" photoshop:TextLayers: " 1 1 2 2 3 3 " photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" xmpMM:InstanceID: "xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:DocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:14:43-04:00 Adobe Photoshop CS5.1 Windows " PixelAspectRatio: 1 subimage 2: 63 x 100, 4 channel, uint8 psd SHA-1: EB2ED42882FCD4BC1F0E11795B6B3E483158C1B4 channel list: R, G, B, A XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:14:43-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 257 Exif:PixelYDimension: 126 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-22T22:14:43-04:00" xmp:ModifyDate: "2011-08-22T22:14:43-04:00" photoshop:TextLayers: " 1 1 2 2 3 3 " photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" xmpMM:InstanceID: "xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:DocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:14:43-04:00 Adobe Photoshop CS5.1 Windows " PixelAspectRatio: 1 subimage 3: 61 x 102, 4 channel, uint8 psd SHA-1: 81D2828D49B81D99397544651501C3AB9696EF52 channel list: R, G, B, A XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:14:43-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 257 Exif:PixelYDimension: 126 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-22T22:14:43-04:00" xmp:ModifyDate: "2011-08-22T22:14:43-04:00" photoshop:TextLayers: " 1 1 2 2 3 3 " photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" xmpMM:InstanceID: "xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:DocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:14:43-04:00 Adobe Photoshop CS5.1 Windows " PixelAspectRatio: 1 Reading ../../../../../oiio-images/psd_123_nomaxcompat.psd ../../../../../oiio-images/psd_123_nomaxcompat.psd : 257 x 126, 3 channel, uint8 psd 4 subimages: 257x126 33x98 63x100 61x102 subimage 0: 257 x 126, 3 channel, uint8 psd SHA-1: 5A7BDC7A11A9E4BDCBEC968375EE466DE74D0481 channel list: R, G, B XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) thumbnail_width: 160 thumbnail_height: 78 thumbnail_nchannels: 3 thumbnail_image: (base 2, agg 1 vec 0) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:14:43-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 257 Exif:PixelYDimension: 126 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-29T12:10:28-04:00" xmp:ModifyDate: "2011-08-29T12:10:28-04:00" photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" photoshop:TextLayers: " 1 1 2 2 3 3 " xmpMM:InstanceID: "xmp.iid:F5BDDC0457D2E011BF419187EAB8EBB9" xmpMM:DocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:14:43-04:00 Adobe Photoshop CS5.1 Windows saved xmp.iid:F4BDDC0457D2E011BF419187EAB8EBB9 2011-08-29T12:10:28-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:F5BDDC0457D2E011BF419187EAB8EBB9 2011-08-29T12:10:28-04:00 Adobe Photoshop CS5.1 Windows / " PixelAspectRatio: 1 subimage 1: 33 x 98, 4 channel, uint8 psd SHA-1: E99937CC4768F96DC58D9B4F11ED3083818E4D51 channel list: R, G, B, A XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:14:43-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 257 Exif:PixelYDimension: 126 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-29T12:10:28-04:00" xmp:ModifyDate: "2011-08-29T12:10:28-04:00" photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" photoshop:TextLayers: " 1 1 2 2 3 3 " xmpMM:InstanceID: "xmp.iid:F5BDDC0457D2E011BF419187EAB8EBB9" xmpMM:DocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:14:43-04:00 Adobe Photoshop CS5.1 Windows saved xmp.iid:F4BDDC0457D2E011BF419187EAB8EBB9 2011-08-29T12:10:28-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:F5BDDC0457D2E011BF419187EAB8EBB9 2011-08-29T12:10:28-04:00 Adobe Photoshop CS5.1 Windows / " PixelAspectRatio: 1 subimage 2: 63 x 100, 4 channel, uint8 psd SHA-1: EB2ED42882FCD4BC1F0E11795B6B3E483158C1B4 channel list: R, G, B, A XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:14:43-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 257 Exif:PixelYDimension: 126 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-29T12:10:28-04:00" xmp:ModifyDate: "2011-08-29T12:10:28-04:00" photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" photoshop:TextLayers: " 1 1 2 2 3 3 " xmpMM:InstanceID: "xmp.iid:F5BDDC0457D2E011BF419187EAB8EBB9" xmpMM:DocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:14:43-04:00 Adobe Photoshop CS5.1 Windows saved xmp.iid:F4BDDC0457D2E011BF419187EAB8EBB9 2011-08-29T12:10:28-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:F5BDDC0457D2E011BF419187EAB8EBB9 2011-08-29T12:10:28-04:00 Adobe Photoshop CS5.1 Windows / " PixelAspectRatio: 1 subimage 3: 61 x 102, 4 channel, uint8 psd SHA-1: 81D2828D49B81D99397544651501C3AB9696EF52 channel list: R, G, B, A XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:14:43-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 257 Exif:PixelYDimension: 126 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-29T12:10:28-04:00" xmp:ModifyDate: "2011-08-29T12:10:28-04:00" photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" photoshop:TextLayers: " 1 1 2 2 3 3 " xmpMM:InstanceID: "xmp.iid:F5BDDC0457D2E011BF419187EAB8EBB9" xmpMM:DocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:047A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:047A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:14:43-04:00 Adobe Photoshop CS5.1 Windows saved xmp.iid:F4BDDC0457D2E011BF419187EAB8EBB9 2011-08-29T12:10:28-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:F5BDDC0457D2E011BF419187EAB8EBB9 2011-08-29T12:10:28-04:00 Adobe Photoshop CS5.1 Windows / " PixelAspectRatio: 1 Reading ../../../../../oiio-images/psd_bitmap.psd ../../../../../oiio-images/psd_bitmap.psd : 320 x 240, 3 channel, uint8 psd SHA-1: F23185BC048E31BAC6BB4B319E5E5AC570CC7B89 channel list: R, G, B XResolution: 180 YResolution: 180 ResolutionUnit: 2 (inches) thumbnail_width: 160 thumbnail_height: 120 thumbnail_nchannels: 3 thumbnail_image: (base 2, agg 1 vec 0) Exif:ImageWidth: 3648 Exif:ImageLength: 2736 Exif:Photometric: 2 Make: "Canon" Model: "Canon PowerShot A640" Orientation: 1 (normal) Exif:SamplesPerPixel: 3 Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2007-01-18T15:49:21" Artist: "Daniel Wyatt" Exif:YCbCrPositioning: 1 ExposureTime: 0.0166667 FNumber: 3.5 Exif:ISOSpeedRatings: 75 Exif:DateTimeOriginal: "2007:01:18 15:49:21" Exif:DateTimeDigitized: "2007:01:18 15:49:21" Exif:CompressedBitsPerPixel: 5 Exif:ShutterSpeedValue: 5.90625 (1/59 s) Exif:ApertureValue: 3.625 (f/3.5125) Exif:ExposureBiasValue: 0 Exif:MaxApertureValue: 2.96875 (f/2.79796) Exif:SubjectDistance: 3.39 (3.39 m) Exif:MeteringMode: 5 (pattern) Exif:Flash: 16 (no flash, flash supression) Exif:FocalLength: 7.3 (7.3 mm) Exif:ColorSpace: 65535 Exif:PixelXDimension: 320 Exif:PixelYDimension: 240 Exif:FocalPlaneXResolution: 12710.8 Exif:FocalPlaneYResolution: 12725.6 Exif:FocalPlaneResolutionUnit: 2 (inches) Exif:SensingMethod: 2 (1-chip color area) Exif:CustomRendered: 0 (no) Exif:ExposureMode: 0 (auto) Exif:WhiteBalance: 0 (auto) Exif:DigitalZoomRatio: 1 Exif:SceneCaptureType: 1 (landscape) aux:LensInfo: "7300/1000 29200/1000 0/0 0/0" aux:Lens: "7.3-29.2 mm" aux:ApproximateFocusDistance: "339/100" aux:FlashCompensation: "0/1" aux:OwnerName: "Daniel Wyatt" aux:Firmware: "1.00" xmp:ModifyDate: "2011-08-25T17:40:47-04:00" xmp:MetadataDate: "2011-08-25T17:40:47-04:00" photoshop:ColorMode: "0" xmpMM:DocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:InstanceID: "xmp.iid:F410E7E462CFE011B8B8C52D9599FB9E" xmpMM:OriginalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:History: " saved xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / converted from image/jpeg to application/vnd.adobe.photoshop derived converted from image/jpeg to application/vnd.adobe.photoshop saved xmp.iid:52DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:53DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:54DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:55DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:49-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:56DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:49-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:2A93235262CFE011B8B8C52D9599FB9E 2011-08-25T17:40-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:F310E7E462CFE011B8B8C52D9599FB9E 2011-08-25T17:40:47-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:F410E7E462CFE011B8B8C52D9599FB9E 2011-08-25T17:40:47-04:00 Adobe Photoshop CS5.1 Windows / " stRef:instanceID: "xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92" stRef:documentID: "E146B3E37A92795EE3EA6577040DE6D5" stRef:originalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" PixelAspectRatio: 1 Reading ../../../../../oiio-images/psd_indexed_trans.psd ../../../../../oiio-images/psd_indexed_trans.psd : 320 x 240, 4 channel, uint8 psd SHA-1: 3DEA3F342B61B6B2064310C06B2AE23692079EE7 channel list: R, G, B, A XResolution: 180 YResolution: 180 ResolutionUnit: 2 (inches) thumbnail_width: 160 thumbnail_height: 120 thumbnail_nchannels: 3 thumbnail_image: (base 2, agg 1 vec 0) Exif:ImageWidth: 3648 Exif:ImageLength: 2736 Exif:Photometric: 2 Make: "Canon" Model: "Canon PowerShot A640" Orientation: 1 (normal) Exif:SamplesPerPixel: 3 Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2007-01-18T15:49:21" Artist: "Daniel Wyatt" Exif:YCbCrPositioning: 1 ExposureTime: 0.0166667 FNumber: 3.5 Exif:ISOSpeedRatings: 75 Exif:DateTimeOriginal: "2007:01:18 15:49:21" Exif:DateTimeDigitized: "2007:01:18 15:49:21" Exif:CompressedBitsPerPixel: 5 Exif:ShutterSpeedValue: 5.90625 (1/59 s) Exif:ApertureValue: 3.625 (f/3.5125) Exif:ExposureBiasValue: 0 Exif:MaxApertureValue: 2.96875 (f/2.79796) Exif:SubjectDistance: 3.39 (3.39 m) Exif:MeteringMode: 5 (pattern) Exif:Flash: 16 (no flash, flash supression) Exif:FocalLength: 7.3 (7.3 mm) Exif:ColorSpace: 1 Exif:PixelXDimension: 320 Exif:PixelYDimension: 240 Exif:FocalPlaneXResolution: 12710.8 Exif:FocalPlaneYResolution: 12725.6 Exif:FocalPlaneResolutionUnit: 2 (inches) Exif:SensingMethod: 2 (1-chip color area) Exif:CustomRendered: 0 (no) Exif:ExposureMode: 0 (auto) Exif:WhiteBalance: 0 (auto) Exif:DigitalZoomRatio: 1 Exif:SceneCaptureType: 1 (landscape) oiio:ColorSpace: "sRGB" aux:LensInfo: "7300/1000 29200/1000 0/0 0/0" aux:Lens: "7.3-29.2 mm" aux:ApproximateFocusDistance: "339/100" aux:FlashCompensation: "0/1" aux:OwnerName: "Daniel Wyatt" aux:Firmware: "1.00" xmp:ModifyDate: "2011-08-29T11:54:09-04:00" xmp:MetadataDate: "2011-08-29T11:54:09-04:00" photoshop:ColorMode: "2" photoshop:ICCProfile: "sRGB IEC61966-2.1" xmpMM:DocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:InstanceID: "xmp.iid:F3BDDC0457D2E011BF419187EAB8EBB9" xmpMM:OriginalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:History: " saved xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / converted from image/jpeg to application/vnd.adobe.photoshop derived converted from image/jpeg to application/vnd.adobe.photoshop saved xmp.iid:52DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:53DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:54DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:55DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:49-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:56DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:49-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:2A93235262CFE011B8B8C52D9599FB9E 2011-08-25T17:40-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:F3BDDC0457D2E011BF419187EAB8EBB9 2011-08-29T11:54:09-04:00 Adobe Photoshop CS5.1 Windows / " stRef:instanceID: "xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92" stRef:documentID: "E146B3E37A92795EE3EA6577040DE6D5" stRef:originalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" PixelAspectRatio: 1 Reading ../../../../../oiio-images/psd_rgb_8.psd ../../../../../oiio-images/psd_rgb_8.psd : 320 x 240, 3 channel, uint8 psd SHA-1: 44362B2D9E51C40DF8ABF87CC749B77F2D0D9F4F channel list: R, G, B XResolution: 180 YResolution: 180 ResolutionUnit: 2 (inches) thumbnail_width: 160 thumbnail_height: 120 thumbnail_nchannels: 3 thumbnail_image: (base 2, agg 1 vec 0) Exif:ImageWidth: 3648 Exif:ImageLength: 2736 Exif:Photometric: 2 Make: "Canon" Model: "Canon PowerShot A640" Orientation: 1 (normal) Exif:SamplesPerPixel: 3 Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2007-01-18T15:49:21" Artist: "Daniel Wyatt" Exif:YCbCrPositioning: 1 ExposureTime: 0.0166667 FNumber: 3.5 Exif:ISOSpeedRatings: 75 Exif:DateTimeOriginal: "2007:01:18 15:49:21" Exif:DateTimeDigitized: "2007:01:18 15:49:21" Exif:CompressedBitsPerPixel: 5 Exif:ShutterSpeedValue: 5.90625 (1/59 s) Exif:ApertureValue: 3.625 (f/3.5125) Exif:ExposureBiasValue: 0 Exif:MaxApertureValue: 2.96875 (f/2.79796) Exif:SubjectDistance: 3.39 (3.39 m) Exif:MeteringMode: 5 (pattern) Exif:Flash: 16 (no flash, flash supression) Exif:FocalLength: 7.3 (7.3 mm) Exif:ColorSpace: 1 Exif:PixelXDimension: 320 Exif:PixelYDimension: 240 Exif:FocalPlaneXResolution: 12710.8 Exif:FocalPlaneYResolution: 12725.6 Exif:FocalPlaneResolutionUnit: 2 (inches) Exif:SensingMethod: 2 (1-chip color area) Exif:CustomRendered: 0 (no) Exif:ExposureMode: 0 (auto) Exif:WhiteBalance: 0 (auto) Exif:DigitalZoomRatio: 1 Exif:SceneCaptureType: 1 (landscape) oiio:ColorSpace: "sRGB" aux:LensInfo: "7300/1000 29200/1000 0/0 0/0" aux:Lens: "7.3-29.2 mm" aux:ApproximateFocusDistance: "339/100" aux:FlashCompensation: "0/1" aux:OwnerName: "Daniel Wyatt" aux:Firmware: "1.00" xmp:ModifyDate: "2011-08-25T17:40-04:00" xmp:MetadataDate: "2011-08-25T17:40-04:00" photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" xmpMM:DocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:InstanceID: "xmp.iid:2A93235262CFE011B8B8C52D9599FB9E" xmpMM:OriginalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:History: " saved xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / converted from image/jpeg to application/vnd.adobe.photoshop derived converted from image/jpeg to application/vnd.adobe.photoshop saved xmp.iid:52DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:53DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:54DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:55DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:49-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:56DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:49-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:2A93235262CFE011B8B8C52D9599FB9E 2011-08-25T17:40-04:00 Adobe Photoshop CS5.1 Windows / " stRef:instanceID: "xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92" stRef:documentID: "E146B3E37A92795EE3EA6577040DE6D5" stRef:originalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" PixelAspectRatio: 1 Reading ../../../../../oiio-images/psd_rgb_16.psd ../../../../../oiio-images/psd_rgb_16.psd : 320 x 240, 3 channel, uint16 psd SHA-1: E42334B0F0684E3C3BF9125F2920B07C44C17B11 channel list: R, G, B XResolution: 180 YResolution: 180 ResolutionUnit: 2 (inches) thumbnail_width: 160 thumbnail_height: 120 thumbnail_nchannels: 3 thumbnail_image: (base 2, agg 1 vec 0) Exif:ImageWidth: 3648 Exif:ImageLength: 2736 Exif:Photometric: 2 Make: "Canon" Model: "Canon PowerShot A640" Orientation: 1 (normal) Exif:SamplesPerPixel: 3 Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2007-01-18T15:49:21" Artist: "Daniel Wyatt" Exif:YCbCrPositioning: 1 ExposureTime: 0.0166667 FNumber: 3.5 Exif:ISOSpeedRatings: 75 Exif:DateTimeOriginal: "2007:01:18 15:49:21" Exif:DateTimeDigitized: "2007:01:18 15:49:21" Exif:CompressedBitsPerPixel: 5 Exif:ShutterSpeedValue: 5.90625 (1/59 s) Exif:ApertureValue: 3.625 (f/3.5125) Exif:ExposureBiasValue: 0 Exif:MaxApertureValue: 2.96875 (f/2.79796) Exif:SubjectDistance: 3.39 (3.39 m) Exif:MeteringMode: 5 (pattern) Exif:Flash: 16 (no flash, flash supression) Exif:FocalLength: 7.3 (7.3 mm) Exif:ColorSpace: 1 Exif:PixelXDimension: 320 Exif:PixelYDimension: 240 Exif:FocalPlaneXResolution: 12710.8 Exif:FocalPlaneYResolution: 12725.6 Exif:FocalPlaneResolutionUnit: 2 (inches) Exif:SensingMethod: 2 (1-chip color area) Exif:CustomRendered: 0 (no) Exif:ExposureMode: 0 (auto) Exif:WhiteBalance: 0 (auto) Exif:DigitalZoomRatio: 1 Exif:SceneCaptureType: 1 (landscape) oiio:ColorSpace: "sRGB" aux:LensInfo: "7300/1000 29200/1000 0/0 0/0" aux:Lens: "7.3-29.2 mm" aux:ApproximateFocusDistance: "339/100" aux:FlashCompensation: "0/1" aux:OwnerName: "Daniel Wyatt" aux:Firmware: "1.00" xmp:ModifyDate: "2011-08-25T17:39:49-04:00" xmp:MetadataDate: "2011-08-25T17:39:49-04:00" photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" xmpMM:DocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:InstanceID: "xmp.iid:2993235262CFE011B8B8C52D9599FB9E" xmpMM:OriginalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:History: " saved xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / converted from image/jpeg to application/vnd.adobe.photoshop derived converted from image/jpeg to application/vnd.adobe.photoshop saved xmp.iid:52DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:53DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:54DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:2993235262CFE011B8B8C52D9599FB9E 2011-08-25T17:39:49-04:00 Adobe Photoshop CS5.1 Windows / " stRef:instanceID: "xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92" stRef:documentID: "E146B3E37A92795EE3EA6577040DE6D5" stRef:originalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" PixelAspectRatio: 1 Reading ../../../../../oiio-images/psd_rgb_32.psd ../../../../../oiio-images/psd_rgb_32.psd : 320 x 240, 3 channel, uint psd SHA-1: 63CF8F7B010D24EFD3C41F51C16D8D285FE07313 channel list: R, G, B XResolution: 180 YResolution: 180 ResolutionUnit: 2 (inches) thumbnail_width: 160 thumbnail_height: 120 thumbnail_nchannels: 3 thumbnail_image: (base 2, agg 1 vec 0) Exif:ImageWidth: 3648 Exif:ImageLength: 2736 Exif:Photometric: 2 Make: "Canon" Model: "Canon PowerShot A640" Orientation: 1 (normal) Exif:SamplesPerPixel: 3 Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2007-01-18T15:49:21" Artist: "Daniel Wyatt" Exif:YCbCrPositioning: 1 ExposureTime: 0.0166667 FNumber: 3.5 Exif:ISOSpeedRatings: 75 Exif:DateTimeOriginal: "2007:01:18 15:49:21" Exif:DateTimeDigitized: "2007:01:18 15:49:21" Exif:CompressedBitsPerPixel: 5 Exif:ShutterSpeedValue: 5.90625 (1/59 s) Exif:ApertureValue: 3.625 (f/3.5125) Exif:ExposureBiasValue: 0 Exif:MaxApertureValue: 2.96875 (f/2.79796) Exif:SubjectDistance: 3.39 (3.39 m) Exif:MeteringMode: 5 (pattern) Exif:Flash: 16 (no flash, flash supression) Exif:FocalLength: 7.3 (7.3 mm) Exif:ColorSpace: 65535 Exif:PixelXDimension: 320 Exif:PixelYDimension: 240 Exif:FocalPlaneXResolution: 12710.8 Exif:FocalPlaneYResolution: 12725.6 Exif:FocalPlaneResolutionUnit: 2 (inches) Exif:SensingMethod: 2 (1-chip color area) Exif:CustomRendered: 0 (no) Exif:ExposureMode: 0 (auto) Exif:WhiteBalance: 0 (auto) Exif:DigitalZoomRatio: 1 Exif:SceneCaptureType: 1 (landscape) aux:LensInfo: "7300/1000 29200/1000 0/0 0/0" aux:Lens: "7.3-29.2 mm" aux:ApproximateFocusDistance: "339/100" aux:FlashCompensation: "0/1" aux:OwnerName: "Daniel Wyatt" aux:Firmware: "1.00" xmp:ModifyDate: "2011-08-25T17:39:38-04:00" xmp:MetadataDate: "2011-08-25T17:39:38-04:00" photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1 (Linear RGB Profile)" xmpMM:DocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:InstanceID: "xmp.iid:2893235262CFE011B8B8C52D9599FB9E" xmpMM:OriginalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" xmpMM:History: " saved xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / converted from image/jpeg to application/vnd.adobe.photoshop derived converted from image/jpeg to application/vnd.adobe.photoshop saved xmp.iid:52DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:08-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:53DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:54DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:36-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:55DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:49-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:56DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:56:49-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:57DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:57:01-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:58DA7E112BCDE011A998CBE7B5CCEB92 2011-08-22T21:57:01-04:00 Adobe Photoshop CS5.1 Windows / saved xmp.iid:2893235262CFE011B8B8C52D9599FB9E 2011-08-25T17:39:38-04:00 Adobe Photoshop CS5.1 Windows / " stRef:instanceID: "xmp.iid:51DA7E112BCDE011A998CBE7B5CCEB92" stRef:documentID: "E146B3E37A92795EE3EA6577040DE6D5" stRef:originalDocumentID: "E146B3E37A92795EE3EA6577040DE6D5" PixelAspectRatio: 1 Reading ../../../../../oiio-images/psd_rgba_8.psd ../../../../../oiio-images/psd_rgba_8.psd : 320 x 240, 4 channel, uint8 psd 2 subimages: 320x240 320x240 subimage 0: 320 x 240, 4 channel, uint8 psd SHA-1: 9E23738D347D63EBC389816944465963005C801F channel list: R, G, B, A XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) thumbnail_width: 160 thumbnail_height: 120 thumbnail_nchannels: 3 thumbnail_image: (base 2, agg 1 vec 0) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:07:44-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 320 Exif:PixelYDimension: 240 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-25T17:39:28-04:00" xmp:ModifyDate: "2011-08-25T17:39:28-04:00" photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" photoshop:DocumentAncestors: " E146B3E37A92795EE3EA6577040DE6D5 " xmpMM:InstanceID: "xmp.iid:2793235262CFE011B8B8C52D9599FB9E" xmpMM:DocumentID: "xmp.did:037A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:037A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:037A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:07:44-04:00 Adobe Photoshop CS5.1 Windows saved xmp.iid:2793235262CFE011B8B8C52D9599FB9E 2011-08-25T17:39:28-04:00 Adobe Photoshop CS5.1 Windows / " PixelAspectRatio: 1 subimage 1: 320 x 240, 4 channel, uint8 psd SHA-1: B29CBBB9F277EBAF908C46680F7D2844115DEE94 channel list: R, G, B, A XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) Orientation: 1 (normal) Software: "Adobe Photoshop CS5.1 Windows" DateTime: "2011-08-22T22:07:44-04:00" Exif:ColorSpace: 1 Exif:PixelXDimension: 320 Exif:PixelYDimension: 240 oiio:ColorSpace: "sRGB" xmp:MetadataDate: "2011-08-25T17:39:28-04:00" xmp:ModifyDate: "2011-08-25T17:39:28-04:00" photoshop:ColorMode: "3" photoshop:ICCProfile: "sRGB IEC61966-2.1" photoshop:DocumentAncestors: " E146B3E37A92795EE3EA6577040DE6D5 " xmpMM:InstanceID: "xmp.iid:2793235262CFE011B8B8C52D9599FB9E" xmpMM:DocumentID: "xmp.did:037A91A22BCDE011A998CBE7B5CCEB92" xmpMM:OriginalDocumentID: "xmp.did:037A91A22BCDE011A998CBE7B5CCEB92" xmpMM:History: " created xmp.iid:037A91A22BCDE011A998CBE7B5CCEB92 2011-08-22T22:07:44-04:00 Adobe Photoshop CS5.1 Windows saved xmp.iid:2793235262CFE011B8B8C52D9599FB9E 2011-08-25T17:39:28-04:00 Adobe Photoshop CS5.1 Windows / " PixelAspectRatio: 1 openimageio-1.3.12~dfsg0.orig/testsuite/psd/run.py0000755000175000017500000000045512271062644020325 0ustar mfvmfv#!/usr/bin/python imagedir = parent + "/oiio-images/" files = [ "psd_123.psd", "psd_123_nomaxcompat.psd", "psd_bitmap.psd", "psd_indexed_trans.psd", "psd_rgb_8.psd", "psd_rgb_16.psd", "psd_rgb_32.psd", "psd_rgba_8.psd" ] for f in files: command += info_command (imagedir + f) openimageio-1.3.12~dfsg0.orig/testsuite/texture-icwrite/0000755000175000017500000000000012271062644021516 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-icwrite/ref/0000755000175000017500000000000012271062644022272 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-icwrite/ref/out4.tif0000644000175000017500000035570512271062644023710 0ustar mfvmfvII*ôØö þæî2F=RS>¼Z2013:07:03 13:27:35 €Hwø•‚  t = BÅ‚”-EVBÞ‡Ä-ÿ B0² õ H¡o¸C¾à„6@ Œ„ó‚¸Þh™€AP¹âC8BØ0„,-© B"sA„"«8BÜP„!™¤Í(à< 5ÂÌ…¼!OvÂ#ôh@„¡ÈBjc{Â,`X@¦p„6¡ ¸( ãtœá|lVp$„ñ¬¸@oH„±£,h ¥Æ®ñ¹  ¦zãVØÔÎ6¾“1º-lŸ[[Üñ§˜( }gqPœ]ð ÍÅân³@"ŠY‚ÜUÏgx7Á@¦^ÊÄiì³` e„£‚¢D~³ü˜õÛ@wïÛHú  h(ZÀÁ2 È(þ€ZŠ‚È(|  qЂ‚ ˜"  ˜‚‚‡¢ v4À6£˜°€>Âø‚¢h(]ª)L ¡ìRF`¹ƒÊ)죀‹Žš$ ú±&„ô@¦r„­+Ë̵-Ë’ì½/Ì Å1Ì“,Í3ÍLÕ5Í“l¸0 ÀÊ j¡o2p!l’p¢ÉŒ€¦…jë&‡#¢!jh‚'zð§Z^!:4°I©À' ®šãêpƒ©¢XœRÉÚAŽ„Tà„ô:Å[&hYÔ„ìJ'¡oø¡]q@4’iY§!û „C©Å‘e6`Ï'#1ªÊq' pN£ h¼„«½l6)Å(ÖÝ ÁÆÑÊCÆ“èDÖÞ ÈÖÚ k–œ)íjÜ2ÀæÆƒìi"ÆÔàèÆÂ.⑸Êú·pí·ƒ²8·»qfŽù(쑎Ⱦìßà(ìñ)²©ˆÐ(xº 2Ž2€ ½?c“íV¿w cIåÏ\AlÄ"¢kàpÌL†Z †DH , –‚“ë Ô  ü0[hMS…Š9¾» R¬1ò \ÂBŠy¨à*ŽzI 8£ŸÊ: ÊÊ”©7sœï=ÏôEÑô/81¬õršB©¥ Ýi¤õÕ¤(Aô…ì)Á’…âiÀ¢…†¨Eˆš¨EÉ>€'JI!ºhxÖÍÂÖ€:ÐÑ£šhCŒIÁª§jÈv”`7!º´„ éĆœ(YÆ„h@Ú„flŠdhAˆB [!œ„ìË»wE±ÿ€ÄB ! gbcZÂå~ÏàÆª+Œj‚'ôÈ DcS°>´î“„‚€‰»1­ µàÉhØ1¡ôÆ•pGMh¦1¥4Ö±–TˆÉ¸@F¶›&qAéÅ6PÌq_˜†Ôܳ‹Gb-<AYÙ@€ÀÈ(«gŠ€PøzÕHŒÀ)Ÿ`ê}àŽh¼ ¾–à p(¡ÚÝÈ † ­P©À‚ñ Ð&îHE"±€…N¤à ( ”¢‚¥N8äàœ.ed‚„Òæ/ 8E#ì£ËÃäH,Á5©.b9W4•]4É™S.fLÙ3æ4  4ˆ¼„øˆ ¢Þ' šBp5ˆ\:'ä67h¸€x!fèœ8’Ë„ ZhBÁ™š¤0•þ•F°+'€jR`'P„. JIÁÂ' p2ª B ´,rp±pgÑ$,o„ êéE4â bhF1Êà±¶Ðo +B _Oåq6D€d!—šÑgF jr'pÆÒšcF¹&1 ¶• ~c`4Ç€"ºk_©­æµ¦6”ƒ8¤ÀÖÕ³pÌMÅ 781spä„©Ù‡8p|ZgÀS€AzvdàŽ]»ðgQ¸c±œ ž¹´aãF©@fy â¹û^ "( ˜*£Qœ@)q¦˜Š‹_®@1±€Úf{€ë’P%'; êa¸4Q@âAP©Ç,œ?PŽQFÚ2p—1îQÀYG:jeɹw,ÁG˜óFö^ÛÝ{ï…ñM¡œ:ð>I¢µTd.l<ƒô+pDy褢à ê&Œ<œ>Ðîɤƒ2šH×hê’wQ ú“ŽR3èPÁ$œaN/&€B—”ZP’é<-5|ù²B98>dá…€2¼À*¬˜bp¸ ÀI¡¤"ŽXrqO ÀÙZnø„NÀŽÍ1Åp„2 S€V®N¬;rqQ@ó! (œÚ®kT2ç1°¬¯ LiaÎæ§7€,lƒñZ  '£hµ ±è‹,nJ7  ÜY¢€¡8³hŒSŠÍ+e„ ó²j ĶŒõ8~AŒ¿Æ`áÕ Uš©+V®@(—!¦Æé’LÏ;qn›; êMraTcÀ*z6Ü î¢  BBJ\Öná&p$, |F4(áZB|E!Æ,&„1¢Šr¥m †˜B@½$¢áî-0EpH¾@Ø¥ˆ+b " $ø@Ù‚ ! ²¥êì¶! ÔæÄü,d6{b=¢hÆÀŒÀÇ XNÊ)Ȥbpöe¬æ¢Æxê< ª.Zlž ¢h%8)âÀÅn¢eS"!ÞÅâÌ!²$¢qÈ>! Ä*N,pžfãZx`dޤ0Þ,`h!^Ê„ŒÈ,nvÍ€²¢p²`ƒ›bJÎ,e”L¤¬Cm a 1Íïp1¬ÌBü7 PŒg†Ko`zp9¯n‘  @=´Ù€€¿@ ÚY@pê`ÌP«.yÀ ›€ ©@ w  §>Ë2Ï´?hª?lrí”6dx`° ©@‘¢†Alj8Žž®ÊÌÌÛÄ8\ÁÆB&m«Š  ,\€0¸ÆÆ¤``‡Å%É`e ¤ ä`¢Â"ŽBŽà‹Ì ¡òá¾½ ν" ½pK%òa&2dM`Üæ&ª ð,0&!R!fïhÅÎP³.ìz+n-‰¢pÖÑž!  /¸5®· âF!cÔ'î3¢¥r.¤"p“‹Ð(!¤p '‚"pLBåÒx!”!òÈc2!mmBE*:!œ!û-òó)êLŸ AJ–! @5°Þ7ÀÓÅôäã~âq.¥4! 5£Y V!z%Èñ`)cXÌ2éÃbhJÆ1Õ4Š LPüD NL†ãŠêð65­ gZS7 d5²z9ÊÇ`Ú €Y@P€ýÀ´ ÃÃqȵ8 ê«á(Ò€?@^  À(ÎıÀ CÖÿ6ÊŽhÒ‚?sà?q„ï¼éÄB˜&Ú%â&r*PO@1à, ( d@“rF §ä ¥RDR…NEë¨pâ\ÁÝ@nànp~,!n(§”  ~p¢B&(® Œîán¼îJÒ]&tHô‘%àâî\¦Äø,d ê, ±2ú!gÌ¿›€^ ¿ñu+2°,iÜÊÆ@o¸!˜t¨F!l2‘1Rˆ,iÌ„’ ¡ ÁÈàO,l W ÌðÐÙj³E*àTàíQÔ0ü"®*9 Àéàˆ€å:Ÿ¯¥85ª,äÌf1²äï’~ØSJ1¬0`=ƒZŽãZYŽB®HVQc`yƒ[W¥¸¼£Z‰ó9JÒ¦#qT ÎÍL®#Šƒ 7€0`pM>;!< ¡¼ý  Ê”•l‰¼µ¸‹BÞŒèŒõÞ³¬r§bÐ)+¦3_€  ýÀ´ ‹€±ÀÍF¢Tàkˆ€F /ÔjyI(¬ ^ (¡/#eN¤‚®LâŽ&Ú…H°pèPÝAöH há xp®E,¶ ª@ ¡ E'ê ¡ø(µG¯O©„&‹ÓÀH´“iö¡j)–aÚ¿Q0˜• œbìnØ‹Âh¢¤Ÿ S2—kpËËôŠ+Rø/ÃÊ/b î'oâiY€BƋ Р¢h  ä'!$ƒÈ25Þ(Ä$`1„|å¨!u+`ÒÆJ2†ˆ%«r"g"p_¢q`ËÈhuí˜L„ÂF,mìa1±W5sNu„J€ØxjìS-4•r‹Š¼1¶ø5©¸CXjéW/¸h„5¶ˆò(Ès˜Â9"ÂlmecŠv ¶ ŽÕA‚€ ²```Í€OMj;%VµJ¨¦Œïz®üÅR¡†=nüê¾ÏÂíˆà°@kFØÐ¨ lT H kÀýÀé°¥ÌâŸè€'fh ¦Úåã!" fÚ¨€•B È€ƼŒÌ%È $ "ÂäS*À©r¼F†(à(áð(à(áø˜°ÎáÇ7jXÁŒ8ÄLÀêâ'J‚4(²¶,œJæ‡X! ð&“S­k \@ë0žÒ@Tµ0’±8à @>õÉ‚ãR¨! *”!R¥õ!mŠP|À¼Ê ¡ pf„ãîÌ! ¦'Ê8ë/N|’ý3îõRéÕF›@2 ‰9£49*' þÎ `à«7zÉ,ú,j²³ z ‚cZü·”žƒ‹W3‡uÀ]ñ*1¯¤uzrOÂMTss_‘~8±nîàg$±` Y€i‘zµÎŒ@ #þ†¼‘Æ¥”ü¬µ¢³$µÞ×XÍ4hÏÜÓ6ì ÊÆTñÊ.Õ@„–AfDX8©FÀýI‹ôØJ¶áhZ¡,aaÐnà&\Ç‹ ÂÂé8BÃ!†êH!òÌÁaaÚ, ^( jp.H!>¹ŽÅB ¦" ‚Š?® «Æ‹BŽG$(ôiPÏiØÇ¬ºÍ¬ îâ²& ©³%L™LšÂ¬!y—RÅt!·MÔà3ŽX:î-3[*çYîtó‹U, i€ë9 –‡óSâËÁü(! Bpa&'žvÚ(9isp”\—-B9,y5"pùW1.Á€N‚pÕ@3¨›w;Z!Ò«Bå›|5©Ìò7YR.øÐ·SQ„S´UW#ÿWƒ'$P€Ç ¢@ñï`€FÉÀ`-„jŠkbhDoI" AŽ&ªü i€ ¦4;5ø—¢¹†œi€ äÀ ­€ YˆìÆæ  KŠ˜¨Ú/PP†Fîp†…¸¶,8¸j‘¡ˆ› z“¥ÈŒÌ¦ô>m 6Tà:m¡üTáTá¾kÉ\ ²Ð  lBn(á˜(  (¡à,!º(àBE8® §À ´zO°5i4„,V™Í|Ýì¾Ìš#4Oîz0†$ò4"ªŸÇÈ‘ ¨  aŠPÉ«)3&’ö[NE Öð·ÐëõQñ5Q@tàׂqÑ”Á2øÍ 'Þ™ThðÇ3`Œe(f¼4½2Ì|!\7ŒU5Gu?X¥nÚ1´§ÖLp1¹#¸>ùW?S™'uX#] KKyˆP1­€W§¯2bQT’`ƒ ã@®½æñ``à˜ÀÕ\ ¡ß[à†¡|Êðàh ž£pøOŒâ‚® Q›ü_Aˆè ”an¸Zš*ÂÂQTT™šb¢ÈókljrUü”_¹¥ÁùrÎ $Ao™Ãî rÏA°@h>±A¨#¥ç`'Ä&ý‚@P@³ÚÁU`t X‘óÀ^Ê¿ ‚êÈm\ÕTp ý\×Ö! å¾Ã€0G¥è!z}^€w èz‚?²w¤ é•ÌçôI¥ÓiõV¯Y­×kö–Ïh>«e u™É±7ËÛ3#|ç³7Çû6ìÂsrYNŽù³¾7Y‡Ûâ†øMfïºVf÷'|µ³\9 Íðß|]³·Îï'7Í“ôe|ëhk¾<,Å#|V·Ï»Âè7ÀK|3„NiþD¹¤¸šæŸL‹ñÂà(ßÍñ”ßè ±BÌóš7ôB7ÈÛšY7Ì8·ÃÌB3·ÌKšpÄ#ë|xD$¤CÂà(ƒ€ÿ$F²B æ§RCÝ$ õ"Ä$ÜC*I¨2As¤RC LD$ÊQ-5 ³T¬$ÍELâ‚ #ŠSSTV‚„ó´½ ©J DÍT'¡z9!qh0¡e²e¡>Hq<…¨”ÔƒMP 5'MA 3Õ""< $´ð&õ”=Y‰r$ImvU¦³ õ`ž¸Àü¹’@BQƒõ8žˆ #‚kh(±MÈ /f€ÓÐ ¹à%ŒǺh¬AEP)@` ŒzN-¡"Ä%0廞 ¬GÌrÇ Zô~¯GÜ ‚,̳£ƒ³ìÛ:Úâx¦+‹bøÆ3cm0þL†8v³ ñ¤ß^lË󔹫˜7Äc|,Êkšh,Å{|]¸«0m˜7ÁZÍÄŽ››j9µˆy7Éš åLžT°à ’ßQìÒæ‹ð²ßz“jÎn°š­ò æŒ­ðÄß#.iüÊ€&€æÐxh.h:ßdŽh¾ßÒ«|`·Ãã|Þ¹£ƒ}¶IV¤ÊpòA:ß­ð+Âȇ‹}6I|AÄ7”ñ2A'•Jò@§Ç YÕÊÝ”#s`Å/irB/2Ä.½'u€/’3Vc$sVo/i॓¬üÈÍPä½JËÇzgÐ $Èt2óê-@%àÖ€$üY)˜…çhpÌ…Å(sO(s·Mò*HòJÊ5TJ)Œ˜ ”mU KÝ‚@,—Rj À¼&¥´„¤ÄÑd y#€DvAk!ËÄ3Š‚Ûˆ.E!Ç(‡%° sÀ(J!yØÂ* ˆ®rÒI@ À;XêˆBG`“ÁÊ ;ʾMVø w€-µÊî>ÔÈ®â‰a€uàÏ@¦D±&jÖ.pÙnØ(–’0èÄž ËÐ/9âì± DrY@?0âÁH¼ŽG¬ba 6Ò^M±È$i¶womýÁÄ(ýgÀ€0sF±fÆùí©£}uið2eÎì^Hsd8ê,ÁlßbP4Y·±”ß  zQÁf8ºù²rÌ\7 š­Dæè›€ á* Ĺ.A 0%7ÑÌæžŒFÔ¤xq4v³š'ÂLÕBÀ Gª`Î&•¹Ã!ßLè@Ž©Íu ʈi75@À Ÿ%hU¦?« 9¤ŠÌt7«3IÄO¹•D@ùÈá.€:î´f 5€½ ã—8ß*‘ ¸²ì/³“x Ë ›4€ ¥*àÄøF츠†è³#Ðæª   ¸æ¯8¤¢YIᣀ 8hàjâÊâ^¥ë»€ ƒð¨Rëš(?¸Óz «Ëy©ëÜ€Dƒ æ„@>Bÿ¹¡+/àÁȱªC®Ñ+0Ä`š»Jƒ9$1¹'y™ ŽQÚ t€R‘ G1ù+à)€ø)` Ñ/;!+7 ¼Ô“SÏd;NÙ2Ù5=0¤(¥É/C!/L°”È,Sq5Ø3h3à‚²X'¸‚»ðº¸4°ª€‡-è‡ùõˆ¬Ø,`(Š—06QTÁ=aTŸàË Y); 0ª0Œ8D]¿ÉÐ|G 8QËJˆ +Ô€HŒx‹ÐŒ8 +¸ ÉÐ ¡  x šÐ–øK! V7H«Ð•@Žx‹šHxôYñ Ð‚P¹€ôé†Ñž0‚±€kjˆ«üÉ:F˜j3-:4-L˜R­+R¸ÔºL/$r€ €í8øæŽ@ÉËcpŽjN@Ø;À³‹pù€ ãPÊ58Œ¢j W𨳠•‹Žô #²XÓèšðæ® ë¢å-»Á€ =¨˜=EEš•H©ÝK˜ß8uF ó½¦"fËü?„ æ‚À./lÔ/ZjÔá ôòª³¦Ïà»90ÎÓ ðÜÓIÉÕñ¬V9$1€c¨¸31T“AÞ ½«ÆXÅ$L˜’`ÖpȪ€“T M©5W€"ªõ|€!o€!ZË!Ú€$±€!.€(!ˆA÷àØ ¡Æ‡/ ïˆ\єѮÕ22è€1²4í9ßjÙê‘­™è6€­Ð hN‹PO+ùTú2ôƒ¬Zx¨½ÐçØ½P±!Œh‚¹†1è‚*‘8šËý[sý–KleºdR¦Im®Û¨H”ù ˆi¥]|¯µïk%Éæ‡€ :ÍÓxæ•@^ ©ð–ž ¡±kæÅ²æ]è³\µÜ£³t€ ÀŒ¥Õ¨¾R0ß3¥Ñ ôOå©ÁæT¯ïRï̘îa®¹£² ß\S¤ŽlÆ^°ß‚€Jr‰¨æ€m%:`ßJû©¯Æ‚œþK’Dh>z%hA@±1ù0§A+ACµºã±´FV`TP/oéç“V˜WŽ“Q(”ÄÅK 5A0ÄøWš—"»€& IÐXˆØ š8BPÔ°Î@ÊÀ»¸ª6”Ôø@JK ׈š<üˆñZA[b’Ç(è CÀžƒ] hàD=d»¸à3X”ÈЀâÅ 5Ÿ+Á”dÇP $ P€N6ya€ðôµ¶9(eÉs‹P~! ‹Õ ƒ¿ˆô¸ç΀žŽx}Œ8‹™Ò{ÿ¶D¸²ÒŽ‹mI^Úm¿dvHÓ@ø#²hV¢M808ß@ëƒ òŽJóîÉéÀ±*k€ä #€SŒ‘!Ý`ßO2sš‚¬p ß=pÐEOi'veo håÿw{š$Yí€pJÑ'$îe#ë%€£e B ó‘ < 9t®P €¹$0Fh*‚Èæ¼N´ªð$PáÈo”‰éŃˆ¡$nZ­hlÔ-ÌÕ‘–DøK mUlîÅ÷q‘©ó±E)ß;æ2‰5y° 0ÖìLSHÉÐòs.(„E«Ð.xrb£ Ã阄.xÏàOYÚ€*ó€)í€-“)T4F)S1¦€1¸3Oª§ˆñ:•L¬8µDr€A¸@µH±Kñ€LùW¯Q—€G«¸w›Sà ëñ€oD@ ÇP&¤H q”•t¨Ã€¬²‹…!£„ÑoÇp‚ê½@¿ ¨ˆ ‹ÐH‘Èl—0‹P PyøV@˜ Æyi‡r1E¶`vCØÌdmº­We.ÛR…%é”iP³T.ZxS' Óösu$U8•Yˆü)@€h C ÐØ@Áð•4%[ zâ0øHâ…„‹a*øJãDàÃxJ4„¶á'hJö[ ¡(ˆHΧ„ž!/ Ü {1„¯!(˜Kú•ªRŒHA/Y€UZôI3J,ÂY4£Ì%™Jœ@Ï•;…†k¥)Q[•yU 2\kô¢ý)¹±n'¤ q¸€ç„ºQë;¥ pœ$ñu„‘lL#ßEÂM³Ô,ô@ŸÂà@IÖx¯a6 &‹pÎׇ5ó ÀW^ü_ºõÇ;Å>ñUÜWÿ-9¸²`éÔ1€;&£æ]øÎ^7Ž6 @0 /½½àx+ z DStP›HÀ€Rã€hFÊÁp¨  ÁÀ›t ÁÀ¡ôÀŠT<@2üQö°€ˆC€8ÇE0nˆAÉHC%¨€†ˆ¨€Y"’ µè€ˆ€ /,ò@ïôÍ4LÀÄ"s\á8ÎSœé:ÎÓ¼ñ<ÏSÜù>ÏÓý8’‡øŒ¥Èû¼|!([¼L!-šA ÀÒ“3%°p½ d ÃR+¡ ”ÊÆ(4¤Žô¯D2Ò Ú$!2A!'-J° *%!-r; Ç=+CÙ@š˜¨½d×Ð2æ cÚ”tÚHKæ¹jõ­(Ø/öª:® L. cñ¯@µP¥VÔEÏC€J‚À«ÀÅÖžVŠñ7s ªPÄ¥+òxžBà¯HÜJ @ºÎ¼Üà8¯Ìjú¯Ì#¬Ô©G“2ÂJTªÏ.Ìó°ØÙ3pÐ3Ásç³Ù b†C ^7ƒ^ µáÓ_h·’âÖM⫊F¸¢;ŠÈjZò$¸¡ ¨I:‡‹¨4ºˆ¸Œï°ñ•laÔ÷/}a»¾‘q›× ˜ @‡t j๰ Â@ZÜ !OC°à%‚H€)‚ÎVF„¼\FòÅÁ H KS™á5ׄàkVZEf¿^(¢œ– A2 xV/ ^|^ˆV~¬ÓKNi7Ð>ÿÁðü_ÉòϤ±¬ ˆ1<„•(4/-#À„±ˆèïš%#ƒ¢HHn!/íí=å™ dÈ´¼ýÀD!(¹eøB`D%E8ºñ>UÃÌ„ˆ²È4(è„åš@É e «Aâ8B]xeà•7@ḇ ±ÂҔ׈Ó k1W!À@!"”¥å\ööK Jˆ¼CÂø, G2Úà2Ey€&Ä[˜bëQ€õ€(r¹ÀNL¾>¢ˆ´5 ˜â”ýKÌŠ+Ñ$,@u3ÌYš!@a 34j Ï ó ×0’0ÃbLóF7Ï 3^x À5ðŒ #^/Íx'5áDâ‚“^-(Mj§Q5$JÔ…!Ń Œ€d8—àSSHñšFÓ3[JþèДCØÏ{“0 ºð Äúætx DÜÀ[1ROtVQXG@9S€ð†¡C”H€IS'^ˆIÂÁ dfXb uËä8•8#u㤈åNx2IÀá'uN^È=V € ×^6A‰%ž5`=àÑzõ1ÓÒP[Ü{Ïš¤Tš•Rêb:&"‚QŽñÉ hRÔµ ³ À+ªïÌ’Þ@æ1uð1S™`":­- µ [Õò¾g@i•Æ\´Y2‰k`ÐBAòÛUÂÁÊBBY&`ÍÀ®ˆ°_*ùV€&@ÂÁ\ÄHv–´†± ˆ¯A@ÂpP+϶ÒYf4áÙ^èK"¼¿—Ê+Ë}}é@† A-1ºÒW¦^_ŒlžC{±L c0—T(S=¤på)™ãxn až æ6F&g›¸&e³Ó^È@V7f¼”‹*Ô¯³KœZÌX9¸cíJù€Qbu°Ž`u“P[ki µ€b2Ún˜ˆ`"npÚ{ÊAìd !—,]£6W•XizJ¤V(f€1šRªàR{ˆ;Þg¹¹žG@ \šýXg®qžE`–€I,ÖÁ¸˜†âÒ›‚ nñ¯W«€MäÔ¶xˆ`PY0n˜ÞÇfªvé@4ò;3xFß7Om0Œ1p€EÕ0„L±•Ä+%Ò¸‘7P#žô:©ÐiÞÔ­Ü’†¢ @EÞ9쀸TâVp(@€Ò§cÑÔ‘lŽà"M h •83B€Ý §^6ÐLBˆ” r!eH×VNŸy-˜‹ŽŒÒ)m2*‰ONõFÓŸô~š–ÁkmZ tMo€ù¶ˆ1ç {êªZ'n9 µ-ˆ"H0k€``¼âЇ&ÔÎ g,²-ð¾`7Mb®0,¨è cÊ„€DƃÞÚ¥È~Âé­bK …6!. 0 ß úa Ê!&|ÜÀ–Ž†Ë€j…¼]a6 "¼a `¼böf4"Nì“C"Tbü“°£ ÂâÚ Á8)GcJÖHÖ{d)J¨Nz”ÆR+ÍÆ3Á€)F 3΂œNQ #= fhà½C?cV5äVfžŒr3̃(7n7ã^” èÒ€¬˜£^U  †¤ìë¼jP2¨ ¨ ÀÌ:‰\ÀÂ:‡xÅVí€L#Æ”ÃØ2ÆÒªÀX€C€j AÁ8REaäÀG@½ = fJŒ¨„\¬ŒuàÉO,N('^f"û ô7A(Fæ[ 0ŦŒFIìÄœ :"\"D™`Xw€`Tçr A¼wR„ xuàfVh"j Aì5DœF"zrÑ"ÀûÀ û' Ñ­"ÑÄÌüÏÕ#3#Dè €'Dçø ÿBaü ï…«!iXqšg…!À\pB£ñú£…“ag(pž Ç€2@¡…¾c°à”,ã 2Bßp´9E9Ìi ´9 TÂÔ°·Å.e2ÂÍ >žªU©`ÈZ"Ò›Ò*½- .BЀfÅ]"Qû$}étABÓB|.QJµÛmnðd}D‚µ›ÍØšM²Mµ¶.€ë¡ê"º®‘ì´pº¡×½Ñ tK]Z=¥­„„ó–¼õ­%¹sm@hû¡s£.€½Í.îVÜ}ËwrÜ­7.H@±¹î]½Õ?t—¹³‰ÞèϺÂîš;§è@Ýäú¬û¡«/êh>¥º* 1dú®ÐL/`8S‹(@Àâ,,jBÎÀ4ú‹£ày¡;f ÊºÀ5H@µˆ¡iû ŸH@¡yá$¿€"IÍh I&†€ê„`wÈ@0{!Ôrh8ª @! gÎ$!²þÓJ|°MK„ê%N¦¤ oËÒ`jËÂ<~¦J<„!¢<£ÇÒBÅʽB„ÔhH@D ASU•m]WÖeYÖ•­m[×Íu]Õ„è`( ­ú>!Î">W!Ò[!Ñâ?a!Ú/Yi ö”Ê‚;!b2^¤¤VcRûè…iò&Ü,Pk¡cÚ^!`²À£âš¬ÙlÒ><¡eíÁ £ö0¼ÙfÊ;¡eò–®h)g ´…˜·Z££áûkq1ˆ8.‹èR!m;ÒÜ@T…Êèø‡´‰®ºAV­d ˆâJÖù-vÎVÒ&’룦ʉ„ƒKjÒ€MzÖ.‚V®&.ƒžÒ‹¦^ç+¡rÜœ«¤±®‚ rf·7J×€oÓŸA9æúÊ8Ü¥V(ç‚íËnõpnx¨î“îèÞó;£Ãºe;£ ºP;¼( G;®ü (¾±D >·Ô >¢ô€A+è ÐA"¬•A;8Ã0·µÊküšdA( ¤^xÆéÔeÔ\‹ê1Ó˜’Í@iù#N w¶Ï`„Ôû`’=+¡¶hñÕ5q(@3j~ð8™J…5äÔ#Øù{`±éð©^s„ m¥Œ@“ÞÄÀ!­AÀG€y„À§QôL1Dx|3R’¨JITª”„ª…T¯!Ä9‡PîCØt'€R!ü½pá@6Z¤mp-@ܘ)màÈ‘õBGAK‰Á$‡ò 2M €C˜_ÖDµLRà\àÑ‚¸×q2K½ÄK™|.쀙 ‚vˆùé,š<”±b]é R Å&PGÅy ¥ÑFàÀ‹\B#é`EÂ>M‹X$!aÐ…Åv±%CˆP#âØA–±² Zƒ-XÀã2¹³⵫šIHßÁ-a¨º‰Šndp¦”É’Ö É.-oxódn\ Jc Ü–×1ÏjgªT4ª×Ïy'ªn;€Þ€[;¯8°6Žéo=@Üî›Ð íQƒ@ÁÌ yP1}¯Ì‰¿,^A.Mƒ„ ãm¸P<@;ãCàa =”>±ù‡N¸áܦSh yÈÉ…#%œŽ ÕYÀ1•Ê÷âBHÅx2 öÀƒ×%x¤Ð&F;óoxr?†T0{`q:Õø)P +Â1*˜ ¡HéÔᨵBut¨"²¡f@0dxl?Äê>Ö¡Y†JuKÂà?LR˜&0Î7ªØlªáõ™³VnÎY¡@?—гÉéQzáp/b?G UÍk˜¥Ú¾ÈqÎ.XÇõð)ì„!p<"[&N Œ‘ózÃ!w¯"?í°Ó%ežé·`MݵD.Ø3™zXaoŒ´™ REˆû¦!´…Ç5øË¡ 7·°…Ÿr>H[˜”%©–I[xh±kŒv:;FÊĈt-b?±Õ,˦yˆ Ô [°@ìUD˜µâI^]'Xzídº% Å‹ZMk˜²C"n]!kPçÉÖ¹@Èææ÷÷ çXi§=3€:HsÛxm'>•JsÂÑÝ¥‡¨g—¤(ñêZ€Ñ a¬äì†@Á”úÉ´ 3SDÇ&p ˆÀ3t@Ó¡ÙÒ-J€5ã¶pŽÀ»Z%²¡÷L;’¨…"œT"ô\Œ¦ð-µ-@£@^gz A=@§jÔÔ«U¤”ü×ãê!F&Þ2Ò“zC‚g¼h7`n•Ò<©P eBT¯ h iP-OÀÁë€U¨&)POÁïÂ<0RÀV& Ñ2“Ýc‡Ù¤xíÓ!„é²KˆÕ«/gwÆùß[ä£Ð‹l»Q Dlœ…¸’·ý-½pèB>Ö‘a ¥K‰p¥HN’àˆØ™'‰•®´ðÒøôn\(xƹ”X–n/ÎñvJ !yèÌÂ>7$1-h¡R>í$”.š’µGã;Glxµ‚( æ 4Žª*±Ø]2˜'­í€€]&Ö.ƒ ñh fj”W´°ª\{ŸVðRéJ±9kEmc€€,ܲMŽKxµÏ<‚]þ<Lp°€‚&¤Ö~Dçå°r$à7=ç—Ð @´s`õSrÞ€ É;¬ÄE¹@"œz@Ì@.e‹IÊ}nh « jn‚{ò ¦€K€|–¾ˆéàI¡e¢Qº:&mƒ¸1=ÿ¥M9J@)?¡Äãh $€/õÏž„ö£v§¤¼â`Ö<#v+VåøhDÔŨâ`&TDÚŽK>ZlMA2{ÀB#ÀTZ€\#À\{Á8N¡ºM@„&N&Z+ÀFZ„€!¸#À8Z‚†>¥&1Aî#ÈR±n>4­â$ (Uîßp¥ p¨V¡FÆn'Š”kX”b‰@»ìl,¯ ‹Ä¶â>ý¥NcŽëf!o@#î,$.xÀ>ˆÂ!dª$J.,ž ö¹®j]ж£@ @ΔYdü·bœ‚>qq )hŒÂq -¤“ËRâæ.-lº“ÃÂ-j.„Ñi¤!od#ì®LŠ$üíQD!a˜.‹à¿†V¡‚Öbàr7Žà@‚`\°§¯ïbè‚èç ìâ>sCž,2LlQ8L¦@z7#vð *bÖwÏ@ž£-n¢nsà@ µÀ©.lš`­až;­‰¸Žà Àº"ƒÔ:,â;¤b¢cºJ@ !ƒÔÏ@ Í„ ¨Ò¨®ÑFª`Ê4ÌHÏšÆÊDD,™@ µÀM@+Á,N¡eAì`€’à Ñ ¨àI )D‘J„ê‰âÊ’z@¥@©Âú'¤}‚Mr¥A¬e@*à.×äêE„ü„ äêâ¼¢< '®…¨k‚jðZ€v+ÀŠ&ŠeA¼N ˜&’!H#ÁÐÝMÜK„ƒ±„-«$ãâ²E R´p«4sH³AHÄ*/¾ˆz€\³X!fÖ#â¼-båìHMî\+–ÑoÖ,¢®?³:!r0.ÂD.†!ÏXæ§¼äâ¹>pô¼‚ dÎ3žoQ!oÎd \2 Ž!k–«Ò*‚d ##Ü—)dbà" !cb#æo —àú.l.‰¬. F@’àpð´2©+³¨A)D®0ÄA'ÉÒ0ÄÔïïŒËV Êêz„<d¤Dê. .˜Ožþ#PtÀD#RGD°…¨„ª§æ|D’zã9e¨Ô$V¤ü‚¼"<§¶×Ââ=„ÊJ@8_€Z€=köšÂ9.UeëοÀJV]Â?Bhæ”@ˆÆ &د8vro¾&T\(âæVnèNr #æTæ¨ÆæFŒçne1[•ØÏeìïB.Ž‘Ž.jÉà눔,¶7”F@ަŸC\ŽoÉöº.Ž¢&¼-dFHÊ#ÀÔÁ!6º–è@@-a”"> €¶îeLR I~k |LrE…ªŽl¶k0O`¡+Àù EqÞLôÃsB+¬eœbHtÖy‘?`7 k@ ši:8cº£@Ÿ‰üƨà r` tàM  y tÀ Ž ¦   ø€CD èÀ N0ìËè@×è×`ÉLÆ8ÇL×6æŒÇpèéÖ ü„V…¨¤ü"¼:KràJ€zOè5 \n,„tÑ ´î¤Îò°KÖe¨fø§¤ç®/ TäêEøGüK¤ ¤V‰~©¬¦8¶ÎÖfs÷†@iб$ûbA*ŽÈ”è ìŠñ’OˆM*Vf%-]äÚ˜$¤%ÊIpFFøNžtÖgMÍÄtd‚‰@OÀJ Owôd°ÅøÈDꇽW‚¢½Gõ©¤°jÊeA|+Á&OÀ)«D¤$΂¼¥¨Ù‚xH#À4eAP&BN J#ÁŠ#ÃÜ!>GXnN †õÖ)5Ò1Þ²[×¥?_; °ý„‡R `À °í@›^‚dN œÀO ¹ó\ßî$!fŒr(²#ö²õŽF!tŽY|³ b>¥ÐÎ&S²»ô nn‹"—ø’ã¥ýÞ–âÉô#ä¤&Ïfܦ€ý ž=ü!jaa¢è"f.æY h×Ûø#ìèe¨‰9’#ãQE[}¿øâ¾:@ïDöHÒ,é ô bÖƒ !ÕX±Ž ã/µ ¦€µÆ°aJ™šã›‘¾zàF4zËÃsM`€Màl@Ó€&CŸ#è™@f vIânràD¼4;´ê=I´‚¼‰zƒÒŒIxCÔ™R6;®¬è®ð§D«¨ÌÃïÄÀ ‰@ ` > A  Îà Û­!€’áJ¡¯ O`N mà~€I ÇÀädKàÀà¥ÀM@Ñ éàEwìI<ôP¤°"`äÎ`]BJ +€ÆTý©¤ªMŠzáºJ¡{Áô+ÀHLàPtÀVOÀ>¥A*&ÄJÊ!‚&n&¾&n!”N­×3-ê[úê#Áò#ܺ±½vÝšþ ü ‚€Ðh<z@€aQ”N)‹Eã˜Ôn9 UƒL00t s€ R@<’ û’+ä‡Ù;ÖHu’äàIdî<½¤çé rHi•Ià‘ õ ƒ’'$© ÞN’ çÓ@ O“¾'À©ŒËQ’!䉹%‚·’ ä‰Ù †Hˆ§Á€/yõ$g)¤I"H’½ÉrEmøUf­ °³ÀV㇪Uºum¥~˜VÀWêNŽüx’/Ç ”H§˜ ú*>\÷~~I2x wImß‚lº—H²ê«ñ#eº¿ïÌ«ö×/ªä|îÐÝ¡/ÏòfümïX²ïð“¼ù¿{ÌžòG½ë¬{Ð@‹¼¬ï®ñx€„»¼"Àaë½€ îïP]šð…ƒPË H O@dT:FÀl Ã0q”0éS“H _Ã¥Äc2áCñÁ¸€âÄbYÇá¤~t d‰¬‘ª|È` `Jõ(2¡ý*3 KÄO„¾ `QÆsH‚€bÊÀjVÊÐÛ€|´úrP .ËÐ ½À(  `ª\Ô`.‚ 2 ˆ7;MEOÆÜ¦‡êT!M …ÒUÕ qC‡¨!ïC•¨ y=‚ ‘?1º‚!ú‚¨!÷\ €B~Y("æ¡*Bƒ[HR‡£·Ãq\w"$V£NŸʪI?âHm$”" Ÿ ;¨‰©%C{+tü+dN$ƒúHè Õ ”¶²Àì”I#6Ë îaÀ º’I9¾’É$‹´ŠÞD­Æà r’+JI0ãŠIÂ’‰&\­ˆjò·Gäé!΢¤’R·+a‹›š$“2¶®²äJH²ÍâIA«i .9$‚N”¤—kð¦Éxª{fj fÛ~íaÀ¿`` ¬Ëʪ¶+¯ËS¶ÝšA3.q츘'ïËó³¼ñaÚý©²å³ò¿EŒ¸£É2æbý ;ëðjõòàÒíÀ ëºN¹ØïÎôš’Žöäëšnð%¼Ž»ëö@ Ÿ‚îñ‰ÎÀ ‰ÔÀ#ÐKÀ!Wð÷ ‘;ŠDÙP XC² L)F*4M~G0 ÃG( ëÎÈ_Gð€sõõ¾ú%`z€ M $q%EØ—ÀZd)¦sØš‡šg+@1ƒ€Æj>ƒÙ;» ôâ~Hä L*hHcM?Gd‹`V€aZ)…;ÀJÂAS ¥BÈ %S ©À â(ìObUSXTÒ„ÊR›µLÈ#ï jX­3›Ê cè‚rˆ õ+QkE°ÆH2Ê_äEo:eËcÔ{#"´–VVÉ 9$ìY€’’ 7˜ƒ(*˜ r¶L¤'Ä‘ÔÞRU0xÌ“‚Ò|Ÿ€Ç$áÄ’ ‚HÏ Ùà+eaŒ´²¶žÀ þ+g)§uZÐ%ЖB’âH ´°c‡Ð­½B¶Ù%ÜŒlÜÜà?0ÊL!@¿ ¶ì&K^$d’ V”ËðŒ4ä#—æŠÜ@‚$ A00:Mé~krxí )"_„~*Ž ­½p ðCÇ E™qÖ Ì»ãqfì2á_‘™—FàRàJs@Î:ë¤í9ÎeÚhh ÔuæuÏÐÙŸ‡zqx"Ûè‡@gâèuÅ!Þ;¨2~€1ä„Îó‘Aˆ©kb!A$$P`]C²¡4p Ç‘0oC²ä¿` G€(²C¢ÑÏ´qVP þ€f쪀"õÚ Ú¨þ©Š2”^Q €&–®]Ð hI}Ÿ¦„ÉÓR€MS4ÈŠaÐ T 9+è&àð‰¨‚ ¤ü+∇@N H¢U0/pÙ\SZtìÌÈ$3 ™Œ’Ø“ ƒ”‚,B®ÐPâñS2>•0ÍTÎ5¶*e@Çò¦ˆ‚FbÓyŒ@8u¸· A !Ñâ>_{ðGEp Ãü¢€+@_¥ ’G@ß@ h+p‰ËÌçl“•dža @`$䨭¢2¶'Ìv)1ÕIìŸ %¡,€­ÑybI10[¤ì±Â˜dG€hcÚ”ÃǦ˜­Ê ¸YÉ#cƒ´’âH0̕¥lôØVÛ—²í $JD©$ió©ª/§Î±dójÀƒq€@Ç£²Nà™°&Ï‘—E å¸9“.ÑÀ;qFí®™q‹FØ| †\Hˆ3.<Öc‹0Eæpeð˜gà ¨œ3šëÑ—}ç^€ 3½”©QÞ¤µŸ¬¶éüä:ú ëÈC¯žÀ#¬:ðèÎ}€tk`N»¾AŽP Ô;DÉÒdˆ3Y¼‰Ÿê OÀO€XŠF¢1¢(™"fÐŽ ÛuÉ£q€=ýGtGãÇÛªa%”&ŠQ; &ʘaÐ ;1©2H¤Ô¨@P&M£•3¨p@b~°<îf@yZ©øµ3”@À”¼ *¨@±™Éø ÃuBàXåhG¨Avª˜U…’~ʘEtŸ€r~Õ C vžÅÌ:. yFr mo7cDÙ²8Ç ´ˆ%îñ¾ø‘hï~{—s ¼,VЂH5HÇÄówáÝ’ŠÛ}Eo €âA©;ð$2â,bư{ „œ»²å?É#-ÒîÊh™$˳F8ðŤ€| 8̼lI0Ò(,®y¹‡“<¸rÍ`’m ×#9Þw$“àÔLý# K @ežæbÚ^%P3à ™|Âß[È`wlÐÒIõÀÚź^õÈ€NÊÛŠI  s€'íòhÕw@Dq¤š f^ Ð2pË©ËN óe‹ðT ò|5x¿ `Žó €Æ€ñ?ø€편tŽò¾Ž¹´Æ€¾Ž¸¦#Ì€Êa º«!¤bkÙ…Ñ”8XÜéä8ªP$¶¨ª`¡˜)* @‘¸ ƒ~¾¸)ès(à?œðŠÉ8ô9ª°*á(ª •0˜À¬°¬©2&À9Ø’;ˆ“9I ±9 •0À!¨„A98IZz’” ˆ€±+²• ¢ˆ Ðr•0DÀv”8“ð `ˆLS9Ø"éS¹SáZYC‡‚=‡!S±P®ð%@€ÁS }¤Ø‚Ê–k6/S ;z;/«ºFê<…€‰IŽB`ƒ=²£<+  ’ƒP§¨—óåFx½+0§Á?‰$*18’"‹«» #R»ø­°Óm€Ü€ ›3 ‰½0Ÿx“´û‰$ ½±1„ŠÛãH|y˜Û½­Ÿ8Áè&#Z ^ /³ÚbB­« ËÉ€¦ ó4@’Dà­¾BW%€*°^¦0#½³6/ )Œ¹Å0`›D ô‰ ض?ê½"‰(Ô2ìªfPˇ¨HŒ¸‚í´HË´<Ûj€ZR€€ŽÈÈX%ëµîózKHʈµTº%ðë¶#´Àï,¤@¼¸P›YIÒ>d.#Þ€"D#!Ü! ˆ0ŒÈáÁ3 Ø(›v鯑0Ì€3 €)ñ‘ÉÀÈIЪ`]©8?)xn¦P,°¬ "(@øŽa( ¸¸€,‡128kˆYŒ[Q€Y•a;a6“Ø!Ð"‰<:ñŒè¦9?Y=€’"¡`€¡P€ª"€²Ð€º(¡±M)ÙP¶i+   (‚A?‰S!ð‡IS©PÉ?YSQ=ÙS9?ÉP¨‚AP“‹9<éŽô–„i¼ë¶Ò÷ÆÐ…€¸Æõ¸X€jGH­©·(&Ã&‰;Ä€ –Ø’6`—ÑH"@ŠJY%`<¨­¤í"âQ*$€ˆ4£ÉL»ëÉ%[‰!}8‚F҈ȊÚÊ’©•‰ p ó&Ja¬˜á L€ ÉäY j¦¨ŸH{z˜ÚS Û0¤a° ºž€ ~ IRn/]; – Ü8?‘” ©c ð¼¸I Ý«@¿i”d€ Ê¡¸Aˆ7ø+0Ú "HZJÙ ˜¿P&Œ¸DxË…»ÄÊÜå¼rUèèŽðÜË¡•À Ù0€l”`¶_RxËê(€L(ï6• °!+¸%`¦À,°2 Œø(ð2Ø›ëc©ÎñB€¼È°Ð¶Ø±@ÓYT˜¬°x˜2È…¼hF GB€~›p©È,hÉÐ8±(Ÿ³†ñ¦Ã¹*Hؽ/±ýÒ°™‹»ô € JÓxƒ=m& ½+‰ñB =€õE²X¼Hû‹`„Ãð‰!–µà˜Ýç7€¦0ª`²Üˆ Ù+ ìUtвi •í7­Ô; Hû?Je@¢Q≀ïŠÜ›Ó_h„ÛÈMÕJ-G€e ø€ÉU?Ak5­ŒÈM`F Û<(ª"œ[#µ³`à:š€A ¸}»MýŽñ·[x«€GÁ0¿A¬´€ÊǪ˞¸‚¡ÚŽòR¼¸ÑóáèþŽô¸Ý`Ìùñ€õ$…€v%{!¬€ ¶!€$añ ¸ˆ×hÔx©¹èµ(Â!û3Þ€)2Vc¡”8>rÈ>¡ÐZ7(@i+‘úЀ9ŒAZBœ€J[CQ€I;I?,12)HMd=“9Z€a·aŒa=¸È‘"( `{•0OœxRÀð È /Ù H@ 2È Å ð -H선̀©FFô(È8‚0„¡SÉP’(È‚)SñIäþ¢(]ð!•n•¥ :ñ”;eËÜš÷Ѻõü´£ªøQnÝ =… 5Cƒ[Rý.”ª…Ü =ÝÞΰR™™0è’H]/¼]Üžèë½À­ÍpÌ ‹`9[ %ó ÙCÞ¨±`“ ܇˜¶0‘èH¤¼h»æ•Þö–¦ðÔ —€ÞùŽK07¦‚ŠÞßq(0Ø’T,Šë?iƒæL¹ŽøL tŸˆ¤€oÓËàŒë Ë(°Õ¥ø¿?S?jëö¸àÞ°ð¼UlÀ¬Ú€ú`ö6a° Œ¸>(8…È-Œ¸l à´ºVÍa©8ŸWÑIYaÀ¿Š`©xÕ Wd0“ت@ÞHëìÑéLÐï°é8Ьx¶`,hÄÇ*! $8#JÁaÀÉTh™Qê¶‘4€)ð€,Ö,0 µ°yŸXÅ‘ÁDžăùôY;$·íi€9; Yÿ!ÐThãâ „¤îL¸dù?TYZbËb“å19Zy;ЇÉÙ †Ð©I‘Fœý¬  “ñH¢ê䢈 “°g°FØ}¢(ÄVˆµº:Єr"‡Y?™P¸Ý“ØPˆ 0& \•0~ðjˆ"hˆVÆ{±DjçuÌѹ¼£y‡#ˆˆQÒúþ}"pTz”€ ƒÀ=ÛÞÇEÓr¬ƒÌ½+)™°œÈ@“¬/¤d3&€ òTšL;òFU®5ÀjÀÓì“$fß Š'ëØ`îø´ÚŠÛè`­™0²¹F –1è¤ôK ‰ŽGuYšiŽ&UÝ "\€ 7U™«¦!š8É$¢™@<ÈØEÉn’]?¬‹ ôš°jÛ@v/`ð¤½è1pC1¸K|ÊÝ^_”êÈë¼h9ņ%p ¸ÒŽ·S5 Š ½è¸êuˆï)NðÌ€ 7à·ø×\€ÚµùË€¼µïÈ3Ü@ïLtÂmëâÍõX…c(cfBIÉAѸã4×$‹€*m3Z+ëñªÐÍPmô-Žö0Y•r­ùð€>¬:|9À·ê$‰ÿdY?AC€Hc¤¨€KRÉR €R¨T(Ze,Á3šh9Üõ Ç•0}Š`Q¬¡Š/JŠ” ¹Ø @ ˆ RóìST¥ z®¸!0p%R‚PØ)€ŒY€¶á ¨ 0îi?ƒµ(<¼„+ÈEï±° ¨©ÜІ2i xN*Pƒ‚B@Hxa‘P®EFj@/á"¥S´EGéLd}&“ÜQ1ÂΚSZq„Ð7 €Æd…  (UÔBz‡"d,«ÌuÀ"!l8² § êà#Ô  ~BѲ‘ZË$…ž€À…òŸ!aˆ…¢²ˆBËÈŠKÔ‚‹…À ”*· ¯5^²ÀAIHD- XM k´…»² Æ £*í)rÊT“á- ‚»‚‘ a€Q‡>ATÄ,AEi Èh‹|V¤˜Ü‹XDi€NE‚sD-Ÿ‘i^ºÈ\1"ÌŒ¸€ØA;<„Yn€%AXqàT€”É@’! Ô‹J°+J#„"Ë¡|M˜”E€¨(ìE‘a¼H°ÄM‹à“³âve8 !v^ ”É(“,‹5`|T•È …It1æT”mN”¢¤ŠÀ#ã(ƒP¹µ 'K˜Ì.m¢²æ Ë™9/MˆÏQà‹˜D2³8½J b óÞ€ÜʇÃOJ(Ø2¢×W0‚A ‘ DÄ8Ô(B7ÓlƒC|ŠÀ9)íÈÝ¡@ƒ€Eu§ø#ŽªÀL±CpèE fÎíZO‹!>CäùE€ mÀ1`VÙ&ñÈ)ö ”O¤åpªÀE_ RÎàP`Và€.<#¬TH+’p " …‚C¸ ‘š;‚íäh²*´`¤Š‚aèx$(EF£Þïá*QêE@L¥_T‚As ŸA¹ Ð0èD(Áï0&ªÀ¦ÈØ U`.ŒFº*´x+à:wòD¤!àJH ÎUbUïÄ=wH 4F#Ýï ãìUhGAPŠ*Uif “x‚ÄŠ’‚„T|ÊT¹È%Å.pràÂØEØàêhMW>è¦èÞ£¦¼$¤IÀb{ÀXè$b¤<dK\FËZ)¥@l?"¤òÀŒ‚ˆ"¥ `>Àû¢ˆš€Í n€Ô`ô A "``Uà6 ï` C`Ä W òÀ 7 €]Fî2©~ªL3Åüq0´y  ˆ@pÁc¢,;€ 8 ¿'W  ÞàkÇZ1@ØÀ¬Z;‡\: †ææƒ´[ Y㺗à  BàWÀ ` gZà@…VÄŠÄ€Zâò*@mÀ&ãJÌ…|Îh{âòBò¼DB£B¤(î\FÎbæ|¥V¾/ `/ fD* PU rH ŒH|"¡ÈHšAŒHDAÖHƒÑæ·c+Àáƒ|ì¸KŽL.ȹNÌ„¨LkÌïäÈS"#Ж¼• %Ñ0¢(   ¬RHÂSŒX p¾ ‹¤öÅ$-,¥ •`‘@Unæ#D:@>1þ­SåÀölnõñ/t÷àYDöTLŠô¢Æç&(ôö‚vnì!p3%UHŒ\Èï`\ÅsY,Œ æF•;55 L\]"µ ÷ Œ-N†…þ!Ö%R"ÐXþbK@©!ç]â-rza“°J!@"Ȫ ¥|MFÜ›)úÇàQ€Ô`.À-kŒ'q@,ˆ¡"À bˆ‰â¸ÐÊMÂfz:@ `€L<ÑåÈpÎ)¤¡À[ û"ˆ¥ V€.j Š@ 7 "€Œ†ŒF¨/SÆ/À@Ä dàš  >à Ì€ ª Õc=@  ŒÀ \@ {Á¼¢Î z÷€ ÉÀ >À=€ x7Ä@}=€žcv­pÔ:i†)lNE2 IfQG cüj…ZàãÎ{À÷á\è$dl÷XFÀ ¡"pÀ%H$AÀ'G„6£üÂ*íæOxår¥V…ÄcI®`/ FFÁŒ>Á,¶Z´BÏÃâU¡2FÀ U`†FΨ bCÀu„X" ^Hn=Â*JB 3ENàe"ëeêλ+”¹E)PÐz³ ­E–@5¨ÂðòäP°‹,(œ#⢠2BõS¤(•ÒV!pú3Â!&%P¥wpèÀ,YSÅ Y²f½oòÄ °ú%,# RO³ãITP¸UUh_TLd¼2ãAu²Yln\€n€ˆµ ÷e†!eJJ )†ÅA›7 Šsj!pÆ) ˆð ¶ 1˜4R‡* ¼dúúâvð`¡ZiÜ`ï ¬‡8!<Bg]wàÔ)³^©¬G0T€›3¬€-óÕ^Â-*v,! &ĩҞ!v ,v‰JKåG­«·ƒdÉOäÎÀ'*«¬^KäPµ°»e–‰¶èb÷ˆœ^‡(€/( © Öú7˰˜¢P©F3ú/äR R#èT d‹˜D  ¦½Ô€¼ƒ¸6â ¦¬ÀTSØ.÷%å ³¯l`UzS”.2pÙÌ#]"Äúù°B¥€Ð ³¯Ùaø¸'¨__¦è„ [TÖ#‰Íb[ùõç,0 !s.;L'tN-¶"Ì'iK– ó |ŽcÌ"Å÷0‚µ Uª·ÐOxTNFpBò›*"ЖdB¥Ž-N\¸Ó ´`À b, Ó:gÀ&(ŠÓ¢Ê*LŠs_`–†­?ªkâ¤È`­Óÿkl*Ob9À Rà€‡ cÊóÈm"ç€à v.e©kÂæšÀ ›ðÖÌ€ k@ ¡þïa =A"­@k É@ ` Z`÷à 7  ·7eJ~ú  Ox€"ò*1%ZJÕÐcÊ;Mîz." WÀW ¡Ád"¡Ì¢0Ü –FªØ”ž z!â·Ýz"ÖBûî"ÌÈ^Ø·ÃZ"Ù’`Õ ÍfÀÐÀ! „D`/w `ü(h ,@(ŒÞ -¤P!JtZ(ŒY‚¥ yL*I¬Óæø?:(–ƒ—­ 1⥰ù°þ ŒÀB€ g¹ .o£ì<¬Xo#*dm‹ *– >à Uv´ ¹R@ñŽÁ|k€ Úgï°À ñ Ìà@Ð`vg<7ÅÝãvÍ ¤¨8çÂ0*<:#¡¢1Dlœ„5X §$}Œdè@R¶…”X^Ì)A,†€õÀ­ ü ô\ЄÌ|†…ÌІҨAê”!—ˆ†Ÿ¨iü†¡ˆAö†€·Â`$: 7¢s â£^ À†h›Ð²br¾ßÍ&J!qR«0H]l„á¨L>„Ù¨a"å¡-Ú¾0`&!x"Š¡8Xc_+p–ÒHHΉ‡ˆXÊ‰Ö ‚¾Ûà L„èhK^„¨h`ƉÓ2'¤ÑN¦„iÂ'%!&{"†8ø5"cª&¸3bª'-gH~zÆ`Äö€Ë(RnâÏ3nðE"v3m„£LÚB„½hL‚ÍÑm²¨„ðòƳdº&e.óï,à"ajî,®ëHÌShóìÞ–(,ÙO·»MèR;XàÙ³pC7ƒ;`þî0>€0¼Äû†»2ô»†ºî"NàÎ7m£›¸T ´)Îç8îï1Šó«¾ê¥Ñ†Î`+»™º;‹Íº€‹hvQúDMl CÌj <D^Ph³A¬`£ƒD2ÑzDH„†äl‹ÉGÄ m90î8ˆ@Ày@)€ ¡`·IääAhX‰’ë%Ï5.¥Tºp@;’€ƒ:›‘ºnXÀ%…€‘Μ@‚qd $w§³0“˜ k * ·<¢”K%\ä OÂ2‡–PÊe9€ã‚\QT |¾P”ècàLàFz”ÀÉŽÂ,Á%x¢Š½Xј„ãvÌ@!'"ÝN‰•‚Œ*8 ´œƒ)0É- íN„1”XÍ'!LÁŽUŒ6–ø6!£i’“½HD¸䆯´Ò½ˆjó! r ôl„…¶_Q ‡€h±DÂÔÏoì„·à3 ç!‡(„ƒRBÙk%#‰°"ìÈK†3±JDÀ±6$%ç€pé*œä%`€nBÜÀäLW5µ@™Ó-cà‘7XEYcŒÝÀì_7 „¹Âi {0¬Òc˜Å@f¡`N• t\9|%D‰¹àˆH¯4äM ™²ô U!0@ÍÐÒ/œ#©H‡‹Rî‚€ #;fØo—z*o©ðŒ"`P»»eàðj±›:çP‰Ô#6é Ù‡z »ÂÄ@Uȇã´dY›qá€%x§¹Ü^ L0P]DZæà|Í‚€üwøX;ƒü¸|ßg˜že*w©Ü: …€1@„4;†ô?@°@iDLýMs¸tÀ#xî ÒJˆ‚2 ƒ@3 Úˆ™9Gœ€Üz”J/¯Åg"ó,N¨‹>9 :gd,y²¯€YÈòX3Ù`¢–ð2À €u°N@BÚëUðS€I‰MÌô“ÒÀUéJ «Ž•à [à/µÁ[â|†Œex™è[P „)ð±zÆ1ÑÏ5bÉÈÇ%´s7ÇÆºÆ*, 9€émË|©Ñб„Qm‡ÐV´Œã3mE‚30–0 !¢¡o‚u: ‰È»XÀÐÁŽs»@ô^ú_¯¢>á `4¼‘rp EÄ2‹‹©¥>¦Ð±ä$Q½L&á}d.€Èk[;&ól8iÄNA—!bx‰ÈÒYj‹ÏÕ˜BZL›R—ÇÆ\xÖêu:vBhÉ E8â'l€ »ÓD%W®B\(!'„Ãí _Jc3"c4‰‡M¶à%© ‚±wZpwHH_"c„ÏÃÆ´€«¤&û–¤ÌÛžÞ$=ñ€&²nË­6ÚU!€-3b@'"pàC ·U˜p.ðÏRõ¾­EdjðÓÞ ’EÜ.ª¤™w¼Àˆ³rfíIÛ{pÍñyÌwXæàis!TA€gp:‰¸Á¡› ä¬`o@û;˜(¹P(O4ù;š œ\ŽäâŽÄ²0.O7DVœÌäEÔ€ –A­¸î>”D`À!Ó»] j@,<Œp¶ …*(¯ ¦:o„𭈣ïP x€//ÕB%Yå6 =Å€}æê8ñÏ•4¬`°@9»U:vR€OŽ U=£ëPÖO`˜†µ‚÷`‹JàŒ\F¢Æ·(°žò¼ëŒŒÀ°`IEK"«Ø2«!5…‹’Ú‹@g lôÕ¾N ' Dœˆâ…æ>Ex“‚EŒÅ‚´beŒÚBåŒ Ec–BÂþ²"jÎZ>€¬Lü^Ž"jÄ!# ÒÒ þb¢ÙàBNbúÄ‚„*/€®!mrçeiâ"h$!Ž^ ò/F®Ñ)Ôhí‚-h!,eÊ¢ ’!jœ)Ü&îC2"fÌ!æläb¢&`¢ë-ô-ªZ­¢' éº"kž-Èwâør'x"Bc€ž"ä›`B¶"jÒ$2áçGÚ'&)ƒ|r­p"mêG-~FŽ´£6ˆêr!*ôßDC‡‚D*².êÜPôFŠzC7®ZK¶+ŽGDX3gx@¼¯îH.ñ®ã̽ œ€ì‚š#¸ž£x.é˜kš3iÄå‚îmD47EúaŽ #¸a3`8£¸sb1À;‹ªk’;Ž(dà;‚<;ˆ(m²o°‡n´ÐoxDKnÔ†öˆVh4Š€…¾~ä^à ¼ÀäÛÂ!ñº­Ð¯(°®¤"Œè¼!ˆ€@ íÀ ö€ ëX~€ ì óJÖÆ>ãJK¤¾…Œ(èdMÒ†-¨†K¾2œu€åàÁ„2!¦OgX+FùQŠA¸P‡ðq°e0rŒÅŒª”ÂöS&JÅbãòd "S $X/È!&X (W€&sÁ.ab`!,0`2S 4´à88 :cà0s¸!*añFG¢ßæ'Ðî!3œK€%í ºa&lÔ +Bôi¶ÚïÎJf ŽÔ횤ã?FÒªÎ!檉 uIÀ{C|¡ó˜1t«n.œÀHm@±`ß‚ïs ¶0`(®t3åbH(Ky‘”3sîvâ&°`©‘ˆ.ç&ä"îóÀÔƒ6n¦`  ´A@cÍHt9€Ë <Ó˜C§`+c¸ ";€Ò#6ÀÒ;€®{¥nȯƒü©’<È’p†;‡ðg0†š~DPƒ48kŽ„BŽÀrD„††ºDK¸d^µ f@m€ ‚€= À $^­o!Nù ÁÛT%úIè(ÅV¨XŽÀ q` ‰ ù a`<@îÀøD»QlM&²8dÞ`h$èX2´N1öFàFBrùo”sÏ!–ŽÒØ! !' a`X Á@=[åB!G`ƒvHöAET!*Qaf‘!!8ÂÚE:OƒÅŒ¾#brÆèìPb£eŒ0äöXÀtŽÀj7aN¥¾ Bâ´¢bÀÁ¾q©À3Þ õ@‚Ú@=P—?lüß䆞‚Ú€:s«ï°0^1T»sÏ=ê"!qö+Â.À/­æÞŸp¼C Û wйm«Ì¡B' Û  B& ­Rh‚'m­Ñ‚BFËA¢ù kªÔ'pÍ`pÚñÀmaÂpÇ‹s –/¦ª"&NÀl6ÇtFZ©Ô¿ªÈ!#,7bCj .Z6ÕB)h!!v¥ã%!i¨.æ²Q¬&eGâ„s·€.è4Sé £ø3t|¨ôܨc7.r@…ŒCÄIáJƒ6ëŒR^x(O“N­@âîò€ò€·ÎK‰gƒ¸@H3`:nÃgŽXq¾k Ø Qíe¾rÆ;ФpÿhÀ ¦$ê@B@íŽð~ÆØq’DGéS´àˆà ļ 0  DD0 ©À Ùà¹áöu€üº!/Z@ Û XÁªEíÔ…‹RÃ,ÍæÆö¾„°N` k ‡`­oLM(Ši`‘ ´àsÀVDè=ŒÄè[@©@L”Þl4P†>Ã0"ÌÃ_:£RS&àå0å\0`"8 $7c0C†8%‚F–ä0#0e¾e´É"ãvQ¢‚:æ²Îfz…:…Œ‚´¥‚…¾:ÃE¾EgŠ ŒÄ:+|/(Ñv­j6!fê$bàÑ¢áBÜÏí¬i NÖ¾gGLo`k¬Y­s"NÔ)¦M wŒbqnâ&Ð1$@fÇ#ÔZtÇDÞÂ'›À Â8Æ&bœ* Ù ê3œ2UÀ#*.! ÿ¡ B¢lgXJXfM®2ZMrœ@ªq+™ñeF"q3@Ø íÀÚ@¤À)qV6×~3py ñaH|«h’MCÂïH ÏQ தKÂè1iI4®.îÔcž3xeIâîæŽd«à«nœãÉl(Cëâï¦qæaD6íüc¸á°Ž†`r鈞{cÌoÀz8.<Ñÿ@TË^;Š€yÀ‰àxXDQú˜Øt"DxuNA§†¢„b¥0•Ž@ f@ ³©™µ‚ºfŠÒê¥%„žr  (2^©ÄËÄŽ…€dK(ÀXLDŸ+à½`$Òôëõä°nëH˜M(*äãv ŽÀ‰r¾gÂXŠùJ¾bÚ1t-~lÂ[à¿ðüàUÀ7` còõ`ˆèd¹0Fƒî!UÁ–' .7`2! 40y=c&JÈìåŒ9f[ãò!NA@T´àX[A²X!8S H0`t8 H')@<ÆJ ã0%Œƒ‚ÙR!¡ŽF+dÏæ'Lf€ÙÂr7à!‹Ö8åpŽP³¡€ñÌÿ£«xÏéÕIÜÖÚå¾x§ ñ PÞ!yÜ/†’^b=—*›ÆŽa*$"ppìkpÈ)æX"f–.è'ˆàºÔ*!ðíQ!»T ssÜ©Q8/°ì® Ïyna.ná¢Æ!&w-þ5¢K×+$@:—„ß°·w1¥žÚ»§"¦`к±m~.n±`X @².ï6׬¨§‚{çUÁ«Êç €äªæcû.î_xÂîê—žŽÎdî€ ®Ð®zÎ?ÆðgÕ'ªa® c¸ö;€4c¹É­Çà<Úð°`}e\fz‡|xÐc‹xn^‚¤ðã͆@ !` '@8($tÄD`À †HZEó˜°^Ž(ÄæËx«¤¸Ý «ç‰x¤n  YM^Õ¨F °` ` Ì K°˜D»[l;6–ªOrN(×¼L+³`\©öydì›;žd7e%^Ã0¬V‘ +à.ñŠû¨è- $ŽÀ'0ÔþAA QaZ°|&!0! 2-¬‹ÃBÉ8!¶'6D,‚ÂÚ#G6XÁ&X!ÞS n3xXÁžS¡p0`—’%¾B¾"0ü­É£$F„"j?@“ ·Å<Û¢'¨YæSŸª¿§í7¥¢9Ñ/oåñ jpà7FcŸr%ýo‚r C*? jXÙFKÈÍj¨"'r­.fÜß=Àßù²'P¿Ñeô- Æ‚LÙÙT<3|‘¡b'™ú¡÷rÞ ÝHf#üj ð{, @$yBPP—S ƒC`q€ `W„ ÅøH"/ IA’X>QuBQqp…Í0`´ QÁŠd¬ªkgAŠcܽgÁ‰HáÞ4Á¦3E ª¢!ê¶  VªDƒ,j¯h0’«9À°f…T²·›N¶ð1‚Þr[ã:¼»UpÕLUZM½·(*£zª«-ã¢`&뎫掸äv9Žÿˆ+Èt @Yÿ¾†ÂnQÈ`x¸hÀŸÈqÚà¤6~ @„( €‘0 @J ¡à(Õ“Ñ-À 0} K² E@7 ƒ¸=º’9€¡ø±h­@Sdv²¹Z›†ÒpÊàœDQHàœŽ'If®dŠº^¢ÈʙΈÜì¶ m‚f¡#²OÎÈÕ ;(I"„ˆ$ðŒ7JDš¨KÔu: p¸í&d*ª a‚#€2<îÄ@ (Ô(w;ˆJ…HL®Õ†´ìž eâVJ „‰ÈJn›M~—ÈL´ê!!zŠ `šæ m=L€؆ N(|X¸@ s6¥—bS`¸„ŽˆM §hŽƒ,—r5{&—Â&¡#è¢à(0ú„·©¢A†&‡¢ì&=€JÈq&ŽzkásÊhŽ,@ ‚š]¹ ƒH02¢[yJ 5*H5zš(4. ”ƒDXX) ÔLª›(3\šÈ2n˜5À Ïbßr€N˜a Æ2ªª§Â ?­æâ6„¡zÞ ‹y”%¦‚·ÚàŽ j©Jª„ ¬ˆ·™ltâ·èìÑ:ªŽ,vÎæìÕ\ Ìvõ€‡cL±ÀSr€ÓYv€‚{gn€„Rj-Ã`dƒ)˜ ãµ…«f ¸bÓfN8`Ó‡F:•“©[Ù º”ø»xÈ ýøc>W˜<þ8Œ óëŒ'ËÞ½ø«êó?ÚütÀ’Ðø›vÙE ²€´+  @t®>P˜@{YÍ" "}‘«E„ %AxË€Žä{$°.”@ÂK)„ %tˆ@€é7É„QqBF"WÐ…h[÷DÜI¤°•Ì‘Oä]ŸCî@‚R">îl ¢·@d¬•UD×zLÄI éØo-øž¡‰›X¤%À6œBá 9jn'»ð%±Ýbq9Wà)تe¾‰S²K"Ø„ž’IôU j=4ÂEÉ Šd ˜ê@Ò‰4!*t}—‚MÑ=Ä RhBR…S’b$!êÆB8° C!¨FÕ:Ê—Sf!"NFól)?$ ]b4–„Џ4“1ý2ÂxŒ&×$€ Eç6æXÇ@Å€'뚈^K¬%¤€M&’>Œ°¬”ša4Hà ÈC(M%ÒWh¸‚SV˜I4²e¼þ´Y6ñ}¡dÐaZÜ[Ù4q,ª¹Bß@ñå¼oÞ‘o®À°rÞ3J«V…l·£}Ëx)1Å ·”³5 @î’’ÞíÌÓ„3[ùÃ@Zc›á¬c ÓÅð |@$¬ܬ‡êPÕ±²Dð*øpç0Ù [œ=††¡³ŸgPÂCèΘ­=€x®x.| 0€z 7pk !%Ÿ3Έ€OGiÀ* šÐhÐ t *Õ¯ÁÂèE‚ÃÑÖ@€`B©,¥{r†8·©Pd  ù@‚KIh ?p%‡™7Ä_Ý[¾Ò=fª†(ÐL#üÕˆ”D6RX$£€”ŒŠ4  Ð&ândD Ò88JîÝâñ;"‘ ÀoL¬Eˆ_Y3eÝ]á—.2!2l4™ê#kÇŠâ»~M!+ðc)H®÷Ñð0¾#¹Nʲ@1âײ¡ ûAfQ'Š46œp$d'=°t-ú­ó©ú:£âÎY[F¸€ E‰[ÞˆKø¤ 6k;±°„²ªM@0ƒÓU¿øÀp±û#¤ '3 ‚ ˆ#· # |Úˆ¦ ¤5.0µp$ˆ6À%5 £÷š(Ž& ЄÁ.ûSˆ2kÉ¢¨š%àÁãJ´yˆ‰’•€Å £"‰£hªˆâN€ñ‰¡x ¡ÃÕî€2€~7ˆªƒX x4 ·‡ -©  {%Š~·hª²à‚KzŠ«ñ K «<!é€9 ÐŒp q ÒŒÑà·øÇ@ø¬86˜·h?°:$heŸ8œ0¸X¦ˆ‹p«˜êÀ”xá‘À(HAx7(ŽøB€œ‘Äj:ÀÅ€::0÷’(¬áã€JÍà÷—€.ø¸r.0Q’é  ±;A-jŽi#ÇÁ ®øèŽú‘3?.I.ø  ’8J PÀ ‘ Ÿ»ÁØòï€Ù âŽêïØ(›++ω¸ºP›„‰%‡‘+¥4xO0 Ø“ #àD©; 8Œ’ý¢Ã§p€Â°¨H@ 9ɨ—I€£¥Á;ÓN­@³Ø™‹œ©Iø•8ˆKóu€D”ë¨àC8¿|£ˆHÏ€ b€ ²–I;¸‰HÂ3AKþ€ y P„ÄÈËÀËР5>Ö£åˆÒF€t \#4×/Ø·°–èÓúœ”„Œ[å…™{ˆKÕVÑS´>@Æ™Cœ¤=z?<±°„¹l›¥ý€ ³ z ˆe½º39 Ø&mJÀ?èz3d× ŽŠˆ4Mè¾²<²ekþ¢eŽˆÐÔ€o×Cñ&Ø-Îð,|ÒƒY› ¨€?&ÙVK‹iÎÔቡWà ¡”Œø´„§øŽU—Âè68ŽZY¨¨ƒW€š(%|ꉤ½^De¥3–›°ƒøWÒ‡BP¬€þ€·À¥±¥ {<€{Û€u5¬ú"¨·µ¨M@Àˆ·…€¼€F`·€ÚœØh¦0­@ÇŠ©O€#D€ÏQ`·=¸"#Ù Óf€%I˜Í+ Ú t+QÐÇ+èªsâŒñ*+÷«ÀÙÍXÖ+ÝÙ€-§€0%œ+1[+¥u1m€5”Ó8áÜ4­®2ÇÚï¬øí²¨AW ö“ÕJ/€I€÷žìs Ù€R´SÕ! b¡‡›œ€dÏc*€cY€hÕ€j ùþ¨àÐ’ —á‘2 ™-*a-Y ³?±0€Â ñ(à   }8D ¸n’8Uú !hII-hŠØ²S쓲t vÖÔ¦ €@w½ÀµÌ¡¤„¸XPÚ(± *.ø¾Ü®Lz'X|Ç@þ2“Ùš¿®–;Xlˆ“e€=Û&c<ÉÌ ³>à™Ì‹Š “ë1aM‡úŽªƒ%Áj&M´޲#€ f€ ŽŸ½šÀAˆK)€ ÁF4Ø›KÝÛ€´Ü° „’ ‚@™€TK&å‡åL5ÍZHK|ô8Þ\˜R¡€ …¦¹ª¿ù’'Sh€Á€éž¹m3?[HKW(…° £è€|-žÐI圊¬þ´¨ÀŒüá ¡È]Pƒ9{k  ø€dfðªÃ)[¨§’·…€¿ xw€·‡S/€ ƒXÍx ÐìG ©X$€P Ç0X·•JÔJ ª1ŒÔ¼%| ØÇ¸>ˆ€KÀÛ  ÈfÊø£i†vŒÓŠ,5€+ŽD¸Æ3è€,()¤€2ï€3þ€,Ü11‹€=-Fxá–è–Ø¤²P¦X‰¸=ó=€BãL(Ay€Ki€J€MuSÙ€IRjhÌ…)(…Q(‡€ï€a~eTq šË´Ô™þ;ZÞ½˜ ".A h+„Z@*`©%€³*È™¸ ’8 ¸ a(Naˆ™–u}Øúµ§ƒ ¯¡¤ì»ˆM¼cسÀ²‰ep£ídJ>YÔ£JXƒ=TW+æˆL†6q4L©åÚäÆ9+0PŽ$I€ñü(¥„ÆÈoÐ#h' ¥±Ô –é¢Ùš{¨*Ðgĉ¦ÿ£`pšZ=Á(pŽ]Æ„4( òÐ"º §!2Ÿ4€²=€xXÁxq €—ÚÖŠ¬/¥àCKf€Ô†"œƒà‹x2Ãà†(* xRPÍ(øÅà˜^`Ÿ8µ «_7èÇ6&_LŒq%€#7u8Ç6ˆ8ŠÈM¬8?Åàz ¸ØX¸Î©ÐÙ«ºÇ€+[€0ñEøáÌ%ë=€34ÚjðíÛ€2åô¡ëXí’¼o€€A~Sc¤zÔAO€KD€HÛ€Uþ2¨&XxWPR³ðT wø’8‰Z©*;9 Ô¢ q#‰a ’8øX¬Ð |‘ÀG’ˆY¬ÖŽí90€¹x¹*ÉÊ Øï€á9hŒZŽï‹`x9è‰g4.(ÊŽ*ˆLÝãæKãVnY‰€Ô0-…$3h€ ÜVÓD€ [’•ƒ¸„HÎP—(c•–¾è„¥à™¤¬oË1 >Bè™DŸq8’NrD´¸€{p![ j´O#ΣËX„™Ö9€ .c` usˆ4Ôc;ú#l'&ìúy’eµæ €»'>XLÜ[8„äÁ‹€6NtÖ‰PÛDµ4ä}Ĥ€Ártï3ˆƒ-´ähš@˜Pj¢ïS_g¸Ì€Wfàšg2c(q¢56—σ9ÈÛE±5®ƒšˆÛPªÄú‡€ÿ˜¸¸6£€À]Šª¥ x`PP°€€9‹xh‚ šØr¨™PÊÀ5ª­ûsˆü1À€‰8 ÷/Ágœ¿gÀ€¨X1Âó3ÀØ‹#A†±i8 ›‹2âÒ T¸[E†P 1v,Þœ+g ÃÞpÙœà@w\á;G*ÑÀwÕRõW UÓUÕB° KVª)°8à@ õÉgˆ€A(˜ T`N·¤wÖÅôˆpˆ:ž€}ó!Q.WÜ"íÍ>p˜0`M`@÷¬+žª`½Ì~@ƒ/ØhbÞoh pm@+° áS@­ /èõ:ODu-}–€ê»oþÏR1su½Øü_WÁÛt/ý‡oãûý{À"ã¨ò1à»ü:óúùºÓ¨AºŠûàÿ;ê.ضê,x :øè8À¨êŽ ðêC΃$ù>@&}(@,J Cð¬ ã¶áÁQsâÜ:³¨*:€ËýÅËË õ€#‹¨ I(ê2€£=R¤¥¾*# ÊŽ0):„4¸êN¢nGSýB›¨4:‚D¨Ö>R¬Pü¨>:ŠÜÜøŒ²¡*>,ÌÜŸMÇ{¨4ÑT› ÊAŒ¨tJ’4Ü?:…\©OP´ !J•ÝTD¨Ê…HÅ€D IJ‚Ĩ9Ê‚d¨ï€uÞ„ÁÓsXˆH?*G€s¡!ܨv!1X[ʆ_V¨H„»V`Ô„´&Y‡ð³fƒ˜A„öeºÐöaX„‹(1„œ06ƒQ€ìš(5lˆh5†SHJÂ`! ‚8W@¤ Ï2Ux€¦" T ¢-y€Å -5¥Cbp«¥Dºq•Ârpk' Jf(öÒfà=ƒŸ˜ê<„´;$±Hi2¼­, àãZ«Ûªk0ÀêË”êÈSë`Ï•ˆ˜L#îê€l|Æ´ì ãàzgÀ€ZX"Ö9ñ Ó×®0*x @¸˽2Ń, 6Ð;9"ã ¡ ø6»c3¨ÑÁNŸføÎ¦ Dîê L€íéÀ "êÞ}àÂ.‚è!¬yêf„gÚyQ}â〠&Õž_®év@èêeŽƒ’—Ýîè{¯Ž\N ÜíżØ2LÎŒêGÀ…$úÙ Év™À ¡Š0~‡“¨ìƒñDQ€ˆuÑÔ&€€dõÖÁÐ`ñ(# G`©þ_g@¥Fp\ÉÐ~p¬ê´ÜŽ„KÉQÂÃÓ¨PƒMÉ]Y$¥L›™ÑÐOé¹¥¢ã@–±ÐIQ&.›¢x~©º§Äö|&\A@ @ Œ@Ý* Å(]ÉP`%F|Ÿ(J 7ðÊ€¥Jy*6xø.R¡MTi¸˜›Ÿêng Ç„¨kÀ– d$%%@ÀBCZT„$Å€8ž•ÂÌ)+1¸6 ›—ü¡Y‰€Ë`(ˆHëd x†…˜ƒÌ`Uf d€Ÿ ÐmfL†‚,ƒ-˜Br r–edÚRA|âhZ ú¾@÷@ÀO5¾cÉ*k ß’¤ÄJ“A*â;’©ÒLÅ‘ äà‚N$‰3_¬ü±0fQè™3z,ü”t&óJ*­œðÃ@C*$¬–ª¡LA(ø%ÑðwÛqn`r´à@Y ,PÐ[@b3Íœ¨Çb\ØB`B±C4e’ñ¨ÌE–ÑÂË€­ © 4à.ã¡¶5àhÅĘ/ÑðÑ¢©Ö&®xÎÛ4‡ï€éA˜¾k° ©N¼ðܑԠoZ31w¬|[ çPš×{uɆà‹¾«’’U`è `œ,‘ñëÇ^•Q¦UTÃL‡@$×€™^v<:M8}3Rã…$³I€¸æ¶_j>qÀ4Å€Õ Qêa‰B`<Ðô|¸+ÄáÐÙÄ[>̨ )C@²û¶±›cŒP˜lãHª„B|F:tÇ•×g€ ̾}€"cò+ʲnÍvu4ŸEé*J€Îfò.'mGþ|FAÛ„-S$®bÅ€b;m‘ðŸã$h0'@hKax²ñÑfL ˆÀGÓKϽ8H—jbñÔVëòó öú,YÁO_­ž!{`/™Ð¡ N;Ĩͮ²î8êP¼u;¢{îý³ÏUV§Ò¡÷Ã)õy€§`âQñòÄåbu;8À øp ’§#‘àž.!!SLI€âºn€ G&Ÿ.Jê>BP¼q‚n\}­7?²¦•4*ÌÆà–,Á»&–eÏY(v Y–eÃY“3£€96ÈJÿ× 0[€U˜JÌ+°t³ÙÑw娀%tµ@ öÀ!²iÀ†² â ¥@ óÁP€äbhü%CÖR"Éx%IÀ«V…¦P&i*¦8¬Fž‚p™@ â@ Afl€ š ZFà úÀ ¢œ(èXégã’ä˜"ä|/Z "Ø&ªQ€e͘,²¦¾®…ìà¡àB`F`5à2àÄj’0‹È1†–Ä|ã’Ý5€ 8À"gÁü¡¡$‡L˜ @(örŽxã^é^d#^á|ç+~'ž" 1ë2ä.L:HF½ £¶@‹J:…: ú¾ ìJ'€ácâLR,˜1ë”16äãü¶ ‚ ¸Ý¤\ƒñ2|º¼äœiÎLE¡`:Ž2È+¶xC¨ Aö6@¦[áw ûÑìF`Ž Ò`¤¼C„”¿OŠ%D,êè# â@D¨^£¡‘ÌILRQX{ƒ¨Ã &Çâ$c –hÄJãšMǾ!\:‰þóäBF²1<H>çŽÚE9D¨„k*Œ¤¨ÂLƒ"Ed ¤Üç†O jàæ¨ôÄfLÜGžFHôÄrMÇÖôÃdI”L@ñhêØe˜>èùDÝ¥˜bàÄ¢Ro\qîHˆk”C.o„VH\ŒšY(†Bºàʨšq„Y‰ò8bƒaò ¥˜àÚ `îož!+Úœ!-K"i`gÀ&@ @Å,ü Ï<† §"$ rd¯è;â.Ó",‚,ä jà ` #à a` 1À a  z` ¡"fþ é"fÕÀ:'àïlgðÐò´gíXgå×âª@jN*©êÐ%â#A ƪYÃúÁTîFlá¸m‡"cXj€‡@2FÞ0‰f¥âËHoCÝ#$Ðphj#(£(È‚Èj†œ£(È‚Ãd ê`ìçX·£ƒ#¤ILŠ ¾41é¤(£@Ë5£¨³.|1çâw+ŠID #ë‘ËéZK|;gÒ釭è¶3š)ä_±Œ:Ž:ľ«\Cƒý˸ù$`éÃ$gö G¦„|æT$DÈ4Ã(E!DÊîTƒó.:’‘.Ø>)^,A1ÈD½Câ¢(ì:ˆØÒrn:ƒ’K¦¿Ò"(ˆâå‰P$©,@‰`iÀy @Ñ ‡HøV@ J†:HMÉòLþH·TD©Pé”a1à Èï6T–YTttíS…(iZOÉPJ‰p÷RdO²¯å™%L[)âk - Y`GÀ&@B¢Œè˜²Ü`& lÐbJ˜Ö@ù,¬ Ê.ƒ.”ðY‰*‰ú“Ïå`ð}¡NúÀó‚TÝ †à Ø ¾­B"Ë®° •  èxÅ–®ÄÒ‚¦pÆÈtÕ"pK³z&p°ðÐϨï<èXèt êãî ^¤¢À 0‚,(j3šF®ŽŽSt"ÚQº§¢ôH@ˆ#F/£X¾2€B`4Ê©ÃN©ç6d"Ú$|æTdg¦T5b?bD¶¢ …@ø\% îï¬zÁ®CC¶g‘²E\:çC´$é€jàN°KaOèªzÌ & )÷‹ç ”+@)µ.ê:‹º.î/xç6ŒN;$L%TÒ:JŒÜ$ÚKŠøøJ’‚»¯LVN¾:šPŽqtNâ‘þÿ!Ä&‰lR¡~ÎŽI½QbO.¨ÄiªJ‰´FÎo<D»$Â(uÂYˆ¦bàÍÀ¸V!2>r–$[‚šˆ¾c’uç/%ªýÁ<ý` `ÜYV e˜` h|h|’ ]ÂeÀœ vUú Ìç]áŠlà䟡¬œ  ïPP Ö&Ÿs" ÆÎ§ö¨b%NBÁF"ÎįœÑY5,®À U &@ ›@8ÓABå–Óeƒêôdäf €iÀgÏŠû ‚Àœ P€jáZÄaDúÁ«TÀeÀùÀ@lð¸0–¸4¨VÇ9 ‡@HJ–2ªž4"2âÄ A¡¬gÀ(v@(ç€(I„J ®<Èà[÷,KGj³k :…D aœÄÀS¨nyq‡®Å#¸:&C‘irc¤ÂŽ4¼kH:Š:I , #ŸžããxãÄñ´rg6êâ.6 VÔwë±MÊ†ŽµQ.À>'ñœ#ĵtc¤ã¨ºà!qÚX:„ÁGL<:­àÆà¢àÅ7†MÚu~d© ÑëF䩨$‡´rìåd~/_ØA!NþJ‡ºŠ²2MË‹ Õ^:–MdJ*QÉÒVJ„S©$²DŒ5xPÐTºDäVRNK¿§ þJ„ unVE©_@÷ úþd¨—Ed¢à@Zê!,‹Å™@|àéSU šYâ—Ê!,S³E˜9 ‚€ÀY€* BÒYì˜C“t˜s‚¾»j!(‚Œ((…D¾èTi¤‘ú„À¨jŒn£X§š¯ð“ ¢   P€ ^` -  bgÛÇ4ïŠÒdÖ\F` ø a`úÖz(ï’âRh«gP}”‚« ¢ ¥ɾ‚ÎŽ o¨Py@K³®/£Œoú¨UxĘÐÐÆüÜöÎp#dÄfÎxD„bÚƒ^,IOu``€U ëè;d!Æn†tAN(> tª:G’‹¬ oãüÁ€là§ç‡B+°‡@…‹1£¨»÷F:F€`@{#⛈xÒœ¿HØ:G6c¾Ò„&Ö²èÙvTÊ:'Î òë”·Ïcã(k¤:”-L@T$”oO§´¡!W’²èGÐH̆¯,:‰ã{#­V½1$©K/!GàJœr:Ú(÷!T¡5²¢:’8º,O¯c!ZÁS¨ŒHêQd©Ä}J…æXûú¼2#ƒÃ$Tm­Üä8^T^StødÜRJœiÙÌA…FTwÀOœd YØjI/up!(ªtƒbœ &R¦!,êxšÖ@·,l!/ñ…¢BÀQ€@-µà¼Y€ ¢ DY’þ€rÊYŒÜŠn†àƒŒˆž©êéú9ŒµâØ  Õ@ bT¹@ bà cÏ’¸¯àµžÌv%NŽÄè%QúÛ¶}  ȶRgæ\Ãï¾Bq&³Æ(`^` i&–ƒ v@Â|Ý qÁ`î@¥AžF`:Ʋ~쉠mC†\ª|l€kà‡@¶ÈÝc@ªE˜5,5óÞpÇ"Áò²(G·<Ä:‡’:S`:t *4QD'À;ú|;k£ÍßFEò|p)HÈkZ>3›F”_™Úzï·yƒ¡š?ÜyI&3R.—BR`(>½§h §ÎÇ#·K.> $»Ñtÿz¨2Ö@ad]Ç•è§ñèËÐíœy šWýmÚí¿ÜÃBÿU òA¡p8h 9 Að•L Í˜H> tÁ’,¥ †€aðó”i >Á‹$ eHcPñD$i‚Æ£ )¼i£ J¡.hK^?„!/ØHòÕ¦F„0‘¼­„¾á&èJÁsÂJvT$£`-ÂWÖ˜J>Àc°7¡/›,0%ØJÊÀ°,l›‚À8°à@C=‚/œàSyW¨¯ö4`B¥p(À¢ò³]:7*˰Dtàl«ÂÀŽh¨aÇ•<À€£<­´e^\DžVùÉAqE7ƒÉ×A 2kˆúïø‹^ðW¼Zï3{Óc÷}îÏSäîùþDÿ‘T p*ÀÛ@£!ð(ôÂ!YÈ@ FaæP€Ž @[èƒq3 €>€aü« ¾€l2€à ! @„^HèJ‘€¤kÅÁþ‹È; ѺY+¥hkƒè1+«ètºž+4 Á2 ¼0´Ó/ËÉàj Ãj Êå: þLì$ìªÚÂ󤮠ź #¨0É+©4¹AL¹>ƒÈ1§4Rô%0à€9 B؃õ H•Èh̸hô ÈÅ[4ÉjƒH0`ƒ'èïEÒî2A Ç²h„£5„ÒX(0ÀƒŠÝ§Kˆ(47x*ˆ~ƒ@À„˜×"ŽÑè$ž Ær =¡0Òl!00…\–jo#JÅ€ iš4HÛnÈ@¡8j]+xH  ×Øm¡+z4ê£Opƒá8¸’e€CºÀLâÒ@º£Yò«ˆ©¡5s,¡7z`âV,þHŬ*d¬JÁV#Kó¹°(È5¬:Á€eÀé˰9¬ (Êë n°%8„Ó†£KVí9²´ôóõ4øH2¡*þ@Õ úI2¼‹O—´ü t4ôS’`8k+®¹%+ˆi8ƒ‹‰ ¹,Cßš¸®õ––{¼ ;Å#¼w»Ô¤u»Ç‹äÅ@ýûÞü@‰±Àáì£j2IEµA LßDmCþÁûDš¸YÞÂuí€dM¨ÈŒ¨hÚ€ud-qú$ Ÿd0ˆhׂä%’+ˆ0ˆJãu;ª4¾¬€VJêÙRgV ¹°Lƒuð•ÝJÜSJ‘PG @Ãñlª dÂ’VÒH0…8º°òÔÊ£M`>%qʲ@ ¡-~@Ò Ÿò˜PkŒ#Ìä Ñ(¢Èhš`²ð- ˜4Xâ4A Dd@Ç FTkÀ:c®@ÇpM!$„…BHAŽ R`”ƒâ@ / qý“ à À è#H6i‡AïV$…šÃ!0œ–®F‚@Ò™ ôCІ[d<£€ «&J,dÇÐ/Ò4¤d‰ 1„ €'ÅÈ{«Ap›XBU´Æ&D&9˜ÔÈω0 Ä„§ò5æÑ$$8ÀF£øÅ9ËóÒâqèÀ°7 #P8À›³êÀf0!°!0½Ì fb„Ä™YÇ?_°ÁLÓ€ðÎ`@€34âXÂBÚ¨‚F…Ž·‚Th¥+` A™ÉA.êP q&Q§GWTUÑÉg…ô]Øxà÷`†wžÐs 3iä§ÐF‡½> wrÐpWŽ @¾|§² @,ü+'¢„jØ A` è‹¢'çàÅÆ ËàXÀ\øh$¢0¹€e„gà5sÚ¶‘`{@8 $B3MR5Yø]ªÕ3W@˜Jö€Ùäëˆ5 sLNPáý¦/±ðÇíŠwI : þˆ4H‰9W¨HRö€ $¼ÂØñÀ Ô'<¹0+ €†k<±0w.Ò˜ÆA*šVA…±&3iRaòi€øÉ%bA£Jâ ŽAß²}J>*àÈ@ð(Fìš \‚ô@ÐX6€Á„éÊ‘«€+‘rÁ„%@­À0ܘ[ ü²iF@ÆÑ`  ª€NF£ƒ™mË âa L¡B2c§7HL-W¥p9°êqcH!5Œ'²4ûÈÐß!+Vv0bíØ´@ µ&/K3!ìDÀ ¢Ãhµu„€58Fˆ™œ  $7+œÅY Á³|„ÒrÌyQñ° Ê`WTÀ ‚΂Àègù·,À¶ áá„ÓÀ¾a@ù§3 :+„F YNlm> 9@"Æ® š€Iað‡Àk€QÔec*G&›¤_<‡$"åÄYáïÚ  €mŸ-O}Ú;çyÅ€{˜ÇòÊÀ€uÁò@々Ì*ÎôB-\3¤¹…ìøçÒ+¢ž8 ’ï˜"hþßð ²h¶¢Ôz8! :ì>þŠ8jà>¬€6ë×øÿBahD(nBÑ0ÕT-ÿ ƒÃã $55 yBÐðÕL.3†F£±,÷ (BËðµ´®U7ágØYZM6”€T°ÓL,; @ÂÊ”Ý6€å…«áfÉü&7 ¹¡§˜Cæj³a õVƒ'tBÏеD, ^BÆ–è´-Á CBÕuP*¡….÷ - V]aå(@ = YœP´-] ÂÙ¹Õb2ÉÃÏóH["!ª€ªàM9æ,ÙøÛžLÆž¡sxhcHP·ä.ÊeaûÀ^»ßêceŒoRä?z0ó>5Û·ñ´žGw9écZØÑÖ49HÆ‘ñ¢ük¯¶ßrØÛ!Æ®.C6äˆ@Ï—ìh¢Æ¨îBÖkkè9È&±¥$ þ€G#jÀÁü {¾02äp1g20o ¬h-;Í01ð1Š„‚| ÀÉä HÈì K! !üB¨Ê€h§€t¨QHä€:¡$q&„%Â~¶À wÈ04H*€#G5Òµ5³™i “›:‘È@ ÍBôævÎlxÔ2ý5ô3ò1†„æ5 7Ó“e€8NTãRH@ìòP°Ì€LH:‚èA‚‹€ñÆ„ÑÍr!P„gM›"YŸh6€T„‹¸È@U®ÐrÜOÈeà‚l˜åò/ZNÒ¨Hð…™èH!$Ú ^¨Y’†ŽˆY£‚³Ê…”i¦Ù©‹àf…’ˆXV…¸(Hœ…ž`¡dÂâªÁ,…ßhK臓ˆXO‘^È@úÿ€3œ„„¸¦¬D}Gh{ú³¬Ö `!dB8!b2üé Á„…hXÜ…ÃþªÓhy:…£è}à çÊ ‡Ùèxlðf®F2‡Ï¨~pâûF€…‡®ª¡yÀ¼€4ó‘I€'óÒ‡‡Œhçî|äf(~ÂN๒ânÕ1¶ B¡ô˜?ŒiÔ…ÛnERäC“H¹;"ûìn@ªÆñPf9Ÿ`Æž,nòup„9ã¿ ”ÆìlA½¼!¹” ®9X§o@ë"÷2 làç&pud‚‡X0¥p4S* ±4 øz* p„fJ‚°!!ö !©”äˆ@±jéQ€D •’T8àîWzÀ©€VšŸØa)©íT4£ÂÒs=é¨Y'4Ì£ÍÂp ©€`4¡¢:iŠ>€w°›¨*•SªUvÏèY@4€‡v©OZ¼й³«¥\ôUÊæˆyb¬¡tqÀR«Gä(À ø M -áµV¢Ü«pŒ€Ñö¸–"§!9‚²Z` d5€2Í ¯.0z ³>%‡¿0wÈzÇ'n ”¼Cΰ†à‰’ ÏÉA? 1¸ØJù)—%ñ€bCÉy‘ 0€†BǬ¢} W€êÕFº'¾Pù§%dÝkäm%„R0‘­T”4¤NY1e³¨ÁÎ5ü;Œ1 {“Y´•pÜÀ×!iÜ£6¼FÓùÈšl윪 ÒLiE!æ¼Þ°²chu+ÈäÂïIHU`êöúriFÐÁ€#.CÓØk$<´· Ìh§52Ó£‘ÀhÇÜ´PœŽ@[1³V€&6rK ¦ÔÌF€ø1 F6 7ª¤„¹&À÷ gÚ…÷‘  a¡ΜãBõð‹“äÀ9¬ãHPÈÐÇ@JB„XiPÝx$h@5 jýeq! ë@ Ÿ@ĵW -’Tá]Ä•H/J‚ „‹Ö‚!˜ß‡`Ø¥H’ÊTl òIž•’s¨@ù€PHœÂ*s8iR»&¨6šÚj[ÀQ§8>Ÿêj\À„€f^›8*=€cP©DR†¹ê–à€whÏÈlà\Šž«Ôä1_«°@Iös ä-À’¿•@(þ€§‹è0 T€.*€·“†–à#[’ºðq9@5«Ì'öC‰ $.*Ì2óÈKØ6pB H~œE\”` ˜È}B’D7$޽ÈXì!bH·i0[!òL„ÕÐ&HZ»ÆÓ²àã2ÈZ+•m¥w›’CèWÀ.WAN^óYx€ÔBÛ9A$6c”ªkj y¥¢XH~s:8ãà1rykD/IM[+EJÂæ(,‡Ä° Ù Î*®©ML¦Y«Ôè!g˜4p€Bß»Ÿ#zÆtªÓ‘¢Ú®­#pääaÙ@š#hs5òr&‰© ²ìã+ilþ@`Óû´‘Ÿ; ³‘º­›Àãc´„ÏÑàÄNDø9tD°ÚÏÁ «ôó˜ÝŒƒi¸ ìÕóúÉ)È Õ/À*ªÚ  ˜ÔNßù¦ Ñ‡¸óú3ü!a¤º4 ”€:(í Éd€8>Á[À¼3‡œ4øÂà5T =ÃTi*ð8Ñ gý7 ðôÀ%cMMCðÓšJ‡(²©À/MJˆ¶Pö€6Ÿ±,Æ G€2J¤UG 0 Ô‚†…j>óËp ¼"rœRûFýx¥]}ïì„;Ðí0:¿Ê@eD‘<ÛE¬]€)€˜¦ߨ ó`,ü€¼çëåz˜;ÕÆBØ „5‘AP5iÁc óµ˜ÝA -w1å±wHN¨!ñ,J"66õI ˜$l0ܨ׼Òˆ¿<µúR3Œ­7Vv7gE² 37Î9Dƒ@ H!󖀺þ‡`É«Ž!ð!nr!ë8(&Žù-&!f>¥Cv!mL5iÎ’¨‚%HœÌ¬gÀÃ(!cä!î!ìÐgí[š«z,ØP<þ®´˜ÇÀ/"ëC’!oȤ*'¦Ã?fêOä#óÀ²à£ÄC© œ1¦&9 iD(2rKâ!ðÙ ‚6Û§Fû '>ŽÀù0Þ¥¨†M(k \И{H1¯v9ꀽ`©³>AGB1ª±6M¾ïŽ 1ªGi2‘è^lÚ«ê°²`t̸lb9 .O¤lÔEc¬B#x@ !*Ð@Í}=„! €ûx‡n@Í>‡Ó`„ ÞQFH&» ­±¬H za`D¨à–tq|`À@8@àË@v€•£H:´€º(ˆHHª¶J’MM ¢¾¨ÑDævEn` @ ÖäÔ; ºñÆ~ _ w  x@ ߀3  F ûà ¯@`w¨´Œå8? ‰ ü€å ØÀÂá¤~¡<²ábå `:À?OHY§´lÚŽ%¹( g¥¾W¸%ò•{LÆ÷Éâ0Tæ–‚È̈5jôÙ+ÂÔR~@lÆú@Æb<)é) „ìÊH!f^‚šõ*,Å”X¢h ûêne"‚“Gr”ì¢*¡*{ÛV‚6§“*– ÞRíå,”|TRà#jÚÿÂDd ¨bÓàÿt,/Z"B§©[ïÝGÀ}ãã nõÌ,Ôˆ*Ò9 @QÀeý›‹¥¶w.1²°¥ƒtz9 æJèGês ˆ1°q@ân^S#‘> ¿*Ä ¤àW`Š ”× ãnBªä 3äjèmˆtä • hȾtU`ÎV¤ çÈ@¤ l m @”€?–@J‡öm!6²Ht  K º! z¤©' ÏÆH ¸’ØŠ ¤ÒŽøÈ©“ræ<€ Í  º`¤à € ` ` @ §À ` <À ³€ ~` JˆÂÐæÚÏôèBéKåJ:ÀÈ@ Ï,h ¸àuàTAªƒåŒ!aÄöMä'^JžHØj C¬oh©â"`ঠXÊ|%¨ !_²l{@|\!¥w,"qRø!l´û‚‚å5X!õ2ÎbQ .:% Ö·µBЬ,ÆæMBbeq%¦¾ÁU$ÔÍ@hmaʉ8 &Wðw ÔO™R#W6 &3*¤Ní@Ðb±Z¨ÉJVž§Î'Ö8p!xt,ƨab1µ nøQ†Cä …æZ f5Ù7Uµ…ãVTS¨–B_  V(-ä­†¸0'"!óu0ðÐIª¬ø2h h‰b3ì^• \Všqp”1³ˆÒIjVP£Q vX3Jâ#‘F`W–1­Ÿ0Šm nÕaY@x@áÍX3õÔIUoóè1°#Œ‡ÂHC‘õÄy:º« 1°ú`¤ßS~dn#(#|@Îøvˆ²à+ @È’p®eHlµj„€pÀDZiH™^ìFŠv„äÈìÁpÁl¾Bf Ĩ6ø„r„€êÍH£°Ž¹1@È@ qô¬±.«Œ.¤$°NÑÆú@ Û` ›€ ¡–NnÔÌÛJ%9P@ y aÀ ¢W’SÐWÅ8×ÀìÀm ”€ˆ`àÚ!°ØÁÁAZ3¡øß€eàT€ÐÄÒH+#¢…c6(#BÇ¢l k°!0¬bNÔP‚g !nÀ!)“€•ç]¢hZþ!p†ø‰ò!óõ©ƒWÒÒrÁ´ìÕ.ȃp0gÁ—  píBPø;Ž!+I¯ ‚¬ú͈õ¯ƒ]Jpñ/â°ýš±¬]š#c°)›Ô}¤-âÔ½Š~;P#ic[°ò5Œ#j!`]0$!}Ò3íDœ°Ëb#‘ÒÉÓ @³ÝìRòð`y C“B}`_ŠäR‚NLÔxÏ7*–1¬u½ã?àG PÝF h@?P™ðÿ SÎÕ‚ªYr9&K«¿ dœ&²ê¾¦`¾cˆÖ¼¢$ ‡`Àq¯@ºÓÒ‰`5À‰ –àg`× íVÂ@ÊÚiÂqøˆà¯‰¨Š"°÷ŽCÀJx‰/|VÑM`Ó•œ€¢`#Eiœ¬F`¶ûರîÊè"'zÄ’ø“ÖÖu…u`¯eVÕƒu`%XSV"÷Í L•¬;+kàZ_V"·Ê0R¬3:º;ãÛª˜Ê€Êõ„ßW˜º¬oû†ªÏªvó¤z¿.㫪Åê†n©‚‚‰C¸â»„»ª!@e[ªmº ÜH ‡!ô‚j\ލû–àø·‹Q",ÄB€S8q“ðe= uÀfJÁ±'@ !k±Ð“ ±ÑሠyÇBœt]É«h ±Ó/+32´#+( oI°8 *€æ„Â$L ¬ÂiÌ,p£`'ÎJÐ €DÀFZOŸ(!VùÀ‚3ðjÑaR+À¼ Í Œˆ‘Èt´œ¡ée@‚ƒˆˆø‡J(*µQ' n‡ Ê "?!ÎõR‡/*ÝVp¢$RÉ ©Š …!õÅ>q"$J"ã¡ò­X‰€Š † ´" Æ!å*"0•Z;/ƒ:+è‹·gVéÀ3R¢2 !!âË VPà <‡Ýµaøˆµˆ)Ìœ艈‹u ;@ ­Ê¹6 ©z -^Gª"¢4ð4¸ ·Ãz®èˆÀ¬\ز ³ ¸" "'"¤ˆßNR#€9’€%ú±Z··–B)ˆ-8‚›ìõph‰Tˆã‹å~Ù­ ›JÄö‚*ÅÈ‚• Ä&‚ãÙj¶Ø ¥‚±ˆ ¢Â±¢k  ª³ÙÒ®¾K€ï¯40Zù¤JŠ d¯…˾¬%Zè;€AŽÌ¬*Àr¬. äö+‚°P«ÈB:¹(¼åбvëàtÀ+“ªÝ»ª°z:µ¨×/‘ Tººƒ¸¥;…#«R;’c¹É»•@^:¬&º®tE ;‘`r¡à'îI@mÅ‚΄E€gg ,†q/ÄA¸¥€´E{‹LDA@xX ÎÄL@ ø€›,kx¢!2Ž”R5¨èÚS‚P5 4"#¦Â•€¢:‰4c$×NšàKÀÚ€eÒÐK@§!°˜Fra„ =>= fÓ« hrž(,VòA2‹Qà­¾,ˆÿ% ‡ŒExC†[„tº€ðDAù‡2ð˜Ö!8zà˜ƒè¨®V*½!ሺ˜ÕHŠi ¡ÄˆŒÕÐAEr1Œ® "ÆCŒBç+c콃´¦kR%øGI !ZÑ)øŠØÓ$Hè(""xˆÈrdÑ8ˆqèˆÉFÜD¢òYà‘e8»ˆ‹ÿ”eðµYS*2($®,W®U1Y±9“ÊÂ" QXgÒÕ¯€öE—À (K÷ AFû+ ˆ¿2 5ÀB ¨<¾²pvÀÙ"'À1–‚V ¹| RÀ¬¢ JÁ×/ŒÞu4U|G%ò%¢°½(8†S¾&òù9/Œi¯€ ¼V ˆ¢ÀÝÕˆ‹C€/“x¾.£¹:¨Yb/‘¸î= ¦‹ãrf„CX_#`OÀ ½ÓSª²À;ŒhË—€5;Ž îG¦xN­Ll,Ô§âܺ"<@ ÷<êòÀ#Ç/ˆÜ®"J©Ü[(Ša€8àD@H""!æùÀ ÜȈA€”DÈk’”ŸEªJš"¦@ :nar5 ˆê)£QFŽšk€¥dxSðé4ú#U(@e)Ƀ€`:“O"rJ sÝZrn –ˆa €B”ÌsÛ1B ˆ ¨zCÍ]§P@¢ßŠŠ¢ à-P@‘-8ÝðÔ€ú-äšXý$ˆé{ô«2 ioIŸ€|60"Ó7YmWf`Htl–ª­s5‚!HŠÇ+b0€ìÃd‹J«`qÌ‚ =H~8r§^Xå6-[)p¯ëÀ±HèT"/ÄÄYk$qa±b,bª Tœ8aVQeñeÀ Æ&…ZPpQȇ,ˆÎ‚ ;-À9+͈*Ñ™÷üàöˆ*D/‰ÒBLù¦_&Û + ¼ÐáyòV/ødä€+*ASY|Îm þ€)ª o ø¾JæÐh[Ø»À ,—Ë¢_8k”\Ф‚øÊÄàX0<çÍí7b86x‘àÉu¾AS¸ýÀªp,O£¸—œ¬:´‘W~óÖ+ ðÊP´ÀÉmTZPãÂ"­` ¡Óª°@%2mXqÖ`Ý,EÝ“y@ENâ2‚Ð "!¢Qå ¨ˆ]dD Ý@€\nÿÓuš ´E˜€,·¡9 Ôu€+u¦QÆ &©uÓæ° íÀ2µÙ¤g )@:wÄL—¸<˜lø™IÖ‚Â$Ãp®&uNQCáNb{,7ÉE(õ?uˆî¤!òøÏ€õé²röeüMºñÄ*±: ×@ˆrwfQÎ<ªÄ* ”VO©«–ähÉÓ¢z‰ÃÔ•Do^€zýÇD>é$ã®S¥‰Hu»UD·U>ô€ Á/$ß‹­0[éì‡à‚ʲ lð/w$­œr) ²\˜1L|mRò¾¼ËIŸ‰¥ ‡"9ˆåêDx†vedGÞ3ÒØDXX…$½Ìõ(V¸ò™¬ÔŒTV<8­ ýPÂY3ï@aä(#Pj€»÷ÑdâùÈ(VrDE±Ñ{>vžtûEcÐ D4°¬Èؾ:¨™‹ã‡ âµÙÀ”8!À«O£ú¨¨×£°î>óLŽêž¡Ð*è£Ø¾1@¨ H@Y¢©ÏއB°Ž¨Úªê‘à¬xî$ñ'#W³¶hêÀX((™°š"ƒ‹„A:m0`>8˜H/€È8Ð+‘,)+ *p¶˜28©ÉøÒ~"Ë€)þ€)Û€) ‘ªù(1Л‘«á€(nk‹*¨(%ÐÄHA›¨è PÅÙ€;\;:€9i€8ì€BߘÐv›8Q-˜S'0v¥(p…YøÀjð»9g–)Ú€〠iˆ€ˆ‘p‚·€Fˆ+%€ û€–<+kˆ*' AÆ4j–+Dž º–ysàšAU¿É‘€°)\cG„º8>ÊùˆŠ€ #€ 8€*DZc‰{G8œ?û¹Æ ³€¥Iû¤‹ÊG0Ž›È%ái¤ŠJ)1V1@·P­:H¨ð‚¤LŒŠÄŽHðŽ¨ € œ•`nˆŠÈ€V Ááˆ*83<–ˆ*î=j…›:gFi§ˆ‰#@Ói‹‚š’Ÿø¬3¨©04Ђ—0Эˆ‚´áþ˜ˆ³¨$„®&H«ó† ¬)"g ~/t®‹䬿Á¿À+äœ Ÿ €î€Ñ‹ãç€Ê¢‹Àáç ÃY ¨Ɉ¾5 sŠÄ¼€É€ý€ˆÀ£â[€BôC€¿A¸ê°x§«0Xî4ˆž¢­¡ä  ‚ È„J€$£ 5ÀF@¨´xJš€ (É .yè ‘©«!©$í¨•q€Ÿiª$Jé)¬J6˜=(©@–Éýj-’²…Á&¹!h€3i€8­1³€9j€9À9¼€9ƒ€8(“ -Eq>˜x8Q­ØR3¨p€j€ ¼€Ž9«·ÈAgÉk€}¨ _¤Ë2 ã€ø;Ђ@'§ä}rH:Qn «é"à‡@å’0%¸Æ@5ÂB 5‚Æà¹©´ˆt!Gpœ;¿ hÑ,{ƒÑØ‚Ìp¡•,+i€ pˆ*ç¾`ˆÁ¸@³ÈÉò¨2³êH/$›€ ´$„sHRï ¼š=ŒC›ˆÅ\¡–*¦ ‰I¬{@©•+ùáÀð–jKAÄ¡ ·€¨Ja(D­0¬7@³u¿аã (p˜8`3KëxÐÓjœ€8µ ã.GjDÀ ¾ ð3Ø*p?Ûò€óд ÄX€-(¼»³XÔäœYNj⭀6ꄎªq‰.ZílªÍPî%¬Ùº€ñæ—àɸ-hÀh³p“¸5``˜8¬XLì£!·"€÷Ëx¸¬$«Äé€ e‚„@‘7á•øø,ø˜K…æ€,ù@´ˆ·@¹Cú¬¿€*“34ýÙ&›šBÛ ³¡!0 «0” •@€X¯øy‹ØRXql`ˆˆì€º´xõ"±¸&™¹ž7EñP½Qg̈‚Ê€1½I OLøÜ„¯éP¬X‚øˆÖ­m/;:h—mp‚m£…³ÍÑ(Õ;‡BÜ®O ÝLƒ¥â”\è®&kGˆ¼$€êÿ€¨¸êSÊtˆÆÙL±ñb ¾Z²=X®0†ù ü€ó‰­L Â0-9¨\À‚Èë fÒ»(᎗X¾S„·®êxÕP¾/uo±åì? ÏÞX¾\céßİB”³Ë¨—x.PÂŒôÃKø-kYßjˆšÍ^ ÂR€cË«U'¼ äD¨ºšOÛþ ã;Ê Ixæ>{ñž¸6s8 Ȭ( Æmeެ¸ÂÊÌŽã)Íh¬)p©`Ÿø§˜ÜÁŽ«5ª8ê׬Ö̀Ƹaõ‹èª W ˆ:tÌìå\ X€"6$A€µ€!žXð ‘k¡Ä4Aò(5ˆ4Æ2Ô:,ì¼€ ½€.€+2-5€)*€-šðÚ¡±€,"1–Oa&ÚZ’3Ž90Э­¡’ß ’:X€;A/9°­[|FÑ0‡<%?»›¼‰w€€ ו]†_ ÄMÜZ³AÛèˆàF`ˆéîÆÐ‡ø¼ag¨ M±˜_ÃÊB"ºèŽ˜XQSX0™ð?}Ê^ê:ˆu:S3$MÓ€2‰³–j`¾hšu1E€ Š‚¨91óíÕ=?5Åíã+/`Eˈ°½1ô”–àQ&‰b}N?0¬]f‹‰Ä”ÀmZ:®JXˆÔýù€ ª·PX›–šóªÊs¬ˆ‰å¦|d„ –3ˆÜEMŠ‹Ò€Àà( ᙿøx+‹jñãCk¨¼¾¨,Zq˜ø¬Vf œ â€<Ø©€ñVóÁ 0Œ€ Ȭ¸½Ð_ A³O1à¬ý‹ãc4ŽäÄ>üöØêË îTX>mƒ©a€„+Ø@'EÖç®1ÂKæ€!³€ é$Á'3Ø*Ýi 4.7(. XÜ9ÐC“,>’Ð(§0Ïñ‘¢ÅÖä4ñnY+`@&¸¯ ˜Ð³ÈnO[—¯@J °ˆ q€‚1eÁ/L¿¤h‡f,`ÒøŽµÂý°È‡Iâë]5‹)T°ÐíFèœ"(0’¾ð‡<õ"±s#€ñ%¨w) !¯@i&ŠøäR)bà«<°ƒ Q+D ÉKÈ8Hy?Í%^¨Ž©e.?°œ( ¦i„¤”˜Ž´ˆ½;È,|ܰޝ“ÉˆŠ—3;ËGŽÔs¾ˆ.¸Šã¸¦ Ôhˆ¿ÿ)®È¬H<€/p†wˆ*³i‹ŠÄ ç,½Z Ù=¤³T.¤T޵¦kø üŸ.x_ Å>º‘q;é§1ߘ>{„-j0ˆ¼Ø>8¾à˜¾*`€°j›¿GIVê—àWjw*b¤×HiɆ€Qá÷Léì,¨ÙÛ€8Žh¬kôýÍF €AHê¹­~6êµÀ³H›p¿×­®ð¨pØ4àaëïMY°n@‹Ø&¸^(¾8DMŽu*Æñ-‘¨‚a‘¸@X–˜LpžëŠ£¸ù>E’k,)×€2€+ù0À5P(8->€1ߊq&²…h0°`Z8q…‘ UjAg¬ø:qî€#¦dÊØ‡J´xËùUÒS I?š˜¸¬_™Êˆ‡=(ÞR—]Ä„<Øš°;ˆ‰„ù˜–*¯Û؈ç¥ ãA>ýÉþ…Ñ/÷ˆ‚¸ÖW1ÃÈ=ò“-ÝøˆòÛÓêŽ^$ïÏß$ˆ/2¯1³8Ž¥×(€ RߣH‹åPSÀ€j›JëZ˜b—§V(–3x¬rœ×,¯2¡À³ÈóW¶fkò|Ý€Lv8êŠÐã.Æèê ³ ʆºŽ¬D€1xV9ˆÅþvà`4t :ƒ !J(< „Ðsì)— ‡DÅ£ˆB& %€¯"ÜMt>‰¥€Ñ2Ì R…%&L‰ÎK™fJi“†dc™3``fÈ_2˜€Íª:öd1£¿(íê<2œÒqet+G{×@5ÐEuÿr?è@” ¤€+à ¢ê¹$îD˨äóº¨îHû«¦å‚¼cÀ8r.܆÷S]ÉëÅçqù;ÆVðtºØñ¹ìÈÉr[]L#uÈ3œÓíq÷'µÉ?j,àdL0צÈí8·ÍãwÄ^Yà ê«èYo ë¬&ðëèd1Ã+’Þ娼#nNÍG{ ØxîNßOvä¹Q/ “[åµã€@«Ì¹:À Èþ½Oãþ¼@+Â6¼OÜ ¹‹¶€HðxB88BÀ²äE.PÓøÆPšðn.@l,LÄ1<뇟k”\¼³Ä¼0³¼Ç¸à¶¹°æ¹RäBÁZärÂÏ A`ã +’¡*Ä̃@Aò¬f¼.à¹*гÈ@àÝ ³ì/’ô,(BÅô™*Ì*ÐgÂÓHöJ¥ä,¥Ïª°e<,1BÍœª< ä¬ú(<ÚVÂÅR¿Jª¥} ã,-2€`Œ, ñ ÅQÄÜ,& æú/ ò• çzçÑÄ*ÌÑÊ5cï@>­ !A*"g¢Ò"f’€•b&¡B%.…(U$‰É(™€[b¢LhŠè™¸"c“"¼ˆ“A ¼œ¦FbdT&@d-&EÚd½)Ââd&Sšœq(ôڜͤËx©Õà R¨íXÙà2ã’€jí ¶œgûŽÛ¯ kD.Ajê3¿y–c^6°T®®Nc#ìy"¹`Ì~„ä>-³ .CÒê+®@LŒº¶1*ê ®Cºåˆ1ö|"ÇÀã 䓸“Ñ46‹ˬv¼" ÂË{4 s®DZêP®Q»ùs¯K‡gúÊð«j <¹PKÄâ¼pÀ –Ÿº{ûœ/(›9K—7®tÀ 0·Î¼› ®PHd®D²äN®K_O,¢äCv½»ökÞó÷½ü«Ü1@n®W‡f=÷Y*äKÂxÚÍÎ…c¯ë–Eú+–<"@Á*Ý Â Ë“ññDÚòñ(JªL«ÇHq1r¹c ¿%Vê˜bBË=í¾%t•F"ÈX+!e<•CR™DÄÑ*º ¿@ÔJ°,8h@SBÃe 1ºO€h  bŽÇ€¢Ž¬¾¯”rÖ‹ˆ‰ªb&¬È±€…ò!Œˆ€È“0°DÁ€R"a„’gÂèT€0“$TI£ù&‹L  ”QÅa2t =càS”ÁNDš e„•hà"”åpÉb€eì–ä”™¢5%áÑøhËF.¥ÇÍbß˨º5 H¼Eòñ*[41íkM)Œd"é‚¥áá—‰vÏ'r'EàŽ€~~żá Tº¼ \]D9r¬íš©x” RêºÀ ›#¹JöÊϹrCÅáïÈÏ7ЀØ=¥àœ:v¶b+|/ tÎp˜Û(|ô9¸KFÀ ¥ hü¾åC’»~Fè¹Bcøó‹Ã$+!!“bðÀ]=DJ ¼ åQ \{HrM€*Q(ê»Á`j!.…©rš ´p°J²´¦Pí*ëâ©€ c!Ô-F`HYªSôª~’ª(KP¼VtL,µw2 í+!e´¡Â&\ €)_f±tJ¤t.‰…’lPŒ!e˜ãRUIÉVP¨è<¡b:‰@ ƒ¨à‚…ƒii¶  º@ÅBÔ€ BЃ¶À­u«t  ­7ØL¢©5€äõ{)h±GÒTsu“áGN .À#ý"v¼¿>HUòjDL?¡Ò˜?D˜¢&AÀ8“* ‰0H&N‰¡€ A@)M¬x¤rM+À5±¢à™?€ P€5e$Ë!”yo&À1 òÄWÕd9F«s-±ž@ú@ ü1îÁ÷—€ì]XóqšNÚSåàÀ¯î™ž8@êÀ ý/v‰ QËo.´”Ó#@K«+/ÔÆ?!Ð u^CÚMDàÀeÊÄdãû ‹Á­1áD¹’ð æl/ ‹;,ëKgix±…ã—Š”güâ:§9Þt¸N¸Çå `@ /ý!eÍê‹–W2üÛ¢ðL…ÐÉEÉš¤^1v”.Zød¹\²NÆ|X¡ú—(ÈþÞ ½/¬¹xÉ_L€uE¨Ç8eà¶çÙx-ûq f=N•hvçMð²oB7S¦@ôWØØ¤útP—à ~‚3Þ…·(0Ç7*îþj™H[BB7´0Þ ‹Ã‹v•f $PQ)‚ÕUFª,Ö4«¦a¢µ7Å ^n ¤td|uU.EX‰!*¯Ðu€È`,…µ‡ê¼S¤IÎp F@À ú0‰Áà°À"–Qͤ‰â ¨€‰P(  ¢¯™ wdNÄ@Ô 0$ ÄLv…’&,Ù&À‰ ° ç€#†?äË€]ÖUà<€¶/¢Ž™@*†«¤5‚œrÀ6nÛÀ§”xè¨(8#˜°çÖç€Ú)§0ç· }€@&›ØûÍ/ lGJ&‡ b€V€ °d XU˜¹ëu›r¾ë5— @ÄÌç LP‚hÓ¡öÌ{:/©;€Â/ -ü€óò’敯<œÒŠ6cÏÕb“à“¯ä.J¬ÙÆxc@Ä@‚"ð8f2®€N¼ÐD8h‰ZàÂäOþ2® /w$b@fš*„+ÐlªúÈÀ~À«ê.PXMímo4/úJª/bä;@#°Z› R¯bä¸ËHg<ýD-ožJ¯¤J§Î¬0¦F(qJ§èÚ‡îBеäª IÎFܨbDÊîz€áäªä+ ®D¾G„,üÀdÊB€J¬ä„… M.Gí ÂÕÀ½€ÍÀ•`ƒ ãL³E~BÆæQÎX]hHz€Ä@l@£Å×ÀªÀ›@«€êŠJf0V"8!¶ëЩAŽt@iqH!KZ¼âpÓ # º€€ €¹B'@”¢&t@jÂ&ÚÀÀLÅåà  ¢& V$ÀìÈ垆ê©Ê¨,æ€ §À · € ‚` Ü  ç@ vBL‚` T€ ­À  R€ µáÌ£ž1n1ð†nàÇ"ðŒû#øÎ Ù@ʦÈ2¦.£ì1Bð¯Âäʦá"ê&µ§¦.ª/ 0.°ûêÕÀ*â.¨ôl¡È  ’L¡¬éz€ig4üClUÂðÈ×Òj6À>Ö¢ä)§Ø<&ªB"/¼±$! '-¦Õ’¼ß-PRÖÍB‡íœ¥ªhÂå,Ð : Y ’«.’(Âå#rðF$9."ðqNÞ2ü|P_$È`+þS 0À¨x%(0†DÏâMäÞÔ%0øÝªøKFÈW€Í<©°„c w% LÝ.Td,DŠû*DªÎ  pŠúÞÇ&DÂf€ZÀÛĪÛdLcKpBÊ6à„TMDÈ~S¤DÅhq5I°p4ëË€J©Êh8†i>QŽ|¢ÞbšpªmìΠ&Z‹ÂNà9 íàRˆ«€ œâZÁâ9 [@â¦0“æqÀ]fV!N¼“á©Þ莃ÈùAC‰RMÀ `p"`^`€ž$ÀÄB&µ  à †´``bdä  ”ã^$ÅÀÏ(bdþ€ ƒÀ °€ œï2(ëÈÈàfM%D&0gŒôZäêÌöÒ¦b×EÖÂñ)ôžbñ8à00.5ìÈŒ’ ;N ¤bäËÀ #Žm2êCÒüHJ}Nãú¢ëÏ\Ò--H"î+Ø2'*úëKÌyN65šMÊ0'T„9Ä 1И̢Âtì¡'/-fÿ lm‡0|„ X@­Gôɱ:ɤ9RJ¨2 Ônà­R*/M0è/.I;1­x: r1÷к?¨TxBå&$K?Ä-[k6Mð«[$-Ms>¯¬®®nvd,sÀQmãZë,¼JøDÇVT× «žBȘӨFƒPÛ_1ªFh¸¶BÉÂGÊ1‘t³¤,Ù@|±ªEDËØjîÏSÄKbdPglJ´&¿ŒM×Â^à£`aÀè¶ öPÂùKàîäá/H@ dª.n?‚þ‘x"eHgð뢥û‚jE˜”ò"kèÓ(î¿¢@$ÀpÂ&é€clôUl€  H@ Π å@ ¯”Bd­€ “  @ƒè&I:Ô’è&DÆád>†¯sâë"`n XÒ’tÊà&S9%rVlD-)ou"-¬$©#‚êÕ“oNæyäÊNJ †(¯éQ(ôJ1‚)ÖC‡¯qÂêt¯vEâðµµ3UcUäÔw>:Ã0¢ë ÌyM/ä.Lþ/ þ.^¡²Ñ-­B  [r,ä!-­*p/xÞÖtòÌâñ}ÊÀ.Bµ£!,Í2*$­Ed@ÐÉ’ø.TŽ/žßd9ê2(bä_`Kèe‚ä€*ú†¸,tÀ³Àƒ†î,]]à 9`Q¼QšHu©0À¬æÜ}±:Më ¯&®Wë^Ä,ä5ò[‚ðÂĪ{ ‡Sz·+(S3Qä-CšISˆ„úfRL(O|KÃB„ª‰ÄMSd«"`Ž€V .n^Wܤ,~8ÄS‚²á“â í¡gKjQÓúa°÷ÀÐë”4ÔN‹8à!H”r–i6Bb¿Hì{ 2 ˜ aÀX@ðŽØD€¾Lê“j WF@ ¬$ÁYEަ´` ¢à ’dr²–«ÂÃâeð“GBde A  M` p,DáX}oérQW©´X­g9 K`&@ªÙ™cøŽ€¥FH mĺ÷Dîÿ—˜/%*Ö `¼XÁM€¨ÇÏzl­€K¨ÅÀ‚rΚM°®Þ. Ó ¡‡*ú¤p0u t÷Ø:À›@1Rò H@øú&ÿð øqÒò¥Çˆ.Lá}ŠÖoȯM.J™[„9¥lúš3# ý0Dc¡ ‚åRŠà:Ól.R@|FSRpœ.U÷7zf/¤*ùNÒ‡]ÒaK$-ͬNbñ^²y_5÷Šs«*úƒš¬DÙîi  þˆFt¸vJª}­KxBÈ J †+ SE˜VŠ"‹dM:GÒ„„îXÑ®|BÆê¹¸¤Ã(¦BËÐb:c“гîQÒ†v(°€‹NÈå@©@Ó¡JL`âraè’ûOŒÃì“"irºb4Þ!QûAE²!L0Œ¼ˆÈˆÙn±ª–¤pÀ{ bLÑÄêq¾œ‘À OtHÕÀ ™v$Ì’¤º±Þc@ ņh²`Ï(aа¥UÀìN—Už¦y&n­w«Bë à­Ïs\—|Ê@Êêf5sˆ9ð.¼¡†c~0-N‡˜1\Ê@¬4YØ/{—†/Q*x¦M†¦|#L*P_²t1÷pÏ@$ÒV¡ÒrtVy’,š¨€0K¤T 2Óäu:@2"5Õ\C•î&ÈÖP=¥d-žü£¢ñ(x(.S×ÚZ.\²ª‡¥^ºCŠ„G22oÌoüE'_§"ñãµr„-ÂÒþ=Ī9¸@BÍšDÄI,àä‡$Íé}ÿZª)ÒR&SD,ßòDÐ|¶ ƒn°h,BË!)`Ê@âr¼Iµ5v2J¥žå¨€BØ‚äS¨…$-´$,Q¸9?Îb âšV¸u\P¤k¬BÉ[E¼ڰV[P 쥶¢ƒ.áöYàé{7¨@” ‡;b¾FIc.!H¥CŒÜŽÀ{›j˨­Ù'+@ü”>&C—¹ÂÉ € $Áb‚&¥æ  ‚& @,$Ê2¤z¨ÜŽ–ü&M È†&bd÷À Fî7¾âf7¥@„°.¦1uã µò$ú#ë¡ryMð‰@µl@Óh w¢ê¥œ˜8Þ6}!äޞЅP—±ÉÐ,œµ2Ø`MÖ: L×°C‡â( ÑéC¡k‡Ð.PªŒ„ÖuõÕÈC‡@ÿÇë[~¶.UI®ÚS$oþœàtZš£à˜<¼/‘ÊCd¸BÓîwUåpÌÍBä4/tDÞþ.JdofƒÍãû­’5œ¿ñ³•Êbñ_ÊÝ[žñ@Šúð ./LÉw„¢äªu\ÜìJ°ø0´„~§ £‚O…_8O[ÕîMY1˜H²¶$JªBZ„H©Ö¹…e38 ’ˆK$BÓw2(IV­À®› ÅÀ¬è'fÄ,ÈÀj„ƒ«–M‚æÈ û%ЇèxÕcù ḭ̈ª &¶“ë}À F4{—jhÂBJ€c¸ë’ à¸9þË… äØ;JÞƒ±`ìˆõÁаwH@’B^R!!JU ™k&>k¼£éèûú>[ˆ `f}Õ€€€:A¯GøÁàР2W‚€P€ìF ?¡øŠv9ÄCˆÄ^-zÂ1\!ËBP‰Œ.Q*ˆ¢¡i8$ž€APT‰² rQÄ\ô ´úM ƒÌD1 ð……£>ˆAŽÐ‰:™„F§Å(@Ž#Ÿé“û54ù™\Ì´}Ðú„(b(ÈCöÏ„npÇÜEA–Ï€¼!©Üñ³ì|úu>tÜÒu«›òŸ„"a«ž¢|SÒéõ:¸@~Ñ„©€,4ù=DB†ä"¿tC7 üù•MÁy8½ß|„^À ·S·j‰áÎ‘Š ;Â;½½dújÓ]@@HAŠãé-úTþœø¼éí“¶ì'Ê[¶1À Ú:À „é.*ý¡0:IK¶¯€KÜ'ÌC·Ád3¤£;pÐU:LS¶*B‘¤.  dé!ÎØ„én” Ácƒ¤AF°YÈé1¨é.@íRL¸2p´é%rsÖŠ1ˆ?F¤„jºS§™1¨ÝÃFR £ˆê‚žÌÈNs<œÀJѩ삀‹œ^PÄj,Ð ÔœÐÍ>Ư¤ï"NàèÎî,îmÐ (>  *´AP‹€üî jг¹VUÇ’ÈUu9;¿Upf‚€Ã BuÔ,tƒ“øx¯–j !Z|-¢ z8 Ë€{¨6‚}i¢|YËBêÀÀÄŸ(ˆÀï\Ëó&ƒ@)ñHˆžnñ¶ ¢t²m\ˆ4Þéò»)÷‹ÖŽˆENƒ*ióÀ’®pš}<€ê2. |„K©ò²Ÿ*éðÞˆØIò‡sâ‰õòŸ èC`Ÿ>ʃ¼¿!hl#C›¯¶" G!Sè ž„è‰ñ8„ˆ@o¤§Ï#®„iéö¢Ÿjybæv¡ "|c¡¼þ¯Û|M!@9 ê²'Æs¤í 6Ά‰º}†»{ÆôùhDzùRÉòBíÜ@`„ÑŽâ„FÞJÓðù6Éñ¤éQ‰óÚ]`ŸΕ%´Ae›¥i=–4í〖„q‹úî•Úíà …®—NCZ^íìÎÞbíÇ š-ŽÛãÝå 8¦nØék`k :D$±Ê (6ºYx÷û¿{¥¡fÄj÷ž­ß'h0‘¨—:Fl›ÐzÇÓ+*O¬`T‘R)– eÓ¹éIÎl%PT½o,6  šè £)5{@ %P õ;­Dî5Õ ŸŽ;† F°2Nâü**áž«@(iÜ4Ãñ¨]J®\@ñ*átAGPË[€z€z‰t^,´«ò|‚2ë#ir—ÔÚX DD–rú¶˜a„D$žxêÇ[‘D@ÏÅâ"Zƒš&‹¹„fO¢ûŽÅÎ.‹²"¯Td“kÄùâ`öB#™> D!‚Æ2æ ˆŠ”!x#r|ãHc¿/˜ŸUœÎB¹1DH ¤¸'ÂH„²#&É!Šh¼°ïdÜÊ8„¸„M ¥4F)O€  ¦n³ òK'Òún£)¢Ý‰ð@:E¸Ÿ4Ù¸Ùæ´ƒAs±¦‰Ê™H³ys¯Ã¶@ÌrG𻃥 ôBõŸ·>OŒ¬æm!€\îˆc‘;rt2ð  ;hX8Ð3¤ŽÍ:Ií¥P¯@¯:SÝ…Äé`O u"ó¥6h”2;bäéBн@Æ;aé/ ó¤ÌÀš@Ôé5`OÛ›a¬étŠt–ÀK ý€#ÚéO€ À5 vâØJ@ Q¨E@gPC=6} ’sôÈÕo: ’Nª‰ÞR„ï ÒpâP,ÎìÔ €¦IÞ¯'pz ,úw&°Å@ eG¢’€” N€…\,wÁYW8úBPUÊõW¨È°i¬/Í€jB¨žK” ƒFO“úô0ñ´¹© íÜQqìuûçöF´t!`±Š ˸àaY°¢½G…aœå‹bg@™(ìƒ ÃrB/±T¤øjÉ©’¢€3#t„NˆÅ Xì¡$qvŠþm5ó\ð€Ÿ`fˆD'Ê9sÎ -&˜.TÅr|ÈDŠ k€ÂyÓlï'ÉTÏìkt@4‚øÕé鄸!X„Kc·!r9s$û9°“€‘ ˆ¹àR}Üœµ2#.·ª]<Âm8²PRdÛ¬:V °¡ŽÞ >@D„eàŽNFJ'Õ0íä\¯I§0Z@йU]Ýäw4IЀht²˜Wnì†Z€N‘jO„p'ÙD]ëJ íº¹B–ð`éRéFžéJL:@z¯ 3¥‡“Õ:L¦±!¼EAÒÈÕƒ€0Ìñ‘­=pàퟄD@³IÓÞ•$âàçðžQAÑ×ñ]Rq‘lDB-€îjNS@ÊY‹!´Ñ©UNûXitœWÀ%=›±1, *âwf ë\Hú€¨‰Ý\€T#cê‰Üµ\Õˆ@ýW «ªÀ·àb\RÎ;ÈFpŸU„îBÖàJå4ÜB¡JÀÌ%kâ#Â@2{³ xôPÈ3°¢2˜ºÓzvx½N]¾©ƒÈC/+.2s@ 3ëì¼,iêÕe¹ P@]Ðb@ëì%ŽfXù>¡‚h÷ØÑ¢ˆŽÖ3"I.vV9Xdäù‹-²yÀ ó/Ǽ+ '̇͒IIó‰/Ó:‹“ã6^ù>ë ÔTC6O²r^Äû5µc€ j<3hÝûÏ|äF9¦«Ÿã+$OŠîq/¯U ‰ÝF³’ß|¤"-€ØvãSjT<°ÿ²²èQT±oΔ€v·~Š’  Öawh°ŸU&šF¬L°ŸcäAf„L2Õc¤=`EL°ƒv¾@Õî"¤c¤»`Ü è§vs-¬N²gBFfKÂØ-Ôr¬Þ:C¬bàGgNhÐN`IÊ”iî½`†€è$œÏ„œ€C¶¤Aðè è±ÁNì`Nïø„DЧBŒð†«:xŠ@JNàT %\¤UÁX%\âXƒ ð‘$…®Êc­ ö.¨^-Jjâ füïb‚!r €a&,§b'Í@ ÆV.Lÿ€¼;B²!š ô,XññP.iœ""p êèbÎ@Éf!<'ì ìÐ@†…âóNr'IJ ¶É®“ÆÂZ £FB ´¸‰‚!‘nO õ©~-)‚[ÀPNž!¾ ðÆ­ãqâ'Á¦š©ƒïò+b|Eû"ürñêlj¬Ã ¢»æ3r/¥rAä!ìñ¦ÐÌ&QŒÐÅŒ7‚™ 6üñŒ3à´ Ìï–9 'Æ"§CHÕ£¤óN/£wŽþÛRlÑ$å`ÿï4R€Ð@#¤¯ÎEL:P߃¥#êù`pâ:Iˆ;orFÄHl|ƒ¶^`Àt  #¥à–ƒúpÎOrǫÃzF,d\ÿk'P˜Âˆ?)äØF¢Âl¦r”•Á¢¼àË,Ëò¯®‹ÄjÊpôF¯¢q²g*ŠŒj¨H:F¥êàdjLÀH2F¨Lûà£@€I ‘@Š q ±` ³`@€ e en l·hŠ¢ ÎXKìñ`Šþâé‚‚"¹àf ÍŒ¥Î¨*),-Îýƒ]â"¨¹3º“1½LÀpÒõ ¦\AŽM,4ŒLÁ >b0d`ðêXá>ì<ó°3ä+:ý¢"T!ƒž'Ì0*ëìà'ž^2Z1s<ˆÈ/«'νèÆ¢úêðhžš,¤0g”6fê•BØD”ìB:F³FeΖCŽÁÒV/¯+C çÆ­nLxÚ€mÇm ð1ö;e/ÐNMN],:T¢?‚ÅÀéÆºüéÁ2Î!i'â3C¶k Ú8!VPP*mÊT–v¢>Ct:TÑM£·Dà»" †Q²R…äN²Œ;oÜŠ ¨1@G'w$ÒÕ !.jŒzìðM +ÒŠF¦³DN¦j°ÉÖF£:j”JXcâjðsä«c¥a6ìØòËÀ ±ÀÛ õ¨Òù3 ^jèP mˆ4er”:“ IÄ56%wà 4Pn× ³xNé:ˆÌ®&…0€ T)XNáLe\À†Ø¢¾ ŠÑ@æ ÀX¦:ùàJ´"NÀ^" ö°Ï"ús`ú.ßD«]ÅàÊĤÄ+»HÈpaõôú Ä–@,ç œ! ð T\ô# Bî! ПC¨Q@.ɶÅHÇÌ ^(ÂJ@eây ¾Q%?Q’,xSEãô i‚)z! ôÆ¡*!fŸAíEçʱhâ©ÖÈ.ÀÎjB•HZšæÑ@ç.² l˜$š/ÈCÏnÑ7 –˜ðoyN6ü.l5Ò €²ÊtÖ!,†! ds¯Î!ºÇM>! D@B7kø*'ƒ¥f’ ³oô!‘¦NI\-€VÔ¥â\ôüT.æ€ iýPc¥,T9Wl«ćvÖÇt‹`âmÀ:TËxÒÅvp˜†Çy*ÄjœK-„IÍDW ÿ€yà:À2fFJn^°È:Q’j€jnð ÀaìC"Jol`°zF§e)5¤jÝSîlàŠo@Nó'2¦`˜P<à -SfPRP@[s^PΦR—>Ní‰\¤¤Ž]fš€ލÄn6 Ê  øq< . Ï¿e"} ðã´E¦:jÀÛ@Ÿ1ohbm@Fñ€î 4J” l2Ί"x¥ŠOz"6Ú¡1î"#Œg1@øŠ6X!_ŒàçxÉAbL.Èê–^ûqت0ˆ z.ìÉ}nh0n(þA“¢üœÄ!º'×!xDò*'Ј9296.q¦òB”9èöfùF†ÀìY–.q4.RYf!u:YXÎÖP烙‹œù"•Ò"ì4l#â}Ôz7i­^`mΜAo„£‡†ÎÓu‚± `y¢;k•c¥L$MSºwtÃ'R ¤OôO€‡€`Œõ&:O¢R'*TÐìc¤{ €) ar/ïÙô¬¤ ÓÉ-k¦#¤Ö#]Yã¶qrÖDL§¥²ØØÄk-ˆvf›Ä€+øtOU@¨Ì Žh~p¼æ€´ lP 8p¤z*ß[ÄVh¶ŒË~¥Þ3VF¬\‡ª•k„  ^`9 ¹à\@ë A  °êjÅq©¢  ºÌ V ÁàQ¨¶€à=&ýPH+ñ3ehã/yB W`ËK6äø ¤Ï"a)˜«6 ­°Ô("/yuùg¥â̶t ÏIeg~/¦åa†òÀÓôÅŠÍavmçllÐ!V;qËm""Ç“ÉHchvã@ïr';tBebûŸ |iÎí Y¹¬bhâæÃ ‚i£`ÌQ¸æ,—ƒù»‚ܨÖ1&ö! ièãœlÕ–[´-Y™c¶Õ€½`5@!²-Dóþ?›’œ¹ÑÑ@ýOº­ä¢3¥% ¢/ôñTžSïvt¤ÌmJR|ÿïÄAhþT:\ y d 2מTzg~\Uq- ŠËœFÚÀ”7Ë]²˜,J¬y%–Á¶.3‚’4´.kõaLißåÏŸ ó*÷»n[í¿/”— .|‚ÐÃøÇ+Ÿ+BuÆ;‚ÓÝ®¡ïÎk`Û¦ÐÒ`•$¡¯Ï}2Ýß@Ù÷fÄRwOÀPïžU¶wp´UJAwÒ§7Kä|%ÄMDQ@KçW[``øÔc¶ÁYåk (šàaL϶vò#ƒ 9mѾB#’É(][ø!á—=ò ]þ5` ¼$; C¢(| ó FÂK°Èˆ'¿a)(IVÇe–Ô%+ :Éb )LR,„‘á'˜Hn 2»á"ˆLV¸Ùêz”€§´hT% .A§Ñ)B=ž·a.IŒt=fÂD3Õ%=qÂN3Ô Žúž¶g¡HHf{3&g²øzRžŸ§¦¸Júû£¡*YêÆz…ž½'¬Iì6QE™ìšŽnž†§¥ëOUš¹êZ OSÐõëµ-ÏYSÒ¶Ô =MÏ_ÛQ¤õEµÒ;UÖ×oG íLóÖÖÒí;˜+)Å2ê  ¶ÕQµ;m_TÔ§µ·÷´€0|‰Ú‘ͨ|þͪxïoâ@ï¯âÚ‚[j>¿‹ã»Ç+ø±Aá+ø¦Aì$ËAî(¨Çqþ ¦ã"‚€j Eéš<ƒ#§82ƒCZOŒˆ1Ü «Qº"è²^Åå Ȳ" ‚ñxÔ„Œx"ˆ“Îh3F(yÿʈ¬K4µ"FÒ”ÖuEéjEíü։ͱ°uÅäšO¡'ŒŒ¡,¢EçbB„“Ñyä“ÈÈè*„¸hÖƒQÓµ!!#‚1¡$ä^?Ñó]$ƒ1HÊ„¨ÛTIrŠô ˆMTU”Ê7ÏÑ{®LÌ„• y¡!ZÝ×èM„X•È~!!ºv¡-2ì T¢l!!Â[M¶[³Éö„…ë 6[ Ít3ÄP2 Ý÷*U'µÝ¢Ï_`Ÿ7•"²Ú¨ڣϨ4Ë£dŠz0¦4J§(æé¨ö\m…Ià~žÓèPWÃj'§³×À:£šÈM0¬€@J{XI²=áéë^£ŒkÐg‰Š`5À*žFÔ\›WZÕu 6©©¾RªwµŒ€7˜Ó0ÆÖ;9ø(jh>•”`#ÏãéAêPÃù7€#6’Lp;ÅÒ¸S¤û§‡ÄA§H© pÁÚ°´€A$ƒ ê@€ø:«ä%n§„ï EÁ §€dÁ¢ÝÈ(nB XƒVS¹•Á!¿8†”cj º)] €³ Qê½$c’@¨»B!!yDb;`옂€³¦¸€’y³H¾…C\SÁœ–D$f˜\3áäFŒ.œKf”ÈA!1ÙbëŒ A„ˆr gàšd ÁÈðqˆ§ä$’€ÀˆLB"(„­2P.u¹d°MO—[pËôÎ#À„Ïjã#Š »Ä ­!®Âjˆ|ä Ö@€hïÉY`h›«/HèÀ)¤%¥”p ]X\'§Ä!9òÌžVÂRžž²Ž¥¥{2žÎ}@ nCžŸ¹¬GSAŸ'¥Ä£¨rR_™$öy\Ѐ =o(òÙ¹3¶Îw®ª 0+"‚ÁµgXD£±º4Ol˜É (×W.ÀøqœÒ2ŽIöbIà å7â<» Ð0n!°¸Îò¦eàï7 ct@דômKâÉ —ÜÐR"t ¹s¼Q!;Í"0*Ïæ‚¸LG‚xï g쾺ÑeÒ‹… IÔ’7µºz 4 °À¶ƒyÀ~ÇÛ¥0Xpp`§“1—‚¼ô)ªÃVÅÛ¯5’yW)+P¨ Lçm‘ՠȢôk´ÙkÈ‚ä&Æ j‘©½ Ø<§£–Þw~mrgNŠQp S'›—ƒÀ§mשf¢öú`Õ: Mr£X¦ÈIà<{‹%k(ÌY öå<½.#7.#¯JX Â!¹; zI ¨Y yï@ÏÀ¤ˆÈ¾7§ðü…ÐWÌ“:q‘F> OPsäuc”~T ß&xŽ™"®=(û”!𾠬ƄH¬挰Ié" X°ÏW⎿×ÊôL8¿òŽÃ1éG­e߬òz@®Ewâz¾À»' `µÖ>œ‡d5¹oz$B¼•¸c†ÔÏc€Nó4» i“ÝÍMª#PR­“Öw´“Pp¦€Û™à8`Yý¢Àl È  ³ùµ¤ë8¦@ÐÀ'ntz/€E,Öp§ ,}.ZƒÛèõ€ €IÒ,8Àc¼oИƒ!@7:¸5Ñm€£Zaö€¤ˆ1 €¶0ƒX80,‚èx¶Ôû€ ¾ Çñz3¾òà-Q € Á€:úâ-Q;§Ác+þ@±°»pÁ<ž`)á<´X7k· hA©þ±C™ˆu«:軤±S!ò9q·,áåˆéåB m¹4$' ²L®h©h?ˆ¸àÃT6${[”à„㈠98­`[ `„ÃèÃúèŠK¨¸z1»0¼h¤K¨» G‰ŠÃ€ :DFX¡‰éˆôº`Ï9Ô:; P 9T/ˆŽ¹ÓÖñ ”Ä|Ák"* ž¹ó¶Û=„KŠ9S Æ%(„§8¿ àB’?=èž·ôd+ÈA¼ZyÙo™Xž²ëÀF°˜Žy–¸< Ï2:[ òe‹°£š{Zu=R‹ jq%`œ@£¯sšc× ëòd%$zFe©–úxòŠ:È€P‡“+Q€…j€ò?ˆ}€ø€Eò*@¸ï&ð½óðE <Ÿ 3ø¬øIb•¿ªm€#~"S Øþ`0÷ØŽœÈƒA*ÍÀz½¢2*ª©È˜B¯«A°8ÒEa»‰”(6Ú¼…ˆØ€/øy³Ó‚ÊáäISx ðƒ;@@ƒ:Œ),Œ²­Ðåˆ{¤!WK|;°ƒ"ÐŒ¼Šãx@ˆ9#K ˜<ç.ÒÝF¸ÈJ+.Kš{ˆá€_ˆLΤKÛˆ*DZ<“3‰–+Ö X..âÝ/I¬Æ‰Î€ ý ù€ Û®ÀLù<°LóºÞ\ã@ŒÎ ‹f˜¹hÎl~L¡ {E`„Î4ëÎ’ùÈŽ¹À¬Iª°ê|pˆë8€ÖÎX(¨'(¿ìlÇÀ¼kÅ€ 3ÓŒôkÆ`4àt€¶HÆEŠ8N‰êˆP<ö¦C ¼äu‰ì{FˆÖ¥LTž§Hèï;p'á¦BÇ8™hž¥3Ýò9APˆ£»¤Œ™ú~ñüÐ zg#Z8ÁóB ²•ð§°3Á €/§øþ<’«>˜Úɪ„=ð‰€"—¼H¼—7à¯è,p0˜*÷ ÔŠ"ˆIˆÔÊ:¬²°ªöˆL¦!™#0&pƒ‚°£!ëÊØik€.–Ø\·J¦£$¾Á©öÓ¸::{L{‘{zI¡…PTÝ> ý–Ø%˜MHbýÄÙ­  €'¤Tí¶Ù¥ŒÄLÈë¢`*™€ëÌ6!+í 4€ e·Ð¬ˆ¡„ج „ŸÄº“ÊK€ @:+°‚¤Ðˆo£Zm€ »Íp„ âá¡„T€ t±ÀÍ2è!Ò€¸6Rä¢ufWÁIšÌË ¨ž¤‹L9ØŽ¬û£ „¢˜¿³ˆ·à# *œ #xž®}v‰êXÇzɺQ‘W¤ýDMŠs èî€ 1E ‘PM[ÔœíÙBú²`„ p2Y¨¼¹¤ˆI.€í2ž§…Yø£ÐýÙ՞ȹõ™Úl5£0 °0+ʘœX9£³ð–ìX ¬|D¨¤GØïò«ÀŠ~ÓÆ‡ñT€¦¨(ž›è°°™°Êý®©0SxÚ¨œ‘Õ¿œ-Ø¿xÚ¿;í3Èþ1·‰ëŽÚ ½©‡FÐ£ÊøOm®0xQlïb(—4ݧEÉdW³lö³Õ/'èû(aK`3•°pQ ÓS PàïQ°ͬœöÛÚ8šÐ±Å ­Éš0Ýh’z¡ðÚ•€(Šà)Me‡ˆ‹à¯TÌåÑ“c€kx; µ^e,É¢…ùN%kUX‰‡ø™hÈ=ðPd+à#Ì|Ÿêö_ÂæÕŽïp©T˜KdˆH!‘}wfùÑ$9ˆN™T (*@MyþÁ½“î€ñ:ÜàïÒ#:°Žñ~žbV@‚ä®ä½Ìýnétß®‘<$õƒè¨étÚ€î­æL]I€¬î—`„52ºÚ.…X X§Ð¤¨r¹„¬f¹ˆ.:=z¯DØÏX“¨ó8„¡…¯6KØL$ÝÎ×2Jlh$úˆÛ#â(¸Î8+áŸJ-Të½ä'¬>! èo ž—„ø õt¦u‰ŽÆŽè@$ð Оڢæ î8rðbc ‹ôÌ€Ola¼ð£ÙÒƒ óºlêþ€F¦ðkîÌÑC2,šòÐÈï$¼q8ÚÃî8ƒÐ žð¸ï2T„i€ƒìÚ‡þÞuuÀ‰í»îa.€ÊRØï(E®–]¼ ®áS58/@€ôâŽ{8€$T‡é„ç콕@$'4u!ùÁ§xÙCd8ðk]†ùå @ƒ€*°0kS’3”ËÞy"Al€ 딲ø(#à­K^B$qÓ³ª1U}¼x]‡ ‘z1º¢Î£æg¦g:ó7 ÝH„×ð¤ôÕø < /•x ƒ$özXá5 *x%&ðôxitDJW¤ÆD™#A*ß „æDçaŽÎ"xÍw{p„û†’‰î“Øè{°aYp¦ü™–›š¨Þf4ë·]¡ê;¸„¯cÉ,ï°YPƒ”"/ ê,23á¿,¡¨ %‘Y„ÂP¹äŸ\# OÛÍ*h ÒTŒòR8xÏb©ŸÖuÀ¿P6ÎÅÞ¥P£ÐÜiâƒÑÜÛ€Ku(ÖþJœPIhê€R–ãÛt”h—°>Äô͸w3ØZ×ðÔ˜¹Çæó+ €&=÷x=¯õ\–>¢íþ< `6L/ éˆabò‡_à F#AxÅ‘Çd¸àY9È]ñ ´„Ç™Çf2‰ ¦9º£IÉ vöz@Í (¯9¦FÝaXêlÓN™ã®°´vw:JB² i_!m×i±éÄv¿2ÈL’¥šµ!CÆ®±ÛŒtͶÇBtÙåÏvÈSRj—‚´Z0 ,u3ÃÇ]Öt|ÒÏ—ŽÄ#y8ì¿\$*,4‡<ƒZqº@BBTJãºÝ}žS²š¤#) ZBþÝYÂ2L„Ï!JF‘|\g;ÉŽòã¬Ù K¡éz€D…/t€¶žï|•!!È_=4‡x)ÈV2e7㣖d ûÊÕ· “€&‚B}<¯;'‹Êò¥-Á,ò™É Vò€/Ô.¤![Êð£­ãö¹ =?OKÊ<£ôA $$CÊÅ€MÊ€GëÊ`¼¬Ký€EÊs¼®° $&3ÊíE‡´m"Ñ`ò¬qcó+m&Ê „ò™o(´ò¤àÞò”(:8o)ƒ—o)Tò(Ø#€@(82ò¯ Æò˦~ŒñYÅzƒ³1`vƒ€H<´@È9Òò² $eIh:I³€þƒ¯ h†h;¤šha°‰‚Àò.{®LsH©ÖÉà™V¶…ˆÐØŠ(ÐÀ<èÔ&%J3M è¼±ö‹j…¨Ù"9£¥€¨Ÿ;øÓhé ”é .Ë`ÞÁÛhØP¥¨è 3€ªšV‚B£C¢C„£ > Á›‰ÜŒОã­Î›HÑ¡Èégic,jÊÇëîŽÁLe’®ìn6ŽÏ²4}»iM.  #ºëb$9 :i@ ù¡¬á"C/£·y«1B#¼I ÿ¯1»:$%<ªÜé¡ B$%®½¹¢Ck‹DR”‡»›Ên¤9J:T?Y £²¾øp$$CZÅ“º:Ʋ)È›)|ò€¼¸@ެCÊ>iï)´ҟ@ ¼¡KË2æÒ¨Ë#¥ÌbòäèïD‘`å¶Î<ÌY£Å‹ÌØò‰«sÊ[v“ŠîQ±dVK`ö–&/<§+ËjÅ›„X’€_'8ôÑeGIš/)˜ò‰ˆ<ÖyûTž[^à–ò·€ šˆ’ú ég=p´Ôš]eIªá×RiAIª"AÔú¥ €`ƒ³õ&8•!‰ÕI€2Mǘ¹ ¤цF›+0(‡‚4/ 3k°ØÆB¢6–au`šâ89’P ÇX_µ"6ðHê™#q%§Áúy€¿kà;±„ `:#F ›CBBå‘#Pú,¶â:Ha!oämXÇ5´tE$!ÅÕ2ò„F䌎 ƒ€­XÄ…B‘ÐsÚi;R¤vŽHDÙ!1l”Æ2°ÌÀÈ,ëܳPôÌ{+,ì„ÉR4Îey!ä†bF"»G¤†Øò{f%'¬Ž±Ò;ˆê–F0½‘ÓêG_h}ó<ª²:·@ »/´ÍvÜœù—m`ŽÉ¹¨Hfº)uÄvb‘Ø$JgT߇•¶×ú½QHÀ$#àò¥™øEȱ}¤Vzc2,  "Ö(‹Y豑HyaÂ,‰<òÅ *£ºF%+užP^ð,H0/pñ“‘!ȱ›¤g~›¢,!h²[¢Èx‹(˜y Ä]W¼¤éÌuCÈòËR¤Ò¸§”V˜Æ©åSô”bžY¢âhm IžSZ:Üf8@\Q€ÊB܃¢òÔ˜ß<¬ÁFä¤ÄùFŠN€:âŠ@À9"ÄTô ûýˆÛ{4ÍÄ”€$ 7³<&òèŽ 2O£|GA)l¤ G¢°íHÉÄ#vÀŽ˜°lÀµ´V¸z€²:*‚ÉAÒd‚26XY!)¤i‘Õû_¢Q€qx™ËJH\uÝ´Tu†12B \p˜ÑÐm'YXÀ”ˆæPláÉ!Jò‚9=À,‰ ä-ªüw¸i!„†ÎÂGa}¢¡ä«ÌYÚI ¥Ÿ ›`eHìMmÀÃÙh~ $/dŽŽƒ·_ WvdwLGGÛDDvc|jyhùQ&2ÔQgHÒÉ #¹ätSO@ w1­0äà‘@¢œ$„µ·ÂS–ɳ€ btâJcdE‘äÌÄHr ‚$*¤ú#2ày^0Wt`ýg€X½°ÙЭôòϰ>@TE™¸áÐO*H¹¬¾%6yf`qŒ=,X ‘›¸޹øò³Ô 3C´Ôw”d +UE‡P5ÀœI¸™ u+BêXRóòã%&³QdïD”½xQ®Ï,ÓpÄ4Á|O€g7ƒ’`€9ü‹»€d5‹%2“d` †©7÷E@YjN*1ÖAî~jNB¤Ü£ökÇ•BB›ÈÙÈ„1‘À ­0Þ%бoa/£J†…É”5F¿%3¼MÇÈéÒ”\²66i ¡„ %uL…(:4 ¼Nóè¦$7bl‚z ’†6`€¾HqHu8$Á l>Gz™§à \CRMq73+©¿#jéM$tšò²4¦1ßxâöç¾xcè_© ŽÓp}0)ï«ö‘ۮG\–U†Dߢ;â@ ,[¦½¸kI~VþÛÀÓvàó ÏèàP@ ¶ÄþoÓÈ0ŽÀ þ›mêùƒ@Ë<õ~(²ê8Þ NdvŽ€(©Üˆî¥í ΢̰JxwÊ$=\\æ‘g@•pÊŸÚ-2E#y¼l‚ÙåìÚaI{Ò‹>«9\°®7¬óÏ+PIrU ñ-<<§òLME‹BKfIöNºGE‰¦D }#Ê|Ïôðö"Äâûå&DÀרüRj‚FzmdÚgÌ# Á n"$RlÊ{ì%@¥¢}kfà¢e(O€œ è·ÀÝð‡Kx(«Œãcƒv@Ù€U.^X¯~EG"#Fn‘‚¨„«)®$Å c÷oò#MÉ#·ÀŠ€È® f# àº €ž#  ް1éâ ½àf`-îö@âBòPÖ$-m b:ë`­ìtŠðÙÞ1­î'F#g`ÅBzeâRXâ6œ ŠCÌ #€™€ÑH„ÍB4ì€Æƒ@nž6¬$*®°1±#©H¯ZkÃÀÁéä$/G£ä¢:ăèɰN1ºÄbB/ Ò‘Ä$%z#±ºH-lNw§~,V•à/Šøà }qˆ$)P§*›£õê"N"#¯°``ëîAp8fÚ¤R(m#Ê›†f§‚BËŽâþRP$Ößà¤G¸RJLðJVE‘öÑ’PN/’À„XÁ<ªnRBÄ€k@ÓG(ªÇhî…' ú ¢àÆ,j~Jrܯ։  °`e`|€`wáЉ Êëav³€bÀì…(P‚ÇrR æblÊjα±®KÊi ÝBÙEhWK¡èÆ$)&¼Ã_é˜ jZŽ äÃË0b—F2qÒ #<åÍ#† —k\X©Ê&Ä#p²Áž®º-”1à à •àêm qRÖÌ\/Ùe†ì ¯6ò@ Âvqö¢ 8ó’ÇB4;$%)PÇàÏòp¸éN#@’$1L0â àElN• †õÃ`ÒÀ2± à`C@@s$#«Êo”KDñIqœbSD¬Î‡@%)´Iv¥ H™ÄR®Ñ®o”yÄXÂ`JBrà ¯ýÀ‘/CÊ\o¶E²E‘jØ/~HÌ~N–N&™$<<¦ %‹¸JøNÖ#Êm ²p#ʆ  &“¤YK@¡òœ<«1€ÏàØ­ÎÖL:bÖPbE&z%RІ ÇÄå>פÿòô¬ðB²‚%À5 G%&ß±®nÞj‚bî‚N€PÁC%†}ªp¢4òÑDì²É®¨#Oc’6&$4Ž)EB $'Ú ƒ,¬ÀC`ê1‡@ËÐò´2Î@Í×¢5mbBÇ#¾%8~$8 ˆb;%`ÀîÌ ïj$6Š%,¡Ip8¥€;h·Ï#,„%-{Št ø³0Üm¸¸ÇƒË9r%+ŒÀâBzïT@…%3lÌ<¦vÅ-$,W¤ÙL¶<¶Y?²E7ã ª¸K€C<IÁ$*ôå£ËMÌ"N2’J†TÐêÃÊι5CÄ H4îC¤Õ§Š<µkL²YqŒÜ¦4.EUO0sTÂOCÊÖ„YNà#¥þ× $Š@ÙU óðÆn ¦r²¿“E.qPp ±jäÐñMš¢Þàå€HT î¶nl: €=A¢ÇøÿBaŒ \…§¡Ë¨[îA¢ð° 8u 6CˆÐ°,n3o¸aÿÈAê…È*öY&‡hYð‡HY,…™ÉÃBº±Èœ‡ H[²Ä`ÁûdÖhb€"j£/ŠüÄ¡gÍy[!ÖÁ>…ƒvq#5ê2I!Κ¦ü¬à` ŒŽbŠW«€ ¤^nX5XËJXªeú,!qj‚[(]„…¯rq%£$â7wŠ¡ÅšŠ…š¸2#cè̶dHÉ…ÅX 2!f>#%¢ £&¾,©Šh]ŽŒèY±Ÿ¬²z2"!fòmgë3.[HÈN…‘:Š”Ëâ(ÍFÐùV£® ˆXj…™üN뉢2•gºÓýœ8˜Ã#:†SµÎ¨É…—ˆHi€[ÓY4èÈ’Ù¡yl¾…Ô ³ /¢çQ5jŒÇIÎÖ÷ò"ýÑ#.(&¬oöÊŒÎ4j  ÀÿX=sÞ½€ˆÈƒÅK„ë‚¢0ÈZ—, Ñ¢3ˆ™ D.‘œy€@9Ææ‚€‹ŽÈ^H]€ ¼Ý3ò*E!x$[lš€²zò5$7D7Z¹#/t6’3ÀØçúÔQÒß@ ×DÊLMì›p¼!zžc×â…é jïL¥ ÷œ‰œ]^Baøÿ<‡Å¢À7?˸JÅ[ß[à?Ô(QŸåFŽËâ†` Ú€'j±²&5ȘZŸéŠÏz^p„uVÄÚ:ó›@A;`°‚õÁ¨”3ÀÑÙ—SnŽDÐ>¹8Tì—›úm©ÚD€=|™¢m©ØÞ;X=†©¸'•€‘.ñ6Ú2€ œ¤&¤L-(f—C¥î€‚Bçpß© *GWpÇIw üœnɪLÆ#!ćN¢3 Í8à„êUðBÝG ,£øƒˆÌÐy## •Y(C”Þ!ièOv$W/2]ìHGw±â„'Ž“)ÐÛŠ!jdŒñG7››àq“³Öf5œ)\”b3T€ £á³?²2òÁÈÈJ!bœŽ—R N!}À²È|½;Èлè³<\\BÍ«OX(…øB•Xè™ ¿¥+Åá_BÄ é³øŒù_Bì`˜.yzyâ3‘1ÅÀè¡í€Dzj}tH›îºYfc ÒÄ{øÐ¨€ Ãq4X~\‘T ½—ÄR¯€Òˆ£~émSôý!þäAŠ’芉¾ éDÏ¡à”¤çYQ0è?Ûéêt³›Ó{H×P•€Jªè™/Qô›M$DdžDÏjRâÄ$ìµ€ £üì[€î^!öΡ[€çà×€ã@¼àÇÈ>û¤Úu`}:h¤`úNË€àúléZ7ãRÐb¼¨ø*èÊê€ÊªF!ÎÁdP©ã*!!.dˆÌ†+Î+äÊêþÄð¢!kΠʨB2Ö.T^†¨!p¼ b†%èà!!X 鄺 T#-x#6®úaÀ…Oâ(›âÊ¿ªÔ2/ijbúX ÈnN# J!ÁJ!i†%°‚ï„!i¢æâ2ß Êç‘/¾+Ä¿Âú»àWâ3À™N¶)LDÇÐÈÅ.Â/¬D}Œ>!ËÖ–VÉ" !k\ò"2­éžc #%¦1†±Ì:ñÉ–éàb5q‘TäÇ^xÏt!kr,ðž8,Èô)&0^žl¾küÀÆ Î®s`ÆDLìÇÌ£^?Æb!°îñÚDËô(ÆDÑ€g€iÂ2O?ÏsË¢Š^DÌZû$L{ Õªš¼¤¢GöJŒùæÌ?Ñ&DÄC@þÆðE#ý ÑôDÒ`ØFÂan  Å   ÍLGÄLo²vNËxD̦óeÜqI'(dÚMÄž€ÉA„ã@zRzNÍxPzqìGc.`ò?ϸM¥ kÄmfà€Ó@ê ßÄŠ)!Èô‘²*Aþ®¡6˜ 檋¼žÂ.­|Šâ†àØ|k†P l‹ Jé øªt¢â‡¢`šìôà‘ ¿2ó5/` .c Ò!!n Äb2å1ÇR ( x1B2"( n>ÈtŽÍ¶b1€8)SŠ(ù4"ÊW’|,¨z­S¡³†ê€èSr¶h "nB«³!sE Êf†)rq9°hB˜TaÃý`‘ ®êZaÌ´ãòp­¨~ l ¬`ú+\DàªOà?ÏÔDÒJ>ü8í’DÁ¦?ÈôOÄrtNešlŠ&ª Üêd¤ÚíÍ`NÌÔnºN„íQb¾M­nTàá’›Sl!Óx0 Bê[Ñ p¶?!²ü@­AKkdôòsM.QT3yR¢ê£éDo ÌHý pík8a…ÏBP°ôº³‡¢b¿%ÊëBú€^! b2  ¦! ^ñL5pÊ)¢SeØzpKX¼ÂqP€wõg<#&èy`SuÕ8b”å+à-0îIêé 3f†`lr!oQ4âêÓn#2ö¨bÄÌxÓUHö`G~¬ GàbF¢„@¯b2ÏV2$†£œ¼§cbi²ÏBdñ¼ÄDj0ï ö\E ‘€ÃÀ"2¯àfµÞ!q0LB•g€;gv!p4×"ÂÍ"`Š@· UD¶*ÑgM Ó•TÀ/4häM´xÌÒqŠbVxNš+ôLÄ’DDÐï#´ÖSx¦âÓG¼?Çò|OÄG.ØKèD„P%M£Þ7€  WK ¨À_GÄ®çÈÚ«€itQ×pÄÎ}£üœ†X!òûá>tâRJvUýOÖNÉyãü4 p6!ðÄ­UU‰n\Þó(iL¬!Ô6õh!g ìŪ!׈©,#`ƒ?_‚ÈÐMö ³"; x,§/{zçpnè 8!*’,[£=2†¸÷®šŒîꎭñ áR×`Š# äâ@x¾¢”ZÄZ5˜#.D@]ÇZ1èH ø.£W{ñBÉñÃÍæÜêô!q©;˜<;µïib”ΠåèÊñGo‰aÂû†ö:ñQilx¢3a £åèßß{`ˆpOUˆú½ Ö`c—Óˆãļ¥ ,ØžEÄ'~™ìÈõO =1‡Aâ”Êò°ÝÔT5lù4ñj‚”AĉƒÞHbpW‰Aò°Â¦†þä&§Hí²Gpéà—8hÒp=èÑ”šþ4˜šƒýDí?Õ6²²d?ÌÔG¶VÒ˜§Äu’Cüä€L¢ªÍG'„?ÖåqˆkzeFj¬OA¿`È‘¡ŠEè6?Ô~jZgØS|M¤ôSDh4¾…vˆHì‹à\js()Gê ®– 1Ö²0¢2ñ …€Ä€Ü1Ž©ìFëíá]bΞË(!pÇ'ÙΙx:³–!rŠÞKÄ ¶ ÚBÊ€# ² ¢ @Þ# Fq8ŽÉ.~àýž•²,Ë]™âë¶r!Ê$î‚3Ž«D#5ÆÄÌQ¢¢”¶o°¸Ðð!z[WÂú¸½oAÜ)P§£X}*°§ ÏTŠ@ÀL ^šŠ!v0±|#,Õú¿º5©âû’&ãWªÌ—7¢˜Éד!y†6|™…é¬ÖEÂ2ìÑˬµXD΢¡/5p7£ý˜•Aõõž$MÆØÓ£€αó;š¸X˜ØXÊ/2D×€Ôø}'JR…ÔÐ … ¤|@pIÐW)L¶,ê PÒŠ|K¾Z´Õô©nRCGæÍ£ü­@¤Ò@?Ô)BƒÞ”E›PÕ­„Z—€`€QlôiŠç¤ ”2„o@€ ž@Í™zH@Žk0k0Wl3ž£T9»1RJ ƒä äT¡>ÃÀäÀÏÑ8,±è§@¡Óµ¿'.ÍÀÚ1¿´G”nFMƒ=g¢¨–d!Öu6ªº WƒÂ`ò޾€e­@8¢2 ×càÈ! è¦r2{ô6³á^‚q0ét'ò1§¢ÆÂ‰l)N»X¢Í‰N™áZ ióÉh5s@éàÖµ÷>BÍ4ï‚…Æ£6ÛœTN|­ËÂí}>®·Ì‚30VÜ!zîësšn׉ÂXÀ/³šø8¦„Zæ/§Mž¹c”¶/ +ÏäÊ!qH"”ÇYÌ7p»#(ª²ãýAÃý[xxS¹F®ˆ$JNrÛô³ýkq§Î!jù2pÉí='Tˆ=ü¨Ï$”?ÑÉB®ãßLKŒM«³ç[i$L±Å•ùŒNÊj£H£ý1€Ö Œ5 â¢)‚ ìhXNHf&G¤djI†hœ€òŽ—°<=ŬÝÐÇÖu¾#Z¿@Ôþ!Øà±Ã\Æ›ò†8d’ °&p?2ì,¤^7 F!ÃBÝÉusöy¾!t>á:¸&1¦Æ!qìÀ†W9g`j+@ê! ” ‚2»C°@;D&ÒâP•¥ ߦ >ç>yäv wäbפ1R#'¶EÖtD!$¢¹#W®ñðÚæ:çq¤À˜`ë'ÊÂ`èø•Àž§£y/B3#o_†161íóä«B‡­ûîÑ{‰“šHí±JšµÜÚÚ˜ÑCÔéÈðBÀŽEp¯îcÞÌNÜ< —Ó΢3[` µ|ô{ñjlÓ¢ç"•m0G®¿+¢r`ëM2.?Þ½Ø2ýí#ðà0Mê?ÛW±¬¦ýõNdÄžRR?ßzAÏ£$"0r…™2s 0@öp²| P¼"özö]‚˜7RÄ’¼M$쮡òÇy=ðw†N@‘U¿À”pš[â ‚+ü‚A€Ìm¥¡Ì˜8‚Å€1`Jƒš!Ë8³k„¬°°|¾.‹‡42´¨)þoÒBQP掦0‡,aÏ(r'e‡Õoò‘Ô9im+¡"¨Æ„•b r·c| âÚà€.ª ¤!"zz)39€22 '_5ô¬„ÍHH˜‡a ßÖ©¡â‡¨p2ƒŠ.E|Ý!%ª!2â]!Á‹}“€9J¦‡ Ƀ¯nžgW¡0Bº`V¡Ô‚y ù¨ €:6‡I(LQ¥!Úi‡MJ\„Ûú¾P‡kOî¸é½Ð¢!Ú^Ä„ì€ÌÜ ^‡JÎÛšlnnfö!!#*oZm¶¹Q¥›¸ú3¹ ¿jîèp 95®h0‡$€ñ¢ÀÈ„¥€‚‡Poíjh¨ILæ°Ïé@‡îoP¬ïè¥Ï¹¶¨`/è;˜Žh¨æžÎmöþ‹.³ûu2dÄ>€Ziµ=¹»DxÜ?¼{ú  ¨FoíÐþ¿€æ¨Þ\׳Fãš¹ª€}·¶ F¬Ý8Mpþ£RTÄ¡Íf }ЈAÉšá*‚¤àAÀ‘‡nL$rh÷@D8+w”¤˜áC¤MäâAXò¾3ÀUþ]áqK™Â²fýÈHf ï0„º ËÈ*Ï,´š8 ø@ F.ˆ‹­"²ýH(Ÿ!Àì¼U~B\avŽ´ƒ°v ºók`Œ‚‰`ÜëBñ €1q8¢h´KÑ4`:âM™Ì ¡È‡1@ š/!1PÅ„APÛ!Ò*A÷ÐSvD¶JM#³!Ëô„‚¥Ö†£68UàòAÓã7ã”ÝáTC¡$f!(N0€lBO —$%ä.YÇ’béŽBk–“4„œùŠ’YŸ!Ñ®UMg2ˆHv!ÒèMYOèNd¦¨+Ђ€ y;ӜߡЈsž?¡T‡JBÏìÉ!/>w0Îh5!Ô²wèijLÌVØÑ;˜³nH\¥#ûÏë8!1pþ’ª"sE ÍiëuøŸÖÐCÍ 0ŒE€ ?´A`ŸÖŽIÒ!¤õü%óš„Xh‡¨ðñÔbÝ@w¨9ØœÕ59ÀŒFÇ5ݶ«@a|#0f£¤× ÀAMlÔ@”€˜F … :='_ÿCÆ]ˆ–‚#_€þ?‡ôÐZ\gÈrÒ\À1H="&‚Õ` ÈIêŽò…(HR6hPk=,–l Ö …Zéê60| J›w1ÀßjažBeØ{àÎc+NÇ ŒUÄ[ à¡ÈJ¦ x‚ò“qŒÙ„;í%üC·ÄwØ@mîBf€ ÎòøáðÈH± DI24Á|—ž  €‡¶Èv^:G‚Jœ~ga Ú4®Z[²Tvœæ„Ì¥€ $&œÇ•ð²™%üàKD&ò¢\@)Á$8=zHzWLååf»3ð|•OU:rdì˜õ1yY“# ‡H@رßd!Âýbè-•L:-Âô÷jtÆž!<9ΜÞðVCãïr¤;ŸÞðÖç !Ï¡ÄØÞ†vö—tDó‘§±€bN&”SÀœ¨§€ X£›“Ñ ªnƼQ@Zvõ˜–(‡y"òšìG—ÄæÊóû¡ÞøZýþ·‰Î`%cx-Û?EˆI3*§ÀHƒ«:qˆsK+‡ t‰™¹@2×§ ¢I€ÁˆHº+渇&´ •ñü€ Løƒ·–h:ú< ‡4À‚³ô òƒ3vAú0˜v€˜‚„è4HMƒI¡¸‚¢’„™;Á8©03ãn¸x„¼ƒ>oqõ‹l È ˆ<:(š ¨Ër ˆKAz1€ \º0™Ã¬JMÁyi¸d/)ü‘À‡AÓ® š8ü € F;„ÀC DDœJ»Yq¼aŠˆrÄÃ\Fø„ÁŒE0‡2›Ò&EQ›Ðž9¸‡DDY_r¯€ öÄ\t€iÃ+ÕŠÌ:€ˆs³A1݈Le­êÆ€X€ «P)“‘ƈ+ÊŽkä ø=é#ê|¹Øæ¢ þ¢c/ª¢»È=ˆ„´y×?ˆ„µ Ù¾¹ÐFÙu釀? dHqk¯€Vàik€2kH°æ¤ ?‚k#éê°l¿€/Ũh92®“¤€çHèš_$ƒ¯X€í€¶‡Ë…aSʇCøó8L1¸ú4AiIG Ç`0Є¤´—ˆr€E‰(ƒ‘kˆ<§$K £»“«8ðƒÄD.EqŽ2ª2€‡¬4£»¡JÛ…9äO £¡,KB h–š€ÄȈ‚·´»ËÈ´"¸‡¸­8ˆ(z¸„„áñ±C“Ž›Ý’>إؚE ŠºØ!i§tËLÄO”tÄ@‘7®ú(#ð‡B¢i¦4¶€ Î:”_t9 œ%¤Ú§ „™ „Á :zЊʬ¨H‡N·G$šŒã¯xÎTæ( \s*³P„½¬é·ð¬Æ@µ¬Ë³JXNLïIö0Å0ßÎÐÎäå)D»­!iÏsÚ€Ú&ôp;Ìöˆtr³ƒEXé«‹ë%¸„½jm ËÙ–jwCÛé.8æÅ脟Ë"I•€@4 )‰Ð4§sÅ*Z’G“È9p*Èú >ØQĉ²hæÊp(jè>IÐ6¸þºÚ¿Žk&´9ö*5}hÇ`Fy3\‡»à~¾;ùúi ¨ˆ- òÍëg7P`:(}‰Pš-3ðˆxƒÏb>¸) €ð"B)"ÒÓ¨ô>€†€ fŸ$¶€Od"/r·ÔXƒŸ€ÔjÈ-Ú èƒÒäˆ,T¸ß/½C£Ù[ Ëš-xŒUÿK¢¬40FŒÆÀ ˆ(À„àÇÈŒ¥ø.5 J?3 ”:¥ù7ˆIø9Ë› 3Ïc/öM*ݯ¬¶JÉUyi¹Ó:=h)4K û'5C;OˆK}×>²P„Õl½‡)UWk ¦ð0d­ÖMz°(„¦ñ™²L{&è‡TÑ›3(¬Ø(„˜FŠU:(WŠƒDñÄÄÉð€§Â!Ŭ ~í9š|S+Y£jâ _Ñ•NOáÐ8‡<ÔZÎ@þ‚U±éÓ’aÖ ¨æ›¡‰á&G¦±ùÒˆq €àLG0„­2¡€¯H£ImŠŽmP=¼lÀ ZÓ‡Ip*,\©øXËS¶ø¡˜}1ø8¾N%0ÖHGø0}†‰‚€ z *A ‚ª’¹k„D>‡Š¡‡úC˜‚›Ò‹¡Ø„Êû‚ˆÔDJc-9-HÒK »¶«›S™™à(M: Ì£8‡\|l<¡”” :ř׋à2€ ŸÜ`š]#B$ð‡ð·C‚¸êKø‡¥$FˆÄEû:"cwÍ.ˆ:~ ÓßqÕ`Û²‡$Ùe׈KÅQ펖œ2ÁÃ?ÕˆÂÄŠ`þŽzxT­íÒPFO81=–Žkq̲2€×Ëó¹ ÞǸ_%ÂF0õŽmá(›‘=H=< =˜lk˜È™ÒxÉD,Áö6øQE^M:ëÇ>ž»PmÇŸ æÐ%€-Z#ÍHM§´Ã /MØiÇ¡ê“Y–‡à•5%1Œ‰è~ŒPg15'0i™8~˜C‡Ê@3—âšÓÔä/@ANK›’+¸*§ÀÀ„®‚¿IXäHäÔÞL€ üßš;¿ª×׆BZJ•Sœe¸ƒÂÕɈ:ú¼Sû€ýÍœ,H±ucº‹Ÿâj;€À –t(1ƒ|ÆYŸ€ —P«ÿ×þÙ.}Ïå!*ãѬÔkmNaÓÛS@&Ø1tR4柙ÐB€ÈpæšÕ¾Œu’am€?žî*ê°à€lˆ°ЦΦ°Q¥06°°|'¨) ~l_ˆsÁð¨Øx@AÛƒæº]ˆ!àv&ƒÝ%ÜÄ K‡)à$|€ò/¾Ì<°ìãqÞèT‼¶[sI”È€ I¹XP䮵ø‡5¾SOK˜Œ2൘=m¥û†X@Ъî(‡(Z £­¨ƒåT8nèxˆH78Õˆ„€8,è‡//a¶ø9û”æ ÈÎÀ‹ÏŒ#ŠË½š͈; ÊK›“`Vû‘¬š¶HŠË*×[Ð$ÊÝ¢cÓ²«MHð@Ôßr ðw%¢DW7 ¼jvß"*pßi*íÜs€pxΑ¤VˆuÖñ;LjـåŠÌ¡€Ðc/2 ß½ãì›0زƒ2 ©Í‹:‘\ª€ ÿL¬s3“¿í ÙÞ-GøÍHaøŒP¼­ÂóFÔ= ¼ë•Ѱ–ŽlØ€e€ Ïᤳœ‰o+HÒ¦©ÁÐ"Ð49sh§y4“Y9€‡ÊFz„üÉvÀž2؇ã‡Óäø,!uôs¾)$íÝ»$`pusLó‚Ÿ@1>{VÝ Lˆš,hNRh²ÕÀfØ‚¼‚õ·ª.¦_WSHå@À]B¯=¿B*ÒT§m¸‡@3¿ÂÓ-!•ІحÚÁ¶hqŒÙˆÐ ‚ #ˆH8®²þØ„«±ª% ú(&Ðtñ8+ÑÞf/Gxo˜é¬‡QCÙîò15£mhoÀýˆs› ‰¡…œæ,x1¾J4›„H®3×^ –›=x¨ïLL¡î•øøO‹³]÷€ ox ‡x°¬Èù†<¾Øi/•øéklõšãÀæ½\Ý—%Ðæöv©Ñiê°¼À ¸w7K$é²o°ÚÙÀ„굎yøþ¹Öh]£ñ hB°qÐÿ_ëuШÖí£¼ƒG±cÓn³_5k NaŸ¯=P¡Ð)0N >E³Žie€.€öZ%È?kq.”Àj °~€iŠ H`sBÀ:ÑèXh}@7l츇g D ÀaµÜ$ɰh´ÇÔÔHŒ¨yn»¡Ž ¢—I€ ÙÍØ¡ÖèˆÁ„€*JcµY:ÕÍP‚ã#l‡~OWãËÚåÍ„¤Œ¤œ{ìЄÏÝÙÙ²»èÇÙ€hˆ(-£˜‚ª8€6„¯Ü¹ñ…gß!h˜ìP¬ÿ°@ ^p„ X@#‚£¡HAÆŠD”~ByÂP€¤<ŸK$oHB¢Ža È@]˜GÕ0„d=Ë=Âó¸üô?Ðcô8ø–Ä„e”ª`œ¨E† W„VQp‡4! 6AR9}–gŒ! yÌRß<¹GÝ”kuÂxÛ–0‚ 7zÁGÑ0„º:b°9A÷/ƒ€EhAÏ3nVã/B8An¢·8/@{r¾<·Icê[rjy·srÜóæh·mÆxF£<Ý·mщ¸n [ŸÐŽfzB[¤ùàÕ¹án\[‡Pƒ6ž€Œ–嵸#n"[™°@{Ö+·'íÊû<¿€ùê‚ê~Lšd‚ÀGË`­>È!Ø”€ó²”|h{#À ¤‚Œ@²‡ÃNg¡2l¡îP1!âÒ ĈìK“È{pÈx0„hx~–?H):„ˆyß JÈøB„=è+&hyC+¤D²‚Ë`¸‡¾nŒÙ¤r(£ñâ )r× ­Ò>Q¡!Z›M€ ‡“(DüÎQƒÀú> ˆùX0 §CÄ©QÚÛ"*ÑÐàâØ‡µHû§O!ÒJ2ÈøÜ„N€ c^¡rX¸#f‚¡ûHœèA„hAr„:¶M§o£÷ ?rݨD“t$wPv.>ÈÞMýèÒÎh@%n·æÚc!Šd/wBÖÌ,ò5£öC€HEPžëp2Œ×KqÔ„Aäߤo <î£æCĤ@³Á’K­Íb?’³ÂÂL-Àôq-Æš­Ó´Ù…€Eº/-׈#âêÜK-ÄCLÏ\à°˜ët¦ÏJ¬ðø·ÏZFh>Ëp ·GÌòÂÏiÌôŽí-Á2Ü­ÅÒÝ€¶k ð ‚Ø6fÀú~Å  §µ‚_bÐÇà U0B –#óà¦#çÇ<ÄéÒ C.B Œ€$j®óü÷X@Ò‡‰(D#_Dçú¯£ùò?˜ ·ÕÔ¡þ&V‡êÈÿLŸ^r ˆøJྼÛO¡Ú>¶ ¢BÂû(G@´H,††è@Ú‡ýÿÕ_RA’„D=¡ó¾XëëYC(ÌóÊAGÚw~àR  È(«´%ñö ƒoD•”Òxà2Ô%|Â>ïÞIW$‡Âb> ñ…€ΫòŠÈ(°!бˆ@=ˆ·Â>]o!ÝåC'ô|HúÀ1A(v.£ˆ@:ˆ±eiŰ΀ ®Š*EHÆ&BG __fyÔBâÂÉN ¤Ò>¶ˆûïŠñ¹…€™ÈCà@ÌÐÄòLðF! ª;D À þ3Âý¬­3:˜h‰@Ó!ø^¢!l €–[—³ÆQP‚–L[ŸmÜ·=·ð[£ˆqà g7gä[¡QfyD´“¶àbd3ÏL VÀ[QzÏÖdãˆgŸ¸Kæz[Ì Ð ôßLÐÏ$³<0ecl?„i4G?Õ{ЈH¥#_ ó¤Æw°±¤>uœ†è#,džöü%ƒÐi¶‡€–CæØ~p•Õ"VêD©‘Ó&(â(9q`gQu¦Õ+ƒ“ÏH„JºSHûÁ£d|5ˆP½(Š1%”ùVÃ7±L—ÀP„~YùN锵¥ ÿ‘óî¡æØ1ä}Ö=` AE¨N_!ÐŒàiU)‰#ôD¸°3ªZ%¤"ŸÉ2IH*þ†KN»Zó‰ŠÍÌ "Y*BaD »UFâ[j‡±¤~Ç—ZêBâ,‘È‚øÁ(ÈøS{–€Ú(ÞN’Ô…!VÐÆHgýšµª¿’7Ì…5xµä"Ü)œg¤´8·Öܾà|Bå‹-Õæ?@°Ãd • ‡ ¤„2%Ï6r?KW©nFQí½‹³0ž±Š€ Ð+M2‹ÓÕ e¹ÙBù[¯ _–†ý€ N[Œª=jÄ@5 £ˆ¥  F#} gt3Òý±€+.˜ÈVÆzy4 DÍËr)BÌ· BÜàU A ¤:‘3ƒU™ÍŒ!@ˆùÊMÏeŽ‚î˜BOxV›Â ±Šb!~†‘ÓŒGÕxGD|õS°ñ€ gqšÂCòÍ2¤$!Šˆ!åXáð„Ñ€í5d"}™ˆë#øð^°”h!ùøèÎG)å¬#⇹0ÜÀe!ú2))ÆÒP¼; 3À‰ÖAG(YN>¸²Fb¢ˆA]‰ OD0‚ õVe¹sɬæ;x€´Œ #Iú‚Gà(t@ËÞÕ²,Cæ+ÅiÓ¨þGå®ÈÌ3ck˜=,AJÊÒÒ›ƒl);M·4.!\½Z@´ùTV 7wýà¡í飤iI)¾À >Ï÷hßîÒ?¸9ý‹ dQðwGL³i<ò.él[²IÀk6Ó€%%€È:èðÛØvÉÌV(œã=­ #êM$“êüýkª!øJà™024ˆ!ŠIJb¢FC§¼EŒßp”½‹ÀEÆTBÜ®ªJž&¤¾ôÄÌÊ£œ€¶ Ù`>¢? n}±ŒXŠÜ RòbFóá†! ä˜ ÞGTú ~ ¤àÞÀ« ´ž!êÂ6‚>¸`÷îøFª‚êÜ*„¦ü(B&„HÝDL!ŠÅÖÂ>€ˆ  Ò-ïú"B¢&€è'n#ñʼ‹ „±¼_%ÄyãŠ"ñÈ0ÄÑÑ’ZfBÁ‘`ZqëB>ü‚?4$rlÐmkÂ\ˆâY(ˆ„Eét^èÁ)blm*Œ·(†¤!Ȳª!l-É+Îÿ¦*\à«à%Ên¾…ÉL’-ÑÖvÈ”'d;æ^%’PJ²1Ê邺ÂF)€mà£= @ÅB?)ÃlQêK2(>R ÂÐäΛ¼îÜC@{À½`Xp! ¤nBÝ‚F_v@-ËjGz3Íz¼NМRlNHðpîe£= ŒZ;qÞ3ÅF¾Dt.ä£l‰-ðHöÃ8%KZ ²L'rD§@¦àÀ®M:d`ÿÜñK»qæ! î ¦UÂ= ¢#àúbÔK"xHÈ«³ˆäóì!ë#N÷ 6B äÁ¢!îò)bsÏrÜz`‹sÆ$là¥4é³hK2ítrñjM³ ¢¢s.² |Í‹4> ¨  ‚%*Ϭ%‰{@ª°U(’!>I{;çlðe¦•$¤#óB&€ñÍ$qò–CIt›!¥§,³Œý"ôôœ¨â¬öú+V$l @O@L2ÇLbâMzüÔÔxC=cN?-£”H™NÅ#-úR4"·Ki@4Î_ !h#î\‰2—®‚QòGZi*bÂpøß ŽÓ:À¯Ã·DÂÝ¡8 ¦€âÀDéÂÁƪ!¶O/GXiB”•Æ ÐC¶•É~ê3è3Çe1 ;0ü-Ò´bÝ . F§éÆ-˶îB€%NF7ùüôÿ;‚P‡û’R H“ЉFÐ4D‹ùx=ÄžôŒI+…Ç‹pòôJCŽÇç0÷,IGQD¡ÓˆV—‰£À4JƒPÏ#1z<‡—âFxj$ʬԣÑðÅn\WªÑÊ­²<臨!îÈ’¶Î¢N˜z~$ž‡Ü*Ñê¤lÏ9Cê1ìonÂZã¡hyŠ3áåØ{æó£Fó À/…È€^ðò¬I®ÑãfCLl,±ámÙ ¤m[ CÄùü”I×NÃÓ÷t=W!î£üxß&6›ãn„0õüÂçåõáýMÜ|_h9Q.ÄoÉzµ‹¡êˆ|R6šïñm`˜z²b¡ïÂ6Þ¼­Òb–Hym¿0*Ö4¡ã²ö€0> ‚•Èyã ¡à :I0°»Öû¡ç¬B\¡áƒ¥ÀD"Äf«Hù!žÈẋ‚‘ >}!âœB`¡àœB2¡ò€ˆx­³Ñâ?"ÊaëÿQHçD2ô§0£lhßÊdÊHÓŠ6dD#|B'Ä+@¬JcÄB¤Jo€D" BXD)ì¦Ä)ü§P1 ÈlÄ4d¦¡˜ò¡ð¶¥(ñ ä"TB6y8H‰R F'"Fú6¢Fª~¢Uz6ù#Ò6(¢@cPø5&Œèx|‰’%Zi!ór=£qsrÁÃ6a3@B×uj?`,:<)!ï=·âr#Áb#×uá šh•Û‚ÔhÜ~+K]ú_öÀµ6B>!á✇àl„2Ž…hx×$¢Oâ6æ£bZ],jXV#c`áuŠÈØ¿MIÀ‡Èx®‰]™”w!溗£rR=C?Ppl"Dzf£rà&#m€ÒˆÙ§¡çÂ¨xn¶ë ‡Õ@¼µƒhy‰&¡æÒFmët!å:$î;žêímØ ‡Á(Øw¾£{¢7´ð(ý@–úú7¹q;øÀêÐ6²­| Å[Jo©¡àlRóÜPB#c„å¥#@…¬!âDBG`¨ˆÈ},g(Þzä@ô J·PrŠSD&_Oˆzg)Ú2ž¡‡Ä>Úpqæd€gØÔŠ7R€C¤CïâˆØÕþ VÑæñ)‘QpˆDÂ!j |œ”À:rNE)¨Ñ€=‚ØÃPˆDŸ W2 Ô@G†^K¼‘²ðG‚9IªÃ±Èx"P\Ã$6X+-°Œ ¢Eˆðd†+š(+Á¥|DA¤=ƒ€ Ù©`¨h‰E6¦ØJ,Q¼€$zBC#ÁÄ;°zÈÙ]îÌ»b6‡Èô7lT‡ÈxJnÜ g#ÌZ/3õòÅá$q€“«ˆ†žG ÖU±°gˆD¬ø= ÑYàéˆÚWX4€‰G0ž‡m¶ÖÃR7J¬JdIí¿œ+ì%dz~ºÒËl #j8JàrÀ Í ý²Ët2»€L!ñÙÉÅÀ]± Qp7‘°L ÈðÌ!õ‰l–Õõl€ ] ˜â²ku“#vôºâ6½¤‰ºåÅM›ú†VÓ!ô°_JZðŠl"L‡½æC§dn]FÄ´ÿ#lg N’6V®*{†ø‡ÓŒJÒ0¾38j‡ÀìXÞ"#fh– vÚI¡Ð‡à€ûˆÞHª…¯ˆC}ãRS„<ˆ¿'”n“Sgj­á¥GìZSaϹ7^Aè"<»4If”êcÌv38¡$¦Ï@à¥@A"U ñRhß$¦ìò˜ „x/@¯€@ E}"6Ñ ÷¯€¿3S6ˆñœ#q”«Ù³ 7ŠxàÁ ÂgWo0€óWu‘ÁuöÄ£‚6Z×4ÄJ>¸ `ˆÜ<ØÖ܉l£O±@á/§Ô‰ JÊG¨üm-»h"6SÀ Ô¸&¢šÛr––@ý}x<‰I€e˜BÒµÄtÿ½,I@zž8„Á”;Kƒ+ó5É ”0i‹ó#Þ„z½än¦æ/•‰ 4ÈØe6 †Sf¨Vû+¯8o€[²Ã"SÌÌyÖž‰Œœ®Än§c0òHÛ ( ˜>/zDÆF=éK²Ì2Iº1ôjht€hÊö!ó»JÌ&Ú³pÀëûäü#kvÙEÀÕ0i`4¥ à_cuM¬º¬-~#£JĨÂ@#ÁH œÒ`BåMxË‚k ¹óENBÖ¶Bdô¸âcw‘^"P¨ü®]#uS`¨ÞÐ"-UÂ×Ss §F„`KHþ55U2‚tb?Dl#õg8O_Â71ŽÝWBUuj!å¿'sWl !ô9û5”Â,»>gsÀÌ`ß ˆ¨#q°p ²0Oâ ÂbA§b³¯xõÀ¹ð[³ò#`øD(ú]TGfÔÀ¬ÓdCZÍ JgUOÀ™ÀFÍÈQ€ÕUåI Aj@qPD5øòsèyI-#äÝR25*­Dkb"Mo`.|yvJOP®jÖFytfR«³ô"LÚObÛEvn"VuQS@€åÕC3íÀEáHed"Tnç07t’•MTã##!I.#Ô¥!6Fç´x4`øedb?ĤÙ)¬!àð,kžYÔzÂ$• 5\b$RÀÙLÓMc ×ôïN´ãÒ`µÁ¿Pà5 P"=OÂÖ_P‚|Â%Qëž>ÐÅRÒ6Ž 8õ3ðî#íìç°V#vÏ+qˆòàÉÔn¿ðˆtmsF÷ B—_V‚6÷5ÀïwkWŽÐ˜ŒbòÂÖtp»A¥h¾®ºGG€Œn‹jT2t·2ðÂ>Œ1x Ö{s k2—Q'XðpÅÕºy‘òµò5âPV˜ÂÃBÐ"H¨¤C=B7Eݯ=a´Úv5$xà€öÔ§ĦBÉŽñààaÃ0«äBöÖJm†Ò!þÎâ>Ž žoÏ)¦×hs ‡‡N¶˜üeŒ2³)]Öˆ§5fÊ "IÖŲmN€ZŒ2^©ÀV‡hÝ*`ò„ÒTÆ!é…'‰i€†¶{&sÄ#òÒÏí,Pr!ø­u©+Nâ#mû*ØÀ7r¦×BÇÂ5,"Ì`ìøˆ×`ë`Ž2ÛEV¡’U¸ô"<2î!r B6à#q„¸ëûf‡¨Š-h2»O;¨ !ñUÖ´¹ldG*ø19Â7“ÌÓ#åËHƒvâ–ɰ#užÆL@†èê5N¯1À…b6ø8Å@V(3 –&’Œ)ÆG=)¹ˆ7uÏ+ç;Vðuï\j–D3©š¦ùä!îó90³àLy¨þ0@Oê§ÂU\JDÖE8‰A#È’Õûñ=Ħ¯Y··‹k ºUçŠdC\çX:$r!êøRPUðÀ@`ø(£îµÒ"Y0±Öò£•Ö?£­\×°2úk,Œ“i–pÀ‹.–Ëú¡Ú5b<üº<561N@@íÚnfºs/²å«Ž]¦L,è Ö¦#§2h#hÏ’"J^¢_ÂX.&GmuÁi–´#²6ÂÒ‘DH!÷Š F#úÊ"Q“Ö´yuê#͇$ßRÂ:0Ÿ #a>O0b7 pˆÞ'–¬‰@>Àš¢>¿÷'e…N¹4+ld@ª[(ÆNšS’3”‰@!ðpÃÛFÆNó Œùµ.º;/ „mµÌrï@Jh;hC.„İ‚[s·b®¯tJj-r{‚;ħœù\HäC²d„D-”Ìõ}D¦àuÔuç± “­Ž‹ª$¬Ò‘RD26£¹‘4/Bƒ1y1"¨$BÔn"O^J”O€C`qí#Xì RÑäCö¹‚a¸BWWD¢%DóXﺮ`¸Ç³)#Ø+¦û˜’æ¸ú#nú|± Âqåâ%šÕÍjøB,u#«ø#mÍÂ"ëû"N4Ü”¼#Èž.N-ìÙÂì#xH=B<ï­¨#e-ÇmÒµ²£¶î#ã{jË"X–f²rÇh†#Ï”¯\³McRàmç©ÖáÐï̃.&Ãt²£sN/¦­©í„å®L ’ä`6ä /Iü¯£b6œ xp‰J ôDzïZÙÏ›â%!=ØCu§2š¹1JÒ†“²ùÏUÏ”_ãC0Ãr|b=C¦’ÖùÎÚýP(ýTiL,ÝÛÕ$§ÔbiÊ5SËÖÏD!òb€§'c6KLDpÖèËØ«Æ!ýNs–D.ÝTîÒK2ž§b«‹^ÎÆ#ocÉ2Jr›'cš°¤N5B>ÄàœQ1h`E3DNî_XDw½îjOb"#ûШ`tÊOFŒè*£R±9ÆyÕ@ mzë¾B$¯ÀÕÒr­â­Ë;*.Ζêä4«§œ3R‘v"U´ñ`Ä«ÀYîüëR…ÜÄ#çX¯…¹¬b% öÖÀ•1dv™lwéBÔÍ«¢>•…¬ Rð¸B5•wd»|#ËIZÚ¥ëÿC8Œ¿64fÒ,cwd³À¿0–ôÛ1ô¾ KÛZëÖ+ÑQwFt¶™åÚÅCRsÐušW'MP‰ïL<Ï‹ÿ'`1„3€[rÃL"@è«o‚?ñÞ2E£t‘®\#ï» ïó©]âFçcó¹¡òR#nÎà8!ÿO’`Tª†i_ !åÑy¾õ:™þ¶¢ÅdCމx+ð]Ñ&¢Ýªœ½O_•±À+¬µ®Ø#j¬Lœ‘àt_^5Á\ëžÎ‡:OsÊ©€ÕÓüv4ÚÕ€úÍ\Þ‹ –' Fˆ`Îú"CJâ¸î ðA`p€î ¯ar¤<„A"Ð÷äNA—øŒ ‹ Äxò “‡»#0™ˆ CÌðb< 3“Cß°eô=Å/O'Ó: LC×°hÜÊ… áæ¸z¶ QÔä•KÁ«P2QbTCÍ‘¨5žiÚàöØÅVKA˜Pùt KCCì·Ê ÿÀÀð`—{½€Ðõ=—HÃã°:]Ž­ˆƒaæˆzz »¾âáX ²q‡ÍàóX¾J‡µ`À z?Ú dä°‡¿áûh;nrÛÃ÷Y},¡eCßPñÜeÛËw@,Hz6 M‡˜õùh¿£ÕFCØÐõ‡Š“‹`¡ä’ j; ø¼Ïú p0!ìûœÿ@y„ƒ€OÚñÂL´Á`b‡{šø½*|¡éP<°:z @‡ˆ®ºÄÄÌY ‡ñ£hŽk4hì•hxÍ2  WHˆ£ÆŽÜxHxÝ3ªd—‹ð„¨‡˜q¤"ÆqqUñ*.hFŒ+!éÜ\¶€E’2F‡ÄŒ‡µqÕ:‘r"½€Aš±#´‡È0¢ƒ (|DƒÉ«ˆ16‡ˆô*à¿«䆵h4Þî&tÀ ¡ä¥T õU±"àb )OH0`×´ˆ1¦‡H0]$¡êÃ[2碇 äÒ)YH¸¸ƒË’g€$Ê iF6¢ ¡õÚ% ab@ Ѻ±ÜhÊ'(pÖè}š”ˆ0t‡ÞÖZ~Í \§!öÅk@ÈtÈ~ ’Èy¨þÙ`’ åÖ+pX±x Ö" !âJkâàHŠb²5ŽV1wpð‡’èxr.xW‹¢ñZ- Àª6¡áUÀù ÔÒްšfœój ž î¬øëËÒ‡Û+"ûÉÃùî¼í1Ò+ܶЇ™¨x.‡°°–ꇙÈyF‡Œº¬\ó"äNÇ\ –骠n¡â"ví±w¸ `ÌhÌ fÔÛÌ!Ìho¡ý? ºnhÙO8œi‹ sd\Y¡õ÷UÆ…ŠFÇEUÅÃÔhOçñpÓÖ<]gïÑp= ¢qto÷TXúà)˜>ƒhè´ƒ¨3€ó`žç Àò…€ò^ù¢ßh1J‡œo$œƒ˜0÷ˆä Ëñüx¾ Sò!átƒ0°1è¤â4úAà’ Ð8µHvÀ &lÂ`åȉ êPªÒ/ !D&#˜‹)ve¡u€lalÇá' ll¦ç`[ p¸-4ƈ0ˆGÄsgŽ@Å|D Bõ~E⹋ ,€ÓH{\ nÀEBk#‰PKݧvô@Þ 1à„²î¸ aŒ3ÈY@¨ áø‡£ä8ˆ2{¤=¤˜³*@· rHÉ@(¤U i¨¢B•á”hJ@G e •±Þ[?ÂkˆO!ê½³Ÿl@Ísò)·d¹"‘—ÒØ„!æCÂÂprõ§&€1GDÕ nf&"ù¦!š$K€)½,È!ò©ç4éÏ:IZ.ê;¥c¤›0‚¤ uÎQ µw>4¢éúc d1õÆÐÒ®ºˆpZ@Ò ÍÒ7v[4PC]ÙKVTƒ^cÌe_ˆáF—0Ü›ÊÓ©øѬ‡ß`~/ñJO"æ…{/& jÄûP oh­FÊÏ"ä=_êÑA„AW$_Π k± $>S à°Q]|رýÙJ§H|?ŽÐåH}ÞÇÝå÷€{:rcœ¼øÀy¹1s€ Õ´¡_¸k È2¡‰›þ‹x«È:Â<¼@${P€ Ñ­ù·’€=bR‚Ø„¸7m3ö‹ê€;#ð‡†ä•Âi/$‡+N¾¤ˆªPÀÁÒW+bi‹¨‡ÀÀ¨K‰:ÈËB3]À¹1ˆzü0‹Â„$B”ˆx;št,»Bº!¬/Aê(‘t¸³w«Y5!•ˆp ó0× ëb@ƒS‘t>5QBˆ@Úî’²r€>3¢#¼€;Ð"è°H@’² ±‰¿x`6¢çpÆž€Bj|¥0? ‰‘sY‘qÖ A+ì<€ ˜v¹ÙeCÈ!¤Z¬r¾ˆT% Ÿˆ<€`€ ûŒh‡¤Ôd€ 8>@Ëœ˜Äø1ð¨8%ª×Ú T½ƒ2:@ie1#Ö"àƒ4±zs [t¢hƒD‚OFЋH2ØÂPB:¶Œ¼8£ ƒ)€§œƒ¬£L¡,…‰{NºŠª2ž:¹¼Ò ±ºM&kú•« «› =K\ Yû€š‡Ç`Ç„5¥Ãð|O€ Ý »æ€ ×6BŽ€èƒ„Ø4Æè2 Ø­Äjˆx;*Änˆ{Ý$ó˜°¨3«."/Úz·Ê€ø¡Ú•ˆ|€ ž¯D5ËÃÇ8¼hƳ‰ÁdC3t°%°€ÃX‹Ë ¿Jºg;‘±(ü›¨Ô2Ódxš¡úFlzÖä#ßè›àª×È/Ü>#,XˆRó!f<¬p>؃%¬d€H‡ 083>ˆº_H1¼jX€‹¼©m¿Ù![ˆ‹»Ô€ˆz~€t¡µL‚ áŒ%ˆ|TÙ±Í)÷Ê•Á®Å€ [€%|‹\ œÉ[^ØÊt»ü‹IÑ â¦"ˆ¸x€ƒ…Ö€dƒ\”̉ÀÌà‡¶È ¸Ï[^B@‘ûŒµÒÌ:}àc½øŒô äHeãðøÏ\†&B !§F»U?îE±}›àþAˆ~B‹òÚ©CãÜä`ª J1O)(K'¸‹ÞC¬MÔ¨‹‘Ù€)~*µáˆº6e ‡¨³¾¾5å:tê„I]¸‡¢ÍVˆGHl€ò€ê”8„^Ãè–YÈ^ðƒWòT¸$¢@QÊV©½¸¾<›½à8Ðé8 È‹7€ÈgdÜ53ý¢së¦i©Áv–V}ˆ}îÉS?b3@Ѓf¬oEÚ¸R§€ á†4±²•ÞwüÚ¾l‚ˆ~#¿ªÍc‚õhúuÇp±ºÆàœ«€Œ“4ð½´D>LN”QË^¾ýäR ”¹sÆ@‡ÌÜI óH$ƽD¡Ë2D„©G¬HDÖŠˆi† 6%‚ðƒ€pJÀ‹áíÐðÓ.&dÀ‡ÈÌ$äöæ°k:r0úÙÅàËGKUI…ñµ|”Eùˆ»?ìÚk^Çþ¾€¿ˆ}º¤q¾LkqšˆyØPª{ÇM¡"3ÒC!áä§Ùjº*s tyvÏd‘KRa;Ãm±… Dv¢‘¦jæF¨ €â=Ƀá‘4 `ttÅ Zåè„0tÿ™È„„Òe‘51‡6>KQ³>C8B˜ƒ½ Øü^¨Êµ¬–9àƒQCà& ƒ¢2Î ‹E•øÙ'Ls€EOûVﵪœl54i7 9î"?«Ô²0ƒÑ¸´T4óW $ˆŒo¡_ÀL“@f8ÃAQIw7UfÞ8Wˆ4æÅXçü+úÊ &ˆ–€'´ÿ£±V¹Òü¢úœ¹Ò•4ÃK3;_=qЇ¦.˜¦!”¸àƒƒx9³¨$RûxÓÜòˆ>”4! Ö4ˆ¿[ð Öÿ,źSÞXŠcÙ£•ð6È×ô5ó@‡ÎnÈès¨Œ·7L@‡íËÈÓØÙ¤–€ƒ1d½yU³rÃ'Ó ¦é‘§CRÎÑu²¹ÒûʈK[˜Å[2軄DUte¤.aq°œÂVs{‘§1¬O€¤¨„Î$*ð0"1Í´h؃Ú]³3¤æ„Žò ³ÝÊ€\3e¡_¶¤Y«xŸvX˜Ÿ«#rXç)«ìÚŸ~µRWmî^_¤˜‡º¥!Ê›&²¥Hƒw6ïÛŠ¾#tÍw\Å™" ìŒ S0ˆ?<¨´ˆ×ô c€°¿ˆ3éÞ¹‚2Ü]~‡51¬#sUm…[©í9slŠé@‹Æ*#<º«Ê@ů4¶»:QÆp óy4(€³ax‡ËV„@ˆ'‘ó™ €YqZœcAÜóЋÉÊX¨z/@ À‡·|@^ž ôkVjÔúc¯FÈîe”p/EÏ/£rð2f–K4žÖáǦŠô Q\)QÜ’±mÉÛùt,Öa®ó¶ÌÐiK¥h„Q¸»lTÊBÙm8ÁÂ’³Ôž[øÀ€AÕõ¤u¸q¤† øt"nhƒ^€öªGêˆK.â@ƒGÈËÌ3‰2"Vtx}•õÍ„uàèƒlf?ˆ.€aÌEžçýé“GÝô* ¼ù¶dýÁøç&W×k*àòcuÜLÖ®–S` 0ÆöC`B8 H6utØ~@ªž˜ØJ’¯DzÎoøŸ OæˆüPÀ€&8áÁ€˜| Õ‚€ ø3’ƒàËh0 ƒ' ÎXä"•Ä@H1 ă8¥2Èܪ 0‹`Ј> N„²ç3ˆL'1 f3¥á%ƒ9µ2°Æ¥gÁš™40 È­L7?+oêWpbN¤;9UÀEH3b¦I?á°–Œ%U"ÂHbn—1¨ò‹$ˆ±\ƒ9h²[¡+¢ÍŠ e!-r,ç*¨²æ„³@¤„‚ Ì9 À` ¤„»` ‹2 þº Ào¢ÎÈV¡'ŒIÁˆ0\„«è¦„¼­üŒÁk:‹H¨GðÚþǪ;Ær”Jšˆ16„•ˆ1ç))ƒF(³vÌhË)Ìñð!#* ø"Àj y Ìâ,â/!Z3O(4ù9GÒ鬃@ ¼Ñ3œ”j ÄÊ 7€¢  Åª èÎTjLLH58Á¦ò ð eBU Ç¬•:,[¡%ò,ËUH°R cHÜŠ¢Â}hd¾TR [Øh0ªƒM0Øüƒ 8Pƒ V¥¬£¶°Öƒ¨5ºÜ¨ôÚõô¼ƒè06ƒ]` ÛwΈÒ  ÀíC wÒŽ\ ÂÒ;€Ý— ó?;Ê/ wH{ß(1òƒBŽâh¼â–ýŒÔÇŠÂ2ÞZ@Òƒ(1ç±hˆB s²Z55¥~_Õz #€U4ÜÔÕ Úƒ¹s?K qÓ¸+ºšBDóX] Ã;Sj `cSL cÃæ’²\| ÄÒ 3hJ²‹8ðÝ} ÅòN Åê¹Z’D‹Y B„Ǽ¸•ï †ÓñNßJC{к"Ëꘄ†qìIò@Âïw1 ï vòè±+2p© ÒÐÈ·ðó¢]8€$š ÂÑÑk"_ÒõÛ!,HN„Ɉ ’þ‹½Ìñ¢ÿÝHN)§"Ò­|z€­Šõ²Þàƒrrs Ãb ûÕª ~ ÔÜ RX À¼Íù"à æüI»$ €?øÈþK©ÑƆ‚Ò€ Í+î’°h> 4R%„±xA¢ ˆ0q! üƒ B ú…D `å È3Ryİ4O€ 9 pìÃXoë<ÄHŒb@‰QDƒ¦aéŠaÎÅÒ:_k%‰qxƒF #9[$ m™ø¥c m -D& h!Ä- Ïèí5é€Õ `ƒ#h/ ˆ1·g‡r"ò ãþ2 Ã#¸¼àl“50³R+È0&=„­ÿ%HGi©ŠoPÐa¼jBf¥Ò²“¸ 1À:˜„›#ñ3‹1°bH´¼ g‰Àòe" Ã=Õ‘`bA„a b@í€DJc¿ Ó ""ƒÐ{XT™ÆXDÍt.8°à‹@ v"È|àA„ 4ÉXüOr\JÔšOÕVM"--È\!#pƒ$óhBUe&îÙ¦9ÂýG2° `r™ùÀ U¢THµÂ,å‘E~æ™ 4ëÀ ËK­˜Ô92 L€ k Î…"F†yÈ tEÚvpSxh Tår¨j’™ Õ^ H2"Ø=^‡ä RSèQ á\‹ õŠF°,WïtE´ CÙ¨dƒW–@ÙqmŒ×{¾ñ À<4×»'UÀB»»W¼¦r¤jËófØPä'±‹4jWié pÒÃ2óSbÞ\¬ Ô`ñ”x‰Yä˜"XƒJ¶`JÞÐyäÄ€*ªÐ JA4ƒ"ºh€ 8¹R4ƒ=«©pÐQr;€|ƒA#¸ÌšŒÝ tîµ®{ÍIxâ&ãΪ¶E„J}%)uÀ‘eBÉ =o–w$p¹È°¦ŒÀƒ€ØEƒµI$ E—åN@€„Ñb=@(Cl޾œ&pðÃSЄáì,—YYk˜„’„7xœâЋð†1¦éœ]ìLXHHÆ—¤2',‚E‹=!/ &r®E ¶ð¨š^Jè¡!8ð¿ŠÔBA¼Ü ÂÍeRVÞ• تf ›–H6}î¯YÖ’³üWév K ¤@¾9û(’¼dEÈ3 f³Õ†€8Ev ‡Â ƒKÊ'gF=1 HMè!\ 1:TtùN#° àág éY3'EDmp©€ Îbó®ÊEö]é ®Í­6¶'R=ˆA­ð€5öËi5’ ÕˆÙÛëD)㸛mµw%t î5åãB×·/Tƒ²iõQØ× ÔÀpy [øSøÏJjAܧ(èhˆØRÅé=˜€-f€s@` ù\ä|j¥økÆ’“—’@çÖ˜`¡â†BTžnDÔÚ@‘iç}H´Sš­€Ì@€*§-“Ä]ÑH`¢aÀA¬ˆÜœç¡ôPÑíI¨œ¹3¢s„E„ár€UòvMùÏ[=t‹sæqÐPÞ86½®¾Ü‰²é“½¨a°ûèòº Ð"Ö/¬(±œðßÉ .(oOÞïàÈêÃè’ ˆ5ý h´„^¦Ù¼@ª€—fÿIÕä'΀?-H·|ÒIvli7wÞöÂ]žwÂôb !§løöúÚ¿zŽy¤QW£@1*ûHR càWtF@öà± ±û_Éj½½^ìƒdnÓðw1Gò„ÿ€ óöù+b†TÌ};ÉòXP_oöù]¯î@ò®åÚÁkŒãRÿÂô°£’ dlO².|¯îøE à¢òži„G(² ³.®éÆL’ x5&Ýàe¢r€ÐN’KvÆ´OÄj)œ&@MFà’˸€©·øÈÿ€ OÃØ0Çì< ‹Âc <<1CÐð$b-&„½¡Š8x~E‡€äà f |Ã×0Äì=…™Íh1ØI.‡¥a Ú6C ð™Òe”Mæ¨zêÞ‡™á”JÕ ±[C ™üÑýM¬‚êPö„1‡·Í)Ò€ B‹ 3Cǰʽ•ù >CÓÊ4&Å4ÁÍW 8÷ ¯BShyvކh9y¦d—†1!—›-îh†+¹É£ÿ)fh¦“ ¡®;‡µ!„øc¶ƒ%ÝÃöSAä0YºxpÉt'–æÍ9ùXÜo4]ÃÛÃL3‘¸îÃ;à Ñ'bà °Åš²üM„i¢Hæš¡ëj„¯¨aN‡·€ Ö^!„Šc!²ô†2hKPš ¨dšAɤ Ú¯ˆØ*Ì!†ÜÂ-º®­`†cã Æ‹28„ER®&‘Œ¯ŽhUÆQ„‹£ `ý!€Ô5Çñ D{Õ'€:Ãà¿#2Qý,%„p=¡€êP=)¡ßBà}H@·qÀœ†H`‰:îÈV¡ƒDqFÍÐ!‡4ppµs†ÌXF!îÈí€ZV!ébáFj‚ !â¢/!ác(ˆ`î‰!‚’/¦]^×5ŠP&… jº È"†hyê†XHI­bÔ¨Ø&‡Ã) À‡…VƒpvÀƒªTZÖŵ^Èdt„¢)¡¯WÜ z„…÷2O!†ÅÆ ØèH¬† h`P‡žŒZXÈeöš_¨MÿhÈJ˜š\à ðåBºm‡€%JÅ¡&Í´!…z ¡˜ÒiŽôÛè`°‡‡`æ†\®â³–¦™zh2¡2ƒ_"bg¦™À9âŸexcJ†"w hâËáä‡À類†¨bå§FÇšââhL‰¡º¡$RÇÆÈÞ¯²!„Ëľ7É¡ ç!›˜¬€;²hñÆ­ÐS!ˆúhy¡œFΆp›Š¥RèfšqÀ 7µa fšègÌ!œØnÍz1n†UÜ_ºò¬z†ZòÊ7Ñ€<Ï›èa,† 4”k¿p”pJ!6o¨fT‚Æ©¦ù™:AG¾©ø@ÜšžîpiÒ@Çô×6€Súh Gm!@ûz’è¬õ6:C!dÀt7üYZ`3ÄÑí–HM Ä=H*V˜`X %ÀtÚ¡4T@Tó¤©A¡ D<?5BC!) „ç¡m=0«Ë#+-lšX ¤-!*à¼h•ÙYr'Ô„Ã:•l!àˆ¾8@ùSÍ^2ˆH?!L„ÃÇ$ebñ Œ†"6leOX‹!í|¾b»`úm1?€)N))”–—Èøº@ &‡7ÆpÌI¢Ù&‰˜„Žä KãÊ&„„„Àµ6tÈIui *–`[HÌ…2%1 “Ò©¦¿àÑÍ!„¯˜Ï/Ç !"l4@‰ {)†Q“h*‹cò&€ÅyLg;3ËXš@Œ‚œê}&¬šM¶0 `µ!ˆ½Î 9 æ!¤š 6¼_'tðžO‚1¼¹ó4H`3†åÍ‚9ÝõJQêg³YHŽ%ôzI#L†7™Zªè|„à ^Ÿ)@§‡Ñ€#æMí !”Fˆ¨sì4,ÁuÞ\LŒDÐ%ð´ )¬•‹¤ bJŸìB ð¸C tÈò¡PSdÙ D2ŸÆú‚CÒëøìšC€jáA5•„‡Î¢h=âLÌå~U¥>CÕ™4YfUNU‚ ]‰¥3«ÄlÖ ‚ÔPRØUåäØi‡:H{–¤mN>à×À¸!–J*Tï$ lš‚ƒ\ ¡å!,ˆšZ EOf´&ÈHŒ’…ÀωÐv=! cœÑ ¨Ä$œËYèT!4eFžá†ª©mOœ¤¤²œp7@ €%ªq,9宯ªœC=q7 „À9 Íñ*`4G.0‘@èeJ’À Lö¸îòZJš¬ÏO+Íùä) DÚ¸JP”€¸Y ´x, ΀DˆPÜÓàË•¹ ÷|à²Þ)Ð$L í=°ÞÉ£†½1d„Å™éJ nŽ¥DšWE,œm!ñØÆ¸©l•¡4 çȇþlún€&•‹¤FŠmäg’!‘ú”Ëkw"ì‰'‚ì lWŽPÔ!œ!…ˆýJå <”à6‹âxÉF—ÊÌ*`:¤l‹`1§N!à"™` É É‹i„—í: ~-¨¤p5ŽŒµ“€ˆF’!€<çâhÒ.’«"i­ÔFÎx.ªj@Ž8F¥0&Šgpxè¢øŠ0&‰] P†}gœ!‹Ö-ЮÔP6{°,ü¢4€_ I^êÄp‚0.G Fð€\窌ðïäœK(üìÌë0K$ö&…|OäÒLGb þN2¬fób Ï,7À(FXÏã@!$S‚6T‰´®âWÑ.&Ç[¥R!…ÀB{æ$!åt&…pª+Ú+Q/¨¯ÀìÂm pûP/”þÀf±R\HzZ‰R!ðüƒ, 7 % Ä0!îQâÊáèúd""àD+. !äÞÕÃp´v`‚hc7Ý¢ƒmØ&ˇí!/&4óQöýåì!.Ü%lç°('ž›( ı”°l¹d["/Þ—Ñ>L(œoËæ‘¨.ñip‹ˆ#oHnîeªÚ—àJÂh àÖg&Ì lbËBhôö{’jøhÓCp¶‰À&‚•(KBx„”oWñ§(bhˆÄ\s¨fæ hÇÒœ&‰Ø—ð!`MR¹*²žFÐl $pK²W(’u Ⓦ6{²Ú‡0ÀK*:»éFz`nî¯$ „j¤â&’&çâ6“@ «8c€‰Ð¢Gàt‚h‡ºe@Ìì ¶k-¨ÚQ¼<î@c ~Ñ£¾à.x,°!#Öj1Âi눨60ªwÆ`BCl 7Šê/ëcðZÙÞ÷Â[Ï¢(3–ccf- <*Â*­DèØ@úh>Ebª)4ìx6ð[ïŒàÒ·!¢Ó³\!çvÚƒH€ë@ËÑÁ>¢ ªÃ"0_4é(.¸¢Ê©c#Ã4+žóÂhwâhº@A.ç£XÞ)`&+q=ɱ”5CƒÚÖ#héŠè&”4y™6ŽFªÒÔñ­6i>9‚ß ÕšSbjÍÜ?àƒø!€rì䂸NìÒŒ”Ž>ÂhÂæÁfø&„„/Ö&’´#Ω8â!ô !”º4¾<ãÖr‹“G,ÑM+@<æ0ÖÑ“LïÕNt¨4\/(4rT·M †@‘úsüGô4¥%’ì+((äp=gŸDçºNáÂIJÂSˆ;ðï(¤TD!”\RbÁNìykˆc ¯g2ƒÈ?(ÑÌ·LÅ^ìÕ#DЮˆùª’+&ý !¬&åÆ#R%ï˜ Ò¥´€qü!+æÀtlòᕸÀÏÃ…Ü!étD³*ñ¶!131ž!(é=Ó`!€eK(§&!ð˜r•îÛXà•ÌÖPT­BE³0!6!éá`´p&ÌÿL€¥ GÌÉÑ:”!騖²c*Ð[D „5ÿ>ËLQäËâ¤íæF´ÄúkJ/f¼Â7eâN)Ee `àÉie+qgnŒ&ÏþB‚í#`"h à¤&€Ž âhÀb&=¯ÿLŒ‡fnש~Òö¼¢ÍT,•b§;k«²&“ n,R$km‹È&–ÏP4þKVÊÓð¼!†oV4g@›Âi ôokŽß€*'ØP4¸ç6VˆMs€ÏR&„à!–v \ИI6pK1¯pÍÈÊpþBJfGCp‚¨H@È7B³ ˆŒ¬üíyE‚!b*0‰vÂŽÀ“SgÉÜk'!úƒò(ÂFmÄ!ñÌè,²ÈÈ bõѽaÒ’{B{iBï'uט! û¨ÿBi}Oßb|IP!0h!ñ¯xDò&—è7Ćð§]b7_BòhGii ë΀å„ORi.[E9.Ian¶x#nû@Ìê[5—‚r‚órˆ–)£Ö{»¬Ï~“à7Á¬½{ïÈøˆf‹ âË;†"ÏèO"i‡m²ý‚i&Ï †88à ¢`Ì&ÎPŠDBUBiñIh¯Å@ç?bô~ûRå;ˆ‰p';ŒÏ„é@ËxÖ!‹¤¶¤QuŒûP™àð“/Š–1"hÓ³6 ç;€²(‘ðPèEl$ºPîúeÒIr‡?¤¤†xOµ…'„¦e@ÀË}`±J’qØÏ¤:K×ܬL$µ|Nö:÷"F` ª¼¶ˆyˆ@@¦õ¢)wÀÖ€ŒÏ”µ€ 5ã•P(!7 g±ˆF8H!9VÐyžðBmgjÅJÂhn`À¦Q7¹¶ÿb›Ó•70 ”ò Ydy”ƒöÞñrÅ+ñ¼#rô—5ÂÓ4ŸBE´Þñâ6ª×œ&—Mšš¶L#s<Pn×¶Îr²FÓå àEºŸ³/ˆ¬\nëò!š3¢7'ß#¨ôT‹‚&‹’#ps‡MMún/ƒ D Z&0 ºh ÊômÔÕ :lZ}À üàÙŋҌڷ „jô—þÁô6UͧîÃmõ6nšh!šÙôˆ¦kGNçÂ&“¡úe§¤q8ߟ».ÝUbipþU–GÑ] †¾Aó›Âýê¨Cx„4l!5«Û3D Mê¨Ñ»3+@.X79PQ?Y3“ ùÂ[Sï8“›!3Vѧ ²ÍÜÜ,” Ît!4¾ñxL>û>&PìÊÅx…y bE°“XX<ô¾amr!™`Ñ£¿d`‚$›l1¥0v!;Ê&ƒÏÃ×¹ºW0â7² ª8=rs`0óå»ÃÞ¿å´E{Zà+G*Î!Œ%7b½ :î@Ekz!ø¸ -®U>SMú)5†0[0ì$Ù0¬Æ2³å5²}«6ä,±È&5dÙIU!#HÁ„"Ü&©lÌì¥C¤¡È’î—û2ËËâKrb±ŽM<É–ä—äï…€|¥ÈîÒ!—þæˆöLŒ<\,T¿5¼³ÌVýd³7¼[È¢ÚQn71¤qÍâhN(pU°#Pñ6§dS¹ÂÜî!€èY„qÂMð@ൊFì™Rѱ›ÀËÙvƒîæ¬ÈÉ9Ý”9Õ*`–ȉžUøôò3{–}J«ÑÚÐùV˜ðGøA‰|UŸ'÷\$v mýqb™ßd¶š!æ1Òˆý/Q.îw¾hʉ:P!æ¢éO6oGyϟ‹S|å8y¥Ó¹XUðYÀÜd[‰þ¸z;Þ&Ò¿Û™†¶…yÞbd|æƒéáÄ(é‹@ßšE¢þÀÁq³%'EÈþ!šú‘îFràáv—Aëº#aè‚`±¨ÆÒ!®dk_üé,þ)›ù(õÆ`ƪõàçJáÇ:¸ðÊ#~YæÉG7±˜=~v]Z€!œ^“Ç.^ƒä‚øi%¹ThHdptÑÒ“Ü_Є³åqQÆ 0Dl¤§#+è…“l„ ŽtV-…ÎBù/@,KÒV@ÃuxH7zý~ìâs/#¶&!šÞ :ªÇ"q×^!7Íx¢6 ~Ïq„(>„4 !îÍ€&‘òQ®ïp €å9½·‘€ßy#;+¸ÂUðÐ{ý]+·°I¹µ½,P!'3Bm(Ô%Z÷”…âiø—Ø·Ç 8»±rÙ?‘s~ÎûôªPHà²Ëyਫ਼öo'q‚m ò*æ¢Ȱ„hf8&&—®´ ‘ ‰‡"¦h’€É…bK˜8š‰Dbpx´Ž샎`êø8*<僧`ê ¬ZÁÅóÙü?vÁÂ0u´WJ‰P"TØ•>$Gƒ©`àj°gd€€°uÄE˜O¢µ+©r €Ó(–šUþ‚j·â$%ºL3š+RZ_ ôbG°Ö馠ó’b îLæðh“NÃO††–ŒÈ>Þ‚4蔉 Éi~° ú')·%¼ÅOŸH:T‚ˆ8܃ÂôìïÔ%(90–Û@ ÒÒ ¯Pq"]Ä«w4¯¶NƒžPâ[1xéo’¯"VR$%¤Rß<ÐÏ¥d áÜÇH—yÉlë|Uª%Ÿ ž¨ä"_Pë¢Q¦h˜`*$_‚$C‰ ñü,g D—Inè%ð>ÇL¤àXSI¨€êÚ Šv‚pTª$;B  ³ÅHAÒëøG«âqªAÓ0‚ ²b°ˆ;}p±{“RAÓq…p`³¿v¬{H8T,êè‰<—Ði–¤=!ðƒ‰Cå&d8„k«øú¡G„f¿¢9*ˆV%¦¬‰-èøG ™„ZEæKÈ„°+d¶ ²ò÷#ÀHnƒÌsÒKX$¡}  vtA00H,žvù5È”ÙlÊ‚8ÅI d´–MUÜ;¦1K"Ch–´b$#Xò1äTtXÛ|&ìÊP/ iX4xäG7‰iE"B1¯HU'D@ ß ´«â$28R ç¹ Ñª8R{ Wó色%E <¥D‡5ôì0Rp"AD/$ ÒD %šnhJЄêßNÌ ‰IÈ£KläJu;Rêšîä«ÒšoÌû2i.­A¸'R€ ž4ÔÒ•Öa<2pƒäôþi« `"AµŸE’%F©£÷GЉ…̤Íís `,j²êøEa-drå Ë€H”L •܉ RZ#é+ —Í &D€Äʲœ‚@ H%ˆC,¨ÎÒ 줂¤Û,æ _€ÓÔQ™¤„RB qîI.qäÂi€nD¦…Uqî•Ñ p_ »v°ŽNð-€Ù Y¸W"±òÔƒ…‚[$cë4žÌ¾òy4+£¶€(Ƈ´gù&טR< JÔŽV·~$²‚ $øDŒDÚ ô¦n»ú7ð}àBŸYÆìô"œ§#CWˆ=‹Ì«qLKk•bF ýcR·&C„¦”¶‘*Ôå©™. ¶6;2T8·2ÄÙ§lž(õá**L¸¦G-@ˆ‰@ÐD‚Ø`"@DÕ6Ьˆ<⦹Ë-T\[ˆ@ ½¬Öß?Á´ÄrÝy´Ä.êLn€¸Y ™`Ý dúæøØYôÑ0(äJ[¿“êIgÓhÉ# ÷!¾ª­A(³œðAŸn³„dÚ,™b@Š* ܰ×nv‹ ˆÂà·å€"Z”@Ô7ö†R;á$Þb%rÀŒ‰K´ŒAñ{9i·dnMÌ%ÚiÜÌm>¶^¤µùÅVz÷7Â%»{~Üã~ò7Hƒˆb[® +¸+0‰5‰‰½‰l ÕdK~b jÏqΕûæ"Çá"¿qÑ8Ð9ºÀ jqî—_æß²±Ç$H:’ØPyÎ14®•Q€Dwç3%§T‰0ư"F!¦TS~Krâ“„¶ q— Hˆ“ÃlçÄ·pÉ‚bäµá€Í—ãé~"X~dNßÜgB“D’ÞÚD»–€|‰j­¨po;*ŒÅ7$ãq)-¥¹ctDƒXpfá,‰gúbýt•¨kÇyªäI…‘~»#Óº>¤ë`½3Æ­?açÈð ë!î{5î@‘Kª—¢aëÙº€`«YS| .8"Y®­–…Ü_ 4ЖO#®¶ö`ðdHXÑÿ ¦ÿÚ×f0)”òhàP–ôƒøî¦Qã -Ä•ƒ·»Œ©06²>‚(2ý‰i% u0Ac;ü¤0˜€Öˆ“}$‰H(Á c|‰jD8Òà’P*¹­¾°„Жé_¶t§ ;l¹Ûtˆ” ¯ZRTˆ!#À»Ž¤9ö.¨þÈ–¤ð„ iü±‰@b€Aç‰já­/r«<º;ذÂï‡ Ü“q›0ƒºI 2jaú‚–á¡óÆ«°XŒ0‚ "#Û*»üóOº‰l?¨ƒÄƉa¹‰D A°éw Ð 0–¥z¦ Ô˜a§(³ëˆ•¤/‚yêp‚˜ˆ’Ã9ySDãà 9¨kÜ€ M´X ƒÅ˜ì¿òFˆô\€ øÅšG3Òb”œ`Ÿ‹¾ˆ‘¼€ sBÆHƒÁ¢ù¶Ìh ¡:[!†ÀCè­XÓ5ÃlD˜ˆ¡¹Ò”°‰x*»·‘RSʨÁÇ‹Òñ² z™ ˆ8B»_ lzˆ:þÂ! €Ú_ jÜôAè2ù­°h¥ü„7¨Ò³:c€Ȱ;Œ)²ˆ#Ŀ¤HP˜HÜ’⫃z¬¨CúÃä:ʰS€€ H;ÂD8#yÉšÔp”¤¨ ²¢²øÍˆ ö0Ð5;0ÉØ˜- 1°áˆ8o kºI€‚Ê:à{Fpƒ†ü‰:é¢(ôKœ#ì+40ç;ž“º$¨Á„´¯ïËlŒ˜‰ÿ k)Û¬ó®l¯“•à‚Z©¼[÷0L1™9fÌH–Ì\o°GAù `ƒÌ¤¦ øƒ˜R×q¼!;˜ œØ13¨3©xŸr¦&èË„ƒ¹ø‰=šÍ„¸'Áá;·Í¸ƒËƒLJ(ž r—tØJPƒÅkÛMðÓB^<2h³²AªÌ#56˜4ìLˆ³ÌPðÓ;´´¤Ð-€™€XLóI/Ì BØ‚3È®h$ãºD³aˆ;<€À2P<\»ˆ ¤É –®€0àÒ´¨;R=€¸P2YI Òς쀧®z È*‹г¬± O¤£°–Í‚>’ªÙ †#¸,ã³Ë‚!Àщ+‘Ç¡ ‰P«H°JɈ"~Ëé#y¢¢[?€H¢›âƒ&ÚÎQ·ªBÜÑ»Ï. )¥‰ƒ¢ jš4º?±Ì»Ü𛇉j®³ôÁ1ŠÌ(òã¬ñØ›ó>€i´´‚¬éoÔЬŠ.ˆ$çCí=#!æ50ƒ½à‰‰;Í À¯å•ýˆ=ˆ=:ÂÊñ…BÆò°­‰N²ñÔÌé%¸ˆP‰à-LR;'8‰HÙ1Ô|P“²á£z„ˆ=.U˜˜.ÄYFð˜5T€]LÍY®ò¿ˆ‘òPòÛ;}€K-õfˆ”¾4KàÔ`³­óHžÈ‰‰¨€` @:Ñ(‰SéšÏjˆ"I›SÓ„… š¶„ ¨C)_™Q.?øWcB ×#-ª'¸ƒ×c¯¤Ä×#ÙR˜.Hš˜‚:³qXˆ–Ø›z×ôK¸ ‚*ˆøHXƒÇ@TA;Ù ÓèÙ+ŒŸxFãˆ# Ø£«0%(VHÀ8b j ÈUEYa¶€eÓ™˜ª-¢‰j•×aä¸Ëq;1È×M¨±‹q@<ºtãLYShZÑ3U¸‚Z_ÔR¬¦\Þ=IÝ´x–ºê'ÖH#œÀ€ ·”(ƒÛÚºœX¢†Km¾Wòœ-¥€ÐXx­ØuÃ=Ä€ ʈ#Âgœ‰Ç6P¢À‰\˜±h˜?à°øEÍ› Ùáw8T ‚‰š€_)÷Y˜U»(Cl]SMƒðÛ%Ú]QS,Xλ]ê¦<ƒ4ÜåáØ}qˆ:$-õ4€ ÔKÍè ‚"Ê€šÓ‹=å”Ç 9¡¸5Í\Œò-òý,môp–¶ #ÌYBTüˆ!2<üP ‚E™HU\€ Â.Àƒ´ †·­8 +Tªá¡ δV×baÔΈ”;µ =-ûsØÓHâFÞ®%,Y°‰B¤Ó!Ø> ºLÃñØÄk +ícPº¥ ÙÇaàÄ8.þ>âÈÀmÍH ‰Q%Pä8–»µ±²ûR€ —t䀃Ö+{×8ˆô¤ä@µÑ £X€ V‡°;¨*Dˆ6ˆh‚©à‰4Uu%ÄŽL•4sÍøœÄVW2Û\‹Ä»¶PÆè˜+ y©–ae¹Iš¨›är§åã\˜f¤QIä¹, ;ÛD|µÛg 4^2P^ˆ_{rûž€¤/c0“ªøÅ`t¯cù˵‡¼³J°Cij.¡šUíIˆ$ÊPøpWq;ÖÔ¤)¤¾P–çËtfz`çñ_Ì\®2ÉÂà˜?<Ž`;ÀhÀƒèÐ)¤ƒÄ.3èmÔˆ%¾4þ†$+ä‹N„.(6xZX¬‹ëiX^2ð®-ã­î!‹‰m^­=û^6’ˆ ½S 96%—Òî¤<ÀO“äå€ ‡Øˆ?tÀ¦">E4l?=ëÍ2I¸5>¯-K^ dk3ÿ€ XbXì®ü>5>¸Ó$—γiU¶FÉDgÆ}–\ŠÛ¤—ëü—XX¯µéI‡D¬H’·(’€s€Ò1qˆòÚ&ŠdIx˜f}ḭ̂LgìàƒÅòƒ½ˆí ’l’}Ò²q‹ÆÕlÛɬþÖ“³_íƒÁv×[ëaI|À.g"€‡ š:V¯ñ] è‘ ‘¡=..ª¸…›!n’J8‚R‰ –Ø ε\à䛀0$BàC÷`.ÈQRõš‹?Wr¿¿Í®ÚúeEN(1m²û)Æá1n -ø³ú_ŽFf£»Ñ¿Ž»µ0Ö.püf|Ó6® âuûPHSÅ»³ãÔ$4‡]#÷e€ØP2â³=lÊ>±?4Ê+â”PË%m8‚gÎë_¬‘P¾ Ï„–ˆ’qÍ/QÂÊ‚ª+MQtÝd`ßJÍ <ÿE¿ÉÃ;Œî} ‹*3I¥EPå‹`Ú3{Ž(Õ‰þ `ü šƒž`ïÈPBTƒ˜áB¸8c‘èSÆ»ƒˆ¡C(̦ È Š¸:rÖ•pu!ƒÌ#³($Ò;,šÇÄðr„g ¡H(q¹P*Á̰¦ñQ`õ8éZdƒŠªÕ”}WáUXí^;f§Ý@1!ª¶ªAÌÐqMF9¨§fv< xƒc¬2ÔtFjŽŠEWj%ÙåiÁÂÐq..£ÍÇZPpÄI¢Ì€t ½»+¬€£í˜:¶QÄæ*.©j7«otqÀWƒÂl7í®;xœ`ê5þË…MwE<öåƒ!HˆP¢jÚƒ©¡Sà޽uÂGDЮÅYéÀºŽ–¨Q,…¨;ö?¯£2ú€&ÚR¡ERr?Ìõ#¢¾#§ÏC R.9hP6ù¿èù¸…è8f…CdU …"T!G4U²P2^!Q³ ¡A.¡B HÉZƒ“(S©ƒ1ëün§SÂŽœïð ƒhPЃÄ!Dö çDŸ$¨P¼ƒ‹(Q`ƒrŒ »(P¾ƒ¿ RßO äŽºÈ tƒ‹h8/'Åh9¾ëÂ(8<ƒ•ˆ8#GLà@ƒÂHéÓQ«B ôê;#§RVÖÁ ú æ$×G5µ‚0 ó@ƒ‰¨9ÛGW tŽ×€*ÿJhèî®Rˆ8Ã> à£Dd â1h óê jPMÜŽ‘@ú:.Œ¨è¾1£  )o£çb4 áÅ·iËë^86¨ÅÑ{]È9¨ƒ•õëu´GÚ3 æU´Vào4np> ä•Ÿ‡Z7î ¶"¨9bÚ£ö6ÄØqĉ»'ùšîƈ!úƒ˜èQRƒ„"Ä(üÒÚZ!Gï‡ áÌà… ˆ;´‚h—e€+j ¤ ˜€–…i´{é€9šìh(9é6Ð ˆ óNÆŽì´|€HUé\ úZåïý¬Ž’èP“‚ ™ÖöÁëÆJO úzÅ[š:² šÊ;p€`Çnò‚n  Öo (8õÄÖ(R,Ž×è ÅÁÎpÄ#¬2¥£¹Š:F¡RR;ΣH?l¨º{VÈW:ÖH#¤·[w–‚y¡²¹=xSPqâ;l(=Z:¿ žç½®bhS¸ŽÈV2ȯ¦)ö€6_Žžúbš €ðæwìþÐÈb: É €°A&â:öé#­ˆ Sh]žxL®¸ƒŒõ®ÙSÏ0}ípA×r€ØÁ ä+.È@Ž„¢:^°5Ät4†Ò»5åšGZ”&^DuÑÃgæDbb àÑx·xTTZ d¢Î›Xžb‰Q ìƒÁ ܆ÀÓ‘Ò’Gai£‰ÆÕÑ••ÊAßÙu6Ϲ ûÀh¾Ä p›]£öÄ(#yA$[/AÎhFx.B† w¨Á»:àH"¼|އRrˆë´#òˆJ@Ä$˜måÑnB›“¬À•œB:%HQ÷D*]‘Ñ>B•£»M¤}ïK –ä¯#¢ˆS”d)’ÍYl½À }$¸¢ 3@ =ä?¢ôGfðCÓ¦f,ç6 á´Ò#®´Î'4XEçÒ)K*5[”Ï3!5Ô˜A‘xF¶Nrc*çÓêxQŽ,Lª8GZóq0s¾o¾R¢c£* ƒ@¨Ò‰ü_0¥‘õ"íÈPH ô²†¸RéÈ$š"`ƒ²ÖüBŸóÔjGYù„*-ÝnGj‘ª¤!êºD–AÆÅ^€4䃀bOˆé¼#¢ƒ£h$hëQ­€1Á@A@ ]ŠuÔ×yæZ°¨€üÈ2¢€5v Dt5ò:AÛÁzÄŽ¨²;¬‚hôXƒÇˆ8î­5¬ƒØ; ódyq óxÙÛSg×Ä#aÌ0»[( [ýdV.Ô1À1p¾ƒvÄÚšA50/ˆY ¿ü}-°’˜_ ³@~X$ƒ’ùRîT…A©÷xÑLr!C0… openimageio-1.3.12~dfsg0.orig/testsuite/texture-icwrite/ref/out2.tif0000644000175000017500000041510512271062644023675 0ustar mfvmfvII*tö þæî2F=RS>¼Z2013:07:03 13:27:34 €Bà·øþ _â 9 ¹!¯÷|MñÄáð¦´M»†Á„ñ1$AÃyÄñ0œ@/“›17ä$#‡°“ûê7kÃ@.x„Ö ˆ"Ø3Ú ‰ˆåÑlM½{ÄÑ0ìAÇxD18D*6ÿrı0T@3D¬*W ·Â‚Õè„Jeˆ¢èƒr©Òjp«H ÿa…[aAX„·†…]_ö¼vR#ÇJaN°8¥Ür:ˆ–;9ˆR1Á­CËj¿ôùÝF'âÜ?æ¸êvæÛŽ‘î_¼þåýÁ’€ä GûoƒËêO·4Ž  ÔÛ_îÎûþÇâù_`3ýÌA?À@LSØÿ¥ßöÿo?ô‰?M8«p¤Ÿæø-`Qþå Œ¢ €iþx§ûH7@ ¥à‰þ™þÛ‡ùÒ‡øgûhbŸéX>©Áþ¢pF@»€3ܧúRî‘=Çûê>hSžƒKpè~´é@&|Ã1MLÕ5Í“lÝ7ÎŒå9Γ¬í;ÏÌõ=Ï“ìý?Í£20 §ùœ‰­(SÖƒìª&Ž¡Qzމ…ˆ‚Úƒ*èQÔ‹-Ë" j¢jþ¢a],«"B&±€ R6+†(húª€ êg.%H‚öƒˆ’ˆC5H…TÈSƒ+èRˆ…,hr "!.ºHU¡k"̈J(00ˆ4èQ˜ˆ ¨RZ…6—2 m"¢!aÈ4SPh"{V…[ëÓP÷¡PŸ!Jë!O{Û!O›®¡U믱ÏZßôk‚±×£å¡M‘ÿo·,£4-CÇQ­ÉÜÔ*íËÜáGúÚܺ1;˜à×®ë‚Ò7(û©(¼-ê6Ž¥6ñ*¯ lŸáp#ôÙâ¨/kNö½om¾ý+oÖVý8¡[ð/+ðr²‚:H"êD8ªÃˆ¬>¶Ãì¤L†Å9Y‚ª¤þâGú÷±2bª1àXªü‚PŸéðg#É)ñs+ìHyó^z6£žÜ¡§ô:ËsÉ3PeÙö¯mÛ÷ÏuØŒ@Ø.Ýáâ&§ Ìþ¬ Ì^ƒ-hQš‰øÕê ܈œV…$9’¦ƒ+(Q–‰³V9þz¨6W¢ „Hæ·€¤„ö×Ô³ÇþÍ¢w¢­z„)j¢¢ ñúå圧2@DÌJúY…ð…0GðDË!K² ‘Xàÿ#ðt…¢KÈSçGf¡Q0â?Ù;€X ˜ˆ%4j™Ž.æ¤Ô!Fk CdAö˜ãÈcŒhÿef8„Rj‰ŽUF8“³CPCÍÉD1ʀܘCr‹ÍÊÐ7%¼Ü•Sr´š!Á0GP™›“HuyÔ"爆Bx"„]­€ÄWO'=¥Tö–3ô‰Ñ]?EÄýôJP½l€2´ŠÈ!> „! !D,tâ+Cå9ª@$?ÈËp ¢v%Y+[R‚à€ØTŽ ‡ùcýh Ãð%Ã+ §Œ ȉnre¢C|΢…u†¡0¥ä¶ëÓ;»›SnnMÙ½7çá”8 h’!=$ò£€AŠ ¤ˆ2² LPº¡"ƒ*¢IÈ1’䔃RñޱM\LÁ£lùŠy6~®ó$F9 OÎùæA§œ)[$M„#â¬HQk Æi‰$Ò þgÂîRd(Õø|?çô^òüÓ¯ ÔKŠ`$@ÒR#½’ƒ/¤@å±xBy¨UƒýPâ ©á :Æ9w¢.c‰ñް=‘ÍH j2‰ ãõÜnZqŽb…}•‚¶nYÿZFäÃèÄö™ åJ&äòXCËáåg”ÓB²u@»ê˜(›rLÏó=«@ñ*CÚ´iä?F$ý¸5¨í„á ¹~ƒ‹ŠUH8ª·jÜ R2€<ž»xQë”ä¼s¸1.y€Ã…`jäÃö%¡’åΤqʇDÆ 0¨x 6ÒP(v[‘î‘!‰©zi›’ ê;¬š¤6lN+í}ïÅù¿Wí?†p<ž и„d(AŒ! 0ŧ?ÏJè"h)ì:kåA„cýv=Â!A!-*à…UŒDá0ÿ„L¿X•ˆ À„ˆX ס 3àˆâÌDÖ\2¡ÔEg@ä´©ÈQ!E@ƒQÉòJŽ!J‚”Òò þçˆÿ\d*P*Ú¹ËBÓ¢0üÇ/ ‚i"1Z5D…S“€c‹‰Ž)pÔ={cªþ5XˆÖcpé¶~ìjÄÕÈzÎ AÒ7$Ÿ9ëáÁUF䕨ÆyH½†±Ç–'›“Öx‹˜üHA(ŒËZz#ö<þ®¤žÙ[¹W?D5šsô…-A­Tq/ ‡¬‚FàZбP·…¾Þ"ô>EOÑUJŒ ¡þKwÀÛh` ¡©dT úÙº€$ýħ- úí\ÂR+f'ô&²ìÄžÖ(D‡Té ÞšcL ɬM.áp«ô €BCˆ:Q‚&ÎÔ È8Ÿ'˜"ž!©ÐAB ‡b¶!Fœ ÊJÇ*tšb ¢Äz W¨N"eÒ•¢N€¨"â&¥¬‚*¢ U€2‰àh| ¥¤’ŠJEDydŽ!Lì^%‚jŒèlÐ(o¥Þ1kžÁ ðª*CÅ,ZQ,\[là^¨"Ö1ÅDí§ø\Hf1ÇÚ!BJÏP9ãª#…Bæ1Ìøï!þÊì‡P%pð70àÍV7$0íÃr«¸7'æ½Ã‚2ƒr6ƒr#£rÓ$::„07*¢:ƒ:‚$«¨†Ü¤H:X…cÄ9f”Õ"Þ@( ?ÂÆ$:DÄH¼ã7è!­úóKâunuÒ#"ô1C45" â´ðXžLXî&'’" 2Š ÌØâp>Î2âTNc¢' >¦‚&âÒ¬ Ò}*dðë?â+éá R€Ê" §â/*À…Lš_!zàNbé%‚ æÈ T†©BD&>)bä[‚ Œ¬ë¢ëâR¥°!MÅ¢ÏM‹[ Cä¬,ôÈꌃAÿÇ8!A~5Ú0*1Ðî÷-˵£QÌòî1Åbѱ01Ô¬1ÈŸ-Cr7aÿ4ãr%­<ï­8(¼誟#¨#ƒl´<¥¾ÔuC(:‚Æ:ƒÞIü6£ Çò|ŒJWÌD¡bb4ÃFXW"l žö¢È*fÔ{ÃPxÒ¼/b*ïgM ³…GŸ/áÿlÃ2Aþë"ð5 e.*5 ñJÒc8ïãP+)Ÿo£rcPdp7"œ1Ǩ73 3c¬7"¤ÒÌ3ƒ4I~7"º:‚Ò»ÂoäV:—kq£¨)C¨<ƒÄUHìÕ"¤çÚ?I Ï£ô:Cô2“œµBˆAªA ‚‚äZ]ÆàSfà9õ¾C2f=sb=áJ˜ãÚ%äLJ$R"ñü(‘Ð9m¶!ïÊ0„¦6ÍD"Z!¡Ì‚àZ‚àe%x Eg£%  §*ÿ^öŽE£¤ É”s‹x4é–Pš¤ÃB¢C:OļM"€ò„§#Ž:"‡Š£Ià Ä5voJW­'UEð†b ®lì%¢ Zãª"n<¦òuÂ"ºíEaÿKBFìÒõǶùF’Q éÐé ÀÇn*HüZ઄Ázà?¦Ã‰Ž<ãÐ2ƒ*‰Ž]:nŪj TñŠ s õ3¯R¨c¬lð#rˆ:1ÖØ5í ,ª’1Ñ,{1ÂÂ1Ñ)œ"1Ýhã‘/në•x1ÕX|ƒ(ƒr­ê€70t1×XACr;G8Üð,Z<<›{4£¨-½b<¢¾:—|pc¨DƒÄTÃÅ7u@CÅÃÅxÛ”>ÃÚ³Mz3‚ª´«T×TAÒA0AÄHAÃhøàØó´Sd,%d,-á¸H•ü6Áˆ…dD* ‡‹tÂÖwûðHÊQ±ØJ'T(•ü*§$>ip!õd)lq´C L* paà„†6ÏÒ ¸6Eëx¼Ê]ŧTšV-BzBà:IÄþ9ã«ð`\j~x²‡ ÌÇ“d"Hì!þN'lc%ÖSе p)‰ÎP Ô­h¾Fú§&gŒSb ¨µ§~…*N<Ë>ˆTf b ¤2WKž¢ð`¸È… ’Œ¨¥Û 5c¦Òă2¢TRpŬøÎz鉫¨Ý"´žc[W9NB21ÖX€Ã†1¡¬õµCQpÚ¦:F#q[5ä¹ù8ŠCP\c#‚îËZ1ÛJòYN7%+ð½N86ô!y_óáÞ¨ ¦9x69yb74Í·£¨Wÿ1·9} R*£©V§Ž£àˆ'¸òyÃ+,Ryúçû 0òùÿ ùÒM dÐãÍ芀Qþ»Î«dêÛgüªëdþÉÇü¼Iñ)F¹³(¼`…gûl Q`-B€¹ÿƒGùîtDu‘Çùê'ù¾ð8`²ÉZZNR!ÿ‰Sè[¦à3"€Í|™%øŸ© }¦iªZ–8i²fKÊ xŸ*×Ãq\w%Ës\÷BŽ?†4ºjv«Ðëî°… ó$š­É•Þš¿ÉJ°š rƒ« ¤™@é©€°ÕÉÓÚ°†jóíX¦³RdÁŸ÷¢jl+Òòk‚&­âj¦EÛÔš´øZ°½‰”†š™ë šƒËh°±‰’ÜšÅ鬪š†ë šÔI«¨€.h fÀ €!Ž\Äi®:…‹LñjFŠÂ”çë ý—¼W±þ,;:k ºÚ ,'+Å«f΃Àš°.†¾î‡þ%˜:á«-Ž€zñ/èk ªpè=Çù”ñU΀^ñ"É{Ͷ<[‹ È%ðì'oJ—¾–b_š%é ¥X†§û`—¬ y¹%){)í©|~²Œ´—¶‘Šq´ˆúÍô‘ŠØÕHúö·ˆÿœ»Ò{Ðíòz'®ó '¬ÓÞ2Ó34<“B;9G3’96“«É>%3«-?`ÿ ’Ä#ùf£üÞõ¢£ÐJ.àHá©tJ¦‘ªšTKÉ*D¦?Ó L e¦ ‡øç¤™•¤r§Mà—æ8èE€JG b€f?Ì èX‰ ”b@™IHü8iÔ–¬’bŒHé7'äán“Ò~ºb”SŠ‘V+EuÌ A˜e+g ™5Òji™^A¦d¯âjI‘¬&©šª¢d/OQ2#¤ÕËRòL¡5E…ŠôrMI‰~+ÇÊ 5–‚W† a_CþC4d‰I«q&§,š›Bj¿‰‘Ò&¦8š•ÒjÙL±5oGP™ÞXc¬€få…þGÂhà[“‚¢‚t% &²¡[–2Â_Üi⥆;ñÜeí¾Pž!ªÁO(nm°¢Ó ~‡ø?,.(C f¦‰Ðlç@µ˜x‰ 5Bç@ãÍ“Äl‰yy:xèÇ x!/…ÃüÚˆƒ†ºTG@¿’ö°KÏ@?ì@cöºKÒ/2ÈÅ‚<4âRKÈÅÕóXŒM3ÍGF›db‚^ZD$$|Çö´GÈq"É<ê$óÀGÙ¢`A4Ù2ÇÔÀKS{LÕ4.ôІS‘!NFÙ9ÔêWSá]N§?¿£†+HÈ“„¤£XqÉ9)QæQJ&¥(@¨ÿ; hþ»ÕjM€H»ð1`%zê½9«2BVŒ²»0£nŒ±Ô¹àDUR¼7§ “ âJ²K3 Z´š‘Ò_âs ( z(Å‹QjmU«µ…PAƒDþÈŠóŒ†äÈï1âðWš}q+ÆÉ¡–:L¦=›YQ,°—re(ÔÜa¥†f Òd\ ¨¸,-Gæ€MM±52„Õ!“%TMK¿‡]z–ÎQad#ýš/²ÂÆÉ«m’7²ô M]±5=Õ¬ %(Ãìƒ VÝ:³üXcpÿ·\šß’¸ÊÏéajŒñ5¢jÓ(âKDÔé8“jx¯zÊ: ÀО$$?çMÜaR:DvÄ}þøúGÚÁ&)=5$òº“Þàÿ/)<Ú&H˜R`@é¡ô^¤å A NIÆV'RpKº|Béý­3ý ˆ¢o©”®ÖMTy1ÆÑJ.õ.”ÑÇS¤uP$ꪔ:"Œøû’+Ø­wH´ˆ!ÐÅD,úRäµ:™A겑‰fZd„–2‚bKä0Ž’¨˜Ú3‡i­nëÝ›·wEa Q[C2ni)^‹ ó¤Z¥…*“#ñÉ”†5XD™b8Ä?ÛŽø,%Ï ÆrÃ"åI28äׇ"jÉ”˜Ô¤ÔÒI2¼…É©{&­Ú “YÒL¡$i, س–Ð?ÙÕ–Çôär½gމaGˆØQˆ\[ ¤Eß“0°µâ¾çCqáØhMPÚsŽ×›°³ˆéKºø!X†šÈ«Xœ X”“BÌHá•ÉéB$"h¡7SwÁ<AL CÀ,ŠÙþ ^ x¯7Èè°™à—⸚_‰©€$ø¯7È@¯À±`™ Èšøš’Й/i”$ñZ ðþ ©¡c ðÌø_°JR(¯$๋2i ¨ó «Ÿœˆ°Ëpš£ÛŽ«êí µ/(š‘h𙝉 %0„Y¯ )¢‹ ¾Å*]8Œ³±D²>¬û®‹ +Eàš…©¹xñê{Œ¸ñ Ž€'9¸è'è®»0ññ;9Ž‚q–ˆèQDÔÞŽƒ S»qà xêE ñ¼ xò z>‰zˆ‘Ipœ x”‘Š x…‹!0‰º ›z’ˆ°‹Ó›j—Ð’ˆù³ˆøÚúûÝÀ‘É'’tw–90'aF“(»ªI5À4¡öÈ ò™:Á=jõJa •@ò5 ‡A*È ”È ‹ A5 8”y* p””¡ «X»”Ðæ”éšx„±OV€ªø5ù³«à˜¡1W0…*àÈ‘óiˆ¼²ˆ@‹ péf …颳,¨’–˜’½è•ÃrÌAª'–ü®TBT(¤„X¹k8*<Æ#’ŠòF£b ”ÝÎË Ì˯.²c£è™$³e:«†Ó›˜²û‰¨$/¸™:š‹%G‰ªè:£9;…t»LS‘šðÿŽªÛ•lÚšû.ˆ°ËÔ²Lrõ ©®ººøU€°­ÜÉ€Õ°@€©€Bˆ.#ØC ·‚gøÃ¤ ÷ÕКŽ,å›Tö‹ ³ÃD8Ž„²è'[Ž‚ ë¶‰ªdŽ€¹ˆñ1Ôï`èq³\‰›ˆ=º»lø*˜ÀIa·ù  {® yÀ¯P—Ž8—Žð—ˆ0—‘È—•p—ÎÁ q¨Q Ú²Ù ’«m’ 㑚ÔÑä’!ˆøÈ=‘"=ˆŒÐÙ-´(™’y’yQ>A2‘É0 ¡0y44ñ÷Ñ;k0±9 ¡:‘É>¬ 0D!dD‚ʲʟäŠê €“ŠéGáGˆqJ ‰K!M ¡MñJ ÈL‰ŒðCCÆz¾¤™ £bðO”Øc@€«`6pS¾á ,[/\ QI¯T¤ )?‰H•½ñl79j ±n-*(T5×]}A„`‚H­›x™-õZ¤¯L$Ã/Ù¦¿¸h¯C9‰È™C\?º¯(š¸, P™ChÅùÒk¡ÌÀ°¢sÕ{š:R?ËŒÖÓ=d ©9ш «+ ­êÄ£¡û üAü½Cቇýc^D[ŽHšŽàßM‰¨á‘Žƒž€HF¤ÀÃh³1)°‹Õt›¸ñB¤"·èè.”HWа è ÜX‰­xèK}æþ`¸ñ'°Ž(š‘(è;*„S¹ÛÀà™Î;”ïq¶ Ë@ Ĉ—Æ2ÈŽ„ú¨—ÆZoÆp—y ¶!¬Á2ãb‘ˆìY™»ÐÑâMî+!ãUðˆí’!êù!’y$!+’ØÛZD{’Ú¡\0A4¹44’•)9y99 ‰8ƒ 8Ç pË q”¹/+XÉÑ”¸ÖÔ€PË-7_Œ²¾;y“P`µ)E hŒ -3 â"èW­à† j ¡K£ê Š Ih )B"Xá¬ìä–\SýÖTØf¾l-HGù)иø¤ÕGfô½EF¹œ6¸Ð‚H°‘(™òø‹ O^Ýû3߯9ª·ð¯1\µ$ȰKÞPš¹], ­èAû}_UìàƒÎùŠð»­Àš®T:rï/0šÄRC0‚J\†‰NÝöCdG¦âKÎ’Ç ­p‚¾„iÅì¹ÄžWa`ÂÀñ8“bœ[ ;Y€ÎȰ§íK!¿– xN#,tDÃWxñ 8èbQ!x!1À+¶RÀ—თYqÞÞ‘ùpÛ y˜F­“b¹b xÉbÉðŽ‘ˆ·ŠŽË-žÐÛP‘ˆÙÚ_žé"v8øœQ 2ñ'Œað“(Þ@Æ]Ÿ”-‰QsM¤ãï ³R M,©5,¨ôH ÞH ’ @Ç d‰*ÁJ KŒ¡MyMN‡ø½À9«Ò¸Æ€•èé€ô!˜ÉIHÚŽÜy·˜ã…"‰8Ú‘hÜh”¡0ÇdS/¬¤@Éf XŽ“EÔ9П–ÕÕŽj­>lïžú °H$±«A‰̦žŠôÀç™x‡ø&‹ ‚ •ý9¸‰’f9Ô(_ùhé¥S»8 °‚³s ¨X膉­ó¯p°¸™^bÞhÍö¤k£øÍªgÕ̶7ìǼ~†hA«ÔBfqד‘°ñg²­Û‰Lò îYŒƒqˆ:¹Xé¶ßuiqáÁ ©ñ"€Ž„¾á»Ž‡¥ƒÈNï'‚`ñ`âf[¾Ïp‡„JHèñT è/øøz2èñOî›À€—²Eþ·‰|ü‡ú9Y,û‰{–‰Œ¦ ‰xшæôu1ìp‘Ñæû;³KˆùˆøÉ)¡"GY%RŸz>’|yÂÑì“(¸¤À0>YMãÍŒ£JÈ"§a:ˆ0h°Œ(d¡¡?‹1?‚Ê$Š|Š: 0“¹G!GéJÉK‰IMyM0P!¡]“!v€ÀåRȵùþI’_ITò"E•3(Šìˆ°+ˆÈg,q?‰ii•kÈ"â (•ßà˜æƒr·eæ¦øJ½Ö﯋x¸¤ˆ!\xš® ¥‡û„ÞÕoË~€¿¸ÒŠô߇úc ™:ùP¯G‹þioðšÝê¯Ò`-™V46¥_ðqÞ‹h𸸠”ÀËÓ|¦;¦V¤Jÿ  é«W”E&g¨^ÂX ®’4 °†,Q^MYßá rú6ŽªP»bñ‚É©:´øÜÅt47ˆÅj†ÄÈñXpN¯“ƒú³¯ê1MŽ€’βr‰'G5;—²°—ÅØ èg`—òÞ­þx xÑ€»‰yÏ®¸—ŒaÖwIþ®Æ©‘ÐÒ x‰Œ÷kp»‘ˆƒ‰Ù9ˆ³ÔÇ/M’'U½·“ø–õ!-‘ÏTx¸x–’yÇi2Œq0u©M´e“zõå¬È Ë‘“©”Pƒ|µ3“áä`,©w¬©  FÖÓ8“’öí ‚X„@Wûü¸€ Gûäš…÷ød¾ûx"¿WøT†À û¼Ù¹Y(tÿ€OðÀXÿó-þý3ßàPµþû;Ÿï {¿À@ü¿À l ?lÖŠÛùýg?€{ÂϺ^/×üƒÂapØ|F'‹ÆcqØü"Lˆ…Vì°+)îÿyYà<Ûo=²‹sl\övÊÍsÂ|òÛ6ÖÏB¬¡|Ø×<åÏk2Žmx=žsæÞ9áFzƒeÎåyçVz¿eg‡9æ¦m›žªYDÙá—<¾Ï=³Ñk(ã6Ïm,³k/-þ*Ï=óÌŒó®àÏ3Àƒ<Ô,§s<ú,¡‹<].Ó<³ºŒðVÏ‹àÏÊÐ9d¼µ‹L&²‹€€Ï"KI.ªÊq®s<.Âà³­"k<à-)’Ó ­&úà³Ázàè­*bÒj®Bßð`ô DYþÚ-!JÀž‹ƒ@´¬ë ¨´¨« î°£ËJ°»+a,µ‹,™òËø°„rËô°¢JÒ¨°›ŠÉþK2µ+Nе «Pºµ+R×E" Öá­j ÖzÒ‡ûxµ´2SM§µÐ(¯Õ@¯Ô·l V¿Uj(l×üŸõ-l¯Gø4‡ýtEï±BÅÊRî¥( aÿ´¯RÇúìŒ((Äâ*à"¿@š¦] r!gý4TS€3n\" >Äa jjðŸàèSíagy†Wð+i f HÂL!³€z·…˜!ÉIÕªb´»«MðÏÔË~R»¬ªÚÞÊ.‹²ïš/ËÒøÈgYÞyžçÙþŸ’‚0Œ³ck+†ÊEË.id3ÓšÊy³iêÊ#³ÁO 8,£`²Ø«+DÊL󨲢L¢L²»k+IP²‚S<³Å“vͬk.º„,ò°²›,ÛŠ²ƒŒõ²ÓK+@²šï>¦Ïqk,#Ã3ÊcnÏ>Ë=-¬»JˆÏlóM¶EK.°´¾ÚgÏpk(Ï,kIÂÏigü²¿ËIhÏ!̺à&,‚ïD¸à,¢¬¦2àîŸîJÓ±¬¥Ì¸Ï%ËJl´ï}âÒg.2Ë ­.ÚÓþñÿä-"„ЏDkN´¶Š·Ð Ÿò1þaûrɰ¸K‚L°£E¤X%n–K±i%E„Ù˜?ÇJY@…!ŠXO±Z<Å„ØÆ?Æ"€N%j 5Ô+EØ­Aô¤  kIEh¯–²¨ZÛk Ŭý³¢¨’—ej¨œ@L•PU­íV·%ZtUhíWeA[å‚®Î:¾ªù¹ ÑþpÄ1O0Äâ”qJRîZ„©kš®}–ÙÅ[n´ŒeÄX×)öQGrŠAA * Ήuç@úodqÖ’I!(FC!½6 ú@' hšh¨F¸ÿ@DŽ€Ƽ%Ålx)2ÖB™Ig!%a•ñøVË -%Ü}–ô¼ÍKÁ[fåì¾´…0æ$ŘÌôKpšÑšjmFmÎ:ÒÊÌÛ,°4²œó(qË*02´h™âe Ñe?…•R¼s6D‹;TíÀÊ#"ÊÔûŸsf圼åŒÙ¸DFxnœ#=?—±”sCý¿–W”‹ûyIE•ÅâÊæéž`Ï8w–gqeœ4@Ï.ç»>\‘e$E¦yùÊ[ * lÏÞXó‡úq,£¸Oà‹ €7€XPºpK$°›ÂÂˆË X+KºÅ¨¢XaAbP¨­â´C”:€7h‹²°Vak)…¬±–´„§”Ú#-gP+¥@PUTµ%Z»•kXd`VÀÕZgU²VÄi_e|pñÇêÜGÉà*JaJ@…(ý-Bµ×.Ëm-­³ôFââ5‹ˆ³Çv¥Ή5„ ,%–q©%dðÉ<[É"`dxt°°#¢Ú÷”Œ=ر"°9ÇûrP¬÷ZÀ“+òË µÒµÉ2h¸ ¨®šde Ùn6Òù˜³˜_ÙÄÁ˜ø¿cdÏDÀITP»Nc6uË+§ç°Ê;±ÿEÌ¢DE´Í•ËË(>3tFœ:#(€;®3Å@Ê"Ê…h™›ÈYïÓ,®fòÕÊÅ•6åS(ò -zu¬Ï“þxϼ2”3¿Trg§vL`§òÊE«Uö,¢Þ}_‚Ê›â.°ãÌ~‚_K¤3ÓZËKzBgªÞTHD¦ºyi¨Oþ‹_bÓ¹Ë+ÃgVgþÁxöà÷ã`-*.-)ÜIJº. äˆ-#D-#ø{âà„„®3ÁwkðDžK&­âÒEÂÒ<"Ò¯ëð-/Ú®²BbÒš‚ÂSBÒPBÂE"Â7Ò+âÂlbÂ!ÂÂBh0K$úP0ŠP,&åÈX†V‰F! ì>)‹zÃâzVÃ:U£ŠVÂîWÈHVÄâIB°Òœ^”X¥†*”>Ũ:%¨.å¨7tN%¶+0¢0!EÄ#EÊ*Ê*…ÐEÂ.ápèH­&+¢dêB%‚Î#ˆH_£ø`J¿c¢fTÁþp`\õàf` n) 4°À@˜_nð)ŽK@B¶“¢î]°!"XbÎïÆP—BÞÂÙ¢Îd£6•ÌV2ƒÅ¯ÓC`š *øbd2„§3gjsf3Ï\œ#(÷êDþc6Ï'B|c6¨Aj>£¤3d`¢¢Êo¡þ;c(Ö!þ¢†œ,£xòjL3Ç…bÊL¬2ƒÔ,¯húˆ9#c<÷ä.9ƒî3cU#¡þ o¦6-ûƒÔýɲ3Ï6ìÂÒ#<ùþE'*,¤°v¶3Íã‚-*m )î-'í!Ä .&¦âà¨Rlì¸ $âAj€ €¡þABÊ7BÒÐ’ûBÒÙ¡’3Ç÷„.¾©êr ' Üç´ýÊP.Îí^êÓBÂ~2ÀK.¶²"Ò§‚¬lÌ,(Ü$²Ù¤æƒD²Qš,$ˆ,%t,0°+Â,b´€ð¢+Dþ+Gb+HD+K ¥Þ.,-sX…kPScD´E6.âÖobÖTn)@u«febîVFVB¥ZŠ“9Ev¥l‰ÅläˆVŒ$Àf 'ã€XeÜZB’`‚”3¥¨»&œZâ [c@[cí\Fä\¢T\¤â]:]€íçZŒ h¼%„F_Dâ¿dî$d`bDÉHådâcèHìBì' .Å–R‹Ì0„Q€5‰6>ÀP”.é¢r—"˜–b–b¾U²8,ñ»7bØ!)\Åf—±Ìñ×FÔnñ‚€' ÀWøþûàe ¿á°x˜š ߉ƒ"nèƒ>&‰…"ˆ˜ &ªˆ9âpÈ0Æ óÄÂñ6Ì@;zDÛq0Œ@kÄãÐf¬MýA‹ñ7ìMi‰ƒâM}qL`Ãh˜f&ø†€Ñ8LiZ¸âm˜'ƒ ân Ÿãø›Æ&°‰Ä À¨™jòÿvDØÑ›~9oDÝøq„M¯‡DåÐeÆÁ^A„(j 07PoNØ› ‰‘0ìœ;ˉäoB¼8ãˆæAoù›õþäÃ…pêÜ<šô:ÚáÆxuÐÿ^xyÿ]m‡°uÀ˜pßYþõó 0í/07Ìëó_:üŽ»ÌóNzû#ü4ó'n¹Ð?­ãú<ÆÔžðZšþ¼oë2þ©¨#Xþ£ˆ '‚Àœ ˆÂ£€Çû¶‚@J£ ‰TJœÄ°Ø¹Q)ìFgLpÆñš{¦`Aþ~u!2gþ9þ‘§ùò,@ç€áÃr¤é3†Ö§üÈâ*4  ¶Ó{àŸðÜèž‚S Ÿï,€™þ©ÇûÊ ê84£Üx´ìÈE)yþºGùôÇúðPÀd¯ÓyÌH  ¨"TÐjV¾§!Ñþ¦š³m„8Êlªˆéé=Fkqô‰X‹hM  Ž„ÚhJ@&zÝk[–í½oÜ ÅqÜ—-ÍsÝMÕuÛ„è % §ù¦‰ËHPn‰Ã¨P Å"hÂÁðê !Ù¨2Tƒ¨ƒÆƒ(™Ôˆ¨˜\Š¢oBh¢fêb…3(0š‰­H1d¯¢Æ(ƒ(섈)¨3xƒ= º' ØŠ "fÂ'O¡È†ƒ&h4tƒFëŠ'U Ê’ kd‹Òσ&IÂ'hKê&¹ ɪõŽŸúb œ Âcš‰–¹Ú&0áâ&ïµx’'/Rb çIè›Ø½g[‰€D2j‰-bô†/M¶d½.KÖG¶ç»jõ‰Ž'ú¼Jí¢õ"n,?f/UZô©/I‚õ ºéúõ²¯QK®É¯N›®\°ýQþd0áÛÌ:ïrôf<Êó¯&$ ›®£ºæãÌô?¨³¯ßèãûâWZLþá¯ë>þ®ë¶þúgûBþ¶È$þȈ %`?D‚aè'ËEGþMÓñ+‘¡,™¯›&ŽQÚDHEy „„z 0A¿ 4GúûJª},0ô°”Î&8d10tÀÃÓ* L¥y6ØQÓy¬Uç¡:4òT“ág@‘AÔú@»ð#ü°(æ4Çø$)0…¤•d Hö(èdDaþ{“ÉÊÉ´!½Áy Xä ˆ”u–[‘) K¸|&ÒôÀ¢ÑM±=j-å°¶—dRBHY ÄøRdH¶" {ˆ0¤b0‰³‚zˆ1jcŒ8‰˜’ùÊ!P!Glƒò&ŠH1Õ!My]±B~›V Ã(ˆ" H›Æ À!·¢`A‹qw„„c`A˜›D" $ƒ3ñÿ/óS"l¨iH?ÁË'ẩ³ejAésNn‘478 )æøKr&oˆ1‰ à ¨—¢’?ÊÉ=Eè¿il?åÔD/R`”òôr2û/Atµô‚ Ô¬&`(` ÝÐ)e꜊aÚ£Í0æDkó* ÈY‡uƒýÄñXaÌ!z &Ìá²ôUËÓç/@”óòô€ËÓ:áÞƒ®vËÐÁ<ÄX½£®^»8:äÀë¹þÆŽ¹T:å€þ㮇NºZ©è,ÊrTYÓ¿Cˆ9–£ú–êû?¥y ²üø\¼ ˆt‚äBú ²%!$ýª'âdÑ*.Yýœ"UöŒÌJ3aéÜ#3þŽÚBKJ´Äˆáþn9"J«í,#t°J’Áã8gý04ÀX:L¥¹64ØHyMUä©:$èMÓáAè2œÉ!Ë8QiEŸ€ÄT‰&Rˆ¥,Ø–J†ÌV„ÜR„˜©Í´9¡8v›B*uÌ ƒ®B$Y` 1GÑ÷Q™Z™e’b"[‹Ñn8Ì·EÂ?–ÚÕY‹r?­¹ƒð†ÂX@P0|›K e£ü‘3ÆB—™&äʤ¦Aa –“(ƒ‚íˆ4¨PÚ©ä÷‰á2ì0‰—ŒPD!vŒ ‰²bˆžAóS¢b'6HTã Ç|ƒPÊ?Øik’ð…2 á‡þR°Ø´µ´r'O1^‘ó”ƒNÑÿˆïlé/Bí’lÐ?ΆmXôÃÔL¾DʼnF9$L"µ" NËÑÊ Éh½cêDA©Ôø"nl$6bô{1~/L?€ èy@˜ &Ý¢õ¥KÑ;'=n?Ê)zwMÔ½‚ôBh9‡dÅêŸö1£L: :íð±ôÃKÒ7@F¦Ÿ³nyªpÿn¤ë¾}†y†æ&g\“uöuÉé×a']ŸÓ•WëÉæA§ôÉŸÚŒ?Áj Ýcýë©„F‚Þ­Ÿ}è‚’Fí…"D¬DcŸA°á•#28‰Hb3áK1##»#œRÊP¤0B¨O¤’«çK*–ä°NN:8g¸áœ¤À[“7L¨ 6„ØOSy&Mè5Wª´é@ËVªÖFtt¨J ˆE0í}¨â0¤RÔC—ŠRž ]õÈÀ)Qà´˜H¦yH"Ÿ'CÑ¥àìn£'kˆ3H¢‹!*«_e˜Aé&¾ä$ëÇžùÖdÀÃK‹á? áüG‡AT HÉ~¼ˆA+dN¢¢ØA´ H„(ÂbæŠF|”$(òdÖ|‰+˜ˆ1‚ }½k!Y庙 ÊA–`ÿ:~Ç'LC,Ùȃ!‰„xJÜ×3s3@›^=c?¤2y7 ×6>œDDñ8ÿùºKÏ}‰¥­ðñôê£3˜yû˜ü‡¸0ò:$7-“BI‡šó­¤þiÊ^›GÄ0îн%¯º@,2` p Ę¢#^çl ¡þÂô¡Aþ £<Ðbômþ—ô/‚ôïä<ÂØ/Mâ/JbÃÌÐ"ô—ƒ®$Bôã®:£®;!þÚ)Æx烮b#®^c®›-¼<Â0?¤¦:ãl:ãp?¢:äâØ?¢ñ „|íÜAd?°š™çÐ?ú°mè}*°Â®… ƒ>D¤ˆD¤ ƒÊFgòäD¢ÀFgúˆäfSäfb$f'$„C¡Œ}!SÀPèJþ&ªC«ªJéZK8b`å L¶L$L£lL£X¶¤ÜÉÈÒ^2dèKDîS$ÐPB$M$T#Ї"z‡bnQbˆŒˆe>ìâŒiÆ(xˆ°ÆIZT‚zT‚f„Ì» „ˆ N‹à«Ô‘b@„ ˆžˆ$¾çÞ(ãŒÊâ@äÚD¢ÜZrÀ˜Z ‚Z¥ªZÏ ñ1åqè\¡F ã®úâ £$"n.iÌ"ŠþƒÎ" `T¬þ!Lv  Ò!Fòìü"‚éª~ x!Iœ`Aþ” $!IÎk¥è"iŽæ&!Fi$ Ÿ(ô^â ›)RÇL’’¢&”Æ–"j” Ì6nP–Aþ’Búâ eú"m²È‚ ?â fÈ0æ4 ÂX÷LŠýÏÄ0ò5%‹ˆÆƒÈ“¢&>ô2©üd'rZ0éþu šØ‰ƒF¶*ÃÑþóàs3àc`Š#à¾fî¤ÃSâôÿV/CTCÔ:ãt‰ç.0ãð/BŽ/IiÌÔ |0ãô±ƒ'î3"ô1'JÛÛðÆ:ðŸ2î2ðn<ЀM¯ þ,j¦<î$ªIZ?§ÆPú—ú*Cú¬ë´ì$&âdв ƒÖÇÐCjêD§ÖätD¢šD®&=ÄJ&˜GbFd:Fb¤FcÐFcHBÁþ? <=ÁìPªUdªXHŽKK8d8e>L XV¤À!ØLäMãþMéxMäˆN„tN„`PB¤¤£Ð°Æ‡"ŽQþ‡d:ˆ´ˆ1‚ä–Ä„5Ž´%H¢!(¦?î„#KÈUkÎ5‹Ò$ÁŠÎ!¼Î ˜‰è,H‹Ð•¢îÂ$Y%þÛ¤Úäv"CŒÀ¬M )¢ ŲÁÑëJt¨Â!H 0'! †”Íâ ˜kÊöAþ bB"aD’t´ ÆÐôŒê}/,"o:RF.Ð̰"fÔ!FÀéèj²œ"b~!Bàâ®a&BË,âö # dÏ”ôÂ&<¢ k’šÇ ~–" òE"f_5¯¤"jÚmâõU(ï¼ Ò¡Ž/S&ýB 5 þœ" û2Ìû,î6 Mµh.ÓË,‚ wb&ÙzX³)*’/B\€¸< ðÍA¨0ðp2âõ1aþÎð<œbõ[àœ0ã:ívòö©„ÑX‘ò0âè/@ xãwÿ‚ôvР<‚:á–0íÂÉî#ƒ®>O´<Ä$ª cû3•BGzAbŠyä$ú&cúàþ&³€?¢ “XDñ– ƒà ‚‚ ‚ná ðD£XD£ÆD«¥.GfFixD«.‚$v/ÎÔ1(;aTãjJ£lJ¤KJ¢f8häQã†aäÀ7ÀC¤Áñ æqBKºM£†/Æ1$ÀAÀCdÊ(䨿QMäMçÎUãÆN‚ü¾crƒ¶ˆBÆT&"T$´‡b‡iƈLR'ŒM„D",ÂLM®´+.¸Fù®=Ñ€?ån6Ì.%@r"YX䜢ƒFd¦Š"š¸âŽJ¤ˆ¾ùâM·8{¢ÜïxHÀËþYŤ"ßJ uÚ uÁN ‚ !TºóøÎ"JL3SÈ!FÿYŒ"”"iX¥÷„ý¼•´ÙOÆÎÏ‚"uY$l:!F‹¤m¤’‰Ü!P4 ÌBò‹ ¢ }AþТŸì˜`øVŸBÑ{×Í{ÆÔ ÉïO2oqÕ‹Mµ8Ó"z3Q¦Ö"bTÑ/(fr‰„J-¢R]îº"r¥m /fc$‚&2¢ô1xÓr¶0úg1µƒ „ÀÔˆá7„b £Áþm@¸)‚ pA¦‚òMÓ>lmj0ætsãFâô'¢ô+‚ô3£®4"ô4õ¶ƒÌ¥duˆ‚ô4x/X’z &ÞÌ΃¯ŒacB:íÞy µ\ÃîAbéä!#û_ótüƒúBå1·gÐ+Û~AgÚÞÚ”?³…Â-B gÎ „jz$K‘è¸D¢zF4Ž~"²Fdzˆä„$G("H–b(ê5„„&äª#SÛCäñ!Ìœ8b$8b8Lýjq.ÕhNM%Mâ8MâfMâðN‚‹càêÃl¸d6„ÐT"šT&4‡%>Qd6Qc`ˆnˆgŒ¨¸ã⤳-$h˜T‚šGÒ¼‚¤¼ãà(³¢ÜÍWÄŒâLq‚O‚%sÌîÂŽŽ«hOVî-×A$ç8qÝ T¥ ¼ ñP ÅC¡"!VÍVðBÊ„¬!L¯QÁþcâauÑv‚!)¥·f Ïhh:ž!U€.Š"zRí8vb&!LÕ¢Ržúwô!JCϵÍ2Ò "ä!\å¡·r"zWÌŒW}Ì;Vâ&š7ªƒ5*)vœ/‰„;‚'ZºR:Þ Òt-BõÌ”ÀÑʈØ ' ,î¡¡ÿâõO"1E…bõ,Hh/X×; /BÁfÂõhÌ(õª/I× ‰á ª nÒ0]Y e®8ð<$B0íp}'N<ÊZÖÔê:ã/T‰ÈOP.<ÓM®kÊÚã®vƒ¯2µè!ƒ®7îgCû2µþHƒú<£®­Öê{ƒÍ ¡þ"Ä0ApŽÕjë ÃúUjð ›tˆâ$B|8à~"L°‡ã‘D3ã¤f$¤~"‚Fd<°n? #AV¤V’‚$HCÊ´qJc hè¸KÊ8e÷>Ķ»S÷¿ÃþL£pL¤ˆMƒàMä¦UãþUâF¢›<‚ÕÅD‰ÁÃËB¥BcS¨v-ÅI…$E"1¢XƒÂ!‚â耮cAÐNh]ñ3ˆ?âHƒ: óˆÀ8,B1ŸÂ*¯õEþFˆ9â*“. ®4"šà:¸þˆ0kƒ:åB¥t·+j嚥z© k’ #þ™R0bã×ÿn×)045`ÝÙÖ ¿ìØ06yþ䯼t€} oIlÏé€Ò&c¬Ï‚€ÆÀî68­õCc:?ì øH€† z@Žìê?úÀ—ø$Úèv³½¨à+òOÁq3þ  ¾@ëº~ …€i 9ÿE¼¯û:èÁÂ퀹þ§%‡ Ÿìè*„$ÕçùÖC È4öðJ§úDnŸçE¶GÑþ!þÅú@Ÿê>„€©þŸœP ªb þçú`oŸíP®­†S~Ò& ñø§ú‚JÇÙþ·.›µË ¸ÉË,›$ÇüË2Lìœ×8ºsˆ@&|Ë:Ïsäû?OôAPt% =•c"¤=èXc3­È"Ђ$º‹¡fdÎa¡gê’R¡Ò ¤39žŽ¡a”Χ †ª¡atÎ{¢hY¤… Ô«p‚ ˆ\¬‚µRÉ úè ‹Ò]Îjš ‰Ñ ‰qþ!lêÔ ŒU+L ˆzë j `´…§$^‚Yçû„TÈ QS –Ô‚ÈXGW"2[TH[‚+%úÓ ¢ P¡)ÿuKh€‚…ÖhC2‚WGý2„(¨"”„)H!tˆ2e!þµ b ^¡`z Ì¡R™!R!„¡lŒƒ€Í`@ˆ8ìo#h²ˆ5H@ŽˆH…:„1èCà© 9’ î!2¤ j+Z Y+—²°kÊãL„;Š‘°½«‹d©& •l©_Ûº¸Ô0h2¤Æ0h⤹0hR¥~0jƒ°w·ƱìϵLKHÍçÌûÏ­%^Ϫ {róRDè64ëbŠ6(ã|6 |·7È¡"ÖdiþL ލ;H£Ž•;U´;±sÖš<Óȉ=>;Ò¤=ÊsÜŠ>À£óÒ¿‘{øŽ?褘œŽ|6€ÉþŠAî°)ÒÂUx,éà ÁQÿÎgýý”?ÆØnÝ% Lÿ@):`°Ò€t£[¥¨›!î?Ù¨­Mñ)> 2ù$‚¤Á–ä§RÂV>Å!.™82‹Î:e‡M,&wÎB šlOEº§ÄîžT4Cˆ‘#Dtö+1R¦<‚&Rk¨f!cµ3¬ ˆ#ÇR à…ÄáþGªç „è‚1þƇûJ …@‚-u*XÔ!b±3©Ø¶BÁ Rþ)õè£ AªT…@xBÑJ“!lÔ‚4u*´GøPS„,d¸´A h„aEõnBÁ9 ¤,\µZA !„,"±rBß©>²äA !¤cöˆÕH\j,\º2 ç!B ‡à‚ VNBÁ¹ DD"hB(Bñ ÃþOˆ´ÊšÉ,ÃØÊ0j?â´cÆ€…¶QþØÈB €Øˆ3R(ãÉ„A2†¾1NBÀ ž/ˆƒõdd@o‘ŠDQ1„!yL‚¤È‡ý!à© Ò!@`Ñ\iƒüd•ÉZTšQ’…H†•¬T‰Q†+Œä©5ÑþÌJ‘E*N„#NW1R' ˜˜2DTœ»5o†4æ4(á i3éXÁ‘#ö\ɤ!¦}Éú´?ÉÁŸ/FÆ®¦ƒbN ‹16&0Ý:'gX9œéœãL+ÑÙÇ$ÇŸœrÜqÈ¡Ú(§hü£¸yéä'GŽ“ zOBh=ÄèûÃìN±¸?… ÿÅcþj@ÿ2¢bº B¦ƒÍ2Vo¸ü?"0†˜íû¥gø~’ñ@šˆ"^h£ýQ‚qþI‘¹z‡•–ä$DÒ5¹õJ?É¡Eá-ý}uÁ“†¤„èj•’ÁnõÍ2žDÊ=_9ä2pÝJ¾tØœÓÒY‰Ö §¨‘€pPB´2‚Ú?É’•WÈù3Œ ¸³T¨Æ!qšº)PÀBÉùÉž0GÕü¥Wôš †uJ²òs%ô¨Læ0‚M²@ˆ$bò¥³¸A*g*TRH¥„BË1käe¥ƒ9î …à‚GLW[ ¬,¦FbA H[G^s¼)£Çù£Ñ¸¦{µ¢öHA0! l‚3t2U! ‚⣀F»b, WEIi”d#=¡2¸¿BV! „i(B !V+¸„¢¸Ìà1R’ä •Ç?Õ‰RÑ੤M\¤—Û¤™J’¯0jΗÝÌ?̃'æ V˜2Š`Ôéƒ4'ÜÆcJŒùn0d˜Ï“ó>ÍLù`sæ“WC?ã¢Eæ|“8o‰Ñ±~¦ÄŸ›âÌK ÁÎ1ƒh†W8erN¿!&h°&'eNÑ£<…ô–ÈRI•=&t÷BÈÒ|Rð?‡@þ£øAù`I Mr*ôj­Ú³AïÕ÷4$aÉÃÇCéû Ô90„,ÖER¥IQÊŠeJæE²?Âq Ç£üSKÉBA6z•$Ø’ÚçID™ä‘d šéçèò¤S9ªÏ3a‹Éi*A#ÞR ˜¸ŒB–¶‘ Ëyœ‚5)ò¾‰/!ÁâÿB=L€“™‚‘[Ç2ˆBV¦i…Xk´…–(‚ P„@[©…µø8ðܹF£ÚˆAk½Àˆ%8‚P¨ˆ„> +B¿:hˆ )Ši°AV¡Ðˆ%xcT¤¨áŽÁ¬®ø„©ƒTˆ+ ž4èˆx©ð„ QÀъ‘u “W–°ÀŠâKŠ™ ŸŠ“tЩ Áž:š ’£‡ùú›˜ÆœYò®HÁ‰ ÁœàÏ·©ÊðÁC¸0Ƹ Ž™Ñ88Ѹ ÑÓ‹Ö ˆÚ¹Zêpˆ|L!sPðÌŽ9Î8Œ8ɎЧä ÃX’ §Iš ‘qQH¨°½±íàþÀþ ÿ‹Ðv®¸M™hU- -Ø’xx̰‘ ŸŸ¸Óº+àц:s€L PãšPÚâ PY(WØ’é¹òœ’±!‰ùôœâä yGº¹”è|3)5È!6 pÏÁY2¡ä‚Œ˜Ï¯!ó“Q7¹ÛËó̼äŒHÈx4Ó¨™J³1Ž Sß¿H…¾X¿±ì³ñJ²¹ó²QJ•árXO;8>চ3“8Œ"Ëè«gˆ#Ò$Ë\?3–Øòˆ$ œ˜û ˆ"!„¾Âïˆ#ቹ3±üŸ$cÖ´°‚$XÊ[ý±Ùòˆ"‡ˆ"K²4“ˆYް¾ø‚(ˆ‚'Óã4¸‚IX‚K×"~ˆ"óùK›ä2il‚[¿¢GÀa2µ2‘ˆ@ž µCûR€– äz9§ˆ„ ¸ø„1Rw@’3à…¤H„ `„øþ‹ˆH„Ay©¥„'€¡°lƒZl«„3p©xšÎ„AÚí àÜAÎ “gÂc;Šá 68®)8©3ašŠÊŠ’›9È©B¨›p© 3k΀®)ó|(®6xÁ›¡ kx®0®Ã|ª˜Æ‰‚¤ iÏ;pÁ2­ÃHÕ ½ ú³Š(Ï«bw øƒ ‰ŒùYˆ‰ ñ숢ˆë0©ƒùÝX®£Ä¸ ðš9ìŽ8зКÐìPòâøX…I IìH¶q2¬¹í¨ûþ `ÿ“(xÜbްT« ÿ­Ñä­PpÔ‘˜Æ- ·¸¼ð¢»i˜„@¥laŠ+Qˆ2‰ S¶“(JòÙ b ¢°pøóŸ ܲê†À©­¡EÈ€.¿Q2“2ŽÑ2¡zh¼kÿ<¢<ªÿÃHÕL"0XRÝ—0…•1J˜ZªR£h……i3ËõJ™#*¥Q3¥‹ˆZV”ªYÏkù"i”ªp›p‚™ä”©ž‚ˆ…Ë8…Z;˜ ‚ˆ‚=£<ù„•ȇLøVh…†‹þ”ªb¹È‚g$¨K€”tª0ÝnùˆÌëýgÁ½3T´Z2sI´A{ÄË Nx‚?@‚IÄ#ðˆ$ûïAU8…À…|@Ek.à•²¨”' èÌ…µð–Y|„ÓV«PÎ|& ʈB[ˆC 5éc„Êú{CMø¸B8„(ชj‚ –’„Ø£Ú¢Mj…ˆ€Ô ”È™l1ƒô ’`¨Å.ˆ„êO@©êߊåoBÚx®O8Å ‘ ”Í · η€¸ŒhÆ ‘ÈH‹*ª»{Œh†·`Æœà’ÀÏŠpÁÐY4 øÊŒú§‘Ý $„9Øž:­‰DD˜ñY…Ûœƒñ4äø ð‘8¢ ëˆ0ãŽù)8ƒÑæ”`í ÀóY+HëIYHŒpî°˜pÔà…àÊàÜGøÉ„èò…:M%9‰÷(y ²ØÙò­ Žò‡¯¸ è;ðÖ0A Gú®(¤¡ì”P³-ð½Hò§H¤Ë{YÆ8°Æ.@’H‘'Hî-ɹ¸@âþH!J‹pØŠA,9 D“¢4` q˜ò“š TµLàY@…ˆ6­‹³RTø…ŠÙJ³pØ“ —Y3ÉÒë½ä:zLÈ:W¿x…™{V™n0©3—°‚LÕ~´È…‹CÔ]oJâ>ÑJ°° +2˜…ÖAmTˆÀ¨)Yˆ"6@‚$èÌ8Ë蔓빂U+׌¿> …²(É­¼yœˆ$á ­ˆ"0>há;3ˆEJf(³ˆKÂpÄÔÙ,»ˆƒàÊŽ9°ÆècûONø˜â„3$×FípˆBƒÚ^'Ã$hˆ P„LЄh„L êCDø„%8„ 48&™ˆ~TXŠ‘ãˆBí‡üæÄ¡ºˆ €®Y•¢(„Zmù¼Š’:Y|øŠà’ ’{ ‘¨ ª’ h®Á‹Â• àÖ ¢®ø©"´;Œm¯‡ûrlý&m˜Áˆz¬ ÌŒøŠ ’CØÒæu !šŽv§pØÀϸ›Pˆ¨ ök‹`FM\Ljû ðÊŽ8ÜQëž ·ðë »ž@Ì#–+òEh©HÌI2pèq³œ¨þ ˜þÄ POŠšìŸ¬RFK‘xx…qúŸ¨‘W­¡˜Ÿ¸ÌŸŠ;Y…c\ÐG‡‘ˆë I `³R9ì…›PšuSuz®Ê…€Èq$€¦ Uð Àm>éþ rÈ)N“·é2¡™+Ÿ8ØÈ„‡:û"}ü“I“£Ì`V`XYƒh!”]uSˆYž±4Ì@õ¨4ˆXŽ L2L—ÙA3˜ãõ=)ˆXÅh…ÌÑJ¦êD£{E°{ä»un“9Tˆ"‰“*^êýxXJ´J…Ì{û±½]ÓÛ€…×¢cÖÍa­yI4Ö´ˆ\‹¸…¦rdLM^?MU™’°ŒÙá ‚U½“²ð%À«ðjà‚o …‡ù~4 b™È4 ~dv:@Zàà„KЄUº“¨nHŸ(„>²†ýl@¯d“ï@œG³ˆ¬càˆ|µ„d°:´àAe¸³p„'ˆNPˆ)©MîúRˆChØ¡VŠ‘TÃdኊ)è®ZÉFBP®(|+ ®)ÒdfÚ™ l$ÙØÆªH£¢¦ŒÜ ÊŒàÆ—Tõ$9*‹·ÏÄ:ïçpϸlöÜ*ç´‚QÑgÐ!Wƒè©­@ë ‰šŽ8æ ÷5רãÐ㢰í `ã¬9óÑAä ò9çYJDZ¸÷Q»8p’EÞ.¸þ  Æ•‰"ìÛ¡Ÿ-Øî-ØÃx’tgĤj^BV­ ’^d£SXÑ‘G°¨.u.(½Gè8‡ÓXÕ¸°§R_ ‘*¹/…VªŸp¤ ˆÕl)ùEì£ê«9ØØë{É“v¼`É· þÔ–¾‹ì … 7ƒiE§ ¥á¶'.ùJ┞àYu#Ö”¬·´¬®3¹Ø‚VÁJÖÃÿˆ]uÖñJ¿nù—Û8™"C°p‚~®Nm[ìýq“<·VÝ`32{?À‚wX‹`†îø1?‚0¦ÇM¬nè…³éüJÀ‚3›'í:8…øé†+aø¦;4ÕÃçðóê¿ YÕœÑa £p37”Àˆ =ð ò ŒÉ%½†ˆˆGêÞÌm‰&Xï!ÁjŸÂ IB6Be°ˆp Y(„°„@.ˆªMX„)^^ž €E‘H‚ÜÔ­ÁPˆ)NþyÏ!ŠæG0©&ÞûŠà«Ãp®CS‘qpˆfè´C®BËe‘Ü3ÏÀ®NÌ?.¸©<Ί’V“PÁöˆŒüf°ÆˆçÏñðÒ*ÂÞ ü÷«8ø ø ý¹h‰Ð«ØŽ`Ø‘z³ÔÆo o&EË ð…gò¹éóŽßàðþ%_ï0‘þÛ ŸïÀ.G?Ãà[ýú¿ÜÀ¼ … ø6"ÿu€ ‘påþ?à€¡þ 5_à~T{ÔÀðáþþ?Ÿïð&‡ §€¶ ½¢h´Ô6Šõº¹l¹Û-ˆ >¡v¾_o×üZœ@v ¾mo [ì0¼!Ž ä_팰WÂËOm÷gø“,LË\ßêL³Ã,Ë ±Òû~²ÞÇ42Ál´rÞäÇS-匰3,½ËB*öËx‡,HË:2ʬt®ß¸·‹rÁ,´bÞËËrÚ*»—,)áå¹ñf[Åoåùg¶¯,áËr­íÏvX…–få†l³l·«‰ tù²Ç¤Ë7Çø’Ë" ¡€Ë,°VË2©¡4ü­êBÞ"¦gøËL°'ø@gùÙ­És-¦†SƒŠŒ±Åš,³Òšü8œû4š̰iµ‰¡´Ë*   Cáô>PÃèÂhÃò:Þ/CåàüP$>s¦a¨Œ™‘¦ºfA ¢^ÃÉé¬>L+Qÿ°íÂhwNâl?60éë7Ÿísö°å´îÖ0ï£Ñ3¹Ç;ŸS½„@‚ó»1N½ì<£N¢í¾”ìýN¬ë5NƒÔáþo¬ÇûN¤è5[»Ë9ï[¼TêØ³ƒ  VèÂΗÙ6-=d'6’0ÃÏÑX’îò¿(€èXo¼VÊWoƒ€£Ý ÅÒ—Ý("ÄÖ,JbÄ•Gü'{¡—»Y{Û)¸'‰ Á7mÕ„+€v‡GåþÚJX~Ÿô¸"Ç8Ê@ Ÿõî<ï‡ý‚ È@,­€¹þ €XvçD ྯª'ýΉW¡`ŸïObtùlµ‰þz€¥ð«!OœK(“«èa|€`ž ©udÊáß•0é]ÓråGÊЭ*J ‡1ËB®½® (º®»Âì¼/L ÂðËal9ˆ¬AìºìpÒË[+y&Ç3ÛÁþ2×:ß3*áÛ,î-ëAÿ­æ{-§-à›32ÓòÞT±ÏzÞ¢-ï"ÞŠ*îÂÞ_=L´R·Öj»tÉ-ßRî±Æc,†-â;,2È#·é²Ìš®Ò>챉ä­ü™þ'òL´#βÌYþ%¾ ±XËGë|ì·Šps,\ÃGû”šxçù½î4¦XÆ–ô°?ÌÑoVŽc–ñ²õÐú <ç8š#“ªS_HªÔ1þqúM/lš S,‰ 62ɘš!T6‡ßio'DÑ“CT[Æ::ÄÐÈ4>ø‰¡Ü&ƒ¨Ö¡óTM‘@&‰°š”>f ¤7OКrfJ ˜VI„E&ð6o ¡&„¬Ã¡âh„Ô‰Üÿ“FœaЩ4uétìaÊa4\æÈs¼aÓˆÿéÝIó8§JdrNíN©óŽTê•0äéN’uL­2ˆ uéIh×ÔêTJÞLõŽYÊagˆ –tìYÉ9gzK%–t̲VÊÉ9E(µu‚ú•i%Ao¬u¾–û4[é™o”ÅÒnKÒ]-9tœâÄô‹š,Iر)uî™—ºQ_Œ¯’"À›(Œ O°„¢ÃcBb‘¯&¯[‚vc+Œ£$?Ó´û9L±²dZɉ{,kàaM+r #Gù¼ãý3éøNÈ¡8DhŽãTS’ˆ”g€ ó& ‘`Ãü÷³–Æ*Gù¸#ýÁqÚ™S@‰62œš\Lª/•B¦M ágne”{Uî[ 3w* é'vü`œ{põ\Á‹pè³ÇüJ-îh··¡jsRAŽ+…½æwl?ÞÒ‡1Çô·‹ó,t§‰WJ"¨•qhe‘iot|Ç:!ÿ«ÁWvŒÌËCWàmÌpd2Ñœ·×²ÞõúÙsæXjÆ[à‘h-çü·‘ÞwЏ·y¨R¹¼¢Þl–Œ·œ"Þzßå¨*©iÀ#‹kŒ´ ·#üT!ûd?αow`·¼RØMR ³Fv«e¢@ÿ³!YhŠØŒÅÐ:­jT·Úòipî¬÷‰–™b@M±4Sv̓¬M‚uCàðü˜––̰8CêÎö!÷¥PùØH|°Bˆ„¼R@6‡56ƒtHª ¡ôüaïônCè„ÃÝS”œ“»š&‘œÃÄöͤtNõŒÃâ2¦aÝa‡Å¦];ªÜ2aÔú5F©Õ‚aÕyèV™FShSê›ÇË Z ‚ÎD%b´J%!–u˜HË9¬Y-|³œå’Ÿ–I:Y&àZ¬ ýIG­[çao“e¾X&*áW ¯95Ó6øñ]h´±2ÄD `^çÅ{¢ÕîdÉŒgD‰`°$ÌÂÃ" 0¢ô~)³¹88CÖ–€ XØÊ~Ÿh¶}¶6FIÙ_dÆñ”šªR(A®LOã€:?Ï9"·œ"°Ðˆâ!”1lŽáþ¬ÚbÙjN„8HÔéÞ üÕ«0ÙÐW² f¶&^YvUE*kÜ•±bVW‹ú,¥}§2èæ*}ž,¥t»W^jµXßŰ\fŠU–I¥½(•sè[Ʊæ1Öˆ…§6c…=Ô1È„· RÞsžAW9…½öhUÓ1oM–Â÷\[ßéo:¥k‹DÌQ޲Lè·Çòß_Gú*ðØ+}x%ï-÷È«¹{iÑûÏ2É.2{Ṉ̃í-èÓ–=bÞeo –fZÜc-~–?q"ã-ZÆ1–,}Ñþ néo4DÑÆº8¦ß ÿƒô¸‰¢7-éš‚ß]Q4X%¾&^’߉¢sãå–\‡Ý3&˜'NÉP9êOƒüi¡óhMÀÿP5£òh×Ì2Ä-àz1Ád2ÏŠ°®$êð-çœØ®®N§¢¯®xãO$¡£á¢ÞBbÞé¡þ¯áþ1¢®…®ŠïCf2Ñc¡\1Â@-å>vãäáƒ,苎½ë¸-ãâtîb‚j„d-ï:õ±Ôë UDj-êÚŽ¡þLÞvB2ÇÔ-á62È€-c-òî¾&ƒâ‡Œ„$ÀïÜ-ëê-äŠëŽx¬ž+à‚#,Šâhx!þ:ÔBÄ>7Žà&„J&bíÈ7"r–&€¤CïŠ&†Æ&ƒð0åÎ@~1 h Lü0á‚Cãþ0å‚&‹^0êö&…Rò#È0ã'-$î¦lRCè¯Ì€R‰6NãD0ìAÅ:Z°h0ãD’e:S¬‚»…:\âÎ) ž“¥nÌ DVã&,êf,ãx¨ÅnXå’8BÎGå’HlÚ)ö½0À(…’Rå¾R¥¾*’W¥¾[%ÒGå¾BeÒ+L]dì]âÂÎí 9z,I¼»…îˆD …îW¦zS¤¦fGæeÉd%mrLÍ”GíF\íFD&2!‰öVÆ<,<\æF;ÆR#RHfX,®ûp(SáàF vRª$-‚,E-„&Æ„R¢ '¡*-9À`Z& iª'¡<ž",SàŽ*fÊOÁ¢\ªä¢%Ô¢D¢fB¸Y"¸S­Ò*fàô ˜©BÊnÅhÞq0ÞÑ@ß#Amù¢ø@ò3áþŠñú2Äh*ñìîc,F⮣,§’o#,"ì} IN¾*ë^…Ã,u®ñáþëþB¢®ì!þ„BÞ·ˆ*èLëgü†’{Kgñh®#êÐü-ïR-ã]HËà*ât­ RéÂÞRñôðçþw#-khï&HóTÞ-ìü-ã8ì¢ßJ®Ä|ÂÞíµä=Rg&”ž-ñ^&Tê-礀Ä>…Aþuj-ëðAþz@äî¢Laþã-WbÞ¤>fˆ:-ò¨&‘”Œâh·Äš&ƒd]Oœ-ò¬çXç$>>2²·•­(KBCáW)ÿJ¤á²Cãè&€ Câz&‚lÀ‚h‚ÿÆCä.ëL0ìü&„zƾ@µ/AIàµZœfƒ:Ãd>Xãá£9œ0â9.¦ÖNèL0ãœZÄî!ƒLÃJ…;0OÁDrüüeh‘‹1þ8E:Xå:[%:’³eSLÊÌ ’É@Vå74¢Î=édVæÆY%f,æ¾Y*fKÍc„u¢ZB‰…¤Be¾D%¾5…¾-“|ÎÅ*]$J]"m9¥×Ê!9Bš°jkåîX%î9ÂDlbD&ÆNÉÄ9Ó¬ZCXVF×#âÛE*Ôg¤ÔefÔd¢ŸlüŸb^cÄ¢dc”dŲe$&e„̧â‘‚(EÕBú¢Dü"D¢"Ã\#G¤bÇúEb0§âˆóz¢®Gu.ÛâÞ 7ú¸­Kúˆ5*2Ä†å »èNê˜ÿ°/22ÔÂëâÞAtФQXàÕ Sç€Cõ~-ë:ÿ‚/&CôÓi––¿}¡È#c,y”º(‘沈¹%bÆ-ï°ä´îÕ¶2Êf&Ž æ¤Œ2Ò°Fhç’UUªÇ',>Cî!-O=¯E\ã,…æ”CøÄä ÁD>HuCèj&‹ä0â&’•”ÈÀ´€l ˆj`Ng0ä´&‚0õÔçÚ0øõ ojCö7¥HNìULDïc¡þÃBØÄîã“™DNå‚Vîý¤~S¤r0âS³3L…hX,°ÿ³£éTVålS°[enW¢Î%bÎR¥’fVøFJ!ýÐ-]¬ÌN…¿h†¢[ãÞ[çX[ã58å¾#ÒLÅÒSåÒЉâ]$ü,H€^é­…ê—£â$D&$C°$B `PyR9ÅÒ;Y$àC¾ÑÔAþˆŽ"2W¦2* öLÆ<=æ<8WeÊe"m C…hãÚ¤"V×dš*B¢Í‚"zP!”!€\lt$VbZJ&ʈŒ>*^;ÀŒZfºÏ؈#š,aVšP)R,„-4]T,ö®,¦äÎÍæ<ôpüGHÞñB/—®0Ax ”1ÎÿŽº*îå&$Ø*â´ôàÜ2Ìü*ä2äb*ò+ˆµS‚¯–˜ãc¬J׊AþJ‚®ô½~"l*ø]OÁÿˆò~‚®õ«i&+¬G4ä„%\"Þè•¶µ7±Û†äp1Î8YBÞ Çï±®K¯‘½"$>¶˜4£õ§{¡ÿ)ø72Í„âi«ŽíêKS>ÏÀßiŠ=UöÄ&€‰NÿBiX,2-àªCòx-õȸ›Z-âN&‹Âaþë˜&ˆ>õ]„>¬±ŽÈì2ËM¹„?‹¦Fd>îï\¸D> ?S¸^‡¯LCë›'lXCè¡»Øg·D¤0ãú&–æ & ržkã„I„ïŽB€0â&ƒ8þ„î¶`cDlWdï`æNþäîþft0ãÓ˜$îØ¢ÊÅe:&ÄìÏÜKE¥h5“ ÈåhÿŽNªYehË:3ÂÏ4°Y%*,å.,å>ØÜ ¦nYöîÎÄY0BÎå¿7å¢[ö¸+€]câ]%äYS”]"z^æiåî8EîÐÚ $Lü$F\`E³Ÿ3²Ï³ÏÁ\Ã41iK¹xä'xâ0ÔcXc#4Ÿe.ŸcècÄ~dcpdÅze$~e‚8bbØðüdÅB ü¢B*B¸ØE>h¨„ZÆ4§UŠF£æ$2j9ŒfSì¾býÀtÉK)Ç¥u'¥ˆ‚¸aJ„%f2¬æT+W ÞâÊ©ª¢X‚»G"éz£Ž/º¸zôûëaþC"¯'1&+3Ub¯°;9®çX>-ãT*ä¢K£,6‚®d ƒcÁ3ÒK‚O^*åf6#,ñB°*çÄ-ûanOÝâ2À¶´âßNv1Ê×O; -ûq±Ø·ÝÚ4¢-òTÏ[&'íÝî¥4þû äC,eÂß+Ò&–·C“!£-ºAÿíìE"hKÂß[›§åÀà£úŠƒA>uøiYkœ-õŽ$t»€’Þ¾aþæêèG»2Ï_"jñ¼bi‡2të¨aþ?{×}èšGKÿZûÂJKÜCãÞð¸ÞCõÚî‚i^×ø&›Å)Oø&‹×]Äï,ÂheÏnkù \`W(‡JNõÿïã$fCòÍ’¶4Nòå“k[Ä g!‰NöÅ:7æVŒ7 ÙJRyjV‰.`e:(–XV™l5E:9ÂÏeùzˆ£fn(‚Ï2å§h¬¡h` ÜÍb‘v#ÞY#yÊe’˜M¾[ãâY"_7×ú*Ž$Ä]z eɧ9á90fW¥îzEîRùæ`‚V$CYμð ‚DE¿Ž%t0W¼šk¸ÔdrÔbþáðEþ Ÿï@Mþâà›ü: ?Â1§û°Á¹€×øþ‚€ð˜:ÿrÏ÷8BÿOñí"ßîÕþê _à0½þ ßáPºbÇÀø?¨€÷ÝþïŸïÀ þ Ÿà`ª¾?àO§ûöS´@ù8N~Å@,fPÄá¢Ù)@ŠËÀ²ùÙBùl“¿Õà “£LÿJàK/YgÉu#­c;R¸Ô½õ“¼ÓRÖµ;Œ–Ã1ÀÉõ,H#XPÔÛ²S<Ç;$úÔïŸäÍ`ßR–ÔÍòÚ‘~²­’©d™ú`kR(ÔƒužÜ‘+RÒÔ‚õ! K쪵.0l5-s$d;mKðÉmJœÉ­JNÉMIêÔž LÉ;‚\2çµ&‹R1§øLÔp›ŠÔÂÌ‘¨þÄÁ(~) ¤Ö€±þÜ1Èë$5+“$_DÇÃâÔŠ11dÔ›­Ha I³DlzÔ›q0Ô‡ñ1ŠÔš±05 íL$Ç­H-M;Rï1ÅtL‹1À“R»1ÈSnDÇLLÄÇ£% s`Ç2HÇ?ŒtTÇ<fŸçŒM 1ÍӌҰ(P Ç2CÛeÈJºªÜÇaþøR©Û1R¡f§R¡%f™Ò¦½gR²å*”R³ø¤ÖutßfH6f0båJÊVbQfPve/f>–bf.À*‹jY¶ˆs ×;™fMW:Õs¡W<ÈÄ.WL‘>Ô›Ñ 0ÂðS$5Ó$58[%12HS0*µ+S%-2F²+3øÉÃR2JE2GQ™ ŽkÙ’Fí!—Òd€áÿ|¯¬¨,j_ùÇ5$)é™(?Æù©@°$ÔÀÓ$ ÍHžHš$jE¹©;PtUð´ÐÿEF`Z¿#R Q3ñ2BìÔÂsØ!1É ÂU6ãL3Kf¤Z’Àcžq’-F8“˜ãdˆqŽAÆH$"dÄcŽÃDÊüÇV¾c@ÆDÊH¥ã$Á rŸŠh˜a"dîc£YŽ|Æ8«át¡"òUDÉäŒÅfx qÌ1ÄJ‹dLžäÏÄå\"JU:ö~¥b2••%¶H)S€¥Sº••£ý„)Rn®•™/[êÌ)RÔ³8ÿ…Ë0·)Tœ³ ╘üá-UÓ ÖaY‰Ýf8%ÎXd'\æñfåÎq9AY„ÍsåÎKÌAR\å¸n4à°¾çñs‘ÓXy$1 \Ä0FKØy€aì"„€pŒ*%aäì°†H†Œ*wdŒ™2GÉ {%åì…3NÌYªÍf,"VtJ’Gh‰ükG”Úi Œ ‚0²}a!„ ˆb Cšñô#dýÌ‚ˆ“ŠÙN4–¢‚bÏÉ©ð'%œžŸá~?ÁóѸ¾`XYŠ|ùŒ•‰¤l9Ú]cÀDñT?΃ùš ºNÛÙv.n’î_ a€/Ä Ž’PaH±H"Æ ”#U cÌI˜"Îà f Á/2@ìÖ%b|j_‰˜f¦¯¡­c aÂ2AÒ ™8jM“2AÖ@c$AŸ¬fJØ÷®dŸ5˜5!PÔ¢ƒ0iL’}<· ËV?ÅA©MQôÔ‚“XŠŒ’²A¤ ™+ª Ì’G3 ÔŒRO̓و¤ð³Rð‡úT2WzÒ™+Üäïy©¸µxÔš¸kxL‘¼y¦¥?™+@ÙI©6†8ý V™ÀîéB½¡°?äŽx÷Ô«ó%#SÔD&Iåâ”d•܆7&¤Ôè\dqŽK—"hßÇøgDÈpÈ“T“Q5_1ĀɣŸÔJ O™ 3RQ4X1µBÈDL¥ÌpSDØ­ÉâsS¤yŽIŠV ˜ä¨cr&9’á ã┪l@´Ÿ€1#•€;B@ =u*ªüR«‹õf‰LqFR¹½JŸå*†”©R«{"©V¥Q†rY„ J¤˜¥'¢ÌO«0°)Y¦áWJY„ÝfuÎU— éH뜉j¥Ø?ò´û].)s¯)db ºçH"±õÐ9¥c _úP.˜aÚaùXÄæYØyJ0¨a‡‘“ ]Œ+EFŸ²B¬Éƒ$% ‘²‚^Ê‘{: ˜–¦bâ™ÒdgG0\#fˆŠ†ÿCM++4ÓèÓKsP {<„"Áƒ?"œŠ¼TšjdnLRôµTLkL„´Œ“R@ò<1#¼Œ4€ù$`s–üIë™: žoˆA2Í6 ÃxF¬Øt§W67KÉ$ä¨À)WD`y'v$¨‹,Â,bÞâÜ1Ž´€0ÁøþïA‚ÀüÕ ¿â xcýÕ†CDñAÃ!ÄqD4GbDqP$@Ó ÄÑWLb )І"¸ƒž ÀЉ¢xƒZ Š‘" €—xÅA‘|Ë_D@_$D‘Ú 'ƒâȃ ýˆ¢¸h ¬ˆ>"ø€Æ!:ƒ+¢p ÿBƒ "(‚ò!ƒ\ ÅiDA«a_ã°!þ6ßë8ƒKš\â øƒ»4$ˆb Ï(ƒ4.ˆ4)¹¡4ºˆ>âÓæ ¶ÍC ÃìÓƒ5~ƒóJ|Æh¥š„A¥8mîs¾ÃsKÓ×4Á棸f¾j¯†Åa›Ù¡¾jk†mf…™­p þ3EÃ4 3K+ ¢?ÁË4fðÍŒ($Á¢c¤È˜0iþ3L#üCÉ‹üdCÀ{4lÃÉ üCÊ`€póhÿò¦ÿE‘š¢ÿ.Ñšÿ&1š/¦±šºÿ6™üFgl ¦ ,?)¯‘›¥+I'úË+%²´²®Ò²£+¬§ÇøBgúœIêŒf€Çø O/Dò©Ï)XªóÌ÷Aƒ@»Ptÿ4Ðjp½œkI¸ÔœÒÆ€8˜Ó‰m8~UO  §U2U¸ÕZjU5¢b]Ÿî‘<°†yþsr#`Ÿñ ³6;èú ‚Gúùhº@™þ­‚‡ûlÆ ±þYÿN–W`gú»t£ éþ€ùþo€ þu€¼äçúNdJáIþù…–¸Ó²²ˆK॥aùÿ)^K±N‚`0Ÿ@l¶…ñþ¸ÇúZt_u¢ºzŸòz ¸!’}''Ÿ¶Û¡°yö‰MYær$8p‚Ÿáj!!¥ª n"° = ÉŽ Â! !¦J Z"2– Áª "«Aþg¢Ò" ² b¢ šÊ Î ¡¦!—]H€®ˆ@i ¨"z Þ¡ªB p Åú! Êû¢Š¨È0šˆ@H5ƒFºŠ ¢ ‚ )!ªr Ýi耜ˆE›ª f´è0¢ˆ6ˆ5IíO,ˆ Ë4g"aþŽ Ï7tÂ'690u"È…€ƒ,¨0xˆiL7@ƒ0b°â¢b ¢0Ä×bü‡úBƒ! 6˜ƒtGÿ€Ã1Û ) Ì» … Ï« ûGû•åøÃ"à ~È30€Í8gÔf—ÃÚ3M0Ã@#âÃLÑ[0ÈÔÃã ¢`9šCJ¤Ã!Ó }Oò{0Å Ã cø‡ #<0Älÿ '臗 HP†ã„ƒš{`@^¡âìa‡²lGø†â²A†_øÔ¤¤<5"2DCüý£8š?Í1þ8H̤E¦Ù™íFql¥2NŒÐz3i‰X­ÆD¦¸´mFg93%4¶?Ë’VIéY|H@6Ÿ@ãüž þy“ÊøO$!<¯òBÓÉpP,<‹§”T ÉŠƒIê$©2® Ð"“^ L–©2V§œ) q)º§ Ò¦M*™*´©Šê«‰*ÑY«ÈˆXŸo£*G¬B®°‘ÂD‹0–¬Ã\³D Ep-döµ–ÙJKx§ ‘þFÄ[ÎCý¦¡þ=éO`p£<§Aÿw«Ø½ t®&Gù°CýR¡þ7@-åè/±H?ÀèœÈ€ó\YÃý ÑþTœÍ³6DÆ>S¤A-,ñš³FZË# í™3ÆnšX`a¾Ñ! 5Ä4fÐCNPÿqCüµØ?ÑcI7dÔÕðAŠadT(8ò îc©%Lƒ²*䇸¤"䃂l˜1lpŠœ‚ N5CŸEŠ…Ò MH1í Ð œòbAƒaˆ§i½· ‹ù,n؈FÒ h3Ûâì²6×LYE|á à‘€A—¡EV]Б¨ÿÛ @3QÀ'GûJ Õ±wb!5‹g„¾`žHˆ„9xgˆ H*^îIš"äÕb¦a…‰& ]c5 ˆ20ŠE¬ÍÓ4›È1¤0Ѷ d|ŒÕ‡îÀà O 1>0ÈÀƒPˆVfŠQ†Fh¸b[ Ó«0È0ÃcüGÌ2$0ÅÈÃà Ãñ¦0ÀèÍD”jPŒ1È?Änø0>ìÀ~DA`½0 × 1°?Øy¢¡è¦?̹þà Ý¡ãÌšÑþ@‡ú=õ±kJeé¢lŒ”Ò|{ÇÉL…äÔ¦C±iM%hаұŒFj‘…3Ü»L’±Î‹ì>1€:VB|U)ä«¥bVžXʃaÉå'§’| Ï4 aò~‚0ò¤ÊŠƒ!jL©³5PVôB¨T ]SÅM<2RTÄÅU%VD•YæV‰¤`¬P2Ž•Ië„,$¤°˜ÊÇaË0®¬Â®A Ùc+Xž-b$¶OšÙ0ƒšÞˆ”ܽ ¬üÎâá=‚î(SÞx/a¶AVô~- Àp+[LBŽ1þŒÞ¦j¤cÅhq…Déè2Sh®04o£”©Ñè°Ù{¦¥Á‘!ðϲb,$4DR-Ë"¤¦ÕP”D™^4·k¦Ï¬1 ¤¨Š‰ÓZDq }cþá9±þÕˆmà©D@çתª]‘?d4Q‘ AŒ…+ÄV§ŠÛ:AA#¼Øˆa ވ1z~з‘ZÍÓÉÛ¬"à ¢ ß:?bdAú‘·ŠÚH„ð«\¡®Ý ôÇû×®DAο"l1ùa ƒüã2È’A®Êj¤BóRA­Ðÿ|Cÿ Q’ ;¡i»)B!_Ÿ)Z3U¢¢ò¿…lù†E„Í2dv…0×:@8C UÈ5ú®†ªíÐŒ3½Á¦i¿˜bGQ Ñ'¿&i£ƒšfªÙ†Úæ"™ª Šd„Fhµä=ê‡ü.0Ƨ”Z#„Z"xZ&2[#ÌØM¢­L!þ!jV5ÊV^…ÒAåÜQ%Ü'‰òM"B!o¡˜‘€Þf Â®¡DÒÄa†2i¢£„¢E:寤Xa¶£!ÀЦ>%¡¬Þ…Ü+¡ì¥î¾zÀª^Fb$a"¤ ¢!®ê È"¢( Çz Â2ãp!B*uþ² ‰"9 °à6 ž ÀÆ"Œ!¡'¢ÌóÂ*^ l‡8"¬®ëbtãv! ª´1~¨Â <Âê"Ö«Â »1Îp¦š"L ÁC! †ë47®Þ" 9 %ü"¤sB 5‚ 8 ~«ÐJâ :‹( ÄÞûqâ;î¢èqz9€ž àáþk‚ -‚Î3Oš Ç` ÏFë,æØ0àèìî”3C$o²|¾*ø²ƒ é%: Ì`Т ?c Áþ0C êAþ8ƒØ±Ã o‹”ëŽ.0Ñ…'áþlƒ +£ 3# lB CÊ3F¬0ÂØ½©š„£^3Kð¥ã ‡áþð¯…-£4ÈðÁc4ÃŒ0ÆŒ?Ë^‘# Gáþö²ãOP?Åà@ Œ ²‰aB £úæà?Ó"_cüc#üiƒü&£ü'D€úó4?ÊFl†õ¤fÁÉØJiàÿÄfö¤œCÃ\FdÒFb¦FhðXsJb|ŽÄ¬Mð.g¥€JÂØMfzQ!°ä é®ð9Äò)Ð<ÎC2“lüÎBœO¬äPðjPi:S°†RÆ/E&XU–o¥&0…8"å8Oe8!eLTF8UEO@´Ó‡œUf:`ðœdF3 C3 ň,¥„+¥Ž.E˜3%˜%q*¢+¥¢Må¬D²_¬M!.ÞÒMå¼*jV1‰Ü"éè%¥Ü6 îF ¬`bMèÝeÀ`BìÜCæaVdBZ)heàÝ©ààã\\D@ßDTÎøpžnXmˆ%¥Oaõ"džVŠ\.ŠÊÎ" (æäØïb"¢€ ƌ蔹’–! ÜëB ,bò§LæÅ)u"4‚ iÊd Ä!¦ø¸òv Ãl!±ÌàªëŽ!²èá2èò&¼Â. ˆ·ëD¢*0‚ ã" ‚ B 寍ïD”â"§!ª°+‚!ñ˜óO!ŠÊä†î)ñî Æþ Ê®îþ¯g¸E, †ú"5dsÎ* Ò¸¿ÎqZ>ê•NÁ¶â³$#ž! +ŽŒ0ÎÅ#µ¨0ÔîÇÓ'#4c2—2§¾0ÕðàÎ3G Ì4yb ( G# m‹0ÃîàŽ3NàJKî3DP0˯`„¼3F:¶Ê3RÒæô0ÏÝ cvCÕ½bì€o¦?ÈF9ÓCÒáOø3H°þƒ4% #@`â€Ò$h‡8!þ?#ü'ü)Ãü3,CÏò[ä=1Bàú¦JCü:DfÆQ†¯hÄJs—jJf˜Fiá¦Mä¬!„f,¤¢g¤`FcÐá&zΰjJÄbê"Í¢º¥æg¬î·¤ò'D¬T„ò&©&ÎLòÍÐpÐÉ8a÷Є÷ Ž5Å&F&•%RSƒÍ?åPl…8l…LAåL‰)uAÈUwNU!–ã…BBjLã BC` ChXäÒXâ¦Xé¦S¢'Â5Å¢¥¬#¥¬F *Y t„„#†4o©ÜÚåÒ<ÉèD îG)òIáÂí®#ŒM¤@Þb: Ã¡Cœgc…âìTÅD®²hbâVdT žUœ ø0—ä+¡¦yÉòF¡á9Ê^Á ÜB2â 7º¡ÿ'Aþ-€J’iþ>§&!²KQ‡¢!®½yK"¤@ ÀÀãB è²&F8’—Xb 1Â@’²ëo4!£®ë †ÅN Ê£)Áþ ‚ ®fà·jĹ¢!_ö"]Qó!£8íb i𭮇Z8G‚!„¡ÿ"ÑíÁÿ(8}*>zUQY5©o‚pcâW{®Œîc QÕ UÊ¡‹¢ À'¼½' †!þ¬Ã "/‡£5Sò†Â ݈ ™a.Ø0ÒqHC3J"°c4ó£R€¹ !ƒ òtô0Ö>Ã\@ã4â !c ò 5“˜Â¬3D(~äV3V{Ãè@£4÷C–ä<Åï+ä 3FÈ?Ø0Õec£ü?# zèR3HÚ?Ó A Å Hzàd@` xdn ä<7£üŒ¸"CÂ.?¶?Ïăü6„f-„j%p+6Ð ?ÖØ™¤fD“8Êä¦^–ÈJpOè¼Jb>JÃŒÊÌÊJÈ“mjf¦@üÛÔ_<÷Xg¢ÊO#Ì̤òFòAäòM$ò‰$òaÅELøaä¤PbeѪdRbØQ¥PR¯¤ÑÅ86…8+eL(…8DLIåL6…V-…V=VDœo¡B™¡lâ|V‚tXB§ DXBjX÷nƒ˜!e˜"B>e¢8Ŭ@…¬¢%²c¡£o­¶8Íøl†6MêV‰%Òi…Ò8EÜ&%ä#¥h6‰Ò>a Ð­æ& QMÄ_ X8¦Q2)†Q zo¡Éœtƒ1^žâ[vW~:ߊæF¢+¡ŒEì ÀÄäŽyWþ"P!®¸," .Œx ÙI^Õ'•¸"¢‰`»P"»hð qÂ$Aþ +Éâ(/a[ç®!µ` Ù8ñ–ä…)§„u¡ÿS"ä!¢ø¿£cXØ~ÔØV$‚!¹uÀ:Y¯.t"j Ëøì$®C¶µ‹{º{ªº0Â> ÎeU‘äáþÃðK7TQìõ—VÃ4÷äê" H}™J3C2" °O¤0Ê·¼Ûã(>"È"̼g&»”ù\Ã5QÇ3+¨3N¸;yyc @ÛØ"/5Áã4ÀvÁC5‘fUéµ£4…Opæl1/‚¬3HŠ„#ýdÏ>ãÚ¾æCÈ1Áþd=3 æCØô‹hXâ€?Ç@`»`†‡%`v„6‰2ÙÀ¦Cýœ¼?ÙÝ´ùòFoŸcüT„fÿ³m¤giäkžä§°k9úϦz%¤g¡0JÄöJÊ"Fd`JÃ\ª3;âëlJäO#hJÅ a-¼O"ìO#O#œPdjO$HPz ‰%RRRiB˜Å&Ð9ÆReHS‚x•…Q׬y ÅJ{Å9 „TÚKº‚ÊDŽ.˜M%h/PÔ'Ôš4XBÊXåHY—z)8Ú·D†xZÄH[$-‰àÛeéudž_Bä¥bÂj]"Êž‚žâø^BuJ#°¤Ò¦úÞj" ÆÈ`¢>2i°¢‘_~‰â„¡ìnF²f^ ÌIáÙHMôIúö+¡Ž`Òhƒ!®?¼œ²!¢V ºâBañø!¸ãŠÜõbõ"+‚ß&‚[8¯[â”! ˜" Ä:gç"T&¢µÿ$»Â¹ûè¢ _¦˜k#ÓXNAõúb+Yþ^®‚ Áaÿ`;;Ó"‚*¾AR±²Fí‡Æ"cµéκ4'ûÀê~ö­Ly£hËr3[o—1¬" ®z‹Z ÛvÀü½ k> Ö0Á1XNg´5ÂC'3B|³#4íRi½C4®.«2”0Õ ”4»ñˆnl#4ç¼Mï# X²¼‘/ü2¶ duK£ ”ºO½/C5øÂŒ0ÂV¼c ‹èb/K÷`=Æ"¢†ãü;ã ¢#ü‹ )\–3D—‚d<> g@¶9€m®`76aœÄÄà2Ñ%›Šˆ¸¤ìbNލ‰ZNv©€º˜§(‘/¯e»ò½ZªóÊ®‹ªé ¯`,KН¬OÄ•­ªrÄ‘­¨šÚ©-¬2ø¸¯—’ù 0Š’ø› ÁDÞEƒ¤¢$,º>ËÞL¿Î"mÐ¥m:2Ó¦Mb&Ö%ÍzŒÙ)p*6OóÉ,›l´à8ßBäÄ Ùÿi¹±ã¨‘¨™™ɱX¸K ?v<ˆ€X·jÞÍÙ7ÏöÖõÀº9æÈ…„áþ°ÿNC$Kšôr±PÃàB¨Pï"¼0¯C v«E ‰’Øÿd'xú¡UVw’Ê€DËïAáþŽªM;•U!„(…OÉÞ`èy&¼*)Þ蘤èVÁN;Ĺ –¼7Á;ÌAY"aH´’”SC ôï”*&IÞYJðïÕ½PÂÀ†Q¬4L-Á;É,ï³¼†ÎòQ;É|ƒEÔØÿIaHÞ…Þ†úgçzIÅ”0EÎó9;ÍÄï#%[ `¢QçxÆá<®‘Cú;Á UtÎñ0;ÁJ *Ùd?Ü9Þ¬I +ÅZ²˜ùÞ'jµµäö«ER˜£ýH©EuŒê­—gqt2#¼¨•j ù•.ü³¢*~17ËÛ9ð:ÀWÃÚÂ6°J˜ðP„lÍJ2ÁC•j÷• 5;)$¡ Ú%±ˆï=‰VÎàïï(ï2˜ï;U´^Ä,ÃûIÄ7ÍÊûÂ)B B ·(FY|²Ø˜8àážÜr¯ a9 ==‹Ð“ë–FÕF 8È+ˆ¢G4œ (¦p¢X«ˆªº ð¿9À·›L¹ð±:΋ ‹h¬N&‹¬‚K§ ù N`ú‰¨‚bñ ɰ/”¯ú¯¥Œ¸© ¸Œá à™ ¥8…å`Ÿ`’`‘ç†(š øuÖûÀËÀŠ@à‰Øà‰øäˆÙô•¨æŽX}ø‹„@éîi °å– ÈLªhPŒ¼À4nVèì¶À8Á! ¿³ìñFq¿! ±Ûå¢1 Œ6‘ÌyŽð‡X3@è”ÀÈ«é³0Ž®bi3@0©42UÁÂ&5ÂèÌlO¨ïD<¿À<¾}Æ,h?ñ h Áq¡V„á]Kã5OÄ5‡þ²ÛPPŽ»^¢qÖ•Z•h`¨Ñ]CÑ)Ð.ªˆK"5Á]%]¨„ŸV™µúŸëˆƒ'D¬ˆ1ˆ1—Ó2•õ¸€‘0€4© 5Óp Å‘|ä„Óôlc{Eð„Ž+M<ù«‰~̈ˆ‚`P–ÎЀH¥@ g'ˆ‰`çÇ(–È“Š —8s‘ dt/3’ `Ô€¯ʵ a b«‰uNŠðÆG ±aàÞ Ͷp¶ºÏ‹h— h¸‹hü‹àŸÈ0¿‹vׄ‹…Pø¸ð…¯ðâÒð pËŒ€ËèÎ pÎHÿ>!<Ö€ 8¤ `‡ `áÉ`cŽØç½È¬šÉÉ<ä)ñâˆ äŽ°æ‰øæ–˜JÔ8døÈ êW˜º\ŸÈ©pQ¯¼l¬K9/§C7A/¨£©‰¿Ïx7Ìi έpÀ÷7YÌ2<òz?‘2\¡Á0¨1à ôñXtìsëÁ åáŽöŽiÞ­•ó÷c¸ïe³n©ûŽõº³'JO© ‘‘TÅŠ%̾YaTÙêA’I ˆÉL[|0¤Œ™~»3&x½ þ_ë(+ü ÂA—l%™ ÂH‘|%' {BBJê„®a/ØHŽ@ÿ"BX–ì$ #ÊÞp–Ì%ÿ+ÂZ𑬬5 hÂ\°Ü$³+RÂ[ð‘,®  JßÓ)Zþ•˜%kZt¬ `ÊÆ±d%c+{ÊÉ·L%Ç+VebiXžVÜ•…¡,éXNV>»@°@7ûZû+^ð2¶EˆˆŽÀ¦p&^Mÿeb¼Õ¶OÄJ @¼Ð»4ñÈf‚ºÐêVÞÍGqL˜“ŒògMØ ¨ÕÉ‚¶€Gý·ÍUy\Ó„È}fƒ7ýÐäSù¾@G±\ä;.Cï±Î߀¯ýÂoà?¿úGþïß\÷õ}ç8÷¦ïx/¡P2vç\ ÜAKôÁAGÀARo@ 9þžÁJ¼8vã¡+ãvéÜ8w€Qݽ±’z§q”cEÑ´ àP'qònxñ‰JºåIþÔÇùøo˜¢2ª¸Ÿì´”KHˆÅÓ ¸Ÿð,Ì‚úæŸèìÜ…ÍÀð|Ÿê¹©åœÞ§ú??„ .Ÿ4!þm€ÉþõQØ6¯ãæcŸé‰FÊTéPHù™å(˜Ÿæ‚r!3 ŒHK«V”k’óU®º ¬5h‚¿¡&Ó̇(K#Vª(!"e‚H¡&‘V¯È0z„œÖ ƃâ±Õ©z W(M«c!%º!hŸêJ 9¡%åÏuMæƒ/H5 ƒ2(0;`®¨2žƒHIŒ„ˆ0>„¯ˆ0`‡hIˆ„ßô¸A`ì‹À„ƒ ªÚÙþdÖˆ0„«È2Hƒ"h5TƒˆMÝ|"WJ • AJx&MŽƒ ÈI¤„µè€ƒ/3ˆƒJ(0Z•¦h5®ƒQH4è&¨2Àƒ',ꔄ´GþŠƒPè2Òjçþ²å(2Š.;BV  ÅòW ÂRWµ¹ˆv(J® x2Vé Wšxk ]™Á%lò‚ N‚ %¥lq%zŠ£ B2V^¥qA G+4,%eÂV…ô)\ Ä ZʬÕ­3RŠбÉþwé_ŒÄ'ìBnÄ<Ü4½1£4”1“&ª ‰¨€c›ªˆ>XÏ9µ>Í7nEŽÄ@+5„¼.Â"Ä(îFRä).Bfä{!Uòrøó; <÷°(Ù"§!yžöR{ËiïsǼóôè‚’ïJ(* ¢´*?ʪ e(~¬tzáIANí%8IámC‹õ34TNÑQ$EHQ1ôT´@JÉC|uѳ GÉDy@ )˜¨€ã¬‘T¦UÒªWJ‹¬%£P—@a.d- &eú™kB‰¬˜¦âv›ŠJZ/Â`ù‰¡þm1(Oå $¥Œ@Ä{QcüÏ¡þs¡C€ÄD÷<8º‘`h b «Z‰(*´æah¯•iª Æ VŒò‹™ÊÁ ¤%µ”ÕZψ1ž Æ©V˜&PBT­d$¡Êu‚fH3Ø À‘`†å|A…jÁ&òl„–r o•¹ D%qòΫMy`¤fb"A‘Š­!dÀiž?Ì$žX3¤2óæA€ UäÝa73ˆL¶òtºâ (e‚ê-#è­Q,Ãò§N£ü—ªÒ¢Ué Zcýt4¢»ùÕ ÍM’¯I€BOLàÑ9´BY™kªhƒM!þHHˆ%n`ÏR ‰ d¬”`š³ÉY Ã4„¹¢Iˆ2¸XD¬˜¯¢å‡û+î(•¢ RHAFä ‰rB%Ù ¤¬¢c2@Œ!dÎ E¼ X¤‘ U½&Ž?̽„%k 1òh T´‹·>ÔŒÒýi­¯ò‚@Qˆg„W¢¢@ŒUw5d¬˜”f¬`ÿB† Ð<2Vj ¹š{ÉlÍ S4 A¬`(0³2q@ ƒ4\NC31$»³ë EÌ°Ç æ‚r ™ÈZç œ‡ä?Ù™È}ãýUƒv3iH 4 $Øvaïa°hìSÞnü# ‡¼¡žò*‚¯åè„dÍA¹Èê Zèp‚!¤Gaá7Cˆ48`ã)EDu TA" Hž¨Ø¶£bHÚ65èøŠY*)ÇùqƆxsó^•YšS=IU%Rv–“¢Zwii &<™ˆªfa)˜™¦³XšÕPÁi¸• :†5!k§ùêŸÉR…!깨ģª‘**0…‰(,ú"¡gn«]¹awÍVª†Ì°[}+ ËÍV±:^NUm2<Ó¡`ÑêfE– e ÖHƒ¥[¡Li/Ê´‘`ÏÕh4p„&bõú«Bé i£ýªó2«Zxÿa¤5“P«D1'ªd$ÙTÕƒS¦¾™! ñXM…‚¯H0ž!,?A²åÈBu½0>ˤ1bz;Gøc©¶ñ3Gí! Äí™öBtÀÿoœ„»² MZëí(R2 «e+•D«b[§ˆKžfÄÅõA‹muWõ$•Òr h5F· f°ÍŽB[øÿä%àó|AˆùuþågH@¦ûÅ!5ñÓeŽ@’ ®mŸ-L@´°ÿ#3×P.?±ˆ½ HŠh"†@3ШD­ˆ'°Ø3ú´=Bm+Ù+u•˜•°^ªJì¸ U(—Ë´Jí×:3DìÃv4ì‡ûÍä6ήN\ÌBý1Óº;éšEı˜‹^?Ê)ˆ † åµzCaŒÅ0*m B.9 öœ‚®bÛï¾O}ßLHñ D zz.=äD÷›´"§ª gÇ¼Ö ¯•nT>hq úì' wÌ5ÂeÅôLŒ¡æ×EK/à º6PèÙ#b>Øøº !H¨µÇ*œJbJiêJ¤(J¥TKBJ¢üL"KD\LÄL$€ÉÀMb*MdMÄ\ÊÆ½‚¢jrÂâŽOãXOæR"¢P¢*¥€Qƒ ‘BfR†xän!T¡¢ …ZRX.JîêzU­^¸%Zo†Õ‚1I ä…‚ÔÇE‚ã-¬“ì Â~ ØU­¼ Ææ¢‚å$nŸo!%f ǨU©òí í"!eZnÁþ‚¸" i%X"z Àä ¢ l£X-c”b qÐÄâ¸W‚0!! Ôâ ãÍ’tqÄñ‚5‚ ~ Et_‚VM| @®%dc¢VuQ’!"z M¼ A„V‚¡ÿAþ1¢ìÁþí¡þØ1\n¢V*ª\%nñbÐz§p%f J J† K”1 ìO¢e#,b•B6Ò&íÃI*11þã/®ç0ã’3Et1b1€1¿C&%z{䀀œµ`ø‰(3Bü91Ñ'C(kÀ;Ì9ÌŠC‘+):€,êò(‹ ?c°*ãÞ½*:@Ä =âz?¤ $‹ö„b’=âAH2çXAL¤/ÈDC‚âAHlúŒ¶CƒÌû &7TCd~ü„pFCXĤl „l3Äl5„lF$|@ª'¤˜<ÒÖ{ÄËĦcä¦H „ª5„ªDD´cä´7dÂ*äÃæLªLÄ MhæÄÜBÐFp>9'@) ó =I#å .¥ :/…%"0A¤`°TÍ_ @­-`]F Ç\U®jêèÅZN† !*\ ¦“èU¦bñ¶.%[“æå¼áBÆnU¥ú ÑŸ¥‚`áþ î !)êU¦"œE ÍU Ð!!ÕÅÔ”!ÿ« ê|X*T£†× 鿝¥Z£‚s ¢ßþh-òkÅ‚$†,Pa˜Û ˆ³á b´iC ÀÈ!!@' ú%&U îÞì!0¸åœj”˜ Nâpb oKáHô> ËJËÓð!1è°ÔÆ3âßâ!'Œ D ÊBë! œ!!(%iÆ?"¯¥«]â„!1À–’¶b#¬Â,âBÉ/bÙÔêîVOB™ ´b%b/RÇw¢VPâhr ¦âVëCæ @¢%o„N˜3B> U6ÇQŽ3A!¢Eø"@ãá'–%‚l3K §ã.§"ƒíSÐ1 xËc^rª3R}¢ü`“'€âJ F `DC<ÿYfÜõƒ4XïD;úõO ;|*ò =䀨Kænê@ع¤ ?Ó@Ã<9è€HFPëú=ã<=æ>AFÀ„ UDù©.ABC…AHTâP…¬&a¯¼D,&PäT_¬FÂcªFÄED¢EC^FÂfFÄ£eèBÊ9TþòÖ*á¾âHJd)5Å6a¤ª‹– KCÔKHêËdÂ:¤Â(èú7MU„Mdá"f,<Á$æƃw:Y:žOãÌP¥úP£®¢âQ‡<AZ‘T®Ý)9ƒ<ðÜ—¡ÿ%•"*U¢2 ÀŠ[…ZÊ* Â2œÓêÚ…ƒFtøsÅZžCpž…ƒu]Nb,Z§P‚ ÂzU°ò K#r%[ÌO®(‚ß ðá± …ƒpÁþæÅI‰§uô.U°ë ’X#vd‚¢ o´aÿ@íÊ*q4 ÑQKi…F0š­BAAþâ– 3Í Õ)L„B sgz§2b^!0ØêÔHîzg³I¢ ãâÒM:æ¶íz Wf"¢ •ð‘Tb aÿqFÁ` ^m!þ¨b UŒ ÂëQÆ€%p–çÂVÝáþ°!þ âW Y€BÃ$BWV¿s5L1Ò;MâV¯áþ`bôñW³qŠçƒ%jÖ¡5S#"V{aÿUb—€‚¤3R4õl&o R4e.¤3XZD1È%C$q 1y‹/F}#¶ˆ1Ô9ÍB`»& ÚD@ut¶¯;  BƒóÒÌ1ûl#°%F#gÃa¶ðe/r.$ìºÈ&Œž¤bÄ !ãß/ˆD=â;.Fƒµocd 0“2Ä5è^Âd2ì11ÑÂb*CˆX¾d85T*¤T‡Rt‡¤dŵnňýùNЀgî†f®JdJfJlvþäªÇò&KFKC˜L'vL# ŒÖ®fdÖPdÖHÖ$„Ü@:ÖÀ¡bëb`:XOââ'w ¤€a^ ß%[<í4@â ÷Rá.!'XU£P–î@X-ð¥Z`1n ÉTÖ‚HZ[!þÙþ¥âË=¢~—ôÚ šU°¼láþ©–X.,¢Â É®U®M+4!&>U±LŸzT Ѽ-¥ZÏàÎ!1}®!+VU·ÕCš"ÙWªU£E[{ôÜ Ñƒ…ªâ 5‚ ÞPÚãb š˜z\b «í¯¬Q>‚  UQzþæê¤ ÅÁ«'êψ!Â…ö†!4¿¡êäñ~„€±¢Ê>%f‡  †ºf&¦ä!7ÂyúÜbøf¬¡ÿKµcƒ•R àéBk( @Ã|«H%ceáþçq`%q}N8Œ JK@¢ç'Mj»·ú5·Â+‚P@ TàâšgbV(ã†ç åW L1 2{)û*#5ºž}Ŷøò3Qü1Ä1¼5U˜µC4wxÀ:`@ÔÀ µ¸ bb`&h²Æíc‘ˆ8ÿ=‘ޱ‹XC°;™},aÞH),h"#.9.;=ã;ä ÁáþùùUÂd %ÞF$ùfAB«aèFD\@„cÄADNFäEÄZ„oÄ·FG°†deÅ‚>‡ddB„luÒ‰ÄFÃÌFÛLbáXLàL¶-òGÂÚJe®Jb¸J¢>J¢*J¢nJ¥ŽKBzL"†L)êL$LÜÉDÖN„Ö3ÄÜurŠDò!äŒ^`&Fäþ/„þ#©5¨-eL—JW>îD!9øß U±WI¡¨â™ZˆU¡3Lâ·sMILº¤ Âç¢pðgý•B  VX"6iÝ$U²Õô*åZç­àò&U¢¸ ÝH‚ £*¯b-àa™Š$Æ- ‡Y²aÿ‘ äÂ:]¦.¥[T ç]±ˆ­ëÛñv¥‘¬ ݳÖaÿ²J0!"ðmF$ZÑÍ ±™|¨÷ÍC"VÒTàXbzíRtZ»KÂ&Mb´aþ-q(%zGFí¤ ]a¦‚Pâb N~Ý×Î%wjߢãþxEkn BšÞCUýø[޳V¯‹Vu80yt XZ0B28f2Ã4A‡f Db M1)O¢”c .NZ£ìS,1<푸¢3^vFc½®\yƒ4dÃ+’‚z#5ºò3R„;ÌE†€Üž  o2Âb|û¶9»Ã4÷ØÉk@£Aˆ‹•Uú5á­MÃÞõ¢Žƒ±’£P=þø¾¨’=ã˜=ìd2ð@Ä(AV$Ëcßó“ÐAC«ó¬&5 d[ b¤89„8† EDC“'¤TÃß`bäTgÄl9–j‰úÚáZãYÉf>d(´’¤|5„¦EĪ:䦌p@ÈÂ>d´@¤Ã7dnL#¤LÈÞFdÖ:ódmãÕñ:“:;:dQž Ðâðü–¥ƒƒìþVÅ$¤B´€øö ÿ€ MXHRÿgÂ]P˜d_ 0ÂXÑ\%ÿ ÄD–\&3DYPPnɈ»bÐ’ä$iDB]X4–(„‡¡-8K"#„Ša,HH®+G`¨K ñœBH‘”vB@ óüÊD¿ç(ûÌÿSÄaa58„¤!/XL– ¨ÂWð— $C ¥A„•´%Í"„à Ò—új÷¿ÂG€ýá XÂ@Y(1v“„¹óÏð<$± ÐÁ˜ð›|u Â_t]hÂ-ƒµ¸üŽ ªÖæ Ã(O;>¢¬ëH—¦´! wë@p˜&ÿ&ëT<ù}ŸëC˜íkóZW„¶u´løÏZÅÅu5ªÍh ÿµ SZ#5¤ëZ5¬K>{5¢[Zå3à#¸ì7íkFŸêc>“¼à2}9mké ¢ ø%ŸàëZfÅ) >íÃ!sZ…Ã0l2™C)>îÃ/\2ÃÃ-d2Å-Ü2 E(¬2p!þCà83ŠKÐ4Æ!Á£€\œ¤2{Û °RyÇ0H-tÀÆÉò,žž’‡ùäçü}ŸòLžÝÉí œ“C@=tP ôžÈИ ¨”uŸ¥H4´€-JÀ |ÓçùÓQ,´„¨Ÿôõ ÍU5%RÒÕ(…RÝÕ+õR±¸]I5Ó_]D5Òz¤ ‹$ذS•ÇùÜûziŸè€U]§mTvéûnÊ€aÿD§ûáq°÷5ÀìMÛݬÐÉ·¢Bï]òâÇüGæð]L '}¡ÿ"š¥ d°(Š˜ƒ(Èô»!(Z. Çš#D æ4ˆ“LÐ@ ®H†¡"Š(ˆ§¨6B™ÈŠüƒeGûP9È1„àh4&(NiK Nª S!)†fˆ¤è3˜Áè4g‹¸(M,ƒ;¨0”ˆ‰èI“¡:ñþ¢.Ê œ Äúr¡!ÚO L9Æ‹`Mc‡úd7¨60Ü0~„¨H1®„ðJ¢4üj¸ É * ÛΠς µ» ŽŸåò :Ú Ê¡þ¡"[¸ Í* › šR¡*³>ˆbH1p—A¯º¸„­mC¡¡#’‡3êB µ¼Éÿæ[,ø&«µ®º Ù³àºWµ¼ÿ—³ý©ÿ3î" Y5¨c>› É£>Ú³ûš ¸3ðØÿ$%·™óàgÈAŸT‰ï‘˜kLéŸD0AÒœñÌùe3è Ï›Ô2‡GùÕ3ë@ðÓ †_hÿBf}ꞤR~ŒùÙC&D϶2OLù4C#pÖ’´2õPɯ3é©­dRÑJEC#Y¢2TŠ)Bi1­J“€±Dax!ðÊaÀ "(ÈdÍ$óº˜â*`I¸¤÷b“ÌHíè ;òz*GûŒIïŽ<©ÔÀXÔ=Iè @ÕCtP 5Ø)D¨  cò%Q;`”ÝR ÑHÕ ”UJœR•Tª šK±U/].RoUÓq”êò8Ë$&±Kòº"«ݬTP®˜°\ëDšÁž¶VÃÜ[gum¢¶ –Ù \oqšõÌu×q]¨sEèk×iÛ^Å|©åòIPÊžÃüЉØè”(X[òBÎÈI4 H´ƒO§ D]‰¤EÖ÷Áˆ•æ45A B\|³ ÁÔÛ(B^ÊQh¥ôÞÆüJ( Láš’èHs!"脊Ò"åÒ ?`ˆ¤–ÜB\ûh",}ÜÈ|ÈKD4%ܬb Œ™ ¤D‰bë"Èy•†L!RDJÁ£þ˜­Â gH0’4…lƒ'B rùaï­Ÿó·Lˆ2h Ðèƒc¦OÈM Ë@ƒ4jÆBkàÿЄƒsZäGøÚ!.•¸røÌø™¡Æè„‡¢,Ík¥5äùaºkTo!(ÏЊÿ ë=>8f´4‘oeÈI3ä,ƒ“?H‹¹Ÿ1õ`Ö…ãDkFÁ­!ÄÖÖb gÚmµ5¡0ÌšØmBP¹ v&~ÞòeÍjh‚æ´/šÑxka•DOÐÖ³k²gâSÀE0ŸgØkIj½P¥="—Êgʲn&|®¡šKŒC6ÏšT2‘Àaæ•÷"“†Hb6±5œD2›gê!È¥@ Ê` ø+àbVL'â¡þ€â’OZ <ˆ !þICš»üm¦  ÜDP•'·˜*€" ¨ {PrB”ˆÊA¨h¤º€zªA"©ठ4*Aꪓ‰%À©&Š¤íªœÆ?Õ«–L}]%õe,¢2Å> éK,UH±^ªÅv"Êx-#®3[l%¶YVÙ×[j‘q¢&\É}s5Ì‘WjT^„1zèhWà_%RÞÔåŽÆ°¸-dÑ!CÎy>„o‘tq.nº—ªA›Iq•t„ ÒWÇù–bÃþ4Ô¶@ƒk¼¥; ƒ<þnH¿ ȃ@Û„@ªðÿjU¤ˆ¾2  ãä2h½Â )3PƒoAþh™bƒüKÑ÷A† Gü'‡œ810ä&bÊA‚É ßljo*ÖlH5 ÜG‡0’ ÈHŒ!ÀÖ¬A ‚A˜üšÉÆ ø˜ÉÉîȱʘ֟ ‰$I!Æ«“­$[ä<™'x€jsš-€ 3Êà¡ “A'ÉãÒ?i0¸u‡øÍªö…h…ì’x±’yR#1@ )'¿Âv’y$Jé@2ºu¡‚BúLL JAL•˜@4N/jO•e•ÙT£IT”òT¥‘%Y é]é]©_–9n,ݘ1‚‰„bÃél©lIl¡m”ñmém›‰qˆaqiqsisAvˆavYvˆYz ñ|’i|‹(lØO»^:ÐHƒ.Ü8ú¼ø§É4Zϊ׫)Pƒ !”ˆLGŒÐ6à< 0ˆ¹€ƒá5ˆÂŸÄ¹–øÑˆ4I͈§áì‚’’ª²(²Áˆ0(6ÃqˆŒù*Ò°ˆ1N0Þà „ÇÓ‘Ž~€OøÎƒ%ˆ2܇ýŸ:¦¬¢¾ˆ0JÄ$.(êˆI‘œ°²Jà¸P„„:{ÑŸÙªˆHED;}QàƒJxƒÜašèøˆI(ˆ0O`„¬XÒHÐ8µ¨Ïœ0ñRÙ™ùŒý;°„žº™£±øƒ0nˆHEXÏʼnÅ2-ŸS_½¼3 l’°HÖƒ0„Óð'áÿŠÓÖˆ0õŒùÓˆ2ü‡ø•ÇÌšº¼5T¸Ï¸¹Åh‰Â h½;(ÖÏxÏŽž:*Œû« øœ®£ÊÖŽú©Ê4»àÖ¯:öÊQ‹ FðÖÃ**¾E?‘L•øëÊé ü´×!ûÙ%œ±!ùÊl>ÊR%“%Öùxムç‚ùü»Ç±0!ô†LE‰pŠÐmá'¾Êö”/“ó”¢=Ù@üÎ#aJZB”£&’ùH!@ã)¡”R2ÑQ%ƒ€¿@ Q"1T‘DÚ3<ÀŠXÙ¢Ys¥‘/•Ô%™e@Üà›ˆ^Æ„̓ÁP–ÀÈ–Â#Ù"¦In”±q”î4´¾mù—lð³pjn/iz¨€€€6¢×øþÖïÐ a¯ñäM©]DÀ1dMéiD!0bäLS]Ä×ò(œ> .ˆ=¢c›ž Ɖ‹âoƒF'#‘¢¸šÂU?ˆ¢c8˜^!Nƒ(âoÈœJꉴâe(˜ k4ˆ0Æ h‰§bl«#ü&1@¥þë8Ÿê(â ;‰¸¢È1j& ‰Ç`Îë›|Äßq7dM«D˜¦Z&‰‘âmè›–&ÚŸâÜüMåƒ6"dø›n&‰¹§q<ÞªWDña¼MQj_ù¸6f ›r­ðcdM…fò€±2Þו‚ƒM Ä.Tâ :Õ"kkï+q2ò•‘6ï(•^ò¦`Ç)ž‰œnSЄnÔy¹@“rû;îR؃#­R>ÕîS@ÕȘå.QôåNQpå5íRˆÕA P&å=Qüå"@þ„µ@Ûäå3-S_NQ³ÆJSTÉÆAë”Ò5Iädv€”.Ä1“Õ7Q’?=Q’+ÍRÙ’iþLRÉþ|LH¼e€‡üm“Á Û«ÐP$àÊΛþÍ´Û4M³Œ6 €qþí'ù®§ü>ŸóÔÇ;RÔâmLCókûL4áîS Å0ͱ]1S ˜ ²´Ã_L7ÄÃY£ušyL fÜVk}fªçúyY±–LCY “Ù0E’¬YÀv‘ÿÛg­´¬VÚœŸêU¶ª]ù‚Ø$ñþÜÔxt@£à]É}ïíýnßÈMý`‡ü™„Å`iÿ†Ûà¬aÖMçúœl—Àôg"g Ê Îê ¡L!þf"‰Ä(RhƒQˆ5¢…(Ò!™Ÿé r"Ê 5"sŠè Ϫ —ŸàËx‰¬P~‰•(Ä…"H1–š¢q²ê Ð W"BÚþ䨀‰’N‹ø‰Ç¨QЉŠh›ÌìÈSƒ:è2ü°Ãéþ³ØŠD¢rf–¦¢cÂ&\¢q…H˜V‰‡™‰¡ˆ0B‰Â°‚&[¢fç@‰óüò&ÿ Èº Рܪ "eš' uè˜N‰†È™ÉuSDƒ!3óÅ Á*&00îQ¾‰Ú(0Ó5]qþ¬m(1“ 4ºz U9T Ë ÎÛUÛqmP ‰¦]k•’íUI Ñ´(‰“îW:‡.SÔA‹aªFƒüä²s”ò 1¾9@PåbZr‹ªI†¨ñ?•ÆÊ8¦¨”š§”jœÉªrª§·ŽQÁ5BÐå!þ1R=5@(åddš Q¦5A 1%5¸rˆÊ2…Èíþ¡Ž˜ˆyª+HÈ$œ£"Œú2-1&Dd›×‚bŠhÊ#"Þ““Jèý”d£Jb+ÈÁ&Ô6À2€!Ý€0Ì·@ Bk` <øÜPÿÁÈÃAb¿ÓiXM¤m6£dÛ jÁS Õ6€eP›”âaUr\Ý&Ôf¦ ˜Z*Íq)†Ì¦b˜BªÍµ¬y8°ˆ\°)Ò²X,†ñ, ÿQ‹&,’²MÒÉ–Å9m­¦¸×(ÿTë¡8­²¼º˜Äæ½y.!u.˜Ñ_eQ}˜Åö¿Zh_ËEÆM˜I‘a(…‡¦dXrubä0lŒAŠñ )dµ¶pûƒäa䀈8¡þQÑ'Ä^PR&ÐYAD§fÖB…“E¢DN)bÀÛÈPw4äLS˜6tyÈïô ­fæB‰Ñ¢l¬ˆ² é5ä)–S¢ÚÑ)ÿdM<‡RÀ×ç¨ó&B„©|Jd‰Œ‚ ÍGù´ Ðf™8ŽA—‰®äƒ#ò vHUaJN òRÖš±’ÄB‘22FÞÙ#ä0`öèÈyïµbâüì "aQîdg›N5N¥…:féˆ1 ÇÌÕr ŠÝQ±9Þ8xj„µDk§("7žA†qʳCü`ѧîA•)ªg$ š ÃBq·9UÌÉk:DÊÁªnf©n`¼rŠÑª5 šª¬j‹1ªg”dÕ"UdÁª¤㚣"jœ¹ª\Fª ùí!IÊT樘§HÓ 5It˜TÙ!"b'Æ©#_´ÄMS"FVä»Dd™ RƒS¨¹1^šœ˜’¸ÿ'ÈÉÏàó”©Q”6í¦"œŒ–î!S…‰CDe‰ê¢mÄF™ §`%€ WB  1*^ÐÚ²`8÷>7ÇùŒM¥6—„Ú˜SkNS ­6“ÄÚTÄéÅL!µ%ɲmZ*a§+3·&ÔÁXÊrÂPõò¬É’³NªÎ+5Ÿ›¥‘˜ÂK,–œ²NÚÕ[Åád¯•¶ˆfrÞ2+l›.‰,¶ÑZèmcˆ¯&Ì-ØŠè)Ëí ¯³"¾Û2þ_+ù\YÄ?çPÿ@,%|°åÃŽKMhar ?Ó© ±„Ý2šâB¨Zgz@Öb¬?ëèÿj¤±­ŠŒî 2$„ô:A§±%;KaÒ‚†È3V/­ƒ±U€å@Qþm¹ÉÊ,Ķš«Rˆ0k9MôÝ-¶ŽS¦«½ÐÓT /cÎ9KDÕ[SU ·ú2Ep™&$ j¢L…LW¼ÁñþóâbbN·©1$‰˜”b2*†«d”ÄÓ‘’ FKEtdC0ò2Ç{ :a„Ħ¾€ÿOüÓ&؈ž(*I¡€Ü@µ"€â“ŒEHÉe¾ˆSi2M­HÉsúM¯ÚÚ0I‰’âM¬Ú!%0V¡þÉŽ|–I/K+i`L…0!åfEéH–ðVeJVdÈÌÉ`'…’lÅ’…f!å’#e’Tå¶4Å’Ee¶L…¶#eÂ\bð[b”]JAþmeä&AjÄeÆL…ö!åðÔåN_ct_ÄÈ_ÄÔ@a%Äa#ta%ºaÄâaˆ¦> ÊF!N§Â¦cö.â x¡þjf¤êB|!PÔi…J¥ )²V8Fv,"&Üm  À̲" êraÿaþà)°!JT¦*¢ lAþ6B  Üë^ïŠÊ%‚ L‚ smö8Ñ8SnÒ ÈÊ–˜šjH{Ñ5çv!Bãcbt¢Úê­Ì"aH"•áþt!þ¯â ƒʰG"kj±Ë„ ÀÚæã¬-ªTq ë Â6 Íž°áþl‘iÂÐ ÃLx‹\FÚ¸‚ÄÞ‡¸ ˦ãœÏ’-b'¢9Gpîè¿€»ÃT4‚ ~ üî`¢+èâÔMD5Qƒ#T{ŠKÃ9OÔ5B¤}/Â&GãT5ƒTßÃp5Fê„D:Oj Ë#¯Tõ#U#Aþ+’ 5Ce!RRàœ9KjFBx5DÂ5Kæèš5BpÅ”ŠcT<„d2opLH;ã”&DdF1&9B¨FOŒ8¤d_$dmdd;#TúЍŒ”LHöÞȪLDã(å8!ÐÄÅ(Ö–äÚH€ÿtý@ …¢ œ2 àƒP‰$ÚþAÚ©”Sƒ@M¢”V%<’åO0i.T¥@’é1%f)Å1ÍP’æÌ’Â>S fÙ `_%R–^Îż”oÄ–*Y"e%½IbY"ÀY"x\ÅÆZ%¶\ ÆFÁž] ¬/0o ö?¥ö†…ö!%öAü/ HÔâÞ_Äfa#*a#^aŠ-n5dFi„)("bâ!Dl Ä3pîéâ zÑÆé" ·ñØv¢ 7JŒsâwq:)"&¢&-â³ÍÒ"fÌ ÍÞæÀë¦r!QÓÇþï!?â&ƒè"€ÙëýB–âJ¼3¢ïêDþP (ââ ÑGyÝC@!QAáþy‚ é‚ ¹¯(â_@±l!J*ŒbÛ´cQjì‚ GÁþt‚ N1¾( Z Îóô” Ô£\tæ’"bˆ Ãw#Tv 0 Çв§T5G‡B&nq°"r~‡î<3¬"kïTè #Ò"gh Ã’5J3N£Ub 0K"Ô’½l¶²Ã”8õàÏAC”eSM‡Â9N éc”X#Tµ£TÀt‡CT?,5FÖ5D)#T(ÃTÁ‚h5Dfôƒ”…ƒT²Aþr£T#rº9KîçzJQÍ%ì.FHŠÏz9BB„dógúúdÄdCTlĸLOPèº_„ÄKéÂL”‹*FCêKE8Ki°FHˆN²®S…FCúFHý. L`r  d @È)@àÂ|@2äÚ!$ÚyDÚL„ÛTS‚¨M§>Ë%8”¯ÈS“LæÅt’ó ãtSVl¤÷E1clVlßE©.;efVPˆVvFœ%’’É\Y"ÄVd>Y#@Y$6˜EÇÌ.[fœ[m5¥¶lÅÖ¥Reä’ÉT'®^í…9f’ÅöEåü2¥öTæN%ü9&*¸àðcò+c"¦ÁÿKè!MÔ3"N*;7âÞqXÛâ&Ùè@â&…‚n­ž)W"e‚8‚ dÁþnãØ!C^·‚&&Sr*ª"AD :r" Õ-„!Q{o öéòî:àª"a 3Éñw2á!*ÈÀ ¡þò§¬Ù4x°‚h!WRï Ë¢«¢wâ Tâ ¢˜à¾"j† ÓÈ ¢&8±*ëÂ&Û1|äuR÷¢¢Úk"è Öêñû{Qpå !ѲÚÂ' &Ú¯B&mb Ž€«nR9JÇàåMä9W´~†4"hh5Q<ë2£TŸrh"a9JÔïï5F|âµJ®È"ooL 'TìÑ5MÊktáU"aþ<‚ ñ¥”9O Èp–#T«5Eò5F‰‚C•OrRgÔ}õ69L,ðcî5O—A#UX7$jLX ÜxDÄ/ (5H3)ä=ˆÄvÄjøC”(U¦LD^5KbFHëã”Å0ˆFU´ dd7¬„äLDÂFUæÏ¾Ê¤ÄêÖM¬@ãHɤÄT "N°sá ¥‚Z$/öSŒ©vLÄÅe8ÍMM8ÌøW¥0[¥0Q…09,–•åf“I°S ,“eg’Ìë€%x–ÄVs?,…f—mþVe­c%’-ódмM ö˜¥ÇTýå¶,A«4…äAA`íÁ10™j†Ö_hÓNÓén_öa&œ’mn$âyþzÃ"!Mî$¦d"d3níº9bcª¨!@È=¢ m‚Þ´„Ùå¦'Q!þ>¢ ã'|N0yb&?­à@Îx"„g˜j!þ¤®4Ü" æÔ$·Ò" ‹3«`áBÊþî@hÚÊø?" †‚yyÉ|£7œyå Æ£WzÔŠŸCFèJiN¢ +€à—zCápÔ:®€÷=B±ï nÍS" ÝFT?ø"m’¢:¬Ò. ÊJ5W–eMž·l&îeXÂ&i4÷CT ÷®nˆ"`¬"o‡\ y"#UoTæxøIÁþ èŒ"xxô²õY¯ˆZ"b¤ø‚ jl 7 5OFî{®zò9R¸ø[€Ä‚ò(9L ­cT-ãUä2†cô9DfFL-±¸´£•WÛLê2FD5UNãHFU%ŠXÙ>ØžFBˆ„šrLÅÄFXšJµŸè~Â$Ä+Ìk,"FE',,N9[©Y}Óƒ¯¿,ÄÅ)×úû2ÈFG*†äÅ»8ìSd°LC^M§MYžhMµØQ¤ˆN!È&œ€ÀC` C`’“2I’þ­c$Ú2< ¿Å02,d’ã&”8ÌsZSC3¶H’ù<–%f7P6SúVeºV|-jp6[)h˜åg6ôÀY%Y#’[irI…¶5å¶FŶ;u¶‹!?…aZ­aø^Å÷ÆÕÀ›¦iÅö›SZ¡˜ÂAb¢à!B¹¦âJ‘|@¢MPü8tz+±"@‚¢nQR ÏÕ?"r @¢ P‚t*v†¿§l*âÛ6Ûob&­áþ-”5AŽ^"÷ž¢ +Q˜§ƒaúb‚qÞ¢!ub AoŽ!_”⣠û:@ íÊ þo¿Ú0pDxðüÉdÁØpx!9Áßu$j•àâh:b냀`åH8‚ –ÁÀPs ÿYÁÝ“ˆ9þѳ`îø8¼Š îx;Vöƒ–`ìªkü#lAÉ0u I[ ÁÅtím÷ÁÉðtmÝ ÁÈõ·,³[Á×ð{=8=VÖ4*qŠâ­Ö ˜Zsª ¿Vá0HM8"VÞµ¼u8^­Ž+aÚÚâ)­´+ašÙN·c§? áÊ܆œ?­¬+o}Mmó[#oõul[}Vó´ámoÈî©Û q3­¼¿qým•:ïÉÁ¿ÙýgåméÖ´Ó€½n%ÖÕS°ü×%ÑÖr:ÏÉþ :Às¬¥9,s’ºÀÀð+’y¿Ðqþœ¹,,Ÿéq¤$4>¦É ("` ¾áѽg4*ˆAë<žÁï©§ûã®ñãÂqäc'0{ ÀxçLJí,xÙGŒ¦ÐÇü§&Jk<¦JGûŸ)¿²›q)Á 9þÃÍ®,¦½Í©È®óhNìÊNÍÄÚ»'üoïY?c¾Gø(P’eðGû)L-´ÄoÒš"øƒ½¨ˆ–ƒ˜5"¬‚9¨#`ˆÂh$˜ˆ­è œƒÆ(‰ZƒžU Và æ•IZê²¢*BŒÖh<˜‚-èˆ&ƒºh!‰Rh8\…TJР‚Ò Tˆºg í "ø ‚% æHå —yÿx “Ò"n âè*à€WŸç Hk æbá_8ÁR5H!‡ ÷Ͱ†U&¬h$Æ‚v‹ƒ¿è!‘R˜Ân`9 ƒã˜‚Èâú] ðnB¬¦(¶xƒäGúŒ‚ h9NƒØU­ˆƒŠ¨9>ƒ¯êtô‚0è&‚è8lƒ°¨ãž áâ! ä¶ð *¢YÊÚ2‚!h"â§Z)Á‚‚eŠsŽ‚È:ê§2È Ø­ÛYJ¶$ `r­é‡úT§X¨"¾§@h š×«f¾»¸«zò×)Å2¶œïî ¶ìêÒ„ Ú·1¶êÜ §:»â¶·©ÇJ·S)ÙÚœ«k*œá)È‚œ`+aó¬â©Á·âŸíÓ©Êê¹, É )×›ø­ NI¶­ï®H*ë!jqÀë®°$ë.ïì¾¹+k’øœ—Ø?ÒaÉ_è=`•LrK)É*È=òrS7Cë€à?߸íàä—pÉP H ’‚KêAä  ´h…I I£ýú ó:’Iˆð¥#¨je‘âG„Ádx^ÒœBëY,&CB”Ér˜‚5*Lˆ;K-ª@°‚X‚ `§C#K;cû ËÅ r‰…1ŠÛûˆ­³ù›;3Ä`ášh§@@‚ ȧ4#J rÉ´¸†7‚­Ä§@ȨЧx§½ åŠpž¹hÌ Ûq°§,Ø•ЧX§à§xˆÈÞÉÅŠÙËøúŠr¡äž§x§:ˆœ|]Ž´c‡ùçŠq’.`­•äÇz.ŽI¹²Ó Ùì‡ø‹ ­³»°ë§;È­hë ÛÂG`ë¨ä*±( @뫸‡øº‡h7>¨ÜŒ¯ëÖyHP ¨ (¡.¡p/P0 â{ÝYi<ê>‘áD)"°=Q Ò'‘âÿ½i)’«é“‰ )Œq/#ù1¾KŠ,is’™=i £#ê#±‚5¤Sê  u70QCpS·0wÈê?  p¨=²b€ƒ›éwpˆ¬y«ü@‹f‡üAŠ„L o‰¢Lˆ 3˜¸ˆ©ñf­ðˆÌ jü4û…ùV'¬?aRDÑ Èˆ›8‚|Ô˜éoÁ“z• ¨ MŠR*sû }CŽ8‡øš@·ÐŒHˆ¥°Ì }‡ûYŒsøˆ<À˜ÑÕË@ˆÎLO&¤V¦×¼8D(‚@T"Œ#?–ãÿÃÈ‚0‚?–ä"Npƒ„bš6HƒÀiøE@¸‚döÂЂO¸‚$”½8ÀügÆÚƒÂì!D!`2€­²{mµÂ—ˆ ©+`§6o¶tÚ pÀÀЫäOI±Šp°Ðä|‡ü¬Œb ÚhP­ÍP®Rˆ:G rx&Ø­Ñàòu r¦?#:ºM Ø­Ÿ ‚0š€§ø§)¹¯ r~Šp¨*h¦€µºÁä'H§8ë‚›P­ÒÐÜ tJüOFë-¬a9à§F(‹xä¬Àª¸–JŽè­ˆ€ä¶ø§;a„ŽHÊä—;¼ Ù®HhäÆ`T…¢èŽK¢BƒÈްªI·0䮘䉀äÓÜ©ûJîù …›hÎþ Œé‘ˆä¯½ /ˆ,иþ€ §ì‰z'/ÙÊb½i*’:ŠS ¡©Sá‘àž‘ààÊ™‚‘àΓI2=¬¥0¡)Šé6’ý8“!“iû>Y6¾T´i9°a6Šé; ;Xv«¶Ÿ°S1Õy‰èp†¸;¿b„Pˆ¥C;¬³…Š©R2â›%R ˜\ '‰RLè³3ؘՆXsŠˆ#—22_NÊˆŠ ÀŽk>;§ ½ˆŠ§Ü̸ƒÅ‚ÄsX èˆØ˜‚ ø65 KÇñR•‹¹)z#gÅ‚N3ùzÂz |oC'ªªŠ(ʬٲ.ˆŠ¹Y˜Ï8J©‘È× *.š½Šø€ ž` šæ {©‘á÷çv× $¡¯x°Y=œ¡ t¯!¬ª‰É)ʆ ’™,â,¥±#ãMo± ³“hð>uu>£âU@{. qà²b„‡üL³  =ô0ˆîÔæPüÜä½¢·Øˆ‚ÝÀˆˆ¯ærZ•#ŒŽšaš›l—udt!‘ˆŒÈˆ"Áˆ$ˆâÏæJÂ}Ж/Í Ñ0ƒŽx‚5\¶–ð0ˈÏñEñˆÑ]ɬi$Û$øƒîw/9cÃ`¶ã(ƒƒèƒªžwˆ=XˆÑÅЃúâQúˆý‚Fƒ tá:ïõ=ÑZ˜§9‡Eˆ °Šp«;"ÂЭ’`§Lèˆ9ŠtnŠ §iC°Z§g­€Ž8§ö£\¡zóЧ §u£²äÐõ'ˆü?Ú üK ð!þЇ¾âAxv$ý‡·âOhxN$‰!ì˜.$÷‰ ãð÷ ®$ ‰C¡1#ý½zD‚Q äl¹Àø‹ŧ2HKÌ9uÄŸ7ø&±"œƒ¢NJþ±4 Eu2Èf¦TªD-ºÃª±^¿ÃˆÕÓXw.¡[óüào·[kþuà@à3þňÈ?ñ¹mÕÿ•dhÙø•4O ­ïE"Ñ4Ïù6ŠX¢ëçî9Þmþ_âšÿQ¾ðf›æõÿ"¢;yM~ û•¼ß8#ÞRÏ‚ÄåF(–}ó³”ÖàáwÇV–ˆºå3x9½ô‹|-à½yCþSƒÐùò®J#øÍ¹B“‚9E[””(Š|Ÿ·Á{”ŸÍø!ŸéQ¤—RL¢®Q°å(j `å= ñ8å;ôFË9A£”—7Æ+‚ä·Ìk|¹G”ÃŽÛ”9Hó|m9Bƒ”é(‡Ó”n¹Kƒ|ˆ·ÃÔ°7Æ3”nDNPŽå@Ê!G,ËmðNå îQ&Ìgø>åNQ5EŽP\å ®Q.‡§s›|+:nT6ßOjË”4LMò‚ȇø¾åîT ߈xC92NS°ß%H*(ßKQºC7Å«”gËh(Êå9Íñ¤‡ª­ð‚‡ÆÇønå0)bå(x6å yQ!¡â»”^¡ñ‘þ ¡åRû7ÁÚ’7Ïr MŸðû|Í ³ò î ¦›”ë ²r à ³* L¹Jò  ¨² ‘ °Ú |¡ârñ ¬j GÝè{ð‚¾È*‚„Ùˆ*‚«H-*‚ªHI‘J!íB€Ÿïr× µ2 !¢Rf‰J*‰8¨Jª‚ÃèL˜„‚È•”„â‡ùЉ>ÈJ4„£J8„¦(JX„×¹Ðpàh4ñá†Ú©éò°'+¡§)úrÇ¡*Òrq« `·€ |à‚Û‰‘à'iËìºåéÎÓk¬ Xº®éÊhººL¢êû25êê•.ª#š®©ë"»²,{"Ͳ-G&ʃLªhÑŒ«PÇžM{xÑi ¤ÚWg¾ Gúb¢JGý ¢ŽQNå9*"ßRª"4ß#Ê%^ŒŽUì¢JÇýÀ¢kÍ÷r÷gý¥ç8*Ó|W¹I¢‰èÊúÁÜDЋ‚R9F˃ñó}9®PåzÍ÷‹ó¹T›|sznPø~€?ŸìDß ³”“ ð"8 ˜å)ÑþûMðâ8(ñ2¡œr‹ÙD€Æø4œ¡˜r†|§)2›àìo@˜9C--”E*ƒÎP29K¨ß-‡¤oQÁx0¸ßCþCñàçèß/ƒ|J ñ,7ÎÍœ¨joqD|‘å#C|ïaÙÊU§ô‚«8|ëÞXÿ>‡ å”,ŽSH7ÉÔß to…)‡ƒþ4ðHr„³Ä9L4†”øôO@Fú1S¨?ÅqÊ5"+¤þo–ðÿ ')\›æ^AQ¾iP¦°”Hc*æúGX' $ãÕ!ñ±â ` ð¶!å(ß9r çÈ*µ7ÌÔ‚Œƒ‡û'²Ì˜§ìABy dýTêAV1R1À‡¯Aÿ,( ¤,‚Ââ {*> £(‰+VCØŒ«!ðl‚¤‚Xˆ)‹$HµUzAYˆÿ|„ç“ =”²爄—2Cç©€!(„‚™¹ÖɈ"P8„Ï‘ÿB¦™4¤%š²‚$N"¨¬ì¼9òª;úN&åaJÒrrÐY¡x+^•7g¸V Ûm#@%Ç0 Ì+d|€5ârP˪½'&•¿„€‹©A.¥(º¤ÂêýŒÑ•p…$À¹³"׌‹î\ÈšS"EœI•3fˆµ hœÿ5Cü«š"Hh‰0ä °ÝKÃQ#Œ…{È4å<•.oŠQD8ø*œÄo…Jª8 ¡ðH®Íòµ(xå1‰ õ”«ÈX¢pV¾X&ùì¨$rœùD4¦ø>ÚÃñóãþ$4s”ËÆ£ò†ŒuùÀo‹í’¶Fø“D‚—Mòq7É:äâkôPG‘ÂÅ5jÏéD„/ å£}(Çù=7Ààà„c•.ô7Ë8žaþ™Íó›7Âtúœ«åz õ˜7ɼß*»ã c ÊY†ú_(p?Â,9I`ß`£”ÎP­°')×ÉQþïùÊ*VŒßLS}È(“9R›ár•!¾€À‡…C•|0øÿ…œ‡ÅÓä¡)ƒ½§û\(o„‰Êƒþ‡B%CÏq¾$„ó Å’y E>ù¥òŠˆ}Ô”$‡Æl¨AE¹ÊacýT[Ü?Ï$”!÷±Zù¼?Ø8ÿcCþVf1þ»³¡Èø4‚²‘þºú­ ª$« ®È)gÍD<¸U¡¢È|âøX„“B iH)w ¥¨„ÁÙCÑá ˜¤i²$–)+D%eV1nˆ)}!7 „:CÜý'!)”„ÑsjBYZ"Hø„”­ˆDiô¢QyJÃ^£̉@fàO »k%a—Ó¤U Å€‚9€@¨á»`Ç@ä]Záv0-X¯bêâ‡û}õ8ÕæâmK©42,¼º‘ejæv2¥¨º3deK‘‘)FDÀ*Ä?Òa¢&&´F¼êÂÁÃü^`r‰aD8ãüâÄS‚y ÷%(‘¬¢žpH;ð8ÈÇ3ø?ÏaDŠãýdbˆý8áÁø»qÿcMôPœßÓ‚‰Mô‘£ç«tw6Q#™¾€2U>?ùYD;Q0åD–r†‰Ê HìàÞmóNQ»Ç+³›äo–1¾ïÛßuÁÿº«(™O˜ãˆ{_Áò8£º›ëè?ìâÉåž:hx“” ÉãÃ)*-3”ðrmLÉTåT¶NPrIç(£{1ÿkÇønƒ]gÝ$" ˜¯¶ÔÁ(5«ðŽVl 9BÐåo˜Abÿœ9P:Ô¬Ó›W)ö„-äc•.4*v9V4‚¬„qKf¬e!áÇçäÏ;NQƒ ¯7M!¯ÜAQ8ÿ•Å8!ìDè‚B #”È¢ #ÀOC”sfB ­DMƒ”½B œ£Fcb$ îâ b[JD!åì ¤ï"ÓþHφ!çÚ!.ê ¢•Â@Í‚!éâå&ŠadQB$^!)¨6$%aþkGä!%v¡mŸ¢$7‚sj4!-l ê'ð+xª°iCªd%BIÂs Áþ-Br¦„."°I†è"â°§¡þ.Br'­â0`H °1  Bú€:D"êÛÃv01ç79Âêln¾.ªÉ ÂꘈN9CŠ ¯°ÏHˆëâ óhL ¢À  ˜ï‰œ]bW" ïP*µPg*-d!å¬Q¯!óÑ"\ :Ã|ÐIu4˜rÞ ª ®VÍÆ!ìHÆ ˜%¬·)""k$(b @Ó,ŸB â“i€ £\!2Ö ¢ à"$>P*Â$9ÅÎj ¯ âañ¸!0ÊðÒ~ÆX"DÚ+¢$,AU9`äÚÞâ½;"$sbr#Ш+l4pð+À'""!#'"•>â°~Âr#€”€…À´$À ìÂvª"°â.¦¤ñ"îB&.­õÑ>.§..ª2"24,qì2. â9D£^Wc"®ovÊÁ$udœ(‰\7ÂàuÄz8'.SÃÒ8+ü îr82ÄuçÔåzÄc‚–þëÂT(‚ƒÂ÷"!.£‚–Áþ¶þ‚tz}#”#Bˆæþ¹þ*HGæ81ËKLBøä tÔxñ¢ˆVr2rñŽÈ| kx­P1Ðà|îҰ7Ëß㔺ËÀ(‹²Bˆ¦»ÿ-"c”z/ZÀRE Qº7Ìnô޹!þï~7ѯTäÖWñ’8(t,DøB§Ø9A Ä×-Ò|áWdøóòb IXOúx/ ³£”ýuõB ¶9@ÌA#•HþÕÿ-ÅL’ÈïHP3(ˆ"  ²9RŽioN ²7þF…þ7ĺ ±Ï%n ¯¼éh‹Ì&!äóY¢ "q|Óã”ÕµWf:!ìòÿõí)b!ï„bôÝ5­úËÀ £µB bKIð”ïn ¬´ ¢å9Ì !éîäü!6I6!þk áÿ8rÂ"EØìÊú4"Mc©7â ­=]*5dÂa1!%&h$dó–!"z!"v!6 M¢0j"¡ðè& ®¾NöaþTÂr$Â9B0'*2è'-^Šª†+n­Â±?•"'0ã9br(Óö*`($€ Í´ 0âd´ ©bL.°ÖP‚ê*Bê(Âê0¢êYN 0"{rC*áGø©ã*^Ã<2´I C*âáþ%ƒ"/jÔÌî(’\W¯Mˆ³ÃÔðO¬–(…颉#4¨¼|sã|;ˆËC|db‰,‹FQÒ»kj8(Åb‰.o"nóHC|X‚‰QC} Q|µÒŠzîx9E3ÒÕb‚ˆÎ¤ïQ¥_oD(‚0¾ìfNƒƒ~H‘ï 8(»wñ |#•GAþð¡þ$Æòc| ƒ”Ryyáþ™ì½á>õc”ñWp³×tòðôC|÷ŒÖäõ¦ËÔ¢Íx=J%v(˜Pî4Ú7ÖYJ5M4/%EdT£”C|ƒ”ì°Š~®€7ÓXì4Ã(èMdaa|O®9T£cb f£|Ì®| ·ûFCµb @ƒ|ó§fþŒœvt7Ò& ©P&J7×’ö;¢-x¬ó$ËÖ1‹8‹:Ó/‰â=ƒ|#B!è& ¯dËà6øæ!çÌ›•4!í ë!1‚ ‰©ÇdÐX™Bv©ä!â"_bŒ,šíH"KÑ’¡ÿþgvÚ!ì)9Ír!é’æJW‚$9,{€VH”ß÷%âê©/mc.‹T¬#sç·G¬ÃpCj21;C#í¨ÁÔGV;Žç[∙âz(…>ø(¥n£|{´Š7Â,(ŒÄñKSƒÉ\@ú‘TÌú#‚`ÿ&‰]”áÃ|YPCÕch†ƒò9B(ŠËÅ þ#@’顬èÚ(…‡ÉPU¢ˆ¾OC²PÃ}zâ¼(’Ý‹rçbˆ+ÈÎ9NôïÎ'"µö(…bU•ƒ{/h(އzôÕ„ÌU Ÿã‚E:è9X=Xÿ€«ÞýÚh>ïÎD|Áe®vç†ÀøÛ°Ôºšý¥u¾7غÏHt|Ú¾õt7Áb…¤cögûvF…¦ªUÀ þ …¹alë«ü5m„N¦¯û»þ•,Ö*¸ ½‡BÖ0·œ,o‡ÂÝð¶Vc<„Jßá<=– …¾°ñHE^ñl„eá<Ö†¼6!c<:Ö0ÓaiL<Î=Àá{§ûßì…·ðä<8ZÀ¼S/h@?ʼ,0î*¶Õ‡ áÀø|­à?‡BÞXp^q‡ð^Üc^"Äl9öõ‹Â^¼Ðÿás`6ðzj¼3p¸·°ç¬è/ ô†Ào2ðôÀncá0yé·‹Ãׂ0{ï¥0ùÐ{ÁþAþ¾Gü>@ùžÀšéIð{7&£Ÿ&œ2™ÿ@`來ɬì©/û& rk/&2ü\Oˆ '¤@ ­(¡Âj¨ ½´ =/ t!ðP‡5"RØ!”‚‘B/”¨ H)”«ÛJч9ÞèCD¾¨#Ú„ Hƒ¬„HŠ…È©ýj…š¨ƒhºÈ ¬˜"²!mn„VÇûÌ„ ¨YšˆX¬2 i¡pýŒˆ3(@¨ì¢ÊV1‚„#ÈCâŸìX¼¾%1þ’ „Í­p"r4¨ƒ°„hX@…¡¨%Ìç¡bŠ !ú´!‚ 5! Iþ+¡eR d!xŒ%€¤¨‚ô„‹ûpá§ú4‚>hEª„1ù*Ž…‰‚¶˜xf`„cdŒß­^4ˆ ]ø’þr…‡è]`¹Å …¹HB䄚> „ J E¡pBñp¨\¼„<ˆDï¡z²W!fd´¡gC9·!aËx!`j~¡lšñF!Êm‰@Zl/ŠcgŒ;¼‹èY®ÃÊD#)!!þŠ/DA9‹—3«ÂR„EËÁ¸Ã‡Z$¼ˆ\V¶ËÃÍK¼&+ƈ)°ö‚ñ¯‚§¯ Zð/ Bð°æK™/‚ð]°îðj0â'*ÃÁ‡øLаâ[¹¡³”F/’ð$°ë„¬¼3ëÇ] kÆÛëÀAä(¼7t˜*# ²—€ ƒÔâ¼Ã¦þ¢E= 0ƒÐ0¥ä˜8õª=ùÒI­í dŒi3…¨<ö¤Ó°€ÛÚM<ÉÅÀš›Z_%)½ž ”bMˆ#ý3€LAYTõ€@¤£”¢`R˜t"a‡û êò+@À_HƒÇ礂*„ A±!ä!½Fîψ Þ-¤¼ªvøD 1D@¤‚èB”†+MÒA°œDA:’ ˆ*†úB i$,"€\?â°VêqtŠòšA””!L‚ÈZß ’ò`¸B@ÿ•£ý¥dBÔzÈòNJq ñedA—Hqþ ˆX¾!rð‚2éš?׸ÿ‹‚ y˜Bå‰!D ¸ÃÊHZr!ð„‚EˆAB! Ì„+¢ðHDÚd“\ª„&B'yO $ì… cjØËÝ! ¨’"包r„ -Ò`HE'I,*±XBÝqxYƒý×6ÃMˆ\/ ô›ÆÒBxŸ#ý³-2Œ=åF”¶´ó(Ù DóÀ…‰Ø&èÈC}/®ž—€ÆSŒ<©ZeâhÀiâB 1x5D! ðÈtÌ;Éô ‚˜tl^( ÿ_ÏpÃÕQÿP©ºúv&—R3ŒÑ‡ Åःˆíëá‡o¡êsê^áx*5¨Ã›ë$ƒÔ™x²#ü˜t¤€ÊR(0èð·÷r|}x)è ¼—‚$€ëz©A㑵øÐƒÑ¢–@eø¼"ä{`R Aî±™1÷tŽàMÈ$i¬@p’k¾ƒÔzIƒý-ø¦?ÊB]Añ¥‹Š“[Êni5¾¥”¿GúRI¥òò€@ `@(<@À+—  /È’ +(B8¡ 5úRIBu*v#{P…!J™ÕLÇAõTʘŒ“ràÈ ¦&DBbôÆA( ˆúb’‚ ~W,â_ä@ÍÑ’zÈ#TèT‚2p¥Të!dЦ‘\?ÄÜ«Ê$-DG7HCJCü&Ÿ|ÀÂôÔ‚SV[–fv!L‚NÕ¡‘H\Ë”ô„ Ä×™u™´‚J{³3ˆ]™ •J êXA é|ä#.ÒNAy5ÇCþcN:EeÑà;±‹sÖf Œ˱1©òî!uBƒ,²«ç~™scZ‘ ïlÚ{Ù! Œ¼R%ÃN^žÁ7¥…×NBÓsä!ý[›KÆÏáÝ®UNìy._Ú©B^@ÿV•¸…Ÿ±ÿéÎ`™{3€ÞBÄmf/ÜÈ[øBqxfÄ"¾Õ£fa×öÖáÏSŽç¡×!lT¼1rñ¼§ÛÄ0ð„AÒðv¯ù rEâ¼#'Æá‹Æ½BnôÃÚqþ÷Kˆ?†a—ØUPɇßãýì³å±æåáÁ—‹h@r²Ð1‹£ ’µeá]]3ЃȧT/ÕÙ—þ‹RºJ£ÿ›K˜vƒàê>¨ì XBHÿ`2¾Ä¿P†@qAH ;À?ïÍî´É| óÒ“N¢M†z.%òf“TzMH©6ø:¡‚M‚)52DBF ñ„!a—’j}þ By_¡ z„õJ¢å”ˆ€:^ƒçøþÛ_ä  ´¢Ø3^ 놿À‘,d/F_±¬@ D±—dB7Ä ñTeuFDÑ L*%zÄ ‘ŒeÃfÆ]Òè„î $ˆ ûär¼#-€2ψV¡R÷øâ aˆ&ã,Šd(OÅbØ‚òEÄ"Pª\A:Äñìeßı”AXb1Q„@  DñfR!`… #1ØT®ÏÑ"h€22ÞÇDQ D)$ˆ1öSˆò!°…,b=ä(Û{D>+üãuDñ§5 `DH€reb€Oögrfˆ69¾XPÃÄÿ¢Â«Ð­t*Äÿ¼øØQŒBÞ…¯yræŠxé;¾"óÄ/gøšˆ¯xdˆo{ö…"ψH†÷¬€ì=ïùþ©Pªt¸Hr{ÉŠj §s2nšÈÿW£ý)õ>?Ô¨ÿY)©3ð$¡U£ñ=æ¹5'óÇãì[~é©Ã&¤d>‡ú—UilOôÒ?Ö;ÇP²›¡VÄvP a‘„ÔF‘•MJì“•d¾ÓQKV@iaÉ”Œ²ÕVHêY¬4ð¶Íš²” .dý€ TG@(  ßé# n;­³P¶äâÛ:«mIŽ¡î(ÿr„(›b B™Êk}DäF’FAÉ2$}¢ AŒ:aäF´"2ûø##|ˆOXØRˆ!«˜…;AþÄH3OžMâz¨B9à9ó#ÇùG!S´¸ D&úþ Ñh…%’ Ë‘ —¤(‘s^D;Á.좀Ò DÑ„B bB£»‘" Àƒ’ãøuÄ®G óQÓ!Pq}•ØBˆy ¤¤ûOŠi„A¦·âOäÑ äA}d—YÈ…Aèž¡ë뉢d)¡ÿ«É ¯cü˜×âÃ`\ùfd(@׊€D«-"ˆ÷ÖŠåcHS„/l…dRD±F)X ‚{猎°)'£ xË4à¯'Œ’Øò_á„…ƒü0Ç”‚OÆ)Z³,o[ÙY™°ÉʵXj%b,5Ÿ%Õ’ËVDYJIh?åÍUW‹ ÌÊb¼˜ÿWà!sP € V^Á%(€P&Œ&’ðYêɯ’F:‡È `cü’kj?Ò1†ÕLŒÑÁÀFQÑ §$)(±¢ Ë19!P؃J²Ëxƒüe‘“â?ôyÔ ˆ0b A,&—#7Œ…’ wˆQÀ£¤f£ðúþ .tþ$ˆÊ}!P$®b ²ª¬ö ÇÔÚ1þi‡úï Òse‘–FI9 ÖƒlÇèÈà±×ëFR2ŽVÜõÜ…Ò ˆVð ¤pˆ5DÃÄAûhŠ„íÆ!OÚßíÝnjxtd@2 ôçŒy†] ¬•N|d(?!¹³"Ü‘@?ÛV !H„…P¡ÿ͹‹«÷ߘ;Ò €HPj"ÛóâÜ–­ðÿ'd+Gš!nIs•ȵab!K_iÉ1£3ÞF9«ØcËøÜãW\Q wž0‹×Ïy¨MEØñ‘؈¡_±ã%i¿$žö ±yÄMDY5T£ÆJcB…Ÿžñ54ÔÓTN]êÝB áYņ5Åd8…¶Gd!  ‚:€–Í ªOéø Ye¶ ¥¶VÖ`ž›(`'" ¼ ìåNŽ Êä= !þ´"2¢ 2¢¡ ‚2Â2ggx!BØ Áf²B ã`æ~ëR³Â ºAþè‹\0Ðmç~U ¡þ ²ì¡ZåØ Çú¦B Ôã.zb2¡áþ‚§œ ΚÝ0^"¸ Æ‚9 ÛMvá¬À#0¾æîàÆ9B2Db°î¢#àß§š.2@âvFNàÖ9‚ Ÿ‘7pú"à"þ Î!C‰"‚¤ !KÆ ÃPÆ6‚ „‚+g Ž E „« J"B â ‚ª²Ú£-#'¶" LêÞæw,2ÍB æÃûÄV`çÔj" hĬå­B!JHÖ"¯ ðb &0=îBsÀ²ÖHv×1¢=ëë „ÇdÕ'Â0û‚ZûF úäMOØ+RªZ 0É$Xe‚œäÔ“"½,¥d]åd!é XbVC¢ME¼VIzÉ¥†!¥d+E€Xiž_ŲXp üÄ J4@ %` ¥Àb]€ $¢aú Õ!ÿÑG©å ‚ @¢ ‚!¢ @bÑ3>êP|µNØ ÉÌî¡þYjRßâ sD.eñ¬‚B2ÛzPÆ "¬ Ã2!NXÑ ÐjA<° çFæ%f¦©íÀ" hv'¯7b¢è¢ ª‘l!B‚ Ë-Ü{ ³Ðf"pÚñ)b æ$" Æ!G`ÚƒÚb ¶!þŽ“?bªÖF gÇfòñ‚!+6!Q;‚ »n”"„¨çtô$Úƒ=§XžoÏjTlîCëY¡þ´FÚ†*~nµE" Qþçlo¡þ³þ3b=ˆ´Ë>!QÚç„ì¢ м=îãkz!Kýxt¢}* =óý<á=êBìèðøôͽ *ÆsÏFçDB!/!G|"j5ǰޯÓç\¥‘!;—!Gq‚ Ê>¨­Z3@#'Rvb (â RsÚƒ$ܶ¤3 {¡þBªÀ!V*qHž7ŠF" z!þ: õSb ªL ËK  Rb vAÿh‘ ÔšÚ)J#.ʱ#:wK@ö!=,p Ù;jáþ|ž#'I“n"5êN"âùG>Šäâ3 ´ßyZb¢Ÿ8ªÍöº·¢ FYg{6ºëþ}˧5y–à—á<ÎwŽî#•7-ší ÓA!ÿ;y™b¦Çœ[›—¬!Mak+Á™™‘‚ ¯ç€˜µ¡ÿT3¶­w™Áþ÷pÔc~„ÕƒÆÔøO¶Ý;ãÆvÚ&-õÃB ÑãÆ7LÀ þRÞµõÈöög®Ð"¶è&ÐËÿw8 ÐëtSÇ‚2çGÿ—œÞ¥× CÙ;x\hïö #4lç\[Ôða¢ÛÁ-Åk¨*:³ø¶Áþ;1_ã]ù•ùÀìFÛ5.Ȳ*7ÔîÉÈùTy Ooj æn{Ç¥°B˜cÁˆðF<ø;çà+þu `ÜQþ!ò üO•ÀþžA™NÀZy Y¶jÔú˜z¬1³¬Êг2Í2¨lκ³jÍj’êÅK2¦¬¸¾Ù­—{ÍYÍf6€/ùQeþ"<_ê*²ók«L*n‹4F¡p©®¬Àj³žÌÜÃÔ4ó}™£VQٟ؊°‚Í6©‰ªÐJ›"ͨ9,ÍÜëüû³)l×Ê?SÙˆ6e}Yf¼TÄ–g˜9V¶EX6am™«fqU¸:ÅM¥fîÔå:·f¦M³s–ªmš¦bªÅœ³ 3®©‘ 1ô³@gøh³ 1<Þ¬ÉÒ¦¬Ï‰þíªfô8³Ë0X³«1Ó*aâ̬ÄJÌ~Eçø¶³–®[Ê©K1 ¿Qðγë3PлéÿªhЦd¬Á¢½*gšÍÊ’‹ 'ªhÜ|9,Ä’Ì–GÀbÌ,J1r¦º*qT|û²Rˆz³"±òå$ãÌxJ."¦¼GÏz¦ÕGÓÒ¦÷ÇÆ£ŸáÔ¢wJ)ò¦ŸGÆ„¢FR‹Óò‹E(ꘓ(—r‹‘EôÖ‡2‰·(®‘õ+1±õ?/‘óëÒ‰Ù(‡õ¼¢yJ*: „GÐü|eYˆMJJ+ §Çͬ|¡ ¥$„Ñçú\ƒ'3-Q¡0•‚„ͨ0¬¤ ÇúHS!HJœƒY§üºƒ4H3rƒhJT‰©è5lƒ"¨2؉J|‰¤H6,¡è5‰Ùh3Ɖ·(šœ‰ÞXú=‘ë&äé<›"q¹ÛŠ)€¬¬ÃÌ_*Œ̆€PR¬‹Tø9Y`Jb*ÒÙþ5*ÉR¦k¬Ë¢ Ö*yÊ ðªn1ÿ­Ÿâ²ÌeªÓ‰ÿR*‘þÑ*ËÀ³ èÞBáÿŠgùrÕ´j±¬³*Gþº…k6¦©–úÌ,Ï  ‡ªf¢­p¾K5"©Ÿê±¦³XÚâ­Ä*lz¦SªÙÿBë*ØB§Á*bêÌÎ* "§ÖŸæzÍKª ²¦7,Úz¦^ªÊTÁÇü•ŪÒqÿÇ΋0' ªÇŠÍÆz Ÿ¤ú,ÙÚ¡&*{O´¾ªš\©“Rͦíª¡Kªqš¦,ó+5:©ýçûT©Ë3Ò©¼þñ^qfE™Ü•7S\qf…™B÷4?ÔS%˜@eXœ”',Ë¢§Çù*a¦dÛR‰üé̾"xTÈ©S( p³òÌ ÎJQ ì³%¨TÚ Sz¤T(%&ç 3žGÇø©™¥†…Ë1hGãàöY†Q~Ãü%ÆTÈê>hÏ(À’Ž’R‹•ƒHù•3 BQ ˜M¥˜‚Q"î­D|«ò!‹èùê£è*•JGÍ•_¥8¬RÒQ0Hø…£ç‘*>#(ú:¨…¨šyK(ø‡­ä¢KjQPì°„–Äì”IS…d&C‘B3HIå]d“#æ –Ñ K#(—€Ê?ÎPÚä\ƒEúBX¬ ÄØƒ/ ŽB`©EÄƯ<Â0û!3‰ÍH”DÏ)"$c3”DÕ!(£þmÁ"@£üÔ.â§'ï:Q‹õE(|þÊ>bˆù¨‘|Ñõ¾á}(»”|{Qõ¹å˜%?ãˆÿhÈøÖ#éJ?Íâ>©D˜b4¢L¥2QA(úöõŒœB>QcþQùy3RˆEJ3|©±þM‘òá])EmÐR Güí(™x‚€ вÑñU”‰FhgrA™ÉqâTƒp(–„¬b ™‘[#ü½b5מcüñ’=t¸"k›CåäA™{ù#ÓƲâ;ãþ-Ò—l” ž7ÏÅN’GR§ ‡ý*d4©¹1þ+’ð Ù £–±…fæéE4€¡ÁS\8@£ÆÀ”mÉSǨûka*²uÑöBé\©ž<•‹¯ííL‘ñ( ÎΔp{ÇJ/ŠøM”}´°ÊQ å™.Çô¢³ÇûgGÈ1uÊ ˜”RºŒ÷©G¾.ÛÓ¾JFrH<ÜBJª>3ˆø˜hóàÒ‰ œr¤„ž´},ì©ŠÈøžg$¢p3 lM×€5‡ùbP’cýˆIŒ*у—˜ƒºoH„0™4@3þ–sT?„™„‰sP˜0’˜–5p‰Ø™Àäx²‚,À™ûr«°­Š\ €ó¦È¨YU ‚ƒéJ“©¸ÑŠ‚A» 1ô ‚.“ófŠ€Þ<9¿‘") €1€@‡ø£„0 ‚ÑŠ™cB’õ `³(0£ª©‹1ižØ¨Z²Ã"Þ+“Zé5‰D´p«6b1³ ²0¢SвÓ1z˜Š´. ÁÈñŠ€± ›³øÎ-P«CD<‹ð8 ²æ·‘GXË ‚/ÛYŠ›s1ÑP ƒÃ?RŽ)P9‘ÉÀ³=p¶bÃ) 2L8Ÿ³ hŠ£˜©®ó¼ú.›‡øÃm1뵡ÁQÀF-!(·²Âù Þ ¸àôT¾ÄqÏ1>û¯£Â…aȳ;áüJ¸ªË´ Å‘ñ¿ó‚ÈElÃÜ¢¬—‹3*“3$åBÔ©"¤a(œ£‹á,û?É(¥ý­’þ Ò(‘ôœ‡ú²0„¤¸“Ñ3²Ã/¡Òø˜¬°Jú®u4¡¿»«‘ò1êˆ0—&]€y^øRÊ…n˜È„–øƒ Ã:²[K¦%À€„¦ @6ÁœŒ°‰´M{Zú}ˆ0ž'”¶AQˆà›ˆñ˜†‡€ ‚CDùÍ0ŠƒœZ %Š˜:^8¨:<󹩊„ƒⓊË<ŠxGð: ð&Nx[XàãìÄ ˜¸‹K‚ýT‡qг€6°ÜŠ…NœŽG‡úûŠ›b©Ð嘊žMÍé 5®ÖT\ŒôÜaÕŠƒ{MЊƒ‰µËŠ…8è«1#’#˜¨F›{Š™ÔÑΔ`¾*©œ%ˆÖè©ÆÞ;Ò4ßeÚ1,°•P©„ÀÖŠ²ýK·x³U†R¨«Q²·H Þ•Àè‹0.<Ä ‚>‡ýf9k½xñ 6}¹&z¸¬€È¨©”œHÜt4Aµ(Ǽƒ$Ü‹4,ܰòC=Ö £a(Òä8Tð©Ò˜Ò~J®æc’¡)(ÚD6Äç­lÞ8©qh šB‡ù´¯ í½X³ Á!z%qhœŠ’ Ñ(†λÇ9s”ò„$ÔáôEeN‹hC¶’‹n)L¢‘ñ2‡ý8ºI\¢A(ßTrˆ¹UŽÓõI–Mê’Ž³œiù(‹„¦¿ƒ¶–¹>=ˆKÝ¥m^ÌÇ@„ËçÕN?Zr’ˆòˆ3Iëî*ˆhbMè3¶ÀoJЃåd@„ž‘Lrgúr2ué„Ês,ˆH’W£IˆÌˆœ¶Âvm]~íp æÛˆ1A‡€ ¦| ]¬e¹·:Vb‹4#äúÄå⊘ÞN;}šð³/1ç‚q)– ÄnOƒ˜¤7 “ÂàÈk« x Op‹ØàÇ ±!;K o”Aî¦|žêW[†ÕC|\ ¨g#±ìò X©Äþ!h(ŽÌИ¡Øãð@ŒzÔ 4…Ïj †8o5½åeE„y @¨oªÓ +Њž@?6k»´dFU‹[ÈÓ\}h员¨jîjý qëfAÍ.-Þ}EÞ·¶/mðëHÇiå?ÇÁµ¿[iŸrmï®m°©o[Ñ–ÿ+ÿvÿèZnOøýîiZÛÅËyâ¶«z$´¶kIƶ+|´¶«Kæ9­ŠbÒO­ð{ä·†«xZ¶#«Ihë­èºÒw-îÒÓ¯fÂÞ5Ëy¸· yP·ª KVšKxœ¶@1Âü·ÇkHS­æì‚´Ègø<·ˆoÞ³­0ZÓ­!#(­ðZ õ­&ÊÞØ­-ûN´‹KyT·¦3­æJÞw­íêÒ¢-'b_-ê ·„Ëy&†%sªÞºDd¨ƒ xt†)KL¤€Èb6´Ñçü:‚‡ëy!-  êß3 ¥´ ´Ç¨)…9¡“áÿ$ ²Z‚Œèad·¢(Šº¡©þÔ ­* HŠ(b΂œÈ`6·ºÈ*Ö‚‹“ÊÞ  ª‚ ã ¢"«­&%v†ZÏ¢!…Ê" ¶‘þÞ ªÊ Å ·2’ˆ»è*6‚ÕÇúGz"!ò{ÝŽ_ìb ž!&z¢) â!/B ¦#VB"…˜Gý@3Ÿæhpó§ઙÞ(Lä„äˆJB„€hŠ”„¤èH"ˆè‹b¤#¨L„¸ŠFZ«(Lð¤(ŽH¤#èKjxƒ!Ñþ´ÎKÜÀ´¥kØ@·Ž+e*’ðšÞüŸáßmí:÷AŸö÷a­%2Ø]-ú»ð·ÍÓ»L·Óh”z=Õ:¤àŽÛáF2ÙŸöJöÎ+cдŒLO ·ÄËLX½ñ\aþö­"RÞN-˜BÓd­:Ê÷ËŸíj÷5Ÿô1ÿÄ/f¢ß-(š÷Óû¹þ$ºkbíB-;"ö s x¼¶0§û<´Â‡üÀÂ-ýÐè·˜ëdÓÛ­ó±ÿ,/jÊÓF­=Óq/a*ÐRè‚Ò7A£p·Ì¨’Þ9H+Û´ýŸ§J·Žå¼Y–ñvòžÙo‰¨·ˆ„’ÀËx2E¥½¹$£Ky#AŽ–“ZUã‘àP·Š’ß×ieå¤Ç“©‹x4!„è´¿—¡Ôb(^“4A^ÿU/h´š”Ìmˆa5-0X£2ÒüÆ™ yë>$eª‘‹H§!‡´„d‚AEaoyk ‚©2Ò2Ëy5 ¡Më&ÒÞÉ(Ê-〷“¢ Bý-á@†;B î’i D†)¸ö[ãta‡æP€C‰iqRVAb@'!À‚‘2 pˆ+GŤÏUn?äáR!„œ‚2 Â(H!ƒñAÂ^ALñ [ è‚r 1UY I¤%fò*APY T¤†Òiä‘”#üð™4?Ê1 £ýš’F#\è£üˆñþ‰ˆIx!)af@?Ú9 –&_ÀÂ;GúÇšDyŠ‘LR'°ÿ\L¨¨°i¨DIyH"¥!¬ 7&^éo„쟔\^à<1-‡0´“R÷šlK¥’ß H¿-›ö‚hÉl„îîø´0Û8 ƒþK@Ü€T‹Ô³€T· I/„ÔÄ´†BØóGø¤-ã̶;È^Î1ä-í°¢ÿ HÎ-”D²òöïùi<%íùe^ë-5RÕ †òÞ· Ü?^5´¦êÆÞ‹x¢-V˜AÿJZ3 °zÓ1òßlø‚-ã·±ÆðZlÚW!•%£–Ü?Æ…!‡vëúým/±²"m$€þAlyiP/8†D‡ìZeäÄ-ìÜ´­KÅ„m ¥¾TøZ`9¿sŒ†WäC!Í ²4 ’ ¯ qql¯Â  LrC1q0ÅžA]¶)!Œ­ÇÄÆbîÈ„AòwâŠë!ŠÄ±ÿ$GøÁ!™H¢L‚ º‰  SL¡TÜA^¹aƒýû6AIÁg¹ †2õÞDWç"$t‚Í‘ÿ™È[D!w!Í4µ„D«™g@ÈID!% žBhŒ!,Ü„‘RÄ‹†"0‚y•|BHq Qe"6tmD•r÷‡û /xˆ´Ôâ÷•‹L°/q“†¨ãËÙ8-!è¶þ&Kf=քĽ”gŽ^Ñøÿ  {ô6JHX¤ð®Ò¿p*ŠIÚækrÝKØ`%îÆ:²ÞFõœ/l´„"ßKÜMˆ%³cÒ€KÜ0û ´bö©-Yi(δ·í!þŸËÜ\Žœ¶q'hZj{Ƀý3Ŷ[*‡ç<ô–‘:[Îa{EÜšÕXâÙû]âJ%Á©‚Þ`ÂoÃd·ñûn?àT â6@·Å…Ò[ì™Ë?׌¶."ÓÒ  UêèÔ¢ÓÃþ÷‘—³/uZïRê%²]ƒŠ[û2‰w¡vĶ[×ái^£þÏâß¿¶´u¯%¾—¡…Y#Çùÿˆý<´µ÷ËÓÈ(LPS€†Õ®“ai¹$ÙþJŽˆ`R-âÄÔÄÄ¢‹x¥!œJùå-Á”®Ii[í¨£c2ß'‡ýÑ-ØxóËæOˆ+›!‡öL–ð·#e\Є=þ šÇø£&Ä'Ú² ÍòÔ>!Šg‰–ýWH*Ü ª,‚ï¢ _d1c„Uçœ,ÿù”¢ï¿—ˆfI"'ùw†(BplØ €œÎ–‘"˜g˜"/Àæ!¢¾¡€â cCM‚ΉÍ>"01ÂÑ+¶ah^*&fæ©ô""º!%’!07bÍå& f¡äÀlÖТÞ ËdígŠJö£ öOÇ*BØ:BÒÂç¾~íäéÂö$"ҒΦ-…ø"\ I¡èâì/k„2 ¢-𚣾æí ¨'@ëÔÛè¼-„ÖròH˜BØwGQ!%l-‹È`Ѐ Â~îV/qÔf¦±#böÅ @Ž"`†‰@ìzà‰pÙ4çú/dr¿%ÈÞÂ-’5BØåáþkbÒV¢÷«ªqËQ#bÒ âößBÒ€bÒØAþyó—<‹X-(D/h#=‚Ù!þÚ«òß‚#‹aþÀ ‹ÿª?©eI¬?Þ®ÊDÁþègöIoxîxŒqZHHâÞe(†Ä$ בÀñ˜]Öyo¢¦üŒ¢Þw lÃæ™ë¢M%?(çâ]«*!€Òv¯ˆ-/Ó ‹^!Š´– ¼,Úà¾JŒ!‹1*o”!‘ÚåH–‚ T˜ ²¸ Â!ÓJ!„6 ²ÓTb '³n-/<óüÍÈóS5e,B ¯Èw¢ª ("$ú¬©)BÔ"%—Np( ³'Õf!2æ„ !$MS¢"UB×TÍ*apñ¨!"pd"Qb,é–(µÅ¢"9‚Ž îžw.B"Ž%bYIªã˜hÓ2@8Ö §¯¬u$`-”°¬O³" ¯Ž JÇàèÐn±®(ÿÊ@sC¾âLìÿÉÄÊÂ÷Ó Â-‹kTb÷K¬-‰qp $:èGàG TªñbÒÚâö½«¤ANä½Ó@-ëÚ Aê:ØrPê"ÞîþVböµÑ@ŠáþAª`/u>ꈠb÷jjP|ÔÚ-ï-!gö޽Õ†‚ö¸ó×CsLìðü-'«Dð„¾”^ïBÒkt\-/kJ@-‘Ôƒ6êö’wQÌ€b÷7 AbÒTzw-6>”‚Þv“·r ‚H‚Þ?ubaþï–£ åZ-æjæ7B‰Ìf¥^-à–ò‘"-7Hêªå±o/Cuâi-ÀRóË’øEMò³’È’½1ÒèçÃ7emнuKø-#Ö ®VªÉÒ-0r-+ê ·%!‹Ìç]W«†}%& ·°¦µXCB U–áþ?¢Ò^ã  ¬KyÆ¢!âO ‚!“``OÎ-¯®÷âÙWÈëõÈ¢1 #¢¦ ¯ò. aO¦\5*"/úÌ!ÿXllÔ å‚Oê!…°!%ÐΡþÂl˜( Ç^7øÁÿ F4%aÈÇÂhôS^ ýV"hj`Ò‚—É´""·dM"ÑBn*$Ý12€„Öž/kÑ=Uóslq2ؤy‘OoâÞaBöH¢ÒRw-â*­‚Þ¼Á¤Ä n!aªë;9BÞ{Ø"öón±ðê-öÄß¢ÞØÀ6: ¤è &ÐV§þ—‚öR#Œ‘'>ÂØ«O†/w†Vº²+ ®¼ wŽ¥kD-"õ‚ÓÏ-ñD{ñ»†»9ÐL°ú½láÀ¨bÞO¢³™jgž;§—"Vi¾xêœV¿Š£øT¼c¨”ì„!: a[2Ï""@!ДÀËav¼BÌv0!-GÙL)݈]oI±¢ ª$ÿBep]ÓNíaÛŒô‚ö{›’œ¼-™Þ¹=È-óEdÔÝ‹‹Ü[Öìu Ø„À 5Fù‡È ;âÒF0‘ƒdcÝ4}áM….It-¼À G"§Ø•v=ÐÆ±BöQ(d1˜Ïd ‚-ˆ–Æ/sëÄía‹*÷j*œ-1„qt|ôÄ"Үʼ/nh¸ðÎúAt!~WMŠ˜€ûXíl)Ê©¶•a²+N¶ÐÛ‹Šº¸ÔÉžjÍàÑXxt$Yäò)é´BFÖ-üÉpD›5;Êntëàgõëñ1Åä˜Äq½¸> -46°6Õ‘gY>ê÷YJ3áŽD^-/Fë’hàÑylBÒƒË0Úâ ©¦yo†™¢ÓMvBW" ï'°/MBß"ô8!š6ñP×¢\Ö ´3Û™þ ªÀ˜4?R°Oâ ¾h¬ ª9ÓP€Ñ^äc«6Z ªº%¾ðŒ¹ ²kÎU6•ït²{#B L Nú µ¥ž!ˆµó‚Xb®öB ‹FQªP¬z”&B©•Z'Iî ²ù|ÿœ+â~Wì‘ ÐbÉ9ßïp þŸàØ;ýËyBßï˜x𠇼aíø  ‡…¡îÈ{‚€ù#ÐRg€_íÉSý®š9¦àIÓüQ?MÜ3øpþkŸ²&îyûf›?ŸR(3J;ýÅ?(€øÔÈ^U¿Úsõtý·=ŸÐié£zošh“û„Ñ«7tÔ¦âš4ü%7OÓò pBtaÁ€Mî©Pu‰?uÍÄ“ó´ý7]ä§àY¸–~µMÓõ Ü€ŸÎii ~›äæŠ\å#=4ŒM4S@æþ±Ÿïé×ûR~&ò)£>~П»æûšüÓ?SMò3N°ŸC7O³õdüEá¤4gàéù^~ßú3xäÐG?3ÏósFR~ûŸìò,§àÊ~L@ ê~'ã2~H§æÔš-‡ø”ú¦…Ì(릪~‹6°âª†IùøŸ¶Îò~¿&‚ ~k?ZŸâä»Cº~!§är~yÆgøîŸº ¡… G‰ø"Š5ÇùšŸ¹Çø(Š:‰£š‰û`†qb~Ò¦†:)(Ei ÈŠiùƒ"‚¬`Š=ɤBËHb šh ’Ÿ’è¡á0"h{"ŒrhÄ!†r~¢ÓLŠP¨`Ÿœˆ¥ɉ¡fŠK‡ø´Ÿ›¡ºŠ?(cþš( 6…€½VŠ.Hj(°¡•z•! (‹!r(Ì¡‡ª("‘B¡’!r! úb¢‰"ž!šŸ!ŒrÉ¡ò("‡êê!š Rತ)ÿj¡‡ú(|!áb{¡ˆâ”!zÑ! ¡ r!ð:!ÒpÀ@ê×¹ÿa¦&Š‚‘ ¦J‘r¦‚ÂoQ&…Bo|©¸P§òÒÔæ‚šn"€þ¼‡ûÜzŸí:¡¦™¢œ¦˜éÿ“Ÿñ­¤óêo+jIºTši¸âoMäo ¦…;o¨'A >3Ð-¬ ü©~[J)¹öÕ¦ô*iAŸãêo' ùÚ›£I¦RŸI¿š IùV›éCÙ4ÊDŸ„²(ø‚qTdü‰È,C Ù4Yg\†CCi S„0tõ(Cÿˆjy63"‰ˆb1‰¤2 Å0‹ÈaÈ!Œ5uHv?ÁÙTD0úàC X« CI(éHBýèjõž?ÖhÿX¤!¾. 0ÿU”–z?Õ![ãþ9…XB \ä “L"(ÃÇø!î8„¿Çû!*Uøæ@@€=EƒGøþÐïÀ/ ˆa¯÷œAµ#D 15üA·kD!耊&òˆ9¢fð}þöãþ±ˆ+¤ñ|M ”A›|LÿlÄÙ6ŒAû‡Â„q7„L&ÄÕñ"{§þ‚ ¢ƒb(2Ã?«’BŠñ7ÜM3ÂÉ ÂxœÒÁ¥T"zH5þD‰§b`_MÕ{¢mïlÓ„Á…Ñ6Õþt"gª&¢eê&î Ð üŸðAþ¥ ÁJ'2H™ÀGùÖ‰ÂH3ƒˆ™>‰‚â&É ÆL0šmb "`Ú&J¿X8¾"ks€‘ j¢gVo¢kZ `Dñ[„í&ñX2‰‰™Ë¯ð\V̠Ϣ qÅgº''Ã' ¿h1/º¨27 h™©%"`”W Z¯ •(˜ŠQ\´Ÿ1Z‹ ÀÈ3ã ˆQY|‰¡Ëm ª°È‡´Éž‰†‘[ï …³D©…ñ[ ±pËÙ —\% €q[e ¢°É²pÌŸïÜ2sÓQ[Ù\U°ÈY?Et q"C1…qFŸómdGøb ¨(uõùþxÅpÝpáC1½q9Y`p¤Ã+%p¢×}qcð½Ë\QX¡pJ‚Ÿàš!  Æê "h’P ÂZ&Q¢j&Å¡IëþˆOø"“ Óéþ¶D>&?ŸçÐòBV Õâ" Ø" ƒì†Å6h€Ö!Rš å­º&7"B T@.\¾ˆ²&€3Њ3:C኉êGþ\ãøœ¢"d£†’çü„ƒi(0âˆ>òÛæˆK™ê|‰‰H…îƒȹ‹¢wª "fˆ0€‰¼4ö…OûN´‰Œl‚&Qkž-®"zí&ƒ:èVyÊ Ñº  Â* nBhŸ<¢è2Tƒ ¨ƒlƒlýB'Õñh0î‰ÃhS7”òH˜V‰H™‰ô©þ»ŸâÒ! ÕNåã¢aÚ' ÏR ² ÞE§&FŽ<’ƒÈžnƒ6’² âb' ËýÒÖ¢cF÷úèŸDƒXh1K^ ÝyþÈ›ÌãHù!ÀDà!(¥‘ö÷†MQ_ÎuU0²&=š‡ál‰¦wTŠÓ‘ƒ„7¡’BArqFtƒlŽQYÈáAµ±ˆŠÉÿS¨eÚ#t2߇ø¦†$L0¢´¸†QiÛEmõ$§ÐˤpH­n!–îÌQY[C,Ý µô2æØ"=èe!–†I„*Efu ¤2zÌlî‘S"¸Ü?Ý4JA—µv¹‡ú“ŒJ µt2»‡ú2C* ¥ÅpÒb²+DªàÈ @UÄB, éÅ«ƒª®!(ÿ*êá.´VEd|€GªàÈN?Òò¸JjàÑ``‚ÖÉí!Où £.?Ãi¯#„@g"{‹®"nÂÇþ`ÿ%y\€²?Ä™†ïx…£jDw#ýÓˆB&ÕÈP·"m&c‘9½.ÈœRœ„AåcúBøÿ#åèõ»â ‰H1!B䉌ÂgxgS 5621ˆævä)Úìé^ä(øk¼B”élSá‚‘²?ÌÅ Å\…R6¾>ùÕu´Lö³šJùB"dÀ…Z|4a›3é<ƒ ²!Gùs8·L« ÈëHUœºpÒ2B¡8Ip8ˆâ'NˆR‹ Úo6{2C‰Sf¤€¤Ê?ÜÈÿ8™†X ]K)±D$œb—JòÑSµ¬‰–‚ ÃSŠafœ2Æ?ÃÙK„*Êú\È©í˜"iôƒ#M1{2u±“Àƒl²ã†«¶¶§cü<¾²H¦ Ó˜ƒ(·u¼já²ä¬·‰âD*03¸DßÒ Êÿ/Lý¨jèXÿÏ9ĉì·v?îñ£,Lƒ^†‡ÅLò "pЃ'œ¼ØÈ2iÝþý÷¬‘6$t¶X‰²)’A‘ýßGu£¡ÿhª0X0(g^´LAšù¸èf“Ä ÄE\ùáõ ”’ ÄVÜö‹òY¯7r6WÎ!ÓW—Rl["aQ¥!›s"ùâ<Ðcô¤ìDôò?°˜‰ƒÔW(_Fïí T2ÝPò+X:&B¢½iÇüwYÕ Ò[ê†HFê*zýwôV[ØžC6gªø¤V‹UÇÇÝ0«ÕqÜZ”cý!™J?εè3óî;4€%g+ˆ|µ•Äw4Jâ’®Ù¤rÛ?æì ÀÒü•¥‰°"l0~"ÖH‚!¡ü.ìÄ+«õBBƒXœHh°:Güæ!S„±Ò3µjèá"&€ 'B‚&8Bý`8‚.›§€½B‰"cfŽnj0Ø¢ sj`‰¥þxŒÌ! F@íÚò|`‚:âȠ†O¶ëšFè" ø+ "67Šè!B6¹'"j !DtãdØ‚ Q'È0 ìaþŸ"Â"0& Ër Цý°Ž¨ âa8ÙÇLh ÌëRð¾£PÄ÷Ç"mK ÃØ!D(µgÆ⎠Ìx ÄZ!GŠAŽ"„`mà|Éæ3p3Dj‚‚ ·â ÆLÄüÑýÂ&áAþ"&×NÕñ%‚ æÑíN‘'ç pÂã­þ Ã6C$  ÃáþíòíϺF&–ßä2n0Ô ÎHð®ÿä28–5 ‘Q!c¬óâ&|.hC* Éä#1~"dÚãNÎ"cœ\0nRÈѤ3 ôNdÆC!vEc# &±DÈaìXEqî˜ElV|ïò¤VâhöñÌKì ÏHëà‡EŠŠ xEo&µ©DEpnd2úb¬±˜V…í‘êElJÿåÞñĆEenPV6 Â6jˆaþJ!‘©\Ej W O…p6pøp¢ PÃD2Oep/ep[Î(àj—¶ÕLlz" Aƒh!H®_ÂW†v`d’!GNn¥°LOzBAd“Pô#ÐÖqb} d¢‚&-»bkiÙAþá&ûâ&Q&V"kŽ!QÚ‚rP!QpU¢ ŠÐ"q;â'/+g"!D Àê! ®ÄíPƒI¶çòþ"ü Àă¢ ®n(F$OãÐ!KHµlN!Iäv“Âh Á1¦N.ÆŽp2 ÁU5í, t"oâÌŽDÏSw-" ráþaB 1¦ÿ2rºº$^"a$1 }¼|¡ÿ1’†áÂ&m8 Êæ1pðw'2ñ¨û“ºœDÆ Ë Ê È˜Ÿ3°vð¬"pï&b aþB'23âŸ2éj Ëæ G¶êöó!þã`ʤ³P2‹ÐEpLvP–4ç*±¤Và­`æ§àC*Ó«B¸D2msÔ ±×JÜC#"´Œ >#p×$2„‚Ebz ”sïO(‹ú‚„2pdREk8‰Ó‚Åé—¤ŽEcHC0Ê'Q£Gb'åJ¬¢ DWIñÌÆäÄC'ÔC.èãèÄTnC-w:dWOˆEb†Y$VÄåp)²nEb.C2Å'IoèW¤C#ôQxRéø¨æĪ`ÉL„êpÆD2@ †Npë)rW „âT¿Œ›Áîàj_‰zþ‚ ïÂ€â  ‚I>!K®Ò¢¹iøßb½7Ìæ)áìá*xõZË6+¢¿iëC*¾"bÈ!JkXT$þ‚·£LîÂJ´Uâ ¬•˜ý«”ܬ" p¤æ÷WÉÜçFpº! .{`ÒËàМ &€D!KÄ€q*¤Æô"u™@k@âÜ!S#U§~¦cŸ“tã’¹[ªˆ ÕZyb ªU˜·³é8Q-çðŸª~!N2ÿð±Äß4 Ë ŽÁG­Ç\UF"gÔ ÁæuÄÌ üá|­^­–6<²?JÞ Âag Æ¯ÊØžUŠa‡³g6ê¬ô`ngžžDŒðsÊxÊîîЩɪyåVë$=öyAÔ ñ…\D2éî“WNPɳpóÓßgVPggAB No#FzC*F¶nŒêäW5!þLô¸"nžZnø§ä2#+#*ưDVµòZóÁO¨Ú@dVVd2}ÂC#Cä2&…Ht¨êC*öÂÁþ+$2ªHnC%BŠ$V9þwä2¼—;UÄ2KÅ„Es#K!þïÅlEkéPd2”$`C%˜Uõè–R0C%ÀÀ÷ãlW ;Ôô¬„2zU(cÑáÞî¨r—£Pepƒpòi`…pŠ –lbêàp%ù-sbâÐ!Kä´¢xÞ"ÐL‘ä!S°}I®MàÂ÷`þ?³Æ¯ƒ‚"sFôZÛš­2‘qkLÑ[Ø~åG¤Ø 5S`ÓlÒ×ö›5b?ìÙjP9âÄ"m¢!V£~â!Q91€^Ff0 vÎLó#…ªj´ƒ€z ª®Bþ¤ãª!Jîžu§ª˜„HŸØi®¼"ksÂv¥¢E5 > ˆRü ÈsŠmhÅb¬GP …^â¼Ñâ÷/0*Q^ÎÈ1w˜Å†6ß,->ÝÂå‹" ݪž" â ŠmŒc‚&íðø¦åæžá*™ã0"uw<™"'“97a9,"qêjxnS“´;@„Vâíž20 ö…n9ë²Ë$w—áþâ2 †Iò†S¨Ží—µ.óûÁÿi´¾íDñ‚ ²'8¤2v92ïr…Vå§6Lx¹ñö$Vx¯Žˆ[p8 EqÍUU-7Ü4¦"m MôókjVVö¹ƒCk› îøM„W“)ŠÂ2To¤‰ñߟ„3{¨ª·ÄV]Që¬Enô§Þï…pS)#uâ†WÓ‰ÿSjáþº Lެž”ï„Eu*"Epë¢WW tWX"`Ò"‘b¡ÿ?ä¼!PjFP6µR û•€MjÏ‚dAZÚIV'eŒ(!S*„Ý㣤fð~øî7Öœ!XâÑGN¶â`¿VB£øˆ"|žX›°“dÚ½ ¢º™$!Kw¯mvª˜ îªy'‹Y9%vðª"´N"!B; à"fL“QYb" h¿a¤"&ýQ:eKX~Ä Ø2—gê Øfø0²OøAˆ\!O7ÄÌQ›N"kŠoÁiûBÔ?*,¬1G%š Çå³øA¹™ehqIÆ•8°Ð Ðë™™ ^-ÖÚ(Iû¼àâÁssèX™³û›ŠŽ+wm !»‚ Ñ7^z#j5æåMD3uT1^h=2Ñèa)´P"múú(v-Ã6w·Nîr´e@"txí;Æä×`Ï'U¥#¨cÚC$£J%ˆ Ä£é% ¶¨„2†„2Ùù×(z~há22ÅD¤Â$VÃ%SÀâ'#ÏÁl#¼3NÙÅl~C7YÃÀC"þWLC,C}l*‰dV¶åÊÂô…§&%ÅCPën¡þ)·ÎEc*W“¯q¢i ÅÙ –Ó@x%øNBpþr ÆnÙ-¤">8Ab†œÌ€˜ #!ºI¢™£é5¥ lVà˜Ûý/·ŽV(²í‚>aaǽ(Ïój ÇÔ!Xó=;•2›, ­†\®pÝ[ȉX¥Hd@"&ˆ’ ©Þ ê2iÑ`Çü¯Æ9§K Xõ;“j!S¨Ð 6aÃÞ!Q”ø¬d¢'Zßh‡Ñ[tϱ¦#6 –+¡ÏðA¼/c7ó7•è7*Þ!M¹uqBCVˆ5ÂliäÜîE¯Ðåâ¶qà Ã#j+{kæº2(„h‚"rè2+9i±ÇÐ]½¼"q𭾬Â&:b i2‡äyE…ÜQ›ÞFC$:àíº—øó{´1i¹CZ¶E{Ä|¾ò÷¹LÖMÄV¿|_ ž`àaþO(êMX²C4¥Æ?©HD¯Y³×a~‚'ª´ô"iâ‡ëÆs˜Œ„WÛ´ÿ!%­È\³!L²`ŽZ…צXžžé!îÄV‹ÚÑq° ÔÜ÷Ëþ<3„…n‹×W6ÀLä3 êÚW.C+¡$W&Ex“ÄV²÷¥pÇ^Ó—²`ã!¤Å'$VÉ×ò/¤Wõ‰Zz¥ø›MŒæŸ¬¹÷UýaþÑäã IráÿÔ©Õ×¹+N[ŠG` Žé³ÐWþ—6;²Žt!\6¨3U½j" jG·÷Œ!ÿ,BšÂ á=ÀÝ5¹ür ǃZx^JÍšÝ?·¾–!Fˆ ûÑœÖ.‚™€{¢ ÿ-ÅTp‡ø6+5ãOH¨&*€8¢ªH«Æ4ŠÃ Oø¨¦4öŠ®â¢xÔÊÖŠ½b¦¨Ð*ËŠµgòبæ*WŠ££M¨¬º/Š¿¢°°ý©fÅjÐ'í4>Š‚â®h«ò+]=ãEX¨f*ǶÅn TUaÆ—7‰T`Š£b²(’ b©«EIQUE“á"ª˜¬û;EI‘T¤UË•Žâ»2“¥˜â®p þµŠ¾"¡x©¾*°Š´¢¯ÛüËpÅ]·x#—È"¯¨¨w—Ft`Yøó–¥ÖYùgªò*ÐåÕøXSyÊb­¾[®*5å¦ù<娆åȪPÞ –h¢¡£–"¥3–› Bk–w9n 9h#x¢ B³–©7†z*Ó·‰óx7šV9`;–¹ix«Ñ3–³7ˆCx’7‰cxd9aÖ¹jÃxy9fK–¦7‘«y7‡–n€þ9i“x ¹k³x½Ë¨;xL ÙþÖ'üÖH茺9k„ºy¹n|º9oĺ½·ŠDº™!øº™éÒU£@c"(´­‚ˆ¨BC§úè­‰ Z­CQÿ‡ù@ì¶ Ó(Òò›(ЊˆÒ°0*Ù”ŠŸhÕ^Hªl­Öˆ°XˆŽ­µ¨"­Ø„„hÓ캖:*g"®Â·NˆÕ¨ÚÂr4ÿ DB5,Ú¨¨HOvŠ5 C:*‚+oÕê-ˆE„©€ëd.*ùW"·¹ÿ'«l¢9&éÚVФ ÚÇVèÒíG-h­^­Æ'ýÆÌ E¢4Ý Tiÿ#èÓ¸¢ ‹«œ4‡ýtÃèò/èŒgÖ°PŠÉ*ݾȨ&™¢°Ú‡bˆ­(¦ˆ«Y¢£b*b£Laþðé"¢z+ GN6ŠÄgøï¬¢¶FЫ£NmþŠ×Ù¦ŽŠ‹¨ªd[Òbå¨Nú*iîH ŠŽs'Èð"þa®Y¸Š‹è«S\â ·rqÎèÆsÍçs¢¢.I‘·‰ã^—ĺ¢³ÜÌèFÈ©bŠ£ä’û£b*)¹kbý7šô_rf¬nÞ°ã1oXì¹pcxò I³yÑàÓ—/ÉÎX!Ë7ŽCxÙN.¯âåÖž"±˜rÒy¼G,u³È–éËðåƒs–nàß9mHÞøŸÁËX uñÂoÙ¼I«‘.ƒc–Iëìˆà2Jâ\ïhÁñþ­’ë7…¢µäž€ù"©EŠÒ*-”ÙMem ô6VÒÛŠ+f‹ȹ;øô%²¶‚ì#Kô·FÖVÎÁ‰£üQ.®Y)scýϵl@ i[Fä ¶!2F޲#EÐ@r¶çˆ¶+aІ"*€ŠØ½ndj'Ú@ˆ¡[‚„7.R*Tˆ0ŠDVFù.?Ýpÿ…l–!\E_‘[•e¨­Ãø€$Ì!ÃVÒ WÜ/”ÄV4÷”?×XÿdhŠ6¢æF‹S AÑ}-’*9ªY+mÑB÷ Ûc MÑÒJ¢4¦ Dªu‘©2?ÉAšcþk"ŒVÖÔóç>r‘Y¬VÌT^ Sñº,Áÿ$ Ûˆe³ýa‘TþH¨œ#SøЄÖâˆ#$ ›?‚»Çúé OÈÄÂ5.3– Pb6X¦?ÚSè"­Æ—*b„iÂÅ9t~•*dEOÅ7e* Ðú^o pÿDV2%°@‚ i  ß"#<÷ˆª Si+Uò@  Ò9kÐøžÙ¢}H©{ J°Þ/"ˆ¬7‰D7åȉ¼—P°ÞGYâÒå\ëÞW'–o!‚7½7Xo#Xÿç.<ð´rÐTÄ¡éåÑ‘þYì7…©ä‘R(ŽŽYc7‚݈µ°‘YØ7’PÞ+cxÿÍá­7‡áú¸1aÎ[q7‰-ÔZ³— äd€ŽðÞ>ÔºšÍâ‘7‡DÞº‡ëàƒü¦þr ÿµ0æ*óx‡Òëå±évÖ-x†ÃLgè¦< ’56¥Éep­Àrlô5T¹$áG¸ÿDi×r5LÇùhkÐ$²!Ùq¡*$Uñ¼$¤HÏ+s>Ì©“ŠÞ¼„j¾µÌ'EHª+uà†:Edèÿn%o¬²+bø•Œ¤U¥¼D?錈ø`ˆ’5Xè ÿ7Xù©%"VÙ˜ÿp„ó@c]a³*×B‘@’ú‘ªŸÈª+f\²+ƒJÛgf/Éš¶¤‰¨Âoem´¶b*䈸ÐTM‘\œŠÛ1•e˜ ‰œNjœÄåm#%µŸ¡-"¡¤5éê[‡ý.çÀB]>?ÏfZÑ$UßÑ"b#µ XÂHNF´U2«Cü¯#ÙIõé´°‹-xÖȪÆäVJl­¤²N\îìóaçaþd ›TÚ!xßœ±fER|˜"»™Ã‘TRo“  N¤ÖËÂrãþÏ;dV›Ì%S[ñ±Ì¬‰mÈo$0ÿD¤ oÛþðÍã†êa1©*o82Uâá’[™¶rÈå9mžï¤EF1Ë•i¼Fho+ ÿu˜Ãà–Mååm°][b?áàÿ3ü(åÛioHÿ¨t\åèCxò3”=§¦ìr´ºüáÚMJ$£–Z’ìH-"å@€Õ°vê€Jt(i Iò].†ðá]8h‰ÇùÀA¨¶òäŠÝpŒñu«ü?ßþÚcü`BÚV3Gù榊W"&&?òNtð§\mAÿ8·¾…òˆ§¼‘¦´i5%lÑ&óÉ“à DW,÷Î?ÂáálïôkˆéÐëe‡îñ¨YµóXGáãR+I*gˆødôšûbâVH¬Í+t[3üu3 ÆϗȪ_ŸNô¡zFFŸ¾é E|­«-ðeÊÙaîæŽ¿è7N4:Ì–yà ë ÙNXÓŒ•ÀRµ¾Ð3XúA@˜ð·84°‰Â[‘Sæ#3Shq hÃN5ažÐ Æ´45ÚÙ§Á¨–Ðñù ˆúø¤<°&YÚˆ×!‡üû}–³™™áüú3'©žŠT·Y‰ [A%„Bè!´$‡ùY*Z¥·HÞ$Sˆ0¥å¼|"ùç˜C€Þ>œ8ˆÞ6²™k¼Ýá¼¹Z“à%˳7èÞ3rÃüDˆàPÁãf¤8å¹s@¸ë° áe_ ⽩X èÞ  Þ@`¢CœY‡úW‡ù?ã½:ß’Eãù2‡ûÂw¿R¨LËʇüK¼r£ú:•‘‚ù¢/„L‘ÇÁÀ‡ùˆ 8Þ!Cd©Ü˜ˆ'@=|ŽLdK«L&¢ézÖ¾¨ €M;Ec \Å+úJˆ+‡ùŠÍSl‡øÀâ‹.“.¬ Å4²­ ù‡û8”ÐÞD4|-9¿ â“:›És¬€å’êú¹`¢Ž[<É0å–´ñ˜ª™x.8Þ ´+G$pÞ 4ùÅHý’BÔâ-ÞEüo‡úŬi ZÁå¸|Y!  !°Ñ6¢E@ ¢#ù‰ðzºc–!¡‡ú¯=:}@¯ î=\ó)JJ¼*˜}ȸ`ˆ/Ø‘›Ú°²R¤[ L Ú:¼ãÐ6€­ÊM¬âó Ú„4w6ЭË´‹Ä±2 /º‡ŠÚs³[×OØñŸÄRN&(­¸4O‡ûL ÚÅÒÅ3ª'Ê1¯ßª:Œ ­©ËÉë§N#GÓUHð§eÒ*ˆ(Ãx‚’;ƒ™Í}B§‘Z²0Šƒ›Œ Ü=¯4ΊÝN/Ћ­ˆ#R<òˆÔë²HB™ÍBLU,U˜½²Î ˆÒ¨Ï›ø*`­³ñ©gÕsú¥×8Ûœ–ji&,别qøI™ÕbÎÄ Ã-]U”ìM Ü… äVi/Š×<¤Lë;ÍÕ×ȼ$Ú9xW’‡WøŠÀµ­×q˜ƒÕ6rˈ¸9uX±4xÁü!¸Þ(•ÖÊw P#z£Ìr·ˆªxªPŠÙŒÜùŠÎ©ØNLÀ(‚ ˜å•`8ã_šúëÏ¥—¾å·ë5“Mår»ÒÓ%A±YŸµ›®]œÈÞ"\2º« â 8¨å¶:(Y ââBbèÞµ9õŽ][dy[lhZ Þ-.Û:ãýýÐ~1ˆ:1ˆLøW¡¤Y‡û­™.¹ÕØ$€ÑEÊ1ÃÎ*m1˃¨L38šî‹ø|øŒ¿½V Ù²±$€©8­¦I|ŠÛ*l6]Õ1ÓH6Šƒ@"°ÌH­¤ÁNÈ’A ÒÖ8X•ÃÓX˜s9š‰u>À¨JvÊ6# ­¶;ŠÜ£í߈ÕgÏëV¼»DTø`¾P³q¯^òƒöVY–( ‘Ý'Œp4§ð ‹°­‹Eô¦¸­Âá¼¢Œ»A냈ձ8 š_ûr§ýy Û'`nˆ© Ûé1„õx`ÞˆåOˆ¢ŠÛŠ9«QP1°ÝèLj˜ÕÊ7ñ²•T²|WQÃØp­Âj‘5T.1ƒ†‡ü–‡û{+4MƒÂ$«œˆ'Ý›«(ÍèK]ž%b½€Ø §KØÑÎ)‰YaFÕ ˆ— â381žÀ½q HŠß$DäÈT히ªO‘@Š«µÏà,ËŒ±keˆ¤_!û­!ÄÏXƒ6@¹þ¼ÅTÙðÏKÅù·‡ø…Ä$—ÅpåâMš©Õ§ àú=Ts”¦(påÅ;äxÎÝÅ:õ¬ÐðÞ<{yZîÆÏ[xÞ,Œwe”ôä˪ áù:ͰÄí±†Èø/à8hù#­º. d!¡Ø%‘EÊ;㘾p­ø|¡bîÑ83Àtú%0g‰ôâ< ¬ã ‹)Ðß’—%ŠÙˆ‹ÿŽæ]Î{šúš`²×¾€ Íൂx±r]F|]xŠÞSÞÆ ôH<ƒ»½ãð:kdèô hÉFøŠ¿ÓÙˆXÊ­4›Ö”ÛðŠÖõFˆU*©c2h‚L匞Šp‚€S'4|·¹©Yäñä“w°®G–Ñ ÜHåí©¨#R¬êƒßת¢ŠÙžTå‡bµ+d|&¢x¾™­´$9êÒeØÆTê0Œ4êMŠ6»Bè­C½3þBä.=Ãä¬Xª•Å‘¨C-£6Å7â=`ÖÄ7hŠ¥‰Ól–K€…Ô0²Ù˜·6én%Kn`â͊ÉÌÒg8k- bF–Ñ(Øåµ‰­e@¢.Ý]ÇÞJg0Ë.Là@>bˆ­@¢Tç0 ሪu9:Þˆ¬@eÌAëxQô;.»äIÒqÖŽ]ŽØK›‡ûpl_Zx¥Œ\->XúÒæxÞYbÚ&#¼ ௬å¶nN¡Å¯íÌò åïÕ³ãjVežeIúÕe² "Å 0ÉX5Ç“Ç" înø}‚jr¡bZH";H•Â’È7F8`HR[B Û¦ÓÔ. ­Ê¤ˆ©ŠÚʈËn…Éñ¼Ë"xñœcˆ¾ê†™GŒ·J<$hŠêv¤˜Šè4áÚp­šóÓ (­Â>ØJÐqt7bhS çÔÞ#­!Ò*²"¤Ç\LŠì,¡h­{æé%ú¦íÜ« ­ˆð¤È ËøÂ]üœ€ Çó½“O¥CÏôŒk¸­­³Èˆ­€½øÖÈ.—Úv,™Ê͵œ Ú /7áDtæW$Ѱ®Îc`4‹Ó2H>ØT’½4ÜåB̶%ND®=Ó÷l·JÇ‹þ?æ¹”äx¨G+ •ãÇŒÐÕnQ*¤tx0láG‹š·†[@G‹!5b$X˜å§:°Ý3NMÎ œ’ÏVÝ}Ð ¥¯<=îŸk®E-«hnÚ î°Ì>Ÿ+¬;ˆ:àÊćü]¬¾_s<C‹`Ù(ªŽ[8®fÞi…Á`ÞbLQ£~_ˆ´.xåÕM¦ÏÈêÕ/E2pù(Îàå¿âòÆmx ß,\gÀÞn3§:6]÷Üí-‚-õeúÅf;Y).Ð}[8Í€ä¢!¤ôZ´.‡Ø' ú&åwÀ­ÓÒGQ¨±„¿6„BG¸ß?ê˜ç)º—P¨­§ä½ÆMkÜS—¤{82­“›•ã'í?zGPäD¸Î²°…Uh…ƒIÝK Þ$ëw ÿO,´ˆª¼ Ý„j¨ÕŠÛ)Eß³iµaR°gþŒUR®ˆÔ]ßÀÀòsÞº{æ›>î5‡ÿ>RÀƉ‰C7|$]›­Íknz§ÍTFÑT‰ŒlŠ'¬6#¯>cX£1—øXÂd£‹ü–|´ÖÍ ˆŠò+Â,šzžz­ˆ®âÆ‘8¦îÍKQã&W+$οõˆŠÜâ¶÷vжÆ*E*kÞ;‡úOˆþê@—0Wû®Ÿç(C†¾„B @xAîÉ„2¢°€ü ©gÂP‡d ¹ ¹!CN„¡@fXÞ„a ¸@†– ! ¸Cò&–! ˆCš –䆄°BÀ¼ qË4¸A>X¡¨Ña)dºÜ– brÊ,`BòÊd áqBRÀ„±‘ ¥ƒ8BÒXó– %Ê$:a[BÒÉô9»,ª@§ë,8,ÃÛòÀ|!©,K&æ^ÚXÛ–`ßáic;I,×Ç þÇsË—aXî5ßòóþpÓ×áÛ^KÀü( _àüb…ô;koñØúÿ6€Ïù‘©þ)wþ³½÷¢Hô=GúŒô3èÔôª»Ð¢ïzx%0»Ð£ JëÐ1„SÞ‚ Jd„4ojŒ=1=ä²c¥ï{ùíâê=z:¡{Þ_¡óÒ„G2KÑâËÞç®oz”,èÅ Q"½àM=çª.I‡úþ0èÈ÷‚¨A çŒ[2½îº„/{ ƒ+€4®Àκ ’< /z²2ˆ¯=ó¢! ß'()3…ˆ@„KÈ8÷œ¨E>!ˆþô¨@6„HCÎÏ}ëÈ(A`×E,È@¬„D[ß`ŸõIþ¢ KÉþKÖ•BHÁ̺ Aj04È@¶„‰º„¶#ÞÜÒ·*Ù BŽ„Waÿwât¡õè١ªa¡œn5èVHD<¦*H¼±ÈBBÇúÙU!$ÏHC›u C3v„HDÈ sª¹÷:!Ù£z?ˆqSiØId€ÎrøãYL¦‡+¨‚„íꦡÊú %‚š:–j‡øpÅ%*®¡Åbt%‹Ú²èr¨‡JóšX&ºqªYO¡Í9ÿ¿iab–«r2!Øk„‡7ŽúX¥!Óz©!ÆjXã¡Èbĵ e·7Ï:¢9*Êç¡ÉÒKgúì6Ÿåè|üþ¼b’ôvHlô*‡ùþ&ÿSgú„NêQîï½á¢„2²j÷Ÿu“ßy J³Ñ‹Ÿð›ÐÅ G»ßˆøž’õYÿL=Ùþ¾½ *|=é¢ÞO~Þ(½öâ÷ëéŠñòLÈ@$z¤!až…”d@!žˆ ?É¡è2Ä-ñ*B6'¡°?ü{×áǼ÷$â@žièzÐP„6ЭGûr=Ì„0qþý@öRD yžƒj@‘‘{ƒüb‡¦@ ¨18à9“`X¸g¼“ÄÆœ˜ÑQ" Š(h”“Cä~¤ =ÁL{ÚiJ°ÀÃÐ×R™2Py%ôÖ?áò!¹XG¨FÆ@p!x–SК^:v Aœ„ 2°R_™*e„!ŽÈØ´@dDE„Mø+=í,re$¦ M< qþ.à!•Ãþ"Ê@…äµ”¤" øÂ?ÞlZ!Ïix#þeðD!$ Ò?HD!ÁÅ^AɦBK±%ŽAVE².Gøï%“š&ôóHrfÈ „D’øŸÔº%’ôMBJÈqÔ–%µ¥HrY,Ù–Ü¡’ÂGAšÑ^ˆ„%] Ž-œ–0)àCŒÿVd9JDˆÛ `>”D°2XG €˜„±µP‚¤Hø!ÄÐ’Å,Cuf$±SãcO `7%‹è‡G&K‚Ã5Ç"FâR>Gø¼›Q>?ѱɚƒð*†ŽÒùï / ª^àâ4é4?Ø!èœÉ5iž…œ?ÉÑè6$)õÆ@—Ñè|UÞ‚·:y:Œç¢£L£ß *±èŸÖ$ôXµšŽ@W=òHRÁÿB± Gº¼;WöBÁïW¤Y@óß^Àáï}‰:“Š?ÅÓø!òÌÐ’mOE4å©R÷ÁpÑ)PÇœ÷¬2}f‰ï/¶¨JõIè¹èªÄb‡dz d DÀäApŽF€ve`Ûêí™–á(„WÑ,¨¥|¤ç¢òœA–Ke‹·œ„û&B­ÎFè °Ã#¤¾ V˜ıþ^îLx´¥¶ ‹@¦ÐåHô!‘þŒúv?é3%’2£OÒXgÈqcŽÄ±柰ˆsV!ÅôÍXÙ´Á%€‡k×þK&°ÿ#„8Œg]¯J'¸Ãüã…Ñþ¬F®'>AZ±WãÞ¤]âáÃü’‡Qþ¼Ýè” StDäT'¡³OcÑ¡ÇøwNä!‰Š?Ö°ÿ£¼wp¡ÿˆ‡… TùÅh&>= œ3 Ž{ìñH¼„ë‹ÏCвà÷Éñþ-Ï{òã\£ŠsI¼@‚1ïVä\ü1_Çù= O ž‚V@²(”=äÉH0Ãß͉ÁèIvDÞñÿ€sÿ9§¡ô0ÐÆ{ÖÐÿH‘ˆ÷ÐN˜O0ÿD  58€¼`Ct)P¬¶n ±úé_(C!ÿ*w‡¾Ú7ÊBÁè‹3–jÂ3ÐE‡ú€øöè3ßçB¯Ÿwç÷ÑäVdRýXA4P?Ó|„ë$ s‚íc,!Æx½“7é¾duþiGÿ+ K«¡Ÿ…ªB'®Þ™äÇ´]jÄ>ÂÛ’šÃáÎŽ?þ¨­¢?„-îÆœ3Îsh÷VìqbšQÈF¹Ó²@Â0:ûXªL ^¢™Â·¦ª¡"O¶\¢Ã…t!ÎÞë.GfþŒÂᘾÂÛF M¨>XøÄè!ÈhÛþüjœí–èp G¦!Âì´âXtŽ‚ NxtbXKƦFç,Ðtúb#Ç:%‚èÙC0£"èè¨MkÂ¥"+bT"¶£“aÿ ç^ØctmÀ«gì­ƒx ®v©¼=æ ¨'AJ¬€øª ^®!þé‚¶Å%âwL$= =ñ EÂ= ö(H‹ªì*bÐí Ä=ìÈ B KNëžK/–èJR G|= i£Ð¶¦<Í…'cЖà¾=íBlƒÐŸPV@£ÐͦàÂÁþƒÞÕàé/Á¢A°l¼Áÿ6"'î=¶yñ0¢â³ÃÐQ¡þµñ(IoÔ+ì!Næ žVÄ£q’露ÂÏ« ã ØU Ãh> F‚æzÍÃÐýFpLƒÐeâŽÿ*^=ÈØÁÿ‚œ=BËâÄ!´šƒÐøÆ7ê ï{ž!.ühúï\ÁBÎIX‡ÃѦ P*‚“¢ú¢Ø=q²Nï"‚läAr\á„Ì)ã%Í;þLBÀ2]¦šOÓ$Ë„ñZ±Ø_5âùŒ–ò\ö¼Ð ‚¡þËK–ù¢8üoÆ ‡o ¢X‚kŒ³EýÒ  Bâo˜íbùKDsÈ!€tAþýI¨!Ñb{PT %‘îÕ«bJ!4ÜI8%ˆÖ!ÈödBÃMc!â^ÐN¿ ˆ…BXÒB`fê%ˆqÄ>¥G%‚!;ðT,*6Ó£%ó<'bY1“gâ ¨9#rsBXvG\ÇÀغú ^<ã•àʵ aþ¿Šìþä#ÐW*êýÒω;é ‚BãÞ¼¤ßgä=Þˆ+6 HÒ¼‚êÇ×,Þ¿§Á=³Å)¡þ’0hÀ!Øg"@ƒÑ+ѧ;àò! z‘bVãÐÃC€=¡"ÅbˆBg£ÑP½?p_>ä~!2=® Qš´’.!ÉAD¥›Q²=ß(xìM¨7<¨ÎQÃÞkqZáÃÐçÁþHÂ\ôf1„ðãjêè  LÄ9ãÑ)ÈS¤bÔ"B=ö‘ÔSÚ=î'GôBÿ² OHt)6bC¥™&ítò'0‚¡`ËýRˆžfe±!Ì›좩Ã'É€ÄBÕQ+˜ D„ K@éXÀ+ðØ OÌ´%ö!¬ B RRµ=Gÿ9ÈŒ\ÕM+ï.èÖ‚#/¤žÈÉ‹TÌåâ R,LÍBl¦6ÎM»%ÊZT@!Ï"Ïqœ„b~Él#âÿ…bfõX”Ê8!†åæÒb¶£q/"XhϤ¢b3æÈCUÄ!íB‡ÂZŒ¶ B줂W°¤%“ú9¢L_‚ð>2Â1ubçä!ÕÞãBâyŒZ!ÓTó£X%‰ääD!Ö7P¼!ËÃ[scáþ5µÉc’9á¤^ãä s”=ê0-<6!çY‡xAbR= ŸEu$#ÞÑN6=äÚ=û$ƒÞá1*=ë4(T¬!S ƒßU!þzðövÈT+M‚dH\ž#ß«Qìui¡ÿ5íÐÀ¢LNjüñ„¾dÀ=žìAâ%O@ÖÛ4EsZF/ %q/‚¿«*î™ÔÖÞbÑa¥Ê·B©¤= XýTO"³£ßhÖEq‚ÚÇØ´‚ ÉÞˆ²ŽÄ‡W.!Ò=ëE)+ YãÞÑù$þ\k‚ÑuÂ[ãÐÊOt¥å¾Ÿñà!YrFŒ·‰vb{QØ®gÇÔàýÛ[Õ?d^6Tîõ@øô@£IH–N ËÁþú Œì¦díq°®hu}‹~gÁþ‡V’e²!:‡K5î&шt>6!{µXéŽxwñwÏNƒ"T†Þý@ÔÒÌmwþX²þÓFI R]Om‰*o¾íÂXýX3,âOÀ!ÌX±0\‚u‰à¥¢`s®ðâ™7è%‡Å0ð!ìÈ!È&&B¢Gƒj}:/’r"Y™wbo°¬%Š‘7ò%†ð8³¨%–dv/â¦Ócb*™âl3‰‚X574 ¸ NÆóà ?BöÜ央Ih†h =ñ4 Pææþ=\QcÐÍ.#„íDáuÂäñ^Ybh!®=[Ô8,ƒÞê=ù"Of™SÄ;ƒcÐ×.Δ/ È1»±øù\àìH¬ •¹$cνƒb>#Ñh.^Ýyw‡SçY>=æZT>|äíxucß"ÃG(ö IG“в!Úá%•yŠDYÊ¡þ¬ãкà J É€ÖÅ8í¯ù–ƒÐì©e6u6*Z V¦.®! :îCÞ£¯8Ÿ€ƒíü RÌnWðë6ësK I ô¸=ë.Ó³û*Y¸°˜èO@‰"†!ÿ€ŠoInƒwÀA‚éŽÀüÙŒ¹UÂ~PëOlÔZ\ÅÆæÕé„y«¦0æÍaÿNla°ùK¯£Óha'PX*Ç kä°!ú`)Lš[™sKhBøÂ]ƒZVîØ¡~R•u¢Y¥âJز‹êt2µ{†Å¤²œ!Å;2aÿh2ýªìü:ÛX‹!Çù®Ml%‹Œé-ª5W¶!Í>9p VvBHÕጚ°%†vô"qAþÙ64Sp%Ž¡c¶-ÒЊ‘³0 ¾<`¼#+€ù‚ ¶ª„âwˆ&¸ÿzˆ@Áõ夣ћLéë}©ÙÀþWuiQf›=îÊU·=·/äÁ°ÃР‡X=:Vs¸û;uº4n!}mCÞù–zmô«®ª:DÌ!ÿAvDEcßlî<=V W:±Œiø÷yî=ædèkw¢øÅ™œaÿQ·Æ*‚¶ ˆi¹¯\ƒ9EPÒ#ºë%Ò#›h°û ¥^ªã e ˜X’[ƒ’ülL –¾á ]+ÎP¢’5Ý”²Ûzaÿ:}k SëÉ üB½]ßÎf GÕÐ+{‰¶ Jû´¥8¬¥äU0™•¾A¯Ñ–ôLï.,6´üF¢âÏ•»2Þ—gDRˆ Ws–\²çÍlüÞô1Šòu+k×Ìö›Ø] Rõ×Ý÷˜L#ÞAvåjßÀèöÕK/AHh¤ÌÆ!Dô[ù˜9í"ìî¾Bô:œ††“{Kìݘ¥ìck/šAÿÅbМ¡zîtYKÊŸÀkd—¦p”f¶õÑëx6÷ñ´óËž}†· ÁÿjÊêoB VÏj0²âS\¾í®ç®p!ÑïŸ'¿(ÜëÓ:iõÀÐ%Ÿ–Lÿ/Ô8І4Ÿ_“Ú´uf ÿqˆÌƒ_³7Œ%Y)0¶BwÍÀû £¬þ C!ú;ïBXùÍÜ!ÐO¤mYÍ¥|BYcZ¢çØrM¶!Ö,¤:é,Ç,çbY^""ŸïHü;\ÁÁðq4í Á×°p°¾b/?Î/ñèjÿk€ö`ÿt/öÜ¡þ–?àR”ÍÝ0oÌÈÍ]0jÌÛ3 D¦- Ì“6ìÀU3?Ìó6DÁ±3™KDs¤ÍÕ:™’æ)š¾`Ö§LS:즗-°Ê_s3ÄÁu8™¹f é¶S]–×å Y™Rf˜˜?fsyL®[;”Ûk“2´À3GÌ6éžþ癸&ù™²f´˜4tvÌô´+^™Œñ3dÏc-¾J\30Ìï0LÕ³9~O^ÿ‹ÊA»9šr`™Åå®9›Š` –Ò£jPqtËÌ^¾ú`H™‘fi™œŽS¿ÊËbrÙì¥w3“ËD38šRÒ%©ºZ¦f2fæÀ ™È™ƒI˜ä™—‰™¨˜A‰k䆩˜°™’®3ÐÀ¦b"fƒ%¥"´äÁÉh‚™“Ы’ 3é™ð™¯)j’Æ)lJ†I™J™¡)lt©©hy¦`Úg"i˜\™”雵!Ášf`9 Ëœ‚H lŒ°Gûh–²‡ùL¿¦a*.Å«\.™Œ ™äƒ˜‰›D–£í‚0%éh>™Ÿ(ƒ§ ªÈ;z–„‰˜žƒ­ lüºH$ä–š ™¸‰&n %²Ú Dék‚ )›n‚rº¯h;rÈ9Vƒ±‰hªƒðš Œþ áÊff æ’ à]V¢h$²–¢(  ƒ¥h%t‚ˆ9¦™‡H²d éºÞ ”R @ †R栉ʄ ’Zg€€%Lh÷ùýþ;Ÿçàýþî_â@4¹"/÷<` Æñ²„a—XÆñ¸ü5ÇtG¤€dl…ÆÓR(Ø&0áºfQ) 4')F‘µÔTžÆ·Tl ÆÉ€ÄmxFë1hÝNU‰GâFxÀ¶6ŽŒ6%‘EF$ÞŒ<£gÈÄv$ÓµãËœ6³‹Ä…‘€\mO Fñ/öäaÛs‰#IÕK0ÿFñºHË_FÞøWûj7´Æ ±±4m+qPô-Ðæ6¡Š…e`8Ê"i©€BÌ‹llWhÆß×݇@ÆÒŽ®³CÝŸéØÛö1ßÏ¢NøÙ66¢†c§þ %£‰ãlxÛó´ž(Øj­#eú6À"P ®‰(Áª—06üâ26#d²6ö>èÛŒ‰ +za ÂèØ¬’(Ú5¢A‚7¢D„GáÒ6£d£» hÙô–HÚô èØè—ˆÙ¡!$ˆØH‹ñÿ¢O’$ª‹œˆÂ"Kr$\,Rþ®¢@‚6TKGû|‰9è“á"/H^¼(“·"J“TĹ"@ª6„H‰$U£`$Ä'<³’‰<Ò ˆ£²"s*ÌF6zÌP´;")¨’}"= ˆ LJº%È€|Ä*@ó5"*‘¥1<2#åN#s4‰?H‘ü‰ "FLÄÊÈ‘´ˆÿH€ŒÄyÒ³"ÓðŸó—"-Àþȇc)R™ù„ÇúN†›2bU"A0é¢Fê0{)ÄN‰Ãø‰,(j†ÝÈ“¦†²¨•膆+Ú0X#eš0ØõRŠ`HÃ\‰S†Œ -ú0`ÝXŠ6£2%t¡²z$A#*6c#Ž \£¡þó!®Iþ7âÍÂ1ŒŸ÷Nf†ÌÈ’(†ÐGø’’L6£ò$¹!­Z$Î"DÇ;º&G¨£x¹þ5#’$¡hoª7įÄ>‹‘jfˆ“j†Çúš7V!´5âÙˆkìŸ9¢{ŸàäP²è®Šèˆà"¢¶ŠåÔ¢†¤(— ‰lLÒbÑ(–Ø»h”~†ˆ"$VºÆó‘"QÆ4‘2ÍÖç7ˆ”‰6¢0Å¢G§„ð#e£høÈ“ÃçÔg˜õ'üü‰ ýŠ%.mH’*‰^£HÀ¿¨ØÚœÛÉé3(Ú_¿ùÒr65£{¢$˜þ(“†ò(“r‚HÚ|áU1 Â6õÇúqëÁ1‘¸ b“RîtŠb6cS’bvÃüK¡²6²ˆhLF¤‰ ã¤FÃb}äqñ¨â6RÈ“PH…Ó$„Ä©S#cm136?Ïq( f5r6ºR#§ ˆ‘±\˜žøÿ$©ô§6HÒ!'"@ 1wИâD0ãýC$Dž‘ ©f ¼$@‚˜ˆAé‰U$C¢‘QBÉYÄDħÇù1H€õ11ú?Àòb*©Zõ¦‘ 2Dq@03ˆAþ=Gùp!±4‰2óMk%#l™…àÿXDHe¶BØ™Àÿ”„JS8DnF°ÿDb<‘"ôC[–DnR5R6ÈÄEé%ÝËæzÅHl³˜d5Å;r%&‡øû>%õÕªD¦(ÿ‰dH’‘! F!á+¤5XóÙ08ÿ Db7‘#ÈCeY”dnD‘" CPàÿäaå9â6aléŸS€¬·²CZi~Ël•Pyº?ãHÿ|äH]G@FÊtÃJäl&„ÀD¡€ÿ“ÃýÊ"Ð?áá )2Ч’5BiST!‡*”˜?dD<õ«1ùQ4·ªHß¹Z$I’%-'Zu«H9‘±zFãœð{Îð‰?IìFÆiŠ/ì²ë5ÍQ%sQ@è_\ˆÜÕîÍ5ñRFtô iuœ‰*BqhUî3ZÏ΄g`ˆ•õ}Y"6ú‰¥)›¿ý[’:dêš‘»jDµS "[Õ›)¬âw8fÊ?P"SÂpTäeämqñ .‘Öܦð‰b6ëxÓh÷yž$F„¸,¯¬U¤Gª…+nûO²*²ú ?ðfö#w®ÑäÔÄÿnù¼y+•o£v•mH”¤È¤H(ɇù)H—xÙ¤KµÏLÛHˆ*â&)s.Ô–þLIIºI*-¿ò$K?É^U1ì¦*J‘ÿkL]5 ¥É',t—†?¦%ª‘zDí£ýf$NøçÃPZ£þv•r\PHÁÌèt†äl`CiM1Îx·;}®k”^ócü[‘‡OXqg¦Î¶lŒB³Ý¦Ja³þÁîy¨&k/vRâ±KÖ¢6^“æL¢»H¤jÞÆ¿ÈÐÊÖ!ï«î½æÜœ¯¸È] e :Ãü1Œ°„uŒöZ8–ý(âœaþ Â1MR# ×lŒ5ÉŒ"Qð½â6ü¢¯â$@Â&ªFó®è!§N°-ƒâ6ìòÛ¢0å‡Vï¨k"6«¢%‘þm-<ÖÐóò"Q&"QØè#ò°,q âJ!°\€G"’&–ÈŒ«Š²Úª°žõÂ6·¦x!§ª{R€Gg ðxâ¶Ð¢ñNáOtøäŒ#\ÈËܨ̌i25¬ÞuJ‰dM`æb€ž0à 0Žr Õ¡þxÉØ#r í˜r‰?&fÚ"P¦¥ C0 d±Bø')vÙpå+"$mòªçr²"Œ­Ë~Oâ6ç¡þ½m™Dp!­T{Mêå˜Ë¸¥ä`ñD$"MDßóX#iÚ닆¾ä¿(ð"K¼¸ªÒ"Müež™d}2Â%/r÷Áþ¿q†ò¦CIü#m=6CH‘4fâ6ÚaþåˆÂèíí‰þãksK ¤it¶äÐÖíâù1̨âíJº!¡8«Ç…Ftîï”ÔLÀ!³¢bÅÞüÍà¢Ö°I¢å"$ú«|"Ph«âlÔÝEâ1Fˆ)5pmJ‹ "Rzè‚$»Tº!®*½“ÙR¢p" X’k@’Q“V$Rkü!¥Xx¢7!‘éSói1³øÌiyXïö#k´|"$\i½<¢ï²â ¢7WÎÔqþ²u}%Iæ„¢7Wu<ª @#nXs‹] Xž©2GnqYÿ^¸ç¸K]b6FI]ÐË õXµÑ ±5µìÂ%KøLT„‰d‰C+ŠWþa„ˆPö¿ˆ mD‰–‡o %~ØE´Ð 6wN‹cκ4€"BùLÏßm¢mÎM nïÞ{0MMô#ðãr!¶ú2å?•/"$_ít}ÍXnÂ0íêJ!¡ #u8]ÅýYÓ n´!ÿ b¤áþ‰æð&b$‰¢»Jo9fäçH"P,ö  ù«×v4O*‚6õ²$Ô^ܳ€#z™$ÔÑÞ&vÚϱxÂ6¢7Hâ‹W&á'930øø•'r,[Y· ¤€Ôíèü ”÷äSNmuÖ(~BÖ" Z@À` ØK€B‡Îˆ!©ËoáþÕÄÉo¾ã¢7=÷Û;Î9 aþÓÎ x7†ÿÂ6]þgDz"ASYr8æPžã-š3橳pÝ>'·(Â$ j8#tÁ„äiG.õZ*-7‚6 Ⱦ"Sþ2øh"J}Z·j£ÅK¢$û×­‡NàìX‡ ñpH†€z²ömêÌPàó´a‚%F‹9¸3XW,"NîçaW‘tc°â"XZñœðiHH¹cPŽ#miË0"C˜H˜Ó?@ȶòfH”hÄ}°KkPL"D{e°ØH‡ö=ŽÐH—H.DˆÕC…‡ë(HˆÀ‰%ÆZ×BäÄC‰;¤¤EĈ5oìhÀJâ&{ˆòõe ytì"QÝKR#œÇmFkíÞ"BÍNÄ!³">9x>Þ¯`b!¦:MÂ1™xÔ–üÚñ÷æ!®ßƒ/Ò=x4÷ð’ååPMÒa´Âãbüyb÷÷Dë"%X!þCPHÌÕ:@"ÔÍ–qšBê(ÒÆÄ—áÿeóßN±?_óò#(ÉÍ>OB$â0Tæ™Rö bˆÁFqƒ8ÏF!¨£„m9·ämRÿ_wÈsS‹ÚѵJîÞGR $ê ƒ¾ ¨ÊôNÒõz?ôœâ$úJz¦‚,×l#kÝ«_"á1­H¹ƒ&ƒh;$!þ¹ŒŒ½lÄ£¨ "LSé´Ëf'@MrŠ,Œpn€»É”vgH¢³îò€VuAAö“ž.€òÔ¡zÄæ¼‹$öO\úd#i HÄÄ¡PK’€¹«ÚN‚6ãÂ$$äñ.Ë÷hlBÕÖzJHÆ„‰®EµÇ pÍm1ÊŒÃxH<¾ƒè ï0H—kF¹SŽípŽ‚6‡Hø»‚7°µ´¡–HH‹¦!ô²¥Ž*$‰“ª(H–_—CHXH‚nH™`fògfôGN¥nYJ)sl¼©p´c½N»‹2Q󈕉p®4c#èpùs;”È;“åÑ8±Ó5Ô×q®¥²½›ÿ-$Z"_PT”B$6â³’ýÍ÷uiÔ#oµ/m•_®¢¦gÂñt+ò˜#iòn—ƒF¯qÄ!þ8Ùò÷;û>ÒX‚F’ w*úhÜ?"2ïs’F# eÇTµ$ ÅT£ 2Üw;fBï3ÞP—š±ø8ÊÕ.ø=$׬dÀP@rFÀ¶ S~qüï*Ww­ëfú§œwzüu9)x?¨9ÁƒøYtINèÚ‰ÚÒ%1wh„ü3_‚$µ‹btë¬fÉ!ª‡‡Àº×z=uÆ“w¨³˜Çc¨c:B¬‰Â6¸·zË s:ýãíäLMrºÆÞÑÖvis‚åÌY¦+‚6ÐQw¡þh¡ÿbòäV2êK¨ºc•ŒRŒ‘“/šZÄLQôБ3±âm¬¶Ev#dÁ“Â%28«¶ñjæ}»Jò‡³1ll[”dÄfÓé@†EÛȲw„ˆ¾Q- Ôæ‚$7Ö4H˜æäÚë; µkmßdjJëWµçÆ/èÅ=–úÀíiÁ,CÁ½5r’# éÆÌžÆ}ß;qà‰ßIÎ|!°ÔtU•7£üÏÃöù!ɇ+b úàÄLP‘6x?â_!Æ%é™°“ˆYä!ÐÝ/ðœDÀYä8¶GŠáPi]-€…³°‘¹6ä8ë­Ò`ºˆœ7Ɉ… B(ቈ¤9eâF¯›3K‡rKÈq ‹ô‡RÿøÌ`ÄM⯢&ŽÈ$W@R4‰­B Gúÿ €ÅR½˜‚ÀÈYÚ X‡’tdÙ wƒýJ¯ybBÛÿä,§€0ôÎÇù…!ÆÍ:â£Èszu0åÝ"'1¦ÆH‰‡rµ Ê9QjCý0•ô¯ŠÓy…i)÷¸T[Ä›+¨® ¥9ûÍòí,•H?ÔéQJó|ΤHHs èˆ‡Â´1ˆ™êÙΩB´¯Ö‰ZDLœ•{ÊŠÁqÔ<¨ÄéÄTUÿf%DM-V {£QQ–¯ -‘7*( Ô”xD­KÒËGú—ZdLT¢ÿNHš×*2*¥‚'øŒ+T:qézTXÙed:lÜÒ ,Q/‘8t&á‰Q¢Jȇ"R£OÿU„8’•r?Ühÿ„P"p4wfìˆ<Äó¬;Šé¡TÖb©â&ÊÔ ’t؇GŠ V »¿dL¡GJŠY‰¤LûŸdnCštÁ*5ÌhZÿQ¥1 1AXaþ{Èpj+BÙÕØÂ?àS–à‰„‡>é-ñ „Löå;d±\Ä9zƒ®A!ë€þŸÆJ»Hr]!Ã5ò&ýHrÿ!Åå)0¬BÏ4¯¸Ö"‡H6?ì¢ëЂ'¹å`ú^uusJ¦C(Y ¸ŽhºxMîs"orþåDÉa)ä’Û[Gø!s­§» ?Õ”© –}¸I”?Ê9@„'åXA Täô‚õÜDÅ¡ X$¼LÄH#+að”Ü?1ÐaQh”˜‰‹µ#±¬óš$6ëV’yQ˜,ô­Yr‡ Ž@î Àåó)m^9Z·9ˆŠ!ì”Òé¹¥åGëlThÿ*ó[/g?Þÿ•Ô¶ë.TVàÿ>åEŸè¶Ta`ÿEhN7Á-ŠÒë4ÅFãöVTR`ÿcó°¨á}2lFгüÔLºYÅíª…kèô ‘Qs0gNô®²jýd"moP3Ö?ôŽrŽ,‰PÎ)†ðP·•Ó„N‰QY)Äí+9›ÈtG~:l‰±0DÞyÉÖ™ó•)ºH‚ áZÍ„ .xÿ,£ý5•êDð¸¸7IÃUêíÚéc6g*; ßHnÁ,~çà¥FÅ&é©Å…Á!Á€‰Æñþ×vØÿ¼Ãþ—ÌëA­wIDMMç­yùXÿÌþÖìC.ÔÌZ„:¬Ï]©Læ[æpR H4~š!ÚáÎ6C”Ù»Ð3iÈaþ¦S¹mñ »í”BíXÿfd;…rB1ù!ÖŸZã’žÈù­yíëd>†Þ&wìû= JûB¡!tÐbúð¨ÿtîÜ…ÉA7í—(OÄa>1åH'-!Å|‚DCš•ƒü!‘2×ÉIÇ»Š´PÃè,É'^=‡ˆš¤sf(Ï¥\_ Ó]'®(‰»¢£|L9QÙ(¬üz×~vŸQ…ECn7í¡Çù±4&°¨ïÒÆTyxÿ®Ãý-ñÒëHq³ä 0 ÓˆqT¼búSp³ÛKÀä$’ ¨®+ˆt C)! 3©@AŸ’¤><艜Ë}•;àªsñ¢ëf>|1‡úý;œDpà. ‰…X‰Ä™¥0¹õ¬`¾¾ µªqû‡ûQ‹ø‚ȇ?;Ý@(‰£è¤“ª‡úMüW h‡@L2 ð…Àô<‡û˜‡ûù»#O±^•ƒ‡úyã‡üL.P‡"(‚#ø›Ò¡!õŽh‚%ª¹”‚<2K¾‡46³£¥ FŠ"=Ä£o¥8…ø…¼¼HšÓ—Š Y|Çûˆ"N‡øËœ …“ìsp؈!‚ !ј»¨úH ˆŠŒ±€­$s2‹8à‰³sš±ø¨½8¨Œq³ššŠŠs“è¨È³)¿iíh‡jqˆ™ù9ÉKƒ±H# Òp¦`ÀXÄŠŠ]¨$‹6‘ܰ¨…0‰™¹â(„ 8á~ оÊ4 ‡ù£ „{«º4§+† ˆœªÁx‰È³@§ ¢<8‰ƒØ­ ;¨¦ñ÷3 s h‡Hˆ¬b]|¬ùÚú*TŠˆ‹ˆqä(­Hj Žœ»Œ«ì&j!§pŸò”ˆqÑŠŒ'Ò±°Ø‰›zŠˆp–É1C´BŠ-|ňp; Ò¸¼2IÜË9bˆ™Ë¶áè:€¨8*ˆ*#EŒ(ÀÞÌp)â ¡ò^8Ìz)00‡Gû ŒÌ¢Áíü¿Åx‰Î[Eª¸ÃÜêÎŒˆ™F;‰ !Œ·tTû‹‡ù¬¬Œï‡ùS·XÅÂÞO9S°(«{$8‰¿Ô4‡øI¡p‰«[I‹é ¹Cwt&2ñˆ\å«0â2|6§·ˆ!+·é^§Ì埂X㥼˭A؉ÃÃ7ˆ$çÎZH" £Ò»(¹ù{D™d½X¨à¯H‚9úRŒB!Ì“ZO$X…ÈhÔ"I;¸¿Ð¨ ©ˆ$I¼ ÍSø¸±:º[O˜è‚°‚¸ºƒÄψså‡û Ë,™Ê\B?ò4µœ Ò£"8¨ÒjŠÓ=Šý5KÅ7 Ôœˆsø Œ9‡û<Í e ô𫔦ù ‡úÒüFIƒäžKb*ÒÒ«Òžˆs“ÏÀ­7Ý3³Úi&첫YµÁH‰¦Ø¯])Îà˜ËÂ@‡¨¨Âr†ªÝC.TÔîˆqøO#üq*’¡“ ¨Æ¥E¢ ´Éá³Û= ˜ø¨¬apAƒ F‚‰ŠŒíÒ(‰Ê¸H‡-lˆr Vbú“˜‡­I¸]4ý>Ò„KÔ;=­•27Qî”m„¦Ï8êˆtxN̲¸€n!:œà0„%©°¨›¦ˆšy’°S¤L¢ƒ3¼ýÉ ´ùÈ/¤É»SOš€¨Â#F#Pöœ@X3ˆ›ª¨§;Íz‡û·Y]~úê¡':$Ô¸ôǃÑ#ˆ‡Y<ã©Cˆ#à´¬ãV‹¢GÓB•êÙR—¼©P:4ú4ƒ ª€—;ãµò- Ê“ŸÂÄ"ôÉ}_ˆq~ˆ!»,«tˆ"p—[Ñ×;šÐí¤ÐB,Çácˆ"‘ÕÈö°±zˆYïQˆ…•‚4ˆ#–”[7à…‰»ºšûW9«$É–¸‚Fôh‚1»áÿ% Ë2D=0­2íR²ÁìÖ뾚iÕ5« ‰j ЦJÒ ÏÓG"Ѱ›xŒ¦âߎûùJµ‘Àmª Ý  ÕÁùÒ¨ùI¾eÜ^$°Í#ÈÅ|>öÞuáÇÕݦ˜‡V¨D* Œr9íD±xÕu©Ô§¢¬®Ë€›C*ùØ05PÜ›_p¨¢ºñû(NS ·ƒƒAø¨¿Õä‹O]kÐºË ÑçØZŠÒ¹·ëÇÓµK“hP%öH³~¡¸9މÙS‘¹+oUÉ?ЉêýÜ`%ö—bô›KŠŠžH² >rÎbrÙìq’2…=ûõšÝÌb¶õD“h„¡Š‹o/¢!;PK¡>Hµ\ÙS |‹4úíF«Š_Ì©§Ëd´‹:ZܪU•ƒ¥´]\¥®4XŠö9™Ü:Yʤ“¥€Ç#BÆ{ c}AàÒòGÜàט‡X5S‡ú‘Ûªë ©/×[ŸÇ&Ò›a‰¼àÇÉÈHixdJÀ€…´š:1±‡,°…á¬>Ü"å£å_ÆN;[H—H‚:X¢ÆØ‰4lÀ‘V[ˆ$ zDÇNURQ$\‚Ü 2AŠŒ`ÛÞ QÄG ‹’¿««‡øB^ ÕõBMèCãïÀš¨‰­ ¨Ö!ê^ö•Ä5†q‡üðç5ိ"HÞ¾ ‘¨4 \< ŽB&>u6MrP¸‰¸ VrÁæì Œq!^w™€­EtLSYí\‹ÙLƒJ™ÞnB§ ²° µVÀ’ˆ¹é®””PÁßôÐ?fv%©ÛW¥Áq=›*:ˆrúæª^ R‘‹Ùu¡Ó‰ê4£ø2¡¾HÀ¥Tß=¶óø0[Û”J­dø­ê@ÁEäîr±Z EaºŠÕ¯ÓÆÁÏDVÚ¨Ì YBV¿‡ú¥V#o;‡ îÀ» «qãEHîlR­1Tô®‚%Øþ4›±ì:nª“¨‚Eû³BÐ@å%S;R‘¡º-¤À‡PC 1Äv븸#¸üø> ä$`Ñ#Ø»ÿÜšÛˆp…E>`,m³BX…ÅþjKr±AäЪU$†’È‚né^ ¾XªK±³¤4…íu½Ì°„09¸ãЉ𑠕,ìšL­£…æ/`¨ç’™WhWÛã)H¨Ä3ºZt´!YŠÒƒK*z8r¨ÔnðΤ˜pT¶&wȾqÃêÙZ'äÆiAˆŠ(­ñ0 ‰¾û‘Æ ²ñfR32žŠ‹ÃC µ/Œ¼¯éÀ‰œ0„TtËp¨¹¬Ô%¬åƒ€­4Yä ˜¯‰`ñq@ã¬iÝÀdêN[ÄuùJœ T—/¹¤áFB›É§*ü娑šÕx‰­²/ Ó‡Yp.(¨²+Ê•î×ЇMìq ArÈâColÉæ€tª‘ørro®q:Áuª4ñá9ØŸ6//6¿äÁÄ)ùÄ›žîÃ×'òp“ø„iCÃêpÏ$DbQ' yZ6˜ëÛr®Ø‰ DÀ Ä™o`‡r‡tV' šƒ*.Ÿ\¼À©ù¢JÚ& «È‡;¥+ˆËˆ"´ 9©Ä#Qê"ž íÊ!2ö2’\(cþbÔº]ˆ®æG¸‡5Ë쀨RBãê¤#Æí¼Re¨…²[¸rFû‡ Ϥ ‚ ëÏuÇQÓb£‚QSÙ‚YyV°„@R˜¹LëvWÔ¡Y(ßTW*ÔŠÕ\À÷qž]}Àk­C*)XèsŽŠÖǨ§—FTömp˵ORpµÝù­ÊñpÊy'¾†ÿPQ‘.Õ÷¦Xˆ¨Ã\¹(F ¨ÀZ+„êÏ™V$àSgý(†Ðà)A¯ýéÖ«åòð¸«öÌk娂 «ó2«á÷‰èËãd‚NËå}¢Ÿö2*·h:¾MíRù!Ÿè޹«^v‚k󾯉"ù"éH¿È8ä¿'÷’m¯ÇkÙ¯œ0¨¿(>Õ¯=êpó ä2ý/Ÿø’œóYº8¾?™ºn¾$úm/‡šdƒ«ò‚A'ÿÉ^¯Ðhg ‚rý×ävo–¾U;ü޾eiý`CÈA{| éY­@76AÀIåøNÔ°lS¡xÉ€½_RéWƒýMø2?Ñ wÄöH@A¹…#ü:å´ýÇøÖ å´‚,È;éé$–ÔNAÃtâÚªaþGˆ!ç ‚lƒÀ$AÁÒÇ ‚Lƒ¼¦AÁ‹±^,Ä¥Bã"|Q‰A`ƒ¦r,;ŸUäi<AxA܉Ãü±F AY†Ä5xð¯¡sá"„i:Dt?Ý¿ ë †“˜>Wr퀴øXF“aj¤âÒVA"“kd$>EòCT°ÿ75˜@(AÂÔœ ìĆ©Ø@F¡Xÿdi¨‹¦HA‘…¤‹°øÒF˜[8,ÄiaõCI¨ Ú+‚ü>ža|…å\¾%Áÿ7 ã¾h„A—âEKâï=hƒ•âù7tÛ/Äô‚ Rø¨È!º›ÄÛ—Èœ?×\í ó‘2ÝnoŽ€5Ôwh›”HÍ"‡;òQ¨°ÿãþÎ2üZH }/Êd‚98ƒF×Óž]%ò@ˆƒPÄQ•/Ò,äR²øÌÚ˜ÿŽd¶ù%H;U/”à¿RÈ;„/‰@”Âù*$ž/Ê,‚ùö®ª)û)q˜¾.²H:É/Š RC"LH$àálƒ€¢$¨Õm"Eùööôž à© àƒ×—Ä?ë`ÿlê¾/ê}ZË |L((ƒ„ÄEWSa Ê(ÑI?Î!|¤*ä‚.J´?× ¤ÐÞ"¨vH„Š~ÅUŒ®Ð俲3©¡vöà‚<ùnˆ!`Od9‚„C*ö/ÊÜ¥ORv¥•Ë‚WHŸ‚ sH$çP®ú H:« †¥wµc2$F­6Û»­v'°èÌÀÄ`“H%b¯DhØD²n- oQìÉ r0eØ,5ïù(A$ ~ „Æjr²A"Dõ!¶<±RæC[Ó†Žé؆Сÿù!®Å`Ø Ă^Œd¶Q2Ý!¬$‚w‰i dì:]ÚäAÂ,$†ÞhDZàlÏAÿS áø/‘hÎaÿ/Vð –H¾7Q_–1|—÷¿B|Æ_ªaËÔyn¸S¶_Ÿ•Êœªh¿fY|²‹õ€ áôVó7eݸÍÅ$¿X[?Ì‹#/%ÈC ¥šD î”Ïþ´KãËÓÅñYùre›š;ðHYAþ¬ á\åM`Âø”‡úÿÃþ/Ž:[‚øc‚Ãaþzø–/Š/Æn®MÜ â‰þ–Ôa¢ü#6/à ༭D˜/Æþ÷«:mãÆ/´ÚOšªd² ˆkP&G‚ P, ægéœ büð!þ´ê–/ȼðŠ0ã ëj/‹xwŒ(/ÉtìÈ /„|E%ˆðxq &«"ü}k£ ëò¦ ð– Šènå¶Zo«Bü`¢†ÐÈYíŽd &H`ÌÈàÎ:Àon\- §òÌ+®ï8 Žä}jBÖË/„Ó aþ^êȸ²"‹iìæÁþËË!þÁºÕ1=°òÍl…$à‚+Ú¥1fþ§$¾B°tÏ(ÊéêþZ¢V m Ò‘7ÂøÁóÀ¬ÍÖ$ê\ž´ðéäf‚h;"üP‹ûNˆ“.jP§ÊâCÐ/Šé¬Ì§SŒ&)ÃRS˜ ‚Æ/‡X²e,ªˆ/‹ PÓ– büZ2€Ø”ç2é òbüÄ 'I'ºèï.5 ”³,!BýóŒ„i Âø\ˆîÍÿâÏRb°Bü‘©Ä ‚ü¼#T²â<ì¾GáþÑøÊMl)çXÂýAþ÷b|íÄì"ªAÿ †¼‚øçüÀÊ^Îp ßÂøûÇþ—¢A0®ÒòãòÏŽÖ¿èL/ÍÔŽî:`õ|—¨¾„‚ûÕ_ &`€Ã`ꉀ„Å7É{.-x$Æå+uÞNw±NĶê3_.‚Ä oíxåJÀ+ÀQ²€õ%I#!þ ‰‰L5.E/…‹gÆflE AþÀ1º§)¢§&•¥!­’Ä 0Ù1?]¤³‡—;/ÚœIÉ‚5câicTÊ"´ ”›‚‘¬+ÂÊ!¦£+Îîóf%KGKabªä!«ü”¢¼!ª~êÂ\ãx!®TCæyÙH˼?þd¯ƒ$ñ.T„SÊð ët/”ØS*\/Ù*hBkË llÎ/Ö‚/‡íDòÐ Îycu'O ¢5´2 ”â/’Ar¼Ö‰LæNY/üêA/Ì¥x±”/Ím*iMÏh k%wp»#àD:/"üÂÁÿ70Û /“21küÒgwy ¾/ÄÊÞ7Œ/ÆÏb *à ìîfwä/ÐÇ¢ í*Áw¸ÎçbB/ô5óà?Ц|¸œHÑ6ø'+´à0¦ÛÆÂ7,ãr8ÿ­ÆðÁ„Tblì/Î:oKG êVã—"hÑE,7‚ÙŤ•Wö/ÖG8ØW"ø,ê ÚÁþ$JžêòZl/@ æð ÉFPøˆ ì×F°˜ òZoæ*˜¢@ö…÷A„8(ãt|^¹,Y Us}þìÎ¥&hi$8,•§×øÞ ìX}sÉ$.ÍbÆ%b$*©Aþ?Uå÷.ã¸j&rࢠânÈ%ô*é>â2!® ÁØãD/GÂA±bXÔEi´lÆ!ÿ1î«^£ o«| èæ!¤#ãØ!¨^x S$Â!´ÙH+6“°!¹6#Jr=Òަd ëN!´¼å¬á.é³$%hXZ¬âýrëãMèyMAšWáš‘¹OÕR‘" ‡Ž8ôŸ„øI'ƒ¢ ÿ<îü4°©qšyÁ;yÚ®¶ë»yQ‚ùìsŸ Z¢ùFÄ/‹¹üv15 42ùud•Ÿðz¸ùªxTŠ‚§°ÙÞØ'[ Nþáö;,'¡¯2òŒÍz „—’ÜÎÐþ‘õb"ùoIbŠÏ­Ðæ’áª?–Ë Ú=|Llêlµ~ï¹Ö¶Q]nŠ ë¼ÖÙºGÍYxμ u›¬äðèx ˜ƒ yÉ`úMhÓh!çy¢Ð‘k±* íb¢ÈðäËAø´ 2SàÏ] ÌI + AþQ¢ù}Ï‘«> õª¸¢üýªBÿ˜qoìÀ_Šzóí79ц4HßéSèï$ãw€Ô4 uÑÕ´‹aþ¶±¿wªÆv¶˜’*# ”¤™ç«'ÝÂ<†ë&'.o÷õÏFÊrðâv!«KÉ\ëkJûlõV!°›¯kü~‚%®ª€Lv ìú‚ ~ù*#N53&9msî!²½hCqû@29ˆ”ä4ì> ›*†Îês4aþ÷³lõ—U»õuòÐ˪¾tW¾|‚øÔHcvx7­­f/ÌU0/ÀøÔ ãH/ŒY€#/Ó2Øs»|Âø”¬îŒaþäBù'ÎxveZGkĤ/ê\¢üB¦`ÏN7šÀLõ__vöáz|]%I´Ïó` õV/”tèQÜ'.ªrôV",µJ]è…É’  L4/ÇΎΰªCNÒ ]Býµ+1WÓ´J¬/Ї›:íË'û{¢ù‡îÍ—߂ҊËOù/6ó D ‹…åÉX"ùÌ¥vÏL/‘âpÓÍÎù)+Ëü„rbfé£ÂeR¿Åȧ¼Ë²Ký‚ÍA8ÛÉG–»@cd`Þ%  C€ÿ¯x-$+ a"øæ2ÐåèR ‡³sÀœ\¤6Ó%¨^ŽåS.»ô;`T ‘üoES ‹¸UQ$U33è€ÌS’C%»˜“ú#E|ªŠ¨ÁœÄ ´ñTúb½.9’ ï´—µëmáþ•®åÑ'!íòO”¹†Ëòw›ÊXâ̧bõûLýôÙLV¢ŽèBì!þƱž!¼`8—[ìoßìæ €ÓcGøþõí°ù ‡¢ÈküÃ`ESqÄT-{DQX|*%ŸÑRT@QÄ1Y *G ‡Á¢P ¼V uÅOÑ4UyE[1ìVvÿžÁž‘ìT­"ET”JU2¨¿êp¦äT·ÅUDVnÿ¦Î£‘WœAÙADqVüAánˆJàÁجvøŠ”j‘VL@#¤Í¢¯ø®"Š˜" «ç Å^2,œ@)ÅR±^–„Ðh¤S¤B×Á?ïù(6SÅI4(ƒŸ+ E]ñXd+SEXü\¯Š‹â¤Èª©¿ƒâè¯ xˆ-â·ýÞ ÍÊEEQSœU9éõ¸ð äTFŠ©JŠ‚ˆƒúƒ=ÇùÆÚ" ;pŠÁ(b ¢j*}"¥ë˜Šºà"N# Hh朇¥$oÒä… ¬ê*\CŽ: "ªÊ F"ld¶ühƒ<ÇùvмOÿ Á²+ Ì|Œò!B *W¢ ,w‡ˆ©tŠÂ’4tƒ –(ªfƒ@çùòŠ…ËR* ¢³Lz¶ Æv¢¡ÄÄ“ ’äƒè©ÊŠ–Òäö»h©XЬ¨2g1Ũ1¨Šœ(©ÄЉóÙ¬Š‚R*OrÚ ÓóØ>Š“ï\öDëJ õLjª ¢ 4öÄ Ë¬Ñ=ÁÇú;1ˆ¤öŒ Àu1=›ÈªÛ1´(2«1€àNLh0Jˆ¨¬ Òè3R… ŒÚ*g"J "º l¡O" d¡WB@ Ã‚ SÉh‚k"2 !W1ÿyöº, ÌR<¢¦­ÒŠØÈT¾Þ+ƒîJ //JÒ ÌX¨‚‚ƒ/·Ž.ˆY§ø»¢¥[®" z u"§!tFh€gc¡OB nŸîŠù¢›\è€hŠŽÈ‚bƒ¬ +Ÿù’:ô«øŠÇT¨ƒKâ äèVdƒ-¨T”ƒ?è4†…*! l™Ê¢¡ûˆ…A1¦†Š¨¨4…¨ÜŠ•(…7Álzžbˆaÿ2" >«A"Z S Ê V¢’*r"»"ªcGø¤ˆ¶ â‡H©iˆxšt}ʺŸî ½ ÄÊ!FŸýç`ƒH¨šˆU(7‰ªlöæ”’RȪ^ƒk\’*!! vÖ.]Ãd¾ºhW'L¶(7DƒiÒ [!Cê*h"¦6äƒn(7#î Ͼ~E_Èÿ$Apdú xãüÓcò?Ö ÿ€0,#W?ÕÅGŠŒÂ+`   άƒ *è“p¤–a@õ_ÁVJ¤T\¬¤öH0f"¥ì÷‘VhAŠ»hVìÔŠ¨‚ :M*c[/¤—Õ$žáÿr#M&4¬A‚©MiûDu˜Ø™9åÕ1¹h"tSz‰éŒd=b*¸S!‰ÔųâA™„V"©” à.eüH À(ˆòÊBÑ$Vµ² •ˆRƒ!R“2tdy’„´…F¡þ€ÈQ£!NÎ@“"*Їú¶q’„Ї" Õé¤ ÍJ°ù2BœÓEzd¼¤˜?Ê<“LÒØÉ¤AŠ ¤TC0$ÔÃ!Kªb·4 Yˆ€E"¢yÅY“-[´XD(`êD\³lMòi#èfÙˆ««!Hàƒ=âB¢pÿ`€ÅÂBÿ3„)}ø=Ø¢Ú"ð–r VÈT‹ Ëm3ÐhO«K Âh°C7œD\ƒ"ÚPù¢£ Ù Šãü}‘P®ED¹y2f’þA¡Àÿ@Y‘Q‚Ei¼µ!QE'ù8?Ä”×uô\¢‘þÊNxÿNÆêóFA€YPXŠ‹Dü?ä%C"ª¸±Uñ kwŠ9ò˜ 1(Ð"nYKQmŽ”ˆ ‚XEd¢ºbÄ¿"¡þˆ[,cþÂÆ2+"i ÿäVÉ«’*pH4Ú Èhƒ0êKEˆ5èÀƒEK?‡ùŠ ÎÞ'Ù÷€?ëhÿ5¤ †6EXœHLvTÕ’ ­766 ÚT÷ìÿZ(LŠŒø6³­¾ó¤  «ð¼ƒRþGÓ ÔþÖËU ê{7Õ‚æ§¶©YÒc±ªƒtÇlÇú“Ll€’ôÆ=Ȭ„§ ìõ>ô÷ GùI€ÈØUj¥õ"$…?áþzˆU¶»èêCfA“ gd3ž™¶cØÿŒE”…Qþœ üä"¬p…qÿNÁ¥¸xƒbì`DZ‘äBa&DŽ;!dW¬~SãqŠDV¤«†(L"=›‘P D'Ωè^Y󓈪§!JÒ<‚!sRG0G‘ høfi¼ˆ3 šÈQK°ÂÙZ¦?ìòjÏ„+?hªÒ?ÜàÿeÙ£?•Òšñ¥éüˆ”sŸ2x!XâCÆEU•ŽÐ9”tEn¼+š·6ê70A© L¶b–B’F@ Ùè…8’ v )éãÝr+‘ÈTªÙnã_@J¬¶Õ!T´ƒjøGY¡9Û˜lƒYŒ¦A„^§B“”F ã[Bbg³Ò« Ê?ïå±]ÎQQ‘[ù“GúR Í|êMñb£q#¤ƹ¾:¶ù†¼(º:áÿGýœÓ‘Yr¨¾Ôu‘Uè?ù» Å%uÌ2 o6a"ª±¨'¶qÁÒ5Wƒz"§¶ñFø¯´$V6¦6ÂCˆ¬Y?Qƪƒâ*bì°\ÆçuüE[Âc™÷z4ó¹jÊêcM©5=Ø-‚hS½fIŽ×ÆD…€y0p‚í2©UËô½ó"qdD0e2D¨Šê!ÿÇ,[Äyd(ÍKæ™IY æ(…X"ßAC!S$+t§\ƒÝ‡ý9.¦ðùÿØÇø{"4Šˆò!™ §&G% òõËîâˆ+Aåµô²ì‡ÅîEEw¯"¾Ç:nt|9¿ÆÊÄVûL|tg¢™å Kú±7.îK"ÂÁ2!GZâB\êò) ïõ(1ä Ñ´!JŠï>È4!QáD’,: \"¥h!Fšù “~çÚßr„š†6lò_IOˆš¤Ü`ò2"x ÃZ!J+J†`Cw*Ý"2nßG´Z_‚Kª&¢  eË»iYGɦåÁþ‹-t~b æ.nÅÖæˆ~Rp€Âí&ÑËOF€ â!Aþׯ†Ë.WLaÿ+4÷i­GÉÃOPHpâ±ãjšè2Þ"¡"Pƒ/GNìðhƒ†!A"«è:áÿ>sÔ»OXBXnù¡þ;Â9³_YkTMŒðgWF¨B”È Åz\ÀLÄ`Öxà¸Q Èb#þ»È½b¦ ÊN‡,>1T[ʪŒKÖ·†ÛºÇP¿Uÿb XðSA¢ ïFV ˜ǵÿ,è"¯¯ëy0äÒH(ĩǗaHÜLcsSÈ¢Œñ7 HöOmÆj“[6lOfˆr˜"´é@ `"¶X ÖP²D÷S?ÄöºL4Yñ, ÊÉ>0°äq–Ln¿$örÑ/åª"£’Lrl€_ CN!O7®B3ðmÿQÌÏÖº€ –” ›ˆ"Ol9µ‚ ebÜÂb!Ih 5’e#’Ø çWGZŸ¦"çY0z?­/o«×Å|#B Rm+„ã“£+‚ §oÚài»Ö¹pÌÍo°·æœp -kà GŒµ0«" 9¬]>l•£,÷>u-=MLRà×]JlÜ!UÂðÝrWS³R"²‹^´Gsx Ü Ñ°ì ØT1YI”Æsz;õ”é .®/'•ûqbÒ+`Orì4ø*œö*úAþ¬ñ„zƒc|7"HÂ6úpk óSBf£ØçSæôÅ#>’gB )·¶ÂM°ìlÛ€Y z- hÐüq(ÅVÛ0Îâ Öÿ6FRæ+Q’´,.b ±RýKæ5s“$PÍB«óZÀ¢áD2:¬„¨…8hüáþµL"ªŠÑ­’Pe4©<¡þ#t>B‡Räît×xfLhHK€‰Ä ÓìLjœ”‰ól«wAò:F„Ç òe@LicÄöäñ^$qbäv˜¬¢äLvj¹ _ÅL'Ef Ç’"  5„¿ƒ!Q€>„Ö!ÿ/X[¯>3„2K ’W–óíYâ+‡·äy ªà‘Mü¦F>1" —OíëTÿ^•öy7Q“aÿZ '’uǰçð®"Ô¢lQ—6¾F#.äb³u¹e]uýôŒÁÔi¢¨4Œã‰÷ 0$"–2±˜Áÿ_y°" 5RAþà•ß 6†¹‚_qnXŽ\lÒ" r›ðŽ"¸;!ëñQÎn¿)1äÙâ ãŠr–† ä‚:ÿq¿—{ó}tá%ódrcÐ!H°d«’¬‹DO¢úîo_m”Áé ¹üüJö Å:³´"+ÐêȵèºzFd `@¤@ß4@b3ÇØáþgÕcÚƒUáÿ@ξ»d7© P3B ù4Ñ%¹xµAÿ?.w© ù‘‡Û‚ùúQ:]©_q0ƒ+ðl„ÇhHøzÔ¨5 ‚*ü9I%:LsKhéòh¬<˜ì Ç&Gµ<*q[:³e'Ãÿ²üVÞöÊž­ Ot“*Z¿ó/œ$öNÐ Ot A(k‡ h©J!TnêÕâjꑱùÚ©h—)Œš‰-™Â ‚¢»I@ã¶í,±­O ø‰…‚ b!Áþ1µ&𲀍AþkIv qNc•B±©ª*m1%¨ZÖñ¡ÿV¢ ~×Pv¹m –áÿ aÿH!þu¨¬/t’Uu¡'&DÔ‘¨H¶0HkNŸ¶\1zü" W¼[z"¹áI&u›#Ê<¢Âk€!P¤=²*½‡þjâ*ã\!0ΪWE·{ý¼k¿·W7$¾ø~þËç~"¡ÀÆ Õ©%SµC5Ò6"Û5k¬é{fÅ^†ÜA0둵©È£Äôû…€mm.œku<üT!Kñ‚ëÏ´© !J’ Î JƒØ×ò®*«Y+àȣɸ"o`½´ëN2ÍÏ©©Ï±R¦"gZ³ÚÏÀ¬gSÌlºF0=‡#†P~šÆw‰©!íÜg'ŠAÿ‚âÂÜf+ÑØ}/Å$÷ êrØ$ƒ±«G~v¼€-ïhõöÜsÕ!ý~h$v75 z1ˆÞ‰ÂŽÉö“,¼h‡¶c "©>B+J+°V¼ÇéHf„Ç_jÈL¤ÇI"Â¥äÆï®' *ˆX¢šÁb(…˜ªg3ÍÆ¸ ?ÊJEM„'ûòz#Óz!vDM°BéM9ð”˜òŸQm€Ä‡RC­„„,äâ‘Xi¦íì„Sþ%Èr\]!§Ê€må1|ôT껩/ÇüÝæcüIkGû´öFzö;ޱæ>cØËãrëHC˜¿Îžn9–LC‹I+ð4‡ ²zŒY ˆvø¬Õ’ YˆBrâÈ…\BìhÿÇJyâ² pâq@ŠÈˆ´bâ ]‡ú½!µc DMŒlÈ!Öh„J²¥tYV̺$‚C#üâå³®&Ƥá BÆQ²õ`„aòºA@ÿÌZ@·ñÿ¢UE‰!sË!LÇ­Ú !a¼‡Oaÿ‡þ[Áä;Yú¤ “!Å·XÙã´kÎz@ËGjÎ(ôÐC¥\;0ظ„TÒdB)ž@ÃÄ:WùËgHAãe- ƒrÎø 4$§Ka€61Ç”´ÑDB±Öœå ‚Œ‡-=ÎH•‰ ;s=Z\C¤Íáúì„ab”°oǤ:’'S8æáȦgq˼Ùrp¼‹´„fR)Å®© ê¿âøC®ÆHP0c`]äœ$éVOÐñ8ÍŸHBCN,ÛEE1¢)Á-Ce|-õÙ¿?gÒµVÎ%°…»öS¯ˆ$rÌÏ¢R Øö_ÙÝÂýä~Aðƒ4t,¼˜µ•fÛä-É0ÿ-óõÁJÜ‚^Bõá/±T—rh¼ݲ$ÒCÿ¾B~B -ó:ˆ'S‚Cªéæ<óÒòEÇHBÖ¢$kÓ² Gúb—ØwO•ª^Fxnd"m“רò†Ÿ8?ÉXQ“ïÉʾY™õÖ蜿GMDKƒHbÝûãýyø_óÿ5! ?ƒKFBöóü“kÞïY:HõÓDLc.‡p…ª‰CA? Rä*½8ĪҺ"ÔijPÎFX‡DhÓ²ü·Á€ÇYâcì‡ü„Ax¬ù¶í7ˆYä«„áºGË‘1ù²¥è”Ë|`‚.¢€§È‚€„0u ÒÈ©2Éç(À‡"CÛ*ˇE(Ê«c±RwU#.à‚è8kV%,µ¿C+CyÖX«?L¼x‡2<6#-*U0„ ø‚C€‰`„ÉñÕ:F‘wKÚ{󧔆¹B·“€‹!=ÔïJQÇ£ ¦¶SÆ‚^[çËð‡ Ô໸ÏR¿Uý¬Xäçe4æ;•[½Šä2% ™sE–žQ/Éo–´+‡ü%'oÂ(‚ñ¥H‚C)Ö ,u³@…¤¼²˜…¡áŒerñLgˆC¢ŒÓðÔT3. "R¼60›3`ä^Þˆ‡.…îË 1ù ‡X‚aNa[!’ä£Þç•Ú|ˆuÂLœ(,]J(‚az×õ~¿ÞZTDÛO=ð›Qº{‰±ÑµCò&Ü#‰½Ñœ! bZ#™½u€9ù‚xžƒuN½{F3rkCfœD§*kÖ¶Ç¢4Ú½lëœzè/rÂv£©)˜Ä¥ÚhµŠ¢29Cò)ƒL—]Ñ8!«cµ[‰¤ZŸJ¨†£eñÝô½Œë–a[þLé[“…å¶saK«t®×æ±ÊµL™¶)€…è/¬m°‚"™¯( J˜‡$\d…¨¥)ì*•™©Îܜۀ„'Dsš]èM€[½#SB“UH…Ò]Ð,AˆZ lŽ1Ňl楩A£/|¡§Ô1¶WˆDhˆ"é#ËŠLÎÚÇ]4O„D¤(‚~kU-$UzOÄlšŒÃ¨>Ð%›)ýJÓ8ãhdåcÉl¡S&ëˆ%/Ö=ª‰l‡J|ÙPÔÓI¦–ÍLl¬¼íºQ€U¬ùÛOø‡Kµ"š¶ýa ÅI½–ëîê-EëB¤Â÷î`¹ø‡úeµ8‡snËÏÆ•\å¬úŸIÒÈé@d„Õ"šd´Þm¹žng „¹â/¡ôH‡þ »¸…ø¯«»}Ql‡·ãòþ$îEu@ÊœsÉ7GNÄ]†íÆkíuÆçõ>fÈ6êÆÔDäì ZJ}ˆ\lP ÇÑÞçˆDzÈB¡³È‡U#dP6‹lÌIdSˆ{+ˆ$h¹ÌùuôÞö6 úyvÝÀ-1œ|Sìz˜z¼¢í»Tè±¶.£Xc«˜ŽïvÃsÆ:°sµ?¨‡ VB–ülD¤Õ¸9Ê5¸ô?¦|b`ã0‚hᦄF+ßMœø§ˆ$sLz¢Z–¨ØÂú÷™i¨*ÿÄ*Û~[¸ßfG&p¼(‚®–"Yqãjœ‚B™µ?ItøŒ?¦P‡e³ÝFÂ%ÊKt‡þÂgyó`:{A!=5¶A‘ïŸý+¢{ËÊY^;z_ +{X"Y·;qíeáftT@¸À5(-J{åld =‘x‘"¯Èÿdl’*€™÷NQKàpƒœ«¿Åd¢èVÚE® –‹ù8.‘â"\„Cõ{5‚—’Q8eÿe‡ùf‡þ¥n¨òº?£TÍmˆÁ8±„$XÌk%_y‘8‹åޏÙ‘ëý¶¹œ]Pæ>:×å@[hÚ_á51#,4KÆx‚5 -àµËTÂ4Û#ä]®JSRá8—çcËkÚ#pX õ\ìf åâ:xÅ6¾<ž%¥h´•@'âYwò„k2;Å|µÀûêÿ Áßá¸[âÚ……!ÉZÞÌ…¶aШ$6‚D¡ øqÎ÷‡0áoHœ.†Á"‡ì8¥ jذ°Ä:YBpé«üc0ÂÏpæä8/ P£°è ÿ yC—0¶´:4ªCŸ0²9ÉeBêp‡¬Æ c‡áÇØZÖ¶Ð!ÁØuƇ!ʘXCA'0,8õ PC˜é̃V!ÅZbûÀB&HpZw…ß!9Œâ"•êÐŒ¬"Ï!‡gahq•‡÷°êìžm…åáèsÇbÿBòpˆ4!§ÓèB.Ѓ„-Udû°Èpòßñ!Àj@ÁÎ$Ø9Q®üÊB´¡RÜ¡0¥¡rI±k"!Á¬‡pAþ¡Áj÷ç´0õ!zP¬PÀ¦¨!ÅÓþ„ ‹hqb‡'®zt‡"mÆúª„¨q°‡ˆq̇Ñù ‡¨r`„Ñùxƒ€Ú!ÐQþRÇçsŽ„ ñù…+˜A™þ‚9'ùº…Í( F‡Dˆ"fˆH\8‚KÈB»5EH"²Î($æÍj‡ˆX‡ˆ\›@!ÔþÅ!’¨¡!Óõ ƒ´z…Î(C‚:HE7¡ &àÔÈZð„¬K¢…ÓS|à‡4b1¡oÝY\!…tÏW¨E~‚: a …¢ƒ ”±ÿdS6U_,¨Bv‚V§ø…×ö<ÿW[¨$‚Œ¨YI¡qz !s6ÓhXV‡-k…±÷Yÿ{!ÄØ…²(A…”r"6ÒUzXψp²…§èA…ĈD|¡vƒ …1²Q!k¥=z¡y þr¡Ãòg­HqÔ…ßN¥&…¾¨@`‡(\/Š!Š œ¡Z>!oòà‡(Y¼‡YçøN‡(YL‡(u¡eŸø±þ³¡JÑ!n©!iBŸŸâRÿ ƒ”„jáB5áÈq‘«g¨B,‚IhB4„Èu鱡zš!Ù’È÷9þt!Çw¡Ò¥ç:pNHrž‚¬gJ‡h8€" |ƒ¦:Ýn\„%HA}ˆ¡}3~‡™B&ãˆuÊ„oÜÿ‡c¨Gš¹ˆG8„#ž^Ö‡HÜ"û‡û|‹wqìzHp™Át(wI¾øƒäòÁÿÑKÄcü`Ãý)†lB 1Tãý÷,k™â1ä:÷?Øê1D8¥qˆÓJÝ! …´Ã^BÎ1Nä!“GvBÁ: t‡B’ÍÈ!À! x‚(Ò“È@_!bµÖ@ ÎYk†¤8ÈH@åHZ«ááŠåâA1-o‚0±ÿ  T4qÄ D4D*A€ÿ8f¸øŠC£8ÿE$ /µB üB‚ „:BåüCpÇ,…ˆ’/È\CJQáѸùJi-$š‡ÅH\‡R$„3%ØC„‘ Ä8`F²šÄi! $‚6aÿH$„X±Y$éHÖ^él‡à‚G1þE ü¢‘1àÞBÅa{!n¾CËQþÞü"áÔ™>†ÞCf!rб÷ÌBÑ1Ú‰.%÷³H"! hE1þâìX”«0‡S†C£*S‰O­ƒè¡Qʆo„!ÂÈX™!Ã66æù=Þ¡é!Ât…“x·=r` ‡†LÑBÕZY †Ãü.å°×^„Àðd„¢I‡úñ! †“œRËGøï”Ü„BQþñù !­žS’G(™  °'°dr€iíóñOèMBdM×é!˜Iœ!Éi¼®G„Bso2±ø.{Ò…U§d9!ƒœåÑý•TЯÃze0HB,}èÆ”!’;f4£!Àуb)æ¡0„!w£–ý“]GF.YùÇÀf•Æ0ä"›EìA *¼“ý!C@A[ “ŽÐ°RiTä!Ëh–ñÿ l+d i.cÖ›ŸYYÀ‚b YH@Zk„¶Ùäßm—AY¥ÕnUÃÂA$ý¸“øÄë®{-¬ãµcüÅ"¹4ÔºÆõ•‰ÖòÜ©  L‚ö^ÜãnœãFd؇ ò*šª~U ÎéQæúBÄuY…Õ ä_²˜Á hwà‚8ÓÎćûER¤.£‡êA»1¤D.°ø_WqQDż’E 6' ˜¥«„âyHAå¹&at¥þjˆB‹•¤8½1u®ÏLs`!ÆØ‚Pgz?Ø> …Ä„CÁþÐÈ#Á!â¶äºôB.™†!¦u¸Â?™ å>°Ô¡þcPþ'! „^qÍçƒFÊ„.µÝAþò¯~k:x¥ºGB–3™·ਇb~È ÑÑÎaÚ µC­‹˜€àõÖe÷OŸyÓ#ý‡­Ì Р †ø*©`XuЛTÓ-ZT 3ÿmƒý‰»%3ôá Cý•P=lˆF! íû¸=YÈBUÏ£þ- *[YÑ‹ÿÔòðÒLêB2 ÿ)¨Å2ã*ظ+A#ÈÇýŽÿØAgF'ÃI&zŒ[à àÊÏò$¶ÈFn3¤ÀÇ ¼Dz¸ ›ƒõwÁˆs…àJsF aA ·ø£]ÈJÕ.! Hªÿ'^+¬Är”1ÿÈùG •´øA&ÊÃþÒš¢üùùt0d‡&jC„±~!L‚"}Ë&G95†R¤Búÿ"„6‚«rÈpd!{¤™R ³‡ùAèqö€BÂINä7DNªfŒ_ !Ù°‚?YÎBÄlÒ!¹ŽÜ?ôg_á ‡½'{ƒèý¶¬€ºBÄå-Õ·w³Î{!-¤"Æ'B»JNzy¼…ÕI{{ò8“y܇7B œ&o«êÌ^A5£™¶øÍ¤ÙŸÐÍË·¶!ý©çP¿]MîäR(wÑÞ7Mv¾Ýò?ÄÑf[ÿ+ñÀ‘.BßÂíaÌ·â _¦´ùûý[ƒ'‘ë4M"Õ¡þvM¶€‹¾ý @!Á¨°¬Z 4 Š® â½ >0Ì‚|§<å¨!Nïÿï6!!¹/|¹¢²pNÁ.ªóBËÁþÇR¯Db¹Â»¬Ó"8J°!懪 JF&vWg$Ù©b¿¢F0¸.žÑÃ"F(lƒØ)dbØdÖ¬ $b†0ÐD– €Ø!ad!ÇVà‹>!hpÿŽ Šˆ¦ ²!o$ ŒöÌåfVÎ<¦ hVîLéäõBF¢ÔªkðܯCÓ‚þTíbk¢•ÿޱ¦˼éÁ¢jþÌæ[ˆ´P¦À°ãBI"aâæêtâa 8·EË¥ä †wÄF^ê( ƒl!âg… ¾ e°HëHÉã(3Ì1Lœ íN«ˆZñ)²òŠÂ:¢Ð.4ï×ËãQÂÄÂu1Úã¶ ‰ªŒ±ÆÛR!Ëþí*Š윊ެ†„!kû«ä¨1îm¢Ä($2ʾ½Éªc¢žFJ!Ênéñ éí­¨Ü,€ ˆ"[™"P.‰µ)Æ_¢éBf©#‰Ñâ ‚@Ê£&´´aþòMžÔ2Ãè˜ Š¦ïèd‘À£+@!Ëx¨‰˜³qŽ!ÎМi˜†@V ´_Ô{ UÉ–}‚lâŠò¼!Ÿdx„rÒÚd„ðÉÄÏÿ B”!Í™’ƧÅÔþÇáþ „~ø¦®…Úß{¢ÃÄ9 °U(Áþh"É)F(´ðPx澡¤b®0‚bÖ¡–H;!þ@ŒnŠ,òôI8ý‰ mÑ0!É.RЏjl ñ)'Ñ” ±a5°øšÂþô׊ ÄK 0e(£ó}7Í~RƒØ‡Â˜³Á Ý7©ÁŠ„†—ÿPÝ8Éc7ˆÓ3vò`9‚Õ)~þ¬MsÅ'ÈÚÿ%Ü!a?êL“O;!Íxçڸ ÑC<ˆøsS¾!² óÜ`Qœó6rÓF™ór!xòÆ‹ˆ"£ç8YÅ 'วó=È"  á`-“t£ò#0þ±áþÅðh!Â5BIM?JL.“žá#ÉH§†aB…I ¡þµ´n—´–S¯1cÇïÆŒ« A"l*â㊊2 ‡Î墪t› ¸ÈRú Š äoÆgkpï*:þåv¢Ó%L€!¢æ`’é±'aþÆ!þ¯4!Ô¨¡þÔ¤¬)°£ô³Om(îØ£îhëÚ >lÀÊB@ gˆ‰œØ4RÍM”š®ê!  iÝ,t÷Ër®¦Ü!NòZìT–6D\n²ÙG’nh‚&ÈN$b¥ÅÔ‚5]2Áþ¡Gè€ãþ̆)„ÈZ­'dc,bX¡š:`t\úAþé„!gV!=l²¢3N¼ ‘qaµimÂF+N¯>7W!jB;ÐZÎ.pˆ0¢𪮗lÕqwøècIT(¡ÿRîu- ;JæËJ"!Ôíd·]\ÙVdºÑÕÒêhLuÂ:l´q§Ê H>× «” èî”äVÕ¸!Èd—¡VŒEV§zÁþÅ5] W«v²|@@MþI$bËP¦•ÄÆ´ÓRÞþ„ë ’7"ø¦‡Ç F)™tô«¬ê~B>#Îj qh:¹–î]LF¦" Wäûj…ZîV˜i]2Š·–\=¢¼ÐÒfF¢[v»ƒÁþq¯6Š‚w?ƒø-’<ж~.‰hþDÂÍçæiÁ`¦`i×!¿6O‡Nµ„…]“€!wØøÏkaø_…X,X¨à!râeBfˆ¸n`Ì4î!Á lMõeO½A·+‹‚¥ŽTrÇ‚´D,ùå*$)¢‘î„Pø!wüç¾ Œj5ä=˜ðMi˜+b X«m?øÉ4ŸôxÙ!þwo^+õ…¦Ú!SÒ çðD=­óðõ6‹tãâÒµF—Ïü!cØÏþ¥Bl%UfuT ’ö3jc*éYp†V‰ûF™´ÃÙUÇÿC T=™w0p&ü‹Ý—f/`ÁÔäô²WlS!ÿsîWr‹KÁþËH'©¾äå†!ÈÀ ¹€”X@ î¤kZZË™ÐvÞ2‹qËP!ÙèѪ^!ÆäÔùôÉÂOgÊþ…w&WC0xDb퀬|òÂ`å²¥d~f Â6ŠˆËC F%Úƒh=“`Bà5è¬B 3+y¡þð¶Ý4}«”j¿1ì‚3ãm­¢!Ïw#( Ô ‚-ËGÊ! ;1]‰²Üû7 !läE˜N!a³/Ì!æäªÚð´é™y¨×¯;ï3G;l£ït÷œ[£)aT¡ÿ©º’Æ\»yFB"§m3&rÓCB’ƘwáþÀCQ(öùu“‰ræÝ©Þ®‚ Ol¥¡ô”!ñ/ltOBçñ,sù2y¼2È´ù¶ÈI˜™“C• #À¼r€Ð„@I¬…”ù\Ü!K)6øÐ!ɘaâ;G+Äb¥’ÎF®œl´=^œ(ønY§¤c?Š>[J‹E°œ×pF-›\¨8F*¹AEì bŠ jRZ2²=RSª¼Æ°6ªG•MHDªA>Ó<Ù‰93ÈÎÙõZŸœ¡Ú2013:07:03 13:27:34 openimageio-1.3.12~dfsg0.orig/testsuite/texture-icwrite/ref/out3.tif0000644000175000017500000032752112271062644023702 0ustar mfvmfvII*€¬ö þæî2F=RS>¼Z2013:07:03 13:27:34 €Oawø?  Ì!å yÂð†Ü,MÂÀ€-ÿ€2<.Èäi\Š\v¤M³üä7‘@0i<êY‘Ë¡ vD „!a \  {ÂÚðéüú…@ªÑ'´J ¢s…Ñ€4úü‰ë BëV«e\\¬Ø` *Tˆ ¤NH\6õp½Vît¥÷s{\áW©çÆ‚.a+˜f £c€9>hð˵®n̼Ÿ9i£y¼(7¨^£[¯dû¨.ð‚Š€MØ(‚¤àq*‚í K§œý‚‚®àUÔ¤°P`R AAð@A×Ô@ ¬*ô‚»/)°,ŠìúÎmXPŅΙºÖ”¬8Ÿ(BÀ“°ì~ 9 çà}€'ÐyGRŸ³ž¨1Η§‘¬mÇÌuÇ‘ì}È …!È’,#ÉL•%É’lp/‡L°x¡¢E Ëò¼¡ êŒ#)b„/)*¯3%IB4$‰J{6­R tŠéº> ÇØ:‘Jʲ*b A,kÂÖˉÝ.­YÌ„ˆYô¸Ì좣H[$£¡tBzž¾@ #>-´½,ά@Rí€/JôþªóLú…ÊÀÞ‘:ušDÅ€Tšõ04W,ƒ¹À`½W ë..`;/aÌ»‚×3L €•ƒNͶ)öKP£Š |Ô·©9²ü1”‚Š뎀é8 1€;,_B ÁÀH<ì¯ÀYžòUÏ+ÏWêƒTù»`«`Ëþ6u$àóZ/Á<ÁÇZP1a¢üCåÎRéžgô*Ô¨yú‘` ú~Ø}À@|“ѼfÉÚŽ¥©êš®­«ëε' @h4LôýžM{ i$Ab!u„Ø–Í2ÜáEnQ€'`0ƒÃ’DŒK°ƒ,S~ÇK¤›6ãÅ'µðp!g-X¹â M€-XD%<êÁºt °Ä´êçDc`"…ÕÀ*Íq ŸÆñ«™³É€PpVV3¹×2ÀQ€VÏeã³u€Ú¯Kã6ð[õÕ¾µ Wo·ë.úµÎƒ\ÕÝu¸“ü-ðÀh ¥YÏ{8®MõM€Á»¢º€ðwêçx9݃º`M\‡ijl/ðr€ <À¹Q€‰ÛH8² 'LX¬`Dœ”BQ)òGLqq8>Ш+1a0¿ ÂBLXúCãè~!P®Q #[Œ}p7ÈÛØ~ DdÜI‰Q.&D؆€4õ–ÉEèCømDv¡iÅ9§TîžSÔ–Àk õ ³TH¼ØHYÍ À´…Ì&ŒBãz/RQn£Ç2«\Ù"¡%¿ˆ q.'q^B; ¨OrDŠ*"ï ë«$@‰MIG d£ž$R’6€ÖC)³$@À¹ªÊï'‰ê¹ààÖ£OÕÒº“ξ~€y-ì¶—j—;fÕsÒv†^}¥®²ÞÒà2ë‰A8Â÷Í,Ò5D×xjAW‘‘¬®¢BoŽQ½ZWKˆrËð@T0F“`ïÈê°£À WÀ1ˆ–@íÀP@AÊVX¼TbqAƒVO@|‚#¦ Õðè5¢U¤2 £ ‚ËN˜¡Èm€V~ë™ûCh£´}ö”>DëN‰ûaÜ=‡ñN !.ú˜B%$ªÕ"F¦B?@Ü'nðÊ q ã ÊùKâ¬}Uqúg€0‘`Á`ÃÃ@éæDºÛZÀŠ+ÆUEbQ`¨Nn¼ÉEC_r”²ÊªÅT°G&ˆ[hwy8…ÞZlÙnlÖDžš°vÝÉ ³Ç::ræEÌܼ-òÙqÕįñs» ü™½]@ü\ ½‹hö 8žÑ¡³>Swoé­Ààâ¨+ƒq*ý¹w4¯  sŒ1€¦0–X mò²ÀtÝóí+4kEI~ÕÊ„P6_€ò#$ áÖIÄš)`05GEi~§Lq;z…^*;TÒ€>Îïmq¡À€ûøj›âý¿ø§a°=&H2HEàn.beld nin­ÂII05Xá!? â¾=QIêˆP„ `"žË ¤ˆzœYj¾Væ‘L’ 6ë*†M¯|ÇšsÛÏ ýK˜‘ "!(sŸI²éÖ—•†cUÌ´°¹Úff˪ÃÐÖÅf=¸Œ!¦AÀ;ŒÖö—Òó<‚áB 1 au›³[oMë è⚺PqvUËZ«õe€t±:NuL:šê˜ÖX >@-+Æj@<º8‹ð”cZfÐ…þ  u pî(ÂA_¡î…AÙ!ÖdS’v<| ñHTån¤> "¹J╱æ°ú aуM¸Ùû_oî$ÀÜó8 [È‚E/£Òk¯I¢»¶øÈÜd"h¯ýƒ+~?UJ#¬âD°@ŸåbD b$A˜¤d%3Žfîg"zsᬸ ÏGHÌp$è:®@¸`‘€,JþaâôþΔ-ˆ,‚è•çz•å‰:`Ð µN¨–LXE|zM*3­*>@Äã6/ L {,ë‡Â[àì hÓËf}‡Ä7¨ÆÍ¥`ïëˆWÌ8¥"_©ÆÖ/ ñ€\9ÈÚ#ÀIØ@`Và‘Š‚<åF¥|âò%\x¢üÐä¢ …|êD¡¢ „1bp  ~@n@Ò@~g@#D5 †Ï–`Â!ö öÂÁLAJ¢‡Àiï»qy¯¶4—É2+*!i˜/ôýq˜Ë¦ÈtÜýÀ»ãvùB•ü%þâ%HLêÊý«5 @˜$Aš‚D@Oð:V):â du*ô¬Êü!iÌ$L¨éª,Eþ.ˆP@”w` @þ€^ $ë'Zëi-.º–0ÿÀuììŸëD–ÅxÑ #2åFgÐÑÉ^µ#d2éxiþÓ å–ᆠ¢Ò¶Cr|ƒnÓã{ crá£ú8¢Œ¤Çí ²ˆ:$°äê„j9Ä+°)²$  ÿÀ—€» @—€>EÒ ¡.5aL@ P@*@`.:`2S`8AÀ H<^êðj«.&V(ÍLˆ!¬ ŒroÄJ"Dr¦2!oøŸé+:±ë:ê›;'BéÌÎ$Sº'0®ë$“Ʋxn¼!e„¯Nžsðf/Eá ÎÃ$"þ.g^r wGu#î¹ @rH.d°µ'¦™ †2댒V5 Ž^`)|4(]E¸]G*€l7¥a'ëˆm ÔE–Ñ­ ÙM\ÉeúÔ†`R¦WÀr  @AÀ#È<VàL S`­a¾m"Sa†Y`&Ÿ *:`,T`2r­¾  <õ¤Å|‚dBNO†|$„rIö¤Aê¡À :`ÝÁíe˜ù¡èÆáöˆAvu4IO´ýO䌠1DÖ-sT«:“ã§/Ö(‰Hb`ÂAÐ*Æ!iÜ$HÇâ°êЬªËRÁÆâD(ò , "D£u:ÑV ðUZ•@Sp.çõh”Bª´d®!hÚÍbEåBx…‹=Ã/ {€cpr²3ýužSgŠ•Ô>õ°e–RJpˆÐ²O\¯ å6*”ð¥\nÙ 5Ù,£r`ñC}CÀ ~î>@ &k‰ åñ)eïr``ò¦Y`5`T`yÀH`8 E@mÔ‘hca,caÐWÀ&5`(Ÿà,‘@05 4V81q ¡òWÁ$!Ú£ ^1`j1`.WÁ>$2æ  ^5¡LlÎ ¦†¶d*„?"æ~@fWÀ`AÁ>$áê( ª/Á1à>@ ® ¡þ¡ÈPB „*,À¡÷ÁùÁØfIaIO–¿†xhû`ò#km‹‡u0΢u,²qBªqÝPÖê(eKnÅLp∑€5*qCÊ7i)lØ’T¡ÿUà ÂDÁU =qײÇ'W6ÏPÇEÐC:“ þxSS8—[ $3«ÎÅŽ…u¸úUå¢Ð‹9@xAš2òw'‘@ÕÄzw|-ràâè’\5ÊÖaº ÀKÝ“«¨¢ò7B7´@]Kx£ŠÁ'à®TL™€á <–BB6*Ö)h6CZpÊhƉhƒäÏÐi„èÚ—˜cB D‚È>¢ Ĭ"ŒcVõ’ifãZx Kl(16·D ì †NAÁîCãÒB¤7&”åUÆ~†DL¡öF!ÂmŒFÑu†º¡*x`2©˜u‡¶É:ƒØÿIMhå}yÉ!‹C‰SSˆâËl®j3º<"ѱR‡E‰XÔ(þ¢Ž”%påÅ.T),Zc‹5±¥åK>VÔ±p7>×E)B0…„¯¥j,JäN„ÎÕ YóóU¥‘Ij/AŽ.eàu¢z7u‘ç¢$áÞr Hâ i‘ñV5qò— º”(·çÁC¥Ô  î2n8¦ÐÉúÂŒÙ`{€( cB¥úmt9È'¼G˜CD»$klpŠƒÎ5¡`­a*ñAÐY`"(À%dV¦ÐÈÞ ½eW" ¡AÁ°:eÌ  ]ÃVvä*KþAÄ& ¡|WÀj@øgdi*ÀB¡ñ„âŠDAödLøEA až–¡”û¼»Ì‰ ú(”¸:BÆL`“³k6So§ ¯Å‰C£Ú…PåJKå p-Šn­%O¿Xë¿§E¿— m D%ÁWœO§âËuš>T¢ˆ—P-mKK¼5©bÛÃ@$CÀCäv}<ç>Sä0•¨sR –ðdWšº/RFÏ…·‘yÎ%¾ 2xÉwºÚµc`5ƒÀü7ÊV ' ˜@ B zY°£¶û5`(À^¾9æ š&7—†–€˜$Âe—Gb •6Æ0BÈeþïè FÐddy®T`./Ø6ìB ä$åˆXWÀb(ÁôAÁ6@ ª  ’1an:`0Cáò:x<;„>!D*Þ„ã…(hDÖ¢i4Å3â¢Ûɼýu×dàtL`yÄçß¾få¾½‘Vd·7•ÒÝúRü6![rõ–!5TDÖo2)1¤<-ÁXÔs2s·D<"sw ÛýÙÄp- sÜ'©d­%…ª¢ˆW‹x“Ø‘ç}ÅK:/W.XöÏ—bêç¯ÀÏsÿÇØÿ@Þ ¡¦,€i`9Ȱt{'È660¶\Œ`,šèÔ7ªÖ©¯¯ãs°;°¥\ÂòÉ‘„B:(Ú`'ð9ÙeE€y€=¸(ÀŒ`*cÂá {° A{Š^(À ¨@$–€$>@(. *AÀ/IÃVr‚1oh ¡”WÀL$àT$à]ëDçt:`”$!Å®( f@Ð1c¥žÊÔáõ„à„öDÁöp¡ö€-õ†]yñ¿FÁ¶¡ïÑÒŠëØ³mÛq±¤‹&1Ø'&Æ¢EÚš's2 o®^%*ÚØÍ¤xÜ*¥X,GyŒ¢R@W¶Já9ì—܇Ūíø2 <‰HÊC“ßÅ‘ùr#ߨåwçà56G”Ï…sákáú²2ã \\iZà~º®^+Z÷wy°œ1`P@6åþ”/%Ö" ¯é^g+°Ãz 7ø wô5ƒaÍÈsŠÅ\ÑQ 9ŽE–ü %’> `· .–;àj×Ü $ºŸ00xBzÀÂ/ÈJ  aP -0°0Ð+B$e$Ì$« @dä0¬¦êÍÈXŠ…ïàâ¬E«5ßòÀ Èý€@'ÅÆÜ~€@'àøý}Ï·˜ºüm€ÏÅè9s€0ÝI¥ÓiõV¯Y­×kö–ÏiµÛg`ѤÝ Þà7‘}«x&¿Òó—*—¼ær­×ýÿCŸè<¯íëøOx0¿Ò7Üî——¼ßôü®ûpßã>°"þ ãõ¿_×7÷ÕÐ-` 4ÈúÐ#@MlШä?ŽØåOC× ? ¸ëú¬þ) ú×É ¤ŽQ@TrN\èÆçâ$àºQ· :Ö¬ ì Ê^jà)EÑð · ÒÂû&Šá|¬„j°Lµ¸ˆ_W`äZ9B*Å… QSz‹”º}K’¹à"äÌ:ü}€ÙøÇžgáà‡ÙvgñÄÎ3í o}_wåû_ø€ hlç>O;Ò„´•lü½P£©:šþ•´#x²B°¨>4Òþ†³¯&8èC8ä2äÂËýTÐ ýaxŒ9?Ù«û‰Ã‡ PФS@ ‰QÖY£F94`æ ù›ãrD¬1L/¹™tY%Â±Ž»"€XXG—¯lÒ¬g$9R´c¶·¡€œÔT­»m2Ù¶7²èmËŒË0< ¸²“:!0cà+ã.€±¨ N/ E |û= àʲÆ"B8BЧCÔ£†Ò+²€PN’Z”ÀX”Ά¯^EƒÌá/Îðñ¨#‚Z` OJ7Z)а3:é(®êÈEl*¸¹b¸o,$í®ªáª«Î@†}®FšÖ ­vâä·§Áü¾\€ò˜qücŒ€üàuÁÐ`úF‘|0(!`”‚U~ˆp;a,öÖà âg zòFh 0l!’ÁÖVP›3Œ„Ð1ô)D?Œ@t—ôàXÉÿ=.dÐ#™Û:‰Œå 1S@9ËùYc€`$¢€b# ð|ü´ƒ˜oÑjbˆH´„j¡Â3Eq@ö´V×ã’`È¡'€~‘†Ê„ñÁ¯¦HØ’ÛyàŒˆLÑ[º[K æF%fú3ã.p@äE ˈLÉp4ò—¬ eÎJP +¨Ç!Ëp8AѨiΑֺEÀA½>„T°€‡^Xø „‘8¦\㨠M©D :@ÇXí `9€ãÀ èQEæ5 Ë eÀZˆ”yÈ¥pX•BWê £QúY¡VÅd!¢.@Řý.AµŽ%Dö/f®?’ä— œ0ÈŨ<‡àôˆ}ð.Gà¸Æú RzQJiU+6 ‘æRyL0‡‡ ²—õù UÐrÓ(½©‰ò<â >h'L1Œ(„Þ&àJuC¨pÄß¹0â\N9ˆ—âiì<Œà D +h)µÆQXe«Z¨1Å­Æs„ž`VµÚ?FfЄA™uM!xR©ÛÿB)"@¥{ Ý‚DH¤ G¦BÖÝ’Ì”iKÙô†áË\œL ñ)P6— XuàwZ©e(&Òq•Å„M¢€2nÃ(‡ ì$Fã°ŠÇÒ,G¨ d`$ð¡œI¸ dcäi1V€¡7 %—Miª©¦Ê(Ô BÐ&OÀQ@V>ƒ„—+"®‚öˆ&*À¤ð‚¬$áhì7 ùD²ä*MéA `xð •ÞØö-d$¹-ĹE_ñ‡&kœ}ÕÎ<‡Øñ8~ À4èϤ«æ–büaŒq‘¶@4ú} ª °/î˜ÎDˆI @£4BSú…M2EVd¬ÈùcèýO?Ü‘U2=Ac•V$‰Pä-#”¿å:É–R+ÀTÐá hð\4í9+¢h32Í-¡×ä$_â0½@®W _Í1B0ÒÃ"}‹iÛd‘Ú)·Ы£±°­âFÙÉ ™´o$Ç´h3„…®ÒÉÔÁ“ª’Ò‚Ñç° z€)d®2ÛZ¹bAP)ÀaëÔ·"õw’PËà! Àr«°y (K^ž{¤Œ›Œià¬,eNOTP+€DÞÎß oqó¤ £Q1 E+.嬛ÐHWAVg€O’ä1‹ ! a« —Òr”- !Þ%ÝN õQ-d¿Ù0˜9N1ãÜ~€;‡æCìX~=W½&Æ|÷Ÿsüf#h=ƒpÂ#!E‡§ùˆÈúIV¸æªçÞ­ ˜/à´¿äLËP2ÖK땘—ûpGQ9«·eÌ×004Ê-!Ð;…wÑ: ÐW˜HÕ¢üPE1Ï7¡q¤úñhE öÔP§€é`l”P[Ñ$U•oi ði{=#$µjÖJê'è›ã|ÛékTâ–]*ÀWI‚pŠŒ r`A.BèH$R Š‚‚x?ÄåXãæâ€HÝ"©||@nS¶vDŠiÒ$nÐíˆ`1É€ÙøðÎP~àoUËÜ Tá+rÞKše†õ%ˆÞÞ0¬H« …µ «x‡éDp®ä0 ¹ ø·ŠáU  X¡ ~€9XŒ\ 8z¨Ø0~ }…›ºA¼ðGÓÖ‘à¿™¡‰Ó§˜{§Àø€ï 22Û±²H¿‹ºP*8šß‹XxÐ%¨£s>²c½²á »K0È#|'Ãk>—¿’™ 0)‘@h"Ò±ë>2C@!Á‘›¼tB Dq­¾à.ÓÅRÀ£RFø€Ép¼ÐnŠ+ʬ²E=BȪÌyÌŽÓ’—-"Hâ“Å=ƒÝ“Ñ€#ÚŽSÛ%D)<²*W‚2 .£€1Ô:j#t¶ ‡>àµ@®éÕKä:´%„a…å·H”¡hžÞž žŽP“  •p ž`  #è N"€O•s®‚ˆƒˆèpqªvŠ¬Ð«PÞ… ä?x¹ˆ°†8¬@µ‡iý4û’ ’]ˆ|9H(«€€ø}†àø~…ôÁÌšI¬› GA¹ ® âá ¢Â¦¢\"Â$#©À¿©Ø¥¸À» ¿ºc¯ bŒât¡ÈôªhаF“;|7ÞIê®â<£Ã¾»0ö;K'‘A:Höà‘@mƒxÐÐ:Jȳò3£¹ Äâù«Ä(²ø:R0D|FÄ„Ä,tG…AOôÃ5¿Å Ï,¢Æ¤{p€d=Q!“ œ ²Ei. "áH=‚Ò,ZŠäY€#]5ât€)Å)‘€1æ(rJ¡C µ¶P‡2ø ˆ ªJä›áB>€L¨€JÔ‰ ÅTa‚<„:Á€e;Y™•p.ÐÇt€yEzm‘¨@ ?˜å¢>§#~@O’øN¯@åóƒT/Ù Gè}ŠÈŽCoˆÌ‹k è+ŠÊè‰HµŸyo¥ä™XÁ‹‘8°ã“¹d“9x€~—p_‡ØÍ‡ A€Ñ |›ÑM1xH€Ê˜éE ¨€èÊ&J-!)œƒ2.º(â¬ñ¡ ä ™,¬*e#Jõ /¼«1Ø ;E$¢mÊ@Ð|/Ãðߎ£¬žâ3ÊÅ'€|•¸†Œ= ,³ñÉ‘L¿¬Á<É€ è€Äút´ Eĉ³Lcͤ\‰æ©€:¼êÈE‘DÉjTjH'JÆD$Â1!”RÒE”î ®zM£ì^%\7¸qÐ%(ø‡Fʉr<€1Z€BD€;s˜k¬ÍšáH à7H"#ÈQ¡ GºPw¸X (‹\s¦ªÏ#y è«‘:’( «?°¦Hy/„ЬÏ0Ãä¯Èå µ€Ùí„’†Á:¨ÞÙDˆ®`®øÞ€YD¹`µ¹‘¼‹“—&¨¬€€€²ˆá“p€ á µÇ¨…@ðÊ€P°€àðø®'ˆD"è…(¬…˜ä˜®ºx@P@”@! Ì Í„>AA ¼]¨¨{Ÿü®ŒXÆ—X~ ˜qàp]‡à\Ù‘àþ pJÀ"±Â›šaE) å^Ú¼#a}ûCÂä³* ©µálª™=)˜í1ZÞ p€ ¥6Zl¿K*3R°ÝQÓ/Ùõ)Ì8Ð<%%˜xñ€DB` [<Á0æIí¶âGݸ2¢¼ý?[}»ˆw È …ôIÜ+ÐC`Ô1›­Â›±W_ÜUJDà°ÅKU’â!Ľ˒åÌÅÑ.ü`âTNâ×%Þ€2áUhƒ“‚S#`•(ƒ¢Ý(<©€C"=`€FUˆð”ðÆâ€f¤HCPf%¸· M‰cp·X€iEf"u`‹X X§H ¨ P "€ (V XK’ýZÑ Þ€ð«ìŠà‹Xd ò¯аꈼ(ÈÙzq@x °ª ÷ŽˆŠ¨˜}¹I©–ê9 |¹À~IS1@ièhàö讄° \ å–I ”©€QÍ#’ø”ð’úÃãAŽYM·!ÞFͤ2]1aù‡þ“> ÐbÎ'"0ªr&âM¦Ó)4=¹š¬D·3þš‘…¡Âé€åœ@h@u¾1A,+´Ô©SѤT±¡ãÃË<…¬î4}@= $N>T #xQõJ4ðÅŒP\0T´©€$N -OÅ®H“Ú¯QÇœ"(nM%ž€(ˆ;ÚÕTÞähNââˆ;ã]™D@asp€BBI˜®HPPGÎàxBàÃ8­À7R…ðäuþ (sö (’t€ ÞŠ8…/„»CŽ è à§€®gX`ÏøŽp¨`s”@U ã@Þ…è¬Ø« ¸¹Kɨˆä`an¨˜`€}‹èÆ —°h~‡X¸}…²øÉ€h·QXK¢³aN—ð¶4Y@¿Ž± ý£ÂN”ð¸Þhèöqö!$l€ÑÒ~+)éF“ ÿii"6©bP½ªÜ@©ìªñ§ )[eêi c=ñΰq5=à|88‡q ê¨('ã>°áV4ãA®ãXÐ<þ²[¬½Xa7"-óKk~<,ÊÊŠ(¸´pc’§kÚGœQÁlJÅC¥êK@<‚Má,­U½¬Ð%‹“’P¸!¥3Î P)Ü‘­ˆ‚~R#è:í=;©ší]Њ£Èm\lyhÎEH€Q”ð˜¾àа sóf-æn ò”Ev?róup pZ XJ§K äá—ð²دЂ( `åHäŒа ÈNf`倫âWHÞá(X«¹Ȭ¨ ¹I‡Æ%H¹ysŒl`¨$ð8~®Šp„1˜L€À% ß-hÞ©pÐùJ©€ Ô1*)»ïðÇòÎrÐâ7º`ß©ê[ò·x—éŽñ(¿œW¢i”ܶù&ù•ª,x¾‹â°ò÷–òß%cTËt‚¥»¸ug,ú7¢cÃϪ+Æ´±"]Û†ÓBŒï.¤µÄ-¾ëç+Šà¼„N’®CÄãUsÕB‘ɾ’É,˜ø¢„[-8ìbLœ"Õô\Ö:+¥d©8”ð"bˆ:€0®2=!t‘Òmùå–X¯P¦Ž<ÐeXBõgJ˜œPx’ø™p“£w¦©Ô ðž§H•ròö0°€¡—ÀᢇÁ—ÑæÚ(è«Gþ‘Dü  ²9p®²p…Pµ²¨‚`äÖ€†8ð®°µŽàŸÐ¹VÁDº†ÔÄ“9:Œ zकñN€`‡è`s€08D& †CaÐø„F%ŠEbÑxªh.L€@/ø~ G¤),’’Šd¡;úJÿ”ÉÜRVì–e’ȤÓÈ4ú}*ƒOf´=J!’¾¤®zM‘#©Oå9ü«>€@’PlêJò’ktzÍ*±"Z« É(&Jí[lõ@Ú×uµ^€.é+’ë] ¯!” ¼Ê¯ÖÉTü_ÆÝr3L®dŽ•%æàs[-£¼ä/’:w›Òju¸àv {¨pÝ[:‡Þ¢Tj‰ ÀÔX@@æ£0ÌWäI`¿ã½9ø=“Žþ8`/| µð=¹ò (š@zä@k§¯ ?=a§P ðåÀ ?¦›úd? Ú@é˜@v§2@G6àäÿPéoÄ€Z@ñL :@;àsìë€;à‹¬.` H£Ì‘€I»¤p F Ûø9)<„ ÀF‘©ÙD|¤bTÆ¡£¾o%ELjnàf•Šp³3PŸ`¸}Î[¸€Náþ;‡è~º@ }³¹î~žÀà~àˆ~ ÆhR ƒ£ýAPÔUIR¡h€'çøÁàÀ@‚€0€,!ýÂ#0hÜ25‹€-¸C’ˆÃ$P  ª9"•Ka©"c(‘ b1 ¬!³sM¦rš®‹2£L(òédvq¤€iódÆTªRètªà+áèCÖ‹X­Ò)ŠM°ï„9lØØ CR€A” ˆ4n½U¬ ?zÂa#¸œ3® ¯Û®¯–Æâ  9 çô6fl?`•ßy¶ÕÁ›fðÚ N×6‚¸Ü£s½ îv $ª¹ ñ›3rç‚^˜P‚ú ~ޝ°Ô‚ž]˜xŠ€ÀŸ> }xXPP;¢ }voóî §€P‚Æb Sˆ(ý€Qì‚Fà œ›!€iò‚`#`sÒÃ`  ‚B > $œgº `6dšÌ͘0é€ÒB £`ê62€B™é %"‚ÐÀ]gáý»ÄÑù¡B\®hÙ¾…R)ªJ`ºB~H JìLˆ)é2;1ú à~ŸÇÜî~ÏG™úzQøs€‘öX ÔHB!4UGÒ%IÒ”­-KÓÍ5MÓ”:6 øa¢1à¡ 槨㨠õz7XÕµ„‘ÈBà…¨êªˆ¨¦!"!bW¦ÀŸ¤U2²®&¶´¨®à’-ª U”©Úv:»g­iŠx¡Ê‹°: ‹p×­BS]+³æÞkºê‰2C/@¨”‘=+eè¶±LÍ¼Ï £‰®‚’‡ 3„3L ݈ÞM?ˆ4x¢ˆëʵ,Ã@y³uË@x³j½Xâ³q@ ·™‹ˆÞ‚ŽRê9 É–Ü·n ÜåÃ’:·(":*û°•¦ã¹;( : ³Ã€×H˜=Z8.úÏ¢p¼Zè)Ž…™Øhi@POð„JÕ@^”P€|C™p-µ`ñh …/M¬‚Æ()†ô’u¹Òƒ(2ôƒPÀ;VÒØB}Êgs¼EՇ̊»Á„ŠD¥ Ö ¢? –ÒØ‡8é žIQÿÔ‹ÂÊ`@ )žàæÐJgìøuÇÐzŸ§˜pŸ’ùx~t}NýOÕõýŸoÔO‹‚Š °[À‘L=iX.Ÿ×ú«_Ûÿ%àå«‚‰V‰j%€pˆ‘2DlÖò°)¥¦ bÈHi"D°)n“Bðgä‰l/ed±HB2`¤«®H–"æ+l‘Ô¶‡RíbD‰ €ÒX!1"3¯þD5æ‚z‚‘ÀP^Œ¬3Š,Dj²@ Æ+bñl°€‘XËŒLlÂ.PÇM¡›1$xÍqÊFÓ@ÍM×7Æ€œs@µŽ#ù'…F‚Åá¿70Œ€órÔ!Ñ Ôè 6–t`(ÇE"€TPz9å$‡©§£pz‘¸…@I(ØPû“©e+@š$ÀFTÜ ƒTA£97Y„Õ` aÎ dÇ€w€q*DDœ0 w€Š-(x !¹DœV„( À¸FàrÓ¼h ;Â1-•X ÒØ.D ÉV RT* ;Ka-‹$ØhØ$Uƒ]"´Š>ÓÁê%Cúˆ¡³&šäJoh~'´ô>è÷Ð~&æ>Ær\ÃIó·ÝKé…1¦TÄPЦ¨‰¡,U€` \CHÃþ„ê¹Z«7þ¶U™1—`n‘¸iù"„$Ñs«RYU MU‚-@JRÕ À wlkª¡Ô…_@ Æ.çxž˜"La ãª°Ò Á TQ¸Ž 8@B‘X©P†…Ö ÄRæB# ˆ: J ж)±š@·qjÎ1¢À«#!Œ1pÐÀTm7b,d´0–ã™›ñàÉø÷ãðxf‚²ÉfìHå-Ɉѥ8¦ä€P@A€(<9Ça€Tºv"°%@Ó‰z¢°³ðË` 2»ê¡°Û°[ã>à삎àFAD,Äœä€n‚‰À “h5¾Ç€,@]‰ˆ1ÁYžA@q8ʳ ¢“ÒðÈ(;ÀHŒ¹Àúåèê”<ÉPC}‚6%RÛ½  ¤•ÂB .ÙÞ l$PAÇb[$¨*¢QšÈPí à‡¼Ã±h€"S/H‘eêÐÿ´t{'ð:Çàêòž1ãKTm3ÍY¯6S1BB­8"5\­Ë" ˆD1€$Z À ³ù€ €VB%´ ®´ådhÕ£–Êë”pøˆ²à¥–ƈU—MV) HD:åyƒU­aá–©Jìž¹`תóˆ–eö€±zÖ@ÐÍ ȯ‡à*Œû;ö“˜ôófá̲m-†ï€‹¤2[WÀiV4‚¯’ â + ÙÌÚƒ~C‰Á’óƒ°‘ D¤Ù·6ðÊ<òI+±¶z@±éñÀ œ05 a¨—QlJ„ÊEž¼ð ‘h-E¢pÔÒ ‰'!Bµ"ß|J‰"S©}\ZÂAsJc×·€@ œÇêvM éë'׺0ü`\Ámš3o‰ñ^-KŠ0ÈÁI€yÓG’)>[i·uš¢yÌ÷ ¸9––”oùg°Ö¬ú]Së<¯°>„eVX•¬AóþqlÖ4´x$ZZ­|]Kœ=>dˆï1=…#¿H„!‹i9„àœÙ œLl+}‘g¿CŒÌ‰1´K‚dnÚ†‰€(êoMîÙjƒÜ?p¸Ëj3m¾8ÃR¡vhÔgˆƒˆU€ D H㈔íð; 2à­ú; ̰(¤<Ë–; ôÈTÀb< r>„nÆLïpã’ \é^l ¡,a`Í\Ä®FL=„ ä ŠÀ;ÀeÀ˜I”CˆT©ÂBǦì.U€"$#p ¡¤%A&D¦Ãf¥Xèb T$~':ŽN ©6 ¡%@H Rë"¼bpÀH Š;ÁŠ$%r  ˜yŽH¥ˆ ¡Ð:ª"{CèÉĦ,îN„Ö»J:¤ôuÁò{l¼¡ø@aúOñ‘Yªf€ äö-*1j‚"x ^#†Іz¿@â/&ùb&0(0r Ïp®ÇôÔï^]k®KŠþ-)N(b*M8¬ñ¶÷"Œ˜-)…MBŠOZõ㯯–/Þò†\ »ëúˆ4,6ÖÑð³¥¼€F €!ÎâDÀBý+HŒFýƒ.Ùb®ÛépŒFB®ۯêcoðf@jD 3Ã@܃†hô2Ü© Tƒ@ÞKå€àfVE ÞåU%ã¢C¢»"6¥T¨ñà ôcÔC¢”à Cèà. ¼CèáéR@~áØ˜Aö h „&\0x(FETI–iiNhàˆ ¥„C"T¤· ɨ'lE(F$x¤<ˆ¬#f‰ÈG‰Ê  2\®Ž  8…@ #J6UVNà>/A´/ Ñýdæ´Ù!P/D0¦7¯pF>0…vf0.¯ò3oöE¨ì-’:¸rÛ«Øpt– ' ~bÃrhÆî8ƒgI²WI‹Š¹©‰]0.²Þ“É8:+ÇKP,;CÔk€ ƒ ¾ \ è“à£ß/¥˜¡¢ ¡ðÔÜAIJ."$,A¤JTÎJÆiå8»àUGÂ૾‘ɨE Rüi>¨àåÊ„Z¤‹T`äZ$nd<ÅB ÂT¤ZêKhžJ`T!@\…A†\¡P%D  ‚KqH ¡|#`ªKc^ ¡æíì8 ®Úe*6;ÁðN'ê‹ãÔêÇ´zg¯Ë¥Aú§É9ÏlÚ ÕÙ]óÅ_,ª!è§±´$Mänbv^_v&%ŠÆR‚2P-ø ‚uõ‚)+î Ñz.ê–Øv)‚8P--,ÚXÁ~ú¤¦û8:`ÔÆ]…¥ß†˜uA2ÉNÔÂüødbÜD /Aàû€E–xb”J/C†KÙi6ƒg »àG–‘ihøÕ9 iË@6ÃAi͇ôø@C¾…g  l2fºvÉÈTÎì:3Ê8„J¦L£f©„®™` (C :7'L®<.&è2ÔŒl/2äJåÒ%ÊC^XW`—À`D -àH W`si>h op†\©F¦•tŒ …G.¬2D¡¼œÁ,Ka…0%n…XÃfåowB EÊb¢pÆ‚bTf¢ ÄZ"b —ÐKa*;À(;Àz$ 4ŸâB"B¤ì¤ZD‹{gÉÄ®BÞuÀíãˆJdêzaü£¤ï7JBä¡àKø*T¥•È¥×ù¢§Ø ¢ åDÂ"Ö¯]èP$Y*ŠâœÑ|¨¢"©¢E(QÙ£ø!†qh-"Ÿrh@!æ$Sï¥ö…:v!®]jû§˜9§¶HC?×ù” ¦Eˆ`„)°Âô­„oe–Žõ!zœ²­m!bô Æ/AÆBô .‡oÚÙcg eË+‹ÆBptŠØ»‹ÁŒHÁŠ6£Œã6ÞKX´lßèÞ ÀCâ4kÆVec¼”˜¢CŽc¢˜Hü¦‚¤0£‡#£*À ‚à ÍêÆ{LÃÃL¹2l£Ô½€¥˜0#¼îXR–C¼, >4ý– vKºBdZ‰Ì„¶‰£Ò¤0ÉÌÈTTZ#Ó˜÷¬= '6ÅÊÆ‚s³ œÄ1HàÈTCÒy@¢JBTâBËEX¾‚ BâBKä¦ äJ&˜!C¸2j"%áöy @AJ'6ˆzµ¨§´Z {aøPÔ¡Ò„~à÷õ¢Ü\RT€ÂTHnOE±Ž!(ò$ZL¨Ñ~¨è>.úXY“á€zˆ€mþ z!6&…°~‘À.úu¨|­¯ —zaÊÚyAbDáHšÏ‚Dºàƒ:‡©´XîÖZ°"ê…@"¢¶®X ûw®xk‡oÎþÈ€âD¼Àë­Vv,BKvŒ:ã‹Xÿ¢®Úï¬7¯š]+oŒ«T5C7ÒÈÉŽI`Š3e˜‰JkŠiV­ŽÆV7¥v"©£sep.Ê#¢–ƒ°àp?~ñBÉp¼zNCÃo’–å’Ž>„<únðxÅT#fÞ –:T0(&z%˜CfnÄ 9 = 8`…[ ÁÈF¤ZÅnÂ)¨!Y‚Ê'.;Ár@&G€(eÀ)v³\ 0œÀ4…@8h!ô'$!¸$ F!FîÆdZô'VíàpH |$!ìKaZ;Àx!L0$ nH¡ºNK5òàJcV ¡êNZÄìzä¤{DüPðaroż_è¢ `ú eDªº!¯`àL-/;-ï|¨T!“ÞÚa;âž•êy¤/e=Jõ¦Âä<½¥Õõ³®Ó¤Z©‚VþÓ¨˜š!$Qåü$R­Ë–?îVˆÚPØÞˆˆ¬ÂT»\V‡Ïk.ºÀ‹ñì^c»ìAÒâô¨“­bôøHÅѶ½ð€eÔU­†dÕc6üی֡FË`ÿ};ôtv3`š7)Ìzñ(I 3imI#‰FÆVWmÏÕà = ·`÷fY€ â` ·`ßíö<;: ´êÆÆ ´=H.çîÏRîBÚnTîùL;ÀCݼ>åÒ;v#B„B)N  Cü uAA8 0¼apÐ4·âÁ( :4Ä#ϸ# L> ‹@<%"$²ùˆYå  €2ö‚ßÉX!A.€0Aéü¿ ‚€U.v¿à‰J€+(ß°Al쥤€V-ý_[@gý5ûdÜ–Gå0(‚€ÐHšó`€—Zeåøþ¼½Ÿ¯pÕúô7Ÿ°úÃgôpA¥ÓiõV¯Y­×kôêÓé’ v¬gÝ@ ugwQ*N×oÃÑíð;®/#—Êâs¸û§>Õ£ºi7V@_t?Ýû<ýÛmáèè7NmÓ­æìxüÙýÐct"èq¿ß8éºl=Ï$‚IÃFï4hëñ¼àÊѪí“§Ï„*‚°è$­ÒàãCcõO AÏ4 ¬‘T+Å  ëÅ‘coŇpŒ´„ZÐ…k@AÆÑ¬fÏÄhŽ€IŒ“,òJjf¬2‚r‚Ï,JëPrJë 0Ì2Е+³L'\ÔLSRÎ& ú‡¼ÔÛÃSPN‚ Üã5NÀ)u?óRb¡@ ²§bþÏáÊþÛ€¯` ø ¿ˆˆ @ÓFuBg …ìJ?‡ˆ!´¸ W£³!’¤Kr/;–¤­@X(‡M "Êš¸Ð(­Ë <€RbM(!^¡‚J0&‰Š0*—À*r¯1 +ÀÜ S¬äÕ¢žh F­„ÊØShƒ*Ù%p*Î,îh­EÚÔ(¶çËɈv­ÕÈ &¸Ù4˜ŸÇê›p ‡Øº€ "š´)§Áú}´göfz§¨w§heŸ†@pŸÇ NÑ4†“¥izc^W£2 &#u/³ë8¬·ÁCt¶·nhè'o»™²ìoÓ²4fãu*´a£j·IŒø¸°sß½9 ²Ô›mÑ”Ý+{Òì¶±*ﳿ{NÓjg ;­Õ”ýï1£ïÌ@fëti8-Ôдq²7Òtuj*òyÃKD 1LÅ7âÑÌ÷Q\gß-@Ø´dнGyäÎH y^`(Lp¤—°TÑž”¯:+rôÓ)÷~`!Êþ™-ÎòÖß•MH”ÖÏ€ipe³ÔÕç€eF§!ŸÛzkOåÉF©5:T:ÅþR¦…ùY€ðv_ÖØeý΀Ü@íZv®RµZ !!+÷ú¯áX Jü‡h°†ÑSÄ ¸jÖzÍv4¸ÒÎQx¸ÒÎ&Ø8ªZ H­& €‹nÀ »0…Òm„cá€AjdÄ—NW’&ÜW“jVÁÑ.ÅÀQ—0 Ø;,âä¯rÈMKùpÜ3"]Jjí@fÀ]Qh%Ô|³"vÍ@72à~ŽbŽ?À$LÌÓ4v›,e”³4â¼þ`ùò4fø»5³j]ŠÕ6#ÎÚÏÉâ™gÉÅžðuÔᣆ ûLä,Þ¹î›HVe7’\\£ƒóÝD3ð\&S§™³¥Å€!Àn“°8b7g.ïfÌÜwà âhÒ’ ™´:t@ ¤Q‡½î¢çT› wsù•´`îÑzDwà ¶–ö¶…  §š‘^SÎ|T=Û¥4 ;’¸ÀwïEË8‡&R¸â¦¯Qñ¥u*”ÀúWNI‘+¹î„zw"@ §u"ËR|Ní„@€ê€"r…`ì'r¼TT Q³\¯ D«J&|AÕ„”ÕOÁ¿ÌpR4˜—à|AT#MP’!èk°±]Ð8ÕÕQS_Ó" ¶ÀU„ ¥¡@@dE6à5€Ô €³ƒÁf ²\*K8+ÀIÕ4¤-DЛ@2PÀÙj¥D A ·‹E@RÁÇ!1Œ”í°pn\édEÀp@ \!pËEA°È@»-L¾V¹BÄ–¾É“c‹ì¢Cô|îÎâ·|_ÁxÑ´Á˜4Ö‹¥Ì¾7¸TôKÓjÖeùµ8UÃù±3g[‹ÄfŽÃö®[«YX ¯™÷žÞÏ‹›Ÿ3znŸ…¶FaºžôMÇ6‰Ÿ; …Z x«,Ë'äûEØßPJÞ¢0JH|â¡êy…è bPú†b-p´7TY‘ÞU£´Ue1½˜èè E ‰ÐÂ+KNZ—>G¦€ÕðÔöš»óÀÓ§ú5õ&bôŠZ¨ÉÞ¾¦\*£ë1)©.–J¨,hTum?•° WÀ#WQÉü& pŸê}gOöIF¢P À(Â/ú0Cu4À6f­åþ¹ ¹®ì„¸âp„=–”;lŠºNÖU],À…Z1Ï€²¶ ŒH!q$˜Ú¢6LG‘F¥S–@Q€•Oex ;0A´Mõ< ;4¼Gøø)¢,­ŒÖ 0#,‘¼‚rbX8‘+c ²Rb¸ê-B®=¾0AÇ 4‚"\ ±.l¹K˜mÀ8.£ÞKù,?%û¿R}œú<Õ£L 1ú4°SHÁÝVY‹åÉÚÌk žã}×p¡£¨fŽ ™ùÐ~±,ÐjuÀÎÇ×°ÄÞ³˜¸Ý:©ñ/'Ç{;G¨€OÜÛÕOÃç»,bIØöE‰ "µ˜rf>2É”eÍ!½mÛð¶ažN ÎöÌû–Ø·@÷4_™‚ÑE Oú5E}Šª çüå' Å âÐe͵â¥:xZ1Ûº~tù' ;8á­KÑè²€:ƒ§4¨^ ÿ§snTÒº{ÌÀh€;0ªÄ€µÿjdîÛÔÂjQõ[‘(Ý^£Vˆéÿï€+²€)ƒ€2€Œ ¿¶Xˆ¿¬À)¡F¡XF8G?rG¨›x€ D ¬H—Ix¡Q]*x¦8*ˆ¬ÀÁ1d ªygˆY°·`‰Š  0z`O‰pR‹ 8 Š+ *x p —‹‚‰È— ë8I‹ V€‰ˆ €—‰€.h…P—˜˜—¸—ð‚'ˆ '°g 8t‹ ¯ ¸à¼.°~‹9ŠŠk¢ üJI™h¾¤¹š ÊO™›Œ³’Cˆbàa«™êW°[«D¨Ök ‹2;Á:ãÍÅÁ@Ó³›Pâ›ñRŒû̳C Dñ½& »œ8ÑÀ¡µ[½¦è'*ÅŒPº¸Ý' Ħyº¬Ä`<®±‹º¦ê‚EÓ¿ Ò&³ÕE‘½°'˜µhM³04Š~½;¹<³Ýq(h£=z~¨â•¨«F)z—=:—x; @„ 3”qõÇ¡0 ø«F¾yè`>1)³P*‹ñš›•˜õ€T¡+Ÿ=¿ €!F˜€!Ü€!;!\ª`Ï !;’É5“V“»`*²!Ø)Ü€*¹*&€)€0Ž€))0¡«©?¬à†°¿š¨$q>¿¸YÊx¡Ø;þ•«²€;¶ŠÄ¬À,A_–®Y_ 4ˆATR–¤YÕ[²€`rˆZÑ 8› xˆ {“°O±R¢kõ ‹€ ˜8 ¢ ˆ ˆ € 20ˆ ˆW(­B0­£ŠŠØ ðn€JŠØ ð¸‹9ª‹q‹P²"ЂЭ‚µìà ¸x¹Áµ™h¦€0˜¯êH¤Ø~¤°~ÄÆ‹ÈÀ™šþ‡È œ‡(~‡T¥XÕ%„KNØYÈ7¥É·»“½;ŒYOW°Û¹»ÓÈ»9a Ò¾<ÒoFÄôE„ôOú¦S¿Ë½1 ÅX•ôX;`ÅÝ1¼!¿'aºš™Pf;ÝK0§B•Ó¾KÎDû 3ôp˜8t˜8¢o¨Ñ9½QØ ©x¨—„w I• Ã¨ìkÑÁ+•ñ ´pE @‚ÚNi$’·€ïž‹ç>t[Gù-? A’è&ôŠÑ-HÁ)–܇´ÜŸIh¿1ü’™Ñ$§€"«”¦#ÿµÕ)V¹ç€+ýÊȱ<hù?Óÿ–,±”Ó^Ô«Å>ƒü¶†ñ°€2€:€C€=>€BԲĊ»8 ‹8’6‡ˆ@¡€YØaaF7P‹7YjŠØ|€P¸QÆäà P   ·ä%ˆ ‹ ¢h :àˆ g €E˜8~ p‰ˆ ˆ ˆȦ„x¸X²‘h¹.ŠØP ‚A & P\‹;¡8¸³º`¦ª¿/‚G¸—)]/À}/ÀŒHÀ¹úQØ~Ä0È€yèypèobŒë©ÎÛª… @Š\š˜Z©©ÏœùÐtúEy¬¨œÕ‰Ï¿Ï%Ð ŖŤ§€SÊxŠðÝÑx¦„lPtZO©Q[ü±SÏ<e' úÙå¤<ܶÐàÝJU‘tù=ÌeÇ(²Éx„Xâ³5 ÚÚŠÇ!î=aÛ(©fG£5 ±¨Ô{[IÇŠ€‹@a)€˜©\U€ZRb–Ÿ%'’Í+H™å¦8žÓJHP³‰)ƒM¿ M 0Èé:I f"¨€#µ!5¸ãO?¡?ÓÙ;ÀQFÉ œ«äž+a?‚¿À &Ê!?P ª ’™ ]Ñr¸X¿§µŒ«Êx>ü¯«`CU] ¹]ˆEO 0˜8AT³X¸a)`‹ €8Ï–Á”¸¦…Ž…¨¤€ˆ²8ÑŽ‹ ‰rÝ Š0 3P ¡È €u—ˆD˜8o‰p €ÂÁƒ(˜@³… ƒ…¸˜€­¨¯ µ Û‡²H³Œp·9À'‰rÃ_Û‡y1Šh‹P‰m h{9ÀÄ}‹¢N¤ºPí¥Ê™Ð~‡a‹‡èfXPýˆØ‘¥…°@â&Kï€aÙï³°Ä倪 € ÅÈÝ2“€ƒÚ•PÕ—cZ;ŠÆ€ ºœÏ-£â¨ã¿PP3¿Š5žÚ–6ã—ºê!Ñ Ñâî6Ƶ–Úc¹†©;𯕛<%Z‚~‘->;6)j†Zí3á¡\€Ò°´} È A«ÛÔ‚Ÿ"c¨|ŠÛñ)“L’¹`€Q€°È«é¾L‡æ =©É`“¿Ì);¾YúT³!¹“ºq€!_IP¡è'¨æ+ý¿•-SÈÈIF8¡È¨!¨g«Ò¹â˲¼J°ݘÊÝà8¯K ÄŠØTª€J¬£5L§€QÕP¸Q;]êª@ ðK™ƒ€jßGŠðR 8Q`|– Œ"€–‰am€£3_ù 0›—q? FŠð_‹  8‹8 ˆŠ08kJ ñyˆ  8‰‹8ˆ T‹PŠØà hY¢8µð˜†¢6 ¸y±²Œ$•9غ‡ªKLA¼Ø¼Î{ñœ‡8~%@_ëŠ ÿÄ›ªbÔ¸@£š1œbÓå€fÑ¿E:Œú‰§¨¡xäœbf(ßY8ÊÍ¡OM¤Åž;ó²€ Æ$Ê´ñl¾/c`øÙµ ëÑ]d€(¯5B€.t5Æ3€) ªÆƒü €:¾;ï€0!,N)ʹ_FzE°‹UÞ•Õ-Iç€NpP­€UP ØÕKrÕ]î ¸S.9 ¯0¯§‡±h€€‰Ø”!Uð¡Šíù€ Ø Š4(LO€ŠØ‰p‹€¥ˆ&¾˜ 9D  8B{¢N³‚C‘‹Pa–ˆ+ 6Á̰ۙêI•¼< =| ê@êüa—$³¢›¡ ɘŒ“†Ë+°N»kÀÓÀ?¶#ϱÉÜ€`Ò]Ϫk½ÝQ[Чs»Pâ§þÉc=–mv0í°Ïcɱ¸â㣀_l>Öõñ¤¸ùœ¨Ýbè»m’pÅsÔmúÚÒkœ)ÒÄ:d~Ö‘hY (Q‰´Ð¨â½uQä®JÆŽJˆ2•œ¶+dìzw¦M¾>P‹Aó’˜ð´†T‡()QŸ&pDe¦Y.ÒŒŠ€(µ³N’›ð¿ 0¿aï±;“¢€%“Ÿ+PS=à"€%ÄS156XªÓýæí-ÁFÀ »k]5°bYFÀbº 0–ØD¦8G¡ˆÉ• ¦6I8ªyX üª¬K²€D³B&€IZ/©]@ Tò&ñà„†ˆt¸•ðqH‰ä¯9ƒ…¬ÈŠð¢¬Å P 7ñÕrØ›€ \(H@ùƒ€ð—W8 ; ¡3œЯИxµ‘ƒ²B‹ `‹€" € WŠÙÖÂ2K¢8"xµSÈz ÚP¦¼p¦‡ääWà´°P ¸¼Œ¡œ‡ˆ~álèkY0~†Ž Ĩ\„;¤Ž(°íEÒ€[ Óû€ ³;_Yõ°û§Q´šÏëìëÏ+®Ñ]8€ bOÛ˱© Ó€Tã_^&ÂJ{ٳÈÿÀŸP ®@á°€Å"0øÊ!C1pyýkÂ!À(¼VMzAÀ $žô…Ä£ÑéÞmÂ$`bÐ%2 ÅKüèaÜ  Ó »ÀŠ ¨(%‚ (³‚°ˆ.Å€¼$¨){ §|"Ãà>Ÿ„(`DŸ„©q› ©ö‚ƒ’(2£(|Fäò~Fâ:\jF怬d§ïB v7­¹û-ˆ¹ó2 H¹õ,¾à)úM²Ò¥8Ÿgé÷9ÇÐ{Ÿ§¨u§Hd†(…j•ó]HÒT˜]cÊ ‘  ~•MtÚ’$ª‘z„È@qMŨj©'Hí7WÕ•uZÓ¨½\èA¤„Fèê¡"ÉSôej”§’„4¨NFôò>Ž˜.„hD‘[V´ídŠB 2HV¢R½!bUÙHågj­‹bkê0IIŠ\ÁV=ýx¡‹ ÿ€©h^‰\ø=å‚a¸Ra«K¢‰(“²ª(*´`˜úÆ ˜²À½ŸÀ66-(‰¶@ºãK‽æÈ’\×±™ÒçS­0­€g¤É ¼> )ššiªÈ9`<ÏGmmˆÖ²Ú9æÈ'à%„Öµà ^µ¦£PŸ€®@ !µƒPvµPr¸Ïˆ #8ÚHY^£òî`‹Œë»FÃŒº¹ð¾êƒ¾p:¡ÓÈìËÚ—³Û¸>X»ä­O¿ï!{à­nðï‡sŒŸ•P\&‚Ip ˜€ì.úV0%ŸŒ H@¬ !ÀºyINºIp9±ƒÈt¤‚Çh(H‡‰ F2‡’~!’\Ádò» ¢". ÖÀ]$¨p‹íñÒOÀHüKĊñüpûgh¥¡î›ŠZÉå;¦qô?‡ÀIÃØQú8Ô¨ü P©(ò? »aíX¯ò"O–³Æ"ð„ رÀ Ø„>¢1 ×ú³ˆŒ X«U_Õ“fšï—”GT+Åw¬ˆx²â+h G©c­r¶H!ÙoDUeÕ©”#°„CfƵ `ŒŒxEÅ䬨tY#œ‚Ž3–›àä>‘ò6/5^ØhnÅ7²€wj¡d p‰ fpÇcë(Ä;F<Áä»2€'0¥ðÁ¤«`H ô[Ød‚¯õš32Nï€ô•¥¿ÌðP‹df-…€5î[Qx9 ѧ4Ùšk\„¿3åášÐ”dá­6ífŒ¸>€Ù¶AàT€#jf ›ÃQ€)¿l‡ÐD ÔÚHH÷|€qÆœ'iz€`TâΩáó¤à Ï" lò8Ka#¼ö¹ƒîOý >î¸Ê·<ß ( ê€ÆäwÐ0¬I @‚Žb~  !΂…6@’Hˆ.£P,è²7tdG‘qf€Ù§Ø’à@’”GØJ“ñ~Ái?èDÎÐ5p¨!€ä—b\/ˆ¸ã'á9$ TnaÈ*‹K@ ‡@² ™RÐõFæ}-zÕÒЭCð§ü?S<Lé¦1ú<@á­½ 5% ¡aR‚>©•­–ˆñV«˜«Ë8mÄ mƨ“n•¥¼ˆÒ$ª0ˆŒ¤®-Eˆójׄ~Šè¨2‹©[«Nà]˜•vÈ[.x¸¨‹%£Ôz‹2u‡šAD¡\ñq€È»Ï¤x\l1Ð jB&íècë”±)G'd¤5€ ú¤‰K‚Û¨•X ¶yIò哊1fmŒ¡ý/Ùæ#,à“bFn[Pjh¶h—„ÆAB3XÏOØ ·6÷cSZá#>‘ÀÖª8"d)#dk ì€T"pF¡ßknO0Ò…F/MëäÙ ã/£hkX„ò z !ŽüˆfèQ€%]ŸtZo !À)ÑÀvib"à2‚ s(W¨®"ôáÁàC€†œ+`Eê Ì E@QRΞ0|‚…Ð ƒ(ª Õ`Ÿ‚'îÑPÆtXûä œ1Fà<— ƒì‰øC!Ù, n£pÿKCT‹‚â~9 ø %Ð-T–‡Á?†ˆîö›“2ÒƒIí>Ø@;Gê‹#ôgåáü7m´ÁÐ?û¾µ—¨D §\•pE"å²T6Èä²îå¿»‘1ZΕáá˜À #âºm½w;‹­;ˆy^]*®íDUÁÅn.4ª’YãÝð¼Ü•‡Q˜{Edy¯ÕÎ näŒU½:`C–;%JaÙ7_’StŠnëÌz*:fjDXIà´…* ž $îR òß"þK!$¶a0a•"O\—ó ^(:š¸‰Òél醷´ÖÌ38/d³ è&¹lœãÈd€ mÑlí5#p ~ÍiÅl›>€Q|m Aè:AÔ,a_›Ãûˆ„2ˆ60 í€2Bæ°Ró´Ù€>y¤ê¤ Ø@GÍž×ÈÍh  (!À,y¢~$„¤ÇŒm‚FäÀB"äz ¡ìI!êl`XI`}cìã(‚TFá^"ë K@Œ'á„I . ¤2?äÐS…8%Áêä2 ÐÜä´*ÔÍØÄ΀ÄòAú-â„Сʄ¡€P  #BÉ ‡páè¯ š‡hö!ÀˆN@!¨!Ž0†B<\nŽ EÊáÐØ*bbä \ðÞ¼°ü‰ê!¨ IÒ.l#ÎÄ%Ø·Îc1.#Á”!ÆÉ(õ€Ú°ü¶ ¨  ¦ôÌÀäâ˜È€ùHøÆ ! ¦O¥æÀ¢¼#¸H„ApŽ)<ê‘t, F2’ÂN^ Â@›,ìq¦•‰H$é–C—ìF€( –β–``&.i…âñ‚Øt¶ñ"Ù€ÀFž/ rc¸ñƒ Šd#:2Š/¢Œ|2¼ kà !€ #Z› ÷Ï:o# ˜€ "à n†È½fÈwÀ rƒ¤çAþz¡j *Df€ ǃ´sÀ ñ  Œ€› #`ELÖ<‰ˆ±CÉ# :/®=¥Ê#ì&ø-"££þýlCXeêb~‡X>€l!d!IDI8!&"á†>€TwÀ\>€bp!Ú"á:%ÀBFà„'áâ€À¢~âI £(ØÂ *vMC0A0v å2'áì~àõ dä~áþO0’NAúèžÁè„(F|y7à8N÷Œ€"!M 0ý¨Ã PÚ›.®Sq)6ÉBEKgÖ‡…V¸ÀË¥.z¶%¦ç3î€%(Ý;#±,¸ DñxŠè©k«=QIÀLò LW+Ñ&0Ò1F}´’Ô&'†0"M«ýb€9XÌ+<ìè*"FFª•b@YàèŒJ'#g`i€ú‚ ÂÂ&PÄo"O -‡<ÅT`-‡Èab/r,i²nÄlò2ô€ó ñàBñ ƒZ<  ^¯L5£¼75"l/V5,+` #P¤²*7#¤ùA¸\ îÎ3~  ˜€ Š@ A`< ›²l:²jt: É Œ àk @Í=¤„üÚ=åÊI–?Cøñà^ %ÀÒ Ñ馦øɺǪ ²¾!üBçx^¤BD by ­RoòEA %&ùb¼ì!YN³ÓdÆ@ÀŸ‚hn~Ü>À~“@¡B–.êbRË Î Ev£BV¦"O@b!TAŒ!”´2%6¼î4R_ q|fNßH ¾©Eqh1¢Àl `Z(Þ#bŒ%xkrIGéHbñnÑûq‚Ù Gªh4´L”½à #` N¢c!#[%` F2Q!ç@§Š³—u£PgÀ %oŠ ¡XYïz§,ÀÌtˌɧ%êì@ QjDòtjàXÀ÷ÀIã¾ñ  R''<.G<Kr?ù àcì@¤FàB!p9<>¥U„…,~à w‚~$nMJ>À&%À('à*ØáîKA$!LH@2Fà6>€:ÖÄoZp.!Þ2EAðXÀVEGö  b%ÁwÁP"àrFà‚Fá¸%Èp  ¢'áÜá®2€jFâän°Œ" °š ¨‡î­Ð‹MÄÊLålLä â€0èWøÿAáh[þ …¶¡kÈ{Ê„€a`(l>Eáñˆd‚IˆI¡cè{Fñ‘J¡2yŒ–S%œJ&’ä€C BÁÐ÷ô-É…¿#³)ÌŽk;œabÈX—!>!l:}v™PŒ¤¸Xò«KDµa¦|"Å^¦€-õûu@n¥H/2[ÆûaßHàµÖbtBÙ6çÎes ±×ÈÕËnÊä*Øð]ºÈ1Ù ËšÜì·GÀvýŠÖíÀX@mr~“4>€%¹v¢Ý­‡+«ÚñÙ[V·¾Ú†6£(@Óµ‰h}QÆÔaÕŒ8ª÷êÇÀ>¬°»{wªåù þ\/zïäq?o“¨¡J>„®„&“ä~¡0…„‰¹ðŠz›(@Ù8EB± !›h@EO`±Tb ŒUQv¡J¤KÈôH°»r<ŒDàcè]ŸHA<Úx„¨°£zòÄà‚Š+È%‘Ô„l¨&!©è„DzUJà'1Èh@5ƒˆÀ:ʃèøA‚èù!˜ëÈT…q8_*§ÚKRÑ}2#ú0T#¹ú²z^± ^ÄX„€IY#ÐðRThAúV`H|×~€éú~þC «ºf«¥úmL€&Zk!+ݤ¡I¶§.–z@ú""V©š…¹h‚à]éŠn°!o !lø\©6…åz\+ŽŸ¤ •¼­¡r&€ak‚zQàÄ!Éf„5Jý†2ø Ã*8¢@ò.LK€/ì›6 ˆ\©”²Ìœ¹mK´lªùŽ€LÊÕÌl‚ -ÔJåŸ-Ù0ëæ-ZÖ1À_glËŽk‘ê74Èä¹Àƒ@㣮¢ü4ó¡µ¹ @‡®¬ó_6¦û«$€b+ªÍê¨H ²˜Ž®ì÷Ìmªº¯ÓÞú²‹Þ^º¹ Å­ßuÀ“ >A›ä¡Õ2;˜ÈA€ì€Ú0 ½36E=iÇÍq ;Ö„pôACÇtToCÓ@ EQøÓFŒØÛ18,ØþS„€}¨Ɉ@ž—Èù?™[@ €tŒqÀ„O/!‹+ù!—Ð è€'Çœp*V€ÊO"-$´“È' på2È!/"ܼ‰‚>ˆÈ@*/+à„(ÈÀÉ2 ðŒü©1y¤`)—’ŽBÙ=Èœl¦02?ÕÂ'Wd |¥H”QR·Xªù€EH?–Ââ$‚“ÔhË—I8[‹I'2»@Ø!in•‚±IØ?€–’Vù I Å’:¸W™^Ž,x‡“Ðt‰ƒ$0…¡rAâñŽŒË BO²áf 6AÈÀÎw@mÙÈÖ;#$Z%GŃÉÐàÀ VgfÀǀ̜—g„‘L€%°ÒÈZ#hæŒÀ´†š™{Aiæ‡ÀÂå'$O Ž5v\iÇ?Œô䙃jÃä1 Áü¹À°°€+c9à 1^mUKmœM•€3> è)À«–lǾJ€A„mKÌF:¨¸G£àuIè‘ ðž÷g…>D|™W&|—Âx€U¼\€$ÁÖƒ£äPÂ$Q`íÀ1ßD)P¾€ ‰@@áCÅ¢à,€ByÇ€ç¤V)ŒPˆ@ ¦€(xT™8Ì({µHŒ z'Ñ8ÆH€8Í€åRŸzcå±?òQJ€N+52LØæU"!;°e@ÊTIŒ À:ã€üU„`E)‘öÕ )® °Ê‚äÆ8Éèœ/ ˆ¼ƒâòúc蜹ayò¤ä}W€bRʲ¤ô}*0V§ŠÄaÜEâ@Η²y+¼Úò.LÉ#:}~}'cD[!òú2µãMÐ*ï ÆÐhäs‘“"3¸ÊY$dѰ…²h½ c…è.€BAGÔ!ijFI‹Ð0ÑøLuƒÖB£ÂåA@ e ¾ƒ—1JdÇ(9“ÊB rèÁ¸NQ´Òø€Ñ •²¬…Ëc Ãæ9Ä%…g'¬D·˜æÀѦ0‘¦d³›XÊy€!ªA°34äH— 'Žš©bœW]‰ÆsÀ74@÷ΙÒqÚ`¿À øðçÉæ=ï#8Cª ÜM:®h_XÞá&JŒˆ´À G*«@ŽäǬ '¸ƒ9Õ €5@Ø`IZJ„eÉ€ÿxÌø‘ ì#!ÀCµÉ´Tž@KÈz(ô¼€©|¢Ò@—À-ü€¼RÑ Lcú õ20ÌØ i€8¼€ä\ëª`!Ãa©$O@”œMD "p(šòDµÔ\¬ã¤Ÿ«¨® q1Ô‚…_‰¤|f€P‘R ®:½©uR:̨;„©ŒX‘öìB’'jÈ* S×Dð0„dNBU ö/$qR7ò1°Œ¶À†tõ­ô⋃“%¼HÈä>Q-+Ü )w'E2¯Ë‰©1aݦÇÀ .!8…¢:M–’c1øŒ‚]o?½D‘4õ®Ø¾+öKH!ì}ƒ¬í¤ñªdH)r/x šÊj€_cOh0é$ÑbúfBi vø# ÷\8H:øI ½âY[-°®hRÑ›KrÃŒ&Õ‚‹›n1.sªg *ºûUÆ€Íp „  j#^æ<›el­¾Tòx¦yµS ÌGêAïb (öÑ—@#ùœ¤÷”<šui GVºÏ¤ÜO~L®ÄÔÔ !À,xð:‹~K°8޵*fL^F”B:-œ"À„SÈøÀNˆ¬ï}Qí0QÀü`i€I “€U É@v !úÀ஡3a@S'ÂK¬ÆŒ¬Ä’K†#êÆ~$NØçê¿À&¢`(U*Ü!.#á4J€,FdþOÃècèPb°-¾S!`/!4#àHL`R/%"!]D¨"z$ƤNòdNˆNL'¡t€ À!Î#¬!€#%H¤Nˆ„ âÊãÅÈé¥ìŠ‚qÂâç ‚!å¨Ï‚@3`s˜2«´.Xê¢è#!âÚ»&tHÀ œÃ®8ZB ZDNZ¢Á€.–&§X+žº1H!hÞ)Aâd,è ¢Ì߃Âj/q8Ó‰0'å£&í"II!k°IDç‹n•/‰.Õ ÃbðŠä>…†ÁÂ䕱 j 𣠡 –C m Šñƒjh'òòf¬ò¬jo\i©ÄÀ$.@X#@€Ðm&Ä˯RÉ ˜œÉšøå„;jž£TD½€¦€KO~p poËܪ2 Ë@Ó‰²:ª ”:ª€Í£ä<*P; ø£!ÚO Â@ ½€ YÀ ¥ÇbĈÑ^çòÐèŠCÆLïÒ¨¦æd€¿Àª qÀøÀ' € }rÀvà3`zÀ¿Á–O!@/!tL`' «cèäÐè¬>-†Dà#-ˆ¤ØYÀ&K@*Hf? aDfèD¨dÆ…2Ë/!ÄLa/!þDæpƒ"0*‚„NJ‡ÀÞBÂT#* 2C*ÍþLa¦Dâ~TÞp­fÁ §,èŒEþ_Â(®8â°ø!ld€ód^SxãÑJ¹ŽºB@úÎf!içŒ ¤!g¬ã¢oκè®¾ŽŒ$Þé,˜)}ó’º3rÓ€dŽì!ØJ€o:`+u¢¼î‚ éº*h/©8/Ú/‹£λ?&èFÄÑcO018îâøálNèB€±Áñ~.OŒ@Kñ–-Îò}x6±Ç¬fòCŽ•³ºò/T8¢@Dc@  iÃWã@3à#Ž'²7ck Dò:©|4#«;àöd~€†:¤Ðƒè†L‹Š„’´¥@\Ç2>Kü޾¤ŒlèÁ‹A >L”Ô>@‰dǬÐd"  “€ =ÐÊD*h˰êhæòx¢œí4¸àNp EJëdzzǦG¨¬N ’÷ ëàDàHÁœD@DánI£èÅ2°>£€c6LM†##-ðRrÀ(}(/!¢YÁ€ÎqÀ0DnOĈŠê¤Æäø#á# ˆ@LU R3`VH€V²%R£èFLaÈDð†!!<#rU-äTÌŒ$ÆÀH" K@+š$ó:îW>Ón!sr‹‡Ð,¸ñª *çåáEÝaÓ• ¦€ÀÂé± ;ý3±;„’hÚ,R‹¬è,åbVU<âjZKŽêb@FbJ ¥T.8Àâ v®D!iAVíCcñv¾cf^¢Ü¢3ÚÂÉ.h,f„#&xh3ªŠÔ/DxÄ$ÐOÚ4”@ïs¿hO#E klÈÚIÂc¬Ž.@„ÈD$4˜ô €h2ÌpmèôfæÉò6°ükŽøTøÀBc@£€Á€»¤t:´¯HTÚ=èø=ãÂD #ªý  ùª,¦f¤~ƒø­RôºD  ûê/ ì -GZÑi Ñ„mRoÚj)#ødš2£„KVF`YÀ}£*æ¬â0Dˆkއn…2ERc6êðŠÀ2Hˆ!:' :#@/!R/!8Lt>!NL`TU X>²#6DàHqÀtS#€!@9àžDèDTƒÈ!! Q€"b ·¢H‰Ä#Ü'nŒW;š!*x$ð[Ž…ÂI6,À!+tgV6åøs‰S‘`÷ ˆ§[gEågn5î91NæOZVø™exÃeŽ4y¸p`s@æA‹°‘xÜÁF5 ª4Cb _Öˆ&V¼ÆV01!A#0&IUïèD@Jê—±BZîf"ðfÖòFy‡`žG-EQöòTßq&£m†Ëkñ^Ë4º c@Àö.Aìô‘óIvý©è6­RË·6¢‚=ìªe2ˆügjŒ˜”«HGÐl:¬SJê–@ ãªYÀ I7>Hü6˜@qÀþrÁÝsY ê^>S¾Â(u£*ud"½€ œ­m ý Â@; GãdCÍ*Lu"EOüv Ê zFH*ŒqÍL©&˜ôj’Å!ªi‘X!dS7¤ŒB0§ÇnËüäfêV€¤@">€$Dà'¨d´R¤Ðò÷€ ôr͹€‚òÈ`/3-ÄN2B0dÆGdNÂ0èF#žLap/ –߀(LatSb>®&Œ"Hã…Kw¢; ÀI ÓŠ¢AY?#€$ˆÆJ&§j¤\Æû$#;   `À  S5CËüËŽìäê¢É#'RpEG, %($zDà)…)I8DˆKØGµ*Gn0DГOà,OÉðB}“‡àKe2"0Ø„ÒÙ ÖH€(S!<€,rÒÆ! ®03mÚ ´!8H½L`b>ƒ*¥2³b3#ái a\rÀj/ r/5z!B#ª!šDá€'¡’gÁ³j½"ç@!ø¤ŽXb,ôc‰‘ZŒ¤$¥®ºÚ$†4›â@¿Ðõ·n~¢eKŠ8­8Ýr`\’ˆ£:»¢{²ÉbAtH€§vî\€!}…;6nèÏ"pðtGúäð¨¥hèÕ©vœ-Ã61¸é¨üKáBÕ§ÂÝØDOly;‘låÞˆ8Ãkllò2dIÞò K@Ôyà©Óºô9iÇF!â÷£@€”lfÿ½-v€ k½Ãjõ –IæáÃ@y Àý Â@ù¯¼=÷Rˆðž<':¯©‡`ú×L!ç#(ØrÀ ;òV>YÅsFÔÆHÌØ U  ™àqÀD?ÆjjCÎÂç„xÜnÿ‚ó¢ ”ähz ài€' 3á¶‘!DJaŽÈ¢ò·È×£*Ú>S và H€#Ë:L2°U^謇,¤Näfç¬N0pU.T•Ò!DDáCƒB>ÍÌU TrÁäS8\Kˆâ{3+âZ (Bh,À"¸nÆéEäŒ}6$ 2_«Èä\ÇŽ„cE¸* 0$£_È»`+ljiÜngDJ:þ¡5ø`8°wb¢k8¨½Û#B4Œe`' s‘÷qŠ)•ñ°+Ÿ[ ürA-È Â! |B°‡ü.#‚€¡n8@!„Dá’X¤šVaØ[ÞYšÅg Ê]—?'QYCúñ¡c)d0.œË¥WT-qÓå2à…XS K˜µj}^Yd—jÂh\N̨ՙPÀàœˆW``¾í»;ªÌº´x‹ÕƒÕb …¾ã! 5æ1³ŒÕ©@%O4¿ÆWÀ”ŒÐÂã1ÀGÖ•ŒpihÀ ²{#AM+²‰CšWžõs¥‹€ÂMè?{[äQ9 È ½ôõ`;§¦íé¸zcÈ "& øÝ~7Ǫ†à€—·Ç^s=ØŸ·sí_‚ˆ!¼m …\‚邚m €cD˜ €k «àyê‚À’Ÿh w꺓² 4@šl¢dTBn( ,ヘ &€4 €Ú¾à €ôBiÀ€‘JžìpRžXL1ÆŠ<«áÂx§… e„Ñþ‡ € ·H)å2LÈhà ¢’çÁ ¦$É&Éjš•O€v‚ËN„ü–Ðо³ q2$ˆ,êW!:š‰Ïˆ’O2"4½/NShD ‚†¨CL#Ô4Æ‚³€ ª‡Oôõ5>ÌÀú¦(DÌUUâ–€UŠ ý!TþŽÙÈY„„N¶4ùdZ*<hDH¡tð ¬r³kY6²"¡'A²ÎO­Ò›Þiú !v¢–·¥Õ4¢MIpr¥Ýjv…Í^…°ŠÂ°ýoà.ØjÄ…„*°„«_kv,—R î€@‚ì +°B8®À 2»J±à¦€nƒ «5"*¬ ±‹bÙJ€…³`KŒ3G;³Mç4øP:+4t1†KJþòˆúÛ€ÛO@¿€)ÊÒ±À(NÞØ`*ÂäÍ(:Þê`6àäX`1‚é«®CHí€ðÐ"éÝ l SÇ«½Ìp¾)àï>ȘŸ:YE7•ÏáúÞeî©à‰Â0ºB‘¨ ö‚ˆ ž8˜$žn扑t4΀/ƒ3AQ7ƒ¸œÊ‚(ñ²†„iàLžhT‰™èñ9‰óh nì‡(i–““Q]Õ×ójh˜„uR®Óià ­è‚¾„ü¶Ér©õ‰€òŸWQ*=Ä ƒ*AOª©S°QtAÔûÁí. „þ®ÒЬ! ídÀµ1 ™VÄ +…²Fˆ ï8à¬]AÔ¸`ú°ˆ‹„B\ÎÔ9i`é*ö !‰AVJ`ž'\–ÈCKZñ,µÅE޵W*¤Š*¨,0ç×3[ñ$…¥¦Vc\_*-£€%Ë#”W½ƒ1HþyVu` ³EÌV@ AT«()[«bô«%]€8 .Àˆ:aò‹°Û…ØÂ3SZŒÓQc²Í~f†¹cÀó™¦ìñŒ:þ@ncaŒ[ŠdÆ` NÈÐd:?à2Ü2à‘(Y*—g sWø–ðF”èe¤v¦è ¦õ7€y¾všXM£€r|¡ÓmN%Ç€†gÉÇ$ð æ\¸ R(ÿáÈãŧ´|¢J„ "`9 0”@tÓB¨u4vðQM$‚ DB(4O8‚vªNÈ€€m·"Hh›:˜è2 h'D ¤|ãÜDÄDð˜á˜ Äé~ð覑ÊS[à9ÀÑ@¿ªðXY‰)ˆ,ÅPuA‡²› ¢‰!<„!’š-AüŠu¦),h`µazènЖƒ&AW0ˆv*­Xfë!©M?è„‘g…\ñÒ-Y†AAi³±<8õ2¡ÖL]S s)uv뀟‹Q…YG5l뢢¸ ™FräW”mQ(&e÷¡œ]$,c»¢ö_E,è(XK®åÜ[¢Û£‘(Yg\— ›¤BÅ‹1,4¦€)¦îÜuèŒ@…¸²]&& .µf>DI"B\ fĹšƒ Å‘v!Ô»Y+ÙŸMq’V€BØa%ˆÏe›b¬ÙáŒAfiÂITÓ¦¥éWv‚=OÀ{‚àOÊ  g*ãÇF•J€W& _àP@èM£{‰@69HÞƒžH#ÀÏ€r¾ßà"`‰žCÆÀFC‰Ä¥{@N7=פØáS«GèuÁHÕEdÅstz`gu§èbx‰à! =‰pPN Ž‚LÒ1MˆŒ#íHg"Ü"7þfˆ jTˆ¨ú;" èáïˆðYñŽ8t‘fƒpP“€x«)»7[g!׈BÔ”B¯8Á2Cº€=¸bµ«³g“1:°h¦¸«f6{mA;€ d€‹¬ªØÀ“t•‚“x¦L B'”A£{,*¨ { à1”ps“•+‚¸t'Â*«;†ëq·ªß¡œ(: Ž8–YmÙSz×Âr2­˜ˆ›à&jßCjå–±J€_9iz9˃ŠÃ%C±k)[‰râ8…¬;$H¬€ú:/€…™¬B"ìF%p¸ÊX‹™.ªS ±»Ä~€»è4¥5‹°¨»K½ºp«Šh=ã bJ0ÀÇœŒÑQ@Æ;º^¥èŸ!H"È€ f*ÀkÛ™±zÔ€!Ϧ°Ò¦«ºXœ@&¸Šq *%2ëŽCÞ3Ð1A=`Þ›°³Ø¦(¯H’ Œà¼x‰€JBb€Iq€I¿HÎIË€PçSÛjC…*Ô…R‡È€d6a¥È±H³Cð pœø&(­¿)‰€ˆ¯€ã‡"Y†‰€°Ø€²i€¹‰ž€‚É€Ñ4ƒSˆ JˆðU€ø†Ÿb˜˜ghQ“ÏÀq\“!e¹ @,Y? Ρ#`@âĉ=¼ð¦¦ël ICÇȦ½— SAg”9T7DA+¤J¬( ò*”€‚È„ kgˆ‹tAz4!“‚¬¢"‡Ðè¹» y¸»‹²ùU¢¬)83Ž«¹"‘]¸ºö€Â8à­2Ý@¼¹**±د®Ç r9tÒCjⱃ\6.+—.ˆŠÃËfC²9&(9²Ýˆ[ÎMâ6$HʼntDê:D쀥¼Ià”G¯Ù…º˜»E¸аç q™‡ ‹°l˜»Ø*‹°K§;|J(Í:C· ˆý$Ë€$gŽÈ»º €"À!¾)€ ZŒaÇ€!oâ°ƒùþ ÐÒ±©Ÿ¼y44*ô€,+B2Þ hKˆ²„xHØäp8°ªMŽš{œŒyŽ›2½¢%Aq€@èJÔ€CÞIQH5<ˆ›°x'ˆRÀTš¨w¨ˆh¨  ”ë¸ã¨ñ €Ž€¨Œp¿†‡ÈÇxÑ™¥kO©¹)䜵)˜c‰àF‘ ˆ ‘ ˆ g‚ R#Þ-ën¶ºb¡< AÄ-Ì ‚ÀÛ‹“jÊ•K…›p8Y]¡2~ÂØ¤ÈÑ62»7‚“4§…’-̼ˀ ÛL¶­¨„M‘;€VLócL"€z‰à!²pj¨~Ô ŸÔ¹·E[Lœ/ˆA±#4-Û…¯h $7—BïiKÔÝÍš’ M’8\ECs—W:—ŠÔ€U ß8z=9•o¢Œâ Y7€„%y׊ÂPŽrê"ú‰C¶Cè®Ë‰tY/˪¤P "~€ˆŠù‘˜ÚÿÀ!‹°~¤ø€° ° ‰€!qÅšP%¤õ˜ÐÍ9´P `ì€#º€ h a©€#Ð!Õ€ Ï æ°<1(Qš˜¦-œ *мXÒš¨¶ù@”€§Y€+Í1èaêb€17€3"‰ð;¨ 0‚隘ˆœÑA×9(¨øœh¯€BC€J$K€T6HØ€Q“È…1ª…@ö‡Y43é&˜3Ø‘£€iÒÃB>èxì€zb€ˆì€€Ø€‘(˜‚˜‚ȆÉ(EQšX ˆh é ø ‘ÀzˆD ׈$¢Óð…11BñûA?¢PXöÔcd“!•á.…EJ°‚м l>Ôãv¢ªL¸?Àl”¼È t€Õ¹?ºX:]X6ºÌÁXˆ·œ’Œˆh‚à‚±þòA€|‰àÖõúÑÁ ½L¡}€ , Öil2ÑÖ:à)]•Þ—5m#,Ý”¹È€V<,7Ít:®š €cÃpŸWP…Âò=0„Vâò$ ªEÈ&è"x¯@ŸâôDX”aÜEœ¼9Ø…€Û±ˆ[—ð]$¸²Øx«<ˆšˆ VØ­ °bQ–ÈÍ8 °µœW‹³¿ Ë·X¡×"hWí— a€"üÅˆÆ 3€!Ë€"Oà‚cƒƒ†’%*À+=€!;€)Ç€+ÉМn<`‰€0ç)¼½¬ êÀ4o¼©·[(铈ä ãÓÎGhé¬ÈC`[I`IÏ€I¾@þQAI€QZÕÐç;…9‡:aAXÇcçà‰ðмº˜‘ÙÜ0ˆ#K X“@Hh}€ ¨ x ÀóÉÍÖIé(€À†„€è€#èÃaB)]— ©€!€ [¬ÓkËd¨ˆ*_ Þº)K^”´'ë`à%çˆEí n·xˆ¸ºd€ cÕ2+ÚeôËêé / i3A{h­‚ ‚h¯RGz€~ßô±é©]”Tµñb¢ªÀ ã•:0j‘”Ã=€<6 ঑jacà¨_•8®£-rj°…Ù˜—jÖŠZô€ !ÍäpÞ|Ͱ…ÀŒåÖä°ᢸȖð#%áÔå—ö­D0«Dˆ¯H&LêÎŇlÅ€×bŠ c …ᙀP °E(h1‹°u€ »,»Yx¶ 틲2O`Õ™Ÿ¦HFÓŒcÈ€%šä(ã„ÖZƒé£‡¾2úÈ€+¤(ž.€,k¨›!Â1¥±°Þå¨9-H=°ÀjÐÇS¥€1a€>NG ü>QQ2b€BЀK0ÑñþNTŒp¦(°|'ˆS§ˆSCèrœ  m%a€`üibqfsCRО€ãÝ&i´™ª†iÈÉp‚ž Çaˆ˜ ’#ú ’ˆ ;SA h€hU6È‚ËÄ«¥ßçù5¡i2„+6à©T¸¹€_Ò*¼ä@ÉT+¥eçÞƒT\/ ‹”-dktYÞKÚµàV¡è·7Ë…¦H­ú:œ@N1(}‰åBé­WÁ$_„[cBPAÕöiôÄÖ“Þ“€Ôþ¨UxŠó¨„Tº×@„:Xrëך¯ÈA«ÃÔD'èk–±áµ}#9X$½â@  t"kâx…Û§Î^:phɉDÌ0еtâbC™¦$ì©Äö bœW¨[бËâýŽ€»•Žغ€ n€DJ úA@C`¨žF0Æ- cPÆq€Í/J]1˜ÎÈý!7€# ™ý” ÈŽÒ×¥¾G €Þ±Ë$9Ãîçé€2U3€2ö€9º&˜¦¸²”ª|m€8ÇDzP¸'è>ÔåPøŠø¼ˆ@}@TÀR'èq-InoÁ˜-M*yË€rb´;B>ÝÉé€)CòŽ8sˆ™# c ˆ ø ?x†€±`gCùŒqàžqU“̈C¬o:!--刉£€,oÀϪˆ+†²P7Pón“$% ä·QSKãf-8¹]ò t9Ø‚ÞX%-g6o;{ž‘U&¸f/h"v…ýªç¯qgÁj›BØ#Dç'soºòx…¸¹W ´Mö –·<6¾¶Ìè"QFˆZ²ô8ˆ×<±}ް¬&šÏ *?¹x¬MH,b"@‰Am‹™:NJîõ”c5M}†Œ ö¤«a Ï‹imÙP¦.)/­Šct‹k ‹°‚DTX‡`¥zÿE»›&ÏëØÆZ¨»^ÔŒÔg¯–Ö; ‚I¥ƒŒ6 Ÿ*%!·-Yþ ``QtóoÀÀψ;‚ý‡ ásj‡á͸szÀ’0LŒC#dȲ0t ‘¸æ@yÊ uÌ¢€KÚw4 çnÈô9U jGü ¾ä‚ÃuWõUëS€ÈÀÙƒb! B«Àú <ÙÂ/ÈF¶ i)8Og ^K`V8 ^Âô@Åø{ÀÚ@Õküsg`y¼þpDѳ¡,û—? Îç4Üø>4€ðf~£°ÑîÀ,-ª÷?)уvºíöîçºÏé›X6Ž_£¢rô|Žfv~}èy¹öFÕ—Ù×€a:1ÖÔÞÞû<¼®Ç_Ý»Àß•Ig^é-£:À¦#ã½°< À­ñªÏ°Àr€@4ù½ÍsâC úlÑ—.È’´ac¾ù t-À¬àà4l¬M =Êðç´a´$ŵñ”= ÏdyGpÜU 5ÑÄNyÂK$NüHr4¡¨€¦Ï¦2”£ Å‘cv#Q;Œm”±2€R›8§±:A·m”³7ÅÚƒ0’1S¬`¯LQ$ÄÂJð¢t"ΖөÛ:Í3M!È!ú.ÌF€Ù1A"Ób2 S(‚1`£P˜õ •  u 8Gà0î€ëv|©h#ˆ–• ¸ƒ­ •ÙÒ¶§‚³€¶-¡ÕUöD¾ètDqÒ‘„HsüàòF}$eªF¤vµÔüèfCLKàC¦° J~ÊàIÜÚÝ€Ujs ¸œZµ€\`b@c8$Kα4Àqе7tšèü à ¶ ,À€ÌX)„€ªˆ ³€½J Ûf˜’W ikG]5ìôMd3ñ‹³¦<­\Ü´aûk3 b¶°üM¥«À´¸Ž´å7ÒuÜÑÎŒêtÑìíóE¼<•Ð/€%ÓÈä¶­õK3á‹Ù¶HTS¦+(W/Œ\û¾°…<9²ðPG>ò•lþ• ÿ7»B±Žõ²À¦$$kÂñ(èÄ1LwÖÀÀÉÆH±Œˆs øM 4—„NuHß—æ÷àk , &J§-HD$«û>g³4BFÄ%€Uø J4/ 5€•:ÊrìÓ.Ë üë÷àXšhIj4Âͺ'0/±1(e3Ó©ãLJ=G'UŽÂj|$hÔÄ6BÚb`H‚Äê™!Äe°(²­À­?îDÐï)<&±N©@ + íP‚ #:[ˆd  tÂOZÈ/`å-–CsÈt¦° G–ËZÊ­l–Àþ"é#, &qšH‘20 ÖqÎL“ºû3€ ¶˜¨i@ZŽô$ÂÅcGœl–ÀÀYDdüDÓrW ` ] 4üä`LKQq0À<Ã~)z h|ˆóX< 3€TüU¶ŒXÓBÀÍ+p°ÌêLilH¬p`[b0 ”Ñ–Ã6k\[X3çLƒsk/¹ÇvhϦbÛa¾àÃ5cPhÂS w äÏÈ#F(Ý"%›®uÓ>Lû!=î%¸3ìnÁ€¢ cn?ŸVšk§Ð3êý¶ÏtèH‘£v¸÷N0þ€ PŸ4Að*LúÛš¯Ï®—jgâJnE ¸€xó¨úB|ì°€23“:¥ÉE'Òž€5ÉMm€'ȉãí9¢hH%”XøžúŠ ¤$ž*'4ÉC@àŸS{ôBI¾&€)Ê©l¦©ÕTÁä$¨àEmF‰)1 $ê^ÀLJ±€E˜¨ î Á  bb ‚*PÄ€%Co +  ù‚¤’€Hn1f@rD k%pÂâ‚¡EÀ u”¸{ÀzE’3ˆ€:bÁE1ÔA˜7L@$Í€DÒÙ"ã ‹¤˜°¼ˆ$ˆÀGÑ(öùªî¸EÒXÞŠ×sLP] ]ÌÍÈ8I êŒT0 ~4êØpEê“WUÄÅx­@8À<\û˜¯@¶ÀEÄ.ì“$Ö)@q­žjI®câ =ìAU] -=±5FïÒº¥x`›@upÌ,7OúÙ”]y2âö#—Hº5€LÃEt5Dä¼t:0ΦÐ@E¥8¶ÄœÔ¡¸IÀÌÚ…>ÝÍ«J<&uaGñ¡¸6¦’ Øh^=&c™ßšòë`l|¾gdfgü£¢“ÉÉ\(ž)'ãÆÐ?&{ŽˆkÆ‘™ötk•ó˜ñ)û][:é 0S}£¨ÀY@@>Pn…Ѻ –#@°gõ{²4uhíüÍDA‚޵ñ%4ó¦LøEÑúO¤º.“qþ_½ó¡&´îe&{$äÕ$ÄXàòäxÙ„Ëê¶N£2LFCÎmÐPÄÖix¥;ð2L€¯*«"~eta’€¼L@Z ¢ÀDLD:ƒöSEB, §ôˆ&®܆àî³à)Žj$âWà(€ 8€:` œ` FÀ   l€ ‹ † î(¸E(€ [¢~ÄÉÆÎjÅôæâðºã"FT †àü¥ö"F_¨š¼Bdà_­Z(:¼ÂdXá`Z@Xáž5€b¥nqPî?T£Œ+ŠÅ~¥ÒènÂâe†X0Àn!,3†f/,…<®è¡®üñéÚ4n訢~É®ð;ƒ>4À /šÄFÎa|6«iC†6¥èA1pîÇlRó€Ý€4Ìǯfi¤t5Æ”Æg8€ncÌŸ@ §(ªib÷í<¨šÌ ª§3ê&üù‘Ú͑ࢊªGi¨ÞÑôúÏ–§²  -šï”§&¾B@¸3ê¦5Äú~#FZ„P§D„vÊ,ýäv©„„?¨BDD«:|ä$î1ʼ{%JMV…‡ç0 ¬ ˜N²`©2Ja€N­€pêp<ªg(f?*ìh¸rpLEN?'à à'ÄÄ X €\  âFVa†T0–, ² n k@-„ çá°†ð† åc ‰è¢ßN 𢭠Åk@ òà ã` £:ǰ#‚>!ÑÏ/1¢¸ öèþÄòå"Fk@L FÀ¥eö»$ã ¶"¼0~%F'¼DÚl…¶Q7`‰¢¬*ª‚‰¸?Ì,±.dââ5‚Œ.ƒv#¼7aJ†á(bA¬L`%Fòž/pÃ\n C ™Qt7ÊJ%Ò1‘”ï* ¶À#jŠ3ºq,D3óËñ¼q*J ¾3ñà†à?#F榮™ŒØGIÂwQÜ4BÂ$g) Cq´ÇŒöÅ`@‰ý2 DÒT@3çzAí !”]EÀˆAÃ>øêmF®4j§"FL”HDÖª>æ´|u žÒNx*˜w$$«F´TBJíE$¤NÑMbÖàÖÄNÑBOªIÕÔ®F¸LGÐPÇÀØmìt$M–·À@*/èLR£)P6Ú Û°@EÀ ¢N® ‚ €BÛ` Ž ФÄàrÛÆBƒR¢Ú%núgH`T3M²ìYxµåô£„Yè¥Ýˆ˜!È¢¨žF å²Å` d é V°È{C ¤  4+ˆŽeN€Eø&CXd] ?1`Œ€[am ¡?U¡gSz `{Àã:‘¢ª®k@0 W@n10,EFÂÎÁÔÀèš”¼eCðCðálŠSÌ3ñ£f›#FÉqÊÊî3è0ºÒj³ü4bΞ5Ôv,¡>ƒFÿ 4 ®@Dt7÷@LºÐ€„ Â1žŒ§CÔ(šô:l£ÎúLIDôoiãÜÌ/6¨6§TPÅ´xDÙ1 û²Eƒ$/·ký!´®/×"¬pBQJöýIJ–BR+#vްÕÊÊH+lO%’O%ÄüH¸ùÅBIÿ„$Ô¤Ófæ×–ìÙTÚa\BNk$Óh&†àˆ’‚$ÅOnLHMò£’RLD`bÏ L@ bÎLAàb01¥b¸€œaÖn êÙ![õHˆš ‹^càî 5(X/z¨o1¶%tÂV  ™ ײ^€ ú  ãÇRÈB²³@%Gà¡ åÔ®îZ$»bvkX'unCçR®jBˆIÆDÚdDeJ邸L€c3’(€dpºŶÈêæâëà…!®ÍO#FAël0:£\œ*Ц&׆Óêl눙aà;g°œjAð~0~ïdãÈIâ (4‡ZɪRðàód¤O@t&”ü#Øâ Œ‚A•dHÁ…ò‡ /4hÖ4q‘¶ŽÍ”È-8IÊiŽoDù¶°Gi)Çv¢àûÊ…!g‚Æö‚:–ÃGÇ‚;mÌÑd$u6ÓoÒLÖÚ£RNF‘ýnzO¬ÑJW p´œòðJj4ýpºcK Dër—6N®’E·GL9pÙÊJn“u÷G•¤ë)ÀYRxN°@iNµö —\Ý@€„Ä º è÷žT5Z€EBTa‚æ äEÁ´K4T*ö™`²¦¡  ß&%{bà A` ž[QâJðÊ åt­’ÂØÉèY8ŠåÀ$n),…², Ž ‹È›~%ö7`¢G“^&ST»ƒ$("d†õ¬ azYA>]!‚èhšCLNjcÎd:kl…ô…¶¿b¾L•èǰæÅK„n¼'â€6 ×øþÿBah@½á®8[¾„Á¢€Æë…ÃÀH\’7 cÔ* †…a`¸[–ø‹Âå1ÉÄA½ rCaðÈ„ˆ= ÂÀp°l4!œÑa²ºÊÁ…¸(U •vˆBßp‡ÌhRd„8ÕÉuô…°ámjŒªë•Þnð°ü,“\·<ál¨[v÷'Ä]±1€¬ .BÁ˜p Ç…·!ܥ蜈ádŽ>ëÐDam,ÜÛ›ÑD Y¹MžÔíô®[Û7&Ób4œÞ2RÏÍijúÆ0›fÃYµ®móÅìrû<<~|›í<@h=5sbx@ 9ÛøÞܰ QíôF>^Þw´¢ö» šö³O!øö½ =ª[Èî€iÈ]¡#,ºï$2ohž„€g¨f†ÀÍ¢›ÈÑ 3 ‚OkbG®@Ÿ§Ô*~¢ÇÑ!Í ·€ ßDŒœŒ Çè¤HdÇàÜ~Çñ䌡0-šñù‘,òËI#*À uK.è ­9¿,ˆHH˜LÊlÚðͰ’ž„àÂ9l@à§ÐÉ ®4ðÏÀ‚!ñ΄ÐÈ0€U(@)]‚(@!dÞ“À²°kº, JÈþ_!¢º¶¤J¢2€rކ̠ Ü…Ã(sç¡ êl(­z2!tˆxZŠºÅ%ŠšË&šF€‚¡s¥Î•΀ í0R €2E¤…˜ˆ]È…0 „ªC½] $—ˆ\‡o] ö:…‰hZŽÄájö6°ˆ„ÑŽcØõäˆ ([º·9©ªÌeL;ˆˆÈX`ꦃ 2ÝblÙØ…š837&"sdzù«„Ü5À –ÍÎÀŒÉYÛ†ÜLÜ%¯9ŽÛN5À$8{.£ n þ"ÏÕ/#Ìù³ï3ã2€VH¼¯ƒøÍ—Oi²ì¿{{ÈýŒØuÁ¼’pf=µ ɳëîí Ï!/¼™O<ö¹@%zÁo o žÀ3Èmˆñ!ä3Ä€¼âÀ$H™Uz9hAbºD“° —€‚*B³` Ë’@ £ÄˆÐ €’° žÉqüÕ“1ë˜ä³ÇÈß@ €Ì° ž€Ç³-Í¡ô²ÃM Lù`Ü´ö¡’PI!‡&ѶŸÈÐQJ1?¤ ƒ†#+Èd]-¥:žRCµQ`¥Õ* k EZI€b½Vä!ZÂÅz”ˆÙ/”¸Òæ /ZÌ­¬q BÆÁ W°ì·&‚BQ‰$À{²ï¼-Ë1ê ºHK%¤­"€°Q|YbF){·ôDQË" X‘e¼¹à9i$ADb5Ùx- d ¥GØÅ$n„Ä@b×ÆË «u!m„¯ÙW¢ e žµ ,ÏÈ€;4¬¶GI6è Sn` Í1SKÌQÁ”Æ~.Æà@µ“rÍ©šW,F1Ù(€ ¦$:Ds_4¥ϪùRÑ Kn8e$Ï·éyÛŒÂ;F|°RxåŒØ>&0ô C6æ€9! EM—fÒ(N!¢8—pf©íINÏ¥`—O$‡pÑžDÖ`à XØÜâ@"¸oÐÇ´ICò$àIdH?C»ç ‘|«Ã€±!|ž€HÂ&ª$n`E^csÑGê¼! @+ôŠ(€¤O’1ÑLÓà¸TŒž0JJ/Ý,¥` €4‡ÀÙù§ÇÊ™©H; ÿU·xÒP~€!Œ¦Ó¦¡™x 2À"c0¥Ox䘤àF€UOЦP€[+¯ª¶_€Ä2l9¤`mÑ„P£A „.M²l]$.ˆ€ Îb„²X씬@ K6 ¸Ê²Û¡0n1Ç #·$.Ó¸œ·Èƒ3QM¤±.¢!oâÀWõ ñˆ@[¤ SËø°º JÀ(8¯’µznù)¹i@ˆ5yB_±™’®"ÉÛÛÌ«2‡˜'»ZÇ¥Eø—Q²Pº¡Ákh³Nö4Fi.¥»~KÕo5ãpÅì{Š˜íļÃ?¯ÛZdBg˜ÆÝ„ÜQÁUÄ>€XÌüøNÏ«ÜDc*LsJzNllyˆ!䘀 3€ d{AY›Q B€1RfðÛ‰4(ý]3ÉÛÊ œç‘F€5°[ :OÐy€&9ž€ºz¨‰1íJÀ$¨Ð91ä} ¶‹€Ø•\@Ôaþl@ ! ‘€LÈTË!d~@#u®­#ý8Ÿ/HWT€tð͈#@ž€†RRw!©?ÔR¤Ê(Z¹`k€TØŠ•¦§¨Ðp QaVÆp€b¶;¶4¹FF=@8¤5ªŠÊËi¨A9.ø!±³(ƒð;1+U•°êÆÀq½ê…½ÀÓ#%È%»Ïy®Ë—m.9u%*4ZÏ€›™î¹žŒ·Þ3+ŠW¸Å×]•ÅÛ¸9)^•’Ò1B‡+¤šl‰„,1ó%°üœ+Ì3€È.âþ™&ž]t¢V³±`NÀ¡+>Ô±©Òà_ôÞ½ˆc8m—Í!.rŽÃ͘Òã™Û ü‡@Fmâó7dÌúØÆóa¼2~gÑ®46 J D{Fq›í1Èdµ"ùäQzvâÀ§ÀBrüÆp’¯=®K.­€ —jQäðè“*Ð7¨Ù€8@Lè4qbŤ‘=ÈV“’` ¦”- шý {+P€/©º\¿€¡@+šµœ!DŒk€*ôHÊDà ¢[¨ÔÑœøÊÀ2Ù¥6¿€“€:ØíÕÿ€qò! Àu Uà`àŒàIœÙH@„Ê¥8OVGäS£bD$e°lmRcº¼Å¶© ÜÅÌä@x]â‡î/WËì!®Âß)*l" P áÎÞ"ÄækŒ-Ä ž¹«ˆàKÞ+ëPšâ ¸b8»GèºâD¹eØdã0´o¼8"˜Œk}n|»è´¾mØ3"½+ØæŽ˜æKÜ´ˆº˜€Li,7 ó æ 5#”,"ßÃ$—P„íB¸éb @ ïãR<Å"+ÖSŒ¦c¾ÁƆš,>í ÌÄ ¤—c˜+ê3äé#>rÀ¼ÀoÜ3ìHnãÆÆ£Ì9@ôC>¡I1Vg¸NºCIÙ#?àÂÑdr¡Cª3íReŒl øcȹ b–žD*òo8½/:B¬’t®þdœÑD€( `@£ à`|ÄgtЄ*øÏŒn S€¦(@±Çà þ€²  QüB§¿ À Œà dÌ{Mþ¬PÅ¥HuIJx€ w€ ¨MhK%€íþápK"0âLå8â0NJÀXÀ¼€eàS€'¡¤i/ã?r› ]@¢ |#†oGí ¬±Äî –1„ðêÃÚz€ŸIÚ1€>DFIþBP!àòňÊj=§Âsd<Œ"d g:NÀòqZŽÆscÈѬª’ ¢ Òç² € ÂÀXDë($I ΤĈB«ü£\‰¯"C„~` `ïfGò`à ` S€ Á` ªF˜¯VÄœÇ@Ç4ÔɈÂ5#Úäù  Œ QMtO…zê"°.€„þC 9Aªw<˜a À„Ã`Wßà˜€~€P `àßḠ¤ ” ïà5À.ÀÂ/†$S‡JB ¼€ÅTå+V·ŽÞ%Í-‚èâ»B†¢’bVAÂG )ßERQZ/Å.õH†Q¡ÖÀiáÊQ¢¾´•+?®Ä‚ »H¿4v!d¬ä`YÊ +Õ+ ÕUˆçðÝ @‚µ*ä þÀ¦u# Tc˵1ÀXÀ É;Àr‘O2Œ•3N™€ÂÉR]m®°ÀÎÖ3ä‚•$ Hº<É”7  D;ihšQV3hâS|˜&ðÆÃôÂ6?I‘À€3kÌgˆLPÉIþò ‚Ìj?SéC6„ ÆC eà@†Vbzej€¡d+¶b=¢tÃÚ5ÔB£”g,ò\àZjT8Ø äHRvB±ôsTjD‘~§ˆ„Ê…" ¨s„~x€ $À ‰ Åßàþ–N=£â5 ðj®Å d=©0ÊÃÛ‡å‡;?l@CÛŠ©ôŽ`rÀl&VœwAÈ€<¸ /X DHDˆ’Wl+Y` M€QÊ¢B¯© Äð’+nÈ⥀²<ÀCÂGöðy×tÏØò ¨×$ O†^äÆÓׄøÀ@Å¢$úOåNdþí¥!¶R!>b¥Œ‰ðI˜$ÊY{MÐB °r‚¾»LPQx" ,S¥ÍbÀiw@–è,µßš" Àû 7šklœ5/xÆ8QW€3OPÙ¿t !i#‚†65eìêrñzB‡RS4þ€m33Ì6!E4.j-’üïË/WÖ+Èæ—,18D+¬äÑ50öÂ+¢ðö´Rþ"úœ‹f!jÊUtëwã>Tƒ*]uð–‘<%oÄP§b"VlküìÃRœ  lÉÆ7D8o§óØ3hlS¤› ŒG%…1„º˜ñ¬\e Béâ3çxÃÌB\x#?eƒãeÇOæœ<˜‰*@‘£ffXg <šL¡¦þ€dZ² .Î:ö £åŽÄ+FU–ˆÎŒÌöîB² €„œ¤ ¤”²NÙLÅ´D²P Ž` o ƒH„³I¤é#äÌT€d`Â26OŠâåŒ Å|Oç,,œÅpíRŠâHâ-þ->HÎE°TbÀ³1+¸Zµ†bEø"®”·Å{‚Û³îtˆwÆ(hØrÀdó*!$”"Ð" â +4`+`Yрȑ¤"!]b.¤ðæ8L‹Â ˜VÒÎè@¨œ"‡8uŽ»H 3eê2‚Eîлn}ZsP^rÖ!{ÏÃBÕ ¤PÆc‚SU®@¹÷¡B¹|fëC!VŒ!îH ˜7>| ż ÄДfb8·åÎŒà64%µ2•Í>ºZ)+½ÂØ´‚{›¢¡<Þ!(là(ˆ•ÊŒÀhÈ»F·Xæ/,ÈcŒfæ ÷ßS<,fhÓR«—8n„VØ®¨0 ¾ÚhóOŸú$ŠâVÞpÙ[kIRA0ˆ\e]ÎB.«†ÌàM‚†`U­ÆŽ¿çㄹ+^Kü&ÀÚ^g\{< ®4¦â Pœ®7 [`¾»¦Õw•äì¸/ÃÌmžŽFÕ… zð¸_†c?†³×,¯fh,o¸ží d>äV„ )ìtø_l£Éfj˜€ò uÑï<66hB±le^e{hœA âò!ÌËp/bUÄF§lè€T $H§$I²,XœŠÏm¤*#öG笥«š¤è£fHß‚¨¨—à llrÁô! ßí\LÄ ID²!äÎK/VïØ`à? à’2PO†˜pä9ùT!ÊŽa@XÁRR!êc`{€Ý*F çRBR ×ø€@0 ‚C!pàB%ƒÅ X;>ú…D¢Ìí{ŸðyL.W •AÁ°¡ôÂ_‰Jáˆ;’¯…8¡°pô(5†I¡N¨;âƒÀß`ìÍfÈVw56s6®D€zG^§Y붤(¡tÁÖuû”. ÁáGÜýs´„`äø8N܃¬oˬƒMc-˜8Ú¹q´C€X¼mŸ‰ËÍ@Cø;bëçn˜è–¯Oš…Ô€E‹ŸX< ëý>ã9µàä ¦«‡½Öã°Û`æœ+ÄÛD5’£Nìâôºù€¾ž=¶wÀÀygÀ(Ó’8ûhw‡ÓìÛ0tô¨(ßÁCÛT€}§oà•€@Á §ãÀ"<ÃÀõ·€N‚¬°kÀ< " €!´ð+(*5 Bà!ÚDˆoÜðhÞ‡ˆ B$0 Áò#C˜Å¡TZŒ¨pŪ(ÃÀ*K  J"d¢ù¦”¢ˆ¡”¢ `1w/LÀëI@4ÀÌôÀ :,Ò<àÞÓLá(N dà `<ò; :¤, DDs¬¥h•¢yÍàD¦&ºo‹Æ™þ£¥Šz ªjÏ+©cR‚9h\ÅK0²øî€'ŠÔà˜¡n° €’V3ª\´%¨’ú…™È9Œ…WôýjœZè9æ…4È]v®‘aâ;½âÓ=€â\³ë<惰\úÛH]S]‹J%!fRz_+ò%Ú©Ãk€]¯2<€2ÍðèV˜ƒ6´µÀR ô‹ÕSâ.5Uƒ³(8®ƒàfûO†€5sÆ´aìØ- öQ¢Y+lf)Óm…‰n*»™eY–XÛM¨Y†Ó„í<ÛWùûÈÛ_º~œìg,z8>Ó™->3©µÓ‹m>˜õèOpt4åsý£¼slµ ®èU´ç+Àˆl;sm €b“Á¹€{­ÖÙÀ¶ðO Ê‚„Qlò—/Œ‚‘h0œ[78@vû›Ì1µ §„[‡˜) Œ0{ Á¨óa $òØ` CóU¸2;%2’Pƒ(ùTY%9²P_(Û€){0Òˆ70c 4äxS›,|]©× >€ÊÜáòáŠCS…BþÎè:Ž¥à(žàãDŽôDZЀj5°¯`Š÷UÔ×!‚ýH"ÔMà7€ELØYÀ'BbXÀQxP°£$Bà@pQ‚¥oÈYò p—µÊK`ˆTjÀoàxÈé…°Ýr¯!ŠB–‘ VäIꆲ€ %CÀ.è\AÀé ÄtƒŒr×\@Œ%¡§X~AÖóŽ„0u2BÙºÝ/ÌQŠ1ÅdW9¶i ðƒŒØús¤ ø3Ü…›%êc‹ª{0é1æTÄÍ;/aLö'4Ól·Ù¶”løÁ*¦¦ÏóB-xVv€04ò8è—TÎ…;Rh ΀ ²uà1¶y@ º´ör =- `Ñ$»|6ÏX‚¥Ólr@¶™†ÚG8VAO\ØIü‚ 0½‰A‰íÞT[!@@m´‚Ž[ÀNh XACtàXGR‡Qløv@™ ²†XWuà• 90–ÒHˆ´‡Y†€©D"¥Ö†) KJ*X7:@”FêdJ+9 à Â@2ÍÝ9¡Ph“š"§j>¤tÁGS‚‚Šï' ÿSÈíN¢‰ gl… k)å ccp¤ƒÔ ±âp¤>™BÞ»L"TLá_VRÜèXëzÞùVðñ3°BuHl|‚Z”€ÂÁâÑ7 êÀ‹¢r@ Wˆq 9sxb© ¤*k0pB@ é!f‘|,•†µa*·„¬¹€îZûÚ!ufÔH k‰ŠäIu€Ômô¬¸x%òŠ1ÿ`Íza€Ás˜1Ðl’uŽÊ©f"ìjPh»3Ù{$Œr»B¤îàˆ'0k<ÓÄ(:N” } 3Ãl}¦™¼C ÓÍ%œ¡ˆºSžf²¦ÓC²4ä¬üšuvÞ¤³< ì,.Ag›é$¼â à]h„ðV÷‹pµÐs,‚¸ÄÅO(\@Ï᥀#{c Õ¸eÖ"Fw@ÈP÷hÐOC0 ¡…œ^ ÆÀ<€Q„‹SxB S€CìFZZJ.ùzjWt+qÙÉgkêªúsrÀÐllü*1È8 0vÓ… òŒ„%‡€D@8x'‘F‡…!R 4Ò ¦ÑjÏ.Uì]W€¾q‚Ê.Òp¬š´1Š!àÆ@ Ðǵ™UAH.]P½|®Ô2M+$“€UÑ8`€† • !Q]…›[&Q³Ø\ëþ'X…M—(hfqfgâp¡ ¤¤-jjýÁ7Õ¤-V éÀ´ ç~F2ÕhÀâUÞßqn!qh”«&„,)š àM¯ ßÀ`x¿s®î»â†ôH®5M>Ó-á!Ziño%:ø/{¡PºÀ ¿Òñ·›i’fÐMà ¨*â¡§U’]°4 =à~3O¢,B—€x€žâVôiÓ¥ Éu èãhV¬ÐÀíìï1ÂñR¬np€4 âA‰œVð !@ Lp`$¡Á”G°CCõ%$Zï ÒJÇ âZ”*JKdq%$ Y@*{¯½¸€XKšy|iEh'3ä¥8x€×€b¤û“ˆ¨´²€yæ‡P yÝHwtê-%H@°!T¹5ÔÄí·˜© ^ ×WÁHBü@5,„*–X·bKJyØëbæ5æ*!‰[ìÌA÷h‡…”'°Z­¹Z a¨‹ï—sŠ3½¿œ7‚ˆ!9 l â! £>ùfˆÜZ¶úάø…‚ˆƒ”´Á8œ.º)™Bé¤H…’Hƒ)€Œso¡Ð°1x‹šK€ › á‹òê 0èÀ¼òÑ :H@³É™Á ¸ ;cH@ªè%Jæ :(²×/ë–/°Û*PÈ) ‰¹©ª1îæiü¯'0é#¨¹ÐӡбÊiŽ‚zûAø;b€>Ã`‚±¡p± »Àð¨é=C²aÁ“.Êqêyx›E"aªx€ä€!ã{«j“ÂÒÀr€É Ð)À~ÒŒ™%@„"€ ÄRa€!‹Q¸€!9)é+=€*˜7hŸÀÆ8ÄYó’Š1`€*1“›5“›;·«Øè2B€9ð=ɹ€9ý'Ÿ›~?’9:‡²p‡Œ1T6Ã^6‚$ˆ:AÀ•Ú ¸8ƒèƒ®ƒl· rŽè;t‹+êÈ‘j‰ «Ûç£éÂ8¿¨…,:¿À´ØQ7h0!˜±•™‰>t´(‘ ò .ÀŸÁÄX‰ˆQÈëü–YlˆR.Á±èH< Š2G £ƒ÷ÊYrˆ’.Ç n:¢‰°º|Bˆ[ôJ²a€“ˆ:€ í”ù™6øÌAžÉ̲ŸKî8évBòE€Û8ÌZZ ´ºHª òßKÔ4C:L–ph/bô˜èEˆ0Ž+¨Ž½€ŒDA´Ì¸Û‚]Žðð „7º€Ì&°‚Pð0#±ªÊcò:㬈)$€'R5ø€ –á‡ÄrD ð!à•ƒûEa €#©²´BÚ„iÒÄ1œ ãhlˆ$Mk,(ˆX*PŒÎòW’Sv€#Ó•`3‘+Æ“ú,N)ø€($’ŠŒ*a€1¢)ñ4PÁÃ:“§€2¬½Á@<Ø€–—”=ҨɀCàˆpq€z·­«iµp‹ˆRB˜b»6ÁƒFøEˆ±²¹¾ùoø…JIÇ «ú 2,¬Œ Q«l ÂÀjã ¸‡y]‚½†|‰³úIù•¶™ŠL‘!ól#üžƒþ='­:í·* ˆ;k‹âÊ‹ñŒ€«7J!¾ƒ{˜1¡–¬œˆ‘…óëAh…Àª¡B|¢K Ÿ- Þ ½€ 4(Së‰ÀŒ —Ä>-€)!!Æê×(Þ33Ý’Œ=PN(¤p"˜)°¨¸û0“a€:p€1ê: ;CP¨ù@¶€qƒé’€  aR¶Â½Î+\ˆ;m¨J6£jE€ÓňFùj¦à‚F~ˆ:ÛœpA‚²J˜…-Œ ÑSˆ¿RãUA¡8ˆnøù7‹aÒ{^?…(ˆXû! Ò·œ”68¬<Š1âæ˜óö6o5«…ˆ;}yˆQæ>Á}7˜òÓš¼TƒÓ°…®:A€ ºT‚:Êü&Ü… éæTX´Ë…O˵ш;¥·ÑcÕs’TµHÂÃÔ´/z§€⯈ƒ¯ÀR·TÕßEx5èÄàÕDAš“‚èÓÃ#¤M£9ê{M\šP4S8Q¯Ún€üû¦À—#¨§£N¹ŒœhÓÁ΀ŒDp‚¼˜šƒªV¸ðp˜K¡ª»ØÄ㔈9ž u§°¨Üy€Ë!à¨5ÁüS‘m|’vy Í‚ X†å [1‹Ì— ’Ú¼±(áC×áI(¥=‹ŠQÙ(§08Õ@!Œnî€4c“I@^É9ªP•`#ߤq@ˆrІ!<½Zˆ=¤JkÍ€ES…+xŸÀ•+’8Z%Ñ’*Q R‹§¾xƒÊkS¿H…¡ÒÁ:ù—ÛöÊc –àiŸÀ"ŸˆuȤˆZÀ2ÛÓ‚,Œ šÕ,²Û»Š¤¡c”±8\ZE‹L ¶PœRÁ!*ßbëî奈”¦ˆ‘oe0è!)“§ðËM/Óðß3oʱrE8Ô•Î](…¹•AÓs‘]еâOòÕ/Ö`U Ÿ1/3¥¹Zøe¨ëÈÏÜÁ°Ä<šØÓ™HÓ¥8 ]YUX1p‚Ôð88ÌV”1N9âÉ€=›MQÄ„7–™ÛV:ñ (+h‚¦þxßk»×Š÷+ Ã¨D×(™±¸ð;Øà>–pG–u{(HXI¢oØQ ˆ¼ÜMÎãjG w€ù ,òÏÀ,<@À@œpF“-µ"=q(¦-‹Fa(Æj³0½½i%Yy]€2§€9š€3u€2H=’õ™>.(‘>ðƒ“87X“î8QÊÅȃÒÕâ!2•F.­È¢˜H4Š\Ú #ò´‹¬ˆ"<Ú¨…¶r [ Å>ÑÀ2hXO7Ô¾ýÒlp­º+ÚÂÈÝ$¥"ì®, ‰Á…Á5¨!«€ˆ>.¡)ëe¾€ г…Ì  ´ ½ÉκdÒè]«=ÈÀC­ø®m £Ø+Ù¥ •Óì¶ÁÓoâ¸Û^&k^æ >ç¤]HLØNÊÅÙn¼3«Ú›:d»U þçˆ0 9˜î¸/â)€.“^çg>s¼ðWs£ehðeЛ˜^ˆîŽŒH%°ÿ±³k —¥E»XÓÖUtœpÞ°ü=x¦ƒ¨út1£‡ˆ+µ;aø†ñ>ƒC)<Øð;Q†€"{# ¼-ªW ‘lNiY ޼_‡T^Wæ›²ÑØžÁ(»ôþ˜H¡ÐàXtˆ šP±@­pO¡(‹(-`Ùy¥Pa9ˆvÇ161”'¦C•¨ºÈƒ¨Æ³Zá^—’-Rë—–9‰Âȵ¾ê0@¼‘6ø}ˆzÐÜ‚¼ˆ\¤®¸œ¥[¬Ù‰ ¬ ÀܱS!|"íݤ‰`=ËâéŠUºìñƒU %)ƒI† ¶Xv²O9Ê ²ßoß>íCZ’önüæos]”c€ ¿çÓ·ÔÈÌ@Ó£+R9²T ¸€Dg/ƒ‡b0h´CxÌ?¦÷±c ßHð%øè1§t€§ºñ®è‰ˆ*w9¡ê¿€ÚÃ{”ˆ*<øà‚§ðƒ­±@çÑÒ逅Quƒ“v‡q ñP‚Å5Êš|Áyï—yéãi—_€(À%d] ‚B q%iº,úî U@—‡«’‹+Ï= 0{!†€.¬áÄþ·i<Py0€¾Ø#Ø“8r…­õ›õ*νöR H‚½˜±uð%Aì;Jµ€®HC×·UÂcaX‹­!.06V¿f ¦°fÐ~ž %„°…ßr¿Œ‘1äˆuÂ"ëÅѾ[cä-ôE07‹x Æ.¯¨õ2GHŒ—’С,ì,Œ–­¨Kü&\`…ö<©lÿH­Aî·‹L<Øšd¨Óò!Œ°}l°ÌXàôþè2ÞwŠïˆ”ÆSÙ¦cPÜxBhèÉNÿ[Ð@ò‚``"„a8”4c1|F ÿ„5!È@F?„G¤µ¬!µ-‚åÀ'ì"I/ˆf¢èC.ê„& Y *‹Â) $!í5M^†TÕñ5›†f±ŠSÞj¬©MAóP¼Ö£JÍD³YØ ÇVÀ§\&ñš¾ €@tÔCfÍZ·ñ þ¿‚k—ùpì§/ #Jþ&¿’™€98q–3ÑÞðÌ  €\vaU¯«èÄúñö¿bdëÀzðV½¡õän%¬ Èâ`tah ±Äذ`3 å+ºàd+v ·èÜN]†€¼›  ÃgY6«”AE#ù¾Ï"&ûªh)~†—!è! ÓÈAÈÙö†œP³É ÀPÛÙ ¾(!2 ƒI††ž°œ:ŠCr ´Å¨k~žhjg>€:¡­Ê ØÅ)Ú<†’ˆiÌò%H,Ž¥Ò òöBqPG(kå?„ ¨i\†Ÿ’|²òH X· ¡‚³ÃÒ'¡¯@g¡®d×Ã`b¨(l†À2„Ý! š ¹Î´xÌr OÉÔž`¡$T?KQhiÊ„S³¼ÛL¤5 €Bú'€4š(Däˆ0šD'È(¦¤Öµ%w]$È…$ˆèmˆ>IeV››¨A^šÅ€ž§ \b é« ˆÔšá]>@„„Lz —oØý€l:!e©W4fˆ.4`¢)F½œ„+ÊP³-ËBk ’Øm(ØÑ{›1"©P8/çb¨¿¶êT\@ $Xß` ¿ÞÀ&]À%Ø+øœ¿œ3Fm ŒÁì*´[F£`%â•mx ׇ‹ø>לzÑß®ÄbÕíÚìíy²â0®ÃþìŽ!¬âi`6BÂyÒ‚kh.†‚ºhÝÜ¿qK×R4uL©1NÊRu£tSÉ¥€:È[ÉQDÙ» ¬¸Y¼†š> ° ¯0£p: ò;Òm0“P6 †ºž&()˜ý@’~åU Þòò^<̬‰Üh(Š†Ñ’¶Ö“ýCȧ€;8‰sw¡¾2 5"4PñJ'® «" ¿u\/‡;I€ÒO~ÝØÈosjü>Ç·2èhW0wˆD†ì¨,—%ûwÞì ,ˆ/h…R²¢Uâ¤RÐQÐtB ¨zJ^«H"Dé h0L¯ÀÒRË0”X$JÏQ+DäAÝ‘КX ÎªMÐÐ~$Aä+UªNUY`´„µtÁ±K¹i”£Âš‹ø*!á2쌸(E)‘Õ!\Q8Å)Ë€4bÐJ)à }€7Xf x‡É| qÜA“ÄôAÀM^@Eüñ”¦¸M@µ€ETßù˜i` ™†’$š†@¿¾³04#p á¹…s0y£€dÌ Ã^,‹ø 5èHÑð 8Myb4qüÑž€ ¯À4 4q¬ sˆ8ˆØ G—eØ’8æ eä„sÉÞØç<ŠÄ¹w y\%gd5á7‚ ÛÚOn$6@€ÚAf¡ôP(¤ý€|y!8‡‰1È·t€ò ª#p4‡‡¶Z9ÈsÒbCcÙé'ÑáúZ9‹3mD"—HhÀ<†iJ·$« Pùž2D¡ª0WØ£„ >â6â"OwÇ9¾(w·žÚÙ2`‚ÓçÐD=­Ô‚¢Ç¶ä€ ¶!ÍíàP7~­œxïæ¥@šMCÈDÔ „5¶ŒEEÔD¬€b¿ÂO`³Õ í_õd¬Ê$Ë€!wZÈhX_D®nÂKôÈD‘V¤Ý[€ rB,I!˜D@bØ5 J×RªPTˆHj†€ N0ˆ”ˆˆ‚GÑ@š›XMm[e)gÂpI ¾i˜ØðC Tk~W/Âk`¸üyÝw {ynËøß-DÔ'—ø£ ÏDb/ò&ßK %b3 |23ö¹˜† +€AÒÍ Æ`š` Â)£ 0Ì Ó_%¹¯’ ,€UnVÈšÌÄײ³±À,Å<LsGE@5¯âe‚8#èú#€¡6‚;ÙÎýBKœ%Ú{MÉÌéêIäh¤‹¿¬Xö訛 ¾¥*Ü6öº@žøe€–È î8)9çÇÕÀ¸!±Ú•ÈÐN'oSà†; ÜCi‹h!·è‚¼ŠWêi!´W-c2&Ô@ áz¤4IÚß–ÐòU§ .{ÓÌÈA^þ -û% "å 2duI.xèGó, <OìK"j¹‰…JžùcE@õ‚y¦ (HCBmc" °Àk¾­Ñ2×Wbµ{õi^ªWkPZw&ä„›±x\B@¡!莞©—T5±dBMk À T4¬û‚H€kIªë ,]Ï)L`Ø@åGôµR•¶.]¦Åû…Y6˜h´*åày Mní/휲ÿ$vé&±¬N° sŒÅ 3\K`¨Í~3Æôó&%@@Ì0¬hÆT ƒ27]ž[8PÀþ€TÌKX<À‡ZèPWü˜â ˜8exÕÏ2¤Ô~Š¢ìäô7ZÀ³mÇ’§d¯`g*J¼p˜”(CVìSzx7yâñ1é ÈRκ$Œ1›ØJóÖySÌÜÈ/zé%`püúú•Â@?9NÛdHÞYÏiZ’Oyøú‘>¤Þž}'Öˆ-©V‹P%U/›ù .š¤÷URªw—$.ª´Úú›¤ë†-«u–_Ài Ù É™*¹iõyO‚æ¦RÙf+€)± UäÔ³¶ êÒo?8Q‰©ÿ\li«*)úŠëK‹T±@Zs\H·ÍúˆGÍ"d8W-¢vÕ&¨ìNŒèZÈâl! ^jÚÑâjŒhr.)`er)K,^À´œ€EÀ ­îiaJWàâD …¾hˆ ¨³…ð322%ÌLÀvX ܈Ì/è/ÂþšC06  t£0c`$gaâg Flâ`¤4aîã0 Š@ rà Q€ — v5å‚çƒ^ #ˆC@ Þ@ JCFUAУjÅê~<†¦ ¤bêd8H Èž* âpHxŸ"6ÉDË ŽCŽà"h.,ºº{lFpqö®îbÅT °è>‡ö—[*Vïɸñˆ§²êJ˜©Å Èà"Hðê'âÄ InÔ§1J%ì-<ôfÒ j!¡r!¨<öÄP§ ²òÏx"qtLäõ( wÏ}í2wÅP ®ÛÍ0"dÿÄšÓ&²*¾Q/PA" ŸÍ2ù%i ÍϰIëDCÌ/ºRë, …Ô-r÷±"µb ÂŒæÒ†2×ë!¥ýåt&åÐ] pË ‚àF¥Ò!ª²Ân&àp!š¥¤ÕˆxÛa!¢ †  0‚a€âÛÎ]EÐc ¤&¦¢7âÀàaÀ^ ´Äk} - €êâÁ6¤ ~&«Dˆ|¥à“@Œ&Ö2Bj!é&®$c.,Šö)IˆÊ„ö¾bþû£25éÈàãX¡¾ƒ0¼ƒF€˜3ZÃG §Žf‡€  Šà XcG cF6  ¡  0Ø!„¬Ie €ÓG Kú<‘¤¤yNèŸB¥G^ž1 IpÒˆ ¥ì<Ÿƒèì‘"î.ÊFb èà$ªì‚F‚F—Cè·…\ÐcÉ8¬•4QL+D I' 3GÂm®, #à:ó6êIëÑšCÈB#nÐH )Y5¯xË O&d¼÷äš$0 ¡hÉïx>þÉOøž( ><÷Ê(!ªÚ)ÈÓ'T|%ОäS¢RÇÐSà   ÊùÈÏ ²ÇÃ¥B2Å@¢ H,ÔÑä×E=d–? ÑÓ×!%ViêôÄBYânŽ rK-Db ¯+T"µTn!ÎP‚Cbk-G/ø$-ÔX ÕŒºhšÞân]€Y¢ Ž–µ”¶K4 "j´Æ aÏü)K«K´”¥²¬ %… rˆU@in )IpdÂj’eÔ'`v`»Hà†~^âþyÀ¼è¾0þré(/ì P$èc€4`L )F”C`C0@ #^“L 5î,¢ì°‚£ÂÎ(¦ €:A¯GøÁàР"  Ðð¬!ÿ…°…4=qÃÅ€\bex´!ë}B#pi,¤‡IæPöü!µ{Ãá’©Lf‰*‚¤aGš‹£Ã#4ÙHn ‡¥²–”=ßN¤J_0÷”!÷N–Jeô -BPŠÕªÑk†?! ¨CR³[°Âk` l¥ãuÂ!Ò“¥ÒÑy„3! CιX!–¹|¦Ë)ÂÁ¡Ø@ÆÁ…³a )u€Ás Œ¥ñ€ 0ŠŒ#PÏÙ1!lVj¶†LÀ!ÈA[RÓìš¾Êñ¼Ù$”àôÈÀB¼ •vRÙ\iýþ‡³±îïõûíBûe⢀FÈxÙ'/X‚;äëd³¾ 0øºÏ¼ïˆMk¶F³de¶Kàî¶B d  òý»ðCg°Ù­’ˆÄ€>Ùˆ0Ü»ålC >$Ù=L†Í{¡@’fDB Ä!/\¡=õÒÔ”®  °ƒ¨C¦»!wºƒ3à ¬¯Wà|¥5åø® 攢©JŽ•ßëbú%'J&¥8+µ¾@<!‹…£(d˜8º 0Àå`,è1¡E·Š¸‰I†È¡Eßw>X²So€9"Ríh™8ž€&26€.SåÛr¢R)! £ÇmêøöÉ%&›e!‚«e­WZü¿-CÄöí¦ËZï…Öt¯¿/n±F€E dÔo°jSV»áÓd¶SPT6GöñApâR™¼` ¼nö΀Uƒ¾nlû[eÅ<ªPq°kvøÖ;ð',öÑ ¶QÀXÄ0Ð5t\SÖ¦ þïáàârÄ=“-œ‘ ¨„rª |±c‘^‚“æ6HÍFÚߌ(ä ϺæüÁZûIÚ›!tw&Ißu§Š5M°l—¼Þ6NÊ&Ìw竨nmյ䂦Ëó<À ;y³'ÀOU΀9º“Ýô Ôeh½0.HB] ôeTJd2òd1b?ŒÈŠ ðZ‘aмÛëáHªâfG¸×a­4g-Az°Öèw¢â8ޤ!þÂÂ/£2îQ V)JR±)K å,hâ zÆWHJZ…¤;d¥å€{n‘$œi¤¦f\PÆ Žb¥­:€È\ttuE€µÞ¢tÀ 3È<ͶӦ³Ž(æÖ€L¢8Ž©)7òt­¶¼QÜÃtZÀPkù·”Ö “àLu´é$×À TLu!G;@:¢Ž!.²)°AúŽ Gi` °Pƒ,ëDµ´ƒÍK,‰šÁx‡„¢ÐÍ…éÈäØXt½EÉ,”É k¡  Qš°JQÄAŒãø™…‘.AEcÍ`Ä-#)²ñOäZ/ò4B&%(".C ÍŒX¹w†Û–†ß"®Ç_ËÅjIðÁ·ÉêŽ7._à±¾! ŽºÆÞJoÄÂCFZiÎQɬwàg‘Œ³2`À áJï D-l„„hz6FÞvÅŠD®Æ%&¼Â1H’Iˆ%'@vŠ—†s#òcd¹ .±.6LvCÄuj¬EÆCú;é¨KüÈ$ÏŒ(6GKš6IºI'6 ƒd£ ¡ m,DêjD,¬%ŠHBcŠ€E.ŽN-äe%P Š´ª\Í,œÎÄB wGšy¨ÆŒÒª$Úpž‡–fÔMox\,ˆLg¦wŠÂODÆc€Í˜ƒHQÈv€ õ`:e€lMa¸‚À €œÖalà@Š4BÖƒ`i`y`±ð`ÍÜG€þBR_e #+šñmô!êB#€ ËðÚ0^%*MEb^ঠÎQ%‚R±Ü hü‚5¶ ›àÙ…rb¢2-iºà¿ÝȰ^¤”]Òv·B±ÐZzr ¦ gNC n|*ŽĶ2Ê—0F¸ Û,z(åê·¦ I Ë™Šb¸)èâmFkæØ"S€,u£”®†œ¢Rrøkî­àxÂi®!R!Ó4wÔ®;ëÌS@%,¿‡„jãÅ ÆŒF©W pÅç.—f° d>obŽDÄÚRRIºšÀŒÃ©ÄÇÄbìD7[pîuƽ òo BRxÀºOÛ@)| &˜-§sB­ xõ›Kb&—ªÚðdù#4¸X š!™WåráÒ÷·¦…cB!…µ$ŽkEÜAÁ gK›–‹5uZ€9y¿¸åÜj ¬.uO°¹°!–¢ÀxHœ•À™‹Ö,áGRön—ªžbXU£N,LâEƒ•BRÌ;WàcdåI¬ß&¼-n6À†üm®j3·4,jº tÆ¿ˆ±H;ävb5káBM˜6[ðpzpÓXK<ƒe7ƒÄ^¦s#Ä›£¾F3D6J–íÀ%2¸m”à06Çë}拺ê!ë±ÓŽeŠÿ-y^¬Úž¶E!t»‚þ€ 2Ö^KÂm“1}ÀlÆmú¢Syºå£‡¢S})­.¼›Ùøs2%+ß0ßÔéÂ" ÷ø€Ap*ÿƒ¿ îˆ8&;ƒ àhl þƒ¤`ï(8 ‰Ã(tÛ‚Bà‘IHæ5ƒ´àëhäÀ<žI% X;êPŸQCr¬q‘fÐçppDr5/ŽJÀ/˜äcŽJªÒ™ä¬샵#¸ãî ”“#€J-`¿jõLBR¼ƒ¼c•9Hž8+ŽoThãJ8°ƒØR`é"±bHQÂqçeÇP0’èŽ 4Y … 'l”ë€nhã§EtdÞÑÁ¾ˆ¢\Gú žˆGÖ%´ÀÀ–ü èœ} {'ZÉÌwŒž#& Ñ_€J~O‹“@ÀšÀ°ÑmÀŽ]CÑÃð·4Yÿ7Ð<-ëÂ= “Âo=òw‰0Y `8ƒ½Ïú,‚5úì•¡it8‚a’qùÖ(%à+ÿ€"$ ¥Ôƒ¿@ Ôÿ« ‚ ( ‡ŠÆÊe¨è" °ÂúGGêZ‚¨<*  ¨’Jit¾ÿ°!¬ƒ¶Oø`ƒq‚ƃ¾H!gè<½§‹p íËþü ‘’žͩ@ ðKÿJ‰{ÿA¿éâdƒ¨;ø‚(|!$Qà,ƒ‰(8YB’пB§‘óž‚2Tã\›³ y ":P«àF¤4+X»€ V ç=NƒÉ¢* K¨á(ƒÖ2Ñ ”°ÖRµ™AI$ƒ„È:š°±Vܤ”Ú® ×\”àŽMˆ"«l åú"¨(=ÜËÜiã - òS&aèŽ/€ȱ‰K¢‚E©M<”Ñ‹ª8·G¡}€Fù°èäžÁ£–ž0ŽÈáÖÄ䬅ׂ;€¼”«— b¥&sE+f¬"Rä´x²9o2mºÊÑV N2ɬ˜px#”HβgªÖÑ;̘4ž‹ÖúV$«€­©4Mƒ´º€lÚ`ÅŽ¼:{'Q2pÀ¾“耊²ô2@&ÉL<9Ë ½¸ìoùPÔÀÞJRÕÚ³R |!p °¤ÇSI¡ J$ ‡ê‚Óþ% ð,—1CÀ ‚P‚$°öÒTr NI©€´uAx75'MH$)ÛKÆ p×°…Y t³n¬fà ÿÏ}5Ü'’òpÿÎH!Á9ˆ#ËîÃ|ˆ?€:9; úø—w:JCQ+Š=v9@–!Ö‰ÊB*pzG'%+N'EEÒÍIâpdÄ-±µ¸Å×’®O Ë!vÕ—Ø2¤q(’xG„r)F"8d€‚MLBRÌщ`ŒÜŽB9"·2l•‚5£&Àd)FŠN¯°_q­#ˆPƒ#E@@fMK tŠàÜ@­¼ÑVÎdäC‚2k¤–ƒ&ÔÀ2gpŸÎdÝi@€3’P2À]”~€#HaPô,“Âä@#”†Üw„r¸1 ªHùèÈZû¸Cea ŽàA(`?á47@,ÝúŒw L!–x e®ø‡Ú e2 Ú0WÐA»€KÈ!|¡®ý}¸X'¢‹Ïäò€ °ŸÛå'(N¢oÈ"/?ôF;us$iŠˆæT@Ä¡h2â4è™hh ËX0Ρ]Làâ³&„aAG^k0,Ã…¢§\ÉUõ‚AÊOÕo'Œ”›JÁ r›>À WW¥µ€’5ÄÇÂ` ã4Ei¸”ÅHŽÍ:Ñ]Œ ñ€ÌA#jÜŒàݰ$²`Is /Q\‚@°€Ë…‘.I¨tAÚPÆ€ŽBy"uKȘR8*Hå¨`†A‰$ ­B× rØÈÚm%!)ºFFç&L€˹'Z(š+ª`€¾NùÔ‘Ä,Â)ÿn; ¾›ñfH<™!úàZŒ¸¨S¼ÎE0%à‘FM²_(áM}] ž€6z¨P éA’h«Ð '¢®€G6ÈïÇЋ!H«*šhAþÏÞ—Ú¹§@…)Ð@Âxp .@àk·±À…cy€?ŽÐfkyjÏZˆAÛ¨Z•æ$œXµ<.?íγѷ–„"ò>&Ná/.Z2ž õQi»j~†ê½—G)z{!Úk=W A AÄ7T*uL£$ñž€šV"¢pª¹áB³Ð«uµ ˜eubÒ Xº@º½ÚÄAî’ T‚#LÕð æÝüV•6Ì–é«äËê’xÐÀ>KÏæ#“ůaIŠ…¯V ‚8•ƒ U”Kψƒûn¡K!<غ}{€&‘—È#T JÒ—E%wŽÒìÚkÐÎ\ À×XXÄ£`ûúVàŽ-–Á¢òL’Äɦh]74#€Ì¯˜›«^¯=#‘½¯ËbRª€ö2„q?€!Th·¢–‘÷ ÞÌ:dÞƒF2nSŽ€äLI\Òâñ™nG/ì£oMÑ/y¤h‚Ñó4JÿøæyÔ@¸Ñªh†èo½$ýž…þxZÀÔÃÀd´2±Ó›ÒÀ¹Õª´¥©~¹€¥ò9ä‚$H¨L …ÕÓg ²Y¸±$ /ª¡æ’³»§|¹¢À·•€›vd)ô² jÓBò/ä¶Aôëµ'èÂÉ@ªµŽ/¨9Gº’«Ÿƒ{Ɇ³Yð+{Ä wZq®Aê:=ï>²À EÉà> áCi&ríÈ"÷|ÄòLšO";¾Åj5Ai½…Fˆ'Ô€dû©´¹ØžìTÊ ©»šJ_‘X†b܃í’xÿd?UÌ)u†’ra †cƒ™ÛÒãý0(¤_-ˆ‚P¶(ž-â„/ #¢ÀCÞ™"´ˆ;ȪÀûyÀ˜Ž-ÐMásˆá€6ª„C‰IZ‰Iq-Kh¸ˆ¸Áªë Hâã·¢0™»ešXޏ”¶+V ˜ä€¬5Úì hŽ)À˜¹¸$1¶%h:Šbˆã…:q²ˆb €3Œo h ˜ J\¼€˜—¸“€™9Øí¹€à8Zg b+¸&Yöô%Úq$ ã€«qó À×>ˆ"úO¾j ³y‘>¨>bv'`ôˆ xÿ‚™× Ù”xvš˜.œÈ\":»‘ùîËÖÙ…Ùä"HœXÿ¥iù‚Q€ ÈÛ©+Ñ‘a+šŠ<£0”pƒ€Ù[‚²r)?3¼Äù:“ (!"óM©yV@ ¼’ñ†+kµ=iA=cò˜p €‚*éN3ˆ›ˆ;÷"é. ²G¢…ˆ‹(xƒƒb´ŠÂ̪j -‚?Ò Â#–ÉWDP‚ì +/ÑGà¢ÇðÀTxΔÛr©ƒÇ:Ì€À¡a@ˆ‚.Ibä•ËW@ ²!Xº>| !šû-9ƒˆ:ÔȺ㱂A±~Éz‰KZ¢rB7¢Þ°Ä‚ºÉ‰K܉KS0¸Ä,%$ŽIᢶ(•€0¶¹u¦1ñ°Âê…Ž9ðÈ8ãq¸R‰L¼¸¨”¥ZøPH‰€= ` °2ã¡ VŽÉ‹pØË½‚Ñ&l61¶$@øŒõ@ôÑÛò—–Þ¼ø§a3²–:/á»#¹k>;!–ÉÃÈì :ŠHà¬+œ3€g,mä)ÀÇqí©¡0’ñ͈(ƒªJ)ú**cKE¥+ÖRp »È«PHËd>bïG!ò©à¤ ¬üˆá/4éW%l-’$€ˆ@)¶5‰KòÊ¢9˜!ú¯#H“ΉI&Œ€¬# ³?ð”ÀsB å9‘‰IVØN€”´,(êêÒ£8é’âÙÀÙ¤ï ¢A-ù| HÕ£”¡‹Ôǘl%Äi Jdµ˜ÉÊÜÙ ¤¨¤3 ŠX”¥kš‰I?€͇€í@í‰ÀŒÃ8%2ø(Ñ2© ¸ÑHÉÍ@¾ ɤs¦À‰€#¸«» EU ™¤$3€#Žx„‰U81x½ígûàWƒJFÀ‚L¥f¼ Í¥ `*Ìl‘€ 0‚€9ÄèÀÈFP„"šPTŠTÁ¶\0Äœ(d¸X¦œ_^Éœ9¶Í7%ÁÏ€#€%.J€#‡ØyÕD‰àª€?Íý“Øqß•tÙN´;'žå~sÓPÁ@ͨaÃ8.À‡ @ÿ†* W`0qR°–‰¥È™X `HÃ.è‘_*è>0‚TLÖc W퟉"m~b…ˆÒ ‚(¦#Z­õh»9üω%É_ Á%i² ‹² «2½)*·Ä‰ü–játõˆƒ¿(Ìb©üƒW(Ȭš Øâ&ß™. â³=Dø¡™ðOH‚b6#IcÏŒª¾ *Æ.EžCžiI ÂÙµGÓäi53,¡.™‚!*C+›/] n µ×Z˜á/øŽrÁ”®S 4cð¢®Õ€ ÃÒð”©:¾‹ ²SzojRÐÚ ì ”Š¡  ‹$€ž !¢†(Ñ-àº-D"\#Õ; 2Ó‘’iˆä€¾¥[*‡hê:…©µ ‚ùÊZ…0Ñ/…Ù™îÄ&XõJñ¸ÐÑQÀe¤{°p‡¿ Šà3üy±Ü=2ác-’:—¬é-iIŸÉÐ{ p3ƒx…+h()¨‚¨4ø\;Ç´ßè%€2óá4Æ#€ ‹-`€ƒÄ¨D«dˆ%×Îq»«œN³õÍiB¢¡?€û¨Ég^ߥ‰áã!¢m€Ö‹à3Oø±%pyáò”dYg} ‘c>¤”ây´ÑÎüuw©ßJ¡4‰ ÉO%n àphÿ…ut€bh]p€? »IcÅ‘™{…'M©ó`fŽ,BƒÉþ«c. έ€ÞΩN{:Ö¸¦«:©8®³Šº8¡[:¿ÆË:R=¨8×€PAŽ(#>N+pâŸÑðâšÐø ìS¶ÀاÎ,$u¼ ÊêÌ$°q”@ÊÆ±È—¸­('iÔj¤F²KGD8¨oäj×€ˆÈÕÆ°„j䀙Lº,h°ß¢ ë쥠‰ -§˜…˜H„œ¿%h"þ€ˆƒ2Ø"Z!€|b;ˆ:Nˆ;à¡`”þ¦#(‹L¡ø°‚#¬ö¡ R¡Ö –M€ š…Ï òÃH ã;¡eŠá#MEx¶À W¡t‚ñ¡5ìHZx‚8õ"Ä¥ªV¡th€-f¦[Êz !»¤¬5"‹!qˆÈNh#Ýn]ˆ%–¡o‚„;à [YÒ@ #2í <´  äþ —@˜à ;\…àêd‚;—æ,±br"¸à ­Žs@…Ño¶(Ò!nÖiK¸¹ ĸ(\‚3n+–‚`‹sÖ…¯H!ž…›PSr½À °‚ŒîûDà Ž…–ð B–R‘€R[E3¹iæÎâ®.‘¡€ ® ‚DÛx!b‹ý¤lËÀn¡opÙ¸¡‹;²líÐK»>êp22f`ZLî5¤¸¥K;¦î/-Z[tÎÞ¨«Ä³²X8§BÓÄn²ªs‘cÑ€ôŒ3šh9ÉIy6l€>VÈÁF¶¤k uü•=À­XmØcyÀ¥€ˆ¬k!žeCBâ[›xý&º!Œ ¨„[‚«hYˆŠ5„y?˜‚´aLüÁ€AÆ£€Iè¡@êÀ nÝš-ã BÐ ƒ86@2H@JÅöÞ]xdˆ*40AÉk"\®/H‚,JŒ¾®€ï@ O †Ad–å’–€H"…±…Ü#ˆ„/,Paf,Y™Ä}Å2(¬Déš+$ü±èAâÈ]E¸7"ÐÑ=,Ò «EìcH[ L€¥Å☲âa¯l„&0xòÎ Æ)°¶x8—™ WíÌ…·BåâÛ//²2H'€W˜cu[¦‚" L놇äÍ­ò+È[Y3ÆæFv„gAñ ØâÈá.»PðRw6×|ÚOA ä-ô(Ä㘰a2­© ÎÏ Žµ±îvÌëaÆ8â»Ð&œó[œ±<"ì›ÄkDgù%€)ã+(63¦” ã;8ÝñÆD0PPÑXœ&]À¢ø:;L@ΰ”ÂAÄ(Á â Ñ;:FwHÔ&™× • ¥©¡í»Zʲ5xÅàŽA2€è‚¥f¯Ee$HƒÔ#¬ˆ)P·Bè‚ ø«Sû‹ôÛT°$L¸—KqD±Â5ÁÙ yF-ˆÀ›àЄàè¶‚yKLë&7Ô6FQ z@2ê1Ђ ¹ˆ±ãÁ"!t`‚ T*eU,--ˆXƒ!oÀ¾‘¸$æåL•!辂ÄÐ@) ‰H°JœS¸ŸcÄ-YUÒPVYô! a”ǘò¾‡o”‘"<Ô %ÑÈ6BSØÒ A è5@²‹•rŽÄª‚®2ÓJóLBã£6—l°°µ€²bá(‚õX@X8¨k¬ © Q­ƒ½Ðv0±!%,È\m× ,& ¨A$¡¤,N%Òÿ/v! –Jõd¸m K@·}x˜Œt!v¸´[¢3€t ÒMg‚!…/AQ!c"Ç‘–ÐÊ‘“ ‹¿[Ã^KMÔŠéEâúì€ ƒ ‘cvÝÜ–¹ÅÚv„ Ù",íÄÀsÜ*1:ÎqB) á÷àâˆòÏÛÂ@ìc)Òß&íÉ5ªÐWØy MÊéÒ ¦Z Ò  ®Ö¬JF©G çJîŽï…AnUw6dE-[cËXÁ¶e¥8q„ùÙî@⣳=Ò™þtÖøâKØgVlÇD›ÐJN± ÆÅ8Õ¢/#Xfds·„zš9ƒ½sx˜Ê\ˆ8—`¤ï€›€lèФ@¤‡ ½ ²€…&H†]"`ˆ† …Io–•<Û3ÿˆ#ýÁ<p‚AÅ^ÓÖÃgßg®+0`8ÜB/,@dªŒèE  ÜBù:#: å)Sm0_Z'Šk€ Tô!L_ºT³ ƒ¢Ia DBõ€!fªh‹«’!i »(ã°<°‚įíð(îe¾ÅfµVŸÂi[-žôæJ¹¨î6¢Â‡ÆPWÃ:—âôb€B3®ÙC:ȺLŒÀ@†`·Àbó iؕ˜Ä)DèàÖ’Är§âKÌ8®puÄ÷ Ά ަ¤n@œ'*P¬Ž¡ÈƒŠÆ¯ŽÃcŠP¦3°Œ-Ë XÐö3£Â8¤D&ìV3¥PŒLDa •@ñJ ª<òŠž$Ðq¤øq:#!‡A ‡I¸D t@pD¨tˆJžÈÖgŒÍÐ5àŸD mΠ´‚61€â夨pùÂµŠ”çeº ŒºF¾Ö;áìhlõ à‹(‘Š`«¼ ââ@ åû ­p D¬`â„@¶hÀ!Œ@jbà‚@d-ðºWínBôÌlƒlô`¨VŠÈŒ cü"h#i ý c|ºE’eñ$+ EÜÙ"¹°…‚  f‘nhb.aq®‚"&(’è|GþO#°&Z.˜ôÉH#i  Ÿ‹–(-Š!"().j°jd¢˜‘ˬ#l)ল¥B‹,Hºìh˜m ÿ&‡ !kø)E 0´º@’æäÄ+”r«š âæ|!jBŸ&0ËBúDˆVÐ1 g*‡pL›‰®¿Ç+ cŠë©`AdHþC H0L´Gñ<6ŒaÁ6B1‹gr¬$Gï3:£:çñ:Wénz³T8³AÃ.dLAg˜DÄÄÅ.ÆVÎB@Ê:MÉÇ.K ~?dAO&¢GC¤Ao6D«:ÄjòAX â€=A¢ÇøÿBa” A…¯¡Í[úA¢ð¸À_ +ǰ9ÿ„7Ý0ƒ Ã{Ââ‘L, “§h[®Ø…¹å™,d›PÀ[ÛžFc³z”Úc!ó¬$JŒµ@Q™Ì*3TBCP±´8CC´Ááo¸Z¶ô……á`ªŒÞw:²BÝP¶|:ù<ÂÀ±¼ V3P„¬aqLm˜…¦Ð·l9© t\#±‹H 0BØÐæ–‹]W…ƒáa˜[fÿ¥ÑÜð²\,7 AÂßü°2»Œ„0Tý~”; $Âæ±—,-æáÀ6¸È79 qsjàä G…óã(ŽŠ§‚°¾¬f-ŽÜy´œ€m?Nj¨-èÉø…1ì¸( Öó q¢(Y¸óÈX¿À!jKâíCÍ"èø¼,hy<Ϩy¼Á‹,h[üø¾o‰Þ…¯Œà0ŒÔ¨H€…¼¬üʧ 脈Ël„»C öÆZ`®š¨sVŒ¨K=Àª2ÓR2Š(IÒ:#'¨`Ç,—ÂÑ&!2¡qÍÃt€2z3k²Ô8 ¡Ñ½§pÚ¶­’˜£!Ú#_«H²Üu‚2É#6Èé€!ƒn²¾à ȅܨÌ츴‹Ò2?¡vXJ#%’ CµªòÙÂÑæ}ž£7åŒÁ(ËC¢2Õ²T.Ô…§h€ ø¡ašP¡w¨ü£8ÀF£9^«¯Ày#:Œ¥{:áàG…Z÷PÈXâÿÖ/2}ª·ïŽÈÒÆÎÖUÀ˜…‡P䇔šÈ[>øâ’4…쀶OŽ\q[0ÈÃϸwFÏ3½D¶…óp ;YhÈ’¤ÄóÈ]žøï°›ÌM¡ ‡&¾6XÍÅo6(S@ÊóZ=³ã¾&ƒÍ¶ð7›Í€p=€L\ÓžZHÀ¤³›ÌkÎ|dóM2ëÉ–ü@dpnI¤Ö¦”NÓ{~NaK§Ô=ƒ³&Ì…«°ŒÚÒ,ªŒ"/È[¤6 áªQÀË}á|뀰ٛÅ$D-‹•eXÙ XŒ¥ò[›2ÎMi=@3XÊ!n|—´HÐ0!#˜3@ÔBGÐ? °Òˆhrìá›¶õÀƒb Yl@ì”RýHË$hàšXˆ\ˆÊ=$HŒ¦0îLk,«U¡r2ýù!i ‡5ž „d]͆P(dˆœ”Â2­Ê®i¥ÀõÚSHX½hPæ³ a‚mÇá5¢20È\}8K ¦Ÿâp«£­$C±ÁTŒê(s®;,!ÂãU-"0-5 eJ€šBÔ ½Ó†¿®²yÉšý!ËŒX.kTBà Ä9÷Û­]s!é›`3ÖfOb0Àýlˆúй^-v‘œÊFYàJ,†KÅÛvBãªh ¥l®Ç@ ‘6€Õ«.ÄÑYD.z ÝýµÌ©h°Ì SÊ9nx § åÈ«€#Á aTï‰Á"/`Äf“^}N`æ1ƒ†’zÇJ~)Åþh'â‰ì’еcÖõFÞ‘“4~$/˜ÛÝË‚rº—ô\„WÉÍ$ PŽò½©çIhšW0$§Éú•qCÐqž;3ÍwˆÊfŸ–0ó<0õ4zCì«eé+zÿòú9î½`S&ÌÀžn3Ð ¯PjDO4†Ñà ¨®ê€Ó@–À | 7Í J›Ì)póTútÀHCÌàaÓ–8q©§Œ@ù¹ÄgNM>¯'ËíŸRiSô©Ï*Úp &pøÀÿÇñ56€8b„­7Töšß%= úÌ ™ÁÈ˨ŒŠ² 8wéW/¼HÁU%¡r#(܇»Vן6ìè„î¿ !Æâ«nei@®´bàT¶@=Œ#H–@¹à×oZ8‚Ð-„G ° î(‚ËèÂs èA‚8ƒHoì¤ÿ#nÄ?†HSBâÄææ#)¶ôæî\&REÆÄ K¨è !Ín#!hÞ¼éÀbBm©:$‚¥¾j«à¡nd#,°Åøä媚ÊÙ­–)о()Ž#,-)Òe,X(0#*&u0„#*p÷ã饦+äw£H·®ô¢k,|ÉÐe(8ɆÿD†žƒ¸y&ͯªõP†ª¤ó ÌDFJã˜>!><ÇDaNô|Êt t5#â(â›`²Ë‚yŒº<ÑÇGþÎ# IÆK­,œgŒr .x.¶M'ŒÑÍrK´o"©å²dN'6 ±HL<Ò„ÓqޤçDÒÈí>NÌf–f(à–- dMÜþ%Ø·¯ßbSPÚþma6Ë`æ Ärˆoò*ë,dÿŽª×¥ðA¨P "³vÝ¢ ²ç§0)F^%ÂË`BÚ!)lÌ PZ‰¬ÆÊ "2< ²b·¨î4ˆôÂ@ê‡"‹ðí æ;â2ÆÒÙÃ,;FŽíâ~ŒÑ̽#Žƒš²Ä˜‰¦_ÍJ!Ðâ6寭²tx+Òâ©\ &ËîŽphZHôcÑþ>Ѓ*+·&@ ®.®)uâ2årºœ 9HP. ,„$I³¬~é‡(¦~#& íCo ʨÍ"2²Ë,ÑÆÿ(Íœ(Ð<ÈêHD»éÒ²Çhµ‡Œ4Œ¦Uà¡èB<ÌÍdÇ11¡)Ô€Jkàl`qGŒJhxð‰Î<À±ªX>%Î%¶œ‘$Í+®¸<̘ÏÍCÓZRÄÌJešG¢ªÇ‰¢:¾MHrfÎ*$ì !N!oðÞ,¬ðXþ%¶̘Êà)E¢ Ð!n$Þ°Î $0$„¦¿3 ‚O¢ É­ &qŽeøŽðÀ^# 4b2@¤! ðç!Ò´Äe’aÆHüíÆ’ ââ-‚ÍêèHïIÐfÐU ­Ž‹lz#(çAâÐp­X”-ß…ùR5‚Ђ¼¼ë>iÀÆ+r®+àe0–½)\ï)ƒ* ´0œr&Rê^“TÅn=.Câqä^¤"2u´öž ÌãûO«ŸPüó^#*â`„zL<°ëdÇg8>*&’$ºkç—ÀÉ‹äs,ä!qlQÆc /I©Ó5¬ü°BfN8êmq ZËhÃCÌܧœ<Í&CÆ À03w ^ÍL<ÇhtGDœlfªÇšz1zJž€Êºøu„NÁþª€ô âð:ãm<'B÷âD@†àËaðŠ.\pŠŽ,"û%ËdL‚2ÃÀŠÜ¡úZá›a )ÍæY$·ðØB¼‡N\o®-rÜà°†2¶õhöè”Lkò†ù.!ÎB°J- Ά ÈÊÑ.ñøêP!€Š# ¦â@x¶.¶ìbÝrb#,qR G —îÝ`FÆ!jKT¢†¬ªŽÙÔ’f¢àð²{J°IaÊÄ×ã£J¢u!&SJž³‚3†¾æ5^ÅòÀ-þ¢fÅQŠÿI;ˆôr)tíÎNkA«z”±6ìFv"©r.¢ –Ô |W6Mm¤†-8Êw1RcJz*'O'e1f—D<·¬°°U„ ÌZ4‡†S˜ž¤Fƒ.âðnà-ŒHjNBŸgr³0̓â¿Zºcâòd<-Èjuvªž÷Ìç1„ ¤âÌwjœwž<Ѻ©çw9ÌDàqçj÷ÆŽ¨âRb€È…Šº-wÐó–M*¬òŒh$ º‚ üp!pnôÀ>£-jEزE¬< -й ö4’~逆!ËHT…iØžõiˆtíË´ ¦²Ö`×âû€_¡_öÒ’ïšríHÈâÁÓ˜Z4€L ‚2 àÞ# 2ž‡ !aR!Ç7!´Ç+Ö’½@ÁÉ®!’†Z«àÄh €¦ª]ƒ´·¨ôxeÄ@B”tš “Kév4” !%ÇnðA©KC‹$Ànõ+Ã+¨êW":A«?†ZµÁÐe,fÁÅÆ_‹X¢p2!kX¾ErHIR—K,aXž¡Ãð_ÛRîÄ5éÓ3õ. ’Å©è?„»3ó“œ]58¦‚ŸkІº’CÌÅ“qjÊr!g= ™ §hpqÌîí“6Câ ï;u#Íjp1Ho›O8Í t÷Æ÷Ãã–—j@iÞõj~<ÏñƒÌVCâ}ÔidÉ *F5P} thx'ö@bres0¼O«'c@ÕbB¦_jB0DÚ@”!>mt,!ØÛböˆçà—1ØŽëàˆ!n8{Q²2‡!Ép#6’"Ñ€ñ Æ@Áâï!¤*ëzâW.CpHb 8# ˜ ‚2ÀÆ! Ä!Ä\¿„ Ù‰!o› ‚ú®(ýAøná®N—Gµò¾_ ²X¸!oÅu0="°ÌF§ÀRx4²‡míðmà>Q‡ æ4‘mI¶5˜Sè.”«åUðœ™K›æ²[%Sª ¸M£Ž×.éuRâÈ  š<@g"Æ+VÑnÓkÃ㥻BI8²ÃêÑ a–«AE#Í"£LqYhj|#ÌjPæ'h ðÁ`®xRÆ>7Ž@bÐvˆ Wå/аñ9»¶NÛšgŠFŠž¦g+v®é6õ«3ƒÌö,£Ñªñâtú<ÈnĘE4 Ë<·´L$lܪʴÊj°Q!òåvØ/›EˆuT“ÝNð$*[ Ô$ šHRëhÛm|!,¿@mš( HA'‡"àÞMš@¨›fø¤”N!+ñ"“(JZ«ŸAB>2’äˆÆ5HY44.L Eè l ®Ò‚-6f"ØUc‰*Æ2–D)ãGHì!É¡ Ä„o¶ +ž^®3æd‹ Z³>e«È˜"Ñ'åÇoZû'ƒ,?Šâ¿«°­ðe&’XÐ?dެ¬mî®. 8¾HðÉgjoæ!s?¯Ì€®)œže”KoúÜ<ÎË-Xü\]q߸{ž7Žž‰ÐZ©"Ä:àÈHyu_`‰·Sr!8<ÎFqLâCÊýÖ̓ã€MØ>(øP(|·VLã~G{U™ªÇÌšË4>-&Êkº->0‹]L>$ÌÍ{jCǹ|dS¿—²M1°(¡ºI€Ä*“˜îph}]L’M*ž¤è (&gw$BæÂûHK¹Nõþ†Ì ó¬ëÀ/°%dÜ2†=:æ!Ýj#5ú¯–ˆ]…ù3J!ËY©X¾Lˆ#-ËG\½SkAzІ& ˜‚3°(ÏBE܇ޠ ! n mÌ+ œŒÏç6¸Ô[yä:¾!nú!(õeÏÕ8§\n;R¡]bþ0_⥴â!(`vS?IÙNÚìÖÄþ@',¾—÷#¯&¾aRA¤ÏД¦ÄÆ8,4´EÆ;YqBТk ƒë££JtNÊ“†þaFCÆùôÄå=‰f”!j²à •3wÿ84ȲýÒ•çZ±g¦ÄŽ3&õ鎞qM&•ÙÂîI`ٻɣã ÇŒ{¼Êgþõ&Äò-ÍgDCÉÞ|ÈÖyªeµ‡jîs{dátÌ´¥¬Ñ" €¹àæÓJ<Å"{¢‚¨ ¨—DNàÆz«J*ò¸6.2!Öª=^TÔáü€a* ·øò(½ÃP0þ†!pØxë gB™Pׄ*âÐ t&†‹áLk² ˆKcÐL* B‘)ÔAù [BžpѼ({ Ãdù*•A.!Kk¦9†’¦økÚ- dC^4‰ŒzI" ãÄA~l:öK.åÃE°ÑŒ6suÃUÙì† †aDÈhNwtˆÇœ°Ô4= áq±:Vnô¼B„˜Ù*Hû†·!­˜kÞ…?lQìä{M²ËãÂÈn†êÁ€\Öô5ó±ÇRŸU˜ü4 Ê]!˜n^=°ÈC\PÞNöE¬g£Üû¼zúì@@(hÎãõ€.ˆk›µÆ¿€UÍ´{Õä£! "&èóÜÒ!§ôû€&Ó°ô$M¥5Èð~†Ð!èi"†ºÀ(†‚Èh !§$2ôktüA¨ñå. DÀO*XüP~.@A‚³ÀNð‹¿£ðÁÈhòfü:OÃú<èôDü)À*ü!ò`§+ ñ*@TÀQsÓ$¡P”(=HqÆ`üGïÀq)ÀTüG@~¿£ºJ#¯<Æ?x$€O?ÑôˆŠbêÜ+¡JÂ= +K©¦n cô™¯$¨ŒÅP‡)Œkîèi¤…8´ôôÔh€Œ†¾Hx†×ˆ„Š—$NzH££ÉB “#Ñ2!#Å«…9ઠ#Á¢÷B,#öE(ñdÅ¡U ÷[Ý7˜6`7"Û ’EÀ †Á" XÈñ|/#ǸzCW  ††HSú—­¾ ‘¢ Hˆ èh|†Ò÷­ö‘B¡° À »f÷¡¦J!¡ãÚÑW íbk%yŽwy>›jå­åç+m:;£ÐMé£@÷•ΆâÒ°Š7ªQð†¸(õ¶ê €Ö7C–ehóšJš<SéhöÍv1âhñÏ0€Él«ð2À^Wbá€æ›iÀŽ™ºm:@¨ß@JLþ "±€¿,¦Å-®Bˆÿg x±&ˆN5dGŽ 1Dx½‘,fš ~j솣û@q!NÙ€JG…Ñ WÍAoÀãžsÀÙ e­‚DŒKšIˆ"¤å˜ÝÅq *)æe ˆó`#… ³nˆh^Ë|jƒ²<+¹Á¨#SÆŽyC"èà1“HôN#Á@½¡nCDüy.n†Ð8σF冭pÈ ±Y1ç@¥% #Èi "K4%êR’€„íÒO›ÑÞB”^æý™6–,sÜ~;‡¥7ЪÈòÈ'é±ËcŒ¶@ $p‡FB%³Œ—ß°€’Ôý¤Æ”åK“A¿Ÿ €¥I‘*™Ôr<¤ÉU#ÎXüP²ˆôy­Ñ幓ðëó} 5´ä/ˆköMQí=÷<§0Lóµ6$·$Ã"#hÑå%'÷\ú2'âm€´ñSñ< ÜAP(¨( ã;yÏÂÈGÜ)ÇèÓZzëì·”˜*ˆèi!äU&Sð{£†Må;1ô!@ÿ"ÂU@æ §ÒpûœÃZ‡6ûbGA·nG•* …r„†›P4àpR’RJ°2Èh»!£„¹¬ù(´å! O-ç0’ uDz•†”Æ€¹’ÈšÙšQƒô>@ûÈ…B”ö }r<1B‘ÁÌ ð__Ù $)Ãr_"ö˜ñÆÕ€h¤ú™Ö ‘1e⨯IV×Yb6!¡:D2•C@ ®;ä*@Üåy·'üÙ7(D•]Äy/žVÒßÉ”°`+ÊfþRŽÍ¡9’‚õ+P{o}÷±ØNÙF“¥<ГTÏ‘ê–G¤4Ð$EH úfG€•áI¨ XЕç4‚LÀ›Dg;«ÒÓM‰"»áOÂñ7È ±tâG¨. OP“P(ê]—•Ùò¶C¼úÃçj€ S€)ª”—ºìY1Ü&Çc.ª*„à &(z…¼(x( ÇŸ‰»”ÏÃÒAQ@›"ûGx~èCÄÁQ§âN*„¥ÒC1Y€u; Ý" æÛAâ@:V˜y ä V7‘ñqÈ„¼«µui€†Cg0†ÊuuEÁ6B™ (Žèjr!t† 6mÂÔA© –€ï G¬±‰%Ì’72¬GÙ rhˆcã K™"7"2aÖXn—Ú6Á”‰¶’H<@œë ëp4‘Þ&ñ äÊEKåö4˜Ò¤5¸E@ P#×Kv›Õ.Q ¥@AYG_m0*ìÝ ÍYsrtÉ mÆi —@æ…ÀÝB±Œ†ŒRy õ^MþyW"=xÇ™Í*_gŒ‘-ö#F¥ºžY)Û*¤5/Ê98^ð\Oê€yRãäzUç5åŠm礼a³8’EÅ葨º¨Ð‘'¬:r©ÄvIu„æcð´P˜å‰™Î×b”º Ìy$7¦Ë-Îß)";` Ö&DÜ‹ÛÁd‰ëãî‹àpŽm@U¨üd(±ÃÄ›iwØ7 úP³Eü:5ñ!5D /’ ìZˆ€T±šà™·ë•4…aš@ÇÊz‡€ì@ÇK³ÈÀŠr½%î¾ù„Br+"°Ð) 7★ CoãœÀ'IX oZx®–^‘à± LÉ ^û§ãkÚ˜æ!Mlê¾»¬ 'ò(P2ø¡þ¤¨‰’H¹@’°>˜l¿<ðqPx8ˆ€q‚¸pâȹ{ÀC ?€‘(CˆS ›º§/¡~-ª®ºò¥Ðƒ€”òQ®rnhAª¿˜à‘`·Ø>x—@CŠ˜ÒO/.`ÒÄ0ø¡ØÞ¸ºH7èçŠQ£-àš2ס(¬ã¡ˆðß¹‚pˆk¤¹/y(¯¡ñ*йËÂiÓJã ((­x笰7°ãË€ í„X†·bo¶y·šbd&rh>ì&)g–òv©¬‰¿À1볈ÿ;ƒ¡È8ªŒ›!ر³ Ÿ+3¹"”™.AÅ8»²:6—0Y1¯˜šy“‘D¨üÃ£à’‘6EHC@3¹8” Ž…0Y*¹ÉrŸ¢+‡Øg¯³²Ê`‡òF€n–@7ø†p‡Ù*$«ø0†… ¯2ß œ®€¹Ä3B¦:€ :ÖˆóY¡D—©²5ÈGÐ5¬'!º¶A“?¨¢†Èn€ Ü0’¼¹¥/€%øGT 5ëf™À…CCX¶¸Æ‡ñ…𠛨<ðøÙÚøˆQ²6D6€ÎÉ28³T îˆô«LSg4Ì2ˆó£®J¹zi~­‹{¥2Or­°„! §B)ˆóì9h‘Ìß½Ã[HBt(À²*ȦY1#g›·€ ñØ4D‡AZtÄH‘1³ç“ ;ºòÚšIÜ즂½%&%Áĺ Á%Zu “€D1 Ø¥Ã`€b¿’hÂe² †»òÕ  ßœJ€Da.ÄÑÜF€ ì²:j³¹Äºâ’)ù3À†¼péì0l€VÄÖ“Iå`þ€°Rr3`Ú0ƒ‰*ã°=Y+‡ØX™Æ)["ÐLJ©-»zAq‡Š>*dˆˆ™X§`B‚*Ѝ)Yˆ‚Ì1ô˜x…:Jí€ g?Ç$Ä2 [ƒ ÈÐÛš1A7SW pòƒ`…7é~Êìï€ Ý?Š$D\!ÊÀ†È°%òÀ¡Ê"°lL¤PøP…ðCH,ð@¸LØT‘£H¡~§½,A¿–"ôªš/k`¬˜…>4©“„ b·€©vˆSJK\¾y’üŒra#¤ELœº1‹I¤¹@SÒÚ¦‡€ Ù'X†ÓSRº çδÒ-©aG ÷lÉLýI™³'“¬2€ ~·¤X¹k°?±‹)sy'‘a4hüCÓÃF8†§Ti™ÊNKk0™!ØŠR~ùþ¤Á,ôM‘'ªa˜ý <«¿‰1âIy6ãäÄ‹™$ó°}hë1“¶ÃôúžÌòW<î©9¨ÉBxk‰/ i» à#ð>댈ÙÀ~ˆèg/˜5`†™¨‡ä%AÅL°’@0VTv¥cæ€çƒÃóˆ…,PÄ ¢+€RÀØ…EHÇ:0¸UhÙkœƒÏ8<þÀúó!à†¨MjÍNP¯éT„¥›EÒÌ—¡i³?“ýQ¹Óò¡¤¤ÀNU“&qPÓnº Rí‹ó»csX´ˆ¨¸Ÿˆóò€ö™mò_ybiF¦¸…^D’Ƹ4Úס¹»¡ÊÚIVNŽ|¥){Èôš?ˆ’¨#ˆðƒ°ˆr4Q#€œx  8ã…ŒˆX¥`YÕ++­©n“œ€¹›$dDa™qÏÞ>SyS2g¶ù³¹B1Pv¿ I)/ñ¹¦èBQʈSœa …@1ÅÈ[‹Û©z›Q¯œ¬à‰œëI›í}Ž‹0…d¥?kÈ]IJ¤å•m €Gq˜ˆDšUÇkî>—QX¥_0š0÷,Ð7îGGéÖÛч˜æ.€XØ·sƒˆè´6Kæ¿èõˆRbš61µ¹%ŠËþ™±(¸ò™n¦ÂUãÿªô¯®¨ÀãThüf>,G´u$£ê_\V?ƒöçô홊x†¬ÃZœ§Ï€ ymÂ÷ñ÷Ó0ËU+:ÚüýÕ‰:çÑÔa—’.vÁX—ïgýÈ1±‹<‘¯{¾’<ÄîSÍum^*h&¬ )^Y"ÎÁÄ›…è2«¤æT?rs!r¬cÅq"æ{2<†€ èCi,í±c(‘«žË2w{DiÿÿÀ !.‚€à`Ãî lXA_®¢ÌŸ*`­¦ÄÖu‚±EWãú ƒ€e@Z ZÊÙS7ä¬3–L'` ü-™”ecYššV«™Ëæ8xI3 ÊÅõ \¶,™ÖæT¤¬3>LÁr¹ìî³3hÊÔó6®%@´Ïi÷IX²Í+fLß³ËFai¢P Ò±ÔÌ  _èé]†€!•&wª [i­Ë]s9 Áñ34ÌÁXËUâ`ã¸LÛ6½Pì™Ò(!ÄÁÀt ; w@&ª‚ ÊÃ31LÍ‹3}j'û)3ãеÙ[ŠfòâsÂÒ±”Ì?ÄÎJ×s7 Ì 3ÚPŽjqðÃ(¼ß¡Ãâh@&Ú°þ6/“by¦aºf<ƒ÷œSü|¾ŒÛè´¹á²f ÁmŠÒ—€&"` šæÔÁ°³L…)›( Øî(sè¹€M 3)˜…®‹,jÆ ÈQßC©™ì…1j…9éè 2èRÓ( bϨJœ Kª–ɨc+ @1$ÊkËâ RàR¤¨&bºo¡Eê Jº!€Iý'!Qz S°× Fìæƒ!H|ö…%àØ<(9) ¦œ¸~¢Ú ƒž‘H”()Ìo²ø+Žt™ Zj˜RÎ+ü¹òŠ`"&s_¸Ršt™Çê`•ˆPKPÎ×Gªfa2©˜MlÜJš˜ ™P•šoÌȘi˜º¶%eÊfo5kõi€êfèJ`w&c²WCAµû,²€A–ÓbÇ€¦a=Æý×` ÎIˆ™œ²a‡(SòªÒ'( Ú€z–+b¡-90D+ê`tÃv#ôç½  ìÈéèî¿(x€5H5 è ;Pâö é\Ÿ-3qÕ’9Ã0JÐN™ ™~Å&o|w©Y O­gï*€›¨>Å?hÄçƒIš¦ G»“bj&g"ý6¾zÄ õTÊ+&n»…)žëÊ7,oiE3F,펓Ô5Tê3€38õ¨ :i€:dÒH|Zv!VZpvÂS ˆhU$šHQ8…c²¥Ü5 cL€Nš€5!\H1KjƒnoÑ–˜NS¿K¡Q— ×~4ÜÊ…kdÛ'VìP\ãô—Œ’6Px £Y0à–Jƒvað\˜+¡ €º&løŸ—t XG&gœ˜,9Ì(fÎLá@kŒ5p& Z¡+\ bVýXÒ)ë,•‹"f+‰›Gè3’´0€€2+x 6Ò`ðŽícOüÁ2`¸J‹&kr—bÒêÀ8%k¼ "¸¨¸&mø„’VIœD.Ñ©»!›É›&u¹ÄuÈ å „Àq´r‹e>#’Vú 4f+±±–ºÿÀ­(•|Ž…;¦0Ot‰cƸúCä=›ãÛQÉl9SbÈÊÓq“$.TL×fZíMuR” P²FS-¤ )ô=ž;ìA®Ø;Ð Jõ¯¿ršåÀ Ä}i‚9îŸ š°DyD©Ú§—‘ƒNàG À F…Ø85žhñ!IqÒ”hB¡!IîÀJiÌ¢ãù}Šþ<Š÷8v`…=ÅO@‡ SÌ?Qø7‚ðÿÄô?ˆ¢ (Q"&¢‰¦Lá10†,A©•³ÒP¹+.%4"f \ócLPÄ¢a q…Í™Ôàà ¶‰äÌÉx®™¹+E€´ßÑ[ž ¦ 8I[gDÕ¢rX¢f1Ý÷´Å,´p`ñ0vKá|D@~LÁ™+•ˆ”O³üZg˜(Åç”ÁeOÉ-l%,æPÕhÔ ÜP@\Ÿ ,˜Fâ€U\`Le“1ªäÏÔ´l¨y弯Œ½8‘HC—&±/t/vÒà™»ú }#Sb†2º°»2g “sÇ vvKW*#¿Œ€ˆCéÈ\û5lSí ÊÅHI@ž h2òêIšziŽêUBç¾æÉéc‰Z!çBíIœ>S‘zW\°4¸mnvOΔaŸø»@MÂfp¡ dÀ åÍâ ãy Q¢©¦«¢„ œ1‚x§¡Œ…ŠpZa))õ²ý@ SR˜€* #Ü{‰QŒv×á£bÔ¥t¬ÓZZÖºà²Q±³Õ„elAÉgÄè53½½œJ+¯Þä¢dÍ^£ ÈIœ¬0` ðÆHþ@ï,S$ÃáJrøMÇÛAõ²Ó9( 顤PÐà[ÝÊä*ûÜXüèÆ…u'9N&5ø UŒPž§éÛG§È{½ä©Ö@3 Oâz€,Ú÷<‰¸à ðL‡øqäZ¥¡ø) \æjvÁÓ€ ‚B©+ÖÒ:înL‘3bÛÚM‚JÈ©@PÖW;"ô~dŸ ý7I#iÖRh VãŠeÒÅ(Ü䎀xµ «ýbf#bÄGÝÙ‚gñý±_KU¿¸ûO{±0¶b€ñãôá@Þ.ºÒïº&hàŠ÷è (¾ ‚` â(@ȺšÄÄüÛ/ Tm„m½ Ê‹V9ãž âVÃæ:`ÌÞ( Œù jsCn;bäăb•‡šË€ƒLRp&Ü6)¶è‚ÒiŒ¢K@”ȼ•BZÎŽpæGv°-Ü&gZ쎈c¤<¦éT•F òŒ~ëð®H&:µn:©.ªÿ ÚjFZñÆxìÌ`8ÞO\w YC€âãGi…(kª`ÂÓ%â I8ƒŒô!Jì` ~o€àè nJ„ÀôtˆŒ§Ê–¢’àŒ‡Ê!NØ­jrrêpÊ€%Mf7ùüìÿ;ЇûšUB*˜{–$‡ÆÐ4 ÃÉÑ)zCÃßQ$ô=G ÃÊq"¤<3”Ç£ó˜ôI×[D–ðùün: ‰¡âˆ“¾ĉT#ÔèØ/«Q¡á8‘E‰¡íè’ð‰V@0¸ðÎ$4‡ƒcÕh|æé(‡Õ, ÄHáFg(Û²$²‡â0µyÖ0=‰¢Lh{$òÇGóPðŒH™ž‡·"H“ï ‰!ãX–²7ªžàãzhÚŠò ÆÉF}Ñ¢6 ãkWŽëgÄžððFÊïÏžm4^œIý(ÃÃxÎ.6Ô‡ø#}íDlì€Ü¿¶7×áù@8Ù>‰6"M˜“âÒî#ëS:¿ÈÙòç3oˆ‰‘Ò‰¨”øÀ.²$æ£gä;$"GC !Ô¾ S £pX;€ê$±€¤q"QÄ Eïcâ»<ñ{è…ˆAÁ/(–ˆ‘¯ƒˆ“ðá¼è‘¯M€¢Aò$‹Eä²% EðH¬2ÄJ•Ê’˜5ı^y¢FJcÃñ*ÙJ‘p¤Eàò%AEà!ôS†ž£q¢<-¢BB@.ö%š›hy`‰(xH‰ (º½G $_¡ælx”Xq:7H’вæÇ-Iº6¡ö046.%XÇÀ †¥µ¯¼9|¼ ¢•h‘|‡À  ‚ÙðnõL ÀÊèó¥[É7@"EÃûZ³(’N‡h”ŠHo!4‡®à>#bˆâ¢²6¥¸ÁèÙ‰øZç'‹²ìò:Œ‚=8’v‡ÎB%ƒ¾V½†»#ð˜x¢S¢ª‰aìú< 9×Xñ&úç¿èÚc¨Ì€ ÙËRÕ§7Ì#oÒ79òL0羬3²;¾-[Ñ#x¯®]Ú’%IM€sxZ#k"6qÇ”{åÌEüà0‰UÝñÕ#ç$JE¢]œŽõï4Js¢Oh‰Q,¸™-…%LÀÿ‰ÛÈÙÑñ+r61D¼â4vÑãQ±-Í!D¸|÷Ý€@|Kq#tÕÅOŸ~§@Ľˆ ýæŒK„Åþ,^Ô`° ãüz¼pç á.ÆÐ)À(JyGË9[:<ÊHÛZ•q±ÃCÛà]!àâ /¶ ] šx#nPJÒ™ø‚m°^÷¿›-€]‘çØUsE‹9 €äW¡]‡b$'ËɤH#ðRÉZ‰_£(‡®×Dƒij0/ÕXYk±¼”’”HÙ#oê!E€Z Ó #ep‰‚éÑæI`"6¹ ü£¢>êØu"Q8;°ÄÈÜcM" ’™QÜÌÉÆ@ žUpÁ¨—fa™YDmÿHžCˆØÒAÇp GbìÝdý#îÄ«˜ÈZÄù¸¯x,êÎâlII¹^‘µ ψÙÔ?„m˜Ã”T¦&ƒG>1è)x²è¥4sÏnR"‘’‰c’#iÉ>ê%,7"Qð$Q+ÉLæ%L#i²ºÑ @ ^–Ʊõ4¸±ÒöVÃ\CéÍg&áC耒€\ŽjÁŽMÑ\¼6:™"Ã#à ‘°‚¨o#Àp‘¶±^!§_0<ã¥#u"$zŠ%ãêD›õ•;ªI’ú‘új+¬2°Tg ¶n¨Dïú$ïÇ¢óIBI6“uDDnm€É5å±v-SHÊå8'm°…rNñ:¬D–dSÀêBüM!‰Wìþ#k2—'LFÒ%MÖ°»8¡T Ž1þ¦2$ôð£Ì[DH7"W»k.0IMhžše'Q|¸MÌ…g³Šò QEÒ÷Ê¢ÞÚn§…P8ÞZŸÃÛ£¨ OLOGq€LH¾Sb•]^rº;>ÎVèêG¯Ø‹À«4rÈ!{lú L+Èz²2§œR;ò1;8L7Q2Cóö!îô¶`<€ „Í$õK^€ ”#Ô\,ø{|%¸#Âå…&ÀqUZ·qÖ¦Æ/õô­ËU)0¸]`VÖyê‡÷NæElf¾«ivj¤o[ RK˜!òY[ê b€µ6ì ‚Ä½F] Á“cB€(ÈðK 2d2‘±¥Ž†;•lSB7`ÈÛ‡n´à[cäX—IÄ uœê.È{’Â@{` Y°oi¾³TáÉDc¨¼E)¹Ö €\9®•<^üKúôOñ㨦ÎpÌ!ƒRK„Ðn8r™°â€ jm‰7ÅAHö¹ÐS\IkërÝ 2ËñÞÏØ0D¢@¦äƒä†2/D¬mâPLÑ{jS€ [Mô_}ÀD|` ~fvH§pÑ:b’œK¡xÆ8*ОˆG@ ¯RZmGuP$à =Ì«ÐV Q JˆÛ± Dð;ßOQð ÛF£FµUm—Dné€Ò[Ä8Žä?|¸½Hx!ñÑ‚«{šFƒŽYèb逢!(‡Þk´¾± V@¸€‹*nù„yå̸Ë3kùމqT½`ÑM¯#̉a²y‰¼Ç`…Ù耾IÅ…ÚþçP*O¬1Τ#mNUln쯼†Kr÷¢$Àfv@æ#a’ â<€ ¿ ²$$°¨–Ž@ßÄ’#æ<Ûë sƒÈ÷B<Æâ>×G¬(–-M8#h~î ’Ãì#nD{CN.Ë*&@âIšã¢ì¢ïV)f0[KÂ#g$ÚB6oö›Î:#áÐ.gû`ÞÀ ƒžSÃH±dó /ÀÅÅ6"J.Œp´˜„üÎ!4¤j‡l}B6´ ÓÐBD«ê-DÀFêLÂ?dþÃδ¥OòB#l¸#îPDJkÎú §¶aîH–§†¶À91 8ŠZ£‰À\ñDÔt§~|QPîCÈ @©ªL$òB$ÌjY«Ulê6¹ÏâôôrA@ØÂ6ÞÅ%ššEª#͈c,Üòì âk ¥n¹kî ¾ejëÂx´ Å"j#Ɉ•hìhÐEòít Ü©¢6Ô@åÂ>%Vs4Óà£Ã ª"F= (¬JÚb¦*€Ì4,ÜÒB=çømbxð1ÂìE(ÎÙ§ "Æ,NÊýNQ$JÕéê{o}‡îD±’Á áþ/Z½† éö!ðnÈ¢q| úá<ÚÏÈzP6øÂ<Ù`Âtý@¿o.œÀ¢0 "ߊ*ÞSÀvàr¢0¦Y¦ê‚æ`¼«­àùåšrE8жÀ˜NEÈL’€|"M–­`åæ$Do¹Šê·q….‡dP!òxÙŽ ×ÊS!1|)Õ‚D¦ iB n"T@˜â:½ò «­u¾+–½ìPE1zC¸½æù Hø9ëºÇâHh—-T†E3#l¨#ëÞøp“LîÊ%«ð>ŽÞ"LyDLS#½ë a¯”ïilè‹êÆãÉQ†dK<î–4âJ(sˆ“3d¨n©L6€òË5/Œbõoɤj¦ bvhÆ¢@QæF¥oJbç ;Sç'¸D£TΫu^Eîë.ÊlKAâ"2,æÛ ssOÂG€­G=,À,Ó$4çw9¨»ïS9€yaZ(Ô!ïwÎ;‘;Ó¸*kb8¦¡*ºa‚$ʯG"6’Ó⫳Ü~qŠ!ép4¢T;RÓ¢%l– eÊ1Ï~«Â¢2°Ð/±è4ó­)錹jôÙ,ˆ€ËRóò$ãçø„Ò_–Ù2d¬!êºÏ)ÂYÁÎTiFÀ`¾#ÁìôÖ"@¾!æN/PiëI$†òÀ2*t¿ÒX4èw<ópÀ•ÚÜÃ@#sÎ0Ì–Â:sÅì½¼ŸKñLòÄ#o7il6h’ÆŽf¯lÀŸ’‰pÞGrL#t†jJ¹6æIIkq½QµE B$Ë“p”ÄÈuMyaĨÓÔâ.–M(en€{cÈíÌxHl´ê¤_÷ ~s)TGÞ½ôø<•=Qñ2¥ÜDö²Y3îfK2ÇÔúEî’…@;ÇÞu „È&ú¨8#Ï^±‹2ËQe‚$õ¶7bF aï4ìÀÏÏ[¥ôE'صÐ6!èD‡5ú#Îè%ž%UÚ®°‚[!¦Äò自¾#Ò!rË(!ìtOš-ìY²'&–T‹÷´n  -K{¯J6=wôûV–¯j<@X™¦<ê‰~bìšHüÎ`"O~Δ‘¸"OêÀ’aô:k‚æÀs$DÜ>aÒ:/ð#ÎZáìos"ã§8¯h“Â7:IP‚t’×Fùa3§}¶ò‰e™B®Ìܤ’ȈvÃðªÛŒxámµ Vò#ôÏ:Ø™m‚>îùŠø¦¨]4ö°JB$¹ <"B‚#jÈÊ#í(µ'¶/F°™,¸¬Â7BIÁ7.œ¸ÄJ„Ì@UœEæN£¢ìc _ì:J†q0`œ Nk@ylÂÁçZîùN8þTø{s~^ðf槤JÙ`kÀ©$YªÚ²ôÂ7z€'‹ÀÌ!ëëÔ-b9„!ò`#x/_ŠÚkwx‚7YÿB<™V±@÷”:#¤Ü["=He¦ª—¾#ìš } ÂO.Å1iB<²·(W Œ€:XùI’T¢<ñªÄ:KBVÃùsaj#¢¿³=$ãHrÀ×€¾ª."Ÿ§|#ÎáI«¡9…›ˆ†o‡ý{6^p.Ô  #afB6Ð ˆáèP†Êá­Pf#v "YªpI.›“ý2(~:”’sÁ ‚=]s¿Œ#âoÒÕóI"?:ʺì±åm–´"R¯EVÙ›“­Š ð4’’иb©·1-¸ÛêºGÀ•Î'vr4â´I¢%29{y¶þ{c¥ˆÏI5ðÈEìxéɺP¬ûtî×rúTD­)G(Bõ2ñ@Eõ-è² ÍO@DO°#§Ç„ä ßBrÁZÑF"XìÖãœà"#a‚ ËžÝnÒÝå!+W@Q8Ø#l ½"?|´£¬sHw¯T&<†Ø÷Š.#ë–eÎl"%i*ø: >(w­¨Ì"Pµp2Hxé+º#rŠmD’Oдpæ°¿¶ü>0[T VÙ†#|D¥˜ëË–kÌ?2%<‰sˆî#ä}Èi+ëv›Š@Àçô’Ê•'¬ôêÆàEäÜÍ.Š"UH™5tŒ™“vEë!O„'nó¾FÒß°@7„ñ„K¬õ}‚`a'ådJ³€0QÅ;|6N߀Ê  T ¯¨ÏÔ˜£¿¥àŽÊ¢|óµä#`þ!ðYgº³ŽsØB4çL"Z¨‰ w.Ó[Óq]o]b3ÂI=gÖ¨¸#Û×%n¾¹Êñ«¤Wì#y[.B6üœCƒN{½K`æG¹B7y“ü.Ê)ç¾:Yîöe‡l‰€6¡Ÿå=Ôš’Æ ÇEn密ö´–”†½Zî6+…+²<Ë{d鹎œµ+–ÿc¸Æí±óâØ‰s N.g¾ôYéHßͱ¼MÛ«KÂ>mJÈk „"V]Ь"Af"LRkÂ>ør#ôE=_´ÎCR;‰“ª~:MyW‹ârKúÇPPKëÍ Ì0hûI.°ÇˆÆOÜ @d_¡ Q5l4>KG<Ó×6ê×Ktù"G¬HÇtÂ75G„:‡g®|¤5"W„ôD´ô\€Éä^“ºRHh …­v!䇃p*!ú¨ô]kdÞ8qb=RyZì¤É¶„#ÎDü×zo÷‘Y“üµ4x±è_d.˜#Ð:‹%¤ù€È‡ó¤î¸^Æ -XZoÎ+s¶k¶rŸ„ì±ô=ó²"WÓC ŸØ%õˆÔ@ –â‘ȳ¢<å Pþ²1I‚$€qMwØpâíY§y‹Â6ûÀ§›ÐæiÀÇ‚Ôa­#Í< Á'`(B‚PGûþ%Äámh°,9‹"Ñx\b’I#PGP “Káó¼ZW fňñb4ÈžÅ`X²¾-B…“bÁyäÉÍhEœ±b XË>«P2 Î,Ò‹ c´ºÃ¦,Ô‹:âÇx°ž)«Ìàx²Ö,þ‹ -ñ‹ubѰAU{Ü–c~E˜VלXbÁ¿bÙ VÚ&‹°NH³2aƒHm³ðK €±·ëk¾,ê¶É'à,üSƒ½] €ûhò,ÐïàŽ j–,¶ñ¢ F ɶî;0¢Úñ¶º2<J(ŸøI,'K ±a|³E>"Éyb~u,/Å…ÒÉö¯ü‚1hYl‹ébŒñ4IúZ‹‰c‚(ˆY²þ¹PK”—!b*,*%Ž£ ÿ{¨ic(‚‰c`˜CçÚ-¡fz,v4Xn‹=(#fH²n‚EèZš‚B“dž"Ð蚀'„úÑOˆ#|…½h$ŠÜ¢ÄÂY5Ïkx¡`ت„ «rä‚3H ‹h´Ü…‚‹ÊÞÉ%RXø €Ú-!ÔêI0€ ò‚;Œ-y1!s¢c,èµa,@ w ‘j6·¶cEb€&B,b½Le˜’Uî +€"ªà6¼ s­ïkv •b¶QêJ‹T@ ÍR­´Uyw€GÊÞÚÌl‹ iév5賤èQ² ¢ÁŠÚæ&Ú,y\ôPˆ9MÀ¼"+Nå/EBÚ^¢Øš ¿€/* e-´bØÞ p®­§€ïG<$%‚Â,+¥•ª| éb½e ²–hòüÃ\¿µ V%…r-=<`*‚²ê-u¡rhº!mt=D"H 2– è³Î‚3[¡Š-€¡rð)€-«IÑZ² –ch ô–CpòHì!ej-® ›lŸÈ( &–*h!¼–Úƒï l‚uÈf®‚V`$Œ¢Â‡écu']ë€:uò–¨·] «*m žxÈ Q¥‹)]L‚H¶2‚K}ÒÞý´Yˆ"Þç6WŸl  €ðÏø~@ B(µÃö"ÀbXgþAQo7Í€žýN)I"Ïià¼XAº½"À´‹%<ð O x»àœJË ‰”É‘`RÁRÌ‚+aõ›2á áÐnKȰ²°®ÅÑmoà?§ÌËl? ‹DbG 9Ö Œ¬Ã>¶:j^¡‡¬…Ðn~"Ë=ˆ˜C‰UåèÑ/×D‰V` ÓA¾[a4 "€ÇÄ2,`H„ 6-œÒ,;Kl‹DY˜€$ì–»6-¡ ú‘D ©€c’Ä›y`€¸kIc}{ïTñ·ÎA¹GŽñ8ñE1,‰ÀUÊû, Ó› à¾á'OØ*"ÁT–3¢# cƒ)ö$NBãЉOXD$BÅñ $±_JõZíÈ$³!pîRÉÇ@@ D°c‘e%3Ÿ-êª.BX­À ‚ ¸–AãDÉa; €Õj4²Ièõwª¥–³6È"i!qÎjÍÒÊÀî"Ĥ²¥$áÊ£@) R,4Ñʆ}o@D§ô Ž”BºFeÈ´È0¦ Røˆµ%i Ñ,IC!Z4Kă2X¸á„WŽ.8‚DJœù`Òc¤ unSþwBð‹A7ËIVp3äYÅÁòîE¨?_ÄY™½µºD),D­o€ÃÓc)ðj*I‘Û]i>-°Â¿HŃI l ­ñZ¡ ª^•Ú»Œql‚6&<[ÞhƒÍµˆÚz(³KjST«–ÑbE¤É{0`@¶ à_!±³ô¶¡Ð¸@ ù$Rs;2é žz ‘€ÀK¡d±WÏD<¿B!,º$4€R‡ÐI$X é¤ë·Hú*"ИOæI±u?HN’ĦVˆz0CŸØTZG Yð¸„ÇJž „²TÅ4ž{î„XâJî‚ l@µZûæAhÁPÆì(¥4Ú‘ „ø…ÏËDÁ8C“…«±8Kì÷lSa¡ó¡G¥«Y¤ä.}B3ÜÖP3‹IèX‹-2mˆ$Ù7V8JåÈ!``"BPêAp>!æ›,š(`æ<]"ËfÈßb È Ñp‚ ézŽUs6¸çKŒM+X 4–Tè1  œL:$Y‚>b- a“Åe¿Dèh’³}m%‘S¥‚Åæf&"ÑB@å_£"¼cÒV é™ÃOÍ"9ðàÁœ m©Kjg:n3B£dúí»Á¶Õ¥Î^—ÐuB§F3E‘]·DðÍxл«xeJmqf ÐѦG…ÏÀ|€ %›-ÍPÒK”l%›É%Î+™: fr4`'1$áîŽbˆÓ R,š!_”×±'hÉÍ&´oɤ²)²Xˆµfs³Êsûo]Ù,'$–¡õ^ÞÚÜ%—¤·`HúYzm¬2—K7´¹"Õ(j1nM'ŸK«Ä-ÒžMÀx P%“O›CT>í6é ƒÈ\Ð@‘@|¼xÙÚW{TBê<2âÀ9¬ð¾Ÿ*ÅÀ‚'iE/âj²é=’ÓШÂÛ¥ Ä,{lßNÕçZô‹BÙÓ–b“hÉu3”¿lš˜[¢ßUƒ 2©ËöÁ8®¿Wß|­œ¸ÚÇeÀ*|±I…G›b¡ ÍDTúÚkög¡Ô—iaºÅŠQ÷+FÅEù« øaæ å€ÓìHƒúƒÈ`óEëíÇÀÚÝsûpÖí ª" ˆgŒ¦v´LzúŒ†kÛ`øP«¶“ψ€2 j=0B7s¦ˆ Q cA²ˆ‹™ÿ’@H0¹X b·±:ìÏ Zc¸– ›}ˆZ_sÆÁQx¯ZWIžˆ Y c¤³ˆ´ˆYGA›Úó§ÛÐ9A`ºÂ‚ Ò~¤…¿„!3ø–0h‚9h³’ñAx–ª8 áÊ‘Lˆ±&Ћ5T§º{¤ÈKÈ@8Ñ ‰\.àC‰a=1‹IP%ë 7jϳ[ð'\ z 1|+{tˆ[‚+Y¡jwˆ#X/ÒS£QÊ%Sãªv>Ô‹cœâ"\ƒ°ë°â|õÜcݰ(–CŽø "¿Xè…ç˜Ï(ˆ )ˆ‚ ]y^ H<ˆø–Q=‹n’µ–»Ž>Ìç©`ÕCÅ~R–`è=Í2ÊŸ[áW N1_¦_ z¿?.fnÑzøC©e Î#¢%߀Ææà‹aˆÃ>J™e էܽë?^xé!hhCF#Zæ©s£´ýÁDŽþ*«ª!€Ñ£W• P[Ÿx‹jÔ°V~0qÛ l°¸½©tÛ9šÎÁ@¯\Üc©o‡ˆ\˜¼h÷,LÁˆ\Û¤ˆ·€>püA^É'–Z/ˆ#°Iê_šç3½I¤àäHâOeˆZËJ‰[ZVx–\ÞWs"p.8¾€iƒö:¤áI€“¹ô§¯T^AÛ£\ ÓRô€"œ—#Ÿ†LÄxÍÔ=0E3½ËQÊ4Ö%  {1L€ ı;µ°ùžÀ ‹©§KÑàT&2fÊK•`Rž'ÐL‰a‹¢¸€˜‚H3X&  €Ù`¬N€Ä)+ÎLår ’ä·ÏÝçöŽéi_uwËHcöâŠÀÑZz)B“»«’Bb㬯v8¬BcIB/ß×é`µä% 2¬µ Zb}9³›XÑ%òäŠÅmf t€Ü£´Xcê(ï‚™0‹-u€«Çuþ`½Uˆ„Í>÷£¨g÷þÀ€  ƒ…¡BH ƒž°¥äEá?ÒOøL Ñ‘*¡DY A ²'ü*I-PH•Шܶ]–Å$BøQ†DP…2¤G ¢}-†EÒ"ô(Ÿ"¦3ª´ÂÓ‘(aKêx‘á@*Ô«"SB–²'.{žK…r"ä(›"pÂ2'Ê\&…$DhTN{YÅÁ*àô)q ȨPKEc"—7+ò%ô)íœ•é €xQZDã¢ÈŸ[¤Š›.H‰p¡ìˆ {²&½,•–Ž¡Tø$w!åÕÀ:ÉnöB…j69®d¾ZÝ…*áK¹H…ä@Ì`Í ÐËY§Ï ë B©E΃yòÓv€ º¤Jâî:ïóæ‚áZ( È €, ‡à‚M[ø‚<ˆ n…ˆP ´€(Êd8@꤅Ϋú!D›Ø…hPf…(PŠ)ŽqÚ…èT‚/h#rÓ½)qØò¬èP`…¨P #¡Kê[¡@Ò&!AÜXÍ þˆ°( …¨PG!Gë$…)H:\ ¡BRã ˆº0 ‘ì—*¨:Q¤¥€IÝ !@ú÷ ŒáC8€ ¨‚.(;‚‚èQøˆÎˆ ´ˆÑ# HPˆ±NÕCHS”Fè BˆÄ(9°…(áþJ$ ã^‚IŒ‚,Éhˆ‘VîÒçfqŠZN¡EêEg»H(¥¬Eh‘ÈUƒf¥‰un)À…\ém´æY¬}:‚éd…/)lÏ/ L`k&DR!F"ExÙ• ‘Z %¤âAÚïî JE ˜«Ž¤SÀï%±ª .]—â\çMr›åˆ$\‚%€r;$TšÖ‚D€¬…f,t–3 š–È` j‚Æd¹hr~J‘"mõ•!E{d…ðö³±évb™iQ)æ¯;ÒçgôÈj ›f¿E¡DФFrT¡[Æ`þÔ`+“3xmÊXžeCè‚'Ž©iZ  †Ÿ¿¥Êmjâ¡ZH™€%§…¸é§Ñ³Qf…pÈF ®åÒ J‘퀠‚”ÍÜ`Ä"¶áQH d…xucÄ“NýŨˆ'uÑ ª zϨŒä‚9²ç ¡W›£×h#ÛVúð8"ˆá@ “õý@ –9¢*oRµ".v‡J€Otçr"÷Ö$EI‘VRDTÙg¤ë*Â\ÊÀì)ŒÄ%‚ ˆˆZ R¬K[`q$O„‚'ðHRé%­é5šO ÈkÐ… öüi€1!B0‘ BMIhÐ0E1q¤ÊKJ™*$µí“ÜO­nä)ÞØ8ÕK‘Î$ˆ·D~K^úØ'†ì‚¥”Bž ˆG^ŸÓà0ă:HSö%§¬‚)ð±À ³]Ì ç'€¼È °!H=ÒÈKSùÙ:@ó€ƒÒ`îà±’ †j‹0Ù¥ÐÀ v?çõF06ˆTh( m¤P¾ \p4db«E’ñþ1ç9Ù¶7ÐH¤ÜEäˆ “Ä{@ V%°5VTF Œ‚&øâúÀ B …r7x²r-…–ô^êV Œ®O x"à M1}¥¥üßÖÐÀÐ…Mè ÙuD©tB…b>u‹¶<´H”BÊ¡äEÁuBž g v¦’çðu„¸ë <ÄHT~Mþ\2žü5T` ÁŠDa@2jˆÓ4 ’È9Î`Ð4R â,L舱 z:Ë"µj€?5´©” ˆ‘.@âÈžÀD¥^f–k™d(,’)w>g›´¶AÈHŽP „‰›ES5ãal$C”¹J“°Ò@¡ \‘A¥˜¥À~$¤)쀪B¡a- ñ³ Õ)%ʽֲ[+-[e ŒˆSi²âš‰ £¡²FBƒ«¶8V†ÑGJKR ‡pàÂF8 Â9§õø€‚H˜!  Ý€ 3aÉhÆ#(w5ÓýS! c@„Il'ÉÔ”äñ2ÉK;1Jš”Å|Kj’ù6.çLSœíÉj§d(C’$7×àëu*†³*¡Y(œ€ ‹&jÓ%Á‘u’-C9Á˜‚*â-Ø¡@©½æ?KÎ7Ê4…?Çjåžä*¢¹c„ûH&/HT9âb]ë§ —›)¾ÂDH Í"37% |Í1‰€¹„ØPÖDo³m®O‰IÇWf¦@ U‡Ú’p¯Im×j÷O1`QŒçÐ…VwæEP0»¯Œ‚dZ¸üð±ªðHˆØ°„ÉSù<‘F0\ëé<)®À–™p‰vŽ ‘L }") ®$µ"Ãz5–´X±%Å mñ},—ÂüH³´1)­Ê¥¸0Dǵt‘=J(ˆ#t%¸ß]â(‰¶4PîÞ=î!U_Rº`½À [¬È‹/«[råhÚø(‘M†Ü2ñÒä³T'šIž¡d‹,g{$ñwâ#&WóïñÄæ’äøP ͹:BhTT6kïôVìW7èDbØs.ˆ¯ãÀAÜ!°º¸6¢ê¨ €©·øÈÿ€ OÃØ0Çì< ‹Âc <<1CÐð$b-&„½¡Š8x~E‡€äà f |Ã×0Äì=… LÀ v0š aéxcÊDšMª4<ƒ -ÃÆðÀ=ÿ ¯Íá¨zþæC*±« É ^Ã0ö5…›a…X{^͇Ðj7x`@†+UÊô1ù ECÔÐÊÜ$£ Ã*{mŠiš4¡ëÈcfH›!“+f~̇¬áLlÒ§R†á„+ì1½(›àöÓ`ÂH‡Š!ŽXb*Ö€k³A `šˆzX„¶Žƒ#sÊ*!‚òEº)±Ø†è’)!ñrh°m_]¡5Jh¹¡/u\³`Š@¡ç¢R·µ,€ ’&¡‚ºòÕÏCæw¡„" Ü7€§¦ÈÙ܇Çi¥°šV(2&„J!…ºe/í`ó!€z'!‚Ê!‡ª:!ë\¡‚"†!)säÚ¨ŽÕ¬šzÖ¯–Ó;d` Ì„àI¤è¡¨XÂh6¡ñ`g!‹ªSæ–{5+¡/úi$¦‰êhèUíº¦R!ö–>š'7²xÅh`p†1L¾î<êššCI¤ØÙ[Ѳ¡.òhÀ&–@;GŽž jh^ ©¡`5¡'(Lš Œ¦VÏ©¤¶„ä©¥æîH ¢î: |†K;V‰¤+¬E2tlˆ`’† ³â—€%¤¹€!ª,r„´†è†s<†n@ "[vnæÂéåÓ&†šy¡ƒJE0o|ÌÿãL²›JR8@ì` «á]M+(¡É£uô!‰-+®&ì>ôdø„>¡†TÀs«âwäÑä>¦@@}Ä 9&2f«É³Ð"‡žh: zÛ#l„¡2h¸ˆJì&ƒ‡†â‡t0xB£UÊú_$ÑU€,IÀ>L÷FPÁ ^àUñÔÐáŠB„<+Ç*™ÚYÀ7öfèálN!ñDî6à1“!"´†,€þ€‘!àm•€  µ!îMƒ´"hkE!䇶wÂP£a \Ð#÷Ò”™è4«  ÀÞjèy·¼Ì\Ñ€Ët†BbÛd˜í.„1žF%ŸRÜàš?âõŠiÄÑ~¨°Ìa4Œ@QKbaÈ`9hŒ„è°a&ÞHJÄ&‘¡K®b4Ü ö&°ËpΛܕ!# “Ad_¨b&ÅÕÞéÈaì&ƒ<†?Âhµ £ò‘>“GdMÙ eªƒÔ:z n€ÑGaù΀ˆvz€ߨ‰ „@&“I¨FäÛ1ù¬€lMä&‘‹‚Ťá4 ræy“I`ž‘4jOäøˆÝ$*<šI³¦¥)k M¼ÙÜ¥ëÅžà iO'Ò€aIȲ3PµP!‘Ò¡¾"§€†§¤ ±@B%*!ð:ªóH"$&‡€˜¼\û·!æ(š,à&ÌI~ä%ÜBBBBQ €p@¡Vö|`Y D2 g”‘r ³šLM’Ü7Ðé€hVy¼žÄ>…Ò…im94¯€ñ“BŒ«âò¸Š" CûD>‡Í9N€ $!* D€?‰¥‹vv¼*⦮ —°†QÑCÆ!Å!ådšrhZϤ_= E4€ xCY}óbAÀC/ ÊlÍ‘°BCÙË!ö~©P”¯é ã:bN¥›AUïœÛPfHLÔ€Gõ€(a‹€@.j`‡Ø’cF°dÖgœ N+­s>·ÜÒè¨M ŸåuPõl¥d$0û ‹¬aÑi“ÞªÄÄf ±è´5ÖÎÛ»u,ÖãP£>}ÚiBE€KÈ!Þ jê¾SÄBÊJúÄÄ&ƒ»n™÷ZÛ¼ÀCÇ"[;oKªövH~-ݶXPT¥z-P D?´ë4È¿;4„Æ‹ÔÊͦ ¸Æâ7…,°Ür,ØK>"(EM“Û¦j¥£æSć္@ àd>XT©+†‘ÄnEÇ"'•Ø$xÊt%À14xä\l@Ž3Îüb­ð\Cã´ÇºG‡M)±Õo¢›„1©Gm›ñì‹·Ig Ì}³FJ& Í ÈàÆdªó@ËП0½{u9²i}Ðûàï´Î«¹–fFéþuì÷E0k¾‹N&@‘u[ÉŰ²t¦2zÔ ÀÍ€@%œ\†œBkàÛ'â(hlC ¡ ÍDÙ“¹p€I£#øä'ä€gñÞŸ„9ö/ ªŽÊ.åË9ɤõ©küƒuŽm/„ä‚iûO˜Ž¸H¶0rª(!à½%ª@Ñ‚hub¤.Òǃ´#hÌ×eê²T¯ºÌÊl!æíaPCcÌÏâ„jÀ#ë¶&!ëÞÖÊRž/c°(I´ÚÂhÇ!#Æð`;CÐè¦èÚ¥ å-Æš ¶¥ HÜ.x&€°!éäiJ Z€*o â£ú  ‰RgHTî ±cH&Œ~—Ë„{ÂhØîú#mÚ˜îž!€œ éÄ H ¢ &‘#^h–à2 é²ÀÀ¯&ä¦lšC§PPBh‡i@ð¦VÿP~|¦Nñ†Vh â§ÀõÒ!Œ´&‡À«¸’j®£®æÌæŽ! ” ÀÆ‚òËè5€núžPÊG2of IÜ®Âm(Pfê˜ÀÅ8D jH~ ç HüS  ¥îØ €ÄO¸!ä¬&‘L°E¶ähjY@­Œ:(ëœ#eZ |U4_E¶» >BËË~!$!ã" Î!……‹ƒƒ‹0¯ÎDðÞT­÷ Oì1×Gx_M±&QŽp¢¾"J#6Â)ÙRL&‘VÛ `zÍOc´ÍANs†¶a RŬÚãG§&Ïö¶Ø`cæR êuÂðL*ÓðmÏhýÂWK0Ãiò!*âs)© ¢Þ è— å Šk¨Ã㸭‘ê‚Kxx®toeø%pTÂæ&öÝ@|« š§â!á4!R‰‚âh§ < ‚†ü¾ŽbU¤¤‘É„&Œ0²ïàŒ ­Œ¬÷Ê,Ì1ü&Œ îï.ÔÍ–.D‚!€4!‘ÂÎÌz褣-ñy±3R$Š©h|²ÞD6Ó'è¨ÞçÑ‚#eêFìofN‹Š€Ð)g¬úCçÊfbß:¬@þDäÒi6NIPo:ïZš$Á1È  ·&`Ï@q² [iå)mІŸQ ¹@bùÏ B‘cö ",ôÊXÂ65€Å`Æ!í ¢%AT!é ’ >À{mªR Ì!æp&ŠÄ>ŽB±ï’"ã0¸Uô2 ¶jØhæG šŽmà2 žPø’mÁ,KC)'å ËêNGÚà !í"[lZÊ‚ýàŽ@õˆìÙF¼‰ú!ò¯+ @‰(v´±#âÀ‹´¢îà­è¦ÀŠb€&ˆTãï/¢hýôˆRän!,(‚RXlí|C­°*l¬=Êÿp¸âÌ(ê`1ÐâÒêÕ€,AϼAh^Âhd .6NB¦3lêàåÈÎÓ`ƒÐ*pDγZ¸”ô)6*oåL(*däs¢i""§sV&Žú=ä   â§ ¶-0 J'·UbÏ€|±& /ôoj®Á`b!³ov†tRt¤@*n9ð0*˜Š€‘Ì¿ üMÚÂÅÈÒ‚ PÀW@Y€Rkr°Q&c€Õí,ψñÏéJ¥j!óFÝOˆ“ut"õC"ð#Q&e O…#`oöfÀ¤+Ý #ÐúMwHjBÚ/Ð)`’â—nØì| !"' Oˆ¾kÍN‚y¶\Ýfì ßÉ“3Ëp!ç2“³f® !‹‚¦Bx«”n‚Sü:&u$?@nC[Rîq5)Ëô]#€è\i ’÷‡H•®ˆ!Œ(Þv–&"?2Ã)ð–=L$:P0z¥[b¦Âö`Ê —“.¢¬Pì)§<;’íA &€: W0 éZ6ðà‚¦ê*õDB/³>ÿŠY3•—:/­ÌÞžG› ¢nF®¬z*sZÁjØÿJ¨Â)ä…CàIåÚv‚¦ï©…\föžH`F[ dô—ö¨&‰{X§hËð[ `Žh±+ÊnLГbÖöJHÄz/OØCÈÝx“ÔŒløå# #*d ò!Bæ2s'+²xº°(!—âŒJv_Jfo,!‘̈o0ü¢Q € Üì­hd=Y¯  +€þTz¾¬œ`xFRÌCÊgƒ­÷hŠ&Œ¥Eu„@( ¢bmfî!怢w·{#¢=%D!ñFVûnÊt®®œ‡iEj*(¸0' x!‰$ÛbBñð!.F„!=Â75¸~»Wg'ƒÐÜÝKË‹Ná„n‹]7Ë´\[j!“ô&˜öÒXSuW¶Ù ÚJ$¢Ý·+ÂG yH÷¥r„: ,&€0 ¢ Ì´5 ÙuGc¢§W;…/Y Ø×nC«ç[bi+Ô¥-—}8Ò}ÂÍL0 Ø»fç$ÀÂ"7r äSt—kŒ³…èÎ3ìUÙß>oÿ#`StO¤çÑê¤)@¸f@>nF—jëf3[ ÀEÃç1ÚDŸP«¥¦Ô!øÐ¶ ]6Œ”ØR&Ç›cƒP¾x5ƒJýY®±vPeo®^¦\9îf!ò]%£J!óÔÍj"‰/÷+ÖÌ èvãmâl…H]Bé®C­ÀTXR¢!ù‰à¾ƒÑ %¬æud  N€¥ÄgH]Di ñÎO”¬5¦«nª‡·¡y‚UÄ@Øà¢h Ú&Ä ãìY4Uä@Ÿ‡2ä{ ¨"¦­‡ÀnÍkxÄðk¨/VÄ– BŒN‹TGh#u‘-è%¯°¸FtΦ€Ž~‰ª‹GêËw[™ÉcuSZªêh ¥yêCr¿zÇtCê;M×ÔêÄÀáÎ"° j2½T-à z¤ô•‹"½AT¥»ÐT½d°àµ@¹EôP&-bËl!úÄp(N3%†”65ÑÅíÈ!”!7e‚œû?t‚ßz$ÅtnÃÐã%#Dñ„[øOÂú¦Ó¢º\CÉ嘀δ¤k+E…4‡EÈ]ÄÓ|d ÿM†+›.«aÖä&ˆáoeK‰Yà86®4N³e7km‘ #N{sJé©Ä×ñvC7Ɔ´GÎÌ8â™LJòƒbÀH>!ŽlDj!$äÊâÁ ¾tγ"]nFfq'‰RËÕwI%ðàÀâ¤7†_4‚#Bjçgjcl€¿|erìDF= ÞñÛJJMŽÎ«7ZûZ!ˆÐgL7u Z$ÁKO,M3”/½#q“*Æ;‰å_×YµõOÆ%*“hèØçõ:Ê®NXû Yž="YÀç͆@à^ª>Á–G'kT!š[w!©=ÀP!*5‚7‹tןS&Û¶ªˆnÅyñ܃€u¤&«]=¼Ââ–‚X» [$úÖôo"°Pb )îŸoW àCâòÓ.šn¹ÇÁ€Ë¥ÈUêj}µ–Bê`).‘„;f*PÙ˜âøÕ¥Šé€Ùfà‚mþ-þéÀÓ¤&Ëç<'Bº®zÒ#ft° ‹Õ‘nÒYœíÇ‹Ñî‡ú{Â…üO5VÑnàP.b‚KfμËx¢Y§¶ñ Wûß0æ€òà±±`ا V;ŒáÎ &›½]+”ØÓ\Á/£Óâi웉Ҍ¿Èƒ0BÀ§U•ÉcWJn¦‘Ì(#e6ñÏ{ p&ƒQ9çŸÚ‚f­×„,FNþL¹d¥74‹àô`а Lx¤X@IèÎ!žR…Ø)Þ÷º2C¾!ðÊ»âlÍ‘‡Iw"o?¡ç̼b„øŒÔ BñÍÏ+šýú‚l`ÔO©øc¥ÞŠW‚®·âÉwñŠs9C%â×mr…ßç¨e\ ø«€Ð0 ¦ƒ‚áH88ú僬aKh;® ÁáÐHø…!Dè8uƒ³cÒPbGƒáA;þ<‚O¡Ð§4)¿‚s)üvI>Å ŠÈ:¾‚H@HQî,’C ‹ˆRîï¦kD(3B™§m*×W¦©Ä˜ð¤¼)ûtšA%BluW’GáO¨9êÙ…_`ƒ¸P6wg§Sžpw´(c g®–«4‹ jBˆ0 -Ó? z‡ ³4¼d‚‚°C\óv¥Á0¦MÃm9…&<` Þà…9!O˜8a…ìü˜$ÂÏ…hà€8PÚ €­Oˆ¬)Ñ }„p¢”(gy!F‚i2/zÞ‚;Ž’œÉ ‹ô/Ø1¬ƒ¤µ40‘¸…ˆTº®¯‚~0PN÷ˆˆRþã?¨QF…#“8‚ˆPV÷½È!‡=é–gúë áº/ âb)JkŒÎRQ!O’HA àêîµJ #–‚(<€’CÔ¬$` Š’ S’HQZƒŽè:æ‘HˆTØ’%H Ô¶ˆ<¼“ó z%hP䃎’e!DòY9©$̺$jÌòƒ‰HTà’<@⃣Rr´‚Hé –…" jîÚ¼¨9J…(Ø> â² ]ׂE!T›¤&èPd…•Ü^–¨Q¼… hR(‚+Òl>§-H _€¶?åÙ¹Ü$†ÐÞ‚‚Œf¸ðúÔ§* Z‚YàTSЮp‚+è…Yh q›ÒÈ"†‚Q°ü!Ṙ̳ÿ ‚ãÞâêPûê‚.($氳ߗҀ Ú‚Z€ ’D;Êí ”‹Ò÷„¨SÕ³C(Ê!RL%5p.»Þ@¡Gr˜< `…O~2ž¨}fÌ«¼p`õ=Æ‚d¿j´R§:P ïbøƒö™mŒ‚:‰"Ä‚wi!„ÂIšà„ €+Ýi$¦‚D}²±ç€>‹¼’e@à®’¨ã`I €h8£0xHŒ|PIÏà´ÄŸœ|YfíÉø§ßã)NW±°‚>°N‹p”€@="ä¼nBR˜¢A¦B¥Ô«k€ ;4A ±3Â’A© ìt÷²Ï€ TBM"3ƒ4Ú{ÕÒ_!IŠk–©¤²Ü(N¤‘¥|Àß$t”6Âq@PJ(’`?À]F³éá&I1ù'<Ò°Öˆ"ü$‚À… j]æX ¤}MG™€ Vz”Hë(¹U ôL¦H5éU8 k¢AÐ $y¥$‚BÛ[üm+ ì’+B—€|, ²Ò€SXä*—À¥KR˜4¤HFHA‘$˜ò½ü­’È!±$%¡AåµnHH¨µŠ¦B¦ 3h…a¥¨N$0íD KÖÖ ‘T€ìIþCË.ŠfÑ"Ìf#-$Ä.€ÌAÑ w6bd+²}!T࿉ö‡Ú€9 õÑ»µR#—³-VÓL˜Ùj¹j¢±á„ jBŠ9$mõ9¨Í)À}s Ä'†’HÁ+…•„EêA»¤™ŒÝµàtÀ àU·§*A½’ñ›Ëù|ÕÈPGI»’—è ˆRë+×LT¾S’u³ ü{ëjšµ”št%mVJ°Ûèp„Ñ 5h‚2£  €XÕxÊÉ`K[>ñÔë(Ô‚I_¦Ù$WC»P:À J”‚|uCéÑ$¹¤ƒÊâ±Ù"Xà…\пe!IÀ …PÂI ýy²™Kl„@jÍ™’S¥"*H=´r ÁRHˆUÚ–Q‚ï ²YÈæ6Âé ^H#ezD*&’KûVd­´¹óbÂG ‘ Šz bIZÀ iµb©rio‰ „nË´Î]쪖¿JH8B¡é¨Àß-‹i}lqt²àR<è¸ÍµNŠ€>Z£¶¤i_LZÂjÈ#Ê$™×ÐüXÙ,„‘µîrîÞ ©d…©ù†Z¯¥Ç}É)za†“›}‹ ØÇ£„>¨+9$Û` "ƒDÒ ôÞMnAœ6ð‚1âIÂ.´¦Úô"S7ZŽ+Üw@…GPÈ‹;vʲ™k(þeSp|æ ‚WíÓ@€ ÏšõÛlÀ{çUzÚâL@]§¿>HÓßcJð5` 2LÒÕLj†â”ÏØ[jºIFQ³„’Å€ /ªÈ=“¹eÝñpGÿlÀ¦Ñ܃ŒBò6qjƒÇ7ÂAå7€$ YW‰Û ùàxa^bAÓ |Ï k‚"Þw}…½ýH*5†›ÈW†$™¢«Øxî*€|¾’D<ÿˆ=ÆÏƒòÏJàùq$Ëd½€·%¡µ0xƒÒ0í¶¢½Œ`=I³¢,$t4  ¢”/×+B!ÄL^ šþ4Ðà#øÃÑŸM4H]H%r*˜!’ò È§>hSˆ;욃o?Á°ˆ;´€ ™ À …8È>¸¼c÷©Ø³§™Ì "ì%3¬²>²rùˆQQA†‹QɈ#z!º>y°Ç` )ƒ€‚È%˜²1EˆRì Rn™ø…2S?@8™º q/Siûæƒû€®H…=È9¢/H˜é&ªä.‰Ù©¡ >ˆ‚0µ5”2 E'“, ;%*£u€+#«¤¸7Ú86iü'x³¬Ì œ¼H’!›¯8™2×#+­·IΉ!¦Iˆµ>ŒÂ|·c|‘¡¬P'‰ )q¿¸‚›ª¯"3º˜®SÁ¾ T6D(9À —"Ñ #;%F3}³ãÁ!ÀÜ»‹E2½šf£9ÀCi´ˆ#ºA(@Ë“$ˆ±ra±2:€¶­jkC@+ø÷”lÉøˆ€)“6k10€ ’jSß $(€ ¹DØ’LÜν ¬7ÚrÂÜœˆ9»KMlØ<‘!Dy±°¥´Ü Ä»„N¡ÇºN Ä>ú@͉Û1ÉÓDÓt¿»ºšë<•ŠàMøƒ³2¹ˆ;ÙÉÂܨy¼ÑÍl#ª¼‘!ã¹Èð’DÀ‚7\Œ£$31 ü¬°ƒª³R¨Štž€›=›È–“Böt²˜§”¬€!‚»ˆ"逩 1Ê”„ `…9Éè¬k`%ê„<`.SLªa›¶Ø?`ɲ°ƒ´RëOìùªúøHP’4k½7}QD5&ñy¾„Ò$ºÜ¹Úå%sÍQ€˜‚H1?Ø3£À»òò T]3þÈè‚B*a¿á÷¼Âr I‰¨0ôsŸ<“Ããþì€ ­¬£µ(…C¼½€ ¯Ó|‘ÞšJICàµF5+&I N)P T;´“ˆQPC*€„ÄŽ„^¬$‡—l ,L"uψ$òšeÖPDO 9ý„0´ø  U¤ø†`"Ÿ¸Ú`‚5“¦¦.±æ¿ãZ  â ‹R¿:b,+Þ+ <1ºpñá~.› …"Üê*Œ ±#©€ Î$T©p>jSJ#ÜË0§-`‰0ËŸ¤¸më 0ƒ´º…¾ˆ¯¨!d<€>ü6Ø2·€†‘€D‘ºÜÜ\ƒ¸²† € TE{ ´°ƒÖ;ÿPæRœ!{Ÿ!*•e… ¯m°µmþ¾Ç+]é +n:fß¶£`Sœ8€8€ 9í±À@L/6¸¨U Mb9;}ŠUÄ–ÆŒJÀ²|k¡§3æ“@3¶–ÕP…5doÃÜw.V9€»QBl€žþZË ":;íð&E $cÀÇ«ð B÷ %e:cQP.”0…8YšT¸‚³j`Ó¾ªÀ*· Ž’–O™Ó*³×BX»¸jì9PSË.Á ¨‡h f 2Çàßv€ÓóH¶›TA(ãp‚7xµ7NiqÂg¬ªÊ¦xµ2V6_Ý:5 æ!2#:ƒ18³“°<ð>ª¥“"1ãÈ…7MðÃ*ÂÜa^ìÉ qM‹€­Ây`«®mO¿ó﹃a€v¾ Ï["“ M T“`Z [ÒCã®’O.OÄ–N8nÛÃt•FàT>L·~º &·²bä\ƒÒ òhu,A§ÑþROrQ†”Äs¼²ä-Š ¶ø)>õ­…V‘¼n³f¨»ÓÎZ¯ê%±³ÇðæL£)g(ç$úòl„‹ºjÁEÚ†caà‚i€q»¥Å/çÔ·7ÞB+‰›¦<ÿr=‡µ€é˜¸A¥nÑ¥bŽ &8«ÚÛ-Ç€Aè½ÍÔ.K*¯!š†Ý•_\`“áñÅ‹=y¬<'½›®µˆU9ØÈ>í’ÒÈj.£€`¬öêÝ-øºø ìÁuŒ€ ò£*ì*ûrr°3~’Ž”ÅBò,G>u^C•kAÓ>¨,ê¦WPB9€ÕÚÀ‚,¸"[þ?µ¾Ž‘¦D S`Y Õ»ºvîL¹Ür±Ìûd ŸÝÂøÇ¨ãÿÅÀµX‡C¼qAE`aÛ½’bDsÁgÒqm±\9ÿ­õä«Þª?'^;Ë|s; ßCŸMÖ$z8u d$™t3ÓÝ­êvª'9Íâ­ññS›Ë!eä¹ËËJ'°ip’'ó€C^³œø|] sñÑC7èûm´ Äm57}77#ˆ’c‹Ì: D”»ü@€Xm Â@è3úÄ„±¡"ÈI )„€b7ü|ô„«`ÁhHvE!HŸ°fÔ&Ça2À >:¿@p6Y¸8ÀǤ%9Já1(fÄ‘¡$ùòq/³a*èHj:›Öi𙌠¥ 3BDP òå ®YЗ\$%6–ÎîÊ…6†Gî2, Òæ¸¡!4 çp»Àê×û&y¤«á*H3FËI“ì‡ ÅRt–„~“²ž Å1v/ƒG¯ÚM“² ž„àÅL¿ÙÒxP> E Ñrç0k')n`ÎXIÆ èÚB{`ì ½_9½~³¶ `¨`ÍøJ½å{ÝÈ2Lú Ë[˜ì½ëÚ’)¡"ú"„½jIÂÙ7À î Ðx» Þ–zX ÇJ’Hƒ'òpx Å’S¡&¼7¡  5¡ ªS Ѥlß¾„‰H¨ƒ&`  (I„Ÿˆ4Љ¨H´ƒí’p­ ÌšŠ `z ·¯¬Ñ€'ª ‹ eêrF d„B 6 eúZ ÐŒ„ž7ÏzP†¨1ž„¼” z‘HHzƒ*Ȭ„¾Ì´%< oj…©-´Î© o¢z„ÑêHp„µh754«©>„Ñ(¶† |¸§ r) aúÓÑ‹ëÞz¨˜- `Õ1…S<½!JH£ \ÈÍhIª„žèHlÚM¦€¨H@„Яƒv'@Ò„—ÈKÜ6Ûr€U˜!4ðX`• ¥‚„±À{Ý”ªÆ Á—9• e[¾„ˆ1ƒ ’ÒÇÊN8¤œo,‚„È4²¤ŠÈH99´¬ ü¤’È24æjNk–´©á¶ƒ¨1U8æÚZ“‘ b [!'j÷èhMü¤‹ˆH®ƒUºæn8hHfƒj­±5ÈN¤âR žyâ^ ÛUÙAÐH6æ‹h6~ØPìç_$ê |¡"r zÍ\T„¿’¤À Õ9Üèøƒ HMŒ¡%dFÈêÉKn„‰ˆ1w(a²y…€ì,¤àWd<žmãÒ k€"JõÈÌñbÌ wš’ª v©8u¢Ñ`n„õ¨]Ø!,Â9 ÎPb¡,Òjôö[euÉx€ì¤Ä' €£wo!5Šrüø J ¡ ñ*&¤à@ÛjíJ Þ’8@Õ:í' Äè”ÈQˆ09! 1m†*@ÅV”‚@Ä@À@HIt„¸¢’2¹ Pä BrE ™1 Ë¡M H‡‘Ô! Ų.´]\»x]$  €$S •Û’! @„¿F­×³¯*‘ rY¡ kào°Â¼ÄÇücn$ºŒr “ÈGž*œ³Þ“SpdÖ€ÀÜ “à‚Å%€V@Þäz!"(ƒ ’> ©A„ %g¹aE%K€ZHÚa¦uÅ&(3¦RdÛæŒçðƒ*’’Q†2Q!ÂÂ%È3ÀJÄèIÓùž5‰å–B4‘ lžM”ô{ÛÑÉ ÀÜ„ÊÂ’•2s\ ?hî@Ó©Ioä I€®“J˜)#0ÏatYÈú)!a\¬…,A…Ãö{G1 ©À™€¹!#Ù¦$4'ÑU!3ŒëAH3E hiÚ€"@â[MHz‡¦’3·z&”œ+Ä`Rd¸‘”P„†ÔË; T)#„ E{0P™* ml¤¦ 2¤Y|–M À‚Oq"Bm줷ÐÏS£ !"6§4&ó&êý™Ï䄹PöWa oøÀæ×iœ"=j@* ¨xm¡Ae€x˜_ T@…€&I©Šè¼‰úðH/‰]v˜d[}6%’‡—p«»T¤P€øj¸$&’º}Pf` É€*mB7À ׂsÀh¾2µî¿ÏyÊ ÜW ÁHks%|Ëž¨ 䯉‚i`l¶u‡R ø–!·BÙ_AÖÆ¶°ƒXºFFÞ‡ëˆ8jeLÞÌèN̈2NBgAÙÓ?­¬¢"£˜!#‰ÓTrpè&3 y,0©s™h@ã›°ö„ªØÊÈ‹'‚€íj‰'jE­œu šW Ø4äo÷ÝV )ê7KúÚBjœ‚cbs1 ÛÒìÙFI¬›÷Q›} æÉ)9.”œ»Ã ”_9œƒW\žœÜI ¤ IÔ ¢À˜²Ð¼ lr3Óâl+Î6u—¨ ¤'*€ŽóH0”Ã)ÏšórÎvÏ3=ð@2Àù ’ Åc6ž÷Œ-_Ö4 Ó.¾„&¡à¥&êSò ´¸¸ž%9­¯€¿D'VQüÎsÀ¤hä µLÌ BCq }Âѹw'Å—Ü7JîNvfàœxlu !'ýîj¹äÙø«Ù9Ë>ñó>lw Ìœ>jëN«5ðšCŸ2 áÍç2€Ï¥€ƒ`ÌxíK!Þ!4*¤K ìy æ!6÷7šT&Ã¥UÛ-H…5i*(H% Ü€4Q@HRqiô{ŽëBâ¶À ±Ú£CmŽR^Q;G³²`mUúªîg%Úû@Ê ±É&£b.°]ï–³)®D†ÜBt n­–­ v­^­f­2¾­=RS¶­¼Ò­+,Î9B;f7/6^43y3Ù/Òh¤zÛ©Fy2013:07:03 13:27:34 openimageio-1.3.12~dfsg0.orig/testsuite/texture-icwrite/ref/out1.tif0000644000175000017500000042717512271062644023706 0ustar mfvmfvII*¬+ö þæî2F=RS>¼Z2013:07:03 13:27:34 €Oawø?  Ì!å yÂð†Ü,MÂÀ€-ÿ€2<.Èäi\Š\v¤M³üä7‘@0i<êY‘Ë¡ vD „!a \  {ÂÚðéüú…@ªÑ'´J ¢s…Ñ€4úü‰ë BëV«e\\¬Ø` *Tˆ ¤NH\6õp½Vît¥÷s{\áW©çÆ‚.a+˜f £c€9>hð˵®n̼Ÿ9i£y¼(7¨^£[¯dû¨.ð‚Š€MØ(‚¤àq*‚í K§œý‚‚®àUÔ¤°P`R AAð@A×Ô@ ¬*ô‚»/)°,ŠìúÎmXPŅΙºÖ”¬8Ÿ(BÀ“°ì~ 9 çà}€'ÐyGRŸ³ž¨1Η§‘¬mÇÌuÇ‘ì}È …!È’,#ÉL•%É’lp/‡L°x¡¢E Ëò¼¡ êŒ#)b„/)*¯3%IB4$‰J{6­R tŠéº> ÇØ:‘Jʲ*b A,kÂÖˉÝ.­YÌ„ˆYô¸Ì좣H[$£¡tBzž¾@ #>-´½,ά@Rí€/JôþªóLú…ÊÀÞ‘:ušDÅ€Tšõ04W,ƒ¹À`½W ë..`;/aÌ»‚×3L €•ƒNͶ)öKP£Š |Ô·©9²ü1”‚Š뎀é8 1€;,_B ÁÀH<ì¯ÀYžòUÏ+ÏWêƒTù»`«`Ëø~€R\5¡üÀ\p5¥/Áä>\ån™æB­L*‡ä€§áð‡ÑÜÉ=Æiܩꚮ­«ëε­ë’păIÏOщäײ Ö’D!"XM‰lÓ-ÎVåP!v1ì9$A˜Ä»è2Å7ì´ºI´n|b{_rѵ‹‘N ÔØÕ€4BSϬ·D«0KN®tF6‚(]\òì×¹ñŒo¹›<¨Pec1‹s,UlöžK7XMªô¾3o¿][àZµvûp޲ï«\è5Í]Ø×[‰?Æß Š Uœ÷³ŠäßTØ º+¨~îqǃØ;¦Up ¤©°¿ÀaÊ4óä qF'l àÈ(ˆTVáöÀù©¥”`J|QÓDœN´* ÌXL/Âð>øúƒjáh¢!ö¶ûàn‘¶°üˆÉ5Øâ„QŠQN*EPhê%-’xºâbôalꬄò“S£qd-,ôh4$DM¿³ 㬄ˆâ ‚i93‘}ÑÆ) âT\<$KÁÈ·úH› "s‡M4ÉVë% ˜x.,(ø jQ.ÉÚ¼¥dOVX‚o¬‚ä^ l¡xKM€"üHz¿yOPΙÓZ›q›¦ З3¬fÍ3×[ËŠfp&ja›|O™ó>SPIÅâ· #:Zczü(8 ÌâšÐ¯ŸËG:8…–J çe_²‚É8 _à6\€áÔA@”=°`ù¥‡ÚA„Ä6 |Að2>Œâ{O €é‚8v ˜å("e#ÌXÚ1c‚OLbÇ´.;„²Aü©pÿDÃÈ}¢¡|>EèCømDÆ¥ªA¨U¢TT–Àk •-´TÈÆØÈYÍ À´…ÌvBã¢/RQ‚§Ç‚«œé"¡%Àˆ q.'qrD»2 ¨Or„Šƒª"ï‰ë­$@‰MI—¤Ë $R¦9àC)³$@À¹ªÊÿ(É깎€à×#OÕÒº”nÆy.Uì»—¶ŠÆ—;fÕsÔvÆ^—¥®²Þâà2ë‰A8ÌøM,×5X×x6AW‘‘À®¢BoŽQ½ZW˘rËð@V°F“`ïÐê°£À WÀ1ˆ–@î@P@AËVX¼TbpAñБÄìÃRÉ":`_ƒZ%PpAÁ C‚ 0 ,¼éß„*†Ðèh4Á¢4b`>‡{L"u¨DÚ‰ñF)ÅX­'—€Ì!¦CUê¡$“!  @ï·zex8„ˆñe|¥ñ®I«¹)3€@H0`±aà‘€.ždq ®µÌHð°u\V%ö”çl ™T6/K|¬UA d.P6§{–ˆ]èUÆÑ–æÑfIé«GmÝ»AŸt©.d\ÍÌß.×\Jù;ÀßÙ›Ò…Ô¯ÀöJ Ú·h“‰í22+ç7wޚР*‚¹71£¯Û§u@:ð»8ù€hÁã@ c)e€¶ÕÏ!Á«,N(#@°Nô ‘÷À0¿#ñ>±îgðý'dd‚‚T:É8“AÀE,㦩(­/ÀôéŽ3§qP«ÇB§a ü8>ØCí£Ž!ô8°b¿ÓüYÃø‡âU 6¤Âé†I½ ÍÍLò Tí!m©4EëÜH4„,p‰)“1·1©¤õD(BH0Oe…Ùq¾H«ù‹¡g2H€Û®«fÁô>Óì‡N4.bD4ˆ„¦ÏýnÌK÷^^VW2æÄçjuù›.«I[•˜\ô¢â0†™8 îp[ÚQÍB ;Uð8Ät%…ÖnÍmÅ7¬lƒ£ŠjéÅ/ÞE~­Uú²À:XÇ:ªMuNÌpF¬Ÿ •€c$u( ]@ŠEøJTL0Çš&ÇH€g0R}´@ pî(ÂA_¡î…AÙ!×äS’v<| ñHTåo´> "ºJâ™±æ°ú aуO¸Ÿñþ_Ïú$ÀÜó˜Ž@[ÈÒD˜hþMnN­©/¦înKë Vîd«¢ˆc`ÙÀYÂD±@ …"D b$A˜¤d%3ŽŠŽ‹âzsEãÌÐ Ï,GLÍðPêC:¯@¹`’ ,Kaâõޏ-ˆ,‚è–‡~–…‰Ã: Ñ¶NÌ–£LXE|zB3­B>@ÆC6/ L {ÍDíÇÆ[àì h ÕKv}ÇÈ7¨ÐÍ¥`ò€ WËð8¥"_©Ðׯ0óà\9Èä#ÀIâ@`Và’*’<åF¥|âò¾¢ > DÌ hà*/À0ãR2Ã8ˆå|¢Â „1bp  ~@n@Ò@~g€#D5 4B©Bdö†H¡ö öÄ!LAJ¢ˆ`j/ë±­ïæ4˜i<(dÖ(‰"œ0!gBåñÌtkÀVé¯Ä! c€_îDT„έªþKaü5 @˜$Aš‚D@NlΠq‰Dä,zuk­Ë !iÖ$LÀëBª,Eþ.¬Pl”°£ªè.p%à³NÖuîÚ“pŽíéjsP(GbÐJµIvW(0®0c.T`}M4–‹b6C.˜  H ¡¾Y`^b -+t7'Ì6íV7±7.*«>gFì æ$SîhBªµi#éÎâDnà!e„°NÂt0’/EãÀ Žç'Bþ.gbràw‡y'Ý à@rz.d°¶'ª™©2뜒ˆ5 Ž^`)|t\]E¸]G.€l7¥a+ ˜m@ ÕÅ–ÑÞò€òmtÊåúÖ`RØWÀrà àAÀ#È<VàL S`®a¾* ƒá†è>`$DÀ*¨†Áë _ 4· <øŒ ¡ìWÁ(!æ@d$àp1að@Tû`ÂH@(  T¨v£¦ì8шYÊŒ„hŽaøSw7õ=Sõ@HÀêqõM8ÓÒ!Ç##§9®N(‰RŽ`!s¬AÐ2*È@$Iæ$HÑÉ9Ξäªü!ul`>$AÒÀÀ²$Aú7SàÍ3£Z3úX)^5w®£Z³ø­Ë4“¨å@N/EBxÅ‹A/ {Àcpž³41 5ÞSgŽ–tGB5ðe–R|p´Ò2`ï ¥6*¤ðÑ`ný ö/Ãr ó£}G ~O>@ )‹™¥ñ,…ï¢``òØY`5`T`zH 8 H€m@Ô’!hh>ÆÐ„Drº(QÌB÷­ü4Õ2D“bWÁ$!Ú¤ ^1`j1`.WÁ>$ 8AÀ^5¡PŒæ ¦Š·d*„?&H@· ñ”ˆFŽ+Ä>aêB (æIM"vÁäB 2#t`_/†gÄL1a¾5 Wˆ$°ƒk„@žÂ!à1a¸e$ä>=,.@û¸°‡L¡öF!Ân‰(–FÑ©ŒÚ¨*ˆ`2ª˜ÛW‰r‚D=–˜$P ’dÖŽø  ’·T¸ó”³‹«Wèà>ãÂ!m3")«¸ûy:³“Bˆà(àèü@âW€RåB’‚Å­Z±B÷y4r+':õA÷“°W”XK V¢Ä¯@êqõßBm ´™fwŽ.eàuâzwŗǦ$áÞràHâ nPɗш5,r&—ð»”\¸çÅFåÔŽ@ ðr 8¦ÔÊŒپ{À( c¼m&Õ#œ‚|yÀ4KÂ@±@Èh²<ãZh*ÄDòDÓÐF $˜NV+·#o/z‚vEº8¥òD¤úĦ\ Ø~5grB¡TÁdBb Å|¤/†z@ÜB d*°(¨|dLøEA až–¡”þ…ļL‰Àú(Ì•BumœÇŒt! EÓ™i*röÿXøtš¯­wq¤¾P‘é™ãjâTü~Tºñ×’€ B\p Äùœ—yY3‘Bˆ—ðYr+[–œ””Ãz‚ô“£ÀCävG?BõA”0•ès™c—ņW›*/RxÑ·—YxÏ¥¾ 2ªÉ#|»J¶c`5ƒÀ(7ÎV ? À ˜à EK‘··£¶ûs€bŒàý>:`º cyÖ`érYàL Yt«rvÙô@ƒáFD᪃à! æ$bh?hÈ!ä3˜`  43†£”aô7AØ¡¢AÀNX€…|"Œàb dÜ #ã¦>#§‰ã¸CâB®B£sAþƒètDÖîiu7B¢ÜIÄþàdàtL`zéHÒnnN±üi¿uBEa.¯:·Ëbu÷]bsMfõº“º“Êü¯&Þ°7hD<¤s·]å´- ’;Az–êâX[(…x²g@É(xÔ´¢õwà•M{.Ä.{lMC<ý•¡³®ÜbÈ–C—½ ¶|Ãcg p5ÈЂɵ[~ ®` ››n7;s·{zUØJœ£¢’$B:(ä`'ô9ÙÃHÀ~€@C¸(À*cÂãÀ{Á±h:0Ѥ6Ë<= Dƒà$[È膀NQ:7@.dú#[¢Ct¡ô_/˜'a”WÀL$àT$à\AÀ.AÁ.wƒ¦ BBQpâ‚dh#£ì‡mgÚfH±mÄLaùàÊaÈbáxÇàŸ½ûäl eÚ¶¯¾Æ‘ÓÆµ¥¼cr¬€$^;©—ƒ#×Hè"R®¨ ãüÁ °@ ‚À øPý…?âñ˜L(‚¿‹pW  Á`ðøT¦ ÁRøÜªg ˜D#@Úî•̧|ÁïN`ó ÍKÁ^³y€~`'˜j@8þ˜1¦Ín®Y첚`ÍY¶Û!Ãñ¼²Ã­÷›Ää 9·)àFD (øpÎE„Á°à#„´²à(™b€0/: Î×´A¨ «njÜP@@dæÙ €‘Îçb·à€¡/õ¸ €Áw%Þþ+_ÀH$ø:ŸO >dy¾ÀgÈ$ y€€;0T ž@`[ |€‡Ø‘|²&!ö‚ŠxPÐ…‡Ê8 6§›@Ї‡ûœ\)â*žk§ `ç,2ç(.qþŸ ô:GáúíÇÛÎnŸ†Ø_…ë+:Çòƒ!Hr$‹#HòD“%Ird›'Iò„£)Gä!l²Ê¶ˆ(T„Éû*¤LrÂ4†KJLÄM ä…Ér#’ÔΚ&ÉœÅ;©tíÎpÓ5TÔ¡üs™!’¢òÑ@þEÀ{3:Çàè°} ¤€àT›“’vOIù@áD8 =<'©NìÓì,r¤!†»Ã*=QÀ ¦ô ëS©%€:’ éÔR}uÉý×'áÒB—ptD}:Á°° I–UàÍW¤hòƒÐ!ö7À¹‚âL£éCnmÕ»·–õ%ˆ€næ1v2¢b&‚R™0ÀUq*eÓ¯¸wRUƒRñ¤¤–â&² SÀì3,¡Î{ÑqˆT%Qá^õB¨P€èÝrtÔØA‚‚°ö¦Tœú˜·Ö¾+¦©ð& K€ {€Šóð^Xë©YB X–€ çÈ¥@Xßõ/!"ŒçýGš›û/”te–“¸× 5ŒÉ-0 Ì!¨°Ä“ãj-!šš Lë˰ £V—<3ðlŽÃeA™¹W€%Õ€“†qÁWÀ)Õ‘¨xp ;B„Ìs€p«ãøíùìÊ@Z( …!èBÀ™ÒW7èQæÀ=ÙȉqðBÅXø>L¸³FR Šx)1,|‚ 9p;p>0É\ç ’Jx1#dÃxÌ=A¦9ÒÂ2‰Šp§€y±âpü€hÑŸmÜ ¾Ù›7glô¦"€h;÷J\Þ™_ ¬Ò•òàR’ y.=é¿«kÝPîA‘ ¢@ƒ°By•z÷âêîmÑv@ñ D)ß©pG+ú{¢w¦€ {.¤ >̈Ìd«œ~0Q\%n°“S„ð ĘB 4© ¶¹ï®‹OÊ*¯&¯¸g˜‘Gä¸hQe5¬Ã½:Œ(ùl€Òâ˜s$d¥)‡•€”€\kÅÀ)Q2ÎÀì‘)¹¢€ó€a†jú 1¬%ž¨ú•€#}Ÿ’¶oŒH Þ,K  |pGr(cœé€Rv†Hì<`5¶€@ÇH€3¬1áК¨È0Y€¤…Ч5€vHÀ ›Üù [:øü°8*PSÁY‰ãäç cBêH B)ã&:¥.A†Ö|7b*s‡©†mN²SôÜãðëáù¨…û¨Ö$yn6‡ãüŸ—gˆÀe5Å•ëÁªÖ›⎠Àd¬#µ·¾öÜ{Ü–À…h…7.úô84@Dˆˆ€ ³€uP±@[‚¿à¬·@€‚‡’q€t 0¢wA‚°jWŠZz¦ÉW°¨…X­;; –;•(< ˜7˜2Ák•8l«X¿R‰±AýŒIùº¿©Ø°Š:s¡"ŽºH “¼Œ9NÂ`Ë â(§€)\ (Βଠ‚ ŒðÎŒ2Œêm™8 XÄ€<4€8§€DBHn‘n€T4€K³€R˜iS@éŠhrް£Âˆr°CÇB±‚ÖÐ—à ‡h­€¨ €ÍÐzðP‡°³à~ŠØÜ Øˆp`Šx`•àQ@ y¬ˆ ~Œ0WH! KYqˆ Hž3ÔçEŒi¾azÄÈsàq€ZØY¶SóG,sG9Ãp B™V¶Ò3ˆQÝœÓùž2“ÉG ‹€%Ü ÀHˆ ¨xʮ؞Ј @‚©Ø§»rÀ´žÄ7ä PާĈȂê›`…˜YE0)ŠÐh'ûëŒ/C‰‚aáW7ø­Aªæ $ Ä/tž‹˜ €Ô+ŠÑB¨Ân«Yd‹Ø·9Ñù Áp¹é½2²’ä%— Ú P¿Œ’È :B´0Œ: È Ì.(È©y¡? 釀3p¸Õ®Ø)‡hÕÁÓ· \@€J‚Éo™ÐÜ¥`Ãi‰@{ðbÃQAHtŽÐ€Á“h|ÌþØD«)6Ž ‡È«`ÑC§xz È„ày”ØO‡³EE‹Õèù‡(‡A\^©T€ÑЧP‡ ”³ çˆÐ†9@ÔjC9Ãï,¨üˆsJ@C]ÆÃ^“h~ø}†àø~…ôrGD÷O|øøGAû ª©ÌOÚ÷œÜþ?ŠˆRç€ ž¬úé¥CøÀ‚ªXʦ¡Q-ˆˆQ‡ÆÄ~ÈÉÕDû¦±5¨€Á$7D·X­‰?Ј~sx‚†Ð:(~M,•‰Ò€ \˜옊iï;xHA™òÒ®Iéc‹TT7˜/QôŸ‹\¤‹(ÄŸÒ„ŸÛ Á–¼¬ˆ 1ÒJË‹(" !†Â²,°•L¯€#ª+«"H `X¸‡%˜Ñ2²€;·€1Ò9BAx€:î²Øü¡ ü¨0ÐP±Ðß `˜é€uŽÐCˆéPv‘@Ðé` Lz+€TIÃ<@!“2(ó€’i«`€`ôˆù©ØpO‡È„êº+dÜð³L[Òx‡Ù¸”»È‚¸ç°‡¹3ã B=(‡BCÑ-3]>séŽÐ~¾³ã‡é»ø}‘Èrôo‘úMO|WËfˆ ¬‚SÀmGPþž ÿG´z «€†˜…CKBˆRå€ GI‰Ø/оñêý‹/H T¦*k”q¡Œ†¸È…à§ôûXê}XÁSÈ“€hÉ0rË ©WѺzÙéïTpA€ˆ"HR4 Ò" £B ÷…À˜¸Ð`ZŠå(¹¢ŸØj (ÞÒ¿¢K 8à ú0²˜Š‘º|Œ9T ˆ©ƒ)zË# 1_)NÃ8Ë&É~ \Â2‘¨0ˆ(HÙ°ÙR¸!˜ Ê€DUy˜uQ€ØðxÐwà€ç`‡ ëh«œ ÉÔL° S`ò÷ ~Ø €`³°|@R ­„Ð{™ ‡ðICJ‡ãK‰È @ £0I%ÀlˆˆpŒ0x•HVHˆs=ˆ!UŽp Cì(°ç>¨¥"êÒ”‰2D$h|â±;ñ…€}…tö×Õÿ_ùŘ Ó T.Hˆ `YdǪXX=‚`iG!0AÐÐT‚ÇõŽ“ñÙØÊt“Z Œ® 7肦”— D˜PâøaD} nR÷  xàéè0•˜0u˜‚‡@KŠÐx’gQÊ÷Ñà ”ÕÚ 0Éóˆ)xÉÎ"b†&(9]Òž„YvRx­ ÑñNÒÚ†bm¯²Â{‹a.%° ƒ Ѐ #‹)xÛHÂBÊ‘ á:/Œ²—1ñÚ€5º¨ÎÀ˜ÍŒèZ €2lÔΠ`9 ŒH;üÀ˜6 ü«Xá‡y¨ ŽE=ˆ²©Ð¯r.pŽËÄeÖù“<ȳD¨ç3 íˆ¢yn€ €pôà°wˆXT$PÈzà™ ¤H,ÊÃ'0‚)˜”™T¹Ã”€xÃã8‚_8‚FøÎ¾1‰€®™(Ã)y¾e±$iº8qàp]‡à\ßîh^†PJÀ"¶ªä‰a>è¥EÄÌÿÇ•„¥CÈU® –.MèÊi“6 “­á±6ƒ ‰”ŒaQXa]„¦©HIqä8”YtÑ9çQø…ASªHxñb@‘¶"ûôûâVžÒ› U¥€ìÂ%¤¨>«•Ðw` …ô¦âl"ŠÓ­Úˆ˜ËŽÙ\_ã=¯J@ÐÊ­( "` ü ùqË;Ë0Ö쵌:—[[ŒÈΡ¼ éw)`Ñ:زf€>?éàÐ`7ÜfË Øß7˜†çJ6fÌXC3Ø`låPx™0£)ݳÄ5ÓTÉüò"0ðx”La.y2(  x ˆV¨¾O ×X™Ð#|ŠØH@d L¥Á ŠxˆrÊ! ˆ (¤1¾ q H 2­–Ù£Ñ3’Ò‡ÛèÙ³¤kåmÏ#a¶(ièhèV†ðn†„° cˆ„”.‘“¨–Hf¾“©n€ y€ nؤ‰%äð¨ÊÌ"hÐ>·A͇ÃȨI Øßf›áM‘“D€9'‰bö)– IWŠæ•nµê˜ƒh’@€;êm0À˜@}¥žÅ¬ê­¥ î'¯#°Ð‡‹Š…­µ°Õ¥¨ð®º(–´Z`¡ˆXakÚð¼Jì¦: Â[$¤+Z‘ëámŒ$-º¥· 2l ~à ´û€(Œì-Û«!À[[+Œì5䂆Õ²&!–ýLxÖtG‡(烿h €è{ÐuÝä¼DТ[¢6ÌÍÑ Ø"Ðò&ÍÚŽ° Ñ’§\…_n~ý&˜…€Øà"»ÕÌܬò€éˆ%g É\‘^Ãã8ÃQTµ ‚‡éا‘®WH:щH{ÎÀ--c5ÑŽÓêõM‡X¸}…°%ó¿ eðw‡WÈK¦ûjè©Dø¦©à-”ˆD@€/ „pùV蟊ˆGÿ‘ºWÌ ÷Ùq>Ћwðÿñ Êè·$ Bhé¼—.Šjy—ˆ ŠÔòï8¼‰r¯rº}ÄÝwG%‚ˆ‚–†©r·šzV«ê±:j¥ §É] #(b¦²ZÀµ9éf«Xð¹@c‹*óó‘ý cR‰qʤ Œ%©—]Œ&¾ÊÃʼ-ÒàÈÈŒ‚ ‚Èa%? ‚çÎêœ êìxÎÁp¯p󀿸ü¯vK’Aa€Hyhð@kÐQ‡P ŽpÅÈö¢9Ýb±` ˆXÕÈ€¯€±uî܇þ߸ò ³ŽÐ ¾˜ôVZQH¨~¾¨ Pùà{ Á’nà§›hç`œ‡H”Œ_ }Pˆ N B ( x^)¢C]jÎñþ¿ßÀËêýAÁ Hàý@°wÛùö~?coWãÌä~8À wâÔ+–9ÀdÆe3šMfÓyÄæu;žOgÓúd™ à`I¤Jérú|®“O˜QÀÔ‘5$!GgRaRʆ_M—ت´ë56•GªZ‚t‘EL¤½é-ªKºÅR¨ZlÕKm²’ ¤¿©/ü=ÒËI|Ò@¸«X€Èe%ðYxÄKá’÷5‹'~Ée² +U?G/tåà´fH-¾é`zm’Îo3tÜæßÃá@Ål8ië•î7|à«;Á‚q2TÐ`)·}ÀÀo÷[³ÞÌîpJxžÞ€Á=á!ÞÎüÀ@wyçò}ðÈ«–ûŸ¯“z?à)À€®ê*¦€¡ÔÁJx n `1É €ð¹ñ Á€02€á„.Æ€9„\DÅA$TdÅG"(‡È¡”€ fŸ œŸ@ `X*Šfò6žç¨Ñø|5j®À~Ç­žÓ €‰ìÌà P Ÿ‡¸ ÎÉpÀ(|ðy5Њg  §ÐçôÔ© óþIDÆ: Ð`eìéTÿ› 蘧ŸHÈc·¢k?ëz† àPƒŸ{€(< }²ý_€™ù0Çá¸'這¥É‚…hÚV©jÚÖºhMâaþȬ«öµ,‹z^© ŠŽÿ©lPq)&ë £µ7 ÿv4ךÑp%á ¼¤œìjȬø£|`X2©uR  —ÝG“zßX#*Üâ©x¤½éyÚÛ´ÍÓWŠ7k>B½%ðË%uÃS$ Ix :øóE|T«œç]yžyœ©¤½Ü Ƴ‹žµNÖà?ùóâ¼m“¼»Ç nl»ÐfžË ï=ok׆€€ãé²¾ï­É®>G£å“˜ƒü•€è ꈩìùAÊÊ*Bp¾:Ššð»ú«` ®ñ„EsqÔDiÄFDD ÅAäD»Aˆ ’6ˆ¡:s¢„qµ!žAañ"RiÔ˜gv‚r ¤@a슠KQ-¢€p Öàß0€‰X"|øàU (zõ¥àB’g„îz”(0£ƒgrV´(<~Ñ!üÔjyZÿ”Q0X¦†/èhÞ›ÊiRþ‡Š”ÑhWÁ9o'xÿ‘²0WÈÉêĤ et¡Ñ"Šøqú˜Ç€üy#~ 8Çñ&&K=lB˜U ád-&„€'çøÁàÀ@‚€0€,!ýÂ#0hÜ25‹€-¸C’ˆÃ$P  ª9"•Ka©"c(‘ b1 ¬!³sM¦rš®‹2£L(òédvq¤€iódÆTªRètªà+áèCÖ‹X­Ò)ŠM°ï„9lØØ CR€A” ˆ4n½U¬ ?zÂa#¸œ3® ¯Û®¯–Æâ  9 çô6fl?`•ßy¶ÕÁ›fðÚ N×6‚¸Ü£s½ îv $ª¹ ñ›3rç‚^˜P‚ú ~ޝ°Ô‚ž]˜xŠ€ÀŸ> }xXPP;¢ }voÝž~€@r}€€R~1ž1å!±ôG™ï ð`æ€`UCp¸zžpèƒÀ<p@Àž }`$DñØg¬`0&y€àÜÀ0yGàÑõgì~Ÿà0’ÐBÁh)$ʱ삅Ï`Ÿ`ïGâ !B\ähÙ¾…S!ªA€ºB~L€JìP)é@;4|3€ú@‡éûgéèGáÎGÙ`ƒT€>„ÔµMUUÕ•m]WÖeYÖ•­m[ÕdèØ(à †ˆºiZ„K48¨ ì=º0öJ{g€¢o! ‚£ªª"¢˜„HˆH„Xêj¶Lé~‘X+U³kÛjÒ¢»‚HDî¨-W*¥w]WÅÖ·'€ ¨±k ‘L‹[¶¦7N»0în»® `X‘$2ô ‰IÒ¶aËkÌ¡,Èâk ¤¡Â̳ÙB®Ë¬ FÍf~S˜ˆëþµ,Ã@y³v£@x³j¼8â³`s6 ·šKˆÞ‚Ž‚ê9 É–Ü·n ÜèÓº7ø":*û°•¦ã¹; : ³Â|¼8¤=ZÈf>€»è>‰Àb>çÔðAŽ@„!™¤P pŸ¡ëÊ`úƒÐ`rÁaòzàm7£ üDdS`ù'ì›xRìÏo€#¡'IôÉÇär €’‰ë RRHB}!'s¼EÇÌÈ»Á„ÈnB…5¨(Ž…) m;ˆtd39£g’TŸpcâðŸð`Á‡¸€  RÈí!1ê?Q(á‰ì^Ávª•:¸‚PN AX-à Ÿ D‚·‚’ÑK5fÅ”FÖrô…•dÖH™ð|$Ô®’À8DH™"6l…h."£’Q5¤‰ð¯’ºÁÀ ! ¨µrD¼Ø„'\ {‘BÒÊâ¹G[ì­±Øx½¸K`Ô†²GK-YFvÅèØÃ@P/@B  Ñ•‹±é˜ VxxÅe}™ÈSNdfR…3%þ™©´3f$ƒ3ƒ2Ï ,’hÍÅY$hi :æøÐ³Žh‰Ä„r}®F²Åá¿718€órÚ%k©7 Ô肃¢Ù!xÇE2PxO9å$‡©³£pz‹0òxƒCé/&Ø>ãýg@šèLF„= *ذ! ê ~",Z…MK ˆ‚$A ,mˆ-&Ä n"&ªÛk3mõEIbD“`B"İËNÙÚ‰0V.«|Ù-ÐÜ0d¸MðßhÎ>bD;Æf)BºkŠÙ«„#¥Ê¸+¦àép'+ž@&€‡°å3 ©*égF8‘§Â ˜äˆÊåI.€“ÉI îVmdpO † 4 êæ ÒæéLf°’pÞˆn8‰B„8§Â„¾8‰žéƒ°˜.²Ô¶:1¤ÔÌ;œ<)<Àb< r>‰¢Æ|ðNã’ªí lÆ@n@,$Äþ\€VÆ@DBàîbHrAà@€ï§H€K@G<D& D¤X¬À'rEçRò3À"$.ôèŒÂ£DrÆp*ð€ïNIÄ(2§ro0öáà!#NKA¬ÂÂTäÈ/!@`;Á–'PO„È£¼¢BZ‚ ‡êŽL…¾ ¡Ð:ª¤BcèÓä,ʬÃ$¬(  €å6¡ø@aúOìÿr]%ív€ ‡ð‡ð8‹âx °-Ž…kÏbDìÍ»HxÛ¢c`Â#ëjY°kÍ:$L,O`¢X™à‹eîÝÒÁ’Â…‚îd‹F*.«)­äpA*ƒ·p†FA@_àá‚ê#°ºˆ°.kº‡`¸òàþ$Aì.4ã cp´ã¦8*îbšË¼g).*î_ ‰7³<3fÐGÂl쾆œ”C6•&^æî€Wã@èÎ~¾Crcrêæ†Â€éeŠŽ®C¢Ã6¥Š©CÀ #ÔC¢™à Cèê  ,B>ŽÈÄàplhØJNâ„aÚ@lA€ž¨–Œ|'$<AÌDB`Jaê @„´ >@ì¤áÜ oTF@I±¨KO Ï@Saªü€ä¢a¢  „'¡âÍŒ³@Dà4$’ê3À<BôGáLˆÆ  N$ V\ \8e. ¡,;À$NóœiAbM âTLâ bT„îJ¤eê¢A„Ú ¬ý:ê²Q NM¤I„ÕÄbúÓaŠŒR[&ÑM%f  Rk(åÇ) Á' Å`ÅhR·.$AÇ'0NéP0!^"#öµg)+4·Ì^0EOôä!ö5'Râ:À\í¼-2èÚí­Q-î,þ!‚¹»R&`‹äÔº.$Ku.•eU#2îˆü!¸Âôu|ÎÓUc6i ‹Ä00ÂL8FªÎbÀè‹Ú䫨eÈù ã{ PºCÖkÉž`@3fn8É»gÓVèÔ€M6¬$ç#róx:.ªŽP®Ìø¬::5Â;þ®ŒÒˆÃ¼°`Ñ2šEÊÓ\ÌÔšQà&AÔ „d„Ь¦‰`j À ‰Ü'HGBÀ4 Ä`$sâ¬À%@$~¡îòör ×A´áóAKX¢!î@°ŠæKA˜¤è¡ðK@*¬‘ÊÊäœK*L¤NlæöâVÁôu!À,(ÂT"‡ÃFb  (âTåB‚b;ÀrCˆùBþ'ô$$ <Â~¤mO¯lÔª¢@Š¢Õ¨Ð¡ÌÖ…Óír­ôÕt´Òà )5UPN`• ¯Â 2£&÷ouôãSÂà)ÂE)’`³‘+D.õUv÷X$í”!ðÚ ß¶yUgN€‡r{-(|Kp âc×yX•h*+êUK/÷Å}.2 )Òe‹cà>/A´/ Ó ~4, Á S#õPã e{òë€ øiKÛ/xpÔÂŽd-“H3n|åìVpöbp‰´4|¿ØÀÈãr6u焉^LÁ‰V‰h`q ¥º; êü£¢ÄV£´=FèȆì^Åþà:öBøŽÔá(d¡¤ AðG*V À³ÌS¨–J@ eaÅà. ÀvfbŸÄ:'RÖEcTuD+AàFAôNŠG/@4!¶d&¡èpÀ w (£Ü¡ò£à  @.RÔJJ`w4LGà<1;‘ ê”NèðA€T!@\“Á†_áP%Dú  ‚NòL ¡|#`ªNã^ ªPA„v ¯¸6‡ì;ÁðQ€'N@Ыˆýg´ M\SaÄ¡ÀzÔÏtÙ¤ÿP ½uu!wu%’ívŠûy‚DèÊÎ!#w7[y7ay+D.*3\-÷ÃwW­D!«dÞ+Ü´éYç|(¾Ý.Dºâ:×ÁŸ÷Ó¢ÒÜäT!ƒŸÚ%z¡Œ™à}a.3¡‹¼À€$A°¢ô’U¥ó/Yc†LWx <E‚”†:eúd7£“Ã6¼l4 â‰ZiG\ ÅõÓ„8H•U߃zˆ“ÉNüƒ£P£ˆ| gÊ ^ƒ¢êæN;0âq0mãà ˆ` ]©¤îÒý`t+~î.ŒÜB`®ôìd˜¬ª@{„(–Vg*@$!,ÀÄCŽD ¸Š ¡n$$öA€®|!’l‚;ƒ&ªB^ó›ÒPª©#rê€ERD&JdHE6Aú Aøà. «¿;ùä%f@ø %z†f§Â2Ï)B`?"EÁ’ÁÒÈ$97ÂùÍ `ê`¢"h^h<2Í,\CÄO.Ôí.Ú¶.ÍÅ>yêbôØî¾ŽÙòÂÀˆ|CÆrèXã®à+„¸©=>sK6€ ñ.â7Õ}ª“ÂìI9õ a̵•¤ë½žàŦeʘZPÚ*îQ¨mò5Fi\Å‚CR;À`|Í„)V`Š3eΉš½ÃˆlX1]æ†7¥¬"©eƒr1 ÔC¢ú³ƒ£™£±)t=S,¾`QÃÈ3¥íS›bŠšRšA´@ žaѯ<}$}Bd'Šäb G<Û¦‰ió; êÌGäžü46hŸAó Ó`6zÄ~ʪ nrFAþD¶w!Ëv ÿÐr„&aæ P ¿‚ »À ¿€ |€Çp,ú—è Ü0ü'Ë/©`±÷,\€åа œpý–ŸÒdzòX­š€’°B^dP@yðºþ“Ó%Ê€6všËµ` ý¯äï°™öýµVŸ@›õès?`Ëño(¿à¥ÿ …ÃañœV/ÇgÓüMŠK)`}›¨9°vc-¥ÒfôÒŠ†WQ­”e³X&ŽaË›¥eðT­~ç78Á s¬Ø m®ÜJó{ '6ãâï:}¿OžæÅ¼mHe‚næÞ^§GǸód Ø?«–¥žù¶VmÕÏy|` ÆzYÄí?­KüÁ) æ¡2 j%†Ó®>ï³ÞÛÀD!ª`ò×BÀêÁçI¢„ ½á“ú÷À‘ZX’@ëF`+ûÅÐ!ß<0yÑA+ 8‘š‰¶±š•É1p  ©`ôFp4fhJ'Œ\Ê2 "rìt’4œ–±¬ÆÊ0p †ÌÎbLêdÆ Lç"XÓ8%3ˆ“Ð/=I)ƒ=É`$à0pˆç:ÌË1Ð~,Äp¸•à¢AÀ9ö“&â GÀ…µH®UFÚXëP žàv`! `$”gº àžz ÀhûÀBQZU yóT LàhZH $zW¢@ŸHà,yèP û¿kP2y¤Ùíj‚@5ªHéu€ô“„²0PßJ9Ú¦’’0*î‡j˜Z¥°ª¦%ªò¡;¤ë3ø" Î Ž©¨ÅF¤ç˜Q€‹6 ˆ+Hì~תèÇᶇé†Â°,£húF’Ç•£èÈÒ@lÄ|Á¬Ü¬ÜÖ5ïûU®¹†Ã°k{!ÎÌ6l²ò3½n~Æò½ÍsvœÌÙŽÍíMÆúñîÏÛk»#¶ËG€ °ñqn€3{{?l;ô7 ³xsæAóæÖÁ¯ì°ÀIÜ7ôéaÀA4#ËE]vÍž½‡eŨwÐyØEÁà(W„‡m>éG%r`‰ Iw'j¶ «ÐÇñ·±ª`ó&{ò\ƒ Qp)I\uË<£7ËñàøÌjlÍ1¥À ýÒŒx‹¤Î˜’ògiœ¥QØžšg4 Ǧvõ’¼N "`‹PÊÈhdSò0&€$ñx¤`L‘I¾)I! 9P@8A `– ¦.ʘQ)£ä­œ‘ÚFE@ •¬£ þ¤ ÁöË1$è<“‚Ü`‡ñjƒöŽáûÆXüpáÂÐÍËJš“Vk\C1,s 9˜'¼€ÌŒf`°^fK¥lNÓ¹CRØç‰–†më hfIÃ8Íýº9Fæf ¹S*ÄÁ3‘œ©‚Kd¡ÀÎÇ á'tÂslp¸À:܈“ö;fÈåÜiß0CI¬™·ÌíÚë¤@”M  KÀ%‹Üþ¸ô]‰æBGÙ*¡Êzèê ±1ƒÀ"áyOè G@íž‚7{à ê ÓûLQœDȹ/¤gºûjªJ} U›Ò÷—I±(—àQÀ#j…AûJ¢cü)¼d&yîú_Êw0-üŽ˜™Á²z°€úÀá~žŸ\Ê0)!ô£Æ9qĈÐjJx2-ƒˆ¸€q¾®!j¦çÜâÌIŠªjðŽ›b QtªйE˜R0â¬T> 4ŽÅšƒ€pý\ 8yÐ]@W‚l|‘T@œkÄ` ] (¹ã ý#T.<@9‰„T’6ã€ÆdG/pÙ÷i•Nw^,%64’Àj‘ÑGÅ@QòN0;Aäî‚r”f“ÑPŒ€£–bNOë.de µË¤LY‡ÌÁÃú9€º‚à¯òÔa$×șƊðh ¥$nÍXÛÎLœfÒ˜aÖÑIÚ×èœò£à¾A0^Üïo³üãælÌn³A›(à„I• Ø 8Æ~‰ÑàȳÀ€ÍµƒÛi kh[2ž×j\èϦØÒÇM¤sÍ*¶ŠJ¸y§!ï«TeØèg:’6†¨hµãùêƒÇØAàPBjÐÕ¥ã¸Aõ ÷ÕGž…TB3H÷ÑÔg™Pc‹_V'Ã@{V ñ#:.˜ÜÍmLh8€„£SS®é¤X` VˆšQoæ¬&3ºR ±oåÁ¿—hþSjm Ð8e¦w6¿SÐC"A¼¤†AjÕÄàtY…$àiA´§€Ì)$œR(@¤20èz%z 8Í­W#´³ *=•Èñ,°Hc#Y¨uf€aÖ³GÜZÃ癀ðH„¦{• A€xö! H‘€&<ÕI,ÉÝjaâPþ! e2_‚G&G½ó½j°âHLÀ$7δ˜IÈ‘¤µ!R`•zR…QP((ÈT±¾•d°l /, œ¾+É•ËüXYÅÅXˆ0bÔ>‡ê©ó!ûßEðü“I¢äoQ‘…€ FS(Î6«@½‰(Ó~Í\™½Ú@ÎdžtKÞ±¦fðH“”ÁÃ:IEQÐçA»f·<ÜŽ3ó#0Íè)ÖvÍYMËšOèã¦ë{Œ6ȃ(ˆ '@ͪÓö¾{D>ˆË6І{Ù›ì%=Ðê¾Û-=ò_ èÍ“¿r)ÐÁ2»õxè¾€BhÈèû'!Ä5EA®¶c>Cã43\?óC ðóëEÀ4À8þ¶Ð,Cÿá!èq€`Gx À  ¶| ›c{ë” ¸|‘œ±6¤½ì‰e|‘sx€Å¡Li1‘ ðµØ+‘¶€ ìÁê¾"{€*¬4ŒhŸÌ#Èß(k“<Å€,‰*L3F™Y=ùI›~¡Z3‡P“„c€G‰T‡ès‹P†Š€K†¸”û•@xðx‰ Q€ˆ¸€H¹|;ºä€Ò äA‡Ë–€XÄp01p€(¸ÄbèqO¢3‡ vˆ0Oˆ˜(`ò5¨â5‡ Ž¡4€ {EX{ˆh €4Y‡Ê-°”²LšDV ù€øˆh €·ŠH‰€ßP£…‘"˜£¸£¤x–[‰`'%8g@tŠP¼¨à¨¹BS H¨;%ˮиˆ€Ç¢`¼èºÆ† ~í‡ú)²iÈ. Yp6½q¸¿ô†S$¾u3šØXÍÈ£,Œ‚pÌJ#â²xÌH{ÛS²†Áº¨  ›‹8µL†Éj‘ :€ æ3k;³»âµÝA½…HëæKëö%?.|›Àcã4ÕB3ñœA PM‘4‹Dª¤©Ì«{L‡Ä­4KZK›CA(UYK, 胱H@zŒ‘›\KŠ’´„ª÷!ím Á6”a6A (jr°¬©À*á0‰*£(‘Kj‰BÁ Ø€ \’ˆØÂ!1ʼnÑ)*€)͹a3©ÀœHДb ŸÊJ‹k Úe€rIà>¸H˜Î0i•À†»‹”8¸°w!HsÎx¹•P‰Ø€¹V‡If-è–P /˜&\¢´ô9ÈàŠ`¬G‰ŠÔÝ4Ócÿ›èk]¶^õMiyÛËx„XË•ôê ÕHͪâE´L® ÉÕ”jd¯KàLjˆ‚Ѐb­Ùã^x`"±àä¸àý\Wk´ ²¸ªÓg«I@YœÉûa`´ŠÂ:y.a11¬˜6Ð>PAä!ˆ^A²·“>%€!5ŸÉ.×Íß×áüÉàRMlë p€€IIIFb©ÎŒ] ˆp 8Íâ 0X´æ  -sðv0¡¸¾9!é1IKêëP !¸‡j€P†¢N@ÑfZa^d2ç¼F 3 ‹¨}‡àˆĨQZ-\ØŠdÝ©2 ñˆLS tº:¹QwPpМRuÅ8‹úAØ[sâ"L)"A L¹"#¨î ©… ¦‡¥Iñ#ð 8'Š;à‰aÐ c–Ÿ;†Š˜’&b ;•8m%1p~äÁ‘¦~ç`&(º¦Bèp~†`þ{çÀÆ…°?ƒ‘§Ž<Å€ažŠT}âr\…èÌ h©Å5 »F€‡€LT}ãT3^™=ÁAÐ’@é 3ݧ/i†iŠ‚*Ð^½L Wh­ö_5Ž< a‚rßjû®Ëãp€’wĨ|€Zù€‚L—”#X 6D­"Ð ‡ “€¨}•LXˆj=µdH0F‹ˆ,ˆŠ) †¶f^@ó¨$ÀkHJè è@’$‰`TŠš‰a¬ 8YŠØ©€ñ" ©× –#ø“¡“¬u€6™z[øˆ kËäà{‡ò‡8~1Ð_ëÒÕqTÒÓÓò¿¸?ƒš>pÛ³l»€fŒÚ‚HMáË?ŒÙâóIÈÁ«hxâ.”è·6h—6È\‰ Ã'#†ÓÛi'Öó2ì˜(I½ŒÛôh/BiÇ=sJA±j†˜ÕÇ.UAºLiÄÛtR=›RTÕþ]Ö¢ê\®T†µ<æ`_ïª5`è9˜qƒq‡â¦VL¹€†À´ëGZþ¿ `(…áè#Ú׆?â°0$Z ‚# 1"‚5cxÄ,Æñ‡Ìaï)JÆqD <£ yÓÂu'ByÓíü0Ÿ +¡ùL>éŽÊ˜|Z‰)gñÃèà¾v,Ýš…tð@¶¬w=†Ä ]ŰKåïwv<À—”Ô áÔðP*Ì w»Àè,ß50X# :@ÐsHŸ¹Çûö–¦~<@ À$ö„Àˆ~U‚O·°$úÖÀA@Uå¬ €lA`,/Á^Àð`ÂOv@ר}p„/Üh‰õÉq 6ï !!¡öƒ*PNˆb$#GQú˜ià+šHÑÚ)`*¶@ú„¶H楾 X)`Ì¥*Çáú©Ÿë|Ǩq§_…âk €8ÈR<‘$ÉRX\㪠ÈÑ\¤•HÒ‰æ€& ´nÊ2²„Rˆ-#ˆ¢M* šÍS|Ó-? ¥-²ŒÃ0Ìĵ=ȳ](„ÒÔÕ+MPœŠiÊ'Dµ=Q´|‹?4u#(Àò*="‚’ÒcJȧLµÈ©$¯? ô¥'HTµLŠKS=R¤Rѽ-QZ¾ÕUÊTY¿…EYÈ´*8H©|Y3¨<üsí™hE‰U…YZ’±êƒ—VŒYMÈ 5¸„\6¥³(VÇtÝ`††ôXhQaÊ)!R5uu€a"ŽuÊA€ ðj#LjŽTÈq£"x‹¡Hz1p ‰ ûHÄ뉥iP£Â1/%uªW‘%aòt#€ j'Y’W6€ út §VZ r)à1‚§«Yø«À¢¬ž YÈÄxb±qò³™ú¨ »,áŠj„ª˜n,Ë\qw± @LšZ¦œÎH®ÀH(Î@’úÝ*ÀRêˬ° éðÌJ˜± ` €0ÓŸ TX×€9ø³ìpyÏ vƸ‘À$~©à™ÿƇ˜$€# k3¶¾ƒ\€pHŒh™€ñðÎÛÝ­–FÒ¥“O˜]$~S¡²\¥F Ú"M¡bTWÒàò4 <ƤÚͧnͧ¡üÀMñB 4O‹©ãÜ~´‘üTÇ«œÄ~™a°?F°Côh¤„ˆ‘’dI‚ä?‡t¢Š RBUpu+%e@ME²ZIh§†¡!RkMd.&ÈZš“ #Éhx«´ø¬S8¸Iþ8XŒ-"Á¢! è²üà& +eV;EŠ^]˸íøä2I1ÀM@¢€0†H ˜É $Ä®\1ãÔF!I+ºä­Œd蔊ˆÅÕš¤éŽ€Fhü‰ÔŽ«´¨2  ;ŠÈÀ+%H¦„6çP*ÂÈ– ýMÀã#€i–¡´ÑÉàÀ©šÃƹpúD`Ë€ß8@$ü€GF@}%(ÌÃŽçå €2`ƱîRÌÓ”q:Ð`6P-£ö¢ ¡øp©éKCî˜òp€€Æà@{šÃŽRÀù.Ó¼á@t¨ñp`X  X‡‘Ó$yÕ8p€äÕ¬ †2è„$~G@# òMªƒ%. Ôèž#IÜ„BTg®TM8¹̈*M£¥6€‘øRÇ™ ïÔš’”ZŸç™´\,ñS´%™œ‘Ê?GÕ‚á&A;^Eܶ—i#t"SÍß!‰hn%øšÅ€6KJ0ÜX± áR¹«Üô£¾€ ÊE7výݵWq0­ü¸ÌÐŽ»zÓ8H¯RöÜn³Ü¢ê¤‰É-!5"œƒñw²á‹ô–‰F…Ë û_G‚ûž Ž·lwî‹$áE“2AáKú°a.?ı³­L¤‡rêø˜ƒ’@°–"–kQ\·b‡z ƒì2r—#c¼_Ï„"Ì…+ˆc íß± ØÞ5•™Q‰–¥šÈ(ŒnW7rpÌ#üeÐ ñ¦ÁA&¹¨²tMæãB­b•”bSyY)”ñ8J˜ã@gá¸HÀA‚˜¦ªàXÑËX,á² `lT¡` ÓA¾lâÔGìG,nCÔ@nÀ,*`BÌa𵀃8`8L *Àã’qƒLútaX€"¦¤=ƒÔô=@F$ƒä®$Úæ¤ÚådT¨!!P#@rRàŒRá|%AÆM œTAŠ`„Æ kX¢~¢6B–€¢R-PüäéÕÊv)áüþb”*k&9!æ£l!úÉqkZ¶Ä–€þDÒ¶¤‚O¤P¢jå8O¤„»®Êg€Î½N¦MËß.舎¬‹«vé$ŠîÚR ¼ì/…¯Œ¤´\ ä´T‰N½kÇQ‘ÎçÉ$ KB¸Ì*ÁѰ»Œ,† àB „ÔÂnÌÁOˆ‘âH¯',J,@@jKO´ô¾L4õ5!ï2I¨RX/B\$ õo[!ïxÄîÔ äå’)\ E¦_@BQ„ù `æx`T!‰f`B—L²lrǬªöâ0Q‚Ëbl!€h#ò’%q¢’‚e"t·àîâVLØ%`*'L¾²°* .*„Caºh@hÀz*À "–Ãð‚¬¡ük ,@ 2˜8F¶.`Flaºla·§v,àP*À«îì^0àBHÀž!Ö0Ë06ÆèÕ`Aö¤Aò10\¦0b¥AþHÐlq2è Í!øqÆè€ƒ âÄìv "Ðúaü0À&$Œðq€*°€Áè1 .£ 30w‡d"¡ì1 =8cÖƒ8H(eÊÌ@ǨÅDÆ,&å.¨"b*Áb`€tTª%@\Mª `Rã’)fDKâ–FÂxb–çòcÌ)b¦º.\´NL£’~ X!úàÁü-„ŽçD‚€àsI E"Eaè)àÅiË]nÿ péDŠ‘ÀËà×ÑÎê‘› ²&¡´‰¤ÂíÀéÂjÊKËN¥Qæ…ëÉ J¢rH¬sH˜î4·KÈ´´¸ nÄÂñ·èÎ#A˜\àŠbl`KOï MTªÁôö å¼1¦E’ JѾE†M"Qá#’K@:ÄI(Q‡*ôÌ&õi#Oa&¯LÄ‚ßE„; ’ € ï„|‚B ãð÷‰db@aOØÇ¯$ gH€?‚ N‚W&CìÍ/ (‰f— –# A( ü„¸%r¦C‚0Ç/Эô¦âu!V)ÄhAÀ+2À*êC`>hÀ~,@ b¦á¾HÀþ¢–£Š)€ŸÀ. =@Æð.À"ÄJ8@Âà+î#,¡`<5< `&öML£’³(JJ2áúj°\C #’r*§ÓJ0TáøÆá¾£Y6Bã,ÏÂútloGŒaî0Ю=@(3”'Ü *Áã98(aòp`<¢ûj…*Ø aìTA#AêBXT@`#@dz^$ˆ#BŒ `€`^%H )`ŒM¡„TRF e@£âTj¢–€b[ #GiBgòE6õBHAü*ÁõbÔ09!Сʜ[$pHAz ý4€[B…¼€è!ôè3ùËmIîʹˆÄ&®¡IDÌê®æêEoMå?G4l‰åHdµIkæê+÷ñ˜DdH´ˆ(´MUH«ïK‘Ñy‘ÊEm´óž3÷MìtM §Xlð·lZ†T 2ñôêJÏšUgFÒ‰™€êñ"5"LŽÄ7Ú‘‚¶WÐZ…‘#lt‘^Å‚À ›oƒ%Áør€¯r@öÀc|“/‡‚âlÄUâe!Ò|kÔ_bV` ™€†>#Š!…`‰º›¦i…B0M¢2#r%e¢ó… Â0$66" þ" B²flgéØ!c¬¦!¬HÀ^` *"˜³"˜ªãbÎpàRl?_aÆlÏ_8¤ |ƒ?[&ª ±N£áäpc6)`ö8µC:H0lr œl *adªJÐÈ´£¡6G=â¦ü¤  rÀ" 29Y9WvV6vG˜ª¶‡D/ôßÀñC8`qÚ3€<§cÖSÀ*À‚4bTgŒB8ÇŒ&,C"dâ=âDÚ8ʤÚâ¯Sú$“Ú aÂM¹H)cç@kn@âÜ6®œ`Д´ Æ6"¬7 qC~‚ìænjGÄ€ÀCs@îBΈ(ŽH!ü/¢èJÎP®BìŽB«½¢ä¬YþJ7•K`*`~dŠ\«µMLV4µPK §|•x$‹L$ŠDµxÚNTš=Gn±·šH¡²ð‹úì¤ÏwqÅ{1ç}US µ!ȃ}—ÖJÙŽU®üò€ó:¡ Œ“¥¼K"Øôåd‘À—ïNŒ%Qã² ìU!ìPõ¼ \éh’µPÇìn$ úå Â`¬^øx"†=U©fß@"Ȫ!—u2‰†d gV OŸ†b0›`0šør ©¼#5‡ìËYÂt à â²Òϔ e‚˜=à™¶îBÄÁΠ@- fRX,ó )‚áâ a²Ò6B,àS^ &láÀ j€.àDn&1 ˆ'ˆƒp:d2Aî8@3C;=ã.ðpL4-l0fH!j¨9.2Á¬Ç6P€ð¢7áü0m•À¸9A言$ã8Óƒ’aì)`*9ƒ¢ÀÚÄaäj¡Šc @5€6g"Ðàx÷DÞœPE.â8åg‡òFzbTLªê%AU¹DÂHç©w$ì:¤êÍ?²€¨!¹8ò»`DµbǦ|ZÕe´.öy…î|»TaØ)Eú±zÃá®ÔØ-‹–€vMÙó³^ÀBlÆAˆÌ³ùªödv¶`M ÷Fæ»;.Õ=U÷ij„€öà{°,à^Ÿ¤ÍSÁµÞ»ñnÿ]ÎßçÀl­û[¡µë€Ãñ”Xéß¶·ï>ðã~0ïL'_yÞ{÷¶€@ŸzdâÀ]×â*ü¯ØVˆ jF  r!( G؆‘ü Äœ„&´À ¢0JµÌœDnB@0 z9ï F@$b À8N|F'É眀à!@ }HÇ)à 4˜r(|¡ Ië& YØ@œ°€ lÀz¡ X{€Xu`,€gôäOhžÀ~ Àyø €0DŸˆ@ ~à"~€ $Ô±Ö€˜„`` Ÿh,z TS„™ú‹gš Ô¨8Q`éþ†ƒçêÔ€ ¶„…^ìTÚv8^ßBgÚ,KZR5ª&ú`T&¹ú„Ê^²à^Ú €ÚFBŒ¶€=>[èµ}whAò!‘Ÿ§ê ` :†¡) , ÈŠ^…¡'Þº¡Æe…9£ê ÿw")U‡,©ëúˆ‰8Ix$æjNê$‹Â—*¬:ò¿ \“µ r¨, Ê­˜/‹ÂЇ3ˆsh¬ˆsã é™že™\@–AB,–h±Ór¯,V™¯k¶€«!Ïjõ0º{:¾¨-(&$ö†¼Í(&ºìi¶lˆNгûNøÐíÊ[AÁ€@¢íb/MûOÝ4-º`îLTѺ@8£sT|ŽKÐlrîÏßÀ-Qvìò|›xÕ®ðßð@¾ïБ$X/1ú¾Qˆ!ù~„ QM„(³0’øÃ‹QX@z! 1HøÖ—„¸³›FÏŽYn8­2ÖŒÏ]È2¤8l²Õ/fû>\@íãÅI8Ü$î Ÿ´ÙÃ;ɹ¬!À|ŒŸö»<'s@%œó:ê@ãŸM± 6@]Ôס@ âLC"bLLå ýµÑWPV¨eÙÇâMi‘tî¹8"‡HKÓQ” »6`l Ó’7ôʘ—c¥4MѦÆý¨€´À0/@p, ¥]ñ×EˆÕ ó~¹V¬;†üÔ€EÄ¿ûK“D½<ªIø Gàaó,Žñõ?œüåÄOøÇy‰!0(Çâ"KE‚äPPI‚¬oú3HC["À Ðb›0~#T„€a¼Z€8}jÑ€BÀ‚(Ë4h8Ó`èþ£`<í é"$¦€‡ŠP„4…„€¡@4¡î—á2‹@9Bä$œ‘úuÀ`€«”àÆ–‘ ~¦È€ÀpûU <~Æ@ >Ô¨Èü˜š>S0à Žõ*Ǻ££š(€<€ýa å|n©ˆTÇÒÂ#ùa.’,"–¨ûä b, ý~"Ãq ÃŒ>0IÈ‹ ‡ Ö8-žBò¦9F9Í¢ë"ÈÀ°ä’¸‡ÒßН’1† !BL4—°älH˜y˜ïÌ‚;Wpµ$ñ—›‰FO¦p!SL¹f=5³>g%lö˜· ZíiÄfqÍP™AESh“¶†>ö€WD8®âlC†¡'T ´Ï‡5Bc»ÖyÚ]«›J ³à¿ÁIæiT?Ràh]™9™¢•¹Ž"ì=I= Ž Ò34Ôi¡š×%õË l\‰˜rÚwH.Ȭ jÌ  ÍP9%è í|Zª‰ªgeë½¶@¢5ZœüUz®tœpÒæ¨éÊë9ï?ÃaÖƒð ÞUn;΋ó¼6P:ÿB`l„L`„Ç;ßÈA·²$?‰€©`J wܢОÐD@¥÷ 4ÑhëXH˜„€pLû®"1¨ðÒÝH}I[S`ÑH%ô R· $y&€>”X ¤?”À=’M· ,'pH0 ©Œ%ñŠS`ŸPàaؤ ÈH©>  Ôbw‰•"–>ŠXt€ð5¯ˆüR#Gºr ;Žò£TnƒqÄ~$P=@ ŠHŒˆÓh3 €(i`©×‚ÙÓ‚Ë”u™ðw$±6ŽÜ‹%Ž6È8|¸!®±éYƒÄgÜcPø)0‚A‘aÿ“ÀK÷%ZfôÊ»7 Ї y†0Ȇ“!D”®à†B›ìÎhÿ¬°fºšš>!̰ë]œåë}­@'w^Ö¢ªhç)Ô!Á$ì<ýæ^Ÿ&š]iÌg¯Ø!ͺ-0mì?  ÒA~q ÒcBN"NÃÓbn¢@43°"/Ìþ.Çr!¼3£F ¢N4êjÕMJoÍiBôw 0z£*GM@nŠQ­fMŒ/JM\/OŽ6Ê”¤ÊÔÛ*rqêz7êÆPxwÂ`F¨ A5@Ì@CreGu£~uࢃTvcð:J®Z  €ôàüj`Ý0H?hÞ§ ?‚;Â’Ü£¼)¤&N äÞ&n ä°¤&‹  B,å"ê$˜Ô².@€jä`2! §¾„ÐäúD@VR¤L$`ÇÜd~H¤hT䀠BH@2KdHшJHÀ G€å&J,¹Ch·¤°@N¨"8N@ôî®D!D¾øR¡|¼¥…íBFˆ„ˆ„PÀ4Q` È%$ËrKÐRÁÜS &e8®â èD°à!¡4nüÁä…@4‚C>r&tŠL Žáô-A`0A46€Hp@R0Eš"À\Z¡|ZR\@rp@zXáð0AVXàh’@L\At©ð"Èd±ch•b! "Å!І Bixbì%ï D"c&.Ê"&( ú• þ„Š! h™iÀ&ð"ýÌÓ-ð"Sã(#&(ÿŒ!Ж  $ìÌ3â{­B!ÅŽ*6!-G0.fm$̰!1ïÞ›¢¡­0áBb, ¢Ü÷##0B|0“Š,k§’ýêi.0U3¢NÛ ‚Nÿ¢p’Õpp!ÏäMe¢nCú_íX£3{ J.o'«Âô£ã4u 5“„_"íâöÙg0§Pz7âi £~Ì@X#T€ÐuGHØs£ ÍÆª“¨ªÊx<0´>PÞ;Íq‡h<¢ =Pê=ü„dd RBaäA@ BDl{ä P¢ ‹ÚDx JKF?`~ÄZGÜdBÚF :äaÆáص"4F!ð³ "F30HÀ$³áÌ· ‚  6! B ¨)C~X@Ĭ"F@D EÒhÀM¡ø…H®$a–„yÅAú…D ‡!®ÔK–IëÈQqùÁö!¥&D+ÚM€$(°eaà! *Äx` ! "!âU 0%*@"6Á 8T Áó$öXAÄ¢ CåŽob,B`+’ Xá(0HL!^"ÍNÅ¢`#> ªC>ÏxpA¦XâŠ!ÞxÇ Nâ ì–f?ŒK­,&—Œ­+âTIŒ˜NbÛ`lÀ@l¬c‚v%3 þÆýBNV$ãÿ/ ` BN×óbø†{™.> â ÖŸMÈ*VÍç`¦z©“Dl°r&ØZo^0èÌÓ3ƒ5ö)ƒ:¡ áà .s…ó‰Rè!Ɔ×ÓU6°ˆ13C6c"øõä_ƒ"©€8-ƒ8pnQ@Kê3€âìv³¡:m“ ð®j3_­<Ò¾@ÌcT  5R³<³Ñ<í’«8£~b”=ÃTxÖ5c½_Ãñ ª€†;Іƒ¼E@ ðd– ôǾÄMðt BAö¢ Á¨!. D eC`WCÕ˜Á¨²°žË8ÀX² BF!¼!Ç€ ³à(®F2@HÀ̵ò‰à¨T/ªç«fTD …#uî’Â$À„˜@ GàaÒM¡üt’XAP`ÄxáúKਪˆÌ@Äl¼$~¼„ØP̼à)̽¤ŸRää؇ÎXA¢å!BÔáôŠ@0§H!øFÀ4¤$êR :åÀW¤ŠëE„‚`æÅÊ#Jf–lJ\¡š? p‘Ç…%",1¢,Â`%ÊõâºbªpAŒA ¡þNë¬a€~D U5ž$*Ê |G"#YÂ^$t0#ál$å$Œ¦!`.˜À$çHɲÛ4ÆQŠÊ_ !œ$àŒ$ð ÐfV-Šö(,ð  ¶#dÍn%Ï‹QŽ–@g¡Ü$ð*þ¢Z <=3Œð-ÓFBNâNž‚õ^Xë–S9 !Óê¨âO7¦oeMgdŠM1&æm‰x4*M‘Ó\/Vmg t40N3Ml/°}mVPÛÖ:Vi)¶J ÖmÀ/ „Û CTÊaÙ-u£ ÎpékÊÂ=c‹ãU6±l„ì;À„7í“mº€sç˜ßC𣼴–ëD&dǾ4·‡¶"¨¤˜¡ÈBA‰` }€ Ǿ‹ €ä&ŽG` dZHžÙäF!ºFÀ WTKñ‚ôë0Äx0h„B S€ÝzTK—|Jö¸¡öLÀLÄÁ—DÚd¾MDa!‡H FÁBXáf¨…{$$Pqú¡üS‹Âí(‚Q8 .à½Dî½¢ ØÅNällïà ïÁÙS€~äÑK¤lîÌ!æN@3GÈÜû€:DRDWo3N )Œ‡g¢,çEʃú"`eŽNB",9)<ÀžXé!Ú"Ç’"Á XáŽa)†ˆž™õ! Ra€f#î0%o …B pO¸'Ë.!!v˜!ó,&¤F¶ÂãðZל€ƒ¼Üœ??~@þBc>Ý\ÖœÖËæâÔ€L"4°¡Çø²ZD@]Ìú&Î,Ba·DúqE,ÄJîXÜî# ¥„öÁæ¶Áõ!òG!ãHT¬HÚ HÚ§H´„„l¶ˆ>((HÈ¥Óè8 ×àz€@w8°ÿ€OðP`ÿ€ÏØ85öï_Àøûì,?"à÷ëØ~<寰`"ý €¨¸Iù ?Ÿ`›ô =àóòŠ–K¯0ÿUiöÞ¯Ðqí^?jà[@þ€€øJû¹‰ß·1Hæ,ÜÖçð\¹_—1Î&ŒPß(Ïë™6ò`®lêçV[îwÇÖCoÔßà<ø=ïŸ@ëw0 ¦j×®['ýz§A¹X­à-Fëµ¾[ø:N;#TÀ!ΆC¹Òn´9 çd¯Ù;t».ÕË?ä„´#m{Åíëçú—ÿ‡»­ ùçØ{'‡ä6Kó>ô3ì«êþÀîÃßA%Ñfªæ{€m“þÏÀ/;ÜÌ>ŽÓúíCëœ6ϘO£Èá6O0*Ù3Dû:Ñ<yÄ,d^ÈF ME 3dD cdnD'Œ5ÇqŒq² É‘¼Mů”]€ñ_Ê2ܻˀpD1$¿ËhP¹€`„CSY/5SœobœBMo$é0¶ âÌ'ˆû0‚T«Àï;Â3 ö0Ó[å MaúæGôU4Èg559Ra=4Mgµ4\¬@!ÐÁ€€Äƒ"V µe†³™GÍ& .²Þ9‡*™’4`)×`Öv`6·€Çªæšh sÀ1n¡kT‹xp( 1¾Ö€Àb„Ê(®hRžç Ÿg•ô~"`@*áÓFé€x&HH Ó ~ž€w!Ž( X©gùÚˆI¨ ™€GëŽ_)`Ÿ‰ºN‘$î]ŒçÚ ’h}‰¡üáGÖ1¦8@¡ò™—‡îFé@îz à¸ ¯V82yÊÜ&±ŸË:"ë:®QŠñBÊÔë˜LÈà0Àä»›äÁÀoltÉ[ä$²H<Î<ƒ„¾aë’®¾ ë{F¹rÀZ.‡Mñ±Ãà´Š zå4Ž3 Ô¾ ¬<òŽ;˜ˆèO}ÓâÙNëdtS>6OS?6ö°TvúÇ`¬ÙTq{ͶQS>6@CeÁ×Ðë‘`f®fDjñ¾€¤ò>’¯­6G$…/#—–}À|/…=ó>‹’) û#„t‡ú7¯™¸D•ÒôE©1ð€'åÑ3‹P(i¢ÐeÔGMÐlu"pšábfE¯L‚”C†,2N°õƒÔÖ ¡jO‰Ìe >raAéC¨0ŽSîMn50©cä¥ ¼aM!E:¤Ôø¼SCeM4× T˜êUã Z€^̘5WÀèÑ«XÞ@(ÇSCx €X’"jìñàü] Ö€VFÚÇaÃM_5²‰€KrІésÉ{v0‹ªú\Ž3TÇy,à˜p·@u` 0=0ñc` -Àˆ˜ çå‚€pëbÖ±öÈÈŠ˜ fŒo2’ ȯ@`©”Æ\>Ë ¬m›—6nÉhü&dœ¹’áØN8e$šð$> ™?cL}‘q²Õ@ФËx1€”Ê‚xÀ [b0 ä Q`8@¦TQ¸±”Ä€ÿ.Kpé—"D\‰|5E¾£ƒB¿5@”ñ¨è†uKpŽ|øUQþo€Q"Æ éÖC`m^¹ow aTA¹¡(¨Ù çøòëͬÐä»§plq²¦Ê0"óå_Oì/3ðƿ׻{«²æÈÁc>âÐZ >B`u—0Üëo~p ï³døÞ FÉÙB˜-iï@,Ù?S>c6C†ÃA¤[iàH¸@ 耓ør"ª‹m‚I‚(¶ÃÓ@œh9…Q $Ã0= ÞJò]ôCJ!o)úôDDZSXBˆ°Ò(Þ`ÿS VQ A0 Â˜AqL ›€1”šÝHqj]0ÆSXSIõ>ß -”Ó„`%M^:U`òU‘Èõ^U` `«QÊ­F1S£ÌÁp@Ãè74bl,Àj€(äVCÓ‡b² ­`S'>I&  É(:LæŒ60Ü\¯aä €p-™À\ù,·æÒŠ Ì–K¶TÃK˜ÆŸ9¤k@H!`(~²DæáS `Š 9 (¤ ¤ÁôW§dðƒ ¯òL?gl<•0 GgáEhsÈ–ÑVä³RÚRFõ( Xš0.i€.‚ Ú9‘ Ã·< N4iT“j"üè'‘ Ü<‹ÈùI5¯Ñ?= ·<È‘à>˜xñ "AK@‚95­ÃÖ#°ÑI¼¸È@¹W‚AV@Á€j`sŠñZS#I‡™V)g‡9Z‘`P-P?;8x€Kñb?†x·€)"›X‹ ñ+ µ€“'c'3HŒ*M†òO8`#ó©Œcø#ø0‰¿©z S:À©8|—ÈÑ€)S:(1ˆX©& 9²ˆÕ˜Ñ€H~ّْ¯ð…ЏQ€  …`§È{ÁX‚Ùµñ—àÕàan5 0~Ap~ {T§É¡ŽWŠÑyšB€Š™¢˜ÀT°‹„˜~x€0­°z x ‡òŠ@)B¯€™¨ðáéâá ¸F Ó: ¨›ø ¶ñ¼…Z0‘ņ`1Ò¢i~€ ê8`ÏÈÞ#x´pÒDZ«`–˜Úœó‡Äh©¸Š˜nàc ñ)‹ã‰˜·¹Ù¬Sˆ+àIðœxÏ)ËDàEø…ðÚ¯aE¬9 ÀÅ¢€³€ Ž€ 9+›ÅC«E"'蹆ÉS€¡Ø££QdbŬaF ÅPʘΜhFí®"€#-P›øí‘ ã«ý$FâÒ‘ÄV€ ¼.qüÐx ”_®y¬ÔkGl~ÆóÑÂê/HÙ™ «½‘X°S½<@™0Ç«°Ò@Åi¼º¹‘ld£ ÈéÉC¢ºó0p0h (Õ‘0†È:”#ï á0Ô(»;È€!>”³×#Ø/„’€ ˆ‚K•xoxx¨ÉÁ¡”˜ò*o”˜dIÀ|z¸Ð=¸·„ø1i'›Xn¿i•}²¨X y$ØŽX—7Ào²ðp¤ØAxÒsÁm—Ðr³ vÐ¥p%ˆw¿Ì»3¢h3¡v3¡ð€@Ї˜t˜€í˜€/ó ™‹&¸Wè!n@I¢… ÌâLWè—›€`™  §b|µ Õ 8é QÕš±€~P¨8šÀš¡D€b‡±|„c†&¡¢€°w ˜’¶{b ¸ Õ€Ø{88}ÀáB«’0){nàtŒ`f„(D* |«¨g*m£ ü-«0ø¨Ú–à·‰€ë+ë†I× ™ÛLAÒz¦†‹~·Ï–ø+¨Ò€´,HÒ¢‚*¶9u OòµR÷Œøe ­(QõQê¾Ð ”MÕ¼ ©«üQÜ•ÑðÁ‹˜{ ¨1À¹…u/Œý ,=ÈQ gÜ‚ ý-¥ÕF%*²â2áêÃÆpFs ŸúâŽÕØ€ ’5å;¯ÐEˆÓ*æÇlvb;Ò»+€p †®Z÷¯rð@˰¯r“]ñ0ä‘_I0H™¼€×"Jü"Á5ÅPž‰Xš(†è4½5“ €“$”Ô\<Šª”˜q\•"öÉhµ ˜c”UW€œ qa¨d©Xl1jN  Š cŒgÅR–õ»Z‡›Xð²,KYg€i|€3§(%nʰrà°©K<¹˜x!{C3€¢|¿«ó¸‡P˜9n83`Pt{:–LØû?à±Pˆ=„‡(Ó…(ˆxU‰Ôð–ABj ˜‡ØÐ’€h} :v“¦ “[R'•xœ–á¡—è©< 采{–àE¼˜€| ¸ …³²P ‡Ù`¶ ©›¡¤* ì-8J‡ð¯T”àC¹·(¹›À¹†pB„J¢Ú±˜ò«¨@ˆx¹ÚsÍéÏ/ð·—ȾOÉŽ0Üfð†AËQK_&à/ ©S…ЈDxñœ>Ñʨ†ÙÀé«ÕÖçðÙ p,©«í¢°»TSݳ’Qð}X[ÅP0®à(Rí úÆ9Ý}â %¹þÒ„‚‘lPQå49,kF9ý­£›‡: ‘Zà 耕:¹®u3˜ ýç^LqSÛ Ýë¯+±<o€7k¶HS³½/r/mó0²ïìéé±5€º!Èd‡ x€‰½ü0y5Ù5¡²¶z ؆À9“ ‚©0@ÓÔùO”ø\”Õ@=\Ÿ•}V™›”š9až’€%h”˜#úL˜b•~j€„àŠ? Ñ‡£•?ÛqVao€bO|¨ (€Œ*G€ u‡Û'à¯(v2õ¤—Ðaé¯Àr%Ž,Ð p¥»L—Ðu%tûã ½bb€HÓ€@ˆ½}‹ŒH§Ëò}î„lAÔ…(/ðTÀ¸"¡’NA—ñŒ4Á¤æùÈ©›—È“ˆ8“ŠÐ— I  U”Å•‹‡ñÕ€ˆ| ¸|§ØG‡ø˜ ~ 8 M³¸zP ‡ÀÖ€Èy ð›¶` ÊŠðc›øFÎÅoŠðŒe©‹˜g‚èJ‹›ƒ-ͽ ð·ŠÐ€žoàß—Ãë7ª²˜·ˆðêˆÀø „þ¸˜Óˆ‡dü…ØØTPøÞ>ôP–]ÄPŒ ¸Æ~Œû¶9ºƒ¤¹µiÙyê9{§´ Ù"¶ò]¶ŽuЀ°‹˜!‚@¹†£?‡âÍUÔ€ @QW;héÝéÉý •"i(’žœFzhè9 ij‘¿€žÆÊßGJõ.ê å –}l\! þ¤­•3€5/YõÊ‘mÔꆡÓ éÒE5Ô1U,à‘ €yêùài0È…F/¶²€R“k”i5“º)"H!“~¼è€²©”j$ EŒ”“Y¼É)F•¨!•xÉcÕœ¹VAWõÈYZ‡Š;†{ª&Š´À Q0ƒ±qZ‡!‰_ÁY·†Š?€°‹€.o0w1m}ˆÅ—JJ;õ$ÊM‡Ùu‡Ó€<©€8—° ˸z¿€uˆzZ¦ ‹€`n¹†À‡³à¯B‰˜€³È ƒCXéFîñ…0ðT €u¢”ª‹|oˆ} mLù— ád[P‹ MH—oáÖÁÂjY@Õrù‡ÿ¬„Ã~„Íx€€ U³ X‘¸~‹z¨ãcÚ{fXz&h@|‹xpeèÚ†x„Sv¯ð©ªh¾ÑæpÖÚ"´Š¸·› ·¸ÛDû¸ŸÏ‡ÎP»ˆg ÀkñŠ ˜¸YÑD€·iëDk…ˆÏ!+φ¨è+óYÝT»묗NÕèBš9(ò îK7(óÂÈʸºÖ~ÈÙFÕ*8tIÿ‚ ÙF?GºywI¬mˆýþ‹ `ì ƒÀ È$: ƒÄ@;Öꃢ°¨€-!‰Hdqð ³ dJ"p@¬(M K¤ò–4÷ žJfòújE…7¡LÈ ï= E„°¡*0Ôâõ*ÅQÑ pÒjÁ°P[ R_¥Õšz‡[) êHò¯R@WjKT@A‘¨Õ,5EÄ +Ãb€OÚ c &daõþ¦}>ïìð½“Ø@ÌSÁõz>oøð00vS\½ÀV£òþØÚ@9(„=wàÎÌ߸ ``v¯xòù0Ýøùà3ÑßÝqð€ï€@Úƒ<à;ÁÜ:à`8¾@ÂÍð~oáðÈA p€ÌÈžÏáüuQúÈ D & 4Õ”à)Ìà„s€`x°Æ'ÙÙ¡`h€ió§Û °X}€ ~ƒ²aö½‚Û„X"}:€‘ü ‰î€þÕŸGì. òX,y@.4 ¹üá'ã ž’X6{€%L€X­¡ ‡ú00ë 0ç!¢0ß# Í€Ð> UJÚŠ€Èz†z+?¬,ÊDá# ]J‡Ò3hΠ¡h,.¿¢µúX°ö%ˆÈ$T}”äVƒŸU“H¨9ü€'%z#m$È¥YpÜ·l †ZiÛ겫½@* g¥Ô~ÝHÅÉ~\×öz&º® ˜B©€ ’ [èuÀ—ÜÇsà‰I¿o‚h:„Ÿ_©"{Š!X†@”žÈ9ø…H>¦øŽ*VgrâIú¢‚ªb,c çÎy æÈ°… *È¥&’j¡HN<ªˆPk¤"Êš«¤,éNjÚ-q©9Èe)'"’’í;ZR© Âêª^šÊ¨q©%âÂRð +øZ1ª‡X(ªŠIôÅk €²Á³„qšÃ¬Ïµ`!îÐñ€ŠDN‹ùØÏ§³\Mhú¤G¸Ì€‡›vh7À)΀ *…®@RÝ€Np n¬> †À!ãkh¨áL  Ò€±üŒªK:xè?@Tp  \“âGñ¾ãèõ¤böÇà@} ?G K*­.*qš>!p‹>@psœÑÂÃíS`S€ô@@aÒîH€ÐO€ ?Œú’ƈ* Þ‘TÕ)"# }t‘\FpÿW€8ßhAÁk\K8î÷ŽòHz–QñåKA”g€ÍRˆDˆª´~AÁâ² @ˆb¯q At,XÒH•„š[C̃‹å 8 \ŠÕ‰²F¸¥Zç$#ă¶b8; aÔ18 %«P!‹öU/ö!0×ë[`dvvQ¨_ìVT­ò-0X™K ‹¸˜6>¹”Á.òµ‰9P6ˆP àÜ…3²U¦ó1$#$…1v`M™!Mˆ”µ2Rψ$Ö)¬¹¡"èJBÉ -D JS< Kv%4 2ÖU¨¡Yn€ k’–€cII-³˜”—¨9JJê%帪 6ReÉTqmÄ® -ÊI[0Íä ¨ ƒ¡Ta8¿Óâ×›‘“†d„ÚŒä@ Â6ޏœ—ñ¨ë€—f†–€BÀ_Æá™#¨Õ‡bg… &©Žäs:á …À(õ;@=܃lŽ@ù­ƒdßaÆu( > XÈSÒwGéÎÀ|ê`(}G9™:Gp€t.€óê/¨u™;¬€;€ ž0>Í g ùfßB (‘•ô„GëÙ€Hi#|EH¬€õŽ 9@ àbâÔþtZ29ә줼ÀŒ!Ĉ»T‡á®…‰½$h^?XGÙBqðŒ`¼Cz· j€¢‡½ÃüñaÞÔú6†ÍU Ÿʧ ¬J(ÄÊDM) ŽÒ)gõ(?âa VCý¬µJ¯ßaa&z²DŒ "Â2bœ3XÌ>$aS’'³/ÈŒf7ä  •€¡tFdÝÇè’qüKÉ% –OØþgPIëÄ)Dz‹Ð S¸o%îˆÀ €T ¤R†¬iÄÈF$"ÚæEÄ.F.ªªD=SÅ,?ñמŠÄúP_ OÎÃRKŒAŸ"†Rè@Œuq‚äWR€Ò€Wð¢°xøÙ¼ärHtÆÄ‰fqŠªFLÓ$_@t¶µìѕҟ,Íü]AHY1y Gî­XY¯;ŒÛÙiÂe"mÊÿÒÑEüfâ¡À)¸E:™B\š†Ô™âÚ úÒÂBÔIx ŠZØÍ$ %!ÌÒ0j-.bP<¡BT!Eö'â~*À¦ êDÖ‰þÓír%)È% )*ª*j ?ÂRppØ­£€b’ц0)-)FFo X))ðM˜/¨k`Â’Øj‰ æD ú ¢¨Ø*ä"þJ¨ g\J8ã4©Á¢4!’2e–rC&Ã&g.C‚þâDê®üòÅV„7á !`¡À ªã~èj X°.Œ7áÐ9²tAìâ@6<NTà Ic~§¬ãƒ»§¯!Òæ*²`:=k", $êà,äÀ*CK$, BöNQŽ®Š$>$<DĶB€C|éëˆ]"Dê«øcx¸C¸4«ˆ¸Äh¨@:âFC2ôE ƒÆG„Ÿ¤»„ŠAD Tä¬ËÆ4¨`Uc0;:H Áö#º¿ƒZ*EV¡ð@@.dÞáî>!¦ Á* a´WáøöÂ!ˆÌäžôB"|åÐóÁþô'¶"(ü¿‚öÀY@\U PU` àC8GòXT¯¼"/*Q‚ÄAþLBö‚|%> fÇP¨`é Çñ0ï²VÉ4¶ŒÁj!¥š÷Å í^ rRb% hËP ý º!ÁW@Ä-/Ú]HÜ êZ RÍOúüÓÍÆ&bt ñÀ-/æY.Müïò!ˆž0aBÆ%0Ó üÀFEæ^"ÄF2ü&m` òÈ%"9M5Æ^j­¢Ø&ÑóB!@!JW6ðm¢, *%)œFá0€J6l­gŠ"@>)0¤ê6i°Lä*x*†%$Fn“¾naž)%ØØ¤Ú@@) š)!í  Ú*´ ¨¤`€†2ÀsÖ2a~r!Ì3Í–1OR€tr Vræ’Þú ðÃhàÞD;AêÞÄ7áã`vÀZU` êØYgˆ7áºvÁú¯ G@Jx  Tà  K º^tlTàCÀƒð+TÁÔ}AíÀ.AÏ>AèG ENð?ÞúE$<`"ö€D<êRÁÎXÝÀ@>!²eV/n¾îºËøFTäñ£ 7à|äxíáî, ²TäŒê(OP!û !ö…ĦTà"ƒ¸!ò3Áâö5H@aðTà*hj¨j½ÈòaQ`èÌÂöÂ&¬0¢#TÁþYHø’"0ÆÒ&Â"{(É$â80Ì@ëø$GÎ!„–"DV’^’ H‚1'¬"Z%xå`/RHü"©ÉE`Æ`ê©ûUå1o¬"%0Ê€% [“$’36ƆR ``Baàý’Þ$& “b)0“Ë& –‚ 2“"buôP351ój"eí30)ô›ïòª¢3dq6P: â%,ádS_¢BÕ a!V&%3‚%-‡¤eszÖ*5€¡‚4àÊ‚€kÉJ–6mzL¤*Š k-e&Æ!@,¦ ^%*ad)"5<°²v “N-‚D¸cna´ bþ`Ž*€:6¼©Ðꇄ*„r!øªÇ"¹þÇ:ˆƒ45Á‹5€ä‚ÂÔ8/àLtAêBàGD¾À Mâþ *Øt>Jø£'ºÊØG”ïã~¯cº'¬.:Êó ç¤}@6:+´>AÔ²ôOç×d¸>Aä=`‹UIäÄ @¯Ü?øG'ÜèW0B$DB Þþê!Z‡ÏLäÞ¥èmÈ”ËT¸ÃÖFN¤ Hc¨FDrLC\¡î¹ ²º è»$O^g JkÄïB¡ô{!¢DÄÂ6‰‹ê!u6;¨R@ucRÄGÀî£Gã¸#«%åyR#'¡þô¡þµO8"(÷YìDŒH˜!“XâŽÂW(„""XR›Uò´T¢èÖqÂBñmB2‘FH÷ňV–Uéž÷Ø”[S¸&7]…´ýbÈ)ø^%£`É¡:öÊs0©¨¦‚ rã¨è ö\æKÔ~ áTÓAðV´ –1qÆ$ï´ ÔÔSÌ"RVCePNB&3Q5¢Cg¶hFN%'N%-ÖŒ57Â~k`b˜×c!BžÕ°FÚ0p¤ùbB<*“‰<Ê,-­‡9"“ŒJ/ ¨ª3«—6Æ*•Ö`–)1À¥ |¨að "¨ Ê/à.JŠ/áú©Áˆ4ÄXnMàç"ñ&ò­¼3Á(ã\á 3Ä•w'DˆPì7à:¯Šä/äŒ7áæê –g¿Zc~–nRgDRŽFë t£ 6´UhÈ¢á×1}câà I`(jáè{ ää ô@¡òU`'è€N™yw¯aþ3Á\d4F§h„6ÆëŒ3ËŒ~‹Œ2j…à/qä,.ÍLWæ»ø‘÷Ø„$ÎIøCHX6„¦KÈfFÜú¡ÇÎAð:‹ùáîBªa,[O’ä`$AÄĬDGŽìbÏiUØ¡%%Jôaþ?b0P=‡ÀK`rRÀp¢0G/ÚWáªò¡¥'¬ ˜XŸ&BE…aÿ\I!„…rd’Q„åRe(Ì@E`¥>¬T÷̈Z)1´ìR\Å3²… `Y7BDlhV¡È¡@JÂ_IY2)Pš ¡c Zà,ØbP6Á;Âbb­ce¥þÐàŸ˜ÿºùÀB ò°"ŒÿÛÝ4[ìd-DÔ‚ÕàžVj /C @ ¼‘ðjc&L(j`!Lûcªib-8Š@a­—P¨–™=Rüp‚ÖP’šÀ¢’ ¨ÙF±`pâRVÀÚJl£–ŠQÇG*Š„Ñ à@¼/à$…ÀãB ¢ã^4Àrà}ÀB©®ÜDáš5aR¦"þcŠp¢þvŽCd–vë'D.%l@ ¼ÝW£~cV;Dz¡À,#Ò°¹þ8 Nw$d;¡Ðva°Áø> =$¦°‹ ”€Ôr§¢ƒ2².¢æÑrkDÔäpÑŠ1”B AO öð7ø6þ€@@@x€€6ø HàÀ-þ“¿Þ’·Hý ÌIƒö& }<×ëÊz ÏPÐü‹Rg€÷ÛÜ}ÄÐØJù×h¬[J_호ü¿ÀVp]©þüµ* M©Þ‹²e SÖçuÅívЂ?m@0ž¿k}Üñ ”ª k³€Ö§pBÔÃwÅÝO«†g‰Úí6»}¯G›µnÐLÃà@F˜îÆxËöU¨­Ý¸3ÿ‘gÂæö·=n§“pÔ„0l´\†ºÔÝ®}7–Ïç•z¼ž¿G¸ä yNB‹‘Ð÷ûžÏóöó€O’Ôú-EË~?ïrÛ? Aâ$äNAÜÁÂƒÉ CpÃ"ãÃ0t4uÃ&KtDÐS „P =³Pì2ýF\2C0(EÐ|iÆÆ¤2mÈ@s"IqÄ20`—š°Éß!pärÊ@ä2ÍKRÌlrÊEŒ2JO  C!¤¥4€q8MS´åÎB\¤ÊMLó9N v´€f»M  s‘ÄÑðÄä1”MJA’Ò'Å®D­-&ŠÒ¹.@( Q€‹MH%@)Ô‹€‡«ƒ)h4À)øÚ¦ÕxpÕÕÐ„Š…š‰€Õ ˜q­ )È ZJ€ Z Â.β`0y³€ é0v°`8¹Àº6€÷¡â çÂT‚,˜×Ò6lx àS€'b# @˜[¡>Ôf@\$8ƒ‰:•­)B¾Ìà«§×ÈÜ'Êú ƒ(ª¸~b`yü•çÒ^ª¥J’faI±®F’­K^°½FÍ.hš.“-wÊ.t.Po3 ¤€'–¶ ÌRT€™.¨-jTÓ6Gú,•2®ÿ|¥UÂ.ÊØfT`ä˺Gþ&»m  ¹ìÛ f-BcV £h»£Èn†Ópcm› ²iT´»p¯Ë G®2Ñ˽NÂæ! «I‚y9;RxÁ½Ô"÷rýãÚ9ózwpÜgãCàû¹G‰!xðŒoßÃ"tHüÃ3*Ôi¹Ç£ÄùÔ,{{õÄÿA¿ ™^„æÁá?‘!Æ¿ÁöÉï@ Ã> ïáú ñΆ^{çIIm%ŸPx!C)P”¤5Ë߀j1 ƒ¸˜’*wJW!”Zœ’ O0i9Ä2îa2wƒÀ ø€0’”¡IúP s XÓô1xuòÀhPQà@/'!ê x4Æ9Dõr”Ð1ƒ¬|0ê3 ­J䶨ð$dÀ 5!@ ªáôEˆ²¼.+0®Ut«†ÉVëX™0 ×( Ä~° 8Uàæ\@1`Bi€0$À{˜5`A—_V0ŽòB’àbMF²Ç„šD@9@½‚—&*€Am#þWòÃH0ºÄŒqŠŠ!%쀴²2JÌé(2d r“ü[@`ü/S\ˆÑødÉñ/ÃÝ-3€>Q HF0ÅpT ×Â4»ž“^äKZåwŬsFZÝ[N9Å©³¦oA+t :~JŽ[©-mmÖ7ÂàQÉQ± l›bÎ>Œè‰h6¦>hhÿ9¦Ð»:2{Aɸ̺úZxÝE"FôhÐ3Î@ú?.A´Ê:v‹ƒh.sø¹–Ñ< ÌdÔpµ³ŽËS·=åÕ·’z‚ÉÈG¥¨fœW^­g> tµTäœ\d9¹ðÖ`\“Ù€e¬õ(t6ûÔR|…c«›ûDãôä 2íPz0±Ú¼¤Ôlû‹UŠ€h@A LóÊyRM‹xþ¬ÒLGˆdBmfìAãu)D2Ðȵ5¡d0­Ô0CˆÉ9dåo†6Ñ=pp‘*~º Èaº1saP­x‚ô”ÂâI9’f¤0ƒ‰È–Õ\†è-!Èea´<ã2SQàP%„UYƒ–7ƒ@äfþ¿,Áé!'ZÌ  -’³ £¬Æ`%% < L¶€aÚ@€3„”KƬÐDL|G1¥ð`L¶ãBë䵂«€ȰȤ á€ü¹@H`^€z'À!o ƒFÈ1$_$ Ç’„´J=„ЈMvE5ÊÙ>T`8|+€?I03—92¤`€6éÇøþòB_à0Ãá¨{Š{D¡ÐTJrÆ@,xH  0Áˆ÷‡ÉcðàD*ÃÝ1'ä^k ‹¾"RX„%æ†3&ä¬3¨¡"z=‡Ræ $z/XáïX¸ó…€XÕ†ÔÆ‘³A¬Ú>Òÿ¤>@páI~âX+q{KÒJôµ­4ü&6ÆcñÙˆ~ÒI»ælö–U¥»‹Ðdô9,•"Ò´—- ÍFÑ cÚ[½6‹mµ„í$£FÿÚd^ö––ÑË­Ún¡…-¤½¥Êpw½ Ãi{m›N7k¸ÆwùÀ~Ó‡Õîø:]PFÐ]´ m»Gϯ¿éðøuQþÐ æÀöÚ ¡ªÚèX>ÎrÍ€mxTAP+ªÆAðÂöÀBŒý€FlÙÀGäABB¿`?ÐÙÈHw© 4c+€ì EgÈf®Bú¸wpn©Aö®#kÚGšÑ‰h£+¤žˆX,À([-€jzŸ@ k!À!ô¤ úzŸS1ÄŒ€§ä « (Q4€ Š` 0 p€³Qä¤Àª3À„ÇPÇZÌ)è,€0w8 S²Ÿë x°À9úuT Z¤žòx}¬•ÉÍ\xŸ©«Ú• *`€Ç`O`€_Hp‹Gû Ÿéݺ ,'úÅp!7â‡õH€² }‚èú‡§ÝÖŸ¨È§ yér#á$…‚hЧéZ¡VÚ‰M(JÈç!':º™@zÖêzƒ`(³²Å€b …Œ!ÀÚ‘ér„˜ Ë}އ¦çúª¨zÞu¦  ƒ'€'v* ãbF<æàÁ¤gˆºžŽ¡Ë¢²Æ¨˜˜uëEÕ/¤£,bʉk@bƒQ#àsÁ¶×µ6ÈÚ.›î€Ö´—‹IÌän®£H%­ ó~Í Ûó8´\IÁ2 ‚Ò,´üC¨Ü8í‡À=HdP†ã~¢=|K½¡†ŠÒx6€ºÒ'@<Jüºmï2™m Ú-_fûræÓi½Âíëñà6€zÒ}6ŽÏŠôy‡¤  #9ÏlÁG“i.º Ç±ÁO u/\2Úà hÚ_,qÁFdtA\#ª|±´^w@ÈGc%òâÌR G`螀0X‡ê—c¨"•ÁôJà-(“ØOGP÷,ÁÈfb8ÉXdÀØ< @@±æW¡t£Ý&(äÔ>RØú,‡ü•€P@T€(&!Àµ*¡‡ B£à±câštÀw©Ò ÇYÀ‡eò©@*¤À$•€p&¶À8ü+ª4ªÅ¤™à)TìWcоjЂGàW8€dž1,]À ’‹ µˆé5[¤õnªEº·Çø\«mpCX9×`ý'«À¯brGÑt_ƒ +r6Aø  p‡‚Æ$I’·f®·Hè†àd¦=%Omcþg-â3›°#l`­m€GHJë Ì]LöŠÍHºOFÄIyènBY¡‚!J$fÆæèeØ‹±±þ¢HK2ŒxbŸ=ÎnŽ>p*Ò5¦pÉmcÔ»”‰Ö5ÀŠ1¡p˜Ð¦ðÝ›™‹tXÇ 2Ò1Hýp&ëÀ¶âë¦4”Æš‘°âÈbvMÕÐÀví[­124Æ›QZO=;/Tê™cP·ªxë‘ÞZB±ªnv®9qÒZF3¥=.¸ê‚2Ò‹ž}\†ÐoÔ¿PÞˆï|Ú D Tk}x‡T½·³_ß‘ÕBÀZJœÁÉ K¡î!£huв}NÒÇ mª 5ˆ ìÔb*`Ù ¨‹Ç„È)°YRºŽ@”ˆÄAÔŒ`´Š`(•ÀŠàè}*pe˜oRèi€nKh 4 ! oÝ!®¡‡ä$ÔtaHõPÀ’M¤Ôø0åPŒ„Qû€úÛ u€k¢¦<ûöþ€ÕP£oèIà«@ ÕpøV꼄€yž­Z*ø{­`‰•( &TH‚MHã)Ñ<G ÷ým¯%ºWVé+[²Ñp…À¹R\¬Ö5Ø>Ê’ü ̱Bâè6ðŸ!s €f 0ß%…Å.¦FÞU¡ l¬xRËÇü´lÄnöP?ç#kù˜‚n ‰l£ý¹”B›ˆºÖ!×"‡*²/E™qÏàL„ÒD [X*eïœ&¢$È@¤!Ùö~‘¢ÚYù.eà›Œæ4 *Én €N èTòqí฀ Ôe &¹!‡Ô†@LÄã›0>-5ΧÓ-±ˆež!†t†VêöByiA•`£q²˜áÄÚÏèÙsžxj2²›‰ÒÕòø%¨׈F¿­4ÄD|CñöŦ»o=å^^žÓOóh5Í£é:»å鞺uMåiCêñ@/PUk: $Ú$ Í¢¬:¸€Š“i¾ì«ì²€  ®=Åm-•t™»¤VݧAC96ŒTWŸÑtÖ  &ÐpŽZ‘\¡À z¦Ñ²  åp¢¸¸Œ©<@"zAnȹúH®øYRz+ƒY ø¥Ó àF )xwm”RŠ]½T‡sÄÀ€UÖ€úa‘Ì}“Ð :HѨ G04¥âÙ TJŽ*QóæŠ—à €p%ˆÀD¨ãÙeŶb®D²j¥ÀH,C*-0 ŨËDÕc-ÕÇ1ðÿ& ua®¬¸’å)°²{h¼4.ï£h‰R ?ÁY Æ$ZmÒ ‰¸XÍ­ É–;שOc`uÍ"$Í ³=k ˜›"v–¢J°¿‚)b "颠¦(()ø!¢|!°'áŠi ¬c jl`nm`<¡BÄ!0(4"¡Mt ÍP<2bˆcaäQ!jÔÀ £ú&Î2Bm&t¤g¤-!ðt'¼!t$« *Ð Ð-'À¦M¦£Ÿ gªí–-!À- - Ç ŽÚ‡ž©Jà!‡X:£b!‹H!‹ £q з Ã"~‚á@wb=㪊íØrç.¢ÒíÿÃhã‚hrK¬¶rç #háà Šâ¥DB6†þá£hƒhC‹ç²<$Ãh1$AC”@n6€Dçch¬.RCV|CªCÄäDX°'ب ÕäW¤ô‹BF„Vè !ä\ƒÀG`‚G 6üç.„kh¥€(±+F¸Ð@|âBÊ(DXdK`Dð€LÁç!¨»gˆ…BÈ€BŠ@NNðQ,ôº@$ˆ` ð‘îSMAÒPPÀ@†à "jÁìNÎQáå!*ðà2,LŒ¡ò‹Aþ]ed†ïVöà ô@"Ál(W†‚ÃånöÌ¢zÃâ&©P‘Aœe¶Åâ`€TˆÈV…ƺ#®(þ†åÀŸl~\¢"\]¥¤ö"2`‚o¢ bkAþUžÍÊ‚Kà)Z)âÞá¸($žþ"2¶þâaAþú"þ¡þÍ Ð!à2c`fkœ É–CB8"Jb¡Ò*¡vÐAò,‚ž¡Iª&J,FVIèæƒ„. ÆÆÖÂ.*PB+â$gínm&ð& v¢Ì@! ‚kOÖnу6-(a3*nàm0FlÇnbÒØM‹ °³ M¦gn4.# ‡ŒÚ­¾Ýj’Þ"ä³pÎpñªº)‚Ó¶{1X-ˆ'•;3®:°¾&û<Ðì¤c|:­¼3¨QP±£ z'L;êÐM¢:°«=ƒhÜÀw#«à#hàQ2B,<àãhy‘R>Ñtg>Pô@MxåK&6‘@M계 C*abF  Éd( €(¤V·éDh ÷¤º,ÏHKa˜±lˆÌ+€RÀ@8 «’ÀRÄÌh<Ñ¢¤ÚhR"2Î…!ª‰`+„òM@R0À¤ž¡ý +¨Šëꨊà¤/…B"ñ寤À0‰ÀÀïêáüSÀQ!ø,€¢ôÌ*ÄÒÅhVE‚Œ<ôepµ:bW€@ÌÌ^„ÀKà'n8(R~[¢¤[¤b\¤[¢`5‰x\j5‚z€†B‚žZB a‚e h b0ͺd!À–ÁªÍAðlp*éÔ* –ÒÖ"RÎ)âîÍ¥.)æ/[„VXÀ†°fÊ5¤éä­vh¡zaAТnbªgÂÆæÌÀHºÎ©èìÂ+p2•´e`‹­6+sbïæQ!(dž Á‡†ÖBâ†}â k7bÁ¸"ææm*D¤Š>¦´š àŒª#ðÑ8“ƒgMÈ9êP!“þPÆ#ÿ9ðµ9‡¤4Ì!rÚÑt Xr¶=íØÜ*L:³’uAW ©¤W?¶@|nR€°EvÈô„wTE`N€È@AÀèQ„,¢ö@@x¶€NèNEºâG!„KaЩúÆd" €0êÆ¤\‹ …€LƒÀ`I€M±Ò+µ!´‡Iþ+à Vº@8†èÈîaÚIì‰`&ð…ôMA¿¯XM@(‰`@P` ]i"QáÐ[u8¿ 2‰À/Q.òHÄ/EJEbbvÁâÌTÂÄ õbaRb‚hâ"ú)Û%à•«HÏ|"!`e#/˜XáþR庑Ln\¬tÍ%ÊQ#X”A¸¡ ¡üd- ÏêÆ×L¡ª!!îkXr!Á-ö."!Iü"$XlÖšÓi[œòà˜fv!€T› JJ/ð!š!°™uè"ôÊ*dgï×#s.¥Ž*¸h RaÀÑ‚ÓX_7 2aì*@h‚Ì¡èœC ¨Bãxâ©è†ËkPoe:!Ê<¤‚nbo|"°pC€±":³¥p·˜D~6”k@N å*Ðq\Mî@gžEÄD¡b6ŒbCDvC`€Å¥CWEŸ´^» ‚Gob@N€Ò€T€ë²BV,Âzåt¹ Z   ⸄€º¶€fLÀJ¶ˆ‚ÄÚÄðhX¢ÀÈ‘dB¸ôäÔ¨†ë²Dû‹ìPÈlMAöŽrM@>î`!ØðóMM!%â3SŒ2Ï0òe=N…J‹…J…vˆàÏJÈnöS€!ù€ %rd&±L*_&Ã'®9ƒXHãŒÌ[²—åº,…À•ºÉu‰"º]•ذ¦PÈ ÕÆ(¢ Öé–h"¦PÂr É¢á³fr!F<Ьሂ$ÉoÈ!â°Êƒ ân†°:*˜°˜â +¢œï÷Âè "ëÀ ÐH!€30# Æ~nbÄŽ'¡ ɈI§e"3bJæVf¤uì!Æ©eÖa6ÂÞÆáFp&c#> ”-6i“¹98jc=5#Ç—¢‡ÙL--ï™6z©JcœyÂ4›ø4±jÒͬÜ##É(s‡Ac¼¥¹ƒ>Ò²Y•ößÀS€QöæÆÆ09]€Ò)qBœ]ègRÕ†°)æðž€@izm`h­"»J>"nîšm8!ÒÊnkqˆÂ“«8»ê9çT!‘QÁGÂÀ¬ÐÄ-3ËÀ‡8Ê­ìg8)æêø³ozFt° H§ Vʛ̓E5pÖ°ñ±(R)v5p (ªð K(žû¡¤êœ[¹ú®5m«? ±-Û¨É9¬Ã páÞʲà(€83 i¢ ¶ÿÏÚUеltDÀ,cý1/Ë´Æ$ýŠ»ÅXR‡ æ[Ø6|ÚÜñtìJþ¡LcÓ2Þ›ÿlLcvÃíxSÁÄ.á@Ëžn|™á!nt9îÍ°ÓÆ8¡ìpqh} 10€ÇòI€‰}&Àd˜Ñé}/õ-aH–Ѻ›G))A&$ ÕBTé±:'tß ˜T@+¥h:Fi}ÉZ¦´î2S0¹;$ô}“9†ƒGØCX(¦€ƒà Ÿhr¡T[e>È û’ú+ ëÿSi¬©D /ª‘I$ó0Ç¡}JH—Ò„… *xA© úÔãRœŽ€ 0Õ° !ËQI”6Ö˜{ f>õ`µG±æƒ]Ž%´Ñ™ pȇhT‡0 *¨Ž€Aæ¿GX1!`|&°d HX(@jp9È r0 à hhVAÄT€(à[ƒøæ±óZAæc%–[ x{±Îy€0ña @Ê2÷L€{3 øw³hÄLZ83`{”&RÇùÍLf|€6°{‰ O!Í Ê)C>ÓÀ ŠGEH!G4r–Ð.[MÜL|4$`9¸Æ #NË—Ö¹¹fbA)™@£dÉ!´SŒaìžf0uµ€5[9eüÚºÞTŒy› œ˜`ô²?¦T×÷A 0îFc’ ; «ÄxHx;ã~cÇ’phhˆ˜ò:jÉ›I7`ì%–ñ›( `À5㲚"øW {Ы•àÊœ§~cÏcÜxµH.1égä^ Z…$ŒIû<ÖÊŸyfNÉ÷µ 0"qWy†SÆŒñ‹>“ ´‚°Ú¤È è‘À³‚Q ZÅ5n³è l 1Ö ´0…ö­je@a®=Ä/£É‹û›k“¸@aÄAR°Ü/°Èû[]m¢­¹ôvEˆ„“À¹}‰#¾/Þ„¼Óˆ iMÅuG{Ô¹}*H)) }ì‡` ]«c´¯P¤}WàíIõ§fV¢Ú€h!ÅÆ"„À’’E©m±Æ´Æ.«>’¡( Ay‘-éYH™|9ÐÓkâ‚I À˜…¦=$ø• ~g‰`0d‡ Œˆ[ €lÊPDØÈn€ÿJäGÁ<æíŽ0 ‰h#@VnL4Õ#À‹€p(N@0@ z›¹Ü[̉jží´PWA_(cô­ò5¢ÈTÙ7â„‘Q‡@­) PÖ¶P3EBx—$cü–ÂaˆÐ.,¿gÄ?Ýó È× ªGû¦¤QÞ=·a­Ì­;¦.ŒœQ¤j‡£Ö`Æ<“€3QÍ<™ÐlÑþ~Oá2®tóWXϧpi>!ælÇý4:&LÄž—RbHu(j¦Vˆˆ°XUC¸5Ù¸œŠT!´j†aù‡e»îâHdž íD:ã_ÓCölã.€h·HÆ„ŒM•<ÜWâ)f™µB•é€Nƒ© ÒZ»Wj *9¦r >3Ëùœ/æ\¶ü˜hNa’†ðlÃ{¥ÏndAi¨Øƒtº)öˆ¤EUB]×ê7—$øZa†}åöÿŸf›×bQöC²øuê˜}!}åôd—ÞszT”LAl¾ö˜­£¡GŠ*K € N¬—!´ª™I .œÕø*K#%w}P@ßëW +¤ÕP@õZ`¡[ZP?°ðÊVÃQi¿„EÇ #¡¸“1vehÿ•£ú>I}±€ Ô „‚ TGÔ¯RBÁ4ÌÅJV.qìĆ쟆l€6ð š ‹AèiÀ/W )çLGI-˜ ’@0Î@C;fä_9Šp ˜§è¿àšŠ{ à¡€8Ê8´ˆ'韊HÆŸEŠ@u(Â…›8SºÓ1²ŠÀpˆc‰˜†ˆÄª[ Š3  ¹Ãˆ"Žˆ£PŒ| aà©`¿ˆñÂàÄŸØÆ!î·pÐç©pÃàÓˆXÇÀ 0 BbÉ£^0ƚ̈¡³Z΀뽈8ùظÿÊήÁƒÞ J¨ŒØoª8HÓ‡H3¡Ý @ñ‡Êʱ Æ¡Óú§+ŽéÝÚš*°Ršà x(}¨gŒ¸g}ƒ*ôC¸ÐǬàì¸a7ùù.Ž,&!TNâ9‚ÛÅ’#²¶ÅsŸ-Ò 9‰+®H°©;‘©4Œ0j¯´^:Zºi” ZÜ’x~j ìk“'ºû®:Zñ!ƒœ¢“¬V ꣯8û;·»YB;à,”Xh‹èi¯bý !”„|¼ü Y²î‰X û!èqWáâD£XФT°ˆè;:?“·øw0òÇB*%h·ø¥@a£èu%™é/ÀY(è‹PtI]‡ðÈ€ {%hg0ðq%ñ€ 5xÊS€ »)Ûá¥Ø˜h$aXwnˆPkó30ˆ¸€és€‰`‚‹@qŸ‡‘—Úa¸·€0 Jð Q›m¦Ð < ˜0 ¤8{ Œ'k÷  Ð(z{Ëà~ ÙJ¹§‰8v€$#@ð˜0ˆˆ (p˜Uµ+l*ÁÕŠˆÉ+ (ªø×35`i¢ŠjŒyDR°€˜øá yÂŒ¨Õ©Áèœr“€q±ðHœ¶pÊÓ ÐÌŽà)À‡!N¿Ãé €y ˆ†ˆ¬ ÈìœI÷‘ ^ `6¸ƒ„°µXÄ‹m,Šœ›f»hê»ÎÄ‹dß ÌýÈ‹wŒHÿ:9­E@Î+Œ0mœHÜÄy/ZȬ‰ 4i Ž(.Ÿ8Ã˜â…øñ”µ¡ ^-lX’´a/‰»½FåÅÙAÀ‚±þ•9ÌzŒ2b:e¿ 3¬Æœn¡xzÑyU‘M#ÆêáÆ¨ûL|! ûÑ»›Ÿ€*Œ"¹äwºØûòûç°d!`¾¼:Ø€C¡ÆùMGøp”‘±ºGùR€«ÈcÆÈdT$Šø€Yi±Ù£ ÌŒ’€óc€eRŽñEH èÉè…‡á]±@¡€ c¥ñÚ‘t‡KëmH‡s±9€‰XX ¾Ah`…ÐØ…Pª€( ÉÌ©¥‰†ñ{‡Ñƒ3rg$œ€Á*€‚5e‡Q“XÈyêd€jˈ€( ™ôˆ‰¸Ö™¡—bv€¢mJ~‡ …0{&¨€HÓrx1¡€zøÑ³EC‰§‰˜x ÊR˜*„[RŒaF_œq ÎÄxÄ•¨©¿)XÆ”85±â6¸Ä K_Ù* âʇø¿†Áˆ“f€¸ðd-‰ëC0*ÎNE9Oá_*ʵ³UÙèÃU`ÆPÿHèĪä)† ‹P!‚)ñ*ÈÊÃ1í¬â³ªøÉNZÎÅtŒt”Œ`w,ÂÎ*àîOx̨ô€Xô‚Àâ—R§Z §Œ¨â‡HË…àçªÅ‡ý¯ªäSàǸàË‘ü9*ËÅJþŒ0Z:,+ˆÑ›:ƒK,3nÍ©\mÃŒªÁžøÊ_hǪjŒ¸e¨z™¬‹’+þt 0(¸ ˜[½ÀŽ,{Œ0b¸{ìX]" PÃ*Û¡|idŒ55BÚ‘« Œ0(“VˆÐÁ;YA†ÑÄØÐù€eàÆe#±Õ­¥èù¡ Ã@µÆj†(¾­ûµi\oa@ êÒ£½"¬ƒ;îŸÒÝÒ€+¶‘CœÒÂñ•ò5ŒÈ£Xj°]jž©T é1@$Ȱw·ý×â<[€9XH¾€Ád©îHȆé]†Há! $‰mqXÑ~ŠA]x©8W€ð¡˜5²–zÌ‹i õZ‹ ˆX—8Шé#Ð8X¨5Œ¤º¤øo30s–à´ ÊÀ˜Ø²† rw™˜Ø × {ˆð|¦8Vø Ø}3w±Žˆð¿à ¿ð   ™Ì –€\#vé°Ð¤´#ŽŠÂ0: âE0qÈNµ,-ñÛ[pÕžÐèÄ›äa«IÝ»z€ ›Œ`* à pÔpÄÃàÜÒ™’³†fQn«Yª>K8@,H¸ål_Bëm¶óx(ˆÕ辰Œ}¯;^’`{¨èQȃƒº|7O(ŠC‚ÎCqöΔEY,é,¨{Î `jž%(ghÊ‹ø* ˜åÅÖBÇ·ƒZry‡ÀÇkf¹b„„G˜ñÀ˜Ã!€íŤþ g€dŽ~’fù‘Å3 5ñEÝÜEÙ&!He˜Ò­ˆ‚a5rÚèìÛ ¢*Nø¾ñˆÃA­­1!”ÀûrÑ'ºÌs·Fì}t¥ê/ Ü®¡9:0R‡PÒ &‹ï9ÆüAº¸_X£ÓáE‡ÁIQW$©<Œj£ •…t©[»‡Ã3•9`·£cðÐaÜ™ò:눖x7ønTˆoHˆ{‹P?ØÐ`x Ê€ v•ØfàØ‡w …Ys€âXPò›Öìð5q%hyhЂxˆ¥¡€ë% d€Jac¶Ûhy¦8?ˆ&pÀ}ð¦Hp{¦`w w h‰à ?àËàzVÎÚäx€lÁ€{‡ËAÒ{Žh.ë€0˜.P™‡òʇòŽÀĘ@ïj9úï¨Ä3zqFQÿ`Æ(üàXÌ«Ô2eàÆèê†pŒ`pÎX¶ÆuÒÌÝØÃuŽtØ ñºZRµ ƦXªŒçµØÌØw¶x!…èÓ†}ð’³€àýÏ þC‡ª€¥¶}œÇ6øÉ ýÒxÁ€c› q+8˜!ìé‚Á©“MŒ©íÙÔÙž x› `z±¸Ý½ 0(%i •üTñ(ÜþjÎÞŒ0^ÉÉÕéö†…:ïCþßí€ÑéßX ‚1+t6ŽÝY0t1&ؾ¡è£?îiç÷G±ÝŽ»ùˆñþ `  ‚<àêˆT2ŠA"PÈ\( /Áߦ$)¿ŒÅ¤‚ˆQ’K ’é( `º…;!Cx I+’?ç,¨Sý/…€ÀÙ0Hè¤øPZ¾àŽ€)£9r „ >ü¥?ì5›-霯¬€7"ÕJºÁ0€ íóJ Ø]4VÐàxÂÍ+Û +{?ÀÖ\½rhã:õÈ‹hÀ@‹à>´o0Nü7ÑŠz1”|U²OmÖ¼cÀ‚<ïÙ7G~¤ å¬^ð0(=å³½`x+fþÝ€¨`` úéàλâ R=žP»®ôuÞô`83L¼@ säŸ@kþø Ó)àdi2€&óüèBX+'û–PÛ¦¨pÛR–ÀX{ÃqRX«'ñÁBQ@»¬¶JÈ¡ lŠÉ¬ÿ%‡<6Ç¥’ÿíÂ]Ù뱓p*ÈI@|„¨h@'«D:½D"É`Ffš?š."Y<'ÊÈ5†nЯid†¬œÑ¤0Ðö¬Ðlti5Ñ‘£L„´ÈD¸º'$†Ÿb²ªÔÄh…¥€Pò, ̦ÜË3X,"õÈ“bèYÍ0%À 9TQGõ4É4…‡Ñøv„xûq@9¹ãDШƤÊ6hÀ ŒL*‡hÇ阮0m€" 4&Ì ƒSF]}D€@FÀ(3TÙŽsäGB¶MFÌ –G~ñSÁh@y  +À(E@|€ ?ˆXOxÜ eãð8 !g‚‘ÂúLäâ% ð<†Á"(ãd¬È–G1Hñ à$†Öÿ>D°¡´:?¢Y µ¶½°!µJÈ D ¬"Æ3ŠÈäX£î>ûZƒc… ±B±þž“3!)0£•TÐÀ)‹ †|$i¡ ÿFU02'†å“%Š>Áþ©’z4³`Ž4P ÒP$C ',õajÉḛ…¡{©˜€™@ȃƒR`"€’‚é*­‘’VhÑŒ ãQ™VŠÁ\½”P-À4TpÙ€­ÌtYøÍf#Ll#*£´ÀQ¦9šŠv”‹=nªF¤¨Â ã0…’;M– –Y.L²Š© dr‰…e$Q•a&šq!:AçYIar–d,Ä@‘ ØEŽg6ø `!F77MP=ˆPÆ!C`…RÇÉ|èÑÚ4‚ ò/ØÓ?i` ‰€ hÏ-Ydä}‚YYYmDY®íLŠe¹»%•®#@9Í0ú˜— JäkÛQ.Cd·Œ]L?ŒÖ²‰å(·0xQ@™™¹E”½ê@Ø!c€:f@:*cŒÛ ó"=9F6À$ÛÂÞ\µBQ kš`8w2 gU@H͘#€ày0*u€(#+À÷”í‡1¢£©€F»TÐNØ€ <+íUãï  ×‰\ö*‹\)ózéCŸÃÑcMJ¨;ãèâAP+,ÈFZÞ.ý:;”¸Þ8€Ú¢(NŽú?Eë!¼ Ñ’ ‹ Dù‡úFÈVÐ"щ"¦Ç%—Þ#$X?ß·T%¢ôJ?Ü™,ˆ[ÄPgŠÈMvä„€-Ç!þ ƒ T–…Ù¯¬–¾hn ËéSØ ˜¨.®@ð&<÷,tZ #Ù% F=£¢]ÝD BÆŠµB;šBS0ž ˜48ÆS(uû„˜ÀºÈS+*E©ID²•”ŒTd9 ëèAÀéŽNÊzÒ²D¢S2TšL!˜GÝE…~N½&D§$(mä}¹‰Âü%Ê›ŒÔ êÿpa" &_Lõ ÂΦ`š Ìâ§@ø‚Zœæa"‚˜¢2æ"ÂÃV ‚ú ‚%ÚÖ)ú""˜"Š ‚¢XÂö#bŠib6m†.A¬Ô``X( 8(ªŠ €-៣2 Ò¢Þ¢Âmœ!gT$`FÎÜâðBŠã>äªa°qAü5"Œ7ÊÒ4`XÛÀ3ü7Áâàá¬/Ôp+N4dÀ4`Z#fÑ€³g7 '#”Œ9cÊ®¤ª 69@2á@áÁÜ<¡Ú:` äN«¸:é^1ä  ?ËDà ŽD£öD±£ä?„†ˆÊ"¶CÂÐTXñeŸüHÐJ „0`^FA¨‰„PÑ¢èœÁtÄP¯J· ô……"EúK!Αá®Kæ³¢GÁüºD „"X„¡ÿÖä6DdW*Î!$ ®ÄPƒ"²†| L –bŒaÍXêU þ‘áþQàDCc˜!çã >P`gÀ¨8íÈzOD!N«$ ÀÖDdîhâþ€¸$|¥¥ï@ƒÅ`8ÃÌBR`….H¶V¥ô`E.nPL%+Œ>! ÔRn!FDÆåžµ¥2W&tE~ à.ee,|ý€Óâÿ2êcrØ0>E ø]éh\Az!I¼ýŒ—â%-€-Ò´!A> áäþ³šF`ýÀ FÍ ¡°"af" €f˜ÆlòFBýb !OûIµ!jgá²"ª<Ÿéà& 6ÔÀVÔœÔAØŸð€)„D)@\b DFb¨ŸâÞjAØkp*aè-ãH €D-àRr#Ô)A€gò/j”ƒ4âäJfjAþæÁú0@ôâ†a°}0CF…P`,àáÂ-áÎ8â*Šp3¢p(BΧ®«!é ²44`.« J}`­ù`d4`T·€ ü‡”6aè„gJ¯¡ç <@8vÀ.„fØ6aÛ!ܬ`?` µ`  jö/` KÇTƒê°ÃÖn4¨–?‚È¡VK2·<….¬F¬:CgÖ!ôEÀKˆ!À‡%Z.Ëk™#„P3pY7r!, Qå1"„¡ôW!¾¶ ‡ö°‘À…$*¬â³dLFNÃP1ó‘²%‰ß@ JA Ò…Lèœ} e2ÁþÁ”Ê%‹F¼²`ö#gÖ6hrņ)ñ¸VR^ò!lD!ÔK**þr0S¡þI²ê¸„”i„|ä®T‡FO¨Ç%6ÀB1”T4yþ$\ LF«b (6Á×!Ì7ÁõdwñRCüwC”ƒwsÃfʪÆ#R1úPGˆÐÁúT DC®£RÁ\ë3{nJ%‹pÁ[yô¦%˜ˆHFŽõn$Pî¬:@t+ 0„d·¤Q5âí„hQñÈñ y¢ì¥¢B²ì'°„àZCuAªs„¶Deƒo]…Cd`V4ÁÜOE|é! AÜL4ç‚ÿXÍž!.ÿ…O{M ¦FR_°úŠÎ„:|!ªƒ˜ŠÂ%ˆ[(º×VÏ%„KnbX¹(rV $GÀ|W $VŒ®ˆUAªó˜TVÿ*µS.þPv| ˆW)FOu)¥–!XX¢±¨ÌLF‹«ŒÉ|òªDÆ EMº,r\¡BLd/¹é-.‚º©I‡€¸dQf$Pd¸óø÷_%Ëe ŽJ4!l!FOb;ns=áÖ!Av&¢ 0CsL\®xf‰µdBxçÆ¢ggá‘fü[¢äñ  ‚™{pÀ†xH£4 ¢‚¦ä°€*†”m¤ÔšB-EÅŒgšè)Iaª3AÎ3LÚ`ÛÚ /™€mŠ*ú/`îÂá´g|¢  ¼‡7‚”|"䣎gC´aü¨AæÞA®8êt1§ G 䃎Ã0ÄËqf4`b‚À #¦ÐxýE¯Üwã‚êÆ$T¡Ö@€ ElG|ÎP.¤z#<<1jã¦á^ÂÄ¡þ¹%$îÔCurDFU.¼FD„€«‚7 ºD€ˆ(^J”¨+;$ñþ%”ùÖô©³"Ð÷Aù!ÌD¡¬ð@¦¯…ûIËâF@N”d® `n„aÜõ GÈëQux€AÂXa¬€à{‘¥¤e…Ì…86€¡þ{Š]»„ÖHer¤Jq¸„Á%1ºíD6öå^FO#«Äd*¹ÄtPDCÁ@kh¼I$iL…dµ¨Ë i…زENRàlU@JúC@Aï…HÊô¥YUzF’”FIK€RTxü ‡ü!:TÐK*²é†U/H@N épY/½µçbLÜ'dQÅ00ÀŽÀêL\‰èE†š{ØÐB%0Âc8›ï4Ü#§¿å»ÁM—b˜D`¦”F8iYP£ÍDÓb-Hñû¼.†¸mIÊB•8@§íP,¦•9IÂ3AnkÖnfÓ7ÓÊÍM/ÛÄÛÁ¼(¡²*aÜm€6.@tÛÑ\*œ+Á° ’EA”†Ð¨J=¹¬1ˆæ)X4aÂr (Þ@J:À¼CH;GiíåDÃFÖ@"â® 4yâ5GN¬£FK‚ ]r‚òÕG„p¡Úx"]¡äNŸh6`vÁìT øb½AÀ0-ý >à@÷Lòý=` ,÷9ÒJø0í@Ÿ ~FÿIŸâicRó“LÀð”°)wKRg(‚FÖI€MézDO`@`FX‘€²Á„¥›,LêSW|±ù4”Íäâ¹é&nU@-êpõ“eH.R†@ ”<発ì9ž+N®¿ïͱµ;¶â ÈY2“Ä©Á¹Kæy,zJa2|;þýN¡€Eíɯ9%“5Á2fÀÏ[“¼¥š >踚½¥šqÿ¥î)ÜI;þR“ç 7@×’€_\­8Vg¼šï¦²ÎÀÿÎ;|›ÎLÌFáaS‡sÿ04ç½àæè&nª§±L(¬-c°i0绘4®;Ì™·Ä=Êt? €ÃÎÃ…ŽÀ~„€F[f»ãÎèDiœa<ªthÎÀ¹ÆÑôb|»\bg»Ü{nÀ»$Fq¬pòÆQ¼DÓG{°mÆ!ŒbJl¥(ž±‰?ŸRü¢ÂÉ­ÄAš$Y˦q’0‰k|ñ°Ð¯ªÜE/ìk8î€t!€0Œ`<{ í(è`a«`Ô༭Ã@ŒR!p‡©N6m)ÀºÌaUd' þ°×u‘þœ”¦ó08™Ž!è}×J›0¼az¬ M®ÐÔ©`jrHÕvâ‡ò¤ëðmÏ'ÊÌ$  2º Ρ )ûv— Ãr!:‡PB @RiØ ·(6 @B£@)Ö‘§Ã0‹À … Àv,|!à1åŽ1€Ð9.€ $ÀênØ$fJ´–f‡ùÙž¥/óÀÍI® '‘Š”¹¢F„$Áv­( J’›J›°£ :n”¥ŠúN—$mNö懙àÛ@§.Ä,‡øHÀÑÊ ¡«9$n’O n¹žF¤aï W€ˆ rpvéL‚t>“©ØG``˜t²“Éšj‚Ð)(€£°ŽÂŸƒ)E’aâŒFXI I¢ Èvì!Léx“%TŽˆ„ñØ~èˆ#¯ ²ws±5Ž$RžÊš|ˆ ­(tÖÓ€ÝE#ô§$ª€Žˆàõ‚ø”¬‹‚"rÈm«TŠˆ†Ùa@½BÖ« )Jô\§ÍÒ!7 §xª¨@ª}o˜C‚9ÔX+kiEõ¾{£‰£8Љ±¶²–úZeЂÙ4ìPþ[ãùi1³‚>–àV@ª­BzÊçÔéZHÐëH›P¥äq CpŽ9ZŽE\Ðf@Az€)‹¢ì@É[€Ú€QäC(ì7€}À ‹ó *Lt’€aï8G‰;ÔBñüð äŒ ’Lƹ)w'¥â7lWÏc¥‘Ž‘ÂI‡ðê%ÁÍ’rüM\#@: ÌI8Ø*eÈž× aÀmàh–DœÎÉ«`t ‚“S¶: % y2üÁ£O TkRÄM^›¢¤dÍ¢=’fÚÇû$fø–ÃHÆ$Ô“™*¦ÙIat1±˜€Hk€5=gðÊ™gpLͨ ÀŒ²ðÑj“ô?”°™ªØxÉa§¬§’v€B)L(oÔ“‡1NØîu†ÜœR?Ì#À&¨Ä¬fô`H.Càê°s˜0pï9H€ÿ GXØ)4wµ‡½6€Äs%™&È8^Š F+ÿ{Ðó¶'nF±¥H|'A‹Œ{Ç2)F+×ø/Ÿ²k æ–¦ M aبÄ]ÜŒCØzõCè€v’)5ÈÔÒÕ„D‘ˆBÈö%#¤ŠEí&N'X”œ Ê" ‘Lu§˜šÇ=ŽF ÏXKú B@cH]“ »á p „/„€&O÷Ôxm7•Ç(³»â= ŽHá èKì<H·]€ˆyïCxÇ3wœyóI›Çé"HóR«W¦àˆõœüB\-hkZÖz^¨¶Ø5¾9|Žá$ 1¦\#Ùrnä¾Â_µ†ØÔ¾ = ífä3J.)ÿŽÍ€%0 ¯¢èàÁI­¤ØÂZ箎ŠK£•j/QÿΛÇ4›<¨>Ý `´Z<*škyÙœí}"‹ç>À'þê y¤üv躩€*›²?` ¨‚€FK’žÏ”à£Î‚Šýº òq¡'ÄÂ!&ò`}µˆæŒ(:€mQ€ Ä$¨ö3'©-¡þñ»  «®›\ }õÑv²Èà²CÈ! të-쀢«ˆâ$›¡'»bšP‘¬ñŸ‘s­ç©(ãº@”Ábz¦ {~ï¬'º¦g<æªF¿­µ¢ñ £Þ2ýã‚j˜°ûŠON“Ç»™‡Q#¦7Næ@MH޼„´$r\H(u "wšVYº <~»¢þϘG¨y¦Š—O²OMd$š0^xÀrCU %T€VŠRé>8èk ÈH Aá´ÅH«A‚¥ð—kò: p % ¬‚$S æŸ1˜”†ºKgÌ)š«O¢@B„tè'D@ǺE¼è¶}À‹`5g‚£žàÂ6 }§%™@66„ –zN)Ì–°:(Ë*לÁk ¢‡!šM„øÝ-©ìÖ-€©ZÏ¥YS®þ¯áhkls•` #˜Y#íS3^ÌÇ’«à ,DM€ —Ãùs޵°7ÖJWS§È‚ÚÉk Mµ€@H X6+à–uꘉ±£¼ä¯VÍx®uÁLAGñt#ƒ’ÕÇû@Ät¼ðË̱0n1€KÿcƒýâÆØˆâ äñ8Ò!ŽHhÊ Îl PB€< ‘¸H^Ù•;*”5²2Gðs§ìGÇ=há çž00áÀ#Àh¤ŒÚPG C|©%ײ’åý3@£üÆT óÙÁ ƒ|†‚'\…š!©E$ŒDàG Ñ,?$z©à9ˆHÍ-`r¡òü?Ðÿ'%¥rl;¡BÍø¶@q€Öy…`x@2ˆä:ȹ¢ÊDq£H %`=ƒ÷‘±šl¤$x†q¢aEÔ‰¿€IÉ Oa€ ‹Žœ:ƒÀç)28íê\‡±<ž•0¯r$šEe¥%9!d,n‡‚RÇŒq! ’”:(@GA%Øm ’ðê7B•ÆRx½°‘.¤ñý2½þíÅ<T09KƒÕ) Ô‚RéÀÝ æÒxNïú&êÀÌC‘CÅ”:31µ (’ÆrlRòe°´€ž€² ´zűúüd‰Iõ59ƒ•~’ÿ–1S«A§àÚs+ ªÐH§F  4Áœg1ž;²\‡TÀ1Nh¤‰òƒù_޼^4Ê(K<Ëà _ ÷Z£ìý€GpÖ3P$`+ ŸGñm£•i>3Ä„_i‹rÎF ~š€@\ X,8€/v"F‘G  ²Cö:ƒðÜdc–"<ËGûÉ%¤„àã*²H"IJ›€Â燒÷’dx£mt{UAi„*«cm´5#•ÈP`*Î@!D@=úó®JNÐ~6 ¤ƒ€0GQ C8ŠòÝiÿw›4à.m5^9ŒÝ²8wGù´§f˜†•ò8| x§ûlîÆÈ8Ž /ÀH­÷îpéE ÿt‘ë~…™•Š®„yó•‹ Cw¡ 6%€êð°y(¤Ü¢’s¦YÕ¯dr©ÒÆG&8xž}ôöu¹ ¦8* ]XR_| )(9L.±ÐLjx´G°‡Ðp 9Á)ìuÈ¥ÎÇ>~OÐŽ20>ÊÅ€ › ´ÿp+Ç»7¡×N¥ÍÐà*cÔñð,àNÅÞÀ’Nþ¹'MÐú†{)â°vñ¼%×d^ §{ñªÑ¥+‚‹yó^~MCÃ(›u(PÁ§×X¥Ô3,>jY9¥p °Ú‘DyLE=¢Ø²JCÁCšõ8ŸÚsHP§¡¸—J¦‘RL€RΓ*sѵ?F©(«Uês¥ðˆâÅEŸ“˜ ¢xpè‚lrEZ5E2“)Â_^`Ém.Ú%*Wá®!¥²5ƒX]@ U`(è²[Ü[k.”öÂ*S¥°ŒÔ"„Æbaû@ Ï6[`(#(ZAü+à Ƙ p.€‰äB¡â-à ¢@AEPÆ„æNp¯Bh¢t‰€4pB:†d ä™b/Kþ" ²FÈ­†#ÐÎ6çæ¬"Y @hÀ¡žnÃÆÃÊé⮪¶^$"¢ÆÂ8~.´ß.²Ü¬¢k Ê䌸§’ðâtBBxÍÖ¸£!¢R¤"’3 z¢.ÇâŠêã°EÃ8è¡ÿ ¢Šë‡Š)'°0àà¢:¸ÄäDñD9ÈÊ! ·ªÆtçî·«z> D·æü‡2„ ¦îœs NB@…~NöðGîEÇNAaø:¤JMª B@¸tãàF¬â»‚’ÆoF‡Ï7A´`´IäZO¤öO)%O–$è褤L"SdúŽ‚’Æ(Hï)å2NP4ÀD¹`OÎL1ŒXZÈ<ONž>‡äXNÂNaŽAô-lšS#äÒš` S¨vQÅÀS0–€P  ~~瀂hªTÁ¼ÏÎð…Ð&€u%ðÍÉeÎEîZe°ÅÜ:’¼_Î-$˜ž e®_ )¦)!Ö5€ dœ€l #fÐкg˜6DZíl»q ê#\#À>…À!¡À2P*`·æˆª‚Š£ç²ãÒ cBašR!®B€`ALMW*ÄøaìJAbŽâR(ðk X5è$¤¨öRàB¬U¡º9áôÅõ‡:Î :¡¤æ±à¥[Nä€üOÄ!¡¢ôÈ¢Þ¡Ü“!Å1AòU T@\[`4TΞTäôLÔeVe÷f&°€6–EÔyÅðÂ*b¬_6˜à—ÐêÎE’夥ÎéŽÅ܃L SûÁÐÕÔbJ'€âx PkaÖ! U&å*.#Ê Þ´ bBhŠ6{j>ä 5!Üänu r%ŠÆ50ô!G¶¦ ¢#€x%¤°82¨zÍ‚C @"<à@ªÒ‚š a¢2AŒŠá.X$&²¥O@éã´#ÄD ÊE‚š"©„$Ƙ!§MB‹Bâ·±K`!¦!!–AÔ{‚BéÎ6g fÂçßpÒ!«ºqU{'޲¢’xѰ¹ÃTB@j1@*j” V·`·ÕL#‘¼¸µ"¯¡þà¡Þ5!Ö9ÀL|¢“D&n´1õ.®øë”.íÂÜäu*áH¶Dé}ÎK#$ îiôFüDÂCÆ訤ðK$ôG°>">aæs!@CïV*| †J@2AõLò®ö$  ¥Y‡ËàŠƒÆDè$ „¤bOܽoFë„8PÐä5‚>`ºIí/"N”B…£V‡è@2‹`¢K€ÃdöRø*NH„èr–R 2K€f@6N‚þS%#c¼‚Dj•¤+(èS>ÅDèéVȶ‹ ¥bè×eWï¨NaˆOAÞTRXlll®ì¥î!ØQÁ½ÐV6N``˜àU©n’“åÎ…žñ…2^,,`H^ @]Aú–Ø+€Œðå¶­P€­ìñf†°›à$Ð"\€žLù8 ò)|œf@jØ ,  0 t! <áü¦}à< bP¾#—~ÙNB.B è[B9\(žÜaÖBAŽyáìyàjpuŒQQ@Þ»O3‡ï"BA@yò! J9Úd‘qs€ï6# >Nö2ãÏvò C¤Ä"¦äรì‹aÐ@¡RÂ’5ˆ„:Oò4PàQbj9òzçõgžôR0 e k¤‚B¦¡cæ%c掅N! ¢R 1´Ì ¾'Àô$¿“dBRûh‹#æCžT#æï¤æ¥"úCæE5•üÆ¥#tD椸E݃¡¶…TNaÀHbN`?” 3%NUo(Eb…h©&‘àƒ’ d/D hEži2%hELeðáý1A¸\!°U¡úúÃî€1@L\ 0ÍJÈNaðš v[%~ζå8 óP›€.!éÀ_`$ žAÌ—Íâah€~ëÂnà@! 8 B­@ Jà@1J¡þ¬ =†Îä΢"b=$¡ÿ¡þÊ7"Q0‹†Ð.dàˆ$1`yBk¬†²§×`Ф'¤ÂR `VpA¼°"ÄjÀö/c¢£dN+)ÿvz)–¢9.œhÚÎ" èàAvñ‡ØQvxΊTº!Š6úã´.q*ÆàQx«VF®.›X À ~(hâ“>¡þcg€f°$#Ýí|"“A©È¢ƒt…½…LÀTpV= Cä-ä(§ïáÂ’{µ"t#tÆ&ȶ£®"†BÊf:Ãà>Ç…£ AÏ4!!@Ay¾Aà Nà^7 `/À täOr#¡úR!@:•îôXRàf@ÌÂLãæ(‹däî ‚[z=ï'W¯  tžä$,6NH‚O%åcçZcæøî»lêPÌàHÄîcž ŠNöŽ¢Àl=9£ç_#æM/°ÀN€X–€VPÁ¬Ná™_„á“Ä8Ãe«\cçµ÷ä–¤ú~H¶ï¬ïYfN`/L Té2vð(OÄÅ….*ÁœCL €j6!°?©(–èTAÌ“ Z $VþÍAüúÁòVª(àlÔü‘%Ì¥ðFó>—Áõ6áÐÅáðÐ`)7°_ÆÕÅ¥ÜE9‰Eðâ„a…âÐ4©êÌ €C‰TÆê`®! | à€ð®˜ýû!axtÿuBÄá-±BâðxlV z… n£¤C~:ámøpV;#а8SJ ‚wÈ.nÂçP¤êÿ·Ðw<|ýˆ_Ãèsjæ…Ó€ð,%5‡`oé¤V;aÙ€ ¨0OT ‚ `!„ ¥\7 ÑZtVÑaÂÀð°„-³g…ƒ®÷”‹0!Ë hÉÄ⸛@vç³°{ôV(ÿÀÀ(­ÃE€˜Šwhl!ZÍ…â­ÑI¶¨ÊðWů….+0ƒ4C –‡ê?úÀ6áÚ-ñW~À ä®ù@þ,ÿõÚ=½|Ñ÷7ëAèö=È«z:KB¨"ú”,Ùõ6°+`Ä€@l†ÌNŠkÌ,gãa¼`Rþ€'[Ä«DQ- Ûk€ kâ àRÞŸèøPÆ“ËƒŠ±¼¨jÇ,q¸þ€Bó}§`Š‘›ªpF€WAq²h·(’LÁ,@ó+Ë,2é§Rh¬p4y N3+•>DeÌ oI³Móà%.„Ri®¡€G¬e €(‚v{L±£EˆÒÀ+.ŸîRwQ£éÛthkÊaJÁ€*vŸêptÐF=ZzVÈEØ,mI2=£¸^å@u[×'ñïEŸè{Ó Jð€Šu¸égz†šlMÀÝ"*vé€Õª§` ñ€góÆ´Øn@@!òÛ€€µÎD !ÍM€‡+•n5à sƒx +…Ð yßç+ÆvˆzÀ ¶w´GhŸ¨¬" ásò' ªÛ¬-"*½¬%ºÉ¢­zâ¹ þv¬ËF¡Zq9Ú¤¬ ½'ó¤°ÃGø~ ¢¼,…,±âÎ*¢Â!n!þÅŚѼۀ'bÊŠ¯ÚºçŠ'¶-!²Æ¢¨»„°¼h«Š» £¨ÃF³z°ë÷®8§þ”ŠÅgþÔÀYªHÇ¡m"Âi `²¨? ¦çR8­~ˆŸ¶]îgs”ƒÓh®­ØŸï9ÿ1S}&ÈCnh#Ÿ€¬(§h88Øp§ÿxr¢…Ük×?'ú“ç3`£t‡`j 4Ì*´- ¹€ lýe«Dswþô]õ€ (Þƒñæ@À™ånÅæ´Ä—GãëNÄ|»Ä^¿,gĆ0*Œ¢jMa‚GŲ“È} e¤’ËâP&Á&’‚ßXËGƒp‘–(ZúKBoAIí &BÆHŠAí)ŽDx2 èç‡Ð…0%ÓŠB’<J"¥†™‹~I)tl"„rˆÀÚˆJDü&X}ÒÀµOkÖ4BÕNÓØEa)•TF9₹‰–%Ó¸¢ÁÙxGÕÂvjOª|¨Ðb©‘ÀžÀÊé)ì .PÝ:#P`=„n‡©í¸¡L—Èÿ\¯=E«…8Ö’º]%ÝETøW€å2` jªÑîoÈíeaE‚&V©qAcø¼AÞµF܃Ðþ€@"bÀ [CÂkŽÓÖ·8&@ÉžœÔ›À­ÂÐX° cŒ!qÞ1 t 0‚È8S ’ÃH¨C!ÇY£êë†o$U›ºò*àKÆ h”ަn7èPö3倬6ñþ ôH”.—Ê,€´4mmˆ·@l«o”˜@ÆÓG/°¾ZlE` a4CúzQ¸Cý z¦8ŠÔþÎÁÏLèhk‘AìoË ¿‚x°þïH]íí«3“ÀCHH Ë0Zø€H%!ÃlŽ·j/‰³âõˆ¾÷Ðð+M…§¡¢ÃvfÁ[ânð\Q9£YÞ ¸-a@*ƒýÚÑŠt'ø´(»PH‰°CIÀ´"±`EYß²Íí6³bQYB `ÉÇĘM‚PCð‘ŠGÄ=ÛÙW²çµ¦TjŸX)AÑ €Äjâ* ò¸‰`XÓ!FI‰Ç36ψðFƒÍ™AèB!ahI0øÍ¼$F ßX:MðùÔF7 èÅH#ÕDDdF ‘ >ºŠ)D l/!ÔB+i@\#ÀD—A²P¥%BȃGQàµRc™ ÇÙ3ƒÖÒ…@"€“GBP’(x)˜²­BT n2ߥ3b¡PjL`›pƒ‘ãQ`~E.õÓàÆ= t®”੤9‰`P¼Ph´†Ð –rÁ[›ð?àÔT£|äeVp ,`lªQ¹*á݇A`!t‚lú·`ƒùò€1ιÆéCƒÜ¨¯2Wøù1 }éCì‚Ài€m€ÂðGñýÁáúÚ‡!Z~ˆW¸H@0 N¾œHH„»ñxC‘t0•… ‡7»þ6Q°;=õ1òMâ~ÌÐ}8üÀMô3‚s®6©ax/ì²ÔÂÑË –¢ÆÀ¯ w7ÛPãAÎ芷aþ ‰òv"®yÌR‹ÐzË Ôhï &âÁ÷ˆÀ™qõ\Pÿ-±™ùº±)(zqíê&ŸX&s@‰ë—óò4^\75¤ô°•ê”BïÉ ­õö5<ACâ§äÔ€H4l£ûGU ²!¿ïã€ÔÍ+3`¥Ú€V†(uè3bµ PÚ– F¶`æ¹ô@;ëÖIXBƒé›çäzUDŒl,!“…SÄ…Ú3™Ú2æôm™±‹Üâ5‰É•¾·_áTâÁ@eÚ„¤‚4XÒ7£éD$œºŒîÇ›J`H‘…”»Ü‚SLÅ¡ƒÎ3±â BI …•iåbÜ~=ÇÕ Å¡ø”Åi½ª À`J“é½E%ŽžˆÅûÍÀ« F&\L–š‚H z£A¬¤ÆÄ;÷Œšð’›^Q`C‚Ç1?Äc9&“±a9[aA!R€"†‰ÙAK11HK ·ƒÀë9Ó%y>‘y†yy‡ao±+<¡Ø³€oh<5Ùa°r³"u%yi"F”Xp`p°~%˜2r&¦â {4  à &x ûV€iù‡B†rŸ~…ˆâž * ‹*İ@Ð /*'øØÑ2`œˆ«*øÙ ¸°¼ÀX`pôÃ’¸ˆ¨ˆ8ü‡Ù •z°ˆÈe€z}*»Ÿ‹ ©‘p’‡úÕ‡øŽ(_ˆZÓĘê˜‘Š€ƒ‡AÅñ Ë ¸õ ø‡ù¡‡ø8 © ¾ä<XªÀ†ÀУЫ·°A¾EQѬ:‹ ¿¨À¥ƒ¶ Êú¬@œ( "Øož8!ºÓ€ðØE9ß­*¹¥p´FÑÂ6˜Š«š(¦ày»ðûª©ÛBñžŠª$wsÌx«œêˆ hª@ŸˆŠ(ð…`Ñ¡÷¨qŽ3¸Œ‘)1÷88qI·‡‚Ú¬ÁåJC“ $[‰ Øhœá7ŸÙ JC­½¢óˆ=.  hwЏdˆn¢Á ñ/ÑÄ!Aá[ԬĢ ƒ°w Ød‘ o‰( ¢‚½K”!Õ€g’Àdk²è ’ “Ù‘|²èXèw¢ƒ ñ/Ñq)‚aAY “øY1éE‡ ?€€–¥zE" Ú ¡R…ù.‡t$"å”Á€‘¾€|•°|h~2€i8 Šp5˜¼P•B •¹R̨q—˜i–Ð{•(•+×XÈv5 {“⪉Ùj€Á{)r€C>‡ñ|‡ÈÔ€ n¦rz9!~Á…iò€ x3€v¦¸ —i‘€Špr™`‡¼L‹ «a™¨º¸·‹ 1b³ˆŠˆª{€+@¨{¥‡üV™yÓá¤Fp…ÏìwGаÃÒD¸A„ ªáд!ĈrÓŒºq«,Ü ‹DdÐjÂxt ƒ†ðkwðÝ 0… ‚¥›p…œÐ¢D0¬²ª)Xï· tPƒ§à‡pÑP±Ê¶¸ŠÃŒC*ˆp’˜{ è“©É»«))©a…QÉEú9’踘 kÝe!óã”á+î‹ ¿‰&¯Iér‡!I†¢(˜!–Ð#+–üÃ1CÇ”Xd’ih û͉ÚBajo‡Q ‡YyˆzWŽPc¶Ð3˜þ†à2$•AŠXk@l–Ò ÙV€E»Ã,³€y=’¤Jc½°–Ѐ Ë¿Xnu‹xˆ4è•(´º\Xw—øv8èw8 pvÄÈ´*ø°(µq´ˆY¾Ò`ŠÐ•CðâÇhâ€T1"‚xƒ‚‰“ (˜ÑÀ°¬"~,`Š©)Ÿ¸ø´7|ýˆ\K†Pwˆè+†È‡|†hƒ€¨æ€õ½€2Ú¼ÀÅ‹ ”h°…è…Ô}×ܤ‡G(â¸Øˆ}‹hs(›@ˆ{ÐiãÝÂzœ(›£ˆrÂ(‰¢‰jš©]ß*XqE*¹ ‡û_‡üCG úÂFýïÀ=‘ ÙÝ ê¨ûÞ*ƈª RdyEE(ĈQøÜ(ž¹ÙÈ Øæ†Àæœ˜Ø Uº«J>ÆÜ®¨Ð¼==CpØ(˜@œ@sT Gi™/ERÓ2©™¬o»È¼²è }¦„|Ésâ(.¥è…Z‘*@-<àˆkhgŸzÔzæ)îš,.¡‚9)ò‘ ‡‘X~’m5ˆg‘€z¢Áý±  !bl©)=I=ÜÃÕ¨y“­~ µØCâFX±‘‘æ’h\²èo!ñ7+ð²™(9G‘ ]”Ø_¥…#y‹ @&Ø#)?ËÕÍ!(Ù=€’€Ãý1~;%yÙ)†!gRé'Cc“.²ÀRY‡&ãÙE‡ŒÕ8I(ˆÈš:FÎSýÈ{Hh$Pt=² –ƒ€•h¥˜•@rpæXøÀp =²Æ¤iqá¾€ yæàÀ­^gX B{ÁF[Ùù‡Xt8v è~g¸ƒ¶€âĪPä:‹@ZqÅfPŸ‰­K ¹°(ƒ‚" ˆ\¹@…¢Ü8ZR°… ²•ðŒ°3Ðß„ðs+@¬L`°ŒØ X¥ °œäK¬à…ÒAî Ck¸^]ä‡üÆ©ø˜ùЏn* r°@}š±€QØzƒˆ<<¯@ˆ: ˆ®ªy2`û†ÈÁ‡b‡Ü^ËÆL` h ŒPÆGL>êÈ´^:êPà|¨†¨Á‡¤½½R(‡!(Šº¥úÆQ̈uCZƒˆŒ{ ØkGmœ(}¬´>©5ÿ…Ëšàòi÷žáÏ ›€#ŸklŠH~HÀ…®JôQ`ò‘s¤j¢Ëm`‚a€¨Ph8kŠ ~-Êhé@ ED6 €#øÒ…>~ä J‘hÖ½™¾:Úìé2Ÿ8½£ -JC.Y—À†.†¨«³”‰1£ØPJýbúC¢ƒÄ$8ó…¡™09,))°ã•v†øÁ…ËÚDÏ!ö‹I±»)¯ª‡Ù#ËãÍäa2`<\¯Ö?©qfIJ1Ñ&€Ùj² ±¤!?Îb<± a& |“vUY?´xhy¨n–øp‰Øy&pH‹WÜLªDúBJ†‚Y‡©Rã’aa\Qq2Y‡)L‡4ñ€1q1t€‰…8ùz8r—(oA¨|ˆ4ËX`ø|Ù(x @Ñøt‰@‡‰õCFï‚€âÝ0Š«@‘`smp"Ÿˆq¨I­Þ€ÃÅTû[fGȽ…ˆu*ˆ/†Ö¶‡˜}ܘø‡ð˜ 7`#màÞ€š•=Ú)¨Š\ÿ ©œÃ€((Šª|FÃy¡§h†è‰)YŸxà€n¢p#P¼0°Û¹Í¼FKÀˆ¬þæM*m+ð8Þ‡ö¯j¥½Üx…ް 而ú(‡úäÞû‹€…P †¨Í‡3· †¤rkC¤!¼8ªŽ•ïùØ“Ä.‹A¹‡yµq2ª5ü¹Ç|9þÛÄ‘S Ò¨&ÈŽhw‘€e r™îU§ˆ‘Êy¢ê!¸ó‚H²€ »QÄxª8ÁÖ‹Ùऑ>6ÍnxùAU û”v瀤d0wXck `—‘œÛÁ à'®¢=ÓÓáì²Ivèe@q’h+  ‘¬©ÕIJqäd·£†ª-umP ñ1=II‡Ó.…iõ‡ŽU¢Â,a¸ØeY&€¡ ¹ †¡7æü,Ï1yy)‚YI–ÊC±y#ä7¼àe’èu’À%è ²îf³W’emMa7—Ÿ‘ðÐIÁ[nq/C&”XnèbÙòƒ8ˆ¹¬‡¹?°l–plYóEÍYa*KX@¥žp^i”Zf ¨4\k]‰XoÁ@q€~¥é8&Âmñg)òxEoðæ†:€óþðÃÝAcÑë á÷¤q­ŒBa`û®9”I@ø{ü5 æ+È`J:#C £ØxûwLa ùí}D‹­°pì^ÃßÏ ˆ:þ˜R#r‡}ZŽÃoèxu± V)Ê@6?Z¤=¦"I¤:‘a¤V¥¸KÊ?pÉ_Øc“ _°™@*9rºÌDsGÅõ1¹C.Ô‰ ¾9”þ ÜÒûL‘$CÑ\R|!ç”ÐU7`÷?!0ø?KÀ”R„®ÑJ$m€fȳß/ôS Å3Ä šB"†Ô©ÃAš(vU(äR´E/ V}lÒ±UG=T  xÎ…ä¬{WÊÈ¥`7ÀßDuâÓCuÄUmÌŒØU!bŸë_L°üÊr!dˆ@ÂÐPÝÍTŸî|(`¤Ég" ¡ÚC ßál„¸=ïŸJÀt¢@ i‚J!2ŸË°|\âä?Ÿë Ô êä‚(@ &“¨†G7`vHaÖ!çÉbš%Mó)Ô8©¢J‰é¡”˜œ0㇮ˆ$j`œ¬ÏÁþ©Êtyº¹WÆâ>¾Í^hˆi‹$”H§ó¤iË( ï âøÌLƒ¶¤‰‰€Ã© Šéiа”iGë|š*wÁàÔr8 £Ÿà¢b!&:>Ï» z? °Zê®Ê9ŸM0p ` ¶á2bî€,²?ý{µâ!†ÒcÙ°ŽAÿcà×U#Y/XG ÀW-DˆÙ&ãàJË©Z¦Q¥ÆrƒX Ý€0I$A*•… „¬2å*åIi‘“Tظ8QT».h؃Ùîà‰èfň_€-i¦EÓ2Gbà y°Öh†Óó_€¡|Æ8Çù›ƒå„©˜æX Cà ˆ¦QäFÀ Ü—½’ó` ü…x„ "K0ÿA„1ö¥2ù‚MoàuÚQÇèçH䡳R>[1 jå ‘À.Q‰£j!/-ƒÆÄB|d 0²9ØÄ[hJéV$}"Ðâ¬R‹Võ ˜¢y€R U£€ \ãˆá‚%‘§G>ùPD0t B4N2ö#íÜ€u"ÙÈ: ¶I?Ôˆ=Uˆ¤"’ ‹Q$ÐÜ7Qþä°ö.ƒ\ÐŽfœ ˆÃ5|…ò GzLL!n$õ‚’bÑÊYæàiqÆgG䌘œ¦ B9”n"¸2BlIúƒOšˆCºFª>¤0~¦*"?ê9HNEÀœ zp“¢=d$ë§‚Ž=-Apj¡ÿ!pe%’¸g·)“!„MVù,À jÜÒ%†%œAþœà-3ó˜«ôñ_]š¿¯±pÿ4è3ÑØ8•08´BVIRº)Zø•m2ˆÇü©€pgÁ|¯1º`RÄS‚@Ò?ãn*Sðšâì©7ª ªDqÚhJ–1L(™!þAN€ç T1’ÂI½$ HÄ7˜üJÀÑPä¥Ò“½‰õ=e³¾Åâ°Êþ3— 'R jHŒTÇZž™€ÁWÔ6¥@éä`Ù4EÁWIî\Ǹ`Ž£$éaU€9’6sÃ` oL‘©9GîwÏ×°€ù’ ç(™‘µs@<ˆXëðP=É”u§à7XHõ7h1iëz ¡!ƒ˜Ž‚QcžÇ#ü” èr@OûÑâ…(lÄ$_‘û‡gÈý¾u¢*\Ñþ É@@=ËD"yá@¢’†²ÉuClX“D$*Éø”=µÔD`§ ;P…¹š&&À”W ÆG7ÈÿÚÅ#v¬7ˆ`ã€UüšFÖìcQ ãÛBWÁbÉŒ³ÀÀÛ’¶Â9uçðƒRhZÀé½eÀ ës „úY $}²ÐWýiqdCßÏ"h@t4x²@i€§Å޾ûÑ%h¬¤ä?÷ÄÈ„e·‘ÖÒ‡ÿ$·Œ‡‚Cô íõ˜€Uõ0'#¯ J8îA㎫âòð9åÐí¥€ûÀ\Dg§·¦w"CÇiƪÁ‹aÀÎpE„©Ñ÷ôÀ¦â‡°L ‰9+aØQÇÊ2é‘0&¥¢“³SiP+Ò°êIREzðfšâ`T¨ï䢓”¶™ —2Ö@"C`Í ÐI’ÞìðIˆ!þvt#‹åÂbbh·ÇxœŸ êà"`L%6(POÎ&0ù‚bg$T)*¥Bbqa†œ¸€1`@„!à=à¡©ßþ*" Â>í¢b¶tà 3¢@r‚¬ç?&mJª4 çÎR+¥Î&-Ø ‘R!¦iÁí£)Æž%ºÎp f’4 D8Æò%3 ¢/Q.þw7Â= ’ÛãX䣄B?Âj6b¤-2¤Tw"²#ŠV)Žr‹ƒ´9Aý¡È¢dFÃôg\HgìÂ2,P)̺‡2ÿ²_k8!á¾÷á¨/‰ö&% å¢0Ô0‹â|È0#„ð³È¼Âè„.­®NÀmþ¨¨:ï`¼Î>L"8¡¤‡ÏâI¶wážAD`œŠ„äö¸€ŠBÆe¸³hL‡2£Œdv$Ñ ¨|#…¢¯¨.L’œOD²ƒˆ©JñDDŠL¶¥ ÈtF©"ãpHø&|ÅfIH~”«ÌRn0£œ%~Vh¨•ÈtT KÀœPÀ ‡I\ÿ…~R¡øR¡¾PiI6üHÄ•ÆûDôŒAôU!zT!ԕ̼È%øÐ¥*E*I’En„éJT \£IÔé\Ò!þ.ÁÚ á˜7ÁjåÀÅÎÊæ.&)˜é‚Õ¥º-d©bM"¬IðZdL¬¨A`0Mf_(2@¥B‚Ðþ+äoÒ!ˆ=gT€&‰!1N>Áþ¢/Æ!¢85aöR!Ö &€wáöÜ"qâiÈÚhÜ! xL 7À΢ ,b8-kÌ  ;B n[&rÑŒ¬6¢PèhuÂŽÍÎFÂb«k>j!ànñ0sç¶d"h.ÿ «¼¬'~ÙBQo’) z%8" ´æ‰L9À:/€:ØÀ ¹bf!'8©¢Hc²¡þáçô&.üc ôžD` t+D@è€ óî°êHæœÏ>MTä#Šîá®!ôH¦¯c„«¨îkvr¢&$äl„ÄAKÄÆgøƆäŠn¾Ä.Ž4½lf‹för,`²δ"ŽäBã>$Ô½•r»õ`´„ä¤'L|ÄÔW (!á¼D @G ã&L‹ÖB‹ô"¤RLGÌB…ÐÔ%"g~h¤ƒŒÄ””¤(„¥~Ll EzńЛBÅ&£p„¬è°Ra¦7 LˆÎþ¤ÈÀ¤È&ÄRHdè$¬ˆˆªPiàÅ(‚È„ÈJÀ^Hh„¥¸Å_ÉHIæPaÆHBKÀþŒhPdöþ¡¼Ï!ŒÖAúÎÄÈTZ%ðdÐhøâ6a»e¢ÍMÈþÉp "-N”ìî!a€#È áš3aÄÍN€Ò ;iHNÓ b3vBCv” ˜E¦}dÊO`Åø~dÊF…B©ê_ƒ:aè7À eÌð-‰¢X¯Â8 Â>éâ!Ã!-‘R¢8<‚Pµ×LúÁf!¢JâX±à—ôt&*‰æÊRŽž À>fÁè`hŠ l”2%ü/Kb?KtRÎÄA •Æ”Ucl‚"Ü•0>áu+kC*˜ñ " ÔÙPZ) ào-ÜÂ@,è€=æuî¿Mìõ6¢ Bo" þçˆ u€Ãp%"“¬àÂáH8j7çÈÖ"œG/R T+ 6®½h q„¦°‚G7G8.1ê#‘Ÿ…â.Ö?@C'Ntº§^·Ò%…²Jââ8º‹ã%Bcb‚¹¨L¼Å0ôw+‚K®ÈQrâ&#PÜ‚c"CæËèK>*«­B¶:îå'$ †!€¢«›K9„&'%"«?Î4éí–*îr£±œ‚bgàf«P"ùDŒ%¢bSq|çX!Ö?–$¡útaü€‘wU"¨âPPÀ*8Æ1Ž z³Ãî#‚ý«bÝH?ˆ3¡Ð€G2ã ‘Œ|þñÛ¤BbL¨uÊúâcXÒl!Ž8í² `8À#¶rbæ˜ûR*‡”ŸTòxô!¯aÀAlPÀ$:ëÌfÄRƒ„Ô¡¬.ô)~‚¦îA^/âD`,G`rD`$ƒŒ‚OŸXøñ¬PÁvT¿DÀ¼Äècþg2ÙÂÆhº ÄЋ|Z(¨@ÐR9}À8Tb%.IÓ¼ Ú‹y-cõþRqš!à•b`2ËĆPy°IIÎ@ÖX@pKÒ>I&°E%õbe8›AÜVpVõb`4\dУ˜0R‹ùŠûæóe¸WåDbÂ`|P`"VÁúÖAÎH´NÔ_î’In– Vv•.¤ôQ¾ãçwÀà.:€ìƒ`"TSå"8·1¿†Â,¢¢-bŠ* 6,³ª$áý"?FîV)#ärÇMAü;BOAxs MUaú8A¾8ÁíÝ ­†~³é¾)àf‚P.ý"]Ñ­’%MÀ8@,8Éf!çÀ!›#Ý"Ê@ƒ4}"G¨ãNÄìQ¿­Qš40”!àP¦`E/eA’;ÔÁþv¢ìBÜc”ÂàfòçìñOpbKÀšB.æ}¢$m¶#„2L†j-ÆC.0ƒ>j"H JP…RÅÐävšdhø I"°&‹’é_È_ÙlRa¬WèÅ6$e'€Ödæ‘3DÉ •üýäÈWF\ hHñyÊD€%D‚‹Ð…0F ¿dõ5Åô3a|&î â΀gÈz@ „!à!3öî{BOèCÄÂ@bgÄ >÷„@å`¹\4ã~Bo(DÌb°Ì67ÃÉ ýƒ2èÁh"£À°à¦ «Chã:°æ¬¨¬º+tgøf­U£V!ïZ3êBu–€ '«x\  @Z®­n‡†+3¨{ª³ŠÖkÐñYgY…Ãáà8š)ØøDØþ!Ù—ðçðÿÔQÝši=(þÂ_ãÚ0Ië@ <«ä+q¡Îmhõ¨Ú õ-*3ú«´Þ?ßVmˆSR2³3u.íMeü‡¸€ÿxRœ}øs:ÔèïhgÛJ{üwf¼m1I›h¬ŸàƒR<`jšª0<Ê+h耋R+&‹S€'“ `B` öÿŸðªŽr5/¼<#NÊjŒ½­¤<EIbž6€z¬q*ѲŒ—épt­IµÅaFÊ$ À"‘X,ˬƒ¬“Èx®+.”ÚªCâFŽP£c”Li!,Î|d?ÑÈþåŒâ ‡15ìÂiøY  ÿ{ÄG 05.bãfË4?ãùÊ”u1k¢Äö¨AäDU‹Áé1CÅZ£h“SÜê$¡{Vm.U%E‘ºjSàÿOD +J†@|´f¦èÃ&ÚMMµ¥ãx™Ì”£d‡BŒ O(µµ:!êÝTÀºL£Ä©w¬CßUµRv4ù¤Î R°L£þ88 'S’˜å:"ýò"0ŠX³é(^¯À”H†¥qJ“FñŠJMqõÙ‹ûÊ*ØÎ»Ó¼ŠÒiáú¯ÅzÒX$ÔË•LCãšó·%”‡±¢  ûQã™NªYû$É Ë*Êu¶µ~ Jx6¢ò5_Žn4R˜ëWd@‡Í´TèHY  -²“uåä¨%@~&¡°Ë²Ô¹ÆPÇð6dʪ[ÁõEô~cRš40œÇó Ð8yJ45®D3Œ @ÑjUw„ˆƒ,ŽÊRÔæ4¸ùi‰XFäÔ¡ƒ¡&†aœkG=R‡„Óu~è¨/b`)­jà>ÖÀéU RÐ$HMóôT¡0;ihÚiÃÍ/@>)áǘã£qþŠÍµo15žSMÈͯ|€ü€\æ+3 À<âc ã•¢Š±Ý|¡Î(Ó '€ç!ÀôHâ¬JÈÐZ<ô!*®V^Ôþ(Ò—ƒ»Rs½€ ¿Ð‡‡ñ6(õ š0ßø¥YÉoJì?î7N5&ÌŒBŒ>ÑÎÂ!Ã… ¥#§ÍHE,ÀÔÙsB[®nC¸§?©Dh‰@(ª`aDŽc@7HØà­-^(fY­Äf³‡h£Œ¬–jL ÿµ­Ä¡6dÁ)ýö i(‘¼¨ŸT^?†¥¸ëNU­«ÁçÌ™0AúB@0X¢?¨ú@)Xz½!ÿ|Š;kŒ×+›ôàCÖ! !À…5´rÜ4OɨtBay£¾BT°S¶zè¦@!ÊNp'³ýÉ)X\ÙôBŸ‹Bt†‘mÊUˆ $J`Àò€„Ê.ȨãB>-­Œš?Ј”¢9“òE¢Ð‡)€É9†y+»&¨‡§é‰[‡øÐ–y+#þXÑ–ái]‡±kÈP%` ?ã–£–Ú5"TÀn xd `p§õ%D—èd%Èl¤€Å¤‚^'Høx—`m!É%˜5„‚\ÙO€qB.Ã9`´y¤G†9[‡Ñi€ñ_ ª€aj5p@†¸—0l5Blµ(„‘Ûà`™˜¨"U‰Y~¨SÒ™˜|ú)€7C„!ª†à¨€³¸¾ ;œ¸£"‘Œøа#Øñ†¦—7°†1\N»Ã‹0 ²È…vŸ5‡1‡°~… ³88® S¾ ±q©à€˜Й܅«F ¬•(yÍÁ 2Ò€k=1Jõ€‚¨‡Û›Ï(ÞÛyÎ5pÚ+øê1PÔ‚8¬½èž0Ú ð£Šx|ÐpÀt P}hÚð³:hÃôv‘ »=Ÿ€+²#´<:»Àè†áÙ€s8‡6°ÔºP1õ,ˆÚ.¬MŽê ¼0³+£Ì€@R¸"ÞÓÎF !(³1›“ðé¬kà2Œ– °@ŽPGÉ9 ‡ºˆ|N›;¾¦@« Ú RzF“àÈ”H”ŠT­pu’°] L«£ºë¬áP ɘˆÚ žˆpˆ¬6ŠPÊ‘ …‘)‡èû¢b»/ :+äJ%!vHòi Á8Á‹ IN¸QX-.г@<ÑJˆ`Œ3“p}pg¦n$;‰ ”(«Ál à‚SCQk-à ±X‚AèúǸ€‡ºm¦Kÿ´z~ŽS’if‡Ñy…²a‡y–i[Q9!O•xÔ¦Ù~‡i‡Ù_‡Ér§²ø£(†+p† ¤m°o¨}˜ó¶PÌ`%B\®K_‰[¥m h“œü€K©_€à•8~ˆ2†q…èu5ìÌ6X†"30„Øê™|/Dso‰™‡¤RŠ€¹«€3oê–†à•€=DBçøþãïÐ „¿Âð×ûê"冀±\Q‹zÆ\L0ÂA‘0- wFJ ûáº09†@ÍiDdÀTP-}Æ\ÑD4W„…™ÐÐsªsÂ@0Mj—€+°áTe{Z Æl.ˆËú3M0Ñ Ò(oÃDqˆsþ™FŠKßïh¡ "¾Šp1\fÂ^° Šüu²¡6è (ÍŠϘ Ò(Ç„„m vˆ1…eáñAÌ5ßS7°Ú´5üˆêßñ0 (ÚŠp!X¨5& ðŠFáT0:Ñ Þ0×-øèE‘N„·ï?À‘O>)lƒcÀ8 >"Š5¡¡p£Öΰ]­És@ƒˆ£Œ„ÀGûœ‚H¢–‡@®ÄŒ¡ÏB $ VâNqÝ—,ðh¢R‡“H ¢€as€ºÓ þí€r£æ¾€ÍJf̀̚4†_Êh})§¨H §ó„͈2—(¢’Â"ú"S¢‡µ, À‚#œ€/‚ „‚P8VˈDJ°þt"Ëqžˆ¾È4Ø„Énö ŠiH3ˆªåÚí ³ìqJ ç€ JÖ¾‡(;b´€šŒàHH\ŒƒJ¤" º AòÚµ´"!z) £ùâ °ŸøÉÿãh ˆÍšèk†œ šò ²{6Bè1 „ƒìxE(Fýqÿ^Ÿü&Œ­¸‡L:nîÛÅ´p’)¡PÉþ¢é( BßÈ‹.úÍz°€Ï &ɲ†žR7~ŠN}""в ÿ°b)Ë…¯z)p¥³šŽCG£ÔO“r —‰Q€ëbA!²Qƒüá&bnÈqh˜6ŒeÇëx2ãý5gš{”‘88–öC“ë%ªÀ ˜V@ïP†=Б“èA›²ÑPÏHÕ€Ú¡ zL 1-§E9‘Î"xÂðý!*  ”ùCðbŽ4Mƈ0ÂÄ¢Gñ¢(˜gªáà†@äaРàPYŠ[Ä0³1êL#ù-€!ÂöÚPX-áþ¬üaÇHšGª ¨È{I×SJÀyêµv’°íXâí4¥#V£ 8ʸ`\A”ëz#&ù"GM|é„w, :·¹Öl½Iv˜Œ‰ô“ã¥GŒ¤¼ÇÂi+G€2ÆȰÄ8DĶ}$JQc¤&P0>ÈATŸ›Ì|¤±ÕÂÇòýˆðné—?€³$0{p_‡’Gà…$‡VáÈ13!HÁÛ—ä?ܳ± Î4’G(ÙP`!…ñÔþFÀ÷$R¶` ˆ1]!Màí§@ÊÓÙ Ð63èC@¡oEŒ8”ÆFHÙ{$&€D ÑgÆÌ‡!à.hÝR –ˆhL )ÿ‡øK"#TŠàF]$<4)ðJE¹@£èÕŽjd8âhù†- [·œ°†0ñ›ð`F_9‡ ™àÑöXÇçàÄ„‘š›H¢H:*´+Ñü ¡y!Gœ £"vFPsKDf:ÄúMÒ"7.ü”j’Güg#ü‘¨F^¥Á! A»£7ÀÙ OÈ|Á7 EH£ä©ÄRöìHr7F’1þ^ øÚnÃâI ø&™j–Võ[aÀ!˜€!ÞƲsapùJ‘Cÿ/H28Ô^ÔÒÆÊ° Ïm£˜6Lh‡8|$"XÕò(m¥÷ 7Â,ŒYU¼Œ¨øÎGÌ+jqñ‚€}PX$§`,ú£ì^’5L¸ZÚ¡–8ê?ã‘o”2V ÿXøäŒÉäƒã°Ê[Ã]BIUN¸UzaÉô«N›†‚¥A*SÇbˆ¡•,Å©„«pl¨ ]Ò Çaº±ú¥IØ$Ðg˜ìŸ’ÌjvKÐ50P×—‹ÁÜcÖ} ˆäĤ2€ã/ǹÐcÖ31p¬&`&wNÇÖÈXúÎëØkÏáÐD"ôÞKÃØ$ƒ2 >HÀ)ôy™â¶~0)"04‰ò´h‡ýÑz$S`¦S:Dmé©”“æIH˜C„Éló¬éÉ"4Á ö× €Â" `Ç&Œ€AÊ×èƒéÙmHqúÒ„;zA’´|" = ÑÅRÇ48á,€†×4BP!!e +ÁzU¾¦Ë¹ÇûÌÈÄo.I¹) Å|p*‘ÔYcøº!¥†‚ÖàÊ8ޤçRA”Ä/¾ÄEõÁíXÆà¿!£¡ȉȶº'…cý£`’È)R;·†Ó·.CG¬M(r¤aø ÊÐÛ"•™ ½#˜?Á³é0Š!*ØAÙcÐä4{n@5Èäc;œƒ4ÿËH2ª”jQ ìºPX$6‘ô’ÆŠ½!4~(Dož<6\ÁZ£CäqÜ8ñØ{=AžÇ F°`ï듇À8ÐŒùaôbCBÎfÉTÇÑVàQƒõ æÒ2ú“è WaET€do„T,p!Æ€ã7aè°†rŒ´~°ÊÆAžŠv6ØËËå®ìvêÄ4Z§aøT ^C @Œ FÉ PÌÀùͺMÁn¿¡ö6H´ÐÈÌ­Å\Ü_äÂIZTåœÍŽV—¥VDºL ~Và,Œ Uf:Êd즕DÂÚEÊÎ&(‘ðl>mŠaÀÀ”báü‚Áìôaà9ì b"oáþ˜bsfÀ#'þ¬â(Lþ  €€!ÊÃð@ b¤æf2LÂ/†Q #$ÒÊB2‚cþã.Éx­ÄVªÆš#þãÎÄx÷ < ŽÀ-)JšXòÈ!ÆÂÒ°j¥¾HÁ¤nÁìJÀ˜)hO©&ïÐÅ0’êJÁ¤8œÊeŽ"Æe¼L’:Ú@I> ¦I̦Ѩ¦Á ¨@TBXáìYAÒWgJZeU!ÅN@:¿ tMÄÒÐnãv>…ˆŸ$Âeˆ…¤ìÀ\¦4ž YOŽAÆWašž¡øÅÅ P­Ŧ8ÊÜa€*UÀ|M!ÌŒ $L!à­Í)l™dÂe\„ìð5åa,‰d¢Ba’Á@I HŽÀ XE/ eÄWaœaÀ1³•åPaà 8ÀÊ"ü@&I¦`>aÌZAÂÕäe€NŠ`Dd0øc¥ò_¡ø×´ÒáÃ@€–çbHc$"‡! ž"аõD+F.Ü¡‹” ×<ØCh61Ž` 7m¾>‰Æ¢´(m¥u¨¶!!ög!Þƒ!Üyötâh‚΂¿O!GäpâS×F!Ã!RUz@C )$0 oà‘¥"JK•6Ý´0~T#!xmƒö|€š *½&@7b¤uñÜ÷‡ÂòŠ`íü!Ar!¡ô<ᦃ!î@à4U 2ƒ Áÿõo4Ô"ŠÐzX 'çšÚb9òzÂ~A‚H„ £˜¥‰ÖM2­þÅ‚ Ú˜¸¨H‹FÃD°ÄˆñÕf­‚)'<$‚¾¢ÿJxJ Sø?@d ¥zI„g¥H瀅` C Œà ðÆèÝB’Kô5$VcþHb8BøÍ÷ÞB‚$ 肹,¶(S!ò,a®z²4Xèaþù¶„& „Z§âÝ…œ}ÄX#(ŠXDŠ!¡¬C¡²m!ò™à(Q€‡àZD-å ¹.Çb„0Z€Dú”ÈšèäJ ˆD\8Ç_(,åˆUŽLVR [ÀPE`NVà ŽÏÚ!¡vYÅ6PÓY‰hZ‚ZÜP¬$ìæc.Dx0¬aùZL 0I¥ÐL ’åò‹Ené*;`ż¦.ì%@¬%Neà\’“áæ_&YƒŒB&"c>  `1¡Þ¤ìÍà†dS żp²H>JÄj>šF­.¢Šà˜Gcw²Û"ÞTf+Uf3ðáâ%áæ,aü£‹€.a²áƒj§C¾+RT». óÄ!¡î §’墶B­ª½Â(Þ‡. Ëføîp8©BƒãœMŒ§È P!¡Â‰¡ûŠbXj¢á+ttä"”¡ó*gîÊ Ž4 x ¢†Ü ÔÄ9ZÞéb 7¡þor¥#`¨„¨úÚ š_/™äÄ>ü2áp\ØMpbO XP@,’HåS4‚ÁôVlm!åi5ëäŽDÜ3öVàN‘!œE¡à]­ˆ%N–ÐRÊ‚ZTrO@C;™Dʼn Ö¤ÂEL2åÈé!žèä °¿àÀ'KþÆÀßn¨@0À"#|ÀÁïH6s¿"`È›â&ýŒ€%ðX@d€ P›Ê÷—ÇÀOðleú½eÀ7Äð@À2Wø._(|‡Oð þiO Óßêbžƒ¬`u•Ñc­YCVêýT¼«ìWÃaÀ À:îÜà´Ä¬¶àÍ–‡µÙö’¥•çimX-`벞ð§€]Á{âæÏVƶ ¬c/f•Vñàm»>ÿ YBVáå<²±†­  Vžë×½ò4üo>#X9¬‹žÍn YnÏüõï€A} Ȇ‚:Šœ´&¢€— x‘(7œ •Å„‡ `dÌ~%Àç€Ô}B ˜˜kß`«*ð·8ÓŽ¢`õ Pmba#ÚÒB € ¢ƒ‚¢j2ƒ™ÙK‰æhfdŒ€Ö@ŸÈ¤FÍÖ|é 5äº"hbŒÙ•ÀÓr4…úAâæ0Ê_ŽŸúòŠåH0È6ö€`mù¦p@·Ë,F­·Ê}„É |(­ðδ§‹2ì àä~²#‘ܪࢧËâ-<þà€‚^­ójxB´…Ëq:²Î`³Y€Û^ÃGzŒµCó;ž³«O ­ ‹2âŒs±õŸýÁþ,`Á„§ƒ÷Œ§Ÿ31Ù|ùl‰Kl´Ó|$ÖÉÐ2ÝD£ÀZ°ërÈ … ž(,bDZçûRŒêyæë€®¼¹ûÄ}ß–ç¸]Y[cý_b0TN „w6@ã-ÏDâ:òÜg ÚÆà貎b݇ù³apŽ("?ÀÁc °±‚œÊáÅ]0qþËqóXgñs¢ÝˆÄ"-åmf“:V¸ÅŒ$%ŒXÿbðÄS l Kø‚0\·8¨Â>yQ‹Ü‚ÆÆ¡eT x¡˜”?Ð)‹0Ä×€ì?ÓÉZä°±s^8 ˆÊêsW¹g-#”´ªZ_;Ò[\‰¤€>   !  ÒÄ3(+e3/âÒÿÇù`…¥~©²‡„ªé €W #T Œ²¶T9o–²±ŽôÊ.`û3Ä:°ôàLÈ+a€‰{€fا‡{  ­'ΩKLÕÕ©0ÊÈx¦dp´¸uÙ*‡œŠ65?Ó‹FDòA‰ÕKK̉“à=éa€e‰€…ôË€)™€…”âˆ3)BÕ¡BXÅÈ h#ý³ÒÖ‡Ë9¤¾t”aý(@zDÛÈÿÆ’hQ1øªGõƒË\%€(˜J‰n¥”j–çÄseÿ7%™Óˆæ€—1[A54g„ écËG–èêiÇýs)ø„­Çð¶Ll”ˆ¶4´¬#·(AYO°¡8¿…D˜@%-Ç-^–ì’ZjÒ7dY@´™ñ߇ÇÁËø¹ù_M60-(ú¯@j='±†eÜàŒ’ì 5àû<ÎŒËMéÉå2«¥Âöˆ¶L#Ëžð%JAbˆ »‘5;*•„T䱋’ЇfJ Ô1\–’r¯™(@­3Ú!cÀ¾QÙ^4·b?"q—P±}2 `(4㱉Z%¯# .±yVr)H¡.€´¦\8ÏÖ±@Ü Í2›`Õ'¼ÒZ 6¤T@hБþ¾í(¨¤¶ð·Xðœã™†ÖÞ!i 0¡† bg†H $à·ò&Sø;.`†—yHÈ%ä âÅcc §€l•h€È+n†ÆI’ž M†ƒèi8±Ý…¸ôE¹Ùiò0H˜VCµáÿò2Á›@C#ˆ³&M>SÒ¯ÓË §å0€X cw¤vaÑꮹÐÿwÜ¡–à‰|ë¸V0æd wJÏwò€ãcIˆi]¦ º[»J<,Ö09bÌ·*÷:®˜§…ž Ð@U%Œà9’Ä™Á\ôå7Î?…ÁÐ-ËÜyi–¡Çõ—ð3^8 9>PòAþËuÖ‰–6xÿdæ-Ò8º™õî˜ 5`;Ùk–±èÿoÈmý9âÜu [H,c)=ŽºæF$9|¨±€åI$Ý1OE»I'Øÿ†ã.FS™ëÀ1¢ÅŒ¯Ö"•ûoQb;K> ©Å?ƒ×‹h, zxP3@ÛŠ ½¡1<2šˆÃ9À~X4 ±‡©fÙÿYa‹»5>•xÙ KøÛh±èd 0nµ!¹ˆÁC€ ‰€á3Z’%œ3‚˜ùÀD¤áˆ5«¼&r•‰³€ààY ‡‘‘‰§á¥³HŒR) Î3ÂGš("©H—~§˜r™pk`v4Ëg7`€È ñ”µ Œ4鳪™G²Z„·ð±1¶˜„¢Ðƒµ›u‡Ñކ(„‡`Ȱ‰™ªÖˆ$E³¸›8@‡I‰†ú”‡qu‡ø£ 0†a¬€4xž ¥™¨?h‚8~†¨¦-Š£‹­úù2§€Q5¡è²”ÿ‡øÌ€Ô‡ð‹ˆJ‡ˆ”ÈwÈ{‡ñÞ 3ö  È©2hñr_@² kÚ<*2ž´üxF€´‚²³h¿(â ÇŽHÐ,|œṖø¸RÐÃ5Œ ¡dFÊGÈ´¢ø§…$¿€v+Hu‘P|Èq¿€а?(Œ+ P‹)[/М 34>8¸Ø€‚Q‚!ù€Dóð rü-x1‘ ˆ:pŸ:ü¯ _¼â è IX8é* ØÖÁ¸yg‹2Û7H·ÑñŠ{ê ÙW€!{€Á# Žk“éQ@³-8­ÀÙ27À±†BC|žŠÚ0¸B h˜“0.p ilÀ0æ®]K4/X¹†@î¥#€#ø”C‹°¢PL ”óUù­£+ÌÒžm20hÀ“ œ \%ŠæœRY,£'È‚M”8`*@s¢Éx! CQC€CRýñØ'ሱ‡HÄ“<ˆ$ß±³€)W5YcBy· w“˜\‘P~*@`„E•áòªñ zÔXt {™ ˜«Wˆ™]Nyuψ±Ø ù~—“æC‘H†Ñ˜ŠAœ1b¤ùŽ€"} p´µJyª8”Ä ŽXg™ˆ §˜”pªD?#R!˜†Y‰Ï} ˆ!_ 1\˜ªCƈ—ø|º špcº§ià¸!˜J J™${ ´§P‰´†š¤FÁ^¹Z‹1+@²¿›f 6Ð °XŒ(i‡À^€1xÔ†h{…K¼ 2W­y°ŠÚ ú@“0 øx€hR3’8H²2~‹Ø#X‹K¨‹5>ÀÄrSù铘wwŸ€Í9ËȲ¿‘D±á8Lë"(³=’U®(²žŠCÀ÷‡Y‡iàáØ/è­… ² œ? 1âÀ4K"ø­¿ãÍ·Ò!3jš¿“°R.²NŠÚÑó Ÿ‡õa1૳X!$Ä+HJ¨ ŒÉ¦ IàQÿ†¢PèýŸÈ·?¨­•3oÁЬء –¸¥zYK ¸ô.¼0}èdxy°®0­¤ÀþÃô 8Ë  ¯’ Aa3û'ÉnW¢ÛêRs,£× 88 ¥P³C#«´‘£»1“Ièrˆc¦YQ È£¢³(Š ÁAj2¹(´Œl%€hxk#,S¯ÑßH»a3CÂ+$±UG˜ë J°¨‰PA3ÇÕ‘Â:¯Òs“Øi€ø§!~‘P]˜˜v³Ejý5L¡Äº±U€H„‡Ñ,'¸ˆ;KX2sf”ÛY“0 “(¨0‹‹L$Ñ9‡™³†Ê¤ø×ÃHÒ˜€êšO”_–ƒ§ñyÑ0†2‡mΈ™¨˜Š“)ljš‡ t™-©Œô 1˜€œªs€\S›8y¨prŒàm€0• †kžÛ{ƒÅ9ª³èr'Ðkð}ȬÉa ‹ü êQÊ— J˜‡P ¹W¾ à S8‚\ˆ‚Nª€›fˆYrñ‘¦©Lˆ ¨€— ˜îiš‡»p7[>Éj  +qQ¶=´Fˆêv— o’pU ƒH \˜©³µƒ˜ÕvˆÈk‰À}ØF³ùQ¾‘$y µ‡ØH`€%:ƒ@z-(o‡Ì˜þ>ôßID};]ŠÚ8 3ì‡ùõ“áÊ~#ˆ²€;þmIbp§…‰C;ÈŒÁà HŒ üˆˆÄ|0Uº¢Ïyÿ€DDÔ;8§¾È!0Œ;ÈìS ÁnnCé‚°åKp‡Q3®ä/NÍ À·/ÔƒÔб€ µ€–ê‹Hñ$±€ fÈÿçfI {×øaPÓ¨­×d”*ðƇñbX³nÑ/˜¹ïF“@È·aPe]Vû”WDªêuìR;“ˆÆ€©pS`c Å h{dÐ|-(³1±c¹!6òµŠÛÁÐ%•W k»IAÜ A²¢õb¤Óø‘ À“€ì9Ø`«%:AW‡¡fáL+ŒÚYb`€Ñ8R €mIMï™ó‡‘+Ñ9‡é[$ÙbP9bP –0¿ƒˆžö—8Æ„:C>/ÄLéñ5€»Ô¨0 “›’I}é€ÃêÄD]—‹Iž:@ˆ ~Šq”ˆj˜Ðxî¯M€™È8 3p‰§aN·Xí~—r›8 ü¶˜Ç:tÄ\甈}˜3RB} …Ô˜u€Øâ˜ëal7™öËZ6n¡ˆp— QÞ°¥›HV°tà:XŒÀ+£y°+ƒ¨€zˆø}ïŠØñY ‹¶˜4­ °<€I*`~­8|¦Ú²’î›ð°<œqÀ¸°b ­½§„Lá[‹ØŒÈ ˆu2‹pS +>G1-˜ýe§ÔVæ‹uÓ©]ŽŽØ ˆ«0"Äð°T“¦#>Ê&€Š|ªh´­Ø~%PuúØu”ˆ},AT ´Ø­œÈ“X XÛþyôµ€ßêЈ€ë¾,‚Ï•Zòã 1MŒÈ:ÇÖ!<×&Ⱥp| r0|žL· ¥“ê-Ÿ º&)°Q =ib «6€! Ž’@?‚ W³†Q’ ³X¦ðË6cüˆý]Ž‹I“€ 8ˆ9 H)Nú›¢û®ÙY !Qn%‘¿h 0`̸:éQ`zPÔË…éß± ü$ hÿJ9  ˆ–¸;²,¢P}¥È\–`zˆÌ‚ `Ü þƒaOp…: `h0I‰±3аA07ðV刀P¨`–¼!OX;òˆ¿à@81 áå“Ä‚P§Lµó™LƒÙøpàcXJ8¦¾a ÜØÚ˜¾*ñ)ûýí×€DY°–Å ŽÉkâ[™CO÷ô¶8ðµ9á !ð—Ì«`<ö—Aó '3¾"ÇÄ_°ºD¶ìwOuš-¨uÇÀOmlKÒİÀ ^ˆ™†{°.|BÒæßñ,;ÐÙ|ÕËîí+@jÂt± 8Z{S}†ð·ýUÿ"\¡Rh~ )R°×!Pt€…ȉÀyœhaêˆ'òøö¦ˆ#楈 r†áB_ÃL©þr>pqÿŸàâ`†ËÈ-¡€az¶ðÒb%ˆc‚3)6ù¨H |†FBFl¡‡¤{ %h`©€ †Á,d#¾eu¡Hr èZs¡L¨%¾qȶ!‡2ÊžòáÔ«€'rª~„œ´‚È`)9èZd’%Ìò*¾fZn èJa‚ È`0 êAþc¡‡ô~‚èS ª0zü†HSù¦ )Ô…iÓžÁ:p<@ Öb!‡áú…4°zT‚T!l!KŠy½L¯ ’¢ ,‰ˆCfìHgJ ø¡Fœ5f1U1[Ÿóº M=µê L)è#©)ºƒ @ƈ­9«b —Ô”‚,çø% €„R‚'àPF…0 á€@êX; fx/Ïjé ˜o¡XN `Gý¶´@TÂG±•K€&Pt0€90&S΄0‡úT‰^¨%°ªrHYއŠ"][È&…P¬à€8¹Qªø‚KH•ÙÁp¹Çl²‹¬¦Z¢%“¹ÿ¼(‡BN-OJño(âéFÅœpª`ù³ˆQ ––§‰“4/ˆ“6e‡ëzc¨‰èÞ„ÑØ:Ý€Šh°ŸûÖÛÔ"&R^n€á }. ¢Z­‚-@ÉË `‰2í犈€`x€,C‚9 0®b C21'´tÌ€¬ c¥¥Ø~DÈQ*=©¡€¥,@¢èj † äl†šÛ?‰Ï ¡¡VAÚjÉ ¡1Õ°<Ø èPÎÔ`¦ìH`3¤ÉÏøv ™2 Í&GÕ$&Ft@È@Á4 `I™ô´É BÎðl§!ü»øÏCK8®ðTŽ@)€=ªÐ‚6QÚk@ä0@vº¶ ?ˆÈÿhh¤ÄÁGùðÌÇqþÐSÜ©CL #‘÷Gr§ ’äö·Är?ËÌÃ!R8‚2¨žB¦©1ð”¥@›T Š­±³@Ú$EüƒÍå· ˆT–b ·Ä“'HdN ”ŽFX‰ÈÇ$l3@Ëxÿ„dÉO’%™QPXŽt¼@±yEäl±¦è?Ö!2‡£ýHaÿFϱ .oHƒ´rlÈü1ãµ—¶PÞˆ1‡52p¼¹ÒœB“A‡"7`nÇBè t'‚SñR îqƒc$ª 欪Ÿ3¶QЇu#ðÖ@DœÀ$˲:^ðÉêÎ@$´¢€Þ: ØÄ0@ ÝQÃ6 Mèa€ ë“Ø´SGYà–~9:¦g É-9Fô• )è7£tÞŽ£z?ˆ±¬D—À J(0Jžúòm‡ù cô©‡ªIÄàãoT€0:cÀ¡äà¬ô¥¤â:“„z€2 %À9‚ «.Ù"­&HÝ¢¢„ _‡©¢§rì|Ä1þ ˆR1=·xÆ“æAñíT·™©{WM„D¼€²HEºr‰‡µŽxCêyJ¤xÐ2l{UEs|… .ˆd0 +pË""xE$0p^AÅó¾Ì,ŒAð˜Wãô!1Ü/ˆ`ð# c €Ée!€xqj…H;vÆxôƒÎhD¥ØÿMA$€ ÌÑÈB7`J#‘øÝ'#R×DANŠyY€ðGbÑý€ªÄȦü†r˜ ü7#†>’ìÜ&Ý î‡KO]1 7;²ÀpáŒïG1«]€×çF )è,íž·šxöû¥¤K£šŽK^5t6Fl¼ð9,8ÞtcÅÒõ#6L/: ùq‚{\ÜVþ\y°¼3Ón8”ðHHü ÀÐ…tv>#HüugµS«ÐÂpÀ5ˆ4À(™eÀ mRE{eÝS=ªü"FǬv¢ŒÕ|HRQ=¹Ç3ê è€ “„‚C3Úˆ ¡íG`’ÙÌðÄ)IÓ±B@Ç[þ#èßPB ë·}ùõ„*1o®ÈÑ@D¤êÖØO ßùŸå¾ \ ê&qZ ÷¸w•Qôœ’‚»Ïì&LøíE¢ÅÍbySé å !ˆŒ&Fäîô   `6½€©dèÂ@¥4Ïìþ2Y€@D…0 „4`Ö¨„4ÿG>ˆîDzIÊ#2=°4† œ%ID(dœf¢ŠaòMA•ÈIÂ^!PÍ¢D4IÍ^oˆ$h#øXD4o…¶Ê”ÞáÄAó mšpìª ŒšÂœÁþZXÅšõ©¸"ä&ˆzFÊ"Ç ¤Q‚dl°Öo¢¤¡þÌǼs°x †ìÆtÃ$~*ìöÈ{Éz å~äØ0¢ŽàßaþùÀ$,à‚PôÜ´3aºc‚Ì ð‚z¬&ô„­ÄZfhGàXæ„.ȃlœ+¼£ D¾%¥°×âClEÄæ…ÞÎ>¡B$kâ¶èúbìéX#ú'© w¦ö åz0î¤#Ð7!Š(¡úÆGz'Â"JzIÌBìâšçVAˆ8¡ð,cvæ¢%Qb"FÚÝ""âìC.-Aêm¡À5ħ¡îqÀ3``{À87aþ6ÃXÆÎb%£zšÁD‚( Á¦"Áð±È' ´~ãÚ0ö÷¡î/þ(þÿ&T€E8Âtà@‚Â*d^!KÄUB‚ãÚèà²CD’Af!ç( ÒŽÉ,fèWO>!@ÒCJ*á¤CFt¥£Ú–²º[‡ –ã€nÁÜ‹Üeë–Lƒà¥b¡(‚HâÒcÚ€˜>hzÎá¦" Ãæùbäcç0rMrø à°>iÆ8 þÂÎPp°ð>¢‚D‡÷ âdó¥` J ¶&AŠ>sb!³Å)Ï€è†c°ç6en4Èd¬=¤ql!aø `bq2>aüPÁö,aö“Àन ETL bÖàÞáþL è&S¾gà”CD°t6sáð'jáðLL ˆÍ©Øá0CQY-` „@BvCSÖˆ`¢(§j‚H$Ò¤CH¤$ àºCSV ’Ì¢Ãæ„©0A¿à‚iœS§b¿õÌ æ¾)âh3RAävH6êSGÄÀÐvÏL–0‹mð=¬I *Öèåê!†¾­˜F‚eÀ-,IÎa'LPp p$¯FHìV=¡_:8 èpFÚ"P é`báÆAÁÞÕÄ*Ás$*fh–¥œsÖ–¯IBMbübªášCIjT¤H¡0ýM,›pÙªJ¦“„r)Ì¢ÌRýSX!F›Ð/lâ¨7E ¶H0€pÎ$$bbF즾öâF´ŽS´´Ô5äæ `tAÀ,qÐÖä’)Ì„ЫÆPh‡Á cR›Är3#BZžoþ#Ì{Á°#!ØæŠ3áÿ2¬âd#>&FMÜrÄÑ#nÆÚ îebš¥ÞÒ¥($tªtx‚²+fĈã$±ô¤Œ†ô| -NET"G>âŠÊþ§,t£{G1§æÚ#À®¥Îhx’Xv‹Jƒz†~1æþ'«^Æzm¡¾~@") P³J„ ¢[Tx8M¬BT ¡ž(Aªnú €^q?, ó:…4¡ð[ÌZÃáôì–ÆÑxT4!ŠP€ ‹äS²ÄË‚Ó TæBaûŠAê–Aè$õ á,â„4¬aqÌØÕÅZ= n!VæäoeFyÐ@+ël‚dðï¤ìV Œx=ªt5£ÚhŒaHê5 qõm`$N@ ù;ŒÌ`ÁB÷5b´–Vãn{®l>pü6I,ÌbYÀO‹Ì¥Yq1âH‚dÃöˆ‘*& ùˆbö’×Ö˜h>#­t `Ñ@l(ónaþšöXìNà 1‚[ X aö`Ôr-éœè úmKt"æLqÑxþÞ—„ä‰P€fL•ðÒ‰­. ŠoáþT®bÂ¥ÄâêáÁöAÌV€vüé„áÇÉ_0écbáÚX‚üާFLQ‰ZsᲕ’hٰ׆ŒÆß0 ˆJY€ZWàF§Vž€f–b2ävúRÕÖž–®i)ÞEIjKÂ$èÎa¡ø÷Ä-A¬dÒ³HÐè,BDk û¤ghS¯:7æb8C…MÃ$Í@,g€M‡¤zÜâø0`„1áÔ*  7 @¥àHA#©„µø$¤vÃ|!FÎrâ$rB.Š^ ¼2C¤%§JpN¦"R:# 7 n7 )ÛZv†ðÔ.ѱfèFFüzƒÀ«âZä#¤áÄ/€àÃZ ¼ÃÐ+ÃÚ Cì¢x°Œø$zöå”]çEDnJ‚õÏ4 ‚„EB Ãæ O-j!†ÂKC{؆’â¡6!EK½‘7œcÚS¨a-B…W@)<8vûØq8q§4­Ó¯’á’ óq, ›Ä1¢ ›T’â cæ ÅI5æ%~n³Â¾™ ¢!ÚGáÊö"S.!ÿ”³ØEE~O¶I½‹3bà™%&B¢‹%. â®!“ïhaÿmyÐSü3~oDQ> t% Å:h˜õøhä.’CçyânD2@$bùââS’E¶ÜcR®ö,eÅ- =òGá¾–SCjdb ÐY*`âªÅ ÊÃ*ô^¹‡ª=©Ø<!º2¥¤ùæ¾Ôp4£Ôo™‚áÀz`¬%J§BüðâbªBüzS=6›ÅKòiX‘Ê ä&ðâçv!²]áÂŽáö×Ñt|h" œÀ‚`@ÀЧ ² húbâ‘"Fô< Žà‚sàŠþ¾o¥WΧ¤êô%¤ã Â„Ýè˜R HjòoƒŠeÄÚ"!Â#”pñ>{ÀT`H1àBâ´•£#Î7!‘Ùá•J´ÛVª‹(@Ü@b]Ú6ÁÀ(¡ôæŠçO‚("CbQÈRÂ"fΘ#T0"zxÎg¼êzÑÈÒXÜMX„ø$àØ…z ¾£Ð$ðj äÒet aòJÁŠK¸WdCâ‡I3fœùóÊ àÌCVžòÈP&V®éöQ•È!^ú Ð!òáæ„.02¡ýïTŽVÿ\¿›þ $^B0ã©ægí‚¶¢ön ¸Sk¸ ‰#`‹eJä4Ôe]ÓAÿŒÑó¨x `]€$ÔÀ÷˜àöì aÌ>ÙÍÇ-bÃÛÔR<¿Óò wî‡(NÆYË¢ˆÛÚ&Yqï¯:i°N!‘xߢHÅØ¤vüì ¶ªå¶Lýe|q"ñ°Í{ð4„áþDÎSI-@Æ÷ƒ»pwëþ%ÁÃ"è;ýñjÅâ04\)EÁÐp>ÿ€_á8;Å÷p> î¡ ü׋ˀùŒ±Ý  âùX3,Ÿ¿è08°i&sEé/ »º%ÒÀÜ]ÇxG"ñ0 _¶ àË{Ó­2ÆäšÞw:زpÞ‹¼dÕ§ø&."ƒƒ¬ öφ É®¦)wb€M—lÎüœ<¤Ù:ƒ_ 9ýI²÷d\®Ìº· †¹±fs9 à*ÑTÑ%ÛƒÏt “Sß÷ žŠáˆæî©ï°|£*`ÎĮɸЫ„+gÒ¸[ßà½wz¾qkžZÞ0"“.m™êƒ‚oðNʃ³\å5Èzc! Ð7Mºà˜¶p|¯ qþÛ¶i(2{¬wC ¹ œà“\)  Ù±Lxà >ÙÄ(Ãt߸ÐÉÿ ϰxEA¾íÒÒ8ЫfŒšg4£fˆã0z¬ù"|´„iòžgáfž¾¨» Ç.§2à§€Dè>Ë€º”•‰4:žº ”ºŒš¥“  ŸâªœU§ ©îÒFlj2”‚éÚS®úžÞ œ°$§«" Ti``ž‰ xÈî®}‹ÖKŠ/Q.ºRh¢æ“X'üb Î4  àI„ŸLÈtW*ЮÚiJF¸¨¹P§>WRzÚ€J– `pjƒ‚Àú˜*uRÜíúW€z§N ‚ü`ç=q9Èè ¨8r â¨Vƒ„Ízv"ì©þï§¢.”QsÂR陵Š|‹†IIrœBçbJ„T ÉßZd ƒZ–6§üž¾ŠxÓöÚYf§¬„ó'IÕHœZÂ"ô«ä Bá…vщe:Iëܦë‚t–B­²÷-аæ-(‹í¨‹©·íehGüîìï©Ãjt(9µ³Ô†¸GøHƒ€¬hvJJ:¸5Z*MvaH½jŸÆû@³·aÞ¿s€†0Cí)3–\ý0ޏ՗2é§qË 3ªLƒ…L›fÏô¨º~$mʸ,×Sg® ƒšÓÙ®øOpNš9O”È“9'ÿÞâ6z&øÎæ&–JãFR€@Xô¤°4cA)èG0s>Ñ|óJ£ý+€a š4 @¾rx€¡âŠÈwb7YŠ)Cçˆ3”޹D@ÇTq °TF̽¦S\3€õJ bä2Mɳ†äÐ~†ž?Çèþ €d² ‡ÊÝÃìN§Qü1 I³u¤Üž¨!þCIëÜ:¤ r‚Ùæ4ŵKN]‘””ª“¦æÉ2Ë'­˜ RR¹×ú]]ƒÒ3H¢>Ë=d\+0'È8'@™PINd¥Â35RàÉHÉ!Ä 'ª×@úc¤õÔ²RzÉÂã7"ç`KB˜ÉŠr{ñ䯣ö@ˆÇ#Éìt¡øgÉë¸bà"u^?ÅÑNšP¢8ó3€78®0 0Ðz£ý®§¿Ëƒ+ jø¸tò8•¨™eˆ“R/ i¿!$(0žÐ§€#ü%’‘¤ËÉc@^$–Ls?H¹¤%†T}©ÔHÀÀ»’ưÀ—2ýÓò¾\ =¥ “/)‡+˸Æ@p*Uª€ñ%t’.©Jq= $O©EÙŒ ãê€JL”žÒ¹Ü †amÜ3ÁþY€Ìã`“+·æü]]Q-€q+±¸|‡ÃÞ4ÀƒrÝÀ›½m UÂTÒX…À-XJòž8N‘|9ƒÝ³²’ šX%"é¨u‘g*iÆ€-ðçÕŽ;IX;@!‹C7SZ¨=Æeœgq8òˆâø¿´2[!P@’šÄˆíÿ7€ƒbB…ú¥ÐL•£óu[³,ÀþF Ë0ÐC4uÖ+’Šè$Èà¸r¨3ºà ù?ÄØAÇ ðz»Ò‚I{ÐM»ô‹u43FÉt×$Š4ïèýE@ €06^Àò!EŒ~NSèÈü}1@>Íàø˜8‘söTQ‡%1Ü–2zcGý˜'¡h€1dAÀ<´Ž+áIÕȾIŽ!=O`0‘jI¦pÿ±OÀž½ê~GÞ4‡”z„2?Tˆ¤ ˜em‰a r{”ægEK€¡)ËK§Ž_^δi˃ï~KŸLšÒ2‘ØtÀpò€Cý)*…£%‰V näY‡ñ•èØs7³¨K€ Œ–äæˆ©³¶&Ù€! RFáðªÎéÜ‘ÿ.®o4³à4¿§ø;KØûßO¶¡kÒn( à©€ lû@º; O}–@<ÐÞIcŽ Yr=þC¸‡Èȯ´hÃËÜ£W5À4ôíj>BИâÐ+ ä? äb.(Âz´’âu|#þ«ùR@J[pÿ k0‹Š¢R«À*†Qµ×3°KJsSøã‡øS3`‹”xŸ¸žŸ¹j1º¬‡°Qðk#„•žÀZb¶¨YB é½”4 1ƒ‡û¥{±hw£zƒ(”ÀóN±¨‹®(”· š%¨“0”§( @¬P{¸vPz2¨(”¤°¸&µû}?H©´P“$˜ž—¸ü+©€ µ©´¹jU‰2dAÑ`†ì£P«‹‚8§%CŠ 24 ˆƒ—`‚ƒ‚°8ˆ+P€LŸ#? Ii+!t†”œ¹`‡áð†¢Zˆº‘€y¹Ñð€ŠZ ˆ–3P¥ŸBˆº•µ2³ˆ»0–8–H‡r•ŽÐÙî‰K¬+aH’CÒ‰a„«b”™°´è–*Ið‡iÜó–€8çZé«`·¯DW+X‹•ÛÑ™“+"ØÅø…·¬½H­Œj¨Á¶‰3P¦ iž@ã2¨1±žj—çq»€ Ç€ƒ`£L¤Ôl»©Oµ ¸#¸ÙÇ1E¸­´€¨È)]€Áz¡ƒp­Ý1s¥ Œ pq–He1æÄ:ÃÐÚ€ Ÿ@ë¨ì ¸xÐ`Œh}‹Ú¸Ý@[罓ô‘Û¶8.IÚ puš·ÿþ©8Ý /èðŽ±Õ ƒ¿@QŸàu’€o H’X"9kÑíGÜŠÊùŸ¨wŽHgH{¾ ¡ùo‚Ø-‡ø8€$Kª´½ˆ}%P}¦„ )øž¦©®‡ü(«Áðœ7hžÀñ<µ0– Œ€©x7øƒp§2h–+P±°§)d‰I©À!nˆ†y²h14=34 aG»˜–'X¥ƒ §¤™šà“@"£«Aƒ‡ð³¢i¡XN*ÁáÁB”–ÄVÁH§2à–+d€H­Â{€2§Œ€¸‚1w5@‡°_Šp«¶Ë‹ƒy=DÁ 45QH*r‹Špç*hxƒ€ªP€JL¥Øƒ‡¨­éH‡Ñ”®8ækª@“™NÏØ–ˆAèÇ3@*6àˆ¢6 c÷†P”¦Ê¨•xjHyˆ°–{cQ¹â #"€2€‹Â‘z©Iy ˆ– a\ŒÂŒˆ8zHgšx7¸”èûQ€‹œäR‰dÆ©™¯ L2¢ð–+J”/8vžàÀ£!´8íKx‹›B2½Gú2H§‡è³pÆ€AvZ<Ÿy‹(ÁìD 4aŸ!·ˆ“‘îLìÔŽÐ-˜¤„—ˆ€žñPŽ>‘F"30 ýÙ¤RøŒ"šKˆ¿ñW‹"öÅ@T U0툀êTÛ=ƒh‰˜ûöˆÌmÑèkº‰Rˆ”$A¸«ñMyZ/pö˜T#ÔפˆÃkÈ£`†L,ðŠ€q¯ü%ºcE_t0 ¾· j¯@ ãþ!MÆ€ R+[ÿ^Û¿íÔÐÍ@"wÑ •ÌT(çqÀJx¿·nGR+•¹‡yÑ8oð¼nó¿ÃF Vt&`¾x¨BÑ ¤S}38éþŲ*j0°˜Ž3*iÌ‘@MÂ"ˆ¨0÷ƒ'Ê*j" ‚jJD}¨yþd£ðêšÙ¯À ê›™¢,pAï86ä€ ÙðŠ€ÍŠ›)Ê$hÆèj"·‰¾‘1@n¦È` Å»¦qºŠƒRZñGx ©°³r¦ªÀH‘J$¼ɪ±þ¶Ÿ0I“/Ó@$À ¤Q‚Ý3ɨ¢ÝdzÚD* P¢è©ÔÛ˜òð¶„-¸B·@3·J"ì¦ŸÊ ¨ŸôØO¯l+ºaЉßN­ÔL˜ŸO Êz„HØÂÊ”ð¦Ôˆ• Kš`’*m#ÀþŒ4Ê%©AjlЩ=s²ìQ GMžz¢cIgí–Y©U€#c$*“ª] HŠˆ)L€GÍXo&`¿B'Ê©4,@¦Ý ›’ˆ Ù¦¶5¾ ª mbÚ*'‘ê¨h@ Ú`J{cFê’j¦ÛJ•>JgZgb6©d ŽŒ…)þdNý:gªÑý‹€íRŸ*¡÷9§ ?@7hhž‘Ii âêjz†­³B?¥)°C€ Þþ– 󾯨š¹þ¼YÊÄ‘(hˆl‘ êùNŠžF«U¸Øé!QÈ`Yƈ©MبI¬¨pkt‚¶o䥤Bâ f$Kò ŠŸŠ‚½ !9*¡/ʚˢ:šÜ•¼¼w: [c ÎGýl0Hiš‘PÚEf×Èo‚ËB?¨©´¸èe¢viJ"¤L›mç)¾?›^*š›à€?€à@"¢ šˆ‡ß$ì9 Ù$J|†žP×€Õdcà"‘÷äÉãÅ&¤5x”ÒH@I¥‰L"ø•ümd‰ÒIuë fg8‰i7èD©’*Îhkè‘CG&¨ÿð´’$†Ê#¶Æ”d b‰!àÄ ¶öÚ[ŒPÿv )§2Q(-#‹4dªÁØZ”€• 2Br €e ¤"šh tézÇ 0÷-f8Š€³n –ÐK,pãOÿ‘ “!¶H”Ø×-c`Š,c& œ(†@Ãn Ó2­…•"˜?ÎèñcãUÖ?䥅cG… ®‰Kë<žqÄSÀí\²´ñó‡ü•w±Bœp̘4( 皇‰~CtîŽFB?8’l¼5¨„ß~ªu®¿Çñ CQiŽå:NPh\à i€ ôÌ•¼2µ©•÷8¨@ â P$Š„~=M,ÁÂDGÚÑG”Ç<üˆøÈ$Nð'Qþßñ"S¤6nžB>úÇø8#ôhW‘ ®ÀCq©é ’R‰Iûôdµ[!ŠDG¥.kÃý®Qò .fG€ºtÌ„šž(•j—”F”C]‚Â! ¬¢B #ãn­SE¸îãG{ZÕ,¦¶þKVN.0Òæã.Ê#–!¢Ä¢Hæøì€ôkC²DW%[ˆhž(’†Iú°kú !«DbESÈkU\IQ­ƒº:S¨ó|„4æ¾’ˆ\ˆj&šv؈ӤºQ½e-Ò½9+p C ñP‚éBÅ k'QòÜì[Ì$JÌW4ÏF¡ Fµ“X}Žá"}ÀÔ—{DWc5÷w0_b2)©< +0:Ï/›Yý5%¤Êe/Ôê¿ }Íёǡ§³ªCÞƉJöD÷iWü’2N÷ÚJbP!ñø&sJPH"T€N9.BE‹18ÿ‘Çus$jêFIç*Ä«1þ7&¤Ü<àŒ÷Wd±¼vI×h·P;ԸÛ£ñ%®Å@ú×>¿  +0F逪S*Jl<ŒRê•ùEz=Û´T³¶ì7/%b•`eçܦ˜B¤ÕGüò_€cbÝ+@ëK ªAþÄÙ ZQJPmÌØ¡pÅ¡„$°½þ <>U ªY1Qsüe+1ì¸À¬ÿ+œ ²LJ”úÙXk°8'“' A{M;ʨHZ!শð?‹Xû äD|¿áùXHjeÚñªa1þrHkrcü’ ÊKEA"¤}&–e€Fèw‰ S›DGÀŸ"£Íå½÷Në¡&Û¹!¯ÀO@ ²†Ë¥´CQ UÃþÓÆSa4@3Nl¢<1ÿˆã£Á.›DãðF€ þ5¢ÜzÈŒb)©hN7FÈŽ®Çð*$Vq½*ò*®À¢³)T"!‰ãâ+Ùs‰xg>áì†HnFRѨ¹8Ýa•Kšr›ä‹w?z®#•aü ˆˆÌÄTw{ÌnQ+a8A ^ñ…*#Þ縘("%vc^ƒz|MÎPb>k1"Lëæî)¢ì*'‚e\n¶l"ˆÞÁþûÀ’*p$A¨*,~6ñ¢Üà÷þ Š@à@Jˆ0"Ià{°$CÂ"#v-ÌŒøg(-Â0?'"#JF†ñŠ6 W®jõqœ>OX⼪.-`>8§jW¤JAV"¡ØDÁÖ€ø“éVí Â>ÀìB(†‚Ü€Áþ~!®–-ÉBƒRœiàh.Ãn€~#ñ0GbD¤Îœ¸AÿP²!«@-` Ià0ù 0'hz"¡ô;¡ 'C¦Ì†rbÇáþ‚šÙÄL§‚£( Ž~˧¦E)ÚçÜh8èDñ„ÎOÊŠ)¤–ÄRçÖgLЏG©¼$I&?!àdaŽèjpN £C‚}`@OÀ:6à vð£â¤KC&åH¨ðªjI'¦[êpV`Y DÀ|Aø‘!ôJáôÍ„Ž½Òô#ë˜ëÁB$O>!ª4oåBO">»âÒç@ "‚ ¤¾áð£O7G"š¬ì<ê!þ@êú$A#ã‚U#ðGnf¸3®R(”?‚ˆA-*fL\­¬ôº-€)®–h$¼çfFHl‘Bþ(Š–!±Š-Ã6žé0(ˆ¤EÆê"(¬èLæ¥NpÎ~xথ*d‹ÅÀ²<‚¦*Ö¸H*Ö¢ôJH Ødg#ëk50ï¥åÃR¢+ÂÜOAþ^""x X}Àx>@2zÂ"±€Ój=*´ÅX®Œ)«ÄÊÉY©^ÏK|a±…6ƒÃBUövÁ¢³æ%UŽ|ÕšÒÄu6"š5ê>)¨DN tÀåž9⢧‚ àt8V #öÓO¨Â›"ä΢ âE["!ä¦éìtòN¡øöAýWOàj#Ž!b›Em48—]u"ký M l£:¡òFtèyÑ$) Ò#õv×RÚ±2)ª´Ç¥nA ø¶Å”ßc×^mËò"*]0RZ!¶* æw¨i!""Fª'âåÀãáÿH# ug&þ?b%Ö Ž’,%« öWWaë]4öë5ÂEBÀtÐ|'–5"Ü‚ˆ¡£¦(…lÆ´B¬J¸ƒ¶!§±IbÜâáÿaÍ,’ò„SDµBù¢**¸ Ü" FV`çòîˆèä!©µXòîò­Ö;¡üWr1â›(B"h` *À65€”!¤\‰`A‚8Gí-Xÿ‹Gè;8TqŽ.´"..jÂDíÀV*8«P¢DÄgîlÈ¢DL$žªT ì ÏLX%öP¥@dä°LãbXÇ–Šö)ÄN46*$Â*Bô9<é>:¦x"¡ÈÏHØ*Jáà›¡ÝPáò꫇­ó„8`1;4¨¥pÞ*³L§4í…vÊQ.Ñ Öñ‡6¦¶›B“k0F®ÄRJâÜ;uîõ=IÀBø0”.R!¯Šñ$N·#Æ4¡ý‹#|< DLˆüØYšAmRâ›`¬ôj¡üŠ‚­ÌÏCƒY´×"¥ØY,Rà>Ràlð"¡¦KÎSYìt½BEaƒ€j)»¨ü5îü‰VRb}»÷¾Äh-I¼AS cÇÄÞ*E.fªCºdtRIV2Xd÷ËdÜzpD=,º\àHäjhp"¡Æ‡Õ²ÑÕ`-ÃJÙâ¤P›…H‘qâpI`t_à”!Äx!ºŸáì7µXcùÜ$EÅÔó˜Ö¶„h‚v¢EinpĬã¬Éæ€-ÂÃon:(ÏF‰sMI ‚Ý Y$AÄIa®Y`7 @6à’¼"dB‰ ÊAàYsþ*;ˆ(–ÿ8$@˜Ø@ a Ø0íh -Q:À‚D"?Wÿ—)‹â?Â(!­Ö³/VÁòzÂ-TfƒL[Ç(õ¹¹¼BZÔaW¡K«qŽ*+žx!ù)Aì_ïPyì$@°#ùj°ÿQ" !­,ܨE¨*l) ´#ádüCXâB"E..)ÝfÏUˆ7iAÛ¡åQ¿ÈîãŠ|ƒ€«Oª_€Qœãx4ç@›'c‚ý„(‰tí/(ÂÚË Ät“v3`&Ñg"BÜ’ îÕ"‰ŸÐ±Èd÷ò¢"…¢¢n”þ´Ãxb¶)¯¤´ß¶"*“.±0I¨j÷D%6f³Q2p¤ü„RîÒÛ¨ݲ$h$D½ß˜–@àµú˜dÎ7²5x²<#’ˆ)¨|ÈÄžúš‚Ö þ)bÖ ð€@tþó„Ї۶Ë€ø@-˾¡Ф ¿ÀøL%Íl‚¡ °´ð‡Áa/xCýí Ãä#pÝþIŸíÐó…i`!0™K戊°«HöôÒ›a‘ÉÃu`d0«V]AŒº[æÒ}¾éoëžÀÿ C-6(üH¥€# E¼ C/¶þB¬‚>°/pLðQ¼«a–; Õÿ}pC•hÕ¢@«=!ŠJ´^ ?oc†–ÔÁu` n h ¥¾¤ÎØÐï“î@*´¦Nl«3aš|oH~ÁQz_8‘ ¡“¨+*­äè8êÝø-®–JšOdëj[Ûäî €h.¥ÎК 걆š0o+ÄŸï˜)aªhË$å“ù‰€u&`äÜŸÍÉþ&…Ú¬³Á©9Î¥ƒO2ƒ °ª b°ñr &€B JXF5 €»Ôšèdv°³i: Â+ 8F†E+  IÇû Š!@†¥‚&2xµg~wH#¾«¨a´ô¡‡Z¢°éþ×,&dá9!’þ@ àšH!Ý9ŸÊÂ̆a„Ê ³êþ“ƒHc&“¡i=¿!ˆˆ¨ Äœ *áIí¡ÿP ©jOR¤àŠ™ ®áþx¡•yÿ  Èaœ‚ÍøR€G„:&“rO9Ÿõx!•jÙq\.Î4l‡JÀ~ØÆâ/‘üØ!.qÿ€JpÆ¡‚ ê):€Ej¢¡ µ€&ÙÞ„VÑüŸ¤è¢:¥`ª†ÑÈa€9ÿs€ØnŸî 𝑻n€Ð0%(MŒ'¨IØš" þ•¬)¢a˜žH!ÏFv`RV ;àB¥€ ¶X&yŠ‚{(!˜G–ˆ!èºé!(€„)þ“èÊ5ú“ç ”‚Q€?èñJOGm(c^$÷êÜ$íÄš ª°‚†е|£hçØ:ãìÇÞдöRò¡ƒ–È h¯,5>Ð7‰;>À òÃ'±0ãÉŠÃJo ¶öºK þ ´ò“ðݾê«`à$me° J±žšjë½Ç"ࢬ7Jþ°Î¼ÂK¦ý`ÃÜHä9¨¶Ã˜ˆa‘»&’Åb¥Ü@J‹ :÷Œ*×õ“b–0 <ù‚NýÈV$qô RÑ96€µš #×*Hu,ð=O ¯*ÉÎÃ,ââéÔA¦aÎ ô[ Ø„b9€–Qþ–Þ¹'9ÃùÉ’q€U™q'0lp†? L ‘ðµ!„˜~©ÑÚ…Ç" D ¹öÅ4jÕQ Vå„Aü4cáŒdm*‚Ayìy“×F¶›A'‚cý¨v‰£Gæ‘Y–(ÈðŸ'‡`b•¸EɉkBþ6 ¤“ˆcý³÷AJSg‘Cý£ ÂN¶C{æ nƒÄGHIøîÙY€¨–I¢F'LįXþ?Ðè'ñ'¢:è„x$à&™ŠI’€šÖnM˜0¤ifMXÿ'à%±Î‡Fë(å4‚°“é I8·@*6žb°¢hœYŠ­0vOÐ=€RÍ1ìÅ‹’f4NàÔñ!ëõoHš­Àé,ãýK‚ÚÈt€…¢ÌUXä5 ‰ÎC̱ Wtš æ[þz¥…®éºèa†8´G4vP˜ÿM…¹Ñÿ7I:Eƒü0a’C¡‡šµ4ªÑúçGÚRu(L~©ÿ 2âàÞ«ššýHa ,2œòÃÌñKG#õçĘ=êhü˜5Е:¦U•<,"F'Ê—–¹V‰¤„'ð^è ¤É1ã ɪuN%†Ø`–C$À£*ÖH‚–CEk.]„˜†G,/ %*ÊbA€H®ÓaKD1Œ©FV“-´Ò6`  X$Ñu°*ŠÅ©‡‹ÄžHTRÞ$Õ‰dÔ¥É;AY•ü|±•µ ÀêÆ’5šq‚aá3*™kH¥ƒh6H P x(°BÛ=hYqœ°«ã 2ÇýhŸ¬È¥‚@šA¥ß‚3 ˜1öHÀçäsU>"[~v–$°ž‚N/Ôz›0“Tõ) †:RCêeŽy&8¥ø˜2þÉÈ›)ÇúÂRrb–Ûe1J-½ŽIŠG sÅ.@¨CIÛlëÆˆÊBO.UÜ“Ó,7±öÁÇ#Õ#ze”úLJü X©Ü¾M0ÿ»à“©Ðn]@tVÄÈ€!À±‡æ$æS(PM y@UðƒSrÌHz¹‚ºY£h8`ß^#á#3`8¬Á„“,]kSd˜)˜ÿË5ɇÄþ‡D+œ¾ÎJš¢À@¿¶b×ázpf/±øŽÈ) ÚtG5 X:€¢ ,:væÐx¤Ñ”8pA‘EÂÆÞW˜Ð w*Æ€“‹3­ ³ ø¥ºIjZˆ`Y*Àü†3›‹ ll›ÕÑ¿Âà„ÇÒ5a…£œe…~eÂN¢æWÆC Ùa‚`-kIêÙKC£îËs=׊æ*ѲÜSâ' ˶åcþ®â¼caucþX,JX tƒê<Tûh±e_!H«*×aâm='‰ð®•iB¢òìuÀñçÐ^K—ftÕr—Ôˆ.~'PaWŽbê?­yW €§\RÀyÎH0––z”9q‡«dB\ŸH+³àÀòm¡ðá‡YÎÆ #ÈÁ‡áÛ¡­âÏ °³ó_Àéw‰8îA ‡‹8y’`o4àrÙ¤ 0qT¶5ê{8´§¯ˆµ€}“›ˆ@~” “ ¦À?Ô!‡ûg§Œ"p‰›$‚pˆJ[‰Â@•x™p1€i ðáú˜§Ñ[€;€zªäóä°£"hRŒª42x†áÄ  zˆdX/(: ³¥p°¥¤Y ß§ÙáÅÀ«3òÔ*#‡àÐ ¹- «?0¨ âEƒ/ ¨¥²à¸½  ÉƆ1}8{2x|”Àx«?a„ ³,» p1k䈆9æˆd€0‹({ {“=вÄø)г¡ ¤kê 9û!1>aJŠq-™£€‘›úõˆ(mˆb@‡a9‡ÄR&Ä \ Ú»"Ü1m²EaG€1 Hv‰Àm v•˜E“Ì Ù@AŒ§e¬Ã0ˆJw³A Ùli†ÛizICu¼Ò'ƒgÈŸ C;0†®Cö—8–Ä™@Å  ¼‰‰‰0xD eè|§('³K‰<4¹I-y¡¨Ñ›JJ4P48€—=2›S­È8£¨°„Ò4:“““ø£ l7а½­x„+ ‚#†Š°=ˆc{¥0š•"ÈRÊc“£‡ñü40[´t‹‡ó£€)ù%(x“¬²B8«;б°º;] ²7‚ñÅCH {LØò¸€“¤å<•І ò°Í“Ñ๣T–•ü¨!H{Ðyˆì¨²S;ȆË® e®EB3@žè΂҈Հ I€ZJ€q9€0Ûç8“…U4ùcXå‡rN Œ¬Ø“ÑÂI¨Ù 8’p%ºÆøN‰¢~ËB$H‚­(G°‚¤¯*2Ѹ8v±Ø‚K:¹!°$ùN³  ¹)ˆŒnˆ*òŸ:ò MàÝ%¢´-xX 4c°+Bý;§Ô<ád#¡Hvèr:8zO#ØÕ• ÎÀ ªŠDÜ+‰á‡R~‡I‡¢) :§°õjSX“¤ý# üIÄ£b?‡èüI½†ú‡¡Š¢q zØ–X“ü±€4b}À~“œˆ$"ˆ y“¨ü.ГÎo°Õ€h |44^³ Ô™Ê™†ðç”+§è6˜ y–=¢B(©¥3½„áð‡r†€Q€Z™€ˆ;©˜Tì dºˆ)C‘mBfÄÒψ §ø°#ü–ˆI,D k(Ðoš™È››[Ö‰P„KnÉ@‡[e•¡8ƒà¹[ž 8/ ²wðý*+ÓŠ²J–b4* âÔè«YÈ=8õ æØc‹ \Áé%®°«& î‡õM‡ââ€}9šÂ ¡R¥ÂÌ+•¤¡= =ˆ(2Š°Ù :ð݆?…!B­ï°˜š_I ‡Á*²°-£óÒ°°”¯$À`Z; ˆ-òÃ,@~‘è¡¶ ÚàS ²_¼ °¦ ß*„‰9õ TbH ä-ŽV0€rI€iáú8”Ù‡ñmJׇ’_Éh“œ˜°±•aŒ>“ꦀ"I€ €€/œ²·bDŠˆš<æˆ,Œ@†U™(ál‡J‰Á §p ŒHV±ú"mYãxbu©XôÉZùŠ^ ŒRS'ò©2Úá€ËÊ¿Hf%£2³° ýØp˲às;úﺶN ,:x p*òÀ Ê€)bjEWX¦€r‹;9Œº´$ùM?0³€1Ø¡I0"q6š#P“•9@凣‡$ ‡Í"ëó ¨½€Š‘@Žêkˆaúfˆš˜|†ˆ„Mpp¸|âK¥$ ΀—¨(êQÊŠ›ˆdÑIÙÚwÊÌ n®‡Ùq€çÈÓ™v”Ѭ€ò/»øˆxà•ª‹8n'ø—(³º-vèÓgģ钕’Øi´â8 tóÉX€Ø(Oð„¡†Põ Ôú4Àùˆ{pP-)‰Ø  ¬°$E µ€!·Š)Ÿˆ`* ÍøBa0«], ÊBê~‡ò¬8†0£ð‚j›¸€©ØÉb.IP“¹3 >D´0îãÄ(º“P£3ò.C*8¬´>‰¦±O“…XÃ!ë‡û„#ÃÞc­ }ýþŠJóº8{¸| 2¼jð“‚x¼–HÆhèÓÈ!1Ü5á—ˆaæP,òž ™[,‡ò¥áIeíM"«Ö”L$w9P« !W€:µsÄË Ò€ºÃ˜‚Bž‡¼ø´3 °^‰¦H‹ë &ß;Œ—»qYµ˜ :ˆ9"é ÷/š } ¹ƒ‡뇵EûË€I€¤[9€uÛxìð‚ŸÑŒ¤©oh“Ó‘ Š^ïç‚•xWðÆHË ׉u#«4#a\Õ@‘N¦ â0z"Xrž¸u Ð~Hà€@I’Íxš?0® ²ûÊ«“Èê©™W‡ðùê\´%¸€ù{øÁ¶ö{wK²ÕZã²Ð߇A®‡êŽ‘˜“ÌJšèÊ:°ygNJI¸š¨„ùð‡BéZ”À¶Ð³&HgÊ‚!\†<‘½‡üñ©’¸‚xÄÕ`‡¿„Úûp€šsOBÀ‚§èy¨c™(™€ h –ÀÃsý6$¯Q[m*È„‰fÄqhˆ„º8§™Ø h™`m”mµÝYØ¿ˆN„¤æ/ À` D¸x07¡lñÞ “ô‹Ä†N£P¥øE³²Û¼“¨AG Â.(°€“T= qEø«X±%7‡öÖ‡íg‹²ÝA¡rÅ;A£ÆÉH‰Î2àƒ¥€Â-/Ê8†wB[»êDxPH˜°8°„Îëgr0|‘{À}Ð#<бG.ð¥€9ÈkmXä>Å#x6Œ9 Œ °Àü™ÒÆÃ¤ÿ+%šû¡ kFŸtŽŽ´làÔØ9ÌóPwÙ³(à㥡½€ä‹XM7‹ s–]*2Šà  Ùù’€Q¼€ #(ž€vd“KŠYV‡ÌãŽX|dH‚°‡&Ò”è 0H~1ûÇ‘ ¢Úü­“®¸€a8/¼í X 8ð‚-ErøªòBLÙ0–ª»èˆaSÒ6ˉˆ w”q²Èx¶AWa€%"EŒ£í‹ë^¢Ýo˜îs'‡ -‡z&¢8”°X 0`šY{F¤šX@šY/t®iB¤o“˜w~±l5¨‚r@˜n¯‰¥mWì*O ­ÉmšI‡jF†èÞwøäà`'” û¿Á  Ã\° D4%A€/öÌ6*xG€‚€1Å x€ÑÀä²€&À'øô†ƒ"𜠢߈9^ð0&ÄnxJ[5ÏâsWär³Œ€œ.hVºÿ ž÷d*}R¤ŒC5]1](ô G¶hàR9<‚£–Ø‹vŠ€…Ó ì …øù"lÿ!æÏPÖ®lKóní%˜Òhõzhø~lþ(fÑÚ8K Ôj܉­:‘¦ÕÂs;=ƒñc6}àoÝëýà ࿄PÛn­ß æÇP0"¦lˆ€@]+‚ÿv3|`'6õ†±&À ô¢äõlö@ ðìžË(}‡lÙ†ª ìmB>‹¦Éª>¦¦Áz3dBÉ­šžÎØyª õ âûî#å£7µX6†Ä'üH°Èø–û–hj2€1 t gÄ(|¬­XH††LÙ*†¡‰¬–‡!®Ú>u>Ẕ#æsNƒh² º°Hø€û“ÈSèšÍ \B|Kz} hQ¬Ü!«:l´¼ÐœÎ›bRˆS¦¾à*µ!GÒ 5e‚¿ mà´ b \ŠPÀsú4#òz>k³j™þ³¸(jšÃùŠÍÖȪ~( Õ\©xsM£ïÉþ!¦Â¿£ðYþê:j3f2X(ñÐãz›H4«„¨ðãöÂh-èý´øZ(Â[6 ŒsÁg âz«`ìvÕhý¤š›’½è#Wõ’j¶°¨Uœ}ѧ3rD!Zª®rjÑÈV4ö!Xz#B`U+£•£o¿ç¶€h€M`ÒˆÇgúõ3#–¢>S(Ö fkÒŸ©âqH€ &~ƒH`^àZˆ¿ˆþÊ/±DÆ™+ú«€ ’q, š#hKZ2 UÀÜÆÐÆÓ'£¢9úq{€€Á-ˆ<Œ‹ 2ˆ€„ ,Ìä 7ÌÙ¼†®íZ2ÝÈj^Ý"òËggä6‘ŸÍ»WªŸîstÑ£ýiÿ ûhÞ!ê4&ÇéA`–Þ]~É­]‘à¶tÿà;¨øÈÍ™ !I ªà+®ÊY…èšl¡£+6O¡UëV«ŸéBmê¬ \ eð3“aî^‡¸3kX>À{]ù÷,}@ójMRiçÝ×£ƒîý…\z-aꉰüDÉúÔi ZF¬Ö$(ŒÚ*…à<«€ØV<‰jñ ¡rfàxÿUf¬òõrDŒØ,!¨ÈerbGß²F"F I°‚ä}³¢SîyGª5#‰”°x}Î\,#àj»j·(TPÃL¨¡àéÇúq#„ÖÖM…i aqýµGŠ@ÇE(€ rlÂi 'ü•±þêÈü'5lYû6ÓXGÞA6„5®÷°½Çû1¢M€z‚r± j}#î:$µ#V¬øÁC§P†¦±ðußCU°<¡@šÇúÎ2„6S‘õø°Ò³h!RÌË™¸¸]m0y!@\³€fܳÕ5HTóÄÌ‚"üälrh=( W`°‡ú¥üSžkpvó*Tšk£ÌÆŒ„(ÐˈņJœï!¤Ü+•€MJ&ƒñ\ŒÇ;I}!T€@ðá€óR u€Z$%I£+Ôtj’"l"1YÃO’?Kf¹5:à( R‡›†J6QþÐÉYoŸF0V@0# C"*?Òá«51š¶?Çé›aä|ú¦´´M}5ä457äGËùº“F(Õ­ÁüPkÑ °ÃúG€œ„ÞA•,Û ?‹y«[¼•±üéM\œá¼ÍÈP?Ž™«t²ü› ° …€%}&¦¨Ã>LØ«0~à/Sˆ?â|>òˆ6™±†@ÇÜV6øó(M%i &1 †¨‚l¯Hüx&ÑšçeÄÙa›[À|…Rl=‰ÍœôhCJÉ«%d|†°²B¥Jà¿ÉH}T'å†TxµÑé'‡ôü+mÍÉ¢ já!]dÔû¹4ÑËëË!«ÜŸ$Ì+ MmXû¶qèVÇ!¡tÍ‹â@ Á›bJ¸û‘ðrfÑøT0 §0o€ Ä('Ÿw¾Mnâ'ƒÇÝ ŽÌ†X! Yd~Ãdð U¸€CÁñ#ôøÊVfÅÁ nVßò¦?Žø÷},04Ó€£ Ù@Áÿ“šq«££ÿBó¾Mt{ xd+Hç $^ðøúm ;BRÍ\x&²‹H²€–Çü¾Òä×H¤†ˆûLe¤½ˆñŽÇkT†èJRCQØ{ [ ÷¶­© c½ ´W¸<  <–ò#72q°žuG““H‚Æ{k2œˆÛèp@Á’@Yמ| ˆâ¿ØU°r²¤úŒ@ÿ­.”œ!ìÄ*¸ …`X활>ŠØÉ" yÊž|×"4ª¥ljnG lp `pƒ!ÄaK«Á‘ö½˜‰?% © "-sƒ/„ÕÍ fÏi«°qáñü°ýïÁ¸Í¡1þMž–ƒ£ùHšµüÃÍÖ‘ƒ£ýßàÀ„ò(¦ê)ΣSmôÕ öÖ?ŒÖm#â@͵¡ü`º‘ µœ€4jD 6¦¯pY&I÷_ב€îкqï*käðÊòkÑ© 'ÜQåãïM[[‘t$4•“m6?ð— +Xyú‘óMS™@!·rññzCU¶HF ŸÂ;Mf¾VÏavM‡#ö š´â?ç’,5c4†¡áÿæ·›3sR÷€RB“y+`Ia€¯¢<™ ÖÁlͨ¸M~â2fsq=“h†GüÓ+¤¤M„RÀÅ‚j?&”°îžÜ—aÀF芰!þ££Vï$+`¬H RJm^Ù%°Ã6˜Ï"¤â©‰¸‡à¬Š¶&4 Ès"«š~‰ºŸ¢[þbÉD¢ Èï´àEv„ú¦c@[€:KÖ€eEþ#îKþWoºªûFìT¨À!¦P¸B¦ÅvÊþSb>q@»Šƒ'¥†ìX$BYb dvƒ @G`cO!¡ž#ŒòØ©™¯xã‚ÃþFºÊÀåà@€*+`@1  qÑÑî&?!ôMa’O® Ò'2låj#…\pB£¶º&Îà "/(ãP"*ÁJÆN8Jlž@Dà`)@E\Nà iÂ"fjÄ¥ '€ !FsÁ†£6Fêòï4Î#DFÃ7„3ãt¢VCVm¡üõ!þ<¡üucVZE‚ã6{¢ly¤„”âlj¡ûÁø‚«ò6iD=#W„87K¦#è†5qWÁü]ž3g°ø@ŒÀblˆ¾AŽ3n+Áþ™þÁiT!HŠïáþÍBjtct…iž&Ê)zãòåDdrti´!OzžCÖ?ò\>ð¾{"ðh¦äòvPAæžö=oÂúÁÿ aþi„ferl6í‘ ò ² ò¥¬J:#‚kÐvNÚè ±‚ïp¨å­&lµÀ~!©Œ5ilZȨ„EœÓ5dÞ&¯´J¥á0äõ \>¦£z!Ía &§òò’!Ffö¤vå\ %ÂlÎ Š}GãðœQ :å~èä&®t‰0®^RV’ i|j:ÅäB`UÀ*® 1 :›„¼né{â?’^õov!´ÐÌYÀ/@0W 4—À¤§dbIý0V^nZ#í½0 :éÈÂôFÖL>ƒéühêËîv"0„­0?Ì‚iÈÉìckö§è\â‚ÂÖnjð!F*Ø$§ÔÕJ» 4ƒ`ÆJ‘èÆð€â<ø"/¦¡Í´Ù%ê-aþlà 18ò€,Dá«Áæ~Ê®qâv'çr dM  `,o`_@@ô¢AÊJaÆ"c$.âpŸÊ¢K@ asÁ,F"ÃaþzqÎ#ñê{îó¡þÇ À#àø3d¦Ã]ãt¿ñz6fO&4Èì&ËnB fšì¶dH‚ô…Ð7GíTþ#fqÒ5d\òЮ)CW%¢t5r6Àp)&ÈÚënûc6~ÊY|\"Cï‰R*  N 6â HJyâkQc'U"„‚éJNÄâãÈþúƒú ¸€s6-iä7*ˆ aá&¡ÀcAú“Ê¥[†×Wâñ£W4í`]‰v $z ŒãÀ—aÿ"Šl#ïKb)EVÀ ÀÆŽ‰1æ¿¡þ…i€.·À*–˸[ hãBÔã7EÉR³ Q¡Êuá¹EÈ’Ó`Y4c.¡€_ŠTΠ!P>‰)ÜbÉÀª£ÊMG`e@8¡€0< ÎbjÒÎ+EÔ<¸V/ÍžJa›*–P¤¤°"è£þE­q ŽeÆ#„<¡²YÁ¿ Jú'4¥F0Ÿ CÊ«Þmp“·ÁîZ@#Œ7,z' TžvŸb‘ö""®JŒ’r¢AøvF± b+}[®&#äš2%¬Ê$éüUw²]%"äJZİb‚r`  l®k ô\ V•ŒJëÐR3ií$cVÇB?0΃e£ui ¾Ô\êü CW4¢>#7_„„yâmEÉ„¹…&6jÿƒèJa¡úãg>Õp7Pzìx 6pý#6½å‡ƒ6^àî€ $8"À!ÿjøˆ&ÏBW‚l$¦ÅœEËUN˜2†Tò»73e5˜#&jº#Wd3º5joL5iüãÁð½âø !46e I`¡€"Q lñ‹ƒWe†R!Xv‘‚!îJaàïáìí H @¡€&­‡Š a®aaÀb€e¯KºJcbj%pâ®RĦnd(‚tpHè¸D¢9­ú/@$l`k 1ªr#„‚šAÞPAÂá!Ø0@ à ®t]To¢ÏM~5jj|®Ô! ™BtW“©¹WÌxѵ`4‹(éX¼AýcÄ&Æ“WÎ̦µƒ´ƒ6z ê„°¨øÏnîéN®XaýWÉ5ŒAþ¡ü…ä¸'^ãÆ‚Vb³¡þÃ6H!ïºAíÏF¹»,[Vjëê—"$YÀ8À¶­“/¯:ñk òúS[¥UsR3`¸=ÄE\èj¯f&À@€¾£6^FõÐ!»¥CæVNRž4˜÷N€"¶j[äcã;áþìÃàFE€J|˜ü"d¦Æ´åÅ\¨ÜH5o–#íU¾×¶ñ1yX€S>ãƒ+(ƒ`¤ò~>çdÛÍ,± ³b?Afä^JòÈ M Å` ƒþ£s©Få`„væ˜k¥pv#ö圗¾B`œ€"* '¶H¿¬œÜ»©¼&·¢eA¢6òe«JïW3iº$Bd<h*‰ÀwbFï´?à,"®dBo´ÑNtÖDB¾ˆ¦Éf@% hçdBƒòõ1Aw…)Âk)¤°FÎê ê@¤½ÃÚ†9ä(åJAÛ>ÈüÒÑMf&yj2+nÂ=Ø"ä!–iôñ'$æµ–|('ï) Â~—7Ü9ÀÆÎ¢Ö(Ì'&ÚQ*JÛU„HG*Q–rˆn@§B‡B^Á Šç{rÜB?=øèùâþC7É‚>¸Õ4ÜK[[ãWáã7VAý“ð4èh#ûagÂ>’Blhèøƒ6# kä5dÖÑÚ¥¸ƒ\Äw¹Hˆ!¾JžÜÑ"Pƒt_Ôóæ4ê&µ˜6®¶ vcfBì|¡òhä´5síb,ÎèÖ#á6uY•£­•^ :^½e"â>Å‚lˆ¾à_•¶i'Ô CïvbúGaëªòˆ’…íWNÏÈQåp>æ%ÞÜÙ 7N÷£¡å.è¥C 5m&ô¼ÅR†TIfÄ ]ÍæÀÿ~*9ä ã‚èÌp„ˆ3"!IXñmd{ ¹R@›õª"‹¤(©v66*ù‰‘Áù̸"d!þ>,u.468Ñc‚h ‹6šwÀ)0†ääN'SQ‹fÒÏVvHŠ}O¹sã:’ªç^£žkÐü`‚Ç@䃿°±”-‘ xÂà`øRÁÃ-è㞊¿Âpp†é…¸ îÈP¨ƒ¿„r¸[¢M#™E…0p#N‰€CqP4b"ŸôSÚÄwà M,‹T"Ò(P–ÿ­?è`ZàpM Ô€ xUaårRÎØX"¬ánÈ”˜!aIœ»° ñ `ïÄÚë°½äÁûý` ~RÀ‰3–ÎQm®88ÍáKÞ/¬` Æê¹<éopt›SXÂ䵇¬  €’­bý ƒS²m—0Ißñi@«¸!u.ÆÞ-JìWŸãÞÖ2,í_;÷ûµ©‹mû¨´+±¦‹»CÉ™H€ K°î"È›°æ¼.Ò°‹;ŽÃX®Ñ²…—îÓàŸËˆ~гÄ=Ðqþ}¦c۴ǢŤ.™¶ŽÄ<‹ÓÜp gðƒ€Cò8 C‘¨{ÅÇÚùÆh[ ‹ ®Ò*".Áþ›;2, `, ÈH«ä–°<…¿ LߢÑ¢ÂäN!fõC3B€ÐÊ â¢ð#´ý áþÏ `ìÓ… 4J‹BÈHì€'Ë L yË ú1À&Še;TùþÝ¡J( %à„¾¨Y[ƒ(£>ŸIÞÑ'ˆÂŸ¥ºMŸì{Æ“H\ò‡ ‹Jˆµt—»G2$ . ç…Nö±ú!GÊòí?ˆQ®…›I5פÀÂ.Y—> àøbƒŠbJ!- ðæzµ‡ø/H"Ðb™šHX-%"Í’,0È8k^è8&É*d &s¸nÈ9ђĈXYˆŸë²-˜Ò˜¢ynj ’ Ò€À†i6V{ä¦s7MX'øZ…çȶngVr-Œ"×H›ƒ” /¨dÏ} çÛ’g/ä”"ÎL©¡iª±Æ£9/gê¹ ºv}Ç—/žæêM/ŸúÉþ³¢-J3¨Zz¬?GùÜ“/@jr»d«3*ÆÊ‹7 ‹jà(¦Sü’׃öØ*JżÓ益ØU§:Þ~+@DÆHSh®H@Û«¶î¬9ªÅm€Ä  êŸû+±LdVV¢í{güÄ‹DîÁ|…’±BWŸöÇrí^NÆuö戰ÎíHYFí^ýKë"ÏÈ´Áþ³ŽÄiä,  þBߪP#øn36‡ÀüWGaÎ𮄉 2Gaÿ=ð?œ9‚£þ²!üOH°7;B ŒšÀGÊŸ¤xì@F }HX];KQ(¨6÷‘Hÿ#ÄY½ƒ@(p `!…Äál€[Ù#aˆ¨Žƒ€[á¼í œBÐpüŠã¼’€óÀ:”a €qšI¡ÓŠ$Ñ–,Sx€BÁ H`*†\BœkX€átŽðÄ@ǼSÌée€!@¡8‡§Œ ÚiŽœ“Ó±Ïöƒ v‹=Oþ’f€‹HVv%Hÿr“KCèÎÀIàê=ƒ¿ =€ê)Î#’±›¡ ]k¨í.˜JBÛh,X‰¨µ€ !ƒ…PÈ@ÀsDà‹%ìžÇú\âäí-aü’ ! „fЋ2±þ’i2mJÕ$BˆˆÉ|o·´BÜKDrÔ2hòâE˜Ø)Òˆ€çH\ÀêØ…áü°F›¤Űɱþ5M $Ç,°aþÔ‡û¨l„šÀ>¬‹`X#qJÞ5‹¹œuý¢O ,‡úÐ'`ŒžAÀ„… ät§ÈaJcoyéÄ•Àòý?žü½3&L°A,+÷P;èþ’ì“"˜žä¡Ý3‹`¢fVì"ͪ¿¡—;Í ß. wN©êgð *+€‚õSI1ž)‹b²€%A¢Tè Âvîv ©“þ}ðvvŸ ÿ“ça@ÖráÎÁ#*§b¤èBÂaÚœ§`O²€v-bö¼8Ó±J£ºÐ†GaVñ,„ÕÙØnn0íR£àê —$~ÛSÒ«Ìë;M¶ñBZTˆëÿhÚ¤‰Ô À)ø|ÉùJ£Øÿ¼!Üí ’gÎÁc$i¢á»UDÃ’䄨Óäܲ › ›NÄ!N,ÑFÃä<àû=Í´†X¢+ˆ8 _€Ä‘cIPŒe!J”ì5 N.©&]6´>ö²?‚Y‚dÆœ‘óGúÁ'È ÌÀØ@0"ÊÓùÕ’¡¢<ДLqå4Gt= ¡ÑBMÎÀ¼!j´g7@?Ö°µà|0 .XÑ3LnpvÕý€§"ÈaX¥ œå¢á!QÕlæÛÕh•!Ö \p»—Ï$Ì'¨êéH]néé™±’vµ$ì ´`’š+KÀƒÙ¹ 3Ì…ìV‰AGú"Î’ñ2d`°˜Ý6ŽP7Ûµòյޗ¤?ϰÿÄ-4âvÈÀ«ðŬ>ÖÐnc÷2Ôâ+F‡ù¯î?=«¶8I•YÉdLƲ>õÔúœ·€ ËE@аÆp‹(Ê®¡ªŸI ~¥@:Øâ3Êm—_ŽX¾ò„Ý€ >“+Ò7"—Ó8W‡áJä¬ÜqY‘æŒ~@…V‚5îV3Ÿ+âä˜Á€q.íAèU“L…­»´v´ §iôa(‚ÈYië³s­£ÉÚ¹ 'j›e#±<hÿv}㶪ÅÝùHÿ 'hP”væ`ÿ̦&™ê“±EGöB°œ~*˜Jk÷‡%V%uƒwnˆ[ø„¢á%‘UZ¦`ccôĦæ>”hý…Þ,‹ôlÕÔgZgjûž!þ ÈZá„¢…¢ž“ùH™€ ›óŠ@ÂÙ Œyœ‘þfWÓÆ<¥t$òØNÄU 6€œŒ¨øúÓ¼“n[Ž@ßá4wg¢U‘ÈR…ŒGa€ø†ï‘òa«Î€[•AÓ ð3鱤8$kï•à‡Ù‡,p«pÿ.P“6“Û ™(ø0€3tˆR¹@p…’0—‡jqvš`}¶Éã˜Ë%ˆZ†Ø•Áj—±vRâøµ= ."ãÂPû8»Àó³<ʆ#墸´¯{æ𭦱š¸Ðx¸| øì/¸$ œ/™‰Er‘-’]Clˆ²‚€)V€ÁÇ”ƒ†À—‡ë¬€ˆ\9 1Ž¥š3YU–ÈYt€)€±O‡qÁ¡€²$­à‹H)¡EœˆÜ‡øò@ŠÙ«¸ (›_‡"C‡Ñ‡à‚ B€†+ñ;Ša6¸Ð‰S…©QJÉG€r q’ùíŠal§RQ b&€@ø¡€PòجFŠÈ²º˜ŠX|+rKøŠÁ ˆ·€bš1Ûøæ€8L€rÔ(¨¨õD[ˆ['ŽÃö‡øR’ªâˆ±G±|ÒZ#¼‚AH‹ í.YÒÙ®¡âˆY»­\Фø3ÔMûÁŽÃb‘’BZ;ÅòØÂ8‹ ì;a±È~@~ ²¥¢ò‡ù6‡òØÁ ’pì i °p–É© ˆ[I0Ø~ Ø|°¹²)PM³S¥êwH±d­Ú?™á …PíDâÝH”xΖ°Г˜ì<ÌC²]z‘Hy°Ážà…­¨ìPûˆ\º*B€Z=€A–ø…¿ÈB¯z6ÔË ÅÁE³²O6X“¸|Ðz&ˆ’Ë‹‚9̈[ ˆhº‰ÿ’x…hà°b,+Ð…à{ w@yùb–8…†ˆ±FÁâ'€5(è…8“Aqÿ-øì%Xƒ‡³”‡bfŠB‡éÙš©BX) ±‡ù&N¨‹3Ñï/` ¿Ø‘0*±[Csy‚ ƒ€]°£TÊ0Q°‡üøKÒDÉç¶‘¹€ª± ΑkkÔáǪ|ŠˆY¶3i­H…¥¡˜»ùûX€Ik)’‡ˆÖëR¸Ý!“D+sËYç™‰Õ ° ¾¤å€u5ø~š#’/0…›²§*ˆ‘œX  Ä›á.*—A+‡ÞQ¶‡áÈ’›Ø¬\ZËXô˜€ð—*Q¤BŽK6ŠXq@u¸~)p¬(™$ã&!Ì a¬€Ož!ZP¤ Þ““Œ =0ƒ¾º1uŠ`̈€ÓcGøþõí°ù ‡¢ÈküÃ`ESqÄT-{DQX|*%ŸÑRT@QÄ1Y *G ‡Á¢P ¼V uÅOÑ4UyÅfïù\;žÁ§ïöìT«!ET‘TV~Ó_ÈKö?š¿ÛÐ×ñ^ 2ŠªâèhªS_á¨H£¹ÅOP—ÚúùrÂ_’ úïLІcÑÜT™ 5b¬ø€VioÅi íâža U 4Ò¨EsÀœÕêàÑDRW[ µÁ¥p«8fŸ‚ß0Ð9‚ ¨×LêW×Uÿ® _EQQÝõ|v".òqÂAÝ@7\Ö¾ãþ *úŠˆµÃ¨‚[\}5À’*ì¡(B º' ´„ŲzlúĠθ/€:(=E“\úð°¯°t×<(1Œ„ž`zu¿Käv"°âŒ Ð‹êù ì,‰h  €!Ȇ€1ëêë¡1  èhP¡ ¡àŠ(¬}1­Ú h¢®¬*ŠÈª¢;hIh†„*h&÷'„Lr¤ç‹pƒHè4à‚¨ŠÃ'ùŽ—"²qÿ Á*+A¾®K>€ –œaxˆ¨ŠË”;\"¦j*éôëêòpi¢±Ð.‹9á<œR!ßOsN™P½G@ƒH‡ü(û5?@ ª±°AÜ!§W_QÿIŸç‹\ýU<öœ-–n! @ñ Éœþk­±Ú€G ¢wÄ}|¬BCe€hhÑ€÷ÜÄ]sýw+¾§=ö-ˆxÛÖs–.®Ïà(“•EˆOk¢1âš ." j g" ÿ?¡Vþ÷!PBÔˆf‡øŽŠŽNŠ”H‚‘¡S* væ3ò!E!Aâ*(¢Ê*Í!A4Ȉi«B…OúAþÉ Âò a¢¥*!fÔºâ*p±O«Ê3 ø¶Ì¨©`¾Ù $Êzéþê¡[‘þý!Aƒ\%¢ÚÙ,€Õš}iG昅Dª"£k0­ Æ !ÃT6þðLJx׈H W])¸¢±º9ä¡'¾JˆqH3ȘT$¢"¼2ž†»`! YºÑâûݾ±îj× ˆ„Öú«¨7 ¾€'Ø6†[ùõæ eбXüoª^úßHT²ú¬çøº¾— wº?Þé}!Hd@K(š!£ÄÆó$Ëóëé ˜À8ö@0ÇÕ‚¿B*1õ$UºS BQ ­w–qØ‹€ø?‡Ô¹aèkŸÊ!,0¬0’ d¼„Á@Έ ¦Ì,0NµÀ b£þ>þeLlSŠi]°b*6hH€z4qø_$hI,ÀhÊgH¨6QdV $ ‰‡ü# ʰƒ=ÓJA&‹\Ž—Ö9]¡5Žæº$øÁRÑ$& à ëÐ¬Ñøf€çD5Õë!9îÐÊ5Ú¯€-"¨€¤€h”’ ée?± -Gágì8ŽF<‡ª¤UHŠ€úª(%>€u'ô~ D–Ô}ºQΕÀä—ÃÖf ôH¹…Wh ¨Z‡Öl'õ‹ Óú¸Ÿµ°ŽäL‰XE¬ à.uÇû÷묅)bÙú !RXŠ ¿Gû!Nª„ª2! hÉ¡D´…†ÒDñ O4t…*FèB¥ñó¥T9´A„é""¥v–´ò*Ä)U;"X@Š}] …#ýMªAPúyÅTÈAú LÃj1££Â S@ – ÔicæL?ÞÉÍÐç.?`ë’!#åÚ8ïÃY˜DVZÖVsOÛY¬ŠuŸ€ü$h6`"4(=_¨ù¦-°)àA›Ù ®£ýPY©ÜEbàÿŽDŸ©^B@QôT¤Y²NûÈŬCüS×ãHHLÄ,TuÑ¡ôÙ¤‚© 2WÙæž9x’'Ô—ÒbAˆéõžcýë j f/¢ä×7>ŠH Žõú€?€ÑbkŸÊ!I)šç{%H…äÜ aòµ"9W#´jÑøúïëN€fº\€tˆã`f€²\¢ @\-æËNã+ñ°I£û.?Í(þºu-Þ²«¨%ž`¥£ûÖ>É  „t‘öŠmŠhÔ¼€IËÙO .‚´R͘ÿ—#áhfº9ÑLÁ"¶Îï:ƒÁ–èñõgMt©09¯Ù¹#ܺ!Ë/‡;dqÖòA<À}Hc¦_w W-@KF39}¡aïžG+r·D}”ÿŽH6@So¤Š b˜€,<`)ýßÃsëV¢RcÞŽDI›—è]KPfÎÚ•“ƒ ‘Uk“þ“ì×Ö4Õ8ö@hÊ€@ hDå*„C 7rD‡øœ"¢ÜˆdBRô¯y ](ùâ Ȩg"Pƒ â ¡ž8ÿ•[l–œ£º_Ëf!G@ƒ+Ү̮ÚBCÿ(“´BEA¹—#üI‘!ºˆƒëç„…@mÓ²’¡`8‚–¸‰(ZĈ#ÿº[ÿ ÄC<€vD-¾ùæ‡H˜¤L>‹#‘à$~áLˆ¯1ᯭµ D¡w笈Ÿ@¶ä”|§s†Aƒ§$"©€…'uð;>°ƒ€sè·È ~`YXäB„ÄÙ ÏÌÒÙU @ í=âKL³Y9)8ï ƒ«2', ¾Ý-{°=I›ËâŠBB"Ï#®r"J?§|ª„ ÎV”B@?¹:+;€Öbv“|L‚›*@ÚÍ…l¥I”kþO õ‚&6º"ànˆƒ6älÇ<åË®#ô)¿ !>"¼ Ø)ð\åQÔ¸S8‘`IʆÏz¯êãðU Tâ*µìòäLéÊoØCäaNÍAâC!Æ’ÁÚÔ!úPÊX©X—ÏÀ“EèþéÊcâ*’„ŽUº"šI°ÆƒÂUº.†º6U^S¦àÂp/Ã\URäàR¥|„ÄìÛ ƒê‹˜l%4–î¶NOäRfjê£$Z ¡þþív"¢Ü!IÞCÂýþ†âl"õ Ð"°ôî ¢ 9¨áþkþ$c„"Ôäêú)lJ ‚ â yâ x"T"°üwëÃcr!@^"§!E2 Ëú¢*³± ¯Ž:Ê| Êj¨.ˆ,©T'kZ q#\æ„"®À!D~¹1@i¯Ê!¡÷¡òƒ¡ø#1ĘÛ^!JúLAýÐâ ʸ!I\ãpé$,D2D ÂB®!NÜå°ßÞ"~áþ Â*X¦‡Â*ôÏîí<gÀ’6C\S1°Cñd†"¢„’ ǶÄÃc n½„òÃNè0 ¸ ÉšXñª6l(" Œ/¡.5Í=ð6>­©ÞGïî¾£ê÷«ð1§ÖDØRë%iÊGÐ’! àí<Í#êÒ`j‚*£ê•Æ65Ä,&È Þ! P—À$ÈŠÄ®†è’L8 Jªˆt Τ ‘àˤ,¥ ¼ÂÃÈOÈI‚S¥ ÿ#éRM„¸å:àg‚ Ð>¦”¤¸ÀN!¡È«3!þiFÚdgBõ¥"i@Z“ˆð÷ç4"¤à>…D”£èd,.J"¦tBÀ<÷¨‚¬Ó€– ¢ïÈ“2,%|†”d($˜äH! Z»Àñ‚øU°¨–vi@Xåô×¢Npz‹ÈO­ Ã\‚F$ê1$ÿ “>פðAÐS``A ‘Ƥ" "âƒþ‚*fx"¦´!Epªþnδ"ëJ"" ãüÞåZ"(Ë©2ênètáb*J"át" b§”*"´KC(%FG~Þ"ª8çp xAÿB„~B ‚”3ºŽíH l¥çÓ"8" Æ"@ñÔžxÁAþ¶hˆåÁýEë¾uAôGAùB‰Xä'BÙò…Â*ˆŒ! ˜†f3 À!ñÁîà§Â‘ôö!GKED›B £ Ãà(°x¢ ès¶! j@M ‚2$Ã\W@çºÎ  \6[RBœ".N–KÐeÄ05Ððrô´•ãê¯"I >’˜|-… â³LÞí<î䝨;ñ0!3—Õ ­Õ„ Ëšƒƒ]6þdθ!ܺ!Ú6aôŠ:Þ€ 4s’cIF! z5ÎÁ/Um[\/¢ZYË.RN N¦àAý Uâ!/êí&HŒŠflÊ)X޲ÄÀöÄÒÒk¡ðŠfäÈf[¤ÂJ©j¡Ãê• u‘$¹`!öGAщD!¡îpÏ{Ë»Šn@6†sËQVN>¤"U Ðåöb¡Ì–¡Ì—!ï+-”[Êž`^IÀ Šl0>C$]1û•PAÌ'!ÊåçJ‚@"™§ £êž(¨5ÃäTþˆË6:æ:!¡ÆLAòÔà4$àO4´U¸Ò¨5ÑÂ]ÂÀRèVA¦B  \¡JÈ‹´!G¢øô°"@ï„÷Ìêî̼ ÀŠ"æ" ´ä©Tê" fg¦Pró”"òñ,!A"«¸!H$¡Áþδ-s·Zk"+AE Q: Ê_w" ˪΂W‹c®&!1„†ÂʬAøfü`è((tJ@äu,"¡¿#ó|~/¨x&jKJ‚ Pš,£¤''z‰˜åب¢¢*ÞÖ=W@³ ¿W8WcT•7ìÍeì±Â©«9 ¢ {þv Ý’âΤ!)^!@Ò.£‚T½<,0'aìl!Ú{¡üÞAÿ"g g¯ß&êbæaÿO  §+°– ®«‘AìÄ5Ðæñ¤>¥:ÂiÞ@Áü:AÑQ€1’YÂj êÇãR£ê¤ÂeË ¾  ˆ€ÑÆ5Ǫ"³2/ظäpVù3,,É"­cêÜ•réæñ¢¿O ÓÀ÷ Q" @4 ð¡üÜ€.) 79.BôuÇWeˆ" k}hÛe†ÂdˆËO*’åÒl RH€ ƒ¬¤–xÁg˜ê‘¤Å„s HÔ:A÷.(l … TlŽ0þ&å8ãêàlNR p¤,ÏØîˆ ¼€Rº )khì<úLOSîpíp"£‚¥­ç≉\E8– bÖåNæ4‡–™% 4áì^ YÂe®@.O ˆÉØ £]p÷Œ~E|ÇÖehj¶øZaÿAþ„ìP2.Þ"­Øá†Ç¢ºg§­Ê"R[š'¢Ô49b˧ö!Y& ÂcUb:E¢¢ îN¯Wl"·f!NXëN!T;¥ª |w$+Ñè"¦­‘í¢²Â¤,ϧÎ}‚"ú¸÷¾!ª—AÍô Ú’ó©…¸1çÐQtg1è°¼$2zZžaü B 8SÂ8 ß €ÑíO°þ>¡$"¸Hå&¿`nr"·C~¢+*¢pëÚ+§äð"·"åD ÇêÅ&죘$¡ìRÜèaüeB­Â ýî‘¡â [‡ K¢*ö(LÙƒ˜LP(=D¸CH¼!/²ƒ\†°ÖÂ*aËönà"ŽÓûx!$ò)Ê$bMœ5æïX®>¦pþêÂ¥qv«°5ÒHz'¾C‹ÊGG@Qu[¢ûXÁ#ê»Òqh¢5Õâ>¥Žƒ!gÂãºù¸2IãèîXM¤‚J s‚'ó"G$|.yb ýä<Ì®¡àlýê! NF êA4Q»MÃêÙFÙ6ÚF!ãn†ó`È:dLBEU©”5Ê XôôTŽ­Nèùº-UÔ˼˜OæÉ]bª)ËJ&¼_l0)åPRaènL¡°üA‡Â £"GÆÙ:é[¨ì"Ö惱 q—Â!E ]ì]Ñâ M´OJ¼ "«j!Rã)wò¾ŽÙ¨!]Lm’¼á ŒB RÅÇj/«gÔ˧Ôþ(¾3œÊR¥ 8bm’–ÅpÞ@«¥ Ö‘”ßâYœ"µÕA"" ÔȦ禎Gpr;XrÀþ"IDL Rެgµíƒ]Nª’4@6î!¡ì¥!÷4•L!AX"­•ÓFPGËn/ôÚB -lÌEÓ]ü~!¡æGAü¢!&”g±ý9$µéáù¸&*W)m]àB€Ò`s¸jË(Œ5ÂþþáÕsû‚hg¼2bàüŽk ÙÀ ü€ÎµÞ é'FmSt¾Cë$›K¿!á'áÌ… 6`&oàºënE2´Ö¢(6 €¿(hàSA¿ b* j@À ïŽB2ú’" òà"§’òêËÝ8¤LÈfó`‡ºxòÌPÚðÒD JPØòe­'E z£‚¤óP€R7mJSbwÏæ– ·—ï”i¨äòˆ((:HF FPÈ4àhœíÚ5Îk§ÁQþIÁÊ~áä{ 4€Pÿ€DäX_Za©`‡ˆÔÂ’A¢¼ï;â^@å€*N7Ï@Š|³ø)PJà@W ‹ÖäB!¯q7u =¥O0·{þ¬ì ÒN øÐ©@'”%þê‚¿ÜpÀ,¨äƒˆx¾51N‚ç„ ¡ #ʾjòä$¡†"¼‰®Nùþw«Î¸' §šüq·Ì â„€p$   ŠÌ“®Eú½ 4  /‘Êä¡ìÊä«Ò"…¢b"„H((ùŸáJ¸Ÿçûâƒ>¨1ò¾;(4PÃgü¸žhzŸgº tžŒ<¸Î <ƒJ1‡ˀè‚Hx`‡›jô>ƒOÀ¢¼ §Ñ¼‚œô1ï:l2ΫҜC«Ô Ë+•5,*¯Çø ‚ŸqP{8€G 2ܹU@ÿ!®Rò ªŸàš½# È»„i¡ë §¼,è~N€Òƃ!•HJôÐ~!àíHPÀÈʱè)º¸œTrñ®RºÏ2  Ëlô5Sq:@IXŸè0ò†Hy<†(eú!•††OH4>aèp‡ax‡“+jÙK(aÀ‡Á¸¾D†*(0 †M¨6@Yh2øäÈE# I®j†¨xꆈ~ˆTýU§þv縒q!â¢{ ÐR˜Æú§¦ggôñ’ K‰üæ Waô‡çз&¡›h æ†.ˆ6Q’ ÙÁÿ:=™R]Ÿùr‘ÚF}VtWŠó£Ò†êðƆ;ªVB¹b9¶¦¹hn‚ŸŠÀ{()ðn«=!ÿ[ï°ðH4aH6Y±¢{`ö& `WUŠhIèG §³æ%gþÓ¿øP‡†(|3£ÊÊôÚÙéè{Öh(¿n•I;zk°v¨  àe¡öú ’õû’¹z  ù¦ ÎH ì°‚έ€5/‚Œ‡£x_Œ dwô8’àûfÐQ^€t‚Â2 &TÆõzQrR ÁZWŸÔ*+À\è%Â@…¹+XÁ`§ÀB;`&‚ 4zª PØðõAœir~£þ'=8V?̸Úy‘9/>SÐŽÙ D< ¬„öW“Pÿë4ECÆq^X*¸°„à€iz ce\¼YTÈ*?à@ÿa…ɤ(<äÞoY×€(†À4Hf®&ÜA–°jãý—c…4|§„r4À€\FÀSÂÒʹ7ȶ$Ú®c¬9E€ )l=ÕØ‹‰+¤Pn%‘1jö3ª@|P® ieÄÁDCÏá#ýïó>@¥ÿ@‘4‡À6’CÂY d0÷óü@¢áƒ„ Ebþ‡ü\ Sô þ!u“¨‡ÎÑþg1 ŸcþƒQŽCÞA¡DqÎÂŽZÑ ”Z‡Èø?Ã9 T1ƒ•”^ó0 d1úê e0e*bÔ‡Š²¦‹È51¢dBÒ ˜A„†b\_*ä0ÏaúC 07DVñpC*ÊÒ¤Cò'XfëÈJ€ † BZ€³õŒ¬²D§<-J­ª¯€õ G»ÞMuµWi®?Þ1I¤×4Å;ˆ3ÞŒ˜€¸Î\ƒa .µ"DôjñY޵ܾ=eˆCÚÈÿRäšùàÅñ Åò)€ ~ÚœÑT"Ö€lû‚!ú¬5‡©rfj+ø! ¹-_UHIA6Œ+2BÁ|§ÅÉYÓ"ƈg£é¼ŠBGÊÃò"-Ô.[“´³ WŒ‰ 9…ÊOe[~dq^¹üŽ—!€›ŠæTaƒ@†AB¸\  Èœ’üíˆ1ð ΘƒBrrýˆ~¬ÓñrVn°ÜÃò:^ùiir†hƒVĨCÆA^i˜ÚÖ÷0\£kLVƶJú¡+sƤ>NOô2®nµò!䤹'å ˆ›V6ØÄŽø¸€yóŠ€Z…Ð\‰jž+˶ª%û(@xk8iQ÷{¹Q@B}ÆX"pÏ…|‡å8λˆ(޲ÊXȤ@Càä©+Òô2`UØAà(WˆÙ¼úĉ Çn؇—¢{õjzz ±(@±ÿ„2¢j¢%Ýý)iÑ ƒ¢SH !óQjÇo«˜z[$„<)šA§ d!í+]Þ™¶¶Ñ↠‚RÈtfرü¿kPþÜÂ,† ¢³wYCþ”î„øÎO,“̳ÐÑÿ Ü éCT¨RiGûz B™à—ÅúÅ 2g ŒgÒH`†+Øss°ÒnËádoÀÔñ0CAÄ5 {¨aöDKÉ¥d xis51m 5€˜Hf£.QÔ3±ì¡‡¡Œr$ Œl‚?ëÿ+ÎÝ){rÑžîº% ³X CÐ.QÞ`Ï!™­éÕ6v6t’—⦀ ™6z€ RÕ¤…eê,¢?rðã¥¹Ï »x® Osîp3€–訄ƒb¼†K’dÄžy÷àCÖˆñºÃVã¾¹HH $!žP§jè:¥ÊÅÐCÈYH£üðô›sÍùÉs™GØ^@‰¥Õ\¦e“¹ª™`Ù’‡¶'×÷ú,#_4KÐ)–@¿avøxàÜ¿fX9TƒþK€ |¡‡L|¨í©ý:ªP€Èñ€±y–3˜‡“°ñ\±!–òÊ?‡J` #S›x‚€y&¸€Óh€Zb±&9kÁ^šiq5Ña±)qÂx0â…ˆS¦ðY넊’ $ ˆ,‰ø¹Êˆ8·z° ¨ø¹˜ƒ"`Â"ŸH `ƒh†;`ƒi †¹Ä/Âò 0†`ƒ,è)Ñ]Bd142"Ї½%(®ˆÉCkˆcœÃ²°B¢¾‡ð숷2äD‡Œ`B!Ȫ™›­­À²øÊ›00Ñ ‡ù2ˆH™ˆ2 ¢™Ø|‹bÀ˜‰8±°„B¨Š°ÀCóœ— 3aÛ¯L0½8°~™êeH|$~ãZ@X‡Ã%ûÓ€‹ÀدB8„‡»Rý‡ùJ‡â‡¨Ÿ‡³h‡áõŸœNCŠˆakúÚ¶ 4o—zÙÀà„€A²Ãá¿"Ë •o®s÷·¾cãž‘ô€ˆ(,鹎ø§hÛà ò‡ôYrœXyàê=à¼G’q+ˆ¯"@$“° Dø¢P¹'Ùq¡=¹#à1{Šn’}ƒØÄø£(€± ‚{‚aw€{_1ˆ„…ð‡¢º,ê¾®aŸy¡Xmø~ ¹<( ¤È‚€±"€¬ˆ+«‡üw“2UÐ3]°}’(kz¹\° à ±°/a¦HÁ3GŠÃùߨ|’ò? {†²3±Z @ à€ÂP€"H5x¯!8 ¤L‡zÖ†©h‡é¼ ƒ&i\˜ Ñz( !°ÉV€,wŽ€nŠq¤‚b0¸‹ëú fyŽÛPY…Q‚ú·Ê'"“ˆë¸†>ö— 32x0+±®ˆ_GÂшô‡ùì08(Xƒ;yˆ14Ò¨ÎËk€8ЃP†¸‡Ê”õ|ö£CµÈ‡Ð0@¨‡„K1¸†4´¿µˆb'ò¨O¬Ð¨ëÉñSO}QØ•€8à2XšÌ°Ê˜.úsŠ8ƒè¶"}8z™6X|¨~NÉÀºx¬X©ðdz”ô€šqé%~^ˆ|üNÿÀЄ©¡ºÛ‡»+Áå©”´ "ë,¨„€˜ |•+ÂñŸ¢y'°‡¤}Ûˆ1ѾŸ€“#q°¸½aÖ®U¬Y2ˆyÏâ:8xƒ xº}•=׋઀QP‰šIÔ‡e;dÅšDö>`$i?ˆb¶a°€ ÇP ¯²[D¥ ”Y29€q›Àw¹ÊB·2¾€ʼn›@Ú¶À/°³i>BB®Pe°S5ÏK½¶[_ˆ}n‡òÙaéa€q«€¹.enž›K-BØI<¬‡Š^†Â¾‡èô@j7‡ûK2𘠠¤*öV–:—‘¿‡‘w†²ã,Ùò'ˆ3úR ¼€ï€Ð³rš2˜ä•ÉkQkÓ׸õ¡+²º1!g³Öè• ‘xq;ñY‡ Ì•ÌG|ÈÁˆˆ€P[èœ ”Ï6 ˆ4øÆþgàH®®>lˆ|ø¾ˆCaƈuŽýHчø"Šó·p¾!X༨Ʃ^‡ïU‡ûÁ=ëûÞHÖUP‹ØÒ„œˆ¯ À}¥øyHyš¸~ÇP¸TiOÜ·z„1ÀÞK_Gz‰8DøRر3Xy'h~Ç{·l¥P]D³Uˆ4†° ƒTaÑè‚ÍÑ'hÔ êPxŽøq(~ɼ* °tùú€©¸Rž0¨€Ú(‚‹§‚A €jµÓ5‡ª¡Ü»(¨ÛÉx(ƒ>,¹÷@‚€2¶©k˜ï€ #þq ‚‡"‡:"‡ûî{{iƒ%.ã#¨¾¡· ¢p×t£Fy¦.S8á/ûãL¨ƒ2°BÐ ˆZM(2—€p5Ò[E ‘_“3B¯aÁ¸PÈ€.µfŒ:HÙéN(–•Ìä0…Ð &ò©Û_IŠàì͵f¯ˆôV§À†+§Ûz¥ýÈ5Ñáû¨ªïui×u}¾ÉVVY?Û›-x‡Ý/>õ¨7äbרƒ C@ú—Ü}¦K§:סÎZû­‡üG©¨7õÿ¬ÿwLG˜ˆ8®Àðnÿ}ÁßíÈùñ Âðwðª@ƒ€P0Bá Ûvû|ÂÂá”DÁ?Ââü¼ …¿!Ò¨#êÀÀ†(8 /5i”)ÀJ œIÀ8YžÞ…Ê óè%rƒ_ÀßP{½)ŠHè>§«8$Ðâ½2Ë^ÇnÖ9B¾@P7¡.ø¸NíÐL%VỀD8DIL^G\Wy:…É@/Œ åp=‘ÄöŸ‚éƒH[*é ¬H¬ðl8™oC,|,øï×€^¡xˆ&0‡)©€ˆ_B `9¸P¶e0  ¹c¯Ø$ ãÀ›GšQ胂á~¹bú‘z €RÒ áºV©‡º™!jŠŠÂ¢¯`!ŒŸ¡·­Š¢%¢‰ Ž’Š Zh!g:iÐ. `qЀ(ƒþž)Ñ´‹€'ìj‚(ü‚hXJ…©È!Ò…Ä€t#@0` `„D» 8>F«DÓ™¨[üćø^¦Eˆ#z½ÿº§R ¼`ËÆ´Ö{»‡j2rð0ÍÈ\Ž‘2ñÿ=€ ’ S¥  Öû'r4­ < °]€gúq2ΉÂö­ÉÄqE§yþÍ ‚êþä’(‡V5™þm¡gò: ‹*pzØHXà‡oÚy¡v2qd •¤œZÈ%°ÆH!‡hYd‡Qè%ƒÙGýºÛö*V'š2!Äzƒ[(XB‡'Gùä‡X×b ƒê[!dê2à)Æ‚§9ÿvŸÁ²?# z¢8šr…ÚÈF0ŽŸ÷Òv!drk)—° g쎗š½4ZÁB…œ“ªqV'q–)“!Ññþ).°9 N›è]ì4ÇûH‚ Nª˜ð§Ý(dçÚÿYçI˜°RÑb¤¯éæQµ’Ž$X*i#µæÏ¡È]ÆŒÈ9îW1z}^ÚâJ^H8ÓàäV eæ¬#¨XX¦ (ÁRžÍ¡å£‡7e¡uÆ ÄÀ‡>GüÑ É´ƒ€¶ùüï'¦Œxk§µðœZi(‚hÝ’;·ŸéŠ s¤R^œmàè MéúÁ5·œ‚º‰šø^âô¤`F‚Tʺù `2‡¡´ƒ…P@ÁHö c&©ÂDAÙ² ]ûF?Ù±$-1AÖBÉ;@<Ü,n€ ƒ`¨²‰‡« ê`Âvhä:)!c°¦A5 ÷Ô `àbÆñk#¥áñÞBÔ"p`pT>˜ A"YOĉ6 CÀŠ$w¼ó‚aÜ”2>@¹Flœ"˜w¤ù‘sv@ñ4waÊ–Ç”mA,^ƒ!þA!82„á=ô’N,8' ´õ“€ÞCœQ_Ãü¿©"Ò$7!Ï6M„PAá;Cü;é"‘lªPò!$çÚ ˆpB!¬å= dù AôºN*cC'­E3bqGøN!Ö KNˆÐ¥q4Dã˜y8H ƒ!Ð@Úö­vWµD/-MÜÉ9[ '€‚R’q7Ž Û!Õ2oY#€C‰ „8a²—#~w•ãÿœp®‡ùŠË:kµ“š%é¸Ùì‚Qqþˆ± ší…ÑqýS$8þ˜“̺w Àµ!n”„KºB¢ͪ#óEÜþNÞ’å!êˆÚ¹¾B%Ä D…Úñý&nASÀÕ€L´ÙŠf'~hbDm!HiWЪx^®Ÿ„‚ €|´Íëð í²¶·4þ"ó;.¢2™FIà I…3!¸=höV` šø[$Ovw ÙAáçN¿8P|‡’{|ƒÓ:A 9å)‹8œaú÷õP™&[ÓÛ¥;Ô&è8UíL‰*4BᣓÊdI³Cýíî2qJïAò±L|WE>²‡ƒ ˆ‘cqÿÔ¡ DËÀ¦ ¢"S•ƒGÀn BúÂ-8 U”?…Æ”µÙ\¼;‹“‚Q„Fb ‡D '4}òY3)ër±Å¯¦Söb4Ñ Ä Û€d8=@“¿æ{üSl‰±ïôCE&žûÔQÐÎK@ëYCñöÃ(paÛ¾p®ÁÞBIÁA¼Ã´Ãz=Žð  !Vò&N,{¬¿M듊üA‰8ä,Nî´UÿÖ¿l÷ÕþKRQIÇ':ÍÊbT•'G¾–5þA΀!g'V\+öÿúåÀ!Ħá’ˆ0`Â%¯î@"¿eÂìäÞ"pÄ¢ (hïñ§!p°ÂÛ8þcF"/ÈSaü\&fa F."" æºPDPâv’ft1áú¢DAü&â;&ê'e´É¢ÁÁþ"0µ0>HbNKr Šàkâ‚   PA!ô,AìhÁúi–!pŠ'Äã~{ k @ iÂDV¦ýo* ‚ì+ë¨)Xðk B˜9NÀ ƒbòSaôΠa@n"pô%6QbD±åô áT!hÞ ‚{iN™áî3A< aîOaüüËì!kZ "‚ú ­¸>€zC0$Iˆ·cZ?ÁÞ!êô)úOÂp˜}®¿IÆà !d­e<E6'n#¡ì ‹0xhªÇn[Gh;âE ÔaDΡþ˜QQtEÚ êëB‡$„p @[Aý-T¾'ª—"}­ó˜¾ cšçú(*NFÄÊ}¨äÿ!þÐ" #Ib Š˜q‘Þå<Vç„è zD<0ä–èçžM2@)‰¸›‚¤ÃcLÈ‚BN,N£lAà/áü"ïâ)ß§$GÀ7@"N§ÚJq6@fú+Æg§6Â.Bp(B–Ê!ÁJ¼B¼p’‚jBòÒÛ¢ ,™ÎââpEFè!rìzMšþ¨à!Í âýÉPZâ,î!ÌNþ³6¢nâ8'ìa‚ÑS$ “ V¦U2%˜·Áþ bòõËäV³3qjÛ@5"pDħµ5Ók!ý2%â4Áüžâp‚"®‚¢¾G®~s!Ë6¡ÿ.~ŸaøµaüYý2äeQæ'm>ónñ/&æFYâ¿18Y@ÿ°¶1 Û‘8‚l†FÞȦÊà·bE“u4->"Î@ è`eÒså*)‡Ìó( !þ9Ì#«òݦT4Áò}aòš XÚ7ïQAŒN9b²#¯¾ ŠÏ0È΂nÎ b0’¡ê]f-ëRÉœ¹§hc)³ M`Õ@¡Pn N¤Öx‚¨ñ¬$EÒ ¸‚gX¾¢ìTM`:Ä ÌÆùHFoFe6ÄÂæ,¢B~ cLRl:B¨òbåM T A F–À†ÞEæ†Iv¯Â@²ò—’F!c5ãR8`%AÞMaÒ!ê­‹NLƒI< ‰‘F!s(‰ R€NÕ@/áÚ1áвA迲ó)Â{¢|N·H)vŠ` J»À5ã9¡ø5!Ú]aΪáé'Àшd,J–ô@Q BŽÌdkB>À€ú3"Þõç<î"ôþàÒ!Ä* !ÅÚï" \)¸ÈÁþÎóâpëî@'°å'¸¤µë^é8Ÿ±©2€ñ35‰0!Ê^É^B&ÕênáZ¢l¾!kÀ˜\1©b<åð €¼!ÊR àëiÁóôvÂ8áþ?ÿÁ!a~!θš3O?u=b"p)Ø#< ˆÞÖf‡`N`})´ë_•ú!kH!Ö©~ ¦nLê†òÖá#Féš}$‚É^+ 'ïPàâKôæŠ"˜œaòOaï;ü+Bp‚Ð)`ÎÖ&'Ë=]GÀÀކ§¨ö¢˜ oDä Ž'waÂÄd¶¨ˆ!ô‡aßEö¨O‡„)iÞß4® 0¸¢Èk°"E0Ö†)·b(¾ áèªáæ|!öY@8`: % lÒì÷8Â* é+j"˜Â(Nš-Æ!âá÷P‚˜» ™OíhP¦$Št±ªÎ±è¯D¢E]Šº áÞ5!ܶáöŠ ¸cº̪àK!ÿ§Ø `¶à>ˆ&Ú)TI´'êå,­ˆBêªÊÊ4",ôØKòä«nª®Bu€ÈPoÖ¶áÔªáôëëëUîŬF›ŠÎ÷ÌN¸dT †ÞJ6¤ˆ%<P:{ÕÊpÈ$Kö"¤à‚ &ˆ DG¾Ó¢D4€D–¾.¤Wú.Äák´‚脉 P|"Û€À"È+°^&˜eKà§qrÁþe¨ÎkÃ9qM*÷Ìü¢]BpM"p&¦û<¬„dOF' ó4̆©¦¼›þf–—) 7y6Zû,9 Ìbq2™)1æ ˜Þ@‚ a´ÔÌ zL”†q8½ÉJÚé<'O5¢ØGÛ—Gz"©Bl®' Æ|ÀÄfTÂ8úæ`$VÔyò–dáø!úÉAüµ1Â'Ä'xôÄy–#ºÌÕè!Âë$L®òUm¼y¡ñ bj'Èçz' 2ëMÇ r'êëIR \n" àëK[;ÒÞk´SÊшP™áà’!øÛ(ÅìCh 5Jâ×aÿgBE$¡þAH£L‡!þâ¢E#áÿ bÑ‚vãRºf@Œ¨ÏCSf‚˜JÊÌKaÜÕAâk¡ú±‘‚š($Rrë¼Âضà@u€ RT†ÕÌP `$z€[@F¢@cjÂ)NrGÛáüÎu€FD‹)“ó’Þ aÔDÜk¡ù¥jèNBzDžzÖ" ŒBëVCh&æÂ,B¸ºø¨¦¯„žd)‘Ékúˆ™Fâ ±$‚J¿¯~¾jîKÁÐ4ÁÚ$ä.—2¤)„DNïâJŽBúsxþ†øºöP'Þö§2IªúBV»º%ÐŒ#®´ëJ!o¿ðä™!´bèåà ӟ1bqCáþ¥c%AQ0!zF^›î' ® ¸' "^˜ìòÛõ1ü°‚ØB'BÊ"p·¯¬»EÂä« )ì™Lº`P–' µžPæ4¢ÄqA#Â|J'p ŃÏÅâp˜Öˆ’LÈ š\”ü`ò2+ðö Ö_p'qú¢0èð“Tb Êxà#(g£üd¶"ò'6!eˆô.Ž+‚L«ÉBq‚QÄøöm°´ë4ˆÎªbqôˆ)•àÄ!öÕAáÁÁùcèâ+ÀÚ³@ÈÀ 5"Dƒ'áÐÂ; B˜{6J©ÀqJ ‚tëÂ"úaïK!ò<1vªàÑZ7—¤!g ò>¸dÙÏ¢l«C B±ì[AÞRìnä΂âqŽ dÂn€õi 2$Z>Óˆ$CäÄH§’—ȧ»˜]æ* ã䦌̘»ƒò)…×¥à/`<íÀZžàV½òÂBáaÿ´'nhÀ6 )ÖØ|nf)‚T²ÞI2y왫½¥’e¨BN†Nyé‚ÌB$pèGÂÈl¢˜€Þ39„¨`:DZÕ¾ãô(Îmáüx£AÏâSÁüèújª@N,À$àÑl¹A¸ð’!þÚÁÿJAþŸsx$^–'ãPåêéX ‘VÑ¢n"sAÿ23>¿<γþ—3ÕÞ!n•·" È@¾ŒˆqjŒ3Š1 JhÂV‚0¨D4¡ÊŠC¡ÈÚ '!„~‡Müi1 €6£‚ŒJGùÊŒ)'üõ>GÇúb„ ¨Á‡Cè% D ”TØÁ(Bâ„MèÊML(u9D#gTšà£J¬'ðúŸ°˜~8@ýCNçýV„EGðà‡D¨EJ‚XäwS²¸ŸÃÚ}*i#;]­DzŸÌ:ºâš0°¡MnLÈ#f>€ô€Æ2™ cfØÀƒK¶ÐøxŠHöJ!À²q¡ 2 àÊ¥ Lz6û_¨ÜÅ?£eº0Ú£t4 †!ÊýqOw˜~© cã 2UèA~… HC ÈÝŒŸHX|ŒZ¶„_Q8}¦`â*-æú#@Í€1sò›‰œ…©h …ƒˆXr‡èY°ƒŸXéà gtê~(Ytã VâƒÖ0{ºˆÁv…¬¨Þ.°hØX…·`â!\Œ„ûà[¿ˆq˜Ïi$JGªhrŠ„V7ÊèñˆÝæŸ88uâç_¦MGûðýŸV8¸H퀆²ÃC\l¡lÝb|ÒP(ƒW˜}£çýb(89s°6ÿ²! .È¡ÙÐÑÓèpnìÚ|9KËÚOSÛ  Á ñúC iÃü‘ðÞF qÄ`äóØA _ãý©À‚Güæà„‚0˜An ŽýKA¢0t`ñ®…h„*òÀ¤:Äa©0{Cf „A³¤Fq $`Láy HsÔ Œú¼CŽ™pÃü7†ø?ÃÊd#P„è¦B"©:d"(ð–C‚©ïª0ãkHq&<Œ0"Àq€Äa ôµÈ!‰!Ž áÈp˜#µÍI H" çè‚´žBÅ E±À²Ãä?c¨þˆCýÇõ$®Î‰{ ‡<Æqüî §GTÈÄ#ôô»œ>åL–¬‡G0Hs„ ‡è„9ÿ%AB¡¨ŒLàÛˆ@둹4?ßLÁtÅ)ô" ‘+°|‡J“vAamBNl¤ã…”uþ €ÿ3„…ÊìFÍ€˜cü8"½ˆG˜cÙPæN<ËHý/ræä.èÈ:!bÁ¼€¶U§£…¢ , ˆ8.„? BMÈDÒçl +&rˆ@¾,HéÔãªB€ÿ[uƒGf:¬(ïE°Í’ºBáú36»§“ üf É45¬‡7`<ÖØéŠ wÌ1ú@ ´€•ãË•FˆEnUGäýÛTx?é€ÿc´h3è:cHAí‚Â!þx!,áŒ=â  ‰Ÿ#üÄËJ¤˜ÿ’Wl½¨’A#ñ¤8\‘‰ew¤Š»W²î®þHÄãâ:9¡¢|™’Є‡Ò RJ”!Ò|¶B $ŸEÀD1DR¶Çø|‚W©ê‰pˆÿÂwÂDøHA1‚$!ùC€ÅÌw„‡â0ZÈ@¢#[Ê–29!ÂŒYÛ#ÉÁãþ ãØ|?ßÀÿ—Éá›Ç2ÇýÿÈLç3áúk’á„Ãø[†ÌB ö2—9hÛÿ'‘!ÃDÏ)aù™GÔ‘¤!PìF¶*#¦…,?¢ì]Ä£ÿ.b"ß$bñ\N1úäGœ_‹X‡Ã’æbÌkr„Qh°BÐØ‘@*€Tx'XÿcämRlµˆÜéÀµ¹ cÃR]þ}„ÃàìÀ8Í"'Êð¸dùˆb!hà„N:|F¸ÂfŸ™ân’ÿш&&BÐI\²Ü‡nGÛ°H@B"# …Î}–FÈèþiÓP€ÚÚ€÷} `ŽœBAˆÝÁm‰˜ívA.‘È„p…«p \ º"R@j·Ö`Å#Þ?ÊI! Š¥†ÔB]Ϙ(ðx­ñÔøG›KË$ØP>} Žèpþ$B ›ã"­‘×׃üàC®A- ÿN ‡ 8¨C“ùñþGÉè?A+ ÿ΋õi<ä ÄN·ãÝpÿÆ„ýåè(a_Ó×¹¢áˆ$ÿâOûü+§6qÜÿülY#ÈÂßQäaÅÿ+óÔéåcü0Œ0B9Sßgæí?dFšF¹KêL=LêIÙô0ãoG¶áüšH„•Áá2013:07:03 13:27:34 openimageio-1.3.12~dfsg0.orig/testsuite/texture-icwrite/run.py0000755000175000017500000000116312271062644022700 0ustar mfvmfv#!/usr/bin/python # test 1: seed top level, no MIP map command += testtex_command (parent + " -res 256 256 -d uint8 -o out1.tif --testicwrite 1 blah") # test 2: seed top level, automip command += testtex_command (parent + " -res 256 256 -d uint8 -o out2.tif --testicwrite 1 --automip blah") # test 3: procedural MIP map command += testtex_command (parent + " -res 256 256 -d uint8 -o out3.tif --testicwrite 2 blah") # test 4: procedural top level, automip command += testtex_command (parent + " -res 256 256 -d uint8 -o out4.tif --testicwrite 2 --automip blah") outputs = [ "out1.tif", "out2.tif", "out3.tif", "out4.tif" ] openimageio-1.3.12~dfsg0.orig/testsuite/fits/0000755000175000017500000000000012271062644017317 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/fits/ref/0000755000175000017500000000000012271062644020073 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/fits/ref/out.txt0000644000175000017500000005713712271062644021460 0ustar mfvmfvReading ../../../../../fits-images/pg93/tst0001.fits ../../../../../fits-images/pg93/tst0001.fits : 123 x 321, 1 channel, uint8 fits SHA-1: FC4F635D410B219477B709E4D6F993E9AA42C7B3 channel list: A Extend: "T" Blocked: "T" Cdelt1: -2.3 Crval1: -73.3 Crpix1: 12 Ctype1: "PIXEL" Cdelt2: 7.1 Crval2: 300.1 Crpix2: -11 Ctype2: "PIXEL" Object: "Ramp 8-bit" Origin: "ESO" DateTime: "1992:08:19 00:00:00" Comment: "This test file was created by P.Grosbol, ESO (pgrosbol@eso.org) Simple 8-bit ramp pattern for testing of FITS readers" Comparing "../../../../../fits-images/pg93/tst0001.fits" and "tst0001.fits" PASS Reading ../../../../../fits-images/pg93/tst0002.fits ../../../../../fits-images/pg93/tst0002.fits : 73 x 31, 1 channel, uint16 fits SHA-1: 4FCD0E343956DEA4E792786138651F9D8C81F615 channel list: A Cdelt1: -2.3 Crval1: -73.5 Crpix1: 12.1 Cdelt2: 7.1 Crval2: 300.9 Crpix2: -11.3 Cdelt3: 0.003 Crval3: 21.1 Crpix3: 199 Ctype3: "VELO" Cunit3: "M/SEC" Object: "Ramp 16-bit" Origin: "ESO" DateTime: "1992:08:20 00:00:00" Comment: "This test file was created by P.Grosbol, ESO (pgrosbol@eso.org) Simple 16-bit ramp pattern for testing of FITS readers" Comparing "../../../../../fits-images/pg93/tst0002.fits" and "tst0002.fits" PASS Reading ../../../../../fits-images/pg93/tst0003.fits ../../../../../fits-images/pg93/tst0003.fits : 137 x 271, 1 channel, uint fits SHA-1: 9D2DEE3C1411AB38B5DBAD0532F3679B797B2374 channel list: A Extend: "T" Blocked: "T" Cdelt1: -0.12321 Crval1: 15.231 Crpix1: 12 Ctype1: "RA" Cunit1: "DEGREES" Cdelt2: 0.001231 Crval2: -10.123 Crpix2: -11.1 Ctype2: "DEC" Cunit2: "DEGREES" Object: "Ramp 32-bit" Origin: "ESO" DateTime: "1992:08:20 00:00:00" Comment: "This test file was created by P.Grosbol, ESO (pgrosbol@eso.org) Simple 32-bit ramp pattern for testing of FITS readers" Comparing "../../../../../fits-images/pg93/tst0003.fits" and "tst0003.fits" PASS Reading ../../../../../fits-images/pg93/tst0005.fits ../../../../../fits-images/pg93/tst0005.fits : 102 x 109, 1 channel, float fits SHA-1: 763996BCEADB93234A73AD0D714C3E9D874014CE channel list: A Extend: "T" Blocked: "T" Cdelt1: 3.1 Crval1: 1299.1 Crpix1: 12.3 Cdelt2: -0.17 Crval2: -102.4 Crpix2: -2031.8 Object: "Wave 32-bit FP" Origin: "ESO" DateTime: "1992:08:20 00:00:00" Comment: "This test file was created by P.Grosbol, ESO (pgrosbol@eso.org) Simple 32-bit FP sine wave pattern for testing of FITS readers" Comparing "../../../../../fits-images/pg93/tst0005.fits" and "tst0005.fits" PASS Reading ../../../../../fits-images/pg93/tst0006.fits ../../../../../fits-images/pg93/tst0006.fits : 77 x 173, 1 channel, double fits SHA-1: B043726D3F76840AAC84713C1A6C323D85CADC74 channel list: A Extend: "T" Blocked: "T" Cdelt1: -0.25 Crval1: 1.5 Crpix1: 12.5 Cdelt2: 1.1 Crval2: -3.7 Crpix2: 19.3 Object: "Wave 64-bit fp" Origin: "ESO" DateTime: "1992:08:20 00:00:00" Comment: "This test file was created by P.Grosbol, ESO (pgrosbol@eso.org) Simple 64-bit FP sine wave pattern for testing of FITS readers" Comparing "../../../../../fits-images/pg93/tst0006.fits" and "tst0006.fits" PASS Reading ../../../../../fits-images/pg93/tst0007.fits ../../../../../fits-images/pg93/tst0007.fits : 38 x 1, 1 channel, float fits SHA-1: 32FB2E046F09E6DC814A6040B03706174EAE7229 channel list: A Object: "IEEE 32-bit test" Origin: "ESO" DateTime: "1992:08:20 00:00:00" Comment: "This test file was created by P.Grosbol, ESO (pgrosbol@eso.org) This is a test file containing special 32-bit IEEE FP values such as: 00000000 ! pos. zero +0.0 80000000 ! neg. zero -0.0 00400000 ! pos. underflow 5.8774718e-39 007f2345 ! pos. underflow 1.1675760e-38 0000efce ! pos. underflow 8.6025713e-41 00000001 ! pos. underflow 1.4012985e-45 80400000 ! neg. underflow -5.8774718e-39 80372345 ! neg. underflow -5.0636046e-39 8000efce ! neg. underflow -8.6025713e-41 80000001 ! neg. underflow -1.4012985e-45 7f800000 ! Infinity ff800000 ! -Infinity 7f810000 ! NaN 7f800001 ! NaN 7fffffff ! NaN ff810000 ! -NaN ff800001 ! -NaN ffffffff ! -NaN 3f800000 ! 1.0000000e+00 40000000 ! 2.0000000e+00 40400000 ! 3.0000000e+00 40800000 ! 4.0000000e+00 40e00000 ! 7.0000000e+00 43f23b1d ! 4.8446182e+02 3cc77e3a ! 2.4352182e-02 3fffffff ! 1.9999999e+00 00800000 ! 1.1754944e-38 7f7fffff ! 3.4028235e+38 bf800000 ! -1.0000000e+00 c0000000 ! -2.0000000e+00 c0400000 ! -3.0000000e+00 c0800000 ! -4.0000000e+00 c0e00000 ! -7.0000000e+00 c3f23b1d ! -4.8446182e+02 bcc77e3a ! -2.4352182e-02 bfffffff ! -1.9999999e+00 80800000 ! -1.1754944e-38 ff7fffff ! -3.4028235e+38 So best of luck with the decoding" Comparing "../../../../../fits-images/pg93/tst0007.fits" and "tst0007.fits" PASS Reading ../../../../../fits-images/pg93/tst0008.fits ../../../../../fits-images/pg93/tst0008.fits : 38 x 1, 1 channel, double fits SHA-1: 5C21742E65AF385B106DE98BE7004190C6F2E2BC channel list: A Object: "IEEE 64-bit test" Origin: "ESO" DateTime: "1992:08:20 00:00:00" Comment: "This test file was created by P.Grosbol, ESO (pgrosbol@eso.org) This is a test file containing special 64-bit IEEE FP values such as: 00000000 00000000 ! +0.00000000000e+000 80000000 00000000 ! -0.00000000000e+000 00040000 00000000 ! 5.56268464626800346e-309 pos. underflow 0007f234 50000000 ! 1.10504270324359603e-308 pos. underflow 0000efce 04b0f1ac ! 1.30269360492828320e-309 pos. underflow 00000000 00000001 ! 4.94065645841246544e-324 pos. underflow 80040000 00000000 ! -5.56268464626800346e-309 neg. underflow 8007f234 50000000 ! -1.10504270324359603e-308 neg. underflow 8000efce 04b0f1ac ! -1.30269360492828320e-309 neg. underflow 80000000 00000001 ! -4.94065645841246544e-324 neg. underflow 7ff00000 00000000 ! Infinity fff00000 00000000 ! -Infinity 7ff10000 00000000 ! NaN 7ff00000 00000100 ! NaN 7fffffff ffffffff ! NaN fff10000 00000000 ! -NaN ffffffff ffffffff ! -NaN 3ff00000 00000000 ! 1.00000000000000000e+00 40000000 00000000 ! 2.00000000000000000e+00 40040000 00000000 ! 2.50000000000000000e+00 40080000 00000000 ! 3.00000000000000000e+00 400e0000 00000000 ! 3.75000000000000000e+00 43f23b1d 53e93c7a ! 2.10188154006588375e+19 3cc77e3a 9c7bf51b ! 6.52064009369660060e-16 3fffffff ffffffff ! 1.99999999999999978e+00 00100000 00000000 ! 2.22507385850720138e-308 7f7fffff ffffffff ! 1.40444776161118415e+306 bff00000 00000000 ! -1.00000000000000000e+00 c0000000 00000000 ! -2.00000000000000000e+00 c0040000 00000000 ! -2.50000000000000000e+00 c0080000 00000000 ! -3.00000000000000000e+00 c00e0000 00000000 ! -3.75000000000000000e+00 c3f23b1d 53e93c7a ! -2.10188154006588375e+19 bcc77e3a 9c7bf51b ! -6.52064009369660060e-16 bfffffff ffffffff ! -1.99999999999999978e+00 80100000 00000000 ! -2.22507385850720138e-308 ff7fffff ffffffff ! -1.40444776161118415e+306 So best of luck with the decoding" Comparing "../../../../../fits-images/pg93/tst0008.fits" and "tst0008.fits" PASS Reading ../../../../../fits-images/pg93/tst0013.fits ../../../../../fits-images/pg93/tst0013.fits : 128 x 128, 1 channel, float fits SHA-1: 2DAE86283E1BCB155774A83F88C75B045FB9B28C channel list: A Blocked: "T" Origin: "BASIC-UX-LA SILLA" Object: "Test data" DateTime: "1993:05:13 00:00:00" Date-obs: 13 Tm-start: 69932 Tm-end: 70121 Time-sid: 36564 Ra: 187.372 Dec: -21.2211 Airmass: 1.019 Instrume: "IRAC-2a" Crval1: 1 Crpix1: 1 Cdelt1: 1 Ctype1: "PIXEL" Crval2: 1 Crpix2: 1 Cdelt2: 1 Ctype2: "PIXEL" Exptime: 2 Observer: "P.Grosbol" Comment: "May 13 , /" Hierarch: "ESO GEN ID = 'Unknown ' ESO GEN NO = 12371 ESO GEN TYPE = 'SCI ' ESO GEN LST = 0.36564E+05 ESO TEL ID = 'ESO22I ' ESO TEL LON = -70.7345 ESO TEL LAT = -29.2584 ESO TEL HEIGHT = 2440 ESO TEL FOCUS LENGTH= 77000 ESO TEL BEAMSWITCH = 'OFF ' ESO TEL FOC-POS = 0.29320E+04 ESO INS NAME = 'IRAC-2 ' ESO INS LENS = 'LC 0 ' ESO INS MAGN = '0.49 ' ESO INS FILTER = 'KP ' ESO INS FILT-CUTON = 0.19400E+01 ESO INS FILT-CUTOFF = 0.22800E+01 ESO INS FILT-TRANSM = 0.82000E+00 ESO INS FP-POS = 'OUT ' ESO INS FP-WAVE-LEN = 0.00000E+00 ESO DET NAME = 'ROCK 256^2' ESO DET PIX_SIZE = 4.E-5 ESO DET BITS = 16 ESO DET DIT = 0.20000E+01 ESO DET NDIT = 90 ESO DET NINT = 1 ESO DET DUMDIT = 0 ESO DET NCORRS = 'Double '" Comparing "../../../../../fits-images/pg93/tst0013.fits" and "tst0013.fits" PASS Reading ../../../../../fits-images/ftt4b/file001.fits ../../../../../fits-images/ftt4b/file001.fits : 0 x 0, 1 channel, uint8 fits SHA-1: DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 channel list: A Extend: "T" Origin: "ESO" Object: "SNG - CAT." DateTime: "1984:05:27 00:00:00" Comparing "../../../../../fits-images/ftt4b/file001.fits" and "file001.fits" PASS Reading ../../../../../fits-images/ftt4b/file002.fits ../../../../../fits-images/ftt4b/file002.fits : 0 x 0, 1 channel, uint8 fits SHA-1: DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 channel list: A Extend: "T" Origin: "ESO" Object: "PGSNC - SN.CAT." DateTime: "1984:05:27 00:00:00" Comparing "../../../../../fits-images/ftt4b/file002.fits" and "file002.fits" PASS Reading ../../../../../fits-images/ftt4b/file003.fits ../../../../../fits-images/ftt4b/file003.fits : 512 x 512, 1 channel, uint16 fits SHA-1: 5CC4340F5D8AB2B776D2E12BFE946CA5CAFA38C6 channel list: A Extend: "T" Object: 3 Observer: "LISZ" Date-obs: 29 Date-map: 26 Bscale: 2.59397e-05 Bzero: 0.710747 Bunit: "JY/BEAM" Epoch: 1950 Blank: -32768 Obsra: 252.167 Obsdec: 5.07648 Datamax: 1.56066 Datamin: -0.139115 Ctype1: "RA---SIN" Crval1: 252.167 Cdelt1: -0.000305556 Crpix1: 256 Crota1: 0 Ctype2: "DEC--SIN" Crval2: 5.07648 Cdelt2: 0.000305556 Crpix2: 257 Crota2: 0 Ctype3: "FREQ" Crval3: 1420584192 Cdelt3: 293000 Crpix3: 1 Crota3: 0 Ctype4: "STOKES" Crval4: -1 Cdelt4: 1 Crpix4: 1 Crota4: 0 Origin: "AIPSNRAO node CVAX 15JUL84" DateTime: "1984:05:24 00:00:00" History: "/-------------------------------------------------------------------- /BEGIN "HISTORY" INFORMATION FOUND IN FITS TAPE HEADER BY IMLOD /---------------------------------------------------------------HISTORY /BEGIN "HISTORY" INFORMATION FOUND IN FITS TAPE HEADER BY UVLOD HISTORY / WHERE BASELINE = 256*ANT1 + ANT2 + (ARRAY#-1) UVLOD RELEASE='15NOV83 ' UVLOD OUTNAME='3C348-CONT ' OUTCLASS='UVTB ' UVLOD OUTSEQ= 1 OUTDISK= 2 HISTORY UVLOD SOURCE='3C348 ' QUAL= -1 BAND='L ' HISTORY UVLOD AIPS IMNAME='3C348-CONT ' IMCLASS='UVTB ' IMSEQ= 1 AIPS USERNO= 310 / WHERE T MEANS TIME (IAT) HISTORY / WHERE B MEANS BASELINE NUM AIPS WTSCAL = 2.64654192081E-02 /END FITS TAPE HEADER "HISTORY" INFORMATION HISTORY UVLOD RELEASE= '15MAY84 ' UVLOD OUTNAME=' ' OUTCLASS=' ' HISTORY UVLOD OUTSEQ= 1 OUTDISK= 3 HISTORY UVLOD TABNAME = 'AIPS AN' TABVER = 1 TABCOUNT= 28 TABWIDTH= 5 TABCARDS= 5 TTYPE1 = 'ANT NO. ' TTYPE2 = 'STATION ' TTYPE3 = 'LX ' TTYPE4 = 'LY ' TTYPE5 = 'LZ ' ASCAL RELEASE ='15MAR84 ' ASCAL INNAME='3C348-CONT ' INCLASS='UVTB ' HISTORY ASCAL INSEQ= 1 INDISK= 3 HISTORY ASCAL IN2NAME='3C348-CONT ' IN2CLASS='RCLN ' HISTORY ASCAL IN2SEQ= 102 IN2DISK= 3 ASCAL OUTNAME='3C348-CONT ' OUTCLASS='SCTB ' HISTORY ASCAL OUTSEQ= 102 OUTDISK= 3 HISTORY ASCAL NITER= 4001 VER= 1 ASCAL BLMIN= 0.100E+02 BLMAX= 0.100E+03 ASCAL REFANT= 0. MINANT= 3. ASCAL ASCAL APARM(7)= 2 ASCAL APARM(10)= 0.00 ASCAL ASCAL ASCAL ASCAL ASCAL UVSRT RELEASE ='15MAY84 ' UVSRT INNAME='3C348-CONT ' INCLASS='SCTB ' HISTORY UVSRT INSEQ= 102 INDISK= 3 HISTORY UVSRT OUTNAME='3C348-CONT ' OUTCLASS='SCXY ' HISTORY UVSRT OUTSEQ= 102 OUTDISK= 3 HISTORY UVSRT SORT = 'XY' AXDEF INNAME='3C348-CONT ' INCLASS='SCXY ' HISTORY AXDEF INSEQ= 102 INDISK= 3 AXDEF CTYPE2 = 'STOKES ' AXDEF CRVAL2 = -1.000000000E+00 AXDEF CDELT2 = -1.00000E+00 AXDEF CRPIX2 = 1.000 AXDEF CTYPE2 = 'FREQ ' AXDEF CRVAL2 = 1.420511000E+09 AXDEF CDELT2 = 1.46500E+05 AXDEF CRPIX2 = 1.000 AXDEF INNAME='3C348-CONT ' INCLASS='SCXY ' HISTORY AXDEF INSEQ= 102 INDISK= 3 HISTORY AXDEF CTYPE3 = 'FREQ ' AXDEF CRVAL3 = 1.420511000E+09 AXDEF CDELT3 = 4.90000E+04 AXDEF CRPIX3 = 1.000 AXDEF CTYPE3 = 'STOKES ' AXDEF CRVAL3 = -1.000000000E+00 AXDEF CDELT3 = -1.00000E+00 AXDEF CRPIX3 = 1.000 MX RELEASE ='15MAY84 ' MX OUTNAME='3C348-CONT ' OUTCLASS='RMAP ' HISTORY MX OUTSEQ= 103 OUTDISK= 3 MX SOURCE='3C348 ' HISTORY MX MX CHANNEL1= 1 NOCH= 1 MX ECHAN = 2 MX IMSIZE= 512, 512 MX BOX = 6 6 507 507 MX MAPFLD= 0.56320E+03, 0.56320E+03 MX CELLSIZE=-0.11000E+01, 0.11000E+01 MX FREQ= 0.1420584E+10 STOKES='R ' HISTORY MX SHIFT= 0.0000, 0.0000 HISTORY MX UVTAPER= 0.00000E+00, 0.00000E+00 MX UVRANGE= 0.00000E+00, 0.10000E+16 MX UVWTFN=' ' , UVBOX = 0 MX MX XTYPE = 5 XPARM = 0.30000E+01, 0.10000E+01, 0.00000E+0HISTORY MX , 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00 HISTORY MX , 0.00000E+00, 0.00000E+00, 0.00000E+00, HISTORY MX YTYPE = 5 YPARM = 0.30000E+01, 0.10000E+01, 0.00000E+0HISTORY MX , 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00 HISTORY MX , 0.00000E+00, 0.00000E+00, 0.00000E+00, HISTORY MX MX NITER = 0 MX GAIN = 0.1000 MX FACTOR = 0.00 MX FLUX = 0.00000E+00 MX BMAJS= 4.59602 BMINS= 4.39417 BPAD= -34.714 MX MINPATCH = 52 MX MX DOCAT = 0.00000 CNVRT INNAME='3C348-CONT ' INCLASS='RMAP ' HISTORY CNVRT INSEQ= 103 INDISK= 3 HISTORY APCLN RELEASE ='15MAY84 ' APCLN INNAME='3C348-CONT ' INCLASS='RMAP ' HISTORY APCLN INSEQ= 103 INDISK= 3 HISTORY APCLN IN2NAME='3C348-CONT ' IN2CLASS='RBEAM ' APCLN IN2SEQ= 103 IN2DISK= 3 HISTORY APCLN OUTNAME='3C348-CONT ' OUTCLASS='RESID ' HISTORY APCLN OUTSEQ= 103 OUTDISK= 3 HISTORY APCLN OUTVER = 1 APCLN NITER = 12000 APCLN BITER = 0 APCLN GAIN = 0.1000 APCLN FACTOR =-0.25 APCLN FLUX = 0.00000E+00 APCLN PHAT = 0.00000E+00 APCLN BMAJS= 4.59602 BMINS= 4.39417 BPAD= -34.714 APCLN NBOXES = 1 APCLN BOX( 1) = 123, 195, 392, 319 APCLN MINPATCH = 51 APCLN APCLN APCLN RENAM INNAME='3C348-CONT ' INCLASS='RESID ' HISTORY RENAM INSEQ= 103 INDISK= 3 HISTORY RENAM OUTNAME='3C348-CONT ' OUTCLASS='RCLN ' HISTORY RENAM OUTSEQ= 103 OUTDISK= 3 AIPS IMNAME='3C348-CONT ' IMCLASS='RCLN ' IMSEQ= 103 AIPS USERNO= 269 AIPS CLEAN BMAJ= 1.2767E-03 BMIN= 1.2206E-03 BPA= -34.71 HISTORY AIPS CLEAN NITER= 12000 PRODUCT=1 /END FITS TAPE HEADER "HISTORY" INFORMATION /-------------------------------------------------------------------- IMLOD OUTNAME ='3C348-CONT ' OUTCLASS ='RCLN ' IMLOD OUTSEQ = 1 INTAPE = 2 OUTDISK= 2 IMLOD RELEASE = '15MAY84 ' IMLOD IMLOD XTENSION= 'TABLE ' IMLOD NAXIS2 = 12000 IMLOD TFIELDS = 3 IMLOD EXTNAME = 'AIPS CC ' IMLOD EXTVER = 1 IMLOD EXTLEV = 1 IMLOD TTYPE1 = 'FLUX ' IMLOD TUNIT1 = 'JY ' IMLOD TTYPE2 = 'DELTAX ' IMLOD TUNIT2 = 'DEGREES ' IMLOD TTYPE3 = 'DELTAY ' IMLOD TUNIT3 = 'DEGREES ' CNVRT INNAME='3C348-CONT ' INCLASS='RCLN ' CNVRT INSEQ= 1 INDISK= 2 CNVRT INNAME='3C348-CONT ' INCLASS='RCLN ' CNVRT INSEQ= 1 INDISK= 2 CNVRT INNAME='3C348-CONT ' INCLASS='RCLN ' CNVRT INSEQ= 1 INDISK= 2 CNVRT INNAME='3C348-CONT ' INCLASS='RCLN ' CNVRT INSEQ= 1 INDISK= 2 CNVRT INNAME='3C348-CONT ' INCLASS='RCLN ' CNVRT INSEQ= 1 INDISK= 2 CNVRT INNAME='3C348-CONT ' INCLASS='RCLN ' CNVRT INSEQ= 1 INDISK= 2 AIPS IMNAME='3C348-CONT ' IMCLASS='RCLN ' IMSEQ= 1 AIPS USERNO= 545 AIPS CLEAN BMAJ= 1.2767E-03 BMIN= 1.2206E-03 BPA= -34.71 AIPS CLEAN NITER= 12000 PRODUCT=1" Comparing "../../../../../fits-images/ftt4b/file003.fits" and "file003.fits" PASS Reading ../../../../../fits-images/ftt4b/file009.fits ../../../../../fits-images/ftt4b/file009.fits : 0 x 0, 1 channel, uint16 fits SHA-1: DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 channel list: A Groups: "T" Pcount: 5 Gcount: 631 Bscale: 0.000244141 Bzero: 0 Bunit: "JY" Blank: -32768 Object: 742 Instrume: "VLA" Telescop: "VLA" Epoch: 1950 Observer: "BRID" Date-obs: 5 DateTime: "1980:04:12 00:00:00" Origin: "NRAO(CV) PGM=DUV2FITS(V1)" Ctype2: "COMPLEX" Crpix2: 1 Crval2: 1 Cdelt2: 1 Ctype3: "STOKES" Crpix3: 1 Crval3: 1 Cdelt3: 1 Ctype4: "FREQ" Crpix4: 1 Crval4: 4.8851e+09 Cdelt4: 0 Ctype5: "RA" Crpix5: 1 Crval5: 115.702 Cdelt5: 0 Ctype6: "DEC" Crpix6: 1 Crval6: 10.3091 Cdelt6: 0 Ptype1: "BASELINE" Pscal1: 1 Pzero1: 0 Ptype2: "HA" Pscal2: 0.00549316 Pzero2: 0 Ptype3: "UU" Pscal3: 4e-09 Pzero3: 0 Ptype4: "VV" Pscal4: 4e-09 Pzero4: 0 Ptype5: "WW" Pscal5: 4e-09 Pzero5: 0 Comment: "FORMULA FOR BASELINE # FROM ANTENNA PAIR I < J B = (256 * I) + J ANTENNA LOCATIONS IN NANOSECONDS: FORMULA FOR BASELINE BETWEEN ANTENNA I AND J (I < J): BASELINE(IJ) = LOCATION(I) - LOCATION(J) FORMULAE FOR UU, VV, WW : UU = BX * SIN(HA) + BY * COS(HA) VV = BZ * COS(DEC) + SIN(DEC) * (BY * SIN(HA) - BX * COS(HA)) WW = BZ * SIN(DEC) + COS(DEC) * (BX * COS(HA) - BY * SIN(HA))" History: "VLACV SORT ORDER='BH' VLACV ANT N= 2 X= 5470.525 Y=-14443.176 Z= -8061.210 ST='AW4' VLACV ANT N= 4 X= 1667.280 Y= -4396.334 Z= -2452.399 ST='CW8' VLACV ANT N= 5 X= 37.719 Y= 135.627 Z= -50.585 ST='DE2' VLACV ANT N= 6 X= 3353.710 Y= -8816.123 Z= -4910.700 ST='BW6' VLACV ANT N= 7 X= 118.761 Y= 445.786 Z= -170.397 ST='DE4' VLACV ANT N= 9 X= 10924.708 Y=-28961.684 Z=-16194.042 ST='AW6' VLACV ANT N=10 X= 73.382 Y= 271.952 Z= -103.200 ST='DE3' VLACV ANT N=12 X= 8324.926 Y= 31661.636 Z=-12190.700 ST='AE6' VLACV ANT N=14 X= 14206.476 Y=-37731.068 Z=-21114.612 ST='AW7' VLACV ANT N=15 X= 17842.852 Y=-47447.285 Z=-26566.649 ST='AW8' VLACV ANT N=16 X= 1548.048 Y= 5883.154 Z= -2264.541 ST='CE9' VLACV ANT N=17 X= 509.527 Y= -1338.539 Z= -745.231 ST='DW8' VLACV ANT N=18 X= 2552.452 Y= 9638.185 Z= -3698.873 ST='BE6' VLACV ANT N=20 X= -100.221 Y= -15.904 Z= 152.474 ST='DW2' VLACV ANT N=21 X= -812.570 Y= -126.899 Z= 1200.964 ST='DN8' VLACV ANT N=22 X= 1021.275 Y= -2683.726 Z= -1494.627 ST='CW6'" Comparing "../../../../../fits-images/ftt4b/file009.fits" and "file009.fits" PASS Reading ../../../../../fits-images/ftt4b/file012.fits ../../../../../fits-images/ftt4b/file012.fits : 513 x 513, 1 channel, uint16 fits SHA-1: 844CE9474D5C9E91154E41D7ED417173DE57286D channel list: A Tables: 1 Object: "M84" Observer: "LAIN" Date-obs: 16 Date-map: 9 Bscale: 2.85522e-06 Bzero: 0.0889426 Bunit: "JY/BEAM" Ctype1: "LL" Ctype2: "MM" Ctype3: "FREQ" Ctype4: "STOKES" Crval1: 185.631 Crval2: 13.1638 Crval3: 4.8851e+09 Crval4: 1 Cdelt1: -0.000277778 Cdelt2: 0.000277778 Cdelt3: 50000000 Cdelt4: 0 Crpix1: 257 Crpix2: 258 Crpix3: 1 Crpix4: 1 Crota1: 0 Crota2: 0 Crota3: 0 Crota4: 0 Epoch: 1950 Datamax: 0.18248 Datamin: -0.00459448 Origin: "AIPS" DateTime: "1982:09:02 00:00:00" History: "UVLOD UVLOD OUTNAME='M84 6 EC ' OUTCLASS='UVTB ' UVLOD OUTSEQ= 1 OUTDISK= 3 UVLOD SOURCE='M84 ' QUAL= -1 BAND='C ' UVLOD ASCAL ASCAL INNAME='M84 6 EC ' INCLASS='UVTB ' ASCAL INSEQ= 1 INDISK= 3 ASCAL IN2NAME='M84 6C EC ' IN2CLASS='ICLN ' ASCAL IN2SEQ= 1 IN2DISK= 3 ASCAL OUTNAME='M84 6C SC1 ' OUTCLASS='UVTB ' ASCAL OUTSEQ= 1 OUTDISK= 3 ASCAL NITER=12000 ASCAL BLMIN= 0.000E+00 BLMAX= 0.100E+11 ASCAL REFANT= 0. MINANT= 3. ASCAL ASCAL ASCAL ASCAL ASCAL ASCAL ASCAL ASCAL ASCAL INNAME='M84 6C SC1 ' INCLASS='UVTB ' ASCAL INSEQ= 1 INDISK= 3 ASCAL IN2NAME='M84 6C SC1 ' IN2CLASS='ICLN ' ASCAL IN2SEQ= 1 IN2DISK= 3 ASCAL OUTNAME='M84 6C SC2 ' OUTCLASS='UVTB ' ASCAL OUTSEQ= 1 OUTDISK= 3 ASCAL NITER=12000 ASCAL BLMIN= 0.000E+00 BLMAX= 0.100E+11 ASCAL REFANT= 0. MINANT= 3. ASCAL ASCAL ASCAL ASCAL ASCAL ASCAL RENAM INNAME='M84 6C SC2 ' INCLASS='UVTB ' RENAM INSEQ= 1 INDISK= 3 RENAM OUTNAME='M84 6C SC2 ' OUTCLASS='UV ' RENAM OUTSEQ= 1 OUTDISK= 3 UVSRT UVSRT INNAME='M84 6C SC2 ' INCLASS='UV ' UVSRT INSEQ= 1 INDISK= 3 UVSRT OUTNAME='M84 6C SC2 ' OUTCLASS='UVXY ' UVSRT OUTSEQ= 1 OUTDISK= 3 UVSRT SORT = 'XY' UVMAP UVMAP UVMAP OUTNAME='M84 6C SC2 ' OUTCLASS='IMAP ' UVMAP OUTSEQ= 1 OUTDISK= 3 UVMAP SOURCE='M84 ' UVMAP CHANNEL = 1 UVMAP UVMAP UVMAP IMSIZE= 1024, 1024 CENTER= 512, 513 UVMAP MAPFLD= 1024.00, 1024.00 UVMAP CELLSIZE= 1.00, 1.00 UVMAP FREQ= 0.4885100E+01 STOKES='I ' UVMAP SHIFT= 0.0000, 0.0000 UVMAP UVTAPER= 0.00000E+00, 0.00000E+00 UVMAP UVRANGE= 0.00000E+00, 0.10000E+11 UVMAP UVWTFN=' ' , UVBOX = 0 UVMAP WTZSP=30.000 UVMAP ZEROSP= 2.840, 0.000, 0.000, 0.000 UVMAP UVMAP XTYPE = 4 XPARM = 0.30000E+01, 0.15500E+01, 0.25200E+01 UVMAP , 0.20000E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00 UVMAP , 0.00000E+00, 0.00000E+00, 0.00000E+00, UVMAP YTYPE = 4 YPARM = 0.30000E+01, 0.15500E+01, 0.25200E+01 UVMAP , 0.20000E+01, 0.00000E+00, 0.00000E+00, 0.00000E+00 UVMAP , 0.00000E+00, 0.00000E+00, 0.00000E+00, UVMAP DOGRIDCR = 1 UVMAP APCLN APCLN INNAME='M84 6C SC2 ' INCLASS='IMAP ' APCLN INSEQ= 1 INDISK= 3 APCLN IN2NAME='M84 6C SC2 ' IN2CLASS='IBEM ' APCLN IN2SEQ= 1 IN2DISK= 3 APCLN OUTNAME='M84 6C SC2 ' OUTCLASS='ICLN ' APCLN OUTSEQ= 1 OUTDISK= 3 APCLN OUTVER = 1 APCLN NITER = 12000 APCLN BITER = 0 APCLN GAIN = 0.3000 APCLN FACTOR = 0.00 APCLN FLUX = 0.00000E+00 APCLN BMAJS= 3.881 BMINS= 3.848 BPAD= -34.453 APCLN NBOXES = 1 APCLN BOX( 1) = 420, 410, 560, 590 APCLN MINPATCH = 127 APCLN APCLN AIPS IMNAME='M84 6C SC2 ' IMCLASS='ICLN ' IMSEQ= 1 AIPS USERNO= 504 AIPS CLEAN BMAJ= 0.1078E-02 BMIN= 0.1067E-02 BPA= -34.45 AIPS CLEAN NITER= 12000 PRODUCT=1" Comparing "../../../../../fits-images/ftt4b/file012.fits" and "file012.fits" PASS openimageio-1.3.12~dfsg0.orig/testsuite/fits/run.py0000755000175000017500000000107612271062644020504 0ustar mfvmfv#!/usr/bin/python # ../fits-image/pg93: # tst0001.fits to tst0014.fits imagedir = parent + "/fits-images/pg93" files = [ "tst0001.fits", "tst0002.fits", "tst0003.fits", "tst0005.fits", "tst0006.fits", "tst0007.fits", "tst0008.fits", #FIXME? "tst0009.fits", "tst0013.fits" ] for f in files : command += rw_command (imagedir, f) imagedir = parent + "/fits-images/ftt4b" files = [ "file001.fits", "file002.fits", "file003.fits", "file009.fits", "file012.fits" ] for f in files : command += rw_command (imagedir, f) openimageio-1.3.12~dfsg0.orig/testsuite/openexr-multires/0000755000175000017500000000000012271062644021674 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/openexr-multires/ref/0000755000175000017500000000000012271062644022450 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/openexr-multires/ref/out.txt0000644000175000017500000002351312271062644024024 0ustar mfvmfvReading ../../../../../openexr-images/MultiResolution/Bonita.exr ../../../../../openexr-images/MultiResolution/Bonita.exr : 550 x 832, 3 channel, half openexr MIP-map levels: 550x832 275x416 137x208 68x104 34x52 17x26 8x13 4x6 2x3 1x1 SHA-1: 564202D0616E02C51CBAD01C4FC34A3D5D77861C channel list: R, G, B tile size: 128 x 128 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "Plain Texture" compression: "zip" ImageDescription: "Point Bonita, Marin County, California" Copyright: "Copyright 2004 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 wrapmodes: "clamp,clamp" Comparing "../../../../../openexr-images/MultiResolution/Bonita.exr" and "Bonita.exr" PASS Reading ../../../../../openexr-images/MultiResolution/ColorCodedLevels.exr ../../../../../openexr-images/MultiResolution/ColorCodedLevels.exr : 512 x 512, 4 channel, half openexr MIP-map levels: 512x512 256x256 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 3694F36696BA49FBA37BC7D35E7ACB2DFDDED2EC channel list: R, G, B, A tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "Plain Texture" compression: "pxr24" ImageDescription: "a mip-map image with color-coded levels" Copyright: "Copyright 2005 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 wrapmodes: "periodic,periodic" Comparing "../../../../../openexr-images/MultiResolution/ColorCodedLevels.exr" and "ColorCodedLevels.exr" PASS Reading ../../../../../openexr-images/MultiResolution/KernerEnvCube.exr ../../../../../openexr-images/MultiResolution/KernerEnvCube.exr : 256 x 1536, 4 channel, half openexr MIP-map levels: 256x1536 128x768 64x384 32x192 16x96 8x48 4x24 2x12 1x6 1x3 1x1 SHA-1: FE90067A116E33C65D2C663C1A19ABCCE2C621A4 channel list: R, G, B, A full/display size: 256 x 256 full/display origin: 0, 0 tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "CubeFace Environment" oiio:sampleborder: 1 compression: "zip" Copyright: "Copyright 2005 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/MultiResolution/KernerEnvCube.exr" and "KernerEnvCube.exr" PASS Reading ../../../../../openexr-images/MultiResolution/KernerEnvLatLong.exr ../../../../../openexr-images/MultiResolution/KernerEnvLatLong.exr : 1024 x 512, 4 channel, half openexr MIP-map levels: 1024x512 512x256 256x128 128x64 64x32 32x16 16x8 8x4 4x2 2x1 1x1 SHA-1: 10D3B289F5E6E0497AC5C297373BEEEEA4F7EEA4 channel list: R, G, B, A tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "LatLong Environment" oiio:updirection: "y" oiio:sampleborder: 1 compression: "zip" Copyright: "Copyright 2005 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/MultiResolution/KernerEnvLatLong.exr" and "KernerEnvLatLong.exr" PASS Reading ../../../../../openexr-images/MultiResolution/MirrorPattern.exr ../../../../../openexr-images/MultiResolution/MirrorPattern.exr : 512 x 512, 3 channel, half openexr MIP-map levels: 512x512 256x256 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 1E48D1639C572C689EE82ACA93EEE9FC9EFB24EB channel list: R, G, B tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "Plain Texture" compression: "zip" Copyright: "Copyright 2004 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 wrapmodes: "mirror,mirror" Comparing "../../../../../openexr-images/MultiResolution/MirrorPattern.exr" and "MirrorPattern.exr" PASS Reading ../../../../../openexr-images/MultiResolution/OrientationCube.exr ../../../../../openexr-images/MultiResolution/OrientationCube.exr : 512 x 3072, 4 channel, half openexr MIP-map levels: 512x3072 256x1536 128x768 64x384 32x192 16x96 8x48 4x24 2x12 1x6 1x3 1x1 SHA-1: 06D36508E3D76F3288D6B50867812CC6E29C3C5A channel list: R, G, B, A full/display size: 512 x 512 full/display origin: 0, 0 tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "CubeFace Environment" oiio:sampleborder: 1 compression: "zip" Copyright: "Copyright 2005 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/MultiResolution/OrientationCube.exr" and "OrientationCube.exr" PASS Reading ../../../../../openexr-images/MultiResolution/OrientationLatLong.exr ../../../../../openexr-images/MultiResolution/OrientationLatLong.exr : 1024 x 512, 4 channel, half openexr MIP-map levels: 1024x512 512x256 256x128 128x64 64x32 32x16 16x8 8x4 4x2 2x1 1x1 SHA-1: 91BB1952FB9254759FA0629F40A721C6D461C8FC channel list: R, G, B, A tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "LatLong Environment" oiio:updirection: "y" oiio:sampleborder: 1 compression: "zip" Copyright: "Copyright 2005 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/MultiResolution/OrientationLatLong.exr" and "OrientationLatLong.exr" PASS Reading ../../../../../openexr-images/MultiResolution/PeriodicPattern.exr ../../../../../openexr-images/MultiResolution/PeriodicPattern.exr : 517 x 517, 3 channel, half openexr MIP-map levels: 517x517 258x258 129x129 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: B83B67E1FF9B24991A6582C997AA9F629C094ED2 channel list: R, G, B tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "Plain Texture" compression: "zip" Copyright: "Copyright 2004 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 wrapmodes: "periodic,periodic" Comparing "../../../../../openexr-images/MultiResolution/PeriodicPattern.exr" and "PeriodicPattern.exr" PASS Reading ../../../../../openexr-images/MultiResolution/StageEnvCube.exr ../../../../../openexr-images/MultiResolution/StageEnvCube.exr : 256 x 1536, 3 channel, half openexr MIP-map levels: 256x1536 128x768 64x384 32x192 16x96 8x48 4x24 2x12 1x6 1x3 1x1 SHA-1: 12BC1AA3805E1D718263F3118BD3366013E13B97 channel list: R, G, B full/display size: 256 x 256 full/display origin: 0, 0 tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "CubeFace Environment" oiio:sampleborder: 1 compression: "zip" Copyright: "Copyright 2004 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/MultiResolution/StageEnvCube.exr" and "StageEnvCube.exr" PASS Reading ../../../../../openexr-images/MultiResolution/StageEnvLatLong.exr ../../../../../openexr-images/MultiResolution/StageEnvLatLong.exr : 1000 x 500, 3 channel, half openexr MIP-map levels: 1000x500 500x250 250x125 125x63 63x32 32x16 16x8 8x4 4x2 2x1 1x1 SHA-1: 573137DBE0076465729FC3DBE2B586A19330515D channel list: R, G, B tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 1 textureformat: "LatLong Environment" oiio:updirection: "y" oiio:sampleborder: 1 compression: "zip" Copyright: "Copyright 2004 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/MultiResolution/StageEnvLatLong.exr" and "StageEnvLatLong.exr" PASS Reading ../../../../../openexr-images/MultiResolution/WavyLinesCube.exr ../../../../../openexr-images/MultiResolution/WavyLinesCube.exr : 256 x 1536, 3 channel, half openexr MIP-map levels: 256x1536 128x768 64x384 32x192 16x96 8x48 4x24 2x12 1x6 1x3 1x1 SHA-1: 2B90F593D0F4188F341438C097DC447D0B4C4A9B channel list: R, G, B full/display size: 256 x 256 full/display origin: 0, 0 tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "CubeFace Environment" oiio:sampleborder: 1 compression: "zip" Copyright: "Copyright 2005 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/MultiResolution/WavyLinesCube.exr" and "WavyLinesCube.exr" PASS Reading ../../../../../openexr-images/MultiResolution/WavyLinesLatLong.exr ../../../../../openexr-images/MultiResolution/WavyLinesLatLong.exr : 1024 x 512, 3 channel, half openexr MIP-map levels: 1024x512 512x256 256x128 128x64 64x32 32x16 16x8 8x4 4x2 2x1 1x1 SHA-1: D7CB49482CFB4D2854089E7FF92690F69337DED0 channel list: R, G, B tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "LatLong Environment" oiio:updirection: "y" oiio:sampleborder: 1 compression: "zip" Copyright: "Copyright 2005 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/MultiResolution/WavyLinesLatLong.exr" and "WavyLinesLatLong.exr" PASS Reading ../../../../../openexr-images/MultiResolution/WavyLinesSphere.exr ../../../../../openexr-images/MultiResolution/WavyLinesSphere.exr : 480 x 480, 4 channel, half openexr SHA-1: E802DC23DA0EEF8EE782CC5D7BA56294C0FA7462 channel list: R, G, B, A oiio:ColorSpace: "Linear" compression: "piz" Copyright: "Copyright 2005 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/MultiResolution/WavyLinesSphere.exr" and "WavyLinesSphere.exr" PASS openimageio-1.3.12~dfsg0.orig/testsuite/openexr-multires/run.py0000755000175000017500000000163412271062644023061 0ustar mfvmfv#!/usr/bin/python # ../openexr-images/MultiResolution: # Bonita.exr MirrorPattern.exr StageEnvCube.exr # ColorCodedLevels.exr OrientationCube.exr StageEnvLatLong.exr # Kapaa.exr OrientationLatLong.exr WavyLinesCube.exr # KernerEnvCube.exr PeriodicPattern.exr WavyLinesLatLong.exr # KernerEnvLatLong.exr README WavyLinesSphere.exr imagedir = parent + "/openexr-images/MultiResolution" files = [ "Bonita.exr", "ColorCodedLevels.exr", # FIXME -- we don't know how to deal with RIP-maps -- Kapaa, "KernerEnvCube.exr", "KernerEnvLatLong.exr", "MirrorPattern.exr", "OrientationCube.exr", "OrientationLatLong.exr", "PeriodicPattern.exr", "StageEnvCube.exr", "StageEnvLatLong.exr", "WavyLinesCube.exr", "WavyLinesLatLong.exr", "WavyLinesSphere.exr" ] for f in files: command += rw_command (imagedir, f) openimageio-1.3.12~dfsg0.orig/testsuite/rla/0000755000175000017500000000000012271062644017130 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/rla/ref/0000755000175000017500000000000012271062644017704 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/rla/ref/out.txt0000644000175000017500000002517612271062644021267 0ustar mfvmfvReading ../../../../../oiio-images/ginsu_a_nc10.rla ../../../../../oiio-images/ginsu_a_nc10.rla : 512 x 512, 4 channel, uint10 rla SHA-1: 2732EF8B7515349C6FB6C8D9B678D9968E304AE3 channel list: R, G, B, A oiio:BitsPerSample: 10 compression: "rle" DateTime: "2011:06:01 15:17:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "a_nc10.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_a_nc10.rla" and "ginsu_a_nc10.rla" PASS Reading ../../../../../oiio-images/ginsu_a_ncf.rla ../../../../../oiio-images/ginsu_a_ncf.rla : 512 x 512, 4 channel, float rla SHA-1: 10419E1D3AFFDE7F351BFA9ABF96F8C18527BE5D channel list: R, G, B, A oiio:BitsPerSample: 32 compression: "rle" DateTime: "2011:06:01 15:17:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "a_ncf.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_a_ncf.rla" and "ginsu_a_ncf.rla" PASS Reading ../../../../../oiio-images/ginsu_rgba_nc8.rla ../../../../../oiio-images/ginsu_rgba_nc8.rla : 512 x 512, 4 channel, uint8 rla SHA-1: 030CF1F960E9585D2F6A1173B86034BC15C26C41 channel list: R, G, B, A oiio:BitsPerSample: 8 compression: "rle" DateTime: "2011:06:01 15:15:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "rgba_nc8.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_rgba_nc8.rla" and "ginsu_rgba_nc8.rla" PASS Reading ../../../../../oiio-images/ginsu_rgb_nc16.rla ../../../../../oiio-images/ginsu_rgb_nc16.rla : 512 x 512, 3 channel, uint16 rla SHA-1: B31B6515AA9BD09C8CFFCB242C1E7D5D130CA923 channel list: R, G, B oiio:BitsPerSample: 16 compression: "rle" DateTime: "2011:06:01 15:16:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "rgb_nc16.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_rgb_nc16.rla" and "ginsu_rgb_nc16.rla" PASS Reading ../../../../../oiio-images/imgmake_rgba_nc10.rla ../../../../../oiio-images/imgmake_rgba_nc10.rla : 512 x 512, 4 channel, uint10 rla SHA-1: 12F22B420DDB3D330092A38AF48F9A225467EC6E channel list: R, G, B, A oiio:BitsPerSample: 10 compression: "rle" rla:FrameNumber: 1 rla:FileName: "imgmake_rgba_nc10.rla" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:Aspect: " 1.333" rla:ColorChannel: "rgb" oiio:ColorSpace: "Linear" rla:RedChroma: 0.67 0.67 0.33 rla:GreenChroma: 0.21 0.21 0.71 rla:BlueChroma: 0.14 0.14 0.08 rla:WhitePoint: 0.31 0.31 0.316 Comparing "../../../../../oiio-images/imgmake_rgba_nc10.rla" and "imgmake_rgba_nc10.rla" PASS Reading ../../../../../oiio-images/ginsu_a_nc16.rla ../../../../../oiio-images/ginsu_a_nc16.rla : 512 x 512, 4 channel, uint16 rla SHA-1: 476760230A4F7540072865C0E01CC6417EA9EC3E channel list: R, G, B, A oiio:BitsPerSample: 16 compression: "rle" DateTime: "2011:06:01 15:17:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "a_nc16.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_a_nc16.rla" and "ginsu_a_nc16.rla" PASS Reading ../../../../../oiio-images/ginsu_rgba_nc10.rla ../../../../../oiio-images/ginsu_rgba_nc10.rla : 512 x 512, 4 channel, uint10 rla SHA-1: 12F22B420DDB3D330092A38AF48F9A225467EC6E channel list: R, G, B, A oiio:BitsPerSample: 10 compression: "rle" DateTime: "2011:06:01 15:16:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "rgba_nc10.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_rgba_nc10.rla" and "ginsu_rgba_nc10.rla" PASS Reading ../../../../../oiio-images/ginsu_rgba_ncf.rla ../../../../../oiio-images/ginsu_rgba_ncf.rla : 512 x 512, 4 channel, float rla SHA-1: 43EB1CE263C8FC4630AEE68E34139C02A13F506D channel list: R, G, B, A oiio:BitsPerSample: 32 compression: "rle" DateTime: "2011:06:01 15:17:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "rgba_ncf.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_rgba_ncf.rla" and "ginsu_rgba_ncf.rla" PASS Reading ../../../../../oiio-images/ginsu_rgb_nc8.rla ../../../../../oiio-images/ginsu_rgb_nc8.rla : 512 x 512, 3 channel, uint8 rla SHA-1: CB23AB13150BBD29947E65434E174D76C0324E7D channel list: R, G, B oiio:BitsPerSample: 8 compression: "rle" DateTime: "2011:06:01 15:16:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "rgb_nc8.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_rgb_nc8.rla" and "ginsu_rgb_nc8.rla" PASS Reading ../../../../../oiio-images/imgmake_rgba_nc16.rla ../../../../../oiio-images/imgmake_rgba_nc16.rla : 512 x 512, 4 channel, uint16 rla SHA-1: C1E653EAAFABEE98913D9B485CADAA50EF5731B2 channel list: R, G, B, A oiio:BitsPerSample: 16 compression: "rle" rla:FrameNumber: 1 rla:FileName: "imgmake_rgba_nc16.rla" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:Aspect: " 1.333" rla:ColorChannel: "rgb" oiio:ColorSpace: "Linear" rla:RedChroma: 0.67 0.67 0.33 rla:GreenChroma: 0.21 0.21 0.71 rla:BlueChroma: 0.14 0.14 0.08 rla:WhitePoint: 0.31 0.31 0.316 Comparing "../../../../../oiio-images/imgmake_rgba_nc16.rla" and "imgmake_rgba_nc16.rla" PASS Reading ../../../../../oiio-images/ginsu_a_nc8.rla ../../../../../oiio-images/ginsu_a_nc8.rla : 512 x 512, 4 channel, uint8 rla SHA-1: B96EF7B8A3B5328312BE6EA090A408681C423A00 channel list: R, G, B, A oiio:BitsPerSample: 8 compression: "rle" DateTime: "2011:06:01 15:17:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "a_nc8.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_a_nc8.rla" and "ginsu_a_nc8.rla" PASS Reading ../../../../../oiio-images/ginsu_rgba_nc16.rla ../../../../../oiio-images/ginsu_rgba_nc16.rla : 512 x 512, 4 channel, uint16 rla SHA-1: C1E653EAAFABEE98913D9B485CADAA50EF5731B2 channel list: R, G, B, A oiio:BitsPerSample: 16 compression: "rle" DateTime: "2011:06:01 15:16:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "rgba_nc16.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_rgba_nc16.rla" and "ginsu_rgba_nc16.rla" PASS Reading ../../../../../oiio-images/ginsu_rgb_nc10.rla ../../../../../oiio-images/ginsu_rgb_nc10.rla : 512 x 512, 3 channel, uint10 rla SHA-1: CF6AE7239E7F8FEE3D44BD6D6FE907642938B471 channel list: R, G, B oiio:BitsPerSample: 10 compression: "rle" DateTime: "2011:06:01 15:16:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "rgb_nc10.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_rgb_nc10.rla" and "ginsu_rgb_nc10.rla" PASS Reading ../../../../../oiio-images/ginsu_rgb_ncf.rla ../../../../../oiio-images/ginsu_rgb_ncf.rla : 512 x 512, 3 channel, float rla SHA-1: B5499846C3D45BF41351BC7A7338E9A31DD883AD channel list: R, G, B oiio:BitsPerSample: 32 compression: "rle" DateTime: "2011:06:01 15:17:00" rla:FrameNumber: 1 rla:JobNumber: 1 rla:FileName: "rgb_ncf.rla" Software: "IMGLIB" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:ColorChannel: "rgb" PixelAspectRatio: 1 rla:RedChroma: 0.67 0.33 rla:GreenChroma: 0.21 0.71 rla:BlueChroma: 0.14 0.08 rla:WhitePoint: 0.31 0.316 Comparing "../../../../../oiio-images/ginsu_rgb_ncf.rla" and "ginsu_rgb_ncf.rla" PASS Reading ../../../../../oiio-images/imgmake_rgba_nc8.rla ../../../../../oiio-images/imgmake_rgba_nc8.rla : 512 x 512, 4 channel, uint8 rla SHA-1: 030CF1F960E9585D2F6A1173B86034BC15C26C41 channel list: R, G, B, A oiio:BitsPerSample: 8 compression: "rle" rla:FrameNumber: 1 rla:FileName: "imgmake_rgba_nc8.rla" HostComputer: "hawk073.spimageworks.com" Artist: "jeremys" rla:Aspect: " 1.333" rla:ColorChannel: "rgb" oiio:ColorSpace: "Linear" rla:RedChroma: 0.67 0.67 0.33 rla:GreenChroma: 0.21 0.21 0.71 rla:BlueChroma: 0.14 0.14 0.08 rla:WhitePoint: 0.31 0.31 0.316 Comparing "../../../../../oiio-images/imgmake_rgba_nc8.rla" and "imgmake_rgba_nc8.rla" PASS openimageio-1.3.12~dfsg0.orig/testsuite/rla/run.py0000755000175000017500000000075212271062644020315 0ustar mfvmfv#!/usr/bin/python imagedir = parent + "/oiio-images" files = [ "ginsu_a_nc10.rla", "ginsu_a_ncf.rla", "ginsu_rgba_nc8.rla", "ginsu_rgb_nc16.rla", "imgmake_rgba_nc10.rla", "ginsu_a_nc16.rla", "ginsu_rgba_nc10.rla", "ginsu_rgba_ncf.rla", "ginsu_rgb_nc8.rla", "imgmake_rgba_nc16.rla", "ginsu_a_nc8.rla", "ginsu_rgba_nc16.rla", "ginsu_rgb_nc10.rla", "ginsu_rgb_ncf.rla", "imgmake_rgba_nc8.rla" ] for f in files: command += rw_command (imagedir, f) openimageio-1.3.12~dfsg0.orig/testsuite/targa-tgautils/0000755000175000017500000000000012271062644021302 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/targa-tgautils/ref/0000755000175000017500000000000012271062644022056 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/targa-tgautils/ref/out.txt0000644000175000017500000001552712271062644023440 0ustar mfvmfvReading ../../../../../TGAUTILS/CBW8.TGA ../../../../../TGAUTILS/CBW8.TGA : 128 x 128, 1 channel, uint8 targa SHA-1: E157488A1D82536C6CC5F38CA2BF3CAA397BE69A channel list: A oiio:BitsPerSample: 8 compression: "rle" targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 8 bit run length compressed black and white image" DateTime: "1990:03:24 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 2.0" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 1 thumbnail_image: 76, 76, 76, 76, 149, 149, 149, 149, 178, 178, 178, 178, 0, 0, 0, 0, ... Comparing "../../../../../TGAUTILS/CBW8.TGA" and "CBW8.TGA" PASS Reading ../../../../../TGAUTILS/CCM8.TGA ../../../../../TGAUTILS/CCM8.TGA : 128 x 128, 3 channel, uint2 targa SHA-1: C3CFE6424C5A9D88BB212BFE230F5B9875F434C4 channel list: R, G, B oiio:BitsPerSample: 2 compression: "rle" targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 8 bit run length compressed color mapped image" DateTime: "1990:03:24 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 2.0" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 3 thumbnail_image: 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, ... Comparing "../../../../../TGAUTILS/CCM8.TGA" and "CCM8.TGA" PASS Reading ../../../../../TGAUTILS/CTC16.TGA ../../../../../TGAUTILS/CTC16.TGA : 128 x 128, 3 channel, uint5 targa SHA-1: C3CFE6424C5A9D88BB212BFE230F5B9875F434C4 channel list: R, G, B oiio:BitsPerSample: 5 compression: "rle" targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 16 bit run length compressed true color image" DateTime: "1990:03:24 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 2.0" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 3 thumbnail_image: 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, ... Comparing "../../../../../TGAUTILS/CTC16.TGA" and "CTC16.TGA" PASS Reading ../../../../../TGAUTILS/CTC24.TGA ../../../../../TGAUTILS/CTC24.TGA : 128 x 128, 3 channel, uint8 targa SHA-1: C3CFE6424C5A9D88BB212BFE230F5B9875F434C4 channel list: R, G, B oiio:BitsPerSample: 8 compression: "rle" targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 24 bit run length compressed true color image" DateTime: "1990:03:24 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 2.0" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 3 thumbnail_image: 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, ... Comparing "../../../../../TGAUTILS/CTC24.TGA" and "CTC24.TGA" PASS Reading ../../../../../TGAUTILS/CTC32.TGA ../../../../../TGAUTILS/CTC32.TGA : 128 x 128, 4 channel, uint8 targa SHA-1: 1ADC95BEBE9EEA8C112D40CD04AB7A8D75C4F961 channel list: R, G, B, A oiio:BitsPerSample: 8 compression: "rle" targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 32 bit run length compressed true color image" DateTime: "1990:03:24 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 2.0" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 4 thumbnail_image: 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, ... Comparing "../../../../../TGAUTILS/CTC32.TGA" and "CTC32.TGA" PASS Reading ../../../../../TGAUTILS/UBW8.TGA ../../../../../TGAUTILS/UBW8.TGA : 128 x 128, 1 channel, uint8 targa SHA-1: E157488A1D82536C6CC5F38CA2BF3CAA397BE69A channel list: A oiio:BitsPerSample: 8 targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 8 bit uncompressed black and white image" DateTime: "1990:02:23 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 1.30" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 1 thumbnail_image: 76, 76, 76, 76, 149, 149, 149, 149, 178, 178, 178, 178, 0, 0, 0, 0, ... Comparing "../../../../../TGAUTILS/UBW8.TGA" and "UBW8.TGA" PASS Reading ../../../../../TGAUTILS/UCM8.TGA ../../../../../TGAUTILS/UCM8.TGA : 128 x 128, 3 channel, uint2 targa SHA-1: C3CFE6424C5A9D88BB212BFE230F5B9875F434C4 channel list: R, G, B oiio:BitsPerSample: 2 targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 8 bit uncompressed color mapped image" DateTime: "1990:02:24 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 1.40" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 3 thumbnail_image: 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, ... Comparing "../../../../../TGAUTILS/UCM8.TGA" and "UCM8.TGA" PASS Reading ../../../../../TGAUTILS/UTC16.TGA ../../../../../TGAUTILS/UTC16.TGA : 128 x 128, 3 channel, uint5 targa SHA-1: C3CFE6424C5A9D88BB212BFE230F5B9875F434C4 channel list: R, G, B oiio:BitsPerSample: 5 targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 16 bit uncompressed true color image" DateTime: "1990:02:23 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 1.30" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 3 thumbnail_image: 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, ... Comparing "../../../../../TGAUTILS/UTC16.TGA" and "UTC16.TGA" PASS Reading ../../../../../TGAUTILS/UTC24.TGA ../../../../../TGAUTILS/UTC24.TGA : 128 x 128, 3 channel, uint8 targa SHA-1: C3CFE6424C5A9D88BB212BFE230F5B9875F434C4 channel list: R, G, B oiio:BitsPerSample: 8 targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 24 bit uncompressed true color image" DateTime: "1990:02:24 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 1.40" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 3 thumbnail_image: 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, ... Comparing "../../../../../TGAUTILS/UTC24.TGA" and "UTC24.TGA" PASS Reading ../../../../../TGAUTILS/UTC32.TGA ../../../../../TGAUTILS/UTC32.TGA : 128 x 128, 4 channel, uint8 targa SHA-1: 1ADC95BEBE9EEA8C112D40CD04AB7A8D75C4F961 channel list: R, G, B, A oiio:BitsPerSample: 8 targa:ImageID: "Truevision(R) Sample Image" Artist: "Ricky True" ImageDescription: "Sample 32 bit uncompressed true color image" DateTime: "1990:02:24 10:00:00" DocumentName: "TGA Utilities" Software: "TGAEdit 1.40" thumbnail_width: 64 thumbnail_height: 64 thumbnail_nchannels: 4 thumbnail_image: 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, ... Comparing "../../../../../TGAUTILS/UTC32.TGA" and "UTC32.TGA" PASS openimageio-1.3.12~dfsg0.orig/testsuite/targa-tgautils/run.py0000755000175000017500000000037712271062644022472 0ustar mfvmfv#!/usr/bin/python imagedir = parent + "/TGAUTILS" files = [ "CBW8.TGA", "CCM8.TGA", "CTC16.TGA", "CTC24.TGA", "CTC32.TGA", "UBW8.TGA", "UCM8.TGA", "UTC16.TGA", "UTC24.TGA", "UTC32.TGA" ] for f in files: command += rw_command (imagedir, f) openimageio-1.3.12~dfsg0.orig/testsuite/misnamed-file/0000755000175000017500000000000012271062644021064 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/misnamed-file/ref/0000755000175000017500000000000012271062644021640 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/misnamed-file/ref/out.txt0000644000175000017500000000110312271062644023203 0ustar mfvmfvReading misnamed.exr misnamed.exr : 1000 x 1000, 4 channel, uint8 tiff SHA-1: 97D6548FF9E9BFD21424B773B1D84FACDF0C1797 channel list: R, G, B, A oiio:BitsPerSample: 8 Orientation: 1 (normal) XResolution: 72 YResolution: 72 ResolutionUnit: "in" Software: "GraphicsMagick 1.3.6 2009-07-25 Q8 http://www.GraphicsMagick.org/" DocumentName: "g.tif" tiff:PageNumber: 0 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" tiff:RowsPerStrip: 8 openimageio-1.3.12~dfsg0.orig/testsuite/misnamed-file/run.py0000755000175000017500000000035712271062644022252 0ustar mfvmfv#!/usr/bin/python import shutil # Make a copy called "misnamed.exr" that's actually a TIFF file shutil.copyfile (parent+"/oiio-images/grid.tif", "misnamed.exr") # Now see if it is read correctly command = info_command ("misnamed.exr") openimageio-1.3.12~dfsg0.orig/testsuite/python-roi/0000755000175000017500000000000012271062644020462 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/python-roi/ref/0000755000175000017500000000000012271062644021236 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/python-roi/ref/out.txt0000644000175000017500000000135612271062644022613 0ustar mfvmfvROI() = -2147483648 0 0 0 0 0 0 0 r.defined = False ROI(0, 640, 100, 200) = 0 640 100 200 0 1 0 10000 ROI(0, 640, 100, 480, 0, 1, 0, 4) = 0 640 0 480 0 1 0 4 r.xbegin = 0 r.xend = 640 r.ybegin = 0 r.yend = 480 r.zbegin = 0 r.zend = 1 r.chbegin = 0 r.chend = 4 r.defined = True r.width = 640 r.height = 480 r.depth = 1 r.nchannels = 4 r.npixels = 307200 ROI.All = -2147483648 0 0 0 0 0 0 0 r == r2 (expect yes): True r != r2 (expect no): False r == r3 (expect no): False r != r3 (expect yes): True A = 0 10 0 8 0 1 0 4 B = 5 15 -1 10 0 1 0 4 ROI.union(A,B) = 0 15 -1 10 0 1 0 4 ROI.intersection(A,B) = 5 10 0 8 0 1 0 4 Spec's roi is 0 640 0 480 0 1 0 3 After set, roi is 3 5 7 9 0 1 0 3 After set, roi_full is 13 15 17 19 0 1 0 3 Done. openimageio-1.3.12~dfsg0.orig/testsuite/python-roi/run.py0000755000175000017500000000010312271062644021635 0ustar mfvmfv#!/usr/bin/env python command += "python test_roi.py > out.txt" openimageio-1.3.12~dfsg0.orig/testsuite/python-roi/test_roi.py0000755000175000017500000000344212271062644022672 0ustar mfvmfv#!/usr/bin/env python import OpenImageIO as oiio ###################################################################### # main test starts here try: r = oiio.ROI() print "ROI() =", r print "r.defined =", r.defined r = oiio.ROI (0, 640, 100, 200) print "ROI(0, 640, 100, 200) =", r r = oiio.ROI (0, 640, 0, 480, 0, 1, 0, 4) print "ROI(0, 640, 100, 480, 0, 1, 0, 4) =", r print "r.xbegin =", r.xbegin print "r.xend =", r.xend print "r.ybegin =", r.ybegin print "r.yend =", r.yend print "r.zbegin =", r.zbegin print "r.zend =", r.zend print "r.chbegin =", r.chbegin print "r.chend =", r.chend print "r.defined = ", r.defined print "r.width = ", r.width print "r.height = ", r.height print "r.depth = ", r.depth print "r.nchannels = ", r.nchannels print "r.npixels = ", r.npixels print print "ROI.All =", oiio.ROI.All print r2 = oiio.ROI(r) r3 = oiio.ROI(r) r3.xend = 320 print "r == r2 (expect yes): ", (r == r2) print "r != r2 (expect no): ", (r != r2) print "r == r3 (expect no): ", (r == r3) print "r != r3 (expect yes): ", (r != r3) print A = oiio.ROI (0, 10, 0, 8, 0, 1, 0, 4) B = oiio.ROI (5, 15, -1, 10, 0, 1, 0, 4) print "A =", A print "B =", B print "ROI.union(A,B) =", oiio.union(A,B) print "ROI.intersection(A,B) =", oiio.intersection(A,B) print spec = oiio.ImageSpec(640, 480, 3, oiio.UINT8) print "Spec's roi is", oiio.get_roi(spec) oiio.set_roi (spec, oiio.ROI(3, 5, 7, 9)) oiio.set_roi_full (spec, oiio.ROI(13, 15, 17, 19)) print "After set, roi is", oiio.get_roi(spec) print "After set, roi_full is", oiio.get_roi_full(spec) print print "Done." except Exception as detail: print "Unknown exception:", detail openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-composite/0000755000175000017500000000000012271062644022207 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-composite/b.exr0000644000175000017500000015416412271062644023163 0ustar mfvmfvv/1channelschlistIABGRcommentsstringcompressioncompressiondataWindowbox2iÞÿÿÿddisplayWindowbox2iÿÿlineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?spi:packagestring Katana 2.8.32spi:rendererstring Katana 2.8.32à Fwk?ø¯] ªIõ¡@Ôkÿ•)¹FØn•)±>Ðd ú ‘!"¤"7#Ð#e$í$‚%&©&0'Ñ'Y(í(y)*˜*+Ÿ+,¤,'-¦-&.§.$/¦/$0•01•12•23344 5–56‚6õ6v7÷7s8ð8b9Ù9U:Å:;;»;*<™<=Œ= >z>ë>^?Ó?B@½@.A¡ABBýBjCÓC9D¥DEuEÙEBFµF!G‰GôGaHÍHAIµI#JˆJóJ_KÌKJL»L8M¥MN‹NOyO÷OuPçP`QÚQKR¸R2S°S$T–TU“UVˆVW~WùWlXêXiYâYbZáZZ[Ò[M\È\D]«]'^›^_–_`Œ` aˆabˆbc|cõcndéddeàe[f×fSgÎg?h³h-i¨i/j¸j@kÆkOl×lVmØmYnÛn]oÞo`päpmqóq|rsŒstštu—uv¤v,w®w#xšxyžy z¢z${¬{4|±|1}¬}4~®~*›€–€‡‚y‚ó‚jƒäƒh„Þ„W…Õ…Q†Í†C‡¾‡8ˆ´ˆ‰˜‰ŠŠ‹‹Œ|ŒúŒ ŽŽ¡£(‘°‘4’»’E“Ú“k”õ”•–––'—¸—G˜Ú˜o™š›š.›É›Yœìœ„žœž'Ÿ¬Ÿ0 À H¡Ò¡^¢æ¢m£ò£k¤ë¤l¥ì¥g¦×¦F§º§0¨«¨©—©ª~ªóªf«Ø«I¬À¬A­³­$®¤®¯§¯$°¡°#±¤±!²ž² ³ ³´š´µ˜µ¶Ž¶ ·‹·¸•¸¹¤¹0º¼ºD»Û»g¼÷¼½¾ž¾+¿¿¿PÀåÀnÁ˜Â$÷ÃBÄäÄuÅƧÆBÇÚÇkÈÉ’ÉÊ«Ê3ËÇË\Ìð̆ÍΩÎ@ÏÒÏdÐѤÑOÒñÒÓKÔøÔ¾Õ•Ö‘×Þÿÿÿ^xœch€a ]0 ¬L›…Ÿ}hG‚‡”ï¢ÃÅÒí¨Q0@`45Œ$°Ï îuh7‚w’æ¡ÃÄÑÔ0RÁƒ˜%Ðe 5 Œ¦Ú6`7ùßÿÿÿ)xœchÄ aÇ sRvxœ°x ðF„x"ó@áˆÍ -5 .T'ŒŠt^$œL;s6ØèAƦ?|ªÏ¤pÃkž›T÷,NmïÜjd×˼ÉErå@{aP ìâû·Öñ?¿²óã%¥êÛû¾Šå/ŽÅ ¯ æõ½þÓPÚš¶UãßÓ²}Y¿® ´FÕÀhjH`¯ó>§}NûI‡ }ûœö:´FÕ@â)¹Nûæ%ÿd]í¸_é^æô¹Éø Ò½cV¡«Kz$^(ÝMX |×góhj>À„ã{Y×âXÎòK»¿qmóZ‡v—~㺯(ÿp^ÒY£ïœ_¹¿szoqh/ŒªÑÔ@o%¢*ùàÿÿÿìxœchd€ãGÆŒ%1Wt~p0P ~pÜÐØâ3¡ bLJí·Q@"Xùì®NîŸ)‹ÞzF’&E!´“¢|Îg5s‡Xt½™AÏ>´‡G°éóWæÄu-‹cioˆÅWýº·áÿÿªi‹¥ÚãM £ ìuÞç´ß‘pŸÓ>§=.íßQ€tm_Ußdvjn2í`ætï­Ì÷ùl™—0š3èØ¢ø ¤wA¢8ÚÁm^^Ûî*—vyo]í:ÐxÀhj ª ùâÿÿÿ±xœchpðA ¥æŒ ]Á– 32,HhßðlK§³ë3):•¡ÛT;-§HÞiðhï°of®†'cÏâX:Â; ¡-¹‰«~ýM+hï0šFØç´ßq`à>§}NíûQ€žEH¾Øí:7™ž0~¡Ù©º&ï-¥Ý£©ap®Í猸¿-Š£'äù² ¡¸×këüDçöþ(@£©að§ýŽƒ îsÚç4Ð!3Áæ.½Ë›üç&øDæ‚ÁòH¥»£©þàNÂY³Ó‹â|(¿ÅÇgówNçšFSÃਠðêåÿÿÿ¤xœch ;X0'åà Ö„xìHX@ÿp‘`sÃü˜Y‡äŸI J¾àâK‡„FmL#¬L“|¼u^ÊâØA #g^}7ë?;ߎ¦FSÃ(@ûœö;n¸Ïi¯ó@‡Ò›»±+Ý››<8áòÈ'2Žû”ú€;‰œ?Ê;Å Nè³%nQi×w—¦FSÃà ëîêæÿÿÿ™xœch +¸`°!€aH€+:è># 8«^àMy&5àTÏÿkÎ-P~öq ƒlƒm-ÅKÇx‰­S÷ôÌìÅÒdÃŒ¦†Q€ö9íw:pŸÓ—±a JO&,œ›<àFÿIyË#æ%Œ¦Ú{ñ_yÅ hzú»ïæÅÑ®dÃŒ¦†Á Hƒäêçÿÿÿ—xœch Ø°!€aˆ7"sRÐ/ŒF °àýÌ›òLjHÁç|~1­ ßÒ :ð†X[0¡`éâØ!oˆ]}<ï™±òì¼aFSÃ(@ûœö;E¸Ïi¯ó@‡Ý°ó$,œ›<´`æôŸì%ÝóGSµ÷WžEqC nóâø1/qq´ë@Þ°£©aðÓÞêèÿÿÿ¤xœch  Px0'å Ã?86Xœ8à@Ÿ°ö`3ƒ| W¨Ì3©! -­ãÝvùÃLÍÆaV>›ùØL!qqì„Ñóü &}å« è`&`45Œ$°×y¿ãІûœö:t(°¹ë7{ü¹ÉC*Ý‹_ºÊgóhj ¸“ÀõƒçË¢¸¡ Ë;¿ðÈ?ðÞâ2ÐÁ8LÀhj}VÚêéÿÿÿ¤xœch 9``ØðA€aȃ .Ð>¼†5XùlËÒ ”ŸI qhyhïçÞ'i… CZÈÂ23{qì‡Ñóü &|PUž=Ð:¤ÁhjH`Ë>§ýŽÃîsÚë<Ðá9¤ÁË“+"ç&u¨t/~aü‚y‰£©ð zq¼ï–EqC–w~áù½8Úu tHƒÑÔ0t¶—Õêêÿÿÿ—xœch 98bÃ0ŒÀž ?hnìL›°Çï™Ô°' µ,uŸ}耒à²ßŸÉ‹c‡ ¼%ퟶ}­ÿbéØ! FSÃ(@ûœö;7¸ÏiË@‡ëw’Ž[ÍM>ð‰LIϤÜy £©ð æ¡â¢¸áÊÏKúÁ¾8Úu vH‚ÑÔ0”YÃÐêëÿÿÿŒxœch )Øð…‡a‚=%hvÃ8/Í7T|&5ì`YÍ™ó2¼Ö¼C lci•ÎX;ì`øäJ£ÍɼC Œ¦†Q€ö9íw®pŸÓ@‡î¥'ŸÊÌM~Pç ïçø£©4p/þ‘ü¢¸áï+ßùÊí<ÐÁ;ÄÀhjZýJÊêìÿÿÿxœch 8à°&„aXƒ3&+h‚Ãì›Éð2ó™Ô0†—˜¾Ùñìã@ô›ªÞ­X;ŒáÆ&NÆÅÒÐCŒ¦†Q€ö:ïwîpŸÓ^çç!º6?“™›<œánWËóGS1 cK¢EqÃr};m²8Æe zH€ÑÔ0ôšÇêíÿÿÿŒxœch XpE‡a€ hŠÃlnøèióLjØCËCš eÏ>tpr°2Mƒ­uqì°‡Ñó¼Ó6/–èàä`45Œ$°Ïi¿ãHûœ:´9ØÜ½Énòð‡J÷Jzæ&¦üàN¢ÙéEqÖwÎKZë<ÐÁ=ÈÁhjŠÇ ÃêîÿÿÿŽxœch  ``øÂÃ0‚À „ ´ Ë!V>;a¨øLjÄÀ²œp£õÏ>t°Rphñ-éŒÅ±#wVòýZ,=ÐÁ>HÁhjH`ŸÓ~Ç‘÷9íuèP¤àNÒS™¹É#ê\Qº;/q45`bÉ/Š9ð´é7ÎÅ1.샌¦†¡ 8ÀêïÿÿÿŒxœch 0¸ð‡…aÄ328Ð"<‡4°è-•y&5 å¡tË)35:ðXûa‰BââØ£çy&®ª èÀt`45Œ$°Ïi¿ãÈ„ûœ:옷 aáÜä‘•îÕ5yoM èÀˆ›÷Ë¢¸‘Ë;‹{½¶:tà:0š†*C”»êðÿÿÿˆxœch :HXÀ0‚Á  ÔÕ! N­&5báÇbnoŸ}èH4`߯ű#ú×W¼ÖY,=Б0hÀhjM H`ŸÓ~Ç‘ ÷9íqè84 ñî¼ä¹#:îÏœ6/a45À€ çâ¸E#–vŸ4[í:Б0hÀhjº©ÁX¸êñÿÿÿ…xœch 2HXÀ0âÁ™Œ ÔÙ!N­&5Òáµ¶?+ž}è¨`߯ű#^,þ¼Xz £b€ÑÔ0šÀ>§ýŽ£pŸÓ^玉AïÎKž;â¡Î•¹‰£©¡¡Á„sqÜ¢»Kï-Žqè¨`45 åÔhƵêòÿÿÿŠxœch *HXÀ0 ÀàÇ„ê†í'ŒÖ?“…@hyhÉ玴Ž»ø~-Ž…@=Ï=æ ò쎣©GSìsÚï8 apŸÓ@ÇÇ€‚Ä»ó’çŽB Tº×Q17id§ÎÅq‹F!–wzìXã2Ð2 `45ÀàÐL &%²êóÿÿÿŽxœch "°8Á0 À–%1¨ÂCü¾|û™Ô(„Õ¡‹Úgjt´ XÿUnqì(„Ã; '_,¨ èh 0šPáÈN ûœö;ŽBT¸Ïi ce€À”Uó’çŽB8Œ_ø^Ð{ËHM ±Ç-…pÈóÅø¬×V玖£©½Ô_¾³êôÿÿÿ‹xœch ø ð‡…a`€ Ô å!ž-Ø*óLj¢Áœàèg:rèöÍ|¥¸8v¢A¯Òy‹¥:rèFSv82SCÃ>§ýŽ£Üç4ÐqCwð,"aáÜäQˆCWÏMy©¡k3ï—Eq£Ê?\ë<БCw0š°Ã¡”8R­êõÿÿÿŒxœch XðA€aà>P+¤‡ØÜ°yò3©Qˆêϼ^| £ˆŽ`eÚú™Ù‹cG!Vè[Uyçÿ@GÁhjÀGZjhØç´ßqâ†ûœ:†è6w¯ˆœ›< ±Cï­å#)5ÜIôݲ(nb‡^Û<¶;tÑŒ¦|p¨¤Ô®­êöÿÿÿŒxœch  8àpE‡aà P'´9Ø7ó¬§Í3©QˆnQõf8;ÐE°©Š›­uqì(Ä[òŸ}舢 M „áÈI {÷;ŽBBpŸÓ@Ç]@׿Íþs“G!>hvª¤{d¤†Ž-æ§ÅB|pA¼DçŽ(º€ÑÔ@…ÔŸð§ê÷ÿÿÿ€xœch  XÀ0 ˆ P'Ä1ØÜPöLj„[T½ÎtdѬLÛ¼8v„-ùÏ>tdÑŒ¦âàÈH ûG!qpŸÓ@ÇÍÁ枹ɣ04;UÒ=üSäEq£0\0/Ñy #‹æ`45{jzý¦êøÿÿÿ…xœch ØÀ0 ˆGl¨êƒ8/=øLj öø=û8ÐQFC°…cqì($žû3y±ô@G Áhj ÷ÔаÏi¿ã($îsè£!(=9/yî($³š›4œSýøÅq‹F!‘ð¾â¢XçŽ2‚ÑÔ@ Ì©=Ô¡êùÿÿÿŠxœch øÂÃ0 H.P#äX™æa¨øLj’õg¾Q•舣 8¤%±8v’}«ºZÜ:âhFSépø¦††}NûG!©pŸÓ@ÇMÀ¤§2s“G!)Ð{«ÙÉá™Ä<–_7 I^ÛÄ;tÄÑŒ¦Òá`M ‰²œêúÿÿÿŒxœch 00œ°`d€  ( ýAV>ûøÀó™Ô($®ä}ù9~ £ÊàÐbÿúþű£dèQÐS?ÐÑGe0šÈ…Ã154ìqÙï8 Ƀûœ:ö¨ î$¸ìŸ›< I‡ñ ;ʇ[jx]ѽ(n’¿ðxlwèè£2M äÂÁ˜€êûÿÿÿŽxœch dÌ`d‚?,32Pƒ°þYñLj’W†¦XN‘\9ÐQHE°GøóâØQH¼£à–¸êוŽB*‚ÑÔ@>~©¡aŸÓ~ÇQH>Üë<Ð1HE}enò($Æ/¬kòÞ<œRCü½Åq‹F!YçKq¯×—ŽB*‚ÑÔ@>|©"‚œêüÿÿÿxœch üà`€/<”ÆÀ +Óv’&5 Ɇ' Óf¥tDRR¾=/eqì($Þ’ÎP¾«<{ #’*`45P ‡SjhØç´ßqR ÷:t“…T—˜S6± t„RV¿ÖY; ©/0¶ôY t„RFSõàÐO ûœö;ŽBjÁ}NŸÓæ%Ï…T»]•îíÔÀn¶8nÑ(¤ äúöÓy #”"0š¨Gjêÿÿÿÿ‹xœch §ýŽ£ÚpŸÓ—ŽY2À³È¹É£ºpy¤Î•¹ C15tm^·hRúlQ¼·8Úu £– 0š¨:5¦êxœch 8ø À0 hnh| 7Vì“ä_ üLjR–å”.ø5ÐÑK"ØôKhföâØQHuÜY;Ss £—D0šh‡bjhØë¼ßqÒîsèØ%tm^97yRê\Y1ÔRCÇ¿-‹âF!õáiSŸÍν$‚ÑÔ@+8©ÑüŒê€xœch ÌÈ`4 3>ZÖ?“…4‚* g:ŠIËw-Ž…4‚.i³ž}è(&Œ¦Z¡–ö;ŽBZ½ÎÃ$€½Ms“G!­`IOI×PJ {ÅBZÁyIó\:ŠI£©–p R¬í‹êxœch L(øÃÂ0 h>8 /nèô>‹‡Ê<“…4ƒá ,$Wt4 –Æ8($.Ž…4ƒ‘3£]èh&Œ¦Zá”ö9íw…´…ûœ:–‰ÇËÎM…´ƒË#½· •Ôж÷Ë¢¸QH;è³Åk«ó@G3‘`45ÐLjô‡ê~xœch ,H`4È‹:ƒÍ eϤF!¡þÌ ´ÂŽj"ÀÊ´Í‹cG!¡oÕ4åÙÕD€ÑÔ@8TRCÃ~ÇQH¸Ïi cš°¹gnò(¤5ôÞ:7i(¤†;I‹âF!­¡×¶E1.ÕD€ÑÔ@HÿÔ˜k…ê™xœch L(øÃÂ0 è~pdÌ`` 'Žèô>‹‡Ê<“…4‡–‡ªÿ¬xöq #/Xã ¸8vÒFÏ‹þ¼Xz #/M ô‚C!54ìsÚï8 é÷9íqèøÆ Ž—',œ›< i•îé\™›0¸SCÛvÞ/‹âF!íay§â½ÅÑ®áxÁhj ¤wj'=‚êxœch ,H`t',$Kt›ÊžIB:Á‚|:Êñ€•i›ÇŽB:Aÿú²´ÂŽr<`45ÐöÔаßqÒîsèÇ6÷ÌM…ô‚ŽûKºsj¸“´(nÒ –vÏKtè(ÇFS=!=S¼}‚ê™xœch 8øÁÁ0 è~pdÌ`` =¦èöI~<$ÿLjÒ Zªþ³âÙÇŽx¬`Ó/‘y)‹cG!Ý`ô¼8áÏ‹¥:ⱂÑÔ@o8˜SCÃ^çýŽ£¾pŸÓ—Žw¬ k³Ê½¹É£~PéžÎ•¹ ƒ35tl©ì\7 éË;ï-ŽvèˆÇ FS½!ýRæyê€xœch ô”0Œºƒ H+šßó½Ï¤F!áÇÁ ¾õXÀ £‹cG!¡}YZá@G=0šÖÔаßqÜç4Ð1ø|ž›< é ÷—tÆÔxgqÜ¢QHgXÚ=/Ñy £ M é“'~ê Œxœch 00|`¾ðD¬ 5¶h V> _ üLjÒž0¬}Ó?ÐÑ-Žœ™½8vÒÞ’ŽãÜ?ÐÑFSÃ@ÁÁ˜ö:ïw…÷9 tì£;‰+#ç&BúÃ'2:—[jxã·eQÜ(¤?|(ÚÄy £ Œ¦†‚ôH *M|ê „xœch L`vx8 5Æhž),~&5 æH®è$€öI¾^; z•öýº2ÐI Œ¦†„ƒ-54ìsÚï8 îu耞EÎM…CW{oL©¡kóâ¸E£p€ üC¯-.ÀhjHHëÔ'*{ê xœch 00³Ü¤ÿLj|Η»óÚ@'(8´8´¯jqì(0xC,äáNP0š¦ÔаÇe¿ã(X¸Ïi SÜIP½77yÌœ^×8XRÃèŸ\‹âFáÀÁm^Å=Î  `45 4¤mjÞUzê ‚xœch (<`&k4›¾=“… çîH+è¤+Ÿ/Ž… b*Ïè¤Ð0š,©¡aŸÓ~ÇQ8ðp¯ó@§ ØÜ=/yî(`ØQ17q0¤†;‰‹ã†;E»tRhM ƒÒ.51‹vê |xœch ìqaƒ\0˜P@ZÌÑÜ) &5 nQ=ö9~ CƒÁY‹cGá€ÃÀ–ì˜úN £©aÀÁ‘ö;ŽÂÁ÷9 tZhà7˜›< šê(øÔðÉgQÜ(x¸ Ác»ó@'†ÑÔ0H ­R{Œtê{xœch ,H`ƒ|á1¸@JÜQln({&5 7y&¸ÛUéÎÀ¤†Ñ;½ÅÂÁ¹¾}ãpM £ ©S›lê{xœch hÜ`ƒ¼áøA|R ”¹½}&5 |Î÷BçŤ†Õ¯uÇŽÂAoˆ¯åM £ *54ìsÚï8 Üç4‰aÅ´yÉsGá ƒ™Ó'åDj`7[·h2¸Íë»óhj…`HÝÔ¨blêwxœch ìð`ƒüaɘA|,R üŽ~&5 \Zñ§žî©a}é¼Å±£pÐÁ; ÑÂGSÃ(ÃI ûGáà„ûœèž¦¬ž›< Œ_¨sÅ‘î©!öᢸQ8ø ÏÅ{Σ©a‚!5SÌrmêxxœch $,`ƒ,‰!6©N­&5 )d[T”VHÇÔ°‹ï×âØQ8HáÑ”g¦†Q†ôN {÷;ŽÂÁ ÷:Ó11$Þ™Ÿ©¡a¿ã(pŸÍCø‹¹É£pðÃø…:—iŸ¸Ç-…ƒò|9mâ<šF!Rš„öcêixœch ÜQaCtT§dƒgŒŸIÂ!ï®É qj°ä©]; ‡LÔíM £ iŸö;ŽÂ¡iœžEÎM…CNÊ£uj˜·`QÜ(ð»óhj…PHIjÙ5aêzxœch p`C,H`` &^Éûf=“…Cª4”=ûH³Ô°©jÚâØQ8d KÚæÅÒ£©a‚!mSCÃ>§ýŽ£p(Á=.4K ][æ%Ï…C–ôÌM ]jèØº8nÑ(2p^Ò¢h×ÑÔ0 ÁüÔ¬`êvxœch ´Ô0Œ‚!6p &fÉ]ÓžIÂ!WòVÎÔ¤Qj8¢qmqì(BУ`jUÈhj…`HËÔаßq5¸×™F‰!üÅÜäQ8”`üBïÍ´J ÜF‹ãÂ!¿ðxmqM £ ÉM @ß]êvxœch ÜQaC ±9à@LÜ’ žM0~&5 ‡Ø“ÜëL•Ä0oáÜäQ8´á1+ïÍÔI F<‹âFáІ÷½¶¸Œ¦†Q†Ä§N’Uê"‚xœchÀ ¾ð0Œ‚!ŽØ00ài"ÀÊg' ŸIÂ!öø=ûHqj8´ø–tÆâØQ8Äá¹?“K¦†Q†ÔI {\ö;ŽÂá÷¸Pœî$<—™›< ‡:ÉKϤFá°+CÕÎ’6ý[; ‡ ¼£àñìãhj…`HYjhØë¼ßq'¸Ï‰ìÄеy~òÜQ8l`üÂ’nòSCÇ–%q‹Fá°<_æ%:¦†Q†„Sº!Rê'yxœchÀ .0Œ‚a¾ðpÀãx€Eï“gR£pÁ†f35ÉL k?¨.Ž…ÃÞ’Ž¨ M £ )I ûœö;ŽÂá÷9‘™æ-˜—û8šF!’Ÿö;ŽÂá÷:“•6÷ÌM…à *Ý+é"/5ÜIZ7 ‡üÆ5/Áe45ŒB0ÄŸµ˜Pê)uxœchÀ(0Œ‚aö¸00à‹uàÄ&ýgR£p˜Aß²ðgÉH »úªÇŽÂaOÿ˜µXz45ŒB0$754ìw…Ãîq!#1$Þ››< ‡¼`07œÔ`µ(n7¸ÅgQ´ëhj…`ˆ/5>ÓMê*jxœchÀFÁ°øb+X™6ë™Ô(†ðîš ’SÃ!廋cGá0„‰º½£©aB!9©¡aŸÓ~ÇQ8àŽw¬`Ÿä¥gR£pXÂùÅ÷IL ›~‰-Ž…Ã:Üù?šF!’žö9íw…Ãîs"11tm™—§ýŽ£pxÃ}ND&†y æ%Ï…Ã*Ý+é&65q/Ž[4 ‡1,è<šF!bK Eê0gxœchÀfd0Œ‚a8àŠ}4ðѲþ™Ô(ÖP¦&‘©ayâ®Å±£pXCߪÑÔ0 ¡øÔаßqHdbØÛ47yo轕ØÔ°±wQÜ(ÞÐk›Óhj…Pˆ™—šFê1gxœchÀ.0Œ‚a(<ÀžÀ¾™AϤFá°‡á tÎL ›ª¦-Ž…ÃFsýÇÑÔ0 Á¸Ôа×y¿ã( p¯3ÁÄеy~òÜQ8ìáòÈ’.©¡cË’¸E£pØCŸ-ó\FSÃ(CôÔp9Fê3kxœchÀ 8~0Œ‚fd`OH GGð™Ô(0É2Œ`j8¶Öqì(Ð)±b45ŒB($&54ìsÚï8 G$˜.æÎKž; G¬k"œÌØÇ-…#÷:¦†Q…¨©+@ê4wxœchÀ *:FÁˆX6`OppÂiþ3©Q8àÊÐÕ¼ÖRù'‹cGá€w| ’GSÃ(CbRCÃ>§ýŽ£pdÀ}NC⽹ɣp$Àø…ñ ¥†­‹ãÂy¾|ávM £ QSm.Cê5gxœchÀ 60Œ‚6`Op`Á›òLjޏ’ך@jX[°tqì(У y45ŒB($œö;ŽÂ‘ $†y ç&‘ãJ F<‹âFáÈ€_xœFSÃ(„BäÔ´…?ê6ixœchÀ Þˆ0Œ‚8`OPPƧúLjލ?Soj°Ë_; Gô­ M £ ¥††ýŽ£päÀ}NxÊés“GáHÞ[ð§†/^‹âFáH^[GSÃ(„BDjÚ‡>ê7kxœchÀ&0Œ‚vx`KP ÷¹ã™Ô(10'ØOjXspqì(1Ы4f45ŒB(ÄŸö9íw…# âI ÇËç%Ï…#†®Æ—Ú¶/Ž[4 G ”è4šF!"R<@ê8mxœchÀ4n0Œ‚6`K`Pæöö™Ô(Ap%¯5ÎÔ°úµÎâØQ8‚ GAòhj…Pˆ/54ìsÚï8 GÜç„31¬˜6/yî(A0~îÔÀn¶8nÑ(Að ·óhj…PK ÖO=ê9gxœchÀzJFÁˆ32°¥0ð=ßûLjŽ ˜d†35œ0:±8vŽ è”X1šF!âK ûGáHƒ8ƒÏç¹É£p$Áº&Ü©!ñÎâ¸E£pÁâ^§ÑÔ0 ¡–Õ?ê:sxœchÀö¸0Œ‚~ppÀ–€àNYø3©Q8‚ å!“™š8RƒÁY‹cGá‚ÑóBªBFSÃ(C|©¡a¿ã(ip¯3ŽÄÀo07yŽ$¨tÏ{3®ÔðÉgQÜ(I°¼Ók‹Ëhj…`K Ä}>ê;ixœchÀ>0Œ‚,N`K @ðlò3©Q8¢`ÎåM8Rþ™Ù‹cGሂ^_†Q…¸SCÃ~ÇQ8Òà>'\í†È¹É£pdÁÐU¸RC×–Eq£pdAùΣ©aB!$5ShAê<kxœchÀ FÁˆ{\0Sè}îx&5 Gô-ÓÚ–Æ\; G<ý#b45ŒB(Ä•ö9íw…#bM ÇËç%Ï…# ^0ÀžÚ¶/Ž[4 GÜâã4šF!BR¤g?ê=uxœchÀ7FÁˆ?80S”¹½}&5 G´<$ŸVˆ%5¬~­³8vŽ0=/Eyöhj…`ˆ+54ìsÚï8 GÜëŒ%1¬˜6/yî(aPéÞÜDl©ÝlqÜ¢Q8Â`yç¢h×ÑÔ0 Á’é;ê>ixœchÀ-5 £`˜i¡¡«sÚ3©Q8âàüâûXRÃk‹cGሃwþ¦†Q…ØSCÃ~ÇQ8á>',‰!üÅÜäQ8ò`G9¶ÔÀm´8nÑ(qÐc»óhj…PJ Šê=ê?fxœchÀFÁ˜i¡Á‚7å™Ô(qðîš ,©amÁÒű£pÄÁDÝÞÑÔ0 ¡{jhØï8 G&Ä’æ-œ›< Gœ”‡-5ñ,Š…#þ`wM £ A©º‘:ê@exœchÀOdFÁ[|0ÓBÃÊkZϤFሃÝúæXRƒµ`ÙâØQ8âàÉÏñ£©aB!öÔаßqŽLˆ%1ÜIž; G ¼¥†-5œ,]7 Gì,wM £ A©É5<êAaxœch@ £`„‚'2èi¡aå3©Q82á5FŒÔphqì(‘ðš Éhj…Pˆ-54ìuÞï8 G&ÄH wç'Ï…#b¦†1Kâ»KFSÃ(„BPjë:êB^xœch@ £`Äô´Ð°ò™Ô(©0­-5Z; G*Tž=šF! b¤††}NûGáÈ„{ÑäyÉsGáÈ„‰è©áAìâ¸E£pdÂh×ÑÔ0 a0ž::%Cdxœch@+FÁèi¡õÍŽgR£pd´B´Ô°ƒ“qqì(™Pyöhj…0ˆ‘ö9íw…#îsBK Ù—ç%Ï…#&¡§N“Åq‹FáÈ„1.£©aÂ` y%7&Dfxœch@32FÁÐÃGËúgR£pDBËMlh©ayâ®Å±£pDÂÐ>‹ÑÔ0 ¡354ìw…#îsBK {›æ&‘ •†½‹âFáÈ„ß8GSÃ(„Âoœþ;'EZxœch@',FÁˆè©áç3©Q8BáG´Ä°¥¾qì(¡Pz45ŒB8DO ûGáH…ûœ0RÃÜäQ8BazjØÜ½(nŽPë<šF! ÆïP;'F\xœch@FÁˆh‰áÙågR£p„Âh©aßÌìű£p„BéÑÔ0 á=54ìw…#îsBo7DÎM…#&¡§†®-‹âFᅱΣ©aÂ`,ðt;'Gaxœch@FÁ(‰aŸä¥gR£pÄÂ(©aÓ/±Å±£pÄBéÑÔ0 á554ìuÞï8 G*Üç„’º6ÏOž; G*LBM [–Ä-…#Æ:¦†Qƒ±“Ã:'Hkxœch@FÁˆPƒ^1Ç3©Q8B¡å&6”Ô°ôŽãâØQ8BahŸÅhj…Pˆžö9íw…#îsBI ÇËç%Ï…#*ÝEM mÛÇ-…#~ãtM £ ¿qN³9'Idxœch@ FÁˆ¨i¡á„ÑúgR£p¤Â´B”Ô°‹ï×âØQ8R¡òìÑÔ0 a-54ìsÚï8 G*Üç„’ïÎKž; G*LBM &œ‹ã‘ c\FSÃ(„Á’M8&J`xœch@SrFÁˆ¨i¡_¬å™Ô(©0­%5¨ÝÛ·8vŽT¨<{45ŒBDK ûGáÈ…{QƒÓ߹ɣpÄÂDÔÔ ­¼(nŽXí:šF! F= 7%Kcxœch@FÁOdPÓBþ™AϤFáÈ„×ÑRæªi‹cGሄ×MFSÃ(„BÌÔаßqŽ\ˆ–º¶ÎM…#¢§†Žm‹âFáȄݥN£©aB!(5˜:êLexœch@/$FÁ;-=êXexœch€ƒ)9 £`‚ ˜€_¬å™Ô(qP¥ÁKjP»·oqì(qÐ%­p45ŒB(Äžö;ŽÂ‘ ±$§¿s“Gáȃ%=ØRƒ´ò¢¸Q8òà¼$§ÑÔ0 ¡95nÞ9êYrxœch€ƒ £`Ä?, 0ÁïàègR£p„Á•¡ ?ÇcI ëKç-Ž…# ÞQp‰©M £ q¥††ýŽ£p$Â}NXÔÕs“GáHƒñ ;ʱ¥†Ø‡‹âFáHƒ<_<¶;¦†Q†¨©­®>êZdxœch€ƒ £`Ä ØkŽÅ3©Q8Â`’eÖÔ°£³qqì(aÐ)±b45ŒB(Ä•ö;ŽÂ‘±&†ì+s“GáHƒuMØS§é¢¸Q8Ò`q¯Óhj…PˆšÜ :ê[rxœch€ƒ £`„°‡äŸIÂÃXH®ÄšÌKY; GŒœýëÊhj…`ˆ;54ìw…#îuÆšïÍM…# .ôÞŒ=5lí\7 GôÙâµÅe45ŒB0DO S@ê\lxœch€… £`ÄŒ ØÀf†oϤFáƒe걦†•όǎÂÃ…7ަ†Q…¸RCÃ^çýŽ£p¤Á}NØÛ ]ó“çŽÂu®8bM w–Ä-…# *ÞsM £ ÑS·ó>ê]vxœch€‚  £`„+: Ø€³ªã3©Q8¢àTO›g±¦†m-‹cGሂ—ØZK¦†Q†¸SCÃ>§ýŽ£p¤Á=.XCéÉyÉsGሂýç&`O ÷âÇ-…# šž^í:šF!b¦b½=ê^vxœch€… £`D?,°ƒÍ ßžIÂW†ZobÑV>3^; G¼£Ùg1šF!âK ûœö;ŽÂ‘÷9áj7tÏKž; GŒ_¨tWj¸“¸8nÑ(AçË7NçÑÔ0 Á[j<°?ê_jxœch€‚„ £`Dž’\à„ÑúgR£pÁ}çSp¦†]|¿ÇŽÂ“ÚFSÃ(„B|©¡aŸÓ~ÇQ8² ÎÄxw^òÜQ8‚ ïgÜ©Á„sqÜ¢Q8‚ òçÑÔ0 ¡[j‚>ê`qxœch€‚ž†Q0‚À ÜÀ÷|ï3©Q8b`YŽEZ!ÎÔpÂèÄâØQ8b`pg£òìÑÔ0 ÁjhØï8 GÜëŒ31ø|ž›< GÔ¹27wjH¼³8nÑ(1ð´é¢h×ÑÔ0 Á{j«Á@êarxœch€‚ £`Ä€?, pƒ²c¹Ï¤Fá+C·©JàI «³×,Ž…#ÞQmqM £ ¥††ýŽ£p$Á}NxÊés“GáHñ ÍNâK ìæ‹âFáH<_Ä;¦†Q†¸R £?êbixœch€‚ £`Ä€Œ øÀ¾™AϤFáeêñ¦†MUÓÇŽÂÃ…7ަ†Q…„RCÃ~ÇQ8rà>'¼‰¡këÜäQ8R ÎG¼©¡cÛ¢¸Q8R â=çÑÔ0 ¡Wjˆ»Bêcexœch€‚ £`„€ øÁ‰MúϤFሀ9ÁFRű£pD@¯Ò˜ÑÔ0 ¡pjhØï8 G$ïÍM…#†®&”L¸Å‘å:¦†Q…¸S|ò@êdrxœch€‚?, £`D€ ð‹P™gR£p@ËM– g ¤G…Äű£pÀоÄgGSÃ(CbRCÃ~ÇQ8Rà^g‰aÞ¹ɣp$@¥{%]„Rƒ×—Eq£p$Ào\ó\FSÃ(C|©Þ‰Bêevxœch… £`D€ ðƒÍ ßžIÂ-íT• V>3^; GŒžÑâ6šF!“ö:ïw…#îs"Ôn蚟 „Á>ÉKϤFá0‡Ýú Ï>‘6ý[; ‡9<ùyábéÑÔ0 ÁØÔаÏi¿ã(þp ‰¡k˼乣p˜Ã[jsˆI [Ç-…Ãv–/ŠvM £ §Ü GêivxœchƒŠ†Q0ÌÁ ‹ Ä€NóŸIÂa ?>ˆ›©ITj8 ÷dqì(Öп¾¾*d45ŒB0$>54ìsÚï8 ‡;ÜëLTbH¼77yoè¸ß{3q©akÇâ¸E£pXÃÒn¯-.£©a‚!1©JGêjsxœchƒ)9 £`Xƒˆüb-ϤFá0†e9¾’+‰L j÷ö-Ž…Ãwþº2šF!’’ö;ŽÂá÷:™œþÎM…Ãê\ñÞLljV^7 ‡35°›/Š…Ã*ÞŸ—è<šF!›’wFêlsxœchƒ £`Ø‚/<ˆûf=“…Þ0ÜÀkMBjØT5mqì(¦ð–tpAòhj…`HjjhØï8 ‡3ÜçDBbèÚ:7yWøD&~)©¡cÛ¢¸Q8\áCù/ÜΣ©a‚!ñ©<ÊIêmsxœchƒ;* £`˜‚/<HÏ&?“…Þ0Œ[ð‹¤Ô`ÉS»8vKxK:e¦æhj…`HzjhØï8 ‡/ÜçDRbx97yOøDfyi©aÞ‚Eq£px‡ò>›GSÃ(CRRµRIênsxœchƒ £`X‚/<HÏ(?“…Þ0Œ[ð‹ÄÔ°oföâØQ8 á-é”™š£©a‚!9©¡a¿ã(®pŸ‰‰áYäÜäQ8á™å¤¦†®-‹âFáp„å}6;¦†Q†¤¥Ñ Lêokxœch†Q0,Á ¤‚•ϤFá0„+Cß'95Z; ‡!¼£àrçÿhj…`H^jhØï8 ‡'ÜçDrb¸“'’äyÉsGá°ƒñ 3§‘žÄ,‰[4 ‡äùrÒÌy45ŒB0$=5dÎOêqwxœch‚ £`Ø/</Hûf=“…à ž0ÌÜyŒÔ°©jÚâØQ8Ìà-i߇?FSÃ(CrSCÃ>§ýŽ£pøÁ}Nd$†®-ó’çŽÂaŸÈÔ5’“:¶.Ž[4 ‡|(_Üã<šF!’“üÜPêrqxœch†Q0ìÀž 䀕ϤFá0ƒ' ãü"+5Z; ‡¼%2Ss45ŒB0$?54ìsÚï8 ‡ÜçDVb¸“4/yî(Vð‰ÌòòRÃØÅq‹Fá°‚å}6;¦†Q†ä¥I[Nêsxxœch‡ £`X/<Èû$/=“…Þ0Œ[ð‹ÌÔ°é—ØâØQ8Œà-é”™š£©a‚!%©¡aŸÓ~ÇQ8¼à>'2C×–yÉsGá0‚Od–G›:¶.Ž[4 ‡|(ï³Ùy45ŒB0$75J™Pêtwxœch‚ˆ £`Ȭov<“…Öդ.øEvjØÁɸ8v>9¦æhj…`HYjhØç´ßq'¸Ï‰ìÄ}y^òÜQ8l Î•åä§N“Åq‹Fá°Š÷}6;¦†Q†ä§-Mêuqxœch†Q0lÀ ‰ 䃕i³žIÂaËjŒ|)H ‡”ï.Ž…Ã†OŽJ+M £ )M ûGáp‚ûœ(H w’çŽÂau®”tS’Ä.Ž[4 ‡ T¼?/Ñy45ŒB0¤$5írQêvpxœch‚)9 £`˜€ ”~±–gR£pXÀ²‹´BŠRƒÚ½}‹cGá°€ÁʳGSÃ(CÊSCÃ~ÇQ8|à>'ŠƒÓ߹ɣpx@+s“(K ÒÊ‹âFáð€§MŸŒ¦†Q†”¥ÎOêwsxœch‚ £`X€(›ÊžIÂa?>ˆ“\IajX™¶yqì(п¾þוÑÔ0 Á©¡a¿ã(.p¯3…‰asÏÜäQ8 ã~ïÍ”¦†;I‹âFáp€¥Ý^[\FSÃ(CJS±ƒVêxsxœch‚=. £`€->(wÊŸIÂ!»õKgjRœ ~ÌZ; ‡<<ùybUÈhj…`HÔаßq¸×™âÄÀo07y}xKÍ{3å©á“Ï¢¸Q8ôag¹×—ÑÔ0 ÁòÔ¡×Uêytxœch‚#6 £`ȃ9) ”ƒù{üžIÂ!cªŸ}¤Bj0þ3yqì(âððãí‹¥GSÃ(Cj¥††ýŽ£p8À=.TH ¬Vs“GáP‡?Ùç&P#5È*.Š…CrüXí:šF!R#55Têz_xœch‚ £`ˆƒj›ôŸI¡ Ó ©”võU-Ž…C*ÏM £©–ö;ŽÂ¡©”ïÍM…CR+5˜p-Š…CÆ:¦†QƒTI å¾Tê{txœch‚7" £`ƒ?,'¨ÊøTŸIÂ! W†æ]ÞDµÔ`+–¿8vYxGÁïëÑÔ0 Áº©¡a¿ã(ÚpŸÕÊés“GáÐ…ñ CWQ/5|ñZ7 ‡.äù"ÿÀy45ŒB0¤^j€Xê|lxœch†Q0„Á‘ Ô+ŸIÂ! Ÿó%-øEÅÔphqì(²ð†XöLÍÑÔ0 ÁÚ©¡a¿ã(ÊpŸÃä¹£pÈÂÌéË#¨™Ä-…CnóòÙì<šF!R356JYê}uxœch†Q0dÁ  Ô+Óf=“…C–å85øR15R¾»8vQÜ™‘V8šF!R;54ìuÞï8 ‡.ÜçDÅÄp'q~òÜQ8D¡Î•’nj¦†ÑKãÂ! O›ÎKtM £ ©›DfYê~vxœch†Q0DÁ†j‚•i³žIÂ! }ËŸ}¤jj8¤|wqì(’ðôY‹¥GSÃ(C꧆†}NûGáP…{©šî$ÍKž; ‡$¼`07‘º©áAÌ’¸E£pHÂ->‹b\FSÃ(Cj§;\êwxœchhXÀ0 †$˜‘ÁÀÐ@]°¹¡ì™Ô(‚0ɲþÙG*§†•i›ÇŽÂ!w-–M £ i‘ö9íw…Cîq¡rbØÜ=/yî(‚°®inµSÃÄÅq‹Fᄎ‹¢]GSÃ(Cê§’4[ê€oxœchh`CüañØÑ@}°ò™Ô(rpeèç„4H ‡ÇŽÂ!ï(ÿ?;šF!Ò*54ìsÚï8 ‡ÜçDƒÄp'i^òÜQ8Ä`üBÚ¤†±‹ãÂ!y¾”v9¦†Q†´I eÇ_êwxœchhàøÁ0 †x!ÁÀÐ@ £#øLj)XV£ñì#MRñµþ‹cGá‚á“‹K¦†Q†´K ûœö;ŽÂ¡÷9Ñ$1\Ì—ç{¡ó‚Æ©áòÝű£pÀbÅkyGSÃ(Cz¤††ýŽ£p¨À}N4N w’çŽÂ!3§OÊ¥ujx»8nÑ(p›×vçÑÔ0 Áö©édê†rxœchhè¨`Cœ1i =ÈY3ñ™Ô(ôð³kZ!ÍSÃ1Ýó‹cGá ‡{”g¦†Q†ôI ûGáЀûœhž.æÍM…ƒîv›DûÔ`ƾ8nÑ(ôëÛ¢—ÑÔ0 Á©þ[bê‡qxœchhXÀ0 =˜“Ò@°¹¡ì™Ô(äÐ9¦:­©ae򾁱£pÃ÷+ÏM £ é•ö;ŽÂ¡÷:Ó!1lî™›< ;üÉ>7‘©áNÒ¢¸Q8Ø!ÇEÑ®£©a‚!}R/ŸgêˆqxœchhXÀ0 5øÁá±£>`sCÙ3©Q8ˆ¡å¡o è”V¦m^; 1Œžöÿìhj…`HÏÔаßqv¸Ï‰N‰asÏÜäQ8˜¡Ò=ú¥†;I‹âFá`†å¥]Σ©a‚!ýR{¨jê‰sxœchhØÀ0 1x pÀ¡^À‚7å™Ô(´Ðr“ËLMº¥†µKÇŽÂA Cû²ªBFSÃ(Cú¦††ýŽ£ppÃ}NtK óÎM…ƒ*ÝóÞB¿Ô`ij(n^øËk«óhj…`HÏÔ·¡eêŠsxœchh8àÀ0 -ØáÁÀÐ@?°ofÐ3©Q8HaNpô³tL ›ª¦-Ž…ƒz•Î[,=šF!Ò;54ìw…ƒîu¦cbèÚ:7yVºzn"=SCǶEq£p°Bù‡‹b\FSÃ(Cú¦ùUiê‹txœchh8àÀ0 %øÃRÑÑ@_°ofÐ3©Q8áÊPk§2:§†MUÓÇŽÂAï(ÄË-M £ "54ìw…ƒîs¢sbèÚ:7yF¿Péž#SCǶEq£p0Bž/åΣ©a‚!ýS¤skêŒsxœchh8cÂ0 !x!Áñ£Þ ‘Ùõ™Ô(t°¬æµÎ º§Sƞű£pÐÁðÉåkyGSÃ(ÃI ûGáà„ûœèž~¹ÎM…ƒê\™”KÿÔàñmQÜ(|PñþvçÑÔ0 Áp REõjêtxœchhx À0 8bãp þàÄ&ýgR£pA=É’+ 5ìê«Z; <÷§ùוÑÔ0 Áp RCÃ~ÇQ8á^çH ‰÷æ&ÂÁYyoˆÔ`µ(n6x_Ñk‹Ëhj…`80©òoêŽtxœchhx À0 è¨``hpb“þ3©Q8¨àÝ5Ÿ}Ô°«¯jqì(T0Q÷übéÑÔ0 ÁpàRCÃ~ÇQ8øà—I ‰÷æ&ÂÁ'åÍM˜Ô`µ(n.øƒ}q´ëhj…`8P©¸Œmêsxœchhx"Ã0 ø ð¡a ÀÊkZϤFá á Vß°Ô`-X¶8v9ÓïÎÿÑÔ0 Áp`SCÃ~ÇQ8¸à>§K w’çŽÂA—Gv”\j8Yº(nè³Åc»óhj…`8©v¥qêixœchh`ƒœ1iH°ò™Ô(4ð³kZᦆC‹cGá {”g¦†Q†ö;ŽÂÁ÷9 `b¸“‘pê‘lxœchh`ƒL(``hH°ò™Ô($pþçŽg45Z;  tˆ9¸Xz45ŒB0øÔаßq¸Çe@Ãä¹£pÀŽŠ¹ ›Ä-…ƒzìXí:šF!tjàsrê’rxœchh`ƒ|PxÐ0Ð`å3©Q8`ø]†³-Ž…ƒFÎ zöq Ãhj$pp¤††ýŽ£ppÀ}Nî$Ï…ƒ.,éøÔð nÑ(Ðg˼DçN £©aÀÁ[Muê“sxœchh`ƒœ1i `å3©Q8àð³kZá@' 8´8v8¼ÀØ£<{ “BÃhjp°¤††ýŽ£p0À}N€àNòÜQ8àp·ëܤÁÄ-…¹¾-Šqè¤Ð0š©¿–tê”xœchh`&004 xRØ%q‹Fá€Á Û:ÀÁhjX8¸RB|yê—~xœchh`fd4 &°2mÖ3©Q8@0ɲ>­p “8¤|wqì( 蔸Kyö@'$0š¶ÔаÏi¿ã(8¸×y S¸“4/yî( X×47q0¥†1KâÂ‚Ž‹¢]: ÑÔ0p°¥NÀyê˜xœchh`¾ð\h\`eÚ¬gR£pà à ½»:úÑÀ!廋cGáÀ[ÒÁtô£ÑÔ0Pp0¦††}NûGáÀÀ}NûhàNҼ乣pà™øƒ-5<ˆY·h|(ÿ…Ûy £ Œ¦†‚ƒ15º~Ꙁxœcø À0 \0˜PÐ0ØÀ³ÊϤF!ÝáÕcŸã:ò1À¾™Ù‹cG!Ýa`KvLý@G>M gjhØç´ßqÜç4ÐqžEÌKž; éÍNu”¾ÔеyqÜ¢QHw¸ Ác»ó@G>M gj ð}êšwxœc`fd4 F°ò™Ô(¤;L²¬O+è¨Ç-Ž…t‡N‰»”gtÔc£©a à`M ûœö;ŽBúýÎóXÀ¤yÉsG!a]ÓÜÄÁ˜Ä.Ž[4 é ‹{E»tÔc£©a à`M ©×|ê›zxœc`t_x4 N°ò™Ô(¤+Ss £8´8vÒ }± *d £M ô„ƒ=54ìsÚï8 é÷:tŒãw’æ%Ï…t‚ï½7æÔð vqÜ¢QH'h|Ök‹Ë@G90šè {jPê‚êžzxœc`tX64 n°ò™Ô(¤ \ºm錎nàÐâØQHxG!”åØ@G70šè‡BjhØç´ßqÒîsèØ&î$ÍKž; éãšì©áAìâ¸E£çË‚xçŽn`45Ð …ÔŠ¯ƒêŸyxœc`t.4 v°ò™Ô(¤´ÜtRUb #› 8´8vÒ†ö嵸 td£©>ph¤††}NûG!=à>§Žk‚àNҼ乣æPéžÙÉÁŸÄ.Ž[4 i¿q-ˆwèÈ&FS}àÐH ™éƒê zxœc`t;<4 ~°ò™Ô(¤9Ì Ne8;ÐQM8´8vÒz•¶>û8ÐQMM ô€C%54ìsÚï8 i÷:tLî$ÍKž; i CW—t …Ôð vqÜ¢QHc(ÿp^‚Ë@G5`45ЕÔc1†ê¡|xœcPxÀ0 h þ°4 °™áÛ3©QHC¸2T&­p £™H°ò™ñâØQHCxG!Qyö@G3‘`45Ð¥ÔаÏi¿ã(¤5èX&lîž—|h*`Ÿä¥gR£f0|ÁŠâûÉDƒM¿ÄÇŽBšÁÈ™~wþt$ FSmáÐJ ûœö;ŽBZÂ}NÇDƒ®-ó’çŽBšÁå‘åC'5tl]·hÒ úlñØî<БL4M ´…C+5ùè‹ê£~xœcp8À0 h.4 %°OòÒ3©QH#¸EÕ1­p £˜°é—ØâØQH#ØÒ¡<{ £˜0šh ‡ZjhØç´ßqÒîsè&tm™—§ýŽ£úpŸÓ@Ç, k˼乣Ê0súܤ¡˜:¶.Ž[4 © ·y-Šuè¨%Œ¦ZÀ¡šr}ê§~xœcp8À0 ¨ .4 M°OòÒ3©QHU¸EÕ1­p #–,°é—ØâØQHUØÒ¡<{ #–,0š¨‡njhØç´ßqRîsèx% tm™—û8ÐIphqì(¤ºe¯Y,=ÐI0š(‡Ã'54ìsÚï8 )…{\:©î$ÍKž; )‚™Óç& Ôð vqÜ¢QH§ýŽ£28ÐqH5p'i^òÜQHì¨>©áAìâ¸E£è±Ãi #‘j`45P ‡Sjmö—ê°oxœc`„ ì|&5 )€–Fm…T‡ÇŽB `(ߎŽB*‚ÑÔ@^©¡aŸÓ~ÇQH>Üç4Ð1HEp'i^òÜQH6Tº;œRÃØÅq‹F!Ùð§ó@G!Áhj  ¯Ôye—ê±zxœc`dƒ?,†XùLj’ W†J®è¤*8´8v’ ï(þº2ÐHU0šȇÃ/54ìsÚï8 É…ûœ:þ¨ î$ÍKž; É‚ñ ½· ¯Ôð vqÜ¢QHäùâµÕy #ª`45‡_jö›ê²zxœc`d‚?,7†XùLj’W†¾t;2ÐÑGephqì($ ÞQðzýj £Ê`45 ‡cjhØç´ßq’÷9 tìQÜIš—”_ë<ÐQG0šÈÃ55iœêµzxœc`$ƒ†#XùLj’-Å,ø5ÐGphqì($FÏK˜©9ÐG0šH‡Ã754ìsÚï8 I…ûœ:Þhî$ÍKž; I‚J÷–G ÏÔð vqÜ¢QH,ïôÙì<ÐG0šH‡Ã75×1žê¶€xœcØÀ0 HX4n4 O`Á›òLj’W†¾t;2ÐÑF#°¶`éâØQH¼£àõúÕ@GÀhj çÔаÏi¿ã($ îsèX£˜·`^òÜQHŒ_˜9m¸¦#îÅq‹F! çËI3çŽ6ÑÔ@*Ω&Ÿê·€xœchh`$€?,7†+X™6ë™Ô($® }évd #fàòÝű£hxGÁëõ«Ž4šÑÔ@Þ©¡aŸÓ~ÇQH Üç4ÐqF3p'i^òÜQH4Œ_˜9mø¦†1KâB¢!Ï—“fÎi4£©48¼SòÜ£ê¸uxœchh`$€€ ìL›õLj ·,1ÐQFCpHùîâØQH4 d96ÐQFC0šHƒÃ;54ìsÚï8 ‰‡ûœ:Æhî$ÍKž; ‰†f'‡sjx³$nÑ($.ˆwè(£!M ¤Ááºù¡ê¹xxœchh`DƒŠŽ†á V¦Íz&5 ‰„–Nea4‡”ï.Ž…DÂh¹Ea4£©8ÜSCÃ>§ýŽ£X¸Ïi ã‹¦àNҼ乣H¨tÏq #Œ¦àAÌ’¸E£HXÞá<ÐFS0šHÃ=5ÆA¡êºsxœchh`D‚ ìL›õLjU|:ºh )ß]; ‰‚.i…]4£©x8üSCÃ>§ýŽ£X8бEcp'i^òÜQH,éî©áAÌ’¸E£(8/Éi £‹Æ`45‡j¨¢ê»€xœchh`D ìL›õLjõg=û8ÐÑEcpHùîâØQHô­š¶Xz £‹Æ`45 GBjhØë¼ßq÷¸ tlÑÜIœŸ“… ¥QÛ@GÀ¡Å±£ åÛ1ÐÑD'0šÑ“ö;ŽBBpŸÓ@ÇÀä¹£Tº;RRøE£üÆé<ÐÑD'0šÑ’Ík¥ê¿oxœchhx#Â0 ð‚-> #”ñ©>“…x`·¾ù@GÝ€­XþâØQˆžü?БD70šÁ‘”ö;ŽBBp ãˆn`Åô¹É£¼¥6rRïEq£ì,wèH¢M „àÈI ß•¦êÀ|xœchhx À0 ð€ F 8±Iÿ™Ô(Ä Ã8µ t$Ñ ìê«Z; qÂÈ™É|;:’èFS~8²RCÃ~ÇQˆîuè8¢H¼77yâ†Ë#•Ô`µ(nâ†>[¾q¸ t$Ñ Œ¦üp$¥©]¦êÁrxœchhx À0 ð‡ #œØ¤ÿLjâ„ú’+:ŠèvõU-Ž…8¡ï¯+Et£©?Y©¡a¿ã(Ä÷9 t Ñ$Þ››< qCï-#)5˜p-Š…¸¡×VçŽ":‚ÑÔ€Ž¤ÔøÏ¨êÂoxœchh¸¡Á0 p‚#6 # °æX<“…8 ÀÕŽ º‚‹cG!xîOà@G]ÁhjÀGZjhØï8 ñÁŽº‚ì+s“G!.xÌjd¥NÓEq£¼¯è4ÐDW0šðÁ‘•모êÃrxœchh8àÀ0 p‚  # ì›ôLjâ€[T%:‚è 6UM[; qÀÀ·Ž º‚ÑÔ€Ž´Ôаßqâ†ûœ:~è º¶ÎM…¸ ÙÉ‘•:¶-Š…¸à‚xçŽ º‚ÑÔ€ެÔî©êÄpxœchh8àÀ0 p€  # ì›ôLjb…+y­:zè 6UM[; ±B‚äŽ:ƒÑÔ€޼Ôаßqâ†;t][ç&Bì0~áHK ÛÅBìð Ó@GÁhjÀ GZjdnªêÅrxœchhØãÂ0 p€ # Ü) &5 ±Bý™š=t?f-Ž…X¡oUÈ@GÁhjÀ G^jhØï8 qÁ}N;tüs“G!vè½e¤¥†O>‹âF!vèµÕy £‡Î`45à†#-5:Ú©êÆoxœchhXÀ0 °‚ # ln({&5 ±Àœ`£Žºƒ•i›ÇŽB,Ы4f #‡î`45à‚#154ìw…¸à@Ç ÝÁ枹ɣ ]=òRäEq£”è4БCw0špÁ‘—²«êÇrxœchhXÀ0 °‰ # ln({&5 ±À¤×:rèV¦m^; ±@§‡?:rèFS.8SCÃ~ÇQˆîs踡;ØÜ37ybƒu#/5ÜIZ7 ±Áâ玺ƒÑÔ€ ޼ÔWP®êÈ|xœchh˜PÀ0 °€7" # è}îx&5 1às>Õg:rè–Æ\; 1à ±üÅÒ9t£©;™©¡a¿ã(Ä÷¸ tÜЯ˜›< 1aæô¹ #/5´íX7 1á6¯EÑ®9t£©;‰©û¬êÉnxœch†Q€ÌIiy`eÚ¬gR£:Ç tÔ 8¤|wqì(Ä€‡—tÔ M ØáÈL ûG!v8Ð13àNòÜQˆþd‰©áAìâ¸E£rüpè¨0š°Ã‘˜i+®êÊqxœch†Q€\hy`eÚ¬gR£®ìÝ=ÐQ3àòÝű£z|x<ÐQ3`45`‡#354ìw…Øà>§Ž™w’çŽB,0~ÁHL bÇ-…ð ·ó@GÍ€ÑÔ€ŽÄÔ¯ç¯êËvxœchhØÀ0 °€„ #8/=øLjb@K£¶ŽšÛX8ÇŽB Ê·c £fÀhjÀGfjhØç´ßqb½Î3JOÎKž; 1 Ò‘˜îÅ/Ž[4 1à7—Žš£©;‰©n/ªêÌtxœchhp8À0 0Àž†‘öI^z&5 Ñà Ã16ý[; Ñà-iµŽ˜£©©©¡aŸÓ~ÇQˆ :^tm™—îüÿLj¢Á-ª1–?´Z; Ñ``‹Û@GÌ€€ÑÔ€ ŽÔÔаÏi¿ã(Ä„/ö6ÎKž; Ñ Ù©‘™6ö,Ž[4 Ñà‚§Ž˜£©™©·è®êÎnxœchh`XÀ‡†‘V>“…P¦æ@GÌ€€C‹cG!ô­ èˆ0š°Á‘šö9íw…˜p ãe@À¤yÉsG!ôÞ:2SÃØÅq‹F!ôÚæ4Ð3 `45`ƒ#35ꨬêÏsxœchh¸`À0 0À‡†‘œUŸIB4¨?Ss #f@À¶–ŽÅ±£ úV… tÄ M ØàHM ûœö;ŽBL8Ðñ2  ôä¼ä¹£ zo™©á^üâ¸E£ zmsèˆ0š°Á‘™÷0¬êÐrxœch†Q€84ŒD°2mÖ3©QˆõgjtÄ 8¤|wqì(Dƒ¾U!1FS68RSCÃ>§ýŽ£t¼ ¸“4/yî(DƒÞ[Gfjx³$nÑ(Dƒ^Ûœ:bŒ¦lpd¦V¥­êÑtxœchhHXÀ0 0À•†‘N­&5 Ñ`ø®Ž˜»ø~-Ž…hð õ@GÌ€€ÑÔ€ ŽÔÔа×y¿ã(Ä„/ïÌOž; ÑàòÈ‘™L8–Ä-…h0aÓ@GÌ€€ÑÔ€ ŽÌÔ2A«êÒbxœch†Q€4ŒD°ò™Ô(Ä?tÄ 8´8vbÒ1FSv82SCÃ~ÇQˆ ÷¸ t¼ ¸“øÏM…èp·ëÈL ŧÅBtÈõÍi #f@ÀhjÀGbj|VªêÖrxœch‚ £ ØÐ0òÀ¾™AϤF!\Ék=ÐQ3`Sմű£z$tÔ M ØáÈL ûG!6¸Ïi cf@×ֹɣÆ/‰©¡cÛ¢¸Qˆ ¿p;tÔ M ØáÈK ¬ê×pxœch‚  £ XÐ0ò€oÊ3©QˆU|:j¬-Xº8vb@—´ÂŽš£©;™©¡a¿ã(Ä:fÌ[87ybÂ’ž‘˜ŒxÅBL8/Éi £fÀhjÀG^jš©êØ|xœch‚ £ øÃ2¡ a¤Í eϤF!\ºðsü@GÝÁÊ´Í‹cG!¼£àS?БCw0š°Ã‘™ö;ŽBìpŸÓ@Ç ÝÁ枹ɣÆ/ì(y©áNÒ¢¸Qˆ y¾xlwèÈ¡;M ØáÈK a÷­êÙqxœch‚Ž †Q€ìðhi gÍÄgR£ Ì 6èÈ¡;8¦{~qì(ĽJc:rèFS.8SCÃ~ÇQˆ tÜÐ\Ì››< ±ÁÐÕ#/5˜±/Ž[4 ±@ù‡N9t£©i©¨(©êÚvxœch‚ІQ€\hYà„ÓügR£+\Ù»{ £‡Îà€Ü“ű£+ôøðx £‡Î`45à†#/54ìsÚï8 ±Ã}N;t‰÷æ&Bì0~ÁHK [;Ç-…XánçŽ:ƒÑÔ€ެÔš­êÛxœch‡ £ø Ð0²À>ÉKϤF!V¾@9­p #ˆ®`Ó/±Å±£+Œœ™­<{ #ˆ®`45à†#/54ìsÚï8 qÁ}N?t][æ%Ï…XáòȹI#+5tl]·hb…>[Ÿ tÑŒ¦Üpd¥€ÌªêÜxœch… £'¸`pÀ¡aä€Í ßžIBp‹jØLÍŽ":‚•όǎB0°¥¢*d £ˆŽ`45àƒ#-54ìsÚï8 qýÎCt›»ç%Ï…8 Ù)ïÍ#)5ÜI\·h†¼¶¸ tÑŒ¦|p$¥5ЩêÝ{xœch†Q€¬ a`h)`å3©Qˆžx™ùìã@GÝÀ¡Å±£<þnÅbéŽ$ºÑÔ€ެÔаÏi¿ã(Ä÷¸ tÑ ÜIš—/yî(Äß ÎM)©¡mûâ¸E£4>»(Úu £‰N`45‚#%5ãA©êß‚xœch… £€XÂÀÐ0Àf†oϤF!^xâeæ³Qt+Ÿ/Ž…xáñw+KtDÑŒ¦Âp䤆†½ÎûG!!¸Çe ã‰.`s×üä¹£/|"37ad¤†; KâB¼0nÑ¢h׎(º€ÑÔ@ŽŒÔÖP©êàuxœch†Q@l8àÐ0ÀÊgR£\É[9Ss #Š.àÐâØQHzL­ 舢 M „áÈI ûG!a¸×y ã‰.àNòÜQHÆ/ôÞ<2RøE£üÂãµÅe #Š.`45†#!5 ¥êá}xœchƒ £€ 8aáp aøƒ›ôŸIBðãƒ8É•Ut»úªÇŽBп¾þוŽ*:€ÑÔ@ )©¡a¿ã($îu蘢H¼77y‚Žû½7„Ô`µ(n‚¥Ý^[\:ªèFS1pø§”³¦êâ}xœchƒ3& £€ðBâƒ@Ãp‰Ì®Ï¤F!AXV“ºà×@GÍ)cÏâØQH†OΟ©9БEs0šˆƒ##54ìw…ÄÁ}NW4¿\ç&BÂPçÊòˆáŸ<¾-Š…„¡â}ŸÍÎY4£©88ÜSH¢êã€xœchƒ=. £€(ð‡¥`BÃðwÊŸIB"àÊÐH…ªŽ.ƒ³ÇŽB"à…XÉ•]4£©X8RCÃ~ÇQH,Üç4бEcÀo07yã.tèè¢1øä³(ny¾ølvèè¢1M ÄÂáŸþ¢êä|xœchƒ £€hpÀ¡a8ƒÍ eϤF!‘PfPZá@G ÁÊ´Í‹cG!‘зjšòìŽ2‚ÑÔ@ î©¡a¿ã($îsè£!ØÜ37y ½·ÎMΩáNÒ¢¸QH,ôÚ¶(Æe £Œ†`45‡ojN5¡êåxœchƒŽ †Q@øÂ±¢a¸‚œ5ŸIB¢á ÃÚ7ýi4ÇtÏ/Ž…DÃ[Òqœû:ÒhFSipx§††ýŽ£4¸Ïi ãŒfàbÞÜäQH<|"£syø¦3öÅq‹F!Ñð¡üiçŽ4šÑÔ@®©&‰Ÿêæ‚xœchƒ„ £€DpÄfABÃp'ŒÖ?“…$A= ¾q4»ø~-Ž…$ÁsªÒ :âhFSépø¦††}NûG!©pŸÓ@ÇM@âÝyÉsG!Ið˜UI÷ðL &œ‹ãB’à}Åy‰Îq4£©t8S·Šžêçxœchƒ £€dð‡¥§„¡a¸‹Þ'ϤF!‰peèó½Ï>täQ¬ý º8v’ï(¤X,=БGu0šÈÃ554ìsÚï8 É{:î¨æ-˜—tRZ; É‚á“ÓY8KtRŒ¦rápL ûœö;ŽBòà>§=.Tw’æ%Ï…d@+f'ç% ¯Ôð vqÜ¢QHT¼¿ ~q´ë@G UÁhj ¯Ôº=™êé‚xœchƒ  £€lpCCáAÃðzŸ;žIB2aYŽÃÙŽB*‚¥1ÇŽB2apgƳ…T£©8ÜRCÃ>§ýŽ£|¸Ïi cŠàxù¼ä¹£L¨s¥¤{8¥†¶í‹ãB2áiÓy‰Î…T£©8|Rׇ›êê‚xœchƒ £€"pÁ@áAÃðûf=“…À-ªÞ g:©6UM[; )€-ùÏ>t4R Œ¦JápJ {÷;ŽBÊà>§ŽE*®Íó“çŽB  Ù©’îá’:¶,‰[4 )€ æ%:t4R Œ¦JáðH ƒõ™êë}xœch€‚/< £€BpÀAâEÃpᆊϤF!EPæ¬×:"©ì¥3ÇŽBŠ oUõÑT£©r8|RCÃ~ÇQH9Üç4ÐñH ,37yR½·Ö5Ô /¿(nR½¶÷8tDRŒ¦ÊáÐO ŽT“êìŠxœch€‚ £€ à‚††¡ Xs,žIBŠáUo†oÏ>ttRvt6.Ž…ÃÀ–ügÆ‹¥::)£©:px¤††ýŽ£:pŸÓ—ŽM Aö•¹É£rhvª¤{^ÂPO œ¦‹âF!åpA¼ÄÅÑ®‚ÑÔ@8´SäÚ‘êí‰xœch€‚=. £€JàŽJÄŠ†¡ î”…?“…TáúßìH+è(¥ü˜µ8vR^á)ædTž=ÐQJM ÔƒC?54ìw…Ôƒûœö:tŒRø æ&BêÀå‘:—ç%åÔðÉgQÜ(¤LXpÚdq´ë@G)`45PÝÔ/Þêî‰xœch€‚ £€ŠàHG…Æ¡ 67”=“…TƒÏù^¬Y&¹r £•L°2móâØQH5xC¬Xwÿ¯+­d‚ÑÔ@]8´SCÃ~ÇQHm¸×y c•L°¹gnò(¤Ìœ>)Ï{óPM w’ÅBêÁm^?ؽ·¸ t´’ FSuáÐL ï“êï‡xœch€†Q@eð‡eEÄ…†¡V¦Íz&5 © W†¾<Ö³‰m £– pHùîâØQHUxGÁ+{IŸÅ@G-`45PÝÔаßqÒîsè˜%ÜIž; © ãfNWº;SÃØÅq‹F!U!Ï—“æß8:jÉ£©úpè¥çaêð‹xœch€ £€&àŒIÀ††!N>“…4€—˜ï/=˜V8ÐñKØòŸqì(¤¼ÀØÀ¡<{ #˜$0šh‡bjhØç´ßqÒîsÚë<ÐñKØ7/yî(¤Üíjvr^âÐJ ›»Ç-…4€\ßÄ/Žvè& Œ¦ZÁ¡”æ{Šêñxœch€ £€fàƒÀ”œ  Cès<“…4‚á :Å„y­:’‰Kï8.Ž…4‚‘3Ïß[Y<БL4M ´„C-54ìsÚï8 i ÷9 t Ž—ÏKž; i—G2ÿ_0tRCÛöÅq‹F! Ï–»Ê_¸:’‰£©–p¨¤ Õ‰êòxœch€‚  £€Æà„…à ƒXð¦<“…4…ÄI>Ÿ©9ÐQMX[°tqì(¤)ô¯¯ÿÅV2ÐQMM ´‡C'54ìsÚï8 i ÷9íuè˜&Ì[0/yî(¤)tÜï½ÅgóPH FÜ‹ãBšÂÒn¯­Þ[\:ª‰£©öpð§ž„êóxœch€‚ £€à ÏŒŒ ƒì›ôLjÒž0Ì´œ·‰m £›ØT5mqì(¤9¼%훸©Ïb £›M ôC#54ìuÞï8 é÷9 tl]›ç'Ï…4‡Odêš”îöÔбeIÜ¢QHsøP¾¸÷§ó@G70šèwj¥¼„êô‹xœch€ƒ7" £€NàŠNÆ ‡ ƒ”ñ©>“…tS=güÙ+¹r £°Ë_; é/±Õ ?þue £M ôƒƒ?54ìw…ôƒûœö:tŒã+¦ÏM…ôýu®xoÌ©á‹×¢¸QHhzZñž÷—Žr<`45ÐÖÔÅç‚êõ“xœch€ƒ3& £€ŽàË ƒ$2»>“…tƒ+C{õuÝÞ¦tÄc¦Œ=‹cG!Ýà…³Ÿ»^ë(ÏèˆÇ FS}áàN ûG!½á>§½ÎïXÁ/׹ɣ~0~á-µÌiógjðø¶(nÒò|é,?i¶8Úu #+M ô…ƒ15ö¸êöˆxœch€ƒ  £€îàÈ”œ ƒ Xð¦<“…t†ÏùºÅobèÈÇk –.Ž…t†7Ä.ßÛÖg1БFSÃ@ÀÁšö;ŽÂûœ:î1À¼…s“G!½aætæ¿Jw_j0âY7 é ·yÝUþÆé<БFSÃ@ÀÁ•|ê÷‹xœch€ƒ  £`€À ‚ ÐûÜñLj,Ë)U8dÔ6ÐI ,9¸8v |Ì·c “M _jhØï8 îsÚë<Ð) ¯˜›< ê\Y©tg0¥†¶‹âFáÀÀÓ¦>›¿s¸ t@£©aàà`I ¢£zêøxœch€ƒ„ £`@Á‹8a´þ™Ô(@è[¶òò‡™šÀ`߯ű£páéí_ùªB:!€Áhjh8˜RCÃ>§ýŽ£p`á>§½ÎÀ ñî¼ä¹£páƒÐU>›Gj0á\·h Üâ#ÿÀ{‹Ë@'0M  >59Öxêù‰xœch€‰ £`ÀÁž ?|Üùÿ™Ô(`xÂP»ÁRçÅ@'††å­ÇŽÂ†·¤ýÓ¶¯åèÄ0š,©¡aŸÓ~ÇQ8à>§N {ç%Ï… ŸÈ”ôLÊøÔ°±gqÜ¢Q8Àð¡ü¼¤ìÎFSà€›™¶vêúxœch€ƒ £`€'2-5 ln({&5 ¼ÆÝ)ý9~SÃÊ´Í‹cGá €×+4vÆÔ¦†Q¸x0¤††}NûGáàûœ01lîž—Ò)5h<Þ¾8vRxGáì綇V‹¥GSÃ(¤{jhØï8 7Üç´Ç…N‰Á‚}nò(¬0~á-µºÆy ôJ n?ÅÂÁ y¾t–÷,ŽvM £.©ä¨kêÿ€xœch@FÁ Od*:4Э&©áòÝű£pÁо"¾_ʳGSÃ(\LÛÔа×y¿ã(ZpŸÓ^gš$†;‰ó“çŽÂ!•î)Ý—H›Ôð ziÜ¢Q8„à7®oœ‹£]GSÃ(Œ£~jä°_êxœch@OdFÁ/$2f004P¬¼¦õLj)XVÓògų4H Ö‚e‹cGá‚á“s…?/–M £p1-SCÃ~ÇQ8ôà>§½Î4H w’çŽÂ!u®è\™›H‹Ôp²tQÜ(ZPñ¾â½Å1.£©aÆQ75úÄ]ê}xœch@;<FÁ/$4PüŽ~&5 ‡,«q7ZŸVHåÔ°¾tÞâØQ8ä`øäl¾_ʳGSÃ(\L«ÔаßqM¸Ïi¯3•ÔÕs“GáЃ:W”îÎK¤vjˆ}¸(n=¨xÿçâh×ÑÔ0 㨗—©\êqxœch@ FÁOd4Pè}îx&5 ‡&¼f/¹’ª©aiÌÁű£pHÂk‚i¿®Œ¦†Q†ÔO ûGáÐ…ûœ¨šŽWÌM…Czo¡njhÛ±(nMØ]êµÕy45ŒB0¤FjLÙ\êxxœch@+FÁ',.4P °¾ÙñLjYøñÁcU ª¥†œŒ‹cGá…þõÍ-n£©a‚!uSCÃ>§ýŽ£p(Ã}NTK Ù—ç%Ï…C:î7;I½ÔÀi²8nÑ(²°´{A¼óhj…`HijAUêyxœch@ £`ˆƒ?,=% Ô+ŸIÂ! W†8ß›VH•Ôphqì(ÒðŽBºÑ åÙ£©a.¦njhØç´ßqu¸×™*‰áNҼ乣pÃø…¼Ÿç&R'5<ˆ]·haÈóEùÎâh×ÑÔ0 ã(M ¢Wêxxœch@ FÁ7484P63|{&5 ‡8,Ëñ©I…Ô°ò™ñâØQ8ÄapgaUÈhj…`H­Ôа×y¿ã(úpŸÃæ®ùÉsGá‡:W¼·P#5ÜIX·hqxÚÔk«óhj…`H~j<Uê sxœch@oDFÁX7yu¿:©á‹×¢¸Q8Ô!Ï—Ò.çÑÔ0 ÁÜÔ§½Uê hxœch@FÁ° Ðã–d°ofÐ3©Q8 àüÏñ§†MUÓÇŽÂabêGSÃ(„Bj¤††ýŽ£p¸@ŠC×ֹɣp8ÀŽ ÊSCǶEq£p8@N£©aB!9©ZÚTê gxœch@SrFÁ0 Ðc—DÀ/ÖòLj ¨ÒàKajP»·oqì(Ð%­p45ŒB(¤<54ìw…ÃR˜œþÎM…ÖôPš¤•ÅÂáç%9¦†Q…¤§ärOê lxœch@+FÁ°=%èñK`}³ã™Ô(&pßùŠRÃNÆÅ±£p˜Àd£¶ÑÔ0 ¡ÒÔаÏi¿ã(>¢Ä}y^òÜQ8L ïgÊR§Éâ¸E£p˜@å;Σ©aB!©©²ÁNê nxœch@FÁ0'Ðc˜pb“þ3©Q8l`ÎåM¤†]}U‹cGá°^_†Q…”¥††}NûGáðûœ(H ‰wç%υÆ®¢$5˜p.Ž[4 ‡ ”à<šF!’–uQêsxœch@ £`XÐã˜h°ò™Ô(F0|…äJ²Sáű£pÁșѿ®Œ¦†Q†”¥††½ÎûGáp‚{ÉN wç'Ï…Ã.ôÞL~jx³$nÑ(6Ðg‹×—ÑÔ0 Á´Ôž’QêhxœchÀFÁ0 0ã˜hpb“þ3©Q8làüÏñ¤†]}U‹cGá°1õ£©aB!e©¡a¿ã(^‚Äxonò(>°£‚’Ô`µ(nè±Ãi45ŒB($%5n¢OêtxœchÀFÁ0oD0c™H`Á›òLjøœOõÙG²SÃÚ‚¥‹cGá°7ÄòK¦†Q†”¥††ýŽ£pxÁ=.d'†y ç&Âá3§ÏM ?5ñ,Š…ÃnóZí:šF!’’–ëMêhxœchÀFÁ°°Å2Q`eÚ¬gR£pAËMld§†CÊwÇŽÂaCû,FSÃ(„BJRCÃ~ÇQ8¼à>'²Ãä¹£pXA¥»ä§†±‹ãÂa¿q:¦†Q…ħl!OêoxœchÀ FÁ°0c™H°™áÛ3©Q8Œ ¾äJ²SÃÊgÆ‹cGá0‚¾¿®Œ¦†Q…”¤††}NûGáp‚ûœÈN ›»ç%Ï…Ãzo!?5ÜI\·h#èµÕy45ŒB($>59·QêmxœchÀFÁ°+°Å2Q`eÚ¬gR£pÁ²7ýd§†CÊwÇŽÂaƒ9÷¦†Q…”¤††}NûGáp‚ûœÈN w’æ%Ï…Ãê\&?5<ˆY·h#xÚÄy45ŒB($>5çŸPêkxœchÀ>0Œ‚a,N`‹e"Á³ÊϤFá°9—7QöÍÌ^; ‡ ôúzg45ŒB(¤,54ìw…à îs¢ 1<‹œ›< ‡ ]EIjèÚ²(n(ÿÀy45ŒB($>5»SêjxœchÀö¸0Œ‚a6`‹e"Á²ðgR£pØÀ•¼Ö¤ƒ³ÇŽÂa= ’GSÃ(„BÊRCÃ~ÇQ8œà>' ¿ÁÜäQ8|`üJRÃ'ŸEq£pøÀ/ÜΣ©aB!ñ©­\OêixœchÀZjFÁ°°Å1Ñ «sÚ3©Q8L å&6ŠRÃk‹cGá0¡}£©aB!¥©¡a¿ã(N¢Äþbnò(.Pée©ÛhqÜ¢Q8Là7.§ÑÔ0 ¡”ÔJ0OêoxœchÀ0Œ‚a*:°Å1Ñ`3÷gR£p˜@K§2ŠRÃÊgÆ‹cGá0Ñr‹FSÃ(„BJSCÃ>§ýŽ£p¸À}N%†ÍÝó’çŽÂa•î9R”î$.Ž[4 ‡ ,ïpM £ II JZQêyxœchÀ0Œ‚aÞˆ00`‹c¢Á £õϤFá°€ÏùTŸ}¤(5ìâûµ8v xC,±ôhj…`HyjhØë¼ßq¸×™¢Äxg~òÜQ8,`æô¹‰”¥Ž%q‹Fá°€Û¼ŸŒ¦†Q†¤¥Ì~PêjxœchÀ Þˆ0Œ‚a`a@Ÿê3©Q8  ¾äJŠSƒ­XþâØQ8  ï¯+£©aB!5RCÃ~ÇQ8<à>'ŠÊés“Gáp€Þ[(O _¼ÅÂá½¶:¦†Q…¤¥I÷RêixœchÀ 60Œ‚aÖ„`_’€oÊ3©Q8ä቗TH k –.Ž…C—6šF!R'54ìw…ÃR!1Ì[87y}øD†©ÁˆgQÜ(ú0n‘Óhj…PHjjÒTêxxœchÀ &0Œ‚!nhpÀ¿$g ‹ŸIÂ!Ër|gjR!5ì“|½8vqÜYX2šF!R+54ìsÚï8 ‡>ÜëL…Äð,rnò(êPçŠ÷fj¤†®Í‹ãÂ!O›zmqM £ IO KšUêqxœchÀ FÁ/$°Ç-É`å3©Q8ÄaYFZ!URáű£pˆÃðÉÅʳGSÃ(Cꥆ†}NûGáP‡ûœ¨’î$ÍKž; ‡4Ô¹27‰:©áAìâ¸E£pHCÅû‹b\FSÃ(CrR„jUê‚xœchÀ 8üaaC|áÙ€=nIûf> •y&5 ‡,'*%†®Í‰ ç&¡ ŸÈÄ/ VjèØÂ÷eQÜ(ºð¡ünçÑÔ0 Á¼Ôa»VêuxœchÀ.0Œ‚! ¾ð|À³dgUÇgR£pˆÂ†q ~Q15lkéX; ‡(¼%2Ss45ŒB0¤vjhØï8 ‡2ÜçDÅÄPzjnò(ªð‰Ìòj¦†{ ‹âFáP…å}6;¦†Q†ä¦œ¡YêuxœchÀ¦ä0Œ‚! ¾ð|À¯d~±–gR£pH†q ~Q55¨ÝÛ·8vIxK:e¦æhj…`HýÔаßq]¸Ï‰ª‰ÁéïÜäQ84á™åÔM ÒÊ‹âFáЄå}6;¦†Q†ä§9”Xê zxœchÀ .0Œ‚! ¾ð|À«d‹Þ'ϤFá„' ãü¢rjXûAuqì(‚ð–tÊLÍÑÔ0 Á©¡aŸÓ~ÇQ84á>'*'†y æ%Ï…C>‘YAíÔ`Ľ8nÑ(‚ð¡¼ÏfçÑÔ0 Á’Ô ÖZê!yxœchÀ0Œ‚!^H,HÀ§dƒ}’—žIÂ!ËjŒ|©ž6ý[; ‡ Ÿ•V8šF!Ò&54ìuÞï8 ‡"ÜçDõÄеy~òÜQ8ä Î•’n꧆Ž-KâÂ!ïÏKtM £ )K $>\ê"uxœchÀ î¨0Œ‚!nh,HÀ£€gŒŸIÂ!Ërœ|i’,yjÇŽÂ!ƒ;3Ò GSÃ(CÚ¥††ýŽ£pèÁ}N4I Ï"ç&¡u®”tÓ&5Ì[°(n-xÚt^¢óhj…`Hij®Á\ê#uxœchÀ $0Œ‚!Θ8ÀŸÍ eϤFá‚—˜£$WÒ(5¬LÛ¼8v!x±æ×•ÑÔ0 Á–©¡a¿ã(jp¯3Ãæž¹É£p(Áݮޛi•î$-Š…C r}óÚâ2šF!Rž®raê$zxœchÀ 0Œ‚!6pÀ›‚}’—žIÂ!WòVÎÔ¤YjØôKlqì(2У`jUÈhj…`HÛÔаÏi¿ã(Jp¯3ÍC×–yÉsGáñ ½7Ó.5tl]·hø…Çk‹Ëhj…`HÔT2`ê%xxœchÀFÁ=% øâ’B°2mÖ3©Q8Dà¾ó½Ï>Ò05R¾»8v˜ltb±ôhj…`HëÔаÏi¿ã(:p äyÉsG἟ç&Ð25<ˆY·h¨|gq´ëhj…`HÔ·bê&uxœchÀnh0Œ‚!þ°8ÀT¬9ϤFá ‡+C %WÒ<5ìèl\; =¼£øëÊhj…`HŸÔаßq ¸Ï‰æ‰!ûÊÜäQ8øaüBï-´O œ¦‹âFáà‡<_¼¶:¦†Q†ÔK gEcê'uxœchÀfd0Œ‚A^H9»Ïb45ŒB0¤WjhØï8 ‡ÜçD‡Ä°·inò(ìPçŠÒ]z¤†½‹âFá`‡Š÷¿q:¦†Q†ÔL =Feê(zxœchÀ .0Œ‚ANX8À‡T½OžIÂA ?>ˆ“\I—Ô°öƒêâØQ8¨¡}ý¯+£©a‚!ýRCÃ>§ýŽ£p°Ã½ÎtI óÌKž; 5tÜï½™>©Áˆ{qÜ¢Q8¨ai·×—ÑÔ0 Áº©ªxgê)txœchÀFÁ SrðÅ ÁÊgR£pPñ–gé”-Ž…ƒ¼·o±ôhj…`HÏÔа×y¿ã(Üp ÃÄùÉsGá †Ìç&Ð+5<ˆY·hbxWyQ´ëhj…`HíÔRÌhê*sxœchÀ NX0Œ‚A ¾ð\À{Ô<ŸIÂA OnèÝM×İ¥¾qì(”ð–tð‡Ç£©a‚!ýSCÃ~ÇQ8xá>':§†¹É£ppÂ'2ñ è›6w/Š…ƒ>”ÿÂí<šF!Ò"5 8mê+sxœch FÁ  $Š;*ƒ•i³žIÂA·¨z7øÒ95R¾»8vBØ’ŸV8šF!DjhØï8 +ÜçDçÄp'yî(”ÐìTI7½SÃØÅq‹Fá „ æ%:¦†Q†´I ökê,wxœchÀ (0Œ‚Afdà7š€›ôŸIÂA“,ëÓ éžvõU-Ž…ƒ:%îRž=šF!LjhØç´ßqF¸×™î‰!ñî¼ä¹£pÐÁº¦¹‰ôO &œ‹ãÂA‹{E»Ž¦†Q†´J ½+jê-vxœch >0Œ‚A>hÜ k4Ï(?“…ƒ†/øàvd€Rþ™Ù‹cGá ‚‘3C^¿M £ 254ìw…ƒ îs Äð,rnò(Lpydæ´J ][ÅÂÁ}¶œ4sM £ i™Fžrê.txœch –Ä0Œ‚AŽØŠ1‚©‹ŠžIÂAöø¥XjÐz±aqì(4ðÜŸÉʳGSÃ(ÃM ûGáà‚ûœ,1è ÎM…ƒ³š›4p©¡ð좸Q8xà}ÅE1.£©a‚!mSQ qê/†xœch .0Œ‚Aþ°Tt00Š1‹Þ'ϤFá €+C­æ?û8€©aíÕű£pPÀ; ñrOK¦†Q¸x0¤††}NûGá`ûœö¸ `b˜·`^òÜQ8(`üB¥{s25q/Ž[4 äùRÞ±8Úu45ŒÂ8z¤ªLpê0‚xœch 8üà`ƒÜи`@(¶h öÍ,<$ÿLj8,˹¤*1À©aSÕ”y)‹cGá€ÃàÎÒ·ÑÔ0 Áp0¤††½ÎûGáà€ûœ81tmV¹77y<Ô¹bvr SCÇ–ÊÎEq£pàáiÓñΣ©a‚!=R®¼tê1}xœch ö¸0Œ‚SrÇÀ²ðgR£p€aƒXKZá@' 0ø1kqì(`xðÞ>åÙFSÃà€ƒ%54ìw…ƒîuè”üs“Gá@Cæ¿sCjøä³(n4¼«¼(Úu “BÃhj>©­Êvê2„xœch "V0Œ‚Ç]ë›ϤFáBËMúÏ>t2€‚œŒ‹cGáÂоªÅÒ  `45 4L©¡aŸÓ~ÇQ8°pŸÓ@§(Ⱦ‹Žx¬`45ÐÞÔа×y¿ã(¤7Üç4ÐñŽ$Þ™Ÿ“…tú3c|:¾ñ‚-ÿùÇŽBº@ߪڴŽp¼`45ÐþÔаÏi¿ã(¤Üç4Ðñì›—§Žc¢ÁñòyÉsG!ÍànW¥»C'5´m_·hÒ r}ûÆé<БL4M ´…ƒ#5I‡ê<Œxœch <‘a4oD600ƒ¬¼¦õLjÒ>çÛ¿ôà³Á$kÁ²Å±£ð†X2 ÇbéŽ`’Àhj Š©¡a¿ã(¤Üç´Çe ã—$p'yî(¤ Ìœnvr^ÂÐJ 'KÅBZÀm^ âG»t“FS­ààI ‘?ˆê=‰xœch 0Œªƒ?,32H‰…AV¦Íz&5 © W†¦XÖ?û8БK28¤|wqì(¤2¼£à–¸k±ô@G.É`45ÐÕÔаßqÒîuè¸%ÜIž; ©ãÖ5ÍMz©áAìâ¸E£ÊçKqŽ\’Áhj \©Yaê>xœch $,øÃÂ0 ¨ 8l >8ad*óLjRêÏ|Èk=ÐKØÅW©¸8vRúV5$tÄ’FSõáÐM {÷;ŽBjÃ}N¯dÄ;‰ ç&BjBï­ñ †fj0áàû²(nRzmûÂí<ÐKM Ô‡ƒ-5D Šê?xœch l`TwT4núƒ Xð¦<“…T‚áÜŽ t”RÖ,]; ©¯ð¤½~5ÐQJM Ô„C=54ìw…Ô„ûœ:F)óÎM…Ô‚Ë#3§ åÔ`ij(nR &,8iæ<ÐQJM Ô„ƒ15 .ê@xœch pü`T &òƒäè>“…T€á §t„RŽ­õ_; ©#g¦K¾Vž=ÐJM Ô‚Ã!54ìsÚï8 ©÷9íuèø¤\Ì—û8ÐQI0š(‡Ã'54ìw…Ô€{:&©>øÏM…”Áø…ÌKº†Cj(>½(nRy¾ÜUž—à2ÐQI0š(‡ƒ95uÝ—êB„xœch l`  H óA œ—|&5 )€+y_~Žèh¤ØÆÂ±8vR= :bê:©FS¥p8¥††}NûG!epŸÓ@Ç"•@éÉyÉsG!0~aGùpI ÷âÇ-…À/<Û:©FS¥pp§4ò–êC‹xœch ¼`d‚#6 ¤†÷ +Ó¾Õh<“…dA=~Ï>tRR¾>¹xqì($ žû3y±ô@G!Áhj ·Ôа×y¿ã($îsè¤"¸“¨wenò($³š›4œRÃh•û‹âF!yð¾â¢XçŽB*‚ÑÔ@ ü©r>œêDƒxœch dÌ`d€ H ëAXÿ¬x&5 I†e9N g:ò¨ö^; I†ÁÏ>täQŒ¦òàðL ûœö;ŽBrà>§Ž;ªƒì+s“G!éPçJI÷ðK ñ÷Ç-…$ÃÓ¦ó:ò¨FSyph¤ŒžêEšxœch 00|`$;*H é!V> _ üLj’Ã'xH^zöq £ŽàÐâșًcG! ð Oî/±ÅÒu4£©t8|SCÃ^çýŽ£T¸ÏiË@Ç ÀÄ•‘s“G!)py¤÷–y Ã15<ˆñÛ²(n’xm]í:ÐQG0šH‡C'5ÀžêF‰xœch 0Œ¢Á ‰„ä„ñ+Óf=“…D²w£õi…i4‡”ï.Ž…DÂðÉÙ|¿”gt¤Ñ Œ¦RàpO ûG!)pŸÓ^çŽ3š;ÉsG!ÑPçŠÒÝy‰Ã75<ˆ]·h ïã\í:БF30šHC+5]¡êG—xœch 00|`D€ Hß!V> _ üLj„á œŒÖ§t„ÑZ93{qì($#g&óýRž=ÐFS0šˆ…#!54ìuÞï8 ‰ƒûœö:t|ÑÜI\97y†Ë#•îÎKÞ©áAŒß–Eq£0ôÙòsq´ë@GMÁhj ½Ô7£êH‹xœch L`À†rBwˆg ‹ŸIB¼0|rÚ¬g:ªèöI¾^; ñÂÈ™ÙÊwKtTÑŒ¦Âp䤆†}NûG!a¸×y cŠàYäÜäQˆ.…QâHH ]›Ç-…x¡Ï–E±‹c\:ªèFSa84S†¦êI“xœch ¼`8Á†òBvÈ•ißj4žIB0|rÚ¬g:šè)_Ÿ\¼8v‑3³•ï.–èh¢M øáÈJ {÷;ŽBüp¯ó@ÇÀD½+s“G!.¸<H&Ž”Ôð Zåþ¢¸Qˆ úlY»8Æe £‰N`45à‡C75뮩êJxœch 8`XÁ ‰‚ ä…êû$/=“…X`YMªÂâg:‚è 6ý[; ±ÀðÉù’¯KtÑŒ¦\p$¦††}NûG!v¸Ïi¯ó@Ç]A×–yÉsG!¨seyäÜÄ‘•:¶.Ž[4 ±@Åû>›Ǹ tÑŒ¦\ph§¹«êK‰xœch œ1ahà…DÂrÃsHƒDf×gR£–Õ¸­O+è¨`ÊØ³8v¢ÀðÉÙ|¿”gtÔ M ˜p䦆†ýŽ£îsÚë<Ð13à—ëÜäQˆ u®(Ý—8SƒÇ·Eq£*Þÿƹ8Úu £fÀhjÀ„C?5DÏ«êLxœch yöq #d@Ú½}‹cG!¶P],=Ð2 `45Ààhj‚ýŽ£÷9íqèøPàôwnò(A³Sñ æ%ŒìÔ ­¼(n‚à‚„/Ü‹£]:BŒ¦>©/±êN„xœch 00<‘añ` ÇòÃpØ€•Ϥ®i=“áзLJçÅ@GÅ ‡_,[;ÂáéóÖòtT 0šFSØë¼ßqîwÜç4Ð11ÀÄùÉsG<¼`0)w4544<ˆé-]7ÒáŸì΃Œ¦†á—ÉÁ·êO…xœch H¼`ÁàÇ‚„”„ß°wþ&5b¡å!͆ ƒ,hµ8vÄÂèyÞi‹«B: M £© ìsÚï8²á>§ŽƒAö6ÎKž;b¡Ò½’ï-£©6ö,Ž[4bayç¼$¯­Î ƒŒ¦†á–”TºêP€xœch L(`‘àHG…ÃÊÂnؽÏϤF |Î÷bÍ2É•üƒ ,9¸8vÂbźû]èàd`45Œ$°ßqä½Îúƒ ¯˜›<aæôIyÞ›GS*hÛ±(n$Âm^?ؽ·¸ tð20š†SÉ¿êQŒxœch 00\0`aàŠŽÇÊBm˜‚•϶¨:>“Qpª§pÂÉ´ÂúA-léX;¢à%¶òÿüʳ:è!M £ ìqÙï8òà>§½ÎòƒÜI°<57ydÁþŽûæ%ަLð zq¢¸‘MO—v-Žvè „`45 /u¾êRxœch L(x!Á0BÀ–5!?( ±a ô>?©Ñx&5"àÊÐS/ut^ tb°4f÷äâű#ÞQ8ýnÍZÞòA FSÃ(@ûœö;Ž$¸Ïi C|ƒãåºWæ& ¿ð‰Ì¤ÜÑÔ€´mWº¿(nd@ž/q‹~°;tb0š†÷¢ÆêSŒxœch |øÁÁ0ìÁ ‰–š„”‡Ö0Ï8’&5ÌaY gçV£¶ìAöÍÌœ—²8v˜ÃðÉ¥çøv t`z0šFØç´ßqdÀ½ÎÖƒ<‹P¾77y¸C+/”B ksE碸áïŸ5úÎá2Ð=èÁhj>1.ÆêTŽxœch иñ‡…aƒ7¨R#”¹Õ„Ê<“¶0'XÃíí³ÌC¬~½Z!qqì°…^¥í¯uKt00šFØç´ßqxÃ}N{\:”‡X1-aáÜäá CWgN›—0šˆìf¼_Å _(ÿð¤Ùâh׿!FSÃpâÆêU‚xœch  °8Á0,Á ‰Ž ê„п/ß~&5 aYÍë5Ó :x‡XÿUnqì0„á“ËuÏ+Ïèàb`45Œ$°Ïi¿ãp…ûœ:t‡˜²j^òÜau®LÊ››4šH±Ç-†PñþöÅ1.¼C Œ¦†á:ÎêV‘xœch HXÀ0¬À– /¨># œ0ZÿLjÁ•¡«y×ìüÿìã@ì»ø~-ŽFðŽ‚OA×C«ÅÒ°CŒ¦†Q€ö9íwnpŸÓ—×! ïÎKž;Œ`üÂø…uóFS9À„sqÜ¢ay¾|á)îYí:Ð;$Áhj{PÏêWxœch иñƒƒaX€ 3P/dF (sã9$ÿLjÀ-ªsÿì•\9Ð:¤Áê×ZóRÇØÒ$üø×•Ð! FSÃ(@ûœö;¸Ïi¯ó@‡ç+¦)ß››< Ù)+Þ›GS%€Ý¬¢sQÜp€ ïyoqèÒ`45 }ÎÔêXŠxœch "ø ðB‚aHƒ'2=%¨&#<[P_£ñLj(ÃkçÎ/š©9Ð9,À¾™©“‹ÇaxM°ÆhGUÈ@ä°£©a }Nû‡>Üç4Ðá8,À³Ý+s“‡6äýì½e45PtmVº¿(n(ÃîRå;Þ[: ‡M CKqÙêYŠxœch 28cÂ0$Á‘9)?¨#¬L bv}&5ás>¿;€Ã R`ìY;á ±«w¯åèV`45Œ$°Ïi¿ãÐ…ûœ:ü†¸“´ÇunòP„™Ó²OÊM Ôbx¾-ŠŠp›Çì΀à Œ¦†¡ ²³ÛêZ˜xœch 2``˜PÀ0¤Àž%1 ¨£V>›ÿ¹ã™Ô‚' yÕ0|K+è †àÐb‡˜ƒ‹c‡¼%}áÅôgÆÊ³:è†!M £ ìqÙï8ôà>§½ÎrÃÜI讘›<”à™÷‚%ÝóGSõÁƒhï‹â†|(o|v^ââh׺aFSÃP3âê[˜xœch ``¸£Â0À‘9)h£V> Ÿ`üLjÐÃç|~1 Åi…`ÃZ|…§vqì ‡7Ä®>žuÇQyö@ذ£©a }Nû‡ Üç´×y ÃkXƒ;I+"ç&~˜9ý'{Gù¼ÄÑÔ@Kð 6qÁ¢¸Á·yqüðؾ8Úu lXƒÑÔ0T#åê\£xœch è¨øÁÁ0hÁ• håûQ€V¦Å®ÙpHþ™Ô …áv|>º@ùÙǨ)?Ô=;/eqì …WxböÎÌ^,=Ð5"ÀhjH`¯ó~ÇÁ÷9íqèpàNâ”<¥{s“+\ÙQ±§}N6#/Ïš>7ypÁø…Þ[u®”t¦zƒ¶í§ÌÅ .ÈóÅk›â½ù‰Î8#Œ¦†¡âˆðê^¤xœch )8à°!à à wTfd(<8à@[ÿŽ<`ß̇¼ŸCežI 8 ŸPmÙÉÀ=Ss ƒdƒMU* ‰‹c^áIJ\øL¹*d ƒdƒÑÔ0 À>§ýŽƒîsÚë<Ð!2‚A×–„…ñ ç&<\Y×TÒí³y45 èØú•‡çË¢¸‡ Š{ç%zoqè Á`45 -Õ>òê_¦xœch 9˜P0%çƒÃ ÐÞ—£€( ÷ùØÁÊϤZn²lè–¼”V8ÐÁ0 À`iŒê½]3³Ç íKL[üKLyö@Ã(ƒÑÔ0 À>§ýŽ ÷9ísèP`p¼œåïòȹÉ•î•ôxo™—4šhÛ~OÙgË¢¸ß¸æ%ym]ã2ÐÁ0 À`45 J®ûê`¥xœch p8pĆŽàŠÎŒ ‡ôòÝ( ¬L[/ybß3)ºÁ©ž-–S$/¥´×G8¤|öWûŸÉ‹cé/±e%®ú%¦<{ ½> 0ÀhjH`¯ó>§ýŽô†ûœö9 ´ÏG¸“è»å¸ÕÜdúÁþuMÞ[æ%¦†ÁDûn} ¸(Ž~Ðôtq¯×ÖÅ1.íõQ€FSÃÐXÇùa¾xœch #HX°aËš'2 &pü`` §¿Fà„‘çÒ/ee‡äŸIÑ ^ÛÉ»P!MGðÙÇöì( vñ½c)û1c^ÊâXÁk‚‰ %߯õ_,=ОÀhjH`¯ó>§ýŽ´†ûœö9íuh¿Ž ñŽÅÉ‹J÷æ&ÓÆ/\9)w^âhjìÀ„cQüVŸòÎEq´‚Ý¥_x|6ÿd_ã2ОÀhjì›\ùbÏxœchÀñ££â€Ãª€',æ¤$,±Â7£€°2-VçÊše3 ŸIQ†/øõ (f–Ñz ûã@{n)?\¬»¿JX:cq,`äÌØú¯×óý²¥Ús£€D0šFØë¼Ïi¿#µá>§}N{Úo£€Dp'qJîä<ï­Odæ&S.tÜÿ“]éy‰£©a¨Ñ¿Ù²{o{(¿(ŽÐgKi7ÇoœÀŠ"Æe =7 H£©að¦ùcôxœch@pÀÁàBGņ€ ˆ?8(pXÓÐàpàƒ€ÂƒôÁ( Ø7óaïò5 ¼ÿTë(?“"Z²Ûä2ÓnQQÚzIþº gÚ£€*`SUãMÝ]3[Zff/Ž%FÏ‹é˪ú÷bƒòÙ_B3ƒž}hoŒª€ÑÔ0 À>§}Nûɇ ý{Ú£€* kK‚Éyñ ÍN-œ›L,Tº§tÏ{ë{Á¹ÉÞ[VD”v¦†á:¶~åþÉþ•gA‚Ï–EqÄÂòÎo\^ÛŒÏ.ŠõÞê»y~‚Ë@{cPŒ¦†Á÷9%ùdÛxœch$€aAƒÆ ‡0e=v8øÀÀ0¡€îNô+Ÿ©4”={îÆ$ɯ°8m,L¸'^ÌñlþçŽgÚ©£€æàÐb—´Í‹Ý^Ëü’|­| žÿÿÿ×Ï;Ž‹b.–h§ŽšƒÑÔ0 À^ç}N0¸ß"äö:´KGÍÁIJîyIYÓ|¶¬ˆœ›Œ÷ùlé,Ÿ—ĉ£©aøƒ1 Çž2óÞê»yq,:,ëòÞê¹}q,Ǹ ´SGÍÁhj ˆý7ùopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-composite/ref/0000755000175000017500000000000012271062644022763 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-composite/ref/a_over_b.exr0000644000175000017500000026340112271062644025265 0ustar mfvmfvv/1channelschlistIABGRcommentsstringcompressioncompressiondataWindowbox2i×ÿÿÿddisplayWindowbox2iÿÿlineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?spi:packagestring Katana 2.8.32spi:rendererstring Katana 2.8.32´fý–*¸Aµ^’¿Ûö "8 (!"×"®#•$|%]&E'.()*å*Ã+ž,q-@./0ü0Ï1¨2—3}4i5E6.78ü8Ì9Î: ;Š<i=R>'?@Û@¬A•BmCOD$EFåF»G˜H\I'JïJµKŒL`M/NOÚO¡P‚QER SÄSŒTWUVïV«WlX>YøYÑZ›[`\#]ù]·^Š_C`þ`»azb?cdÌdŠeRfgÆg‰h:iøiºjuk%lãl¦menoÖopPqrÐr™sStu¸upv?wxÅx˜yZz{Ö{˜|X}!~ê~­p€1ù±‚vƒJ„ …Å…¤†l‡.ˆþˆÃ‰ˆŠY‹ŒØŒ²sŽ8ÿ¶^‘’²’i“”Ú”•P–—Í—„˜:™õ™­ši›&œÙœ‰ôžG ‹¡Î¢ÿ£*¥O¦z§ ¨£©¯ªº«Á¬È­ç®þ¯±'²,³6´Wµj¶{·™¸§¹¿ºÌ»ã¼ø½¿À.ÁOÂNÃbÄyÅÆªÇºÈÉÉÎÊÚËçÌßÍ×ÎÐÏÄÐÃÑÁÒ³Ó¢Ô±Õ–Ö‚×hØ_ÙVÚRÛ3Ü$ÝÞýÞãßÛàäáÙâÆã½ä¬åæçsè\éNê3ë&ìí îïÿïñòñæòíóßôàõÔöÑ÷ºøÀù¾ú²û©ü¯ý¤þ¸ÿ»½³¦² Ÿ¥  ó þ 0a…¨Ëû*[ŽÌù&T†»ê !4"`#‚$œ%µ&Þ'ø(+*v+°,.0/ý/Á0„1[2"3é3Ì4”5_6B789Û9º:—;t<Q=+>?æ?Ú@BC‹CD›D'E±E9FÔFjGòG€HI—I/J¼JMKØKnL÷L„MN«N@OÉOaPôP€QRŸRASÒSsTU¥U@VÓVjWþW‹XY¡Y6ZËZ`[÷[‚\]²]D^×^x_`Ç`oa bÐbcGdef×ÿÿÿ”xœchQÀá€Â½Ã〠.Hhh0¸0°îƒHÕ?g8[ßXÿ<ý?#¦7øÖ7Ú¬ß2ÐŽƒŒ¦™Q@2­›F©`Ë^ç}N˜p¯ó^çvÛ(”@RÉuÀå]wT`Ðy/?PDà½ë@;n J0šfFÉT3íwÄ„ úi Ý6dªÍùØÿÿÿªxœch`FÆ•;;r¦àSUÒ±Âä Ï— èä°Q08oýs‡/ñ¹þ*¬ÍŸX߈>芿"ðáA»|Ã@;z (M3£€ 0Z7ÒÀ^ç}N0¸ß7D¨Úë<Ðn |ÞWt® /ërÞËÿ,ëâÿè¼×yïÊpç=.íèQ0 `4ÍŒ’rtÀ7D®¥Ú̓”ñÏùÙÿÿÿxœch¶`AÂ…+ÈÑ[Òãpàƒ@Àj»i r õ?álüÂúF’ásðúç–ï¿5Ð^t£ifFë¦Q@*Øë¼Ï ÷;’!:÷:´F}Áž»*Î{ù?’˺îõ® sh?Œú‚Ñ43 H°Zé€éVC ´%¢•ÑùÚÿÿÿ‘xœch†@àà —=5-”›”3EãÆŠÊMƒ<¯ß"/â_·¾¥¾‘R˜¯=?QÞý¿É@{iÐŒ¦™Q@2­›F©`¯ó>'ÜïH)„˜³Çe }4 h ž…ÝUáÿxˆ)‡+ÃW†ó¿wh/ƒÑ43 H°Z逥bÎ^çöÑ {ƒËùÛÿÿÿŒxœchV€á€ƒÇj›ZÒ#ó¤£‚Ú¦Ž‚A|ÿŸûŸ®°¶¾‘ªð¹@xüÂýËÚs£€&`4ÍŒ’ÁhÝ4 H{\ö9ísÚïH]2sŸÓ@ûmÐø¼¿§â¼—ÿ#uaYו;Ê.í¹Q@0šfFÉ`¯3¨.9à@]©¡Úoƒ0cÏùÜÿÿÿ†xœch6@àƒÈ›‚ ´3?eÎÚ™> <¯./âÐ[ßH#(}þÔÞú-íÍQ@E0šfFÉ`´n¤‚½Îûœö9íw¤™¾×y }9 ¨ž… |tÞËÿ‘Vpe8Ðô÷®íÍQ@E0šfFÉR/p „ÔOíËA2žÏùÝÿÿÿxœchÀá€ÁzØSÑ!ñBá=l4Rõ[ìÖ7ÒJß{€—a ½; ¨FÓÌ( ŒÖM£€T°×yŸÓ~GÚÃ}Nûœö:´oG€¤²ÀG~:À•áe]Î{\Ú»£€ `4ÍŒ’¨f:à@{©ŸÚ· tFËùÞÿÿÿ·xœchòÀá€Ádþ„tØQA] . Ú8 †ªßb°¾õÏ¢ÁÃ’ÎHòT€öí¿ ´·G=ÍtNÉAƒ]E£if ´ºé:¤zE2Z7 u°×yŸÓ~GzÂ}N{Ú×£€ ©,ð‘ †¯ Cƒõ|(*¨?¸ ´·G=ÍìvE‡©³©œbFÓÌP šé€ªÞF‡›üP‚j§öõ"LÌùßÿÿÿ­xœch aثɹÎÝQy"óAàð‰ïƒÀ#¹;* ÙíðX2'¥§„\›kZ| ¦_F]À #ûXYv¥gÎwÊVJ½ßù“Wí©4NÈözi䤸€•Ï®sMˆŒoûzSx™a}#YÐoýv†ôz©€Q@2ØÅçS˜$ôOCúSÐ.GÜ~sï\fwìp+«sØuظ+óŠrÔlÿE¡ýÙ£if„]|LtÆ1mòO#úZö‰ÂƒšÖjœð¸…Ì“Œé)sb¯ óÛä¶ó™d{ÙVÖMCìýÌwÊÜqÿÀ}Nûœö:´ÿGÉ ñÎÂÓÓõu/?•¹¥æ½•ù¯Ù)ܰ£Â{ëÜä'2Ë#|¶<•fù#ùµx‘™ÚšË ëI€~ë[äÖoèÁ¡Å‰k=…£_¨²mÎS¾ï¼m} %P÷¼îÑòÊCº|f†ú÷g¦™a iFR-kAœtsk5PùΛík‚ƽi¯ Ñ)£uÓP{÷9ísÚï¸?p½ãþ… wìuèðÁÄ)¹ºWÞ nô·?XÒ3)Ïì%p·ëÞO{\²¦ýbËšÆ÷‘ŸxGH¾wèÁƒ˜_ìJ÷LΚžYã´OöqÄ JàaÛÜÉ>[´¯r}“Ø_@JŠM3C ÒÌ.·‘5-9S³)€†ç}¶xmóØá¶Kýæ‡$AHý4Ð2L«ùáÿÿÿ9xœch"Àá€Å‰ h¾q=P8e¶ÉoFFSq®Ê™rÀ¦Þäƒ}’*—•-%UŸIá%EõIO¥© _ðÊœ±vûC²w#O~}#10?îú@Í(À6ýbþÊœ¸®¥cq,ÚÔ:¿6p=Uáî 6uy=ñîs¯3ÕŽ¦™!ÐÓL—ɥϳZ«© åìqŽXî¹µ¯Pû ‘έ›3Øë¼Ïi¿ã`ƒûœö9 tÈŒ ksøªú&³Ss“!p·ëÜd³SÔ…Ìãš,íÖ½ü‹•ÿ#qðŽŠó@Í(À:¶(>(é]°(?ñ¹ì‰XA]˜4oMÈ7®Òn÷K£GÓÌÐèi&d휩ÙT…·U$¤Ìáù2##f‰Ã¢ ¨~è ¡;ä ùâÿÿÿ,xœchôàƒ@Kͺ‚L/$Θl˜’CØ}.{ .Ð>F àÙ–N?f×gRp85ëÓ£×w%ŸJÓ ® ¹*,¶óë™Gxë Aÿö_:F Ø73WÓ±gq,šŠ\x^{} íà;ÕŽæNʹ͌M3C`¦™ÛŽk³§^¯m­¦°Ïi¿ã`†ûœö:tð,BòÅn׹ɸÑßq?ïg³S´ƒ?ÙCWoôûÅæ´ï#?aøÁe i €®Í猸¿-ŠCÀÂ~Ÿ-å+h{‹¯kpXöTŠˆ3šfÀL3<_:+:*³§Òúmz×XÿA n‘ÂT; t ч„™ùãÿÿÿ%xœchÄà„‚'2  ~pÜRÛã2'¥©·;kZè(£8±iËçŽkZϤP`âTËF–§Òt‚ t×Ë.¸x3Ÿ'¿¾ô[ßòŸ±~Ë@×(‚]}±1V‚e‹cQàFßòƵëé×zçVÚ/sXt©v4Í €=ÍÌâi³°µšNð´Év%QO%µ¯àqèhÝ4xÀ>§ýŽCîsÚç´Çe CkAâÝΊ¹Éè°®É{«Ù)zAÇý¼Ÿn«J>ÿÅÊÿ¼£$ß¹ tp 0áôÜÑ]º(¶V/‹ŠXA/¨{ÙgKÖ4ë#K£GÓÌPØÓÌšP÷9S³épxm›“rQ?f‰ÃœT?íuèࢻ‹ùäÿÿÿxœch”@áAÄŠ+: ƒüb»§´ÇeN .{ìPx@Çè`3CÐcO›gRÐyÞó«âO¥éO.³_pñæ«úF¬p‹Â†¶ V>Óä,ck]‹'dc^H˜ÛûúÍ2‡Eþ£ifÜiæ‡dŠf}k5Ýay‡Àû%QO%ëq9y´nh°×yŸÓ~Ç¡÷9íuèPÑ`s—ÞåMþs“1áOö'2f§èëš”îÝR•|Î÷‘+tÞë¼Çe ƒmDƒ; gMÌN/ŠÃ„Wµw¹E¬ ?üÁñP>kšõì)f4Í <ÀfÒf/ÉžJ(ò¦¹vNÊE}‡8 ¨vè`£óÁ‡ùåÿÿÿxœcht`Aœ” ƒüฦµÉ¯¯ÓÝ%=74èZ£67Ì™uHþ™ä¿ZöÝSé… ²2|˜úV£¾ >èº2Ð7BÁÊ4ÉÇ[ç¥,ŽÅ€ü<7¬\? p­÷ëïñ3FÓÌ ¸ÓLõ³·ç[«ž6‰Ÿï¹Õè ‡ÖMö9íwŠpŸÓ>§» 6wÿbWº77³Š_hvj`¡ã~‰ç¥Ý ø>ò£Á².þÎx#ÜIäüQÞ¹(Úü±b`¡îåm^¥Ýª·ÐSÌhšH€;ͨßüÁ™35{@á<_8~8À€ úi .Sô‡ùæÿÿÿxœchTà‚Á††!^‰±™—ÔT‡ê~ƒ $àF.pV½À›òL +üÈa_ÉüTz@—%ý: i<ùõÈо¯þù@âÛZŠ –.ŽÅ ÕnÌ\¸~ÀÌfãÕÜ—Ï2ÕŽ¦™øÒŒ•Ѓ¥­ÕƒŠ?Y51Wû šFë&úƒ}Nû‡2Üç´Çe Ãp„Ò“ ç&c‡Žû•î™,pRÞ1K¾O¿Xù?¢Â;J®ˆ# Ü‹ÿʳ(;”|~]3bÅ`‹â¦fw–/‰M3 ð¥™ã– 9S³ Ô¿È÷éṖ(p¿ã^çDš/&zùçÿÿÿxœch4`CÀ††!¾q3ZÑRƒðẼ †# Xð~æMy&…ú.ýºGð©ô ƒ/x_Üɱ?=3¶¾ ·̵ÿ2ÐA9bÀÚ‚ KÇ•/2&¬ \?ÈàîWŸŽJº¶T¦™øÓÌÍ7BûÛ[«”°Þÿ­à5 $oŒÖMôûœö;}¸Ïi¯ó@‡äˆó$,œ›Œ ^0Èœnvj°Aæ¿:—ù>=•âÿƒÎ{ù?¸ tPŽ`Äý•gQ.xÀÁoSÄŠÁ“æu—Ö7ZM3𧙇 [½s¦f2x[u^Rmse»Ã8ÕN”4Ó`xùèÿÿÿxœch@áÁœ”?, Cüa¹¡±.¨­ â—’ž š#lfá •y&…æÔ¾<+úTzB«Cî½?WN¹ìS߄Ϻö— t€Ž°òÙÌÇf ‰‹cq@ Òw×V¨{~…Åß»ÙËFÓ ¡4³ÓR¿º±µzBå;ÜŸ?ò6Õ@=3Z7ÑìuÞï8\à>§}Nž#lîúÍ¿pn2.ºz·«Ù©Á w»NÊ­oì,çûÈ„e]ü:@G¸“ÀõƒçË¢8\pVÚkшƒ¶m¬¿¯xÞ€4ÍÐJ3†ÙgO¬Ðð¼îå˺Ӳ€!¨~è¥)ë{tùéÿÿÿxœchpÀÀ°áƒÃXnh¬ i©ù‰ãÇ@‡ê°+ŸmYúoò3)œPýƒ»’O¥9´:äÞ+Þvhfl}c½Ÿý—ú-°ÃZÈÂ23{q,Nè´óœöúÀÁuϯ°°íÔR5šfh§™›.k®×¶Vr¨|‡û³ëÎk`OÖM´{\ö9íw^pŸÓ—×a î$Xž\977ôÞÊûÙìÔ`‡»]'å²üy*Åÿ‘ÿãþwn°Ã<ˆ^ï»eQnXÜÛY±b°Ãöõ"o,¦ÚÂiæ¡BGeöÔÁ Ïë^ÞæUÙîp÷;îu耥b nùêÿÿÿèxœchppĆa_l Å5Õé\q80Ð!;LÁÊ´ {üžIáÏ_=~*=dàIÃ# oÖ„ðØäO¬>Ð;LÁ!e¿?“Çâ†'V®20·w…qcè)&¯Ñ4C3@8ÍÚZ=d`yGôâ—"ÚWFë&Ú}Nû‡#Üç´Çe Ãv˜‚;IÇ­æ&ベÓÍN X×´<âÛ/Ö;*w”\:p‡)xóPqQ>(ý4bÅÐ?8ÂVÉ?\=šfh§™€9S³‡ y³ËMýḟýŽ{:piv&lùëÿÿÿÕxœchP°á Ã0_xŽYUµpØÐ–Àyi¾¡â3)<ðÒïçO¥‡,¯I àɹô?} x‚m,­Ò‹cñÀ'¢«×9¨}êÕ[•ßÑ4C@8ͬ»×Z=ä`qÏÿ²ËwŽÖM´ûœö;S81Ïi¯ó@‡ï0¥'ŸÊÌMÆw»šzð˜•ã¾Àõ·•]:€‡!¸ÿH~Q>¸Ã#bÅЃ32ìp¿3šfh§™»*9S³‡Üç¤}Õk«ã>§`šß«gùìÿÿÿÊxœch0pÀaMðåó'20 \;°o&ÃËÌgRxá¥ßÏŸJYøçk›Ç¡g: ‡ØTÅðnÅâX¼ð‰èªÀõCN §ýŽ#>”’ûœ:´‡ØÜ½Én2~¸ÛÕìÔІŽû=v”ôÌMM3ÔwÍN/ŠÃwxD¬Ú°¾Qú鼤E±ÎÜÓfîªäLÍÒð`yçÜa—fcg^ùîÿÿÿßxœchÀÀð…‡a &¬‡ Xùì„¡â3)¼ðÒïçO¥‡t°iphñ-éŒÅ±xáÑUë‡<ôÚ¦ø"aqpg%߯ÅÒìC“fÖÝk­òð®´ý›£i†`ŸÓ~Ç‘÷9íuèPÒàNÒS™¹ÉøánW³SCNÊ»`07YçŠÒÝy‰£i†ð ö‘ü¢8üp‡GÄŠ¡epXwÚôçâ—ö! ˆI3wUr¦fyXÝò@aá0K3¹î[ùïÿÿÿßxœch`pá È?8fdpˆðÀ¢·8Tæ™^¨²ãÆSéa-Ï®[ªô‘å¡tË)35:ð‡(Xûa‰BââX¼PæþŠÀõÃ*ßU|‘ôQô<ÏÄUU!øC“füi­°¾ÚöÍŒÑ4C)Øç´ßqdÂ}NöCÌ[°pn2~XÒcvjxÀÝ® @>RºW×ä½e4ÍŒ¸y¿,ŠÃöE¬ðµèÊ;‹{½¶:tàQ@LšY™35{XÀƒö÷«4UùðÿÿÿÙxœch ;HXÀ0‚Á  ôõ! N­&E†÷*=l åÙuK5 >ûø@Ìíí³ C ìâûµ8–¼'»"pý°Êw_$@}æ__ñZg±ô@GÂĤ™È•Ò­ÕÃÖWÛ¾™1šf(ûœö;Žd¸ÏiË@ÇÁ‰wç%Ï%—Gš>p·ë˜Ï÷gN›—0šfH&œ‹ã€æ'#V øZô€Ìg¥Ý'ÍG»t$ 1@LšñÙš35{ØÀƒö÷£4weQùñÿÿÿàxœch 3HXÀ0âÁ™Œ ôù! N­&Ev¥\¸+ùTzA˳ë–j |x­íÏŠg:*† ØÅ÷kq,¸0ú¬öúÀá•ï*¾H€ûïš`ðçÅÒC“fN ¿½^ÛZ=Œ`}µí›£i†\°Ïi¿ã(Üç´×y cbȀĻó’瀷Ôx?›Np·ëdê\™›8šfˆ&œ‹ã€º—;Ë#V 'øZô€ÂÝ¥Š÷Ǹ tT @Lšé¬è¨Ìž:œàAûû ‡Mš[ÂOùòÿÿÿáxœch +HXÀ0 ÀàÇ„ú†ý'ŒÖ?“"ïHÞ=+úTz˜A˳ë–j ùÒòÐ’Ïi…!Cìâûµ8–ì*‘¼»>p¸A廊/|=Ï=æ òìŽ!ˆI3¯ŽW7¶V3X_mûfÆhš!ìsÚï8 apŸÓ@Çljwç%Ï%'åív5;5Üàn× ȾTº×Q17i4Í&œ‹ã€!k^‹F¬nðµèd_–wzìXã2Ð21iÆòÄ!ûì©Ã ´¿¯°p˜¤”Lùóÿÿÿæxœch #°8Á0 À–%1èCü¾|û™øû?ãj¾§ÒúqPFñëÊPŽEí35:Z5XÿUnq,XÒ½Åi]àúa½¶=Q‹Gñë…“/T… t´ j@Lšù«ÀÖßZ= á]é ¡ûFÓ ©`ŸÓ~ÇQˆ ÷9 t¬ j0eÕ¼ä¹ Ä ‰f§†#œ”—9Õ¯ñ ß zoM3ø@ìƒÅq‹ÀêÖ +†#”}¼Í Õ¯<_ŒÏzmuèhÔ€˜431_óFÎÔìa«[ä-i:ÕKùôÿÿÿãxœch ø ð‡…a`€ ô‹…!ž-Ø*óL /œšåRÀøTz˜Âˆ-NÊ~Î Ž~öq #g‚}3_)$.ŽÅ ÍN6^¸~˜Â™Õâ1üìU:o±ô@GÎ Ĥ™ÛŽWZV¶VSØ›¼#tßhš!ìsÚï8 ±Á}N7ƒ<‹HX87?Üèÿ“ÝìÔp…Žû3§cú9tõܤÑ4ƒtmæý²(?,ìçø±b¸ÂúÆm^˜~–¸(Öy #gbÒ Ï—]î9S³‡)|'(÷há0H3ºEùõÿÿÿÖxœch XðA€aà>Ð+&† ØÜ°yò3)p¥ì»§ÒÃæ,þ¯€Åßú3¯ßè(t`eÚú™Ù‹c @ «×cøT¦¾;‹¿}«*ïüè(t€¸4“øö|kõ0†v« r¿Ž¦bÁ>§ýŽ£7Üç4Ð14èÀæî‘s“ Áø…f§†3|/(ñ›¿½·v”¦tp'ÑwË¢8Bð OÄŠá ÊW·bó·×6íÎEƒ—f~pæLÍÆ0aþ„ü¡Ÿf½ÔGùöÿÿÿÖxœch  8àpE‡aà Ð'6†Ø7ó¬§Í3)Pýµ§ÒÃί¼U$‹Õ÷[T½ÎtD "°©Š›­uq,è´sEàúaWF~ÃêûÀ–üg:¢ .ÍÜtah­æðۃŠJ£i†°×y¿ã($÷9 t< "еy³ÿÜdBÐ{«Ù©á•îÝRÃî{³S%Ý£i:¶˜Ÿ^G÷F¬îðº&ß'ì¾_0/Ñy #jâÒÌC…œ©ÙÃÖ78îêi™ @ù÷ÿÿÿÓxœch  XÀ0 ˆ Ð'F=ØÜPöLŠŒ˜sê®äSéa/ûßÊ’Æ[T½Îtd °2móâX0yÖíõÃfϰ?…+ [òŸ}èÈ$€˜4cU#|½¶µzØÃu¢eŽŽ£i†0Øï8 ‰ƒûœ:® ØÜ37™\ÉûÙìÔð‡¡«7úã ³S%Ý£iî$-Š#•ïv–G¬þð¬qa?®0X0/Ñy #kbÒÌq«ŽÊì©ÃÎKäþ2´Ó š>ùøÿÿÿËxœch ØÀ0 ˆGlè+ƒ8/=øLŠdûƹ˜ç©ôÈ€ÂÁxBB`ß³e¶±p,Ž%ÚÝ’Y¸~DÀêÎTE‡@˜¬ä}ù9~ £o@À¡Åþõý‹c @™û+× xU{mt"0ñ(舩èè@\ši\ð§µzAõëšÂ£iØã²ßq’÷9 tì ¸“à²n2!XÒcvj$AÞÏ·Ô…IüÂŽò‘™fDWt/Š#öE¬I°³\÷2¡0ùÂã±Ýy £o@qifEdÎÔìÛ+Û+Ù4rØ6ùûÿÿÿâxœch 1ȘÁ0 ÈXfd8 u :ÀúgÅ3)ðŽäÉ»’O¥G´<ë! L \V†¦XN‘\9ÐQHw°GøóâX°«ä´öúÀ‘•ï>Q‹'.wÜWýº2ÐQHw@LšyuDúzmkõˆ‚õÕëB÷¦ì`ŸÓ~ÇQH>Üë<Ð1Hw}en2!8)÷³Ù©‘w»fN'.ñ ëš¼7¼4oqÜ"0dMgyÄŠ‘_‹nó".<_Š{½¶¸ tÒ“f,OtTfOYð ½ì£…C4Í.Õ5ùüÿÿÿìxœch 1øÁÁ0 (_xhCƒ ¬LÛyHþ™^ÈÿÞ°‘å©ôˆƒ“¢¾É©g' Óf¥tDÒR¾=/eq,^Èÿ¡¬qmàúÏŸ¶‹#6±‹oIg(ßUž=ÐIG@Lš©Þ j³°µzÄÁwŸ-ú…GÓ &Øç´ßqR ÷:t<ÒÜIR¾77?@x­æò¦ŽJºõ¥óÇ€ÜïV®‘0{†ý)B¡‚ד¿Þ訤 &ÍH*=j­‘ph™£ãhšAûG!5à>§ŽIº)«ç&‚“òÌNLºz£?áðÁÐU#'ÍÄ>\G¾X12áYãÂ~Âá³(®»Tþó@G%Ý1iFìuÎÔì ç%rŠiŒÖ1ùþÿÿÿÑxœch !иÁ0 ¨ΘdÌ`` ]œ 0x¦°ø™xé÷ó§Ò#Fl û¯@0œ`0|AýŸÏ>tÔÒ ì“|½8–|"º*pýˆ†32ë»ã† FÎLþ¼Xz £–f€˜4s°î^kõˆ†½É™¹_GÓ ìsÚï8 © ÷9íq蘥x97™ÜíjvjdCÇý/‡ .Ô¹27aø¦™®Í‹ã€;<"VŒlXßXÝJ(”Ðg‹â½ÅÑ®µ4Ĥ™»*9S³G4|'8!¨¥0*ùäxœch p8ðA€aÐÜÐø @«XP°O’ò3)¼ð’âé»’O¥G8Üšþ Kš@H!òœÒ¿:zi6ýš™½8/´9xF{}àH‡ß¹Ná'TÜY;Ss £—&€˜4ÓeÂ}½¶µz„ÃeÙŽŽ£iö:ïw…´ûœ:viº6¯Œœ›Œîvåýlvj¤Ã ý …2Ô¹²›:ziˆI3!k;*³§Žtø‰—ûËÐJ3„ˆ$ùÔxœch ˜‘Á0 h$(< UÌ øhYÿL /œšeÐÈòTz>õ{åI ¬Ð¡JCÃÙŽbªƒå‰»Çâ…f§J×®…¶'R„:tI›õìã@G1Õá4sÛQÅfakõ(l=\u4Í€À~ÇQHK¸×y c˜ê`oÓÜdüp£¿÷V³S£ÐìTætBa…KzJº†_šÙØ»(?,ì_±bF¬~J(¬Ðἤy .ÅT„Ó Ï9S³GáT¿ ‡Tš¹#ùáxœch  ˜Pð‡…aÐ|p8@›¸  ÷Y§Žeª‚ãå ç&ã‡Ç¬ÌNBäýüD†Ph¡Ãå‘Þ[†WšiÛÎûeQ~x_1bÅ(ÁÎòþBB¡…}¶xmuèh¦* &͘žÉ™š= °½2wÒÂ!”f)6 ùÜxœch  XÀ0 h8Ð&öln({&…~ä8Uü©ô(Ã¤Õ ßä„&ÔŸ”V8ÐQM5°2móâX¼PíÆgæõ£÷;±‹#b˜Ð·jšòìŽjªÂiÆÊç½f}kõ(ÃglºýÂ#<Í4ìw…ô€ûœ:¦©6÷ÌMÆ÷?‘1;5 !PâÅ{AB!† ½·ÎM>iæNÒ¢8üPòù.·ˆ£7ÜU&b˜ÐkÛ¢—ŽjªÂiæ¸å²˜ì©£ÕoD/:iÚŒùâxœch ˜Pð‡…aÐüàȘÁÀ@‹8¤3Ðû,*óL /,sûñTzÂáÝ!† Zªþ³âÙÇŽp*€¥1 ‰‹cñ¶Â5ëG!²ÿM%bØ`ô¼8áÏ‹¥:©ˆI3+vîi­…pÈ¿”}D§™†}NûG!}à>§=.ßTÇËÎMÆu®˜…¸ÑŸPˆaƒJ÷t®ÌMi¦m;ï—Eqøá?¦ˆ£'æ 1l°¼SñÞâh׎p*bÒÌMœ©Ù£›k™4ZùÈxœch XÀ0 èNX,H E,Òln({&…v¥{*= Qà¾>S¡†~|Üà;ÐQN1X™¶yq,^¸0zyàúQˆ_É&5ìп¾,­p £œb@8Íœvl­…(pûÊèœfö;ŽBzÂ}NãƒÍ=s“ñÃ[jf§F!*\I(Ô°CÇý%ÝC?ÍÜIZ‡ê^ŽX1 Q¡ùIB¡†–vÏKtè(§N39S³G! ôÚºpˆ¤ 1ùúxœch :p8ðƒƒaÐüàȘÁÀ@ý˜¤Ø'ùñü3)“ NÜy*= 1྄d!‡~|Üà;ÐQO68atbq,^xNgeàúQˆeŸ¥9Üп¾,­p £žl@8Í\ ÿÚZ= 1à¿3GhšiØï8 îsè˜'ø|ž›Œ³2;5 1áòHB!‡:î/éºi&ñÎâ¸Exá}ň£fMÃnø`i÷¼DçŽz²á4cz&gjö(Ä€ÚW‰4M÷ù âxœch 2``ø À0 |á‰XAíØ¤ Xù,|ò3)<ð÷ÿÇG„ŸJB,pÚz¼a‡ž0¬}Ó?ÐÑO8´8rföâX<°¤Û~ÛúÀQˆ úíLÂvøà-é8ÎýýdÂiæw®¸tskõ(ÄÍ]F`šiØë¼ßq Üç4бO¸“¸2rn2>(ñbRžÙ©Qˆ zoÅvøàËC3Í<ˆñÛ²(¬n•}±bbƒÅ½øÃ|(ÚÄy £Ÿ,@8ÍL̯mÉ™š= ±Àû ‡@š­Îù ×xœch 2(˜À0  ìðp8@í¥9x¦°ø™^¸EøíSéQˆZž âP$~ø`NpäÊN$ƒ}’¯Çâ…ù«×B¬Pù®Ñxá‡z•öýº2ÐI€d@8Íìœx¹µzb…õÕó|®¸4Ó°Ïi¿ã(8¸×y SÉàYäÜdüÐìÔ(Äw»:î'~ø`èjïÍC/Ítm^·/T½±bb‡¯E%Ÿã=üPþ¡×—N$ÂiÆðBÎÔìQˆ´?j9øÓ /@ù áxœch *``x À0 ¼‘xAÝ8¥1XùÌr“þ3)<ð¹Àñ»’O¥G!¸/!oø‚Ïùrw^èd@8´8´¯jq,xCí´öúÀQˆ Ê>KÃ~„à ±‡?:§¯P­ëµ­Õ£üwæãK3 {\ö;ŽÂ…ûœ:î$¨Þ››ŒfNçýlvjâ‚Ë#ñ‡!˜9½®qh¥™Ñ?¹ÅáƒÛ¼:Ë#VŒB\0kþð#·y÷8t2 N3ò:*³§ŽB\PûÊÂAŸfnâù Íxœch *PxÀ0 L( n¬ÒlføöL /l´ýöTzâó—[CBpþ玴ÂN Dƒ•ÏŒÇâ…k½Ö®…x`ÙÄ$aH:ÄTž=ÐIh@8Í0Äh­…xಠ®#*Í4ìsÚï8 îuè”@4ØÜ=/y.^Èü×ìÔ(Ä•îáA°£bnâÐI3wÇ- õ/F¬…øà’ü!HzìXí:ÐIh@8ͽϙš= ñÀO¼ yšÉù Õxœch *ØãÂ0 ¸`0¡€º1K3p§,ü™xBóðSéQˆº‰ú¯€7 Ã-ªÇ>Çtb ü˜µ8|Ï·,pý(Ä ½¶5tÇá EÂ0°%;¦~ ‘€PšÑ\ÐZ= ñ»҉¹_GPšiØï8 Üç4ÐiHÀo07|"cvj⇓ò$^àEÂÐìTGùPI3Ÿ|Åáƒý…+F!~(û¸º(† <¶;tb J3ù“r¦fB¼°ºeBþàN3° ùÏxœch "XÀ0  øÂcpšqK#°¹¡ì™^è\ÀøTz€t#„#axÂpCïîND€•i›Çⅇ׮… ûßTáHÞ’þðx €pšùв²µz€üKÙGLšiØç´ßq¸Ïi Ó`s÷¼ä¹xáOv³S£Üè?‰Odâ …4s'qqÜ"¼ãGÄŠQHNÌÇŠÄÀ‡ò_¸:A§™]î9S³G!Ø\³pP§ ùÉxœch "è)aƒÌÈ fìÒøžï}&…–•œz*= ‰€Stð†$q0ɲ>­p pÂèÄâX<0xåòÀõ£¸6:oHw)ÏèDAJ3™MF­Õ£¨.Ü8BÒLÃ~ÇQ8¸à^çN€Ïç¹Éø Î³S£xK Hëšæ&ö4“xgqÜ"<ð´iÄŠQH Ô½Œ/‰…Ž‹¢]:Q„ÒÌ’Øœ©Ù£Ø^±p§`çùáxœch "x#Â0 8c’°€š1Le°2-Oõ™¨ßÈòTzs§¿—Á–ÄÁKÌ)Fm0ð€CÊbù‹cñÀÒÆµëG!ð©ŒÔ‡8¼aI¼ÀØÂ·c @8Í8Ø,l­…D@»Õ6€4Ó°×y¿ã(lp¯ó@§ <àNböô¹Éø ÷V³S£ø^ð˜þ°$îvUº3˜Ó̃è^‹âðÁeQ+F!1ð¡¼ýAüaIäúöÃe @8ÍxìÌ™š= ‰€ óÕnÞ4PÙùÐxœch иÁ0 x#ÂñƒzqLePæöö™XVrê©ô($ú½òÄšÄÂç|/t^ tÒÀ V¿ÖY‹¯\¸~ mO¤à Mbá ±âµ¼4pBi&³É¨µz ÏWi¦aŸÓ~ÇQ8øà>§N8ÁŠió’çâ:WÌNBbaæt|aI<Ìœ>)wð¦v³Åq‹ðÀÓ¦+F!±Pú)¾°$nóúÁî<ÐI' ”f–ÄæLÍ…DB¿ mš‡ÔùÚxœch ØáÁ0 !øÃ’1ƒz±LUð;8ú™¨ßÈòTz U‚7<‰…+C+þÔtâÀÖ—Î[‹–6® \? ‰„Wµ÷úÆã Obá…há8pBiÆÁfakõ($ª_ÿÅ»mا™†ýŽ£ppÂ}N6p€)«ç&ãƒÞ[ÍNBb!ïçº&üáI,Œ_¨sÅq ûpQ>¸,*bÅ($v–·VãOb!ÏÅ{Î8pBiÆcgÎÔìQH$l¯\ºp¦ËùÍxœch HXÀ0 -XC­x¦"8a´þ™è7õâSéQH<žˆ7DIl‹ŠÒ :‰`€]|¿ÇâÛ]V®…$@×}ixC”xôÅåÙD0¡4³2A¤µz’à ¿ ó4Ó°×y¿ã(¼p¯ó@§ xg~ò\<ð‚Ù©QH ¬kž¤Á÷‚s_š1áX·dû±b’ç¤à OÒ ñÙEÑ®D0¡4sS#gjö($¦Ì^8HÓ åCùÛxœch ȘÁ0 18câp€ZqM%ÀúgÅ3)œpj–à,®§Ò£$x²ÕO˜’/1GI®èD‚ö^‹šbü².pý($ ~OĦ¤Á Œ5¿® t"AøÓÌmGÿi­Õ£$˜þ1yX§™†}NûGá`†{: ì+s“qÃþǬÌNBÒ`]¾0% îvõÞ<ØÒLü½Åq‹pÂÂ~¡w+F!i0cî%r}óÚâ2Љ àO3<_æ¤æLÍ…$Á=Î eš*ÇùÖxœch ¸`À0 5x!qÀZ±Mà¬êøL 'Ì©=ýTz’“Vg¾—Áª¤Á²Û™šLPÀ¶–ŽÅ±8¡Î…åëG!‰p¿“Ô‡8<¡J Ÿœ\2ÐÉàO3;-µ[«G!‰ðÛÛ FÃ8Í4ìw…ƒîsèT‚JOÍMÆ CW›…¤B‰Ǭð…*iPçŠ÷–Á•fî%,ŠÃ g¥E¬…¤Â öñ…*iPñ¾×VçN&(š1¼35{’Õo¨ÝŒiò‡ÿêÎxœch  ØÀ0 =øÂ#ñ‚:ñM`Á›òL Ôody*= I†Üñ†+ið„aæÎkTà`mÁÒűx`iãÚÀõ£d˜º0o¸’oIû>ü1ÐI¥›…­Õ£d¨ž­9lÓLÃ>§ýŽ£pðÃ}NRà`Þ‚yÉsñ@ï­f§F!éÐq?¾P%>‘©k ɻܞKâWÒ!Ï—Ó&ÎX š{35{’—ÄÜ—|i5}ûê¼xœch  ¸£Â0 †訠NœSžM0~&…†'ü}*= ɂ͢ð„,9ðN.``ÉS»8'|¶&pý($ >PIŲäÀDÝÞN.`€?Í,8³±µz’·32Ó4Ó°ßq8Щ žEÎMÆ —Gš…äÁ[jøB–8)op¤™y Åá†YÓ"VŒBò`Þ%þ`wèäøÓŒî•œ©Ù£,èµuá K3 !úêÃxœch 8àÀ0 †XÀÀ@x§ì›ôL '<¡yø©ô($nYª'tÉ* eÏ>pšÙT5mq,NøžoYàúQH6T|‘€'tÉ.i›Kê4£¹$ µz’ Íß̆i¦aŸÓ~ÇQ8”à—N2][æ%ÏÅ ŸÈ˜…äà ¸Ã–Äá còà¹?Í¿® Ê4#hv­µzRíVØ`4¬ÒLÃ>§ýŽ£p(½Î”dæ-˜—<'äýlvjRß ³ÂÂäÂcVÞ›*Íq/Ž[„†­ŠX1 )ƒåíâará}E¯-.ƒ2ÍdMÏ™š= )‚ óÕn¦4TöêÌxœch Tt0Œ‚! nh8 <þÉ'œæ?“ªÏ^*= )„å'œp†1ù°,ÇWr値™rOÇ″R?1¯…”Â[:É8Ø|ÜYøëÊ K3Ñÿd4ë[«G!…P?ÜtX¥™†}NûGáЄ{$É$Þ››Œ 2ÿ}"cvjR Yácò¡ÎïÍ“f¶v,Ž[„® Ùå±bR ï+â aJàiS¯-.ƒ.Í”w.‹Éž: )…Æg¢4ûÂõêÇxœch œ°`CÜÐp8@y <ð|&…²^¼÷TzR ]ޤ~“ÃÊäò_É•d¶Ô÷/ŽÅ—¯ \? )†^ÛÎÚÅá eòapgá¯+ƒ,ÍTnþØZ= )†w¥û…‡QšiØï8 ‡.Üë< ifn2.ø^ÐìÔ(¤NÊ{/ˆ;”ɇ:W¼7DšÙܽ(\±bReßUÆÊäÃÓ¦^[\YšùÚ35{R «[¢— ž4ý—õêÐxœch 8`CÜÐp8@i 쓼ôL äÿy ÿSéQHè÷Êg8SËr|%WÒ9Ílú%¶8äÿЛ¹.pý(¤´=‘‚3œ)Á…¿® ¢4S½%¹»µzRž?®:lÒLÃ^çýŽ£p(ýÎtN2]›ç'ÏÅY9î7;5 ©3§ã eÊ ÎïÍôN3[–Ä-ÂíÖ7F¬…Ô€ÒOq…2eð´©×—A”fÔo~Ì™š= ©ý6.4i¶¹óê Ëxœch xì`C\08à@i* $œ|&…†÷*= ©õ¯ÆýWÀÒ”À-ªa35éšd¶üç_‹Þ“]¸~RþenèŽÃÒ”ÀÀ–ŠªA“f"WJ·VBªÀËš±¹_‡IšiØç´ßqm¸×™Îif^ò\py¤Ù©QHøDFâ®p¦ šòÞLß4³¹kqÜ"ÐüdÄŠQH¸Ë­ºW8S$xmq4iÆgkÎÔìQH¸$¦?°¤åðê!¿xœch l`C±9à@i: Xð¦<“ ŸJB*AUî@œ!MØ“;a¨øL +Œ˜sà©ô(¤T½{±G GXS öø=ûH§4shñ-éŒÅ±Xaò¬eëG!ÕàUm.†xaM)<÷gòbéAf¬jÒ[«G!Õ úuË='†AšiØã²ßq¸Ç…NIæNÂs™¹ÉØáòH³S£z÷sèj\aM)ΰ¦ošÉiîê#»xœch 0Œ‚aÖ„00P–ˆ+ŸIá„[„ß>•…T„lªax›2xâeæ³tI3‡Çâ„ù«×B*BÝë©x›2xüÝŠÅÒžfvN¼ÜZ= ©Ó=¹‡AšiØç´ßq¸Ç….IæNÒ¼ä¹8 Ù©QH]ØQ+¬)‡Odæ&Ð'Í<ˆ]·T½±bR¶Å֔øE‹¢]<Í^È™š= ©÷8/iN@íê$½xœch tT0Œ‚a¦äP–ˆ9k&>“ پ¹*þTzR:KªâoÊaƒX4]ÒÌ1Ýó‹c±ÂƒvŸ˜×ŽBêÂi%ñ8›rxð^ͧ™ÝýÚšõ­Õ£ªÐãÈú!Ÿfö;ŽÂáé’d.æÍMÆß >‘1;5 © 'á oÊ!ó_ú¤3öÅq‹°Â»Ê»Ü"VŒBêÂ5ØC›ð®²Ó§™˜%Ëb²§ŽBêBó AštØêê%²xœch \0`ÃdÌ ,5œUŸIa‡n=•…T†/lcp…7`ÙŸz:¤™m-‹c±Â¯¬+×B*Ã^i8›0\x〦Í??Z«G!•a\,ÃO3 ûGáðûœèdJOÍMÆÍNBjC濸Ûr¨sÅ‘iæ^¢8ìPàCÄŠQHm¨WxS*ÞsÐ4“?)gjö(¤2x¿p¤=êê&Àxœch 8`ÃüaQx@Iz 쓼ôL œÄñTzR:Kªâs áÊP5†³4N3›~‰-ŽÅÕϯ \? ©§•Äã sJág0ÍLø<«µzRzY?¤ÓLÃ^çýŽ£p8Á}N4N2]›ç'ÏÅ ÍNBêÃIy¸CœR¿°¤›Öi¦cË’¸E8 Ëžˆ£ú0d ®§ò|™—è<€iæªNÎÔìQHuh~bဧ3Éêê'Ãxœch \`à |á9à@IŠ ,zŸ<“ Oh~*= i_ØÆàsjÀ†f35išfÖ~P]‹¾ç[¸~ÒîôJÃæÔ€·¤#ªB(Íh. h­…4€q± C:Í4ìsÚï8 ‡ÜçDÓ$3oÁ¼ä¹Xá³S£ù/ö§|"ã½…¶iƈ{qÜ"¬°¿0bÅ(¤Ô¿ˆ=Ä©Ê{mu 4“?)gjö(¤x¿pÀÓ 7;åê(¿xœch ,H`à HšÙ¸ôxkõ(¤ ô8²~§™†ýŽ£pøÁ½Î4L2›{æ&c‡ýÍNBÚÀIy¸BPé^I-Ó̤EqØáÄüˆ£60d ®P§üÆ5/Áe@ÒLkMÎÔìQHh~bá§êê)Éxœch Ò,Íìê«Z‹´ûļ>pÒîôJÃêÔ‚§ÌZ,M÷4³»_[³¾µzÒÆÅ2 á4Ó°ßqG¸Ç…fI&ñÞÜdlð½à³S£6ù/öP§¼`07viÆ„kQ6xWy—[ÄŠQH¨{¨S nñYíJ÷4³dYLöÔQH(ð~á§@åê*´xœch 0Œ‚a :*(IxÀÊ´YϤ°BýõמJBšAgIU!OxwMÒÌ!廋c±B§+×BšÁi%ñ8Bž:0Q·—îiæ¦ Ckõ(¤ô8²~ˆ¦™†}NûGáð„4J2w’æ%ÏÅ ½·š…´ƒ“ò°‡;µà¤MÒ̦_b‹c±Bÿåk×BšÁ ©8BžZÐáÎ:§™ÓçµVBšÁýoù‡hšiØç´ßqO¸Ï‰&I¦k˼ä¹XaIÙ©QH;¿{¸Sv”Ó&Ítl]·+,íŽX1 i¿ð`wêAíÎtN3|Ÿs¦fBšÁoœ 4Í]¡åê,Êxœch ,H`üIX@~ÊÀ 67”=“Â#æx*= iUï^ìQÂöÔ‚Ïù\ŒÚhfV¦m^‹&ÏZ¸~Ò^ÕæbˆÇöÔ‚7ÄÒùvÐ1ÍXÕ¤·VBBõë–{N É4Ó°ßq_¸×™IfsÏÜdlpy¤Ù©QHKÈû9t5ö°§Ìœ®t‡iæNÒ¢8lPùnÄŠQHKØYþ\{ØS nóúÆáBÇ4sÜ*gjö(¤!l¯¼/?iœâê-²xœch ‘‘x-ô© u.S;͘p,‰[„öûmŠX1 i w¹U·b }jÂÓ&ÎtJ3<_¶yçLÍ…4…Kbúó.Í„Îàê/Âxœch \`ÃüàX@nêÀ ,zŸ<“ÂËJN=•…4‡–¿}±†?õ å!Í_ª¦™µTÇbÁ+—®…4‡DS°†?õ`ô<ï´Bº¤™Ì&£ÖêQHs(_'7äÒLÃ>§ýŽ£pxÃ}NTM2óÌKž‹ê\1;5 iw»b }jB¥{%ÝÔM3FÜ‹ãa§M#VŒBÚÃØBŸš°¼s^¢3]ÒÌ’Øœ©Ù£æð¶ÊÂK39’Ýê0½xœch ÌÈ`Ãp 7u`-ëŸIa¶ßžJBšCý«™ßä°Æõ þLMª¦™å‰»Çbk½Ö®…4‡™ÏÚÅaêAߪº¤†Ø­Õ£æð²¦l¿ðK3 ûGáð‡TM2{›æ&cƒÌÍNBÚÃ'2ï±Çõ ÷Vꦙ½‹â°Aý‹+F!íá.·»ÊØc€zÐk›]ÒŒÐûœ©Ù£æpILÔ’J3àÞê1»xœch \0`Ãxì 7}`ΪŽÏ¤0`CõÙ«âO¥G!`ò 7,1@]ø1aÓ̶–ŽÅ±pVê'æõ£°§*K Púÿ?Kó4ýOF³¾µzÒÖóë±4Ó°ßq¸Ï‰ŠI¦ôÔÜdLÈü÷‰ŒÙ©QH(ñ[ PR7ÍÜKX‡ ׄìr‹X1 ék›±Åuai—3ÍÓLy粘쩣ð ÝÂJ3z­ßê2Îxœch p`#|Px@^ Áûf=“Âõ×_{*= é#¶d½—Á Ôƒá tÎR)Ílªš¶8 tÚ¹"pý(¤ œ‘)õ!k,PFˆ4N37]Z«G!]`oòË FC(Í4ìuÞï8 GÜëL¥$Óµy~ò\,Ð{«Ù©QHè¸ÿ˜¶8 &\YÒE­4Ó±eIÜ",°¸7bÅ(¤¬o´?ˆ-¨ }¶ÌKp¡qšy¨35{Ò¾T»90iB=ßê3¶xœch pü`#ÌÈ /…`€ÁgRX _úÿ§Ò£Npþrk¬±@M˜dF¥4sl­ÿâX,ð5÷ÚÀõ£N°lbÖX &tJ¬ qšñÐXÛZ= é—]pBi¦aŸÓ~ÇQ82 •’ÌÅÜyÉs±À f§F!½ Ò=lq@]X×D­4cƾ8nhyÕgRP¿‘å©ô(¤#\UŽ%¨ õgjR!ÍØŠå/ŽÅ€¥k×B:ÂóÆéXâÚз*„fiÆÁfakõ(¤#ôky9dÒLÃ~ÇQ8rà>'*$™Óç&cBï­f§F!=áOvlñ@mè½…iæ‹×¢8L¸,*bÅ(¤'äø-¨ ½¶:Ó,ÍxìÌ™š= éw¸/€4ªpÖê7µxœch L(`#ìð '• ½ÏϤ0`âÔ}O¥G!¡¥¢:–¸ .Ì 6¢8Í,9¸8nô]¸~ÒzLÀÔ…^¥14J3³xËZ«G!á “ùC"Í4ìsÚï8 G¤8É/Ÿ—<Ö5™…ô†»]1c‚Ú0t5åi¦mûâ¸E°µ:bÅ(¤7üćÔ†òh”fÖ„æLÍ…t†AkÒ=Í»Øê8·xœch hÜ`# l ' 2··Ï¤0àÇGŸJB:Ã?ºXâ‚Úp%¯5…ifõkű0ráÊÀõ£Îýo*–¸ 6ô(H¦Iš9™ý²µzÒò/ei¦aŸÓ~ÇQ8’à>' “ÌŠió’çb@Çýf§F!½áF̘ >Œ_@iša7[·úl‰X1 é 'æcÆõángš¤™ÎŠœ©Ù£Î°¹f!ÝÓ V#×ê9½xœch ô”0Œ‚fd“N€ïùÞgRP`×SéQHg¨z÷v³"–Ø .L² £0Íœ0:±82~Y¸~Ò^Վ؇%6¨ +h’f,ü§µVB:Cõë¿î>i¦a¿ã(iÂ$ãóyn2&¨ ·ø8Q=ÍÌIÍ™š= ~â]H×4ØD×ê=Àxœch hÜ`#üà =¥ÀA™ÛÛgRhðŽäþ§Ò£p€`wWFŒPZ’O+$;ͬ~­³8 v•, \? F/OLjjÃèy)ʳ©šf^Éo­…ݦßäi¦aŸÓ~ÇQ8òà^g²“ÌŠió’ç¢ÁIyf§Fá@Á’ôø >Tº77‘ü4Ãn¶8n Y±b,íFêÃòÎEÑ®TM3–'r¦f‚<ŸÒ5͘%Õê>´xœch ´Ô0Œ‚>žV  «sÚ3)4ÈzñÞSéQ8`P_S#N¨ çß';ÍѸ¶8 .^¸~üÍ—€'Ô†wþS5ÍTnþØZ=  ¶/™0¨ÓLÃ~ÇQ8á>'²“Lø‹¹Éèð½ Ù©Q8pð‰ fœPv”“Ÿf¸Ç-Bƒë‚"VŒÂƒý…è1B}è±Ý™ªiækÎÔìQ8`0wÒB:¦¡Öê?°xœch l`#tTžV À‚7å™Ôody*=  ~4‹Âˆjûk2ÈN3k –.ŽEƒ¥k׃TR1â„Ú0Q·—ªiÆÁfakõ(0¸‘yP§™†ýŽ£pdB²“̼…s“Ñ¡÷V³S£pàà-5Ì8¡6œ”G~š1âY‡—EE¬…`Æ µávgª¦9S³Gá€A¯­ é˜f ´Ñê@»xœch <‘a#lñ!=­@ÁÊkZϤP`NÏž§Ò£p¡êÝÛÍŠh±BmØ­oNvš±,[‹ÿ1, \? ^Վ؇+Ô†'?ÇS1ÍÜÜÓÑZ= ª_ÿu÷Ù N3 ûGáÈ„d'™;ÉsÑ`èj³S£p !ïg+è±BmxKü4s²tQ*|.±b$ì,÷Ú†+Ô†åNTL3ås§f„핫Bè—f§ ×êA©xœch 0Œ‚ žÈšV `å3)LxàÖSéQ8 0â‘;¶˜¡&¼ÆHfš9´8~e]¸~(L]˜Œ%f¨ ¯ šP1ÍhþùÑZ= ªgkÚ4Ó°×y¿ã(™Ì$s'q~ò\ hvj,tÜ+Ԇ䦙1Kâ¡A+FáÀBŸ-è±BmØ]êDÅ4“?)gjö(PØ^±niE&ÓêB¶xœch 0Œ‚ HM+P°ò™ôKÿÿTz(ŒØ’õ^KÜP¦’•f-ŽÅ€¯¹×®… gdJ}ˆÃ7T…ʳ©–f<4Ö¶VÂ…½É/7 Ò4Ó°Ïi¿ã(™p¯3YIæNÒ¼ä¹hð‚Ù©Q8°Ðqÿ1+ôx¡:L$/Í<ˆ]· ZX1 Ö7ÚDªÃhWª¥™/¼9S³Gá€Âw‚j7é•fN9ÒêCºxœch D¬`#šV €õÍŽgR(°¡úð]ɧңp€áÉVc´˜¡:L+$+Íìàd\‹g¥žÒ^8  ~OD‹ªCåÙTJ3Ñÿ ®×¶V†é“išiØç´ßqŽL¸Ï‰¬$“}y^ò\Èü—÷³Ù©Q8а®in2ayi†ÓdqÜ"¸&¤³Q‹G‹jCi*¥†Ø­Õ£pÀ¡ûešiØï8 G*ÜçDfš™›Œ ™ÿš…ƒfNG*Ã$òÒÌæîEq¨PÿbÄŠQ8à6/ô¸¡2Œu¦RšzŸ35{(ûh!]Ò äSÒêF¶xœch |`#šZÀàÙågRHÿý©«âO¥Gá €.Ÿ¼Qâ†úð#YifßÌìűHÿÃ'æõ£p0@ñw)(qC}(M•4S½ÁK³¾µzX®¤4(ÓLÃ~ÇQ8Rá>'²’̳ȹÉÈð˜Õ³S£p0ÀIy¨qCu˜D^šéÚ²(ÚÜå±bøR5n¨c©’fÔo.‹Éž: y½.iPÒÒêG»xœch 8`#–ZÀ`Ÿä¥gR(°1ûÄSéQ8( ßžœ÷2hñC]ø‘Œ4³é—ØâXXÙ¼S´ø¡&´ÜÄFFšYzÇqq, œ–¼*pý($ð•lZüP†öYP%Íš]k­…ƒn_=èÒLÃ>§ýŽ£p¤Â}Nd$™ãåó’ç¢@ÞÏf§Fá`Ë#ç&Ó*Ý%'Í´m_·†­ŠX1  4?¹(Žvð§3UÒLÖôœ©Ù£p@¯­ éf¶ÑêI±xœch $,`#–V à„ÑúgR(ð÷j¾§Ò£pÀ­é©hñCU˜VHFšÙÅ÷kq, Üì´.pý($ð;w:ZüP*ϦJšé`ëo­…ƒ.Óx;èÒLÃ>§ýŽ£p¤Â}Nd$™Ä»ó’ç¢@‰f§Fá` æ&Ó&‘“fL8Ç-B"VŒÂÁ-/Š£!Œq¡JšÑ¼‘35{ø‰w!Ò sÐêJ°xœch LÉa#–V €_¬å™Lœºï©ô(DÐO@%†¨ Ó ÉH3j÷ö-ŽE‚}—®…ƒ>Q‹G‰!ªBåÙTH3³xËZ«Gá ‚+B÷‘—h–fö;ŽÂ‘ ÷:“‘dœþÎMF†uMf§Fá`‚™ÓQcˆª0‘œ4#­¼(¶VG¬…ƒ nóB!ªÂhW*¤™5¡9S³Gá ‚²Ò<Í.#ÎêK¯xœch p`#<‘!-­@Á¾™AϤ ëÅ{O¥Gá ‚.Ÿ¼QbˆŠð#YifSմűHpyðÊÀõ£pAñw)(1D=xMЄ*i¦róÇÖêQ8ˆ`¹’Ò K3 ûGáÈ…d%™®­s“‘á{A³S£p0ÁIy¨1DMH^šéض(® ŠX1 |)ŽCԃݥNTI3Xs¦fÂAE^/¤yšOÓêL»xœch ¼`#ìð -­@kÆ3)$è—þÿ©ô(D0bˇ,i”8¢Ì 6"+Íì™\¼8 ¾æ^¸~"8#ÓñTìbZ@¯Òª¤µ­Õ£pÁÞdOGÇA•fö;ŽÂ‘ ÉJ2ÙWæ&#à f§Fá`‚Žû7ú£Æµ`èjòÒLüýEqÈÐòxÄŠQ8˜`}ca?jQ Ê?t¢Jšù›35{"øNû ­Ó IÑêM¹xœch 0Œ‚ zJHI+P°ò™ dûvè®äSéQ8¨àåZC´x¢Üw>…Œ4shq, R!Íp~Tn­…ƒ ²íü3ˆÒLÃ>§ýŽ£p¤Â}Nd$™Ò“ó’ç"Áº&³S£p°A+s“iKºÉI3÷âÇ-B‚3"VŒÂÁÿ1-Š£œ—èL…4³Ï9gjö(dðºÆB§ð8ÓêOÁxœch \`#8 %­@Eï“gRHp‹ðÛ§Ò£pAÕ»·›Qâ‰:P_r%ifíÕűH0¿suàúQ8ÈàUíˆÍq(ñDèûë ÒÌΉ—[«Gá ƒê×Ý}6hÒLÃ>§ýŽ£p¤Â½Îd$™y æ%ÏE‚f§Fáàƒ¼Ÿu®ÌM¦>ôÞLNš1â^· ªÞŽX1 ì,÷Ú¶(ŽúÐk‹ Ҍᅜ©Ù£pÁöÊU!´M3à„ÔêP²xœch Tt0Œ‚ NX’Ràà„ÓügRHð÷j¾§Ò£pÐÁòN(ñD øñYiæ€Ü“űHp³ÓºÀõ£pÐÁ[:É(ñD è_ïK•4ÓÁÖßZ= Ô74i¦aŸÓ~ÇQ8R!YI&ñÞÜdd(ñÂìÔ(|ð˜j)ž¨•gS!Íx…ÖµVÂAß}¾5hÒLÃ~ÇQ8r!YIFOpn2fN7;5 #DŽ%êAòÒLáÙEq¸Í+bÅ(ŒÐerÕgRp˜ãÿó©ô(”P•;)¦(‡[T%ÈL3¶bù‹cá0~ÆšÀõ£pPÂEÉ)H1E9 lq£Jš ÝÑZ= %Ì7$i¦a¿ã(©Ì$³búÜd ]mvjNÈû9¦(‡f§ÈM3_¼Å!àY㈣pp°UÈ1E9\àD•4³ 1gjö(”0cúB¦ItÏêTÇxœch 0Œ‚ "VŸNÀÊgRHÿý©«âO¥Gá „.GòÞË Äe°ìM?YiæÐâX$ÈÿáóúÀQ88¡×6éq(ñE æÜO…4S½ÁK³¾µzJxWúá£Afö:ïw…#îs"+ÉÜIœŸ<Y=‘1;5 'œ”wÌjn2õ ÎeòÒ̃˜%q‹àÐþà.·ˆ£ppBÙÇöÅQž6q¦BšQ¿¹,&{ê(œ°ºEí&íÒ ñÓêUÁxœch \0`#|áa` > gUÇgRpxBóðSéQ8háÉVc¤Ø¢ ž0T|ö‘¬4³­¥cq,¾ç[¸~Z(ø=)¶(ƒ·¤3KS!Íh. h­…ƒ¦Li¦aŸÓ~ÇQ82á^g²’LéÉyÉsáð‰ŒÙ©Q8xa]ÓÜdjÁ'2sÉK3÷âÇ-‚Ãþˆ£pðÂŒ‹â¨Ê/Šq¡BšÉŸ”35{Z¸Çy!ÍÒ È_ÓêVµxœch hÜ`#LÉ!>• €2··Ï¤àðù«ÇO¥Gá …—ýã‘b‹2Ø MfšYýZgq,žX¸~Z˜=# )¶(ƒïÕP%ÍÚZ= -\'úc¤™†}NûGáÈ„d&™Óæ%Ï…ÃÌéf§Fáà…¡«ç&S 2ÿ%7Ͱ›-Ž[‡ÒO#VŒÂÁ Ï/Š£¼«ìD•4°1gjö(´p^âBš¥à;ÖêWËxœch dÌ`#üa™P@|*A¬V<“‚CçƧңpÐBÕ» ÿâ‹|¸2táçx2ÓÌáÏ‹cáð°ñÚÀõ£pÐÂ«Ú ÝqHñE>¼£àSO•4ó¡eekõ(´Pýztî×O3 ûœö;ŽÂ‘÷9‘™d²¯ÌMFÀŸìf§Fáà…¼Ÿ%^ Çù0~aG9¹i&þÞâ¸EpÈñ#bÅ(¼°³¼ºuQ5 ÏíÎTI3»Üs¦fÂA Û+ûói•fŽEÖêXºxœch LÉa#,H > ~±–gRPÈöíÐ]ɧңpÃîvðø¢ª4ø’fÔîí[ …íNi¯…ƒjÜO‚Ç%Ð%­*ifwýõÚÖêQ8ˆáý6žfö;ŽÂ‘ ÉN2Nç&Ãà{AÞÏf§Fá`†%=ˆø¢–ôŸf¤•ÅÁà]åÎòˆ£p0C§}ˆø¢ÎKr¢Jš‰YÒY™=uf¸,r!Ò îíÓêY½xœch ìð`#üa™P@|A¿ƒ£ŸIAaYÉ©§Ò£pPÃù•™ðø"® ]ø9žì4³¾tÞâX( ^¹…`Ö‹gRPx‚ùåSéQ8È¡Ÿ€2<ÆÈ…I–a¤™‹c¡p¯ÍªÀõ£pÃ'jñð#:%VP)ÍdÞºÕZ= 9\ºo€ÓLÃ~ÇQ8!I&ûÊÜd|"cvjv˜9cäº&JÒ §é¢8l¯ŒX1 ;Üæ…ˆ1raq¯•ÒÌ’Øœ©Ù£pCÙG i’fÚ,Óê[ºxœch üà`# |p8@| Á'É?“‚ÁIO¥Gá ‡Ü1F _`!¹’‚4s`^ÊâX(T?¿6pý(ä0ua2<ÆÈƒ‘3£]¡Rš™ðyVkõ(äP=[s€ÓLÃ~ÇQ8òà^g ’Lâ½¹Éhvjvè¸9ÆÈË#½7S’f¶v.ŠƒA—=+Fá`‡>[1FôÙâµÅ…JiæªNÎÔìQ8Èa{ÅBš¤ÉØê\¸xœch (<`#dÌ 6}`›¾=“‚Âßÿw=•…ƒæ,.‚Çy°ìO=ifå3ãűPXÒ½$pý(ôð©L<Îȃá©”f~çnm­…ƒÚ­¾4 i¦a¯ó~ÇQ8Òà>' ’Ìæ®ùÉs¡Pâ…Ù©Q8øá{Á¹É”A+ޤ™; KâAaukÄŠQ8øáCùEq”AÅ{ÎTJ3ós§fÂAæ/¤Iš…öÙê]Áxœch \0`# \Ña` 6}`ΪŽÏ¤ 0©õìSéQ8à–¥ðX#Nõ´yö‘‚4³­¥cq,²~_¸~¨ø"k¤ÃKl­‹¥©”f8?*·VÂ!ÍßÌÀ4Ó°Ïi¿ã(ip I¦ôä¼ä¹PX×dvjxÁ`n2ùp£ÿÜJÒ̽øÅq‹ 0cFÄŠQ8à‡EqäCÓÓ‹¢]©”fö9çLÍ…CÞWXHƒ4'Š’ÌæîyÉs¡÷³Ù©Q8à™¹ÉäÂø…Jw)K3wÇ-‚°U+FáP€í•‹âÈ…<_¾q:S-ÍdMÏ™š= ‡\»i¨Ž×ê_»xœch $,`# ô”›6p€FëŸIÁà$Ž§Ò£p@¿=Ÿ²¤ñFÜw>…Â4³‹ï×âX(T?¿6pý(°p‚ã©ØÅäÁd£6*¦™ ŸgµVÂ!M÷»::XšiØç´ßqŽ,Ha’I¼;/y.š…CfNßè?7™<Èû™Ò4c¹8nºì‰X1 ‡ôÛTØ¿(Ž<¨|Ç™ŠiæªNÎÔìQ8àoî/ÔO3¦ÓÖê`»xœch ô”0Œ‚nh›2pßó½Ï¤Àð÷ÿ]O¥Gᢵ ñF,˱H+¤0Íœ0:±8 Kº—®…C^6K€Æi0¸³Qy6ÕÒÌïÜ­­Õ£pˆÀëÑ–fö;ŽÂ‘÷:S˜d|>ÏM†@‰f§FáPýañFÔ¹27‘Ò4“xgqÜ"0¬nX1 ‡ Œ[´(ŽxÚtQ´+ÕÒÌÄüܩ٣pˆÀ_¬ ©žfÁ,Ûêa¹xœch ¬ˆ`#üa¹`@lÊÀ ÊŽå>“äֳO¥GáPÂÁÐx#® ݦ*AqšY½fq,²~_¸~XÝ™ 7Rà…Ð7*¦ÎÊ­Õ£pˆ@ñ‰Â–fö;ŽÂ‘÷9QœdVLŸ› uMf§Fáаx#Æ/4;Iyša7_3"VŒÂ¡UoÃâÈóeA¼3ÓÌ>眩٣pˆ@ý ©žf?ÖêbÀxœch p`#dÌ 6]àûf=“ÃK¿Ÿ?•…CZž-x/9âaÙŸz*¤™MUÓÇ‚áÑUëGáÊw¥?ÄAcŽx.¼‘ªiæ`ݽÖêQ8D`}õý F”fö;ŽÂ‘÷9Q!Étm› »]ÍN¡w»³‚ÅñPçŠ#ÒLǶEq¸Ã#bÅ(*ðµ¨ýAXÌï9S5ÍÜUÉ™š= ‡'*%™®-ó’ç‚aæt³S£phA+s“‰…Þ[¨•f:¶.Ž[†ÒO#VŒÂ¡O›.Š#zmu¦zš Ø˜35{)¸(v!UÓ ‚Ðàêg´xœch |`#tT—ˆzÅϤÀй€ñ©ô(RM5 {„àÝ5TK3Kï8.ŽÃÃÆk×Â!u¯§BcLÔí¥Ašùв²µz)˜îÉ=i¦aŸÓ~ÇQ8 Õ’ÌñòyÉsÁð'»Ù©Q8´`GÅÜdâà¤<꥙¶í‹ã!Lj£phÁö‹âˆƒ?Øifv¹çLÍ…C îq^HÕ4òÆÛêh×xœch 8`Ãlña` .=öI^z&„üïO]*= ‡´<[ð^øa·~³TK3›~‰-ŽBþŸ˜×ŽÂ¡•ïJˆÇ~xòóÂÅÒTO3Õ¼4ë[«Gá‚õÕ÷7Ñ=Í4ìsÚï8 ‡?ÜãBµ$Óµe^ò\ øñAÜLM*¦™rOÇ¡è‹eëGáƒñ+Áñ‡ú××W…Ð ÍÜ|ÑZ= ‡<ÞTD÷4Ó°Ïi¿ã(îp¯3“Lâ½¹É xÁÀìÔ(zPç $þðAÇýÞ›©™f¶v,Ž[„"VŒÂ¡O›.Š#K»½¶¸Ð Í”ÿÂíL³4³Í;gjö(‚pQìBª¥¤*ãêm½xœch ÜQaÃ|áù @\* <›`üLêYNÏž§Ò£pHB6Õ0` bƒ' ãü¢Aš±ä©]»øÃÒÀõ£pHBÝë©ÀÄoI§ÌÔ¤Yš¹¹§£µzI˜îÉMç4Ó°ßq_¸Ï‰IæYäÜä¹É¡«ÍN¡ ;*@1ˆ >‘YA‹43oÁ¢¸EqÏ%#VŒÂ¡ Û‚b|(ï³Ù™fiæ¡|îÔìQ8$áç…TK3ÐáênÉxœch |`Ã|áù @\ <[ üLê™ßÔ‹O¥Gá„–g ÞËãž0Œ[ð‹&ifßÌìű‹·»¬\? ‡$T¾+ý!‡èð–tÊLM¦™• "­Õ£pHÂúêûŒèšfö;ŽÂá ÷9Ñ$É<‹œ›<7ù‚Ù©Q84án×cV 8D‡Od–GÐ&ÍtmY·(ŽíWÄŠQ84ákQûƒ 8D‡å}6;Ó0ÍÜÔÈ™š= ‡$“ÂÌ/ŸJÂ! ?¦è€c® ]X|ŸFiæÐâX Ük³*pý(¢pmt"8‘á—;ÿišf2oÝj­…Cª 7Ò5Í4ìw…Ãîs¢Q’¹“<ŸÈ˜…CÞR››Œãv”Ó*Í<ˆ[„í•+FáP…º—Å¡Cž/Ûišf–ÄæLÍ…C¶W,¤Rš„Kçêp»xœch 0Œ‚aþ°hÜ .þI+Óf=“BýF–§Ò£p¨Bá`p,"àÊЗnGh”f)ß] „¥k×Â! «;SÁ±ˆ€w¼^¿¢qšq°YØZ= ‡(Ÿ(LÇ4Ó°Ïi¿ã(ŽpŸ’̤yÉsÐ{«Ù©Q8táÜdT¿0s­Ò̃˜%q‹€pYTÄŠQ8T¡êíEq¨çËI3g§9S³Gá…úR)Í‘ÓåêqÒxœch p`Ã|á‘xALì“öÍ z&õ¬»èà]ɧңpˆB¿=Ÿ²¤ñƒ' 3w^£YšÙT5mqìâ⧴׎¡ '8žŠ]Œ€·¤}þ qš‘Vè»^ÛZ= ‡(4ÝïêèH·4Ó°Ïi¿ã(~pŸÍ’L×–yÉs“o©ñ~6;5 ‡*Ìœ¾Ñn2>‘©k¤]šéغ8nQß§Îòˆ£p¨B¿M…ý‹âð¡|q3ӌӾÎÊì©£p¨Â-ÞÜ_¨“füÄèêr¹xœch 0Œ‚a¾ð| &îÉ+ŸI¡ïÒCO¥GᆢµÀ1 ‚' ãü¢aš9´8E_, \? ‡0¼l–ŽI¼%2S“æiææ›ˆÖêQ8„áõèNº¥™†}NûGápƒûœh˜dî$ÍKž›|ÁÀìÔ(Êp£ÿÜd|"³<‚–iæAìâ¸Eq"VŒÂ¡ ã-ŠƒÁ‡ò>›ižf*äLÍ…Cþb]H•4ÛWèês½xœch 8`à |áù @LÌ“ öI^z&õLêÀ­§Ò£pCËß¾ x†q ~Ñ4Ílú%¶8vñWÖ•ëGá†DS€ñ‚·¤SfjÒ!ÍhþùÑZ= ‡0”¯“£[šiØç´ßq/¸Ï‰¦I¦k˼ä¹@hvje¸Ûun2>‘YAÛ4Ó±uqÜ¢8+FáP†;<ÅAàCyŸÍÎtH3ù“r¦fÂ! o«,¤JšâDéêt¿xœch D¬`üø @L¼SXßìx&õ¬ËìËSéQ8„aÒê`pŸ’ŒÓß¹É/ÌN¡÷ë\™›D4#­¼(®º5bÅ(êÐgËiÓE1.tJ3ós§fÂ!Û+NQ!ÍMéêwxœch ,H`ÃÜSr8@LŒS 67”=++9õTzq¨zf©äJº¤™•i›¯\¸~qxP¹ô׺¥™Ì&£ÖêQ8ġۄ«tJ3 ûGá°€Œÿ÷:Ó%Élî™›¬sÅìÔ(ê÷³÷fú¤™;I‹âN›F¬…CÞVõÚâB·4³$6gjö(â°§Ø“ i©îêx§xœch ìqaÃÜRk«ø@LŒS î”…?ûøèáSéQ8¤¡êz£ËÏê¥è’f ~ÌZ¹peàúQ8¤ajåLv:¦™“Ù/[«Gá†Û<êkèT75ìw…Ãîu¦K’á7˜›ì¸ßìÔ(Ú÷SgùŠ0º¤™O>‹â|¶D¬…Cúl9o°’Ži¦³"gjö(ÒÐkÛ´,‡}N§`âíêy¯xœch ±aCœ3jªkhx @LŒS æïñ{Væöã©ô(Âðî<ùõÏ|é’fŒÿL^ÜV¸&pý(Âðá§ELµtM3+vîi­…C®ó׸Ò@·º©a¿ã(.pŸ]’ «ÕÜd+f§FáP†:—±ò,ër¦Kš‘U\÷)bÅ(ʰ»tI4}ÓÌMœ©Ù£pÃyI1K8ìw¤8=–çîêz¨xœch òáÊpgº¤®Eq~›"VŒÂ¡ èŸf¶yçLÍ…C^Õv8†û)Nõ¥îê{¹xœch ¼aCücZ‹Ëš‡ÄÄ9… Œ¯¼gÏSéQ8DáªÓ+7×7‚¡ßúÀúçtH3¶b K×Â! ß Ü¾kG÷4ózOGkõ(¢ð¼á;Þ:XdÒ©njØï8 ‡ Üç´Ç…IfÅôÐÕf§FáP…?Ùëù>òƒá•;J®tH3_¼žKF¬…CößW¤šy(Ÿ;5{Qè·é²®Ã(Üï¸×™ÂôFÓðê|­xœch 0Œ‚! ¾qÍKBŽÍÄÄ9…`峜ÚÓO¥Gá„/xõÖ7Âáó„\:¤™C‹u.,\? ‡$|Ã}ï²Ï¤™–Ú­Õ£pHBù}¹õÈÑI—º©a¿ã(>pŸ’ÌäÐÕf§FáЄÌy?ñ}ä‡Ã².g:¤™q³Ò"VŒÂ¡ “æu–Dš1¼35{Ix[õÃ$¸ß‘Âôp‰òê}¹xœch 0Œ‚! ÞˆLÉAM•;ÄÄ9E`eÚ¬gw?=}*= ‡ Üb–w€·¾ >¿ð—æiæòÝÅÜïV®…Cj˜; iFRéQkõ(‚ð°ÑÉzÔ¥CÝÔ°×y¿ã(>pŸÍ“ÌÄùÉ“òÌN¡/8îãûÈ˺œižfD/{)±bE˜;ù©ÿ€¤±×9S³Gá„>[â9@û)LÞõê~Àxœch 0Œ‚! î)uT ÇfÁbâœ"°2mÖ³¤ðßO¥Gრ¬ÞK:×7¢À-½õ[hœf)ß]l¹oMàúQ8äàÓ?â]E”f~ni­…Cò¿×¾€¡t¨›ö9íw…ÃîsÚãBã$s'i^r]“Ù©Q8ô Ò½ºF¾ü(Ðy/ÿ;7§™1Kâæ¤D¬…C>”O™Í?@i&mvÎÔìQ8ä`sí&?‡hp¿ã^gŠRÐõê­xœch $0Œ‚! Θ4ÕŽ_€Í eÏî~*= ‡ü³ó+O~}#¸…ÆifeÚæÅvÛ֎¡7,aª°4S/ÝÜZ= ‡dú­q…ƉØç´ßq'¸Ï‰ÆIfs÷¼äIyf§FáPƒý~±òÄ?¸Ð8ÍÜI\'û8bÅ(jð€Ã’èK3µ-9S³Gáƒõ1K`û)Jêiõꀯxœch FÁÿ˜6ùáŠQž/„c"°òÙGŽÝO¥Gá‚«Bz?¬ªoÄ ·µPÄk@ÓLt“Qkõ(B°¸Çú@=î(¥yÝÔ°Ïi¿ã(NpŸ“ÌÅ\Ý+f§FáP‚Ǭ˜ÿð}äÇ iœfÌØÏ˜F¬…C ÎÈY3°ifilÎÔìQ8„à>'®opÂýŽ¥›wõꂳxœch 0Œ‚!^HL(À§Ç;`ŸäÊGŸJÂ!/ ¿5–¯oÄ¥ë¥hšf6ýZ¸2pý(2p¥£Ð””N3MÙ/[«GáÙ“o+ˆT×M ûœö;ŽÂá÷:Ó4ÉtmqÚovjº:tßG~õøáýš¦™M¿ì ×®…C&/d/ð4“¸sOkõ("í{C ÁH¥qÝÔ°Ïi¿ã(^pŸM“L×Ý+f§FáPJw;Ëù>ò€Î4M3[ÿ3E¬…C*Þ?o@(ÅÐ>ÍÜÒÈ™š= ‡¼®9-Ëá¸ß‘‚ÔÛùê„´xœch 2f0Œ‚!þ1ír#£ 6GˆQE6`ýSºGð©ô(pUˆPíŒúF‚Pzý+š¦™=¿'¬ \? ‡|'Ÿb<(ÒLîþöÖêQ8àyÃolµÄD*릆}NûGáð‚ûœhšd²¯dN7;5 ‡üÉ¿€ï#?A¸2Ü™¦i&þžÿ¦ˆ£p(ÀÞâ ƒ#Íl÷Ιš= ‡ôÛTßèp€¸ß‘‚íúê…µxœch Z«FÁ߸ÅŽO¨èp8@œJ²ÿ‹§Ò£pÀ¼[ל¯o$Jß©NÃ4óÿ­LàúQ8àîøPÏA‘fÒ·VÂ!å<©'.Ri\75ìw…à îsÚãBÃ$ãô×ìÔ( ùïO6¾üDÀ•áw”\i˜f^G®ˆ…C&Í“88Ò̬%¹S³G့UÕo: îwÜëLvŠÿ¤üꆫxœch f¦3Œ‚!žIM( ›00#ƒxµ$ƒ»:VO¥Gá ‡IŒå뉄Ïzi˜fšZ˜×ÂA_0ˆLI$ifyW`kõ(ôp¿ým¢•¦uSÀ{Çý£pØÁ}N4L3ç ÌNÂÁ%^„®âûÈO$,ët¡ašY=9bÅ(üçË.WbS ­ÓLṜ©Ù£pÐÃo\ª· ÷;’""kûꇨxœch ¶z3Œ‚AεԎKxAŠjÁædݧңpûwÊfÆÖ7 Ÿà¥ašÑ{ÿ:pý(äðá'å–ªA“fVÞ`l­…ƒ®ó¿¢AR´Ò´nrøï¸;¸Ï‰†ifsÙ©Q8Ø¡Îå§Rü‰‡e]Î4L3ÇË#VŒÂÁ»K- ž4ó8gjö(äp^Re»Ãà~G²SVÿêˆcxœch ö;2Œ‚A þ°lò#¨ a©:H›Ã¬žJIØÝuÇLýUÜú–Ö‡š×á0­/x¹Ð£3ªõ&{ÜÔ€V‡ú?¬ªo$ >g8KÃ43¿åiàú! £—ßS±<ṓëûg¾OpøP6bÜBõë§ó'¬p7Rêž·Tifï÷s­ÕCºM¿Å(~|¡Ë›úKbà°g¥Û…ÙW=çµ$ïop7R*ßqßZGj´Ò´nb°wÜ? ‡ÜçDÃ4³¹ÇìÔЄ%=·Ô2§{o­kz"ƒ€Ë#•î9îï¨øÉž9} ]H¸Ûµ¤›ï#?I°¬Ë™†i†Õ2bÅЄ¥Ý ¤Ÿ÷fÌè/D@ó“Kb|¶¶åøá·i ]Hxضt¥™®­9S³‡$äùì½Õã…½Îy“Ð{ëgÞŽŠ½Î;Ý·zUŸ¡BÃó<_÷;’"uPù‰Kxœch .ê3Œ‚A >ÌÈ ‹˜@á9ºˆ›C­ŸJ)X>ËöÕΔ¹E²Ï¤À†êþ¥+m師ɅÓ"ß{ÿ©o$na` YšÙR{=pý‚¼_lN¬ˆ~#·8–œ•º(ú’Îf/÷mífòáj7¹aƒ,ÍøNZÜZ=¤à4ÿWÇ' Û+(L3Ñÿ „¿†ßˆU’npW“ ¥ŸtÖ“±4¬›ÌwÜ? ‡!ÜëL³4cÌcvjhÁcV™Óo©ÝR››L2ÿ½¥vÌŠù祿v3ùÐ{«Îe¾ü$Cç=.4K3›»#V -(ôNú©îe¾O‹âÁ5!º—ï+ê_”}<Ðn&2ýxOzŠ¡mšá1Ιš=¤à¬TÿŽû§™òÎÎ “3‚ïkZ†š°µzF†Ã2à>'2S üêŠ<xœch (0Œ‚A î¨tTŠCìà…yúßÿoÏØ=•"Pÿª6sïµgR$Ã;’ª:Âù¯Š¸HôñÊ’Îõd@?ywš¥™-6g×ø—ù¤MÖ¬„ű$î’ï¬öû~1´H…ª»$»ŠYši`pr®m­"ð²æé[ßk–“‘f^©þs¹G³~Àý@Lš£}̘¥YÝÔ°Çe¿ã(ŽpŸ’ŒÏûä…f§† |"óDfyäÜdÒ᤼¹ÉuMOdÚ¤û¸®‘ï#?ðŽŠ3ÍÒÌúˆCîrk¯T¾»(Žt²FàÜ”]níR¡Ø«”Ùä¤Z¦™†½‹²§¸$fQì1«…d¤Ëy“Rg/h Ófmòs8@ÜïHf’…Sÿê‹;xœch 6|`ƒ<’ë)!w„ÀŒ JMÀ ž×GDê<•ÔPõnç»gRT†‰SOpÿ¿*>à¾Ããò—Ö7RŸ;ôÒ(ÍÌsÛ¸~PëÚ÷“ÇRnô‘üƒy ý† ¦×‰ögÒ4Ó 0éIMkõ †ê×.°¡zš™Å›e¦§Y?à¾ÃÓ§7WP·4ª›ö9íw…Ãîs¢I’yî»ÕìÔà†¼ŸKzæ&SÖ5ñ~~"3Ð~Ãç&gNãûÈO,ët¡Qšaþ±bpÃÎr§}‹â¨ [«ÃVírh¿á‚åý”¥Ú¥™†ýmÕÙS7l¯\¹êifMhæô¥1í7\pˇÂýŽd% ËùŽxœch lŽ|`ƒ ±iª#s„ÈÊÍÀž¯×ˆÔy*=ˆ¡åYMMÍgR4 ÕŒ78¸Ña¹;O~}#¥P^„Fi&Ïm_àúA •ïþæKXK8+µ±ÊeÛ@ûʯ^ÍT;hÓLƒMÚ“šÖêA ë«{—L Qš‰þw‚ß_ºyÀýˆƒVi^¡BÜÒ¨njØç´ßqO¸Ï‰&IæY¸ïV³Sƒîv}"37™6ù¯Ä‹IyíCLxÌò+ÿGÊ¡3Ò ó¿ˆƒ¾í/\G¸&¤¶Yöñ@ûNÍ^=xÓLÃþ¶ê쩃´Ï´Fi¦¼ó°]MK΀ûò}ŠYâp€b¸ß‘¬$@ù#xœch r¦|âcƒüàXC(Öˆ1K¨cðÍ/z­õTzÐB˳ë–j<“¢!dûÆpƒóˆð€û#dý¨ÓLCÎ#‹šÖêA ë«mßÌ išÙÝß_ºyÀ} ƒ§M&gÖQ'niT75ìsÚï8 ‡'ÜçD“$ãó±«ÂìÔà…»]/ÌM¦%|/(ñbRÞ@û÷K<çûÈOè¼×™FiæœqÄŠÁ _‹pXGKxW¹¶Yöñ@ûu/¿Üi¦aÿâ¸ì©ƒ´¿¯°¦i&fÉa»š–œ÷) þàpÙãp€*p¿#YIÂùxœchÀ 8440Œ‚AžIM(Àg¤ê™RÿMêËŸJZ¨z÷Y¶Þ3)šC¶o?ý¼*>àþ•~šÔøÁX¾¾‘Zð¿ MÒŒMàúA ¯j·6'.Ž¥9[ÅÑ >—wÙC^× XOËCí4Ó°Ïé€êí쩃ªßàþ2iæ¸åU:øSèÓ>‡4„ûINE6 ù—xœchÀ$44L(`Θ´Ôà‹!ÊAM‹Ãªè[¯o,úTzˆGîϤþþïYÀHc_þÙY53¶¾‘†Ðo}`ýs*§™Î)òë!L]˜¼8v@aI÷ãµ4ö¥âÕ–ª¡•f€uÓ…¦ÖêAÕ³58ÍüÎíhYIc_2ý¾¢AÍŨ]7ísÚï8 ‡7Üç´Ç…šif/ÿÇðUæ§Ì!tÜ?7y`¡Ä‹Ÿì´öåF¿§Rüi ï¨ÜQr¥ršÙí¹"bBŸ-‹âV·rü µ/8Xbif¿ãÕÛÙS#l¯X8Àifbþ.÷û²±¾²ÝáMá~ǽÎ$& |Àù˜ xœchÀ>44L(`~±­ Á;Ô ¨iÚÞz}cѧ҃^îQz&5Àí›Ü$šùð¤áÛ¶õ4‡[¨™bÀi¦sŠ|àúA¹âÇ0,ïpÞYGÝøÄ¨[7ísÚï8 ‡;ÜçDÍ4³—ÿcø*óSfƒ†®ž›<Ðð½àÜdÚù°®‰ùßG~šCç½ÎTN3»]#WD Bø\rQÜ@ûÊ.{hçÃ"o†`šÙïx@õvöÔÁïËtŠY³äªNÍ|(òf›—Ã:ÀýŽ$& Zù™xœchÀTî44ÌKb^HLÊÃ7Ô"o¨hØæ §ê®?•tpkzê3©AËšlᧉ/ o¨«o¤”¡ršIºÌ¸~ÐÁïÜé‹côÙÜ›¹Ž&>\é8Y§ýŽ£p¸Ã}NTL2›»ø?ò2?e6èàƒ¹Éƒê\qÜO†®öÞÂ÷‘Ÿ.ЙÊi¦«¼®°ž>)†ºi¦a¿ãwBÙSüÄ»pÀÓ ® ù ˜C ½sÚçp€.p¿#‰ÉÜùšýxœchÀ|¶44,H`tgLZjðÅ 5AÄ *¶ùêz—ÔsO¥ìÞa÷LjPÀ©ÑGhà¿?;«fÆÖ7ÒÆ_¡ršQa \?è Æý¤Å±ƒ7[Fÿ)nPm©’iT79hl­tðþ›O-XíIÿ1ý¾¢AÍˆÄ ¨Z75ìsÚï8 ‡;ÜçDÅ$³¹‹ÿ#ëóSfƒ–ôÌMp£?-ü·Ñï©ÿGzAg*§™Ð5+tÚ·(npÀ¸E´ðßËcC3Í4ìw<Àõ-{êàƒË"xjÀ?¬94ð_c}e»Ã:ÁýŽ$& ´&ù›xœchÀJz$0Œº‚_lðÅ õÁªµY «Þ%õÜSéAï6+>“$ðî§§TõÛIà gÖ×7ÒúýO§jšQa \?è`Äæ¸Å±ƒr¿[EU¿åö.³²iT79hl­tðÇÝgžV`PRéUýVÞ1;±ŽzqH  bÝÔ°Ïi¿ã(þp¯3Õ’Ìæ.þ¬ÌO™ :¨senò`“ò¨ë·º¦Ÿl|ùéï(»P5Í„®‰X1ø ×¶Eqƒ¾§®ß~p¬ ºi¦a¿ã®oÙS\2Ð)Å^çPÕo"o>8 +ÜçDR²ÚùœxœchÀ @䂆Q@GðJlZî8¡ 8à@%ƒ|ÿ3Ö7Ö»¤ž{*=ÈàüÊÌgRƒò¿g_ÌC5¿¹,1bc†;=¡ßÿtª¦eÖÀõƒ ®ŒL_;h ÿ‡[2ë¨æ·ÌæÉ2‘C6Í4€ë&Ç­Õƒ ~{ðtÀS VoغzÕü&þü¾l=µbX@µº©a¯ó~ÇQ8à>'*%Ÿù?²þ1?e6È Ò½¹Éƒ³z/H=¿MÊ3;É wzÂ;*ÎTM3¡k"V 6x]sQÜàöÊSÏo‹âª[è›b¨™fö9p8Àõ-{ê`ƒõ <¥  úͤù9Tó›þÅêV‡t†ûIJ7œù xœchÀ fd€È £€nà’^[î¡Px@%ƒ6;DÕ7Ö»¤ž{*=È`ÎE—gRƒv¥£’Ï(¹\ö†:}᪦eÖÀõƒ nN^;ˆàÂèåTòYrñBö²!œf u“ãÆÖêA¯o6ðt‚ O ;RÉglßj¨}$ªÕM ûœö;ŽÂ‘÷9Q)ÉlîøÈÿ‘õù)³Aß ÎMLð–µ|¦t·³œêô…Î{©šfB×D¬lp]Т¸Áu/SËgŠ÷ÏÐ;ÅP3Í4ìw<àp€ë[öÔÁ±.ðt‚ ;+r¨ä³ëšÓ²Ðîw$)a âùž xœchÀ ^H€È £€.àÓܱAK2‡JIÉ‹Ô7Ö»¤ž{*=Èàþ9jϤÌñÿI±¯V…ä -†8ý¡ôùSTM3Ê"¬ëÌŸ•°8vPÁøk(öÕ;Ù–C<Í@ê&Ç­Õƒ ΨY>à©ˆî ØWç ?qÖQ+îHT«›ö9íw…#îs¢R’‘TáÿÈÿ‘õù)³A—GÎM\0t5å¾úÉþ^€ï#ÿÀ•áÎTM3¡k"V 6¨|wQÜà‚g)÷Uo±ýÁ¡žfö;p8Àõ-{ê`ƒG­x*A… s(ö•ß&Íëîw$)aŒ‹ùŸxœchÀ $^€È £€àƒÀ¬4ÜqAk ð€*Æl>p«¾±Þ%õÜSéA#¶”>“d0qꉻ’ùjZäÆIŸá=0p ÓŒ²kàúAgdf,Ždp£ïimÊ|µÚm‚bÐO3ºÉñ@ckõ ‚½É§< ÃY¼J×k)ò•ô³£õÔ‰7r•ꦆ}NûGáÈ€{©’d6wñäÿÈúÇü”Ù ‚Žûç&6X×Äû™2_yoUºË÷‘€ ó*¦™Ð5+¬o\7Ø`kug9e¾bú·,r R õÒLÃ~Ǹ¾eO\ðàÂO#èpMhG%e¾j­Þâãp`Àà>'š2ù xœchÀ §ýŽ£pdÀ}NTI2>ùAð“ù)³Aëšæ&>ºš÷3yþùÉ~AŸÖW†;S1Í44F¬\0cÆ¢¸ÁŸKv–“çŸÞb†á’fö;p8PÛœ=upÁ=Î <…`‡ò•äùÇoÓUm‡ ÷;’0K ù¢xœchÀ$@è  £€†àÇ’\q@?P0*ÆøÖ7!Û™¥O¥Lú¯ðLj•²ïÈðMÄ‚¬Ÿ§À!=p‹Ã*¦u¹ïëlèŽ[;¡Ç†Õdøf­·ü4÷á’f uÓÂĆÖêA#s¿xúÀßž'Ã7§M&gÖQ#¾(Ô©›ö:ïw…#îs¢FšÙ#𑳙Ÿ2TPâÅÜäÁã’ãÇýÏùÀ!=Ðy¯3ÓÌê°ˆƒ V·.ŠŒð 9¾Ñ½üR|ؤ™}N€ðƒ@öÔÁûó:u`‡?8sÈðÍ—=îw$!i"ù£xœchÀ@è  £€fà…Ä„\1@_àp€b#63̪oB¶3KŸJ"8­1ë™Ô „Ïö’ì›ËÂoåÁá<ÐЯþ9ÕÒŒºÜ÷Àõƒ66¦/Ž”ð†ÚR’}³ÒQhJÊ€§j¥XÝ´0±¡µzÁy6oð¥ZšQ—û¸~Á¢)‹c)\뵆$¿$/d/ðÔB½4«›&6´V"(_'7àidˆ=@’_ؾ7ÔPQTT¨›ö9íw…#îs¢8É< çÿ‚¿ÙÌO™ "¸Ûunò`…ÌIó‹ÒÝÎr¾üƒ–u9S-ͬ‹X1˜àEqƒê_$Í/Š÷Ï tZ¡fšiØïxÀ?dOLð¶ÊÂO¸ Ðû’ür]sZ–ÃA÷;4U!ù¥xœchÀx¾@è  £€àÓ\a?Ààåf•Dðn‰Á3©A }—"Ú«B #ç‚Cx@û/TK3êrß×"¿2qqì …¢/–íwó”M:P;Í@릅‰ ­Õƒo*ð´ Þ|A´?Îzmª¥<–¨¨Q7ísÚï8 GÜçDyšÙËÿ³™Ÿ2DPçÊÜäÁ /ïŸìO¤ù>ò"èLµ4³:,bÅ`‚§MÅ VxÀxô_Õvif¿ã ü =u0ÁE± §ýŽ£päÀ}N'Ÿü`ø›Íü”Ù ‚ïç&^轕8_0ÿeþà áÁ÷:S-ͬ‹X1˜à]åEqƒ.‹"ÎIóBÖ ¿4Ó°ßñ€~Èž:˜`Ô’Nø Ç΢|q[•ë›ÃA÷;4•ž$ù§xœchÀ"V@è  £€Êà…Ä„\á>pÀá…øÆ/¬oB¶3KŸJ8­1ë™Ô †~S/á‹ËÂoåÁ¡;˜ _ýs*¥u¹ïë llL_;ˆáv—Døb¥£Ð””O#ÔO3°ºiabCkõ ólxºÀW&ˆá‹ìÉ·(Šë¦†}NûGáH‚{)L2>ùÁð7›ù)³A½·ÎMÌð‚1¾]ºŠ¾ƒÞQv¡RšY±bðÀeQ‹â3dûEŒ/®kîrèB‹4Ó°ßñ€~Èž:x ÛÎ…ž.ðÁ›9DøBèêm‡ƒîs"2i>ø&ù¨xœchÀjZ ô††Q@UpC£­ W¨$x @¡Rë[êíÌÒ§ÒƒZþö}&5ˆ!ÿû—{ øÁ¹×ì²8l|ÞàK¥4£.÷=pý DSÇbÈÿ!mÂ:~Xb1›½lÀS-Ò ¬nZ˜ØÐZ=h |Ü€§ |°zÚýíüÀõ¹¡†ÒÈ¡  ¸njØç´ßqŽ$¸Ï‰Â$#©Âÿ³™Ÿ24p·ëÜäÁ YeN'ä‡I¹å|ù,ër¦RšY±bðÀ‹â3´?è·‰ëÏ tú MšiØïxÀ?dO<ð¶ÊÂOø úÍmÞ9ü {yZ–ÃA÷;™4÷ð%ù©÷xœchÀ ÀXFÁì!>ðÀàeúÎÖ7‚!Û™¥O¥ <ÙjüLjPûŸžâõÁ–gÝÐtÐþ •ÒŒºÜ÷Àõƒ ~O\;¨!÷»Ux}0OCo Ó­Ò ¼nZ˜ØÐZ=h`úÇäOø¡¤Ò#¼>øÅTKYÌÐPZ7íuÞï8 GÜçDYšÙ#ð‘ ³™Ÿ24°®inòà†“òðûà‚>4dt¦RšY±bðÀŒ‹â7|)Žß Ã6Íìs:à†²§¸Çyဧ üPìu^\Õv80Há~G"²ì)ùª xœchÀ fdÀXF•À/¶5!ØÃ{0€‚ ißìU߆lg–>•4ðn³â3©A Ÿ ìÅéú“†oÛv@ÃuðÁ-¨”fÔå¾®40bsÜâØA o¨-ÅéúÜ^ùÙž6h•fuÓÂĆÖêAÜ}6à©?ô ­Ãéúòçu”Å -…uSÃ>§ýŽ£pdÁ}N%™ÍùÁð7›ù)³Au®ÌMÜ0s:n××51ÿ჆ëàƒÎ{©”fV‡E¬<ÐkÛ¢¸Á ·yávý‘7Ã7Í4ìw<à†²§¸*d Ó!(ÿ(§ëEÞlór80há~G"MS,ù«xœchÀ (ÀXFUÀž9)ØC{°‡hÞÜ U߆lg–>•$0gqÑ3©AÃþbu}yMþÍWÐPœÐ¯þ9UÒŒºÜ÷Àõƒ>•ÉX;è¡à³5X]¯}Šo‘ÿ€§ Ú¥DÝ´0±¡µz@»Õ—§ýŽ£p¤Á½Î$™Í]ü!ð7›ù)³Aß ÎMüpy$v׳’xÎ÷‘Ã;Ê.TI3«Ã"V øP~QÜà‡YÓ°»~F†õ‘N´L3 û8€á쩃&Ì_8à)‚0Ô½’ƒÕõûœ.ê;ÔpŸQ‰ßÄ-ù¬ xœchÀ DÞÀXFÀ‘ ØÃzð€ hö•X߆lg–>•$ðnÄ3©A“ZÏbqû³—ÆòÐ0¬ðyƒ/UÒŒºÜ÷Àõƒ²ÿM];è!ë÷åXÜ®y”oJÊ€§ Z¦DÝ´0±¡µz@þ¥ìž"CÎÊXÜ~Øæ–%B@QÝÔ°Ïi¿ã(ipŸIÆç#?þf3?e6HàFÿ¹ÉƒÖ5asûƒÐU|ðPœ°¬Ë™*ifuXÄŠÁ'æ/Šü0c6·çNÞå:Ði‚¶i¦a¿ã0ü =u°Àæš…ž"Ã}Î9XÜî³Eõ¶ÃA÷;•8 «+ù­xœchÀ ,NÀX«ÂFÅàB[öLÀàš7?ØU߆IÉ›žJؽÃî™Ô ‡üïïFs¹àÍË>ÐÄÐþ UÒÌÓè?ë Ô¸Ÿ´8vÐCþöÛÐ]¾Üf {Ù@§§DÝ47µ¡µzÀû lFwùšóhfö;pÃYiÙS \¹pÀSa¨~³¶%Íå ¦e9ôp¿#Q‰'„0ù®xœchÀ b–ÀX F…àŠNSöp\ `%º æÖ7‚¡Kê¹§ÒƒöLjÀÌ/QÜÝèö˜'žƒnq8@•4£,¸~ÀüY ‹c‡Ük³ ÅÝÊ[ç2ÕxŠ yš×MŽ[« œQ³|ÀÓ10óÖ-woòÖ¸BIdÐ PV7ísÚï8 GÜçDIšÙËÿYÿ˜Ÿ2$pyäÜ䡟Ƞº{nÒ/VXxfè¼×™*i&tMÄŠÁ•ï.Š °½ÕݯE—Dtz CšÙïxÀ ¹¾eO,ð¨ÕÂOÄÀ%±9(îþ³ÄáÀ€û‰Jj›.ù¯xœchÀì £€"pÂ[N`pL¾ÿë¡Ð%õÜSéAõ¯þÈ’~&5`ÄœHî¶,®„‡æ ‡ö_¨f”EX× ø—ÙéTìâ¡“g-Cr÷]õN tH3 Hu“ãÆÖêA/kÚ::xz ZÕ¤#¹{Up ¹ñ@@vÝÔ°Çe¿ã(‰p¯3™IÆç½àG~(dýc~ÊlPÀ'2ýç&¸<ÙÝ»]øà¡9èá*¤™Ð5+ÜåVØ¿(n(@å»ÈîÖ¾:ÒLÃ^çPÈõ-{êà€Kb¸¾ tj ·ÊAr·Ç‡Cîs""yŸ+ù°ýxœchÀ . Ø F`‡¶¬à‚™}íÖ7B¡Kê¹§ÒƒnMO}&5D JÔÕú‘sáa9ø¡´}ÒŒ²kàúA¿s§/Ž"ÐùZ¨«ç(›xJ GšA®›4¶V ¸Lã퀧bá‹éó ®öÚTKn,  »njØë¼ßqŽD¸Ï‰Ì$ãóAà#?²þ1?e6(àƒ¹ÉC–ôÀ\ýDš–ƒ® w¦Bš ]±bp@Ëã‹â† ,톹úªöÈH3 ûœ8@!׷쩃~â]8àiXÈ÷9êê¤y†ÜïHDòA{-ù±xœchÀ$ ³F™àÓ†lá;xÆ ²µúÖ7B¡Kê¹§ÒƒZþö}&5D À‰;@¯ Ysf=<$‡”žÿ‹ iFY„5pý €DSÇxNg%ÐÅïæÈÙ x: SšAª›4¶V (_'7àiXx1ü+ÐÅç g%Ö‘o_7ísÚï8 G"ÜçDnšÙËÿYÿ˜Ÿ2p·ëÜä¡Y\ü“ý'ßGþ!W†;S!Í„®‰X18àEqCÞW¹¸·xU؈I3û8@!׷쩃ÞVY8àiXhz&èb¿M )¸ß‘ˆä}2ù²xœchÀ( Ø FYàÓª0l¡;˜AÆ 25nnªo„B—ÔsO¥¼\køLjˆÀ²æÝOW…p$ï‡ãЀ~óS!Í(‹°®ÐâBââØ!}6/ |'í8à©€^i¹nr<ÐØZ=( ¸eö€§bᬻËZÏNK­#7 ]75ìsÚï8 G"ÜçDf’ÙÜÅÿYÿ˜Ÿ20tõÜä¡u®˜úÉÞQÎ÷‘HÁ;*ÎTH3¡k"V 8+mQÜP^Û"Vô{m9i¦a¿ã(äú–=up@ý <- ׄäNõÛ4+ÍáÀƒû‰HM÷2ù³ðxœchÀDÞ Ø Fà/óª0la;ØÀ²´ùÊ?¬o„B—ÔsO¥¼Ü£ôLjÈÀùâ/“÷ÀCqè@éz)ŠÓŒ²kàúA¹âÇ87"<ÚqÀSýÒ rÝäx ±µzP@ó='<%S™/¤Ö‘ú Ȭ›ö9íw…Áîí2á^g²’ŒÏG~8dýc~ÊlPÀÐÕs“‡\ÑQ·ŽC® s¡8Í„®‰X18àsÉEqC†¯ôÚ6’ÒLÃ~ÇPÈõ-{êà€÷å:åÏNs80á>'‚É'þ0ù´ðxœchÀ,N Ø FÉà ÷Vl!;øÁ²´m~°«¾ ]RÏ=•ÐoOù3©!O*Þ;áýþ§Sœf”EX×X8!cqì·¤-ðø§gšA®›4¶Vhºÿø€§RÒLì]òÂ~ ™uSÃ>§ýŽ£28TÃpŸYIfsÿGdýc~ÊlÀÌés“‡|"37‰ï#ÿ„wTœ)N3¡k"V è·iQÜÐå»K:öé›fö;p€B®oÙSÜâ½pÀS)iæ´" ‡ÜïH0yã!7ùµñxœchÀb– Ø F‰àLJØÂv°…äé3˜[ß….©çžJx×-î™Ô–‡bL©÷»ßÅ¡·00Pœf”EX×8©0mqìÑófii©nr<ÐØZ= ÛÎ?žHI3š#­nÚç´ßqR÷9íqš¡¸Ï‰¼4³—ÿ# ²þ1?e6 Î•¹ÉC*Ý[q[iu8"‡tÞëLqš ]±b0ÀL‹â† ,ïôÙ|g¤¥™ýŽ ë[öÔÁ¯k,ð´@Jš†=R(!¸ß‘`ò+å4ù¶ìxœchÀjZìiY £€$ð‡Eã(ä .` ÛÁ"V¥Mj}K}#–±ý~*=`Ä#÷gRC® }évоöá¡8„`üŠÓ ŒHàúAS&/ŽðŽ‚×ëW#.Í ×MOd[«TÏÖðÔ@ZšYuSÃ>§ýŽ£|¸Ïiè†"Äí$Iþ0hqÒü”Ù €Žûç& ¿0s(Ü}>òIèLqš©i‰\1 Ï–EqCò|9iæ<âÒLÃ~ÇPXÝš=u0ÀöŠ…žHK3È¡8„à~G‚És5ù·÷xœchÀy F à‹Æ HÈ-HÀ Û¡8¬åyýóúF8Ô7}*=à݃gRC® }év’¾Há8t ßÿt ÓLçùÀõƒÆ¯L\;à¯×¯F\šA­›(4µVx¼©hÀÓ‰ifÕM {÷;ŽBòá>'H8îsh—÷:“œdž… |ä‡ÃðUæ§ÌÔ¹27y(Àø…™Ó if/ÿÇ¡ï(»P˜fv»F®ˆð´é¢¸¡y¾œ4sqiX¦p€CÕÛÙS\»pÀÓ‰if¿#R8!«[qO2;ù¸öxœchÀȼ  £€°r %=˜¡;øÁ‚’µHí/©o„C}cѧ҃ÞmV|&5à–¥3 áèû?]  )$‡ ÜBF2CM3Sä×±9nqì€,ÇF`šA­›(4µVøãî³O¤¥™‘T75ìsÚï8 É…ûœ`á¸Çeh†$ÂDIeüp¾Êü”Ù €:Wæ&hvâ>ï+ºø?=è¼×™Â4³Û5rEÄ €^ÛÅ ¸ â#)Í4ìw<à‡ª·³§¸*d S©i¦a¯3JH¸ß‘@Â4ù¹êxœchÀ y FÑ ¢9ìTî`†îàHÖòÜ^½¾õEŸJ8ŒØRúLj@K§2¤Ü|áRH(]/Eašéœ"¸~ÀáŒÌŒÅ±CFË-‘iµnz ÐÔZ=à°7ùô€§ÒÓÌÈ©›ö9íw…äÁ}NC?$Qý@xÎÿÃW™Ÿ2pè¸nòP€J÷‘BrsrH¸2Ü™Â4³Û5rEÄ€ÃúÆEqC–w ‡÷ÈI3 û8À¡êíì©ß .ðô@zšA É!÷;âJPÔp7ùºçxœchÀ?y F‘`AjHN(À ÝÁ|¶¬EÊþK}#ê‹>•px×-î™Ô ‡* ¾(!ùü:RHøüÃ] ÓLçùÀõ'¦-ŽôÐ%­p„¦ÔºéBSkõ€C¶[Pù £€ðDÆáfXÊ<Á†`ó‡UõH°ü©ô€Ã»%Ϥ7¼f/¹#,¥â¯ „åP[°¤ RÒŒMàú‡ñ+ÇjxM0íו›fÐ릦Öê‡Ç›Šò£@‹Sfu®ÌMÌPéžÙIlá,©,€šC® w¦0ÍD®ˆpèµmQÜ`†å â±…óHI3 û8 Áì©W… tª /Í ‡åûñ&šÙ9ù¾Þxœch FA°WèåL!ƒ Xœ I¹o}#,*=ÀÐoOù3©A -Úp…fþDŒìðùƒ·¦›Àõ 'd,ŽÔ0”oÇN3˜ ©µz€¡éþãž*ÈK3 #¢njØë¼ßq’ ÷9aÍ=.ûœÚmÔó àó^ð#? ´8e6À0súÜäÁ •îbeŸwBh¡9`Y—3…i&rEÄC¿M‹â7üƉ=”GFšiØçtÀfOh¸Å{ဧ òÒ ¸¦G Ï!÷;âM"tº>ù¿ïxœch@ÐE¾q1Œ¼`‹z˜!€ÌÜrƒL I¹Tý–úFè«öTz@á]·¸gRƒvë›ãÏø+há9øáÌrƒÄ4Sɽ#pý€ÂI…i‹c1<ù9~D§̺IíAMkõ€B¶<]›fFBÝÔ°×y¿ã($âÏ}Ní6Òá>'’’Œ¤²ÀG~Èú×ìÔÀB+s“3¼¥†;ÍHªðjÐy¯3…i&y^ÄŠ…ÿ˜Å fØYŽ;_Ž„4,K8 ÀÛªÙS^×X8àé‚Ü4Ó°ß-<‡ÄW×Ú;ùÀïxœch@ ÐE>0Œ<àƒ@Âô0C€Ž Ürƒ8 I¹o}# ü©óTz@¡ß+ÏgRƒ†/p2jÚRûKÐÂs(@¿úç¥ ·}ëÚžHY;haäÌd¾#;Í`ÔMJOjZ«ž?®:à)ƒÜ43"ê¦}NûG!ip¯óp O|>Â{ù?¢Bß­f§fNŸ›0Œ<Àázˆ¡‚”9øå#¸`@‚âÍ Rõ(ðS¤ÎSé…—k ŸI Z¨/¹OxúÖKŸŸŽ¢ƒJÛGQ”f,Üö®Phq!qqì …¾¿®Œð4ƒY7)=©i­P(n™=à)ƒÜ4Ó0ꦆ}NûG!)pŸ¾ðÜã2C¿ŸÐÀæ.þ¨Ðw«Ù©…¡«ç&^è½_øú¼[Ž¢ƒ® w¦(Í0ÿ‹X1°pVÚ¢¸Á ½¶â ß‘fö;p@­ÕÙSê_X8à)ƒÜ4Ó°×#D‡ÜïˆÇK h>ùÂÙxœch@ÐEÞˆ0Œœàˆ zxÑÁ øyýóúF(`føTz@áå¥gRƒ ìQ%9D?ÜÂÀ@QšÙvô`àú…\ ñ‹c)<÷'pħÌ’ô”MMkõ€Bó='±‚žöëQ`î»§Ò-ÏV?“´p‹ª¡ uèE Ñ!ã¯P”fLlή@¨|7sqì …-n#>Í`ÖM‡œk[«ÖWð”AQšöuSÃ>§ýŽ£x¸Ï‰Pˆîuh7ÒÂWHÀç#?L\hvj án׹Ƀš$º{0ÂtðCgŠÒÌÚˆ _‹.мpA<ÁÐöi¦a¿ã¸ !{ê@ƒö §ýŽ£x8\Ãt¯3ÑIFR…ÿ#*L\hvj ჹɃÆ/$&Í< GÓÁ÷¸PfÖ†D¬Hhy|QÜ`…_xœFÓLCÃ~Ç(pABöÔ„ŸxxÚ ,Í`†é€ûpû áâAùÅäxœch@ÐEî)1Œà€zhaˆQ5¸À‚âÕ:ôÖ7¢À?VŽO¥Zþö}&5H¡þLM"‚ôyýs´0üp )é #Íý9¸~áєűƒúV…Œ¦,u“ØûÚÖê„òurž6(K3þnÚç´ßq ÷9 ×0%Îg°—ÿ#*T¹gvj án׹Ƀzo!&dŸ…£‡éà‡Î{)H3ä#V $Üá±(n°B¯­Ä„ì°O3û8 ÀæÚì© o«,ð´AYšÁ Ó!÷;âôwüCùÆÞxœch .0Œ¬`‡áЂ Ä©L€ã‘ }ë1 CìSé„«æY>“”0'؈¸`uèÅ®ƒúÙ«Sfôo®@8';iqì „^¥1£i+H\\×Z=€0LÒgÀS…ifX×M {÷;ŽBâáð Õ}ND&Ÿ÷‚ùÑàÊóSf²ÏMœ0t5‘ifF¨vxGÅ™‚4¾*bÅ@«ڋâ'”Hd^Öi¦aŸÓ4¸Ë-{ê@”٠ùÇðxœch@0À†Q€H¼À -ì e±* À–°©ú-õhPŠ!ö©ôBgIÕgRƒ&í¼Fd¸>??#\7ô«NAšÑ7¾¸~á´’øÅ±ƒ:=ü1šf°–H‰‹ëZ«zY?੃Ò43œë¦†½ÎûG!±pŸ±áºÏi ÝJ3¿I* |äGƒ+#ÌO™ œ”77ypºFbÃõY8z¨vxGÅ™‚4¾*bÅ@Â5‹â',î!6\‡sš–¡Ðà.·ì© ÍO,ðÔAišiØïˆ®ƒîwÄé#CùÈxœch@ 0À †Q€¼a`À -ì@à±* (é!Z©o}#œZœÿTzÀ êÝ’÷2Ϥ!|Χúì#‘¡ú¼þ9F¸nø\ «~ ÙiFW÷QàúƒWµ¥?Ä-Ž„ð†XþbéÑ4ƒµnÚ\×Z=`Pýúí Fž>(M3únÚç´ßq ÷¸ ßpÝçD¬ïöòD‡{]ÌO™ äý|Ìjnò`„™Óç&›fž…c†ëà†e]üïÜÈN3:W#V ì,·?¸(n0Âm^‹¢]GÓLCÃ~ÇhÐcGöԃ핪7:uPžf°…ë ‡û÷:ãð RUEùÉíxœch@0À†Q€ÌIÁ +\ `ñj p8@”²Í RõhPàYãSéƒÓ³žI JèDBø÷b„ë`‡~õÏÉN3Ú/×llL_;(ááÇ¥£i°ÔMŒLõ­ÕçÙ<ðÔA…43Œë¦†}NûG!±øðßë<Ðn%îu&Êk›»ø?¢ÃKúæ§Ì zo›<8áOvÒÌŒpìðŽ² Ùi†‘!bÅÀÁeQ‹â'äøá4šf@`¿ã4xU;{êÀA· P04õ"V§Nam}#d;³ô©ô€Á?ÑZϤ!§ýŽ£88üÃv¯3Þ’Táÿˆ§äšŸ20Èüwnò`„f§HN3{1ÃvÃ÷®d¦™­>+® Y7á‚§Ñ4û8 Á„ÙS–vtê ZšÁ¶ƒîÃîG%´BùÎéxœch $0Œ pÀpÈ¡–?¤êh0#ƒ ßúF,Ð%õÜSé‚I«KžI J¨?S“ÄؼàÖð¼ð¹C/™iFY„5pýÁýN‹c%ô­ M38ãÆÖê‚ÏØÎxê VšžuS×ýŽ£XHj ìsh“ ÷9ô”Ï;¡üõù)³‚/æ&N轕Ô4³¹ 3l7,ët!3Í„®‰X1PpCÀ¢¸Á ½¶΃#!Í4ìu>à€¹¾eO(¨~cဧj¥™†ýŽXBwPCõ/ÅxEùÏêxœch@°€Yi £pÀVø€ÃRu 4`` ¨äyýóúF øgÒ˧ÒïºÅ=“”P¦&‰ U¿Kèjøß„Ì4çȸ~€à¤Â´Å±ƒúV…Œ¦ÀZ7Ùml­ ȶóÏ€§j¥™áY75ìuÞï8 ‰…¤ÆÀÐ Ý}N=õ,Là#?T¹k~Êl€ Î•¹Éƒzo%5ÍH*c ÝÁ ÉL3Ë##WD üÇ´(npB¯m„óàHH3 ûœ8`À->ÙS ^×X8੃Zi{èjˆ£þ2æBùÐáxœch &0Œ pÀpÈ¡ƒ˜%¤ëH`q‚ ßúF,PßXô©ôA¿WžÏ¤%ÔŸ©IzÌŃ>ð–Ì4Ó9E>pýAÛ)‹c%ô­ M38Á…¦Öê‚ç«xê bš†uSÃ>§ýŽ£XHz µðÝçDÐK>>òcÀðUæ§ÌfNŸ›<8¡÷V2ÒÌ^ÌÐ̰¬Ë™Ì4³Û5rEÄAé§‹â'ôÚF8Ž„4Ó°ßñ€T½=u  ßÆ…ž:¨˜f°†ï †8ê_/EùÑêxœch@°€¾"†Q€î¨` +ü€t= &T"õߤ¾漕{*=@ðr­á3©A Ã'p‘¾ÿ±„ïà…[™f8•×´¸¸8vPÂ+<Ö£i°ÖM&gšZ«Š[fxê ^šŽuSÃ>§ýŽ£XHz µðÝçDÐK’*ü1aâóSfCWÏMœpy$éiÆKèfè¼×™Ì4£v+rEÄÁYi‹â'LX@8Ž„4Ó°ßñ€äø‘=u  þ……ž:¨—f°‡ï †8ê_Þb>ùÒÝxœch@?8°†Q€`-Ü@à©:tñóxöúF,°ü©ôÁSUžI Zø‘Äx^ÿkø^(]/Efš± \?@p¯oüâØA ¥GÓ Îº©©µz€àÞmž2¨—f†cÝÔ°Ïi¿ã($îq!5ö:´›I…{ xéY8ÿGlÐâ”ÙÁº¦¹Éƒ&šfž… ` ßÁ W†ò#®4¹"b€`kõ¢¸A £]GÓLCÃ~ÇX`öÔ‚«BtÊ bšÖýXÃwÃ}NX¼ß´CùÓëxœch@/°‚?, £§ýŽ£X¸Ï‰ô8j!LØ{ù?bƒ¾[ÍN Tº77yðÂ呎$'™Í]ØCx°Â•áÎd¦æ+^×\7x¡Ïf‚á9ÒÌ~ÇX`kuöÔ€õ òc…‰ ÍN ôÞ:7y0Ãø¤§™gáØÃxp•áüïÜÈJ3kC"V ,î]7˜ánçŸfö;pÀ$dOx_aဧ j§\a§v3ip¯3Ïø¼üÈNÉ5?e6ð‚ÁÜäÁ KzHO3’*ØÃx°Â•a.d¥™¦úˆ8,ŠÌp^’ÓO3 {8`…º—³§¼¯°pÀÓµÓLÃ~G¡L?Ñ?ùØxœch€ 8À†Q€üa™P€+Ìp‡¤êHpCäóúçõX¡CìS逹ßäžI b¸2táçx£@ªÞï~;Žp”ð~YiFßøVàú€gíâÇbxGÁ%¦~D§ÜuSââºÖꀒýž.¨f†WÝÔ°×y¿ã($ îs"5ö¸ìshWS͇ÏÂ>òc…+#ÌO™ |/87y0Ãø…夦I¥ÕáØCy°Bg²ÒLøªˆï*/ŠÌç‹Çv|!:üÓLÃ>§Xá.·ì©£– tª ~š·p„ó „û1¼¶%BùÙãxœch ±aXÁbÂhÜ ]ÏÀ…x$}ëqÀË:O¥éËg<“ä0'؈äHx>ÿ8Î|p YifÍê§ëéy¿d,ŽäЫ4fD§Ü rU}k5Ýá4ÿkž&h‘f†SÝÔ°Ïi¿ã($’ C+œ÷9áñŠÏüXá KóSft‡Ç¬æ&vºšô4ó,{(Nè¼×™¬43-;bý¡Ð»EqƒÊ?Ä— ‡šiØïxÀ+äû”=•þpVêÂO´H3¸ÃyPB,µ/ÙBCùÚìxœch€ƒ 8À>'†Q€\Àj¸À„Ru $YƒGRê¿I}#V¨¸õ©4Ýá Û˜gRƒ®ìÝMb$<ÿŸŽ#œ#ôë¿NVšÉzþ:p=ÝáN¯´Å±ƒz|x<‚Ó îº)t]}k5Ýa\,À§Z¤™áT7[-ûG!©pŸ©±0´Â¯ÿ$Uø?b‡á«ÌO™Ñ2ÿ›<øaüRÓ̳0á<ág²ÒŒÙéˆô‡úÅ ~ø…_˜÷4Ó°ßñ€V¸Ã#{*ý¡Àû…ž"h‘fp‡ó „û1<nvDùÛÿxœch€ƒ 8À††Q€|Àj¸AÊÒõ p8€Sêy<{}#VÈvféSiºÃänϤ= _ œVHRøÖKŸŸŽ#¤#ô«NFšQ—û¸žî°§*yqì ‡‘3³•gØ4ƒ»nZ˜ØÐZMwXϯ;à)‚i¦aÕM ûœö;ŽBÒá>'Òâ`ËÐ é=.8½ò,œÿ#vø›Íü”ݡċ¹Éƒ.œ›DZšñy·gHFxGÉ•Œ4³:,býamó¢¸Á}¶,ŠÁ‡{šiØïxÀ+ü =•þð ÝÂO´H3 {q†ô „{Ñ<©!@ùÜêxœch€‘7 8ÀІQ€\08à€+ä°Ž¤©´ÀWþa}#vh¿ý©4Ýá݃gRCnQ ›©IRHKÙÁÒƒn!#ͨJþ \Ow¿2qqì€-U!#4Íà®›> 6´VÓo*ðô@›43|ꦆ}NûG!9p¯ópé}N8=âó‘üd~ÊŒîPçÊÜä¡ÍNyo&-ÍHªà éÁ?¸‘f#VО6]7à‚¯-¸Cux§™†ýްÂÚæì©ô‡‹bxz MšÁÒƒîwDs>”>>ùÝùxœch€ƒ 8À‚†Q€¬ a`ÀvØ€ÂRT4x!SÊ×þ`}#Vè’zî©4Ýáå¥gRCžx™ùì#)±ÀpGHFè'ïNFšQa \OwÈÅ¿8vHÀãïV,–‘iwÝäx ±µšîÐ|ωO 4J3ænjØç´ßq’÷¸ {Ú½¤À}N8=âó‘dýc~ÊŒî0tõÜ䡟ÈÌM )ÍìÀÖƒÞQq&#Í„®‰XAø\rQÜЀq‹E»ŽÈ4Ó°ßñ€VÈõ-{*ýá}ùN 4K3ûœp„ô „ûÑœðî>ùÞìxœch€ 8À¤<†Q€,‰a`ÀzØî°|@ç n9…µõXá§Jž§Òt†.G*ŸI ȶ¨èÙGRâgX>è—ÿ p‰K®§3ôÚ–¹8vÈÀ£/6,–‰igyÙSÚØZMgxWúð€§¦™áR7ísÚï8 É…{\H‰‡¡Öûœpûc/ÿGìÐw‹ù)3:ÃIys“‡|/87¤4ƒ3¬¼£âL†?×G®ˆ 3”}¼(nè@㳋¢]GbšÙïxÀ+tÚ—=•Þ°ºeဧ¦œa=á~G4Çkù?ùßõxœch€ƒ”9 8@WÃ( Ö„00à ?Lp‚xµ b–à”z~~z}#Vø<Áà©4áÖôÔgRCžx™ùì#ññ°@GX>¸Åài†G+p=áwîôűC·b±ôˆK3¸ë¦;*M­Õt†Ë4Þx: aš&uSÃ>§ýŽ£|¸Ç…øxJa½Ï §7ž…óÄ˺ÍO™Ñ^0˜›<”à™¹ $¤™½¸ÂzðAç½Îd¤™ß¬‘+"è -/ŠJ0nÑ¢h×—fö;pÀ ÏfO¥7üÄ»pÀÓ Ó Î°„p¿#šãΜAùàáxœch 0Œ‚`CÀâB³¡Áá@I±j1ð­oÄ ËŸJÓê3û?“Rp%oåLM"ÃZª^J  Ox6¸…Œ4c¸žÎð¤MÊâØ!= ¦V…Œ°4ƒ4µVÓ¿%5à©€vif¸ÔM ûG!ep¯3±a½ÇeŸÓ@»– þòùÈZœ2£3|"37yhÁø…Þ›‰M3’J]¸C{ÐÁ÷®d¤™Èt†í•‹â†üÂãµÅe„¥™†8aöTzÃE± <Ð.Í4ìuÞïˆ'¼Üç„âx¼)7ùáþxœch€‚ xÀ†Q@œ°p8€/‘Ä bU<˜P€UxsƒT}#Nø)Rç©4]áüåÖϤ†üø Nr%‘ѰùÀ-<á=¸ ôÿYd¤ ·}ëé Ë&&-Žbп¾þו”fð×MJOjZ«é —]pð4@Ë43ꦆ½ÎûG!¥p¯3±ñ°Ïi ÝJ<Üç„Õ ›;>òㄾ[ÍNÑ*Ý››<Ô ã~ïÍĦ™Í]¸C{°Á•a.d¤æ+è —Ä,Šj°´Ûk öОiXVpÀ [«³§Ò~â]8ài€–i¦a¿#žðdp¿#ŠÓøvAùâöxœch€‚„ xÀ3)†Q@x!ñA_8"@ÀâÔ ðƒ«ðf†Yõ8á¾F‹§Òt…ûç¨=“r°¬&uÁ/¢¢áùþåxÂ{pAéx+2ÒL)ÃñÀõt…ù³Ç9>9¦æˆI3øë¦cöµ­Õt…3j–x  ešuSÃ^çýŽ£r¸Ï‰¸xJáÃO›;>òã„R/ÌNÑ.œ›<ô Î•åÄ¥™gaøÂ{pÁ•áÎd¤Þ/+è •ï.ŠzPñ¾Ïfìá;ÓLÃ>§8á7®ì©ô…G­x  ešÁÞƒ îwDq:­¸<ùãìxœch€‚ xÀ=%†Q@øÃR0_H"€ÏâÔ <0¸€C·¾'ücåøTš®°ì½Ì3©!W†F*T›?¬Â⃠Ú!#Íý9¸ž®PúCÜâØ!ï(ÄJ®)ioÝ$ö¾¶µš®ðæ£Ú¦™aP7ísÚï8 ©÷9C'Äqùh/ÿGÜPåžÙ)úÂcVs“‡"Œ_¸<Ò‘¨$³¹ _ˆ.èLFšy$±‚¾Ðþࢸ¡y¾ølÆÂÃ/Íìw<à€6×fO¥/T½9бOë4ƒ?ÄÜZrª1=ùäïxœch€‚  xÀ†Q@48à€/,a€8Uƒ¤ÌÁ*üÜ^½¾'”bˆ}*MGØÝ•óLjÈBý™Ai…#Bê¿ žLPúü)2ÒŒ¾ñ­Àõt„ÑËÓÇYè[5MyöH3øë¦ÄÅu­Õt„nÓï xÌÓ:Í ýº©aŸÓ~ÇQH-¸Ï‰pL Çá›gáüqÕæ§ÌèKzæ&]è½uná4#©‚/Ä\îLFš _±‚ž°´{QÜÐ…^ÛŸŒ€4Ó°ßñ€N¸Ë-{*=!Ïç…ó´N3øC|PÁýŽ(5ùåþxœch€†<àˆ Ã( |á‰X/‘ѹL(Íø¼Äæƒ :ïq!9ÍLËŽXAO81QÜP†åO›`Ë™Ã+Í4ìw<à€ò}ÊžJOØ\³pÀãÖi¦a¯3Þ0T¥¦‰×4ùæíxœch€… xÀ†Q@"8b³ _˜64püÀ/?xÀŒ l¢ gëqÂîÈÉO¥é8<“âP`ODƒ/Þˆ²ÿ‚'Ì|îÐKršÑTþ¸žŽ‘5yqì‡çþT¥ï4ƒ·n ÜTßZMGØþÇbÀãœöifÈ×Mûœö;ŽBêÂ}Nøcbè„9vŸìåÿˆ>“6?eFG87yèÃcV%ÝøÓŒ¤ ¾0L°¬Ó…ä4sM;b=¡À‡EqCÞWœ—è<¼ÓÌ~Ç8aÒ¼ì©ô„¹“xœÓ>ÍàóA÷;"9_Q4ùç xœch€‹ xÀš†Q@2øÃÒSÂÀ€;T(Ô´à õÁ~p`Üü`W}#Nèܶî©4áÇgRC® =p¾÷ÙGœ±¹áùú<¡>x t¼ÉifÙìßëé×F'.ŽòðŽBºÑ‰ÅÒÃ6Íà¯›Í õº©aŸÓ~ÇQH}¸×wLìu*¡¾Ï ‹ó7wñÄ Yÿ˜Ÿ2£#¼¥67yèÃø…¼Ÿç&âN3›;ïªà õÁW†cóþ4#ú&b=¡îåEqCò|Q¾³8Æeئ™†ýŽpÂm^ÙSé Û+xŒÓ>Í€ÛxB}ÁýŽHΰŸ7ùèûxœch€‚€ xÀ‚†Q@x!°W¸jÜÀêƒ\À"ø|ÿòúFœÐ%õÜSi:ÂçÕòϤ†,«9´ôà³8¢âùüãxB}Aû/$§eÖÀõt„ËRãÇ >9…c±ô°L3øë&Ç­Õt„;ÿ± xlÓ#Í íº©aŸÓ~ÇQH ¸Ïi ®¸*¡¾Ï ‹ãŸ…óÄ Yÿ˜Ÿ2£#dþ;7yx@+f'ç%àJ3øC}0Ag’]º&b=ášEqÃ*Þ_¿8ÚuX¦™†ýŽpB®oÙSé K;:®é“fð‡ú ‚û‘ Sø4ùéúxœch€‚Œ xÀ¤<†Q@6¸¡¡ð{¸:ÀꃤÌÁ"(5J}#Nø©’ç©4Ý`Ä–ÒgRÖå81œÅRõ[ð„úàÒçO‘œf¸Ä¥×Ó ÎÈÌX;Œ`pgƳÃ0Í௛zJ[«é{“Ox<Ó'Í íº©aŸÓ~ÇQH+¸Ï {\ìuh—Qà~Iþ¸¡ïóSftƒŽûç&'¨s¥¤{š‘TÀꃮ w&9Í®\A7X߸(n8ÁÓ¦ó±…ùPO3 û8à„Nû²§Ò¾\8àñLŸ4là õA÷;"9´--ùêîxœch ´U1ŒŠÀ…ØBÖáq10Ð`A†o}#˜tÙé©4Ýà]·¸gRà nQõf8‹%*¤ê·à ùÁ·`q;þ4ÃÂn¸žnpRaÚâØa[òŸ}fi?h©ij­¦dÛùgÀã˜^if(×M ûG!má>'lq±Ïi ÝEÜëŒátŸüx`W¹ù)3ºA+s“‡4;UÒ-ÍHªà ÷Á÷¸˜f.D®ˆ üÇ´(n¸Á ó1sêÐN3 ðÀiYÙSé¯k,ð8¦Wš¶ ð†ü H5+8Û-ùëëxœch†àÃ( pxA(œ+˜‘&àûŸ±¾/T5T|*M'ñÈý™Ô0„ú3gí¼†òÂ}°Àç½$§™_½[×Ó ¦.L^; ¡oUõÃÃ&Í4¬›ê:jZ«éÕ³5<~é•f† À¨›ö:ïw…´‡ûœÐC~ŸÓ@»‰L—û|øÈ64™¢tÜ?7y8Bï­u¤‡üà€e.$»ü'GÄ zAŸ-‹â†#ôÚVÜã§=.Èa¿Ïi ]Dœ«Ñ’ÌæNüxá%³Sô‚¡«ç&Whvª¤{^ršÙÜ…?ä\îLršÉ›±‚^pVÚ¢¸á $ÌK\í: Ò °|<à€úlÉžJ/¨aá€Ç-ýÒLÃ~Ga?(à~G¸ƒÐ*ùíæxœchƒ À=%†Q@%pG%b"d ‡ý`0„|ëñÂ?VŽO¥é/÷(=“Æ0|Bÿ›i…D‡ý €ö_HN3Eή§äbˆ_;ŒážbNFåÙC=Í,ÅÞ×¶VÓ šï91àñJÇ43Të¦}NûG!ýà>§½ÎC+ì÷9¡§™½üñC•{f§èCWÏMÎpy¤Îåy‰ÎD‡ýà€Î$§™Gò+èŸK.ŠÎ0aÁi“ÅÑ®C=Íìw<à€6×fO¥¼/?бJ×4C0ìÜïO,b(ùî÷xœchƒ  À†Q@EðF¤£Âá$l6 ý)sО۫×7â…R ±O¥é]ŽT>“öð9ß‹5Ë$WBBÿr¡?ðPúü)’ÓŒ¾ñ­Àõt^Û2Ç{xC¬Xwÿ¯+C8Í®›×µVÓÞ•><à1Jß434릆}NûG!½á^ç¡úûœÐ’̳pþøáÊóSft“òæ&˜9}Rž÷fg"CàáÊpg’ÓLøªˆô²Å ¸Íë»÷—!œfö;pÀ w¹eO¥¬nY8à1Jß4C8ôÜïO,“h+ùïöxœch†à€Ã( 2øÃ²"â¡,`A ×÷?c}#^(ð¬ñ©4]྄ägR#® }y¬g[ƒ/°p Z"œf´5^®§ ”}–¶8vDÀ; ^ÙKú,†hši X712Õ·VÓþ;óqÀc“¾ifˆ´º©aŸÓ~ÇQ8pŸÓP ý½Î(IÆç#?xIßü”]àòȹÉ#Æ/Ìœ®tשÁçƒÁðxè¼Ç…Ä4Ãȱ‚>0kÚ¢¸‘y¾œ4ÿÆééÔ´,6Vq0°P:ÞŠÄ4³dSàzºÀW²I‹cGœ’·A&rÀÓIi†`Ý43³¡µš.pûÊèCzÃ\;ßådë)®>h Ðë¦}NûGá€Áƒöí"à>'Ô4³—ÿ#~(õÜü”]àòȹÉ# .4;i~’@ ,\îLbšy%±‚>Ðü䢸‘ÃV}ãªnèTAbšÙïxÀ/tÙ“=•>ÐkëÂCzÃ_ì©sª[ñÇÀ€ÃýŽÐÄ/gùòxœchŸ- À´,†Q@cðDfC@[¡˜(`p…»ùêúF¼°Œí÷SiºÀSUžI8¸RöÝÓOïOž™pÙ‡@L ´ÿBbšá‘ \O¸×7~q숃VªØ,·Ÿ½l Ó‘i†pÝôD¶±µš.ðï¶AúÃÄ·ç[…_ÏIlª¡B-B€V75ìsÚï8 G!>¸Ï %ÉlîâÿˆZœ4?eFX×47yäÁø…f§n©ýdë,ç#IL35-‘+"è[«Å<ø…'b…Ó¾Uaç :e›fö;pÀ «[³§Ò® ]8à1Høƒ3gêMõÓ²ðÇÃÂýŽÐÄœÆ"ùó)xœchƒ„ @[Ã( øÅvÆdN ¡Ø³…»™aV}#^˜tÙé©4 åÙêgR#þþÿøˆ0Ðÿ' ™v®½ùŠ@l ÜbpÄ4ÃÂn¸žPùnæâØKºí·üŸÛ«¾Áh‘ÿ€§Âi†pÝÔRÓÔZMX_}pÀão àï\qéf ÿË;˜?‘¬§¼&¡>@«›ö9íw…£Üç„’d6wñÄ»ÊÍO™Ñîv›<¡Ä‹Iy ÿ×5mô“|ÎG 6:ïu&1Í\0ˆ\AøZtQÜH„Õ­²AþÿÁqÀÁúÈ@§bÒLÃ~Çxá´¬ì©ô€í xü œ˜_Û’ô¿È›Æú‹úøãb€à~Ghbi©ùôxœch |ãbt¯Äv¹õ”7|ë B^µ§Ò4‡[ÓSŸIH¨¿þ<\–hÔ\fHD¬Ðn!1ÍTrï\Osø;}q숄N;WÀC!³¹0Ų?{ÀÓ¾4C P{PÓZMs¸Lãí€ÇÞÀÀ›. ðPþƒ­µ‚š5 À~ÇQ8 Á½ÎHIÆç#?AÈú×ìíჹÉ#zoE„¤¼øYÓøˆˆºÂ÷®$¦™äy+h-/Š™°¸ ‹â$ô xÁ›f8„·U³§Ò~â]8à±70ð¡B<ô/Ö7¾!'t†ûœÀ‰Ìùùõ*xœch‚ D€gR £€ŽàÓ-µUa-5ÄÄ }@Gœ)õߤ¾‘ Ü×hñTšæÐò·ï3© ‘BbUˆúz£äc3c‰ˆú@¿ýËIL3¥ Ç×Ó~MY;BáaãµH!ñN ½²*Ú¹¥jÀÓ ¶4C\Ýt̾¶µšæP¾NnÀãn à‡–•H!qÞp›ÇŒÔkÔ«Z(HuSÃ^çýŽ£p‚ûœàIFRYà#?A(õÂìíán×¹É#þdG‰Ÿì¼Ÿ:ËŸJŽzÁ;Ê.$¦Þ/+hwx,Š©ãrHôûlñÚfyl S ö4Ó°Ïé€Aø+{*íám•…ww¹ç …„ß&¯m³Ò*Û Ç Ýà~Gpr2ˆùö)xœch‡ D€ £€îà×)³9)ÄÄíÁ 8Sª~K}#A8¿×û©4Íá¾>ÓgR#>¸}V-<^ðªNÛtóñC{è'ïNbš1´¸¸žæð•lÒâØ o¨IÞE7ÜYy&‹ü<½ §âê&ÁÏu­Õ4‡ÛWFxÜ ô mªnD ùáËŸHÖS¯~¡ ÕM {÷;ŽÂQHîs‚'Ieüá”\óSf4‡Ë#ç&T˜9}·+zx0ÿ5;)ùœˆø¡=¼£âLbšiªXA{h~rQÜH…Û¼^‹¢‡GÒ¼o\ÖG:µ`¦™†}NBÝËÙSi½¶.ð¸((ÿè=zxÜVM™sQŸpìÐîw'‚‰ù÷xœch‚ŽŠ"À †Q0@àÈ—¾"bb‰–@ç œ)µ¿¤¾‘ œZœÿTšæðÄT•gR#Z,¿Š5T¶˜±/¨«AD,Ñúå'1Íèê> \Os¸×7~q숅YW` Í£úËvf ¢4C\Ý´1¸®µšæðï¶¹ƒX±†Êa›ÅQ†g¨XËꦆ}NûGá($÷9Á“Œ¤²ÀG~‚p¯‹ù)3šÃº¦¹É#*ÝÃ* n©&,à#"–h ï¨8“˜ft®F¬ =l­^7rá’ì¡’;9kšê­M1¨i¦a¿ã‚ÐcGöTÚÃU¡ <æ~áÍÁ*>[æ¤pü G4†ûÁÉŠùøxœch‚ D€ £`@Á=¥uAmUÄÄm@Ì8Sê¿I}#AØ9ù©4¡åÙêgR#NÕý„3tX½_9å²qE¸Åà‰iFSùCàzCå»™‹cG4üýw5ÎÐyúçÇ݃ìeƒ"ÍW7nªo­¦1¬¯>8à±6°pãÒã8C‡ÿýÞ¦êU5$¤º©aŸÓ~ÇQ8 Á}Nð$#©Âÿ‘0|&m~ÊŒÆp·ëÜä‘ 7úã¥{uå|DÄm ó^gÓÌ5툴†¯EÅl81wè<”¿¯xÞ` R jšiØïxÀ Lš—=•Öð ý‚µ…­598C§¹ö²î´,Â1E3¸ßœ\&^ùùxœch‚ D€eQ £`ÀÁ/¶ ‹âˆ‰/š‚çñìõá™ÝO¥i ·¦§>“Ѱ»È¨‘O4<ÂðfÍy"â‹6p Ii&åCàzÃïÜé‹cG4|!^Ö¸Oåö®0n õð4C\Ý亷¡µšÆp™ÆÛµ…Ò ¬6 ñ„PyGôâ—"õ´©pHûœö;ŽÂQHîu†&™gáü Ã)¹æ§Ìh /ÌMÙð–š÷V|!T×´<âñEøÞ•¤4³Õ'b­¡åñEq#ò}Z…/„~p„­’8ði¦a¿ã‚0aAöTZÃO¼ <Ö:íóØ™ƒ'„DÞìrS¿I8¶h÷9“ ÀÅ ùú(xœch‘7 D€)9 £`€O|‡ì&åkÔP†¯üÃúF‚pËæ§Ò4†–¿}ŸIpXÖüc ?pb{½„ë{¥±F]è·9Ii¦{¦Dàzâ)‹cG8ôÙÜ›¹Ž@8ewädnOÀ4C\Ýdq²±µšÆP¾NnÀãl á¬»;’» „Óq‹åa¥õT¯zxÝÔ°Ïi¿ã(…„á>'h’ñùÈOtÞg~ÊŒÆp·ëÜä‘u®8î'NÞ[|¶ðoÔ„w”]HJ3Ϥ"WDÐîðX7Ò¡×¶úFBátÖø´iÀzz§ä4Ó°ßñ€A·({*­ám•…g ׄ|Ì!N‹â>ñ9í#gT‡ûÉ$ ùû'xœch D€–†Q0¨À™->ÄĵÀ (ãùüãõa÷Ìà§Ò4†'[ŸIxø\à×~"BëÓû!/Ig"âŽZÐOÞ¤4ÓÜb¸žÆPð{ââØo¨õe®#"´Ô˜,°í*4C\ÝtC£©µšÆ0ýcò€ÇØÀC¯Ð ÉÝD„–ðë/œz¨^ÿàðº©aŸÓ~ÇQ8 Ã}NÐ$ó,œÿ#aøLÊâ”a]ÓÜäQ˜9Ýq?1¡uKí½@}#qG-xGÅ™¤4cu,rEaÆŒEq£p›W}#1¡å´Ïþ`Êlú¥ä4Ó°ßñ€AXÙž=•Öpó±‡òÞ æZ7Õ5¯oò#sT„ûÉ;äùü)xœch‡ DO| £`?,—ôÅ”+P†Tý–úF"`Òk­§Ò4…—{”žIÂgÏXVóbV‡–(½Xsž¨ø£úå'1ÍüèØ¸ž¦‹!~qì(\|Cm«Ó:¢BL÷|zqC¨'ÝÓ ±uÓ9‹šÖjšBó='<¾ô }ÉÖOTˆ)ßaÿþR¤žº5n¯›ö9íw…£0ÜçM2’*ü‰]f§h CWÏM…s“3§K¼ .Äv»*ÝýÅÆGTüQï¨8“˜fÎG¬ -|.¹(n.ŠÛæµ!€¸;l«x_þ!ýÓLÃ~ÇDÀEqÙSi ïËtl (ÿHãFQ!fxþº¦úMbb*p¿#0¹ÌSùý+xœch‚„ DGr £`P‚úŠˆ‹EJ@Ì(c3ìúF"àÝ8›§Ò4„.G*ŸIB0üýß®’™è›yôYÙ[ ¢b‘¸Åà‰iæKÝ©Àõ4„^Û2ÇŽB0,éž¹–è[í¶Vc«`Ó ±uSÞôÚÖj»҇<® ükð`)Ñ!'ýä7“áêVCX¼njØç´ßqŽBÂpŸ4ÉlîâÿH œŸlvŠ–pRÞÜäQ/”îrÞ[/è',à#*)Î{IL3+h e/Š…XÝz]“øcúÇÀ z‹Ö)9Í4ìw<à@Üã’=•–°ºeá€ÇÕ`órˆ¹Öê«Ú?ˆ‰C á~G`r6ùþ6xœch‚ŠŽ¢À9#†Q0hÁ?¦[jË¢šêˆ‹KrÁ‚0õü~{}#ÐòNÒSi»nqϤF!ò¿?Àýš„Ð[¢¾¾@Æ‹'Ÿ¨¸$n&bÓLÞ§;ëi'¦-Ž…PÈÿazò*Bï@zåÏǘjé’fˆ­›¶ú×µVÓ²íü3à15x`õ†gf×H½ó†Û<öj]¡ve„ uSÃ>§ýŽ£p÷:ƒ“̳pþÄ@½Ëæ§Ìhu®ÌM…0xÌŠ÷3)¡÷“÷ÓäÜ_¬ÄÅ%¹Ðy Ii¦§4b-á?¦Eq£í†­"%ôz‹}¶lñYMŸ4Ó°ßñ€p^RöTZÂë <¦T¿™5=‡„ÐóÛäµ-aAÌbb’¸Ï©7—ùÿ%xœchhXÐ@$ØãÂ0 9øÄ·Ï©§„Ø%ÌÈS¾õDAß]O¥i“o¸=“…H0§ößA’Âíõ£Ã;–£¤Ãç½$¥™UËÞ®§!ì©J^; ‘ Î…Ì ëH ÃìŽWÏÍú³ifˆ®›VFÕ·VÓÖóëx, .¸Óòéþv’Âð¸…ÿºÖ ZTJP©›ö:ïw…£8¸Ï ”fö|ä' ÞQ5?eFC(ñbnò(D†¡«3§“†¡«²¦ñ£¤Ã²N’ÒLö´ˆ´„µÍ‹âF!2œ•æ·‰´0É‚ûÞþù%xœchh0¸Ð@$XÆ0 †øÇtEgN ±±J``¾ö뉂IÉ›žJÓ¾ÈÖ{&5 Qàïÿ̾Ž«BšÝfß|Ed¬’ÿ›”fžFÿ \OCØÚœ¸8v¢À’î«*«I Çwª[µùÓ0Í_7ÍMmh­¦!,?U5àq4ØàïÜŒ‡I Ç󆛼ŸHÖÓ°njØë¼ßqŽBâà>'`’ñù ð‘Ÿ(ØUn~ÊŒ†ùïÜäQˆ %^ÜR#5²ÏM’|ÎGd¬’ IJ3ÞÛ"VÐþaY7 QaukÂRñ·øµ¨õÚ¤HšiØçtÀ(8+-{*-¡Èë…Gƒ NÌ÷ÙšCb8úmúÂsQŸ¸8%îwlØvþê&xœchh˜PÐ@$˜‘Á0 † x&µ&¤©ŽØ¸%˜œÏÿ§×7­¼?=•¦!Ìý&÷LjbÀ²éÅ<$‡fR#K›-O>‘qK,Ü"ð¤4Ó7W0p= áY»¸Å±£¯¼+³ŽäÐ|Á`8û S-MÒ ñuÓ„ÂÆÖjBÉ~áŸÁ3›¾®žDrhî·wÙ©u…ÚU¤njØç´ßqŽBâà>'`’y&ð‘Ÿ(¨wÙü” á{Á¹É£ê\y/HzhJ¼`þ󋕸˜%:ïu&);\ACxWyQÜ(Ä„§MÊ“š<_DÞ,‰¦MšiØïxÀ(8##{*-aÔ’ŽÁ —Ä&ÎÏ!94¿qmóŠYB\Ì’÷;6(mùê*xœchh8aÑ@$h©aC |ØáÑRClü &€ÈºõDÁî™ÁO¥i'å=“…X!ÿû7¾\'9L§E:D.ŸKdü·8 )Í4·˜®§4>Ÿ¾8vb…ü«¾3“¦«ÝV+›·TQ?Í]7ÝÐhj­¦|÷ùÖ€ÇÍ`…Õ¾ñ»jÖ“¦ÒO¼7]Õ fÕ­›ö9íw…£8¸Ï ”föò$>“²8eF387yâ‚Ǭ$^<‘!=L½·>‘~*Elü÷:“”f¬ŽE®ˆ tÙ³(nb‡ök›w¹‘¦Lÿ®j[£AšÙïxÀ(XÙž=•vð²Î›Á Õo¶[Cz˜¶V'Í«l'.v‰„ûµOùê-xœchh``h |âcC |áÙåÖQA||ÿ3Ö7 “^k=•¦ y&5 qÂßÿ×Ëþ¸+Ir¸–×ÈÖÚH:Ç„ _ýs’ÒÌŽ=ëiC6¤.Ž…8aI·ç†‹Ú¤‡«ö©Œó®"ª¦™ê¦s5­Õ4‚ûßòx¼ fø;÷çÛêëµ$‡kqÏw6Ý Ô«š@uSÃ>§ýŽ£p ÷:7ø|ä'vU˜¢Œ_87yâ†/âò~&=\YÅ/¨oä#!–ñÃ;Ê.$¥™sÆ+h¿ð,Š…¸auëžÎrÒÃuFÆ‚„”ÙÔJ14Ó°ßñ€‘pQ\öTZÁoœ <^3œ˜ÿƒ³£’ôpÝçTߏɨ&îá÷('xœchhPxÐ@4¸£Â0 † øÂ³Ã£¥†øxÆ(440œ­o$v¯t~*M#8¹õ3©Qˆæôl”ýqW’ä°-¯±‰\>3–èxÆŸ7ø’”f6íº¸žF°lbÒâØQˆþcðÚpQ›ô°Õ>µ\Ù¼¥Šzi†„º)sNmk5ಠ®'ƒÞÜsæmõuÒã ¸Ç{ÓU êTMàºiŸÓ~ÇQ8 ‰…ûœöò$>“1;E+¨tonò(ÄCWÇ/äýLzسz"ýTŠøxÆ˺œIJ3â¯"VÐ .‰Y7 ñÃç’_x:ËIÛWµ-Q1Íìw<à@$L›•=•Vðï“ÁÊÿàì¨$=l÷9%Í«l'6– Àý«ƒø)xœchhpÙÓ@48aÁ0 †(øÄ·!€ø˜Æ 4n4øúo¬o$N-Î*M#xbªÊ3©QHæôl”ýqW’äðe{½óÌz¢c7”žÿ‹¤4£«û(p=à^߸ű£ üÇàµá¢6éá›Ý±\ΆJi†”ºicp]k5àÞmCÞÜsæmõõZ’Ã÷¸ÅìÄ:*ÕM ûœö;ŽÂQH,ÜçÔàó‘Ÿh¸×Åü”`]ÓÜäQH†®Ž_Èû™ôðí¨øÉÆGB\ã‚+ÃIJ3:W#VÐ ¶V/Š…„ásÉ/<备ïYãUaÔJ3 û8 =vdO¥\ºpÀãc(À‡ò?8;*IßEqˆg¼p?¨ ö)xœchhȘÑ@4ØæÅ0 †0x"3+øØÆBÖ4HÍŸRßH$\e6ý©4M Ë‘ÊgR£Hø‘ãæoÖ³¢$‡ò§÷û'}&:¶±C¿þë$¥™ŒGŸ×ÓzmË\; ‰„j7ž‰ÊÝ%=”ÕÌR ¢Bš!¥nZWßZMxWúð€ÇÄÐV>ÖuªIeá׿Gë©P75ìsÚï8 G!±pŸSƒ¤ ÿGbaö4óSf4“òæ&Bb¡ãþÝ®»]Iå[jJwùˆŽmìðŽŠ3Ii†û[Ä Ú@ÙÇ‹âF!±Pòù×¢¤‡²Ó¾e‘”¥HšiØïxÀHè¶+{*m`uˉ¡[ÞU9dOz(ßTßâCl\ã„û&Wò)$xœch ,H`Cüc:fÕRCZ¬£‚„ÜúF Kê¹§Ò4/lcžIB Û7¹f³¸H çU!Qí3cIŠuTøœaIê•EX×ÓîôJ[; I€í¾±²YGb8¿xøV«¥Š¢4s–¤bÉñ@ck5M`\,ÀÇÂЂ»ûïÿöŸFb8Ÿ7ü÷ïª%USC‚½ÎûGá($îã{/ø‘ŸhÈúÇü”M ó߹ɣø^pnò1+RÃù'»ã¾§RÄÇ8&,ëâ')Í„®‰XA¨qQÜ($ÞUø ôŽÔpî-NX`yŒ²4ã¼Ïé€Ñë[öTÚ@÷ <†ŒY’?ivj‰áì·Iûje;ñ1ŽîãXð)xœcHXÐ@è*cC¼™‘AJ¬£‚„Ë ³ê‰†Ï žJÓ–Ÿpz&5 I†])“mîJ’Ö[̾xÿ!!ÖÑÒ0Ñ‘’fØx´×ÓÞÒI^; I† £7z]Ò&-¬5 Ï £ Íœ%©nº£ÒÔZM¨n:àá?áIa•Øœëµ$…õa›®Âz ê¦{÷;ŽÂQH<ÜWÚ)ð‘ŸhXÖm~ÊŒ&ð˜ÕÜäQH:¼¥Æü—÷3ia}Á@ç2 ±Ž–ºÊHJ3¿Y#WDÐÞW\7 I‡º—õ/v–“Ö¹“Þ“›b@iÆyŸÓ¢áyÃì©´ÆgxøEØY!ø¾£’´°öÙ2#ƒø8Ç€û,·ë) xœcØÐ@øÆÅ0 †<øÇ´É´xGŸÆýŽõ$@^µ§Ò4€–ŠêϤF!Yð÷±N“8HíU!½V‘ïøüÃ*ÓL%÷ŽÀõ4€ÇŽB²`I÷yÝókIíw±ñVd§™»$ÖMjjZ«i_˜Ìð°ªðwnfxÆçY$„öyC·­ud×M[ö9íw…£x¸ï#?Iõ¯Ù)ZÀÝ®s“G!yPâÅ1«¹É¤„öOö’nRc˺HÕ‘Ì‹+IŠyÜò`‰iÆÄæLàzªCå»N§bBJ`ò¬ç¢»œÖæ tÕÉL3 $ÖM‡œk[«©ë«í<Ô‡6´ªá®ódë':ÌW×Y7}Ùç´ßqŽBâá¾Û*üI‰ ÍNQîvÝè?7yR—Gîv•xAB˜»ð‘ó0è¼÷‰ifmHÄ êÃ×¢…ý‹âF!%Pùî ć¹öUrÓŒó~Ç$À ÙS©Ús}è0êð¸Õ9D‡¹ÇRâ î°ë) !xœc˜‘Ñ@8eÆ0 † ¸`@Z܃@M‹€²CT}# °lZöSiªÃËþñϤF!ÅpjÖ´è#Â&«ùˆ õ} é$Å=ú­—«÷%1ͼË{¸žê0{FÚâØQH14;uܬ¨s·Ó:¢B}‘±§$@·]ÙS©Ï,ðpNð¡BGÅ‚á®}•”¸ÃýŽ H{ìê +xœchh(éi ÌIaì "%öu® ßúç]õDÃ}7<•¦:´TT&5 © ?rØ/_m&{DOÈŸ\¹™„Ø÷Ë?R¿…ä43aWàzªCƒ ‹cG!•¡Úœ‰7Uܶá ù›wíHN3 $ÖM/$[«©_˜Ìð~ÐÊçÐGFUéf§ýŽ£p÷9íqiðyWÙÅÿ‘x(õÜü”Õán׹ɣÚÐq¿Ò½[j“òð…|]# ±G…ÿÉiÆæH䊪ÃO|‹âF!µ¡äó%1 dã ùûФ§™†½Îû8 /êgO¥> Z»pÀCxøÁã–_x½·Ö´äà ù˺ÄÇ=îwÜëÜÌèêCxœchh09Ó@è¨`Ãüàè)!.æ+:~pÀØ{뉆ª’–O¥© -Ï~Ë’~&5 i/)ÊžXi+DKØG,[fHTÌKßWŒg¯ßBFšiíÒ \Oe¨|×éTìâQH+hsð¢Îf/÷mØÂ~­7S6éi†¤ºÉàBSk5•a}µ½£ã€‡ìð…]&Âá7b•¤›±„ýi“¦ "£¹nÚç´ßqŽBBpŸÓ>§=.4³—ÿ#ñ°¡Ñü”•án×þs“G!­àn×cVÌ'åa {Çý™ÓøˆŠù•á+Ãùß¹‘‘fRgG®ˆ 2|-ZØ¿(nÒ ~⻯¨Qö1¶°×½Ü_@\Ì£¤™ýŽˆ†›ü²§R´çú2Ðá:œaÈZ“3‚ïkZr°„ýŽ7"DÆ=¨~Úë L0ˆâê2xœchhØáÑ@ø À0 †8aA8Î+:$^|€s7'XÕ7’?Eê<•¦*|aóLjÒ>Ÿú”9·Rñ¬(Rè[WŒséûo”ÔK‘f,Üö®§*Üé•¶8vÒÞPÛérÈfI¤â]äÐ_ «Nrš!µnRzRÓZMUË0àá9 W(WB­Ð+«‘BUp ÉuSÃ>§ýŽ£pâƒûœö9íuFÔM]üI¾[ÍNQ2ÿ›< i3§_0x"£to·+rèïvá#ç+Ã˺V†¹f˜ÿE¬ .Ô¿¸(nÒnóbûÕ^y]óµ(rèk_%=Í4ìw<à@l­ÎžJ](ð~ဇçH€ònh,Žmh8dú;ˆˆuHýM0’wæêVxœchh``È™Ò@¸¡Á0 †øÆÕT‡+®kZBÖH¼ØàpEØ÷?cþÄúF¢áü^ï§ÒT…ÓÖÛ<“…t„ÏJkÕOW­/°Ûr‡w+O>ޏö[ØÏuàÖ~¾úç¥C‹Ëë© ýv&-Ž…t„7Ôô.\ÒQ¿~ÚxZækî:¦ZÓL‰u“àçºÖjªBs‡Å‘½B¥,ï‡?ôœ×²;YÿÚœ‘£njØã²Ïi¿ã(…˜pŸîqAI2>ï?ò“§äšŸ2£*ôÞ:7yÒfN]}̪£â'»ã~æ¿?YqÅõ•;*e]@ZÉ•¢4ÓT±‚º°¸wQÜ(¤'Üæ5+í¾âa[ŽõIó–D“šfö:ïw<à@4Ô½œ=•ºð¾ÂÂÅ‘å\09³×y§û{Á;ª1KpÆ6¬ŽÚ댔`ü¥äêxœch†À†Q0¬ç÷‚ 328 bö„Å‡Ž …8ïÆúF¢¡À³Æ§ÒT…—{”žI‚S³>çpøì þŸñ¿ ƒ É‚_ÿ÷/g8[¿…*iF[ãeàzªB.†øÅ±£p€ Ù)—c‚$§™’ê&F¦úÖjªBó='<äF.¼í(÷ã%ÉuSÃ>§ýŽ£päÂ}N{÷9a½Î{\p$Ÿü$ÀKúæ§Ì¨ CWÏM…7úÓÌžòλ*wT`qì¼÷ŽÊe—=ïܨ’f"VP>—\7  öÏKt&9Í4ìwÕeD«ÚÙS© ïËt¸dÈó帥öÖ ¨vÂ’\ÕÝêÅxœch†”9 Dƒ £`X‡ÄÇ>øþŸ}~z}#±Ð~ûSi*ÂòYϤFáB}É•4N3ª’ÿ×Sò~ÉX; úþºBrši ©nú(ØÐZME8ÍÿÚ€‡ÚȆd¥™=.ûœö;ŽÂ‘ ÷9‘œd|Þ¯çÿH4üd~ÊŒŠð˜ÕÜäQ8Ð{ ­ÓLCcÄ jB¡w‹âFá@B¯­Î$§™†½Îû8 k›³§RÎJ]8à¡6²!©i¹¿èê¼xœchƒ Dƒ  £`XˆÄÇ><—w¯o$ê‹>•¦"Ôgö&5 –½é§qšéœ"¸žŠð¤MÊâØQ8€0˜s?i†”ºéBSk5áñ[Rj#’™fö9íw…#îs"#É< çÿH, _e~ÊŒŠð‰ÌÜäQ8Pç2­ÓÌn×ÈT„í•‹âFá@ÂÓ&Îd¤™†ýŽˆ„ª·³§R.Š]8à¡6²!©iÓHåê»xœch€ Dƒ £`‹ÄÇ=x>ÿx}#‘pËå§ÒTƒ¢µžI„9—7Ñ<ÍXyo\O5xÙ,aqì(@èõõYi†”ºé’IMk5Õàõèε‘ ÉN3ûœö;ŽÂ‘ ÷9‘•dž…ó$:ï7;E=¸Ñnò(HºŠöiFïrÄ êÁ¸E‹âFá@BùÎd¥™†ýŽˆ„?8²§Rþb]8à¡6²!©i&iìêÏxœch€‡+ˆ÷”FÁ0ˆy U¿%~a}#Qð•ãSi*A˳ïežI„+y­ižfŠþœ \O%¨|WúCÜâØQ8€Ð£ ™¬4CJÝ$ö¾¶µšJ°¾úþ£µ‘ ÉN3{\ö9íw…#îs"+ÉH* ~ä'ªÜ3;E-¸Ûõ˜ÕÜäQ80~íÓÌ#ùˆÔ‚¯Eí.Š… ¿p;“•fö:ïw<à@l®ÍžJ-xÐ^õæ@‡ÙH‡¤¦æê¿xœch€…ˆ‡ìFÁ°ˆ‹ul€Á¡·¾‘ø‘«æ©4• ›jØ3©Q8€ÐrÒÌ›Ìçë©u¯§.Ž…Cû,ÈO3D×MkÃê[«©Ó=¹<ÔF6¤(ÍìuÞç´ßqŽçS}ö‘i†CP9p=U ò]éq‹cGá€Ábù‹¥)J3 DÕM&gšZ«©ë«ïo0ðpÉ ifŸÓ>§ýŽ£p$Á½Î%Ÿ«Âù?‚‰ ÌO™Qîv=f57yÌœ>7‘iFíV䊪À×¢öŃۼŸP”f@eÕãGöTêÀƒöª7:ÔF6$'ÍýèêÀxœch@JzÐÅ0Á7.†Q0,€Ã±M8|èªo$]xÕžJS²©†=“…õ%WÒ)ÍTrï\O¨{=uqì(@èûë åi†¨ºIíAMk5`º'÷€‡ÚȆTI3{÷9íw…#îs¢<Íì)ïâÿH²þ5;E ØQ17y$ôÞB¯4“xGÕü”ÅPâÅFÿ¹É£p  ÎïÍôK3ÙÓ"VP7ö/Š…O›zmq¡RšiÕLðÀ9)ÙS)‡ê7¸¿ t¸dHnšWhìêÎxœchÀ (<À. FÁ/$ðÅ0É@ªþ9ÃÙúFœÐ%õÜSiŠaò ·gR£p€`YFZ!ÓŒ²kàzŠaOUòâØQ8@0|r±òl*¦Bu“ãÆÖjŠa=¿î€‡ÜÈ…TO3{\ö9íw…Ãîs¢b’‘TrÝËÿ7dýc~ÊŒb(ñbnò((¨sen=ÓL蚈”ÃÚæEq£p  âýE1.TL3 {÷;pÀ ¹¾eO¥´[8à!7r!ùi2éêåxœchÀ vx”ôà’k«úÇÄ0 †0øÂ³!wÜ“ 6',èªoÄ “._ ‘}*MÔ¿÷_á™Ô(xÂp¯5]Ó {ÀÆÀõÁ¿Ì Ýq‹cGá€À[ÒÁÉTO3øê¦–šk†Õ­”ÁËš±¹_<ìF*¤QšÙç´Ïi¿ã(®pŸÕ“Ìæ®².þØaWù/v³S”Á'2/æ&ÂOdâÐ7Í\0è+ŽXAÜåVݺ(n |(ÿ…Û™êi¦T~pÀ §eùmÊžJ\ÓŸ?Ð!7r!%i“éîêÎxœchÀà’{!Á0 †,øÂóA_Ì“ |ÿŸ«ßR߈ê ›>•¦ Ȇ<“…OÆ-øE÷4cæx4p=E0dCêâØQ8 ð–tÊLM𤙔÷ÙìL“4Óª™8`…Bï²§R¿q.ð°©²4‚oïê×xœch 8äLÁ&~ÊŒa Qð…烡x§Hý7ÉŸX߈˦e?•¦ªÞ½Ø£ôLj›i˜f@%Ù ˜2'{*%°½ò¾ü@‡ÝH…”¦Ñ"ðê Õxœch H¼¨iA[Â0 †$øÂóA€˜X§øÖ??°|}K}# tn[÷Tš¨ÏìÿLj›iœf õÒ¸Í+{*%pQ콑 )O3gmõê!Õxœch (<0¸€*ÒSÂ0 † x!± ¸8§0œµ?X߈W-S*M6LZðMî™Ô(¤;,«1jð 4ÓÞ¯¸žl¸ßéŒ]ÜâØQHw>9*­>i£nê¨hj­&>cÓíðð‰Žif¯ó>§ýŽ£p8À}NôI3{>ò£Àìiæ§ÌȆ/Þ ÎM…ô‡:WJº*ÍL(ˆ\A6ÜpWyQÜ(¤?T¼?/Ñ™>iT3p@‚oD²§’ÕoD/èЙi¤ôòê"Õxœch 80¸€Ì'Ä0 †¸¡± ø§HÕo±?X߈€ÇõŸJ“UïþŠÖz&5 éËrœ|0Í”³\O¼ª}Ù,aqì(¤; îÌH+¤cšA¯›Ê&Ô´V“կߌîðð‰îif¯ó>§ýŽ£phÃ}NtL2’Êù‘ág³SäAÞÏýç&BúC+%Ý™f,NF¬ v–Ç-Z7 éO›ÎKt¦cšiÕLà0cFöTò`{å/Ö…~#R'Í•Aóê#Òxœch (‹N*pK3ÕÖ½Ù³Àá­×véæÖj48Í_ké§ MwŸ xèL8¸ÒLÃ~ÇQ8à>§N)p°·in2³º`PÒ¿PéÞ¤<³Sèð˜ÕF¥{:W jG!½¡Î¥»ƒ'Ílì]‚ö88íûÂs]SöqÄ t(ônbþ’¯mµ£ÞPñþ7NçN*pK3ê7*,üÎÙÐPÓ’35 ÎJm©ùÌ»:d Ãn¤Bê§^ÿê(êxœch \`ƒœ°p8@ISXô>y&…Ù¾ô\м… bïe0ÔŒBúÁâ$WtBAk?¨.ŽEƒíþ3|äû…š7?Äa¨…ôƒþõõ¿® tBAØÒÌîþþ=S–Ä@a®Ï× Fn#¶4Ó°Ïi¿ã(ìp¯ó@§$0oÁ¼ä¹hð½`èê'20è¸ÿ˜ºŠQHOè¸ß{ó`J3FÜ‹ã¡Á»ÊÏ%û aPò¹ýAt£ž°´Ûk‹Ë@'$€-ÍÄ,y(Ÿ?) YªßèPÙi\ ÿê)€xœch 0Œ‚A¦ä00PÃT+ŸIÂA ÄZž}èd‚-Ž…ƒ¼·o±ô@'0šf;|i¦a¯ó~ÇQ8¸á—N%(àNâüä¹£pCæ¿sWšy³$nÑ(Äð®ò¢h×N&(`4Í vH›4~¼ù*€xœch œ°`ƒ|á1¸@YìÒ<ð|&5 %‘‰_0ÓÌæîEq£pp‡ò_¸:`£ifðBÚ¥ˆsù+€xœch 0Œ‚A .,H 4niV¦Íz&5 !Ü¢êÝà;ÐÉ+8¤|wqì(„0°%?­p “V0šf+¼i¦a¿ã(¬pŸÓ@§¬àNòÜQ8(¡Ù©’îÁ™fÄ.Ž[4 !\0/Ñy “V0šf+¤eš6Qù,„xœch Y€Õjnò(¨tonÒÐL3²Š‹âFá@Ào\‹b:úÉ£if àÀ¤D“ù5xœch HXÀ0 èþ°LÉ9à@øpÂhý3©QHg¸2´IlæLÍŽ|2Á.¾_‹cG!á…£÷ÖU… tä“ FÓÌ@À¡fö9íw…÷:tÜ“ ïÎKž; é ã2ÿõÞù,Š…ô‚å‹€”ë@G:…`4ÍÐtš"´ù8ƒxœch  ðØÁ0 è8,H N¬ ,H8ùLjÒêÏŒiðèø¦ØòŸqì(¤ ô­ªM+è§M3ôƒÃ%Í4ìsÚï8 é÷9 t|Sì›—tÓX –-Ž…4€7Ä’Y8KtÓŒ¦ZÁá›fö;ŽBZÁ}N{\:~iî$Ï…4™ÓÍNÎKŽiæd颸QH ¸ÍkAüâh׎`€Ñ4C+8ØÒ ÓK ù=Šxœch "`TXfd00P3–X™6ë™Ô(¤2\šbYÿìã@G.À!廋cG!•á·Ä]‹¥:riFÓ -àðN3 ûG!mà^çŽ[;ÉsG!Õaüº¦¹‰Ã5Í<ˆ]·hRò|)î]ã2БK#0šfhcš•©%ù>xœch HXð‡…aPpØ@½tà„‘]¨Ì3©QHE¨?ó!¯õ@G, Á.¾J…Äű£ŠÐ·ª± y #–†`4ÍP÷4Ó°×y¿ã(¤6Üç4ÐñJCx'qáÜäQHMè½5~ÁpN3&|_ÅBjB¯m_¸:biFÓ õáàL3HQ"ù?xœch "ØÀ0 ¨î¨hÜ fì J`Á›òLjR †O`p;2ÐQJs°¶`éâØQH%x…'íõ«ŽRšƒÑ4CM82ÒLÃ~ÇQHM¸Ïi c”æ`Þ¹ɣZpydæ´áŸfŒxÅBjÁ„'Íœ:JiFÓ 5áàM3ñ²(ù@xœch "àøÁ0 ¨>L fÌ Z£#øLjR†/HPXœV8ÐJpl­ÿâØQH93]òµòìŽP:€Ñ4C-8rÒLÃ>§ýŽ£:pŸÓ^çŽO:€‹¹ó’çŽB*Àå‘Ë#ç&Ž„4cƾ8nÑ(¤ôÙâ³yq´ë@G(Àhš¡Üiú¾(ùA‹xœch *¸¢Ã0 (X¦ä(< n¼ b âióLjRW†6‰õ1œ訤0gk]; )‚wŽÞ[úìã@G%ÝÀhš¡Ž´4Ó°ßqRîu蘤øà?7yRã2ÿ-é9i¦øô¢¸QHäùrWy^‚Ë@G%ÝÀhš¡þ4à»/ùB„xœch *ØÀ0 (&P7N9p^zð™Ô(¤®ä}ù9~ £‘®` ÇâØQHô(舩èh¤+M3”‘—fö9íw…”Á}N‹t¥'ç%Ï…Àø…å#+ÍÜ‹_·hR¿ðxlwèh¤+M3”¡f¿Ð.ùC‹xœch 2x!Á0 ÈGl¨ƒ¬LûV£ñLj’öø=û8ÐQHwpHùúäâű£,xîÏäÅÒ…t£i†82ÓLÃ^çýŽ£|¸Ïi cîàN¢Þ•¹É£ùI•xœch  x!Á0 p‚ ´ ù! V¦}«Ñx&5 qÀðÊi³ž}èhTàòõÉÅ‹cG!93[ùîb鎦AFÓ ~8šf°€½ÎûG!~¸×y ciP;‰zWæ&B\py$LM3ÈàA´ÊýEq£ôÙ²(vqŒË@GÓ £i?êié¸AùJ“xœch  p8À0 °‚hêC쓼ôLjbe5© ‹Ÿ}è„`Ó/±Å±£ Ÿœ/ùz±ô@GÐ £iM38Á>§ýŽ£;Üç´×y ãg‚®-ó’çŽB,PçÊòȹ‰£itl]·hbŠ÷}6/Žqè„`4Íà‚Ã!Í9áCùK‹xœch 8cÂ0 ÐÀ ‰„´ ïa™]ŸIBXVãn´>­p £fÐSƞű£†OÎæû¥<{ £fЂÑ4ƒ GÓ °ßqbÂ}N{:f-øå:7y¢B+Jwç%ަ\ÀãÛ¢¸Qˆ ïã\í:ÐQ3hÁhšÁ„Ã%ÍmCùLxœch x À0 À´ ëaNlÒ&5 á0|WÂÉ´ÂŽ–A võU-Ž…px…'ÿ?¿ò쎖A FÓ *M3D€}NûG!2Üç´×y cePƒÄ»ó’çŽB8\é¸o^âhšÁL8Ç-…p˜° ´kq´ë@GË £i§4‰­FùMŒxœch ˜’Ã0 Àà‚ÁÚ…ô°üb-ϤF!nQ½ÐûäÙÇŽ!Ôîí[; 0°¥øƒêbéŽ!FÓ Ž¦¢Á~ÇQƒûœö¸ t| àôwnò(A³Sñ æ%Œ¦Â@ZyQÜ(Á _¸G»t„ 0šf`p¸¥ùÏIùN…xœch ``x"Ã0âÁŽ´ ãaV>“º¦õLj„Cß2)CZ|M°lq쇧Ì[Ë;ÐQ1dÀhšM3$ƒ½ÎûGá~Ç}NCÜIœŸ§ýŽ#îsè8b`oã¼ä¹#*Ý+éñÞ2šfH{Ç-±°¼s^’×V玄!FÓÌðL3£lRùP€xœch )˜PÀ0"Á‘Ž ‡´ Ûa ô>w<“ð9ß‹5Ë$WtðI°4æàâØoˆëîÿue ƒH‚Ñ43 HûG.Üë<С?$ÁñйÉ#fNŸ”ç½y4ÍÚv,Љp›×vï-.üCŒ¦™áõWùQxœch )``¸`À0ÂÀ´ Õa V>Û¢êøLjDÁ©žÂ 'Ó :è‡,8´8°¥cq숂—ØÊÿó+Ïè ²`4ÍŒ’Á—ýŽ#îsÚë<Ð!?dÁËSs“GÜèï¸o^âhš!<ˆ^œ°(ndAÓÓ¥]‹£]:è‡,M3Ãê[VùRxœch 1˜PðB‚a„€?,kB8~Ð:D‡=Ðûü¤Fã™Ôˆ€+CO½ÔÑy1ÐA>äÁҘݓ‹ÇŽxGáô»5ky:ȇ<M3£€d°Ïi¿ãH‚ûœ:ć<8^®{enòÈ€ñ ŸÈLÊM3”‚¶íJ÷Å Èó%nÑvçò!FÓÌð }^ùSxœch 9ø ðƒƒa؃-5 hš#<[àtHþ™Ô0‡e5œ[Ú:°‡ Ø73s^ÊâØaÃ'—jœãÛ1Ð=LÀhš$ƒ}NûGÜë<Ða=LÀ³å{s“‡;Ô¹"ñBéÎhš¡èÚ\ѹ(n¸CÅûg¾s¸ t`0šf†' ^ùTxœch иñ‡…aƒ7è’#”¹Õ„Ê<“¶0'XÃíí³Ìà ¬~½Z!qqì°…^¥í¯uKt0+0šfFÉ`ŸÓ~Çá ÷9íqèPV`Å´„…s“‡/ ]9m^Âhš¡&`7ãý²(nøBù‡'ÍG»t0+0šf†úÌ^ùUƒxœch  °8Á0,Á ‰Ž ú„àˆ¿/ß~&5 aYÍë5Ó :x‡%XÿUnqì0„á“ËuÏ+Ïèà–`4ÍŒ’Á>§ýŽÃîsèЖ`ʪyÉs‡!Ô¹2)onÒhš¡ˆ}°8nÑ0„Š÷°/Žqèà–`4Í 'IfùV‘xœch HXÀ0¬À– /è~#œ0ZÿLjÁ•¡«y×ìüÿìã@ì0»ø~-ŽFðŽ‚OA×C«ÅÒ°ÃŒ¦™Q@2Øç´ßq¸Á}N{\:\‡1H¼;/yî0‚ñ ãÖ5ÎKM3´&œ‹ã #Èóå OqÏâhרa FÓÌð£ÐgùWxœch иñƒƒaX€ 3Ð/äF,(sã9$ÿLjÀ-ªsÿì•\9Ð:Àê×ZóRÇØÒ$üø×•ÐFÓÌ( ìsÚï8\à>§½Îž#¬˜¦|onòp€f§t®xoM3´ìf‹â†\ xÏ{‹Ë@è£if¸ÔålùXŠxœch #ø ðB‚aHƒ'2=%èf#<[P_£ñLj(ÃkçÎ/š©9Ð9‚À¾™©“‹ÇaxM°ÆhGUÈ@ä£if ö9íwúpŸÓ@‡ãÏ"t¯ÌMÚ÷³÷–Ñ4C?еYéþ¢¸¡ »K•ïxouè€A`4Í LxqùY‹xœch 38cÂ0$Á‘9)?èZ£ aeZ³ë3©!ŸóùÅØé¼èàrcÏâØ!oˆ]}¼{-ï@à£if ö9íwºpŸÓ@‡ßw’ö¸ÎMŠ0súOöI¹£i†þàA Ï·EqCnóâøñƒÝy p‚Ñ43çsùZ™xœch 3``˜PÀ0¤Àž%1 èN£V>›ÿ¹ã™Ô‚' yÕ0|K+è ±àÐb‡˜ƒ‹c‡¼%}áÅôgÆÊ³:èF,M3£€d°Çe¿ãЃûœö:tÈXp'¡»bnòP‚OdÞ –tÏKM3D{ïX7”àCyã³óG»tÐX0šf†>â²zù[˜xœchÀÀpG…a€7"sR> D4°òYøãgRƒ>çó‹a(æH+è ‡_á©];èá ±«gÝqTž=Ð6 FÓÌ( ìsÚï8Tà>§½Î^£ áNҊȹɃfNÿÉÞQ>/q4Í 00 TèŒ °2-v͆CòϤ) Ÿ°ãóÑÊÏ>t@88¤üP÷켔űƒ^áIˆÙ;3{±ô@Ô(€ƒÑ43 H{÷;v¸ÏiË@‡Ó(€ƒ;‰Sò”îÍM¬pydGÅòˆy £ifð€Ñ¿Ù+:Å V˜°Àc‡ÏæÅÑ®P£FÓÌPÚ•ƒù] xœch00¡`Eà X8dÌX0p¡2 ð½Ï¡ÇrŸI *¸2Ôpæº?›|:pFV°4fUöšÅ±ƒ ÞQ¬š |+­p g`£if ö9íwŒpŸÓ>§›Q€/Ïš>7ypÁø…Þ[u®”t¦™Á Ú¶Ÿ2_7¸ ϯmŠ÷æ':tàŒ¬`4Í UUˆù^©xœchPpÀaCÀ†Aî¨ÌÈPxpÀa`Ãcûf>äý*óLjÀaø„jËN$£€ØTÕX ¢¸8vÀឤąϔ«B:HF0šfFÉ`ŸÓ~ÇÁ÷9íuè@×–„…ñ ç&<\Y×TÒí³y4Í vбõ+Ï—Eq÷ÎKôÞâ2ÐA2 €Ñ43qéŠù_¨xœchp0¡`JΆ$8è0$½ÏïÄ.P~&5 Ðr“eC·ä¥´Â†Q@X£zo×ÌìűCûÓÿSž=ÐÁ0 H£if ö9íwX¸ÏiŸÓ@‡Â( /gù» ȇ”Ïþjÿ3yq,Ýà%¶¬ÄU¿Ä”g´×G™`4ÍŒ’Á^ç}Nûé ÷9íshŸ2ÁDß-Ç­æ&Ónô¯kòÞ2/i4Í Uð ÚwëÅEqôƒ¦§‹{½¶.Žqh¯2ÁhšJdb›ùaÀxœchD aAÀ†=.?8hžÈl(˜Àñƒa ý: ¨Ny.ýRVvHþ™­àµ¼ ÒtŸ}hÏŽª€]|ïXÊ~̘—²8–Fðš`bÁBÉ÷kýK´gGUÀhš$ƒ½Îûœö;ÒîsÚç´×y ý: ¨ïXœ¼h ton2í`üÂå‘“rç%ަ™áL8Åoõ)ï\G+Ø]ú…ÇgóOöÅ1.íÙQ@0šf†“`ŸùbÐxœch„€ãGGŇ/< TNXÌIIXb´ÏFMÀÊ´X+k–Íd0T|&E¾à׃¢˜YFëìí¹Q@pHùáÚ`ÝýUÂÒ‹c©#gÆÖ}¼žï-=О4£if ö:ïsÚïHm¸ÏiŸÓ^çöÛ(  ¸“8%wrž÷Ö'2s“©—G:îÿÉ®tw^Ò¼ÄÑ43<Áƒèßì?Ù½·=”_G è³¥´›ãÇ7N`Õã2О4£if°K9«ùcõxœchÄà€ƒÁ…ŽŠ  >0 ~péßë<оt][L΋_hvjyäÜdb¡Ò=¥{Þ[ß ÎMöÞ²"¢´k4ÍŒ$бõ+÷Oö¯< |¶,Š#–w~ãòÚf|vQ¬÷VßÍó\Ú£€Ž`4Í NŒð½ùdÝxœch"€aAƒÆ ‡0e=v8øÀÀ0¡€îNƒ¬|¦ÒPö칓$¿Ââ´Yh°0áždx1dzùŸ;ž}h§Ž‚A-vIÛ¼ØíµÌ/!É×ÊwÑàùÿÿý¼ã¸Ø!æàbévê($`4ÍŒ’Á^ç}N0¸ß"äö:´KGÁ w˺ç%eMóÙ²"rn2:tÜç³¥³|^'ަ™Qb$.Ž=eæ½ÕwóâXtXÖå½ÕsûâX Žqh§Ž‚AFÓÌàÑÏùopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-composite/ref/out.txt0000644000175000017500000000006512271062644024334 0ustar mfvmfvComparing "a_over_b.exr" and "ref/a_over_b.exr" PASS openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-composite/a.exr0000644000175000017500000014414712271062644023162 0ustar mfvmfvv/1channelschlistIABGRcommentsstringcompressioncompressiondataWindowbox2i×ÿÿÿ(displayWindowbox2iÿÿlineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?spi:packagestring Katana 2.8.32spi:rendererstring Katana 2.8.328 Ô † ¶JØaÜcñrû‡ “{ðhàXÐQÑRÒHÀ@µ"š– } !}!ÿ!ƒ"#Œ#$$ %€%&„&''ú's(ë(q)é)m*æ*f+ê+d,ç,a-Ó-K.Á.E/Ã/C0È0K1Á1E2¿2A3¸304œ45”5 6…67€7 88þ8x9û9s:ö:m;æ;`<Ú<X=Ó=X>Î>I?·?2@¶@0A´A/B¥BC¥C'D¢DE•EF’FGGH‹HÿHyIôIƒJïJiKèKiLÞLWMÐMJNÂN8OµO/P¦P&Q›QR}RìRXSÜSHT·T0UžUV‰VøVhWæWRXÁX0YŸYZyZèZS[Á[;\ª\]]ï]_^Æ^5__ `€`ì`Za*bcËc–d`e#fØfgLhúh§iUj k²khl#mÏmwno»orpqÃqyrsÈsmtu¸uUvôvœwIxãxŽy5zÙz„{'|Û|€}~À~YùŸ€?éš‚>ƒãƒž„6…ß……†(‡Í‡uˆ‰½‰aŠþŠœ‹DŒñŒ:ŽÙŽy³S‘ð‘‘’5“Ô“r”•Õk–—°—P˜þ˜•™?šÝš{›œÁœiž«žaŸ ° R¡ü¡›¢:£Þ£|¤ ¥Ä¥f¦ §¦§T¨ì¨’©@ªæªŠ«2¬à¬Š­;®å®”¯;°æ°ˆ±6²á²ˆ³/´Ø´{µ¶¿¶k·¸½¸¹Aº »ñ»Ô¼Q½¿½1¾¶¾.¿¤¿'À ÀÁ¡ÁŸÂÃÃÄœÄ Å¡Å(ƳÆAÇíÇ×ÿÿÿ”xœchQÀá€Â½Ã〠.Hhh0¸0°îƒHÕ?g8[ßXÿ<ý?#¦7øÖ7Ú¬ß2ÐŽƒŒ¦™Q@2­›F©`Ë^ç}N˜p¯ó^çvÛ(”@RÉuÀå]wT`Ðy/?PDà½ë@;n J0šfFÉT3íwÄ„ úi Ý6dªÍùØÿÿÿªxœch`FÆ•;;r¦àSUÒ±Âä Ï— èä°Q08oýs‡/ñ¹þ*¬ÍŸX߈>芿"ðáA»|Ã@;z (M3£€ 0Z7ÒÀ^ç}N0¸ß7D¨Úë<Ðn |ÞWt® /ërÞËÿ,ëâÿè¼×yïÊpç=.íèQ0 `4ÍŒ’rtÀ7D®¥Ú̓”ñÏùÙÿÿÿxœch¶`AÂ…+ÈÑ[Òãpàƒ@Àj»i r õ?álüÂúF’ásðúç–ï¿5Ð^t£ifFë¦Q@*Øë¼Ï ÷;’!:÷:´F}Áž»*Î{ù?’˺îõ® sh?Œú‚Ñ43 H°Zé€éVC ´%¢•ÑùÚÿÿÿ‘xœch†@àà —=5-”›”3EãÆŠÊMƒ<¯ß"/â_·¾¥¾‘R˜¯=?QÞý¿É@{iÐŒ¦™Q@2­›F©`¯ó>'ÜïH)„˜³Çe }4 h ž…ÝUáÿxˆ)‡+ÃW†ó¿wh/ƒÑ43 H°Z逥bÎ^çöÑ {ƒËùÛÿÿÿŒxœchV€á€ƒÇj›ZÒ#ó¤£‚Ú¦Ž‚A|ÿŸûŸ®°¶¾‘ªð¹@xüÂýËÚs£€&`4ÍŒ’ÁhÝ4 H{\ö9ísÚïH]2sŸÓ@ûmÐø¼¿§â¼—ÿ#uaYו;Ê.í¹Q@0šfFÉ`¯3¨.9à@]©¡Úoƒ0cÏùÜÿÿÿ†xœch6@àƒÈ›‚ ´3?eÎÚ™> <¯./âÐ[ßH#(}þÔÞú-íÍQ@E0šfFÉ`´n¤‚½Îûœö9íw¤™¾×y }9 ¨ž… |tÞËÿ‘Vpe8Ðô÷®íÍQ@E0šfFÉR/p „ÔOíËA2žÏùÝÿÿÿxœchÀá€ÁzØSÑ!ñBá=l4Rõ[ìÖ7ÒJß{€—a ½; ¨FÓÌ( ŒÖM£€T°×yŸÓ~GÚÃ}Nûœö:´oG€¤²ÀG~:À•áe]Î{\Ú»£€ `4ÍŒ’¨f:à@{©ŸÚ· tFËùÞÿÿÿsxœchòÀá€ÁúÚhpÞ6Žª©ú-öëé íÚho Àhš$ƒÑºi ö:ïsÚïHO¸Ïi¯ó@ûzP$•>òÓ~pho Àhš$PÍtÀžT; ´¯¤ÀÍùßÿÿÿxœchÒ`A‚Ì“°·¦EáÀ‡°yP ¤â¯Ô7Òú­ßÎ^/5ОdÑ43 H£uÓ( ìuÞç´ß‘þpŸÓ>§½ÎíûQ@ØsW…ÿ#ýáç½+Ã\Ú÷£€0šfF©T3p ?„ÔOíûúqÍùàÿÿÿ†xœchÂàBÁ„³½¦EäÍÀÙ> ȾõÏ|zëú­o‘X¿e ƒaFÓÌ( ŒÖM£€4°ÇeŸÓ>§ýŽA¶ïuèP$Ÿw•]Î{ù?¼£$ß»t0ŒÀhš$ƒ½Î â€Ã@AHý4С0)ÀÏùáÿÿÿyxœch¢ aAÄŠvCCCΔí†Q@$ØÌ0+~a}ã@Ãü¸ÿ飀H0šfFÉ`´n¤‚½Îûœö;4Üç´Ïi Cb 6w |äðŽŠó@Å( Œ¦™Q@2ÕL‚ê§ º(¨Ïùâÿÿÿxœch’€åOMË@»\ö\h7ŒÀ·þù‚ãë[êôßhÿe ƒd£ifFë¦Q@Øã²ÏiŸÓ~ÇÁ÷9íuè€Ï»Ê®;*ü üà2ÐA2 €Ñ43 H{Au‡ÁAµÓ@‡][}Ñùãÿÿÿ„xœchrÀàBÀ†v*¨ia`h7Œ<À×>zÿòúÆAýÖ·üg¬ß2Ð3 p‚Ñ43 H£uÓ( ìuÞç´ßq0Á}Nûœö¸ t¸ŒœÀçêpþƒ ÞQ’ïÜ:`FN0šfFÉT3pLT?íuèp¡Íùäÿÿÿ{xœchbà„EEÇ@»ðØ¡ð` Ý0 °ƒÇï·×7:¸EáÃ@‡Í(ÀFÓÌ( ŒÖM£€T°ÏiŸÓ~ÇÁ÷9íuè°ØÁÞ•áütÞë¼Çe Ãf`£if @õÀ‡ÁAµÓ@‡ YÂÏùåÿÿÿ~xœchB€AáÁ@»7(鹡1ÐnhÀ÷¿ ÃÙúÆA Ÿ tÝè h`4ÍŒ’ÁhÝ4 H{\ö9íw¬pŸÓ>§¡Q€|Þ»îåÿ8XaYÿGç¢Q€FÓÌ( ìuÞïxÀa°BPý4Ð!DÛÜÍùæÿÿÿzxœch2€ÁgË@»0¸àp` Ý0 àÀ÷ú‡UõƒÚ÷Õ?è€p0šfFÉ`´n¤‚½Îûœö;n¸ÏiË@‡Ó(€Ÿå]ü;¼£ä:Ð5 à`4ÍŒ’¨f:à0¸á~ǽÎN4 }Ïùçÿÿÿyxœch" `BΔv1 f‰Á…vÃ(€‡Þü‰õƒn1˜kÿe Ãj@Àhš¤‚Ѻi ö:ïsÚï8øá>§½ÎV£ö|äÐy/ÿ—«Q£if @5Ó‡ÁAµÓ@‡!uÏùèÿÿÿsxœch`EDIÏ@»XPÒ³!` Ý0 žË¯èªoð¹@×þ’°Q0šfFé`´n¤‚}Nûœö; rë@‡×(hx^ÖÅÿqh@K:ÀFÁhš¤P™Àah@[:¼h (sÏùéÿÿÿwxœchà†FMË@»4Àñc ]0Âïýwë[ê‡ô³ÿR¿e ƒmDƒÑ43 H£uÓ( ìsÚç´ßq(Á}N{\:ÔF4ðùxG…ÿãP‚@÷¾sè`Ñ`4ÍŒ’¨´?à0”à~ǽÎj4|OÑùêÿÿÿqxœchô€ãÇ@»€ sÅáÀ@»aÄ)û/õCúåO¬>ÐA7bÁhš$ƒÑºi ö9íwzpŸÓ—¹ $Uø?=xG厒ë@݈£if ö;pzp¿ã^ç9_lÍùëÿÿÿmxœchä@àÃ@»€\à²ç€Ã@»aD‚çõÏë‡&ô¯ûŸ>ÐÁ7"Áhš$ƒÑºi ö9íwšpŸÓ^ç½ ž…óªð޲Ë@߈£if ö;pšT; tèÑ…¡ÑùìÿÿÿmxœchÔ@àÃ@»€±BáÁ@»aÄçõÏë‡.Œ¿ÂÀ0ÐA8âÀhš$ƒÑºi ö9íwºpŸÓ^çÁž…óÊÐyË@ሣif ö;pºT; tÒ¡ÏùíÿÿÿpxœchÄ@àÃ@»€R1CáÁ@»aDçõÏë‡4ô›œa ƒqDÑ43 H£uÓ( ìsÚï8´á>§½ÎŠ# < çÿ8´áç=.Œ# Œ¦™Q@2ØïxÀahCPí4СHuªÏùîÿÿÿpxœch´@àÃ@»€ `BÁ„vÈÏëŸ×7y¸Åá€ÃÊFÓÌ( ŒÖM£€T°Ïi¿ãЇûœö:tHŽð,œÿãЇÎ{÷¸ tPŽ0šfFÉ`¿ã‡¡AµÓ@‡$•éÑùïÿÿÿpxœch¤àÂ@»€Z ¤§`Â@»aD€Í RõÃ>Øëp` ƒsD€Ñ43 H£uÓ( ìsÚï8<à>§½Îš#lîâÿ8<`Y—ó—ÎFÓÌ( ìw<à0< ¨vèФ*# Ïùðÿÿÿpxœch”`‡Ç@»€š ¤§`Â@»aØƒÍ VõÃ>Øëp` ƒt؃Ñ43 H£uÓ( ìsÚï8|à>§½Î¢Ãlîâÿ8|`Y—ó—ÒaFÓÌ( ìw<à0| ¨vè¥""Ïùñÿÿÿyxœch„`BAMË@»º ¤§`Â@»aXƒçÿMÖ·Ô7#ø\`¯ÃÖa FÓÌ( ŒÖM£€T°ÏiŸÓ~Çá÷9íuèPÖàYØ]þà –u9ïqè`Ö`4ÍŒ’¨4?à0œ ¨vèP¥žwÑùòÿÿÿxxœchtÀá@IÏ@»ú ¤§`Â@»aØ©z)®úÆaŸ ìu80ÐA;lÁhš$ƒÑºi ö:ïsÚï8Üà>§½Î²ÃH*—wñn°¬ËyË@í°£if @5Ó‡áAµÓ@‡,•ÂËùóÿÿÿyxœchdà€CÊœvm@Á…í†a ¤þŸ;?½¾qÂ-:x‡%M3£€d0Z7RÁ^ç}Nû‡#Üç´×y CwXIåUáü‡#tÞë¼Çe ƒwX‚Ñ43 H šé€Ãp„ Úi C—*ñÛÍùôÿÿÿxxœchdÀcÇ@»€v c†Âƒvð¾õ[ÖÖ7Sè7ÿ8Ã@ñ°£ifFë¦Q@Øã²Ïi¿ãp…ûœö:t;àóÎm/ÿÇá ï¨8ïqè v`4ÍŒ’Á^çýކ+ÕNÂTVXÍùõÿÿÿnxœchT@áÁ@»€¶ aÁ‡vÃp gë‡1|Îþ?} Ãx¸Ñ43 H£uÓ( ìsÚï8œá>§½ÎÆÃ ìåÿ8œaY×e—ãáFÓÌ( ìw<à0œ!¨vè0¦?ÏùöÿÿÿpxœchDà†Æ@»€öÀg‹ÃvÃ0¾÷ë‡9|þ¡¼þù@ô0£if Fë¦Q@*Øç´ßq¸Ã}N{\:œ‡ðùÈ?ìaY×%×èaFÓÌ( ìw<à0Üá~ǽÎÎàêÑù÷ÿÿÿxxœch4 `CMË@»ÀâÄ@»`Ø€çûKÖ·Ô7{øüÁ®ú-ØÃŒ¦™Q@2­›F©`¯ó>§ýŽÃîsÚã2Ða=LÀ³°»*ü‡?,ëâç6Ð=LÀhš$PÍtÀaøÃýŽ{:¬)lèÓùøÿÿÿmxœch4 aÁ@»€^@æÉ@»`Xßúç ³êGô‹gèà`4ÍŒ2ÀhÝ4 H{÷9íwpŸÓ@‡ö°>ï+ºø?Ž xGÅy ƒ{X€Ñ43 H šé€ÃÈ€û:´)aˆÍùùÿÿÿexœch$ÀàÂ@»€žàÇ@»`_ûƒõ#JÇ[ t€0šfFÉ`´n¤‚}NûGÜç4Ðá= €ÏGþW†;t€0šfFÉ`¿ã‡‘÷;txSc‘ÍùúÿÿÿpxœchàÂ@»€¾ ¦eBÁ@»aˆƒÍ Rõ#ú­—û?k }ˆƒÑ43 H£uÓ( ìsÚï8’à>§}NæClîâÿ8’à••a.èCŒ¦™Q@2ØïxÀa$APý4ÐaN6wÏùûÿÿÿxxœchÀá@MË@»Þ ¤GáÁ@»a©úÆõ-õ# >ØËÀ0Ð?„Áhš$ƒÑºi ö:ïsÚï8²à>§½ÎîCH*ßUáÿ8²`Y—ó—ø! FÓÌ( €j¦# ‚j§w2q)ËùüÿÿÿtxœchpÀÀ°a Ý0 bÅ@»`Èßÿ³÷/¯oy0~aý–ü! FÓÌ( ŒÖM£€T°ÇeŸÓ~Ç‘÷9íuè°¢Àçýêpþ#¾wèÀ¢`4ÍŒ’Á^çýŽFÕNöd—ÏùýÿÿÿmxœchpÀóe ]0PÀâÄ@»`¨‚oëG$|þ`Wý–ý¡ FÓÌ( ŒÖM£€T°Ïi¿ãÈ„ûœö¸ tèM°—ÿãÈ„e]üïÜ:ô‡&M3£€T°ßñ€ÃÈ„û÷:tè“bõÓùþÿÿÿjxœch`P0¡¦e Ý0p€a ]0CÔú–úÆ‘ ÿ› tøE0šfF©`´n¤‚½Îûœö;ŽT¸Ïi Ã(‚=wUø?Ž\è<Ðá?Áhš¤PÍtÀa¤ÂýŽþdt3Íùÿÿÿÿ}xœchPàp aÁÀº``AMKGÅ@»aˆ©z)†Yõ#ú­Ü¿| #aˆÑ43šfH£uÓhÝD*Øã²Ïi¿ãÈ…ûœö9 t 1 ©TÑÅÿqäÂ;*w”]:†M3£i†d°×y¿ã‡‘ AõÓ@ÇÉm;ËùsxœchP ða`íx1ã€Ã@»aHçõÏëG4ô›Ÿø?} £aHÑ43šfH£uÓhÝD*Øç´ßqdÃ}N{:†xÎÿqdÃ;*w”]:†M3£i†d°ßñ€ÃȆ Úi cDÂÃÑùzxœch@° ¦e íÀeÏ@»`Í éë[êG:ôßX¿e £bÈ€Ñ43šfH£uŒÖM¤€½Îûœö;Žt¸ÏiË@ÇÄ›;ïªð…üïÜ:*† M3P8šfˆ šé€ÃH‡û÷:tL6Ïù|xœch@°a m<€ãÇ@»`ˆßzéýËëGa½Ÿ½ú@GÆ£iGÓ `´n‚€Ñº‰X°ÇeŸÓ~ÇQ¸ßqŸÓ@ÇÅ>ïÖ„ó…üï¨8td 0šf`p4Í ö:ïw<à0 8ìwè¸ |Íùwxœch0ðA`àì\ ¦e ]0TÀÞúÆQ„~ë[ê· tl 0šf p4Í Fë&­›ˆûœö;ŽBÜç´Ïi cch€½üG!ÞQáÿà2б14ÀhšÂÑ4C4ØïxÀa‚ ¨~èØ Ïù‚xœch ÀÀPÑ1Pv>2g ]0€ïÿÙ÷ÛëG!JŸŸ^¿e £dЃÑ4ƒ GÓ Q`´nB£u1`¯ó>§ýŽ£÷9íuèôÀçêpþ£W†ó¿wè(ô`4Í ÃÑ4CÕLF!‚j§Ž¢ Ïùpxœch `rf lœ@ãÆ@»`ð½õ£¥çÿèü`4Í ÀÑ4C­›PÁhÝDìsÚï8 pŸÓ@ÇÈà{ù?ŽB\î<Ð12øÁhšA£i†°ßñ€Ã(DÀýŽ#DÈÏùsxœch0¡``ìÌ`‡Ç@»`PƒçÿÓëG! |ž;ÐÑ2¨ÁhšÁ„£i†­›0ÁhÝ„ìsÚï8 Qá>§Ž•A ž… |ä…(°¬Ëy £ePƒÑ4ƒ GÓ °ßñ€Ã(D…û:VˆÒKÑù‚xœch±b`ìÌ ¤‡a Ý0ho}cüÂúÆQˆŸ tý7訴`4Í`ƒ£i†­›0ÁhÝ„ìqÙç´ßq¢Â}N{:f-ðy'ô‘¢Á².þ.5ƒŒ¦lp4Íà{÷;p…¨T; tÌŒ2Íùoxœí•± €0 YÁ ‡ž•ƒ‘dô´°ØDtïâï°¥é‡À=#®ú'Tô~©c:¨rK:¿°3¦ìLn“ ·é›‹PmŽèdürNÕ¶eE'ãvÆ”éP¤ª-‚Næ/ÎÏù yxœch ;8àP0þ¶ pCc ]0(Ôÿt‡ÞúÆQˆ Þèè”`4Íà£i;­›pƒÑº ;Øë¼Ïi¿ã(Ä÷9 tì J ©ì²—ÿã(Ä:z%M3øàhšÁ @5Ó‡Qˆ îwèØ!øÍù {xœch ;yB;‡ (éa`h7 B ¥¾qb…Ϻþ› t B0šfpÃÑ4ƒŒÖM¸ÁhÝ„ìsÚï8 ±Ã}N{:~!Táÿ8 ±Ã².þ.AƒŒ¦Üp4Íàû8ŒBìT; tüsGËù zxœch 3PxPÓBo;‡p80Ð.|€aÖú–úÆQˆúÕ?è|`4Íà…£i ­›ðƒÑº ìuÞç´ßqâ‚ûœ:†ØsW…ÿã(Äï¨8t >0šfðÂÑ4ƒ€j¦£Üï8Ð1DÚÏù qxœch 30¸@o‡¸`0Ð.dÀ×þ`}ã(Ä¥í£:’M3„àhšÁ£u!0Z7¡ƒ}NûG!>¸Ïi ãhŸü£/\î<Б4ÈÀhš!GÓ ØïxÀaâƒû:Ž”ÏÍù sxœchƒ L8à0ÐnDÀ·¾q€[¢þ§tD "0šfÃÑ43 H£u*Øç´ßqâ‡ûœö:t< "àóAà#ÿ(Ä ÷ÞQvèˆD`4͆£i ìw<à0 ñCPí4Ðñ„Ïùqxœch +ðØA_û†&и1Ð.L@am}ã($¥çÿèxL`4ÍGÓ ­›ˆ£u2Øç´ßq‚ûœ:žØËÿq‚+Ã:žM3DÀÑ4ƒö;p…„à~ÇŽ'¼qÏùpxœch #X@OÛ†2˜P0Ð.4À·¾q¥ÿÏè¨4`4ÍGÓ ŒÖMĂѺ ö9íw…ÄÀ}NWƒìåÿ8 ‰+Ã\:® M3DÂÑ4û8ŒBbà~ÇŽ+<õÏù~xœch #Ø@OÛ†2HXÀÀ0Ðnàùþåõ£øœaÖ“Ž®AFÓ ±p4ÍÀÁhÝD,­›``ŸÓ~ÇQH Üç´Çe ckP€gáüG!1°¬‹ÿ½ë@G× £i†X8šfà`¿ã‡QH Üï¸×y c 'o€Ïùpxœch X@?»†>àø1Ð.À·¾q ýìÕ:ºM3ÄÃÑ4£u)`´n}NûG!±pŸÓ@Ç×`{ù?ŽBbá环ÁFÓ p4Í€Á~Ç£X¸ßq ã '¡™Íù|xœch Ø@?»†>¨i1¸0Ðnpð|ÿòúÆQH$ô[ßbÿe £lÀÁhš!ަ0­›H£uìsÚï8 ‰…ûœö:tŒ 8xÎÿq ï¨ðpè(p0šfH£i ö;p…ÄBPí4Ð1†ã_Ñùqxœch 8à@/›† °92Ð.` õߤ¾q’¥×¿èH`0šfH…£if´n"Œøº©aŸÓ~ÇQH Üç4Ðq6À@R…ÿã($® wèH`0šfH…£i¦a¿ã‡QH Üï8Ðq†ÞîÍùxxœch ˆYB/›†Ø0Ð.@à[¿Å`n}ã($ î/èˆ@0šfÈ‚#:Í4ŒÖMä€]75ìqÙç´ßq’÷9 t¼ ðyç¶—ÿã($:tÄ M3äÁ‘œfö:ïw<à0 Iƒû:Þ°yÏù|xœch  XA{†H™ÃÀ0Ðn0ð\Þ½¾q’¥ÏOÿo2ÐQ7``4ÍGvš­›È#ºnjØç´ßq’ ÷9íqè˜0ð,œÿã($® çï:ÐQ7``4ÍGvšiØïxÀa’ ÷;îuè˜Ã®ºÍùrxœch  Ø@{†`ù3Ð.0ð|ÿòúÆQH2|¾@w £nÀÀhš!Žä43Z7‘ FpÝÔ°Ïi¿ã($îsè˜0ð,œÿã($–u9tÔ M3äÁ‘œfö;p…¤ÃýŽsXìÑù{xœch ˜‘A[†#¨èø0Ðn°Ù!ª¾q’¥ï+ÖK tô M3ä‘›fFë&²Áˆ­›ö9íw…äÀ}N{:ölîøÈ? É€+ÃW†¹ tô M3ä‘›fö;p…ä@Pí4б‡°2Íùrxœch p8@[†'й2Ð. U¿¥¾q’ýò¿tô M3äÑšfFë& À­›ö9íw…äÁ}N{$Uø?ŽBòà玾£i†|8RÓLÃ~Ç£<¸ßq cÔOÍùjxœchƒLhÐøÖ7ŽB à‡…t£i†28ÓÌ( ŒÀº©aŸÓ~ÇQH>Üë<Ð1HwàóAà#ÿ($:ïqè(¤;M3”Á‘˜fö;p…äÃ}Nƒh¶Ïùpxœch 90¸@{;†3ðÙ2Ð. ;ðµ?Xß8 ɆÏ?Üè(¤;M3”Á‘˜fFë& Á¬›ö9íw…äÃ}Nƒt>ùG!°¬Ëy £î`4ÍPGbšiØïxÀa’÷;t ¢o]Ñùnxœch 1Px@k†?Øá1Ð. /`8[ß8 )‚Ïr:é FÓ ÅpÄ¥™Ñº‰r0ÒꦽÎûG!epŸÓ@Ç"}Áü£"XÖå<бH_0šf(†#.Íìs:à0 )ƒû:Q¶Ïù|xœch 1xAk†?HXÀÀ0Ðn #Ø|àV}ã(¤>g˜õßd #’Ž`4ÍPGZ𭛍FXÝÔ°Ïi¿ã(¤ îsÚã2ÐñHG°¹‹ÿã(¤ –uñ¿w舤#M3”Ñ–fö;p…”ÁýŽ{:‘žÃÏùvxœch )XPÑA[Fø 0Ð. #x~¿½¾qR·p舤#M3Ô€#*ÍŒÖMÔ#©nÚë¼Ïi¿ã(¤îs蘤س*œÿã(¤:ïu蘤M3T#*Í€j¦£R¸ßq c ùÑùxxœch )øÁA[óG (˜0Ð. xÏ^ß8 )†[zë· tdÒ Œ¦êÀ‘”fFë&*T75ìsÚï8 )‡ûœö:t\Ò < çÿ8 )‡Î{ùß»tdÒ Œ¦êÀ‘”fö;p…”CPí4Ðq ÏÏù}xœch !``ȘAKóGàø1Ð.  ðýnþ”úÆQHèg¯>ÐÑI0šf¨GJ𭛍FHÝÔ°ÇeŸÓ~ÇQH ¸Ïi c“.Àçý=þ£ðŽŠó@G']Àhš¡)i¦a¯ó~Ç£p¿ã@Ç&½dÍù {xœch !ØáAKÓG¨è8à0Ðn Øœ`Uß8 ©¥ï‡üOè¥M3Ôƒ#%ÍŒÖMT#¤njØç´ßqRîsÚë<ÐñI°¹‹ÿã(¤\~GÙe #”`4ÍPŽ”4Ó°ßñ€Ã(¤ÕNŸP§Ïù!nxœch !ðØAKÓGx1Ð. PX[ß8 ©Ÿàèø¤M3T„#$ÍŒÖMÔ#£nÚç´ßqR îsèø¤ØËÿqR –u9t|ÒŒ¦*Â’fö;p…Ô‚û:>¡™Ïù"|xœch Ø@;³G"¨iø0Ðn 1x¾y}ã(¤ô[/W/5БJc0šf¨ GB𭛍 F@ÝÔ°×y¿ã(¤Üç´×y ã”ÆàY˜ÀGþQH5xGee˜Ë@G*Áhš¡. i¦aŸÓ‡QH=ª:NÁµ³Ïù#rxœch yB;³G&P¹3Ð. 1Š¿Rß8 ©Ÿ_ø;БJc0šf¨ ‡š­›¨†}ÝÔ°Ïi¿ã(¤&Üç4ÐqJc ©ÂÿqR–u9t¤ÒŒ¦jÃáŸfö;p…Ô„û:NÁøÏù$zxœch ¨è Ù#8hÐøÖKßo¯o…T…~õÏ:biFÓ -àðN3 £u-À°®›ö:ïsÚï8 © ÷:t¼Òø¼_ÎÿqRÞQv舥!M3´€Ã;Í4€j¦£ºpŸÓ@Ç+Ïù%oxœch x!A+“G20¸0Ð. !’©o…Ô†ö_:biFÓ Mà°N3£uMÀ°®›ö9íw…Ô†ûœ:^i$Uø?ŽBêCçŽX‚Ñ4C8œÓLÃ~Ç£Úp¿ã@Ç+ÆüËù&pxœch ˆXA+“G6p80Ð. ð_Xß8 ©ýêŸtÔÒ Œ¦ÚÀáœfFë&a\75ìsÚï8 ©÷:tÌÒ ø|ä…4€w”]:jiFÓ màpN3 û8ŒBêÃ}N³ Ïù'dxœí•Q €@ ÅpRpwü‚&†± PÑ,,¯5°¤/YgâWŒWôÛ~HÆéŽ ¡Í`¦ÝŒÀHû›¬U/’°Õè¶ë=<½D\¢ãBh3œY7c^ÎYz‰nk ëÏù(rxœch  иAsGACƒÃvMÀóùÇëG!M _ýóŽ^š€Ñ4C;8\ÓÌhÝDC0L릆}NûG!mà^çŽ]š€gáüG!màe—Ž^š€Ñ4C;8\ÓLÃ~Ç£6pŸÓG.êÑù)vxœch  ¨è ¹£ ¡ÁàÂ@»€À·^ú~{}ã(¤ ´ÿ2ÐL0šfh ‡eši­›h †eÝÔ°×yŸÓ~ÇQH¸Ïi ã—Àçýêpþ£VÐy #˜`4ÍÐÇ4Óª™8ŒBÚÀý޽ ·Ïù*pxœch ¸¡A SG 8hPøÞW¬o…4ƒ~õÏ:Š©FÓ mápL3£uÁ0¬›ö9íw…´ƒ{:†©|>òBÂ;Ê.ÅT£i†¶p8¦™†ýŽF!íà>§^Ïù+qxœch YC SG (<hPHõ/©o…4ƒ[:Š©FÓ mápL3£uÁ0¬›ö9íw…´ƒûœ:†©$Uø?ŽBÚAç½ÎÅT£i†¶p8¦™†ýŽF!íà~Ç^vFËù,{xœch :Ø@}3G2¨iø0Ðn *x¾y}ã(¤!ô[/W/5ÐÑLU0šfh ‡_š­›h†]ÝÔ°×y¿ã(¤%Üç´×y c™ªàY˜ÀGþQHCxGee˜Ë@G3UÁhš¡5~i¦aŸÓ‡QHKª0‚׎Ïù-pxœch :yC}3G*Px0Ð. *ð•Xß8 i ·00 t4SŒ¦ÚÃá–fFë&:€aV75ìsÚï8 i ÷9 t,Sø|ä…4†Î{:š© FÓ íápK3 û8ŒBÚÂýŽÁÔ4Íù.ƒxœch :È™B}3G*¨è8à0Ðn ð­oÌŸXß8 i ¥ï‡üO訦M3ô€Ã+Í4ŒÖMôênjØã²Ïi¿ã(¤-Üç´×y cšjÀçÐGþQHc¸2ü޲Ë@G5ÕÀhš¡^i¦a¯ó~Ç£¶T; X ¢Ïù/lxœch 2X@mG6 ða ]@Eà[ß8 i¥ë¥:¢©FÓ =à°J3£u}Àpª›ö9íw…´‡ûœ:¦©öò…´‡+Ã:¦©FÓ ]à°J3û8ŒBÚÃýŽÅÚÍù0wxœch 20¸@mG6PÑ1Ð. ðµ?Xß8 i¥ï·×oèȦM3ôÃ)ÍŒÖMtènjØç´ßqÒîsÚë<ÐqM%àó‘Ò® çï:БM%0šfè‡SšiØïxÀaÒ‚j§Šb IÏù1rxœch *XPÑA]G.ÀÀ0Ð. x~¿½¾qÒþ7èȦM3tƒÃ%ÍŒÖMôÃ¥nÚë¼Ïi¿ã(¤Üç4бM°gU8ÿÇQHè<бM0šfè‡IšÕLF!=à~ÇŠdäÂÏù2{xœch *¸¡A]óFn1ƒa Ý@à{_±¾qÒúÍŸòßd #œ `4ÍЗ43Z7Ñ “º©aŸÓ~ÇQH¸ÏiË@Ç7€ÏGþQH'xG…ÿ½ë@G8Àhš¡.i¦a¿ã‡QH¸ßq¯ó€D2ãiÍù3pxœch *pÙC]óF>pÁ` ]@à뿱¾qÒ JÛG t„SŒ¦zÂá‘fFë&º‚aQ75ìsÚï8 é÷9 t|Sø|ä…tƒ+Ã:©FÓ =áðH3 û8ŒBzÁýŽÉà Íù4{xœch "`` ¦i£€ˆY2Ð. øþg¬o…tƒ[ æÖoèH§Œ¦úÂáfFë&:ƒaP75ìuÞï8 é÷9íqè8§ø|øÈ? é÷ò¿sèH§Œ¦úÂáfö9p…ôƒû÷:@4ËÍù5oxœch "øÁAMÓFa° a ]@!xÏ^ß8 é· t”S FÓ ½áÐO3£uÝÁ¯›ö9íw…ô„ûœ:Î)ÏÂù?ŽBzBç½Îé‚Ñ4Co8ôÓLÃ~Ç£žp¿ãD3óÏù6qxœch "Ø@MÓFaà±c ]@!x¾y}ã(¤#Ü¢ð` #B0šfè ‡~š­›è†|ÝÔ°Ïi¿ã(¤'Üç4ÐqN!xÎÿqÒ:ïuèH§Œ¦záŸfö;p…ô„û š—Ñù7rxœch 0¸@=³F± aÁ@»€àk°¾qÒ>g8;ÐOM3‡vš­› 麩a¯ó~ÇQHo¸×y ãàóAà#ÿ(¤3,ët舧Œ¦™€C;Í4ìs:à0 é ÷9Ñ=¢ ·Ïù8rxœch `ùC=³F±@ãÆ@»€°yÁ¯úÆQHg(=ÿ×@G<`4Í Úif´n0¤ë¦†}NûG!½á>§Žw Àæ.þ£Þpe¸ó@G<`4Í Úi¦a¿ã‡QHo¸ß‘î 7Ñù9vxœch ˆYB=³F± ¦åÂ@»|`0·¾qÒú­Õà;Ð1O>M3‡xš­› íºiŸÓ~ÇQHo¸Ïi¯ó@Ç<ù`/ÿÇQHoxG¥¬Óe cž|0šfñ4³ßñ€Ã(¤7ÕNtŽhÏù:sxœch p8@-“Fi€ãÇ@»€L U¿¥¾qô³WèÈ'Œ¦™‚C7ÍŒÖM†lÝÔ°×y¿ã(¸Ïi ãžL ©,𑼣â<БO&M3‡nšiØçtÀaÜïHç¨vÉËù;}xœch `ùC-“Fi `Ã@»,°yÁ¯úÆQ8p‹C~²Àhš(8tÓÌhÝ4``ÈÖM ûœö;ŽÂ€ûœö¸ tì“6wñ…÷ò¿wèè' Œ¦™‚C7Í4ìw<à0 îwÜëLרiÏù<nxœch ˆYB-“F©à‚Á@»€<`0·¾q”¶èØ'Œ¦™ƒC6ÍŒÖM†jÝ´Ïi¿ã(¸Ïi cŸ<°—ÿã(¸2Üy cŸ<0šf Ù4³ßñ€Ã(¸ß‘®Q ï„Íù=sxœch  p8@sF9 dÍ@»€ U¿¥¾qôë¿>Ð € 0šfÍ43Z7 (’uSÃ^çýŽ£p à>§Ž2€¤²ÀGþQ8@ðŽŠó@'2ÀhšH84ÓLÃ>§£p à~GºF6þÍù>fxœch  øÁAsFÁˆÏãÙëGáÂ-H£if áÐK3£uÓ( ìsÚï8 îsè@2xÎÿq üà2ÐI€d0šfÁ4Ó°ßñ€Ã(8¸ß‘Ž‘ ÐÏù?sxœch  Ø@sFy@çÊ@»€dð|ÿòúÆQ8`Ð/ÿû@'’ÁhšX8ÓÌhÝ4À`ÖM ûœö;ŽÂƒûœ: ž…ó…ï¨8t Œ¦™…C1Í4ìw<à0 îw¤cd!ìÑù@|xœch ø@ SFù ¦åÂ@»$ð¼þy}ã(@è·þUƒï@'’Àhšh8ôÒÌhÝ4à`ÈÕM {÷;ŽÂ„ûœö:t* < øÈ? ÞQ)ëtèd@M3 ‡^šiØçtÀa$ÕNt‹n(°ÑùArxœch x!A SF%€åÏ@»€$ %/Rß8 >_ ;ÐÉ€$0šfµ43Z7 0Äꦆ}NûGáÀÂ}N H’*üGáÀ².çN$Ñ43ðp¨¥™†ýŽFáÀÂýŽt‹ntQËùB|xœch pÙC SF% cÃ@»à뿱¾q(ô›?å¿É@'Àhšx8ÔÒÌhÝ4À«›ö9íw… ÷9íqèt@ðùÈ? ÞQáï:Ð 0šfµ4Ó°ßñ€Ã(X¸ßq¯3¢úEÍùCsxœch ,H¨i¡Ü”Q@)Ø0Ð. H­o©o… ÷— tB Œ¦™A‡Rš­›JuÓ^ç}NûGá@Ã}Nˆ{îªð…:%FÓÌ C(Í€j¦£p á~G:E8 ÏùDnxœch œ° ÜŒQ@9p80Ð. ,Эo…ýêŸtJ Œ¦™A‡Tš­›JuÓ>§ýŽ£pàá>§N ă½üGáÀÃ;*Έ£ifPÀ!•fö;p…÷;Ò) æÏùErxœch \ ÜŒQ@  ð` ]@$ðµ?Xß8 ÜÂÀ0ЉH0šf :if´n4`ÈÔM ûœö;ŽÂÁ÷:tZ ø|ä…ƒ:ïqèÄ@$M3ƒ4Ó°ßñ€Ã( pŸ]"ü!ÍùF~xœch 00TtPjÆ( àù2Ð. øþŸ}¿½¾q¸åÂ@'¢Àhš§ýŽ£p0Á}N&€gáüGá`‚Î{:Q£if°ÁÁŸfö;p…ƒ îw¤y¤ »ÏùLzxœch ¸ì¡Lÿ( 6Ș1Ð. |ý7Ö7ŽÂAýæO©ß2ÐÉ/M3ƒ þ43Z7 :0è릆}NûGá`‚ûœö¸ tªÀ |>òÂAï¨ð¿sèdŒ¦™ÁšiØïxÀa&¸ßq¯3#ÏùMzxœch Ô´P¦P¬ˆhà¾õ~ë[êGá ‚ÒòU0ð€Ñ43áàN3 £uÓ`ƒºnjØë¼Ïi¿ã(\pŸÓ@§ <Àçý=þ£ppÁ•áÎ0ð€Ñ43áàN3  šé€Ã(\p¿#£ºÍùNqxœch l D÷(  093Ð.À|÷;Ö7ŽÂA·|脌¦™Áwš­›%ÔuSÃ>§ýŽ£p°Á}N.ðŸü£pÐAç½Î0ð€Ñ43áàN3 û8ŒÂÁ÷;Ò8Ú…ÏùO{xœch È<¡D÷(  ¨iy 0ÐnÀ ¤â¯Ô7ŽÂAýÖ¿jð褌¦™Áwš­›%ÔuSÃ>§ýŽ£p°Á}N{:eà’*üGá`ƒwTÊ:]:ià£if0ÂÁfö;p…ƒ ‚j'šF;}ÍùPsxœch ¤Ì¡D÷( ø 0Ð.À žŸŸ^ß8 ÜrÀa “N0šf'Ìif´n¤`×M ûœö;ŽÂÁ÷9 tÊÀ ž…ó…ƒ:ïu褌¦™Á sšiØïxÀa>¸ß‘¦Ñ5èÑùQlxœch (< _ï( %ˆX1Ð.ÀÎÖ7ŽÂÁ㯠tÚÀFÓÌ`…ƒ7ÍŒÖMƒ Þºi¯ó~ÇQ8á>§N¸Àü£pPBçN¸Àhš´pЦ™}NFá`„ûiñOÏùRrxœch ¼ _ï( -HX0Ð.À ¤äEêGá „ÏÎtòÀ FÓÌà…ƒ5ÍŒÖMƒ Òº©aŸÓ~ÇQ88á^çNX¤ ÿÇQ88aY§Ë@'¬`4Í ^8XÓLÃ~Ç£ppÂ}N4ŒxHéËùSsxœch Xœ _ï( -x1Ð.À 6?ØUß8 %|~€w “V0šf/¬if´nÄ`ÖM ûœö;ŽÂÁ ÷9 têÀ 6wñ…ƒ–u9tòÀ FÓÌà…ƒ5Í4ìw<à0 'ÜïHÈ7„ÑùT‡xœch 00Tt«wÐL``h7`ßÿ³ï·×7ŽÂA ·8ôþ7è$‚FÓÌ`†ƒ3ÍŒÖMƒ ʺ©aË>§ýŽ£ppÂ}N{\:…`Ÿ÷«Ãù?ŽÂÁ ÷ò¿wè$‚FÓÌ`†ƒ3Í4ìuÞïxÀaN¸ßq¯3Í¢ ÍùUdxœí•Á €@ í@K2çWÁbü{vdKÒ, oÉ ;Ó@`ÒUñKÎ5û‚À²’¬oÙ‰Ô \`3ð7ÕVÜ$×V² Ì÷ðôì”H@ÍÐå5SÝ®Qruûlú”ÏùVrxœch pü Wç( °81Ð.ÀRö_êG᠅ϼè$‚FÓÌà†ƒ1ÍŒÖMƒ º©aŸÓ~ÇQ8xá>§N!@R…ÿã(¼°¬Ëy “M3ƒÆ4Ó°ßñ€Ã(¼p¿#Í¢c~ÏùWwxœch xì Wç( ¨i9à0Ðn@ këGá …~ëÿ§tA£ifPÃA™fFë¦Á cÝ´Ïi¿ã(¼pŸÓ^çN#è`/ÿÇQ8xá•;Ê.FÐÁhšÔpP¦™ýŽFáà… Ú‰FQíÏùXyxœch Ô´«sÐòÂA˺œ:©ÀÁhšp0¥™†}NFáà‡ûiýjÍù]pxœch l G×( ?(˜0Ð.€ßýŽõ£pÀ-:±@Áhš*pð¤™ÑºiÈ€AS75ìsÚï8 ‡Üë<Ði |>òÂ!÷¸ tb‚Ñ43TààI3 û8ŒÂ¡÷9Ñ ú÷Ïù^nxœch H¼ G×( ?y3Ð.€‚ÍnÕ7ŽÂ¡åE:±@Áhš2pФ™ÑºiÈ€AS75ìsÚï8 ‡Üç4Ði 6wñ…C:tb‚Ñ43tà`I3 û8ŒÂ¡÷;Ò úX2Ïù_uxœch D¬ G×( ?È™2Ð.€ßø…õ£p(Àü‰õ[:¹€Áhš2pФ™ÑºiÈ€AS75ìsÚï8 ‡Üç´Çe S ø|ä…C¾sèä£ifÁA’fö;p…CîwÜëLõèdÏù`rxœch p ]Ï((ÐQ1Ð.©ÿ&õ£pˆ@¿ýË:Á4Œ¦™¡G𭛆uSÃ^çýŽ£p¨À}N^€@RYà#ÿ("ð޲Ë@'˜†Ñ43´ààH3 ûœ8ŒÂ¡÷;R=f Íùaoxœch l ]Ï(( ód ]¾ûëGá~ñì`FÓÌЂƒ#ÍŒÖMC Šº©aŸÓ~ÇQ8Tà>§N/@àó‘xGÅy LÃhšZpp¤™†ýŽFáPû©ž":Íùbxxœch | ]Ï((PÒÃÀ0Ðnhx^ÿ¼¾qø\ ë¿É@'™Ñ43¤ààH3£uÓƒ¢njØç´ßq¸ÏiË@§˜†gáüGáPe]üï]:ÉŒ¦™!GšiØïxÀa¸ßq¯3•gÏùcmxœch l ]Ï(8° a ]Ðð|ÿòúÆQ8dà–N0 £if¨ÁÁfFë¦!AÝÔ°Ïi¿ã(:pŸÓ@§˜†gáüGáÐÎ{:ÉŒ¦™!CšiØïxÀa¸ß‘Ê E¤Ñùd_xœchèÜ`øÖ7ŽÂ!Ÿ_ø;šfF!IpàÓÌ(r`À릆½ÎûGáP‚ûœ8Éø¼üÈ? ‡,ërM3£$8ði¦aŸÓ‡Q8”à~G*'âCÑùesxœch L( UÇ(XPÒÃÀ0 xþ?½¾q!ø\ ë¿Éhš…$ÀO3£uÓ^75ìsÚï8 ‡Üç´Çe@“̳0ü£pÁ².þ÷®£if’>Í4ìw<à0 ‡Üï¸×™ªIp¡Ïùfgxœch pü UÇ(h° a@­—²ÿRß8 ‡Ü2 )f4Í E8Ðif´n‚`€ë¦†}NûGáЂûœ4ÉHªð…C :ïuM3£$8Ði¦a¿ã‡Q8´à~Gª&^ƒÍùgdxœch xì UÇ(h rg`íWX[ß8 ‡|~áïhš…$ÁO3£uÓÐ]7ísÚï8 ‡Üç4°if/ÿÇQ8´`Y—óhš…$ÁO3û8ŒÂ¡÷;R5 ÞÑùh|xœch 00Tt¦c <(éa`0Ë}ÿϾß^ß8 ‡|.Ðõßd4ÍŒBàÀ¦™ÑºiH‚­›ö¸ìsÚï8 ‡Üç´ÇeÀ’ŒÏûÕáüGáЂe]üï]GÓÌ($lšiØë¼ßñ€Ã(Zp¿ã^g*&. Íùidxœch L Mý(`AÂÀÙíÐ[ß8 ‡Ü2p)f4Í Q8 if´nš` 립ÎûGáЃûœ.ÍìøÈ? ‡tÞë<šfF!Ip@ÓÌ>§£pèÁýŽTLâÏùjgxœch ¼ Mý(@ãÆ€Y-%/Rß8 ‡”žÿk4ÍŒB’à@¦™Ñºiˆ‚¬›ö9íw…Cîs°$#©Âÿq=¸2Üy4ÍŒB’à@¦™†ýŽFáЃû©˜›Ëùkqxœch \ Mý( ¤‡a€¬öµ?Xß8 ‡|.Ðõßd4ÍŒBà@¦™Ñºiˆ‚¬›ö9íw…CîsÚã2@IÆç#ÿ(‚°¬‹ÿ½ëhš…$ÀL3 û8ŒÂ¡÷;îu¦Z"0lÍùlfxœch äL!Mý(,`AÂYì›?±¾qA¸e€RÌhšºpàÒÌhÝ4dÁ€ÕM ûœö;ŽÂ¡÷9 P’ñùÈ? ‡$tÞë<šfF!IpàÒLÃ~Ç£p(ÂýŽTKËÏùmixœch | Eõ(L@å΀Xû¼þy}ã(’ðù…¿£if’*ÍŒÖMC PÝÔ°×y¿ã(špŸÓ€$™gaùGá„e]Σif’*Í4ìs:à0 ‡&ÜïHµd!ƒÓùnrxœch p Eõ(L ¤‡a¬•úoRß8 ‡$|.Ðõßd4ÍŒBà@¥™Ñºiƒª›ö9íw…CîsÚã2IFR…ÿã(𰬋ÿ½ëhš…$ÀJ3 û8ŒÂ¡ ÷;îu¦R2Š»Ëùogxœch ˆ¼!Eõ(\`BÁXê+ÿ°¾qQ(ýÖhš…$ÁI3£uÓR75ìsÚï8 ‡*Üç4IÆç#ÿ(²pe˜Ëhš…$ÁI3 û8ŒÂ¡ ÷;R)EÏùphxœch l Eõ(\@æÉXú|ÿòúÆQ8D¡_<ûhš…$ÁI3£uÓR75ìsÚï8 ‡*Üç4IæY8ÿÇQ8TáçÑ43 I‚“fö;p…Cîw¤R2€ÒÏùqvxœch 8¨i!^õ(l g Ý­”ªo\ßRß8 ‡*ÌŸX¿e4ÍŒBRङѺiˆƒ¨›ö¸ìsÚï8 ‡*Üç´Ç…ÎIFRéž ÿÇQ8„á;·Ñ43 IƒtO3 {÷;p…CîwÜëL•„QÍùrdxœch L ^í(Œ £‚Þ6:ôÖ7ŽÂ! ýö/M3£$8if´nê€þuÓ^çýŽ£p(Ã}NôN3{>òÂ! ï(»Œ¦™QH€4³Ïé€Ã(Êp¿#U—Ïùsgxœch ¼ ^í(Œ@à-”’©o…CJ×K¦™QH¤š­›†< {ÝÔ°Ïi¿ã(ÊpŸ“Œ¤ ÿÇQ8”áÊpçÑ43 I‚ôO3 û8ŒÂ¡ ÷;R%!8ƒÉùtgxœch è\!^í(Œ e-”Ê?Rß8 ‡0”>j4ÍŒB’ ýÓÌhÝ4äÝ릆}NûGáP†ûœèœd$Uø?ŽÂ¡ W†;¦™QH¤šiØïxÀae¸ß‘* PÍùugxœch ¤Ì!^í(œÀá]­{~~z}ã(ÒЯþùhš…$Az§™Ñºi:×M ûœö;ŽÂ¡ ÷:Ó5É< çÿ8 ‡6¼£ì2šfF!IÞi¦a¿ã‡Q8´á>'*$R^Ñùvhxœch p Vå(¼€å-“úoRß8 ‡8|¾@w4ÍŒB’ }ÓÌhÝ4,]릆½ÎûGáP‡ûœè˜d$•>òÂ!˺œGÓÌ($ Ò7Í4ìs:à0 ‡:ÜïH…¤O„Íùwbxœch ,H Vå(¼ `]­ó­o…CJï¿5šfF!IÎif´n€¾uÓ>§ýŽ£p¨Ã}NôL3{ù?ŽÂ¡W†;¦™QH¤sšÙïxÀau¸ß‘ IaÏùxgxœch °ü!Vå(Ì@àݬڼàW}ã(òPº^j4ÍŒB’ =ÓÌhÝ4L릆}NûGáЇ{é–d6wñ…C® sM3£$HÏ4Ó°ßñ€Ã(úpŸÅI‡Ïùycxœch ˜œ!Vå(ÌàýìØ[ß8 ‡<|Þà;šfF!I®if´n€žuÓ>§ýŽ£pèÃ}NôK3{ù?ŽÂ¡˺œGÓÌ($ Ò5Íìw<à0 ‡>ÜïHqRØÏùzfxœch äL!Vå(ÌÀæݬòÍŸXß8 ‡<”^ÿj4ÍŒB’ =ÓÌhÝ4L릆}NûGáЇûœè–d|>òÂaW†;¦™QH¤gšiØïxÀa}¸ß‘â¤ÿÏù{rxœch | NÝ(ì ¦Åá],z^ÿ¼¾qè·>°þùhš…$@ú¥™ÑºiغÕM {÷;ŽÂá÷9íq¡K’y&ð‘xG厒ëhš…$@ú¥™†}NFáp€û÷:S˜Y>Ñù|gxœch ¬ˆ NÝ(ü`‡]¬y.ï^ß8 ‡|ž;šfF!I^if´nF€NuSÃ>§ýŽ£pxÀ}NtI2ÏÂù?ŽÂá˺œGÓÌ($ Ò+Í4ìw<à0 ‡ÜïHab<Ïù}cxœch ð|!NÝ(ü@å}ìyð¶¾q øüÂßÑ43 I‚tK3£uÓðôª›ö9íw…Ãîs¢OšÙËÿqXÖå<šfF!Inif¿ã‡Q8<à~G ñÓù~pxœch Ø!NÝ(ü `]¬y¾~{}ã(p‹Coý–Ñ43 I€ôJ3£uÓ0tª›ö9íw…ÃîsÚãB‡$ó,œÿã(Ðy/ÿ;·Ñ43 I€ôJ3 û8ŒÂá÷;îu¦(1XÝÑùZxœch L NÝ(0àÐ[ß8 ‡ Ü2šfF!‰.if´n¤‚}NûGápûœè‘föò…Ã~pM3£4HŸ4³ßñ€Ã(.p¿#E‰ÿÀÏù€hxœch 00£j Àó…æVøþg¬o…Ãny 0šfF!Iif´nf€uSÃ^çýŽ£pøÀ}N4O2>>òÂa÷:¦™QH¤GšiØçtÀa¸ß‘¢ä¦UÍù_xœch ,H FÕ(* b,ñ­o…ÃÆ_M3£4H43Z7 /@ºiŸÓ~ÇQ8|à>'Ú§™½üGáp‚Σif’éfö;p…Ãîw¤(9ÿÕÏù‚gxœch °ü!FÕ(:@à-ؼàW}ã(FPº^j4ÍŒB’ íÓÌhÝ4ìÍ릆}NûGáp‚{iœd6wñ…à ® sM3£$Hû4Ó°ßñ€Ã(NpŸÉ£VÏùƒ`xœch ˜œ!FÕ(:à†­mØ[ß8 ‡¼2šfF!iöif´nn€öuÓ>§ýŽ£p8Á}N´N3{ù?ŽÂáGÓÌ($Ò<Íìw<à0 ‡ÜïHArÿàÏù„fxœch äL!FÕ(:Àæ-ðÍŸXß8 ‡”^ÿj4ÍŒB’ íÓÌhÝ4ìÍ릆}NûGáp‚ûœhœd|>òÂaW†;¦™QH¤}šiØïxÀa'¸ß‘‚äýÞÏù…mxœch $V3 †¨èp8@S |ëGá°‚Ò÷C꟦™QH¤y𭛆 uÝ´×y¿ã(^pŸÓZ¦™=ùGá°‚+Ãï(¹Ž¦™QH¤yšÙçtÀa/¸ßq¯3Ù IÏù†dxœch fdV3 † i¬nvˆªo…à >wèM3£$HÛ43Z7 K@ÛXÝç´ßq7¸Ï‰†Ifs§ÀGþQ8Ì`Y§Ëhš…$AÚ¦™†ýŽFápƒûÉNsÏù‡fxœch ^HV3 †xACÃ¥äEêGá0ƒÏðŽ¦™QH¤m𭛆% iÝÔ°Ïi¿ã(npŸ “Œ¤ ÿÇQ8Ü`Y—óhš…$AÚ¦™†ýŽFápƒûÉNâåËùˆÈxœch 4nV38AÈ+?nhl@ÝáqÁ€åÊ9SÊeÐÐðçó×7Iè×_˜?ÑþË}ÅýŽH¢Ï®Ø÷.H¸ðWamþÄwã@Áç gGÓ 8šfpCÚ¦™ÑºiXšÖM ûœö;M¸Ï‰hdØÐ0É< çÿ84á³?Àay×Êð²®².ç½í¾„@ÿ¦,p4Íà†´M3 û8 MH¸„hdØ Óù‰Îxœch BÖV3¸@ÌŽ V¹ aBÁƒ hî¨AÐÌh©þ%õC n1ȲïûoRÿœß=ÿ?ë¯ý‡Þw5ÝC‰a4Í Bc4ÍJ4L3£uÓ04¬›ö9íwZpŸîq!췽εCϔýÎ4K2’*ü‡tÞ{GeeØ]%Wž۳*Ìe/HÇ@»yB‰˜<5šfFÓ r(Ñ0Í4ìw<à0´ ñe/¢Nh7Óîs"3A>jÍùŠÃxœch ©L ¢CäMÀrt:x!as¤¢ƒÚ.¼à… öýÏXß8d ôývùêý·Èð§T}£üºõ÷ÛÜô‚~òîTO-0šf†+¤]𭛆- YÝÔ°Çe¿ãÐûœö9íu&ÇŸ{Az÷9 ´èVÔN+Pàó^ð#ÿ+Ã8Ì… J*ßUYÒ?Rà²ò`4Í WH»4,³8 H~™ «•Úô +2“yÉù‹Ãxœch 6R1X@EËJÍp8°ÃÃàBE5Ü3ØÍü|ÿòúÆ!¥ï¿]ð«~ E¾•ª—J°²¾ß>ྡCx­E¥4‚FÓÌp…´K3£uÓ°4«›ö:ïwpŸÓ>§½Î”ùv È”}Níú„uRx&ð‘HÀ•áe]üï])ò­¤REȤö }‹Âü…Œ¦™á i—fö9på-¬&h¿Ð'¼È $ zÏùŒÂxœch NXR18€Éj™åpà„…Çj™6XAE‡ÃÚ˜¼@·¾qÀ-{ÿ›PÉËRõÏ$(¬p?ÑJß©N¥C£if˜B¦™Ñºi¸ÚÕMûœö;¸Ïi¯3µü¼ÇeŸÓPñ7%!¶Ç…Z!† öò Ðy/ÿj…€¤’ë^ç!âoòáÊð;J®T 140DÂn4Í i˜fö;p TÖRËÏ{Ae÷@ûˆö!Ffm  Ëù»xœch >R1ð ¦åõM5¸ ñ¢¢ƒúæ0#ƒ&Æ>¯^ß8È¡ßúW ¾T÷¹¯½ú’ûíî;ÚÁç½T5M3í;ÚAZ¥™ÑºiÕM ûœö;v¸ÏiŸõ}¾×dî@û¶áFýP‚gáü;¼£RÖåLuŸû|(ïZ9|O>,ët¡z¨Àhš¾Vi¦a¿ã‡ÁAå,õ}©—Úo´ 7²oOÑùŽ­xœch lŽR1Р¤‡vf/H``(˜@;󈼡‰±Ï×o¯oÔð¹@Wýšø|ÿ›8ô¸iåEhf£if4Í Fë¦Ñº‰T°Ïi¿ãà†ûœö9ÑÆï {A¦´ir4 ´gáü7,ëâÿàB¿ÁÎ{Ú‡´ƒÎ4 ´Ñ43šfHû8 n*eiãwXÍ<Ð>¤]È‘(cûÍù­xœch r¦R1° ¤§`­í`` ½b–ÐÄXßü‰õƒ>Øëp€&>‡‡@}ã‡Þ÷)õრ´ ±Ñ43šfH£uÓhÝD*Øç´ßq0Ã}N{iãsØë¼Ïi°‡¹aG“óùÈ?¨aY—óšøï?:ïhÒ:Ó(·¦™Ñ4C2ØïxÀa0Cš•°p©—ÚŸ´ ;²±¼Íù·xœchÀ 8à—hPÓ2#ƒ>6ñ|©è Mô T7Rê¿I}ã †~ë_9ôRÝטÀ·~˃öûíî_ªÃÿ&T«Ñ4£i†0Z7ÁÀhÝD,Øë¼ßq0Ã}Nûœ¨ïklá²i }K}¸×™êA%©,ð‘Ã;*e.T÷5&ðyïºweø@û–ðõCo4Í@Àhš!ìs:à0˜!¨|¥¾¯±…Ȧö-õ!Y5;ó6Íù‘¦xœchÀ &à—hÀò‡~v |°8A?Ûè.PÝÈçÿÓë1|¾@—ê~Æõ¾v ¸© ¥í£¨N£i£i†80Z7!ÀhÝDØç´ßq0Ã}NÔ÷3.°×y°‡Æ ¿gaù1,ër¦ºŸq‡Ey×@û—Úpe8õÃo4Í ‡Åhš! ìw<à0˜á~GêûÕLíßA~éÑù’¥xœchÀ ^Hà—X±‚Þ6nÈ™Bo;i .PÝH)y‘úÆÁ ãÖo¡ºŸñßýŽùÚ×Ô„ö_¨F£iŒ¦"ÀhÝ„ Fë&Â`ŸÓ~ÇÁ ÷9íq¡¾Ÿñ‡ÇàÒCêA$©ÂÿqPÃwnT÷3>à3Ðþ¥:t¦z¦T0šfˆû8 ^¸ßq/ üŒ?<wˆ‚dÛËù“¦xœchÀ à—X° a ì49C[iJz¨o&ÃÙúÆA ·P߿ĽîsjÁç]ÔÅÑ4ƒ FÓ ~0Z7aÚ9Z7áûœö;^¸Ï‰ú>&ö:î0!5÷¸P=„ø?^è¼×™Úþ% ö¸ ê0! –uñ¿s£v êðM3”Bš¤™ýŽ/ÜïHmÿ ši ýMÍ$#ß èÏù”­xœchÀ |¶à—H°a l~ PÓ2PvSL ²›?¬ªo¤Pzÿ-*û–èPix¾¾eÀýO¸ÅáµCg4Í` •Ñ4ƒŒÖMØÀhÝ„ìsÚï8Xá>'jû–øPÌáBÜëLåÀÙÜÅÿq°Â•áÔö-ñ¡rGe }O-è¼Ç…ê¡3Ð~ GÓ 5 õÓLÃ~ǃîw¤¶o‰•Á.¤A2jx±ÅÓù• xœchÀ JzðË$X1pvLȘ1p¶S00PÙÀÍ]õƒJËWQÙ·$‡¨ùS<¨ÿ›P9hFÓ 0šfpƒÑº ;­›pƒ}Nû+ÜçDmßö:æÐPÜÜÅÿq°Â•áÎTö- `Ï]•ö?µ µCq4Íà£i7ØïxÀa°ÂýŽÔö-ñT3 ´ÿ,>\Ëù–®xœchÀðÉ,H™3°ö30D¬XP¸ì¡ªq¾ÿë)”>?½~ U}KrØÄ/ðP ôBíphá„£i†JÊif´nÂFë&ì`¯ó~ÇÁ ÷9íq¡®oI ›}NÔ Gª‹Ïüƒ® ççFUߟ°! :˜pM3Ô‚ÔM3 ûœ8 V¸ßq/•}KjØìwè0 N8’ìun«Ëù—³xœchÀ$à“XÀòg ]pÀÁcÇ@»rPÓâp€ªúÖ7Rø|.U}J:úŸ®°vÀÃRè·>°þ9UÃe4Íà£i+­›ðѺ Øç´ßq°Â}NÔô)9`¯ó`âÃq UC…ÿã`…e]ÎÔô)@RÙe‡±ðŽÊ%WjË “Ñ4CHõ4³ßñ€Ã`…û©éSr¨fèP F8î%5÷òÍù˜¤xœchÀ>à“X ða ]+Ú”ƒ Ô4ío}ã …ÒõRÔô)YÀ·¾1~ဇ¥p ue4Íà£i ­›Ѻ ìsÚï8Xá^gjú”<°×y0‡±pŸUÄÿã`…+Ã\¨éS²€Ï{ÁÊ¡3usßhšÁ FÓ °ßñ€Ã`…Ô-QÉ ši Ãr¸ß‘DoÜ`Íù™ xœchÀTîà“Hà²g ]2f ´("o¨hØæ §ê'ôBE’67<Ÿ?e Ã‚R(/BÍM3ÀhšÁ£u!0Z7¡ƒ}Nû'ÜçDM’ö:Þ0°ÜÜÅÿq°Bg*ú“|°¹ó®Ê@‡Äà ËÑ4CŒ¦ °ßñ€Ãà„û©éOò¨fè° {XôÑùššxœchÀ|¶à“Hð@a ]íJAÄ *¶ùêúÆA Ÿ7øRÑŸ”©ý%Âø+T Ñ4CŒ¦40Z7£u*Øç´ßqpÂ}NÔô'%`ð†Ñ€„åæ.þƒ–u9SÑŸ”Ie J!5Ãr4Í£i ìw<à08á~Gjú“0xÈfa ø€Ïù›šxœchÀJzðÉ$x 0Ð.@ž/íJÁªµY «¾qPÂç ¾Tó%ÅàÁÛÊ ßÿtªÆhš! Œ¦d0Z7Fë&d°Ïi¿ãà„{©çKJÁà ¥ÍÍ]ü',ët¡š/){:4(…w”©š£i†(0šfÁ~ǃîs¢ž/)ƒ7”hš2Ñùœ¯xœchÀ pË ,ðÙ2Ð.@ Ú ”T2È÷?c}ã „Ï?Ü¥’©|ÿ§3Ìð0¡úýO§ZX0¸o°ÃÑ4C]H½43Z7 Fë&Øë¼ßqpÂ}NÔò#5À—}N"ƒ$<}>|ä”°¬Ë™J~¤ðy_Ñ5Ð!B¼£B­ðM3ÄÑ4ƒö9pœp¿#µüH ªÃ:DèžÁ3ÍùžxœchÀ fdà–Xðƒc ]€ & ´ ( ¨dÐf‡¨úÆA ¥ã­¨äGê€çÿÓ§ýŽƒîu¦–©oX÷9Q)$Uø?N¸2Ì…J~¤ØÜ5ÐaBQx†S+ަâÁhš‚ýŽ'¤ZYJ50xʸߑ$ÏçiÍùŸ®xœchÀ $^à–H1c ]€ .Ô´ ´( ¨bÌæ·ê!ô›œ*þ£&ðµï[ß2à!C>ÜÂÀ@•pM3ăÑ4£uñ`´n‚€}Nû#ÜçDÿQìu¬¡EÜëL•`ØÜÅÿq0Â;*Ôñ5χ»*.”@ç=.T ‡Ñ4C<M3P°ßñ€Ã`„û©ã?jPÍ4ÐáB $©¾çžÏù ›xœchÀ 'êøº`°†}Ãt/ÿÇÁ÷:SÇÔƒ4´ˆƒ+馃4FÓ õ!ÕÒÌ~ǃîw¤Žÿ¨ khÑ L8èËù¡¤xœchÀ r¦à–H°!` ]€ |¨ih74nPÅßü‰õƒî/¡Šÿ¨ ž×oYß2Ð!C6”žÿ‹*¡0šfH£i Fë&RÀhÝûœö;F¸Ï‰:þ£.ØëòJxGÙ…þ£>Ø;Ð!C>t¦N>M3¤‚Ñ4³Ïé€Ãà„Ô)G©ö;tÈ÷;’àQÏù£¡xœchÀà’X°a ]€ (<hPPlÄf†YõƒJï¿EyøÐ0œðÐ!úÕ?§8FÓ É`ħ™Ñº‰d0â릆½Îû#ÜçD¹ßhkˆ÷:S›;>òB¸2œr¿Ñìœ!F¼£ìBqŒ¦’ÁˆO3 ûœ8 F¸ß‘r¿Ñ Ö#’Pç âÏù¤šxœchÀ.à’X ða ]€\h(PlÄs{õúÆA¥ë¥(_ûƒ>äÂç ¾û4ÍFzš­›È#¼njØç´ßq0Â}N”ûV`°†ÂõY8ÿÇÁW†;S!ri|dC{*”£i†t0ÒÓÌhÝD:éuÓ>§ýŽƒîs¢Üo´{:t6\÷òŒÐy¯3å~£Ø#0àáCAÈRîÿÑ4C:éif¿ã‡Á÷;Rî7Z}N:t WÑù¦—xœchÀ .à’¸AÀ†v¹ `ÅFøÚ¬o”p ˆVàùþå>d†ªÃŠ}?šfÈ#;ÍŒÖMd]75ìsÚï8á^gÊýF;0XC0ÜçD±ç}>òNøÞ• QK+ð,|ÀÇLèL…¼8šfÈ#;Í4ìw<à0!ÊP‚Áj„á~G¢= rÑù§ xœchÀ"Và’H°a ]€phPh€oüÂúÆA¥÷ߢFèÐ Hý7ð0"úÕ?§Ð÷£i†0²ÓÌhÝDÑuSÃ>§ýŽƒîs¢BàÐ ÎP#îu¦Ðó>ù!\N©¿h $U:„ȇw”](ôýhš!Œì4Ó°ßñ€Ãàƒû©µ´ƒ3ÔˆƒD×û¦ýÍù¨¥xœchÀjZpÉ $ø0Ð.Àr¦ ´È(4@j}K}ã ƒÒõRÔšßÿŒù<”ȃÏ|)ôýhš!Œì43Z7‘FtÝÔ°Ïi¿ãàƒûœ¨84{\g¸Ñ%l%Uø?>¸2Ü™*QK+àó^pÀÈ\XÖEiØŽ¦rÀÈN3 û8 >¸ß‘QK;°×yp†UÃð©Éù©’xœchÀ `h°!` ]@ð|h .P¦Ÿál}ã`„ûK¨>´Þt‘ í)Lí£i†\0rÓÌhÝD.¹uÓ^çýŽƒîs¢NøÐìsè0¨°Ý#ð‘PBgêÄ,íÀÞ¡ ÛÑ4C.¹ifŸÓ‡Á÷;R'fiö;tÑg8K­Ð¡!ªß2à!Eô«N¿GÓ ù`¤¦™Ñº‰0B릆}NûÜçD¥À¡)œaG ÜëL·7wñ|°¬‹?Ñ Hª t8‘ ï(»PàïÑ4C>©i¦a¿ã‡Á÷;R+bi g؉¬û²^Íù¬œxœchÀ DÞ`X qc ]@ Ø0Ð. oð¥Äߣi†l0RÓÌhÝD¡uSÃ>§ýŽƒîs¢RàÐ ΰ£yøú|ä„pe¸3Õ"–v`p†1°¬‹’ðœþM3´…”¥™†ýŽÜïH­ˆ¥%œaGÅð™Ïù­£xœchÀ ,N`Xð@a ]@ ``(˜0Ðn \ @óæ»ê|ÞàKµà¡ðýoâÐ;àaE´ÿB¿GÓ ù`¤¦™Ñº‰0B릆}NûÜçD­Ð¡%Øã28CÆá»¹‹ÿãàƒe]ÎT‹XÚŸ÷®{:¤È…”„ïhš!ŒÔ4Ó°ßñ€Ãàƒû©±´{gèQ-|‹GÏù®›xœchÀ b–`X°a ]@y3Ð. L D·ÁÜúÆA¥÷ߢVèÐøÊ?ð°"nq8@‰·GÓ `„¦™Ñº‰02ë¦}NûÜëL­Ð¡-œ¡Gîs¢Ä×{ù?>¸2Ì…Z±JSà3à!Et¦,Oަ ÀM3û8 >HYÙI?08C0ÜïH”÷ >Ïù¯¬xœchÀ°‰4¨èh 6 ´ ÈÈÔèûŸ±¾qÐAéûíõ[¨@´Ï÷/ðÐ"Ú!ÓÏ£i†20ÓÌhÝD!uS×ýŽƒîsÚãBÍð¡Øë<ÐaE.ÜëL¦—}Þ ~ätpe8ÿ;7ªF-­À³0-2ársåhš¡ ŒÄ4,[8 >HAÉIg°Ïi ÃŠ\¸Ï‰ï_Ïù°xœchÀ .`hà²g ]@<Y3Ð. \0 S£¯ýÁúÆÁýŸP5xh ¤ú— th‘¥í£Èôñhš¡Œ¼43Z7Q F\ÝÔ°×y¿ãàƒûœ¨:´ûœ:´èÆ>>òBèLÕh¥%Tè°"® '7ŒGÓ ¥`ä¥`ÉzÀaðÁýŽÔŒVÚ‚ýŽZ4 c.¡Ëù±‘xœchÀ$`h ða ]@<ø 0Ð. hÜ [«o}ã ƒÒõRT ƒ¼^d…ñü_d{y4ÍPF^š­›(#¯nÚç´ßqðÁ}NÔ Ú‚Á‚´ ã½ü\îLÍX¥-”!HÓ0”>M3ƒ:Œ÷;p|p¿#5c•¶`p† •ŠÍù²ŸxœchÀ(`h°"b ]@<œ!HdÌ Sãæ©úÆA¥å«¨<´ƒ3 C¿ùLJ•GÓ í!ùif–¬£uíÙuSÃ>§ýŽƒîs¢fèÐìuèТsoîâÿ8øàÊpgªF+-ÁæN/ràrÃx4ÍP F^šiØïxÀaðÁýŽÔŒVÚ‚}NZ4 cÆìÍù³‘xœchÀDÞ`h ða ]@ °92Ð. ʾòë”®—¢rðÐ<_¿}ÀCŒž¡<šf(#-ÍŒÖMT#¬njØç´ßqðÁ½ÎÔ Ú‚Á†4 eŸüƒ® s¡r´Ò< èð¢o(¦ÊÁHK3 û8 >¸Ï‰ºÑJ[08Ã*¡ 0Íù´˜xœchÀ,N`X3e ]@8a1Ð. p KÛæ»êÌ?Bݰ¡5X ;Ð!FôûŸN–wGÓ ÀK3£uÀ«›ö9íwlpŸUƒ†æ`0†! ÃysÿÇÁ©©4{:¼ÈƒwTÈ çÑ4C0ÂÒLÃ~ǃ îw¤nœÒ Æ0¤R8Ž¿ÑùµžxœchÀb–`X`rf ]@p8PÑ1Ðn (< OŸÁÜúÆA·| jÐÐHÕûÝoðP##œÈóðhš¡Œ¸43Z7QFZÝ´Ïi¿ã`ƒûœ¨44{\c(Ò.œ÷òlÐy¯3uã”Æ@Riuø@‡]Ãy4ÍP F\šÙïxÀa°ÁýŽÔTZƒ½Îƒ1©Î8šËù¶˜xœchÀjZ°‰,`ù3Ð. \h"V¥Mj}K}ã ƒÏèR9ph |íx¨‘ã¯åÛÑ4C 0²ÒÌhÝD0¢ê¦†}NûÜçDݰ¡=Œ¡H³p–Táÿ8Ø`Y—3•£”ÖÀgÀÃŒ¸ß‘ú±J[°ßq ÃŒ[HÖ"eÿ¥¾qÁ-h8´Ïÿ§xÈ‘Ÿ¸K²OGÓ µÀÈI3£uÕÀˆ©›ö9íwlpŸõÆö`0†$MÂZR…ÿã`ƒÎ{i¥´ÏÂ<äH‡e]¤‡õhš¡9i¦a¿ã‡Á÷;R?JicHR!¬›³Ñù»³xœchÀ:W0Űühr¦ ´ H5-HÔ"•¤¾qÁç ti:4¾õù<ìH…~ë럓èÓÑ4C-0rÒÌhÝDE0Bꦆ}NûÜçDƒÀ¡9Øã2Ã’pXïq!Ñ£’*ü,ër¦I¤Òø¼ð#ÞQ¹£äJ¢OGÓ µÀÈI3 û8 6¸ß‘‘Jk°×y0†%á°Þ‹?‡0žÍù¼xœchÀ>[0Å,Hhdž ´ è6XUß8Èà LÅD©ø+vôïÑ4C=0RÒÌhÝDE0Bꦆ}NûÜç4СBŒaIƒÐÞÜÅÿq°Aç½Î4‰RZI•9²àý9šf¨FJšiØïxÀa°ÁýŽ´ˆRÚƒÁ–‡6GúÏù½¡xœchÀ9S0Å'½éó‘ÐÁ²NšD)­¤²À€‡épe8©9t4ÍPŒ”4Ó°ßñ€Ã`ƒ$—–ƒ ư$ ÷;âõQIËù¾žxœch gÊ@»€|0Ýnq‚$å¾õƒæ¡QàÐC3â@‡Éðùƒ·¤úrðÁÑ4CWHjš”`(–ï00ÝNbÝÔ°×y¿ã`ƒûœh6´{\ö9 tèÑ<¼}Þ ~ätЙFQJkàóNhÀÃŽtXÖEZx¦j‚‘‘fö9plp¿#m¢”öTÓtèQ=¼ŠÑù¿›xœch@ÐE˜œhdž ´ HHR.U¿¥¾qÁ-h8´RñW<üHoËÑ4C]0ÒÌhÝDe0ꦆ½ÎûÜçD›°¡Øç4СGóð–TøÈ?È ó^gE(í¤Ê@‡íÃ{4ÍPŒ„4,K8 6¸ß‘6J°ßq Cêá æ)ËùÀxœch@ ÐEpüh:*Úä‡$)÷­odÐÏ^6!C µ¿dÀÃŒ¯N’/GÓ 5ÁˆH3£uuÁH¨›ö9íwlpŸ‚†`0†'a¸×™?îåÿ8Øà’|0¨€¤²À€‡!®ìBŠ'GÓ UÁˆH3û8 6¸ß‘VQJ{0Ó0ÄÛsËùÁ xœch@ÐE¬ˆhPRæ ´ H HP¼¹Aª¾qAiù*š­o½ôùé‚$‡¸} ~M3Ô#!ÍŒÖMTþnjØç´ßq°Á}N´ Úƒ=.ƒ1D©â›»ø?6¸2Ü™fQJkàónMø@‡­C|4ÍPŒ„4Ó°ßñ€Ã`ƒûi¥´{cˆRâA°ËùÂxœí•±€ CÙ@kmEÀtp{[ÁQ¬¤Õ ì)„_€áÎ¼Ž£È˜öT_þÊ÷Bô¯Ýwa³SNÍ`´ªI•M!&be¬ð ÿÎä†ÖÈ—ÑS¼JtOú›´–£±ÉDÑdb¢!Œ xNÕÆ2É4½ !I·q¿3¹¡uF[¾÷h^J8!&Âò—¢µÏùÛxœch@ÐE”ô ´ (Ú¤ƒˆ$(öµ?Xß8¨às½4 º‡ÞC’aü<8šf¨†}𭛍†}ÝÔ°Ïi¿ãà‚ûœh2ô{:iæ>ù,ër¦YtÒìð0$’æ£i†ê`ا™†ýŽÜïH«Ø¤Øç4Ð!Hå0€ÏùÄœxœch@!kÐE¸ìhP Ræ ´ H ˆV*Õ¿¤¾qpAÿ'´ º€çç§t’ ·à¿Ñ4C}0ÜÓÌhÝD0Ì릆}NûÜçD³€¡|aJîu&Ú{’*ü$Þõƒ< è$#Ì÷¸í¿Ñ4C}0ÜÓLÃ~ǃ îw¤]tÒ ¾0% ñ´ CÏùÅ•xœch@ÐE|hP †¢$¯Ö¡·¾qPAéz)š }ÀóúçФÂ-¤xp4ÍP û43Z7Q ER7ísÚï8¸à>'š Àà Sê†ú^þƒ ® w¦]lÒ< è0$:ï%!ÔGÓ ÕÁ°O3û8 .¸ß‘vÑI0øÂ”¢PŽ”ÏùÆ–xœchôà„Å@»€RP0a ]@:àøA¤BßúÆA·,H eØÐ8ôx(’ ýìÕ‰ôÜhš¡ ÖifP‚Ѻi ÑuSÃ^çýŽƒ îs¢eØÐ ÆP¥Z¨û¼üÈ?È ó^gšF(ÀERábC}4ÍÐ ë4Ó°Ïé€Ã`ƒûiŸôƒ1T)uŸjÍùÇ xœch@Œn"¤Ìh ˆu©ú-õƒ úÕ?§eØÐšfh†sš”õÀ`t©`×M {÷;6¸×™†AC'°Ïi C‘T¸Ï‰H¯I* |ädðŽ² M£“àYø@‡"É¡®BlNM3´Ã9ÍËЃ ]Jb°ßq C‘T¸ß§gõÏùÈ¥xœch@ ¨ia`h7P> ´ H%=D+õ­oTÐo}Ë }Àóúç’¤Áç]õ[ˆôÝhš¡Öif´n¢ ÎuÓ>§ýŽƒ îsÚãB˰¡|áJ½pßËÿqpÁ;*üï]iŸtÏÂ:I…e]üï܈óÜhš¡ Öif¿ã‡Á÷;îu¦m„Ò ¾p¥ Ü…Ïùɤxœch@Ø0Ð. (˜0Ð. 8 JÙæ©úÆA¥÷ߢmÈÐ8ôxH’ ýêŸåµÑ4C#0ŒÓÌhÝD#0Œë¦†}NûÜçDÓ€¡Øë<ÐáH:ÜëL”×6wñ\pe8q.ä`À€‡$©ð޲ Q^M34Ã8Í4ìw<à0¸à~GÚÆ&}À>§GÒ!ÎVîÏùÊ•xœch@<_P¹3Ð. H™3Ð. ÜÐ N݃·õƒ >¿ð—¶!C'ðüüôKáýâ¼6šfh†qš­›h†oÝ´Ïi¿ãà‚ûœh2ôƒ/d©ò{ù?.XÖåLÛ¸¤x>Ð!I:$2äGÓ À0N3û8 .¸ß‘¶‘I/0øB–ìÐüÕùË—xœch@:Wx 0Ð. ø0Ð. ¨Ü!J™Tþ‘úÆAŸ7øÒ8hèž×?ð°$1ä/ü%Êg£i†V`ø¦™Ñº‰f`ØÖM ûœö;.¸Ï‰¶!C/0øB–J!/©ÂÿqpÁ².gG&}À³ðIZ…ühš¡¾i¦a¿ã‡Á÷;Ò62é_È’òmîÑù̘xœch@;è¨hPLh "V§Nam}ã ‚~û—Ó6dèz<,I„ñWˆóÙhš¡¾if´n¢¾uÓ>§ýŽƒ îs¢mÈÐ ìuè¤UÈïåÿ8¸àeÚÆ%½ÀKR¡3q>M3´Ã7Íìw<à0¸à~GÚÆ%½À>§Iª…<ÏÏùÍŽxœch@3X0Ð. ˆY2Ð.  š?¥¾qPÁ-$Ôs<4iú£i††`˜¦™Ñº‰†`˜ÖM ûœö;.¸×y Ã„Z`ð…-UÂ^R…ÿãà‚Î{\h™t{:,I†ï]‰ðÖhš¡!¦i¦a¿ã‡Á÷9Ñ:.é_Ø’ö)^ÍùΜxœchÔ eÎ@»€z€åÏ@»€T0#ƒ ßúÆA¥ÏŸ¢CÐÐl^ðkÀÓ4øÜ¡— ¯FÓ -ÁðL3ƒŒÖM ˆ¨›ö¸ìw\pŸíC†^`ŸÓ@‡& BßçÐGþAW†;Ó!2é6w th’ Ë:]új4ÍÐ Ï4Ó°×ù€Ãà‚ûi™ôû:4©úà¢ÑùϘxœch@093Ð. p80Ð. 00Tò¼þy}ã ‚[_*&HÕoðð$þ7!è«Ñ4CK0<ÓÌhÝDS0,릆½ÎûÜçDó€¡|¡K…Ð&ð‘PAç½ÎtˆLúIåÁºD„?A_¦Z‚á™fö9p\p¿#í#“^`ð….™¡ïÍùЕxœchÔ€ãÇ@»€š fÉ@»€4`q‚ ßúÆAýìÕé4ts§ýŽƒ îu¦GÈÐ ìuèð¤zø? çÿ8ÈàºD&}À³0OáÊ0Bá?šfh †cšiØïxÀapÁ}NôˆLz}NžT xÏùÓ—xœch@/(éhPlhvxP°ùÀ­úÆAŸ ì¥KÀÐ<ß¿|ÀC•¤HÈ%à£Ñ4Ck0üÒÌhÝDs0ìꦆ}NûÜçDp¡'l!Lq lîâÿ8˜`Y—3]"’~àYø@‡)µc`4ÍÐ ¿4Ó°ßñ€Ã`‚ûé‘ôƒ-„ÉŠhëÓùÔ–xœch@&gðÙ2Ð. 6x 0Ð. | ¨bo}ã ‚Ï?Ü¥G¸ÐlnðP%J×KòÒhš¡1†if´n¢5~uÓ>§ýŽƒ îs¢G¸Ð ¶¦<öòL°¬Ë™ñHG°¹k Ã”4¸2œ` Œ¦ƒa˜fö;pLp¿#="’ž`°…0Y1”ÏùÕxœch@x1Ð. 6x 0Ð. øl! àùþåõƒ>?ÀK—€¡ØÜ 5à¡JR |¸KÀG£i†Ö`ø¥™Ñº‰æ`ØÕM ûœö;&¸Ï‰áBO°×y Ã”Ê1ð,œÿã`‚e]Ît‰HúͪÔÑ4Ck0üÒLÃ~ǃ îw¤GDÒìsè0¥B ØÓùÖ¤xœch@9S¸¡1Ð. >°92Ð. TtPà›?±¾q0Áû!t z‚çë·t¨’¥ï·×oÁëŸÑ4C{0ÜÒÌhÝD0Ìꦆ}NûÜçDp¡/laL(ö¸àõŽÏGþAé‘ôÏÂ:LI+Ãùß¹áõÏhš¡=ni¦a¿ã‡Á÷;Ò'"é [н˜ùÖ8Ñù× xœch€††A & ´ ¨8 ´ HðHúþg¬oTp‹Ãz… Ý€Ô“WR ôþ[x|3šfè†Wš­›è†UÝÔ°Çe¿ãà‚{é2ôûœ:T©>ï?ò*è¼Ç…nQI/ ©2СJ\†/FÓ =ÀðJ3 {8 .¸Ï‰^QI?°ßq C•â8` ËùØ¢xœch€ £€æÀá@EÇ@»pCäóúçõƒ n¡[ÐÐ HÕûÝoðp%ÞÁã›Ñ4C0¼ÒÌhÝD0¬ê¦†½ÎûÜëL¯¡Øã²Ïi Ã•¸Ï gž… |ä\ð½+Ý¢’^@Riuø€‡+I_¾M3ôÃ+Í4ìs:à0¸ ÞrqˆP ` Ã•¸ßà }†ÏùÙ“xœch´ fÉ@»€6@ãÆ@»€ ð¤o}ã ‚[ .Ð+\è žÏ?>àaKB,00àñËhš¡NifÐѺi0¼uSÃ>§ýŽƒ îs¢S°Ð ¶p¦ |>|äDÐy¯3Ý¢‘žàYø@‡,õba4ÍÐ §4Ó°ßñ€Ã`‚ûéôƒ-œIŽoÏùÚ˜xœch€ƒ ƒ \hÐL(hBÖà‘”úoRß8˜ ýº =Áóÿé²$@¿þëxü2šfè†Sš­›è†QÝÔ°Ïi¿ã`‚ûœè.ôƒ-œ)ˆIþƒ :Ó-é ž… xÈï¨à‹…Ñ4C0œÒLÃ~ǃ îw¤W4Ò ¶p&9ãrÏùÛ¦xœch€ƒ ƒ 00 ´ hRæ ´ HpJ=g¯oLð¿ ýÂ…ŽÀ·^úüô[ _ýsœ~M3ôÃ)ÍŒÖMtænjØç´ßq0Á}Nt º‚=.ƒ-¤ñÃ=.8½ò,œÿãà‚ÎtŒHúŸwk]Hãƒw”\qúe4ÍÐ §4Ó°ßñ€Ã`‚ûé‘ô{[Hã‡{Ñó.¦ËÍùÜxœch€‘7 ƒ ,HhÐ pühP øÊ?¬oDpË@Í€”ý—]êÄÄhš¡>if´n¢6uSÃ>§ýŽƒ îsè¡l!Mv<ø|äTÐy¯3£‘ž@Re Ã–$øÁ§OFÓ ½ÀðI3 û8 &¸ß‘~ÑH_0ØBšÄxòÕÍùÝ¢xœch€ƒ ƒ |hÐ (<h^Hà”òµ?Xß8ˆ t½†®€á쀇.ñÐOÞ§GFÓ ÝÀ°I3£uÝÀ°©›ö9íwLp¯3ýÂ…¾`¯ó@‡-)pŸNø|äTpe˜ £‘®`À€‡.ñðŽ î¼;šfè†MšiØïxÀa0A§ýŽƒîs¢_¨Ð ®°&;&ž…óLЙŽQHw°w C—„xØ‹;&FÓ Á0I3 û8 ¸ß‘~1H0¸ÂšÄ˜£ÀÑùà–xœch¤@äÍ@»€–Àá@IÏ@» À·¾q0Ay‘©z)®aàþM3ôÃ%Í 20Z7 °ßq0Á}N´{\ö9 t÷:ãð†ÏGþAq¹s8I¥Š®_à{WþM3ôÃ%Í4pLp¿#=#‘Þ`¯ó~Çaâ!Z;ÐÕÉùá xœch€‚ ƒ \0hÐH¼h&`ÞÜ Uß8ˆ ´}†¾`ó[ÆDÇÅÿYØý0šfè †Cš­›è †AÝÔ°×y¿ã`‚ûœè.ôûœ:„)Ž‹Íù\îLçH¤/ØÜ5Ð!LB\„¹`÷Ãhš¡+iXVpLp¿#}#‘Þ`¿ã@‡0ÙqUóÏùâ xœch€‚„ ƒ lhÐ %ÿýàÀ*¼™aV}ã ‚ÒûoÑ9`è žï_>àaLt\Ä[aõÃhš¡/if´n¢3JþÃQ75ìuÞï8˜à^gú† ½Á` o|pŸV/lîøÈ?ˆàÊ0:G"}Á³°ÁÞxã"{þM3ôÃ!Í4ìs:à0˜ ŽòpØ€ÁÞøà~G§mNÏùã—xœch€‚ ƒ 00 ´ h |¶ ´ ˆpHøÖ7&øß„®ÁB°ùêcb¡ý~M3ôà ͌ÖMôC¿nÚç´ßq0Á=.ô úƒÁâ¸á>'ì>ØËÿqPÁ÷®ôAºƒÍ]ÆDCgì^M3tà Íìw<à0˜à^î>`°…8n¸ßÅáO¬Ïùä›xœch€‚  ƒ„¬hÐph Ræ`~n¯^ß8h _ÿu: ýÔ“gâ ôùSX}0šfè †~š­›è†|ÝÔ°Ïi¿ãàûœè*Wˆ“ÏÂù?xGÅ™ÎH ©2СL,\Ž=6FÓ ½ÁÐO3 û8 ¸ß‘¾8`p…8 ±Íùå®xœch€††A4n ´ hr¦ ´ˆ °úþg¬o4Pzþ/z‡ Ý0Äó'xH·àòÁ€» GÓÌà‚ØÓÌhÝDw0ä릆}NûÜçDç@°Çep…9>¸×‹|>ò"¸2›‡ðy/8àáL,tÞã‚Íî.d8šfÄžfö;pÍŒÖMôC½nÚç´ßqðÀ}Nô•ƒ+ÌI½ü¼£âLïø ©2ÐáL,,ëtÁæÑ4Cw0äÓÌ~ǃîw¤w\aNt|…Ëùç§xœch€‹ ƒL(hÐàaM´ÿ‚Íõ£ifÀÐN3£uÓ€€!]75ìsÚï8xà^gz‡ÊÀ€Áê¸á>',ŽÎÿqð@ç=.t¾ƒ+ÔñÆÈ wýhšlk¹¿ßñ€ÃàXËÂaW¨ã†û‘ OzÓùé¢xœch€‚Œ ƒ &·Ð8hRæ`”š?¥¾q@¿ùÇé(¤ê· xh¥ÏŸÂæúÑ43`h§™AU &·Ð 麩aŸÓ~ÇÁ÷9Ñ;L ìuè°¦ F$Uø?xGÅ™î‘70@RY`ÀC›¸2[ŒŒ¦™C;Í4ìw<à0Xà~GzGÞ@}NÖdÄ@Ëùê—xœch„ÀäÌ@»€~ÀáÀ@»€8° CÈ·¾qÐÀ-è&¤ê· xx'XÜ>šf å43¨ÀhÝ4ø–º©a¿ãàûœè$ö9 th÷:c8Ýç#ÿ ÎXÜ7\¤Ê@‡6‘q²ÇÃí£if`ÀPN3 ÜïHÿÈ(°ßq C›8ˆÔ^[Íùë—xœch††AXþ ´ F:˜‘&àûŸ±¾qÐÀç t$Xøxh'½è.M3†nš­›F€Q75ìuÞï8xà>§•ûœ:´ÉŒŸù ,ërè0¸BOœtº j—¦™Á1Ó °„<à0xà~Lj¾û:´IŽ#Íùìœxœchƒ„ ƒ¬ˆhÐølh~p  lf˜Uß8h ´|Õ€ËÀ€ÍV xˆ'ñVèîM3†jš­› Ѻ©a¯ó~ÇÁ÷9 D¨ Øç4ÐáMVœlîøÈ?hàÊp牼›»:¼É‹“Ñ43p`¨¦`ùxÀaðÀýŽyö;tx“'ç:Íùí–xœchƒ ƒ|hÐ ®°Ç .`ùÖ7(]/52p`0…=NhÿeP»{4Í Bˆ™fWù8Z7 >€Y7ísÚï8xà^畃+ìqÁ}NèîÞËÿqðÀ•a.wUØã†ùxP¹{4Í Fˆ‘fö;p<³Î`p…=.¸ßî`˜3Íùîœxœchƒ  ƒLhÐlh)sО۫×7¸ÅáÀ@„É‚çû—x¨‚ÒçO¡»z4Í šif´nP0$릆}Nû Üç4a2`0…>ѱò,œÿã`Î{$â ¦ÐÇW†£ÇÊ`rõhšŒ3Í4ìw<à0Xà~Lj¸ƒ)ô‰ˆ³VÑùïœxœch††A ´ F6° …ëûŸ±¾q@¿úç&|<̉[Ð]=šf Í43Z7‚­njØç´ßq°À}N$Sèã†{Qíó‘ÐÀ;*Î8‚v¸Ÿê„¡óTW¸‹p4Í Nˆžfö;p,p¿ãÀDÝÀÁú¸!¼Í}›Íùðšxœch™' ƒ|hÐ8h32P¸RñWê ”®— @8 U¿eÀÃ|îЋêæÑ43 `(¦™Ñºi€Á¬›ö9íw,pŸÓÀ„É@‚ÁþDÆ‹¤ ÿÇÁW†;PÄ Lá –uº Z7¦™Á ÑÓLÃ~ǃîw˜ˆH0˜ÂŸ`¼£òÉùñœxœch“3 ƒìðhÐ8h?8Pù{ë |ž;0a2€@ª~Ë€‡;!(o…êèÑ43 `H¦™Ñºi`ÁP¬›ö9íw,pŸÓÀ„É@‚½Îê¤ÇË^þƒ–u9L¼ Tðp'W†£ÅËhšP0$ÓÌ~ǃîw˜ˆH°Ïi C„xÎÊËùò”xœchŸ- ƒ\h Px0Ð. Ðâeó‡UõƒÚ @PÀpv ÃÄxM3†\š­› ¹º©aŸÓ~ÇÁ÷:L˜ ,L1€îsBqðæ.þƒ~p hP°wÀà DÍË£ifÀÁK3 û8 ˆVŽ0˜b;Üïu*§ÀÑùó¦xœchƒ„ ƒ”ô ´ p(˜0ÐnÀb– p73̪oð¹ÀÞ ’RÿÓz<ôñÁ-P\<šf ½43Z7 8ruSÃ>§ýŽƒîs˜h°×yðÄQ1³¹‹ÿãà€e]Îi $•]ötØã‡Î{Qcf4Í 4zi¦a¿ã‡Á÷;L¤ 4ÕLöDÆ #“ÍùôxœchdÀeÏ@»` À vIÀ·¾q°@ÿ'|ï+tØ„[Ý;à®ÃÑ43ˆáÂÞ0Z7 °ßq°À}Nö9 tØ‚{‘œëó‘Ð@gœ:¼Á`Šð½ë uïhš´%Í4p,p¿ã@EÚ@ƒýŽö„ ´ÝÛÏùõžxœch‚ ƒ|h ðØ1Ð.À:*àL©ÿ&õƒJ×K `  0PX;àáúí_wêhš$`¥™Ñºi€!T75ìuÞï8Xà>§ “ûœ:ô‰ŽIeüƒ® wÀH`°w C?¼£ìwêhš$`¥`™xÀa°ÀýŽg ö;tè7–fËùö¦xœch‡ ƒìðh PxPÒ3ÐnÀ^HÀ™Rõ[ê |ž;€2À€ÁX kÀc7ô“w‡;u4Í 0„ÒÌhÝ4HÀª›ö:ïw,pŸÓÀ…É@ƒ½Îûœ:ü‰ŒIeüƒ–u9`¤ 0ØSÞ5ÐáÞQAÄÍhš$`¥™†}N Üï8pq6ÐT3 tø7GTÉù÷žxœch‚ŽŠ†A . ´ \0hà:WàL©ý%õƒÚÀ@hðÜ^} ÃôËÿwéhš,`褙ѺiЀ!S75ìsÚï8Xà^ç “ƒ)&0á>'¸C%•>òøÁe£l Á³ð<ðŽ "?¦™Á†NšiØïxÀa°@¤òo‚Á˜p¿#Ø‘ÙÍùøœxœch‚ ƒ”ô ´ hÜhà1KàL©ÿ&õƒ>Ø;€A2ÀóùÇ<pÁ-àîM3ƒ •43Z7 "0Dꦆ}NûÜç4p!28Àà‰ ¼±#©ÂÿqpÀ².献Áž…tà†Î{±3šf*i¦a¿ã‡Á÷;\t 0xâgìŸÏùù xœch‚ ƒ¸ìh 4p8°a Ý@xÏ^ß88 ÿ“ŒRõ~û—t,à[ îM3ƒ •43Z7 "0Dꦆ}NûÜç4Ða1Ð`Ëà‰ L¸×êÌgáü tÆ ÃH*­D±ß»BÝ9šf*i¦a¿ã‡Á÷;d„ °×yðÄ&·1·Íùú¦xœch‘7 ƒ|h ÍŒÖMƒ úº©aŸÓ~ÇÁ÷:dˆ °×yðÄ 2Üçu ¤ ÿÇÁW†¹ hT °gUø@Ç6xG–§GÓÌ ƒ>Í4ìw<à08 ¼ìáT3 t\`ƒûޝËùý¢xœch‚„ ƒLh pÀÁgË@»Ä,263̪op‹Ã A¤þÏú°jÀc#† .@Ý7šfìif´n„`×M ûœö;¸Ïi Ãcp½Îƒ%V°ÆÐæ.þƒ:ïuÐhL@R¹|Ä öM3ƒ ö4Ó°ßñ€Ã`€û2šÕL8b´%Ïùþ§xœch‚ŠŽ†ALÎ ´ ``x1ÐnÀ ÀÔóûíõƒnø0°á1¨€ïÿô·§Žlq´Gà#ÿ ÎGƒ < èA‡e. ‡¦™A mšÙçtÀapÀýŽIƒ €jƒŽŒ8õÍù£xœchh0¸Ð0HÀŒŒvÁàt® ´ðµ?Xß8(às‡Þ‘A¤þ3æð˜A‚ÿMFÓÌàƒ3ÍŒÖMƒ ʺ©a¯ó~ÇÁ÷9 p€ B°×yŸÓ@Ç Fù|øÈ?(`Y§Ë@ÇР’ÊwU:^P¡sÃhšÜ`p¦™†}NÜï8ÐQ4ø¨fèxA‹#ÌËùšxœchh˜PÐ0 5X°` Ý&g€Äóÿéõƒnè¤`3ìh |hM3C ¶43Z7 z0èꦆ}NûÜë<Ð!28Á>§ÁGûœ€z&ð‘pÀ÷®;ƒì-ëð¸Bgp¾M3ƒ º4Ó°ßñ€Ãà€àro`P0Ðqƒû¹˜Ñù¦xœchh8aÑ0(@ÄŠvÁà @PÑ1Ю‚ rn}ã`€ñW:<-ðýÏøöýöŽ! Üâpä Ñ43èÁ K3£uÓàƒ­nÚç´ßq0À}NƒìqÙç48â K{ù?è<Ð13hÏ{Á+Ã:~Àq´K£ifЃA—fö;p p¿ã@GÍà{AõÂ@Ç4–Â&Íù£xœí•» ƒ@DÏÛ.ä>„¶Û  $ÆU¸ ÒûB@æ˜ À±ã“îM£'­”õ*Ý€›¤ëµ¥[:á¹_†7AfwI¹íúL£øN¯á[œÉ&gÊoʢ߄`£aH°Ò×àÆ»`¶ò­¢ˆûu)üçÚ´~¹K¯TmKÓg2ÉD“4C¢‘ž…›ó/I¯”t8<Ê7ŸxœchhPxÐ0(ÀƒvÁàÔ´ ¬(440œ­oPÚ>j`Ãb€çõR ³Ö· h<=oðM3C š43Z7 0Xê¦}NûÜç4°a1À^ç}N_ xÚËÿq0À•áÎ#ƒ< sÙ{Ge`㩬Ëy4Í !0hÒÌ~ǃîwè(üR/ p<ŽÎ8ŸxœchhpÙÓ0(€Á…vÁÐÔ´ œý7|ý7Ö7hÿeàÂaçõR ³Ö· XD¬ —m>ûë|Îp–^~v@êúÞø…ôŠ©«FÓÌôN3wG릡è\7mÙç´ßq0À½Îôòóð{÷9Ñ/÷ñ}ä°¬Óe C~ÈIe—½tŒ©®N+£i†r@ï4ã¼ßñ€Ã`€ûœ:è‡.€ÔKôŠ©ýâÖÐ8 ¤xœc8àÐ0@IÏ@»`胀 RæÐÞž¾ÿ&õŸ tÕo¡½o‡5x¾ß±¾ñütšÇÕ–»FÓÌ0ôK3 £uÓpt«›¾ìsÚï8ðpŸÓÚûvxƒ½Îûœè›ûn«ðxXÖÅÿÎm Ã|ˆƒga«ÂW†Ó>®œ÷ÞM3ÃÐ/Í8ïw<à0ðp¿ã^çô¡ õâ fÛÓ8 «xœc˜‘Ñ0€Å‰vÁp2ORæÐÎüše‡¨úƇϼ¥/Gð­÷ÛïŸw~:ÍbÊo½\½ïhšF€>iFj´n^€uÓ‡}Nûîs¢/GØã²Ï iS{Ë:>ò8,ërèÐÀçÝ}å»*+ÃiSwTV†•¦™aè“f\ö;px¸ßq ƒ{x€½Î„–1µ Ï7 —xœc0¸Ð0ÀvÁðXþD¬ …É<_|íÖ78ÜrÀþ¹Àáó‚_ñ iSFÓÌð4M3 £uÓp4­›ö:ïwx¸Ï‰þ¹`¯ó>§}N4Š)Ÿù:ïuèP^`Oyíbj4Í K@Ó4Ó°Ïé€ÃÀÃýŽÊà @ê%ÅúÑù ¼xœchh(éip°` ]0Ã+¨g¢Î á[ÿ\ «¾q€ás†³Ôó×(€ßÿ³í¿äwè¥Z<ùå©ß2šf†1 Uši­›†/ QÝÔ°ÇeŸÓ~dž{©ç¯Q{÷9 õâiŸÓ—Ÿw•]ü–uº tøCàóaUøç½Ô‹§;*üïÜFÓÌ0´J3Àòk¿ã‡†ûœ:€‡#€ÕJÔ‹'p+ÜÏù¸xœchh09Ó0À ¤g ]0¼A‚ &PfJEÇ[`o}ã€Âç]õ[( —Q€lf8{€×þ‹C/E±$}_1žO£if˜¤™Ñºi¸ê×Mûœö;,Üç´Ç…Òp¸Á^ç}N Hi,!âi/ÿÇ…e]üïÜ6T‡5ØÜéŒcg ãyeøÊpx<¦™ahfö;pX¸ßq¯óÀëð°Z‰ÒX‚ÆØÙÍùÂxœchhØáÑ0ÀÀàÂ@»`d…DÞøl)é!UgE‡Ä pîæ«úÆ…ö_¨4£`˜õßDÞýƒ€@‰1$}ÿí’z)¸A£ifĪ¥™ÑºiĪÕM ûœö;,ÜçD͸À^ç}NHz ísÚë 7hsÿdžÎx<: ¨öÜUáÿXÖUFrŒ¯ /ëZæ7h4ÍŒ@µ4Ó°ßñ€ÃÀÂýŽŽ# ê$Òc©h®ÍùÞxœchh``È™Ò0 à†ÆÀÚ?ò€ÂƒTîxìȘO]MKȉ ûþgÌŸXß8ð~-Ãg`†tùªÅþ*TÍŸ‚'füÖös¸µŸ¯þ9ŠöÑ43…if´n€Âº©aË>§ýŽ ÷9Ñ0xF°×yŸ âÜã‚¢Ýç½àGþ†Ît#ìYî¼·¬Ëyï|ñrGåŽJYVrEÑ>šfF  0ÍË©ýŽîw˜¹¹FÂ3¸9W‹ÍùÛxœch††Öþ‘ &ÌÈ8àpÀ NXpè¨Px€S‹ïÆúÆ„ÒõRô ŸQ€|ëÿ›8|vPÿÏøßˆAÐdÁ¯ÿŒû—3œ­ß‚K×hšÁ€¼43Z7p@FÝÔ°Ïi¿ã@½Ît žQ€ö¸ìuÞë¼Ï îuÞã‚C“ÏGþ…+Ãp¹lÐø¼úಧ¼ó®ÊXŒ8ï½£rGÙeÀ;7\ºFÓÌ䥙†ýŽ ºlàà>'zÒ(@z [›T;aÑÙFÃùuxœch†”9 b– œÝ£€Làûöùéõ·\è$ƒÑ43 H£uÓ( ìqÙç´ßq à>§öÿ( ø¼_Îÿq  ó^ç€Q@2M3£€d°×y¿ã‡‚ûÚÿ£€$'‹Ïùfxœchƒ DÞ œÝ£€lð\Þ½¾q  ¼È@{FÓÌ( ŒÖM£€T°Ïi¿ã@Á}NíûQ@xÎÿqà ó@{FÓÌ( ìw<à0Pp¿ã@û~‹pÍùjxœch€ :*ÊæQ@x>ÿx}ã€@¿ýËÚó£€,0šfFÉ`´n¤‚}Nûîsh¿²À³pþï(» ´çGY`4ÍŒ’Á~Ç÷;´ßGI½éÑù}xœch€‡+”ô00 „½£€b U¿%~a}#Ýás®ÿ&íùQ@M3£€d0Z7RÁ—}Nûé÷9íqh¿²€¤’àGþ€e]üï]Úó£€,0šfFÉ`¯ó~Çô‡û÷:´ßGI–ŽËùpxœch€…èTîÐßÎQ@-ÀÀàÐ[ßHgøüÂßö÷( Œ¦™Q@*­›F©`¯ó>§ýŽô†ûœÚߣ€|°Çe/ÿGzò.çö÷( Œ¦™Q@*ÕLè ÷;´¿G‰>~Ïùnxœch@Jzè $ÐÛÆQ@MàðY «¾‘®pË@ûyPFÓÌ( ŒÖM£€T°×yŸÓ~GúÂ}NíëQ@ ØSÞÅÿ‘¾Ðy¯ó@ûzPFÓÌ( €j¦ô…ûÚ×£€D+êÏù{xœch@è"´%= ô´oPøÖKßo¯o¤|.Ðõßd == (£ifFë¦Q@Øç´Ïi¿#ýà>§=.íçQ@ðù°*œÿ#ý`Yÿ{×öô( Œ¦™Q@2Õè÷;îuh?ˆ»Íùqxœch@JzÐÅhTîÐÏ®Q@+àðY «¾‘Nðù…¿íßQ@9M3£€T0Z7RÁ^ç}Nûé÷9 ´Gå`OyÿGzÁ².çöï( Œ¦™Q@*ÕLè÷;´GÉÓÑùtxœchÀ 2f`ŠÒL( —M£€†`3Cúü)õtÒÿg ´wGÀhš$ƒÑºi ö:ïsÚïH¸Ïi }; ¨6wÞUáÿH¸2Ìe ½; ¨FÓÌ( €j¦ôûÚ·£€d,"Ïù}xœchÀ6`§6H™C[F€ïÿÙû—×7ÒJŸŸ^¿e =; ¨FÓÌ( ŒÖM£€T°×yŸÓ~GÚÃ}N{\Ú¯£€*Àçêpþ´‡+Ãùß¹ ´gGUÀhš$PÍtÀöp¿ã^çöë( )SÏùrxœchÀ (<À.CMÀÀ@{;F€Týs†³õ´†ÿMÚ££€j`4ÍŒ’ÁhÝ4 H{\ö9íw¤5Üç4ÐþT’J®{ù?Ò:´GGÕÀhš$ƒ½Îû8ÐîwhŽ2§Ëù|xœchÀ vx”ôà–¥Ttp ¥ù£€î`s®úFšAéû!ÿÓÚ“£€ª`4ÍŒ’ÁhÝ4 Hûœö9íw¤Üç´×y ý8 ¨ 6w•uñ¤\~GÙe =9 ¨ FÓÌ( €ê´ƒ Úi ý8 È13ÏùtxœchÀà“§ (< Ù£`€€ïÿsõ[êi·00 ´GÕÁhš$ƒÑºi ö:ïsÚïH+¸Ïi ý7 ¨|>ÜUáÿH+è¼×y =8 ¨FÓÌ( €j¦´‚ûÚ£€,}-Íùzxœch 8äL!¤†PÓ"ð掂RÿMò'Ö7Rú­—«—hÏš€Ñ43 H£uÓ( ìsÚç´ß‘úpŸÓ^çöÛ(  TáÿH xGee˜Ë@{nÐŒ¦™Q@2Õ#¨AµÓ@ûm»$Ëù wxœch H¼¨i!F)@ä µMƒøÖ??°|}K}#u¡¼È@{lÐ Œ¦™Q@­›Fi`¯ó>§}Nû© ÷9 ´¿FÍ€ÏûŠ®;*ü© Úc£€f`4ÍŒ’¤^:à@]¸ßq ý5 ÈÕ£Ïù!xxœch (<0¸@œJâ@Êjš6 #`8k°¾‘jPúüôú-í§Q@[0šfF©`´n¤‚½Îûœö;RîsÚë<Ð~´{>òS® çï:Ð~´£if @5ÓêAPí4Ð~d*ÍÏù"|xœch 80¸@¼j| ¦¥£‚:&‚A ¤ê·Ø¬o¤ô[¸ù@{gÐŒ¦™Q@2­›F©`¯ó>§ýŽÔ€ûœö9 ´oF€¤²ÀG~ªÀ;*w”]Ú;£€`4ÍŒ’¨f:à@ ªŸÚ7£€l~;Íù#yxœch ((éYA®ÞQ0Doýó†çýKêÉ‚ÏTä«Ú £€Î`4ÍŒ2ÀhÝ4 H{÷9ísÚïHéhŒ:Ÿ÷]wTø?’˺V†;´FÁhš$H½tÀ<Ò;Ð>®ôÏù%ƒxœch 8àù’°€T]6G>kã(â@ªþùƒ`†Yõ$AéõõRíôQ0@`4ÍŒ’ÁhÝ4 H{÷9ísÚïHÜç´×y ]> H*»ì-ëâÿH\¾2Ìe > Œ¦™Q@2€ÔKHƒ Úi ]> (Ù÷Ëù&†xœch 8øÁáp ¢ƒµ':*(³m  Uï¥Þï~{}#AøüAûþåíàQ0à`4ÍŒ’ÁhÝ4 H{÷9à~G¤n Ý; H*¯ ¿£²2œÿ#aXÖuGÙe < Œ¦™Q@2€ÕJCºvï( zæÏù'¤xœch ``(˜ð@AáÏ–‚ ˜²1K4n\0x @ ›FÁ0¾ÿM>7ø2¸ëÐ[߈·˜ÏO´ïmðhgŽ‚AFÓÌ( ŒÖM£€T°Çe¯ó>'Üïˆ!â{Ú•£`Ÿ÷®{Ê»œ÷–1ÿGtè¼weøÊð²N—væ(D`4ÍŒ’¨f‚ÕDÐ!¬†hWŽ*GœËù(rxœch :ø€`3õmà øÖK×?¯o„ÁÿŒÿMÚI£`ƒÑ43 È£uÓ( ìuÞë¼Ï ÷:ïqh‚A|Þ¯ø€ß»´“FÁ £if @5Ò~GÕNí¢Q@ek¤Ëùopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-composite/run.py0000755000175000017500000000060412271062644023370 0ustar mfvmfv#!/usr/bin/env python # Test for oiiotool application of the Porter/Duff compositing operations # # test over command += (oiio_app("oiiotool") + " a.exr --over b.exr -o a_over_b.exr >> out.txt ;\n") # FIXME: no test for zover # future: test in, out, etc., the other Porter/Duff operations # Outputs to check against references outputs = [ "a_over_b.exr", "out.txt" ] openimageio-1.3.12~dfsg0.orig/testsuite/texture-fat/0000755000175000017500000000000012271062644020622 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-fat/ref/0000755000175000017500000000000012271062644021376 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-fat/ref/out.exr0000644000175000017500000052671712271062644022747 0ustar mfvmfvv/1capDatestring2012:08:17 11:27:14channelschlistIABGRcompressioncompressiondataWindowbox2iÿÿdisplayWindowbox2iÿÿlineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?qË‘'¼;XREj*ƒM¹rÔ{î˜W!6:éQ]hí|r’Ŧ»»Ï\ãí÷ {’2[DÜVpg?yìŠ^œRxœíw\W»Çs}c‹åš«ÁÄ€1Æ7ÄXb/X(l¡‰‚(HvÙ2åœÙ¾,,E©*Å "±ÆMìæõ_c××òÚM¸3Ã.ì.eî¹ìœŸº{ÎÌyff?_Ï™yžSæ-ˆ„ÄJÜçj¾dÈ”û÷Ò­iwlÝú¤Yo—è妽à¿äýûüþà? _QM;üÝ¡9Ý”ÚAmRO]]µ®d8hWÿå’ðÎßsjQTùuE¡åN/±n§Mù¾/æ[ä–/0§Ò÷zåN‰ ÓåÜ/ ^Í|¼|±Ï'Ï6æöoÑ£×ü_‡…•D*VRbT¢M ž Z´øê¡Ú©ÄñGüùˉßz‡¶Ã ·_’húthŒÛ]õM-$Ïî\1ë½Qþäü ·Et’׫ âhÃfbðu®ŽH£¿~Te‰§Ücà¶ÛSkíÄm\—®÷j!Ç?Šmu7 ƒLæNwæãä×Ðß…·\ϬrV;oûˆ£cò7&&‰!\ƒ 6Wf/&Ɉ¢œ1ƒ?=D;Q €ø#þˆ?ù#!5J’â?Žøe-nÓf“Ý¢d¿/B=K%“Ô‚ìêøÙëÏ\\·Î»—[¿¡ûT_é=‹~>+}TÖcá¾+9#KjŸ"­üŠ6ÏjÒ7?4%²úåùgÝ»û™¬§ø>„§'FÁ™ß/yò|oøý>©+U_]üä¶Ü>K T‘1iÅ“ Àâ$‰ì_½¥¥3‡\wʵW>ƒ€ˆ?âøó—?ß6„šQÐ×Ý`l¨ÔtQÒù=–ÏýþÎYW!.hRð!íËy j 1ª’4áÁ£¸Ãõ™Üá2å̆M»Þ¶Ùž¾°T\1º:ùÅYSbÀ V|Gí[wo%$ŸµƒPø¦#œ[‹s†o–ûÞø.d™<2lgtØ¡ÙiÂjKLÏÀ% uõ*±¿ltûqÀ3-ÄñGüùˉïVªß{ºí’˽ë*QVžPyüá×[§»êÚ?ã´[ñàño¾®DŒïŽûulèì±ËÁüJwøþºÃj»wà«üÞ 5éM3M‰) Î0-ÅG=£‡Äv»r 6•Ù”À\ãÐSŒþà-ìÔµqûFoJdÅÒÞ»§k“(ó5ª4(ËCòÅ:¡l•_ŽjÙ´¾½~Tð¸@üÄŸ¿ü‘x.âß2²`Ç¢³µv‰^¾ùhëq·eK ¾«×t멸:ÍuÖnëí=&-óü<¢áÈâÒT¹?ôõ MýøÓ[Z¸ Ó²*7|DëšÌãö¦Äø½\ˆP×ûÜLcÇ™}ö3¾AÀK8Qxîø2ïc†,êp+'i¡^Ÿå_—â¯Ñb`u¸‚NW ÕÞ›¢[¿6Hú­Î­øû»Å<ž „ø#þˆ?ù#9‹flnš0åæäÞŠË?ÜYm±ÿl´4éc·®ßÿÃÎa¬d¿ H7¥KEzõ&2@ z8?RÓ ]¨ËôÜÎl¢½Â=òáî3æ¿o0‹1ŸfÚ¶ªïõ/âzÑÓ‹†"!|çvõÈ÷ñØë¿ó,V¢‹¢g•{géò1­¤ò.1Ü ¹ÝA¢–c7T¿tí]ip‚n@ÄñoŠçàÄoýÖR™Ú4Ë ®ÃÜðke½bªfózM÷ý%Sý…/Xáˆ}Ô°‡»"ÖçzŒQrÙ0ÏÉ¿‚Uöfû+]LI?úŸðÔ‘‰F%­ˣɢ„(C!,QðÞ™íÙ£çEU³oÄ¿i–ˆ¿3ðGâ·F-®ÜåRïŠ «_Δ9T’GYk*ìà…¡Ÿ½få™ó´Ãö7\Í?çð÷¿AøãNn¼w牃… Nú×dcí{µzÅ•k!ŒÕÛúûÇXd0§Z½¨úN=ô9^xþMQÇs;·ö…ðR—t¨¢$ozÏ|.ûÁ#áØ bçÔƒ¿ìKj4„ܹR¥ƒ1ÉPK‰—•4­ÓŠ];»tÙA5óñGüþòGâ·Ž>>“1v깦ãÿè›v{¨O¹‹ë?'O/tï×HW´øðèÒ£ôÝ7Š+×½½Ö^ñöé!o¬™äRPä>¼ÍÉv•À¦lA›Ÿ,rGÚëµçæs䄨©ú];áW-| 0 /(ÊS±®û®Ì-F_]ØéAç&è“!PÓ*9¤Cuª8%$Ô>Œ´ Kx{ãõǯ2šwñGüþòGâ·Æß›v»ÝààËv+_’u;²ò“ c»LJKÝíè"–’ä­ÊVeëŽur«g2PFIÞ[_kë Ÿ÷=?ÿÖËfó\]¶E.wÔ:s29Þ”ðÚÅ~¶¾x=ë3¯çÅm4pûçk B•-[o«h_v4sè6¹ÿvŸC3kÂUJ•I"qÐVD M22çÆ¦.,(Û¡Û5MsnÄñç/$žËã–«¿WðO"’iHz¥ìñûrnÔœò“S·,zwšÝ \§î¸þºâÈòŒŸ~l'nøã¶mGêZD&:MŠ‚¼ŽYm]˜mé(LØ[<6Ä”8^µ´¨ÛYŸ®×½:ôï×iüùH?ÙëñŸzÅ÷¥¤xßçå ÁÆ5îW½å> ZMÉUn\¨L¢„Û# ¥ê¼§h[ûûšó\ ÄñGüùˉç"ß‘ÌÊ‘ÿs^+Ç{î@ȉߟ÷n1ßsÎpYç]Ù7»®xÜh@ÜSæzyæéì#»7gg5ôV0ןÏí¬¬gßÄ×+nº̳X <$tŸe‰ß»T'ƒÌŽŽºªÊvùúeµky^v!yΩ"¸¹íQ¸?dÞ¿§g¼TJå;1’:0M¥š½Z˜,/“Õ‘ZÑR©R†]S<Ý|iõ'Ý_/oÆsÄñç+ÿ²¿úþŸ0‘Ë4Mɹ7eW¿ÿ’x"Ð))Ø”0{‚$%E®VPr‡WÇ’röÚdÒ¨¢¬ìȰ\ÛF ÄYvBN®^%Ôg»ÌnWS87Üc? Æ–”Ë l{k_S‚½äñ^u³Qyu ñoè*Äß¹ù#ñTì~¶â“8N(4UUókÕO L¤Ô*®¹µíEᙄBO;~$„Î\å)‰Ö”ÖRBk{(aÙñÇTmsR¤d¢o^6ÅÕîM!$¤¸låvÚ¦CçkÊÄñç3$‹äùq²5_^wÍ7‹))êÕ¨¿V¶¸”RâqFÇí!R©-úñ¸$[§0]!‘Y+b æZ dò¨ o±ïÿ„pÖF=ëMp/ áZ‡*Úõœ´(CüÄŸ·üÑýŸßŠÃi%MÑÖÁ¾z.‘&)éÆÙØ!†k̃<À%É*‡ìŸ¬´)– ÌвâúÚ>ÊT«5Gqºº„´jx‰Í‹ÙÂØ“Üïå€ÐAÀ9ƒ€›Äñç-tÿç·pk¾ILUÆå:…ÃÝ€Œ)“ª™6¦Ê˜P®WRvÌOC–D×Q²8¹Q%áYµ‡+ ÖÃY «“fO`D½œ±g¶þ³®@uÐî¯q: ñGüÞòG÷¤F @B&Ôhéì  ¥¦-Gû°ö]Ã݈€)4õ5€D¦h°”Ú»Á„½V…Sš0¥)AÊ ‰o‘fÏ>û³ßQ:_ Ðèúø#þˆ?ù#ñ]RQ’ÚÎ^¶[QJhØ'ýZAÎJ}tkuµ¼0±Ôz“¨f5qÒ|<®¯Í.f½ @Ò5£€¸ÀÁ óÇI€&ÔÄñGüùˉïb뱤úçH2©ZE×S,Q–¬ªk/ ¥bn¾Og—J X¼8ÝÖC˜½Á:ﻥ&l~M×ñÇœ?VÇØsÀMӀؤ#QM§ršTÿÄñç/$ž‹íÑZE1:¶Ã“Ð Oñeíh}-{@ˆ(m]Ý~"Ã3l3±D™¢²/Ð;âߌøð¹ªgt¶O)–~>C)6ø’} ì9=Ãß@ÚëèÑ.´ù ïýÃ'Þ´÷ýØ!—-¢îò‹«ýùxG#Ûþ¨Ø¯è#*•okõm©µéÅÁƒquÆù¿Ü¸q:),–RÖ æl1¢”^…Sņ‚LB§3fÇíK/0ˆsem÷mX×ꥃd;È?äòÏ]þ!¸ŽA‡ÙkNÌÅ1”_ttéñy†oŒ¾Z›¶ibƳg~_Ö`›‡I;N´k©o[U0îâÉ7oó^¼Õó'K]»Ó[#ª&W(¤ÖQFíýT­×)H%k—ÎÖ„jI)“-ÏÒ¨¦¦GŽvµåý ž@þ!ÿîòÁu¨ÎŽü-ž¸=sûÙéE¦ ¹«+.Øá§²ÆèaëúµX¹~jMý+HYï­÷+#/lox€.ƒ:í?"zwd%Xy²º:¯d‪¯z÷N\'KÖÄöíéZI’ÖÆ}õë•.çóêÏösÆ*!sz½†™ôÌ—µî7>re×Ý‹ºÞÄW£ßíVrâþ±’Ø•ŠÕYóijÖFî£5©Ô„Zm5èãȹ‰G3‹Kžvr"avÈñÆ;­Ï‚Ø@þ!ÿîòÁuä$>žØ£Ïï7ÆLØùÿÐkã:lˆçCu®Ù~®ŒÝ;ó4¹·µô•Æ „T[¾è}@œýâÏ Ždtn@®dÄr­¯nñ >>IY±}Ć“oýP§•#-­ö͉Ú;íPä¾é–ü´%‘»ÆPËSp£çƒ2•˜PðÌÀÌK)#„‚»ÇÏmùÛV2ˆ=äòùç.ÿœ†$\UÒýܳ-:ö¾Ðcøj_‹CR»¿_ü¾MeØL×;xèã|¼zÏ—Áz#kPͤ+âšUú¯EàQ«Û¾âˆIŸÑs’¶«~î“aÁW’¬9ÄkÚZg³"ÞÑÐÛMõö[è#¿Lfãj6¯ê{МÖ®´ê½K©"Æžˆ©È^ˆáúˆ=ÑFRK¦`„NO•%ç%)ažA’m”tÈ•cï^h~oqÐÖAþ!ÿîòÁ](#*ï·vòë‡á3Ç=®iµ!40ƒõBxþ w¯#¾zƸ¹!ôQdYdÌÃÀõ&¶©¨xrãY¿ã*GmóÕßµÃú˜}Ë0;õÀÃ2…‰u9¶¥k9Ñ8¡£Ò¨ Çvêð›Š>> e¢Âµ»o]Þ•P9hbÔŽÓ7mêô`ÆfaŽá&]ôγ%M@–+ šM ‚2*KT&áéJÒÓ—ñ-/í!¯>ÿ£)§È?äp–î›RÛcÑžá7VŠ»NEêÚýëƒ;ãð÷"ê/° ÈÙ×rª«F‹†TOÞcxý”× 64A{<ïY‚Bñ6¹ôFØ ßËÒ5r_ýW¬±7F‡L¹›òáã]ä'ÿüƒu=?Óÿ‹ÁuNòõI¶óž™côA>›†ßé{èæÛã(„Â_ÞüÞÒýštÓØª”U|“vluÔºT\¯Wª ‚²¤e®ÉH+ÑêKåªé Ex>?ñι?–=~¸'¸j ÿÈ?wù‡à.ðÌVñ;Þ1¶;÷ùÃ7bßJ­fªs2âëÞ¾œö¿c¿YöçÆäÍ=Tþ^ûÕ꺧—4«mJ1½sÙ¾^^:oÛ±n7·R&"×v‡}äSW°1ÉÙ|0ô+éÈfCesG²®÷ÛÚÙì»»ÀÞˆ µ/#âõù‰>>»Élkº¤Ã>ñö’.e›˜9a/œúÛÅ´a-ëf-™¸ÈˆcvEïŽ&J"”*O"$–Jgj ‰UüY»Þ­.Fïœìyöß·WAâ ÿ¶'†üCþ9É?‡!ê­»Pñxø€òýgò—÷ò]F\ìÐóKÁú;Ó|Y`ˆ»ÒbÚ‰ÇÒKb^=Ìà­Wn¥Õ2Ë„ÒCä—W/üZ'¯ä[¡ú. ^=x©ûƒ2{IØðÔ¹/d ”½½ÙÙì~Gäh½ÄvjšÌœz]§'Ñ—'¨'íßvL‹n篮7ü°éB×Í™ÊBP¤ÂLiË¢vEéV¤’LÖúÍÂDY)‚„굩‰æ’Üäž—jÄç›]Ë ù‡üCþgù‡à2Ä-‡Ì›ûjíËÔ¡'ï¯õ4T¬9ÿÍ Ó‘¢æfЧ•æ{³K7ÝîPt½Ñ-A]˜²kSH¼³vh0"IŽÚ½ÌxÐSfzzä/EˆöÜ›ìÏé{OÍßyœ{ÿ¯iE®½@°£ƒ­ä´]¶ó¾Œ§»}z}œ(Øð¶!²'ç©ß Úó©ÚðÑ‘ûÓg”’…X.I c«ÇRZ%aœYI¥Š%²øÕ&Þ¬r¾)ƒ°Ê1Âsÿì¡ã7ÿú¯^ ù‡üCþ¹Ë?·A÷íÝç#ÃûÄi_oùÒ•]æš?~ÒkW‡Å~»QYÚ¬¦¸$¬®ßg†V¨÷GÍÝZwÄ»qãvqèò;¥,k³úÖn?:¼^Ï{©#·>RÏsfýJ¦»×w½êh,ow »$0§u³xŒfçATßÒgüønwç^èùcTëÑŽgOZ%^–mÑã9);£ ¥€Ôj€FSéäúI.•ú@ÊåyÌhˆ$u±™p¨+4éAv°ë·@Uvcbž8ŠËyù:úqp\CÔ´ÈúíOÔÁêìöù‡üCþ¹Ë?×A›µ\eÒú±@»c¦*f$ Ç‹?û"ŽÈ”f²!}i•4iÕìD*ÏÕùÐÇÑÙþ_þ\\èQ\dÐØæ#žQ­)åî¶ÄæDα•8£j ’Jóéûã€v¸&`ã·Ý­pÚ?äòùç.ÿ0•LmÐj|Z0m˜-èGi½mߥ/Uýè{Šb ^¥©ïA0•Hc"½º¥âBÿë‡üùNyzÔ"_GÏ(ø¹ž³ž{M3;óNûGí.#œ÷ÇYÀ€´A@—ýCþ!ÿîòÁuØÒ€z½wΖð³ý ðoÞLOL5–Ä"•åé|Ñú Éà¡£…”ÿñ”szËfX´ê™;gíb¦pþ„)ìNÃmÞ…vôýåB“Pkl¯óMôÎ `y–ýCþ!ÿîòÁu0i8™IÇNãÙ~LÐOç#èçK¿á4 ŽÓ/Ùf.‚Ö—‰¬¬4 .5P<¬J/óˆö-âY‹ÒÖzŽ.´°¾Žk)Ž:¼‚=hsŒ›YµŽ4 -Ø”A@û‡üCþ!ÿÜå‚ãÀ†È©q¬ëe~ ¹Q¯ÕÖ³ €!2ÄLú‘fBtVÑÀH´*suŽû£ó #Éå^S\ÉËZî[d/Æ×Ê g$бÈ–¤_âURÉ<úþ8ãšæí óžöù‡üCþ¹Ë?×aKã”VcKø)¤:ŠdÞÖ2~§¾„0hë§ñì?q¾ÞûB=1L)Òš˜…Á¸D8¿!_ÄWú¸ŠGTeëØñE\ʪlv½õ sü:™=h/¢ßùéç‘­h@ÓR€¶áƒ. Xßþ!ÿÈ?wù‡à:pÆM:Ú àF¿Õ> ë+ÄFŠðŒñ1?`!Î Ú%ªà[ –Q`lHÜæ«(Hô¨4}ÙUó£Ô²Ä0ÌËþí@ÎB få/ªš) S˜L›ôõ]AÀ`ñÞöù‡üCþ¹Ë?§Á$ü”YiYåVmC«}GåR »–‡Yñk6j©%g•kÿ„ù3µ?8P‰²JqÆ™‹YàÀ•Nt­víóæˆc*¥Ì¢¥ç=MLÚ>¨‚€^öù‡üCþ¹Ë?waKø1A? d¨É_/€0Ä­DÆ/  åyé+Æ®Äó¼jX@#·ú\”“kÏã)ùH-Öˆ§-f]F4.§¡rº¥}I}A0³ð‡qˆTAß8S€ÿok<×Aþ!ÿÎòÁ]Ø*|Q… 7ê ÆHPDBRDcÙ:ÿ£¡* “FS3?ÔÚ){“ŠÕJÞè7^ˆòmþØÇNã8&Ÿk´Òú(¢g]gÙ¿=áÇj8v±9 Lc{~‚I6yLA@Vý7äßö òùç ÿÜìU> £ž$«}˜4žÔ¨#ÈØù“Ö™õj%Ïà·ÞÇ&’Q`dÒpr¾µ~Ñ,ê+­n’V¸ìG%©‹LZ‘…=k+PGá¯{MÝ7Øó€mð˜‚oÕk˜ºà?³(H<€Íþ!ÿ ÿnòÁa8ª|˜ ŸçjG S [zúWfRË<²i`^‰Öî©4Ï×– Ø„5:š´ g/p õ…‚qÛÙê ;'éZ 챸c`«ÿQÙ¾ÿŸúúÁÜ ù‡üCþmÜä‚ËÀp¦ÊØK|ëYS ,þ¶m ôÀBU®oZ‘~ùÏ3;ßáqL%f¯Ø!6y¹ÞKÑ&áaì´*x’EzÖBê®'Æ®@ŽL k+P`ÏÒSTŠX˜4`Óö· ‚Âì€üCþ!ÿ¶3ù‡ÿÿs"™ÜDiýííåwKÐÆÀìÊ×™ujT%jtKP01¯„õk]Ì0C½_Å“QÞš ¤¨¥þs($‚\VÙ{/0×O8#Ž-A1›´Í`L53ýýA~ ŒõðA¬‚üCþ!ÿö3ùÿ?sÓ ÿ #xœí] tÅÖd‘M* ć<å=-B4@Kd  d_'™}¦§«f¦g_2 !4ÁˆHPAá‚‚€"«,¢²ýÝ=K’Y2<ç'¡ë;œ®êªºÕ=|ÜKÕ½UÕÏ@&câ¸!Á»çJ]Õ/ùOõ±„îWg6£Ó„à{±Ý{?x£FMËžW³7qEŠrÓYü{ônTÄP‹…ª¬%å?ê\¼ãÝEëì˼›ôÕƒà#Í·µýd¶*Ë’Áou3gJ¦R×3UµäuÙ_ƒ Lžf˜¸é‹éKÏÝí¹ørôÛuá'&³*ü׉ r–P°d»¯\ P‰ä¹ìpEŽ@ºLiÐFé…\µ87ž½ÿøÅ½¬ïÿüe¥ =øñOˆÄ?⟹ü#0a;”M·Q},=h‘ωUM·³Á;où×2-,§o?:½çR`é/C7rà vôêW¶Ú/º<^½Uù×_fõ“÷µ›2YïnÜ`_Ä6Þ8/ýîÓ…÷Ê©û;ëë:ÜRXr;¼Íéý’ï¨$ŸO^ÿx–ü‹Y<ð‘WéÛµUÿ Ò'†y·›¢pN^‚V#žY>GXå'Û<„(LiÄX˜žà (¸ïÕô©,4·ÿé•„“Žè`‹µˆˆøoˆÿ§™7ü:¯Ç¡!ã3„W\Îê­«ðÝ;÷¥²Ã¶"¼íÇ{ %÷NqŽ7)é5ø÷œõËœ=bÈœ1óö‹ZRBæïy0Lí¼ƒÄdÜÁ0 …Ç äw_,xm9„O××õ]ÔÉ’ÛþÒ:Ýrï• X@^¿¯ºB^Óö ÂgÆ.¿ù§O2¿Ç†IÕ\¿«°Ô¥XfO¯ž¦Üü±ŠŠ%E’¸¤¼ø4NH)7^µtC” ò ¡Y1æ…ƒýK½S®lÅñøGü3—¦#IÝæêF9¯ªý7 £¦^_³uÑÎ=Ö4*æç_^vê쬛·Üs6àù³ŸË^ó­óJìðžð²qççìIíùnÌØt]Œêÿ/‡²NÛ·SIÿìŒì.’ˆµAõu_}n ŒkqŽ­¢'Ci~Ôûÿ¶g/„ÙÿÞF ç>¨Mœ’ÑåyïbÏ7›—$Êô¢;¦ËtâmóÄ_Dà&,Tøõ²Ey8W…Çå¤UK…|)ïíÛ߇|{ã×g<•ì ¥’-mH{t!ûÒ®%ßÁ¿­û+%÷…wÖ¯sZQâSW$ùWÎØ>VO"Ry¨Æ`F<ŒÛ*áË*QlµŸB²á‹ÁxH· ygOÜ9ilÍñøGü3—† ÊÏ}eÀ¯ì¢pÞ@t°öëë†÷êâ\‹G~²((¯mÔþnNª%œ7/Á^Wš|Y»N)LÆv…c\Ô/Ym`;~¯zÚMh³z’"mj±­òÐó¶Î ,>Åÿ ·öF^>ü‚¼ÊμÏ)÷'dÏ/û"¦]Ÿ¨Âmo\\³Âg[”&;£Â¿jŠj} Î” Uªø¡0߸,qÛb]‚:-JÏËREñ±Ñï·9÷rqÝõu+¶ˆÄ?⟹ü#0â#ãÎõyþÔÒ…?:‰Ñ…¼á]7MæåR^reÄʲUëfí¶¯é³©ÿÄcí\Ø@¯?£ûÎN{kÔF§Õç"ÿëX¨ŸÐ`9‘ßû½?ÙÔáv²å>ªwkÕì æÌ±ûôôb[p•dfO#÷ðcŽ> /㯻ÝÕ»Çâ=?õÏ4,.Ò/gùoŸ^鯔ÉLl(W³Ò‰Ä oO0W‡cêønàÝU ›<ëÖ‰ù5¿]ÜD´b €øGü#þ™Ë?Ós·¦f.¬³[f †(V­êð•à§ì&åÙÄÑ˵ðPÑ¡FÍÄSî_›ÊÑýãçÊJd£…¯³­68V¦Æo™áXzóxiÃÛ熾^ÄŸg™‚pm~Êë~“Ì™°[Cè4B”G^ÓTaäõüÆÛŽÍþ¦¼ÑmOò—+J;æŽ^—¶1\½2vVÙô/§ÖÌe¾r.Dª×ú$”*’¢3Å"%®0ê‚ôÒ%ÝoïütÿÚi+¶ˆÄ?⟹ü#0Ó~¯2u}Än ü/>X8{q› ù·ò :vZ=æ­œÞõKxÛ²‡/É™«uÿìàZ¯ïö::uíèÁND"5ÚQ$âÇ177Iû°B|X¯×ÑwÛülæ¿$€„Þ¦´)”v&Žé6мvZÐFs¾Ÿ J~ .κúlê[{~5ò´˜ÙeÓ¾ô¯òÑä-%ʧA¹\¡›¼—'óx,±,6M®ŠH…¦(5áû{틟œ¹²¯UïBü#þÿÌåáÝá¥ÿy}Swóæ^¸ðŸ'ŸQÝø`ÀÑ»®ï4Ä›š×/ˆÇþav" úŒÉÝïå`xlñ–iúd¯¬˜_ô]áÁƵ[§M¬r”ytÅn­ð¹Ÿ×(ocL?Ý&òÎ_·ÞZa¼ÒÞœQ~g^D<%ky6Ò¨-È"Í]ø½~r8ùÚ!(Ú9lªguܶøÈŠyVØÜ²•¾»&«•¸RŠÉÔª5±I¦Yᛢ%TÊX¡µw¿Æ‰5Ûû¸âÒÅÏT­Ø þÿˆæòÀt*Þ,MÙñÖø}â}EëóÇévWî±¼øèËã$óÆG§Q·ÒH°â`{ö«·ÚFí¼Q›Ùš÷!þÿˆæòÀt„O;ÓþÒçü*ö>ÙåµâõçŠ2š%V%òEh‘êV•ï`1˽„‰þª]\K^®2nÉ­[/®÷7Îñ;îăF÷i\2‚ó#YüÃÄ^=»Ü?äZŒµ"0¬Æ’;2Ð|£:‡J Ó? íÜIþ¿!œ°Ÿ ×Lùà‡ëþغl&ººClÈö9šµKæ—l^é³{’<…Eä‡K%z¦ÎTipn^,NðÒÄ¡eoî’' ñ¬ntÈ9vù0å>mµñøGü3—¦Ãëø37: 6ŒøÜF{z.h=fÖíî1â|›’˜ö›¯4½dÈn@̈炇v Üòü·{u¶¬Dxú·nN¤>•l·T¹q“Jx“«?¡·áÛ ¥_ë¿ýñžûÙº)]MÒùS÷mEÝîždW†_<³­Cùè´s+ lóHèt2éÂ\»’|¯ÕÖlÿ=üŠÁ]?³8ß~g°¥âoZ޹{ÏH½Â¦âa¤ÕÙIÛ'VÊá&?LºG¾Å»ã—¹»M æ³Ô©^8^á«âr­ SÉ6@çªØF±Â˜!ÅzEHK Bùâû7Úfí»t^Ùö!þÍ·ˆÏøzøG`6Öv*Ém–ð}þۀݕ#Ïú½³å«”‰?¼Zмèȵ+YwyŸ¸î¥KvÓÛTéí8Íà°'\ÿ&!˜¨xÔ/Ì™ÜÜO½vÚ½ê÷²-/)º~ï5Žõƒé)HÒÏïXÊg\ûÈœ9úýÍÓÊÅTïNRþÁŠ¡9°£Ø{ Ìàp{„I*æ¯h?ç³ÿ’Ï[ÍVèñ)5Si15¾¸R!‘JUx*'wiØ ™”ÍNS&˜BL9I‘ÿ'R÷ëuaLAÕ£Ú'oÿˆÿf þŸ*þ+Ÿðóž,’”„ŒT—n8$"žV%“z䨫âÇ¥jRˆÌ 9å82ÙÐXÓIyA¢I-¯C°t…‹ÝÂÀg»ÃSÂ31nh®Nn©ˆO©oa;þˆ,ÓŒŽœÚÛ„Cõt)ùû9z•T&üÓ<Í·6SðÿňÄ?âßœa ÿ;žô §Œ|­¨T½Jóêë¬ZO*9°œf†™ý„ôÐßê¤gæß¥á´9[¤ðHÿÿˆÄ?sùG`:¨0_§l2ŒGóÙËÕÎÌ%ÏÕ»RƒCʰ$™Ô²8Yª«F¢ÈUŽ…³Š,^Cˆq¢²´ò؂ڴBëúa³â[†þf? Å HZ V!{œ0`‹vz¨ÿˆÄ?⟹ü#0¤rc ©®œ€Ô= &+]Åù¨0¦w.pNLŽÊ{ˆ¹b(ÎvÕ øT8®¶ñ>¢$aªÈÔÀ/)¶}D`}¸yu,@jùûyP¥´™Œæ [OõñøGü3—¦ƒÞóäjça@0AœQ§hjOÊs“0 En¢ƒ´üqºÞÞ·hW˜êX(¬¸0Nš¦´ÉíQ›+вÈq@‡1¾Œ ƒ>Z¬ÐsýGü#þÿÌåé Â€\cvü±Ò4MÅ÷,òBŽÎ^žüGçºü›&rV XFÓ0¤³½?F¥7ÒV Y@dè««ÿŠ)Àæ Ž›'fƒ@ÿl É7"ž¦i'¨Ë—‡-Ó4GÿÿˆÄ?sùG`:Èa¾H mìã£l¬Ñݦ䅌G9þâµ¥G›ƒ äá:›<ÀÙQ«ÔžˆNäZj=.9ÕÀ ~Fg{ÈÒD;Ÿ .RQ¢$ż=‰§±ÉØöYVY'8ÕŽâ48”ªlS€fê?âñøg.ÿL9Ƹ µœR ÚñŸæ°ßǼ˜£´ø (Â,÷Hý¹K7š·ò@\˜¤²{$Îqv8G¥h\ ‘(IÄi ”¼°~¿‘Z4Ú²Øn`óRB"È5ò¿7h1 ÙúøGü#þ™Ë?ÓA…ñxZ%©¶![”ât¿;y¶^EÊãìÈ<ÿðæ[Çܤ°’=V¼ÑYLpáz»R (hynD¦–€’z?Z YVY—ÑK€hçŸÍ p F…Ÿ ðúøGü#þ™Ë?ÓA…ñ„:™0Aep‹óD^ 0(°H½É£Á?ü™¥ ÷ åyü[€O™ãÑÔ¬ ß®w±Ô|ÀsØéjê¥lsë ËÀ²ˆòšC€2@"¹=ÐÌÅOiYaÀÇÒÄ?âñÏ\þÅñQRÉZ§a?y\œ‚ Ÿ÷éØ\0½´±'àbÔ[ÀÎJgb"‘Þ®DHXÝ|¸(ˆz fÎ[C– @ m ¨ i pŒ/U­? øxúøGü#þ™Ë?ÂÓðúK¯øå§<•ÚÝ–×}² Æí–!s[á´¥}uθVKËã“Ê*bLª}± ~ábõFÛó­Ãþ‡[&æÃÀAƒ³Àh@ZBõ7€ôƒŸ¸øñOñï9ÿOÿèÿfkînVò/&H ’Õ2RùÍý2¨µœ¶Z{öeP òÛæädðú/ƒÆ*œ~BÜÉ–`®¦^_Ä–a+µ'b}кÈlx˜Y÷i7 À%bF)ý{aÀ'm*ÿˆÿæñÿTñÿpKÿ0”xœí]w\ÇöFãÏö}jbb‹Æg,±æY¢‰¤¨ˆ"Š "½ÞËí[æ–ÝÛé—""‚ F#QTn‹ÆÄ»Oô©Ñ<[|A»·q\ô÷ùIÞgçûÇîÎì93 _Îa眙ٿ&£!®ë÷s”­ý^úñiÑÌOnõ#Á§"ŽyN==…|ÉNsÎñÆýMW=㑳Ê7ïziKÂèÌ=e³öà½ëû‹¾þ‡–íèö%²ŸmU¦k‘E)Nûx߉ÕÐ…ñŠÆê:ß(ý™L4ôz3û êxû¥z­¿ªN_=áäZÿsÞܹ寰Q%—‡cÛ®ãñ:÷}³Ê|eîÒJw •Ë}€rªjx,9ÁJÊš_½XÂ!%SL}r‰[zõ檓_Öÿ/ ÿÈ?`,ÿ̆6qk 뉤UÂê+¿ÜôÙ™¿®8#¦ËÈM¯všÒ‘ê„›â—è2c}üëÃT—Ø;=¿]Ü|ôûà y™×TäÿµW…çAW2%* )IÕHŒËa‡À¸©‘© Iº 3P;|Ø£·eßÝúI'm[ù‡üCþ™Ë?³±¬KÿÙS§¾]áTŸÖxçoíìýÆùMæÊñ³CºÛ¬í¿—´¶C\T# OìuÊP⮹1±:îóú[͉‹~ë±¶ÙÖ#5™·nvšU•b«Šœi[·îÚ ËbNŸãÏrg¾urH¦F¡å!¦êM¾FwÈÖêOg&±¨c×ç<êxoÓ]<‰küÇžÛòà›[±5˜œ¬š³ð¼Ëç×¹Ö¹Õy€ªÙ„‚@0%šÂÖ-Æ‹bA6;VÁΉXŸ¨ŽÌrE¹|Z·Vïô=ÝGÛyÈ?äòÏ\þ!Ï7äw#ó»=ÏÎlQŒÿï ŠOÖé94ØÚÔ|ºEæf³"ºÉS[ÕÝbÿ1òØ™„¹"è£)nMm­r$Žxѱ¨¼¥+]˽µÏL± "ö>¾Ú¶µ3WX–sÚ×!šñV;åµøw—›Cƒ {¼o¸DèèSáh½w»\_ /%c¾9s@0|»ÂÇͯs.¯8ñóšû“rHŽw©o™W¥Wµ‹t³Yî!–Éäb¹@'žXÍ \/e‡¥agoËÎÆ&)MY1 ÇÝ ¯.5”*ÚÒ@þ!ÿæòÁp`ïdïu9zcרæÓx+‘«¿ zÇë=VÉÛ„í=¼®úiVeê2§}áR÷îÐÜ·ªWè:¹óƒ•Þr„Ì+ü§æR‹MÎtÙþãÁÉî‚¾±åì [YÞ¶Ñ_Y–ÿv›îrÕ…éD@É}|„)øöŒ¢X}¬Ÿ—Lc–ô@òp³"ôl;7·EûòƒW<,)¥S%xW{Wέp«›±gŽdûBŒ ²É$2»0KöÎËdI9iQ²·vòjy¼çà?:be7®¬!ÚÐ@þ!ÿæòÁtð«§u88xòˆÅצñ°ñ÷öo˜Ðuh‡Ìᇠ~vº^qhÑ‚3N:š;å×é[ m§¡·†“5ÏÒrfïµU¸2ü?Ý[l2,§ÓSüëFÍwï=¢ØòÎÆql…CS8:Ëò Câpü€mÇ•eíÈ6ÖÇíó2\¤dЧ˜XŸlÿ×êø3·Ù¿ƒ9µ y÷ˆGõ×<º^)32ÓÂýwÅeG¹Õ¹Ô¸3I‰ˆ%„D".…Ê4R™\(R ³V‚4¿u ¼‰=•´÷Þi¸ =äòùg.ÿLÇ*Ÿß·d øÝçÎV»[œëþ{òŸàïæ K ›Õ ¹½ ûÃùñ?5+Bù‘)«öÿkÜGöÌÂŽ¸xáDÞ«êq˸ü[|pá¯ê^X²æ+gÑLµùÎôßfÙ'¾l7Á*Êøâ_Æþ°ó¼N/YØŸ%×ã{êy¡ëõçˆ}‹è“÷¢ Ô±â³Tæ¬ËáKNÆ^qÈÝIé7Úù5ެË9¯ -NA v"S7cc¸P¾6“)1u¬†‡‰€L&D 1"•¨úñˆ*¿iîù¯;wµš~°6óÈ?䟹üC0Ó<†ŸÉ¾‹Xg÷b®·]Mæ|úpVssp p¿ÿ‰ßÖ£ÆHMsÓ?ÜÏ/öªOv|wq»Ç‘›?#Þ™+oªî¨zÜ’C¡ŸaÑEÍx0A>ºŸÉèk.\SØJÿÞ±ŠQ†sLâ‰ó'ç"?O›ö†~„•aèü£²bBÈc€””|½(ßw3#5KÆ“eÆó"·D')'lÿHúõõËÚt-äòùg.ÿ ú;&îYíR¶ö}³‰ Ã®×}ÿ`îþ„΂'Ns{XlQŽèùÍ‚NWó"}ÿ~îíK Æ7«wI²h|Ñ¿M1ÆÚ-WƾÕr§c—ô_lºž‘BÊû.Ý[ð½¡x8¿øê@Â*€‰§»4å—ìù<ýhp_]%u}“ìi¨dlן•ë}èSÃhzið¨ð;Ìê3–>_rsð¡Û#Î,8Ømd ëÃïfì-\ºr=GNb.{&mäJDg'þn÷ÖÓ»i*TeLÐNÛßíŽì>ûÐXÙ럆yÍWÔú Ï¤GÔ±»ð))«~£·J÷èøáO:m*üטÏ_›:ô‡u"|y¡ç~÷½³ŠWb»ÝÅZ©H"“’B‰6Xª[ÎOIçìŽB˜¼m©JÌ–‡NíþÔ3{çoèÁS›yÈ?äòÏ\þ!˜ŽeŸý2­Ï¹#½Ž¬Ç}W4t9yñIØ›«òZ­âr¡áÙÃGÖäZ× ÜY¸¼p¹3ý˜å»—º–.(¤ŒzÊ_ßÿäyÿâþ×,Ë<-sùQ…†¥K¾~ÒÑN>|¡kú`Òð¦ÂÌsÁ%~~®¥ÅUÝ? •±Þ†II]zÑã3gºP§?v§œÇ˜n”µÆæ€*—ëýÝyP³ê‡Qã«t¹•0áÂ^Un{\«ÜdD™&“#+e"tc^ G’ #bâ× " $‹£Porõ?ø›Ï\)¡c–mæ ÿÈ?sù‡`8ðÑß½ëù؈¼Œº_æÝÝ^\÷I³ù<‡˜rüþ>­’Ó0Ï2÷6øNd îÜüô¡&̹¼½~ç…ŽOÇðGwt¸«§%fv©|j]üÂeíñÅov~s÷Ïí—mÌŸl]qb¸e\³ïª¿D÷m$K\$݇^|d¬|ÚhÈX.*ÐO::Þ ¤~Þ©gtÌ»€÷v Tø :±?²ËÞêâjÖæþ_žùyñþ¥ÞÕîUnÕnµ Ö'ÕbTLH•˱Í+År¶6=ÑÆk¢ÖþϽP(->äE¼ìÚùì¶LBþ!ÿæòÁt ·V}8?®&£øñŽ<·zçKzm€> ôžWÂNò‘ÉüxêžïÙwSݺ-BñîgjRRþ].nt&{rÔ£®v•cÃæ^Ĕʂ,ž½Â¹q6Åäp˵HÇoÀ5ºÝÄ!™;zw7>o„ËIÃEyÆúäwcuô>Aþu-@Ç< oƸÜÏÞóÜ{îz™]½ÍHÌêôq£öjö]=+WŒÿ¦húBPúXS8Qø£r“ÁU|^8A¯žÍj¨«³»¥$XÖG–.µ({N/6Âÿs¸—(oØ*–1³x±·aæsŸžú)@ãN5þ…:ÝVt CÔøeà]bè À%ƒ*ö‚Ù·‹FT…ž4\w¡±Ãw˶%‹¥ÑñdL¥ë¹F„ˆ B¶ˆwНBd @‰b™+ŽÍNFµ7{k·F œÝg퉫åm¸òù‡ü3—&CØãhÅ;[O-…vÚòVI®s G’³³6¼®ož$V¤w¾Áû°ºuß1"ìò•kµ«—N–h[ã¨?¨wxƒ1¬úEÝÑÞ¶{•=ûÌ˺¢üýo,J1Âô[ ñÅíG|¨z˜èª×_9±Áp[î«_ \ówú×"@i#õ»{Èû5á9HV†ƒLYè”û¥CN¾þgðüöûœíG¹Ð}‡J_á)®ñÀÉ‚P\*•‰Au(ˆˆI•’J6‘¨‰ðJÌ™3±]/Ñæ‹ Û(ù§ÏÈ?3ù‡`2"*¼ÎÍšÕ0°½ÛÈK'6zµÿÖÅn m«€Ü¶cÆŒ±Ží’yÿľ—SsvZu÷G_òBï¾ zïƒ/¶5÷xKFnZrŒÓ`½Ñ(È8m³&hÆÒÒǰùÆ1Cpýá‚ÊÌ]õ·èÂþÑ™mY“ôç¥W]©cáÂè|ÞÍ=ExFí[„[ýÀF•×ÈÛŸÉ î Ë%Òɤ‘ë\÷ºUyˆËÝk¼„òJ[# Û'‘Ä(E”–ÈŠÔFcóªSWig zò¥²üÆ©ä6X ù‡üCþi0‡ÿê×ÐÄŸ±*™´>·LÄJÓ´Ž¡|‘ú¥ô­ÂU©21Ž#<‘šp¢ =wÊJจ+H’ãnUo£QÙ¶Ulµå@OP²ùir‰^›oî‘®pÔýDõÐ=ŠÅúõø8*@”2É«„Iqœþ©iM»”½V| ù‡üCþËm›öÑÖàó$ ™¤•Œã˜ ‘®2)è½DÙj}c+(;¤@E’^Ÿ#mÙ‚p‘G©²¹û8&bI#Ö:ž[”(³Ä'[IrT˜0^šDÒÏ‚HL®ÃŒ³žP±¾ Ã¥ú®è§Äq‰Áœåø’x©è¦éÑÁŸÂ”Aþ!ÿÆòÿÿ3e ¹TìÜ€©?X„/N‘Ë,„) ä([¥oÖ†+ÓdbS£¨­R4¯#îÛUÍ7Né³|·*eôñÀ|;»ŒN·’åG¦©(}1g …D³ÃkP??Ÿ”K_iðgðÕÈ?䟱üÃÿÿ Äâ«H‰ Ö¿êG'kä¶Ñ:ZŸ§vªoGÙÁëUVåsí›5ÝEæmÖ´tÙŽ²Röú¸÷7vUáÙVUˆXJ÷ωϠôùæ¥@æ¡€q€cú4¤uÐ0  «Q‘@I¼Zà´š¸ @-äòùg.ÿmÕ1ÄŸ”e#|Œú n!ˆ§üÅéÔŽ„ôú¨ªEý¦v„áŠ4ÂÆƒ`Ñ8ÖG| ’Zn–—‡‹8¢$ÒÖ…œT»îWæY ¡¡([˜J"¤éžé½ß ´ŽZ;1õ»A˜â•Ò€m?¨…üCþ!ÿ æ‚éÀŠpe i3¬ü% © Ên›@ŽL)uj8Ê *RÙ‰Ñc‹D™£4 â·:¥åFÑÙ»e”¾0TÖC-i×à:+LhÈRÞ-N®P˜£x"SxÒ8ÀQ©MÐÊÐŒ/%eÿiÀZù‡üCþ™Ì?ÓA§ñ¸JÒQNø‹Ñh[Ìñµ* ˆãêåŸt$B/Ø;}dYFš“°d  Sz”âÇ')-õq·r;{ÄCÖX5‡sŒ»›Rú¼èTµÌèßÌ3€LÆ@ ádHçѹ@}P “¯š4ÛÂìòù‡ü3—¦Ç¡@Eئñô¿˜L§‹th} E1êåE±º¹1¥ÏçiI+}$()ÝÉ;µÈ½BjÒç%¦X¤Ñ•ùö¡Êˆ,kûO0ϦôÙœt“¾Àä¥L©@à ‹ Å$`z@•‘èÕÖµéÀdÿÈ?䟹üC0ú4nµ–Gøc Ò[µÀ‡Öçáͦé—yºÃ—ÿ&}.f™aDW*2˜?¾BgÞ¿ÇD‰¸Ö<‡ƒÛ¹ÎhÎþ©"àâÉ}ó ÓÀr íR`ƒ WC p…ó ¨££í<€Ùþ!ÿÈ?sù‡`:ôiØ´È<°‹Ú:z"—¯šl›  …ýCþ!ÿæòÁtÐÑ>ž> HÏi$Fé4òÖ.ì1ésÔöiDçG-¼ü7éói@4Íma÷O=0×–ßïÒ§ñ’tsu°)š˜l]Á'-Œç+ÊMSRúæ@MCPûkJšVÀ8*ÈIÉ+yýàµ{+û‡üCþ!ÿÌå‚á ÞùQP-£·Å`q3Z·¨Çªá mÓ€8š°IݪÉ1tO ¥ô±HþZgæXáÅvžáò’I)Åe:°žMLP$¶$ðô–¤nŠ\Š›f5 €E°)hØ Ä˜ú4 òß´ÈÚþ!ÿÈ?sù‡`: [r‚X2¹õû‚ÚèóÄ–CúåŸÈ [»?u«¤1¬§ßGg—Ù-ñ¡Ó€l±†ˆW;ø6"TÙ´€Z6@oBë'H´„y5pÓn £¶ˆ6M6åõý£|±üUÓ€¯}`kÿÈ?䟹üC0ôœ–Ÿ) çê¼Âß°1 (7ïJ5·ô+ÍK¬ŒÑ§ñ ]NÃ…x4šå@†Ò$¨|v;èR„Ú8Ó`c !úq 5Y°i`ØÄ*h¿ˆ1 È#Hé+é…D¯ÙØûÈ?äòÏTþ!˜ :þÇg±uJœ«iõ–žö­Ð[‚ªô™Cêå?œÐµöåߤ­ŠÖ¥9Í< =v;"Pýs•8ØTä6’‰–ŸÿÄy†Pú¼¨L¥Q¿¥Ï`ÀäèØn™TØmHÖ¯ÏØÇ!ÿÈ?3ù‡`2è À¼XIª‚Pny¹/ƒZ7„¡<„þ2(5–øJû²Ûb`ñþÛ@³[‚š; Livo0œ$H¶³@¾Ä&^ˆÇZí/bž„ã¢DaŠQß40®2ú“½€!hZŒ!ÿ‡-A_çÀÒþ!ÿÈ¿¾ž1üÿ/XëQÿ@åxœí] XSÇö·hk]ŸŠKQ‹à¾Öº¼ÖÝ*²‹¨X”ETT@¶@öÜ™›Üì€ JE—º°#n¸`Ýq·.¯Õê³µUK]Úú¿7 á&$ü?Ú~f~ßGæÎrfnøåœÜ9gfÒ " À\œï ,KîzhP+"îÙ½§Nñ "|«ÞøwÜžzÙxQü ä'qãd玤XÜnÊæÎ—OWšmvqXàfsuÑ6ýºæúœwñØE/žQeØŽõðÄUZ Ï Oñ´9>o¡ó†½Ð–Yy€Jzö”Lž-ïKeJr œW—„^ ²Lÿö=÷ô»Àïâ2awohgUk8»ØëÀôR—rgY“¨x¦@$–Æ… 7É$óñŒ°x1.“¯³ç6 †ì<_üùƒq]:¯®¸W®"{ç4ð_ö?âñø·^þ¬¬Œl·soµc^N•„…µüÃÿXØlÿÛõÅžcÛíù‰ñ6䎸–3<ƧÞì¸ó'û‹·2M7»ãØý{³}Œ<ÓîÉáýýU^[úT[<`f+£†âÈZnýgýµ¿£àÖÝÇO‡ïTÉ•ND·ý55n‡1µ×6~‡ÎßÌ•Á¿Ì þ) þÿ5°.þ¬‹wL¿Í¾vä÷qÞ'g¤èKÝ^1¿ÍÎú"iõÛôÎyÔƒ½pÞÒV@ݹ´NU³cJ©«…ÝûŸ9ë^ß¹‰f|Àî]&ʵ8üYxŒœziÖ‹s£ˆšbÏŠ(£†’YÛh9}v¹>Øîzá©6O•:4—Uè]ì]äV6í ;,ðâ)Å|(‚b(T/g…¬HåÇ%,;8þ g±‚Kfñd1qN[ Ár¸´Vô×Ä¿ˆÄ¿>cEü#X1“ÆV9Ÿ·Ç“—gÙÈè5XÛä-~ YWw ‘4¶SpÝ>:ð¶Í’ÌËS[ï·#ê—Ða¿mÁïÙ·u™áé£ì¹—ýJÞÔuBº\d~tßßFS©g^‘½m¿{Å7´Åüvkîµlµ¢5={%ÄU=þ‰¯ÏÞu§Ú)~(®öÓN T ’¾^DÍ=†¶v'§J!=Ÿ'B{¾­Ümoßù“«%“~rÔñ,ÛñÃÀÁße$Nú ûô¤ŒàE˜Yì”»P Ø("¤ÒQ«Ö©æÀœ0ÿÝø qlr| ×§-†ÍÚϼ™Òçñ’äüÇ„Mnÿµ@üÓkÿÖÀ?‚5#î’‚YÑDHDç}O+EƵ¬c~KÍþ¸—÷-¼Q½.ñ:—GøI¯Øÿþ.7³ <;Tml£Ïòïõ‰ÊŒÊI%Fí&–ùÙÙší¥ƒ´ß4ÍhÕM2øý‡:j"…ŒyWµtøMϛҩ6SͲ…:ÏñIçòªO´ER¦IóÞ\¢’Œ“ä£?ñÂm¿}6n¸øü{ÕgÆ?YÑë¶cÛ-»{Yþ}õ¬_8 ·ÑŽ/‹]‰îB© ÃùrvŒˆ“»ˆ#‰ÌRà1ÂS³¥Ûæ²Ù÷{ÇÍ×±ÛÂß\ÿZ›Ô þéYÄ¿!ÿï:ÿÖ ·¹ëNG3‡ÿ¦ÚjRÅO¡ÜíÿÌùnnÃûGáŒe-ùº-yøÝ§ë"Ý^ÊjˆäýcUãmœè%1¬cYzŸQ§4Üÿvò‰•l‡ù•{ÿÙmÀË<ÁÑ3n¥îe%nÂýy˜¨Ø (I1Q©X Î(ÇÂéÒ0îí1r9w}<5³¿Í¨ø-ׯdR“¯&³ˆzño Äÿ»Í?‚uc[¯=篽Z?z•Ùão+Ùy—û€ÑÐ0Þ‚ œVŒ;®Ö… ]î40¿\¬¬WòÕò7ùJ ¿|qg€ËÛN£9!S¿·ý¼Ø|?©Õk[Ú]üãÀó>ýí„ã#+UF-CûøOÇOÖ_Þš…õâÜ]¼$ÉÑÊt[³O³ééú´kdr£wu;²“çÈ÷ãuB,z%<×çAÿë“ÏØd;tö-æ½~Ö‚³'ðM@zx¡ç!××Þœb/¬ÌB‰D8[¬ÞÇ ¯Ž”/NÂEXbœTXæªàÊgÇnî$î",_ׄa@Ä?âñ¯‡Õñ`Ýx<=ú©±Î@ð‚û¢ÇgÛר6$Œ‡íLóž=Æê\á^îZâRê’/ÛÅ"d¡ä$€&'F­^(JqÁÍ Ë\Ì9èŠLŸÿ¹mÇà”׋šn/âñø×ÃêøG°nŒ˜|úp½[|ëúé¾òÁ¨oêíÏ×á•Wøw¶G3è…¬1cò‡·RnI´çµ í>aª†w¼åƒæ[;yv×­ø >}üu²ùŽÚ·Ü9Ñ ûùi‹R_—k?½lnÔtÉW·»Óó‡|X›iuz»ö<;Ó¼×ýRm²Hcòã\MÙ°þè$wóHòu^KÒ6}|*œ.aÁ|×?[œs¾Ü¥‚éðñì½Ê9I»»íÛx¤øt×>s Ýʦy¸Kó=€Šàâ+¹Šˆ€²Ø¥k‹äbi¬H¸¨k›h•ˆ/‰V®ìßz@DÆÍª-MµñøGüëauü#X7æojP³€Oî ™ÔbÇ£-6¬ÉRûów/™iK\4áä»ìK3)Gað¦3áKRÌTFøf»…_Úà‘Fíæ }:ÜÃüÞO÷íòÚ¨ˆ ¢ø&øÝÊ–cîÎÏéùÉ!G×Õ¾›ì«Ôȇ€¤•߸­à)z\ÖúAïIOž¡Ú(ݨ@dÐ7º'‡?³r Üä>õÂ)ç;Å9ôò(Xã•~ùòŸ»ãìŽWð$n™’çCîñ–ùP,Ei© H$–*B$R![¨ÈõÌc®‡ÏžZôp";çѹ¢I âñß þßQþ0´ÜæSŸü>—æZãyµxà—¶ÈçEމº1Ço®ý]ýå3¾ÆÏ‹¤Kß3ß·{UæA§²?"àéÑÝ·0gôøhz]Oå‚_Æ¥ =ÑÌÆÐ4ño 0ÈõævmfÅfý~án¯JœN^-P½ìÑF»>9«ú!•Ír„Lþ{œ´·?„\ ‹¼÷ò¾Óáh¬c¼l×µ«ªn…'N=í%]^äR>mcY±‹t¯'!Ý ¾Ú=)Ç›¹†—’ U0²‚œO‡¦cv—¥Ysų&ÛÛ+˾=¬ú;÷!þÿˆëåÁÚÁ»·Ài»àûÓŒîñXŸ º'¾Î6" Oým«®ç`?™Zhxú¯ªŠQáa ‡æ¤¯4hôfƨÚÌ£±þú÷2©`Ô¼…úVNÊxK{ i;*±™:|í;Ìœˆ_¥<†»^vpƒ ¡r¢|öw­D÷2qoE¿5[]Oü þ´È+5ìÍ"×bWå>·Bw±8:&K9PÍ[&ÌYŒ‰ÅÑ")“™.Œä{Ê¡GžP¶`ýâµç®ìü[÷!þÿˆëåÁÚlg<5vg×2SµNªBÊ«%ƒ˜•g$µ¨Vy§Ÿk³·N•gurûqÿ1m8ô`ïx¼tÏVõÓO½÷Xj›˜b²Â3tÁ†¶[o\¤yð¼ ÚŒIßV|q﫚Ë‚³çK»ÜWzßÔ”TÅ==F¥é¯ÿK½¹[G“æÄë[nì=º5”,õyñâPTŸÁ®Û¾^u~(#ßÖû[µ2õ{±g¾g¡‡°ÄY\8ƒ#“Hp_½Ÿã»Ÿ—c˜4*MÌŽ¾÷z%Áà¿ùɳo·±Ù7ϯÿ[÷!þÿˆëåÁÚ1«ÃW¯^÷æÙuÂxÜР䋙[ŸgZü±ÿ%[ªE[º­6ÚnäÚlæú9W!k°d´ÿÀ˜°–aíŒ÷ñÐñË%^¹ÉŠD°ÈîÜÏ?\0C¿—èõÞ m–Þ9R]›ÛíYûvz_RÀèÙýÇ|ýA×»Û4aÄÔ?~¤’/Rﺓ‰Ý ;òµ id“ÃÎB.!„û:ß*‹ë5jì–W“>x©b««d§ßu“{йģxZ™'çˆ& —L°`£Vq¤P›'º09ªÛßSÜÄœ7¥ó¹xÑõJÕߺñøGü[/ÿVÐ=»r{ß!/Ë'*ë˜óÇ—‰¶¾ñ«¨O~PÎWö]†œB·þWËúœýWƒöÏ;è—¸’w±ƒÙ`@ÅjÓ~Ä>c ŸÕ÷{°F\{¬kÒ¾h›á¸í¨ÍÄ|¶@¿’èÉ eä«÷!ÛUcó›W5£Æ$ÒL¾HÜFQ~µ˜2-N’³›ÐÙÇD0*“w æ²Û|s)ÂIùh•Â@ž!7Þ§ ûGF»&ØÑ y¾PÛDšÎ0 ±Õר½)@š >[LZ€†¿sýÐð¯³e5C"þÿˆkåÁšAꟅ­T"Úó>©Á¶B"|; 0v°BÍIl¬<ˆõùZ®³@63A"29±{Ì«wYNÉ3ã’¤4ùèã[L/LEíX<ä³ɤ<0š@.„5ª¯3”î“Wš? -—#7z 5€Â_`Ê´Ã!þ5"þÿ5°"þ¬ZÇ_xbbo5)`cä'¸ñN@y±ór„|¦h”<`ÌÞ£WB€ñY¥Iy¾Û>óÁF-Véäã‰z ‘IÆúĮ̈5»5Àbxq|µX(ÐM @Û•Þ¨}ö×é>¤)¿ÖÀgCYã€ð¯³eˆzñopˆÿwŸk†Öñ¾V%áuÕŒš0 òÜH @>ü/¦ÊH!?ž7\@üÌÝJÚb\R^\g ÂÙæûó² ½|ŒT¡“a)ÆS>&¡g-@È‘*­‘A¢æ}i ÝHóÖ™<!&ÞÎ ¨A[€RÄ? ˆã›@ü¿Ûü£ïëŸÏŠæ®¢¼|¦U\”KÔ<üoK$p­<'^ÑÐ0"©þ; ZRò Uy®ÇÅ5„À3_?…€v´ZF¡iÆŠ(à( F£;5«´ò¸B7¾Öó§Oë7š0 D"|{  ¸É,@âŸ>âßø&ÿï4ÿèûߺ®H’YôÐÀçrↇñȇÿeø™ÞëøŽRl:Œg$ÉôÎK0ÖʉÆV†APÂ* Ý1ãRèaL>“©¦Â€ 8Ó¸s,ÎÐÜ0å4A®×ɇ­Ó…k–é<€Ú€šEÀú…@4€€Ëýdž·!þ $ÿunñÿó¾ÿ­¡ Òú¼{Tˆ€å Ü ¤yøÏI×6ÖÈEýò€5c»ºîƒ2%éaD²a…ß"Ë’äyŒU¤|àæ:~Ćv„'¤Ek¢5òTËš%@ÀÚEÀ¦ €Æ‚áÒfp3⟞Gü›ºÄÿ;Ë?úþ·nðL…ýŒA…ã%R¢S€±–õ2ÃÏ:)Ï‹—Èê‘'µz[²I?%ÏÊõò×¼D ]a.F;ƒIynŒ\!Z¸©ŽþG®4(Âx´sÍ0¾D/Ë‘+4ãóEžÀ`­0\¤ë€ 6Ήª¿u-šÊ"þ Dÿ&oñÿŽò¾ÿ­ aIʉŒKësÖ}ø§ÉÇ+-ÊöŒ­ÉæNô ö"Å©dZyëcþèÜ lã³cTÑ™Æã†ÊÀâ€xúê#®~ó2ànL5~Íi 5@`"X×@Œ´‰è7(Eüäÿ¦oñÿnò¾ÿ1‡«$,†ñ¨‡°VnÒÑ0›k! 83³V[Ðjø,®J#ÏwÛ£°t1P]·š ã-ÝPg71Sj8&[B³|\_‰aB>“HÊ×lÒyµ¾¿:€¾ H7¾€ËUX:ÐÌüÒ&MbªÿˆÄ?âßzùG°vPGz²q G‚ÀcÌÛš(1S¯9R7Fß´T‹ÊAÉÇ ©0bxìW––Ó‚ù&I <6‹”F q8BÃ#AùX¤M¨@ Æ‹ÃUŽ™òjç–f &z‹#A›Ô ØpýGü#þÿÖË?‚µRe3a<êáK3ýð¯k\¦Ôdpý“×Öç£är6ÝÂÑ:¤È´yà¯XʼnQÊ Æç mÆ¡/¢‚au$i¬BŽëÖé<€F!ÀÚ€~Pû0.W,ntPs&¸Áÿ©hŒþ#þÿˆëåÁÚaþHPòá?Öo‹ºîIuäYʺò€»@™Þ€à˜& ‘”nqfä:ÓÕ|F°jÍ (`+ G kWAj Ô„‰„D;~°Îïh €f%°‘€˜€Ï•ˆÔ¬Ñh"'`ãôñøGü[/ÿV* Èæ+ê„©‡Aš¼Þ¶æHQ¾ñ‘ž€$^O4H)Ƙ³9ÉÒ†e¦Tš®ä²qÒNÅó%zy,Ö(VÈ!hAÀ‘êkµ HyfÄz|ÔýA0Êàô®ýi* È—ýs€ÔÄ?âño½ü#X;Lý2¨æá?;©ž‡ÿZy¦È@ðaÄ ÔëÖ‹¿ йï›®ápU¸æHP¡¬¹WžbØ‘@@?XŒ¶H3ÐÞ?ƒÐ.ä1ôÖ<û×bl´#’PôV¿«ÖaÀFë?âñøgøÿ?%PÐðPÝxœí]y\TUvÍÊÒ¬Í}É5?MEKͲTVApcSPöu`ö™{ϹwVfaWDPPTDDÙ\Ê5—R³0Ë­úJ“ÏLS˾{g˜ fd€~_¿Ÿsž?æÞsîyιðð¾œsÞsÎtíBDp·+kŽØ%ü^Öœñïêê8Ðm?6± 0ö…§ýT¤M‡Öƒ¢JJ¬#;$ïšvîbÓÞ ‡õsÌ–¸°ãxy.vf}Tìû•bIÝ©TÂùf˜I¡"OÚÚã égj®¼â}ê›/˂җ›4YïÎêG}>¼ÙÂ?턺dç˜øÚ0XîPZ?:áé¦q×ù¿ŒbÖ{É'wéì«§SµK½#¨ûXQ³@*ßHAªE[ÃHIì1#z£@(̹þ›:)É{•ºpTÐ#ÞÞ/Ï%©è×°îö÷éôGúÛ®þ¶‡_CÎßÊþxÀ黩s¦‰!kÊï«M qŠƒp£äœewô÷?ôQjoÂ&~ÞmÎ"»±‹dÇ÷¾@g|¿Óy,uq¾<±Âè^!œZ±Úï<´ nŠX·?n,¼Ÿ1ùzô¥ÅáU+…xîðž-?άr®r®Y$¬v–¤¨bp‰HLP¸efWDîÁˆPehn˜ÊYPòèU‰(|åœÑ|T —ªÈÒ ý‘þHÛÕÁÆ÷RdÍ~-þÌŽÑ’a[ ˆÝÁwv6µ‡ú+#«’£ÿÚý†(6ç뙊G×­$ÖGDM¯¢®SßjêµÇ}ß#¢e‰¯=˜«Íé—^{¥ŸîÞ!¯rÜ_ e@é]`ZlzE–Qjé…¥úû#sužapŸs}|ã÷NšPAgÜ9uœ¾mÅÚé€K•Sf±‹²ÌI"IC± D‚mÁ¢7ÅFn’HcIYÜ¡D"¾’'MHžxzýèàÉ!™g/”(à?èþH¤¿íêð¼`èõVdØ¥ö?GŽùóÕ§NóNsòä#ÓÛÉç_•ŒgÌž1ÈÕ-·ËKV²Àâ=/Þ“ÒwÂÆÁ.Ì¡ü•-ŠnñÝfžÌÿ%­—¡¦§} kEàåÁg|1Ób Öó—ß9qOŸ86I7Æy§ñF¿»œ[GS‡yþ¦Éà„Ò—ƒ ݩϩ+@Ø;ë×(øE×ïÜ`—Ë™#öY7ù‡ð:¶O\îŽmÝÐÿˆjº÷Í⨀Úù5î¢ 7‘¼Ü#E¤‚#^ƒç‡È$ÌÌÌp‰$‘“Ì=ë ãù2õÈSÜð…Ó¶–0ÓïœÍ¦öH¤G€ô>ôG°m¸¿ucWǘÁ îGΜ>aâÊY ϾÔ'îó]ßâòTÿ¦›]fZË9±"Êîjó}|lƒ¸«ß1ÖÞL“" MóÌ“ã|Œ)œµ™'Fô*]ãÔß´Ø]æ6J¦»êïw:¤4ß³s¢`ñ—ñsÆ=¡3°©ÂKÔ…½é:êÒ/³Â-_YØÝq‚Éd<Ü7²º"õý_|>zì’¬ÚÉž;Ó÷jìú~ðÅ×ê… Ö¡Á­.wÃÅR‰ R&WÄã ‰\šÂÛ$$ÙÒâ@š€ b\Æw”–^=’B‡&;éþHÿŽ1‘þσþ¶ÂÀa—¹©ãŽNx-Ý·(Ûïß:ÜmaþÕ‡·Iþç*¬$„çs+ I¯»gìêÔã‰!ÏÝgö›êÖL~k?üÜ$cõËX×¹}…!sñøof%ã¶ëWÁmf\€~vW/¦öõ¤Û¯ý‘s‹º4N¸6˜ªãÆÏû LéÔ îùä=¨3àþ˜Q5esš–íS/É]¿<—Œz½ib´=óMP\í\ç†Õ¸5Nb¨ˆðÕŠ¢ "?TMJ%$7“ý~y2å„ Xje@Í·vc‚SŽ~¹WItÖ ý‘þHã\ÛÒÁ¶qy6ÿH(n?t…3ýRßw«bKÚ«¢¶Ë›§¯ËÔŸ²³m¦À˜q¥ÊÁøÆÝî›ðhpÆMýøã³Õ3Ì0iÌ”1¨EÖt©˜Y)Qœ4ίÎ6Nn}|M¿Î-Wwk-Â1q'7ŸxqvÝþé×·Ðù#]IùˆÞ³íåFO_{ ®Ÿ>x '%Ѝ·TÌúÅ£>Í=«pifrDV¯×›nóïq_8âP· .0²ÁJ*cSEŠ„Öñ){Ôb’“X˜zÕzìÃZ’”H×GEE.¶0+:ÿ‹3šMñH¤?ÒßvõG°mpÞ¾YÈÒ0å|{gðº;(XÅ,®)µ»óÕÄãh›_Xøáªâûñãû<UkEùþžƒ®kQEC—£·ÞkšÕogsÆ•žÞ§-л/Õj ƒß8ý(ûí§² yŸ5üb4 €¬­¿"†np4feïÂÏd ó¾ÿÚ.=½G?8ɤç•G×Qã€Å~çE0}¶Ïw¤ÇÁ}‘£ëJæ)§OMnÛ,S/ÆÏõj´Ÿqàð|¯‡£K²Ú$på×kn´ÌŒtO›»ñÈ!UšcsŠÞkÍÔ òóÕÖ¹ÜÒ=­œ£ßK4kÆšÉF¦Ô¾ý“!å£s4ð¨ô]ú» tµ]=/=ÕyÁ+átŽôAêÓsà7Õθ!æù Ä6DÀòð1 õ¬9¯}XÔ­)õ…?Å»½²äowøôRâ©!{—ÇÖ:ï_HÖº@2Cˆ@dr¼Å¥ 3^£PHH¦š±á€K‚©fÇì±$hÄ8YÝåêÎíBú#ý‘þ¶«?‚ «x•9øöÃcþÖoà þüZ¯­ådÕíã«îõ:¹qàYϤvµ‹õúäòNN¯?•Ç]øõ²gbÃ}6˜&8žRo¹žrèÇ·DÖßkò•˜)CcIìŽÌÖ¹¡~ f̬^´Ž{¿»n4п·q‰Žïêïñ•k“›oCª3inÜþóÚ¥ÓŸÕÞçãxn•vÈØG]F/¦k[´—dùæ§@N^$Ü2þÐá˜qN…ý¯€¡`Q€*+°ÏWÝ{úÇžÇUËê\±šùë½±ƒî€‰e"Nš"P\â/„$[L`aõ¡ ^º¦XÀåHã³£ÜzÏ MûüìŽNíBú#ý‘þ¶«?‚­ƒwÎé훜îÖ…ñðï‚îL)-;P¸Fkj‚Æåïf^=Ãùݺ0ž˜=ÿÒ»ô¦ØmïžÙ+ÝsØ?>k’{aúÅ®Åfß§§GÕŠÆA7_@·}EË-UÐøõ[ã[ç «váásëȾ×4{— ßrKŒ+Ükø½Dê7¥Û}¥½>2ïñðˌˡ´ýÃÂùÿêI]~S?¥>ÞáÖv(L(ˆƒ{ÂÇnà¼î9*ÌuÖý‘ Ü$ é®°¼ž—¶_ˆû®Þ¹Æ«q”ï÷x’Le¾€Üžê•åD´L,VÅ‹åUNbîÎ¥¼>áJC½& ÿ(AÙt:‹vöH¤?ÒßvõG°uDFŒÛ›õXnw¸í²Ð¿úÂÛ¯_:o8f3†ÛgÊ»©y}ª­mœüà˜sts_=!éÏ ücDC÷Òg4{Ouë…gœÂïv ¹§¼¼ å=®]zÒLöýü¡ðÓ“Y¬Ïûóëè§ofO† g^4$f×èöÁÇ‚æqB®¯´ÇG% <~P‡kb…}»ÄÓžì|ãç»~K:ˆ-0/ …E±c í«z´aÂ͸Ë£jƒù+J“WÍŒ/yeï^ÇZçƒñËk–Å+6Å`„¤X@,;ã’ç+. ‹ÈLŠÎáÃè¥ !I×È#7¼sxžÿ¸!¥U|UŸÚ©½@H¤?ÒßvõG°u8u-¿kèí{;̪mvÖû„O ÏÀŸä&Óu‹^J½3-gb—ÜuV5dŸM:zë´RŸ±¬â†ÙIo¨Ò,0¾ÿøûW-ìì¡°z¢ã@•ãÕOûÖ[*R ýf²cúu¥Œ5Ö¥ïíŠý ‹<¤®,sʸDþÝÿKÂõG•‚¬ æ)ÏËNš7bÿ”)qÞÓét}²=õ9Ñnd„ÝÀKlê÷³vôÎÙ·Åý¤:öá±KÇÿv8fe;¼(VÊŸÐs|é’ºÊ?vFÕ8Ö:&ís%ªÝ!•Š))û©·„2>C"•sÃ…ÊmA{V@)Üœ9xZ`ò±ó{:·éôGúÛ®þ6¼÷Ưîþéz¦|¾™Cµ XRpâÇá^݇?:Õâ°Ë­•t¿[=£0ž¦ðnÂë‰ÓÄ ã¬Ñ›ÓžNkyx´ù½H/|œWdieïíð˜ŸÒõňޖ&!»” ™e&{²×5=z·ÊG½žüôõ™_èýÞbP­aÙÏîšÞE}èÕ| yV‘çŠKޝô§{âøw©Ïƒ¸ÐÂ×GCè\” ßß] cŽóûéþq⽟x;°à]ÑÂe%¿»qñ¥°“¬oxÀ©Ö«_Ä‘$•{‘bîºå¢*¹DÄ!%¬¼8ɵ¾jÆæÐ¤´NLÌRûWc·Nçuj/Òéô·]ýlœýÎo+8¿ ¼k1Œ'8è¼ë~"êíe뇼Ãó^¼x&`VÀͶö .kªÿܑߢò ³¿¼ýÞOkV\2C¹2‰c÷Ÿg‡±;S_øvûÈí‹,|—È[3ó{šÉö‰cÓ¾ÕËzÿº»æÑ‡{Ž+&™üÎvo'ê7 îrf€öN›Ýœùד!¹‹?£¼Õç¹ô¢»ßÜ‚ÑGô²L‚“JÖÀÍŒ±Ç…_ìVŸ<ùÞòõÂí©+sÈØeûx^ìÜ[Y þ‡k݈ý 6ìš/Ù )Ipeb¬D,V`âp© OSÆ @o;yí%(;;ÂPW|kãÉ”NíBú#ý‘þ¶«?‚­cµÇ+ÈÎzü^aþ¹»ª¡ÑßU0âóÏÃüžÖp»õnÚýìv Ü$šTÖ*?&êç•ñ/®×·¶|‚Ÿµ?çãßæûÿf¿uê¾Æ’SÌ==[›}ÅL¶cè˺>yÛvOÉþþÊ×—rÿk\ä˧E†@ì¦õ‡OJÐ ò8|„Lѹ{W•e~™=e èãÀ†O™By’€·ËŽÃ¸ŸˆàðÊÓ0?~ìÉÃç^;Â4Ôoç:‡Ü‚%™)á±Ä; ç.?µ¤~õÙ&§Z'qå"r¿'NŠd2/^ ^{p3O%–3Ö†I¥I )‘YbÜoklJЪ€—Ç,“5œ? ¦]d‡=Òéô·)ý­9wÁà|¶\&"t}d€q#„Ù ‘•GˆÐ|V’„!œ-RkÉ ŸJÆKTÊ í›‚¿t·…q׌ZÄxñê$-Äd˜VXJ£ À“éS8®™¤ø,¶JÓ>´~#HÍFW©ýÄ!©½@S¨ùB•Àù|‰DÔŽÅÒú×i¾Òï4¿ýt3¨ëÀK ý‘þH›ÕÁÖÆã*%¤Ö‚€ aEaªÔ‚9Zâs”Òf¾0,~›ÌZ²À¥TEP|.[-A3,ÀÏ´P‹PèÚrX)2šÔ¦vØ c:Obx,Й,õú[Móµ†OY4I“p¨5ý¶Ä1@&!ÛsæÐn®âos²¤?Òéo»ú#Ø8Ä…\<‰² `ªó¯´¶óoàsp…–Qbµùƒ¨ˆbºË p!WÒüV%V­·p `‰õK›(>WS8Òëø¤q†ŽÑ h@Y¸Šj_køºmôÍ@kû–À1>–$j— i†þ&Ð1ûGú#ý‘þ¶«?Âó`®m²År!`ø¶¯óoà³$r‰E®Ú“dµùóÜöj S|Sš$nհйÒ—™€£-K”â3äI‚O¶8/ /€6ž4 IL(Uˆ4žÔ;š8¶t´⊥šÔ4ö‘þHÿéÿ|èþÿÛ6–ÂhmBÆÃ#y•f'â¬àóXJql@™Âj6,ÊÑY ÍOTÉZ¾?;l‹…ê@œJjœ„—‘,ÇA‹ýN Qm\0,ýÁ1¯˜ˆ²`n¢ZEÍ3€Í!Àg8Êú5œð¥²ãaÀ¿ÃT!ý‘þÒÿyÐýÿ·mÄ*Äd‡=Æ\†‰ŠUíÅÒóQ’buû€íQa´»˜âs¹*Ó0 ˆ’¦X²ÿèTÓ®>Ågs¤2¥©÷¹±Iâ|³z.#r•R‰†ßÔ­²Æt$ ¨{Ií¥ó“€;‘þH¤¿q®MéþÿÛ6x\(› £µ ªÿÌ fPÑ1>]±²@ª²š/tÝj²¶@\À† ã0 ¾¸ØÒù# "³åÌ ÀL^F 7a¼È0€BºãNñY¬uÚöõ!@ƒ0 šwÇx@Þî0 Ô;€N{€H¤?Òߤ[Òýÿ·mà¸-¥ÃPíà~‚ï–4)°¥²Öa8«ªÀã–ïR X2+ù€ás E°ŽrB|¦\nàó]«,}‰ Yß*2HñWK• “öq®I<Òx꣗<Ñí'ʵaH“ nÎà& Œ^r;µ¨““€µH¤?ÒßfõGÿÿm`|n’´“€Ôß=;’»Q)¦ ÏI’u`àñËv&Ÿ¥´ŠÏwÝÙznÞKÄTëø •m©"°*׌kQ)ü„¹Ñ$b‹ àÊ I£¦]ùCïEb&ÓíÝZ`Ã"`í½æÖ’ z`|LܾõÓÍo¦½tjP‡ôGú#ýmWÿŽžêš'PˆÛ³ˆGÓùßœ&# -Ÿ+l_SÎXZ’LÕ(¾@Ù6ò?`ni/†ã«$>ÎPZª÷+4gÿ 5!àpS¤†!WbRN@’@ 6h~¦imP»Èh)°`²H(Àdâf°éôGúÛ°þ¶:ŒÆ%¬j:ÿìMJIsyšÏ!ÛFxÂ’©Zƒ¡ÃxdR|ÀsÛcÞ¶i>‹¤2A¡sËBðe;ÌL³¶L pA"©Ò[ —šðŒWÍê· `šö6¨? ÄÈ<ã0Í$ vhµÓ“€uéôGúÛ²þ¶@Y[Öj/¥Â|†_~ºÌ¨ÃJóYr+ùZžèS”¦«¢å‘ æ€­Æò-†öè0œ‚² n 9o®Ào›¹g\RJóy ¥n71Î6ñ3€'5ðŒÚ%@šLŒÄ©öå"  z [ ôL@{ŽôŸjíéôGúÛ®þ¶«Ã€šÎ?k“ªEoUs$¨Âê0"‰ÞÛÒEÆÄèHP³ –g¹ÜråtŽ¥–ň2,–Á‚6›{ÆÇèj)>'1U¦Dd)L Ñxé@÷`¤$UI ‘QÐhP› ãaÀÎMêìéôGúÛ®þ6úHN–dîHM“b¸€êü§É[E«ŒŽµ¢1Àô*Ì4ùc×ð1…E¾Ð=7ë™Ýcº Íó+SXl_ºÉÜ#!GEhßIÀ¨5a@žÈ$Îh²Èd ;„tûB™\¬i¿í/i¹ˆcòÀÿ= ¨·¤?Òéo»ú#Ø:è#99"ù³öi:ÿ‰y-;ÿ>}$hÛÖâ-kÅ-ŠiÂxb¹y ŸŠ6¾#Œâs¿Ë;1:Ëû]…/{|ß`ë×jV>N³ ºÍWZçê_ÚÏ@úYagºýüúh°}ê•$ú#ñE}N›¯¾D¯Ô&%©“Ê)Ä×·’|ónÕvZLö’¶Ú›ýd†ÒñŽäëd—8øtù=.h}é¢X÷ÅÙJ窎§þž>¿èb¯äC“’óçb|·¹ZsCöíÚõõ>§ƒÁe±‹š’…N`*‘¿¾tòIò}B²<>Ç4cwph O«áˆ¢æNÌ8{öÜ: Y°ÁoÊ þP¨?{õ‡`9$o‰õ’øVkVVÔÉqäm¾¹Ü£kÚŒÒzøhKBÕ“ïs¸°—ÌÖ#c_4mƒÞŒu"|Wu˜ôjý‡ín¸Ç‰a~olüä–ctvÊ®åÅ’©_×m%æ›û É­¬Ü™^Fê¹wîíðºCf†ä ù"á¬}rmºëÇšz¸ÑxUKÿ/6vÜÓ¢ó7­R¶N§î¹ò˜|í…ßàÉ‘G‘àÑ—½A^ȈÊS^ç;]¼;;¿Ëw²þgE¤hb”\¯~ˆë­—ÇžŽ›|8¯æF¿7¡ùƒw7XïK¿,NU¼'j¨¬ÂC=—Î!ZÏÀ´•-ïp‰ôiO˜%O2OBfÝìhÎÓ"¦éÍí<«jÊŸÌp»û׃ nGlø¤ÛLòò‡qä+úÛ©ƒä¾ÿ¡8ÑáêB<üÒçƒýoø||7§ßÁ^ÿ¨]‹Á¢Íi¸ð#Ç÷ª¤§N-þv¶¼Ì1§x¦B›(Å¥r‚«ÂP‰ÒÐLÓJ^tÔ äQDŽòc|'^Ä}SŸ+ÖQ*5Û@ý¡þPöêÁr`CN¾]éÜåJœq¢‹+»±nÕÎõXÙ¸ì+?‹Åšxg™®nŽRuÐ[Øêµ7—F§g>§6\\ðÏɆkMŸx8ÀØ`÷ûþt~Ýçϱrsnp9¬b¢íÓ’×¹åÊ9Ò=µôƒxÍ ""…6ÙµÐÜš½‹kR~ 99Föã3Ÿ]ê÷ºââ”]äåœêª¿?òWÒÍõ4ìîúȬñûòÊù¯.÷©r=×îDrß7¡»9Á›cx™*]‚û¤‹×zTV¼ZŸ³°b.Øé¤Þ3•Êe*© •‡ä‡-KÒ’Ž‘°ÊmÿÒ˜Œ©'$Ç'\åð«~Ž“úN.Ù{*Ÿúâšm þP¨?{õ‡`;ÄßFñ?¿Uš¨þHÀH7¿÷)«zú 3@~ ÷:y£cš¶µ%eeŸ.=s䣆õFsH÷†ì9Õmsæ54íHâI7»›5I¬sȽï?Þý¾ú[Sî׊C‹c’ç殩{¯¤§“¾¬ý/âœñÚ÷É_´µCq+L®…ÿèçHMò¤r¤1áãTýAPëõÓ³º#¯ÉöÚo,éxüý!ù*îû úÚ ¬ñzýò„³oºýøø}PÀ•ï¶1s/õ_½ûXjuÕæ­7+œö¸àå¡á˜¶tÊäRñNÄ33ci!†J€†“•îþOïת€å²iLäŒáýÝøÅWOj)›Öl õ‡úCýÙ«?Û#p<ÿ\—íƒö'”oXõ™xü£éë›ÂOúLÝÕÝåt¿£´›erÇïFt«j Ÿ»òÃ/9Y~þl—à«Óû´j˜vr|ßt%ÜõÛºªÝÇ´©ÄwÐá8ÎÄ{ƒ§Z--ºÕÞ㓇Ý­ô{mty¾ÿ€¾¢¹å– ¦tfEídfœ«j¯1ußÍCPüÎožtmõ1éÜNEÞLºäàÀ²9ÈU°¾÷Ï® ÀoðÍêñ;Æ<œ~ð“ËÑ7Ã\·e¸åez¯Áâ¼JS¤_;‹—ûwÇF¤"{eûÀÖ%B “K´rƒæÇÈÅ:B-“ 2Nl®Ãf½^’â]€HxQK¦÷¶÷ÆŽUîH¢>m³-Ôêõg¯þl‡G× ³;_5¤ò‹þo~ˆÉdsA¯ ,꽯]–'ö~imœ<ç”î¼¾O#Bˆ– [»Sw»Oõ†¡iuW#3@=e‘ð)í:l:±ºMе1ê÷ÞÏCŒ5ÿÒy‰•C2ÆNÙ3nñ¢¼»ƒúÆPsiêÓ¯›³}½vg˜.v†Ô¤¦ J² ‰?®`ÙØ´ä>ïS Jöv%ïú¿»òü+Š@ágßÁUU#÷2}ãàAçóóJf./Z˜‘ª‘ÉVµw 0ùå‰kó÷»àûP*U?P…eë¥èª@9§V&¦ù>œ@ ßÇ•Œ£8ó&ö˜´,ëÌ™µZðo Ôêõg¯þ,öiIu¯ˆâk)“¼Öðò[k~¿íß}ë(nÚÙÆ«ú,âºC^ã œ#Ê+<¾wØ>þÜôøF<=l¯¥å¶_‡Ãhî“u·'5 yôNÊyF^Ù½j«uA˜r£ž&ßÞ¶û£ÖR€=Oû›–ÿó³5µ0-”*ËgLüÕQÀøŠu¿ì~8óÒxþ¦w¨ýN³>¿r çø£(úv2Xí;ðNÕ„Ý£ŸÚW ¬ö>99½Õ[ý¹QúUK²P{ùì{3° Ûçq<÷ =JE²¤<œ!:©0R^äŒDçb2~bf¼D}Ñž¯¼Ûaõ×X®Ä*‡0-qãùéÿj/Ôêõg¯þ,ÖYÃÕ<‹.ʸ¬nV¢«žƒ¾Ûî÷’ìôOÂ÷=žº·)nòÐíí;©Sd÷öžäzÖ¹‡þ=kë„è{ÃÈž³Ìï#qH±Çê¦Û‚ë*ò èâ4Ò«]ç%ÀÐQ´Pæü©×Ì{‰¶®­7ı Ì˜úJM­W–<ëê¢^Ü×…šGìåMÅC''^ {`ûQ`•ݽ'Ý÷}ÕrPþøÇ_ï¼û·¾×Sþei\Jš.Úc·6a]ºðzZ‘, t·“¦ÂI¾sž' ¹05JšÆås1‘¤ˆPpK€7G·h g`ËÕcŸ¹oîzIݦCäî@~a¸’£S¨ˆyJ‡Îÿêìýîþf`GÜDJY¹ÀYB¾uIüȈ¼@7>-)z¯³ž—¤Æ\+Ê_>í³‰Þ©ÇOoÖ6{/Ôêõg¯þlÚá“·®È3Õ§úu<ºòYANóÊ™ÓÜ‹.m_ÔNquR@rÃËVt_ðð]‰:+²aûÔQD'«×0ïéÿù˜_ÿ7í¥]¬ôŽC6â‚VÕVs’ÞNâÆTø¸¶=Zoì•BŸ„œc÷Ú4<`dmrMá$câ@LYoCbTbO…l[@~KwÊ5x±‰²Q=×ïwÑ乌~Ø¡ÅÆY.·s§ýâTÔûVâ­yA%üðBï­)„`Ny›þ o^žùæ•_ÞÖ›S]ˆ]ó).Cq4_”–¦&‚ "V±<C³¸¡xË÷dƒŸFj°¨™1¿˜¹éÐÉÍÛ õ7¦ þP6êÁj„Œ ÜYSr潌3gÃíl™Ôı{ ÐN™[B[ôÝÌ›"(e:€«^Ì]“²ô÷jü»-Ç»îéYïÔá³Nƒ®2‡G­š>fÈÞin³AÏ~#­ÍÒž?Õ&§ol1½ûðÅÓ.Óò_3;â)c?ªIzµ¯ÆSùfÃpÃ{¯”17{Ç+þüß}9ùèëI[e·sÄl‡W`ÅlûÇCîlqIÜ–âú÷”¼Aw"O$,ØJ,.Bc5„<"snżžž›¾>û—f¾«tß Å.WŽ+‰8>ËZå³Z5KD†,>r…ÄgC¢.a“gjxžP 8òÈP÷þC]ÛÎ_B©ÕSM´P¨?ÔßVêÁfHZ¶¹°ö¯Ÿ:¦ëà•ÌèåóÇåŽ^O¹t·{ŒpþÒ‡;´USùá§æbö•¢Jû3G·Ÿ[èÁÀ3`I”tkÝc»í±±;K–›nmðØœôÀ_µÉÔ²š@=}îö»b—ÝŸ½eØèè{ëÁOî_fÐ'æV‰žá—@Öì‘ÏÜö§€u ^•fÂS¿ÒLÇìS ½3ÕÑ whå‚ÙºñKô \íJoÏZ—1‡Øë. dr‚Pá‰HL|iÐ ~HŽN£AD¸Pü ·¸Â%¹t†@/::ôr<ûäj/P£-Ôêõg¯þlòú÷ƒ¼ÓSý쥥æŸSíûúY€×=YZ=L’ð:'ÌñNÌì§‚¦D‡Ù ííÖÅœýS߯Úâ¯þÑ2?Ú'生Mã@b‘ÿ'ý’íø\­´ eäK«›1펢_t8N{Üs\­“1áÏ¡æß 9UÞ­&é2®ªÈ˜ \Ñç¾!á¿J \~ìï×7úì‹8½òWo5¿)X’phçxœ[¸lÀ{ï< Æ´ôØø°EJç—D^°>;(‡¹ìr)oÓÞ.#5Üÿ§‰²=ŽšÝΨ/÷”Jåè%±6T°1, ¦!ÁÙ*,2uñæýv¹­ŸáJ¾:>`ÑÐANñEç5~/Ô@ý¡þ¬Ðo=_ë€a¡P#Ç¥ u@x‘ «tr¦L_ e曀òæååÈŸÀ0„ä+P'ô-·5»Gcëôˆ€Ÿdͧ LLcª‹È0‡ Éúù<½’¯±8¶*h‘E jj &Áq‹ɯ©Å E 7¼’_†™^ÖüÕŠŠD*òûkð³Z}ŒšwŠ9£ñ´:+¦ þP¨?{õ‡`90€"L-íz†Š|W.W1ö­:|ò?ØöS(ß3k…ÂF6Åçcê:|Là¶Y߈-ÀÎeJ’ÏCµ õc~*cÿO¢wv E8²ÜÒâ‘•ÛˆŸE}ò´µ FøÂ$Ëú±BËX¯Q×½ ‰@O #¢"ºÉ¢;¬Ö11Í¢nh?A €!øWŸ`˜$¿ñÿ—0 cÿ‡úCý¡þìÕ‚í0„á¤*cüÇû奩5ø§ñuð׫žÚ¢ø&š³.½Œ¼Ž¶’HD-ŒˆEk™ýI¬õº`”“DòÔ¦0¢Å Ekój`‰§‡!k€Œ5¤Õ dÿyÐfÿ‡úCý¡þìÕ‚íÀ0‰H Vq¼ßŠô¦ þi|¾FAÛ „ ƒÃJ4ŸD”yZrÜé»ÃÖra‹çC”™âs’”µõcÉÌN–mÕɰDNò‰úš§å ºÚ^ožÄP\jj?Y?mPã µˆ¯ù·aÀ @=ýêõ‡ú³W–ƒ òiLD‘¾9¡(_€ÐˆÂÐà-º&¸*á#ZÄcSJc8ˆËÖ:|Ô$šX«0NBb¡iÖGž ϰ .b"BFñÅ|¡ÞÀÇD2úC€Äz5¬ý¡Ú/ÖQD¬Y€,Zˆü›0`Ã.@}ýêõ‡ú³W–îRŽtuZçþh b>^F…mÖ5韙âs‚yÛp>0Û®º{„(>—P€è²l31Vo½·S“…?‘0„%ݱtL{€h3€K@ò…|ªþ:€¾¨¾­@Ô^ >¡”ýw“€õö¨?ÔêÏ^ý!X røÌ‹ˆ*T‹Tu÷Ò4¥ TÄ3ð1QD@qRSDz–° 7CÕˆú±N¾u?¡Â€‰Šúç3Ÿ †qTÖhB²´†/LЪ )à[,[¢;´%@´@Ãî_ªK¸j%i Ÿ€é4š`Z„ŠøJ%þ_Y€zý?¨?ÔêÏZý!Ø jìšà—“¡ÆQ›G‚6ªêHPG"—nÒ7y* Cæëó¾VÑ`ý’¥éÉLPa<žNI ¾k™ÁRëÀ ÆU&>Ÿ«Wˆ”N·pÌ{€Ì3€† 1’í—¼y ±!ŒZï§gü`5ïõ…m÷¨¿‰õ‡ú³NVÃ0ø\KE¿ŠÑzô¬¿$êHPTž°dCrÓײ q‹¶iH¾DÓPý"[›„¨I4D'õ*¶q„˜a8\DL³…$Ÿ‡$É„OY:¦eºæÀšÀ)O£ÚOà†`Í6à¦j7µDÝü#A-„ä‹Ülzým ùDðZWÅpCûÆ…DŒÀx&¨Í…@¤âÊÿ“0 íýßP¨?Ô¿–Ï2ý!X Úà¿&œe}$h“ÊC"—VGr6 I”¯aTo8TS —fÙ.œ:tþf|It†õm,.™~âcõj:ŸîЖÑg!@ƒ ÛÏS˜t`Z LuüÚÑ:ãJ`j/Fµù m> È`˜û?Ôêõg¯þlµf†ü[ü†iDÍ bH¬OQ*h:ãÏýf9^[¿P¨e:RÔÄãæã=k‹»lè ÉeX8ÄWX¸dýa2oáЖÑfk]Ê$˜ÛO?Ülh¿  T"hÿŸïb<ÿêõ‡ú³BÿÿùWÿp:xœí]w\GÿÖ¨‰cï½—X° &6Ô(HA# (Ò;W÷vwöz…£7*vÁר}í‰K4õ‰ŠÝ$Æßîõ²w@~ÿqû|ü¸s3óÌÍîÃ|Ùù~g† FXÙiJmaµ“¸ó‹zžA6ü É ºú*+w˜°‰ Î>‘ÿ“Ã[C_\w©ØÐKÐhæ$Ń´…ruµƒÝ%é­}É#©ÉØQ¹ˆk­-I—ÞL™×ìñE/M«%¦}4¯ÿæE߸3·Ï:D +| ù\ðæ¹¾°ôÔ×Úä{é‹Tuʱû8ÕþÍT ر}Š÷Ý8ŸßÅåóávèx¼ýU!Š=˜t™ýkvÊzìðêu§v3goêÿ}8:¸Y½5U”èQéV…ý*°ûP}æ9Í>0¶Ê\îsù|L¨Œ,šW)ã®+â&Gˆ1I˜Ëq¥‰Ê¥Ë™‡î·Xyή:XAÊ“žÚuÜ‹õØ®ú8ñ©s‘®ì‡šÁ't_uæ[Mj¯cŠêú2»^‚÷_Ç/ϽhÛr·óGüÒ^wŰ`¿¹˜ØgÂ;ÊÆÄ?øëTÜýôþ£žÆT¯*¦Ëx¢„¤¥Ub>äP»|À7î‹E œ„K ‰@‚ÑâPþzyÚìËZ½ÖfO*Ó>°ï&~(T§¾x“ªmC„‰þ‡Ã£s„¯û8 zã•#[¹8cØê€*)&ô÷H±£>×{]Zuéù­¤ õ¡¡Àͼu[ã8^Sì\±X:ºC}~„ó{á%¬ÊåVxLKE @¸Y’ ISyt)^±'?ðcâõa4žæ3¢b ™Êι|:OŠY7”þZPú›—Rú7wý)Ø2Ø7ï§@ÓÚðùß›bÒ `d͈²ùãÛ_Knd“^Ó o±þñÑðíOuXøþæ¸[þò†©Ÿ@ëm‡çͼøë®­™´G.ã~½ëP1#ÕZctNòÅ©æZ·÷I}ù›×“ œ˜´óSÅ"3ûêoçM³^tÿá)æÛûÞò¿ããwÄOk7é V”i“÷S[(Õ©Ï7«)Ó+U×È“§ÞÞuüÎÍ™°‡‘}cí0l ç ,ó7&HàžXz½Ç ÏsÎ [ŒòÛⓟ±r?:¶@›âZáz¨õ_u¯]îðdŽW¥;"ªXŠ¡PˆI|q<Åq…χç2fšÕÖ|Ú> T¯Üaíy“ô³}Z§%Ú²ªs3g<{w8Ø$khßïq Xûhìo÷FM~UÔ·Ùª/R|D›3ºg®:Å))œ£J¬ëÀS­šT5âuÇ_ŽöÎßPa3œkq’£¿®ÇÄ/0%äWxmÁñ±Oœvø)´V1}ËOâÛc…I´tiŒ×!9šºožÈuQ·gÃ8Ür ®ðDy|° œ¤›C¹€•…¥„ E œ„ ŸŒ/ÓþiËP°1meÈ쳂Ý;.’r˜YJcPú“ƒÒ¿yêOÁ¦±ðÖÇsÛ7[qnîsg˜1Ü¿>6sÑ»¡Ë ¨¸f{JÞÝ¡W>š¼ê{÷Úõù\ÂÚ¯væZᶪ­ú†û#i‘ÿð´•ü£ýs3´9Ý:üjµ+Ón@Ú:!3¢fNì0k/IýyN¯),s†ý”UsL²vny|¿D¹,¹>ahšSBÔпõ…=ïÔ9Ïå}­qVO¿‡ÂžÄÌ4ó‚A;®©ñi}bž„ŒG¹Ûj“«l'y!·g礀iìÕ#Ž–ÁzÖÑbS*´¯ëqk·îÓ¬C àý èFoU×Üî‰<Íh½Àd¡³¿Ý%õ¤Ç¹úû¯×>ùíú}éÈÿꃢË?ÚkRÛ j{úOl*8mý„#wœJ;.n]ó½¤_Ø'<ÏQTE´:é+,wõ‚·gìžû縒ÉÏ]uþQü±_üþ¨¨ÝaÐò½Jݭµr]AÛÛiüÏ=)ñZ$-[(T¸p¹ikYEÒЬX JaÑD±Å’%å¡ëY̘œ¼uÕ+|õYèÉÏòÿÃÂ^"öíqR†YlþyÑï«û¡!÷þ«³÷»Ot¸xpþ€BýGôÝœ’uÇÿxÿ0Îa¦©§@Ì•¿N™d býªŽŒ‚6³ܯ ¼úBÖ•%aÚtï!SÓ5É;h¾s‚º·Ú+“9×:¿í¸Û#ìeç¬;xÞÌ<ÂÔ-œÜSƹñtà¡ùÞmúö•ë–÷cjÂ×”‚µ›èloÙ®%• ÎÜŒ¬qrN¯šQ}̉[ üx"¡/àsÙ,œ‚Ñ“âó1^\2Bã'^šÅu<ÆÜ]Ì OeÀak ™º»vªD¡Ú DéQúSúÛ¬þÖ…掺•í«±„5>>/úý6hYm£™!]'üwÈãˆ6‡-Tˆîé{úsgî yqDx›çîùƒ±OHK[>ï*ú”FV¤A,ô:=Äç¿ÚŽa®µü©–º¡Ï.âM†a=ån¯ëïÞŸ¹[ˆ]nÏ!›hø-wom’UÜú¬v•1«ø¿µmWÕÍ›©ß‹Ô®.Bw3e[úh¼‹^5^ÂÕnÆ,ÉüñÄ|èú㟡Ïó”q{æPJ¬%ž?ÙS®ô¢ý_»y)Aë,å8W,®œ¼aô«•ÑåŸcØGã—‹EeÞ(C’„XÞÎ5b4|?'65š• * ÌtÛ‘º1,NÆQ2"•Q±næ†m¸x"—°ô×(ý)ý)ýmVêÀ¶!¾=øáb]Îã¢×£BB’šÂu|%üzŒÓÞg¹Ùd¥q3êçÈ;ÇÚ¥“ªàü1özé©—’Hªìˆ÷É̲þý^­—Š¥¸¶ƒÏ™âwÄzåá]†˜X¢€ž#ï)Æœ´v.ß‘ìP1Ÿ¯½M²Pöí ºÁÃÚúÔ_ôùÆW7ÁÙI Ò•Îí¥=T$4x’ÚŽLžQª^g]!Ö»q ûc×½hqë †ÅOj§,\\²éÖîѦGŠ: ›,oè QÐ7•vfbF;øÄ×+‹ØŽTvá7³^ŽËš>nçv·ÂÔŸ¶)I8}ö4ݦ¼¢ï©ÓúO3ò:Ù ôJ¨z§yp'Î Õ¿ê冀¦Ó„«â‹\•QðNm×èÿ¶YK«Ó¶/`ãmúϬ܋aR‡I]°žöô­H Âö0‡”oíµù×vŠ®o¸a!”Xîån•”ÚW¹zu”]Îp5n¾D˜ÅîÎnsoOÁ£ М0¦òê$ºçvøï™Ìü) GOñ;½GáEéOéOéo³úÃÖŸ…fŽÔ÷²ãO÷MÉ]0kÞ6  oŸÝm<²÷ Ï_ML“•O¿~%g‡u>³lZ=raÀ:cþ–¾Õî­ì- ¼xìœá¯;m æô¶Žˆù¦føîPæA¾l2÷᧺¶CL²æN¼Uiðù}ÂèËcn˜^®þ¼±VWV¸˜v¡uA8tàÕdéáõÕ!¢7 ÿ¨O¹é5ñÂ[.¶`Åa¹’Ü x¿zØêKÛ8™¹#ëÜcLóVÿjâììÖ«ôÔ㇤gîÊ̈PÝz w½#´{’Ú\S/%F[·â¨WÛÒ÷á—˜šëåuÓj¾?Öò;u| ŸƒIìí{c¥3~‹¥m=ésvÀAÕ_^–vè¶fÿ‡BEP!ïw@ʺV¸U®ÚìÿÐoÞ5¶CËÎÒÿ¸3¥ù‚p ÀPžt5ogXá¿• d1‚˜~4¥gM\ªx?„™ ÁŒŸì5ÒŸÒŸÒßfõ7=ဂmáyz›YDdžWNÎIHÙÐÁä€g(œ¦Ü“¥÷×ìØ?ô0&XÑÈŒ¼§Gÿ6uÆŽ¬.šÞ”Ò¢üö·ýýw"­ï ˆQ’ü¹„–lReH D‰Ž ¡Aß`¾îÌÕöÄÈý‡h Ÿ§5ÄÿM0x30M,æ7=P«mËܘJ (ý)ýslB 6 8Lâå_Ä'ä S*æ‘@‹-"ñË ³DܦóÇW²ÉèN‚O—“ñ‘ ät«V\ç³i ‰ $JHŸ >Ùd ¶‹Çd-ßh€"ºžDûGË¢™  @eôÊA2|b…醾Þó@~Äóñ›dÕDÍ•`ÓñOé¯Ë¥ô7o…Ò¿™ëOÁ–¡~ùÏÌ&yù×V@6G& µä $ÁwCŽÖ•¦âCòÆñÑ8ß½rÓwu³ ¹Ð”8.û¥ÖÇ?ƒ–¥z醙˜˜\‰9°ù¦ûaD„¿è3YÉj>`‹ ,‡§›è=€šqO$Ô¥@Y9þx ¦¹P ~®5#€Â[.üN@ 8jR‡Ò_—KéOÖ¥3ÖŸ‚MCýò¿)YlexªÂX\IcÃxIôÉË:ñl·Â\3ÇÎç0¹¦|@_Zný´@g©&ŸÁ•òÄ153`ÈÔ¢†”Gðé\¹* à ¬?š{1„ËÓd`&åñ g<¬ñ “›îÔÎŒœ€FãŸÒß”þäPú7Wý)Ø24/ÿY2¡u÷ø‹,MŒë"´eÙÄFUËG"ýIßéUa@±ØˆFpÖ[ NåjùD΀ϡ¥|—jš ñj~‚ŒàO`Lg¬ <€¨fÜkø•Kô_¨z‡ÿ7€ð"Ò$½¡Ó\ ,€Áø§ô7¥¿…ö(ý›¥þløË?#2¢Xiíå_WXRQÃa<€Ò¼3 $f nˆ0–¬>`,Ù’A¾¤‡ã1ŒÂ€°O¡Òzg@<¦«¡ &éùpt™¡ÉL¿e© ÎgшYb8nHê=€º @ÕN;üŠg²é Õ÷›ÍJ ë P”Í”‰ÿµÐ ¨ÿ”þ¦ JK­Pú7?ý)Ø2Ô/ÿYò^þµµQ„…H ãáÙ²HjÞ¢Š[ #$8ø ØB1ÁgÂú0"`»Y¬«¥Ä“ô5 3a…v/B6y&25\,‘fA/à09 Ïh`¸Hï4ªøÓß¿jè[6–f(̆ÿf/‰ð¨.›Òß”Aéo¹Jÿæ¥?ÛPý$üå•Y¤”4vacñÄVÃx¥ûH7KIHUa<ž•0"JóÚ‘bÙÅ¥ ãñµ|·®„d !Jjä#ø4T=‚аl²‰Ì2 ˆHëDÄù|Æ3œìÒ{ B€šaô÷L €ñà·dp ¦¾ÿ&ÃÈ¡ô§ô§ô·Yý©ßÿ¶ _õ#G¼ü§gË›òB©ã‰ùç eøq·É,5‰ó!†Äp–ƒVô øt©šK2 üWÅïRXýáTñQ²#=Ûm}~ƒÇ\¨ö¡¸¢{–‘ `C k³Í#„DÁoœÁ%Ý< ¡f„mX“8 (ôýý€Ì¨_¤6AñûWï¶l¬ÝÑÿÿO¢ô§ô§ô·Yý©ßÿ¶ ü:ŽY˜jÅ‘gŽ!0S@r$(@YA1¥Š††°êHQÄŒDú›ýa‰Oˆ£Y­þI´¸z=É !Õ^"¡„H§H¢Ù¢bÀ~Î ¥ºESÇ€xõ@»H;@‰ÃÖ‰ç§õ¤ÀÊ2`Lm„ÿ& ¨5”þ”þ”þ6«ÿ¿X?@¡E!Q"Åzy}:a8¦Ddb=`®Ú™Ôˆƒ*Ua@© 0–g5î”K"Œ–è_’ÚÐ;0²²ˆtŠ âCŠ2ëâ’ÍÌŠn¶‹ÏIHÒZOÃ=@@ƒ Á Õÿ1Ä"¡¹0\ „YY„@ª0¦•{7ç¨;«ê¥?¥?¥¿­êOýþ·m°‘‘…É\Hn)Œ× `È$ k]øvecG0̆d†Gr{Éi‰Ïð,J3;Ô°Ïv ˉˆ#E#òÈ<,Ùº ”!330àÃ,f’†o¸ÈÀhÔžð C4%ñü¬‹@û_…ñv!JJJ›ÕŸúýoÛ LÉQ1˜…5úHO3˜ýeP|ø‡†–(»4ÕìHP4Ñ»$µ!‡ž?~ÙnȬ÷öØgé€P€!«ä²¿ Êd¦YF+€Tlå0€:~ `ý1à¤@½P=Âèî³l¬”ÃTýeÓ¦`a”þ”þ”þ6«ÿÿYI³,€Ûxœí]w\ÇÛ×hìQ‰½Å»ØbKÐPDŠ *  ‚GçúíÎ\Ûët¤)ˆ "EìÆÄ^ýYÐ$ö^£±kÞÝ;î¸NyÿËÍóùèÌÎÎwvw¾;û<ÏÌ\#ˆÄ¦E²:íï ¥xì.~¬œx•ß F¢âínŸùí©ñç)<çÅøgÏÿ×¥}Ó:ãc³új—xwÔIêh~Úí'×F—×=îF‡¯¾ ¿4´Õà–ꀰ±ØÂõ€c#ȹ;¹G±a¹ ÉùÆu›¦ýlPð/½ ïìç]pÌ4ÏŽEp壔.ºSmö¨ÎqbršœC§ì6ê ž¾’J.ü0{c\Fÿ î|¯scå2!$FÙ÷‚ë'\û æ­löôÊÄŸ‡ßž]ÙóJØA‘SÎ­Ž²ã“¥ QɲH ™€íXî\á¼Uäѵ·sçØ–lÁ¾ÙBQꉋR_~aÒܜ謾P*ŽX‰ç¼‹~ÜA‹Í8;|añŸ=Â"½ç!þ!âño³ü[éW$ÿ}¹ÐòÒ‘¦"Ý{½‰ï?ÎáõùM kÇ»ÿ£€½kbŸ,„¼Ö[_-ÙG9 >x_ûª~3º”ØÊ%ÇÿŠÃÊ#£ê ÅŸUt|=ùÈÉ^“Û *Î0_ Ÿ»d•EåÓ¥Ó|×ûîØgf'ë—¿»žšb\·[ôiÃ>:Ú~ŒðMû¶“ãN×”„¾?uÕºc'Tg~õØ_“c¶ø@P)Í»ÍwTž¶v1ôRu=v¡ø‹þç^( ÔV ?éó¼mwgdÅØWã· »¹hï¡îÉ=³+r€‚`ÈÒÙ˜c™K¹Ën§Ý#V®ú~ŒkÉ8æqgL¹Ë„b!;…Éãç qĪB]ê·R·å.MzÔIˆA,’‡ø‡ˆÄ¿­òß§–ÎEòß–€ç7¨3 ûî!×? ï KhPC ßžÎнmŸX<ºé¸õn}šSOüðý¿‰ØÓï¼w÷{2?÷ʬ:#¿‡¿–NL~¹¨ì®òüëG‰¹JÇ‚“î›°û÷x邪-Ë?²Õ”3&O²WöÎ#DÅíÈÿ]/Iå}ú¼|VöÃóºSQç¿“Wg7N!ViríÊö¨Ó÷¹«ÕöNŸ¯š@0”•‘0ÌýËÖÛ?“E¢1CûÀòÞ½à¯ß‡¾éW8³CçœIÏÝÚá¼3–V¾y%{~±J=§<`½ðñqǺd¤þöàp›ÀS ”‰<î ]çÅ^FÄó'b“BTé­Nªƒ£’L^.gÞFüCÄ?DüÛ(ÿu÷Ñ ù/Ê­.„6Ë>¹Œþ}Þ„¹íDÖ…s!ÐÿõAá¿ÛÛ¼Ĭ7ž{ÃJ^ÚM¦ ù~lð†ºã¾m“žC¹Ù°ç Ûþ׿÷ØŒ3ftß ÷-6áÍfeçâ_zŸÛÞê:ëj͉žGžWîzO„üê?¨ŒL@;¯“hâ7—:Éuç^²;j³å›{k2´« Ô™èIv³¨´YLJÈç?“K›²å1!„‚QÃûÁ’7<`Ñì;C†ÝÍuŸ÷güŒwyýnEí Ü( ȇ+ó#k©ÿ‘˜åXá\é0Tq)lIz‚Ckè T%n€/€7ãK‹X®ùD BŠÂDéŽ[ÇÝd‰áíÞ; AüCÄ¿Zÿ6È?úûD'+BììðïÑ7'†_Ó‡÷1ÇÎïÛÐ@b$f7«ß¤þÓùzÉêŽúDûm¦æ5ŽMhüX•tºÅN“JÁ©If  0%zè_2 Ÿ±^gÏón½öÄ»ãʳFÍåU_«SöŽ;ÌwâJ‡=ºS>k•…gXïj—è…ù³’Ô™W—üA¥§Ý(ÛrLn"‘2ûvÙò`¤ý·ð@ãþpÿÔ“ý÷©ÂJöP‡oÒ‡>*‘zæd{­Zµ$ÄÌ+SÎe.N»‹b&ÎÝ·¿s»áb!𠂚űR¼T*ŽVE e,Eê²ÌHÿB.§•þs þÿˆÛ剭‹Cãý‹no¼ø¨lmÃðŽí“ïî8Ý©Ëý܆á=ÚJ÷¾Ýã`!ŒgFVœŸ5ßéFõÁž0¿™<·sr²Q-Ï)_•Z)â¸jµ/• ²÷ŸšüÉΞ§Òœ°3ŽfR»hÊ‚ƒ»=~¨ÐäBÆÏé0¨üM‹l¥öÜü{ßkuYØwÓûkrmFW=Pg¶÷(Ré18‘JZ ËÛÜ7œ8´QÄíG„šï¦ÁÊi'¦Âࡪ`=?}‘ÔÜ{sþìÄ Ã¤™! ©Á,àX:§ÂwSµhïYß<™ýÙó —”¹ã"L Š{Ê•ŽŠÃÀ¥òÐ5Q‹3ì/þ9NÞÜðÑÿˆÄ¿íòÄÆož÷zÞî6vº+€Ø­½w’åþYñS=¾àõ[ÈpÉy¼xß»ß[þZ7”ãM_¬s¸Áë×tºÒzȯC ãvã”7>Ý0Áê$ñiHõLÝ [W0â>‡œé¨—‰ˆu-“B¾˜³h“ÿ†a›.v8¿gñåó˜´tŽŠ„KB¸( B@šÂ§0@$f­LÉ^µLþúµLòÞèÙÿˆÄ¿íòÄÖ…±ÓÃéCÛÂ>j¯l( ±_ûn }7t·ôw½ñ¤L™Ó%øþ¤hö¬Àûus!ö]S™¡w̽2ízÛ«Ÿ"_ÑÇ·9û©õˬý¥]µƒ=PÐÍ!sÏ êH%K\dR{ßÇ0DºeÒÒJm=V|îØ.¯£šãÃÏ/²´ç"Û7®Î=½½M²Gvú‘JƒŠŸRó~às¼Õ!ÇáSTíz½á i?\ßO Úë‹–5~vvá/ή<š7,¥ÏzypøVZœP.\œ¾F@—8W8W8U:t÷©+ÿrY¿ÃenTÕ9òŸu@pZο¼+Û ("ú)3úD°ò¾Þ$¢‹Ãþ ´ÜJê#—ñºƒXâJóÆ“n¿”açëŽ&µÏݬŠ3,)®è\£mè ÁÞç<Þýûjõá÷ghm¡60³zrÑÌ;¥ßª3ˆpõ7xûª>¯É?ó˳à­ÚáµK%Šs)Sá²Ûq·ãæ€Þ…Mzz¥%s_ be\š¤(håF Õr‰X±:T•ÎúÚLg þÿˆÛå‰­Ëø»„ýÅfeÖ^W'`Wþ¡‡>\÷£épÊ#zSÚüÄ{Éiõ¼ðè¡ßÌøãˆÃ‹€“Ï/ž{)6ã™Êð³bcE5÷ãt¾ oHÓ8•¶$ùŸUcGZneQÑ¡ zæÊÂÖ]O÷m”Ñy‰Ìýø¦&vŒß¯O^–䨥íÕ;5éùöû‹ËºùJÉü—ݺùB­ä‚‡š\f\êu&£Ù=.•þ/={a†<4]JæV(¸|&†°ÿÄ7þÓ;72?׉ŠEp K²21?#`‚,ŒÉ'$aÊXÕµ¡Ívâñø·]þ‘ظð^Ê~©ø[jîĺ†áÈø–[ëv]K¾Ì#óØGéöø¡Š Fµâô„Ñ6¦ïØrÌ4“&Ù¢ÚØ×dù­‘|5òæ™D“K “,¸d§ßÇ"»ê€ÛßE7³ÜÊ]¿ÐÙ램F³dÂŽÌ}Í™TŸ_õõ~Ã’œã]õÝ©]çúý55ÇaÇ{Ryì¸õ>V{âê·ÚjGw;¬y"â_* W.&“1.Ý„Øç¥»óç4Y£¸=y œ²z½þP‘÷»ýjÿpRÞ”³6ô¿±¢B>'óÔpùfùª4a¬[i<ÆóÙèTá¼ÛyO˂ԑç£Ç¿Ÿ!PîòÄ"-oIž½5<$E¦ÀˆÕæ¹ÜvæûñøGüÛ.ÿHl]b2¦÷NªœxÝ¥Ža8øûÀ ÷e±34q-—7©y³ÊWN×ë±hñ Ó×âùT–±mô]çwíf]´Š¯VT±7s‚}``¹$G:nš:Œ¯Íó³»m¹™©ïìCÊ J¸zþúØ~ù© ‰&+€aé‚FÓ£þ>¤¯°[£Žv™Áá>¶ÂÞí¤ÚÛrHÒ.N1µzÒІ÷§Ô»Œµ¼nG©¨½»$ûï~ç.ÞŸ}»z,t—çJ`PBn$<1ýàøAï3g·œ5òÉ‚í§zÈ;¾â•-ânâOþk]Ê]HàX9óË“ÿ·-<õý–½~1l1!„PiQ)qÂhnñBDœ²8…oñûñøGüÛ.ÿHl]Œns¦ä·Ã½âÚëBx=t¬¬ÿ‰¼šQà7©qŽëÍ}®ÕùŠëJ<¤3´QÃÀ_.ù½àþè‹ë­@^ÚGs4{j…Ç_-ËöMq:žCÐ ^zÜr3+~žÖò+£²ˆà_rý;÷¹kRû×{¨‘a¢¨ê®¯¨–ÞžMÛ'골,¬doûÝ8;Rö®Ú)‰Ÿo´]“ó‘æ©ÓvS‘Éå¥M¨Æ>\ÏiµüIÁpÅò-Rˆc"È¿l¿ë§Ð=rw¿¿”>¹äwÿ‹wÔ+|{dÄæ0Ž×Îx"ÚµtÁ64zø³Ö»^q½ÓÙYuÎ#$*Ü  ùq1D¼ÒgWpH.KÆ¡ò™å>Aü#þÿ¶Ë?0è”[‹wUMÏ‚ÚÃpOŠ~þãí“k¥¿éãGœzCØó2=±nÌ…/fþPã‡a€løsï¡*‹Òø©ÄüuNθÖäåÕ–g dðyÊß>»,_™ó²—wžIéÜû—f­™ü¤»“‰“ßõS˜QÑùLJô¿yÈ‚žNöy÷rÐçWzê¦(oz»µÚhßüÕ?ê nÿb™:SâÊ£\™é  ÈdÜÛ;›_ž<Íf•¦°ç§g‘6‰8<åe·µ^p'½_ùaÎGÏ)iÒÊèK %kAx2ÆŸSâ[$±]w9U:íáïº!{àã[g[Ü8P(óE¬TÖù¶%ñˆ[&– kßÿˆÄ?âßvùGbë½»Šžƒ}j ý{¾<·ß”eŒ¶Øä݉#Raª.uÙR´Ç«MŽÊýý¶°Kþ—ÒMBk¡L[»~wX\h„7 ÿnyrʉ¤'N°¤&HŸ{GÒÍMû0¸£Û‰œ3¼ýèn䫞 ŽÎ4éAÚÓ›6O¤ ôÐRÓâ«.(>jÃlÿø±·µ_aØ9ÑgýûVq;è…µÉÌ.gWrÍ•³+J•ª¨-ý;­Eú,:¼×°$¦´³Áï‚öºžOû>Ÿê:í`ïŽÓÿÑžðœÜÓ§:‹m·VÙ·÷OõЏƒ®T:ññ•Œ«83䉸àçÍ£/ûkøP6ñ’oQfÜ»ìt‡ ‹´;Ë;½Â#¢jˆ T©Á)<̹ĵ|Å1Oý©rú³.›ªz·Š½”©*vÃ!*¾p±dëÔݱ<&¶µÒ'” þÿˆÿÿ.ÿÎVúÉ_r¥B>8¡žÒ°ßÿxØ+–oH×½-1.ƒˆøjà,ŠÙEÔó3—NH«ñf¯À·Ý² ‚‡$ÃX©)L2±-0¶Ì°ˆÉûçÄJeçé=7¯µ[&¨n MŒ¯. HH6N€-2r j €j¼LŠ‹k®x:eP´ ÈCÀeHÄBY­úÿªfÇÉ%ÂzhCw'âñø·Yþ‘غü¿Ã€8cIŒ¬PQO/”þõéþÌ­ªz\°çl×}Sa8¦ÂÌýzt¦åa8qÉ|-ž®¬ ºÔ4jh2¨ÚÐàYt‰LOý™õêæÕ(€jO ©AXš‰PÕaA#?`mxu²öš1ªˆøGü#þm—$6.TŽ…K$¿_#ü³U|EÃÈ Ú;=I)®»D{•Öx)'$‹§0ÁƒXÆ*+ŸÅ¼° Ý·9ÉÓ]pp©ÉºÌÈ”ÐÕxÚj½ëë{ñ SP§ødÿ3©þ3¯jUÔý+Ä–mÑXFφøGü#þm–$¶.ÔZ–@Úµ@r¢|³Ò%<¦°Axª ŽoÔSP÷0$ÂÍÑÛ©0ChŒÑœT+ã Z£[©CâãD²ê0 ›`z\`4= °$ºÆ ñ@=]`< Â˜êþÖ€e=@j õõ-?­ž˜ñ”"þÿˆ›å‰­ †cH‰z‡äF-JÏ’ Îa6O5GùlJäㆴŽaHÀu/0Z¤ ¨Õ°2C<ˆÄS¬4‡gè­Ú¡Âh L4ý”6™Dzs~äÑø ©öúz@3!@ФêÕÀÚþ³ª¬yÿ± ‰¨.Ýg®âñø·]þ‘غPa0ŽL\¿0 9ü£¦®– Ô«YÙly=ñê6X® ë >…g)ê„t÷b¹‰Ó$ ÂIÖÆ¸Áv%ðØ !$ÇSdºÉt¾@r0Lƒ§°`MàÕ‚6£§ öù¡F¨KL×Yc3¨0¦ÕJ”˜¯øGü#þm—$6.T[XKc ÃY”+S¿tê0Ö#Œ§i£ù©·þPãqYðxÄÒ"3#” ƒáò<¾RbÆ‘WS?Z*18M…ñ0jr¹&Ú…üÜçG j%ŽˆÇÀ«Ãú@ h5‡é MªîÔZ"¡ŒÄ5PÏO^_TkÐBŸ þÿˆÛ剭 dŠ$uãn¬*_® {‘x†¸xJp†{v¶f4«ñ¢ZÈ e˜{ËÕ[jŠI|õ U¨¬:Tž¦¶$¥‹e"iºÈÌ c€'`Ü8B½%¨¡Ð$hVP&-’ UçÆ‰k ZìÄ?âño»ü#±uõ ã^Œ¬P®·p·~x5‚´C®Û1àl¦¬<`Ï)²ðaOáéŠj<’`º“‡^]Û¤MˆN2]¸ÐØæ01uŽÚ’“¯ïÔj@Í$`~ ÕÎeJE"N@¾ñÀ·¾)8ÆŽUÕ²%¨µ>Aü#þÿ6Ë?j-‡CmˆUû[x±óE›/[}ðjÁcçå¯2Ð <6G.¶¶–ÄÌÛ%±tšÂ³j<”ª°6þ9±æ>óÅŠÊ‘˜^ßt‘©mÀÕxjKP¨çÔÍ2VÔ¦æõ~,šœu;Ô: XÝÍTÖ€Vu+âñø·Yþ‘غ¨Ãp°kq/Λ¿Eiü­Y¿-EÇ/r§ÌHƒð˜ÐZ -°ü…[ƒÇ²dÖÆ?/ÌÜö êµD¼Óë–ØØ*àBpÄš0ÊżÆXã÷« ê)í* ¾&¡V3+Eêˆhõ¦`F ÀºÀ¥ó©0¨%±Î âñø·]þ‘غ€:ý2(Àâæã[”fVœh¶%¨‰,µ^ òÙd4˜ ÔÃõζ¶®WÆ“HD¸ïZÓ<ô„”cv® ‰ã%šþ2¨é œmh`å"¤®Oý²(&0ã¬ÙÄhžÐõ¿n1¾¨ËZ ê—I-n Z+ˆÄ?âÿ¿ËÿÿW/ñ-xœí]w\ÇûÖ|U"V"¢±Æ‚,(K4Š ¥)J‘ªT¥\¿Û½½NQDAPQP”"E@ìblQ£)*¨ÄnŒ-öøÝ^ã:'ÿý¼y>Ý™yvv÷aÞÏμïÌuÀ ôÁ©ïCàºòûWg tVé5yR.i奢aÚ —º¾ôÑqæ“ÛÛh¨²O ÷`mõlO˳æÑ37ö¨ÉÑÂ2È~¾­©ÞËØî?¾ÒéÕsÿ–T=µ„çT°µ–<²îŽ™îpŸ¾1M9—FÝÀR«èh1W:²qêG¤á‹RÜîŸO¯6‰T”|\j/;üÀì&=˜0“<”H=²?™éˆô'Ö ý›¢g"V/Î3“6 ±?‹Ž !Ù;ù¤Gýw僮EJ\1à«Æ›RÜKS„ëœ+SŸîQä±çž6)«ÞléOs³rb¸‡‡°äâ#Èña“JþÑûî@ý¡þPãÕÂÈZìX͸qdu²ö ߺmëíâþí|íÅ`p…Ið´ÇoêW&èk&âR¶ÕÓ&ÍN¾?ðäýìþœDeoŸO;zC0©îtÔëGÞsºëô{Þý¾öbRΆI§.Ï›tÛŠÛšKõ·úÄS­¸z“]½òysɤï$ó~N?2×äRÃ89¹^ö*c*fgK¶?=XI¤&g¬%&pp¿û÷ÅIßÈ›yö÷ÁîL¾vh mS–áþj$¶!fæáKömÏ+´¾ç]ùòÿýàȲØðRL2†;íç°Ø„ÅU‹«jk¢ï{|´Ý€ž¾s«`³y\A`b~8‡ØÍm¼; êõ‡ú³þÆZ½بN¦M9ZJ‡G :g:ï X£ýûY ú…•nwšCœ(´ñeÜoIÅã´KÚŠ˜×WLDLNGßàªàqθo÷ëlWÖßn¿M8u#éΪ•»½Çh`ˆ1ôÛÜùܶקNÇ\m͵ÁžªÝŒåß©Ü_öKéÚaI}|Ñߣ¯ÉJ\ÿ›$;júvæ9é‘_ÐaIZ>ˆ]J¤/ì{']#?¦ÒÏÚ_®6pÂòW‰¥Ø¦ùf`y!_ÿÛ4mϬ“³¦½p*x‹|(Ò¯ aevâê­Ì¸eUBAŒS¥ÓÀž{Õ8Ôœ~rµáúO-Kc…8‡ÇC"6÷ã‚,Ûzw þP¨¿ñêaìY5,}ࢋä~?kY'äÎxQz³1ד#<¢ÿê’Ò¼oŽéª1ÇnÁ±?/ÔQEéni3ÖvK·•lO3û¥# ¸ÿUÿjºxŸy°C‰Ž ƒíguýC{QòÐÊæ¿Ã|2»õïNyî°¯{žQ«¸ ;­|^wrûMÙ!%çaÀ%G‹Æ—»$§½Ü3ºÊJÞ~ÞGzdS'ÈxR®øé?‹f3–¦¡¦<,ìö‡µMËÎ.ìQsËÿé–Và{}øÇ¡9Ž÷Òg·Øe~\)tÛ¼Ë%%ß#--$›Â\\¾¼Lˆ¡””ÊñËýéÏæ¡îc÷ÚíMÁ\Qãr’V†\ ŠìnÀËàþP¨¿1ëaì˜ó¾Øyè‘ê%[Uóm ÆZæ[<áW;Oû–¼a¬¼(جµ,g–}Ó<¯N¾“IâƒY;GµlÙ¨”¹­ßéÑÌÜýê1”Ùé¹~<Ä,>MkOS«ýó´s­ï{§0ÿá.ó;ßük$-Q–]0!ZÕa ƒïp#˜35'E~8¢cHß÷·†Ó“ˆ³K7È{Þœ§ ¤—t¶å-9xó› ‘Þ$#Æ+=£:‰“…Iø­qGÎsïb»ln8ce‹ÿ7ûFúR¬šeŽ¿Ù¼_QTk“hÒŒmŠá„nI­u©ŠÇiŽ•‹««köìönæýÞ=¹Ðq—±¹N(ÖÍ€—'½M¨?Ôêo´úC9ÿm~8a@‡òb‡x¥ÜOì<:¤³ñBØ5Ýrå¯ÁöçÊí´U}]w•j‘J˜g`øô¤z2_‘÷_qò@¯WQ×ò½sSþó¼>ðèm–*ŽÒsËSí\fIS<&3!? öm[½™tsêùÔ(µšóW¥žU>_P1WÉ#h¹õöŸ:ìCð/½<(7ç~Ü@~»,9¸Ú{Åq"­Ê”Lšp_‹ÿÞmW1Ͳ`Å蘄ê‘—c•³þœÂÈç,Y8æâWgËrúßEê¼cJÂÈ 8îVºžÎt¬pªZRíX³¨Ú¡våˆYtp§k7ê8|n¥†³ÙaáGðò¤€úCý¡þÆ«?„±ƒ¼wÉOO×åvñ}­øÊµkºwôàÔ¦š‘‰úˆ2P*ZR¶>àóDcªB‚oXéä¡·ëtâ¥ÇTï;27^\¿¯¬&0äÖ'Óçþ•ùë´?ÿqoð[ñ»¦ Îüá²rQɺ©’:w'lë»/<ÁU2ËuþåEµ ´©òhÉ#üŸ·žùî*.ç0Œú"½u*Î\+=réé±Dr½x=aäÀ‘’ àW[ Ój±bÀì¶'|¬|:;4éÌB,ŸÒïâ9ÿz³+ÇʧŒxºv?yu>;d;•ä^)à‘œ«X\á£xøFûêºÐß&íøvO¿Šjg”ƒó¸lÀcÈÛ“êõ‡ú¯þÆ?û¾C~ØþÓÇZé¹ý'ëæÇ’í½Ò ã¯r6}þ6ûÂâ7ê%g•Üþ¨£ŒP¯Oe,sSÿ'û$§=ÃLùô6£ôê¶1d †E†=öá™zÒ›vjÔxŸ™vK9ìÄ)Ò£æf,/Éü•ºÑ³ÎK­æUç•Ï™gŸ)Ÿ—zù5|Za·;íJ.VµÔɲwÛŠdAÀUÇ‹¤³™I aDyðá'÷ _O?È´¿ù÷ø©¶-}; ÆÎ[U®ÀJB{]v=üÝ Ÿê^¿#‹ý S—geyoL É¡0œÊÓh w<àHħþsÏ[+k“Íkq>?J”¹!oO¨?Ôêo¼úC9À¤[ÔáCþÛž)>[Ò̱,¹t5y‹Á˜~'ä}E@ô]Q†rîÊŒó ¨(§Í9D ›óÈåÄÔ¿JŸ¢DhÌíÊ'Ó„umrĸ„ÔH"nÿ;1ôpLçæ(õËë´Nq:¢“ß´ÈŸpyKcõ'ƒ{x‹°w‹ºUªÕDª·R¹ˆÿaJQÅÁ ¨•Í=Îþ½Í««_|QõÙ+²ük}G<“…Ž¿'™ÝDüêˆtÆåW óÞÎâ$¬ÿX“t—_F]éóo{ÞRá‹Õzü2üΜ’qœŠÝŒª®ÙuÓãK— ´Ô„(ÏR®(vI%1èPíXëXçÓÜ}Ù£Û%ï-ór\P—ÝÑ·× ¨?Ôêo¼úC;XO8ÕuÂ#‚-n¶õ™Ûnßð<©ù5­ÈööØ„ÿåný¾Õ‡]o.Ô×>Úãš§yÝ6ˆ‹Ü=lf½×6ÃrŸ_ KŽ@/¶wÞŒAOò»«ööËÞs¸)Ú¨â&ÏåÙ»ÉOÀPŽÕÀ‹]‡|d[¾´= VÕÒöúE•Œ3G(=çºíÞCñ±“Ú· …µ&[žo6ÄYv7£³ŽHRGÁ×ßi¯^Š“˜×;ÞŠ“0óñKŸà‡Î¯ù:3ºœ†ºœ„Õ;›øtò®ioçäZ=ô-/µM´ø—Y¹’Áçq< ×£d§r¯}ñ›Øq‰ kï©w©kZw¼Êçòyÿòö”õ‡úCýWcGtú óˆéf—‡ ̰á‰~~¿ÿóøq›'ºM ¹7·A>u7òÉù×ÝÑ·€H ä‚1 ÓN\é0+ÏÆaZ´a3î/k-½eÇ´ÊȽFNU‰6w<Íu=ˆÍÄýJ±AÌ3Îî/—ØŒ tñW«Éʨ­bWº¬ëCS:Ý€†ò™gú.ãÚ0¯£kwy,2ØõLæ 6J–üW;M²Ø_Æ œüMʈP0³ñ^1©ëvñ^‰¼¿JÆ< S£±KSêfM}šî0¡[Ê”7.;-šã^{I»bȾżu ËÊ…šk™£d€/¨Úg?#d>÷OÁnÐW½>@ý¡þPãÕÂØ±ÜºkéÕ¿K§ì@ç#Çÿl¾÷„vŒgv¯k»%§¬^È»’1†¬ã‘ÂƳyï.]Ÿs*arŸé1>êàÚSqìÐðâÞí±SŽe·ÖxÇ}ß½E»úÃÑå^éUŸQ<€?&ð¯íꣾƒšUɰ8¨´(x¥eáU ‹ð:•w÷1é‡w¤XYþ£O“½õ(’,þÁò»m-—¤³ CåÐû|ƒ8 ë9Þ[þëÓ¨ÚÑo[ag¯M½n³Ï)ãŒÜ}üoÞÜÌá¢*é>Û“|·ˆBr)4—òd@[\áTµ˜˜¬q¬£ÌÏgÇ–}8˜µß ´ký/Ôêõ7^ý!Œ`ÄIóQÙÓ¼íöüÖ¾õÏ6—.ìs%Š˜r;›ÞqÇšz·6YJ°=o˜»ÆlÐk—Aõ3{¦cÊÛuütåõeÏxÞ#WÅ–¢ó"¨×t @‚šçöQÝìáñ¬.yKÕª2cX« Â:É>襘xà˜‡8YÔø«‡U‹(¯Ý²ü5~geAÀÑ SQÉcØÓ"ÝD¼¥I}›ˆíǺ÷Ç€÷Ü‹W·û‡;Äfa8˜}´WóÖåXeô×g×ý|õ• G_ß=\3 Ý’¶y¯O\ƒ%ß\çªx„p áØ×,:4ûõ™3ÛN-lèhМ« þP¨¿ñêñ¥àú0ƒügðéî½ÊÇüÜ‚« }|fÓšØþ¯Kc½¹?&ÿrô¬ú,>ëq˜ÛâoIÖ]ôl)ÚŠÑÛ¦¼JRÎ@>„ŒžlƬÉ· ïb—f§‹^aét]5t z»èÙ|ßCµøãÎ&î¨d¼ ”ãšé™áÄ>ãh×Õ-”•\_ê?ÙÓY*|Q$ʹ{n‘$fizížÕâdØ»Ä)ìëñ«0,)²‘™ÚiçâW¶üÄó×nÇ⃰#þç-®êýå8Õ%ûAoÞ­1([È ÌKãF»T¤0QÇñ€c­CǾv¾—(É©k€ÝF¨¿4êÿY€úúÏlóÕA|ɈH÷§A+hTRÆ>8Îçvß²U9Ö—ÛÁc-Q·éyɨôŒ×óz\i›¡Š«ÎîMN ;a@åÒ_;yªf‘²»e—]zÐOº‹ãðuÑ æ¬Ò0O´}ÿý°(¯kÏb•lº³éÕ F²üJoÈÕäªt‚ZÔrgøÍÉÌÊ¥·ÜdU"¾ú%98Ü#Vòp=þ½j…?³ÖD€P“qÁ–Örmxstu—C6»=mbÎÛsÆýØð[®û‡Þ©ÍŸœ4è¹"tmQ$™´‰ãµ#¢ª–p$ö9¼"¶jӘͽfíúCýõ¿;m€ú!úÑÿÞ ¾päŒ|ððtáç²ÂOï.l®ÿvራ8Ëôʼnüöµíb~nÞ ;·¯Žö|c‘Ýv}5üBa¹Ð‡Öµ¬ÍåG`’[Ɉ1ê¹¾VÛæ¯JJT÷21•+&‡#kŸNJâ¾¢E9òc“M_¢—ä”-¹.ŠIÚ'˜üý"‹øùN . þ“ÿÉö@h¤$GûÓµ=vƒúCý¡þÆ«?„‘`(Bg‰¸],!ûR “yºŠ >3^7_~•HŸ¢d\Ëï‹ù4–v>ºÖ«‚ߦaó£WUôµF¦è¸` „ÊLà©´lõçEiB“€2eW€Ee²“x >ä½ ùûS h½@Y4z"_«£Ô€þõ‡úCýWc‡¸²¨¸€‹kýsÅ?® …§ûoIÌgÒØB|PŠkæVí}àSq-|€¬âlÑñe«Ê§¹ìIÐ×>ˆ u²bSÙ(“Ìq•BQw–ꟷÞ?Ii峨òÎ\f4äCMÀ&øqøê: @[F ,N<¿ êÿP¨?Ôßxõ‡0v î|GË$œ¸û¯ŠÞ•ÂÓ;¿Gð)­|y fèê}IºVà|²PƒèKö¤²mˆ¸b!éiØ :ÊеiâOo„/Tâ*_ýwÄÔ€Á“Ÿ«ñ[{½Òd ÜÈGJ€B0|o§[º¸}Í)Nû?Ôêõ7^ý!Œ7^`Ð H롘*ø*.@Ù°@þá¯Õˆ‹Ïáàr uJ,A,9Y >¿jpÿ‡úCý¡þÆ«?„‘Câ†C…jn8€Ð‚#v¤ñÛŒî‘L"ÒOÇ$"Ýomi¼¾Oy‚OCUùÈšˆB]nGU2uU>GÌGâu¶›¡£uÀdH†eQ‘_K怫ätL:¢à·º[c€´¼5AÅ&€†òùâ÷¯l "®À¢2yªn@Ãû?Ôêõ7^ý!Œ‚r¥Pjhø¶õtŸÊr´ô@ñDZg~Fž<‚Oá*ñÓ;=Ó ý?9,+qÃqµ»!3|³®+!k×ãÒöQ&‰+wj‰Ò(B€¤g,œ%çD‹ PÞïå¨Âb"Â'7˜¡óÒ–PV,WÕ ø9ýêõ‡ú¯þÆPUÈW¸ÁÄÝ?<4o½À î¯…ßZ@uÆö‹ÚCˆù”V7  ¸èvªIQ9)Ÿ¬Ý È ÌU÷çÉÆ$ÉyJ'%Èøš@š[ù¢À|% 6 íø2 KPq7—½?­À#Fl¢@ÉH}^ÿ‡úCý¡þÆ«?„‘ˆÿ‚è ‘Ì PÚšà­N%}óénDÀŠò)Lm;“ÂÐd|tG¹®¨]5ZlìfÙj\®¶–G$8K—÷PqÅÚa‚O%ÖÒˆ{E n1´ x¸r1Ž+øJ.@å ÕU@@ñþÛi0¡RRø Å>³ÿCý¡þPãÕÂØ!qÃbJü1J‹ÊÞ üŒî¯ÂoÍDÉni;ôîÏ¡Æn4€±rõ„ )³¢)›8 >hº!ш]7X”äÖO1Ÿ7"ÆB4ꌔoE¸7JðLa>1@«€4 €ìýé\ Ô&P&M”›¥ÏîÿP¨?Ôßxõ‡0vHÜx\Gé‘«6g~^÷—ñ)Á§;í\oûO -Ù€MÙµêõ‡ú¯þ_ @;¿J ŽÀv¦¶¹ï‡ÎvQUº%(±ögûÃüx*ü8ÏìÍzvU&RíÝ7[É è1tš VLšZ¸ÑHÙDÕ5@ “tt ŸÍNTðõ•Õ@Òí@ &àÊV«Ï”IÆt¬†nP¨?Ôÿÿ¿þ†¹O ¾T0´­Æm0Öù&o">ˆÒ®–¥[‚Šù€ê‚•‰>ëó_ʧ¸flp 2@Hp²úö^7œ@Á̰-:;™®±8H²¥§P¤Þ¾Æ@-H:(k?NÐÊWlÒ ¤×ˆ!s£bí‰"L#Võ‡úT]• õÿ2ô×üUccÂZa{&ÄÝ?Ú'a[<Û°_öÔyÉ– èZŸ]éí˜FD£Wìákl ª½%duz²F-b-5^¶%'@òtÞ ó´L4Šùëd_¥ªÙ2µ Ù  ¬ýÖ-E•vÑøUPÙN j@\QúþÛiˆÍÛ˜P¨?Ôßhõÿ?îÈ×! xœí]wXÇû7Ô¯cﱓˆ-¶X1((‚Ò¤s\ß½ÂG—&EAE¤ ˆ`ŒJÄX°+¶¨±÷’DÅÆowïnïöîÀÿ~¹yŸG§ì|vf÷üÏÍû¾3Û ƒbÈræ\§¿•¹E·äsë¼ù(«{¿ÙœÎë²éãO8E~Uç o~ý¬/½Ý~÷ h1˜Óûf‘÷?—݃:_¦»-ZrÕ¼ÄH³ÞtßgO;g&Á°]ŽjÁ~løÒ‡¦¾K«ð¼ žWG‰›êXß'¦´J¿G¥è\ä-Qd§V€¥ÇW]Šž]œÑN^ÍxóMŠ<ç+"Ó{ýM/âÉm·÷¿ã‰W«ï}0lç¿uËpµçý²â$‹‹ó±,·kCNÚ=»_¿¤©ïe½ïSެJßjŸîã±…Áµ,áb Ë.Ï¢Ââ€ÐuÛƒÆïÇ@þ!ÿƒåÿªÎ÷å¿.N~ÞûûýO¬¿­RüþýòØì§[vûœ…¬CNßnødâ×VôUÝsjÚeFEÍ®hh/l)t¾•Ù'+/ÙŒX™çä÷J'žw÷´[ÄCš ü»Kë7~êsW {åØm‹¶̹±ž¶~ʺ¸-Ž©…žWšêîßu©£4šÍ;L¥8ïQçÊ<ò1]±0p‹÷ †}Ýögyµñ$þ2ñ8HfNZÍÏ“cÝ*ñÄ£•‰?†|p[±Æùºên™GkVb…¿ÔŽþi³…ÿñÐþßm÷Ê)/Í"æEOQ,Kì½9&ÜÇvŸTl¹ÏªÌ²Ü¢bÉ¥Åa ¬!ÿÈ¿Áò¯:0((®¿ŒLšm_Ýóæ":™ŒsH~k,"tÆú5ƒÇDU»w?úUÝ3%M™o¼Í’Ùé` ‘œá÷ÒL*1¿íæúŽŽhS¦«—§]LÒNÓ^ @ß—„ È~¸ÄúÒm7è™|*L@SsÆ(ý‘“åŠß«ŸíTÖ…t´6 ¥´ K8`¢RlSòiYcáè•{÷*ߥ•½ÉÁ°…þyòÚ„ôïä¹YÁÆæd¦Úe%±jØËpOÜÆaØÙ³çb\í†Leq±å]œ±ªùÕ3JÅÓ· >W_‹¾^¸,½ÛpÄ6¸Àƒ.Xïç³,K¬Ë¢8R¾„·xÿâJ‹ÁÈ?äßpù×ñÖ „L}™ëZÊ ¹™ŸÑ¬æAC–[e-`zä)¬Xæo2殽r/[ë¯g’2ü4²ÉºÞüø‹Œä–ÁÍ_$]Ãs ¼?‘ £ñ Zû}c_/­ÐrqEG—¤#!ö¿_7^Û Æ$ïô)¤©gÝIºÕûg+YAÁ€`¥ôÒypÒŠsh˪åù§-€–gxĽ­¹Ä˜F+Xë‰Ù£ÈÌ›\‹~dfæB$›ú+€õ cBð¥FñÉtlZE©•骨èìÄø_—`¹ŒÏ÷N¸í~ÞïpŠYÌÐþÅ ·˜G&;hM¡ˆ-\^Žñ‚£,ö[T%¢ ÿÈ¿!óÅÀy›ðÔ’]™´Ó"\cÆdÙžÛKb®–^nlŒ|N¸Þ•ÿzw΢3²ÑÊËw©ý7]Rئקš^ñ'=~Ùøw3K¶j¿÷ĤÚêv»&œ×Ö¢†fNW?æéËPŒõûm}{M Z\CVVWo¹AmÖ/âX’JñYIß%›gõÇ.ýPìÙð¯£eÛ—"¥ïp¨ëgùÃLsìèJ¤[ýH¤>Ç~ØŽ'ëFò0¬¯°/dŒM]0é~æß?­Û抵®ýpN®é3ËÜA·}+„6©G¦„åÙ‡ÅDÅzÆðÀ†ÍÖ¥ˆLÆ“ð×v!»€üCþ!ÿ†Ë?C‡iý†_è4ü}¥Îf,ûçbtÞÕœ©’¨g÷hàù&šþ£Ë §!ߟd ™ã0†¹,l®ç…#3^5z`ýܧ±¸Á¦>!Õâó²û{èÿxõÛEmµ›qñv~X¾3Rê^·ƒþºÿPÛÞ´«›;¥cç×ý/¾­K@NFЀcq“© €†á]Ϫ–Ç>òjZ«ĸdúy^ïÓá¯~æ÷ÍÉkù¯) ޏt"Ò9H3âòëK"ðĹS_…^¿åaXù_œ~?u|=táçìŒhwiíܪ) ß§Îü8{‹É3§ü*“ðÖØ%ë˜ÛüÀò¢(‰¿MI,ȘÖÅKG)Æù‡üCþ —(.`ì埪“ڜ۬½Ûk˜‘_øá_üœÓ5ðãë<ûl|÷Ý•ˆÄf÷É_•²Ô‰}›,L¹¾êe+›[¸æ@9W LcV©Ô˜ß™S)zý„£ÙºGëáÒ(Ýw\ð¯àä öŸïÜi÷2YÌrÏ~JwÁö„Bflþi} ÊÕ´íJ\M”ì/ÿ“ÚÌxìÉ*ÅÑ%Þ*c7ÿÐá0fõ²û—ö4F+•iyì/¶½SL5‘ö¾fô?"þØ;OÖv싯Ì×åT`ØíËA¸V»w¿9ž²›3ãЭɹ?¯º1Ñùì»îVÛúÞåT¸{æðÜwpd¡è²Â¤”)µ*µ,ÿ[9È?äòo¸üC1táÝA«®?ôŽŸ¨Í ÇåØ%1 ~˜ø,šÎ—Æ{„än{²‡Ÿh¢Í §.7÷lmß:K^â¿â'Ø?{Ÿ<,T7Œ©íZÝEéùÈc~z5¿$­—Æ^¦»²îáúœ“«‚Ü:äÕ\¾‘N· xë m¬¬¯¥K™|ÍzsGõ`í0ʨúd—üH} ëŸ_¿¨Z¾X:y~cô=’ÿ߃=Ý-Ý«Z®è¿Ô£ãuy.ТŠýãψÔôµÐOÛ÷ÃÕÖ.íW ëP‘ý=ÖñÍœUÑËÚ4ôh›b‹íg>ytœuNüSìÈž{Eö[“’âÖ¥bþ+öI"}—íóÚñ¨iHÈ?äßpù‡bèâ+ž9°bÖƒ²Ù÷hÝh˜l<žf/Ó‚vEíhaÖl˜¢Èrõ0oSR4iôÌ‚³w¨ÍÞäWìV-w1òhÒÆŸÄO}Ny/¯Å_Ï®>,¯ýwÜ/òœu‚Ü{Y8|¹ÙäcŒ%ž¬i;¿‰çôŒC61~·›eÒïÍé¬ ¿Ý6qª ·‰>êvÜø¼û¡6uèÍe;¶YE5—ò$‘~I\æ²âŽXòDuLÈ?äßpù‡bè²lp§ª•ÇÌ^Þ¤ÙìÂKù­ýÞÒô‡O׊·Þ:¹ÕÀÕïër›Ñ™—鸙? Tµ÷­ûÎ+U(k{n—n(¨=öüžÿ8z§IÇ ¯?Ö³&“RíqtCál}'”´;³€qyÎ…[C>õ]‘¦~µr`¸6‚¨MÏꦋ—Õ¡øÁ_ÖMß~ju…¦f›E¨”ûlI.m*×U­&R÷EÚðñŸ²T²Zºçåm2<õ‚|QÀu ) ÒÑm2~“խà öˆ œ’>i»¬úwÞòÙ§sÏݦaÛÙÝ/Ÿ]Q5ì–]I¿ë¾•a‰ß>CK™®|»¢°(ïÀdqxà{êÃ@þ!ÿÃåŠ è[5·W« 70ÕÝpüì·?§u\üqY¿Ëºðƒôngæ«ÿX}]-¹^8îã?&Rñ#Ív1éPë¡Ó]ç:ÉžÕÍ#›¦ÿñÕígö93öÊjÊd{úëí?õ…&§¯÷,ôÀ¦xPV+túËBíHÑukòÏ,¦ƒ¡1–ϧ7>_mžúaχÕoÿ¢¶+l8CÑ@UåVsšJ§D}äS~Öé:éáÿ»‹ÉþGš o;šä2`™™“X@úv-Š' ƒðEGÆbÌ1Ù wòÖô}ç^c'í±=îu}oÎ+šðbÁÎ1÷ÞÿF|’O>Ó}'×'ËŸcS- ^¦®B!ÿÈ¿áòÅÐ…}Â;8ÏDûS fȾÂòü ?îþ™6 ¦I8ç<ù‹¬¬°žºµÖõOeï©;¹×6lh³r³› “Žì·fȪŒ’iðï¯[¸×æo¡ UÓ„¯âE˜cúlŠíÙ Àп×6Šuɾ¡@Ýô'iqÝ¿H7ªÑoÿ]ðV6ÿÁt5 ’ø2ç‚jù͈ Mo˜qÇÚQ¯wl{´†¿WðïÜ)SXèî§¹ %3F'’{‡: 8×Oì?"oÇ=‹/–¢;ØËßnÛáé÷ÇI…íé1/~Ü6«ëØx³w–ÛÜ .g8eÆ9lNpÞ,ñ‰¨ÃŽ/ù‡üCþ —(†.^¦O=‚ G]hšÈÛ{·òÜ÷ÿãÓZ/ÞËÌñN'ÿŠqZ×”ë"¾œ_XóNóŠ{HÚÖ;e Ñz–ÝãxÁu()¢o×.˜SÞï²f•»­þ.‹Ÿ­zAd‚ãº'ôßr±;Å͹¿˜ÝÖ…¸öèˆHй”™ùñhneõ V¥ÝT›z Zn/©VëÞY_’xºsâWº•⃺;]aŠ”>?+~öO—žDúqôã‰gû8hž˜úJÆ0[† +ú§õÚ[©‡ÜD7ŽÍ?4uîƒè…ŒZ¡Ñ’©›Æ¾tͳŽ?8[ŠÈ'ò³5¥y È?äòo¸üC1t™×漤ëÜã+µFkÝWc é¾Íñý›Ú³Èè¸Ûþ”g/*·kmÂÐ z<É…Ö*gÙ¹Ò̶ÕÀ÷%ÛŒàK>w<ýYëÍW|›óéËÁ(Gñ­'™'WŸÕÚZ!Þ7nù>—?Ýê¡›ö}pÈ铪²gøý•#£èÏH?P0†Z³î{žÿèÓGEQŒ Â.í|TË;ªÜg4•òÍ? T柘òúÜVBôÉì®±¼r´ÍHùGH.tšJ. ÞÌ}|OVÖ"†iÂ(ÍÇ0¯õ×°'¹/äwvÝøôdÔÂÅX!¯õÅÿšú+ྕmÆ‹ÂÚ9ìBWŽÇц¤ohŸòù‡ü.ÿP \ÐvYÝr}î–;’n8ô¯nYûÚÐÙefÍ;à í¼³acpïš²•ZZ/öèz^þ)-øow=05åvÕRÚS7ÇI]Cº[é8/ Ú}®ôÁÂVGgF8ÀZ’¥ãô/…psñUX#Áؼü™]MNLh Òõÿåð”ZàåUWÞ©¯ &qÂÝŸØž®b 98m“ªM\·N·®K§F[èŒW·5‡÷¿¤‚§°s9ÀìJföM^M.m^Íj ,Švo{¶ÇûeÁ0çåVm°aE#r˜q65çÁ L;¬Â³¶ÇùµUß^ñ=;7và«Àâ<ïí!!+´œxù‡üCþ €UÏÃ. ‹ôúƨ7pdW„C_Öb|ã}p<›ìe{h?®¥Œ¸g‰6?\ÿqNޤiP„Åã‘õ)¡Ún¸\:88ŒP^$µÀˆ©m„rc>&RÊÆ”x€…ÊjL1åEB² Àˆ&(&þþIþ^0L öO¯(ñÈóò¯¬ÿÏÿ×}¶ÊEÊc ¥baKf0>ýƒV s"B‰¿±¯À«Þ C˜ÎÁYq¡-ÇŽMF’ïŸ% Ó×?à¯I À8ž)"ñ¨w¬TëMø~ ´ >3œ"’‰…*H”%£¶\±ê4|ac`|Jà‰ñ£¨R1T ¤fäS^S(Þ¿£*B𥾆?ÈS=äòÿÿ™ÿ¯£ ÊFþ €%•ˆÍþK€ä€åD‰‘ø k žz34È.:!ZÚr<ʰÍýs™azð€·rg8}"ÃñÀ?LK¢3ÿh1­þ`ÈD—! Sé_s€ò$ª(_e=xa„ËÇ€+!ñþá¡ I4Só“"€üCþ!ÿ†Ë³[Bù —# 6sâÓ?ØÛªlOàÙáÍÆ«Ýãì›Îã´PŸ5%aò)pØä ÐÞ˜k“/ÓjÜÃñ¬‰0‹ÖzÀÒš(•b8ž)i2j.øÊ^( ñ«_€xbüJs_£Á¢„òѪ)Òˆ‰KBj.t‹òù‡ü2ÿP \þ‹”ƒ†…6ˈ§1ý[ˆW»`Ÿ±9ô+ð€ç,N—ÿÎ&úg£2xÀ±Ü§Ý¸Gâ‘p†`“Öà&ÀcFÓ^D‚£‰Èg!ýÓ,¸U´ªÔJ<†”LM(&>Àûç¢a"| Ñb À ÿÈ¿!óÅÐ`Ÿ-’ŠôÏ@|ú3Va»¢%”_Ûž%n^MP–5VHxæp¼(¬%xÀ´ÎŽSN¢¦X;°­tÌ9>dcL¢Hkdc"m¨ `‹ÅÒÈ Sº5¥„Q-€>ÁñþÅ2|ü1@M @¹P*SW¸Ž@¶PBhšH ]"h|~È?äò¯­Å›(†.„Œ­ß Ÿa¨·#ð¬»ÏÏ1+^,ø <hW¨“KºeÚð€µb¯Dçq<{ívínD4(œ>:˜ÏŽ!Q#B×\¨…©YáÆã„„KE˜J Òب+:€ —-‘ÊÁ-VŽòù‡ü.ÿP \ˆ½8\n¸X§Ÿþ!ü¬XéOàŸËm¾‘Ä !¶‚½ŠßÊø½¹ÍwÄÓ+—ò“^„8îѺ¹GÙ†ï-Õ²—°Qúè ”!RöÏaGÈÝ€š „OÑ?€'RÑd܉ Å0 @>¤\(þJäüaš_»P5âBþ!ÿ务 éÃtí¥!¦¿{û&‰®…~¼‚ëé¶;¶ñïÀYóð€c—”B5×xF‹ ·,}óã¯Oe-nDÀŒ£u.P¨!¢&'ð4 ž¤fÄÄŠñ*ÔPJ[ n @ù@¼ Ö¤´*•QBþ!ÿÃ务 H •hs£ŒâÂÈÜ$¥þúñÍÑà_â·©ÄÕ’n¼Ðf¹Ñå{bÕ'$鯓àxu8òʤݿ£*ˆw¬å…HÂÄtKÄ'žþ{&dPcÿ ¼æ@-ˆjTýAâÅ¡aÊñ77ëQŠ÷OìVîj‰ýòù‡ü.ÿP ]@xì0ú½4Äôw ̈ Ó6ýx–Lç^œ&A9ë|r£(?≽D,™T/ ¾«‹h rZðh_ºöØe#¿°ˆA×?–ÐGVh“j!úgDâx®P}€J Õˆ"ŠPf¦ì_ePãA`º€xÿÌp‰@e7°n% öHÈ?äßpù‡bàBºy27 >ý™ëý·&èšþMøf JìýÙ’¢–Cà9<½Gzž+?“.¢‡Äs#Ôðh@pšÞù‚@ é†csiÜ€€Ã¢Ÿÿ[õh1^ÀV_N(%ˆbl:úƒÚ¿Æ. F• ®ˆ Hß#Ÿ……‰„Âæ)M–!ÿÈ¿¡òÅÐ…tà 4Žô$¦¿‡Ï–„0}óˆtc ô»`Ù€‚M[]sð€µ,+~$txÔ¬þ‡° ±—‡%Ðp#Ä7þ°l48’r¼'q¤¨PÆ S78ª…©[•;ɽDbEÿMAÀº€¢DüOÆH ÞŒÁi–PÈ?äß`ù‡bèB Jî%QùûÄ¦ÇÆ”Íz§¿~²eÄOËq(9ùþU@ ìÈ?äßøÿ?¦v;<°·xœí]wXÇûÇhl_{‰ØK±b×/v”ŽD¤×ë»3W¸FUÁ®Hì[좨1ö.QÄÞ±Çè×üv÷ {Ü^Á?;ŸçÝ™ÝÏÌì~nÞçæ}gæl ¶Ï t<³ªiÈ÷Rî/œ>ÉÞ=·®—ÔZ>g—ë÷'Ê ùÊHñ›Ï/»?éÉs“|Þ×aÇövù 1¾èÑ­ñ²+­Åæêœ™ÖÞ¶EòŒ…ÏÅ«³yYÃ!–Z þÓ6rÖ ]JXîT55Î&>莮ÿ™‡ÕŒDѧ>›ÖÌÄ.gt»ó,0+àJuž{£°áô{>ÄVV§\þ¸û½>á5õQö£ÞIÍâ‚*ŠC××d*mžô¯qo<3üeǽu½;}K÷{swüç6vÂ7 ?uVö²¹KS‚ë›zH¤?ÒŸ½ú#°þÓ»r–ð²œÿSúª ¬ø 6ùž/'±üù܇Û3³áa†‹µ½`?øåf3ü`Ÿ=ξ\w_Í+ø‘›:”®³Php½GÞÅŸw Ô–¼±Øà÷G"–ž¬NF&¼[¾"( óu‘&Ý©Wˬ%ŒÄÓáÑsŒs}wùÿ¾fÞš¢GôYíî¹—ÐoQņV§bìS/èYAñ‚ª~ꂌ×ÞM{­ÑdÎq>—D$ÇʬVLü•|…^¯;­$£¦d<‚0jXC7ˆÍSøôÚÐñSÐÐ^§~9qå¿»^^=ðs®Ýý°]2÷ì߯«r)b[™~H¤?ÒŸ½ú#°`ðã•Þ+½ãÏíÌÈøÐ³åŽeí p|–>x]¥àîšå5¯ Xwm¦WÙì$óü1UâÆŽÓ Ÿe-3Ì÷92sWò5‹õOú~ùhÙðäáð6»,Þ^Ûû»Nô —:n‹fü^”F¦zLºÓµ5#qÊ„Ê@cKæÕîŸ7ã&L˜Ík•¬Íúôômoú-ø¡_šI{ K¥î|®ëÜ¿Ýë8'Ù%8|w{}3m®C¶æ1gU$urÞ9dñzi·š8Œœ*ü—ô{aX´ÂýÂù ƒ:<ÏiØêÁà¼qþ$ní˜Ñ÷µÏÆÃ½•oÚó¶Ïç45ó>þH¤?{õG`;D¯So÷*)šÛbP‹O›l¦Ô–}L9ûêvŪܑ†–C˜9zÞ¥vOB²-ñmRöäÞïZRè  gŸÃ:yVº§Z®oœ²Òé|ÚáMuþÁòÝ‹l†ŒÈ7ÈíR¹W‚¿l·•AÈõyád‚içÛÁ8×Y9.9ÝKЦa—’&Z'h³UÓoyàß6ŒõVVèšÇ¶rlAûÔ¸s‹B®~Ü¡—Dtû+ƒ:‰åœM #eñzfG4vR€-„’ÎoÂ!Œ÷ôá)_èZàšU0àç¿—¸ÀýüG—¯Ã—Ó¦-ÿñ1gWèÂ|ìo³oéôGú³W¶#&«êÞ†Ðì'¢Ó0;¿Ì#nõøŸ‹ý¼Ÿ¹>¥‡ñž:µ<2¬¾tŒe~|áÈæ×~u¹G‹ö-Íì•¶Òªú¹;¿ä©F_{UînñÞÊN•£jäñö=±oTòˆ‰ç ¼ë¸Ô…!I w÷å³2£\—ÿ…Ž“ë±¶7÷õ¬qšÀßѰeôéL‡êT«ƒò"}âgŒ;”ö>¶gr”|±‹&³çŒžÁÔÉtÅíÔÉïòáäÂû±].q˜:Ô­„é­+0ß ˆr||/é—éžEÉX±¸ãÁ²àãÍ.FÚÝAÕ Up±rVN] ïéôGú³W–£õïEM¯ô¼úÓ¸ –ofœ¡Í*sÖ):½Ø©Ï ¿ï=õ»gÁý§ßèz;”ô}¸E—{1¿û^?+ëœü³×~Úµ!…–î´Ÿé<Ù(7Äû~Ÿó ‡¹_XÇéäý`;#“ãÛ.´¯qö™ç xùÉÓéÜÀ2Ê`=yÿý,_<“ælû¶z¤Ô4+71¶˜YÙçúÆ/úæR™W“y=©“NEu5C‰½ÊѤI™ùÀ.8¸þ%­npÄ{¯Ú<±½¥—‚ôGú#ýÙ«?«Ñ¡Í®}w?Œ  ëxFõME€>çç4Û÷²É%Y†6'±;¼ö 9ÙÊïž`À•É]õ¿%X¬É蜷ÿæ•ÌýV7Àqv«Ž/9÷£,x }cwü6‰a¶ò+Úô\¿ûuÏŠpÎL¯\al9à”JÕx5„ÓÚãñåã?*¢¿/ÿxy5ýž‹.N+hɳõv,\+ N­í0âU FäÝ}t˜º\u¾+­Äw©Ç“Ç™• ˆƒGgÂ4––Ÿ&ÔZjÛ6áW…6¹8ç|ÎõY§ºÞwÚØÿå´¼®ìX6)µ•Üü+AúC¤?ÒŸ½ú#°ÝzÕM[Ÿ¿eá…sÎ>~)}¾íã"¼Ë[-wÎŒJïN}Õu:»ûªÉÛƒ=f& zš 3ý†bIŠ2nõºùSÏÔb.R‹÷øRÏöýó2[˜]¾ßc~pK&ë$sY|²îíaÄ~W²‡g÷’¿" ilׯ=?_öQ w—Ý4¸gæ…¢~Õ©ØöÕAÑAÛNQõ×™‚.­O¶¿­ÓØ…Ô彟&5 ‚­ËÆ’ÇYw:o$ ´káÓ}G—C¸®Û…08#ç>ïLà ?RÈ]÷ üúë²Ñu3íßzmhuOÔÍÜ Aúk€ôGú³SV£÷hûwÅSN÷â– kµ<ë¯BÇ;fÝšD¤ÔÁ¦Ï«/»†ÞCü[ªæÕ_­?:¹Ï£|Ÿ®§^CÑ®Ü>‡Ò,“ôxüÅÑ?°aëMâŠþ§Í܆ ºq}ã%N~»hÅóõNn0á³lWdßÜ8wü©'jÍ0og3ûî¶‹l»ì…Kf·øž~ uÍžØßÛSŸP^<øXSAÛèäúOß÷*%Ûv&·¤r%ýD—ÉcÔæ-Ôêæ9åv¤ lш(ð‡äijlkö~ð´¸MÖ$-ÛPì4ïBâËoˆ?L°´ëó6fÞÒ_¤?ÒŸ…ú#°< †v‚C®ÜyNk÷y³äyûW™;ˆE¸tx«ê;~ôû …?̰ÃFDù¨%ñìúЧ¬0¼Î© î“ϕߩÍ×’zçöÝ ¹ÖÙã§Âæ‡Ö˜¾¯¸_´Ëc׿ =z##½îà›9Œ—Ã.ü˜Ï0ž±…Üך³ãv¬L¹ß¿áÄ‘»Ë î946"“–Üri„“>±ý·¨>š³‡ÒˆWîtؽ‚èï ŽjæO ÞC5ÇG)u›Ï ;rRH½Æ„ÕqŒÎßáÃòßTŠCŸÀÆ/F?rÖ þs¶þŸ‘G+ÞHŸ–š~H:þH¶éÀj yUìÆi»î‡[7ˆÞæ·AMç6¹t :ý›Jíw÷¸Ô°oÒ覑Q6·,¯Ç­Áï²·,¯ÿõÔšSÝ~–¦Ô‚Ê‘.PDlî½ÿ“í’M?]ô`ÞÅ‹DEù;W“¹º¹×´[NLžÇˆ“uº÷4αíø݈adÙÁQ¶·¢îÉe° uë }U°ïµaÕö ¬r¯.\x†ïöwvmª Žs½«ñS6^÷’òN=vž2ˆs¯Úm%¡_,&¬ÂÔe‡ÉyBy&Ï|²ç´Aó>,~˜8µè¤ïÑö·|vµ¹MÛ~ÄH ý‘þ¬ÒÕ%jî“5I¦–ÖÕîÒÉ-] =ôΞ×ÖêÈø§çÇ ü½xìªx‡Ÿ›[ZúËÁ%ÿÙU»%±;nεiB¿Ùs·žY…·ç_»õzœðæUOMƒ={ö‹ÛÛ±Ù‚— C—!U¹L}©>”ëçûâ=ßMôI+psc`B¹ .ÓgFÞŸc«¯} _sœüûÓ->wS ÞŠÛ­úS“W~µ#å |õªyô»hGNQŽûø™'R*¡«0{„9ÊGîösÛáë¼ÄæÚ´’ÞO§vø£éÇEú×ÒéÏ"ýXñ‹û7phðȽlô÷}þˆ8¸;®óÙo †,쮺‘˜ }ü̸áL#,ºƒ`ÕŒºë?î°¼ù ·n‰Zw# N¤°Å˜>ï†ä·dž<¼;4~h ã-Ž×«ºÜ"6áp£F—š¼/mYdÌ”]91YŸŠÏú{ï½VØ¿N†C¨M–Ò§Å\/©ž]o^#Ý´iøñêùІg½ýKš¬hùP»SÉÁ&Õ!]”S³çëD6NUQEކq7B‘Gbf6,°¿äðã¡€µ_5»?‘;ü«ãÒA¦Ÿéo ¤?ÒŸ-ú#°“òÜ|/eìï>ÂÙ–Þ×Ç|.åMš]\¹/÷ÛŠýo[§i9oŸçù~Sÿ‡pJ½Ø”Åɶ6Ömÿ¡ðmß N³xÈ¥iöÛviŽuÖ/c¸¯MiãÏëÍY¶¿ù§âÆoõq–µÌȨq /›\Å´ éxéZÒ×.J H½ºÑÀt{p‘î<ïÒ@Ÿ˜úÅF¿º÷êÿñå¥G_6rðÀÕä­ïFÃfUO¨Å¼gìH–{ô¹`zô¢Ô? ô‰Š< wu. †åmBÚ»•ùÖ÷°IŸrS2ÖÔ£"ý€ôGú³DVÃyOÂoñ~ïƒä ×Ì`6kê(þ¼V´Ù+ÙÕ,†´¼z/ëÚ;×ãÛ]L‡áÌ/o¼rÉÏk»&¨¬¥€ŸŽ,ˆ;¬ Ã۵DzC~x{ÀQatãô6§SgW#bã–.¹ë~izµÃ±>5~ åײ$ŒÁ)ÙWüïdƒ7Õ7_~é@à”².´›ã†4›@KâŸ"ÛV¯´Zø9[ÿ+]Ç8Û¯+ž14µaû,íÌ õx%5'ëÓ—/ÔäÀSÈØê¾m•¤pš]a°ßè¯ð¯Ï;`)%MZmëðç¶à£¢/×O3ñ¤H& ý‘þìÐÕp;½Ü65O9ðIÒt£Ït|‘çÌÞý„6óÿµúÇ@õ–‰}==ñÒŒ_öµ˜ÿÉDÎ| E#Öz¹gLhÔ=ൕ||gÝŽ Çëû5ÿø„f/‡Ž™÷¨æWý°bU—|£ß*¡»ñ~«øÒèÇ¿>»à{Ë€ï?êáíÎ ”Ji®á&Û¢ÛÃy¾Â9—«ó²{ì§Û–¼Ì{Õ)eŸC:÷ 7ÿ[Á…1ï97Ýp\“»peaî6i^<.8Þiq8Ÿsóqpìj a´s‹A°Û¾52+Yókþ„è¶7œÃO3ÿž ÒßþHÿÿWú[¿‹« &âI”R “ç¼°KV¨eÐ글¸'QÈ$Ì€Åy¥ä)M÷`³|<Á­p±Äl[H>W¢¤ø[´Ä¢±XPŽ\_&ÉçH•´úE¡YÌ“Ž€H 6j €‚…T%£·È Z„Rš ˜¸:…©®~teàº3Ý Åbê%úõ(&ô“*¤ä1¨þ«“ïéôGú³W¶¢)äRâ#‚ñƒÒV%Õ¢ûkù%Ág"áü€ðiRså|W¡`àëY”fÝä#’Ï‘á^›S¬.$p3jvc’ŸHö ¢ó†eš0: A!3¾ÁÅ'ª¤ZS„Ã"0Œî"Iõcá¸T¬­_!–i¦ï÷Ö1éÄÈdÚ0díýH¤?ÒŸ½ú#°ã-Z—g)­ù¾ÍXÆ3 <ÁnI²øõß`¡~ÛgܘáGûmI¶l¾7*ÛØª|>GMÖÇ)L8PÈÔb ¡øñIº0 Ñ C`Í X[¢R®m¿µ€LPfà˜ˆ—HXPÆ  å—‚ôGú#ýY«?«A|ø¢ý`žgÃY[ñ©Ô²j>à/ ܰ$ÑÊâ9Á–F|ßÄ5Ö tà<—ÜôD©¥;à¯f²rˆøü$‚ϘEà1© ãr@uFŸ¬©`¸ászµ}^{I;!˜¬?:CFÄA  éëf Àq…ÆÀâøéôGú³VVƒèþ1¾° E†ñ ÒÔZË¥a¸j>¹ö'±Xm½9Ñ„U:>žà¶Á”'Ž™Ï‘'«,µýÖ3%* U2,r© ¯#à‹™ 5Ðð9P­Y‹Tc PM e´„Öhë×´_¿ Èz@XP>PÊÖY2‰HˆôGú³UVà‚˜¹0/-QˆO`¢\úÍ€àsä>¼À°Â4†€™•|ž›avY1%•s˜ù€'ašDPaÀf©skÇÇ¢¢Wk]lÔ– jaLÀ‰2¿­ààjœ¶%(ý–À8'‰>ÐÖÏfÈ ù5<€ô}@ÉN¯/€Ü\»%©nõoµÐæ0 V‹D¹\ÿ”&ŸéÏxÒéÏ ýX  >¢UÊšá.* ‡)¿5 °Xo¸^‘ôíaDï®\›\>À#Vêzµ%©Hm´%)u´Æì´d ŒY"ÁE<ŒÇ©™¸†ª5"^\¦!¿¦3$PS¿|£8Î$i¦ýHÆ’þHVèÀj Œ÷ã¯ÌP1t3ê—A¥5·ô´¶\^`X^Ôý²è7´ š•—,Ö‚ð0ÁrÚ¶dNÆÆBßõæ÷….•A£_Õã¤äMýÑ*¥Á/ƒÖð„ æáPªýeR)Ô t³¬0ÜŒ´ º_5ñœHf ý‘þÿ¯ôÿ?;ø¿.À×xœí]w@ÇÛÖŸ1öcìÆ.VbXQÁ¨  (¨€Hzývæú©°¡ bïFDŠ%Æ Æ®X‰ŠK¬ßî^Û»ÛÛƒüÉÍó‡³;;Ïì,Ͼ¯;óÎÌÕÆð¸uLvwóô8î‘Íeg»Ù÷ªë×´â÷ ƇU¶··òkÓÂÉu×¼i.îYcÛ©÷ýÃÈkžŸ÷V‹"pþÐcÈS™>#h~³lBÞäF4µ„©ªÞ ^:…aK^‰ö帉žæS¯=ÉuëIC龤ÔDìˆà¹Ác$)÷Öë²½.ïJ)ѪEwý³ùö:V{ÜëhÀøvMïÁ㟊&ó€wbºˆ88ÓµÝg" ,¶;ˆ'ùWNã‰Çèc äŒ~;ú‹’D‰0ѹ4w½êÞð.³óŽö }L¤¿ ý ýk¹þV ¯ÊÇ_¼\ÆýÓFO[ º—äòË2‡+«³kTqhïߎìh3çÞ°¢>_̽•‘QÓ¶mûœÑ>sOêÓȺÀKù(9­îÕv¥Ë$Ô¬ñ•Þç].y-YFÍ~ŸÚ0UÕýÕöúûðtê»ñɉnM¿²’ô×Ê{=x²™†sIVôÑ8ïþ›fw¾ÔÓ 4A“Þp²“”RàÇì?u'cçÏ×oíÐÁÂ)US·œÉYžQ˜JäÅÌÚ­æìò–HƒØ®µŽß…?ðÄ@Ã@U}CÆu? 3æIU›Òzç>êIçÞ‘þfô'ô¯Õú#X öŒS™äy×µw†Õwéà³%ÙOðòR3Çtí¨¬ÁÝrîñ•¹QG ¯ÅŒ=ŸºzxÍÞ@#H}°âßdáGy¡|Âùyýä9Ñ“nç8‰ ò°ïäÉý\þ¾±3¥_G>³ÏôïA« )—lGsyØ©—žon¥ó+ü°ÿ­yOÃéèáàjÔ€‚,Qi2Üš× °±†/i_D)¹£ÉŸúó†u5tܰwÊX3™à}\çÆù¶„åÏôÿ;’¼˜9­O%‘.9h{OÚº_Á“`ÛzlÓÛÿÍÂûíÃ|çs«ãª;Ž;>éOÉEú@ú›E­Óÿ ÓÓ"Ôz|+q}ehpAËŸwò{ï­œµá<Ó×uDÊøo×V]py&f(e€éÊAàêëg~#N"Ó:JoÙßty$²Ä£ øbùËÎ!8%zíÏß}²¿œtÇ?$ì‡áUÏK± ìz-~ÒhB™þÊÛ§áu‡0ÖõqAD·äçÀO¿mÙ¶ —Ó9íµg•ûƒ¥4œßT‡LÌ,®gwÉys›ã¨“êœÊoUv”§ÂÆQú^&*×s¼;5Ãöî>–ïm÷øËxû{ˆ¿x“Å G> Ò°½¶Çð¤Ï¸}·JËJÜMnntožlFÅXx`p‰“hR·Ð¼,¤?Òß°iHÔ6ý;0>-BmÇëÁ#¾>ßOÍñïæ{ÏñÓ·¦ ¢r3wVŸVOZ<êWì®Þ½°î_úì›ìrVõšmßäÄáK\›‡EŒ44¸yuŒûã_ÉãyuÒ=‡oìx»€™ã³ú§‚Ô<Óü…cÞx—çßí{eƒ6Gùgï· ëtÍÐŽ.žz¿õ÷²Ngרϧþ=½= §å˜™S“Œ3“.ø÷ñ,+Ÿîèár<‡Èº¨Þc{hl„î¸EÔuT^6Ÿ»‘H9?ÞëýÀËøôýº®È‹A±î—ˆtéNÛãxâÔo'á$ßž§BX~ñîÑ—9ÝœÏv+òŸZ¥hÑéôGúk`}úob|Z„ÚŽ Ž;›Ü=¡\©Ë’ØJ>öü»^­6Z"ƒÎ§½ºVž‘¬¨Î½lßö> ³Âfêê=ϺÖoVö¿‹‚eL<ƒ:~ž8¡ë ͼ!Ðÿüˆ;ysÛ_‰Naâ¸ÞY‘î6—îʰK]åÓŸLº¨]{í6ýõ¿º’ZLèßb—‹îÌéÚ÷Mš‡'VÌ#O³’Ž·¡#mM:õÍ8¯ïÐàa’‰7_ﯜèØ#¾¥öX·ÎIÝgyIyol'¯{‹`ñEõ죩‰áˆ4r«-ѳ˜Ùz31"˜÷èîÍ;dà~0¯ï…Øâöê(l·Ï0¤?ÒéoµúG2=,B­ÇéØeE-&ÈûhÂpAã÷M¯7ÕmïvßÕù*ç–Åäm*ë®ìn9 »ÂGºr÷«zs(y¼›‘˶ üUv2³<*8¹W›w/Ãt1:þƒ~¯mÇyñ­éÞ42Ä9ôb;ÚK‚ʰùe…m3Õa8‡ã'g,2ùT§‚Ÿ}Rf«÷ا%#¹±‡’¾ƒ {b+Ñ}P7î»ôW“H*»øÌ7ˆÕîÒðÚ¡K)oqþ_6õ¨Ý×°ó¶|k_íñ˜\‡'ê#á=É»†¯Jl$‰«ÔÑÇAùеDo÷;ž6Hÿ„'÷žÛá´ð•[EpÏGXpa†2 {h+¤?ÒéoµúŸƒV ˆ‘mn¬9”<” £…¸—'_ÿ0ãZï ª¹6'$vXXq9{ðuKa¸²3¾uSß6 *† ¼ûaü›üeÕ Ž?ȾAh3JÎRéOe¶?Ðï¢YR+·á+_ß2s1*Ù6»íÌK?ÂOŽLûÔŸn¯aýK"wRÎcWµðHŸsñYç#øñåï'ýCGÊ^~©®qÞÒc—ÿÞ€»M{¸òì¾tØî:8êÆ"%eú³âàhíqé‹WžšÃ}+ÛþòzTä垧܆UkÖîØZқǮ·;ƒ'¬/‰_põ~Ùñ=¸Ã"Ê͆U7 p+‰êùéôGú[±þÖŽ‰MÞøtònùåB¶Ð¦ìµO3¤ãÒ³ÕæO¶y¾j§Í犋̆³ðãÀ!'ì—w5™q2µU9Ï; Ëë3Ç!\="[r%˰ ·öW¦}8;ík1MˆÄ³!žõ|v×SmdŽª¦ûVÁ˜ç¬~¶w[P\æÛ6Ê g~¿]—÷6»Ø¡ nqÚƒ®#RçǸi&C”Î-KÈ©:~C7nlrècÏui^ úÆRKŒ¸y þì•Wuk“Y’yDsèµî`£º!~iM÷Œ~§îE5¸´—l"{ñ}/ü(ÿ7ÂΡÛ7%†S G¬J_a²ÏãþH¤?ÒßšõG°r`¶²-9wp6ªké§°ûÿ“½&|›í=Ÿ•¼;}0Èìr!Aäoù½¯ÙgÊo]Ô¶0göõ£~ÆËdLJ<~m×ù|Ã\Ðqg½ysï½>9‡~µò᱉Ù,†¦õØóÏ{I‹Ò_å826a^“yçÞå Ü^~ÒÞá¯_FNÎÞšŽ—y½žÉm[mÞœ<vdߨœôi×~ëÒœ@Vš wœû·èúHk~l¡í¼Ônݽßoi]ºa/72ëÃÝR"åeÙ] Ò÷Ø› '¸¬'Î<çM« cƒÅ‚õpÕdbý6Òéô·^ý¬¬}þRI÷\~Ã'Þ·ŽF—Ì*}V“59ø‡æa_–g×+Ý¢ÿÏln”ÏÑðBûgt9%óu±m94º!ãäèÿǶNç×51‰rÏÍýõnÛùSb¾Ññ%±K…+S½ü«ö‚îE/9ºÆïŒMÀ:^+uH0ÊŸöƵØ+kÊ‹7½©OððìNú3›þnëNêݘ§m¨jÓ®X÷Ÿf=°Ös¶z QųòIdÃÒìÈÙÀŸ"žl…0¸_êU¼z¿Iv# ›rns'‹#ý‘þHëÕÁÚáëÑ¿ðÄ_íÇ}Qeõ9ñ¢NÍ̇ÿÜŸ Yß,þ±”þ:ÿ͵eùÁ|šq‹vVÚzŸl}Šé.ß7ÝWÞŸ.2ÔÖ{gÉ;Qóc¦×Æ6Í?ÖƒnkN Bcšv=¬Ï5÷¦æFµ¸"ñ¨xb’¿Ý:Q°xÛ y:íH#'÷¾©c¨ïøí7Ía”êýŽž.qجuáÔ­öO¥Ükö¡*ÝNb í§s5滇٠Zõ™nŸ·bÇK2ëÖǃˆKµ»L¤ÿó½q÷3ÅÒ! ñ¯/„1slô»"ý‘þHëÕÁÚÑ·ß{¥p+œSänÓºÚ;zP0ªjÏYxÂ]ké®Ö=4¢ œâ°ÿ´Yþ˜›]ü¾ýñV†UÇM¹ë—Õ?o<ü¦ÆÄ/9vgÞzµ>ËøÊ» è1ñ{ ͇S¿S=Ý«ñ5¾/³óûЮq] f6‹.<]µ, âëÙ¥{n©&”çAãu³¡æ´ u¿q`âÊ©Eþä¿ÕŸq óFj=”MÛj›y6^>½¾ôî¯{9)KÔû†^jØL=™8ÁŽØ 6ð*-Ón;p÷)èñ,BñÄŠéúº‘þH¤¿õê`ÕˆÍÛœrò˜zgå[ÆÕ´f!ü”QµÈþôêÍÓLÃpaþãœìg°UÛlKX7óAÏaŸwN6·glf æÿÐÎÄÀÕÀeüq}ô¨3;œŒ¶$Í+iïêJ;/× Eæ^ö …ó ƵL!_~ÞL÷À.{e›ÇŽñczÑ­eZ¼¹¢IæÝ›[ôzäˆozœy½ ¥¾þncÊ©òÑ“-Úã§'Nh㭼Ǜދ@ëÌQ/ß}•!gÿžjÝ™ìqˆ•®i“‡ŸBâL²nCßòþ©ƒnùjkCú#ý‘þÖ«?‚Uƒ½õð/sð‡£óg ®ô¦ £YFôºéSmSf¿ñþhÜ(J£=US¶2òc \FV¨Òÿ7¯Š¾âQyçk®ÙÞ k—s×%ǵ™g¾“FÆJw–U£ýœ£Cnu[hïuŸÁM¬´véôƒ„¼ÒwK[9O÷¸fÊ¿·¾­»É.'¼ìÍ7ëOù =6Tèþ—>ïT·ú³€F ôÎÕoç•æÐõÕ‡sr‹ëv}9kÎCâþ‡ºzM\“J;ýM¤6Î…Ä.$Cf°pG´þóùåæv:¦©é‘þH«ÕÁªÁÙŽÛœolìþÝíÆ›ö¬[ã_öTcžSÇŸ¾ øzÄ ÛíbÃ˲N»Ï,²ÄŸ?¡Uëç5#þ=@w5)z˃”'\¾Ÿkã'ß¶œTµKŸ‡=êÈÍé}¼Zíy¾­Ý为sž18ª!ÎMJF˜¹â[òñ…ç/a4Ëfí|ÕÈ$3Û]j0g:,ø‘S ³û¦þ—A‹šlZ­/p}Œ“~öó©+ß4‡ßºL'†g*X:öó¬çÛ ¦ý˜»Ä59ìtƒHÛ8dc‹ŽŽs@xçø܉wRÓ‘þj ý‘þV¥?Ïüs"X-àÇ.de¦©¤v¤ `|¶B.ÕxšàGz%ç)E­ü/|¢†@ÿJP>†`JY¼ý<–RaÂÿL%cX”/@ðcUÆ|aD ]· p%RãûàgÀ äÔB˜P¢ïå¡Hbp¬n¿T[/À X¤>‘, B1y2Á qò_QÛ#u•œ¸?7®š| ”¦I J÷çÄó08%ޱFÀá%еü8¹°%r:²g2b‰±$Nà UtM¡ë@!_[ 76^Ë7Ä„#€”î€Pî£ðut@kúT „Eú#ý‘þÚ«ÓýÿoÝàñø*)5Œ…›?;8$quœÌ²Yü%5æ3FyÂmñúf’Ï‹«.ŸÆš±*S¦5¸êñÏ;3ÅL SÀåÅÉtƒ €žIû ¯gpY”ª>7^Ç73ˆ¾À“Hp pxZ>Æ—”@™¤ïCÜ?J¤nÿr4ú!ý‘þHóuÕ2ýÿÛBO„Ú€ 8Æ#ÌI*7¾æ¡: «€½hÉúTÃQ®ðÕ͘Ÿ"¡z[d¸sÖ&Ñë‘|¨ #΢µ¦Ÿêau*±!°¤´3€è;<…˜ä³`œšÏ8h8Hë p„êûW×hlŸ™üý‘þH¤?C]µLÿ ½ ÔFü @Æ@È^([OLý/|Æ’üH/Õ&•ñDsaH3uûn§Ú2¹I.g¬÷|³ÓzòYr…š÷ÖÓZ°Â¥ C&äÇ*Ô|s3€è;@ôc(|“@”ÂÂ0ŠÛÓ; bêökížÆ¨§ÿP¥€ôGú#ý­Uknó<®’\ËB˜X€xcBµÍßÏX cÏænJ–™”"ø•E¾º,ÛK‘§0ö ø€=m[‚ùi=Ÿ­^Ë~YÌ €!ˆ ¦÷gÅ)>™H;|HÛÀ¸r‰†ÏeÅ|ã@ƒE@s€(‚1ŒXMM´è€Z>: [¤sH¤?ÒßzõG°ra4R*Á?&9a‹à¦Äš˜¿šÏ|¦A8À÷IËQѼq$_ bæ«Kb13óÒL¶Ó°À±3¶'05 çsqÄúaPJ¼ûçE.7šœÏ'ø\Œv}@(Ðx2œÏ|ÌhÐ`Á¥7€îuûÆî€n ÿC¤?ÒéoÍú#X;È0œH!œp¸1Q^ãU¹DL¬` Ñk¶$ÒG×È ©˜ùšJÂæ$™:'’o6 bÜŠ˜­šà³Å8 U˜‰ê›”nºœç³$8_I?p¤¦O¸R“|±J*æ‹ úÆ!@ý jo·vMû!´äˆ„º!˜îþH¤?ÒßJõG°va4– ‹òƒ55 ŸiKP¸!þ9é ó׉0žé–œF¥¸‹‚‹TtJ¶_AÏÇbÜw0oë¥æÇ*¢H°ÌÂ'1©¤"Ôl)*fÉé㇎i@=HÏU)Ä|¹A1ã en0¹ jÚ/ª¡ >?Òéô·Ný¬ãF†/…¹©rËãp´|" hvKO ˆöÔmýa–ϱ°¥'Æš‘™cf‚FãÒ†±(Ï"úa9c>G!M³0ö Ø<Ú.ÁgÇóEô‘Fú_¤Ï$À ÐhQó!@jo€X¬Þ’T¬íRh€fÐOkíTÓ7 ÿ!ý‘þHëÕÁª º&g%Toå] ˜ƒÑ‡Æ É].gªZ½%¨ñ–œ†µDz›ÖEúX˜Õ£åsBä™2f÷ø¡+é'ùühA6ýo¦Ðv0ŽB?¢Gòù‚?à9@vH>&UiøŒÀtþÒéô·^ý¬¸ùs#Àµñ˜LYÃ-9 *p$t[rkD[ã-}Z›åkk Y¸5Á|%ä–¢ãö,"`£¢:ODøÀ™[TÌϰ%©æº øýc¤q´|ú€PH­ŠÆŠâ¥Ô'|‰Aêwì¦ ª„ÜÒT¤YM\= «éôGú[­þV Âü£|àÚü·_öÔÔCl jÊË‹³!ÅÂÒZ ßü– €ã-ÜÈ8’GÇØÒu–o­.ËóZ¦´°¥(-5M@(I¦ CÒvGfð Ä–žQ‰|àÁ Ê$`ÍO€l‰Z á#ý5e‘þHkÒÿÿä <Ыxœí]g@GFÅØ?,¨(*DM°%XÁˆÑX°¡ˆXQ¥ÃõÛ½~Ç¡tAƒ¢c‰5F"`°k„ ÆXPñ»½º»W8.ÿ¸yþìNyffïÙy™™wv°Á Xgo¾¸̺²ýì¾Ìï·Ùï¯äd[Tøâ˜$ÛÒ³,#K‰zí,ŸñÇŸ›[ç¼ë4âßq•É›õÒ%óo%¬ûÍdîwƒ^_Z|Ošª‰áð‡s72«ùaQ³S®\\™Wƒ$ËÓ?Óæ«FKÓÙóP΂ê7QÔ, oŸT½ì ŽRÄœ¿$ÅïÒÛ|MÐĸ=§KïñÄí²6àœ½´F}[°öÇ1øuÊÃ9çœ7?Á’1lפyWñ8 Ò¯ ¿ö&uU\f¸ŽXŠa ûhÊú«õ‡ú[¡þV ö•Ú—]Êh‡¶»œ™Â¾#,sÊ]¼6ÍCfQaœ‚suyü¸Íc¤š¨žNllfîssøÜÞáÃ;ŠEY_J()+J…s×ìM6ÍG^bÛÂò?ää|.RE0úœA;½ÛmVãY•­Gò£Ý÷Î.ÎuÎ÷f{5µmZ¬:<§üèqÞÕ›;ìÈx¯ï —ý3·÷Ûää|¶KDÒù_Ôîl§æÏšxæ{Bú°W—쵂Y¬tõí×?-Á¯¨ gì)ÿi·:‰°,ï€ð8«ßü:`ÍKqYàÜÁ°Ù«2Nò”T¨¿P¨¿õéaÕà\o³nÎÌùc{vý>SL9°ø·#^5|‹Ê‹MxíCÍéiU¯íÜ6»-Á7'Eo2•4®Ë*¿v%žwɯgm×ïÖ=ž8µÑw6&kÔÛ›™þw'ßPf>’ÒYU£ï;o³sè­‰·O½_j¸ª.ãò.]2Z„½sòJ—cÛú}iï~‘”py6±þ öåÌù”¨Ð›À9Ðc]ÿÑçUáèѵºT0cÌßšÀ:Ú=OÍ}ÕqŒò†Æ8w½¦ªðù„ßy‰ËÂ÷àQrzŸjü:¸Wà Å%ÀÎV¡Óƒ¿õ'êAý­M«ç®ë—V¥“ÖùVlWEÍurxÄò÷£Ã–¹`@—Ëc ¦¿¾wÝcúÏÁÞ|ÒáµÙüEƒÚÜmXÿ±j?1öÝq»ÉùSÌà/ý²ƒ¬ÎèP¿ü!‹]+¦™W3ãé¨>%ØÊ±uS;•]ëuu§¡<ü‘Ag Œ–P×pùÇZÏ?[ÎÈè<ä,±{‘?´é¤—}Ã…AÈQnNÜ›•^±>ò¤Êjy¡Õþºäi «Vj­sSµV†–wµêî zñ€s§»•î…²” ±cú<À¯®ÿ›ÃP\Âl^áMù;ÔŸ¨?¨¿éaÕà>ùôÔWÃ˶J Ò^ïÑD¢§j_Sqšof¿¡8þ4Ëñä¬ç9©X ûÏ./þö±¸ üOÏNøtüõ%šnµ/&¹Û_…Éí~0‹?øüÐ í&Ø•…m–y½¸ï1Å̹‡Óóéô"!† ¿Ø=ðç ×ÊÀýùëòr͈.¾Ò·ÚETôÓSÝìô²£]{ÉçPâær†·®r²›†“¼Tð;×g/#$—vCrµšŒÇ ö_u»–¶taÉuû\~CO©`òúÞOñë¤7ŸíR\Š~¸uBýI€ú«õ·ý!¬H½çœê¼WcζkóÕ)rÒºP·Žçžñ‡Ý´l—HHĈ†KË‚»FÍ’GÎ9ÖTg↸!wÚ¦ü•5øšª~P8®v¤Ýßfóч³ë;^ÿ<ðCív£vȰɜüNüò6JÚ‹3 bÊi§³z¹¢Zcú[y4˜7ÜÅߢ›Þiü¾Ó™8hg,‡_?Y’®—ÿÁn·q"rÔ`›Kí´ì¶ŽœŠ_«»ðî«ÃûÒÿôzú\˜¶d~wõmlùþŽj±§Öîï?Ýǵ°ë üéSƒ{Õâ×™5ŽEŠKeú¯?Cý©€úkõ·ý!¬6>Á#FÜG8{Æú_ÑKœÒúA¡kõOw/ﵬp¯¶·ï¾?ä7<™t¤éü™ËÓ„­ê~ÂÝpœÙG…gÜîÖþÜ®¦ {²£.ùèâ…F6óR15ªÍêÀ¢ÞG;œ\Ú¦ˆò-ÔÙÐå?4^Æ/²$ÕÞaÿ»JºÙîé¾K½_µ;×·«~~›eY)QOžVøbØŠÁYßåÓÎ;nOÇ~ëØÚQ—Ìì&|¨Û5|¤§ø[õí¤{-ªÔ·7Äç9ëó`ܸç÷T«ŽéAÏð«ï­®'—VN•Cý)€úõoöúCX7jøÒÄw»×ZÇ14ÊGZïPïüÓƒÁ‰•޶ÛsB"çcÕ]¶FZÄï¼§½¸ï%Åþ ˜oyPÜñ{géz¾»éo@¿öz«x†øÞµzí0-ßyÿí?’|[ÿ<]JÌ´t¥MEqƒr~‚mÜ'*þ¢Ÿb¦¿u¹2NµˆZPâè§¿pèý¢¸ò[r>ÚVqýò»C^Ã&Œ)“]4žðE±C‹Cµè°#ašÉÕsûÍNçüS«<œ Ô.ë°ô¾rùsóªžÿà×ðsíð¡ÿ™ûï@ýÉ€úõoîúÿ% ¬ýnÞ•S˜Scx‘VÀŒ–Û‡ýÏÌ4A-¸žô ìbf¤€qÒoigðKxË{ÃÒk‹Ë›èdþ¼hgÇé‰ïÌ[~ŒËòv0Ýa_›?pî7Y¾aÏ|ÄcÎ×6Æ·FÓ¼B%ê{ÎíY¶¹_Åmxˆÿ¾ÈÇ‹.öú„3žÕQ¢úÜmh‰ÿbÜ{3ÿñÐ[?¨Ú¿¾vÕûIÚ€l¡¹ÏZZî¡if¬ûê<×þ„êN¯ñög.ïù/ž")hqMq™7$g#ÔŸ¨?åY þÍZÿ§FŸÂðYmÄðEÿ;ôCƒÑîà=¤ ÔF8×þ’%nÀÓ“‚¶a…µ{í–t¹ÐxnCXã×7tèö3¼‘“V0ï›wŒÁ§£–f¼ŸÝö¤9¹¹á­ÇÈc6lhk»0¦Ÿ°åQ]Üý­ çã…ü2°Ìy‡&Áx¾úÎâ¬zü´­œo¼—fèågætòìC‰+ýë_ÕwÁQÜW{„SÂò\n•]%¤ËfÇi;ÿ|µæÞýðÍ i+{ï­ÂÖ‡tèS¾$ýÜ ¹Å¯Ç<%oÓ›J¼ìNP þT@ý›³þ­Œ?„ hþ®—}eW£s0úé–ݨ·7¹x»¾™¡¡EåÃËш[…61þYöÄÈÃSË=ó—w¦Ž“ÍÀ‚_ãnï™5ùÇš­™gî)i¶ýÈÆpæ;öÝ샯ޤj?ÞyslùŽ2ã…Œ=>bÛi]p~«µ{]FÛJ’1¤¶Ôµ‡>!½ïšÇŒö>è¦Ôû´Y–r;ÎûXM·û„ )Y¶ºÕ—ÿú‹æþ×þ9tõ­çÔ ŠiÊŒ·ØÛâ-euÙ Ë“³¨G=žrŒþìþ¸¡þ$@ýõõoÆúíöœRô•‹Èdî³Ô—q‰ ¢òáâ-;R4v×ùï_\óRú¼éüS4ï†}¯&;L|¦í¢G xã&¹»øéõPÆ÷ãêwÅ;;/¨RòÁáî'º?2^HzÚС-ˆ¬³£*[—ñÇϽv»ÒÝAŸàä1s Õ´?é6KsÏþeøå+žÞîvì>°ðRºT%+ÑÜwiå ^d8f”ãF‚ñÇž÷:ú<äåzÛÛàIfU¾‚úëêoPÿfª?„uÃ)wì`_sFõ‹G9¹¨òéYo–MZ-ߙۡßÃÍ71ÌϽWïJ—çW–8żõ·2ö†C^4õ;"–óËÇ[¦}r¹ßŸ'ÜkŠLg¯úÔ­s m\ã]Ÿz`ö?3ª ñÐx·;Þwþ]¬ ÅÝâWãkW3Ô¯Š·¹uȈ©û©g"¯¹І֯x8áÍüè² d,ùŸ6À •nÔÌ®ÀÍå#Ôÿ~m¹ÓÙŸ”7«?ÿ®KûN—Ç>-Ê›ißù8ªä#ÔŸ ¨¿a@ý›¥þÖbéä£ÿé’0°”ëÝßýÅ¥ô¬Æ3«ðw÷Áõ…]ÏàCP0è·èÑ×SmJ’ ¬5й3S³çžüým¯ßeúGh˜bß9ìÜ” uçÎaW–b*»Ëðñ÷½1”âQ5éÔîÈ#z"†}Ú©E fb*"¤Õ¾Í£ÄyÞ´ÞßûPkzo}BÈepë%®aoÐ ‚_vú£~s]y¹N{$é„Ogk“Ý׸ºiîÃNrR·n¤[ú“©¢^æ›Móª°#^ÝZãÝûþÜêOÔß þÍQÿÆŸÂj0„»Û–"ðÂâÈ„|že;C¦à³e"väŠä\¿ñ2 ò5ihœOn†Èt!pÙ¬x" áѹbópV§Ë(|½Ê²,+O;ÑtvÅïйªö5xPc þ:*ÔêomúCX5ðîçe¥É´oœ¢³™R‘ÀÒ׃ÌÜX_¬0ÁÌ.¨á3dÔúQúÂÔ\=̧ËÄjsÆ æeš[9’8ŸÅÐðõK Ɨ΃'UØ=žÂ72à¢ÔµIÀáóQM®å#qúBìó¤‚iXÂETí×õò É(.|¨? Pen¨¿õèaÕªýƒÌtaÀªˆDØÿÉ ¨ã”¹v}nº¸)Eª Ñ¾;ÓÌëÈ8ŸÅ‰ân4ÀY'ÊhlÕP4–¶Ï |¶\¨ïÆÃ gE§we$: · \&›â ‘Ö£L Õ›ˆ²Å<" $ à\€ák€*,²ý(F5Ê>¯ž |¨? Pêo-úCX5ðî·IωȣUÜÆ“ü'7 ÃÝ€;f)¶_nnÔãkx€³! p“{ˆ´|ÅH\Y<ÝÜÚ-LµV¨äcÝ€ 6µ “*Rq>'#»A N®Þœ†‹ˆåp>àò‰6‚´E (,ˆòùM¨?…õW7 êoúCX5¯)'n%;53^DŸSÝxM.ZÁ§‹ÅÀXFߕԤῆÏaˆÅŠÞ¨b¢¬•±ûeæ¿´8Ÿ.QðÙÉ©f÷Æê<õzœ–¯GE#e2ãå6[Ù͆ph qVepXBjë‡/àùd Ñ=@%LÕ~`Ê@ý)$¨¿¶Pÿæ¯?„uCñŽÇ2’¶È…Ö l–Tlé" Š/Ñ ;ãÍ·SùL™º~üëŸì-f~ÇCä‹8+3RÌž6°–åk‡ã8Ÿ¯ÿü€ÎÙd¢ï ‘êMÊ >‹!×ñ O mBÙb¾ŠO—Kp>Õˆ5š‰ ø˜ªý˜ÚEhÈ@ý)¨?¡¨s׺¡bÅmʉ×û\E ¥ ‘vƒ™å"Xôlwb“ú-¹~®LåÆC"—îNiÚ*"Îgrÿ‚d³û?guV¼nÀŽó¹ñÔçì0SE|P¿ÎhdÀÁ¨Ë‰AÄ*£‡0¸8#õx½=@|#@Õ~žÐè êOa@ý‰Í€ú7sýMüV&}MŒ|›Üp÷ÇTëƒLþp¢ŒàÐø¼¡åD]?Æ^³?¡©Óœƒ5lfýY—DÜÜ‹ó|Ê×ÐYŸj nŒö€œOhøF&¶¶@Ùßu|ŽÀ¨ h ûpo ²ý<±X½‘H{HˆÆ°¡þäüPr; þÍZ8°nDGJòŒv S¹á$bÏ¢ 8±K°<¡\ò_¾%âÐ¥Š˜¾8~§ÞB™9|úü¬ sëH˜$‘T‰ò[")™Æå&ŠCcâuzßÈÀÀ Õ  šO“) Ùˆ"„‚ˆ›€ û”Û”õK¤êú© êOÎ õ§6êߌõ‡ÿ­K»Ä&G÷ø‘œl–á#9ƒrøŸ“.äZÈW‚»ñây´%Û7›yŒ (}~^×䑞„ºÐH4•2ÉÀÝpL’0èɦþc:‹CæøF&€)ÒÛ¤^Tór1ÀH¦ƒ´ˆ¸ Eµ ªýÀÊúÕG‚R €ÔŸ\Ô_¯qPÿæ«¿…’@4Lãå'ˆ[S鉚8Ó(p¢ý±} | àKMÍ2¯ŸÖøáŸ†€Æ-Ü/GÌ­¡éùö”ß"¡Ä#99Á[L|ˆ Èd’·ç#J«á €¡-@š@Ÿ+%»ì"Ü«÷ÛO1Pjn¨¿þó@ý›«þÖiùíþ¦;;÷Ü ;ó¾3[ƒ°f¤ú*3-µ\CÛØŒš•ꢰÈ>(bÂcÌýáœÁ‡tŸ…7‘}¥6aËœk}Ÿ%~íï4|_öy¼ Gy-˜‚½wF…‰'ªS¢§‚tÛŠ´ÝdÌæ¾é[ßœM[„Tñ¹õ»e·MX2öÂöÞ™¯ÒÉÃiX19µáúmoV=ÐwÎ**㇩7VˆIy9ÇóÇ„n=»«tU#©.¸?mcªå¢·¹†ôwevÏôI›i–êR;C.ˆ·xŸž9Á­M#M†SÓƒ]¡þD@ýõ¯{ú·bn„`LÍo‘áÈhÇfv§7ª$ÿTir›åü†½ì/0GH†wÜ1ãîî‘w-àãÞøntgÛ›«¾o4fgý?†ÿm9Ÿ33`̓Âoµé˜eÎÏ~·w.z‰‘áôÁ!¼’¡0vu¯§©é]Îö*|Ä\)2Ð=åmõ^6uY—_öÄ«ð•ÑÊÅ9•”'|ðìûwø îý±Áž¹_5îL÷Ùýú€BSK÷(ª1¤ïÚÆè“ç£t©•¯gœ«Èî3¦t^f릚Œ‘ïšBý‰€ú³ê_×ôŸÌÜ+À\–‡X:¸whQZ¤h]yóg³¦cµÖøv!R² —ééÐhoàçgåÛkUíBùÔÃõïÞ‚ywû˜a×Ë»êÒK©QÕåUÁåôŸ¦÷z± P lÎ0˜óûÿ깊qx˜í|àÈ×{íÏ~r,a©Õ¿aÿ—hò‡^¬ªºïÖåÐjrÉM'7,%å=Yºâ)!ç’óp‡ ¾9 ¶·½[}ÈT¸ü¯Q†´â§‡®údöfl´.Ú;z2;³@Ú[5´™&Ã; êOÔŸPÿº¥íd€°z möOêãS~æ `9»¡`˜Óù2lÚÅì‘D~‡#Û´w,?¿¬µ¶_ºwÃì$ÿ_Õ?áοø÷ÈÊ''"Ó,£†®êø´{ØSÃGÐã·Î랟Bk޾ù±áÉHꣻ‘ß÷ˆ­«ë®;³r<²,ƒöLÛµ¶dðñþÁ‡ŽùÛSI*xŸÞ²î¨z:y4!#|åƒ÷õ¾p¿á¡­ýVÎæ¦Ò‡«å¯ éo‹f\Õ'®¶Õ¥æ÷‹Øô{ûT컯²jÚ2ß=  þP¨¿õêaíà Ï*à]ë'ìÂâFðÖÑ96{çÅ®$ðþ\˜ÄãØ C:°ò h—ó¢JP?I“æŸ ŒusGZ3÷RüncÞ¯˜2—C‚ëÅ$ M¥töEA]ßyWâðÞ ˜XìÙ²hÅœ3,V#{o*YG[‚ôøÊ ´{-!äOªnxždË?c?ø-!çxÞ¬-sº}¹yr.öRÃÿ·¼UÓ¥#f˜Ös÷;ìè“ß´ýtJ—rwK¼W8ï ïiÆÁ´í7 ¨?Ôêo½úCX;B‚ÕìUדنE¸f6}˜÷w3jYXh¿»aŠßÑ%ºñ¸ƒ0ïâ®å¥zó…=7¿ySõÍY ¸“zhÑ.àp[ß%#o¼íªÎÿ£±·]Ys/Ÿõ’Q í¼ÙiÁíD‡™mÞ•Ù4ØF_ÄÉíüó©£Ã޵&Î.–ÙO$Û^ç¸Kì¦?û½~•Ú¨õîIû½ê¢Ùøvë…?} 5~§YU†¡áöŒ!úéVÿÀu"x)«Ç—û/=ÉÒH@ý¡þPëÕÂÚ1ªærîüù7Žmb²8W>ª{¼WÇ˜Ž´ËlcêŸwšüǽÃyUçvít[Ô©¹)£á±€ÿ­½ÿøÀz–߉.}ãUº—˜9¥é^—ù6­ÞîÊ¥Øï;Ø»{D‰™‹Nm•=ZšÛ 0›ÉBðÀ¡ó=† ÊeöÝ>+|&i±|ÍY#ÌžI¶]ò"x1'xÊä&~Òé—Öju&öuY×TxSvôªñCõ½ 󞼬st©6üƒû°í~¸¤åóO»×²6“P¨?Ôßzõ‡¨#Hžo¡äÓÆöe’âÛè—ʦ¹u÷ŒSø —ßcà±Án½üÖî³èÝpDó·?{Gþóƒ6Ýø!(¹Íñ=>If¸moçä¹’Ã…ÐÖyÛÎK,?0…ì†köˆ×yzsw>öEލ:<šÉ ØsÄôóUôEñÉͽŽo.:u¨ÝqÜ^¦´ú}F’/ÇÙ3pÀ+BŽ[}eOèµy‡ûo·:$_òÁ·ŸjúóC=8ÎgS’á¤KU/»¼mò4ò[syÔŸTõ·Pÿº¡ÿç©QW°âÕüæ¹Ñ(ˆ+œéÿ(¨&´  áßÞ÷›Ðªü$ãVÝø3ü]d6 ³1ë†BÎG(_¿ŸG¸§ØÇ³þí’Ža5&ž/g¤÷u.\GÉçýöÓ£W;÷%¹áÆ ,w%âR!ò›3Ä1Þ-ô1ý"æÔ û{3)Þ“˜U6áCrÌé€Ü^(Ùp§ödÛSUåÄo(&ßî&† ¯Œ{¢¸9?ävΩǸhì)×Ò!Û~hàzØì«Ö¥n=S¼?<†œ(õ‡ú›m, þuAÿîf Q—¡j4´å©ZîÆÕcÎÄ^ÊÛ®üÑÍþ¤9ŸnZZh§¬é}œ…ï?åëˆÊå“›3SQˆäø´†¥+ÈÇAS;ºº¹ÇÇöw6òɤ`DMÉ|?û.WÇܪ¿ŸüËÑO{›¹#5þy_¶®rqQ«Øw»i ^õîPݼáäÓ[Q½ÓÎnœì¥ÑOØa\ö%ʱ!~oÒNãI‡&h¬"¢ßl¸>ÒCñâ¯A}?™J[LGºÒßžhg,qîwYï/=uØ6Zý'ԯū“P¨?ÔëÒŸõ«ƒ¨ó(–,ÿØé¯më>‹ Ü[áãú]iábA|«Ö•õ°kKœ¥¬Ïæ`ðƒ,o»¤Ÿ®äQvÃÐ,wáÓG>¦ }˜2pϽ˜[kÝp–•5ßÁãE:mÙ¨§HS/ÜÊ+LyqOÛíPÁ>§Ð Êwâ·Šªð«÷–¾L¢Û UÚxÈ)&÷æÀ•û‚ÔßÙ”÷Ó·H»ØÕˆ ó…Ûÿ­&ÛÆæúöyNȼêÐã’&ñãï5QßYy«¨‰©@ðõNã Rö.Á°Å´™ýXï®-¾è0KówtÙF¨?ÔêoµúG˜m'D]ÆíÔçÈsßÈœ)æÜhô>J©ð}É篞¨ÂgWùacÿtl{ÖÜñ¢g)׺¿ÎW¬CvÃá1urüó…Ñ*j¬†¼N>ý º<{ÃŒ{qN¶w?\ÈàeD>&¯­qØQ0ÐèBß=tÐü ¥¡Y.²å»%åº7˜fK/ê^¦ø5Ãæ•0¬­F{NœÖSýØ'‹ßï®W¹­³Î0äüq½ÈÆ{§8–W›¯Ÿ×æ€6I¢6wš3qÚSé\׳ˌ·ÃÿÑͬ§|¡ÿ *t'‹"÷ þP¨¿Õê·Z9"“<½|‡ž;êUmþ‘—QKÝ' ô¸sÆ çF Î]´h+¶øzô$óü˜L·ï{Û]ñzÆXœÓí¾»ÎýHÛ—–¬Ûc=6¥Âó†EÌn]}½d^âò‡7ïü{Nµ‡Á ¢.¾]rˆ¼i™ ô¯çïùcœ.Ïå ߨ»_£Ô_9jÿ¶WtT5º nkyú—ÖŒörtÓí…ìpø ¥®3ûsÚžÈÕxüƒ}ÏÞ÷ÈwŽó3•¾NýÒø¡ÍÆÅ†BüëWê¿å¬7㜵 ¨?Ôêo½úCX;¼¿ )égóúy[:øôéÜql«ñ_Ðg€y‹"§wõ˾¬§Çtçv5Õ~öÏö2Œºá¶æù™Š9 Å~.ÍË7l—~õh])¸Öì—‚µXÞ2w„Íö1-·÷¼§Ÿ¬´tiœBñÂQ1¾ßÄ/Qÿ œð–‰wÇåïÍ$ƒŽ2™¾Èþóg8ê’¡žÿŒù¦ýø2ÍQ¬"û!—(Æ@Üã)1ëŠ+7FŸ óªêò`Àצ£\¹GfÅòÛúäÐ6w ;›T¶3:êRP¨?Ôßzõ‡°r‡Sœ™»K®Igq£±ñ»žŽÛ­òDªî©yBÛ‡.µ8ÙÎB~3Á}…oO3¼Šl/wI@ÉÉŒ Œ|§sÓ›]¨hrABã†CSª?Ìô¸Âã ”L¨XÜý*_{FFê÷F§ž±ØëÑmî‘£QÚý3C. Ø]ÿêÌÛQĽP (|’l -Wý?·iÈ:}zTy'ïÒÑ)ÿ„$cØåmÆn ç ™qš¸R·pE“?w>¸^o?.³cƒGÁɆœ›S?”m‡dÚé·þ`MØFYôË…_èïêõ‡ú[­þÖþ9áÑ–aÇ)YöfO ¿Œ¿¿2ì[O¥æÍž‚i/vòë ëb~‚«¼¢ýa¾³“hžÓEGòynFôf9o\x+~–²8¥;Å 'ñu¯YÉYì‹›¢ÊXùȰs’¥_©Ç‰'?Lª°à½XÑ É«m÷µIäEÌâgarÓí ½´Àgö2¦×«…·L˜iŒ2F>DOÝ´ xßr[)Vu›Oõšö´ÝêHÌ9éoü€ÖD{¤‡ û5|¾o=ÅX|ç‹Qåúä%_WC¬Slw¾!¬êõ‡ú[£þÍ·¢C$[¼ù`¨ˆ Ì2 @ù‹ƒÒ×(%ÏššÏÃ,ç®%X\”"þ >@£ü‹”bCý@É΂ ì$úr Ÿ‹iù@–%c» _¤¢ 9:¾<~i åÉ¥älT Ç_DÍeªL÷ LjØ8ú“R’EQ]ûQ±öº@}E¨?¹"¨?S£ þuNÿÏ ú€¨+@-ïþ˜æ£þËäR‹z À„±3°Í©2“q­øÄй3Áf•XÍçÈkÇHdè&…XKˆˆ#Kdã«{vZ S¯Ððãå>¥T±õ$2Òµ|!':3IBS„ÉÕ‘,à „rE‚˜v@Q‰ÄD›±ÄR7OÓ~10P’9ÔŸ¥YPÿ:¦?üÿoݵ§[2k(7laÎJáÇ^ >áZHì´ÕY‰b-Ÿ«¬  ‹#6&ÌÕ|ðÄ4šþ‰ãs•êžÊ¦±õ”“Hw ?zi"Mý€/¥Ì €@JE¡DÈQù@$Á­8¢¨É ÆÁÀ4 j¹Õ÷¯R*ú ö1Ôêõ¯+ú×~%ª0ˆ f{ ˜YØ–ÒZË*Íó‰,aÄÜ‚ešKiø|‘2AjéÈE±kM}Q˪ùB2˜û¿Ž/HJFdÑ<àãn8.~o­z –œLS?ÂSRFÒ  ¦5@‚ð„I>ŠàXA€éžp³à±¶ýR±äóý¡þP¨¿õêaíкÑĉæÜpáÌ‹[›!§ô% ù üàEÛ’u—ÒºÑÄ»h!/¿Œf†.‰cíÙz>[Oû€o“Ìà €›(¦º!È)ßyPm%• B®‘ ¸–°ˆ› íýˤµœƒ+úCý¡þV«?„µTÈÓ¸‘Xz ‚ÈyØÖdº®¤ásåì|"÷^¶^at{ø–Ð0 Í!»ÑP!'‘Æ…ç²…öèùñ³¶©X¦ à!Ô }«BãòRý(WA™2PWQ‘ºÃ#ÂøÄD-Ÿdº)Ül€0H´í—*dl÷Ϩ?Ôêo½úCX;4n,¾RƲˆDñ¾ØÆerz -ßr7 @¢g®ËÄub³n<W*É&wh>àld}²×ó9Q+ØêHÄr¦iÊ•% |n‰µbDHZÄD¨L¬®ßÀ'ºñAÀÄÀÐÙµC¦ýqÉtnHËõ‡úCý­Wˆ:‚Zy(ÂG,n4þâ Ôu*¦.`ŽO², *LÃ_Ër>à‡(VR#kÔ|BçF<¿¥Ù›˜ 1•Ù¨îgñ2¦a Ü$1Šp•Œ°x2Ê÷E³(KÅÚETEˆ1@¸ `3>â#q`l¿e€úCý¡þÿ}ý?ïÝÏu‚ÚïÅÑC³†'eØK€(vV&cy@Öð% Kê€;'n;i¹ÍR>à¤fÒì¸Õì¦åJ©nH ÌaZ¹Ã›!‹åJuýŒnH à¤2½]å$ª;žvŽÀ§ ¢[”Ju÷¯ãB …€–oá÷Oß>¨?Ôêÿןxb!„µ!J.·Ü G‚Ö —(§s£„¶pe¶’ÕÃÄÂ'_-Î7ku{¬Æ¥0Ǽ¹´Ó5_À¥ð(4-Õ‚ØX4¤¨û¸‚Ñ ‰D§0ùˆ—$ÑÖOä˜J¡®"H‚DÿñJ5ÅÇ‚€ñËø@›ÒðùP¨?ÔŸkUú^Ûau  67+ÆàÔíý)L!G¸XÊ'Û #çä¥Ót&L`†¸~9Lž8 Ÿ¯"ò²(q©‘1€“!UóyI õ.Ê8ÐLĺúy*œáÑ„QW ëð>JŒÂhÜdÀà Ô¸¡þP¨?.Ϫô‡›­ vGzRèôG‚„ã››¡0Û´|ÔÌ‘œÊŸ¿ (…6’Ø<åúl\Æâ†ñ€ï†h$B?_ Q…¡ÙrÍbUÊèêg‹ÒMôõãø@„P†Ô@ ”èrôüTJˆ"ìÂBjy¤+åÖ þP¨ÿWÿÏ“¢Î@s$'/á3ŽädáÀš‡%ÓsMá³¹õ&h¼*_ÅI¬æsXø(gê¦e,z‘š ÀܹzœP©Ä:~­“3£¹Ll¨?^fäÓN³ˆ  ‡zkù21Þ‚Ì>@ý¡þP+ÖÂÚ¡qñ²Ï>‚˜fïÏútêÑÌ|67 f÷OîJÆ®DïÆ3•Æyoa9ГÊGãåRâ /Ôñ¥uã)iêg‹2Lt|>G¥çD  †‰Pò !ˆq9TËGÓð;­ð1@øs@p¯1 P¨?Ôßzõ‡°r|Þ‘œÌ|€ò"‚ùI,¢YT?„l¢}iŽ/PÑóˆõ)JeCRw0ÉâýóÍnÖØñóõ«p@Ĩdä½@JeÝ1àêÌò  3™iøQ™øú . 7˜Â þP¨¿õêaíøÿpßÌ©Ûû“ŸÆpô‡Y>¥pý£ ‡ÖšÐXß­)f~êÄûçùå³½ÛËH-ÈÔ¸7ƒ,8€17 ò®’:i ®!ÎåG­l~€úCý¡þÖ¨ÿÿ3åÝ.ðˆxœí]g@G–€ 5ŠŠÑ˜Ø{ï-  Ø" ˆéHçúíÎ^?Ž.6 –ˆèG¢ì¨ƒØ{‹ØòY¾»ãÊîÝîµüûvž_³3óì;ì³3ìÌ;ó^# ÃÂâ¦ôŸØ³$sü}MüpæÄoŸV®w[ÐigS 2XO­àGòƶ^^R[8ö/#û~ “cöÚêFBSü(Áˆ½¿ÿeôe>ç^]Ųý‹ÌýU±IîEv9<âœ`ÈóŒ›'Í7|wIöÕ9ÍE|v_ûV]| ߨn.®SЛNR »J\×IVñêÐÓþ‡]ìÂ.}4¬>çÐ7OˆY»›´£¿b8#{N*ùšŒå·÷\Öò¶{­Ó¤ /D“ #ûK[êõ‡úÓWºÃõËÆµ¢ÿª«ÝmºÓç#—JÞÜ=ÚÉîSlË¥â?äVñ=Ú¿-NÓöÉùmv[Ûº¼+˜0Ä NÇç’ £_W²i2¢~ën~TóìzÛ÷JIÀçãÜk<£-S‚…»Š´W>}/ô‰íÓò÷uúEËþN~AÁ{±qá ÜõÏCÕ¿K¯êXöHØ&Ïh¬Ëì-:JÌ¡·dÃq×~ë6½SlªîX¶F}1nMiº¶Ì7¯ÂU;…ì> 5»Ð-G?\Aý¡þPúêAs Í÷¸Ž)Ú½w/+Ë6~«Ò =³jü½Ý,Ï‚‚ng¬å·-ÖœõÅ¢2ðÙÀ…w3°s¯&¿šãƒ¯ÊºŸœ«"4 —=:ÓeúK¦" ë¾Ö<»×ï÷få—/AõÙŽÃ÷½œúVlÒóû–¿ïvPî\=_¡Íê±ÿîÈ4R®ïú{‡®Çg 9pû„Üqø‰°xµQíV­+{s\_úÏÏÅg4*fGI‡_pW¼ÎnÞ³uE÷÷l¥Mxðù¹&9Ëûšžõ‡úCýé«?ÝÁØž»ïz–3ã[‰M|æo¡©ŒþƒW½Áª7Ø%[Ѓ Àª AWžf¶ÃqãºMõõ»Y~6Å<Ÿ}2 jèÅ~“X-õü ¿î|÷­ÛoÙçþáçóü\`tMéÅ&©4×Îó aZ«õ¸¥ª"‚ó_ͧ:0ò•_>=øÜá…ÄI ÿŽw_´H©YP´Â°öÒîÚ=$fÅ;uÂ_sÚ. ìÚ¢µ˜ý·Ê~nN?ýTêÈ‹œ2múaÿ ¥ )Ôõ þP¨?ÔŸ¾úCÐ^£ê?º‹—t¿`›0Ð']ñ—/#—ÿâÄ^[øÁKTÆüYÓåŒÎþèÛ‡{O ,øÍ¢…†ôXïÜï<ÿkÿÎ;¢ª°Û†tS$"¢:3¶:åÛkÁF jÔfuô%äD±œ¦N}Ý?ßI3à0öÄx/§¢?t…m fÅ š¶º;kŽÇÑ£ÚhûDĬ1ð×ýÖ„iîXçí½ÓqŸòÒ¡ãUG]YèwmgjÓÅQÑHCŠ+%Þêõ‡úÓWºclýÙMuçc/*²‰>òÒ¥×[׿N†m¶Íþ÷ï%ú,Ùxs¿¶glIw‘,è.lf!ÚDzyöeÇþ¢qù•÷8åú Ôbû3¾(jÕÎ+ètõóugºŸ³Wóf7[ù~¼¨Ï§õ+UW+öwÙI5 Üská0ÃLÏ6²ªÙÙ«¥F3€W/~CÌá¼ÛùŸ®ÿ²¨ääÍ:Ÿf+•|¿S‹yº²Fk±;ÚttIÞ ŠFAý¡þPúêAsðß䵿rKœºùgJÏ5‡¯{6ûúË­¤x¡Kh$@>ç}DÔm÷T¯øñö^Ûq,¥ÛÃ]A”@òžO~Ödÿ®Yêž9¼íÅUñ\,·¶×t‚šó{]’ÌUÿq¹ÿ«*ƒLàœ¤`Õ“Çÿ™ S^-­hJé|¼zº:Ühž¾-(ù±SIûƒÃ ¾Í½ri~˜Õ nBhe±g»—] ¶Í]Äp80\Šý²n×g]Y¦ÓUÝH4ùÞÑ‚úCý¡þôÕ‚îˆ[ç͘Ûþž3‘ùÊDØ­tØ:^öªë¹ÒYß¿ô··š¯Fbñ¼ù}gÄø¨äû ‘Õg^ïäÊ,ç3vÎvyå²³¥ÿ;!†u`ר+zYcÿè[÷¾j÷O×%/L9RŽMŒ³/*—Ù•®NŸ6Ïã÷@€Ù{¹GÂl€_ŽÝÂÆÙÜS“SoÝ(œµ¸Ž¸æÞøJ™Áuæï¨ dì)LÍ==ù5ûAžÇ⛉BªôLÏÌ®ƒµéÎï–ñ€úCý¡þôÕ‚îðù®¿`ìäùš·Žt¬¾í\ìáõûµ£#Þ"‘ñÍþb×.s¶“Ž·?„½);šþ²ø®™žhÿ; Zðu±ëç_±×OÊííjéê¡rRjæ¾âžûéŸ2Ó5?ÌÚñšÄ1êkwFqó‹€W»¸ÜæË£âŸÊø*¢$?âô›ÖÝ¢‡Æ=!Îz®öydøÕ~µ®˜°¿(²ÖgÌv,"èÍšÑãG?]8¤›Hÿ誚ν¡I‚Ó?SïýúCý¡þôÕ‚æý®­aÖ6ùpj3ÕîURÖÁá~é›öF؇¾t=+`íŒvg7¬µÍþ°ŠéóV ¹°vÎÖÜd·Ö•Ísu íûñÙÜk9÷bC~n£:„KŠéwÅ›vuе[=Ÿ'ÍÈ ‡Ç»§ÞÓ®"+™úxqÍðŠÏÄ? ˆï¬ «¡‚/»‡Ï(²^›üC•—¿©{ËÃO/Ý!V ]¹² á ïû‡tåˆ4ý¥ûÖëk_ÿ^é¿óY9¡Z·*û«µ6P¨?ÔŸ¾úCÐܺ¤»?{}¿tÅ”o¯fxµltC².&c¼;òÚQÞAÑ+§˜u£‘‚÷HVíà³´³6=±þÂ?¦UAý¡þPúêAwÌêÞ­]¡]—úgåUïúàš»çš]Ç/dk¾1çöúúCð”Ñÿ<Þg›}Ï~íW—Xüöç¹6ñ½†8<°êf«ÏcÌÃÿöáãòÓ{0Ìw”ÝòЉù®Sn>öx±Äm5åaÉÄzÿFMøò4¥­’në—‘ž”šÔâä$gׇC×9|vFwJØ=ÿpýMbEίXDȶW´V§–º>¹ëõ½œûú!¦ôîÛïË/ßÀLêõ‡úÓWšýêHØì5“sÍWŽúRêÈÀZÏ©ÔEÛ_õÒáúa™I7%@§¬eC£jžȶßûø¦ƒ;Ï¡ ÂAÆZ&›p_•xjìŠ/ÄSé²Ýïí@›„FT÷L÷J[Ô:ê,ÔOS½Æ’–T¹×ÿ-ÿg›‰3‡ùß^’¬Éühp±ÁtjÚ£f·à3æ••÷Ôœ^ÎÉuºÅ©‹ž¶`dŸyÚôµ¡ãMFƒúCý¡þôÕ‚î`Ÿdî{}úöXÑ`³pî‹_uh9±ö~_Ü Ê9“XR}ªÅ4q›"MýÄIjÞ{Š ož´§m‘ªØ³'}j~)@þ!MG<:âp{¼:É»Íéw¢,QÑžt2fLjâ_¼MÜŠÿx™wÑÈ?3“[Pœ…Êt'Š4ÔJìV‡›R1£àØÔM)öš‡ºyp5ã:y2û¦hÛ„Ô‡{ä;]®HqÐÚš“õH[±ÈÛÜÒ,Ôêõ§¯þtGHĤ®Ý™…¢‘·L;‹| ÷IÀ‚ÊŒ#þWXô¸ö5eûSFP»Ñ¨ñø0zþÑ/nr.wØ[œU|?æÙÇÿi±öEáàóó7ºÔŠš‹haŸ³åíKV“Ô³{wôË5yã¸Ø§Ámª&ïC~–jf/Ñüñ¤%Â÷§lŰ„b.-’^îÑpÐw ÃááªÝ­Ò;2>T^ צ²;0þˆbï©ýeP¤ÕSÝ–¬(ó?õõ‡úCýÿ_õ?kªé´(Ÿ%‘Š„˜m[Bp|€°Ã²×$‰¬¹“ ûIœŸ/˜¼ŠÏ”’ðçU’jšLä®ÿêd ¾‹•w–èê á1¥21ÁàGgQ>”)•èËT|†LÅ< 5~|Ô0åIpTò¹‘Ëqö · PL(Ð¥Z¢Ï…úCý¡þ4Ö‚îá±åR¡Ù®bޏñ¾XqªÄÊ)ù\™}À‹Y´>Û¸OðÙIF|€ÆzïL¶ -:>Æ ÉH³¤ñ€ÁÌ —¥ ÚGd2ª>›0ʨøL…LùüX2ãApÄ™A%„Áå2Q_ )Æp"Ð5äÔêõ§¯þ4ÀP„Ë—‹m´|À ˆ_“dõ«¥âsøIbñNhÈ–tó³ r>@b|w*,qs©ù<…X„DH3-i=à†¬!|£›¯ÀÛv*e Tâ@U[Éç%+íódÆíExRƒLÀ ÂpUüûÊ>¯7¿ ¸ÖAý¡þPúêAw(ß`>[ Û¼¨âA‚?¶5ElÃ(Bj ÌØ6…ERÉg ‰|€Dùo³¨ÿkø9ƒe[²x Èô$ÂXƒ¡<¶@®·èL±¥€>K(q¤Æ$ÀƒL”'&t_åŒ@¨üûµö-J¼Ôêõ§­þtÊ7X*U¾ý6ŽaEcùÙ2ÛV–TöYRÞ>@â¼W­–Y6œèøz:?*ts’¥Û\U|¦0JºŠ²×âÆci=XÉgÈõöQFmeÈ »t$þG”k¸ˆ!| ¡žrF ÄÙGQ¡¾­:€Ä>Ôêõ§§þt‡Ú —$±ye…‡b…éR[=KFö7Ò¿p¹aG1Ég+ô|ÀˆÞ˜dyc”|Î2n¾Ô" +n…aŸTñÙ:7 àÅ.§œJO4|fôzï)É   C¡g¿ˆ0˜püAý¡þPúêAs¨Ý`ˆÜÐ g!ð½±<…Haߨ>¬€èí)–o&V»áP=ŸžX ·¢)J>c^qŠ%í¼àÕFû’T‹ˆD9‚©ùH‚œrÙ@³ÊÊïd6^à°Ó(CvÐHå Ë”¹aIV ]€‚Š*>S¤âcøMÀ„ÑÀÔõ‡úCýé«?Ý¡v£É¤"kúìÏæ4)fŸÄ¾êôO~ŽáÊ—y>—%oàsBÀ+û?Ç?Whø&&ò2Èú‘Ê>Sí†HÔrj_"é@ÍgÅÈ’d†öW]€ê¯³O9à“¶êõ‡úÓTš(_$.Wn¥`|f@üÊ•r‘êEäð¬åís¸*7 à„eX´‡p-ã,•¬2{x˜Èå…¤§ Ga®ý€I±SHe_ÍLõ Š €êé%Èv²}²@>Fl€æTÚ ©â6£ÿ€úCý¡þ´Õ‚îP»±€ñ"”IÊñÓ„þ°…Of°²KR¬UÎ"%‰ÿä\+û??Bš)ÒðM¶ðCs(æ ö•# ©@”åD æ³@Ñ H²Hâ‰4öU|~0>ˆ™êõ‡úÓWºC“-¶"$(|Æ,/[Þð^YÍ'±Ï ¾+òÌÿ¤à«Üpb)gIVŽÅ»‡ˆH4?G$Pñ™“nL€ÆHS¨¾î5|A|2õò#åCXIB„ÏP¹!ql„k„TU µö•|&" ºé€¹êõ‡úÓWºCåFbË%–ºñÊŽ Ķ%ëBXÉ'µ¿,Ö‚àŸÔ|&Ûà ë–›¸J"ÀðnD  L¦‰¯{%ŸÃ’1äÔ;€04QN1à¡2eK8LÞ>àaF+€B|<š¿¨ù˜¤Œ8˜ÿõ‡úCýé«?ÍaUHІ³?ë3q¡?Ô|^Ò¿)Š0c 3­%Ž·ï³>Û:> á [†Õíç*¨Û8!kMM.”S"N,²ZB9… ž ª0à*>W!ÑŸE"[4rê7ý¨ù 7‚àO™ÿõ‡úCýi«?ÝaEHP€°ÂÃbBôÎRTuúËK7ã†3u”á™\`%e.Þ¬ ¢ JÅHx†Âä"ª’Ÿ L¦¶O=@¸raƒ} ×~Ò@ƒC@€/Ôf¨ù¼4œ}€þª¹Aû¡þP¨?=õ‡ ;,ýeP€òâ}±Â ‰Sé_ý²(àÅú®ÌslþeR€&zæe d¿ j‚Äò.Òëm)*%gÐxAªi/šrZ䟜AÁ75l±ê»^ÿË šúF+€F‡€Ta@ô}œÈWÂE5® êõ‡úÿ¿êÿ?®”õ,}xœí]w@ÇÛF "ƒ±€±‹QT¬QbADE#ÖÈ!EE¤—뻳W8îè H ‚Šb½D±—` Š…ØËφ¢Fý»·åð¿ç™òÌ;wÏ͸3ï¼³&3ƘUœ›pìöÕ­ •5_ø¹ç¼·×ÚÊHEÎæov7¹Xr¿xs]-£½Jâ#)Í8jõþéùuåc˜°Åš’fׯ °*?µÎHÒGÞ´/íÆ×|ŒiVW¦4?ïôßÑlêI/Ç9&3¶®€)›w Œ4Û»’ª8ao÷ <ªTvøû=º?âb—æuâcX@À¼3Ã~´Sü1Ç»ã0sûP3…¤Ùo­Í÷áç ÑY÷Éeƒ¦:‡}!ñùßç›cn.0vf—àA‰ÃV{†ý#7(¯`ê•×£V¹•ö$·§µo!ºúJ† ™2®ô6©f‡= ýÂ]á&KÉ—פ!WüCßèì‡Éƒ„ë™ûLÔêõç®þ\ÇÜiö×Ì’…ÓÛ]"oïéa^|>e"æîRJóˆî5ÓîÈÉ?ܺ@ɧFâ¡NËîlÔR|x69â¶yÞ–gëÔmïv>]¦¿Pc¾s;˺œ lu‚ÔÜåí#îöù-´r;rá•ô‡£ÄºÛVš—e™TN)~Êñ nÞƒ7°C¼ù>r©ÓË¢©#)yž7ª÷,ƒ¦åÎ+¾Û…µ>°<ƒ<Ü’_ù“¡™fÖ—DÇOȈÏgœÁ_ÅKÞûŸ ȯL"Ò^{N*ÊÚ0ÙÀ G‹qŽÅ»'îäëw “å÷:M­Ø’?žÂ ‡ê7¢è»D3ƒl³åKÜß6÷!g¸œú*°enI*œóõ†¶HÛÝmÛí]ƒU„âW¸Ž¦$ŠZȇԤ€ezŽóÛ·{®õ*¾Iªz¬ÝÐÇÄGú ‚pÉ×}±Šô nŸ¿ûßîþ*,·ô  !" þP¨?wõ‡à:BÒóY´ãÕM†Ä¯IʇÃR±;_:ÎÈÍšÁ»ý§ûžŸqÃaw/luµëÖY5Ã-<{ÊÄv›\_y|0t£QÃ~U®*iÏèªêy“~~’ûÅ£œ™o"Uõö5Ìço×uÉk?ºÿ¯fSœ¤nm5–¥j¿éfkÿÕä–u/Þ}Â&è¼þ×Có)‰ç‰;ª#:îðz1/hø•wSÈŸ`gÀ¨BF`Ùô.½Dà»ã‡ŠØ_yg•ÉÆÚ wgéµ! þP¨?wõ‡à:f éé3E8¡Cü@É‹C†nùØÈ‡m\ó†uuµ(üÝúëQv[Hûv8z¾<½*«&¯{Ç"ì–YÐ6˜)B¸ŠoóWÔ¬'>œ_‘ÉVuA³ïž«çxDàÛ•HF¬Îüárj:Eë><ÞZZ;„À€ÒàŽßÚ—$’Ýp8”v:i£¡^# ½ãõïw²èª€›Çÿ•Çv()ºÐQXåŸ#ï»^”}‚àb©¦šþF=¬å€´ BŽÓ“‘ùÿÀnú›TÕñIæ—£„œÉ3DŸ`¯ÃK£±1œ §}ÈùŸHdþµÎáTP¨?ÔŸËúCp⛊£÷Ùò’GU¹Ñíšl·Ìè2Û9i 1g{Åwå­LñIq`ðêÐî­SÁ¢‹­V³%d<>( Y6Ĉ#¬W>}ívµù6|–ôV°õÐYZ?«Ó/‡KÓ=i9X¹äÈ›´ŒžúX(o›TK¶¨¤fû:÷ ¨ª„|BT]Ù¶²C Ë>»Çš=ĽŽ;£¦Ñ†HèÃ6ÿF´!Y ­h’@œ³‚[óñ^L Yÿ—9†š ‚O§yûW%¥Œý«; þP¨?wõ‡à:– ãqÞ{x£óKÝÏ ¼9xäúh¬ï‹œ«ŒãÈì­Ï].p~Æä†Š+6Êkaë09ŠÕõT›gÇ>boòâ6òÜIEHüp Ï@³³cÊhø¿&´XíÙ$•®Ñ°å?ÜÝ9¡tÔM™n8Eÿ»ÎâMBLoÝ­NE¬îSæþzå«_.WÛw¼5.l %3('¾ÐŽ”ÇßÐã̤æËL‡] æO:´i*!ð#‹ÇãÒÞ¢çù¹ÎæR[‹“ïyáO˜ûM ¨?ÔêÏ]ý!¸ŽIí:Vœµ³xø¤ÃfŸóq³Üã5ÉÜh¾kG«²8ÿžÏ좯ž*èYjópëxвi][ÝéTþ÷vC‚˱IÖéÞäì™=›¬}e¶àS)õ [xÁ^±í†¶Ýí> S$˜^ÏðcoIJmfº]’ǸÖ&ç ~ãÒÿä‘–ªb©l5ãœÇQ3¥ /’C‘0/‡Ç›æXW`rý¹ ÑlÁbw¼§³i+—4ݪaÞ°gýÍÊ7«ç´l þP¨?wõ‡¨'ðŽNû&Úò°§³Ã¡Ó”É~ë- û¤oëpw);¯†oyd†}×W€etUÆJæ6UÆ­¿ö'U!hwÄ¥íuÇ{Eâ&3`ŒÉ N£ ºüáð ä¿;Au%i¤lò«¢ü2¦†mŽÛõïÕ´xIBÇ?zÇ7dê…³¤Iósq“èwÒ2èÝ–î×½+c¡ì÷öQ2Qp!¿™aö V­Fµq¸5ôÈ|Nóbtõ…¶¹ø3Y±ã‡ÿ£ÿcÀéfãÊ^LE þ4¨? þõCÿ,ý†¨ß°·FzÛMP‚ã¡ù·íOõeþØe7öÁ"¹Á#vÂSÁÙ…ý_Ö4n¸«·Ÿ.tõ >IsNGt>p™¦og'YGš+Iuß¹vÝç^Ú¢H|Å_1ÓÎ}†ÜÊÐy'µ7k»£¤cÿ%¥~A­{g.R|ºÂû"¬`¬«íÈ8‹ Û%|ÝŠmî£Êƺñiê;f5µñü¼Á÷ƒ ú?&ëÞ!%ê+nï±Í烈՚zÝ߉OWä[TîJŸùLÚ™w êõgé;5 þõAÿ–,ý†¨ßðOŽîGçcÁŸá–Mfí<£È·V•SGþÂECÌ7ÞúÜ ²/iÑò󣋱×þ¤ )ò °ÿè;õ”Úömÿ‘¢ÂÎe)ÁÔ“þa½o|Ÿû0µg1™ΛÀp@X@±õ¶ ¦Ms¾›7ctÛ$ú̳Õé9Ä™&XѽxОNEÚD—¥›Âi6=7zOqcIƒCÓúny]ø[Qû#µ™wzÿCZŠt›¶»Ÿž>/­ê ÒPuÿr¨?ÔêO*áŽþMXº Q¿Ñ³¸ 2ùz1µŒ#Mž.žœ¹ë/lÈÔ=u»˜[ÇF÷Ö|~ ì Åû/æ5öæy_nbÖ™ïÜøFÜ»!ן »€S‚¼ ÷pÿ\NSìÒ´Ø?[óáÕ‘RÁ´RÓŠBkÖiÑÕ¢ÈÉùq:øôàT!KÕSÏ´}·H™3,w·¹?qf£íYXûÙQ£](™ïîPÛçùûzЬ6¿^•$ú~cÍ;×|²÷6'ÔÛݺÓ—Ùž—Wý=ë§½P¨?ÔŸ³úOaé6ˆD¨VÉeLã`R¾wè²Ìfð4 ±ˆOcYäï³.Y~#_Ûþ[^‚L,ÔÔD^ñµµuý§ã~èrs» ja }4BEY¡FQm_PÃGÅJ²A€ ¤&DY»+¨å‹"jí#€¥ÇäŽ@ý¡þPÎêÁq EÄRµ’iT2Û¯¢¨£ã‹µÒpj`3ŒòçDnŽS|+_×BجM‰r-_ª1šÄ å¸;C0Z>/XÍÒ*ˆcPCmHD±ÔÑC@Œ©dÕö…’ØJ>@ÅÑäú@"'i€%¡ÿ¢e}€Öõ?¨?ÔêÏYý!¸í/H*”Ek*i~8H#ÝÀŠT5õ/‹•OÓ*æ–´F#—éøyùºByùº[1P‰Ðh>.V¥>ÐñejC>@ccX‚4`™•ä|-Hš†ª¿Nýj>`õQ‰’è&Rþh' ª±¬ŽÔêõç®þ\Ú Ri74›U¢@olc\ÝAÇDÓòiHâÀ¹«SõKŠ~'.$Ä}s¼öY^ÏWEÅ×jér%±¢ŽÏ6ä£á’d9K›h„"F;%‘j*û ©D]]¢µ/æWòQQ”ÁðE¤QÄ6€DŸ‚Ê«ùº”Œ­Ï}úCý¡þœÕ‚ãÚ_X¬Ž¢vƒI¸;¶:EÍð³Ò»5Ô|:†À×?/±j$Ö¯#!A[âô½Ò»ñbŒá4$.NÖ°nŠ"jN “ø•öh(ŸR¥…âG'|Û¨ÄÐH>¤¨tC 0­ýo †úCý¡þÜÕ‚ë@û VªªÜXC„AÞX^³ ‘nÈæ8Ú ÅØøúj@è¥Î¤¸ “™ðLF§ž>–I¢¿Rˆ}(fr}I@*~$êùâØšX($ÜСWÝA E¨@…KâcI±T@"#_[BºHåŠ*¾Ö~ PCý)MCý™õ¯ú×õõ ¢º_©Y…š+=õ±?ÙÉÑu¼QŠýJQI˜{Ê* £ŽÙ§_Cüž˜N9’™ø _´†%ªWïFÓ_ ŠÄÒ=¼ã[T#Šjùúrúªé á* ¦!öß Èà îp­}$êõgé;M· þõ@ÿ¥,ý†¨ßŽŠ–ó  w£Ea‚!qk˜¯þ`àÓ¹á/™¿fÕûDjùJ¥d¸R¾Gêrš'yz>Ùõè¯U)A¸”õ P _ÿ é¸kÀ‰t1PJ"Õ*Âoà$Ÿª<\c_õ‡úCý J¸¢¿†¥ÛõÚ+=þÍ”²Ho,7‘íêZ>Ý›=*˜œ—Àx·&ë›EÊŸµ2•¶ Ú7{¢·¼X#"”ô|¥0˜õ PÝâITWŠV¿Ù“i SÎE¨P%Ç¿´Ò ùP ŠÖ¤Õ®Æêõ‡úÿÖÿÿ«Ú¿,Kxœí]g@GÆhl±7b,ØFcoØ[Œˆb,ÁŠ ÂR¯ìÝîì×éÒQl¨Ñ؉ còa{‚&VÔÀwwÜáíÞîÝrù—ç×íÌûÌ;˳3ìÌ;3kƒC°o·;MÌ÷‹µŠŽ>ÎIªL_û|óß>2kø·÷~f¬`·g49«Ý»S“gº%É~0ÇÇšoï|dê‡÷­Ž¤Ìç©R`5²;´ü6¹MÁÌî.‹ ¤܆?¸(µX¬sÞ«1OŽ"¯¿·dj·0{Ètr"è¾ã÷G'¼?9GÙ>àVH5µo6"‹ß> ‹,¸”Ùö§i }â‰ZÛ®1³ÑË;NÈ6ºöí:ñíYƒÿj¨?ÔêÏZýÅ–ª ñßFpŽ»zwÎׯ¼;YÓ~±ëÙã¦Æà^' §[n-TÙµ‚ë›%lÊiEänyÑ_C Ó„Qæù¡û]×OÛ²³§yEnPyעϫš—Òóy‡Û$—÷á42æújÕº%uŸBÿÔâéBW7ëõNbÞpfí°Pq²I² tÁ ¯ƒÂyÙ¬mh|´ÍLªðÈÊÏN~L›0²Úå·o3ÕÝÊ óøû[ßfGÌša:ôþÓƒ"ÃÛ«EË@ND¢hº‡š{æ\·3(Ò³šÞ •øú}òpОáŠêÈØ†Ã}Љf%ØÌø:¿[Ó1¯ þP¨?{õ‡`9ÀÐG‡Ò7ýØëâþlËÆâ$Š#%GÇ ³¼uyO–uþG•„ö7÷JaÆÇÄIÂÃ*WºÖ2(`lÅV·bÏ[y›É9kœl'ø¦iVL¬Jš(»®¸¿5ÕâÿzRùÞS o ëHÏÊ!é»ÿLK2guúêD7GÊAÒ7o‘Š’´ݰ ŽÔTPù2(b|Æ­Î {„ãó>ø“"N›8¥bÐ"ÒàZÊÃÆ×_øünT:Ôêõg­þl‡ðÉÆÆÅÛgø§.‰°ll„AóŠÿ‡cÛZíêú>>o /}aÃøˆª6>çä+$óê˳ŽjWÌSÀˆÿ2ö¡ýÎ=1Yߨ‰Kš´JU¹øè»˜2›¢GYÛ¦)ë68tìÓì†Õ_SsûÌÞòÇ)è­üN†_Ûtƒ2 kS°½bºSH1e>>ê‹Ï}wQ¤ß'#/køíbSÆ!7îí¨í$Jß”È fþO]#Ü ¿El•Ñ%Ôêõg¯þl‡äâ5È›Óg–ØP…ÑèH³eÇ9ݺvÿïòØ….n-Ê..ýоæÏßþÅÕ%Õua4¤ñ°»¯¶ó²Ç¨˜ñSçNiÛjàý%/a¸Y?|R{ zÏ‹üàÌÙCOõò|¾¸RǼÝùYtȆ•äè›?wŸ½|W£EOèç+>½H7ïÆÝk_úy<úß]jþñÏ]GGõP—÷ð×Ö˜hlÅŠsöýÜÔðçùŸ ¶¼e×=7'œ}ñÀÝøêõ‡ú³W¶cáW_ºdñ4ÿpÒ²mÀ»gQ•=ð]Eöo5/“‹¾îûOáøÖïYçép»a_U8uz« £¹ÚÄ¥TG:ñbStóyÇû£}º¿÷CTÔW³¦gê àäü`P¤=(‘ý®ûåéô‚#ùäÛ»¹8·IPŸ ¢KãB×2äMMÁêõ‡ú³W–t/UlÏ»y"%ÁµòÆaÇ›WW]³]»œØ]ÂWs=8“˜bÿ¾?óçñü\œ¦4«ýîÎ@ÿ‡Àø«ßȪðšK‘‰õi¶á-}šÛNØÈˆ?¤lM§ä—mË”ñ8Þ'u¤‡Ã Kzëñ6¶Ïús}G^[ô|²q¿w¢£µÇ VЗ2þäÃF¤{>à™ì…Ò€Ûö„#ՔݯklÀ¥ºŸ“ïŒÊNj®(ˆjö}Æ…ƒD;,7Š\ÿ×ÏO‰:Cý¡þPöêÁv.ƒ+³{<Ÿ¡žÄdÖMôãæ§¡øRßÉ»Õó˰Ò>=ÛÏ‹¯´Ê?r=ù¾ç8çÈQrŸši®} Ÿd4ˆG´¯´§§Gô׆0Ü;›ðñŽœ {ˆ >D¶%Ø¥†l(³Ÿêцém¬æ87†‹žòc—ôº©Š·£ÞK•Ü+óñ$3Û¤„ggþâ~«[Æ&[S#½;g%Uôó÷^útô=×ûv?Ç¢ÄöŸ—ûªª%!á§êÒ@RyP¨?ÔŸ½úC°냿±_þ0;~J¥åGcJô|¯Z\¾ àt`ýªoÞŒS_íORnÝ£ÅA¦öoÜ÷\öà?®øqõís/å–9ÆðÅímsýîíšt¯nÞð¾vLïÌ3j ´zø+F:õdÍûY‡:zz>! m˜¸{wŽDý¬¤_¯ÒqW¨æ-=Ö‹}‚®™)çE_\4ÇÝïîèŸMòl8­£TU.},½e¸ÙÜçèkeÞÓƒ¯w"…—¸zä®q¤"õ‡úCýÙ«?Û1»]ç·_õ¸wûÁ~ †!ü>UøŽúÑ5§c»G¯¿¼ÿû^ëü;tiyé@\áR¹ÍÒzMn0~ׯûün ¨º¹S{µ«ìúÅQfVå’ñ]Ïw» ›ÖíA§¢B¦¬eG[Ô… —ö{æ}\ds)‡Â,÷”Ä{°™b°’Ós¿˜äþdK«“½TÎϧÇSNÌžx±þjÅð›Ýú 8þê’ü5©¸öx~9áØ-Åò~&¥Aý¡þPöêÁr`-,u OÞ»7ÿöÛeTô¡gøøüg–üb­‹Lâ=(¢zXøopö—î\qðáêuÉ—¬àw94¡ýÈ׎Çâ¸8ÿQÒâËr´èvxHùãÉÊx§»›LIÝg¶/ôÖñûé¶¥ qÍÓ3¶:ö~p¡¹ÅH^›ùå‡[8†ÙþâFÚ¢»è¡Ãù±T$×â¨U‡[àëï:;Þòæ'ÎI'ÚÙ¶¸_CHø;ò™i¨êõ‡ú³W¶#ôÞãe^3³ož_z]w»áõ$iÞ€I:ñ׳]H“°£»ÒP¹™¤.B¨?ÔêÏ^ý!ØŽ5.ö'ܺünû öà6¿ÇP¼<êØð®¦6îËÇ~ö¶S¤÷€ëÖ :ÁýÓaEçVò×y¹é“zéí5úNíŒžÕ F®ç ¸5ÿó¨X3‡€^¬s¨_OË ê»Ç±6¡9ÀæƒÚ¬jî ô{§Üû/Åý‘. w ØfK8õ›Û6Û‘ê²k0²–pxêIÛ™mÆ´˜p”`‡LuêåbœàP9—²P¨?ÔŸ½úC°ãÞü~¢<*¸ì\>uþ‚Ë?K=ñ~Ùê S©òí«oî;­¸~†<8`„šÆ®Œzµñ|ù“Ta4˜V{º`¿kÚ¦A³q+&Ÿ~Þ¹(hp늃™Ìì=ýî+›×ÍöÃkš¼,"¾`;?¼la™™rÐÌVÙÈAwjÓºßòá5yÆ{©Ž•‰Ï¡bÍÈ<åBìãuH«*™sºéVÂl£½ÛfåㄇÝiêõ‡úCýÙ«?Ë!zÕß6) "g] E® ;.GÖo•ÿ¸ò 5­Îìñ*9:!Ïj7«y «:^9‚\µ9ýÉžÌ+nÞ!—Ñ8³yÒÆŠ?3â~ÍnxûyÅ~š°¥íñ½‹”=¾™m—‚?Œ°vYOº¨|®t0ÞK¼kÞ4±3WÐõÝâ^ÚB`»õ*Ÿþqø3xK5Õ «[‡ˆ~!Ý@÷ìÓíÇïÿçøDãÅOgo`¶ êõ‡úÿçõ7ÿÍ"ˆÿ:†""¥4 ·n¢ à(Ã<.E-µª€c¨¥ôÐà¥aùáaf‹5ïËÇBgÅÉhËÐñE*>à¯J‰”X¾#-Ÿ/zæª,Úb\,Âd²Ž¯ÖøÇ±`5]=1¾LJ‘P¡BlàòFú“‘˜P¼þZëêõ‡ú³Tëd‡øÏ@Ó‚Q¾D&±²ý¢|Ž'ž¯¶¾Á„ü0¹”ìá†åIÉJKPÇ—(Løú\,xIvUã1ÏÏèó]Ÿ·*+Ââý¡oEEt|‰RãAÂiâ”å©©–0D,Ãëùú²1DF²Â0 ]õ‡úCýY¬?Û€¦ÈåšGŠi2Lâ‚'Æà*…U|ƒžBãŸ@˜`ýº­eb‹…Ró ¥-͉5×þëø\%‘„Þ²x†DÃæ¤((ý«¢ %høW©ô Ë©²0¾B"6ðõþŠÊHý&’R€HbÔE@ý¡þPöêÁrÍ3ƒ J™Är[3aŠx>ëñ<µDdßÈ¿@Eä4t’i¾él)ø†R‚¾ßk©!kø„À"?Ñ&úiC2Ÿï©¶tÿ€Ï¡ÍhýóÃ¥B”v€…ª©nB;(ÑóÕr½ 䚣(±ÀPÂ?¨?ÔêÏZý!Ø yED0%Í$š†¹á[6*$À*¾± ð0È%2KÍ gàcšˆì .¹–'òLø^`ª‚qûz«ÕB*ÿĺøÆR¾Å×ùçc’`Ú.EJª¾A;(6ðUzÿ˜Ð$ˆbGŠbaÆÅAý¡þPöêÁv y‚¤ò†…q=7(²ÃµÚp¾qQZ~ØÇ0$ˆïêôM ¦C 2ß, X–Å`"OËçIëù òÊT2nÿX€8 7æS ¦+€Œüs½ÒÃéøWA9ÒÍøReTh$­ÒtÄâ þP¨?{õ‡`;´a$Bf)ŒeÌÀQAàJ|k´îÔòùʆðMýóëÃxã­õˉ–3ïNˆ|C¢ÈßmG$³…<>Ï Ä%_Íøã$JùÔÿúªhýûÇÐ…ʧ¬Ž~PÏçªtþŠ’˜(,ŒÈ#¯‚úCý¡þìÕ‚å0ìbÆ@º ݘª’Öµ-_¨bΧòoàkwÿà yF©ü¡ÿò&y |D]ÇǸßçF0¾ X›®Ðö6B†Ô[a*sû„&tK§ác åä¡~P÷ˆˆZóê/B1ùõž¤øõ‡úCýY«?ÛA†3kòýÝñmQrCûjßœMà p‹OS1k¹Æ|>nì ~+wF0-ňx«R¢{"ND„¤ŽT´÷x<š@ú|,QàÔ|€rÃ)¹¨@aü÷çéø‘‘Œ†ƒ‹@$!—õ‡úCýÙ«?ÛÑ0`ÝÞŸä•ÑÑV…Iþy2 x{fÄË:”¨çˆǽ€ºÝÐò¹r-Ÿñ` éVäS¾«‹8q4+€ôž„Êa5Fü8ˆëúd!W®Š1¡\B¶#­¢Z õ‡úCýÙ«?Û4Ï“@!·<‰§1äq¼ðÜ⛦–ÏW2à›ñÏWÊpî nnã8tþÀ›³á"âz>ÂWÉ%B™ÙsCˆÀxœ”ºÊøÔ“x!bº->uα p)ŠðT >ÊUQvHF3€zÿZ>Š‘{ ”„‘:ŠEÀP¨?ÔŸ½úC°LÀu{Ò㔤“¯F¤ò/ ã.WäX8üÓßFxf«Tý‘ ˜?–ļûˆG²>´§ã Õ”G’š_¤5ÃÅ4| BT”íÕhPïŸ/ —ФdOä5@Ô»€ þP¨?{õ‡`;ta,1Ý‘š#ÝÞq^¸é ]Œøæý ƒ=C’“,þIË×ûמãÉÏT5°'Ò…Ñ>ª4Æ€q€ú)" a81U áfw,0B{¤'%ãK){$ `!_†›DOM×UyP¨?ÔŸµúC°º0š\.¡oÁú½?™1 Ê÷Üq¤¨Žr=üÓ”ÿ"Œ(äÉabÀ_ ÒÚþu|Ä/ “ùò#€…ðŒÎ Õ)ª ØËƒñÑf Õ$4|Ú%@@ !­íÑðCC7ÉÉk€PŒd‡R‹êõ‡ú³W¶X8T»÷ÇUµY-¥Ù¯J{$'#ïhÈDŒPîÒÄ( cÿ@è§&M¡|”üeQÍ8Abv~@ͧ;ÜdPÏç¡ä0¢É úz@ý¡þPÿÿºþÿ‘Ë%= Qxœíw\GÿÇMÔXQ±b{[ìQ16¢ b•CªÀq\ßÝÙ;®'"RQ ˆØ°+46bO¢ÆcoQÁGÀ ó»;ÚÝm¹;~ÿ<¯gçów³ûž™õs3¯ÙùÎ p((R±³|À¦­Ÿ±ÚÊ×ó¦‹ð/.LÌ_GÅGf{ñðf.oX­ˆ<½‚DMJ·+W•´,oºäƒ³h[«nPÔ®…Þ§´èU’ÐÁ:•ÎoÕùã¹NþURË·s–V¼þ0WeœÄ?æ1ê|E«¾¬ #¾üXï““i2B~y)>¢ÿ$<ãöµëè…ãýJêê?¸§}ÿwdT†ýþEÌÒ„ÿNõ<©p[õÂèùuža~• ÿÐè?sý‡bº–LtÉó½;Û¥Í%³¶¼*oÁ·x,V¶ý6 ¿Ìu@JŸ¾#í~²­ÜAØÌnoOžeMï#y6/jB«s6WÝ Ÿ))ó»W>.ûÑv¶XvãŸM¿Œž6óån¦',ÞŠ]ìpÈ4‘µ¨ÓËi7½©KŠú¦ÇáÁsérº’¹ÉiiõÇŸf¥ÚÍŸ‚?쯽XØñÈäÃdÔmÅøËù¬Ã•íY¶”º·É—Æ [ú¸<̘ÒÿçÜ̆Tܶ´0·q?î­-mEÛ¬ß%§?ÿ™zØÅGnLµtÿ¥ñ½gOüÞ(‹{‰ÚtŽ:=ô;¿•+j“Â?œê5ÜÒÃÔ úý‡þ3×(¦Kô@û.©•˪$˜úÄå­f—V­ÚÍížxÊ/~W±óIu‹±pg½¸¥~a³’šk²SÇ¿ˆ}4Û.ŠŸ6¶£¡/þ0è⻣7É2'©mC'^K5¯@ÊcÎ?jÿˆ¬±*úû=nÌfÑšY]ì¶gUV'L_½m× Ÿér:sÜÁ«ö ÖXååìV”Û_nøÎîÖõ˜¥©|3ãÔŽZ‘‹Wü¿Ÿ€Gìëí&§eõZ£qwŸ÷ý¥"J+Âhy¼/©šónp¡ƒ¡É‡kÝ\]|î{”YË×Ës\ñŽçn䱿ß_=Jl⽟ÎänM™†ã‘i“{ddMxèþ‚6Œ((Jx;ã¯õÄ Q›ÇÛõº-/›õÐÀcý–õ=Û‘.''49V÷•›ÿÍ»œŽ×›ºÝÑóÒk÷.%fõšE|ŠÞéÞ.ÕØ~Æ­šú³ŽøJlˆ¨Bÿ¡ÿÐæúÅt¹÷ê3þT^—÷ïjÂ`“>ÓR>ìý½ž}vYÃÏéÛ½ŸæÞ€ËŽY¾W¯2»Ç2‡q£F,¯ùÁzöwj?ËٵɎÐsDM©Ø× ¹¹ó»Æ¬å­_´ »rõ\Ø>ýÇ%#ì~-8ˆvz±—p@îÉ®,Ûxç¢vÙ_?Þ©ÿvÍ¿Ûs—$²ûjuTt§£·Ñ÷“>Hª‚®º›§ûòWæw”ŒZM÷-*&fóag\>Ý£»uCjðå…È…?]¼}:>ÅŠ»‘ù}Ù]·u›Wט@·â`WÓ³±t+gIä’\>ýåÌW÷{\\ÑÏ5²ì'¥õ¿{áGËkx@Ðï²gëW¿7½†“ŒïkUù»;çlé%0äêÔÚ9_Þ¬Ãñ°²‡Š×„@¡IѬ ;ÑãÆ)#~ñã°Ã“î²µ8>̦=9dÿÁ€±g ©E÷¶¬Ý3æFßøÎo—= ‰Ó'aékÆŸ¤«€¹ ÿÐè?sý‡bº?‰‹ûKoŽR|£Â}\µcðfÅxže5Exª™´r’r8éÜ•‰XQC&%8r­9þ,8x_úÕ÷ªÁ–y#uiþ ‘vï.ºÅËÛ'q_¬é§°ÅNMêz»ÿ½š¨Ÿø.7•Jc»SNxúä¾³ÿPAqYü4R>YR$Ö~)Ã?‹ÊðjG;·'è};“¤$"¢‘¤Q|¼½Ìãw9]Éž7•Ø!ïß¾À]‚–…¯¼-í›o§G½N¹vjCW‚ ÿÐè?sý‡bºV‡Nº´{ªrÌ•ïnï;ÔïúŸõ?Ù°±6 bRŸ‘ã¶kÇ<±õ‰û7TÝr»kÒÔƒ8㟠O&~`C¡AirÜún§uC£[Çþ-ë›»Öñ`²öSej|bí÷5`èÇ>Ëw¸EÁ#==U'6o£Ê/\1àY§Ëñ¡×G¼98§åUº² 쟣f{ŽØk{žžù˸˃/9|>`ÚßdØÜÞ/Vœ&¤¢Üæ!Ž8ÎIì–c_zk ~û{o¢«QÐè?ôŸ¹þC1]®-¿x±tò~ÞA_õÀŸ­\ì¼'Ñ2d¤ïì>»Ù“ëÞmúÕ§ ·]ôÕü§ÓG™]˜ÞöcÑ“%OnXt4è÷F/ÇÜù¬:î÷}ûòìŒO-^]Ï·ŠÍY²5&ÀuG}‚{——²Ys–]Î%|BÓìC¾¦ÎÐÓé¾÷Û¼ùÿœn©e'µ /{q—Ö+Ìõ¸1"ís¬Ù¾¡BGé‘*~—ü·:{?íIOÝ¿Kû\v‘bW˜©ëcÞœeë©(Ðè?ôŸ¹þC1\hÓ‚™SwOY=lâG|‡¢8û<Ö¼`òÈû÷îç%ÐÜÅyŒ¸¯˜Õ²jÕeßzï诳¯Ÿ<Ħ5ìõJº úý‡þ3×(¦+j¯×·•‘ðù;ÖÄ ±6ó܃‰•1í9ŽÔû†füíèw†ÃJ¬â]­Ž}·Ï9ª³å}G:˜^ߦIÿn©Mà­BV”?îϵ·|$é ç‡Ü¦;uçV„~ã4–Ûš¤ý·î*[G—§ðŠ÷âòWýr×_Ü?•¶ðôÁsš­"&‹n.›rôiFñÛ)®¤’Ìøèâyœ˜ìqÿn…áƒøÎ’‘ñ/χð+‘yç–Ó,f¢ôúýg®ÿPL—ý…·~8Ó¿AçH¯X8üU#o‰×W¿R ”_´ï[¾pÄÅ<Ò&ºj‰Ë“éÉ«œ¯[1}¼Š#RºNI¯Oby÷/ä<*q2?Ò” yGooµ 7K]Íê‘Ö훫|‡b€á±³Ï_¤Ï5(Ø‘s²©Ûö;-h{ î袅 ˆäBhd{·À¬ˆwg’rsmt"†9vàZõÇ5»!#»ºl´V½)¡¯+™ ÿÐè?sý‡b´ÂØ!…18o ïHðîåF¿½´¹ô÷À›'H7±àâ™ãíÙŽ þiDuFÆØŠ3±]Áï…ÙËÂú8¿m‘®ne²ëçÛ¿±ƒýÒîÚL…U+p™`׃kO Ý„ëǽž Ÿï!, IWß¼{(ÒR¥¦ÿ›3èL¬ôà¹tº»â›È³H¯Ìj’ò…ß{Ö ²½Tà‚wö(â `“ÅEÜ75Ÿ=šÇ¿ŸÖûSñî‚÷6¿@ÿ¡ÿÐæúÅhæn“6Íÿ´;ñÈÚ²‚4 fQHùÆvתpÍËÉæÊV¬ñ*gMóèä\HrÑ ´2½Yο[“r—Xš€DJV‡ Ü4 ÷¡ÿ¤ä~~ek¾'푤ÜW; Å…Äa:Ú$ýÕ¸fÿîß=ËìHÒÑî³ü–eñh-¬ez¸o/§kû¾£9’4ªïFN~¸*f¿ñB²´ÍëƒHöBM¼Î™NòB:…§Ü®}ZÐ)£0f_ÅKG®'í9d$‚þãÐè?cý‡b¶¼ûžèø¿‡þÕ·2ìÙúI,J±3‡°ƒ[>òý‚ØXœ$÷Vd¯EòÇÒ¬ñ‰Ü¼Ð×=päkŸÏé›pïùî9ÚV[Ìû Nî¼y½ü*}«hx$þRÛw‚nd}w§ûärï-Í|þ6jGF>{æ« Ú*Äëô8(òYWï7Ôç§Èïû´šâšà˜ËŒGW‡ô&9’t¼´¢M!<;5«ž?=¥Å7<_8Ÿj¹²Æ‚þý‡þÿøo呌PÌÀQD(UFKq⯠`â¨%xR²&ZBGÓó‚hrÞBɘ0˜•™¨ äëËçGøoLQØ~p¸n”-ðI‰©Êºò!‰—šÜpLÌVÊLx ŒHŒ¦Ë`ìX¹„‚b±šôa€P*7ÏU÷üü°x•iù˜˜|é0YžÐè?ôŸ±þC1]@×Ì …î÷*1¿€òCðÜ8¹”ö·\ËÛØ€Êóå䬕Kt<_i;__>ÂY’𢤭$+d­]'ÅÄ<•UåÀe'™7AÝó‹ø¦<@ÃcU´Ù¡8FZÏóTJ#ã)e¤4*PŸ œh‘ ¯»•YÝBÿ¡ÿÐæúÅpÝOH$RéZ¹ùÈVé…§'ª,4 Þb©bÎbI~l´ÄÀ Õ6òF9aœ…x¶¶!<É6Ètå EV•„+3‰ [×Q …cã ×Òwšhdl]GbÎëú] ùÖ_QÛ5£Ñ"AŒqùÅo ÔuþCÿ¡ÿŒõŠéÒ5uDÌ&‘tãjÞê0¥¡íßâ‘ ˆ#—FçÅPþ8õG‚ Ýcög9¬äÊfe«INôÒ‡ñ4d<¬ÌT[¬•žg‹R-ì¦x¨æ…~:9O1ĸɑ¢}°!k€ ÿÐè?sý‡b´ôóGQKð¸Ôh)eÌšLhÂp®Y™œª¦î^¬ã XÍÉÖ˜ee%0΢1dã|} #á88ŽbeŽDDÇÊi'!)_ªy¡@KÎ%ûsg˜HVר “¨˜ZŽ#6ýÇ¡ÿÐÆúÅl€ðCðì8øÿþeN* <¿ð- ºá±µY>K´™Ø•XÅÀ]G>MGÁëÞPÒ#@‰Y %¯¥ÿË¢Ô/†ò…! ä<&”‘Íbµ!ÀÚúód*غúOÇCÿ­ÍúÿßâÿÿIé.0•xœíw\Gÿǃí‰ì=vƒ – Æ.v5iék{egëÇÒl($Æ»"رDÁ®($hìOD}îh×v÷~¿âÎç/nwÞ3Ã}vç53ß™¹o0(: ˜ý£µÃ8LyjçڹёÝ'÷ýöLãŠu÷2a£e‹ƒèêÞ+ç\›Æ‹"ãÝ&Y,û¤òÚì$Y*fäÙâÛYa £;v½fï¾5Êì(! :Ùÿþ©Õ…LÜ›Kfu´tÀúÉŸê×z&î>÷™¬Fµrµßó®²¥ pDI"ºóö OÝõB¬š˜7¯t}½Óðú›ë™aÆßÝâB_¥ö£¯Û—ÃâóWËZ0¡ÿ‚þ ú_§¯Æ…ÚB}½½u-õÄÓ®÷ï9&ßwúÍæK2Å Ë 7g5ª\0èfjdå·oÏnÐÁÂn%e8‡¶ÙóÁ?øvœçosZe­&N:2?Ô:yÀ)?ìŽt†_òÀ?ÓÓ‰haEïäæCåÛÞã êR>ófrªöâE¡[`§ä¯¡£Í&'÷o}hvPiL2AdÏ˾„9¼ÁºlÍóY—üLš`pÇvËoSvGKFWê|¶+w:×Ï6“ý'¢¡ÿ†‚þkù¯ÄÂ-t~ÁÊ9ÑÓ22öÏÊpÁr—}Ú†qoÉËÙ¡Ý]f)M£8âÞ“=p »$iš.o÷vFZðþûËKrMñ¼RY±uø’À”IÆÝûZù¾<34!2­£—*9÷9R‰¤•ãÓÅ0ÑOeί*`QdŒ”Õ]rèÎ #¬ŽŽªzÅäO¼¸EÆù°:sNó¤VXk÷2a>a ,›Ÿ¸>›?â·uý;–ö ÍŽ{˜óź_j¥ì8½úý§Pa ÿºú:üÇŸÞ€¢‹ZúggÛQJÛW¼ábIÇÙ‰Ÿ×e>Õ|>È®möïHçê$š=Í^™ÿ»ý+-¯kàÏENK¦~¡Ð(ËfŒ”Yrpv%Aù‹s?4ïTõù)Á¿ª²³zxùEÁ¬g¸|«EMúŒ!.?¸¦[«ý¦kŽ1–g¬°}’>¦Yó_ÜN¿‹; cùΟ0‡9•ÖÞŽ¨L’­3µX¤º<·2ΑÏÙ#_ w…¹Ùºô.ôúýÇ»M ÿ(Têë•Ò¦SÎû'¦ÔÇu澟Ì1éÉÑ¡¢¸šKszYô.+þÏóÉQ"9ôíýÝó/+Ô^@&Íß—o½j×⒠ú÷x6wÄ»gøa4Ç€y½¯r>FØ<-´ìx㇄yUq&̰©+6›ŒYCV¾ÓÖûKJƒ[<È«ùÜ÷o÷¼uÓ©Ô|^â‚)UÉn#ÌÀ¸¤¶··á$ ©šÜ^xŠ0‡ŽíE»šŽy`}°Çõͺw¬Dãv?™œ«iÉø—Ðè?ôŸ¶þ?¦RY¨¯VmއZ+ì[e*%úf´ÅY[n}sªWQýŎǃ5t?é1æÁÇ[Ç%xa4;+ÖÏ]¿o’AÜ–€ÞùŽ}Sž`‰F÷<‡ »•×§éØXÌh:ýàÇóH¼æã‡~Çü‚©Œ†ìÏš€ŒÅ€ÕéÑŸØ´½gœf™ŸÛ«@Â"ÚPì’;g¹aÇš%þ±:·Ú·Ï{…Ó¢‡bÉ ·\ƒþCÿ¡ÿôõŠæbgŸò$sI«ÓBó¬³Aç1¯ò´ÉÎ:!.v>ëpÛ' “³$â2öT>¾ócÔ ßQ2È÷Wÿùñ)ë)óç#·ž.k6I4È8ŒfóÜ)q@Þ.ÙX¹¾&£lÄ\Iƒ0V¸öÀˆ¦»M|-ÜâÐ߇~îÒïÕ¼GáO6kO­èÑê0u§{™Ãx÷‚¸CK³ƒåŒ¢”A•㣠Hkµëùiç|Œÿ8ÀçUé}¡Â\;ËÉÃ\[ZàüÓ â_Y^†þCÿ¡ÿôõŠîZ¾lªMØ<ŒñcYÇ•s¬²Û»³æòõèÝñ^1ÙÒÅ#ù¨qÏ–ßø^=bÖb#ï  ƒ]¶îÝ~álß ŸÚ_<·G>üŽaù]yÎí÷t#çýÃlÊìt!ѦDŸG<ý[—ßö0(mýªOyÖЫBÞ¨O=÷ö)¥RëÛÇ'ØpZóW0°¼°óØw¹V Ó8OWýL˜ZVî´3WÝNIûlrílsh v/VoÁ#qzúí³›]…þCÿ¡ÿôõŠîߤªüÀðÔkÅF»Iµ²=Únä•ÿbå%-‡ö”'6ûp#Úksɵ¼Æ•?¥ùëB§”?î\Yõçöõ¯~pÝÙצAMÉ´o+vv½v¹ô¢AíÓÛŠþ‰ÃÍ&˜âg¶.K-êUñô\ŽîUôq;ë9>Í)̘Íi{›……˜¿<•íý|Á¦Þ”ÖÔ†ô¼ºIEÍß :]r´*øñŸ£ëôÓø?(UŠ ÙZYŒpX¤ÒüñK÷‚!7º¸79P_òÇ;-áÄd›,ž¼ƒñeè?ôúO_ÿ¡h.AÕv;ûž©Û˜D½ÝÑïãŽzcÓT—Tl1æ¿l?þ;iVn„ánTŠå7Ýf;ôŸ9!¥|³RgÛ#Ï7ŒG[lüÝë‚Ý»Vê^¾ƒ_=Šeõ7Í·ÞÞçæû'ö­Ð £w•Mü›®—¨”ß>·}æ“QW~¸¯º¿¡Ç@ÝÍO%W$ÕÕu‡Ù¯¹ÛžsÑ_ö<§ïÑg!ÄYü>0`’Y5ß;ïe¤çÇS j÷RqýÜ-{â´¡æ·Â™ž„þCÿ¡ÿôõŠîŠÌñM/ñü.¸§aç¾Z MXúŸ—fÈüƽ¿lŽ7M¹}EÂáų?wÇåMŠ‘·\¹Æ-ßþÍéƒe»š\d(æn/ù5±]H{0ÚÍÚØLÛšÏ:à>ß9¿ghk-¿ïb —V”ÊgûuiÏ_ª:ö»Âµú™Ò"›Ñ‹¼Eî¶uŸ8….óÏ›01ì³îf%ß«[.‹Of±tÇò¬€šï›{qÑØ³xóÃ>Ô¸Óþ'ß!ÙÆx| -ÁË úý‡þÓ×(ºË}Ö˜‘“Ùõ¼†Óo\<ë°M w›^TÒóÍ×?ëP¬}Û}—usºZô˜i~L'ÑÄÏ/ˈóð±»ÆŽ©ý;À¿°O˨–5ó~e[—^ÿØpßÛ'õ€ñe úý‡þÓÙ(š X?;³'I4èÜá͆·x÷-«¾¬õnÌK«$z½Áðò“›½w¹x§ãI¥ü¯tk[þ<ðBÐùvâGWîñ*ÞU»xõ™u7£ïÒG3ûrÇŠ­ Þ¼Ú#MG˜+“\¾\ ÜœM|³aæöoß_Ÿß…²/¬+O¨»¼wê‡ÔþMû¯X¯=’Ô» ¬›ø,awò »ú ß¬*å—ÝOßdhöRq—OêŒS#ÅSâfý‡þCÿéë?ÝÅ{šÚ¡ÒÓ6dµG¬þoå׎ç` ÞzÊHÖÃòž§¶¾´d+Ó-†8‰þ3½s—V‡´ñ‘¨Åó_'ÿ#^–¨ÜàXFŒ*ýß<Ÿ¶Råï“+yIËv¨£ýòùõÑ|/'ÜÓCñùÏIw+=cGå9P9tÅ£ÄÈ"½µÂh³¤¢›¡åN¬ßt4âv¿ûÄy¼PT´×ò­“­Yxiç(†5ë”m±Ù;sê~‚[¡ÿÐè?}ý‡¢»Bâ\Ã×ì;xÚ­…îSÏØúðŸ,,þí^‹¯‘ò¡ ÎþQg/º5£v¤¨žøòч|7XTŽnrËí›Fðj…§ÿìdw¦í=·*ÍÖZ³©ùîk–Ý%ÞBk¤ˆµ³º²{îª £ù§FÆvû»!m#sði8ùë+ ‡€”®êóþV’Þ%fît 滣-]ž×òKŒw—œ#Ì8X ýÌÞ=¥M‹¡_z8— ±"d!ÎTgwаIƒþCÿ¡ÿôõŠîr´¶îß·MS}'ršÎ Øé"Çî¦Þ†…ǨGt0#>¹’HþçNö xÒþø@®jZ×oùËT.£ûÎèšïÖûÓQŒs&Å¢¿ë¦ÜŻܯ}oUÔšaùßCÓºS;¥ …ôPC+i³Þv¹–8ü­écÀû<ÚuoÂ0ƒ‹^3Z=²ümÿø¿k$ppá­Hâùį_ÚöÓm+—;˜¾ñéöÌŠ<æ¸`§68äèVK™„Bÿ¡ÿÐÚøOðó†P4hÈb€ ¸‘îXjŠBŒ¡<ŽT*6ò8)P[†ÃŒÇpÆrb%i΄¼~*”½T˜©ÄID€í™'ÂO æ¹l¹3(]Jåü@©1äõ“Âb%$w#‰(G…ó !‰¦þ,9*“’͆™@ÿµ<ôúÿï÷Ho¡ yƒà±}ƒ±M1Rõ£„¢\®BÕȨŸH<n˜‡j]4Á{§Ç#<¹„´|€²<å«xIªy®‚ŒïØ1Ám\ ËÓTNÿ€!Pa¢$)EøÑÄy.KÁÇå•âp€%Öo¬‹Ÿ$†þÒУjCÿÉø¡ÿ”Ž*€új…ˆ£(ÔÝ$Ü[ Ðô;†ò oo˜¯î²ø¬NÆëÂRâõ“ L÷¸t9þ+f’ˆ¿8™¤ ®æ9@¡Ë~<ÖtÍ5)¹)#^? é°¤b|EÄx­Êë5ªÕõGâ ÿÐ ®! ÿúü¿ßÿ •…úz&–Ѝ¾Áå±<9XŽJRóŒ ~‚Àå‡Ã>Óƒ³q¥”ʰÂdùe¸¤¬’å¥áÙBðyi2²á&à³Å2-Ðv2шA„É•B5ϒȈÊG9²Ÿ…Ë«›Pî ß`\ ©Cüƒþ$€þCÿÿåþ›øu#¨¯\|."“P ã à„.ÃÖ®”էׄ‘(ó¸Y¢\Ž\‡€á†mU™ÿò· §ŒTÂ÷ßø!akää?ÿiDÙÞYd-†V(›™ ↵µ' ‘Tý®#l£0 Ñ 5 ÷5È?è?.ý‡þÿ{ý§­€úzP—/§ÆÊeºbªÌh±¶w©¾H•'ÊTW?Ï!^‰«¦Âz<( ‘N™)dc 2—oÄ[zMO¦ÿýš ˜¬î¶O4H„þCÿ¡ÿôõŠæª9’7 ¨ÙûÃpä¢%Ä|žjù<æŠðØ,“‡’”èÉ Ô/°×–XŠï?VÔåù!¡™§‡ñl¦ß6{†ê“ׯÒò†G‚š¨´_V5_F$š\!A†Ðè?ôŸ¾þCÑ]Õa(T.2ZáS»÷g]œœ|Oµ|Ó7(qUtcÏÑLròº6Jýþ,ÛK½5©Þ …jyAØòlŠ/s=ÏYšKmù„DëŸnP¾F&€ËSjoW—*jx‚@õ˜ABô@ÿ¡ÿÐúúEwáïåÑüÍpÇâÓ•bk[z¤¨Ìc¸€UÑJyã÷iÊÕ‰ âï½-¦!O»>F8oW5h-Àø>™ jõGYÃåÅÕGŠŠtþu#AÀ(K¦{[óÄ5<á 8ý‡þCÿéë?ÝUÆ38ÒS³÷Ç/Û#3ݳ¯6üV÷×ÃÝ…›•1ùËž¤ås95<_¿mª†õvuy”¹(§Çœå”ªÂýeNã´<ÿd£X¡ñ‘¢(Ù‰b€ÏÒo¡ªÙ³º|Â@ãs@õyè?ôúOÿÿÒWô.@™xœí]y\×V뎥*¨Õ¶Zµâ†­Z¬X-nTTú\P”Me'$“ÉÌÜ Ù @AÁPÔV­TÄ‚¢‚ûŠ ZqA­[]ŸÖº½$,2“Ì使ÞÜï/23ß97|¹÷wï=÷œiFB@4øüL†"1åRinNÝ•…a[¾¹EŽÚ…îøªÔ<¿×™T$fçõ²ÕÙ,=û4óÉ™üuÄ¡‡!cžß/ÏÎbÛôZÿv•âYïÆ½<š™¤i¶,ÿ}Wt;þ  È÷»2[ž^²ô·k¿‡ü~7+úÉC{ŠÈ‡ýÎ'e˜yTx¼UŸCG$M/;\žÿ¦ÃÔ)WåKtŸæ´Ï’£7bÝ·ÚÖÇàʨꙗ‹³#k@›§7z¬¤ Dð†m-¡5õ‡úCý¹«?×!<-½Å?w{b¢s‚î#þÆ7ýbeù´<éÝ~¥äª×¹®IãUlÜ‚c½Ÿø¸<_¯ÜÜ:¾Òñ\ÍVü ˆv¬œ<Ÿ°RÌ–ZE¸l`ÉÝ%7*ãÂÒjƿȳ!î°"Oõ*Ú8ô“ò°ô!rÓÏ&_sÿlþ£ËØ#<;êÒuMf?™öS·•äEž˜ÖFdg»ŠwK .á/0õw—»­ÉòœÑaw!gFïþARúfAý¡þPîêÁu„ĹNæe/s~O’³ú·Þqâ=y \pzÈp*ŠLžàW¸9gâãxæNyö±ø Ôvðñ?a?:N¬(^?á! ~#„‘ã‡|v#7Ø{qûÇ[ºä˜'4A¸ì‡^ûߺ8üíiÇõƒYQù’zµõmãh탷88ö}ÇÕbn¾ü£¬K7¢Ó¾ýçÁ‘¯+ÇT‰IïÌšóòãôF¶¼Øß¹]“k±+ìïH^EŸ¿z<´-E ¢º¾/w0Õ0¨?ÔêÏ]ý!¸ŽmûÚŽ>}ûòÝ"äX·KŸÿ5!|Èå‚Ã6F›UtpéÚ«¥UóÕw~cìrƼÊþç;’¡?LÖvú)Ÿ~öäüwínÞþÕ¢æ“?}Ö¥*$X²m^ðý›™ð§÷².™)SínÇÛÈn†fd޹}ÕzUs+ï¿« L=»éÓ‰ÙÇ–PÝòø-ð#›Wæ‘íñmgùôã~ãì‘1M¯Îýú¹»°f¥Í2 Nó +mM~ ¨?ÔêÏ]ý!8ªhÿbÙŽãŸó®u–‘*ßwûŠÖ°à[ï™7Ë'gO¡Ü\¬-Ô»F·úâê„j=¿Sñì ®{ŧ[Ðz-¿Kñ¤M-ÆÖ,+ÜCÙÁÌtßëÜÅ)|ÙŽÝäï…e>!@Ï’‘orV<.I¡¶%Þ±ÏAÔþ¿Ú7 |nûŽ/^€±Vœ 7ÒsÔ3ï*£ñ *ë.³·½õ`U¨¯«£×ˆu&¿Ôêõç®þ\¿(¦ÈÆ•':îR!"ÿˆ>ç™úÂän–oÌ//]sz‰2 ’"bÂ7VêC¯óx¹µû"ó/L-í÷3F£²Ô>乇² ¶Ô¿{²•,×÷KÚÜ[[¯MÞ¾[F w›ä:ìJkã%?;ƒÓ,ªÐ‹ #{8+üĉWN &þõ[¿=¸i¨ñeQõŸëS½†ÕÖØ¸3á°µ5¡þP¨?wõ‡à:ü½Çöíôîôõ(é”óë45Ó™|=æùÜe½4̾šÁOmÁªÕìÑôö,TÖ_ òw´iu%=fð‹~ªCºÖ¼—?×xѲŸú”>K>ï7FÖÿ >êò‹ oòXÝŸ¡QÏvÙ^Òï$ßLÅÊ1et¦Âø}·µk]ä쬲3{ç´æý~…áØ¼ùDbÉäW¡Ÿ°MY½vï¼_÷6/[ûņGjÅ:åoóô¨ÓR›ª`§Ýk­µfxø9Øy\°úÀõúüÝžÖ;«z†6£âßîyñ}³~¦Ì!%nÓ$iY/þ¡?‡t7­Ÿ+Ý1©CKÞâxé,§EÏ ù(ØÜ§È”c þP¨?wõ‡à4x…V»Gþd½}FgõÁÑ]N[F›;qXéÌmž£lhÃ`Z¸z½¾Ôöñ wÕFÃŒ·Ë-=jB:cçÿwAYÛåOJvúMYÕ‡˜Ôñ0ˆƒè´Ö>7ïÖO Éœöñ!F,<«ïèfü¥.¸î;®p—Wû}ÆGLïä9h›é‘eÁ\ÛL›ÿܺ˜¶¡SF–8¶§¹É+ÉŸ49ÛóUT Ã\,ÛæékM:†úCý¡þÖ‚ÛPðÀ/€LzÑiXË7)mï²,gØßܵzÕ9Ñõ5Æ%M‡nšÚ¼ÅÀ`'7pï4¶êÏ,ºTæñßý3’æ˜upÍ6÷âU3¤ìÑRƒ\ÚšØU$¡þP¨?—õ‡à4çÎÞN&y§¼Iû/ÛÛß;0ÓƒqÌ¢[©ï·–ý°h…eŒ$QÞ´,«žü6 ‚r’+º›ò2±Ì——5]ÍØ'µùÍý³_ÅhW ؃”‡AÅ gj›f·‰ ¿ðǶR{ª¹îP^¸æGÕ@ÎJøÛmn| ©9ûæè•ìܱÊ&*,™3¼ÜœÉ;؈-;oÛ8’¦“·1!”ªÒ‡¿ñ*ŸY'oWTŽ/Ý<´ñ°4sïL“*Ôêõç®þœþ‘øÁ$—Öä~~醽iJ÷àÔW¿î™Õœq 0„'ºÍ´Ý¿Ö;J¾ßïúÿ$ŽÚr¤Í™”Èäszœ9<ë5SÿØDÔËo«Oxèw £–ü4õ»Áž™õ’E9ï27%9—ëÆ¬èÌ)c¬íz\u{j–™ÛÒÍugw˱9ÎöûÜï»=0äcä#/mI3g³üéàG_¸óÒ_ϸC¹ Þë=žnuå›ï"Î+Ýúáº3í¦_ÿÀìáßÕ„O¨?ÔêÏ]ý!¸ ÷±!þ_(H•Òa¸úM<9Ín°_•gç÷oióUMcÆ€3òå½[¾¦Úíê÷äNqùéý<‚h»·Ûà¾N±E#ÚýÍðÝUh§öŠ ßÇŽ®ûìþÍ^MýämÍN9ß$ÙÖ¾DköðO;üå´ Û3s%M‰{ïzÞ÷¦i?;²ãÃU‰Ò/í4¸\Vñ¹ÞÛ\K& Ááùj ;;€Š&èù|ß©léÂ5ŽªdæÛˆ˜øÄxãÊÝZÿ„z>À#Rd&,H¼ÂðvŸDœj³’@%Rz‹P¨?ÔŸ»úCpÚ„ v ÅuEqþ|rC¢\B2ùÝ4á3w‹ñýcV§)â-ãû'AqëÕÆ=Œ!µ|€jÒLu>*2.ÕÄ×ò͵ éæõþªŽOµ‰¡à¼Ä&CT 2ÊŽŽ£rSÿ¨?ÔêÏ]ý!¸íŒC¤r‰þŽD+Ó”R¦Sr>s§¢Ø9äÆdí"Ã"~ÿ™\Œ`k,ø©×ñãE¡’ 9ËþOÄÆ,“×ò͵àá‰*ª: qŒ/Sèù‹4¹BÜÈF= *ªopŒraðá¨?ÔêÏYý!¸m§ Úi¢Xû[ñ¼HñFµœEwüÀgî’@#æ«rÕÒºAG„(Yñü#R¡oÒ*ÊÀŒ¯ÀÃÀ »ž€Àoµ*^Ǩ̴€8a õþ¢–"µ|s ‚§2t|J†ÅSvt f†5¨?ÔêÏ]ý!8} Ó…&[H®Ö(%l:ã>SÀ!¡Ë—)%õ»Ž,ùÆþ‘°à¥+-ëÿµþc49*– hˆ&Iû_kCšš»£¡ êû:¾P” •¤¹€¡Øã¬åK„©”;€*5ׄúCý¡þÜÕ‚ëЇ‘Ä @yÞdRv‚Œu & ‡‘k“•èÕñåòxF=4Ú›ÌOltƸ6 §`Ƨ°ˆÇz‚U©óµbDfПÅÕñù ¹„ˆH5¹0>ô§PP…m…¡þP¨?wõ‡à:´“rA¬p!¹4SŸPcGQ%ƒ\]¿AÂS›L×u|!“\J‹X¬gz†TdqQÛ•=–k€¹0^HÀÊ„:B£0MÃ’)OÕß×ó%‰é€(©hù$‘Ê?@Å N6Cý¡þPîêÁmÆúr­FaÙ6š> …+¥fÙºìŸÀ¨ì¥JÃa†1ŸÊ$3;;]NXÊ×ö¾o¦FŒ²ãÑ"•¦~>n¦ý€ˆCiN}à#˜H”af ¦YEhŒBÔ* ÿ„Pf>õ‡úCý¹«?·¡ÿ#‘¤:C£´<Œ†cÂx…Ù\}öÏz¼éT•!ŸÊ¤(fΪt¹Ç‰%|ÝYÞ ¤¥R BâY„!4JëÕ¥OÓó²ŒæP#¾`áJµ)ÿ©è*ˆ”§D%Æþ.’›­:õ‡úCý¹«?§¡í{hœI®“*¹„U¬± ír3|@ ‘ó$yjŠ`#>•IQÔÜ5KäbR†SÈY_®sŒ.”d(Xòˆ[Óx?NÆSR󵃅Ì\…- MW˜ð¾œ6¡G¤T 0â 7„úCý¡þÜÕ‚ÛЕá&sR$Æ0ŒGi†48’±\Eµ'Å„OÅB#}Ö¦Éu)̆ºÉRèê‘°áaPºá©^-_HS”D§›­Æ G®Ú„€Å%Ñž#Æ•~()ÚàÚlP¨?ÔêÏ]ý!8 íÄSëC*רeb€¡ÄW’Ó$_—ýã#Ôÿ¤Ž“YPQ„ïºT¹¾œˆ…%IEá«u Àz>¡bÆX¸¤IÙðZ¾’"… ˆÂRhï˜\,•“Tü:u¥=r±®$hS>ŽÊ¤&½Bý¡þPÎêÁiè#O¡aäB"&ÿ%9Mð@cæÖÿ´ˆOm2|þúy-AFdX”ÿ†Úí9|@ÄÄd6ÝŽÓñRc> x˜ÆüA‚©¿Þ ›DkGäÚ~Žc|©Ò€p‘ÊÔ÷€úCý¡þœÕ‚ÛÐíZEÏ'Ó–«ôóF]J¨±£5˜3Á¸º¶ø'=Q2÷¯íÿa~>”ÎÒóÙ…u ÀõkŒùðýÖ— ÓñÆa@ 5sHÿ‘*¥ä7˜Áh¸®¸Î?_eÀ"¹Éïõ‡úCý¹ª?§¡ïW@¹.IQ8ú_”ä¤áë²Dd¥+Íå°x3(ÂEyÉ'qY¾YT;9wÏ3ÈåaÄŠpœž¯³hã[’3xGÁ ñº7“Ò„!©Ë€74ˆÔí¾YToÕTî1ÔêõÿÿÖÿ?^$;P‰xœí]w\G¶ÅD“`Á®4‚ØËg¡X£FQÑQ¤ˆD¤·ëw; ×àèE¥" bCE¬£ ±E%1‰ ‚‰ßÝqÀ•Ý;¾ï/vž¿¸÷™w–gg~ûÎ;3ÛG@ „훇œðƒ¿­ª^Y¡ºÄ¾ˆßv±¹d-™)mS•ìï±ë3­›#±Õá Ju¾~ƒõî¸}d|ÎuÁwC¬»Û˦I¨…VŒÂvn=øIë%îüÓ6b'‹ j/Ã-zôËÂ.Zøw¹«lÜ×Å%åÛ§Õ$;™^Ô/àÕ²óRl‚,E-×À»ÑÕK^Ÿ¦jÊÌÛ!ƒd׳’\m«"’Ì¢õ Ì-Yl%„°HâÃJpœÿœa9ãuRÊ@µ!ˆ€{Dú#ý‘þôÕÖÜÑ)ó«“•øAnU_ïÄæ«Þ‹f3ê’e³žE¶©ÖM! ¬Ýsgþ¡Å_°Ê*u\œ‘^r¤4_bû¹ÖåÙ}â<ªüOJÛÊ/ã%“Ú¹¾^õzvØÕºüžGæZ2«+±(û^8=©ø·ä_µ%¬OÙôžËLn”‡$Âh¯ŠŸž¨¸šC\]÷Iø£³~ñM²ø>9g‡P5dw> TŒDÀìøà¼Ûþ®òÒ‰•Ü6îí` cOð¹¹±iÄ'>õÙ3·Ûå5±$îþJ ý‘þôÔÖàÕ?šyì[ѵӳc:…ŒCA{ßðü˜©‘Æ2Œ²€‚û€)ós5ßýh—’2|M×+wÂg÷Ë:³oÇ`–™ÿeåò‘f ž|§WÂ:퓜±÷‚{°~MÏÇø Æë}u²ìsÞ¢àâW“9ý ù6—ާöìïóV+ç‚cήñs¸=U|·[^QiQMÁÿ“ïçsKù÷Úz¯î›yÝ´HLöÃ3¾‡°¿.z›ÿ@Çpo­uº³#k¿3Ô)Ò_¤?ÒŸ–ú#а ö£–p¬“ð¯v^ÙPFÐËÖ~=cPÀY_Ëš¶¥‘Ö9[›Nm`{Xþ¤âVor>«$aw]¡ëŠ6¸LëôÏH™—E5Üÿláv—7+اÊ<=&==¾1;`ø òöXà5þøñõžc~).cš§Ñ8Î)ý«¿×íãcqxè›C•3« òä´Ã·ˆš©:zOtS¾ACÏ/k”>¯iñ(ã‚S-lUh.ýQÐüß1 Ké½uÀ¤?þHÿv­ÿ·T^Ú5>ºH˜Æ ÿvÖ¸³3nîž[¾›ÀLm¼ÙÊÓýêwÅmò ¦ÿu§üu²ßJEí‚“JþÙz 2i¸ÁÉÍß?Ÿ»€UŸÛ³çÐgè»Ûç g¼¾š*þ(õî7ºi4-Ø÷]?Á}k¡~Éìwçùs¿Ú_{’0ðÔãpjc Q‘ó:”{4ä|ÿ[YŽ|wHä¹2²v¨0.Ö—{[ýcQ—Cv¹ õ%Y­`Áò^;l!lÐÉ@çý-?—~´ë3w[ÓJ¤?™¤?Ò¿]ë?‹Ò+B{Æf^®¯~ Œ«+/MüïqAÞ3ºñ$¿!ÇjlÉŠˆ<Ÿ„6yæ¿ÌfrÐ_š¿1Þ¿w!¾¢û?>Œ‚=3Pþëíƒ~/•%íZGl0 ¿¨Ëƒ%Õƒ‹ˆ‹oszž)Û›½{ É’ãõyÎËä?L¨"âwÌé’xâÇâ}Îi´®•n7=Ž“µëšó·ËéN”¬ˆ /ó¾ÚAN™‘øò]âæû4ç×Á'¾¸|dqkÌ4ã]ÝÖãñº6¹°uÕ1Ž™æÜ~óéô×÷„ôoB»×ÿC*§í§-/ÜÚÐ[7 æ#á3Ç—ÖN˜” ãg¬–Z<ªÙÐ ¶í”!ÙkøŸwzäyÉyþ|ï„T· ó cø¡;\ÃøÃ-žxv#ôÿþbA©ÉbÆ“0~XÁêM.fËþòì Mƒ>êêïžÄ™¼ðâ•®ƒŽžõø=ìncõ°Wq5W,îØÿH¯}"ó[+02Ü/%ö§–Ÿ¬£ÖW{þiæù²eί‹½Å´[0zȇg/q4~³OÛ€ôGú#ýa&í^ÿÛ0cZàLyyÚØa=¿×šwtË]йÞ6¤k©ãc’)¹U6“KRNÛXš\n[ÐyÆ„\¯§ ‹-ÃϽ½VS·3r=‘ËìÑñã>w›ø±þøuCO¬ÃŠUZç«l\ÝéôGúÓVÿ³T>Ú5†Ý-)²f=<[¢™ÆZåTqÂâ ¾þÞáèn¾)P.®ÜKrwoæÐ­¿W쇾e“Œ¬Ù%ÿÙý[?Æ“üKÅî;Œ€Ñ÷rùÇ:}|¹h»^ѹZÿ†Ú+ùÉ©düñ÷·yóç »–ŸEX.ñó®î9 L®M\6-Æ®:Gg”É;*éÃK§¼©u¢É¿Ö¬~Òç’SÙIJëá®ûbïj^±}Ìí:Yð0U½kÇÇoì²`­]°rs¡Î¹!H¤?ÒŸ¾ú#МŸä*,^®HrlIc±ï­¯™j‡ì÷q4»NÁçÞ•¿)¶øtuòò¶í&åÞ‹}¸æÆûðSÇvï¤îzàÕÆþî?rÑæôE2í°sÀ¦»Ó˜MÐ]ºMü_eæ[†m'#(Ñ&#‡§ýÙ¾OˆÿDz³ïè-xæ,­¥Ë“MÙÃýïS·Ÿß ­¼?îÆ€gæòý”Ƙw¿;ÛeZ+|¯$G &¾Ý‘;Iu$)ÿç[ÒɰMÀ¸ÇówgÚ—þH¤?}õG ;|Ó†¬q9EËþUO@Í4”蘉û¦õ=Qó%Åyœ øE¬pÙíÙçð¶m»Iý'L]=¨|DÌĬ¤± ’%K–»]8éð—vÇàô/®:ë?‹êcíg ü¹biÁÖ™ž÷N^`•C6¶'ΟÜYòçÕ¥O5øÇ·¿dÐ’>g¸¼Wæì)ùy&J žV!×9#%,ۮǞûýaÿPùjoº(¯K8ÑP¦„à·ò…º ¾‘þH¤?}õG ;쇎]ñùš¿ž¾:£üxÀÒeÈb^6(«îå¹ÔJ,15ï¨sÃËoÚâ_hâ°dúÃVägÚÂÇñå#†™§üaù¦á„fµËÊõ)ëgÚÖZ±Âjpwg+»ŽÏêõx5fêž¡SÈ×%}=¦ï‹ž«>|Òz¤)ög`¿¸å…†}fÄyâ§—×9>:¨„Ê[ýÐ,#FwœröÁ¾Ðîéƒj•ɽüÕÑkraücó ®èÍ"ý‘þHúê@s`½*p¬«ühzŽ ½^\v±n;wŸ…ßÙRòûTðB;Ê+ާn3ÞùæîGom÷¸çs~`ý©¤­Æó•þU9>8[ýM\ëù×ó C&v§ë èƒ`H•÷ì<“Ú ™î‘¦¶õïþ¾t˜‚?ì;w+7ïUÑ-ÉÆkÝ·›¼ßcXûeyi{Zï+€*è;†s'îg=þ˜Ëóž`zƒˆ¯*Ë ˜Ù󤪫§ Ñ»ŠôGú#ýé«?ÝÁú–ÿƒsÖ6ËH›ÍÜFP݈'NXú uJª™_Á»<+ëÐØ¨é†°ùjSÎ |ïò·Üù~JÔ£ù*°/±OuÊ|1C4±¹»3Ÿfq÷u—©ÎøTs•uðnf¿…â1ÚÃ…3{¬Ï¢ßãïBh-àÞdìÏœç$m>ua…]‡óný m?slÊŸ!ØÙ0òæ \Ÿ.ן¨äÕ†ˆ¿ÌÜ;H¸Šy4ÇÆç_¿õlÁ¨„ôGú#ýé§V\ ÐðÙÁð-)Ra$Þ4gpŒÏÁÅ-¿®Æ€îŒç%ˆ"I+VñÄ0ÿ°}½Šâ„¦J>7¯´Ç˜k¶&µÖ` ðƒ°d! Vh ‘±n‰Š¡îðX±Ðÿž€%V}:DÉ­z’~ÿéôGúÓWZà.ÃÇ bEQ­Š'H(Šjó@Ì7x ^AQ­þÆöÙ´[®Ýµ”|V´¡íWôMϸd‘æb`á~™bB%Ÿ)Òâžo’„`é‘.‘ d‘üf`L!±O%[À–ª…ª|f´Ø€ûGú#ý‘þôÕÖP½*x㙉R¡V§@Àãˆ/êm|€ˆøŠ§’íë”!Э|¶Äÿcyûí–Gé…òU¶œMQéb\÷þ)øŠÈc]V Ä@Áç²¥|€… âu[IÀã&)¿þ¡Ço1„éÝlk!E¶øgÉ(ïé#ý‘þ´ÕÞP¼hrÂÜñ¨ü˜è(wupùa[Ÿ >|¦3;YB>ýgœEÿ÷ *ŠÕëÆ´pü8Û$ú÷Ï“’ñ×O íÒJ>‡/¶ü[gó‘ãž*Póy2a”îX‰q0),ŽPü3Ä–I\b¾Ž;¤?ÒéOWýh ÅCÂcmöÇsâÅBý7Melñ¿¥µøpC]ñüx‘aCŠaþÆ\ÏÎ!膆·_ñÒíŸ#Óm%‚Ù©ð.­ä³"[ø@$Ž¡ùš5?B/ á²hhÀçH›}@ø:MDú#ý‘þ4Õ€-@À Y‹ÇeÄD.6Q¦ÁD¢Èÿ% ¨Á;p½(?F¨óyl‘HÑ·IfáL<—¨ÿ«ùÑbR¾ÊŽìQDÐ7•|–Êcãv ÉÍ´ð#T?˜á„Ë…t9ê@ÍgŠÕüV .>ŽÞšláCG0¤¿ÊéôoÏú£z#~.à1=Ãñqg(º—+‰nû$ à|–·ÿ–t©SRÊ4GJæn’lX‡ æ7Õºª˜0«FÎÇ8^iðÕ¸Íüæ4àú&S¯Òtø-S:4f›ùð4 Ò¿¹¤?Ò¿ëß¶/7"´° Ó@ŠÞ©Úû“š&%|ýo²ÁLÜæ4’Š/(ùÊÝ?«An¢Øôb wNÈ”Áê¤ä«Œ°°•… Ä!ðü…‰ä¯ôJ>kº, ‹3`F æ ¤Zþ?œd Æ „ßZ†ôo2Bú#ýÛ³þäG@hï‰$Ú Æe¸ŸõøaÎ)Rø˜BÁW™`L÷m‰¤ _7„nîÆÑäGJ|Àñ5`v Éo¹†±qx qq­&)s¼Äú!ý›MþHÿö¬ÛN[Bh/à¥ÑTëC½ñmÉkD IÑAÍl¿qÙ1F§£Ti4±2EÉuÞ²•tI1)¿É€å)OÏ©ÁøŠWõµ¹zë†ùL‰‚Ï”A sŒ‰k™)Çi–DÿbÜ‘CÀ±$ÚÑD?¤«Òéߎõ§Î: ´g ãòt÷Â(sCaî8^#¢˜ÝkJã‘î…!w¯â‹qö†ð̉ñS‰$iH€óBWoK'ßRD•Æ€í¹¾,YÉçp Ò€€³)>§é@ÅÇY Véj>GÖêpøðˆGgPu éôGúÓVšCù®ÏÅ´Þó›÷þd'H¨äðöÏfq<ññ‡Âù„G‚*úˆKfÙ*\R¾º”ãÇÊ’­ä%æ~ – ÝŒ£ËÇ$\ÿ-†¬Ò Ôÿ¿Ö#=.Ï$êÎâH¤?ÒŸÎú#ÐzGjª÷þȶËtþ0Œo´>ÓÇ?¢ÐØô…xÁnÙ©bC&áàíÜ@ÿ\ò—feNïHP€…ùgˆ š]Sñ¹¾¬"Ô|asð˜rx€1¥úç¡ ý‘þHÚê@w(ÓHq´:¤Úûã†çÆýaßh︢ÿû‰râ¢Û:7¥ôÏ–èøWôÿ ÷œdêþá«‹øAEä;yù°Ön7 ¥×Âe“L3¶Zêj~Kc EÐq‡xéôGúÓWšCóHLÕ¾à xrº º÷‡Œo¼sÀc¸Rã£cþŸGŠ*ªåzä&t¤üHO q&ÞLÁÜÍ2âCÄ|¾¿0Þ€û' Ôþ¹²&ý¡$‘ñ Òéô§¯þthù2'®Þû³3Ö˜ã¡ZùF?]@µû'?&ŠûÿC}¬ËÍäi£nˆŒ®FÚ·ïÃ{»5Ïdn“xþ|¾çUŸÙé’@óño„Ÿ¥ºÿ–GoÆ»ÕnqQd­]ûÎâÚäë7b%ƒïeµûê“㜋Ú}¿ãñ=[^+ªÂ²õ‡úCý©«?Õ1Þ±u‹C•/? : R#¼^öË,"Å÷vr~žáºõâÕ]dXÌå´ùþ]Ъð¬7­î†Î:xùòRf1¥õÛsÃÑ3×.•é?E)ž}9ÝëóÇj Qþ´v¯<;x÷ÎùmM×d>Þ‰gö„1³:>)Úî`÷à‡RÝt´o։˵D‡M/üuZI OŸßOo´ÒN8^\”–‚9­ø¸\ ê´vòk÷*Ù´ar¼>­àl‰Á¼õ‡úCý©«?Å!ü»lú£CI)GZƒîA»2ç=&é‰ íËæÌÈ,ØÎË NZ¸mèkƒÄ'£_¶,›6éjÒÆrv:9à öË'Œ8µµ|'3M·žYÙgJzàšâ´.ÙgOõþ=qÖÿWºâÁÓ£Õ„&¤ÃŽA¯ÊŸŸ¬ˆJàåã—Þ;tš¨m´Ë7]Öü9¹×á¤Ù5‡B’ñ:ÿhŸ|»×íÅËwß—uÞ`ÇçïËŸ=v æ-¨?ÔêO]ý!¨z½oE© }¯ŽSÞÆd“æ3·EÝë<Ù.¾/®ÿiŽöÏß›|4¹Óá±Å:~ùªÜï>XéDï%#m[„Ýai[;‰;Ð]dË\ŸÇo9“6k!™`koˆBÙ±Ô…Þµ>jˆ=8U4jÊl%1>û`Ï¿};³£tI¯œY›Ü›´¡’#Ž:¾"ò“6í<™mp'Á°E7SRq&5î)¿e¶:Ðfλ|\C?»®©ÄùQ þP¨?uõ‡ 6"ò[upر8÷Žä÷¶žˆÂß\/Ǩ¶þsú]"ÆæNð<òõó›xÙjýç€ù£ŸãÓç‚m¯èŠ/OÇë'pÉÐê£ÛÒVôø¡Ž·gïñÝ&^H#Êö´Kðtk¸Ë·a#Î;{žÇ8.GU a+ûg}ì]EïV…×Ðî^Fç”[xw#Â{0/^¸ÚîÖ`\Knüšµ«pØP¨?ÔŸ²úCP‡óöéÞhÅnÃÃöÙÔ:üñ¹Ã¡ì ßWn&Ò<´e•Ç?ó{d„ôªp¨gí÷å£7Íýስ4˜û£ŸTØ_[™^ëtêøå¤Ìþd;óû7ªc½.W¬×zµó/õÚª Äùã^ìGCR®—$Kgª¶®#Ì+=[éÜs-Ÿ½*[è¹³ìnyv;AŸ}ÔiøQÍ©{J'r:†·à‡®ó,źõP¨?eõ‡ 6–„=Y˜.[~óúO¯œ5!)6õ”×Ó¹Ë$Va ¾Ç>nmÿdýsxÔW„ÇzsÆšû3Úêÿdnùü³­½ÿ ,7ŸÿþßËåÖ¶5±Ê¼Ú0ÿ§Ž~O°[u˜063Ôò2Ô¿P¨?õ‡ 6&~¬ºî{€àµÃF2üÖÿ¡wç÷NÛæ'~á1<½ôõn­NZçÓ ¥­=WºÚÓÆ×"å ×Ó 7 f‹Ç8 EŽçulýó}›øKÇ÷÷uÊ Ô¢ø"ˆóvü”$ßwb¯I3ÆÔ´ÙþPC˜ÓÉëÐÈ¥u¦víOœ;ö/¬ ìÓ)>©w¬öõçòy_OÜ¿oê«=XwÙÉ#Ÿµ ÏBýõ‡úSNJ#öÀÌsþî &žå´uÿ©xM¯æH)ñ –1о SƒSnTnZk­ÙÜÍ]×u\_ä4ÂÁt¢@Ý.䉯~óë·%8i°æìçîo[³º¼ºÆ6þ Ëß3ís¦ÜÑåa*Ùiz%K3£WçÏ|M¸†– Vñç.@yë×Í|‰ç«r³¦ÐJÓç|ÖáÅ 75™=;D½cãÌ?È—EJnüSöÒ­ßëÊí3žÚVR4F6u”ûï'nw)S ‰‡ñ}:haª&ÿQå´_‰ÙŸ_íè¾xQjãçøÔqÝOÇê©wÌ\uîóíÕÂ,ë¢ø¨j\ö{9º„O¼2åš…«ŸÀ~oÂG›L.AýÍõ‡úSGJƒgW–xpÔeÐq×A‡§´¼º‹Ó» 9CýË'‡lët†Ë€zï~v»Ö»¯CàÛKšc<Áɹ9 0wúÌêáÖíñm‡{¿‘>‹$!Zva˜%Ý»>z°—,¿óúºœ=·eÛ½g.y²ð¯NWgs¦¿¾³“aëõC¼gteÑÀ6{Þ µ»QfÚòVZÐÞ³Úƒ}ù!φ9¤xÈß»bQðË)ö’´ÌxZ€úcêõ§ˆþÔÆÜ…µ6N¯Ûr7wëñsÛ´=Ì`Îaìþ*•pËHû#±Tû¿NÆ,&6äóÒˆ Í À·qøï‰X>lýÑŠDË4˜Uð—¹#­¹´Pü8«÷áï*²È~õ:ûÝEšût§mùXi´fðcò1Oeáö>»fÜý!RÒôå‡uŸøûõh¿cSZ†m|~ŠcRIœsOÕ’›m}P³•îÈIüèøèûÛ8Ÿ¡¥šÝ¾{ê9b\ êiêõ§„þ”ãÓýïŽééÏfœœgô²²°«&´özMc™‚u˜UéÞ"«2Ü’/üaýŸ.ÞÞßí]P†A5€]ÉÜߪŮè0‹4˜5p†ýXiO[{2ÿ8cç¯ö燋‘â7¢ãèkW½Y“Ä.iÚ€i·º'Þšõc|^ö?§Kú5ŸBŒ]_ò™é–]ÞO1šð¿—)s5æ× y™Ú_­v†LL®X°ð¯D F¾M •w6]aÑoKú6•Xúãêõ§€þ”êÙ=î)ã¶nx>¢ü·S&÷¦zÈçÇG¸g[-håäãýøwÍãMq³•?`,‰Uî°R*$$h¢Ûâh kÄ-ñª;ÕÝ5;Vx€Ð°q®]ŠÖ†_·%Þå=dÿIß/ì¹S:ì*I>ÃM½ù¨_j|œG‹÷“ÉC›/¨ºô÷ î¥æµF#†ÔºÒîä >×Ägׄz±r¬/F:åzOÔÍ«ÑüÕ'ŽØ— ¨6±ÿf¶ wsè? þPÿ¯þI<Ä¿(Š8R¹DŒرa ;C%/|#Ÿ IÏBNtˆª(Q‚ÚÄ7¶Ï–5ñQ”X¬•‰vgί¿Š$øå¦ÉôaÆGfh¡Š¨q]{n„FÅ•7ûü(?ûëèí³ |!Sÿ…QW%ÆãCý¡þPjêAu ¨ÏUHéÀBLüí5âËIÒPTÀ ¦e¯VI€M|SûeE¸QÁR s~ý5„œ”¡ 4'éø£Á7ŒpE ì›P¨?ÔŸºúCP(@„\¾„ òµJrîŸ'ÐÉŒ`á3–¢TÝtcÏ>Šp"C7&ËIÊ‹–¦IIL>ì˜Õr_ 2¶ÑoPo_ÇlþG–Jb…õ‡úCý/QIªCçBriÌ( [¯¶É×½ŽXNfêÐÓø`“Fn´äù–öE =_ç¹GDlJ–‘êɈ_åE²ó Çñô|¶¸Î¾ÆÈ&ái£ü˜$µ¨‰Û`°Ï爔N þ·„úCý¡þÔÕ‚Ú@ÇXÉyi*ëjËK‚êüyŽ\.!ÊF€½jUj¾ZZ¶#ÉÇ·°Ã"7'‘ÿu|¶¢É>Ê‹‰*ÂoÖø+`½šDôartë_®àQ^lº•üžŽÏÓ3Tø{µ¬D¡þP¨?uõ‡ 4ôî+7>È2ÒÔR}D BO)#¸|@Q~‚/??CÙô"ÉÇ·°CbJ“ˆGàš¾‘ÇU5ØGùñþ¥‰df |À Ó&“ ¢Üðl…¸>§Æ~« €zûta–÷÷ÃBýÔêOYý!¨ óÈeù"`­ˆ•ÖÓPÖzѧ¡1>Šðè¾ 8EÞôF“âãÙ*Eìúf ùño–ÆЗ”’Æu|¢” ã ";‡hÂxI²XÔÄÇ{~ë €ú &/I†DDù<Ü=àP¨?ÔŸ¢úCP†ìUlÈÊTJ®äÎâ!Á³<úÓ?1Á’É>]_¢x7ûB^€¬Dc“£kd2¿,I%9‹øb1ƒ™Op焲c³ä"3ûX ›YøÌø4%îï‡pÅrŒ;PKûPõÿ¿Ô‚ÚÐïþÑŸý)N’KÀ+ g¯?ý—™­–š6läÛøšêøºy%qmãß$—à—«%=Zt|+&fk" ?åG¥4$ õ|¶çù›[úŠ”IñøúDñÃ@ýMìCý¡þ”Ò‚ÒÐ{¬¨(›¦/ý„ǧ³8DøºaÆ\ ÖjæÁ.Ÿ§zû|Æ2Y‘†Äù_3¾n2ä+eb”””)'Ý‹Ž/à®NÅOÃYROÛ°Ò0Øç©0Ó€(Â7³%I·˜à+\¼4"fêo‡úCý)¥?¥¡c¹ô@´!ÑPúðµápcÍóuS7~(I–Y¾ïfÆ4OK²Š™¥}17Bœ­´é,?.x½š„}”–£hÜ·kH㡘ߟÈ@HK’àñu“;Gb¾¦úcÚ‡úCý)¡?µ¡y%„ÑAAJسµ¤§QÍðõ§"#×&bºÉïb_ïÿ/IÍQð-Jz’èCo_$ˆù69Ë:7ý‹|’¸}T'3.¦_Y–$„á UbÝ‚N†™FD…,ó ÔÓ>ÔêO ý!( ƒ»I šüĦ ‘> ÅUÈÞ% g•¯?ý³‚“¥ÂÙëj»}]ÏŒ¥«s€ÏQ¾Û÷§ûiŠÈ¤ñŒÈìàt JÜ>вâ3MÜrCPeÉ'´`ªä7h„úãØ‡úCý) ?µ¡?û“à‡€uÉ £ÒÿÕ’œ· § Å?mâ[1ŒòiËsV«Äïüýy±+6'‘Hã‘yQ2­DÈãMcꩦ%C ÏoÉ'²@ylèù<5†}ó ÔÇ>ÔêOý!( CåÈØ0‘¥6=xjHƒ«%)›ë—¯?ýÔPüŸoR’“ Y”GóÍËRê72ÙÂoêH@[ªÍ³)ˆ ã9r‘Î> –ÆD_k–X|" „%“‹ëu‰,í›E¡þxAý¡þÿ~ý!( ÃvSýÙŸõIµ' i0™ìÔŸþ Ñæ©­º×Øÿ™³Y£¼8ÿ5™ú……Mü¦Ž„Œ/sSAóÿ™ƒŠ$«tC°}„n´¨¡CIP¹IAVB ÝP‹Ì"€PÜŽ þPÿ­þÿÚï¿-pYxœí]w\SI×QÖ¶öÅ`AQ×*ØØU±® Š é$¤çÎM ½ˆDPDÝUwWEW,XÀ¢¯Š¸VtíeÕU—Uß$´”Û¿¾dž?4¹wž9Ã}îÌoΜ33EiE“+û­ªA•tk‘cŸ uwüç_¿ê ¼xu¯aµO4ûp¿l|òåÿîּзG _A°ƒ˜ˆïØâÍ•õ›®UýLÙdDåxÌAÖ:Å—)/Nøåì¹Q¹Kÿ¶/ýiò7Ól-;ÙÖ”Ý9_¤8^råéõ]èŒ6wÖÜëwçaY! c*Ãü†ÍŒíËß·¯f­ 1{~¢ éÒÅÕÛòÒ×V68ÑO¨ø0·S¥ûìƒýÿ.Ù¢~»"c>ݳá3ÔP¨¿ñëaÒt«y§­~bþqÚñbûüEÓMZ˜XÈL7¬þº"'×á´Œ"FšÚUðùï¬çQÏë…å5$üOEã&öeïŒH#.Ø„ M{N™˜ñÝ|Uƒ-¶´k¿¹àçT}›lß>`É©Íwì,Ú—îÞ”¬÷݈£A=ZuCQ¤mQ¯KÞç—DHà1s¶i¥s鸣cvçžн®0Ϻ„EfŽšè*« ßêTüovšûÞÝ,qo¾>çxéÔúP\@ýQ¨¿±ëaÚð`u®“ºU¢åîê‡Q"*?0ç1§õ³à^ƒ,Dm X{‰ÝÿuˆMlÓ5VÒ÷?çúÍÝöȧ_Uz‘òöäB¬cÉŠªàÒgÇcaR±mC‡eìZ)ÙÀ\aÒ-F¿†GY-ûý¯„Å+xL†¬}hG=ø?Ž—?n—v[¤øÈÜç>'j¿uX[B~5ç:¯åBŒnÍúÝsEŸ°§ƒÂZ5Ü,óس7í ±ýµ}}F®W“]êîö2èÛ1aŸ›+jëÙ0BýqõWêoÌúC˜4X/s‘£—Ñ?mŠy_mÀYäZ:mâëÍÿ™>¡ç¡AFfÓÒ.åŒ@Ú•Ñ¥£~źåïÑ—= =ä×é„êkôṡÙħ櫱ï8 _|z¸?;WÖþhÓýƒ>´úvBýqõoÔßhõ‡0m8O½9©¸w'4­¼µ×ŒxT`÷ üHŲ.§“…±pøÃþ<¹·@Ú÷ì¡­õÍ>s‰)°êÿv’µˆ ßþáÑ<æz (:»•]ç·nâéweÍüQ¦ºíÃé8£¡ã«\×ècI÷ ³•ߎN/9šö”¸m~lÿÖ¬©µSßdÚëðÓ£-.„|wSõ?ÔPÿæ¶AýS“FØiZoû¿ Pþ€“÷ø/'Ê­Íüæ»»ÿoâ0x2;Ör샳<•|~Yṩ­3fžþ´ö Eþã5­Os~ otO$+êXu&±'£´ÅQ©ÚEþÓ5fÜÕüM‹´3œpbÜ»ož—Sò_e¼ãó“$[æQðW”°ºfw-ð¢G“ý¿3ž¸}ù?ÈñÃ-yÕŒÓɪ‡ .ý¦¨6oÛtŨFßÝâbP±r€_Íàf¾yzE­´Ë/;œ–xoPþ õ'Ô¿ P£Ô¤ ¶t·ˆ…¢O.»þÛã.áT»ôfÉ+ºßáÜÙôgÄ ˜w8aþ„[Íߣ·O(o“g¾äI³}¨?! þj€úŸþ¦ ßuãÎô.ÛŒN8±×îÈÂL’Ònv#ÅÏ¿êhiQf˜µùÆGŸÙ»­ù©i¹þEÍ÷È¥IÉyX8Â6 cù°ŽŸOëm–W> B¬=N-9h±OÆ”®ŸŽQ48¢çð×Úa _—ŒéçÔ¿òG›º \Þnÿc“åêÛn<ÆÛ ¼Ñ-tÀûCØ”ýƒËÆ]Ÿ…?ºx9uµLñ‰·{»?jK­¹.É84{ƒ¬ÏKõgàãÒþþ¬mE£_ýÒxêO¨¿ þƦ?„IƒkyöØÎÇQє˵Ï.&· 6kS y‡óV zV¦Åf¥\)±éZr±%š!wok¦OFèS™ÈŒÛu³4'› ”¹óé=ûîîGÓé ÿE©ÿ¢gOeeQ²ç&muµ…k,hl#T|3þõ™µëÉÉ̢ۜ½Ó°o{9zbe‚yEê:,†÷ÈWç|tN0üêê¾1÷¬/'”ö¿q9ã9q"Y¤ÍÕà;TûXLõÝuI†ê;ÔŸPM@ýKÓ†Ûª· ?MDãWÕfަ²¿•}>æ¡ôùéI²¸a,b~¥ønØ‹ªä÷'Ït‚ÄíYõ»~|Î%QÍ‚u® SdxEÀîãÌÏPᆱÎŹ*¬õ¢ç‚ÄI¸|5øYV:´sô¿ß¼ˆÇ­åm_8{¥|‡µSJöò+QS2vhŽo¼[à÷›/ƒi©~øp½«á&'ÞÁO;_e1c¦^°÷Í%Yˆ½´oàÇ#k5.ñŸð7q^Ÿ•dVšúê¯ ¨¿1éaÂ@DôÛéQ¥™èÇý Ï /¥²¨¥@`Ä\·¤‰É.o #Ñè?Ì ºõþ½ìÒŒ´ñiådkŽ:bΚ²üta–ó ûàì¶w¥û™,Î8L×b5wúX—ê[¦>%o¤°Ömöì>ê)CÁˆ³Õ»sÛ§>$áß5—[8¦®*rê}Ôéî¯Sju›g½öÊö vÄãpxܸ+eÿÖÊo¥¿$nÀiOºµö>áˆd‡W¬Î9VCýÉõ×ÔßHô'9w ÂÈQý8jÄñYåm\ЪâEkB¬)Oè]:Û;|ïÅ«pÂXd˜ÞåZþõ¯O£û¶…~oÀ4tf·žfÖížß|°ó6²ÃÙÞëx—7úã,-ºZ[=¿ãlvïÞod–8¯†ÓÌ­ŸßÕ\í›Ý£óµÕÃ;ÄG¢ Z.,¦»´Ô}Hn½Ú•øùâ#M-̲¶žýDÒªý-r­«¦¿Ÿæ½…İow›¶O'X»xpZ¹0üÔŸÌÔ P£ÐŸKb¸Ñ&³nÑà ÃâЮáS겨Ÿ¯ Z¬–‡í‘a†±HÁñœsdr-:»Ûüû$›X±´?è5?4»xŸË{àËn'Û—vØüG\~ÇC‹¦.+>^,$ ƒ ;öéåV¢uv9ÒõÐì®×Ïæ‰ZuÁúßų0ìwÿÝÙºã·5ǘÚGš¦Þ°ÌÝåD–_ zûißáãéu$%ÿÍìºKÇOý ©”ÙBý¡þP"µþ¹$\ãÆš¯·¾ii‰ ùCöLvþ¤×ٞѿÑ \Ñ3\ôÝ&М2/®È(ïÚavä"Cø(Ê<ñó«€ÌžÜ!ºÍæúÅvûþ¥¸Gñ¿ø|Ö‘°­WíÈHøgƒm›ÏìäýuI‡"${§ÿÍü~þËôÏlfÞùkŽÎ._,òk;±Ñä/ø0fD§.ä?µÂ¹@vÍѺY{+»/»5h°îuîå€È¨?ÔêOdƨõ÷"µa̸=yüžó,ÑVï[K¯³ô9K‰åîÎC$q>Cïé$¨ÓFæ›w'ÿXX•ùzõÐÛ†)ºÒk’ËA!Íî¦6Ÿ5Éañ\›•há Ù~ËÇw2™f[CdÿÑË’ ·C«¿Ò½³Êot«ö2‡\ÅåGž6Ë|'ìTáÀ@û§%`ð%u¾àTÀÜóS¢†7 (´»ÇÑ^Ëgm§ÙÎ|ÃÇ (GY@ý¡þP“Õ__Å!Œ [÷Wö:ó E{šYܱzHùLŒF€±ï_ÔþÇÖÿB¥+‡* /?ÜôõD‡öx~{äÅ ~™S‰ ÿ<(« ÿ{n§æuz§?½ù}¾ú1ÒÇÛû6Ȩ.'øeÏ^Ï,6~p¸5«Mþ|}³ÏÛí·N≊¸¸9.*9yç¶‹ù%iω¥µÇÕ4ý4ê—ì%½)ýÒØ˜e+Z³î<9¼… »zpÒLì8'Ôêõ7]ýõÜya¤¨€Ï F×eÄÅŠPí7£¸!4lšŽË±lLë˜üRûpÃ|6¥KEÂz>—'1¨ýa,[ŸÃ3€gUZ’XHÝ>à‡KE:¥”|¶Lƒ¯øóÒcIªCØ@&lüûµøªÛbIÓ¦f¨?^EP¨¿ÑëaÒ("àD-GÑ‚‰ã-UÞçòãb °ùŠA‡áƒæ'Kt_ù/µ¯è{¡+rÓ¥õ„F>É8ƒYÂZ™)Ž@o>à…‚teS=_ |€0#×`tJŸ/Sã+†%‘œä±ATBlÓ߯ÉWÝŽŽQ«êYÔêoìúC˜6@¸Ì€(4;UÑÇ0ßQE_°ER1ö] 0øå³Bbó/)i¥Š7˜ÏIpZ‡Qᄬܒ&i¬Y_~sE€(\'TðY"©~|E ÍŠ«Ÿ‚£MÎÜ 49ÖÓÐáSq‡“Ð0F`ÙÔßxõ‡0i¨:GäJ4.WŽ¿H¥#xl‰Â=0tÐáÀc®ˆ^›)Çr9¾Ð>@ØÁþy©’æš l¿Â‘XÍÜ( •|–T/¾ÂwðÎmê|":Ðù©bÌZ|€ÐŤÂJ›Ÿ6ÂcJ¥êövý~o¨?‘Y¨êo”úC˜6”ñ¡hoš›D4AŠ·“Ë5< ¨ÃW8tO47UJmYM/ûŠ®·: ?E­ÿØ~¸¡«óâ=MÅçÈôà+¸´ø”˜æHÊ€MÛ Á;ÔLƒOÉàÑ“Åj# €Ã‘«Ù‚˜¦Š¡þ8AýKCýT“†jm(,MY/'~¹Ua$$Nl@ ƒP;ÜÝšKþ3À¾¢ÿÓh)š+‹J?‡‹à-qâÕÄX¶#AܰˆÇWØÇÈÂãòÂ9™ÒæHÎü0)FŸ’X¨¬y4ѱ_ÿ£&Pš þj|¨¿ñéaÒPÎk9Œe(º%QC²ºÂgÇH ªñà³CsäÂzÛV@ð¶$íª•yÎl±^aLÀô(Ln˜ÄëÉƪ\™†BÂH4} þ´^8áä€ 2Q½Œ’ÏŠÑÃBý‰j‚ú«ñ¡þF§?„iCX F33ä\Ua4i,¥1_¹ûÇÉʈ‹Ñk:NÍ>0ýà “btŠ)SØda8Íšè?¤6u"½øŠù·ï†xp‚Ò13€Ôø¬8‰êù‘;(ÂáÅ‹´í×óÕ®@ý‰j‚úkò¡þF¥?„I£iïO~‚”Jr‹²<÷e{êùn¤7š—,Ño9Qµ—‡'#±Ñ~Ûcu«¦Æ×¨ÉkCš´9kI>àǦiNÒU|®¯˜±ƒì  F>às¹Ê0 JÉ`È$Zöù. ÔŸÐÔ_Ë>Ôߘô‡0m¨öþF¢Y©T[ª0ªç^]¾ᄬnK þÓàÂ0@ùÑ+˜… ýŸ_½4Â\™)ÕXÄ£ÌüHú:©VOS¥[£8|…Ë„›¤Å0ÈÀe&Š1ìYƒ}¨?‰5¨?†}¨¿±èaÂÂÆ½?â¼xê‹Bÿ'a@‘ˆíÏH_/×]£ûrûŠþÏðlMÀYZÔ§ýa¢ëeTòY±TÂÃ'_·ñ/L–@š×SÏçQp¦8N{8Qò™•}¨?™-¨?¦}¨¿è'¦ D¨ÜÔíÃGs’õÊ‹UÉ)5ìHÍ>‡Î DsÒÈÿ4È>@yŒ¥’¼xÜТ’Ϧt¤'œ fŽL««PäÀ^•–Œ±œ‡ÏW Ñd½ZÅgÅ¡ 9¹ÀLŽÑµÒx$(ÔŸÔÔÛ>Ôÿÿ½þpÿŸiƒ#RÌ„ÃÐÄ,‚£?°ðÅG‚>3„†æ%K ›„ÛWôºG¦ü@åö+7Óòãµk¢ÈWAÖ1ÛøaDÀ Ì”‘>UŸÍˆ%HnÂF´G¯>‡'‡úCý¡þÄ 5býÓH¸Æ(T‚ò¢—¡èæD½ãyª•C¡¡a@åîZ0º)Õ°ù?‰}ý?e£N¯¥Ê×(Æ ÷.ÒŽ¡QåAdhvÎ…Í‚”0HÏ È–“*.ˆŠÇø¨?ÔêOlƈõ—’Z0fðyÑB~xš±†äèL¨Âh±‘!#@xÑ^üä5"¹Ô ~£}–˾¢ÿG-MÏ’w£ú0™}EUÍ€±øDYÓazoÆ ç©v^I´ùª )•'¢àsÖ“fmÛRÚ‡úCý¡þ¦ª?až!„ÑCyòGH8Šæ%”Ìcø‘ ÊßþŠZ†æ&Ç _p¤¨*Œ…Å€éµfƒŒlMáHNåüyIAŠóéòàÐR°f¾vðBâÉ2€šÚF÷ÜO²r«<'£êõ‡ú›®þÿ2Ÿð.€xœíw\çÇUÄ=ZŽÖQÔª8+î¢âBê(ÈP)S@!}Ï2–,VÃp+"RkUDTÐJÕ­¢-m_Z·V)úK˜wÉ%úû£Þóù îîý|ŸÜçž{=û: Pd–Yw‡ÁžƒÐ7¥Nå'3H€ó4æJdi´œ’lœ>—t¯ôò}ÇZ¾^R°)ÉˆèŠø¯äモ’Š‚U‡Þ•g<­ýzá²*=<÷_¹y—Ô¬]þ2¼K¬}®æ_Ýw¸ “ï z+ôpþž ØôËÚ.Ç:²yxñMå}÷QoÜï.m;F94Ãdwƒžœ7Kø+378ð-.²R(Œ¬Wôúý'¯ÿPäÖ}ÇÝ=P¯cL“Šf¼jÜ#âl5³æ@à̉®æÁ`Ûn%GÇe½9ŒÄ¯]`Y.JZ<µµqñ]¬§^{bÍŒ~ÛxOÁÕ½Ck|2^~K€_¿dbÁÈg¾ó>ªÄŒìòm—)ñæ ¸ w›q‰uÓ˜Ö}*0NÒyãÆî-*Ý«#¾çÊÏèÙ´dÛ^gZ,*Ï ;br€@Ö  jë}щ®ößïqè~ï¢'V7mø³…}>Í<¦‹¿Ÿð—û¯,N¶­V!8Àö¦ÏËšhñ9nM½³]œ·¤©£°îÊUÛûâŽHª‰zÒåÏÍOŸK/7Þ»œ¶m>v/%…Þ¸çFÿ ô¿…‡þCÿIè?¹u^2 µ¿8¢óß¹9Ñkþ}œ½×ÞÔ¸Ç$˜ï$o,,¶7!ÂÏÊ-xM §šn¹Ý\åEC„Ž> =‹Ëì;“ÄÞ6ôÄ1ûF%?ï©Ça+)°‹ÁªÐc*TºÚÁÙ¢úÌšWšñIMÂ¥•ÿþC'OIZi3cAÝ%û%Ýk{ÒÃêñSôÄO³™Û׺ç ûÇ > ñÁY{é?„2î»4ý̪jöb‹rëßìîc¾i.;4¸£vëúß*è?ôŸ|þC‘[“¯ èÕ uæV&"ô«QÓ§zþ¼ñ¬qi­0ŸìßsnÇþÕ?ç†ûç¿%P^c˜G[…uÕ˜ ëê|û44œ2.þןµ-NÞáÕ µ8ÝÁDöì‡*¼1 Ù7ŸÉ-ŸÒå…fE¿ºXú8ÒÊÂ\ï0éÓQ ;-ëùì;µÃ¬ŠßF$.èï<Õ¬[Ã2Ï~ËP0ÿM‡5㉽ RëÓ^¢¨‹åÇËØÃ”`\Ä™[]1Yk|úß.è?ôŸlþC‘[Ç¡×å+«˜…Šþç’ú/ËÍ5*1d`E¬ð.óÌ‘ì=W†3\7˜Ïæ?ìºý·Æög1;/`þ$»ð}f¶qñ‡žGƒÏ]=‘¶Å,Mz‘pæ¤ÀƒO*™®òŸnJU_ Õm÷ÍWÑ~Ã)º»ðüÈ á6#þ,—e¨ÞÁÞLâ¾0Õ<âEe\Ú4÷ãS=^ì#”mï9^½¾Ú%Pðã«Ü]¯2½,HÕ¾Êâ#·³ê5BÿUý‡þ“Ì(²+ÛtfmEÿÍkWègÐ;¨cúþBãæŠÐËAm°ãžÉ‚øë]”²«ïm(G¾aíWGU3*@Ídz–¢yºy<1.r«f8Ö}):B-ï¸*¶Û²A†­JfVsÎt0Y*±TFûbÑÎ!};ߩֿ>‰YÃ:úÈaÜ×qSUÖRM>59fž@|ÖÏŒýgÖÇöÞû–߃J,×îréÝ´Wʿؿҷmvä%ŒÑŽö$ÕôõsíÃÐAÿ¡ÿ$óŠÜªòýîÑn—¶ »oà Ûœ› Äê±¾Ú.¶ü‚lÇþóåC<øØvÌ„R ]83ÊÒÕOù‡ØXE¼‰¾|`\üÊ’®¦Ù]ÿNî·{I¯ç†Ng ŒX8qþÀ}©sëÛãÛ}kñyN’ÅB;l´)(Êjä«U§³çÜkk×l|¾Ór‚4ú°ª‚9³ûç'ßÈgýb^^aB,÷'Ù-ßÝüvÚÄ›nºüæ“3Ñìëó° ÎY †þ« úý'•ÿP¤V§¨‰{7þuC¥°Yu7râ`Ñ•{D–ÎbhA½³¯•ÔÜ=Œ{ ã@™EãKÔdXÍ2k­©uÏ;P;žºv§Ô¸ø‹{÷~´`¬µƒxYýºKWµ§óêÓÒ¾Ýnõõ»w»¶¸õˆï©…•ÓÜ¿'¶?Úò~Îý¸íÕo?·öÞqzÝÞµÁìÁø+6ì—ýV7/Åì'ÊsbÈôäÍ´×-ÿ¬ò,yù¤iO®ìиJúÅëû'4ÇC¡ÿš‚þCÿÉã?¹õ»ýò¢/ÕÆ‹¸z„ÔØeíæ§ãQ:ÅítÐÕû¼oÞÞh¼Á7ï©c¿e.ÙXøOí))\ÓƒŽÎGYûÑÍÆÅïvpõ§NI§öñŽÆ•âlÚ¥KH›Ù[”b¶ÌÙ —ï -»}ÁZת|ŸCóLj¯œ.‹lé|ü±×óã¶|ƒô?dÙ×w»·•ô³‘Äf­Ù¼tok÷$0+wo¦ë­“Aê ˆè×—‡v}¦Bÿµý‡þ“Æ(R+©Ò"¨óérG3bOXéèJ‹ÆˆñÆm JÛG9ЧҺSÄçØü´ôÌX³7çÆ-z;sZñ¦]/*]»Ñ0†±ˆ(²Ø$áÜ‘ú©$Ǩ¢Ê‚²ŽVdšE o*SÌÞ¦—{ó8­o/ñvþûÀÄôsÇ?£iâ ¾ÖEÜ}'ñ®Hú)ÿ·öæOŸë¿X)·g×ÒÛ7 gœó‰´þáӹ̾j[’¾õ™xÿ°ú€þc úý'‡ÿPäVö%^#µŸL·Õ Çl)Y½jìmã–Œ¸ÛÍ!>îj7öϽóæÓ±ìy¹2gSM5óýäï4¦Ö¨øL§µ[«»ÌÍ)½i\þ½×Y6¼™#ò2ÿIÁs÷ðê~· ï@œ÷Y?õ÷ãQY£~TðaKê)KÝ>ªk“Ÿ—…x¹ô›šMU„ò¿n@å‹ö©ÌO ðs`RÇ‹ìOT—´ÂÄÆµ&ô[Ðè?ü‡"·,ÏUÖå•aœSÝ« {¾rQ ƒiOn_óžos¡b·Ö¹Ðpïì*'4Õgñ°Ïq¾¹‚éOoVÌÞèPU¾ËˆèQËd²roÏ#ÁG®œÑ#¨Y/®ÕTE^;Uˆ‚Cl;^öî(kCÞ%sÿ¹’Õ3î—ãù(bs²|ºû³)ÅŸ_8ëxöÝ;GÍš7gÜå´FÕ#‹¿óê“u²¾tkû±å§'±F¨eú'è?ôÿÃ÷ŠÜšò¦Çœ®ØkmØ÷ó¦|}é³ð¼`ã¾ÌÉþ;o‚Õù™Œ­5ά¸;ªãHCCÜØëø<çQÞhóÊUÈ6M^¿¨ÃYœ Ÿ}¿0P(÷!¶¦Vü—¹ƒêª²BÏ„'åvfqN› ª:s_çö>r¹(kÇzéË¢çƒÕoñÞuزìfÖã~án]_öl•S·ÜìWëìD:ç>w¹ñªtŸ]û¨EG†]CU—DAÿñãCÿ¡ÿºÿ†ôI@}xBf¤ošœ'ˆAé*(ÂeqEühža4\Æ&_´P*@¹,Ž˜o\ôæøL®+Ì-#C£/U^í.Í-3Eˆýõò€ÊJᦎÅ„™* v?Ó?AôÜ?À¦&bß è?ôúO^ÿ¡È-.‡¾EÓ¥R‘ñ%ËeD‹b¢ â`Gù…ɲcÏ9—Ã4˜W‹¯Í+Ê?Å=+M­?M%ψÑ QÞÒ4Þ N¸~[u壉«òË?]Bì…ªHž'ŠûÏ×qÿ £ØéAÿ¡ÿÐòúEn±Y‘žltKB W,TÔ,a3„ñŠj/‹æ‚f§(jè<#x}ñ õÌÞ,&Pþõæ ô^¦Ž¤”<]¤à±®PÐÞYRµo-pÃx2‚v„EIá#ì(1NüÖ0Ðýù‡þëôÿ?ë?¹Å`PüÐØœX>Êa‹†vâµ (0–A¼¢ÒËóB·Ë„ÊfGÏ¿[|5 ÌP¯œTbå_O|A‘¹±:«ð ž)Áä-‘ a²î§Éœ)"ØÈH¢—ÉÂŽß,„ÉŠÇúÐl^í,ô__ ÿÿQÿ¡È-Í E·JÅ|à°±®N$RÔç âàЃcòãÍO¥¡¼¾øa„øä¥ˆˆ>óJž °ã+JpH`~œî*<>8Z&nï¡*HZyEÄx¢åUÙ ê¼vú\šXˆ±£*ô¿‡þCÿÉæ?¹„&eH„Šg _hü0œA<@Ø‘žŒÔŒX~kÁ0Œ×_Qþƒ}¿I¯óâÇ(‹â¶3AO\Ó0š»h¾T¤Z]}ñ—¾1Pžˆ³hGÏ–hÅœgy’PoǬ4UH #*<àPbˆÖ×[-<+ûþN8Æ è¿&ý‡þ“Ç(rk ŠÊãÛ;­š†¡PkItŠ(›îG‰Ë‹ã«÷‹½¿øÜ¨€à|™aåopië3S‰¤¥ä¨¯(y›²‰UæÛy„’ApP['~ëU ®ö&è¿6ý‡þ“Å(rk º%Imóˆ÷; ‡wQóêŸÌÍb¾f±x_ñ‘(¿Ð‚CË?v|€DnˆO#Ö{¦äé5^»m‹'Z™oáyì ™þAæµÐÂG 1‡1¹Ô8­Vô‡‡þCÿÛŽ}¸þC‘[KßÄi,|€ËfŠ„ÆvÂáÊe†y¢ß$bm:ò^â y _ja‚ÀˆD”›xÞ» *Û¼BãÊ¿V|å`ÿ¢=x<—ê¯s P,žáSHxÅŽZ …×Þ°©2¾zŠÐñ¡ÿ úÿ_ñŠÜò“b—²¦a00ú†áðxåꟈõ-›âót¡Ññ`G¬çÊe˜í b ¨l ªHâ¶#Á¢£Î#t¯,}뇵ùpzÑü«7ZxºP¤~ ×ô7>ôúÿÁûEnmÂ(RêýoÉ©rp” ¨\×7GÞ-¾²ü»€Ì„x£óß4ŒÖ²%'@Ùa®…2AïU°6Š’ œ{ÖFa"ÑaP@K|F¬úïÜ0©z6 ÿøI@ÿ¡ÿºÿPäVþw¯Z¿ìùN_æD°xåêŸÀÁöÖÍ? å Älª‹$W‚ ïåË¢€C]+O2°3Q•gSh™†î¾¸ÔuÙ ó¯ÕhŽÏÐøý“©Þ ý×úýÿýÿ÷Ç=Áxœíg\ׯ×,Ñè`/ÁŠ"Ñ Eš EY–¥l3»l¥³”¥Š  EÑ \ jÐWF%5öØîîÒVØÝ)äËÝ9Ï'æ™÷ŒÞó;gÞ9gÞC¡¨,þÐ*n‘®_Ò’=c¯Î/9ïñ‘ˆÔÅi wé÷Ö'.y jýlç%ús l/æ=)ÐçNßÈ/YÜÐà9P¨ï4-ÚúøÕ(#ãŸ9 ȰzvÝsQ‹BrœƒY ?¹ëY8I,òø¼ÿßRb~ÆÎµ¾k,ýËórà\à$—AÈÍûåQåüÛǬƒ_{¾‰yö¬]koÞ=Vì`×Ë|G_¯—‚Ö#[#Fô·<¦q ä¯G?äoàü¡¨­å%ƒþÒ“ÜŽs+ïòG4:Ï'uù5s,ÊNLcT§á/¬°‹µGmûXÓ±úý_Ï3û&ýÜìOœ%ß·¶b©cÍoóL3^1q@-¹ö¯_4Uba¾öá“A§9´D¢~ç%&Œg[¶Lù¸nž]:óbæ^Q¡gGMÜ'´ìuëdÇ— û…ÄŽºÛþ{‘ÿ³œe=*ZÔV'Ý^x¤ãÈ_¯ Èß ùCQ[;]·ëû=[ ÄѧáDÉNR×ãŠóm˜¿VîÛÑ~lãÔŠŠÎiórîèñªýŸ6~“nžrû»½¹DÂnÌ”¦ú{<§~8©1?ªç™‡ßn'Ñzeü)W·1ÏåÞ[âôâר{yÄýÓ¯)|äV~˜aúMI±NˆÖ¼Ðs…°&nÕWRÓK9™&>J<‘ö¶Ëa‹ß„Ÿõ¹`ߘž®þ™;÷f‚whÇÿ:äò‡ü ˜?µu¨é*Ƴ%ÖÏ1=.X7ØÆ;bŒÕuù¯Ä¼>j}Uâê˜Ö#ÓRv_™šº½ÚØÑ­ÛÏnˆyºÃº“|U4þ NAOvWÔIß ìkQÄKŒ]“íø5ãßÝñâŒ87–iºõ( ?ç–ìš•£Ã£ÇÛÝý¢ˆY™·Ïç[üþLúÓeñœÌEúŸ>®z`'Zp°ó@™ñ÷%Õ×mŽÈ²çªý‡]\< ý·?f|Èò7XþPÔVábæ9þ'Ÿ}æI¹öo±ËPÚÀstÏ´Ú–oÿZíç6¼oé32(…¾Êºn X½A¸¢°ÈþoÜñ—[Óîärœàó§ò‡-‚•.e%öÏÉ{·Šìžç±ÓŠzÞ"åвYÔËÊÎçОýÄŒ_<È¢5¿O‹_fÚ#ãÁ»{úÚ>¹P]–öž–ßГïüyøeÛ;ªùGó®oï/jëŠ!‚ü!CåEm}†«°f3r¦“×·n?«$eù¨é¶Ó6==¡ü!0póY…ÊUTÛ~-Ãç·3Ù²gÒÛ?ÇpÁçgT»º´¥äf?ÎdúÅ“þUáÓóA›»gÎÕ[‘¬œ­6‰-q—ì»2¥œ³W¸×©Ò(]3eXÓxÆêžwKõœ½â¦qÅÜÒ®¥ÖÎ0ª«?Øÿ÷u)L¹Ùžÿ?®ø?äoü¡¨­à\§!F•|ñ4ïÒRE©0È S\îØð#e)™è—¿ÌœaùÅÄ1÷N½Ä[C†TEŽ©<,Ç÷íÔ[q5£‚S¢Ç\hõ« ñì‘æh|:©æ§™ŽùGÌüæã±ØÓ%­ðOê{ÃöõãSÒT"¶¦©†˜ŸÞ£*ÃÖ8Ob­½W#LÖy20:ðrOZí¿3ùþ«³öÿ}IB¥ Áà÷ÛÞù†üq…‡ü!ƒäEm¼~Œû³O9o4ºç˜½³ÿ$çüêrù§ü9lmÏ=þÆcwÿ·æêi§Ø§ç–MÌÆ³gøaóŠQ³5íþæ©‘å5fs‚‹xTSKwÜÌŽøñîüHS q?ŠÎ¸ie¾fÓâAŸ‹¦ðûÚýqÔè_ßchµKÝ%ÆÇoÉÔõK’ÐÙ·ˆ·`ß¾Wne-¶Ü”/¶øDîøõ^ïvϤæ–Ç}ö n?X[õûµ–¯³ûÅÞ¬S˜7êðƒr³Ü´žº.È6}9{Ú¼Yý·Î¾Oð Èò§2(ªkÁûýú=ø)úü5}e(=²ìÙûÍ™ªñ+5D¯|8ßxΡ¬v-êÕãažqþ¥Æ'‚?ü†=˜ò¢ÒkÿAÍËÿõöz¨Ã·õWJ6V¸wº«düàsÖâêk—öõ£Üæe{{×?òAåoü´¯ÍâPï+e5·þdcÔœ[ÙëÉݺBíg^W?ɬL÷übÅà[bŽýà?¯Þp»ø’Ä4ò‡ü!êò‡¢¸¸/‹¼‡¿I!åç½*^iyô·çþ׬Υ¤Ý&:æ½-¶Yùšžµ‡©» ¦òãç+Ë|ŸÞ‹}·ÎÅëQ¼Äº9zǾ°$bo»õ{J+n^<ÖÕ]{KBä[Ž^\ΉMT|[j6¦¶¶¬4_Ùe²&$.–÷j{ïùpߤGµ~Wî¯ílð”á›’þîË!Cö<^>S1ù°‰Ðà ¨ùCþ?uùCQ]![ŠŒÌú> 2!8vocç <…Ã9ôQ¯Ý»ú†+ý{ü¶_Ÿ5ÿmŒ¾ø¼Ò¿>°9=îßy×’Ðb?EÍÌu=i£miê³aÙ+—%ÂÔ³a|âwÍdöApKÔ%f?9ž]™^æ-MËFŠoKÒ³?–öøîhG/~Ôƒé6å̸­[¢ZU•m0-×W`Œ8¹1Àlâ¦5‡/Wæ»Aþ?äO]þPT׫aMK¬Çé*Cé—ŸMÀ¤yRÔá?c*d„Ñ*¹®˜÷:hŒ³ÍØËºãsR“«†FV¥,µéºÀØmÕìf«•~+G_"Ð~úwÌo‡¿éùá u_mÞØe¯uÐýÓ—JÆ+jŸ žN3ªOsþä¿;:ýìþlW#Þë'‹Þx8ÓÕüñu¦,í_z¯èãfœ4t[ÙĦä^‚ü!ÈŸºü¡(.0­éòÅÊ£««È,"YÒhi¹q:ù×Xî%ßôÞ¹£áœ9gOìÖu +Ôr]ÎýËuƒ&hYîÌ›OïY^ôÅùŠ]¸c²&Þ-¤zmXܯÊz}ÝÅÃùZØÿî[ýßtŠÎyxL\?fË•²8l&Ne¤^xgëµÑR½DWvÝuAQ¾lúaŒ7Œ­žî]“8åááZ\»¯täùCþÔåEuqne›Î´9sÎ2V‡×¶ÎFì†ñuýM$dyi-caÇÿ#}Ä[Ó…ŒmqÚOs¸“_²öÂú^Zë„Üæô!¿š­cowÕáï"gT3˜±î±¨e³‡iýŽ›… óÖØõéoNHHQÝ1÷IÚû ‹´¸|'ì}8ÆÛ²Ã–?iz·5/ÒžÌ=–¹û«Î[š"׿Ÿç¤÷ƺ›·Š*ZhBy¡Á I[ùCþ?uùCŒ¸ä¾Œ¹5ÎMP‡žr1"èÉ®W_CÑû8ø½ É/sÒäÎá;Çë\újõÓ§e|D—ýà–ý»ŽŠ–ºŽ&˽pÑ¥7¾-EAåý¢ûÑò½7[ßš N_ë˜ó¤Ñµ'î-IWƒ“ßÝ9Ö² ‰ž½ÆÙ.kô-Ì-UC—],jòxÕé4FîêUŸ¦Û=pyÙi-Ól9£qòÌw{C9Ó8G%/]Cþxù¿+Èß@ø[àm>”AŠ)ðuÖÊã²"Å‘”\©HíH:ûŠpB‘ÔÔ(¡îØzüx"vˆs|v”€ËŒ$ãïˆßâç…:g$Iô·V¿ß-?Z@Ì@Ħ$gûVp’¨Óiêø©†ðB¥bÍ.òLjùCþÌŠÚbëÿãá0ÅâH>Ù ÒæWþY²èÑœDi$ÖeÉÆWæ?ÝEžù´?B"€pÏ…”hþ·û#Ó;9^H´ûà‰bj?vdÀ£Kd]ze|v„TÃØŒ„H³ Ìø?äo°ü¡¨-.F *Çê›#Õ7KÐ+m~¸Ì-¾h~¬3ÿ[ülÑøÊ´ vMΈŠT%›-‘o¿ÚÏgùñ3º¦n¿„&KˆvbHM!Vv–lvûÐ2h‰¯éH_¦q-È+>äù.(j Á+3ËF”Lú!Zg¿29ýBc³£…xJåg‚ñ•Ã^ÚFEšL9Ô%åïŸÃÝ™Ejà¬ö#h0+‹pÞ!l?y´gûµOÚâËÚü€¯ÑM@þ¸âCþ¿Aò‡¢¶Ž¬á2…Ý(¾ë(ÍpA3’¥å¿nÄ+È#]!Ugì?Ñ~†«  –äƒ3•?‡^CÔ¯Lin¢ˆ¯ö‹°Ú“®e€¶”#„meD„ɉéè& |ñ!ÈßùCQ[xò¿¥ŒÄ’ˆp”¡pøà±hžhn‚ûñÙøayf¦H[3®ÛíWu'ùñbò÷Ï ÷JN$ê Â7SUuTµŸ)Åh?àKu<¢Ô,^HTÇ+@?¾ËAþ¿!ò‡¢¶p~ÿ ÍíV°Ý'Â?_#Æ? '_™ÿ[¼³R¤méÐÍö”Mw–n!ÿ€ä^K¸ŒÉÙ*‰Sõaêösô—AuOZý쨖ÿVX|ûLòÇò‡ü ‘?µ…ûûßê2*é^MíW­þqáÉ3d""É@,>à1}¶%I5tv£ý冬KKD’¾À£¯ËŽ.c†ÒS%­OM.Õë×3Ðô£H˜°ýUfÈ_pÈò7DþPP8õO•ùˆjõO¶\JðqøåElÞ.—hfCwÚx çô$‚]†Óu$Ü=-†Ï$æ€å—%hˆ©¿ ¨oÐê«üœà¯Aþ?äO]þPT<‹üZš¿D˜A>èÎXüå¿wýbìøÊü÷÷ÏM”¼;ÆíïzA^˜W´BÊçq˜R2~U&ûKäB„Í"ä\:OÞ¾nXÙ~½~½€V?S&&Eæ Èò‡ü©ËŠâúGÊ€lÛ7Tš-"±­ÎøÊüÛ¼%/QÜ鯜tûáƒfÊäïph¡éR~‹ÿ‹OHÄæÌŽ‡uªö³x:ý€V?W&DBbÅdBþ?äO]þPT—ºŒ$w£ Èc3‚QE ÖæŸÝ‰Pnø&ÚÎQ× ±Èµ LÆöèH¾ÚÏ'Q<†[~ŒªúFÈØ[¢4שâGtù±&m~ \ÌùCþ?uùCQ]ª--Y"Ò[jÀØêK¢ü§kKOeþ‡y…h_°CjKQX[6íŽQ=‰#¹%©r$ï¢Ú´mKP|~À e¤¾3V×çÇœ´ùÙÁ9„w3×ðCþ?äOMþP—zKKŽ„dPµú' @9þ'öúoçøú·ôTv2aaqZÜâðk¹ ;hãî8‘*çÈøÕWä'«¤.ãáØÒ³ÅÆòMêRÆÔå\:Æ Õ—“š¡?äùS™?Õ¥.#!ÒHÂ/𨭜Ðlq–HD  F4¾2ÿCÝX»âtt1-~ øÊ^‹îœŸÐz=Œ2œŽKpè[³Zr“ˆpƒAb§/‡¨üLD›Ï å!`C¢Ûò‡ü!jò‡2á^ÿÛÉr_U}û+Ä ÍKPVwÖ©¾l©Û¯L×PgdW¬Î)FÇ—9q–áPNÈú+<¼Nä«ÝüìÔæLrõ…œì ü‡ÿé½A]”ÝÙoÏflÄå–Ym5¾BùzFW‘Y™1½«SÓÚÇ´0Ñ?$$¬ÎªÁ™Ç-cVÿÿ¤ê¯(àGð¿•TÝ:ªâò~5^«˸ lÚwtjìÒ<³J-tDÝ‘“o¶Ì:Ŭ>ÏÌ»2kýü•â3k"ò^Ì›«È¯ÙU÷â·¤'/‹ñó ÿ®G~¯E¢YØw‰O²<®Ý´=Á`ÖÁ6ÇXõÌÍ7Z%žE¦ºü¿F«mùWÆþïâ‹\-ðxnßlÊœ(öÝðM…Œ€d³6Ÿ’{¢óÇ´ÄÕáÍ™\{îí3à?ðøO«£úß@¦æ@V†Nû=ñÜw<•hÚâÕùAÑIsß’ä݃Õn#á¹Ê$ÝvÏP›å‰ÜäTËתÅ÷bX/äÆdmšÛ.w|)?ǤæôºŸã葸ü:ö/–.é;sçþŽ[NrG1Õ>Tóǹ’›rG½aË©–ÅeÅsžñÒKœ=½=±Â¸í|x³MF–^ümö¾çí¶ÕµÐNù fèß|u¿töƒ/Q » †•h—Å+§ M€ÿÀà?eýרk¦ÆØ™­}Q¡?«ÿóÐÀÚ«ÏÊI·¸2ŸWµ,Rk߸Ö²N÷ÍÑFK’o×?+U-¾¥–¾žAÙó›OKäŽÚiîÔùU¯û,§~Þ a½ß>m¹ûø~9Ÿ,ó¨|kkç~ Çè y|hß÷V•q½Ü¸¡»«¿\¾ÓzÈ û1öú6îÁäü{닌_¢ß! Õ8?oÓô—·w:Â=Øèo“Þ“°:H“ÿ”œ­uÀà?ðŸ²þk—êÈâ~_Êà[ìLÀOCaòÝKiO‡âÝ¢t…_Ï÷^xÛ@Ý49&ïõ‡./Ô³Ô?È>ð×=qi0º õ²uî ûMýrpòØä¥qOŽ5Í'W@}ÊÜVLϮص¯Xh—%9£‹ÅËm;êFùšyÆ¥§ñS"ÁÛÿšzzS½­üÃJH«Üvâ€;5åáIX À´›gì"Œ«jWXë]4m8ÆIüxDÞ¥º¡åÄHt®Wå"à?ðøO]ÿ ‹up…üÎ8ï0ÄJeF*¥Ìï§ŸY0Ø©{"áo. ¥*gê"¨UµUçÐg¾$ô¸ÙàP-Îxâß,šBKCÊôtãsÇ~~˜5ê_Cu5²ö›’x.G¯Þ×E·x8d„ó0ŒmÿêÄŸ  ¶ò•NÑí¸3øŒ< ÿa#bØIOø®}§ÂaFeÀ–rÝfÈp Þrбû¥îK°.Ë<럚¢£33ìÇuãn?›?-½~]¤šqÚtñsà?ðøOeÿ¨.Ç•–[-íœÆ?$Ñ\Päd7Ç4méZ×ñ÷ øÅ:õËz¬FLû¶ 2Út×ígtðówOµøkfŒ ðaù޽ûñÙšV}Ió•[:•éCI]ÐÅyêÐ%HTÐØ̵HPAÉó[ïΫ£Muru›¢Õoo:ÃøîZ&­n^ãËúÿ tÂÝÓLýÔ‹íˆQ=*Ï>¡>u f æR&ÄÓǤÓäh”aŒ:.wÄ 7sóêå²¹ßÀà?ðŸºþQ\°isk×Ùç]Ï\ÁNCáò“šß5{îw®n7n1íøºÃwÿ°R»¾¡u¢\g{Òû7ÏZ5Y.ÿªR|dr˫۵Ó—.í’Åéº{íÅ Y&ÿæô&¹¸Ø¢ÓóK…~)uÕ;°ª~oãóSGᦢžžÖùI-·¨þÜ6œ líâ§ýß·V <“ü¹Kcñä›e·Î(­ó•ê?a}Õ¸‡séÙj7ÿZ×x²@ò†“ý[ý˜tåÛŒ’<++e/€ÿÀà?uý¢º8Íss1@r™˜i(|þUÑlû•Søy¡8<ýd÷„è× (¶d7Ê·LÎß…3[/Œ. %bÀñßM™;ÝM\” i¬OcûGyoÛuʾ…ìæ"ÜwEÍÇAiÅþbôšs¸4yüËb ¾Sá˜aÃ3rvx‹°ƒÔð‚l®î?’ŒÆw-þN¿lû.x哞×è—»5?ÁËeBÝ µÏ¾s`ÏÚ8ÑHÐ=LbP^ûøã+à?ðøO]ÿ¨®€M^yêÉ—¼ôÒX ÌòÈ~›ôàž×`L~í*æ0;DŒ¼^òJ©£˜ã‘Þ˜ÔòÈKW9ÅFFAynIç>[7ˆÕx:: {WBíHoºÄîI0mòÖD?9ïlsß®b´íÆd¢;óRĶ­ë40çOŸïsuæÏwÏ¢ž ÙéÀ Žç~ïóƒ;½¼<¯&©·þ!{í}­b‹4|zðØÉ{Nï[\&Ö„KŸ_ÿÿÀêúDuÙN›Ú¹JÃp¬öUÕ¶ä\1âéȉ&Úu¼Yí±3¸¾èJ7åLóÇùæ3Ì]V-þªÙf7ØÎÖS^88ó@Ÿò£)†Ú·Ûïž;áœU¼ýôÕ(ñ—õkâÍ S¿þ›·ÿŸTó˜ïÍsõ÷sÊz¨áÝ0ã´ƒõè«-aVg LzÔ)æ§ÖõwZ~d$/ ‡avðªðüX>êYb¥8‡¶*=Iø¥´”§ HóR€î'æ‡}~K’‡YÞ1ëyJ¥$<‹¡ÌK¢%ò‰ëà 7Q¸0òë¾à?ðøO¶Âÿ‹þ«¶Ö¨£ˆNú,/ [Ø>^±CÝxy1‘áªð$ãÃ0+x• 76çÚ2žE2>Ì qŽI†)+å™l²¼¬N¾ì ‚Ï¥Éò078$9å3JÎ0YQ|æDE…“¸pƒx+øü'UåøÀÿÿÿHÕ¨£*D„«ÚG i#\ÍIJ•þîUà•ãÃB^ÒÖWÇdÅàµ<¥,êoŒ–kXíá¥Å9AnÙÑòw¼¤§î¾!­E£òd̤Åñ8,à?ðøO«ƒúþÿ—Úâp‘<•[ µ‡%}Ö'd“X({pÕnžd|bÚÇmŠæ\—||bxeÇ(<‡kWýa(Ä!3.BîB†‡Ùˆ8µ€”§óåyÒ(„' ûg¾øß^øßîøÀ²þ«ö‡ @EÒ4Sš†S­¶—‡a6ÝÇÙ²^Àûð“ýgâK¬oŒ‰ n×$ãKzá>®…땚¡, '$UÉ%¼‰‘òU"ÁK†^éBŒÊ<ù;@ÄG€ÿÀà?eýWñkê(‚ˆËâ|UŽoÇ€öáßJÿÀà?uý¢ºdi$®àëÒpD¼lõÏjX”ÍWìê~Ó4 ´ý{»e$ I·ÿÏ<&sCœbR1»ÕRžÉÅáe…Ø~è—Àåa(Ä;]€oiË“À¬Oë€ÿÀà?uý¢º$†Ë¨¾‡˜—®þ tD2„( s¿a|ÉKº—gf¢kÒŒ õ‡¹t7xc4öei8‚ÏÏ¥­,@ÙËëÏ–ðhi@fyÅcÎRæÉ /ó€ÿÀà?uý¢º¤[R2ù_·%(.Ãl†’'DíæÞ’ó+âàÝsÝæ!™>0Éø0D÷ ÊÆm„„õ—\Ã=N‰ýõ|ÜTy’173H‘ƒ9~1ämËÿÿÀêúDqIÓx,¶à«Ò€8¼´‡âBãçJ7ÿDF”†#_Ê#ÜPŸ,q;Û?n|bÊã>ß#¨¿¤ïÃIÁZÊû‘GK#J:ô®I4èÏiHÒ¹2Àà?ðŸºþQ]²4$ä‘Oœµƒ—ôO¥«’7Da®uùVñ¹t7ÿl1Öl\žÃ‚0¶õu,ˆÃì¼ñNsݲcðfòJ×2AÊßÌòˆÇÔ–òÃ8þäÊ<ðøü§¨ÿ@T—t- “÷u[rbðWÿ|Úü›ÿê-AÃÃn´\Q¤*w@¬-E¥ €·ˆÐµ-‡p±ësCÖlŽÃŸÉ+åyŠiD¢ù¦áÏ’çÃ4ReøüþSÖ ªKÅö$ä¥}ÓP/Ÿ6›ð*þ|¥[bÒhîÈ–xUÚ?V|Ùà¬DmãŸ9?œ¢{F%ÜCÐxfz‰ˆfµå#9I*€ÿÀà?Eüÿ/:ëÿ.°ŒxœígXWÛLj¢bA¢ÆØ ¢=/DDÑ×@DAz¥-,°}gfwÙÆÒ¤#½‚ ŠcE_»Dyˆ¢òª vÄøhžÝ¥dA`ÏÌú%™óÿÄ óŸûÞë7g®sæ>s¦ÕYˆÁÅŒ‚KOUåóY“–^íwæpaŽênZÕ ’—+œÌ¸ñööôæ]“{˜u±2/›XüþÍeþK÷šy”ñ£c/IÃ3¸s*3Segûѧ|}~ÈUïŸpYàíÿðáé´Œ®™ vÖ,)Á‹ïÝ?ù ÛÖÔäù¹äôŽ}Ss8_•ÌZ–¿áÕ°EÖº¶3'ßU?äù“—?ÙE?#lúA7ÍDd-#æ?/x’¬»ë±•ŠßÍ]v§ »lñÝã³½ûQݪË("á½'ÿì:ÿ%äJÈ1¯ðn­Ñ}e%[,íØ§5ilME”óØ ÿ ìò Ýÿý­¤ó?†)\[l™]©ÆÏªEN÷Ó]è;¯Ýîe»éBQ4Xþ¬sZ8¬6'3täùCþäåEvù|·q_1-Ò¢¹·žz/þ u¶y{1±Å~û®ÙW¼jÃl±Ü¼Ûi¥¹êü›)kmbŽÉd¯øêýTÎÕÓr+¼§:Ž—ºì¿\[­ÍÝn¥.mj÷ÏGj¯ÏhŠ¿äßʰœkñ¸}£Y¶É ï¡7Oж›TùCþ?yùC‘]á¥áÕ+ù¦Z³$êîο?ìø\þò/è¦b [¥ÿû!ÇØ„·—6õR„—Qç; ¤ã+c-´™+Z±Vk„‘žàÀ¿x¡ÃèFÄÊ`´Ã”ÝOy1£˜ÓDX¥e¯í9ëÂv€¾{»ÿxPÁE¬dk’¨}׌Ñú#ûíÒ©òÓO¦ïD¯Í`“ǺpVÆ—ú+À³oŽ/Xñ¬:ù03´ð—5CÇN§&©wtÖ†ÿ™_SΜ3}øøÜ[2Ë»Z÷ÍLî9·Í»qX<çDtÞ2ãa—‰åï¸Ìl¯Ëø›å×*õ—î†ßï´Ü8ÛPÛcÞy^PПcD‡Fâñ»XM—>]L9è)¥e)¸-|V‹pWÆWæf3)t'ÚJ·oæ­‚ü!ÈŸ¼ü¡H.tb݉ŸæÛÝ­ªÀÑýTõž¸Üøö[ü|ú‘Qø»áè”úŠ’ñ¡O«Ë ÕÌ© (.Ó*PUlÝÞÊPÃúù’[Îì/À[é7úµ4þ…ëïï<¾›Jà‚ßÛÉÏx?ºfOֆãw-wã{' 5kÈÖ¿û-‡cþÑ=»MÛµ/F+ʰÓ'1­neªwuò‡ü!Òò‡"»˜·· ùÐ|{í¶M±Dì+ð“Òu°úH'£7ˆtÂYw㿸Þü§C’½Ú2+ožÁž¦Tí©²9=ðbÕÇõ9òv¤KÊ÷xæïªœô~¤¾ø™Ù„; *¡§h쇱/8ïlƒÒ«\ý'›„œªÁëÓhaà<Ìç¸)lJÃÞÜŒ1Š?9MÑwMþ“.È^.UçêV?äù“—?Ùµq¤žm‰/¶ÓÁõìJ)nÿ-‘U&Èœ¢oH¬ À·ß’¯WXjÛWŸ.¨?f¸Âüce¢êd™ÀÈõÑ_—–Û~$ß~ܤØëªÏuñ{PpÔ:Û æ5qüÎûÍS¬pß)qV‚ؾVû*›Á§ýb>áyŸK­w¼¤•‹†;¿¿¾Žà’¨?äù“—?ÙµjÜœ0'­Æ¦¸§ÀPËôR_ùS}ˆvà»÷§‰Å_3ÑÄm„õÞüñS¯‡…ùÄ„Ÿô+{òýÎWúÚÉ3임趼;I$:õ}B˜^Óþ]üoOñc˜­á¤Yâ½·åñËû¤ìŸ0^Q´¨[ªA|aSx…Q<öçÌ¡o Í—7A…Ÿ!éE™þü$1HN]üòá% ÈØîgûfË>ßï×Ôùc?äÿ·áEru[#î—÷H™a.XBZ”šòŸæñQ„EuF Ï™? ðù!FÜ¡î.c…g?DTñËï~ ꟪غ_B$Ò]ð?äù“–?Ù¥,CñDš•Ûý(Êa„xa™ ’HÐ RYÆâá/ÊÛ¨‹4O&äów_ރ݋ãÔÖ.{ò·íâ†9îˆ}ˆØ)>'„“8¨ÕÍ–J0M?äùCþääEv)ËXB_£2šÒɯešV#ÁÑ!%_ÞUq‹ÉV<«û ùÓEJ?вB\ ãE¸zÓ*þöÔè¾qÛD éÈýl†P,¿_ððÍj .°é"¥GÖâCþ?äORþP$*ï±²Yb!ñ‡hŠ2šDîǸìp7¶$W&Ä3+Uág±$øâ£#Ä=>3J>Ð äït®v¿¼?MÝ”›ˆ§×îgJ;âËï"ìT ž;`›ÃXb3€”€h)¿s|¼‚ü!ÈŸ¼ü¡È.eŠ+Ö¬Œ&÷ó&Õ KI‘â|Õî¿k —IñHØ¥|Шð3<þOã3¹¹ŸøpþÖ2";tsè,âÎ~nxH*®@Š€ë· Èò'/(²KÞž¸ ¾ï)ýB”IñÅrâÅÀå??‡‰#¾üxF°WrZTd[“Ãéï!>ð¥Iq4]?CÐåF¸äàêÆwø1¦_’ OøÖ¯S|‚ü!ÈŸ¼ü¡È.EŠ)iRFdÓPÎfV-&0P–ÁD ñí?Ð'5UÙQuÃåï!¾ÏðÃ2q5ÀNþÖø(Âð“&â«"*ýt±KEðÍRxí~À{×=LJü!ÈŸœü¡H.C–fK‚²Ã±Ø u‹öäG¹,6`RÞþé›Ó“U–¿Ò´ ¨ôÓ˜Þ‚èH"÷¿âc¨b P<óx:üLAD(à»Cí¶Ö@»_“20äùCþdåEv)ÞEa!Ý,i hG9tŠ–šEð 8⣇î¿%#IªZòÒ0ÿÖ;˜'cG,ø À]ýmKzr¨.;ð¼È«â§xïŒÅ5¡E$y~oñµs|Èò‡üÉÉŠìÒdINÅÕG÷÷ÇâSWÿÒ$>Šri[ý3“º,ÿ­ñ’¦#Ø37A¬é’¢(Í35žÀ]DñÂHÃeÅ´4.Cþ?äOZþPd—²Œ%(#ɯ=v„ËcRÊ,¦úøò±mK`vÂ'Ÿÿô÷xZVˆ‹ 7V³üb+HŒ÷5¢V?ÂðÚ†'¾Ê #¾fe`Èò‡ü‰øÿþü¡H.ÂKr*¾ýæŠ%¦JøœÏ·$gÁ84_JN‚ø“‘†FKš¢Š€S˜†ù3‘ $+ŠÐ§IQ6Åc{4ž%=QVpÌ_%Þ¿L x6Èò‡üÿAüÿ ­þ.ÀÇxœíwX×úÇ-7F£DÔ X°]£ &*bã—HD$Š ¥(J]êöÝÙ3l_vé½FŠb#h°EQ±`äªQlx£5Xb»»€Ô-3Cò<¿Ëœï;;ŸyßÙïœyΙwÎÙ(vÑ¡µ ?Þh¾e( Œ/g›šþ²ù§ã½‡°ý¢Æ æãá[Å8Á«v÷Û6Y8O¦q/ã»iÃF^ò4¤š[aãW4]8G3¯AHrC|ÎàéY|¿ëæâYR¼|£˜8¿Þ¾3¨¾Šòšírz¯Ç±ºT#™©Ð_:'4Ũå3û3︟•}èd1øÐè?ôŸÌþC‘]nîK—æÞñeX<ãcf˜·lwÚ?|.Ý ”-‰m¬RÓÙõØù¶r÷\l){³x¢‰w}“¯gzà¼õå]5ßnòYdÔ'L0çwœñÁµ3ýù6VG£víåÄâO?oÒËÙìûÍñ}û18Y*¯äå¾vfã’ÏR£t#Ç{z¿}u)¬í&žAÁôAâ§gûGâŒß$è?ôúO^ÿ¡ºXØÊH´3à€Ùý ÿÄÂs{+îLG£r>ëÿüˆjKð.ÿ£ûcþ œH,~p%¯ßýÙ‚Æ«)c}/Ó[ûókâ©?ûnzÏî“à±8Ê`6Ãi†k½ ”‹PZwÆÕ»~úÁ£”Ñ&Mû‰–y¹jûýpCêW"|l±Éä%ųè‡=Ââj Œh_èä)Ïf§Žj¿‘Q´‰ïwûæDºô³ ÿ-‚þwÿ¿Àª›‰1þ±2ƒåÄÜBK«q·uóyCß•ž+ZiXl8A˜Ü´ÍqéÂ1©Ç—,1!X†rúqÞW²óklMntâg¹V2ï?‹xÓ‡­å¥³ÝCÏ:7»±5˜ão@N'†UL¬•«>¬˜ýóaöcªpçï>³ðWAøáÐ×½løÎ£¯àâíãÇ}˜Â‘£®ëÌnÆ»_ÖÅþÏ7¶ a¶º;O.–îZý‡þô¿[ø¿_êPÝL£G•žÃRFê,0åIíÃz“NÉÓµëÊEQÑ¡'i§k(Ç&}|o˜>¹}3ÎxFÙé\bñÍêoT~?ÿlÙ®ßLœ»bHQhÀGm60ýiõIkŠÍ…;1F¤Ô×½¬=mÕøÔ|û¬²pDªãåãÛqfÎ?+óé,Ÿ0ƒ [^¢\)ÎÁÁ"FûßM‰®*lš¿(‹ÎÓ©9²U;âs_ïƒWʘNÛç¾*aƒþCÿqeÿQÐÿîàÿ(<‰Cu;EýñvS %šËy˜n¶æßý½Ó|´—¡Àè3"‡"&š&é™gÝæ­UΣô¯­ïù§ya(c©‹ÿ8mÂôûÓh?y´+c/†Öäžµ¤Ø=O{Ëæ>I=üþbî–M˜âѧxÆvÿ€½;šù§é_¾}àÆÏÚˆoIðê³ïúG'ÔÖ4¤ ¾^‡*¶:‡c‡‡(4ìQ¬z÷y•¦·ïQfüöu;÷í•£gêóŠÎ1w©=8Ðè?ôS¼îè¿7®Ì¡º›6Äüiž^º~(Î2T³ü"]#ýß¶²õ†ÚxFÕòÂçé(ûhä¾Ëùíø—Ð*Û¼òõŸ‹ï»ATºöॠƒ„­Á'OýºÍ›gÍ6ÎÖÁ$8#y¯º êØS%8%ÈÙÅÿĸ´…OvdĬ{|ÃE ߢ¹tî†+>çÝøékýèöïmè+ÀÊúÛzM^ïiÕtfA™kÜV¯þö‰Kom¼wõΩcÕ|œ³úý‡þ“ÖÿÍxò†êvZf6§ÜЯÁÀKÄÊp˧Í.Õc 4üì¢fÞ•ý`òÕ+Xyeò~^Þ˜µ›1óࢇýì<±ø+¿™‘wæ“/õË[x^ýùïœR”}ß;]'¿j¦Yæ–›ÓŒúŸÕŸWõæCjù:ù£ÖmkfO‰Ô_8Vï4ޤ}Ø./'…¥@Q{‹I!s¬˜Ø÷FdTJ¾óÉžÑüqÝßž¬ÍSû”javž¹ü þŠÚAôúý'¯ÿP$oäÕýEt«ó‡óu”‘4Œ¼–_è»úò¯{5v¶ç|ÚϪ*]]¨7#Ͱãû²ÀèÚž\×MUE{²ˆÅUµ3k5ëFInfóäúLrã¦ë?HÂÀ©Þ÷CäÝÒ]:w}aq}å虾js¯ãª3$ÃOý~jûÌ9s2£é1¼ùªò$˜x=…~¯×ë³[u߬e³9‡3µw ücüÉÿŠuÛ5À…ÌTˆgùdEª‰Úï ÿÐè?yý‡"»˜Ã>}â¸wnØ*íe$üå°^7K†¯PÏsÞ)F^µ´Fí. 6ޝìÜÍfUÊ?œv¬´ ·SŠÏº*½Ï±Î&òÇ&žs,̯º~ê‹]ÏašÞ˪ý#Ù©§]ÔR¹Ž=“6¬­®«Yßîiû_²Ç<§‘kcëâ[Ô 2~Ï@¾^ÿ›ôž³³ÅÆØE˜–Då<Ÿ,83[ÿjë†Zi¹³³o¼¥Æ%M3n3}|UÃúý‡þ“×(²Ëƒfï[nŠÆ/é…¹ ÕNžŒUžGÍ%ÉKz¨ã);‡}V—1ÍÃ)‡ZžµÒm÷÷‘éKÞ‹ïűsNZ–’ióFųrüë&ºœ}ÀŒ.Àø^‘7oÙ¾sNÎ’×Úã/øsEOÆý·ævXûÛµýÑÛgî’——]zDñ&ä|@^sÕÐW¸d‘-·t¿õXø“ÒÏ,­;ØfWŠô‡9Sï±Ö´¤êæâÄCV©ã5úý‡þ“×(²ë»aÓ]†ž¿ùR[I‹ 3³çN»v»AÍŠË&ä> Xyé섆ºeœ²>u©ãŠÛµ LjÅÿaÄdË™ôÇ÷Ÿ£(=ôŸ”Zqq˜ùŠdÌ=^ë‘¿þ¦îÙQm{Ù;Ùº}%¼´_§³°121ùí\¿'õG0… <4nÏ­g[–O³5jð®#Ÿ?>¤öaüµé¸9í—.;â}¹Ù«ªg’ràG×4¿¦ ý‡þCÿÉë?É…è‹â–Yîø9)ÏÓ;fµu8<K4éð̾¼ÓY­ë“ò†÷ü±wÑÅ£rKªD=z€Ì´ýÆá¥.óªjJÄj—DuÛO}a‘:AóA¡ÿÐè?yý‡"»h¹5üJ;DË?kjåsª+\‡"íyZ…ÝÉ[ÁÐú~ÿ¼w™fžþ+ûò† Ú—`6±øô"v¹u…ܘ¬Vœ2?$™pŽ‚çHŒc¬Sf•YãBfhügÏ Á¯¯ÏØTíSÇŸ`©(šb†áŸA}ºâÁ‚;¶–mª¡Ì2zዊ[ßò§èZuÞ¬…k'U{t¸¹1Ë©¹—{/NR·$idš}«´  ÿÐè?ÙüÇö¼ ªIåqY¨DÈGñÌ×QQLw4-J*@ ðøâÀ¡»eDJw"–3Ê ^—+]ÍŸáAÙ&$ÂÍ-QÊE¥˜ã-jÝ·Ñ |§ãAÿ¡ÿÐÒúEv ¼‚„bž+HyÕqèþhV˜DB€Ç_Ùþi.ôÌH _ÝDòoQ.Í%4IÆïjþmcLŒ˜Û[®p"ÌñÛ/LÖö‡P?^MÐè?ôŸ¬þC‘]Ê+˜Ã’ˆù!˜/ å5Ç¢:Ðt¹HÙ'ÇÏ㋯lÿTgvV„úöO$ÿf¡mâ¥Éh×ò€åãšAˆH 5AŒ"¦#ßq€6?f^Ý!¡ÿÐè?iý‡"¹”Ýy„Í• 1_ApY.hBœ¬ñÁn_|ÀãP‘lU û‹òoƦ§V˜ê¦®äPN€Cš\H„<¦{¢‚'>`SÂeí‰ç¯æù(¶, ÿÐè?iý‡ê6ÄËXL¾c©±èåë‰n‰›.Y|<ÎøÊö춆klÿã+Ÿûö0QHHB° ªcºBÀ"¶?ªìÎ㈯f€v-úý‡þw ÿa€ÜBºT†‰ùXx€"š+ݪ´tYñð8ã;ÈÝ.Òvu+yS,„`x,?—­âÆS À·‡á)‹"<@hž©Rå‰a¯f€6åÏKþŽß¿ó¾ÐÿöÇþCÿÿøOì— º‹"âáÂæH°ð ¬`g42I.jm®<[ÚµøjyeûtâoShmÿâÀpÊŒ’|ÂÍ_y -YÆ'ÂÀòVDšî@›%ÓÍÞi€ƒ×tXè?ôúÿ?î?±~†ê.¢"RA—Ê€ˆDg©ñaS€šÝ~Þ‰ŠgñtóÚâ«á•›YÎÂl…XGËÀN CzlËkEDó('È9G!P•YÎ2àÑ⛇ yõ€þAÿ¡ÿÐLñº¡ÿêÖ €"¸\– ksqtó³¼(hF„DÒ¡©"]‹¯ŽWnd®—f(D:{Ö<_‚1>Üàu‰ñmš’Šg °ò­Bh.‰‘b4„x ÷dys ØxM€¿à÷‡þCÿ¡ÿÿÃþûÝ¡º‹Te –XD¤ŒÕÊ‹´—¡T³hN@^~Ù Q§z#F¾áÛo~ÌË+<¼Í¯uý‡þCÿÉë?ÙExILL|ãìw*š­èXþû{â+ã1(XÛ?öøm&w-À£»EEµ¼Ÿ„Ü@F\»w›tò:Ðè?ôŸ¼þC‘]Ê+ˆÍV• ^#*ž%QÏ«fÿPPEjãâŸøy¼ñÊeøxÄ'„â8¶øí&àÛìÎôA¤m^$RòL)6ð®©òö½y]¼®ôúý'¯ÿP$×ß·$çÇÙ?‰±2-¨þÂøÊû ÝÇ31OûǶ¿sF´ºuÅðåPv€G†¼ýC<¬<Š ªCo¾‘çh,Cê@ÿ¡ÿÐòúEvâÿŒ©•oœýãíÛfñÏ¿;>à2<}’•·\GÂ_ÙþƒÒc¤j;Ò¸òH°CVx»B"ö%=BõM’uü-µó€í©}ý‡þCÿÉæÿÔÜ'=Ð¥xœíg\SÉÆ‘kYVWewUì¸àE)¢€u- ‚€)Ò»ô–žÌ„.E¤#*Š\ÝUuÅ¢¬Ø{/kÃuõâMÀ’sr ~Ú3Ï·ÌÉsÞIþ™ùÍœwf¢†@AµËÃeÞœ=?:ù›=£æw³ž¹e˜çŠ Oäýî1O,—½Ò‡õüoöZU~O÷¹SòG…LxD-¾—§•¹Ä”á|¿4­úFꥑ«%¤üÞ>3MÂgÄ1ÆßÈÏö*Ž.©¦oÙˆzÙ×ïçÑŽ Òy¦wbñB9ªsOÇ]{®ž(_è8uøHÖÚ¸q7UûYG·{ô¸ðáœb¹ÈÄ~WÝ™8ßsó"cãÂQ*ï ùCþ?}ùCÑ\À¼µç@“²ðW§æ·ø ÑwhûÔ•Ý_Ê̺~mÖéuð°Ï)ªo0Q­{·ÖKñg.í¢™¤®þOsíÙÝóuv4Ø”ð,E$ýSþóáÉö1…ç/üŠz™_æz²*ûÛ›[1è´®ï® —•77mÇ ÄxÝmÚ qjkYÇâé=ZNÎOÙùÜ6•î;§ºdî®ÿM¹—š¥ñWeÿ£goÖ—+]’ˆM_ܹ¸Rå}!Èò§/(º‹×Rî9e„pXMÍÿ¦bÑ SÉFAöÇÎßÉcÞ¶BRK®T8ü%Äó¿­°÷5+e7çèâ¿+·^ühamBårO/“xÒþÿUXÎë’·•™…r\U®Åï^5Ík‚ÂW«˜6UMR²-:Se°£PW½êºÚKE×rs£§¥›·Gd¨p{>Lz˜qÝpòA ÃA×ïÜœ®pŽÈ$P·pŒÊZAþ?äOgþPtWÄÚú¶—ï$÷ðì³}pÅàyOëŠÛ^•5Ò,Œ½gvàf5¾?²4h“Ƽ.OB~SŠYæt·ß¨ÇàO!s´ñºEm(ºlcü6t(Êä¡7¨&*ªÅÇžXD—ûe²±U ¤rò¡7wØ®²ÌÖx¥Fo÷M)òMXl¿Àq^ýéÍ!úh×bvzÅ ggi†ý Ðùñ™š†·.*v J‚ü!ÈŸ¾ü¡è®e3g ¯½­o¦}7…*ÇY?Øód‚ÅðË2ÿ¼)EG}Ô' —h° ˆø¬¦öÚö÷´ÉÃ/R‹¯ý`Wª~Ò_'<jRÊ#ºX[¼Š4v°Ú¤ÜÓëò=’Uø—ÛN¸3ËÕ×zð9õ÷²Ò\t±@Óe˜ï6ßø\ïtÆüA ˜~ƒž©ÝÖV¸¡×Âc‘AÍÙºD­ÓüË34×k¢öùCþ?}ùCÑ\@ï^ó­ÛÃÔQN#ò¾×téâèokk·"üÇ +Zî"ÞÇš 6è$â›eþ1ëëÇ÷;zh •ðflÕ?¥ŸAFž@ÉÇ'+ÀØÒsˆÝÔ!!!=lV©|: LÝâ¼mÊ™ê˜ïa?xQzÚg?šßôÉÁÜQ·ì÷”b¸£sg°Ô£_žÅˆoöl¯èé0¯?wË?!1þ/ý®_&0€ü!ÈŸ¾ü¡è.μQ6s¸äøSû¹pnåéZX¿uÏóž^Ü8Ò%yaêéczƒèxœs'oøHë^>yÞ¬è-}4üý˜Ç„j ^¸rû½¶±/tKëPîQ8£Ån“~D¶bÇ èœÛ»Ùf«Ø%ã I¯ÙsÞQÔ1>ïYNßmÃb×:`ø3lfÚï)Çú>y/sZ3ì3’JÉ-¸r¿hþ®È@uÍÛùCþ?}ùCÑ]Á 9•Nš¤×дû“Üâ/‹‹«ÍZ[\Óª†\O{¶{ZÀþË·<ò µ¦×Þ`|a÷ºž=êÈÅݾ{¿hl× ÷>¾õ´ÿwÝŽS«ÿB#ÃøÊþº}»þñ¥Œ1›°kûOß;øþÅ&úÑI³Lû©E½¼B|ÈczÓÛš5Xþ¥¦zÞK™–ƒºF¹È3ÑçCVîUDÙ/ÎHË̶zCíHѦí<^Aq¾åë6?ø_ÀŸ§zÍ™_”@Ìȱ¶ôÚºµÄò…R|›3&:GfŽÆZ!Ô¦ ÞìÉsªªÊ,d[u÷ž»´v#ÎÇ Ff™è:½mVÛ‘ªÀqòr› ×HL Èò§/(ºkz_cË}Ó÷×?¯¡`æk‰íê; )+»”ñd.¥ßÝÌôMby 矢í”A«|enËìç]ÀìÒ—–?ŽéZråÂg iv¿‘Zã?¼ôx¯ì•î¡uϺ׾Ex]ôÜ#4º·üsía¥Â…ðé3ÆŸÚ¤‹³(ÊfàÐ7£{ݾ·»c¹]âr³ô…ýqÚѺ™ï­ýà¶ìËXè]ÌzPdL´î2Aþ?äO_þP4¿k539uòšŠLB§wtPÄñ%7ýýf!K™ÇÍG¼Â\ê¢:þ7UÖòÍÛWæzLFÄØ¼ø—ãìÇTÈ^ 4ªƒÃBÂ~ù55—R|A¯jowÑî]‰RÿLíg3ž®bˆ÷÷Þçé° x_¥8§C9?yA>cûˆixþï«]fOßslo|‡åSœoj4ëÌtñã÷Û¿ØÔ°¹~?² öcµÊÎ_W}6©‚ Èò§/(º+ú7Ö™@‹ñÝYfÄÎïø"Çà7Œ§ÉMÂÖèšBÛ±ì Ÿš)(f7ã˜ÕÄe}8ãˆø#bFXrwöÛçƒû|<~#fOÌ!c‹9ÆÔâ3ª¢«š‹q %Ž|õkuƒgTî%±• aˆÜÙj¾noL‡P}†×Gkì³÷OJ˜‡"¶^3?4J '$jWîòªiód6YGÂÖW›Ý'ÐÛ9 ·^-G¢òäùCþtæEw¹-™;u½³ñRi4`Ъsè‡ûL#[—îD8¸ݧ–†sw´2Íõòð0º‹ï^vÞ«ç»ÃÎw_~~8æá<ÓPºÂÇè6µøž®?ë…s™†uމÔÌ‹vŒ¨'å÷v›:Ün•8tìu¹%PË4ÏÔl°˜–øxMìß÷XvŒÜ‘¬S.Ù×|†H|_?³žuj›¹úÍVÚ>4Þ ;€ü!ÈÿßÈŸbVê_(<–H$ŒC¨í˜E÷KK9Ñn¼ØÒI\¬Ê•øñba,áR˜•($yŸO~Ìøp£œsr„è×qýro0ý’V‰;~2?S„¦\ U~ ˆffŠðî ùCþ?]ùCÑ\|.G"Âi§ªýì„~iéŽdä&Çã6H ì'W™_/`ú†e%mÿ¸ñ‹vOÊO¼q{|1~ý`‡0òãb‹ù\V®p#ØŠÇ'?‡îœ t¥xŠïü!ÈŸ¶ü¡è.€ø¾$žz è—–ð˜¡~HaFB<þÀ¸ÍÏKè\|NˇUœI¡ýãÄ?Ƈ·&9óÆDën„kYªÒž˜^EÉhYægóPzZÀ!0€ü!ÈŸ¾ü¡è.éoœÏŠ“P'mïò~éý¸1~‘Ⱥ4‰H£n÷‹ ôX~>/:tR’N¥ýãÄ|f@ȆÔx„`ý¥ÍÑ=/]¤|#"~8ÁâtôÆÜæ•(ûœ`"Èò‡üéËŠî@Àe‹ÄÒ±)å4œœ>;z9")I&ðXìëİ#]Õöߟ%FÌ`Ÿ²4”fKÌ/'V 0;íFü€’—ˆõ”RêgJ”ü„'?äùÓ—?Í%Kãq¸K~òˆ£ìp/${u¢ˆè¾“ñ¥?ÿ(ÁjiÀÎÔŸƒ–”v-¡¥éh©7B~¹÷NhXQêJ"|?Lÿ,姇ò~v¢‚_6i 6€ü!ÈŸ¾ü¡è®¶4’ AHq-çGé`tER,ޤשø@À‰r«S’ÐÒ`‹/½u¸ëÚ ^+¯?@¸QŽ›Ò02‰í~ vý7œƒºHί˜$1€ü!ÈŸ¾ü¡è.Ù^¶Ð^Õ~i“‰ñ`#¥)ÄÒ/ýís"]u)B.±½8˜ñ•÷òHÇÐ.E«¥QqöñÞ™˜M¸Í/ÄLÃAŒwq’Šj øIM Èò§/(º«- 'u* È’ˆbì(7$µ YDr0þÑO:¾´ý³#—#ÒD€Gů_~ ¸QN¹«±ž¼)ùei<Œ,€ÄËUÑ“|Nã¡>"œ Æ  /~«ƒŸÜò‡ü!úò‡¢¹¤ IÀávj/Ž€Ã#œp_$/+pú¯“ñ¥#_v¤k¬´ýÇ}…úwô„+ÛœL¨+kÿü‰X{‰7ÜomŠŠžDægs1ü€–‡º|Û/ë42ˆO Èò§/(ºK¶x‡Pö’ð3Y¼R²RO~ Þ¶x!_ÖþÃÝ…R¤¿b| ·o ¼_îšì Àªý.ò¢œJWŠT.ÆöËoæ ?àG³ÈL Èò§/(º‹Ä‘–è~—€Ä­Ç=üó«Å—¶V¸‡d­´ýÇv¾þýÒ{3ƒ7ªÜL´þ@ÀðKÎ’à,%Æòé´Š—…³YÑO~ùCþ?}ùCÑ]²4G,"µxç‹YvE¸7²27YL}7.‡-!_ÖþC½’‹SÚ·ÿö«Œø¬ ß+Iì,ÂŒ/;4¦·5¶¥ñ”ý€ã£ršŸÂò‡ü!úò‡¢¹:s$'íþ D’²Ó%„ÇÌŒ+Ô;µ(ùc#ý*GŠ~ò+Ôw0¡úKGð®›Râñî„á—vA‰+ ´ey?• äùCþôåEwµ¥‘b©É)|Æx1‘â$DDäøoñ §ñà3C|Ó ’>Ò)¥âÐ~kì¯Éž¹Œ¼T–E‹Ä—ÿ.k꼕«7—ÇBÕVÍÑ »/‚j³&N±áÆäúDÔ?Ãßs~ç¶í“»ÎFõS}Ì3Ä:.5ß+¼þkÇ*î/†ÝÓQæwÌ^=·(ÛëÅ^Ò¹*=Ÿ¡þ€?àO\þ@D5Ñ+kPÁßܤ(6V9ï‹´wX™mʺp˜šì™ñUAÙMahýMå—â‘R³óV•ç~»ên™[\óÆZå6ý–û¥»ÇÝÝùú¡çw\ùþ[6Dœîjdtúùýoûa?†–K`A¾ÙŸ^ýë½£œ2ß•P jÑùi¹dATÞÒZ¯>bõcÖYYˇ¡Í§ç;1ý·uVüép"eÖÎ#€?àø™?ÑEšampgа1ƒ¯¡š²òz”ì2°\ެ Þ[ýŒš„ «gÍ|{yÄè_Åxö¬^¿Ìžñüô؉惮èðÿt©¢Úè/z¯ o#Û½d7gê½Ü%3-^—ï`cU´5Ü-!‚‚ Âá_ckqjEºýôo+ÕùëWm4• ˜ƒÖï¸Ð¼ðû ^sûU¨ýO‡uq3åχRNKÌ6ß´õ𶯸‡køþ€?qù\ðÈ»g® š~ïØ±m(Zo*¶{¾sQ_äTú‡'AÃT_Sظª´¢—íÓAýoš?ªêDqç5Ň³µ¶±ÙGîܯÿ¨.EPH ¿é½_÷¿vépò`¾|³]/ l{×Î'Åå{ÿ@rêá¡å{3•X齺šŽºû ½üƒ=Á”?ÆWîÎP>ré6oÀ·¡åò-å±^’±sßÕ~Àðü ˈèb_2:ÿÊò(ç0½mIž…Ú&8"»E;†»SW0ã܈ômþRÌ:ý~MâÜŠî×)ÿ}¬c¨–V¡nUáî”È0¡§†™1çnTÏgùßã´ùukb‰Ã-’dA¥µÅ *qDv,Úaí“H Fà+kÎ;ïç‹0øŸDÔÆî\ÇH^Œð=¢=gü‡šˆ¥É{q‹$£NŸ·Ïðü"ó"º¼ŽüÛÇÂòVuënÈ7­ýáZ¢›ãÂû—ª÷~Þ÷K®åT–Æí$uÓã×"ŠÄqôBú’¡F?lJ™ÊM3$¯ÜH’kj°Qf·)÷vî~R Ãî³–‘OT̉ð+Ì9Iê„Ç ¾Á«Ösj‹‹I¢ii9Ož Y†iGÒ¦°öNÝ/œ!}MÏ”~öS:¦|*ãáõe;-¯‘ÞaÝÂT'Àðü‰ËˆèZ~:‰={ý=Îk&øÆKï÷ïø±»_¥åf¦vÙ,ã®¶GøíD§EǰùW޹€¶Ýªûû½'«> 2ŠÍu“:8"wqŸ·G°øþ€?qù\ü¾eI9Ú·5]G+—XSƾÜ`$)3!—ÒCÖØßïL|ÚíÕÇŠ¶èòëÈPwÑ£äÀæ´–¯ŽVÌÉðZýªtæm{tùËÃJ9e‡ÒR±Fû|3Õ¡2ïŠUç_ކ?’’‚Õ¯<¤Bê——}íoŒÙÍK…Ã1þÂÃÎ"΢ëUÅOnoóŸÚéèw©5c¤AÌ­™ÑÓÒ¨lÎzþ€?àO\þ@íF |e f‰èÅnc‰d¡V?<ÛbGß>!{²ÓÜ'\øx±éWœyRø4Ý$ÂL2g~©ðaˆI¦¹Ô¶ùwúÓpÈÕ‡iÿâŒü—öŒ¬2Á]–ÉI²¹ÇN€ý5g3(Þ YxËÙäüt¹µ{çUùçà˶&ÿ=Ì8ȵ)[V*Óïh*öE~…±I÷‘Ï쟮]{¬›êsù†%½³©‰ùªà‰€?&þjþí„ÿL¬É@íJóç¼ÅWÆÚà¹ÜîxÞFÈú?×°ø™à2"¤žâÆç6ÙÕkÙª‚B:b]ƒ¯ åFùñçôãØúuS?ïÖ£}ÁAET“n½u½3wŸ%‹ƒÊårëW˜ò¹Iay¡ðA»÷ÌE6×¢C¬_àë¿§ÿ‚iN|?šO®8/»ß‹1o¢Íó¼O§æÛGcì”Á§k}sÞê3´$ðüñðoüO`OjGòK*rŸuæ×#-xl9ûXsÉç¨Cmõõ‰HîAîÐÝs#Z6˜ýõp³rAÞ¹G‡ñå[÷f´=£ð£ƒŸå”–­ ùæÙô¡eÏ;ês¾ù¾¿ìÔ¯—ÀÊ¿dãÆJ¼$Ù~7ܦ×À¯œ^T^û½OïĶwÿ·ÆnÏâ­ÚzA¿^§ Í*Þ•_Ýò4¨Nñ ÷V).0ûúÂÉ—€?à'ðoü ð$µºl±-_ú´",·ŒÉ Òä_îÚ1‹Ò#™ûÌÈci­¦RdPèÉ.¶IÜ/¿c¡+u?)-_ÖÈÏܵÃð„ә廽/Vë)«A] Éîy[wJât7l$¸Sä³ÑOj\fÍLA õkRùÛw‰p] Œð»št`ö 5azâZCð{ýd4#®ç¿»Æè´ì³0(yZï¢I€?àø£Îloü«ñµE–’S»¼¡Yh¼TF¯hyô’)ÞÓ'´ðóG¼·|1ºó`ã—îâ;'5EÚÚ¯sRF}¤›ã˧ø6O™Ö‰1ös}Ì”“cÞiÿ#½Ûjè»ý §,3 0C]3}¼õRÍwoF$ïR>`ìÛTÐ!Å£gÀhÌ<µ”5]¦&õ‡ï–¨‡æÇñÃêN£°ùy¢ÕÃ<æøþ€?aù/Á• Ô^´æ§…SNñ§/1{€¯Œµöçù–¥6?šÝoæ§ß Ytã:LçÕ<ãoÑæw\fkž¶d™Ùïø®Z·ÂfLb"iÕ˜ªz?•ç=^ts¥âlÊ ‡tZem,Ë"ÿ2æÊ|Ûy±r/ï˜`PwÛ-òêYCý÷PÖšÞÂÕÿÕûïùy¶Ë[×Ñ×ñ½ÿI´¾÷wØtó6AwKÖ™wÙÅO™ øþ€?‘ù\ð¸W¯:ÅÝ1/¹ ÷Ÿ55ûÇ¿ü£6ìñä“çw5yž16øaÉ)»q?jœö›eÁ^=%ym]Z‰ïŸ9a‹?Ÿ<öììNõcŠóž¶¥ë™?l^@å·¬~xsÁ$REE¾þÆJ9$o™“_µè/òëº[ÕÜ;7l˹²<½§wòÏ~ 6–zñt‹-RhÄùΨ*ÚóÀsáÕhnÉÚ îKFþä#cÀð'0œ{/€ˆ%!.G& °L3a„ÏcR]‘¸h…XÀç²åýÍòÑùa˜ÇôöЉ 7j‹Á¯í¨u~„Ksˆ‹Sˆ¬—ì‡Ó4†9¾¾©"TGRùÙŠÆ~ál‚¢¤(ßÚ/— )Áü!þ€?àO\þ@D—r,CH&Æ2‚`˜Ï ðòEÒ”>~\ùÊñàE‰‹Uˆ›´ÄÓÿù<¹ˆÏ +’ÅXǃ_üå—F¸þöÛB$è¥ò³¡&~ˆî–(DÙ‘¿€ë©@kjÞÀðü Ɉè‚b e"!êï¾jÒI_ÇG2ƒe"»W> s<}¢•ë¦íÚ$²ÜùéA(­î|blˆŒD;ƒWùyìF~f{…¡ŸË«ü,‘àà[þ€?àO\þ@D—j>Ï–HEÔSVÛß Kª;q…Ñ/_9þîÔÄhEóñ_çgI[—Ï ¹ ³B$¸VÍòa>‹Åa˜Œ7÷óühqrŒë1¦ˆí›Œsøþ€?qù\ª2‡‹¶ ¨ÿ\¦'’©*œ 0ûñåÃ|Ý•–%o9þëüœÖ”!Õ߆zÒ®+†9T÷Œ`t@M~>sC{ŸFÞŒwøþ€?qù]ê2_.B³F9Ýä¸Ò‘Í¡2qÔ‹_K>׋µŸÄSÍÑפDjÞ££ß¯'bùº$Gaߤ!Fx4ûÌ0Lk‰&~˜ã‹ ?øÙÏÜØŠþþ€?àOPþ@D—rTóØ"©þ2šr²ÉãÐÖ!⌠i£¹8j¿Ž|–X«_µè ;qÒ"äZ¾âzüúÒùlª“(9¼eÄ/ù0Ät Š–a[K4ñÓÝS±žËƒaˆæ(oUÿÀð'& ¢K]†“Jô•ÑTSMÖ&W$:V!i2Õe,™^¿Î|µ_“]™Ê¡¯å§‡kÿzüz³9~kc¢$Ÿ¿>ŸÃV¿>{#3Qå ^ƒŸ¥ÊG`–WH(Ösy0Ìö¦&4ùMÆœøþ€?Aù\ª“x\®\ϵ4꫼}”ðæ§ÛÐùñ嫯¿¿#¼Y9C×~аþZù0Ì¥9ÄÆÊ8ýMó®ßºìÌ©ý\…2ŸëLjŲ¨ÎÑ|#Äâoùüµüõåþmžøë··–?P»Œ¿ŒÅFdºÊhê½&t'Ù"7Ÿê£ðã̇H9þ‘-¡:Æ+òa˜GwR$‰à¶è¿ˆÏX—Žc3‘ÚËÅ0Ó% Ó µY¹—#*ÛþšþúòÀÿŸå&Äô7•áê&©,g$8)Hªa¢Ùº2œv¿rü³iŽHf¨T÷œù0Âc¸r҃ł6é¿í-‹‘ã…u~1*ŠÄ|1’rÀ‰óyLÉßV†üõðüÿyþøþw¨½(@ÓØD'Õ-19R­~õÕ?¾H|”B¬y+®ê–š²Öå·ô«Æ¿Ÿ²5D¦odâÊWžá飾¸-úÏdQÄ)AX'ð_ü,¾?ûÕ¼ª@”B¨òËÀO:àß.øGâIj7¢·EKóFÕÕ?n´ú›jl¿ §Ý¯ ,?²`kˆÅeìùªÃ{»×]ÜýgzRrBñÜM¬ÞÏñÙƒyPÝ@‚üŸÿ—Wýüÿ’?Xÿ[-¶®Œ¥Ùßpõ`‹êæŸZޝÃ:Ÿ%lâW Pª³(3Xÿø×è×ká³|\2"¤ê9·Ú/hEæ1ÈQÑ:K•:ýÄõaÇißê¬5—í­\6´Åçøþ€ÿÿ+Pÿ'¶Ôe$‰Tت2–&¿zhP7 ñ ]§ÈÚ<†!Ö&iF°Õ!1çÃ|ö&rZdCÍ®•ýWþšx»¥FÊð¿(À94Zû/¬V›j üÀŸÈü.|ÿì©ß¯¾×4…‚$EÈuŽÄ¶Èo|KOåøgúº*Ò”ãÕ±ÞTù¶¨ŽI1Ÿ§Ü­»¥( s69% xß¿ò½âXÿ™µ~øþ€?ùÿkž=ðixœíw\ÇßÇUÅ¢bņ5jŒŠ€š *j±¡‚wôÎpe÷n÷¸<©Ò¢ÆŠb‰b "¶رw15ñÙ;P¹ã¸Û]òWv>Áî|æ;Ë›™×ÌNÙv(Å=Ìw¨nÈŠH!çœ?~Ü8$›ÑÌØ/CS,ˆ¶°J:æ‰HŸÿI¾ûþ>ŒÜ°drñŸçMY²skcˆÊïíxqçŽè«rÔ÷$>?ü"oâ¼üp~PŽÔ~/Yõº×—U62ú“ÿuÞØÉ9®Â‚€DÂeç—vr<ðÝ®-eÁ±E>Äý(ÚµÊ>Ä#u†•?’n=ïð3öÃ)Ê fîßõ8…×gýªã0߬š~üÀŸºü(.d`ÝÑs˦žûeÿ&rþAWW-œ}éPY£¡G—C)SбÙ[˜ýb û_=xd¶kmùÞŸÈÅrm_™ýæQÔÄâ±+blöÍËb"þa×K·‹ºûë®Bý áòÁsÝâêsjŒ4úΈõâ\³ôç'Š •›msñÜ”øàcö£olMº[ñOÕŽû¸…Ÿ[—СڼaiÊ…¾dÈ ~A?NÁ2Ï"-ÿõø»Í{®L[G *r9Î.)åzèãXî-ÅŸëÍÇz®_kØÖLì—§'ñýFÈy¿Ç=²˜ï¯œÏ?øá÷Ì™_òüÀŸ²ü¨.?Î*Ö$ËŘø4”Ú­ˆ¸ØN²Ñ¹“ˆy=Þ{'³?úzd<·ã¦ÝøüþðòÐ “„|—ŽBRñxËv/ðº0ÍùåÔãq÷ˆõÄ1?ºÔ;wpÞ6çvúâ[ž—†ñ/?¤}'P¸xm̸íÅ.(¿í.§_nÛUƒ5VA—eáÓ–9¿#ôü¯ƒ*¯öõ¿™ƒË.t[pês®ööüÑõ=›]üÀŸºü¨®9ýlx¢g5÷>à\:«-§þ“#¡·uÞÄ}›ßŸ>]5¹÷^—õxýsN ¢›Þyü¾‚\üyƒ&̱>²rM7Þ,ÄíLaÿVã– \Úðâ¯c­§±å»­GWËuV7ZÞû¿!cæ×ÃÆõoàé—)}Ñå¨üØ+Õ/ ‡°¯Üòu߇ š6r{ñƒ°Ø.ÖCG§^ñ÷k ®Ôêµd»óZK€?àøS—?ÅÅïV‘T8Öf{In.9 Eö°Ù;Üjf•îÛ–Áíü—v‘á÷U›Ö×uOiv6¹ø¦ŠAGvÔ¡´ûeHøÍOQ#ö‘}ÊV—,-Bà:´‡Lt,Õá÷:ÁøSQy =gD®·ãð+œ˜lõ˜‹ß§’ãs¿èì¡” üeޏù›-lˆj’•ßï$cùå£WŽ&* ú8íÙÛjåøþ€?eùQ]‘‡…òå}Y†íèRÔ!ô÷tÞ_ë³ϸÄq¯²zÿô<ž×QŸýåÈ-QLÔ Á¤âóÿ¹UdÝw¦CØ•›ÓÈdÀú¾¼Fž3:zš\wڅηéß"»¯:è|KǪ„ÎÍŽÙ;AhÛŠ_KH½ùGÓº½]š6O³« “cä5SÄSp·š“\äȬlôŸæí*ù½d¢Aï_ÓžÕ¾øþ€?uùQ]ë<œ—TÝZl_O¤Þ6ó¯[è´´Ýþq^=ÐŽsßsšð »§:ý!C“'îìÁuÚÝJóö›cËèƒÚ=Âî«o®9xL8òé‚O ã·îÔÛû8ËQéâã9°‡¨)¹oˆÃH{»Í±¶ØKÄ>xwðü–—Àð§. Š ±5ê3¶ŸˆW}÷¹ l¯÷q†2IИúC·”ÓëeßѢ߻„3wö Ý6šêiøÄ\nÔ½æ6ÀÍ5øG§½ /ÜÜ«ãf”¿Mr߀kå«Ï¶z\×»6(ÌK®\/Å,äÒ#æIW«/µu¦I§‡žGê®íÂWÞÚ¯ƒ. pºôù•é¬níÿ7ŽQs³ÖÀ(³mp¥ŽË€?àøS—?Õ7”¬C{õ—þ$6<¤ËÞ[yc—]ñ…‰i´µMñCÅàÅîaFö ›£q/jç·{—Ú/ÿó¦³ïf¹¤nÛßÊûXìºæ‰GÆV¤å;DhÓÓ™SS6w©Ñú©&¼Å —܌ܸN5 NØoqÚ±²{y³á¯cÉÜ9çâ7•ppɺê/šÙ·©=¿ø»”8L9²¥dw”Þ¶—U\ÕSç Àðü©Ëˆê / ?4ßèG¡ßHI˜kãý}D¯ž®*:}ù™#½›CöŽéÐéUØ(bñ£öTÃ~“™ûÜ–»Œè`ù6l‰òcbn ÚjÔaü‡ðáÚ­ÿZ§éYãÃR¾ÞuÄŽÀ¢Çíçµg 1ØúõXP]¸¢_÷ DìòÏ®içÕ…1Gë /Ι5ªÒ¡o³ÓÈ=¾i¥E=™ýõiÚm½ŽEÌjþ€?àO]þ@T× §ÙãO•ŽŸn}‡pý])›\æùµ(·-<ޞܑž«æÍ´Þqâ{Çá7‰ø™Ù%ßD''¾•qºwqœs~®ÓÐäâ¯^0ÝRqÍuþÐkš~Ää@ |åK·ÜªÖë_ãlß-èÃZ硵â/¸¸5G~SóòÚÅ6Ïì:øŠáò³gÖ}4áDókž®“ž˜¬â¯´ºØº?ªÈ»Õ{€?àøS—?Å…Œ~üÇ›“{«ÞIÌÈŸ8ªÜÝ$Fõ¾xÁ8åä©äâóäÖݽC*ª¶ã7… 3?uâBq§1}ÇOzz½nÓ°±'+·‘‹?áYíYá<›êŠ­×Ç~5=/`)C1ã¹þЉL|~éø*Ƭӿê?ˆŒÙµ@&€dï—i­'F&½^¿vlˆ¹¢@!„x2R~,˜é«”ñ‰úJ Ëøþ€?UùQ]Êã±…õ”_U)ØLTš+ªØ˜æ´->̉nlg°úÏ òM̈á­ÿš~ƒi(ÂC–+j––ˆ_;;^”w\Š!ëG>Û7Q!„ÙBB~áø§Ê›þD€?àøS—?Õ… |ˆ#Æj*Ù¨íWU vˆš–&ãèØÿñÙ•ëGú'oˆN|ñ2aíK›'ÒÈ¿_;;>'•#$ëÇþÐÜ0vºmòão4€?àøS—?Å…õ×ù\HÖ–—p~¬Bp£|ÃÑìDìžnõ¿Xþ©J9¡ú?>‚ÂQ~A?Åke¯~ßÉ•áië4³C °µ›"”¤_勤åÄ ‰úµ€?àøS—?Õ…Õ˜‹HqÕVƒ~¬:À܈Õ(Z ˆðujÕ~>¾ÖB_(€£|CÒÓcDDk"¾øØÀ†èS”Ðbz‘\ù±æ$buv¢D Pù9ñçÇ*rXÝ“'æ×þ€?àO]þ@TÖgoÛ4ܿꟙNC™1]RÌ$j[|¶HÄgù†)ÓäDë?ÞøBËK’¶ì:“*?ÂcùJÒdªÜH>?3‚3T=yb~aû§É…WÀð§* ªK= '˜FjÅb?°‚PeŠœÈºTõ4š´Mñ¹,„C‡7¤’¨ÿ~ŽøŸê‘“"Óõê ¿……–+ô« ÄòI‰ šülN?3¡$ÍÓÅÀð§. ŠKµljÛ4 «^Bñ¸‘46º1žØ ÅÏ~òñá¨À43ENªÁ«bá«3T=g] áò#ÄX¹9^ܘ™çÇrå¦IÕµ’ãò«q-Ëøþ€?5ùQ]êi(´mÓ€˜?šÏaz Ñ±R‚kZÛÁ†/3™TÿO|õàTeŒHw¢åÇ ±.5Yú©´$žáE®ËmAñ#0nñ}Àðü©ËˆêRO#‰Åm›† p4y½ÿôŸ†Ÿì4 öïÏe®æ+2â$m›Fl5¾jðZyVëë‹–á³øÊf+q ??‚p¤IŸ$«ü,1¿j×JùÀð×}û?ΈâRíe¸R{Q>e€À&ä¡Y‰21™C1°ø2{aûÿÌÕHj¼„ÀÂ#ñ¥­ø±‡‹ôâäÅéÙ_¤×ß217Ä7?Nã<"~UzˆºA£áAl™a?6Ðõ}QÀðü©Ëˆêj㑜ªwP¬PoÇáŸzⓚT¿ÿ[nTˆTGb¶yS‡¿i°B¢'o"åGPˆ±²0Q£9!øüØÂ;µq!?6ˆÑ}ðüÊò¢ºÔÓH ¹i8õîŸ0:*ÊQÈHé¥Î"šx|¬þskÐü‰€GÆo8¾jp€oa‚DïÙÊð"½©Zû‰Ô~Îi@l §JµZ~níëà€?àøS—?ÕÕ8 (‰&õþޱ‚ýQqjR ™÷mˆÕNv¸Z€ <È—ÿS|G’ª"ÓunnáÇu¤'Âg²3b„ZɈ)Šð"hŸWð#HëŸ0üÀŸºü(.õ‘–‰iÀÆoyG¢™Šh$†ô4"©øØ=;Ì-Œ—QÒGj6‹¯Ã¯Šà‘"3´¯ï‘ Xï]u¨X;;GŠ";@ž(ÑÌÑ“5àøþÔåDu5NÊ„¿L©²q˜kQ´0VŒB|Â~ÍŒˆù„Ç['(T`õ_@¯#¾ö—=Õ€7¤ëÞŒÃß2áž“¤c>Ÿ¿1 F˜²ÅiÞj¿Þ/ƒê¯ÿ€?àøÿ§ùÿ?dãÂ-openimageio-1.3.12~dfsg0.orig/testsuite/texture-fat/run.py0000755000175000017500000000015112271062644022000 0ustar mfvmfv#!/usr/bin/python command = testtex_command ("horizgrid.tx", " --scalest 1 4") outputs = [ "out.exr" ] openimageio-1.3.12~dfsg0.orig/testsuite/texture-fat/horizgrid.tx0000644000175000017500000003063212271062644023204 0ustar mfvmfvII*€. 4<1%D2j=B@C@D~E¾Sþ¼$‚(‚ 6‚ €@»ƒ Bþ maketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13nÇ yÒ+„Ý6èAšóL ¥ YYYYYYYYYYYYYYYY 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³M@$  * 2 1%: 2` =B@C@Dt E„ S” ¼$š ‚¾ ‚ Ì ‚ €@»ƒ Ø ômaketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13€üx|||| 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíÒ1 Ã@AûÿvŠÔ j.&0ó±…®‹÷=Ïshù¾ï£û_ú‹þ…þ¢¡¿è_è/úú‹þ…þ¢¡¿è_è/úú‹þ…þò›~ÞõïÿÑ_ô/ôý ýEÿBÑ¿Ð_ô/ôý ýEÿBÑ¿Ð_ô/ô—Óý1—g\xœíÒ1 Ã@AûÿvŠÔ j.&0ó±…®‹÷=Ïshù¾ï£û_ú‹þ…þ¢¡¿è_è/úú‹þ…þ¢¡¿è_è/úú‹þ…þò›~ÞõïÿÑ_ô/ôý ýEÿBÑ¿Ð_ô/ôý ýEÿBÑ¿Ð_ô/ô—Óý1—g\xœíÒ1 Ã@AûÿvŠÔ j.&0ó±…®‹÷=Ïshù¾ï£û_ú‹þ…þ¢¡¿è_è/úú‹þ…þ¢¡¿è_è/úú‹þ…þò›~ÞõïÿÑ_ô/ôý ýEÿBÑ¿Ð_ô/ôý ýEÿBÑ¿Ð_ô/ô—Óý1—g\xœíÒ1 Ã@AûÿvŠÔ j.&0ó±…®‹÷=Ïshù¾ï£û_ú‹þ…þ¢¡¿è_è/úú‹þ…þ¢¡¿è_è/úú‹þ…þò›~ÞõïÿÑ_ô/ôý ýEÿBÑ¿Ð_ô/ôý ýEÿBÑ¿Ð_ô/ô—Óý1—g\€   (1%02V=B@C@DjErSz¼$€‚¤‚ ²‚ €@»ƒ ¾²maketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13êNdd 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíÖ!À Áåÿ&>*nЭWL]!HŽ·÷þ>^kÚGuýÕ}ôW÷Ñ_ÝGuýÕ}ôW÷?0êž¾ŸQ=ú»=ú»=ú»=ú»=ú»=ú»=þÿ€—g¶xœíÖ!À Áåÿ&>*nЭWL]!HŽ·÷þ>^kÚGuýÕ}ôW÷Ñ_ÝGuýÕ}ôW÷?0êž¾ŸQ=ú»=ú»=ú»=ú»=ú»=ú»=þÿ€—g¶@Ø Þæ1%î2=B@C@D˜EPS(¼$.‚R‚ `‚ €@»ƒ lèmaketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíÔ± À0 Ál&o&æÑ¤õŒ»ò+V¬ªµÖsØ{_Ñ»{fÎ>Ÿÿwû³Ýþl·?ÛËÿG»ýÙn¶ÛŸíÀ½^NÝ|à  1%$2J=B@C@DÎEVS^¼$d‚ˆ‚ –‚ €@»ƒ ¢$maketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíÒ± À A舠Â/ J $KvN²f¢ /¸ˆ(¥¤×œs{·ÖÒI½÷Zë×cŒís>7>Ùÿ÷þðÿeûÏÚíû¸Ë̘ÀJ PX1%`2†=B@C@D !EHSš¼$ ‚Ä ‚ Ò ‚ €@»ƒ Þ R!maketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíСÀ0 Á¸»ÿ2Tˆ\ˆq˜XvÁៈ9ç9§Ù½÷ó'™¹ÖªªfÇ_O~ ÿÐp¯4`x" ~"†"1%Ž"2´"=B@C@D8%E4SÈ"¼$Î"‚ò$‚ %‚ €@»ƒ %l%maketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíÎ10 ±B1T†R:6wÒøÓ·=“$cÿM—ÿÀ‹ è³’& ˜& &1%¨&2Î&=B@C@DR)E*Sâ&¼$è&‚ )‚ )‚ €@»ƒ &)|)maketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíÁ1 £¬ªEñ²ƒÐvN’þY0ð¢* ¨*°*1%¸*2Þ*=B@C@Db-E)Sò*¼$ø*‚-‚ *-‚ €@»ƒ 6-Œ-maketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíÁ1  £Ø?•QVc°-IÛ_30². ¸.À.1%È.2î.=B@C@Dr1E(S/¼$/‚,1‚ :1‚ €@»ƒ F1maketx horizgrid.tif -o horizgrid.tx2011:04:12 17:40:13 32 1 2 1 5 Plain Textureblack,blackA$maketx horizgrid.tif -o horizgrid.txxœíÁ1  E±*£XcÐ6É 4Popenimageio-1.3.12~dfsg0.orig/testsuite/ico/0000755000175000017500000000000012271062644017124 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/ico/ref/0000755000175000017500000000000012271062644017700 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/ico/ref/out.txt0000644000175000017500000000346512271062644021260 0ustar mfvmfvReading ../../../../../oiio-images/oiio.ico ../../../../../oiio-images/oiio.ico : 16 x 16, 4 channel, uint1 ico 10 subimages: 16x16 32x32 16x16 48x48 32x32 16x16 256x256 48x48 32x32 16x16 subimage 0: 16 x 16, 4 channel, uint1 ico SHA-1: 563F978D0860CB8791716CA694AB94EEA83E6E03 channel list: R, G, B, A oiio:BitsPerSample: 1 subimage 1: 32 x 32, 4 channel, uint2 ico SHA-1: C6AC509D1005F1B1377A24F33A77D4ABEE425628 channel list: R, G, B, A oiio:BitsPerSample: 2 subimage 2: 16 x 16, 4 channel, uint2 ico SHA-1: D9F2BA4010F3BC5D0E24FED9D1C9FC2920180AE8 channel list: R, G, B, A oiio:BitsPerSample: 2 subimage 3: 48 x 48, 4 channel, uint3 ico SHA-1: BA341CEBEC4D0FEBC090E329310D2B8BBEAE1F4C channel list: R, G, B, A oiio:BitsPerSample: 3 subimage 4: 32 x 32, 4 channel, uint3 ico SHA-1: F1D395FE75B3E6133ECF456745EC747CBD53941C channel list: R, G, B, A oiio:BitsPerSample: 3 subimage 5: 16 x 16, 4 channel, uint3 ico SHA-1: B39B76D983D11966C8C344506084515AF9A0F40F channel list: R, G, B, A oiio:BitsPerSample: 3 subimage 6: 256 x 256, 4 channel, uint2 ico SHA-1: F44C9B94AB7D612F62A4DC29FD9C56FD173F2614 channel list: R, G, B, A oiio:UnassociatedAlpha: 1 oiio:BitsPerSample: 2 subimage 7: 48 x 48, 4 channel, uint8 ico SHA-1: 127700A3DACBF25FCD800642D78F8EE91EDE24B9 channel list: R, G, B, A oiio:BitsPerSample: 8 subimage 8: 32 x 32, 4 channel, uint8 ico SHA-1: AA61C682F659F487E2E1F559F0D4682B782C6836 channel list: R, G, B, A oiio:BitsPerSample: 8 subimage 9: 16 x 16, 4 channel, uint8 ico SHA-1: 0196F151853CC595AF7504196C8CCC5B3A3CE446 channel list: R, G, B, A oiio:BitsPerSample: 8 Comparing "../../../../../oiio-images/oiio.ico" and "oiio.ico" PASS openimageio-1.3.12~dfsg0.orig/testsuite/ico/run.py0000755000175000017500000000014312271062644020303 0ustar mfvmfv#!/usr/bin/python imagedir = parent + "/oiio-images" command = rw_command (imagedir, "oiio.ico") openimageio-1.3.12~dfsg0.orig/testsuite/openexr-suite/0000755000175000017500000000000012271062644021161 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/openexr-suite/ref/0000755000175000017500000000000012271062644021735 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/openexr-suite/ref/out.txt0000644000175000017500000002267712271062644023323 0ustar mfvmfvReading ../../../../../openexr-images/ScanLines/Desk.exr ../../../../../openexr-images/ScanLines/Desk.exr : 644 x 874, 4 channel, half openexr SHA-1: CBFEA416A3CA23DF2B1599A0495EECE6FB009E5D channel list: R, G, B, A oiio:ColorSpace: "Linear" compression: "piz" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/ScanLines/Desk.exr" and "Desk.exr" PASS Reading ../../../../../openexr-images/ScanLines/MtTamWest.exr ../../../../../openexr-images/ScanLines/MtTamWest.exr : 1214 x 732, 4 channel, half openexr SHA-1: 0C7FC9D17BCF20EE043335F7D2DCFA2F19B3BA09 channel list: R, G, B, A oiio:ColorSpace: "Linear" compression: "piz" altitude: 716 DateTime: "2002:06:23 16:00:00" ImageDescription: "View from Mount Tamalpais, Marin County, California, U.S.A." latitude: 37.929 longitude: -122.579 Copyright: "Copyright 2002 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 utcOffset: 25200 Comparing "../../../../../openexr-images/ScanLines/MtTamWest.exr" and "MtTamWest.exr" PASS Reading ../../../../../openexr-images/ScanLines/Cannon.exr ../../../../../openexr-images/ScanLines/Cannon.exr : 780 x 566, 3 channel, half openexr SHA-1: 8855671D158731258798358D78E90B2A62CF206D channel list: R, G, B oiio:ColorSpace: "Linear" compression: "b44" Copyright: "Copyright 2006 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/ScanLines/Cannon.exr" and "Cannon.exr" PASS Reading ../../../../../openexr-images/ScanLines/StillLife.exr ../../../../../openexr-images/ScanLines/StillLife.exr : 1240 x 846, 4 channel, half openexr SHA-1: F794B0D381CA2FDCE32BCAEC3734B2AB49579401 channel list: R, G, B, A oiio:ColorSpace: "Linear" compression: "piz" DateTime: "2002:06:23 21:30:10" Copyright: "Copyright 2002 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 0.45 utcOffset: 25200 Comparing "../../../../../openexr-images/ScanLines/StillLife.exr" and "StillLife.exr" PASS Reading ../../../../../openexr-images/ScanLines/Tree.exr ../../../../../openexr-images/ScanLines/Tree.exr : 928 x 906, 4 channel, half openexr SHA-1: 75D2AAD6D04D8B8F520D391926767BC4A00E6A0F channel list: R, G, B, A oiio:ColorSpace: "Linear" compression: "piz" DateTime: "2002:06:23 15:00:00" focus: 3.5 Copyright: "Copyright 2002 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 0.48 utcOffset: 25200 whiteLuminance: 621 Comparing "../../../../../openexr-images/ScanLines/Tree.exr" and "Tree.exr" PASS Reading ../../../../../openexr-images/ScanLines/Blobbies.exr ../../../../../openexr-images/ScanLines/Blobbies.exr : 1040 x 1040, 5 channel, half/half/half/half/float openexr SHA-1: 7228F3D22D0317764870CC00CC697E3E5EEDBA68 channel list: R (half), G (half), B (half), A (half), Z (float) pixel data origin: x=-20, y=-20 full/display size: 1000 x 1000 full/display origin: 0, 0 oiio:ColorSpace: "Linear" compression: "zip" DateTime: "2004:01:19 12:55:33" Copyright: "Copyright 2004 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 utcOffset: 28800 whiteLuminance: 50 Comparing "../../../../../openexr-images/ScanLines/Blobbies.exr" and "Blobbies.exr" PASS Reading ../../../../../openexr-images/TestImages/AllHalfValues.exr ../../../../../openexr-images/TestImages/AllHalfValues.exr : 256 x 256, 3 channel, half openexr SHA-1: 4428F325F403515E6B3BF8E290FB7EDBF959ECF7 channel list: R, G, B oiio:ColorSpace: "Linear" compression: "piz" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/AllHalfValues.exr" and "AllHalfValues.exr" PASS Reading ../../../../../openexr-images/TestImages/BrightRings.exr ../../../../../openexr-images/TestImages/BrightRings.exr : 800 x 800, 3 channel, half openexr SHA-1: F6528D07E75DA1CE490DA6A93EB68573070FFB4B channel list: R, G, B oiio:ColorSpace: "Linear" compression: "zip" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/BrightRings.exr" and "BrightRings.exr" PASS Reading ../../../../../openexr-images/TestImages/BrightRingsNanInf.exr ../../../../../openexr-images/TestImages/BrightRingsNanInf.exr : 800 x 800, 3 channel, half openexr SHA-1: 73F0C53CFCE17B37DD873CF5FE4C9DF0DDB4D3DD channel list: R, G, B oiio:ColorSpace: "Linear" compression: "zip" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/BrightRingsNanInf.exr" and "BrightRingsNanInf.exr" PASS Reading ../../../../../openexr-images/TestImages/GammaChart.exr ../../../../../openexr-images/TestImages/GammaChart.exr : 800 x 800, 3 channel, half openexr SHA-1: D21C1DC58FEC725E62D5A9F1503965CBD1A9BFD4 channel list: R, G, B oiio:ColorSpace: "Linear" compression: "pxr24" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/GammaChart.exr" and "GammaChart.exr" PASS Reading ../../../../../openexr-images/TestImages/GrayRampsDiagonal.exr ../../../../../openexr-images/TestImages/GrayRampsDiagonal.exr : 800 x 800, 1 channel, half openexr SHA-1: 4CC9922AFAD6CA706D66E466BEA9E93D9E813B39 channel list: Y oiio:ColorSpace: "Linear" compression: "pxr24" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/GrayRampsDiagonal.exr" and "GrayRampsDiagonal.exr" PASS Reading ../../../../../openexr-images/TestImages/GrayRampsHorizontal.exr ../../../../../openexr-images/TestImages/GrayRampsHorizontal.exr : 800 x 800, 1 channel, half openexr SHA-1: 1F0A6393B53BCA1AF072EA8B7795AE19FE2C8883 channel list: Y oiio:ColorSpace: "Linear" compression: "pxr24" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/GrayRampsHorizontal.exr" and "GrayRampsHorizontal.exr" PASS Reading ../../../../../openexr-images/TestImages/RgbRampsDiagonal.exr ../../../../../openexr-images/TestImages/RgbRampsDiagonal.exr : 800 x 800, 3 channel, half openexr SHA-1: 8C973B65215B6C1BC0D29376F1C49D6A9A6CFA19 channel list: R, G, B oiio:ColorSpace: "Linear" compression: "pxr24" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/RgbRampsDiagonal.exr" and "RgbRampsDiagonal.exr" PASS Reading ../../../../../openexr-images/TestImages/SquaresSwirls.exr ../../../../../openexr-images/TestImages/SquaresSwirls.exr : 1000 x 1000, 3 channel, half openexr SHA-1: C0A591BDED4A83540BBEFC9FD0549FEEE499EB3A channel list: R, G, B oiio:ColorSpace: "Linear" compression: "pxr24" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/SquaresSwirls.exr" and "SquaresSwirls.exr" PASS Reading ../../../../../openexr-images/TestImages/WideColorGamut.exr ../../../../../openexr-images/TestImages/WideColorGamut.exr : 800 x 800, 3 channel, half openexr SHA-1: B49406C6AA10E1E3CCA7AAF3BF68FDD3E5790643 channel list: R, G, B oiio:ColorSpace: "Linear" compression: "zip" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/WideColorGamut.exr" and "WideColorGamut.exr" PASS Reading ../../../../../openexr-images/TestImages/WideFloatRange.exr ../../../../../openexr-images/TestImages/WideFloatRange.exr : 500 x 500, 1 channel, float openexr SHA-1: 9009BE7DD8CC438F258A48243056E6D46E6147EB channel list: G oiio:ColorSpace: "Linear" compression: "pxr24" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/TestImages/WideFloatRange.exr" and "WideFloatRange.exr" PASS Reading ../../../../../openexr-images/Tiles/GoldenGate.exr ../../../../../openexr-images/Tiles/GoldenGate.exr : 1262 x 860, 3 channel, half openexr SHA-1: 828CD8188CC4A237C8025BA6634D1682A7F8C9BB channel list: R, G, B tile size: 128 x 128 oiio:ColorSpace: "Linear" compression: "piz" altitude: 274.5 FNumber: 2.8 DateTime: "2004:01:04 18:10:00" ImageDescription: "View from Hawk Hill towards San Francisco" ExposureTime: 8 focus: inf isoSpeed: 50 latitude: 37.8277 longitude: -122.5 Copyright: "Copyright 2004 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1.15 utcOffset: 28800 Comparing "../../../../../openexr-images/Tiles/GoldenGate.exr" and "GoldenGate.exr" PASS Reading ../../../../../openexr-images/Tiles/Ocean.exr ../../../../../openexr-images/Tiles/Ocean.exr : 1255 x 876, 3 channel, half openexr SHA-1: 32BF0712FEABFFB448898D91F97E5C38BD351FD7 channel list: R, G, B tile size: 128 x 128 oiio:ColorSpace: "Linear" compression: "zip" focus: inf Copyright: "Copyright 2004 Industrial Light & Magic" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Comparing "../../../../../openexr-images/Tiles/Ocean.exr" and "Ocean.exr" PASS openimageio-1.3.12~dfsg0.orig/testsuite/openexr-suite/run.py0000755000175000017500000000337512271062644022352 0ustar mfvmfv#!/usr/bin/python # ../openexr-images/DisplayWindow: # README t03.exr t06.exr t09.exr t12.exr t15.exr # t01.exr t04.exr t07.exr t10.exr t13.exr t16.exr # t02.exr t05.exr t08.exr t11.exr t14.exr imagedir = parent + "/openexr-images/DisplayWindow" # ../openexr-images/ScanLines: # Blobbies.exr Desk.exr StillLife.exr # Cannon.exr MtTamWest.exr Tree.exr imagedir = parent + "/openexr-images/ScanLines" files = [ "Desk.exr", "MtTamWest.exr" ] for f in files: command += rw_command (imagedir, f) command = command + rw_command (imagedir, "Cannon.exr", extraargs="--compression zip") files = [ "StillLife.exr", "Tree.exr", "Blobbies.exr" ] for f in files: command += rw_command (imagedir, f) # Cannon must be instructed to use lossless compression # FIXME - on all: chromaticies, screenWindowCenter, preview? # ../openexr-images/TestImages: # AllHalfValues.exr GrayRampsDiagonal.exr SquaresSwirls.exr # BrightRings.exr GrayRampsHorizontal.exr WideColorGamut.exr # BrightRingsNanInf.exr README WideFloatRange.exr # GammaChart.exr RgbRampsDiagonal.exr imagedir = parent + "/openexr-images/TestImages" files = [ "AllHalfValues.exr", "BrightRings.exr", "BrightRingsNanInf.exr", "GammaChart.exr", "GrayRampsDiagonal.exr", "GrayRampsHorizontal.exr", "RgbRampsDiagonal.exr", "SquaresSwirls.exr", "WideColorGamut.exr", "WideFloatRange.exr" ] for f in files: command += rw_command (imagedir, f) # ../openexr-images/Tiles: # GoldenGate.exr Ocean.exr Spirals.exr imagedir = parent + "/openexr-images/Tiles" files = [ "GoldenGate.exr", "Ocean.exr" ] for f in files: command += rw_command (imagedir, f) # FIXME - Spirals: per-channel formats, iv >4 chans, chromaticities openimageio-1.3.12~dfsg0.orig/testsuite/gif/0000755000175000017500000000000012271062644017117 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/gif/ref/0000755000175000017500000000000012271062644017673 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/gif/ref/out.txt0000644000175000017500000000363612271062644021253 0ustar mfvmfvReading ../../../../../oiio-images/gif_animation.gif ../../../../../oiio-images/gif_animation.gif : 10 x 10, 3 channel, uint8 gif 3 subimages: 10x10 20x20 30x30 subimage 0: 10 x 10, 3 channel, uint8 gif SHA-1: 74DA8D1F72256D1E6BA2C379A902B74A549A4FC3 channel list: R, G, B gif:DelayMs: 1230 gif:Interlacing: 0 subimage 1: 20 x 20, 3 channel, uint8 gif SHA-1: 697CB4AF27DF31D38FBDFFCE0799A68197DB811C channel list: R, G, B gif:DelayMs: 1230 gif:Interlacing: 0 subimage 2: 30 x 30, 3 channel, uint8 gif SHA-1: 3CF612475D2B8C81968A243A0E0B74FF28E2F0BC channel list: R, G, B gif:DelayMs: 1230 gif:Interlacing: 0 Reading ../../../../../oiio-images/gif_oiio_logo_with_alpha.gif ../../../../../oiio-images/gif_oiio_logo_with_alpha.gif : 135 x 135, 4 channel, uint8 gif SHA-1: 8EDEB5C51B7C376D2526BAC0E3CFE2BE500F4115 channel list: R, G, B, A ImageDescription: "oiio logo with alpha" gif:Interlacing: 0 Reading ../../../../../oiio-images/gif_tahoe.gif ../../../../../oiio-images/gif_tahoe.gif : 2048 x 1536, 3 channel, uint8 gif SHA-1: FB29B5E79C01217F6FF7306194D4CDF23BBBA0EF channel list: R, G, B gif:Interlacing: 0 Reading ../../../../../oiio-images/gif_tahoe_interlaced.gif ../../../../../oiio-images/gif_tahoe_interlaced.gif : 2048 x 1536, 3 channel, uint8 gif SHA-1: FB29B5E79C01217F6FF7306194D4CDF23BBBA0EF channel list: R, G, B gif:Interlacing: 1 Reading ../../../../../oiio-images/gif_bluedot.gif ../../../../../oiio-images/gif_bluedot.gif : 1 x 1, 3 channel, uint8 gif SHA-1: D699C11B42E27B746F565C0EABF18AE1A78853AD channel list: R, G, B gif:Interlacing: 0 Reading ../../../../../oiio-images/gif_diagonal_interlaced.gif ../../../../../oiio-images/gif_diagonal_interlaced.gif : 200 x 200, 3 channel, uint8 gif SHA-1: 31B97C008117F6925A4D15ECE852B84B481DE8A3 channel list: R, G, B gif:Interlacing: 1 openimageio-1.3.12~dfsg0.orig/testsuite/gif/ref/out-alt.txt0000644000175000017500000000364012271062644022024 0ustar mfvmfvReading ../../../../../oiio-images/gif_animation.gif ../../../../../oiio-images/gif_animation.gif : 10 x 10, 3 channel, uint8 gif 3 subimages: 10x10 20x20 30x30 subimage 0: 10 x 10, 3 channel, uint8 gif SHA-1: 74DA8D1F72256D1E6BA2C379A902B74A549A4FC3 channel list: R, G, B gif:DelayMs: 1230 gif:Interlacing: 0 subimage 1: 20 x 20, 3 channel, uint8 gif SHA-1: 697CB4AF27DF31D38FBDFFCE0799A68197DB811C channel list: R, G, B gif:DelayMs: 1230 gif:Interlacing: 0 subimage 2: 30 x 30, 3 channel, uint8 gif SHA-1: 3CF612475D2B8C81968A243A0E0B74FF28E2F0BC channel list: R, G, B gif:DelayMs: 1230 gif:Interlacing: 0 Reading ../../../../../oiio-images/gif_oiio_logo_with_alpha.gif ../../../../../oiio-images/gif_oiio_logo_with_alpha.gif : 135 x 135, 4 channel, uint8 gif SHA-1: 8EDEB5C51B7C376D2526BAC0E3CFE2BE500F4115 channel list: R, G, B, A ImageDescription: "oiio logo with alpha" gif:Interlacing: 0 Reading ../../../../../oiio-images/gif_tahoe.gif ../../../../../oiio-images/gif_tahoe.gif : 2048 x 1536, 3 channel, uint8 gif SHA-1: FB29B5E79C01217F6FF7306194D4CDF23BBBA0EF channel list: R, G, B gif:Interlacing: 0 Reading ../../../../../oiio-images/gif_tahoe_interlaced.gif ../../../../../oiio-images/gif_tahoe_interlaced.gif : 2048 x 1536, 3 channel, uint8 gif SHA-1: FB29B5E79C01217F6FF7306194D4CDF23BBBA0EF channel list: R, G, B gif:Interlacing: 64 Reading ../../../../../oiio-images/gif_bluedot.gif ../../../../../oiio-images/gif_bluedot.gif : 1 x 1, 3 channel, uint8 gif SHA-1: D699C11B42E27B746F565C0EABF18AE1A78853AD channel list: R, G, B gif:Interlacing: 0 Reading ../../../../../oiio-images/gif_diagonal_interlaced.gif ../../../../../oiio-images/gif_diagonal_interlaced.gif : 200 x 200, 3 channel, uint8 gif SHA-1: 31B97C008117F6925A4D15ECE852B84B481DE8A3 channel list: R, G, B gif:Interlacing: 64 openimageio-1.3.12~dfsg0.orig/testsuite/gif/run.py0000755000175000017500000000044712271062644020305 0ustar mfvmfv#!/usr/bin/python2 imagedir = parent + "/oiio-images" files = ["gif_animation.gif", "gif_oiio_logo_with_alpha.gif", "gif_tahoe.gif", "gif_tahoe_interlaced.gif", "gif_bluedot.gif", "gif_diagonal_interlaced.gif"] for f in files: command += info_command (imagedir + "/" + f) openimageio-1.3.12~dfsg0.orig/testsuite/bmp/0000755000175000017500000000000012271062644017130 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/bmp/ref/0000755000175000017500000000000012271062644017704 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/bmp/ref/out.txt0000644000175000017500000000361312271062644021257 0ustar mfvmfvReading ../../../../../bmpsuite/g01bg.bmp ../../../../../bmpsuite/g01bg.bmp : 127 x 64, 3 channel, uint8 bmp SHA-1: 3A3A9A7D3A25907693A33D4403B3FB5BFCC9E5B1 channel list: R, G, B XResolution: 0 YResolution: 0 ResolutionUnit: "m" Comparing "../../../../../bmpsuite/g01bg.bmp" and "g01bg.bmp" PASS Reading ../../../../../bmpsuite/g04.bmp ../../../../../bmpsuite/g04.bmp : 127 x 64, 3 channel, uint8 bmp SHA-1: 83CE69952523E32894E14052E6B497E9D2C8867C channel list: R, G, B XResolution: 0 YResolution: 0 ResolutionUnit: "m" Comparing "../../../../../bmpsuite/g04.bmp" and "g04.bmp" PASS Reading ../../../../../bmpsuite/g08.bmp ../../../../../bmpsuite/g08.bmp : 127 x 64, 3 channel, uint8 bmp SHA-1: 18C1DA0C611E94F164B5C0758132EF9CE202DD47 channel list: R, G, B XResolution: 0 YResolution: 0 ResolutionUnit: "m" Comparing "../../../../../bmpsuite/g08.bmp" and "g08.bmp" PASS Reading ../../../../../bmpsuite/g16bf555.bmp ../../../../../bmpsuite/g16bf555.bmp : 127 x 64, 3 channel, uint4 bmp SHA-1: 630022A1DFE41AA6AE07F272E3D441205F612240 channel list: R, G, B XResolution: 0 YResolution: 0 ResolutionUnit: "m" oiio:BitsPerSample: 4 Comparing "../../../../../bmpsuite/g16bf555.bmp" and "g16bf555.bmp" PASS Reading ../../../../../bmpsuite/g24.bmp ../../../../../bmpsuite/g24.bmp : 127 x 64, 3 channel, uint8 bmp SHA-1: B1FB63649469F31D02D7AD065D3128EE04CC662E channel list: R, G, B XResolution: 0 YResolution: 0 ResolutionUnit: "m" Comparing "../../../../../bmpsuite/g24.bmp" and "g24.bmp" PASS Reading ../../../../../bmpsuite/g32bf.bmp ../../../../../bmpsuite/g32bf.bmp : 127 x 64, 4 channel, uint8 bmp SHA-1: AB315E7E66DBE94299A2E0F2749C5947D924B48B channel list: R, G, B, A XResolution: 0 YResolution: 0 ResolutionUnit: "m" Comparing "../../../../../bmpsuite/g32bf.bmp" and "g32bf.bmp" PASS openimageio-1.3.12~dfsg0.orig/testsuite/bmp/run.py0000755000175000017500000000031512271062644020310 0ustar mfvmfv#!/usr/bin/python imagedir = parent + "/bmpsuite" files = [ "g01bg.bmp", "g04.bmp", "g08.bmp", "g16bf555.bmp", "g24.bmp", "g32bf.bmp" ] for f in files : command += rw_command (imagedir, f) openimageio-1.3.12~dfsg0.orig/testsuite/maketx/0000755000175000017500000000000012271062644017643 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/maketx/ref/0000755000175000017500000000000012271062644020417 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/maketx/ref/out.txt0000644000175000017500000003231012271062644021766 0ustar mfvmfvReading grid.tx grid.tx : 1000 x 1000, 4 channel, uint8 tiff MIP-map levels: 1000x1000 500x500 250x250 125x125 62x62 31x31 15x15 7x7 3x3 1x1 SHA-1: 97D6548FF9E9BFD21424B773B1D84FACDF0C1797 channel list: R, G, B, A tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=9CA964417213269190944948273FB1F00A4A8393" Orientation: 1 (normal) XResolution: 72 YResolution: 72 ResolutionUnit: "in" DocumentName: "g.tif" textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=9CA964417213269190944948273FB1F00A4A8393" Reading grid-resize.tx grid-resize.tx : 1024 x 1024, 4 channel, uint8 tiff MIP-map levels: 1024x1024 512x512 256x256 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 1DAB274639828223059FDBC0E30BD569C07B66C0 channel list: R, G, B, A tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=C4BE40DC3B3534F30ACB906602F2FF80A246C01E" Orientation: 1 (normal) XResolution: 72 YResolution: 72 ResolutionUnit: "in" DocumentName: "g.tif" textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=C4BE40DC3B3534F30ACB906602F2FF80A246C01E" Reading checker-uint16.tx checker-uint16.tx : 128 x 128, 4 channel, uint16 tiff MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 75BCACCE72A4275AD11FAF4A5D328C624DFF69AB channel list: R, G, B, A tile size: 64 x 64 oiio:BitsPerSample: 16 ImageDescription: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Reading checker-1chan.tx checker-1chan.tx : 128 x 128, 1 channel, uint8 tiff MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: F7DAC8772B7C6BFABDA884D61ABC84844C949AF1 channel list: A tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=1D0A2254373A69C054C08672041FC7DE3BAE5179" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 1 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=1D0A2254373A69C054C08672041FC7DE3BAE5179" Reading checker-16x32tile.tx checker-16x32tile.tx : 128 x 128, 4 channel, uint8 tiff MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 1C1A7D35CCED212B768B31F002B442EA947D89A6 channel list: R, G, B, A tile size: 16 x 32 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Reading checker-seplzw.tx checker-seplzw.tx : 128 x 128, 4 channel, uint8 tiff MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 1C1A7D35CCED212B768B31F002B442EA947D89A6 channel list: R, G, B, A tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 2 planarconfig: "separate" tiff:Compression: 5 compression: "lzw" IPTC:Caption: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Reading checker-clamp.tx checker-clamp.tx : 128 x 128, 4 channel, uint8 tiff MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 1C1A7D35CCED212B768B31F002B442EA947D89A6 channel list: R, G, B, A tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "clamp,clamp" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Reading checker-permir.tx checker-permir.tx : 128 x 128, 4 channel, uint8 tiff MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 1C1A7D35CCED212B768B31F002B442EA947D89A6 channel list: R, G, B, A tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "periodic,mirror" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Reading checker-nomip.tx checker-nomip.tx : 128 x 128, 4 channel, uint8 tiff SHA-1: 1C1A7D35CCED212B768B31F002B442EA947D89A6 channel list: R, G, B, A tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Reading checker-camera.tx checker-camera.tx : 128 x 128, 4 channel, uint8 tiff MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 1C1A7D35CCED212B768B31F002B442EA947D89A6 channel list: R, G, B, A tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" worldtocamera: 1 0 0 0 0 2 0 0 0 0 1 0 0 0 0 1 worldtoscreen: 3 0 0 0 0 3 0 0 0 0 3 0 1 2 3 1 IPTC:Caption: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Reading checker-opaque.tx checker-opaque.tx : 128 x 128, 3 channel, uint8 tiff MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: 6827D9ED3A5674C1FAB56F96E5D7D06796D43144 channel list: R, G, B tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=2BE3743A64D4309645F94CA7B37D0CD08AF0B38E" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=2BE3743A64D4309645F94CA7B37D0CD08AF0B38E" Reading gray-mono.tx gray-mono.tx : 256 x 256, 1 channel, uint8 tiff MIP-map levels: 256x256 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: F5C1F9FA963006D501B14542F5E941AEDB4C5907 channel list: A tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=24049CDF337F17E162291C7B626E0588A9D71160" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 1 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=24049CDF337F17E162291C7B626E0588A9D71160" Reading pink-mono.tx pink-mono.tx : 256 x 256, 3 channel, uint8 tiff MIP-map levels: 256x256 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: D781FABF7CF958AE9D9429255C8591C77BAA9917 channel list: R, G, B tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "SHA-1=D5F1500992EFBDA77B89E946A9F53F89D332B6F4" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=D5F1500992EFBDA77B89E946A9F53F89D332B6F4" Reading checker-prman.tx checker-prman.tx : 128 x 128, 4 channel, int16 tiff MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: DE42A8468161DA333BABF1BEB60811EA0FEF6534 channel list: R, G, B, A tile size: 64 x 32 oiio:BitsPerSample: 16 ImageDescription: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 2 planarconfig: "separate" tiff:Compression: 8 compression: "zip" IPTC:Caption: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" Reading nan.exr nan.exr : 64 x 64, 3 channel, half openexr SHA-1: 47A8E8F3E8B2C3B6B032FCC8C39D3C5FC1AAA390 channel list: R, G, B tile size: 64 x 64 oiio:ColorSpace: "Linear" compression: "zip" ImageDescription: "SHA-1=44B96A7C3AFBF8D7621E7C6453266E5DD1962D36" fovcot: 1 openexr:levelmode: 0 PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 textureformat: "Plain Texture" wrapmodes: "black,black" Stats Min: 0.000000 0.000000 0.000000 (float) Stats Max: 1.000000 1.000000 1.000000 (float) Stats Avg: 0.500000 0.500000 0.500000 (float) Stats StdDev: 0.500000 0.500000 0.500000 (float) Stats NanCount: 0 0 0 Stats InfCount: 0 0 0 Stats FiniteCount: 4096 4096 4096 Constant: No Monochrome: Yes Reading checker-exr.pdq checker-exr.pdq : 128 x 128, 4 channel, half openexr MIP-map levels: 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: FA921281D5C8AF14FC50885DD54E2E17509202EC channel list: R, G, B, A tile size: 64 x 64 oiio:ColorSpace: "Linear" openexr:roundingmode: 0 textureformat: "Plain Texture" compression: "zip" Orientation: 1 (normal) ImageDescription: "SHA-1=D924CA144A02479D1507F5910F5FC8F51EF78765" fovcot: 1 PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 wrapmodes: "black,black" Reading small.tif small.tif : 64 x 64, 3 channel, uint8 tiff SHA-1: BE1D5EA24E907A4C4B3FB3C28EAC872A20F5B414 channel list: R, G, B oiio:BitsPerSample: 8 ImageDescription: "foo SHA-1=1234abcd ConstantColor=[0.0,0,-0.0] bar" Orientation: 1 (normal) tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 5 compression: "lzw" tiff:RowsPerStrip: 32 IPTC:Caption: "foo SHA-1=1234abcd ConstantColor=[0.0,0,-0.0] bar" Reading small.tx small.tx : 64 x 64, 3 channel, uint8 tiff MIP-map levels: 64x64 32x32 16x16 8x8 4x4 2x2 1x1 SHA-1: BE1D5EA24E907A4C4B3FB3C28EAC872A20F5B414 channel list: R, G, B tile size: 64 x 64 oiio:BitsPerSample: 8 ImageDescription: "foo bar SHA-1=1DD1CB3C76F9A491B115F85A6DAC1B1A8DD2D3CB ConstantColor=[1,0,0]" Orientation: 1 (normal) textureformat: "Plain Texture" wrapmodes: "black,black" fovcot: 1 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 1 planarconfig: "contig" tiff:Compression: 8 compression: "zip" IPTC:Caption: "foo bar SHA-1=1DD1CB3C76F9A491B115F85A6DAC1B1A8DD2D3CB ConstantColor=[1,0,0]" whiteenv.exr : 4 x 2, 3 channel, half openexr (+mipmap) MIP 0 of 3 (4 x 2): Stats Min: 1.000000 1.000000 1.000000 (float) Stats Max: 1.000000 1.000000 1.000000 (float) Stats Avg: 1.000000 1.000000 1.000000 (float) Stats StdDev: 0.000000 0.000000 0.000000 (float) Stats NanCount: 0 0 0 Stats InfCount: 0 0 0 Stats FiniteCount: 8 8 8 Constant: Yes Constant Color: 1.000000 1.000000 1.000000 (float) Monochrome: Yes MIP 1 of 3 (2 x 1): Stats Min: 1.000000 1.000000 1.000000 (float) Stats Max: 1.000000 1.000000 1.000000 (float) Stats Avg: 1.000000 1.000000 1.000000 (float) Stats StdDev: 0.000000 0.000000 0.000000 (float) Stats NanCount: 0 0 0 Stats InfCount: 0 0 0 Stats FiniteCount: 2 2 2 Constant: Yes Constant Color: 1.000000 1.000000 1.000000 (float) Monochrome: Yes MIP 2 of 3 (1 x 1): Stats Min: 1.000000 1.000000 1.000000 (float) Stats Max: 1.000000 1.000000 1.000000 (float) Stats Avg: 1.000000 1.000000 1.000000 (float) Stats StdDev: 0.000000 0.000000 0.000000 (float) Stats NanCount: 0 0 0 Stats InfCount: 0 0 0 Stats FiniteCount: 1 1 1 Constant: Yes Constant Color: 1.000000 1.000000 1.000000 (float) Monochrome: Yes openimageio-1.3.12~dfsg0.orig/testsuite/maketx/run.py0000644000175000017500000001206012271062644021020 0ustar mfvmfv#!/usr/bin/python # location of oiio-images directory oiio_images = parent + "/oiio-images/" # Just for simplicity, make a checkerboard with a solid alpha command += (oiio_app("oiiotool") + " --pattern checker 128x128 4 --ch R,G,B,=1.0" + " -d uint8 -o " + oiio_relpath("checker.tif") + " >> out.txt;\n") # Basic test - recreate the grid texture command += maketx_command (oiio_images + "grid.tif", "grid.tx", showinfo=True) # Test --resize (to power of 2) with the grid, which is 1000x1000 command += maketx_command (oiio_images + "grid.tif", "grid-resize.tx", "--resize", showinfo=True) # Test -d to set output data type command += maketx_command ("checker.tif", "checker-uint16.tx", "-d uint16", showinfo=True) # Test --nchannels to restrict the number of channels command += maketx_command ("checker.tif", "checker-1chan.tx", "--nchannels 1", showinfo=True) # Test --tiles to set a non-default tile size command += maketx_command ("checker.tif", "checker-16x32tile.tx", "--tile 16 32", showinfo=True) # Test --separate and --compression command += maketx_command ("checker.tif", "checker-seplzw.tx", "--separate --compression lzw", showinfo=True) # Test --wrap command += maketx_command ("checker.tif", "checker-clamp.tx", "--wrap clamp", showinfo=True) # Test --swrap and --twrap command += maketx_command ("checker.tif", "checker-permir.tx", "--swrap periodic --twrap mirror", showinfo=True) # Test --nomipmap command += maketx_command ("checker.tif", "checker-nomip.tx", "--nomipmap", showinfo=True) # Test --Mcamera, --Mscreen command += maketx_command ("checker.tif", "checker-camera.tx", "--Mcamera 1 0 0 0 0 2 0 0 0 0 1 0 0 0 0 1 --Mscreen 3 0 0 0 0 3 0 0 0 0 3 0 1 2 3 1", showinfo=True) # Test --opaque-detect (should drop the alpha channel) command += maketx_command ("checker.tif", "checker-opaque.tx", "--opaque-detect", showinfo=True) # Test --monochrome-detect (first create a monochrome image) command += (oiio_app("oiiotool") + " --pattern constant:color=.25,.25,.25 256x256 3 " + " -d uint8 -o " + oiio_relpath("gray.tif") + " >> out.txt;\n") command += maketx_command ("gray.tif", "gray-mono.tx", "--monochrome-detect", showinfo=True) # Test --monochrome-detect on something that is NOT monochrome command += (oiio_app("oiiotool") + " --pattern constant:color=.25,.2,.15 256x256 3 " + " -d uint8 -o " + oiio_relpath("pink.tif") + " >> out.txt;\n") command += maketx_command ("pink.tif", "pink-mono.tx", "--monochrome-detect", showinfo=True) # Test --prman : should save 'separate' planarconfig, and funny 64x32 tiles # since we are specifying 16 bits, and it should save as 'int16' even though # we asked for unsigned. command += maketx_command ("checker.tif", "checker-prman.tx", "-d uint16 --prman", showinfo=True) # Test --fixnan : take advantage of the bad.exr images in # testsuite/oiiotool-fixnan. (Use --nomipmap to cut down on stats output) # FIXME: would also like to test --checknan, but the problem with that is # that is actually FAILS if there's a nan. command += maketx_command ("../oiiotool-fixnan/bad.exr", "nan.exr", "--fixnan box3 --nomipmap", showinfo=True, showinfo_extra="--stats") # Test --format to force exr even though it can't be deduced from the name. command += maketx_command ("checker.tif", "checker-exr.pdq", "--format exr", showinfo=True) # Test that we cleanly replace any existing SHA-1 hash and ConstantColor # hint in the ImageDescription of the input file. command += (oiio_app("oiiotool") + " --pattern constant:color=1,0,0 64x64 3 " + " --caption \"foo SHA-1=1234abcd ConstantColor=[0.0,0,-0.0] bar\"" + " -d uint8 -o " + oiio_relpath("small.tif") + " >> out.txt;\n") command += info_command ("small.tif", safematch=1); command += maketx_command ("small.tif", "small.tx", "--oiio --constant-color-detect", showinfo=True) # Regression test -- at one point, we had a bug where we were botching # the poles of OpenEXR env maps, adding energy. Check it by creating an # all-white image, turning it into an env map, and calculating its # statistics (should be 1.0 everywhere). command += (oiio_app("oiiotool") + " --pattern constant:color=1,1,1 4x2 3 " + " -d half -o " + oiio_relpath("white.exr") + " >> out.txt;\n") command += maketx_command ("white.exr", "whiteenv.exr", "--envlatl") command += (oiio_app("oiiotool") + "--stats whiteenv.exr" + " >> out.txt;\n") outputs = [ "out.txt" ] # To do: --filter --checknan --fullpixels # --prman-metadata --ignore-unassoc # --mipimage # --envlatl TIFF, --envlatl EXR # --colorconvert --unpremult -u --fovcot openimageio-1.3.12~dfsg0.orig/testsuite/texture-res/0000755000175000017500000000000012271062644020641 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-res/ref/0000755000175000017500000000000012271062644021415 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-res/ref/out.tif0000644000175000017500000004663712271062644022750 0ustar mfvmfvII*ÎÖ ö2&RS: B{´í¯'ô7-?fF999ÂE9992012:06:19 17:05:18€ P4þƒAÀXT.†B¢1|"‹D¢°(Är7‹Çã²Ô†M%”E$ò©LfY/—LcÒ¹”’a3–Î&ói¬Ž}" M'SÚ æyC¤QéSú.‹;¦Qª5 }›S«Tª´šÅr·N«×ë¶ Õ†Íe´U,ö«MfÙo·\kÖ»•’ás¶Þ.÷k­ŽýbÀ]/WÜ æùƒÄañWü/ {Æa²9 ~“Ëd²¸œÆs7ŽËçóº Ö‡M¥Ôe4ú­NgY¯×lsÚ½–“a³Öî6ûm®}¢àm7[ÞçyÃäqù[þ/‹»æqº=›Óëtº¼žÇs·Îë÷û¾ׇÍåôu<þ¯OgÙï÷|{Þ¿—“áóöþ>ÿo¯üñ@£ôþÀ/ËùÁ<ÿÀP\ ýÁ4#Að$ ÂД+Ãä7Bðü;CQ MŤOE0ÌYÅÑŒ=ÆQ$aűÄoF±}H¤uÈ1Ìy!É<•ÈR\‹É’4£(Iò$›)ÊÒ”«$Ëä·'Jòü»0KS Í2ͤÏ5M2ÌÙ7ÍÓŒ½5ÎS$á9ͳÄï;N³ý1P¤õ>Ð3ÌùAÑ=?ÐT] =Ñ”5#HQô%IÒÔ•+DÓå7GRôý;PSU MRÕ¥OUU4ÍYWÕÕ=UÖU%aYÕµÅo[Vµ}QX¥u^Ø5ÍyaÙ=•_ØV]‹]Ù–5£hYö%›iÚÖ•«dÛå·gZöý»p[W ÍrÝ¥Ïu]6ÍÙwÝ×½uÞW%áyÝ·Åï{^·ýq`¥õ~à7Íùá>àX^ }á˜6#ˆaø&‰âØ–+„ãæ7‡bøþ;cYM’å¦O•e8ÎY—åÙŽ=•æY&a™å¹Æo›f¹}‘h¦užè9Îy¡é>•ŸèZ^‹éš6£¨iú&›©êÚ–«¤ëæ·§júþ»°k[Ͳí¦Ïµm:ÎÙ·íÛŽ½µî[&á¹í»Æï»n»ý±p¦õ¾ð;ÎùÁñ?¿ð\_ ½ñœ7#Èqü'ÉòÜ—+Äóç7Çrüÿ;Ðs]MÒõ§OÕu<ÏY×õÝ=Õö]'aÙõ½ÇoÛv½}Ñx§uÞø=Ïyáù?•ßø^_‹Ýùž7£èyþ'›éúÞ—«äûç·çzþÿ»ð{_Íòý§Ïõ}>ÏÙ÷ýß½õþ_'áùý¿Çïû~¿üø ôOö¿—ùàDOþ@¸ þàd‚0BÀHà´‚°& AÈ7 ¼ƒ°‚ BM aD„ðªÁ˜Y át1ƒÐ®BHa ál8†ðÚÂ8}¢4‡Pö ØyâDG‰Pþ!D¸‹âdFŠ1B'ÄH›â´Rб&,EÈ·¢¼_‹±‚-FÍcDTŒñª4ŘÙãtq‹Ñ®9FHáãlxŽñÚ:Æ8ý¤tQö@ǘù äD‡‘QþAH¹ äd†’2BGÈI$ä´’’²&LIÉ7#¤¼Ÿ“²‚MJM)eD””òªTÉ™Y+åt±“Ò®YJIa,ål¸–òÚZÊ9}(¦´—Rö`Ë™y0æDÇ™RþaL¹‹.ædÆš3BgÌI›4æ´Òš³&lMÉ·3¦¼ß›³‚mNÍ9gDÔœóªtÍ™Ù;çtñ›Ó®yNIá<çløžóÚzÎ9ý8¨ôŸSö€Ï™ù@èE¡SþPº >èe¢4B‡ÐJDèµ¢´&ŒQÊ7C¨½£´‚RMIiE¤ôª”ÑšYKéu1£Ô®™RJaLém8¦ôÚšÒ:}Hª4§Tö ÓšyPêEG©Tþ¡Tº‹NêeFª5B§ÔJ›TêµRªµ&¬UÊ·Sª½_«µ‚­VÍYkET¬õª´ÕšÙ[ëuq«Õ®¹VJá\ëmx®õÚºÖ:ýX¬t¯UöÀךù`ìE‡±UþÁX» ^ìe†²6BÇØKdìµ’²¶&ÌYË7c¬½Ÿ³¶‚ÍZMimE”´öªÔÙ›Ykíu±³Ö®ÙZKalím¸¶öÚÚÚ;}h®´·VöàÛ›ypîEǹVþá\»‹nîeƺ7BçÜK›tîµÒº·&ì]Ë·s®½ß»·‚í^ÍyoEÔ¼÷ªôÝ›Ù{ïuñ»×®ù^Ká|ïmø¾÷ÚúÞ;ýx°ô¿W÷ß›ù€ðFÁWÿ`¼ ~ðfÂ8CàL„ð¶¸' aÌ7ƒ°¾øƒ bM‰qFÄø«áœY‹ñv1ÃØ¯bLaŒñn8ÆøÛâ<}ˆ²4ÇX÷ ãœyòFGÉXÿ!d¼‹ŽòfFÊ9C'äL›”ò¶Rʹ',eÌ·“²¾_˹ƒ-fÍ™sFTÌù«4åœÙ›óvqËÙ¯9fLáœónxÎùÛ:æ<ý˜´tÏY÷@çœù ôF‡ÑYÿAh½ žôf†Ò:CGèM¤ô¶’Ò¨x€€€ P4þƒAÀXT.†B¢1|"‹D¢°(Är7‹Çã²Ô†M%”E$ò©LfY/—LcÒ¹”’a3–Î&ói¬Ž}" M'SÚ æyC¤QéSú.‹;¦Qª5 }›S«Tª´šÅr·N«×ë¶ Õ†Íe´U,ö«MfÙo·\kÖ»•’ás¶Þ.÷k­ŽýbÀ]/WÜ æùƒÄañWü/ {Æa²9 ~“Ëd²¸œÆs7ŽËçóº Ö‡M¥Ôe4ú­NgY¯×lsÚ½–“a³Öî6ûm®}¢àm7[ÞçyÃäqù[þ/‹»æqº=›Óëtº¼žÇs·Îë÷û¾ׇÍåôu<þ¯OgÙï÷|{Þ¿—“áóöþ>ÿo¯üñ@£ôþÀ/ËùÁ<ÿÀP\ ýÁ4#Að$ ÂД+Ãä7Bðü;CQ MŤOE0ÌYÅÑŒ=ÆQ$aűÄoF±}H¤uÈ1Ìy!É<•ÈR\‹É’4£(Iò$›)ÊÒ”«$Ëä·'Jòü»0KS Í2ͤÏ5M2ÌÙ7ÍÓŒ½5ÎS$á9ͳÄï;N³ý1P¤õ>Ð3ÌùAÑ=?ÐT] =Ñ”5#HQô%IÒÔ•+DÓå7GRôý;PSU MRÕ¥OUU4ÍYWÕÕ=UÖU%aYÕµÅo[Vµ}QX¥u^Ø5ÍyaÙ=•_ØV]‹]Ù–5£hYö%›iÚÖ•«dÛå·gZöý»p[W ÍrÝ¥Ïu]6ÍÙwÝ×½uÞW%áyÝ·Åï{^·ýq`¥õ~à7Íùá>àX^ }á˜6#ˆaø&‰âØ–+„ãæ7‡bøþ;cYM’å¦O•e8ÎY—åÙŽ=•æY&a™å¹Æo›f¹}‘h¦užè9Îy¡é>•ŸèZ^‹éš6£¨iú&›©êÚ–«¤ëæ·§júþ»°k[Ͳí¦Ïµm:ÎÙ·íÛŽ½µî[&á¹í»Æï»n»ý±p¦õ¾ð;ÎùÁñ?¿ð\_ ½ñœ7#Èqü'ÉòÜ—+Äóç7Çrüÿ;Ðs]MÒõ§OÕu<ÏY×õÝ=Õö]'aÙõ½ÇoÛv½}Ñx§uÞø=Ïyáù?•ßø^_‹Ýùž7£èyþ'›éúÞ—«äûç·çzþÿ»ð{_Íòý§Ïõ}>ÏÙ÷ýß½õþ_'áùý¿Çïû~¿üø ôOö¿—ùàDOþ@¸ þàd‚0BÀHà´‚°& AÈ7 ¼ƒ°‚ BM aD„ðªÁ˜Y át1ƒÐ®BHa ál8†ðÚÂ8}¢4‡Pö ØyâDG‰Pþ!D¸‹âdFŠ1B'ÄH›â´Rб&,EÈ·¢¼_‹±‚-FÍcDTŒñª4ŘÙãtq‹Ñ®9FHáãlxŽñÚ:Æ8ý¤tQö@ǘù äD‡‘QþAH¹ äd†’2BGÈI$ä´’’²&LIÉ7#¤¼Ÿ“²‚MJM)eD””òªTÉ™Y+åt±“Ò®YJIa,ål¸–òÚZÊ9}(¦´—Rö`Ë™y0æDÇ™RþaL¹‹.ædÆš3BgÌI›4æ´Òš³&lMÉ·3¦¼ß›³‚mNÍ9gDÔœóªtÍ™Ù;çtñ›Ó®yNIá<çløžóÚzÎ9ý8¨ôŸSö€Ï™ù@èE¡SþPº >èe¢4B‡ÐJDèµ¢´&ŒQÊ7C¨½£´‚RMIiE¤ôª”ÑšYKéu1£Ô®™RJaLém8¦ôÚšÒ:}Hª4§Tö ÓšyPêEG©Tþ¡Tº‹NêeFª5B§ÔJ›TêµRªµ&¬UÊ·Sª½_«µ‚­VÍYkET¬õª´ÕšÙ[ëuq«Õ®¹VJá\ëmx®õÚºÖ:ýX¬t¯UöÀךù`ìE‡±UþÁX» ^ìe†²6BÇØKdìµ’²¶&ÌYË7c¬½Ÿ³¶‚ÍZMimE”´öªÔÙ›Ykíu±³Ö®ÙZKalím¸¶öÚÚÚ;}h®´·VöàÛ›ypîEǹVþá\»‹nîeƺ7BçÜK›tîµÒº·&ì]Ë·s®½ß»·‚í^ÍyoEÔ¼÷ªôÝ›Ù{ïuñ»×®ù^Ká|ïmø¾÷ÚúÞ;ýx°ô¿W÷ß›ù€ðFÁWÿ`¼ ~ðfÂ8CàL„ð¶¸' aÌ7ƒ°¾øƒ bM‰qFÄø«áœY‹ñv1ÃØ¯bLaŒñn8ÆøÛâ<}ˆ²4ÇX÷ ãœyòFGÉXÿ!d¼‹ŽòfFÊ9C'äL›”ò¶Rʹ',eÌ·“²¾_˹ƒ-fÍ™sFTÌù«4åœÙ›óvqËÙ¯9fLáœónxÎùÛ:æ<ý˜´tÏY÷@çœù ôF‡ÑYÿAh½ žôf†Ò:CGèM¤ô¶’Ò¨x€€€ P4þƒAÀXT.†B¢1|"‹D¢°(Är7‹Çã²Ô†M%”E$ò©LfY/—LcÒ¹”’a3–Î&ói¬Ž}" M'SÚ æyC¤QéSú.‹;¦Qª5 }›S«Tª´šÅr·N«×ë¶ Õ†Íe´U,ö«MfÙo·\kÖ»•’ás¶Þ.÷k­ŽýbÀ]/WÜ æùƒÄañWü/ {Æa²9 ~“Ëd²¸œÆs7ŽËçóº Ö‡M¥Ôe4ú­NgY¯×lsÚ½–“a³Öî6ûm®}¢àm7[ÞçyÃäqù[þ/‹»æqº=›Óëtº¼žÇs·Îë÷û¾ׇÍåôu<þ¯OgÙï÷|{Þ¿—“áóöþ>ÿo¯üñ@£ôþÀ/ËùÁ<ÿÀP\ ýÁ4#Að$ ÂД+Ãä7Bðü;CQ MŤOE0ÌYÅÑŒ=ÆQ$aűÄoF±}H¤uÈ1Ìy!É<•ÈR\‹É’4£(Iò$›)ÊÒ”«$Ëä·'Jòü»0KS Í2ͤÏ5M2ÌÙ7ÍÓŒ½5ÎS$á9ͳÄï;N³ý1P¤õ>Ð3ÌùAÑ=?ÐT] =Ñ”5#HQô%IÒÔ•+DÓå7GRôý;PSU MRÕ¥OUU4ÍYWÕÕ=UÖU%aYÕµÅo[Vµ}QX¥u^Ø5ÍyaÙ=•_ØV]‹]Ù–5£hYö%›iÚÖ•«dÛå·gZöý»p[W ÍrÝ¥Ïu]6ÍÙwÝ×½uÞW%áyÝ·Åï{^·ýq`¥õ~à7Íùá>àX^ }á˜6#ˆaø&‰âØ–+„ãæ7‡bøþ;cYM’å¦O•e8ÎY—åÙŽ=•æY&a™å¹Æo›f¹}‘h¦užè9Îy¡é>•ŸèZ^‹éš6£¨iú&›©êÚ–«¤ëæ·§júþ»°k[Ͳí¦Ïµm:ÎÙ·íÛŽ½µî[&á¹í»Æï»n»ý±p¦õ¾ð;ÎùÁñ?¿ð\_ ½ñœ7#Èqü'ÉòÜ—+Äóç7Çrüÿ;Ðs]MÒõ§OÕu<ÏY×õÝ=Õö]'aÙõ½ÇoÛv½}Ñx§uÞø=Ïyáù?•ßø^_‹Ýùž7£èyþ'›éúÞ—«äûç·çzþÿ»ð{_Íòý§Ïõ}>ÏÙ÷ýß½õþ_'áùý¿Çïû~¿üø ôOö¿—ùàDOþ@¸ þàd‚0BÀHà´‚°& AÈ7 ¼ƒ°‚ BM aD„ðªÁ˜Y át1ƒÐ®BHa ál8†ðÚÂ8}¢4‡Pö ØyâDG‰Pþ!D¸‹âdFŠ1B'ÄH›â´Rб&,EÈ·¢¼_‹±‚-FÍcDTŒñª4ŘÙãtq‹Ñ®9FHáãlxŽñÚ:Æ8ý¤tQö@ǘù äD‡‘QþAH¹ äd†’2BGÈI$ä´’’²&LIÉ7#¤¼Ÿ“²‚MJM)eD””òªTÉ™Y+åt±“Ò®YJIa,ål¸–òÚZÊ9}(¦´—Rö`Ë™y0æDÇ™RþaL¹‹.ædÆš3BgÌI›4æ´Òš³&lMÉ·3¦¼ß›³‚mNÍ9gDÔœóªtÍ™Ù;çtñ›Ó®yNIá<çløžóÚzÎ9ý8¨ôŸSö€Ï™ù@èE¡SþPº >èe¢4B‡ÐJDèµ¢´&ŒQÊ7C¨½£´‚RMIiE¤ôª”ÑšYKéu1£Ô®™RJaLém8¦ôÚšÒ:}Hª4§Tö ÓšyPêEG©Tþ¡Tº‹NêeFª5B§ÔJ›TêµRªµ&¬UÊ·Sª½_«µ‚­VÍYkET¬õª´ÕšÙ[ëuq«Õ®¹VJá\ëmx®õÚºÖ:ýX¬t¯UöÀךù`ìE‡±UþÁX» ^ìe†²6BÇØKdìµ’²¶&ÌYË7c¬½Ÿ³¶‚ÍZMimE”´öªÔÙ›Ykíu±³Ö®ÙZKalím¸¶öÚÚÚ;}h®´·VöàÛ›ypîEǹVþá\»‹nîeƺ7BçÜK›tîµÒº·&ì]Ë·s®½ß»·‚í^ÍyoEÔ¼÷ªôÝ›Ù{ïuñ»×®ù^Ká|ïmø¾÷ÚúÞ;ýx°ô¿W÷ß›ù€ðFÁWÿ`¼ ~ðfÂ8CàL„ð¶¸' aÌ7ƒ°¾øƒ bM‰qFÄø«áœY‹ñv1ÃØ¯bLaŒñn8ÆøÛâ<}ˆ²4ÇX÷ ãœyòFGÉXÿ!d¼‹ŽòfFÊ9C'äL›”ò¶Rʹ',eÌ·“²¾_˹ƒ-fÍ™sFTÌù«4åœÙ›óvqËÙ¯9fLáœónxÎùÛ:æ<ý˜´tÏY÷@çœù ôF‡ÑYÿAh½ žôf†Ò:CGèM¤ô¶’Ò¨x€€€ P4þƒAÀXT.†B¢1|"‹D¢°(Är7‹Çã²Ô†M%”E$ò©LfY/—LcÒ¹”’a3–Î&ói¬Ž}" M'SÚ æyC¤QéSú.‹;¦Qª5 }›S«Tª´šÅr·N«×ë¶ Õ†Íe´U,ö«MfÙo·\kÖ»•’ás¶Þ.÷k­ŽýbÀ]/WÜ æùƒÄañWü/ {Æa²9 ~“Ëd²¸œÆs7ŽËçóº Ö‡M¥Ôe4ú­NgY¯×lsÚ½–“a³Öî6ûm®}¢àm7[ÞçyÃäqù[þ/‹»æqº=›Óëtº¼žÇs·Îë÷û¾ׇÍåôu<þ¯OgÙï÷|{Þ¿—“áóöþ>ÿo¯üñ@£ôþÀ/ËùÁ<ÿÀP\ ýÁ4#Að$ ÂД+Ãä7Bðü;CQ MŤOE0ÌYÅÑŒ=ÆQ$aűÄoF±}H¤uÈ1Ìy!É<•ÈR\‹É’4£(Iò$›)ÊÒ”«$Ëä·'Jòü»0KS Í2ͤÏ5M2ÌÙ7ÍÓŒ½5ÎS$á9ͳÄï;N³ý1P¤õ>Ð3ÌùAÑ=?ÐT] =Ñ”5#HQô%IÒÔ•+DÓå7GRôý;PSU MRÕ¥OUU4ÍYWÕÕ=UÖU%aYÕµÅo[Vµ}QX¥u^Ø5ÍyaÙ=•_ØV]‹]Ù–5£hYö%›iÚÖ•«dÛå·gZöý»p[W ÍrÝ¥Ïu]6ÍÙwÝ×½uÞW%áyÝ·Åï{^·ýq`¥õ~à7Íùá>àX^ }á˜6#ˆaø&‰âØ–+„ãæ7‡bøþ;cYM’å¦O•e8ÎY—åÙŽ=•æY&a™å¹Æo›f¹}‘h¦užè9Îy¡é>•ŸèZ^‹éš6£¨iú&›©êÚ–«¤ëæ·§júþ»°k[Ͳí¦Ïµm:ÎÙ·íÛŽ½µîX9À7+ff­.òYÊ€"p)ÉÀtªÀ(q)É@Š@Pq©¹@ p©¹À0s)‘€gsªA@«g¹±u¦ç¶õ{‡[ºì}SÖlwkØv}·eÕvý}Þøßiáw]ÏqÞxž?‡ãwþO›æx>‡èù øÿ¼ˆ])ÙШæ™î#¤ȨÈj“ó)_BGõ#ÿgЦýßzwøþ_?Íõþÿoò…GÀFÅ)+áñé@WªÃ_£õÁý¿Wí ƒå°:Á("üàœ P\šÀ—å`ÄðYÃÇÿÞ\(x¬48·`éGt' îN7½ H à—*L…$‡ƒ€,CÁ@)¢ÛrN‘Ň­¡LQ…qIåE8­bÃÏ…QeêEHµ¢ìW‹ñŠ0Åǧ⃮=ÒŽ†6!ü#„0’9ÇX;`üŽ‘Þ>˜ðûá|qÊAGgDæH1šE¤˜= #Ô†Ñö@ÈI-$䘒RVMHY=%ää¡’2~NÊ68!4[Œr2U q€ JØ ð`É&å¦Òê]Ê)w)f¾—¤l@ˆâQÅ®ˆÀˆ¯‡‰e\ÑšN4JÙ«&¼d›2²lLù·4¦üÔ›ÓŽkNIº`…ž‡’B_Ì().f ðÐjvÏ)í=gÄß3¾}ÏIõ?çár ñDùËAã¡Qþ…ÉIï@'õ¢TFŠG™ûE¨…¢tjŠÎÊ3Gˆ¨s†’Nen0$SŠs”:‹Ò ;CdÌó£”ΗSJa.)m7&C€)Òi¹6©ñøƒÂ!P¸T‡B`ñ¤N ŒEàQ˜änˆGã²ÔŠO”He2É\ºM-˜KãÒ©”Úi1œL䳩¼ò$ ÈèsYíDœÒ(´ºU ™O§Rgu¥N}U¬Uèõšån›V¨Wë¶ ÕŠÏR´Xm6Ë]ºÍm¸[ëÖ«•Úéq¼\ì·«½òÿdÀØðw[â0¸¼V Çboy¦Ný•Ìeðùœæo–Ègóªðú™ £êgú¹&¶?¯Õê5:í¦Ãm²¥l`îöŠÀ\oç*‡w»Üê·®^ÏŸºæsv¼VŸ%¢ìö;zækµÝðß¹<®§G¡Èéyvþ‰÷“sæôûyÞ¯Ëíîõ|=Ÿ¤Ìàw‰žx÷zÚ‚ ˆ1d•óöMÌ<|ÚÇé²|_˜f¡çö‡ßÇÞ'ˆ¢ˆ†+OM£Œ X: #8Ú ŽØæ1‚c¨ú<ƒäÖ;Œ¤HöBãùJ‘ä¹"FdéJM•%VC“%ijX“å™rS–ä™vc˜%ù^b™f‰žP™¦²j›¥éÂm'9Úož')ædšÕÖ–‹"’# ¨Tl *xTº €VÎE_§È0tVÌæ‘7(ÔtÀ (ª&ŠjZÍ©Ñ@–g¹¦®ŸjÆï‡*J¥Ó­¢ÓB¢‹MŠñ8+åÁ¯Ñ»ð“›ʲ_û57²ìë ´m =Fµm‹^½´ÛËnÀ·èrŠž¬« Æåž®›¢ëS…l ).J¢ƒŠ¯Jšö­Þ»Î†¾ë›ò¨¿ë‹÷À/ìÔ‹êû« »+3ñŸÄñ*· ŧ|cÇ1|7Ʊü{Èñ››%È2|‡$Êòlo(Ì2ܧ/̳«7Í3Œ‹5Ï3¬³>˳¼ª‰pL 0 a90 KËH¦ÔÁ÷BÎu\î¦K-?G×/¬Fב‚KLÌ?TÚ3ý[jgëMºÛôVðoÚt³wÝ·œÏuÞ÷÷zO‡µl€#µ½‡‡~ö'_Ò!u€#8d ¦D:DfWÇu||¤FÊD\¦Cn »ï0q·uÞ/ª‹·ÌÛkà3ÞÃí:þ»²íô׸߻n÷¼ì{®ûÁìü>ïÂð<Éñ¼ß3Ïò=/Òî}?[Õö;ÿSÚòôJÆ:”ñ䎟Ùñ>*H 5q÷øª×Š ®KÛú}Ï©ãÜ?ÝÉÕ?6æþÞƒ×PüÀ‡×àRgùû¿êÀ\@€ìê¾PÃßÄ /npà21’|@ÖÀ·!T0² ÂØ; áL†ÚB¸k!Œ3…ÐêC˜ƒ!ü2ˆö"Ä(o"I‡q*$=Ñ\ùG#å ±>#ň‰àÀÐAÿ?xà ±^-ÄÈ™W¼un p7H¢\g‰±Ò9Å£ß|`‚L1% ´u2:©‚˜¥cÄYŽÑæFF‰$$tÒNKGy3#äÔ•’RrHÉy=&å”2šOÉIA*$Ĥ•Q!ÍJy[*eœ¬ QÁw‰Mc}„|¿yk+¥*kkæ7L‰w-£Œ«”SYL)i3¦Ø eP¿÷2¦CI„À-Í9¥,f|äš“ŠfÎ9Í4g\ᓦsÍ Û<§|îÚxÏIç=ç,ðŸ“Ö|O¹Õ>¨ŸÔƒO”Ò8T_›3&cÈ+0h=’tB6ͺ3&e¢´~Ñê;HBˆ¡±†^Q@(" 4R‘ÏúGé!¦TŠšS _N)Ý:§´&™ÓêOé½A¨•›TŠkR©ÍG©tò¦ÔÊ…Tª3±þ>Pê5/J1Á—U>©ÏÊ/éE'™u¤Õ©Z«DÂ.¬VZVÉø÷¢uB¯ÖºYëÕw¯u¦¶Wêñ`+턬òÃWû^lMŒ°V*ÁØ‹cl ”°¶.ÉY‹*oÅY¬OÊϤ#e¬ƒÇ´’?8©ohì}¬²v®× q@+)5¨ P ‰u"lš²ööÒ\ [fm}÷—ßÜ+‘l-õǹ·çÜË¡pn]Ó¸·FëÝ[•u®Í¯pVv¹Ñ‹LA­Ýع,þñW+¾°èåܺWš÷]KX8B™qÕÆ­U—És¯-ñ¿·n÷ßËÿ®Ö¿w·à[ူ^ Á`|#„0žÁøW`Ü$ôCp¶¶ž_?+½†0²:½âûѼ3…0f$ÅH4P;ˆ-¶'?ì'㌎pÖ,Çx¯cÜu±æ@ȸ·#ãì/ñþHÉy+"dÜ¡’rR¼£%c)q™{#e:Ç6±5èµY‡(äÌÏš‰Ø}¶™s1¡±ó—óFOÍ9;*gl«ž³Î|ιûMʹG'ã®Ü`ÝñgöÇ38–r¾kµõ^o½<ïŸêÎ}ÐPµ,(Ï×q‚ò¾ùÇLFBó,i´1@©L„M¥·ÏSèömŽÁÑbà°„œ—vëÊzojå½·œöþÙÇ;iî}ÛwïÚû¯xîSòÑ4À™Ö¶·A›b€?~—ß;ßRæž7žlÿ‡üë|ë¡„ˆH{÷ŒÙƒ#ÁõÏ%«rÂ2|Î Cz/×úï…õž¯Ñ8,p"ñLâ¾/·w¯qß}¿y÷}ÓßûŸ{ç}÷Áóžëáüò¾Ë€bu'å¼yÄ?æxO_å~Ï”ëßwÖû õôÝWDqàëè¡"=OÔü /©ÌpDºõßí}ïÇœ>ß¡¡Û¤°ÁuúòŸñ ò_bà2`" ó`6à:–¤‹¼qŸñê“0dS ‰þ¹þ_qþ ©ýಠ‰M%â`Ak€ ±ô œ§ÛpÓ ß¶ à¹ý¡øa [d0аÁz àZà>àFaBàV¡V!Z¡6abaNÅ퇹`ú!}•é!^áýȲa»›ŒÊdÙË E|E|ŠDùË  ¾`pÂ_î Ÿô²ƒy´áQ^R ! ¥1Ê> â M–Ää p0¤WÐS!ð°â}àNŒ¦bb%¡VØ(‘¸azâ¡f!²+âÊ-¢Ò,bæ-âÖ/bê#bî0IÞDÜ(>$ ¾"Dì=b2#9‰Gè0 J@h¤A¦. ôK¾5K!ýa7â@(¦6ä¨#z2!2œõn  )Ë(q#¹JVæ:#¨CR3bÎ0#ò3ã’>ãú/¢ò/äA$AãþBd 0¤ƒÄcÚDK(Ýä6 zB¨8­."R$a C•tSÊF‰…ùb"$†JKy7ZI‰Ô8$¾7dJ*Œ°Þ@äòC$"BãöOä^P$6O¤ÂPeQe"Q% OU((QôbV*a!K(¥&SeS ”ÔÔ¤%$~2d©B%dû$âMeRXÄmdäFãJYÐÑ[Ž Øåª J|-£ê\¥_e:R¦V¥-€ P4þƒAÀXT.†B¢1|"‹D¢°(Är7‹Çã²Ô†M%”E$ò©LfY/—LcÒ¹”’a3–Î&ói¬Ž}" M'SÚ æyC¤QéSú.‹;¦Qª5 }›S«Tª´šÅr·N«×ë¶ Õ†Íe´U,ö«MfÙo·\kÖ»•’ás¶Þ.÷k­ŽýbÀ]/WÜ æùƒÄ(5´yM†Òr4¬œ+Ëœí €NÂÞïø,>—G†Óè´8M&§Y¨Õâ4Ûž·i®Ùn6» ¶öt­¨ì†G-ÆÌr2|\òÃ;F>mú[íWS_Õƒ¸ú6g—;ïwò\¯Žšùâo=]g_ݹéúýô¯G3»äòñþÓ~×sø7¾/kàë@o” 7pCuÀ/œA0tÂP„B0¤5 ü ñ= Ã7D0´EÅQlKEñt?D‘œcÆÑÌkÄñ„uÆ’qE2…ȲDQ%ÇÒ$™ É2t›#džp­˜üš¼/ôû¿i“úÏÒœ£*M<Õ'ÈÓ\Í6IS|å(N”蘊¿.»òûÀüKÎK<Nslë4·ÀçÏó Í0RjrÆÑ“×BÎ3½5CS³R´}%QË”ú”=;DUsu7LÓ•|íXÖ•…mYÖõee]VµÅ}^W5u{`WöƒCØÖ-‘eÕ¶ewdØ–¡iÙÖ©fÛ}«cÛ6µ·e[¶åµpÜ €"¸!BÊTÎ\ýRÑÊ9€ KjA@Ü–•¿}_6½ÇÛ×í÷`8ïy½5%ExR8cøua7. ‰ÀG±uÝø^5v^8ÍäYb7æ ‰\X¥~`dí†ãxò:pY ’æ™&m‘dÙÆkfùž{è…‘çš.}£h:&¥é9Ι¡éÚnw§éZ–¨jz¶‘¬jú®¹­ëÛ ò` ìaŒexV9–mi¹@j@ëú¦£ºë[¶³¼o›÷¿&¯®Ù—m8w ¤9–óÅß2×Â弆ÛÃòw°/¾îüÁœ”¾Tòò=*£œçÍoZï3ÕïýgUÖöeÍö=§gÔöÝÏqÝñG{×w]ÿkÞs…Ûøþ‹äy~W}æ÷®à•GEÂzü—±Ð#¥!èy>'ŸñøËðý° Owlùw{_‹4hzß?Õ7Oî~_ç²ÿßñ5û¿gÈñŒ}®~Ÿ—ú@Ƹ~°"¼È*ó 4‚j AÈ1á„0~BXI ß4#…0š‡Óál1…ðz@XU ÕÈà Åm‹A5 t@‡ð4Žm !ÄHˆðº%ÃXaPÔ:nÄ8‚D qMñ6(/!Œþâ¼aŠÑSÄ 84\Q=|ŽËÛSÛŒQ”ˆ7µá¤]QâÇÈ•$yÑ2@Ç٠䇒&FHi"$t‘’NEÉ)+% 8à †0FÈü#4 ˆ‘Щ=%åDN‘ò¦=È©U%¥y5829Ê)jûßxvrÄ…€Xàå#”Ÿ— ´;˹[*Ú\Å–“ ÷LÙ–@¥Ô®˜òÂiɉ«+&4ÙšSjdMyy7æôᛓRqÍiË6&Ü雳žpNÇ’8IÁ’ž[LÉŸ=e! zE¹Õ9'üæ 3¢uÐ9Ú„&ŒT”3{¾ðë;šøÀýÐÊ9ñEßxy¢q@ñEÁŸ4Ž‹Ðú9Fè-) ªRÊ Jé…-¦4¾™SZiMè=.§4ÎÓj{N(í:¨(üpä°'¥ ¡TZ¥q@*' }¥ò¡Óê«P*Vkê*R*13ªYŸÕ æŽÇWb­$©³ŽÑVjÅ'(Q¢´PºÁkHÕŸ×Ú¯_«å°VÂW*Éaª¥…°ö.Ĩеc«Œ±öJȤ€çÅI®õ²»Lñ#§ z±V6ÊX !i­-ƒh‹žºÔË7E`δö¨ì±zké iFÑÙ;I)B…­–öâ‘Tø}emõɹ.Ô[û•sn}´¹×2é]{u.½Ð»ÎìÝ[·jWìÊ(ÁöÍ[{ÍXHqž”&éÝ«Ýw¯}ݾWpÁp§µè¤j*z_ ¯>ï-ú«óïÛðú½ÏœþÀnû´å»K¼í¾P Âp”+Âð„2ûCP$1 Ãðì8ýBÑÀ((ë€#¹¯E‘|AÐ\[Æ/€°‡È{ÇëCý!AüE"Ä=É<–Œ£k!ÀpE ÐóF’¼-FrÜo,FRô»,Ë“$Ã2Ìs4Ó4MsÙMÑÄã/Íólë:Nó”Å;O3<÷9Ï“Tý=Oý AÐ… >Д=@Ñ”]AR4uFÒô¥1GÒT…7JÒl<‡ =%E ÔµEFøUOåOV@ÕucRUð¤•$ÈÕ5gYUuÝ5KS6<¿²úpR¢½Y6¡^ÖÕ£^ZUm©hZvÅ«lÚöÕ†`#‹@QYŒ€×öƒt]uÙNÝÔäø;¯¤cõŸZ×MõI•Ͷ’À«˜¥È’áOÝ÷n#ˆbwŽŠ×Ø–/uc8¶;Œb˜ö7cøÕÓ“aÙ&C“ã™N[‘d¹F_•f9^G™eÙ®a–fùæs™çyöqšhz‰›h9îhúV¦hº†Ÿ©iz¢ y¬†¾”ÅŒmaHù@Ol^³²!±|ªäµ«Æ¾² ¯n›züPÍÊlè.ÅÀ §¿£:iº£ªñºžÇé/¶ýŒvpÄÃŽú’#]?ºnËöñ¬*’.pƕÌ7qœ§#ÈrzG{ÜwܯwÉx~‹Ü÷ÿ“àøþ'™ãx×ézG—êy¾¿Ÿåz>ϧíú¾ç¿ì|^×­ò{ß7Óðý_ÛñýŸ×ù}ß/çøþŸGíúÿïûó¿çàþß¼€Pü¿Çÿ` €2@õ ”. @Ø/àTƒ0N ÁX9àÄ"ƒPZAèM a *„¶ÂÈ_ á”.„°ÎÃHQ ¡¬8ƒ°öÃèaá¼CˆQÃÈb Gˆ‘2#Du¢”P‰.*DدâTQ‹1N-ÅX¹âÄb‹QZ2EèÍc jŒ¶1ÆÈßã”nŒ±Î8ÇHÑ£¬x‹±ö3Çèá㼃R<ÇÈÿ"d ‡’2CHõ#¤”‘.JHÙ/#äT‘“2NMÉY9'äÄ¢“RZRIéM*e ª”¶QÊÉ_*å”®”²ÎXËIQ-¥¬¸“²öSËéa.å¼Ã˜S\ËÉ2f ǘ“2cL u3¦”Й.jLÙ¯3æTÑ›3NmÍY¹7æÄâ›SZrMéÍ:g ꜶqÎÉß:ç”ÎxÏIÑ=§¬ø›³ösÏéá>ç½ T|ÏÉÿBh  ”2ƒP õC¨•¡.ŠPÚ/CèU£4NÑZ9GèÅ"£TZ’QêMJi *¤¶‘ÒÊ_Jé•.¤´Î˜ÓJQM©­8£´ö“ÓêaNé½C¨UœÓÊRj G¨•2£T uSª•P©.ªTÚ¯SêUQ«5N­ÕZ¹WêÅb«UZ²UêÍZk j¬¶±ÖÊßZë•n¬µÎ¸×JÑ]«­x«µö³×êá^뽃°V¼×Êÿbl ‡°–2ÃX õc¬•±.ÊXÛ/Fˆ€ P4þƒAÀXT.†B¢1|"‹D¢°(Är7‹Çã²Ô†M%”E$ò©LfY/—LcÒ¹”’a3–Î&ói¬Ž}" M'SÚ æyC¤QéSú.‹;¦Qª5 }›S«Tª´šÅr·N«×ë¶ Õ†Íe´U,ö«MfÙo·\kÖ»•’ás¶Þ.÷k­ŽýbÀ]/WÜ æùƒÄañWü/ {Æa²9 ~“Ëd²¸œÆs7ŽËçóº Ö‡M¥Ôe4ú­NgY¯×lsÚ½–“a³Öî6ûm®}¢àm7[ÞçyÃäqù[þ/‹»æqº=›Óëtº¼žÇs·Îë÷û¾ׇÍåôu<þ¯OgÙï÷|{Þ¿—“áóöþ>ÿo¯üñ@£ôþÀ/ËùÁ<ÿÀP\ ýÁ4#Að$ ÂД+Ãä7Bðü;CQ MŤOE0ÌYÅÑŒ=ÆQ$aűÄoF±}H¤uÈ1Ìy!É<•ÈR\‹É’4£(Iò$›)ÊÒ”«$Ëä·'Jòü»0KS Í2ͤÏ5M2ÌÙ7ÍÓŒ½5ÎS$á9ͳÄï;N³ý1P¤õ>Ð3ÌùAÑ=?ÐT] =Ñ”5#HQô%IÒÔ•+DÓå7GRôý;PSU MRÕ¥OUU4ÍYWÕÕ=UÖU%aYÕµÅo[Vµ}QX¥u^Ø5ÍyaÙ=•_ØV]‹]Ù–5£hYö%›iÚÖ•«dÛå·gZöý»p[W ÍrÝ¥Ïu]6ÍÙwÝ×½uÞW%áyÝ·Åï{^·ýq`¥õ~à7Íùá>àX^ }á˜6#ˆaø&‰âØ–+„ãæ7‡bøþ;cYM’å¦O•e8ÎY—åÙŽ=•æY&a™å¹Æo›f¹}‘h¦užè9Îy¡é>•ŸèZ^‹éš6£¨iú&›©êÚ–«¤ëæ·§júþ»°k[Ͳí¦Ïµm:ÎÙ·íÛŽ½µî[&á¹í»Æï»n»ý±p¦õ¾ð;ÎùÁñ?¿ð\_ ½ñœ7#Èqü'ÉòÜ—+Äóç7Çrüÿ;Ðs]MÒõ§OÕu<ÏY×õÝ=Õö]'aÙõ½ÇoÛv½}Ñx§uÞø=Ïyáù?•ßø^_‹Ýùž7£èyþ'›éúÞ—«äûç·çzþÿ»ð{_Íòý§Ïõ}>ÏÙ÷ýß½õþ_'áùý¿Çïû~¿üø ôOö¿—ùàDOþ@¸ þàd‚0BÀHà´‚°& AÈ7 ¼ƒ°‚ BM aD„ðªÁ˜Y át1ƒÐ®BHa ál8†ðÚÂ8}¢4‡Pö ØyâDG‰Pþ!D¸‹âdFŠ1B'ÄH›â´Rб&,EÈ·¢¼_‹±‚-FÍcDTŒñª4ŘÙãtq‹Ñ®9FHáãlxŽñÚ:Æ8ý¤tQö@ǘù äD‡‘QþAH¹ äd†’2BGÈI$ä´’’²&LIÉ7#¤¼Ÿ“²‚MJM)eD””òªTÉ™Y+åt±“Ò®YJIa,ål¸–òÚZÊ9}(¦´—Rö`Ë™y0æDÇ™RþaL¹‹.ædÆš3BgÌI›4æ´Òš³&lMÉ·3¦¼ß›³‚mNÍ9gDÔœóªtÍ™Ù;çtñ›Ó®yNIá<çløžóÚzÎ9ý8¨ôŸSö€Ï™ù@èE¡SþPº >èe¢4B‡ÐJDèµ¢´&ŒQÊ7C¨½£´‚RMIiE¤ôª”ÑšYKéu1£Ô®™RJaLém8¦ôÚšÒ:}Hª4§Tö ÓšyPêEG©Tþ¡Tº‹NêeFª5B§ÔJ›TêµRªµ&¬UÊ·Sª½_«µ‚­VÍYkET¬õª´ÕšÙ[ëuq«Õ®¹VJá\ëmx®õÚºÖ:ýX¬t¯UöÀךù`ìE‡±UþÁX» ^ìe†²6BÇØKdìµ’²¶&ÌYË7c¬½Ÿ³¶‚ÍZMimE”´öªÔÙ›Ykíu±³Ö®ÙZKalím¸¶öÚÚÚ;}h®´·VöàÛ›ypîEǹVþá\»‹nîeƺ7BçÜK›tîµÒº·&ì]Ë·s®½ß»·‚í^ÍyoEÔ¼÷ªôÝ›Ù{ïuñ»×®ù^Ká|ïmø¾÷ÚúÞ;ýx°ô¿W÷ß›ù€ðFÁWÿ`¼ ~ðfÂ8CàL„ð¶¸' aÌ7ƒ°¾øƒ bM‰qFÄø«áœY‹ñv1ÃØ¯bLaŒñn8ÆøÛâ<}ˆ²4ÇX÷ ãœyòFGÉXÿ!d¼‹ŽòfFÊ9C'äL›”ò¶Rʹ',eÌ·“²¾_˹ƒ-fÍ™sFTÌù«4åœÙ›óvqËÙ¯9fLáœónxÎùÛ:æ<ý˜´tÏY÷@çœù ôF‡ÑYÿAh½ žôf†Ò:CGèM¤ô¶’Ò¨x€€€ P4þƒAÀXT.†B¢1|"‹D¢°(Är7‹Çã²Ô†M%”E$ò©LfY/—LcÒ¹”’a3–Î&ói¬Ž}" M'SÚ æyC¤QéSú.‹;¦Qª5 }›S«Tª´šÅr·N«×ë¶ Õ†Íe´U,ö«MfÙo·\kÖ»•’ás¶Þ.÷k­ŽýbÀ]/WÜ æùƒÄañWü/ {Æa²9 ~“Ëd²¸œÆs7ŽËçóº Ö‡M¥Ôe4ú­NgY¯×lsÚ½–“a³Öî6ûm®}¢àm7[ÞçyÃäqù[þ/‹»æqº=›Óëtº¼žÇs·Îë÷û¾ׇÍåôu<þ¯OgÙï÷|{Þ¿—“áóöþ>ÿo¯üñ@£ôþÀ/ËùÁ<ÿÀP\ ýÁ4#Að$ ÂД+Ãä7Bðü;CQ MŤOE0ÌYÅÑŒ=ÆQ$aűÄoF±}H¤uÈ1Ìy!É<•ÈR\‹É’4£(Iò$›)ÊÒ”«$Ëä·'Jòü»0KS Í2ͤÏ5M2ÌÙ7ÍÓŒ½5ÎS$á9ͳÄï;N³ý1P¤õ>Ð3ÌùAÑ=?ÐT] =Ñ”5#HQô%IÒÔ•+DÓå7GRôý;PSU MRÕ¥OUU4ÍYWÕÕ=UÖU%aYÕµÅo[Vµ}QX¥u^Ø5ÍyaÙ=•_ØV]‹]Ù–5£hYö%›iÚÖ•«dÛå·gZöý»p[W ÍrÝ¥Ïu]6ÍÙwÝ×½uÞW%áyÝ·Åï{^·ýq`¥õ~à7Íùá>àX^ }á˜6#ˆaø&‰âØ–+„ãæ7‡bøþ;cYM’å¦O•e8ÎY—åÙŽ=•æY&a™å¹Æo›f¹}‘h¦užè9Îy¡é>•ŸèZ^‹éš6£¨iú&›©êÚ–«¤ëæ·§júþ»°k[Ͳí¦Ïµm:ÎÙ·íÛŽ½µî[&á¹í»Æï»n»ý±p¦õ¾ð;ÎùÁñ?¿ð\_ ½ñœ7#Èqü'ÉòÜ—+Äóç7Çrüÿ;Ðs]MÒõ§OÕu<ÏY×õÝ=Õö]'aÙõ½ÇoÛv½}Ñx§uÞø=Ïyáù?•ßø^_‹Ýùž7£èyþ'›éúÞ—«äûç·çzþÿ»ð{_Íòý§Ïõ}>ÏÙ÷ýß½õþ_'áùý¿Çïû~¿üø ôOö¿—ùàDOþ@¸ þàd‚0BÀHà´‚°& AÈ7 ¼ƒ°‚ BM aD„ðªÁ˜Y át1ƒÐ®BHa ál8†ðÚÂ8}¢4‡Pö ØyâDG‰Pþ!D¸‹âdFŠ1B'ÄH›â´Rб&,EÈ·¢¼_‹±‚-FÍcDTŒñª4ŘÙãtq‹Ñ®9FHáãlxŽñÚ:Æ8ý¤tQö@ǘù äD‡‘QþAH¹ äd†’2BGÈI$ä´’’²&LIÉ7#¤¼Ÿ“²‚MJM)eD””òªTÉ™Y+åt±“Ò®YJIa,ål¸–òÚZÊ9}(¦´—Rö`Ë™y0æDÇ™RþaL¹‹.ædÆš3BgÌI›4æ´Òš³&lMÉ·3¦¼ß›³‚mNÍ9gDÔœóªtÍ™Ù;çtñ›Ó®yNIá<çløžóÚzÎ9ý8¨ôŸSö€Ï™ù@èE¡SþPº >èe¢4B‡ÐJDèµ¢´&ŒQÊ7C¨½£´‚RMIiE¤ôª”ÑšYKéu1£Ô®™RJaLém8¦ôÚšÒ:}Hª4§Tö ÓšyPêEG©Tþ¡Tº‹NêeFª5B§ÔJ›TêµRªµ&¬UÊ·Sª½_«µ‚­VÍYkET¬õª´ÕšÙ[ëuq«Õ®¹VJá\ëmx®õÚºÖ:ýX¬t¯UöÀךù`ìE‡±UþÁX» ^ìe†²6BÇØKdìµ’²¶&ÌYË7c¬½Ÿ³¶‚ÍZMimE”´öªÔÙ›Ykíu±³Ö®ÙZKalím¸¶öÚÚÚ;}h®´·VöàÛ›ypîEǹVþá\»‹nîeƺ7BçÜK›tîµÒº·&ì]Ë·s®½ß»·‚í^ÍyoEÔ¼÷ªôÝ›Ù{ïuñ»×®ù^Ká|ïmø¾÷ÚúÞ;ýx°ô¿W÷ß›ù€ðFÁWÿ`¼ ~ðfÂ8CàL„ð¶¸' aÌ7ƒ°¾øƒ bM‰qFÄø«áœY‹ñv1ÃØ¯bLaŒñn8ÆøÛâ<}ˆ²4ÇX÷ ãœyòFGÉXÿ!d¼‹ŽòfFÊ9C'äL›”ò¶Rʹ',eÌ·“²¾_˹ƒ-fÍ™sFTÌù«4åœÙ›óvqËÙ¯9fLáœónxÎùÛ:æ<ý˜´tÏY÷@çœù ôF‡ÑYÿAh½ žôf†Ò:CGèM¤ô¶’Ò¨x€€€ P4þƒAÀXT.†B¢1|"‹D¢°(Är7‹Çã²Ô†M%”E$ò©LfY/—LcÒ¹”’a3–Î&ói¬Ž}" M'SÚ æyC¤QéSú.‹;¦Qª5 }›S«Tª´šÅr·N«×ë¶ Õ†Íe´U,ö«MfÙo·\kÖ»•’ás¶Þ.÷k­ŽýbÀ]/WÜ æùƒÄañWü/ {Æa²9 ~“Ëd²¸œÆs7ŽËçóº Ö‡M¥Ôe4ú­NgY¯×lsÚ½–“a³Öî6ûm®}¢àm7[ÞçyÃäqù[þ/‹»æqº=›Óëtº¼žÇs·Îë÷û¾ׇÍåôu<þ¯OgÙï÷|{Þ¿—“áóöþ>ÿo¯üñ@£ôþÀ/ËùÁ<ÿÀP\ ýÁ4#Að$ ÂД+Ãä7Bðü;CQ MŤOE0ÌYÅÑŒ=ÆQ$aűÄoF±}H¤uÈ1Ìy!É<•ÈR\‹É’4£(Iò$›)ÊÒ”«$Ëä·'Jòü»0KS Í2ͤÏ5M2ÌÙ7ÍÓŒ½5ÎS$á9ͳÄï;N³ý1P¤õ>Ð3ÌùAÑ=?ÐT] =Ñ”5#HQô%IÒÔ•+DÓå7GRôý;PSU MRÕ¥OUU4ÍYWÕÕ=UÖU%aYÕµÅo[Vµ}QX¥u^Ø5ÍyaÙ=•_ØV]‹]Ù–5£hYö%›iÚÖ•«dÛå·gZöý»p[W ÍrÝ¥Ïu]6ÍÙwÝ×½uÞW%áyÝ·Åï{^·ýq`¥õ~à7Íùá>àX^ }á˜6#ˆaø&‰âØ–+„ãæ7‡bøþ;cYM’å¦O•e8ÎY—åÙŽ=•æY&a™å¹Æo›f¹}‘h¦užè9Îy¡é>•ŸèZ^‹éš6£¨iú&›©êÚ–«¤ëæ·§júþ»°k[Ͳí¦Ïµm:ÎÙ·íÛŽ½µî[&á¹í»Æï»n»ý±p¦õ¾ð;ÎùÁñ?¿ð\_ ½ñœ7#Èqü'ÉòÜ—+Äóç7Çrüÿ;Ðs]MÒõ§OÕu<ÏY×õÝ=Õö]'aÙõ½ÇoÛv½}Ñx§uÞø=Ïyáù?•ßø^_‹Ýùž7£èyþ'›éúÞ—«äûç·çzþÿ»ð{_Íòý§Ïõ}>ÏÙ÷ýß½õþ_'áùý¿Çïû~¿üø ôOö¿—ùàDOþ@¸ þàd‚0BÀHà´‚°& AÈ7 ¼ƒ°‚ BM aD„ðªÁ˜Y át1ƒÐ®BHa ál8†ðÚÂ8}¢4‡Pö ØyâDG‰Pþ!D¸‹âdFŠ1B'ÄH›â´Rб&,EÈ·¢¼_‹±‚-FÍcDTŒñª4ŘÙãtq‹Ñ®9FHáãlxŽñÚ:Æ8ý¤tQö@ǘù äD‡‘QþAH¹ äd†’2BGÈI$ä´’’²&LIÉ7#¤¼Ÿ“²‚MJM)eD””òªTÉ™Y+åt±“Ò®YJIa,ål¸–òÚZÊ9}(¦´—Rö`Ë™y0æDÇ™RþaL¹‹.ædÆš3BgÌI›4æ´Òš³&lMÉ·3¦¼ß›³‚mNÍ9gDÔœóªtÍ™Ù;çtñ›Ó®yNIá<çløžóÚzÎ9ý8¨ôŸSö€Ï™ù@èE¡SþPº >èe¢4B‡ÐJDèµ¢´&ŒQÊ7C¨½£´‚RMIiE¤ôª”ÑšYKéu1£Ô®™RJaLém8¦ôÚšÒ:}Hª4§Tö ÓšyPêEG©Tþ¡Tº‹NêeFª5B§ÔJ›TêµRªµ&¬UÊ·Sª½_«µ‚­VÍYkET¬õª´ÕšÙ[ëuq«Õ®¹VJá\ëmx®õÚºÖ:ýX¬t¯UöÀךù`ìE‡±UþÁX» ^ìe†²6BÇØKdìµ’²¶&ÌYË7c¬½Ÿ³¶‚ÍZMimE”´öªÔÙ›Ykíu±³Ö®ÙZKalím¸¶öÚÚÚ;}h®´·VöàÛ›ypîEǹVþá\»‹nîeƺ7BçÜK›tîµÒº·&ì]Ë·s®½ß»·‚í^ÍyoEÔ¼÷ªôÝ›Ù{ïuñ»×®ù^Ká|ïmø¾÷ÚúÞ;ýx°ô¿W÷ß›ù€ðFÁWÿ`¼ ~ðfÂ8CàL„ð¶¸' aÌ7ƒ°¾øƒ bM‰qFÄø«áœY‹ñv1ÃØ¯bLaŒñn8ÆøÛâ<}ˆ²4ÇX÷ ãœyòFGÉXÿ!d¼‹ŽòfFÊ9C'äL›”ò¶Rʹ',eÌ·“²¾_˹ƒ-fÍ™sFTÌù«4åœÙ›óvqËÙ¯9fLáœónxÎùÛ:æ<ý˜´tÏY÷@çœù ôF‡ÑYÿAh½ žôf†Ò:CGèM¤ô¶’Ò¨x€€openimageio-1.3.12~dfsg0.orig/testsuite/texture-res/README0000644000175000017500000000071512271062644021524 0ustar mfvmfvThis test verifies that the texture system is choosing the right mip levels. It uses a special texture, miplevels.tx, that uses color codes for each mip level, and renders a 256x256 image where the texture coordinates are exactly aligned to the pixel grid. In miplevels, the 256x256 level is pure green, the 512x512 level is red, the 128x128 is blue. So of course we expect the output of this test to be pure green (except for the text "256" in the center). openimageio-1.3.12~dfsg0.orig/testsuite/texture-res/run.py0000755000175000017500000000040212271062644022016 0ustar mfvmfv#!/usr/bin/python command = (oiio_app("testtex") + " -res 256 256 --nowarp " + parent + "/oiio-images/miplevels.tx" + " -o out.tif ;\n") command += diff_command ("out.tif", "ref/out.tif", "--fail 0.0005 --warn 0.0005") outputs = [ ] openimageio-1.3.12~dfsg0.orig/testsuite/texture-pointsample/0000755000175000017500000000000012271062644022403 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-pointsample/ref/0000755000175000017500000000000012271062644023157 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-pointsample/ref/out.exr0000644000175000017500000247537412271062644024534 0ustar mfvmfvv/1capDatestring2012:06:19 16:59:39channelschlistIABGRcompressioncompressiondataWindowbox2iÿÿdisplayWindowbox2iÿÿlineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?q±5#o¤¯Ö÷wHÆ€öPj¨þbT£©g7XΰÅ 'eÁe!"‚}á(>Ę=ðÉC6•MåÉ5 ¬† Ž× \( 83xœí}XIÐ¶ŠŠ s:‚9#*¢¢( ¢ b€$³dØÝ™©™Ù]rQDÁ„YP@P0§N1b>TÌ FL_÷Ì‚z÷}ÿ'ž õðì3ìöÌtï»U]ouuMø'â)ùGík¥ªKÑãÕþìÀã.m²sGfÀåR€>}Æ.òÜ´ßDäí}ÞŸ¼ yÃP÷žÖÖúýpÆÑÔ Cßøƒ‹–ƒGbÀ’P0+î;dwàÝÁ2±ØBˆWUã•Þ=‰·’Î]|OàÜ?r_<|æ” zuöt‹Þõ'¯ Kå³±ø—îœõ^GÞ,2êÕN¥ŸíüÐ8ÚÃVwkëÞ.“ÔúO²¾?|[p».Z4DÊWžŒ¤(ýú£ÇÝì8¸‹ÁÒ³~j·öµÈR¿+]â•Ǽ̔ 7, áá7ù4ùîðG¿ÆÖ;¦nŒOŠ×ïzÉ“u¾†â¾*á)mßjG „w:µ¹]/Åhq£$µÍ“ †GSÁîR@ã—ĉ‹§´¸ºöµûØn¥Jž»{n²‰Ì9ëØ†YІë‡Ë?Æ?lEP§Ëæ;ûNiNzÁ;£Aïšé°‹sw àóÊRo^.l¿ØüݵíÆýî¾ÕǦ+”À'¯°Z?ø}8˜îôú™øïÚR¶ó”ú?‡ èg;bÓ[r–ò“†Í|œâ¾Á?¿Í:€ù7ŒhŒÿûº*7ŽÕÊÛ¤âZ:CS©ƒ('äCŸ‰5ÿÒ- ßXŸ–xßFã7Fïõmõ±c¶(Š÷5¥¾/Ñ\£{˜(÷©Õÿÿ¸8†HÝ… ­èTu±síçÏšX†‡[þ‡ä凎g<H¼®$Ì]ú¨p ôÉYuÒ0/ôÊÔË ¦d}³#'öqÚþa[ìiÑ­:áQO=»XŽJ;ì0ªî®vôü÷ƒ¬["Ì»3Ô1Ò-Ð: Áă^^gGåzBx·Dº ÓøóºŸz÷±÷¡´Ø—yÛ /®Ûü›OÿP»‹çŸ¸¥V|;ÊÖXD¼Ó _/u <8QºhÃ8QV`Ý Ëñívko<9à ž5ˆÓ7 /ÜfóÙF^tÝ`1t€Þô K#>Ù"´Ì°Ùi%~¡ô²KƒN3ÃÂÑ ¸¥,¨Ûg¥Ûr=Âh _´Ðµxíf¹¸tŠC²¹v©ÝË9Ö³nŒÞ|zšùÚÐZ\0MÁxýhùüõr-²ZÔ´¡s#€tÛÅI®tðdý+†(]Í ïÿÄâÑÍZÁ”ÔzçvÁÆ.ûüÆš¼‘OÐÏÆäÓ®Y·oñ-j7{»ê#¯ ò²>¼½£ýLô‰üÿÙç÷ËoؤÆßrñz‹A¥Œh¯µÝŠ8͉ xümNÖ4üÁ¨û®G¶?ÆÄ6ˉ×z”4àC+ÏÁ¡ã S¡XsÅ ½«ïÌ}99|“(§{r­þÿÇÅveí¤ZsÄx__á=€.3™WœŠ»ÊÀçáà<½I ›„$·ÿöû!õi ­tv,”-ÕÁ3¿ß•nR·®±‰ zQ&0?öîc$ch2£#@LÒÈŸ¾]¥"N™ù¬êYgáZØHsðx¬M‘*5ð…† <Ð_#;óÎx ùƒ¾ÒÝònnî8SDzæ°ß[Gœ3öWÑBòHòùvÃàØ<-Áñ7”­Ö†MMnõ¬ÈD#ÁŽÎ&cG%v}Z/¶ ¿qLbàÜe+‰ n§Ûôv»t4S¡Æ&< j ²hí3á׌ A ½3ÁÚ%¬Ù¦•éa –Ee÷ZÖ㯬È%xcý`¿'ë§{ŒJ;‹–zrþ¡Æ±Oï·n}R²høÝ:Æ "x¤(²*߃¿‘’ê¡©~¶­‡vÎï#7Œ>p^5”7ïY p÷ÈÔ°t¨ 5+P¨Fwf‹dp É…e`ÓJùção˜th†lïñzîíß-§sYõiè¼äà1H]¥É8}ƒÿjˆXý䮳DeÆ¿¯g@üÝó·:¹wú:­¥Vuê(_ôèj[Ãð_ºîºpÅ>‰l.™)ž ^hƒÑ§2ýá8ßÿ[üwStþs©8ü{ÜÈÈéßû…·‹rü¯qÝEo2â×5köRјýHiœ;Úw¬³ß€pÝÝæ—Û\ÑÜ ìUt†DêžËÞš3<Ø3wÀí1 ¨ˆÞŠ–•ê `ÓÂZýÿ‹¨è.ÔÊç¹'At´cS£Ñ žlè+\oyú¨f@“³ÁäY• Mipz^zUnÚZ‚]×$Nù u/4ÕÉ8ÔrBëÆ«ÊtÀÃ'™Ž¾[Ysƒ¾Å-ñsUd4­_kÙU5Óì7wC@»g»0(lÀÀD­,$,óô3Ø–aDíš—0õ™ì¸Þ6^c¬þºéùõP_’vg x>PÓ?`5ê–Î ‡A×][=3ÂzüÑöÁjªª$Gþ%âzñyÍÉÝBÎÑs÷·Œ,¾Q c0 î©¡  ˆÁówîI`PGGóŒ}’«ÿÓ=ÑËý” Ktl…ƒÄÆÞ ½FîÝQ·Ï r(ó‹mJµ¿ÛïèÚûDà‚nï=?—½Ê¿aÃÞn/›Q¨`cœ¢Qûqò½øw8?°Íø÷‹ZÜ>(rù* X¼ úí²mNÇo>L µyõ|mÔŒ>†ÿíH DUNEü~æ/;öNù‘}8–|Ë?œv«ÿÛMb¹ÁéoñOS†Áû÷ݨþ’añBÙ‚nèûeŽ?û#†ío&˜‡‹ 4ÚÇ%fÁ›§-}ø;ÀÔ†-sÆ °ÇP朗ê5¬}N‰ýT?<" ÔÅjõÿ?.ö¬¢»ðÿ_E÷ ê‹ÍL×wõ›jÁ¢֎͇A÷sÁ3¨¯¯B/ÖÙèr¥‡7òª¹#X>²l˜¼ÕIçÒcø¨ß/ôvÿeP÷Ԟɉ& j!xñÍy8®D7c—ÞëÌäé©6?1ä@ó2X²¸;€§“¦„šG0-žÁÌ×KçQÌ[ïõ?Lm‰ƒmZá6±Âý5ÁBç~tÙãuË ]FþÛg6‰7¼z¬úÕwÀ8³b­NfßÛÙ†wî­‰·‹Z}º£—¿×­~kMÛ”9BðMÖƒñ­žS¬t³©:«eÞ+NéÊ®-ÈžY¿g·° zwÂDçejEŽGèBç‡q›t@0ý0€·Ù Ù½ŽÌÛ§k4"¶€êsLãb2LSêã·;ÅÏŠm¾ö<ØŒl:ŠÎœR4n?J¾ÿ<>ª{Ãõ“—ÕÆßÑQBØîi`ÐÝШq³Þî¦Æ]\ÎŽS(þõô;ï³³\ íOø‡ø¯=Õöè;õ® `¨ŠÀ ¯õiSw}‹?í¸çbxÍ8üëŒÙÝ*¦­Œg öô;¸@íT$ì®Wcð‡A›²rm¦ÀDÑaÇ&é&·bæ ³Ày­ÊÐA²Í¿¶8;CmktìéN`˜Uvb? 8#;½X°´VÿÿÛBÙÕÆÖk‚ û Lohtsš<¼éX1öá Ÿé½¼êÀîšê°mˆ½jÑ਻¾«_/é,‚³a#¡¡û6ol¦¦5V‘€Ú¢Œ“@¦Z”$¿Ï9"ö_¦ÔöIÞ½DƒxˆŸtÑ`×Ä<0iûj3ضpé^'Ÿ³àñ—¡ôöïf'4¯)°Þ”|Âd¢ëô…÷¶,˜×L0&Ý›¶Ý´©nÀ ×Mlú?M›ÚÔ±QÆä¼•ÝS§1Ç5}¡wøoÆRnåuX¾OVç©ð µ9Ù¼ë¨ö½ü$ è{1h§ßÜ%aÐyý÷f²bçýãšo¹Ñà)øÉŠz¥…OÝ~N))Û|ö¹­CL‹µÅgu&¾lh©ÿˆ®Û°Ý¹U°,oš¯·Z‘ù2³~&´ŸS»émžÜžß>l½„m¦=VÑÀý ©þ-=NõT^Ó1þÕH\²= "ó›t“œ;«>ç†éÛInŸ¸¬`ü; Sx\?ÌaD#¯íä½Í»[Ô A¿mÆ®Aþ³“Òê\NþþI“gÞ£³“ÚûJ8üÁuðE£efüƒÁiÐ~—n?ô‹ÀøO¬)!€¹gÍÀôV7Z¶¬÷‡É3‹ws!7~Y'·èüH;»å­‡¼7ÓÈK ~åî{f$ª“S«ÿÿmºG(º µRi‰ÏÓXµFÔÈw£3„L-^6'4ýt=_íÛ~ÐS³èߦ_:ñ6ÙE±°d‚Õ•õ tn«f£´¢øØ@/þÉCHyv`lÑ©ëÜ$~»Ëî[¶t†!˜¹©#ÑÚ¢%Àeb¨=ö?‡§iÐ_mº÷õW‘­:,µ ¯iøÚc°\í=é9¨Þ½âPû…Ù°ðõ-M58¯{ÂWuçVՉǨ…Tªg{£ Ñûê¿Úãºß5“i©}»+ÇVlìG¦†Õág•ž·Ì­uÚŽÊh’Uïœä[l3Ï ƒ%³O ^” â'ØY&\¥´¦×k;¯@ežÞA÷…iVFûˆEIoŠ}›õ˜Ù2Ÿ™­yfÌñÏŸûwZ¸ôܺ¡Ê½êtn{¯b±·ËìŒÖ.‹/˜5Gvö©Ñ _èÑ}¤R˲OÞa‚ÜÍtJ·Au&}Ü'ÉÈx›ùºT=}Ù ›?b ¸Þ䲚(лtÀEçñÉm~3 ¶4º9«´%uÿ¼þ'ÿ3C ÞJâßú}z¦ÀéW²t3÷ò/7®?¯jàM…¥]¥à9ÁgÑá]QÅï‰û“¡Ëê#Eêiacöü ÿM ›Uu÷q³Èuþ~=ú”¬p¿Â'ÑlÃD“ÇÍ̺¢ÇŠW©Í|G×üïÿS+“]ϽÎÁÒM2èŸcšK73꿌v|™Þ%ííîŽ+ý 0ÑäàÞk÷_ê±`§tIºýàÔZýÿ‹]£è.ÔJ¥$¸Ði„Îsck { Â,JB3Q'|<Æ÷/ù}b4P .ˆÖ$èË`´výâ%½A%ùcÆÅm@=é ·~‹ÕêÂ󔬭$MeP”åñŒlf}B+ eU±ª‹M%°–@¼ßrÒ$Î /ïÍïqm}N½€_G°Ú÷r¯{kå/ËŸO5<¸ÿ<=ѸUOEÃWi©,þª„Mò®yTÄ ;xXeð¿Ôˆ^»öV®7=—ÚxŠr¡NçY# ݶhorÆvÂE Ã6®m¶îÏø·Ü…¼‚ø±»LsGqø/<ÐðÝ "Í"ìöí4s!ü¡áçÙ›;wR4|•–ÒŽ–óOêôåÆ¿±þ¹)£þ­ï·ê3Å,0 ¨Û׈’!î¦h¾þíЦ>}µ=σטm‘!ÐpxŸœ_Å]kõÿ¿-¤ÃJEwáÿÚ½K¼aÕ„dÊ¥íÞ½¥µzz°Ì]åÒמ^¬³¬nåaר- º“N"_ÞË'là–%',§ª#t!ßn ¤þ‘8\M'Éâ—Ë3#®2bÈšÄ5è[€á»æäÁ{ÑúbHMÿà®~씡lgÆ™0·phÌ _Å–rNÌL\VÏ@Ï´r`¯^çÜä@%¿W®îž¹·^¡Ÿ‹Û»{º ýÍåûf•fÅßíyyÂáHÇ6‰/Ì[[4‘}®Û@ÓMúÇ=ê·#Wy€§ÕFB]®5¥aÔ¼ëS† ¯Øu TS22 玻/™ñL»ñCÏUN« SŽwmÏÀ*²Ë}×Õ.¯=y*V͵ÛçÙl›~ðls£iØëñÇ™´^áiK S.ë5/z®¯V?ÖæØ’…@Å)¿ÊJåñ?ðŒ{G”­ßViÉ‘ª„ÿÝN4Œû¨ðþÊ6€ÔÐ!Óqs§ûç¿ö¹&÷ðÒIÎ:çÙ¿à_§³ä‘÷Ë^îÃK£ƒ%–#Ž3ÁãÆ¶[âÝ5¯ÇÀ7×Å«mFê¨ÀŠj?€±÷€OŽ>ªŽjÀ‚çj¦†ë[gÍg[„C>œÌ@ƒyc¤ÐøZ|Éòî êˆG§¯ö%:º×¬kõÿ¿-^ÂPEw¡V¾_¼ÁºË´¼;´Û¥ÎáP¼óœe:Õ×&p²Ùí5°=|‚˱!SOŒ¡fÜã]‚ ¢å÷Î]&_¾Ž‰{p*‰šñ€À'ÁIç,Yh14 Ù×gi¬a¯_cñŽ{RÉû/0^ZG?ô·ñ.2a¶GY!ìËnàO1û@VÊÞ 9Ò¨A‡XQÑóÝ>2M3ß§ ¯ÖåqÛ’»Z=‡9ÎH×ÞQ¶|LÏ }Ÿ¸®_èåÓ·àÙC¥¾ww ×Þ2æÌ,ÑñBäÂMšO–èùôØð<f\r}l«Öó~ÀÞm„Xl«³¹Gúh¬–”hѽ¯¸†ü6G{ÛÔž¿þ.…Îìn±7pÞ†¨éßhN[?å}DÝ5×¼IÏñùa~V«s»&yÌTm²ÅÄ´P¬uZ¸|£Íàß<[Ô_ÉÔ?lbž¢¬œüüEž3bW1ü :º™fJw Mòã©ÁæÍqX»ü­å&›X]íÜ“½oŽ<F"û¿àßR¦dÞˆ ‡»pøo¨ô…ðß=ɬP2{³Ð=Ú#ü»L½³)“*ÁÊÊœ~K:ˆ¢f'À¶--ÆÞ¤4ƒŽÂãÀOÓðø— š|ý@ý £<ï¼7)”€è­ú¹Nâcm·<Eÿz€šx°Vÿÿãâ$Stþ*¢êT¦X²>1$ÃÔ/z—ÍJl¥&áÃއДÛ(Õ©¿XØ¢íµÇ4A8øŠîn˜ÀdJUvë" £ØÆ©}}€µ%·5¯/ Ú,Îoì78C“Ï/c X”ݹÓܽž©ÚA­^%-•N2=œðáʶ—Ma‰7›D6ÝsŒü(Ñ6jð^mÆÌqê3[}kœaz¬y|þ–>¡Ì”õ¾ê5+½YîÅÁ½®•9qR+^-¶Ï¢Û¨eŠS(Z49}£•ÈQGv ƶ.Ö-“ÂŽYó`zRÛí[·•vÛ@Úê16>1B­V=íJµ‹Ž;H¥›9h4Loæg%Ò¹þö¨|¸º[¥ÝñîL‡³#¢¹¥§Àf¡Ækç6¤WaîqÇóÇüÚŇï+u«×ÿéB²ñµÕô&EcX©±ø¿i £·vñè ¢3ŒY«‰Fä¬ü6‚Êi¤ÿ¨ÏöE©”íupfþ‚û W ÐøŸÞÂã^é&%>ÿ¼e6mÏŸ‚v'Lƒ²voêó #Âÿúå&ŠÆ°2Ò+9pŸµNÎPÕm °ÄÝÊuÇ«”ÆxügËÝ3=^†Æ-ŽmÕMÚäD‹  hüñù»â¦ô¡¡QO Oç®/«$þµúÿó¤ê•®-üÿ7ÅÕ³õ’¥ŸBÍ ’ŒŸÊ¢†vÙ:ë<è²fÛìÝâ v¯>Dº¶»gµ`dè¦~çãnªÂâ3ûC*g L›ìMèï }l¼Ê@|“ èHu^¯÷8f½ìÞª‚þó>ïëzS5Må¨ÕS³öÏ=„­æÂâ¨Á¢ÇAýÒÜÔþƒUO½®ŒR†[ÍbÅÓRxÕ£»õ‚°Y9æ%êBhãšCÃø¼úX¢Qý ··Á¬Ç®lùôQiJd`,}~‹yªGã{«/ö~ôøä¯vïwß‘è3;²¬(gÒöMxsï ÿ¸:cFœ±úÐ.щøTp|Ñž3%©vÃ/ǺBYú‰™iÞWš˜íŒ²xnž** Ö·œ¹±Ó/ocb½êfA`ßë‡Ú'Y…úeô Ÿ}3C_Ö]÷›¢Qü~ùø·6o]õð§:û}i5»(zÍGÊvÕ½z¶¾OïŸÙÚâ–o½FF'GÈD…žþ×m¾ ^€½ÿ‡¦<þösêvÞä ¸õ½[ÜñôóÝáËñÝ&¸ãd“zA–ªw«”ÅôÍ*Sš 4gÉ´vÛ­‘‚×» ²"ÑñnëV(yç]0œÒúNÁkõp0Œ¾< e‘OÕÄ¿Vÿ¦NÑŠîB­|—èڳȮéö™6Ç÷ÅéC ô¨ÿ˜Á©û:ëÆ„Qádï¸Ô©u^4X±c’ÁÉhË8_;sר4p|W|bÊaû7ý¢¦BÔ°dƒÓ tîÝ-4Üp³Íë¡n÷ûlìyðàcaã„ý‹¼gjm&â5ö}èÍÚ[Ÿ(„QII4<‰þñËUŽ ý€D#³_²To²·¥NK&ú¦xþ«1˜¿Žèï‹[ª€M‘Ñ1_BbÛOSëÛôÕ‡–…:~ÉYµ²j$ß{-p°'’÷N&RÚF-š`Å@›„3ÂqQE3B§ã~QÖöµgãûê­§YÛ)XÚ·Ì9ˆiz>àÐé×MïîÁqgGNº~ÆÏ#lÀd@ÃX˜;ñ™‹ £ñk—nÛ= bm”gô rol2ÞG¹Ž¢aün©$þãzwyÚxÈã‹*†ªe²×ý>7æ5q`ࣰ±G«^Ѱp͵žwòÏ5,»Ùfr~¯ÅߪPçc û^c?@¿~ƒá¿-ê÷™Ù\’mK ãw‹gÇ’¥}_Ø…&Þ}„ÆïÛÙ ƒÎ²`³8Íf |zÑëÊoŒ6¿e~›_7ä÷7õÛÜõ 8<Èz^Uñ¯ÕÿŸ,d°¢»ð•8‡+ºÕEÎÖ;µ­÷[ýüÆMÈ] y‰VÚmΜ›Ðq³–îú¦/ÓËqúx8J¹áêÛdêxÚ'rЙZ-. ÍlÜ¢ýZbìq€·u}ý;_ƒÖn>Ê¢M#×--¨[_ŸÌßÛi±_?Óã".$ÌTïÚzkÝÇ¡¿X5ŸùáNÏn+ÁËa ÀîCÍMZªl¬÷ˆv‘ˆC==Ó0…蕽¾¬a—Ö³ŠÛ§Z:CýƒY,,ë1¢í°¿¨›jrÑ(uPÃgNF°J“A ¥þÀ kó”Px´ê}:ïI3±ùÔYFšÒ(_däzû¸zÈ«ÏÞ¯‡;ÿ–±vnd°%t{«”8~fsƒ¬þÅ[ϼtÙ§çµN\`¥ ÝfÕÍžK,x7v뙿<6ø²’³Pó© Ê)â¸îòö Üß½|¢Fµ¹ÓëTa“¤h ¿S*“‘Êšú=²Üñ.‚0=Tµðß42ÞZ2WInõ¼Ð.~bÚÊØ|u—‚Ù× ¿É‰a¦¯¯iÿü“÷[èÃïŒtEÿ·_‹wD‘)Ì—@ì13uy¯×îݺ!üûiõ°ZK¸VWƒã•`ïå½öØçà°Ñ–mä‘ï¿ Ž®²Ð?¬â½ ›g *[?`ÀÆÙ™I—¿ds~«ªñ W»X•ñ¯Õÿ¿)Ùÿ¨5ÿí¸úEwà‡K”[-!)?¤(š–ÑrþcÂÅ_j°GŠØ‘üW@ÒjÃ_âOæ?õdü*>Áç¹ÏÝ$ÅÒ ,P‹“ MqW¥I}àã‚Ú{ËX Ÿ‡2$‹¢#‚EG¨%CQ‹n„þ£ ÔoÚÕ#†b€»¢X‚AÑŒ‡/?&·àбñ/‚0Ê~q× ‚%t²EKñ]Åb‰KERÓ2Ä1CHHBBГ~&4?Eþ1þû¤ø»§qkŠ=„4‚õü¿ „(Aã÷„;„P!$¸ÍªÕÿ%ÿ|ûJõò~¼Ô, ÊéM—;ÇX•ù#ÒÛ'H•xªxÓn1¬åŽxíþ‹÷Ï)¾\åø iƒ †1d°˜_мyå^ŠçÊs§ÑœU@þ¼—ØGJxâ…­šMhÎ #wß6Šf*x² ˆsr/ã&õCW`Чèw¨èÄ7Þ?ðoJ|H“ÜõMþMHXÓÜt€lრKHm¢Q7lÍÓ¿&߃R,Çï1‰ãè>0<ûg9æË ¶é\Â&Áh¨üï(ÙóY4LtEšgúßàÏòDp˜BŒ¼’ã…b›x4™qäÔ!u¨†á)xü àp¬àüÈiãðÇ*ŒþXüGÙ™Õê ’ïØ¾Z}€g@r¶úKIºÐr/)…K˜LÎ +¦ž:¡³é %┨¯Ê ÿ;á®°|Ùšs³„‰¤X÷¸Ðúá¨'ÖsÏ@l‹Å‚Ô/ÄØ(ZŒ 2&&HCÝCP'ð|#fH rò‘A‡hÔm‘ 뉉z‚ÕÙpŸœž¸„ð]ሠà7ÈHÚÕ_†Ìg˜]壗S2±a¢†R1¢¨¥PF“¨·"J*ž²wŠ`ú×äûðßÈP_Ñ}d©)L·Ä˜ï£IãOós-6È@-·T þ™øw‰î'ƾ€XŠÈ!ŽKˆ6²xúôóàÂú™rº‰?A°ž„œS“2jTx§¿Ï¥<¸åœhA¸Œá¾ŒÍ­pÞ^©Õÿš"ßU¾¢úxÿŽÔ  “´f¾á|”È%Ðùvaï«#ÔP4 UR2–Õ(øÆ |±s6GÒ”'S± Ì›‰\ù19ÃKÆH•‘òƒk ­%¤@ˆ…è±B‚ÿ–J¨$$Üy4fqEH}|9^€¹E8E{ùc=Çfœ&Hùˆ˜¯|~Ц*"‚f[³@ãÇsº-IO`¤$î‰F&¥C’ŠH?‘DTÎDSÖ¿ ß‹:K2üz9¦Ö/¹Ø°’<¢ü|AyÌPþŒœÅ²ÜÄBqI èM~ÁMr¦¿ÅŸáú„<F,E—uŒ¤…R¯^pÁü"š¬PÈ~¨DãÇËðh®•s~@øû²fðRç0húç‘Q­þ×ùÎòUÕÂø‹Ô1$±'®àˆuBì* ü%Œ*Ï «8¢Üç›JWðB>Ó‡wõåêÏ+˜h:“Ž &öôB¥ò¨p#8£ù@1æe Â+M'Èç– ÆUæbt>b”8HHД„Âq\’II– h.Cˆæ—ñMi°ŒÀ¡;.¢‡Ýž—0|ŸœÃ+’“øŽJÕSžÁ4×§AD ý¸NŠã¿èZŒ¬ S²ÄÈó—Šõ 1 ‘× @õ¯Èwãï›Êˆišáx¡œsÖ‹är+°1‘‘BñGƒC°Òˆß¡“P§1‹g¹ˆ6^]þ‹||Y.þ‡*–bÇ ¸¯ƒ ”ã‚[Áÿ EнBqœFBQbo€sn>Wp4 âlF¾˜ƒ’³jõ¿fÈ÷–¯¬À¿(5Åàò¿½)©' -·îAà/9áïQrž¸l9$Gþ_©¿\kr¦0Í—æò{xw_ìUžð[Aœ>†u)°CǸµcîD>¬ãA ¯ ŽÀ,Ç1y[L2œħucÓàíO¹øËÐÙè‚f븢þ8Eð32]|PyØzƒò÷½ýI²|ž“rtO„ZIHÄD¤RlÃDR1DY’0T^?Z*ÿæÈ ¦%G”K D¼ µšœé©`ü“A¾ ìÁ¡N’R®5—EÆE(ˆ?áÏò©è¿ë#Ž2žýÓsÔþôDE‚öçÿS<þ>CžȥГ8¨Ã‡ÇO @8ܳtI­þ×ùþòÕµ@MLÂË+XF ‚%åÖ“¯âÁœ.» Ì%õìð—7®ýɵ‹r°H —«¸ÜçÇiaBŸà å—ÊßãNa‚òżŒâz±‰ÅZt¢È-œË ²å7ÿàÅJœúË[î1^ã=IÜÂ.Î &í¢ðî"ÆÝâ{öu询£"_¤ç2DvVÄ!‹/‘àmlÀ?Ô™"–ÂyÄ"œäç"DA„Í‚ˆaðƒÒ‘i` ~>Xÿ‚T ÿ=þx.à²ãå¹\z=zq0U<þ>¾$—Ú@s,–»"ÅíîÙ~"Ò—Û…ö'üÑ!^uvŒ¦8üqJƒáÏMZáËEÂ9üIªfà€ððÁø‡H¸ÜMîÛ—ÏóÀ‡;h¼hÂMÚ ÃåÜñá<Öêµ—Ê<¾¢j{ÿbô_.5Á(Ïÿ&¢ËWɾd‚—ïïý†þU|"4He¿è¾¼)í1'~ ^q¥*<}œQÍý_¾\ÂdÎ’ˆ‘‡oå»ñ~[k<^‚CmH!@»„\Ö/ÍpkºØÓÇV$ü{,—‚Î- â³h±kEî+g±ðeçOù‹< H²˜; <~ ÙœFc &Ŷ¼JJ²B0Ê£[.Z㇠¢DŒ‰WMX¬$þû$TÅ;ÉE[þ3ªþ™L9‹'¸ø?çœúŽH~ îÓ7ø³„„ @Â߯0sÙç$+¦ ³p§,býßḚTÀÿÏôAì°²œœ‹XnÜ4—Gñ.Þ—pžÓ…Ƶú_í¥r¯ªÚÀ¿/ÕßȬQäòTp’ù*LU¤€UpÃò¹ÀuD&Ñ_‡þМ€ƒ~\ÖwyՆ˓o'C¥òt.±3oﶦËw,—ʃ㶠Ÿøc&C^=úC/bšKÄÂÝò`.gpºWyšáÃø‰å›Ù)ÀEúK¡"h)žÈ(.¢)òÁ©G8ÉÇÃg‚3Üeñ²"% ôAÆÁDˆHEdÎ1 ¥bÁ< öc¥²øÇ$-ǹØ$ƒæ„ª‚?žbh¼rM;Dâœ>ÜFà—ïÄ‘?ã‚»‹Ó¿¾\Ö;ÐG å“–¼Ž^wvŸ¥ Ô~œdsµrøñaÎã@xyä»;ñŒÈ‡þÉ¿T}rS«ÿÕ\*ùøÊªëüûôKµw2ËuÑ!O–«–õmè÷ Äz^QñKîï›;ÁæPyÖ/¹Ðm§?áqöÛç#ç…ØÕ§H®ä²š.¡’/Ë€¤S+ßiÍ¥!ïÛ<™Ð˜ NH »œþÃâÔ#yüdÜ1às´Ë „áZ–ßXD¤±ßü¾qÿIF­”r¥GhpˆDÇ‹•²$Á‡¸ili\ç#š ¤IÕž!dB¦¤ã‹Vÿ `åñß*/çF-t®Jøgp{Ë“(y;¿ºŒ8'MÓåóÌ7ø£¦,Å¥ûþøVxDòuf‘WŒchýln3AµÇÿ Ÿ I`Œþ´<ôÏ×Hâ7sÈCÿ|xžK øwhüæöµú_­¥Ò¯®ºÀÏ‘jîdÂ× Þá’oB¿_™|¾¦×Ÿ–‰©»|t´HZIW¬óQ?ÀOS^–¯â%¡|H?Þý§<¤èT¼ƒŒæçÞ‹g¸”mô6b”{>ðÀ;¸•¨ÈôqŒ"pùO¼`ˆìɈX|Á@,qó'mW²_4ž[•š+'Ü'vñÝá–!ç[¶Š&¿X )GwÄøT–ÂÅDhVLI —‘ ¾ì_KýlÄ~¬üüÓ|)ÊÑ´ŠáLÚ¬dåÓ—(o\·êá_«ÿK~Àü_=€Ÿ8ýCµö2¿²æBq|úy^ØŸm?ºÏ Øíµãè/µ=p”'Jãx)j+·$_Ìi±½oË˽ošæKCEÕoÂ#„FzÎi7ÒPûo7G®7^Š,ëâýAX‹m£n½Ë'" Ó9÷ÊÊŠ—ñd_]Bñ{¸t8Íee½guy„ð†…D';†±´Ð)+;¾¦ÞÁBZbÎNÚÏ% ‚]ªñ2àÀ»—yÕÃ? ßãÿ¥!!–É‹Ìrt×%¬buû[ü‘»€ïO¡‰…Ç_,/O%ļÔËŸ+ @Éñwv¬ÆøüRÀ™OàDøsé”<ëŸÏÞ//þ‡÷PPü@.©ÏþUÿZýÿ{òCæÿ*èü\©¾@†|a÷«¬o7™¯üÊÂÙr"È¥‡}y°‡ØÂysŽ¥Ó…°3HNø8.Õ%áŒ@yà+8fbœç+ {Iä{€) àªòÊ,ÜÆ_ìx %ü9ü2 S±˜fabÞ†seÀðsI(Ï Šß³Da~@xúñ…ÉÀ)¼"­½<Ê-wÿù­J2ÿcpý.GÛŒ3¸F)ËÅY>Í"4|–$b!.ÂQ–Vç‚p•Ä?9‚{:QÅðÊøûƒ3žºùçÛ1´¼ EpIf\«ˆý+þî¾2<rS?È·›‹ $íÅp‰"–ñöãbäú B¯ò’…cøÜ}ô%ðYÿnR_þiˆå™~8TÂ'>¢)–+ÉËC-Zl_Uñ¯Õÿ¿)?fþ¯jÀÏ¥ÿXª«ù5µ“QöQÌW{¿ääðK­oîÀ~qt‹]zÎOáž ‹3}ø®rÏ€ãÒ­±òsõ=p4ÄTÀ1Ú‹‘ sJðUÁ°-ÆaUîI\’ÐæW÷pí/>‰ˆ ¼BPO\BÑÕ)>þGréÀ bÛ ÌZÄ C¤Wäús·qkÕß>•„ÒºÖ”L†"ÅR.¬H“.CÌxà‹Ø «b[ˆ FÒRZŒf@d¬¨)Y"£,ÛH 19KÌ}ebcbX©þáIlÅÇâiU žþã%~ñ¼­|¡¹òºÄ4Íg¹Œr  þüùy÷_"âñÇ)hÞá*ÑcObRi˜åE!üKlW×z0ÙÜî>yXŸË¿ÇiQly¦ÿüg=`zOÙ™WeükõÿoÊÿ¯KÀðj9xœí}\Ûö¿Ýxm1®ŠÝ¢rUTL$$TD°E鮓3kæݨ X¨ˆ¢ÒЉ‰v‹J(‚Šùß{æô½¿÷]½?¯Þc}ôpbfÏìùÎêµö4€ŸEvÁâŸ6V­#¡HÑgðÑï`ÎM€}ç*rׄ‡Î×;·ÎèâúùîbÚ%6øäÞbk?°Ô±¼ðNíÞ4õ··Ä¦¡à0lÒb£y½l’>¼ˆ*±H7°0¶ƒ[柽޽%&Ä#oӪΟ¸±;ÍÊË;slÁO»{'8®þ{fNcåÑÊ.‚i‚7\U‹^촧Ľ úçš•œ[‘+tŠ”^Á“†R«¤náÝžt^úÛ¹»+ì3·n’´]\µ¢cL¨Ã{oNÓEV±Ï'¦OM™/xÂøˆ Äï*Ìà9Ũjnä™ð›3¿å­ü ?D§Œ,|ιf«¯Irô³÷9=îÕ‰<ˆv4 Ž2˜^/é7|Ï‹uWVˆ/½»³Xmï¼"°L¸ßìCO™Œ¤,v]}â?÷Ú#½÷c²õš6_g`¬ùàïᇣ抆òoÑßÅéhÉÉÀ‚ÑîÏâ*û®9æP‹ð?½§YܸÍ8ƒ úF~ìû“¹£î4.‡ašíc,Éž™;þ8s¬Å>€oà}´êÕòW÷{R)sYü_r¸–Ânüí3zÞ»öé]ï.^0zEWÕäAOíê(þM¼7ªöEóo/ŠJ3AsaÃéÁªpì ¯…f µZð¯ç…ß%LѧPO?F×G6º0}Œ’(À\#_íºØF,˜=.+"ñl¿ãúF†­T<¿±= J½W¦î1tÚ¶0<9xÜUóƒ5•éeŸÍFÒµœvù“Á}N´Øïi ð|ºX\.ØÙå ¸ÞX­OCAh˜sIZ¿\ðùALÖµbßö6M®æ> rò½¾:”Tšð3"û7^´pIÿ>Þ”êq×u|XyE€ûŒFŒ½[ýÌ·hГ¶)Kî5îý1Õ`ͨ=»îIx}à€ó¢û½ÂÆ«)59%Ìm×t2=¼ôáãuN£%¼ `{0²Áa˜·¨Hh—þ"¨´ÈçM©¹0Öaר)åÎKãߨVðl-@ôþ~‡ÑüdmEƒ»«urÏÏZ¥*<5‹-E0£CYsžÏ³òè{"ÓÊdFDAtù ­bïÁ׿Óâ¯áçzÞrùÒD» ÜÝpä@禗ÛQŽÚÂõRk þs^îß~ˆÃ¹Á»~¥ÇöÂpŸ"07ßÚç8̸ËUt®<ðˆ¸Ü‡ßMý·ð˜ß`ïì%<éUþHá¿N\PñÎ á?åRfåjÉЙ`8&â9”ßèÙ4P4š?Nô›~oÙ~œ:ÀüäË{HߣùWnyð4š¿ªõþ2M4§MÓGk€îФ§ëþõü¯(rû*ú~F°ž¤~ÆyÔ²‚•m:‚EÀVÃ^ÊI‰v]š…}ë&ºsïÁšDà<6ìj‹ MãÆ_ès÷õŽ%+æ¸YƒM›ø§,©z¥ÿrÍÙY _ôI±ðçeêP‚ܨáˆãKì[×&Ð)öõ/SÉïW­Q'z¦€£{@¬=²ëuQõ‰›‡ÎÁX“7ð²Ì7*Ùh~oÇÞ°âåЩy6c‹|·ÎñŸ›ÌY\0d/Ī‘©`×êùK¯\k“u±O&iNYwt™ÀçøYœ`rå²Ô÷%d»Væ™OïCʼ‹#ï÷|ÐOÀ‘¿²làçg:ïïÎZÓF }'ô‘J8ûL¸]«Ÿn+Ñd9„£lÿôƒW§57oN <˜¥;7ei§vC“ßè’Ôæ?kaYôåùæÚŸ¶Töº¿¤et“‹­šö±ŠÞ5>ÎöÂ¥FF^¡ÑŠÆóGé‡ðwïzscäÇ&Wß_nÝß{P`Óüh•©óÛŽÇyñâ\jþ’²¡°êFçd«ëƒoLâˆú÷Ú2K©_¿|kÈ8/ðf‘_öëÀ ooYMj1dÁ·ðA¶ŽÞ¦Õ­úî«o#ÿ+#€#ÿë›ÜîuÎËì&{‡4ê0nfsŒ?ºÿëþR€‘ÊÁ˜ýÔM¥(¸ÐZë`¾þ}lgtqO¿]j›;fªGª+ø×ó¿É6TÑ©r¾DÁ'P—ÈÊ¿ìñVý]ª‘'ÄGã {vã)ã|å6Æê„¼+«r-LÏYƒ w§ÄS¿ÿš¾í·\‡ÍQ íF¬ÝÛ½„|ßìõŽ‘åG€\:û˜ª´€èëmgi.ï…›wÜ„UÞ¿]6ê÷íë,æ #Ò÷Okóšïí3´Nrݧ31]“š? ÍfCËqûåÙæðXmÓ¡&Pó9O]#zìXp¾oPî4ËKÚ¥ÿ¸F7^ª×hcë•Ý«O_6ÄãzYµn«èÇwºµ/(ÞÖ†³zê(ÝÑTÑΩ}׺àuÜn„³´áÅ# tnsu‹IãßÇrG_ì\ýñÕ¼„Ø‹#÷v?  fq#ÓèPJ{ðÓØÛônܪt¿ápʽOÊŽŠ·‰Ô_ß¶UeÊ%qn“Â.SgQ”7Éõ6ó..ë2ܪ㴩„®ÒE#úcôÝø¸ïñÈRÜØ¡OZ*4.D8CN¤]»ÃO­R¿Ú&î$ÉV¶°hHÅã¶k¶õy—yçœIÌhûW7›6\™›QûõÈÛ}[LÙØ Æ.õzVÕzÚÚãßÂxÚõ ýáý©QG÷.ðK“á]-z_¦Â_*¾³ñsƒ1ïOQ>@Þïíp¡,—†÷JnbSE#úcd±6&+kÃ%<ÿÇãN¾wî 0{{[·Æþ3Þ/,¶½®˜²äÂ⺄=ÿ+’jO@=ý5u {ò,»UÙ+. Þîwfw‚¯)mh3|\ˆ±e×íFú ;…Ÿ’þèä "Wýp¬>±<ÀÀól bI_à†æ°æ·k“5,ºðÓgÞqÕº\ÍaÀhÏÉ{wÈè;uðÉCZ‡¹a†Òø‘OÚÝ€³ÔXàv¾A~°vî¶S«/i„þ¾e“ú9Ú®x8:ý:~8©Nžjô©ãàY''hŒkó¾bÕâc³i¥†*µ6Ic×Dhž[À ºZx̆LôDúôTšï·¾ öhk%E‡8¦*Ül>tTou Aµ—ËÍ^ç+üN&™r¼fÎÎM]¹p¯ˆ÷SÏ-WÓ›hCnQ|L¯$îfaðlê5²½ïã·÷áï7¼íñ0«¯ÏZ²AnçádrÕmàpŸ´ NŒñœ¡2ûfäüôJ^>öb2üŠ&Íz•ü.~õиÍ3ÊyN7ôòûºî“Úó>÷õyß±üá{Î -K?Üñ¿®ë Ü”2 zK÷J€;¦³/(Çx› nq¯Ó?¨sÝ(‘cŸ±B$ý|û¸¶ÿý§ýˆæ3ÎÃÛ£ êÐ_â?ýõÍËZí]¦nyU*åêiÈhX›¡ÓxBɬh1¸}äç39<˜îûä÷6ŠÅŽsg@ËѱRÉð5ƒl¯›°|Ì €ðÓº‹º]=Ô=M«²œê ¹Í£×±Ë—}¥›‘Z»V»úìð–ã¿gΨ9Mˆãÿq%½Ÿ%‚ íb#W©ê®W£Ýî?U^FQ1/êþ½·ÛeÚüèT4Á)9S暦ôëÿŒ?é×Iß]¥îá_Ïÿ ''ïÿõYç)£½CÊáŽ;žO$b3FÀÂA¯½ÂÁ`eçù. ™ Éë°¶eJî¢bnô½Ü|€×MbSÕwÌö³µû¸ï-ÀÛ«|€  ]×Ìy5Ùûl'2ZL9̸gеšè©“ùTµ÷‚–M»iðtSfµ½ÉÄ®›û¬Ýº Y÷ÑŸ–‚@2¬°Å>íèK©f¥¡ a‹ðð²‰mÝ>Âú~ZMÝ;ö‰Ô'":vhx(x?¿Û2{e‰cöƒŠ&Eêþw IÏÇÜ6•6“óBh‡BJ´+ 'y~¢·êïÒ«G³Éžƒ›¼ZÓñ’‡3¢È× Œç¦è›¬>¡a?âa@ÿÓÍÐÿ oV¦kSu3%únǪžÕé_¿ZåÝA|gÙ…©•=£íÍ|ºžÁÑžU;W¾õ °Ë·ÕÙò¢‘´¸MDG¶;s¤Õš"wX°Coœ]³EÃúÝôŸñw¶—HòU7'­ ¶*¶4]½:¯Äó¥²gŽÉ3U‹ð<01¸À [ÝVé%ÕàŒ]Ú£@ü×,ô½âßîâµüJnî¤þÒ–W‘sj6 `ú2“’hC•¾ÂåÚ×DÅJ+FY—|ÿAù}î]hÔ¥Uãþ Ç?E(*ñÔÖ@ø¯ZrsļF/î'Ì[PD­U+òXe–LÛa›¢aýnò•Bj!ûÆœUúp7Lòt# ÙQ1ϺNâ_ÏÿµlÂiÅØQ‘±‡ºGZgL¬ [ü‰[¿EšGô^&n¼ ̸±0íÑè ⢙Ý.5nUÞ€? 'Ü*,Ök5¶î¶È–I–O`Ç©ùÃü{m:|§—ẊÑC1ÆÎèIý—&À u+7)¹÷gô†¸w}²?êx†µ~æá×SÓ­Sð15wö™„™}Ò÷•½ 2ouk›åv=ç}ÁÎUN•Ñw§„C@Û¤,ɪ#–s2§†ƒpݨ4 >œÍäx®ÚûJµm±uxeí53^2ç;Rʦ]Ñér8Œ¯nwòýÛÃâW¯Õ7¸0Æåô¤Ê[áe[rM;Á¡›³—©ùV7W4°ßIŽÿ›ÓÖ:Ÿîô@Çk‹_Pï6À@vjÕéá‘¡¼–ïÖÙ±±j¸h›·}O”z¿ž{^ÄÃ"åŽ05+Paø¿3±Òÿf%Vñ«|E\Ïéë{ éÁ Ë·±E`ë§¹>Ðbyì&¸º?è©–¤ýmü‡¹f&¾?nvI;«u;BޱüV¦Z€ñO_4VÜàZÎÓ͆Üj*<·g*ƒ–‰‹šoË7Šö;I3l;>¼4"…¦l1|~ϼ1s*T6ÔYüëù¿Va÷SâðŠ#ûÿ‰^F‹‡³O4ö‡i[bíö¹Þj`fžpÐCý Úe€1ÚO-ÓÊ…Ñî»S`>¾\#½Õ9P¾àù 4Ó8ê…«Vg§F޼æïq÷wd[vj ¿‡ö ×›†ž_jÜúöša¶MZòy†›ý©æGogéBÈ„´G=ž53Þ¹åÉ£ÀíoÌ€þ«coÃHÎcWÇÐ&&{/sú`n K•íF]ôÿ\õ¸{›J­¦¿gO×Á¥v‘ã*ÓTŽxç4FµµIèÀ‰á’j«YIÙGvy²bn±ÿ²“ú‹§©BÏÄ\äʬ,£ ´r}ë×ýøww-hãÑmárñúeÕC4Û9ØüâÂÈåñ³Z_Zåòvíj#L;£{ÌÓ%ºò•§¿÷M+Á‚{CÓ›­M ­#•À߯ôÛ·Ècö{w rCëøË„NÚ~}nα¢pâþPox `ùS×.)Ž)fÑò¸à«÷Ö¿ô¸u³j °§ß¦€ÕÇ*ÿ¥ç ßN‡J{½kÖó€êÕ­Gu1ŸöüRãõàþ¡Ù‹ì0—…Ÿ)³¡3ÇŠ‡LºrdÔÅÞ΂ÿÝ‹«JIÊï^'µrè,9þÏ«š ›ƒñÏ„E±ºÇ„b¨¬ŒAOÇ*à:9ØgÇ7[ŸZWð8­¬Þx.SÙÛy"z ²Óìë0þõü_[È“ôëJ((ìPWiæf ˆ¼hö‰WåL¸î[ ó.™J¡/D³l“OÿÑÝâ óˆcÃ&†)ïÉÎ;yã7€czçF¸4Ù>ÃIæUd~ƒ«g¢ ð‹ù³„MÊí*½hùüö°·ù9s>=¸ã|þôºu»ô×U)ûrFDÞ ¥õtóIòv“s‹ãÀÛh pݼTÑÛÜ;¶W7ºÚH4):qÐ}îån1÷»f¾N\¬ÜÓÐ,ž¸2üê¸AÛÃãMòÚfÛ瓜•3ŽØ…:$õ:rïcãöÄÝNk 6Ý»}ßû$oŒõlë1~Éó8?^œº¤é®¢ðâWÍž*¹ÇU³/F´¼ -TL˜¿rR¬]îƒC¯^o­¼F:øØõž üdY67Ä×!uœX¯‘£[ñ>*æ·ÖÖ”´u‰ ­{¼×ÜbšÝ1ŸÑäó‰z¯í÷Ð7ðœ'ò÷Õ<¸çd¥ Õ@¢¯z/,”‡–¤F)l$Îs ¾à^Ó­Ïß­ÝÖœ˜Ý,štññŽŠ^VxnIt®^ùäÄ'Eà>£Ï½™Â…žûžU/w8×ãé¥O‡œaΧ‘é;ú z‘¶jvZX«C—6”µ_ÝfŸ0¯­Y>ü þ=òÓZùô»²v~ tÞÏ“ãOwG÷ÆÿšC޶õ#“„ÝZYw¡n÷J¦"ü¹;„ÿ·sêþS9"r‹Q a_ ïí¿PWñ?èTÏÿµŒü¥¿øˆnþ¿ø€u´Ë†>Ó°¨­á|ÈnÕM@2ê·î›–ñ·]ð:ìMv2˜y5É}ùìhŸw*ߤ§Ü+Wq<ùt*عmáÜ.^}š•v̸mÝÍÛNš›j å”£^›{^­Ÿ’pñÛ­+cû— L«‡-ð‚ÞÑ'DpX“ß±`¡zËQáFD;XPÑ,*–N|þ–“üÃA½ûžt¼ÒäL-õ~ýyBkƒ!ÇÏßø…ª0õ^A\¯¼v­}&ï©(Ù ·7iÌПXîg¹i䨱³am”a’‰ÿœ‹3 Ñ_e ÷(HÚ÷±ª©æÔ…áSÏN~µ{XÕAÝéÏýª—µŸq>²Õ mpHSÉ(õ}]4q똭wT–4|Á]`}êRß.ÙÙÎBÍùýŸoÞ¥¹°*ˆcÅE†íÉëÖ[žŒ×,u%´ï~®¾=ðJŽjHž%¥?þc4ÌÏ[Ã13¹¤htÿšþ ÿÔóÇȵ;da~M0œÜÑ~;À Ïaú*®ó' õô? }lŠƒÊão=ÈÍx¼]¯Ür$û€Š¿ó}ï;"/}þXŸQ†½[®¾Û-ë×ãRƵ ˜¤ö…gÖLXfAKÀµv›Éõ†ömZÌÜn÷|êŒOSz›—„FŒ>4eþá?ÁÿæI·½‹·œ·ßÒ*|òL9þðîq<@ ÆßâæTk'í»Ÿ_‰µéƒÏùtÿ)½æ‹’À~òUE£ûפuÈ–°[<³%À‡»¦uÿzþ¯UdY‡WÒ±þhdÜ1«òbjCØÙÉ`«¿ÅÜîçtã^ìºAcúÒçˆÌ+øôìI,²% Þñv›Ÿ[ç%–h¨u·ç+ó×€àq¬ä#ÝWœ7%¤ÊTU¼m.)„ Ï®pÝävÇŸ ‰ÐŒ2º·©ù¦½Š’CDû̶}în÷ùì)¸—×yÆö…Îý£ù“\¸‹¸ûÇó&gÆå˜;õì*uk1û€nÁêÙµ^ø¢¹˜UôtÔÝm%É2–ê¿rCßöºG ßvéþøÔ½+ð8um¯I®ó5žFÁŠN¿„þtþºýù™Eý÷ ¶m–¿v /¬ºvæ™623 ó÷= Vsm…À1D?.˜3Éù&Ùµ,]ÍdÃ¥‚Â$ò½á£‚™é±f"÷—“M¦l ¨š’ªnõî]œ÷‘Ðò«ÞÊ©]¢¡‰Õ“¦eNgËÀXKÑøþ}…ÿrÝs$áɵýtâšàí»ÐÅêœSÖœêS›®6)ôÄ$¯?æüqñrpþDúäñI£|€cὈyÙ!TÏÝIþÆ¡U¼JOqƒ]lïSÎeübü ~·x«±1’×Ý ËOÒ+Ø æ¯w¿ì% Írœû°çc÷À¶ÙSØs¦½ v 0û3ü禀ËÖ+í‰+þO2TeÉñ?´¹d‡Ä±ã¿!ÏBsÕ»éËàˆëËëн)× ±Œ2ƒá…8óZ_ NjêÅ¿|pÝÇ_× žÿk "~áÑþ4öÏ%•hæ˜éËx‘Äüª„–ðápß¾ªYÇN¶€kæ¦C喃΄ñ³}3\¡ñ²²8©Ó[õV—Ávºã#€>ið(¹ê—â/[Œ?¹ÉZ½¾ùl}hÄn²W>Bm}Îp/Dω¦ ñ=Ø<öŠ^ivþÑîÏu<úÏàœÓ÷ÕÇUÿèå{ŸñÌ¢kØzÅoQoX|©áÑÐæ3=ÊqŸï¦ùf(/ø¬3éÀì%3p¸‹Øoäó5÷Ï[úìÄMâüÚ¶±N‚Ýš pѧqXpþÚ°J€Ä€ J%ƒš·è±²wèÛRyWðý1 ¢=Ú1vÑݺþ>ï’Fg°Oìp "甌ª(×4{à/>'íauD­eF¥4!Ï5ª­f¦úáÍóÚîH.kVsNXÆÁëÍo&ÄT´à&Ï^wªkñ -ƒÛ<ˆÙ|ó³¢!þ„ñ?0¶°W„·ûĹ{raˆ÷ùÕúO7θ­\5K Ì^Ù½ïDŽýËŽ&ôY—û¿Áƒý©Hœ¶V¸¤’†Š•±-´žs#_è?§h&¸ìNÉ‚ñÁ‚rãõª~û…ø·òì"µ8VüT [2åþ(ÎjézHÿ¾Rv-Öø°îPׂ’6cû«ŽèÇwM oý訽ü)þZ¢ûN¯škcïPöâF þ§Ò"SâÆ¬«ÅAn3½ò ;“lžÿÆ·óy¤´Wo½+§àv¦óþõü_é—=Øùgþ¬e”é½rD €æ‰Qþ«Ú+W’ÅŒmYçÆ RJí€?j¢RDõ>9¨I´Ž'@áÍôh0\¡<Údß6ak:µ{ ^j.˜5Áýu4mRòòL®(¿ŒúQn9=tgl¤ŽjÄlÀ7;ûrã‘ítl£FPQ §tž6ƒ„¼â-&ô3} Q7•Ü>´ër"~~O—Fš~ÖÔ1¬Ô#rìÃÞj]@µhøp*nm† ÖßW áî·fç¢å4ƒ6ÐeÎÐÂß9}ºdš(meD^m¿8Û³}K ´ÛrŠäf³1Þ¹©m–´ÒÌZ·®`°÷ÿÕÙ>¦-Fæ(Mú­óø£[ÝsòvÞ8=n¼z;+Øþ¨",®¬íN÷<’䜔h§•º8«µOœ“ÕÊ´@_#‹S«›fŸ¡ ›õ'(¤ò“Cv½žr© ºá;{äîØOá¼õAÑ ÿÚåqý0À™$‹Þ^Ž—“‘³\š¸¸Õ2óKÐûx¤¼Ö™Þíd¿sñSœÁ|W“Aƒ’VÄø%Lì˜î-EHÈ]ið{Ut©sØÃäî÷t>jüa}oOßG3­åøeøƒ-D¸ævIÒvÐŽ0U^@Ä©“Ni»¾Ö*MIx²´EÈÒ£f¾0¥dA8wí!_¢Ã£ ÇÝÿ€æjHVç¼™…xÖàÿn¯?Ü9øÀãÏ©ØVK÷°P”JrbìÑÎöÐð È4bõÉ'Šù?Ð þd×zþÿ;”ýÓF"¡§úÿоã@3~Áiü|BBQ>5ÙIŠÂ5p/úŠi¨ (ŠýÙÕR½¤ ôO„~Š)Òc@†H "Ò†¥H´è•RH‰Ð;—ˆAH3Ïhr  i¢/I’¢ÐÑHR„?’B÷ €mÅãGŠˆ(¡ +¤Ý$^„HHb4„˜ …@Š ô5GDÛ˜Ã( ÐÙÊ&ÄåûËgÇN¦fZx64,ú™DÛEîÞâ…›„²ù)ˆÐFBx:K¡@$ …f/»rØÃà×öéïâ¿Û˜+\sY=æ×"ü%Jˆnt||£’h ´~‡÷F_~ÿ­t˜mXügg ai|–”€ hŸ#:@‡B#¢aê(þYÌü1N4 ÑH4tµh’ÆH4ath'ta\j9þõüÿ½tðç U{ €àñ}ÿ­@°Ÿed’Â÷<~ÇúÈE>É°ŠœÙ¹sag ÞL("hŠelÄrˆ¬—¦(ô b~’¦ðWXrˆe/€d6ábF xot4»p´%1B$†‹cñ‚Ò*Ii$%°ÀPH a©$B/B1Ç)‰e’ ÄD1‰å’ hL1~‡NJó€ìlIV»¹øHds¡ÈÁ “t¦4s|$ÏýIáÃÎZL"éNZûÑO„„} %¦x”[¤Å|©]X á#ù(¨“µ>ÿmÔW²ŸbvD×ÙÚ¬ÖàŸàÀ·'AbíF"ü‘Äd¯Rè…Æˆ"¥5>Éÿ$æYü ¬šXüÓÑà1: §@Æq !øR4Q»P¬lˆºŠÅj|_¬—è*\ÆP2™«†¶!¹úuÿzþÿ^ú‰ú¿6YŠ¡:hd0˜± ïþ/îž³Ÿø  ,ÓÍì6Ä ]ŒÆ•bÆ"CùEè¯6Ào ÃxVÿÆü¤»DJK¼3r´áñ|‘À^”DìKaÞÉíL1’ˆ‘Åh$$°‹%Â>’$C‘´âIÏ“ØE@Qc¦3n)4Þñ•¾² ÃNm8}œ–™13Wì:Pž^HÈÅŒ+‡g„ ÍŸAXž ñY ‰Ÿ %Å£%|®7)áÛDÓ‰m$áê* Æ¿M?ŠÿZ„?c/È\)‹T’Ô«%øïFç¨t®¶!èø„m8ºmI` ãn"eFÉôÅ7ð4¨³Ÿ€¯‹¿é¤ÔÐEAg‹Í 8bôbΪôR·ýÃPš+£ç(èÊP¹»O¢ù³:ÍKH ͬêþõüÿÝôSõ-±þïîÿß¡ÎYðµÿ/îaAánÂaì—RrYPã…s6€H iZÆIÈáÂ["áHòÃh6 (”ûŒÍO{ˆEb”þCìË‘"flj¼ rÐø€ýf,o$‡Ç÷C XJc— Yßè¬x ÐAÑ~Zd7âW.ŠÀ1Ü6‚’‡°™бÐG‹õ#ghÌæ8öÈ8ûi‡PÂ6ÂÓ© ©@Œü@6? iZ¤Ô*šOHâÏN“X„ëe‘ø$ÅÜÙ óoÐáŸâ ·äÊÌ&¨ ¼9µÿL„7’Õ8:‹vÆ%%p C¾¦ÌÓ£õ`Eçeû-üÓEaB„¿¿¤D2üÙ@1:¬/­¢I©B;¬Ãt0þøþ¯sød gu?ãîc{€É¤]vÿ™À:úè°¨Îà_ÏÿßM?Yÿ× àˆþÿÕ1 Cæ÷}•Ýæ þ,ððg5€ûHöÇF6ót2íˆxí-ó´„€xØÕvÑŠÉ ÙL·n^RyTP,—6m ¤ƒX"îFlFð½ÙÐÑ$Žò¥€Ó°H^ó‘ÄaKŸtö3Y@X@#&ÅL+ÄÒ'mg¥Éý¹`"žÜ«3l¿îL¸ùulèÆÝb†Ï\ G ÞAXÖPB+ÁI_°Š–HR¤n¦@Ê1A覉ùV1àRÇÿùÝø'ùS_% dËlÊXþŒBp5Q<þÙøìwƒ-“¦EøSŒçÇEG =ñ`ù-ü‘8G§ÆgðŠdø3[c]Ôš4)t±f&ºÿq¦[+›$¬cIg#E ø÷)‡b5>“ÝǶ ãîc¦FÓä{øÑ˜»I÷yu ÿzþÿ~úéú¿Š¥ºedÈäK¸æÎyÒ^ܹ9ÉRÌg2Çá¨ɦXe6?«Ìa[«Š°\ÀB[0þ Â"†-ÔaƒyB, ¤’ŽaŒøÚÇdR§ý(œ%´rD<|q˜¿J`.ŠøÈú· CV;ň ;„›ïWF¾}˜\°mVJ‘51@ ¤ã `7 i47_$(fCOZJc8:Y,SLB_>ÚéGR"Ž—i’Ä.€æK€QÚŠóoÐwáÿu  &B ÿÿ@Xe©`ü=ý(œ4FGGÚ‡ÉìU¬4ü°Ó‰ï^tT\n†57r2¿…?ŸfžeÆàO‘²Ú1ô‡¬™â8W_ãÝàäOs|KŠœ©@4œr˜ËÃ\ Ù…’™øøR°øë×1üëùÿèçëE[?Çýÿ¿ŒR—,¦þ d%1ŒÈÿ&)Ájkj%« ¢¾”û1QĉŽò‘|É—L²p€/Ép4bag?ZÄø¤L&Èd(.ÂB–>N ’$OèCQäšXlÀ‹ÑnhD¶úGxC$9(°ˆÅ•À´¬¤XH:…á  [°@ÄHwÙ ¥™&¿ÿdkºÆc!­£(ÙÝù%ÈñcÊ“÷×…!ÁŽÎVç[#L:‰ÍOÑL¡8©Â@€3‡H -Oºlƒ˜@@€d u) ü—øC²OM jä¼lCòë4°ü;& ¬@ü³ Yº˜`‹Dlvgw­£hFã°Úo#¹~ÿ ¤$H 8¢qåø#¨[€I•ãà²xe<ɘ!Ö)ü2aoÆÛfX]/¬$™ t—¯¶¨{ø×óÿÐ?¡ÿm(žêŽþ/²Ÿ!™}O:.e‚þBûPŠi"ɯÊý0w³ýBL‘µL“-$9h` —Vó84`_p¬ êÉ yB$ݽ܃)6H²ÕÀó² 9ˆx^¸ÏJ–çÜäIúR\)ó³ÀfцÁ ïî‘Çÿ¾*ùá»Ë=¹äøð·b¦ÍäñTø8FˆŽDᔄIn ×Q¬ À•"KD4ÄB$<!á¡I€«wf(ÿýgüw Wš°£þƒã÷oÂ_Þ# 8üÃIF}àCɪR¦$9{ž[0Áè &»Œ+úA ù&þ8Ê…‹Â°û'Ã_ÿGøcû‚ëKïf[èd’:{ôåߢ,Šbkþ„ Å0ä…=Ž ë$þõüÿ#ôÏèZŠÍþ×P]±2¾v÷¾õ¸™À¶`\Àûx~lâ31¶Æ¿b/J&**“›û²N_Gˆ¦ÛG(/ø••þâ6 `E,Ó´ƒ7G²˜C;…áky/[Ì‹=SsC3Å9ˆ ™¾l¦˜"}½±@ÆÁˆqÁ2‹1ÿ™ âr‡P6ùWcóƒ;-kì©qh‘̆ag$fÜ;¡ˆOÊ]ßW‚DŽ‹"fÇ»HXq½hš°ˆ¡D|Zì( œB°\’Y[MéÑŸãŸ"¯ïBøËaœ)¼¡Ìdƒ©5¶æÇÅ Ã?‹qqmƒð'Øã1šßöeêÄpq-w7¿…?ÓÈTÆ3½p2üe“AøÓÇ ÍÁ:Ä®~¤È–ÁŸ"œCf혯@L„rp_k&žÁšøÈ`r3ª³ø×óÿÐ?¥ÿë~àÿhHÔ ã«xËÓo¬öÆüJ1ºH*¸yI±-ÀÔý³Ñ2¶fÜH¦P–Ccš}°t%ÛÁÎ `JIÊn³ØÜf{~)&±‡Wýpý縆 C‚ñË„²vÄqLÐ%ˆÍ2ö)O"¦´d] ¦˜m­ÆšöÌ|d½ìŒÀGa¾!‚dïX¹…ì¦Òd×k§É½$4$¾Àö! ´CEâð$’èb —@"@.ðÜ´"„’ºÒ ümü£bñƒ;kÒ¤»”y§g„“dÿJù׬"Ä«óCqŠGFIë¥Ë®0Æ„@fÅ ÄÌFÄ:2)>Üíà ÏA,oàfꀘfÅ0]#šñ/?ˆ/!D‡`)¨ðx~ ÿ}qVjâx¤ìvD/n/™ÿ‚¬wQÛ†èLâaÉYi_ï „ÀG&išË,$†‹„Xša€’JÂçùxxI4}¶{áÂ2‚tà™) Øï¤¯ð_IÿÿŽŸÜ‹¼$°/Ôˆø/¢‘Ùš µ2ŠAàFɶYñ‹ñ'|ñ†B¹ùe:ÆÉ%Ù%àp­·›Ø›bµ ÉF”¿…¨&Ù yžÍšl}!I (ÜmˆÛ帎/hlfð yK îwPÒ¶Øpw5®ûøƒ°žÿ”þaýÿ‹ €Úåþcªí@ºhœù¤Ï)Ð2Ç7ö!bÊý˜Ò›š?WolyãÈ!óùS/‚mhœöwûÈËpÐ&!Å}ˆ»¾&®–v]üˆžXÂ…Dí^ãŸäG}åÊÕ\­T ºÀ$QÿuÕ÷¯¼Ažk(%GuÁ/Äÿ€û—Xs3«Ç8„ÊWæÙÂvŒâ XŸ_`I3n¨æŸâO1 äHO¸5ø‹<½'(Œ¿lÁ@‚ãFt4ä¯ïO«¶ãŸ¾fõþõüÿ£ôÏëÿ_hüt÷ÿç X›-€m¡"ö¾¸[ß_Eý‰š?¼l*Å4Èò]B°Šá¨šÅÿØG|¸ø³]×è?Z…À+u" <æ²O•MSŒ`Öhq f›vØÐŸü Ø;p 1 ® 1¯³•Úì@„ {š¨‡/³+³(s¢n/&`'Zr©$óO¾Äñ˜-ó+ðcþRb¹»Ç¦2˜"Gç !Í 5 œJñZfA8H2_‚÷NómÃ(d qi ð/SŠôHœýØô!¨6/ ›*ú×@é¿G}ÙÏò%qJý‹_øUÕ7áì/˧ÊuƒìÅÝø—áŸ-³‚Ã]ÛòUg„òEnq%8c¶²ø3¬?Å?›Õfø)sÀp„ Yy:É,Ug‚Ë”µËo=Š]l Pî† Âö{è¿êùÿïÐÿ¯Ø"ÿ y@xœí½\Ûû?n·¢¢( *v'6’‚b!¢¢t.½13Ï̹t©(¥b‹¢Š˜ˆ……ÝÝb·âÿœ™]à~¾÷úyýî_„{?<÷uÇeçLœyÏó>O³uà7å’ø;.CˆÇUþ]2}Ci ‹&gÀöÑ8Ûà’Âz6?²M~ct0Ø-jEó†Ý'ø…^ž4ÿh¿3¬¤Ë#KõÐb~@wì¶i§Ý’Ðn¦Íóø"M{×zºÇK#¯ª…× ¯á%Wxì4êÝñúÑWb¾üÜ„£u6 ïÔŽè&^X²·u£Zk^·± ëú½9a¤ýâGrS°Ð>×Ðkù¦ir·„s²7?¾d¹CðUi·ßãsÎ] ¢çn÷•[W<;á-¸ß³~ÓÑÇ̬ìX£viÚ;ëÁºÌL‡"¸½ücPývsûž«Ó"âCs1x?:î²!ëÞàDoÑéÑ?è«*^ªQs×øth31Uœ»Nf‡-ålÐÃ$ÜÿÓè ¼rc‚³üòÀx8üq§ÉÀ}Ë‹¦­Ø¦×ýÌ[©F‹¾Ô[.ôK|¼îŒþÅ,G±¤ªM Q÷w÷ÞîÕš1|2$_ú¾®Áܱ»F¾P­n”ÿZ&¬²“}|»®ö¹ÙuM{àÚnŸÞ+òG )ðæMø%Ú§ôºõÃË;štîtȾ ñ•ÖCçì0>£m+šZdÚh"íwø¤ûú[´¼}³MªK‡Íoý·ðÖêÃ3›Ip<§ÃïÁ¦ÛŽMµí.L|÷±Xâys8¬õÛûÚã&Ÿ»©ëû¶¯v°=z-ƒ DˆÃÇø‹Mû9%ê|ÓüKüûn]ãÛB ¦Ñã%χ.ÇßoRuY5æbüO..¶Ú!–œj±"Šï6áD‘Ê^£W^sáÅåØum?‡ÖâÿÛð¯Õÿš*BïØª¿ÉTý5þmrÒËiV*=½+¨‡F}4Ä» Y|hê̽©òô¡ÐвŸç¶Ã¹÷Qˬ€Cj3P¤é&Ok ³ ß`N[{Õ”´õF?B§f¿t­c¢sN ÝFîÏ™ÓÞq…fÙI†_7|‡ï··¾û6zžÏñ²c)Ù mô¦~}Ú(w¾š¼dîÒ:ÿxÇô§s ^Ý6CF¶Øt§ÎÈYàÚ%ä3tù0; 6laaQÇcT¸PÚõîÇf;Ü­¥:Gîdåy.ذ(ßÊb­`iò6]9¼^™Ÿ}pÊ’¾"`kÒºVâÛ#ç¿nìÊ{MSµ†úGy;6U‰üš¼6{ì"ÝÐáÙf‚_N|i¸vë;Þ̽ý›Yñ„²Ï. }òZ÷:zÊß?uxCÝg[=ö$]ÜC/]æèÿ4©;@Úún„xqKFŽÚÓ/Û[®Hrä»ìz´ßt™¬Ôøð³&­?ò«ç¿#ë±M%ðæö––v†uŽ#”Ïпnã¤ãM68‘#Ýü[ã|ñ훵?v.6 »ï²öø^Ð àÌä3-ƒ¾4\ÙÄKw}UeÝ—€S°í&ÔݸvøH>¤ƒÎÝ «½¿ÿ’™Ï/¬¨OtHÀbÕðB¶õŠÎ ù:zôØÒ«‰$øÇgðM}àÝñÀžÎŽeA_—5šþøPCÑ_ã¿ ŸË6ÕÖ‰ûž{ª,îSŽÁËpà­£1þ£„Ògkoé/N} vRm,³´sÏFø»î(vèY“Wkñ¯Õÿÿmñ–„Vñò´€—°Ó8:Ñ ¤õJán×K\’”i˜¿[ÓÞL’ží´~z¦?ÿÐØ0™_Ñá„ûÇFî\æÑÝ “ß¼: ×47ÉÎÛ¥Ù¨äô>퉆Ükó£~×Q£‚`\#}XZÖmIîèÞÑwÝ^õýB©¦ý¼,«>﾿LñZç‰(•mžÐ:é²÷L×O¡Åïnéúyj¶2nz;­±h§ l·}éȾsŠa.<÷ÜÜâlÆÀâ7!$¢»Ø6êGkƉ<<¦›øÀ=³÷+`ñþXõìÝ*§çŒM…?T÷n?Øïø4œ9o«ûþ¯^ï>xµùÖgÇ “ÇC¤!ü„êÆùÏÅ æÕY¨#j0c¬|益v<:?àD+µº`¥ÕÔíÄËúsÔ)óíM¹é¦¼a™úN¨ÑAÛ cz^ÌïØ„ïóÊä5¼kxr@œ ˆ æ/z,²þTt•öx/è&õ?gé/pO¯zü…óãîíð\S5úZñˆ™·L¬ê·ßT_oTïz%í–ô°lµèØ'J³(I/|ÂŽ}=¥ñçgÜûâµÃ4A€y?gµiûºó÷n\M¬4ñ‰‹/+P/§^ |UºpKó±—u5´×¾›WÐ6~Ø“Žuíuâç]…ë;KMŽ®¡ö)húø67Ünn$xe¤A>$Þ³i¹`ÿL^>Œ<®i2bQ‹öÎæK7L»º #Cwx5j I®COÚÊ_%µ[42c]Ý*ŽÏRüC&´:^ÿøaû£V_¼½žNz·¥Ðú˜ÿŒ.OÚîÝ{¸/8?yRQTœçÈÆVZ÷N?è#wøÞ:êÞ¼ììûL¦ë¥SÇ̷ׇý—2€úßí\fú©6i†[»î€¨¦C›i4€$qžžø,ÍlùÚyËq{ð¢T¾Ëm2êµ™MÑ-ö®—Ó.«ž5kßsU³hÏÝžñ®½6>–Ô¦­“•t_ucýgÒ¹¸×,™÷ÍP÷¾ÍÌ­nf "˜Å|žGE{‡ZÙÍ^  mÆKùæfVàâ€Í+]e׆Úx"&÷†î)+b‹é÷rðïmÕ ùüK‡ÀÊ—÷ªU/Õç{^7ë§Ò­mVVb€žú°P½Y«ÿVù{-Ë4Jù°ãÒØ¢÷z¤ÉÓB½ž%À€§.0'<¬¦ò%ß·¿^Ö÷»«ù}¾ê,Ù–Ãé¿ÖY×2î=vS*(ÇÿcA&z:ä'ÿˆ×$ý~ïú5ôõvϺ¯{œVè°~Ψ·ÿÝÐæü ˜»¢º±þ3ùá_«ÿ5\ª¶ Àù·Ôü- ®î;øKÉ‹.ƒ.öøÎvA{ìÔ¶Ž>ŸuÚÁ´Èï620éNèY-Ìqë›àsdç×Dí®ã¯vJ.ý&Ó×¹W4†ö2Ÿ¤¯›ìùbÞ%³zñ%üd©úN›ÒÏ­ãAû™&ug‡‘#R‡” ílâ dJ¥Á„û÷©r‡]JàΆ—²4›íwL…EÁI`f‘ç¼ë49é@~¹øÈra”\’=Ùâ¬Û -Ÿ«ÃGÓ¶jø©Éµ¹¼È ÝÒëkÄ|·4ÝYBvÒ¼¶o4ÀRs´éá{³lÅ®k¶Å•Šr:N™àÔ¶>›tîî Q“Ó»î9¥?¢”¦x³O¹}½•칞 –9úrAä®ïä¹Jõ6ì{lضº¡þS¹ð2U]*§“>­°­U~àÊÖ·¢Á(ûdo1Øõ\=.´ì©6Cd\ø±L Û®^Ž ú;?×hD½|$3Ùô~Ò,˜Ñoi—yÃ÷í¸~ï0jÉÕ Zs^·¹‘]üÝ7^tN·ÿÔ‘Šß¿`–Ù¹w•â÷®‘ŒS¿Îœz×âñ‡ô‡žé[€ŸåÖ°ùmŸö/zì}Ôá‰ÓT„þØ¥aœRˆÈ.»ûüÅð]ÝAüéŒ(G¦¿Ç'ý!¿ë.Ë‹{¡†,þºjÞìS’ÞÏ­¶iØ«7î¶hëžvæX¼t©n¨ÿTþEø×ê¾tußÂÿ³¥Õ}U+ÖÓv·hÚ+û«™© äê)ÇàÓYažê4/5 üÅ Î?ŒÙ cÖ»Ì7oÚût„×4¿ ™0íc\ý5Œí¤u¡ÛoºŒj2ï¡éKk».òH íú2›.KQ†æ>˜ñíÎY87@Ãú"µÝyô“ˆ£¿Ý8 ´ã a¢Uöí{¡[¯~†¯+S 6-µ)•žÜÑÜ=˜˜$ ‰Ø~ÖÈò¿9Þ—Øî'çgÌc2[¾Ñ¥†ª$N»Äø?v seÖƒÎÁ"7QzãoìÊÃHVHôˆ9ªÖùQ^»s#7‘&øÏÈÊ<å‹ÔRÓ·óN×¢µ÷Û¯vÒ$›7&»ŒÚÔy/ªŸ[´ÃXªqPÿ§D®q\ætbd˵A›Ç}–Bd@¸û;g~xòðý ϤvgV¯ Ðì¾`ˆKïÍV lj7>?yõøp߉<’\$¾ «FwÕ°rIuƒýÄ e¼Xå‹–Te¼ÏÅáÇÒ~‚¥Âo3“´.YffÐÞ¹'„‡¶ºn*þþ ¿ç¬{ÁÌ#¦ie@òFœŽ(ÇÿŸŒ_[rãohüê]Âßrkû¦v~aqZ‡dêË–œL¢dgXüß̨ſ*ñ¯Õÿ‚x†U͉ÿý‰ú*Có8ϺÜÚrÝ#sòˆ–4¤ÍÏžÎøh=j6¨Î6³b€5õ­Ëઠ3Ò¸ïÛ¯“âSä0òݶ±'õºL6Ÿbàp˜Y°tÆÁ@¥‰–¸Í]›³ê—\€¶g×ùÁ¹Ç™Ã©šôâu½}Žê#¤|¯.…PË’×5Õ³š †ÓAý€š)Oµqx½¼£…÷ÛZ¶-@jg:½Lý³mĨ“WB»~kãÆ€Á,ÿ—^Q#˜d›ëÞ›·0c û°ò“’À;’^‚o pÙ¨ôë=w Œx ëblº­9“ä¼°5o¤Ç†ûoÒ ÇÐà;â [ÚøLÏïM¼ËY9ÔcgÝ瓯»ÝÚ=Ûrrì­7Éêo®6õ_ àhjXš$)ÓÓš¨®QÏîf1nKsøôx»Çª¥ïæ|¡'^ à}19ãg¬ïôyG $%yÛ~nìn9¡aRÛÂõº›·Z.»ö\íë»öCZE ?µ¯nÀÿCv½["ýð¸»éþ¤›Áïi(sNûH† & žïÙsÀáÚÇ ò\ûa¯·èóÁZ$š\§ÿ¡i†ÄŽSÝîO»­³w_¾Ï"‘9ã¼™ί6œÓéSÀÜâ¶»t¡JtÚc¹írŸKæU†?Œí³@–ì<ÙåÛµËõOø[L¿ê—bô¬ÉáA%†e43f±Ñàf«Do x_²‹µø×êÿÿ¸8'ÐUpÖb¯ÑÒ˜<˜”•ZNà­Ño–CPÒÆ‘tÑõª}3ZGÔZy{ Ó§.û¶ðn6P·ž;‚m¦žñ'®z> ôwê|ìxßëÀïòÜ)Q0=u¦Qà›)šiÃݺËÊ>õ.ivnÍNs"£½aó—®á-ŒªÃÇ2©±í-`&¬Xû¦uƒsèÛVÉ.™pe„¶Vƒ¾Ã`×äP¾±0»yCЕg<蛲mÿ³¯·hf«>×¹åÔõ^ÖÜÀ~Õ¨g'F>{«¢ºìûC‰a ŒØäÿùkYÑÇw¥ý÷­H_ÒCÚx÷ñ†ÏR—5Û fc¾õp‰xù¯ÚoÔf¤®!½ÔsÏ¥Œ/ÑŽgëd%ûjð$nÃeá‚,¦ÉÓ yoå0&—ŽÁ¬Œdoû+£z^o¶µˆ‰ì~žÐ;™c8ö,ŒXü”—6ô·hÓãÙ@þø'vM3¹0¼mgJé'=#öÒRçsN·''{΂'FƒÒîdy%gŸ­nÄÿ(ò×§7Œö¼¹Îdâ¸GËÀÖaæcZ-úŠî€ÞÆ¢°âÔÄMÕÈ“Q[®¯Œ„g}Çoòó¹1$褓Ÿ…pfó¬ìò'òv¨!•;1ÒýHæ•|êë‹Ù³_t?a5UeΣ$‘–Ù÷‰ú‹zÞ 4è4¹ŸvÕà_ºþÉñ¡ÛtR„ü*§móc׺wƒOáß|û±Þó 8ød™=ƒ°ŸštLëм8ÚÒʯÝÙ«šÈ[fáb÷3ü…If+Ï~¹óštTÆtx²µþO§ÞRo?+ÏÃßóm¿íLÂ á…Æžó_ÑGʾÁÑœ^žîàŸ1p÷œ.Û ŽT7â” þµúÿOÒ­ j!«rîUK‘ËÞ8{Ly§FÃYi·çt§©ZÚ¾†â†’˜:õ4m¨G‹~0<®›ïå2àiÜ~£ÂÒíðhÍä iQW ÄÈE]>Ïý)*{‡ïkrÑ8ô(±€jMiOD„Ö}ºäDŸÇSÒ'¿”¸JeF]ÐXiùðÊ4¬;À:ýºùÓwv'ƒÍìSß×L}ñãY†{\¸f» °°ÐæmË~7–¿}nxÓšš;x÷–pߣ¶wx2ÜàÖ:ˆœºBåÀ—V^ײ*Ø=n•zˆ;,|€Y´äŒ‘ììݽ0ËÛ¤ôËÃÓª±dâÕ1EzA›)zŠª¾£Ï³Ë±'&ñzÃFÒË„]õŸåÂ^ðïÔÓBîYOsÔ”bõ°aýF¹OW ö;÷ªO¯õÛ)Ï—ÉAS;ûÝ\Ÿ°ÿÒðPdYôá\  ~ F5…¹±ÄÐÙª[§SÏŸõ,…$ÕQäX½üêF¼²8ÃåWÛÆ¾vH¥áÜ­±®COò¦q?Y€w=^t³ÓÝ‘äÛħ ßÏ8ÓÑ!R”vbT»íË ›ôhÍËÛ9ü˜ÄÊA4ä ÏáPg¿"~³Õ&­ sègo ˆ% Á>%Äû½^ïïš¼È4Þ·OëÄ#“æU€½eä¹ÎñÐbÿm+]~U»úéÖ³~cËf·~OÁ ê±n¬¨þ¥D­H/¼ÝéY0E·¶nw]ÅyEŒwDÿŸáoqQ-Tc ì3¾ÜÛÅoÈŠ3&Uàßáh:˜t=ÊâísvŒEøïbxåí7€{Mâû¨’€ð¬  zññàZü«ÿZýÿ‰¿(âŸÑ5þŸðE®ýø~Hûõ)ý†³Ï·ØÑ}îù¾=Å­ÒAxçXzfD›};`’gàU€–Í'Ó[fÇŒ˜ü¼€GŠÄ2Ù¼Pá5ç=^]’E‹[Sf6¸[°J7àñTƒHðŽ5Û^Ÿ¿­€÷/†”B<5e#Ùú À&­Ö6#îŽ-ì{’ïÖƒº‡lšã7êpô¨Az“fÆõ+òÊà¯ë’…Œöð’Ìö[šwˆowÉ”2¿L|aÈ»vž-KµŸÚŠGîÔØd¶Å}¤üŽû´­®·6ü*_1ö–Îljo»|a¬Œ¼ÝPþêKá,²Ù­u©« ö—oгsûO±ª+¤ƒÁvõ—];toÔ;ÁnÛÀ õ‹[|ÿú@n1ôêõô}}Ô†³ þçË[!jFƒwk;u3Ò]ú棖e¤ì´T‹†aY_,G.•K õ4·&BÒ‹àúÁN®¾˜<¯é¨´ Ñ«M2E-º÷Ö²×­nÔ+$àl£…æ+oÑ`ëùéÚ™‚žÓO›÷{$¢^±Küµë)`=¤Ÿ)Ú,k³¡ñå­GRÌ<ðÓÛ²LêóýFAS/52÷¥ýÃê¬ð 80×&ð›ôÕï*r{ý}9´|uÆ=¸ h-ÌÊûõøë¶¦“溛¹]sÓ†Ù=êÏï[’ù}J]ŸÎ¥’‰eækM ºÈÒ˜×7ÔÓ™ÖåÀkoè);:æÈ×ù1?ÅßÇÇ=hÿ4a6¢™óneëUà!®y88%w¼Ïâ/Ý~· áÿÚàExc4föi9kÔŽp~Á±ûßßsh)˜ZݨWÈ¿ÿZýÿG‰{Ä¿¼ªîŸ"³§Z©œ>>¸à‹Ø:†Edö~ mc ž(¸`q0Õ _zŸ‹F&ë¾ì>´òMmÖúÚåDK3ÇóëavI¶r›¥WPhfi%¡õ`æ×¢«Ñ-êʺ½¼ðhÞûž—:ö˜rî$˜õ,<îb·@íßüDáxu« á5N>ܘÑþÙÃõŽÍ€?àÚçÆm6Yz ‡4϶\ÒûÍå 3y/ÛÌÿ0¸ûm#—SINGÖ·éðäú×Gº¾ãš„™‡‰q”ÜtçKûÙ³ašpC4¨ðþÒâ6Yé7Xmw]˜æ±6–œsüžR87×¢Öh ªÖjâ5euÈ“Y-‹ã`¹Û;ÁÓæË¯çL:>|é)AÓ&½OMuÏ*X°÷°m€iÛgå ¯<=NYŸœöÝÎzëôT×´ýÛÂ;o‚ë|ÚÛ{§YVæ•°Û0ÐÊAZ˜·Jš>aícϯ¥{@-¬ƒÑ´U*.]¬Ç̨nÜ•b1.ø@pûé§Ž|ZØfþ tí’íOÿ"Û}ÇY ©Í´G“s‹N7šw NÚlý°£ßg×âCËC÷‚SPñø`˜ÛìåV€yßzKé’éÄ"ПýÄ;tý±%?6©õ)9:xÍP'Õi:Y'aIŸ\ã“~1þsù㞥ðücßw{—–¾†ž[g_‚‘g7¸Pç‹oǹ½ß0­ôx:ð(˜…6Mƒ…“ÿ8˜ŸP÷Ë„gLcŠÿV#CL›ÔÂ[¯J ¸ÏˆKøCž¯JÙ€=ËXü ñ–g²nÃÌO‘½¡E]°.}zÄÏóëp„ÿS¿i»?ÚV‹ÿ/Ç¿VÿÿiòKËjÝÿ¿/¾{tX}¯¸[2ŒÙKø'Ù»&«wÚuþRû8O^Æ„žõ:g§sݵç³Û¾n_õ»Ñ¼<൛¹rÙFK'AzŒ‡ôÇHHÑQ鸸…ªÓ‰‘ç 1ÙlîI2üÐÀxïo¬ôŽñÚ–=Ñn<çZN¤NÿÐ$é³#À°ÑЍ¥÷ûÈÅ~§{Ë€ÿb³ûGéÝÖß‘7¬IÓÓÍ誾 Ózÿ§Pèg€ú¾ËF,‰¶Pmù¸åÛ³ èÞ×ÔpnÔðÜ #ôXÇæ·VX‹2»ÚÜ.xõ5óþõµŽ™qro~YvMEï/ém™GÌÊ+_öÎò¸|µçÃÖ# þ×qþókúyÊ¢`Žõšä{ðX¶s˸-F¯½ô$S¶ Ø/ëCCÏvoŸ; ßÖ{ð]³8kGNWÇ1ýdÞsú7 èÄ ¬ç{[')¯ãb©Ç·&òÒc£ëÄXÌr9ÞëÖý~ÍšÛ­ØoÓ¬½Q›:v4ñKñG=‰¬ÿVè v‹øt|öL³OÄõï~ù…ÍrŒ|ëu›Ú`ï ÛÌè “¸,N,¥ÁcÛœPðÝ·¬mHñOño4{‘óª?ôÄ‘~GûŒ<²üBË„ ü©ü>¡^ÄÚ‹á,þQcÖzÝÐ@øïo›çv¶½Ñ&èm#‡åñ÷h—ÈxzM›=gßÿ!ÿükõÿ'"¯¸_uªÚ…ÿ¶¼Ç—Íϼ ð-õ,/ÝãááìOÛ]:ÜR}sõ`äѾp´K‚ êÝólþ¯ÓUÛû&š§´ (›ÕG ë¾/ùö kû#F ± “‹/†À :|€†'ÜŒaÎRíÖð¤tñQÑÞ›õoÙ‰Êæ ˜HBý3f.à¼êªs¸ÅÕ7žÞ­¾Ú¶Gúx¿}µ)ÆsÈÌo%çÑß‚¾ožY¯Ïþk{z­ÚK9úÓª/àZƒkiA«GÀ8žý%€5¥ßE¾vϧéš^”?×Ù`ýaÚÇ›vù¼+ê«t§ôìžR`ª{Üuá®vßÀ«T¬^;ˆF{}kY¯ëá݃“ÏöŒvÖëì.iUºàúlÔ{ XõUòH029 ¦ÕÑ-KVÜfU¶ùNG‹wÝî|¼¡<)Ã7=,õ’·jëJÍjý#2Ä8¿¤OïÒÐ’Á°¹Îæ=DÉm£'uýxr|uCÏŠƒ&¹ÅÕë ÀH»½ËbR‰óq—‡¶¨çTÇkíÒñ÷ä‚-{Ôà^ß”®Ëó¦t_é¬.–«µµ’¸}ó×ð¹ûô或]µ.(»÷ žÌnsö$à[2«^.†lÈiÛ`®ÛÉÀ`ø¨Ýw=ù"7öxTÇ*Eƒ©_‡¿A˜š:E×4ƒ$|‚ße’N—Óþç^ÚèÜé¾Î#˜‘” ¦=Ì8×=££}ýÔöÍżƒÐ\9àG¦õ¾k?Ç?|õ…¦~_L zµ2û€!ï*ðqÏnuÒê añÿpn*Â?3[3 ÄXPw<Éì~v0Cîh·õÔ \Órœh®Å¿Vÿÿ·Å‡þEsöü«ziáÿ"ÿà%†Æÿ‡ìRU†Ú,w¥’'¯#>íóxiYÖ!uõá×O:‹^$®±‰ð–÷ß—Ö5Ê­C6åÃÊ’=}ótmÝM;5þ”úaC»ªïnH×±Ýü>3˜Ò9|r|“~ Zx9y.Ÿ?rc¾èÀê$ þÞFù^Á&—ÝA¼ÂåκâË?R×÷ز0óÆÀ'í»þ𸫩yþ髆c¬%ª|$ãì>GÿlQK[ñæCõ}xÜ”0ú+u%ûþ—*A0hÔ¾ûâRËûªm6§%“ínhœ Ü[P"š±écsZ»e®ŠŽÈŠAð`g/^ÇD˜ª…7‡]ß·%C3Ÿ+¢Ü ¶/µ½›aîœcÁÐ`AϰWÿ2ü!ĩӃ¤Àc6ý¶¥Û^/ºñ²M@²ûÛ–Nm¯š5¯Øx•‡~»am®PShƒF]ždëÅ™|×dãc›Vˆˆÿ/ø·~²ÎAÝ«Yï¡'>Œ9«j®W–¤[Œ yÊßÄâÿEÂ$wø˜aã³®xÃ|ïõÏï-ÜtyÿŠN“u5ŸŸóaÆzfxT7øðoÁ¿Vÿÿ™âó+~²ÏGþ NòÿKþÑù‡3¶‡<Øs®ÍaL4»wðaìÖÙàØÄ—C;·y05µÞónÈñ9ï°íÀvÙEËÁuŠ=Vñçà®ú{î'‚Ø`}××FîÚÞ\~§Åí\B·LƒŽº÷^˜ÙúÔdûŒ˜Î'×o‰©ÿÜvcslÿl¥+áä¼y&Ò!.”†Q Uvh^ˆ‰r¼›UÚöÅ%¾FŒšãµy†š–-?7ž{z÷KiMngYL™PÏ)icæ ­ó½×&XÒ ÈL7ý â[¼¯Œ¶èò~€¤í²>û,è@üí­³Ü¯ØŽ¡£rG¢÷Mµ‘#ÀÌ׃T³>%µ;k¢½jÙ&žŸÓj¹4c.ÔIïncg½¨Ç}ÏsCºÓðé½ùܲgý"£L¶ø8¬‚o‘Ù2ÅÿØEkXo´¼`+ܯ¿¯oŸ$óVKaÑ­y`‘k3ÂúU¨åœ§NZ+/S¾ÅÖKãÜ\·ÁÝ{/¾™cQ6ñ¶ÝPóÁ«{pH¨›’™ÑèPôÈZ-g¶ß¸Ñýˆk¦é~踼žÌ k–UBƒ™Èñ1éÛ àññÛã·£þ÷œÒ·Ó=?ÿdb±Ö?Jº³8A¿ÐeÏ‡Ž™xkؾÎÎ/´VÞԺ˘‹»_£õ'Ôoüõeø@£^0ó£,(¶ý5ø«×³¨¿D£Å—¦½ñœ2¿¿q‹Lè0£tÝö’fYŽK—Ñ Lh¤7 Ù½ûö·Z­yA8(¾q—bΞþ9þ£—ƒ´õ1pôÑYôþëåoª„ÿü5CìŽ#ÿ+óÖ[N!ü¡cÀkJ˜%²æ-íúnM³­ë¯ÕD©¥«å<ªÛ€ê†ÿß­þÿSå—, üWµR?Û-bJ{ ¼±ÍYâµz1Ùþ~@D$è&Ûi_+H1‹NPŸ1ÑÔ»z{EZuoBÎ1X³Z©D@ Õå6' à¤­ ›ãvËíŸbÎ3m4 á“ýšï´ÎÃ\-éÛŒ!p¡¯ŸÜçöÀéÛ¼F†¨rO¸|/É©PJjܼ®!ŸS³Î¶H™èè¥{(ÌŽÇéÀݘ]n®¹ýøG'òn#ßµ“ã7.N±jÛA¬·¡«O½y±UCg®)ŸêAظû¼QàåyGÇtmÍ·ÖàÙ!SÅ&šyÓͦqs³]ÞnHGzÌšh Oë®}|ØÕãÙèìµ9c!ÀÓ}ðÒ AVÍÚ¿ý<Ç0HxMýó@ŸŒÃ}¡cIŸPçæÙÇOx¼Ð¸øç»{uxØø¹JÔ®cǶnßxÐ-ÝI[ ƒ§k]Š(X¯ÞúzÜžÂÇ õ¢Ê¦'.XUŸ/þäþí[Ã6N–íN>Ú6ä@¢¡ÜÇûûõ¶Z‡vׇl}AÒš=ÍÖð®÷¬nüËVúoˆW«ÃÀᮕLÀÍAÒ áBó˜šþ8åN†×ë.«µÖŠc†´Î©æÓéÇs“>MK`¶Ð`™ßú=6£kSÓ®NðåÁUϨ}AL«Ë[xi^ ŸÐs%5òÙuU ‹îó>™õL¸7ï™Ç““¨œØF©¯?œ5º3ìWà¸$ÐsA~˜ŸÎÌÃ[[Jì`aW|p’͇¾)N&‡CÆ-1Ó³„Xfùv¯úXýe_î‚WÊš z­°û W$˜=õzø’ÿ‚ÚËPÈ8[T¸n̳¼ù7Ë<åW4*áo5îõB£€Ö3€Åâï‡,þ0è{é£mSÉ"C“ÞÛµëŒÜ˜<²Wwˆ5{,=×â_«ÿÕ+¿e2"¿e„®±v@ žï‘+¥)‚fh ¡HdS$CÒ4‰¾c÷ ?¤)ô'”˜¦øT0þFÌíE[†Fm„|9:„¢Äƒp@£ï‚Æg[X#FGhƒPBS„Ë2„D Ф˜ÄWÑb ЭˆAànÈ7œ&iü'¸ Û ÐËDŒ@øÎ(†J"b´Û`¾üp|4þÿCHÊ÷à‹÷wˆ}’PbCJ€`HÆqº= ½² ¾z"\u > PRÆ=õý-äN‹/ $:•/BK)‘PŒD@KDÈaÊ£¨CÕ ù^ÿ);Ð#´AÑCP< Ù§Åî©´oQÿ)î1sÇqG€ðç´bÃ5æþv²û=øçÒø4è?|š 0¢øeÄ$%ìïV(æ>¡ïþ4:ã_âO3Ü ŽvÑèJL9þ¤˜À:Bá»BG8ŽI í„8%Aï>êå´t£T-þ¿ ÿZýÿ–‚ßs™ßbÔØñ¿[{œ–Ý( îX§‘’â—óƒu‘ R ôzÓlCÔÂ;L ”+‰(ñ'å%Á B‚1¶ ð·a?†ÛCð Ѹ!ÉxF2,±Šðn`hGš"Ì¡ˆð'ÜA$E×DRÈ”cMÃ÷b–WEDè"Läü ^ k|`ݦð–+ôÿ㔤è1Eóƒ¸W…ôBÍ]âÑMIÐÅèÒˆŸÐÿXùÙ!1€—–èØ ¶uh^"Åbú p"aH‚&e´u”"zx€¡…bµ5®tÿ»ä¸$0œæ”«¨R*ÈŸíjÅŸÞa’òš[öHŒ9ï“À¶þÆ4ùø/JçÅ ó SŒ$À Gl»¢Ë:'±ïjÇÛ¹jNºÄ‹)Á_ã^k—x’fíYÔ¢„-ê8«(hPÂc‰ï=¡X̾õx4AgÀ–ˆ¨ÿZý¯‘ò›ÆÿßaTÉðÿËNZC-€òbÑ+ŒüÎ#ƒZ¬ðôY«æ¤Ô•„K<èÅ,ÉAÌŽø˜1+*î¼!°= WŒý)dï3T #E×ÂÃ:YØú‰Y¾DŠI}r‰’!ú¦X—€ÁtJce§Ñ¿ˆ ¤þ¬ ÀÞ7ÚP9HµEa PyŽÊ=¿PZ醀’¸ðíðb’‘ÑCHü‚±_—r¦oŠÑËaçp|„Ÿ0»Ub²× ¤¤_!Äœ!¡i!)ek@“¾³V.“а_ ’ YV¬¡ ‡ûÿ?öÉTΜ¢!éÏîf1Â?¤œì)ªâ#Е6‚éUÿBŒñ§Ñɰ)Æ~&>û:ú†¢!¿Ñ@†Ð¬‡ÞV´Gà‹Æ†¿Ä7^ØWùÿ4~”øã‰-Œ?Ž4 ÑX ¥ì5+-‰ ;pÑšÔâ_«ÿ5P~ÛøÿÛ²5Vj¤°©Pƒ ‘b#™¬_„Ãj àiÖP8ÿ8DÇnÈ%Ka],Ò¯¬íœ_†]0¤Ò8s€ÃØ‹B ’/i--äÅЬKÀ‘Æ Bšg£­ˆšD³¬AR†9м£cG_>r¥×¢TaÅ?¼´QîaYÁW.¦ÙD¢sË3¸ë¼HÀ‘äÊ9EÀJÔ-š r|¹8B}’8%‰Íø†²ý=£wIE å3Œ!ä O@¬V¤ÿ\rÙþ#üO§ÂóSf…ä¯Lƒr>r¢˜  ü<ó¶‚÷ÿ$ÌÅNÙc휪ÿ|® å° µAƒ¶wÁ¥ï±‹‰_B1¥€UŽ:‰súŠëS¸ÿ‰?Sà²ûèúlè€ÃþѬ#à„“ ¤o$Žc»&èåaB÷h»Ñejñ¯ZükõÿoÈïÿÿ™!€_iWÔ<  [ºˆ“ØÄ0œ_„è“Æ>‰s^À þlÀÊ㤠™ÀÚÈ8 \d” )œdJ+—ˆŒ²=¹°žãÒ¬ì[Äþ°dK.I4.°ST(3H€u·XûÃ-–ó¹$ll•K±‚Þlî³l#ÂŒëéòÚÊDF¹Ç²ob%°]úO0>r6Vlùëó‘bÒ ¸WÛäŠÚ3 K¾S¸ž ø¨ÿˆËÄBb-2R¾L ƒ)Ãzš”D?O¿‘þsÉ®ÜÉ9‰‹pV&{P8pŽ ûl”„Ïâ_árôXôý 0»!L«ÿ\ؽDøcOLŒŽFï;>°¡Z`XGôˆaoèò)¡¬†>‰oǨٛP¶`üƒ±Ê Q[Ê ¤%8††Räú‰I‘”fëÒ„RE¤jñ¯JükõÿïÈïÿ«Ð¨Áîe©i@>Žúã[à'§ƒ¿PÊ&MÙP­¨ÀÁ|WRqR„_PéK³î¾¢æ- äZ+ët€-+TFŠoŠÓ€„¢æWñP Pè+âX\ÂÍÆå>è\H!y¡RRÌîæ¨Â%‡þÄ ågãbc”™Ë@" Ó§÷Ø/)§%LÎñxÀ  da#ðæ Çq)†µWÝ "”[ÿ\0Ñ7†c+šðˆä8„’¢/ÄlžO*‹pY°ˆ–R‚ !åº0GJÒB©G ‰| Zu‚ý'’§ÔH¡_]™ü+Ò§JP¡a\{%þ Ÿë?Ò¾åÎ’òh¥'È·¨2üóÙ rv8‡@Q8Ÿuɹüûþ±U|èr.±l¤ p:™‹ ¥?Á_$V$© 8‹ü"Êñe•~`Ó\Û-ìÓºÍßÃZ Þ¬"Ôâ_«ÿ5J~÷ø_UÀ?dø‡šfäS\”q—Ÿ$ˆÇqUÏ\Õù @\êLs£9bN_ލ’BQú“–7dk­¹”¶¹ÉŠyRèœ|&Ès6$¯¢•!JA6øäŠÒ_tÙ@±Ùô˜X/ŽÄ5ºØ4ÁB´o8"6P‡ÃX_1+ëíd”©G–’<"ÃA«Äß e~‰S¢rv“¯\²D CùÈ‚0}àŒDù†rÅ®Liĸ®—ú‡Ë“2Üšô bñI”@ÄF i©P‚8Ï«$@"Ä£qÍŠæU$¿ÂÓS–„‘ånRÅ 0ŠæûF³Í„B\nEV*¯ˆƒ² *ÂÂëªÁ?Ç‘%aL„¿§˜ñXŒCýÂ`ÎÅùçšdçëÑ~rEeó3ü©J^,²hAþ‚`ì²¢ˆÅ?PÆú 86,bÜevœÁÙm<Ø ä)±~-þµú_sä÷ÿUcTåøÿ‹Ï]£ €‚а>Pîr[nÃUòáY4žÀͽaœ%yaâòÙ}~â 6a†ãcå¤Òïg+ •@†ˆ‘ží›"AúÃ*Î:Pˆx_£k2žÑ¸L×P±)ÄÎBß(®2˜¤Bh¶$‹¢…llà„!¾Žéå ÊQ åÏT =:&)c”ÈÿKP~ R<%xöá)îöqÍî>®z¤®¤À=Ž¥F×xù—2Ç\¸rB&cÏ)ÃeÍ€K‚Pp5„ i)ðe"Q0IÈйÐC’’„(„Ô«6°ÿDò*…uÁ=RR™ìË«¾•¹`ÎBøKÊDvЀJÿÇä/”G‹qÑ¢dôa¶oàïšÁŽóØOgëU ; µHipHÄ5,\2‹ÅŸ ÔÈ…‰ú3ü—¬"À#ž5]ã ììUàï$ÃçEƒÆŸ/«(agëgPC¡;•W]„´ÿªÀ¿VÿÿžTÃø_À?ÇýÇRƒ,€|œåªþ_ÎI çãSŠ ¶+àúYÄnü0ÖÝgÀjë#aírÎh¨< 5Ê7„{<7U‡Âsw±î³U–þ²“¶hÊ=ša­¤bR/ëp ãÝC eˆÊ“²­IZÿ€B÷Y¾J…ˆhEÐ=¦"¢§ 8ã|öÒ$î?B²A@óàE 7C¨ þ)¹ñ²~!-p‹Á“(ÔĘðŠ*È1‘RB¼/ÙW [E$E\G?ˆ¬AAÀ\eAÛ/§Ë«¾•åà\.˜â¨2^žhe'p¡þWbüÊAàÿ˜î ÜSšÿzü÷p+Á\ ·Âø£CÓÉþÊ UÊ#šQàˆ!¦ñyôŠ?»€tXEÁÙ~²½ÿ€/ÍâÏN¢QŽ{Ø ¯HÇÿ›Cˆ”+ ”2¨¤ÿ\þ-ø×êÿß“jÿ«* ðÏ‘cì%¹ªì£ãªÿA$­X€µ ØÁ_$f3^ÈŸw’ÑÊUh® %ð‹b¸J?ÅAìšÜ4@vænÍjgó#BöŸŽ#¸ÞϹá&ÿP슔ˆ ÂóµÐ̈Y%cÓxu/ÊKŽØ]Å#»ƒR–{!VÖÛVÎ3Š@¥_8Pþâ`…gR¹ ™öŒþ?uAxò.Î׊ÿ(B‚nG„“Æl8žL±mèrº@Ê}ÖîÞQxµ· /D&ÄW£%  ‘K@ õ cp~Dˆ±PæØ{0­VÐ+I^¥º-,|~üüÏ#VÂ#’swQUöKäœ)Ÿmy´¸"«Øp#‹2ë?óãŸÆ®ï†^TÆ;XF;$aÝ÷ s^Wèƒú…)œb†]L90b!ð < Šaï–]1T†nNè‰C!WS… %·h܆œ³N*“×¹ÕøHT®úÆ$‰ðÿÏø¯Â¿ó'Ã˜Š¡¡RB˜O„ÐJ&UåøS,þ4E–ß-:¼bÙêCpƒ–G¶³Å³3öý¯Å¿Vÿk€TÛøÿ+ €àð_S €|lÇrž>~‘E‘±b¥_„½vM3Jà+ev¿Üݧ± $}‚e$—-cS¬ÜZ©¸ÜŠ]&ÕŸ £¹ÀFÉÖÑYa Xž…[>€¦—áÌ©˜ L¢×ãâ`…FÐì*ë„Xàž„—äÄñ?´¡Y GõðÂß QpÞß0\£\¡ü!ù†W¼/J`Äìï ÛŸ!Ýb¹ ä7I?wD‰ sŸÁ³‘ùÉ °ëˆNu»¨Y9È•ÐB dì{&þH+ð Qi™Š1@᱇ Ù“aû„a÷XƵø×êõKõÿ¿Ð¨îñÿo^¿&XŠø?»Âyy¥ŸÈ=åº|a?:”ù“\v_™üg«§Ù%E® Š«bí``”Óù9]é÷ØZ5"Ø%e#ªx¡ðŽd]ÒqÑ–Ey0-°ñÚ‰VÃÆ¹¿8ˆ]OÉfctØ9ðŸžÃf"i\ ¤@Ã7/ŒÎ7PÎEò+ç*nM/œÜƒbpŠGº/ôˆÄåâŒGly鷈喾„ÿ‹}Cpi7(6ÎQ,‰Ê°“ÍXGö‘ð´H!¢‘Ä].!%BšÁsÍÐóÙ®ŠLªx…TŽÿ–³=áO)³Â,ãQÿŠ”®Ò/$+|Qô_Ѻ" ‹·¾*¬² þ þÜ¢Âxy—øáÕ*áŸOáuäiåb—4»Ò°¢,– #ƒ{4(‚ xCPó×S"ÃêüòïÀ¿Vÿÿ®Tçøÿ«,€êþÿþT¿P€Íov*nyívdøD­üi?FàCK”>?Á(Vd—;„ÝŠ|ÃÙ5½Øà'¥(—BN˜gly8QÔ`«@(ŠgÌ.17wš’€€’qóµÌvÈ‚[wü,6G²v9öâHðŠÀ]ü{!¬»'b(FWÅœcRY}UQ¼Œ#šY»Q¡\kd«»Å³Õ]X_ñ"Çly8n[ ”+æS"Ÿ(Dö¸~¨Ò$g|Zš›¯DÓ>a9xE„H\õ‹—ÿÄQ?À¿ &d qÄæù¶œˆ Z€!ímUm¸+%¼² ø1!ü¡¼¯¦R×ÿàVüœÈO®t•ñWL™þJ©â3û×à¿[±^KÎxÅ6nv·˜ ›Ñ±ký³5úD.CÇÆ+…kÒð’U´b‘ë¿Æ_ÆMå~<Ž51D•ðßͤ_ÃÎù'³¸Óâ6l\B4] už„ ‚‹ü,?àÿ!ÿ ükõÿoKõŽÿ¿Æ¨þñÿoKµ{þ°ä;ÓŸdóá…H°BФ4X9=€R$?iå"@ÜO²I~´#‚ÙÔ«¢@õ;Åãe¾•Óñ@º Š *Ê~dÆ)Ë/œá¦øØ-É•`žÅ¿"@šmˆÂ^…K«pí á–Àp@à¦{;¦(s”²80Xé™à3±¢"ãG!þÅŸ(îg]‹„‹g€XÑ7^˜˜¡ø2níXœÿ@h¼#Ø‹xÆ€ñnÁ#»Åêç ƒA,Å—i’Àm$"×åB $¨WÈYÈDèeZŠl¯h©ˆ&`ÚžjÿeÐÿˆÿV;/TÂN!ü+Óiå_ß)ÉãÏR¥X¯S‚¸r8¸R™½–ýÒ_€¿(•+ýÇyU‚KO„(¡q4èÕy»-c³5­ï¹ÇDõÒЄ÷vjšWŒÍ/Œ}UÁÃPcˆ˜Ÿ¡É·¯\j¼@3,1Ó ¡À®è* ¬×àØMÏö›vçvÍŒN\ô3òSÿ0Óà&ÀÄ8ש÷—\cå6­¸¥Š­^JjzÓa¾oLa‹G/õöD%E>‘5sóZè˜9þèãóÖYQï ½SÕ›øÁ)Êq¡S,É\TCWíŸì:EÐxØöÈÃ*þ/:è%ä^•®Ë‚»Wº·ö§Íá¢.ì}Xæ O­™[¸$8Ù-<úãuÆï˜b‘‹ÓMû -?-Kë×ôQœÙǃZ>ͤ ôôKa\R?ãZÎ¥ÃmöͺðPøA½÷(Sï]–Kîolúf@Y³p;õäAïM»ºÅ®ñR¿o =ÖÝ:>Øpƒe€lþ¾%Í&'¾×Ûv†Wì}§Z¶¾~ü{ñtÿ㠀ò«7-S’Éiotp,<ÙtAè+ï­Šn]^FÃø–½<‡]vPÏh=Љ,…[hü«Ò.Û&Ú-U{±Ca•Ø~3¬oïsàõÅ4€d«Å> »éäè‘!Üó{m×k¥PÔÉ*duNíÉï¶Úû[ª×9ýùu?_ù°ÏâΧ´½Ywl¹YÐmðnRí7aÜ» וË\C'S!;Ý“gª^LH}Øv…c[‰W{mÅI Þvœ<ÍÀä…˜ìÒŽ†¥^XòÍüÑìÎbµŸÄ¿kÑ@é°~SµKöÍOY»ÄËF>=i؆“ Ù ÏÑáþÆÏ÷KW¿¯×pP]Ú˜ÙJèCqT‚@̺՜ZnêP L´Ú%KЇzRKé j]:þ¦ìÁ¡ÂøQÚŸÝZs–…ª×0ÒlØÊ¦åÎŽŒø}øŸºåÓQ—(,šíÊ¥©²'1±‡“2÷P0겓“H”6ž»k’½o7ýH¯ŒÊÆ'ZÑ’¯ª«ÐøÏúv—1FúÅbïØ+_]Þ ²ëê›p°Ö£á£gδs ^³ÇÃ=A>p};¸°­÷v›Ê.Ïj|ÇÛ=gùåk®Z§šxCoñýŸÂ¿Õެ5ZÍ̬ó§™FŸ¹Q@ÑN’(ñæú= Ò§»?îËšf?±xmÖ–°Q±ëóRX¼¸Èlå°§QM;-°Ãë_²ø{ø¾ÐEv¾Ã}²ÏñÐÄž9CÐúoݰ:þBçw’î”±Ùb ë¿TÂ;P.OÑ;wèu£C{ݺ¥87íu·ÓÎÛ5øÿWð¯¡ÿ¿}#mÂþì¡"ùóFþum_«¥ÅONð‰&?A7'ó6Èa•M2Þ<’Ro —Ò0'ÑæÂtÕ´CñÔ¾/ÀÛ–y½`êÈMô£ ËNä…Y9Rû&¹®YШeÂ(˜Òïk”Ú¬#Í µ£`CfÜ™¾Ð­Õ Îï/Švš¥£š>݇2ˆðÐ9,?g Z?-žújæ­]×}áµw¡pïì7‡íu‹Á5}6 /œ¿´A˜Çjzh7£O«ï­™,ó»ÔÞÁsÄÙ\‹/EÛg$¼TŸ?ìÒŒÄ÷K&Y=j5,*VëÑ«È{ªW<{½¢‹tÏ97 º´†7£ÏÖ–š5Wƒ=^}³uw§?M á,?±êPÿ¦¹OV%Z³3wK<ÏÌTÿdººuœ zdc@×:£¶.ؽ¿ÁÀ†­§OÐöYÞgŠ%K:MÙ ð­—6ϼSaøž}v½6Iy__ËŸŽò¬–ÝÂ÷›fí¿×BjÛîNÄ»Ïuá‘óëУÎå¶L”;ü6ü_LÌèÓuéœÀúèIG’Fvq ·_¿Æ•›G¶h˜:`vþ«›GúXH®¢Á óÛ`<¤Ç«Bë'½çv 2®{§ou']ü¦»ÖEJ–fŸ½)=½”í`6èú¨Á) Ž?|þ©úšæy©Ò\f*xÁOà³U³Ï£sg.¸ØîáüÚÇ kå¤Ûö‘°v}†œ·C~fDìÛ_ z×eÖìÈ/÷ †vƒüûÀåCóZ{zSn°íóÃírмã='ÿxý°HÛ×yóèx²U‹:aë„»#«ã¿¢´©Ý1Myâî›þèÕ€ð_¼`¿ùÄ£–‹º ›JëÃúÍ׺¾…ί§Úõx Ó³5)ö¨Á¿†þÿÕM(ü“s ôüïÞÈ¿®QÝ/<‹ýBi<§6FŸ7ƒKr-ëZuÛt_‘D@ÝwBíùù¯µWLw¡¯ûˆ^täÜÁçÃ÷jŸâÏžB§w "¼Î4Ú}¹¿ÖË«—·­VÑmÓ¸†{¯7‚%š-Ün˜08:$oX/$6ÝbÓpþÁOŽÇ‹ ‰Y^m!3îíòÖ(±lð¡WëiàöêUÞ@_S§Í6ïƒ>îldR*xZ·Ÿ›3xü”‹‘]_Ç–ø—1j [Ún­?oÖ]J}×nÛ͈ç‹èŽ÷êlÊîé¢û ÷Û**K̃Íl•ÞÊFã';îÜ.PŒÛ=¤ ‘ã1}qª5Àõ’«ß 9aº N<Ý)^eä©Ð5—CàÐÇãú^‘j†_•5u`^ƒ6‘îFí ¦ƒÎ¶IeâOí—A·K^¬·˜6áäwå°XÕkæ'£ÓóƒÐ­ÖÓ`x¤j=|é€Òr€¹cÞ°2Ýq¦Û¾®yQ,ê±ëŽ·ó´^¶ù½ûè$|ŒÆ?fÏôK2Å´÷½£ÀÁãA]ò’шh]ƒ+ŸÆ¯îµÛÍ,ߥÏçýÓÈ%Å-¾æÏºê7AkÆ T‚iþÂ)/"Í6ôi—qr̟ƶ»×ʃûéõuõ’ZŸµL[ñx]èÏ'õ^»Û^^7¼v©ë¨8Ì\÷4ä1d>» ƒƒç"8i×zAÛpO˜psþwñÿœs¨qkîŒ=Ѧþ–‰Ì\´þáhuücÀfèÑ0…ö|kÿ…}¯dDŸÇøw€~­ÚD.«c ÞMR_þéN0t{œÛh/PZaµ§®­Á¿†þÿÝÍÞûÏhÁv?›=ø/oy'ñ’­4ˆ§œ«Sj†©¹g oÔU%š–Ìùdi;y©]¾¡ã«˜…{ˆ9QýÞÑN³ßÔ?°ãq) 'û¨^ÛCõŒ¿0t\›•›în%¯ùì+”Vô¶k‡sôŒI~Ç·dµ§NqË€ÈU¾ãÝé´ëýTtŸDííÒÇt ¨G\¢¯Ì³õúd'W€-F}\V'Ûoyï,º?N6דÓÁNñŒ7~Ì“&–l?5¾EQÛO!X%ÞçÒ|bŽM#[êz›¯TjÞLÓmQk#&ZˆÝ0}Ø“;·õ6#òLãì.‡NëNv*Y5ªtõåo. »ìà¸q‚s6¨éì,Ü69F´¹ÌÁûË´0µ{úù}ßF,þ²ùcýÇë‹Ö:ýú©Ûžáz{ò''¼.n ìÝB zª…¿.¼úùf=÷UcàKªg!4•4^ .³4 öÁðYÁ_¼,fø§Ãƒg^;§gî}rŠ {”>W8ÑS}ý§Éƽ30½maƒNô»¨Ú~óg¿ÿâ çvô9mH¡Þïë —SŸ†æä lQmûâuFÇ–«œt^–Նŗ®•†˜?Óæ@K '†ûm(ê)¢Az§©(¶hF¿÷ªKS}ÊÃS ¯ù§ÝŸ¿ýÆCqbzÉçÁ‹[Èí¹3°‹Š9sÇküÓz#/k%­ŸÑ;ø èä[ÐwçìîKzòTûá–m}Åw´Ö|/Ûª¶>*S>UçeI;CƒóŽ1>OBiÐûK£djÏh¯ã8ëzÒºwâ^H^zêf.së?¤ÛwñŸ¡'ãÕNfF›š.=qùlýäî;3ªãBßnuöÁ+øm¼ áö« "äÑÛ;¨¥u»ÞK{ö¹p§ýõSo¾¼eõdËüy®5ø×Ðÿ¿ºY…ÑøêRÓªµþ‰ .°ún¶·•EªpC\‹yE¢ôZ‘}>î…¶Ã¥CÀ¥àkÝÅG¶$úG;æ4QÔ²·µ)Œ¹(NG®–ßæíNÓ¸GWÒAetä@hµ)ÏÉÛ}¸ñ¾ã ¶ ( \K N‚ÓÙÞàøäËV¸9«Ç»Ÿ=Üú^yi?ÏUwî_‡ŽóZAìÑŽºÈ¦ó3 \5Îx#’K¤Ð1ÌÿÑ8n¸ºkѨfcÁ8öŠFP´Æ¥ç :__;ª${˜gçÓûgé².>ÜtotyeáíµwžëânE;` ±}hÐM`Ÿ6ËÝÕ²ö½+ê–UÒÉÕúLìã–Ý8|Yf££Ís.6 }Øþ™¨ní¥=õFŽ:Z}ôÀ'fÁoÀ¿ÙðŽxüóÚ_Ñ´Ûc(ŒOœ¤~Ń(}º6$¾ùí8˜:hë#p)~Õ\wöé…ä€÷\€‰ mê›tav?IQ+–²ïRn;ùF ŒÚ4»ÚôÍøäí>Nãí!ù¤IW¶‚HõÊ6ÖzïÕûax¦ÞFú:U¥™wÖ0[Ù­O†ç Çš÷šÚûOàßÿÒ’­²E;hòÃùƃžôhwíµZß"áˆ+V>0wÂØäWƒ ýÿ«aúøûìýûëÞéôZ ̆Ô%€õÏ~9¸áuÇ‘ô™ ú¡å@çÒî‹Æ„Ã9_0i48ÖðAn¡Á^Û×s§€Õý£/µËz æÍG …Z#÷Ÿç¦GîÑy7©¬ÇÆñ»\½ëS>;»Ñzÿöã]YÃìÐÙ°Ð.!˜<:¿yÎUÍUj«æB9ûšŽ1u Ôë>…¸©KÊÖx¦,‡À³Ý]ͰÓªæè–Ü6ëÝB#ÒÝÞ çú”ÇËífÅíó¹õ'k)RioëH÷¥Ïè¥LžýT‡¬·nÛÒ‰ Ó¾fž²ðq˽P_Ì|¹åÿ)ÀÓ5ÁvL*Àx“{ Þx±Gìš/o@ÝÁÚ`ñ6V%ØVpÝ[Ý{òo)¹}ú\¯{ŒêêÖÀ|©pÞgŨ€Î>g¯õ”L·:²=MõÖj‡óÞ¯Œ¾ôÖí¥¤ÛìX«C/ª:ù¦Ì?dØ¢£²¥j'wÒ¾C‚áN³p°Ühú!£öH‰ÈÑqr‹…Ðö)ìYúëÁ·Dã7´Ë ?šÛÚ°™Cîþ¦,HÌ6ì”i—aë±ÐÚÖô#`»ùæâ"´ÌÕƒàCsfý÷ñïáÇ–­†˜% ÞLé«3×t%´È ¬Ž®žÕÇ[oÓGêÊãïms×ãobRh6¤ýÀ–†k²Ðz˜g¾/L)p\¡¶¾5”ÇÞrQPƒ ýÿ«›€ôý#ÝÉŸØ7PÓp 3žžôqÎð0t:»uŒ´üLÆòumÙtlýèÆ¾öI°irœ‘½âĺ6‚”I÷õ;¶QßDüÒ'ÀÒÂð:éá-ÌžwžÝñîû=Eò}Î’9Z ŽßYmš·çý¶U‹^;lNê¹àÀÌÇÓ÷;»û”:v‚œÅPp<æ0ñaâ0‰ÁÑ[»üŘììuÜcÛ8ºÅŽF‚Ù»4Zu…ÃæFîŽßû´½p¿tRçÜ PµK/Öº»áV£çÝj]\O¿Øö¨PóÊæžO¹2 ·®»Ñïê•} v‰Ø30ÌÅG¸èxÜ,²ÍÐÍ0©cWJ§œJ4?k6u›åÕ>žîö^XüäpÈó#vêcÏd¸=M§6z­6Í+ÉdSpQ“2f…Y&œ^xy˜a­˜Ý›d§»9˜ï·^³¸xwûZ_kÃ!í±žÍgwíPbP0Uê~BÃ;<¤ïíã]$%‹3ëØŒ{ƒfTM¯ex^­PFìó*ª6¬]™µäÁ瘽šŽÅ¯³î益:ðWãŸÒ'GðjZC?X¾9Ýg4ÝúÒzkË}e ÒçÝ©×è@ý©W„6å¬H]úŠèqs­)Ÿ»¾[çöe_ÀhÙ†u°q}ĹÛ/ž…ÔÍŽªý¼ný¥S¥Vê 5¼gýðp±Ý‡gëì´ =îz¶ßí—¢W÷aJÚj9úrÎ5ijÜi¢—Fª/kHLÌS9ãup³ÕÄ¿DãìÀ ƒHZZÿÝ®…áÙ®dÖM? ýÚ5,yd~¼{Ìf#{»m»Ìžôºã½ìÓ/èNClµ-<Œ]D.íØæjÎαƾ.çW43àÕ­ ?€þá)1u¦ì„Å[–{Æ®¡Ÿwr•ŽþÿíKErx5hN (ñ×úú>­¼á¿úÎxÈ«õX;mä«ýOÀÊ$?A7dþFŒÿqµï…wJë>îZƒ ýÿ»›¿ìÇ;ÿâÿŽþ¿ü’Ú-@K³Õ‚öÍ'}Ü °íbïËLZï:2Û¹.À˜åׂÁ:`Eók*onØÊ† i7Œ‹†ïšœ;Ü51!ÑmGÖs÷N« üýH#b+¯>.< χŸjaOµˆ±§"UÀŇý:P!÷õ=p¡éÝÃî©tR`ƒ0ÔŠÝ:/¬WÀìË£M÷6©6x_"Í)T]ìÝç”ßZç7šR¹¦ÉÞèÝ0¢sñ)f[·u¡6Ns·Áð>ç/é¥Ox`¿hÀPcFåÈîz_ûnÞ'‘®nú\½³ Ý²UûíñŸ®Z¾áK‡ñ§ŽŽñqcÓu©£õ× >†ôŽ-·ˆÎ€ÚÇ 0K„'Ù*K F®½°äctGW0:0'& çþ­NÐ.àyA鯷`Èí¨…–]ZuK€»¥ûµô:Jwê¬èö`âe謱¬5’Â!?}I?gÂS|·žómËpµì=9]Ç »Ù˜]pÌ’j_þkñ§¬WELSù>`Ù„Yõ&ýìáµ±ÏÌ+&S#sÖ-õ!n»¯˜½}u­xÕÝ }©¬ƒ} “ ŒF»ž<"énï–Ro§\œkL;÷§vÅÁ»úuË©ì]€ëŸw‚ó£ëйnýkÔ¹y/ê$j7ÞtK¯ž±E†ð~š6”_½c1KSåáßQ~ ²a¦ú3æÌ°Ñ9îë>½)2•Þ¾ôÙ§0‘‡ÿýªîó–7ž7SË5þjd«¯­Ã§Î6a¸çÇ™`=Þâ@ôʧsuJýèþþhNF^Jš(µx8”¢Á[w@­oð‡¬“ë !yØ:àñ7Ð+˜qÚ üÁbš½|ŸQBççîÏ[­Î¸;~UÎèú÷ÂrF7Ú ,´Êjð¯¡ÿuûñ4Wïÿ§7ò/iîËž…Ü+½^ ´ãô²p½²iÖÏá )ª7DG††)–Ÿ ÆGÂÆÁí¼§{‡KÖ[™5[³¥.P/^‘í¡û/@ð¡ÁÅÑ’ƒ=ZÔ R¼q J˜tïFvßé)¤ÅçRrõÍO3_òmNdÝÞåä?ü µwD€¹dé‰úì‹­Í"SÕËĈ5¶ˆ²‰—™Ãë•u†¼ôl^tü~ÁÞåà$)ë”ieLù’úm:{m‚Z“c'&€iñxgÙššnäóz-?E-÷r2=@vô»¾#ËwòÖã:ßäŽs7Š‹;ÒoËò)Ë|×’§®†fÎÞǺdt˜úzsÙ½È ÖÖHt1‚u{‡#^X¾'´­–U¢fLë¨^4ÈMnÓ¿Ôöloû=+zÕ·ö^¾«aJ¹myXñÀaÍÓt-LÂ)y¶æ]ó¼e¶,¿áþvÌ>’>§¸,¾ïô†×?ÙuGf9IÕØÙÞ¡ôýQpºu©¦Õïq¹_Á“4á눨}ê¶µ^5ÝÓhj½HÃ?äûÙ&p¡ÜÚ•k]n ð±Ë›{þ¶_5]ÛÌí$·GC‹ÏùšZ·kÆCê˜øCÈŽaADiyå4ܦ\èö±­- ƒ»óÁýcËócÉ«mÝB¼›Çªvr}œ”5tÁqU=-úBIo‡‰½§¸”î¹!¼xû Hnôó›”þ›ã[…öŸÔ}sâ†a+]v ¦¼tüqür5Œ¸W'šœº¿Åý§“ýÖ? v-^7ðë˜õÏ[Li4‚dê872Ž]µ*Cbv$»LØÄ,;жÔ߸ðö‰ÉFMÐüõø»<¾hSüµ|½U¼AëÌ=ŽY\ÿšvßà¦kƒ¢ËvÉÖ%Ї<þOå 9Ýá/t;Ñà$8®“ Óžˆ84µàö ¸{K°Ñ- ]?qîžÁ¹‹kðÿø×Ðÿ?±I~°¤ûïÛ7ûOi‡‡.Rítød3Õ«¹#6îÛÚ´º{Ø—çÖ,Ë>öÙ!#X°)Ñ™¾Y· ´x•Þ„SÅ`úY @— ó!ú«~'qA«OfkjO……£<žÃ§Ã“E¹™ÑóuØ~B\cÀ(Èj‡þ¨é¦¹%óœ^ ~ôC½O­Ÿ ¶fòÀõÕ» ¸Yy­: ÿ¬ðΜҳ¹©`ß¾ú v¬š_&êoì±»ƒ½]¡ž:»³Cº/ô–ù‹Þ˜ªì¡b· —ç&íŸÁöíDÕ#$Òyæ‹ôºgì Çmàb7¦Ò;.qn‡ØºaM ûÌÿäåvP;²|ÍŒ'eý|ܤÝÍ(NÕ³Ln¹B¦w©`ÚÇèsÍ’7¸0ÖnÒ¿¥O6ï`0Tlà@7†DÝnü´ ËÀré Bæàs`òÉ{M›¥µ”×uÀð^g¾z4ÓúÿÁ­K?•DigŒ=6Ç­³x)ÆæXAî î‡ lËþ:°âÎ5°üÔ à½çËnÏömm\ƒ ýÿË›3£ø^Ö4[°¦ý&foþ™6y¡~Íïõmo°í”º…¤ÖDgÞM°î~ÜÒ‡/é˜-¿«©~ lÀ<çȉ\ÇÄyv-ùX¶ ø:mCôùáµý^}°< †]âîÂjÿ¶ïÀÌpå]Zhø|2ÀéÑ$¸Zœ0׋'_ì’¬r£Òu·ì!€þw÷ï·5MOëµY\דâN%ŠAEŸŸ…f]ºÝíŽ[›2`Çe%ÏßÜEš%Kuv4È”t¿èê´0•l’¹üægbØ 85AT^«MÜ q³/[“¬Ã­î 5ƒ6½ŠtéûºMÀèÈè¾W¦‡ ö9?Z8_p{K‘ÇÇ#êÓ¶ï&g…_Ë*™5­¡Âï¶7×ZDßÞk§CYÞAŠ.X’¢ñi³\k4LîÕÎ?7EÆÑ—™qA]ÒI ‡p£w˜¼ àþ–+^ôHÍIæ¬MÝÎs‚"ƒ-½³ÆŠ©ðÌ·çoWM8XAšC5V~ÞþeHîÒŽMÝ{q d¥däŠÌz‡. gÏü4ù—á/Ð];ãm[÷‹ïÇûMÕåàìeJ¥vnÇ÷Ö¿jš §Nž_ìë uŽAã/kh™àö°ý‚üU§)®·NËš¾us¿ÓÍ}ïzyhÉ[ÀÊïˆ8ä]x–Ö‹®ƒwôRt±åm›€h€¡ ¼h»}~*™ðzÇ3u‹î“&(F-™Ø×(䙯ì!µŠ®ŸStzñcø<«~Çf«äM`ГZ«FûPSUGFš¼mÞ卯-R¶:αnd'}­WǬÌу˜æç´n¬*©·omú“v —?ùô…f[L R'&teókc¼À‘Þ³Ú=Û= Îl÷ÿ ßà_âcƒ»¶ZßÊãn+þ²3äµ  ÞÈ]¿t½¹´e[ºë‘ú­ä´Uê¢Ë³²Ö˜Ôàÿƒø×Ðÿ?¶Y±ßíS³÷ïç[»øCÚ7VXv¯ß 0Óý°Ï%œ=º^÷˜qhç Õ‚¼Ë“ûO¿Pð NÒjØ•“8óHËÁ¾°}bþ €h_°ñqr,ìØ#Ö’Ož›˜.¿œÑo¨©4pïô£²y1#L4Ý‘š¦Ï<0uÔa³“ßéÁ¢µ#ÕÒšð¯»àê¸]vôÔ†#A‹½$ˆŸtÜŒKæíß:ÚÝëò—ÄN:ÑÈ9‹_·Á×½ÓÀË}˜1{ô“Öºm¼4Þ^áÒïj iÛE vòºsQͳ!ÀÁpçÞòÝU(‡iêãÝ=–÷ P·¨à=Züjx‡2¦iÖæ¸7_Ï%å/X:CÇz;| Ïaja:•7fí^Ð/±$ƒ’7‚aï— ¶Ûè^ÃÎîZÞvSãÚ©ë­&÷3+¸Ð¿×»Ï-·h44QÖô} pqù˜ü‰—¥-M¶Ö›<_$©Y×{‘G›‹¹žp»ùüí‹uo`þµ_bñ4È®3ùp4ôÎéy·çáGßëØñŽyüèÓN¿ÿF›ž>ô¾ÛÜ‚3kzPDfÜœòi ÌÌåI8oÎäž+ÏK4êot%‡õõÝ”Û%§™M;´ œ » %SnÜÑìcã‡ÃÝÌåµÙQ^¡m<;Çlxçõ­NêÏ-µ'¹Z¨J˜³£1ôÚV>ÎRxØñðoþ ~Yy¯hÓÕÃÏÔ×hn«3¡gÁä¹M®6¹Ô`V„[ÜÊ3‡Û’f--4í}tºw‚&eœ{Aë|WEj£¾rµÌiËâÞjßд}u@è1æGð_Ûòò.ÙS¬Ú6ïÛf§,ù|p ÙÄó|ô7ø÷ôTL¤aº‡wÈxüctÜ ?=„ÿÐÛ¶>s˜?ëí§1í@z~ÏM“§¯ÐÁø×{~øZoŒÿ´þkð¯¡ÿq£¾[믻£îi°Lñ/ÛØ ¿ÑÕæùÒë¯ZO ‹2]Öt/@ç¸öÝéчKc¼Ìk±pï †.Øn‘}®ïâ8…ñcñÙ§Ržéã ãžVâ£f Œµfh?ߺ߾§ìÔ‡ë+<ÈÏ{Îzƒý•ûW@ï•4>ÏÒ[´,o9,›.½i7­uýǯœš#ÇeW½êåu4)7'GNêÚæmV§Íàœ0$,þø˜5Aåu­V¤—Ý ¼¡>ì@댸Œ¹ôÎÅzl· ° ëÖ¤O`«'Z{ôõ´Ÿ¿C²µ†­Š0œvrÉÕyú7Ì«7ÔrÖÔN+ó‡ßÍÍ|b™äPxö›ÄìIÎعiˆ”²Þq¥MÀäîV}ÐPvweZ¿àFû…+g†Clk»Bµ%ËNÈÍ·ÅJëÖ{!…Õª­À&VŽ;~¡–GŠƒÅ ¨íýç†÷¬U7ÚÅÂ\Y+9ŠÔp°¸±ÚeHž¯“¼ÎÃ/¯ÆõY¤-6ïp;\®÷gmÜúÛx—/¦W¥ì»R rÎ^··Å‡×.=~ þÄå6.‘Ïô–7%CòzžôXñ€Ö]}"R%^÷5½Ý^‚  õƒ›÷7-÷°ž8xÇ#)äî¨/…ž×ÞÐgÛhó^Fƒ^8›ˆ;×f56wë.¥šÕ^+‡âì>j©sßÏÐÿ~ðïÒkÛCaJè¢û‚üæí^=?pã­\ÚB˜05ÿÉkÏ·oœîdHg^9&Mœî¯zÆÅ™M¾‹ÿHÙÃåµî5뮫9~ásRš9‹Ûõ©M«2Cï ú§G>8¾}·ãŠùõŠ8`Ê3Á–Ѱ¡þMÕǦÙ)ƒ¡Ù ‘ù¼ÍÍ®ÐIuXŒ ZOê¯ûCøø(/›ò=ëë¤ûY{R0ÖJø þÃÏ(€ôLŸÜýÖ\%þj¯„«t0þ‰°° ÂÿÒÒÙ¬Ô±½MлŧO¹ÙšTw;0þÍj½·íZƒ ýÿ«Ûwž ,‘þªùöÏr;¶ÏP·Û»ÔÒXÛ€ºå3Eý¸Éèᨳ…½ô}ý¡Ñ<ç¹#¼kçùžIý¯€Ã`¥ŸŸ^¹¥Sô¬”ìÐî}}Õ'Íw7Üßs_ôÌ£“†º]핳ó~‹xÝð —ŽFÕU?ò8vÿË.½î{¹â ж×Ü,˜ 3¼¼6…ÌtI*ÑÈh•áúdá2‹Û]ÛG4¿~¯óHèbc»Qæ@Æív»£ÞëèDy"?Ø}të»6ç[Dìœ$[æ‹gÁÀE_SgÄΙפg¨æn€¼ÒS½ï]+èÙ24s”øÓ«})ékUdÞ´i2öž£^û¦n›|ž—v Ÿ«€k™WË5‚3ïw,Þöìz;ù‰ÂIåmÄ"¿ZÆ Ö_/¹QœŸ(zT!ø¼á‚½:¿~‹gM|a}VF‹¢ãM& º¶ú‰òm3!Y<\ãÎ5€ Í?>8ÜðìNƒ+9nÝ0<Ù3öO®ŸpÔ«´ŒmvÖ5â€ú©õ3óL™8R/.‡ÇBßÚ·‚ñ0s†rMžì|12︢ûš+á° Û`ÞÝÙ°²–[;7%ùÜ“å+œº¦l¤u§—;_ ÕmšªuÞ8²êä8,þþ‘æ#·ô()uªÖ~Gº½&b¦ß˜–µ}Êâ³Ã¦I&Õ®ó¹é »‹žÏ£b¤*Ÿ+Û;O£å\¹û¸ ÍöÍ>óXÚ~`‹¾N'μÝÞ$ú/ ÿ¤Ñ±:)7Ÿ,GÆ¢ÿû}¯9v7ÐkäoðŸvkå”+–¥ËÆï\¤ÄE(jÇaü/î^ä¨òì]ßÓ7â ¶a]½-jï)pcç`oÑÆ.9ÿhù´ÿúÿÝ2ÅEþ¯FÁÏŠÓ¿·<žú{/¢Ñô‘$ÍÐÉR@R«(‚%Xjm(K¹;³4 ú¤Q ô³DJEÒ„”"‚¥)P?ÊoÞDoñÑgÒ}F'£•‡ˆe4÷E Ë¡“2Mêìó"†²\G1è?Bê<ÿ+EÚXJS ˜·#ˆÂÞÔŸ–HI Ý£Hè4%‘QèDR «};K¸U |¡hng>?ð+ÌI„¾ç¼*èxÜ‘‚j+§t4îèªè~_"%h@£dÐè´ÊS*O˲è&Ë:Ì&ÐÄ9øHeè¾¶Bª+á‰n—N` 4oèT4+4ÒpÐK%ˆô~êU-ÿ‡£B<,/4L4е¡ ¸;á8žQîW%±òóÈχrZù_ìü¤o¹îvþReïo_ðUðñèØY?*ZQøgÀ@áw$+𢖰hq“4‰Ö£#‡?ZÔ Hh±'êxýâàÖ?E9|t*$ º ð€I€êøKI 9pøÛ#‘RxM ²"ŠäÈjF^6–ë˜é€© Ý…öo½²ýð¯¡ÿ?ßýÞËãöóÀß»ýV àâJˆì8öIIXL›€y"b””Ðlƒâ\ E!v ߈$è$(ðÂÔ(€c+Pãptë.ñ¦ùÏ”oá]5¦±6œÅcB\žáAJ)ÚÝ%¦+îÜdáψ º¦ ]’ü( Ç>mBåüÅø£³?ê””£ZŒxCIñؤh2Q?š•€höï·4<Àsw%ó~:0þÜ/Õg´B(©–ÿG9)hvlB”¬½¸Ò^U¬1r*„%žû“øïõ!/&¼E’Í3^¡H‘ ]‚UÜáïÅ' 15ÙŠ•ˆÞY‡|± Ý›Ë"¦:þhö±Ø„2Ê3¢Kƒ?iO(Üꡤ¨#é͜BBS¿Wüð¯¡ÿŸhùÿ“ÀßÛüçÚoÔ28+ž³Ð,Ÿu!v…¢Pä‹%8(m~´V1û$)F)¹±ÄÇ=IÌÅAôФíÅÛ)èDÃt•ÍÃÌ¢[ 8³ÅÝ [F€Ø- ‘bPwÔQ†xi? -w…XñšÃHМâ3,Vˆ(ÇßXø;U9¢j QÉÒ…î~þJ;Iù37Gü¬Vrs>Y…›´Œ„¾üôˆ„>Ì7\¿RÊ0ÊëT|p\úSøg`ËYñ€%îè&Ãhb«’sh!£ }kç+ÇR˜&ÐÙ¬õ²œq• éwðÇòFŠzqú/·xI¨Ž?’ó–‘”ØÕŸÇ¿JϼÔ)ÚE ±:†Dcf„ž”{ þÿükèÿ'Ú_BþÿŒðÿ¿S8¨tfR,'•~|‚rð“c9OÙ`ÿ?Mbå3M®7ÏÓ°æ@bå¡ÊÿÏý `=Ñg»Féøö…óÿc]€ÀD†Õ ¤WÌqƒ¾ˆ–°ÿÏ8Ú õ!1ŸÎŽCg¡y› _ßÎ[*Å]t4å„hU"ÕNb+ÿ öE1ÊÂPžH%‹£¬Âh¬¯ îRåѤ+ÞJ±sãJ/–!{ÒÑé=„C0b"Viñì óëL€}„´Ðƒ’à{ ÀUÐøg1î-C¢™ziÈô›™J¹+hì)1¬Û*Û44$$X©xÆoÃÿÿÇÿK8úzpSfïÏVòJ¨”Õ Aì+®ò£ÙW„}0ý¿º~9ÉÁËþ´øoŽøÏ㟊ÖŠ¢Ññ©§Hù(8]-J¬àDK«0 ð4z!°óß³ò©kXý.þžœ» uà=Y¬2„P‰?’ ‡¿Í“óoáØLOC÷£“ʈÉü ôÿóNìÿçÎCði\¬Àj( Éõ•°3’ѵ$ˆ›Óns¶„c}sìÿ#Içå"ÅN9¢p¬4¸K@Û-IQRr5U¾2ì÷­‚¸’S ðú¿òÚYAó, fep,{C¹0$¾¥H‹H>v”·¾á\R¾#V’°£™ç3v!ˆ™PŒwÁ*2@‹¬H/` W…i Á{Qh‰‘9´ÎoÂ?MiÀUóÿR¦â3‰ðWRÿÓÿ[=^\q477þ•,ª™•ÜK•,>¢Šð×ÿÓøgò&9·¢°/ ÛŠHhà˜êˆ¤+^ª Å]pÄÆ™DŽÑâírgošâMùßÅŸ_åˆVp@ŸÆ½¹ÅT…?Ë9ŠiÒ.€ÃŸË.ÀCĄ¥ y¦ÉIaÍE”^|c5ø×Ðÿïhùÿg5€ˆø‡ß¥d0HòWúÿq^”È>@Î-VÌÀ%b¡¥tǹ•þž‰’À98&ÂðÆ–· õ$••¢Ÿ¦9uiÊ\†g§‘Q·;âiHç†eqˆ/ŽŒpNl8öN +±xlÀÑ1k·/AóyŠ8Ë=´“9S‚wAV°¡'DZª^ܼ@itÁ ª‚åQ®ŠŠãÜ|±:ŽîKàÅðæÁJÈpóéøò¼›™©`™ø8Äïù3¶ åÉ— 9ä‚lmÞÈ$¬³—LBŒÀ“DÈ´Spnúš&Hé6ç·àŸZÉ¥+ü¿ÿJþ‰ÿ»ùC¥ªû9[®jò+x£=Â_iWš{UþߊàqÅBä‰]¶óþþé€Q“0XÄSœÿŸ¡Ý<OÆBƒ3åÌxcD±5î^¼k€Å²˜"]}*ÜV®ÞßÅÉм ’ñAŠªŽ?çJÃâËÇŸSh„?oźyшʰK€%€ÑÎÀ Ûœˆ¶HñÌükèÿ—·¿ŽüÿsÀ?Gþÿ ƒVúÿ±ðGeæ@þ4'9П„ÇÇpG ÍTôáübÜF‰2ëût3)ÛükèÿW·¿’üÿ ÀßGüÿÈþàÎèç,"´¦Ý‚d¼ÍÏð Ûü„”"ìѬØ€ýÿÀu«ôÿó ŽH$ø¹ lLVáú§ªüÿÀ(3jÅ2ÞÿoDá‹aê&ç¹Â.?ιGRÔšÕIR{£0]Š¥8õ—Z±›{ YËùhbÆ~6Nþ>Õ–.>J%§œÛ„ÑÕb‘•È0,U1"İÍ}{Ø­‹Ó € V²-ª2HKñl¹øà‰"YwþŒb™ÔÉSʼH`Ñèu“1«@Ä/§Ä´ Ä4%ãyŠÅn@VÌü–0`š’Ùã÷”áUÜ7 qÎ3mÀVgûPùæ?ý¿¤DèÇ3^¹Œ?«rzÿÿ/>Â6HéHFS?Oô‡ñOø£wʽ`|ÚöPáÝ ñ8 ðÅe¥£VlÆpN+>i…ÛÝ…sô‰ïãÏHã|À[ 8/4—^…¿„åFìXÎ<Ä¥›FÓ¼–Ru£Ms¾e~ýÿ–4€¿;þ5ôÿsí/%ÿÿ°ð÷ÿ?Ø~¹–&ݹÉ<9ÿïÛGrïgb•"žXÊeòæ çÛ¯ôÿs~o aÌ¥p©„¶!¬RàWf(ó‡q,€Û:HZ‡)÷AsYD8 ™Å5š¤$Æaà,*ÞŠ"ì “åØsö Í&@7AA iO¨Pÿyîâê *F†d¹S2 $n¾t•ƒÇŠépâÐx&ÀÁá‚@Á]šÄ¼€0Øóyxî"æ ˜™Ž8ãªàÜ&¬¨b÷³Lb‚fP ¶!ˆî4-xIhŠaÅrÄÑRJ`ã“AÌÛ²9H­döbW„?ÇÝ(Þ™Z•P…¡¶c¾ •þ_e'~2þPiÙ„0ÿ‘ÿ Õg3ÉlB+¬AŽ5ëÿAü÷úîþ$ư7`]x϶´i~s #’ÑÊ´=bf$n>xUâ˜g¶RïðçT–ËbEPãôt¿ÁŸó¤q/<þ$Ø…’”á/fRì…ˆ‹ý —À-~®Åþz ð7Ç¿†þ²ýÅäÿÔþaòçkéÊŒ~±K€”Ë‹á6ù#+†ÏùÃŽKŽIQŒ»Ø‡&Iš÷ °| dd)ÎÿOX®Ãõ>ÈŠ‚?Ç@å&áÓŠ+ÿø\ôéýjü6@ÀÅ<\ç"›„ËÐEʳPAÒBO.Ó Ñé>g·/N $%Kwájp‹KPNÞ²ªØ(‹ðœ«rPµ¼ L¿.2åw|'Ž_±Øœ£ðÝâ(-_uD,Å¿H)b±ɬ¯à\ÑEÀ;‡hw9Åm‡ Ñ<”8õ—r Y1בB'Ç[‚e@ Ñ°"ZfÄ2±LLÉÑ7”\„=#Eê4ÿ×⟢LrH«1ö ·nU˜FøWºyùå4>%çæ§Är[1Í|º] ý?ì² ¿/nbÒ£ 8îL® ÿþ©X;yyðûµ8 ¤]Tõ@>^¬Ì ħE ÐÉó¢v¿é›å´Ùï㿞Û4È)µØ.•(wúWßÛÎG´8ü)\—D¾7ÁeýcÌ'â„J,ÇûÄfdR®¿x7øßÿúÿÉö—“ÿDø‡‰eû¥öÿÓâ ÊMþ Ï%¹Ü'¨úèäáÁo˜â\b•²Ámwvðõà«òõ±¥ïNzqµN8VAUX^Ïpò”q¾NÝÇü»Ú¬`Ë:®Ö‹(W4 È‹®36GbŽ” l7Ð8¦ª»_ÊQ/iÊTT÷ªâ&J‡_Õ‹ò~G°u0ËoS–Ò«H $¿ëæï±"õXèEq%[½e´è?­|U)23e\Ýìà%”†¬Œ£Ñø)œæ‹îŸ;)EË€óÿáñ‹å#ú_†Øš± ÿb±ÆõWâÏù%ÿol>eœ·"*¬üˆð¯ðWÅ}©*înï+‡ªÌ(î<þoæÿ'°³w¥¸€ g2e½òÇñO•’œ—Ê:”Åy^ÄoOSȼbù1ïú.ˆ ìÊ¥9üÑiÝY¬áò9ú?€?Éï3㢄”¯ÿ‚7ÅTßáÜd¬„Y¹™ÇŸÁa‚æ÷ËÒ|† ~Áû¦`Áð»Û¸ÜÅüÿþ5ôÿ³í/(ÿ\øgÊÿ_ª¤³¤PèƒÓ{p}K†£@Þ.ªÊ‘VŠxD 6Á Éï—âŒz’ÛðÌG÷íÍ¥êp›fª²þ]¼ä¸v*"WÞÝŠ 4à7ÙÚ¬£9¿¶Èpa/Åѽ{À¹Hbæ^_õƒ6pH'yoꃧ&f|é´ ÄB_àUrŠzczã6󿘪*œUpü¥m‚õºJ¦á†+—àï¸jÈ8 ‰¬8‰”÷‹qñ›`ZReîT.@ÄPh.wˆßDIV˜€äfŠ\-0)>¹pDX‚œR‘\ä!¦¤ ˆR*‘‘´D/ýW†S„¿¯ ¾aiü6°ÊižÅã}Qÿêþߪ9EïþÔ7éá<¯wö’}“î]Åqì§2%¬â ̬Æ?ƒó SÈ~úri8^ë®À®TÍÕèÁ¹ÛÈ€Ãj&Å¥î— ˆKõ/B‰r/ààOUº»¸mh¾}¼  þ\!ô+þÀ“®h§@p·£Ü´ˆk b‚#¸R™4¥Sƒ ýÿ²öW”ÿ?ªüCÅ?üJ ÅQáEÓÕŠürûpД/È×ñçJc]@äFWV "iº¢^ åîÀ(Kÿ+³e. a,åƒý<Ÿå6àü)gÎõÉyÜÅ.ŸAüï…Jâë,Ùà89.Éi¹2YŽóùÌHCF'™ß™Ìñ7)~Â"^nžÕØ ÇÃܼ ¢fŒÒ‹|”Š §®ÃÌt.ñ‡«ù‰ý\ê1.øbNJù:òb;£”Šs»yó UèÝz| —+óŽÓ|•©E2Ä/¬ƒebî2÷DØÛ,1)cÄÀ°bšãl`B'ï…»ô2(ɯ îwôñ¤•V2úÍW‘"¥üYlVñeU ÜÑÝÍ¿’-VóõrÆY[Íæ«r0#ü+x1ˆÝE¡^üZ<çÇðO§•›PH–Jå\tŸ¢]=h~»?M)+íºyó­nï>·x±×@‚ð' –Ó0þº?„¦Ò€'Ü€ à&çUøsåâ¥ÜMðøóßáLC¼I6’ĵ ùí‰ —/K = „¿dîüÿúÿéö×”ÿ?¦üsåÿ¯ÓÒYºÚƒ}ð?\,žàÃ`¬r«Y¥ ¸‘Þ¼_€ã}Ê¢(îÎA\¥3Féú缃|Il¹ú‘•ÀO`ÁÏÂ{j”¹¤ÕJŸ8†`^HÑ.óÁsMX±b)M8ûÒ®óvû`DÌ2VFø™*Ú‘QnH.™Ø/UÕ†ÒX1>™óoT˜7è''y5«¤ü®†$ä¸>'Ëg\yÇ­Ch‰ÔMäX…£Í3?K\R »ŒÏèær‚€”T$I‹†#vUp|q +ÁfšJŠ–$ ΀lV‰LÌ¥Y Ï"9îJº,üEø'³üD)¹}E,´’íWcñü¼ IoÞ.¬¾LäTéõ­pýòýñg„¥ÍÇñk|r7V®dÃæÕÒxOåösÞtYüøGmäœð\ý$ýd8@ùLÀÕdð3­`Íô‚¬H4ÓH!•ÏÝ)†Âøsûú®òÿ4~ œü†Ëb±ÅÛÐ(e@þ|èævÉpøKðZûJ+8—ÒpÀ$/ÅyÎE·$bx7*2ó°*¤õà«òå’¸zàÓ“1;@‚DF‰äˆwˆi©Í3éÿ´±ÏŠ_ƒÿ¦uLÕ6(eÎWå||“ë]! HgEÕCÞ8K‹² •V­üêÛœ/„•›—{Aøó µÒ&r=SÁ¹+r´i³5ßÅ?ƒÓàî“Âi‰} ’³N~hÙ’øù18w‹‹89+€Û/FrÀê+£,D-± cùˆ/ÿìÀÁßÎOÊ×ôã¼XÜ®¼3àü¹âÀpa-ÿT)ÅK@à6 ÒÓÓñ-ãÇÀðî6¼,ñÎBŒ?Åû,«Á¿†þÿß·¿¬üÿ®ðÛÄÿ¯ºð/ÑIÞáEQeýy›¿b ÿd`.ÝOù_«0~Ó_â×NáIó)³<á¶À7Oÿ±WpEWñã×»$-Â9Ò=l ƒcä܈HÒÑS.­pÔriû=)Þ.“¬¶< å÷NSÚl2 íGþÄ*z3(Q‰Êâ_ßx"9ŽÏT F áHV<ÕkîΤ•ÕY>iG‘) ¡iÎÁGè&[…Uò«J& ,M+Ÿ †'JÌ;@ÐGwU›@.,ðEv!à&‡ÛèŒúÉD %K J8?MÂÈfŠÒ ˆõþi„CÒ3Ký‡ ¦ÑʾŽz¥±‡ð¯˜ê*¯¯2ëšVžˆrð‘UúÑŸexÅmŒýbåJx<<ÙJ9ƒ÷‚ýŸøïõáž'6…ìdbÐ\#üi7OìÀO`á  «Ÿà³ÿhÎÿOrå*ñþ}nªÄ)³õ0à³ ÿt«u˜P”µ*«ƒ?…Lyt\ÆV‰?^áHìa¿Îÿ§)¾œ¢ Šæb€ Þ§¡wD¿Ä ü7Æ¿†þÿ íÿ´ƒüð@™Pxœì½\ÉÖjÄ„1`ΘQADÌŠ€ ’ ¨€äœ33Ó}º's’D¨¨°bE ‚1 è«î ûí½ÏûžÞݽKývÛ™éîJÿ:ùTÑ þÂÅÞÛûßÜ þïuä·D¼¯)?,îµ$'œ°nûÃÇ»ôZË™‘OÙ,±{¿Mé›Û ƇÙèœõ eåNϡ̖ùoúų!IoTòe×ÕF¦}‰@1Ó÷Ì ¯¦>uötó â½K—Ç&Õ^rzYßñ¾ë,ÜÖ.(Û“áDhîÌÁ’…ªSÙàÆ°In¼.;ŒS\°DëŒØÚ ±µë8[ÃØ3_ºZ&ÔM©¬}…w<<0­ðA“tåm³µÛöp®9ߟ±fnSLû·šžûl™‹ï듸;«`ì; Ãb ub<߉1#çF(V«²«&¾iÏ,ÜœT9"Ø"{ÅIõÐÁ‚DT§A“öþñ\г<òAA{V ÚOÅ•Ÿ.5 ¬^Ÿ¸€_Îîµöô”çNÓïÏ·©®ÞÐpúÖ"ÏáýûΣ‰í㎯|€çfzh“P¯J±Û€§ª[ÅÏžó>®!XÓ0mÿíöignÀ#é¸e'Ê @“`î›fœE.fBÖñ2Q‡pBE«‘4¯ JX·Y/0ÈN÷œÓ¯ÇÿTÓ¾ë¹S½4o*ì\ü°³·áèá$lŸ¹TÄýkƒº†VTÀf¹+Îê«•Ì=é×’ùÔñɧ!²Š$ «¹îâdD”^¿uÄJµ»½‡; ~'¡[sC‰Q¥é”Š%/Œ×zX¤¨*'›åª ³Â<’‡ÏR&áLúç#¡¸§MS5—ﺾâ¾Ï„å2ßwú]º÷ص÷´‹ÿÚ)o3/ŒËµ0mž=¹‘û¹wa«ööGœñðñL™edFòR»ÚåVëŸhr½´ËE/»±çÅxUÇx%d5`òù8¸÷pÀR/Xpðv؃‹ ~ÿÛŸÉNžª"Âã½KË_gçõdêŠ4çSßáiëb¤öƆW ðÏXv*¥\„¿g6€ºo@؆Õ–;%†Ç/Ø—åæ³n{# ¢Ü€ÂŸkvܼÿúÿGËpò_Üq ü¯väµÜo,‚ë*ƒ<@yŠ˜ìΦ¥×¢?÷"Ìû®^Ç|³']ˆÖ4‡ŒsX鱌€ÀJȉIÌG…:ÃÁ…9`Lÿ½}çÞXãSÁÛÔ BAW¶ôÌÔ:w°õrŸ6ª·¤lçë}rà]ûQŸYÐ'Îí‘ûðÞLãv‘Ï“îOââK6 ƒÜ«l± Ë¥./“ \š EVO÷Ùõ\n”=ÙÕ{6Ôš5ßm•ÁÏ)‰~²ÃÏk¯9—2Âù‰Â8½WAC:ÍÓ«„ÔÓvWŠ“Ú#*9û&»iãâWt¦¾Ï0›£:¾°OÔ÷4´nS5Úk;¢% ´oKXÔ+ö½{íã’ÑÆ™Yæë¶WAôbò ¿ž/À»dËg!Vc DýXWÇÅ®)q8“‡Ï‘™Þ64`¸¬¨Ó%n‘k›4‡äœ.d«³Çc_Ï7šðêTÚ›P¡ü3æ0/ywþñ€–÷ÑYyªJ{ ÚbÍo‹&ÊÍ€¼ÊÐ*÷ë´®AæâqßPž¡mnؤ95î^Äõwo*‰øŠÔNøÀØáþZñWãÿôî>¸™:a}>0çÝÞ–¨Ù Е"“Ú¹Œÿà³7ørXZñ—o¸\£ã'œ„k”o³=h¸4ŸÑY6SÁæù®çOYCsÍ•Ý> p~W4lÞp9-FõU¸ÛqX÷o;ÜfqË•` ÿc'Ï)OK%„Þ±¾9„‹‡Ï)‡Å+ªÚ„¥–-Ê-ƒÖK2vc¶vjýkü›ÄÜY¥óÞϧ?ÄÎ^=#‚]™¡¢×Åûó~ûxÆëäÕ }DE^ø¤È ßW½B>)ö‚eV“kÔ£ˆ64ÞfÐ\×xý‚ÇHƒœ!i•­bA?†ÿØ-̆;Ü;Þ™M0£dbÎØ´ëF~?àœéžéù ¼ÑÐ?v÷#KZ‹Âÿ‘S”EH× Øm‰û&)WÃË­)b€’WÎÞìÔóyÑ÷©Ñƒÿ¿Á¿‡þÿ ³Žüãž¼ÿnG¾-,öŸ×öÏ.Ê·WŽï•h쮓Ìû”ž)ÊkO3ûò>ÞТVT¸íÐQbk_mìÞ2ðóU·ÁYZíK®6Lͳ˜±JxÒEÀð›+À[£Ù¶!CªSZßLþøêÓ±å~'÷ïÖ*è¼åeçHCäŠcvŸöîYa,Qe,}ó¾ªÁ˜§£Î,Ú[>[$ K/FºM8|É+ÙbˆüróI+ÏtõëXør[ë°SÓãƒÌýÅð›|~¶ª-ÅÙßmS ÷®N?“,Þ\_íXÅ™jñÛæ{ÊẠ́׬3ªZ0 ÂÍr¼âÙ;3+$ÞKtÙÊ xZ) ¨À{Ûפ9_3}ùÎâ¶‹SÃ(n²ä„¤¨úb™¡“ˆùÅÍ ‡ç{$‘Ñ8ÓLßrˆhWy¼¥Õ î5?9;NÏŸ,Ô)¶„¥ws•Ó”5ÿ+üÉ^í>Çã2.zà’é‡g|Jž”{xø«{ý½#—íRafúfI•|,©Š;?ùäÆD]ÎÜZ‡Mça³¿ÂüöEJµÇ¡ÂJ‰„ÀÂV}ë­~Œ¬‡LÀ;K÷Ù¢¼_± c‹wÍ÷ø·ú›·ÎCæ‹<£ÔŒÄ÷åG(ü… ³:„°E[@Yêâ[ÑÃõöÉ}'íkvÿ,„¿î‡˜l ±ü{èÿ]Ü<ƒþàWË¡ô”ÿ¬t(‹pC6þ–‰±5™¿¿ø1ÿH`iÿdˆÌ)Ìy™¢wà¡— _wMèýæ£ïAL÷A&x䪮/æaŸØ¥¬ŽšÑrn9wѪ5/'„Í|µ¸öM¬¶ƒiF§ûNkekÇ_úíÁü,Ö‡‘™¢ãª>ŘIú”ÃcQ(-V[š¾Ý2ê¨ý:çÜÈ,å³Ïr°–»E%Í·"tqÊSÒo5ñ”=ò gUˆô§ª¹c†-?iÿÄt@‹Í)àûœ—9¬ÙyÔ+7òà¤aR¹5ë¥5K–÷•vö¯—Ë‘6ð½EÌg±úWæ‚Åê3ú‹¸ µšÑkGnŠiN–‘jÚ˜zë+l~7ÀÁßÕRA¿×Ž‘9EGd•«¶æ5‰;²p#¥››s‚>¼wõ]¿ôQpßÑÕ0(hò“BŽ’×ç=FóYj£ðl„+ˆI·G/M娕5Ë¥S;޹¿¾úò­ýSLQAæÆð¡*÷§'º±Í@δ6ÚýV¿ ówc:›‚ |ŸäQºtÌmõ¥_ŠÿÌ{ÁÍ©ÀÒ˜ë8$žáoF*½åk8U“®ìüA"&iÛóýJáîô cÜšàø½ ÛÁ£@Mî$?óÌ}lDÍ—AKS?Ý:*újò¦=;÷@Hkñ9žcGòX[¹9%ƒß«Y“Á~^•“2ÿ¦ÉƧ½¾ãdqH‡—åËENV¹|t§ÝÎ#»ǶÕuJáýZö 'ÞûcüïÌšVÌ:eÚ¼nqQ,÷rçX¼ïÂÓkKì´¼A!#r²¨6çæð>vÖáµÏoš†Fïq…ú~)P{=bôB¶uDt¨ø¼Uʹ¾X{Qæ-,oóâ¿@f÷z¤±¿7ZÿÒ1S;̧M} 7_ô{ü›Å÷ž¶Úß¼z%G€¿Âü¨ ù¯|þ–Wņ5NÖ÷rcã0¿(†€ký2àÁ„]±ÀÜãyÀPû¸tþ=ôÿÏ.¶þÿÇÖÇø3zòß,6aÿVŸ¾pŒ]êÉ9èF據¡ R³Q~_ª¸8°,Ì"À³¦kf|;.~gñ다½ŽDÂÁÐÆ[¶ËÛÞ×›½m¯4Œ€²–ëØg?ê8^Ñ€#÷îGå’âthS•ñ†à ôÄNÔ©º:¢ìžéÕiy—ão²UOð¶‰LRý᪪ˆ¦×CzøÖŒíž+ߨ5ΨY0ƒ¼³ùsÇå]á%ÙƒJÅ *žÜ„óR êÑ<ѳòÂ-jòËö°Æ¿Õêd—Ìê¨ÜüŒ ž½ûû[¶Ü¸8¼÷åyZ‡ýÅ/›Ç¸¼o˜dñ~RðÜZó°hç+Uçb |‘?lΛ tO’9Ðøã–Š‹3Þ|0Ì!ઌW–*mƒÌc ^?>™Ò«“Þ2…Ÿ¾í>ÛXSÝ¿ñ`–ÃH€ ø©»S>…¶Cl¼Ñç0Ëe‰ Å%±ïgæ=Yðéqoù÷†ÆÉâ¨óŠ —‡.—•Þ?o¢ãhs86vÄzH+žáéîMb’güVŸá0Í혙ÄÔùÒ¿ÿ¢¦r€í“æ¤÷*‰5ÁíšYÓ|a­oÅlñy½o´—ð–V0h_ÊÊÑì<’ø`q›z Kó¬³ZÕܺv¶®J#üöª?ÕÉq ¸½¿uΞ~àdu‹u¢@âÈQ®óJ>ê ¨º/Æ»èUç~j6Çj¯9’Û«tpªzSIz°žHïE‡ÂÙÌÛ{oÊ·¸0ªRÿœÑà/é".îGuÌ£±íû=‘Ûu£ë ÞTŸŽþÛ/e„¿Ë1mæBŽ¡Øbºyû«½Ø yeZTùöÌtžæµEzû™Äê3ýÏ5«@\WU ¸ŸØ ÊGKz²ÓÿdïO·ž†[Ìý±Qãù`Ü–Xr)uó0ÇïñI *.ƉŽåªüG-«c•PøëÞ*3˜*+-³ïfæh€è±Ç’Aj1µObrY~K/½ ÛþCÕföàßCÿÿèbù;qÿg›ÿîÿ&1ñïU\÷[i:#¢ËL_W²Wè¶m°·Æ¿†óŠ..Þõ£ócd;Û$÷žV«®5H~OH£vBRì3íú˜ ,¯’®" v§$íãW7ñͧ¦9R‰NÊ>‡œ±€lì>À‚îÜ¥óË2þþ¢­‹ö2T[Uê4µ²|ä…IÈ-4 &iìga“¯Ù»nÉóùWSWßV>_Èìkmsgùì[m»—,½äqj“Ó©«zû?Bö›jnˆJî.mÓkç¦'.0Ì|l?Š?à#Ò/‚ë¤B(L5XªD2¶'“ ß}ÿ‡þöyøÛa€U‡·§ïoªA [×(.¸$¼ê”-­ïŸgnß[A ‡D«N‚s’ îQ ,qâ.ÀûìGÎÓº“ž»ºÿó™&6[J”ÊÞ¾@ïè©=£¡cÉVÃW¯‹ÔŠ—œù–;ÔB¬ùlÛÔr©uC!éÂÒÑÆ¶¦cázÇ”•* ´ñÅ9w…Ri†»çƒË¯u›_jÞÓVfç®òU¨t«ã~ÈsZqyÎvb?;HQêÝÆ“ ã‚Ý<Ô¶7Îåð[yßA* ËÃO-æÒÖÝ®ƒý*øÝÁðæ³‹[±LÒã‡tÖB‡jÍc Ïô{7SÆé6ÉÌSüÊà„sφmššÐýGo#î»}]3¢ŒÎõÙW1ÎùÙ¨v“ËûbfÀd»'FäÈÛÃg¨ØYåL½ÄŠÊÙ'ªxJeâ}9WΕܰm29xYØI26 àtF[ã4¦c¢‘ýä¬cð›0#(]ª$ìÒk”V«}¿ÛÉÛÕ› ‰8\ÑÍ|Ýéµs«ËwK?ÕòS{×EYX˜g²çù/¥u¸¢´ÝÓkÑîŠ P{þ¦ ÎÏ)˘ ‘¶L£¦$« Ô–˜![} Æüaü™Í“±†÷Ý]³íŒÖŒ Šìuñ1ssfÿ‡ßã¿ì™î²Š‹ï¿“:X€¿±}Ħ‰Cõ)ü³tçF!ü`ènëùVê…›tžNñŸòªü¾¼þl㜒ð0`¦yÛ‹võàßCÿÿèâ‚|ýÒ“üÿ³ÊêË»âàŠÏ#/†í"p£¿bBEšãK7M?pN¹2ÀóòD^Ñ‚ï²@õ£ÿ|€ºk#…§ÈÅv]8|%Œ•¶Ÿ²¤o†€ûgæP`UûõOÅ®SáN®¬Û1Ö0˜ìo¯²¬â@Ô^¤: ZfÈÄ^‹ß5{(ÙX-qH%Âqå¹Ð \ »z%®WÚ1 &ùÆo[BÉü¥Ç‘U{ï;0J}TöëGP—1zúx·+ÓãA7Dh”¡Xƒlyµ4Ëž7¤ß:É‘ °§Š¡5Ú©=º2®þ@åVIÑùãö¼—Þ7~Ó£ýJŽù çÙÎ0íu3§ºäÞ±ÙÃ6¸àìH¶F& ñ“`—£Æ_,|‘gxkâØýu7¥ŽË?—=¶Xᦋ¯¦ô*Þÿ`ël°7j™îO¾Ïvë®ý†ì~·iÑÊɶA÷ë[·™7…;Çû¼xÏ0+ÜòÀfM˜+ólǘÅ>à)Ø?œ½­fÿU“³#£AÈïÅE)›0Ãx[^®|Ô€Ki4 äO<õkð*Ku7ý ñj„« ¸¬êšçôHÖ#üá®<ð¨¡t…ùîÙê”ñ,Œ<ޏ`åÑŸÓú\*ëcÓ <ßï™(še…¾À`¤Øú`Û£BA¢ÞÑBâ+ ]5j¾’›«²Á鸈¸qïÌ…ûý áƒNöÏ7ddwõ³}oµ`B/ë©°¨|ñѱl/œwPýåM¼”©žµþÔwø›<¶pÀ5¿²]¸ü¾Þãg–ÛT«™¶uö¹np*ÌÚ÷a-Kr‹œ–ÜQëÐ2Õþã OlYôÔ‡_ÒÛt}ÕÆsúQÚ®iz{uS©®âÓyjÔ"¼Zâ‡ñ·p†ñc‘…¨öbÒ~pÜÛÙ9þ»Œõí¾ÇwÍÕì /À?Ðý,_ Idl«QéZ¡5Ya"@ÍÝ«ÖÁ6« ây¶4þ¢µ™–.×'îÝ¿ðHþ=ôÿ.ÖÁÁ'ÛÐ?µ#tqø£¬Ä¿_ñðz80ÊN¾¢woɕ޿'†x æãÛ| ¨2#Î#>€SNôZÜr?ìú šÇûn=ú¬¤æËŒŒH,„ºŽ´ %o®êÎZÒbž¿C[x®«a]|èJíäÛõ9SâÛ&M½5Ud›Sxа»b¡2ôŠ¬Î‹÷þ¶Åj´$áé`üéÕeVËÐu2EË.@jÁ `Ä($_X}Å×yx}êþyJkß)ôóÑH Ün¸ëžeܘëOÇ8=V±rHš°[HÔ­÷0ÀHÂW¥•ðxW2+ÆóÓɰÊú ?(¢‡]˜õyÿ¼@¢ÏGgùÂÙÊ#–œÔ‘„ä ¾nsyì¹£L:é=ZøË¼&¡1÷ÐøUÆ©`4_ ®ô">Ô?«_˜]ÅK§½|ÁÁäfc¸ R_vÍQ˜,vÏË–wܼOËÇW ¶fŒ_“ÓË„-:Mì¸â+¡ ¦­Oƒ–Öí=ÇÈ`7üÃ’ŽÚ¼Í…&\¨˜Tn¾!<Õw¦Ñ#£€}£¯>2+< £çø¼Ö$¯h¿ê “÷åFú¤x+ñWàïÌÙåï㺊áSð÷|RßkX£ŸãØ…JŒ¹j¸Þ_· Ü›ß €¥¶û³˜•2Hõâá³ð`Áˆv€zÊÉðr@ÖÒ”%^Awvi œ#Vê”éãò "}NäþV0äx”Öím>5÷z¹që5ÖM?²-+´^êÚÒ#ÍOœqg5?ðDÄ)cn× œY 6ÉŽ 3Å|aýÔ1i“Ž?ˆlj»Ëã$¬<šðÿ¡<¥tlR±\а©n>úCÆÀq–fŒ)SRnÄa-5Ù1Àœt¤À1û7c¡8¸1"p™Q§‹Ìh~&ÖP/¿sѳ®eËð2ÿæüßà¡’®=AãÿôüÊ!?Œú>‘ýP|EI(-Å¢k}j¥ßI&çê¦åßã?æ©}Û$Œz´fŠr7þ{}~þ9ŠÂßúe¬Z‚áæR¸úhcC*,ñy«X¶‹[sÚD„ ó ÀÊýŠeŒ/{ðï¡ÿrÁ-£øÜ?·#ÿ[eBäÄé!¦·d­“?OQ „M#å6ÅAÁàâMsBçk¼/ËMÚãÁ#ÖNÆò}œ›r¬¾¼›è’½á©›¨e4ê”ÖK¶õú}¹À0-6Ø6e0ÚÇEî«—àXÒ~6ŸË—\Qî¼+¬ä£¦WÜç^-‰›*S§ž4^ÖãnçÍ6ÚŠ¿Î|~i8©[¸â°)Áb†\‡¾޾֮N9 ¼#í%oÌWs1΀^»¹Ñ±9"I,ÓZIãtïÉ ÛÍ›ÞS Ö]Q#`Ùõ_¾³ ®°½ÅÖ×áí(›JbÞ°e¦ô¼R¸ÿ)UœîÜX“§‡9»×Ý$=wR/Vè‹´”py8×)УYìQêçÛã”Ï­”oænÞ#. 0ÿlH0TNô&ÀtɵhpÒô< î[ñìà-ƒœÅŸž\K¯âØ¡¼5³®Çž\{)³¥·–ÈÄ W#haЏjÝÕY|CHébl".rí’‘¥šžÃ’'×uÚ‹nvãoq¹òóáM£B3 ¥3—ïÞ7Ïùqß®˜æO¶¡V[.|ë´Z¶ù=\Á|ð^7êþÔûDÐÔ^Ê!Ü=#ͦsOiõ&[X/]yüvñ [¢¢|ý–ì’&Kwþ0þa_Èœ±JT‰Æ§é¼ôÓz™Åç³K§}¿ñΪå`CÍVåH!ÀŸc…Y°â")üô¬Gøäù@løÆ@#UÝm/4V¯37šùðegL h'ÜX=ø÷Ðÿ?»0©¤x‹¨?»ÿQù3O*ø-W_W/˲'BA®}Ì!oxT©<\oÎs#P¨º0#C›NÅ{ñºD“I«ŸFYo‹»×o ¿Zc!ÜrÀ LnŸ7L¿up7@E×cmÂBd`gŸ~J2z œEÑId]¯Ê[ß1¸Q1wqoøx¦„áEK \az5l è˜é‡Ù±´Óo…/¼`ކ“ØøÌóËoÎ…àkÆ“ÈÐîœhË®¤¼¦|.cÎExØxîw2̲ÚZr5—ƒÛkT²·sͧ릨=%+D'^HúÄ·ŸXÓ×LA\í—»)ß)8à°œ­·ßάŠå›Â½‡ÅÕbmb³XÄ–®žßÏF&Ðà )N~Ôø¡ljÍÈ$ ^íüØÛR÷Õ5ó7¹Þd»%?_Jeó;GèÜÿÂ>x¬Á1ñ÷‡Þþ¦ñ8jùE™ÖCRX 3 ^#‹GˆWJcœZÆ0Ÿ$š~&ôQ²q*[·¬m”šøí­ýãßÞ#ÄÔž—¿ð‰^›ê³õD®Ét“9Ò0=ÞìþdN|ôÇþ“«§œÝòàrâ¨ŸŽ¿í™Eõ¾£AwÈz-Hš\]]‘*Ýhº}’jžcÏ*ÂCmæÞ(9½Õlë»1¬-ºáç!dU €£É\˜=éTÀ[ÝÙûL4½\ZO„5vפzÍÕ¯Lc÷ˆ=¿µþ·‹±©¼„·ŽbL·{þW°›6m“IàÛŒF ñãø{3f¹#>_×’0]õTzlPÅm‹¶ÅQ¿Ç¿wÚ†Í*8<¨qÛXþwõóZÆÉóñ´!@í9ÜkS8“ ÆÍÄ÷ —òÃ5CM8ÙÐÙï³jUï+£3K{ðï¡ÿvqäø²È¿ÆÞ?ëð|𯬯䲔]ÌÌ%[T×O°½w lÒ#JܧlYÓvïgqÀdáÒqÉŽ1ç/–…8xÇ€dê€Vó² ÀìzlØx‘ì´¶C‡ÔªèÝ[Ê«#í¾/ÞVTÆ}ÒÞ€ôœ9 (9:Ç "6‡‚_§ûg;‰²wâá")E3F©¸I°¼]kÖ¼Çá-[¦Õ½r¯ºç^t@|c­Çám3fm«%vV &¤@J2u Vf­çµØJ©›¥¶fvh…7 ¸®pa”?äŶïŽy¼Í"syÿMáµK…Ï>¼§<§q‡¾ïJÃ'ÜqV“”ÿˆÓOæxÝû¼ :Œ7â¡ù\ù{+ä$´ßñ*?q£ãŠãÛµÊC9¯rNƒÉùǺ²1¦Cúa¸eÌØæV§iŠæ×Ìû(ì¶Þå¸î¬Ãm…C%£Ê6˜ùÆûÔ„™'úžÖ~sD'ÌNª¹¸Å œ|RÖ-:ý–Eÿ¾$qTGÔ‹²\¼|mј¤ý.FÍ_柗+AtQúŒ$é¤&Õh¥#1ìUßÎOW%¯í“–õÈ)žè@Hk¿ÓŸê¬´lN£ðÄpA#CËmÁ@68Ä<ýæ~ËûüoÙÊÁ0½óÍ}õ­Éð`RçñÚMÖ¥ý«îö°u§ïÐ!)GÉ<*dâ wEõÊv‰À9©—¡ã; ôvíîpå ëk`‰_\šÏñ<?;xÅñ½#%e§j¿›u'Áãè XŸ6gÄÖokÂ)ÙÒçãûÌ'<Ó %¢—ÒVÔç‚Ë…ox7eçÞ㮵o¡a»|jÄÙ5í­‰0qÞaÙìLO›¹­Âk«äE`í·/½mà"«0„è½}‡º#®‹½ÞvÌ$ЈWtPø€ýÒ+«ž;M*"}[¶|úð‡7Âf ˆ'‹dÇÍ{o&)¬Cæm”ªÙÊù=þ8se¦ê¦”ÎJbð'Î%–1J¥ðGô—ÊFø#úÈ×µH4Á¢«”œ /oÚJ(=•gi0ÎήàÄZ÷àßCÿÿèb‰ÿ…Åé¯ÿûÛ_çϬŒød×÷Ô‹¾A !RÞ Ð•³øÕQYdÕœö‘ B“ûM|_¼D)mÛ`¤€‘ÏEpeDמTT®Ú¶ô8.T\Î#ôõ÷[ý„/Oeo[aZy Ÿ4ïØ`Ø—{¨%l‘ÿÀÕ§nï+btÊLàÝ káw…##êâBÿ×BÞ MYæ®S2§¸§ÇT 8×7G¥j(¤ó.zµ|>EI ïn“A+7y:sí't‚¬¢ÃÛ¿ùK%0%LÜo)k^w6%5’Ë$-OM|ø®ëdÿí÷ ‚ø¾W[矒9“°ù=çã‘‹Ç…f܃֌fÙxv1ÁqOd˜ ˱º†_1]»¦2 =„œe"±þÅP?›tV?æX¬Ê®Z¼8# îpœGCժǵ׆5ØÍ.o¨¬œ\CÜ-•W •u³­ÅýTì:¥šµ1`Þô¥Âý,eW–çm𪟷÷7‹(Ï3jGäÇZf8ì×ó“Ó×¾5ž$û<"e½E½{ï3Gbª·i ¾?¢øÛ ¾;ºYQý§‚XÓŽKíÚzÒŽ^!ßxAªk}°ë‚+ŸúLÔi3¼iP9ÏûÜÉ ®Ãv§bb‡ÃaŒ«m~°DÞÕ·m’¡@ëÂ~7?ÄõZñ²‘±wWé¥ú3ñ'È´J7dÊ`ÁËMkËA&³“ZÑ»«0»jÚ“±úÚ‘ð_d"ÖК%’P«À2ï«+Ë+˜·WéÄ»¡3Ìn&@õš®17ïy:B¢•Òø|£¶=²ÍR•3J%j–8oÉ¿°¶£cMQ¼•S< Óü(ôî{¯JSß蛨h+¡ùà?^dœ²5׎úM¬ ~•ÙýŸ'8`·?>a[ªuÎ‘ŠæÉŽÝøËôQÜœ¿rÿ§Xá]L˜˜IôŸºµKJtí<‚½×”¹šœîW×iÚº´#âå箾»â|¡ÿúÿ'§ðp ù³{A—¿²cÿ‹çÂøçjHý]`\Qu£<ÀŒ¤A’dÁ°‚ykÕˆ‚Ùyဪ,0ª“}^ÂZ°¡è6€VÍ2„NURŒ½ëçw4¤`©ÈÕ€¼°{I<²”'p09ðZõÁC0y?Û @Q¡ µâp7X')d³_ó£ú«À~Â3o¸½'˜­îò§ruÊvïõÒ.r˜"©¡k R6hÿÛz+¸ÛPêJéó/y¨O99=õÁ¼®Æv»$™©NÒã€>®×µ±ûûú_ݱugk×åšÑN,³Î훬dFª€1Q³=x‡Wý,Ÿª©×'‡À™ªr1á°õÕ!XCâøtõ(cÏ·TôÆ÷*$8¥Š{>(¶š{Ɗ˵y˜v']9å.+å×ÇfÛN¨ 4°0ýôr½&¹½ÃO]œò(8ªåëºHxÒ«S-0K©Â°hw'§HŽk G÷–rÕÛ!bK½‰á~²%Ê?“â&ó·@¨qíߟÚþ‡Z݉á‡Ï_Ô˜Ù5¶ˆxM8t—£õï}ÐùF\*&g×ïñ®ÓΗ?~l¤1.ìÆßªtWœSÉŒj ÿ#õ·f{#üÃwäh%Iw#'fXõò·¥ñ¿gË–œh{ºÙo}Ùš4þ:Íkzèÿ[øQ÷û—ÿË/û‹Cùoj´«võgT£&Vl5Ñ}í6Œ[«ÂneK›Á“^8MQÑ’IÀ–ûc¹&˜w`î–¾íþÒºSn½…1™—&8ÜŽ…;›\“Ä‹«TA~VŸSKˆâŸ5Þ¹³tУå+Úö/«Q¸¤éÅ™£‰WÓ9âÕE*0úá‘×'x™Ý·ç³ìJ9‘k%qiŸ°YHàëZÝÓJ¤cÝ¥Ž•Ä“¦w~K>õ1 É\±¥`ä“ߎ>ƒx9;ÄN2=áàë²00ÀÎ2Ž›ì¼;Kïñ6GKnë¶læ`꥓ +íwL{æ{²h «uµëè€Æ5gÌŠt‰^ÕåâüT¯ló{é6®Ä^·‡Æs’ “^8H»)™ûnEeC.6lAÊn95y´ªiËE±iž:>*©rö.žëEéÑãVí]°L÷Åó˜k²à¼ð`lÔ»:™£!­°šÛ;–w[ôÞ ñ !L›…Í ÃnçX8y4t®‘ÝÆž¹9ƒµÄÔÄ(à°yñêBÏñfö¶õ™Á™´d³R5±Òb¬3Tºögá_óø˜Ù‡) Ñ ·—^˜6ûé§´›p¿ìÞ±]X_19j¦/»š#«+†¤}åúʲ·A–Ý[{ÿ,ÈéRA¡¼Û/ƒ`ê¹úQa‹ ÕÒöéÍ~Ñ8‚x¸äÌåyoNß9cµ“s™ 3£JÅ ¹m’±ÓæçÛ@Îý,ï¼zV´xÕþ=½:v•hĽÎZ¾·U}ŽÉ4¼ÿ’õÙG'ÃØjò U±Üé™qö-*:À›vŠ8µ^%+Á˜…qqkŸ¹´z»JÜm:™à4NòhÁ ‹Òs:Ï_²]_½eW^Û6¼M;#“E‚‹æE•­ˆŒŽgþøcÙ[vG?ü¨T9V{ C¹Ý—ìÿ{ük„õWp™Ï‹Ö?÷yÌûëËÌ)ü£Ô^ô/\Æn´¸ê¶ÄÔÃWó0ÌË—8£{u’Y§]pÖ³éR["ãȵ±îøÚËÿ\üµ~¸îrýÿœrògUô+Ê¿=åÿkdþÊòsC}XŠHð`ù8 Ð:Å1#Œ$g² ô#ÇIÁWÄ0ÀØõ Îr %p g£;?ô Á¢EŸ0§þn“T}Ôwê6áN°Ø,6ÁÄÝõ6“PsOŠô †ÁÃFßwŸ‡ú“Ï,‚»oAú 6°€pÝ–Ê!™ÜjgU§ÍŽ<´pÂ]ã—j¨v pá~I‘¡ZBtþ}á¯(ª%ô §FDýïûÒw€°Œ¦ÆŠ~Ä-鱡N  õšÁAï£1¡Ú06kðfBÀ$?)_&“æk®„7ußáÿ…»ò_ÃIø*>¾raOO~ ®\6_°à`hž_àÀ íÀƒðEr€ÃŽ—‰´N7Õ|t—ÅrfS^e´ ™¶¡H £i´˜¤ 82†ÓÒ•dµ2‹¥à iüyFÁMüþhÅ#üI„"Ηû\þ{ü‘jD‰œ½Q€¿‡?ºÃäRøS•±p.°0=±”€D3ƒË’áHþ£>R.¿ü{èÿ×–¿¸üÿ× ÀŸ)ÿÿ‹mÿj §x#n…ˆ‚ÉEãb‘Ý6?ß¾§lvŠAÑôÐMh5vl¦]§Û9ÀW øš}!»5&›Oˆi²y¨Û6Mb¨.'탡ü©Ê=¹®jÁéˆöhãŒâ®Lr·%d|vN±k<¤¤<äÒüGý8ýn¯“àätøÈ0œ‚IªR7¾!øÅù½UC%›GÑZ¬´”Fý4‹fSv9öƒø¡Ÿ‚ºµ]g_ÿ=þ‚(sŸÉǧ¨ƒ|çª1~ZKæ÷ ')—Î'5„?ªœ ØÆü{èÿ–¿ºüÿWÀ?Ãü§Ê¯ÕŠ)ÆÈ¦è Z°ƒÀæ§<“ôò¥%3e,ÑA1HJ§ä3Sã°|#ìéÿƒ´dÄâSCÎæ‡ øNXÂ6˜°Š¢Ÿ¢¬(–b|"A{B)õ€Eºª¦™&¥@#ªEŠ7ÎBÃc‘çÆ0=ß8DL8x¨äÒ®Jåô@ÚL8æFþA¾˜|£œ»ú|åJ|ÿŸÀK)0q(nÀt¡ÎsV*@£¦‰ÝÕç«=N~Ô1d§¡±"VSƃvZDÝüJÙçvóGzØÈ¤„nÆÆ± ¥æ‘i‰¦‹&’I›h& ¶-Ø ’Ë Œó8LªnƒàPLý¦ðKñ/LÓ9ˆ/(q|wè7lŸoÕá_&ŽzáÏû–Ùµù¼õIÒíF¼áÿ…c›cø-ÐÖ áªå{ø[ D¯?•?Æ¿D²WÈ @¬Ú^;Û ‚8”q†ÀpǽIÚJç»Õ]¼J6ÿ‚ÖZl@"BÉYÊúB³\‚Ћò?ˆ?ßceMÒÞbê}Ò>£|gßâOtë¨FþÖá$éÎ%)ý ¿Æm‡c!Mšil|ÚwÆ77©w{ðï¡ÿ_Wþúòÿ5€›ð¿Q¾j8¿R üÿˆ"nèJzóÙUw¥ P.œ´g î <ü˜Ÿ·§{ åO£êÍÃø^Ú´á+ »;fÀDôájOÒ5àˆ´ (‹L @º©ù]FnYlú“«bSTÎuwXˆR"©$GM‘±i¢8†Z†ziÊæ+õ¾œîÄ ³˜¯œì‹ÿz°Ûð /”GÓÝÿâÿ£â¨|ÅfÒ2„v&cð¤ªvôv¤LIáƒjäÐV$¥ÛÍ€G8Ã)“gØ…¡WQ]4 8L’ò¿ ;iG\`p˜\d=(õ'Jy\â7Ã]íâŸÿÅ=Šðÿjó d·W` îÒWþÿÂõû‡®`êâfO|¹á°#‡ ÍËnëÏë( ™À=+è„›æàŸ‹Ðdš!óž¹ù¨/º‡XZ3LJr"üù^J5¥mn$÷Š-ñýÿÔƒ¨ôB¥bT¸+áEº{ÿ þê˜?Aé”b¨ˆø§L~.‚Ü&œï@#(šA*.Iðýÿ”.‚zLG“N R”/äç àî›{ðï¡ÿ_TþòÿÄýŸmþÿ—Ûÿu@É7}ë@.•ÅGÉ^Ú”¡<8?ºÿ%¦ßmé;>tˆÓ‡×-âùŽÄòèçù>Â/Ùˆ9"ªÅÀÅ›ãÉôf ÀŠ+Óæ>"5ï,*e‘N)Ð,‚bˆ”Ùf­Iqôw:°‹á.šy´»as&åzSaQþ8†zž@§•s«AFç€oÙ‰Àÿ'HÛùÆ3ˆŒ6‡J`¤Y‹Ã2IAIgzQ…HY>OØÎ<:ݨ›‘ 1æÂÐô¤¡W_ŹËÕÊ òdøÀ¡ªe ;\q † GŸˆâYvÑ œMºx±ÁÓË,'HÒbç/ÿà›(©u¾áó_ÂÀ߯}»çË…Jš£X ¾cùD7_l¾o²¯Ð|Qøû‚WvúÇ â¾|ë“õÅŠÌ(mZµîÿÁ¿ˆ2Ó0Å£þ¨eFL†j! e‘L,«š_ãÈÀw Ä)—1‹r½£…ÆâR«˜’Ú,¾_J´*0õ£øŸä“Ÿò‹á$íÌG·¿ÇŸJr¡_¡¤ÜÓßüZ-íð÷äòÍ}O*ÙÆ>œjÁÅÕÆ¶ ÇéØlëÁ¿‡þIù{Èÿß+¶øÿ¯—_¦”  hu—btŽ2ãû4~tŸÊrÂùýˆÜ]BIA^ MtgýôFÊ'JüäY ³¬)…™oó[…R…«Àâ Ç|q6?QšI¸«qr1Ê$Cš>e– Ò0š­(3á¨/ê›GþPÅ—ìwQd覙EuÑi[ž`YðU{O·ANAìö`‚Àÿ×mÒߘ)˜M­zðDç´Gã÷©%8›[°i¿=dÜ6„üâÁDﱩ“iʼnRzØ ¼;݈Òù©E”îäÅC³'è&(€ŒÅ!=ÙL7?0w×(}è®'ù À_¾”ýBçhÿ. Ì7`¾Lý£‡K!È ³ !~ïúØsÄwv!}±¢s³\¼¸|ž¨œé‡Ýæž›™ Ý ,M\`â*Ø÷øB“ÏpÚ^D08nª¹ˆ™‚“fN¥äQ¡%2œÜÝý9L6‰VAÉu L qSÿŸ6Ó(—.PÁw¾v˲ñûQü‘G«ÍþÔz'¨lVJoýÿîh¢ ¦’pây##áO}#is“ŽVÐ ²RLÉw×04¾ë ÇYÀßÿúÿIåo"ÿ§üãäÿ/Ó ØاÖ3%ûÝüép>}'ȤCœ?Ë™&†C(§MzŠs±l"Én/?ÍÍè]´7“²‹ø›is‹áFÐÏ`æQt¦“æNG×Ѓ®jD>§ƒ´t”§cÝYTL\ — 4ç&õÍòè%°9•:JÇžRÿÉíN¹‚˜#Ô}W6¯›%}›Ôíÿë6o”ýÕGÌÿ7 ß8ùí|#˜aînÉ7Î4ÒyßXC~ëaþ.M gmùÿ" äåæÔPÔï6E”͵Ý16¼ø¸Q~¤–HÉb>„,ŽÀž~ºöT¡ã ?Œ?-(G1Ó:R`Ïc8bðþ”drèÍ~LþˆÖ,#Ø|-™IG…©l3þ†D*‘Ž@óƒÿòɱ¨çˆ¼{ðï¡ÿŸ_þ6òÿ[ ௠þÿû}ø%@1?°qºm~Ž÷÷©ÿìî¯ôæ@&›eÎîîó¯î _Zi Ÿ¦ÞâðC´üïŽ „xã$í)@F‘S úÕ&K%¹xøaஆL’N$éôlÊ…æîÉõbÓiH{pQGÚ Õ°6eq)òål*޶ù(µ”RÃøYGtøŽÏ‹ìØÝ–ËW[æ c¡S³ŽüêÁÄxôø©ý9.”·Ž¿ èˆ/Í•Qgµ¢‰Ø˜KWH±x¦?ÍChAŒ¨04ÅŸ$áêK²iž4"`9cldœbLÂòºz"6€¡©â‚'cp¨D#œò"ΰ1Á¶×úøðrwzÎ\¯/Ì¿Û+°ø¢áÏùjRW†ßW×o÷[_g¹{3™;îóE–°œ¨t3Û*c óð£¬?È!¾z}é)ü½Ùc \´¿âŸËC¢'òIœÍRÌò¢¶ß˧#ü)Ã$­ Ñ ü)p¥âRÔmtarqœ>äI\TÓ&’ìREæùÃøR±zZá„; НbÐÞ‡oðÇ©ˆ"Üݺñ' ¦S0µaζ æ‡(s“~£ä»úÑÖ/“ ‹|`;ý’ƒßÿžø÷ÐÿÏ*#ùÿUø+Èÿ?¡ü  gý|±ù1Ë0’NÆ»Sÿ‹ÃéÌjŠl½ý¾úYÿ„“è¤ÁAAØ—|Ö—ì?»@N÷oˆÙ2™˜m*!]@×*—Ä?ß·G7DíÄL Éî®CAT¾/PÖ™©>¤D#ÍXøž>– ñsÙšƒ¬'`¨ç𙘛fPH€¯À×gAÐnZâ«QƒîöÅû&J‰úhÁåÇ)ÉAi.t.u€—oð÷"1»#—¨*jü‚Ô"œéË· q}éìiƒ¡9,‚Eç(S®?6ýÂE<…EÅ—‰ã\O’ëÉeRÕ»¸FPÓB'{üŠƒ¿ à cx‚qKúœnîΠbv>ôi)ßyèjü‚´0â[>ûí…æÅݾeÀ=þ|Ë¥k—ÅøÖúã×€› ¤~Z0¿èjfØ?uô å"*š¤Æ@žÊ9l*ÿg;«‡ûûóCµ,멬l‡–®t 2·P;L¸4¬ðõ ªÆŸÖTq¾=ÆOù¼v‹6ï{üݽh5øö$’Ú£àCtgšQY ¸ €òyÑÛPGtt¥›ÁY\pîÁ¿‡þvù;Éøvü}ÊOìîÏ×N¶‡n¿=úS9ª8ƒ‹&›ÉîvYÒæ>Ë…ð'¾ø0~æ•/€”.µW°û@DcÝ®ú‚Q½%IeÐûû|y|3 £V6åüçÐq6œ²âHW58€l<Å>ÔéAL’Þ/pÌÏU-‡¤ÙsW:ê“©Å€Jp*ÌM›:„?@OOÂû怰n¥å«c°;I—¾˜Å¢qÑ9ºÌ/Gµy°ùÖAgq 6pc$ƒøj;áVáô6"* ¬|’>̈Ÿ÷€Nï<È&iéÃD6*8ømÉç 3Á*1Ç04ÿ—E¸qyàIr”(á2€:®Žë©œGI®'ñóÀùÝ™Y_S¿³ƒ/¬šÏö»-Dg‚J¸O‘czlVaìï¼¾_¦W` Â_0ÿ ¨ÍÁ·;Ý ÍîöúòëqÕ‚ƒhö6õþ²i ÛÌÇ¿ÉtÄ]™; Þl¢_D™òfEô?ÊÔwSÏá!N ”}çáIø# €:,†Å¡cñ,þÙ:t¦+ų R½¢üïF?Ž?ZàÔŽF‰ «pÊ@¢&ÅßãOå%¢öÑ¢GãæãwðS¢ñ· ÅÀ& §òÈYƒCPH Æß#C‰!Å" ‚…õàßCÿ?·ü½ä?½Jÿ*{ÿ~X®ÿL}ågkE$ÿŒ‚ø&õ÷dxó•ujs !8õ™2nA_Žøã_.~*HeÎßG pøãßíý£ÎäàkÄtÂ5_%Ǭ"%D²iµó@8ïϦjcîªÃ¡Ü FxM²üC8ÔŸ¾HˆæS.Ó(­…í¡‘”¦¬±ºmOu*/È1>Ú„ÐÝËíà›(åw&@·[USHçh{úâàìO?Ã׊hÎaE90èÃdÐ{]#ŽÀ¯‡iÞ]#Ah€ó÷QÓâÈyWܯÛ×Ï?õ„>*ÚßÌrg{ñO;Ãøsøçã ·@ òXÌtO–A³Mg{¨@.—bÒ,#—tT‹]¥ÎNuÕŸÃü`kO ¢Ýÿ§½«ímÚŠÂ?n”–¶HCC“@ê&@PJ“µ‰Ú$ö½ç^ÛiC[’4”"Ð$Ķ¢mÚ`ÒÒ²ÿ¶óœsm‡jV)ÚVQˆÚÄŽcßóúœç<îòŽwçÞ)Ù–„4÷m>Î-o.öò2 †Aå¹J›Y+‹­çP1‚'†V¡ìÚîÕ±Êù_›—X ]ÈÊs½].5½¬V¥/–Ó¹"Ò qýÅWpÝ{%Yé´.Eù‹%ðööÍß;%ô»q…Þdr‚oV_:P¸ä˜íÚW´õøTYslò£»]%w¯¿·ÒJϪÔÞ¹qÌ6ýú|û­K– 'Úì. ÿo¥ÇTÀä‚  T³Xƒÿ\þÊLu ܽ|ý& NÊÿØ ¶öù¿çs7W7 $'š,™LŸ}ŠÍðc` Ëßá‡JaûÚ³ñÂ΢üÏ×ÿø¶³hÿÏž0Öm¬À‡ú€÷J9Ö sç±ó%ëæµRb*±Ÿ/Jüh”žÿï6ýêDƒ TFª< Mþ$»6hyÑhO@d|¬³@ÿýEÚϤZà&Ÿ>·¾yóï^g&·–é§mYM—Þñï^l>A)°¿W¨/3ó ;åÔ4‚ ‚×KF/”Žkó «1ÊuZêäУ \`N±½ÒúPé %A¸j•ʯ†Fäû½T¿&‘&"Sé9i33ä‡l¦ˆî8‡ˆ]m¯¹È¹ú:Éðþ˜\Ë´A‚)Jèþø—·-¯þ™#c3ûÙ8å/ú?§|sTÖ}íÇ~4$„ü‰þ&õ[d]=ä_À ³Â/•‡~¤ÄJ¥ù`¥I=¡‰=À\N­Ä4½Z“Ãiæé÷é}ûBáf.Ëÿçm饚8LDþ`‰ÜÙãÌ÷åz„¹VkB³·m\ÝFe>•’Mƒg« ø¢(I $P°,§?2V!¨_ÞàÛ°Øã§ÇzihùXþoź`Qœäò—tiùq¾þdz9û|Ëÿ‰ðom'=±yÇÚîO±>}Ià+à vNͺšø=Ðþ~"}h%Ky 0ÿ¢ëµYëQ1÷¾uÒllIÎ 0¢+u±¼3À6—‚ÑæC¾¦wm~ð§èP’´ÆMÒéÔÛ ¯3¯×$=Hû©"ohåËíE·Ÿ”ñEýê©6š>(|~¾Òåõ$ 2ñqR"üRéçñ» OQÖ°ƒX5˜ «” zEMü §ZŒží"uª°b۪˗Q;JŠÖŽ4u±‡#ÕÉ´‹]z¡‘H?±KV2Kl+"ëSTm¥­v‹µ™K|ˆì(­ |˜Ç|A!?R]5ÍõÖhc$=.Ù–ÑO©ò[,ÿ"Ö“@=ý·½8MT¸ðÉ Â<—xp01*34”ê®jtrÍ˹ü‡™Jj|±sÏS¡óKZ»rñØ)áê>t©ãS¡Š”γÜ4Ü^Ü4@wŒ+;§?0©ÎÇ¢ÚÌŒi®ôÕøŸ”¿Ž ?f œ7Š#gYW’œÀ d¥#$…JLDÊÁnðÅCrA[,–£1ýéÊݺÆìùúÏö„öÿPGUxœì}g@KÖ6¢€1I"ADArÎybŸî äœQ$š$IPQÌ€€‚YAŨ¦¯{Ô»î~»î½»÷Ý«õ£é™®®®ª§NxNfxà« 4&÷Ä!ýs{ò×( [ßm¼=} Ìúh«°NíYc P§ò5 ÓZSœg}¬Ü…ÅãøøA8ÿ¡›AÛÜýº—̼1³¨[ÏÑ*gÊzŒÉ­òÚ’·¡™Üzc‚lÊíš«üàØ°Y6î€Û÷÷e!©ÍMe”Ú Ö—œµðPÐM¼G«ºöú)î©eìÒ©«®.½ô|¶ÚñSä‡cAeͽƒã‚uT:¾{ZæŠm>|ȲÎg‰Á¦…{WNYtè,ºÿI·ç‰¨'2ódÖß¾Ú”»ýp7¯s—–cüÔO.n¯uÅ$Ëê‘×Ý”'q”"ì^Þè]¸sãÀå²*Åø*p{-dRŒÉ%³²?I©[¡'¡‰¿[6ôuÓôüJ¸v­ËÆ«±ç¯»°C®oMÃ2Ò ZÛ¼b$ø¸yZV¤»!éŒ{ZZ0*xŸC xÞ-»¹6íÍ(ž”)x£C0kêQů:µê¼T^·0¦ÑVNév7=N\ã]ßE/\1gp\¿Mhx§«…þÆW®ñzfDoŠwÜ'qà¤À%Ø0¨ñÇàŸg±ü[éÍ,‘k Ã$yýXþ¾¬æ¦&úçÇQ[?*–kC©£ûàh8]¶Cò}O l'/áлY´ñ~%ú‹÷çHÆgótžM$ÐÞ?|$•"õ”DšÓŠÇ–bŠ‹" V%=ÂÔãöü¦ôÐŽë Ç<å[¦Õ-î«5·÷ V²èÑ…ëÜ~j=jì6çmÿó%ÒB)/tIV¼ý0eÿÁモֺ^ic?|Å_Áê®ÍmeÐ}–m4áO®o}¡ÂÊ»èõ”{ã—{Xê]3>þÄxVžÐÑ“í]3%oXÏ›ÈKoø4B._Üú•Ädg …æÞz'(A™«Ü£èr¾¡êØà2yÏþÊaïu| 9mlRYù9êåîÕ‹¿ìåÔY@¿Þ|ŒÃ£!ü{&)lݰãàPbqüPííæLÉ É G>U\‹ªkà)uð<cJtø¹ñ÷ÿœÞÓ¤4~ÉÿÏX†ÏèÎñfG¸åkwþgKg…©7ÝÃä®ÅX2`ÔšHÂ;{«BwÿrÞU…=ƒ ºc—óõt Ø€ÙÇcž.k‹¹‡õÂÅȲµlA¹-u#YW\mvuO–•”Ô@ödøb¥6‰óˆòiktû2›%Ús¿=¾~M£ˆØ£Òà 0È…0‰#¡»{p@©f_ºÒ–J?Z2™aÛ,Dc,Z7#©íÉ„³7jËÂF*–¼|_nà9û‹jêCy¹zï1Â(ÝS¶$3O“Ÿå8Ö0dú˜žÉ·Ü>FÒèè3Z8gouŸ¨ÕÉ`MðïÕÑxùfI`Jž<À‚ô€û¯³wj{zÒ3–?Õñ0Q,>–`_:¦,=ØaŸGä¬ãò]6¦u(¬­¸¼îýÔ ñïF¸‡ûV*¬o±Zwý¤ïºë¨á¦—#6nŠ +oÕ«ÓÂ/U¶Èue¥DȲÊ@:´'É,Ãd±ô–Àœû¨Ï̉¯5–wÞzm9nñ‚¾O^S®Úƒ XèŸÈÄ`YõÔugŠí®ÕÜð\ UìËŽ;‡[z=î«à[¾ J÷÷Wy/xc9Cl&©ÈšëxŒ„û2€²}Cö°æÕµi°Èl’=ÄžZ›µõÃÊ»UësVפlÛÒVÝÝço¡ŠS`<§ë(=øÕÆE•‚‹Ök¹…ØY®˜y; ѨV<ïféÿ\}+ùØ–"†åA–•¨òƒ~­ÖßâŸ4+ [¡ƒq¼\h›w}¤žEgÆÓØ^Y-S¨Lé«A¼ –Ë5Wïj¸'ýœ–bÉ……S&ºM/Vï^Üìtc=И®¦ÅV)O#hãä.‡¹ž‘·ÙuØìì(þÂßM´]·%ùúa# ³Cg}?LD!3µîÍöíPü·øÛ%T]š®cs ½³kÿk¹Â6Sa1³]uà†ãŽ Á ·ØD « t{îËD…€ã¯¢»òòž8þÙÑÕ?)þfûf_€>æØ_òÿÓ2ëÖïGŽøózò)®ÌE¬¾í‰@É©ÒÔÆ&W”ôM¹? /oéÈ\¯ôu|û“ÎY5€×ö{;Qÿ Ìsj§çfÄg<(›K¸ÛâôÕGKŸÔÐ|ws¸÷¡ˆÍå1Vú¯SÚLïžÊñ-~ž[á¹?4MÕA8õOzªÂÁq9ŽãGyÞñµ²ªRÁÇ6Ôx‘Ýa“FJñIMÓ^«x½lêhÔ:¯|Z§šÝ5͹'2¡iÁ‡1é*½ì ôÏ15ÑG^ÍxþÒ‹OhòKËWRr'ðúú¸JOóô̱³©ðxv¦Ÿt5å˜Ã½Îš´NKjWýKë™ýAàl7RÑãã‡Å ÈÅ2hí”Å ½jtZd Çèq x³i:€Wº3åŒQ¸^/:Àÿ ÁŽ0¤J´Ö†ÖtéþÌò²’ÍŒø6mƒõ¾ýcg„Ý$çæ$ÜFK»³]S;Ô>(¦ì̪,›ÈÜŒŠLÓÔÒ)pØ3Ê@q—këaH”?¡îž¬¡[¦¹](æ¿Ñ? ¾o2èì'3}#Ëì]ö§í í}«·Ø;Z{Šd°Ã‰s’l’²7&`îŠêüÿü»ÅÖ ˆ…íŸäÛHþ¦xYñ|œsBÒƒI]<öB —v7€ÿõÒO(å„ä†W=ŸbhQûÀÝrö,ÊÌñºpU¢­ññ+‰ ^×°»qèxнG»Ó'F=6½Ô’D~VRéß8kuŸ-VåµC»º·¶L´Òkr¿áÍ ÃnndO}¤‚g—íÝ*©)÷yJ”Ö{#§U¹×W«¬J ãe”Ùµ:¨h—Á¬¹µ‚ƒÿààYú™ §â–ÌÖ‚iüézcû½I”D,ÏȤWV7˜T8wì¸îI„ºy‡ï§èy×·ÚûAƧA[h‘°jÝ 'wn׸FIUÌK&R¸vÿ!ümÛ?…’”% «ñõ¿[f2Ìïi˵ñž½úõßâ¿2k3{U4¦PÆÿ(øíßtüéµÏ®‚ë“™a¯Ëà®Pš …õv¥f𜠟™Øa³õ'0Êg0€ÙV^ž<ê'Ä¿@³Jß›ºïAëüÃY¿äÿg+.1¿ýÎú“:òŸ)>!ÿí'ö*LªpP]1v„6ÀÛŽÄXÞ>cÔ¿èêv^µëª¤ŠtæŠýýü~Øx’0²û˜è3S®*‘êä—l¸îf?Õ[ÖÊ\ P³»q"ˆêùUw¨ÆIó€ó«ÅþbÎôî©7–RAâÉÎ4Ä@Ø{’kÅx‘ø÷.Ã#’¯#ìŒe/¯p„}ÙŠé{Ä\û« -ú»*´)W ­A>@“ùî1 š„-Üòí:j¿?pOÂ)îicÕ'•ßÜÐÖr»°z¦Ìà=Ùeï†1È6ÁB¶IYZ3Vn]Á › uºNóÚDÖ¬†—BÓxyR“dà5¿ÈKÈéê6aç%>þ>È*’í“[3Àvj-6s]ËÇ{Vt»Ú‚ª5¢R&s y1óÕ4÷È^ƒ…‘îs0§‰3“Hª"Áyì¸Î)Bûf†É¹´ü{æ›D0j×ÉÝÞ©¡)r]¿&$Ê{¾zÇÆö޹uÏZ§7µvÛ{a5uÄÂåó”ÎÞ˺™~Q}á}Ëà"—ä9k³¯¬NpQô»ñß Þë¨ ©S®ŠLX>/t >ÔîÀ‡“»N¹Ïœ‘.®²ìX’6g´)uq:适ï6Üù;,EÕ)ô2È+É÷=ycß-Øûo"r¿%À…"¿ >+m7»qÿ)ø¸>P j‚'Ôé8Øó ÂæÑ¡rHß}RÚLoªÕ& E½EZèªü£ðâÙ¬©÷yÑ6iσð}Ú>÷¸RËwÃw+ߨ[+¿Ã¿~Í­Æë«æJD½äI\@}?¶çRXΧ²¯¯–l[óiý¡]o‘ýÏ/­9žú°#£oa*#äsÓÅñAÍZ »Xp`æc1ªÞ~Òz!´Gý ÿÉÂM•½¯>YIÐ+ãU\bW–$ßMî†ïð K슽ìóúÆÛ¦Ó“Z“8øï ‰Ï×ÃñOõ «l톢ÅÖ•cvf°W7Àè§QÕí³,·¼vI^Ë_Ϥä9¯kýéð/W·Û´–.ûå³›§­¿ñKþªâñáÿÓÓœâþ+AþcÃÔ’X®QzÀ–½Å™AÖ((uá»Î÷C¶Î<ÕK’«à´¾,@ÈÁ饽ëÿ1)i•³Í l‘ÄÀãý"[†oå!5KrË8ß~¹žGl¡·ªçž Nx¦5°C?îâ#‰µ<Ë6&¹-P-R¯Yùè½\Ú“W¸«jÊ„3Ç)RöܾßCe2®¿'ºsù#ÕŽ=~ó.ì³IdìiÕ„ÑYÌÆ矷WùF›YåÏi¢j/ÕAg ?nŸx^çCñýókÃö&8¯Ýc9còæÆÛét¾"möƒš^ŒÚ¥¬©ûÏ2b=©…I‡(¶¤€ðègë½Iùy“é ¼évw§§Ð™£Ÿm)?|üÀVÀÇ?#² PN×Añý' ³'°ÝÆ¿£Ù?µ Ž=®çÙ@Pc,føD_ywœÐ<ÕŸÚíÁTÏŠ†ùâ“ÐFá«j°kZXŒŒÓò>¸ðhmyðÑþíCÞ×›Wš6ͼi`ò\Ò£’ý¨Tå}µ¤ÁÈ-ožgù„ðeæÝëïÞÌ\qSEÊy­Y†d”M€ú¬ß‰¾?,§6n‹Ú0s%À½W<¾r+wöÄíòvødzzõLì!hžn°SIïSÁ•GdceíwÓç -­€°¢àgC‹ÃÈÏ쉢}èÝfûüãS&q¯Q(š±íêêþ¦ü鑇%%WŸª[—w¹§K¸oLXEüɰW+Ì’Åné}•Eö«ò_}eœÆ–Ù°aI. ï¾ëoÌ ëvš{¬ßµíó1$ël»”¥Å€!cpÐç^ß ß/ð„71´ ˜<­)(ã=+0ÙYØù¬(þ —Φ!ûÀÓ<9¶oÖƒ‰°®¯µqÔàA$ƒwßuݬÝL»µûßmKJ´u’=yæïãŸ9¸Öæ@K[òãI{Ví®—í×<øH*XÿXªE ?ù•aÂÃÚUyŸFÈÞt „êù÷n…L3úð¨­È«Wevh„LjëA©ïyñ)wÓ›­=öcø¿#²aÆ•‹a“IQ7ë••Ê‚A#³k)î±§Uøÿ˹7Õ¾j^[X³ç’Æ0þ<•5­2ùqðÇìNÄ¥%w;œVîâþtH`‘$€®gVuÇ=ùòºy¯•ôæ~Rœþ§Õ:?þš¥®ë&*«{䥖9ý¿äÿg)Ž7ãÏBÿÛùë”A÷HQ[§ËšL£[9üÉàuꥡßÄŠåÉoòÞN?¾dÇØÅ¦Óë(!™°-Cê8Ö5ÕÓ2OoŒðZË¿*È{å j ­ð¦êX Ä8•Œº°T¾e5φÀ üyç×ccÞŸ^S:¦é„ìãÛ­2jrÕñ²$0oÞ‚5Þ¼¥§kÒ)Vn”íØgX©ä8£ä‰Ï;‹³ "Ü hŒRa)¡Ú÷§f=pèìŠÛküxíæ9JÉÒû,B>¬ÛMsËp!©_œ¶“' 5àˆ‘5sfå’áë.Ž¿9çîKKi6æü7!iG}ƒ¯=- ·nˆ,tèÆ|wÖÎ`<"¹yþ’:ɇ~¶ã'2SÉËËͰ×Çn[—©‹X°a:øìÕ`g‚ÕÅ /*QªAo7m3Ö?Êåb%’c×hk|¥„x'ª¾“h€xËO<³Ñ·JuVSœ6ýðX¶Ë‘'–µ¯Ìrž>è”[DÓŠkýAó4ÐÙ±öª³$€Tv¿öÀý„W­9úæS ŽåòlL’†ùS¦+ÈlJnlU¥j[loÕ–Å-½Æ µ[Ñ6ø¾TifyèÄä®i““’f®£ADfÓÔ›=òpÀÁØ8€WÜv\5Ê•¶·ïñm­eʜ”×çn—Þ{ @KH*ŒáäCJ¸»ìJͦˆÍòò Z4{¥Ù˜“øQ»ævŸ &ƒ%ŽxÆm.b@íAÃÛ0¹c3'ƒù§SzM±”€Âµ䂯ÀgS)l>OY_Ó°yýªgôìJÐ!“Guˆ®Éψt¿4ª8ºhö-=¸j9ã8õÄã'ðþù…1ëÂîIO|= ¸t‹—çzþ¤i¾y‹RKœÎ=.WMx%x ö#„cJGÖµÏA\_=ܶOÚ‹@ü³[^!ñŽ‚2æÛòÖWÃËα³ÿ}üÍx}ì¡y?^iL‹»b·Ñ !|gOs½IR¨ß ¾éGÎ¥~L=qãåkOúØ“I66§p'®:5 ŸDÔ¼ íÈ£<+s}”œe•^ŽÁ*géë«€…,vø<åì»z@.…Ê„cÑêÉtêóYv1¢7>Ü+|0SÓ~︵1Ï]F{Þ‘¬~Z ÷¹¿6h¥å±/`C|^h cÕî55ÓÙÌóžç»ýcüË-­ëy2càqÁ±w*|¦ |Û­¯*¥nÖ 9¼óAïQÜÎñ˜X?8ìyb»fð’­ýŒ¹åS5U < %ì–žÓ¹Ý ·6Nx {¦ü þ¾õëìR²¥èJ´øQO@æóù«ã¬—WÝ÷¾ÃÿÓˆÉõÖ/¾âÖª|¾àŸ-5°ÙUDÀ“ƒüBÙ/püÏŽ}ÇÀäjy?ϱÜ{·±sš¬eúX\EÔäéØ;¹:HÔ7í'ÁŸéaR [ºerI°tÊÉcÀó$®~FǦ_òÿ3”ü²âø¿ÿÞŸSœci°ò©Ù‡ÚGà¬Þaœâêf&6}øϧÎ)‹ç*oÈœÑ ™£´k»7ÀrQ làÇÊ»jš«NNµ‚ Zn3q…`çíYž¢-¢XüÆ£ZO'Áòç/‡÷¶Víû\$º5Þ[£ÖºgC@nÅøPH·³³<±¦Öx š¤X`eüjSÔyl>{¿áy¹ŒÕU3ä-–dTÕe"'ä:„‚*F‰­Hžx#ê_?ª4@57ÕbÔV˜¬Ý?¯›èùêSÿä¹²ªvÖ¨Þµ~_Ÿ¹ó°÷£¹ Ú-YR„‡@ÆLUGdV•±ßêEà_§DÒ~Êò¨Â ×§G:ÀÔ^v‚`WUµÙåÞ óÍë E„´ãcV±Á ?,/ÍòêüIs¦wfökå³_…²w,Èé\°h ÿÍžWݶ‚ÛÂ(ïðr%Šî­¬•†ÕÁ‹fM¢$[¸äU~ïfkDù()ÏÁ;ëæHzr¬‹ÒfU&eùžóö/s¹=³®QjåÌs/Œ0¨[BY=×õx ½¹ !–nÿz³ºÞÓýò{m¨ûv2æøçÝ«)2/Ò]׌¯{”ʽÄÍW!žOô~×£ö;H]º…8‰<5ª‚ w,ýQüGe±J b\®V¾>sÉ8VއÔ+Ûü­ò¾Ã_\£LËö @Ñž—[G ãp}Nb‚üÛqy, Âñ/¾¼uQúûâe°ÿ#ùÀê5sg=ê8º{˜»‡OžÅ·`Ó¹Ÿÿ·5MþP8æ¼Rîîîê8ÛfÊTÑS˜ùÚ¢GNþ’ÿ¿zù'qvVð©#߯°? ‘¿ŸÜð/äDëkP¯é´|Äá³PD®ëÊá§6§ŒXyO¯EÜb?-Ù)jå£fÜ«óô9WÂ`ÃHá#è¶¹ÈfÑ U“{xÈfÍÏ.Ç‚½™Ôt@T>os…²®0JNß ¤ÒFƒq·± Ë‘½ H=ôé;äûÀ]xŠ#7?Ÿr«CsêV~퓌`½Âhæ¨Æ²Êy˜ïòc^ƒÈÝgÓžÈ>8(u®OÕ.ì¯møIîQ›bCxæ¶ý Sƒ¯ÏmRóöí”(×z‘r=øî´b\K\èÖpeÇæÏ“ äÎf ô>Y@cïø\ú&ÃáôÆmvº =)Šz‚Z)ܟСw“Óž5"3Úx•¬ŽíD½µ_É%(o¿Ìج Ðßa»ÓE±Ð‡‚=(̳}*ª; Ü¢¬x…mò ¤ï¼,j‰VN})á%ñáFÄ£«ªv¹nq:ª<ŒÄMz×X;RY˜Â»’yµó#r/Üš$>·^âÞüm±×*ÿ9þg߬ónÚú¦1n7”D«$Ê¿Ø5ýFá -^µÂÖ#vÕí4]ž™÷ŒóyÚïëèå''LôÊèT·}ÂË౜›'th¿ùQüý3mœ “ˆßo‹šbS¨ë09UDƒ¡wÉ Á"ä;üSç=:Em/žê{öƒã5Ù/ø‡)¾WBÉŠK8øËÒÁ{ﮋV¨²Ðâ^OÓ¢ñ°M•ÏNŒñ­ërýÈ.½g×{a’ãoBô_qã/¿s¬ÕÞh•‹Ÿæmû™â0ÿz¬y¨JNÄ‚6R òKþÿÒåŸo³;ÆbÿŽü_(Øÿ4ÛÛ-rÐÒYG¤ô·Ë_žÖ³Àý˜V¬Ì]{£uÍû0­iOs¹¼¢uA/UaŒüèirðéÁòGNˆ1A$ûº+êþ’…‰"ºZg•÷Oz›U¿ÌÙðÞY¹† žw÷¯õ÷ßþžæ xZÆzžçÔ:ýމÃçžDÒÏß®D ÞȃŽ oAÃä©÷yEZã>aÄT4ömòùcÈK&rÍK ô³¬vñLœn…ì¼æFœàÄ}q…­ð!ïdÁEðÂ¥®}û˜õ0"¤¸aóŒAÕå|’|ßÊ"t Ku»¾Ô´{jÔ› KÅ+/¥w`þNa˜\£ÄÛÝ÷Û4í²õ†œíÝÿÁêÇbU2é¾Pº*ÛVl×™.þ«&¹iŽ[Ã>…â·;v³ºèÂ6ÉUkwŒX0Fmìž•"» P%ºOÇ”ƒ;Ë9teáÞm !Ä{`]Ta¤{È‚6£œ Ù­ÛÎ;Ð7Çõ,39=¶‰àö†'Û'›–K†4a°oA…ZԴÑnñ­‹š&t.kì2OL[¹¡9™±lN-NJ4š$œ¤ úM`›\Å¿`’Þ¦öÒ•Á<^ìIg,aíB±ÿöäÂÓó² àÅÑ8êÅÒoÔ«¨ò>[} ‚™»¯Ïèoî"£lK‰ç$\ökÝzðš­<'2>çu7ŒÍ{h€û¾¤h Tî݈úYiŽAâykWìS|ÛϧVŠtÍU¸¸,øí“œ0¥=O72Ü´GÞO#‘æ­râ¶‹_Þªfþf;¼ÍÛ&õÂÇûËÿ#s5pÕóîH–‰Ö–n°)s@Óð. ç*Z¯|‡?³ÉRO$ýyŸÚüA$¬%ÎÉsð¿kˆ­X™‹ã/086Qf9`ôÁÈКå±öø„T•!ðG ü?âøëÍžôׯÿݘžH`ß,Ù3¤¥JfØïž01Ê®©ÞÔ*©m9Œ_òÿ×-ˆß?§÷¿Ò~¸¤}*(3ó3r7y&K,NÛu%tÓ–"žÍ7u´Z‰j€Qo”ÏÃ#›€%Y0”®é§0‹}áIAé`8£Lb…¦÷} U VÀ´ZI ^cãìïTøè¢]ŽúÞKœ$¤>⤹äSOƒÇPÈs ê[¤×(…]<Ø “ä¡¶³¨ÀìÞR˜ÕpsÒ§ÈÎò&IÞNœñ²¤h~SN´OÂgïÙ@.ØqWË×Ï$›µ÷ Hêï÷«Áž]ó,í¡è}ÉCgü?],¼mOŒ4î‰le°LB#ìüHmû´ÌÙúcäˆØ â‘Kx$ÔÚn²ƒ§ù*ðŽÞŒnƒ¥Gõß<É0ïóˆ2jÓaÀ%™3Âk—¥ki š‚Ñ“v…_×Jݽœu"Û#T_ýt X.qà÷òÑî¡|6³!7ÃH' b#L§'h]Ýpzäs߸îVǪüÁÒ'‹œ°eÂÈÊJš{HîÔ I+fK)÷±ð ²½…S`½|ÚS@NXIüæ£(b'Ö,ÙÂLT+0å!qøòƒm7bùOëÏVÍÝ7ßÕÿ¼ð!Ö}þ K³ýW{5@OåT,Ä=ëÅ-IWn´.ɦ»¸€7âW¦H>3  ˆ­žtPl²õ£>Ø •Ó£”ÃÏÀ>Cë­’A&_K}(6¢±’ͦ<ì­6öUÙº\j¯îñUºBëNk—»R»¦ò :&µóÇìI{w™ÕøÙ¿{!~|¸­5>}òÕ÷~Öþ•)AÒéaz‡<ƒ_ÒÆ°&™£g€y[FaÇDGµÊ}侕«wN>0–ö˜÷MA¢Üò\” «ÉÂçêö±#ƒy?ék é•6Kåxœ‹}"}yEöl‰sÌÃ+—>òø%ÿÍBÁÿZE·à€ÿlOþZeuƒüŒ5> .XVL”àéz–#V8˜¼ñ¹ÕµYò’†ˆ?`“ =‘¿vE ݦ¯ÙÏ€‰e—À‚„“ËTǬ9ʘ–î;Îë}HÌA=žÁÌUº@ŸyÀwí€+èðºí8 JEaH¹¼Ä<í T“5N+ÎABšCb&Âr¿Vøà!îÓPŸâ°x^l’Ùäw;Õê_z}cZbæÙ2‘Ã+ÂtÔÂWýÌÇ0‘=²´bÚ6£Ÿ_ÖZ®:^À‚Ý:9^»D½[÷±èJI% +ÃjÂÜ…¦W¥›å *ODŸbíjyGÿÓÏš1¡[·Q$ኵééå*6™—à]ô4îö cô‰ˆì5|üüŽ¥±ÌÝFbhîþŠ6=cz`¢Ô–j)íûVèß2¿l³k “æýŠ7,ÒsÄŽg•|ï5Tß‚å=ÚÆH÷ûÕ#m?N+ÝJWR”Ú±;⨟=3˜ºúߘ#²Ù0ç d)ö‹†?±²K]Ÿ9'Á¡% ºÆ¸×îÈ‚Nõȶ°[öÄ!E˽ÚpóÑ–Ù¥,¡™š:¡«úGó¾¬LGK«¦Ö¯š¹ìÇðW>dÔÇ[‚#Lk/*®¯h Èe›ÍlŸ­:1Sšê>‰£î‹.¢![ƒr}zÊ®½‚±°RYÔJÝÖ^ c£À4›Á¯>ì?à³ÓòP6ПPgl]µ¯ÒZsÔ»²çáÞAjù Í»ì‘u¡}k´\•NÖˆûyz”¿‚ÝišTðKíäÁ%&®gí$˜EQ³S{æXV‰Â]öØo[5ëiŽ‹â.€e˜òËÌùàûºæú1=‘¦#:™Å³íÐ-³^Ô|N›åÈ|IÛybûíMsn&&ìÚ~ öRàS²OÏž¢DŒ3 o$´Úä¢d®F7$>xº„feb³1|ü¤Ýñl¿ë‚Gá„ÅÛUÞ1k€\'”í,RœuÇÜPTºì¦^µà¾qÈ„®7#â€.r9Ï}ÉÒ7Æu‹oC6Œ¾^söñ¥;Ry®šµÞgz#µë?çMY…bç~æ¼Ä"rÍ…¶ÍW…ƒ•ÏŠ”’É$ZÕfðì{ã´O±wmؾY{cJhGu¢þ¡)# œ¤d1ÕvK‡òn3Vœó#øë(ÁÅ蔌˜¸Îù!™0óyƒhŒ½ì—g¹bz·ïJÜ4SJD@7߉ Kfˆà#ìÜ‹rè;%Üã|’¤ì3o1 |ÔÏ¡ýQ>×: ¨åÕ =´çïº3DšÌv=“«ËZ¹Üãsäeõð} AAš¥á–pm䃻æK£=³ŸÜIT¨_”½ô8½^væ·t,OX>ED'ê&„þþ®áãÞ¸×ö7fšŒ¨+U©ÜmZÕÀêh”ncÝ<ËëjõûµçÖ•…HÜëêNUº:×$a²Ã]>õ ÓÝÁÏùÌãO¢€©žZŒ‹nÍšÆQ' bJ=Be²€>²®D¾Çÿ”–’[³ä]ç)Îû}.´Þø‚\5í?°jЧøñ|^ÝÖîb§}vû-“pùgtí}úÙ-7¡Ýk9@ÿ;'1MU¥1¡í6óþšø'I9¸¾ ©?™}ëÊ‘ ö :âöíûg[*m<[¬¢ºy…Kµ%°Žù­¿äÿ_/•?Rùÿ@Aý›“Ÿ´lúcš© „ÆD¡3ƒÆÀÏh(†"tœ€{8 _ÿH~Žâß ÐøôSXœŠ(†WDˆk( EˆÛü˜(BÃ0â*oF t:ƒ{@è€qtÁ¿bÐÎD(~á(Þ.ñÒÏ¡1ÏíÇ€h³1?&ms9Š"¢¥ø÷]Ÿ†‹ aLZŠ˜øæPÍâ ñQø%ã0â:££ÄÃ9?©@h §Yü„‰Ò¹Ó‰éJüÀÑ&BL1,:Þ‚SŤ!t”s|m |˜ä0ü”?“;™Lü %£œËtŒÌ¦3‰ßQÂ{Aæt¨´r€yÞ “Æ* L|м¢¨À¤ÓY`˜¥²œ#0:þ¯CÅ1qßþÇà_Æ9C':‚O qFG¹ýBÀ-⦅_$'±–;gø|£_náÎøð5â ñe µÀ9x³†§ÐoÈ0xCÿ0î—^†¹Áñ';ŒÛ¢­ÕÁ(¼M»„Û8lùŠrJ¬0 $Œb€Ò€8 ˆ•S‚0¨ µ2|u)á¬GêÏYÖ8nøTâ+oÅ—"%ar€Bè~!”{3ƒXH~?ÑìßâOÃç–øÈÀñ‡!üñ'³éÏÁáÄñ'z‹0Ïp z‹ß‚˜es4`ø:¥¢÷sã_øŒÒ=vü’ÿ?¢œúcšù¯•¯¿ƒóÂøÏý,Ï?-Œp h(n— QÅW7q$7Ìø a´iN‘ÑøªD9Nw%㾂kVŽ9W*sØsp gànFˆ)â ápUIÇýnmüÀ¹ƒ†ù°X(âîëvMÇ[vÞUÂâ´î½-6‹‹Ÿ§~¡ÝiLwƒbŒ+ºtc8ȰÜâ‹qEqKNÍR\RQïPBZ ¡yEr.d\=‡zbH‡!CªŒÆ":Š«Z\àˆñÇã5©øø9N.œ¸8S1Ì1¯Ceª–|Õ€öIC:Ä5’ÐÒ“ÊäüÇJ¢S¸FÇ(Cª“ëFqí nAp=L&‹¼|~0 >» £†?‚²(,Û1š…·AcRXø¤‘ñûjþe…ÈG_UÌ\¥ÈÁŸÖÐU®Ô ÿáè4–Ã5‚1Ü ¸D)Gî4±Ãó?d 8ø{z¹dŸM ™kä½#ò·÷ŽRŽ G=v~‹n8Ñ ×îÓé.± ÜÅ”º9'ÁýLµ‚0¤^¡tÜ«ÅW9“NóŠÂᦰpmNÅA)L”J88¸¸-Æ}b’~ÿ2\WãÀ—cÊq讑ÄwÈßâO4¾”QbÕã°ágÇi`.6á4pjããøâ/àæ2\cˆ6ˆ9Á?’™ùIñ/ÃÁ$¦•jâòKþù³ÿ¿1úÿ'<€?±üÀI|sô Á|8Ú… çøBpt\·:†S …{ÑîÄøZ‡ã ãQ¯ˆ Þ %/É÷´_$åî rןBãâ à"<}£zD2¸AX kå…âÉ_Ž’CÓÌŽÂýfìTú­ÐâúŠ1®ÒõÒ¢ˆ–À͸”»04‹ Ùôˆ@8ünHx„àn5ý2ÝÃêlH+ÑQÿpÜÉ'<ÜÿqŒ%ö1|± ‚—@BÅBh*|DRˆþ†Ê )4+¨,çØ¡Ù"œ,2:¤l EÇB¯ãÍѸšƒEõˆB4ÆÂÆY,®PJÁ'Â&€Â ±h¸"@É pÇ)¢‚ŸÞïÆ¿tˆó}á€_y¡™]ƒƒ¸øü6ôË™-ìˈ~kÈ~„Òô£‡ +þ/ñàoíÀ0äšs¨á+]œÁ!ˆï8Ä1#Ú£8µŒÝ¾Ã¿ ·À‹Çèzé‘8LÄͰ£D[íØr—(‚âp<”IÁW,Æ’ØÖÂ[B¸t›ã’ƒ:“Œ»Æ†H¸¸C†ÔŸŽª~‡? !L9Ê}ò0þDW‡€ƒ?~ Aoñ~cÃ2BÄ.0îƇÛœGpbˈŸöO‡aSq-DC˜T†Ÿî/ùÿåËþoÿtà¿´ðó{=€SÄ:çìãs8?ŠrBÿt„³såaÄÆ>Bs&6±ÒOG‰¸?AöQdx€³q@l…¹•€k'o6Û3ˆ ‘7@øË„ä tlx“‘ëE#D³×s~,j0‚q\k/ýƒ‘4g‹°#lÎ¥U)ÆÀU,UóhÈ× $1%Φ’È#úÙ,ûØ“ÅUhš%D52û›!¡a¨ì/ê‹ó)àKüÿžÅ‰â£Æ9Cœ8ãdž÷H8öo.²CŠ…«Ø€Ã¢ðso6‹ÅùåjN„2-Ä…7Ž+|ªèÜÞ29ê’‚Ïoþ\E0é~þá,:Ý7#³ÕJY¸¡âD—|\ñ°µ&®_Œ~'þeÃÝá!| ýÝÇŸs'g_9pIúMEtH©}¡€tŒƒ?gëõ+ÙVö¿aÀÎÁŸË¢¼ 3"éN6aXŒ,í ‰¸:FÕù;ø§'08©"ôíÙLNÊnúaŽù5"iÇŸˆpÑ.mÄש}"Íq< ÷ð;QÿÎÊ'\Swqþþ•4ŒØLζWFˆ fo6ûny¤áOtžh›ƒ?˪ƒÐý¨axw|ñ¨Uâ‰Í9&¢mje¸çð³áŸÂIâL+®@Ày×/ùÿ]åÝþÿùÀ¨ü«~ÅïtN s~""O$ð7‰k?¿Np€Èô£¹Äâ–žCr¸®Aåé(!&¸JbÇnsrˆý1"C hF‡XCtŸ0ñ߈8¡ 9948~œ*Å;'gÁl§ÆAµµGbK£ûoMO¢ãA †¶‡ˆ=] '˜ØÞóuÛ‹vŠA·äs(yké7!˯…Nsƒo™Ý%îÛ0¦ñk’\ L< á¨t—H—:”ˆ]àlFìf- Td˜9àjˆÌþÊ¢§Ø*s¨6±ùKX êl`‘`bzHÜmÈ-'^,N \s¨•ú3霜J:°(§¸n"§YNAÞ¡ø„³(tÍ߇|ecÃúyˆìùãø†î è7$gHsÓ¿Í CK醇™¿Iûþ€ s'‚ãyEâS̲6vhtB 7Žë·=%‰Ó¬æßÇ??ˆX&¾îIø’²‹Ã4rÃqðh í #Ó'æ¢(•î‡O7•…pº4Õ5žpn _€`ðÎ?†?F¤Ò¹±^J7€Eðyºcã;üîB‰].l*A÷i¨:bÓ˜µJŸBHˆÐp³ÈˆŠx{ õ2¼ ÿ@n„îwnÿáÓ rŽpïŽÆä˜a_òÿ{Êÿ”ýÿû6ñ¯êü«åwy'¿îû#\wWNÄG²k ‹ÐTDx€ ör‘±ÇÀ¾lƒ ù œÜþ¡à‘Ö4ÄthžÑtçx¦ûCÄŸ›MäÖ ½€pï@œâ‰Ìlºc4››óDì@08—©›H䦲¼õ XC^<ÅÓ3{ä­ÇY•L„øœÌ3M‹8éGྫø«¾úæ@Çü,€Û%.ñ fÄ'Í N$ó2Cðð6 Å?Œ3=œ€-gNñDG镈ÎrvO¸eøYÝ9™3[ Ü—"ÈÃÝÁïa7r¶ž©Ä—^a,êG':3œÎõ¨¸»OEYžAƒÂ¤bd&Jì$û±"u¿Š¡¿ÿ²¯û¾Èo¶xÉnѬ/ñY $?rñ›m`ý¢ì~c8*ÿ¯”ð·‡áD¨/ñWNxÈ1–ñ›§ýH:æcðð/aÑi¤¼:›dš–²8LßmG)±MNdí×¹sD^ªŽ?n¸Hú#è¶o""MÄ$¨ý þt&AEqé!Á­7ÂÝQÃ×®süwøsºC´HeÒá þ„!žá(?Æí2‡n^9Až=C AÁe†EÄ¿1 ‹ó B8?þÅLN¦%(™¢¸^ iÿ’ÿ¿ü/Ùÿhèÿ\à_eêÿ¹ò;<€r‚r9?ʉìÓ¹[ü$×è‚îÓÂ+ •(âÍbsCÿù~ˆH‘æBep DØy§8Œ ‚w± ‹rƒ „²Ûc_ÄdF¼ûÇ‘šµo›1´ àc€[€a*AµpÎ ä@bJ:B¤N3¿þ¡:~Aˆ{8öm´’;ÜŒg$Ø] ¡ñÙÁçÈÉ@ _h(Å97¢ÊI3þf”îIOÃüÑΜ2ˆ&ðK6‰ŽÒ0.Ÿ©à<ÿ‚ÌÝdãäÓ;‚Šw$€Æ Qñ+,® #l²W4‡Nà\מL*“¶¹¥hVRÀGÿßÇ¿txèC‘É¡-^Šst‡ÁW½îÍâ†Iá»7À†T)|“î Ä¿ëþºÌ=plÍpøWÛBDXã¸`"tïÚ/æð"ÄÌ%ŸÅyÔ–ÿþå'ŠDeP­mòC8›M¦HF$Ls_šã}‘Y~Áˆ[80¹!+:÷5TŽbÇqÅ•-óñ¯Àm9ÎÓ9oîq‚c^xS>á¸a¡}‡?Afá¾ñ.,~ç0þD~8møã¤’xŒF'Þ»¡qüD«œ:T”“@à¨U"à£û³àÓ çÌ4¿ýL±{HÌ:øèý’ÿ·üOÙÿhh…þÝr’Ëùaèe#"w@Ý‚‚/™~_²þiNñ#ÎIŽ¡£Ü¸J8Çôoò9–Û+—M®† ¿'Fô¡78ÀùïCy1('ôêÜÔŒH7 D‡²±pÉ ìö8ÎæøàöÇ_$½Œ˜aêÀM³³„Œ¸aé&Æ$ÑRͼ@üªWøðÂù²Ñˆy‡âõœâÑ/ ~óÆ îq¢D"‡œq2³â9;´îZ„ 6ciÜ 72ý-ÓâG«™3G4j'kˆÜ1ç(gü¸j p#ˆDÈÅ#^~Bظ˜Sð;1:ÁežÐFeQð.±è>¡(…Ibâ@ó5àÿµw-ÜMWøÇCx%å´MH(¡)‰m°,,Ù²%íîÌ}È’%ÙXÆ/…Rò izšðpbœä·u¾{gveà –Ûžƒ÷p|$$íÎÎݹÏï~ó»#Ë—*Cσ%}«½téÅŠýæúPØëîýY_gª½T>ªvRŸç=о6UéÝe ¦M9Fœ‚+sßµø“‰¿þšü¿\'²‚¬ñaï<Õ±§‹q¬§Ô¥ ÙQÅ~?‡’l´Ñ˜PŽÀhòñ¨mÆ>æã,ÖìKòÇ Hen%xùs+8Vþm €Ì\¾LÅA,¨[Û¤ê+3)P½=òßÉP¾I¾\Ãsu=‚@'>>YÿG;Ž‘ýÿU#âíø™;]5WcÊIϪeWÝ'Í+Ã}„õaeÀ ÔƒcP@ פµ©³pj./!œŠJë‰Ð«aU I }æuVíJ 4öP¥ÓbD5©¨rùáú¥¢88÷÷M^ª xt‡Õ¾ª«nâbŽóä°ÂXΕ^‚ÞaöË'¶†AF’ÿ“ýš›Íù  ¨'·|ÑäÈ΀´‡ÒÕR•5ÂÈ!$ Y«Hž½ZW–EÉaC2¹™p7:Eµ>û1¡Ÿ{<³6>ÅÉR œúDëZeWe†ƒy¶js˜AI$aÖl&³‘®}Ÿ™ß3ÁQ“€»/òž&‚mu'àÌNü. fð¹N‘õ%)‹iP3¾·-r /¾FþO:Œ]µ~gµ›­ÙK{Qªâñ ;¡x¬¥Àùÿj ¹ÙèÖÄ€ßÅÜf—òSwjTù[…mŸþ¹ž¸+æQÒ ö‰W/Éß°¿ÓÂ-ñò—¦kK ÿ.anC ¥5Š”½RIÜY%àeÞù¾ÉÒª¿÷ÕÀ"]û)rV´gNÖÿ‘ŽãdÿÝÂÿ†Àÿ¤ðßžähÀ/®îDgïõ|cÅU÷•Oý380æþ«rü;¬¿ eå4\¨/¬:XwUÔ¸pGºø‘ Ë£ëâÖMK|´0ôvz…¿ÚõÙ‡ƒÌú!HÂs€éðÝ­5.BþƒÇexT”nT1êºÙŽ&ÒAï6Œ³5ö¥u”Ïm¸¯Ê«„*Ó\)=Ã:}Tù3àŸ=Ft3VмÊ\}ô’üùÛ®+Œ­¹È•7¤ÍXþ ]¬(+íM<°ƒ&¶®1°àVÎ-‰¶ò×ÕKo¶üÿÝC|]šÖF>~íËÕT_üºƒT#°õ·Þ?Yÿ#ÇÆþƸ¿EÀ+#8/f±ãñõôÔ2¬…QŒKýË~.CÝ܆0ä™ÈcT¹ßr¡½' ²¸Õ˘áŸÜôT7£z*QJ È @}GÉBÜH +Héý3Eñ·|åowíÔ>ú¾P_¹A_ ø[zê“§±(%’ŸW6š×þ›hf`_–îÓ>\ËÒÔw.2Ñ!ö*ð˜]©“›å5n}„÷‚.™OåÁµÆ(¢°åÃÉUûÂ(Rí‡Ô:RH6J礴:¦,”¸!‹ ç«É"è^ÌÔªýNëÀ¨V@³kA-ô›6æ°ìÔNJÓwB«ôÊ€;|ÿ>+N­,‘Ì‘›Žþ•«oucÓ'€‹Pî/™2ý@G3½t8Ìÿð$Ô»rÁœ„?˜O‹ï¸Þ¿×Ëÿñšèî©«?$xDíTÛ€*±z’ÓKè³SiiÍ tÎ Ð|‚†@¶Üöµ>²ü[h&îBÙL T‹~Œ¿,;–”}ÖxùsÂÙ.E–-]äfœ© í|gl0³f¿tÀo`WNíªÜ†ßó†ËµEãÂçh0¥ËïÚ_Ô>þª‰–2ׯOÖÿˆÇñ±ÿ‡2í¿•p¸Ñýÿ‘=€_t#ZBËó¥ÞR,œ~9Pr¢Úø óG³·yóŸP†C”¨´ °Ã(,'Í” ¼ á3¬‰{gìeÂêªaJTf¯¡Ìª+ S»"V+ð} ãÕ×'ž b^¤§E½û,É+‡ŠÎõcæë«\ˆãʦò/-$àöÕÍ\c!£dÃéAîRyç"E®G‚ NpBæ—ZÒzvˆcŒL—®{ÑÕ…[…:øÉm†7‚ºYܡ뙖dN¬:P.ÿiÇjg±´bg/±z-Ò&%SkÝM>Ù¶J LÆ¥IO=KlH ³è½±êíÑ»wÉÊßÁ¿¢òÒÒ§ÛÁÔ¯#€möv—åÆWà]zÞŠ_å¤bù»»."CÜ/£¥…zEò§n¢ÊЇ›©¸|å°òÒÑ׬üÁœGÂ:€Êzˆþ• Ó››Òˆø’;ifÜ »VÑ?²üâ}0"M²^HçÃd÷=(ÿX°FX‡rùǼ1ÑŸµõ+iHÆíVC¦‘ÞM>ÛbÏg,mDé©çq† Aþ{sýhd6€ã#ÿç'g®?m3É3=ÏìHƒó;ÌƳ¢îdýrûhÃ~’éøÙ>¾sÀNõœîs’'ð\ÿÒS,AèÔÌ’íA¨ €êÍ¥Ôe+‹è_bþFmu¨^Éù´èÒº+8b-j“p¤LmÄ TItF¨_HŸ»¿q—®~Û…ÚRžɘÓ(ß=K|S33rsë½%8‘é¹vZ€wñoz›dWN+. àH¼âƇéös$Ásbย<­ Ðo®4™›‡éæ|›ÅqŠ7Ö¡ñÚ)íŸ4'&“P“ÜL" Ók±ÎB$†UË#œ©H§æÓ{ZAIm&Á¸Àd××G$ßµ—›O›fù»É¢"´Ë)Þh¨ØëÚ» (¸ÿ¤ÞìåÙâ"ú“,ïümʃ,‰ËøÇœŒ7ûs¦î7júŽK+«ó#ÈÿÇ”›ñ"pç62üšÀÑÃ]zDöÕø]íí,þÔÚil'™Iݘǿ¼>²üeK8ëb`¢ZÛ™xpk Òï ü1¼ûÀîžÉå} îÇòGœ« 5¥wÚ0“[’pC>Nóx¸-ÍobõM•¿ya@šH§ïß¡Óô‡ßuAªßyÞ2̆,(N°œ¬ÿÃÇÆþÞªŸx#?[•cÔÔ³Pïµ$ÕŒTŽú—6˜|g`öyY”—S‰bø‹Ò¨*E3„ðûe8²¶ZÚ"ÙHì>Ll S¯¨XyÖÎÖšfÐa"€ÊÏp¬/|Ë0Ûs´Ã˧~éI&ÊǧËWhë~þ¶ºœÇ² B‚‰í}&ÀŒ)t&ôqrÂWiw¯ƒˆ%Í)Û ¦·–äßœë9~…Fî…v-å­Pqë*L® ío2`lX×tZ)å-dƒfÐ%l£Úå™&ePY`5%*k˜6 ;»g>½‹æu{Rª¼?Šüw9òbù÷‡ØZóU´?õëÕ¹È_±“¿Wmû½_Ýy|I”låŸç~}®—nläj0s85ƒ%~ùþì(ò¿wŸ­+(y+Ëœ`G±?ŒÑPüÿøv„ÁGiäv ´v&.dq/êˆòïöþœ€Í‡#}Yþˆ+1Æ3.Qäß2B.'[Cþ¸k66ðçØÉQ+:½g&7Ë@Óàô›)ÿ]žÖмÃv_¦HµÄõ‹;);nÄêò'ëÿðÇ]Ãð`²Xxœì @MÛþø£È4 ¢4e&’¥4ghžÍs§sÎþî34Ï³Š¢A%ÍhÐDBdˆ*J‰"þ{ŸâzïÞ÷{÷º÷Ý÷Üÿ]8÷œ½×Ú{¯õYßq­s.üÅ# ýõ•IN ÿ¹'ùWÅŸþçßó(÷ìZ­§f8ެ/WjµsÎ ĆZSmtd%H«Cò~8˜ àµ•Š ‘÷\á~rkòVùþ2a€ aÚ1Htzš©ýºI¡0äY”„cûk˜ÅêB³Geì9³¯¡fŽ `ýaä :/…¹ëÔ<Åú}ÖZ]ï>½úRÇ!ê3(±l@áü­¨Éq¡Â=}p{“<6lë×( ñ› §[9F:'Qo.­—gä?óÀ5…•½óŸ-Y¾HÃ[çD Ð_d(†]u»»kM®ÁÛÄ ròYÛh+ÚÞ,ÓËÏñ½8{I/KºÙÄÆÛ Ð{¹ñÁ™Ê¸F Ï|ÒA©·ûTæjôî®uEöª¢YÕäK‘É'¶.É9 ðQG6Ø‹ç\!À¦9²é…ñ»OIÜ—M}sÈ)•Q´Ê-ÀP¼ -ѰNQ-8²(µ¬;„v6ä¾â>·‡’bþµ ék[[wßÐî‹›áŽ(UFyÂû ]p©>QÀn—[]XÉtpGp’-Ì”3P×oÐ÷ŸÉZ°XwOÀêu„Ó'øŒ4»wÀ}‚}ÒK×iIA‚ªc#Ñ”0w…5óÇßÀÿé]£Æ(ž£²Hê¬É1™*ãŠpL‚z_> ŸÎ„¯^òn¿~ ÕÞxœk¡Á¾éŽã€:÷R~½N8¸ø¬Ú-^QÕ>.X˯¶*M`/älôÉ7Ûõ#ʶþà¬x€©,ï8X‰'vB™­‘Ä¡ÝÕüüÁå Öª¯X&BL(¼ä"SK QËèû‡§GÁáyk{–ݳ忑ÿëðÒ¬Þ¿A—³.5,°‡§t›¤¥“à£Î€έ¼¹lA g2>®Ö?ä¹@èá;%ñðp†dæ%Šüwð×~¨z/*:¿­9ôõ¦ËìžÌcìË;A'IÏòäÏùk z²ÀåÇäâæå_9+»`qPáçµ þK×N”Ê^Çø\á°'`Ϲ ãò¡oÄàp- ¯8âãoUs¸·矱vÉ‚¡¿ ÿiãt=V±»Â4´s²\x]#ªÂq»»ôáÆÇ;ÃÅrG>×@ƒ”võöCwÿ–ÿ¿Xq‰þMÕ½‰ÿ¡ù«Íb€åDïÑ31,ÁÇ̯Ÿ¥ÁÂ5Ñ+o/#†zºŸÔKÂUž8ˆ|ß}êyY®6µê\vFYEíFÇø–O»V‡cÔÅI]–QpÝÓê µ®ÂÁªù«\ÊAvÝ £[Õ™õŠM-k]Nèf-ºâSö¶6ÝÿRW/ªäž†]&ëáUôÑl·*,Ú?V.têž;QÎAÙÊþîÜ–¾wr[iï îpLÝ1rÄ`µL;qÙ(›$å¬Äk! Ó_Gg’i«žÉ–û,Î,ë\0Ÿ+OyD¯v<ÍhâÃÒ—å CGT¶Š*Ôh&K^á±Në‹íŽ>îRÐ(ÊÍxiº$Žz©ÖŠôBÐY‹õÿ.SºW”E“.Õ?¾¥Ú’ÅÑáØe¦¢¤‹«í^XÙfÍò¿]>ÈŦ ÍÂ,j€.¨¡'ÎKå)ƒbýÒ®Bß«õÓ÷X SÆÀ¿ûâššWÌû/‚Æ4I•¢%&ð,Ä }§TæÅ9>0š¥2Û;»ï³ÝÑ#:±”÷^gÛ\•‡¬àÁƒÃY»Fâv$Ç/±±éÒ#½ò({öb½É÷8SAzËÐ1¯TŸ_ÍÏ€áñm¯ò3ÃÓ×0Ë-/YÙÒyIŽæ§ëQ Äwæ;’ÆSDï® l¿î`èžËE`N~Ôô¹·¯pe×ÕüUÁЙºC ȧد,‹1üD·¨j t¢¥ ægÆod²z¢òtVù^uJžÿ31«ÒëÓ]`d‘Ÿj(ÓïæT©¶ðÖ¼î"ÃcŠ5ÔPàä×¢myÀcxfôzÇoçß²œ—í1ðFÒ´$·k™š^òG7½åXþ¸æü™âÒÓ³AVgÊÂçHˆowÏÅËénéfæ….ówo†ïàôâÕ}ÏW<8bajZÏ3˜ßdÅÈóžŽ×{£?çÏ\ùiàÆômoà†ž™uÛWþ4“ÍíâùÛ×dð‡„tUÔãO]:MVpSf_6Ž‘Á‡ûî—´¶êÝϱaá‘àêÕ©`Ã<”ëzø¯ÇEA\‰Žò3dèg î‰Úõ¤†gioHÓ4/¦YnêðÛZ”ª›{lK®"˦¿åÿ/Uã~k §ˆ3ÿ³‹ýŒjüŶŽR¸q3¸Ç.:²d‡iõÜfÌwmyÄÜûäswæÖÙc»ôýë\PèîR>:íalCŸÀJXÍ· ¾0ö# ¿ç/änÓï½ìtX®cç0óNúðñ›zM°\Ïo”tÀeL2ð‡¦,í®oÛn8/ ¸6cB¥Äøƒbx!ŒÈ¤îŠ ¯T_(Ô’]qÒ·ez {m’;·Ú›cL޹ÜÞ׸‚ù|Y çAp/ËÒxû.-}ëÃ¥R~åwš:À{­I+"Ä/àíëxù8‹ÓÏ/’Z!€©©n'—×O£Òa£[/‰ šÅJ«ÉTšã–'D»T¡NÏb6Çnx5"ßëíǽµggöN~îZù¤ækÞ\qP­Ëïp.»k$Šõsí#–»å4{“;Ó±x&bÉ ÆîÈ\¥*ó;{ Ì=ßÒƒõCéw …·LŸD÷”éŸt奷ƒ>'À¶«‡3rÍ"½2H†–4¾pd©ÕŽâµWOΊòʾ;CÏáè²"n\(&ç¬Ë –¼×.¡­ {ˆÚÚ²ÏO’Sb/ûtöšµŽl[ÏÐx°”úÂn‘¾»cÌö¶üJþ†þúá‘í«#RÝ[úrâ­¤=žÝÜŠ=âæÎÊ‘•úól2Å£/— ¸Ôöªåmù{z¥}HÝÚÐ 0ï¨Hø›§sÚõf_÷ê[žcƒÄ ª¤5—ðIcNkå©Êã@ ¼- ®–{ ÞQÛ}æ´¾[)Ü@ŒOôZ'{œ8¹¤WŸÔ 'ßﺿؾþtTú-õßý]üïHÉÐJõ.Güx¡Él` ØsqÿYUzÍø…ŠVg¯Ðů=È´+'ʺnÛ¬G!aÖ¢ÝpC¾äQlŸ.ÿüss—íšûZ-<äµ-ô'|AÛÛxÀUSƒŸó¿áq³¡ýó"ÿ]±ìR¨üÊ¿]¡’†YfŽã þ,=ù³­©8цí½öЇÔÃH7Mö• §ÿ>v© Í™›:Ü8‡¸aüEψ±—»÷×âmÝAV! ^(è5˼ÉëoЪ§îNÅ›µ,:² ‡sž4Ї’ Y¡ pÃ5òßòÿ×)d¿àßÞÈ>á7,ü…Dýsï÷‡ëýYçƒtÑCe†k^=j9ÞW•or›Hå&êMBS3tŸÄ?ªþXø´Þ»SÁ!µ[¼jS„R6˜ mŒÝRÓ¬”pck –t…ø;D†Á^ #vp*]|2Õ£./™Ý·Éè°*¹ÅüÉsKe«¬ë0;A…Üîq rë €‘€˜¡ÞËuÕ_JùœgnâØ`ºÏ•~=ùŒ¥µÛ©­’°5ü0i½sw,Œ"„ôÙ<8JÌ{ñx–h«ò#…34Gv…õæq/êßž³ÉW~VÑVU~O(ž¸Ì<¸’½—×4Fœ7¾d†…•ȉys5žmpòé~úî˜Ð‹ƒ­9°XásïýÑËéʾ¹ÚñækÆüÁÍ\jú®êÚ¥Ç2—ˆAO§tÁ…67^£Ž¦ì‹Vͦ¬z¸Ð(ÅQ€öä…CžÈÃ¥ûI~—¨¶½}ÏKr?Ù{­6_©>€ ñ ­Þ…·k|Ðo±Q?ñôýØæ£ä}Óøêëú’5‹Í×½ðJ~ïô¡ NŽNTX·p‘Ôüª©½ÓvŒÌ|W¹cZZ± `LÀøfW‘ù9ù·1…¨dí<¾cXÜ=äyI¢ªëºðË›Ž]}OçHtìZy·o…vÙ½i®õ?ø!N.Ü÷ŠW½zÊ †~ùΊKÖsp+MÂN™‰‘{W¼Ÿ-a”vEÚ@˜kÏ´ƒ‰È«y4ëÈt€,^þ€›(,‰~uðô¶jï¦vÂ÷YMUI¥@w}¸§dÕmêË á†B¾Ô;áÝzêJÌ¿†üš}—.]e†µ ž¤+Ì®ßÌ[ºÈžÓ?Dø­™÷ñêÃ¥HI}ÕmôíšÏWõ4Fâç[T¼º™°ngRÀ™ék>J´Ú¶]Þï,¨¶È¹éư¼ŠÌm{ö}ŠÔ‘ìSð±”¾nF»{ýÅîÙî;ÝßÑJNTE޽Ǟ¦éóYà/\º°QÉ)¸V>Ž(µ Žïå/fÞ>Ê›:ìÀȆÈsþôÂ,-#Ò<‘ºÐ½ÍV¢-¤rÛq“×2F«[XßdôKoÕPþhÍßÃß©Rþ¸Èéx·4—³ÖÎZ&^XÇ’²Šœ=sqgÛKþ_ào“Ùb-!2Mì¡^Qçø‰ÿ‰ƒ²#5 NÃÌ þ,5¯÷ßÄøë«Á‚mÕvÁ}{L·…%l&¢Jª’«ÃùS[Úe¤®js;Qï¤ÜÐS×Qý ño|=¸6(nã|õñb‘–Î{îÇÖð‘G!Ê æS¿Œv^)Úâ4¶àÂìBóŒ~A‡ù‡BhÉm‚¼^J+šUrÁ‰Ù\úýŒ²>>ãuykzv<Møìƒöß¾Mò?›-b}r æÒ£6<‹Ã 36EDJ6‚!uxÙÌY¶WG‚[°þëµîÀú·;nY¸Ç–$é Ü‡¦ïê'À°÷Ãå‰Åç¸j”½JµÓm÷pÛm–in·RŽbÕ,é‡öí¼^Wg'[Bo½µÙ¢ýœËý¼_pc[è¾àþù….#{gäDÔÕ‡9pAŽlÀ^&Ç TÕƒQ®ŽãÒé©fÙq—’8GT˜Á/{»5wŸûYùBz†û'½Š÷YÊARµáõÒÌC_*\Yï’äëáÑ¢Š8Çxx$ÿ{þQ®¦ÑA¤jÕ+kh³ršõ[üöŠ€[/$ó†¤ÐÛ^„m¼ŸCÕÞú>C\ÂzÞ. T-èÀ¶'3Û Ä#I*DuÏ„Û"‰E;ÈMƒ†‰Š@ðYR_ Hq‡'HÏ…¸«ç{`ØöQì¡Ø4{ '? †ÐýŠw!­P<:`È`-©U˜ÿD“v¾]ñ<$ªºæöö×ÙRNêç~ÿ'¼kô-w/l¾:Å¡îͲæbÍ'¥Në^¢CI ƒ±åì¥y¼OÜž¬¢ûw¦±å®×r¸Î}ŽIæ»ø7XO u:pJî¦u½gY¼îa8 ^)szù)ü눳;V}溈¨h{ZüÄ_ÙÏ— Àøƒ¿ï´hž'›qþîåÿ­=3ÜÙ7^=tö|aT|…Šáuu}œ `üCwžÇø !þŽy=|û¶[Îó›÷øØÊËmikظXì雯úœSæ©Ù—ØJ—´Œl®XpêÖú: ïR%Ÿ8RÈŸ)ÿ¯oýˆòÿ#”Cñßß4æÏLÊ#òŠÃÏŠsÌoo³h¡–lhðFÌ[$M«H(u•(ØóFzË€©Pþð2=¦ò"ÚÎîú5(( °€^ŽJmR€R­‡ëËúA8R}Ír0Rc1€ŒŠ½³®=«nÚR§|1ìÑê•ÄœUþENãþõÝlºbofçT–¯ÞÔÖiñaÓkÓJž‹Vn‹^a¦‹ÀÀ §czÊ<Ì×'X4ÖðÙCF´:¨¦ˆ€¦xÇ $0q4³ÈvˆI’ûÏ¥¾~ôvcÒ’eÀsy|eÄu&¦—w¼ò’­£½íŠ? ¸ÎÃÞ‡ª<µ‡Š­–]*¢·ÌbªÓRUØÉn?—â¦ìY[¤º½œ—tçÞ\A¹.¹ÿHvŒ.èlŽØÍZò4iìÙÑ”ïç^ãkJ0Xæ·@IǦIrb”h¢R-‚Džé.TV0ÜË_C-¹_pýsg6ls¾¹?Gý[£uœzŸ|@T×@.Ë¥Ó„£ðÆãø[¾cëw°ÌZ;õÅ(SQ˜Ï>Qæ‚LG4øéä._E¿ ÁÄ@ˆä÷zE2 ΀J—K|Ni½›ÃÏy³¹s¼«rÛ“xSF*âO¸¦uAïÜÇ £‚2tâ•Íwf[£ñ€r©u ô:I$¡÷cxÞÚÓügáLàÎ!·í‚`¦]íåHoi‚ŽÖ+!ðy®åÈ#&¦oT…–kœ$>b©Ù•ªuÀðÒéÂáêý]¶ë9ï÷}hWÿ ˬ>½`— ‡¢0Çaºñ’Òó Pm/»çÅ©CÛ}ÊÁ)<®¥Jü.þ"ܪjGbµÔ7GigiuA¦—~xÿv–a¨Ø0K­M?'t}î¥R žÚü­§cÇØÀo…å÷ð?ב‘.³L(¼[WÜШÍQ¿,KH„$Á«€)þn‹_àoW´h¡vŒó–]Ç.ž¼¢¯üekz=hb˜ü1ø u¥áüÝ/¿àvàxwU<‰rstV»bû¶òÝ5*ÁbÕŒJþ¾mÒËÖÂxkñ_‚ÿÁ¦ÛNÂë齃ïf/á „CoOŽfœô5«ÜØ´ #XÍ?<—÷~5ïkÆ…¼¶œk-iÑKVHÁZñßòÿÃרßÑqø®µƒ?¯øþWoï ZOÑÝ#ƒYÑo$˜)Hpiè8tZÊ‘m  G¢rî˜-›usvð ÞMNà‹_¢˜X&HØ4ê2ëÝç¹sFÈþBÞÝ~ÀHì\=Àº ÿ]‡ã ÿôÌ\°Ù .Ïôõ€¸vËb˜Öºó1}qZE$¸ïذøþÝmƒÑ÷ÖkK\? &™¡`[¾?¸D™à´ë¾é1¥Üà<.™¡{‹–)Ȇ[ˆwåê¥Z¨ ¨Ê\´^ŒãÃâ¦-íó.^Éqeæéž $‡G"±­‡ç¹Å¨ú¶C¶$Yåææ+.ç³}Z¶ÎÜð”¶UÀÆ[¢–÷Ž ð øñ@ýy±$Á$Âåå%«Ø\ü kRwIWí &úû[&GC™—l&¤ø8Ìvñ|FïÑõP˰ÍÖ’ÐH›Fõ 2®³•»ÁKìô‰m‘{®d:§U¯GýÞ̱OekÑÍ,ˆÝw»·-ÂåóÜTp¹ûæL»›T¯±•6ËRÇè‡ïz¢ªxŒö¸€çÙúÛTc´Ü*ÿ2î(‡úí¶ép}¨ké°ö6ÏKçHne›µºd®k¡´‚}YKzãL”B~ªg æÇt1mØ"VèK\h.dá{ê@>pDùßó¿&7XNR¢`E¢˜ÕÕ «Qddûi~ð|ƶ§=°H#yEh¯EÜÔÛ«_œ¢iÞ)óíÎÿ}eÁ(b8ñ!•ê6ºœsç·M‹4Äãý›f?A¹ÃëÜa¯my,غ¸ .ÑsFÀÛeù _ïÅÑÀÒ¨ßEWk½(AöË— Ä—~že½Š×ÔÏi‚3Î¥/¥?宕Ýòü`Áïä_ØÐ›ÍöÉâîö°fÁ¢£¡GŸ”¯LS³oþ[þ삸Gþ®öÏïŠÿÄâð¯~¬àûv=üÖ‚V^IUÔº­¾'–`ÏjMÖ’;U‰w}–oY°ÛƃSf<‰<¼ý,¸‹Ù p4nÿœçkú­ Ì›ÂÊ:Ø™‘úÞäF?C¡v%y7¯$¼•90Êa÷\X[¡7Ê5q†È> ÖRN}J­ržÓâ«„]¯é71¥í”Òi|’Ök7Êí›d—c!¢5êNI¦Å /‰®x¸ÿßß„µ»:S¯ÝV{p ¬ð@óþ릫žEÞ{*üšf”Kd{‡ºQC?.91/|ö— ØÄ\¶ƒ½¶¢vÆ­ÖMË]€'Rz%ÖͱÄðõâ\Jú‚kîÀÖ|梌®ã©³K§·oBEõÕj"ªKo¦ÞY.àÄû ¹wþ]Kðì&Ux1ý`9ȾpßÖ±U‰’ý½Ë‡Ÿu][sË*˜í¬ýýü•+‘šæwú'×NÈÇ–®açÎ4ºùÈ®O©ÊYó€˜{êU¸Xì,gE•î#~¼‰ßÇ_§ZfûX7P.¾ÐþÌuŸý}xw²eê›xÛâ{)Äua¿Ä¿ÇçÒ ý¦#v½ý—è°'æ'þPª¨æyÓ€ þÑô§3’ët1þÇCuüþ&¡²’›¥o=©K:]ÜX”„ÄØ.Áøå;Æõ]½ ºF–ûØÏŸÇí8ßv˜YV~ ™ùÁN¸“¼À¾ˆ7~Yí Ü…61*¤HŸY8vGë©pÜñ Ú,Íö¹ÔEþ–ã9ûÿ–ÿºüKûø«‹[Àw|}àÏ+¿+¿ñ{‹Îæêy¢T0 wô.ñQ+÷¤¨ôÌz[ºÉÂW€=ã¶½:@ œoË(hˆ˜Y¿¨9n[±éX xU¹š|*?µîù•Ù‚ÆD\˜§­;VÏÔ[ßP`ez Ö¬ÄþÃÓ¤žŒM %<€Uïf߆HÚ¦ëì¢Ôý¹®W;îªm¬½i‚ @XÀÀ(9cŸô®W|ñhêì˹ÆD-x`´»Gk„¥ìÕc`Z¾õ0%lØvÊîÆ' 5\Ãùz<º¢%ø®›ÍÚhàPl™o°Û±Cøn¿À‹™Ã§o€ê‘¥ µ]*ŒÅ¬äÛF! l_lI›?ƒbÍı¿Š rƒo(¬jNNˆŒà›‹ÔäWë—BÜMX§vî"zArúª³ ßnp³O£«¾ Ôí{SHÑ€¸2;Øä]‚Å s«PÄtýº±tÅËw³Œž²\qõ=â¶yºæ“ªë:—5¹ÇüóåÍj»ßÎ%v¬¼Ý,±A¾ÙcÕFþõ¬R{.Ÿ2·0e=qØ“É /5ôÀøªŽçQŸ†5.m3}¬t6?ël_BØùCþ3ç—­ kJô¾â£Ÿ@R’›؉ Qí’(¢RËArŸ¥x¨PÊt. ;R.ùð •^ÌL§íÉGø7õ3²ø\Û¦ïªÙ yñ; š‡1÷yVxây°ÕìÉx½„zŸ kN¿áXð~Ãn-û8èzÇžn~ £­ÜžM ¶6o6} è¬dö²Ëá¯0÷rÀJR'¬^•‰ME’ìz¾|fÊÍ¥½RJ¥ÇE8¡é~»‘>ýã!ï+ñï÷noû#øÙ“8ÐeC]¼f鎹̹Ÿ$av{•»ô\íÕ«¨ª©o„$ïù (A.AÞy2ãÓ¹ïâ¯ÙQÄÄ´{_ez»ôè-Ùkb >ÀðÙËóÎ\ëL±v›{à/ñ_Ì´Ô屫E†µQ¹ÞËßð/±€*¿ÏÍ0É?¸ÿÉs±]ÿ¹·Ú5(`½eÎÑâµÂ3橯Xç)%ì Çà¯âx.(0à‡çŸuUu»¸­VWÄ` Ü¿1~àŽ ½ì—±Ì€ì…É×ÐúϲÛT7ˆR–RzÐÏ+½J¼è_Ÿ?ºƒ[líµA?Mþ—›ýhòÿ?_ˆÄÞßöÅ!Žòû/ò+ÿÙmÿ÷ÕU*èYk.×ÓìºÖ±ÈÒg6}º•°Yju©Xk¾Dé9‚æäà’|~€²ü3ý uY÷½tä¬ÁăáÕÙ°bþŒxÜ.ÉÐ*oŠæ ²E²6+sqŠj,!ÝaåÐȈҋÍd¹ÀV98ƒ¡\ˆxV?‡9ºéóÓ> ?ì©c©1pÑ 4Á=!™Ú0 --V È×Nçê5Ç÷Á”c‡\#vW¼c‡½*µ{)ùäŠbíÑÒˆYq†Í'd{©‹Z8'LŠ-Û¥ñ$É;5}î€í® *n鑽kL›Ö?Û<8»{« Ôå&9Ly«×ÞÖ,|Qv‰ê)!£s‡#Ázý“õ{jáñfKx—w@31$ .];.ÿ¼_2€ËƒˆÂ†˜±àÀ} w¨ íqô|a]! ŸkÙ X(©†ý0ýM0ê’%›5§jæç]²¨Æ¬N:ï¹c IÏ=Éc ¹ªû¯Ÿ50=Ú°]7¦cÇzH¸pÇ.t_YˆúÈ¿ä_+Àk¦'—è¦X Ø”YÕHâÁú´é+w‚ß'âœHt·¿U³Wnß{Äb¦¤#Gwƒ.Ýàѧ“ÁA±f|gS Švžl?)¡¨I\°Ê;ßÍÚä¿}t§øb‘Ì3~ÉWc…«HO3{ýr¾¤• •?…×Ç`Î:Dîíõ×ðú£Ëq¸+åFô‚}Ù¡Žç7Rºƒ™}•Z÷Çð/b«°Œ¶.osd­ £-hæÒsgU¹nº[€åŒ”žÚ•ØŸ}eE\Û²ÇßǪݵ ¶áQ†Zצã÷D‹áˆ TTpÖk߉>È…_âŸg€¨7ô,ðQM£`ò÷•¿P|^SÕ Îb“ü úïö’wãü¥.s¬Áø†~ô=—sžo,ý\ OWíŽ&~*^€óOßÙ%Â…û$QËœ8g?2>XÞ>0ýÒYØöºbñc¾ÝîBb`F¤‘£lC»F¼îF8ƸÇóº7ïdû<-Oÿ¦`¢{çØæho–Ì[ÎFNWþùbþáäÿ¾ü1Yp²ãá'ˆ3ûÑŠá§tXm­Åª³–ÁçvfQ.„Í9ioWmO¨^8‡ °¦?F8ödî%‡Ð÷¬ûà±ëÙ–œMÖ…›&´«½ÜÐú,挂àÍ# [ÿ„ F K<¸¶À°³0@ÍÓ{(_E!x¿ä âçi4h»´Y\bL|`K«ËE.´êð»2ÐfAÍÚ™EÖ¿s {x?å¤Èi l˜#ìÆ­Ã^¢ÍÕôÖeˆ–oØøÛ‹lÒrÚæ}=Ô¶¬â¶ŒŒWó¦ ç¤yðúeD¿Ø#[Y*Hg5Àf«“»ÛϪeÞÕ–iŠ#Š ÉŸ]Ú岨æÅvéHö£»oIƒÞü q8ÿ•äÈ$^à¢&ï?N£ˆJö4·*зÛ~â>Çžf‰8Ì/m™¦áµOÅ­Käbd$ë¿Õ Îgq©êáîg áy¥ò 0ˆzWÜýºZ&&¿zåuÌ,§TÑf•Qû¸x‡hðº`Ã~õú7à™taðNsñ§^ùcªof¡°J“ÙÙâh”í‘æ™…0v%7îÐ-Ê*3Ã<á:}2&I°,-7Jnwpå =ѽòî'N8J ð_>BßÈÍx8i×µ`}M›é_þ–ïy–<õwÕïNÐzX]ç1¹Ãú7­œ^þ·)¨ï*çAqŠÞƒMјû±àP˜„ za\µÄ¢Ç·s6œ0Ø}üù>kÞ$ƒË}}Qn¯ùÝ£!9ça3¬iü<ÈÅ–náÓ3³oP`oKG 3_Eh¥ÄR`I”`Í…þsOäÏf»±£Ppg:K)/Ë·nï'ÿQüW‚È·«Ï•ô¯]ñîþŠÄíëòõ„ˆ)#mâ{7°{€só• ç¯8cýü ò¸n®7N.±Cˆq/§Ã6‡ ‰pÃT¸vÖ¡°û—øÏPG rFeXmZ›ßø‰ÿòWöp•¯tËbð§GØïvÇø™“¿e‚»`ýîcÑ´Úìå‡Åíó%P¸Î“6òŸ$ÏB¼¨.;}q‡ßË?ÊյЄ:Kjé!ö0ñ>$ªV¿ ÞWæEFDzóyªá1ؘ§wçÙ_Ñk°øÌjw¤ãàF\PX/q’÷Wüßï(qnSãëßËA›€°x†ø#b®½NÏ¿B¾4Sêô-¡´“*7½DcNe}z&ŸØàRoXÎ;+®gx‹ž³EC’Ô˜N(¤sòÁñ6[•Ë´çû®jžéïc†5‘õsFfÙ¿ÉÜîò2gèEfF·2ë·Ê =V8¿Êêø)!5áÔÄ¥ºä«Û£Îq4 ¾-Êß)ùyS±‰ó´±wÂèòÓGGD"ÏlÌ+ßMs?«+BU´OÖ®Œ!ÜX±ç´Æ3>¤ÄeEN<½—˜‹¸f™ þ2Ò/Ãr«{2ë@<³v_­ãœç¤›’áQ9ÿ+%'EDèä‰í.€¢Hƒ‚>T¼DãÈùC N›fÌ2p8C0‰Î3ßÙíR?çSBLÜ»[òﯜ£(Úm9wÿÔæ¾  /w­E«ëqzQ½J‡j¿H¶7ØOpåè[²=ü_Í ›¶ÙÇ}KŠ<™¼Ã•Ïî./yðdÓÍy’«“àQ2óÎûÓ­ªyîÙl%Áœ½Üh[¾û[¤ÀjU©×e…š_¦ï .sÏ%!÷͈¦±ûuØ”¶ù#•öžÙ†T^:TóMõ_Êõv §ïwƙٛ0/B¤°ÈíÝØ–6*àÿ2h.£UæI PÝ,ŸsW‹®"o‡¤.ˆ60«ìñ µº~¸tØþjßü„Lêvºu/mO9ºFI,lê²àÕdè§¾:LÏÞp!xýü5¦¹EÎ^ádÙ`º]÷”tì罋uŽ‘âź·Xö¼Ž¦¡Å+UoF¤—«š~'ÿÃ!ÀöòЦû+/®Ý®ä]®·'o%´Ö÷ƒìú`ÖM-¿Ä_ë”ô p縔šfì¿ÿfÅOüÁDß!ÛélÚ8ÉŸ¨Ôè‡ìÀù#2W0þ'EÖÜœ7Ë nè“ÙiÙs7¯«[éÀ»^àpMþÁ¹Ù¾‹r‹XþŠÇZ-nkì‘°c$ex¶WsŽÌ’Õ/Wž=[ãÙ[ÖÌ}9¶Ï¼ìtòÚM—ÐüþÙ~6» ¼9gZôpROÖõ¤…Ö;õ·üÿˆå·ÿòï¿,Îaÿ¾Òÿoenóéü!ÀÝõ(€v1©~¾`Ò8 äÓªžQ,¼Õ½G„)ÀŒ²áÀ Ö·÷ÓEîhÜŸ© é<3»0°žÿ"\‰·½>™»÷Ú+]¸í®ÌkÀ_¢è$ø\³×Ea§: ŠyA! £A~3ÌŸ”@ï~lÎêxí“OÖVù|žv¥s›vñ=aŠ«Ju,¨pkèçuŽÎvtˆq$(ŠlÊë"غêØ) ϧ¨}.‘uÜí¾´¨”ðÃãH±®u¶æ§üšã‹Çì2¸É*\,Y̺Üô£kÏ›CÚÃ{CGeý7}¶»åü`qÝ5»HPHËÉf&ê› ­§Õ«[L=¥˜mt娔e÷œ¡óž¸¸5Ù¡ØsÒhÉ)™ê²EU©EBáþž…GC¶'E%'55¤´Û/ |žn¦wuM1ܾڔ´%¬3giRA´’UÒ½0 }_´SâmÆó¶xð%gF¢%s‰JxÖùÃÇÒú9Áú©ìÞù q( »Þì ÌÌœÖÙ9új.8_yö`K¨Á2U“ÖCn.‹Ðå‡BNÔabõrâ ”«´Õ™¬ÍåÝ|ëºoôü~¨‰?þ£^÷Ç*Q0z'Jw³‘-¨€yÖ µÕ5lWÞïúnBÖxÚæ$ù+ªÖOù²è^7V‚û¦ &&›’?–±£³JA‚Ãá“wžiKß=A¦$¼S–bŠvûtOtŽç' ¢UB’l²?bE_ûü/WÏ5üìe+…gÚè_&V)oK%Cž¿qLÀž+Ž¿ÈŸ¼Vû# o愸Êi²⯸ðE€Ñt¡IþÇÕ‡Ÿœ?Ì©+I2ë:}!®œe‚57ål¹ðJ"Üó´Æù_ä’Ýâñ® äZ÷ƒòçï;Êaý˿Ӵao²*¬¤ÝyYqmqmôܼÉ:\³d>\[d,Û —zŽG…ZÊúiyLCœ;è½y¯¶¾ÖÉ64€ÜN^åÿ‡+ßó…ö]þ”Ÿ&ÿ/o5øYq&k_(R•©Ø¡04?Ÿù€Âºûj3EÝ"Ca¥dó öð_êo_TRÞÄðf りLÛÞ‡*¬óžÓç°¸;Ð9t¼B ;yg*ìçXãÓ?>º`xWógωŽrV.GnlG(CïÜò*úÔI¯ç§Y  ~É:6uñÄ¢KsÀù„d]pé»û—&NzKÌБk*æ;"~…c`:2Ýp´LßÓ}/Ï ·æÑvãgòðú¨*!>eDùãšB[Òrñ½µbï?õeÊŽ­=f~½¯Ê,,¼(îµÌxWî’"vBÿÞ¢ÀPÿ¹Ž¹£BµÕÁ™æÃóÏ´šþ)yÉåXÓÖõ%ëI®¡cc¹áFÐi²$÷êr±“­KZ·j%³¸}ËÂÆ4`–Â:/ãœð3×ÙêÛš À× ­½Áï6E™¼\öÖR˜N¤i+‘È$J5)´4*£Ñx#wL| ¬RZFôžÉÜ;à¦wÛÁ }QCØAâèv4ÐÛUàç³ÊÉvÃͬ"ZsÜÄÖ­°AŽ˜¾‘Í(‘cÓGÁ=K¼¼R÷¤iŒs;‹ßž’dçúd 2Âu™"»™×'Ùp¾ÏKhþðsþ9„¥'<>Væd7´«¹³h‘èÞÑ•îÛz‹´À»2îÑ M;p¿„ïRúÂÅB&ÁU/. `$ÒtÕHÕZ®ç…÷ÎiR•ÆhëÂÀ~`A2䘨ÒI íÚ ÚœÕݹlBÈn¹_Ï€¨kÚÛùp¡ŒÅôÄ‹‹—’gÛÆÌE–,‰ôH«ˆ#k]·u™ÊËoR.ŽÝÙ(NHø<²³õæß±±;âo¬ëýþQ¼…zÏÒ£Ø/u®X«0çÁ²ÁÛumç œŠ/ÿó«£ _JN@3ÓâGw©ûµW)™V>û >”ê_äŸ)£e² ‹QÉåAtéûÎ~?ñq™»–.=kßMò'"ÓüÙ¯¨`üË‘Ùý¡(v›Ëàe’¤sc‹y‰õj)Àþ' ä—Î6ƒQ»&æ‹Æ‹‚Ú_ýxü (9¢õ£÷÷_<+€,óÖ¥„06â'ðkÙ³L|Ö¢ð4MW¥&+¸4/ä`£?ñ¼J›Xç›ÒéNw¢NÉï*Çëû4J{N ‡¿2û[þ¬Böüc¿½@rþ£²æÿÅò‡:šÅÏ—“xWß;Ö0¹jw­ÆÚ˜üéÔñÓXd¿esñjʾm&ÔKg‹®JãàæËõc&•ØÁó9¼ÝÌ–4¶žÝFc«—É,’»cçónè@ˆ`Œk—ˆì}ˆ’à—Ç{ÛÈ@ØjûêNQ8ÁbAÔèD†Ç€ ³Çr‡Ûž·ÇSÔSXäxò ÒÁÙì’º°³4w;¼´†f×]0ĉ5m‡®‰$—Wñ—˜<ó‰4Ü0}Ep™C­Ý#ѪLvòìy‰÷Ʋw•òNß²ºñ¾¼¿ÂÜ‘ztm0»° (žôJꂚ‰çâûœw!¨ùý€ø;äg¬{ô²_íÌBÂËG‚$V¦K …&º ÜL¹çš²é@ˆ=ñ°@<ùüIÛ›¶cDÛH*‘¢œÒÞ¯>æøôv¬^6›rvÓ^dVTöš@ ¦T„óX¤#%##rQÑ™»Ö\ð°Iq4L ôþ¬Àu> 1=/3Q7búehèòWÚ²`m>®î¥a\•ìñAùÙ -D-ôWRÏr@RËW‘³¹Š‹þxþ7GÓJxï˜)˜2!¨ZF, ž½’JU~Bó…ï³lQ8©_ioL¦xt­ü^þu‹wìpƒæ¹Y Ÿ²3dÕŠ]—vÙ)6F8À»9¿ÈÿšõXÞË‘ðxÇø#³««r~â¾2£Ö·w3ø¼Ø3¤Fœ¿±Þ†Ø´ ӓ󰨱'ß‘^&ŸhX?Ñk®|â±`Œµð[Ã0²ªE¡5k¾wÁÐÇ¿ëlÊNNPÎL€k‹Wö©5@Z%åQýË Î )úoæ?›Ø;cd^líjb’cÆ£ñ±‡ÖNs7<‚®Ûþ’O¦SÖ‡z7Á©fcq™¸›Ëÿ?–s -ù~Cäþ›*ÿQå¿þÛ?…ßP·Šö×ËêXŠ©‰J·üûS(((˜¯ ( $”ŠõÁj£ûH<”ˆ}$¯ˆ5"QÈN1  X¬! Ô©v$«B&ãõ\¢h@F°K)(Š (‚ºDbw@°F€U'ÒPFm"H%Ñ€„b×ñ¦h~{Òq¬ê¿· «¾:™±˜„ ¶eÔIÞøÕ]Ș:hŸ4…†LÁž ðK)vISSdª ‚¼£uðjX‡½C©(%OöŸŒõ ðž“)$:‚wë"Öe§¼ÿN Xo¨(¢t¿5êŠß`ÊMc¼`7 ¡$ªOÙ%’†5eŒJœzÜÉ ë.h€\b±Ñ£xĬÿþ^ô ûcc‚=;Š’¡£þ@A±áñ§éžAб1C¼B€FQ„J’}*a÷oà_>ù8Æ“àÄ?7ÊèÍä}‘(Æë׃äCx6mª"ƒÆŸú¥?“•'Ï2šásqŽ¢~{ûÇàÿµ:e²"~=üŠØ1ãáÑüüOE`“ûHv8Œ69 ÒH4" Øôö§Ù&¡8Q &‰ŠÝDõóŽÂ&!‘Ž¡Äº}ÿ  DŠW8 3 øœÆá³ðäÆºû3þ@¢á€L>Éþ$×X 6Õ#‚Áñ¢ŠñǺFBQ\º°Î±7x·À—†K+ ¡y†`µ1þàDVü òÏLÄ“MµrlØÀooN,*kÓr „ c ±&:žËÿ¯-?ȶ€ßh]ÿ+ÀÿPùõ@5®>HŽÑA¾„é¬I¥‰ ®4ÉøLE0A ®vg“67ï zG0”çÔ‚æ0L>& Œ:dþ‚_ûŒ]›¿ö‰”ÉëNZ|÷:Ö„Š;@Áý ¬ã3à  â2M>KU‚Ó AÂ4á^Æ;gâ@ƬPCNO‰ú“đԊÝ"¦”0dyR`òÿEö`RAùú’C¾¤ê9ÆC0^È~A ˆááJjª Š`ýg ®¯PŠÿOhJì‘I퇔ÎðnH`žN¦1ü„Lþr?2êƒR±Á"!¸ â×Án@cŒ‘?®U±qÄÚâ² ¡˜ ’€F$ÓI~ ¿¡_ Í?bVÎéà¯æ_?Ñ1*ã?¥–¿±¤åÛSg¿ÚŸˆ)[À8æïœ€þ4¢ðí©¯/dûDÊc€ó¦MŽCõ£ß˜˜TÌØŒ¿êoç:ÿÿ` ®fc±Ù‹)\:æ (•Hµ=ŒM+„1ÕŠÛUŠo /)”aw0·¡*~†ÜP'í3ÃHÁìîcÆ0ÄêŸùO=-6÷Q×(*ù+LbF&e„èCC‚Á¸?æ¹ ¸láÆŒH¥x#Ø]°+z…â½›6ö=þå8LP êg°Ðœö`TT!—3 zlX^™¼ûoùÿ•åǰÿ¿=¸þÛøu¥ ø]‚ñ éLG±‰ŒÏ:”’0Œ6¦ÑP÷yý鸪¢2"ýI‹ˆ=¯ÈP~¾ä0Lsa8×P¾ºD†àLú˜M&ÂqÃNex¾LKc®,£‘ÂС˜Æä…!ÓxC¬"bmy2 &C Øsgcy÷ô1sX4)tØAïà)Kà« P†©Qð œrÁ'£”I p(7¥âp!%;Çaª"”6c≧òmj$H¸vŠÇÕà ÂΡ>´ ©î#`Â×{M2þ$ AŸT)t\sc×´Œ £àÝÂGôŒf (d,òÀLPð” HîQt<$ôÇF³@@ (…B¤“HtìŠR­ÄÆ‘L%¨AP/_É¿CåÌø’[ÈÔÓ~ Žþ!Üûò È·ué’[Ç#DFJü)ønüÖ-§hFþS>îØ`BèKa¸9$*aRÃùÓ'¯ýEâ‚5Õ³¸ÒÆÃ=ë?#'+BÀןr 3†×óq2ÒÂ<}|P0sàŽ…¶d2Pq Pý<ÂâY‘4Ɔô÷ ƒoS¿ÿî}Ùz:äM*)Çx¼¡sõ›èï‹Òû)Òû&ŠDÀ1=”è÷Åv¹öOYßÉç™TÒ6VßË¿(«EaÌ?Ì@àÑ?žÿÇâlŠaáž· ¥‰4Æ¢½Ÿ_8ƒ`ü=ü‰˜ŸAF(þÌ*22úøÊ4â…5VúþεOÀí.x_ùãá&Ô2V÷ñ(ß=8à‹ø1<‹À´Ò”ÎP±€FÀ×  ¦_”ªˆ@Q©R:ë¯þïù—Ò¿y =ï3Ùÿ/º~aã×TD_¦Ù$ÿ¯ýý×Ñß׸h2Ò"¹GÃ7YÞo¢¿o7ôJÔøüÏÒ{H&ž§Q„æM¤ác+füq/—á(Þ” ¼×ÊßÅ¿ iøZŒ ‚§‹Éc†ÇÉùø3Ü`Ú䪉âû*cíŸ â1(PL¨R¾‡™ÜQ‹ßK© k‚ñ¯òÿÁ~þ´³( ³’˜ÃF¤ù¹%`COP?ƒÙ8Š­IN,fºqR¾š©iصMB1¿ ¯ˆñWû[þÿ]ù!ìÿ÷[ñ?×øúz€ëÔ0–!Âp<1'%»FP'Sÿ_L<žúÇ7åâ^À”MÇ"Ʀ6 ÚE£0¹]Ï—1V`j§¾€'æp‘Á_0UGrŽƒÉ<¾FÀðˆ´)_€Jšücÿ”2”QñŽùÿ¿ö®„»m#Iÿ¸µåØq'™ó2cg'ÖmR"%’8ºº”¨ƒ:lGY'ëMv½3/“kFÑeO~ÛÖWÕHÎYÙ'å O’HºÐu|õUõ‚ŒÃ64ПúlfÞÏ~Ìa¼·Z?vøwuì™_2 z¦ö²?Û"ŠÑô^쪫Ê0.Æ<ÿÀÿñýó•,hêA²{fì12Jƒ¨w­#IX¿Jj˜ít"|ÇÝ/•ßü¢Ä— ˜R?H×ÖiQ Äé—„ÂgJ%» ú¨%ÓÌ/¬oð 4Lƒ,`?Éñìg… ì`–aÒõç[YPïÍàÝ_“ÿ¾hE²ë÷Ÿ«}3î B¿ydãßcùÓ¶×á̆`9@ªò/æbÜÛÖů$ÿd×iì“ýlWQ[Rí±0Ý / àë•åŒ"Hã_—ÿ'_iò_iÍH[¼§—(ž²#òŸY5J÷‹Ú2­ ùãµäY3†÷tA}‘.pm[! €úo%ÿ…ˆ´ZœÔ}í_lÃ, Â’­¹{I½ïlnn~ƒæÞݱÚéQv»ߣÿ^?œ¬ô¡óŒËÑG§P_Ñô&臩ą‚³ íZîH²¶:Zlj˜øþ–”/†ú-’MÌ#¦j¿ÐŠ™gEà´a­‡Q ‘Ý)Êlb…Û ù¿ˆP€IùǵM¥ËòÇ¿Pæ‚5Ó› ÿ©6ðê=©M* F^„#^þ12ðíê’MJá8}Æô{)à£hîÖw«úù7w\ÝûO_‹YíG×.çÿK¶ `ÿ_Ù žsà7F^î8¥'úǃ lÑu¤ ïRH.âs„ 6&â)j6ú.~ØŒIüeÅ¢bÝQ4êM ð¶Ó!Ó¬¯ Íß'ÿ ™;ýØSoù¸É¾]*©ÀB7ò©»Rµð˧÷¶á¾˜¹÷¾±ãgàüš‡m»A¨¯¶¤¡…F²c«²«ßÞ…îÏW_ø!T£<£›]‚nW¾BÔâà$ÝÔ®!¤ B…ÿ(>ø|V(B÷26¨nð`^Û•}å®P¬ÆzNKŒØçÇ3«™„&Äa•õ¬á¤ 8ŒÜØ“Z‡(kñìù·Q ôÉà6ÛV8ý(2Y<þ²jà½"ù¨#ê¡_t‘­¤m (¶Á ¯ÑèëÛÿ@ x$œKГÀ»lØZµuÊäRiÛ‚É?…ü÷à©Ji?˜~õeØz è_*öÇ’P|ÞVÆb«ßþÇ©ä?¹‘„© Hw¬4|a’ú—£ò.ô3Ù»•âÉå¯L³™¾†›àÛÆf’åŸiy¥£Ÿ×zùÜ €¹…ö“§¼w$ò7@l˜þ÷‹-ÿ–|ø/yþɇ Û+=ŸÄ½’C>ýhV™ýôº¶î$ñÜbìZ¯_Îÿ·soÿÏÄxŸoà·upö“=€ªX”õŸWî@‹^^†ƒ#0qc‰a@bÂÞÂBŠ?¡™¬w÷3ÑBDªüu®8Ï$A×´Q†æÙ擎Ôü͹vâÛl`®E”JÍ8"‚¨E¯ÑN¦‘ä)ƒÆ²ŸÈ:U?{ œâ†Ô…›±?£Ìío°à¥gìUoSÿ™-ñ?vö½Ú·ú:áBijý äD…+ôòüð”|‰2£1ú˜Ç§²˜¹ .5Ø–c¤ÜnÏçÑŒ³z¦žtcwuÇêÙ”M…SÂd˱ã÷2I¦ 3LÜrBü5µ¾EË·MVÌZ¢ hd/º±+ÅÂÆ}úeT=ÙìëØæÊ·¸B/ÇBíëô)iÍ>È㟙¬SŒ[e±Kªv}¸7ø>¿Ì'mù`Îuì¡äoì‘àèæÙÈóž?¸®i˜Ì‚åHÊ…À‹§Ñ3!–´‰ÌƒÓÉ_´}è|ÕÛuÌ`lø×æåc‡ä Ý댧Á”òg_¢±€ëVù!0äo"[íÛ¢ÉḞ$>e{d#X)Ûrc[¶zr5øÿ¾Ësñ,²0aù#ºHÕÏŠ!ë{µ©¸œø#›~úàiWª$yXƒ¶¡ê{—óÿ„íüÛÿ31ŽçÛøí·€_AÿÊô“ð¢Ú'O ÁHµ–Ør”Û"æ§ÖSídäQG ÿtg??\ÁÈç‹i†=„3+‰ê’$w´( Ö¹y«öSûPô7”£+“†â›ô=y×»?Èw&vø.Æz=™ìq^”tg’þ·O¹@T@ÞÓ÷ä 8‡s•ÕêT×ø>¥5㮨nä©ïÄÏ']²¤Z_Îo?º¶£ÉƦ^b®øÌ¢¶ˆÒ@Ö9Å•ë>Þ*&üJµŽÂh\hÔrXh¦7øÜ®“üv& "7( LâZ𨢠ˆMEu5ˆ»tщLðý!è—⻈ïßÿ«øû¡ºp¹°©µ4꬗Ùúe0 Ü@b­œþü3õ¹Ìi¾´KøÖœ\‹è±Õ2/0±á=§Ú‚´D}ñ£O6ªÔäZ@Ô6¾%r,ËÄšê£Ù¢v ‘¯ÏÈ/ò#×§ÚeóáA_e¦Ön7y¨Ré ü¯±ÂÎDm$ñÔFܶ}Ö[YÓ¦,¥(µArteØ}ÿÃ]Þ®òω_—GÑÔZ–ßPªÑ0÷_®ñ6^’ßL°Vä?`ÔnùïŒåÿ·U¶°6Úd—´[Od*›Âº–>:²Ïèiå߀ü¥ŽÝxm½‡¾À`Î(éÐÌù³ëaœôÖB- ¦˜}§_!2h‡l–ÿݯÁa Èé@hzÆ&ÒQ’`r>æ ÷ Ê±fjÖ5š‹'ÿYZQ[) ¬èÊ ,´ÙN‡…7µÚÁ!Á ´A ¯Ó ø{÷žƒ dªËêHc2vÌ[ó—óxû?šFÏðpZxœìý \MkßøG™›(4h Ræ¢A ¡%•CEó<{XŸ=5Ïóœ)!5 H”)RJú­½3Ýçužÿ÷yîsœÛùßçózYíµ÷µ®u]×ûúŒk:ø•Å2êÏîÑøgwù·Í«öcûófâ2 ¼?ó¦öù_ 7Xg¨m¡p]d,A/GÕEq‹ù ·•=¥X©’9»éû<]-ç*õ‹F«ò@QX¥ÙÿÓ–ç^ñºØ†Ÿ{9ðˆáD ݆ÄEöªÚ`.X›vúl»ÇóšPaà_¶âÎ…5-•;&l_]Ú.>'mnÀýÉ/ÂÏó7ü·”¬òâ8FpkߤµýÉJÀO©ö!ãc2Z=ÚÀVÞ_z9ŒNº¬ºP"˶M$‰&÷ðïfùÔ„fÆ£Š†)iw€?‘À#É„ì±ÿµº¸Ôg½»@zpímçú¯Ù‰‘åIŒdn”qìÔ Xøh—Z+(¡l§­8t(]+ý[¸¦mücæØìŒ~ÿcß$`„Ç̪×åì}£É>òð€îHf¡hêç™Ç7Ý‘ü÷ùÇÛ§³Êþð!`ÙgØð!õPW?&Áå¶Hpõ‘ñèvüù ßå¿ÿ³…sôÎów<6U˜ÜÂwÕç_ZWŒ+S:ÍWÎó÷êaº2ÝOåoi=j­¡ ýa<ítÙÚî# ³d?,­ÐÒfÞQ€õ°my—AãJLË/`Ãþ^üÇI¾Ýê«¥ݸ`袬ƒfÎæaØžbÝ_µS‚?× OÄïXå:ôèˆÔeÁÉî. EÝ?,|Ʉ̄óžzÂýŸ¤$Õ«Kb:ñj¹ÿèÿßG<ï?¿SëòŸßé¿ögßàÏ”'å ·C’pà|1F$è ïµ:wŒÚ(k_»AÞÜE+½÷A¨]‘"Àf¢JbÉS±sJSLap°˜„öpÜdÿ €—o‚!lmÒ˜²ÜÖ5¦ ®®›Mª*Á¥Ù…§ûÇ »ö XÞøHFVçºÞ/:=½E¾rw3ß' ÉÜ»ãèD­L _Y4tµ÷@íå|ÄÔcà ϑÈk]­þÈJ¡#Ûš¶úƒ<—l#»ùb¶àqÁ1—1³íä"ðãO¯>½ÁöS÷¡âç…|¸&©ûrjf±køú,Øм"[ìÀÚä„kÊ9K˜ÚHì|=C;$o8*`nnÉXð!‡2|FÜ„swÍú8EÄ´ngÝ2rÎ3°äijaÄØ\²Dqvö±vt^Ò¸[rÂ~€}wÊÊÐ[åo]»éÞ‘“¤p€Ç_·Šìž=©Ù¦®X¢vÁßÜô`ð™æ;¯Z‰<ÓÔ£Ò× R˜Êaþ‰s[ÕIIkV¢ÝnÌêЀھB9¯Ð!¶7,`­>^3"å¦zMàÚVk¢“䨧—û™P·Tãm#$kñÏ1`XwÔÇœ¢Ç{Fx}]©¶ª³ y9(KÅÔûmúüæ˜uÇªè¼ØÀÃÆ:.½ChoÇ¢-¤3]äíDð?“ÎÌ$SÅúã¤kvnVÆuñæ’› ®Ã™Q‚€ÉîY+83>QáTCÿi›ŒC³Ú•·Nûó=@{7pNÜ“­MaÈ^S“쿊^ò8ñ^|`©XË1JØ*ãÅTr’ÿÀCþR[ãèAøR˜(ÞíVùIüŸ¯;mq€—ýh·•>€q~}Wnúš`óµ·úϵ·uêDÛ¾óÿ·ùëFÚáÓr{Ï“E’|O!Vk†*úÖ‹ÒŸ•*‘n‹þ.ÿC -¨þÝrŽ,gw,Íyéwþú`édëÓyþŠçY f¢v£üGìA{/Ê^~Ƥzxø“p)âkr<´––­|›ß©dc³ÑêÊ_áÈ ¼àù;ño©Æ7D§”(Ô‹¶nÈÓÚbÒ|Š“|0öøRPn«_Ý«]jϲòøäv2”S–S/oÚòòk]ÕŒQJ™ZÞÙøè@9³ÙŠ6áªÕ•“»dþÑÿ¿‹XDÿŒ^ËŸÒíßTÎÕ®» øÜk;ÕÎïåÜ Š'À-]j¬×Úá(/,{Kv•*/çr™§Wâq°Yèzð[¸x…°8Cn;÷ά¶\I7¯" ²š¦üÀ!L5ôœªeB£°K8ÜzœÊèálºþ ã"c¥¹ëXVó†´ž{v÷4|]MJÍÇÒœ¯½UŽ–iõÞ-TvK¿!ö‚oBb ;iñØÛ¬=ô“üC˜®ÊS Xéõnì|SR}jJq¦‡üUØ`Ò@FêÄ_¬Ch¡ùÐYÎÞ¹ ÆeímE8-ëÇ]ü¯‰^x¿lqYÉÏôØÌ¹vl¯E`‘òKÁIÇ7·Ì|^=º¸zqô; U ‡1,ÉÙ“ô}¦S«ñü¨ÙÝ|ŇöÚÝßÒqEn¾\’ý©cwøËt× ÓmÏ"©H ±‡WãVŽé|™¡5ƒ‹òwnþiü%6¬l Ñ‹2M´Jõ¿ü±Iïb·æ%Ó›¶¥-†Û3¢ìªé™›ýÿmþô#¡.ô'jXÞ5ó'XóN±Œ¿H¬Izÿ.²ÉpÕÜ©¿Ï?GÜÚz»æ³¥/è;üÀÀªuËó5Xæù»,ˆ1¿È[Jå¯èy¾«õ>€ÑÝT‘ êýáT“„º(›tž½y%ÿé5Æa1÷î+r3þFü_‡Ã# ”—ËjF+’œë¶…÷Zq®¡¨%Þàtóð0}pßxZlðã¶õÂ0. ×J¦{–¸™%nê_,¤vë¢WxÛêN7Ͱ cÜ+beó•%Xñôÿo!ŽÄŸÓ1Æ!âçtük†ò¿o{ÃQÓok»‡ñs\ä6ôtGO[pãÃ.›B³vNï—O£Wt²Ñ1–.€ƒâC ½‡™^ˆ›s0a¬í1gì¬)>Ð.U& ÄSêwƒoÛh|`ç¹X§Öú®¤{1û‰`ªt,ƒYÌãf=¾x1Hb~c ’ZúP¯»ºÊ´ñ]»Ç>ùÁ×–Q{s*Ea9Ô¥yÚŠˆT¬‹6}õ1°3J×fáùÒ·z¾»`N¿oÁ’œzß\µí´¤/põÞUûLÌätä† õõúÜ› qí­ aMï(äa¥e÷@E½Ûœ ŸyúD0™8š²è“$”O|¬MR»ùxÉ Œ=S‡Í¤a€ÏûäŸmŒfê±×²-*”µç aïS[€Ý£‚ !7öIÓ]YðÂj óO…ãÉx®Rºš%_³Ãñrô5opHOù%“fCâ¬#ÁŸ.j/ƒCskxx­ÁaºoNìÉDù¹Ì,­}E“¡@¦ûvö‰ýDþy‚9^«VžŒþ,Sé˜yl{–V×Ö&ç˜H(¡·6)¬ú÷ù«xìW†K±Âq®©—Ø£¢}ôG¶§ëEÌ$=Æã<6wŒñ¿ËÿpÎÆœ@õogCzµè9Üü]®ÂÕ¡‡‚æùW?©c*éׯ¸Qþ£à}k­ Æþ+ƒïnÿK~ä£]*¸Y]Þ2}¡p5ßq4çUûÛðß)®f-Ý0t\O^dó>…í›îpüCÏ `©Ü 3nqçC¤Î¨ïÎ¥=&Y÷_욹빥ݻIÉã¤ç Ë _ãS¸}ÃÐݾM¬+¥ªŽØý£ÿAlÃZßNDÿŸÖ7*î>?³÷?S6ÓÒ,ss?p†=•^BŽç!ƒ‰aÝ»ûlM¹S‡P@”üµÇ}ƒSßÚÂ)=i›·•šOê˜áì÷F'B±šó9ÃnÓ`È^g^¸ìGôASçí½+;A“÷füý÷¦‹*,î9Å.,L |Æ»­TÆ7¸?V ÂÈ3€íŽÝpãâp›Â¾šv±S¹‰FÐÊõÃóš”Óï0?Y`“i!f?sœÜ·˜PÇ6y¯™ ®ÿì´Ÿ3…P¹û‡·?g‚ëÙìÂ;b½ò·gUÉ,w|Σ³¬^R•{x‰ $s7 ,Ky½ÓLŽÞ¾nE‡RÎ}n>ùè[Ä»µ³’¬ã-ÝRœN¤7ñ…¥ë «íõÛyXKÈ0sï–&¯ò=Ÿ²Vë°1¼Ü`3´Ýbqr¤D Ëw˜•å|€“õzx:E Wryÿš¢¤£Û–ªæZL/wvz³6ÂуcÊwsác‰ó[vܯ]ãîcžû>O ïÁgÆE!š;™È%²,o}¢1»Ð-}í• œr]`_ Oãu.¢Ë5-Uo¾ˆÇN!;d1—MB^ö ×Ù×ÜØ7xkc(籨d7öŠûwÛYÓó7RÌßè)øs탮˜éÅ_ùï*©ÚHÀv“ ?ùâ„ãCz 8ä_í«vëãÁî.*áHšVg‰ûã|­ºÅÁþ’$05~zì]^/EåÀäíÙç ŠÒÉ€?þD ì f?þòÔ0á¢ÓÉ<·py­”Óø¡+Ã%£ÓH.C™?°Þ\ÏÞѺ~P¦‰ø1À§r|“ºtí첬3Wl~.ÿQVmú{}<2™¸ú­ëJ'ÒÞÂmN½û»ëL¤:†yìCþÿ“s¥CXBû.ú’ü½בqúï7ZÇZT¨îluæé bàÔ5Oý]þ³yŒŒ’ CR»½Än±ãB~à h–PN½yþlì{ªÏRï 9pß-Â$ä¡X.]ý~™Á¢æîˆ|Ž{+ؘ~ÞÎ:žŒò‡u*ÿ”wïa釿ÿ>L±t(–Å0îbfV¨LÀ+à|™dø!Áì§Ù‰†„ŽWí„@U F·•½‘2wóU༽˜_äáì…Ü,?£Kn‡Jï_fæzÕŒl”®3­U?…G7düzVÿ£ÿ¿¼XÿÔ$Ý*Œô3»ÿ Bøß·mMíÒ­qäšlp°n8ÈÖ¼ò8¥ä‹Û›ö€ÞާVsÒµ‰ž÷·Ÿ»  á¿sØ«.y¬ÇB<4 ÝÛUj6»Æ€9˜‹ èê3×»Ç>Tß×]ïÔì<ª[·ž‚-AR¬à§ *GGp‰ËßM¢_/”YJn®Þ_gÍ%–ÁÿÉ |W\-­¬kægEÁº—Â,|Ã`˜=б1lÊ̵Vb•4(ãœZϤ>(Å4uÔøµó²T°á-ó‹D wELôã]n ú•ŠŠ™ ´²Ì7ÍìîMÜ|Ýš¹|Š/ì¡jÎ ›k‚(…0¹O¡’}šÕVa/{Ô6?þÈÓMÐCì¿å¸j”pÊÓPä#wdÕ™ÕÔêTil¯ÏAùuF7§Î%ÇPDùÑùw ¯à÷&û,££‹9°4Œ ¯ä˧$ãÅ屎3F†sš§Bî&fô_?þ®¬Ê…‡õ%ÕèþSÊhËl}é,®¼ôB§uˆ®éî–d¾«°òêÛcAv”ì’dÈ$J7œox.‘çžoÚŸ´H÷Š ÙTŽÂIaD•›t‚âum}ƒVnˆ)9èxy ±R78e¬8*–{¢Š FJž²·LðíJUËû`&¼|¾9šää™7iÚ6®Òo»tÜEÏô¹Xo.2–aöG½1Î|UDÆz‰¤·¢Ô#8à™Æt£pa "ù.kq±õš*n/ÄàÚ”]°~Í21ÈÀG÷²·fÖ½ÙŒRï»L¹nâ7c <†O2ΛªÛžŠ{?wj"gþ€¤à'óg°Z©ôèä§Ó|¾k/w6^æ;sjXS tÏ&—Ý›•‹_ñïó¿}¯ÚxgYÒGKÅé UÀÓz69åt5ÿ!P‘’=ð»üÉà¿•÷ªñTT7Ö^“ïüg¸Ì¸;÷tïÌ™ç"´_ìÜÿÓ‚èý½®ÉÔß’ ¹³Ïýx¸ož…¶CÏ=%²_žBù*kyö00:6¾5=ž¿ÿ¥ã»Œ*w,ÑH’a"62ší„íBÙRoà¯X±º—GZ}^õ(O/ÿš¼Õ+ò(U²TI˜ô~ OŸ…T÷Þʽv!YÒmóÀ7¬M]õö!—N½zè~ýýÿµçús¿©ÿ÷û€Uäÿ­½mØÿ»ÍÂ<öÀCg XÇs¯ÍeRÏòƒšTzôB.eAåñ#sÐϻݩûÒvóîfyVÁŽHö†a=1ÄÓ~ ÜÿA}ñL^“ÛŽ¬vM°‹iã#KèÝ8ëÎųÓÚÇáTøE`ÆKT},]fðŒ`ÿ*ösß&Q¢êc[g8ýxûE0_=ãE³å~d‘-QäRO/?Q©i Ëš/]Ê-®Ê†³`e Y5¤là!'q>‚Ø,º%Ÿ.¯Ö^í1°¶DÏ ˜_„h\3câöu96ÇO/¾þlërØ`ÑÍ@ÐØ½ÄÀ“Bg^øùMçMËn;ÀŠ&Ù]µ¨º²Ö}]ë#égÒœtª¾„á %97’I8ìk:üÂî¦ðVKBãݵt–c– ¶¹½#}E ]™~ ™¸…á>7ˆ]-xA1É :)NDmѵĂ b]oÓ=säcm/UòÂ{IM«ÈýÜÛÝÝ4zT}÷¦ÝyÈ §¢ÈÃå]¯¥@ìLV•‹_Y˜Øs¬ÑÉ¡¡ÆôÿW–Ÿóå¿ÅÃåá ÿMqúÅ~ÍðŒŠûOÒµ(óngC¡ÈÕD™+ ÂüòŠÙ±ÞVÚïê³ ôî=›òôØñýQwûôˆ%¶ZîÚaðLy{6 ï2«üfÛ\7 ßÂçúãòNœÕÛj¨¶ÎC8ûžóqx+»Q¢.anÅÞŒ¬ÉKðÊÍ]u®‘ì>wɈ…al• iu†¡€¢dœ šLn”®ª–äPàïÐq‰m|§™=—li#l(;OÞ›^dÁ8xJ¢ßoEãµàÒ«©¬TuTq¬Œ¡1ñ@¼<ã¾j¶…Ü(bFÌ~íÌ÷œÂÒ=¶¥‚ër–‹Ó—Oviò ,[‘"¢•52,ß×Ýfߟ`ôD ¸h¡Ǹvì„C }Å?>[¯M¼' V¸EŸöëw{ôŠ'²r‹‹¯|:†« p"dhB`áÓ@×u—ómXË-œŽ$>súH`¢s bžÉ"ïúâÔܳ¯ïØî¦mv¯ŸïT*…±Ÿ÷ÌÇdXÏ©”œuMgéìº °5eŸüÜûg¶=™—1[®É·± :åòœäÖJÛƒ›»=c }ÈúzoRµŠ)†Ü§±Öòi¸›ix’SÕV [´g½¬s€Y¬‡WÉê0û ›Ââ<6˜©»ïÝÎÌSñG ‹3@UÐCˆ¶ÄMåÞ!IZÁjWé^ØÖÖ-èet¢FâRÓM>ëÆË¡¯ãD,v?l·¸sÎu/‹<øayŽŽ%0OèdÀÉ¢Ãù™}•t†öoVKN¬ƒ!÷$gF‘м`’*™Ž3 7ÚuÊÞ¥:6HˆÕÙM;X%v§1ƒì—¸|`“£ÏÌ ¸îæ1‘ÖûWðç"fwènjÁ"Mb/R3t2ÎlþàîË’Ùf [–ý#ü¯v¿…ª5çî olükòãÄî{{xM öË!USïè öBÞïóÿX.“½â¥9 „PýÛæ©úÿaG¨ïŽyþÈÊ΋‘‹ŸSù×>GrŸ# ÷GNŸ<𤪔´T„vSë4þî)”«×òØÎÀùO/‘W\¿6ÿéª +} ç´´°«Æv€Ó 9]ätýU±Ãe¨xsªìW»àm æÏtÔ×ÍXµì+Á«;š%ÚàŵWÆ'§‘•Šð»ïo•\c~^Ï÷l)¦šÈÅ/,›ÛˆæúGÿ]q#þ„ßýû­ØûümÔÿ$ùüâÔ²²ÏR‘ÂŒ„¶Ýï4¨HÞzþøÈÚuJrÎÌ.d°àx à>Wâ²™žèœ´« ŸFp¼°ãràþçò{æöe*N"id}Hç{îdŒÈÛÛ&a˜RÍ@¹¶Ï€i¯Áë%c£Ø´õæ ¸UªËãà ã}´õÒÀñ“ºáÀ[õëx¹7p~óºÞdÐ׿C<üIÕså+ÿR "âÌõ¶HîâÕ <”¡ÕÞÉ[Ü·¬„ðéQéšÎé™m5Û³²uf½gv‹Ãñã–G6­<λrìÙ^‹ŠG0EJN¿tþäìã÷Y”©’5Ø*€/{aõ#]>N{Ñ•¾Šõ~æILñotáþU´ˆºä3`_J¹/¥ò^L7[Òã0 Ô†^Éd4 ÕÎH' öVN‘Iz÷O‘ÀîL6ðGÞxàåç¢;·§^é¯[TšªäÛ]œmÔ8ÚñH›q2ý>3Û˜ãÁ{Þ>7=x2Ž7L,róòˆ­]OÄ †5,5è<Ñ„i›çø¥-ÉVÅäw!‡ƒÁeMé§ õÜúä¥äkGT²_ 1Ÿ©ór±›#BUÂÉUaÁg²­C`²Û¨ð}Êé7n¥3Çn®‘‰ÆÛŸgz~ŸÊGK‹I#g#Xö|IËÐnpK•Xr]ÿ‘5pÛMwûÇ€誜(o¾vŽï³ó Ñ@Šë'4Ó)…¿22ûB¢Î¬‡8Àà™>ouKÞ;ízâ£zÏxYøˆg?IX‘àÿÄe—Ö“h8‰½Ý>`XzûÚ8IU ìfõ÷?нmº|ÙæçŽµlŸ#Þ'‚¡[Ú  ÇDðaé* iÚ´Äôõ–¿ˆÿæ+cÙŒ.‰nnšÝS ˜¢ûŸ-]ù3ôþ­OgÞNÕIì›<”íääG™ø¤]ððuPÎ=Ýþ}¬oÍ#-â쟿P?Ø_%Y»Ñ]Çï•øüGAÖ¢}gÃÔÃâyþÞ"á7¬Tþ­%ÁÔûÃh·Ñ£®”Ó“W‰3c«ü:˜Ø_¨~ßÙb·œ¯|8¬´]À8$Øÿ+ó¿É¹j«È?°%oDêïn÷>œEÂO(+oj˜«_,mî;<®¬È“†íÇçŽÝl3÷—»~zÿæW!ç‰ù8¸•–!/9;5Ko°Š%Ðiã½HƒvßžNÁ&«ëato§Øö—‘þëõÿ—•?ÿOÿüþm"~Òïü]Dû‚îŒ÷ƒ'õlÙ€{YqÈ<·vˆ<žxpdå3è¸ÔïvW’ aËoæcái‰ k1ž¾|J²B+æÁéÀË ‰ÈoâÊègzgÀÓ9µçÞ8Å ¼tä–š·|]|XƒùE6Psuºí ΓÁ®2Bî÷¼GbL ½µ‹ÊÙèßÞÚÀxA °›ŸñwÃ\MÊk› $Þ§3<½§€MpÕ»ªù\G d5ê/Žpïwˆ¿¦å/õáXÚ£ùДö¾F…—¥`c·ì-åã"¼lÍÛÂwþGr%Ú 8Ä3M['£°c„õ̀ŮþŒ†¬Ñ÷k0pÚ¨ YÞŸŒ·•hórk&÷s½ëÍǹ¦Ô—¸lÅ 4y ê.VP* ‚›—ìç}þOMÏ AȃŠ3ñæÊ­›÷:àèöÅr±ÝÕ1³äWO wôd v2NÚÚ(6Ás’ÀôðXAØ~“6'¨DöD*&,£“"Þ¸–t;š‹…lS×´€¤•ëà©‹ék3”_{2ÙÜ^‹?]’Þ  Dɵ ðÞxðÏ“ów¬½WNèxyäʃ³j‡GHð:m±Ä$²&Jß³ CFìÅ @ÁêÕIkú ™GóD š™?(žúˆ©Ž½ñÿ—5¼OQ”I\_9šê‹O–W²}úv*ðö²Åñ`drA´ûrÝ*²Th.lpê©|ÚQf‘¬2üÐñDÔn'Â^£ËÈk™‹óLŸ‡}\0ªM'™™eÞà‹æ-ß~P–ÔuÞÈkσ°ˆ¦e‡‚ê»ïþ‹Q¡mš`éG„òX2Ež¢tgljMßyá³ . ÖüeüÍ,¯è†{á´ö úÛîâPºqìîóv"q_þû ¾?Â×ßZIÄçRT `õ]ÉrÖm2ˆ£Îvs£ëÍÓtK´.þ>W‘À›Q»øº{Ãݹ¸;f?ðø¤[[øÛ––áïd÷ð0š©üÄâÂ,¥ïy&!Mö⾀Ò.H‡qðrÈöF2Ü,^Öjúò~7¸ºhü:ý²üŸ¤”óôZÙ×I};(nàO–ì|–g—’Tâáæ~Eõnc‘»7vµ]<Šó:ú\Â_öÔÂîÇnŸb‡Vú†Y±$´ÖH>×Ðè8dÔŽÅßfÍ“º/bòöcôÈl­„æÛGC÷TÿÛõÿ?íþ±ú‹ü2Þú'v¡?§ß?WlµÊ^ð,ay=C„ýB7+®jG!òÀ‡8n©+ dX÷Àj“hº™^Àî•K/™©—ÑÀâÅÆ`°3Zcr^msKm¸—íU·ÆÃR|è @pœÀV»ÆpPîs’M ár»Eþ,ÇvŠ®º®':º+<†íôоÐovfµý †«ž€œW&ssÑ…|2Þ¢üA ,\pÎÁ÷~ò—AêHÔ«“—£”;L]ÌcC°ºYÈpTôÝH :÷ã“íþ|ö#OÒüÂùý‚óÐèÅ U§M¼‰ãÓ²÷¡<ƒ´:òßM÷yŽ}›ü-õj1*I½U3³¡`–fÏ’ùËw škg‚ˆ{´²Ô"’•f$F Íð’¢-c'Â@ã,OyÞSOæfåµá¸®‰°–è`e>w¾©òd³»«Í*¶bÅh+§Yz ÷P¶á¢´¼08(—ŸQ¾¦œ ýÖcšŸŸuß$ÂÞøtÂÆ¼`4 MP"ï:¥xhúe–ƳÍQïÃÆÃÝ"ÔÞ+ºçÝx{Ð>xŠ j×]#Ý‘j›Z AÓïÁ·Ô°n-OëúGq`Í>îÆ¹pú~ø¢Êû ¥Ûö>æØKOW«F‘¤ +f‰?=´£C%=$LwåßÂ/åqb˜§„ï¼.iÙG€™se}·—–ÐOJžÃ{$‚á½–¿~Or|ŠÊº÷·MðЕðÉ/ØÙ‹Ñ~9„YÙÊÝ&+=µˆöTgéúÁDÝ@äŠZùÀp‘;KDôf£f"áI¯ƒÖòãKÚŒuP¾û\:ˆ)Ö6€2×r2|â3& ÏMö<ðÎAÉ!ÿµaž~»j³ ¸  ‰²õM3˘ÆÇꈿþÓä‡SÍ³Š®þ!ŽnÞÞŸ%T ϳ¸ñŸõ'=m©ÛÙöü>ÿ" F¼•,cÛÆº6­>íþ©'è\á »ð<fcE“s”¿øíséD”?, Z8Ýxa´ò¡Q’’Ý06©wwl¹4Hå ¹VuGÇ™÷(—Ú_–¿øä‰‘Ô·Àžðøt‡“>4··&> ã< _Nrhd-X ô±#Ö8j!ºÇFÒD¼>Ƥy«u¯àئôRÖYelÓ'ênà}0ßԕŒY8ðÊA—ö=wõ[Tš’h£Uþ_­ÿÿiÿó?b÷óÍÿVÜ<ƒÿ²{ýz‚?ÓéÞÔ½ÆI=zÑàéÍ!…l‹ TZ±&0YíÊ’¸Éœ¸´’ð3€Ï Ýã-Mžº¶®ÀÄ­ëŒ9Yh(x*­\‹}†Ùkæ+x~÷Jðsöé"­›Uî‰âÅXù¥)1—ž ß;Ø@FN¸GbÃ. ¤ë7>++\\¤Ó’3½kO¡ÊÉa‡'žúæ,ƒÔPœšônñ»‹˜ñL•…~ˆ™QúzhærûEíÃð,«æäU%é…›’—Ö{6ÈR}͇@Mërtòä°ft•§ÅcY•ž;)²w5¸„ïóÏ=Ý»D$LÚõÎ5ͽÌã\Mán²¨©K‹–Ý\]!—©c‰ð"qÏ0¦—Ààj€½K°wͺ”ÕÃx.'÷c[¥ÏÂѾcsêòê‘6±×9G7\Ù8áuw"M#ËÄêbÓ²èôý= Ä‹Ÿ¹P-~ñ–*—a°ñˆà}†œ³ì74ZC¹ôã=1­Ó¼®&ŸTÐÐè@×DÛŠeW?)œ„ÉW·¬œYÎÅ¿[½)mE¯hÌDG¦×8³\e• {}´rçìîЈ%Ï6 ž0²˜â¼ªaà“rBjÚ\ˆ˜teTúM94¦ÊClÍôÒÔÒÛ•5·Ìc>ïÛL¦ Ês¨ÇÁ"íÞ;RSÍ‘ Öô‹óÏÒ‚mÛ²¦ûYs$ßmÃMÊj2USÙ†xV/… fï! á5fRܸu;ì®Ðà¤Óðñ÷éhóÞËÜÞ„ôü Âó§å0V[ÅßÍ1‚ÕÊjÆmÛ»¥¥A©tnæÁAO1&yüMƲB‰gÿÕúÿŸö?¿/ÿׯºÿ1± ðú+o÷—‰›ïÿ³‰vÆÄ¦ê7I }66ÓKLp ìÓ7À왊kÍ­²>õ‹ªKÛ8vÛ31T,¾®âUê, ÝÚ ,yLMž6°|8.“ÖîŸS ƒKoiô=/%x5  _‚ÎàÚ^ÞðÏg†¿Š„›LûzĶúM¦i»=Ï —㨩Ôå)ÌH½_7¥X§3½iõêÕŒ`5“>hè ìŠWŒÄO®çÍ ®(1'‡WÀ”ù£ºnzàIp%à”¸yˆ2ñãÍ~5òŽj7Á2,¢Xº¹å¡Às­ˆ˜ƒeÅÕŸégEÈ/™ÞvõdG[t§Ô€I÷Í|¼1@S€"^¾]èÆ(¹ßÊv»(¶#d*è° pùÕÃMŽ"’T3, ƒæ(v°áJi­¢ecÔV]e’'÷L¹p¦Uv×¼©V©…¥›·T:¬ê¨´Ð‰a°Uq=¶ ÄA8÷¢~˜DTø™K=c޽H ð|¼ÝžÛÚ8· fÏÀ)<Wµ™Rº=ÏoŽ‡Ú ?NA÷)CÙ!3íèÐOXûŠv<ätýýÂ÷œ•»2ò8­²HÐ`|é8×÷61Åg–^FáEsÏ#ë,a–nÌ…òñ„ dQ±Ì÷–ÝÆWɤgt~g¼hü_L‡DÇœ-$1›RR×4W,/–º$~5ܹGs õ&›3Ùvºãý‰²%i‡Î{ ~RFͦ±Aê%òc7® § mnôa—ÝkaWÊ: îâ–C÷ÖÆg€8tëÏUÂæœ‡Ùaõg½Aøµ“NŠ a}G¡ævÒ«Hó*+7À)e„ÌEv€vÔÎÐ,ïwê¯æßm¿9Âñʉ“3Þ‚¸±Õ†Éþ1Ÿ»à=åñ¯ì|ë8Àøô¦lgmŸ²žáçK¶Z›ÆIåê–ÂÝXÃùÚ®¿Ïß L´L¿ÿŒ9:X~àbå”Öî Š_ø_Yzĉ³>ÊÃÙÍUˆòß®Y³ôJC¢Í¥ŒZY‡Gº×ï¦zLàÌÄDÎê¾~Ž»l9È¿rLªO 6|ÌâIp]d;(°BÒü…ñçyìå‚÷žÆ¯…*Î<Ú©" ÊŽ°hÈv0N‹>º¥æáœ¸Ìúó&. _ùX%“Õ6P¤á¶šÇâ fÞ[ÿxæ²”µÓÃkI‰t)%èxç‡D¯ÝAîhÀø»¾” ¼Å¨-L<³ÂÏñÙmçD;Ôš™sje%‰]"Ù{–|2òw…Zà—îÕ+ê=¾@³l£ØZ"RzÄî1kõ5íÞ“aáp·`˜ *Êã„§¾ '` õiƒöñ‹ïJ W+ô6Íéd0l-°É1**<¨rfº§ ¯³Zâ?µŠMÚ+½:Ùô¤V_T8,%q|Δ |tÃ÷—½æKQ¾ _sc©—nå`gT*ð&WŽMâGÅÂlk=@Ùò ÿÖ­}‹vú€§ Skná0ÅVϸ5 `·UFä9¯Lñ)¥¯bÜo7pÄÚ&ú.˜ f[r8Þ ÄŸëØ@œ=5xf·<ÓÐtXÁAÂtœŒ%ŸÃ´"ÔƒñìIuØ®ð´Ða×âÄ"Ù$µ.¼½Àj Î%‡ëwÎ.AFHq3¾!=ÿjÃÚÕÅûÞ,=¸}Øiø\š*¾SñÇøŸ\ÀOG=õ7LI:–›6Úðö;*Þ\ýàÓŽù}þg ¡¨êfJŠJÒL¬•ÞÚô¯ÑeÛsŸÀù/üÁØöPù»~Ò†ó(sNÝðÍ|)z¡úI!šñ‡*GÚa—eïØd»´O˜íµ¨ÓÖ¿*³X„¥<JèmïÛÊi£¶Òà4h½3;NÿçÅ4 o—Ù4Ñê&ºë®­ï2¶º<ÇžT{ºnßN÷ArîN¹q¿ˆÇ¦‘wtRT OW( fíž–açÖõÇ•7^Y#{—o³”iÜ›ìÓ Õ8ÙÿVýwþO; ß•Ÿÿ»¿œí_ZqøeäVíÌ+Y}hx_ìç ýŠk¶ê> ŒTÙÚ€C߯c¹xE¤ÌùèèãìF¸¢«ët:Öí܉I~€+Ûw‚ø8ÙÄñì¦)‘ 7˜§×œˆíÆ .1€À212Ô,,ÂÂd™Áv9]½ž²J³X–A5hšÞÃ* vœÉ¾ ýûùJ jj‚ˆæXK[xç2ÍΜv‹£¬cU¶Â¹w]µsåùÜqOÈ-|‘¶õ.¾f2[¬w@IÿEk8ôÈÁÝÛæôô”9°±žõV!1ë2d‰€É9¸Ë’ažpbÓ¦­©n¦Ë–¬)ºú„_þSŽ‹¿èñ9w}QïÅm«AÁn)ÏÏÆDëÇÏÍí3aj?ÎÇÞ¨ÂZ}ÏòF¡ÅA$?ùà«0uÖ·ª ã.~#Äû;–ÃY‘=™+ K§ƒþ$ƒd®‰îò×\œIû %V êLéJ»j¥ç³³÷lÇÊe ËÀ ®cÏ'©åÃÊ'µÝ™Dsú—û2NÇH¡ÁV?K•°¶þT‡Ûµ+§N*⸽&£k˜Oðä_ñ|¥XWé¿xš¡é\fó%£—pt¼–•;ýT‚3~ÉË$Ââõû#mX/ŸFѶ±cmnë€CÕU³0MA‘×yWìk<Ícª…«“VÇlEc%)ÍoüÁ6ÖZmÿ$s M÷V벂ۙÌZ§ƒQŠQÎ'˜Ÿcƒó &pYKàºCŒ!{\p;¬%DA‹Ñ#‘ãl©”¾”h±F1¸¥ äOcú P›‰—èȶºŠv<øv»–z“CÅÀ_Te#¡âr_ˆ. “…¨Ì`rCOŽ×àËô2ö?Âÿ¸‡ûbŸK{¨pcv&¶Ùã_y°¦nä²c;½Ï _‰·*#¬íŸÜÛbu1çÈ–¥Çp;¥r+SŸN>»ïmÍÀ:À¥ús“3! ?ðo ¿ù~ò"í>Tÿhü™÷ÝÁñ–]¢ñ§Ð³Eh£üý]ÀÉF|è}Ž…”é­¸nM*¨Þ¤;¦[+"`ǯÊÕ³Ó×<}q…­‘|‹á@ÓàÂÔ!Þ ‘&ïÓëéA¦¦“_¦j‘–›(˜Tœ¯;+„™ƒ-ÛÔÀnãðd›ÞgV"7^žag2ñÄ Û!kŸîÜI:ǹ]´wãñ«¶æ1;ÞêgiU~¾ Ž5í¿Sÿ¹þ³îç÷ÅÙë?PwF~±_ÙÿKäÊÁpð¸ÿˆ§¶¨.«oÌôÎÇ.€ÅÞ¹§kÕÂÁ¶üÙG+»k¤ä]MûCîÚižœ±—íØ/4»lnAÄH˜.Ãa}€ † D°Ðêץؕ¶]«w© Ïni\—ä¾W7°ÿ kºÞ-mߢ ®Ã™†½D½:’šŸlÉ-Ùðu.bñ q¢ C? 8”[Œwû¹º<€§q+áÝ þ7i®î¯÷ž¥›AB$EæI>Ø”x +ŸûD C²7{ÔçªÌKm#°¡g½^¿¿ã¯í/OÜ`•FÚ’+Øa¸ˆ{jyÕHC¨Ý:uA®þKÒ:“‹¹ýC=u’»ç’¾KŒÀGÛÑ]mÉ݇½ei]½fuѧÁPØYGÞÀ%ÿý¸p³X³˜ËÚõÇMÀíàVîÉ͵mvE6yªn1‹`Ø’?÷•9ìJ•`j böZg«I¡îK4W€jT;8”­a™º³Üÿ!^ô—3¥"ž÷W2ŒØŸïÛ¶ÄŸ¹cÃÿ>ã|Jt†Î M’ÓŽ–žòÇ™ ÈÂgн˜û¹ûBŒvîÆÕ¶ =¶“ãïN(çšÙ&ÌJW± )¤Ûf uþWêûÚýÿ”ÿËŸ±ý_ö?¡Ðÿ7’ƒ¿9§þ¾–D x"à ‘AßÄ x¨§nˆð@ 6 ‚ú¦«szJÄßâˆDô:<‰€`\ƒˆè9Hí!¢‰Úšz Û2ž€#ð@m‰'  ±d`-cˆ€E¯À¡ÍPîhÏ`t.3¶Ð´@ýICH}¬ÂÈ_€"Kû‹€œµ¼€ DPñ¹Nkíî3¿…¨j‡€UÈööøþ§%¾}ìðµ[Âüáp àêà]ÈÞx:EÒü@çèz¨k„¾B'I{…®A žîAÔ.БPGh3úr+ô‰@kMÀ“¨Wãˆ82žˆµ £¶Fðdpõ£6$›?µot¡pó—á‰D ˆXê):uËHÁ.„D žHÁ‘< $"H8 cHXoO †@ƃ5.J¹!*ð,ÙãðoøR…'—_LÚ¸ _•Å |¿üÛ:‚»#ÊÿÛ{ó 绡^Œq üúî×åüzÛí|%;!Î2f:õCZC”¿éÏàŸKåÂtÔ"DGäè$ô”@¤î?ž€Wú·ùÔOQÔ†$êvÇ‘ÚòP5€ÿ]þ‘h(i ââOUøÎŸ8´-àHøyþÔáQYFvÁèÀÕ`ôS@[R[£š‡q4;| U·œâß‹ÿµ@ŽèLðj(PÓƒ6ÁSI «ˆ%Z…zQ¡£Æ-í.bd|5ðdD!è*úBr÷¥ÙjmþX•ôÿ_äýþß¼ügýó#€??jù3å_#€2ª>¡»“@Ýz$ÚvF·-Í*bÈè»Xzê@¦iuÓR6BpÁ T-$̇èÎÅÑ7pD„' :ëJö¡©Ì{xZC‚vãèåC Fš³G?E#êæÆ‘Ý1~´xIP '‚? _ŒæWÛÿƒ7 ¾Â:‡Ðô=Á›%»Y^§F%ÈᤚS ûW…¦µpÑ¢Z€ojÿ –@h,àêýoó/$Qù¨1ôRÕ mzu4ðôB}ð»ü=‚¨ozzšcÀ}çOõ=4ƒçdêÊ?œ¦-f±Ôû¬Yêˆß¢ôΨ:ÓV”ÚÆK¾ØUõïÄ¿‡N‹6k5®¡zrZ΀£yNÀ8‡ Ë€nw kz.ÕÍô¢+¡x!šº¬x…ÚD;  Ž®?8ÿGÿ´ÿÿƒ—ø%äç8ÒJ?HAæÝ>-õ!ÌPs*-ݟߤVÒ÷ Î.À›Ú}ýµ.€¦SÔOð´‚ZÀ[†QЖZT@K÷iªëNö¢*>ú ˆ_ÔÖóAµ£/ýî£ñ/¢€*êלï›U€¯:õ=9™7aÆâG³Eê×|¨ïáH_Cpø–ä ó³p>~cæ-Ò|“/÷!PÃZ]ðVádªvhÖu~*èDZO5UT-¤Æ8­âìG½$‚äáý-Wý–Ô`ÉÔs"5¾§æ4ÃFM/ÐØëèCùºéQóBµhBšðøù WѲD qQÈ$|ÏoÜÀ·ƒ«¯“/å_¦Œ¾41Î¥Žñô†ïà‹¹B5\õûši|M€¾wûÅh©”Ì—U©ñ=ïîGœ·@Ôt=§ÐÈùç_sZ¹Z ,µK¼mø›bùͺ|É¢õÔJ1ÌÏŸZ#Æx!x4Î"~³Jh€|)¢í°_çO¤‚ÂR§ÈáûGÔ¢ZÄð$Œ›/šHDùtT4I@ÈT HËç(`Д<ˆ(ùïü _ Ìg?Vt¿i ‚ñü¶Fx”?þ7~¾“úê»ð¯îã[ö‡òÿ¶Aÿ¥.ü…„U8é­ŸÈÿ•?M¥ÈÔÚòïŠ&Ôd~W¢…Ÿ?-ÝÆÙ†©!,ÂÑk Ô Íç¨OÔ&¿ÃŸ€ò§¥„x"M5~àO‹£ñ_ªhT¢T‰ÊM¨-¢¨Ï\}hµ4¢|1ÕÑêÿ¨Û#Ñ¡¯5jêŒþ6üC¨üçc,-ÿ eXj’@« xR.Tþ„yŒŸ 15(@ýš6{SОPíµ‰D8‚â?úÿU~aÿÿ3½ôOŽ~NáâO”o@)í1è—Ò?ºÕIóõ÷ù'÷Ô‡m´|õ߈+Ù Õtû¹»„|Mò¿>؇ùëhzöÃ×<=ý¾TjZîoOjDK½Õ|Á׊ª4@UqT¹ì"i_À‘ñŠKúMÎ÷59ùU£ëHÀYG0C¨Þ«^ˆ¤}jò¯©ÌW7€Ã«äÐ ~T»G«qÒ €ðc1S…úÿyRã"Žjvlh¥;Z5%ÕÒÒl*O+™¢ŸY‡Qk'¨ù–Ï§Ý ƒñÿñþó©Å—Q¨æƒ¦Ý¨z£KD}\L,Î6Èë{ý ؉„ù,ù:A2­.ZÔ‹š"ø£§¨í¡àñ´§€h<…§ X"Ñ0áp!Q¡!¡#+FÍ€ÊÍ£_ùߚؗÒïüÄ¿/ð×ÂÔ#ʾ„Nåÿj*¿f¿y ìééÿ5'œï‹òÿñYð¿\C{Eå?Ÿ,ýí]‹r×qý·„”H™‘œÄq)‰£G$‚`ñÜ™ûšÇ.ÀH‚Ž•£²T–Ê%%¶Ä‡¡ò·¥Ïé{g ; A¢¶X[1;˜¹ÛÝçôéûÚ‹µÿ#D~ FÖI°d ÓŠ4ÀyþyÚËg°ÿc9¡- ±«€áWE…|Y÷Û³ìïsÚŸ -Wr¹gÀMˆ¬SûÇ3Âþ塲ÌÜQ¾ƒ²¡wà¿ÿâ²Øÿä9—pÆK¯|'ìÿXWËDê:‡ÀÛÂzXÊ ïù|ážgh–o)0W?½G>gq†½mdX]à¹27¯ý°ÿõu‘ãÿ‹ ÑßkàO¯]ÌþÀ,Öå ôI@¦)zeÈÂoÍ¥×Ë©¤½, õJ‰ÊÏKþÅ2†ËGÖ&cÙ³Ä/²5óµÝ(ФnR&AaPñ Ýp›ùm’7ßú¯{ÜÞŸ¦~ÕSñ=—¿xŸ¯ïk¡¾Æú·o|Uò˜’wr®ó;}­þÔ5_ÍþáoMXK#'RžžmG¤A¢Ø”fqVq‰Š`Óý“£ük,!„­F/ôÆAÛÉriØÍ=EcÈå+¥lá r·±zÔú]Ùì… ”ˆÉ#B“\¸ 0V¾ëÆÁØ:nŸ×âáçUݲ¹óLû{·ûì‡;ûK@ˆG,¢ý=i`ÎÑÖžî?Sâ@Ù­—¿!/Dœì?ÉÊe“¿yÛٹξöÿä.yA\~Ó`y-‡`1Åy-$[‰Ï!é!ð¾|û½Çúe%>ø9ñ¹A$É \ìÿw?ìÿèÿ/èëEèï^ðÿMˆþïã58V…žP^ ®’œ|©KÚ=ì|éÐ,ï–ebýcuß)/s-çãƒæÆ]É €¯do. £ôß…¨ÿ/Ò fƒbù‡¾ï÷;?ÓÃsÛê96Cã£Û2óÿöåD}Ê`¿}½7Â$çÞ}ßýj¦½üϹ£6RhM/ä+÷d‰2䯴X’ H/t4i!@ÓâR¾AÒ&ˆsã(ÄÄ_¾-Jåÿðk®>á²Ê¥lU¥RÆ$dÛZÈ-[ãÕt•ü¼òèÖž6.ÙHN6Ø…Ÿ_cûÚ± J¨–ÄIݺûê#ñuEYgà¼eñêB {LY„‹oÿß^­¡†Q©ÿJù’.6ÙXÀþh’€.°X|ëwÊêÍêˆ6”«¤Y‘ ExçÝöÿ…Žÿ/<<¿ÐÃK.žu=Èþ ^’N2‹EU 9¯Q] 'Ïæct_›û%É|°÷âÑ´<  1–ÒTöNirLâMvÂ`¦'+æê(,€¨Çɰ. Û£$g‘’†~îߨølÏõz¢“I_FÄpó~BË{ŠùF×Ígãú6'¾ÛÍ­Ãq±Çþȹ/»±­‰ö¶P&v±®ˆZ±ø¢"ϧìÍJ47tÔ\9Gݸvw]ú:IžŠµ‚gL2«ºð•5!^Þ <ÇŠJþ(0wÔ^8¿ø@ÞË£—tfiqY……œ—û¯\º‹2Ydœâ ‚©Fã¬Î®»÷%°å£ ü¿@€jtÕµú¯ŽëƒÄèz² ¬Ëûw¸çÌSÓXöZ¯û§›¿[>îkƒÀêþÑyØÿwcT= äæ„ݰhÎxñêYìÿ˜¥0Ù,ù*ì¿4c› Øä#϶%gî(h ±-ž¦ýRŽ•²’™³ã>òviûϲCNõŒÊÝ©<Å ±¿ÜÛPNPIT’­wùbÛÿ7ûLv¨¨Óny"3QÝ€Â~Mg`,ëð§Ûh”%ÝkߟSeHX"~¤p¯þ°ÿ/nü?xþÝãžïë¯Ü7†•{WÈ_7;çû |êß Ãýq Z1–ø™ °3€ €˜4h^ eÃb‚M»úLc>ò ¶#3À„;HÓ¡º¶.›ÿ™{t ôÀ:,_˜ZK¾À  ‹íZ=vŠCjÿêqŒ©ä§@pôcç¾*£(¢cë|Ó?}Ærbp*ýõ(˜õqMFtyfùÜõÚD(øHeà6«xë£èÉùÎü¡ì³írw$öG®\ZÍÅ“ý¹[t$íO6ÀSHSˆý- ÝÖØ”·ö¡ÂE OZ&æB²Ê škOÂÜ›ÙþÇ.‘ƒ–;e|Zç· ðÅeä¦F,–/y½`|±ÞŒÅŒ†¸ÝT¤Œ ©Peì:òež_{é÷ÿÅÿç™_ö àÒWcüu'²á?×…xV*gaW~´0+Cñc»±HFŸ¼g©%3m[ n7ve»‰2æÏÚåãÔ 0•³`!þûõþÓðï´kÚ˜¦ú.àC>ÜáÁQdâ¡?ÿxÎèväû•ëîîǽbgܤú«LC‘l{qY# ‰ôðÍ{¥w¹XQîÈÑrøÂ¡¡H`WônCI¸—o×ô7b,ùe¹0èemèI=­á÷¯‡1‡2€[€Cï²ãîÖk¬‹ja&A+ãÕzGfk4 r­r\9œäèϲù4Yé³›G¦.Ê€^ 1gQ»Åëÿ=v®«›V®Ξpñƒ ë½pPöBC\UÛ¹|ÍÑvÍÊíÚ¶›“t>Á¾˜S– ðµs³ÿƒ=¡$ߨZN-Jλ3Ø?Äz´-àTìUŒw¹‰Øc¨xÚþ¬!¯† 'T”´öW‚¹ B–ö§²º8“§U^2^'†ÊHÎa˜€Ä™›GI`U(ö_ùÉ…µ?à?zCš]@™2β›SŽ7Ôà¼N‘ Î3»Õè¢à*jE™“¥ D4—÷•Ÿ¼äûÿ¢>¢æÜâò ûEç”ÀœñeÞšÂÊYçáb çÓÑ?FGPä·|§f¿ŠYù$ô§$¹Ÿ’Ž”ªÓ Q`ævš1”¬ìb€ SM›U/«’ ~ºÿë[ûeçìñ²]ˆlá⬣ì°m×ëÆ¦"½““ÌZ'Å>º¯·–4Ò´uέ98„ð&6p§A_‚#{9Êv¡nõÚ€èâ­}åa LŒ8óQ£ÞŸ†ÔÞ)¶á"ÈÉ8*Á êò¸ÿµÔ%+MpµŒK`©ñLŸr~[;dëåì §È=WÛ¬ ⪢ºÆàîëQ|Š°Ñˆý¿§{¾{àî[—/‰ýqD±z§Åå)^ôbAª»Î§:sSìŸÄa'ïÿÂ6*¬¼yŽöÿÍ>OaÒKÄP‡i·ÎdÿÇmgLQ!h0°ç‡ ¨Ü•Ió3ìŸ#?rÿvc;Ì=(|Ïþ©hl¨E@Š*2”ñÖýTSŒ"°Q ìÜ„PÑa˜EWyR¯ÀJ—Öþ‡bÿâè#ß§þa‰†ð‹wÒx í²Xkð+§7'©QÀum€àÿÙ(W(œÈý¿ÔûÿyÆ’çø:OXþrS¶¸òáGÔ¿N´°Ú™_¹N@1\>`Ï+H¸¡™p<Õ‘¤].`#Š—ÏCzëP]e‰+3û^ ùÖÿazà£Wvœ TæWÐû…‘  ØÐç£Ë1¦îÕ‚ùÿ‹³2 ë —ÔwÞ ZßùžâšsÿÓÈ·Ãq9xN;€$5¡¬Áj€¨trÿŠåZº9 ûXààMgm—Þòõ*z7Û9Û ÀÔi¤ÁfæA§9÷ rÛWŸfKðEy« zîÜ)™(YZ†ûG¯Ø`¯ÎË|ùžøq®Éä$OŽÎ0Û` ØÚNe/‹9®<ø(Æ×Ôíu²×m¸Œòmdtyÿ­ï¾'è`=-¾„ýÝS¤o‡];Áë_;_û-­ÜšmÌG ãÌå3Ù?Õ¿Tsû³­½ë†*¶4î´ý-âž/æD0奾ýÇN›ÆÒ@a¹‹¬Æ…J–nxÿ¹ö¹–fé´NI·Â”ü¹[ÍÖøBÛÿqåF 8™ ¥H!«3eš†`MÃá!8°?ÉvDúB¾â±ô…Ín9îÅ•—zÿ?Ÿ(ò¼_ç ž¿¯ÀŸ±Š‚Ý‹Ñë_ìzŠF{£b‡û\áRVíi-ÓWwêäÝýE”ûÅnÍ‹ƒ3Š,ßq¡®tÔ@øš_Èd‘@cÓ;ï}ÌÇ1޶v}ëÎ]ʯ[¯´¶ããmBó¤n¤X™ñùúýÿp)R¸ö (6ôÿoëo%x·tpÚi-1 Pn'ºº¸¸‘¯Oëµ ¹ØÝµ4£‹e_.|1ï#zSžmÃj7ð`/¹9 Pkšì‚Ÿwó1©çq…»•ò)èX·V¯ûÖA‰± ² 8í óÄ3³2ƒ8H~^çW¾*9¾Õ ËÅçÎWïìö ¯}åiÿÏw{`,q¿'*ÀvÍì©®S¿ìT)@8{âÀöýˆöoú(ït¸{÷öó¶ÿgW ¨P9LÆsÖÎÂá™ìoK­‘­O NÅþ°|e_ëõŽ#iŸmÕÿ»!ûd#æ¥ëÙ_ãŠ_<°Ñþ‹¸hHÄþ(…°iìÊã’ýje x Èìýý)§n‹ñ^ÿmqAíÿé=9]ní1?{½á×ñHnp ùNVAîWÕ ö³"?~ïCˆû÷y¦6ÀÔn¯Ç ÿæåÝÿõŸIÎùuîù…üÂóMbþ²—†ùÅë+Û)@[N÷ƒ.“~W¶Ç¤Ÿ,ÿ Á!Îß ½©?q˜O ŒÞ€’úíWÊ×o—ªŒÇAÐNt$\­¨qÍ}e¬7ΡkJ´îâaÏI%@‚cLáÝʾzü–eLß&ÌÃÒ?»±²§À®õQ¶ èýá£b8%ƒGáC!Ý™;*ãØÃ8LžH!ñrÿ—vUQ^übR@EŠ¿¦2QÕä"w¢ªï\\lš1·Žƒ=YÑÌ!ß’Ÿ¯ïê­ Ö«Ã£|W<}&ÀÛâ$ÿ’óË=Ô;nÄY`¾¾ôͨ‚+Uûÿ¶>©ôjÁ ºx³2™œ Ð16ô;¾zï'0 ßr\èÓ °„†ÒÔ™d“áÏßþýçÊ®DdÄdÖS`.ËÙìÿ˜ÊâŽbçšØŸrtÌŠåaÞü3íçe.ÖÍ„@S2ïÎþ…‰-.Gû;UѪê}”o»[ÒGÓ¨À‡,ûm4ÜäH‚Kß É/¨ýŸ¨r¡Ø £Ï4Ò>ï4”b* C¼Þ?¨F3åC¬$Z±±N9V|„éæªô´$òåë/ëþo5 êuþ‘óûJü©WŽÀ+;ðUû{Äü4ú'ä™.{›- ‹_»û"£/Ééêš¿Ã8ŠìOŒV9Áà èäŒÅCŒbÑŽÏ Â‰ºµÏÇûWÜç·[±ÐctS(à7.·IŠÌÍdc-Ø„ÕTžÝÚÖ{ì\N¤5=C@Šð>æšuŸtßÇÿåsp¤"`ëGÕU9Åh0+“à×oMU¶%w´p—!F Ö(£™Å»€Õ‰5àè¸â‰£µ”jåø$QíâLG¯“†„ƒ/‘)ë-—…¯ N^–Ób><ôÍ«“©s—¡¡³À¨ÑÌ!•£JÂN“Õ9XÔ«Ç™ö'û?TÏ}rôK¼îlñ°NëïÒöÌÖï¸Î»µcÓÓ‡{˜;_9Pn7Ý\ÿ3 º×¾ûvˆ\„¼æÌWÉ^í›g³?ràvþsŠ…{úL­ PNöÒÊìÙö¯-›b`lØÖþVóe§¹N0âüØ?صq#ö?ŽC¶©ÿ/08¿RaOyéØÄÁÑþ_L+U” ³ôüKÿƒT@îRn8s ä~Fçò*æÕb‡µj®ekª³—´PÂ~àC YêPX_r¦%ÉÒ\5/çþ¿Qï[ Æ/gÀGþ É/¿ú«#m|†× ÕÁýlõPõ}J™qš?˜ÌÍ8Ñ5 Dî@Ÿuj¢ÎOÞæï†”}G»'è[t¬ ‰J7øûþèkîCãºcÕ›¬M;¥QrZº+ÌžNŠAÝ=%ro#eÏùèÖÄ“a‚\ûún#õ…ઔ <1Á›Ù!qÎmµlQë#|íLàúkrå¾ñáòTI§yIlæ#¼ðdNäÀC:MáªGÞz­† çÆ ŸxšØÅö$;uŒ¤®y^¬çX÷I£reÍc)GsnoñÞ`ï{°b ƒ¿å…€Ä±61®&¯»’ÅO§›è šöÆ_8S£%“Q­3mîHõŸïGO ­È‘€î€«uTcã"¥«³Ú€­™Ý`Y$EÍ'Óâl}éì]‚cË ;?÷«$S/oÔ¬~ƒ÷.°y*‘zœH;W.\ÆžÃþA \žléÙdÓéý°ÂŸ­m6«©ŠÅðÀ’Ýé6Kî-œûÉýZÍ5¨ÎŒZyü}çí£ÁG.!õZŸ+/}à‘ƒs#?Zˆ”[úËPà†ãX\ºãAœ=LãùðÕ¯UÀÀóÑæ¬»ù"ãÚÖ™©Ýûâ6ïÏü¯·Ü L—L1:rùÈ-û…Ï®Uä²¼ é“/EAd^G}ØáyëïG³y&‰ÄÙá”Z[äUjZÈç[FgGïSé§t€¹ u^Tã/­¦Ql‡òð…Ñ b†Ë¹’íRÚã¸;î¤IôPí+>Æ@nåˆ%Ͳ5+ u)¤KÈÛ/wóyà+ÄÐüEþF#¼Œ¶H¥+>‚Õ£sD”’ßnx$X`C ²/ò¨±2´Ô\Ñûþ"»2 T²Î!<2`©^`ôxøGþ3#J3ÁäQ¬¨ó$v}Ìeo…àüýö iaüi1•l¶Ò““ôj2Mx÷fèc;|:hiËÎ{÷‰»¦(˜ÿ1ûݼ‹'ÅUÜd¦Ac¸zuthÑçrËþ²µ }÷X›ì;$bNg évZõd,ý#Ä…«×-½ÒUvlÃHMÂÙ;ª,wÔ›°Ž“ Û+¼ß³ÁãÆ°R¨ñ;¹¿¹ïŽÌ%ÓØ»Žûdn™˜.Úᙞ†²OÿŽþ?›m0ú{:F,£~OÇ¿µmÜNØñÖîæ®žC#¢†~Þu;­*e¼Ý_ Òɬ r¼ K–æ.Î÷×°†;Vž9Õ·ù¸Öí—äÍ`üŽ7Bl‡hÐs¨³›êç*þêˆìnî=%³3·ÌM ¢c)Þ0Æ£Ò¡±1p£/â_n¡»yxù´ò6 ^õö¹ï{–²]hÍܶ§‚»W¦ˆÏ…ç^ÃnN¹Û ü‹EZD6dô6¡ËäRÓ§MSïRô‚¡7ÎÙ³}ç‚Øúj±ùÞàže¬Xãü‚"÷ÛYÂZµð0#ö'ü×¼ÏÞSƒD‰Ÿ?ž_:ãŠ÷ág¼?òŸÙÚ·™>ð‡MðO&Y8†’pþ˜Õbü+geÛëŽnB¡ÕLÂÝÅû†’ê–Q¿@ó\n ëÕÓS“ÿˇ÷šÁyÁûhØs,ÒÌJ68ùíæóVÐ4Ýwnÿ’DZäÉÐãTÂ=†Ø‚u“åÓÀ»3+¬<|÷…ð\‰ÆUj“/ÎÇç¡Ëá|„ç Æ¥›†*ç–[÷¢;Oë:;á¦@$ˆT| ù;úÿTkdÇßÖ7Ñ1ì·õý[š¡Úªã«S»Àþˆû¾iìQ%‹zÓgT‚Éaàëß»z[³Ä~€c÷ßÜ»“¡:n¼rº¡oüƒÍ[¸oÃ5ù–yŠâèí¹‡º€×Þêm (7NoHú…M~´âmÃvÈŽŠ;?ø!*oÿÒ1¾–‹P3 †%*‘0j™>Á:ØpVÌœ?4XäZPÖS5ÿu—“Ám ˜[jU²Òƺõº•×A¯ÜËs¢ÒF’´'EÓËPz> ª%½;ÖBï ?íØ¦¡K°ÞCvFR`^wó¡Ë†‹Vk¥ ·& 5ˆíæÜ^ñ¡?áÕ2‰ŒÛèk&")F W‹;ª;Üw<0×Óz-–KÜ›xF©ºUŽ‹À‰ŒÖ˜ÙQzvºÑ”1­Í~>[Ssàˆ•~'Ìc‘ytJ]¥ë®c!és @ÄúraÃoÙ\–Xˆ>Óf‡ÛøPÍ–ê\Ð>/‹§Æ_Íæ®ExzëÊÍG©üͯ¢šgß>Æ}wwyøë™Eû[‚¹aàú‚ëoƒõ¥º©ö«öèÌ»öš5J×gœwsà¹úzǘçЫe}—ÐJ(œ;å9ÔYHqñ‹áb¹&šùáàÅv罹‘êG‹µb4À¼ÄÊÄïG4!2Úå°]ià?ð‘9~)QH€§,”ç/Z'Q“Љ„ùÂÙXðìÒ*Ô­ÒÉxe)äáO£wn‹Y ëk{Ÿ@JAW3¬ RØpÃb‡+e`òXàÐS–™¿—ó,é¼GÎ/úœoYíxú«ü—T ²­BAþ°¦ü©ŒÜ»²(q%X.N¾–PÑüÜÙËl y»ÒOøÏŠûØ3bÕ1ÇX&üÕ¦NüÈe79ÜÕÎ× )Ÿ9É_«à~^‰Óœ¿?dºDD3KÁc <$[Y¼1ó÷t«Ï ²‰æ7€x¿wªòbƒO¢k l²Ùúǘ¿KšãÄÛåOÆwmYêg\¿<6‰o6Ò)Y½vV$|*ºKciW©T/‹ ±‹ÐŒ‚•dIš08½_¾ñi¨¡¶óÆÇT$Ô¨äþ¢´Å0#èH éÐÅÑÔ®¥¯/ÜdñÝRýwóÿ)Ø~#Ý÷¯¼œÅïZQø7;ŽÛàÉãšW»©‹ãlýfIúÊU»?@Q0rW¶°„.¸µQ"™E€…&2cÓiO° »~Ÿ`ë÷VAüóÍ~ò‹-lÍÞpBt…ú·ûi‡$ëõR`œÿ]bs¹ær¡ë-ÉþFšÍÂeÀÍ« «RlêANÜž=XOŠø–J:°–›þIÎc¯—ý’™¶¶)ϳ?¾|%Fxé Äh€dôÔ¹VÕr…:í½6ˆ鶽D~²7IA·ƒñ$°ûF«v‹ UùNä ²í}tÃÖmð*üKæI™z½àÆu…Òá‘„;GMcyEaW{ÆnÑD±–Ì#—,g¯¤8¾Žg€Ç.m–þÙ_^lRºðõÅ‚¸E*ûòŸ®ˆ64ºæá¶Juý‘ŒãªOiÁ‡»\÷Û½ûò„ã×Ö7ë×<ˆ’ŽÑêÝt‚¿óþÌM LÃZ¹óBÈá “ŠvÅxg¥-¬ëÁwv;û¸Óó£Þ w,2¾qñ Ç ŽƒÁ&c ÐZÁÚ½ebôH[?íW†,I+‹ÒøÛŒ¤=¦×ÙȚи3MU†=oG(\7Q €‚’ægž~ê̱•ô‰ó> öRÿ?CèÌ ,yøt\rX6ºÏÉ}ëåBïQõGT°*îÑÓºFé Mmð…$†ÿ’È{þ¨áÆŽ¤ãDŽé›­›>®Xº¹þ‹y„CÒe® HIÏ„ý- r 3÷S°{زw@Žmš†n}ðv1]Ýb‰°Ë ý¹Š»~7ÿöÕÏõó, ˆ„_æoêcë„cOw€œ{RÆ~-ÿºÑ"éJÅêr⇵Ÿ„è!?á/{ãÄ;iѪ[y¨Ë¾2Šeêü…:#ëÅ^­uäÿ|£•ÿðN&"ãêW"Æ?†c‡õ¯‹@Xª2Ì3›C(2 H…2#ÔôÿßϰKt§Ãa¸Ø‹Õ2ÜÂP]z+ï‚l˜Ëö:Ðã˜ç©íŸ§m[ø"ŸW ƒgUïŸ ,âе»ÒÆnÉÕÏ; }O%ÇÈp9•7ÌEòXSì±$[bÊÛ%;ò û ˜¯?;H$¼9MnkÕqÉõOÜ{9¼a÷pÝèkÖxó<Íoÿ^þïý_Cÿys'ûýÞX†ÿ¦Çÿ¤¹ÿK>¶¡¿Ü•^¡ãâ1Dü<Û2€UA{_H9ŸùÄ}οð°ôiîà™7 ±aça€cov­oËÒw]±ßËd €ÎC©x@V³…PeìÈ1ÝÑ÷Î¥—ɰjD1þ?ð7@±Ú¡ÈkmOMëíözÄ€çš`hùv™|¬N³OìPš ò«Hï[ë]t.Iùbq…:3­Ù»cÁ!j¥Cö½ùCl q( Ö£ÞœY;¿ ønÚ}ݵÉðêgOŸJ»ÿ]3M»gŸKÕŠÒ%…—ræ?$(Õñ¥;K–Ìx|úic·sÛAÄ£;í«³>š€J»¾QDm­=ºD¸<Ç~:ã_åePs-¿Ž^)Ûà’åØä_$í@ù˜aÛF÷ŽZìY’½ÚÏæ©þ¦xµÜÅgîJºk¢ÿΡó #ìº.¼‡wÓý+W|Ä”Úòµ • KtØë{æw¾O7µ™V3—–°~-çV÷Ï¥‡Í· 7É-¯ÝÍÒLƒŸYTY 0–VÐòìžFyrÏÄ„ô×ÈÖ^ ôr–õ‘|ê<ûy²R¯¼~±™çòl·‡`¾uø?á?ó•ߨÜÒÓ£—ϾÏAJ ~ã‚a€GÛ®Î-œÓœ|0AöÐÜ@ôaðBoø½?)¸Ó¿¸9s\8©@7ÅE­ œv ˆ\+h0T°4{±þýêgÁd`™ãU¾Ñ•A‹K$Ö~@…ZbηÍÑ mß–)â¹Ô£8ö9_÷ëýýüš·ª}]|äuOö¯ò'‚dÜ9-%ï«@âim­¼÷Fk `QƒÝ9XE© `Pœ7uƒÖÏøÃîØu ¹Ð¦£SÇ5GtµqUÖü¡œsï}Ÿ"çÅIþYêgð'âü_m§ÁøãýÃ`µÈôÀÙŸxö*@m³Ï>§ÃÑ•S’ÿæ: Ë%¤ ¬ó|}TkÅq¡÷Áð¸ç:|E^=#­Ïp€iºë`ûÚ¯Kå/g[Á#kmøYj7e•³ÃƒêöTPÏAH Ÿ¨¢¾_ßÝÛë &7BŽmáÑRí’ßáæ°æòáاÉèØUæÈÂz$gñå^å…Ë‹Å>ÿü_é—#È_Ý~[Åü½M¥×¬"þ»×ß”ðÔšË;&C!¼u@l9äŠ%“ R޾ ?§¿Ì#ÂųvÞõrŒH}>0~p Ö¹[7½8¬c÷h¶U5vYD–ƒaÀ‚1oçã)«/ÝB$¢žn0˜/6ôޝ¶„Ñul+˜óºF… yÎ|~B‡¯Mûžƒù—¡4ØÞWº’Rb¾?‚¥Hé°Ú7ÒãíÞ“»´ØÁ|w3 âËd|$cŠ ÅˆTÌ›I£ðŸ˜c¹Zœ4\¾bšµï Pyò~–±TJt~ýþb´;Á×¹DáÖækqON]¾&Ç­¹béq&{ÍÊ>°ë/bW(•á[56Çê®öî»rµ"`Ûq.ý ê½ÎV[z™ÙHä€ÍÂÇ—õFæ®Ýí²bL쀰säȶ7Ç«gr4Ãï®±¶Ã÷8Aú¡3 œkØÊ€Åía>8'+ÔÝ,|Z >_°ÒjÅá…б«öǬÏÏ\ /Dï¿'KéÈË¥[4Ç–±}lZÎê>Meýa…w¢îú\ó·…(D'z9ª.Øfž¢f’K@:‡7½oÜsœŽŠ5î«צñµÍ…æÆ˜ÆžP®ò*Ü`_â·ŽjDu¼né÷öHTBÄtþîžèE\þV£,‘f â°_˜Íœê¶&µ.>mU-|cî?åï%zKW´ËC¯k†(86­Ö¼ê`Hï2ˆì-àºNƒ+${¾Ò•ᮟOvUQáòÒ-°«‘¤‡»Ç̲ –xO›¡zªmdæÙ’mˆmâø‘ê—¢`ÚšõÐÂê üë«Zw,ý«¤|–yî˜ü‰3î ÅÄÖq¡¿ÌÿT éÈ×—îÁްG6n$ÜÙ ñÄ¡2ÙN·2•eùóT?^<Ô·EoëÏøƒJÂîFdFŠ­y[¤nËäz`Ánçjªûñ×rßø{\ñ‚h3œÿR…s|TŒ¿óÙ‹[æÞš%¶EA§nŸŸŸ‘Qf–Z ôÔã¿ùø¾Èf…#Â2p”C‘2ã¤ù]ñòmƒb(Iå¡¥Ný û¢ù÷ª»«Ào‹se¬Åa³»´+›.êræîõj@âMŠ‚zæWnç{y$–mý<{eFqÙî,¢*…"_ÔêÄu}"ô2ÌGœƒO¤‡× ’n 6ï2"aöÏNûûøÿÁÿnxùÏ›£ãwÀÃõ¯{áóëð¿h?iäAÖ³ÁÒÓ€ÄD· JÆMbÜã­¡‹*EYÛ@t4åúòXàDò ;ƒ¢æÑ¢”·úøp6s:°ð£ÄÞiÊÛ¯»¨¹Ù„áŒ\Ÿá´Ðe2¯ÁƒXîPë9óz’úaÖ²üe'^;6K?> B Õ ˜wi#µ\±êÏUA3 ‘»jó`»ôþWÑó?mU û6‹§ƒQ•mò¬ðÌ—¡Ó½J 6_ë¢:äû‚¯spÓê¶Õpt_—ú9³¾{ÅfÃO|öU¼Ê÷m> §[È,Úv""&î0bÐk±ÿTK}ÕõÀæUOxÜܼ£‰îÙÈ!³è™†<€lMŒŠ¹ª$WfhHE¢{Xö0l¥•ÙþV_xÙ¢0à3]d5«Òu¯á{¹ÈžúÂ’•Ë)Zìm© 4BØw%dØT¯xÁvÍ DÏy5gå€+»-;ƒÔuÞj]ßÅ™|Ïo¬Rý õóA'¨!>‡x£Gþ«1û\ªš”ÁÊ›aec~0_cÜy³õ£½ÁžË_­ÕÈœ¬õÁ¼òaÝ&H¿5—êßB\{¿Äìk&¸k–Û^{ö`»Ç=n4 å8(i~µ™ßðÐÑ…çøyþ¾˜[65ÃQÙiVæÑÿœ¿E¢˜:—¹¥_%:ðÞãƒÍHæè—`j¸Ö tåËñÐÉÙwÍ×Ç ³ú`MÞ†«q§ùÐ.†—É’³]ÿ«" >g‹'!ºv2~1^1!£•CëžxžsÁÅOÝû›®G¬ä¯ù"—4>OG>Kªj¼Óš"ü3ö˜so'ü:ÿi^SÄrgû´‹Qƒò°=b÷ˆPEéhi8»²d×+î—ôS§;·YÿŒ?lh^.)20ÿ¤Ì ’©$üÈ¿}£,°’A êñ$Ž{qåù&ÿ•ðH+Œ?˜¯å2SåÉÁó¯¿æ9‰ýQáûw` Raç:Ëp' µFb×½j½,£_0`C|ðÆ÷I¸GÚ î!_‡© /t:°ãT&A£>¾­ƒ.µÀ{_¼!ž(º¾‰mýšÞžYïcT"µ½z7|¿ „å=48Ã|Ô¬…–ƒCŒ´ëyÏÓå[. 3ÿe5õDj…Ò Ç‡ìæÖiÐê. Ü>ruŠ%O é¶;AäB»“\Ð2R~¯ýÙõ¡`cÝë(”Ýpí2˜‰ö$…?àõkçŸÖîõÈþÐþÌãå†T.s<êž6ê+Q 4]r{„Ñ\±›ã³ì_oE\4’Îí*“ÖkÓ iU¥ïgèŸ÷±©SOo{r¿gãÑF©Ó0»à|”kyôÇ+Ð8ž|´¨‹º\Æ-ãŒqÌŒí ]—vßsRà=¯ÐñmÏ?§¬šq`Á<¾z_©£}TcËOk¨àœöùvV°ºD]à—”PX­ÆúvTäEÃÁÍÞ>$8ÉÏ—¤È|æ_|%—OÒø˜ŸsrØ‹E}ÐóžèòÆ$Ûo|){m‡‘E<:ÇølL çÇ?ƒÈšÒP<‹w^§ìÏØu´Â™m9dë„Øû¶%£´h ̯ˆŸïû¤zÐ<à\¡ü¡è“©?å_—¯ä™U 8^Æ…ÁºA*¯ ê$ D8)èÏ«ból«ÉØ¥AW®<¹•çÁ×F~^.*w·o…~{KdHºÕ}%¾.ê*ó5Tê-yÔafâ½H0Ùé÷Üĸ@Gº6NLÞ Ú+ó© á¾¼Œ©Ã_¡øBý—'k~™¿‹^ vÿ[ï;\ Ûw—åôÈI$“—½1ÿøå¾”^9[Љ…;ïmÑíÿÿt¨hl²‰‡&÷«™U Ö„ÿÈ¿ÿÀ Xê¥Ê–2“ü÷]‰m]ÍÙ¬‹ó— ÏÛÐâØ–Ìêc¥yÐ8v~|æ›Á團ÂT䟱#1ÜÃq¼¿o=œ·5¢‚L§>ðl]>š½•d.é?_9t”är5Ôd¾[/iÂõ·{Û&Ç;î??¨FµNïÖðÏèXÛ$OºOe‰ãŠG>ÝÙ5‹š;+Þñú1.˸EbýzV‘ï{û¶Â³m[uÒ¤Uƒ©Óûê·týj•ÂîáÿŸZÍ:tª<|·ˆ¤þî!ü_¶ÿäJA.ß4öø3áØµýñ~€„Ì37_»×ò)™Ö‘,¼ÎfÜ–^“ {ZFz±ª^šˆv¿XC¤œ9Ö(xdÞMõ}NTÍTÚ»^•c"ÛÃ[¤SÀKí½غ`ÆuH­·±ZÁ"4‡Ÿ±¥âSÙ=ºñƒÛóê¿®r6úÀÁ:G0ê…õ‡ôù WÞr!{…FÄô{©`æ ’µòÞw¥ß7É!<²@Þq¦Àùxt÷C¯GÍœÊä'÷Û{Ž×|n·W×Õ­nKž 6«7Œ ;ÏQ6u»_·™ßà"…Ô>¾˜PGÜÜÃM…[§~0ɦôŒEx9n»¸qZãŠv9¬ú¡kF›ŸÞ›êVõÜ©íŒÀkcxcº$ßL¤0š¢û\‰2·¸÷¢¡rÃÙè<ñ–ŒÚñfˆ,ªà/Ÿ&R&Y’™AwåM9¦Ý8Øý¸Ñ‡Ž]®£îتZ³J§ž®Ú ãî, ûù[Å|ÜÇìâ©¢Z¯Œ®s&E(侓"Ü»³?˜íì8•w‚ì¥X ¥š7hN¶¹[>tE]ÙòÆàúXT„_4úDã£WƒnóÙ÷å wÒ“¢ãåR¡"ƒÏúë³=9ç  ”j«®Sc~Ô>ÍñŽg¤Ú+}2Ñ&ê›»-¢ROÕóoýœÿ®“Õ”|…ÙÎ÷%Æ£AÇìµ–?ÈzZ~ÄÿÙ,Jã´Kîƒõ Û@~BO;¥Uxtú'$¾|zPä¹9[ÀmÙ}˜u#sþ|•Ù –N§Å³Wf”‰ˆ×Œ¿Î[¾|dÅ+½g¦Ç÷¿ˆÈuUë7“BüÇgÍR7ý:ÿHß´ ÖßݤPxf¥7̶ˆ.ßUÿúÎÛ’³çñžœéê ?å!/чö6–,.·í|Þ|m|ùü-†”y8¶^Q-„oü?Ó´}çqþòÚÆÑÿ´U+XôÉ4ÂæÃl@²P©U‹øsk¢§ÿc"cý¾¢àýŽÊ¢¸ÂË×½¶&NY4߈~›j­‚ ßçº.ÔšÕXEJe-—¦u6&e)Ȱ%ßY ïéM|\ÈNÊ×µ›vxSG¯joV"„¿‹*8X¯ŸЕ·Ó$ÕúÜÁ rþA ¹ÐgFá´ ·€ÂÎèE) U Ÿ1z«¯+¹%œù[øÿ²ÿZú¿j$çàß=„ïbýý"ÂTþ¿IVayÎKUÁüŒ×½ ®¼]€ç¬°}]ص%o‘à‡`›´?ÏÍñèPª^t¶v´©ò6ðm»µð¹æ*LãÿÒPQôS‰´v²€J¥ù‡Ù."/îJ?¯zH)tm¾h¤Ï¡Ã&¬œ³° ™³—L…•UOvƒ¦ý™HÐ)ꌀç¡‘ó9Ó—ñ¾_?^¿Œ*ûIÐÞ‹÷^“=ÓηY<ÛÁh;1\,jD"f^‘»d}“&ûj™4/?j½$¹cC³ÁÚqêŒ! >Ñ Õµî ÞµdaŸÜ7e¥ìI„C/M\ ûj,`k†ð(BqP¹#ðÂÀ7ÐQ>v®z‹ßŒMÊíÇöF>ùÐz ®Ÿä\.I‚6O—¼;G¡¹ ,Õ> jzxºøxe óò*SBzä¶äHH\UÐWØgëô{Y‰¼ Ú¾ùû‘õÕÛÒ³÷ž8­bÿ »¹uÊÊuî]×Ómö,€äšEo¸›6l'Dn¹Ù°Ñ]Úõ}ïâSM×W›~y‰%æu)·‹5³Î»×pd›âÎ Í-3œ f!äcÑ WߢDA¡u{ŽkÝòR¯ éËÉÕ|B6#.!ªìë-}æ÷‚]Â7¦]DÍ?ûÆl¤I ÞW^×ü¥G‘[Æê"[|‰yôÙ—ýKþÿ9ÏÀ„NŠƒ£[³yÞoVaXß›q;:CÿÍ8lt=»êI} ¤åëjzËA”dÃßn0¼aþÉù!„:é ·ðuÑÙ©ÅÿÁ¾Ñ]ëO"º‘-Sõ‚H~™s/ýÓ Ò¨,Š\z, ¦“ž zÞ\ÿ§üûv°ú̪æ±`wå BËÓä?ño/ž¡ lìæÆñœ“ü©.5õ/¨ÖLþP£ý¶ã?mËû5µÁ_f|U±*z›_pvs6õ_úÿïà¿tµJ·ëÍ›¾‹çÔ¥˜®£.é7Š¿ õÎÒàÐÓfŽÖx·Þ ¨õÛ¦'é^öþ©®è©x<Í?ÈÆ¥GÓ¾?ôRä‘Ê\!êsVëa:E4)5¯[p»ݸYô‘–|·‡®àË®ˆ`èC»-¶ˆ¦9Žk;俺œÞÑ?Úîí¾tÍËçæÛæêXš¯äüøÿ[ÿÿý/ÿýØ\ISò$ÿÊæä=@àt•.yL7ÿ›ž#E¥ëO7/O(¾Ú¿Hv–‚]¥"âî*bž{ïªW@Ï\/#¥k©ð6ÒKëÞ[Ï9W¥öË™²¨Ìò..w`kÙÔ©vÑ=iU÷IFíB~ •y·;¿Ô[³×=|מ߸ Ι89öKpò*8k |Šé_»‰9ïýØ€rJ¯v´«æ½œ_sÄ=”íXLåN¨ @4ž„‹ëˆnÏH;‹ƒ j’ÝÄt”ãFÞJRº¨ù"‰plcÕªen™åBšç=¬tÆÖ Ö²¯;`<¢")b/˜r‹fY]9;OqíF £¥{yÉœo{f-¶ |?#ˆî±äUœãØ Ö‘[í톉 çƒê…o4¿l_«PJáíp °ÈPÏ›[|]jN<éÈMˆê rÙVøAâÍ»bÔT\,c¼Á}kn?DÀP~YŠ}°@XQ°{À•-ÂõÝ`òѳeÚ1Ý*„$åÛ–ÅK¯”®¼sOçÊ“ €lž§yøÌ­­žþMÇ[šŸ¯â<] š5Úƒãí7f;O!:ÄqûÆHílH{cé~“ÔeÃ}oå’¼!8°tµÑÕº‚à—æî+¢Ù¯F{.W¿o¾9ñ³†Û¾ñð vNÒ¿ä/ñ|K4:Àcï’WiÅ’ƒZ¦ÚµÍcÐ+ƒ§<;)O«Û<6¯X‚išèÒ}Ní¼„„ Þ„ˆºoÖ³h‚ôéù«PÓ%DZÂ_èÈ.Š•ñÇØCž¬¢Š8xÙ<8CÕ°ÅØaÔT¾¤ZuxYe!{<„†„SY«›OD%÷½ûÐkœ<gñþ±^HQøÉñõ(OzNðìÏA#¯÷$®8¿‡Ò^æ Éu‹;…ÁúÄð^±R[ʱúÞRÔDôa€³¿pv&UTè ò°®00w^±`€Ã<ψë /§ê•} RÒå·¼·/ìï}™Ež~½mç̃ìE’óŸT<µ½ÓÉK`í÷I‰8Òì{òŸõSWCôô& ³j39]«„éH‚AðcQWÚÖ¨Ãl'—H½hµ0„… ظ^n üÖ[Ÿ,Ðõ§%ì½¢ÂɆó6@µ_†"Ç¢Û¿_Ãù\Ó2ÊVP\0äË=`ô9Ë<çn—À«Î‘]±3à²ùöB0³èúe Ϩ;M­.œÙMƒ‚Óc•ó®z¥7J$š›¶ôÖFs—ÿøßeËF7Vl€æIá39°º¤›Pá,üh©^·^¼Š_ÜŸ~¨î@$€Ïc/ÖgÛO9eÚZ¯QòŠåh¡nÜí ö'´±ÈåcŠÅÃ-›f¨ýÈd ^ÎŒ¹ïZNòïsa\Hfóeò.½âZŒÿÂØÐõ7½Òr8ç $Bxxïk˜rücÌ`û¢ÓË5åzfµòïòÙæ‚¢v'ì=rh…tßy9¾A³Ú‘îÕ\/¯µ{ª¿O•÷»u·õæw¯„g¯ 7^šÉî ½³P4·ƒöª¾ŒË¥ ž%ôùìêû_Ú“}uì.ÀûLz7ˆò˜«ÞhxC¢ç¦ÆrÚ„=Þd·ú×Xg]ò%GŽYÿëþßó»ПÚÔ*ÿ™í/y à¿ýÿ/4·bò´zÖ€Ñ. ÅÔ±óÁ𳋩Pæ{Ê÷y7U3ºôãð)?p6Úú*P·Døæ1ÅÞL¾xÈ`ÚáÅI®§~°\mÓVXŸuÝÊ XצÁòi{ÉÏ•­ ¿õ¾UÓ£¯òêïÊU“bœqÝØìr^c}£Ï ñzE¤Þ¯í݉%oaÎ÷Þ®kp[[1 ê=€|ì­,5]ò™Ä ¿wñÞ$©Ò8€ágNc¬Ue1Ãàæ¤×?‘MÝÒ2˜D¨d¹à±cùzòÒ~¡’„ Ì[_®©"-í—Bèæ¯E¿Ä(øÇÑöä§!4£(GôXÊmï õ+Ú¬SÈMâݨs×nÈÃ6ñöµ½ëîÙ­ç9<õ4r}#ö_ÞæF)æ¹föˆ+‰Jî‘=±õ®ûCIÏ»WboÚ†)ÝJ!Û§ZŠo/J-C9MéĹós¢dêÚy 3„cÂf6¼çö/qÿ¯ª`2šÚ ‚+¶Ñ›6ÖlŒ7]«¦¿ùêÓÒ›0"h:ÌBùB®B¸Ê®p*oœ~ ÔjN£„\eo úQUž4ò,nº~ÁÑ1ÏÙá&˜ý~ÚUvNT°7*½A´@)¤wîÆ‹.êÕí¶9¼¶ÏÓöK;øÝ‰v “x+Çé<¦“`A8Mt0jp[Wþä¯AÞ"ä Å*îÞ¤O_·ˆ‹=‹†áNg*[òaôI@º½ÞÚ•°B"éŠø†™P€Ç•ßWÎó#Oöa¦=Û‘é§Ã½¾ƒÛwÁ ““ƒaÛ=¹ƒžÑ­ëT2ûYV=LkÖz0}Wåÿ,»ùÇ–îžø(¸¤l¢ÒN@Ûz;ZËFã˜aÖµ2bŽ&‚ÁÏ~Ê¿îr,9ĸ'‚Rz0ÿ«_÷#ÿðtÊCd¸ÀµhÝ¥;“ü¯˜:T3­eòW¸ôõ`üý¯Ìt³Œ,8¢* î+ª§®ÆB« ‡èB8¢Ù ÄG{œ¨&¤=é‹a%Zæ/ý$Ø Û‡Ìš}-°–x¾€Y‹ô¦×ÀòÆ$_Ú46âýròãÐç=/‘´G/Ñ”™¼ŠMaÈÑpÂ|óuˆŸ‘`7• »8yô®SäNT4°î? )›.›Å”޽“Í‘íÅYù?îÿ¿;þüØìý¦`µM²ŸºÁû¯hÖ¥]EWà KÉ;ÍN^± T©h-çXsœmíNɳû ñ¤*–½‘t#ƒdÈéâ½~ÆÝ‹ô÷‡:<ôT+`)9ï×ú^}J„“îëæ€…Á>õÕ `w«]EO›?Lk]:Ý]…ûëØÙÊśٯ=rtÇÐLá«û›¡3Eq'¼TZ|+ÀîÔ#K »Ê7¸Âåpþ€ÈS [¢u~}Šž›0¥.‡H"÷;ûØõY­ X¡ê³ecß—êÓÚjƼp®TÁY ¥,/GÄ•è¡ø`46Æìc}²vtN”!ôZ±>ç‡rw¶âšpóWm¥ÿÿži+ Óª×¢  Ï³/ÍÕÃl¤¨%2nIW¬ð6m³˜Å9ŠÔYK²ß•HÚ,ýXÿÎu%:žÝ€Õ|ÃòÂ]¬9ó`ñâÀ#É`v`·7…;"? dõ[éÐÒ/½Vû–?ÿtÈèЂE.~Y¡+–̨ QaݸºlŸ–Â)®F”ý)™/3¾œ&¼Ý8‚§Ä¨b ¸ýÈÿI¼›ªÍC€›Eì“üu5ÀÉJx€†ó×NÕÌ:ñ¯½9î:XR\æEjü75A¦˜îƒm1ÇÙÚxëÍFŸPŽÍÜ÷ß›Á¾g.)ëŠé¯yìNÖ@FLˆYüËõÂw¡Ìg«fÜÑòs*õpNÞÁÚ‹”Õf›4¾Ì8Ù¡`³öCûhF±Âyþ\hß¹a¤…Ë5|t¦i|á8²ñX¢´î~^ê¥åç¼E=z^Ì÷.Bï´uÙ®ÈN7ß»3r¬_ ÿûÿÔiÛ©iÁÿwá¿Ö¼$T§;­WY ®6 _0hÚ±TªcÐÈÌo°ç$¸]‘Ú-t¯±ÓUõ“@oÁµé¯z¸Ãê¼/¤°¹7Ç8õb‰TxÞ5Y©XHº° ŽˆJõ×9.†³‹YV7ɧ>þX¹çâ`C‰¬»uR‰dôû+ŠWZ©Ift—øÐA•Å2¾Ù;€®3ô梫cß¹¶·û›¢€ðhG|8º,$y9MS÷vmÂ!—d ¹Lšííñ¥Iïݪ:¨Šã@³5ßeõ2ŽõIÎ1O¢ÍšØ­s­ rÖ5Ð|Î×öNõ¸û™k:Ù~†Ë[ý›(—ÁÊÒˆÓîI•ò*éD°l*ɸMXÕ)øÎ"Zd‡€tq·áÙ¥‡-ä¼ïHÄœ<ù&{é­œÌ.:Í¿rµ¿·âH ä3¶åÚÜݰ½´Dª@”“- F'Wó‘Ëùw @§c/gâ /½Ýà΃‹tùxüå“€ÔùÆúAðè;Z”½¸ü‚Êm×x2›y–±ÜØýf%ý0TÓÖágƒðäFÕ©3¸«-O\wA¢M®j¤nÚЛ£Òçßá_ÒØMˆ»¹ !>)õíÂ7IPXãÄ`k‹¦€ËÇUß±‡¹Ä—ñÓI3èÕÑՂ«îAsßUïM¶»EIöï?m¸=ÈÁvº®w!ùªvÓºÀOuµªü-ËX®Ùb`,ž•,ú~jò/Pþ øo¦ƒU¥Œ\•HÅ¡B \n¹Tovo9àçjËßà£[ª¢™Ó4—öSþo*FN-ÚlL¦yðE &{ó©âžpjp0`†ü$ÿã=ŠÔ{²Ÿ2ùWk~¨\—Žñ¯b»R©e­io®´ejñP}úJ\Ô¼¦øeº=’§ÎëE 1ùŒaÿš7rCóz×m/å¨$Ò;‚?G˜ÍÂί‹ t7Në0åKû÷ø¯Ów‹ØRæ÷ŒônøÝ-ë·d,–P£˜øîº:æåiˆHiô…y.C_ؽ<ž»Û®*p_ÏŠã@ý€ÏMg½`WŠjÍ ÍtØkr µkà}þS-Ž©ÉëõŠ¿Î¿]CTþ¸0GÌ=¶X©Á˜mïr‡Wo÷‹áÒ[Ë®0„\ƒíêo~Ê_u‘Ø]àQ†OQÖ¤?ñ×fÿ°^½¿¶V´õî7þ¼¾ó•I_Twâü<“â;àü·J‰Å™>«ˆS©Óÿÿ¿á_±º¦ÇÁ|[Í-Оñ²‹V]¤pÛå6Q Nì2°Ÿ¼ðb{EP°6Éï¹þnx$$ÜfþÔ±½HYÚb5úÜG¡¹øî†q0.4ù:dœnu¥D]ÄŠæ•è¥Ü_tV'6Yë±Ô³Å>ª‡WÃÒðºÍ’hyþAZ}*„—‰¹ÛÒS¬U.ŸKC¡/³…-Wä7ý%ü§¨ÿ×ÿîôÏò{~ó¿ºßß4‘ÿ¤!B¡R耸¨]ðE©$¡ 4là*™F¥P©gÄ¥B¦¢ØW4 ‚’±£2ÛgïëI2ŠY¡b_¢Š‡biB¿&ѰûP:©€b’iàÌ``×A|C™ìŒyBdà§Ð)ûà‚7fº?ŒçAÄ`˜?3Qð<‘‚Ú†N|B¨Ø??˜ÿHv"£û±)`ûtòd|ƒ ”:yàtü“‹&Àeô[/Ìþ]‚°cÄ®@%Qi$:Bb‰†]™Š–Bq  cÆÃ¦B&{2{Áç…™ 7+v•½ÌÎ\}¨Ì¹úbó÷úq Ø‘ B¦Q€ŠŸBìd2 ˜I@œ• ÿ“fl0a(âäÔ>ióPh|þaT„„Í“N% À@(!¡(Ñ“H¥0H "†‹N<™ñgþç|'zdk¬ø¿8ÿo¦G¨“û'Ža>±Ã&6á9£eÚ{’þ‘lJ›ÀÉ<Ó™áù'Û3/4I”¹¡¨ü>þW©8pÌ (‰Žïâû‹ü‹°#1¢¸yã»É¨«âäé‰"X¯˜ÑpŸ ñ'üƒBa‡ñ§2»ù?2Ñ Š_a‚ ‚óÇ|–â„}C¦a1Ä6•Œû' ð’éØdôR§(ÿ‹>Ø|ñP ~K»ýqÅ Q0rØèq¸8Ù†2Õ a ·nQÜf-§`l¶ŸDÇn{lêi\ÜDØ„±3°{»P° §™GS¾Ç#*v4>y\¼1Á儌™Ž†&G‚隣/®³˜ 0ÍÁö!~(' óG²(T6ÀD»ÿLI°ë2ˆ(…AÔÍ È LÿÄÿýŸ45ÉÑÏ‹iøf2øã b1 fr–“±ø›Q±ÿüèß§B± §ýv'/õm®T03üüÓ#³™FøEþdÜÀ3^0ƒædªe8Ý,†DÃÂæEøýÿþxø¦âQ1þžÔ‰¯¿óG¾ ¨ß6ØDHOœ?öÅDÐÀüiâ¡á]ã\ÉñqÇÂ3m¢2`*ô]`2 XF “ú0¨àäOÐ¥o‚„kõX`C÷CÑïN2±{" Ç|zbϤ¨MãìO>pÎï{@@¨б#ˆžxp ã¢‰«ò7±¥àLfZ„Ud:^Ják'¸ àwÚŸ´pr dûÐoU,sôx‚«üD^EÅ L]èàFŸœöU8Éì"pB™uJü^3ð* OÕPÄ݇â‰ñ$“±Þ¬"d S09`ITOld²W‘BÃFúÿææ«»'åã~/Î&-øÝOð‚ßu!þ8ši[gO/ø#”Oçö¡ßŠð?Šúoßý^þ¹~ØÌ'¢+Ýû«ü½1¬xŽNä¹À lD‡P*3ha!žJC˜ãþgü‰tføÂd šad/°ü‘?fo<^à§OòÇÎr÷Áóoó#Œ¸a°ïɳv$+`™ñ ¦*ÿO\iheÊT"ŠeÓô˜¡&Jy”êˆ/ ¡€—÷øhñ2„Ž¥8(lþ˜Ý¬é~˜r‘°Ic†B1äL³2#7Ñ70VÚ“æâ3!Bˆþnþ?ò[Gõg¿m2ÿfÇ“ñË(™2€TΆãYì¤h!.n¡xÐÆÓlük òM9f5ÁÜ熯èMTÌÅ|ÊD¥ÁüÜÀ?˜ŠN–ûy…Åobçùj†eã‡)?èÔï%ÅŠ³‰1M¬DÓ¿&qÃb–1û£ %Ù‡aºC›0+_$aÚGôÄÆÆLÐ0A ‘™G£˜îxí-ĺ²‰Bh$<1•T,ñ§Q†»‘FÁþüÓÂ&ã%óZ®®¡ßãîD¾›ßçÊð„okÆÈG3ÿu/ôËOn˜äûO%ù·³(‡È¿›ÿeO,XL¬Ñ+þ2ÿ"*óaÙÝg"ÏÅi ã?I£b™‘ä'ü­Ã)IvY’]‚?|ûƒ?V–RI ²'yrýŸˆE~~4“ÿ5Ì-0þxŠ1YäãQ KÅiXA õõ?úÿïç&‚ù ‘Y`Ñ™ Q²]}bÈyK¢˜æ ásÃiáPðåyÌ'ª€‹àši†o1Ñ$Ñ™O`)ÌWì‚éÌYL,õNÔ@ÈDíJþ±8Â{µŠ`ú½“Ï÷¿ë„´ `Vhß1˜«ƒÜÀ‡)¸q'ï/œŒ`Of¹A¦'ìFÇôˆBÁ­â€/zþ,A!# l7v6J¤" ÀÆ?áÁû[œE0þ@ýn§ï«¾è÷ºœ)âˆm0mb˜?<ûØ2…~ò]䱃ãO!áV×#¿ŸPJd0ßt!2~•?#f².d¦Ç–‘xqJröñ‚‰×23hýsþůÛ`µ¦c ;ÆŸŠüÈ¿w l®Ëm(såÿDÅù£Xº@ÆøãýX˜î†u¿0éÑS’ÿþ’3+ÂŒŠO+°i~ã2ß "(YÅ3×ö™Vafø¢"Š›Ë±ùû£ÌE<ÂË}sýŸLg.úãË’ø* ó5 ¹øb ÀñÈßÉÿ§N¨ûÖ~oùÏÁÿo€_o$fq‚/MÈ^œÐðå|,åôóaÞÓø=æ0—µðROwqïÄ„¿ï‰¶è÷u2^`LTÿD×*Ê\~üö| ¾¥dóhÚä'˜|.€«ä~È øcQð'ÀL7`¾n4©Ùß–|ü]|ðsܼñÝP¯?ÊoÇc²>yÍ“'†˜Czèä×nAÌ%S|ôøÓEL5˜ò1¹êˆXFOø+Ñ> ›,0",nÐ&™Šÿ=kø^}/u˜ý™EãÒéîîÐT7Ÿ‰·¸˜2€×@Ù‡¹8á{ye@Ç€¹Ô Ì*‘oO[qÀ0ÒÌØbŠâf%ã_xн&<¨4¦šXÙ@§PD:‘ý‡þSþù(Ó¶${oæ¸áª?øVqOXlNý^ý}nh×€o᫼ÌW¾,¢Ð×…'b EeJðÏ ÅSUœ™?€&–͘Ï&HcØ,‹,d‚/þ^ óyñ?å_L¢yx1—×°‘ÙÒ¿-uOðÇßâ£àÈÉ´IþQÌOȤ[‘QŒ?¬F™Oû‘oo7 Ì\|âMß©Åÿ|ÀÄ[ ßß@hÌw1°Cñ×' ƒ€³?¾àÎLa€¹sò³ÜÇñ¸yá?º¡žÌgü½æSJlóÿ”w¥ÍmGôÏ©t9ÎYŽÇR•]‰e‰'‚$°ÇÌì€" I;þ Š-;V'¶£;þqé÷zfw¡ˆvlQ•- e­AìbwfÓ=¯ûuÏp”’s—¯¥ŒcâÄÆsqñÞ^Ÿùÿ6—}±W+ŒïY6â-øË^ÐÏ U õÁ xü¹XéÁêQNoÉb’Ÿ¸;Wÿ‚X°z ¡:ìúØ®•ÊÕ½¥àD.]G[äeA†U¼Œè0Ÿõm[[3>R÷»à‡ï C%òµ0&I~î‘U"¸v!êï•À ªl‰ ú[rë›ÎØÿfh>y³=òŒáx÷³–øu;ôó»„~´¶ï¶à€3ù½;§Éÿß°ît.{ù»¦üá¸_ w”àN[7x<Š!Fºã•Y—0ÕK’ã.|—ÚHƹò¿_੨ âðk”¿7ìÎèÚù‡ŒŠXì»ÿ˜á|¦ºÈºHìò~©õàÿFȺp±®…ÄÐ:Ý9Ù@xMæ»^-²»­iÉ}ý˜ýÎè— X(~éÊ_÷A” tÆôÉÿOéÅäOÜ[rC2m’-ÜÎÕ˯WÇK³Âã0u}fž —‡åiæ5$§Øµë³»Þ)8Ïþj¸ƒ× ¬˜;Ó îÙæ;vC°~K¿ÿ|­ OŒƒîªÝšKqxJñ¹qDNîÈ`™%¬v2•¾ ÌWºJ]%ýO5±ÈÝ<æ°JÿWw=<­ÜÓ+û•ßzy·ô»ô4ƒÄÕa@®®’âÜÃð=ƒbÛÀÁ‰œL¤úTvïÒyôê®;ÿ÷.¨ѯb3ÙŠ®ËMlÓR„“–<)‡ezºü¿ØÆÁnÃ{[AÂêCŒ¬ô?Dîy"Y:,šê½ÿÚ¿<Í«GÈáÚB‹äÿÉDz/*ÿCòëvõSF:§’.ïŽRfÔ¸s§Êÿ SY´`ã¦üAN3 ‹¹sAþO<ëŸÙ ŠüÁA€„«m:³oœ(ñ°]ò?¹Kg¾ÖaC¡0ÐxoìüþÇ2JÝ)CH¯ðÑ}5ÈàPFý[dËÝsçÒÁD½þfsâó•îCȨÍIœ¥E’Åeœ/þÿ-³qm2ºgÖ–—àÏê•Fé ó¹«p3ÙxeïêÊ“<À}µÜž-¬X>QªµMµˆzSòÿE§ÈT[ÝÉõß“Z¸†@0Ü^~˜Üø(S‚,jeÙýmY#¾ð¯q bYÚ—›ïó³¹Xd¥b ]Wf²(ÒG¹òðÆóþ_bå° _ÞîÙ{»îƒ;Fш’†“¼¿%€e죔 ôÁä€C²»b:/=´6ü–*åŒV²x쑨Ér™YLɈ  lþá¡f©Å!ø½t0æÁØ—I‡fÿ‹-i«œã…h.’{L¿Äó<‘ûef˜eyT¦ÑˆDðSå"žiªøÿB pޖ޽¬Öó+»¼—›^Ã@Ô}¯Ý6Õ.ùµ“½òìH’u]š[M•uH 7~üá©ò?²ô?§E¦óhaoNþa,ÂrÆËŸ(9 “G…4^úz9ãw´c–³î{çÿÿCþFNÍ`îó…}â×tÑ8³pX˜XÉàåšN™Úß®¾ó¿eþÿv™Ê6­F^Ò+aM?£u§Bæž3«Çòë¾xçOhM?-ÕW(ÅÏ£™¬tžÁE%6|à&ΛøÎÖ¸*&”úl@.nËDJ®V'‹×§ž“ž·ŸÕHOõƒSRE€Y¬ãÆ %-²à•¬! Ÿ`òþƱ!¼–2‹‡y…Eco[š.LãVöçŒ ²Á¿ùÅSéŸÇtÔÅv¨ŠA’4UIª\F#+mG™Æ™wBŸ $Ùª/ÞîÄý=mq"§puf~Ù…h#vÑÔÞ®¿Ozõˬ3õãŸÙ¡ Y£Ô¬Ì\‡)þ.Ñ& )#1nL b,0§Ê‚þõ½òÿä“€Z\em†«Ô¹¢lýÌ ì$؇î$0ïj¸7‡ý¼lDþþs¹uòðÆÈ?”ê³ë¥ÖÅÈ­ç¨Ã|Åkû2hO“¿t<¿»§¸Ð%Wï6åOW¿eŸ—?n†(qš†G‹üµTibêÀKœ¦Þ´Hþ_Ù€ôî'¬ hØP­/RHDþ£à#§ë!c‘>fú[­žóá1ëõQP ,”6ÔÿLd‚8Ç @’1úgy.™ÔG×MrñÕŸÿíâÿµÎà¶®AgýbÈ“Ä~àŸ”¬§»™–ÄüçŽ>>SõÇ/NsVµJ÷cy?ÓÙά[w2ú­÷7zÌO^ ^MàwäZ±EÖR÷7ö~^+ˆ —Íù¿ôï…ÑÞœg²â¼úîìù9Çq÷Àz=µ~+|¯öhJ¼Y¨¿¶ö‰ ‡œ5B˜^T9†%GɆp¢Á¡§ެôŸõ\ •ýÌìõÛÚPÖlɂ㽌ð|MlIW •ȼ=¢0vãç¯úüÑ}mÎöÕ.øÏ×™¬Zدð2>&ïÓ•5&­Ž™Ù…w"Úó‚\}µò‰R£9E€ p‡Q§,#Y×lkRŸ/ ì‹®rÑêÿ+¯€ÁO×¹áeæ~}Ý€ÏÀeþwö×F#¯>*¤/ëª_Þ¼õŒóØ8_5³Ìôžlâ»~­ FO/\³Ÿ~lhô• Ücu5‚Ò.Ùˆ¸C¹ vá(Ð h´Rg.>¤G¯á(½X+ÑYóÖ=ÜR0m@1öÃÕäi‘…<®Zæ;h6ÇZ–‰}¶›|Esú¿`lÿ€‰œøZi†ñÈ&ãTôÉ䎙Ý•?(ÿoËPùu®êËüÐKKؼˆR}é¶C ìgmãJàÜÆo¾²ò¬Úêš›=L÷[÷\N[|šüÉoCkµÀ–ôu­)“õ',ŠCbåºð©íRþ¤¨ ·Ppx6%.¹vÉÿ»8­žš4Š#8u«cÑ¢ò×¥Ã#)/ç;¶,lÛ@ÔW¿@’ #È_ ûÆ–¯†à•€˜›Œ¬Qd($+€…w^ñùÿRŒÊO|µm·²Qgø2•ŠñnýάÄr75¬‘qkr–§® L, €è’_0Ý•×hÑhc:ܘ¢dw Ð$[^ke ¢ºO8“,»ë×ûUñ…Ь†Þ ²Ò¦Ë‡Ùœ.²Á§È7èUdðÛk†—ûÛþ¶µR¥‘ÝÏ€ÞÙË( ÕÍÉÍ?ä]¢ùBÊF0ÑzkMwÊ}rZ²xB­OG5}½úSvpc:'+3ô² î#¢ëm+)Ù¢Œ,kÔ4§ùÍ#*»ÅÛ¢Î;Ó°Ê”¾†A#íV‰˜&žo'õ Ÿ;Y—e‘)뜾Gþþ[ïÊ|ýÙJ\*ÿŠõÝ~ ®÷<LÜõ÷_Yù[çKÂ’ƒ‹&ÃØ?¯Ì|¡šSäïkÔØØª·Ú!¬–D[«|¿T½Õºô†üÑ7¤¯õÊq¦h)ñÖµMþOu3¥¾3¢à—.‰¦àjˆMß(FØWHÌéßh¦?³+“$'Ý%tYª(éOJ¤_ôwXÍÇTbMaÆk*"£C&cèÒ"Îοâó¿=¯¶ZÚ¶¶ë,^©å&dø‰¥NÚèºz»?pó.~ì¼ ßjÕÅýÕ4 ° Cºý(6Vêvôºj,¶Jp~Ú±ð5'×°wÅ~=®‘^Mø¶Š«¼`òs— É©©ß^Ié»(¯K»Vß“ù°pä| ­öûç . Øx .=ºdí#$Œ‡xa bMØmÄ™•v&¤)sLÖÝ¡„ñ•¹¯ÜõwLûÃkàY¯Z‡ƒ]È‚;™¶Èç([ªÞÚ„/.³D«‘;†[ ¤W=Êà/tÕþ!Plb ²Kßœe¨!#³m?,ÿ?דÀk0¯†æ·|©íƒÈ?«„Ò~Í?žÁƒÃÞ»í”ÿ¿Þ<ùéÑ`²¶Çwô–9Z.Œ‘ßÿ`'S{ý|ù#P L7³|È¢ùœü•ógÕ£Mùn¨;ÙLA~|ó„ífD›oµIþ÷ǾôOÖØY€)dNí¬ íÎyn¾ƒ˜>Šøim#YÃÀ››ûÚÉ Ö3Í HDþ™éNÉ‹äÊÁg÷±zPT¢2¶e 4—;ù·uþ·iÿŸöÚÙo™ii×<£?$öÙ¤çv2&ðk1kÀ(Óÿå7”*¯ NIjÔÝ×>T2²F^šu§Eƒúo“gØPš ˆ/ò §Ó‹éô^«r±q~ß0îì«&$Ûó IáFâù~¤ôp_ô# ×p÷·›”f=¬ïYì ª;Ã2#¹³ë  u822€4+É¥A¬L¡|´˜‡4éÂ>=ÜÖW­Èi<ê´,±º32BĬ FoeTµÉÃ]™ÇÃd›*NДgn/ÎFrå@‰Z¢¯,Ð#uA¼º'Ÿ$EdËøé’ÿW[~”MÅù²Õ´HëMÎ|žòÏ›Õ`Ÿ‡ùæ À›7L;å¿ÝØø§Ëÿ1&t ‡Y,l—6’—–®&J§}¾ü«ò4Þ‹†ŒÚ¦üs³¹q´t˜ùG¹Ñèvl’ÆZ ÖQ EìÚ$ÿÃ{>ØO>Ÿ/rKê=tDT(_øÎ>™~©ÈŸdjz„ «´¼»[ù衤ìèLo@Ò=pÝ]_6€Î9שëï $€!ÅÀ—JL6Çg"ÿ–Îÿÿ[ÿ8+VxœÜ½ TßßøŸ")JBH’¥’-Ò¢T¡$JE´ dß×13÷}gƾfYŠˆ‰ì¥¢ÐN‹JD%$•%YÊÿÞ;´<¿çóy¾ŸêyòùŸjÌÜ9÷ÞsÎë¼×sn&À¸)^žaº YëØ?Ý„ÿ’³(s_Ï"–Õ²¡àôÀºðCÆš<ྪÐ|;3Kûjœ1\¥¯*QG'ò4ðx µèòþp‰Ž6˜´®Ç³.Kù节}“eaþí¥É”™µ(MÝ!ý„ý…µ²÷cì}¢·ÕÛÁ•#ü sÖ¿6Ö;ae²½+²l- m§éÿ§üÏo Yyê=4ÃÇmëL ?ðZ[àÇ4¬”ãÞ*QÎźÚ6õ5?8w´³ ßtÔ%Æ­ƒû09¬hé‡äw9ÜyÑó98.v9QüW Èç§«vçÁiäÒ5‡LÇ)ÿ‡ëÚß^ýUþK$êZœ“xnÝoyS¡h"1ÙPTÜ <£íìƒÝ=£x>‰F?·¿æÏÍrº?Uãõâ€ãÌÝ{ e=Ýÿÿ/®‡~οÁí¸ÄQþÎ7ô§€({‚¿­ÅvÓŒ¿ouâRﲵ㋘䫄)á*œ3ެ{` Ïo×ôö²F§^I¾ù?}–³¸6·v}’9¥MóädÓª<¥æûbã*šäÇ[`Ñâ¾¢F±]û¯ÑCµ>Ж£BÛæuzÝ”q¹1- ê…¼Bü=œ¾Ì ØÒ»,u6­¾jäÛ³Öñôš+êáÚ§ÂíìR)‘*g}ŒÌŠ‚_Ì•ñé4_k ñ[øSùŸÿ§ зb5®M,É%òO7á£l¬t¹Ù~2º¥°uP³··ŽàæŒæÞýŽ9nox´ ww×\XS4éüÎ>€ë·Þzú plƒ*éɼ°ÕIûþq%Ýwa Ï¡:ñås–Üí–ž¹N]Û‚š^Áã½Ú_D¶Eˆ[ôØË½η»9œUdÐ 6x Ñ×7=•„йe&¥iê0ß0–/KÔTˆ¼šÛ(fb²b:=¿ùE,psì‚åzåç`ÉQ!ùð½r½Ÿ}ÿØ,v89ó”²Q“Î2ï.…EŒåT²mܼæåéé°6'Í"š§yëïï™yjÅ–KA¾;,ï" •%½ýR¬š`Z<+œóÀ\‘e“K]’¯®‘G°FÅw†[W(ð»aSÓÒK Wk7дº ÒRõç{ä@kÍâºwÍ ³ï5Žs xvOÿf˜ÈoÉÛùE}-xšl倊²v‰n­Šwí²æ^Š ¼zŽêwÞÐÙ=d…ˆ—"ä¶Ñ^ž”pì#‚mB½m]»å\B¶§Àïá?>åÿOÛŸoÅ…ð§›ð÷ÅÉ÷—èú»ò×Åé'2(^›’ŸëóÍ] û è“iIÉ*rÁ™soQÐö‰ÝÿXÝgºÎ„$Oå;Ç:»](—z»Ó®0p<X`Â}/­7Úße]À)íc–©rÞ†å »ràœ¤ßñ jo<–ð3‚¥æì·üÖ¥n ŽA?KgÑ®RÅš<ý¨¹wÎèQz£‡÷Yévè¢Ý<é‚„J=Ò~bL+x+#-Õ`Ä2 Žb¡Õ”|Ã7°á~Dýð3Z‘ÝËÊòO§›gIÖR6ž‹eÇws5V}¼bèzÖ4G<÷€ÿûÎÒ~•J$ûÕç¸g¥jÛUOÐ=U½ö>Ö‰ÜVË_ë=ürmnéºð}kî{ØßSsríÒvu„å…¯‘–‹öÖ§µR±`é}¨ñ‰„•;Oœ¹zL:x¿£‹l¦›B¶0»êàäõ[m?v.\1áåË€™oûÃ\¬ÿþâ®î_²kW—yô ƒGk@€ßrô¥dù¾%­Ÿ¡Ap2Ý¡ÙЀÛfÔŸ zòbÎ\uÇN¾:GßX;iã½x–£—¶<`¼«W¢}Ø||.Cw»¶Ï^mñ$£–×’§Ç-³^£ÁC;Ÿþ"·ò=‰ÜŸCjgVs‚ù%C¡õÜpØoª·öÞzÕIfß”º¹,Èåükþ» Ýw¦cøQÞ;)›çqcò×úÿÏÃ~ª…F®Î—È—Çø ܾ½0}úËÛ8ÿýfA–ËcüŸEÍy2æé9ŽøŸ(l“HÈ»µd‹çZQ[]òTØ»jÈ´ðw<-’ÊÊ҅΢‚)ÿpÈj³íÜ¡fÜÝb0ýÄÔõ›Cû¹XéTø‘M¼¢ÜÓ‡Y_×/2_ÔÝi I5°Í90ë­zf事»¸„ûVèñùôLp¶Ê}$å5™%ÉlÊšÕ9zÕC¯ Ð’ác-SLÍg/×K[u°Ðç7ñ§ò?N bó§›ð?ë(ÚŸnÂo.˜Ã€ÌŠZˆ‡ ©xHv¤ÀˆUÜáðÀEiõˇ0Wò|~Ü«„YÜ{ìµÌÚNê¹OY»ž†TµçÛ°ÿÙv¿0á!€ü××’ š廽×VlšlÒÝzX_²¨2j?ß6äˆZ€/õ0]ßWî†süêªk ‹òÄ4QGRΟÞXÝOã§­[F{?‹û- “k=Ó.}ÈxYZ¤xÞd.©þ¹»®áKЉ¢Dμ,ÖVbªüÒ R¢¸µóºò룘‹õã_ÁÜçômÚ½Œ›²®÷ØØgoÙY›ôë cc–Íü£DûToÇ}32xç€W—\#ͳ¤÷îÁøÀˆƒë.«ÄÌçjT{Ép[_é§Ÿ{Ó“Õ¼'b7€éê)jSXû5½¯‚¬{ š:Ëy(¥¬Eæ|Üï€;cж2úšÞ+@〙œhê­ôHlX‘O üÔU–0ç6 ¬Ý$Ž'Çaßõ¶‰àp}ƒÇgÖÒ&pŽlÑ”bo k+­5!ËRNÒ os›Ë4§þ}gúž E–§µ„ûÑž6‰ °²Sb*OÁ'6ÈÛ¹&¬fô®ªƒ¦×3Gî­ÛwfßäÉŠØÃŒšýj'T%Îøµ÷­ú ´Ëª®´Mêáo59PGEóiþ ÿ”µ$î>@‘¾g޵vÊ1—-ÊÄœ«BÍÃa¨cøÄÀ}VîÕI¢$ÿÊ©yŽ®&BòÆëù¤tú–Ây!¶µNmsí ‹ø ÏKÝÞø:÷B¿îæøå_ëLÙ·’´ˆG÷—ø?”ÆÆÿ“=€ûË€\H}[ I’œ@©>jæ!Ý»ø3:EôÂ×ü5R•ËîHAö˾CÂb ¶&ÿIu£æüLU»¤KÉùøöØ]$BduÁßpǽ6÷`Œ?íÒíåã‹ÿ„— ¼Tz×™62—Ê ×m‡mMR'–%là^-ÈáP“$‹4zR¾ÜïZô%nƒó U!gÕú yL›ä OâmO÷Àý‚¾-Ê FLàp¨lÇ&dFrÝsÑ(®&p—(8EOÞõ2œßÓÜPŠ¥›WA~Õ©Gn•aŽgt}¸ßG±É®:Ä#l`¸®|“¿‡ÿ8•ÿqRìCº ÿs¡ÚŽ'埕À†gºÕz—£Aû̧ƒÒèŽù¢•Ò0/$BSÄÔ½aNXEÙW™|i§v…•yÜE-UŒGhp¡óLñoba5ªîíð~hL6„Ö÷Gâ¼àz—($òæ¿hob é+²¤ŒxU_f¼[µfG%HíÐU‚sOëdg^¸ò%;[ëÜ@·«ñÓ:öxÏÜ]pÊÏ"úvÆòÁÁ'jäü}Pó6-½nþ6õIlæ 4ÒÇLvÔ¡­œ(§œïZódMû`Ù rvëì¸UR€,»!ôhŸÎ}ôÄÆ7û6‡Y'˜2¤óV><Öiøh«¡Cû”ÊYF¨y¦!eW‰sè!Ñä‹)j±,·„y“}éQ”=•%©Ã›õr]õÚ£¯sÚAgG¬´°F©îé½î«#@½©(Ôz,;‰*Í ëEÓïT-½«%+$J.YÂÝ”åü9câHcÍœiR瑚R¾=n¤˜[ _ x¤¡¾Ïó(çÌÍ2\wƒkt6TQïL‚c“h§NƒtV6@Xß3kù€;¡0éy†½ãó*‹îow\£ÍOf]âc·¢[ççÄÚ+oJ^¹¾ÿ\ô·'?¼÷q¥ô‹¨ønKÁ‘7¶íR4àɽ¸O@bã[qŽM4¥®rÅÂÑ/ÿ”¿ÇàÅmPg¥z c °Ý#Óe–½ê9G¶<öÚ('X\}ø“¤ä@ßÜþЋ;¾;ß,¤ò¤v ¯–4’ÏDPVŸ×à)¾v!´žd³žŒÄ[Î_þ¨ðÇD¸g¥q8v°ÿWø¯¾Œ «6ÿf#G…—7OKo1ð¸Ä 9ƒ—ÉÅûÖ==P°€D;aœ9Qæ¯ù °AÆ”éBÔ.h&%ø1ÀKüþ¼éš“>kÑ”„GùW®1)°¦Ã Á¿]\QƒMã_Ȧ™c<ñŸÖCs¬ñСå:Î] à!YbRMét2˜öÚfÚæ¨èX¿jÖU{Gs}"壼~¢øbe”m÷ŽMtÄðŽ©'<~VÃÛvÃ,[nLÌ]øD3þ(M?¨hs äO.?e$Y¾³Ý$)® Õ }bû0†—e¤L.êPü—[V©1;¤ÚH Yâ•ÑêU_ÝÿÈö7ñòÿGÏw…ìôïX^÷ô ÿésÝ‚~cC~S±à&—`Îéâú‰ ‡êW-*>{€[hê>ץϜòªfõÆ$sÏuÕ~5àpXî‹Ì:í¢;B=¾oW’Ã$A€þËÑ碫œÒ@=óp"¥¶ôÌÕéG®)?Î(Ó&^ª:‹PÊ´>D–?ÔæK c j…ÎËìýô¶T$Ùù†Ášìr‹î6˜´ß@›Z”VÞÆŠïéµ6<™m{çî+ Ÿ%ÏÆC \O3b”Ò'èÈÄ_òwù(b;7-z{ÚyЙÌwDñ–°Û{¸ûìL¾ÌýÃ<·`Òò»¢Ð|½þ”Áöwõˆ`³¿ß¡û µ©KcW>ÛV"gýtzwÈYƒÆ¹¹®º;³½¶Ù_UÁ)É]¢]3_p·êÙÛ\qî+Æú¿é€dµøB­pG¬ÿýe,Ë—é{¡É#³© «NCuòƒ«Iš"Ç+ÓtxØhìâÑÕ.ª§¹Yh|Ý… 7' !²Së.¡h@¦ZíZâ«rü½bø£³ÐڽΎ{Ÿ¯(D©âyˆSÐÔ“÷ÀTãb"P/‹ ìáõ>‹B¨››cHdž¤»>ŸzÀ5#v†££Ñ–¹zGŧ÷Ÿ‘ʶDøvòOú¬KVl*{çà «“YÙé~ªÎþÞ:Ea h¿ugKT¸^ÚÕˆ/<“½ÿ)ÿÀÃ[àTBÛ'£®‘H›ú#'§¢ ?kn*Å)«K\“Úzîcè•òKÙZוCóáÐZõÙNÞÍ Ö]„Ù} F`ðÌí€/5 åŸËýN³&˜zM€®Ô±ÏfÖ´ñÌÿL!㈡`Y·Ë*ÚƒlátêøâÀî䓃FŽt7 еZ‚ Á¢B!\²{QXÖ³ …#ZgÌ2Æ5GŽ~ZÊ[Þ̰[ÃŽ÷ ~žT¶ÿô }Ö;yÇçG¯S fõ»ÒÚÛ…6¥´Ë8‚]Ókõý ÿîÇ]µÛ¢êªvCqÎÑôÑü©ô‰!ìƒZww‡FñŸG ¾+)Ðÿ]¦.×1þj·/:þ/Ôà©Æ#ržq M×{ò'é(û©òƒÛ‡¤tèÁú7êa°™šO»çËsrÃÑ#¥}൞6H›U…®Z©åDóºoxOlßz•ª«kCY9¢Âsë,Â02fÑ‚o©Ëî*R½&ÌÈÛ€ž}9ÁÝb§äž…¹S?ú]îõ«aúÅã°V@ÛTùz¨¯-WωÔ[•3-܂ț’Lÿq(ÿ5Ú1‹‡÷ÿÁî¸ßU¬bÐ?Ý„ßVd<ËÅjó'ÑùÛ ýì÷'^ò­žÆíóÎîò{ï;nÊ–ÃÚ4–Ï´\ÞâåŽØq]t´^Ücdý•ÈCôëjAKôψ ›çékÞÃÆi 6»ÜŽ_^§C$â(m½1‡éXÙ·éI¹ž“ò}Ÿ<ˆÜµþŽOÝ:{°e]I9A®¶Ì¡~òäô½°˜WkžË=à¤i-vj œb)eÍ}ÈÝÈmë x­¿Ö?ȵ“åòj6O%4?M ÜzwÚc$vÝS’íÌwÜ<ê'ç~³d}•§cã‚vM úƒŸX+¸UĆAä„g¬Ãú/7û;›í Ÿ;µäû«l£§‹¶~œzöó?;Ý?å‚rtIÓµÂc+d±Mò˜ÞÓè"x•/ÞØˆoΊP¾B>˜Æÿzd09dìØo{ l6¯[½ÍwWë?“ñ®¸ù9îAàãÒË.·daE „›/yîpåÎ|˜ua‚€ˆñâ©Ü÷ýW²Å‰ƒ»ØžÀ›K4ª–»î€Û•×O\·SìY×k‚áØ¾¦>üô=¹†._Ý2›u/)Öï<]:·Œu£Xþò^ƒÚ°c ÛTÃý·h¼RêaXºñ히´Ë °¼rÞYÊ_P˜”9mÓÏðÙì“·Æãu™á¤(ØÇSõqRI Š¡AÏb•MRZ¶N­þwjÃÐ,3WðtîËm‚Èêì7¡T6“®+0»Â? Ú|ù³j…<´5¢nð!òN‹UÑd\ó—ÌäåH’fѽRÒÀÇ®¼Ÿæ€ÍÿKI¹Kî, V¼¹+æåÓm‹6–Wô­’ï"üIï$˜·&q¹ü5Õ#'Ð k rÌÞkLõÎL¹›‡üÈÿµÇ½×÷ ^´‹©FùÏ©«‘õð¦èÎ_\q¼ð÷&éXÞ§“B&_Í!ߢIžXù â ä_k:aQ¡VlÔ.Ø\w6PsvÉk8¯‚„Ím.–\ö¢³v2IÔ%\l«ã¦ïõ`¿H’‹RwïÀüÏÎmB’õÇW„Ã÷Ÿ¶~ÊíÑ‹%éÆö Í‚Í{×d·ìe—ÛÌ2bdYhzbãå¹  Å²0ü޼™EZ ÕM  çòïâ?þä?éO fßÏþý×B±ÿÉ´‰§ÿïmÈo(ÂóߨLÿhaйᔥ’е“°fÕn9Œ,ÅUžÎŒ‚ j{E°ˆ=;ËÕzÊ»}ýò$õRx±!X¤ô›—„^HŠ„©Wf‰¢”gcÍ0u÷bg¸¡ÉXRD_wIÓsÕª-ž¬#ô³ÛDg«,û,”Îj79ÊÖYÔA¨évÿeX´Ž¸*›nNÜ~Æ2|ÝïöfÁÛ U˜ ”š¬ŽÁÓeWhÜÑ Ì™õIS¡m虊ÜC_Ù'tX›í˜ì t3~ÿ„…Ýï2Ðdº®ÕfÊõÅ-äáÓÚ¶ô«,jsœ÷(.W”ÄŸ ׿ÂG½Ö:Ô`P1Ü%>í5Ì\C»|nkQ‰µ˜£w®¯ÚYÕBŽAn ÙÒ÷Ü“VœW׺¬ë{ Â&‰ÁÄŒ[tàaÒ™ƒ=óîÍ)Ñ„Í5A<.;òžûÝH¼ò¨dèЕTP¬³fï?»yÃö÷¤†^)†SßÜ7ÑÞ]\6.gvÇ_=áH}­tˆÕm&B¥ˆ¦M°5»Ø$ä ¥r1È+E¶Ww´[¼·é$_x%5Ï[D¾¹ýôÖ·ê˜Bئ)#UÕ-l”Y1'2téÆH£Ik”øo-ŒBžŠÉƒíõcb<ÜKÖ¨O–‰³”ú¯¶ X`q\ÕI-͟㿲Äc×õÃVÕ§‘ZÉ jH6ïÉ8 ìÝ$¢Ì€9Öö\à×ý¦}Có^Îö[42¯âʼmze·ÐBMl 6 öă÷ÆS@G¸yŽoþwx-“¿·fw;€×ûêF¾’Ÿåïý‰±%=Û=i Ǫ], ž§&€M4_ÙДœ¼yClµf:×+ò]ïþkþ x £A‚­ Bñ¶T ÅØnùÏáR ”ð D½ÅŽñßëL×§ÿ-TŽKÅ0Žø7Ü¿ KصÁÝ×(Þ°úåD‡ýþ6ºfÐ~:o`‹‘(È¥®¤†Ì­¿±lÑíÀ6Kƒ ùÎ=v¹iþý=[áñ÷u°4Buœ†j¯§sUg µš½šoîy  Pþ^œAºñÀoã?þäÿOÛ¢üâ£uÿ÷Åü/ÊWü]±‹„ÇÚj"Ý­Ùw÷ì¨=¶‰½d÷C=˜"q\ÀѵëfaR¢iؤ9K£€\ú¬¤DóÚáÝö>ÎÖ`™èPd8ù^ÜúûÈtöÿ¸Ñym,DÆ/> Tý¨¸ë,âwº¬|R©0ÈNI{ÊìÕ ^2·èŒ›Cù'·–xï\Õ¾­ÝJï-VÝ{ÆíSwü‹ß>V.M„Ò[öÕ¡Èu™€ &ße)a»u<Š>4ûœPagÏÙrÕ°·î¦ÎïèîXuG!zjØ5w™À§”Á¾„ *Í “¼ø6!·D§Ìòlÿ´¤Ï"€Ü²ñ´<¤q)†À³ìM¦ˆeŽÕÔ.ûy?×[ËÚ²Ëùl£1|Ìï^\ä^¿0†oçäaõ ™~3&åØ)Õf8’Z­Þ”8 E?…w^Ò_øÜË%O·Ž¶àRÂZið›tQXL‘r›n!Éf6íàÁ¢î~“þ Ï›±ß>¯Ù"Cžö¼ûšÑQ3‘¬Ò4¸Ç–Õúªû®ïjÙVôJísk ½-¥Í?u¯ïKÊS½yb>ô¾ÐÞ¨zðQ:1)ÿËÖŸä_’ä~¼ƒœ7ä$L׸UjÞYºïÙ‘ŽåHºÁîøXŸäï˜)‘‡‚þ¡ çû‹ó§ö¾ôPY#Í_ÂvꆲO|‹àŒ{–«Ç9ÏÌÈ#ÂùM£Wß÷fï5¨h”ùIþ=XðpƒPÁþ<†¸ÜjøÅà”H2©&»5›ÌО# §Ó9)évv'þ†?hä‰̘énm§¨êÇ ºÊPûþåÁÄx–¤ë³le Nu“.J_x{ŠiwÎ6ç©rеŸ×«mó¼ÌÒ —¬~òf7 }±á­“¸mèûb»)­†uÑJÜ/*¦««8o(ÓoÒs ´/+=¿&Ý’þÛø;ù7ûÓ/ÿÆmõv¡>?q2nVl£ˆC/ï_^gôy€ FÇŽ,‚öá„tcõ½ÚVªÍ§Y-ÀœÿØ+€7—>ç.2âR“+<— V;®Ü›û6;érœv:_=PÒ>l­­†’m³aêqŸ<º~­ëLõÁùÜ÷üTV.ìXÏeÈUÛmû#œç~hi;ïúV ÛÒÜŸG€Ë‹¹!°(*ôh:Ù<#W³¶m]v|…rëcßÅ' ¬`£âdÚNµÉæÀòyG±W KX ×Xï†ZqL!C1y“cÛˆM’¿3Y,œŸÖÁ‹)ÑZÅ¡ “k½M1±.š÷ö²n=¨vV”m¿â¡fåY¼q­Rµî†E+ÊõçðÌdÑè-…ÖzïM“·)ÉÛx›ƒœ[µü€ÍÐÇ©‰*Xÿ=“”/º²XkHCn¤U±DGæé4øwæ€hHÀªZ¾^+vîÕ^—å±þ'Þì›hi¶¬=Ä¥2Ÿß$Ù €òáêH²ÂVÑ֠π.¾`+ÕëÐ9ÛmÛ…í§}ß-ò^Þ³ ¬7Þ•ãË\lÃW-;ånÉ{ѬLO3êÓ•«Ã“e ´ÍâÚ@瘆‚ÇàÕ›å3‹w †É76 p/|ìJN ö°YŸ5i{pÞå«¡bÝ},½Ü¼mîªÂUþ?Ï_*?Ž ŠÕ‹DÜBz'øNZîÓªò_à²ÖØg>W=8(§¶ª= †¢GvÅÃgißm€ Fô…Ð*s^Jx, óΫŽõ¯w–WrçN¯Ð,¥¨Àì·ä¦ù‘í¬WÖi¨Rè,3[Œžêèæê®yÂÃAMüÒË£”?ß—YþR¶¨WkÏ­ßÆ¼Éÿ´@ߊmø¿àÙ¿ÿ§üÔ6ïŸñ~¦ü‡žÆŽÂZVN·ò…ŸD>cbo.: PgQ›±×îµZ®eZÌ?ÜYS“Cì´h=Y—Dß—yT¡LZ‘œÎU¬7<¯5äÞ¾l7;õÅ«ÀA%p^³m3ñé“ZAHæÀòë’L«M}jg*òU,Ñ—áº'|´³Œ´¤umTÉæõ°. ¹ÍxäÞì(Øþfþ—i¯ø«4½ÞO_vߎ•ƒ颠Rðՙ윒nÉ+"“Ñ$ÔÚ 9àÆÖ =ÝíÒáa¥V*®ùÇ”£`›ÐƒK `Psµj­_„FBŠŒ8û£ÌâÇÅ+ùHÉïwc…&ÿËåÙ&ó¸-»Ñ3»cÅBã«9Aä2UÌÏzût=¨ˆX7ß³]Ïä쀔¹1%œœ¿$Ù²//zýÛ_àŸ¯J ŒÚæžYï²½»‹Ž¿>ý%I¢GÄì1xŠÌ0Æj?õ) I¯i.Ukç°<¹Îæwóà ™Þ¬‡Ù«¶%]‰x7¼×¸e¼óW¶ #ï™? @:ië9¯íôÄwé‚?ÅŸ*X‚’«æ>_q¿á}K ‹46¶0T MÅNvðqùÌ«¶éÃ? æf¿’ oÐ)›V5*‹YeÚå~à¿iÎ<€ú¥Ç¶ƒ+ïô1þ—ŠÀ=_:žà7ìß×7>øwìTÕô,nL YU¼ûõ òÅ¥A1®—üÎϲú´m À¹þz¸ÛÔnyèKÑyIÑjÞ¹‚°¤ã j|*u+NþåÐu°opú‘ŒMf—X˜î¹ähÁV1Q¦Mpkž'ÔgO?è|[ѪœsöÖr]÷W3b†GjÔ=LbåBïÁÓ= .]½'yÒÁÍ[vתdÚí>iŸdex>2å åÁèk‰pAö÷ñgò/ð¿l†þ“BrøÓMø©BvŒúÓMøå÷†.Fâxy"w^m¹•º°xbõ]9úT n·êʰzº]÷߃Í6)ynC`:íÀ8«ÏP{n\–¸PtÄA´R·g-= vUÍ¢ai¢×R¶'ÛjW{6Ìó˜²Ý ›ù2,äMfÀ<µÜ.0:›§ð@4h‹ú;h]óÂЂòÔNŸY™äL€£o?BÒÁ@K·‹¶ŸN²† îð“Ðþ¤ >^³èb{25Ý&~äA"ŠÜ|_ù(õã²ÃÈö-÷ ãÃò'×uÁg]iÍò½’ŸáÅîû÷Ó}Vš(\[²ÂV‰=?OS½äá’Q*Onuiï™%Òxûd&Ý=­wîÎÂ[Ûå) ƒ7ÚÖèöÙD³ˆÄé‡C¸¹vÅþ¸óü¦éîÃê¥Ïœwí>½`KÝÑÄw…»…Š}N¥iB¬]žsmL Ì€ ßåàuÖ`«<—@L}ØD´>k£(l6>õÜVwù'È)—¦÷ÜéCªNw#í&ˆh†ß²[Õ"$d8½{þAnß©G² ,´¹•DŸ…ÛèTߨ‹xq5§ùAí8ÈÎ*nUw8ØUqƒ…$T`œžt†CŽbf’¯+K¡ù³f#PJüTw]Ziô`Fq2â«.Vyãhk¦bÇaËÂ_áO3åäà|ç¦=+þÂ}8nßОE§m)ô À]9<·F*K½Û5Ÿzó7ñƒ¹j3õD~h­-¹ÖÚ·°Ëš5êi«}ÿü=›8×T™<½8mÓ‘ÄkæG)ñê˜þ 1˜Ã®žú˜óøº°ôÙÆo“Žq”|֖攼¥-ÛÔ˜&ßõP®•úþáJyÚ霃¬øÞô¯O’‚¥·~äÉ<’{*ÊÓ%=2ÆÿåÌ 'øœà¨Dü9ÚÂ4œKCà¦QgM߇ÅÎ×5Yè¹sžlÕ°é’’~)Øxo«‚’§¾’]áÌœøôò'ËbdPj¸hí@9éG?h^ C¨Xû5C˜Ò† >¯øÁiÕÈŒ²@›)\}Ã=n áö=Á¡´MêÏm2”´^)½±Î1²³þîÑ}ö¬›wÚÍš¤”Üoä'uI ë¿IZêV¿ßÇœÉʳ<ßÊ¿w?½ í?ÒO¡ÿo4ä§Ë½GN¯Á¢!WãVÇÞÏ@ýšÜe?¸ñ¢P¯Î\º4Á'mÈæi§v-@ajA‘/ØV,|t&{ëaÒ#ù™Gïɹ à±ÃÉ…p(ÝD/ôSiÀü¤R°zé'Îùi2Þqú[”æ°?¿lÓa3fI.à”Öî:ÝxÑ{ O¶ñÈ#ù>Îì6¼þ[·,“ü<õ}{F€§º‚Yâä³^—\jdûÐí×P¬åֺ߳g¦D‹÷ Êr@ªÅÃÜùcl X–þˆy–ñí­žê&ƒèB-Ç%)½0|`vš%Á(lÙé9º¢>ݺí¡kއü½…vÃS?ÚL†=ÑzÅ>;í1ª5I ¶³Ê…²™ýÒoe8ÀìÖeî7|9 ®xU˜=ã¾ì#§žÊÉ­WƒÁí–lžáü—“'ò=läÐ}ñÌ >/49˜0’ ðE,šôE>6Hæ<,š´è4x»ªÖø‹×§«Ò)>;Báö:Æý@0žÉãBšb\_î:@¶õuøðuîªÃ ׆²8P^#7㹫'Èäiš¿R*LÜãŠÚwÓŒÿ8¹2g†ãR¯Å‹!Í[ý’ÞÊ¡¼äñ|•³½3tÄú9Áx`º¯jvß‹+A”$ÃhãôŠ¢I`i18-.ë„{hœpÑsÁÒ_ãÏšp‡$0u¤ ¯–]ît‹5éàå~—ƒfdp±ÏvÏ6þ8gÊ]ih`;[el»£oÇ©ÃÉë\öO- ¾Máx(zíá¿€¿“‹}p@€ÿ{[KÁ†{ý€T£Ø.£ôø'øÇ‡‚6§4À›Gö ,¤{~î`‡¼±àÙô¡r9¤¥,¦wàÌPÇßð÷s9Ü;9"Øž?J9 ÒrÍ•®—&ýÈߪvuàÌê[ï[ü¼ãÆøCèž" ?^Bð‡6«ñÀ9\ñÏ°Õ µlÛ´=âÕ´†WµÙÑ;e5Ã]JßEJ%D–víEAy†¢v‹¼ú¼7ÙÞº1þ°åò=?Zð8š€ºIàÒNëäA@b«ëËɵEœðdË&ÖiÞúññ#í‚RhµÉ‚ြÌýW'» µöLå§©8gê¿¢”/á™já´Ž5ÁÁ+; ¿v°Noùj¬NLÈoä?¾ä¿åO 7jÈŸnÂÏ›ˆjÏÇ—0«&Ü6œ U†Œ/îëv{åQ °}ÇΉÞZt‹·ýÛ ̽åìRÚá•"p rÕQÙš=nÓ¤Ï,ÏUkô°+וž›ö‚-é#"‹b 2ÑX'Ë‹ÝÍóÃl°\%)ZóÍ• )kØ»WG”ÏxÂ9•¾L-ºöÆl¯ÆüÔ %àÜÔ› SæÌ/¥:å+ÙÑ’þüÍŠ¾‡;*¢Å"n)+]Ö”nat+ÁÚ9È~Tsþú*#É:©çTóª3ódFîƒljn›Àê¥Ðgœô¹-~Cœ–ýB`cí䧮ȃHt½ÊCrIkZû‹jÍ¡gçä=œRê¼=}àiÊü\wï´zo([\~À ÌÁË/ê¶Õ²ã—¥¼}J•ƒfÞ@CN¼üÖ€ç[‹çmù¼Nßš|GǯÅLÖ·ŒH1»­²nNvs…‰„\aGM ÂáÚ#y—¡¡Îa¢ÍŽÐ¨ZqQ#ãe8¬\žønO¬>Tjà84Ô(¨_0ÝïÍëì+^W§*Ñ€£•ùén5§§?äžÛ¼põ,ýSÔìk2íÎÀe=ˆó™ v’*•oCžŸ“]f)”—k;§tkëJ“ÜUQ oz7Åšz}z6€ŠÁÑøü¡#“~•ÿÝþá41õ„yÊÛô¹ û!óôôSï4T'¥ÙçÂ'GDèwÏqbüÞ{èb·O¯ÁT´bZ!,nõ™©ÿü_¡ŽPwj&™ÑÃÅñÚVe_ÿ³CªyŠË?ýcþ‘—¤{¦h©~h¢ŠccÍ£Þ¡¾Çy7°¬:Ï:›Ó*­bá¦XĉÝb©eÃ?Ý?`âˆË ’æ—‰G”DƒËa Ùüá¦HÌž;í.Ÿ&vD}åã¥r@k ÁŸzt<ðWº^d–«ÄÖ=Æ Š-+Í_1Ÿ>͵§²þEÆŠÁ×.å‡ Ž^¸w-æÉ"*¸m?¶þ7†J!gð!èò\{¼îŠwË\_·k‘2Š'æ,xr¥1ç·ðMß6 –l‰ùr3:7Ü0JÖëÛ@}Aô‰jÛîe,K'=JP½xUâþ—*Xøø1#¶º²*°¯ZÎß¡™óûø/ùwüÃöç_ÿ«uÿåÍ·‹È>pçÄðΙu$.ì!µ)iw¢Ð·$U=x]çuV^¹gp«ÏÂB{¾'þm7‹a¨¥y=Ô‘–J>A·³¯)ÿܬLͼ-j_ÄÖ¥\8t"%zd²6H§æ•¾ŒMó_6D гë [üÊ(ÀÄ%‘º®"ïð#\®Ž@±üŠò%øEš×ºB×ÂÉ2³&öP{/ô8óÏç¿ ÀR•eóÖ¼ž¹_ ò“ngg»ÙcG'©V˜ñH¤ÿž’}k_\ ^¤·åuXó|ôÚ“¼å­ ÷Aï.=ë@”®TÔ ~ྡgøΧ)!ƒfó:¥vÞÛ–§M"ïTîeÍ÷a{­§ qwxcC¶!ëNÜÒ¼¥Ubß?›^4ïb½tœ¥Ø9ô”æni%0ëhzäöA­ùûËðü˜I»`×É8åOÓíÃ=ßqíÏ´Ž¨ž)êX0ìnîOƒ ÒW&m©3ÕY–6¥ašË_ýøó÷~ow(-L¿ràƒU;äy°Îwá6Ó:~¹l¿‘ÿ¸’ÿñó ñ» 0žÛöK…BC* û t*Õ)È¡aï(4ì ë8ø{À´ŽU* ¥"ðµ…F¡£T Q°Š”޳Žb Û~m ;;BÃ~RñÛa JÇ_˜{硹v14|ç"v)æ BúÑCÄø±3|Æèàý`žˆ½³‹$ŽÛ ±Øaì#óx…^wì…8 À2FOùîÅ3‹}‹7¥10Xÿ)Âozè32†àaö El£id!†ë5ùÛGïŠàㅽÌ6±Š¡i—’é(™Ž>þTÔ=Pì-2Ñ{fg˜§`ìB£cCŠ7ŠŒ_–ª¯suô®>XË)4o¬Ÿ>ØW$h4*vuÞ‘ÿŒo7ãOüÄÛ†~¥5ú†Ù5ªM$(v‘ø)Ìö~u ɱwƒqÊß-ÀÂüWùãrLÖ„ø`„`’t ãððÁ(Õ*†®þ×üñKâF¡³…J‡øã¤0ÝÝÌå?:hk0>ìžH~ œÎøâãÐðÞ¡¢ÿ¢eØD@è~)„FôÕ ñC©(ãWFlB3°ÛS1‚õµÄš‡i*ü|Èè„…O)Lz¨šÁg03Ï3L7 ¸ÒÀNÅæ?Bh\‰á3™"ªc°fâ©dï L*p‡HLÅÑñ ÀESÒ¸Ð`I#„¢ Ç£€âˆÿê£öáÛ?u C‘±ÉŽXG££¾é"ü”ÂÈ´î 0­ Svö'2¾ªFøz/@Ý‚¾*'Ó{„ÆAµ‹ñÎhœ ÄEÓÞþxã±wƒÌ’®]°€ P¨˜PbŸ0‘%‘ƒpáÇU …¡^0fŸ<ü™â‹x2ïïüÕ Q#µK±ë…A 6¢ˆK>ìxO¨c—k8us1jk«8Ì,ö’˜§4¼EXÈÌϨ],‚5 Wß>NaˆmÝEŸÿœ¿ÿtÌÎŽê}@‰ñG¾á¨*Çøû⇼½ƒF+?Ö_múWÂÄ uó¸åˆæý"ÿRâkŒ¨‡Š¾RãÇœ?æ!c¾±ÖøkþtÌÄQiL‘!ìFmÁXûpÛ(ÚÑó LšaÔÉ«éÿLãÒ©Þ˜(¤c5Pðð#t ¡ 蘊q 'Tàa•ÂÕaˆ›C"Š ˜1¡j]`¶ ‹K¿Þšìñl¨9óÿQšãaB¦ñA³‰¦Ðñh„þ½Eø"xÿ±è¿«zþ¨‰ÃñÈ›y?;ìsXQ/Û(”N£ ˜øÏù§EÂwÑòíõ[hG|r ð}ëæãƒŽÎËÿ2Ößj¾Øî·ü ð#Þ[‘!ÓÚ¢£/©1Ìr`P,ФÐI ¬¢Ùÿ¯ù3ínâ0DÀÌüÀ¿3>x2 ˆšà fEœ?°x|K±ÆSrtÂhþ…XPŠbü‰±Áõî΃@a* Ì*y ²K83BÇ,wŒ"R"Ø)Þ>D^{g’¸C„ùØ™Xìûø Ã.f‡ñ§3S)t2‘Àz‰¹‚?‘dÁF×QXmßÄœÊÿ8)ãÞüÿ£ÿ¬⌠.bWzEž8C‰t?í»à€âj‡….˜¼0£.4”ÈhRñ©Ê4ê47ZOµá¾‘](`Æüx. ‹d¾~æ5À{d…0Ø1оŸçÈ÷š›x!¡ âØ×¯ø•)f\ˆ9׸²e†„L…2«c ÞžÁcÚ‡Ïà5 ý@èþïŠW Jh²ÛvˆÌ`j—Q]ŒI3¤°“Qdt¡ÑF•æÀSíã™IB»R¿õïæ¯}u "úFÇ“žþ(S“PQ̾ѱ?xÃÑH×:A1x/BÑc£Ž·Ý>@»_—¡ ¾¤Ñšåˆ¡{žxâ 6ÿ ÿ¿ï£¿¯:ü‡Üi_ãBª}Ę ÿ>Üû^ñ3¯è­;~ùû0½ªë®_âO»3A°ÅëàF ³3˜Œ¸f΃þš?nα[c7ÁîOAm¢<ûö‚ç¿ñÿÜKcŒ??´Ì¥ª ÆŸìB_üÏ„q+Gü¬‘ Û‡Ýk=:ˆ®3}/·‡xøMT¤¢àG'†3yx^€Â zâcKÁ!:n‹É *±Üx‚ì£oÏ QÍ„CÀ“#tÌsÀØáÉw:±ÒÉ^èïá?N圔…mýW4ò_1Ãÿ"$‡p_bñ‹ŠR¿ËèÉùQì³(ÄuÃX¤Ï ˆ~â5¸SB˜É4Âw¥Q±¹ˆŽ†;£ç—fºÌ`h&V?º°…€U í‡ìkªwÔ8…¡ßåˆ …äJÿ>ĤÍç›òÿnñ—y küÿ›t§û}¯ˆËài<Â!ÿ>”´‹\º1…cjYx\é÷í[<áéOäÿ°(!–i±Ê3ë?ö 4.|S€(3[QE¾ûûÎ>R*žC$3—a]ð ! á‹v£½þÚ· Ž!t<ICÉßÂÆh¦eôƒB,bŠ¡ã ’n ?”ñOùçÑÐÿF}}ý%è«vÇM*ÁÿÇqÌàŽ]{1±¿ü¿þrd¿õ¯ð/$†•>–FÆ¢xb9Ÿ¹ Çît²Í_óÇàÀŒK¿ áü±Î`.Jd‚Gù×&,'6¦˜e£3¯àâëGOü G76PQœ?Œ¯®3—,¨¸§[ëF,ñ)"†°£ßËðT< ï „—D:ž& û%pó –8QlþcðL ‘Ì'3C ò̼Èh’áàoâ?åÿ÷Y’_+ÿËú+íDÆa™:›bžNQtbk •™u"2“c s‡¾ÇE+î8žÑÂÌ6žÖÂ_`(Š«’g2–`º×^Ä2ÓÓ&ü|·ÀLƒºéÁYÿo3—â|þûe`B‘;‡Á÷ _f¤aCÿ.ô¦;[¾~þ&4ø‹U,q'û0ÆWMŤãéÏ\¯½6~. Ú%d±|÷à¼?Be9VbuÁ5@0ã¦wC¡áëÏx‚PÈ”@bD‘ÆäÜ%tô]$|ësz9B—p”¹hÉÌ#R½pS…`o©ä*Ž 6ÓÙ–G]ŒzÛÏæÃŒ41ÝFŒ4®PðÄ<8B5PÈá~ðOùG»÷÷‰sø:Ž^^!_U<ó Œÿu¾mÓûöâ¾}<ó/øê‹Pt~…!a41ëäBd* ãO%ByÀÃyÌ`z”¿æÙB"ŠÅ±~5ìßó'|obAÐ1þ(™FÁ“Á”?ÌZ8†ÓÇlXñD=ar)N£)t2àñ=s>PDïFxN(0SbŸU´s#‘ ш…„>šÿÇ#@ÐÂ.kƒï(ûP_bÛ±¢‚E=·!ö1‘T:†úïâ?弘¤‹ýÿ7µô?)¸ËŠ/ƒ¹yEî>‚ïBGÝ„ðS ÂÜn„$Ó¡£Jƒ™Ñ^øÇ¦1»Š™~ª0©Ñ˜©D SQ‰ê‹ïÌ'R)d¼»„;ƒxyâüG3$ ³6¾A„Ž;ø2<>¢TŒ3•BrŽÀ—O¨Nľf|ë?•Øk€'Lþ&þãPþü²ù-å_eTÿUýоG!¹ù¢DF‘Ê`úªÌE«±Ç€ðE/Ârã©ý®ó~´¯Yÿ1ÅWÖPŠ]$]à¾s«?ñ5Õ†x;J<H¬˜Ñð}ÄgvIÈõù¶ÎK 0ñ –~X¦ÒF¿‰@¿îƒïÉ£*ß&¾Ú øNâ˜ß:ÂüˆÙoæv3¦ª". ßhæ)š/ñ´¦“¬±G£ˆÇ° HŒÑý¿x\@ä?èF™ÌPŠÙÿ(<Ÿ­YðCK`,Gúíþ__è¨]˜™A<üD<ÝCÆÃ’6¬ÞTâé6tTSýÕ] oÇþs±c;AÒ4iÆ(òp[­%R"·¯{P”L½ŽÓ´hE $nRÇuí×™ov÷ŽLmÄ´ši€’ÅãÝíÎíÌ|3ßÌòÑä^ vìö0ñ*AºÔ€Ì^Ü95>nÈ8YÂ-p¨yäÿpô?Ð ó=¦c½b¥ÛR V Õ[èêû–¿*âeè:+7ç–ÿ3 Ë@PqF®ÙS-jÑXàtõçÊ_ªÛàZ©®åïÕå?j™Ýxù{Ρõ'ã¸Ëßš"ÿ ” L`?àî¤F€~!E‚@›tLʘÄ pèÂtí®¤á3Ý:‡ñG„€¯YŸk!?}¯Ê–›]…öQ  ÒJ’Ë’óÖCøz¡,êÜ@‡©»E‰Ô{íìor.Ð'À[a´2Àw §ïm>ñ.¹Ô÷ºŸN[g¹÷X•„]yê쟧ÝC+ÍÍÓÃÈ‘åï_39›ÅZ·ÏìÒÀ¬´7L Øê†žY=tb–Îmœì©……tûsL—M°Û;5sµÛ»ß¢šÛ—ÿ› óÍ¢‘ ކÓ†i 0WŽ­zç¡ínYàKÒÉ&s„¯ ”ˆ/ÕkëMŒžDª<5»Z-Ÿ[É)¦Â— ÃÌ<¦åkú#¹=䦕½ñD(4) ÉøùG”–¹§[¦ZÂŒ£8dMÑ:£¯Ì%ÿG‘Õ4†‘.ŸVõšŠ§sm†¼oo|Kßl¶üß~8å>¨÷¶æ•?Óg4ÞÜåÉtþS, pLsv•–Ï—?g…·w˜’gõûü°¸×§å&ô¯F·Ms®*CŽ-V’ÓÝ6Hþ_Ÿ!sò œ1$2̺X)þc‡$Ý œ¯¤è~‡¡#[°Fògî!1?³4O½ óÙ.ÖPw³1 #i¾5Æü9— ‡ ‚o\šü›·þ_Ý‚\ÂkáõÂÝðó^ôP¤·ŠóÜD_Ìîûf>œä—2 Ñ LM¯ýù’@!‚ï#bV'%@š´‘ô¡óµ€Û¦tÖçý3ÖE™¼À;šG6‚³ <$=Òô1  ÙÀ5Ýà¡ÿXÒ`ڮοº½Xº/ÿÖ>uÁ½GS]}QØ`ן‘÷M÷ì!1œxTj-I˜Àµy iW„gQv¦cõºy"…XtÜÀìÔ»€ÄŠj;Tƒ¯z6«q·üâdó0 Ó=ÎÿV™ãº-ÐhS· éú‘õ)>À„ÀL•`RÀùa!Etûw†Ö¶€‹b`d9Ÿ¼}ž™×žªtëݧ\,TªÕ½’4ÉÌPËR[¹Û¤Àß®?¥‹vó"Cc1dBùZÝ )ôÄ O;…ls¯‡Û4Œ¡õ#2ª”4(A¾†!ÍÂ]®!YÌ/ÿÜ«£?‚äoêðOûȦO±wîeu«%ÓÿUÓå¾£íßÏ'ÿg"儹îÏJPZ/8(AxíòÇŠ¢80Eó74ó©ä¯S¼ñ´fAþÌ·:»"òÓÕù3±Â"öµˆ °•3³ƒDg뺲_óóøý”)ž†\*’¿U4MˆÌ³–aœ4Â2¦{¹}ß"Ç‘f÷×NØÎ2©oX¨,õݲaÎ\ mî\šü›¶þç¶—ùZDû?ç]ÿlÀO¼®Éá쫱ÖÒÜ=…,¤óx <§ìòÍǹ'0¡‡Íl¬"õÈÍþ<™XšŒÒÂZ>”0U' Z¹úšþü«H±ËÇyM}óó¼¹?K ÿõ‘àÎN™¦¥ÑS]_ª7:°u^…™ñË@åš~ñáL1¬{ÐP±¤4бµuÓüõ¾Q!A÷Ù…/6’^`ô·}ØŸ‹UÿÕL[戞­F°r0>vh2Ú>.€â¼-JÍÆ:”,Gsܱ@º‰‚ÆÇÀÁ0Ôº$”Á´,“ÈD ç‹!€.^AþßçSèÏügÐ_²‰^>7ÖL˘æõ Ótù÷öâŠÂ8øn[Ì%ÿ35ÆûqRÖéØLëîaæ Ø9n/þùg¾h ) äR9WÉÿÓ·ƒt¤óòGÜgÅabÙö5AþO¬Ð” º“ý\k¼|T€Cu&ùJ ö&Î7ŽÔú˜ä_p\€k]h¿,³Ž¡/£°S ÌDIKdò?¸Ãh+Ú6«ÎåÉ¿aë¿|)£òÿy-¦ù_Üû®¿¶WK¤!×vK¸‡læØY›îÝ}zrœ«µ “>WW ·“Æ~ôˆ÷†_âãˆçIp@ý­ƒ˜÷G€ÉõƯ¹ö«Æ®¿¥«'1 Œ8bVTÑ [‹!jÓž”¾§Ö¬ŒDå´ÏbÚ-(¢Î8…(lè<=¾þ,A-àZ…eÝ{4~ópÏpkr4'0Bn6-8î@¶vdR¦{Î<#uÚîù‰Û2zc߯«TöÎÆÕé&ÒB+'È.*iɪU&ð*ýÃX#9à Μ³ÑПH/ð5HQg€‰ÉÆ„LÃ)憓éx%ùÿ+«îÞôRðíˆþf B²µ~@xã·Í—ÿãÈÿ>DwOߘGþûdYßÝ WÕñ…nV· X6Z»Ï•¿r÷?͘“½m­¦åÏ|•~a¹ŒÍùëέ>n죘iGh±òÿ~ÇúR ™õÀ{¥Hþœ0Ügr}^Š/€³[é h2ß ÇŸZ’?Z%†®?v&þ÷Œ¯‡ Ä(é­3v9–5ˆT! 8{åòäß°õ?šÃf\ökqíèwþ³~Ú«uPZñçõòYòõØz»ûeÏ=ã¤*H÷ßdÚŽ/ô'ÆoìãK¥æ_½> –f´|Ùí§ßô5sñÇ@{‰o± ýÀ™£ž_92a±Ôu¿±õ\äzÿ¬Žï¦ ýhŸD\ÃêÅ%8~˜ð©‚7žjôýJÎÁú5º?R.! ð8Ã#Útn0ÛЀ?ú’Ò­?¯ˆõ¼½úÏræ~Ȥ•&ÕFd¹~—•Ë€œ¦ªGŒbn³3I•#kÄÚ¦u|÷LxBþ* 1ñš&ça–˜ÕW“¶GR²³*߈fT9Vß5•G'säÿX<Iã“A©-§_ZþJë¤ìÀCóH. Á·»åô±ß†æòYaß%¡m=-ÿ)àk#meŒ“ðÿräÿÅ—‚Ý}ÿøByäàÌ&”Ö“üá,xs¶ sNÊ >Yës‡'¡ú-=Ñq©u*¡f²wb邿úöçû˜dØo€çˆÃ}¯_¢ü›µþX\óoæ¹ùf9)âä raIo¢±§-¬Üagéúý€TN4þØÍw¾Kc¿Aç83ÓÔ@l[y‰;º:)Bû­›æ»¢†÷B¬ÁTwãTiw¿N ›ÎÇ„ðòÙ¶Ú5ÂßšI,ó[ms¸6¦_‡½‰Ý˜èxZÑý|àæ~f$˜hŠ·S¶ó®)ñmh ÌAcÛÜuê­ïé;ïüGtà¯|u×€1BN®Ö½›Ö¸(®_®G¬y6™•Ô>a(a£Šà¸H±ãÂííÊ'dôǽèСtÕ…œÊ½ªü¿‹l¹j9TÆs þAP«ûSñÖ ÿ]®?Æ»¾¬ü¯~}P[ïÌ6í“ <‡ØUé_ l]ÇŒ~冸´ìÆY—¿ÁöfX òÏýiMØPï——ÿü0"ÅyÒa’{ð ËöF#»E–¼»oµì;†}|}?\vÐe?CÈŸµL&|†ä¡ùÝ>AÄ@‹+d¥Y“ü]gÂ]³„Ûü£õ0S—mgtyòoÖúÿåíÿB›ÿÅ¿}ë {ФëƈzF±ö¹00eBNŸw•=¼ ý釜Pjõ8S‘ú/$?‰ €Ìk… ¨áäë•S_ãKësðÆlíW þE<¨—N}¸o£ÿÅ>ï[S6ËƬïåác£«Ç3‹Íë§-ëèìÚo£U#üv|-ï¸F¾óÒ"Šß2C'»UJÑúÚáaþÑŸØ|\y†ÔfÏìJÖ4]9EôÒôwÆï$ÊDÆ7´ÑÒ}%-QE(½vHžSoôã²á;_øšcºþú¸ô»%¼ëgÎL§Îž³IëŒ®Ì Å?¿šüNIþ˜äJÙWÒ óîå©hüQàƒ·Aþœšaxá­Ï^Vþ–äoú#–¿ß|G¦Õ€ è¡=ŒÏså?(M n ×ý“iùƒÆì0ý¼üÍÒ©¥'Ï4Fþ_]x‡Æûÿ}ô^Þ¿êsõèœsŸûº¯ëz½ž÷k^¯ÛဟÝý|öþ]ór ÿ[ýIÌQšAÿ´‹KàŸtP!^7ÞÃýHàªóŸæ{ c̸,úx¡míøW"€¬Ÿ.p –TN^îºû¾˜¯…ìT‰,€¶Ì}mvtgtnNZ²)&ÎÚkËæÝ<$Ìãs¹=;Ñ•ÿŽõ%0ó/ 77 ¶7ó!—š›MvQ ÷î´=‰Î†:·Ðº„Ç0gOùÕà=åÓoÁÙQPæ¬ðüB¨q+4/¾¨`°Õ’ò6w¨š ûܲác­÷é ’'HÏö.ë¾®“ªN ¾R¸µ/²Þwv´Ê¹ªý¼a¡òÛFu0°/‰1EèTûD®±¤¶N잸ü‘³s¼á¼!·½éDï8;FÝPnƒ¼!ÓÒгºB‡ðóÕçnž/5÷Yäþ˜²E76]TLÞm‘,tcE—§O[O+xYqéвÌPãX‡ðl#w+kÁî0)õ;’ÖþŽøðz8O ª‡  )Hq ó t»ý³~¨çŒy’i@Tto +ë4(oyy©oø ±Üè#§€À›ß«ä˜üÉ‹LÙ).@Ò'3ÆÄ? vÚœK›ÎýwñäÒkÒ}è¢ö­lÖv¨Âyü“x„´—p”•ÀF¡¼~7ÿEÇNRý·?À_ÒÔvaN¥['cb€¬mFFPžíœníïñ¤°øC(îo±ü!Ä?À ýEð7‰Ÿä[Am ½0‘Ké$D·SÆÃ"­§© ›ŠÉDi{3L„<–Œ¶º_³+¼û ÎU?¨~rZ>¯ysÄô Q}7¬J8yÄmá\ŸB.¥Ür*àq®Úù”æÌ— ¥M›ç•ƒ<ªî™84#æ—ºŽ?6>ª²šÜ}_sDqÍ¿ç¥é3fàΩþIV ‹ìB_Mjw<û‘6šøÿJòOSôÏÅ!êg/á_7¢·ßßéN¥Ò¼ÿÐsúÎq0áÜ-"ãWâ4aðÞ2:ôŒ›«]Ö<ÕÏæLQÔŠkN‡¾Ü¬€Õ1D”ÕÞÒÜ“T`½KXÒóÖ† ÙÑõCi<§¶†SÈ@‰‹ßÐu¬­§xoÒ/V6&9È4Ù\â£Ü·sj3èT¦È3Æ«·¤æzÁ`uœ«}†¯‰ é±X@§Ý2aè\XX:BÃç*³>cÈüý‚~~Ò²v ¹âÖ Ä‹8vr¢©KuSï¨ |×WTKFèUöG³S‹–Y¼ÉæIói<´3ò-'!†fR® z®ùf„}O `OM”bHNCÇ”÷îzNÊÝfÚE¶T-=¼ìÙ?åÄÒAîè½Iný\wŠpgľ•=Jmç-5/§{B{ë~@ñ)cgL´£`l¯û$0È"ïKQÜõ îGIúž\ýí9×d(tû,[Ï¥GHˆ=X¼tÆrt#2+ø{s<ösÒ;½iWaÀ’nTtuøšÜ…SYR¡’ï7ÝÙ(g»u¡ÏÁ6tf²ù.ª1œõÚ &â IT‘¢°—^½ýñ\wŽ!¯`§3µƒ&óZ¦Ä8jïèO—c×Å.xUPÝ_Z6òÁÜUËJ =6—”4=-\¢¬,' 3½mì¨àŸŸ”^&z±zŠÔ)@U*ŠÏ•À@÷¦Õ\„Ãï’d˲ ìÙ׈ =¾ýܧ@œ9s#ccæ#áóÌß•—+¶iž&4(3@XÐåµ3ÚîÍ: {ö ¾æ-ÝØìËëÉ3`Ln5@7v¹L–›lj¤äxtü:sCú–\sJŠ?÷»¿Uû„¿%Ý;àÆFÊs¾P2#L4*Èdø¹ zMëA¼ƒèúÿÇõš5㥶üø»8®“ûQx¥µ™N½³Å‚á~efª·L×»âæ¾òeÂÜbæ/{jÁëŘ/ÒŒ·ÈPããMÊ¥6Þ¯@9) 4N½+íð ”.tvh‡wß+€Áv˜jëtm¤ù¦Œ‚ç·K6VÁÍúf#k¯óÀàH¾å7]Ü;W¸&a¶4N~Q¹0àÖ Èz°pIbcØþwv›¦®’Mü-ùÿÉÍ6Œñ³—0 Í&r´lúßjv‘ÿv„ o˜3N/jhLòx½¢ ‡¼|Ô’µ+' TOzà®sNå< í:NGvé6Xíy\<@^@Ê3ìèöÄ—kÕaž°Ú­…~ԹĶPjÙøi« «[3[^BðôKGîy­xÚ¼‘Õ 6ß¡®O˜ôv'9¹£àÎ2›A3É‹ˆ 7ÊñFUNÛMÜõìØËãT”“=êÀeúíTØ<«òþÎ*»ù¤ij•úÖNЯ»¶ßª~Ø}YßÈýñ¡›öíìš*€ìš%¾Æ½ËýÅÏú¥–çq‹‚Ç™½º‰i%„9pgEBb(ýÈïÝk$v@º•JVgSCü4ˆÞ“V8Þ¯uý¼oÎõ8pZ}b”ð¿&âGvwõCºº„¨|+2³Î.ˆÞyÞÍ«®™°xÐÛ”¶ïdIÍ=$v ¡÷½‰Ã™§IO×ü&ø¯ ‹÷!h†]¢ÒVÔ¡>—œÆ•|hI 17>9ðù¾×ߟ¯,¤E;sóe¾xO¥k(8ô@ò¢WƒöûŸ¬ô§—=»MIѰþÚ$+~ø!þ’÷x—·M×µëžW¨–¶‚fQNUˆòü]ÚD9û±°}fÎ+€ü×éí_’ ¿þiþj ·¯5é_rû|Íþ‰Ž¯ Ë^¿ŽÐ–¬½ú®Š2N!P¯ÄÍËÉ7Jaú†ºVù¶ßâ‡ò›ŠA¤›,ÐÚ¬nºõÊ„Ó÷€êîxdвíø!iDjŽ4<’ïK:É¯Í•Æ çž™'Ë U5Œà…àj½úÌãNë;Ý®ˆ.EÓúÚ¸¹ÅŒ–Ü }8NðC«×•âôt]»ÃTdÒÉrbÐ…¹ú5A Gÿ_Hþ{ÿ­ù—ÍÃ=ì'¯`tÕîÐ_ïüOãöÿ³ù³þŸíUô&9p”¿µÔ©]ÛõÀà£J­ßDÓ/¬z+ úxN§ùV‡‡è£Ez©4°Üï÷bÜ;Ò}ë"7€YÛ’P›ü´ê¦ÕöâÊÆ;çQ(ÌŸà ÆZ‹Æ¥zLI;(G>¯û^UßJºñ$ˆfÏ÷ãSªPhÐV‘k…³“]«ùR†ò+‘Þÿ (\–3|Ýd/ÄgÏŽ%— îhþPutÜ´)ÝÙÇäûzA !ƒ^U]y“;HtÐ2ùš“ j‚$/ÛݪwÈxs3Z5åɶ&IR÷cï½f鯠=«çéÌÔëÓ íåD¦=$~xÐ!b }ä²›ÖywòNß»¶êȱ†‘3n$¨9+F¿œÒݪ²·{Φèñ“¼ v4Hïj™<“s?q†È™—Å?,ÐêϤô-í43 kÚNCYC÷9+7MPÞ÷vczÄòG艬EÏt§.‡-Ü/jaàhqÜŒ±ºúj“W6“TQ|EúÝúØüGQqþIþ¡GÖ%[ä»ðîYàÛºõôŠø—¬–'¶æÒª63Lá x#œ¶QKºÏnî;w¿<}7ÄMÑá¶ôšQÅÿבÿØQ1Cÿ¼YúóMìߣyx„þå¾açþ/6ç x¡-{Ûe\â4Žk1µ9/Àks¡ƒ¡×]ÝDXÏÿ*Í\ϼj.øîÅbL Lpº b`ãæÐ£àûª5‰äẽðlʉ]“ÍD4ÏpeÕÃ»ÞÆ`QR•†a¦/78  8L×ZäœG¹Tލ™âtÌÖÛKÖèKQ2®·µÀ ’oU‡Òâ^9¡3gS D]¿;Kz¥ä˜Ö=ž•˲& Óîi»SÓÇ`ú‚(ñ(mÎ5M·—"E(9»­™Ô©÷báAEIÚ’6eÔ«N„Wâ¤Ý“…g,–xÆ@¯ |.NY@4áµ ¢¯ [´nžó@Ò—gûJ\?¶.ûkÕMóà=ësx7-Ç佦)¶Ócàä‘ããAŽÐè7©Ërí·Rb {¶rBïlPUBòóÈײ÷æäwñ½VûúՃ祪Þg0ÿJבl]ë hF@üàš)r'cã~ošÓp?:ñpà3’YÕ,ѸÈiDϦ¬êÓä©émo¤!”~j¡NþÝY´Ê-cZ-³}—ŽÕaοzòe1’f‡ˆ'9àØ®¡:íÖ› $‘ÓV˜DyÛGLß2ÖþÕó·Î\–h\qåöM¨¤?WÛä)uN‰‰ÑæÌLW®Ö>5·…7ö# :Fõ6?‹ô,6Ÿ;zø¯>~¢ÎŸ5óJØÇ¶õðñNð˜øó@}2ë@22í¤8ˆ\l™‘9¶ñâ·[ü­øív®ûi²QËÙΉk›HfÐ/õd¾»YzoñÀÛ´«cKþþKšóuˆàUqáæir ΩÆV¥¨™-;a>­o…¬4í¤ÞÚËïÿCü¥fÏM–ãmNLQ«ÈîU» Jï¿ÇA¶®l“w_ZÂ×ö‹¿à_·ʳ'¢üÿ3üçË4]sÎh ]ž¸¹°ýYIÄÎ.ž´Ö·ÌÅcÖ3z´˜™daæ 2À±–àØèÔÞì(þHé ÉCîº/e\M6ÊÈRºc×võ¼é‹qwFªœºø¨ø D(¹M}vaÖ£ÛgälH€R×OAìªBe¹r¦´b*Å9{F@1¼ÑɾӅ;.<•T9ÁytYàÍÞ×yI1³@¬k’ºéíQÅÿבÿ˜Ñ2Dÿ¬9£V ö5‡@ïÿ÷“þËb‚Š %š¨ÛÑJ•w !Ka~P­WoZ¤ ˜KËS$¼ùkÒÊuöMÀìó€ q9fO}|ˆHŽ;2q¾·V“)™ÄK§éÝ É ŸG‡þw7œõN?y.}] Ï |[‹Â´[~˜!F¹pñÁãAŠ—[<•ÚqÖ—ú…»(/œ‚ Äên¼/Äz >§2p⯭77_²ÕD¼ïîS«¸üö²4{a§E®ÍñÙÍàjpÂõÁÂ+ ZÓ\NçHQ–ö—ï“Ïœ½Îý=z6$|x¹ôŽ1+(ÞÈÕYþîÐÙæ­À˜ß°7ã•ß„zéÆ};D:½¾,¿]fà¡q¯=¡á°;¡õ}|1]å–‡ŽÞ@ÊÕØ|žJ{` 1DùÐ¥ºgSÖ¡Õš÷—Z€g”Œ[ÇPHH…˜¶w¡®¦eàÄ’+ÆìJöôóĶÒ(ôêv–žt÷Ð¥ŸÖ“âkDy?Á×÷ÞÁôÅkyò ¡ð öÛsÔ³z»½]¡nŽÄ¸Xþ, ^ïmSî™~šj;ÑtþÉ훦a17ÚÛTŠ;¯9nç/‘XpÈÂ`‚4`ü'¾1†*„¤­ óÍÛúòö².C¤Ï8wÛ è=0MCC}4ñß”bøæ^ Æ£¡.ì—ñä%ÀmeK6Í›ÉX¦(n?fÆoƒŸ<Œ–ô”yK#èúG$w */5Õ[g.W\þ¶š·üuüÏù8å£aýÛÞšŠB‰– €«Rœ¿â§ƒ˜:œ¥Â[¶žóD×Ô…A1ö‡ø‡øTˆPb‚ÒsÄý<} U­¸®òüOÉm n2è7-W8õÿ¨RQ‰}ª?ÿîq>Eç^'‹TZpØ~Œ‡9QPPb@° ~¯;iJå/¬¼äŸà1¯;Ë@šãÇÄmJ£. Ím°c㸼Ì爙Oí†K·¸ùAê;f œxôΚ¹ßc[/¬Ñí_|_ë¹*ú¡oj½î½o\ ý€wÿL¹òbm—¢ƒìýùM\žc/*J¨çêX«Ð[Zªë¨ô“—¨›$´lUüùçú÷è_4ªmôO´Û_Îfüi]þÿ«æqL5Æu…®“0P'—˜dŶ‰tÑïý§ lõül’½SMã'7 ºÇ샇;¢É@!ûjœMuÑà§RÂQã·ho9 pïî¹ÃR玽Hnòq ¼h±*|ì Or«½’™²©ÿ%š“6Ÿ.˜ ÝðÌòýœƒ&¥6°Ë–r=µóЇ—kªgGeï|´º! N)¶Óúuʇ^íõÏ„EhÇV%Û]çɃ÷M x¡ÄÖÉM0•>kŠûѳà¨YEíô7TÔþ¬p!1W,»ÍV0JUDÇŸ)ñ?=¸r¥ø†8ªÛïƒÿ¦’×ׯ­×IœÊ)f×h˜÷¹üPHŒ[cã• GyÁfƒÆ¼ZåéLô\ÝÜ‹è—&8ôÞ¿¤ºàÖÕc”61JÏËÝ7áââ 9ÌQßa²ç°Åñß•yf\YknG0Ì唤¹ø´ÏƒëÀ?ÿÀ¢’ø¥šSÝrh#ø¿n¼6Úòÿ·ñ7Õ,jàäÌqç-É»Óz­MlÀ-èÌÍw2ºTNZ¶½cúJW³ãæÑîÁ懠«i–0Läôð¼vñšzB›U}þ½DHY”³d {Äšxx§‚³M¤êZ¾’îÄb²ýñümâD³ ÄÕ„Ô%”(% ¯õ'88\ëûÛ&…KÐ7#lOŠôâ…€<¯ô/M·IË»/0Ñ )V›1–•U)ðÛ3&¢/†Äù9ÜP_Ä©[˜à6+azl¿oð¬>o«·2Ï}É5i|Ëžvgö7æéfÈÛ¬‘‚ÝDªaÀÝõæ1«¸#7Âåê.ØÐú²äò‹«›3`lh\i8´'¾ó6³] 7šì¦”½ÉŠ÷‘™oaBk¿DY—êîôæ&±ÎuE«c`R÷Ê5`§æq0gv..éL(ˆµ”ö¶¿K¡__P¦å<».÷…楾ËlW^ ¸6PëÎCVMCdl Û”ÕÁœ×! _MV¹ü0nu}@żª•‘œè”’åI¢Û–Ë ô?D€PwAqYâ„ÌbšôJEFRÍìfñ³­.ѺË;xÒf.Žx{þ°¸Üt:"í;»ÑÙuýký…­ N¶QÉåÖ‡º-Š•î™`Ó°-cNAñ²e‚ágLnΰ˜n›{ëø•Ýö„£4H_œå;Úø[†Qçé¦ÕlÓ<'ô‘ѪèzK”y ã\õX0ÝäÙð° £Q^/U¥Wó7ÂßíøÔ5\¤]»úÆ]Ù•¤¯u*mëù¯öqå`Ê;=Û¨ž‡Õi*þ"þïËò|žZ®8±ŠÆ;»ÓרúDÔü>\e—™„<¬ðßæ~Õn7¨çø–nºÿCüƒd¶ÐŽ<}·{©Ÿ¨?Å;f›)¶|þ÷ÂEnjYû‰#øƒŸû¨ËÿßÄÝõüªøúÙ' "ÇÍ}< ©Ý4(o¬…©+±i»ÀéJ'Ô+î>´ÎÓDiE´ÍÒ¨53Kf»¡Ñ™®¤ì+ÉìÒ¯‡ÒêÔZ®ôJ(W9½Oö÷ÃÞ]üùÿ‰DøýŸýûcs¥þÓùŸÒJÈDظÞðŠ8–]je: @¢,˜éítVcÞôœ£ŠÛ|0› Ú=ÌYÔ#P#³è<¸Nþ'E1Í›µ„;\m”oxÝ™’þZfĬ½eØéÜq% ;°:ÁË1Ýä]æ¼â'‹:EãMrj2Öª@Q†a‰’¥PìÝÒ[q0ËŠ1Tüz6ÒŸíŒö“%Épû\ÝüŽgödÑ”K$W×kUÈ`êsxÌ–“úÕ÷$=úÏÞqAÈ¡6Ž1å—xl&C’ÙàÐÚy„ÐP8±Pø ‡­ÓiTÍä;ÒÞàdµÜÇDvq#ûR䇸G¹–ÌMóº£i [$–Û.½ãí÷ïñ×8zH/\ΗN‹°ˆÿ‚¿>ÏÏÅ_PHÖÝ+ž«¿L€uÑŒi0ça„½·ÿ†Ç!›e¥}h<œË]ÚE×øæÏz®\µ9à óHíS %ÚÆ)›n Ĥ½‡¨¯Ì§äìê0T€(íù¢61`îš^)¡ñiÂEhš§7¸Úå¢LĘw7§Ž›gùñÓÒOp.Ub\_sö»±Ÿ¼¤ÃÎ }”Ù—ƒolñ–¸ÙÃO ¿±3f¨Ú¥GŒëLσQÆÿ‘ÿ[?ÓøØDÐæôÿQ³ ý+O4Cþó…|ß(ÿ7¯ŸZYn£WÔv¸í“Ÿ¿þþgIã|žtXl‹™³‘úk° bèd@Èl££.ñk§ÂæIQ3b¼¤¦w ïÔŸE۔̹›ŠÏC-êU,¯èÁ.›þ–œô¨ó¦‘²ðùâU2À)Cg>9 ‚U×ts!Âæß¦QT×¾;g•ˆ'l·šñÇØ¬šÕÚL^‰ƒÚK×pƒÚ3[sšSÇŒ¼¢ßoºüÔ‘åön‰Ü­³Î<8çÒ§±\º&„Z&mÐ/´º±O¥.ÚÞäv«í:¢CûG¯*žÍðˆ` Òû©ŸÞM⺽ÓÔ‚Î;%NÁÄñ“½-â(â·@BçàR× =¾@¼,§¡ª#!³:Ó°®(3{Šñ†\¾IÎñ!aÚL¥šýs[gìjÊ“_>Ïõö2‘¼3nþÖ—ì­Wîs¤Ó61+í_iª`r\´+ƒ}€áëâdd-Cû|Mçñhq$l"fX©ç{$‡ï1tÑ ç™gU¸`·Fóš¦HþÏÇg ¯Ö#µØž ãs&4‹»¼«[˜tiQ Pý%êí#NóU¼™¼Ç@£‚i÷wêÙ€âNÇèçûÊ4¢¤©"îm^m±F‚Ÿ?·~ éE–Ñ{¦E"·aÝG]€ˆX,°(2Ö:õ_àõ('[DŒJ®àtäûkZîO°|°…u%]³A·ËØbÜ~+ü×åèF¯cææiøID–®x¦%øÐðó"ï<‹/}ÖN«šRmçµ»Eç¯áã9ö¬Jå³´ 8­{m-€GÛÂÕ79 Sì’ªÚ;೎D ÒÕ¤“÷ë…¹:ó‡øÓ@ÀÞÁtÝgÿ‹wÄ/¨㔄íŽïñ?£ ˜F«‡OwslýøWÈRE©ºçt/Û­HðxÖ“&ñQ%Ê/¯=#1ùE_÷R˜S >tÑã(lÕ½s§æãäúžœØµÙgN>&oIÛ2²¾w‘s–>Çrv$d©>ßd°kUº?k`à´æéÔÅ4r¹º[÷ıÜõnc/mÿ•µOÒ -n«B÷DÑÃסÉvÒ1˜ÝØÆ“µù@3å^Ý.´ÓtÜø)Ö]ÑR¦œ·/ÛœÒ _2Êøÿ"òÿ››×_¯˜ÿbóûT5dÛÏàS`bB” mǸ ·—G3@~¯U¤~ ØîyZà çÞh¾Ñ¬@'9€xav³Trž|D'ÉÕ3w**6|Àà M‹®Ýù—Ư½A#h䇀CœÄ¥·BéNÎÌòv¥Jf ¦·lSŠDeYúðVbÂahÒ•§ƒÖªMŠ0-ù’èNõ;!°âšB1y~p&Œ“Õ$Ú÷_¹¿ =êsü'ð.˜ î–aað.æÆ±År]r:Sµ,Î7+L ºàVÆê:scË' ÿYD6 ¯ÛoÄV‰o¾|ûF=TÊ76”C¿–ô)ç˶+À^È>(M˜\»Feþäõ·<‰æ©Ô±o#àγlü"p¢íØR“76 Sý„óÚŽûK³…N ö =?˜»îãÝÁOcW„ -u$•k̲ÕXgd¬ÅÍCàgåzÇy'tªÊÜVts'GÃ3I}WË ëÄ @ݳ…»¶;ŸÞؘX•A—÷¶Ez²¹NO e¹}Nl !ÀôÐÝ O?ؼ¸ZqõQ„oá›Bh/YY=±F1Ùò¹Ê¦fº2%ðI5iæG[Äd)•­>:æTe(gýä 3ß™ôO9ó#¯†ª$Ëçï§Ò˘™Û(è^¤€öÙÜÎ.•ÿ‰Ë´ÇùM~àv_õ@€×KA›È˜Ûsì:¦¨¸£zK¤³X·‹“ïþVø¥¹|ænòn-NØäü`ň‚WS;E«7?qÝ*ëû. ÑØŽ7¼‹†·!ãÿ þÊ©ž¼=ÌêfI­¨à¿,_î‘Ë19^u“ÓÑœ¼"A_CåÓÆÍmGaupÍÁâ€Ç¡Éõ|Æ>2 ]i5œþÒ"ÓÖçø{Ç=Ÿå§½ô²ô üÍhqpVÞŸ -KOo2E»pX}Á#úbH½ðÆ“?Þ,]¼÷Qê㋉yÍE÷øÕ:íb£PË{Rò”·ñýô¥¨Í̵p5‡˜ÉÛ½×Ôo“÷TùðZtËË ½9Á]‡÷<ÿt ª{K“ÐGˆö’R•Q™ jÅ¢3¥ë_NÖ¾H)—d†£è„_F¿··í‡·®#+veü ùŸñóLbó?óìßÉ)âg/á/¶9K¥!TäþóÇ;üWI¹ßßô A²Ê næùxÓØ`[ œ¡£@²Òßi¡î±ìW¡ øiBbõâ:‡9­tãb°H<¿ c+#ˆt ±×]1Õ–û™õe€ê¦»ØMªß¾`áXž¨Ùhjyˆ cÏu¥!Åï5W÷ðg:õRž¬x9ƒîJ$Ãówº÷ƒºãa]ݶSÁ(!Ø™jhr ÇP™}¯ëæyÚkšŸ:£Cuê–¤„ÛÍ8¾‘v§2ý´)cïI~ö®ÞK•Z§4ûç§ZÀ‘‘ Ñ÷ò4úòoAáL£×6þ¾ãº¼º<¦¹¥µ§Áeޝ“7Wè°ZÖÈ=XÇuâpž‘‡z88/ú ^¨IÊšê|Ê*í @1”oîâ–5—…Þ=Ø[J·žq¸:/‰ ‚¯šgäVØ,†ñy—IùsÍŠ\,DRŒV§qtÕÜyf/c\·×péÅVíÞ,à§óX€¼ÕxP,ý ÔÉœÛÏ ÎHÃb°¾Éu-Â>(À0‰‹ûØn¶¹9ùWi/b@Àb6oãIìÔ~Ë ½`CnpÚu]“Û-g¡7nüÃÌÁg÷0þÏ”•‚õgÕª ŠÇÕ¹S*O2Ûq L üo🻊Ü%%dí:]£¥ s¡ ˆ·N~­ëʆ>ŠÑr«tÿß ¢øÇgõ ?¿@Ðuû1ˆ «Î ë” ½t÷ “L¥5h†.NÊQG­ÙI¥©:ŠŠñÕ{³ÝEèÛPØ¥ôÈ™’W07 )ôb„WÜz(ñcü-Š8ô˜‹ cMºòÌgwÍàú¾ û?àoµ(%ø@ LÖ½Tï[ù àÿ„gáªâ;'ÂD®”É%0ßÚtʯ’Í[o«ôÒsó•OÏn¨ûÇ]#ÏiþŽ;ð0·›NíÚ- JOƒvPÆzѸÔÏÜ—˃+“NÕâ@ñò›!3y¨>&jò|Ϥò)Ó“7ìKÑ^2¶kòÈ YÖNΗ¦nôIÀ¾æ‘B€¨úÜ'§Ëä\ºÍÜK¯TGàÙsBÍǦh”ÍñYùP] ËûÕ•›D½7üþP¾Û`Iª°a?o%šhÝÌsÚÀ®ó)ÇiÞÇè™ð+x®øLfôGôÀã]ÖêËÍVVEÁˆkœ>„sÑ=ž/%¦7¾™é»qá"ØÐ±¬…·Ò¡îéªH|œ2ܾü3¸ëÜ?»þ+ü;ÎUÀœ›ŽiÀ¨*I®y:;øŸÍÁ;àÛ÷‘æú æ–]üÍð×8䇎FJAؼŒþÚ÷“íRÍæ}š[7àµÜˆâÔßÿf|S¤°ÍЊ¿€üî@‘¶+›‹eüÛÓ>‚ÞýÂ)þ -=ç``R9?mò ©Ó/îñ›¬¦þÿÏbL°¬4?®à<½#ôîbµ„nIÈ8ýü«Ëל´ =åÔõ%?ÿìm^G>vpmP=ó½ýAÀP íÑ€Ïgdïwôö|ªªí?T|Ãþ‚Mûò N 3uï=ý›”ÁqS·zd9ÿ’±+o}~^û_KùEwòoßæúرmÉlwrwÙçRØôR©^J¨ÛV|´ÒLáÖñÄÉï3w"j`â®Ô-ë' 8Í} .ýÿ“-U{^Îqó?Ì›™Ç5ÍÛ|]¥õeéX©Üù¼ï8Mé–·ë ÙÎwÑz!u}Q ðfU2¤Ãl¶¥‹¹%züwÿ‰mf„ý%•XŠÁ=vÏfÜëå\;£²G&ÐEQ±5 ®ëîóዌ!<0±æÊyù§ø?éñ“ô{ý˜hؘ£åø8 ÔïÉ¥€§Âîqy© 1þÇÇIÖ&öQ ½>°T®ÿZ/Àígbñ¼{¹>{ÜžpòÊÆÃÀÿ€¨Î «ý>ù¢ãö’}§ÿdüš+„]Û»ÿ®Â¢Êè7…Ÿå’ù+Ì<#Ÿ=©¶Ï'‘à—p¸uåú×aë§*4V &Ãîèp°²uÏß«jštkï†g׬…E1—€:ØoÏùg²¡×ªû¹U®É4@eì¹×¸çY¨EÃ&(*$ä=C¤ƒ|Œœ;ÅÇ›[fl!¤?í=»öù¸§¢Á+/“˜”êõó›Ê#$éÅÜðz“–¨Ê•GM}H9Q?Úøªü{6þCùÿYÍ.èìÙ¿?¶_² Àý¿T4þPíùÖïå=­Ôm†s`ž÷Fíij?ÊÖñ‘â›ߨÅÏhTõ³è¼ø‚JÎÍA–âît6e­ñ¬Ò_Ðej>)¤»À£øj[*À‘{A¥!«×1¯ª+¼O¸úñõZæƒyþ®>î]1ü`çÕÁµµœé¥SS`Áø„µ°ü¹g^•Vîbk?Í+v&æšz“ýéDÓ9C@u¸«@¶`„X7ïm<³c—Ø´õ§J‹Dà¢o¯æTUsÝ®J¯cx¾&»)0CY÷>¨È…t¦ì·½ªÎDªÑý|TîñÞ9œã#¸g‰}…:ï>x\$ã,ð7o¬ŠšT'l!ª_wJ$4„s–6æ¬Ìœ‰8(˜¶é#DŽy¡ÉA™Wx—[ÞGA[|T©­Q 8uJ+eÝ ÉºŠEäÓÂ`t¾?Y°®Vè[³Ú@h"m§ðSsIøQ»{W-¼‚…,ªžß[°šª~…ëǧå hE^GÊòéL‚Õ¿Ï!ÄÓ|åP§zLþö–£Ì}Ä6nà'ykÏûyósm[Q—KkÏé23Ȳ²¾]Ôî2m}yªY½µ¥d$–÷=MË /þŠm¬+ ˜Nbrsú hmŸ„8Rè«öü—ø§/Î: Öyûaɸ ôÏv¦+$¾> ôÅ«Îmjüíð§½&!úæCÏæv”`6¯Ÿ§­Tçº,?öSÛ€ê}ꄧׯ§èåÀÅäåz'BÏ)ýþMè=‹Ês† —P7ÊT«ëi©y8^³.6ñc”y‚ìn4±Ø+8 t„*«vgþÿe*;” ÄN’ÉÖQ4¥ì–{‹ Äßýï^þ"ZÚÞ€Q?ÿ Ýô‚%ÐÚk”;?‡eró]ÀüXùRº« ù.€ÐJY€›»ö¥£ª†¬µe‘†.÷ ç*— mq(¸wÀþ˜?Kná»nÍÜ©$Ä;°¶¥’}­z*ÃËEË“`ï“÷Ûó HñÁˆêך ¤ö~¢á¼EÞãk$¢Š7¢‡;?0I­Ûu¡«^ïÌÙëüãvîÔ-õEÍ¡@¼Y n+ž_ žj;_yY÷¬puüGSþS©ÿ‰ü×ü3àéü¯»æ—ožn?þqƒÿó=ÿº!ËÝ'椈uôˆžÕʤŸßBm^f#€’¯MÛìêéÜÇ[¾8äóæë’Ñ/ åéu"æ8t Gl*/H°˜àð4£â8 fÄžõ´†'¦“>äj´¸‘BÄ›,¯`š49ma0“ksEÝxY5}ÿ½Îb8AJ:æß—rêà¤>Ýr ·T…(QóhᄪÝ5¯@nû cd ?’Bv¬œFá®1”£_ó€' Ê’\½9¬V+¾/»<#çhÂÛ˜@ü¸N>ªm6ÇÕ­ ¡û ò@b‰VÍñ ÁT(¬hHîçÛ`ß\Ÿ|еaƽL¢‹¢iÊERC{(Sµ…Öû*ILt÷ÉÜ¥;C¸åì«·óV´O{½¼‘²úv9­?Þ™ÃUY“µ/º6¯:Bp™>Î::vÁпڗ@êõÕ6ñº¡‹Påi’4 <ÝŠJ<ÐHH\yEçôa#¿ºË¯Ê×Wn4–×$iÝ @rt­ÀÔÄkž\©ÓPxŸâqu§£Ÿeõ¤œ_1Ȇ7êöÛjPc…93§ÇJßޏ³äöŒísÖé¼ Þ|!©Ñkx*_BÐþ(ŸÚÃÔŽ.Þõ+Pµ:_„ãnpZ¿·ÒMþ C¡»úä‹ÿÔ"öNôz2†0þûÍ~}ÜkÖð»¹c·eÉ]ã̺ ?Æ?·óVÌÄ ¤áaÌYto)—tðwVýþ›{e?ž§º,¯C ù™øjn:ÇA¹«öîàë^Ò›¨÷`bù`r5}Ú¨<]€´ó-zè)Ó°­Ü“ÀYn©9ŽÂ+l=iÇ+`]‹äåwe›o—B)Î[”´cú µš|ôüäÊá­Ú:aÌcâéÄU‘]Ë"[`ÖÍs‡ :ù{–›u¢ýK:†\Á,ÌÅ/xkßTž¥ÆâC7WO:_00¦áüÃ~a_Ú¬Fà_¨9úø¦ü?›úOä?ýg @à7¯ü»ŒÚŸþù ýi„Â@¨€ÐQ@¨(•„@&dv v‚ušB§Ò°oPö!PEQ ¨È¶Ð,”bætì…F¡>,íKo„="ûHEPâEòÅOa#P÷8ÀYldl¡úõ_ë/ãY ¦ñ*Í>eãgñ¬ìÿøµØ~†ŒˆØDÑð>Ãß}”cè—/±|X`/‚™¬A€½öR¨4µb2 t Ĥ0( ®[5™(EàŒ/…†q£cÉ(é$o„¤^Œ±Ä5° PkCú9œ¨j^‚Ëš5ù0©‚/Ç•}¬£Ùght2ƒŒR¼äîéËâ#6â„c=ïð’±q¨>‹ F›ÈmØ9B(k,‚±›F¦ÑHÃÝi(J üqüÙ#fçý‚%2‚¨Éøb@ø-ð/@ïÅ#†uP5þ.þÅØý€3œ†s” !.œëÎ8Ãi¨U •Ê@°Y~€¿m ÌŸ ØldŠ­Èþ=þØh„0ì»n Z \þ~ üÏÑYccìÀôþBÅÆÖT>¦UÈNá(ÎV  ŠQƒ—ŒP°[˜‚À]‚`ÿ±Ø’ñ5‚Ø ›(:Þc1֛Ї1 »ïÁ>Œ†wÄ$!3Yh¡dl Ø`öÁÞLᥓq^â— ÕÊ£‰ÿ¯$ÿ?ý ¼ßÞüÃߦáÿ¥ðç×Q±{j\Îq¹¢ØEb¢„+$„ÄÄå»h,5@Aé¸ÒÌ~㢂éܰc½42‘`oì;“üþ¤á·3þŠ xo„%d:K}>‹›“ÕÝM Ž(Ž//˜fÑî_õº'“ ªËpo–$¢ðÅ KÛ" n¬/IÎál=?,µ#ÂF1ðǹ½ø¥`Í:<,~­z®gq]€)”Š ˜zñòFqU‰ ^˜Àu[ϸҵ ÐlÃp¦RÄ¢zŸ][sîNÔÕ›ù¸'Áš•ÅytX5 ¨[ Ó;¸¢(.˜R â«£€;F ®I¯Öm´€‰°Ð§§PBaFb£`š0uJb(°BÇ! üS1ü¿QöèW•_AüÖ ®>LVW½ßÿ‚o8ŒõÕ?‰9L¥—ÖßÃß0 ÅñÇÎÀˆÞGHt`M ü3^¸!£0\}„°,>f0‡“?lu¸ÿ¬;né_ð?цYQä—ÀÿDfÍYScš¥0ú0E‘Š…ó„Žy(4¬£KvÅ=ŒkQ,únànß-7ìŽ? ?s̉À\ llÉŽ¡TÃp‡›ssØ‘ Ð/B8æaÊ ó©èÃnUMü-ùÿÉíÁþÿ4*þ½'°‚\‡bw J ˆ'9eÄ‘oÜ}v¬B–ÏáÞ.¸óM15;ë3,µ#±8ÿ‹/ÀòâYÎ.º¬0…†Ø‡c·)Y D¼°ß¿Ø‘0 ¨NLýBú׫¾vd ™ê=¬…ÜP?ü+äû@Ð)døùª©†Çòðõò ü&la›/†7à´á‚‰âÖHB+€ `®Q"ÓQw?V6¬lðOÕó¸º0p&à‘Ÿq&Édœ;ÜÎŒL€»?ŒP=bÓXS«azg;ŠH‡†ñÂè¢bî={áž>TšU4›oL<³‚àÁ nit 1qò±Ó X|‚+D²»>5ƒJ%üOúÀ°9aëÿøDˆØ?,ÃTþöß” ß·7bÈ— ‰{þþn”í"é¬?Ê…ÇjëÜp 0[‡sœçåØqéÖâ·ÅØiw? Ã2 ïȰoñ÷FI Ì2Ž•i`áî~¬PòWÀÿ< +ÜΣ¬Æ,ëNI ’¼Ýqü±ÞÀJL`g1ëg*ðŽ˜¿‚°² ñ2.¬8þxŠS@¬„ÎV*JÁœÌÙ`O(ËÎã<6,ÊÆe%ùp7Zõ¤Œ&þ¿üÿìõÿ óÿ7éµÀ¿‰•uÄî `'1)ÁË\¼ðTmD `òÎr Yòl·Š¸Òýö[Òp³>œ·ûjçñ!ëÓ(xˆƒ ¸àâW“ˆá¨£>äú~£â¿ya“ö%l`+ kZÔ÷îîˆ`kûÉñ¢Ó¾({Ç`Úpø•[NAߺÍ#‘Köa€Ó?ÜuxXLâ‘ Ó§,µ‹GC \i`áÚ>+8ŽçYá®P2Ð=Á aT‹ñÐã !ö'¢Z€O!†¡1˜5ë—T7òÅØ±~×[“I :…FÆ}(“x: ¡Pp«š?¼>bðã‰0‡ÅA÷ðqô§±&` ˆkZ,tñÄ5-‹{ôQÃ?6ŒBûŠÄw _¸Œ¿qü ~ü²S¿ì¬ïwN ë}¿ÝßÁ¿2 ÿ@ÜDp7€<óâA5ÆdÜ2á©î}?Ä¿7Ú˜us a'ªqûGûÿ`<Ål˺ŽàO£2X‰bä§ãÆegHŒ‘ð§ÏFà:½ñÀÊmÓ©ÖôH«#3pTV^e)2Fî›c\ÀøïI‡‘¼BÆ|/&N?kމ4ÖiÀ=0-œ)dÏÜ~Ü¡áÙrVΆ£Šÿ¯#ÿ_²?©ý¯Øÿ¿GÉ/à _ˆÇxF‰%r,5ÀºS‚é´¯b+–»n`åŸØÖ»[ñHß„Ié¶Ø£¸ÀâÒçüQO¨!øMËŽ4¯É¬kwÑÓSbàëû²ÿö‹‘Ý^Š-F$¡}» ü%”Ã>ºŒd}ñk­bY‹NãS9ý!ÿû5Ú´‹À?9†Ò‡…qx9jÅøÎ$ÂÊPQ¶/@òÃU+G‰)¡méQ8e4*ßSdé"ʶb¼÷Þ v\b”J¡»ûÐÐýGX+ñ¤úÁ—X/#vêë68æ/ÑYAŠG:$×PÖ6(ÆP’/(=³.Âð@Y{-xÄ„ë}`ýÈ÷°Ša²+PpÍu§þ‡’¾ZløÖ|G޽==wÿ6ø|Y° ž¾ßø'x$û—ñ79ŒsÁðgí(ÁHZ—µùÍö—Y‘9¶jìßñ/dí°R<VFÿ[ü­cX³³ úÿB€~ãwxèüuüøn…?:¼yÁªäcYWO&;{Œ[8Œ&/æñ/Ä7äqƒŒË‚’ìR¶ïð§àøãÅq¸©ÁEðÀÏÆ?Ÿ‰WúÑÑorýÕnx‘+ÜEh,²ØøÓXÛ#xFŸQPéìJ*‹õ¸‰·ŽÆCutÄ~O>U;ÄŠ¾ üÙÛ!`»ö,wŸ´Ž"Q´oT÷ ü&ürÊ& ;r¥ç5ÃWßy¸ÈË:zD*‡åÓÙÛù&$tñ§}{øå:ì¦Ø_ŽÔè²KÇ(À ü)€ï$R†õà™ 3°ß‰‡Ñ/;€¸²£d|7W/¢m/ªÕË †ë‰ª]ÿðÔˆcÄ0Eì"`@½¼ÙÇ(ž™d…2¸Æ‚^z+El†­ß°!ÃõÉTÖ.9[sbjˆ ïÆRñ5Èx•»»`4ñ?Mg0ðÍæïÈŽ/À·a>þî©óûàOòùø¨ý¯In6­öFÿb`‡Û»ÿá„/BˆVâÀÎ{z³bp|wûøŸg™nö–3†'Šï…{þW„î²­+Ž?{'ùç⟆DÑÙÙ©þÃKרø.?…ýP»rˆE õ!l‘Ž¡ VN†“Ã¥ÿd:« 7kÖѬŒTÜ?Ç>9ùøP†ëòðð×ÙA¡³õ,?·„‹9ûÅóä^žAÀ*qÀÝ”ì>ºøÿ*òÿsãÿÿ5ûÿ:À*Á“€°âr\ŒXjqaø ¬’ üÎe‹8+8`UºGñd*!ߟCXå~T R!½½?òt»7+Y7ü þ8ÛYW8K'»ÑFD‰}ôÁábEenAøÕ.ò©ß/9b¶jÁkÉ4›ûÆ×š/LÀ¾ž–dd¸¦œJ¶ ˆ«·÷ÅjÅø6¦]ñœ /öb:†SYŒb' ñ<¦¦ä+õˆ' Lô1}éÁÀ#m¬·r1Ñ: `5²åGv C¿y¿fPGÖÉ@ð”'àÛ€¬ÒJ»(¼v’Æz µ Ep”¾ÞR81„¨áŒ2ÊÒóª=Ëh²èe¢#ч/;8šøç}n„–uû¶&|ØtãONý>ø|Õû#d9†}ï¢Iþ‹ø[EâÈàT’püYùÖ³€À*8×€™?×@<£ÍJ´ÿÿ( fÔð$:Ê~°¿„ö=þ4û0Ö“(ë1–aüÝ|i£.ÿÿsþô‘²”…gýlE×ú³Ò,ïÄÚæ°‹`°ë¨ÃÏàû&˜uGØ;‹T§0–W€oÃÓÿ¿î®…·ãÿ9˱]4A“4iÜM¤¶EYÔ“Ï»ÝÙ½#)‰¤,K”eÙpƒ>]4HÒÀÍñ\ç›Ù½;*¨¢R)š0dJ¢x·7Üy|óÍw2âÌößí+þochå×è°QÈEr û¤§æË Û_²{À}ná|íyöÿ ¯]ø§¹[žŽ>o‚L{¼±Bº޲†îT¶8¨_hÐQº´7p©ÿœI_ûË1™P&è'ÐW‚²­gýÚ;:ûÕòƒjùW†0œL«à²vgL''ÀÂß!"°ßŒ Z|3J–Ž"¢‹ñ°iü—ÊØé—Ð3—›.ć/¥“áÂH°tR;}ë‡.-Ò XÞ½Fôu?t…u,¼jwõUÀ6ßýŠì'}[Cº‰õ—í*ü 80®™ r1Ðm a'h›Ÿºõqqõ4®õŒ/œñYnŒm’ÖŽâ› Sæ¢;½s·ÿŸŽ+–øA XE‚×ÞŸ'ûGªuyÀXÁ”“©yFû÷µ¡‹Û?Îz’*˾ ƒmlúSí¿ÅzcW*dcI*V%œWìoMíÈkª*ÇRû§~¶öÇì_ÚæõG^p¬¬Ub )ûOzÞÎ4û=ó­îXúr–a0à߸›#ÔÇø  ©Û“:÷ŽlÀÿMs¨üäBàÕ¦=ÐÞÔh½P’ó_<$GHés¶ÿ%Ùÿ3Åÿç,Vžñq¶Uý߀ÿqÀĉŽGUõƒ´»Çn!YßÝFX|>º ²üãÿòý> §žÃ¶ñÖç» 3[ÐâUäGy¤Å²86¤ö)B¥—twuä+žžŠš¬RþÉ—ÚAá¯Ñ,^W¥q®œö#w«¬ñ¬CÐÐrá£Îßx5Å'•  ϭäËû9à@R°Œƒº‘lK þª#Ò~KÚ€„Ž£¿sÌË|‰‹wŸ æ.ïJµc¯}[v·yýYá]â§gº»í1¬h-;>œ¦††,;>Có*Å2Æ}òÔù…oÚÝQXÚÇŸf­»û&g¢¶€O0¦æÈþ˜¤§[µiV˜,Ë´Þ9›ýÔ:˜@;[¦Ke&?òeP†Š¢Œ5§ÚQ³1’J/ÅVGo*ö¿ú‚íï´s~ëÉå°¿{Í>¾‹WòJµÅ ˆtñwßrZVXÿŠhJᯒ@Ø>w?¤ÏwÂÕJ—ºŠŸ/ߢoÜWʽÅÉt8¼šÿoõ²ê@Xá|ìúv.%ˆ¼Blˆ*Vƒw¦N¢m¶äMMó~Ñüw˜¢E¥U;ìJVÀž#‘¤š½¥µéïÒdÀ9þ;Ÿó½ö½p”Óü ?i -î;å©á4ÌÒ¡€¤èoËéØPxƳ_¸$øHT#žû(W'ÍÛ›O+°•=-‹á‚†+ %ôp×qkÛ½P!`hšÄŠaÿçy4¡†aSК£I`ÿæÊþë÷K¿cØÒ¤8ÑÐb»øÑYì¿üÀSí¡î@2÷€4¤®6ñ&Žá9Õ§»¶wªý%^#äIMŸô´»}ÂþIÆö¤Áe°ÿ¿‡êO–ú*û/ J¡¹t´þæˆâh=™ÅI.5?ç{N. }á 4û|) .nlg2õÐØ¶J(†‹_xçŸokÝÒ¶m™ ÖÏÙþ—cÿû ˆ)g|’Èëø˜Ÿ @²J|<”z, ew$·¾Ó ûºÅm! š4òd£ø«ØÝÇd°½ê^ÈÆÔ1@JmÙ/Tî6é›tü´ðήÛG>¾L·jôôã _SPiWà`QÀ­‹Ïl”„e§¶åŠ a|ñTÞ@d= ý-þÅêP@çë¯b/P¡;’î\˜E0Z¸‡Áê7ˆ¾dð1K²Ä gá;•D6+©_øÞmb~w­Ðß݈*¨ÜPym7^ñ L¾9”#–…ó¶ÿ¥Øÿù9Ç“Ÿð˜Ÿ ù3gXÜlÁ—ðPd>ÌëùѲPP0­ºJö¯³­€Èv[…ý<Å"_G…l÷Ƴ‰“ä½!ß8IÌ>âƒ{˜ýªx…Ím°é°¤…árÕ&e­&¿†$l,+ý2N«ceg£\w¨ï¬YækõÃl”†£¢Li¦Úи5pÔ¯¿ÔºH€I®õooY„B ¬›CE´{ƒè[OJ^ö¿ÿ3{›»GR‚xóÛgì2jG¢ÝñëÏL7Ïô£ÐÈ‹f\l•ÆÍgwŸÚ*õ}ðÁAäì¿ÛZ‘VfËTWyç‘ñ÷”ê‹R4bøô¸¤J—um=ÛÉëtQöÿë$dø¶ü'fŠMÊVçÌþ¥lT‚‡îZøa8œðÓî›g°ÿ ïÞý,Mò,Hµ¡£h²U”%£pg?9Ýþá‹Î·ß~”ä÷&šÜWíèª>qÊy›½ý¿é)d¯yÎf¶å¢ThNñn!(•~m‚ÒÃî×4C)‰qMT‘¶?Î)¹›‚¨’¶¾ŸQ³‡Î»Î’@"²+Hygàä{ÅÖÁ—`ûgI¶pîö¿ ûv1èµÿ4?ë=6­ Ž©j‚ %Hr}4à6÷”K³Ê@’NwI©¿*¡˜~™±›o?ß T¦ 05h6Þ¦¿ȧ¼(·¨~?+9_SE™\L.*Ȱþnm«jÈ€–á…·©äÑVya þÚv¿LåÃmDtêø|äæÈ>ê‚N¸h´ûÜ E†sÃK2bd×ߦÑ\lŒyÓ¾õ%f_émXÌü$͸6Ø%×ܶ7¾p¤mý~ÏÉØŸ]שjˉEn]"_T™œ¯ÞçHÅúËÅ8…[}Ýú8AiÈë××y¯(ÆÙÿ‹íPÀ +qþÞ¼ÙËëÙF¿ØÜ)8á!aá*[¾çõý˜ýWøÕÜ1WŸ÷­\SÇŒ‚¼K¼þh•­ïê]jÜéö·ñž>ç Âv\Åž°?Êd^?Â)´fkÿà;.Ü*ŒÓ<¶¿ôS‰ò¨ª…º/ð¿m§3r2/`€df~m+¹€¨%‘¬ÿ…–‡×Æ>9i@­Ø6ö×¹?ü¸)àš¿“û$7.JˆÜG»5öùyÛÿ\÷¿M~æþŸÕc^âãÏ~\Êžð))ÆÃ|¯dÿBÃl  GYçsbq@íÆH”&ã“ &·ÑÜÝ~|ëë~y?¹_Hq7@!ÿý'›rç(¯ëûSEß´þ{£——½àÂ}ß9òÓpœŽQñÞå«£Ÿ_Íw¦ü{‰õÚÐͧJ (é~Ó÷kOPxD5ýBâg¡ºtË¥6I<¤[?¹UJ‚šAÚ!³í¥VjY.t®|ç7ØAÞ|Fï'Ðþ†"§á„|sÇ: §§+膺 G«3È£›¨^nï<ôN(AI\eäÃÁC^ÚÉ´†[X’*ˆ6^•ëÜÐ…Ùÿy^^ÿH0ÈsfÿÛK¿òK%Ùˆ*D·ùû¹ù̽7œp'Z;fùÀ5¶qC*zᔤQÂ{žf ª?H±q#:Ü¥Ê.œ´ÿK>;Ø_€†ÙÚÿ»ÌÕ¸ÿIýANq0S\@Q (ô²ýU>ƒ¨ëµ¸ý(³‚r;iðŸ˜Õû„»!â@¤w Ò|A%cû«€·3.PãâÈaœGààÍöÿøÜí öÿÌúÿ—2:žóãÇÖx2Ïà!ª™¤›z#0HFYùôU7`VvAIŠÿd:kû ûê¯ò‚´U™~ÉõÉ37U8™ÀÁ!W~Cÿ>¼ÜVt‡ª5 ñÿ²R®˜‰m_ù>]Ûs%Z D·9¬~•+Mj-W7rÙ$ÆÓÖVå Ú®Ü|…š_¢(G&çŸc•Ж$tÜ…Ë.kçî ÚbÇé۾׸¹ñBð@—]yÉnèÊKQYÙ3·ž&ƒhv2L³JlŠ'/Ûº'Ä=Õw41tÄq|vAäsy¿²èÌh‹Wo•âÓÄ/M †uõeºìâì¿÷Ø &¶±»_ÿpþìÀ²oB!Xa]‡VÃÚ81îtû¿â·ÝKÿðigÛiö׺<õ™XéE™Sì/ƒ Ë…°%{Âþ6¯‰ýñÙ,íÿÅP:#¤"i7Ýqaô!âQÿßÕ}àäšÈ”¾ƒý ê?ÚÔIÍ›bU.Ü/$¢õOM±¿v 0þ w1◻ĻֶÞÇjVUw°ê•÷Îßþ³ßÿÿ¢Ó°-°9Uxœì} \Mk÷?•™Ê „¢AÈLi.¥¤¤”Jó<Ÿêœ³×>Cóüyw%ör°'®[žE»Q#ÞÓ/}B6¤6Šë*9wCÒâ_cƒ†øEDª"t¯O:în0†™âÔ³óÁÖ'¤GîºQÍWâþX¼ZÊ%Ôë-o(wWiWSÜÁµ Ö8'­(‡ÝRQzÆÆ÷‚õ¸9Óäú®¤½o UÉäðó.Œk›B|X/(õ@ºÀ?øˆaû\…~½YLtKð'Š,ð6&‘ݶ_Øðt×û[·®Û¾Ö)…þmÍ æ³Ü3lÏ-_͇ÐàxúiX¶·‹‰…â@¹}mžZðvêÛp@z‹X¡Qñ K´‹ü6Õ6}z¢‘ô`®ðΗé0´­° ƒ¥¾üsW®ô5›¾©Ï;ËD÷@—xêÎ —˜þO^>?«=[¶WçHz\Ôn7ó¥ ªÊ/Æ_Ú³ˆþªþ’ÕãÞíA£à”@ÃäR[Ï£ÿ@üÏѵ¯ùšT Ÿ f[±™¡\l4QKyèµû–áËKs©´çY¯·ŸCá‚–Ÿ2‰ú9þžÍO]zOž=*ßÜÇ@WÞ/›7tÀøÞ»2W?…Ugú·ÊÊLrÝ)|ôŸãßë´ê4éXðî·åÏR,ø·^rX ¤MÙòþ’“¹"hÏsz7¥s¡ÖØáŸ)vR™k®í£ J„ÛÚù Ý€r2^‹x™¿ ½½0W =nÝ «–Z(ƒìšçÇÁ…y0JÔævò~°Øh†æˆG ß½ñÙbòäºÉL"0o ÒùÎûE«”‘QÃcÔF‡K¯é3§B©—”0äú+v ÉÖEª JÝ­AïˆpK°e,xŽvðM‘.Š4ë]««>´½w XíÜÖÇ)˱aWaAü_Žÿ_*ÿö~ÿ7ò?Vf‡6F+ÿæaEk~6ÎáDsÞ̾¨ÐA–)ðõYøÄ(¨ÃvÒKj 4o¹ ˆYï_/Ú{ÿÐòf4ù£Ë?ßFÌœ_i\ë-ÞÕÖùZ)l÷jJ·Å¸"Àe®´vÒË–Ýô#³qS+¸õ›è|)§.Ì©¸ä¨~Å"ˆNP2€VcPúÄœ\€Ît¯}7"Å‚ýŠKÔPÇûìõ:Úã-Nç ðixÒÊ ˜MáqvÜXAy–ü$) îðJº7˜±O#!Ù-ýöÑ/Ž‘Q©Z_0 uÛWIíé±”ÝùnS"™_¨ªáœº÷ª×Ф#7W2Lƒ%æ+‚\Âu½@æå;G‹¸Â©qùFõµóÆ­ÏC„ì¸È~;bºLÝ˵ÏÚ¤æÎ–³ÌXq¡Ü  "ˆ™×ë·½…(²u¶b;áÈkxS¯ðYþŠ‹v–Üea;w~öf$'¥V´kÎ ý4•ý\†÷Å»>±ò&·-ž{~õ;K?¿7PHyäpÄœév³Àb \¥u§QÍÍÕà8ùÅÝ” ¯SNµc»<é(W15ò£ÅºË‡ åìΖwáê¢: 'ÞXÌ÷ËdP™2tÿƒ¹z‡Ðm¡LmD§’”p¨s³M2æ¤\¢æÎõÞ^aùÑHa"mýËñßXäOM½i¶y3$/ǵ´(ö§;§æþ þ÷n'fËÎVeŸ›vávL@ΉS"椂B2_EÁG‘Ge9â.ç3Þ®Ò´9"y*H+·LìÑ,‡¾¹×i¾F¢ÃæÍñ‹ÊIÀs5 ˜&©·=ó£û}£”¬#¶Æz¾j¤«A:'öу%µÛà³ï°íGíÈm°Øho´°=§çTˆ>™|ÛG+([Št/šèá¨brùø†ÖëŠûÂŒj ÷œ’) ’÷S²ILK¡w®·<@"ݨÂmÞŠjAá{ï&9…[ÈÜÍÖ’îw4{]®÷)ÊŽZÑÓœ¾]õÍ.2Ný²&ïÛñnì‡üÊ[>—¿N=tÓܬ6“Æ/Èn¼-JK—Œ]Úz}r•3ü)¬ÈÍ´”HRu¾ÇoxfØù˲uÁŸ‚÷\ ò#óÜÿ°8™¤6jåƒn© ×W»Û‘ØØ7çŠD ,;ÿt=8ðòžÝ±"¸Á,Q)C6Ms4Ð\ä}*»`wGçÒÉG÷¬‘“†¼Ë‚‹ï{ô°ÉWÕÖ`öTgëѪre>  =èý"N*óðoŸs¯8õ@G9 ÖÞ~G•Ъ"þa›ÝCÕ³HÑwîz÷NªöÎý})ÆW–¶°½>j‡2ו?[(×ÎåyMÍwMþFIä£&g¯S?Ã$<Í—iFh…û@z{r_T¢Dî‰Êá„´û}.ñ`'õfÒß\2ÝÓÞ}z ¬,ù9þvå*åÒ‚•¶å‡\AÛ­ÈÛ§íÐæ»?à¿X»bßÓ¾Ž-[òÆ ÿS‹JHã¶m —Xðþ–U×§–KƒéÏðt{ˤe]]}BÆ´V5:ÀN*eÇxؼÒbˆ^˜8 8Æ‘Á-…÷6,’Qßë ä0QGáñÂ*ð2Ð]oÓ}5syÁ¼·rpùྱkS5^Â¥°•°ÞªRǰ{K—.Z$½å6´ØnØ»S§‰{µ­•Á¬ÏçÙL&ðAWò`¸Ã̆#$Ú† JÎþ:\|ÖQŽË_9…¡iËCOØM_ú ðkùw³ãà86 Åðð kþp8S²7¤Àë-Û"}©ã²§ËÓU·©,*;!œç&wÓ€¤»i妸=ñ½;'ùTÙÙÖ™™Ãìœôñ˜Ue5ÀüĪ >–øŠ´õòž'¯£(o4—ÊÚëQó:|'%ܹ+¨ûâsÒ ´H2Ûa#K๟Üü`‹áÍHðÚ\€¤Þäà:•$î[O‚ç9EŸÕW9”ø½ŒWOm]}~F—U~à̱þ Æ;cBÚG‰óŽ+^ŒÂŸã?ý2<]½Ï—žçM¥ÌªTëxÚnvóGüm=cnéö<öl¬ðo䅮ĎP˜œ›‘îÁs^²¯Ø›¬ñ0Ò›^dA©$Æo#'=Ï_ꦋ]¼Dþ[¶ÝË×ðÜý‚Á¬àÌ…é»–ÃÃXnw᫉GÆ­ðÔÍ0xØU•¯|>-ˆ—ê…Û;Z¾(›/ƒž×àýùºóà‡¾Þ9ô¡Ä€·^NîÎÔ½¹.ARŒ«–ì™·‚/xÉ…eÂ/•S9†¥²ü7]ôÏR÷ýøÿÅò_jüÊÿ„1±:dû±Ž{ï°òkþ`ô'¼A§ùS&O®"(^6·Nƒ9ÊiG§µÚaì|ôÉð8s:{î\Ð÷ÔʸP€«é­ \vÜÚ uò{’ê?S^4.N–\ÃL·n; v V'­v€ˆÆòƒÎ_€’¸#²ãÕKŸ r(Õz:›|óµ}†SĬ«RHù¨–_]ÓÇp9¯GxÌ —4G7óì´[& z±® 4GÑ>ÏÖE¤°e·Ÿ¶]³÷Õt:’¨ý|+ºØ—½5õž³ÖNŸ›/ÆÕM:Gqf̨iå OƒÕ.¯HǨ•{äÅm~¼¶oqO7Ç¥Ý7w÷æb0ŒÍ$žiy¦AôBf¸Ì¼RÍxfåµ>pÇØ4öDfl,Ò}¼{ŸÆ=%MhÊãì5”̸J¶»¦ –[VJñ=u™Äæi(Ð ŒÖÐÙ xÄ™‘XˆÅ}îÕmißKiÇçO`ØëîK¸ ‚)²äºÍ<ÅëßPŽØï˜a¡²)ÐP}À•³›êVµ9 f¯Ú ŽYŸîBìæÁ¸õpâó#/ã”OOó.8d B©Ä-5Ñs~N³HåKÇ0ÑH¥{®ªuïN낽 Ë?€{Ñx}Ã`€jÅ奷Îl5¶†ß߃ÿâœX×è°ú€+ÛgG‘&þ©%¹q‡,¦°m~ëvØÓbà‘´±Ø[.æ$E{K8×î2Cö¶ŽKÊj›&tGò¶~=’§SÖã¯úI¼˜'”²e÷7û,«ÊŒÿåðÚ­õ<@IÝ©éYÔ-€OÏŒKÇbî?ÁvÌDÀø7«ÉjM‡bTÚ©)CŽwæýˆ£æõI%ÐÃ#ü«eèÐ:Ø…Œç/{æôú\ÍÅr²Ã-‘é“@ÙX~kÏÙÖª›|•$õn~cgï\ZÖ–î9<©÷a³XG6h˜]Hyð4MàÎÙÖM¢AVNî¹ /¼ö¡¨vÆôF•:çÒ™¡ `™yÈuZ¡ˆöÎÇÞRË •`ªå¾õÔˆÛ‡5„Êwše{\‰F=?°@ê5ް›[Â3’ÂjZ¸­ÚÈ«rwûë)PÞÞ †W2ÇG{ìÎ÷½,Õ¥·ŒM3ÂÞMçéóGè<[•÷ÀÚA%“SÍEg¶Ë½®}u%͉ʴmÿ1µ÷ý«4¦ÿÐýTžÎÇ÷$¸ítð¬ÌyqêU„Šô°:Y¼uWΞ ñéÜyѯz3U «ŸF\¥¨UïtS™5'Œ©Ûªjcá¶Žâ Ý`MRÇz+ÞGŸ~ÑZÄý‘cü #õI³µ:&­ã¤î#».ÑôŽvº$â¡ ž]åú':†ÚNz5=DšöîzUð è¬™ÓIžÎŽù‘¸å4 %†÷M¨‘U. &‡𚛟æˆtNœqg{”ÏåŽ;~r‰™cig×k¾SyXØR'7±²U“ñ»ð ¸ 4Kørª†|:çúÅŸzeÐûÛ&T7f‰ÆœW?tÝF»Adå­lƒÈûMç†Ù¿ Çj%ëP¼j¨V}4nϦí9ŠP÷üÄüü¼óˆÿµìEáË^}ìqÙæ^iÖ§kíLò‡-AÉñàRyC+|þ`Û)÷N­ÜÊöbý þ4/ÌK(–·©[s€3ëc²â,¬øø÷*”Žë¬Ðûmòÿþ «˜ÈÚY[1ü;Q˜•\ ©ô}Liògåز•Ó¼}3rY «ef0¡ |\9ei}¦•Íø0—ž°p'È´×Óa Ð#–BKqӂݪí`·óÃÉS—“*+Ìúàyo¢é˜S©JP íÙ·`ÿ¬Þ„0ÒUH[žrÍSج٪R¯™FfˆØ¿¼Ðrkëeÿõ9ójÞNiüX:£gàvÉø/9gý üÿbùßOùä?v,ŒŽ‡{äX,;¦ƒb=Ö$üû¢uÛ ÷ãÛðϰnÉ£³ sÜ顇Eå|€w¼Rã%‡öAÉ%¯I؃k^¾¦=ÎQð*Å¢KHëC¨niäµaÌ Ôñ«ËG¾]â+Òy‚¸P®•-.ÁçæJ÷‚£óÆvÓþ­–[$äé,ðæ8M/\~MÅ&Û¥ÎîÆuÛ¬Þ_¼Ÿ@1 9Xªv–;wòIß«[Ð}˜w…ĦÜmǯÜ_vciÐÞ,þ X˜q§O³äh”pØ1,{N(ᥦÂl×!âcÅ8ƒeo\Íäüà –?ñËz¿ü>üwÇ‚ÐÅW3—v3ÿ©ø“æÝm{Znºèî{sû Î63 ì­Ë8 üF[åOX8M¼V>L¶éÛz_õ¨äü™~Cõ þ§. ÎVðz!м³zÌ(¯8çþÙ¥þPœ,¤=øÌeÓÍó!¨kuŽhYû>Xsdý`ƒÅ‰f«3E…nü`&}9v}^2<Û.™AxÄ¿ù€°ë>¸2O”&ÊŸ~Í;ÒžA½’ÎcØ¥´24]ʽúkîBái~gî­ŠÜù@¾'*u=Ä®T­z{OÁØܩ ´¼eQåûôÅn†Î‡ñI`y®j>˜.Ï­u z1ÿWàÿË¿òëÿPþÿ@¬£þ¾û÷ãp… ±&á_ ÿjâ•Ô¸ìØ©qàx¾U4mÖ ñ0ï3]pÖKqú<§À2¿æMá¸Àëbú­½Ç?¦U™_k«=±4ÃÇ4HÐ-^wdÍ*AÞ…kõÏaç¬oÑÀ¶¢èÖu窭Ks‹/¬Œ¯WÖw¤sAÊ0¿_:Äs\A?æ$•€~kw ¸t¥Þ=áѾMÅ»çùŽ×ÐÙ;*m•½ œå‡œi‡àqÇU/~úž©`Ãý%Üó•â_(:35ˆ³™crú{žÃ¯I$ƒÙÓÀëÙZ{Szk»Ux· ‡“G“½}{$,Pòò‡¡æ´ýt@\°A2C£a3¢áw’¯o(¼¼rðd!XŒ›±«Êa`¦?ƒe¶¾îMi=Û{äÚºÌ}g†?œð¦i›_¸qäSÖ¤œñØýD¼ÏŠí½äJ”êÖ^•^)²¨ Ÿ Oê„Dnº|’¦@×mÙ²î¡ñõ :/p˜9Ïßݧ$ﺹ`g¹©ëêΤƒm7qôL¾`lÞÙÌèúR8¨˜®ÿæúˆ'Èõå50¨‚ygI•Ñâ!Ó_ž‹Ú t÷"OVêÁá#û§Pì£n­BCK7@sRê¥Gô¤}ä¡—‹™/g½õˆ·âàöŠ‚†§ù[Õ©Œ;ÜÒ¿(ÁŒ$zQŸû7âÿ*æE®}×µ ¢,þ92$˜®§¢ 9Æ÷æåÙb‹“O’tRÚ‘¬¥au .œ®ÿ”ïd¡Ä®ô§ž‹ü  p†vq Ê;<[àÃà/j=ÑtU¼îù×m‡kÄkÖò/ ˆ{wI%|»àI™¨Åy]€öâº8°tÓ¹[žhÿ þ`^f4Ûs*~g¶U¯=¤Ý±2¹ô#þ •½fÙ˜à?7ê§°ý ¬)•|Ög/4Ö:ž×\üÈ£f`ß Ô~œ(ÍXÏ)åoù,ïzX’&,„WäˆÉ ÿY ^ÖaA`{icÔÐÞ¥gu8vB\©¸å ª_>vÇé7çy‘ ‡.«x쮪œ…’ÔŽÄ'kßdß: j[.ŒS³SD¬‚‚–´­Q÷ïÝŽ°#DºLê¶Ô+SNnJæøt?x^'Où”³*E–%Èi­„_‚ÿ_,ÿÉWþù¯ÃãŒü}ûá~é° cü›³c[Ø6Ðw¥(öEݸ'HŒ,T¾œùb'æœüT‘Ï,›2Sœ€CØ^7<‘Ç©œâœ²Ã74 š=sÕ:§õÇl7Š|¨†fׂ‚’T“X;Ó[`ÙépØì0SQ¼CßXæ·?`Á–¦sçÔŒ×=¤²Í187™ì£’Õ/`¯æJLÙ…,¸ Pÿ¼:ÖeüKnv`ÏDoq¼S•à¿:G]þöÂ%•Ïe7™-C«‡†v=È Þ%¹~¶=Ï ±Ç9„I•g`¼¥óÒk˸šÚ6ƒ°ÇS0òjÿRÅp^Ü%ûbBU`ÓÚ¦söv×uÀµ©d‘¾·WëÎI¢3”@™ñlmè]æâìß,Ÿœ$aV…ùuØÕº/´H+Ñ_?O£‡×ÕHUÍýû¼‹4sL?5Õ{øW¼“’3ÜBîžÝà¹á3[€‘hœŽ˜q8BÛhìm‰BUŠw 𒘺m-ÂÌ¿ï9¨ûúp”ÄN“r”丶gwËÄ}á÷—ïè{ÜÕbéÀLtHãhHÌ(cØet‘k° ëeXŲÛJäñ‘Ÿb e¢.kè¶Ü[Îfxºj·Ïm£—´³LÌɬt {ì­­éÈßʰ=¼ÎœU˜ îÙË1g£óa1”LOP-Ó΄×h:ôïäþÔußEùÞ6&OC®ú=qI§»\;µö¡;îÄ­Rä°È,U‰ƒµÇDNŸ³ZæŸ &XÇ$›\Ðâ¿ "‡z©°õľJÑn†]¤ºük)í¾¿,Y;¦–>‘< <_Ì_Óù!ø}³3éï;f¿Fµ]=ýÄ¥Ÿæ…Ó÷\‚e´ÞÒ­¿ÿ1•ÿßoq(¶ÿ5ßýûq Öc[íÿŸÃ®gZ€g4ì^"g÷ùÁ¹Y`ü%¤û(L8yÅikˆ 0,¶ß]sñT9ÀÌë„U$¨­Ûµvò óÙ¹_™EBãµÉ°ŸýªÇ9æ³5ÌRžÇJA &¢¹ ÃåØÚ`õ—¢Áó­syÌ’ßé/%,#ÆÓ:ÁLü–KŸúÊ£žíMµHã’9m§¹¢ÌŸÐæÅV<]æÝ1Už¹“Ó‡mº-ûæ%ïNÞÞ—'çØ•ùwr„ƒcfâ84$k Ë2ëXOPÌ0 Û\ ±eË©ÂÇ4I¡èÍÓ= ¡50m 9” T4ÑþõÑ•Ptr†÷u±!ލ´9Fmäc;<Œd2^¾ä‚¿OHÍ¢zŦ¨'üÃ&}0Ê»ºRk€ºl8^2l¼¼Òœtv6|tðÍj ¿úmrµ.SŸ„üfü>S?üsñ¿ÔR|FK ãˆ[ †žƒÀÉšíÛñÌBÁàËlmÿôˆÉ7DäJ6?‚ å…ãÂÄÕVª‘ƒr?^s¯Y•ú*xvà¿Ãßü†tÖ<õϾd=šš §©ÁÕo°ØðÀ{Œÿi·-AAÓ†©^qünò=)Ô™Âüü·&Bm+…ëU»úKwA½Üñ†ê`ã£÷#þB-”±ÀßE²ÕúÒ «J—œ=*Õ”PÝiµ×æ© ì8» *¿ÝÃMùë…NÖÕ®v|¿˜ósÚm“Yá¾ôdÆy,j[¹T.Áî7f!ÇOÌN“¨7`¸}Öt)uº,è|ý)ê³ÞÓ2nM€SC•OìoO{t‚E†óA²‘ô@ˆ,]í|S¤þÐ!ð‹Wïá§ ‰N_²{“oVØ‚t_ùézKk^\n|;Óx@¸}‰äLiÎaƒk*¯S®VÿüÇRþÓ~¿É±÷ øý‹þ]†·óß«õ¡ÞR0Ór˜Jȉ}/O¸×K?iÃÊ¡\pS©öÑ Mu˜¸§ñșݗ÷&ë5Н÷³IŒ²·Ä#ñéóáÅ©ðV€c/¥“ߤv6©=v/ å0 ù¿ ØÞºŠ†?“ [z|ñ€æeöàDS=Þ­¦ Xd¡'…1¦D,Àì ¦9ú.\Ðÿ(ù¾ŠÎÔROß>ØoÞõÛ}h"\>!ÎîÙûòÙVQ-ßШÖÇ´§ 8M²›ŽˆÕKÊqÜ—ð~£½‡äb’ÒÝv&'T‹Šï/5—ÚÏ ¶^ÚØ}4¸¸Ož/—Sæ‘ e*Z͘eùLXÎ'öm#å‹ÁOf[zõíÐù]\À—̨&G¨œC|¼¡o@óR8íÖ|(+Ù³ùòž{ç‚4«™%O3ÔçÓŒþªv‚ÂÏì{#1Èíjgmp/§6‹[ .eOS ÃhõÔ:ÿVÀ| U0zó‡2sw²Gùw,v,“|wÿaÀ·šàG§x·KC³Ígê.ZñÄí¹”Éô`mÙàV'°i”óàÙ]#Þ¸¼6r]]µùs;Äûkæ<‘½.2”šVí4÷£Í“Rû; ´%Sö4¿,,î⼿Ú7"8ÿ6øJì®^z…¯Üqèø3üWdf¹k Ìa|Ž·)”Üg›õÊÝòiji?âï)6øÇµÌ€£¾ËòÀ#E#à¨\éck.ÀÍ.lÃWß^`¦íXÖŠä½vé6<íLS° Þ\RêŒù,UħÅtùÎð PÂpg~t.+Þ(U;@þÜ.åĵR›\&á»â¾qŒxz¯zœdQºÅ j]ʂ޶ëyþügN2l±îo[µ~¤ÌjL0k^º/sÀi‹kÈî³°`é”Rh*œfïÉØré×à?†òßðÛ-Ž—Óß´î7 gÆÿpưð±‹Raêã­ÉÖÕ~º1T§£`{B?`áé”È L KA/¸$8÷ùÚ§¼wká›ÇªroŽp‡,àgœcºoÁª]o,yžK HSç*E™—¾ÅAQ÷Ijw®Ø,†dŸ¥/(ô ÝðÛ^ ù>;Ø)2 ¢=ÚÝ>çµH[M~`K½´âð1Á¬uó¦Ð?WÍ_ÆÜm>¼ÏwýI¶‡UÏÎêòòNUušP#xÎ5+ÔXÔ™ÍÕ\¶4¸\™öãviø¸ç|³]ͦ í;@n/l|%eT­IÏ>‘7— kËÂîó–>y†É©;á%§À½—<¨Ð(=iЙ÷DµJ‘ïRµH½É"š‡'VøWš4®5¬Elº‡Ñ’ÔÎmÃNúŒP»Ó¸~"S"õÊU)„fè¸Á‹ù2WõΈ\Q,½ìÜß´E¤7³zíBþÝ9š\O( ¹_(±Ëf²Í—´ðóÞ‚bú/B¡ýÕ9صéî½–ùkI~R®áA©ŸëJi±g%Ý} ¶r™Ñ¾j¶ë-žôjSÎÈ®ª†R'ûšÙŽ^óÛ®Pekn@Oïw*ÒbïQ¬õôuиoa¨Î™´”ùüøÓp›\«DÜ 68}ïúDÓ]Hâš2Xî]Õ°–Õ'€*g¶ëàwAì`N.óÂgÏZ'u ¯ÒÒš}Ýã‡äJ±(æyòG€O1ÆÓÀfÑ…=Oª§°/ëkÇâg€Õ•Á Kü¢Á}EèM€æ¨ 5®vô©Gá¡§°n­¶|ˆI”C ”›¢îz%!yñf\yBQp•L!?žãeî©@JX¾Ì°nvâØ9ˇúVMdkNöìê ç)‰u°»¥çù ‹±í'Ý~NUëÄl½ƒPÃuBHo ½·nmÛÓ %éÂÃ>X RàŒ¸¤ˆì’ý“,Nè-~ïèïój~€Öþª4ÍœU©y¡A! ÙæªM­ vòß\èˆê}±|üô¾ò ï¹õ’ôsÀóSÑ- =ëi“‘’¦k¾lÁ¯à {æÚ»Ù6/;½óAÿYöÃð‘ ùè/svm"•Š„“ÀoÕ¬(dþöÅ cùäë®8[d:n6Ž¿ ZxlÍî©î+C뜦UÞÏYQJ-ëð«[ ÇK²KÏÎOVo–’éLó0IªV¤HlñISºÌ!Òöf“¹×=¸~!çÌîränîlpižP^º'<Vß‘*úÿøÿ'øÓÂÏvU8ÝÍTT}dݾMKR²{9qÞÛ|Aö„d³u£H¹Wï t{ò*‡F¿sÉjŠã«>{`Jq©vÁ$íeq[Uÿ¿´m_ômø<„×uÈ'Á'§WAÛ _H9.Ì¢µfõŽù€åÚË_ê)´|¼´D­©#ëOðWtw÷)/SLŠßi5òïf¦ì9_£ÕòwÀ[QÐâÒÁ^a@óu€gÚc@¼ï!¤ *ôç²~ ½Å„…¼ê4Åê¤<úh î ?ÁeiÉÓ½¸6Zb~že´t*ù4P÷`ʹúªÉ‡J–H½sGæ€ßÚZÙ6/4û•3BbW†USAf®0¿égµuã %ûM (it|߬µ òÜï×þ^Ý[ñgíÙ …zÛÅm¬Ýæ_¶ú¦‰l“Ó¯ÁìäÿÊï68nž¿{É¿Ýø-mÈÿªÉ¢^œæÃv¦^kê}ÔtD6xÑÀ"ÛýSž9ãÀ>}±Åè&¤––O;ÃM‡K«ºL¶¹jˆæ}ÞvàÊäcjR¥è'+E©%íŧQ`Ÿ]û›…§ô&¹Æ3¥÷Ç\p`Sïƒl¿ûþ-ìšµÕ$LÂÀÉP7-ØdW«™^ÕSš-Uf&y$]»àáÛbÒ—ùŽ šw…Û7Ytïǧ)4ÿ#мëí`K`!C/ßAÜ`Ößuuó Òv˜Í„ÖT<Î]ó‚¡þÆãæÕ{¸yéZ)§ÕÓ'×gï[RQhwÔÈäá G²ætóºÁ.fÊBÄáîºØEg[/.läüEø™üŸþÕfè‡ñ_úÝ¿‡§{ø¿ÿŠß@ú_ýêÁ¦Í” ì<+±ècõ­í >.vxÅÈH~dQ¼¾×–ísŸx¬æTÛgŸµº{&*¿¾¡Æ%NO2we‚O±­. ¦ò¼‹=3Þ(½¹egÀÂíÂs;’)î åO²òŒ”}™ŸÞ\¯ié‡>M7‚,cÍ£0”bÎ’*ÚËãm¢§Þ¤ßÄ5ñâÝxž@¡ü>j¤Kz!GçdLçR“0¾|•{:dhN+“|ÙŒæÅ<âŸy­fsÑF®ããA½ØŠ„uÄNH•$¾7Aø“‡Ø°E-ÁÇüä`©Ôä´<õ ãô xVTÕ'öTƽÑË ç°š£’€FÁò+ží‚p5ñó®„ëBµ5’EÐÄdf­­(Ws÷¦™Y“ Ž5jÉ• e–\[S*ðqŸÚÍtš©l«7ó™ñfO_%y™5*íý¦÷Ï}ç´¦þL {†‘ÉSæÑ¬ÍÃBs?á›Üsôª{ÞY²Qj" Lópjàá¯X°ŒvxO4 /L9í{ÅKõ լˠº™×‰¬¶gaÛFZ=ØD­ …CßM žÒ‰ZO©+ úòÔ¢øÂ–›ÍKÚZ ú0,˜îWÅo¼Ã]ÃåÞEÀ³Ã탢Vê²KúÖµ°y¡+ŽŽþÔ+Ò´ãûÿ©ø«‡Z‹\)ƒ#4Í”·áîL‡­’"2ÇhŠÅ—ðéOƒªƒoÛ·¨§ÞV(“› ½òÅäg(ÇíÇ›äêe¤_ŒC6Åæùfú€ Ó'µJóRiq@͕ڗ’Ä÷tÿq^ŒÿÙH@Ù°ÿÒ óKç;2]±Ç³nü)þw½*¾å»|—N…¬ô¡ûFÑ"‚c‹?KþKMÌ`¶OV%„|Ö[%4NéË/ðРÊ#Ÿ6øæÎ}½)rÑáâÞä¸Óu{çñn ¬†[ï4ŸÂFê&Ì 5{ ¼+óØþþº-ç.šzÕƒc½,äÅ\ìë/æ<³'ãz¿Ì'q]ö»<1VÖ­)3‹ß¡Ù²>6‹®(OÝbæpsRÆá‚ÜÙÐWãIªMPé(àpù\"±®6]‰¥G¹’x_Ù>[EBþc&ÿ¿y8¡!¿}Í¿åpðýÕKØý¯Z ½ø ‰ÂÂŒÊíaoCÖôR3¬2c%f¢ÀQÖ¡Cw~6$`i¯XY&>o[SND¨ÇC:Ø0ÿb¿kHøtßÐj·š<ƒ¯‘ óìºòk¡Ý¿,?9ÝÚËÌïuíc€=1˜w#þ>z§Ï¯Ëßéð ‡fޝ.³¾ÿ¼ÚsêqÌKß›zGs÷&¸6lx±5 ö ¦á4n¨'=ºÊÎ&Áióë‚.ž\+ö÷Æn¶Ô•ís³™ãA»Àƒ–?§Aç˳’Á®À84e\Ü´?)HFr¢½hšYɳ] ¬uÎqœòø0 dçµë?‡-" œeÇ|¹i¿à‹½SDT«û@€ï ´}­M~³:‚{ç‰5úrqÕ­†_}æLš¯.¥ÊfY³Y®ra¢þkt}ÿD¥Î¤8¡v£iY+O#SÕwÒ-ÞzûMÇ$?á÷•´i§ÚvÇ .“½cây”v'c µwUWO”íùݼwÏ]à¦^·À±.^2´ f(·@!uÖÖÐkÉ ¤Ã¨ãáŽÄIòêS~]àÂZ6Isñøwpl“¯ˆR´“CiG•ä¯ <é/;ÎËûÁÆšhk¢s+ãÃv›ÿ5aŽzò&@@çTÅ2™bïcPr–=`_cOÙéߎÿpÉéä+mš“þ™ø¿. 7ì˜{ÞÒÜ-°e@¿V>Bþ)ªsŸM­þÌg%'ô¾wΙh:»Ònn?·c{ÿo¦Ÿ¾ÕÑpÒ²Þ=!Kt¦†:;lzŽ>?<ý_ñ×êë:fÝt#ÿ”Ëà•¹[=eÎ!(ô»Rq^ùI æÛ§®ßáá˜qNŒ—oÞÁ6óåò?Å]ú€0€gª1ÀÒd©iÀ'"½è¹>sLñ•ÿ©×§ê:¾ìq.š +”+æÛœT Fá0ݾEò4Pþ$M‡ .Éqp2•7Ñœ51Q÷ªkÛNÅÇ·#HëD>Ͷ͑à²â }õð1®;Ú¥åR‰Ìfl‘˜þ YµÙ!à¹íré›#_„ÃÖ£ÉUsN )ɃÁµ—’ÛA!;ÈbNZ¸á É“³m25¼†}öÜ?„ºš‡û~‰ NµÑ/ëž-¨>K,üá?VòßñK-ÐOÿ _üûïAÈL ¨(•ŽQK ¡T !•FîSQ„TŠx;DÓ°i %Ólæ‹ß`ÏPÅŸÇþ س€é#7zªe…QèøÃ¿@Ág¤Rˆ—*Ð h,öT¦ð”JW_Î3dô QÇÀÎÙ#x”¡Ä½ø¬c$àûcŠ·ßè!þvЏä1üØ‹Iv YFo$þÆÂFü|< Å7B'3¼ Á·…’|€FA)LŒ~*A)€â›:±WÄC „†1Œ“¯=ÔBBGd_BE&bŒÚD#†G½é@%ÇÕ—9ŠMô(y#dhØÊè÷Dã»b"dK‘âKàûÇî¢ÿrüs}¿#g„Õ`jñijA,ðÕ+`iØ‘FÎYÄ}G¹ÃþŸâ8þòåÎ!FØãÜšÚFháÃ2È<„ù"xý3üQ 4Œ*ì3ˆdì*úþT›ß?•ØÉáŸçOäÑ©ø´¸5Œ;tÖOTÜ ÀŒ2¾@1üqŽàö'”µ*~„ÑáDc`·ãó 4†?î`V·—#nã>BÆîpcøáç`Ìeà®07µŽdñãþé.Œß(B'‘ÿzüÇ\þÇÈþ³ÿ¿büÔøß5éýÂAøï„OC H!Ô}j€‚ë 2n &!âTÇ\ià=˰SFïÁ_P”¥«pÏÑ·-¥cq}Dº‰Ä]âG6VÔõ5ÌÃ)Îa€ŽêëQO›jýî ÖF Õ:fÔ* .Á#z¾E}ßO?òKEÁ>”þžg]Åþ¸þý¡ZF&* B#éd†u w± ‡€Bpæ¡Ü+À2:u¿-œ ÅT,&›TŠU”¯BÆ.ù³X€#wQ(ÆùáDS%Jq˜Xà$y„Áˆ+ðF:÷ùñ“ØJøe,FÁ´±9Œ êÈ$èWeK<ˆkV „°ö@fíß?í7à_Hû>üÃõœûž"þ*ETÆhÕç2nü¬³ðùþÆoN ¶Ü~ÇŸá_NÁ¢l—@T¥×ÜÀ³ðÇÑ"ârìMÃáž dø9þø¿/Š_Çíc@Öøüq?£Û? å±À?9‘FÆ3ƒ#7b{ÄömÁãpçp"NÀ‰¼¶ÌîÙ¦n±(ž] ö?’¡ZÆâ Œ&”âLÌ›Áö „G€M@'"}Â^âO{s₳sÀˆ,žk áØã?ö¦0q®b*þüÇZþÇÌþµáûãï¼Y áäã);”{L‰ 6žÈÃ3ÚØkOÈ9~–ÈãÛG`n2ÙéOc9›ø[JaE xî› p]@„ ¸FŠRr<qLb‰L(aòc–F¸EBü¿ÿpA&~}­ _ûÛeâA²[èÈ<ø÷+¿i|`yæ,K@¸Ñ˜L'’’T«Xô†€dæwñâ÷6Jù,¶»pL¢ŠPÍiÜÐcGd&‚«„fŠG1¸€ûêØþ }°¸Sî@ Àü~L!9‡0O&BwöG•‹±€ªZü-r§áû9&ˆ"@Â~2KÂI#™WA¸ŠÃ5ŠïŸB÷Fÿ…r\Î /¤ô¬8Å“Î2šV±ôß|ˆie³ê?" BÃŽú-¬í»ð³+áÿ’» ¨ýw?šüYT®Œ¢\Ȩ-þD\NäÈ)€Û8,D6‹ý9þ–Ñ&bw"ÜÅV£Fóþ>¸½G)V±ÈXá_à‡Ž<‡çXñľ¾š<ìÃ˨>¬  Vpðò-k6/òïÁÿdðH¦”ÆQ"®>©Žß^>ßî-óJF÷û‡øÇãù~šq*b†ñЃ„ÃÍáÀBÅ”á­bHpËý þ0b.CŒÇ¼ Oß‘(ú{ü1Æ׸=Ic„fäÈ;Š»ÑDÒlônÂØRhþ3)Œ‘䀻/óká¤î…¨Å£„ZÁðÇŽÃ=Â÷Àé@/¢Z‡yl)2›;Oóô%Ö&¸_OaÜ”õÁ*R`Ü2‰ýø±üþ?[ÿ›ñ÷µ‡¿jü᎑±åâêãƒi<<Á6R g¹û#I@*Ѷ7’QdµêâéÊ Â+lÈH¸áÍd=L#²U¬ ‘N?¢v‡]±ÛWÄ$´®BÈÊgè£Úõ_ËißüfªMÔhz–PöÖ‡Gb5VCük-˜ØÙ…ãzSP£±ÆˆyäkþO£Ž<ãæãóM|YzßËùšxþþ'29˜LCèˆ9W' ¼º ÇPÌè3XE¢%Lw "¹Ø¯Jâ!©>$'±š¨´=ÙË1¾éG° Â>1O wehÂ'¨x÷†OÐHF‘£Ø) Sl9d¼çBö-â_Û ‹gYÖ‘ÐìÊg‰2®0‰ÍFf2~þùLë±-wýCñ''0üE^–v ýé+µnðu³¬“6†ˆÿYÔ>œb™€€Ò¨ýÀT–c ›h:…áíH1ÉtVá€2’c#²ËñäÅæ0âᇷàë+x_~7Þ`A8äxW$ÑD€`><þ/Ò`D°ÒóØþPp"xa4´Æý{aÈJ¿ÿ±–ÿß?þ‹šÿ¾7€xAñ¯£ívñP¿ª q Ï+}­â-ÁØe’k±‰¢¶þÒñÒ 6 Ïžb÷àfžÂ@GÕÇÈ´ToÕôüë:@ÚŒ<Ú÷áßWM>*/£4ŸÑË®~Œ¯êFÛa¿ÙН=²d’?Å÷[HøCã×H_% `¬pÁŒÆh‡qñë¾ÑñÍ~(—4‚iSk"8#Zÿ=põâ®> žð¢öݺDÃ5‘õð%’wÞtº«½I)ö£\ Ý( ¨Žx×9¦ÔK£9˜QDôøÚ£þ]©a²¢oîqЭ£ñ(,ü µˆ§W0ù{…ô­¥cÊ`48´Ä"ì4í7âŸCÐDÒüÇâ_4²‚ÁE]šäÿ/=Œø7ý~k¬ìÁ®?ÀÿBqŠÀ›äÏbäx©ž¥§!ˆC¿ÑnŠÑMptñ²÷ÏñGGßLVfžøª*«ûí_ñ/',ÇXàï›OCGêþDï?±‹Ð¢Q⻀4ƒe†æÈþq·ƒî³RÿD³ÃHë?BàïGØB\ôðH%– ù_óÿ”pˆp3…¶Q¬4Ý8þ¸C„w*ÑȘ°ÓFQir¿ÿ1•ÿ±ˆÿÿn†ð·¿qdL¹AH7‰ˆ²ªy¸ x¿Ì×êJ©"„C½íØMv Ã~¼ÞM‰'þO{×þÜFu…ÿ¹˜@ÂL=”fB vü’mÉ–´»÷ž»»zû-Ç´C;-™´åHBøãz¾sîÝ]+. ?Xr4ž"­öuöÞóú¾oIÛ„FP@ÖGñõÏ_4æ¿íeÝ\£¯úgf}_7+‰+ÅÍnk{ U±Å€+Bë3½àJÞ¸<UWônÀ¯­C51ÿ™¶É¶Í¨ŒØ©v é^™Žúõê1ø@™¢ÆngQ7ɶº ÿ˜WòïZ=, RW&–…ãzcó¥µÿ~VL§I}Ïi¿w»§ úSjw'‚›Å^¹ñæùöÿ™–Æfù”sä§p±s?Ûå»äûܵÝ\Aº˜à冂…žcT $µ’ _L ïöw޽Û,ìÿ]*gá\QùGAà~&éøß%ë{¹¤à†í½ ^ÿhаƒBå·†/vd×Hmºtt4xí8 )Nº8#æ‹À'Û°#4„󟹵>_‘#Ø5ùÊèBì?Óñqžåÿ½~£é?^—/ò±žî»1s†}„ £Ùe,½ví ëúÙ~Ù¹³ÕæŸ6ö4ŠG…Aòlû£÷g›o€ûfÿsÒ¬ê‡Ïþq'e‡Àuq½×\} ÐäáRœ(ò©W½ùeûKç¼=PV@„©Ðúí¤ýãœfaÿÏþ–<ƒ蟬hSZð"!ÊäóG"aûK¬ |€Ô—þÑèH»ûloì,ó1 Àh¯ì>TÌ­dú¼£µ}¾òé^¥È±Ov1êýZf÷] X¼ûÏrüÏ ÿ¿|NpНËvòQ&`væËw~#ú×ûC…½nC~J²¤6êøxÞÙõúgà“4Àƒ5=‘-ЦY¨u‚Ê!0;tIò·Gé—J76ËýÛnïµÝJ^xæ¥^ _pç”’µã°véJ'¡ù_QÿEÆÕJõkt.Ël0d§ø @ÒL×h}ÔÜouœ8“úz¡T;”†_Kž70â–NHæâ«|ög7øj™î ’Í{ý›”Ú¼þ£½&Æ­!G ®¸OÚmˆÈAl÷}Λ«Ž‰å½òÁCÓMêB‰F{y̧¿:&r• å(—>o²5Âq‚QM×þH’^^û?¢éá3>|»z¤‰`‘þñ7û!õò[àŒNfóëçÙÿûÜܹ_{b®¢ÁDõ!¶@™”þ[í¼K""g·ú©ðh$Mý%ûׯìæVÆNyùÖ÷‹Ñ ?kÏÂþ?t4ñª?-nAŽP¦\]´Z»Î6ò>¶~žQpž”þ €X`éÔÅ+'Â@äub•õb€ ^˜*1]ì%αë8C¦¯Û\MßÎ2¾˜—‚ y-À¹‹±ÿ Çÿôýÿeó€Ó~sþvvWDbcåîÆëcH‡æ!ú6n\Uªk£7v¢`q(Y¸'„àÁ˜¾”Õ¦åõ¯y§à~•¹Þ¹ißÄ¢Ñéôwé ¡eÜ2ÈFûζãÄU&~Eý×D=¼Sþ˜&‚ìÈ×î’L^ÊC>“úQôÚO NBéhuÌã¯å€Vz‘qjr©ðø,¼Z,æë? Ó)¡öÀÞü³Ê—츨µìÖP,éàWUÊLUzˆTuÃÚœÍt‹d™¨›¤¾»ëÄöÎþnÿ_cÿG¡  ß$+ã¬Ê % Ÿ!VÖ…¢ý‡sìÿÔ4v“­aæ®<ÁÅ›{,wéTóaÛ°û È=ß›¸çØ‹“ó2ìWS¯t‹êüe°ÿýqPý>–¦ûZ ¤@ÝX;Þ‰ýIi€V¶–•²© Àªè®/œòv¢x$NaDJšÃŠü‹z¨ h š °Ñê‰ä¢I„I à äD\©+dÿÙÿé{žßºÿ¿\WÀVZ|v›zJ öA±'!ÜGEoËõen, ¿ñönБß$óSƒŸDEÆ“÷âÛ–IÂî¾îŸÁ³”-_[LÕ:j¤ˆübq¸7Ùì­–~ ‡€aW;”/ÖÝPþÂËO红‰»Å´_nÁ6©'uã¦êÇOæ¥&­{‰¦R¤%¥—)ITx"ÓGŸ&© ˆÈÃj»Òàùeãtð„"Á Ù¥£Œ¶sº&`z÷ŸØûä{¢-"§µz•Q<xþ¡¤mž „6 1”ëAäDµhà¥ÊVŽœZÒÍ‹$Ñ^0»Êßíÿkìßí¬—ŸçÕþ©«2Q?€Ð†¾ÝxûûG™{E8îÝ“¦žä/ t¸ ìê¡$çêFìÌóû×ÛÞîoåPšòFmÿtìÿ}ß•Ò?>ÝW½ß¢Û®þZrwÞµaû;ÕEˆ5>Ñø[h€ðóhÕG9¶¿|¶Î÷?ððA>ʉ^êÿ<ã®P IÙà ºjRWÍ4?À„ ‰È…Ýi=½ûÏnüOÝ]&ç7«×T®Á‹ Þ†Òµ}Uô¦ ŽK1µºÝÁw^gLP¸v›Ç& [aþªþGÐ. Â^(ø½ÿ=ع½ð0Èùª@p*GNx[ïÔ\±vñË7NÅ7IÓKhp"àÊuÎÖã^Yÿ­x×ö€ðYá¶›tHï)y‰IÛ½0Î4ípéDðFÒ÷ÝÚ4 T¸K¾‡¨Bâ¼Þ­é<~˜ê[ÿ Èß÷!¶z,»mõé/¥Êü‘”ª#z8×T/N¶hRè@8EÎCÄÝ{Ÿ.ž¦þÔ½k¬ïpþ1’º!r¾¸ë…‹¦kÿ¯vnø²Úÿ/ªÛ‘½4i°tWáž!‚—§h 9þ»µ0iÿŸÉ¼ýÀ]y׎Al³Û#ûágTÑ~‹kGixT¨á¾ú<ûðÉÓLš†àÍ9 mìZõfmŒÿÇ.¥²Õ²xfPü¤ö˜€L|žM+4@@ ¤ïžÙ¸µ#;4´pЇ9…„0@D~“¸¯Îß&•Èâ¸ûhîmz. –¢RîÉ ²ÿÌÆÿ´ñoüW}MFa‡Û¦¨Žƒ´ƒi€‡Äâ=¾ã½¢iw/<ä‹ZÛ{BòÕç{e¾UhVs…¹R4.ØÀŠ@ö iÌS÷kÄ×ÇŸÓ3ÝÞêx9ëÌÒ‰k%ƒr`QYú=ƒ¾A‡/L+Þ‚Wunã«Èüжh0hîÜ-v=Ñ• °¥ëàâÍÚnG†4’åùj¼\ë/Wð×[£ ræbw\ +åd}LPá«j£¾¯ý­YdU#¶’¡º,ï6¤Zé´ÁzIª½@äÙ•ÍæÁÄÕB  Úg*Ï>û¾I]rõeµ`€ùf‚ôÄþåftì-•›à_l ‹ÿº>ibç¢û)9c_}ªw”/ðù[•瑎·Y{®ýbû» ——;õxxÇLí¯ãÿôó;H¼Œ®]xz…µAÝžíßâ8<©r 4@„¶OÜ“68þ[K`A(2äd" Øøú?Ô¤.gEؚœœµê/á»èÿ£ÀŽ$î¢ì?³ñ?å×ïé¿MáB¼` 8áîŠÈg»±TM*ãLãb}2¨EÇßÉ£B”’Œ¡jVÇixø‡ö EYÅyì7yÞþWÌ­íùûûÏBÀÜÄÿÃ"☞l½ß)S¾bú.à_¾¢ÜÌó²Ü2C¿b¥ ,ñµ ¹aõ2ámÔ8à89Ä÷¡Ùçôúc H'l?ñûæãOm&äÊ“¥èH`ª3‡SñòÏëH¢×ñdPP¹³Wžðd³¥‹§tû3¸q4<øßºïê»áHx¦:œ;/rëÎ¥$¥Ñ`CâÄ¢¦†3›\à4è¿Ø8ͧnÿïØbôúËiÿ‡äÂJ¸Û_:éîÌ“`ËÐD;ÀÚp0 ”oÏŸµ”fwNí­¿;;÷×lî©£7¿L»ZÑEÛÚn »*ÏCÂsϵÿS}ÿXvÚþÙq3µÿÿaûÛ ÂXE³jÐ"‹6d`l1ÐÌ®=#D ͼ#O+H`›í¯ã±„’Ûêûú?IРé>PwäZ[°¿($ž4i•ÀêÕï.Èþ³ÿÿ{ñ69À¼Vxœì½w\ÿÿ?®e•ÌÒ@Š”´”QJih)Eiï½ç×ã:ç4N{ïRÑ$JBƒ$TFV¢DEÈú]×)ãýþ Ÿ?¾òò»½Ÿ·›«só¼žãqÞëù<Ç ˜ÖBôHC§·Çnqùí¢pIÿe'ÂÕêH}¡ ?:›Z—h¾§=4¿ÊZ>ŒXúÍFOw?x¨¹¼–ºk™õ–¬þà-,¢BE¶…Òd³ÅãÀaÑ© ¦5$W?çá4Óê®xÜ ›BtãîLdMö¼¡ò7_uk[¾sUï@º°CÉeäÔüRu ayèËâžrÞVW«=zé SñË™*!ü›²¹œc{¾æ.Ùý‡w|šyBbêV2û‚ý~RÂbí|Ñ»^8íÂÌKµ½+t?¯ŽòÐI¼ Ou×ÇŸSü<¸dÖù’g@6³hyÉr@9¨üÓJ.Y^e<<ÓèQûb ÊÒ_X¸HÕëK¹^)è¼·v'ÏÞ$°©A®ÜݼRŠMübϘïÜwhÔ%ÈÝì|…l¥,’Ò?~2AaeŸ‡pr¯ÐëW5¶ý,«dJ%[ç¾9«Í7k³¥©‘ëˆüÅá%°ÂÎR„ËövC^[ã¶‘9á!÷›A‰Nß‚èôL°ÀË­N¼©ƒÁ)7~l³õË”*í~0‘“¢Ô¹ˆ>§ãänß0ÉF€Ü¨Œ¢ {l¦hÄ)kГÌhK( ˆVŒ×µÐzîÈü!BmÑZ=ÔΟw_躻Ã;!nO7Ÿ°©†Y>+MËÅ÷-‚ûtãïÊ=^‘Â9ìýøÛè¿Îôš Î:'Ê/‹Š<Öª­ó³ô—¿(™T¿•#Ýð5fÞûÅY«u¼Ë2-U-Ué÷ÌS^iežj Z’Ž"’Ë4Ž›Fþ2{Á-@P—Ý»ׯ;r?þî-1˜©Þ™ÖìpÆd„©Oýúî¸Yõw@êÝ“¬€n ù¬‹ü€ÆzG ÈØ·_>ÅQåç=xõñÿ‰ÿAFÕ÷SçVë>>½ÌÞ W|ÉbÏ¥“"s×™I¶°ˆ=I6ºù¨:úËáÝËÎôí:Ø-^¹R˜ H£Ô@DùŽ ñ{2AñÒ‚a˜Å³¥$ÇT˜s]n’+}[ÜvÉöŽédù"ÝH†ö-¾v‹°Í¿–¹í)±™U%_»KÌ›O¥qÊF†Ú¸žhQ0¿¯ee‹ ®$Ée³ÈÁ6Ë y°ö|ªKz˜f±jk§v¾ÕïÂÿñ?ì7› +îÑôéíðŸ\Èîi?nÜRC^‰¿ªá­µòð'ÙÆ)î}6 …€7J73Ô<'΃'/ºE·?`^~ ÖXÚsp‹Þ÷r¶ä„‚ÙÚ•æ=à¬ò<}É—Ïi> :sµìabç9ñÚŠSpŠîaˆ‚6Ë€§A;툉毻^="^›G—Ü yÖÒ°Ñà3抬Ø*9¥…‘&‚ŵñÛ Y.A¼0ÿZ!Øñê $žYéû (ˇT¬.–Ã!wÀýˆ#@Ò©M[|ÏR]Rä|ù¤ÀÄú*löÎç½vŸj»ö)ôº}<{VE»+4B…žò¯Ú;+ÖĆ~lÞ˜ñQdÞ> 'ÅãX?oÍP–Ü>÷Ê>­Ë/Ú/s<‘¿å#zç ?<Ô>Aqʺpã¹KÆý«ÝˆWbwÞ6}A[÷×¹L7Ì­¸åÏ—C^^ÑêÎ^¥ýᄾ•Õ¹=eüº¬›úÞH<¦Ò µö圎âcÞð¥As0Å([}'8;u;]˜}Ûêj ï‰5ÅmµÎƯï[„À„†pDÁ–·êTÒÎ×V6öê—ã(@y[÷ Rí¸éñˆ>±@Ȳ¦ƒ^¤É-DØÄkéÜqþ ÊÓP`å àiÐvžè}-ÁÛ£{-Pk×nþš÷û¯’Â[Ž]Ñ»7ÝøóÛn|šåzœq6û ñwNö°«²\ð4Ê..…t\ïþ¢¯UsõÜž'nåæOZó|Ù#oYÃwÀ¦Dvó+Ž7Ç|‹u5KREú_ïú¨Ñl Ζ׉ì]¡hö3þ`œyÈ,NM´±‹DuÔ¹Þä@>v“O±[H\x4&—=ˆ@ýó>;uÓÅ4pí=Ê¿ÄAÁI¾<¨MùîÆBºÀp¯½cµýÿá¿à¿³Ì­c>˰ùÏ _ 9v1 åK¸LºmEs¡Úôö28(à;&gâ÷QÑçlÏÑ'\RE=•¢}) ×!ï€xv­¼CÌÊM,+*š`Sg ÊìrA ¯-¬¿t,±ifOT÷*šsظ=R äõ^E×jɘ½wföÈÆ%ÅæR®Eýû`ÈsM®ÝÉ8£ŠDÕŠ–lÉ<„°ß†ÿŸáÿËß`uþçì÷;¬Üß[‰q¿·ƒÐð_T0•§ î x_›{ þÂóN‰“ONœù¬w6èØiÅ,Øv_9YB×·nT U$Qh„Œ÷‹D4>;Áj÷xÅ“î¦D9Íë¨0 ”‡Cÿíã÷e\j¬_ß]Æ-aUoî‡áµ†Ä—*+N‘9ªÅ˜Xמ”ùÄå32o]2‡¦·5ûÁ¼N`*X©Gh‰ÊäM…ìœñ:ñ"ÏÓIîÌãû0©O<^ïuPîSgûËw<”•@¾¢rÎ%&DUabšab]g¶Üð!¥«Uú™Ó&è)Έ²ëò)äèT|ˆfôƱÏËÕE`Ùl Ñ;BMɑмëÜš˜QA}î/ŽËØBBÃM×pyò¸KD»ìlNôrËÁü%hÏÓkï;³]ؼqëå0/§Š{›¤/¿* ;Í$à¶Ì|óÛ¤pÝ. Ñ1Í+ÊVÙçÊF„Øž§Cüœ+û`ÇÖ7>~bnŠÆÖtV¡ó^ JDÞåõN_tS M¿bðÝA2Ìè¨ôÑ‘My6uÐ+lš¼O£µÕ¼é">Q š~ ²y_{É•žCÑ&Ѧû§ÿ7MCN-5}HÛ/,Ê&ð÷áOÈÕŠ\få¼<f†KŸß×Út4ÊD¿È–¥’ÍF'¢BŸ~(dIM5@\µ"øs_îãíÚ‘ ££5à—øç[ƒwÜø¹²Eö³2¢)A =pÇJŒTø§ðÿ7þŸy.»¦n§ÿ*÷c‚B:ŸýÆ:ážßz¸èwÈ1£ó˳V=¸÷¡Ô5dî½j±ºòjÅá«¢šf²ƒŸÛoƒ2`¡5Í߈yqÁqÖEÜŽÛÞSX|æ¨Õiýšœ‘ösíG›Á$äÈúCy Á(ìé[kÛc=&â2¾)y¤Š:ƒ`0r4Õ–òNÖOš}{M癵eõêVTíÆü6·MÐ_QC¨Ë{bYí·áÿgøù÷ÚŸ-ˆ[â4çþñÅ#î÷JùŃ“r€³Ž4È›ptˆ °Dî(ûn‹×ãÀ{q)ÿÂûÁàsö¥ÁBÏÛZ!ïWøÀýºxè¼eóÐ8Žf¿ãX^ÖÃyÃBóîœóÇrÁâÝ…Îû&Xð\ô³ml/ÀN—£@wåz uÜŸmo›Ÿ¹š˜Ï/lÂ1õí/І1ËrDZçôfªÙ¢æ'ölyàOàȈ@í3}ïÍ–0eƒ›„bRÙG¼óV»„SGuŒ8[nÂÑp*Üሎ4Û«QT–¿³kªEÖ ¼!÷ |}ÑãåºʼpÏDÿ _ÜvÂp©ê-Ù~Ö›)tU‰B¬Wc糨eôÞ÷³MF䩱¾¼Oùúáýùë$gIèÊu‹òÒà­Ó>­¨ÀÑGnçEÞ›¤m4ïbRó+¬¢ž±úîEiϤê]—BΗQx(\Ä}ö£÷(§åM`Õ]Àû¬æc;˜/º%”Ø=.“Îóú›¥Û¼Jqµw]™Å±oÖC‚¯Gbx'[æÚj+¬4LˆvNÙ=ëºû¨ß‡»=eŸÊ¤ÆFYôʤ‘¬´îjÔ©Hۖãš·Jíî‹ÛmRš–»_ÍC¤J°|¦0‡¿wªÜ–rØâ@ˆç4ã/ÚE…kfç°®öÝÖ·nÅ¿ 4Á’B²‹ˆ…[‚HAÙ©ú«ò2‹ b³ÕãI^ûqBÛ /],õDïžÂŒùºì®îu…O®7-:øä=ÛGûõƒPtBùþ/¸¹r…ôì’äwóª÷ì%EjpqÞ:²?ôr0€Û,N¬Yñ¼jû¾‰/EÑù™„õ;ü‰¿éÑG‡v •¥[Ô¹ØØ×¿ç,Ü#¸wü!üÿ ÿOÈ`>†À|€eÆ¢Îps@• T½»=õ…^ÝÓC\±1ª ¶¥†î¾ë6‹4ž B;9¡»®¸଩+|V‘I «óÅq³–™µ©Ò®Ë|Ú:ïQáøé±Œ¸ ƒE}·áP¤>ŒJÈ•°h;<˜ƒµÎ_-! yrå¾trC÷(TËèÈ,ÌŸ˜9qÓUúD—Ï6 Õ}u}(aAÒý6ÙÃϨºi¶·ËÀŽ˜±ß†ÿáÄoµ>ÿVüC“¦³»¿£|?à‘üzß’qÞ …™­ I1þg¶ÄŸ;Ãê ä‡Ï®vï×lˆõÛWmT ¶+”ä¾®Xµnñ~ð­UÏ·ÛõY8 ¶Æam¬¬÷úÔÂ^n)*&J;/dž~÷‚ã)Ÿ ªvÒ$Ã8dÓ!D+/»Ò2¾¼µµá?xÖTF„eeI3Û ¶×ö :’¢á~ç˹£Ay@+ØW€óâ´€(Ž’¯ö,°|t|*[Û³‰$£x³Ñ÷íœ7̵#ß½íØ "¶ñÞ A’ÒL/ÐØiû–îÞm,àØY`<>Ûå ){SD1·–ôn²¤$@<ï°ëøÜEfì™Ác{gù.xþub8r!Ôœþø\”¼±ºDª&qa¯æ…b‚ ø³Ü-O>6G¬¿„ÿ…ÔcÔ<½R7I¤cv–?}Ö;z=}Ê3í'<ݵ+¶+–ßÓÍéÒS‹÷AcôJ|=Ƽm—¥Ã¨ÿÜñF5œ»ÿJÓ¥·]Š¸Æ­KŽû">ôâY:øQr=2r7¸´x”=¢Ë‰-¿ºTùŘùð¶Sç€PçlNvD«Pˆ™õ~vËÉXÌ8!¶ëÈ‹B ÉFqßüÿÿ§³ÝR¨ÓÚáßQˆÞ)´ÿ ée{Øf€/[—É7F€_ãa¶ðʾ¶rS²àárêyÑ4šRÏVM¸8 ùtós™«ò¸¼Gæ-kIkJJJÍVxüÆqvÊÚÝà"2Ïà홑KvõÔmIç¡ò_vu,l*ð*p:€6³55k†òô×Ýȳròîçgͱ~-·1âŠUEWôÊXC©qÖz¯~™üÍræ†ÍgF}‹Ù†F¢†ó@ߺ9&n­ë+,~¡AWûŒþý·5$Å­c#Ü@¼«ncǘecèTm„º²¼K¢Gì-Ý»øïÀ.áM°ºSôåá=OæF†öW=ßq Üå{QÄÔ¸ ì’=Š#€áA}oYý={P5_µ Ú7Þ^wïkä¨-#…JÌÍÚ¸°eÉ Ò|uû5¥¯5Ú¯$ý®9Pеž(±Ò÷D&ÒjTñŠ‚ÓB§ð·Øô`‹t$'s¦ŠHŒWóÆÕ—bòß¹¡ì5ÿÒâ5¾‹Ïï-‚… |¼ùŽÅÆ{ÿÁ%\¼g Ï‹½ Q†ê£ñz/˜¬Ö›~üÿþÛç@1~ ‘¹ ²“vc¸ºÆÓ~q«¤x¹$Ž¾Ç‡cÆäZϱ* +õÄò7Ö_ŒêOXèvºD."©ðbkë ò°íjï‡T)^ãÇ{|àIÌ`¶ºue§†¶Lp º$ë~²`o6Š9ëa ŽÑoˆ{ù™ìááŽø-|/ƒ8?‘ýDá$H^pïêÆ-%ù`3pn†VÜh°e:\v Øzo=~xBªã÷áÿ‡ø?mÅ‹;½ýEÅbð?¿ÊÕÿŽrx[ 0])ˆ¡ƒÞø–ÖÚaÅ.€hä—¹þŽÙ@Žjíî÷–æÛÑ£†ºIàx§q–ZŠ­Y{àâÌì,xSs¶uqæZÛ½zQ=x­03䨶ˆnÙgº7³Œ>ñbŸ¦…K—*@Ó‡²·/fÎŽxÃ-¯ööÓ‚H× •1„ Ú ÂgÛÍxý eäRh -¢÷Ò#õ0ŸuQ/„l8|(&ø†H<økùµû¹I¶EE÷ÄÉ7fZ>œ=á9j.CõÛ›•EÒIÎ¥/¯e½ÛÕúi2Ák&;x]q2zºÜ÷Òúäþ¸åw…}ŒÚ-añî©¥ýÍ@i[(:5½ÃüO³B"‡icVÆc£fx&}®«s§ÑôˆOŸ_0g3êaª¦/#pXœVËQ9p{mÈÙhд7˜»[övŵ]iå‹F>‰/È×´kkÍ»Ó Þ ê Z§ÚJÙUψTgñ¾¾é¾†ëñõ8©™+U#‚ž Ÿ4B‰š§òÍ 7Ìpzñ‡;*[ŸÕTJÜ¥¯‡È=×µ‡ö?|³ B†„“:ÆÑcç§ßö³õ¹üúÖ€8YþÁ›š.³"»¢é0`(Oö8w@*Ï|Ñ}Þ/bòÎfÁ}¦ $£ˆ:wð÷í:êMz³b[£í]ÊÀ׫/èlšVü;Þf>|Æ$ۥȲcq§j\é›m)„Ïþ&ü†8|xµÐcH$:à¬Zp8´7“ŠC葌ž$Ìž;Τ#c>Ás{yÍš£OxÊ?ßE#þ€ÿÓgj^©ÿùîßÿPÜ’ðÌȯëÿ¿/²õs‰+Ì[Õ©@dò7•øòˆ°Š$¦ Â}Ù¸´+ijɽѴ‘£r9‡¾ÂeÓµ³0 -7=„ã‡X:KDY€Õ¥á6eÁÇ&é »&]ÏšI¿u|<¸qÛ`ËCtZñ—:|õWúÌG áu‘Eú;Ùú€G¼,ÿüÇ+¹rBgH cËÖ¿ *=ÒöÒ¯®Ò'þÁ«œ4Þ›zͦej¥-fWD–—øÄ/:¼fØë2í„ã’5Á¡}’@³ÿXz¿Ûú¾`…õÁ”Iü1>n{jîœet{Õ6r‹ïÆdÄ-¥,ç0°âÃä\—@øÍ{2a÷¢¯É¿Æ¹í£Û¾cÀ—syŒƒêšIò?S$!~“$8Íøÿ/ü·sŸ+¢C-­["\ýè㉞'‹WIÞZªê‘òu”iLX¡q='‡é‰/|³(éN\—ÛÖ>ˆh¿»¯›Òàd †!5p×ÑT_Á4΂ô±H›tvÍ]˜|pY)þ$Ì8Ô¬GïøÜu­µ€‡Åz믽†X$Å3m?Z±Gç´Ê Á;¢ÂQjm{ŒïnmÚýxûaÓ¤%zF¥—ŸóÂõ7:¤0“ãzØ"V/P~Ü©´h/:¯=hݱ›ÁcëÖÞu>jÝ-½¡Õî¥t†YP~ÐÉÝ ¼B.}Õðhä‹OI|®]óû,G™«öó/™·sÞ(ÔjÇ{ÑgÏrö9Yí7”¼@(òx; ïÙV}ý+l¤ñì ö É‘çùðNàê葚Ö¹%¼Z ŸhS˜{ãÎiúr…¯=<¶WvÁç×<%Þ·Üû¼s% ®N'þ/†Ž»¾Èz“£YÕIïXªÅWš¯Í>DðoÁŸEX¢É‰eÉÝ5Nóf7hqìúTœàzéùíçK³7—¥øŠÎˆØíbr?(ƒ©³|þÝ(ó‡LR0›Tøõ Ï7(|¿ÒëÂÆ†=¼Ús¡5DAáâhúPôàŒ ÿ³Ýè¸ÚÄægÏXOt–ˆ€O¬ÈƒüµY"éèιk—?Ànù‰¬ƒ³Á#h¾Â¯ñ$ǹ6éD [¿×Ýí´fĬ^²fïi®éÅÿ冺— Á¡ÅÉ8Õ§È~É(ÑßÓ¼>¾¿È~ú``ñ6Ø)¹[>,’o½‚*T¥ȳÄ(z^T¿¿Ý%Ǧ^ɨŠf"3ôéRÆçìZ÷ Ì…IÑu×ß¶~Yšb÷Ê6É-F ˆîWeÛ"«Ua§‰w؉J¥ uZ7Çm÷=z\ùZi·xÑ¡ÕÛùÍW>ß™ž™á¼ã¾‘ÅÍË~#þ‚ÿÓU‚þì6÷?½„ú'™2ݽ¾¼¢§²O)¡ÎÎüW=G"Pé+XŒ±Ð>“ªÑjcô·àï!q•ƶS#À—3°­"0jÃçº×¬Xî•À<i÷¬ÛÜÛégü{…÷ìÍhv»mfLFßÌ¡V ’ê ˆ.‰QŒ¾£§q@áô¾Óz¯$€çÔ±àȽ²¢yøû¯Ú°n÷{³Ù½KÉzÔeàp5X"., uWq3=Õ?ûã­x‘²ÄË«v¼u¸øÐ´ª{ù¯ñÏ;³îß~œ»4ë£OÄçøA: ½ñÍŒÿñÿ$oåã´ýÏ!/W8;=Ì ™$aÆuù®Bк"ÚL ÓІ Y‹ÇôøB+Ô£×8Ä M8 YçèÌ›Ÿ6©9ËJêGØ—EÜ +ÛÈ#o¢ÝÑÖ«•÷õÑ`î@U±HþJMÑñOð;ôÂRŒ‹æÙ¼8:Üq.Ô>m•3lÏ~ Nšw;‡`[é‚δ.‹>î °q{©i^ô;ñŸvþO›¡A\“þóÝ¿ÿ½ø„Ó}óïü—rÇ#F8 <¢ÉÕ,Ëë’ž<iO·Š‚ Ç[Qø|éÎ\Ű¯÷”à­ƒt 8•¸Ó++"!4042,Îkµ±ïJxLn_STvoí½aȳ¤×¢¸†ÕªÖì§Dîkÿš0`Iï~Ö³n) XýÎ7c]ûÁHgè >n]ûn‰ÌJÊç£„Ô nŸŽP®î}»\&mV‚ß õ–'R. ^wðí›Q˜˜«-:½ŽÊ ò©c(¹tP—áÅ©›;ŒŒçÝr| ^ ¾P቞.zÉ R¤Þ#°;Tæ²4‰-¿.ãÌ-°±óJ„Ÿ³ð|WpaYX±“ÐÈ|…Téé,ð–FÜ`kt*—39 Ÿš% îa74Œç|fó=­ŸãõP ^P>ï·ÁvF_½Ër˜ †#¥Üi®Ù Cz=í¸¹QÊ<êLWðÍv£„§›1qÒˆovovÌÚœ<` ¥gtþõ¾*]n»O~]¸o†@Ø“9Ñr׃Úcx¾ªœwmÜÍ-£ÁäÒ®¥wÃ"/^OL¿‡‚Ë‚as+3äÓÛ¢ÄFÏÏØIPQýêO ?Â~—†œ·{<%ÉbÂÑæSO˜Ðk=e§fr,2J/"'Wb±#ÿ¡53f1‡e³H¦o¤øh©ÝM›Fü½o±Vûï;zMŠ‹_]@!(8Ž ûÔ cýÇ?›»|ðïÀß6Ñ, ‡«ìU!ƒM2;f‰ø[F9 ¡·åì”Ê«¼&PtQÊ®pDi/•:Þ\Vb‹~áŸs¢öô¨ÍBVC΋Êlf†G9ÆÝI)TÖ‘£  ›[1üÉÏ£YÖõ¥ßP±T;-{Þ#dLâŽ?8@Ó,U;³¸ºoﯗß8.!4ã)lŸßHÐY˜ðküâórÃöºR>½ËŽº°7Ôãµ3ìÞÿ“øÿq‡,õYäË·éVMQ[õÖ=‘dþz#%xhç•Ãþ{>}u¾äT²ê‹a°ÑõÒ­P®n»pL#ŒµC†ÚUsf­wns.}ÙÃCŸ‡ÚöË„Ãáé(%ÌGýB8¾ö Û¿?¼¢sìÆèkß6µˆ›ˆ/‚¾=jÜO‚½V1….*­󥜣œ”÷3aWè:E}ŸŽ-ûA±ìÞ­Y>©1'÷’ðߊÿtó_iº /élnÿmÅ5eº׃eOH‰êx ô„f—Àühé×pDš™jäS:5±xôE¬Õ Aß8vLi¬ŽÞ_Ž,âFйC2#Ä{ìS)¼T¬÷f._¬’€Ô¸WOþÎ\,ÈÓ[ ìà m¼Íôµ?ý¦ÞÏG&òÀÏçiœ«ÿüÙÛËו{„0%Dôðñ¶P³æŽ>ƒ gµûñhÉ5M[o*U9²U:Äãk‡ó£·ªäÐÌÝ9ÏfqEfÝX̵úàX´ŽÖ9 =©MRÚ|ƒsŽ\ î~µF„ºMÿ#ìù a˜du½Äêß$(Òîø$ÿD×;é{;ÑB€xLþ„ d³ÚÃÎ÷â,†ÉThó¡(„ç×ø×*Ø•8^ä»/dN‹ÀhS}æm¬ØðÏâ“lÏÅ~]y=—V “l„èr]€A-}ÇC^t®G°E¦¡)õlᢓÆc x2¿lÈ‹}-mÞ:—Ön„;7{oIHU±ñg‰ULÐÚÛÖL¢ÈÓœ0¶öt×së‹Ü’ƒ[ºŸ(^8ZÉœç£ü~φVÏG’ޱ5¡`:üu× äÔ«­S9­<6¹îkšËŠ\g‚'óFÖ߉ÿtóßqšì É=uÚsÛa!;gMo‡ã„ùqOkoî|ðUf›àðF¸Š.d} ¶·ÚÞ-¤ôÓà¥,ц »z4½\ª›X Jgd1UUó‰ÌlJУg§©à£+ñ5ÁÚ¢)%||›4HÝô£A¸ÿîÂøULûÀääÈ š¯Æº”޾ 0gx!/“ ŽìÉ”‰v‡õ³­G{[npÓî´¯:¶åEÜÅk~ÔÝÖ_+$ÌU'â,s$ç0-}l cì÷Y…ðìÓã-àÆý‰ –eA”¶‰W²…¡Á Ê \ØŽ $Ý]$N"Ü¥{-® AbšÜcœ,²äc/ªxD  j*ƒv¸géÞöµqÑÔõ}ææß¼1›®õ!wµ½‚ZC»|ªèµKuH2¦OÒZ=–]÷]¶ÏÇáõú' ™+çòÓb>ÏñlߪÕ`IéØÑ.3j)IQHÛÙë—¨.­¹ýÆÍÅšJç GZä¤9jåûÄ‹wPY²OV€åÀQCɘ¥Ã®‚d½Êºäk+àŠªôžë·|y˜sŸš¹o¿4p)Žmw¹w ꪇӔb±!‚¬|YAƒ2hSÐ};¥ƒ oZi<Öõpd@TŒÞ÷ô–›˜¬àäZzñ œaÙÖ¯“ÃÌM¦lŽ´ïä¡éas¦ ›ƒÃè{®úT°_1 pÁÓ »–Å â‚^oÚ­½³ú™¦ýþ>þ–yGç€RóUXûÌÐ×]R^!_÷¶âvo‹ºt·BšZï3ö„'¨rªËYRÒ…Ýf”÷7#Nï-ÖVtOuùºaWR­•p‡ïÒw¦Çƒ]__²ï_i8_=õ­çŒ ™~1Ð#$‡6­hwž»Z¥±E:‚£/^à)-xéÜ}Q(&cŽCWÎÇI&ÿC«÷]:æ| óâ¯ñ“ÚóÂÅ"æ¡.NÇp–¬Pløçñ?­õ&WÕ‘¨¹¢”u”+!÷ö=¥±­üÜ/v4´ÇxíqéʪWBçãDW?‘,:H‡ÛÃÑÇÀ|T2 –öÑ.½¬°¨oÚνqIœU £¯…f£=íâÙ·^ A½7ÎÓ ìÝ©Èï§œ^Iôºð³sºòõLWŒÍåvÈǼßëj„ úÙ‡H4[êœEѼ—gñÅQ”ϯƒÏî ±©dþ,æx¶Ò£ ÷ûèâµrÙþZò—>ÌÒH¬Õ;cŸë4êöZÆÃNen£ˆVW@`ü–«P·åúC'³wÚ+K_C\Ž Ô¿õns)Ï-ÚŠjFä wÛV,ÐYúùÁ!ë_]w’¹ Ǽdx{ÍüÍ<ÅÞô#î +´ø¬ŠÉ{?Ô`÷ª€HúÎŒ¤ßÿtòîô˜™Ÿÿ|÷ïÿZ¼¢¦õGA¨TäìA÷ùÒ(Xμ¾i ©i¤ñ|µ;Ì:û&üöŸ<!ÚÛARÃ!êÎs^,((m¶¾1‡kÌl›a-% Z¤ÜŽ;Ñøyfs}v¸(?{Â.Þ‘]g_Æñ DCOg‚ÎMmƒþ+QhY̱6ŸŸ_xK˦yç,Ö3C^ßy«ƒ>úrª†?'¨óm=hIeŒ,÷´Þ]½Ð-;Ï•ùYG^¡æ":²ðr6=A‹t&ó ~!W–,7Ot³(«6˜M¾›'!-…çUOaì5ÿ­ª„^õCpÄ,2ÖOËÒj˜‚gΚpw¯A7ò°OÎ[îܘXB]íð®Ü¤,^ *_±Ï¿%£Q*‹D¾>rÊž`N’ T ?б80?±oímµã‘P±¸—35 Óž¸xƒhî:—SGïu1é‹Ýb¾U9×GÒ4Ý'yÕyé´ e"Qç"äÀËâ¸þ§†–c¨¯;qqÖå¬ ²ïÆê7pÜ1gÐ;m¾3ñY³õ8$¨RøŒÜH­Lt¿€§²1A‰JËÔ?’{€Óuƒ{@tËz¯ETÉ+ᤱu6¹NQ|½NYk˜ü 2u¿ì,ÙË+ÍO£9³Î£‚ÝlËÏ‚¤¦Ö˜DÑŽøéÂ_fxsqÌhp6£€Fs¥*°nõgm*?dï8_ÚÿtßÕ"4ÄþÀ?ÿÑÛ_ž·ßS¥N˜<Ëíž²œG7η;–MhðY\sóq»«ÜheHçÅ=Òë¿puòŠ?ñ 'ÑP±UyÛù?ãã%Ö0‡æù„’ þKsÁ¡§^´QüÊûØÊµþÙwÏì×uÉx­Þ‡ìÛÁ'ÏÈ๑‚nÖLð³=BBÁ‡÷¨êóìQ!à0Ö6ý?àÏ]Ï–P¨@÷QOùš¼Rï(ʺUùÈÿó|Éó—ÌîççnêDím¹÷¡ÍýÌAc¡³eAI%–$äôz±å­™¦¶Ýz’ÆoñÁÕûwÀl©­T‡º9°>S ¶K{¬]á÷꟡®[ÎöêÃÅÎ F§È•)Æ·€Õ#å'Ë„Š¾(À]?éAnËûj(kßç¦ÒK>²§´…ñsï˜ý~ö½lØûì¬çbžwgWÇù˺¿q¦iæÿ4Ä=6rZ:úÿAÁ|Âßÿ?/.kFÈï¹vç8\4)øZ.5 Àf·e‡[)˜(öúÝ£ ¤‰®×Ýhaøyð÷ŽE ./¿3K[j+¬ ØsÎè F É Õ²º'Ü3>õì*=¾“IwAè9ë c;LéŸ\^»ùg~‹8™©ZÿmšÿB+öáÜß@Ó¥åB_Õ‘FqŽ) Ø¾g#ŽmÉ´H24ÜZ½àVÌêáU2—ØèÇë.ïhZœ„áåÀ.¾¬‚éñªºöÂNª·ãˆ8ó\rï¹ãí•Õgvh÷Z,”äêÓ6QÄëµI¥%î©Í¦†Ñ[ ¿l +µçÄ-…XQ_´âJ‘ĺ}×»Æê4êsÖúÅn¾ŒnmÚ™>›õª±B‰Ï‘óNrm2íïŽÅ@êY1ж¶¬Â£Ü^¡KdVç̉rÉõÊ´É$sÊ×΀múµ®Þ_^õØz¸$Ÿ<èÝžïR/‰Z¿» zžbT§Üé»;I-z9 ­W܇ÁmÎgÿ–}jš®{ôîת¨¯z‡Ô\,8¢‘Hß|‡L!>Õ2­{qåíÖi}X™Ô‹^ÖdÚu„ó9ýñò Íjÿ„N[ÉX°¡™æ³]9ê|± .üùsv:ÜQ¬M°&Þ/°[Tâ>KcA ø ót‡|ªÞÖjxš\àWb3ôÏÆß]}hÉ|w¶çv>ÓŽ±wnÕ8hûÖi^ºOí_Ž÷K~Š;­'¨áµ]d•S'E.ÕDææË5ÝZfXtM"Çgùžý¬Î9ï¯úߟ“´Hø”+£¯Lâ„Æg.J:8þÞ›Ngní Ql1¨‚Y7Ÿ<샳掶´—í߯±)Ï×å]Øyì”Gz Í[þø7„CÙ>ûtxOû|bCö²eËÿ™üRú&˜ªp<¿6@goåÄí;ÙJòá|G?œ5‹{ª(±^½°þž°Èi‰Cð¢ÇÉ!tÓaŒ>¶yÅb§‚·ËËS[ÅÀ 3:Õ/®%¦m—•麕TlnŸe ¤ûŒ Ø]:ê‰4—Õc| Nê:8ž„ž¨´qåóKj|]¢ŽYñÜVA¨-qÃN&£˜0Høaá(ÆEÜáÚÓ9˜hˆ4@¿ÕÆ8‡RH4L©cÊ“ ‚˜zAEVÏŽ}¨^6R“RŠv Þ¦ù¿î˜DÿLsÆOI+ —-Ö<&tL_á’ÇšÅ>Átî‹Y£Ÿ*eJPSBÀ5Ó+€5ÝøŸ¤Q°Ù㶆dêýâ_óÍEaèyä{³þßC¾ˆÃ퉂¿úþ_®!¦~?ã߀’Ö߇5ú­Y†NŸjÂ?·d<üÂçÃHG@h|O`0žÆV ÖDp|› Iï'ü1Ó‰™ ’V-®Úæ!ÄÐèIEθ0FCB Ç%ŠG¿Ä¿³ ¡ ü1 pÑÓàQÿþÿÆÿü,ðÉx¸Ï×dªŒñ,6AÊä%„@g88ó0üñ$Ád€úÍi 22Œ‚K:Êðp_`2ÝŒ9(#ÜÇî`øã“ʤ/“á>æ$àŒ¦‘qü±NÕfx|¸œ¶ÿ6üÿ ÿ§Õÿ'ûÿ_Êïö~å„âî8Ã]†Š™$¦4‚q?ñ!yÓéxž H ïÿÅ‘å›×îOe¸Éx Á`¾Æñ+[`«;pÀq\{À÷ð.hס˜o«~0ë_´?è´IŒS|¢iß=ëïü¡É=“¿‡?ÒÃÁ”È4ÄÞĉõ#ðD`ÊŸÇxËx¢!$4öÛ'ßÝ}ìbŸG%âyCŒäTFÆa¸ÁaØüH¾ ü€‘¡aºœÊpú„$!c%É®áà19Ø ó0£…¹ýAtÔ;õ¦â}ê`Î»î ˜$ûOvÎ': ¾¥4W›(._,lAù?¼S†Ð±÷ȸ@ j$ü$Qì_H ‘ÆHÔN'þ5¼/L×2Â;$ÈàoÃ?‹2¥ö§ÚŸ4!áøT}~vHBÃýn)#ÁB? ûü-íú=J Æð£øÄÐð8[£Í`ûÉè“?ŽWlž`Mô—ø×â)ò`j$n†QÅ0ªÿÂÿ¿ðÿh :îå[Å‘A@Hô°IϯˆøD…3$ÁHýã”IaPÙ#…Ñ5Ö {pëJ ¡ÐÉ A!¤Éüp ¾þ{ ŒP›"‘†g°Çc<­>éP0¶"xJÀ>í·áÿGø?Íöÿ?æÿ¿”ïB™^,¾÷>éäS&÷ôpÕðö~áè$í0bP蓉:*®O(Sj€q‹»ì(ž(CÈRÔ·Ìä÷==w ±0È&>P;¥—¿gVÝ-«Â¦Þ‚ú™òóÏ`ý¼zFFkJ»Ký~»1î~ó¹¿]0†º'Ò~ ôÿ˜ŸêLrqê†ÆwMÃn±ùük\Š ¡ÁÉøÆ"#õÈØlcl_26å0)!‘˜Á'†á1?JaTœÚ ã©|›HºÕŒcù𬣇f.2uŒª&åí6MëB<ß tF„65Pü“ò¦Sñ$,IÆõ:Š0R˜ßŒç/µO2T•;žÑžš×ÜS§ÿ#±èT\È&;³¿ ÿ¤Rü)Ä7e4˜Lÿþ¡Œ rø®ü'3 XmÝjF(?)lýÇ¿–‚š”‘5H˜ÑÆ­’E €zˆÅ‘Ôo}‘ð'ÓáRHPø/ñ¯Å‘ÀƒsP”É@‘HqÍøøÿwü¯ÃëNuEšÚ„øÖ ž“'¹¥Ð¦ÎàN ›?Jž4à Z1žùv€3¹O¡0ÚÁ…€p÷İIƒˆg<ñ‹a¤õ)Œˆy2€Æfx ¿Åsþw=±ŠS¬ñù}øÿ þOgùOøÿß–?í‘'·£ñ%ňHxŠŒ-H²Gà$AH±ôû^àŠ£ø‚àIÀÉÕ玩(tй“[€ŒCA@ 0‚¨2Ú”ãÿ#¥ŠèÀ êÏáßpkê&”ýs”‡}DŠýÙÓfPzÊ É?éþ9b’WòOÛÀ~±?ò¿ÿ®ü±[Ï$F6Ñ3‰òCSMÕÖ®C'÷91Íi\ÿ (暎§þð‹ ›<€ÉÔ?Žˆoý£“Ç­ðW~tŒŸÛOQ trósüŽEãÊ"óáwÁ·˜÷”â2 ¥b Ñ7v2²e\ÜÒ€Á!BPÜÔÔ´OÑ9Y×t<€ÁG‚Í!D`¡ÌäÎ%Å3nRFžÉè÷=m¯Dì…JB'ƒêiÃ?®$ü[\HÄ?Æ“«d¿ ÿø¦ÉÉ\/£×´IcøOÑ C;–¡ðjÂ? «­}’ò³Ç''ñÇ€ Æâ~²YžÁAi(êÃ0R“sÁ6ŽYhPÜdúÔò¤õL¦L÷¥©^I“Gæ¦ÿÿÿÕáøÖõäÀ¤kE±dÆ6>Ň£pQa½áÄÂ7 Bƒb¾¥þñ“DÀÏL$‘#'×ÃäB¬!`í3ðŸ<€9á~q$|ó‡…2ó3Žûá›X‹Iø. Ã?TÇ8ÀH%`²ÝþûðÿCüŸ¶ò§ Ý?¶L æO$Hß¼|ucF§Zp‡ÏúÝÓ^upp#˜tÑGñL줳Ž{øðÝ'»&…¡Syé®0[àý‡ãÿ#æ#¤}s“ÿ›ðï§„ï$X5âG†÷[ ÈȨQœÃù~  BCb¿wà÷Ó†ð÷3¹ß ¦3BI É=íi&/Úõx€Gd ‘ÂððDbh8#ÈVð ¿e†Âô-±Ë:¹‰” )(°ï§Ž©“cÆÆCÅó·¡tF|ƒõ‚»!Ñ$Úd΄†R'•mè·3ÊßNˇÁÿ×Þ•?7q%á.@€Í’‚dCm’6 øB–|ȶ43ï½™‘¬Ã²-_ÜŠ")ŠbkI0Üö×Ýofd’Ø?ă©²ª,Ë–4Çëéëë¯{´º\šüéÚ"×[ñÝÆùOIþL ƒÒHÐlé—#pô û79¬oÞöl@ò½XTþï)*š[5,x÷¯^p™V–'*[OÚ†‹æ§–G’a’¿Ërw­Ê–ÿéÿ³'4Axe¡òeüF¼å·0dù æ& ¼ €ˆÄËÂèwŽÝ ÎÔ59hbp`~ õ^QÍù¹¶\ŠÂ’? ÿ Xþ¡DüdO¡ü?‚þ—èrNÒÿ?~˜ŒRúžCPxpcìõjæ3')^ û.jÌ S¥þru›"MÇ!³tI¤/E;Ò-3¿æ<ë×9_4tSÿ´÷ﻑSÕ,Šç¿zÙû€ýå_DSÒõ5Šº™êj<ýjúXÄ™Ý÷e`µîfn¹­/«k^N!ÝÔ§fâÓÏ% š…=˜ê°­Õ5²i $ì?–ZH¬P*lÔWc)ÃÝܶ)Ø8—ÃH:Jà"{fφg¬}o„EHoÏ^´îmŒ ç.ß?¼°Ë;E²yíC´yò+OÍYiì1K6ÀàWY êh´ÈŒtѵ„zi¢,ël»íóhþ;fé•'ÿG÷c'‰¿x$5Úa2ÿå§#ÿAKØ}Ö½Ù2 JL·Â«±çŠr3nj‹žÏí"éµ»ùgÿ!òOÛ‰ó¯{_¼g_øÙ{cþý<\Ê À6kk)„.,ÿ$AAþè(€(é?Lm;&úÿª+¬}®Pä6?T÷Ã)îú“ýpŒÅ“ü]âI± b–?û‡¢†¬•†›_n+þ_]óødPGCª• ÎÅ-¥h§.Ð{@ú<04µîÊÿ#èy“ôÿOoqŒ/ùùšžoVno­gªë)§²Âõw8ò= &‚ËÁhÑ%¿h;#@xIî«öhà_ÈùnüƒÀ#6¬MÐó€Ûˆ„·¶Ðõù~MìhkŽÍ åãÛœOý$-Sh¾¡×Õ•TwÀ‡cÃÌ‘q’tÉôPX·H5èüÕ’XN” _1§#]›èÞƒUR3týª}¶jÍÎvŸ·ušê›‹é5çö£¹5¼Å]1™.äE’Å4é`]›¤ºÆdDöϨ³‹ÆÛ™Û£Í¸8.Sþ¯Û#‰¿zFbo\ùTäýQžfÞ̺êz¾È?ߨH—"C¯é g+í»Ùf­½þÈßEwí ÷b™®–ÐÞºM¡âžF¬ÃDu h+ÃÊR°Ë=}¼êcËCÎË%ûuA¹òÿSýÿ ¥—ø’‡†1¨ù È1i¼¢»nmÇŒ90܆BØ5·™]Ã} –){wvÎã›mN“§‡²§4”Êý¨lk{Db¦)¸ÿ1c~M\;Bù ý/ëqâþÿü!줲÷*P§=Ü—n¬š”á¬i\~ÖUÔQeô:í –b¨Ú–Uã++èvL7B ͘k7ìÓMo‹³FTG¡¦ûRá(±Ù¾ÉÛÎtÚE§àK¸Ö†s§ñàÊò@—yŽ`f¯ W¼ûàʤ¿;™³1vbK]“TÜÞaÞ†Sê¿qÌ£èL”æ¿`¶ÛAâ1µ Ã…N[²3Üx“PxíGlðôžg#ˆ"ð¿/‘,vŒ=÷à>ŽÑÎ ´ÖOý°Þ ÷¢ó‡gã â¼á>ˆÜ'&·Q D®H»d)ȸMÜÁƼ¯m•)ÿŸ¶ó¼0æÞqG²Y~þ©ÈÿD²À‚ UN Øy4ÓkãÕÔ–É.þ6/¼ú$æ4Ї\„8ù¿£+e±¹ÓMr¾«äó>ÛCrŠª:'§Lƒ ’¥fŸ®Dλ?wªÀƒES·éXÖpä¹wþ¸èÿà%Na¡¤0Àð8¢ÐE7f „¸þ3è?Ö±Rã[2úü·(ÕÖ@ìAÊÍÙ :è ¶á@  Á¤ ñ©[LaãE™¼Ãп›ØlÉAñAœ:Jù—®ÿ‰9Ìãý?ðaÊ­ÇÈ>U}Ñ…Àãúas!Ô_3½’Ìlæá¾~Ð —!U_}k7™Üï‘f瘙KÒûóaøŸå φydEÏfjÛå±ó>Â7OÝÈLÜgocž…'KOþÛÍ ˜ )8äÃ$FZSúŽœÿP0žPqlôÿùºÙQ†7±öˆÐ–œ’FTáèdœ€ûS·¸ZÃq6#ùóA(þOLÀÚ*3rhKtþHž™ƒ‡ê„ã¶ 0$ '=® %àâ Ÿ]œÛ42ž€êÔ‘Ê¿lý/-8Iÿñ(‘BeúXO­‰ŒÉ| °®uº±©»®§þbîZbMœwéDÜä$L· Ÿšæâ ô.%‡%˜tóÜsVÏóøYÂ~£v#a V/Ú°—ÁlþƒÙh8CWr\(ñÚpaEÒ‹ßÅÅÌôZS[^usWSŒÆÇwÜ0\·=«Ÿíô€¨2¬Zìî›ï ësm\”Q}-Jfz‰ÉH¯îô†‰šS`«®<XÊSW`‡SSûÊ®þL§3Ïa½[˜ß’9 ×ÙBÑ4,²á¤±'v¼öÂh¶n kÚ©Û¡p—!¨†Ï>h™{­Lqyò¹ª•emC³2õ «æ|Õ¯?ù§]5ýÅ5®ÞÍt—§À «ôá•‚Ÿã¯ƒzݘ|€O}÷Ôåz€³©]¶?ÑGñ=©Ïmc°sWr œ0³ãBß%Mqiþ`ù³»ߎ4Ðó$ Ê¥ÍñÒÿ_—]øÇ¡ábÔÛ¼@aýì\KäÅJ `f¼âÿì¯]¢m€Òª‹ ,#àÿÜáÀ#9hH­é+cÛ1Ï1p²®Ž‘ЖY‚3î(å_¶þ—åÿOÒÿC=Jaú0û7Îxçq7—tùUeÐP>E#VÂh*‡ › £@r’tœªiå²]yž Qûô‘ñ•É×Nm²Ggzq‘ím²è*îÕ —Ó½šáò¨í/˜ŸZ3înÛ<ðÎ ‘ú™äÊ÷„n† ŸC $ýpÚÈ XŒ=¥lÃÆ<ê“,@=Yze¨@YWÌÑý|Ï¢Î{ê½Ð ¶OÌ÷cöçµ,Ý=ÿÚbT]„‘ ×ïûÓÐ+ŧaÎ?…½„L‚-N›\H¬ y€)·l›]ê°±߉uý]iò_nc}GóBdŒ¼ŽQ¾róÿ®Íëƒ>2iüζùk×uÎ@àw± :Ú³ ˜üú~ʾ$>Ý=¿K)éÜ*{æÆ='Ô‚$>ε·ËŸb£Ã…ýñ$+Â3ýËIºÔX­fzNø÷ 0D3÷ RT‡Ú ˆcj„­Œ Àø?l¬U2¡ðÿäÏø?ÏÛãe”6@nDCò—ʹö ºtCÑàÓG+ÿrõ¿<ÿâþõ(y¡|r*c=…‰áötÝÔƒAÂ4\cÇïÄù Èß4DÆ€)݇g‡ú„P,ZYOy.' íÿv­fpÂù«0ÿm=µþêÆRä,¯Â”¸‘Н]Šº™É_L[…à¸5»ì¿®÷׭扙"?Š›l»â?ù@ÇîÊ>¤mQÊæOÛ«›2 Àúæ?JN†AGZ¬h=1zœŒÛLßÅc y¥µêxø˜ ðäá˜Ðöúõ §½ŽÝåÐÞì….ýÎ~…A^ä01²˜¹>‹un…1žWhžXÕY>ÿ÷A)Iþ¿teôN†Ñ[Å(û̧{&üüøË¿0>?NÜ ¥À3UÖƒ|¾;×§dì?OðötºšòtƒÿšÆ–QÈ?ºµM 5q¬;¯µTüîþâ ÿÎÁò¢Åì ÉŸ¼Ù>vú穦_„²‡iN+Ë7nûÆÕ/Q–ÐhiQì¦]èðŠÎv¿xkÛ²1‹ <—˜%J[rÓdì‚ Úí²äÿøvš„ÕI¯ WÊíßt×… Ç]þ/㼑m‘li[Ô)O÷0Gÿ®ÅÎE+B‰7b4]¢ G#ÄHXfàlN½g/¾7Q3…cü  èjYhœùl÷ì!äo…<‡Z9Éßõ¬ó(ÂñÒÿ—«V À×/=ì§5"ž¨ø‚pý ÿXÒýê¸ è–»úI, ƒò#'ýùû»j?„pq$|¢–àr‘Ç0F¨¾‚6ÀKÏTþîï%ë ÷ø‡·Rå<zfîL %Üd †-nÔ†-Wh š‹{Nç…ÉAåæJ!VLÊ"™T‰ò]Ø·üýª½OÏ HàhC­­|‹›„©}¯õÓ}ì¯ßËyD¬nó,®˜þe8®üoüçkiÎËɾ#¥·Øðÿó®a>]6n1ò-Á8/@ûP"m€X6î´fV™•»Ú…¨/=E(±²³[ê„Öžyq@áµÇÜ´ä¾|ºƒY€´”§w+ßÚ»µâ´*“Õ]–Žqrû:¼ª÷ùU4yu/¿! Š 6fºŒÓæÙšpâ[Y%éÅeÉÿu[»ùܱxs8þ"8ËœßÙÊ7Ç[þKk#Ç“}F˜^pgQ¿°Y|üns~—³ÝkOd õK?ÞÑí…ü>.Bþ>lOV÷ÈSü’ YÑ`1ŸˆûOâ…>sÂÉï!ÿT ô†‰¨•A»ã©ÿ¯SIfém’¿Nú5Îi¡Hî (æB8¹Í$ôYAÜp_<ô+Ãø?Xð.ª¬µän€Ò†Ëásw¡ÑÍv¨]‘Žo`$Ë:×ZÓzýhå¿Wù¦<ýÿ?ê#^)ÐÈWxœì½ 8Umû6 )EEJQ4) džR$d–yžíi]kæy¦ iÐ d¬PQ¡ÉÐ(‘„4ˆú¯µ©§ç}Ç÷=ß÷=½Ïÿ½ëX{Ûë¯ó¾Îk¸×fLGñõO˜–qþÅ/ Èn‰Ó6\s|«{}üœ€G~®Ê ¶¯TOó÷gfèzæ5¿~Ä ð`ný>ðî_¶ZåJln€^¹à ¨Ù§¨*¿V§ H¯´´BA(ÞÙ¦Þï‰-ô®x‚5†ã™ËÀƒ\é¸, •p-q9@Kñ+EöoWQñ {§BŸef‰H Èýz á ¤½…S¼â°ÊaT¥ºd¡`ÿVL—}‹ ö.5¤”󿀧žc ÌÔ973f¥ŒÏò«;µ¤•¹Ò²:ÎG­iVôx²& l¿äË,;®.ÿ~Ê I Žª–†7W>é¡Y2Ò ©¶n,kehisåÈŒyuG"PÏÛþŠÇwèzBtŽ=êÍY>*3§úx©¦Îð.'"å$^¡he\I8·~ÎÒTdެ­‘Š¥rþ÷°^¹¼Á-Nè›Cû²C×LÂ@ÔÓ~ö½…•­TfÏ:'ˆR³/…—³/ÖÏ… Yg”‹É¿‡yy2ó!h˾ÁW>,¸«á¤öY÷pS¯%e¥,wý —Þ9]5vïW °ŸO ןe¨Fõ8§p§ÃÂ-o¾„.´Š°÷ÑG‘ÞÑÎ º€lºjmƒÆ9 xíÚ®k7ÆÌŽë¾?Ÿßª6×7« ÆÆ¥Å„´yÚs¦Ïœ&ü½B‚εð¼ÝWŒÊ ìÏP5±­~N[Ú"?ÜH·Ÿ§ÌÒYC) Þß6ŸêÈÜvѨ”5-¨~ÛçïÌP»æãìVÚ²à(¥¼L«n¡šu}ëÖ&JÌJÙÞoR(xøˆÀGÛ'rj®Æ¯à¼&' I&:ŠÌX+øµÏ³YúZ~µ8Åô~Ã2&þu#y™~à9#‚mÔµ9êðâkU¦2 X×Â"V1÷¥þ®Ý±ã#Ÿœáƒª*t°7üü-ݺÊœXÀµíµÀžï¹;÷ý¦ú¯ŸDµJä{.JÃÎQ…Hpê_EXöìò ÂÛp¿hVFl>®ª*£¼aÍŸÝëuÙ{'ÆÂ™»Ïò$,4J^ª¢]aeq–P?–ÛñlØA³U™¹ˆqoÆN2܈Œ!o óKÙßKcÓ•Ç ?m˜3Ãwù³U ¡¦~$•wäÚ?rÎ/y}\AœÛãkìßMŸþOC¡8Ç1¦cœPñ#EMË8ê¥3n²o¤÷1ó¡S³Ó7¦ñ¹È¼¸×¬Õ•MG\v[€„Öå/#Âó/H<ôˆ ЏÛ#¶æaGx÷dÅR>=_|Ç£¶kD&ء욹?m¾ŠÔvn«ý” ¨4QË>F8 °´šã³òæO±•3;¹W‚OéÂ*€åÏ‚ßEs¹ M/GŽØê­¬_)„:óZèér¾q±ŒšLÛ5–hÁïEßo´—m¯]ËÇîÔËGÝT?6xž€|¾òɶ7 óõ}‘‚ª^v4’{ù@Ê+3Ї V<,±%ØßÌ\+Î\‡7Oøîñsj¾" ?8êy•ry¤žøÙp ×GzOe;Îz»ºÏçýŒ\"Ã]ã1^\U1×ѳiÒ6éÔ—O/¨ü‹au¹S%[þëúá]¹¬×.‰Ïz±çú[ž5jcÚê}IááÞÔùå¿»‡¡Ð0‹<ä¯}<ÍøÁåóJ Ë-BhožE”0Yöl íd]½¶µ×CMJhóF2z뚀ôùSb ò©ý,xè˜]Zß*3WßwL.jZ¡¢me*”ÈÀ»º¾éºCc7@y•¢ <­ y¦‘Ð|èWËJ:žœ&ü×_œñnÑvZtlsÏg;RÀÓÂsµàNØïÖì}ì©ÿ|Jå†Î‘ÊŽoä…Š~güy›òµŽ9“RŒ{·"·xù9<̱¾Þþ<û¹ùöÐXŠïÀ‹¼PÊ5%ÿôå·eœ3ªÌÀZ4ëý éÃæeIwƒÂ…*Mm%Ÿ.§5fåXî±ÐÖî&úP£ÎNàŸlqÁÑ8ä– ‹}‡ŽÖ4šìrO~¶3&É- üJ?>B=ß) |z‘ àÖµu¸Wø/àß©eöþÌm¾Èsn†/5`«žý»ê¿¬–wÀ&Š9wÁ– Þ~ªêüK ÷¶¾°:pàf²[åiáÒµ—ç¶Ì2xDù‘Ó n*±…NFé¨àÓè=®)5Ü~fE™oÿð9 _”H±~×®’—2vS(äòªðäŽ „Ö¦ì]½d’Ñx b~A7èBÑJ¸tâ›Ô˜Ï»—•‹zŽ>œ{´R>Úʨ½§:–Z…ù9 ¼¬›jüWiä˜&ý6FÆb¦c˜J Á¯®QÓá3-¾çºùc [€÷Ê.B˜ %¹É«sÓ(·½)3¯ž×](\óSm·^°ì€?mÖ¹–õ%R^27ˆç]wó}Z9ç«Èmᣣ5W›øä?œ#EÃTŸw±s\25ÏÁýqÙÃËßÇÇ6o൙ °Öéi$XF\±³ßõ’çF*…3´*–” ñ„õˆB{çZ¾Àó:a[Ø…0ر•+’–½â2ų_Ì$Õ'ëåž>™µÛž%Ò‹wûÃàF°ÖI/æÔ[¡½›êȶìŽÛÅŽÍ÷½:Y½O¤ìñó6÷9{Ž@âi9¥+«RsÉn+ïo°äáÅ2sY^H ’ü ëÑû*|ùÚ¿Á ºÚ.ÉÆ}8U‘rbA“è'‡‹ê— ˆ ­=‹–éÕÈ¡:ަózÒ¿“s^:0O¨Ö¦âÓKÅ>2MÓ~³þÛb^_]ï¾Y2Œˆ™Ž÷.›µ²E¬àHLlYK‚VÉLÞïº/6W}3Œ²ô”YŃò"]å8ûݶy=0[Iµ!e{Q µäÆ<>¢kÁ6Tà $2€[᪬V~í»=­n[9õÁœ º9ñRkÄ(“?l&Lþ/Çà@Zº7@·ãÒXHæ9ª©ºDôû¼¾U0?÷6À'l ”_MuávåG¿/þ§¥½ö¨j™1*™¦åuüÒX;ÒÜièñ¥ oo{…Ú<_—¶pÈôfºÜèEqi÷XšŸfeºIL¨Šî¬²Íý¤6NXðĬ“Ö¸ò`FÖÝÂÝz΄L·[v{xOßÑÑø«”W.Öú,R“÷PœÒ‰)íLÚõýtYLþ[š1ù;p`¡Ü’O{"Ò«ÿþo»÷jœ½ƒi"&Øhûûêÿi©|h‹y{¸{Bèp-H&<ùöÐ<ʶf-Ö‹Nl-Ür»Rù:¿à¼âð¾7R;ƒjÎq¢› {Ãáöy.ˆ{1’6Â&#¼*‘v°Øöd~Ïô§G¾½Y-3÷„h»ÝJh¹Öí;ßýÎü>!§™+ÁEý‘ l¼të´ì0¯£€''ÇÍm×4üOšz¨Ý‚Ãf¦ãœbyåGÓ¢ÿ/§ÁÆÝ©Ó0Ì?§3_“Ð)j–TpO@G‹9åæ‘[S½°M…ÒÙÛÖ4÷Û{€Óu™GÇî(Æ€SöÛJµXü‚Y•Zá€Î÷$Þ¢óR˜9¦×Fà^]*õýõu¹ÄÓ1v*é€XVØ"-£`õmÑ  sÈÁÏÀl¦õ6*8lì„ÀwÞ=WHo„ Øî}k§q²9JÌì¨gñ0#–Ükº ¨üÃF~mÞî â{_ÁPJ/I ÎgŠ‘[š}Ÿ»m>·sMÿ£ÑÔÇBwèHˆ@Á:›_òHWK=S¼>_—™æà9 o.zëøÃ7ÈI(`æË¥E#­0—xuïþ%W²%o*xª”2„Ÿ®q… W܆ŵ§¿—¸Î5Th^„­2¢pÔï9 $ù{^Wl=}(Ò-¸Uô¬s­ÿù…ºØy >|!¤ nò+{j3Æ2Y¾Ï^jðV°Kki!…_Œ÷‘Qaâé7[j ÎVùié)1>"cèj™Ik3”EJ¼t”ÏãI bÊÕùáY/¿Åðؽ• ‡¤s;úGS´ww^¦¦¤ˆ…Çôʬ/_#ÇaþòuGâÝù §ÚŸV#­[´Õ=.çÖ7KÛ³q6³lE‚À~ì‹–ÿ´à¿µV|…Hû¶¶fP~¹/˜ü¹Vƒw¹óX¡Z*P˜££%¦W*;ÃÖÍÀà0»Ÿå=Ù ±DñwÅ_VÏßn»ž@¿J¤÷ÔÜ ¼¦®«{)â˰KèXMë|Ø‚ sN^ƒ׋›âú§uKc(z5I¿›9ÓØSÓn÷ê†bú½TVhÉQ¤zlõ¸É!#?búü¯Å%Ô)ÀáT‹ †¿È¨RftµØÑ“múCqÐõà`òÇl ù;©ëF_Lƒà/à?×¶I…¶åj8XÕ ‰gÿÎúß!¬8OÓ&Ä¿ÚU3†|1P!<ò•2!I|‘¬ùͪ÷Úcyãݲ6ï2ž˜âpýIw|ïžçà+ü$¼î¬J³`‰sÚKôBù\Ü%(Àƒ¤›ÙóÅí4n…ø ,"蟥]=½ ‹×v¨]ê°7\c[¬-ðà|Ú&½ÙP@z¶†ê%—*yíÕ[àaíŽ';YÄÊŠO5þ…ÒÇyk­™ýœr ƒE²ÁÓ0Ê?°<¦ü± ûñ%­-ƒ@zöÈõ8pzƒ|g«¯âïçwL~»à©xÙóÅpA‰Öv?ýq@ö_w¨ùš Ý~µý›àsâ°÷âM©JÞ£r!ž”»1:/g¾ßGÝ­2v ¤9jvâ:ež{+AѳÑ2k©Ðß5~ùÇY¬*ßO ö ´Ø¨j–"tòí Dô6ßZíå0”¶O¶ëä§%êàg=OpÕc•Më f46Pæ»SØ~ÜâXïÁƒs?·y^!W7Uå6”ºÚf“ï1î9AÛ3ëŒç¾oYçÌÞËïÿnÞò÷b ;™Ì›!°ïHÓ7¯¹ˆí–hÀ\‘ÝFo|T»_ú~­z³lÏ¥ƒ›¥U ¢2€E”÷¡éIeyÇep]" BQµœ3ߤwÊ]‡ÇiܶkooH<¢Ìx¶Æq\ÊÈ´÷ôc9[–=¶JsΚ#|‘-”<î7IËŽï÷°HßÖ6ûãTã’!q!àÐÔë?ëT€¯Ä©cÿYÅ7|ò75üYñÿ¹ÜªÏy5æ)ºÅâ"(XyÜ4Hp­ÙÀ“°`~E …q°„3:DL€HüÊ‹ Ñsöœ¯°v|¡!IöÍ Ë5ÚéFÑùáÎø¬Á]¶/Ú¼Yqï5q%߸,cˆvzÎÍ(9¤mZZ;¯\ĨŠ.ÿ]£ÒÛrÁàI1áöyÿ¡:ƒQtÝÂ\:â]®ƒ9§‹¿Ñ'wÕÃ)í(Õ<Åáúdï{êÎÁyT¤#ŒAn§.õ“\-MùÎËׯì•ãxÁuÆåc· D…ƒG3ß‘EoøÊ67Û2ÊMÊ">èÙPÁªz9—¢äÙ¶ Ì9-’Ô–t‹çœa@âãõûËÄ÷Ô#±fT‘.!ë™ÛnFòuµs³ ±ön:CÌ^½¿Æ]«Sš=ÿ6x§b¤i#à!˜èä«t¥¤jõ8„O³t÷’¬ïtÛvyÇLÁK•Þ&+Ú¶Çi1Ùײáp¦Ý „5ólº}×_1¼"È'YÒ9ÛÛú]×BÃÛ&Þæ5Ÿ #!"tY§Cßl§–­VÚÀÃ…ókóÑ7¥¦±*Ú}ÙuÓêxpIìì¸LÛ¤öåV˜Èò8÷ï•àîÌ–ûiÌ• ± /ÓŽžÓ/SC¦†>¼è¼k3mïtàŸf{scȕۇ°\ç|'@iB”$Ø•< qÑ>äGúj2<ª¯»Š Cón¯ B²drÂáÀèü ¢Kêï‰?‰Ä³nÁ18WÍ×~: z_ÌÁmN|—}ª5‹È¡_î‰;©šÌÒÏ<´‚ÎItd™í·ëØØò§K…Û× ÀŒÚbß±õ¹ЩáëoÌvKþ«M1ßcJ{-ë»—Ï •_ð_úL.¸ š´ç±@4ÙOŒÉß¼ÇÅèT•FÙ…¼Ìá˨†mU_¾[üüƒê·Ô¾#>»ËE ¿¹þ4|ZÏŽ®y°Ã£$1ƒŽœÙJ,òÓÊÏÙdEz¬øÅp´Ìt k8vPnâ`[ŽžlËnì8üR*\,s"Õ皤»]eÑ>œtÒÒ&˯ðçžø,)JÝì³# <{íü~¯PÝ+·Õ•–Ì¢l=›þPfÛáï,kºÁ5ªÀËÆ@éžrü±Íke€š»Üœjýç˜Zó‚Ä9*dÊù§BÐwÎq´©Ay"_Ã3ƒ”Å õÀî–¶ëK€6ÛkjZC£ @b7¨‡#»†=hX—t! ­)mÖ°óíÛrÈy.aóWjœ[o®10Ú(ˆµ>G 2¼GýC‰ØH²ýƒ€HÅ,ŽçwfÜWZ5–i~å0|vàM ͼÙãšk¢ÀíÒÜ[èý²¦Ý_çZÆI„6Äò~Ù"Ÿ}ë[ÿË«{ÒôÐõ÷ ì-°®Ûä<¯·kaËÁ1‚—)-&»¥‚3¬ËahîlŸØ[e©[•,3ÃÍp…Ö¢ðJ3Š$‹%×½ØkG>E'Ѿ¼§¤yT ŸR þåïÑ=='¾Â1{ýƒíÁ‰þwûòSÃôlžÃ¶+z)1Nßiu5õásÐu¸kk­þÜ)©n”æS[khê??¬+ÆÃhÍ·§+bfÝʤ óÕòî-3þpªbfZ²îž–%]ãë{Ï/~S¸8HÙà;¼Æø¦Z å•/šîpÁoÎ]—$­%ë¡á]U¡îõ@Q›¥2g¿Ýøª¾ò˜½7Xt-õá€ÍU‘ã3_{ÀGÝ݇÷½OR§Ÿë ±ŽLðOT¾e¹ë¨MUÖ¯àvЍ{ìaÅç××^!Ú¥õ†ðž4=&j©°ÔcŸr_Œ‡Öž¼ÇÓÊöÜ|û]✪Ÿ//å"UAbjéœX ǘV«ÈyQX‹j=Há/OjøÆ"Ðù qIªocΑԪßȸ°³i‹Â¸¢àŽ5ïùv?ð°Ê³ NèáKK\¡ë€ÿ‡¬W)Zo´!ì…Äá#ÞŸn÷ ؼF]ôh|äXñî§&‡7¿Ú½’ ùê6šhxÑm˽ Vé…(õ ƒO²Ìõhë ã¯rÁI#ïê%¥»$´ž|â”´œíª°~·»nƒÂq¢µì¥ ¬¯ æò•uVðŸôM.P ê_Ü{¸ÙÁÄ_Zf]NËŽíà–Ió(¶uN„Swz:ôžrý4ƒøTŽØfhâ1ƒ—±ðàðLA ÜV@¢=Vç]ôPmÜq•Ú'žlbB(\”‰bŸÛ]Õx(*¥Ø #uöh^Žýêñ¼®-ö+ÃUpð×¸Þ ÇD;ÍÁÄ¿çë](4}c"«nðbë)>úÒŠ`Ê«Òga Q¿²  P 6 ·ì‡VË ÉÒ~?üŸDÍ»‚u[~Ž*”cïÍ}g²×>¶üµñŒe$µW™ûæÎ4È·]MúÈ¿7kU»××g†¤éñÇ·\³E¾s{!™²gœµU ت ìoÞ‹s ÔhÆ|½óøè焆k¯Ü–hþŠ¿ê®;Fï®[è±e‹d¸›P×½hOgÃl«k”–¬Lþ‘°¤ë¯à¿rÍ7(ìíD‹n¸.úЕ˨¾pÊWÔ¢³ñfŽkC?“¨Û… C€3-3Þ¡ó èâÆHÆXŇ$EbÔ£ùWOòu€K$)éÛÎÖR£°ÿîœf¨îz 1i>–aO^éò™À­#‹`ðSƒekË7©4;‡Ý-àÙç·®W vÙ~Ö˜Ï.º5%Zú7íi—W>á¹$RŸ¡}fkÔã_Ø Vƒ›hS©ÿÂSh[˜…ìOŸê1þÅë—¯ÿ|â¦l¿Oü`ã´åþyb»vm^fÐÊ@ŽÏ#¸îA[nƒÏ‚“¯@ØvO‚[3@nÇ}ÂÙÙÒšzzã¬yÒ<Ï2î+Ç œÚ’Ÿõƒm¹»wŸOßKYÛÓν„Ø‹µMñ5îä*}È—®ñeq¥#|j Ä¢ßxÑû(©M´Hæˆp"ªÿÉ``OS×]û,ôí›ú-É—†6Ÿ=Œ)j%PÒN¥ìz”¨ ÞEkòÁ†› rÏBb>8ÈZ0žrp ’O¬XS¸b—PêUy*‰b"ŸÙ´ßÔbØsdf±Gª#âËùü7gh°Ö—ÈŽ&ì—Ý.Gn.ûxiw߆4= ®~NÛæúÇH]8Æx)šÕùޤ»¥I”Œ/Îé;ÚÀ—O™øêƒ™_¦ojòþë–ÔŽí|ï+Ÿ jŸC¶†yÝ…§7>¸úMÜâÔÂÜt`ÅqM“SNrû‡~¯œ­@AcÌ×ôHu\Tt8¥RDÐ,-ð21ç‡Ó§ìû§­g¼žŽÎÉ)$ì<.žÑå]¸‘ŸäÀf»vúGVîV¹ÖgÂiö„½ÉG4åê:ˆ¤•w‰0Œè: ŸXN¢ªšá¶õ¥©`¿ì¦Å£ýÆêܺ+õ×YêHzDGHß2:ÃEv—mõð˜¿öάF¾£Ó€ÿÈp2wFõÆJ…¦ªåçŸÑú ``… ~Ämóïw¨:,”o >à_øT„ú¨£ÀïÌ61äÉm ëXå>˜ÿî÷Ãÿ@ìsùú×G›ÅÃÒÊÀsàh¹•´?ïgS:µÂ+¹£5¯Ej‰ç0BÝØùíMúq$*:: a›#Þº.ÅÖo-ÊBR\Õ¿®7ö±¿: ö^úgsáæãrþ­&ÙÔã´ëï¾<£>³Ù‹§PÿOM™e™,îÔè©âYH¿zM!Sw„2[!‚ÃkD< ¬ ÌO¨žZW’ž¡»n³DèHŸ×År’¹F ÜÏg›¯õ⾀ܬ›¯¾[oµeŽŠ¼À:ÐóiÒ9jsÊ{ÖxwÃõ 6úŽA®­÷èFW+À\-,žã\¡Œ‚ÕxÌHú€^`}ôûìÃèþÙª;³À¤l¼à¤PÀË•[ÐöšÜŽÓµf,và ë&-¿·mÉ…A Ó˜E#¯®*k+Zð{(ZÕ8ÑÓe6U:ÇeiU„…ØŽ …€û¦ÉðÊm+½æ,qû¸éüݹz'¿t}{’÷©+>Ñk‹J¹ä™…Âã CT¥«çÒÖdùöåuˆ\;ñäöcëÖä-6¨·'ã²G]}wªÄ™^TÁ–‡×FåÜktaVÆÝ‡k-¶¼q }°ß<ûEôº …¶—–Æ;ÉûídéÚ“ŽÑÛÊ_¾+_Ü­fv¶¤ÙËs½üº óEõ=¬®:JÞfý¯…i#µU%Å¢ÅþºN6z§5#ï›’íW]Nâ¹Òõ:9¹¹@ªÅÆRª{øÞýL¶F‘§Uonp]þÕµô­ÖÃü\wóôöÆÀ¸@Q:«ql…fPÁ½}A‘ÚJ°6Š›ÿ”þLöºäüT£ŠZß°‚­ÉndM1©C'5VÌS©4ª3ë[L òÔ[Ëq¤˜¾qêñoéÁ°ýö6 Ïø‹ÞìDê÷IXŸ¡¢NîÞ¥±l1x*…8¯ ‚u±ZAI¶IèîtË8zø¼£œû7ü÷z_RH>ªöF :àÔ¡C«üÚ%ãc¬D .ªÞ¾Éþ]‚²S«ñTà9Á›} n^Ùo¸ý…dÛ»¬Ýëß͹%…f~¿•¼åKèе˜À;3^4Ö ÖÎ9èÒo·6Ýz½ôä’Á?íðƒü·â‡„CÜ.ZK÷œ[Ðaèlê]‚ï2`ò§“ÜW%ÿ þA[+Tßë ¤$ügè¿Ó…ÊýüE+j©!Vsf+‡Ÿ/y·Þx_évïì‘zÍz`cyšµŒƒ kͧ—‚õ¯G¾ûŸYgW2·¢Ä‘f.“~+ûAU4r5I‚¦[ld•{R¯H5÷Wì´rVР9–¤Ò$Ø— ²û5ídñPóí-²/@Ò-Ú“:ë³eŒfÍ4à^6ÃãÙÉŒã¡S¨ÿS[îÿýîßßQœþ^1R&»ó óœSgÜ ”ŽÎ( ÿ1:ý;µ_T6‚£m©ÕQ`ß¼çQžc, ȳ¾3 Tñ›4VÞ¾Àp”졌¨:<¿žOãùz­TÀ§çÍåqn‘5 ²h®ŽÑhíPW•>PäßJžÉ’çŒý«ÎÓ(¿crç¯ÈxÍþºìñqñµ}Ç‹ äjÁS@6¼4ÛÇAoë?àC„æ¼ ‹šÃ(ï.ßd³á :‚+³+l6“¹³4*é¿è<ÀÆc^êæœ€DÜ?ÖŸÓZä„Ëņ–hNé|› Ù³Z5ìÔýØ8Ü÷¾°Ä™&V²Ò® «‹çŸWÕdy»ãlWû|_ªnj;eyr½ÀV·ãÙ ¥KY—¡'x˜‘Ú5æ|æ,%æ\%™)Wy­gÛB¯»PS¨ŽŽï^[¿)¸(­û)\ÅUt›ð$ë7õ—>6+ЏE|CEö+ŠgYT¨P„Î5G­‰ÁÐÇßÁÐ$-ÖEŒ[Ë“ê¿öÊ©‡ñ¿| ºé+!ê¶,܈\xNMõ»æûa•݌’ ðpÙßlÉ‚«èã Ñ*Yå¿Ha~Ó‘™3É›äÈÂÝ˪JXhœû$`FÇ.SVôÃÆy5 !y±Åëî§CuýŸ‰ IHÞ”ãß7IÚ`&º|ý#ÒÕ¹@1!괃ĵdþFK·ûD[û·"ü•϶˛5ƒÔ¦ a@Ò;XÁÆU-¥ª/p£êr® öÝ2ˆk®¯¯å=‹,#½"ý{ÛŸÞ ù.ã.ÎÖ´¨5LÉä#mãµÍ¾ZN5ÐúQî{`÷œVs޾Q{ˈl6¡7·èÚBŒÞ+m•HÎâ pÂaýåM""+ãh¾!®A`«}!só¦ÓQ–#!”¶åApÙÓpQAØ‘Ä(D~¥ ÚÎÊ?{\ð)Á;Ò“F fæ÷Tîx`š§mOF±N˜Aî Òƒl ³õƒÄŒC‘ä4®w¼É]±ª *ìßðÿœ~üÌýŽt‘eèÌ¥¯?ÐÀŸ÷ó†«,gnå* ¿,³¹+4„=fÙó*Þ¿„?ø´lëMÿ9ú{ãôb’<Ë2ïÂ)‘FŽ—x?Ël_,œ ÿeÇ@°6ô¦lQ… Ì0ã–GÅXKä5Ó§òîòóµ@¯P¹‚…mÜ|«IÔEé¸0p_ÑçQÀØð”Ú‰f¯îuTÊLÓÌ"ñ½çئ@OtžÑ=“xY Fª)b«I‹Öû¡îú»²«Gì4à?cÆÇÙ_ÂG©Ð}ï.…í Ä”èéßjTþ­øù&ü÷»ÿ—…ü/þûþÖ“7æCëOJΘ’¦WúIfÞòŠ‘F7ׯL'ñ,ÒÍ…‰äåhY%À·æªiý,qÚ»ÔžZ‹½Ù¢À<Ûý8€äEYN«÷_Ämã~ Ô„éBvµy+ácï…º9þes·QKÙ¥¾5„'ägJñ¹ áêû(”Ùlâ+Òíç~Þæ*G%´Ç}䙃¬?¢rß.û6ÊSéË‹“_Î*’lÍo:õˆª–¯_Pp6s(±eÿ†€ÜÛìDh×8ÅA5_¯ö,Ú¼“ÆáweN•A¨Îݰq¶‘»äj·È(“tïíÕv,ýT¦Êmßi¨påÝ×§óFæ„©å/1Ž¥Á2Ö&²–÷fJï#%§€¬¸O^8 Î*»ª¥+ì« è@šw Á|Ë €Æ ›½ÞMž5x~VÙš|Ë€Õ1Ïm¾ù%ë’^}%ôÏ|f ÷ ÓÈ´½Dn/pˆR£—Q§Öþª¹Ug/fsú@€ ˜J8—~u¤Ê¼^¿1\&ºRkÇ’a×Zúè}ؾ÷E"@o@à3ƒ@,”ÚLºÑæª$g+ÖÆIL;òÁ…¨›ô9Ht÷YŽ/é(ÿÂüÜ:Ã#޽:+ï¬RÍñ">\¸õ¹¸ ×¼ä }η½¾Œ]6Zÿ`äÂwd0çÁ€ .+Žý;þX¶±Ä½Hð6T@¶Y6G—?x/R.j Ýd÷ÖAqîêËTDÃý/áHÍçëÿIúÏ»vÚûP?ØÄö/…§ÆJ¡ ß›. „äíE°òááã ï^V•:V‹¸ßr¸cc%_Q¦’á©Nd°­?裸DLmÍj'¢Da.,õ­(è^$÷BŸ È¢éì°–ql œÛÌѶ’w.¾‡ãP¹ð£<ÅðÒ=ÖÚø&†;ƒÏøºU›Nþ–M>ä À§Î@Ñó«$ëO…þOíWó(.ÑÁS:Àÿ¿Š[DÐÿ¾Ò_.Žø÷ Â3úßp5ÿóë‚àwi]Ó«u«ýÀ gÜÓ´Õ÷2ä^(…;ˆœFN‰)ch’ýY{²lÐ7ù¼? àüÙ;ÍòW¼{Uú@³mQeˆ;ߘ°ÁBSí…Xsúˆú0 :­.¡ƒ*÷)î‹ ÖÒëÞsJ2¶ªʳ†Fêë&î/UƲ#ê&˲d‰¡s?6ù¬÷œ,ž]›  'p“éCö'Ý›çR &ýÝPÃ+° ž„iêzv´$/“SÛÑ.ÎýæË¦…¾Þo–pÞÊë}:ßlÖö÷¶ªt*„šÀ«Ú.øxÙ£þyÛI®ÄY°9»™ãxÎŒ¼>´Æ~|Dö}°ööáH{‰”‡×ÅØé•û‡Pﱺ۷ùá áÌèO$ÉE78;2½¿á¼ä9ÄÊ`[òeã­ßP½¥üešv‹g¬z’#úØŠD[äR¤S«¥u\ýô‡%\Ÿì3Vßkì÷)Òam¯°†/…­g%r¯í2È…¼ÖчüÂLòtïÚÁð“ÒÍq»>•ïð9!i¸ö4kÐI…Vl¥–ÍcöÝxaÉú3—êÄÀÆÉà ÚL ±}#í©W—^4%^kt›³y¼kþõ³'FaŸóu“Sü+Õ½¢tlz`wŸª^?Õø ”Cá.'ðÐyVÁ-¼MÝfÁ€Þ@Ò‰5`ÛÅšœºhWëÊŽäø]Ò5âh=•ã¿E(UÔ¸k‡ä3PÏX äçU¨{Jàïƒÿ]´H'SñÄâO3“^ƒ¹~šÌ0r€oa›EŒ &ŸÓmÛÕþBå·ã 6[2˜-'™:ãôÁ`R4¥§Á£ö…Øúºó&°áEùçykŽ’T/»´>Ã>4¾jõDºiŸ|SsôÀ¿÷à ±gjmó—l¸øØn0ùüp;×Lo0~Tæ©WJBÁdå_Â9ÇÚÿ£ô? KuVË3Ð'²n€uµhTìZÑN>ÝÎéþ°Ü\£Ub¬Tð ÙOÒàÛ™6xÍßÕe²Í¤Íƒ3˜|džÁ‘‘“wjßFõ_¬ÚëÑWœM+¿qΨajÈ¥{3µkôÚvmú¨Ãï2Y¾o"ß¡+È÷ÕðÄO²] †oz¬ŸüO³›dŽeW³‚ÁÙ¨“aÕ߯ÿSkÿ½HS÷äú?¿¸ý»ðþÖ_ ì’ ñÀŽ >Î)om=LŃ#_»PohRª3¬xçïpwELïÆïb»Z®å/?D=†Õ‹ž‚Àâ¦ÅÆ¡o†ÎÌS¿ ÉÉÕV³]"#E%N\­*[ØÌTÅ"o½Rùœ~ZãJ{_œÙä}올kßÎ…®9:(œ!4p_ž}H=ãéT —o÷9¯Í›®Õ†Ó^†´U4­u YÆèKéÎé8ÙœÔP·iŸûõ>N±—‘³úÐİ'ÜÑþ~@Û)bX,Óí7CO¾ºµýÌ4]2¶–Üi¿vtíN÷«2=ð•tìrY?dïÈ:8ôYáYŠ·’݃Z–£1$®žxåjb6bq¨U¨ªM’4Ä‚–§¬k['gôk;sA7Ý›G<)+µhW6(ý,Tx×yGtá–•ˆq齄”egÃÎp¬YIAý–vèV Éž“s‰vnQöˆê~ãvÃ:®cµ{ìçò{ÖIJ=޾‹\ä}N³õŒõrN[W¿`ˆ~ ë^{£d$¯=Øà¾JzÓ+¾cðJS?BRa5D±ÏŽÜ’’Hß”ïc/žP¼* ÀÃQbr{sŽK×ÀWñc¡Ý—d¿ïl‚QL.±~ïaJ¬Ù5¼¶v€/2úÍÆýþ¡$ºÃÎ:“)ÆßA}P=y‡×"þ“à~v^3€ÏBAsê竹ÝÒk ‡ÇV¹7jl6Ú±¡(g5•üe~ˆuÏ׿Îà{+"ŒÎïX"6³µâ­ŽðµÖßÿp=ÆèNï2»Ó}þŽïQÙ¾ j‘}oì3v{z±<±ñkØYw D³ÌØL+^û„ú?Þòîµ_Åtß+»°ìÌÞŒ"tå¼ —êíS;eí}ƒ¿ W¯LÕ‹ÿè²+[;¤£2ýÆÿ„rÞí!ϨØ]A‘GôÌÈ·²2 ° +Ô“?@®XØËý%üïýšþÖÛñ†{z‰~º´~ÁûÄ7C‹¿Ç, ʼYk‡vÛÈ«åpãÚøl³€ç|Ô ¹u ¼ÜÄ<þÀ}1¬ð™éöý¸Ï\Üðõa[„âEQàã™ÄÈÒ>¹¯Ò’02˜µ¨9*åÇ¡G}]…ºwS„ÑU§Å2Ñ/GÞJ¶˜q,A‹”ÃåïÌ"LþË¢ßßÑyÈÂÜ]NÂÊW~·þÇþ}æäß Éõ¿ßýû)”æïoýËÀ¾á0Ƚ® $ó¡˜+:>vzÉN§œa«»‰ÜnXŽíŽÅf‰ÐÍâŸæ,t8ž ˜3 gŽ\«Õ•P={§£žÑ-sµ6:tï½ÿŠH È3qbH‘ ÆFËSw¸r½ê6âï:ù8nB÷ާP¼æ?†9¶Ý«>E–çßÐû$±@_`Ç‹#…ðõÚ.v€G¢É~ç}mÀº]ó¾öa²qJ[ÊaH§‡€âfn€C‹>³éïä_jd‹Hä_½¯›Ë÷‚šô "`ù E„¼ËBjËÁhq±¥Q"!ï@9í8åñ.Áª7‚F’ \#çX,†¾ž´eÉr¹ÇÀÚeíøÖRõ’Ï.ø7ƒFw’{ÞÊ}\ö´ Ýßb$t5wzAáV÷+~+ÖoÜvSõ"•H&ø¥@À9½ãÎÜb»yXF/ùen€=ÇmKÌY•ÌÁSXAAõr÷6¶'ß»äzæe lÞ~EéQyôËÎè…öq‡t…¶Ý¬¾ÀÓ¼züÄ®ëþÊ× Ïª~yÜqöXè~ÏÃ^;úŽH|ß&_ ìàuèbH,¬»‘•ëþ4°èX¿Ý5\³;€?ó>@ ßðbÝKíì‘zaø¦yð— ‚N«¼H42•J¦b’  "@1Ï¡ùgPÄÅülN­ ?à_.ØÜˆÔ`ÀgãŽaFÃÙüé1Á>#ÿ0˜ ‰þqÓ„‚wJaÚy̺`ñ™ÄŽOŸ(^[Þ#¨ÿÎø—MLcÒrMºØ-sG3ñ 2(âœ@…_Œ‘³|)szZeµÎ†žŸø¥·3ñ/eà;È(·ƒ¹‘(…ŽÒq»K4~\pˆPýÿþÀ4ˆ€GÜrý£~Wý?–†Ãˆã?W1qùa]±Æ¸‰)¾VÁðG)î˜F¢a®7nîQ”é*àêH¦âÍ™(‚ç‚à:ˆãoEL2Ìé0kcã8%a–“B¡ã.6|¢( ÅJrNVbü#02QŸ&ýŸ–ßÍûßðÿÿ¨LÆ!Ó"4ƒÊä9 `ª‚G±Vè85ƒ{d0Ó³'ÿÉ݇€€(fE¦¢0YŠg˜Ì=áxc!X0‡0÷;…¬ šþ3ŠCaÒñÿÀýÂáÄw~ûÏFbï¼Ãé“üÞòŽ™L ^¸ò0•ìxï_lÁD\è˜2©¾ôàAáäUtÇýŸ?þðßñk e§œSp²Á‚ £F¬³0\|Ø1ŠÁèDE0²O#Ñ}£èÌ4F"X}ŒÇÁ38Ï"ؤaôŠP(zE¨u:“qðøAýö”`£2° Ù: 1?ñcs ÿ“$°ÙÒ=#0¤(¨ f»0oŸÌäzìN_í1çý?hœüÓÓ©“.lj€S4žî@qÆÅÃ͉äÀ„C€MÉOï÷Åÿ8ýWk5iÿNít˜÷&ü‡lwøDSΖBŃXÏà`|<«4æ#½qo b‰2§§ñÿK4Ëãl3(–þ¶aç´2-*&Í¿€?•xOÅŽ[ßßWÿÏGaa»O8ÛØþ˜ðJ&òk´¾2U[/æÑàøGbz†½ÇgAÆ›¡L_¿×F˜"ܘ” ‡œŠáÏL'\ÓX^Ñ%÷ H€¹x(¡†âˆbcQ–™SŒÿE,f÷Ó›ýŸŽøÿ¿áÿÿaùsLƒØ²Kç|»Pj.žœõ §âq3ký‹»OA}B&3l8!!?h€ÁŒ"(Š4™ÌÅ#=G3ˆ:E¢„þÉýÿ7ÇÿWB˜øÈɲˆNvÃóÆ€¹ü)lÀ³\vqaÿó1Ù ý%lüñ%³’s<íüïO¶÷ûC»˜‰ûŸA‰¶Yt<÷âô_€‡ò(Õ+’2ø3É™Ž7V ¤„bwHXHÇtÉ1JS-ÇÝtDåžÇ*öJö&b Q)Çq²€¬d 0W :…“òaªðŸ¨sR ²sžÑ$O&3ÉxÎÏèbäˆñ.ä~Š‡ÙŽ>-øÇå1ü™“ª'í<…9(’'“˜+€gqqÖ¥8ú]ñ·Ì¢ÿ`á_2Úx®w²Éd‡¿4†ÿä‰èP2f»‡ %þQ$Ü—ÄO&ð?‘ Db8.ÛÀD·`’¹1ñ]Ç$r`úIplýïñg†Ä“ð0;ûõ¿Œ‰?:¹Oð'N`â  ›æLló>Ù..|boá™1?u˜ÈÿãRb®ß1†ãø6K “è¸Odè(d^1 ?7À¦ÁÜœ”Éãü32phªñ/Ç'îd: ú?=öÿ¿æÿÿªLƒàp××=Ž:‘ÛÃO™ú{Õ>ôP”y¸8qºGÃÔˆ©çx¤Aq‰Çb¦3Τs ®'Ìgµ˜±ÂD?/ļé€óØö šLT1—6q…þÉý—L ¢ yHØŸÜld"»;©HÌÚõg;,jräžgöHù¨Süä"Š{,õßxÿÓ`?P˜¨È$¶‰Ùj\v‰§1O×&/ØØ;<<¢`ÁÓ¤»M¦ãçŠ(Í)‰ù,€OH0ó AIT¿ì¶ù)ÜiðóMÂ# $@§u r‹Cɨ_0SÒXà”þsT\{ Á?£(bÐÝÇ)š)H` ÄHŒáy^Ic’=`27þÐJúcYAmZð¿†"^xÀƒ5Âi{Â^ýzDõç¡1žQÁIRõwÅ¿[ÿŸÖ“‰LÌ€P‰Ëp`œ™Á;”ñóþ÷½)f'ñ~1ü™#ôÊÀ3œî‡öÿ‚pøîbÀ¡Ä<ÜGpç“4™úgÚ'æ=¶¹þ÷ø3“S` Ìiý­õ¿‰ÿÄq}â¦sˆ§ø'œo2s|ü0ƒ™5šÀŸ‚GñÌÍ…‡Úø®ÂÁq§Á5ó­0üW)Üqwa>€ÍOŽLœ‘Ò±;.­Iô‰gHøSŒÂL>©N½þOÃ×óÿþÿä‡À¦Ü`zèBF#“N>Ê (~¤HÚ/§{@¦Ð'bºû$—„_o#s ǸºP(x‚‘©‘3'HOÁ·'Ù%ñgê駞ðë—àà —‘ú§ÿP¬?‚?uÑ#’æG †Ÿ¤=™‡û#ÿ;©¬ÎIdÒ0çœ19©Ÿ£L¤1MµMtÆQ³%x$PÿˆF&R”Å'“Îøó~xê™HqO(Ÿs"æ-`>γXáœDÅOU+H¸± ŸFU-‹lLfj±u™'§“vüCò[,0Õž‚½C'ÒÚÀ PýèAL•Ã#œ(LŽ£2ŸE@ñä(é‡LPL ÔéÀÿX àa˜K"mÒØOÈŒœMp»“‘Þ„ÅÁOŽ Z¿'þ¥(É=ý—I`Wï¨ÉMÍýÙp"lsN¤N&Š™Á)‰92¦3ÅTT£̳±O5Á¿Œ>ab)4• ø3²Ã#m÷h¦­ÁðwAñ*¸XÿþL_Šy å7×ÿìTtò´?Âóï?.¿æ(LïìÿkïJ›Û6’蟋mιq%›ÍÞõ%ë"©ƒ Ì€¤¨‹ÔaËv®ÍÆ»‰¬×e+‘éÇí¼×3¤èƒÊUr•X6DJ €™F÷t¿~ÝpÚ%ò·’ ‚Ÿ /Ñð¼£´ÄÅ÷‰ƒ 8vCªÇ?ЧÑ>æÇ°DÑnÊÈŸ.À•Ëÿ€«½ŽF­ÿƒÿ/–ÿ7xåÀ =QWº ÎVƒæ.6ÖRF’´Ms3àœ~òô¢^–T­!Z˜2 ɽ}rÜ‚df>rá_[Æ9ÇÖˆžë<}[¶‚æ¬.Ou>yÖ-{Ú…»m|ÌÁâ–3zº—–ñßCx°?ëøVÎúæAœÈáüºòYâ’Ck™ìu£¬¯h2Ü83…]¬“A­5"FQN •©õ $Ú6Åí8ÙsöúW`G½$%I_þÕª+Ñȯ.v¹´çG5{ͤ/­r§7M)†õkÞDípeÛI¢ÜÂà ˜•xlļ_˜\­RZÛEèöYÈÿç¶,êMÊ?ÎB@ö†/À XòÈvŒ¦:8ò_YÒv!^)~é!‰Åïè<”û¹ÚÓ¤‚ãþ÷{Oõ™çÇùã_ȈEdOîqQ(äßÞuq)ÒÙfb‡Ì ñäÀ àiâ69ên\'¿Ð«5ɹ×ÿ]YÁé-ZÙ-{¬,ðô?ñˆ¢Ý|äægº—qwÅÍDŸ¥ªÀÿÇ7îã+øü9[1ø;ðìÂ2h.ŠF†’ÚI2ѸüXG¡Í쇃ÕÿÁÇÿèÿï{ vþ4“vΪŒÝ‡Wïnäbõâìz›Ù=ÄDýRë“Ú‡ ‰®®d¸•ÈÊ$ùg-£8ZwjåâUco䧺隲ʎÿQƒÀÏ jÙܸù2 :U`½ÅÆ–¾§ïîàpñÔvøó±ø¯¶“[y¸'Ë€¾³“”ŒÑµžñðÀ+ÁøÏß;ƒϬdÖ…V`Õ˜m€ †ûp„L?ËýnQ-+&ä˜Å»óÀ…_êýg©û›¡Ý¶²·¾Òc;VÍtó¡Þ¸iËÕšÛýúT®n 1”l†_!Ù9‰ô¦/ƒ¢±—úÅ…6l»´Î@þ?ôSPë: r¯Cª8¶:ÿŠRã³Ë îv¹qýüÉÿOpüZÎM”¯1rÌwÔ4¹ÊíüN º›ç†y¾÷¼q­GŸ»ÀíÖ—×6³V–ÿ÷Û†“yû¡$!Àå¶þ¸„¾µñ”@}é$ò÷„÷‚p¾õî# |²‘Åž [*&p÷Ôݬ®Nþ¬b”IàÎHÔ•ð7Ç@>%çU[uûA Æ. ûU7î«ÌÍ “ i Ý²]¸üû,¨17¯RÿO³¡ì±¯‹ðÿ^º4iƒô$ssÕ6È–…vGÕ~ÛÃ)ígl|\`…äv7¶ m†V!„rL:Û‰hnêS Xøâ†RY˼žË Y^1ÍÕ•jcמäa™=dÊq!~h§µ<ìb´RÄ|º” öÇ™ÚÊ5',ª–stñyì~Ný.ýóçÞgv_Ý~謢Gô ÎâÖ¨âÀÔÎwQ*(UÓë|ۜ鬮»ã'úÒ>’™I<´oÌõ/3Ãui/XgŒyÖåû›Ä‡ÿ­=ò+$ZW+°”püÂÖ.+OIŒ²¹vˆMÒ3ÿ^f&¬lªëRs–x£Bñ_ŒºIîjªºŒ°lèüÉO@ç4ä´nûnxH—*‹§Þ-VÞÿÚ™~÷‹J3Ðýpë£ì¤\kø°ü_t™X¾ùÐÝE°è®’- á½/à.øÊIäïâTæ¥b¢õç^ÿ7ž$40ÆçºN@˜Rœx蟕þÕ Òý´“¿Œ72à6-ãÿjj‹× Ä ”~nµž 2[c÷¤º9þUÁ¼4xùïË0ÝÜš+Ôÿãÿáÿ›½ÊÀ@'1fÆ7ÍbcU*€ÓëKt„‘¥A þ˜ää ©îq6$žÙ´åB`©Ê•‹åðjñ]cž¬£Í­šÜ6G3~¥”_9ÈSÓ[4ß÷ÿÓ/ã¾¥I)ö¦§=·½¹v+Lãüào%8XÞ#ÚÈ„ÚzI‡ƒŠß}øµœXÕ6–Ø™ŒÒÅ.· ƒV±mv¤€Ø™Í$6ã÷Iqw±•:pÐw×W™¯œZøÂÄW^ëù57ï—öLn›ï³+‰÷»ð`H¢é S½A™ùvKPGJÔ ´XhLàN®ù¯´/ÿÿ®¦FhZÂÑžÜFÅvêI´G6ÄübÙÉîVÚÉUcô¼ÉÿgOÿŠk¶ì†4Ú¦dûC˜f»d Á=ðQœ!Ì»·ÂaL×[`f×ÄÅ8$ÿWnÜ]Bùk¿» <Ô€¼ÀÆIä_[Fb›í«Þ ýÚ\"aŽÈ¹HÜH“Ä@ÖÿlOè~ òGî ñ>NF*L<þ?ÕCމ%<¨ÜE°žœ29 ÀÉ_|dôÜœ$ÒQ‡`º¾|ò?à° q4:@ýìë"ü?×i{ÁŽ")¤¼Cp† Åqe­ÃÆ^Çcv/-ô¼lÌ|²„¤$t–¡'ÃS3ºuÝô§µ £`×_–₲-ÈMd¼­~ú¼Sö´l‚uoÄÝœî¥'6Ó²í7ù·™ÞÈ aßÈq*ˆ7$æ[èØCŠ•Ÿpð¬í18pïkí%RëaþF Oȶ¤qª%ø?C"Ó\\5v¢¿üÚSgÑâ¡g„m¢/½6©úÃíÕŸMäbËgž´ö©ÙúθÞ5‡&êÎŽ9„ÿžÍ(„DOnjO|ÂÅÛ&` EF³;×gßJѸü·§~–CëŸF½çר„ì®ÀÑyE‰b$l«~|¾ä¯ÖµÏ ÌfKÁÆÀ-y(ŽÀÜx.(ÈßLnbÇkOÉsß“û a ùï¡8"ÿûÝ´Ö—8rNYhu¦O"ÿ¿|Ëö8€ÇßýßíXߢ¨þ÷½"Ø€’“œ¬`bS&YûS¨†ÇÿU:µÁ®?,«HIwSÖÉßÓÔbÇwýñ=.Àò€d¦1xùïf‰ÛÌrD³Hÿœÿ¿Xþßø¥OÜ€¢t&¯ïUc;6®¶V¤w§„Èîq÷}É«{ÒÐ9lÚ) ó„Zr¥n õXÁR²øí²ã_Nçú'ô¢ºš#¬þ2‰n…§]F ó_Ì·[…É¢iýYâ¿•~n’iCÄÖ¦WѰπZc’©ML”ø’/Œ2†[¨ûc¬€ÙVDzxy1]û†ÌÜxh?NnmwÜOÔ” z€Ñß|߳Ņú|)k¸¾5[ÔnÞ Uûß+IŸ7ËjàäB˜ÍîÀåÿ¿Õ²ÎåÚ”?kÖdoa‘Ié?M²Œ¬ºŠZ3ëÿuì\ɯ0ñÓDtMîXà%…m~mgVÊ®Štâ¡âfÇí°0ö ÷ޝºÃÞ¸×!<üùÿØå(RìXl9y¸ÏZ¡oor"ùsj´ÞýÄ©¿ñ•€,Ú+zq©ùv[[àI Á9ç?d$‡ü%Ÿ dÈfOˆØÝ~˜DpHµ@ý—ÎCl5à]¬ÄÍ­ºròßw¡‘JïbÜÿÑÿåS[PŽ}]¬ÿoþ:✶àÍ ‹4×Q-M—™5¾£Gè ðdJíÁ½‘_;þ É»¸æ !Ü´ÖÍW’£7-ðÙ©¾MŽ:þåj`lšÕ-[l⫾>´Žú›ÊjVƒnG麑ã¨à[Y?Œÿæ&^Çsë<¬ŠÚy¸W‚~ý¬ì[æÙ2=ºû…ÿìꦆí€XØF€Q›P¾ls‘Ö“s=¤KkkZÝøúò¯@vu4üKËÄCJ×—ýî3w®«/Ã(£wyNw]ª}K@!Oop·B(]·]¦<ÝÉ›m–{DÓ]ä0³AËÿÛ¡wkˆ'¹ÎLõ @0=ëÜw·¯;v”!WÔÝæòÈÿÚOîºGwg.4G¡ÿƒÅÿ/–ÿS}® ·s±Þ*³ºhn~›Î©¿DýbÑ![ 3Îb½gä™"aoÜtIõšÜ²r«zðjWðD—•þ *#ðŸ^:dëë=Y?¬ oü;;Þ¦‡pOÏ,çÐ[1h0ïJÅ_eû1o¹h̯Ò™ ãO”Uvüø§–Ö «¨69¸ýM·b@¡åÉìIÎIL¢tì; s™ ¿s *0_öOÿI#?^;fBWöµûx`ƷИδºÔÉ×9´„ÝeÆÏÓÓ†Åîá|g9ÿ©m¤³Ë "º5ÓÄ7'„MŒj Zþ»¢Uœ"/LÉ:SÙ íb¢„ ÚÑ{Uà­° –ÒÀùbƒ÷÷ÎüȽŠÏù~8Äìªß'Çhqб°Ð Im\a×!ûÉS·²}ÿG‰'aûÝB¿g&¶XËð[ù¿Â\é;÷¥GÜËPõšA\à$òÇ£'’·JÿŸ­I7?Ù@ÊŸÄfÃwðl#µ€È×ä¯ß@Xðÿʺ îÊ!Ù}¿RŠüU}(B”ù2À¼pæÄGÿ>ùá.qj¹£‚0÷Áéëÿ`ñÿ òßïyÌ)O¨¶¾ãšè«ôñXl®¦“™`²0yÖ Šº6Á‘´túp.k%ˆî-Æ<ÞÌÕ·òC#Z>fàXh¨ÂÁ0xDpòóÙ±°ñô·Ü^ȱÑu£´^øIuö¿ =825wÒ-Ífb;Ä|¥/†µ`aaÓJG.¶ Mô\+K‰èÏ-LôIC·Ò›Ò³€|pƉ2•öz í+õ·;ÏW ¦,ê7ü²•¼³ï=ôO~šñü6_>’áú‹7åKÌÅw¼´*}7~1B WëiV¹ ÆE3ƒ•ÿ›:ä‹åˆ¤Š£°,…üc< àPK`ò¹È­´?3%•ÞÎNO~z^ä?»•ßÖüÞ\«%˜_×% Û¡[ÿ *m>ÚhdO«ëã¾Ï[ó=X޾ÈÈ >Nþÿ|ÄV Ê!hiÛ+-—ó¡'‘ÿ$ªÞ&ýÿ%Í3!  ¤°î q.ñ|ØMp ò÷ Áþ_[OÂÓýꪬÇö ι?ß#ÝOP¨-pÊ eGzå,äà®ñóïRÕl%ÒÑhü³ÓÖÿÆÿáÿï{ í-ùX ÚÝ…ùU°Å÷´Páôïî'TUçu³Ë— µ@À\LË^ùÌ "RzüsÖþäžhEšÙ¶(M€Ér(ûDS÷l‰x%AÎUõsr,Œ ?ªýRþ7ç{áùÞµÕRæ8Ÿè°˜¸Eã¾Ø>Niý¤™‘}PŠ͘Ö°ì#‘VÌZ@ƒp–qº‘Žm#ïµ@âFAq3ÓITï´œu™[Óváªy…%N]þŶô¥ý8½öÔÆŸgÌÝíDOUþÆsU™W‹9ÂõNo¹P·¹ý…f65Û3Í9gìZ‚àÆã=ݰü÷²ÀÑNÙ;½H8³;ÛÎè x\@r,êFò]ýKc;_ F›çDþ{GŽh&6ya\HM¸Ÿsxâî=©×– f¤.ÜÉß b4fñÙáˆÃ/“„-á>þɨ¿+ÿÿ­ªþŸªÊ†âw‹–Nþ;'’ÿ>Fü–éÿëõÏEx¸-®ö¤=É©ÿnÇÆ|Ï–ðNTu%eK\¼Mä9Å’Ì €Sþž4à;â*}7à(a`àòÿÇwVÝK£Jõ[ëg4®þÿ5'Ð(àXxœì½<Õ}ÿ?NY! ©$ ¥l)eoddegï=Î9Ÿ×Yö^Ù„„$²J…”Ñ$¥M¢’†ÊˆþŸsT×ußßë¿ûJÝÿÇ}½zôvÎù¼?ïõ|?_ëý9ÐÀŠ1~!›ÿß\ìk K´ÏLïR|³úŽÐ—€‹gí_¬³˜U Œklô[Á%ÏŸÏT&Ä8ü‹b›—F^çÍÕ2•øP€³íá¯ãœ‚÷Rì;hÓ˾XwÈ”~ÄŠïI‚ ýÈô4nW³²½ÈM pŸ†vé¸Ûï¸)ëï鱈'âü;d»§Ï`u:ÿ¼Ó¸ÛÒâ.yÇF5qòñ|æbiQ§×+‡×‡»Ë©°Ä>üÈDÜ£Ìò ³ç…ØgÓOÖ¦û«uÔÝeZùž)dÈ`kqÈØŨÐëæf€ìN…™>»'­ÄsÃ?œSä‡~Ìnøüò‘¬O«ô ÷¬¸WÏ™Œü+_ÃíÕaÜÐuî#Ü©”ëÒ‘Y¡’m×Ï!½;MGƒBçË›«ž¸ú…’tͺ|ô”¸Ï‘çæ’61çœëMF|Ní(q9ž3ÃÁ¯wðuÙΉÍña·ý¹Ql·Ò î¾SÏrxO>q„S“׃e¯ü¤p4æ`l–cà­Ûª½ëÞ¹âaqGÛÈYq[O¾-D‚ 1Î(}ds¨’“—®œ¤—ëÛžµé#KŠeÝÚ¦²‡»ºIߨñ³ À{ÙÇþ|AèßÕ `3¹*˜Ü¹“­=K=fŸ<ÑŽ‡tÊ€©ieà?–T•»²ä.(³òúG|¸]-óÁÿ`³Þyè´›º;S8„óæn:<ñߌ…ä\ÀæSu]|[1š\°c{s¬T&›Ô1Ц×êü”e†&Ý/FÄlQd¦S”ˆ=_ùLèX£µ’wÐÓçŸr)/ožöåOwjÙ¾ßõº@äœÙ1ÓÈ?Æÿ ·Í$OJwïÊ›høÂP‰÷8y(|›Ñõ/f¿õïá_/òÿ?þå§Ó8qPúétàÔV~«]y—Ø•®n :I®÷oRÀ Šù2 !òÇŠ`kÞrAkì~ÿmÉ`zÎŽÊœst땩ÚƒÙ#±t¯Èþ¥Ñipt!>_-$”e˜!{H¤w‡Ö_žáE5OÔ…îx)¢›“Ûº«õYŽoìOÁßqBQÅù‰¶ïµ«´…I! S·°…~(ÿE~˜-ù¿ä“BXÀæÿÄ-å?M ý°ø%¤|5.GÂF,{»v@fÛ•D)±'´¡ßµÆÞ:¤ç¯i` œ~·y$¿Y‹dwúãé sAEô–•ùÒ°¤—ðÆC¨SúÓÕó»iùZ w=ÄGYEFkp¶ëý­†+ÝõF÷Áãd˜']­åˆï†Š ™5o¿Übèô½ñ 9ñ Áò¦ uy)€XþIáó´È£8þÖw’¼Yºÿ}‹ûxÿõÁïoAÙå­v°üã’1ðïa=w4mcŸŠ—.xe³9€é6ùåÀ„+ó, 1 ä>s)]?ò!Žn$ËêÊ%sÅKîFûÜÔô5Øù ft±pmHC•8·u\UÁ(ï1Þé5È;¼R^i1$é<œê†XÕb¯²a~mÞPòøyp†ýˆôëe¯6xV¸Í­~:ÏNçÖÓ5¯M’àü)Q[™Î•'LK¶öúð˜K¹Kºë´ræs­ÏmsۤܲýÞœH3ÆVaÁÎsøvnßúÝÇ÷GvIwÐÕ€Ê9€wO£­²*ϵ ¸…{·àô±­°Z¯D[0sÁ£ü7ÝJP]7©"Å¢D³ª( §BÎÝF|–fáÀ‰/¶W:á#Rżù¬–¯ññ¸%©ŒÓO dÒj›ÉÍ+Úu ‹ÿªÒ“ñ+‘KkÚúž)*¿ø Ö†»8*D•†à—ä æÌ›¡UãÃÉwa[ÏŽtØ|Nó&@H8¹Œ>+êÍK¸µv lIh½ÐZå\UÞ“ÿ ø—5­[{=Cãë'"œò{YdžÌ¨¦5fÓ=Þx/õ¢À_Îûãë{T0®‘.iùÍ9¹_±»1Tvéü †ÑçÔ—#i)Á¾Ôø'ïëÄ®a¶öÊJíÁzäC§Ì-Òù»"þþ^D£Ûã–ü½Pž/ϳ¼¨µå wéõvò§‹‰!›M¬ ÿð_ þ7éû‚Aé#Ì™ºÉC¹ŽL/è8wfƒ4jÎN.mƒP.ž£l,ír°R`sî ñ¬(8QE¬©ldÄ©§W¶zUF„—ª“Dèæù7 ¾¨’±Áöî…@…½J[[.é[ó¬—›‡“D½ŠK”daCv®iܰ“Ýwy4ï§àŸ%˜-AsßÃõ)zœ Üåƒ?¬r÷òÿ‡’ÿ+ˆ[Tô6ÿ?!þ?u9òãºØ¾Ù]÷¹ÍY€Ô s%·øúä"ƒH® \°w÷åÒ¡õ§8ÎØú3Ÿ¢MGŒœ?Páâ´I Ó+*Ùà_×ÿêªj‘F†›¤ÿâHè¸ĕO«Ü À¼A%rUtø½J‰ CÓ»í=[âüÉoo]¯h¥3à2³Üø¬M]Ìv>øÓJò5Ž÷+ȧævpF(låö«6Å“ a½zDÞÚ£ªáÁ# Ñ×T)‰wº&C‚aÏõáp%…7ÚPQg¹/ñˆá†ui§PÿМæ7GäM2‚¡Í†i™¥™cc©§± Æ9ÐÈìÝ0Êã:}„’Üñ¾4¾éö.wÕk‰Vê+ŽYÚfGjg@<˜Ë¸*©Î³ö D\f†$Í’ç|ö:Oëì Îi¥nk¹rŽÕ›Tçì ÄÜÑàe5¬¢¿Ñr¸Ç:ßãÝÚ¥Ö›/¼ãS+äaÑHÅ¡hðmP‰ˆô¯ÚYà”>yämHËë~1ìãûUa‰ý+’^¬8‘zn‘\Q×§ÿÌ/PWyí±¬îÞ@׈(6»èd8. ‹Ò‡†›]°ú5+üßÞ.]Chôíy“¿]HÝMõŠ‚Ì—Z ¶Èí½%Ow˜òÚ'?óý2’êP–¿ ‚héˆIÅ Šÿ[Y¥ÍlQàÒtTÏÙ·I)#éP…ÚwAõ¦·«zÒÀå=™;úßX5g[Èô3ÆöÊE:°íV‰—Ü&b“ »±çaÕË"#Ôí¥gÜ8Ÿ½¹~=þwVLj^žÈž Q7 4&Óµ#÷0™×é ­NtðJÊ\4ιœ4iÄf*sl?=m½ZF&G^[ŸbÇtî*Æï%VÈ¿®â€dlÔZ¾ƒŸ–œ¬Ná–,½´Ä­¯ÕÈŠ >$ÉzéáßÁPg î—¸[Å×)'–°I3®ñKt¯7«ºO¥ÅГÿüŒÿ'Eö>apÞÈ*°E{’¥´7h`‚ãTÅ…¾|陡ÍãóÈåy¬ù·äh•I;*›*•«49÷s„*¤‚}æ·§÷1ÏwíUAVðMŽ^§UbAs»’Üþ¯ëÛ’÷b”ÚÅ@²èyr¨íE 8´>Ag¬~V½O¥4­Iã§àóæÅZq3à\®ËêÏm…Ë:ásOíäÿ‚‰_`ÊZ¯¿äÏK¨OòiHö L2¹æB/1³ ÜC‚Z|Ö“{¯"çâý¶¥5ÀéèB·±« _˜šéÎ½Ì ïŒ.}È»­ý¬˜ÿñ9¨O—wÏXgl3úƇ®2—H Ñƒ…ý©üé²Ù/ÂÆ;¡²nüª pèbíR˜xÀ%, zÝl™¯£ £&xáß “àö½Ž(ìì7룥¶ŒªéÒz³,Íøä¹œ­…[Ã9x+ëñàäz?Ϧ¿ßMÃáàI–Jh¡_¼¾î=)@ WÞ¶¥¼ã#P½Í߃-%M=á{¿×X¨9|Ë”1´…KYoEún¿ô†pÌ=e¦nËÅá`EÎ׳k6í10'`,†K3·:–˜îIHÆß3S{¯¶Œ³{ë]€ÏÆB…6yõ íç"?tŸË±cŸ *7t•ˆ÷Þ¢Ö4zðÃÀKxË%ôä‰Ô°·ô3‘n*Ÿ¿/xÌ2`å¼ý§¸ ‡X_-i0nÛô¶s5œx¬Ò ‘Ò*<Ι±bŠ£#0.”—^uÝKJîq œûÊ«'ð¬g£[4²¸ËÜzÁõ¼1‘˜0ÝÏô$%6Å3æLó:ˆ&€»SfØFû©œãĺÅmÇñ2fKzÅNkCä†*Yk¢žBcìƒðb§y&8-6*°ø;ÛVp(¶½]7ºá&p¬SxGSe jË d`æ…'b;(pÅù úF#8̶ ,ªm¡Ö4F?eÊ¢àXdzjÜ%åì Ò²Õvvq%èŽ<-Ôiº¼ü.kÞ¯ÇÿàQ—|…B2Såç#ŠÏøýœO_T9P¹>ÎaÖ±%Ÿz$‹œ…6w߃ö5:7_/³×Úr»ƒ©G®$|kË©€«_èXÔÐDüCüz³ZNÀÓGŽ´sš¾€®¿ç›:·€æsø | — «9þ Èÿ3“Ço³½›úô¸â¹°ðð1¢®ËÅ·¾o@ô­ @ä°"CkI¨¾¼âŽV‰” ²U/:„ò@î*Š—Yº«]›‘ÝØ—×®H:§rÚ“nŽ]€ׂá…Z®:8•UëÖۜЦêdŸ}Áô0ÞšhÇ* WZßãCITÀàÀ¡g?ÿdöÝ<}‰„3¥£ ©_âsoC–ø ûQüwú1fäë–¾`ÿψKÚ?¸àCŠúí[¾oß`)4¢|ÖU]fÕÜ˰oÀ‡ŠÖºµý2I°ï‹,ήë @3šekÕƒ°îM´@f¹ÛÙCMS¯hK®„‡Òn؇‡É ÜwÖl\ãÖ^Ö6‘¸@ñ§‡££} î,n-ýjÍEö¯ëPà;dÂTÁgÛ§ M¾A……ª™1¤CR©à|´l7x÷?郠«B*õ<ìÖ÷ž0áäA‹Ï#¨Ãú:ƒ›«ÐLhÿâ,Ü+u‡xêœ0•®$0… #ÎO3W-_¿Èà•-™†WÇ^Cë–1Ñ1_¥–X^º½^'µ»‚hé?”€®Ãy^º$›©Ã–%L—@~+»R‡Á Þ/A œOÜòÏ^’Ýçn½]•¥¸èH¤„Ù° p“ 7OvÍ~Çç‰[>³Ä hk®-‡H¨1ãý‡¿‡’l¢÷)9I[aàoV]¾¯ôɪ»!ý“Õ-º†`„l¼W`äeÑD3Øl»ŸMÈñ1çäÄ© =S!=Jh,Œ›”dºø›l·š­e¢ÁKÇå>xI‡FyÓ²’ ì¤Y´§ø™œx€Úó, ¿ßr2J×Qõ~%lmI ÓÛÊ’¸w!ñ/\q‚—¤Œà>Ö!P‡ŒAÂy4YÀ›µËˆšl Z¾_µõɾ2ÛG{¢}co¦ÈswÀuñJ}hn/î%­É&õ€£E`f‹´CšhøàۇܖüÕøãOËótgœÄGB[öP#t2z çL1¿39’íMr–¾žåJ<»G®‹Å˜Ž´ZÊÐbe…_“Þ‚%ú¯šófðo»t|CxÔQ»£Ó̈áúÍ+Ç"J/Èv”f°b¿KËóOð'{‹®¿ß‘¹×Ÿwp¸°vÏ!ñðS™pðøÕø/(ÿí ®GJ? ;”¤?GƒúkÀêø'1}#ƒLû•á“{\+B‚Ô„Ã-7e`-Õøœü¥LUjgÞ@lêbh8O'™¿Ÿü¼Ë%Ñ3 d:}7<Š<Ú¹èÚŸ ÎIÆ+‚¤Ô¤WÃI¼ÔÚ>5NÀ¬ŒûÉÎÀ.¥ÀÈŸ„?ްÈOÊ<¾m3R+ÞÅØîÃ<‰îÿÃÏaDþP¼pI Ööÿüñ E\“ˆ? ýeN>—`4£­ {ж±ú£Ù¡F5G·3HÑ]¶¡×·tEº åÚç_Þ^ÏÖBþxð_Ωw0¡øui3l6LOàx(Úî»§¡Àù‘]lkö 4¢Ý¤¾|n‡¾<2ˆ§YnVuW¾é$´Ÿ°­}£oYÌ“lZÞ”ÞÛÔx…“Y:8®Ÿ=xîëPnSÏ \±·µ"5½`ÈçÖ«Üe‘X£qä–媈¿ýeSîQþ>gïᬖdNØlý)Ž`– â9Žõì±íL'ZàÙµ®8½Q7–|è.Ú³/øuÒDp…¼\4gšTŽ7OíEzxúŠ7>2¤aºëñ^çÎÓb‡¡Í¶[üï} S|ñl;W°öÙ¨æIØ:c6õ¤¨:/U^‚Ž£vÒØe÷[Œ2¹¶¾*%޲ú5ƒ:µÀ×úFêŠÞì¼rͰ5ín¢R§ŒxÛGnï’£hôðñnmïî„Þ‘Ô;ôWF6ŠmÿbˆÐКº¶Ž46³)õèï¶ Íq2šìÉq(iÔ™Ø|܈m#< £ÉMXÖ3wËÉöyA÷]/v`½v Ò”V𙽠ƒæª,ê<›q]\ª“ȹZÆ0¥öÍ ‰?ð¹ªÈµ> zð4¾ 墚H9ÊŠ#ÍõÌîzbK¢¸| Åß*QvÇn÷gEÆèT<-ïá:Wz÷4ߥ÷sj) û!Ÿî =Ìñn¾'G&áqÌò_‹¿wç­}0ºC«á'ëÝÞƒ0ÑÉ 6|ÁcÄS ß¥aì=ç(µóCá#–E|úyeó~]t²öõ²~:s¬O&8_¯c7Äré:¸çÜ6ç÷=§qYÂíŒÎ„ÇœŽT=Bð¸â(ãM:×cšjnt½†3íô |ÿ.ó+NÝ“ø(ÀòÁÀš¹‡ëv‹ž†­JôÅi/8ÿ(à òöû?jMhÞb‘Œp6j‹E­FÉÙ×Äûî³ZnŒeC®v²âlšyõõÁMC¼•/F™0vµœ¦·ÜXfÿÐeIÄTŒo·‹XVÛå:`hN_€NÖC[d½ ëW¶ ßʰ¸°¹®]Íìfïž]ßnlSñfˆo_Öøù(™Nd;a`÷ôž8ÿh±®rïu‡?•L]ë‘€dçåuõðv.ñÄáE 5Ð"7Åá™÷V#+ÒoÙgk…Upæ×÷E–+Q>·¡WUn‰’ËáÆ9z« ßÂC Qî‹áª.Ýó2Þ:²þ)=ŽU$°?coyÄ´,€.¾¹jŸ‡À†–eò’²ÓKŸä<'`Ü–çcMÈmy{õŽèFµiW½»¹.fq{òe4s—>]éŸú˜§Æø[L:·'½urYÂ,P£h]<›jN$Ä=¹Ö`Êë\[,˜øùÁ×­õúžw¤¢N)'<°¿dV¥nQË3Êí±pø*D `£yùOÂ_FH°(ÜB÷Œ[Š®ÅÁM‘‹Dû…Ž96<¤m`hùóüù§-È âAŽ[ ¦ÿÇÄùŸùà€Ä?Ùºâ§s¬€DË¥ŸÓ`U9Àì3â-¹K `ÿ2­ÝYMŒÍ ût p¯¼]ß^v.^Öµ TÉdè_jœÎ»w6²¶ aèª+KݙǸ`ûËž£äðxÔADX—:rSSêLPøÅÄÍÉêмc­ò«—YÇ ¬a=+s;àX7ØÈoã$yÒ N2ò2 ^ÚýpEñœ<Æ;¤Ú‚Jå Áˆ1E/“Vé·ä]¾ñÄÈ¥’JØ’Ùš&7“<¸´ï}uA m}RY>ð.±‚ë2aþ†ýÊènÁÓê‹qOTu§U!È@qxpu_ºÏZ×'¯Û×<™Vi`Ùxׯ8Z-å*‡€c«çVn»•pú4©qHqÀ%•K;@…Q(VNÅ9mH€ºäݶ9›}`i¿ú8AcÅšF]Ýê[âê>Ë#ÞíÓýô–Ýl÷xèÒ·ÑÚ'ñ¸\'íAÌ”Íg£h—Éïçf¾–leß NZ¤® Ï—h‹X¯uìKyò¬JëC˜Ò*É;Êèöp~à2w‘ãa!c©Š`Ù/tÄ ‘㟽V°Uid¿™Ìê–eg[žµ°_vš~F:½æÝÒÄß²#š¯ö`bî-w¡W$Xݲš×Û.ÿ®gMé4„(èÎàf<øÐþ‡h’ÂNsO«¬6MgÝ¥•”¦Ì½ž¼ójì›±b‘Ý‘àÝÂÕX ŸäpC§Ì¯Ä]ŸQ¡xh÷Rå‰(À[ÈBþmöXIŒ°×çÙì £¸(vÏÄ-šËÝsÜ<©!\0"/ö!whÕ…>òt±8ƒSºQ‘Ižüśܙëo[Œu|Š“"j¼OÈÍ)wÜð|—ßáœ,Æöôލ§bœq¶Þ9 Ø5º9pñRÏРVñx& Õi!þ?ƒÿ5†A0“ú|4ºCáÀõÂ] oä:@äx2´r\Ò›%G÷ ¸¼cä` .Öï>@°°î Û¾xÝèÝ\á/†‚k–5‘tâ׳/ýøØd` ÀƒË Dlûê\'ÿc-.ÒÂï¦^O»Ùªu‚mYïêmû[°oÝ‘ºÏΓåøc„ËØ†ÍpÞhY¿qy€òXÚèÃ/Là½Zâé&s¶B°¶ê!.“å0‰ŽQ¯—‡ÓNÊ_ò2+¾”ªÞðx÷á.i¹äå7z4V®‘í Çñª,g'XWÇŸÍÆI±+AÐDG—cFþe>ý —ÖO¼íY#¨x©ÿ‹·8qݘb%wÉ]>¹X¯©¼~Ÿ-ÑÀäYÈ™¡ !è’ÜÇo¼hÑ0ÊëÓio¡@®¹ÿ¶”ÇR+éŧ…¶¬ÑðÙã¥ïÙ$—îÁ!ãPL„,7 !4M?wS¥öC¢9çp~œgU‡kÖ‚á¯=·1Y“kI£­eI÷é wH@¨š¸°õä°2¼¾9ò¨®oçÄÉ¥Gð‡®Ê Þ1e¸Ú¦v€Âñ”Vå ¯à’Ïe{¿8müpÜ‹ñYèìùPï;¦­bŸvûè'¤ǯtü:ü=Ã[$‘ׄwϵe:6yõmiÂ:*àó„wdïóª¶;V‚_¤»íG%bÅXFi8pú鑈¤ÍkÀe•ÉûÄÑñúi( w½•¼CøóUÙN±Wk°‡˜–a³üý´žlŒ.8™¥{%ê_à¯ÞPýCÕºÔz;€•÷Ÿ Ü]­ó!ÄœÅ{3aË~þ?‰ÿñÊíV—®×¬[çQ"οV8¬†œñH}_ˆ¯æ,€º‡£ÜãMAD²¹úÑ‹¡KÝÜ”ª9M,¼ðºÂ<®¾ÍT „Füð ƒÏ?®9Ø~ N¬¬#­x¡Ðï-¢yr™/pÔÚŸ:J:½üí¬¬3®o%re á? ÿL'²ÉÞ€‹×gÂśeîâOlhð©Óu„e‚Ffõ’ÿ¢?ÈýàÜb~ÈãiÉ¿—?åhyÅãáºÓ›ûŠL…ËNò=Ï2ñÑ +Ž(ïyŒÅÎU½qá2t»W={Òà r• »×"`}9U*cõÈå¨ãÊr0{k`‹¡Ï}À7$™›yaM8Àê{¶ÅøCÝJ~GìH»šú9S·J]Å:ÛR<™ÓÑF°ÓÂLy,ÿðìõ•A Èê¦'O‡ÀŸ·¶ë9ËÙvÏ¢"ÐÙí‘:Tꮂ‰¾‡& ¥-i©²mužJ8oTû_òtú ˆÎqž†éUØè¬ÇY¬Á („Òn΋ûH ëó ÎK¯àh:š‚˜bš"Žåù‡%W½Ãz†‹Ÿõ¾œ£ñ2hv›ž¾¨ëŒ϶ ¢*%@3¥Ê-L)î,²xS>Trô*·s„aÊÖž\„ýÆŠ%„ñ¼7Ï÷—\ J0Uœ´Öo<"ØôþÍú)×#зå&È"~k*«TÛŽ«Ë]ø-;ΓBãÖÉrûrÊ3Q^íËÎÖrßK‚—ãÆ¸É ÊNDûÆ È³¦oO+pòâcÂ:ÝÜ94×-™¶tFJã ûì¶Õ0üªè¨šCb»i4æ<vüM^ÍѬá{1â[˜w§E÷Ö¿–p~€Sê Ђ«fØÓ4£®â”b’½`ø æ *æ¾’NÓ¸KAPM%¬åðQ¯L`Ã,S:XÙÓ€ÝÑŠÁ_w±OÙ«¨ñ™áθ×+K=`Õ±f¾QpgÉy ¸˜æ€l·<Ö¥ú¢wa¥à ˆ0ô«‚iÃ¥yR¬¿ ÿ”ÉõHj5‰Ç-…Á/×ñϧ]ªÈü-Ó­fËØ‡ìo³zÏB3öBDÈ­ì²Ù™­Ç²I _än„v˜[´î”Ÿº>¸’ï!rMŽ|Bë‚§©Zᾫÿ ‡ \»(C!¶ntýq|E^ë‘%{Í;ªœ¹}z7ûËðÿiü÷ŽÀ°%‚Q„ àBåºá¥l?ô¦sË žI«Ÿï­ï‹UM ªY—k UžyÕµ²‚3#¡EÈ…ñ8!1±ü@…Ѝ(ÄÆ¥6Æ{ÝÇ73à)Ù75žƒ| “‡>n{!&Öç—s¤§ã"LtŸÿLG`Ï#ý4ü·È½WJ1ï®_}³ÎÚe ãôÁ¹ÙR¬Šÿå?Ìýø'ÿõÝ¿%ÿì(¾Ö?úŽÀ¿Ó¶ôS<`Ë*˜Ú-^îµ€m2€­^ÏùÆwmû6DTzÀ”*Édˆ»ðþÃÇWSî÷'¶Ýÿ@‹__^%#(uÝX3‡ÍÔ;%–{…˜TÈW\¸ãmþªCÛ܇·KÎÒ uˆ‡ É pDÒŒý€Î¸è8³0ÞûÃL.0Ë%4ý—äjp‰Ö¿,'3Ü´•v9»þ2AzÓøáy/šï}ÎÃÇ71˜GMU/ÀćIØ¿” áËh*óöS§P÷‰êi<Î¥_wØM 8êÅ |cлa@硹RäE•ŒD²¶Ý:kùPœËâ7^O³*€²&sèdïMQßkë3cÔ¦vŒ}4¾z[8®têç3KÙT5ìMQ‡¢}qç%8ËAZ@èIïæoÝͯ»ò¤ÁNÏæÅøž£Ldbpä0»°Ùèèâ8È„Kæb=•æRsÐ9·Ž0 9óqpՑ䣟!¼$/­|Š„\ÐScÞ¨iÏ…åJÕèãÌDZÈ›f0åyÚ.ٮѹiÇõ Ž «\ÅD|Ä­8°Îwtaï²J’³•TmR}pä^)€çL‰’sîÇࡆ£?Ôìå¼´aßÎI«<·…¿çÞµñËzwgÄD„$ç$­¬Ú3ø"€óÃÔbœ˜Ýا]Þ8ã®” ã!hMN7ÀËš!¬hõ£»ÍlõÎX\™Ýûy-SZ´mëTÅ;Ú´à¡#dc:|&ÄM@ç£l©‚–‡Oþ–Q‡>²¦ÄºUúï«V¡eš4‘}ƒ!º~YÙSB?"D"?÷hìÙœw~Šw®qDŸêv¶,øÒŸtž1#Ò¡i¾~¥+ïѽ’õ#_­ËÖšsþpóúàõGk”\´¸!ý_âß8íБa<’âx0IK V]yÿê"?úÇÜ÷~þ?“ÿ³‹W[=ÏádO«áÆ/¾™‘H´Nù²¤Nï+¬µ6U(Ð<ZµÜc[’ §‹×Vâ-FvAŠ3/rAâÉÈJRe†—î©\ÑþÇKNBÍ\¢/»Ç] ¬ÌÛ.Š|§¬šCà²`zd`•Nxùÿ4ü›T^­°íxN”£$ì½¼ÕvŒj´óˆ³®/ˆ é×þüÿÿ_Á¸ÿõÝ¿Ÿ(!â÷,¯£Ë;—8^—ÁYoåuÝî0Ü`Ô\L4f’×wvßF´ƒŒn×C·-{@l­³…{D‘ù×n,ìu¦“X¼‚Ï5}#ÔãcTÝïè/×°ì~/Î} °COÊ’‘%ˆ‚'Û¶Dü'o¤áàyqXtqmý=¶Íò_Ä[ÍÉvAÏׯ‹ßÕ:À®!+QFD&Ûêżø¼’1XRãó«eÇÍ…sêÛ¤O~~;7pšŽûÆñJÚÍK^v’ØEDSnJ òÂÊiÚ—`·Š¥=ñ+!Í–xF“呯¥„o‹€Ç|©·ª-ÃÖóŠ[/†IT›S0¾ª;qïô=ò°²þHr(KžÃS©R}‰nI%ôgínæ/Se|ÃDæÚ&0•Öm1iIô,×_$híèo[š {‹• 4^¤àp­ÕÔÜ+ß¡r÷Æ´†¦wY{s‡WH3í­ï:—ŸcÚm`~ìJKþô©ãXâ…Ãa†e{'XÍ*ƒÃœº÷HаµJƆ" è SlPxòqL}QºÉÐí~L‚þª¬=¬ˆ»ýéӛ͸/܇4w£3íaI~ÎmÕk ‡*»•‘¯¼åÏ´®õÍ =¯œ¿õyåÎ\ÀŒ8t¶d6ÔÞHÞ­|Á] ²Ãx S±PøsTµýÙ?AHÅæËŽØ×#áë„3›a½ºî¡ð¢j(’L_3ºÎŒí…c`AäAVÓ  Q¿ ˜Ý¯¨æh¾*L7Æ•¦f¤žtbiTŽW¿°Ég0ÜcÑ!±–u‡{õ,YËõé×àk>ÈÏý Á;JiëfHµzž5ýÜU¦U&„?Žc¯+ö¶·ÝÁ¥)l.<Ãwù7ÝYÝÙ§ÖÒ4ž’xyÅX¹¡eç¢^Wž-†ÖU\âøïJ:¥;Æaz„cñ4ëÊñÁk ¸‘½á\›ÁÓõQë­¸£ô1¼¹<æaººŸÁî„T#§ô€˜˜Æå¿ÿŸÊÿ at×-I’Ù{g]u¡§Op¨Ñí ½Xç+ûeg®YÞÛ‘ƒõ9[Tî6å+;<¶p\{-™”FX—ŠFÖ©J‘÷²¢lA«Üî¸D÷ Oý­R—§Ø†VMŸwx“¼^'ôé·Ñõ,~¯žyBIn%'þYñ¹'h[O؉™ÜO@=â‘ÂŽö×|½ÁÖ‹ö®ð—üôgø¿â ö¹´¿äÿIÜcÃþ³KMà ‡Q,´ØEåT¶ÇÃŽ™½ÖqOŸ¡W§Þ”âÝ«_ƒâ¶0š85e÷zgfèŸ ðç‹È® âšS­É-ÒÄ‚Üå‘¢RY?{€èA†Ïº4/?‰_=üJhó©ÅVÅ—#}½2¤¸bä«5·ô6˜pçjÕéáûyäƒÛ2XØ7ˆÀ[­sÂÝ“š ª+oS~ÙcTK{Ž­Xþ(,´µ¤ì]Vì¤ß¼üêÑÍ£a~ÁjçŸìã磯{Ë#_ó;ªÐv~Ùs6Ü‘¨ +çôkUiÖ†ËÏn-}ï÷bÝýõ,·¤»¸*ÎçÚ¾h:üžÀE:Þâ¯~É;Õ²cñÞææ±ÍüÎjûîÖèCRŠ&R ®44©}[Î,+I‚é¤ëƒ5ò{$§îhÉ“Tç½+ºÒ»Víwe;#æ\¹ãdaóÔz_ÝÒ“»¯H—ž½½¶ìhª‘îdBÊàH˜TKÁöX…¾5Á£(d[Ã5ñîÌ—½;"·³Ò6X1r_ÇCX ü Ñfo>xc¹yÛëû„4Té\"Ý™éµnOho¼wš B>(é˜köEÀKuº§œµõ®e댺Ä\?Ï-z®|X?=ñàæ`'ºY±æ­…l1@#%– "íÒ`°´hÆÝªæWàÏby»ØÇĬSÏ:4ת.µ=|ë+ñØSêAI¶ü{úÁV›q<_XÒµÃão/˜oÓet©Ô¬ðÁ±Ä˜–Ø MÅÅ7áD"C¥sN|¦{q½1Ö„é,óLÞÚÆ?P«Çr{V8åßÁÿÅÇ$¹Û°Æ2¢§žnõHߌòfRÔl˯Àÿgó_;+»Óbm=Ø­·¶¼ñ±›”ß|¾PZPT±Ã`Mð‚†_UÌ8®3+\žgåÕÇFK> ÇØß¾díT€îéz÷Of&n†›Öyst iKGmâëRû^MXéê^Û‘Ö)ÀÛ¹.ë!>fñOÃßü-ï…Aÿh\ÄÕ¤5NéþMË7m<>ÔN,<ÖXóŸòßì¡ïìõ×wÿ~¨ü‹j•´ÿèÀ%øz[ªÂõcºL»©™0¿¬°_“]]5…[K>]L¿µ›'îщd 0¼#°6üîg;†,ôî]; »_^ºéîê[†íX³‡‚‡Ä °«­í-$WÒ©^¨@ œ'ôªãñke# °mñ5kÌ0·äþqö™D‡¹î–Û¹¼’m6ú7 IØo7hâÜLèÐìÙ§wwCö0+]<öRÛ4‰½EÕõ^±^ï–ƒ_»/tÕ¿œ·jh½óöm*KÇXÇh³g;íï ñ£‘°+'Àå’,uê¯Î1¶ã)ï;ègP /®Ç$Z/žyª€¼WÒõ³zÿ´Ë.;ålÖJ0‰Ìùƒ¤qŒãbµìÝ\èK£wŠ/Òî·Ã¶_«¾wËc"eP,B§t5Yä²Kž¯J´Éµ uºöêé¡qDaXâ±_ô¸eêLØÜ<’ª¥7¾Ç¯ Û¥[L&hµˆÌPÞ~IªöŒóœ;7äÚ^>>™U|nö<©jç³ÖR„‡œà!ü¼ä°rÆÞT>·ËÖ+/>ˆkЉQxRåâ°OŸ†ïd…OÎù÷'ŸÂQ†úÛÛÂ! F;ˈFhî”×A5T_³‘Æ92§ÌˆÂAØAð>539B•æÁµ ƒ{Û‰«€Ë/ wŽlgT[J7RÎjíŒïd»etA§4?fšâË5x°± üŠÜ0³Ì¶ùר*x|ÆåL¹ûGl›.1Žc9ÿV$«þ“øtñ'ë+áw­dùPÇaú¸¤Jèoú+ôþ|üµ2Îïˆ|ÏÆ{½’®=¾;IsËCë3Y;hù¦|Y@ÜNM/‹•^,ü>Öú•ÏFu>”W•¾Tª{%œ~HLB¹°+Ó´ÙË]e_§ÌãÖó±|¤b ß–ž —ÞÊ‹èdü%ÜÕøwð–,¯·Úµ»RR–2yÿ$¾Nëçãÿ ø/¸ØbÓ¨ý䢈&ÙæõUmQ÷‘É’[ñ`QúBµã0Á0s²ß„'pÙYo™ü8 ø9qpÑ_¹ö54»p$x>zþI pQA +Š+Á)¶‘ÿ’Ry0y$ªw´Z£4 ô÷‡;¾ eø’¶óçáÿðáÙÁƹûÅk7òoÃ埗} é»J¤ûÆÖ¡æË-Í7þ3þ7ÿ'Fã_âþãþDÝ_òo Ö#õ?¹mÏѺ«O·‰|gEõ8z€Ó#Ïî JlÛÀýxP^upäàîfï€ÕÊ똭‰‰E½ñæÏieáA;¯‰\Ê^†²Ë(æÉ`”a¡ùÉûêJ½Zµj/´×ˆŒå欧 3`ÞxD*ÌcÓKÇs%+À1‰iM÷}ÎxŸÕ¡¤Ä}ñ^˜T«¶ã£ ¡…çÈö³qÆ ó2ܪ”]‹IZ;];¯Ø×ìóKW>Q¨ZÚkJ Öæ & D²¾Éev%D¯Q»|ÆGÉ€ñ‰“ ¾enÊ‹ÌUZ“a&…%àöD Œò³­ž7¹z刾i!ŽäBHõÇ”ê§û¼lØ‹à µx`É›ðã›”cC0{OÚîÉ”åô‚ÙkaëXáªxX©SŠŸMÞÓV­ýªBÛkVó킚=LâZ\cl³ y…$Œ×€Ì ±©ò•OãØIàS12y{ë‹ðí […¬aš2)o6Ý]ºŠë’C°ÈKÌPY$D¬ººXÆ´zůh¬Â†`ê…´‘Ï4Ç[ˆlçQ Œ¡4¯sˆL·ž‰òn]“H˜mjÍfCÝ<OÉ‹Ä#U•H=1Ôé¼ O±`ŒëY°œ{7Ø1  oEwòAϽ@ÂÂàoÔ VsKyNe+@¯4¢ý—½w‹Ê/’y\ƒc-6ŸI¦›@ô³åi5k‘"&ŸéúíÉ>;ó,4yS}ïžUèpN\†W#Ìüá«•-Úiö{y¬“€KmBF$y´"|ãN«Ýak»v>gHþéøëä&ó¿ÖicdôŸG¬Å"È¡Š†c–f÷žW ÐRÎSp,öùf¸^|N£Û¢¸yÛéGé€4~© Ρ1¸»uo|ê«@0]ûEôõšÜ£ñN«9m# äáçâ4Ü•™{S·F÷qLNˆApÿ™éˆˆ­OÂÝÀ{HÕÃÛã]Ø^ïm§G™„1j«¬â¸Ûê!·™¸ <“¢ý¾à☲ñ â: ÉÕQÀ_ZçyÙVÚô¥áà\;´wF¤÷ѱv]ýµ•ØAŸÁÜYX/ÈwW¤põ|^Ù¼1wÓŠk&¦}É.ïù#bñ›lNÕø¥9Üò ÷TðŠáèÇõ:«3ÀÞºÉpoÛx!hw»`ƒkn>:¶§èý— ç¼x'›Ro•¦Ä1–ñ\Ýšf;žÙ8Ì^ÜtcQ±úéÎûÁt,ž$!ÞrW.î!WK¥Vl°³Ýª/ín#­†RðÑE¢VkÖ^9ìuN—Lf¶ö0¸n~G¤V­™«vú×R¶Äãƒ¦æ¬ÆÚçñ·¹/¨ûô˜A`–©²R‘ÖRó³>ãLÉ6­0x•ž3PÛ­Øz-芘 ³{Á€›Á-gçsú›¡¤ÒBó³·æ@ÕœÂòjé+Ïy™OG 1gQ7Q\|ÙVåËÙ'’W툃€cÙâØsÂ42V² Ë¥' õªÀ¯ø6jCfêÙÁ¡£ËÏ£­F>j㉜eíE²´dC‹ÃRe خۿ à1 õ iW€—Å –²%ÂuíýéMÆ?× ú=Aû£R^ò%^Þ<æ#‹Â2ÎÞÜ7Êz[ …ó“0\J8GmÞð&õ3'GJ ²$–:½;q®Øú`á¶['u“ýÕƒ¤Ö² ãx“ƒÕWzˆ8¶Ø?ä]þŒ¹¨°É9ƒ—æßÄßêÞõ¦s˜Ž”¡q)ˆ‹¯¸ì´øãÜÿÛø¯`6"öE ‰|]<”ñŒï0!€$r±M¶í€ÓÛä¾SR"{®Áxù³}›Ñ$Œ}ºèæEø}\ ñëŒ0{ªÉ8¡Œ¥:p‡Ÿß%8ÅŸ2>ô:2 Å­ˆÃSðÇãÊCŠB8”²è@‰£,:n”¨0_‹Eñ§¬(eÜÔûÐ%£Ôž'/«ùSðÏÇóBBÈ~L§öÑþ¡üÿû·¿ìÿŸ“ð礀C7¥ ªŒ‰H¨gl$E±ÐýIT¥î;tëã(;½BQ èGX…¿TS#øo*>(4ŠÂKtƒ¡êkå ‰…Äy"ü¦]ç§ôíXß*G¾íæßtÎ+Žô­"B€ß{€AyÔ76Áß´Œ¢Ðõë[*õðóï½b‰³š>1ê}óŠe¾×ßýáù‚ù÷T[D½‡2‡”(tå¨Ìà:µï¨Ñ ÁƒÈD”’xªÄ£ÊCq0Dï !a‰XJATá`HXÀ„#Xßx´ªÄ! Ô«Â šxŒV#–¤VO5Tx&^·Ò#¾Ù+C€3wÊ€œ_ê|‘oÓžÿì¯Cõ ÕÇ8´¬o,É)‹§`‰*L ¨iÊ õÆÅ?µ8ï¡Ú÷Õ4P*"TåKQÚü©ú—j3 EÀ Ö+žÒEa#”9Pu>–ø€ýÿ ø'EÌö[³>84Õê”Ì‚Z~­ã£è߯ÿ(}!(þxªñÄ1´Ë#ñ¨gÓ­C5x-žj þÿz‚k*þ«€£v…¢@)Õh¡+¶÷¿ÿâUÝ#¨©¦Ì훲8t cQŸ ƒ:$¨I±r¨ëM¤n&Ä3– ó¾7¥<âK TœwGñ Bñt(Œ¦: è<"£J¯”^Ði"2z‘âí ýþpÜOÁ¿A¼‚VµG:…>Ÿ†êWý0þ7ý ;òò—ùÿó²ðÊÔ¦l ”?Þ±ó‘ÝÄ8—"Ž Œ øÑw7ïîSêSü˯!°¡Ô÷¢ÜH |P5u2ò77õ+}ç5îïøŒüÍçŸWÔŸïâ·©âþV58Ùœ&ýN÷/üÉäyÇû»ºùâÜR ü"‰ßCÇ¿3ÈWeÅz¦¨¯ü|˜·&ÔË¡ÎùÔ°ý[ôÔ˜ç†j  eBõ´‰”W€®cè|¤=¦QòhBƒ- U±D ž¶¹$ˆ8F:"Xå Š ‚í í³çGN£“ M %ί|,(Q\`4å#ô<6¾#ƒª=·Tßø¯ u´@Ĩvv!ñ?Aü¦RC¶ùx.Å?¢ªjTiGPWª±Ñ…¦æNÐ"Åÿ«r§Œü(¦Þâhùëñ?œ?¿Q¥*þ_ Ýw»Gy!ÁïúŸ/0è>ABp‘_k£ÎN-Þ-ŽŒ§¤€bìþþÇÒBñ¤ßÅåTÓŒöDñ€€òaÈþ Æÿ:žÀRã{ 8Û”ý…âO¢lÊ‚ã).PŒö|çž:¿xÔ(|#QŸ”H­C¹‘²áP'‡b]©Þ(¥Ål( ­ˆú¦”äZÝT_ Äæ§à# 6:ÐÍq:ôù¿`ò—ý_8ùa5×I P£ŒwD…Î5ÿJÑ܉DJ\ð=뇆¹”H÷[÷­âüejp€¸¦)ÚBurÒçÿ “‘oŠ•BJßhÒ× ¿OAäw]ü›æ˜/]ü™oÍýö1Î;Žø;ŸGøÍF%$8öÛ`p¿(Âïóïf~7ˆ HTiP‚<þo˜;o/t)‰j”f@ÑÔ´ņã\SÜÓ¾%ØPÍ _€@áý#PÊ1dT› %BÆ’ü#(šÛ;* ½‘bX°îfxõzN£:œèjVB̓‚v Ѥ˜ð} 8]T·Fý]özþ­/åªÆ¥  T-IÍœ‡EÀüh)á>”„%ͧ) ÿ£é )!"%ƒJ )IYäk¤5Ÿ[F°~Ñä¯-Î[{jžŒN›Z¢Ð â×/uë€æ¯Ç¿îûÛïýSBñOw-~—õ¦H@$| üü×WÓÞQä¯âfYGÕûÚx˜0ÜÁÿÿSQuµ(&šŠº¬h1?%/…ýåø/ ÿ gÑY#¿ßëG¢:ˆÔ(žjìÐ5 ˜UJ^$88æ[þKò"R=ɯGIO©ŽÅ SÎðAQ”y+Iù)g¨%E¨¾€ÆÏÁ¿Gô#DâÕkI&ÇH”Ü!5ÓÕüQü_˜ßÿ3÷_æÿÏË'à‡y5uM BHQÔà 0JR8ýÿ¯ÙnŠæ Rt¿Q]~Šg Ï$<ÊEOS€JÊß&ø»#ÖyRüæþS³a®©¿Úæ xüN“ÿ¦|©E辂Tø}b¤¾ëçß\ðïç¼þäï§]¨þÿûÀïkzðß^ùÄý½ë¿-´ªèP…€’IPé‰E\PrkOõï)‡†'ˆÁáó‡’¢J^àëY8êà]S‰”Úh¿N aµ³DD£CÔ¨'"ꨚѩEÚµ S÷mZÔùœ&}ªüc¾ì·4+‰ Žš¨¥øü~¤<†0Å(ƒB(eñ¯ŽüVKU±øùCÛo‡ÆåL5_üçó”,Á¼ÎÂyÄ‘çӺߜÂ×)ªó«ñ¯ý¦ã¿Ã~íçz?ŸÑþ}êð!a¿ãò×vpÔQ ˆë÷cp§Ä0Jæu/p„o'ÿÿ³D*”ç%аz¬B¤j|j×óÏüRü”ÿEG¾¦(s›Ÿ S*iÞÖa¿=4B åaÞ‡\„z îM¤äàkþÿ루]¦Fú”µÄ㼋 Â{ €ð-Ga4¢þ“ðoB}=BTo@4›(Ó¢hêþÿ1ü_Hûÿ—ùÿò€´À_Ï]Qª aóÁÙÿ×Þ•v7q%í?ÇbC’7aÂ$Î¼Ì 03x—åEk÷½u{‘,/Zlc’ÉÄœ,„YÁ0ö›Zî½Ýr26’òÁÍ9:²hµnwu-OÕSÕqÂ5$±¼Þ«,zÎá>ÿ4cVk¸h¨Xƒ´.™ ¨¼ ð÷Ñú¬º7˜Ì,.km÷%|ÅoŸse¶Ì@,„æÅßìqûç!{KCßdš’,b±kËÀk”s6~G› v{Ë/ÈDÊ蹟€YÜ\G‡„—ˆŠ£B ¢Ò(Ù‡B³%a¥ö)¥3ãzƒ0pˆ~CCåz\ì1|ÓÁZGIáòQ¬§¾g7;:œ8¸ûÔŸ¾€{» uýÈ]ZÞÊï¡õ̸+Z^?}7à‡)™jàê:[î`©K PQ €QÉ0åÿMÏ()Ãâ—¥^L é  „‘êkm~Kéâ 1ÊŸ¹€`ÅæŠ$Îö@ñÃñÊ¿ÙÊ‚†AzÊß{1wÿSÉ "˜Ô~åÝRW¾ƒò·Ë˜ü!Bùëé•ѧý‚ü·ŸEI¯O¹!2’Ó)Üxå?lý¾NaÒ(»ÆÙ>×Á|Nm¤xlH˜¨€ÇZìÊÕ‚Õu⤠~&œ z%ðèîˆn2Ò3÷ÉÙÒùÓ2 /&1ÍB<ùÏ=4ᧇæÞn3˜8Ñ|0RˆH¯Üx+ú?¬íþ}{é¶”ËÁVB îƒ|öhhð¦÷ %a‰ó³D¥§p_lz–@PÎ*DP\Ÿ¹K4Uøi†õÀgÖTˆ£mqƒµ¨åuÈiQŽ LÛ{/â¼E—{ùÔ¯+ÊI-ïÃÂ.¿+­Gƒõa¿(þþ°Ø‘¯ÏôËVêÈ“ÁÂwŽÉqÑ C\þÅvq3A_N%~.± Ý—q´‰nDz1Y'–£Lj¹Ô†`e/@ßoîôê*?=ˆ¹"xó©»n¼²;÷àñNvn‡d/)hò©œ†`†taxɼPŒ@’!Êÿej‰ab¶|Ýßáy6ÛŽP‹šÆ¦•Ù§ üçC,°,BÅ!._Ì»c•ÿQbdè^–Iþ–ÿ-é_þŸåöiñ¸/Sy¨lï?[_Ùeg÷ e øóòÿf‡ä1B¥\‰T·ÙÅq,:Vù_ÿ{ðK}µgÏ¿žH‰ÒMT£àŠ{÷Â.yýåÏ·"î¨ùò&R¡)aÅHA_ gúÀ4€ ÏÉ:R#’ÿqüù A{`ôͧFËn@1Þ¹{~ýOÏíA~z»pÿokûùÀÛˆBeu¸ZÚjKýe.©P©àT_ëý(Ü—Ö ÞQ8@Ú²ˆèåß!ükŸ òà–»_½-Ð…Nœ ¤ íÄ}ï4È¿¨ë½Ç‘á>Ay+g(¼Jê(oç™#.ødïÓ”EíR[ã"±Q¼SÚ@ Š )—S4Q}~?æ’·ô&¡Dí†cnbúALy ¹w?Ф§H/ôµÜþèÕ ÷û‡.\~eâKÂV·›°J uS‹#Y2•9Çê®Z¾¦M/A‹ôŒ 5 UÊè ‹‰Ò C”ÿ³¶r¬¹2¶»/’ú?OÎíóÁŒŽU¡Q˜dû* Û‰Ë÷+í‹Ù ›æ«ã”ÿ‘W?a€Àd¼Nsû¹Äú®ÏÀ?¡suæÛ&'Pþ°t÷E‡8à@ô¿_’ÿóu͸œá¾4N8ƤVa:FùBÿï?Á“á¾Ô˔էœ?ÑÞ8â¤ü“vùŠ Ñ ^m%@ޜܠàOY…Ò˜BäÀr+¢«‡»,í’¿Ä_Ptm@"Ñ«£’ÿ‰'NBýÿã Ú¤Ÿ®¤D56¨,WÏ­ÿçt?»]øÿÑlçBÁeº¼Öi€§þ.%uáÛÚÈÿ,b¤%Õu‡bâ9Ü?¨@ô} 9sš+äÙ%„ÿ¬9ÂÑK¶¼ãlx.ÂÎÙ’°­¿ÿuÇÿY%&mv4o%Ì€‡Õf åç³3˜·WN櫪 8»OþÐ@k@´^bZ1¯ %ý¡ØE#½²ÃÉo3<ÙL?ðmÚ2 €ê¦À•q¢ „ {xi+•ž J3ÝO^AT Ú f÷ XèÃGO"¸ý%-,üà°gO¦ú>À‹8‡Šðx,»Ð¿‡ï¸ J``¹•&3k^ưäŸ>·¼1aý‹çHœ¿ Ö9Ù[«û³Ñ´ UË;%h#7•q{K†XÊÁ;ã“ÿ÷éÀ½™Õ]! µË²î˘Ùý\";§Âλ)”¿Ñµ5ÄôkÓ½[hûQþZ/¾Aþ¯( ¥Y&rR¦:qI¦¾›üG¤ÿßuäž@?R’Ô?7º0ˆ&ùÎÆé•õÔ”Ò8"^ ÝQƒãâ0UEDŒ««eøˆnWS-“i«Äë—G%ÿå=S›ûL“üïü¥þÞ“.§gЛ¿sNýRpáþG¶/ ãˆÁa½ÐipcOd©¿ZX5Žú« Û1§É\zùí¼£3ÊÞgˆgõâÇÿtÒô±»cúlɲ|®}ÅÞ¼AmÓ~¥·Ó+Ï—¥©¹Äáj£‘‹~=ä°ó çw«Ø&Ë9…éëM›ðÅÏ·Ó¼À×UÝ“„?$”Ì'> þÉÙ—D¯©ÄMCu~0±®¼ ¯¥&ŽiÔ1Lq/.ùÃõð‰œV˜,MÁýC¶…µ¦]ž†9Ûì¦áÚ+‹âˆícQt°¸\£Äƒšüÿò—¡+¾°¯¤wÜ,ð§è‡åT†®+©-‡ô¥_‰ƒm<@KQ–nŽKþu1ð¾= »/+$ ]Ž›Î,ÛàCV2g÷s¶ÁÀ_àß•Ю˘¡ko’ÿÁ#²øa½ajÄ'skº:6ùLÿŸ¯É-¯7e€„àyDÞ0‘0”N]qxÀò·µ%NËÝûä i+Ýp¤¢ü)EÅl@”#£pÃÏJyTò?Vñ¥—©¹t¢ÌåJwÜhÀ¦Ö€J–nžKÿ/üÿo;0žþïó\jVU]¶¿Àl,ÎÑFÂ(‹Ôô7ÖØpŸÉAì´h282·tÂQTúE?‚ÅN4[ý)Щ©ÜÂ:É@¤Ÿ³§8ÁzªøCÄo íÈçÚ2¸—Õy=ì€`v?ñù_[ñÍÖd‹vŠ{iÉWsûï}Ý” )yÉM¾õ¸°fôÜÓx  œ~À£Ö² €¶^«¹ÇÉjaæ _8¿ÕŠtpû0†KÌWá{/ —•¹öüÝ—r6K]ýÉ|ͥꥎ_m-qïn?aPBÞŒšèå®m6ñC‘ÿ#–?ðèaýt÷¹º¿x!‘AænESob÷ ÒÁ/’:ð#dæÂÇ‹c’ÿ‘ÿž;„»39ÔXèÚŒ¯ý홾_”qîÃ"dºÿå?gÛ-\èíGFÂ~QþO»dÉ—¶eÂþhM¦,¡ˆnIþ£Ôÿ×Üɯ m#s7©îÆåò{T#1œôÌì§|Q^ Lø¿‰/@ÜGÊIË[L”gÌÁü>žq-5–@gàêÈäÿ:ÒWŽCuíuLœÐ¥¾r„Ÿ1Ó±ˆòŸ?‡þÇK_¸ÿ‘nç‹T[©Œ§q½@¤ l¹µÌn¥!áZÇÁ6‚‘L %3À™4o⵺÷)À¿R2é3L>ÈÏ[×s€Dæh$fm•JŽÙXËSy¿¼¡®¿óðsÚ{f?:…ô¼ñqaÇ•©Éz­™ßË]`m‚Õ®7þt°Écà њ'„‘Ðrï«ù>ZRÀ `¦‡¶§*ñ#4ÞÐÿ“0.´‰ À=E”! ½X`3OĽñ:¿ƒæ÷3¸uˆ?3ßÇ¥}ú yíeîüñr7302hbtj9‡³û \}TÑ-¨;,ù¿HÈìN?Œ|û˜Cˆ\°Ó€¥w]8ÿ6ƒ<»G“ÜÖz‘cü3ÅÛ¸hÀfœ”(q &Æ#ÿ#ОíÓ ü7Æ üååîzÿ+ò?²Úž]€o{±]Ércµôfù €ˆï2ž‡›ÜÅ»c8:ùTÿ¿øŒ‚Æ™}™è#±!Qÿ•I~èäþYä/´ÁïüyôOÌ¡9¢hªvpï eíVz/IHkîhä¿Ú5ý¹fùÏQäŠòŸxeïrÔ‰óèÿ0¶óV¥/¶ÿq;ó§$Xn´â<õ rÄ­!…Œ¾º§KѺvá¾q“>¹C›Mw ƒ%¡ô{rûÕ*m·:KNÑyH`ïW09[ Š=S2Íè'Â}0û—òo·AÏôóÖ\ç`ƼB5N–[6£k±aÎUؽçØÏJô´rݦ'œ(”Ü>™ØM®¦·QiS®µ¥ýŸ1¡[oh‹ùy  âü1¨‚Ë8³b'a †.àΡ2WŽ4ÜþkÌçã¯hM ?øO°|Ö3<‘-4áü%W7|wJ±¸™RFsHòÿ†ì7b%”¿dô³"€á‘ÈR©?4ˆ“âч±ü®iIâ…@v”17þ;6 .¿7ù¦>ˆ8x¬AµÚvpˆZ7GÎÊ|›=¢ý•°ØuU ¼ºw5uþ¿YþG‰\æãÀ2sËÇ ÿQëÿ?¶š>ˆ\ê_r÷)rÌòÿ ‡F"áÒ$aŠÏ£4—âxvîÜ}Vë ¶Uåïi0õבÉÿXÁ݇ ¸ôŸ(üä Õ5.¿Žn|§ =ú€âò{gÕÿèô¿j»€ÿoyÓo¾œgŒ¨â·Ôøk©¿Å‹vg½@–_¤ç: ƒ%\™ÝÍfd=÷£öéÀ¿©kÚVeSgê{* ˜ûº#kµj7Œô³ Z.8ΕÕn}{äÌ~.ÿ›é]9IÁMÉáÂÜŸøfmÓïOæwb¯¹•âçìâ©%Xžöƒ×#‘gÕcç¡ÐÔ N”’ 6¢ˆzŠÐh˜Z¯mQ|@OæÈǪla2ó¾ÒÌ5–I0?ÐBp9¥ÒN4Ó/m‡×<‹¦­²ö%•Œ®‚æŸÈ˜¾1€†ü_4Í ¯6Ã?"’?Øí@J@ØҹňMäoá¾f¦ çs¹À=À;žHÞaajôò_ø ´sÇv?XKýO¯¦M«ÃRnœf+ÀôåµM©ûÅk”¿¿·§¾;öMòÿòÀñÜH`• 0Zù^ÿ_Ò0 ™ô õŸY¥”Âçüd„”FÑç¨s—{¾ZÔ]ÇãýxïÒ–±Ùrþì*çz©}Bè™ÑÉÿDë+Ç ¯¼ŠÍ¥p©Ôgû¥šàÑYóSgÓÿaøé ÷?Ží¬@¸¦¶à'Ð0õ—Õ¢Œ§þ2.°“FIQéÙÎ*–ñ(N»ä)!hêið÷7ÛÆÞçd4wõu íÿŒd}=ú_šƒfÁ«“ÝûT:ÿ]£*˜WHkòó£¹rvª†ìS½¼m}C6#&—˜¬&±˜ž\z8\Üse`Eæö3/ˆF†x.À®Î^؉L`( Ð¥-Û :¨™@H昻 TjiK&™rñíq¡ pó[³ÐN? „^ÂÊæb#UE¸ðt#”ºÀ$±¢-Ws³A ËÛÑpäÿ¬ Ò†E£æöb~b3ý˜ÜàȆþ‘€^‰•_%ÿ¶Tâ‹ö!ãrFññ0äŸQ9+úÿ]ÇMýáѸöϺJN&KâÅ©˜co’¿q3‚pýÌ ìÎáT’„T[f槱ƅ=¡I01:ù—zFÝxfÛ‰Š/£5¹z õúæBOhú€²Ñ•³éÿY|ƶ ÿ?ží,@%­T¶’Œúk[EèÎñ³#¹ÙTZ‚I*ÛîYn§ç‚bÔ×vÝãJ%ìß7Îk—mÍÿœYu.E ?4WÒsñsIÀµ¿ìg>;˜û…\ÎÔ@¦q–,G×Ùxí‹¿ä“ðô]nO´™ª£õrÛBÂÉW1º-7ÿGÿ ÿŽd°Lìž= ëˆN«šð€ F õ„’Ý”@(­Sß;=@ €Eㄊº×‘ݽƸs¡¬…7]àà¹z\Ä1fÎp¢qóÄS€@8YF˜°¤Ò1{„ ¤~ˆ^®tqgú•fŽÞ v̦Ì꽤ëÔÕ7™$.×ò†_¿&õÝiç};š’ ŸãŸª¬³j´ç¥{™[MõœË8*á09Ð’?eKÒô”óPYf®&Õ#öF ×Úòí²Ûµú|ÜÛW%‹| …:w"ÄÎÏÑtQºAî²e—8#HPitš€Yž¡—L`ñIþÞnÞwF„»DFk‘UW¸RÅÆ_ôøa—ÎQ[À(yí{û»2îp‚Æs¤±Cf,˜•M‚èŒ:ÞûRk$yhïH…ëTãˆ'ÃÔÝ‚…(ðÝ0òžÖì„ù‡›;ÎbV‹HÙÅ¥lõzxh;¿ÜÕMtk×I‰Euäò”L-ăÍMg #[é©M¸8û€›Þõ]Xr¨Zº•ŒaÈb÷½Ñ3Ž©Sëá\òƒòØÚŠŒ‡m‚e*rߘÆ¥JÖ4‘å;·°k^ƒ›““‘F³C‡å3ïÁ­5î¯'[ÞoÀkXÜ‚ÌÖ{­v3oŠ1­›®¨pÛ³°°¦¯kÌ;aèèL…NéHò† 1ÚÆÚïþÅp¤¢Ñjš[0@ºyšx˜Ž!o·þxÓþq„ß‹í­S”\å€cúûÏM ë^ºlú,óúÂïÅŸ_<è)AO׿ÐXu\uÃèxq½ $ß®Œß4σ—n:9Õ•VpÛ•ÁT&æ¶ëBß–M[Ÿ³> H,V¼Š¿í£sc39'“Grâû·–aV/N{”ôÝp)»æÙ*!©òZ üm©'“ƒ¾ÿËawøéoL_¨<­ª¨Ø=˜¯=­î+ôágãßMXÆ?úþeÿ“=©©ŠÎ[¹ðÓ6›Â!öó{4)—ƒWþ3rhÈœ,¾µYv>…¼Ñäú-Ðd»'7ˆëm̸ŸÉÑ?ØÃ,µZà,§èx´+d¥”wïíQ ɶԴki¡óùÝ»ÕÉýý®1IẓÅõñ"«2Ãiƒg” 7$3 ïÊI\Ý5(ºŸê'åyî\N25>LýÃöÿÃè¿“³o,þtû/}!6ß•'üI§z.R°lǪ¶­¹Çãcêžœýpæ7Ò®À=ö€[¹•Z›`ªAvÜî¦\èY…q;á´¾¶Yòïd ùþI €8¯šºOG‡vÜèÊ|êúÖ s«×»/'CO(ryí Ì=–Ðħ¼¾}­¤ß#€Á¤<Þ4ðHaꎪ®Þõ©£èÁ¡¡ä pù=oL Yè"êC(¨ãÜl_·‡Y›Á§ÝF=Ú’;a—’ßgH¹]3 XÇÕ—«â ò®¥Dp»-àž+ª€÷żx-Kò1&†3|MS¼Ý¸±vòèŽ®ÖÆ•ú<ýy¸­µ8_³hŠìú1¸*ßµO¨¸d`n׼žŒ§¦Ú<,=äfññV<¸¹íuê·+¹1]*fók­8Ü&`øxŠôêÏóŸÓW¯£Z¹²’ÂpýDÀw¤Ž¯vìoOê!$ws‚#Ó®\€³"Ìj~d±ú­õ¸T~þÃ߆YÝ‘ÆD»ªy³aW[ÇÂν[£áêFúü³¯œ1:z·LšäC‰`¶–žˆŽŸ'áägÌO#>S?P+)0ìÇRº%b°ãçV¡Zú\ L^M4ƒ]h¥x$)%„CZyóÈn“S‡7dz€ýˆ¦ÆxöÛ߉ÿ” a"ê >I|IšaêóÀ%`|0q$T/zöqõ‹E+¾þÍ#Å‹¼÷°çžêß‘ª[ä4æ"Œôò¥T/ÙLÙÆï“>!ÎÔ?¾íàc*=+a£ÂÖC=ë»j‘Ň²}QÕ‚)‡9”^ÅYÇå}/þ[äê¥BÀª],˜£GíÖ8½äãòПŽ?ÆïŸiÿ)¦þOjþP$b¯Õ«¹9õ5Á*^Gå$áêÕOiÐpÆΞLh~3ƒ#ÓÉàMPä…-µð ©8>¹%ø’<í|aR~žÎqÐLdOèáÕŽ‹!ì«x¥jŠ7¹lœÎÖ‘ª‡Ý÷aö7â?=kÇ?ûí'N–«'èzj7¨RòöoB ú2ž\:§A´f½Ë¸áíßÿ§‡ _‡è€ŸÞé¿„|gNåëû#ÝnTa àX÷†—QÛ0 ”Îô»¼~³k! ¦ïP“˜ËÀÍ=•ànØ{àõ¥ü \ߊDEïƒT» Œ„íN|_Ú7·Þ20‘(- ¢óÖ…¢êû­² 3/ÒÝÝÆŒ›>+å#¥¬ah»ô£©y8·NâÊà>£%Ÿu©€¡>,G 7Ú³GɾŒ½l~ÝEn"w8­bôÞãhWô¦jdôì ô<ð“”r#ÃR?—!ù4`´j¿ê~^W³ Šè)c›^ ëJ…¨ä䵟”eb Jt1Ç¥¼¤Œ›U¯Š6Õ:»¯¿3s®M_Oºl £º’sJÊtèíŸ[õÉ-Àßß­ºiÕ™{«rô{㹦\á²Í¶¼/€‹”nþÏ@ëÑÞ>ß`OÏìZ#bªïÓÔ˜h:¦×ªÖÀd²ë&»Ë» u/šW˜«]Ž~|·lFöm}ón^®ŠH¹äkJã¼ÕÿÈÕFeës÷N~œ—ù‚u•6è×»8Kü"zûUS;3‡ßmŠ'Üc†¢;û©æŒVQîu·ûWåx÷•ªÇ½TV XŽHóÜ‚¹~5µeÞðÆQ‡)€A¼‰ï ØšsK™ôþÂ}ÎGÑ}¢·©* §ZÁ­$ùŸå…&Øoñ+𧿬ð 6pS4lu‘úTaùe³WÄ»Yƒ2,ÍzT)4 ßkÁ„3-Ë$hÖʽä©p¯7_ÒÐZ]7à@Õí71{CŸÅ$– ѱ4Ìl‘:Zµ&qÞ"G_ýZµèê[òã/ÃzsÅÊÝlbäǹé½bpµø™€›*Ÿ.žÌ òÕÁ»G&kåécm«Û’6ÄZýx³–ú«rq”ÈܲHá@åÐ-îm)t°†‚â6QdŽúÓ¼„N0{A{ÃÓØ_‚F-‡ÿg)öz% h{·mèsbNEÚcMÏS§øWÄ ¢ã;¯n@„úÞ½¢ûÜC[˜yg|öß=ï £ØÇ°‘Øœ »ox n>®U–ÀÄ~øœÀ:É$«¡ž=×Fc/HHÕ(™<Ž:kÃAvó„]§™¥eP´Ý])ÛÔ߇ÿ‘³–oàåù¹2‡€ ¢j.‘àß,“¼®o{ÿ\á}ûh…p{Σ^$?¥-Þ É¤! Q£3I`óæ<]?_¥œÜåÁ sô¦µ“¢ "1NQ%|¬ì—øðˆ ƒYú¾È»ç•“£Þl‰ùü«OÆ+ºf„£òС٤¹éÕ¥Ÿ¿tíà?ÔþÉýæà³w>øk°9òiP²Ux.ZÏeÚáS«Í]#;üV¦“¡Ôå«;“ò­Â @ã7ƒ«‰“X›Ð)’ę̀¿EüødÖèFØ0ô@0ȶÒÀ¯Ëgƒ›Ÿš”Λ'†þVü׌ŽRO“Ÿ‹Þ`‹)ÉÔ/•N;2êP’"MÇÏúyd»z{Râ>€7]}ÀùL)£¼GxíA<4×ñ W~¨$§Yz„~ä9wÂNn$·‡S:<æ–AønA6hIÛùì×Àï|ïjíJ­léFì9ÞºU'°ãìÞw‘ò@Ôé!uØ¿ê…lõ´…âY_.ª•Ó/©Ô¼sœÙ$÷ncv™‰hºÇºÑ~ò™¼^þ Zzàad–œû¢KâðÙtg‹sD …(à #ÿÞ•Iw‘%½yOlš›;^0vŒ¾š5W ʪÑm‘NînY¦×w_ËÑ¿:ã9ìVô¢ï¼› wÿáûø¶ƒyšŸœÓº³d+3„¿õK^{~3SY;ë°$ ¿,Ó’àwdˆÙj¡ýf«êàv¿wÔaV1P:2‰é]ˆ û8’ p<ü–DÞ: ã Ýu(õ×ٽаïÐà/À¿è5ï1¤í$^ä~ÍÙ™E•ç×k(ÛQÔUényÎÏÝÛgÑKGé…#‰€cÊD‹ÅS£Ÿ£3{ß÷Y½ôô¢ùòð2ÅÙ6«®Ý¸xy[8¸Í–"€m”ûˆ‡Ñ½N8"MðYãá0 ž>j»©þ¦ÓÁo?R}î-ž…¤O¥¯à¹GõL˜­}.ý0O“/÷„þæze§ ÔÔV ²so5÷è>~éèAsó¸çêWy£T™¢Okµ›%;L÷ß²{á[åí¢|'jH]ÉA®zŠÍkx«„d°âþë¶gD¦üþz"ãÎØÅÞ{×€Êà¾ã¯ÀKû´/lhëlRËú™Æ³*áj”÷K•AfZ8³c5Ã#ºeQ)è;B&*ææ®[žòù“’Á-ÏA^óµ§~^·ç¸g—Ëb»~Aþ"Ù0ai¿LRæ»ÖïÄÿ‚/ÙøÝ°¨È¢2Å»"c4uy÷úFCg¸"ž²Í–nF1xˆYçö°ÿŸz» ðŸÝç¿´L¸ïê?ð3€JyÔrp’²IA÷+ÀÐb/!F¹ÚÌZد`׎]w2O ”ÄØ Ê ³ñØöòxÐî–=qå¶Öþ0Ü4 ¯ˆ™äÁþªUq2ùab ^ýc5rýx³u{, à|·Mû&ÈÛ™ð1~»:AáAóÒòÔÃØüL€QÈE§ÃîÎKƒY0|ô$À5™‰ “pm‘{'ð˜ðs[¼xÙ´P_gÉníÕË— ¡ƒu’±ëy·RÙQ¥×dåYtð)§Ž.œ¶Ëˆ5?wYýL:ûÚ€ËÜÛ ¾ö¬3³1(%]½Z1QõÉÓiÿ½¯¢œ°b&ë6&i³<½Ö39³Ã£#Qaýͤ6˜g°Ëø!üib² ÷uôÚLñ¡ò#ø7åOÆ¿¼Ao Öxó?Òþíï(HZˆëœTý2Ðb¡cÓ ^¡ž`{mb²áeÕõºúÁ­VÜZ(—§tSn¬1ˆ :¼÷‚!ýz?Œvµ§Ñeç3x37$*ÒüäCVÆÿgžÖAÂüD÷Õ8§Æ¡„‡Äöߊ¿ÃµÃÙ—t¤“¤{.Ý|¢úÊ}=}§¯úIÑÇZgú€`â{žEkxÈ4¾×þý½XôÉÍ3öûÃÔ¿ôCdÿý¼^žÑßLjÛ9èYl’®ØÝiˆ›ýÔÒ ê 70S·F€ïÜŽX-dº½^Ë[ÙÐë@†ø€ò$@­F+R_•µõ©!ªX–—GÉý(ƒÞ÷OÞ'™Œš¸Ápßš÷‰0*ÒÇŒk½Í;ÁÒøc£ÒËU)jL1ƒy€«"¿)©§A^ëdiùÀþ&Sƒœ3`<Ïãç+·š1 Ý Zñ ¹úã-‹ak&][š:é+RôÒ8h—tÂ]=s¬»î!‚ì« .¸kƒºEº˜âdزðjîíªtÉ;‰ÕWòÝ9~6¡&yV'óáB’oJMÊì­þ¬˜Àg7ÔUë¸[œzD-CO?2R“ ã9»zOœžÁ>ÆqÆWµÁámBݰÎFJq¹'™XË„€Q6Û+f>ò4·¦ •ݳ• ðh¢²šjp„v•DHiØND4Uy˜ÁÝÓó_:•E 3o÷tÑ~4;?Äû€û1ýàÑ)†ÔEžcž…© rûDùäv,^RD€2ûÎ U§ì€—£¨Eмøx¶Æâ+¡_´^¤]Ø0!͇r1ØWãÖ_êjŠU"ò®¾›|ß$}l¨®‚(“ÓO°ò9 ~þ¸asNhÈøéøÛ>k{ K[Xl/>nõ*/Ê ÜXöèôeÁÌpu·Ç‹2®â ^6ÖÒº`©Ä£o>Íz,h{Ë‹mm÷ P蜎€=—‰á,çD ÑKgø½ñw›@J´ Ó¯€wwäæuÍÕØU踱7¤²qmñ¡Lˆè£½÷“,þ’;eq;dë/6S`ŒÙ…T¡c¨ˆe“A5¦‰º¹%²d,Ka‘('–I> YõgàX#}Wtˆ¦BeQ˜xÐc ÅFCF³-‹¦Ÿ/R,Ú »½öµèÔƒ«G>SzêzoÇÚõ²‹jŸ Œmü1üŸ2 Sß ·˜±åÐýÙøãn®à?ýϳçCðQ/$0ÂÚ’Ý81õÛN?ÕM •ýñ).èhŸ[S³¦Ù­uŸ÷. ^³Âʊݨg=Ò2ì!¨ôi[C$•.ÂéùÏõƒú;(aÄÑCøÖ1©ûÎÐ`Í‹-¢{û{ñÜ©U¾ ±”¥p×]¬’Ä6þ £<-ì’2:]O󭈣¬ÔîyþÐHïö÷ÚÿߊDÿ‘°vÁ?·Çéo’cHàwñ¹nW¦™e·P¾l9Gg­óž0$€LÐ]‘RØ<îÓŽqíz…åûóMéÊ· °w‡¶£›nŠõy»–ÑÃ-@ϦUÆF5QCùà¹ÍÚ­ÝŒ“u¡ÐfWÛ“"s 4]Âå\‹¨+@¥HèòÓðÕØ=Ðý2ÜŠÇÚ˜†8ãK«i{B/ÿq7žR1±àÙœã©üäßíŸLVï³Ãƒû™¬øH郔·”JDœÔ‚£ò²‡ñ°Fw®¹©âuﺌ]¨V»¡^(/áäE_š’·8ÉÌaèz&=¨ÎE+ó9çÆµ¾Þbàfà“³ï@˜Ó9bÄþ[¡8Ÿ"•ÝÝrê'9ý´¥ðƒ”‹6‚Ð&cƒ[Cë]Š«+ˆmЕN•ÚsÊÔÝÿÂ6æF¸ÀÚh(“Õ³×8àáøõk¢QQNi“ïusuÏEÞ¤j¬œ_}'cóÙìäy ¾'„®<‘Šß´ë_Ù_zÍ;Lâ8 Û(õ¦¤­?èIFrUó©HÈàÛv¸yëI´·K*F­\‚»Òÿ¥¹m޳aWšý¨½D‹ÔÓÄÛ®X‹?C¥§ëì:,…†â°{cqÑWÒ Ùü 4? ¦5q3g¥áÒç·ŒxÐæ½YûÓñŸr&Ãf¼`&w¥±38ôŠnálWKy¥•dÉztüóô/@LÈq¢ðl¯øëáðWL^úô}€ÈÖM!po«Ä:ŨYÆš}èøÖEÛÌÆðÞ$ürêåb+нù €S<Š`ÃSÒ·Ûíšz‡Þè.<|8¤»‚lrúïÀ¿E¦oÖÏE©ZxŽ™µª0ß>ä0ͯ9Ì÷ °S¨u´±@CŽýúK—$æ¨Rƶнe³ST[±“Ï^„ÇE¼¤¯ãyÀŸUÈxåú´b{W¯à¾°!÷~¤w›•*ÎÙÿÒÆm;/xO|€¢§ÏR2·½VJ™ÇäN0 Üto¦†‰g•†ÂE›°Âh”²G\‘µÍ(Ƒ̔ !úíbR«î /6ÕBýá‹üW¸|w¹Øº*c–N¼_tf<Õ-ð\oÃ7˜L/Š ÒŒÅ5Õ"·†0ƒ[3dßÓVlîÖI×竺ìb²¶¿Ò;@„Ð$_)F›Å c%ô3çeN¸‡Ö]X ¦¥^æ&Ó…òŠÄ© %φ™ñHÝÔøËûð 1DÛãàÄèR/H­—ƒõýÁùÇ)¯)#‹â·ÖÉYDͼ'™AtŸP¤ÛHoËÏÆ¿ÐE=^’1-™ËµæwcÁqb¼ pToBIãG^˜ÒO6<‘‚pçp?AìŠÅŽçéšÙá5F©ŒÌB寀cÔßpÉjö3ì²÷i("Ìw^ˆdf;ýéJ§xCŽ»uiŒ`cßšÂQƒœ:Ö¨>2=›ý«_–L»h†óœó­&Äoæûõø'DÔ˜¼xiSp(æþÆñ$cxëI9xØBÆèÄsl1Cw”O¡8!¤/|ê"Ôõ¤ 83”³ìZ ?~ä­è@ÇQá`ŽÍ¬¬Üy˜Â6¾Î b[çÞŽmÏ„”ŽÈñ‡úqäå©”l {ˆ$&:9ÄÐKD’~ÖA¢quˆ‹»ÞM2Õ-Å7¿ŒŠ?NúŸfÿ³„5>Žd‰˜mÓà+U±v-wºˆ\éÖ ½U 8p¹ ‰¹%ª)Ñž~~ݙՠºùyYŽžÿëËs=E*Åø]NrÁMölÙ¥‡lN¦°#¡¡‡È*NýüñÜïÅ?§”®Lu©Ï¼m—Wó»®+íq‚ÊðT=¥-Þés ¬ ¢5æ"‹8B~ò;ì÷ßEÿ#ù8þûì߯$»¸bÇÙý÷g:g½Vo*à~@ÆÃtbé Ö¶³¸žT)y¼5ÔâŽR€^é"O±˜}€mʃåðÁ€Ïí‚™j€¨Ïª²Í«·¯Øh,É`ðêB†âÄ'[®ÞmïÖ}Xb Q{$©D߃W¹9ƼÏV0t<2ßFS:tú\÷ûjÒGÁÛàpvÕ‰ôSºŸÙÞZÅmµj°& o’`’Š;ìˆ};Ïn3ÁÃeÏ€¦G8Aݰ.¼öF– »ËÖ„C„?4½/€d `Á°ä·æ|Œ;åS¹÷RÞ{Ð =‘ä|‰³(½š®Éá>gú|H¿ Í·SñÔc‡Ð^˜ÇpRwÎa÷Áîªt-¤]̡å¯ëÁƦˆM·«Áù•Ðð&›'n`Ó8n«–4j§ËÇ{ÈŽBWåÉÇ6™ëBá|ŽDÿNšÖKq¶-´oéhµ¶Š5xêùaÿÂ,íkãq±a–{pædü£ ç„aV£Â]m™ëvžE“s\?ö¼}µt¬(,„õ5p¬çZ¯”NBG°4>QµÞû•2rØš…ŸÆÖÒ6í³RUû ™²§Ýâxm‘ïëÖëО“6":ªÛ¢ÄÆ 3Ò+ºìnQ¬£ÚZÁ2²ÚÄæÍ¦ùIy«xØtr'gßÏÆÿ]qù‰èäôñ2o o€ºµMxØf56W‹!¡• úÅI.ÒÀðËþxßËKi1’‘ ›J„˜úýpBiú—ã¯v,/ðÄD”¹Þžÿ bš.ùUÛ ÕwØSìë<𧛫fÙ$|×"%„bÆÃ3¦çˆBc%XóïQ»\w¥ªËa­š¬fܱ¡§tŸâA‘vô–`óØ&ÞQ<Ñ(͑ݬüx/ÅN{^üaü„«LÀYáW.ÎAÔG?ü"ü5þ3íÿ#Ìm‘@ [=µÎáÃTJÌžvì;ƒŽ1o¹î~#§gB“€³ruwàxvÄ‹ê·QuË> 6€¼6J6¦t`ÆBÕ¸Ð-tÞö—º–Ä&}ß –z†äèÿfü•:®‚F¿•ÿÃ8Ñ8ÀÇåÀ;Özûfªç­Þ× Iã.\Òñp¢Ëê¿Ûÿß Eÿ!ÄŸýûG‘&â¿p¨¾È©šÜú†òü–@™ãàú±½NÜ1ŽE“ó`g 7ψ@íÛ#óÁçën•ð¤îb€ýñFÁýŸò÷Ï£ÓßKê–5V¶Ú¹çbãD1¯ÍpB°vèÂçJú‚ií'×0¸£HCfÌ”Þ?OÁ$PùjÂ|_^æ=N6ž@qÞ½? ÊÌæ+¿7§às¤k°Ìö+&´ÞW”áæþÍ!ýÖÉ»}©C={sq­/‚îÁÝêû@–jW˜?~ð}>ál­ Vt}¸_íûô¢š/ÇÀöNø´Öü´è±sD&9{‘xk]w.º5KS´toëŸQäÚ;aµ² T˾YU«¬÷73XŸ¸•ùjMå Ë*^·½D ÝÀ®Þ}2Épðå4õÂö`«‹À™’ ‚¬œÑÀp/4×–«ÇÓ±dh=U2ç!”KØÒ‘»fæÐ1±%¶‚0ð*KúÉøoc’ ô¾¢.VL½Î¯yc[p`6n0„÷™|¸Õðþ>—·à 6hÌ ã';$ ~Iš0ni(‡ÝYób`¹¡gDb{¥ ›öÒ·¢ãwÌ•f«Eean²—ÜGºŠÝ²÷‰3åûÄy=Pe¡ÇØ(["BMf¥ª³~_ªû’×ëéÅã¿-â·¯&Ý ½„× Y‚-ÒúèÏ£éð5 }Àª®ƒÏë&ÿçOf}Þè)¶³k‹¦_MžøäpÜê÷Kó Ñ…ãO[ëÝ.ÞÊÌ:ËÖp`͆a‚ÃçT…´/IcöaÓÈ12Æ9¬µz,\üãøŸÎ¯=ë 8†ó–«noÿ%ø§ëÿcí³JGCùÙœkL›ri ž(‰bÀÕìç°HVv$!з?†pN†åÆ*jÛž 9Pz,Ö\ÞvOÈ— ‹ ×À5ãgùûpÞÌbz½ôÀê!¨ürW¸?€]¶ú7ã_ßCÿ¨Ü޳…Û^4Õä`ªi>ó(<˜§œ´ÚJ7sÂÇ£àh“q*С+Ä=æû¯öÿS£ë¿ÏþýZÂüèû}Á>â}Ås´×™û÷=lꊪâöf_·”'Ÿ2 6_ª_5ÐûIÕÈ©û";OÙ|¸žü3_='ÚT€ó”OÊÔ(xÍ‚ ÁA›Þ¢½,ÚôdÁü°u¦e“pZ&{åL8 Á›—N ø=Ï‹w³Æ{¶«¬^,Æ)—  £Û/˜äì˜^82鯞•N;ÍÚ¸–»Sáø†€-É„».®²da[de1z¶YæçÁ4lSvsû»M¤õ¢ÍÆóZ:ó¹"8¤Fvóe\”—ä¨â0}ØBëtÅö’` °8Œƒ­¥n'0|XE³1ŸÏ†üÂY±þ/‹ ¡?ˆþ‡ƒáéêŽÑÃàçáë¡ÜmV¢dÍs£,Ô›¢bÖνº‡ƒY[zSS=÷½ÚÃŽ†¡&éí"hRˆI4¿iN±»{'áÎ8¹ÊžÉ K1â‚Iqû°ÿS ßý8»µæŒ Uk:ìRµ¨Ù˜&^g½—v;?Þ¶õ˜Eb»šÓAµxKé僥 _Àó|´þÕS¥26éƒ)^¬k|;²ƒ®  PMeÔgl 0ú(°-jC—gWté+lƒM7›J"3²Njš=àóø2|y¯r¯×` °>ïÅöB€8ç¥ù ÂäÜ{ßÝe Ë)<Àà÷sñ‡§Ü&V@Q‹ÁIÏ»ABÿv–ò}p²”yÐ&'òJŽ`ÑcÁÊ\þã¼i@üÂjú ›5û÷fW„íéþ<uÇë¥Sï¡„Ž¯ôênâŠg¾éB¡'Ÿ'÷?ñq—eÆbËû]jÁä4”|i¼R½÷›>°.nÕÛ®t¾/I1dG•Á¯ÅßI‰;ÁšÙúJ‡9ÂAËÆ¬ Q•'êLÖ°:†ÆÜ8Aä|Ì—^8G°»Ó8]åðý»—Ñ4™BÍ#Ùo’ö°sZ%näN :ÛXš§['zØm¬¼ ¾vì‹>,g0<Þ©\m/†Tù¿,—ù[ø3ÕœCålÇl’r)~ þAÄ®ý‡ë$ƒáè1Ð{\Çk¤õt[n¿3p+1_ÐÊÞôE€4Ky€Nôš ôoaËØî?á`’’ žÛÇYSd¸³Èƒ?€ ÷úÞÚËz®e@ÄNäNÀ¾÷ó즿÷aJù죧® pt-ì¼û„[Ä¥¯fµ³ö¥&E;‡c]àõh,íõ6 ØTüïö?õ·CÑÿ›pv!a?±»é ‡˜¾åýÖÓ3 Ì/¯ÕÓŽV v—¼O>Ñî žéÔi9ç¯ÏBF»¹·ÜbÉ-#90ÉuMÈ&ßÊ/¿öF8¸ßÐ;r¦[¹µFõÙDY–ë8k:Ò ^l3*%"ÜîìpÙ Ï]ÎdñVe…;b·ar Q©¼ÿ4' M§b|Üd˜Î*#ãdŒ-×ÞQâòLfi✒ץ5ú idîÇ”±™£·\{³Kå›À'E#<Æø¬Ò`¢í‚n_{Y ¸Þû@¹ÍïÆǼËZ¶mrÓäCvåm$4âh*¢vjîè&ÊaüÞ¿,Å»Èéõû>9}ÓšÞSa¾ì½§c×Uéù­Î;ì¡»Á\Å:­¿¤zÀ(0f„¢Š`Ð-¨Üd×suÎ5y°zŒr!öX)¸žì¼Yny`ÍA3» `Í&ò~œi{ýW¿V¶ìÔO ·6±·¿GÞ—YÏÙn=Ìã¶_)íÄ=É;nU#Óó 5‚#‡D6Ñ‹¼öã j‚³cýý>úîWe3DÜ©·×ž—Uo±Hæ¼E^Òfë|‡’Äfžæí@´ËtA‰u`‘˜lðùŒ”«àiàÚ²ÿá®ðžÜèU Xÿ^G”û€ÉˆèÏÆ}{:1VÛ3!û$3&¡úã eÙöçÊ4§rFn ¢V=àz>õ«››†¨Í}2*éÅ1k°¢*Úv±¿ì:Ýí´½¯íZjxѼÇ[©øýú,ó3æ”`åÉCɇYàA@ã•)î*8•©…ûÁi[p›¤öJƒG2ÞM£¡©Šÿ`Dâª`É”ãWâ?[HxMÝyÄ••8ïù¡éÊ%mãf-àa4¼p7»]l£³û‹£¾NG7?ìE?SG{ãgŸTÌoœüœ|á Û³Ãï #qÍMÏÅk¢UV&÷6ÁX÷ZÍ •£ÞÍLî ZןíŠÔOŒpÀš¹Üþ;øïãÞ\®®7ކ¹¦üRüÿ‘öeÏéL§©­Ùvã( %î¾CÏÜáaåT¤8Q‚&Jz¿…¹îéÁs””‚ýžÕ†ÜZÑGßÅyJ”$)/ù­G²aW/@t9‹_Dœb·><‰Ï-«Æ§Ù¹(¸T ¼ùÝød9¾µ¿¢©èU“ í%RÞ£øR[´i›`®.ºìMþA® vD=ëãñ¦âÿ›ýÿLrñþ÷Ù¿"aœþóÏNÿ0T>`vÚ±p+¿1xmCNsÀª©…»Öfhr®Ç_èwb8@m¼Žœ ÌÎ|¼é°6@Ö;ÿÛaqk8BݰˆÔ-ÝØÇ8y+|YÒnpÊc ÇýÞó6ogX÷d˜„\:›s&gD@™áùuÔ‡w_D?yÙ_™©Øs\|Q ¹á+žèt:^4úÁ©Y+p« æêz‚µ§üvîá×ÉŸÁ¶.m·ó¾ðYé¨ëkÕ)€=ûdl«Fæ kOÍ…?TØž'y6öV¹ºG»×Ð)ˆ8˜¿±[© „"« 0ÏkI¼ZÐu ¦’N¿Ûä4n[ñÃ0hRC6º…:[«A¹±ûýÖâðg^l«ÐÌÖÁ“y߯ œV‘·#l¦6ûöªô¼ºs +Лþz9˜¼«Pß k…øß³/MŸªŽâüÓ2N磅glý£­nøãéZÊé?Ô*|{/…öœ®ˆ»Ÿ¨–í¿÷Ä;îÞP±Ô|W¦$¢¤È÷Ùu´€‹J“}ä„BF§sÄÒù1íKzWÉ^`y*Ô’C3l¡&\ØÂ0Käé°:ÒjyŽ¿_> 8öxDÞ\“GÎÓoô$ÀÔe[½-}î ¨ü{`Õý&À9½Ø‡¢/”€üTüE謤" aNm€u¤"êøäè)×±þ5W^_„¥¼Žpgñ;~Àók`a3¢@€ÁÄ[öÝá÷öTµ½66|üþ¹;€ú5»@àzdPˆŽ¿ûh¤ßâ°IJÎÅ/E‹÷pÈ‹{ (yò¼ßÛ•‡ ­áf‹!‹±¥ð­ëPÅ9"1Eçtªé„6ÖrÖ2ç²¾¾Xù…øoxÚzHÒ¬JŠoi°A"ÆAòíøK ˆ¿Tê<›>×ÁׇgêÞC?…·rì=ÐÞèßÏrÆÆzãZ°ô R/²Ó+ÇXŠ=Wxi­AM}Ý|æÙa¯¸zÔ6Ù¶r=Ëѯ“sò¹¥.Z1Ôu7ó9íßÂß9ój? ò/!þÿTû¿ñén“ζXâÔóƒ0¡:(-6’€ëRB Oua°fà$Ý>ÈÞøÒ @ûjÙõgÀŸº•9žŽ®÷VOγÌaÚø`4Œ`)&”I‡xjw°›÷µývüYßiú"!ép`µ›nT?eÜK O|ð#£§[•‰WÂÛT¢jLÛ”á¦òŸíÿÊO 3öÿ>û÷ëÉçïüÀÒÿŸ6f*ÄÃÀöXȃuáwúÈ ò×´Y0ÚRƒ¡ñ¤‹­»ê'a°¸Ì_F¯«[o•çêCÚu²ñØ… T‰¼c7w› 7|5P"d·0ÖÕñj–Ù£Œ) Ÿ1Ok‰ˆ{Û d ÆäKM³áíç®›ºGÞ9îa˜÷N%ê@ð~yˆã©Kµá9á°ìæ8Ð.¤jhÒ'(è•™âl½§¸\š®Ó@ ®JÈíÐû ²ï ã]ó›“Ôv—G4]ÝÞ!Mwãs¯íB“ñÓlNOªÇ1ði5²Âù©Hv«\à‡ù’;ãE?SG=‚#ú¬à¸ˆÃAtÍ{g˜¦6#]ž‚Q'=Ú¤Eïe®ÿHl»²°6ݯ?ÉÒ*]% Ù°aÖ³gó9¨9¿uõ mÉKÓ[X­-¦îô®y Î…g-kðOhÛEH5¸é#³‡$ÏäÓ Y;{Ì 9ÅP0¡©úpwV(ØrÍ` 32G"Í¢ÝUn(p{°Q¾r1”ûù‰D½Ò|ÉxÛ 7sgsD$‘û¦ls0XKi.Ð]VÀr - –åˆîÞn‡G¬àô$íKÙ[7ÛÜ(9B–ŒÅ-Ðù° ?€÷ôlPù'äIž­ Œ²Ø­¿`ÚñSño 9d0>TØuä™H ·UÂ9ð(JµOî?pôMA©ÜÖA½â5ŠÝ#ÆdùpûíšC]çÍ.RÏí†ߜAK|ÂñlÞ~ÿÄ¿‰ÿ•«÷Qù?ððä¯Ãÿkÿ z½¼ ª¢ð4°íáƒ+TQÍéÕõùÁT³Áò#ÄBÃtš¤êÔ°Ù&8ÕÞ§>¼u¦„bµ¿~\äÜl}p¦ÐHéB"JqôÃFçøSÅÀ½(ûâlH©Jÿíøc>§L§ø9Ä3L=µ?’¯éb°ùšM1{Ÿ%œ¥êm€í»Á£E <°û†PýÿöŸúÿ%ýŸäˆDÿûì߯'§¿õKÛ˜ÿù—¨V<6¿#.ºóµ\jRâÔoóݬ–®;ÇúTöíܼºØ’µó‚–©ì:#•,Aý‰¬#¯Ñšª!ÚXx'$’îÃ{= ¨TÇ®”é( _K¯XŒé#¦Ù\ôfyåMšwüü¬lÓíJ°µïV¨óHª9BÙ™_ |,çvHp)(a!¿Ɔé>”Kx5ùëÔ¬ïUÙcéà d7âÁµDî5/±¬Ü ?±††ºá4kÜcC“#†Õ€„–R¦†‹¬í= Jƒ?Çóˆ›/äfI®cÀ¯¶o¸ ­‡*·qh­ed÷?äÈ?õ4FF«/†˜Î㢽í‡÷øÐ% ñž¾žnÒtªÑÈiç~¾•Ñe·æÆ7í\‚1=;ZAKkÇì=—ô¸MÚDD¾œ»8È ûø¸?Qß44J1?\©\ê^©új3<ù¨×¼¯ÝCÉ,LöußÝ~ËÎ`ña”…Œ „­*`Qö|a ßÿèñz¾Gé›/^ ¶Õñ;Ì7ü.¹ûnùÀ#Ò+]rœ~Ün(S.”ækÖå³âa¯ø¦ZiÙ»@3häóoǰÛ5td£òÀ×hˆyéèhXùéóÓ`ÜÏé &wˆ ƒ\8ôÚ €X]`˜ÿÁþòóÿ$BþÍ~6}ߟÿC~XòˆƒOŒ?KÀ#€%ÐÏÁ€t†Ã#À¢¦Ž`<ÚLº„ž nþ~D<Ê8žøF‡óœ½.@Qi¾+³Y>zcBÑ+¤+ʱü.cV®áIÜ8ür鈳G³¬[8Ĉ¶-¾1~=üE,_îþ¾gŠ‚¿1†!ÍñOÒõo·zãV&8E¿2~}¿ò +‰ñþ:ѯ‡•‰‚›ÿÊ›•,cCp<–€t¶ˆ‚ÇáˆX?KDeèŽNC’ÜpDÄLÄáÑŸŒ?Ê€%¢# Oâñ!âÑ¢KG€óCå Î…ôGßã¤_?¼t%‚×¹ˆB%ZCU¢3ñpà P¨ü‹P<Πu´–åU8DῊÉ+ í½´Œ] –CD'ôKð/% ‡®‚&]«&„ÄODdy¾þh **>t2(7:*ž$Ò$°(þxŒ[: ÚFD刊 KºŸtXÑtþ8À/pDô€%¢ø«ü^ü#CVáëxÌ å ûvßòMÞ˜•Ñ}þäÁ} Å÷{ij¬kÔ2q²?Ê(ÿ½øWáTÞËh9FVÖ^A?ôê2þ¤Ïÿ û/ D‡¤NX<æ‡Î‹_™ø²!â–EG<‰+ö‡âê–$3 ú‘$T4èbHfí‚ø S&Y4 $,‹G”„?j¨‹Ð߈-¯{p²5h¢PCÒv÷x¼AA¦vÙ¿à$Çã¥òÃöÿƒáâ{èßøÿ~8À!ˆ]aY+ðxÉ_`’Aì»bÝÔ'à–?j!$W±‹'Ém¬4¬xŽe—à­šHø:•?¬œCüIq„¿\üj4ø¯Îù_×(’{âƒþàùÓ^ÿÿ:¬øl‡("Z^!~uìÿGë7ßÿí¢ðí>œ]üJÃ׉þq3 .‘¹øõly(›¸å ¦WLŠJhìÁH1õ€°­P¡¸…¢.‡_ɨOr ö<†àŽÊ •4ãñÃ÷Ѿ}H Kðõ_6e’ÐmðÆ£Ÿ1Î1¨K—pÀªDpÆ™xG«¿ŠÇËWâ¯~“4É­X›@V<òÍ`IþH2—¯F­’ääI.•—ÑQOFŠ ¿ÿŒ$Òh?$¹‘¢Êã‚JÍnˆ$ω¶¡‚BY–Ó ý[´rEþ24z„?ú).|íåû:=_ÿÆoqîëð@ñ'èCZ¡Ç÷⟿"V’—G‚å‰Éütüü?Óþ«–“FürÚ¹¼’.gŽË))IQP!x#þh.JjÁcmÑõ“ԈĮ³¢Z*4_¾OÒ?R3Ö¿Œ¿šÉbÔ#þ>ပ«Å"&éDäd5Š˜Lž(]ë«TIBÅOÊÜl ~Ðþ~ðoøÿ%ô}?œ`Pc÷ö ÅóÅ~¨N|- ¾:„•ÜŠ·X® PMÂ:ÇàIé>©Š#~cDÁšš”þ9“•„ÕW°‰ÿVd}«ËVÖôø‚e;÷$­\uõ[¶‰oföãJ¯ðW?X% ÊŒ=íW†ÿ³„Ãÿ•ýOÇŽ÷Å~ÀÇ'ìÆ?³ìîñ·æ«ô‘oŸ1.1è¹<)Çà‰¤Nò+h%ºRÔ`Ðû‰¨A#>ÚºR^`mcýI§~è-D’ßÅ“h,D ¯åÍ®1hß''þ5è&é`‡OËLÔEÈÔb𲵈a&±‹Aõ*š¨Èÿ˜ýÿüìÿøô¿ô=ô½ À°œ#îþ~@XNWü5ŽðÍ!,pËNûën-~ÅI#Þ+;º(ãWgCòX‚›À…è¿ìÒýeÃãûÕ±þÅØ¿1®hâÊæ˜C¤ÿ×fœ],ñRù³Û?Oÿôó¶ñËEžrNÌ_*½¿8ˆ¿ìÿú ÙwÿoÛÁÖ€è¹côJ…ˆÿs1ËÅiÞ¾a _EÚRCƒÏò®?^ÐLªŠHÛúXÇ8´Âù¡¶[Žéh óuŽEÖq+E~¥Ü_vHx_¿o¹*å•tÂ+ãG*NâÑÜ~ùÔÙÎ7p9  ›À™¥7ZÊúúÿQTy“6‰x¥one†wN •j¤Òëÿ%øçEãWÄ€#E÷• Ar9èúQ)-÷ ßúA=ë·/H¹ÀòÖ3Ö!"`%œ,'M_ Ñån¥Š#%Z¤¨F\ Õ+<**ҙϩ߇ÿÂÊÖ/òçŽî·m‡Ø¯~ÿO5GõŸ”ýQþYî­¼Ø{y‚ð8ïÀeý·ý#hÊÿþUËz…_ $+Èò÷áÿÛþ/žn‘rJ i×hù+:·­w<â ø•ýÿeˆÜýII;YæX.÷I-(þ$‘¡y&üI Ždê$F,„ÿÉߊ zâóÿ´w-LqIúÏ!$Û»Þ°t²×Ÿ-Ä{ÞÝõèîyÁ0 @Z?´ëÓ*VŠ•ï´z"ôã.¿ÌªêlK `8.‚k<Ìôô+«2óËü2«k?8ÔæÒkäkf~Ðñô=]o%¶‘i79tõã“ÌÿSß.àÿÿýv@Ë4 yÆ]+)=gF…@s¾c*:œFx]ŽwÁ‹¦}¬n~þH?ö j—T1k&Lgã¢2I AÀFy˜»ûÍÚFÈ Ž$ÍŠñ?|/î¸wKþïî¨ÚGsoM3î„È1?L öÁý«ôг.½-œim¥3„màœ!Á Ò1¬NI_[ËRŽhó §©Éš×õΚF™è]=+ù§›~ ?eÒÊGŒ}Ycù‹ž/Œhm—Æ ø°Þá]yüã]Ô8ü·Z¤ªDôY¢ñ8ä¯õ¹œÿO»sc?“I¹87=âQGþ5{AËËK¼¸•ŒìƒCšV˜×ypÏL›ééCpþ4 Gý ôÒãÁdméf ØúMޱ0˜»Ã{#.eÌ'ò´!+L£XRËt0•p\€Á í8ñ’.âú#£>`*Óÿ0Ž öÜ,m2Þ¸¸æ7%ó€°+«½pÉ6u¶€#¸@ÑK›¢âOWþYþé;ëÎQ :2Éß…cÉ%à£óŽÂ”˜¤^nwéaZ¦lÑ·$¦+ÅÖ°/a¤x>¡çMTí†Eš3¶_MŸ‘ü_š#Ÿ…°@ò©åeqcn?¨ø<\<¶ƒ€!QI;üçÔ‰äÿHr׌ôÝôôå¯Íùœÿ¯,_Q—+ÌŽ'‰ÿ“ü1RÄ_ä³Bþüy#qÇ,qÕ˜…¶«%€€i¦¿:SùÒ0ÿóCyßT¾~@³còPÛ‰WfehäÞ¬K¦5¾þî¸óÿ´õ…ýßvàø@ þêz¼Fo4'm‘Ó¥1.P©°H˜_³2H ;Vþ`Ìí{p*•£žŽ¸ÿøPÍÜ1ÅÏÜ…Jð•g",t€³Í¬¨ jÚÍœ¥A—>SWwîûom‚yÀ­Ù\Ëâž+鯢NÅ4Q“¿§m$h¶\Ôß0ÍØ0nµ¥}6Fâ˜#½Í967車ùÅ ñFi?¶ò%2µ²ßþÕÿ]-lZ eN7N½4溾ò—#PP}ú‹ŽóG‚40gaõêFP,“¹éB£DÀyòÝ]{êò¿óSËýI·nEºB€üxæŽæ|±K0ðw¼@öÒx~hC\…j~ÐrÀS ¿“Kè8Š×=©‰@ßäÙÈÿÁ–„Ž$zWÚóF-¨tuúæÄY륒Ҟ\žÿ5½Ü¼cdÀ ‘ŸEù?ÃÅ«r_Ì7?ÿ³ÿ9™ÿ»`SÇÕZÂMœh¢iÕ?vž#G笮©5p2}Q’?h):TùhÍ5:š“ 4£'ÎVþoèJ.½¶µ¨¯.½†¢˜8HÉ ˆ¯ÿBNóÀO ¼Ä—;ÿoR޳]˜ÿs³×@D/‘ɾÒn%œ4tÔ_Ø(aosô,…Ì,ü‡ˆnU­ F€S7¿DíÓ¦˜âãSñÿš+ÛÆ”°c&è¦ÿåî¾ZرŽE“§ÔTþ¼pUVþgí“nòA„@äÎîçB\w…bÚæä0³ÒÍüiøäªº^ÔRÊ*œz“Ò@°4%ÀŠX?k2ZÊÖÛ ?Y€|ÄŒ¼h;ÓHŠßþ] OHœJÈ0!€Y„¥zⵈ-ôÇJ§MjŸ.´Q}õ熬.Ü¿£XS^ ¡%÷¦’rOįlºüŸ¬Fú¼·¤øÔBøì¾i,ï¸Ì€@ÂØ¡xÑoT†ðŸâçê>º8½°“8€“Í€;¦É\AÉj^ͺ®¼@2Eg!ÿ“ü/³dÇFËæXÕ—SjozŸâ7jÁÜeŽZ8ÉmÔÕ åÿ ö®Ü5¨¬ä¡wò?7óÿ_›|l\X|ì†shƒî(ªw%Š„ùgSW ¸Jò·ŠI;˜ƒ4ãúB-eΟ‚Åqžêxg+ÿ„t*íeËYO_zCZGràêK=qHó¼ë?‡<êsþŸêvaÿǹ$`Žç€vÅ<^X.¥oÝ–Z,“HæPE !ëjG.@ÔÉAf Iì©ò‰1?…æ½áS¹)m*YÇ#çÕûÐö.'=SœÝü˜çHP&Øæ™1ÅOnÀÎK»‹ñ߸¶žëô]Y73»ö?w¡x¦^âkw¤"¬ qÓ 7‹K²Q»ìj›¡ä¼Ëµ@¸œS–ÿÏ{b÷ÁºN8ô\ºŽÛ“ü­—]NÙcp¦²]³Æç)$ù¯1„SR»ì»u¬@–j’Ä'Ç \¸>~ùWöø3ùè“«Ýbô!?B ù =\íÌæÊ ˜¼§û‡»yBùÿðÒØÈQ!.Âáð±È_JÐÎÝü†af\A €zŽÿ³üµq•þ›.€*í²u‡ÅÇôœ»½±cŒÅ5Ì4î+/Ÿ­üà†üK·õ7$•L¾R¶ÒêØ—å@’ËcôÂõcÌÿÓ­ÿ»0ÿãÝÆà(ÃAR|4ºW‡T—âÒ¡H2I’ ¥‰BƒÉ«ïxvO*I£¿Ì!ê”ÁFç}‘é3¿™‚c#µ\À„9Ìj»mFüd32³âÒ~â ‚ÿL_+?OLÈ€y¸‡#4ëýÑø¯ÿG÷ïµ=}]Ú;‚b\æÒyóV]=$ã>{;cp *•C¬A—¦PÓ'L+†ûå~´´™‰/q- ÑRÀkŒ+ÿ—à@½KÓ‰¸µVÛ €Oõõ÷ú#„©«Ü†LêZ@±|u(Ò×WÍÃS1Ì*™kL’ÿMœ–S–ÿ³ŽrqyãÀº”–§R?îªÈç7.*—$€ø|*Ÿäâòæü­´;6‘=©ì„gÕœÝO]1 Ç 'øtyìòI— Žv¡âJl™1˃ðwéE/åuµ¸)´öœ(Y‡«e X0ªJòŸ:±üc‚œgAi«öÇ.ÿó5ÿÞsu-F”¸dZ}ÿËÅü)CM÷]9q’üyo@y\PŠp“µqy¹ê“g,ÿ׆¤H8ý×øê!—ßh3q[r6„¾à*:–4ò¯/¾{þ¿Ó@œ`»0ÿçm{·À¼]V©.èW3]Ñלٰ£iIPÝ¥£2ZµE«×ŒAí•wêýxø-*°â4Ø(ûGFj½2ÌQôùÍÜv:âJh5‡bÝÜÝæŸ¨øÞ©ýBî{¥ B@ˆò»šîp²Ú/f÷FbtL: =¨ëõÍIŽú‹Í•ÆH ¶ìŠ~åûU ¹©›wÏ:ûù˜Ž§¨äž^â4p‘»@”¹awé"›„榳…}ŽÝ!)|å¨<*jî£ÖN$ ü¤íÀ ^®¼6PçÚ&H¬³ÔOWþnK¡¸<7é(Ùe÷Ñq Tóïî2Òöóùœq¯—·oÝ%£¢¥êÎÎmg¹ÕwüA;àÌí¸†/ü5™5ä .[þÏ¡WµIC×®ú‘è¼ 7”k]Œÿ»Æ†! e?¿éâ `~Bw%àQÌm5íÉåÿ¼ ô‡Æ‹´MŽ[þçmþÿíû˜=BüÞMTY“ : ÅÏÄ?ëä`·*÷¹<@:åÔ¸øô$T¦'ÎXþ­.é–†M’éÖüÞôÊ䡉'’wò ‡©¶R¡¼cþŸÌž¼}»°ÿãÞNȹ,†';Ò„HC«Å~k¤áwµã}$¬›÷1\_C;–[=ݸJâÒʽúÐúãh¯«ÑتA'Á9Ö•´“Ïa“ÿiÇå¡•hY Э/m3ò‰áþôhãWñ_Ú»<È §t].o—û¾¬ÖJý#¹nÖ‹³}ö÷¨ÊiÏ8xû%HíÌïЄh¶$»^P}ÜFD¿¾AGi¢¨r,÷5Ã[&ÉÝ܃ád$§Á—¯¿Ä…Véd Ÿ÷ˆÄ·öHÍ¿dhˆ¥! °Oµú'²I0ZæÊ+.1æ«gÌwºòOŸ¶ô‘Ö?©+ .€ÔB ÝllX×õÇÅhÁLJéQ¶ƒ/ ¤w@êà~´¼Éu±oòšHž}]!GÖ‰ãÒ¯«Wþ?vù³rÚ5þ•¿84…S^8°[Çø/ÁÔ(€çgöݬwiðåï#ÿƒ$ö-õäxåçÿãåÖ?b9éF·]ÙN¿QKÜG´˜|oÔr?‹R†ûÕi´–ÀÜ °e¸ëögwÏXþ‡¨®õL<cø‚Œçömtùµ8´zqËqa„«ˆpº¼mþŸ¦½¾0ÿãßÞC`oõTœ¸®T‘õ)>cf¹%(³×ašDs£m««2Gz„±›ÝZø¬Pû#'ÎÕ€D,7›é+Иüžá›h^þ.(¸û5µf~=§pP¡ŽÆ…nóåÓ, ?Ù ÿÅ 85‚C×Hg#¨Å߇Ã7ÆTJ÷¥P]Íî¤LP‰£X[éIzUg>ÑŠ"z·Òç´ÿRÔ¡ðRAV®4` Ä®1½d¡©ˆ°®®iÛ˜¹›é›wLi×$Ó»m€ÀÐ9¬˜>ýÂü¸—|5¿Ãw_~Êò¼¤Å?J|¯×6ÖaGÇ@„€äÏj~Gó7·C[¿2× ÈYWõš•Rv® p-™½^á;f×Ìçã”ÿ·÷åžåF5ýáMµ—Ûá‘w«}þ~¹Ûö“7¼¼‘ RÆòãúßGþÛÏ|ëS«üÏåü™…¢QVV7«ë“D™Pæ"&2àVgo§Loê4aÃÏ;éˆNB~ »ÿõYËÿ£·¾¥Õ¹»-ÓÌîªlz¯¥&R×ð(µ¡C=ÊÙo›ÿ§¹]Øÿó¹½Íˆ¤…7©×òüpÚ}6ª„ ¥^„©ëÖ8.[HÚj¦•èÄ·­~bÌî= ¿Ž÷ýf.P#¢Wða¿FysTY„ûh= šê@F1th®&_«•ä×ñ_¯ÕE›è|iýânÆÛ>û• }Ò‘ßò4·h YlfVóó£C@Ïf`• 뫹íÌ1ð(#Ô±Y®E¸¥ÒZ72I"•ƒ\LP]aU á L=Où©«/UòÑSmK5ê+$˜Ÿª°)/T€Z  žS•ÿÝ{ÆÓý¤±_E ;‰ d™k÷«f·Q·Ì­­k`JòOƒÿLcbMf¥¥ër¯-;ò¢,²Ì ¡Q]SL0—2V‹3$kÍ¥qÊÿ…£h=¿G% Yäo hÎCa-cBÆ¿èy°2–ûU½ïòÓrõ½ä÷g÷éŽMþçuþ¿âN…ø¼ÒÏ€â1QÙh"B#k•"ieêµu+E-޼¦PÂÔ¡Dbx¤êÒYË¿9lӯ˚û4è‰WéÄ_>ŒÓ?EI°BãïÇkG§xþgžÈrC…#Z·vƒV縜uuž9ÌÝß àœ'¾ÃåV'w¿‹/ô¯ùñß÷Fâ¿Z/sƒ »Sþr*)zÐ.oš0G”¿ÿlêÀ ÙoÀú¯7ûyƒ0¼Ì퇖®@ìzЃCKàyÐ~¹( Ê*ë ª¬´Ô &®cºVöƒç¥½Ä«82Kd€Ä˜Õnêšé¸[(¯»wÍC^2_&•Þ§)ÿ'\U?ÒúGÌÅ{™‘Õ•šß³ø3S–äÏ Öp\À:ãûþ!êZÚɘÈÿ¼¹ÕÍËÿ}TÆ)MOþÏC›5Cò×#iàÙ=“[@÷ÂPÚs‡ˆyü» pe-(i÷™6NnÎŒœðýäÿ¬­¥º4/<}ùŸÛùÿ½îk'iøïšÅ.8`\- áûÇ @ðÅ£Ì7 p tÉVÍÌLœ¹üföSÍÕ2)y.êÒA2ñÆD—ߘ•NŠ ›Pë Êà¸Di‹üÎü¿°ÿÿß¶÷Ùïy:§þÒ .}ñã^ÇÊR˜ñâ[‚^Ÿe£´«.‘!Iä»Z/]3æ^¯×ö§:¢|°˜ äjñz'Äs˜Ý#K‚ɾrÛ¼O³²é‘¿  ¯˜>3¹ÊÛ|í—ÞHü‹ë0_n tb\õíQéÖí÷<ªüé‹™á€[ÿKpÔe 4·õ,åu¸CiHæqÏQ^´–æx­1²,BÜF&baaÕ@¬ ´‘p ¨¼™#½¥/ÿ}àVlŸ;׊*giàŸõê5cŸú•A[>ÙÈ¥ì§(ÿÿêõ:ÆõõѲìšñ)~´ó‹R¿ T÷¨WãuWÀ‹‘E%ÔF…†ÿƯċÿ R¯mºž¿‚tØ5˜Ýj9<…œÇÿ±CTýd\òïo”6ÉßU‰Igyv·0ZÅp»(y-ê‡Ã2Ô䯭EÈ™ó³¢ÐûÉ?yáW¶ã’ÿyžÿÿî©Ô­ Œ\Ú¶²Ò_‚UñÙÐdA‘þOx=I·o à¿‹ù©$*uÏ\þoš$ÿ+ÓùS’?¡»¬X€…ÄÎØiæf‹ m˜ògþÿ/¸8ß.ZZxœì½ 8Vkû>\‘!‰!C2šJƒ)™UæÌcæyzžg]Ïdžg‘ˆÌQ¤RÆFS•YI†â[ÔÞïýýþÿïÛÙï~÷qìë¨Õ³ÖºïkÝ÷}Þçy]×ÊSk`µÌÛ%š¼jÎþ±Õ6äBÂÿrgO7å~C€2­eæÇ%ª083ó6 ;ª½z Ì…IÃ{#˜°ô6:Þ7–øœ‰in˜“Ùò®P?ØYDSCÙX7º àqqªî—¥~xðqG‚ˆ[‰ç÷¯aƒ“ˆêG›~=¶2ço }ùü1Î*÷ãà$rs8}j£{&w²bo©Ê]c0GòQàf#ƒ{+^4Ùùv(G* [ë~Tï¼wJêJ9¢MsgYä÷¶ ë¨ö¤-¤²’ãϼ’#—s÷ D² »Ô¬Ýq«>èÝ$ó­ýSBQãsx™v"°ì–$ɰhèú²ß9ràEô׊[D(‰–‚S³gíºE—Ä€¥Ý Wž êâÄ£ü4鑦 jÞžÁƒùã`¨¨GY}²@ß fÃ[C¬ îp½xb©v){ÆlÛkujŠE‰\ô•Rì‹p*#F„z ›×4¸ßž¹3uT®d÷ç–-±.!˜D}âÅ÷ÝÝpªmèëeã‡Éoîš1¿ÎÐM•K¾„“½ïXœv\?ṡe øzqCKç#‡±Éòüo&®YåšË§¼)Tp¶A?>|©B¤éùÞ¹\4œŽ\GîÅÛô~ÝCùT( ¬Y•Žœç÷’à|Å,0«‰ÇÍ»Ÿ> j‚ÛpîÇh*·O+T­¬o'tž“~mÞ-m»¡ï¡YˆÏµ –pÒ«È%RÕMŒZUØ>e)AÂU˜¤þÂ@„ͯƒÀ>*Ò$ÆQlñ€ª¡´/J–¥,¤|™à&>]ÍÓ>Ϲ.è´ŠRn‹›÷PÚ©Ô)ÔS§H3§Jq?çø¸aÛÐtˆ<©PŒ0Ëãÿ'áoªô7ºa“õL_ÞÄñÝ­YrÙÉ–ÛîEï̸ñ€˜æ# ˆ–ê¸Ã¦ÔæÜî˜oïò¤î¼<ÆÑº4ÿ~ïñK§Ÿ+ #y„l›UÌrRˆlŒî®ÞhÓ®ƒRþí<$Or-Uõà®l¾ìƒMâgrÿ0þ˜Z†ê0oTù“ðÿïæ?7^Ç; åÇ ô‚¡!yꎲÈÓ]ùd0= ÎíãÞþæó€Ð8óMŒø²\¢4A†7ÏÛ.%„hV=ZiÓE+‡tþ±‰ÊG>v üÇñ/«÷žèlrNõ Á¥X¨W¤Ä¹8ù_“„¯_HAÁ¢æÕ÷u® ¡FpHÞ’Àú•¡i7ÿÿÆÿUŠ/äUóõýŸÌ;ðõóuþ÷‹ŸèQè¶f-ñ]©ZS6ì,LÚ}ñsš¾œ]ÈÛx_Öš‹þìJmÉëßÅa¼DÖ°„¥,”Jt¯2X1ätÙÛ «²:êôÁ`‘HgþpéÐE0Öé³ÐvÆ×ãS‡@ÄœI €¾£QNð ­Ÿ®ôIFÞ¨Õ,€ÇDÙÀþWæÌ þB_·—u„ˆ½+Ó‰† ¾] lU7>~Í"àÆ!}øár¸¶Qîï~ƒ ±Èwc|þ·4ß…î #:6€˜‰E€¬Q4îˆ=†1šêŒÞE5þ`‹[—X*ÂøH[ñî4_¡PÛ<àÁzþ‘;Ò…Òåñø£N­P˜B¢é‘úüÈö‚_¿pâ*ùj+tòà"$ê^È8#©<€ß~HÆ3ú²‡J*8Mnß÷¸«³Žb]Š®@z»Wêä„û{y˜-‹ªÂÌCrÕÎWüÃEß(<œcßG'ξvò`0{4yÕ¸¹½æúÅŽ‰³Þô–u 7y,¼åºæÓ?ÃkèBÇRº~Ÿw d®Ô p’]z¼ÿZÐ4os«Ì(ï‰(Ðí± ÿf9Dÿ>“9¶5æ:»R%ƒém•ªÅ…]cû¾ñ†¬›JÌÑM`Úª  *¸Šø[ðÃ! •D!/Jåéº>&ú's‹º;áä9d $­ê#úü/Ÿ×„nŠÇ˜–}&®Yô_Ÿf$¾¸¢˜MAŒ@¤s€€z¿€1Îä>€¸á ¤MØ7WÂÏ¥÷ áu€7-ÎìjØÇ%Vä48*áAô$úhùaM}n(Ôøsðg6ƒjM—m|~oáâ.\n Øà.ùEo½ðË@{¯TüyÇãaž¾Ùj›îÑ–u ^˜{Ðé‰Ã~§EWÐcŸ c#I¯ÞÕ)¯Ë}eóÞfwÔ…+F¹V(òìD$g-çú2ÕmÄ?Ž¿tìÆXNÅ\Ÿ‚ÿ;ÿYï^+‘Ü3ð,]UÈñ¾ñV5‚Å'Îpà .½|ÔœsH}«bä¥P(º» ü´1–uoÎ " ÙéK­iNÁy®©H•[a\mp»6ë‰CÆ{?ò_€?šáÙçÆP}wÝÀ¶}2E¯Ý#»çr`»Û>7»fÁÙˆhÔ°îf() :KZ[ÞÞÿ‰ÿÅ?Š~g1ÄÕòõýÍ5üvtñú·ksý.|ŒXO€skvŒIDÐ.©Ìu>KΚëqqÕ¾ؘ܉ٶÝÄ@Ƴ×!G€‡‘‹N3\íR$NØo2dq< àÜ2ñ°AŒR2UÌ1”Ó‰D“Ý}ç¹™ÑÖÊŸ¤.XîÓã¹ò§\š;X$Z°ø½ÉK­}Ä3*BŸpSpÞ…‚ +ÌEà›ó“^ƒ‚ô™æÞ¼È£¯ÇTz#÷š2|Zpg†à[Âü^8zÈ$øPW–‚°Ô–yŽ_|xgØù!C[ lÏVœ $ìe$–n?¼õóWæˆ@ü„á“6¸³C±"bŒÀQ¦<xÞ[Ú.é¥õoo 7Q:LöNÂ÷(ï'½ °ÆIÌøæÙ¼°‡tÞ™§# ·÷èyz¶æÎ#£ë§R) OU9íú¹ueõý4{$I2SÒr;eØ6Ï–d€™ûÉzªá¯¸8Ç^rDޏšM”à—k>øD?·9jůGŸìm8âMÀ[–ãÍ2XÕZÇXÚ€—Z^ŽõeàÐØãMy½wK¨çªU=b¶%6mÊx69­w}såë]y6å<ƒÎ‰*9Ýg{9¤#¡½ÿÑéíDþÊ`ÅÁ༃Ža -CI÷ÇdÜ.f€þÏØ2n™Ó¦ÈЇ׮&þ¯gè( ³Ï)‚_ú¨ IéȬ}¸â‚, صû »{ñMoÝsž ôù'ÕÆ 0·”y—ÿÝÁ\Ó®š-B¤-.RûÂÁšæÈ9€ô¦ó‡A§sKhcòãËk…œµ>Koôn 0½ºÚgM`£Û|øújU"4ë%ª«PnGvˆÃ‰YÆrèù¶kŽð&ë ,IŸO®Ì¦þ3ðO>ït>Sð± Ù(¯¡ù•c‰#çW=AJxÿþ™ï9™üuCù^^m‘¢ˆA5ÕGÐâÚ£‰{Ú½OZâæ¨IÆ×ñø’ËÈ×j½ ážC;Â|,}|Çâ-8 êCõVÉOOºŽñåõG2×4Éx¿ý üÇ^qµÅ·¤ùðÿð?Ńïcf³Â.à0]ÙåB~x 7]Þ‚-çœX„î}€ÿù‹jÅL3p…ý,œ?av®pcÂ7Px¯u²ƒß÷L׳á0¶µe"P"’øà?F/Ý$6lDÐv(ëÙ  Pyxò“c\?<2×6¢ây!†…Ãìâx¨{44‡¥É`OJÜ]ÀLý?ð• ëºjÎþ±?Ë.ÄþíZûÖá]¥·¬„êyïEœ÷•Ì@À‰U¿ßÌw}: ,‘!¯ü™>€û‡ÌX°]Øö…“¦`»ÀQÃ˺=¯Ñâb¤ì> ¡P9¯1N±™b 3#ßpÓ!ñ4P?,tt´Ü%„æ¡ S!€dsçÄÀ§±~Ý–ô; £Xò°gG`úq\]Ì7ƒ9iÖu÷üÀ<<Ê5ÀÃkèC% vŒ! _%]7ÚÝÆRúö‘þ¨ß<#5ç?¤V".ÝüÖCb³[6< 9üVžäêÜË¢#tá¡1Gbõé£d™A8¯žx³•=„½Ã1ªÌßüøåi*É”»Zö£·€dÂ-~‘s¥8ù£Fc{ðîß¶šð]Ž|lúFl1G¢$öõf¿æ“3IŠ NS„HŠ‚j€JÁtT¹·,iFß„®Æz[!.kñÊ ‘û¬fVÿTªòf'ÅèÅzR©N½0À¶T»nÈ•ŠKpÚÄ{ ³‚1pZä{Öøºu±Â3'\Ú€ä1 Xµ §;ì¦ð4ñ–•†BÿÔ_ªgKÅ@: ¤c€üv) h7T ×Û.4¨/”Ò}a ºÙÕú”z°k‹o¦YØ“SÃ/cNL˜œ°NírUj§QÒ½oQ‘+H_x”J%,{õñß©cë0ÙFˆâ•øF Z¥Ý˜+ªoÅcÞìÙ4ìäÈÃ'M Û›R|6OD’»qMuŠvÌPŸáìóYp´»ƒÔ§Jô+Gõž=Y„¡j­™2×þѾ =û^Õ‹}ö‹paˆÜE7Ã]Ų²]Ät}¶¯ù üß5V.\Hùðÿ[ð¿‡=øùíÖÔB¢Šbå#q9—ƒ£¥×î…N=5TðÓïÄaŸÜ VI €®gwwD˜†=¤n¢¥*usF=xgZxq½\Èúé;1$±ÌÿMw˜Yqn…ÐL‹Ì¹×§ü¦yÏ£]@çÛÏÅL¨ÏÉÃkŠ4€cA!Áýôk;¹ŽÇ_ýø¿*æâýï‘åûsÌ#äwÅÙÇÿ˹{QRçˆê0~½5sd|žÎI€ºp§Í#É(_»°£eM&‡/‰‹Þ} .'ëBbJ¬jüŒ›õááö¤!ÆÆ;K†(Õ×ðÍÛ¼Å?‰±Û‡‡ªâ™KXB°mè“uO”L‹2¡ÙëPæ—œ[Á ².‡¦]Ä}‘Žm'ý½1þ›“¶‚xD3óE¸FëÝ´q «¨¤ªÓn“†CSøÛ\ß„  ’Kˆ°n㼆¸ÜÞyN\°| cÇ?¿†í|µÔ¤S#I`ÙÇš nø ¨œ)²íC#÷+@d÷l‚ñºSÓ3g UEkÛ9 ³ÁŽ®ö`_Z>Á¼7ü\ïU”0˜5Ÿ‰8˷ɾm§Ú« n gK]ôv0ïðg'lÍ=lWéÂç÷öCdãã~½šmŽìØpbMäø@â›ò›¥uâ%S>Í;—ðŽ-ÞË!ëx9Ølç6 Q•°òãqÜ‹9Í‚¿Tÿ'Fm##ì¹l5È[n«t_ªê ’ž­v®HQr0¤u¥~p³â¢N¶q9ÙÀ1ܹƪÖís*’S%£Úy†ó0Na[]?å.³¸'éÙ¹¬K/ÓKÎT‚ìzáHX è¾ý Yñ>"›Ø ©§¤å\…•äú^®þ›¸FHƒx¥~=_”&)]=NÜÚxÉ&¢¹ŒÀoZr†U–ëËDõ@ ÷¹0”Ò£mSLcHOÜd8†IºŒ±šûðÜ ¯o/M‰m7T'ûÊÛì¼™9_zr=Aøe¢ 1ë•&Á™sQÐD¶ÀŽ›}VJ¼Î:A˜÷Æn$Kíôͬli€+{ó¬> ’ä䈸[/nîÄ©UÇß“ÐÇpšPiåŸÆBü VŠÅª$¾xíî.!ö°^YÎÏÃMû¨-*Ù…a—FÞ Ë½Ç .å¹âíˆü£½}ŽŽb‡¦»ŸóáGræþ(ÍÝ/“mrTœ«=¡¢­ª\-eÇÔ"¥¤7So䥣7~ ÿ]~A–rVÿ¿ ÿ3 Þ±Û6Õ2k”釞Nø¦%FÒÀÕ¯¿¨¼FÕ5ñ6NBPJ‰PœÝNE= `ÞtòÒÚŽÛj.±^¤[RVV×ãA’SÔÓ»ƒr“°fÁ_€?¦¿HîÑ ‰F¼q7¢¼?¨èxy}Š5*+šœAö”¿T—]xCUeÜèþ¯JHšã6¤lÌ;õ¯üïûÙXôÝ|"þàßJÿcÀÜÂþx_oïÈߟ ÌXÙÞCIÊ®]úM³ÀshŸ &ê7)6Ô_0¿A)|çÄ3Ãû>Öx?É»ÇÔ9íµ/î)\™ÞOM0½KOcò/…ìYj-€Î›”tï ›öžÅ]?É£8• Ha×ÛX0r¬çzx½BÐ×F`ëùÉ|°Î-l’”µ‰q‘»FŸàs‘''` 8wl/ò\ŽZqSJݺ×ȨÖáyå‡fì>ΘS>ÄQÌÒ•²<¶èYú~˜.û¦ó÷c àÛ /ä,¼'KŽVäø25ítH¸pJÑ"ëPZœ|Ý@ ¥ 91‡B™*×2ÔÓ#Gê2èã¢Î ´ýMÑAb‰(íésjêºfÆ-p uäÓìµ3U‚} Û¶¦Í‚›ŠEXá³lÆN ÜœîÆáRö–ÿXp„6Œeuœl=\îÅF’¡BOØuBÊ×¢2PŽЇ]kOÄÉ„W=ÿÖQäc› !FÓY/èbájpaJ%÷ ONŽn¥EívP³¸õý©çY÷Ï0BmöVoG“i¯CðºD^çKõKI¼þå”aþh•žäæuÒGw¨™ÃôÇ|#Æ€ŸÆ§“€KZœÉØ“ST±3Ú{›ÆààÙUÃÿÌ^ØhT§8åLP~Rx~KÄËý7¯ØCÌt€œ¸˜m§×2½NóLî•> p×£ÎÙ†úgÈIz9¨ùÈq—©>s0²’hæð:ùY¨q伎¾;QÙ?„4úSNùKÞ å‘: u™+NóÕ·çabkgŠ ¤šwCì¡ô88óðÒiØp¬áÙÇ!È+¾@£‰.ØäüSO«äÕÆm²î4¤éí•çós©RfYÕíßâÆ' ØÙ^¦ù»d`®•ùŽb„!–ÀÁÐÈ4È)â û{šO¨X`²1c½Ì‘¸Wø×2–h²¡p®ÊªDŸw½×­¢3Êx°ž áh¼'3[}ôÜ8Ë.ë[{Âw>tÍžÓ¥gÎÊ”ÒoÆí÷+9‡0gƒLwOqF;ÖdòHGn*HåÇ馟68º9ˆ@®Âê‘´xp¯¯SìŽÖõcåB&ÛYï ÖÃ.£š8L ‚™,%^¿ªNl×ñã÷޼?ÑbàZÉÕræœvîxvºñ ãWöÄеg¸ñÕÈtÅà­ž÷t÷ñWOµ7>rÃUZ<íÂÈ–˜Qæ(8å\@dù¨æ] kß|•½}TÈ~ô¸ìß]‘Ô)Ét ç/o¹­°dʼn4¾´X„ Å[ܤÙê°×1{ûv{D;b6ÌÏQ+Nœ>›wM*‰ˆ××ÙnÖ~ã–b™•RÅ —CÔ§Eƒâ@Ÿw#\ÔT”Îm·Iìå[ ð fQpžNø@ZxaPíLí÷øN‘dÅ·öó u£׊Ö¿;¿çe½ù´óî;Wð:¬4e/7}µÞÈãJ´4JV}<ݤwòÌ1£ÕÂß°¡ÿy6¼e¯;@òš·ùx(louf^ €;Jày×Ñ-bÎnÁWñ åxõ"@D¶õ°âü±RYºÞK€H\ÍB7Ê «\ýª—¦ ±æNægfñ eq©œÎÞ÷ðy8íF3ØÀ¾~Oi¨Ñð›‰:í¦4;³{?KÝÇHæ"lo)¥i2ëidhxIùiG8w>þ¨MéUÐËÅà]Æ·¯.þÅ»õs0îb½Ä9,§|½ÞG ­Ç¹ºÃcC]|¢ÓÚ°µúØ`Œx“GnJ7ŠÞÐÌ3À¤|¡-¡zH3{T}Z¾ê5^œ€/6{ýM¹¶/ú¶ÜK©&éB \é:“ãÌ<óÔé¿qõôòÚQîq@NÉ‘ÏI’ÿÝÎÕÅÿïÄÿ™w2­2NŒ Žó‡›ŽPËl„ ™`ð™Üì­Hµ}\Z+b|/Ýß :0uSkΜf·—&~\÷ˆ!d`©¿‚3—ü3E‘üX×+»¼¿ÿñ—Ÿ·#Ù7Øfn¿€‰ëó‡J5³Ç‹Ü>7KË•ö$ Ÿ•h;að¦íyð¾:¦-xs:džI½4!W~ÏÿU‰(^®ÿ|÷ï?j?ó5Ûø_²µË*Ì©®ÀYq-FÝ€æå,C œòÁWQ'Ow\;m­S›ÀûUÂw8®¼[„ðHa:]»=h½ ꨤþ«oƶ úÑP¨íOzy=*»t#µØ¬3íü=eS—œF»¯·>Ö¤èÕûÀ¾¿®Éƒ£ïõ¾L57sMDbWÈ)pC':Oö˜òøKDO‹öûÄpU Æ ð¥ˆ™D\ZêÁ‡¾Éó< S±ß/¯ŠÁ^Bc°Âkgâz¡—Á=¤Y %¢±µï}©cw“øjâo CˆË‡¬ÉÙBûÙ5¡Ô3_®÷á w¿ »|g„cGðzE¦0²¿k ×[ò–™ÛrÎêÖœd“ô|—?&»f"ÂÌE 3½Cʯඉ´ ž»NUp/ÈÕâã)_Ñ…„}ü›åÝ7¾'duK‹Dþ,þ‹ŒŒWÿ¿ÿÝc„pû.—ûžNOÏë ` 9ª¦K°Üœ`"§Àó⮺ëw›Z‹ÛÆ<¬“BäLÖo|æ‹©L‹CynIù¡cÔð1)õ³1Ñ.ó¯À?ã‹È+žÞrv.éw ç]äݦ1«POé["N€ÕÁù!í¸G<,á×8Œ ÈiVÞ„¾ô'îg¨Í~å¿ÿÏÅ¡ï†sðÿç»ÿYû‰X6¬cÜ÷jYíߨ’bî(xšÐ÷WLXsH[1$Ô;³]ô2¸8æ¡©ËÉÉEÕ ÉÀŠ¥üJ\–š<'wgv“+bO^›ìزñàENàç§ä ±`9m'†«7ÜùZŽéò|2zõ¼1°ˆñóZ<ÍI]ìÁ3Ç‹é>^ö-}}([|•(žÇ´"MöëÂÁè‹0ÑMDnM$È]¨l•Ó_ËÞr(€¡Îň³ ›¾qîþÃÏŽ¼Æ©Û¶± i•=2Œ´T˜­)-BÕV뎓­2Hõjn\zÞOqĈW2æG¸ß„ÜÖÂJà˜_w§|­R¬nï°È 06ž… `‰i{ï»p\7PFƳ< ÈUxgn£†°É Äû:úÅ PÁbŒ7h\]6¯<Æs #âúxúo ³{W¥%l9t`’Q:úŸ»mŽ|ÌÂúp“h³HÍû¾¿Aü(`Ëb¤˜e®_ööУ´LV¼ó\ü~²ù1ƒîKÞ%=¿ð¹Ì*qf†xä Oʇ+ÛÍ/1^~Â2*òyé­fœðëEoµübÕ/×zÖñÍ£HMϦRz´xtÐr¾`F‚‰.‚‰©š3r°¨Â =AŽ jVç5yˆ±S¦W%Ø"\ø£˜gM^}¬Óí¹ð:•ÂÍô5›â@ˆ­˜žŸTMƒ=[ ÓÍÈ=\…l7»£ñÃp&Õ]6²´Ba°ˆU—à{ƒ¬"þ´ªP”¿=ø\Æ k}Hv,pœ§u “=ëÌëf¥THñíκ›NAr›÷Ãé®ÅqçÑ“[Ô^Ÿõ#©o™½Vaø4s¡%Ãa§vîý%é4sÅ*Ïem Û¦¯ª°Í2ì¸ãó“ÕbâM¯ÌCÃû,Îþ4þkïI®"þ;þ·ìÊž4xš”¸dýíÝ•h?²Ûˆê9€Pñ‡6w+æC µ"ú·aŸ!ÈïÔ’ÙÙÞER=‡[ÏiÖ%h%Ü|„kÈ ‘w>> öüKð–¤)M‚·º'o¨áÌô¯©<;{¯›îªŸN¼'œÛv XUÏ")ÍßjOœ™à¦Ê Y¤>îhô(çÿWÅܼþùîßßÍx[DGrÚg´ïÃñ.+gº»—¸&ªË2ƒ¼f7;`1M9lP’Û2öšƒùYæ|'ý˜wNÜÇ®ŠÆÅÃÅ–‰‰ CÚÆ >¾NIät/ÃÓ÷µ»Øúì?<‚”3 3Apì³Í!¬:Ò~Èõ ’©!RÏ™‰©|»¡ ¾/X–×ÿýu¸¹¿èB€O[ç™E¹j¢C¸À…ÀHQ̦¹'ßm}Á­/–´lãÙý`üF’Õ˜ãÑQM“èþ]úsâü§hGz`°„H÷7L!àWqÝO»4I¾Ðf àIH ¦[ü½®³>ú"ÔÝN©ó  –Êí!hŒ®?\E"”böm=D׬›Gv<½s ±ÅÚþè@ülñ)¸Û¶]‡ÆOOº¦Äi×èRÕßàQ¾{,=:ÿYÞ—raA6q'¸pËŠ(œÄCùáuà Çî¹ßxCÝÑyþÓþ¡/ ì1:“GÝç§j¿­ñþ¹ Þ’]GIŽâbÀõ©µ8us'B·í·|“ÕÃÿS¨EÜb–§Iy>¬ùX»< ´/õ}+·ØmT ?"N4{-|´Éf͆Aì‡@/ /0lƒs[Ãf>)X©G_Ôð#›žÞ8­³ÿMÀ‡¬¡€™ŸŽD>MCéæãz­Û;†Ï3M& %6 rÿ<þx¯UÃÿoÈÿôÞÅퟃÛíx·+¯‹†›¯'ñ@ÎЃ‡»Rl¹Æ<Ê Àõw!þ净+`i_5/Xd#gÝí2>d|ØÞZìýKðâŒû¶Éß!àðý¨sÖšÄÚ =j‡W]:I]XcÉ–W£kò{mkfÁ‘„v@Œ/³ÆB1¿žõAq’Íßùo¶ ¡ãòsÕè?öÿß\~ú‹}`°á9Íè—­á'8Ôånõ¿™õß °t’Í­ô`·3Àú¤Œø\à)Ê»¢qG• µ¥Ò…½oAc{g¡ÿ‰ÎÏS” [ý .ôï¢À.ÈXH&vm1 íÒ:‰4ô¸b·[ɤÙO€ 'ÕîF¥˜µ){]4½MÇÞ<4ýçÐÕ⹄eV;xYzž †ÛÕ|Mœû¶Ë°ÜÞ…<ð©<ÔЊž²¡f»æð‰·a¼÷™6¹?óBvf§EpâyJJ%¸<>Mßš­¨h1Þ¬ïþÜN "»o7¸vðÆûVnRŸØiõ¤Ã¶†“™ŽË¹"%*Áoþn„:m™œ¡œ€ÚÖ(öš,˜ª=ª'Kºý±RO‚Áì’%þ16öäp{ùòm™þÍäçÏ¡ÙJ÷­ÈqeSo|Ó‘*y;öp yPÚ&˜Í¾ I9¶%ÍyÚ&ÜHÛ<' äàî ]üÖ±Z­_Ö¶ÞZèÙ¡èñ`ëû–od¼ôZD~s')Ú´CózjUkŸkgkß3_­%U‡ôý}mmªÜeé´%ÚÅëä0Lí~æ9½¸‰ÍN3c'é‰côg"—]…L≠gÊ©*k?/Š icµpG»QHiþšø6öH¨”u8Ù-}1ܸM9"ç¢"€Fá*áÿÙ‰Õ´ÖžPK…ÁµÊŸÂûtqþ¢@a3ÜËc>tBÛÉP8ر˜ñšf.CO‘î'õ·Æ“v?Ý ;¿Ú;‚ZøŽµ¦ÛÀiû‚ÖÐ^ ÜÆª*À¬‰þ®gx9ÁWjÊ„sïBw‰§ë.kªn3ÚØÒ*Qº¥ÕÂÿ¤–ßDà&*>ˆt6z¿6_+;‰t4wǵR[_5„OyE)§hmG°NkÚmž²§€™H4ÓÛߌûóý%øã¸oWll”k~tMgTÉЉ¿XÍaÜ%»EB!  ìÒž \#}>Æy¤>kH™¿`ÊLŽ»¨{ǽxÿÕEΘ˜~øï?n^ÿþoùüÿ5Ûxü­= `3Æ\i$#Ê [_ìðÙÍ¢ÛŒÛ>ðK•÷ÊÎhìªk³ìò[ÚGš¦ø˜S÷Áï¶H”®ª¯ƒîºk=;ÏH{3H„¿Dç„åy™î>Âiº©aS0˜žânúpêËñÑ‚ÆÇèó?ÑÆ‚ûK•\p¥@ú×vŒBF³Ow=l yï¦Ñ`­qx38Öµ‘>yÜ=$ñð¶øÔt “×ôؽ5'Ïû÷¿ÒYëÝyíÅc×<©N·{{ŸÊ:Z^«‘ «®ÞËyfWgý»Wšz20Îç+ÁHßÕpª‘ˆÕÁ¿a‡ÇP g"ð+r@g‰Ýä²»F™šÞ¤îqy1nžŠkŸ1CÉáÎ_ ôpêµ¾GHÔ‘BïÀA>Q‚]ï8,Ƚ¬?º1ì@÷í퀅‰Z>&ëÔù+Û‘«š¦’_>írÔº ïÅ/P}£Ë©ø/ÂÿïÊÿ5߈6>8j“è_Ó[Ÿ{°¡Â0‰^ÔÿÐýÆÄðŸ¦Ö1¿uišmƒmE}šYwuLbýZY“‡8d÷Uý5ø[&ؤ°ºÌa‰oic´gýÖ?Qé3”…ùp¤¶Æù8ÿóÝ¿¿©aœc“Žuo³½t{d.SÍÄEŒEÐ;<´*jÕ­M}€¼jl²Eæ–ÚÐ[»ET¹©Dµ÷‚'>1õpMG|0@ )–Øä¬ƒc׎(ˆ ¢‰009Ú$©=åVzläàõld0 ßbmºrÉUÚ=އÆë.@ùÍê"›?ñ /OÛ£L­ùÙ;á /˜Å¶Â׿f¢¾ÖËD£;Ÿ¿—N–à3tÿÀqn¦˜P}¹Qk—¶0ðJþ<×›LM  ™"Ld0á™›ô@òŒªœO¹¡0Z÷¼?ÌgÁ®îÝ­X+ü&sgcîÕËk7|5Šñ°âhPV‚²-Iy/¸"ƒ”üA(µjzìŒW=!9ËûD†sX¡¬þƒ™g¾pbÝQâ#}î'cü_pðŽ+Ǽ–Â[-NùÒ¯•‘›99H\ÿ ¾ùÒRO–çîļãÌ?“e`Ͷnœ‰¦ìž+ñ¶@®þ5 ‰/§oζ¿æ{÷¤±J>Øïl¶—ûȆôþ~-Ÿ¦«oR7©í“¬{Z1¨Mìyu6°+àk$0û_j¼ÈaóИ5ÌÞ?Ý÷ˆ¾Ò½ãY¾ò¬¿›8l1Þ=Ì‘Î!2ÚÙ!5çSvL;ãªå"]ü>ß}Ø(æÞ‡úì”ZVö— p°¥ƒ%úÙ!N‘Æ9®ÐZ^§p§571a;…ˆò×Aƒ¸>ï½GÜäO8zkKô1*ìÄ­p³xãQ©€†nºgwvÝ0È5âœÈÐÚ¤BØŒ™ÚòAaœó<ølÙ^Es¯_àS@'m†`|ïéP½BMÛî[ýÅÞItÐw¯—Å×ÉΊ âø“2ä€è>zp%ªÔ@Äü§;Wl£¿…Ì®þ ×½PJ‰ñiŒÇÑÁì>hñᾡà¸M¤OLñtÜm_ƒxu¼û†·ØÅp çZ oÐàTUãµØ0³×÷ÚíE-69Þw|*(DKI¢îÛ¯÷=þ{ðÿÛò¿Õ»òæMÿ­0Χ‘V>—')¢vqo›Æ5PV{÷©#bó—Úó\ÍÅÀNî?ZXK]œ›ƒÑ•º^a—dœá÷×àïn¹¦DóuÄô6ÖGj—@ûË‘(FûÀxߣ~H ×¶lmt÷Ê?)#-ØÏŸ’Á§¸– Ö=Ÿn^ôžßn„Ÿ}u8"ÿ)ÿÿsŠZ?Gî¾_b.héfð³‹85Å œA¯Ü=OBH`ÕyøV×éY¥ƒósï'¯™Šþ“êçcáØj®2ƨù+¨&ÄYŸä¢%½öµ’¿Ç{¸Ÿ\œÎÖß/Z¿#ÜdêN±Õѹx˜ôgÕö‰‚Ûç;7õŠß9Ю¹?‚ùB6–:o˜uÔ‹/1Û¬À…!y¼†²ì˜±õ»DHo)ï]ÑóüÊ¡Á­£a»¾nyòÛ®,à#ZÚI0‡i©†#´VP×¼• šÆšKàt#Fݯ´³ñg¯*å:qýñÏÖ¥ªÞ5.ˆNiht ãipðNçÁʉc›—Ò¦ÔxºjaÜLÀÏÊ•uRëÓÙAe³‡d[?Í-›nÝÄ6ñPQ.î&ÓYÈU–Ð(8­ìQ¨^‰èð€)åF0ÐyÜËk¬Ó«×—¤S¿ ÷s±÷ñ ³Nò1ÈoX#ùFUœ5g}ïNÁ@Ïö'8¼ÓlËþøM1 Ø{MìçG÷ö^31¯ñ×}.R'®Ød¹1zŽô…‡¾Ç>–ï87xÝ®Æ%š1¿#–Ý¡ýÈÄUk±öh°DYðÁ<:ÌšÄ ‡K„Ê€kB@]T R Õ.p†“ž nÓ>²†¾½â>~´,«ªíÉ¥½æ¥ZÁ¡àŸùìéÊÙÇ2²ã¥hͱ®O³ÎkžÎ]»Ë‚‡ý1A7Á¶~£ð6·L½…ÝïÉ©e\² Å¹ŸóÎÒÕ˜¤÷‘¯@3níî `5ï¼\ ïò€_°±°üî©è—†¹F¡b™< +.y0T(qÇË:R­·"hùOþ‹ðG¢ä.cÃa*‹lÿjo¨g¾3á¡Wš~¤xÖ»ƒÖ¹IŒ †Oñ…ÓXA¾vÐìTÅþ³@°}HjXç‰òÏoˆì¢îg÷<Ýþùîß_c>ÿ÷6ÿ7Ó/vƒäÂÅ3·®t-¬Ý‰k¾õ `më½ò=>ûÚbiœ#©ûÙv¸U™ù°U¾¬¹nÒ] ȳ¡Þ 8á[—Q'ÌúÜ(û‡,MÁa¾o×ÐköC6RáU|—=ŸúÒT}Y‚AELCÍlgŽÎ1[€Ì5MQ ¶”g½ÇG³„ÀÈe)Ÿä䚯šö÷ð!™Kä5糟×d'L½Ê‡Æ¤=ò›™áf×\Üá­Þ9Gü¡ ¶¾ú^½ìÎö¿;/¶L;K¨;ÄÒkÕš‹àÛBNž¤ªâCp™œùLˆ6½¤¡tŸ L¶ï\‚(a«>ÈÓ"€ªÒ:ÑÛ5š1r™ÇK— 7ï¢yÆ·_o‡•VnÍ fýºÇ@f ׎!MåÃÀÆHm«¦ˆTØ@ü›gxžã øèA€2 ¨ m(U>qú3ØÇ±øÃ5 5ÓßÚ·}aK$[ÝÙ¿!í‘åŽËóTœ¡Ía`áÁL¼r€/9fë;ü Ui.후ŸÇ?ë \stf~µHØk9r¥ÑkC#©æ7|ÔnÙ„ûŠ÷]ëtòeÙׯk)6¡%ÈÚΠK ÜF¸ªïöL’È~ÝË9mŽ&£ °N7`>3óUý%‰/æ¡`Œäy°—æ 7´\£:° LƒztñY‚äR¯QÀLqÇýü«=ˆû*&ñÕnwmØzFÀGÍõnm\ .+ýe‰ß+Ù´È‹´½nªyÛ‡`£Çœ¤úyü=Š ·yrã"d O ³[îø Z7lŠŸò¸ú¾{W1“jFq¨áV°˜¯Ãf+>ÈŸ1^„ÍwÔJkŠyÛëíð·ÜfÙºu¡Ãº ÎÕ7lèÝÓœY°«(ñ#cÍàTõ›çS^³o}ÿŒêšs$9Ûþ¿ÿ¿7ÿ¥Ë°Ñ§Â¨ê{º(rü€m$ìAv ›PÚ×>±¹¶¢ 6î–‡XÑÅ'`…Iå>‹ëÞ(Sò§aN7a<™jû‹ð¿†L)#_‹€ÇªHhÖ5öð°vâA‹ç˜i/ ©8U q«——Ö@VÒ™ÐF¼ØŒùÐ]qâ}XÛÊ?Ùû¿ÿϰÿ_ ëðGÿ;šì¿Áê1G`4åÑî%"¤ Q¯)Áoà¡ä[²:³¿ÊncˆXCE.[ÍÂB0 õH…í”yÑÇ–L5'zßLõo*BvR‹ ÄŽÛ+Y¿m0ô¶‹ØãޏQ/¯6’]Ò6UT÷ {h.àÙü;trÞ‰‚g.C€’ö›ƒ :„Ã’z¢Ô¹¼ŸÄs,”Ü;4`FwÓuè‰Ñù vEù7C¦®`&¼|¹¶#‚Õ¶7ià«}h9{EÙåĘÐuÝÊ;r@Ü’FLM/ù#àü‰¼·—‚ëKlßÞôvÖ©_tÄ&–ß¾!2òp“(Þüöâ ØÙ†%êù|“ðЫLÓMvqé>j þ|òÌ2÷êŒ\ýpkÍ7dö±~ÙÛêϾ —+ùÖRø†yÄæ…ðÞ†A…s®á ¸õ·GGÄ&™ÝæTеŸh„}M`Êooë[φz>´ðûj¼rvöhú1*ÔL†ʜX?Í}6Œ-Cûƒ™;·ð¼w2½Jöïó—0¦ZL²fûÀœÍ-êN1wÙ<î Ô<t_U¨Žº¾8¨¬ƒ¿Gìn‰6Б{œøYÚM!`úâ4¸Ãh÷!äVÅ"Ï3üÌtPª÷Ë›ë"áåBz8ÁW}ç7 F?ÎXxÇOö©ó—ûIü¿³¾„u¢bY ÙŸ×Þá£Gø{kÐrUõéˆs£šÿy—©L.½­N^á+ýVF‹#üÖå—Nè/Áñüã€Ø$à—ïüþÚ§ß]XZ“~ñˆ6tŽúÑÿë˜~=_ÕrCtþNÑ+·W~ãü¯~ÀW½ Ãã€X àˆ84Ç£K†#`âã.†ˆ®ÚO@ÐU  ŸxëDô€†„—‹Ç‘Ðiù//-ŽËËŠ~ÂqD›¸å~èúc‰¨[ïçAö/| üXœK°?Þ<¯TŽà•Êðú¬ï3ZâÊÙ÷–p%æ;Eò nèu»šø—¬à%.»ýÞuƒN]PôteZhŸ_º cÅ-7t \n¸âvt-¿wFüÈ?ü XúDìr'ô–ˆâÎ ];z –(þ@@·|Àáû "ðÊsÀÒäO¿üÇô÷Ê6$|¿±âÅÿ·Mùû­o“ˆüºÁQüÑÎèdð>þxø¥7þÀ¶ñÿBÀ¹ýQü³ÑÉþÏÀÿ¿›ÿed<‚!}Ÿ5Ö9= [uyG¡0t_áÑ9Ñy‘àû„WðG) 8Ü £—wæò#áp+¡{ËGù?Ž˜?xÑE‡å}u "ÌSrUX¢ü-ô":Üåɬ`‹Ã–aEGXšüoü_û'üÿ§ ùƒëü?fT‘e lX[?û¤ä€åýî!_¿ev´YCº÷WDYÞ±ø_$ÝQ +rY4£¿‹Ï¿ÊÀ‡ÿøã‡|þRœ]ÜÅœ9ðÅøUàW©øÞfÙ£s°ÿ¯ÞVäÅ>î‡r?<þ7úÞ§œ÷CІN1¿©äï†ó›r®4ôuFð»r}÷¸2-äWŠ£”?]‰Ç’–‡*† p‰ -3–EÓ1þ¨K?ê|YgÑ@®<âJ`ÇPÑXŽŠ€÷ò4xù‘°¤å„»¾üJÔÑe¨c9TéÁ9ô—hâëŽ(—ãðz9¿›ðï熧 p# ôi%¯ÀºŠøçD¢r‚qŠ^Ž'Ëø{°¬@hä^N|PËòôýâ÷Ø%¡ÑÙ>ÖeiŒ'9Í”úrt_7´PÈò@—À ™â°’]ü¸`â߇‚ªôXµÜ]´ ºþ€Uüsð/ûÑïûfFp.( ¾ïVïý/øõ°’ÁgáPÿáÑ;`Ùn%„®á×HöÃúYéã_¸œ©Â\lµñÿoçxºµÐmµœè ø£;ì{B°ÝWÖûG.°¼ ËH ø—3Wäûš-ÓG\ÞŠÈJú‰N§ðŸÇ¿ GDœÂH+EIdǸFâNÝÆàÏg­ÈÌ<ç×Ê4ÛQüŸøÿOüÿûÙíÊ–i¼¬£?RyÄÃÉ ñbž°"âl¹ÍŠrÿ(¸ð¿ÖèöE7’·*ꢼBW_Ìò”þ–þÿ&H¿$ð?òƒ%ègŒkô÷›X‡(ò¯­Müá·BâW¡‚ÿ*ü*;¿ôûåð»jÀOýjäiÁ9Äý¢ó¿O·á×!/SííëLþ%fÀï ø¥.T*'/×åËóE#Ãò]oln%@иƒ®"n%Îã¿–õ’„òß)}Ær¹±R¡úºE—«4û%/_!ò²Îú.ç+am½ÛÏ5z¥bÇc"ý­•ˆ³|mþ[¹ž!¨ ?'4h¬xÀaÑì Å¥V%ü’\¬ÔjËiþ—WˆŸòŸ1éÿ¥î(þ¿¼!Xycó¯ûñÇ-,¿?|åÕïÍGñÿ·áøü:ÆìQú ü+ˆË)˜S䟀ÿ߀ÿ¹h*0Žqßk~4×\I+ùú÷\`™‰h^´\îû øcIèÜWZ/7Dƒÿ2 ‘ïïü¢üÿÓÞµp·Q%é?GI`xå; 9dHâø%[¶¬W?î½Ý­§eËOÙ “ÀîÀ2, Ã@ÂÛúªî½Ý­øœÝkq|Ž5ƒ"K­Vw×­×W_UŸƒüŸÓÑ•C•âúýÚ ³‘tïïlêʨÁ ÙpšÏȾ¢3nœ¢ÿ3z\ºÿ ñ8-ˆy½ð‚ˆuPùsD™Ü(•åC.«²K %çpߺÆç€gÛ‹ŸÒ—¶Ýê&3TŒÍ%üÏ?^+S¦¡®‡ø¤ÝÜÎÃ]YŸEÖN/ðÕ 5r;‰“ ±}*ô—›¼¨~ôcO’“¥ƒÿÍíºß¿EO“(ì.ï¦>ŸÉ3 k½œ ‹'+Ã(¿ªnvà³(·­‘+¤¤"¬ˆ'ÎâC²¦’mPþ›Å¦žôÉÉéÚ62}ÚJ ²=‘ú —Î1ÓìW°òšÎ_캩 “F0ºAn®aaâÀT\Ð^~ [ýêGz÷k$A×…ðØÏLþß {vJN7» ñÒbĸŒ‘µEF•8ûTWClü)xŠ“¬N]äO.™>ûsèü@À•NIþõ·Ð¿A†Æ±‚àd¿«7g/½_F´¬y£6ÒVFn¡Ú=qpçÝ bùÓËÚ–Mü².lhˆ0O鳕­3Èÿðkò€êÿù_ýÒc?/íÁÏsÎÏK¿¥”€ˆä±êÈ»Cþ;v¤1’²KG‚…¶j)úýå¿KÊ‘ª µ™èPgQRëgæøê/™~íybæ'‚›Å…EA_Ë+R¡ W½yŠþÏäqéÿÇÇP›éR¬¥ HJÐ^Ÿ¯jýÕvé–Õî°º›X[LL1¬Kë.•¼ Bä¼ñ®Ö“Çi®k󇉄ÀÅHßEñåTJiQöê6Y˜õn¿ðIÁJLƒ€ü·U쬡†E#îÐÚiÕŒ?]|ÊGµ8yÿ->Yk76)8ßeÌ7tá=Þ ßúÐ?ò…É9vò=sÇBXIºsav‡,’|a Šª£EõH|a¤ ÈU:J7€ÿgZðÊP®œÈ™6R.êÕ²œîmîÁÐN:…s»쥮Vwõ­Eý mm®ýbäbÎLþ#Ó{jÈŸÎŽƒQ `Æì§ùdonúTámz±¶M‡²Æ\…ä]I ¸ïÖVœ¥€¸¢n.É!ÿaðc6ý窶aè_2;E¡Yt{næòæ _® ÄÆ—YÊåD4/P×Fåå©V·`¯ó^¬üPt ÿeÌé,òÿn‡òõ™Ëÿ¢èÿsü˜!ù3þ/5*ZØ7›áВĦPëæHk» ˆ%šauaå`YÅ8t\;ù¿À!š¨™vR`Ž«;JŸõ†»‰¾ò‹¡´œÁ7ô½-ª>1­sk®¬ÿ3B.Ýÿïú8C0(¸ÍeÀ0‰6µ~´×†³DèU+îA%$ÓõãÜM*°ÑŸ*Z¿éŽ ÿ;ºê)—Ñ%›ÏÇËû…¸¸@¼dÄ*Ä+;©|¸Þí•7vû.fx¿9ù’ôpñ¨ô3åâoa?ËÝëVÜ·çQ3åÕµ_á®ƇåˆùbFª6 À¨Œü5åüÉ­cB@˜´û´uœqjb ͳ¸§¹ Ù›!OˆÓùCÆÿÉšPÌð'Ö,TøüÕÇô[oéª?u2Å, L‚7ÁÓ¢ThO!ÉHg&ÿ7`pÀBõÉôQâñ #úHx4°fF”ž¤Ë#ò7Þϳ‡×fr`âù¶Ša´º“q4¡Ö;}£%ˆY €]áØ€ìgâ$zcÖò¦óš€[²*®mñµW©Øîü{öËhÞuy)ŸMÇF/íkS®I(3äÿ¶\„g“ÿ“žÒ•YËÿÂèÿÃ/i-[ü™4½Ëž¥Í)+(¬+ZŠäßE„ŠŸ5“"Pæ $´xõ•óÿotŒXæ$°‰î|¡Cu­óLÅ¡êS²AY³¡[{Û¢©]üFYÿÿÞãô‰òÒÿ_˜G)PA’0Ö št}ùžÖÇÃÌÄ.Cc6L\!ãÿk—(®»!U[ý@ë/&¶š¨­Š7ô þ¿d>]2`ü1µW»cSÐóØïQ¾âë…n¤¸«{ð»Éò8³±µÛ·µE9%Èí§ùî·Ûà)»Íìu(„éîÈè»L]fî²ÅIá<èÕõ'}DN÷•Ñ4òØK‡@"‹5¡5žL È‘‘=NQšCQ;ÂÆXR vþ±±9?òàÿ!Œ”1{q»c/S¼JA¿®p‚ »=­Þ|jOCN«äªD2-JÖž’ñ‚9'·:#ùÿuâjñZÈü?³È<ë 'ðY¢™ßRû¥= Eò÷œ~-}ñx“Ü9 @æ W÷6]w,¶‚:¹&c솜éÁ"k¾5[ù“5= E ó§9~p‰_19U­þ4P­–¾ ·Ç¢Þð† {g”ÿó4R³•ÿEÒÿ¿“ü ø?/ÀŒ#G^}ª3€äÏ¡ÉÄl# PFø´‹«ç!ÿîDÀqL°V$£Âùƒž‰ÞûeEn}Ñ6œ‘6Kˆuû­¢þÿ¾â÷¸LÿçÇY]Œ"U_š DÙu»r›>ùfÔ6‚|.ñ‘!Ž—R¯öbQµËËJ)8¦Ì ¤¼T—ÇiñOî–Ì@ñ=Ukz^ÏŠç_)GöÎh´Qà> øMã„Ó•\9Ϋ‚¨´¶¿\®oYŽòÒ™/Eëk_Ø@rU”ž’ž çOUÆ™ivP&e‘e8!â’õAê«sY[QSyÑUè½€ô* ûà0ÿvƒV­×žù«Ð6mN&L¯ Y“._3Útåcýð/ûóOÏHþRXå\Û†jyœ0‹LI`1|pÙ*EÒgÆ™½æN¬ò7Ž(AjÐi© i@œO»Ý{Pâ<åO¡Ë~`¹€B¹ï‡³”ÿÊc{ýÉ–¨€“óq¦[Ý\'òÆ6ü jÈ”¤7;•åôOíž/þÚ¯\;«ü?ÒÑLå±ôÿ Éß6–ÚV9h"&JüÜÝGY4"wJã‘î+:h®ƒÏ„£¢Gÿ«.‡üÅá):Ð86Åàè0ìÑê¾ò¨õM„,¤‡Ë•QJÒ$½ú¡×ÿ™¸íK÷ÿ»?fD´Úî~ö$`Ôܘ«IñÏò‚@Ÿ%†ó€`cŒÀW8?Ük-6\Åó·lï_ÝvÉ£5E;΋ÿQïê¢Åõ:µ¼Ÿ.ï¤%(‡äýù7AÃ!§¿b-ÐZùb EãhqrzàïLE³yû½¸SÛ+˜„b¶ð2þÇ»½{÷ñƒYÌãÄ%Й7¤¤—­üd®=O¢ô/F“ý|ØhYµSâ’ò§¥C‰h–  ÜW“”Y…A-ð‚$ô³»7I ܡſ óa«ë'r>¹e˜Í¸w‰Òâ?hýÏ¡bFÞ äß'ù»,Þõ05acÛgú¶s¬ÀþÓ¾ÓŸ‹jmì’a]<äÄ_¶f/­€–ùr&Ä,€ª Ö‘ú¾Ë@[ܽ=;ù?M¦ _·¦é÷͉_§%¿¤ e”Eðש̼rÝàù“Ëy•Ó™øîóËÿYgfò¿€úÿÄó& áØR¹æÈa£¨”ãIüIògÅåÉàù$Œ\9ù?¦|?c1­ôÅ *ã!dW_ ¬Ã¼ÌD"ç¹ÆÓÒBªfýŸ…ß¾tÿçðPg¾ä¼¨x#…W.ö³‘õ\ÝÊê½ §l‰¦Böõó™›áÈ"³Ø\ÌŸ«u!’fÓ¼ð¸¤âÓПÑEË@ÿÜ?j¼ÿÝHOç|¹/°9 j äOfQU‡‚Ѳ¯þôh„,‚Žó2LáY€‚à¯öÒÀƒýØÙ„8LRÚ:åÂ>]¤¬ŒQ«v{ ‚*C¾*½€óGíŽD†Yƒ&~­¼»,Quן¿^8.\V>Vn+°o®å½›(ÏHþßdïšÞБÃð1É¿Äúçn+X{2¿”2Yþ(]6£‘sÕâ¾eªŸ¤±[íl!dqÅG‰5qüTžÂV°€ÿSœBò{Vò°YÊKeŸÛjµ7Py»€ÝŒ_QîøR[ï•äÝ Äõ‚-L¦ÜžLzeä!õÿ‡-™Åk$L„<‚ lHVcŠ ZCei(ô­ê°+ÑµÂØ:éöÇ“s‘?¦©L?Rpuß0ÝCFæþÂ(†+š‘ÖµSȑۣÚ'¨Tí=Èÿ_såÇ¥ÿ?ÇÙ^¦’iFªòñ^…,änv™£mXÿ57mEŸ<™Sp.ÀÜlµFväèQZÿË£?ÔÂ~¦§?õá¿iÙ• ¶®÷;§Äüy9Ó2js•nÿ”¢ë—žòÂ÷žÇHX.œ&´´\ Ž×ÇÚÙz7Zš˜¼|)¯<Ãdæ±£Q–@¦hþ«×ö¥ÏµÌ1ÜþïˆgpîaVÝQ8FŒô2%‰¿RÒ2ë×OtÑĵâ³@ïOGÕìû³öÙ\Ò¡ÏümýÕÑLäÿù£T¹,>'‡I/ìv±G ¸AÀZ¶‘7¥âß^9`'o Ή½uñ¶œÏÓ“| vþ`ö‹üºb?Á¾å Ê"þ¯ã¹‰ºÿÉläó©öJ;ãïÿ¬¯¤ù’u"òž;~)ÆÇÕ1¯ÿ<‹,åήTLiþ«#ÿ‹ªÿ'vX#XQ®!P:n¥Ém‡i8ÜI)÷ÒÄõòHnÄ¡õwÎGþ/4÷ +&±üéQ ùÕeh‹~Y@'mPðpÿ–þêøÌNäÒý_܇ÒWþ9äA–e~vWŠˆ~i©ð ,j[ï=vCÛÚÍ‘’^ ™¶V‡äÿ=›Ùû:ŸCøb™ÍåæjPVçVs”ÚOÔÒ^Zغ÷è?¹&ŵ^O¯ ²B€_LNÉæyäè •ø>M-«…CŸîñAs3±æÌî1¾ñ‚{qCÿpל á µ×Õq¼4‘ö”óÑÓÇ#bJï•mìãñ@ŠcT[³XÏO(ý×Ò¨9 ¥ ŸñÖuØQüÂ$y2AO·uä¸ÃùÏéÏêvnr§R"c…‘°3‘ÿ#™íkøüݨ8&ð¡IÉ ]8Š£ÿ™ßp‰^µš˜›Â |¼´‡ìÒ´g˜Êo7æ¶6ɧßK»ÝèõÉ?‘ñ@hæÆOd:§þË €ÀŽ>çõX]üOŠ®)W.ù»:Ž—Êy±]˜`Iœ‚ŒÇ2ý¬)$¹äΕñø/ïì}uäqõ<:^(ÌÄp?Q(np½pÀ“~Ý@6Ñ ÂO*¤•T½~>òÿFgùD1òý·uAîKt0ÿ"—ÕíDñ•µC<.¦™AÌŠzU¿8³ï¾ìý;§‡šÅUMë“ ñ.Ùö¿5¾°„Nh¡r!86+Ÿ~—%Ó{µNÏOKxð÷—ùèSÍ8ºE[äW|1PPb¥«‡ºh‹§ ‚å2ŸªluuiŽxIÙ}B—›‡ù‰üÊþ}R´ý%¶[/ïJ•üuÜ€Goçqý¤£¬-Jú‡å`Î:ÕLíŒ á_æØ"Q­ì³æò¶¸ÞÝÚ>«rhd° €ØÔ‡ÿ‡¹9)yMÌNN+*öüßúÉIg0dìw2uEqþ³ÿW‡‚4 ûÏȆB”ér¿MÿÙix.@$£g¤±ä¯´\­Zk‡½¬ÀÝü‡·8€F ûé2÷ ,N×ù-S@Ù» €‹@òÇ… ®ÏBþ?g…eVÎþ4°ÛíMS®ù›™zk?ÐÎr‚Nò×} ¬1ð¦Äå_{eä‘õÿ«#™–N#OôÑÆónL’ü+ˆ. ÉßÐÖÌ.áÆÞ«ç$™ÄP"?µ+‡x´o˜ZzQ;£/¦i'€ü0ã¿Àw ÍÕ“étG¦ ÆÉúÈAXü³ºëN«ìÖ?8»üÆì¦/ÇrƒmÈÐÞG«µ^'á„GvE‘íFNÙ°‚  ÂÅIjïrU ùó¬5[2¹`4£ñÊö?ét†ü10åÌ3_@žìH™¿YBåü‘LHUÕ›g—oO¿düm˜^¯î°ü»þ|tA}¦èªì&îõdx¤ßZfÄÈ\XÑ sýU‘ÿÅÖÿŸQ&³#„Y"c”–X`}“ÕúH Ý!E_kàìLC¡<—ž“ü“!™pñ|¸¦ÕÜæÒãú(.Æ73Àú§%¼º'¡ˆŸldê“>cpéþ/øCݹ­ÿ¶/eÀÐ,Üú©[¸É—–[ƒD+}¿å&€Q®ìËØŒhî6zò"‹µóH×f!ÑßÓ³ `žmm¶¶ó™õ¼º™zw*\ˆ¢sƒ 7Á›öΨ~£ÜØ”S‚ÅýÄíóÎÝŸ³Â†>W÷ZIG2‡úâQåÀ™!z¿ý¶tòݸ´½ D—ucÈ•ÃÅ +$»x4^!B_Û22î–{­ :;æ9cÕa>ŒÌSgóGÀí_û¹ús¡‡ ¢ÕG]Ë­½ø¹€™rQ°¡~jÙ»g”ÿ·;<óWšü5sý ½€2€¼ûQÊÐ#<·#S¾)0Éß1ömÚ^¦âⓦfUjí×íÊDn¤šªŸø»ÿ¤º08,áÿ‹û‚0{øÎí3Ë߀õ:U´óõ!vÉGÙs‘WØ2§­V®Ýk¦Êxüoa¸½Û†þ¹þäÕÿ…×ÜØæé¿àõ%ì/›¦Ë½€\L/é$î6Éw@ÀWZ7ÎIþ¿$†{‹"‹´úŠ—5 £BK#Ÿ5 ²:P…¶Ü@Sn¦ÂÚ*Òü,a\xœì½TUɶ.LQ’"J‘¨‚‚ˆJVA2H 9gv˜;s–Œ’3E1"A‰"JR¢ÿÂî>ç¿oÜwîéî;†gôë©c±ÖªªYUó›s~U¬½6$€ˆŸG,üQqó‰#üáÆËŸǸ?­ÂTblÏp<À·y»«n±&£Uoú¾Íäªöqo`åÄákèf’dnèCeW•Ù ©§q€MÌBÍŽddŒ\{õÖJ|½'øƒH˜˜±™K´÷okÂ×E–dºÖ¡³Šlt¦Š €(¥¾¤½n·‚uÃî /ó; ¶œ³›ê¹˜&çn×G÷b*CÕ®Ö òÀ3 <5k–5æ"Hñ“+O±ÿ:ëê–þwèø¹ÂP¨{œé€-ñ6âZ+l¸ålÓkÍÚùö¤ì;çÒjbšÎ¯»3»õb7©ÉÕ  8`þ‰Í8,†½ó¡¼YÂÞçiLk’B¦Êàô凇k•nÓäÇS¡PØÕÒ€Òξpˆ:ãþ:Wƒ3©Ó¬G–®{Ç'ïêâ}˜DWüJ´ÇC“Óu¾)¤Aîõ1Q½÷ïÖ¡œVêÏVvÑñ—rØ$jK=¸F·§ýì;5}£,Ë#_‡¸ß {ù+ؽÊ5R.ÆîÓui9´o7ÙV©p`kèïšgò8—C쿆§,õyýFÐçÞ"¾znxX·ws<  ¢D¹¾žm…éê<õ€¿Ô¶¹X:¾k¢W­õ X’%‘Æ ) LÁž;nuº 0?SFוå]øSø³œìÂÒ§ÖzÜŽ‘¯„1 Í€òW1æŠLzàpƘ c/þVA"•ã±=V1°‡_ðÀ¾{g¤Cá!1ö'O 䵚Ñ©6XS°H$ Fú'«ëCæß'á pjÕÚ*_ (FŸlˆ;î?–¯Â©írc'¸ëú6ûç“2жAƒJ¨â¯u‘§Œ_ -ÇN^ðmÒÁˆ¢§°æ²o…Na™·¹F*WÃÿnç¹A0tl€Ï ®7»ÃeSV©ØwcÔÊÄ:MöÑønÖJþéC×p׋Ü+¬ Š4#Õ*¢œ²7º‰(ÒÅpëõc‚cÒØŽ&í6[yòÍ¢#ŠX)‹/¤Œ»ÅŸTˆÞFüfñ–S¬@4ƒXkÖãÎî˜ÓI×½EÄãoüGàÿˆÛ°ð>=ÒWÊCDUgV*!e˜×]×¼ƒÅ­ƒßkHbàKŸ´võ;WŸÜ©2Õ~çÉ5¦ŸÝtXÁßûYøsbµ×!ÊoÐ;“*Š»*f—”oÃ%…/K4L2BP¹q®E®cf¿8„‘Ä€@eF08íÎì»cŠ¿Ò€Kpðã§ð°?MBË¿À?­Â†c}ù}#’`¹Wù†}E˜wYhò9ÀGY}õ€‚.¨EHͶùÌtÁñFSíg £j‹Ù˹*VÀ³©p1Æ5LE>\5*¤8ˆ³,ˆÎô ÒÄŽ€—Z|Þ¼³y$,çrP!&óÍí XF©7ƒÛ3õwžBh…"c«7€­}úà’w(Q°% Úåüšoóêí-<ŠÚ é2¹^p—9!$^éfÁͼG¥¨>œÂgdXv\¾a)2Ož+b*ñŒ»Ô°ÏõRúÊÄUêØV±˜ÑÛïÒ'øóL@]Ú†¾0(Â÷ }/@àšˆ+œ<-0~?ê!\Aès‚ÊÂ9"èôÜ8YAPðÞÁëÓñw¼~¡]G@”ƒ¶ªt¹?_™xí x¶ÓÄa—h‹G%Œ¢Äžæù£òã Š/É7Úæjµ*Šõ <ÏovŸ–¡éŠ \Ê6®ƒ½A¥ë™Ñ%2%1Êì>=I¸{aî à´Au±¾âÝw3¸LC<ÃκÃð@èÅÔ¯¯´¥]¨Mò“î‘°ãxOQgHžHUàl’‹R˜Æ,­¾Ní¼ÒÙ™6}û‚2˜Þ¹|¸Û;|"Ñ ­ (§O‚¬•™p}gfw¦[ÌãË ~ÿÕ§k÷y¬ ÅWpÒ‘cFD8*¸@ÓŸ>„‚C\jtˆóæzÚðÀ“÷ãQ¦-SxPçšÉBtëá4æ¡À³¹â×isô €ø¾æ/e/1ÝðèßAÆIðãõž$‚EÚq„¹‚z(nÂ9Æ“¾°Ú&½R1⑃Í*y½ßXœlŒèçëB–iZrU·KUyÓœBïø=‰:a’©*·Ùipô¹ ôuQ«AÆ åíC¼«„úsø[Å9ïhi4Ë2=²‚ ²\ŠÞ²†Î©!”o3“ŒwƃlóÐÖíë|XAæFòMðbgšõ[þ’õÐOd‘{Ê)†»ÀïšðJ¡?‰!Gµæ_¡|a÷FQÙ++¶ç‡úÅóíºEëN2~J=Wä <‚ŠþðÿKÄý½™ÌÇ·»›Á—g PDÖI9&«ÿ•úl×Qu$Üæ»ëqÓÂë`S Ç:Àÿà¹Qj:m\# (ª¹(x¼œžl-XU‚1ê•Ëþ›Üޏ5F©Ä*žWx Í~32Šàh{¼'J‘•‡yjÙÝÈ+Ζï ò?L—A×w^âˆÿþÉH2ê‰RÇÕXÞꙄ—»óü1~ê ôJ‹–]µÊ8‘Ü{Ñ` ž+ËÀR$­+\ÈãŸuL@/-÷'‘a(ǯ”}pW¯ôõǵQÛ=´Ÿ~“s”Üßa¿x¬Gx >>¸8*A2¾ñLLîèõ|©âIÖô!&Óâz9ˆXk¿8 My–q6ꩈ—†¢ °Â3ùÇ"[l÷¨ Ö@~ㆤ€·ùr¼GùAyÑøâdm^a'mõ´rXQ ±âˆ4¶^¥b@8”¼`4Ú²&’Ztºü–„-‘ìnW,ä'ðLÏÄÿ ²íx¨Oþì;GÖ¢"]i q •X­HÿFÚ%·QÃmã‡<ÚÇwÎ$“Õ/ ª¡[±úz²Ìq§§@™ ïÍN…‚Ö·w˜eEYÀ+¤` è „ÒÌ?HÆæì{0¶¿ÞcÕ:û¹÷ð<›pº`˜àH&;Ÿå5¥ógðg{]wª1.U‚ž]âxk9£ö†Á³œ ¡Dëpâ¾ ×[ØÑ­›Eeë® ~¡åzàüPlæ5Ïá <€«©¯<"0–Ø­=âg–Ópë%G…^È©ú7 \†¿è¿ãV,ž­¹¤#—8©…¯³BX Ó¹ÁL×þ•ø?Ý⻸–±Å •'^ðÅ\ý@ 5K„kÆ¹éÆªís†icèÅ7õ&³ à$w„rb0ŒéþÔ÷ÏÒ9K·Úã\¢?XTy$«×‚&e1  U…"ݨ”† µÔŒuÀ²Ëò¦ «pog#@’ù?·ý‡ÄßÏ>®ÑAÿ‹dô·üNqˆÿ“ XȾšì m7Ýz˜n÷*)Á©Ö~wë«6ŽÄŸ2¾À¬q\ÖýM×æš²ª»iKJKžSbï­áÂtœóA4øPD¹Q•J°ÎÙ¶?\1(g3²SvZ•}cQpîý.qÎrER9Û·¶õÖ Lñǘ⽊RtÁ†ã]Ð8§õáVØížIT9ð^drž¹3CÌp`ðÒ®ï¥ïdŸvmûJmÌ‹Ûû=d1®Ó{‰Óìêf–¦oƒÚO¡¿ÈÔú{¦¢„ï?”†¯Ñ£M•Vpʹ¶ÉB¼ûx2EÞ(kAU0öö%®kµá NûØ[²mRËÞfc6ôGð¿#æó‚©±“9ø¶€ï'Å ÿDd㘗̥€9d"¤‰ÝFvv’w˜Œm´¡•dŸNžé&ºÊpr$ê>o™3†¡äÄøÇ}†ØÙ‘¼H>TkôUÊjYk”$·èÞþÎ^5p*ΜDú§B¶*õ“øa8UÆF åqÜ3ÓX?µ¬Â+1‰Ú¤oÛΫ÷ &{:»¯uNÓîH0Š’M,D +Ú€é›I"ô[²å?.¯«¥ÏyùÇñß5÷ÂBÆg’³°ãŸú{·4F=%ÌÕR‹Ó )D»>™P¯…ç-ŸTVf¦>Ña¨nîf®œ ³Åw•ãlìÕ·§ÖLìöþô±ºU«q*Ž`Yzu†éŒ8ŸCš9ýH½QÐQEÛ˜^²Š`¬;­ iwÃîŸÿ_)þk6žá&]‚eEhµ]±µGaöùñø)•FÃÚñSr»tW«zq¾7¹ÚKÎô»<Þå+«<,òüÏÃü°µOv<°ÿtGÅ7Éúþh?œV¸ÕöT$’;¼á¤øŸ@úB:ŠÚÚÖb¸ŸË 7¡O¿—'ÿî9…ÿ¾Êž±Žþ–Ÿ+Ö'ÏÐòˆvWÆ~/ðš g逇SÂŽ\a™y¤i^ÁMqÏÈÞfZº\‡Ây©ÉFÏù*M\A·zãÀýñÿØ›3.çíG‘õàErg£Ý¬ ]Œdspa÷ ëo{s»Ik .ÙÕ´ ~8Ž7ñ¯Ù̯îŸ14Á˜Gò›Ñ< ®¦S±/a.UŒÛî­9jà'¯sVW“1xùQ,<æHy²‡)éIå,¨‘’è†uYšp¢ºÕ3Úž0"œG•Åñ›­xÿùig›»/ó9Xhë/Á‰$ŽcòóY2fÚþn!u{?\9Ö,ÌhÓ™%aþá\sº[ÛþêùE-[—’GiòZ/!¥H2úPB~¢c”ºòhÜ÷SÀ¸Ç³}„Þµ,£Û’WèŒÝeacfD~^ºÈaqìöåÚ´BçÇÔT¦|ä:¦ôZ§4V2¹òäßçrØ»Ágq¨Šèåê\îÇ+Î+{¿è(bk åá0ËH¶m‘«f«80}êñÁqrž†ƒÎ1,TÓŸBYÍøMA¥ƒóõœçv‹rÕtï´MRY˜Û+'EÁ6ñÉHVö Æ&„HÞp„ç͵ËIuÍÇo¶ÈâíYÞf}_î?¹xTð"ÈÞu ·*UzŽ@ÇZ´´÷ù߿l‚\óÙL;£FKMcU„.Ü<,ØdçµVp`ñòà“"1/Vô¿ú¢ —Nx~€Yl»Ø„â›d`(XGš4ݲ24÷릠òÆ ¹²pƒ‹Ã•'¹Ÿ×]€|¢£šßzF‘‚éÿ¬žNmdGTp)î…ªËùZ„‹5Ooí‚}7ár†À$\+“+¸ ´X®+T ^S® “k¸Lù)BÓñÊão’wÍJ ä‘¢õ±¯9½ù£øW¥†½ °)Ý_ ‘W™j-{ŽÂø®sB¨¿~†‰iÛ÷XÞ ¤Ÿ?#uðM1Ý(tÊ¥PÆÖ¸D.åŽjIfÃÎGÓgÀ©+úD¯w¦Bcú«C¸ô÷d.^¡Â›#óŠ2|zpmú üœ‹†Ušì{æžû³ñÿkÅÓáÌy‰/=[ëÎÏLó4 „i!}zÇ•]ü‚j Z•‚ÓȤ_ë9îêͲÖX;Un9§þA•´ÛmZeîR7’m½1RãyÇŽžf¾º¶Ø$\¥Ä(Gôª¿µ¼»ñ…üI°òÎp—z ;¬‚ƒ^1¯ÿƒlÇ~åñ¿EDË»?ðÔæÿ'Œ5ç,‰È}…Ù)àWd„·sáeŽ‘àÓPôÎz`ê[žß–ýì4À‰Ó=„˜Ï" AHXªàÑ:ÉÝd<ÙT®CÎŒ¹?o<`i•ʦT,_aÞ|Ò˜Yvôo–eù'®Îð{þlÉ ½´•p^—ö `îʼnxí€È¾“(U÷M'¤ ‹ÁRz¤oÃwÊþ³»¤ÄèöÎÆ™¯æ½ÏÃyãX(àINŠÆjBÊ%’ÇA=¨Ž³VóÇÆ÷= “û²o+e3•&âcõÊuE´XÒ0Øk³¬ŠDêwMÉãf¨íF%–¶Î‹²ïhΦ¥A‡·æ gßgð;þÚ‹ø[ ÷4·~pñˆfé)ÅÄž®Oa&%׈œn¤¿\×\‘Š»¤øŠ†Ïò¼7XÜ“ÃrÏØl‰yFY>Fýr{ ZÖ˜öα‚£zæA Ä⵫K-÷­¡•33—¸É¾Û®RI\W/oßjk«>_Ôp!™Q®ÑÚ1N©G¥öT¤Ü•쉯ùzíTíNåÇÏö¾(è¨~dvã\«Ìù©ó rÕ8‹\‚ÅÁ~‡›èjI¯ ì,õwLû¬»ö‚$gÿü­ÇejvÊsÙ.WÞéÁ…‚îÊ·¹¨´1J°?ÛZ:ZdzDhœ½Ý˜ŒÓözœ½÷ØÑfÿøÓßA§ùø‡ø™Þ éëá$qûuV´Ñ»¾EÛHƒ€ RsN`¹m<^ +—Nú?<œüñ»Ü÷«€Â嘴¨@éè¯Iž³)A–uΔƒg¸‡È€OƒØn¡­oyÊÝ÷ç«AyVœ äGøJ ïØHžðzųn?>^ª¼Xñ Z£{÷­èúšWå»êó6X­;kºúTØ1–Óøs‚·du¾æTñ£zwPE-V³8ò¶Úô5JJ€4yêoñü1üe“6çø°WƒÒx‡5’ž¸~0–<ün¦·â…dL_LH¾GÆt@ø\;–¯3–ކšÖì†Ía§a‹4lêuð|»ZƒBóÚSÙ&Ù¡C(6 gOšå?ÎdÅÚÅQÌg­/] X”|±•$ÕÛ¹¦RKÙ“ÿ™!»)’[%£ƒ?=öçâÿ—‹ÿ—Ï}†£‡|x}RM#a÷ä¼vn¾&BF\Ëã` ÷Ø<2!ôÌ„#OažmN]¾½€^äçáï-[mÜàgŽ¿ã„yH»"‰/=xð$™F?’9–Û2›²€ŸM2Ö*)#‚±ÓWxá:{‹Aâq¨ÇCh§„›<\ýbÿ~÷ïg úOAÀð'ÜçKH¿p%åãI ×¾ã‡d 8žPÎh62`=EPšÀͬ‰þF¤³¡ì|‡†€ûú$ÝèÄs^OMÌvÛã^3Û9¯Je?×Ý Z츽QÚ2a›{„M ö ½PÛŽcàbÛlÕö<7|ðì¼÷0Gó§H‹–­5$Á:Pw{×Ö˜f¿:Þ”6H°M?.|&ÏYW­…,·4D6"\ÅÌf8¿°ô˜[È€·î.Âç&G<ÙJ€Êaüܲó»ÄÜt}ãJ[dÓ™Yj÷Š„Òœ5²(nÄî’« æ Ðøp Ò¥ãÙî’6õ4ü$e(ËëPR5nð¿¢0éãb;JŽ}P¯¥‘ÔstO¶Õ4ˆœcˆ4Zˆ¡ ¦äz gkÝ©„'_<ÆášD.dYº|­²»U{`ˆah¤Ëøùênµ.î†ücÏ%ÇׯaB†\—Ò³‡o\HêÃŽ#ǰÜç5ÔµXN2tK¾?T›dð³ ò º¥Ñ‚qŸä#8–ò\Hõ!I\xyBå£p:˜Gú'’Tw>ƒy‚&xÌp™äÔ+Ƹb-ÒS­fÆ4fw¥íÖ)•y‘Î,WVg³‚¯v¨É, †µIä¦BO´´2•Çx=@1‡Gݘ"Å­½½ÿ{ðÏØ}Ár–2äJóÆ`pû Ùì t7â¾ûæújƒxï{Ì5ÿdþŽEñîÈ–ö:@C~7/'/Ü|£øÝkgÄÖNZÐìªÁo᜜© JJ†q“‚‹Ç’Ѧœx½@ ¢uA¨Bæâ:@_»";”Û|ò?5ÿaäšÀ¾XMØ•È)K¸Ûþ9ˆö´ÉÜDï{CçÊÎ&>ÅÐÕž&Od8f)  zQ43é%Õ«ð˜W„ƒ÷õç“çõT—ÂþþÝ^à”ã\oBî…¤s)ß RQá˜dÄxÈŽéKóþ‘øƒY Ò~'´å.À]ì&áußJ*å…/,±YXA¬‹UÕRÎHë5†´‡ š«[“-™{ò‹<·¼ümSc=ó⪸Ã(YõØ&¤4Çc¢žÅÐÜÚ¼¹ªÿ3ñÿ+Æÿ7äè€qáz G‰»k݃} ‚lŽqZÅ…m€X·/¼'‰tl°Œe„­ñßyþd÷îß—-ó4:ßìʲr=Ù’ïùC Ûºi:G+ºéì¸ÛÀæ¾0¸cãé×^MÊ@`ã–8x³,æ¿¡OÌ¿¹©÷sŽý3Üó·ü|AÁ‰xöõ5«xð{ºïÞ $FÙß¡ÙV–qÎ=_]V§Ç ü6©rËþ#ç3À­Iúþ‰òJÞGßÌ8Ô*á­Ë­„dæ$˜Øù1±>Nk0%_ò}œg÷ø‹ ,PE€ÍŽ@æŠÿb5xË„$|ï•S§KBÝ^Ÿa=¼…;ð•Ð̉뀚«<-þyEiÈKEh [|ºC`ïA “r¦!¸²u“@á3Ç0˼L%~(y#Þu£:¼Ûôul$€BRNPˆM¦-€¸Å8,é)B éãQ!ˆøü6üESëÀÐDÚ=Œúkõ9õ :ÛwÓ Íú~´ Ay  IY͹ßóÔ ­-ï.ÆÌ~„‹Zã¡®¶Œú—ºûv„Æû°L„ÚÕ=# Žkz‰l¨çòÅ/¯èKí¼¦YNYü:¸Ë{¾dyàíÌñ­áíÌ™¢Ex‡2êÂKàžcRFÓ\o>§ôIk´ãW—kðnU瓬ªO¥{†âÕ#oÁ®Ã¤]™3د 3þåÓMS‹q™+nŸùæXtËÆXÇ‚SH̽¸‹¶ç›J÷ç¸÷f3Á NJ:8cÈ¢—L}æ£OO“bë½§êGLKß_R‚4ŠªBÎ ÇÙ§o!ï5@å 8¦d]ăWéî髸7|a€Z!ÝljòþøQ{ÄË4â¶2IàZrf¬à–9 ”'÷>—FérÊþû¢I óÙÔ û ß3æŽf0XÒªïÏ«$ô1¶½R¼Ÿ5Þïo±s¿æþ{ØÞ5Ζ—¾µ:XãJ’E€ï}¢Žž@uÓ •íIïâS¾©´otÙÖ}cç9®Îcrr ‘ýh5I'Ò$ïuh<¿uïeÀÿéJx» ÎÔ¢r0L/|2j%‹{n"8VàP°¿¢V@fÙãÞÖýh¿{Atë¹?‚–’áé8ù{gMÖíõf¸:Nÿ³ˆ—bû§Þpꌯ« ¼v“ܦî.–µ½ïÕ V¾¥>:Zv·g©›#ì©ðôžˆÊKSì1}Ìb5øØåÐÒ@r ­WøwøRã)Ÿ·³þ²Ç7Ó}•!Ô5ôɱMîwDkÁcÉw?ÿ¿dü»q¼­Õy#¸ ﻫs Dݼ§g%EHªmu³ÝöOÅè•á{v.¤{ô9|èåe2k½üñoØÑòéõ=¨vÝ’Å| î/Lj—qôÌð‹—êEFÄ/ç½ÜŸ “EAc{–òOŸýd:G‘åóµ@ù_ÏþïHÁ!úßùTÖû÷»ÿò§žÄ+儮ܔÊ'|l[âf¦sPŸU§‚ª÷Y³ÆW2ŠêÓõå,&TJV2TT=B©Í péZL#ø+Ïû\§:Ïæj ¼ç¥$ù–˜*¸“¸··‚ULC"'>M­•Q$ÎwsYþ'³vhÝÚSÜü%òë‘q¬‰†:Uh;/r'švîÍß¹`®íÛB7ãéJÝ[gžh¬ÛoÀ Ô³Ák(#kÚFVZë—nhß9Tçæ³°Ï>ÜŒìØ³ÃGE-ÏR£C—à[féS ª©Èž]€AœÉE}½§Y.Q¾lˆAö™*òF-æJõŸСü*8ó@Ú-´½RCóëž;„|ñXíS«!é×jsrf_u …k§öI[W時C²8<´Fˆæi,KÓÌk ö\‡^ޤB±¦[°B"«V&;fçGteñ¡(šê6¬³l„DzÆÙ÷?KoP4;*/ y…nLOyדȾÖL;¬©zî¾ì1 ‘**&« 1cø¦y¨7°ªUm rŸÓ»Þ =c$òèÈ&ìÞ}ã|œ ¥ѓˡ¹|Îá@Ω ôŸýèw¿Öö ÀCgÇq³Þ«S€e±okµ ÈúwñÏä«x}f髿A¸D?Ô̌ԗµ¶R2»–ù´ÈLntpSÖ$]„P×~?#¢Híe]D‹làâѽ{ƒžÙLO¤¤ÿ›‹š-ˆgj)DeÞ]‹™o5Š.<Ž à^º‡Kè°èÇã ÇfC[ÒÜý®Áb·â@xûþõ¾ ev 7£îÓò­%U&S¬wÅĵϭUiœZmÚ·tC¢¹.RÏïY¶TpÖMuJ£â˜Ÿ‡ÿ_5þ½åÛAKv..—ÅŠ½åwLÕ|ôœ Ÿ†ƒ*oOýµ¬c/DzÀŒáĺ.Ku•OQøOÄ_oÿ¾£Þ¢&ó/Nr…±b¾zù§FlÅ=R^–-2Ý‚bñ,-Þª7ð<–š¿¦!$ÎÉ}ôp&dó<”kþ·¬€µKúŸ©ÃËýïwÿþ#óG¾¹áRKS)ÀtÊï‰ÔzZQ·“E¾}I‚›¤ Ó¢çÕè‹(ýë{¦ªHûFãæðÀ'Á¨Vt¹Ôý+ÒÖSFÀþxf-´¹TÔŸe ¿ òÓù°þ°1hjŽ‚  jž3­=Žº› ´Í-àõe%_:„ÿ{¦clñ‰°ó8'È›ñèéT¡ËP•+Àð“ÆpðxOüZîû’=¯·_ ð[ZþåÑàtɯ"ài‚¬]û§Zô•¤«ëç¾Ìåà3{3vÝLšq¼—]®S|ºm?Íڢƙ ±ç°€dóçQ¢`ró \yF 0J4×óÆQÙUÊÁ¶Èš%â½Æ‰ã´ßzKƒ>ˆ¢3»3ª"Dh«0À™;Oo +AÉgOö…Š;Ð^Œ%¼^/.)b>އú¼Ê9pn¦¹Xžžmv±ÙäØeöš]OM9½?ÛcÙX‡°’[²Y8äííö¬:J°?M3pÛc9|¾A³lYIQFMÖ8¨±÷³ÀÛ> wkl0?ã—#ŸF€ÏZÇ£!ÚöñYç÷»cã^Ï/+àMêu”ÞÐe/kù¶8 ҿ礘ףµÒu2Mbàu¦æˆÈ·O©¿ÿ¤T–txÂâGÆòØó"„xpu^¥0m’·NõrëTÆGWÖÈ56p%E»'ˆó?z”e6”Àá"1wÉ2-G>Ù*õ»' Ï[ƒ#t÷äWÍ'*ÀaSþr‚¥J¥Àj@0ÂUKïá0¯Ž²šŒ>‚/KÈáŠýiøÿuãß5¿OY J¼"«ÀªÍA@7 '9PUIl>i¿·‰¸5‡ê-¥ƒ ðº½ESì~"þ‰;„âiNDœvÆ6×±9D渺¢˜™}྆#&ÀÆ }õvîëó¶€Óÿz¼û¸uÑ œèV"ÁãýýY·ÿé»eÑNQoÿÿ‚õ¶•m•¥ØÂØZ‰‹¨@j#(Õœ(¾7Bue_pÖ8*@ðÓ·à`îCHõÎýô̓¬å7brÈŠÆs¢ÍÄt;×Gˆ2gvéHÍDm/ M°Ê}î}ß ž¥–ä?péñ¹Ãôá4n_‰€mèÇCÔ9cŠ8›÷Ö±YYàeZŽdV{֕а{í›û…+XÀgÿŽN:÷™xÎøŽsä!•»uÞÉ+}þ¢«W®?m¥ïZ™Ò2{óPÞ͸Gà6’l2…Ré{NóñD¡]_“BkŠÃpÆžµ‡ïMÑžÚüÁßÍÑ—ív¨ßöH†lºðjXÏkã@·&¯¡A¹ógq2'G)PhJே]OÚ3Ä"-¨hë¯ôP—ŠÇ”BÈQ5í‹õŽßn¸B‚+û¸á>"}öÆ'•8ð[Ú àToˆà/ªÂKL4éb÷ó¨Ñ¡]{^¸\ýïà_Á}‹Lõñý ÌÓFÂÔ’ieÅDµ„§'‘Šã¾Álxø‘úbsØ2@¡šð Ø Ü;s0œŽK ŠíФ,z zÿCì…ž:pz|AÏgz!öÔšÖÁŠÇï©€Ðøqžú”]·Àväíƒ\+w¼÷<³½B¼ŠEUTÕÌ+¶âòtdPë ðy) €´7*¼$žBÿK° ñå~B{4ÌHÞ8o¿xihÍãõBJ‘̲Úþ]4pÍGu‹OÑFÈ3ü½øŸ®ŽÈšk%;sörÄ2EÐ÷‰p[ƒfWá³ëŠSðö½ß•yô¯iæÐqww¿åINìH}ÛM‚µ]×+ZßúÝëFO$½¤\•ÛÍ|.­®:9ÏGÂsÍ Ÿ¾¨Ý3lÈ«Ì.¤YM¢öv¯)/ÍRøù¢ žBï¦óòz_ƒþåø§‹g¸3Ò]ԇʤ…1agXûôíÐ0 a§Ühï™MGæ ØÔeñù¢]ü3ñ'kw8zhñ²¤?¡ý­5çˆÅÑ,­s[p?¿½1ÃQ:¤M€'øcS´JÅJo±fß„†€ssSEÿWZp#þë‡ûîÞ±òÝó¿åIlÿßÖü_$ƒxõ@¦Õv®…Eü¡«b0¸&[»—ÛÄÙÑ.R¨çÎoqai`¨«»2®Ò}Èýåø[¤ñåë·£ƒ|Kò`ñUcqîž“c!pwb¯PùþªZTnFûÎÛŠZ×YÞ{Ž5àõMm$-Ô§§ïÅ éÍ05ʔǚ˜kGyúMIIåY‡Dö`Ǫ–‚{KKæ–"ººÞÝd4Wÿ¨¸pÐ+€ë7ÃÁ©öp Þslo‡ªAo9ãËÇîë…7¯2Òµ²Ž[™x¿yU^ÁFì9¼ê™¢FOî?1ÞsGKþPBƒ÷ðZmvQ!ÅÅQ‘Œ´;{` íÞdÑÕ‚[½#{‰ý\ýgö¬2Ö8µä’ÓÀ óÑúGžñÏe?s­0”¡_¤±Õ–xOíªÀ çY¾åóíÏxºÆ0óªB_Å¥ü N«ÛÀàºébì“Àó°±–àåÛ¨4¥ÍÇëüÕÊ5?ëJºš6çH]ͺJË“ÈèW!v°Ú›Ä£ƒp¡˜+Q;÷8sê”}qêX{ÑÏo¸"ðêëÐÕ–b×Ù™-%Ö,‰ªìë!X”LA¦Ïª]Ì89ã²Ï>jêž_Ÿ!wó µ0¬ÂQMÐ1¹B§²ŽYß OPÏΩ}ø4ÿãhÁßåÕØã8“$ï¤IjðÈÛÕAÖæÈéÆðéW"WFÿÏø_Õx^NJÑmÐSÿ…æ…Ù‡ô~¬Ýþ†3Ì—vsã;Œ?+ìåÚ¨ryegv8B9Nî 0wš¢S¼þ 8XNò–_h˜÷ïšUÆšŠN„Æè´ÇÐêìŸä©åÎs\ߘÅ¢‚z€ iV`v-5‹àXŒ_›ñs‹ÿœºÜSoÈDÄ{»h9kPT1îá {ÕÖ(²é|éÖ:ŸO)s‡‰ß‘@ߣ¼R©E{›†OÎÈ|®b‘Çe<Ý Õ8ø$t¨ïöQ!(Ù0ÙžmºNã÷á?ÄbÿJ~‡ ¬ š8¤qVm §Ïô½KÖ_¸a6s1´¸ç®—Þç뉚Õcy+“¬/½­î• ˜V;ÓÓãxî¬pf)Æ8O?…D,kåšGtjký…ö‡†û¥ ˆRß0k’êÂkßzaX?cˆ?ÐÆÙ? ÿ¿vü§î¥Ìd˜‰Ë“(÷ÿøâEÃëT@MÄì& îŸ41$:ÞS }~;´ ÐøSñ‡9ksÐÏ{-D¶%¤²3NïãT»sŒfŸ~jy•ÈíRÆØ[^!žáÎNM98Â¥÷ˆ‚÷ø³>h>÷/¸Áî_ýeç¿ßýû‘?óÀÁ¹µ,\úÒ-Ï^½ùdí.²v¶:aÔ¯ š%nuÈõ« 6,\j`¤­¦ÑþÊçÛ×eö¾Àz5éÝÂ;Kb=Þ$löçr’‚´¥©Dë"ñ6ÇÞï_nÍa…/$Z¥‚6á#`ôÌÛåË}#\³%ƒRñndy©žZ¶¥öE³8˜hV§`ɾ'rê#ÈðÝÁxø}óÛ°:Tˆ…‹®Á—½£_4¦Å*¼t²³)s0…ì|±­K0h.Bž×6À»•¯Zc]$Ý¿nm쳦:‚Aõ4Â+Š`ˆ´ð­JX»6ýãðøÍ×¹dí³z\X²Ï‘ã”’rÃu•ÛŠJl^”«ô=L’+|¥‚“,¯'Y{])«!ÿH)<þ,Ý­¸`óI•Äcß¹Èö›\”ÈõDç‚€µt ²±eðF²âÑû qŸ`‰uñú¬¨ÏN? ÞkW*,°þÖ¿ˆ+rÏ7Àg'q¸³ò Ûåe<¬}µ^±)5 ’9î‡dH{TŒqÔ×t4¡„–$+!×\½XO(xyÎ6àÛ^{bÄÓSŽAO÷äêÕ1ÔÙ',>Ñ&ÜŒ“ïüª* æ›"ûÞô¤£ËwR«“K U K²ìj><73"º£!×$¬>Ž%û!Àý·Sz½¦ÿþ\AX”N ~åÿ„ì"W/GsIÇäE‰èä»Ô$4Š)Ê6BîÌ8Bû‰ñ 2IeXíæºHÀ^¤¢,…Ò‹!œj©…ügÖ{qà}„[,äÉZ±è#ñy7`í–$€W)âÛ/¶£ÓOkÆÂ÷x¥S•¬,=™ëèštÀØG˜6ƒ ¡¤TUŸ› ìBe5 ýXͪtÂÅf%ž ùR‚ ›ãÇ‘ç×—àæ˜(Sµ>HŠ^Coì»Z%A½¸gãÉî o¼î¥÷¿æ—^ä2µ‚´]íR]zñ‡±ÏÙÇÛ·š#˜µvJÔ‡kv›|`¶th»®­0ChåþBbч»BßWl³£,(ç<4Ùÿc9€LÓKÉ&Ú Cÿ£nBLôoo¿Awr¹ ÆÕÅ›«Š°$ÍNÔ®•z¦?ÿ¿|üÏSl,^9fÆúÒ‡a/ ­BÕQÁÔ=F­ñ°ãC,øïTê9pIϦDÿ3ñ—¢ó âhº½¶Î7Ñ.ZHŽê¼(Ú‘d{Úµoú@¬M ¨0AÌØÙƒ<Ÿ«ô© “|‚4.÷þKjøÀºúÿýîߌ`ÿðƒ_™Åtöî®Ûo€ÏRÖ¡„ øŒ–µÖ$ǨR€²X x8JÒUóÌ6É/PÈßp.ÆäkÙ&å“*k€;â‘©\o`n¼¾¹ˆÞŘPî”i^bøÝDÄ噸h쥯,ÀÞ¡h¤»­/²½X ƒ.Tö«°%<8Ä3÷Æ~Úƒû@Z í£[Í3ˆì*mR²àR¨X¾"”i2tYOá<÷_ƒó¥ã€Žá9ÆÍ?|Ö™F—{ƒôÝGïs1^ƒ Ì_>ìmLžL‚‡½œjx±ø„FÂ¥Ø+6R‹pìDøž ÙU­ 8²°·ËË…×y 7E±q`ßš}“~¼+$o\àôÝ)%õ„¶Ä]í¯Jpiž¨ºJEâ¾/dáÚmËxð“ºQFàðZäöt½©?2îç2ÈŠVV½‰ÜÝ8Õ±’C í¹ê]†A o÷ôûB”€ÁÜœ?ˆ¾÷½ÌE=jô¶ãö%ÕëQoKßë#ÛvòEÂêf(Om.DÑêì¹8~áwà/–¡ý§ÅÍwH˜Ùymñ5{• ¾Üã†~Q—XzuÍ@¹Åå€69¢iÚôÓ6åZsVr<ÏãnÂ,.p¶bŠ%ù\"ïàN.oãõÊAe‡g'÷”V  äoÃ?~ßI‹÷÷i¸>F§‚²Û©ïÄüdð­é¬Ì{ïFÿ üÿ_ˆrU…ýÞÂRõ_ß”kÆ“}¢+Z—J¨ BÂʲO¾ÖMæÎP¾òB`’WTJù©øìzöí‘#´(ùÛd-¢ƒÃü<(I†áñÌ3÷1ziË·Ï/˜hÞg C;ïЬ4P9¶ƒè|£M¾^ÿÝ‚°ýÅÿ¿û÷$ø @mló5§ÁdéîÂ\÷ÍFYŽ˜ó6`/]íÇ<HÔ½Ñ ó-LÍ `ýÒ§t¹ç§¿_¼4= N·´žñíÒ­OÈúÞâ°ë1£²Ç»A#YÕ‡|»ÊF?<²àcîl£³[9G{>0dš­AâÈ‘…éG:F˜WÇεÖ`> … ë­ÃöüYõÙø¬Oß߬·$¸AÉó–`rFÎñ,—f'fD«Ý/òìyE8‰¥˜[ªþzÙîkc~ë#›×³,~¤¯Õ}' ÈY^@5cü¬$úº÷Û˾ף˜S¤;hE§”8ïª"Ü­Ó²?€Þsð&(Š1á@SiÈÞkJÆ{Ú³¿¿*C%^Ò žijGOùíÕ}À™ÕÄGK 0wòGâö­Å}dÁ6ŒÃlcÊb˜ù³rí¦Áo¿Þ‰;hÔ*—¢Ü¤®¿¯`vô48d¨4k¤E=bøìì– }i²_ÞNÍï»|Ù‘Y!ºéTg5>î²È¡ô9íËü¡V*•Yø¤&¶@w*¢IþÞéî< 63QÀˆÅÜó¹úH=ÂøV9GËrã c†*9 ï`]×k6¹hÓ›åŸ8ß–±tÆÙ¥áÚNaYòîwqé-^ÀÙk‡Ö/r$bÆVÃLÓü@]Î:¬?:hæÜ7Jà«úÎ…Í9º~‘)¤3«ýŽþ üyÎìob¯Ž6oþþ >)«Œœù#„ðÔ¤`°ü‰aÿ©ÅÓµg®e‘BÛòš/ÜE–K¼R_$ôޝ£Òoí®¬îYñ›ì˜/eô;ÿkäûò¹ °!‘ÍiÃÂ'Q§",6w¹{™ß,KdE §|R ذÃXÊg[ _ãIéW&™>Ò¤öúu‰¼>R¾L÷ÂôF1G{*{¯¶éÛCåoz+O¯3:׺׳t¾ÁDT_X@5¸®\ÀØŽŸÂÁñÛ9A#ç—]ÆL3/Á~ý’Þ‚sÓùéÆ“í³»vÛ3×·+ûN¬ì6”™†»Z€%ú¦íx:M*=?0øÜ¨©Kdø·†;'9u‚u€?±(6À¤˜4ruŒcñÝ WÄFµ›0œ1ÝQfz$¸sQê£=Ç–ÞêBV™ìÛ&,üñòaáO4þ[þ”üñmÿ?,ê@U0âÀa1æ…Y‘Ð@Ø~º€õ2ˆÉ$àƒüGàFÚøùpX´—6@@qà:¸_ÆóãYÄoÈ%÷ã‹C»!kI,ÿÛM¤ÂV¿6Á¸ýRñ—ÖÛ71vI¸ßjoûÙÒ_`q¿ÕEh×hü¯õ0®‘„_-óÃ?+þ¢ùá÷‹ªm×ǨDæãþQq»Ö¶KoWDNШ Œñ×8Ù>õE…ý:Gd`—p("»]€Ø„€C0XÄ€¸fDF€\bð(çx)áȃüÃû! 8ŠˆÄ(~[0 @k›„̃߶±b‹% ˆˆrÀ]¨ܯ£úÅFžáÛóÇã~5Яo†n_ü6£_è€šЪ ÿà’ÀíY£ñˆm…(Â(°Û†¹Æ#ø#w±ÜµÈ)CmCØ‚ÿöMä6Òчô²»ô…Æ#ÑÛÝ"j E,~»î¶}1D,Ú5 QB´Ú%Šø‹Fìá FƼ MÜV»ý[K4Á³­%úâŸÅ¿æ7·úÍ7±ð«oŸ#3ùaf—¸ã~©ãôOÇü%¢ô€õ úÅQ±¶I¸øñ?jm—ý¨¨üÿ_ þcóñXij°Ûňóa§À¢Ábþˆ^øqÛø4ƒ”"øÿðR$1xÅŸ…=°È¨~9 ¾î(·Häõ# Ù'Áö´PD,Á‹ä(ÀúlÇ(6p;<Єßä¯þ¦ÿŸ)ÿ $Aãp~*uôü‰ó¹œK üUì6ëlçkŸkÎeÁ?27BPH*Eò„gpøºDüÈBØ_"ñ¤ÿ’~ ñíØôE‡ÀoIó786RåøãoIüÛÚ¶ýÜß=öרÿ5sàÿQú‹çý(ò÷‰ü%´·«bãíå¿DÎ?ºýqÓ>þŸ)‰7ͼèß*nëþQð  }Âà·dóË@¢G`àoyN¹:x›ü{!!†"lK@!I¡jûÛì…ä_t0RˆžGÒ-ïŠPB2Øíà¶Év÷ @¬ö#t±.ñd5¬p^¡‡bqƒ!ô· .Öþ—ùý OÀ8Æáå6ÙýjÐëÇ™Í øÅÀ?@ðÓøø—„ÿ7öÊEØùŸËd ¿PüvÛó‡ÿ¯½+ño£HÖÿÜæÂ.,,,DzKbǧ$뜙>f$ÙÖaËwÂõ8²ÀöAüq¯¾ªîž–Bâü~OÁkí2±¤Ñ]]Ç÷Uu {wÜš‹ ȆÒÐ…&K“ž2Ú‰îŸ>N*»ðúÖG0_\ã¯Xþ0g<?fŽáC B÷@F;Òa , °€ £›Î:—OþßõËy,¶YÔ@fä‘û Í»km›:Ìm™ÐüÃ6?†&•=o÷i_ÚÑç1A.= ò?úÿÕ)Ç“ðýˆ8iîÐŒ¢[ò”É$4À7ÐàÌÔºW ¼ë…™Éÿ'm¤Ð:ŠäŸ#¦]Û¤-)Â5RKƒ@›b:@­®\gmMC ÿé"ºæsÿÿ»~‘ÃAl¸ö‚>úØ l2+½-Øgš*˜égë/¦shl2Æpv‹“ÊKZ¿W„`¼4þ}6ývyäŸ;Ú'k·Ææäïp°ºí—!¼3'JO„º„ãЦÓÅoOnp„¥Iiâñ~íeèp0F¬ þ\ÙºÐÒ>ÁÎJ¤¿Üyá6 &@/ Œ/}IØ´r2%ð\4²Ã™x!…®lÓø@wºÌ`ˆ)4¨niò›°³tÿŒù3Ûèá=ïI±/Ü ¬»Xô´5ˆ,PplÆDƒÐêùŸ°¯½|Zù¿Oòg(¯~9äMCÁÎ PÎ1Óé—ÇÀŠ pX: ï\’vÚ#ãwðr~^Õm{›ˆX@NÅ?^×÷ÕiŒÄ»» ïSnp‚¥‰)á]øÚ #ÿæóiÃOü¤]X/‰•aWvtR¨žœ¨n:ÖÁS‘üÝÁšýè°|˜¹'@þgEÿ¿'5Ãô€wOrǬÑË»à4˜7|™* ÛºÐ)ùYá¹^ªÍJþwq~°¤t¡tÉIÖÚΠ«#³ÂF³ÊtB7 È1+køNœÃÿÙ¾›Hµ¨¸Î^½¦¿ÞÖl|i‚ðTÉ2ÍfØfµ7j{Ÿô à!ÖÑ=êë͘ÑóQ¹Ÿ1Ç)«®X[%?ͳjŸç¹6ñ7/1Á ø+ý®7Ͳ©w{'ƒ5e]–wlIõò©^]¹eïáéüóGS;ú+Ã[¡•I.ÿ ƒ(OÀ“ g0ΉeQ¨V?cZŸLE²xÈcKŸ²ï¡¯ræ§ihÈÇÃ3¦–Yjú©M´.2³¼Íl9}°äÓœY•=u'¦5i³´'F#ï»á°+èáØØZ•‡ôÕ•ÓÉÿ;Æ…t¯p?Óâ92k™*Æ]°¿0¸²O×é‹„Q¼!wƒ¬b"¾Ú8ÊpƱ8¿f—Nò7‚ù™ÈkœÁº1Ü¢M¥_äÂ8€ÚèÒÅjÉ8p”ÊA‰É¾Ó17 •@;¾²øò¿ãçÀØýáÿ-I!à7é¢Ì?Û½{À)„IW)ópäCi§¨ÃÅÙËÿìèÿ]¸sr<[^nþˆa²Skh4©„î_ekÛÌ'%s3“ÿ/<·9­Hב›Å}ºPùcþÜ ²r[õ‘ãÿyÃiµøõèÀ9üŸõëq€WÞï `#ÔpQë[=)Ð+Ô)÷ÇiÀzåu=þtK;Þ–Y^eÒk¯kýßûyî{5P¥(ß²Þ'ëÛŽ#tXA¦}²´o§w ¶@«ùcã)ÃiЙê•q÷„’À³Ó:«˜‹ÿ#<‡»zæúû¶4"ÞhVÆ1ë[&RùÛ¦§.ÞÍ9ú6`¯c%5È)~$ —ö ùGÅ&©ìrHÎ~Þ,î9ׄDòü‰LÓ+{`#9yHz½pÐMò¤X8JŒ*$  À oðôrPØD0„¦Ë\šä¸Øù£“TÆSCH›W?èy„–^>ü?#ù3/ÊPži~œ?3¼#Rœ‰Å(’?þžÑg¯M÷¸´oøÃ*eiácºÈß²ëq˜Ÿ-—À}S®Ž{Šï_†_ÈG7HÁ‘»êÚ^.@WndêéÓËÿ–ÕÁÄã~=õ+LðÒ^é tRÛÑexiï×ÄÂZÙ¦mºp˜Ã+,rH4Ÿ³gf-ÿ³¤ÿ¼—¹iž¶b¦µ1swÌ£#3e94RpÓ¹jhÈ?{jvòÿlDá …Ô·Pä’š¥..yþµŠµQkÛsái:ÎÑůGÎáÿïýµò׃rg¹u“,À]D‘.ŧ,c “Ô^ÔúÆžâ$¬48¥ª¦|<éÆ(BOë}&Jc¦Ì@]ËÒÑ ÿa22%ÿ)»PhÍQ„ \qLàÿÔ•£\Ÿ4éê®9aì"þoe{šÿã_7ŸûŸQ”)•m£—ëˆ.Ï/§®nåH¡b\ôÇ~Þ–Õ€4Í.øDÍ¡§ºíqu áPÒÉPÂÅ€#NîТÐf¬2­æXs¶QØkGÐ/üÇÎ!6rÿ¨ôrÆFÁ­ê+“ o¹›Ï=ºüoîpËÖQ ‡/~Àƒ³ëdòŒ1‚ôÙ}ÔÕ€éh¸ªÜW®§#˜/ÎbvýÎ>±—n5‡ÆºâÀç I€ìÊQHl†3YÞ·‚ât»ë©ÿTn«V¶åxŽEo«æåÓÊÿëÛ=úuiÎÛ…Ï+ÈT£í„ Ïä]Ê=ùT| ÜAsìeËJ67kùŸ-ýÿ×È`FqˆÍõF¯÷È‘’Ú¢ŠaA&¼´{›aË꿾š™üD¥#N”圤û·™I³.ç-°˜ªZˆ•q†JO¶ð{¤àÜýÏþõ˜@jšÏ~z•6 V—^ÖÞÈ]á4˜i|ÓNÞ]Ðúú{=ÍàLqÁzf;o]%ó¿£ÁèùiïµÉE±!üw[Þ*µ<ÉÃl¬•U7zᇥ-mAµ×_+Î%Ö`qßœdÑhÓI¶N ‚ÒT’þ—üŸ˜*bùµÿíÆêK›Žê{éoËKB'§û¯.Üt˜_Ü>Â)àj@UÛ̹^]kÎíâ¤à€€PÄ•÷¸€ÆÿeÀ•CðxÎÙ“›ªÊÖ74tºH)hÀ×d†.܉ÉT²Q;ÓÚî ð‘²ÏêÈ|xþ·ùü‡GÆ·K¯=¢ü¿„üóL ”G¡^Z¢x:h^†Jj¬LŠPéG祰 ­ntC-€„¾»X Òï{øï¦ó HþÚá|—@0ˆE’?ÆN³½vÁLfW¶Å 2ÜãÈÂ0®¼|:ù¿ûÏ(Ù®Ýä•ôö® â¡Wf±œÿW¯ëiåTèêQdìé<ëݾ2\f\òWŽ87[ùŸ9ý¿] 9Ø&n«‚ H1õ•+fõ°<¬;i&óÊ[³“ÿÏIÁ8Ã/ˆil ÁemjÛí!¨E¬pQnþ›¨ æþ_‡Éý¯sÿÿ¼/@ظòÒ-šB4ÅažçRýí««ÒTxÝ©×Þ¡=ÿÕ'ÿ„’4o€+ 6¿èiÚaäÂT’«¸¸œS%…š-í›EÑŒ\ÞÏË»‘EC¥acìµ<±S_”á~§:1Þ*«€"hSëç±JFÆay'æÿø’Ĩ\R·l¹3}µ7ƒbG€ÁÝþéÔ‡Ïü¬y §» $à>9Î>›Ê<*ÅìÓÉ|´W÷Ù¤ùP¡Œ"¹P@eúC“Ÿ§Ã(©"¤Íâ®±‚ü!¼)Y , Aÿê ¬Å"§ª’eËkcc³>àq\~í»^p—Ô£Èô9yåÎúN 2`I¾OÞ‘Ñw&.Ȇµ€ä¡S’¿¬?R€£4%ùÃÊòˆ¹¹h€}¡¥I.Ù})`â¥ibÎÚµ]çøyü‘îäì Éßæ’UŠùd Ø|3=δ®r_&L±ª¹ôTò¿3EÂ{·ætuä|Ÿˆt»n¶òz‰)笽<ËíÆØxhF Ü‹S)©®î _[()C¾+½×†ÜÒ €{ ¬^ÈhÇÆŸ]þùû¹k~èå½Tƒ];СõŒsͺÖE¿®‚(3Àåüç»’Qæó6²Ú‘-.œ›üϪþ·QH7©9ûk{  x! ·õ²™t’BÃ)òµ ºÿ¦f(ÿŸ]Êа%˜ßèfÄa@{}§>JWÅÝ0– ²N’û?Âï¡€søÿ„¼+€×Þøô="PUNﯾ®?9f}Q´¦QBër]3Ù?Òo¿Þ ¬c¶x`TiCXܹ? Y¼°ïæ¾n¯úïd 첄î‹Êf7VÙg;‡);½7oT²)õâc‹½Š2Œ"þ¾úæ÷…$´ ¼©‹ç­Wb‡Ïß]ÜírMçd·/Íé ÃäºdÝ,>dË¡¹9@bö4Ô¶%jÇrcðÍä÷˜Ñ[Þvýë¤ÜˆUipW—”9r É^ú2à$Ùð’u¹0Å5ê*^Î¥ESÅß?:rÁû«o>œüÿ½©<ÜOɯ8¸/}dðcãªþá’d>)ÀÞ˜ä_¸ÒÈßàó˜>ÙòÿIþ¨šô]eŸÕ;[ýç²ÿ®Ý÷"ù÷Â7¼Z!cBÝ¢A^]‰“Ô»úú#ËÿÖâ^è;†>x£f_‡½/Ì æ¿VÕq°û%µ`8÷m}ä`ìäH‹’Wg&ÿ³«ÿw ÈáìÑ*RÉlàÏ}<£.@ãÙÊÿ/¸™˜k@›Õ=É2R0¬xa@fº¸%‡[Ýø«žã·#€søF^*±ºýæâ—»Ò M¨¶§È¸o±-ÖR ö–«EÙú¦Ù•·4¯ýÑ!þh·†^ïé(‘Z묯 ¤«»’yktÌ–‡À¿¨¼ô-×J%iŸƒm•{û,G©¯óÝ=2ÙÒ¤–Í=ô8v4­œÛsॠ·çæþÿd9Ö6Û#-PKrÃS”NU—«ØÙ æ(÷S²2¹¡Ñ*iq.LZï|'~•ë8ægý»6¨ü%“oëÆàÙYxGxz_WÿòòÿrGZòZi Vxy§OáP|pÚUR*<‡MóÊF_AþFÚͺÕeaÑ ×ð 0o‚ï4ÉÈŸ½Êæsÿ” åZúhéþ' M§>(ü`÷V‡Ý¨0¯4`Œ•ûÂÂ}~ù›}xiUêÀJ+ÍKÀåCÎ+x?K¢ÙlckE÷yNØMx'Eß´Þ‰üϼþ¿ˆ'I7BÃnpR¾.ºŠ]Íà~>¥ü>%K`-·ã6€Í ¨!€ÕYÔ¹%6ÛŸ¼Ó++ôz@pÎþ?I¯ÓûÅÅ©ªõæ¢îÿs`DÅ0ºê­·õh]àþËÐ{é­7ûrgXxB£Õï;aBO]=lwâgˆ(ëo*˜Ø8?†?W‡yi’ÊDOíx_k”Cʳº™G1wÐÔáÝÛW~°ò˜t½QO‹ÑV?ÆNQ‘jÿég^¥G÷OÃIŽEêø‘ìW¼Ò¿N*‹þ·†3ùï#mÍÕɦkø“²‹G¥ØÖ|}ƒ{ÒòÏWý«¥£$_Ú¶¹ãÿñp²?ܲÁ ™X‡[w"hØžñB˜?Ž ,( Ö›«ºsÓ»!xëʃä¿}ð/ËŒ´„¸Ÿ¬N”[6.M~e­¸çöi/©ðO"ƒÅòÏ|G×ÒGK“_åz¨ÀÞ§è|°6°Öjù»&¿Ò, =ñx¦þ׋¾qü?M°ê¦ Ýø™ȨÈZƒÄçÔÛo?‚üïL3ÚSÈ|«ÔT5õÕÉÆ”çÒÞuÕ7ü ¿Cee–ÇyÉÿj=7 ùÿ'èÿhXÙª´Ò®§fòç"׎<î´ž`Tû™™Êÿ®,xå¹Î¥¯Õ±bäÐáÖ?(U ùÎ˹haáºhgËì~ųœÃÿ'êuê€ó{ªÓ&ý~2´ |²vÏ){ú´Ö?ô•¯ tMAÒ¼ñ¬ÆÚŸH5ÝD¤W3ø÷÷5A¹ùžFíÜèË5­ìî°S¶€Ë®ûÕn§wŒï²êWé•í<\fmçDƒÊ{ƒýöÒä¦Q+»Yå¯ôÉÁ8_ßÚÎ#Ö7ºÚKws^h[¡oþ—t‘4Ôœ\^Ûæš¿Â¯0ò¬î*:ß›ø‡ÿ@}y)/ƒØfÏQÿˆ¸¢|r‰ÜT΂ë¾pÛ©£O.Þ[nD÷?.üH¢î×# \hëÍšÞøx$w”uzίáɰ¿*ÿoF•¤4Ö03ÜÈFêû¤w,gàËç¦19 ¥z ò÷+ý} W íc!úº@NZ¦W®ç¾8°Óû&¿Æ­Ô®‚ O¤s’üÿŸ’¿*ùÿ°@‘C©MŸzxùßr€¯• üü¸Ç ºYÛvÝ»G]¢MÈ?Ìÿø°­^°²þi)ÚÏK¯àŸüÿ+ÿÿýßÿÜd+Uù ]éËDœ­4ü 6ÉÓ³•ÿO(îgÐÀ5ÇÒqSIK`y.ijVF]yŽHÎàà û?k·í- Í_xœì½TTÛ–ï ’³"‚ JRA$*9ArœsªšU9çŒ 9(A$ˆˆŠH H΂dÉ ¯Nßî¯ûußî¾çŒqϽß;gŽì½kͽ7û·æúÏY¬EáÀÿbN!!å(‹úß\ÿ´ßÏ¿‘M®H­M”›Àu&ù‡ èÝWQ g€s$9^á €f™Ó+}“$«†°9ºõ ëéøy® ™©“üh?Ø®hšž '":_»¼UÂѳï#Ö«Õeªæ™G^m™aWg&öóGíy£]&Ÿ3-í¸0Çà^ÏH_ÑlÎûƒcæ¾×½P'­ãî<'–{þÑÌÊ*`Äî”W©¯Ü»9ΚꃘHø% «¯6%h ŸFɆ쉠œÜEÇ5²cÖ‰‰ð9È^Rƒ‹9ù8k€€niùæ³[ÍݦE{‰ùD†“õþà&ǯdƒŸI‹h÷Ñ ¿óÜf~Ðp®¶BJ;4ÛGœÂ“± õÔÁ7V{—-Æ}©î³´có‡Vçše-g@Söóõ7^8u¬ÑëœYøïø›ŸyÛ ²gŒÐýм¼›q?¸ &o8¯· ýÎÓKDCfßIÉ6¼ùhôQ'ýnõC}º//^¿Xeá×]È×1¢ M½Ú‚–S·bAÐí¨”OuWÔœ5˜z«±^´Ó-¬oN„_ˆõó+…‹ jßî*cŸÁ Z4ƒå¶y>¸íŽÖPv°½ð+‚ùPeyȴ耋±OAœ®f¶¯;ºGcà#ùÛ3¨Ù?w{S7Vô»67 5nz{h’ªŪ‚ù'ù·¿¿•¿èKtMc#¼úöú©vÒí4 ±f(‹"}Ugéè¶Èš®O0_Úe7cƒEœ‡àøåx{×RS©[™ Á˜B*…M˺°‡ê¤óy ž>c’šáñnádDç„ÚûÁK·ËtŸöãr Nz‡ná7¼4–¦Oêt‹ãåÅQ¿;ÿ?Jü7„í}+í ¬¹'µÔàd&+íB…RåÛZJS+õ°àƒ QÎ?–æÎ L­Òj+?ŒZµìÚ?ˆ­q†°Ùû"`uµÿÆ‹('Š[–/ØAÝõe”nÕiC€Š:ú¿A"¬“þ«¶¸»Åÿ6ÁùÓþ.ö[õ?-Y{°õã6v3›éÀbŒ E¢™ÖÉ£Ç ‡­Ž¦oÍ€æJâ@Sø¿\Çó何£´†mnæQ°4j´Ç¶eê1ü*‡‹9?Ý B}P&θ¥ïʽH¤ìÅì TX«=ữ”`x 7Ö&@ìÀUx¶K:…?¿õO>eY$'¿úsÁ1'œ»FuÊÕæS,ȆW‚S¥Lqß9›X±ª¿°ŠhͶ?Né½ÌzfJ®]á›"˜`ùz(¾ yþg‹ÁW¤14¶ì¾QLÄêÆtË _"Þ£<é ©L6¿i±3xJàCvA–ËG`ÆfínÀðÀ”+‡~ÑàoãO0ü9H–ø 0Æ3f^y4hV&H«ˆôCÒä´˜_9£C¼Kxˆ€ï³?Û®~Lu †«'¨ØôÎ~ØÅ¿m 8wñ`M9õ„ë^]ñºãJÆþ)nšþcƒ{ú’üN&8ðZ } ¸+¶}zÒ0@lR©‘xÖ?`ïwçÿljÿ[M·F|QH<_á|Nv+ „¯ zbØ…ºYo%AIeÉyïËß]8Qcu†ÉS½¬Â“"™'-ž a¨²$T`¸âÉž<†;e·p|?ŽúKYð øî“¢ qøÛß »¤ÿtÄß!0úÏòÿŸÊ¬““ÛÓ›.x;¼?°›–*°r€YÍ%ôjùú8¿û eîË"Ði3…sf}Éà£G*d‡œ}?ápW«°žàRhk ¹Ì€÷'ÇsEpp]­ïáâÇ\7?÷5[ÖhÓ-N´3ÿ—lO ™”¿"*èk ¡£%„ˆÊ’Zj´÷Ø|„Îõfð_§?=i~ó]ÀàD3ÜYù€Õ‹p¤rpnPÜd” ~^)kÊ¿ócûª.Õý;(˜þÑ«ƒʯ]ÊÐqÕ7dMœ}‹G¢Üò…¦ÆØ™7‘[œCùÄÁ,ÁIŠÁD~.1™çzö z~Lˆv.Ç*ݹG úñn™`{Þ.ׯ‡]ëiˆuW— ² ®¸˜b›"öàj».Ɔßó Xg;Ëúêþnº‘éë'Ñ+¡™V‘ä9浓Lnkž?øºB‚īק:x^3׬_ ¯?·8í´\ Öµn2Å@ÿø`ç!F¡ŠkÇî8±ªÝA»aHn´¯\´?Ä/}~¾Aδ̥I*’zr“‚K{g4ûçöéø÷‰æˆ®|ö? @Lä\¼2÷ùRΚt+5ÙØs;B²©~÷ïW¢­Þ/öñÓ—P2ïEgÍ—9™f¶; V­Ý§žæÞˆ{‡ò¿©0¶yô¸_Ë?eý‚*X†£’¸^¼°*Œg}’/ü˜ Ûÿ ÿRÂÂ"p &ÛÝ»|Üã 5Û wü^ÊÈm¬–d{Z¦©vX¡ã™ìaùŸeüº†Z¥üìjÀÚÇ;x"–g²š¡ìn\Ïyðè»]%„íTÉs53ëØòçÕ€þ–ô0ÙÜG×—HÂC Dò±ˆH@ÁÙûh˜ðxD dKªSxBŸ#Óp—n—Pœ§ã·™=U’Ôa¥VgÉ;ûåÚ…÷B½+b“Of,è9¯YŠ\Èbs©K •`Ø}ÜÜ´É+Æ3³<“¦=?[#X>•håýMügh¨‰µ}³ÙÊÇDý[­¨?mͼ…zõ:%XÙˆñ;ŠjxšY$¼:QsS K:³Ò0ã–WȤ^¾ªÜ"JÑVÞ"áê•ÏßÝ-à€D©q‘Þ/:{‚¯'1b‚ nù|¡n½„ŸaÎI?Ñ—†°IsAμHîÀÞ³KCñΓߙÿ*þ•jòmâÅô„ì"¤ÜùmØfS)U—žcüûQWÅ›æyÿÁüaê{ù¬w0:†ö â’ ‘ÙèjÉ„r6ßY5°•£äMìŠî°KŠ.G5ž78¿Z‹Ç¦‹þËFOŸèÿkßÅ+ó›äæOû»Ùo{ y‚ÊÅ»!¹WG [x¹?Y¶=±{J‡cŒÄAší4PÉz;<ànö‹÷y@K)}FÛ^h!;>­=é¿9J>UæéT@xáłɕ ó!Á>’À©Zî<­B}ú³ÙbÀ¯«ÉËÿp=aµõk6åž\¹{Jxºw*†6ÖsņÀSÑd|ëyKp&Öã»Ç ¾d€¶©Ógˆrom_ƒn1a&6úè/’8ýrˆk} ã6døž1 ©ö6'Ìÿ&3€À™UŠŽÉ€#¼0&Ýíb>"ÍàWöc¨ x™ âÑÁ@ ÜÓSX„W’¡ú@ ß^áݓˆ=au7‚ÀŸ§¢7ãf°0aá‡]&”ï€ûEHõjÞÁF2íl­ „])Öþ./qúÀ+Ìê>õ¥×ì•JV‚pO?;@£ä)P  OùðyLÝ4­8Ò_Ø_/zÖôøí« ˆŽ¬d©z€L=Vrhm†±×[–l6ð YÞêZ3@îô#üÔ+PŸzTO.ׂ„íŠ X“ºÍ;Ps„n¯Ð£àóÀ¼ ö…X*ϪþMüÉ*ðßw|Ã#~‹ØüiGC ‹W«ùý_~<(Zpy<›qv³é`ÖxŒØür0ìI—ÇpÇŸÈÆgv €`njÂxÓ/…ÜóÀ›Æ±ô÷ާƒçú±C¢Ž³9GïÛEÇ!+‘fl6¶ë}¨z= r嘰UœoO(÷º5ÑÌh“a\x¼ãÑ “„ Ñcχ ª8¡ç~éͬӮ¤Ÿ>…ok¨ß¨™4·èR'Ó=eVeVÊ^@£Æ½² ¸Rõo_wQK %ë34£×¯…õ|èŠÂü滋®]ÍÏ:AÏBy'bê%ß%  űf«Ú¸{.&mÝHØðFü}>ßü² ^üEUåÐSyRú(7‘1À_ iñºª^¯¨¸ç>t*W¦{ï'°úȇ+®2Û¿ýÞå(o8bàðÚ‡yÊî$Æ8P-é„ÐtmGúɼe4ižUvoFêDâ¼9„Ô •R-ý|Rhk¯G‘®¥¯i£[É›!û5»¬YÊ<­í0¸âÛ4±t(Ð~ãÚI᥵7’}u ÏŠÆJ6µZ»D*eXí²£‰K©ŠÐ‡·W‚RœÌª?rÝh j®»_äP£?¶Ÿê r¸qúœ²x?ͼÿ%}‹0¾élZè“;‡_ø«Ôé­æŒgT¶0].ÏÎ5E,÷¥Ý5޳r9°h7˜IÉ^ÿOüÃpFSãnh¿Ö’½@ú0³ö¥ä ;Gƒ\q,þžédB·“à>u,¸· µÖw¯ ð”Fe+kaWrä¿‚}mÇÆ#0':bFÓ¶Â̵ß,Þzo4mD¿N‰ ž“wKž{Üú,¤êž¤Ó@=œ02òSâ8˜ë×^Ÿ¹uyÞf{8TZ} ím”íG$ÕÙ$LdყæÌ]°•«Ê‚ºní 0øhð9lV¥ä>3œ‡É9Þ%Ÿb¿ÒÅý!£…oíÁg» àEë É—Ø2‰fìdyHàþ½õoàï¶x}Änm¿/ åòh6t;C21•FC S•ÇÝÉÉŠ†¾eDzÒθEØ9çÚ墘úB;®ߴʨßñl„¹€]Cþ&žì’IÂm sìçCßìå w=ª­Ãõ‰‚ã¬ì¨¯ 2<„U®¿xˆ+DŸñ¶çýIHù]ùÿñâÿ-iÆìXÛ{É=É÷>ö+\k§ )â¬z¶±ÄN#öÌßÞ!_ì-r{ªÔ,ˆææË–=Âr&º‡kÿ¼Œô\5ö»uÅ ™¿¿‚ƒ…!{ˆXžéÔSè¸þ7+Å¿O@:ùÇý&±ùÓþžö›þp!”åY² Í’Ì›ª©Ø ]îÒã’3 \ñ ˜#2ÇÀë—.B©¨^](Óeaøö\ŽßDóž.€ÝÏà¯ËÞüîÊ}£|Ð4Ò™$îã$°§ÃùñziúÊ·j„'FÎûèkG±@‘`zpÃã-ÏD\3ˆxWdA°€:ÕÁ¡uŸ`ªüÝÂÇ¡ £xç$ÝâE$ÓÖ=ëêz‹s ÜÂÄÚÎÐPµÓÈ~··w¸ÛR’Gº|Ž¢‡ûÊOA›=[ƒ”¬]†ƒ5ªJUfk¢/t-÷üh.4nuŠý\¦™Î¾4-xݼ°x·Õ󽯘nлNoÅHë²vjð]ÄKó÷}>h~ÆÓg½W†˜{= GÙ¬zØGu÷c§I±Ï † ¢Œ+-wú==Õ!°2ÊÂ÷›A-‹YÕÎ^ Z9"bòÈiêRˆcA£v•÷îFæżxÀAÇ:w”:òÙ'–bÐY²ÏÔäÊ¢ÕzåœË<ë„ûåXùHƒªa?ørôBÉ”)å+•i嗲Ì;§ÙØfÛ½CjØEEë$D¸ï}©·Eô|z÷´§&´ðƒUóÉsÔ1²ÌµC ”¯t´_›$ I>‹}/¼p*™îË ƒC¾Øü˜Ò-îF%x A }•÷á,í‚q|ƒhð_3ŸiI¡­#À\»ön†$à­ª#ZéžçSüü=èä€ïpfå(xµÊÖùþP4ŒQtgŠ¿BÒú5¦,²u3.%æG©?8— µ$3Ø1]‰Qicôëö3ØÅ‰õØönÅUuˆó7ŽkˆÌ;8Á<Yð™J#£„ýîx¹ü+?’ÅXò«$!.§üŠÅ)AŠŠ¯›o’Ï ¶^ ¨Â±mJ¨Ä™3¨$ßï¤4AÁÂÅËD[>?ã‘oÕÖ¦e4= þdïÙË?ÁQS‰d°‹íåH¶99ƒð|בÍHµ’3þ;òÿ#ÆŽÆw®^XˆGÂ"9"Ÿ'*¯m‚Šå°"&áý«Í4põ‰EÃöÈË’v!Ÿ™trãÄ“îeJ6¶Ò^U:ɵÙÛ„WÜÈ «r܉ ‡®ü©ðsJøË†§KTèoš?íŸÒž©ÔqfÐÝìć!ÇÕlO¼ç™Þ® €í ¹ráyc<‰¢G6¬ÅX'jVËïŠ<‡yD9ؽ$f÷Ž||oc¦äÙM·²pÚ77%­]ýësÔïÃmúûV³0bL±çB\çGš9”õF€x~ŸÕ2\én>Ï#Pûª}È´™±çjœwDPet6Ü+÷‚{|¥d#~„„ØÖ0–HDJX^:²ÿ.Æ®J`÷H tF‡.ƒ$Éf+xÈËcÛÄ üèúèæ/R’·ÓW8À^§,@þáòZ0¶×f9#!«Š;ì7ª‚`¹uQ¨ñÝ«3eVïQIG.Fàk¬ÕóЙó¢@¤+Å"Š¢)ügšÇ Ndpö Æ‘H ü¥ÆäwXB¦„ ¨|:ñSInl0„ä#ì7„ÙŒUpÏ?J4œ”òµÎÀ½¦†à"^=|èðpðEœEƒ±gèsŽ<©‘Üå¢\…†ÌÊžrÇ¡7½Ë§—Ýk´\¢–<™“lœ[…ãawe\¬3LÎy‰é‡ )©¥N5ñfbû¥+~øàóœhòr{Ü# ½Pû>Qýµi7ÈK!Q1!ØÜþØ—Þ3ÑXî —E‰E} Θ³TùwþÌ켪õaß–ö®b÷ø‚më+.I5%df# ÅZÓ=§”“ä)9€B³.ã¨yi¢ä¶ˆÛ °Gù,×v—þ 6Èyw›²¢/оdÁ²m¼ãÚôÈÞ¼*}ðúPIaf˜|},«-þþjéøÝr tß:?ìƒë’ˆõ±ü5«óÃ[´xÑi6ú%`”ã qȲòIĩĊœ(qÂ*õCNU¤„ížH¡Çm‰Özfâgz§—Õ>Ý®¸ÝÐ~Ø"Ñ8:g›Ø4ü=’›¢Èƒ˜[SÀGF‚rcÎHËã5×ð•FÍ”¯¢2´K¡ÜðûñÿcÆ¿ajÐý:ø–nÏH{1/â«8Á6ÊGÝ52%>2ÇèÍ?ò³G~ùç1®ìùÛ÷ÊÞ1>º0Z‡ßz@À¶oN±iHIc/üU1!O?·‚¥< Ð¥›>ÿÕ¨Ñó_#nðËÛþôŸkÿþÍ?à×ûX¦¬1åóÅdøzp4­2`>‘V€ºÌ5‰iT§t¨'UØbx½¼²|€»Wé%‰Çv ß ‘Î(¼Ï T*ÉÈ!gðÌ×»áNß°#l7‹fˆíäÈ`/ƒ|±cV°žjL¢$½ˆöºC]1 Þ«翞ŠV“¿y1 @_>ú#ªQßHyÚÎÒ=×ݳM\\"Þ…x®¯žmm[¦‹²m.§J…y²-ác9 ìzÕ Ãý¶'ÓUªî?Ë6NÚì“GX¥žŒQžß‹pÊ»3~\R1ðeãÎ ½d»ˆæ¢:g°Cq‚/”ãTØqòNtv¤^vã­Å@[W‹^“RGù \`œ;µ^Ökô`ÀaLÐæËèøúì+C:혳ìkݸ ôÎsAÎ…[…]üÔô„XÒy{/1‹¢g·‹oMݱ[ٔVx¡l—æž©Ý% <$f5˜•J.A©¨zëàþ¤3MB‰:~Æ--jô‹“÷¤}£šœ`ævç([õ¹ ï`ñ't/^¤LÆÄYÞ/"0Ç·슌D:ÆUàÖ*ž—6ìë9›ä£höÑ>Ìr™#›ºcLŸzÒÎÌ1ø‰~vñôÿñ¾,Oè™KMŸŠ òy8WeHCÐH•HNÁXÖ êWïŠ>B¯2ú–-ëЂï2YÈjËÒ¿ñ§Ý`Ùèun½"NIQóùSš?Ïgÿ­ö.ÎÆõšÃw±¨KJ'^=åz¸*ô°ÿx’w{U‚{®‚k£»6I«@ªÂu·±*lÆy&® Å!Ch upß/×áÌj8¬YŸ¾ˆrn"!­ýùòzléú9öb@óa‹q©â¨ˆ«þ<WK†êGp¿¾»u‰»_8!eÿZ:[£‚Ò)„Ü4o)Úæ+^°Ø Ô°UÀlÙß• §4Ú¡¤¼v‡_ &Úg£Cp/Ò·„®–ã¤X¼³SÆ@¸i,ÚKoZ:´Bòõè žñ4@CûÿÌßÖ=è…ôJú(mIÇDº2(R ˜–Äó;U¿…Ä3YØ,Æ\a¶Û¥ úʼ| Þfœ·Í›Hìd'“u' °¬²<=E¹å>{s‹®Z-ºÁ?d8j´.Êü,aù2ŽŸ¸tñåt‚êÔ×ôîT¡U²ä-Âp§+ˆPðxü»ñÿ£ÆÀÙ™ÁyÙç*?Š*Š–x97eÈèž«XVÈçn“þÃù7NM>øÂ^´NV}-k‰öu9‘güÈÞãP æUûñãL¥†ÉcoÌ3‘÷‡=`Â_–­Wûura‹7÷Ø _/4Úßßlþó:ÿÝTÍzç…f[ˆ ·©§ãú2´‡o&„dž²kQ úáÙ"À­ªRVóÀzݱLýâ%Þ¾´a€Ž²×H³EZ\»K/ÄXųÌʰ¥(÷žø%{k%þ8ºBûy="7îHìSwg°©—O‚i¹Éq7yT˜÷7leA3£ùüüO}Y!\\ͪA|îi‹í©§#}_Jˆ%Š?‚ðã/!¸jå ä=³TøëJãpÉ5…Q¦ý*{Â!@šU|‘ÈÐ¥i¤à±¢5­ŠcκëPõúïÓ&ô DŠ^.Q“|2-o¹êj³àr.ä 8Úš¼‘¦+K"'3LuŠø+ŸÙ0ç™cªrv@ ½µJœ¢Ù=?—¢#NOäÝæm.ÎïHt…ü§7¶;Å(P­÷E¾b§yßz¤;ùz|¨·ààHÞ J "“£ê9ñH”e³Õ÷í¨iov©&UnR8Æý„[oàF¨k«R×ZPÏyGCfúÒh¹ñ‚€¶Ú³ëÕÉm"]6 ”þ*x×üüÝ~œÄ;±ô…cD›­lñ'æ`d[e³w†-ÊÚs‡ÞÕ†ò§µFE¢­'ýP7åž‹Qj®^U¨gâƒó+øty¦]퓵àò𶨬ï–0¶vFs”ù”eÞySC¾Íb¸,æ3 ýa+¯œû/üõ]‹·JònÑÚ0\ãöWy´i @þ#ëÞë÷ô×Õ?šŸÁ6k¥>{*ŒOc{<íÕ-2€~ÝJ6ˆâ{EK­æ0¬PË ª¦5[lä ê\MmØÂÓûÉW–}Uêò¡HÞSBØ«!‚Á‚OøÍr6vOT‘5¯ÓJ ›—²Õí3C 2mä¦J‘ßCØp/öZšÐ³‚3-,+iµ/_зžç8–µºƒ‰âv¥ë’±“-­ÕÈ;­j²am#£êô `úµ}d73/µ>A††yÔÅÝ6 žÁèÕæÎÀ…B<ÒÿÿºœGÄBÐã/ߨ½ÀÚ10^é­ì§ íb-OéÛqÏD-“ND=ÄüÔø–„ï8bïí:µœòôMB’³ß #Í ÷ .âä<ª_+âØ}û*s¦´ên~­ï®þ;_ {#щ?æõ ^ÞŸ)ïÐ8?‘|<‘Ƽ–Bð‚™à÷âÿÇÿ³ølÍ*6oBòYÓÎϬ¾¼’£½$©ïZWñ?œ¿6 ™òýc#ÐêÚwåg™7`o˜¾raÿù³ >Ü|s¿¨KÒ†˜ ñ_üZ½@ÚÄ9GýYþÿ¿cm§¤’O\ ?…ã’Z•ÂÁu¦ê^E¾•4J‹o›jæÞõ?¼¬³Pî/Ïñ˸~‹z¡\Ö“Q SÌ!0—)±XöÀc)|xŸ GõÜ\F úv2á£!…á„£¾çâÙà# gÍ8€éhzwg]&²®´>Hȼ`¶Ýo§ï’ ²ŠâNþ!¡&k¤>ËÆ'¨U:¦r ò— ÉŒx[´;ÊF»yMRÝSŸóàKŠÝðZ8‘³%Å—ÈPÁ*ÂÃûv/aüü Ÿ=ЕïèNÑà£F8 cL¹´Aà#Ñn­y’þ Ê2¥m§R ¥œ$õßûËp±`ùKNñ<Ë·ùb2¹Å:Qà<¿uÏ›~î&ÊŸÏP1O­ƒŸ-M>D$¸ œâê3§ZˆLmóÔ€·IA,à™ì¢N‘ˆbG&UL©Zgï)ñå¯ò}˜ü©¼‡' ‰q)YMòH†ÓTï}?ð“ÝvR·> ‡9 Y–ý¢Zñ‰Å:ôŸ¢âœãü^šÝ *dK| £t½ÁÛZVå `^øT|Nƒ7Û+C±ˆE.¦™%_k‰E˜†'‚V÷‡“èÊ ÿ šf¥¦Ÿ-lOAÒÞèX‚xó4°Þ}I](`ñ?ðçiL}ÉㇹF~´Á3pê=£Ï ¸ώ뜴h'ÈÝÝÅ÷“&dm aóH—ª,2m®4Ú7Á—Ê;£¯ñ’·‹¹uŠ>²AŠÞMúyW¯ï€úÎùtxîÄù X¬Ó<‚6“e:îÐ&Ö)éòkåigŸ÷çÚ¿Ró üßÛüßF½âöÄÍ8jõ>bËù!f+uø5ŸîÀü…為ó¤°A³B“8LÔqqHëä‘Ü}]úeŽQ †X63ùø—YßË<íèµ™R©TéÜw€¸±±2âà }5» spCjMtÄ+²iþ)‘~nýH3y g¦Í…¥Ó#ý€d¼,²LªPÆå5Žlî—uñãg$–ON¶òfm c‹N/˧ø«i§Zï9U=Yg‡˜XOüørÏum¦ð¸ßÝ÷Ínû'–Q?Y!"þËi£‡ »S5¼_,‚"­OH²æÙë.®MüÜCK·<3ú«Þ·ðƒbâ,Š wsä9.ĉ—y„óì :œfšžé…ƒw¦ˆëä¹á]7q¢ëC³ô# /ù^(™Óš˜Ÿ¤òoðmÞ†‰°3È¡„¾$¬å/yížì#‚ó‹ÍS%É Õ„ãIŒ²*â×›…žöy•çÏO×m’«Oݰè'’÷m+Ùå#ÕæÙ2­R>Ìö_ºVö¸ZõѰ^AðNò’;+ÿÁ+±·3L|=®E &Øq÷¬À^g|ÑààåÁµJm;OAü1ûÚQ`.£ ö°R¯µºbs‹•i“Cœö©7tã©Ì¹Yô9ý4«:>䞆ͧ~ûüïËéÏÕË[’Å)¦×3ÈÌL”,׆nbù#ÒÍNmÂÝ,(ìõù4+¦zfï¡›7;ðnöønÌáÞ´4¯õ“›Šó€«®Jñé®î00(û‘$DG ³øDŸÆó¥ÄéÙ ¤V_ ¶ÿ!‘=.>ò°UÔ‹=­íYX­å¡ÌÚ;ázèa*žŒx¶/ý«OƒpÔ}Ňx¢Ÿˆ»c”¯s5o¶Œõ=ÚJ¡G0ùÖsÙ×ÀJݪ-ìH^„KžaØ5-ø–lIA,×”1xýû÷âw/×ÝJÔêyO‰¦ÖÜEÍ~ÿ t»Î2¸¡}O&QÇüí>@º£ú ®}üïùëEéh(ÏÐÐÃqépø-‹0-¤f)ùfP3<WrÜ/M ƒ1­âöÅÖ.ê„Drã€ó¶AxÐz@·§»‚îŸ"r¤Jó²Û<üöãñ$‹ñ¼R°·%2lñÌÈú3›¤È ŸWß>䟗>Œãï^úò°ñÇélÿØýs]÷ûðÿcÇ?C¾³…Fñb¶³c êf‹?Úgè-Òpÿñü¿=å¦/´ îͧtxmŽa ßMF©–õpò¨À« 8kùÍ© Íš¾ Ðýµ‚áíîôçô¿R³Mü•çÄ»î{ §ÿ2¡ñ³qVF•àÃZeØÄðkEë¡ +”Üæ «¢}]í©ykç/n"‡Š|1ëÌÊ…Ô»ñt›PGù£}ÑlHÆd–Ü&9£oh·fcÓýÏí:ÕÉÁ×^=xDÑõé)»‘è“ÉQ§1¾“\µŠvä<6ùpK~JùâÜþÒ;úÎWgßB yû,ÛúÕ™€y%~£#…£ÙÕ£çÝ)‡ž}"Y¯ˆNâ7`’ñƒªYüàGý>ÏòŠÛk^ÞÁÄm~D›a…ºÄ´¬(GÒ½<#\'¸‚mf÷£|¼&ýyýîMj€ÚÜÒà&Åx¯ˆ F @}]}ÍIuIÌå{‹66q¬Û½‡¹j¿K½S®-”ž½U|áö8ÅüÂÚÐMâS–§ñïáßvcKYï9u‹j< -poj‡_ý³ÏNMl¡Aï;ó…]›"«`¤židö´ï’8 Þ§ïùn¦´+’°È)ÞŸD]r?2Ç€I½–5£G”‰Db¿Lèxëa;^“gÜ;5Ïw̵v¾=(­5û0¼Úö¢¹jC“eÊŒß]÷¦‘^Vu‰÷æÕ±dxæª מ•:Þ¼ÇÙ ë¢[ß¼ RCëÆÙH-+š†{|7 î¶«M=¸"ÿ4ÒR_ÕýœÄ}ÞG®öœ»gk°y®û[yˆþÞÚìFMR)IÙìâ°£yÛø"Z”èFݧÒ7¤gûÅÇ¿§ú›BµM@xˆÏÎ^߈ˠA3GÎ#ÿY6Y±¸½e7ΣAìͺáægªaªÉ"å‚53 è²Tàá ºpƒÿÁ²vi¿‡Ðê>qϳÌû¥Q¾žû,Û~ÁËs~pøªeºzÎ>,é¼üJ‚þåu™Î=¢}–ZɹÞ])§˜ %ƒß‰ÿ;þGtU`ôõôÓ» ù:F-9ËÿÍž÷?Øž¹±è”h]hýþV˜J| 8|pÖo§b`öC,À¤Õ’„~C:ñZ[†·÷Wê ‡›„?×ÿý?b’ ØAS < ÜU\íÇÐHOC‘”J:€°ÂKNß’D?\]|КÇ|7[vEˆûa㯵ø ·çàV½q’¦<ˆÕí‘7G±!U"{øÕ?¼oûY…- ÉõS™_-1þFie”µ,Þ]€òÖÃ.w>k‹óŠip¯²{«.Â!J¢ÆãO*ìÖ'4À¦¯BÿŒºBôCGÓ[ºãV@ýÑ@ ÒNýÖb2[ƒ*x»3Ÿ56/î éërñùc¯œR“7ÙΜ¢Ð÷û4Ùù¥º“ Ø0%/ŒBsbÇyký§Àã4 HVßMÃÏ x A+¸]<2í‘äïkÝAã¹Â[g´x3Ôj }‘^9 ž‘?ë§ÅÄy':9T.°xàÓCQ-€÷·Œ 8\V¦ç9œ{–áîÛüa ®=ÒË‹|}!Ëú“¯ÑcEÇg$ vi³¸@ºbL¢ÜÓçe:éØ1^ƒ¯ì£ÅJO‘- ðóª0ãqdð¾ÎŠÞqóàÒÑòº iÝÂ^uÃÇ·Oµj–mÔ¡5dt\ °¢‚wTÓ‘:7ä=”|4žÇ<…À%ðC:åt\d³LpC~"Í ö¾`xŒëb·®Ó¢òÇùB§t'w0첨Åè2~z‚Z”s7g^;)ÍMóÜ£yù €AÍ—R=©5³89þ•¿?³>Gé @~Øå)U«{nô U}Dy3¾I7.ó`ûáûèÆÛÆXçjé"S gÑ'"¾y3r´_Mœ_™-}™ó•ûêý[’&i `±sry°Gé?kT É&¬ó°îìTu8Ê…<|±BË®êÄØqžkÜ)ëÞ¦ ÕOXHD}}A•W­;Q/ÒÓt äºí…¥Ê®]Å{cÒŒç‚iFGÈW³c€ õõǬ _ú®˜®2­;wËe€1 pJ5ö".%ъ뮿±œçΡï𞨪F¨Yæ Ë³Ã@jé©yúÜ_çoqùã™T0Ì·Hy/ÌÏw6}¥ÛmŸ©›šný㡆^ˆSUåà凉ñàY÷J ¢ýÜñÏ \ñ´v *€e6»9^„æ'tÀm*"ì*ãUšoïî8ïĉ¶H§2 )Ñf’d·Ë»ž_ìÿ–»Œ»…\Üì^nL~d2Ћ£,¨„úûóÿ,âñGÿ$£Páäˆ|ôSuÍH€/Á©Ù¦ÖþñücÇE¤Úø¿%¾g)áG»¬‚q†ýYÉ©•H¡W´‹ÌøFùézr9P·°ÒÃ|—¸­\x¸þËÚ?¤Íoûw³ÚßÙ|~åÔÌjvc‹Uâù@ˆ"3iÓW^‰â\y:jy]=@¥Ãâ“}-A(÷ó ÚŸ!аQ‰ýe¾ˆk‘rY5¼8á¥;Œ³'#ù«N׃³; Ý‹%G”*ÂǺ^›Í‡mi:Œ#¯Q0Û5èvK—8ûü‹œÀ{\ó®‡?õÃ\ïv.äÓÀ‘ †SD†T^\“>A‡¶K”®PâÇ @ÿLb£}f‡C£ºevߥi¹> …øXÏÛ<át´JVñ ôjò–2¤¼L¦&|ì·!#é—ýs) j¾f½FÙŒ5o£¦OOrH¶&;ˆ!Zoç>ÍúêôíŽÒ¦.Ì5VÕŒPYi+xÀ’? Vìh ›Žw÷¸>oø’õ[K¥t×hŠýÝXèU´„ˆ '—uZí´Èc\M(ÀAÙ:—¼K,ÞO°4Ç ß`èWJÚí‡ù€çúÚ'F¢nýäÒŽcùÊô[´EÕÓWº!yÂ6c X©î@Ü›Ó ÇšY÷c’F½*,Aâ¦mÖúؤ#sxñ¼¸DEØü”(Œ×üZßÒéEËT‘¬77Q\mÑãk òNñú xs|õˆÆª› °Rþ°ôjÌ•#^FÅM3“O"uÆ®en‘v¬ëhÑ®XXή¶¹'ñ»þš7‘®Œ}ak’_éµÎTq,¿€MÕ"€™ öâìú †QpËKe'Øv]ÕéßùW¬bP ~‡#g®Ø(<Ázv pжTÀø½¾Ž§‡l˜+Ë€)ÈéWסàíS Ã:‹¡Ç£öàžA5‚óý¡ž™-'JÔí¬Xu_ï`i•uy‰žqµýÂÙáW¥yƒ»)ß>cÐÔ³ê¯Ãoѹ2{©Ë"È—_ø 7’ìùЉä£*瓱ßÀ·ú§Ñ ´(/|û©±nã!ND“ È]Þ£Q$žÇ¸ŽÃý ¹W· j ÚŽ%o£À|êû+0¢”ÐB!g‡Ì¦Ìy”’(éà ¦Òô™azª‘kù]ÏF&¶Æb¯ÿb§1©ÔK ÑO©ßª[E= Q—¾»ÀÓg,`›Vz´8;êÌÞž¥ã\¢EÜÝ ˆ’u8-wáiÖVnJþذ®Z L»Àê­+Iïi;nJâ]W‹|U^bкùúÉ6Éé+íp5R­ºuÁ ´) Ãm;žãÑÓj¡IÐÒìòakÊ—h.:ÓêzϦVÌIsQµKòBT´ÕÈFû³t¯›Ø¾Úø<Ú$û>Y@»JÝÛóK[=4QbŽsÍ‘Z& ?£Ìâs¹Kn|ËÖðDЄ óͳKº6²7 #ÏS½Ùã"ÞºW4žk›€4‚Ïö‹yÝËPÝê2ÿݶÂ]­}™XSz,Çn*û nm™›ˆÛÚP¦•?_züGþ?öyÊ®*8\q_áY«Å°Š~@^’RWDiÒË^]…§Wºus¨-&ÇpëirãFh|¾’ ׫“·ûäÒ;"}Y×ùèy+õÑ”Z:O…©]œn¸ BøÆ{û?Ì7ÒÃ&vƒ€ßÒ¥÷Ø$бïò²i9ù-RêdVÌ5BÚ#«Ð7Gè [—SWÔʰ­ß¶k4ÎÅKÇCÉYóÁ³%nŠÔÏ0„.˜-׆ˆˆÊ24wl¢€Ö­¬…J’-´(B[¤Ê½kûØЛA¢]ôª×šTâMìŽÞNxY³ Àî”7) µnA.ÏCª»ò[-x âöm ôÖ°%¥?MæGdI‹‚[ZKm's.ˆ±4ž®Ð¾±h ïÐEX±±Å=Bj}\]õýÉb‰Š>Ä3ŒüÌ»Õ@K]lEQ==ƒ17M£h,0Ç‚Ëg—ëͪ\\›ÍM<ßÃò®×¼8À¹jRòºÂàfi 0Uù&zbŠR(>-t; ¥f”ó™òÁ ^C¡Œ"犭Ïz¬ã™ü·Ð¶hkDZ½:Ÿø ß>x# ¬Ïc‚ãózÉrŒNP9xÑÞ–i”L1ëÈ?—‡fwOŒùec(Vx»pH„æwQNϼøzž²u› §Ô]Àwy]«2IU2šŽ«¢È›*ìC2GOAÔÓ…Ï–ª, ðÂWÀ™/çÀ¨‡@l–à‰OÀFEð‰\²3¥Qˆ"sœm÷¹¯ïÑŸïoTg%y §×F¶Åú\êuv¢`†'-Т]frLOD„w‘ÂXç"»K²çåŸñùL+Œ|ê…rnÁˆ9”•Y5j /ôè ÙÓǼ„]bÓʺø•4=œ^ݪuþ(¬ùÿË1…ô³1HIûe±ò—~ðËÅ‘Hô_n‰r ü·ýé?ÿroˆ¿¼üŸwÿÅÙ×!öÿü×3"Ðÿá´¿t6$ê/q€ýþ‹›Ÿ[ì¿¾àˆø7g õo­ÿ¥þûæ/ßöñèmèøo.è}z¿ÜÍ_îç_]~yÅëÿ´w%\RÙúÏ=ô#88ê¸ "½WWwך™7"³öî®ê®Þ@œÁfPAQQ\æÇ½»DDF!ãÏ86u ºª222#nÜí»7nþùöxþ°ùNàÚ^×@¶‘ìZCáPë“_mâý¥&Uëu´Uª€Ìj°4£Ø:±…ÆSxZUI­qF5T*ÉFFü=³ØF.å”tZ= ÖÐyÊØ,O­Î}•kÓÞ˜`÷rÚ—? ƒ‘‰’éwwR+tïü•'ŠG€¬šÕPÝ"ýåìJè'¤õê£ÿµ+]º)0D*£uVà9i®UŽô7¸®h1agÆð¨Óœg/—å¸ ’¶Îè3öÀôÇn¯?–¦ W~Íw‹W… ç‡ZãÜhl‘mìàUpft=ÝÆó¸GšÈèÒ´®ñú<ÿË[¶¼[à,þVbs$‚|Íèš8\¤ÍŒ¡¹Æ[.Œnœy\úßÉòë_OwgaÉ"æÕF]ý=÷”ì¡,ÒŸèèÖ²aÊjÓìS›dcbÜ¢h->uúþ¿ƒôo¼WECqÚ3®©]C£0¼<ðöèV!×'ž-ý+Ÿ[™v›"[¸¬u.ë™ï»"úç"#€áÛ¡õÿ*âš^¿PÿÏ×ë·ê¥I’=èàpÓ°TPéÛÿ²àDAªW_‡«ÿ-¦®j|«ý›ßa!%çÐw½4µ~ík ¡X xჿ5³M³²]¸Eåz±Š;bgÔŠ_µÚëy!²(³oíd$Gjݼä@ÿçaqÁƒX}ëú~ã/xîݾa\îoÉUŒãIn½R¿žAA: ¿-{¤€x08g8Ø\¯ŽQÛ¡–ÄŸH_éâEä~{ùª^ÙÆJsb_TF(RtŽöBc3}™Ø+R|k RRû 3T,š±áËß»ã_¡"u÷ñoÒÜ‚rZé8]°Õx?®oJk¾s}„ïê[¦ÿ½!«~År ÍTˆžWH”?|·(…Ð KHö*gbbkRÒkàVI§A4;6$CÀ(Í×O éѰ™„ôïê ‚µ.Dh/àÜ^À n¶ÈârÝêV:"¡ëZ׿†æè¬/‘rl4dd.0uh’íêëGÿµëneýwŠhý‰Î[€ŸõÀ(ž<—¯ÒßÄ«•W¼®œÖ ´¥·fŸ—fÝ‚n8õÔé|øÿæ~­ øº‡¶.™…ѶA3ÈôEó›– ªØ••gKÿŸð.:$`ߨ_XžXRóøFVxóûÈ“Ic›¤EžÂÙãlåÿ¥ðÂýî^¿ÑHÐçIæçé  ÿÜ%û… Z½¯Þ2³“ý¨ÞZ†;c ÅFNž†æ¥9€¿ä1Û‡5"|Ÿ®=ßëÒ.\9kþ«µ~ZÜËù€3ü!ˆHÔ–G¸‡å ²<éxç@€ˆ]C>è~©u8€Uëv"n/mKÞwž>“~ñ:ÿ6w"Y¸j"¿D.œžù™¤y‘¨ò’õêØÜF&CK{cÄ.(«ÉÔ’-€J U‚ Pif( señˆ¦~H‹v_SkD“aÃiBÂØ*XäE£0…—¸à$ò~!·gÜm‹°A¡Éóšÿà¿d~‰úú¤NØ6ÏÝúùýVõôÿô0§ÕâÝ{ïîÓ °Ûd}« õí47 Hv ©›˜¬÷5¹ò„yTûÔBH^(SI óyb/`K‚Xi¸¥‡å1·]™tâÇ[' ˆ:w+‰áZÖ99÷é: êDÍfBî ².èªäÔ!Yœ ÈáLó±èÿÀÏþ˜®OÜÚr"Z+#þ Áû‹–gFÊâ¾-X§ù¸ ‡ò<à¹ö^ìÊ88•§ž2ýÿ…y`ÉÓGJ5—¯²kY½Z<ÊèôÔ3¦ÿo€îZ<È“‚p ”89-k¶ „þ(_ð[¡1x,-ñ°ðÂýþ^¿Í¸ˆ¶`¥†ºWv„ ivVÞùº‡²Ø° ×É)€ïº´ ‘ìF­‘4üª<„·*áÀ¦éC0ÖCÃp8æî¤2ÍéÇvc ATÄ®LdøGæ?ýS GFÍï.‰––v)ý˜—vq˜,ÊSü‚ä,†_ÚÙ9ü0¹™»¾4ÌM;&ŒÍ ýä ð3†OBº9~Êjq÷MÖÕ ëóW˜Qz ¶dµ¸‡Ú ÇOÚ(:h—‘¿2FÕG­Ó‚ô¼8vî z»;×sWtž´1šKW!ž·=ʰ»ß§,4Vvéè‡`“¥”fàã+EÈÏÊ{_õJ¡¾òKúÛGËEPBëQZ 0‚®UËôD—€k¶ÐúalŸpIãzH+SKm5Ç܆ÐzñÌQÌ‚wàÅ@éF]älGa÷ G6›Ÿv=8ÀØtË–Céùs·ô¦–vPô¯÷ºdl¸£hòŠ»¯ GT°ãBz¤´²3Cÿû3 ± =ïõ:G8ëÌøw^ð×¥)Ùõq8ì—~eâ®âÜ[¹àü!£¾¨4殀|j¬>]ú;þß»âÈöÎÌün.4­2Æ¢Œ>ñŒé¿þ1C‰YÁD":Ž(¢©ÂG-ì± Z™ò`ó5c¼PÿÏáë·éÿsRÒìì G]Eýƒ²X'áH™‘€Ô¶ðGÔH®¶é™·&%Û@dß+ȵaá¹K–»™áaö4ØÜ®«Mf;0uÛ÷㈱>gøþB0s6GË{¶´øg¬ø ߳ꎩEìs?vɪÝÁ!_ÛR¤TÍvn0§¿ØÌQwsTõS¡W7;šz§)%wþˆx N#rsFîYR Œlˆº‡4NÝ Y“âiWHº»¢ëÖθðWÂñ”m¶уÿùž½†ÈÝj÷ÜØ t´?7!wï-Wt{2Éã£øÜä¸n¡”ésÑÿ³ ¹,ì¸P¯™8Bf'…3ôï |$…LJÛ­Y‹•@Ð#GôAÕÔ–¥\ m ÑT(pX¿4dsÀeJ·–‡89ð-¦?GXØÑ¼qÜ*ãœ2”¦h>‡ôÙÛO׈þy‚ÿ.FÜ}6båD Ûà¡Ý9ùôÿ÷V€Õy1UGE)Íñßü!}‚! Œ¦y¬›”çÐa6ƒ\kçÙ&à­Ö¶|:ùTéüøp¡øóUþ=auÚåtô©›Ï˜þ?))ˆU–ôà#Á%IïƒI«;(E² ”'Ø.^Z/Ðÿçòõ› ÝRÍT¥ý~§zB( õê·v •-#F/½ŸZBF—ßؼՙa{ZšJeùºÌYl?/î­×(ûÇó×)*Š€¿-íþq,PP³än+­C3ÃãþçåÓÌ/èi ›ôâh_èÌó¾—œì6­oÓóß¿DBµæ¢¯øýÍŸ€]bÍÑ5’”‹ûÀAFñnÓ,2$lÎ o˜¹ê„˜^˜ràY³B¤Ô…#N$èŸí{mÉݯØç`(a£Ûe±tâAZîî«ãrêé7t„M5ô“›¤HÝíu ˆ<4½úöÍI‘#²ô^LÿÉ­Âgƒ1ÜA°„RØQÒaúK~qŸ’K­sÎEÅsF% 85£®‹Ý_Üò¨Œâ@³bH@Â.ºÏ§ ý­×ñܣѹo-p2›%¹ò´ú3˜KI%þ/t0´¦ ÈÖÆ/=ýßxÁÚ*¬ñ8…­N0Êý#©täœûn¤ÐJPl׃RI ýùãɧHÿãÈÿß 8U$'KR#ýÙñ'›“!Ø8÷¬éÿŸÔ0Xã’†*;Û2ѪT´*›ÉZ¥+ÃfÉdSìJh‰þ¥`+¶½Šk>ð¦ZÚ7¥`‰#~Âÿ¨ÛV³=µ±@ˆ>Fo&tK‡çG›1Û–×&°o8¬—öß§;½Ÿ—b¹}„Ôî_!}å'†ú)%H2o³¼]›0óáx³Bµì1hÑÜìsR–€höMš3à½L`(6T6Íñ°ûÄпÎ w¿1È4™Mºi‘¬Ž»hù×ל. òÃi¾0"J–a­÷;^6‚Øåg ã([ï4îuf¨¥OEô¿‹ôç$cE Dh‘ÝH×*xO¶=Bg²Ç®]«>f„Kˆ““Š ŠÁ™~­êT2úI˜êléÀº|T4¸Sö@;*€°Ÿȸ@¡‰þ¹xú(È$Žõþo­KÂNé+ÒßÈ'>ªþÏ9 xœr!‡Q|.Mß%¼åÿ¡ÿ÷nM†i5¢‹j«Õú2ö ù£ËôÆ;YÞ3±ÒÌÞwhÛì3êËùàje—Œª5žý'ÿß!>fI/$G¸èÚ…luAÙ>õ¬éŸR–-zt?„A’$B£—ì¾2 qDÃëý®Ë]|‚—§À ýÿ\¾ôo ŠŽU<…i%^«›nïXÙØ•»=l­?! À¥KW®³æ¿Ökôw‡]t Òö 'Kš–DNäƒüÂ@űÀ-ú¹ÝÚò†ÿL,pæäH4ô•”m"¡áÞà¡ï°¶og=…pRdiˑŽô ÀíÑ+×K$óRq„«›Ö;'ïSf•Ï'K‹Œ÷¦å=Ù ˆÚ¥2%O_yH8ßœmümc“ò‰,¥´¶\žÛ—ü:Ù>¨lR°™Æ˜ÏɉE¥©áă0V'•-e_@ÅñÈ–öm©)À»;#n~¸|sÇÆÔBA}ÖÓÿ“£N@ýiµ( µêE ›»£Ñ¿9êqºŸ2H#QŸ=î=mÞ@#j$[¤W)Ò¯h¯@ÚÜrX¿»€xñŒ»¸¾„øÝƾ&Ó_[p¦ (k\H‚‹îcÿ¹ÛU@‹¼ŽôÏ9rËø?Þ˜‘3óÒrp@€²HT~w‡'þ÷zaMïÞ!ýÁ»{+Ó‡‰yzµ‘Ÿj^ÿaýÁü‰ ãüßÌ;çÂÁKÔèäS£ÿqåÿ[œ[O°ºº\¢ž­Ž,iW‚N’;zu;w+&, ¥×†½´“÷Nω£‡÷ýøm0KCµ×Çë·· æq4óÞ7³ý QzR¶±í]‚°:ŠýIkþ¼¶i/ÌÁÕO ö—»÷›2§nL Õ[=p2ãüΔ}%è³E’Ù úœzkZ9yúšöëéÀIØÓ߉Š'« Ö部"rrÑ%-8_{%|ýb”@]!,›~Éûn%›Úœø>3yü•?~e#ùÈmÒÚxm¢©7å'¤ÿ‡Û7º±n )¯ýE&æÞ÷02üOarÛ…%€kLÆèyc#ue;wé~‚ÑkŽvÒUp¤?+[í»Fúc*@é„~— ¤ÈÎAUÚzµ‡4¡4(7þI‘JC`n¸ƒ"Ó–·ùk¡ÿ–CØ ÍºŸ·TRZ&EeÉ”¨nÙ Â?®éú«¿Fÿ­i¯v+JÃê–ß Æ™ %§Î†%=\l­üôR‰ëÝç P X´¦[éH›“O‹þÇ—ÿ¿ÎúGb¾ôïKôßçõfÍùÁ3§ÿsÊR„hUvÅ»` Œƒ` dë²Òü+ªá‘/Íï/ôÿç¥yÅÈ&®ð)k¯œ7ŸMŒ³À£(/ õ×§$ÝC2/¥©¬½?XÉKñlÀ+E-íÙÈž-#nÂŒíÊ^œ8+&ÿÜÌî¢8XÊo¸/ÉzQƒŽ·ˆ‰ÿÅŽ ý?po%ÛEŽ€¼ù$àfÞAßgóslxùƒo Çí³ÿÚ!N;{{‹¥L㵟Ù'O®&§ÞÒÀeA4­^Y)ýƒúx£%ïÝF¯[}áRÎÿŸ;$­$iË{¢Œ,Cÿœ èAqÅhu †ö©Šµæ®ó¡Âd¦hêñ‚›#Ý‚d+jS´µ| nùÈ/–ææñÓÍÝŽ)Kÿ ~ÎÕúëxîÝe}­8^O^ï§_šZ©$ÖeFJ]Bü” @ôN¾ÓÇjn¿Mþ¦l(Ñ‚2/ÐHÿœÒýjBg}ª¿‹PQ ‡ƒœõ\3£ëô&É<™NØŠæÈd = ÛINÃöxÞå¿ý ý¸e=ëfL:²¾9ëý9dŸÊ´zÑ‚Ÿ?°Á]ž:’–Š=0 HyÒ$Õa§š>úkþPpš¨2ÍW>Û¥Ý+§ïl’Až5Ï>súÃ.1 g qP"5YWÌnWÙ®îð&$Cò'KtºõÄê^¨ÿçöõä@Ò¡­iVJQˆð%ÉÕÿ¶Ÿuε# Ç(•­R¥ [»r5agZËiåoŸv!Zš!l蜂“œ17²QŒè9OUé1³»þ$fÉ‚lá@âÄz!Fôf ¼Rj' šš¶§ÁÚ¨(Å_t-~NTO_¾w4€ÓÝ{®ñå¾à+ï‡JÕéóh à&l9%I¿ sm PÓ&#‘±¨ è•=Â]Œø«:«N¤¾AA•Ùñ'×Õp²zQòd-à C-ì¿ü@¼ çÈ\ÁÆÒ–[’Ar”gE˜ÏFfÆ‹`"HÕ‡J…É×tmÔ+¹Û3,¥õ¤£˜s ä8‚ܘ®NM)XêYöNÕílÈ Õ'܆í¾!ö§l)Rdu¦7ÙTOÎÞÚa‹]ŸâyHÎ]Ãy;ùm×r!:vÎåHÄŸstQût¨ KÿƒPRå*é׿q{Ñ“ €Õ-Þ#`Ä•Ü^ÔœÍAjiË©7Å1‚Öú_„Da'ð[Ý)-'¿i½´g ˆø@ÑöÊE€“"ñ’ˆ©;ø‡œ½oíªDâ4¾öÎHJîq¸Ý-g9"ýKæçM_ÁÓ×É:ÅGd³q;Ør ñë2ýÏmà§…Y™HÛ—ö g $•=ëƒTÑ7{ÿ†þéM%Ù+ýfHÙÀé~ ¬†`¶%°uÒ¡t‡£d¹dééÿFÿ¯zÑ-±]ù$Ug2í‹ÞDg§xý ¢Ë«Û³tm(LÛre㬽û”è¼ùÿ³IΛx_‚ÐnlŸ¸vÍäúÄs@ÿÿðžVÙ(ÄøU³ÁîÕ®€läðäÆÿû¯_X”—n×'&¤𪕒;gnìv|½6à".– oßh¾ ۷ƆŸÖß„k{îyPžÏ%m˧+;6fqwªöênáÏQ¡l¹8'ƒ®o0 Œe•Ú \ß0ÑÓ#Æ-›™+ qºQ$-”Á üÆ9ø&—×޼ǻ‡*ow¿²œ=84ûf>¦}’ú¯¥ˆìÝGËie•Êâ>¹û” h g™Çe?º’QúŸàÑÙ­ zœ»†JQ‘›¢$™u¿”;IG Âǹ^ ƒÕUð>˜óªc?­¾Bªˆg?À2G9DUºNnÞu¤°õyZÒ…‹Žþ»·!”þ¡[\Ü. Ã’’ÀhNf„W8~—ýǾ»2²P·Ww:¦, Uÿå¯ö»ä6Ñ}S.€Ñ ëçekÒ_;w²&#ú|ÿ— €u5d{z®Ò/ÒßíÔÊ•&êsy puSÁÅÛ8ß[t`íµGÓ?ý8ùnF½Àñz8§q%ÏZpà._™qwA¯áúýS”~¬tKt”¼ÖíïOÿÝÍ׎;ÿß§œž¼òÆðK\-/l¾o>{úw¯s–!ÔŒ‹Œ¯Ž)™öñÚ ª(Ë>‰ªˆ¨ðÂxN_ú é‚BÏrŽ6šˆY‡W½N“æ=èû^dV¸µ×ðg žŸ‡[;Ž™sÛçôѯp~Vm\ˆ¶cÝ÷¬²+aÀ˜Å5Ô•÷¢•ìÖy¶phaøËm—² ÙÞÏCøgu+½(˜€øÖJ^|™zÞ+e™oTJ.dW®·µüÞþ§ŽÏÔó÷)@ÿ |z ìÜ|aT3?÷3‡3)ÊÏEû;¡‡Þéò¾­÷µÞ”ëŸ{ïß4á7Úã*ÙHÁŸËGœPæ™rw²ó{—¦¼úŸm²+üøµ™ƒõᬠh$GYüfr ³vsn¹Ó7e^ª½QÒÿö®lí—•‘¼š}²Gá3—åÝ´ ÓŸKà0V¦¼‹?¨x.§ zx e—¸ªÿy¹3@#ýsÿðyTÅÉ·ÛßÙôô)ZÅÒ_68Á^<ÈÆJÊ”¤ç›ißef¶a{œfI¸ø’Àe5$Îü!öYùëÑõÜU€ûàÒ#éÿÀ{˜²öþ•©iô!žzð±_^yt¿­W<:ÇëßÖFÑo%¿°ä~ਓ¿?ýïý/wþÿþäÜ:Èò¹÷`ë ÐM{ö9 ÿçH+[Y©&á‚\ÛHÍ0\Öµ!˜à‰óÿ½AøÂx>_Ohh´ªŒQQmT²Í¾ÎUš¬WÚ{»JW—­Ô¼‡Ú®^á-§Ñ>`{_,Âì£>ÙïD–¶n66–<ÿ`:t+†0·ÀÎÇÊV7{±e+«*˜»Ùú| ñ8hh³B †áDŽ.ÎÚÙ†C"iÐNGeze»[ÑÊÎð¨ê˜Löóó_ö}WêôÞ €ùóðMa6^ǹè¢+sö»eë»ÔR;ŒèKˆt+$=®{g]Qn-F¨Õò8ÏœË(ô:eOgiŸõ;§ÀÙõ”|Ç 7% ÐvzzøG†jñÄwT4ö F襋d}ûe §¯LбÝX†QÏX•$µ%l=Þ£‡ øiå.ÚVbúßï…}]ºøé~GŠJr Ò>Õй²;°¼‹9K³aÀñ%d?V¶z¦Ôø~§¿{JúóWéÖ• 2|åPÓÃÜC«Ô&›?²¾ŠÛÝühAªÈ˜"ýÙh Ü@Up²Ú/Kd\›ÙðÞélmL„:éë¾€§øûË¢ÿ·…ŸõWÖ-îVÖO»n2‰De^–åÒ¾_¦“³õ1u–ôJ<À'ó;ŒºÜNhÝÉß›þ¿bÉ{ù¸óÿÑ £çß%Lhýp@ûôó@ÿ/_åUÎLHõB!Ïä1™¸±:¦Xƒ¡'|Å{ÿ^X€W&Îç´‰§º\u<¶ö¶;(u­T¤å„¶ã:›ÿCa¾ÖŸ9 èƒ}õ×ö>¦ŠßNÊdÉÊe.+ÞïUáæŽ••COÝtÙFŽÛÚ«S[z2Œœô½¼Ð&ê¼ 5~úWdîC»>™ñ…ÿ¹ýBþkÊéf‡ }otb­ÇŒ}Z$)´^½=nþúw-€ïP°îäí©Éc寽ÒvŸÖ×>6âÁò#~Ä’ÀØ:1òd`Pê;:§0жѣ§I-[Îâ!–tCÆÿc0l€^(ÆImâéÀwË ÄñÄ‚gœ5UÙ%]Y®¹u1Úw 8œgO’¼cúÿ˜g†]h£ëg>î.&ÅðE²¼H} zùо½CBÀ!®z´ÞÛdú›P€M‚Ô×îå’>º=ˈ¦„ü³¨5礿ð‹»Ïψ r!o¾’Ç“žo¶·ÛçÌh¬íZ6.”q%%e*g[D׺]2CþWÿdÄ|°V·þôKú»-ó¥ÖQÖ mþ„ô/Ñá@í f~öÓlZ¢¿iöÌ S¸¾gRÀ,ôgúß²?™%¯wþ¿3n¾›wò„+#áíœxè¿9i×ÇÀ(–+¸´Çnç%fɽ‘?ÿ… Ï.0µ`xœì½TTÛ¶®K’D2‚ "" HFP$ ( 9HÎ9SU½ŠœsÉD "IP%IA$ ˆ"éÖÚçwÏÙgŸ{]¯íuïzm¯¿Ñh5köj|£Þ{Í9fáÀï‘¿sXÌX´MAÿ®ÍÿÒÿù„ýëEe 8ƒü~U›P2×+ òîúªDY‹wÛCVÛÉ\éÛÞp^`3tÔRÀ»èd WÍíbçi4`®\~R—ˆµC‡ …âº,@Ñ÷0Rð+ºõÀ%]¥ ÿRuJŸ(Žˆ(¯Ìï|®AD³™PPw2 ´h‡†µ¶êÉî)cÀ€jÚ·¾ÝQL´o¾¦Aú;Dkb ¢!¹ú`Ti—4Þm2+¼ÉW> îA#Ö¼²‘tµÌ” ²©« Ù|È[òÎ’aêé#Ñe$Gò ®Á¥Ú¯ñŒ&^ò Íl&[ïnñ—³&¢3Å“WT—NzJ'KKñDóûµrÆ8'}ß$á§4 ,;ûÐ-» < c§º@ ÃÍ;ˆ!%4Û<œÚ›ªû(ŒN-ˆKÑh¼ñys#õH+îƒú·e–ÃÖ«ï\á#£¡Y:Íòlbbót6 ô,Å ¹ºß:E—¶—º¹CšZ*g?ö–¸3ÈãÆ–&Bx”è;L¹Xß§¬ö+l Ã¶“tö£³_jª>y0ˆÀÞÝ‹o"mö˜»œ?-÷MY´‘ýSÊÂÊ06S¹çýBhÜöcܺ¼å5ÛZÌoú$F Rë6W¥²#ª\bÔžœŸÐ å:p} ~ö©™Â$í(ZÍ:·»aàšžª¿æ[(–'—Ú0o Ìþž ½Äeµ|ðo:£Cé¬oT¨3rÖЦæË‹5‹=ÏþéÀ®­|ïŽÐA4$,Îù„|^ydm:ÊÞàøù®¥ëäüe2U£L@‰“Š‚Ï ƒ’‡Ñ‘æÉ$Á²då Ê§u{ذ–°óñ^nbÌcSëLÏÔà²fBÃ+÷öø ã­ü”“â9J®ˆç(†àîÍAÌlÃ[+cFWVÂàú®Ñ*Bì7¶¬<"/‘}óõV«T˜èÌr¾æº'_ù/:vV¨öQX0Fû] Ô‚€¹Ý XKêlAÓ,RVRJ>I“Èt¢8¾±KÔ6ãjÏÿ’8Õ@%â~áÁf<¼~õ 7ÒíºóuÌ&À0·Ì»J—µ:*ï¸n –2ê+©Ï5—wa¡•kzð®Ò~ý;AÉIñKf¤Ö7uˆ[Jګꈽ™ ÖÏGV}¦¿+uè¢ÿ¢ðf‚Ç4yžÖÌS@Ò¤†9h½ûcùc…ÌÞ]LõøW÷Á \°m@X@ØP‡û^øÏÀŸÙéKϰ—t˜[·WxGÓ¹÷U*a´kq7RÝòÙ¯‹/‘qŸ%æAɾJ—mþ{‚Ê% >è?¾pLù=Ûÿ¥ÿrLüÆÓÏkŒ— |%S‡Рe]©z†îboò™Œ‡t¹eê{„/¡p{Bçx5oÝY¥àÁçg¹ªr¸ÌÑŸ]À’þˆU­B^UŒ¹Z `‹ÀÉë‰T—ªµß¶|N½z{¢‡c½Zƒïמ) BùžRõu”ØÉ^Å€ÛÖýÊ×1BuC{/ ¾æ/÷X(×ZǹÜðž·Ga;ÜÏo! ω:È©lúI²¢B¯Ê¤³ïTþ:Âبd‡èýöÝáµ õÛD`ãECøŠò¥¤Í»+Î Âݯ­´”Œ“kã÷I. Åâì†AT~Õ%ÏCßÃè³~çƒÁ‹g`BÌ?H:ïv tØ(<jÍð†˜O+ã\ç Á};wVWé*Ÿ]ö5Ú8`xŸý”R;à$±ÊÕŸèt\<¡m£·­ðž ijA”èª>|{Òö®Vgæ¯Z‘mÛØW¢+´Ùl~‹DÉ›'÷£šÉ0½‘ªeÔm©|´ <Õšb3¶D{Z^Ì[&¯å* \ýrKÛ±­)@ã0Ç…Ó·.’ÔÜ>±¿ÞF/=Ém0 yîƒÎæ”ع6—Í@„˜ôDdгškáŽWºÉ|Ô…¹Áb{¿ %Òëêc™…t;|Šh¿3ñõ2ÜÁÅ$# 3YÅ&[±>•…ÀÂëÍ4pÑýùü5'>üÀö£!©µ2¤eŠ7å )lÉM°Ã?j°uEôZý’•Ç7‘c^1¡»`VÕ§¦ cÙ’Â/øÖýðæ ôz›D!:ëVÐÀ‰lgò§ØÁmÁL™œ…„G/Å£ëŸW´“ÎjãE€F~ëé'ä‹:_~ÒômœT{=MzÛ«™°Q)w+<ÎÊ @G±z.v‡ª0 fêU"êÄuù@è”ÆW¶à{|ú c’©—{ø¨¢îbÛh4Æ=YSψ¼ëƒÇŸV²ž^jfž* -¡•¨x7aÞüJÆÎ…Àã˜LAªÛM7ÉzÅM–þŽ¿e wµBÊ $â­‚î­`羜ð½#X6jÇ ¶æðÙ|÷W`ÿå<"ñþ ̳ƹŠ©LŸ2 9[^nòàŠ´<‰çDJ |d÷ž]›x—á“OßU{ÏNØT#_}uêóQ¹½älg^†Ú…Æùàv é’v à›g×G6<ÿºøGòYå¿§½-ñäœUeˆWdþåÿA&Ëðl?£ vHÿüQû„ì“4[´|×{¯„†2×1¾ÔÙ¸Ï,ôŒÎ“?x×”†È¦@LýÄÁïŠ,>®Q‘÷–W@Ì?4ýKÿÿn©;2,t.ζnHè!¸à­L'¨‹x_%Éã~-Wß(BÇŸš·°ö²Ï”AÀrNW\áB*ò¡€~ þ€õ®"'u˜UÂæøy£éÎ@Š:¬u“1¿bk2ñF²¿øüã]ôí[YÅ÷ip1¹0¥¤ƒÊÉ8^ çRQ‰„€E©S1{_Â02!ÍHÆñn%€÷Vý¿—mè¤>ÖÁ¨L& „Ãv{M: §€)èMÝülŽ¿ÛöhÙµ¨”¼£\°F^ì‚Ï”~Ø€À4ˆ­K•o`b‚>ϼÖÎȉ§¯Á‡Ÿ¥#dea¾Ú<‘`Öeër=s6CªR7¤äò ªÿî­Ø÷õútPsОå_­ƒÉ‘åšgø½ñ¶)y»2 ™â|Çþ!@¼\L˜kIÙ©—¢¯²r%¡«{Iõ{×5²@[Ú‰ Ñ$œüYðÇ dOV[…£6„bÅÒs¹Ôî=<Še 3,÷æ“X¦™ö‰Œéu®ÀsJÁÁš3ü]Áå~Ä=õ¦9YíxSÇy”Wªy¼Hçõr™é€I<Á½ºi:}ÕºR{Gl­uí[!W®ÁS‡fî0¨°aÍ4¥^LñAoäyŒ5ÎåÀÙâú.b_ÍÝÑâ’31ÙS¥å-úBm}“aÌ~ èkµ‰†ÞœÀZÊÏ7דŸÑÆ<(C.3ÿgþ[&m3_fD¢æ­Å»®ú/ :ÁfÔÛrÖ¡ˆT3+š½¨&ŸÅ\ÿ°ÓU“rë¾TWO8/Ê[>7æ‘sÌÍ›@†ã ›¯1õ’ÍûE¼„ø™çÏ[—|¿rëÇñó‰ãFÙvˆ—WÙF̪‘‡_Úïu¿K7Ë1"%x®­§ ŠùâWêùòWrN} >› ŸÞ*E¢þòÿtëç2¥®™ª¶© þ.©÷£!ÇšzåÇ1Ùâ¯ÿûYa _»ëAè ÓgPÓâÆp¬[¤yú•³füŽXt†xÌy×1&øŸ‰þÒ?K^¿n‹Bck·ÂÅò9ÛbßE{šÛ›ÓØ«÷ów]»ðgÄ:Œ/íâgI¦RÓe5—çÀÇY’¸?¤¶2=Àù2uþc{0áóS} ·i–6±žÕß<öQô~\\Ápáy¾ÊŒîƒö¤*~¼Zƒ!söV'`¦(¥RŒo„óovãå0ÏÿiœuíñÄÎS7ÁËý3 á±cT<>7yKsÂïÜø_B¥nƒÑÕ¤;ôaͼAÀö!¸å7I¾ÛôÚ¹òû0>³wYÙÁš¤W Чjš)XÎÐúògqúWÕvý3¡uüEëøÆ”{çB”ìò\”_„¶Ø€ûyÄÜšß™¡Wœ‘`Z8MÅ#üšŒ,xpÊk9a«GÛÿµ"¨ìl,ÚßòúDvòÍ£ËÚã+¥iD{³º¹<@þ`ì1½gÿ½8v=‰ó#Œýƒëf=aœá’-K£ï%DhdˆÏN°G‡Ò—þ Î™YŒzrVÏÕkÖ³´k̲ܷÜF×Nx‡?ù>f‘µÍ²JËá¸1þPÏ­§W^lª’žm¾çû©\ù˜? Øq ÔµD{,¥7\¨ÓƽÃïýóö uM ʹwˆ[¬zÔÖá˜h!9 ³ª°e3#®U´íÒD3uØ{µë!¸žXþNޝ2VvžˆæŽQušÈdüïø ˆòð{2Ô µ±I6–Ùa øK+JÀ˜Ûz·6Ó$<ü#+,y_€‡ß{Qt_‘°¾i½ôÌÝ:í†íïF¤Yf `<ó:64ëã^¼U «{Û)åø³6—w{¸A\z¸:Ú?wO mp8÷™~Ñ¡‚ÀWäå`x±ú"ö#\ž±~?Et9Ù¸›¿£VTã5¤ßÀ¹ì1‹zêžpdu¸"¼Kj˜Ûïnæåž’š%¹÷ >à[B¼Úro¦àjOÿýA}eº™e˜]lÂŽm?NÙ**îS"Fnö=WÛ?ãû¯ypw‘9½1ø1v…ŸûOü ýžZ|ŠÓä¤>fbûHþqÒQ¿Ýo=AŽî¹™&^a{ÇÞw-~èA ášàÐ+O…8 #Ü.vç¯ãn}L–Ù^š ·Уüq´3É—ž²Ïp"gŠé>®îé•x(»ÄÝwÖz |÷oÜíÕ:¯OʼÜ#ÞfÆRGø“:»)ͬè#oØÇ_ádâœ3ØèÕ…Jtv_Pßú¿ºÿ[ëꬰµRÝdüò§àÁz”sûfA¹,[ëú˜c":"À×Õ‹DS†h{ßäìÇw»ï?ˆ!]ËößW<=bÿáµå¿nø“É)á—Múés^8ÿ|žÔʑ΅߲{’>×|2Z^pnVkQZÁI1¸ZÚ…5?þ„Jíƒ b¯1 s€¢n[¦Å€A~#˜š&u'Qîi*°ž,ƒ&Ë|vCÝ÷o|;µ`šmXbÒÄÛjIkGnD.—…²|cwW—½Z‹\ðý åg¿ ‚y´vñ¬ßõίòß—×¹Üba¨èÇ•K.…ÄêM,®LkàšM¾‡§·î`ë¿ît^cï„XùÖ.›',À@â%U!W¼Ìé›?ø€^•ß3«2¯«\ä¨^‘Ù!’ÕÆÝå¬ óÖôë€ÐJ÷ðe$ÞG™˜Û,5·X<´‡«Eá©ÛÔ>8¿d¯€D<‰KÐüôÆ-0© wÀÁaÒ¥*ÑSŒØU |§~ú-ݶȨ鰉SÍͧö–>8Ö¨çdÛ! ­´å«Z0`ÍRÆQÛÅ,~wr´“r‰·¾¼ys§eæd"ÏÌ®TLrƒËÞð†r$Ÿëظ‰GÍbÛÿlÕU!T´¡ü§äÿžÿI†Ëq1áœ-„uÖ}=\ÀæìH³ÆJÎÈ«ç¦Æì•’iUOÜ´fè…À!ç5ÓW^]ûtö‘¹àHÔ<ÐÊBÛ>|gå¤^¸ƒP-î­aûßãûÏíW“4¼4ÜöÀ-d„"„»€M3|ùA#£á)©¸ =t¾ì‹»á²ô5<\ç®2‹¯m.áKiéÂbÑ¡¨ÅœmåšâöOÞ1:»¶¼:Äé*[xЯà <’a´ÐÚ0Úà¢:/— õ&àyÈgÈ¡*©ìy÷i{®â·µ×!,é¼-¾änÏÏ6ªÙì¼PúAî|'ÿüšƒf}%€ƒêÑA&l”L.œ¨}À“ ÕB¹"S²¢Þ'®Ç³Ïœ#iš°P¯Ø"‰„ÄIÒtöį„¡Z³;Í“ Bdí\íö}½?_‡³]ÐP‹› ¹8Zäàøöf»Fõ6æø‡%§q¤]1kü> ÕA¾©'ø—è®Øýaü™›R“!Ò¬ÃEðŽ&À•',LãéÿêþoTÀd0öĵÀáÏÁ~j1§Uˆ]ëĘ+Öârg[ßóBû@©†'—K~´½"`Zúõ¨à÷}€KÒ¯ïæ/ý¹¤/üM£™öÖ^.@á k’dA/À)ž©!lI0BôšNÆðjã]-üŸ§+ªÂ ¼%€ liÏ|éûo.A».€«®ÔgŸÖ–0‘TÐþ®p=”ã§oTÌ:Š¡q:ZÙ›oÏ}þAæoæÏ©ïº_ÿ£› ˜Ù´ Â’07xÒ¾¡S&,ò¢²ö}Ô‰››¦;ªŠÄ‚Œâð;õòìûm÷«žï/j•Ê90à;Òo¼o*†?[ò³§ìט÷qßU¸t’³ @š? ´b_Êœò$ÀéwÙØ &ꎸ•NÄTØœ†Ô‡0 ¶;ëëjD5Cߦïr¶ûÛ±î{j3òtT¯INƒ²¬ lŸHϤ땑aßyÎp ¡1X¼½m¢ Øf$b V€™k£üUôsØå˜Ü;à,’n>74?¿b(²‡ìpý _éÈðÛ÷;8؃'F xŸ.Þ®®Í×ï=ñÍ®^;Y¡Tw+Å.³L²U~$•îfÅ`Áɽ˜SG àzyËÛS]7˜ò˜OWÒÒ­–ë­Ÿ´žL/‚¬Ï†…<Û†(°}ïeó#%k¹¿&me×?z¤W7â"æÒoâmÎz#¢¬²mkþ~¢'*á>ûÅ)h0[ø>XÕˆ—4Ķ?ËcŽáMöçZFÿ+þQ76/ô»v/Û–‚H/f “¼ \ë—YX_¡ß7}ž’š>}æGªËó쉬‡3ßËÒ¨þ“Pò2]ƒÜWø3§íا\Ð;3ؠ¶Óh¹'{ëVßÊ+lÿ#¼, úd¼ ¯ 䳿D¢½rö+^jE{F×÷2¦ûm27μH¼pz˜üñ¨ë‡P lã}à”oe?%ÈTrnjP4[ßR™b;Ø;,.Ê!fhÒð¨©> ” ž sŒ‚ã~z޽єF²7Ä^gòqžóQ,•‚EkEÀà‚Óñ‘¤ðÅ[¬‚@ÖÜ„2²ÅžâWªÿÉ?ÜÄž¨i »\õ4EjÈÁÙÂVºq¹©$ºµ{(>0Xfq¬ô¢fZ¹Û 9E|í(çéd&‡™Ðƒ3qo‰ö .mÈíá„Rα Çç˰žÃ9r¼(>Æ9:sÚ·‰³_ÿÍÌ‚s¼ô« Ð‘äú·ngw|!@ÌnÎ>YM{ãâê'#³h4œ¢5÷Äóúã”S¢ðDù/ÿ‡j%÷d¼ôçà¿ïïæ¿Ì‹qql}—ô3¥ËE©[Ã8[¬/°bWu·bî[¨ïÒVÉÕvÿO¿'Pn¾q!ÿÝJwÌßßð—þ/Ê#êW-/¬Ô%(ã™o ‚úXµû•Õ PÉè‚¡©g[oÆ ³Ã[ØØ-ûy*€ÕÌ:Ô©wuà Në`½›kæ+$æ4üÈÙ8>oÀ¦,÷ý[?ïL­Üí±}ª ýfºðÜ6·ËÑ"¹"åý#S5-Aq/AḚ̈ &nC:I÷úŠO,fD?ò#{r™10Eçí+%N qd¨·Š¢«õ¹ŒNNÉU… ¨yBþ²‘€¢Mo @ó²gˆ¼ÌXèÄÕj ˆ*ì•é54P Îd"¼výµ{õí¸Š+ õŽ7a òÄÅj¥¨ö˜ aüDV8—ÖùÂ85,ðÑÕ9_i™Êö4) 'ON,¬š"S:ÿºøV®;›—¾Þ;WÔ¾¬ï’æÉ;‡ÅÑm…çÛšÇažm>»NpC 5ê$J½ŽaŽiï¤Ê˲KÉ;χôüñ-?ÃØ%6>¹»¡ÑJ¶NƒÀx“]¢ åÆ>uþó!ÆÛÈêRÖ2˜)N‚¸úq)`Ûßkæõ¢È~Áùü¿áÿ…Rö·¤àý&6}DËߌ[„é‘Bb?Ó`°ëm–»ë#úi»ï£b 6Vò}¿@®4g×P’3†Ÿ_xRÕÆ[änÍ$báÀÛɽ¾E˜Gχ¦†—»_”Ø€±´¸IX»¯Eìþh?ÕýQÄ—–°P!ʶ}ñu1 L»H¦-Ý€é–3§0Ù¥(qN›ïó5š+¬¶ïF%C‡ûÉã§Úï¤ààð8ñžƒ»#Û± ÿÒ÷ ÓþΡå¢-SîOïÄ*´1:³šØã—‰ÁS;cln€t ÐpP:æcqML·6ØI[ë–SëƒQé6á\ÎvõþçÿF°º+ý¦dŠ“”MÙW;îŸ<§§ó9Ä‹'Y‰5RS“¡ eÕ•˜ oñG±Aç&ÌrŒe1¾¾ýQ"ú_£¨€Cˆ>+Òòħì`5ÕôoðHºi¡i /Å׎÷¬k†zB8È>‚ù³YqeÒ4®|Ïü:M 6ÝÙïnþ²Ï2þ þg‡°í?50³„/ ޶smøU* ®Veù¿Íç²Ûþv”Ä¢Nº'¾QDËu88‘7a\WOÅ¡‹Äü«ÐÙàGf!)$?Ÿ]ÿå˜âçþ¿ºÕÏ>!ð—wõ—þh¹Äýª¥Šø~qu“øUlw¿\/£á`—ô<ÔSPývõ\(,D^±¾v»ßøÖe ¸ŒøcptÒÍͧâvàû†§R8Á5ÒF¾:Sð»ëo6Æ‘1|Š£rÞV¾ª8·PÉvð¤ï¤”<]«òqËtëøÐåãÜõu1 f>‘ ¹SÌ$Lå—ÝÇîÖöÒl(€µâñ]xvƹÕJ8¿ö³) ÜbsÅSàh{´•ÍæöºgW á%=Åø´JÝÏ‚{*™¸®g* Õ*bœìÃò÷S™ÇåA[PÍ|¾¤q‹¯¬ÖAZΓ:2hœ-f+B|©ºÓã@l¾+P»ï“Që£g .³'Ñ]O½¶@—„Oü‰‚îž¡ý§ëP0Ÿ¶è…ÿø³ïM„ÓÄFqšÈK„°ÈÕ|¦Éó ɃÈË@ëÏ®qrónx^ pÝ£f ïU‰ob•æ’hÞPOŽ7±|a w¸¦ŽØÍRìnÆVÀgúlÍ„v»{m’ôÅ>‘§+^í±¨tQl8º ·ùx¼Ã=^]Wl©¥û¤%ܧ¥Q©´$OzúF3j"Ñê áøXWÀ²k¬W•Þ~$1q¾ŽuÛ»ƒõýË ÐE1&Ž-Yf]øûm¹™ØF¯n]õµÅ"·“Õ~ÑØI¥%%þ¿åŸøHlN„¥!kîÅ{¾Œå˽ºF?DûýÎÇŸ\îUƒ$TBœ :cè+;Þ©qp ¸<:r,¾ïV(E€ .¾Íè§öF–¸þt©4½Ø,öý˜þw¸©‹èF¯àv¢6ÒìC 䥮-µqî®éŽWÒë²~Œ/Á5¸³ ðÉ›Ø2$E¼’vù¯ƒ´¿u30µÿL1bü t>¬iÒÕm1 2ÒÈ ø³bàÎpCž†pgC;.¸HŒ‚/¹yÂ8NÑÍ¥8EëSPt3Ø>¦ñe˜?—§í-ù ;œì³ÿ?nxm ¿<€Ø«L¹\Œ?”—ßS°OaéÈ%¯óÌïš™´ …÷]u—}~5;"õÁª0w=zÅΟ, TøG¯žãÚ#2ùq xÞ ×…ãÖsîlf,WqÆÝâž”Ä1ÍÍt_ €s!ç.÷$Vú;êVçÓSÜ ¹4È—7yüýá_Õpv[ì ×Êa“ö Ÿàâ+nÇ)íîuÿ7ó°é>…ÿ'áz¬qçáiAú\gfªÃUeÂånçxb³{ea;xi6Œˆ^‘uã!‚ß_Ž(ÿeîß1°Kýåý¥?ìtèB¿Àßf×x‡ Ž™´›4IŒDr£Ž+è¬t¡¢V&´±éq¦´9ªGQê›w„P2;e‹¢Jl›(ø؆ô½}ù*®zP‚ó1ãÆèëæ[)wJÆsç°¾ø„Lj´ègî Òï~$h®ô–>³+Ü«h ê{©˜ë±¼~É™æ™F¨+O¿E=ÊU_W'¨2D‰Dxìmh‘…2¡ÃMß"Ñ®ßé;ßF]|y´/ b^:€PÃÄÁf'âÛ·‡^žL>} )¶{‚2hçR42<Ñ8 >²¾ä ö7ÞĦ8'ÓßÅÂ3ë­ã¶ê ¦;×¶CboÜ^ …!Ékå€S§Œg;Y³œ:÷Me¤4ÅÖT Ã Ëö[iˆó6C0L›¨ù¡eüi΋/2·DA¤jGÝe‰—"hüå㤞Š%ºù˜8ãÃí2× £aâ¬_¤Ð[ÅnWU»ã4}+=ƒ2cHÜ|„®îcoŠÍ¨.ñZê–eFŽ#´?eTßÓAû%¬ìBë2D ›Ü”ÝSSÊ- ñƒü+ŸÐó•£< ÎêÈsé,v\s#UÑ/Öf¤B†è/\ý ­:Á1%w]Â,lcs´Ý]¡ön1}Š·cÄòH)%ĚϷØg¯ÁcÄŒõQÒ#õP@Öch½«ãaê舢À¶¿MÒÉæäzŸÑ·_à_ÅùâÝɸ?Ø»r½®D›ã|ŒÀzø·î}}Jê|µ¾Gxè­¯‰Å'JDq1P+X«’k_‡'̈íÖ×´aë(“Úío!$Qók-Œ÷\Ad+B zØìcÕ¥Ô9ʲbYLª`«ö ^¥ï•´<í}Áì–.f¢$•¢]Õ*JµŠ@^|P9V=Á>¯Ú°=±l ð ö:ù.p7§‡Ñ‰p`iO‹#Ç)x?µl¦[»>XqïÖyWõêÛr?pêµ¼à 1 ƒG7 ²kh¦Ì•ÜV,ZäÚ¡: ¨_%6Hvþÿç#Ânl°ä%€›\r75ƒ9q¯KÁÙF fÞw}+½m'çÕiÚsÏG#•™fg+mýNüô ˜uÜ2ù9n„î¶9]ëÈ1áQêR-%èŠ~¼ ôd$oty¡§Dïôúó$uv‹¹Môßf’ívO>WpŠÁ+ÊüdG@¾¨üð'oãíI>-:aY ÀíÄù~edëxb²WqÇ:–þÕý”½ÿgá¯}'Ã1î'Y•¶ì‡7ûF¹`T—ú²,/ƒNt‘Oß'hì!þ¯† o·ÿ2÷ïïåçñë÷ý¥?Vn¿8-³DÏÓQ„^#ߨbæ/¦*FÒ<ñAÄo…@ÖNjڻõ7®5XÛ»©¤ß”Í,ª:QÖ©Ž&Ò»ûÜTÛQÈp›´ËdWS³ƒ¼a˜Tëê•øhl^as1~,%¼ã‚íF;ÇQ [(7áþ:…Y¬¯#lª—_”ÄW)>”os Œr K—É y¿ 6êÚš$c=ÄÓÊëÀh0Qâ5cš`ºˆS‡­[U«Àw¯g™!S„çw0TmÓvö2Üç-#ƒ|Ò†7y|¶~|)[|ýL.±Br¨bMÇòŒ5=f+VÿË’ÞûgW«¼©.Èxy]‹é>±'˜ñ°Ýœ.ÆÀ¯8ÄUâ/Ãçú¨ÑFÔê¦0'Jûìyezï·AèVÓîpSÌ€¬&¾XùÅ[=ï¦VõKÀ8-†{ç|†v-‚™^< úÖxßXÑžntS–ƒŽ{²æêÙDlYÍ·ý°1r~š{1§%Pcßë„Þê«Lé”gÙûö^(/³‹ 5Î{'ô檇w ˆ‚é'(›øSêñžÂ?úSÖé;Ÿ ·K¡VùY¾·FLã~¾=]È2~Èå[7[–Á¾…" DkŸ_É%ótê¼ä[hø‹ÞSù[±~*]ã,!Q½íu¸& ±¸†)\,ó›Lc±àT5¥,ò^,ø»´ýáœU«X¿w‚ÖÆ†|$:ªQ}Á(Žì>”OŸp%ö¢¥ä,G¯‡b§€6<§Ûÿüœ}Wˆ’„3âVpæD!kIÄZÄà‹eîÍ<€n¼)¸XÌâÆ cœ™m\¶ž™3a̲àÑÖ|  ï0¼ ,+&i…¸ i©ÎÞÞÜ ¦%©´iqó{Á°vâň”î"ÞêT5Iñá¼n¾®b¤žtÿ’ÌÙÇ7‡mÄ z;1=Ój¬°yGVëé(P>¼zéÏ4àiöð;> ªk÷çTëGÅéx¹%Ⱦé#V¸L¿ñ'¦SJŸ¤LªþoyÕ 0>êð•å~íúšÜ4,ÔàTD×hFå•Äô¼Eʆñ]¤• ZÄyx­(·ÜV=,Ü­®eª+³4 ¥¡ŸlñÐpOžo|?y<ë¥Fú¢?Å× oÉðmZ¯j½Ü‰[JtHºc×óþläYBSÜ{ÙûËŒÍTýS››[oÈâvQcœaÆœÈ#€O}6Λ[@³þ¯îÿ©Š Rþм9ÑŸ~¦|œ/ö—r  ­qâÈÕ šËª|H Åè‡y¿úü„3úÌýû{¹†„ÿâþþÒ,ר_³ÓØJäð£/y ÐØxx©SÝi#z®’ÃOot€µrëT­ÿÜ/<Ÿ¯ç3D ðѳpWûh¹ ºë²ˆ®£Á¼,Ÿ ßc@9Ðò‹(ÀWµ'ñKÕÄ4ÛgŠÞK^‚kÅyŒ"I½S6uÛÓE@vúb´ÏÙ-7l=¹ & AqÒe#‚3ñ>„À½;¡ŸÄBÏÇx\ o]ùÕ@tŸŒ:=uЂF—Ù ˜W³v‡ƒÖún7˜Pë³ãS[=ÔW¼,uÒ!>M» ª…½àuÇv4*b‡´ÜØT+zü]R×ÙµÄv¿ÄŽÆMï‘åk$yÞ;ס,8^%„àÙs_Ý'ø`&7ÓÊQjè'Ž6×Þg c‹‰‚¾ZÄ…–ôÀœáuðÿ´L¬²·#Ùq×µèâH'…}¨¯X÷äð5ªHàt 4——-˜Ý 2ã¾ÓI‰ºz'‹ïô6ò G<ð·†CiyTÿÇ·z%Mc›ÖJ‘ÆIÃß'ÎÅÃÀ ƒò ÌUR¬;=§äʈ \ˆSðRLÑý‘£ž% Œ‹íå¯ãÒu. €ïqÙ û¡ÉLju›S_^X«§Ix„?Ô{—ÀžO¢™"P#ˆæ°,Lbš$X‘FXGÈ7[P?J•Áóð¼fkú úu.çq¿·«¢žqŽ?ôȯòß'˜zÐ2¿Dé‰Z¯cW´‹†mf×׊W¦œª΂£è²kpóbôëP¯@›q\ë/?[”¿ÔÑ÷ H@K9'ž#L«–ð ׎W8Á`®n:C'qébè9Ü·4,D¿Oï_Ýÿãÿ4üá×–[‹Ìn3…ê7Îë]µÚZz<óiFšEʾ¯:¤¨'ÚýêóûܽþñÜ¿¿—]Òÿ>KøK"±G튪´—‰ú€E‡Í´#Û4J× tº<òf 1Ö7±¤ PÇáåõráOÀª½s½Ø»ÁBÊè6j¼@R°¡Y&k5~¥q‰Emm¬7¥É|~ àìy@‘]¯—Œ±@ÏoJë](Õ«±…±ÂÞphf¾‚biÎ÷µE Z°aÆ“&ÆuZÌÀ¼èLʰ¯FöÈÍÀhýÉ“-àÒZP½F4š2¥@íùe†ózÎ §‰šAŽâ© )ÁœÒn”d wIé­Ø;—7rQš†eÍÐØlÖ+ŒE@²°±V‹^2gŠ—cü°?ù9\¨ÆËc*ÅBõÑ S‘µ³$¦ìK-ž¹¬ÙáÛ¬…Šuð7CÁÊ»ð'_NŰ\Ýc8C’ŸP¢r  ð†Œ½[±ž«ØÐþ¹ÀÛàXfÔçÎa×ü¸ v5xˆóU©W© º˜b7‡=u O{Öh°s×í†æÃ“4ÆfÅJ­eQjúHãîî•uš®î- ,ò™†g²„3Ù™æÚçHxÆre8›­n×L]Œã3ãè‰fÂë:žEHí¸lÀDH¦†£„Š1Hë4.ÙåÙ¦ªÛxb£ Œrt0OªÓ†Ü8Ir*õúJd%`Û¿\‰Ièø @ÞÒGg?,ª÷jm5ʈhë~YS[ªƒègQ0ŽÈåÍc÷¦ngøí¥5¿c×’;Ý ³×°˜;WmyŸ£N–4—éG°.`‡j×óÉ`N(yývqÄñÚ2@úNÄ" ý<×b¦J²•4¿£" skUO¸ý`– 'åA¶y’~®—áUŸAÔàÓ²8 ’c8_Àê@·ÈC±5ª_¯$ÀÄx[Aö‡m´"i„%Á§÷ð94p¨¼v}©ÁEͬcšÐB:3.°ˆK߯÷¾”§Tv È['[†N¢Hß4{=Táe·aIät2Þ:dEèûŒœ}ÜËž‰ÆŸÙÅ#¥o4±ˆó‡9Ÿe±0¸O¸:rÉ?͆Á{ n¤Ô»À&@ü›s±?wùGˆjºó;Z|¯?Û«Ã@ÉúTrDzÐf•æÙÝé¤ké­xHügó§Ðúø P ¯§ôTßÃ]Ÿ]^— {$l‰3±ååùdÿ‚®±uÿÿÓð/?S‡¼â;ˆ(6‚ò»òWº}¢Jj9.JhÞ=÷!sòsEüâÄ=çØ_›ätøë‘À ýÚ-€÷T>œÎ“ÃCƒnCŸ¬B Àµê𳤷y@r}|07ΕqÚ ðîÕj•YôºŒ³I¸Õé.`Tí¤¹šî7¨fK…y5EßA£™×áý~kL·™ßÞ3jSÆÜ¸Zù.ÖïfþoWàZÓúºè«GlEqÌñ0K+èà>¢¸˜¶ÓžcÇ^Ñþè×(m©l_™ÆXì1;ëÃ÷W¥l†dR±ƒÔ¥Yã@°X‰ýQYûµï¢"s¨ãx޹>ylò| ½Ìˆqj/Ð4q‰1e=2Íw»Y ja~.?ãj%˜\i›Ô¶åПʅ. ìÓºz}ûþÈ­ŸùʆW€Ï:¯çfŒÃÖU½ò+fòNû9Ik߯~YbB‚um¶R´r´Ä,:Unä¼Ogi,ˆ´>@W•õõ„ºu´ =©ñ~¨Á;\Ÿ «vzc*¡kuÙ眯õùå ç†EûøéT° Š <Û”œ“*>õBgQ 5ðz¹MnXÊ…¦K  þŠ$ß%© ï³‰8Í|y‹êY0GE¦æ:]æ8ûÚFå¶š8ÃÂb¾G?éq¾¬ÒmL™°ˆº²Û%Bæ”/°é{›Béäé  }ßèYÒ»Ë;§Ý~ÿ`þ—ÛРØ1­H.?#I /=ÐWÑT– @œåÛ×F/i æž»]iÉB6ɪ¦€n¾Ó;Y™~tÁU?ç6ðHÌÓx¾Ï¢®‡ ÞߪpÛÁŒz÷ÛƒA½>‹¦¯jnüò»¸SC )ººë' œ}Þ@â§vH.ƒ`´¥•"-í¸ }b^ÒݦÅ`SÙ îJ`ù¢B0Âß]Ï:ÖøäŒÓËÏ]Y¶)2²xvÄK­¶Vç?ÉöáÜuJpo"½º2&­‰3||)~‚uìä%`Û%žE_M]TN°r³ÌWƒZ4 óËÈÛÉ9¾U¥—A¾J9Ï¿xƒ-ke?7žúh* œ:¾{°„8VâÊ“XcÏ-z tÞµL«¶ozdWo;tÃ[»ƒˆµ ¤F½i¢¼«_öñÕhä¶› Á½Ì6iâ‹'î0ÒzE ¹w'APï gn ì¡°úãÈ@¹Þme¢£-7Ùëxùÿdþ wE²mgÑˆÛæÝ`c[éÒ~²N!Ëv}õi¥´Egµc|:&„aþ_Ýÿÿ,ü·ÂØXyNà¦äÀø•òþ!?i+!7NÄ4 ‘ÖgV}UÛ¥f„+óú Ý ÞÛd–íoÅÕ!í6S´@§-gñÐ Ç×ø«-FüF¡ßð’ÚMêDö~Ûã ýƒ»@Èbœm<ò`¦nCmoÝŠ ¸GƒýO~¾][$“«R393Î#1îìg8ñ”É=Ÿ\î ¤ûë©îOK~ËL4['ÖpoËÆ×>!4( ¬Å6±Ö­ÿü‰w ·lžJs-p¡) ˜ÞvZ‡ØóK¾X J™gzX \ÙÉÓ/ˆ\}QÊÖ0ÏS"žš›2þÝGrô´Wáãˆ÷³l>Ý¿“¿D=Ùjbv+ué[’½è§\®+‘åëß±UŸ¼rX˜Ç¹Îfàþrò=À¨bSÞÞLêbÝÜÝÕY€‹ÍìnþÒ-×–äîäÂð¨É $|ˆoBu5GHÙVø¤[›äÒèú¾ øéD¢"Ò<½6_ÌwSUUôç=—R‚OàÌ:Mn/} ƒ¹¯@ËG,™Wœ°_ QÕ°YÄÏ•ùð\Wøzܨ¬¿]ˆâi$´|û©x1lÅ ü}©ÀM±$:_!™ój×O¦·Þ=Ür)"‘0£ösà³ðþ¼Î¤¦ç>·> l_®y^4f¿M¦U°©Œå…ûçlõqäôÛ¢Ó›vOMÏK¾R ›îDÚ‚Ô#¸"y Ù.(ÒÝ)¶•ožuŽœù8àƒùâ |õ•‹ Ëß²Í\âæGø…“¹g'õâÁOà6½ZAó’æèûuóÿÚ4 (éËÔ NetšRy¬¦#VÑÁ×@n7,·!ŒˆQëY8 …µÒÁPþ³?…Þî€dƒ!/À»Ní¹ô¤ Û ÒÉ,€;=ltü´ÍúÜ€_ªÅóhN~EY¦ˆî>æÊï‚C— O4ùWâÐL·Á±YöÑa^¾ñFé‚:ÜÔÀâÿfT´ƒ”LÆqpáÓ®g\î1æM-ÐÐ «oì¼wYNÐÛxvœu^Ú*Cü‡ZœkùE¾#Š)Ž0lPöâê𺡻PØÆê˜X˜°ºñŒe/ç(àÞä]¦%à áÈB‚U2EnÀhè1ƒhÝ¢X¦¡/*4yŽõà[ &Ææ¾¼3´¿Ÿ½JÄX\U-¥ÃýÌwEßlm)ñÛ ò‡6¦ÔÊ‚ˆ@Ä-Š}4(ðØó>ù«zæçØþW°íòÛ},æZ¹Â†EÎÍmj£½Ò ’±üI ëàU“¾ KP©>åA1Áktî"¯ZœW3q摲jDÑ…)ïi6»Ú«Ïè>jšE‰C๎P Úø&ß‹-áâhP+œçø4ðÎg¯ÄIV@&9£€çÄðøi#t5†µ¦®ó$0ÓÄÜb±¾¦ðÛÖÁÝÜÞ/£ïT| ßÁO½ì“Àà6{İsõ¼Þ›ßøOÜǕóXk?Õ[–iʨ¼ ó®7è/°\†xÏùóîåwJ_Ðõßk SgfXbZnN¿XG¹ µ{yµ€k~Ú$ßô¡+GÙäøI1 Á«¼) ¼¯Ô<oµÓ©kŸ»GëQ0[dÍÝ 0µH×ÍÀ¶ÖÕ*ÿq¯¯šoŠ€_æMW KuÕçâ~ kŒ¨cc-³X %ýÁ`D ºm}ä_Ýÿÿü¯ô:ßÅ‘ÔñZŠIÞN&f=Q•8ÇG¬¨œlçú3ÔÕ^ Øÿ¥/õ‘.ˆß9»ÿ¯Gÿ ô+^~>èåéxLê0sXªûÚØ3 pâGµ@è~Àð5ÆYìØ[[‡ ÷+Úa³^åÄÌÓþR·*g€ §Ï^+X|.غ‘Ñ À雎0:é ÁZ¢¿@Àªœìyn îó¿ýL\¡¥­×º–V˜9vˆŸñOÓÚ¦º1C¤äeÕ”'ÜU£êxš·É`Þ@2 PÔ|"¶–KjY@½:Å6ÐÛƒ_;̉GµloJêÊBÛ ä<@2Å€³Ù÷çÀ½*Q-οŽö‡bHMˆšlÚ“–Tøq®ÜÅKž:d†æ™¤¯+Ӥˆ¯Çýê±Vs´±qæd«À·ÆÔMÃonvÛbÛ§4¡•Ø—‹»óØ]’; iø½’‰ß%v¾Q’#)q±^1‡Â°<¹"? `gÀào´GÞŒó1ûY?ã¾ÆV:W÷Á¿ûzëź2žWê»ä>ƒy†}·7¶æ“mÃrÈô¼ðÞÙ(hÙ€ÜZp8º"’ÝŒiw–ægö7Èã^P™=ó¯Y>v𤠾8P¦˜~áÙæŠ ¾¾c‘2p"o7Š Høœ/;<ÈÞoË¡â¤Y&‹ÏrÝ'¿‰#ð²r³+½†E´s%ýYÙÿÿ²ÀNe6’ÊcÚ,†¤ÚÄkŠlÒìO†­k¬[HuyÇ!‰d*µüØfãXªq§@ìæªcyM2OžE#rRúE™`)hpTÌÃòˆÐ·GÉ–E MÛ„ý”e ‹;A$L”¹¾œzD]í>zOE„›=­§üÃ3ն̹©S8ïŸÈ?æJ“_˜§‰Álý+“$ðÏŸ[òÊЭÁÚ©æX\»ù³ÈoG)QàCIC»Ó_þÿ'à¯DÏ^w=R·0Sòƒz.Ñ«]›^ÙüWœ/ÀGYiò2WDA ÿÓâ_QþO'Ôïbˆ$`åëûÛŒAôAa0˜ Â…]‹Bb_ÀßLÔ°¹I˜ß€D£ÁÉÒ³…ùÛA‘¶÷Kc°kP¿-£ÀßÍ»º(A8Xä'ÿ?+ì“°þvŠÿÖwި̿õßΉù÷×ûû›¡c\ÐÿìyÿiÍ¿íñ·+SÿöòÿÝÎ3(ô?þÏÿ£½+qs¢ØöÿÜsaqD@P@œ}’L2Yº«NUwöÌ$3™ÉŒ€(²\½¢¢\÷{g©ªî xÞ'ß?¦? ™¤ºÓUgÿS§!üt½609Ö¦ÞèË)îS¾e寚iò>ßÈ>ÔKç~¤Wc¤,«eBcψɻQÊÐü×Ù_0lúAXVü½°Å&:ñá>.ù]+Þ­x1û¹ä‘±‰¯UFHM åe ã)¥qÂŽBÌ@™x4_šèQö‚£ó·ºŒ‡ B —?œ¦ÿÏ)¹kmž£½vç¿þ«¦ù¥÷„©ô§Oñ¢ÑXÕCxŽÿñÝìv c¸ØÕµWHÿ‡kM^zr¬h Þ>”ÿ_Û…~KÁª7ý7¤Ágw,) ,:Ìàìf£SlÌܪ;ùKØ xÞþzïÐ/Af~ÍÆe?*Ž(˜$¯- ÁÒ$¨OÑEåÀðÛää Î*òþ¯Èi(法[‰ZUDÁ€Û&°jãÝ­ÛÞ'. q]Q}çðŠœ™,ÜðšC~ ƒ3?5ö€Ã7Â8óØ!H)½ú@N+L {£²>¥ÿ€ ž'¯ß˜pî cïó_Þnç$·zàË[õ÷¾ïãeß»»ºñío'–xŠù#à úÜ?â5«)†ÈÅjˆ(¡(R2M¦‹}RpŒùÁ`ˆ¦ A_,JŠ­.Åœ¸j‘e(A§1¡xèß§èîkü4[¤ƒýŸ§<Ÿzu¨=ÖZMÍHpt“ã¡ÍüB¹Uv^¿Ž>ÿâèÿ{#ôgmjé| cÅ6ðìèÆ±ÝÛλÔHrzp¥Ëz@¡6!„ÿKÏ©(áøÔ°™]†>ƒ § ðÿOÑÎ/mÛ€ 0œ¯ˆ¤?!û‰x´ZÀM|½²F×&¸gAü«’(Áù£·Ó S¸ ç9(¤?-^ïʸm& `¡v|šþßlàÕßÚ±Óͱ$»õo¼H Ú[¬\på^@æë ó[¯ûý] Í1*ä­ù‘WGÿ1ÑŸü*`÷ W¤úÞë.ÿ_ݪxÜG¶zïæ ÿ3ºâÆêˆŒB)Ã…-FÈ '‹Zƒð-û2øÿ Â÷ù¡p Ž—p´˜xÔˆ‚DÕ}CJ¿P)kn˜ð£e ràÁšu(§3Î^„¯wˆ5ÔÅþŽÇÆJg|½•fy;ˆÏ˜©O5·Åðd¼Ü¡ó¢ò(-Ètv-r.x.úÁs[Æ_a±Ó .74NWñõñûßnãG…ž¡°N¥Â ™Ê.¡ÌΑ9[^GkÏìZ 2%Å?‹Ùеš0ü¦*ȸÍÀí—vÈ4Š=û¦Öc/žÀ4`Ð[ˆ’7ŸÊòüÝŠOBndŠLû¬$Ï_VÌ#ÃòN>þcúßÙ!ƒ_êO8y„¬Pü(‚;ã&¡ Q¼>šZBûxnœ’ωôOÙÝÇ R“‹ƒ³ó Çw9}ŠóÆdí ¸æUàÑÚT‡ÁKÈ…û̳¥ ós/øŒôçâú=#gkœ¿XwöB”¨ce‘þŠÆ ‹µØéH*Ý]ÿ¸0Mÿ§È<ËÃýaà`á¡.)í:»ã€\1eBÊKÞ:Ä©YÀ: ÎAø[® Õn Å tô•ÑùšW” &&+þ9{îu—ÿ'èÞ›PÏ©ƒAÿÇ„ØòüMlTÊ90|!zDÝ”ÆÞõKXî‡ÿù:<þv…›™.P°ÒmóSôÊZÁa}µV®ï6§SáÇ£¨ä@_^ºoª—áΰÀDd‘Õ“£»‰‰—UK›‰Kƒå.›sˆ!'Îjqì*Vò¹À øÇRì)b¥µ0¶Ïá|áFiöjEû•n3ÿóòia-»Nµ8‘Ÿ¢{:‰aîOÁÎ-2Çÿ…±{×~I›(eQ"Ö]Ó]qÌ¿Òg{ݨ®q] .s,¡×å,Žy4 ®¬«ÐVlôü¶!Ÿ‚+Ú´•@]íE)þœ].8·=p3šã´äõ½5l¯âÂw¥çæÏ:½öQõ?ÑÿÇÕÇ]éŽÆ[®^™û£” +e)É>¯¾»ým"¼VQm ®® ýÅ$Z|.Ôc£œç X¿±1Ò?Îe 8=¯B_Jøè÷„û¤çb —EÎh½ÿ¯—6ùFÉÏh‚|M9 —»-ŠóiC€ 9Ëë &¢V˜³…ÃñÆOTh¯cFÿ_ñïâß?¶‚‰ÍØß•ûÂÕµçø¿XÜÌ~>ˆÑ [& ú—«]‡–ç‚Ù󻯈þ·¾Li¡®ûB„6áŸoÊ?ܼ‰ ½}0èÿÕ€³…é\+̳tQ+øÒháyQö}ü±ù {xcÿnó} ìZ)ëUsÛSe1ÅaÑ»ÿ}ãÂ?a6ïTÇÿ‚vJÍm4…Õܧpg#q®<3¿î—lOÊço÷~ñâ'Bÿ§¸&D`ŽR3ŸÂw›‰Ò>èÍ]¼yÈŸ‰&¾’¶þ½|&?äýœb¶»•ÒF蓜Ÿ§ˆ…<ý·pu>¿ýoÊn£D^ùïá›§2‰ôòÕ`*ü2þübêõ¾“CÌ—ƒƒ3!8òŠèÿ#ƒƒ6G lÂÕ‡òÿ+Txã€ÐÿwËá~”Ö—¶%Ï¿4"‡€Ü>Ê­áË•ë^¦þÿÐÿðõ¡ppŽý;qØ‹¥d?9°å!)»P€Jo•|ÜÛcÔ~N6‰‹Ë‚}b¹«~ïÞHTGÿ–OQµpæn/õWíÌ• j çÀ5äò…¥N+ü¾HÈüËÏòqAæéÓÛjÜ3Ùµ­Tq3'ýY¥Ÿ•‡îbôB_6T[rTaWwþ{õ$Pê·æ`u¹¿kié$ו֥œ(fèMQÚóóëTõæL- QiýAMZ®~JÿäJpù )z ±-µÛ\@e”®QÆÎL! ¬dœ40ê~ë7—Äù+QõVN Ñ Wð¤E‡ hpþz: ¬)Íÿ'ôO3T‡`„£ªgª7¯sü§yW ²Bù}ø~s+ªPLÅ•¦\ÂM–ž²û¼PÆ ¥ºÉĹñJ§í!‡è#ýewe"zÞ`—–®Æ]—sϱ{¤‹›äEQ]— ‚˵0Ð(mJ¼•†êÈ@ºb” ýqùñr•xê?ר @èßÞÅ%+æzÀÒš°êX;n%úç¢6þçÚnÀ£§€z—ð)µ[Þ\y"ÌN¦â[Þ¦½úß»Ú^üIÔPaJåÄë.ÿßm«$º’úÿNã‚HªnÖÚZ¹ê"t3mk)ËÙ>ÿþê»CKU(ï®Âw¼§D¯ê®1ÌüTÐ¥¡&{¿Ú9€-øáNT®^»¨6…7‘ï gÛÛ˜…/•3QïA3wbüÙWiîO—qÌg÷¦…ÑÌÄæ„ƒŠIêeuÿËrx˃ô9­-oA&b¢í~©0CÖˆµ~†ÒÇ‹Ñ&Ù£å ëßt© ¾Sý¹ •žájUßÁp ±;¶bI›&÷¾Ú©úGk¹¸É›ÿb‰þ-úa1mI'ãN[uèt´JnÛîÜ&½››$Rós)¥øÈ;â,SOɈ½¢Ê¾¥m‰ðvhU‡MŽ6OQÞ_70òb\‚0ʦ"ý $ úïÍ[½øÀ`…éOµwd~jfþQ°kt{µfH,«Å±ÊÞÅ1Åû±æ©ÐMÍNlFAg¾ŸJ盓w_ýéð%ˆÕˆPÆ•H±ÅÕK¯»üÿÚ2å÷ýô¡¡´b±Ó&´áÚarÒ´4}Ñû¯ÿÿ“ð?ðÕáq ½OR(ÚYÍÛ­C7üÑŵ&¸-Ùø²Âîÿ0´~ÌÝq µAù§<ÿ™aÄÙOïlEð)µ“Ô>ü‰Ä0F‚ð –+™õryÉ ÉK¼@eASÙ½€ú+j˜Ý¶y?Ÿ’—KãlXfÓÂ&[Q®™ þ\a4!¢ø”®lÚÆU€ä[tã/ÌÃÎÍwô±‘Ù?»ˆA!·ñÉC£IÈøP¹Y­Kn€˜øZÔpmŠ¡”r27¡Ñ`8æ'H˜ ^'jJ"âÅmN+p˜ª}ÞLµ½1†þœçÓÔHhD:z–Ýj'¯Ru¶»Ygû¼Eua-ÍÖ_­œÙýî²A @)ž½pÃXI±SÕ\—ú¤˜ÔÓ¦’FßH¤O]zx‹Ÿm7Fn’)ŽÙJGH ÚïÒC`g‰ùÙ~ Äï€ý˜« xþâð^D²èÑÒ8ÔZW4Àµâ@$è4$nÿ %âå ±{²ÕI+W6•þLCûöÈš _À›GˆþO¨ÑÙ"µÊ³ƒ/ê2Ô´|z7+·e¯íÜ6LÍÀp’Á…YgŒJ§­öÂíƒ~îôWÓÿáPš,X·ù‘+„¥hˆ“%o½îò?z¤ß:(ô†#Säj ¨f·q‘*]æsª4¼Y†Ú†ì×bÿiøŸ£ÒáqŽý:1«DNÚ2{j~Ûza>Ýö{¿²œž,NïÈï}’xÎUW®ýЃŒ“uùŒ‚×M¦gl5=×Låý¦S“:T®ª¾?[G¥ ç‡b§ïÒ}#;¥ÔâÖ ó‚Y4€óÏ¥áf'æë×J++ÍNuÀõ÷¾ûøñ-×ÂG°{‡ö©QïÙc1þ„9£æQ¼1Ò¢*­”Û( ’¡ÞÄp˜v¶qàs‚¬iƒýïm×µ¸#eÜ @C¹’®¤Š28:VGžze@ÿGÅMm–F™~ä—Å1xZ@øÆ¯:Ïß©¯Æ§Kû¥ÿ¿n*ƒ6%¾úÙO]2ÐåÓ øú:Pp.Í|ÀZMô׬oþç¢x¿ïÏíÄâ´'=*ºodÏ€V1ÒŸUcÜJpï¹"ÚïFq˜ˆáw-aq[ª(;¡}© Ìõý›ÃH+"Ü3»Ãއg® ­+ÛöŒ±…S”®ÿîcÞ¸p¶î¸µwc†móªžCúçÙ B¯¾½`M{Çù]-îfO©ôؾ@`^ÂŽÿåôß"ús{DöÅŠ#à ­?á^¯·ü?:}`èÿoÊ2òÆbTH•,¥­V"-FM¼´µ_+±Ÿð?ã¡Ããïs8Œ”5®v´¸Üšjt$婎 ìþ÷§Z¿d¨`”E9ؼk¼Ð^»Ìñ€û>.è=L39÷za#™ºL€sî) *ô›n\µ6„¼`û¸@Ä:ìáA=“d]GÈ‹žŸä…=—ŸÓAGD8¯Ë–G¹}¹Ô܆ÂÔúûÔíF£Øx„F›"Ýßš¾úêÆ¤’%D¿fZij @ýåæ¶ÞñGÐ3Êê)4i Ñ,}ïZ|ÑM6YQ²Üoqv|yH?<5©‹°sà¼îuj‡æïžeª¢L¨&è3g h¡þ.È*œÛ?ý'w »àŽ×.>¦‚%ÉÑÄ–>X˜J¢0vÔÂ(¡¥q•~ÒŠ‡v÷QK´É\Å%Y_àB¿ÅùЫõ¡ „ìpy³$Ä{¼þJJ]‡¤*¯ÍîÚ½ø?¯›ÜÃqm Qú …Q’­­ëHût£MÃÇ~XÇùŸZ{„ëQ=Iõp{ùÖ™†MÜê1¼£çÇVçö‚-m€'\–öÅaÞô›¹$ 7ò‰mOÌ#9ýè±7åZÿH­°L8­BžúA¯¹üú?îƒK’ßjJͶå6¤€Û XZÛ§µÞ_ø|‡ÇýØŸkqfÁ–2®  bÚ­ÕhCËfÎ/g6D®éÊÄZïµ~2÷×EÅh]<û}Ï+]]¼BÉÒv–†t–„Ë­‚VðH\¾Ó§÷Ð3#Ûi D<ÿ‰BÈùÅþ¬'Y@„òyèÏáiyyU\£,gC¹í s=hbaäsgŒÓ¬ž€ß1lAT>ИÏÊŒÙá’@Ò8¦ÁðÆS¿(®GøÒºÉZº‡¨b:ùë&ÿYÅR³n_‚þÿX“:~¥ gwP¬õêÒ%€É­¶ËÅSõ˜4‘«¯lØEâ|r¼x–7<ºœ{5ƒä£ì|º¾jâl§€s8£ ©Û þÓ_¹ä@„ô·Þeð/|%ý¨‰SôwáþJ»%%‡ô%'Ï¢‘ò K[>ïqàê;ð+Òÿ‚•ßé†3¥5˜ %‰þ™Æ—^}~•µÉñv)ô¬gpB€{M%`AØ…Ö4æÈ_Lÿ¯w¨pÝäZÿ€‚Ê!Õô´#‰}á‹×]þ ýŸ‘ñWÊ"?7š¨LþT:“ºGˆÈ6Àýõýšÿ@†Ãã¿}ì‹¶ 5§4ù•Æí„ujÿLüy„aêìEÉ’ì}_`Ý——–|;uSb =nËPˆÞܲÂÄñ]ep? ÛǼ°©©npÖ]+==Æd"# •ÈOVÅv7÷u¦$DÅäü{šåÌN(RèÿçS‚>Ñ—ëû¥|pBŸ»'€8h0 Aœ[‚É×TÅôÉñ·Ìµ‹po‚–¬Z€x½‹¦C¥qâcÇâ:¸î¿Ò ¶µÆ€ ‹`+kÁp?CvÔ¼»Þ¤‚Bàýí…M®"ä'y(lÎnsB–,3¼ýTú„¨FÍt6òË*AE¨ý΂¥,±¯—ˆþsŸ½$ýŸ´5s”‰Ý¸a þÀ]8÷3ºo­k,éL<•™"ýoþçÝ#Í| ·Û3Ü)‘Lü¢Hø£¤?›x¿»/çøÂë+f&‰Ãÿ•Fúg%ÿç’AëqÂÔÂWh ý]K`Á {wB(¤ÿ ÙQ˾ùäøÒÿ2Üž áª+1ô‰þAùã;¤ˆÝ„”–Äàÿ+ƒy2åO/õV ¦ãëÂCÔó,eþJúÓÞ?"zöP ú¯Ò©&ÝAúëÄ·~½åÿ Ðÿßô öcýsD:›±u ÄÙ‡Ër?ÿùØ/ú†z“#²Fb'Ù_bÀ‰¸öñòF…žûu{œLeZU—©(x}£Ù4VÕëý¾ÛÎRá–ÀZä¼|êî:URÅ«”C€{F¥sÅA¥nš—xïÀçÅSJºVEnØ7õ˜‹D4jUßõ;ž}A{ðL®ÃO£´I^¿¢'€@^öÝÿ. ö?Qã¤cß«ïüÔתÂiÔxíòN‡[ÚP@´Î ÓÌUýÒb4Ο‚|*S+“/àJÿdÓZRéî(ÄÅþ«Ð&·€Ìby åy1µß'~Ë=ªÇ8¤Q؆|ôÇ9\¯‹œVÞƒðý?|yúÿN9 Â+ï?XKp.ÑêYrnpë¾[uýÁù':áÝ‚„‡ÿ0Ž/]…)ÏÝ’%НA×(¤¿ Ï0¼Pöâÿœ×§ËV«C7:úâºui…iüŸ«I‘ª ¢?-¸nt ·Ž|¶Œ–‰eê ”,¦\õ·‰þá wÅ¥žyíqke·+¨¬6]‡'‘c8¢¿£Öʲ|±³Û­ôr1Ôè£õ݇ù´÷Ñ¿”þ÷Ɖ´þIŒký£jË—ð‹­Q3Eÿ´^k]@ùý×]þýéÊsAÉ'ç8‰£Â¶kꟌ¹/CýRá?òÿÝCïƒaúb^÷T|±® €­IùÒ2üAjN¼–ÐÔè¾¹±ÞnŠ¡¸D},žƒ7½TÎ]ܘX½B¶¶®w<¶•kúÉ¢Á]G2é†mÿ>ÿ/þlahåé_Žís_çÎËüdP¹ÔìÎóø_Vý Ù?P§åxe˜Ó$ÚÅÚú„ eü €Šų̂ŀvV©lêûØhf4 «¬¤Qúü˜7ùshOårôð˜ßlº ´ò\Ñ/-9GàÜö¸ÖgÀß5Z6¹9N««¨Îj½©ë=P™7žz&ð˜ ?ä,TäÔ™þ£w+Ÿ®ü?èÿõMWÏgæÎm|™è _¢&”*>à6ûZJïÉ®ÓF®¬¨L¹–&ôN|©JÖ˜éo¹C27êáiAXÅúö*lˆþ„ÿdzHBé¿ë/%a u¸.õþBiäú„,£©HPd«ïüs€£ÏxúÿÔ¬}Rx00&Zè¯åâ¹ù­Íz“§åá[¼º«]Ïe9S)£¹Ö;˜Æ…¡7š•ž7IΠИ#!ýÍ=ÎQùš?B–.àïÜØè4¹Ç r±T£ï´xæPþýŸ‘FGßœ4IBÛ¼5Óßò6@Þö­ÿ†vã-@S_xœì}gXTY³®ˆH”¨$AQ” J €ˆ’E2JÎ9vwu79#%#I²ä ˆ‘ Ar‘ pÛù¹÷œûÍœofÎû<3ïÝÝ{תZ»ÞU«VõÞ»ûü7àêòß‘û߀°‹ý7[ü…ß®¿ÌZ™S6À’áE»ö.‰)Õþ`"‰Ï¸CDŠ:íÚ£M?Œã>˜··Á¬Pp ëm®‹ŽH¾]Å.U®H±}PSž 8æ'Gø®¹¯X½0~¾í19 ¸ÏÇu Y>QkÉ–ïhÎ8›³¤Ïƒ ¢Ît~ž.1V Š1]¤Ì¸b4ðhnH¾ X¸VÆ·2¤ÿ†`rŸ.FàæV{3œk›yf1éÖ@K'¾ÆÕyéŸüÓu9D–<ùì{µmUc­Ã*úF7´“¦K¹;t¢Òg"PÀìÚL/âªÐ MD.`î€`£Ë–¤H‡ >$nÏ Ã[sYð–§3o<Ÿ›y®Qð>‘ÿû%”Þ”°Q“x©^í`˜—26ßqË" äÐI­^öûño_¸9ˆû‡Í„1SI>G†k0@Ñ’Åw,–ýFˆ@"H’ž ¨£UÏIÿÿ<ÿñËûk%½‘¼/Qû¸-A‡eÈ<ØÃw ± Nšûª‘ÿ4âcÄü{™WdØ¿Ýæ/ü¿Æ½äüç§ÀŠ×öx–;»fwúé"é1 gÍ.YŹZ?*Vp§çgZ>¬öE?¿ À£~¼\oàÔ _ÞOžôwm‘‰äâ{àµNäÀÞ»Lõh`1=sèŠX,ÕþÎ8‚è£Á=͹g»ºÙHð\Ö~ñºd{/êþµ×Î)Á 6.åè=zƸ¹ìl Eá?nÃcBó¥óôAŒø½G" L5+ ô˜3 ] §m‚Ç eÇ‚ºKÀº[ Ü[‰«½ÖWh>§Û¼3c¾?“ÁžwòìO¶Âuâz@ ãá2Žüåæ"˜Ì“oÖÒg€”žD£$5×àÚœ u* Œ4œ“Ä:دÓóoV6Ç›©Óïz7ŽÁiApP¦dƒ[[2ˆQ¼ëèØ„j Kó“_Á“¦²Ó=m5ÌÓºÓÓ¯³qiïbúÓ-&(TýäD%Y§_”qÙº¬GŸœè3–‰QçIʰÑY¶’Ù&6x&z_ëa¯Ðâryöe~úD«¹l™¦@Ë"¾*< ùÞiÜ€ÿô•fj¬­Ðx›D R;À¿ÒûéÙQÖnÛ#U@ÒBEìå_ac@X—PJÓμ[¢,å]úDµ“à³mv:¹¾›€’ò’¨j†äl)!;§V ’Rø¨s í¯Ãlí[#´-ÿ¯9câ )§@êÁËÜ+……î|·î—ª=ÞΑ>úTMí±§º¤Da.f³/cCß»”~à»äi‘¯ïžÝŠlü¾Ë“>o]„ýà¢À¹Ãµ¼1iÁlÛ’× ¾?xY ú_?ÇGZ‚³nußɪ‡É.UoŒVŽÎôÄÂ;î¯øÀÒd_(ñìG¸dgY[’WÁã²ç ’ϲ(^—ì—¿€ç¤7pì71ÀýµKŽþäošnmÕG[iœš¤Û8 ¾käI$‚ÙM*I'¦F¥ìmSr7Eh¼rd¶{ãÝ?ø¶îƒ[@ÜpÉz$ÿæœ8?ë|Â+Ã[V¯<É×BÎmG~ ×ýJqøèf_‡BñÑÛ–(ƒê$<þ+ÔSäîì3ØfáùµÒsƒ›Ž,pEÜá<ÔX|‚ñ“=b`¹Pµ"Þw†²ÂLÚr^çðÅ’ëÇâ}$/аJô¦Ë üÝø·½ Ê“|xžëµ ß µœ%¼Î¤’çA¶áX —ßnuBEïóÈÒ‘Îöøÿÿ€ÿãÛ¶nÁ'Mðò9m^´mñž(V¥ª2@έ‚gŸšé/§”³{Dà¯É-6‘¾¿¦Ù_øÝ`ýKQöfÄûŒIª ºJ uxƸ8ÇN±ˆ Ç1Váľß5R¸±ã0-«àPŸÂ±›rŸKÆ!´„Å·<©óC—οÀ™;á,z)ÐpXÑC‘ï€RòÓ€p’*ºGM «^;AiëÑ*qW·,Áã(±CÜÆëèz…L'IãÁ§j/|•¹ù©÷OF¼ü\ÂàbæÇáEE.2èÊdÁ 8ùöò:Z¥áòÑé&óá§ žn¨]†;µÂ¸|K™Ô †ÅùwÀ[^`ý!:å"iÕ4Ý£À«ß}—eÜù£OˆZ»içœÔ¾ÔŸ«8¹á²oi:°¿H¶HèØ=÷ªn’ÒR¾ã󹺗٧eIOErEr=ð«…fÏBZÌ%‡yœ·Üb¹y Ÿ¤êãeI©›Ç:¦(Bfœ—Üù8Y¤ãhCßmaq}¯/T°¥( D>ˆÆè'é"ìÄ'z2¼µrÚn«ÄSÙÖ$˜wR‹Ãñ-9o¨ bªøxZ‚fÕ'Ûè£ÖŸHû\»m@ –‘Vq4¬·"5ËÜõ·xîW‚®ju2šÜ ¹Ÿ)ò}k­M¡šÎ‰ëæW¸)ìðÏ:YU[má QdjJEL¿0óæ«:o×ûF)«Íþ ³>Çî†×K?Ž‚C°öá–¨âqí‹‘w®»×q¥Mukµ&ów¦g´¿½,Mɹ³ÓGÛñ¶dén™¼ ΀óbÉL¾o’k!&¦ #tpT˜ô/dúŒr™<`6Çu¢m1V ;¬±ž…H+îw Ãö}!+¯jáJ3S±5‹»¼ñGJPpmÄU)µlètÕê‹÷z£ c´–ùúî#ˆ0%ÖêP _3¼‰ž˜YhR‰Ù·£ÚžžµE™ûT(ád劂,¢S/—ËÄ´˜s®×OtUl(¬Îä@*ã¬î&|3#H¤~ÞÁðlúÚ•®“ã°ÜõÌÞ÷.ã¼Tß·´aüOþí îCl;Pù?:Î_Er…:§(úDçy*Äh|±O…]îí€,ØÛò98þù˜Ù~õQræcŒa¨g»€ì´ÿ:ã\I[¤òì*Q†³ÌèÝ9îw 6èÑOè 6š«üb8]ñœG†tiÂsrT‹¥5Vo–kM¥q’}Â_Ëý½ø'ÖÓÖ·€[º|±ÇÑð½ŽÙ ¿ Œ§yb((R ðôļ‘ÍŠ¢.@kN{]¸lÂc''â?{üÿñünãUÛw ÷%ÌóRV‡9j‰´Â—@ZÛGÕ/‚ø°¯~9‰x9øG UúAYÅÿªvá÷‚[ð/JäŠÝþîT¡éÀ5?T$Û+½'./Ä¢]^<<5߉¤Ä YË)Ž0E½¾D{E7Û¸ÙØ}Dâ"úæMÇQÌÌ™pÔu2gqÙ‹ñ¸™W!Mº)7Ø0ò“‘•à¶A oÖµz"<ɶ¼0ž¼îI´a*E)“÷ L\¥«†®k™ÍÛc,GP<×¢’°S4¡nê·JêÃÍ“.´¼”°Qî8øªk®ìèq´©ø-(˜85»¡ï'®Ì⿼ª+¸c(|À­ „ÑjÉ \™&ÇCO‡ÀíeË.ÆkåeØjèÛ¤^u?’Å:¢²üuùá}ãQq•ë2‡åg™®›~랋ւaPùí5€ºàž“§Ý“³}LßÒ`ð»t5ÄŠ~÷ªóÖ°>½ÃgB_²T±7°Û#ËMëïê+X~ö ÷ÄöÕÊ[N °kÀàѨùli ü¾0ØvÒk¹Ômñ¤ê^‰¯öúy“»mXvý¿¥Ã‰S§ —ÃQý$èrâªóîc‘Æ>c2þv>ÝSäó^¨¡ˆz}n_î ¬(‰*šlÁ«€Ìg/©¿Ú\@éA0Î9Õtµ=}'­ôúkÁ@Ðô.ˆ˜–ðfú£¢?ï?Ö_ ŒŠô)xG¤˜ä°KƒEm=m‹ó\#ñÚ =åˆ1o}ÿý7ñ¯6@?©ömg‘÷jjEcÁõŒ8Sˆ3ÕQȯÍ7Bu“% ¨]ó|ù÷Œ¿ò»©*àR/’fç_~)æÙyAì؈H’'¬OŒµ]u~¸ ‹½³I“ Ë/ïmjûШJ†ô®ªJ/×_Õ® ئ½bÜZ„éþÌ÷±ô`þÄ„u«!»LŠ|ÖP=¤W:åtÑihŽîõ¸[®6>µ+ ù°éÀÇŽMg a­K…®xû+– )Ç}„³;»ëŒssÓX›^¤Ç[|)«Ô`;Ð¥ Œ*–Ëñ ÚY¢%ÐKª4ŒÌÕþ?øW´¤cœbõX§Ç@‹½L8Åþ«Ÿ‹ÿ@‰fW;Lˆúísñ‰X~Ûî–äKÜ:ð¡Þ:«qè¯*êV|ž zùîÕ½AàÄ;䆺«ÝG•»‰ë[ÅüŒë_ѾÌR3g2ÃךH@V7P¯ý>üSªŒðYÃE8pïí€ÑQÍ*îÛxh•¯›5ØÊËñ¨Ó ÷ëq#£\ÿ“ òí.nد² ;Tuüÿ0ÿ€?«Ò„öG—é:ÒN[ÇòëGÇ„„S„~ˆ÷Á§ ö~1… ¼£ü~mþñvŒùµMÿÂÿ#¸îV°no\ˆ¥ͤXùq5—öÂPîÑa§¥µˆÉlœÍW–zP½,ÞI´^üËŸ¿BÈÙÈÜäâÐi–¢¬W€0XVI"NÊo@Fëî1B®mtÙSrk€Ÿä%P9$%Õt´7 sa¼v{ÓTž›é †!E2Ãá‹Ôå:J)úçI7‹¬g¥Á#À¡íÂv¨ò'€À@â9fÅmše]b&LH‰!P8Ã㎠>‡¡@()ÉÚÄÒ?ŠÞq‘œˆ¨CB©Ÿ’5œïë$í S ð\À¦2U¸î}È·½¸Ònñ'Lv¿ÄË'ÔX‡~éhoó f¿-s.QÛÔÝ3Ü—­°Ð³jv¼j¯„¡ HõÖ²´Œ^v q½5TôØQ›ó•]ñ`Èûq1/8gË~w¢EÕ®S‡ÀD§•F¤Rì1+ä¥^ÒFæò}ÕÏᾆ W?èé8?´ dcdâŒï»ç…@81)ðîuþb¾„³·jT\¹vèÆóÏÒJ…êî†yŸ Mjäòz ®4§Ö]pÃr0Ü××Ê1“}Ë<ÓÛàý¥Ñ*RÎËÜѦ!{ŒXàö õ/Ї×õ¨˜tî²Oë<Ñ·ÃÍ’w´Óζ6Ñ~ؾAeUå0®t¹vñ½ä‡âÀåбÊßÈ?ãrV®„Œ)C_îqŠªt\HÍŸ„¾¾ ëwZ»T€teJÀ¿aqEUºC–©4s¸Žñ†¤öÃÞ¢I>]ð\1ã˜,à“Æ‚¡è‰£äöjŒ7É 3 -¸­M· “o±ípÉr\-ûÔPj¼>J¹7Â?ñDÙ˾>¦#/f0lúò)—~äÖK¨Ü{%#§éʘ ‡»2 ‘ã^²À§ ÞbÙ¦;˜§°-òq%.Ê´ åN»nK„_ô#MÐs¿]Ê0å7 î,ûÔ<5•¡SìMJ7ñ㜛»?þHü5aÈZ«xs1ƒæJ ¿ybSÉóßZ4Vi¦˜Ö}bþ™ñðßC¿¼­ÏÖ¤¸]Bái€~||FòH‡gÍ| E–û~Í“ X÷™ô£ ‡p§¿âÿå_ºÁ6:ù5µ/,½êÄÅmWpŽ–Íª¨¤ÏS¾5$¦irâÓƒ»Sðo¹ïŒùwoü ¿#l~aýÕx) û°ŽQàÈ7pþ]P¤eÜS™õ¶ƒJ­°û8¡MÑíg„„¾Û1ÎíÕàÝÍ'®<»Ÿ}X®;)%!ª4L `ªLF LÞž²±APÔù o»Ï±za/bð˜x«ªß+0g_8—qUwÄíl5ç! 8ô¥|qŸe†;Z„:Á/¤4ÒîòeïdW·ñÝ‘ pXät 5'$ÜEÚ¥÷Gîod”2E€¤eðÆ‚0%¯‚Re˜ªÃ²-ßê°àôðBxŽq£JÅkÉjN£¼°:ø¸¢.Ò?3Ìן´Üº(ÓdLu‹Ì/hÁš9r°HX68½SÛ tóõa:ÊÉ·êú‘¡L©nd²wÅÛÝ=j ›_ ¼³Îþvì2»Ùë”’rƒ}³÷ÚÁNlZÊo®Î›ûhvð÷X¾$ðÇ•]ŒÉç=ßÃ0ŠóBÞ:~µ¡ÑuxÕ—¤ºð8ï¢7Í»±ÃuÐd yô¨·H}”Ž/™ÕÇú]ÜÎ Âõ9 ºÙSrºðaãDwçêÆŠ½<ÈÎlOûƒû¶ÙóŠx á~¯¥C>랇Ü'¶¦±ÛÂ7+â_Ê…û¯°·ÎôÝAšF¯,r½ÝÌ}‘ya”«÷nºbñN ŸÖ ØuÔ1©F9ù1E4‰o‹p0¸ÇU}´ÿíükg±‹°(a>Sá’ÓÓÁzú¸~ž·³g|Á4¼8BÙ¡HÓ‹I˜ìq@(m\‡ær\!mã{^: <»ËO}«—x’:÷z•C£‰x7:4“@ëH×ú=‚¤…ºö[2º±bO(ÉÑ úÞÄ,ÊŸsºU¢%ÒÕÞëÊ<«ˆSÃV~‰ ÖJ‡Éô¸/ܯëT‰Îã¹sÏ»qÀkë6ÌOŒ0±öÁ–@þ°:“•+²ƒ‡‘dy½êlVàmQå±ÕyÐ@GÒê3®ãq‹Ý·ÜË J •ûÞÛÚö ò?¸Þ­À§‹±Õ!ÝL‡íüŽ~ʚѕ¿ÿ—å-ñDDPuâÆŸá}¾xªî½;Œ{{®%.Ê”§¤Ô·=¦(Í™×Z÷Mo «^*2 ÷Þ ù³ÇÿÌ¿ñ››‹to°SëZ«Ý¡.Ù15¤ ‡¼“ÞJ¬‰iò/%„* û›RõƒßÖþ/üxü­uféqú:|_{ÒG…gSžRv Ñ¼?°ß+Ê+¬èCœðæ«Ã•‚•¨@ÝDæÑ2Øo>ÿ‚ÑtI†gÏÊîËYôN ¯;S¹þdU1õÜ:$$¬è Îs§ƒ:¹\àû›"—îð¥Â$xZçÎ4e&Šj4;]p…u­8UÎ쮵z†¸i†c=ÓA(œÃ“0ñü”ïÇ­mvpÂVôòå5y?ÑØÝb MÃ!îÙÆå¸äÃp;q—$ðÁpŒ}kÇf¦ #—䣺ˆi\\ËOàê;;ÎEÜú>¨²TDÒV é|„R_ØÙÂ÷T­¯J¸¯ðÇݾlüÅXØ5Ècަ»žäU\8æïš·kŸ‰–:€m’>ƹư—m§›³=f“G*,*¯ßÌÉDv,ëY8)7§¼S¸ï à»!‡HË l"OšWB'TÑ̽9 oú}”@Á2þ“ üíßà{è× C×L©91ja™tºKãæÎ+w`öh¬zaª)‚nq½µK¯D`] ¸Þ¦hDR¯­Ž=C¶¢&‰˜VÄDF¦Vec·©(ì Nwº„öY,s; žùBZì,ópù„lX“­¾³Iüʨ;öþ‹ÉAT­¹Êlߨ¬ø2Ø?¯qÇe×é/ Jƒ¶1åxA_~þ±Ó'E6Ÿ…¡á>›˜OÁî·|Å{©~¤Pxr}'ÿpÁ-*(;sùM ¨r¤U˜î\!ßF& *piçéLÙi¾€õà匲#Õ |Óœ8Ò=ùv©9¬º):à\öñUƒÍ¸Er *qéÔZS€íz÷ÀZìw€ÁÔä °z¶» »±Õ£(E‹óuÄÃÙd‚º‚e:|wŠ€žC žb{@˜› à ®B ;ôð´" u*Ôø['y@u+faÛã)ËóƒF&÷{Í3l“­;Wêî–‰[ øý'þõÂëd2¤sÜ@ßÕᣪŠÃš±Ó™7œP»"/Zl%Æ'®‰÷1²MÌqž8buaYÎÜ$ùŽÛ¡®è’áÁþ‡Þe©ñÚOß{v–”›>Љ—¥ ývú•$Ê­2lw´6¿¿õËBc»ï¬0Avo¤Ð&2Ûiážo4H_û>Èý}<à!«Þ–f­Ã;b.8PzÍ\êòÚÛH-L×·…FJµ³Ïõ¶AnÉÆVwuài{ጛuW§!³ëZF¶®¯FZ0Lz¾ë^QéÞ9±l¼Íf-â]ågünmAL†Æ8LèèœYc•¬`‰É•#Øž–û:¸ùòøPÌö]Ù14Èå´t:”5þ>üÇßB `AñÁ‡‹øøžÏ§Oˆ¼Zèùõõ†U’ö s|Ko^¦ßT›C¶¼‡{³ƒï}ÝÌ£&ØÄÓ@b’·:À³†§óë‡U†«Öåq«—Èq#8=Êöðh>hWV]²[Žý³5ÌÙM —8\ï|,…è}§]¬á1[?Ønl€ÌÆXBà_¹Œ…laÜ ¤(@¹ 7iÓW` ËÀËáoàUÉ•DBèOk³¢o¶ >³‘X¦ ¹…‡³ó¨*š¿ó 9ö[—r¿#tʃy¬ ÓáòUÉõAŒ‚´å5çMÌEäF¢ª‘=£q…¨ ÓW'Ö›I›ûñ¢: z«Ñžê†ã¹YßyšÒ­U”þJõúkÛM KëŠÔ©Iè:çöCÕöÀƒ™6áíü5’ô]6,dðŸoÀøÃNvè m4Ý⵺±+¨ßÎ?"àV;Îÿ×BñÏÝI,»=ïØNl pUþÚ‹F˜ŒòØõ¿8zïè+ÿÁ‹EÊA-"­.¬Ž’ž9»Óògÿ?’ÿ$3²ÆØTÛ»"{Æw>Š }ïg„Ø3O  ŸøI6û~!?x;üšgÿþ3<Ý~qñþ‡`ý³?ÄÀñY³ÒýXX øÝ{Õ>i,‘p·Ã+í ë“j<ÞÃõ¬âþ(­£{ž;4ûæÖpö{ópk-à“ß“¾çÓM¦ôXOã Ü'”™V\3O·àÔÑê¾Ñ<ð@qÆw”dÝ*QHÞ¥Pƒ’p= ¨¥ùv>OÿðñrO]˳‚L„RÜYê% EÖÐrç\Yåáês½¡Ÿæá¡ÌËðÂúØàÙpöIÛ9ˆ¥uÁ¦Âk£¨ëúï°€à?wP‡8/䃼ÿ:û£(v¡7ÍÝ.´e’ožÊ©d‰°tž=‡…«.³†o§·Ò%#ŒÓž«E…Üh#Ú¬/¥©y”@äw¡UÄz-¡_ù•ÌEí=…*’ ¬Ô¢&<8–Þ ˜Ø6¿‘}¿OZþ!š6öµ?l¨HÁÆáëa½6Ñ÷z\–?Á§˜N."˜<5Ë\vÝ66¨;Ð#;M<Â~^OÚÉË…ÂôØ(å'¡Q§’;„‚¬(´ `ìk”=÷ªݶ‡íÈŠ¶§¥(yԨʸ0íÆ¼ÿZèÿµ=œ³<§TžãÅA>G¿‚/^9ªò=ru{BБ0Ñè²zfîÛ5í Kò{g°-LqÁÐ!Š‚~ƶUÿ•°B–úK·‰)œ 4Úw¤ 2õEð®c L Z¤Qäs4=Œ¤I oá¹iru‘—{˜1tµw?ˆ|}Û6Ùµµ øÜËú!Á>äé×ysoþñ-H5ßÏÚ §M~}'§ò%¼¤}'|p¨X<îÞC/#J:Jïc¿•ÿ®®Ë~(êÄ=#¡~¹b@÷ °ç1T«`¿Xþ9¤ü<±›8ñİûFãø¯ÎW8**{_/ÇË:&ò±‹0Ãügÿ?’‹1 ŸÏUÃFVJ‹{¯xßòHËžÑÑ(¸Ë¹-ÙÔ#ðóÉåäð{d!‡À_õá_øíðüY-è‚7è˜0`dªà7z¹ÇPªJ»•¢ÁËZ¸ôÛµ¬ç€tTÞÁ ­¢Kí·|=iM'~%þ_ÔuOï…£{ ¸ ¬¥=]—mÃÚÉb.ÉUmXëVŸš°Lt=«) `ûæÎr ¨úüù›Cúüßvù€ªÙ‚ ØM2 Ëû˜Ÿ!|ŽOÑV“µÔbý–jQÜ4Ħ=™íª#Dp)ÏñËizv=ì÷+ÀP®û ¹Ñà=kÓÝQñyKq:<Ëë‚NÚ0c,¸Ó:¶ ¨kX\¹1‹š«µ—¡‘D›^Ž¿Ùˆþ¸ÃUè#“Ó=’Ÿí&©nÌÙÄŸ©€¶ w‰ô+‡ÔÓå nn©‚ZƒZjˆÉH÷*zÁ¼OdˆB,_s› ²Ý×› u•’ù91›DÁù¨¿C{~¡x®4°_G'[]Q¡¤´œM‡kÁá3³8+«Ð$O#Ho(¯Q‹xZÍCì+¦tc£.5߃­ËƒHâec=jhä´à³™¹÷Ûò?U}-/Ä; &§f“cWƒ– }V«°ûÚoCZVÌèåð%žTøÈD< à@`bF•‚ÚG†'½ÀçF¼¸J_¢£Zü¡åÕÈ!ù©SÓPuÝ/¤Ž˜+ÒÂЪKÃ÷ô>ì*7²KãmpÓò“ÅûËéBÓ´B~Gþyúšߺb22´ŽA» ÿÜ-%Õ–­Íh8?¶uŒ²MŠzw^Æ=ù¦rÝ.&.†a®nT]ˆH9à˜Šé«Y s¼PÓN=âË|Ï|÷Ħ’pùêŸH” =l?‘·ºn‚§'ÄõÒ$õ$Æçn4(Oªx@½çÊ8¸K¨ìÿÉçTænI†øY ”œµ»IWotÈ([Ƭßí²ÚÄcð'ñDõQØ<«’ŽæOA5ŒV/ÝÛÇ4{w˦W·dõ\…¸ÅÔ‹Â*†Õn‚²+07ÔëÿÆÿne›ÃBoxTXq 5WvÖÃcµähÛÛÊq•`Á°?qÆŽ€4Œh+èf&„V“Ù¹{×å[¯`ª (K¤óEx‹9¥éP¸IòNÝ®oåη ŒxÙ˜[š®;ÍøÇg¨0¾Wî¾!ØãpoISÒÝ8F‘ßÈÿ‘šž—œ€x®òø¶Ÿ¬Ä>¦ézBš4Ø<£DÒßg lŽØ¿È»ÅW*ŠØÖ¿åÐËâ`ú(z5”,³™yóŒí L´¯«fÅŸ=þÿ@þ}Hv+ÇâÛE Ees•8¦¹éƒ'ìíß³þ¥Üáþëžýû/°Šùíß#ü…_ÔÏx+¹Ÿv}2ºï¹üb± Pj(ó„üd”ŽóŠN€È ŽúŠÄ¹n_òdXÃ…·ì-¶§ ļoA¦ é+>JÏ,Ûûù·z@y· n=”©ŸÞUžï9BtVþ¬i[u:Ì2`¬¢j±²¸ÛªoÓn/“é§‚XWû]ùºšûuœYO&óx>ßG ~ø!tÞ^‚2ïîöɈþ®™ÓéZÌ´˜›€<|’¸#ÚDa(®Ô×TÀý='Êû¸æÏÌGœ¯Ýz2$êÐaÿ,ðÍy` ,‹é2Teú=Þ;÷ yn³Ö«ÖøÚL$rÏ|Á¸í´–&É;ëb8`ËQÚo¡Ä„Gp‰@ MÐ GˆÆòç£ÀS4û)êm‡c§ôß‚IÅòÔ£ @ÄôµŽLá­|KPâÏðœ‘è¥j[}®Êß;Nʨ„œ•jzeZÁ÷–]ÒÍŸ›|£ø:é/û0-íÓñ`-ä‹Þ L„K ™oŒÿÙèEL^â0Pwâ³DµæN”\Ée–×k´²t‰mãQe6+ßjGž‡€æ1_²ðúpkžd¾IË#3 ò²½œßX·e?H¡½;DüÑÇ)ÌI–­žSß[önÔoc³£ðc5PäíJ)bù sm^ÝöÉÆùwlžqÌT²þi©ª(Çõ3¶ 4’u £²g}ó¬ECn¬Q¦”žãÜG#²Q¶Uª'šhŒ6Ì@ˆ«ZTÄóRÆí8R¼9FÄÙ ú¯‰ _…n#IóçsŸ>‹QO !Wཛb‚¯ÖÝà)ŒåöÃá?ã´XâÈâ–hm„”™öaßõž “!GG{–àH—ñÓ0Ð×ëHøè’»10­Ç@­rfüã¶A- ÏEORÞ2ú é5»[}÷Î[?¤“¸_TѨ*›aÎNq _/ìD@0É2Žÿéɯð¬çV¼AªÕJãáÁ7~gþÙ´ª"ž»\çÒøÎAËp•ò²´nÞ÷’)Š¢³VÜ3þö¾9NäÓÏÁ6Šñ¡Áj±[áïÑò’Ar„Ž ÐèÇœ‚[»f3Ì”PÐÖi^¹ðêFÍž¸<Ú ùÖ)Z«Ï”ßUIï6‘Ä‹ñºk.³ö,Ÿ^:WÎzº)A?›9ܜӳÿî^¿£¶¿ðß…—ÿ¿<” SÇÑ ;O¶éÓ‚(ù±9^"¶zœX®/»ã°Ñø=DÏ›¸É¥»q«ï"1±6¦8ã*¡·¸EÝ"‰ž[x^ã•”..L®‰SxVEy’oo‚w[Æ#Ijz±WKÖ(¡XÒ"k§‹Ô3½^}³[â“uÚMí4'u7(@Ì6-è¾Õ¿ÈÇùÀ– Ïß#ÿ†aX.Áó&ÿàE,e—Z8:ŽfzWó‰`)Þøû ܲ}öñ&Ö+Ént/ñã'/ò½@·²!Ñ|GŒ»ÂêåPPÐyñPɲR¬øÚ· Ãd'_4žFm}̳E(B©°PÝ´o¦‘ò,[¼ÝZDàwyÆt]óÃ*”Ó/œkFM2|Ç <ëõŽßÏ}DØÍ4‘ÍmÉÓ#ùRzáQÑm¢Õ õ®±î~a“tthŽ7„­òëÌ(÷ wâÍ6¨ ôšqZ6vLÞµuôúÈc#µâùÑë F(ñûóO:óqë~šªh£‚X¦õhCNT:X"$¼ «ZízøW@|NI¥àI‘’G¼¡fѨñérWö94xH¼œdóJÐ0a%>ÈÕ¡ÂSéè|±áGõuóÀÿòž»KhêcÃûݾN’^±p:=°½¸s‘Ÿ#î‚ñº;” ½”ÕÝ=X{½nE9ŠqzÇ"$á›w¡°aIÄæÀÒ@Q<;(äZ^O È7¹ùö]& ÁW¬2ØMdN#9u516ãÅ}6»€e­GCÃv|" òúvä{Où¿âŸïä©ßçõØH­l¼¡SI‘ç+[õrïØì”|1I–Ç磮¼:›`ìH뇖©¦ä‡±z÷šBüä5†àì[ï­¸Òb–OÇE“©g}¼½Í;Í,b“º)ÓïjìåÜ~LçúÊ?ß!Èz¼ør¨7f ˜þ7ðÏH@Þ_pº|êÛˆº€Çmtò‘PFd`qv]ãc{hÍ}¥Aåû,­há²^è9tÊr”ÿмR·/8,ê¾=0·CdZ‰ŸzŽ:3ñgÿ?Š Ä[¦š0…·F5¤ÔÎïÍzôé¥Á×ÚõŸÏ{øÏþýgØ…þëTôþ§ð3W><»q•ºà°¤ú£¯Î®n”z;Ñ.S~–käž(añÇñv”50á Px¹Z×_Îñ%ˆgÐTb¼CæëóœJQ1à2¦röµë;)1¾Ù߀c_OCÓ1#­¾.%ä'íÔ­¶ÇȆ¨_ŸÒ‹”TžrÉóâ ;8ùr¶¸ðx1äÔ¤°*=êE†‚:Ç& >Qïo‚É–¯4‡‡°7O€Ü ïsÐŧ;8m`Vgÿ{º/î<8 $ₚ¢ ÂÎ}ÒÕË¿†.Õª>€XýFepßž¬ó‰kõ¥ ÑS};u/ºüÃ`¯íÊÜâÞŠ#Ư`=Çæk:IŸî$2KÓœi—9öb¸6ÙüÚ×ÛýšÃS£fwyà4p WsÍ—xbùd­F‘FžðLä½0Û°“¸Ùcâ“æÇ>+hÔäæ_-6,J}à„@¡P|Ÿé:úœ¤½ìg¤Jƒç:¿ôŠÛ-j@+Ô„ÙCeŸLMׅΆ +ÁªŒÝ¥‚CS6_!¸ž{ƯÖã_PûHe¿Z¤æ½?ËŠçQ7|þfÏ©Ž[pײÁ]3ÞíŒy¢D±Ðäç^º>gת»·kåy7îfrùºpÞñSëèN}èk&|€üÚ-âÛ¸ªÙx>UÅUÛ9P¦—ŠÿøŸa¾Ý›!W÷šD™œéä”~)ïúÍj…¹i9³€ÕAƒ„ŒÍwõ©>Y*@¡ƒ:¥×²E),d;Ð¥aöL!=_E´ªIŠ®çwÚòƒcáÏ5¾¬ÄÊ}5šâ¦kNÊçª È©*ÄÚ³gh½œ¹RÍì‰ô9¼½©Qÿë$™ > õ01ÔáÇ7¡öo f ŽV^'m£N{þQŒÁ«FÍ n‡‡•Ù$Kèö8K†5\QHBPîÝ]æ'ÿÚ÷ái&;µâjNƘ ÜÎç_SH;=5Ü º;ßžEÛFð4ƒ±ˆ#µ~ð¿zžãØótZù¢9™)QÔä^Ž.élc»Œvó &ÇIÜ×üPtN)æÁO†¬# /U{„“.EYF®çK¦øÄ–Y…É6|rõ]R734'¢2¡ÜRWD}ññµl•A{5»=xV±Tä…¥ãç C1t¥ ¶”ê»Ë ÌE%vf-¶5vwnñ†ÿ›ã|רùöD]”Åe+®d"uhª"2nµµ•âjNõÍ#p ðao OY\`Å#ðÊ™¬k@î¾óTê"Zwííл¹{lö­ËÖÑ'\>#8G'jÀÁ/xohÐ_> µ•ÅArG½b8úúº‡öc£(îPÆZ9OGè\J<Åqurûsç3»Õ·tQ—D¶¡DÚ"Û»~žJÅòÄ—@dZáõ!“Á½±`å] '˜|£|·¢2ÁÊoi§p6Á†NÞå¹ÏY¨«Ë„(ÒÓÇæÜýþ'‡|z ûX^r-üÐ÷Ãåc`…·a–t·é.(ϹôòoßhW‹²{ßCãmÙüAÌÚ&¶ÜÌg‰0šc˜Ø‘cQ*/Î}–ÇÇ Ÿ|õ}/WÑ-ÐÕ¨hïÝÅtxO9+ Ïý½è8Klf†ñõ {i#û¯æß×ün~áõØ þ¹Õ€ó¿;–7UGæRªh2,t§¶SX²Ïâüï¾Â›Å´R& a_dCá>½¡à¬úk}}oWðôþìñÿ‡ð_ï¬Âs¦nÃ3@'6㊠q±OMJŒÜÿþsW÷½íý"~ÿ{öþúgà?ÞÿŠç²¶ípÇÙ‰²ù¨³OnlšW<u¦èî|*äa÷Bˆ:›ÅÆÅ“±ØªsÉßòCÚGƒ˜ýýÅàÃGj¤iwwp5½è»Ý† »´ÅØ#ùÖ¼fåf`ž=£¢¹k÷~×îžç€•#7ÑgÍ«P«ít;|¯ Zn1˜SôŽZ˜ùñwɯpÓ?Oé–OÂJ¡ÀñeIÝ?¬•gG=ì<ÆßŒí]”/ õøÍ(W†lïœãøa2k¸®R©‘£Ð<Ù§6TsÌëôh—È> ¢¸´R€P \aš ð¶X&ÈàÌ{Å÷2òº<¼skWý ²‡ÔCi^©³qI²›$ù˜S8jæ£ôa”ÝË~{1vóíâ}Íï`6n¬ßYöÝèµ\•:îLŠšºÌ61›-øåG‚‘SlCe”‹ºë,sÐ:å`1°÷ÄÄßó¡bxÿÅÿ¸ÛVŒÏþûÝÞqQƒ1ÏØÖPÞ!Î#çeÒ%¹Í,n̈á‡5 ÅÆvæAJÍ€àMk³§a\ GQ첫è³*7¥Ë$ºÞ¶k@šÆˆS\ð´tò¼P¹’¨ˆ+£IÜÞì3õUfüñÿÀvKT|iVC¾o_-wZwnœ±‹ /£€­Í¢?APÁÙ±0z…ÿ‰OLo‚{®8å!3 Âg¢”¨ªñ„«×#ƒyŠp™ª å-‰Ù<9CÆ)r~ióâ­‘^I§ã"¡THz€aÅ`pÓ»â>ÜgƒYx¿¬D‡*ZS»Z,Õƒvœ=E³çœ}C¬o3Ä´d)'ª³?O/†wƒ.[`ŽH´îA›æÙà)ÈYz¢Z^6¾ÔYAüt3©ét—E!Ô F€ÖÛßGY[„Ý÷gù—w†c;ˆêÖäÀõQl•¤žà2RÊEI w=Ö~&-FW))æûOöçPèñIemò==îÛ+´A­Õ1g—û„J~8=5uŒ”àóÝ„Bvïáþ|&3S~‡_®¼aÓI‡TQÕˆ_É?²¡:Žä©<¶|úYàn]Üøb aÿ œ¥]Â#|ªj@ø¶ÇçÿÞêÞ2*sãU.Ã/™ËoÛ4~Ub†rŸµv¯¿(@r‘¶ÞnðÁŸ=þÿþy”ŠUñYG‹ŽÜsˆ¼3¼5¦$K¾ôßÉ(€·hGýÛ-þÂ¿óÿo"(Àü´EbÐH,îB£?n õÁ ±hé„+¥ ëo¿Baþ®…ôÀE6þ¿ò§}?ÆÈO‘hÜoÈ Cÿí3ÒY÷ærƒ±ÿüûùé÷‰týqwÈOʘ;0ÿù›Õœê'µ?íCZ`c°8Aœ( ý?5ùIÍ?”ýÃÊžm$'Š´J@ÿMþ?úò“Êÿügc”«¿?Ê6ýOþMæïÂ(´'*í…«72bqû¼•«pA*äGx(ᄟcƒFyÞKÃbXœ¼—Ú5g B`Ñ>¾H$n>Cÿ`ÁË-gçzÛð '—Wp>óÁàœâáS‚DaÚ ÐÞv±œãÐX,Ž?î×§§‰E oTàÞ¡r&êïNñò·ùqIïó?üÓ§÷nÿ€kî¤óëøÏÃüäPÒEñw;…ÁXÎ%Hœ_pÒ¨îAapbn¸†>¾?y‰Æø`q2(,Nñc‹ü©[8Aœ·°?FnÇ¿/Î=ˆ?œ€;üÃ>ó“i,ú4îÐOÛH4§Ñ:ƒDÿô8•8ûÈ¿û©W8Aœo_ôß6H—€¤m4àüp®€ÅuÔïGÇþW{WâÞÄ‘åÿ¹a ÀpØ–-Û²îîªWÕ­–äK¾ Ȇp „dÿ¸}GUuË\³à¬g?ÜäëÈêRõê]¿w4ÒÉ6uf[ûî¬E©i}áéwÐ<ˆüÚgn¥~Z¡Ö·ðð^»4qíš[ÿ+xaªsÂà®™¿Ðéïx|]Vkœ­l‘¢Ñ—ÛGÿ{K†îIÉ¢L´ÖqëxÒÍå~3'.¶<õƨõOžÿÿèÿJ u1h}#ƒ˜f6ºfp#k"#þ{J)öÚ|×øÿ°iR1N>‚r,Nü|ÊòP׿©á¸Ç}ÈYŒ…Ô¾­Áòú\GØ—ìÄ/ÍýÏ:Ž·t«^Î:³ó¤0Љ|×mWXß3m^±„ïä2­r/ 'HÜá\8>ÆÈú(9®Y¼¸3ùoŒ»=¶Šœ¦Ãy˜÷séå$9Ãú¨à‹ç]|Âñã4Qÿ÷žZRèÑí ϯ ÝC=G¶•eì…óªa3‹¦DÏ?àVìH Ò8¨ajé“,FÅ…ßµg–Y_Žnj9 ÇÇb9˜¿=ÉŠ"žŸ°¼mgÒ{ÙëžZÆå*žåaãxëCéÿéO·dP¶U'{Hÿ4%MÁ )°¾OÖ'Ñõ8]4 vå·( I䫉þx¤Ý1àÔ·ü¤h ðl±JÇ!xýhä*¿tͺ«#-^+–kx6hþqš˜þr6<Âé´J´L$é±&\ûïÌü=ÐÿEó+´ž9ÝT~¡êv7û/«ºÍ˜2hZx&Ð…UGŸ¦Lq¥¥1ºΓŸvï¶Ñß<íóíĨ7˜ÖøËÚé \Yší}’@V\À–Iöù'Ïÿ;Oÿç™!9ŠåHÔ™X‰Ðô%s-‘eþ~¢þýMïn;¸é÷€8Ù™P¬xd_ãX]HˆA`\Äu¾FúoZ†þÿ'×Þ§ñÅ9Š &h¦?ý6"d€F D|õø›2Ü M*‡†èŸ>5FÜUÐg‰þ´Œ›iâô&¡5¶APx ÞûótóÇ×¶®Q\ÿHëêœc£"ªÝ:¸=ôÿÁÑõÇ™˜ÑÙ1øy BíÔ’û@–›¸›H‘S»ü¿Ãôÿorâ”ÌeÖø´dµjLoÛ>\ý2ìnÿÉIN0bÅ3²XEE{ä;ò°Oëdºç…=³b<~~^LƒBVauæÍ{\ðpnXİÇW0âC ·±àÿôîfpSrýÂü>Õí‘Ð(¯åg,˜û²½Òyâ#“¢ØËYº°ÓŽùé -Ýî'¶ 4ÅãÕž»¡zþ…J:ÞÿŠ€áKgàæ÷å£èe8нx —–;ä—¦ª6£ gèȵ¥œ ´½â¤UÀèÐ*‘X¸Ï ƒ MiHdcÂlhO­‚©exƒ§¡%:üúÓ°ˆ™\$5¶Vpò/¥=EÛ#>’þœ_˜JX mÎ.!HŸÍm74=`cÁPJu,>:ƒùr`d@‹»fÕT·KJz‚ m´\q µØè๎(8•Χe/þë© ñ“S q;ÈÑ”q¸ÓߦD3#>?YDºAúáÌWð t>Lÿ§YX-Hÿ̲_Z›Ëõ¬CN|(¸]_Dú•óeYSæ„É—¥(ÍÉõnAs{%µw{èÿ¤ÇÆV·cÅWejE¥SðË u¢¢$ -iŠ3*pZÕßwùgéÿ¼GˆÓŒ‚„–PP ýÊz¿zþ€ä¿áŸïZ;¸½ˆ]ðŸÝMy”¼“ûeqõ0ºµš8ã|ݘ¶~î,¸’lEÍ–±Ý^j i ð[šì!’åùÞý©ê=oC-ÍÜmë\6äö½Îíy]ZÊø![í¹a›?ñ¶âî£[™\÷_ÉÇÜÂ÷Ÿ§Ýš5ºa]ð/çýœ»aü»§ø$ûžÎB”NãĽR{Vïò")ÇOÛóóK¤òÔÔ2Çýñ>(ƒ ,å¿‘øä˜@-µ‰˜_¬{.nZ²ˆ5ô‰ÝÝVc‘h4-D’ŒRe÷¼(J7‚Á´xzãñð ¹äÈ¥Os\=öñô™Ò£*ìKºšS¿Ü²Gj$ÓŸ?Sœ4á}Ø÷þ=ç ˆùH¨ Ýž3|jçóK´ŸSù\r Ã¸q #1Ñ_I$=ï0QC;ÃaN÷Ãóà 3ñÈf©üý˜~é eJçµ>Lÿ¥;AÏhs~°À gr¹(üóuËßý»ü†ð¥+ÃJŠ·š q"+Â:&5°w;è{Õƒ3ë ’6]?÷íD¶±þµN’õlJæŽ!?øÓæÿ¦ÿï‚ÿS^0¹ûh'ÍŒl¸´©íûÔ|œû_ âî¶3Ûû(Ì.™Àz$ï@²± qÝüvÉÿ¨'+UNm‚]®FÎÝ\éÈ%„áªÓã5>kv} Œ zæ(dOÌÖ¬ßp_žÅ˧n®‘…ʼ>1H _ ïî”üßK›©;€Îip  È o ÆÖm]÷ƒ´{ÓÀÌ?˜¢hŒÏïø>…$Çùë¾KD1K¹ÿÏÓÓcЯ?ë“ÒìÊž¸:‡Jš¶CÐ?i ÍÐ?…tJ€KŠ*½¬×HÙSšrtà¼*ô]Ñ)æü H;œ×6¥ÌO÷&7y4j2Ô·œ •ií)ø¯Ä½hã§­ëY(Êb6à³¿ä»æ™©m ÿܯ62¯gÍ ”iª)rϧœŠ/ºµžáCsªÿÄbÇp. ÇëÁ%ó[cB¾ÔêâÊÂ'ýÌôÇÑ{•<]¶ófêü¿³ôÿ³ÝQI’»OÖ¬˜OèTaöýªù#ÝÿœÄ»Ûâ¦IÎQ$“ƒvÎc …Z “ÇqÌíA’;”£ëm÷ö7ݺ¹qª•³tN³ÙÕõ±ï72wäüE¸½âbxÌQjƒI¢‚í £×¯XçÄ“«A©ø1gœ8‰&Vm`×K›I8l}Í­A’+;9Ÿ ²` Hç[çOœ£›³ØV ñÚáßQéãe¸»ÚÜîï¥sd„G)û÷{~'}1¹pê™Ôµ%¤âIi[‡T«k¤÷©F ¦ÀŸŸSÇ6Å8“´‚„Á—×2©dG†>…sþþ¬Sq²kgúšK‡8Hê+ò©ÈÑúám£ÿÓY61©«j”¥Éê}ŠÆâÒ©ëWº˜V4 Ré/cBaZt8C é3a蚪BQ®#ÓÒº¦jH ¾èD(ÉúWckyui€bhÊ Û‚Ò`,§pú“ˉÔ––% €}þ8•¼D²)8‘ÃÎtö¿NÿÁ§Š ýå#œ 33gÜ’ÑfÈasÿÍdí¹üK?F‚ dØyÕ–/Tmþ3„oH{|ñ±ôßø~Öµd²ò|âÓ¦¿~0âèöôøþu鋽vø‡k©£ÁgŸ:ÿï$ýÿ‡ÿ“©­45Ö(­s1Pï~ÿß6©€] `ç¶w­Ê€}.†õÈwJÜ'#CR°{óÖÁSîdÒu‚9îBãÇn°Ð£ñ³8âæb–çVü²äP?ê„ñ<ñ¼Wùg;‡ TéÌúÕ¾ûs¦›81ð4äáPÚ×ëéFmÙ†ö@”WÏ’–bÚ¸üÿ€ÿŽºŒ¯Rc[HI p±ÆeŒ€DЕnæÜ}@úS¦"Á6JÉUå&wÏ›ègɹr“ßPU~gEè7ö²bJçÆç¿täqëmbyHìçZ±nâÎ]?ô‘ô4Oj‘$]%tD]§¨æ_© ­º²hÑbŠÆÉýÿy±“ @U=xŸâ‰PäÚü¿ƒôÿ‚t"(/˜ ÿµ4ã"ïѰMú×رíÝú_«ZÚãÖ?š°dÃiüI«Š¯ýb– …]`ÚÍy`žŠO |J ¨V‰r…w­7OÕå‰;¹ê"¶~Ë8ã´u¼+?%9ôè»~˜ê×Üï‹§©JkÌØC†a¶6̳ñóyy. #ÄÍ‚úÊ=¶êÚ AÕöý¯·ìÂUi×°'ÑÓmÎy¾Z1#£·qz(øxÚ'<ï G>uäY_Zþ}S¦pÀå+䕆è>;”\´ÇóoâÖ,êÙUÇ Æ$Ó a¬\ÅM=\¶.Þ-ï4D”>Pž·©tÔ\î‹§ýÛ³tH“rZ¬%=(R8Ì–š9¶­ô¿zËpXIÙÖñ lü”ºlñ\ÅǦöôïö¥E<&éfÞñç•HâRɇô9Nêüʳ Hc?Á¤Èßå h?P­¦®áOÕ̺’+9•Èn1èâBr÷Ii4g“| !-¼L¹9¡Õ#ßHª'ËåØ ÁÁ[JÀeüd6ûh*®Ú☰¨£4ýÊÕ®›D@Î9øBá½GÿW;ücò!iÑãA‹ô—a|jií¨ˆ Câvé;ÿ¬Kè¬6¾<~'h1®|ý©óÿŽÑÿEbe4º›¹ïT°mêר±í]@D¾åÄ a¿ˆ™–L²ÞQJ_¸ˆ#η𩖊ýÚ:p{Ùè¸VèærVàŠ‰“çøpÄÉ2Ü]døâÚ鿥¾ÙZý«4å/Ý̼9½d‚_4üÝwS½~þk9ÂÝÍû¿r_Ãû ÜT@¸ò €è™Ùü‚8ê@™,óóúš#Ð<øG«ÝÓß–àÚ-­?׃‡ )Ÿ(½â>½Ñ^xÑ1õL“ßîpê9p*™t¦¼·ü$J£ò±*êf_é¤ìô"#zÔ$ˆ ¸+ç”6µ]G÷ŸRÙ×ŽÑÆßó2LA'S£âÿþC¼îœ¬Ö…Ñm¦ÿÃàVHQýtõ§ÅYë“ù¥G)òê¥Ò¿/vÖÓËÔk†xR?\{¯þOöû®Pùò€¨´i} -ËšlF© ‘þh4¸ž“.á“RA—óo¹„Òµ$¦¢¾áDÊd4€Ä§fúû–À)Û"Íýo¡¿tÉþ®04¸5[A+û{sÊ<´'W¼šÎÑbm¦ š¢¥ÛàĶ-`ö~ýŸÌò„ûÖ?ü‰k4¸j¸µïî²õ¹þ—ÎS²H׈A@ÃıG‹tóÊ$ê䨧Îÿ;Eÿ?9®Å) ’ 'SKXû>•¼ Éç۵vb{‡ ¾S솰›laÑFS+ÄHñÅÍ®c_2¨"Ü7óÀŸ©‘ówÁ¾¯â– ÑÄT4Xí$a91л §È±µé#zz+2»]ëñ/ f¸`­ˆÿ¹h9þGY<…_«¶äOñP•Wœ#¡$rO-y¾×CA:Ø{wÄų(îú:©„?¹*/¶ ;«½ðp &ÖøU=Š‹ü%àÊý»_¾J¯ Šít®9Gs§ 03}i ŒVžVzê°ßZíQ„»A…=܈Êî4ìù--²‚—“ÓµÕX€Bòl#ý£¿‚þ¯’HW⢿äòQ,¡Š¹ÛìA‡-×â¯Ëˆ>eá /ö‘ÔüÑuŠ„°ïÚI“QIÞþÃ/àÿ¥•ħþôßœYñ¦ïø¼‹] .¯È€¬ëM.SÒ[6ܘºíy;ýï¡ë¦öÎ 7r3aeÔǘí%×vºßâúX à¯kãH+Úê0ë†Ë÷~8ýÓÇ™Øb 5BZ*ý¨¢¢=Å5êÜ•¾{…ÃÌ!0÷¸¦•-%5z×: ²óê_~êü¿3ôÙ‘Ö?Œÿ~K÷°ÔïLØ~õï'hwû¿ÝÞn´CãßéÌ¥È{ 5y¸ökÈB/hÍ9ÚÈ:¹+´.]¦7||E4à¿n?˜Å?0q ®OÒ˜ ¦ñ >ø2®Û\P®ë̺Fãkž‰‡¸è^Žÿm) ÂåA^9ÄøZ-Ë<'ÿÂçñ½­›ÜÜçß4ãÙa³Ýuåô0Ÿ*-Ýǹ;qwŸ?£'_t |^vš†´»´¥ã¬élØÝ×ÔÎ.u¨?^˜Ò ÈPKàzß)D}¥g=ãxézŸ}þ±“H±²x”»ù½FÀõbãï*Yׯ¦u»|毡ÿÍï ðŠø›ÿÑ»t ~ù2uŒ /ÿ¡‡iOp€Î~§¡ükihóŽs:º–òþïÎ(øy`Bó_>A=ËŒTò무*t£éö db¹°Ñ­®g ·\6®FÀJ^\ùè;èÿ é~K[6õZV™×¿n2Ù6aWulÝyˆšÈüº«Ê·Yï³B*­XÖäp ÿýï/Jò…»Hß&y=Ò¿l˜®‘‚ÈÆå‹ð¸Ÿú1zæáæ¯ó®R½|üSçÿ¡ÿ&d¹|ÓLá=ýÿþý¿kìÄöV@IÁzf‚­XZÇ€®QãÿÕ™,"¿8 o€¡O”[ðöjÇâ[«I€ž¸Øgô»äQdž•«÷ix0W0–sí‚Òxæ8_3·ñùÞù%W>^iÀó%´f(pé<ƒÜc¥ÝB-Pá­^ÂT“ƒdˆwpÔø²)òSÑþ§¿Ê‹I!çGØ•“‚ó)–/uûÀ+)Û¯øe™íü¹ßNEÏÃçê¥ý ì+¨,°òoâ·¨ñ‹cÎaÙ°ìßC׬ë ÅÝoô¤õO$ݽh‡6‚‰ U«k4ÔøõîpbT…7Áº¨øÆWs™Bˆ0L,D,¿¾ç/¢ÿ¯}Ë€†(ÞmÍ-f.Nà5û&4™•–ÀõEéÉïÞàßéCô7®¯ká//ïѱÁç/àÿ2ÆõàöýþϘ8ùãË:)¶dÈ@ÞDÖ5¥awŸ1Í}†)GÝH7òo‰èÈJѾwÒÿ¹ÙæL/æÂK7XF¼G6}@˜»îøåÕÚèmñPý•SˆŠküáÊѤÿ掤[’±Æà ½½9O˜éf.‡ƒB/¦v¼q{5‘Œš»¨ƒô?<épgnh­?WŸ:ÿïý_·û¥2a*B<-­âÂÿaø&¸Øð±øÎ‘ö'Ê88Bææ§ÝÉ«¼š¼CAœµ)°:ý„®vóœîCëD'S½™(‹˜«9:RhJó‰l-Ç2„ÏÊ„Ò4Ùk¾/ÊY€J¸sÔÖª æËó‡ 5¶ý=çd›{„»Y_cÝb/{“rŽ1ê0é°ÜQuDåxìÉ]’h”Ê"M6Ú€û]òo†çÄ¡é¼ó ƒ\ÌB¯¼ûùѻԪ;6÷›¯$‰Q5Hì…‡<[œTà–Ù÷z!oükÖp×Y–«å4Fï«n%×ÐÓ:ußl=w€ý5¬^\yµdÈdû¾$G"ŠëTñ ™Péèþ.K‰³+0%z8V©- ËFZÕ¹É%ÝS|.„Ó²õñIc›(Àƒ0¥|œºÏLŽqe²àžÛ· ¨ÝM÷‘áâÁbËRãžÏË×ùìˆß‚›èKu›dí+OÜ(ÉgÜ(Šá$paa¹síP~eûÿÎ?¾¾ $4CåòÀƒ²}P¯8¤Œ&eÌ`&}•26ïlÍØÒ×»¼ž$n1+qÇ~ŸÐAn,,W‰ñÃЮn‡£6¤¯·Éà„ØI=Hm4”ý“ýÂárd¢×ÅÂzö”·¼N¼¯ aòº‡°EHé¤ÿ?Ù½b£Cì W/¶%×dÝ™|ŽX•*)ç¿õP †|;©ñD®FÄÿ`ª½]`ô(û#£K€W㇮¾y÷HAàŒLt;#ɹR6rCF_#s¤ýÏÿÿþÅ' ”¥ß×{Æïã¥}Á§[V{rkÐÌo× G¿üÿ})ÚÛ0Ò£ø/ù ±Šýõ㣳i…øÌ»WøŒôéP ®¤^¬8— ‚´–mÚI” ç;_×cµò¾Ë§s{–j­v¶b¹žÜç ™¯šDûdœÃBŸß-}YEÉ+"7$¼_‚9³tÚCô3˜ÖmT78%gdöA ´¼^ÞÙ%Æh‡ù®¼|}z@㣎ű½2íñ°‚˜Z®¾ b·Y &ÎÛE;§}yꥲ¶åô,±]€2@BI qÁY‘¯>±öɨSnËàÀè33»r`îµãKPDZ`¶ãV(~ϰþèÙã&£;Ü?jŸ:B«\žuTaîtÚÌð‰¼ów¢Ç¦0 ^Û@p,eî¥m%}Ý¿– X»°¾Ì‹3ïj“ôÔ¯r)“šøœaz2È‚çÉÀî<ö‚•OngS‚eÎÑRðaütiƒw+—š¼ŠÆù["‰lp,B[-üÏïL=Ùè{Ý?#¾5&HAàÄ-2|ZÒHã¨{ '¢‡þôœ–z„6‘‘7¬ó±Ù¢æîîèÙÚSÏn^ìrN±Ë¹ô¾¿áøó=6do…4öp,ìßl›ºË¬v{âÔ*ÒÙ˜ãðÁû_Õœ^NÑg(P[q ÔÖ¶Çc.â!v©_ª‰²¤À^œâÈÞR¼µkè}]ðºNù[!ïËŸ€Qðµe^¸5 /“ØÑ*ïLfJ%YA{Š'#€`Û̇:j– ×êLHä»ÑCëÙ KzµåH‘M_ç="·h\}ûŽ!n`gÌuÌáf ÜüÔh5_¬Oxî,)ÕIáßýô€Ã½ÄÝò|•粄õR½ÊH¶ÛoÍjß»W"ˆŽæ›0¹Ô¶õæ„ÉÚb¨Ì1 3Ù]ÀSu¼:b}Uÿp˜õ+àégçh µng¼ Üú,Âê?]ï y–7@(úSbš_YþÿüuÛf›áMEÞi °pèóÈüLêR¼á yëúËÏ]í^Î6¿•8&}ßµÙ0Ãð:¸|zEµ°°ûÃ0ohëK‰³åx®¦¼;D_Þ.ë¸ú7å¥ÎòvÞw3˶Zàð³JÒDŒ[—ÊÄ¿âf%Xñ|\ç8û,G–Þ°ð¨H‡;çGtóc‘1ÇéW;Ì&Þp1 ¦Ýlóȧ•TÛÎ#­îœ…wk€rA”Ž«a«Ö½D8«°üWüÿhþÎEïÍØnFœÈJÄÜ*ÏgJ|#'ÿíŠuÀ„yÿŸÖ ¿œõoÔ£¿äôo̸lšO©/d5­§ë&)H¼OÝœ‘Æ%¹÷0 ¸Ø+j§otÞê1¥€nçƒFç¸Uà`²³¬õ‚ªQ”‡¶P;¥=C!Ì‹|9Èñ°äÈãsáÔ»Ó:Uù+c9.Ä~‘"ÞÐè0]2>2þèw—3o3ëðÅÂøÊ„û}è‹¥†’Î.ú蚀&aîÄÉj—ç ¼xñ¾\Z0+xTºµv×ä~¥6«6u_ôÏìDyÝòCß?¼!D3üD4ýð˹ íÊ(-Iµò˜¥Áœ‰Ùà¤Jò?¾š@wG¾O<0G~×BF!)˜fÇpÕ•À„oçåOÞ¦×v{âÌF÷®s#ãï•¶Ö* ò ùî˜4LÄÏ3äÂÛªdQ¹lu›§á¼3sƒ»0©DЃW’ {øhŽA> wyr Iê¡诞̓5ë?vEïY•RpÓWáh`›+Xç3È…~ê£pò…ÍAÛÑKÇØ4ïÍwÄæ©l =ŒÖkµ–J¹šÖ]Åp%¸Ñ¬£Ñs e*íÖÃ9µ«~–é-»£ „sÁìkïì›àjNò@)¦·Ê] ¾óÚÃHæü·#>‹Æ¹üÿùÏ%‘Wí©?î9¿5Â[ضME½r>V0VÏEMúöEÀN‘–9²M?£˜{ ?{ï¤ûAõòºouà?RŸbãA}Ø\cZuüÒ¹ìUU£€-Ü&YÊËô>Ýþ^>8eÕÏ·V.“'îÒŸâlvI'`g½i],;¤ý[|<ðñÿ%”Ä2àÚi§+ç¯a¡ÞÖxµÄŠªØ ‘nV)ó|Z¢}uuʇpâÂËU˜ØçcO€û×J={ÿôñÿƒù'|¦þ:™÷²C1Ví\ÉYŠÈ Ëá¾·­³`¸ºý…ègA9EþÚÿ’ ñ·ZºæsŒÆø±Èô~™s=EEøp §à³E¤ÅðŠþ0>lgöÆž¾ÍŸú1=ï`:uŠ ÀÌG õUO(ÆR~Ï¡€ê·BŸ'¶t3ç 4Zá„÷`–/kE_Ø à«K;ÌþúøãÀÕÄÏÙeÄe¸Àк5ˆÿ€ñ´Ê}ªžÇñôAøÒ³x—üºmSȾµ"1 Kj_ͼ®qÃÙ#M±Ú¶t‹-G6鹜æn‰ðçfªk=€{7[ °Å~ô±ÑX½Er|fämr-…$ÍsY,Ùn°°®ÎÅ\oƒÆ‹KÁ©ÀœT*¶÷ŠÀ‰GVØ…ýU–@–PÀÂáÁP&æŠ ËQ€G&c0èFE´G%y¼J¥ñtÞØïšßyWgsz€Çó=˜o&Q»Ò­zJ‹ÏÏw®ˆ/ó†IVǨéËúĉwÛ˜žeõ:zuJ± Þ#Xyx¿9è;*[:Ï]‰„š.¹*à!u£ã †÷IRÅ“)–­döA‘’ì”>ê¤×ŒŽÿ^ Q£­‡unV˜ão­Ð3©+PÝg¹êø8‡Ó$Q¨ÉïµØ}'C…Œ& LH)L“6Ÿöæbxˆ¬Î^m,!‚Óî〥»¦3&&ñ?OBU÷­¾õcnŽqÖ2Ft%< ­<ÿ»ÏR" ²[A/Jòq;©‰G‰Ô¼h [9à³ ¬ßõE’× jfÀœÆŠ”dq=,ÏVÅÏduBÚtÖŠäFÆ Ø”cxIgSä==IàºhIŸŠóNœø°“8¶1,4ú`tÖ_–Õ‚u|pŸï ÃÅý42ýøR2?^o˘n÷qšÏ•êD€…e… à,|š¤Î‹º¼ƒt,{‘/d(ऎ=C¤cgÀP"ûÓ×2Û`ùøÝÑ0Öj$Â;Œ mÜt>ø-_íÉmd„–®OlÀ ‰ñLÏëÅmIaú(Ô9£©±ìuÜ„×òpÚ³5I)|:ØÉyäÖ˜ð[U@uÚ¨R«>Lª‡·ú¡®?½âó¾zíh!af!¤TÒ¦fšÈÃmòüdmðúnS;äå͵…àø‰Ë5*&DÃ>Q/ w31߸½`D"°ÅŸS¿&ªÛ0Pb"y]jÂn]jV4K´Ù` ÁÍÞ0LDª¦¿(_~L7€ÒúË”W=âNHÑÞa×O‡µ” ²ø!üS © 89bST‡«³Že®Ãe‘­DÐùºPN²Í6°§Õ¤ƒ„ =:¸.^”-puÁz0ôñ¦öÊÊs"\ÕÎMôµ,ç¨8ÐŽÇØî>ö®N©ŒûÓàmÏj~ÕÈÁ—§KT^+²ŠŠF; ¢s“b{žZr:>3?›¹µ¦‡ îs.´qÆÞÓî)<.î3Ëåkäo›hDãs♌çÜÓÈOV®~òHn›_< ª(o¸øÜÂÛ«ÈB;6Âå&F2·}¼~ÿGÖAƺ[×/aÀ›ê•%ÓmÐÃVýyªù¨Ý•bÒH…„«¬_p´2*䃫Õí3DÛý´ìƒ3çÊnûÀš ¯ÀN?6·ˆüÀ‹®ÄaË¢[_ '9Ža!qmô=‘~Ã-°t|§â½›üIýnkpºKˆRóyùlØÎÉ1½ý5ysë-ª²s_LØ>ï÷Éþç a!¸@À}uÑõT8»¤¢S51iôî–­’`6¨“@B&û]¨ÉkEcfs÷ÏÛ?{üÿ`þSC5 ô»üàFºA¢I7*TŽoÿoT œ³{ˆÿX¾‹uÔo½–ö—üß˯ÿw!æÌ?‡½B"ï̇Jw±­\¨|Ò”ÇjþDJŽJz»4ÞébT^ã@"KÒNlsTo((U“$|¡Cúñ¥JÐ}­g®òõ«Ò(zºIÿ¢öÝmo[ yžÂÍæëVjðAF=³Å•&e:!zß Y¯6"¹oD.õËy«K„q *¯Ÿôh1>Vœ p¤È^höÒ´¡­Q¶ŸÍ»b†$&nm3pbѽ!–ÃêfU€Éª¢Ðmꋘ¹ŒW…ŸÞ&>¯¯Î…î²Àeº˜´ÒF3I”㨹C-Õ¬†ñigwM%-õ¿ï\T ÙWÇú±Æ™¾¥9þîòîíÝ®»¤äžºE£×Éq“¬³4ÐŒðß5èàu¦ ´Ú^Qk'PÑ¡íÃ^Ø«Y…ëZ>†µÎ«œs>A‘+ËOŽìƒÐO;!œj¿Âü^þ£·ÖÁA»G¦Œ:  Jóäco žÃxÝk»xõ3{Õ`§5Mæyã³þŽsh» ²ÐYXì;{sÅ£·±–ØÞ0êRÖýò•Æ*o6KÍ_¾’¤w8”nŠáTfô@=ÏÎçlnwM—îEáBûÏéÕºŒ“ØöÎìRÈ3k`2¾Ä,ÞB}~ºéÚmÕÜ'g!MŸz wiénôyõúö½ü1ü Þ¬¨d©Ni™0lžoÎÔ¬£ŒJ:>¸}’¥se~ÿ¡e‘¼7ʹæàl˜ëºöøXC]¥ÛÈ;®í~ìž|á¾Fªq.)ý2êÈðM ’5%çƒâvÙ‘át±ÖšDq+ÿ/ù] |ýI ˜âè÷:˜&Ø„Úf;’®¯ï3>Ríúä@U‡’}xþ§xö—?k™C™ºØçå¦7k®*þ†ýÈÊõEÿýâÚ×ÈÚ‘_”Ï:!¨ü8xÍI;YÁñÄlm­X†d2o½œ¢À±Þó‚íOrRóÇ|¨‹SÔõÝ»pB('þìñÿCùï?ëÈ$¡ì_îxþÛ¶‚딟äòž+fëþF±ðtôýã‹ó_¯ü@ù­7N551êG.Š’Àâf õªd´ô’ä¡’²¼‹©‰™÷†¸[#‘ÌýÄ>ñ®)÷ Á¹¬.j%Ô#ÁŠp<ÇÛ.ç(j”7hÖKî«9'¤us †0Täë<à4»’ލZ+‰ÏŠÞã\“¸’Ö… ²}ª ð^žô\B¬ €¬Ÿ…L÷éê¿ %O¸BGr—g*ÀP¤]Ù –Àv ê–…¦ggÖ¤zŸÍZ4ò“Wi2)\"Gï‹ùnxÌÉê½!j4C‡]¯= fuü¹Èr3™m'NS¸\x§Í7Ö#ÂÜ|Ìvœšaæ½] ¾ƒ–rø9ã`g4®8ú?‹’b!pª¢zë„ [ü†ßŸF/@€³‰)™¾ZÁNIÕ¼ ¾41Nrö¡Z!ð(8 ¾xxµ;’¹†±ÛÈQ´ßÊOÍoTÖç8¡cª\j@¦»Þ$YVÊoLHbŠS1[Z OZvEm-aeW•äSšX9°^½Qrýò¨¼<©„rÔ¢‰–Ç}UµÃKÔÕuþˆÍVŠP'QtC,‹\aš”ÍÀ/Fn[Ôs}q/×ó®gôr?ÌßÎR–PüÍf W›¨ô©PeüºµÔ¡ËeÜ‘!$‹å BÉC·¹Ÿ™E3j DÙZ¬Ú‰~r&/º‘ì¢uàêLî»àºäþ…>lo ‘‘ìËýaüC¾Œtœ!€Îbÿ$žE:>ˆ –”ª¥gÛäXiÎ3(ë\¾âú!ƒ(ë^õŒùÔaª§GÈ™‹¼‰Ûu¥0Çy9‹ÑÉ—–é-—¦WVRŸNŠ[€ŠdÏ]¼~›šXÞ‘¾­ÜÉw/= ±ÃQHXÐ]KŠƒô‡‡ˆprœ¦t ïe€¥­[Þ‹[i×kÕœäG¶¿Eîà‹´6ˆ}ØñoÇlÂBìe¹cêM´¼žgt;Ãûø>ˆº7D¨1ò;ùl©Ý!¦~58zìâïä†É²ì ž?ØÑÍïäïã`Vëd•àÈœS±D¥åø0TmËR´‘¬Kz«BîTüZ7­¼¾¦R…¶ŸºÚËÏËÃã{×q7d×Áa´T@’‘pSá¶€3aϕɷ§®3Çi4·¯ ¸ü›üŸS-);ì™­óîÔºPoÃê^­ÎÂB´>D  .—óˆÛM‚j‘¥k/0 böø=k;žKËvä¢Do¡²˜8YUÔO¢2dI®ÑÅ_œØ±mÉú ¤.¨ù³ÇÿäïfA;zwbO7C¶eî‘ù#ãÌ»†B~½&`QÌ·ÿ,žná?ÂÌ_¿þ ïõƾ<jMÆõÈ ËÛÌ8FÛq÷vï’§{ c/sŒï»':]52Nùi€VÉ ]?¬sRaRb}‡,¥=©ÆßË?KßÅYŠþ˜×rrc2FYrÊdž’·ð9_Ð;ï™Ù‰Dú©4¸NJCßfTRûÛ Rqg>­×{ß'7E­ª Ië¼søÍuûè[Ò¸¦eš­ñ¸”¥%'ÿ p½s%Ö—Òâ>èY½©¤ú÷ø×=‘‘ÏõèŸÚ,@mç-šjd¥íÐ[ÎÐ: ÓÉ”ÎÕ è²ë]»­ù%O؆vÚÈ|B]îr‰h;-…D(ðÔFàý¼žÙ…ÖRCâä¹Á/e Ä6KÌÓø³ÇÿäïxÇV7Ôí.àÞṮŒRÞMÏßßûë¥ÂÝÉ?øúöïŸÅ>à‡L4þ’_ÿ-è¹ÀÕËÕƒs7.š\ÕO´µ…4le¥b ƒGñài·ïytré¾,p®Qݶ‘|Êh¥5€sÞ—ÚsÍࡤêä^ƒ‡&À àþÍÆ×`§ &ù*;¢’Ã&ëeá#5›ršj€óÞe€Ë©¯ûž³tü¥rHÿ<_”Ìû,‡€Ò!­›y@t=|ôÔ‰,àq·þŽØßsR0‹ßÊëÆ©Âp±ˆÄ’À¼-o-Þ%CõËתÀ«·Z»ÎåtÀBòUzÐ-ek#@\uhò_慥ʓôá/X‘‘<½O9~hë³(MS•œy/R!ñ‘^òƒËü6.±;R7 … ®®¸ùfýT•#ØÍó¹.Áç’[wüòÈÐSÕ™®#]ŸÞ¤þXþFÉçZž–õÜ‹á|˜¾ž °ÿÙ» ¢ûx¶øXHV{HÖ | ~–âp|\;ÚFasDX«ŸÊmò¦€À­áUÐ içz`£×1>.žz?½ MØMe«XÐ.èg!Á'!í““ÖóÔ—Ø}°$}[Óç¦ÏT:îbòìl–©@Rùý³3°¿AˆýDÚ»z…Ãô }¶™W9·»ðÏûšúÚŸÉMƒƒ×V Pï~ÕSAêÇy?½s·t§žÊϵ'Úèõóü~þýŸŸ8½zT—^;Öö~,>L„"5»óŪÎÕØõÃJâ°¬}T ËsqálÅÃ|z8;·;%Al°±pŠÀ·t:=,³`|û«¦Ì§y¸˜'E&ZŽX\ÅGOø éÚåó~ª7ãG½#}¹ÿþt\;Žp€™~0·6½eAö ÐõîÃÍpæn×QØ[º¼3è¢Þù‚;·×7ÆgÛ(`'įâ8¤v'ƒšè@&ÑØß,:Û*â€%¦ÅÞ6¥T‡5 øÜGöD‰MLw$/l—N‘ÅP¸îå¸äXÀ²œi¤¹êÂÛª±#5Ec}u/ lµÍKR;u˜*4Zþºg‘5å+ð„¼—uýweÁÌ!ÛÖã6j|{´bqÅ;#zL LÕ’‘o,¡"þH¬V÷w'»q§‘Õ7Šp§X¦ÜÜÁÃÖ>±\€Ç8PLJ °d²ƒñРàM |[§?_~ÊÏÍO?•jàêSÌ«->÷ßdT –sœyÍ0õÜû”k|ûÂíSO÷8®àh]‰õÅ€)’2.é¶å³Í—0‰’Póâ~¿²½û¶ZŪ"ÃOYôú!øÈëÌuf}U×̸µ¯ ÎܳjËTË ùlI½ ÷Ê]³§¨ª:—WI:¥&\d8¥œŽ¥CúdOÁK76œe©´=ƒåÚ.E;S]X$_WHNš¢—üf„»x?ÎÁY”ᢠ©ª‹|Wšj)É\ý;\m"hGD±ß&g„´ 0ÿþ_¥x¬2Þ¶ '‹‡ææ›n½Îx@©eÒ'¨¥v¾qß˻Ǖ֭’sàj}ù °Sª–t;éÃ4–¬Ñ«F¶´ëKœGcp6DmÔhl-ðÌöâ©™·áuj»ÃúgÿÆ¿^ý5{¥UÑ‘e‡t1D`„Û¯Š~Ü‚w|²¼y´É}Idž͌“9îù–@dþ –#Ç£öpä²2ž¿þÙ®jÇ¥i·x\øË¡š£ÍCÙ»LÒC½¹Ø°Eäúr~'.ÍãÎÌ-_æ~øãùw&Ú$RàAB†£S-øH$~»¨©²*¸vü”ð£ðÌ%½ØÂ¢;hŒ2LuÊñßæ¾2¹ãa'¦÷6€ÇöBøöŒê.Î\(ÛÔ· P}’ŽœÍÃbpz%<‹ÖN€L3F~ˆöú½ÉH¢ûíU• 3¯ÛR!£½¸íÂG­Í‹‡Bêj<õÉáaUtG4ß±„„{2$6]£öžlzóÖõkŽ-Òýç› ä_XïÎîè.‡ÆËoifåfågÙèu19ÿÚ ]böÐsC«ÑuÜ.ÛF°O¹|ÿ㸉»Kî3S¿ØdÌ—…»l¯iÞ}mîÛ_A,‘=ú%‘Àb¾åf„×ËC) “®u§èˆzu ˜ž Ôî- ¾øýüfK† ï½ Î~¸-)ÐaÁ£_»«Y’Ë 5ê :ŽöËJF°ù„×zËd0 ˆÿ N¿ÓÖaǃî{ÌçáuùçTü [ÅG…8·Ëñù˜ n…NÐV »79¥A8*¬†äŸ¤}ñý™þöøÿQü=#ú>àð÷Æg–)³ƒžmÛ¾òkeå@øƒ¿ýûgqCÿÆ‹Éÿ©üËG¹Œ'*wA(ðð–ò£¶‡«#r¼ê³Û±ó€;Ûæ©€þDfO”TbÜÞg©Ç®Oѯ9â Ð 5ºçŠ|äöxŸl_©V" ;Ä@Yø8Ä%c5ú}œ½ùpŽ%¡\ I h»/UG4É€V:–¨ªnûfÉ#@æØã1Ü$'À›±G»Á½ »FHWŠãð5ºK9@¯WÉ è:•j«ò‰†¥ºTpðóWA9|éG²–"F½>ÎCàör¿/bß]ü=³òhéÒ­-né˜ÜlÅ>Ú³"®Y\µ€.Õ~ž~M€B§N=šg¤ ¦{ŸÖ s ôêŠëÄîKãòN{}£:H‹“ýç I¾w®“êüDËY\¶5h$ΙóÏA¸*/qÒáD°_d|<ª‘ —NM*õ21‘Q\šƒ#c4óøZžm´c_¹Á®í À&µÞËle ‡ÔuŸ«xŠtôÍõáXÇ0c¬„êž`¥ÊÇä˜Z_õ Êh X>ãû&îûªç=Ès˜"µ“êÙËtÞ„Gäž^\¾Ö+óem„°|—õË;Íd‡šëÕæÀ v i×Õ¨aÑ&ÍÕ>¼oºÀ1t^°PÔó­X–M/ÅÖR½ËýG‚øß½qä)1Ž<¼*/ʼ„4·¾ÿ §clÊžàx­eöÑSƒ]ŒI» ¼A¦ro_0xÞJÒ€¼Ë÷Öñ‰y%`ÊpÀ \÷œ&Õ~NRNz‚}wðxF“ùÇlþõ*©?=|G}ÎÀl2Ã6Œ]„fØ‹z 訢ïÁåЪ9¸ëWÔ,çW­¯]ì#_Ë $e$W+{ Üqg=H«f3Øùâ¢x7¯ ¦³­”-_fwʧ‘ø‰Ûhv{1eˆÂÐóvo¸¬NÌÂÀK-.Ž‡Ô¬´Á·µ Æxúÿ=þ¶SXn›(G0S±ú ÀìAî>²Òe¯Ÿ¬Å¼l¢?– » ¶ûxìê´H hm¡œ:Ôu¢É<¼6ýÿ+‚sòøã¿ýûg± ùqþ¼âùÏïZ ä¹(SßG깜‚>ª‰zXüØ"èÆ=mT–Ôˆ$<\yÿyüí¸‹`~½‡¡H{5ôäËßxÁÓ×ջвïS@Æì¨ý›•/šLŸe®ôë‹»:áÀÙÝלoß›m»ÿìñÿcøs˜%PDÜ\¯.g³ñF­[³þJ‘ðpúßþý‹üõÀëzÒÒßWì_»‚LŽk¿¬´÷pOݤpÞ´µsG< œò¶Ù—Ò> ±þ$½u–{²ABáYm8¸5K»Õñ½ ÔÂëžêØD±8mÆ¥³! "`/nw…ÍWÌpÅÑö«ÕYXö¶Í~û²= /ÔúKu„¥A1í.€B7®ÇÀ”Õæ|e»$T[JÅv6µz}&ÿÐ@n⌿ã~ÔÎÛo-QÝà‘Óª¡¸°ö±Ô­§bºb5² ª]ÂCq—¶>qŸ;ØÀZ±$¶@ÀH_!Gæ•ãïž‚ûÛ„E^s]“JÏto—ÞUíØþú±â.§ys[(¡€°vøt 5ÆÊ>àq ‚©ÏQ© ¨§ž…¼įzA¯çrvp. ›ÇÖå–CöRcÔßXQ B²qcY3€c o7§q¶ ¼ç›Qyµ¡‹¾`€ºKºª;£yÓ5µ& ǃjY-ƒè¥”šÊK)Ž'æ7>þ)ëèÊ™-lÖk×R„²Ó`ÿ—KÑ>.o„}Á|cNâaƒîk=ÙøèqÍ[þXtd#Z†{à¦W¸ï`©?Œnà ;xrg “E^%Ù^œ—Bñíh%o³¥ÆþÈô·l8)Mãê½S¯ÜrÏÇÚC— –†G.A‹Ö³I#k½¢ÞLi/Ëêg<‘îr56ò¿Æ¿Õö˜MýN× á/“‡â’}Íé~8¼j^Þö•…ù‚‹ë€ýÝ9so¦­ŒåSÖ8ìü” ˜šƒ‚ópæm…Ü+ЇOΘ¾¼ ַ稌ҩæÁ)9i¾Ï­fèEPpmZá7{Ú”ÈæK)î–Ït¸à@†c-è“‹;â!R-*ž D¡š+VNrgÁR|dsÈ5Žôç5›ƒÑvÒÂbÎÔ3iViO™‹%ÛÔ<šR;ŸazO¨`€|ãÓ[Ž¥»nþÛüÕb…›»KAŠ3H?uYó\”:RX'u~ÚþJ–»ÜlõK†à® Ì%çܤú1&'BÙÅ,})æC{ƒÉ0{}Xϯ4ˆ£é/2Vjõô>-®l'ÐLv¸úÐëýe¥¿¿Ži[éÞdpß¶cíœÁÜrµx+ïyˆ4 †ÕkÒÚ·áfšêÄQV·pðxÉÓL—>»-àŒåB×[Ї`ׯokó‘+¢®z‘À)÷Å“%:±8PL,Ö Ú”œ˜““Žî,’ãÉ?ÖßÇüÙãÿ‡ð/Ÿi·Ž¡Mi³‰þÊ„õ¬>ó¯%ë€þ1ßþý³ ¢þfÿ\‚ûÇIVÓ¡íè¯l¨y§¤"¬Ž'œÙŠ^³y›­7¥|”’Ï<ÀóMdŠóÖíµO, ¹wÉ—ÐÐN±ÜÜ|Wë¦~a¹m8œ-iž½þíRZÐ:Á‰%§ Nn•TŒD¬K!(È}#×Å)š"d%´NáˆãŠ%Ë ï[üÛò_´ƒº¯œkÈ 8¡L»Õöý”šÄùdóe„ÌÉk`?f3{tÆxº…ŸWŒÕ61ì1ŸÐ·,¹]HÞÂ,‹\Cì_Oä‚s×_ØfÜûHá\æp,_SU!ÉÆqÆf×¾ñ#ED˜RåU)ûr 'C²?ÓMú'·ýä‰Î}ø†‹üÖ=ܨŠ)eÝ9Qƒ6Ì_ë¢Ú¤lÏÕ¥¶°>šY]V²HÚZ>®¢‰¹$XÚ#„h%†ƒ äºJP^~#¼w.f÷RîÀ,ð˜&ä<"4Ñe¸XD%ìYLØc¤º(ÌÛDÇûÁ«ùVýH ‡ÉØmÐd•K‚”çJ ÄæÀ,!ñÌw‚Idƒ[ÖwF)”Û–]™£S7ñ| $œó%ùóÜL'zýE¾ ¬ÆÇƒC)ûƒ/e’7ýOÙR~}|¿¥Ä{|ø‘«\‘²4b$#UVú9¾í?Œô&¿8þ•&ñ㣥bàÅÕ @ÿi‹-OÀqã3û)5Žl€US¹ ‡v]ti–¦pì»bmï}©.»f4¤î Ñ™q€;™Ìj¯Å¨ØÊö]騷{esè7Ú)bÝÜÎYöoVÂ@W~^¥ŸÄÞða骴»tž#I°ŽŽ+]»s¶uuÒ§Šïì{ø"}ÁVW^—,³×zÉ3Wr:N(̆müü+”á£,lÕ€gåPõü°*¿Â1=’Àÿ´è‚å¹7!£{`Ë/‘0æ[Pxµl_óûÖ-'QÜrS'¶õN”0MvèiItÉ™;ò:;qOfâÓ¼HûÌ©õ¨ý¿‹¿ˆRÿƒ•~K«ÉJ®•iÊé9¥ó1w¦J+´Þ¨ â Å/eì\3^ëˆÐnvÄÿ_ïæ‡ßoBòÈŽÖ~U·" F»Ymo&Z܉DˆÈiEÉ0æ0önæŸõs× µ¯þÙãÿð?AeB¿×¦cÏ}çÓ-¿R!ܜطÿ,.ð#_;üSЇß?ìöXÊ8VË…‚µVÇ5TLVÝò^ä¨âÇæƒ¦ÄëïÌë ¯PZTÙ~rý²Û„q¶}ñ˜Ö¡^¾ÑL€ëœç- sðSb5¤¢'€sY†¡jÌU¶EÔ„ã–b€¥7wšTO°ì€’¸êŠÆì§Ø7ž„'n‰nq­U6î—‚ küe>ú‰@öQÅËÓ°>žìä ½ÒRªj"[a—¸2’L¶kˆÕEz~ÞõpnèãžPMù2‰&/^@'?½ã'‡~÷}§âû Ã->àñ-€ôš¾™-‡ìMØöY`§½ðÑÇÒÎ8O©¥ª),S¿ÁŠ\pOáy¨áÝI\û Êª›Ì§3IpÛ±›ú‹½AíðkÞ”t¬µàzZ~<Å3yÊÓ¹3ÕóN³ tüVM×ÝøñïK:x´_J\çÝ‹>½2-9Û½¬œûÐ2¦ÍŸ"}.`/¢½»Lñ)yÔ Ç½™_Õsx#æ®=,kœÙ(O‘ø!—wê’-~ ©f_ØÑÝPjl¶sÌ9W¸òŒ õÆýTãzEÉçá ñ(oÎ/öžÕ2ºº}ªÁC÷8ÁKȯ ší™ò€áÀ LD÷%ÖR`bW ÆË9Š|Š—¨±éøzæß“íåþ &SÜ3î>»ËœæP> ~¿´rø¿ËŸ½óú”$•º ùBˆÅã.!e:ØúIT’; KS]Ëeñ³ONÄ_Ü¥ šB;P0e£§!7Æ@Ha:Á—šB>ìÄNmIueQ4F»4hbèÀÝOÿÞʼnýCg“ÏÓæŠQdš¼ÊÝÖ<í‡ÿþ—¤z‡;.ÛoàoŸº4Ö“€ÿ»ƒßßcÄzz…lÚÀ~Ñýw[”G0ÿË…þ|µÿsòÍÒ?ìon06±ø¿Ûý»ÍæÉn$ï¿ÙúYçæ%YGêó}ÿ½{á‘?'†pÓ#ŽˆÃj»>Aî!lžŽV¹‹5„œP§<G4q.âpÒ‹C¶°iÁ" žEèpœ+ÉCÂbIˆì¦Z¬kò?@ÀañÀâ îû.Î:‡ÇCðòDfñ›±x Q±øóuÿÝýíeÐ_cl7Á}gE[™ÿü‹½±È CîmÓqXÀ¾B ÚÙØR¢|]䮈 âGÜwþ8Ä3X›öñ?§Ë·ñØŸrÎYW`®û$!Ê6ë<Úp®ˆ‚R’Ó0›¸Y¯ƒ´mÖ¼Í[جéH‹}…t!"™‡s þžC±›ä$|¿ç`dæ€ÛT‹ØB‘(oäÀf°cÜHþH˦ÿÐxåÇŸ*~J$›~û%÷üÖáÿ5ÖYïåÿ„°9ñ!lŽ?œ§ï÷AˆÃyÙÞ@ø‡7Q#Ù,·ßïù—zý½”ã7󨦣œq!›S¤ðoÖe<¢ñ§ósùv!úo6oz‡Ûœbl’üîdb`Œ'þ4!@Šûw›Ð óÿÚ»îï6Ž$ýσd=﮼ 'Ù’¼JL 3ÝÕ3ƒA"æ°âÙ”ƒ,+ز×:[§ûã®B÷Lƒ¢n%¿'èÏ‚ALcRu…ï«êš!… èÑè-Œ0* b #b ¨t¿ˆI°6J ðM·êcƒcÜ [l< }qôïåÿ<„Žç®œ.¸{‹ÿŠë|[éw@ò·3˜…×êdÚã»*r‰’€LW;]«,ÊœýSò?Üì]Þ&vñ!n¢ÿ@"ÚƒnU6è†ãmÅ[¦®|»ƒ¦„F‹`TõÒðx­°.F#bU÷‰|N„E5{x§È“# ÒQ8³ÞÇð/¬Ñ´Õh!ÉðâÎŽªEHƒžö¤gv /^ú¬™(E”Ö2bÜ,õRº„Öµ¥w,ÿÛÀ@Oª²p/%¸ÕÈþ?âÕDüñ½6¤ã¡Âvd±;y`ÂÚ¥^7pÖåS\ ­Ó@3·€à\Qø@wä£ð$á2Ê_P|äŒ<›Ï¥~‚ÎO“ÞŒø­Õšœù{rhqSu#cõHbŠåóÿ^þ?¬6ÜËèúË=htMö% on7þdq=‚'üP8ÏzvÛXr¦xåÏÈÿÙÀ9˜0…ÿ”ˆŒï"©†™xý}ñö´Ÿù«Çv 8 ŠW|³+QÅGšÜÑì'^ÿ§-ÿÿE ÈN Ä*³¸¡^Ïÿëwèþ!?õÓ×t^¯óÿ  aZŽ.l¡µ-\ ÿå‘Aù4ËíO±ÊÃ$#óJW~\Í©8.Óžžu…Ýʦ¯ú½/»UfùÒwëDc—>Ø&_ë04.<£IŠkµVì—r¬°0îæòüuXڔ߾Âÿ•†ð”ÖSlfôŽpk´A•×2——‡Û<°<°FÃþkúG‘>9eÕÑ?Þíl±Ó@Œî¼xàE£O”6¼ö顦Ø$°ù(Ѻ²Ñ`WD×oBˆƒ r;Ž(¼!‚Sh Æþ`ꃃ±K ´:`þãW{½¹ÐFŠAœ«–¥Hþ‹×Þ½üŸõ Å“£¯|öÝ^gK(ÿ>±ùÖ‡ƒ®]z†–Á‹iâõ3b)ûvqÜE[*?î%²Î]’" üñÓ=B³çøöáÅbsU„Œ{#FŸ„Bp7²o>„å±åîÓÝŽ)Cq@yZßOÇLtûìÈÿy£orèÍ®D{„3ù¢8ÄJ·–äž3בÓÁÆ“M½o}¾£üø‚3Bþß¡ü ‘ƒXPh HdxÙß7âÊã}䁆OWE¬@¼ŒZ¾0xœâh'QúIøÑ‰×ÿ)Ëÿyjù"ÞbÔ´5õîkùÿw ÿíN#€)¾Ž˜ÿ1dZ”¶]Úhü·Å{0 $N…ì“vé+µ°åX_Õøìpœ’êÆü]€ñ!šl¾òÌj YIJÎÜ|<„vñÀýõÎ$ѵ/»(¾š¤™³„s›i>ÐiÊ[Ðl¯€g²1åA’ÍÙFè—·ü-î'z~Ûò×ÙÈ ‡4YlÅŠ|ö§UC62$ƒŠî=H`1^e¸¯JtŸÃ>õÄÙkv*Q¤3q)º“Ê(CD­š£‚ ®Æ=ñFñsûâç˜Æ#Ãbô}øI3 ŽÅ#‡Q3 £ÏÍÙÑ7È­ƒ(ÿϦ"ÊJ’ç6zî‹'«xàm¸¿™jç%8ÏܸöȦØu5éÐD%F”îÐÜF7ˆ±kÈðŠ \-€Æ !r%òÅ|—‘ãÿ9™À`Ukfô—7íJÚR¾T2·óÛšÍ7p(a²$]Ba+&Î…¨úáo"ÿoF]Ϻ¹–™x¨­ŒäOU“n&³Ù=÷yo*Î'.‚Ó`(>ûÖòï>î9Ià¼r2á2¼|) @µ…-¢d8 h|vGÛêò¿ °ùuŸ£+âSð:8kŸ=éú?eù¿$Ö_h*Ò:yüë\ð»wÿN*§¯)½Žó“Ù£ILA.åì`i~7}/)7rO6.ÍÈCåò8™Ò`v´º}÷§¾U¶vå ~=:Ì2ï'å˰òHÂSm‚ëå§êÎ¥ÿb;Ì9Ÿ…Ù‡±ðb Škyp,nÆÞÀœÛ‹&lÁR?uÇöÆ,cÈnºÀ9ÿ£ý‰-’Ø[܈<µWyö”.!¨£|ËÍö·”¥ç´ YNú°ÔÚ ,ÎWàpõ³¡[Dôž8ÌÏÙ}(g ¦6$ê=Ť¾jq ‘h;Á¶£˜É-9EJl#N¥Owþ F Õ(yTz=¢\ 7~v°ÏMµROÀ¹å\š_˜Žüבk%ÿ|9ÿ4"_ñpÔ1Rif„ˆn?J™hÆ«*®Ó#ÿh“"ù¡ÌÕ–àX ¤ÙBÓØ5-÷»6Gàóÿ”?ùk©D/fˆJ@ïN¦åwO¾…ÌãR…fq#~!p„AȵrqPÄÆQ p³þFòÿ¹—[wÿ“S€úà(8EùÛ1Lò`afr%À™Nó pëmåÿpâ:[K“𥲡 ±Nå2€úØØ2€àö_ûÌGá,­ ÒEÿߣ-rÏÒ…“®ÿS•ÿÌ3Çÿkã"€ÖëúOÅÿŸÓ|ïÿY! ÿH‚ŽÍXU(üß:H'M¼½ R¶!¨ëF7.÷ïwÈ*ÛÔMp÷ ÉRsŽ(¦_}9Ö]N¹va…rŽO»¬ÔN÷Hñ¯u´Sb´ì¼iÔÖ¢‰îðžž³Á›Ù^áÿʬ¹ÒdèG®’éÁ<ÛÍo˽Ž|s_h‰»ZÜ•=àWõÏþLjŸ‰âµFÝøåZn¢§{Ѻ{ç;)˜Ÿ´R³‹ÇÀ¯QU¢Qµ®nwL¨Kë”ìGiÍlQ/‡"7±„†k¤ xwlÎÇ¿ÅrÞÂÿ ¶ã$ã>©Ê¥©ÉÿÑ:Çhª{Q‰XᎸ:}ÂáF_ïÞS\£‡'¬J‘pͺ^_ãå‹ÚÑ.š¡T¸@½µ:™/Ëgü[.â‚¥^Ç ôs†qÎíÙºœlC=N=™Š¼8¯ß¬ðܧ’4&Ï“XÌÏ­öÉ_㟷PÿKký¶°Ó©¯âì~ ÷¹D€| Ž &ª¡*$(6výBOS=š¨²bkhµ»´åqšw“`òMë¬üH’@Í;óS”ÿ/}Î.«0._@ùï÷è²,žgZ_µÏ=öED£üÉåǺÞb#Q‘”:n?óó D$-˜°9âÿ—z‰ð¹ÈAek(™¢ æ÷"/ “mD*÷#Û•´6±Í…]”ÆTZE§ß>ó¦òßøžï­Ê¼ÕêNH‹_2ÿ]e|nÿó™Z‚ívІËkøýÙ·“ÿ“U ¬ÄÅ+²ÀBà+R xÁæPþ‰+(^¾ZAù—æpOýoV»my“—œlýŸ¦ü_‚e¨ý9øZLSòÿ§À_ÇI[3õéV÷-õ Ëþ¬7iaW¸æKgj˜Ï®Ü7¨ÅMpÖ½r{ÉãpÍNã ì(“¶ùW›¤=¨ÛwîíJ]Næ%èP3ÿø¹'Ÿx² £ÃÝ¢ìòß¼¶÷8[PƒAvh³ÜK]¤ívªF´«k.ÙAØ÷ D‹= À!åÌ[”¤ç{Kœ©Øݾõ59!hÍ} ðkº´ÍsOÆ´x xå-É5œb ‰ €™=® $sKQDìªÚíŒXÜ$‚‘Þ?!”°õ:$ª0’ÓFp¦07ÿ&ø_{ƒóë–{–¯NWþ\@8Sݽqo?¥s6¶„Ÿ‘¦º{ý×>0€g࿜v‰1©¢üµ,Éwܾåÿ§I, 4Êßd¼Ùâj/àÿqO\J(˜¤Žòç`A"¼­*ès8%­Øãq·‘\Ž ×ñ$)|ûàÍåÿp¬³©î‰‚}ÂÌJ‡þøô@£üiHaÓC­nþò[½? ‰µ!ùÏ–ÞFþ‡(3Aæ5äÉ)º ±8GÀ¹–Å œ¾RJY½³èäÿÝõ„ ÊŸ“0Ä´deÍs']ÿ§'ÿÊÍU*ñÿïßýgçúzç¯cý?Èš&ªÂ˜lZëï-àµ_\nâ™xG‡å ^t”ã@~Ù®<:¨TŠ­N?;QNg(Òê.^…ݯý³ýEø}êö˜iWóüæa”+6•›Üè Bpì×±üŸµ8Jü­KÝ®û˜XÐ[5êûcÂÊØ~:–ä-­6—Û˜¹ë/¹Í†ÐÊ6»NNÕ ÿŒbݾXƒî“^[w!Xºø[—a‰Ðƒ„«ÈÈ«3Šp;œÝŽÔì)²î(ÃËþ47 µâÌZ©”­Qá‘æqQP^í|ðÜž7Ù%f3kæ¹fÕ¼NYþ÷¾6vjûZã•…Û?ExýÍ¿nƪ’¿Æ»XØB—»ØHáÕâåçü¿´é˜ ¼€)Ž:vËd)í;PF›Ø­X5`€Aƒ×hyM>÷úÑ®£ ù-&–œ†¼eîê[Èÿ—Ô¯®Èì< ŠHôIÍsn;’GÜufíŽè…Ÿ¨)­vμüŸ±ü´þ!/UB¼FH:3eM€xyOBÝl޲Ña¥Rn%½tþÝOvúÓI¿ 7¦/ÿ§#»~ÏTϽӱH¯Z!EÁí[Ö"ÛÝ›ù´+kj~ÔÌ¿»ØJ3Û@:Pîy~GÅÌ à Aùw&Kÿ…Èá=¿•Ɖ”‹¹‹Tún,Sà'¨‹¬ ù£Wl|úVò·Ýpޏ2ô»œ¢s±| 6)²¤ñ‘·Ù]§<ÿØÌmŸ{sù?îâ_‹cc[ÿø†‚£$RŒvb½c*PPï¤<õ(i…òo›4âŒë'ìˆ- ð»Y«´Íh”ê¨Bíæœýú•Q%¼ÒŸÂòó„VÛºý+é ¼+ŒáZ)Ã}Îû‡&v-!+´M>©æ‡z]éÜ׿ˆÈ‹úì-¬]x/òÿµ¯œ³xùá:¥ó©UœM—.o~Ï„€Î øDþ6ç63¯tÌ>÷´ð>X^wH?¬wºàºþð:-»¤_þ@nø‘¿ 4s;Ìòƒäh”ër§WZpÀ›ÕºÎ𣷓ÿ½8ÄeFI…Ö+„Ñm¥À®¶,ãûYÊÁ•þ›Ê¿òçû?³ŸÕüÉò½ÜsóòLi·—à˜…Dò6ðá¾”4¶Ý˜uøñI×ÿ)Éõ›0²” ‘ÖoÇ9 ˜¶û‡Ó`:¯Wý?¥šíêé­ÒºKÏgãµ_´ZÍäà`"_¨³N¯94¤OayÀòO`SÅnHöÿ 1ònë¶%(ÿÞœý©'Ã,¹·t5üqdµÍÖ¼@ûÆW]Èý‹Éù¡'שFÔ³C+ñ·gO4OìÓ¶VcÕÆ÷Òƒ4Ǽn\vSµ,­›3ÔѲ–° ©Ô‚M ­nÓ 5ŠÑ]ª2×Pÿôɘûr"8¥ò3ÚÓ£‹Ã4‚þƒ˜¼ g÷uyØX1Ü OµZ{-++øF‚büVž# Ñ}ðt 'j;–NäYåµîfk?§,ÿq øÃÛ7îÇL‡œ4VËç#–ÀÒÀ×h”$·°5Lðÿܽ×ëÔŒú6|æÀAâ‰naoÜ#¸tϾÙXu(¬¡dÚ)ØÅ¶ ›x®ÎÔRð m”ÿo+œßà$’Mg(ù`%µº@]—+^5…Si*s©ßžySù?\‹¹ÞTA»µšùkWó'e\7¬Œ »¸€X”×µ3+|G½ ¸‡H‹I!PœQÿô¤ëÿtäÿËPsƒknaqÏÆW^ïÅÿŸFSy BÍ «ˆå’çþÀ2…ÿ[)dac%M_…Ú¼& ÆŸl× /U¬¢I¸qªÂ5øjßmnÝÜïy9<¨^¯îDî€òe³:â–°…?`ù¿üô&sNyk5îf£þ<Ó åF¸¡ÚédZ6 2Ódgq3l^y)hœð ·õ7.»ïÚ€Ñ"ÿÙÎî£ ˜¿BÅO]gì³€š)ñ®%€fON.žªÍüê0{Z7ânÀDRCc@»:¬s.>úf#ÎPÝ/sÈ‚îåÿ|oòÿf,€oÝÙM³J3tßµkåÿ:ˆl¹™Cò߉„¨÷©ª—°ü^ }~(>Bù3ÿ_ÓŒÿדԿ-%ÌÞ–z©¡x@W;Iì+؆óô™×ߣG)¾ýí yñ­åOÅɪ"ܳ`š©ñtÖƒíĵϯ¬ ò} ©Ñ÷%c½„ÖŸ¼™ü÷ºÊR‚,WyéxÛ8odÀeícËl©@(O â&@’(àŽ(Åux[ WOºþOEþ¨½RÆÿ‡Çøÿ÷äþO€©¼Ž!€}é1õëºVYû%Vš#âÂFä?øÍîÉ« w“?uºÚëø‡;÷òŸ8‚öô,ÙÃè°“T岄.³¹Þ™v}¤}¢ÐÍsËÿågSvª°IïuB‚G¨¿#4¿‘º~ü³©{Þä§Â»u*n_øünë¢fšP<%éÍ 7cSëòR*ʿÒXå®ð£:PK«c‚¥øm›êÿ‰G ¹ûP2#^ ˆ‡D\êwn%ÒAœM{]ß[Øïjs±J¶°q­òåÿlÀÍ|ÐǨu4µ ªü2`4g¤‚T-E­úˆ ¡]´' |É Å¼$=öj²X ,lЭoD}c«%)h`¶_úµ‘af/L-š¦ëÇmüe[æ9ÏK•$=¥!Ö…ËBþÏå®gå_<õG9úÓÒk'—AÙŒô‘ °·A’Ge™hs=y#ù?Éü“Ö? ¯_R/DÏPÿV8~ôdѵye´¾‚ê© ÉĆ”+`‰ÊÓ¸á±þðÄëÿäß»7¿ƒ¦@j1Ž­ÿoþÿ4˜Âë¨ÿgŽÌÈêr % ÿv’ páÂv6ã_m“׃ûÞç·£‰4pÎBÙ˜[‡­ 0i7rÓ72ðd¤ªtàÑêD‘®b ¨E=€IMvG•Ujþ¹xn Z5Ù‚ üÙ Lð‘§Óè¡RÜ;Yi“‹#@@ŸÝ?Œí ®m'e "^Ø'KÍi1•‚æÀ=4oþ™ïv÷HÀˆåJ?võÿY%[CJèJ„81'•h!쓽f·¸Œ…ù¡Àqh>|Iõ¼{¹=oöæAé‹÷+ÿç©ÊãZÅ…ÅË?­º–À¼4PU4ó¼°OɲéXž äzp™Zäøÿ<h+FWah^Súïú(ÙN´%(lâ'.îgÏ=ÊÑJ§W.òr˜O}øgä¸ël`†«ƒÌˆO ?ñ$ÿ|®ûPvn;‡„y;8û&ò?܉]óE`ÌoǶw,Ó„\tØsGRbáçôé 5·Û1\ yGVõÏE*­ Ôi™÷dà“ªÿSÿ ”ÿ§k»£b¥ÿÎk7:`”Zxœì½\”Y²>Œ •( I‚ ˆ ˆ (*"‰%JÎ9Ó¡º›œ3’¤(   ¨ *HA’¢QT¾·qœqgï½ûÿöîÜñ·³õÃæ ç=uN=§ê©:M·$ð{A¹A\Ðß]ý¿ÇŸ¦û¯!)?žÙ xW8ÍÖokÐúÙÖÄ«¥NgQ4Ô2òEw,47¿[Àî8|vç–¶øf¦ìŠÁ;¼™~„òHð„™^á–G .¸¤Ù; VÂîy„ý ™¬›Gsn] @:<ødË#íqcfÑ,íÓ#-Šä^ÞÈMy¶95rå•3žæŽ°Î¦‘w¢©{…­¡Ô$DjŒÏа¤hžô‹Fº•.À9Z¼Nx$8Þ¼Y=0på]dÍøÅ./Xí/ß¡û8tŠÈ6Aƒæk>€ù—\hœ Q åO‰ùÜßZ¬›`U:GøÖm_ |òº9þ„ûZÁ”³>pà|w6œ—(¯ÆüI~=2÷€Áרûf4–ÿîꮘý±¥<¦8Âl^c÷½žè²ùaf|Ø3j€Ëe"@؈yÖú¬@TâI狑݇«ÊìÍI¹N¿æ»¦¬7Ì:‰MÑV)!Cã4U §ðáºú³©;Ð0N‘+ GNQ¸$ºñ=äT”}|onïºýÑ›Q¶>,Á7yŸŽØîfÎ Þº;9}á›mÇzš­tmÄĦ,«¹ª»%¾Ñ„Úrf­­×ð¢ž#òÏ<&g+ïÕ’ïq„~h ½•2>ºj zü6S뜚#ðëšïFZ×;ÜxhÊu`”49’Ë)ú Ûƒ Ã(Oùxß;³bRýèxмJzÖL€¥+• ¢'f[€Ðl#ð+§Šz _?ºå" á”–5%¦ì,K & ´j!© ö$-Àœ%²Zå1õÐan/‚ÁýSøKˆMgä¯aKêdØ™];|fm»Ü·@J”úË»&@Ï“5ajˆžÛíƒ÷d8,ßÐ?Å3vÒã±Yi›ÆùŸ<­#EÑlÉg>Úm}†•`ž0'Çšøÿ€§²jÎëŠéFö¬FÄþ4ò¸Û¸×©àÙ—(™ZÛç†æ,]O„n²· ¾uïm¥!ïVðëäë“…Ðãu6$y% T[Æï†8wñ iOði?;·pÑŽþ•/ö²= U”:)WŠäõ̾ωu×åmÙr¬ÚËÀ`õJßUÐ!¿´ bZïÃÁó)ê[f‹^ÛÉJÝuGØ:Àƒ4¹ìh4yr»™ÀÑ)íƒt›½_0‘Ðâ*OOUë?:0ôÖÉ•ßyjæ3-kÔDé>'[¢ÝzO¸*4F€yhbHÌ 8îhÃ1®/. ¡LÂÒ†¾ &a O¾Íƒ¦ïYR€ûüûMß&TDsõÂt¯“ìž_(z%(Ã×»v?ìÃéQrÚhVöÙšÀ%o£­/²¾¾M™ûÀE§T(<§·MBÚîÂZm;̽fôášItèwjèÜ=â~ÝU÷"ºÆ²wÃØåwáØ*¹©Ý©Ò|¯rÉûéh<’Þߪâ›\«É«õ @Ÿq¦RØz¡8‘þ†+ëÎÞ•ûóñ–Ö¹¶7`ÓwìQoi·Qô‰$ÉWÑ×lK^ö]‘δ9*"ÞéöËËõ'go¸‘mïÌÓ‹„cûa'@‹|‰2¸çÍ®v9}>Úy> ÄgîìÆÃÇó¬±`¡ `œ$]»}ôc×[) ŸÌÏ»›lÃ.gj5Z: 0µ•ÓéªÂ˜4˜&•EŸ / ˆO¥~veAqJkQËèl:X¢¾ö¸I3W˜¾,òí@‰=\ã##õÆþ±bp¾©%¢@† ŠE’-‹îMþyÎ`¶¨¥÷‡aPs6Qv4&úÊMmî«DÀç8µ!-ˆ2Ãûi¢)/¹"3  ?‰ÿÕýÿÆ¿õ.Ç<ýûy˜h©Ú¿c‡wBìŸ[‚x%ü©úÿÝÅ'⇯($—w+™È$[dÄJGä"åÓ {>IéÀ<ã=þcãÅŒ†Þ‚åæ«¡-~¾¢Å2PJyeNh ÇOúz—Ó’´zÙÈaYê=¨››Â¼{(Ó f_(´CŒ­u„F{ÒT€í:)ìÅ ?÷p|JC#ÊöJ°õ¶2”£aEÒt Ï*£¤âŒ×XQŽÄñ‡¼?×ÀÓ ­ÔO¢U02Ë–?†Ä*Þr†Y¢€ÛQâ̺÷B·O*ОYgn -£Ü©>½ò¨ÌÏø€äÃÁ=­÷Z>‡ˇ_˜rÛwòjúˆùç_‡Ä[ûO9?[vÒiûgFk6‡½?Üþô}J¿[öc¨ã¹ÔEsôÑ‘i(lf¤Y†8µKÊ7Ü´áýÉô~ŒÛæ’I_ò@²•LÿÞø1ù­h¨d1Ilº-¿©¿È6-B©<‡}‚ðžºôÃEóp‚—UæÃè±›IZÇÚã[éÃpÇÛÈÓB®NÛcS„êÁž”â ú)ð¿™Á$ŒõYŽÑ¦øOy«˜Ë:XˆûðÖ>)VnšI»ižì¦Ž>€Í"¢Ù@vªSƒ“Ä‚‡õÁ~ð‹µ„É``´:påjK9=k‹]WIÛ>`Muš31Ïöë€:.I ÀÄpàÕÎ3׫¸õlcÏ÷g:Æz±…‰a¶…æ^åKk Ï›¯æîÀ)¨hß Ø R‚0¾Èõ 88l G,y6ߎ2åi‡:XÝúÏâß6_Ên,eë o†kÙ» .+Œƒ½_Õ ˜'IÈ3]½óÝàü>Õ÷øÄ¹U©ê`Ît70c> ¯?–ªÞôŽt9ØÃýhÈÚ–=òÌÛÞ¹í:¢Ç¶Ý"n™™ç^É?Â_U'°+†m°[­ …ÆeõðCG2ÌWÞ ’¹måù@ódãûfÕD3W‘{F.¶kÕëG“ÔLûÁWïÜW#€ØÃWVÝèe8¯¦Ð)t—[æ€ñÚI‡KÚùu‘ÄZC_«Å4RþÆgæŒC¶eû_Ýÿÿhü…]Z³Ž%ÚQ«xk~ÿ9`<ücÂÿoxè¿÷?}ÿÎâ˜üÛñqT3Ô)á]³ÚÐ ’¤|‚K†{úpð!Â?)¡á#;@·”aN|ü5ܳ]OÑ´[àš§ ÷>0Ã:ôw¶§fÃ12Ke2K$šö¸»I¶ZNâ|Ì) e}wzSÙá›_y£omOj€Ë›ëñ¼ÓíðÁ§u}fÝŠµßávBÕ›Vwê'%á~Ç'ÒÔHKŸ(vN>ÝŽy(0W[ÅaN qwžã`'.³ f3õÄ=ºIf7Ÿæ´†‡}޽)à—Ý») &ΰ{Ý|w*¶EåF’A\Ù ";Z–ñZy!Föù€÷Çõ$ÀÊžþ P…Ò í¸çç·_w¨ø¦ÄN Ë:·Э1‚ÁÃ>gõ‚?mš~p-êŒØ\pÅŽÔ@ù2àÎܤAEå•]ç‹m<8ýˆFú±ãi.—®äO_'pªôF ×ZçðÐ9¤Gv(³c§%ô‹Â Üß¾„S}Ö˜ØAÏ\Ùd¨­^jh9ˆ‹]>ϯŠ[ Àó)ÿ%ð¢O ÝËÝ=Õ·ãHëºZ1¢ÊÔŒ{Gÿq½Ââ o˜}ÂÁ)G¥0i úHBr|©'I’ˆjPî< ½yP`D„C¨¹¶(¼‡÷öŒ¸úùÛ/–¢v4Uz@Å $+ñ4ÉÿçñgiK…Úþ1ô(ãJ"º]ÇËö‘­¡»+T.Ý 5e¦ÔÎÅg:ç8eD™‚íÌ›µcœ>Sž)ªd½£§ðªOàSñGw´W¨órv‰+¾Q‹‡mü|iïH¯Â?ÀÿZ[ñ0fµ¯å› êÇ dÿzÓÑÀØH άÏFßðI(Î˰‡œðCìÇx¨­+áüm+5“¢m<M†»Jȯâàììñ¡}LÖÌîàëðn<ö_hƒÖé.<<ˆ‹™òy€?;`ÿú«†»§uUÑ#›E£q~ûþêþÿãf©¸i'|ý:óëßqƒ¯Gh þÿŽŠþ;qHú ño+óÀ‡s¢®yK&ÐZïN#FêFœ½òpØ;QæGâ°ïgòQßÕb"€p¤Å­éóáÅ+°º˜ìÂ#},g~ }˾‹Ö*°£AÁ*ªüW¯–‰§UÖNZ+)Íl ‰DJT¤Ú»tÉò×뮬¢Ë2N+/íïÒê@JM>ù‡çfÀÏiÏsžÛ­”i,ñC\< é4VG.Œ:MOK¸П:Á-İ©/¿1“oÉÇ:H™ªEýy;ƒ‚]a@&mëU1 4•¡¸Mƒòò˽{,Ó†A’WKà­L$¸çGiö#»çTˆ~ä­˜WY[ÓÉ?ÓÖв4¬»¥}ª”›=ù%.4õ¿*%>.ÄÌä/š¼I©hòT=’ÿVßYÝϼ’™䑳²­J”<«±Q…ç¼°šþ·À1Òè*,,™6¦¶2œ@õÛÁº)ë/º‡º¦ùÖ¨“,Öéb5ågÁrf®µSÜA”ï4 5*¦MöéVÚù|!~­VÆãóϵru"=J½°¬E! _-Z’AEzõ‰¨<=‘¦ u—w]WW•y?&ìé‚N‰Ü¼¹‹Ã6|•1ìøaqsî¯hºŽ‚ÁêÅí0÷`Ð|¦,ŠõsÌ\ó¹œQŸxÔuSޏAÖÖg>$[óÇ  Sb5~üó6h„-kz N ™ ÖdYì÷FöÝ•È)¿"^c$Ö›çö¦¡ÍÜ0þ1ùœCÑæã@=‹Ì £ ¬k¢7Bý^ìÔœ˜€M¬§ H2ž&V)9°Ï’¦CÎDœ;úá\ݧ}Ù¶Ì’—Å ƒ˜ wîÛ‰w~?›pñxoÕZCÄ)_‹Iûýó îúh«¼[oÉH\ÚǼ5 »øÇ°¬÷ [úú 1×wÃ=õ·‹ÏT†üü/ðÏÖˆŸTœ:€V/ˆ¯YHåäæ0µ|"oäÈÇZ²,~eù¤¯É&É1“ÜN"­‘­Ì´ÍÁBÇyàºØ^r¨si ùêÀކ’wÎï!S®‚7¿T®·ëiüñŸ©µ Û‰ÇH(ßÍĶ®5(veÉÄCmÇªÕ ñCjÅaaÀÎÚ‰TÍš†ý+IšS{QõþäK¾¤nÀl–FìïìŸoêX”œJ^¼´-ÃÅC•ðôÐø*O‹IdäKù6A=ÞbQðØœüŠûöÈ;-æœ Æ Nrð¯îÿ(þ“×Ï¡™‡”ã¥~Ç hwT\Èÿ ýO‚qJùÇþ#ÿœ7ýõë¼Ú ™k–ɯÆ.µ#—\tpUp¤Ð}û£ø~X2?1wçÂ:–×&Â=ã(ä¦ro)O•Ž…åq«èbmÛ8³ÎØÇà8Ëï–Y  PÄå%þEÐç%ÈžTˆ¸ív¢+1ÈtëiV¥ãº¶* TpÞ—±5*ä6¹ž½U¡“S¼ž˜+Ø'}8ñ[]Lï©g¿W ¢*ÚØFÊòI­û„·ÌG(œÙ}ÑÿÞ–ZçÈ/,¼ \½5¸Ä·]aK&œ¸œ î»ég#"w«|Yßí NºU §{fpNÔ=Ûùá!Ýn2¤X»£³Od—À~‰Àòļn´úTIú8›•œý'oKæÖ¢T×¾gÒÑQë,gyw¼ …:ë4(¶wÂä gñµùHì½²Œëfã·ðÊ¿¸c« êh÷±&àÙ/™j'zgYç;šA0¶yogÎ\|ö&xÌáÀÓ¤^ò‡tLÏê_€ãGl†µÚÌðÛÔO¢ .HØPãC KR– OŸ÷®›„æýÔ”Í7ë^¢ÍXø¦ÏÁ°±Ï²¬Ð ½ncÅ¡D7±Á «Ì|ÖZš¯S-²ï³™6Ái¡Î&잇‹¼ýmc½Œ®~I„ ­.¿mÅq¼IëkÇ+®ŽMlsþ‰ðÏ%aO”n‰FYÎ7ëÔí ©<›{©`s‚ÞSœ‹5R»¾Q“ ÑØëN}4ûó&;‚îðã/A€-ó4Ã[°Ç³„ÇÛ錹/N3¬Î˜;+ågñNóC´çSNd€5ùÊ5Ò®Ø KOy@ûÂ%«T<ð¦«c±ýGªÐFy‚KÐû™¬ û\_ºÆë“­‚ä+æÁ@™ˆç÷­Ãÿ#þ¼ Ó7€”‰‰ré‹Ç8P£h:ž>8üyõ3By/+âA[PQß–®±ÿÅz*6Ñœk8[÷«s4`\cgùAœâM€•TÝ:×îCAÞæÌ£òˆ4ñ;¯nWv(oÛ&ª½Só–÷I?€iˆôp0_ƒŒý©ø”!&ny RPSNy´û¯îÿ$þ“œ|[-/ÒíQý[fðöŠˆÂÁO!~~qöþmÅ)éûQá¡ÃoÏÚÙ­„x“gI@®‡\ím(Ôs·wD—A€z|j˜Ñ*¸Ö^)fuùc¼îRæŠËq§äíþÎZ€”ÙË*4]§‘TÙ:¼÷’ùsÀûrA,г‡-©1v\ƒÜ$%)y;©/VtxQRš'—vïHQ“D²ÎC¤;+1E̳éô¦yY€e¶æ7Œ¸!Ÿ^"„Rª.Éœ¬Ð2_áø`\ìhÇ#}Q€Ò(•u@ôOÆõÆTŽû+Y@±ê&ᙯÏ0‡<ÓÁ?=ç8S{3°O/ÐD`©ˆëP\WÞ¨UzIûïîðªžì»ô¦•ƒàŠxPxÒõ"Ó:#ñ`Š:>Ü«•žQ§â€¦êßGòä+/xv¤A{kKœ{*TŸËͱ•tqPrès³ÆY%Pâáö¹lœ&-úÂÚ0c›—اUŸ€k¡IDû‚ªí¾£%p,´?ê(Tá¨éìáËpT&Ý|{håglÀñ6ÙÛíÏaáua ½sÝÌ(Y;éÏIƒA¾æö½P†ÜEƒéž¿;»#Ñ8! dŽï¢ÈWIz=FÙeì•ëý/@ç˜ÞWXeàë~Yq+ÕJõc_°Õ¤‰ÔâåÒÊxQ[Û2ÒòâOîZpè>oä-„—ú¹ðÐ)D)X×1VîÀ3n×úhþ³XjSÝüš¦3ݵ{•Ê®ÇA~inPd¯˜¿µŒfÜã­‹Ç&SĵDC˜©Ã5ÀÄMÀªœŠ~ÞÚ‘~Øö©ƒ°ïT°¥:üV¢žþC0ìÐÿ˜ Ž Ï›{%Àઋ%@•ø€ó_wá¡ÊÌ Àã2c<ôK€Ç­KGR%¯òè ·ã6Aë5*CrŽÒ»… Ø5眓ÿ;üåõž¹»O çÏÙ+Ÿ‡çþþ.´dPv>óxL™À"ÖÚ§øÐß3·7;R®*y‘Žß1M™¨È„1E¸±}YYŠäçîµcZüVÅÂ+¦ï×üö°íÓùð­‰iÿPùü DúÖBð±›hŸ‰~ƒfKžÆû~ zZEÀô´þý&ÀÐVÜC©~˜˜ì4õ¡eãh‰Ídô}£kqB¦ëmÌÔ{IúMúwååwbå°œ]°^Jµï¹{?’ã8¥÷Ϋ ‰ !ÞÖiæ ¹#ú³­»öçºÞ±iñ„+¨Ìµ ‹·`;%ÏýÜ' öÃÇñýÀæÊjŠ«ïÒài¹5‰='sòž¾$ áÍœxpÀyâ Uìn™ƒ×äN«>kæêC ÀünRR«.ràÌ“6Tú!rÜaI%ÜÛÑœ¬ýuè|Nw~oe® >Z7ZöÐfP®Ë—þ*±ÈXuqZp‘Í/ôsÒ&ÈÛ]íEɧÁ5ö L&ÈÇ©û’ìš Q=`n(þ9·³îmÞKìœFÍ÷@ñ•&î´?[¦Ük ¶]J–éoœ*‹ÇqÔ§ÝRhÐÌ:ѳçÁ‡ØÉãs±Š\4{Õpº³7m¹K.ˆ^5± st(ÃØìyÇþ³­,àK€i’s¡zd’Shœ=å yà×Ûò" ‰sLª“µöSŸòýÞ@A%–Vô‰äéÍ8`¼nOÈ‹¥µlÐÓJBþ/t¡B=Ãá ðsòiæ+Áî„=#XœM`=›©cŠû kßÑé勹z‡g,9_ª¿P̰±9Õ.Iõ¯•ØþYº-ìÀÿÌ ÓKf¨|R2¿æÃáH|!Ô[±?M;gZC/@~ÄžUnUÙ-8ÐÍ¥Í ìc_ăO!>Zù½TŠ„Bée-å¤DTvÖåOÎCáaêÐEí:u;†ÊËqOöÕÓ–…*»¶b„a {Ï"Ù|¤ú¼®WþåWœG½Ö_Ýÿÿ8ü«s<¤DŸœ°ù›?õÇzúþ©Ÿýû;±OùI6#þÝÄ3ú—ƒ"p XqK¾ñhâÛ7{»âxz&sHQ%æ^Û NfÉ’À¹"¨Ÿ„ÊŠÀŠ\ª Ú•€v´G< ô_ŸT–¹?¨è±´ü$Ûdz,lÑ\¨Ã—zø°šàcgÿtyM<.ÐíM1 º©4ƒ½à/IJ޿ß(¬áv+9Òrü5Žn(ùýYë•HŽKô=ºìÎq‘tD¿ê&SÀnE_.À¾7|Å«æêÞŠÚK±8­²W¯so*–ÇÕõJÍ Ì¥ÇbŽs#µ[°cFÐ Âã E’þ«{˜·!y¹Ü„›MÏOKÀœY9 Uõ–Ù8••½iW}X?{‚Þâ  uœÛ&Ï 4Uv<Ä3f–ì cÃAú˜œc7 Þ[.úŽA{¹/Ðߨ aŸ9€AYSœZñ0cüÝÖÉ–#¥¤–»ëä2ât¾äVÇ0™mEίV1Ô‰gÕBk/G‡ƒ@zÉ:…æ‘×Læ0Ä® ?ÔñJxyÀØ>‹âù3N$ìÖíFK'ÝØÿT&© –ÎjÇ¡ƒl$$õº.9wGV‡«[0ÓÁ[G;iÜÕªùcï@ ½<®tåÀ¾ k±ÈqŒc¡¡À=–[,“qg+iûî¾äx«á]*ÄÕ³rÐÂQïªèÔŸÿíï}| µ­ÊkóøÆ¢N"Å!Ÿp*4ÉÕNq÷)³sÑ$BHRŽBkÕ~©Øö3=mÃ[ïQ‘”*G/)0ñŽî!,[ïSg&Oг‰ÈûûêP/øì ¨"ªn¸N™žng'Œ`~N¹¨Ò¾ÞKèöËXól‹s™û?ûûb8ÒjnÉ_ú*ÆšT(c†™ò^ÏËêV!44˜èÇÀèr9@5Ka”…‰|Vý‰Wó²yYOý¯ñßíþÅ0A«DâVˆÉ;%Ò}tÑl× wA¦ŸÍ2½¬0ëá‡ÆAnÉå§R|$%‚¶Átö¤~÷«²›>åÕ%­œ*çïø/§õ»Ý R`æ†1Ž™µÚÿÿ¦K>d1LjùY¹œ»Ç~›µ§ÁˆýÁ\?±•A?ƒ}P ³— J©|“AªvY¶ªˆ‚€üÕ{“Ôó倥â“NÁgV‹Àæmryᆆ‘[Êáq¾/GZDô}¸J£â…Ƥ”‚ ¾Ë@zÔ[#©u[=÷½X,Ð~öþ«ûÿ†?ûÆýã.×AÉYÁß=èOþìßïí’üýGþÿ‹sâ·ß‡w§…ß“¢Ûå_ð9?½ùêHŠŒÁ ;w©…—Ò!3—ÊvõSoظÔ‹<ɇ¤.BúÉÛ]Ë[Þtˆºï=øóè9˜|Ù‹åot¿…ôˆ±-®zu¢î!¼±¼·èÑ-è›Q¤‘„Ï”‘´O>o —œ„“øAíg¼>^üMÙ­;ÃáJçË‘œbfˆßQäƒè0ΑqÑ7Î))È+Gp…ߌB]\¦ˆnõqVØÿ?«¶´}“™º&ožÒ8YĶ<ÏÀØpu™¦³|ËÐ^.z-òOÏ¿žo´B½oÏ4‚Zø®õ5£5¶spêÿ”øçðÜ Ÿº‚Ú‡‚Çk³aM ¥áH+Zýç/HUœ@·boÀÂ5—w°‰‚¹ü’ö 5*ª®ã-ÀìãÄëgŸË‡AØÎ ‚\úñ†Â7~L"¸¢"p¤Ô‘„óÛÙ§ WF? IŒŸ X†¦Ô¾zP¦ÅÃæ1“» ø„û%<Ï¢'JJ<4~ºœ «Éúl€"$;Ù«µËÖ|Ê·9b:O¶ÉfÍ‹c„úÿøK^3_ÿL'j­NÇ ÛúGì €úùe³ŒhÛ]{˜Ô¡FmùV]Ba®dª?Ïã¸HëmNª‰…(¼X‡_ìK¸SÆùØ·;×7ñ[¬œ~xþ5Y|0‘ÿoðï3y:™ªº~äKç¶F€ú‘—«‹—µ€ØórºÕëËHB8¿óÿñc‘Ù´ªŸ¶e©!ö¬Ü¬@Áê U@«æžêÙAëÀ®Xg"»pT±‰Ï)^]‡×¦7eDãåÒóÜ–HžªŒF»Øo: ÐØmެ‚!óÒ,눽÷¥>¨ÇùÒúÜ·Tuÿÿ£ðÇi*8ãöÊBÿ⃊ù³‡ðo-˜µ»m6ùl=9£Èéµ®eû|Ù#•5Gñ ƒŒ 3¦â®´äןî«eÙ^Ò‡5ûrÓRI¨¨$¤•ˆþ²”tþL¶í#MíÖÔŽõŠÄ]Ö’ÖãªûwØ®ÇxMìÌ·’9Ã` ˜ÍµÎ¥…Çâ[!ý}|J£!whüó 1Ÿ|¼¤Uç¶óÊ (ŒÌmôãCÖWªuTë5¨ýlŸ´2a{É)ÇÅè9Q±sQ–¼o`ƒè/8•Ï0’áÉap{ÜM–¸òàÝ‹V¾Žcûwz…Û?’"¼¼*Ç ¬N¯!zPÖ g³ j¨ ^ÊN­Aî€å·Ù®;£¬Ö—RP…?§Ú´5ÖlñÚrf`Í“¾ØT!AÊnÙîŸ1Pkâ,&‘ûœM×¹^¿¢›r:úeiI Öúò£@éN(˜ ƒŸcá§].Ï~ˆ™ iä)ôö}%·ÔxZ‹ëÍ«®Q0÷™´E.ì®ÔÏÕ{±Ùº6O¤ºõˆgEY‚HfFçØ´ŠDæMÕ‰IÍ<Åñ#fÂôþa·ZIà‚àÀì¤9ºôazž2¼K+øšVä®ò~Øß:Œ:|¾…ÆÂ­ˆ2_¤§bZÜŠWhL UŠ<¾åuÔ]?¡Ã4 Α´ãùU+×°y… ­L’¯ƒ^ý¤ø­qÚlÏο·¨ú’)#lèúŠ)G‚÷Éê‹CTëŒ@Ý_nÏxðû_¾¾€¤û0“1räj¬ðxèçÀù§g€ßÜx¶ \°HÄ®Jk€@µIüöé¼ú2msÑͽ«.2 8âž‚Óæ¹ìàÏ÷á¬QÞµhÂÍÊ;_\2 ±üË…Ï-gk|á½+agp¤yœ£¼¨¤U(HVw‰Ê&³§nO\=¯éBi”ЬdÏD˜‚­Ù=ÑÖܽE*iGÒ|P:op¤¿šðB¿×Bô›uú<ý™¢?Ŧ-ô(ïÑ,­¢¿n— Ž…©¬cèHJ5³/hôÛá!`Åg>á«‚€£Û·Ü }V¦4.=èç®-¹« 4ñšÓ¡×¡í¢R-áóæ‹üCQ§¹0_M aT"Æ&c_”é^ö;®RÔX¨&¸ÕêâÀÉ-0ÍQЮñþ …Ń*fO×ËÔÌÐ85 (†llcCm‡^¡ê¾ƒàŠ ÈP¿GÕ¦òðô C¿/¬*¥Û>:NB¨àÈY52á‰Q6„;4Åt™Ú{´Ð,Ó6—@Cˆ‹ƒÈ^N;|‰”•Ôrïò„lK*Õ±Ë ôW«}ßWu-µ¼hòH[xíqX½‹m«™×É m<ñÚ_¼¸ŒwÔp ¯¡í]?7çDôÓÕ¬n—„™1ÿâ[ÏŸý¼øk25j6+_u£x˜Þ_âèr®¸†xG~dÜROêÛQL’êêñ•V„𨉂ÿ¦¯H1s”7g3®½jðäÔ×™ì‡Ò¼;e€#ßj–øeK*}udr÷K +ÒqPû‘¾€åµp)yõN£Å›º±ÌåÕwOœ;kjdœÜG{VD7å¡Ë¤*·wàë‰Úáî1”Öw»AŠôk Ø}àÆÃÍ«¯*Œøôn-óEª‹<ý—àïyâ¦Å8Óš‹A0ÁîLp?u¯N°Ä­¬ÈE®g7Ø'½iv(‹<ۀؗV÷ä]>ïU‡èŒÍã6Ç»­¹}¾õAénçS©v@¥—ò´ÿ—ø‡m™À¶‡¸NUÕ [“Á[%†û/e±‹ýÂBõh@½©‘Àø½ïƒ4}.>  4÷îÁ°œ=×q>Ï9¤°@ê{ü(y ¤¼°7Ô†CVËBUY—e±ô×ó28"ƒ{ÀsÎùÙ×çÍç,iýâ·Ý8ßù¨ðGpÝ¢g†Ì}§„õîÒrãC0œ¡ôÇD‚ÚêIvoÞ%Žƒ u»4 a§‹òL´í5ùTði­ºxÓXòMXí.©ˆHo¿.Y`jHÈŒó—–#™Q›ãœgò[8KU$ÒZYȆG­¿ÚÅ5ˆÜ5ôP°I~ƒwf`þS½ÁKN绎và­Y”È3ØÌÁC–‚Ë0(”llwi§ñ–ºÎ¢M›8a9FOÒU„A„IÑwѧ>%ªÖ.؇s«ë ï¿øv=ëò3ãs‡ëVQÝïFéèŠÍ"ic£ZŸ‹Gs—Zº°kϪ¼ºIYv€}ý®¥g]:Ï&·ˆ¥€‚Bo€Õ:ª“N{àÔÞUÜxY? `]3aHxèï¨éC¾ê“ûx[gòôC‘EðÈŒ.ÝePEÃÏ g\\ÀÑô±¸µç¾¿êwþ« `èw«Áùd%‘ÎïwÁMétO`òµ¢ßŠ~Ñpö®œ{ã'×›R—þu‚º~ôÓ7Ã=ê”"PØ%?!@½¤áy£ç¤Ór”øÔmj¹ŠNßz ±œ,³—¥šužîÅGºÈÞ‘ sÏa0È@îŸ|$*à×ìòà¿Âÿ­øèW9ìt°n4Gêù*FWÏWš8p¼ºÞšêO:üjœ6§6·îÌ…óM7ͮϴtõ *švêÑ»Ÿ¨;W®Q«¹BˆýQÍ ï²ü*—·L’â­°¶W€ C5`ã¾_óÉ3ªÔ1)Ê¢Th¾püì(êLŸ?¤Ôá7ò°µŠ¯î¸jÿÕýÿÁßfï"î‡rëíýÓ|öï÷‚rKúÇþ#ÿ„ˆn¿ë8wQëÄ—Èó@Ó1ݲ0lG„ØÙTàÊj‚ƒ ]%0•²+" nšz° •F5ð6+ŦT(¾ü °Þl¦Nf¢ƒ$âµǴƹÄô<0L# ÁJ|;® ¢|ÀmnæTPã%õa$Ë~{FUl2¹ŠŸ5–®tXIqЀólÓîBÌ̦PÄsÑûm¹<üÎèŒnG‚ÆAÏ„fÂÙ‡8ÝÄ#Öú&<¬7r£ùL•†¤D߯VsÂÌ3á—ô5 ÑÏÃÏ›Œƒ’;þ±@ãõ)eÙ^¡!:š1;°vÅ\ö|ÈÎîALšÆ²Mb—–C¤ é›Ü`#n þB,¯Ñ&xV”ÿäØbÜu¶íóº‚WçA“ÂS–p¼CµÔÝïcaõó*es =“©R‡Wqi'¬éiÆ"xËo%c暀A“%jÛíkâæzä>\g ©"ëä=còêsÕÖvŸ÷ÖvW:!Ï»)¯ë3]pXÜ“¥¾«vn/wA­B¨öËÛIbàJ^ó0 Ž´ø}Ÿ'¬¥L´h¥ñ¯Üî&[Í·dp ïóvxèâÅE„h®+ïÙÝõR.Â2·mZAFL©°?k˜¤³ c\[„ËÏèÆË¶É04ÞW¹Ø™‹2/oæñ9póJ[À6,¢kÁ{'I’KAó±¶¡˜D¡­ÊáS§Ý£.XÝ?}’‘Iÿ>†CúÚ*è1Ùˆû8øñÚ^ ·R>»IŒèŒí…àºK{ÙàŽ7w/ÒJÆT¨ ~yHEúG[€ Ô]¡úWáOÐl5¡nÎÆÅ€âb¸.«[¨™vºôÊ—Wx1õf´Öœ‰òP£F©Ê߃\gLaüãv¸œã£ŒºxñT¶;íòþlÙØ­W+”'dH_î<'ûù¿À×p“dë¡h̙ˋ€ÖwÚòüŸ´Ãù+>ØEáÕúRøPÓ…¦µ“UF*ÝWB˜ L‚äƒw¬¬”—ˆë¯ÆAl¬ãÍ@]Yò§pÄþ °6cë¨“Õ Ïã–Ï—G/‘õ”–xü䲞YeàI;ZòNv™(SÐTo9{3 q´àv²ÁáKðW÷ÿ?€˜ù¿}Æ>À÷}öï÷â‰ÿ©>˜ðï ’OÜ\‚¯m»¥8H¼ä)œÚö”£;¯ú¡ ¯å/q«®höÀ>aèÆ4Ü·A2丫ú¶j¼[³”Å”·Ía?Wp“đúͰ„c–cjDÈ*ÚZh v<’yÍý9#´ éb•s*Ö©ƒ™*ø<Èf6颯©pšXþ;ÃÛÒáj ¶š¯æ=2 7¯ ׯ´§Í"áQ8ØHMGk é¾Hç0½$Ñ ðR¡¡Ê©Sñ-< M¢ «]¨Mà7sÍh9û±@x¤‰HE‡›Fy†Q4tŠì…}áØo;1l¢Tã ¡ÖxÒĆ)Õ"~áx5€ú \uÒHñÊ.U6b]¥F¥Õ?=ºLÏÛrabŸïë=÷wã>ÒŠ:g4½¨ÈñšÝš4Ë©rÊ{»åÔaƒ÷=ß‹8€_ËÅ}¡¯?$ÃòÖ&¿õ·*Οî³9Y¼®Ѳú jÞðpÚËTODØ/í–¼Ø=“õ¢â«”ð6õ= ‰¾yYß„Äù(ØNˆ¹íhÚô6¿ÆÅó_¹–A>z…‹aißíXÝ\D‰]fo)™}â NÒ¹¢M&ëŒp¹dtt(½—Zägé“lÛ¦$ônÛèTÛ ãq™:EÅχßpú]W–ì•Oϵ5!1Ä1fk¼vOqê§Ç_aÇ«8(È4Ôø³h]ñÈ÷š…ËËBÁ ±UÙ<*S¶W§ÅH¼Ç’±Ü§hP’¹¯‡eÛËL>ï©pU;ÆyqN9“ò¬x`ËP.€ý¨‹*l3ñãôäMR½×nHºù‰TÀŒ¨7ÓéÇZç‹5ÝÇŽÅéFuIg}^ýÅwê¢Ü8¦HyR˜Çkï­íý’·î­Øu¬vƒÚ¾K]†())RÃ>Õ*³!þŸÇW z•Úc·M…ÕÖ"(™ctfØØÅ;aw¾XΗ¦ŒšIDú⥊ÒÌ5W4 mJ,<)> Åö„‘ÒÏí8OKMùùU “Áµ\Ǩ¿Ç?hWÖ]0$ía>ì&NMÜCñ{ê´ãuÄô~‚,bèï.Ì.:À­.d'Å)…öÓ-¦6ž•ª±¨è{=Ïq°Ž]ëú)Ú”hexH®ŽÞ†ÀU‹)Í—G‡5-í¿‹‚&M™m!ðÂŒbe°-`ÉÚc¼d¬ ÑÀ‡²˜ÝÖ¡Êt*¼{ÛºRt¯ýåýÿ_¿O„é‰ïl€ñô‹Žø/Xâ§‘ÿüÏÀÿjqC’?e MV°¼¶ìC†\Žb…Îý€âî~Ì·Æì ؆­Ñ‘—5?¬à¡ê‰LH”ÍÀjðwßăùÜÿÒf †_ð§o ^)»÷kbÿ‹{©8ï´@¥œé·%€ö]yYëÅ”†³¨Y šñ¦K³ñ¯.s¸j¶Ù#Ìòð’âo?¥xB‹Ü pÉEfª¸èUwƒÝ…ôa×¾>R]®`9$”+§#VìÒ~éŽú©nÎÏrN¼V5=¬»<‰á°…ö„è0¬~žõ%ðXm†¸Œ.èÐPÊ‚5;7aà?ï¸ 4?j¸F8’ìH†Ì»JưÎèŒBy¨ß…G ªÞÁ·¡çC5 û’YcŽØv„Ûˆ¿ ³ã|K(È ü0}ê$ Às /LR¸]&!¹áý©¦@w)øL =€lSÔ_h¸ÿކ¸Þïóï¬yÑd¹ ?¡öyêx,vó½:°Ìbšzq” Bö™7 #‘û:L;í‡ým'oÇyµë(]×~-{ìÀƒ/$Ìê@ª_ìlÄêfB`rþÐaM"9{èsÏjpàåà!þ#4‰ÉJpP³}ÓAB  ºjV/œ’ñC@øÁ}~;ÿÝ‹G8Á)ù‡ž7ºü:¾ûÙ·Ððí®§~-ÎM„͉Ñrƒ16ˆ†€#‘4S\0ŽK‘ #̳ªbذžÈk®ñ@ DH¨  $ª"†A:@r÷$:&}ˈÁCØxAÊ; aN ¬ˆVâÓ8"ÿN/"1šñÒ¿Ï÷7Xœ,ÿ|ü “`ƒâD»!4äåfPdX"iŽHÚö ¡¸ FðGRÀçk4‘ÔÑć7Z­<óýöÑcˆø#Ù° `ˆöGlƒpbÜ â¿…Ì ýHòDÌ<"ðþĘÈMìòWD¿½ 4·-ÒÚëì?‰ÿõà_VëÆj‚ÿ¯¦þg~q7du ëÿû#?¬WïÈ×>öÒý˜ˆA<~ƒÎ%ö ‹zD $†Á"ȳ9,v#UÂ|Ï6jØ`wĬð-}Û˜?–hQ¤+"þIß{DüMË€ŒðôÉN ‡œcoöW÷ÿ?ÿøL å˜ôKèÿ=;ÀŸËÿÿÉþhùÿëdõbˆ*ŠXChaØ·&¿æ ßB<Ö!ÿë:ûì9ùÕ!~Ë97Rp¨ _]Ð)âJ¢¾?€ò3öGŽ3#Ñàêe”šEøæ¹U€ò°_ÒùÁÇ݉™¡ØÓm´CâÆ§Uˆº#¾;æ†b¿ûùߺöu§[毣Åá~lýƒ§ýàâ8bÐÀ'á1Åß²à÷ ñ-CÿÖ¥V(Ϩ`4ž8*báoÅ!‘u0éþF!†ß* ­UN´.f#> A¡Ãˆð ü„´A¡±Äß(1—ÂNþ~Ä/ÉØ¸DŒ.xD `ü"±Ä $ºàp/ÄS,^¾j£8wKü>Úß8íeðSà=¾íKó 4Î×ÍÎÒÒCQAø vÙ m"þD ÄŽþáÄò›ÈÜÄ*rƒš¾×üDÓ#„©ß÷°þø_7¿l lðÜÆ.Beø_)žÈqDÚsÀ%w^6¶~©ô7Ê» ¢Dr1·¤¿Ñc ò?‹Xù/ 뛭ѨТz­Í ø–_m= 9 ðþnÖêR߈߱Ù7+ÿ#ü#ŠÂˆybÚoÄN@ T$< Œ›LL¾¾Q<)kÃ;8 "Z{ öGkƒÅ ó'®#âfÖMñìèo»þþÆÞˆ²‹‘@@{df}ÛJÀ(þÕýÿÆ¿ˆ£qIFYÌïÿâïϧøOðË öÛÆq‡ùÿkïJ˜œ8’õŸ[¼€Ùæx‹ÃÆÇšcn¡‘4’ZÝUYÝ­ktŒ43ƒa ‹=Æ¼Ø >ÿÜË£ª»$Æ~Ïè…"fv#JÕÝ•U•™_~™«2¸‰v6Ñšõ¼¸Ü ‹cã8Úš­+gÜj™rÿx;_ÙsëLW"Øý"•/ÂõðoúCþ¥®^ýrÛÂZÁE€W MÚ7r”+«ý½ÔuXØIr˾ÜjÁÔ’÷mþ)ü: ' d¯õ„ó¾^kìO´öW—ÊÆCö}þù€VþÊ.©ë!’n±{iM¼›aœ}# `ýÂ7[¨ãiËÄž}ç f æ0¾2þ ¹² {äøWšMT;(Kˆ×‹ U":£š7:!žçìO|õìþ€Qþ+s"ÿŸ ¼ÔZå_ª­0º?H• °¯Pþ4ZâÙ—Zm¢´qÌ |Ÿß0ê*ø”¢îùs¹š·®¼ü„ôí×¢ìé Qþb pk…cäî³áÅ ބƼó—ÿW£Ø)!ügáÀwN}½C³P’£Qþ¾Æ?Œ(„äë19ª ÿ‹üŸõZ`Ä‹'3€†•¬„ž3Î ´ìhÅlg6³ò5Îý§?D+h4ª°‰=†á•:ì?"K; שÞà#–¿2ºzéévÌá¼{Ò×ÿŒåÿž&ì™7ðÿ¹Ðÿ§Àl_ù…‚·ê°DKrïó–™ZÙ•¸ ¾ûw\,ÿ®QP´—Ü¢â x´ÕLØB 7¶îwS{½tûEj»(^‡Ñ^Vui‘=|=vR73eÑÖËã dSyM>zç÷Vû4þ‡úFõ¡¸™šl<¼ÖÖŠžZqx¨¢NíN4°±HãmîôŸ­ý¯=Ö-ÂHm¼X‚¤)(h›jÚäwçK,0^¿òªmPiˆ©˜âÙaB^¼"ÔŸCÐp•>ê«È¬êgÇŒâÑ`÷¬_J±”z<ÿÏ}‘^q³é D%χüwPµV—o%!÷ôhØÁÁaèÙíëë;¦ÒÈDtÓ…±Eâyp%Äìáÿäµ³»Ïø¿V5ÝÃûO8À<;aAÑèÂ(àÉ?‚.ëûíåØr¨Ç,@n0žn.ý ù¿l['‚:É'h¶_³½GóäÂàÚ ké^îù¹¨0þáÝ/þPþ‡Ÿ·9àDfa€Ÿ<Õµ®$]¶ÒÑg@ªT·Nœ“©}»­ÄlÄ ˆ ªìêË­”ÃITx`‡ä/öËŸ,7”VñêI_ÿ3•ÿ“ƒZ,nN×û™õjÌôåé2QChv·ª—q^ÀÓ~^\öŽ'ÞÝG-3Çwÿò0pNòâßmÄl·’ÄÅEt.SÊËŸìwÀNi¥ÿþ¦/½jýé|="g5Ðý@ç¶i2XOœÑÆ _ìtŒîn»Øõ16ÿÔ^Pm ñºÖ¿ƒÿù®„;¨0êÂ]F´õÄjŸðœ,_û…!{ˆjI›@T2úɵŒÀF— ó‚Viá‚•iŸ•X þpñëiaëÅj¨ÈZïŸñT"š^<äM£¸­ˆõ‡m 6pÇI V4a̱•AWõÌFöµt/¶b¥«®^Ss$ÿoG43ƒ 2ªÕ4-ö¬ …4ãÿ([ÜžýÆðî6hñ癇Ù»&Ý-1y Ã&–?X ¶P ·&§K í Þº•p*ø—tˆDþF¶d=çOzÔ|]|'ܺtùOÉÿµÉ|·Åý7\R§·p(dþáü×ñ„;AËæ¾6çþPþÏûÌâ˽øØ2ý„ó‡ò§aÅ{ÈR5ܨÓ@kVXDT•6µÜ4Å[ð¬ß”›V?øü m)ŠCéò³!(1>½}Ò×ÿ,åÿ+JÍ4\>œÒ 0'úÿÔ˜å+7ÂÒÈYú‘¢-<ÜkNyqÙÆ.3I-ïo^@xL? \ 9Ö£Á8÷|´ÿo'žY¹z´åÖttàe3öÏ/Nš[{Óó[|ªzÔXòÞE¼ ¬†L'ŠÊ#5ûëìP0¬lá›…Cã}«ÝÝj÷Wû“èÂ÷›V!èµ­”7IvÎQgi ¢çãVYîÆ‘Æ-6LÜ® ÔÙÃÇ„èS°°cÆ&šðÿÉÝd€fø?b¢ 4T—Þ^¡Õ·Ž?Ý:ëvÔf½ÔirÎAÄAÐqκ%úEõƇÏàýgÔKøgïÖvmbñ78¬…mB"”¿6.K@†^P„ŒHÁ™?+ÿo†vDWwÀ 8¸©íÆßÀòNì&áúf:¡å66óÖ¶ í¹?ÿ‹~,#êÈüLo¤ñçÄ&hl Yw› à€±4­, €¦©h¬¶‰€7HI(8c”`žl·”Ëèàìã¯w´…týÂI_ÿ³“ÿ×ÛPüaRÃΗú‡S `f¯l*ѤX´i2 ô€ð\²‰w¹y[N;¶—þ¤p>8qUz®¡ïÊâÜYI]ëpm\~2{ú+÷T*™keâ9‡Ô·!nNŒë~ʤ8`Õ«ó,ÿ/÷¥¬ínâÊ—£!©6É_dâߣJŠPþlØäi‹ÿK. —îGùg¹~¬ØÔ½Ô3ë?q,›aÐ3ö#}Qì¶ìGF_ˆbéxdv¬^KòÿÊßÍD?,¤0rù:ٕٹ|O[¼˜@>—Ý:ª_:Nþ/6S¶.µ-ýãgõÇù³ÕˆÐlg9®T -(Ég"Ž˜ ‚p½ÝeùkëîGŸ,<ßÊ cÇw¯CóÛ6[n ¬5åNúúŸ‰ü‹_¯r…9Õ³§À¬^ ÿ£ËS§'lÀƒ½–ó⌳3ˆÈsÿ\`ÔêNì­JðD5•®LpwœÊ¢ifŽaôñê¿ÛÙzQqX~à+±ì£[‡MÛ÷y€ç=«%l©²R¼é]¨öƒÖ|lÔ„Ç®sÖ«[üVìÿÌ) fP â *Ïô?D,mX!î­í$kêÌíàâ«?*F‘ üÓäœsÂ¥¢Èýݱ3÷Ií»i„^fûþ ?‡[ð8Pƒ<À–¨ôŒØ‚ àîÕ’Àù‚Tá û¥",†¹Êœ9óE3¶«ƒ•›ó-ÿ—=ñôIÓ“v)ʼnáRu&f’PUøƒZ—XVIÄ~©â”tûxúZ•q,IþÚ‘Ma;fŽ€° H´(2Tñü vùÉUS(ÿ$’ˆ„hJªŠÑêàÝ·&ÿWaÛB¿àM°lzVz¹.1 kiÍ)Ÿ¾§kgë¹cäÿ埕þ!2¿¥õs1ŸLŃp èÑœ# àŒ” ´Õ€cIÄñ& ,Fù'ô»õv“yDÐ/üСºd¨(Ê×4<qaG”‹á†(~çįÿÈÿÛ1³_2Ms«þáÔ˜ÁK&…ßБ*³ùÿU:ëþ9S6{—ym}rk1ZÛ5úb#ÎצÚB8á’ ¶o¸uëe3£{APþàÉXžMR¿ü=†:jüÀ÷-O!©»Mï¢2ÃßÓERtò›<º¬ïL¬ Y°A?oíý$;(~ˆ£âðͬíd°ßÄýÓÝ1yTL"Ï£M14Ë{d¸19ã¥~,h=ÿûÜòÊ´Ì¢èüÖs[ú‡£¢†€›DÄ Ô@Õ¾ÆMƒÍ¹Î\ÜÇm8LógQ)>ÂÙM&`)ü>ßòÕ¶gLÎ+¢üU6ý_ Ã3>Az†è†’4ÈùfJª®XúyPÜýÒÿ¤øQþ=¡þÛ-ŽE•ýEñ€¸€€ ù‡(c©\öIo"Vz:Ã;oOþ½çž5àE€9@lÅ£l˜J“K⚥{àQØsÝ»oÊÿY24~²Ž¬Äh«xŽ)Ç`óô×öŒÍàpT(™‹ȃ•¸c%HG¸º—ÑÌ­O_¥–î‡ÿtGÛÌé€ÚÅÚ¶ïÆù“¾þg ÿ_…ÍnñÍ·Š=µÞö‹§oÄ%Q7s¿J„hù_ŽI›Úìé!o~òWbšl–Ú·áûµ*]:´f;º!…ˆJŸuýÚ‹–[Îåk¿Ê:jiDh.¶ìo®§2…­Äw œùË¥mpΩ笷ۭ¤ì'œdÌÝ’¿ëý†ÚГAs!K¢³|?5ò¨˜Dà÷ˆù?FêÈP"_Ê)yuÝas?L9|N1lR³‰™¼xõ‡.ªq)ýCL3®hä‘€6Ú‰<˜YÿZ¼<=Q ?@jÐ’5ªco=¸¹:ÿòo¾–²»L7[wÈ/eo•ØUZHFë¹ê1ŽDa+/Þ«î‡Ëø?Ê_Y\À‚׬¹×Û°Ð?×ñ±¶• QØI,ÉOÛâ°¡,¢ËåÉÀ óÃê-Êÿ»n¶í;éä¯j'gƒ¹E eþg0Ùì§÷µ÷¦å4NK8ÿmÁ&ó3:(Å|ûàZpÿɸÂÓTQþYŽ€Öö¿1?!Pþ­.}&ë åoë¿|õÙHÉs„Ñ*[ûàñN‹­ \{ÑL(Ü€ç/¿wÒ×ÿÛ—ÿo:þféµ.pqWxœì½y<•íö?N¡ÁXÉÔ R”ˆ”RB"’1d&ó<ïmï½ö`žçY™©De®P‘P¢’Y©D%³LÑïÞ›z:çóûãûùžžïs:Ϲ^uï{ï{Ý×°Þk­÷Z×mC+ÍË…N„熳‰ÿ«§ðŸ×ΩP7¿š}9ïy6žÈÊ}ý#˧•X€m˜Ç8¦¢½bŸ8lb£Fû,X&ÊŽKË1’À£‡“©,þÓ)r °ÝoKÅ@ð1KŠH¿:»R½P¶Œ´ÚM×wûz ±ìâ³3`œÞ±%DZØuÕ†Ï_3ŒÍi.Tn£&ò <ÚÁq5`ð•ÕÑ ÔõÙ3Ô­»«N¯þÌë<äÃÄWÝéƒeÔ}ïßu·I‡€Ã}¦ûS>jUVTëÅuÍÁ}ƒÖ!Sú¹ 0S3T̘Úá¬Ú{Ò¾F´ãœùkò¬d…©è;‡çÊŒOô9uog¥öö·_`'±F1dïÁ;wÏ2½Cí¢'*c]1m•ãÐýºÝŽ€ãTæ$AD™t€K§îiÿ"U2LÕsÅTÆ©OÔgIìKãfÛµ¬mr2¹g gžèÚgÙ N]KÎf…Ý[dà™oPù³ã©ÁJùøf®èãç¿m¬ç*#º\L âݹÇâãIf`<¶è‘“âVh`^yY6ÆÒ—îøa´fLÿh È4Ûĺ¡ïH‡_@ñ /ܶØ2bËk–ûrbF6ž?Q'­é+>¾½iã×À3Wwv¿ÞÁÖ™l1+h —CO¯ ÏW¤ ’ü²Ä?õ[àÿ%´%¯`öµqÿºžž×®`Êœ:0°ßcýp”E ”xíQ°ÿvÀ@u}òb„¦¾!#F½D/ …ß-(’ßæwl•Û°:¾x]‰Ùˆ%åù<á œìÏUüë÷ܺzSÈ^®¢p¬N¾ ‡¨ýnt5:q´{Tü@°Å'“t<5d“qŽÚ¦íf›-_ì:-¬¶ø`d©I¯ÂÁä¡\ýKñW, îÚˆißJ]Ñ™…š…± Tþ7Œ¦>E¢Â¨NŸu+sÞ_M_ é§Méy™ß˜ÝQ¼ªuÓ¿C‹÷Žp:}n΃þ›M®´y1áŸðïW¼?ŸÌ¼9ÿ.ƒœqÂun‘ÕwK^\¯@7l9Vw2´@ƒg–ÃÔ_óˆ8\:¾~À¸*)$/ðºp•Æ[ pÖÉ´‡… ÎÇ)D $¿öVfïn]?§Ô8ZÞ2d|V¡V¢xT·3•\3H‡ æ ÑZ„ ÇíãÊ­¿8 ¸‚åJ˜/áŒÎl>0?†‡ÒùR¨fĶÈPëNÑ¡ºK7Ÿ[ÇN>½W$ာ¿h§WÅõÍŒ ºŸ›(LÛÖŠðÞËÑEMÄŽmmrØPäŸÜ™#AøÂ€ô±QP¢Mâ¿dÝ®©G«¦íí ˆÝ๯1òÍdŠ»ŽxZ6*élîŠ0ò¯Q8ÕO¦@]t2¨V ÇØì Ô´YýJaCÇ.íù¼cIÙGçÁß*’½Ÿ•öh‰„˹›wã”m F^½©¡Ÿ–b›—I I…3ã}q ÜFŸìÞ¦Ç|…xÞ”|BÇ ·Õ°eÜÇ .ˆ^;E&³D›~kFåý&øçÌFŸE’†“–“F~É=uê´5šëß®EqL—ÁNôë'ÖÄ¿±hµp—ºÍ'ºsG`椔Δ÷? X¦“E-7†Ý¹»…W¬_±d$€àð‘äXSNZPî2oFt½¶@ìåó¶7%*0ï2S⦨÷L‹÷¬S–ǃû¸õï†mZædJ êBÜÛM~±s p쬲’åXö­él—›‘¼ÓAìe ®sÑù¡ë5œmÖÔ½Yk¾`ÞÚUwÿÿÕø'£lW¨ÀÝ- ”ð×1Ñÿisö ü«§ðŸÔœÃ‰êÙÞ7‰#‘7o4Ù‚#I/wó®+?dê¨b#Of3qXÓ²8<ôVŽGà¯á~÷á ’_3­´[›‚¤ë‡ 6:Šù(! óÏ z}_ …ú]ÜstO<\]jÍövš ÛZ rëUž¨O…ôµ˜î hM—JÉá}3Mèk3Ô»nÜ ô7±íBª9»DfÇ@ÿ]ø£;.:wDe‹ì`!€)×Éã^/•ÞÏÏß{òåó¾à¡aŒÐÍËMw lZñ8Ct6œžeßAE¸ìbVnZ]jhÛqˆ) ô¡Z;AK7¡ÉâÂމˮW3¹ %ÔZDH㹚N[¬, ÍýÌÆ}®Ñ€º¤Çb¨Ñ®ov$kÚ¼ÄV×f½Üc¸BvüŒÎ)[0þÊ Ð]oáðõðÈ©p†.g1TF‹‡ŒÔͰùö+×Z£-À×[­¼Ûƒ­JÈíN†‹‚‘cJ¨3°¦9Û/ÒñBãÆGà•j ø{\YWµPÏX² \%+ÒZI; e5Ÿ*kíe÷¼ê-Wᣞœsè¦Ã§Ì‰"µñm.Ð8eÇ%&óÜ757¸äyFºø]W'ìèkyÿÙE¼o£X?öÒðöVP™Ç‚ çºyƒ»¯ÖX͉˜y„Êü»8_çÑö:wËo8öŽ57sœßJo_TTçW)MóðÇ‘"žrÕƒÌþ—éû™Éê 8ÕX&%p«Ðâ8ŒíuîpF”jí‚јpŸ˜ý’WümæÒþG«º† Á„­6È“¹ú†¡äÎÃ04<_×nôêÆŸñg_%uŸ+«‹–ëK`ˆ^ÍR¸^aàBã¦Çî°1ø†÷Hîû‚¤\~`"¡oV4 0Îï‘^%þYFνdSlÈqömó~Õxˆ§ïsÙhµA}•càîõ† ¢ƒLˆþ‰ûRJÊ΀“E:ã’áfÅi|í;Ü•äa­Šf'bÛœC­³ÎÉžæ=N‚3ãc­Þ2wÿÿÅø''\¸ß_FCÿ›fó¤)¿O3OáÏìUˆ&Ÿ¾–Õ¼¸¯wö&c:{õ¿Ô8çÓç%@•êåÖ©{ÀÍüÝP›_²Bà*µ2¤£„s À±¢òn¿ÏN“žôQöf‹ Õf?¬36D ¥bï{ú$ÐZ5mÎy–[¸”Ó»wIQõwSËzí+±$èç#^®Ñ”èåˆL÷)œ#\¾«CO¹¯=‰ÝðS$õ³ejïl6P–Ø ‰›+®œîˆy3~ †Sô C +6+—Œ¯ ‚óê¶„ã/àVo'aCLo¨jú4Êb«Ê‡O~•Hya—ε'Õβ¦h¤ö©ž,Ê$ºF„cm:îôeAÈW+Ȧ©ôùú8i"w’àáÆ<€™K¸Oáò»f"@t Þ©ð€¾©ß]Rî¬AO„÷ºµA«Î[¼8ÖoR±~À_9üzýìBWôä×gîÙ?ðd¦þ•ôWõC¥î³Êor§ž©&§è§uì÷úBo¶ïêã·sDŒ¶ã9gP&ÜêA‹M¨>V€Ò¹àó¶D6°w6œ™K:q÷¸ŸÕ™ÊÇrå[š}c³N¹áxéÈØ÷ò=oýZt$¢íÔ¨’«í“`•¿ÿÞUK‚§®\Ä5²¥ë“TýÓ¯ ‰Üöï†ØG5dÈú/©&†‘ÙˆhOÛ*C}ïM¢9j× ;san“"¨ðN/OÒõwWÐüŒÿð ¾ lÀ=r¸ƒŽ$b­¹§4¥mÚÒ&1öÏŽŠ*ØNòˆ< Ô O¬¹‚Ó£Kû -`jö¦`fƒ}š/«¤("ÖmÌn~€à/v¦0)ïúá8ÛC“úÈÎcOÿ¹ü]Ÿ<ý3«Õg­ì‡ÙÎÈØ@Œ‹¥Ñ þƒD&¬†vÇ»²áîí}—V¿ö¡K»¬Å×wø›"œ`þ»ûÿ/Åß9œÂ87 ü_Ã@ÿÛ†µ‹û«§ðŸÓìýB-Õ"JHÈ鉈ç§Î©öâ©ù9]«;K0:Îܱ«ñð©±Éîál]$â¾ò^m^/TÏ7x«Ó{‰À¾Mzç¹™p_PcÍßθhL¤ ™”Q±8xî#<õÑ;òöcàðý]µà‘Ä©¾Õ*O.g™D2‘:Ì€Ýø-%Ðí.?{]<øêÃ|Ÿ -¡ àr³Q\?ÒK}:w?v 2 Áú¢Ž›˜²ÈÃå©}ýM:Ù†;¨Ã%2ºý0r'ýêjviƒ¤Æí!žÖBá.²®HÐ>ÚuÏ^f9ZìyÂ!œª ?‘…cÎ ¼ ¶^†C•©u!r1Ǔ˫>¿vÆcÍæÀK¤%zSû½#ö¤³×5QñÙN{Úxê8.’þ}ˆm¢ÊùÌ>^juÏì6éÝ3¾øå›]7¢ñ’ý\iíŠß3Õ¨‹yÅÊø„5¦Kü| ÕsòBŽâªŒõ U¸×9:\×ÙÅ&”^‚‰Î#I½áz¨é CZ p?Š'ÔòZ¥VkÍëPXUÊa|yÅ¥n‰å¸x›ޅޤ! ¸°j GE a6,ÇŽ‚í%6ëX%ip½q©\âQIš¸³>5¾ ³ Á™~¨ÚÝC=UJp¯}´êÒ›í«Õ„.‰<å´Ô™û½ðϧ¢W³¿˜/ϹãÍþRl½ %σììà•ç…`Yü©"š¶ÓCq߆R~íjkwìRψÜá—ݪ`3š€ûá›þ൷<¶Œm6\uЩQ/Þaèts1ëÅz§ I’6»JWe½ZH°áŒroõ‚w† ÚgSÊQêÛvˆâcBô%Y¦U£x­py£DÙ5{Ca1u¸QViþÅÛݸx'J¨²ßô ßtÜÓàØ?¦Q€ÔñÏ6ɾ >¦ïÊ&izJÍ;Ô•`usIa~Λ„såI™™Xb÷}÷äþÀ¿|÷3y§nüe¾ o ‹õï‘ôü;d¥« ŽuÝÐѤ[««aí„qSÊݼ‹­ÜH`Òk£úž†߬MÜi.Ï"EþÄÀ®ÜÞ’Ò͵ҟ7à¥ä§úp_¬‚‚£”Œ]8×YDÿ¶‡CïÄJŠ-FÝ4 œØÂqó”•m½¦NdtÖb#XZ\:9•¡|m¢ùÙN$§Ä~–zA‹Œ¯6ÿîþÿ+ñ_¦oB8é/¤¡ÿ]óôŽø«§ðÓ0½(÷ !ä_ulšPÙÞK±ïòë>µõÃzÇ;`î¾õréØ48žÜíEcg Hƒñµ<ÿ•Ó`Û§!"ƒ]ÅÀõç‹X{‘·.üJn_^êçé8ðZ?븡° 0­éïüüâ¬Ì6~ø´5¯—Ÿ|{sûÍ È?9ñTzÛÛ…Ú—Ç^çƒ»Ö |pqžE«Æ‡AÑ·è*Àñú¨G´#ñç²Õ!Ü5€þýD>ÇF†S•ÀaKwt `« O§à6>íb¿#œW`sg›Ä4x—ñ`o£|CÒ8ß8+ãq®¾­‘;lÜR oP¸”¬€ÊÜ|9 fÌ·`Ý?4‰öó÷û6‹¹Nµ¸©w[Ö“xŸk;Ök¢Û­1·™‚ûY§X‰|J¥=`ç!LÜ…¬L`fž rï.««&çqlK,4<üöø †õùp“î@ 7$9_Æþ.$šå5þà«5ïAÒ+`+jïU• [xÒÿ ”j­ŽN] }•ºÑzUK}Œz”àzÌ&QZW)aÜÅä7P(7Eë-^¥Q<ÛnøXW}zP™÷aªJáõ6ÐÙÝt望“øfèSörxߎ¡» å†O¶Á¾nΠ—(¹2Ó)Þ ´Žhû/7ÁòýH`O»Ô°Ñ‰CXTˆ&Öµ•Ç/Å'£«„öf«+ÂÖM3Šùs=0r{f-x£œ89C»cÙà'ïÛgÖùÔç t`« j¨<“ʆ“l£å"–e–‡Yÿ ü;?ä@/Gâá[*ŸÌ‹ ém¨ëúv*½'#M#žîÈšƒ+ƒOëô-Ô®W9‚¦ÐˆnÆû+uÕ.COšvwñðI¾Ö/³º)g4Åa•øb]¡œ<—SœØEUÇ ÀºöÞqæWéõ´Wÿmë§ ›®–Ó¯u }ø5ÀdÈ‹µÓñ-§žW *yix#”™º/$ÐçºhöiÞcÕ€;kYÔ{äNIFˆþþ5ëëͼ/IýŸe;频iÊßV ¨:Ý âÖwÛÆú­‚ÀgØÙ) Ç9g%_8µ?ž2{žòk?µâ]R­$ã/Å;†y;XˆÏ ã÷íýVœ,_xœá»£Ëu¼çÁÕ3؇uN’ŸJ©¨Êp-Áw? å¦wùdüýA·¯$Ï0RO˜ÛÞ ôuwól¢¯Ì”L— <œ`Âwm¥ZB*\‡¸á¡aÇ\e3œÖôÅ5['"Ç.a€Ø¿Y?ܪ‡YŽ™98U{´*Ržoõ¾O­ãmqp>ý3—Ÿ_ÛÆT€÷%mú‹àæ3½N )h‚ÁÞù–%ÅÝ›†ö_±uo9)Q,œ ÏÀ Fmz.¦>q'·ØŸ ®ºÞågáå'¼ó‘žT¹}Oúàdb–®6뽘Ú,”j9Ð ó\ÓÉŸÖ*û¦èL“@U5qYhY“·4t¬w}[ò8×ÖqÐ/Uš+m…µ{>œcö#úz±¾uñ9$H‹¾mÃÎ >Væ[·Z¾â)²Âoß~V?©BR¼ ÿ>™Ûï³»4×ZûŽÔ¡Í¿!þSõ[_áâ} $v)Î,ƒ®­Wþê= êëTÞÊ64$~¯èY}¼_‘žoÌÎîÀ?k@Mèu¹Î!íÀª>¤<4yê9<ßÅÚš…Û;9ô"èY´@öÝ×^<|ÕÛ °Àfbfµ9 Èˆß Þ¶ö…E•l¦uº`»@kd^¼‡Ú{M¿rÍ™Z“n¹ëÜt !ý9øïÌIɸBE¿ø\?|Úœî‚ »êgüš9’V-©-ÀûÅùâç¨q˜$ŒsNÿ‚ÕÔΚãø/‹áÑTñ†:…Áø ŽïUñßñg<•L¿¡5 küÊp) nhÁ1g‹,~Ú’.Œ® ÎÀKl߃w7Z£¬èÎ]þ¨û8áH?fç8?¬×ˆþŸ Ôm>ø„tTSyÝÂàÁéÅëF¿EÏ{‡Ù¿ðîs€;êÊwk§­sk•PàhçöG¯ÁâÔC…+b­éÞ¦/‹6…#ãï´nO»ó (V©UòÓñ¢‡÷à!2öõ¼“XïßÝÿþ‰dðtõ ÿÍžª[Çý&+þÍÛVzô]ä5ÈŸ( ¼¯ íóÚ ˜é/ýéZfž–’öùÚù­Ù\²ÂGìJvÜm?|8|>ªŠ3ô#ÅáêXtgX©±a´ýý¬dX[ò Ìíýw ª"kõšW9 0/ó¨ ÄM½—¼šïÃ,8g%¯+ù³¿Ø|×ê’¼+•Ôd©+‘ñŸkÌ`>n¹B£›=Ë sÅþ"©]ß”™÷f?–ó’E™hìööá5‘N/]…‘ñ×h>îûíX>処ƠA°¬ Çï’o»¨ûŸYNÙd[S<ým$N§z©÷ô™\£AT¦IŒ¦°ù;¨„9ç}U7y×õ–½0í3 ‘üU ®ÎœÉ~ƒ÷ìá†!Y-<-§”ìû°Ø¹M†x§½ìâ;B¤ÖD~cïÌsä¨7_éa1ž”ô´¶(vÄs7p”¦%8‘]Ÿ`_››àÃð^òö^. X—d×5ŒSLgY8¶•3¦¬BÆÇ±½Ù`E½[·(¨ýi…Ѹ€z ’¶G}œÚ6ÅØv ¬´´tK@QõÑ›Îú~¾,ŲUž¬)ŽR»Ðô_µgœù3š4p›(çi§ªÁÉ3¼8d+·ß£í>°Ý<3 !ÇUf¶V)·yˆ»êÏøªííZ)a¾(šéX‡K¥t†æ‡Î1¦ä ²:PIwr©í»ö$MHQõ¡ú3ã×á2/ƒ™ƒÏgW8AßV+°ž[ܺ¦;MÒím\-Sê°5HhO ásψCÆÀ¼³Ÿ š _òXfWK/¸»ûv¢–î3蟜ßÁ;…Ó=^C]<›Á;Þi“Tó[·°(7óÚÖc¹AþPšpàš&8ž½oÿ­/óhÉ£ù§°ö­ç7îêlÛë«Ñô¦ka·èux›Oo ùïÑ_<öóË;þ®ø{©2ãî}‚m¶wòûs#aL2ð ²”¾u1¾ðÍ-½ª ÜU{Ç `QBì×¹*±ˆÁSá^› LqÐú<ºÂ¾Ï¹st/¸°oà%!n#P‰° îæ¿vA {ÌØ šwì¬.òç&l8uôkâlÑWîˆ'r7nîoüVR¸Ívaxƒbvª+Ñåý)c|¦w °† À¼Ic†áOÃÿù.¸*”P'©hÕ«{ûý¡ŠîÚ{.dý‰J¥¬rçÓ|EÚ"\ú‰_­‰þ¸zsef«ä”yá-Ö¬‡é%Ö¨“+ø·E”E>ñTJÊxq>Õ'$¶6¨½4Ý/­ø ôO•csñþÜ]àQ¡çN€InÀÚ ³™4ƒ“b"¯çA17ÒË+V¶y·D·6V5{Ò”©®òÆy¦›‹9›CûÕ‡k?%$Ý0h°5íÚT`¿‡Ý(CX_@¹™!ÞÑÿ– g d|lÅqí.ÍX˵ÓâOk?_ëÈæŽžä^5²9åÉßÝÿ þi8w÷€°ß°švdžþÕSøý›^‰%ùÉÏ5yéÜèÐ!:-ö¦/²ÉmtsMQþ?ðâaØ{ÞÁ^ê<ŸìrÙw$Œ-0ókìfúöP%èîquÙç£@[Púy*qín3–õÛÛ¼‡Y‚ÊŠÀáë57!ÉuÚF³ þÒñùa¦ÅDÿÀEC1po>J´Û·+_)Ó¹]ýe6[3aùð®­¼$:$PîRf Œfòox¼ëÝåïq©"-o£McJ¹LŽ,àt€ö¬É‰f®%ÉAȼ·˜­Ÿ/¨/ÏODn•úh×¥¯NlH„š®÷þ‡X¾ÒzöÎí\ bÙq`š&Œþî¾5±ðÅðãM0ÅO 0:Ò€MÊ£"puÇÓÉü½ ¸ín¨Æt\Ú ¸Ñ4x·]6Ÿœ[Øú@aÃ8ùå¬L¾H.‹ÙNê/І' >{M–ÃÙk¾Ôåõð|k¦Cä“kÚ¡öçîL/àà ÞJ¹-Í]Úšà´ñ³äaY©|„ãÏ@ŽõI÷vÛzÉhï,‚ÊîŽà…˜ÓÚôLG Ÿ;¹?ÈY®Þ¢êõpÏ¡¬‡ÆYgš©Å®T¾ÜúÏ—xßÛëÀ[™Ó½K˸itI1/hßgïv‘CMë_a¶ϯYjÿûâ¥|®I &¤˜ òÅÚ}é|–qjÃú&àÄ;†Á{?É:ÌWñj1±ÑwÝNÅps%Â>L;ÀzUV&Ç Vö ÅÊS»mꄳE©Öd°Bÿg8³Š9à‹Å.ð’+ÛŠÅWàÔ3ðMÞÕ ’KÄ×’¿"êˆýIˆplH}p×Cö˜}Uº~ˆ0s\eÏæ'Æzþð5âƒ&íx¾3Ÿãù°:aúð (UGƒf§Wp|˧>:©Áá$¬½ÿÒ*®!Bš²fƒ~ÕÇ…dƒ[‡Ì†Ä+Ý­—ñ/_ç^ãÓµæÃÖêQ€b)‚ð†Æ#gÀ‹kégžu<œ 5öo QŽÔ‹MÆ#ü½ì¥¤ ‹ì‚<,bÿùLþß–v+tÛäVy< ²lí0ØW‹r ç—S ÜÞ¶ª<Ñp¹·æ À>Ö¤dþÖ4eÉ—äîZ“‰9PÕr_L¡Á[{µÛ:'Â6=†Q޲ý…Z!ŽŽ2‰€Ò/ó¸Kü»ûÿ¯À?ÉÒ—ïþýs³‹ø}~hñß´m`?O~éÝÿΞ¶R[B·GZ‡äõ…EwŠ{=ƒýkO–_[:{€]5¾ÿ˜Î'¤V ­(Û Yà %›ÿ 6gÕãXŸKu†û½HÞ`y’jý âÌ”Ú `Ì·¦ª¦¨Õ(Ž9†Þ'ŽrÍbä"-ÀšÍzBäÊ5ð¨yÀæ –9–îûz=C"ƒL•õ†ð îIœqF2=…T’pl{á*¶n;2¾uÀâºDóGÎ\KÉÞ|.º¦€áÀ¾8x.ýyzÃ׋˜ê”®&€¥ðŽdpFíTßAFÝlFõüç*Ï(÷…&ÅŸô!‡U2ìEm9FT.2wIÆ<À~!3ºz`MQÕá^ÏUiÐöu9Â#õwÂá¬M$X&•ës² mðW,[ÆÈ3«žZîï̇±äõ½œ,…Ÿï9ˆ›Ó„ZÅÆþ~Ó „«Frj®ií9ÝZbØæÙ?W;Zõ×ã½—)3CEJ»Óó÷`ºuˆ=yC‡Kû³µ >Lã’ü±¤-ø®ÞØÓÞž3‚Úߨ¨d5*njogü¦ÎgkS™mº½ -×+¥ZÜâ­ëd½ÅæžêLÕäÛ 1¸°iÎ ÿM•IQ)º]Ê=ÜÇXbmýE”Ê IÉo¿r‰–m͇ËÅ H$µÏ ×é½'êÒ¶¡ÝMì¤ö¾,‚‹´Acɰ¥ÂÌr£R›(¯Wï»]-ê^G7†–"øPÞõÛ¾/$}¦z—F±÷:¸#X½ý…ðóá ã–·Y@Ю)-kBÅÚâ`P“nÉìNe’åÔœ] ÞÑw!N`"AbìUh‘S±*õ¥Ö+ó5éÙpiTäOÄ_”KZç³§é7[ÒW/o||EF ÓS™M±O0W×ႰܧIg#¼b•„u0¼–gÙü(mu®sČΓÌvó-ã?$RkàTZ˜~LÚ:$±Ó`³Ø.qxO3:d#ëÚ,DWÄàþ @–m,.,ø®" ŒI/¥ÊwWýäY\(rӲΖó}óµwÝ>¹ËÛh©?~RSnVq ˜ÕŠýÁóݶØI=c„çÛÔšg‚Á±ðÛ+hª×¾\@Æ7*¢ŃÄá Fe€êuåe¶ÃЮµó¨m2¾¹Ë=Õä‹jwÿÿ×ñgœ«gpðoXþ“Û%ð¿ÚüZø ¨Fe•GŠN|<§ðà@Íâq³’¢ÁsŒ%@íqí1Àû©«£>’ìHÕEÔ°âTooÃŦµ;4ß/ñ‘ÀcòÛ„]öÀ>kí|°5ác 8ØÜÑ~ÏJÿîžž5)ÐñÓ¨]˜/‹x¿Û4*à×Ì»$¼NsŸ˜ö<¼‘_ßÄáVmס:s‹Ý¢Ÿ¢%‘ E[Á'¾êKåf¸®ë§×Ý„6Oˆªfp»õ2f’9 ü™[0 -›x½?ñ4„T‰opÔäÏOF2Ž ¼¯¼Ú 6žÞŸYû¸eo 3\ÕtN¢ø¸"T3 €g¬ä¸‹Ã7×Ñ.þu-žckoœ74Îj¾Ç?0¬ïÖ¢(inokKTÎ7 í¾éàãJ¿ö1~jýÔVÏÉ×ûèQŸ"s'±Ï-xtI³¼p3@ÁnP~Çk°gŒ;ñêdÏ7Ãw¶M ÀõªbLˆ($%Ó†y-@JÓ†Vû£B‘ƒ¨q “5Ó™|IúxAHu÷ð¢ý÷nË£–§I‹*º%GÙüêŠ@57x–ã&‰‡J<{û˜Ÿ­ ÊÔVzâŠ#äðëvªZ¨«ÊîF89è5ŒÛ2ícº§£ÄÌwü¼â…h­´ª:¬ÂÇë»·äšýÞø§U¯{¹³3£þX(ŸÒáS1àÙ½T ÆûR¹uâîÝŒ©ºàtW©¾Ì;¡Añ"÷G×*é‡îX8‘ ÷±°hؾé ºÍIqº;¢nƒI·%]»uëI±§j‘ eÆÚiçBëçN_ybUSn€jöP©Î?L×iÎ$L4%¼ä¯×r¬'#àQ~¾DsEÝ0ÿüyõé@0“ï°í•øSñßóÄT››a÷§}ªó{&¸q§ÕÖµ¦Ç1Úsb½x›à@M·Oˆ„ÛcS™æ‡Ð½leË>?nV¬k~ùtqÿ)ÆËê¡Gxv¿ç\…¡ÆƒÉk)'6žÆñtpª– lgÚP?Ws^«:Ñ#­ÿÔyv/ñ Ǹ¿ÝéÀ5Mp¨çÝ7õÀíX `ò+JÓ3¢æXáÒµ”™ —Ýuí™ͺ%}Î7Jƒk¡w쉠Âc 0(%›@„Ý£³Ý*ë 醡ÿÈìgné@4ëHHaÿúš–µ€¯ä²?Ðúª;Q—¸ÃRvïßÝÿÿUü·€— ñ7úîß?7´Kô_=…ߺ]6Fá9s#;®ì#ðG3$°¼Ä-§ü¢ >R ¤hN2Û#µÖ‰æö³™‚lûµÒňâOFÄЛWqX|š9ø"Nuµ4Á-Ÿ¸ÿ2jë“Nd-GJ‰Yuü™ÕŸ‘n“Ì>n½:o„CÍ£‚®Ò¥ûzBÒÕ2šæƒyÚÛÏÜÀ¿Ã~sân_zÓy/ým@‰…!×½ `½tß êüšàv"’/ä,×íCN\{¦t†å"aOH÷SÕû½lbò¼‹ÌjÕwGjÔ2x‹~ø %ùÖ§]°Žc9 {gËŒ­]Š õø/”ÁÈá÷ WU;™Hõp¿ ¢p—I¥ã JÓ #ÏC ç|Žg/¸é” ë×þšÎoVWâjÍ×WÕ*»(Øî4 åúŠú÷ûú³qÛ’ÞågKjï×цð23q4Ah+/¢²}þpª¥ðè-E]Ùs³éÐnz &;­›:tT.í/ÁwÜ¡ÉG‰‹h]x fL¢“pñÀßYÍj¢8 ª Ãé²÷óìع˜þ¨¬W‹`óµ³û"T¬©9QmìûwƒðŽ¢‰n>4 S Ä>ðÅäi÷K®÷b•è~>:Æ¢¦ð1Þú·Çÿø;.6Þwr=m}ãîz9öÖ.÷qÿMͳ’ýiN43câK‡¤€‡–æ%R»>ý ›2UV»ëÊVô®kZø(ÿÔåúÖ¦m7-U¿Â^®ˆ}€•8Æ€pˆäN€é)³bH°ßòàf¬H (Zݪ£[¯@¶-{'È]…¬Á¶ËÐzm5Àú/ˆ:ˆàÓÓíÔ{éÄH§ÜŸ‹¿¤‚€ €’QR~^r¤Þóƒ ¯iZÀ«up¯ìîݰÑwÍQN¶1_­µN‹W6«~ õè‰cÊ´ ‚)$ãéÒbÍ$Åã|cî>ŠÚ‡xÏ\tÀÅSh¤ö^p,xlÓ8ÀæPÉõ¯,LnPßÅÙ•×Vo8BZ:Û´‰ÄÕ Ù{Þ¸ƒÛ‘‰ç JtìµÑÊ’Fôæ”é¬eò!rï·ª«Ÿ·ìõ‘ÒÕH"©yâÓÓ¹ÉBMŸì¿dÑfÚsÑ?êk©4G™KÌãobáZŒ¶€õ”ztÍ¡àj»éìÛàfzš7bvõÖÆ(¾¿»ÿÿ‹ø'`\P¿×wÿþ¹¹~ëéÿÅM‘ü›??.Ùà°ž–´NÇ¥)8ç|ùf GÏÌc&Ñ 9/0Ç¢ídμº6‹tDQ´'Á«g—¿¬RBV9ùw†wõÛVžÛð–Û‚îYÄÅn€<¹}éT $ÛÄÐŽô‚‡5GOéß°¬ÇÙšâÞݼºæþ¬…!Éqœã1ªÃOÍì>ßÞ{âÇ®°ï.˳ê)U0…lµ4©ªb>"˜‹ÊÄŽÄ0ЙÁ ëäsðêi·8{ è5`ïfsãá-Û‰9Y³n7={©%4´~(ŽÞÌðLÍÑrú—êNF¿,¡ ¢QˆÝâLå~Åpq£òÞDËõ¯¯£ÝF8fæSï `Äœ£Î:ÎñæÌÿÁ!Kµ#±/šô}U‚NÛI0ùŽÛíÆüàïšFuz7`쪵 `_·UfrsFƒCo+ TŽ—o_ÐCa½vÜíÏÝ©)TO4S^æ•fk»AsþÐ…t£±×æŸmo«ÅÄk†;„MJ¡˜XèŽöhbïмVù¯€lø,wÙ˾ÐÄš›cB¡þêd2ø•§ìƶ™sÁÂhDZ ï+ i}x…&%3óŠ?ŸÙ)¯®æÞ*yÂÞ‡£¸¸SM°u­nqjÛ© 5œÄ_’¦V |¸÷гæÅh˜7Ÿµ³ØÚÁ ¬KçÍ‚©æÈø3ï¸Åf9&èW¸·oàx„9„]¤Š×Ü çº51ƒÍžñ5MŽr1††;»êAŸj‡¯Õ‰PÁ­D×T³PVÃ¥aÎ[í²;GoØ¿˜§b8Ûåá°6©âµ¸¿­ŸãRVq-Ö;|nÛ€@—Ç’,mÖg425w¬Çw’$.úÁÙ„À‚©0‰Sñ•ÎݹVŸkïƒ7Y÷é“@M¨ýõê,ªæ½&›;À5•þ ãè¶¿»ÿÿKøñpõûݾû÷ÏÍ6êßûþ»7¯rªu2à²øII<:Ïñf½z*ûÄ¨Ò €;Ìï‰K‹N¿Ã³þZnÃ"Rpñ-­F.jD*ÂUîYšR–™H'²t¥_Û ÀgM«Ä2÷À‰qõ`jâ»ÿö‚ê• °Ž·ð v uóðÉQƒÑ·Íó貺p®cªJb7/’Àc{”/xžW«Tl}à4± ‘K_$Ì£¨Ó¿œ{ Øu'wGÀð#g«›€»®LÐ>¼ÞoÓ#åïP#ãÛ¢«mb¿]OMï´8XóUñy.ؽ³@Jk¹Øféj/•×’Rr}I·fGtŸƒI\ïQ‚Ë@Þ„D:õêÙwó‚£Å’€ÿí] 5lì%™mwL^4½üÒßí2#fFÍA“Øxô¡òÑ ŸÑ&™í§LÓo3?ùÚÞ |Æ^i2õ_íÄYî½S¼Ó™á‘£9ác&ie¤8(ö@Î×N_¸úz<êʘ¬ãÎf¾eõ¿.šÒî2 º^¡:†ÔàŒŽÁurk®Úty•† °ä*R_ÑmèNÃu®¡Ï$- £cQß:%?'ŸŸæP¬s…]"½WŸÓ=0}Ke|.„nŸ ©ÁÑÍI×Á¢‚4Ýüç-bO ŽÛ7Xì46–7¤zó?ÿº,vň4½·½Í`0åÀ¸žK…Õ™Ç{‘¤Ààš&2GdÃ"„ªœH“§š•%Ž|t·2yrz ”6 9Œ=û†Åw–úJ‡ºg¦Á§‡]6Ážšb߈«2ªÓ¿¶täÏD.̽4OŸYÓgü±ví±Þ·¨8‘± ÌŠ\A4m½!yI\æÛ`\•ç2N·~_Év>…?ÿ`5Ö¹ôcépïv{r­êMú‘i @xj=ö—/JÊú‹Ìl¿ñ4ž„¡µ®~šÏÆøÐUß6CŠY ÞN\¼ŠÛöͬî5€tȆ¤+æÖtážÂÎO,ŽdöÆ“£¸‹„iýɽG7Õì잟®#†Ä_Á†’ùÞ6Dÿ^Î;è¸Û`Ÿ±i†²S_Kº•йApþàÚ±Φ°[jÊÎqÓ¡£Æ6ì*Q‡{-¤*€“­ö–ƒ }*ïBÞÒægözT|+rßg!¦3L ˜/t¶)@¨ZÔEíY] XyâyÉÏwÿÿð¿áŒ ÷ÿkéç_oÿý1€©5£ª??d.Ķ—'¦çCZ¶4ØŸ¸Õ.¨§×„Ç2•JöäÚϱad®qo ¤ŸJ/³»ÃC$Lß.П=²»ÎzUàUv€?ج¥wõn—L¼e‰CŽÓº""ж9štËV Ü ¼½ï˜K¿?/˜¡DEç¡Ôm¼Ï3/ pÊG×8‘à¨Ús5¿˜ÕÂA÷’ÚMĶPð›«Ã(·×›z sÑw*ëQ¦ÊÑjçê÷Ïa5N mBK4pœØ„ð>tyÞûÃÝŠu‘‰òª‡±ÚÇ`¤ÁõìY„ŒG#Siþøå£fU_è½ÛÜçrÁuòô¸_)&Jo°¶ÜÉÇV8µ Dÿf7ÕÃý­P*T‘›·­˜*aÏe“wéOƒmБaÓ¥xèçX” ¶§5K€b¨=þp|rƒ]¶ÓØÉ0‹ q1}ú~Ü/ÉÅÈ1¢õ!&ØËOœ ´¯f}Kùã·ážá†5ôßÝÿÿ¯ñÿþ÷‡üÿ÷þ)@Ü¿ùü~ËæCÀc àãLþ@Pf pÖqܲ)àð°rF9ÅãV>ÄVÎD(gÎA$òuòg8<ž"ƒœþá>,Ú)ÒoùŒ,âßûñÖ'e‘–oÁ¹8ؤGú. œônÈó£ôcaYÑËV€Ãcl¢}—e–g²<>ny²Ë³G&€qˆüOëX–¦ÌÌÛ5ÿýÆå»—§ƒµ‰#¬ô@‘^>PVEþÐ9ÐoåìÏp.Á¤Å,+ueŽ.:DðÁð†ˆ¨C@®`ðÈžø€eA<·„Ç‘ÿªt‰Ç¡}½bˆX"`xdæx,Žˆ³Â—!’XŠ PºÅÉ7û08Î )Ö8r‡€"2"ˆ÷±GÀt CzÆEú‘µ.x¼\^,«ÇÇùÂo^4Y{d% ø“õµˆ¢°ˆ‹ˆ!ê!k9âˆx‡dä‹8äµ…Hã´°(×h²ºpdE!ë@AtŽt±#Rî,–| †@ { r@Ô 8dx #ˆÉ‚8¬k0‰¬ D½d(×qˆÂq.¿ÿ[¤'زò)æ@ÖµSøè¸|…,ˆ±EŽ®¡ËvŒÃÿdÑÈáô?á–„ …àòú‘ñlPˆ$È:ÇQÔŠ,¬(ò²N YGÎADÎÑßõ£vFV¦”Mæ$Æ‘–«H2“`ÉlƒÄU[„ÈU$†èƒ÷ ¦9à"¸e"!Sü²ó#=bœbp^*W"‘€@椘 ‘{$‡ ¹[û8Š ¥P# ¡/rðv÷õóA˜‰–€0 2 ò—}»>¼Î–Q¦Œ¶5û}ð/õ%§=Þ®‘ä*žBÚ8²ÂÈâ–+v<¥úþ^Ï{úû®°2ec€œ4¢NþçJŸ²9@>Åy£Cðߥ)>¥ž'sLCAð?¶bNäD‚\±áÉ{äò„Á+üjüs"XÙw’"ÌíbÿÉ&W ‚ÿϵì¶î©ñ3þ )~xò. ƒÂ“×O\fýb‡å¥þDñä4“ìäÂãµ’%¥ÈGÖJ).Rò5 àO–^ÙÀA ]r¥MáyŒµQB ¼<-‘:$!!pY@@œ·²Ý@VJùïîÿ¿ÿ;߉~ ú‡ÿf¿¸‘3¼›ù4?~dÑNÁ¾+¡yEì§Àþ£$üži.câAø™¾ï/›(Â)Α¾øŸ ¹‚ö&'ç[ôq6¬L);ØoÙsÉ)µ¥YNÄÏîì|¢3‘yy¢CÄD´L+>_qvœ}áîÿQòÿïyýÊ4ÜŒ§¾ÿà)?îöq‡¸òãOdý”áð?SËÛ” >J¡‰¥Tøeæ gûËë§D«ür©Æ!ïÖ#Y!ûå /¢/`]4o’«x2}“«ì2ã#Ý¢ˆH$%ó<bÈÌõ½€Àcí£ìâÉ•-yG êH…C¢ì|cñòùaäã¦ó;៉d5žè0r¤0²™s•‘ù‡RhýHLÇ>ŠH‘ø.MŽÅX´S,Rî#<ܺRî¯ìícœCü–5¸¼ÿOI(÷¡]#WRÊeJäpÃx“ñGƧl@w&È㛘ÿrü þ¡jýq@W쑲sò³e"øÇýT°®l“¯Ÿþÿ‚å-{²‚ý(j]ÙÖ_!vŠZÉ–5CÙ;ù±£OÆ97XÞõ'k‹¬òFDÎË%ÒùžqEåÈúÉpHÈ(ÞnúßñÏö§ìl!Âx¬¥Qne»¼»C~þ¢ùw÷ÿ_ŠAøw÷þ]øÿ¿ À¯lˆ/àpÞ–‘Ó”X¿Ÿ*6òcà?žá~ìð?Ê?ÊEÐ1Œ°R«}ò?Rr<ÖM¦”eã\î‘XÈÛi+;ÅX/w7û@ÿà€ %³_Îo½uàŠß÷·1C{È Ç¹B–3ìÿßÄyhÊ ¹wŒsþ?_–CÛÇ}?ý‡»/¡<ÿ#*î{Ñêÿ¸)¸’n#/ŽaøŸþí]kwÇ‘ýsk¯e[›¬“õ•e'–H€I< ÌL?fð$ø~F¶7‘ob¿¢¬üØ_·U·º{z ~ É=&q$ƒÁÔtWÝ[·jøYû×?†ÓÓ*"õ €Ÿ¡W:ùPHÀ^ž3”ÏTÇ‚|¡åì]Ü2°¹§³"ûÍÊOá¶TÐh]èÏy`’c‰^@r©ÚØòâÃ8ÍZȰ0§öµh?ûW–Ëþ_Áþì¾ióì‹Ò ‰}¸&ë¨g°ú⪲9šCÉúyÎZøoŽ—”aAŽ}Ôœ—?À,àMg Ùß2h½‚NTðóƃ9{Øl®Ú¿¼û¿t'W„yk/K­\BÛ=Í6ö ¢š(šRæ^iÿ?²ýáwùðd+,ƒ .(ž÷‰¿eú_dÚ‘`ôÁƒýÁðS¹0Ñt$ ’ýg#ãᾄ4„퟊ íuZõÙd6ÜÍ]ѯ6INöÿë„mkâÑüÏÕÛ>ÿ¯ÓþB,üçÛ]p}7^ñ¶Þåg_MD ¢¾KÚ¬ ÉW? ü³r`ÉõfO.|ò)¨¿œ“H𓉠lYùŽZßÏýfh‰& mb°ò»ÿºˆbwÎϽ­õ·ñ¬òbü­UNî £óë§AÀS†òQ¼Ÿ´wmõ øNÕNm”_,W0㟚êëéÛ/&4ÚdÈî%CNr2 ßÁ˜ v\°#WÍ=힎Ž2fFL6D{ëóàÍO?-° h臄H Ú `ƒ‚!P^›M™%‡.0Gv¤¹nMèxn½·töÿ;ÙÞr3+Ù§9ƒc³‡7"íª™‰ùžë§ÌêîGJ?yJÑ•JÚó\@¨rž&«æ)Ž3§@+¨@·¤bÝ3·íô›°ÿÅgÖ­1¤†“w1?Ìö=–Ÿ­y°ÿwG¥Ò§ß¿§¼«ÎY\4ââE}â}rŒ|ü_äÂíõƒ]=h‘ýy³t¢ú ”Ìú¾•”AÆ£)p°œg;qL§¶kž_ šÂç Ïxã¶Ïÿk´ÿ¡Ìäerÿú.¸Æ›Ê:lÒãóCŸ$ ò®Žvià ôÔWùZi 5èîãEÇú Èãó­ß8Jîö8Ù<2V¾ßÍÌúCýÍ4ò;’ÖúëYôÕBº[*î] Nãš³ÂÃ=âÿþ¯ÌncHÛN_ýÕk‡ù+‰´’ ä߇ào=ÿ½I\ÌO“Û0­GûÌ`Ò (ˆ"mxî4yÙeÀŠòŠzÚKªzsfô•éÝÿz -“´YZKÀú«Ú¯pñŠSüŒ",Wª“Ì ý³z€Ö™DÔÈižè¬û°½„öÿÛ,óî›]‡EÚ2áùñÜ)£HÚ(ÙßDü¿ê¯3À…OO_˜å>^€Û#û Qëþf*!«³î ’4¶(îDiƒÒïg¸—s2‚ãŒäÞÍØŸy{µÖ«gúE¹Ø‡í_Qnéìÿßd§º7" Vm½£âåE8vòJrxÊ.ÅO;Jñý~íY—#à‚“¬¿~Lð?cj¼.P ›ÇÖ…¬EΜ€$sÒúýbªCܵ|ïþmŸÿ×fÿ!Ž›^2ÿ\×-3ƒÆzœ?/"=:Æë,²)QÜ¥@°ÔÆbT»_ÿT7™Û0¦œRxì'3]N"ÿÅo~ÐûìÂz´è­•ô'Ÿ–~¦"ïñ¡qœòcÎ.Dî˜\·ˆt´ „ß/ѽO&êÖhèyõŽbC‚Õ‡ÿëD>Ö-1¨ÀÈŒ²áß?¥¹ŸNYú›³8 Kƒ•°…L±çš°²õ¯jï}_Xl¢TD(”À7Tx5`ž0ÜM çôi^>±Î$ ¥‡Kiÿ?|ªÙ»—”µÃòNzÎ)kÞyIÕŠ‹j§&¢«ù /€Ù¢ûfý (Åg©Ö¨Èµ”S¢àÂfÎP€t,·*¬ƒ{|˜WÜý_„’Ëp'"G^•þìÏ…m—x.±ÿÁ³ñ"Ò'ÿÓà ¬¥Ö+ý2d–D€ü‘p%Œo}€nGþçäÍ„’1dg#Ñ€ð" ûèûâò‰¬ÞüpëY LJ<Á"¬¼Ûçÿ5Ù¬—Òýß×tSI÷~DÍ•®"=ž©õÓòìoW.>[;ÈCjØ[i°5ÄSµ„{øLk4ò sÑâí[£/K—âÎÔ~ã‘Ò_î^Êÿ•sUùÝ–­ £‡Eƒ&DýLÛrwô«O±hÔOµ+2r[äÂõèð™x´|u= z·÷¯ä¨S|ÚÍûÁˆöDŽ”Hs:Võc©‡„SIà.­Ÿò1ÌKOÏ…ë4‚EY|ÇM`(‘ò]´+H´ºwÿÆìÿÒÆ`>në6üéOLkgœÑ)ñŸŸ(Îþ_îA4¡”/àUý~z‘K\ C}3» 9à².„T(ûµC+5ÿ¬ ¡lÍÆœV !Zt®w€´QhÆ€Ð"÷ÓŽÅé~ؘýeæeƒ©”!êÁúÃô¶Ïÿk±ÿPÜÿ2:Ó»ànÙ`õ=œŸOL}¿Öz»Ñ‹—?s!§‡v„´òø<£³±¿q02Þ!Äïx`W;¶‹oà_¶õžÒ_ìê…)>hï«ûZ¿ÈMé•*‰­…Ô ›R½+ü_ýÜ.¼]Îãhtª‚_ÔE‚¡ê,©õ³ Vo}³‹4<ºÎp£$èò”u svCõ“îÔ\Àá>cžÒ*©ffpå\R¥Œc“{ºÀ·åÅ4üQìÛ_úEš¿h qD½´_@@R;A£*êé[Øþ 8r œ˜¶“ÕŽ­ðlI¦²6ßUúë]%‡Ó3 iBö¿wÛçÿuØßùÿåô¤wÀ•oƒö¯ùዹ ˜ÏŸü~¥nçc˜Ë’¯r`”Tòqµ ëFàˆ“^:Ï«£ý`£'ÍsI8Ýx_ë?žäÕ)®:ý}«;¿Òú¥]àÿt4ªHÓ`ƒ!0&éêY®ã‰îˆ²8€–)Ý-ÆŠH›{>K˜ä6númvü«÷~ÿQ<¤æ™¤¨9CŒ44jœdy²1›á5rÕ¹”öK£\ª‘ØO²1»· ´ùÝÔÃ}.6fsß@Û/}D$àw«µ&„"ÔÆ®É±²(½Ýú¥¶ÿOyâQ¼óÓBÉ£éЪ ÿÏ e7v áÿ“•óPùï¸fŽ—ŠÔB/ QØ×+& þ%ÅŸ4wÙnºðBÃÐ €C±Tβ?ó í^¿¸Aû5‹ÐýßÜ÷aS`qð8–ïÛÆ® Þ±šØÿë¹Ðú@ú pyhýÓ·ü I{k9 } Pé/™{FüY/›/äÑý>Ù?ÍYadÍCÈ\E‡r2€tƒöïóãB PÌÇ®³}«Î/nûü¿ºý‡K ÿùv\õÖ}T×®ökþZ7[õx.¢/‚þ´¢³okÊ‘¥ï;hާ¶2¦šÆfúËm**ôÖ>ÒúéÓÀ(;’¸iæülåý,”¶†Ø]¶àSƒ¦úNV?eÒ’»o,êUeÒøÍ*îΙ‡}ÊÖNü–¤`yç?¼5qÕt÷~DI~Ž6`™+ññ%Á ±Ðtþðt*€Ôx ¹–Â_åØgrj?8ÐË€]yÿQ5‡ô“IÜí¤U`Z¨+æS?ÉCÒÚ¤íËmÿÏÏ´Onò+؉c§Ñ·žÿW`Y{]?QhX; ú/ýÇhùð–As`Zl¹;«uýþÈþZÚä.NwÒsY"‚­ñ˜›·ZÕx÷Fí_¶„ÅÁŒ+Úà“èi‡s™®ŸØè„íÁþ\û'Õu&4üQ󳫄 €~Z–ÅÛÐ(êTö¦¡d£}Ò^ÁþR”á²ûÎdÂ@X`ÈþÆÉ6KƦÇê„Ï>É…Ô!'*šìÏ ‹'¿¹íóÿªö-1üçÛ]pµ[áÿWSS]•]Ü(g… înåÒ`ZG'{d€j_XU;ñŰ´´o ËÑ¥'ÉBSj¼±¹S„ía„¶ÖÖµþó!Üò>—nLg8µ³·¡ÖñÞ»jôþO~?ô{{šõ¿§ùeá~4}J¢,kyÈš®ç A•Qsû˜Ñ<ãwû¿xY°¢—á6ú{‚(øVE¾‰#»ÃÖŽÖ‘&´ÒL3KþYA<0:Õ¿âo6Ùëæ§ŒÓÙHx[ÝœrïP‚IÁT4—ø‘[´xŸ/@ÉôsÔ’9³âÉûKoÿ¿ÍœÜLøgòpäÒ6¶ÒXZlC£Þçîs®¹¯oh¬ëáXª‡ ÷Y7¸~\ø¶Áeé  -G‹ËÍuTöŠ‘KRWÞöárMó2íW^¤œìQ0\Ǥä4iWßþòÝz¤|Œrs6ó ¿EhEwæïT†Æ'™ëúŸ–6ë¼^ŸxÕ¿´þQƒ7ÿr"W²h83Ãe€TÜX.cÒµs…=Ié÷èSûúÏÁþ/‡Ê·¡CÓ:†¢ UK?zÒzš¢UÿþÕSßÄÏÁ}é Œó@™§t™ö§¿7'cß÷¯¼óíØZèׯMÇdäÞMÛÿO'jmï”þ«Ä€ògí̪Kç¿ñ&ÛÿÏÇ`‘B…«û4ÒdãJòqd2QW¸×ª— r¬Ò8’nÀ*mé9ªØãæ®w€ƒû‚ïÓÚ‰A†pA¯³¹¢õÉÓ¹‘²LGýw¥Ÿƒ1ƒ7oûü¿’ý—ßÿßEW¹ý“µ_üÃ^ ±ðÚÖdämBjUŠLª}aqóäƒæd,“­í¼KH»O;¹MºÕ*FY·–Ñ''“‘‰­¼jÔŽGÁ4ßÕãoMð!Þµ¸‡Eþ(V5ö™3ñD®¬a*û‰¤ ý~ü·èÈDí4+kýïf´h<ØüŠ^\؃vÙ=¤ª¥á7’ÆpwkGV÷¶÷4ôìÕÀ¨>0{¥<ÛaUàŽþhKG~¦ùÎß'Yi‘²Ê­-ZX¾¼rÍÄéÃýIÆ=ÅhçêGô Œ"^ûYØç[›„Ê1ÁîFøW/&übqmB°¿Yàÿ¥Ã BãÚ°p£×Òwk2FvŸì¯ÄÅû;ø²ÐQÁHv—ðn:7êÁÚÛŸ/Šã|Xg¦â 8Žäaî,W(ìäg÷è•ÃgcHï• M~Ky>®ÈLjìÏ—¯“Ø»ú¢  q=‚"½€\R㸶Æu,Ù$Á9ÂÄ÷hBt‘Š€ÓÓ ªßa¹eš±ýU÷‰h}ÁöçÓËo[ÁþÂ"/l¾sÛçÿìÏ3Kï=ï€øÆþŸk¿T˜¸-v~Å9ôø<_|í2 '„™ÑÕYËÓ¿¯ŒñŒr‰{–çWШ§‰¶³Ñî|’›ÀËç¶7ýÕ¿°·žèÏ‚üªŠM•^FÞIëê4xR•uÁÑ*/¼6=aÅPtŒà Ýñ•A·þ-@ó+\‡'%™H€ä¶Õ˜Ö¹®:\€V :ó“ß+­ûº`—ݧí|øÑÐñ;Íf§¡-敃»¯Ë%iýlÎYI 3Ô¼¿þ3±ÿGŒ*­réxó*ÿZ¤l ûKÿßä×µþ ÿË ÀïdO˜1Hä @| F¹ê@èIÞ IöÿÕÿƒýÿ'\Zqk_{…o> kÍÉš6Ž€[ =síŸÌoA à÷Z×ðÇ_p™Þx|:4Ú»oÀ|]VúëÐò/\*ˆ^&ûÓGú̓‘ŠFGu®»ÈÐi`Û2¿ÒËÈþ=m÷Æ;»“Üøk:¹J„ÞÖQa‹ ýö¶ÏÿØþÿÇú(€„Sxœì}XÛ²®ŠYŒÁ@P‚$QT’€ 9ç0±«g†œ%#HRQD €Š"b% "JÎ*""@_÷ (ûÜóÞ½û|÷lßÖ³¾oÏôt¯^¡jUýõ×Z¸ß{†¢ð·/¯ÈŸ=„¿m9Ôj¡ñœsÈÎ¥ÇYzSÁõ,)® } îcqƒÀ¢Ì»[*”\ö,Ä"as¿â9õ@¾½àõ”мÂ÷ádÝ&âv€)ï›åP82ò8çLLÏÊmŸ÷Þ¹ö$Ò‘£ô¼Ãçjþ|á[N B )gBöß2¶>9Ç%S7L¶SÎSÕ:Ÿo÷ñý”€½=Äž„FVu¨ t÷y!n!Å‚Wªfcý¿oó(ÅØ”ZÉÊe·¦Þàª.'/ K MÆfÇs' ƃF8ùxãM#Ó2µs×.-s5í6{üÇÈupøfuã:щ$U/öú(¸ª$'ýˆŽs±Ï¬é Faù[SCµ—€(V7qR<ÖëÍ ;Úµë¿óÍy n ¾n.‡€u`ÍvP Ê„íèäWsÃažœ]“Únºw¡Žc8"þÖ@jßTh± ´~¹ýÆÖ©3[S>ÀvYN±Æu¦}B÷BHºpR÷Hõ&›Oç¨YË̦Ã=·PFÞJ§AX”»z¡W$ÆK:š®é/E4[½]»úµ½Ù»ÉvÞ%¹†LÏh„ÞaÉ)î;?Çþ¼G†´z$Ï7—¼à½ZÐܪ^s ¢ŠZWü2ú×·¦F\H]§’oª²ü–ÅÃêïÌ÷Ë$Þ¯t²Ž¢ù!öä«÷ÂæIµ ?ðÁþTñá…Tö§mÔ¥×—Ï Þãܨ½ørùˆÒvþ^÷>G;MxÉÅ9àQU vkŒPÜ‘éóAÍ- kÖeg5œïÀ¦3k>l_÷äÜO¦‚ZÑmyb¡„Ôû+C š»þ ý<áYêR2Y¼·ºx¶¼t0¸¿Ý«kóÁýÅÄæY¦7h’C¥‡ô=Êbí2Ë75VŸ>)‚‰Èú¾þÑ8 .Ýë ¯®™ È”Kè½Ó¥…v<ž%ß®Œé[·P{Îny²4›ÿ³®G§“>ixrbzùWŸ»'"gHNS–P-Ýáv/±AZ‰øvé·ÊrD`hþŒõ(hyâ%½± ‘WR¥°3ärXe¸1å7l¤š>í‹Ð;ö_[_ tžmw]Ù2ïÀÊêÕrë±þo¬J3ÆÕz›Rùì½$Øô»Ûÿ¿ªÿ&4Ü÷çÂÏÿRq øÙCø›–†å”{%fú7ùT£-}(ìXh(KÎ1¡•ÈEèL™v¢ÀY¸O1%xW«/¨ôPn™¨7¡ ã'>äúH‘²JiÕ'ªîú´§oS¸:âõ>îaÞpè*èᜎ‚cz­¾29ŠJ'4¸´5º‚Œqkã–$2UÿÒ•bm¸­Ö±«P¨f»J”+Kv¤§Ë ß NK¾l{*¬ŸTÙ°‘¨G:}ZtL¾ UOø"ˆ‚뵨Š^÷<€&¶OïŠ-ϬÿC¡!•!GCö;•¢Fcä5(8¸x\ó%øí9…Kϯ~ÿÙ»›ô¥eŠ$¸—ó^ô…];ßFzêI &ŽñÌ9,I«OßkÞ«‚ÍÿÞÈ•~¾3¶?ݼòÒó3Ä•íMèqI1´½iDeëN ù¦Û?Rv«žH°Œê ¤£$E²°w°jÁÅíÏ­iÐ?Çž'³»Ö3ï"•¾±Œ ~ò7á‘îÍ•vöº—óÞ»nRi”äÕ<¼ á:Ï _à‚U×9[ãõ¹”CP?Užó ¡v*!\Û¸±|ߎš™a©_mvæˆÛYúu+2…Ý:„üêSMÛ »Ü7„ ‹£ž†²Á>ñ—»ùîÚ2…Óºâ£IUá_Iÿ·d=üüÏÕK$ÖÇ}Œi3TŽÍˆ»Ž*4 V40îÚ ž2>–_PDâ‰àØ@HWÕÚ#ù`IXbþ: vI¿¢Ô{´96ÂÉà‚´âR¥­êcŸm—ÍY¦v¤Ly]·4WÖrÔQqjDwš n§åtׯÒ;ßK¿¡¸vý᪟{vä—·Ü‚69/W`úkô¿×)ðâsûµdÔ@$®ŽÕ±Hvjò9ä'65ô;­Ž¹Kˆçô¨s?ر@lú¢$ë'Çã:6¼-^ ¤þvÙ»”¾Ð@r>qÊ ’ÁeP¦x»>½‹Í ù¥_ø“©._Xþ(8ëðn»F«˜`¢e ± ø²©íA&\øÅÅ|ôy=&J}‘ ¥€V‘·Ö·/ËVÒÀD‘ýËsO™Z†»••°ÀÆÙkRêá]>g"µ)¯Ö$ƒcdŽ. Êßì#4aý“sß™}ò÷ýlͧïÿT9 NZ?ú(ôš‡€õ/$£aL+‹´‡ –Y¿»ýÿkúGƒƒúÏ,vÑ´Ÿ=„¿cñ›[EHF7${®8{J£ \ÿðL‚Wf7F·¦n²¹K_pÏœK¤"”jÕ‘“På§è­ñΠý@~”ür½°{û“UœÖèJVñc5M\éè§OŸ1jWYóæ…¶Óe¤®oÃP¦WëJÄ+î/ö 2(ÓГ›–hÉð¤^Ý6{ }AEº‹èÐú2€ÀS:^÷ëÏÑš·¾Ú#»BŸ¦îîËz ™Ò&§u)6ó,éQ©¬ÎÔÌÒžÝsÚ³7Án×6hë:‘§¬8(Íõ¿Iëi!æ|µ8ÐNÔ¶/~¼f%‚D°S»ÃQÑ…*(Påú‰ í§ÜâT$ fœ¸à•ypÙ0Øè”¹d+G£ æ)ÃNñ¦†aóïqz…L‰NXå¿sÇö~Â.Íw ç†È†{ˆk¾Ê*ö*´ú„‰<‰¥¦­Oô£v^x Hnìv nI¿²sÞO‡}zï6ÃÄö‹Ïòv‡k5ÙAªB—dM w¸¬Ôo(¼ h†õèä”Þ…­’í h+«ÃàaΙg74(È+^Ðû˜G Þú¶z&EEŠ#Æ~…ÖBš¢m=UîÁè!)è½WyÜ8 ëcðmS7/ÒÊuË?¸@ùºub rßôQëB3îÞúújdZ™V?ÔŠmOË*''Vú•ô_,pÒ,xñSk6î\xgY_@X¿Q€1òmë×Ç=/¶Q[ <†úÓûQ G†øk5&‚“¥Ú×{¹ËÔÙÖ8wÓÕÁõz®À4!¬üdOò<ø Df©<õ¹íØ­JÚÖÍJ_Ηx¿ÍYq"RzZˆ—×Y£Ñýòå¶«£ 3ÉfÃ+Â(¹õ_Ùo^”cKçÊþEúïŸ òE©ÌÈáw_‡°ñ ïwZ7,¸æŸ4neº¨µ’ж)39ÈkhzªV̰ᩣ; jMJL8bxÐau]yÕ^¥cg.8–a‚Z9ࢻãñUý €ÅñÙ©«¿\‡'¨A´Kþåa€'n×xÅMÝ¿Ú,oÙ[Ítõ g?Áä,ã<ܹ„´î9òx:ßÇ,›ÛœÞSØNš9O3?(|+0¾Þ+¶ŒrÅ:¬Ó͵ŠìøîïÞn}÷ßã<¢õ,DC©Ï§š' ËIes‡»°þ¹ú“/yQë\) ŠŽU¿»ýÿ+ú—cülú_+T‡ØŸ=„¿_É'¼¡ ‹ÓÂ$¡kâ«%Œ\R0#exÁ-d×i™ ÈvÃý]y Q¹w{aÑbÐÈÆé¶üì€ã÷ ý×Öu€òÆw¿4¬Am:zó³1BØýßø› Vl1î”±CœÞËÕ¹USÐÝæ<;QŠYb˜Jù«fõµ³$Gú{áÕó"T„ ÃÁ:#¢÷Ü<“7Ä í»å+À‘ç3­Æ½øÎ…ÕwzQ"Ò„q4ŽÊ½µY†ó:çÎU§‡¤é÷†gÞ­„tˆý£nÿätÛ0jÙˆ±ýí¹ †¥ïçïÛ[¾«â&dÐÐÓZÓ:Ó ‘ä(oðxýà3ã ãL z¿«dþgb´CΡ_Kÿ:föz5agä×qß7ODA"åæà´ ç ‚$_ÈvçWßbE …ú† (CÀ9ü:)‚véÊOzŽjÒøj¶„_ÜFX:æ¾ÁÆ ê[ŠDo½ÒS+ýËôßÕ&â(;}vv¤XÙnÊ*_³`R§°<»ÆwúlI] Ç+šÆ<å'>Í\ÂÖ©ýÎû³ ¦!DÕ3§·„c Yû‚3'ÿ¨€yE‹ÎÓƒ‚ÄhëƒÃª†•Qð½b´-û.à¬ÁE‰xçzXL¥áùáe Uˆ Ãç“?ªwÍEñ:xM벺Q{ňÉ»wUÎû†“æûÚ~X]Η¸®E‹#ÍêÑó¨>j/yˆÂnËéCMæÙË“>Úšbýó¶;ăýd“á°ôËðt¿áïnÿ^ÿ_6ýoobøÏÂß­(ux)N¿qCFäöò÷Ò?ÁЛ@ýú:ÞúN¿ ÔRw’¦IùÃëÉ`pÓxl>JÊ4¡)h¿”ÁѨ™¦K,ÎùTÊɲÉ07ÀSé9_k/…´Ü—Ø Ï9÷ 8ü¦Ú¡Ô¹/“gL}›`'|±Á΀¾Qc 4æHÈí Ùëëçu÷Ârg~å÷ç<Î_› DíÅf¿¥fo¡¦„‹˜ 0ÒëHsVÛ„‘“äYTî >çœw“o býW)-¦ó3ÞÎç—~¤»Wm6 ’%¨s/ÜŽ¾[Sé—ä_Sf¹óí>Cv^ᤠqæNÚË]ñ~>°nJð××u« T%äh›ÔÎmÊ>µÅ§ üÌñe¾IÓÄ‘¦sxºLˆŽ±ÂhÌv=´âÄÖ`bJþin=7Ç•Ò^¯yÞ³ÜŽŠ~‹6ù²%y?I•g2ç­µ ‘%º§Ïeð…ˆ)ǪR³¨™9âmàŸÁ ¢ PšÒb[¶LP6á´“}«ÃŒ«t<<^ûÏWxæ}E›äÌXØ@Ê”Ï4Mž<ˆ¨>”'[耪G\‰N’ü’»³5?ÏòÑO ²NØz‘¿qXÐôô‡ Ì†«ì×Óõ~w ö«ó)VÝéc;‘“˜<‹9 ÂÁû™¼PBèl ÉC-ÿ¢Nî_§|†øì0qüaú_ÁÇÀÜ¢‡˜0[\$ªnºÁ ÷eçÎX‡'÷s^¥Ü+-q;­˜ëYçØpҵʷ÷þ]†LJŽs´4:oE&»›ïýËo:ÝmjÒ½ŠE|‡Ó®}–¸¦U}G6u©V‡ö_§ÿëG áÒʤ#ÄQΓŒ„*/Ç»Zœï«D3Ÿq$ó¶p*o ²”ué_ûæ]®qzÝ®{³×œX9¥"•ŽÍ?Ë7²xÇœ·@®›~Fw›¿Û èýœdvGë Ez€ÂM­áí¨÷λ .³.¹A ÝZ‘v.òÖÝ›XdSøéÑgC_Ï®½wªû° ã Î¼Ï'ßÁÕúýü4Ê@Ç©ô&«–ì‰ßÛá†&XøxoOìaúzdªQâó¬@ j“ùyU;¯ÙžÒ¹…-·ˆd“o¥7)Ob¾ÖÍh ¼ëÿÒâ\¯h I ”RfÞ¯<‘Çý»ÛÿŸÖÌ/–3w ñûÙCø[$‰gÞ+Ìrí$dCx^$Ö>°äuh%ÜÐç¼æa^ß²÷º)·u{+f‹ûÕvyp¨ò¡ Ì–˜¡1-ùælEÎÔ×TwÌœ^D?Ï™¿³³ ±MóJN¨<åòáD<åĹvÓå9†+F4Ížë›R`^æcþ‚­c sFÎ ¯í Ò×=ì^°gKî /¢QoB·×ýF€¦çYïé)öoИC·H¡Ïƒ_]¶ù_€Ô«¹Öä¥ýþiXð­tëÿÉtÍV€˜¤x9˜µí“d§å­ uŸÖ¿,¿T(Ã=–\:7%QEN5‚VUløF’k,p]Uýšò%/XšsôËf½DI‘Ã͹`¿OeÔûyëŠ×Wö͸yÖÛ]±^qžÐg“”£Ûýs:–éoèä·y´ó’=Y;E¦Î;åˆäÆo'€án±ëÝ^"6¼g¨¯_o1¼tƒP+é8¯ÉüÊ\…ÀMš³€ª¸üêË`»:Ñ@°TÙ—_I.ÙþK.×燥 ùÕÂ0øâ›Ã9( >¥RfÍ[»xÀÒò83pãî…ÇÁavºuObéT:Ù†£ª EtpÉ*R|ˆ/òëB#?>Fʘsh*.ûØT˰þ=Éùßšü7©Ž/¸4¸f{î…£¤÷¤3'øOO‹ê^Œ±:½&¯Wð„œS•/Aäe,œ k—JÉïŸFíÙ¦ H·×§³`¸©ƒˆõ sVùåpÞu÷J2À{ø&PŠ®"‘?$/\<<˜XåŒC…gß’úÀ;C+üÄwbno/ÔÍ[Øé8ŒF\©7X‘w"Šb­“ eì`iÐ:ØV)2@Óð¶?œr1 Cžfr?q™ÿü.Ã1RF HïQHÙï‘]éÁƒ}Š‘’§ºh*¡ºî¹ïVÃ.?Õ\<—æßÞèYá¹dåÚœ9n^³ª7¹(ßßh½ª‚Ùbý¤ø9²W?uîþמ4çc;›ÌAmú‹§¨`æÕyü1rǪÖX ®]•lñ|ù°˜/ÿ•óNÇü½èpùÅÁ⡇Ûì!{( ¿ þO3T-§´'—lЧ\œŸ’Èî ð?MóW]@~¿z¿¨R ,YÖq/\´à6l Q!&T/¼àIêÈ)ˆX¸x‘ã%kð¸«Ó¨ëº]1‹• °©Èªª Ù *¶$ .7ž¿;wÖ…»o2@gkÈ=r Y'oÆSÓ f’3é©þÇDÂ¥*[\Ô$§DºŒ}[ßB‹ÐÍ9¿ÿ`Ë6`îx…¶ž(Þ«î¾4`©¯y~AåàŽÐ“ñÅ’5—ÙQ 6¢Ï¥¾ô ho»‡\ËÄÒG¼8²td~u”G¦^è$†q„ •`Û"r/\ÞC‡Án­KYPñ¢Þ#îΣÜ­5.^wØ¡ÔÓÌDÙ]sσCóê÷oÏaòÙh›'(ˆs©Þ}²Z™ž) xW6Š»7Îù› àyä ­F°1aßê´o¢²Y°?>ž?²ž^yvÆÍëVzà.çÛ2v>ÅmÒk»Ù¨Ë™£ Bk7Àš,ç]¯£=ç÷G8G¬‘¦\ÌXÔÍ×üüè Íé;î{^sY'gúcXx±r;¬Ø$:Ìá¼;òË.àr»ªB*U¢S ÍQú%õoa³ýº.ƒÓ¿#ÞFåb(´i‡(í ,îÌ¡e$ ÒhÄÇ4D¦ÿ7 =R%k@jM]˜® s‚O^>˜y¹Ãcº½Íà¾,Ã/ä¥_ÛàØ]Q1=-[vó¢òïBx²rHz†TAP~Þbð¹€ê¡ËlįÚX“½HÝ¿¯½ +ï†Î_¬ÿœÇ+Ä‚ù;Œ: d_wÞ|½ž#Y냟îXœqþ{ý-dkÔÍëhK$Œ®–h^É®Øü³òúÖ±?˸ܪrI«Nh ß—Ãòü÷#Ú0áq¢™|£ÛØÏ•Ÿ !ÉE`rɾªl©„±Yô`¾ö%õl€–Œ³MÖ|þ}ðpM_Âû rçZ¨~1¥5~ h•O¶ªp~{V™À 3ŸÆúƒô§õQÒ¹ ÃÎ.ÇÈQp¹£û ÛŽ¥X_KéZ&—4µ Ë›*`äNëš½Ìó}ηœù·"@ÝüÂ"Äwn¯èÓÐ%WÊ ¿»ýÿ ý+þdüù·ùÙCø»”£ 5«}Ÿ97LIT½ÍKƒ”Ê}–œåöV€FIWB•Hïæ†@ð=ò¡ˆ™%WÁçÀ ZAÇÝ}Žàuù‹\Ö˜ÛÛ((3÷_ñà¢nÙ í HÛôã™86ÌsdzgЩ†<Ú×òÜnFcd´F:ñÝìjgØiðö•dd°Ý]pnÏ1t“Ùg+ 1 ºÓÛÓUÑWík;~e£`1‡¹WÊ‹9 ·è9OÅÜoøuë;.-Rý›óWø§!é<0õ„¨Å4e“™1O’¦À3 F•tß’øç’íS^®"ƒûŠ Ê||Ø–Û;kÿ›ƒk}+¯ç¸[}·ª)8 €—ÝÀ \׸‚W#U4ˆð.¤;=¤‘'üйi×GäÉs¤x:röÙMiiþX·¬£eåMŸí=Ë_ÈÙp|2”}·8mÅã6¶¡×gUw˜s£YJá°«þ†èqnn€yÄŽ¸ÏüwßÙx[Zèúå²÷­àCW&X*§_B$®—©GÚs«®€˜{+£){­²ÜÝBsÝ ­ð4©–{i²|zz‘oëKI'¾„òâÀSQÜVqÞ¾L5È(öæšLȈ]G~Wô²ÇÜïá†dBÌÜž!vP¿òLtƒU/,­½%ŸØ1Zmê¥;d¶Ì^‰þ¢ú×qϺ¯0l¨ì‰Fõ®³íÅD}ÒOÙìõîËé‘àµj µç\ÙJûíe7rÍ¿][%e²â€XQ æ{•çi€S*Á&ÒãæÞ OÒíÕ;cïMMN›½%Á:fÎ;AIþï_õ\oŽ(6’r/¿¥fþeÅÍí~ÚWn¯8ëö‚–o­Ë4ѯˣöÇyµþsk;›{w鬦XWhKWö?¹½¢Å<‡ÞäæW{æ~ˆŸ nŸg‹v•¥ÏŠS¨”ÛÈ8lùð¹¬Ë÷ç™AÛoÛÜ:ÀEÙ^íÇ>7·DƒO’sïçãS“± è´o´¤œä*ð:i]dkbUlDŽÀ¡—n7·#Zôl%ŠÜ^pÎsÿgÞl¾ÆÏtZ¸Ót7Àz¡–úScÎãÀXðlÂu¯ÛÒqÎ}GnÈnür=9å—™þFÚ·ðÁƒÞ½àtëé\£›æµ+4¼Æ’©ß.zé%ØPe÷µ-™ PÞ°þÒ°e±‘÷“2aõ p¸-™Â ÜiÒ÷»Ûÿÿ\ÿ¿^þŸY"~?kø·– E,$&ªïÕ¹ÌV;@Ó,ÙcÇ5ÌrFönò\ûõ€¢<±ùS@Vûp|èòa ó €uAøW<xKZôÍâ~•?À&놇›VŠa뜨ʨt=š»% ¬<"±0¥xS˜ÍÚ+šXœ\{NqÏã2,Šçì¿Þ¸˜’ìA¡ðz\¿ ý//O5 +®à”[¶{>)+ƒýÍ_(J‘½6ûœ @§]g9F7Õ÷ª˜ç=Åö\oLÝ‚W/xM÷V×kØg~ñŒÙ¶Wàÿî[üæ4Ï»¡Ÿo¬L‚êœöžNê¦èRpÿøÙú 8/Xf °òfbB…CûM³š„(jÛÖWÊÃÝe>æ×Ýiðe%És·Ë#LF ¦¤Ãº´Í"GÂ8BÛvK°àÆ®ؤä; ôË=|€8â4`εë`/Pt³Ú©ÿì Ð7}kà¦Û“]s%µ¯#1i£WMâñtíåáœç7Që×ï§¶£Rvõ6+žð³ÓÀutW~KAw@ø2é'˜cyW¹úÞB.°²Ñ9úxs®eW=Ýøµû¶Ë2ö°ç»EK©ôm >;>€Í»“ç%'©ºj¹–¤Á«§àQìô¡Ñû-M¹ü¦º¯ÂîgD€oBhÔú-PÁ„¤ý à2Ç ?BNxàvðî³q~"nÔ£ú¥òû¸\ûjÍŽ‚Ò;ž[îúüÁSP‡g}Ð=ÏßÄ"j|}ì–W¥€«Ú¾apR™¡ ÊIذí=¤Þ86ŸÖ;käãØÖKŽûŒß„îÚÀ¦Í=‚yHÇ(N™Pž[ðäñÌÀ/‡æ=°Š½ªŽ K½¼ýpˆÃñ我XH¶%>mð¨¾ÑP±‘È@Ý+†¦¸š®XËgï ©[™^¾ ^‹ÉfiÊL¿Þ‹R"Aþvá6™† ŸfÒœ[×4®µ•~l“,vIOh†Ä}ŒÝ`útUÿ6 Þ—ôÔûuõß54ÀIz%\¹=(-SÅ2ÜO>XÊö”“^$pÁܘ{Ð=¶>XõÑ‚'t¾-—¢%#»Éñ‡Ù–æÂçï¯vÒ‰BG49@oGy l].L³«|UëÖß8B`­-¬ÅóJÀêT–&˜œákÒÐ*à­œÇ_z߬e” Ö ~–ø úOU¡iаû¸':ú ³=Ÿ^´«ø–DŒK}©¥õ2çÐ1:”íð$:nÏ}$Ñ þ/ïŸh7sá5–Ò—âcûGT®ñ§c&#,àC_þ~q €Á7EÇ2ëýÁ± ÇšÿhŸa@X†ZÅfÍWj€”´Øö†Ç‘œf8 éo:°¶xWr>_d¨{î¾!Ølk ÚK]Úî `ÄÓßå#mú¹'º‹ÙŸÈ1Àª¾ŽëU[‘ZRÍ1´ ¹0^Ñ@ΗV<´õÚP±8y–Jƒü šÝ›9dzMKTïM ¯ÐÅ/°V³rÐqÆÛ‹MVΖϜà퇤ßÝþÿgúÏþÙôo+$·¨Ÿ=„¿A1‹ƒ9b¡_oÉh$Iœs]k F‹LoŠ—VÿM²GÝô,Ò€‡º„¹ml„Í‹+ó`Ê4*ìüd_ >© {Ål°¥BÚúD¾¥K±ÐÞÒ°Œ+àëÔ^ ¼õúf‡/c‘ÊWŸžœçã‘„°çšÞ7ŸUU<øÐß+±„jªÜã(NâÏÈ1 ¿sjŸì–ktlp; ÕŠñþ‹—¿Ë à³Ñ«:¸.ù¥Ú7ý X ëØ®Í Öm0“úüF ÌVK©c6•i±ZÑÒ°Š< c3ÞGÆZt›aEêÆ ~#.1‚áƒ}Ø,[·`èæõüúù;{Ü.û%Îhm8oâ´ÍMÄë¡Ä(›–;{=k½»ºÞ«~¨Dì@Ø^WñòÎWÉ¡ÞËgS7i渴S}]2Ów—óRè³^–Ë$õqð^»bæxøî‹eeuÉa77Àü'üâ\‚D.«tñ… Ðû:Xä3ºïuåöѧ÷¼_gær]ØÈnyè“>„¬>g ­f6 œÄGµ ¬>{õ¼• 8ì“àù<Í4Y뤺:aè$eÆqd¨Ü%ËÓõtÒ/%Y|¸}V÷v‹tÕ–#$_ Ñ9 RÂciáP§h32ÃæÓJh^uqÑÕAŽ²é…žÖèªö_Yÿ¾†Á·Ï­†ÚÑ¢Š™JŸm<o)üñÜü c=AÑwEù#µß[¯>²ì³V Ô§‰öƒüˆ²h‡|É”ÜQÞSÑÕ!1·²§_ÜŽ¤±9?¯;³ù=N¾£pWÏÝO×ú(øª=Ú>¯H~FNK׬“Ýly:k¸KjóB>Çìj¢ìÏÐÿ-nÙ‘Gp½--æ,|1Ùäë6ÝEøÅ×—™óß¿/{@t5Þ3 ï­ïÊž4k»°%_”’ñjg*´÷·› ^ˆ½ˆZ[êNò¸•ͳÍ<ŸÔ@FÆf`ç‹}öœŽåîïNé=š‡¹ûœÒËov·„wqǪ)¶#>lèÄžòØpP=lFùÁc#Ao@Ùë «Å×÷b+¡¿`^“¿™˜ÞhÌÒ²ßkï‹5ç{|;ðþÅO5”.(±ª:œv`Ç—¹-áoz:Ö%Êefpuµ:K:A;Àÿ¸ÔŠðd»ßÝþÿGúŸýSÑçß[ÜA?{ÿß—"aþž*}^S_½(À¦üEŽµî‡ørÛB×ɼE½,· «Ídçg 4cbŠŒ–¥HÙ˜©h{iØ#"«ƒƒ–h`Ë׊mìÌ–Ø‘… ðÎsHÑMÛ믹‘GGôxw—•ß)ãð€yä¼íŒ)/Ü4ÀaLÃØ”Þ&â ³ÂÇ^½ðÕª²ÄÜvn ™7tAé9ˆ>_Ć÷ßz0w?Çvº’ï]ŒnГVq°ë›{áŠ_.J´Ý1Ѩ×qI¥¶¦&/x×É.púa»€J$4È(´•GîjÆSDÞ’J¹;+Áãhd/, omvû°8Ü⪴Ý*ŸCp½ùF6 jÊáÞ99Áµ@.•F¸‘úþ2d{›êäI(¯¶ƒ¸sò6 DÂæl‰FáºA+þ9¢G.ÝÈð®£.IEN][ðâZ/¨V 4å“¥× ÁI›L£Ëûž’S$Múc—1ìSgõƒO”]0ÐnWôè‹Jòl[&ÔìLj0·DõÍÜOú/;ºA«Q#ôí ŠÓá»@“¿½ªìÛÚh¿¶‡µðD5é_¬²~;ªOæÛh ÚûIB [¸MânÙÖ +ëP’si¢ë?¸0u›âËÈhèüj‘¢ùiSÅûš_[ÿÇv×]åª9~Œ>ñò~™S)¶«]æ+ýúHîž°¢ëë¸i¸SaÿÆ”à}c0%Òù#ˆÙc˜…FÒ`kyX™ÞuG=ÈÙì/Á9ÆÂ&oóƒõ¡³ÒðNœ‡¹ïRƒ79jù .Î ð1–v?M-#ú7í¤•Ü•»&M©ŸwOµØSOÌÛNu•„¦©i¦Þj\ £™2¼ræÁ¥…îž÷CÅCËç¼Î‹¬­Õ…w={ë׫kV³[.Æúoû(ÿàìÙÈ‹/5ôu¦™_°‹óÓýýv°oP$cO̳|«Þlðög„оµ§=zWáúdˆä݇1Ë^Ÿ€Ø$=ÖY4|Z"–!|ÿž³úý°àô’ÅÞ׎‹aßçêN€~ÌÃx= µî™•Œ1&£WðY¶öˆ‘·1hê[p¦H@é…æìj2À¹€ª*xDbANÉÄGÍç½:ÛHŒöbÙi38™±NÅzh/‚ŽÖŒ/«n& ­ ÷€7פ‘{«îKé×-RÓäâA†OÆy3GŒüú‡›ª`ºÙ;g³7Ç(œ¿{-`¾ùмQ…Ëùê~uýß´2Ô<–®¿èàX¸ríÆ^­wc C“<Ÿ*`yÍIJÝŽÑùtªDu*ßÊĬFš7—ž~9ú<ì^ÉÅ×ñ• H6(¹û¼—=–K;êEŒßo…^ëÈ„Ý(ŠÜ0o%>0+ÐßD;j‡“8(ô“ô¯£w9fÁÍh{ùa0t¹ë€ŠÝ«™1,qNËs¥øQ}‰Ïâ}{Wú²ê~üè…ׯ?Ó`5ÒHzy†‹»¤êHàqÿÌ“‡èË‹;…4_Ãð×PØ7Ÿ,®UBÊnOÀµ~'…WGÊ’%ùÈÇ[×}Á¥W}m”Òë©p¸ý…rD­ 09IäEЛÜתw¦úè¾pÈ\«S˜þ« …ó‘“«‹·„oÈnŒìq؃õïL³ŽA®DÛž8—ž Ö{BïÃëL–}Åú·«ó•àºÑ“°ÞvÕðú·#óæ¦ëp¸õ»Ûÿ¯ÿŸ @ÿÞòŸcÿM±ÁŒz‡qkÑ\¨hèÂÜÞÕŒpûv{ü!Ÿ—ñåðG›7 Y˜~w|æ JÒ¹ÿÍ hvcÜY£Eu{é°HÿV-ÀT·=ÃO\‡y½,ë)fáo woï^ó Ý•k¶ZOšBìiÛç?›áج-)²6¿€¡Â¹íq{4Ъ÷&Ž<³¼N…ýݾ„¬dîs¡WVlº’¿Îª©P#¥XZw,‹Ó§ï´ÞËRzo¥úzál7×–Cä‘ü~NÝpã÷'ë…š‡y…»+4bšjcÒÇØŠžm,à½&¡n]  Ä3EB°ÀoÌŽ©ðÈB¥mØß÷q@•®ü ØbûýP*¥Up”}Ä]g-˜6Ž>dámnÒ­oô[ä /ÞË-3{‡?ŒŒ¸1,ë‚T!mKý¹ØÆè¸›M>Sr.麘’âSa—…§NI[Ž-WPû@k½4†ì.D$¾äVìB ôrÏY¨õËëÿé,Óòï­G%ݬ7¾C|Ahó² lÖ×K|Z¬®¼ìI^éßX|èš…6ÈH4ÞA¡Ù·ì˜šoýè®c]z ¼ä„õ¯árŽ|{ÉÓ¨¬T¼õ¸ÖüÓÄÊ*ûÏ4{´fåH×̱);•¾¦³™Ä}”GtX³çLái]«f¾¥wpi8ñä§éÿ0!ÃPhekçJíC" Ú×´Ø\TMxÞ™/^ÏkÎ0_nrÚˆ©6†f#3|º¯iÁF¥z©ÜÌP¼bw=صàeÿÅ ñ÷/bW2é§uqÑÀ N%!EÁK ÀÆ„¨)i$n€´ s­²…§‰§.ü¤å.Ó&QE¥! ¬bj^•5¯,'Ž~ê\Ö€ÿAæÇsƒ{NV™j“·•ö  )T—àP€&N–w‚ÀkWDÍ”Pþí I ÌE ¦Tî¸RÿÈvéÜOcÔi±Ågd÷…ÛZu|@ ØNŸ¶?̲íÓ48ålû»Ûÿ¯ÿ_»üçÿ üÿ,ß’x¤W b–ìxÄ3ê{©ª6Q·(g 7—èTšøèúWè{VóÄ2j—R¡êw{QÀ™Yn†1Ù¤ºÞº¨œ10™c¿, ÉÜz –ìÜŠÈwæå6¸ö âø#» &Hï‰Sö‹Eì¹7óœ@º¾%‰Kê 嘱·—ÖÏF(¾+oƒ½åPòWE z¸6œâB°þßD‰- ¿ Ý«)Á³úÝIä<],Èž-Ÿ©Ì.ý–Ú‘C£´ìÓ{€ŒÔÒÃSäÎäÉÝŠ¸Á-Ë©ýSU¥µjÅø' 0kÃÛƒC€d+iˆ¾êÖh R5-­jÁ‘bÔ-ÅiO»Êo½ö¥pÙÌ#yT‰¸&"œì.^°{ñÒ±ÅÑõ›^Ü4›w.yÎÕ“+>5D…:.C©H¦ 6b4}¤Q” ä4î€wøª^Ä*ý@J˜©ÕU€çFê˜ Î5Vªcƒ›IÞ<«VdÙ,J-¯j‡ rï‹xznç”Ô¼. „Ê™g ÖZøI¹2ÕÁ+¦©ùIÖ5ë69ìRªïEÉ[¦ÚÚë§€­ä ;š^ÿF?ƒL[r2I|z9«¶ëÌ»µMÞǼ½=?´‘ü.Îãêþa, 27 oÛmC7ÈŽä¼ß@ÿ÷…7\‹‹€²’éÓ¢â[‡4š`†DpÙ ŽäWÓ‘ec¶Þ ÞÓü¼sfx5>wkqË’ª›°ø„´«Á¨ÁCuç÷$ )ĬAhúÊ6 ³ËÂ{TÝ9äŠP—,©ŒWС¾Ò+Cl‰_¹ª:…W£;:·dBvJ°2<ï'êß̓ua#ùŒüñ16ir»k3—ë $–v›íólh9¬Jo;t—?ÝJ•ñ‰»ERJ­}¾%+ À½Þ·à„j¤ÆºÒq–ùnŒœß¹·KÉI]õªtµ|ãƒÀ _Aµ‹²)•jKL‡ZcOã®ÑK¦Þèx «³Âšœ9Zì>ŠùD Tm°T׿s‰š'˜×-¹Ã¸€1MèüàÖÞ@.]´í=ÔÜî“Râ0N ¼Y@¦bý£óžJÅè–û[›ÅV»ek›rËdîôÂAÍ©~ðáÿ V=ážY¶ÃµzºÝÂßÞþÿŸú÷ÁLùø÷ò_a?£(Ä%øâ»$T&D#öüXã¢ÅnR©î‘ÌŠTįЉú0þƒŠb¶q(Å›Jÿc³XÌ:B›x›Jï q £ã•T ÓPó}¬¢g8þ÷Ì·ñ—©šç&ê ¬ÑÒ˜ ´I÷æ™=Q¬ÂÃÆÂz̬ÿ½뉹±æd·cx…O¼÷Ï>˜3@¿Ï±=¦}1“- Áæ‚5AÇž @Cð:T:BE˜ÂøèˆK$6:Õ9̨ ¥Ð©(6| ŠýGÀ"d_ðÂÞ¢!$_”Šw€":JFUF©˜pPðöÃÞ 1¥¡ã½à##3À+˜BCÉ *`ÍH!ØÛ»ý_ Àç‹] {•ŽÉP) tâ&tL6˜Äh@2¦ì ŒI—#…Ž·¯L–þÞ5Vë…ŒµÜ¡É#»‰ÉüƒBÿþUÄÞaj —9…iÚö˜Æ_¡ÿðl–î€àûc=â£tB7Ø=¯ Öü7ŒÝT8žÀ`M_4\Z˜“Þ>!—2v“BeN>ÁñŠØ™q‘³"~ƒŠk‚LÃÉÔ?1œŽ²še*“Š=Gqåa•™]3pi1¯°Î¨.a \%•ŠP€ëCV\xÌÇxÿ>ž¡~èøÛ˜6©ÈžßÝþÿUý3~ ø‡ÿDÿbÁðÿt0uM÷Åã«}üj›#˜Kjü0§?Vü~5qæ‚ù.ÜC܃üÑïu&™Ê@øÞ"Ë£€6©1ÌV& ‰YŠ iÉèÄMÂ> “údžñÇßCØ9Å1ÊÛß&ùŒI¾`Ü€'Œå‡W Pƒ(®‘€þ¡Æ„±Oª?fCÔΈcZ)ŽÅ˜×Ã\#•NÆÀ¥0ÝÊr¢¸ó Á½1.ÑX+T£@b`¯`öŽ»@:î–Á3”YŸ‡/ ç1ý4s"¨t æDŽaó½˜ÓÁ}2Vk ÷3T„Ê@1?ÃtØ#ãWÒÿ_&|‘é´ƒ!GrÎ<@`â<ŠÉŸ¥ì9mâY±Ž)æ!x½IÆÀŽAÁ%ˆ9m*°ôÿã!S¶Ì¸ÂªøÀûÅ,à‚Æ_£ÿ즘À! e¢ß÷˜Œµ(™¦°`w|{øÓiþŸ ÁŒ öGi c#c2àSÄeOÓ?~G²ñŠXkÌŠ8Øc0…âÍ0åOcÅY@ôÆô?.”5A Ȱñ)c_´ïA+|šqŒÂúbÎ’ä‹­lù.–±J¸þqµâk8ÍßÝþÿ5ýÿ2øÿŸà_*Êpâ˜ú_9ß÷È÷;CÃM»reL’ôdú÷_\õ8r Nžñ¾èï>¹òž À5aiúé?Ï—‰N›¼8YX0þlãX‹’UVhÀÉHÌùñ 0…uŒÏ…Åù¼rõeñn&ÄOTÄù,õ²8wÅÅŠëßÅkc÷˜,¯3.[V 1Ñ"ŽNLœ'z‡ãMàsdEôñ12…¸ÒC˜ÉlX¸ô˜u9ô»Ûÿ¿¢¿_4ÿüù¢ giÿ@à~dp']2éìcPt’uMTüýûáÓ1fäM!£Oöî“êL ôóàåë7©Ù ƒcý¤:ü˜C0p…SáÿðÊòãý³zrŒÀ¨Ì7_«%æ÷äüõGþ“¢Ÿåû ¿ÿënØž ÜÂ1hÁ“¦,`Á] 3 ˆ»3<ùÉLú¢ˆ]N(x¶Ð“áâä‹BgR22Êô˜¿¤x… d™Åâ17€s57t0t(ˆÕ.Å\Ö,3Gˆy„Éа{˜?%3ðÜ7Ö ŠgXQ’Ú¯¥ÿ³áÀ"ð8gÎšŠ‡d&«dQxœbáYUÇp,î!»àÿ™ìó;ݧS'RÿTä{r€™Õf:mŠ^62³Yü ÃX@†L\‘ÑqLÃə羿Lÿ—qd²ÿá÷¿GeãX€à{"“Ö-Y òYxÅÓÓØ°¨ a%ê™hÌdè(>z<¦´‹aæ¦ñŠx-*+9€‹_!€§_§[˜úÇå?Áâ±Ç4æò 2é>.œEÀzûúá;N4”°¶&6j0ýûãý“a<ÿÏl–ªïô»ÛÿŸ×À/™ÿ‰þlQNŒ˜`ZÿŒóýcN˜yIòŒø/'ÑDt<⦎§p Aþ`N‚˜‰¶&ô5iø;!Ž‘ôÉøÀªÈüMv ˜<ä ‹Ç·/ø‡»“òx´dÖÀ¨N¸ AHàdëþã{“SßâN'…OÌúŸ˜=üáUì7io^0Õ6ŽÎ‚fÔŽ™Ž0Y$s»ÏíaÖ3€Ætq8C%;Gâ5Ðñ$ Àt¼"bÇÜ÷›Hý±v1J…ѵÉ(i ¼6ÊÌ`”ƒÊÀ|î]p÷íÂ$§øÎ÷~=ý_öÇkÖ1Ì;b.o‹˜ô¬|=SÿX À"씌IàiTª Ì@azXÜ_cÁõÏÌã¢ã›@›üC&eüUæ¾/Qã¯Ób2ë¨Â÷õ “9 öíò›ð µ˜þ™›÷ÖO0}–´¨¬d>ák‰™kg"~¤šÙ+B¥2·Lhã¯0‘›ÊÌúã䜆2øx2õOûÁâYmá3fãé|ãYü€c$ƒ© fB›œ@ 9aúÇúÇ·$ÐïÉÖ1€ßÛþÿ´þ¿`þ'øseš¿GþKòwb¹:éR¿§•𦰪~'‡¯üØ/þNÎnØr&ú„MöîÿÍ60óe|§•ö‡Šãyc²]”ÿx÷ÿ`ÝÞ:—èÈ­ùû@'çÿ(Î ր܂ÿ—üß´Þ89`~x£^´€ïÂøãFà‹˜˜ N‰Ô“RPÄ›†ŸØ¡OÄüLHžÈ3í‘F¥‚p_Œ½‹³Šk8ž(d%ñ¤=ÊLR(þTŠ/ž,ÅHþxâ Vƒ°7'µ‰¦cm`NƒÌÀ4Î{qÿ ÅX„W0ŽŠxÊ»AôÕùõôÅ—ÂÚgÅÛaH¦Ëÿ‡ü¿kw›(ŠëŸÉxqtwŸã©æy¦¢X;ýÌ–þñÜ8ÊŠ$Xii¦Ž˜+OöâšÂ ,¨*¥þ1l;îññ´üxö]P^A •)Öé˜þ}™ñ¾Hp¦†…ÜÌ]#&cÄÀŠÊÜVÁW•†éÅ,2QÿÂ+²Î 'rû(~€à‰Qy‚OÂÜÂÃ0<ÿ‚ׯÖè8Ýßz@ƳÌ}~²käx³Ôñóx X \ÿxÿxŽçÔ‡ià½÷w·ÿ?©ß?ÿ¿—ÿD¦ØDÐñŒ.íœïG&øŸÝd+uÀ3ºÿ¬"k—x9£zQCpã<£Ç,ßkO`ÊøøãÖÕûÅã]ð|âdTøÆœøƒJ"“â÷üÞƒs¨ßxÌùÿ1æÿÃ{?œóâ€gY›}íÿlÌ—íŽÒ1ÜððóÃÏ…QèÂ`fž™ gf󶱬}> gçÄDæqvf oÛ6a|w±¸ëÀ\3çqñ8\¡#Ì6“ý³Žþã  m á1Þ…3°ýõŸ–Èò|?’ÐÌãTô{þ‡ç”uXbMÃQÙ/ åY±ÀxÂàGr€ùáC Fû0,bàbet™´•ùøûP©¬äØþKõŸéÿ;ûû.Ö‰ÕsÉI›)®,ýÓYpÍâüÔïL'§ã€„gæY‡™»‘ã§"XYgðã¦ãWø‘ufÊžŠ`úgfù=~L?©6kÁÿ,€uT€Â<´Á̹03 ÄPôŸÀôO£ÿÄÓX¬CÌ0q0øÝíÿOéÿ×Ãÿÿ¦x0€¼Cxà Î7‰—ÁøŠžt“ê2÷„DÁ“LlÂ6°D׋£:FÑ&{÷šú?í]ùoÇþóÜÔ6’ÂEˆÑ-äC’yJärw®]^")Qeh€Maƒ¤±[8ÿ]ç]3³+ÃR~±J›˜â1r÷qÞñ½ï½ 0¯iнt6NÒGëÃC¯µ´”øÈh6ê®1ß-›øŸNþU62svkzw_N+œ?~~Þ_„¹¿±‰H@@>z7À¿PÚk®Ý“ WaJÏPLH½âXqPÚÊŒA3oH 8¤þ‚2¿_ò™žúYpÆ‚üܬ De²»úõ9d÷‰äR …þ«î¼"n11µ¶Rþ?,MAE þá&V õQü+Fô…nFŒ½$Ü7\ Âk¹ÎûKH×¶6ŽòÀØ!mĪ©à þÙÑýO,ÿœGÔåù•–(`¤šb‚ýÃ¥Äüð³@ëI #¢>pÑçàåOh=€ZÊUà À ð²ÖjŠá¾.öÏJ±î¸Êi@œ†´?,&Pê`6‰±.Ã?ôò¯4‚-Á+ p€.uçÆ¯ÿ_ ÿ-´ÿ·À/8%ýú% ºˆôš/«`26Ø_áßJ~|Åî ã˜dEú—‘ÏÒ>8K¾ðÿÁh…).)ÿ®‡>¹oÌO•øúéSü¯½'úaà¦ÝýT‡¨PŒ–Ïÿ7¬Ö—XÀøyâÿ÷Þœó&Ûáð >?,N¬³b¶8Ø"Ý;6Äç§ŸžNð¡Bò0€€@[· ø9å’ åbóÏþþ \@¼ 0‚° ÐÆ1ªpÌ'‚ÜãpKå ˆ ‰e¼Ö%ÖN"ô¼ãåþ;c@þZc5¹ iÛGåéD ùðSHþì/%7ä—Ž€‹ü7ŸZþû&þ‚d¨ÅCAT{zÙ–x÷«™ðÒ’2@„M0Š7± Á¿ÑØA)$ìÀp„n :äO9Äï¾pb!¬²ÜD ¸>Žp/ÿ2 „+ òÏŽ+#¥šÒƒ@¾„Öê³›¾þ¯.ÿ­´ÿ·À•!¡U~e´›=ZLPâ³qU$œ¯ÞdÚÈ¡]l&“ªeñ&Ïd´r‰ÏQ7ùÙJد‰Z¾XwÝ2.R~g\Ýþ=ýßóßÈã•ykø_k1•)ð‰ÖªLÜýô} ¬‡ßgi½qLC×ýÿ:xoñI÷Þdù°>$œC¸ Ù=ЇyE%y‡‚©úë-Ò¨õꕟ Xç^)Çý)Ljìõ£Y!ø¦ÒýÓf%ÌãíP†1¶óAìºKC9EPÙÖÊÿg¸žL £Ýb  àÿ­£ãÿ^4>¬o­ümÁá¾)l,7Ïê§êFûgf÷uo<ƒ©™P™ÔýañáˆSúîì“Ëÿû¹¨¯ŽM`üÑ[†‹éŸÂ:ˆùÛ«*ùµÆú‡XH4€pEÁÖö¦3h¸GpKPT# G”¿eæÀË? Ât¶¤w€€uLWµw¬Å€ñòåLС,iÿ‹›¾þ¯*ÿ-µÿ·ÀQ àÔî9:†µHHsñI ΞlÊÚsúB ˜u±V+êçμ £©âð+m¤¹ëŒøÔj¾¨~ÁÇßÕìüÙ öþok9©‡jwÓ€:͆/‡óèö‘dõ£åÅÜ_Ò¯Ž¦xöÇŸ ÓÄJÝ™N‰ð‹ìŸ‚0bñâMVÌÐñg‰öZq¤gB¸†xÞÝSœ•Ÿß+ hðc0.ð3fûÿ7†´“Pnˆ@t°@6;–æÛ+ÿ×熹þ¡ÿ ø¿1Ï–cILP<Ý@¦À¢³¸ÉúØ–̼¿êíùTÒþ;/“RnÉ ièlÃ=ûÃ5ÈÿmA`ù “- <¬£Ç˜¿Ø=wÜú‡˜~Ø9)–*‰âÔ÷[ódSáÀÁ¢ X•·EœgÝÙÜ¥azgîœCw’ÇÄp_:˜·¢D2.¨Éq3v .ñŒ ŸÔB-  TnçáM_ÿW“ÿ¶Úÿ[àjÇoydÙ2]—”áËEûy:0¼*W_ »ëq\|¸Îž¼¨„î5»Á Xu G½Ø=žï<B}¦¸gÌ÷G ü/XtòÕô  %n- ˜è ùbþo¿šŠnPÚŸ£ùWBæó~ñvfÐ,€b+ne !5ª=U¡BP{¢ûØ4íÙ “†A{ÕÑ›—TNM>?e ÷½ðº+ugú´!`ʼÂpÃ&¹C@TÛ,ÿŸæº†ÿû+Q…PÞË_}ë]÷ù2Pù ¶ú'\äOÙ}ºùóW¡ ÿPØÅ1f‰\z=¸ò/ßÛEz_à–llù‡¯ÍpŒ$ý+C/)¬ü'cŽô5Jä–{¡woò§¹ôâqñY÷´ÒLÏ·Äy{ôª¬± Œ¦Ò!k Š õýV©Þ‚jžñŽÊñ4™1Ò‚™ñÏnúú¿’ü'—Zˆ_ïqë\~d‰_ìïõÇc¹h1‹üësÅ{Ã|& k—%›‹Pô]´Ïj£Åº|¸,>Î9³xÔÓ³I|51édÊeŸóÎ%8ž ¤Ú:šÆSýÐOBÈÃW{¬³â(DΟÿ‘­½|ñFÝ}}NxÈ”jŸ).G>'XB޽08š"0ßÛ`ÓPð ×‡˜ ….©p2’´Tí/ûp¡‡÷þuŠe€Ð* ,µðøx#ô4=Únù¿7XiNø¿XYqï^ÕšÍcÄŽÒÇ“ ¤Rë2Hß;nñgòYÙ»BL<ÌçÒnB'ù—;×#ÿ>O@àÄ<9·"`'y~ àûÕXÊ©Ç!·çáž~ØŒFs Lýü( ”AÄÀüKÏ,K®Ýwœ#Ðþü­lÿ„õ/› /ï.àå/4€\ížMˆ0G3š¾Àý‡Š2»{Ó×ÿ俽ñ?·ÀeLjôn¨aQû§e-Òƒ£YVOÚšÖœÓÀipÈ+'ón6µ£6”ü¡™ÇÑMÖ÷…n°ø7?ºMöì¬JgLÒÀƤf ó¥Y|—”óDÞÿiϧÑä„pSï¯]„þXÄ)ð›5wiÏ'5}Q ÷¾Ú}ë¢P¬Ö=ÔØG½¢~qÊB¸h§#傎?LcEx¥} འk­´õñB4º$’ŸéÍ*e;ÞB•v‘æÈ+?Fù§à‘W¯Û.ÿã7ÅDü_YÂÿAjÿϱhÐðýµeê?„fDýwFÊ ìÔÖ_[AJ±$± µ!6|‡¾ztMòÿa&jŸ¯ SÀ*1ƒãZëÿÊ>µê  ægJ ïéÓhøoô³ù,íTkìå?®j>øÚË_º÷#¬Ï½À?Kº#Ú͘ƒöòçbŽlï¼Â6€Ô|P©Z ªÀ†W7}ý_.ÿ«™‰_ëqë\rþi+ SUëy-žŠ‹„~×æÂ“Z?~é¢gjn5èVµ¸ŒQÝ”nÓ ]LóÀì:£Í°¿vx¹Žÿ’Qøú‘y}šø÷q êx«ÕXâDï¹&‰"ˆ“@øŒàü›~ru÷Ë÷¥¢ñ%§Š÷Ö%føš?И”IÖ7%Ø#$K Jƒ~{ÿ?µÕØ=óÕ`g¡ÆÃ÷¦‚i-,qóМ½¥E°ðoÚvùÿûÔpbÙpw9²ÜÝùÔ õœÜ#ï÷Î`ËŽô):X’îM”¿ÐÜ—(ìP„.‚!(8ÊC¸ ÷´?ÿ´GòÑ?ì{ù+Ù(ÙG µr2Zšüjé\0ž€íàóé£ Mmýµ•òv¦vo>¤¿þËM_ÿ—Ë»[à£G–„[†¯Ö°ºURÓ%iØû‹§€÷Ýuý-<#Á¿Î"ÂR¶ÆêÎ@üýö¦¯ÿËÿÿŠ•7eQxœì½ õ{Ýëó¹O眽öºÖZß³®ïõ½ÖÚîaðÿûâäÿ»»ðç–ýƳï èí\ŽƒOÈþì{2I²Çaz‹ ½2à†ÙÜ`NËb ëªÀcÇ–—xÃ"—ƒà~ÔŠ0=˜ 'ÿÔžÚY°»UÏI¦sJÐѾëVsù€ Nãÿ²I9Ñ@aÙ3!šJßÀøÔÕuH´yä«.´Æòkd¼x…ìo“ãç)vhe¾ˆpöÛp½e±±Oóîuê.7=£Õ7æñ°yë¬.|ÉÈ”==àÑÝ÷Iªg‚§ñK8ßÇaãØéqàtãû¼e1€ºË>”‚;Û.àŒ×¦–D›¸Õ”S  ¢Úá+FÃcý¼¼“ gVºz‹‰»Hov•Ô”á‹m¡d¥YxÐFüÀ¡ûj)/÷Ù°B7\ñVyc6Ø'YÆìnYb›OCè¬} fó_ǃ…˜ jãý¬¨Û«6®ô&2³‹pâ^˜Ò÷w͉“-A%5.jG§‹_6ã³Í¼°0PXn3˜tI´bå¶ÈæJOÏË 1¼?ãÞmŸ}Ã.Í•X~Tÿ¸r+Üj½ §÷;îØ9C ”…¯NbÕçt2tÊ~¹úp¦ö¨1“/;œ?¦ ¡;îè0ãXÿ÷VBt}é¼{ð¡ÐØm`'$é am.Á¹vaùGðãq¨ÒÓŠ71Ñ0°U"­ªÝwœ3flâ­ý{[û`ùè-h¥ˆêKâÅp"àQ߀séó‘ÕÖ³~ðõvÆ®÷»d.ÂËWÇA>">¶Lúv´ÛUXУ T½àwâ/\zaÿýëáÁW%%e˜»`éÚk+aËjÚ]¢'¨LÉØnZI#ÀmÞUÍãÃŒî€ä·ýëŸt< ó¡OßʤàÀª=͸û W¹`·½œ¸…ßtïh­M‹}’»š7¸¾;-¿o/€|Pù™½±« Ø÷á¡eaŸP€mÓ÷ä8ÓÛ;a•ÍW6Ü “RôZ˜ä)*Ë®üÀçe#ûÒ³%#BÀVãâò³Ë6,G‹Öú1íĊaà˘õÙ7Áe»[»¾‡ Û, ë¼æTOCðxÆÂÒ€¡ÁÜÞü‰Â{vÊ•_ÃA0>»ö1F­Ô3Ô×ÿÿˆÿï& ÿF±ÃwþÔbËìêx<ü>9ü)`ßãü_0òtü!»æ ÞÓBÁš”p˜¥ÕuÄÇuN ¸\0ëÓË3»|šÈºÚ}‹2ÌÙÀ¸ä¶ä{K"\Î)hØZjd|€°´`e4÷Åù˜ÞÛ}Ä÷L±g~p̽^?)¸ (9gâ»­s?&ú´,Z}ýúókB;v©z<Ÿ ‰Ã_©Ìó?.fI¿ŸÏKt#èÑ/VæÌ³ï]°òËÜSàxEZXΰÙO‘Å ö¶ëÅ%e,Ñ íŠ¸õøÜ1eƒQÀÚtv=sdư8Пø-`v´§zoHÛîûjV»¯~'éi¸ƒË5ßk]|s'É6ž` &,[´¨P¦àŽóœ–G•ãuµW{Ý<—Ñœ*³0\Zo‚Û[¥öOH„KæUã‰suy7!eÍ»%°ªI+Æ„9|wÍ7Yr§D–-vôÉy¾ES˜c'ITbZ-à­9U0Q¡+gÁòôÎêêÙo•óÖ$.üV">Ýz¥]G7XiZ¦ .i3¥§å%^ï¡s+qCÖiïa0±ÜDc³r“éÐÀ?`_¤›±5øëìL¾«y 0«•ÉÞ-V×|¶›oÁ˜Öâ¶zØ;ê{€‡¢é'82¼Wä.㣽‚Ÿ2ýÝ‚ÂHÅ3çKl[d6È«Moòš¿šʯ`|(ä)6P̓žç¢“a‚«FŒQËå•sl¡Ý0yšyòÆÀàŠßŠÿãôvËÓ×*§fB¼äËi´Xz°Òóéš‚E^Ÿ2«…¸^]ØÁ6æŽ4½£ap8ãÓÔµŸ¶æFƒ“tQ¤"ÀÂmÇ—p6o8 0™¿ØDøäÆ+@£Í|»ýÔƒ‘yp1iúÄÀÁ_{ªÓÆ*—z¶õÑ;|ÑLjmµ±š¥JÄýü ¾Ò'â‹Û¤(+§.ÿ#ѽä#VÈþ#—##cÐúÛ3¿ Oݘ_*Œ›S¦ÏK:!‚ì»ßé<‘L¼®v|æÖž]#ö]4ÿÝŸò»žŒÌþ.ûQ ¼24ôèÈ[ùó •Øl¢1ËÖê|êëÿÀÿwÐ¥0íã~wþÐrXÀN)0ý ìU÷áú»ŸõV—„X\5´³.Ü{ûWÑRöÞdf·s]P:؉¥Ö˜W`Y­lÜúM‡ZœüŒÂö}‘¡Ÿ„hò•[ø°NÙ•ö.h±}s¸÷, ú$€æÃ›ÎX?Õâ`ûÞôÃ=—oQÓ>Éù#û¡úߊ›?oÞÎÑy±Ö¾Í vzž¿€ Ž;L¬LN€C¶Nüâü*h©sGð¾f˜Øè·80¥Ëq£ÉÂ>+ŠÎZàÐl´ì Àõ!p‹FÛÆÌ«R 3u ôÃö,X¦·êËÎß:-ŽÆýÓ ‚»üažæ™„°W£ÓLø·ib ÷¿ƒ÷™}Ñf°fK{x„«E7b¶ÜÚ ®#Ò”„bíJ6­-mf;뾤 WÚçVi9ªcò¸ÇÒN–üÓ*öEîJ‹¹þnõ2ý-Ý­ùyùacEŸÍou·––@4\նñ÷¸8n§(Ο®V3MeÝ~x¢±‡€Ÿæ@ˆï¡½¹þŸ¼•/¿ÞbôŒä¿â/¤¤„fÁ£ú›°`“¿d“.ña=dW˜¯•uªY VŽUÁYÄ䀀1ÿnÎ4Fm_£ÛÐNH4tÉŒœW+oþFî9Œ9  ÷ÈðüÇ·â>dð:©ÿxÓÑü¥ªÂ V´ŽÂÕoÙt£©hò˜Óš|wg=Yd©z´lÚCL»8q/¸Fì¹´FiMND˜lÞ }ìŠ#¼`ª¯ÎˆS8¼ð¡—ÜèÖSÐt79õWØþÍ|댞Ë휂‹¤6Ž^7Z?½cø×Î] ñJ.â÷f½Ž/+ïùÍøO­’ˆÖ¯BàK™²µÍ™‹]Ww^ÄÿÒt;9v‡ðÖyOíüd-ªß 0jú^傊èý°å® Ñf'µ¢ñgž†üpE­óhcn&Nùhü0™5lì3Pâ[‡Éy°ç¬h#æìð`WFiËú¨ÔF€ÛI¶ê Qo‚f2¬ÖKŒÂ±”ùûjá¡5?kœV³.²ÿxeD溈iAöfúÉÌ÷~1ýΦföõŽtËFöäw$ @‹xý¦šaº^g³&‰2úº´‹%>Å¿¾w¾ˆc0öN@:ãñÇÄ] j‰E¿%–ÈÌ¡¾þÿþ¿›€þKÅ“ö»»ðGÛa¢úô·"á@¿zþ¨ÿãÉ7˜4=0¼³Ûÿòè¹oôÄ[æ|Ÿ|µ#OëÎFwGõ±ÕM/’t_a'uMॠøûÞá£ÊÁûجIOn]ZXÇf‰D¶Äóƒ š¸òYTg‡ˆ•þ+g€‰‰÷kE?möö¾R í£ȾGèìC—ŸT³éM÷¥ìèÂ&Uÿž‡ù|íߥýœ7ÂûéÏ%罜' Âúf^Pö¼¥û¢y>²_·Y6%·ë[{iZHâŠã#€Þ~௧ ‚ÏâÏ‘cZx$Ýô@åBÏöÄÄ‹SÎwW‚΃ËýA{YU>0~(,(Âjž=jÖU~ù%>Øÿrèw¯Ž|?Ô64þÓâlo¡’R؛Ֆþ6¸{4›ÊšÑ>þ;Ò˜ð²^½‹vÉK=¼3ßüÚ÷@¿8¶˜¦B´Gê¦Cn£Å<à…Êe)gç×îÍ;Ê(qÝXy^@B"л+ùÌÎ ?îSŠ?Ó&ì¶1sô¢ ¬›oHÅ8mp?¯ätÞäpö$ ÆžÌ_GfzÁf“çØ©ÕÅsЉ*=S˜ùÐôÈ>³‰¼¤Xè»ËwƒÂk…®sÇí[vV!ÖC:uƧ3—±¶*оQ úÐÁušÒ$ •ÞÏð+ÿ;áv÷v½íå„À…ª‡@«é5¹Ï+.-_R´ªÒíFò%Fõ2NÈ®S˜'¹:\ßµ‰ŽüÅwŒŽ£o9`6Çt&4,8«6¶“hÅz3kÀÍä@9Û“9þîcç˜tÕR¢~7þ·C$<5æ^Ž’êëÿ?à/û» è¿VÂ8¿» `Q[ê¼V °Ñâ©elݸpp§E‚ÅÕ“›ì½žŠs—¿X? ÅXŠL 7 û…{˜‰}KY!ŽkïÈ?ãä‡owß°ív )TÅ΀…bÍO»ÜųVÌV & ¾Xª Ýkyô±Ø]éýˆ€,ÉeSˆISt{–|Ï8 :çx,²¯ºóp£&€˜’Îô` z¹ ¥n[ÌÜoÆyœæµ ã®òˆ§àS½G/”åúô˜ Dp{*š4ì¯ ÛùÕ11å)R“2÷~6þ›½¹Hì_ÜÌ©P€WE#Ýu ’΃Ӷ=oaձ؀uoM€¾*\^}å Æ[KBTOpLÙœ­vç3%·?K=ø`¡Wø•IG™ÏƵ«òë|;^÷ZWä1üÄñK zˆgG\]p<}Ÿ%®©Ýû·O‘ir÷¹1eÅœˆ†íg#záÌý¸bÚ•{–Я´ƒÕ=³nõ´Â¤ Eßç]?¿I[h>¸ÝTíþphÒ½­»a„­øEÕäž&§ý'[ï%üwF[oÃÂGo$zdÎ÷Ó¿Y6bØvõ uÙµuàzPõ €½À péLNuÏÉ÷IÝñéb‹‡k»3ãCÌD¨ã‘C¯6yÒ Þ§ß¶!]a'ÃÒÌ oÁâLá X"07 ïy'À’k`ñR„ÍÞeï8ùûñ·¶=xŠ5+#D·ˆmOHðs-3u“Ó±º( ¯Ó~µ¯lB"Øñ‹À6•Ñ€êžsžØ^§ÆJ>ÐÌ ØþÈgÂÝÑwsÞK?ß½jÏ–gÈh6<ô*08¢f‚8ËfîÄi¶_êÇ*}õ”½0fþÑù~{ø…òF÷YÙ6£ALõ€þŠ·¥M"Â;D‚9'†‰¬¬âÔ÷HÐXmö¢ôHô¦I&¯3#æ÷] °¼‚Æ©•z·€Ö,mÌ|[3}†ÿŒPÑþwú*v¿›áï¨nõY[½îÞr·:±V)ÿ±·& „n+ì’>²þêÉž¼\Q¡Q Õ»öœÜ37xÓ|5)MÖéD„.á®É¬e%É0ëþ1Såë» OËüº70ü¹Û,Xyf.Ð¶ÐØY[4íîe{Å>éH¹¶fÕÆÏ‘¾‡à‘¹ª¼]M& Œl¼ãNçËÂô) £¦><&ïžø` æË?0Ôl•z“`¯UI]‘ó7_VÓØ<'w8xpɆº=SZ³Ý˜žC “†Åy»äů¬ÆÇ kÓ«júaØ*¥®å[æ£Q*v~ ´KM`•Ÿ?ýµp"x'ŽQs^aIðªõÌã×EÜÿ²q{¤w56¥C–~ù˜ƒwªÚ-àWF,Ó3¿Õ>~í~³wÛ#'{¸½mݩķ·ðÒËÉþv¾=Ó¡Ç^À¤ÐL¼×ë63vUåþZDŽ_‡5]Ý1f­`^\S*dá¢9×ßä=¨’MF ü… y×'\ÉÄ ³—º´§´Weœ}lp9£)zõuèŠxðöocö¨£ýPŒ>¥d0õü$PT6ÿòÙ;®îÇÝ} fK‚ûŵÑ[|Š­óEkôzûg» C!TTs2nçgóuÔ{$ײ’_ø¼-ÚEçf¸öó“²6òO“ÞéɾnŒ ¶™çBsÇ!ûÒŠÎÃK—Ç{4,ÓO™6fKp‚‡Û¸,] ÀÄ]ºX“œ¿ õõÿoðüÝôß,tç˜ßÝ…?­<>r¬-ùDͤ=¡ oœCÀjÍ+اü¤Èˆ3VÜÜ1nrÍ‘çÛ$¦a¶õ}Øy_Os?~£è3NݲçëßF.Ú¸‚;F)¼PUûð|GSþU/ý4?Çn¼6Ó/bnäMM‡{ŸGú¿f ø>¹ÖÎXmdvkWõ‚½³éÑÎGªÅ}öð•XÍ<–rí\é$Ic±$†|BqÙ©(‹©6)½,WÉnõB«làùYá‰Í?ªƒ,|ÈmÀÆ7+AU­ÍÍôÐEÀrSePtž³Z?7tnä cÿ ‘¸lÄ€¦zµKDgµc{ŸÞòÜ50S¿ñ8j›/ãÀˆ8ca4þÛ7w-ä³Ë‡™¥›Mö.O#ÂŒ«DzÐæ?C½—~¥P›ø›‡&6Žsø¡Ú~Vª —¡ª¦ï²âMT¤î Øú޳Î-” swvÄúdÐZ…üdÐô<\å4½g/Tíw€ƒ½‘=·Þ=¢+¹ .¹o¬ÑY6äKÛúUQeD´aãqÈö×±WÏZµp lw.NFOimÞâ‰ífpÛLÏWëÕéYáèÈX³G¿-f&Wì;m_ªé óÎGÛ £ù»olÐÎdúöß0f¥Lõˆæ0õpY¢ýPÃÿÓ‹îMפ†im5ÁôƒGN„"bª[IÊ/²F»Adù¶ï¯Ö=·>X¹ëz/0ü¾È¯ãÎHén©A!n;ªØ÷Fã>è ¥Œ„‘3%ΆfN¨ç¯¯[É ´Óï}¶Ž¥+Q¥¡—À9%h?H¨Ëðîþ#ð§ÙÆTÈ3Ï©¯ +ù¬ö9Ç.^³BÑNLáÆ‡òÃçÆ¡ñËÂVmËЖ€¢ë½Ÿ¼1g¾ €Éˆ¹{Ö¼í«OˆY1l%ÃP| @Ë8¦ÁÉã®Üp:å>GLUeݾ¿/]fÛlÓv>8BÂ|ôìT-akÓá6ÇSV ?œ¤~–Y†~y "?(¦Ú‡7Ît=©&Û9¼ð˜òsTÛ®óõEhûpt™˜E ²o”}¦µzëæM¶Ý¯ô ZØïÌàŒ\¨çôp‚%²Ÿv¦ù2ˆéóŸÜbås0É“iqÎEËCã%ÌG2‚*¼U Lj6Ô×ÿ¿à?TöÿyÅB~wþ¬’á¾ÄCá+Z)½DH‘ïÚqþàÓ,²€n¸M= `|Êí%·­¼‚#à‘<ƒ“nV"Ž#…‰)FØ…àÝ:>pÍ ÿjÞñôÌné«bÈ!œµ5[]sŒ¦9|?× 9¦¥‘žcœX6ÏìLä” \~g ˜[m| Ÿ:ŠoØÚØ›¹V~ýÉÏȾŠòÝÆÍ…¡SãwæÜsß¾ùYȾ/^¡ ÀÌz&ÝJ®kœŸóäx®ÚüùZFOM®šl},@v¨JŒ/®`,/þ6 KÓÔ0dÿUF½i¼‡d:Ò '&NIFÿ<9°î´Î§N5õ…¯NâìýéL‡d4~ßà£FygLMyâmÊ T˜‹ä~>’1O½û.*KTâ;ý`6çn _’‰¹l»àí äCáîànÆI8 «™E8Œ-?Ɇ;[öX™]±’•ަ<¨é^woaKEÀŽž Ù¿BdüDÔàé±^‚ñÌt]HŒú•L™Ò¬Ö¸jð¿¼ôrÌÓ4Øm5¯ðO{å|¯¯¹q²ó^ÉXp™îÛµ#¶LuFÌvý@ÿ1ºã;>ª‡Ž­Rª/à–—ÒˆØ{=·A.[µWÔ+À!æ0nVò¶N¤¤ûQÔÞënø*Ý5äð¿ð®3] 1»¨X7( ÆPÈHo´…Ȇ0E?zÜð—!àþm§"‹žui‰=ˆ›í·Ÿâê§´ù]›]dÍû"×µ†-·:ésÜíK‹ ¢ÅÒy—n y,|Ûî:áa©0‰ßœ€3tØj|3Ì0ëÏÀ¿=í­çêУjßòþÂÂøÅgÌôܵ¬ÙtÿõÚMëÐø‹ß]^.ç™hü£G;Û”|‡z»? Ì_­aWÒöŒx.%#„K´}i×WV+¯ÖTô˜f4vôiÏWº‡Á´®¶F~xGS8•H;6¡hC 0=’ {B³{hUßkO† ÇrÝ: ö~ì¹$Þüà&²Ï§ùðг6ÆÍ-sÈ?z3¾Ù÷¸²ÿS3€ž³¸›Óâ{JAVæÓŽvƒÏÉ;a.ÕW>™,—°Â €ÿåM¸8;åη¨f%-;ˆìË]°ö.Ø`/©­2Ô×ÿßñÏÿÝôß.vQ¬ßÝ…?©Ø=‘bCÙv0í¹¢$•y`ÑõK¾¦NôDtÙÝoÏ‚¶·¥OT5ôË¢†¿hÞ·¡Öèfm<€âf+g™=%¾¨âîEM7×^”80÷QN}dÂ'3˜¿ããö½á¦£½ÀÝ]É¡ ôÛ·Ò…¾!€PQxÛPl™…õe´‘ö÷-i‘R™Mí|ã:=Œ8àuÅÇ0ÈÇÅßCê¢])²o‘Â8—6ì­éƒWÆ"\'yv,àƒÝ"]kšD¯åƒ½7_íyÌd¬ËžïÜÁ 0ßráÜwíZuq‘ cÁc}ÇE€Ž‘îš¾ZösÊ~”»üáxlrN*Föר薞;®Ç{‹[Óï«8El÷™*É‚}÷‡©m`ƒÖîZÀi_f5ÝqÞss™yøP¦™¾ó­õ%’UÙmçƒo‚ÝØÆ™»g}šÄéÓ'‚${}ßÓOƾiíBE°¼ÝÑO­4@vãÇQ›:Ôß‹p6Ì5Yíž2Š‹¡¯OçN|uŠÓèİð h‰ÿÁôÓL3C‹²Eb ?súÖK;$æÛ³NûlË?®ÔÂ÷†Õ’§Ÿ§8ùrãÓ¤ës•-—e¿>{}Ö¤÷ñ2–Ó Áø²YÜÿ]O,,yµ=F¸²áÓf•€]å¾{C U|Yë5nN¶‡ô}0Þ‰6†{Ôèæß9Mzw¸ÙÊ—¤™Æ,«èØÉ?cá#¿Ã:±¥A`±³’`ú·A¾nô7¼ÇvJì)!ç‡"þŠë_uwm®\0^b; ’SºuU.‹þ€¤tWí Úøs4RÀ=ûsù“‰ÅYÞ,¯0ýº7Jœ°…ußËà’*¦¥Q-¯Á¤g.gÏ×Ù³Þƒ”‰Ü‚§­uy‘°LìÝ A1ˆHýcë.p<ö7ì’û2î³UÍÚ{Õ7È>KÄiŠEñ.ܦR¬#<Oô_ÊÓ<ú´s±?ÌÉnÝHx³–K¾¯8°þ€øp‰»f» ë7¾ÔÇØ†R£ý·R_¢+´sgËFpd¦. \&¦°Q îy%lYÙ Ï-•‡úúŒÊï& ßP|Ý£~wþ˜"y“P‰Â]Õun&  ÐÌÔÉf;îVc—…möÈ% ñÅ®Œ‘¶ñ8Í,£ÀüÔòÌ%æ  ¬tȳ=sÂöéÄt}sNèo$'´nˆA‚Qm«’h½’ÝA6`ŒfqŒ3æÚ)Ø".ä©]M]ûm&NçWZŒì»«ÏÇf½Ë­ sÀ–çŸPfk·«Ü’¯öñŠ7; ý6fñ&‰Ï?ZVdm+wâ„tH¥OM‡£ãÆëZø9m¼ó2dÉëa7§N s‰§ßÕEÞ 'iÝäÛþÙ Æ\‹šôÄåð@"å²ñ×÷÷‘}|ú™3}5>¯9 ð:¦Õ®H˜Ê«C:BgÛoö4`ñ¶½ma½ÁýÚ@»µ‚ ¸UÓ¦W²$<¾¿½×A¹D6t7Þ¹ü@û„j9Àp²&u¬ˆnuö•hؾ‰‘ÝÐýd¸<ð˜ßÔ7úâ¬Õ¿¦‰UoZgõ5q,¼w‹ñqâ׈}[æîð~¬Âp™OVP´fßfkí²Î 9} Žhºq«ï:Òp$Pìr uѽ²+Ð(çH·Ì­úžÃB:݇Ÿo’ïpg—ÕV¯æ”ß œ¯ëë™j·=§:{ÅÎV¬»¯·fhâ¿ øóK—ûì²Y*"_Åv{Z«oðìiIG¯g•cA«¼J8îq‚±¹þnfNþ 3׋õ¸€ñ4ðâuó‰.x´"&;ná§ç k 7߀ßOüP×öY6.7‘ìéz4Ì&/é»rÿü3§ȬX­©,Ù®1‚=Q M”Èz·Q¹áKO ñ§ˆMý¼sK Àcv–šÞ:f@»k`€û(M‹ à ã:cÂú2ï«®G“p7õ½¦Í G€*æ=»…/ÑwkLfÏ©_ûT&0YB5ð]ùCPœÅœ£´å[tËÆ”ÍÒçt} ²o™­œø:±%θhí€Ö™{žz'|øxÈô6ïÜ:  ºÏ>K·|dSlÜ¢ÂíÅpD´ûü¸ ãFÛß-‘@öÕÇ«YB]ym]•ß…8ÀfXµ…+hJûò4aÍ"ÝÐ:a¨¯ÿAøWý^úùMÅÅoH{üÊæ±Sªô kS²ãî˜nzƘî“V®õ ÃXª“uÇÁ½ÏE.ëßw~Þš–¬Ð<¿Ë¯ÝdgºscåÛg°pº»÷Œ1pJî¸ûa‚Mì+‹%Îm®—Œ|¶ËªÜób¶Ž»áã–¿OÙÌf¨Bé)µ¾Üû/(°«ôL}s£><\àkê‹úøÑ¸º¿œ’ï{ÐkuÜ"S qõÑñNdÿªÿƒÜx0Rõ—£TáøC.À ¼ÏT4¦-L^?ìèéwÈ 9µLÆÛgà#'Ëî/ï)=nÈþǘ¸o÷6ëâ+Gà7¹Rßr&G¹ $Ø,ôÀÃïHÊíút{rŠ/æçäª tiµ`³ rZ™*ßÈ®ù±ŠÞ´#‰¬Ð'Ö;;éV¨¢suë‹÷ã›ÐóàÈ×sÞߟó¬Çj †M¤”®ªÈ,@Sëu‹™°%2íîfd~dYM¢òÕLJÁt=|ýÅœoê͆¹~-ç/Åšce·j›™¾£±q˜G)À¥C’Á. ²ZoSG$‹5cn3ë¢ÃdGIž-‘‹gf'N:ŽÜÙ$S5"AäîœñȾéG}*ÂSŽêž ƒ.í7·Dí²KF”Nf08µ›n„³)½J¿FYôÅz`g»-t^l ðòÛ.ÉÂf1TæéÉÀ3«NÔêêîlµgúH‡>™D¿Ô õxJ$Æ0.‘‹‰vªJk \u«_4AäØd¹uÒŠµz˰qÆM Ôä8–ÙY“i™ *‹jÏÃi>§µiº5wuZ¦I=%ìµkí`•” Ìs¿?#ñê¢v™KXôŠ"ð™~¨Ê0+øSX'Œ}ª&ûfì ÷PkçÕŸhêÙ1m˜#ÞÇÁ®Ãæ7Ÿx+ ¥s o™c'ô÷~û¼õàmþ"Uºf\Øk8¥M,½´.:«½wÈâÿ]ŸÏ7ò°RÛî ˆ´æ´ºœVŽ¥Áâ\ß˱{¶=á”HÀÊ+s_Èj}оåFs°É´;ilz°Xmܘ¥«†9vH ½~ý¸n”RÛ…˜Ýæ£:¤öy›gÌ{òñnñÉ‹Kªºß®oÙ¬ŽvMŽü…£íÚ^óV)üê°ó€õ%.™x±æ3ÀbØ]?qLÊ€6/>¥)‚(Hc.*s1âÛ´°É‡naÅâ¥ÆÙ?¢Ô§Á‘íã:M¯&â0樎Ï‚ÿqÀÞä»WÐZ-вÀôIc²Îk€¼ ï'aàøÞa%‡©™Ü½u†%²¯¬ÚÛQÿÙg|SšqÂb÷0dUme´ÍÖ2³[•Åb jf6)Ðþá»õÂPwrE48v¼Ìgxr~`æŸ /"áÕkõ SVã>#dÓ`»÷éàžÒm¸o½–aåVÏH/ü£ØáU™˜KϤ/ÝX9në×* úPx1ÓP}<½|¤8A«žÆð.¯ %9BY…DÀpëd½¸JœØu†ÿZáÔQÀÑkÙäòBQíR9£,ظʺöJNʬáïÖ÷bA&Î×<¶äî: ¬]GHë{ëC„y}€¹Ìºi0m‚&´}•ì-öm7ÐP}N µi96ëòÑçÇâ èÈ>ÜfÚèíyÄ2ä•f)ƒýš38í8é:®ç6^ºuÏÔhÃq󼧇¼aÅíûñõëåôæzU²·âräød˜î÷ _õåÿ×Àgç?ß=æBg3~4˜½˜h8Wöð+·HõkÜ¢ 4ß`‹×_ŒäÖA{ë^ߨ¹:sáôû«êÕ0[ìíÙ)ß$vW˜â ‘U³ÇÔ)°Oaü+ŸE‘oJŸ IÃî,øœÔÌí:S ;®¿þ&XPß3.JNgÉÑÓYøJ“fót¸â¿” çúˆhILTî,†ÕŒWÀ‰/› óJônâJF¶ ɺõ;VTžë ̄ɗ3q[‰þáQêúëøpÐ’vÙòEn-xÏxÃöy8¢dÔGØñLèUgO;Cýí<¹Åmïúf)¦ƒÑQN™ Cóš(C£æ‹f)#Š¿’~Ifq@Ç€y›Š3 Þáö=ͳ–^Ks»­³Ç7 ªÝV»6`‹Þ+쪭‡€‚{´›O†4_Òß»!ûŒèÊìÍkqØq}û¤¶i—Á»ñ »ä²RFØð¾wäœmvQ»FÔ»ó[•<¼!¢¯êçr!{ÌaÈ>l3¿JF5³TFÕo%¼e/爞zƒìßÛ|}@.V§ "/.êëŸÂŸÿwÐï+ÞÞ¿» ¿¿„–xÿÄmóKV_rÕ¯†;q p`¾Y7âÉ¢ì`XwÚm·×Yû ÿ‚éç&-”39 zM›@?®ãl»ŸÇC‰·ââcŸ lANž¯¡ÿJ_Ÿó¾5yÉ[Z>gfy·-Š˜çF0³¿ ª2¾¶%6]reÀ!=»Ó°5Oøm¼çi5yìWðwI‹ Y¿KÙPtFGNfcS+"D†«Eä°?Ÿ+y¤b´¯a]¶'Xû…û‰Åêä'´ÜP=´ö9ž`­J>1RjÛÚ eµ$\ƒ¾»Y5 3ç€Ó”ü«03ÿ*nf~ms HX~!kتÓ‹`ãê‘ýã /,0ãÛ”ïšé >l–¼Å½{³(z¶Æï᮸֮(}‰Óç×oNxè€/‘ؾ튓?í›Ôæ˜v>0Ô €ã8çÐÎjx;füäïa[N,ÜYçnð—±ù§c_F]]Ÿ–>áQŽÝ˜Gf–ϽB7AÓèH¬–4Ãþ©¾–GNîŸ {ǘ)X“˜«üK8uJѺt½îøsP~BÄoƇ`¿S°dÙïHK?/h©¹Q~ú-¨8aä18øT˜¡Sk”8Œß ¯¤÷a\È{øÒåũ1ûT~’Å•©Ø¶þÏìCéʯçW.¯üëm©M~$\¯[^wyüz ¸M•Ü Ìa;RÇcÖ²'’6¬ÔÖÌœ¸vÖ¹ýµMìè"½¡ ç^ŸG§Ã]÷QçÀ,W²hŸÔ´ð[Ë:­çóªsýp.Ⱥ¿äOÿûUèB¯Gé^{-'Oï›``¾¾^èqz 0òdãM>KØ”f½ùÑèŠðQôJ3Ï]‘ù|á%,­†Í딀®›n9«ù†:`êöw<ÃΊœæ€¼›Ý‘¨)/˜IŽ}y5¦R­ »Œê«Y~S ° .(d±&4Ã\=¯O‡Ñüï:’GÚß­óÖÝz­•Ȧðc žKþl1kç#4<-‰ÑcôüË*,½dëE¬(¹¥¸æp:lÙíQã‡ìŸ}¯d€Äñ傤rPW~¾6XðI¹ ûºÏ¯bÜ09oUÔÕaË· õõOâßú» èw–þÏÀ°nuŸw+Ö»˜ Y§ç½|׃ú«ªAÇé /í«?>äÍòP¶§÷êá’¯—a³uµ;6·Š´¨=u<ç}=wßjxrzÄ]Ñi8ŽÅj¾œxÌ2àÅ›õö‹F€ÞZ0~^´î¶øTfÅ·ñ >\öºç¡ p·Ž¶Ëûv`ÝÑoe¯²N/ö3;Ïž a•ñ‘-¢œ6¬oÞ¿‘æGà»Ôâe|{VÉyoÅBœ7edã ”ùiXNå¯B_€kÚcõmÑt‡øýæß_Ü0Înœ7hó'o}Ï >Fßñõ °¿Ñ¨Ñ@ˆh¥JNÙ¿p\ +jå!ö8³Ð9aG™£¶]nÃé2 ^!Ç—]E)ª‡„Í$›9~ö¯‹oß®O_Ÿ™œ›ÔeXc%úF`Ÿ½gÇNmûæ/*•wåÖÔ7–’#FœsÙÛÙ©4¥"wŸwº3kiã%^¬ÚÃÈ_ZAkÈý `Y» &c ìÕíéxoˆ}MKºØÐ|9³â¹|n±–GU6Œ ù†­·1øóð?=±¢m—oÉ» üÕéà³0ZàöçÉσ–ÍôTY{’ƒËT³¾°yEVWAPs[qût$“ ‰)9¯d,ùH¿ÜeˆƒýzøŠ=—Pï³Æ„®‰?b º³:î¾m¹~¸o`*ƒÊøÅx{ØÞ‰á@k˜zÔgñMA4ÿ›¯‡•%ík}sÑ‚«RUoÊUŽÄA]0å±÷ÔNb­á‡U7ÚOž1Èý²œ¦Åö¾‹”Õ$û>Å- ¦Ø½ÍæìÔ)—3w¿3x°ömó5Zò¨FedÕõW3Tš2¤Ãö0–llÃˇúú?=ñËï& ÿï ÿüÙßÿXhhzÐü`ä1 ôžš,·Î iÃ0œ|KÖaÁ{‡a¿¾óƉ·"º—Û"Ý5ØŸ{ËO+8¯]&Ý3‚[{ðªEn3€ñÎh`ýÍâLÇhœéaTE&1¨6÷ª)Þ`x·øl( `iî%×ÿŸwS_Qƒ£šEãç6ƒýlš{3Y³'ÿ†··Ð?ÞŒàvþåÓLIÆŽ8FNƒ¦p_0`t6ÛLš3úDÐqÏœè-ƒ 0ª8Æ`qïfbŽQ¨ t Îf1ØÀÀ ôêºÄ: õǨya:! ‡±˜„ÏÖÜp›¡Ê@P·¦Y,‹lvhà§f”9Ù ü™äŒRWH04ëhšÑÄã''ƒ@S‰úÀräü…ó@ }&C3ÌCáÏ»Ìmì—ææß‰ÿñp à¢BÍE QE†F‡£©¤:ì1É¿„AaL G¿wŒœ-&9Edw0&õä„bh&0ô‰ *¢Ÿ·EŸœ"Ô{4Ï ê;j1]ôŒ@ï˜89ÅAÎ?ù….2¹öQEÌ 'ñ@@‘-b”} €¤šeQÑ8TGÉñõõÿ?âÿ‡$þ·—"€ÿXhý?ì¿y`»h‚÷SA?%œëR¹ÉýrÀÿtߎ¡,‚÷Æk‡éãÅÆ¹‹¦Ÿ/˜D³x°ý]Á~m»ß‡óØ„‚Ñ—èƒ/ÿ­6·«<3ä—NFÿ50Ýü¸tñ“4-q»hÖ϶Úà¾u ààƒ½× 8…±¡Nî¥^˜„•e1­EÔ6“EzV´HÉ%îêï“ì‚–,q3Å@˜] AR5NG7 —@U$=.—iÞ¡è-“°9<¯@v™Ëî<7€zïÍfcä`pÌÉ Ðô!ÀýHµhƒ˜ áDø'¦âäT" wÿ42’1€" r–D¼Ì´Cý¦P![@Ðáˆj¸Ð5€M²"6nÌ@¢ §pÉ…87^@  ²6••ÙoÅ?ßo`zxóx – Ñ2€úƒ¬ðb5~‚Çʨ¨ œ"d4h2¸\Œf„ŠH¦§*:†°X8õ b¢Ïh\hXÞnQlrvÈd@RšGªYiøãÔ<¢Ïä¼0Éù§fŽl‘É`ã¼h‚´Ïpš/‰?ÆâEξ`¹pƒÒ47!›@ãêëÿÀÿÿ9uü/*ÿÿ©øþô®˜ú•øzDÂ`}Ç]4ýü0 É A†]<έØ/L „к:Çp)žEý–Aœ% 4ËE”JPÁÄN—¡¾þÿþCƒÿÿ‰þS¡ýâÓ‰:À½û+ï—Ø/TñoHƒIÐ=÷ƒùºûS–ð«wgÚÆÿB?ÛˆXÿ¦ ivX àüÿ*ÿK}ÇØïÇSº”×7NàÏ»¹µa/À¨ñÿ]p_¨\¯™!‘oéž!?¿Äö [O„qW3î“r“‰Sj€aÇuˆ¼´*ºêI¦aÑJFz‚\È”OH¢Fí£PMÛxJ0ÉxŸ ýé>ÉOé?‘C@+ŸÒE¤zblI=„ÈU“*'oôÅQ,Àd ü ýåÿ™8ŸÉê§/Ê+Sú’IQ<‰ 9~ÄM,!1™½˜Á<ÙJ)Jï31„Ý3˜ÝOqd²—¼‘Úu oùÝø'â@?Öî¡&ljD\¥? ¼¹J¿_þs™»?T È–KÚ(ÎA–)¥M>ÀÎð ÜÓÇáÏÈú“¿$n¶ž'ÛQ³hüä²£<¹Â0l ‹ÀÍ PrŸd3 +‰?›»@Q<ƒÚ¨`’›a@r€··À¤kõõÿð*üÿOðï íù7Hé‘/.Áì~·L•ŸTÑ/É~ùŽtThÜŸQFë?̯ß+ÿ-[û³Yoß0øEÀQî„øÙ ö«.¤9G®ø€.ý74ðó6fÿæ³—.@kÐwhýoÜý¤1x/´íÌúEô7K÷Èhÿm³Ïð‹7á½`šñ©lœÚ[¦Â}REbܼxû„Qé@Ê+ ™ÃðaL›SŽœ9œôä¶(î8Ý9Šðf›Î¦tb!2‹|JÕ’KÍ‹m©¨X˜ÞÚy¡¨R2¡¶‘)ÏŒtªC ÿ³,f?5Ès]+ÆMë“@þ9Z4Ù.!8ÁÍ œ` .Âè!l^mnŽº_Ôñ~UTNr?•¼E™›?þÙ¡¼Yá*TOêO¿³os7íÏpsô¨6FŽGãgSÛ8!S\Ln³…†IæEx)Ì“ØâçâO zrë…JÏ£ È€¢¿12ÓàM Ãûå~†`PIf)ȇþ¼ÂAA@t €ªÍ=@aFômä–ƒ—öP_ÿÿÿ¡ÃÿÿDÿ®ø ¸ï¿Ë?*ðµ‹%uý”nƒTÜ¿¼#wÎú·xžLð´ÛKM ˜ró÷$ÿ®ðR¸?u w‘zyE°À‡ô·„o? `¿~ľ´3…”ƒÜåL^t'‚vŒ7ƒ}å>Äõ/ôÁ©>†Sñ·½Á@ãÿ5-HýkoZDðöýHÉBž˜¢ö™© ÝßÌè÷ì¾´`r¿”:ÅCP iž/@žƒ\ÊääEÕ¦?•¤vÞ¡vpyÜãfý ;£¿8¤ì"(‘…ûÈCb¾C ÿ´D ô%©‹Üð~]ÊsÈ8µÕOQ<ïdÃ6ž58/À § L§(œ2NŠSîÜ.šÍàÖŸ‡È¦ƒÑ€ÿiO’sÂ=FËù„ŒÁÀî~êa‡3¸g'I0úÏåáýä€á×}¦]4Á¤Žà!‚¦ð'¸ñ56^ÖÿçQBÊÂÿ)÷1Þq?jó{àp&o‚Q½~üy „þË¿`ÉòŒŒn¸Ú õõÿoðJüÿOð¯Åãþ™ g4¯b@óþSOñ*lÚþÜØe:DsRj¡þÄ ¯ ?Ïr ò"·í£‰Á„ð³ÁŸ ²_sbž´Pò(Eýìõï·yVxÔ¤ ÜŸ¸sgýìÙßòýмÃþU0ìcXýfûÅóOŠ#Ï(ÿ‹ðÒ-ð§çP{x””aRÄ€V4rœdFwyª±äá*äÊØ\ïF&)wˆSº€\ÝîÆ'ÈèŸÚ·%7Gɤ,©I‘V@&Iùy Š<ÖFJ)²ÎP‡"’çHJG~Ä6¹¡¡†ÿ©`Rê’~ÖÈìWñÜ$87™Ïm HqŠðÇyÂ“Ê ÐÈílšC ›{À‰S{ÎÔÎ5å¾Ñ— Çh •õ‚s÷0O?ÿÂ0 8G±8÷x>9 dš·»O² µ¾ž!¬ÍOžh¤Øµÿ‘ÄEÔa>*ÀxöѨ§dÏhNaþÄ`q”4¥jSg$©t µ…ðçfÈD¥fyju¦?ç@æ0OzC¸ùùá?)ž»ÍÂËÿS *‹CPšú颡mòëÿ_ðRüÿOð/ÅwÀåÿ›ƒ`Ô¯Ù‹<£Í};pPüïýââI÷ !¿Ä¼="X¿zå¿?6àݱWþͶï Ï w"„{‹}ìϸ|ÚþE ø îõÓ]à ›k€Šÿ Òû}ŽÜ‚šñdùcø€làdsöëï(óoîƒrš¤Óøõ2cë±X^ðqÓz\~aò6ÿèvñåáHíèéO8ç¦U‘{#HN")†ÎAA>}o:ªFe®éÜCêy6r›v&˜ )÷©çþHúb05Ž$ ÏÀÝ4t•|.kˆá–Í%{wV0/ÿÏSñ<툈„Gä@¡„ðgzF€„éä߯K¹»Ô¹y N ŸíëÞ¿Àà=HßògàŸÏ;†¦ˆäIê@߯ÇíD=õtÛísÙ¥_±Ù'þå1@ª"ƒN#S+L@ø¬A✻‡ÿ·Ç¹»ût‡è Eð:¼¼´¢yJî{ üIÓ4ÇXÖ cLàm+ô‡T²€B” Ü“L†æP_ÿÇßïÿ{ü/,ÿD¿ŸÍÝŸžü—Ý]ô#uc Öe¼50@¼Ÿx¶–Z9”8£{àÁ¬¿±ÄÀäý9âéÅùåÊ@'2ºÜšLÇÀ ÊÅ3 ºGøÏþ8”ö+ àà¡ß¿ èÁƒX£?˜ÿÙÄ@¸?0þŸ5Ý9þ¿dýx…~’$3z3Ä­£C+b¢H(áêBŒ÷9÷”¯/#˜<ê±/-˜Z씟%³~ÔÆ3A)tòd9îc,Ì%Ø#œ:ÎNƪ1Äî”z¥Ä§c¹+È{ ˆ<ÞÛóƒ¸â §Ž2†þx!‡Yî™Ùà>ÀÏÍSƒaQ'ùxûÔ&>Ó™|°±ÿj˜$þ¼€€›’åž)Äxçþ€îéïÏ{Ì‹àž. t¼þüÉÿ/2wêÉ#`,âWÍÏÛ'¨ Ù=dÀ™|°$®.'óã8WÅ“™nErcŸÎ;õÏBøû£ÐȓŸì0uJ‚Až&À¸›öÜMàžú§ì{2Byû¬NàtVî ß>FâOMšwgõ`ƒj#Ö¤’ ª£¼x…œBíC}ýÿŠÿÐûxÿƒ m 5xwûUé1cú á§kæÞ÷Ÿ„ f‡Ó\‚ˆÁmÿkƒÎƒÿ|úÛ•:nÖ/÷ÿ| Ã.ÜŸè7í ÿã6ðÿiïj{Û(‚ð¿£­Š„ TBj> µ4mâ8Ž;w·;»g'±“8Nê„ ñ¦‚ZPUðëØyÛÝs#øq¹Vj¯Ïw7Ý™gžy¶ÿ²é~ß.q w³ˆÎ­ ÅyJœœÆû§ïŒÌ "£-›äéï¿ñ^çã?ÆÖÂ'S>eHy†îlì9\_R­z”2”‚ú (œ3œ ÍŒpCsU0øùòPTŠÚSÓTŸ®ý¶Ï€í@ÙFûÿ¸ £ƒýmLe1çDŸ{ù"%]aùô2vn_`/Š ­nØäûôÒÙÎɳ0ÊD)‡5Ä²Ü ¼uŒ½T˜Ó×ñ\·Ž_y*Wï±ÛFû¿žÚwä…½§Ò3šóGJ ]ÆeÈÈ„± ð“r׸ù¬ŽX³ª"G[ÆcgGw®ý§/ùYã°þKÎ)©ÓÞKuŸøxèIFÅï¹ PTÙ±ƒh ÆÎ¡£ô –d®¨4QjT¡²ø°‹Ï¬_ÔH@µÒ vØ9?p±=ÀnÍ&Jàѱà€ð6—'°™ƒ®–I·Ú>ÿ3û·ÿ§ã&ÐcOD#ý»"Óë÷uèJÿÅÚ™ù_åfuYË£—ÐsD‹c՘ƔÝg¹CÈ¿¬@ñ¨»Ø‡l‰çà|¥ ¼Ê·ÙÄS¾ðfˆx£þ¾8«Û€èÝþ„§ ªºgÐjYšÌmÂrëæö·—^:€(Ü—¼8ÓÒéP÷Ž…Þ)ë~auýQ¥!5­´òÖPŽB O/¨8M«¦›$ J\îðþ`&Ù…Æ¡ªèè΋µ=þ¬µöÿcXÎ#þ¤Á¦4N<³t˧ýý18~ôd¡gKMרˆ*žW™ª^[on]'ûæ˜VKï>¦ÿL ƒ¤ò˜6J¦¿3>`X™:íKõÌ˜Ôæ?Ö"9AüérÓ\Ô¬F«ÌJjéUbTV¤™õ_tÏm¤ x§·å”Ñ¢ý]jí·å‚3Ô|PjýEƒ—£B½O£ºÝöùí߯ü›€ÅÿcÎÃ^ÊÁ4€µ(=/Èyú§“&b­E÷x÷dÂÃôÌ6z‰ˆÉtÙÀl匚…J¸=,¼ƒì‹®ž¤É×t1)…t8²{&ßdø_œçñþ” ¼ì³Z'º!ê5¾™EÐ?ä:º³‰>I»öä/Ǿ¢Ñ‘@ÃßøI˜¦3Ï BÈb ­ÀI¼ÓÚ‡…½GÏñ©ƒSGMæžµf€”~IìÏï9 ¨¹+œ1¬<åªÞ½×SgkÝZûO¿;1µÐÆtgâQ;–dü?“ÞXŒ%o5fc‰²uaU¥ÑØÒ ÕXþmÅb¯Áþ,ôRX{t­ìÿË!> sÈî›ë,òK^•“s|$É‹®§s^s õ“˜Oˆœ,è@itdž%·Í"Ú#`Ê )Ú@ÔvXªî{¼$Â(m­£<#û;íÖ@Õ¡%q…bPÓà „@4€ÿ§‹€î½¶Ï±ÿô½Ãÿø¸ èPü?³Èª» P˜-Z—Wš­¬KÀnlÛÝ=Å&3ÿV±—Nw%œ²nN·yËAØjîs?ƒ§DŽ®ØS®Ìä}gúûW<ÎÒÌî+ÞA¾0]lŸ;ùôÉùXOk#½’ Kîñ…nÒ½ÿû„6ö>\À°Ì·uÄ bpyó´v#sÈ[…,‹€Ç›q °OeÐþø€žÒêL4üÖ`NÛ€0G¯I:Õ<únŽZlÿŸÎ´^–HÊ@ÔùŸ$tO»×;÷õ¯?›09PëØ/ª‹³Y˜ÇËà–JTÆÙúàšÙ{Áètôé,3ŸªûÔðo¥»ÏcÖË™6Kÿcw¶r¡¹°?’ýëtFݪ‡ñ ‰õïxŠj{NÏŸÜV¦/ÌŒ~k·í¼Î…èþÑþ–)B`íÁþO!5øõ  ó'ÌQ_©Ò;xÿÄîÙžÆ@r´på{øRôüûÅÝŸÍ Î ­jñF`¨»þ6–¼UˆÕ`¬ †Ñô9ö7Ê 6/(/¨ÜæÂ{Ù%Ä!r·ðíþn‚« -x² ?°{·¿øjlËVÛÿ͵ü! RËÎcÕ¶gGB [Üïíb¶§µ¬Ôsf/Ì  ]Ü‚ýi ï^7û_~íñK ýRÝ7^jèÐèøÃ4Ü¿ÖÝc“}SÖÇâ ååÁþa’Ø`ÝU0¢þ|6b|0!buaî`ϺÔ(Ûp ÚŸh¢Ü£ å³9¯¹P8 [1» ñÿ4 þÓûmŸÿhÿ¶âÿtÜDŠÿÇôíj"˜ñºr÷¦5ä©™m$g<§A±}²OgݵS=côqŠÙÌ!è9ÃU N#ý ÄÈL5é,Avi‰¯:¬º!hq&õ ÅçµaëÅ~X~s9Pl|½ŠÿñŸ½C\Xp½~ý‚â«Ø¶”~áÝ/¿! Øp-ÓJÐ}dKI"©_¬¬‹?ª“(¸ì Š+QQd Û†õ„ZŸ¬¯6–ÔNÌmP¤ Æag–5ÂY ‹‰o~çå¼l¹ýÿýRøç gÑçÆrñÜäY|ï°–€Àr¡@tHàkShä4àëgÿó ÓÆŒ¸aÍùY &çÁs;–ÕöÇ'IöHY|Ô Ïà@ìOµ•]3•}R€Äº%c¬î‹«Þ ö—}|Iõ?ÛpØ¢ý ÌÇÇ! !  ³ô>d4€ ñ4´‚àÿxÿÁþwÛ>ÿ_Ìÿ1:ï) Pxœì½y\Mß÷?ž© Q™ç!EÆB%SQ†”P¢$¢yžîxÎ:÷Þæy.©4Q‰4"%SH*’ˆ Q¡A¨ÌñÛçÜÛàõ~¾ÿü¾¿_¯ýà¸Ã>{í½×YÃs­µ/!ÐÍ"‚øÓSø³m}¢;ór+WÏ–& Øè‡Ì›NÊgœ…?Ó۳ͺ \ÈØ/ä:.ˆY°Ñt†68=À†4EƒyÏIy_“u `¹g÷ìðùixdœw›åez·UËÑúŽe~Ø—®ˆÙE.ö}<Ôé§}ÎêÔÌx>¾ÐQ˜éôÉ…í¨¥˜ØÌ¼¬âcÍ\™vÑj)¬!•{œÛ Ìæœº©cRƒoÌ"@¯½}£êFDù¯íRs}ë ýÆåI€•²…2 ÓGvÑpÙc汸Æa>Àˆ_gtìöB»ÛŽk#>b7¶°ýDî¿+ž{¶Ý ¸rwËÙtƒ‘ £\‹è_)Ý?,L ¡¥ÏkzíÌ™8{åMóƒj’Ëý—ëosrÄè7Úö…¸ïO_‰¥óbÁðÛ«Žg¼ÂÇ%|~"2nlNA!#~çëv·§Ž†/Of‰Ÿýé"§E}Ä:šÞsSáæ 8ßñ`‰ÍK¬=YÁí-¸´+­ˆÁWê¸u.ÎŒ:¤³JÊM^º»tÅí•w³4Á¥`£Ÿõ e}yÞ /w¿ÅÎ. ¶¹ú~ÿÓ1[æñæXÜ­Dl™¾%è;f={|3èƒ0l*Ù´ÙEè‹hÄËѾÝìxùrÓ-U°jaÔ|ÃeuŽžÿDé"3x…æŠ °>Ù°ð•a#BÑþ¡q×”—Ž šØ]ÊØ~Þ“ aZêúZ-°åuJº6¹ms„nóŒâŒ y±ñ‚¿i²9WLÑyE˜›nDÙ.fЦ_òPÖ4aõé®ýbN0³øø_È­Ó4Öû«Š³³'ûk-m]ý«r@ë?lOW[#É‚îRpŽÇu‰Ú‘?˜&­òm<«¡3ô,1OrB¯.'g;ûð7 ²Ó3ÜM7Ëö¹¥”R ³LòÄ3a»C·ŽÈ•=›ýjæqÓ[™SÜb†å\À”hhÿ &Z7ô· ¾Ëû 87½9«~[y©\oüfHÀÊ»ŸôJŸ˜Eø-íXb$;Ñß?+ådr!@,}j9Œ‰8¹Äö¾VÈîr nº´Îo·ƒL"â–'ëÜ4뢟ø)ÛïÛqO¬2 ¦.Í?­ós ËÿŸ¶?º±mÃÿôþh+ؤ‘`¦Ñ6'µÔÛögŽÔ}~Åäú&Nbû¼)Ûk¸ßJF?£°¨ÆõZjúTŸ-°OhÎ2–Êh_˜–Ǭku7,|«¢4ëÉ ÌóÚ%\†‰ìšnèIû>-QéÏqϮ󊿞ºÅ×ïép¢TÂNuƒœ9€bšµA2k;¢orÚóg7ÑÇ@3" `ràÔ¤‚ç߆ðÜÑ㼨æ«{½ÎJi€}ÕjGÎÛ,Sõ[6‘Ȧ¸Ù+O¹,5'ÿ`Â|€/ì7IØ"Ïäò{•³FÂÁíäŠvw?Å_ƒ<¢5Œ§—{{qaé$-¸Õàöéø¨íêí–ßmãAÅó»N3ë1Dÿ\²p¿NÉÒxj½²-6±”I{fok÷Ê:Jë}ólïÎL`ºÌØ4 àã‰7)Òævù`‹ìóã`§vi8lªn±3B?ÉC³xB=Œž» ¯<3 6Ml~ö­`«Ø ÿ¬yæR<­M‡‡ƒM¶ œËU_:îíhc•]ž%Ýì+0–Ñ y)Õ—VN ß"B¬óɇÅ4ó÷J!ùÖÊÂXþãgôàÑ´P7"æð½³î[¶Â“ÁIŽm÷Ńrï¾»ª•W¦Ç¯ ¨•qKßü@mÐêÏÿ‡-ªb[ÉÈ ÒTR pÒÂõÞõV `Tsþn(Ùuãî=æŽÜ:ó3[Ôyažë †ñd3mYަ¬~`ãé€ë7>ÍhJj ч¹°424”u¬GÚú ùÿyÓ®Œƒ—ÃMæ\Ÿg0-c]îNKëLrýsÝÚµŒÑ^—ìþ:x®Á¹|ô€oQV¼äÒÑm°îéÁ/Åb©R¨ã„‹œó _7ü@J–’î ‰X´þißý§ž¼Ñ °lìð[˘âé"€_€iÉÁâõàüd¯x) ú7K&Ìø%&Í>¯j…èoÑ ÖuBôÙ©ÒGO¡ý7¾Ûzd÷€ÒÛB6ˆ~1ÜW±°.tjaõÙ8akÅi€D—™·Æ–=7}ú 3GŽ]k,Ñ{4Þ½áVÀÖ¶à•h¢ŒK§C°xàd½á˦}xðdÅ7lù/úc–çoi.ì€?=…?ØŽœ;´þÞ'3w¤Ÿ ˜ߨwÊÐö}PZÛ®‡¸Œæ1~@÷ K!\kÑvx›ÉÝ oÀªÒÞg~ª£%ÿR»KÎ#¬nœRkr‹qÐ24G²Ñ!Š´rÆ·\Ê%€=(Gq¢ýܻǦˆcú¢Oo¼æèÏ+ÜÇ|V]ôý*¹¬]!eG]ÄHÁn.V}Q£m_ç{z+-¾”ìywWiÙüC>ðòý*öçÀ_£V‡oN(ú–ü;¨‘1åÙ¶‚–Ð6D?gú1fûÙÉ›Ÿ&µ…;«¿Þ>|¶! w9ÇŽÊ®¦;´eð,_È»ÃÅŸý€•¸¸Àÿ\-´_½gËÙûg¸uœŠ9­I•Æ“—Kâ&ðHÍÅáaøDŸUê.?ƒ/Üý·îœ,Ág{Ì™&\دâQ0¾ ƒ»ß=Ûh½Å“¢åkg(¾èîTÀ©u–ÁÑ9…°ÝóXO¿t´;ŒÏ9?S^ì®®w'&8±†Ös‚ŽZ¥Ê_†ä3‹€0‹‚Ëë$Ö×>€×Ý6ž3Ø×žÍ1g¤_ûà‘Û´ágòÃMà`Æ’YwFj/|é ª‘wº´>@¹¨ÈÀ 8‡tɧüËÿø=k/ra®bÎåœ\©sCšu_C‰¾È=;Œ5ù!€u ;x¬^[DMxêüø:”55e°Ïϰ=’¦Ôo¼Ójv¬¥Ù¸ÎT8úÃ¥ CŽÅ‚_’·&}8˜þò_êÜ!­hù‘-‘ÑÒÝ´ÎýV|¬«7G/ñýRî®ùkÃÁyÂFJJW}Àªéþꛎùo‹×2½só¦jÊXí‰ õaglšÿš®ÑùÍRñ1E›Îö­› [%Žÿbí‰ÎºUv@‚ N‰Fš~3×lˆæ‹å€ÙSo ?1gåw¢ïdúíj²îõš^Ý£ß>)§[×O®þ†%èW±Ÿm}+W Üû#$65–ûù³=†­h*goo6D_|Ã=Ë.€ãÌÖÁ®†CÖÔŸi‡ùÍÒ}úÃ…ÁnEÇïzâ9(ÙzF瀖ÿÅÚýÍ&ÀýOOá5s°Pø®çÊHÌX˜Š\y•ëÛÜ#„ð÷»ÒÏ»ÓíÙ âT¥;É{™™¡XœM-‚’“:ê:azÂë|Ýs %œªÚƒ/‚Ó¢c9ø­„Þ`‘¤_ãUï[E@ÅÏV t×ZXa&g¯¯¹aÕ:€Ù[~üÚ¼í=@mØÁE\l×vYè䃈þd¯g÷§’ôÏZ1Þ}ýmÑ YoZ=€ÞwÕæGýŸc¶é3à[ÉórëÕMþ.¡cª¼aÜ”¶méñÇrÀyuF®=Ç%rÞ5PãÀ÷¬äsfM+ ñ/ʆ¶îGôµMâ>9ãJ&ÔD×4·<<°oQ*8ã|A{òsÃv§†®dÎÔ.»¶ðóÎU0QÃIÞŸ[tëဠmY%«O|~ ûïüäæ.^pNBüö‡ˆ¥ÇŽ’Ô›#¾4)9’“S6Ø8¤}±IÅÏ…ï£T-õ‡-7kŽ´>+¢ïü½qE”šô Ã@£bÍip4ØJod”ÔÔÙ çm¹Lgy©Û>œì®´.ã Þu©vì{åP¼ÒQ„3@ºà,l]üæÌ^žŒü|º;ƃÍ?®]¼¤kã&ÐÝT{Të¤Á©•'„EñB¦TavÛç7ç€S’¥¹ª¸ˆí#ø°À4w›ôš…6-ô˜Oûö/ÿãk•Àá_ZÚÅ)¥U„­·lqüCö"xvòt;:(½æ 97]+ÓžžŒÁP¨Ý¬W]ru”§Y×GzÙ&Å)«sÒ¶ÕÉ|ßß$tôÓȈÑï0;õéªo Ùþ…ü åîçù…†Æ%Âken«Ð5ªõÒÞ™xéñ"€a§+–Mô}—ïæ"lÖ¥V›÷p%tÿö…Í0í õ;Yî­Ý Ðõ1_`}*3öl+.ž•›$ bô–è|§eSAÑpR£?!%r 15œ~p8À¾kò™´buØX÷¢Ñ¥cxdË#’¾|³½£çêÚ1·æ;½XY]éÜzFDÛÞÙÔbî ÷Š­ÖÈ$ß^N«]ïBÉÕ­½ÏŒ+ÓLD_-°ù8Ú…dËCOÐcý Í¾Ê }¬SCô½ÂíJwãë4C£><ßÿb@Ëÿ¿m —|¼œ7qúñõĸNÍÓÜ÷_~>ÆÒ›Ù.nIkâyî‹­jÂæ½ð^#ŠœZPS|;ÖBâóD.tt™Í½rFd¤_ûQç&åÉ‹NÜ{Ú£f¾äJ@³Æ¸Ìi×dØÇ–kÒ?ˆù€æð ?|¡«>wZ!¦L@¶£_ûªIùÈ ù:±ói*¢º»£Š9$}±ºRå0ØûMæîJÓøŒµ`/<Ü!ÔTu“>]–eÒ\u.{3Þd´íÎ ¸ãö®h¯Å ¼÷ªóºRô#ì_}ll/kžâ¡=q½§w˜ß«}~Bæ•QE_¾0ìaÛJ±µÛ@qð²ºiÌ{-+F{ÃÅÇ Çã=s‡•£b§qÃ3~¾ÝÓö=j‰s’f'›ãÿ`"÷õ6ß] )3 ­Å&pþa:n'åBe¦Î2/“üÛ`_]ÜJ8?NZÝm°\èðÔWàü~ À|×—@¯M *f—ŽCá}Y •¸’̓Ñ®¥îÙævÅcÌ›I¬‚À›=© UçlÂ6ĤÍ!JîLÑšsÝwµ§‹T}øìâÇób¥3/‚ÂÖæÈ—¢Ëçï4…ÉÁÕCyÏJÌlay÷Fý±R—LlÁùÆÂæ% w'K5`幈 [íÚeg-Ž+3wÛ3àùßj0·d³SðOåÕAP|Rè(`«ö¼õ†Í‡;öº¿¬Ò.?‹EX?¿ii>®FíÔòx÷àaÀµ5X)^úÍjÛ<áô:Ð~Ÿ QÎGN½ûűNÍT§Ø=Q°°[ÿïã¿@þ›Æs-K6{mTÜ3.Ðíê’Hp0n®âµy8ˆ/Þºl(Í‹°¿I®p2Q¡å¯?ÊîúàùV­¿øµí(ÅMvß2g,qЏ4xÀŠ ×ëö2º\0Uþ6¬Þå’jÌç% /jobE{æÞ$@Êì×}ÎÛǶ¼ðwoº…èƒl6ë—¤éÚGëØÿqfnÁ˜Žª;`Úrúu,ŒßgpâyA¢o›59;Ì媂˥Os<"4 2•Ý8ñ3ä¥bñåˆFÁ‘’÷7†¹¾ÑWv„djПF ú®ãe­ðÝÛ¤Æw–ŒX±~ÀÊÿŸ¶?IcÙ‡ýé)ü™fæ†s¦ñBª†ÂÈA£8›ý®ÞÐý¶þðÖÊ5ÈWŸ=&‹ÃVOò€}Û‚äצÊKðsõ&8¬ ª˜Bl’Çõ¼ÈÌ–K÷`öDµ‘Ž1 B»#”ݦMóï0Ÿ{$êÄèr•ï;DÄvr¶ÆvÔ¦Þž›0ƺàèYÆÜzÐýá/ ¢CìU~i.¢èö™‘v ƒF}/ׂ Ý·Ã6Ðu‚Å¥ª%‡x?–îtxWG d·IÒ*TÆÑ]•çDœê¢¿uªŠ"|™;_óH?2˜}âÔΠֹ•Lõ¨§úÁ‰a _‘Äk¬)zYõpÊÀÑpiÇëŒW‹á^¾¼ÕOoS›°jÁ×d„XEq`Ÿì&%ÿ“U»>ŸúµÚâ¼Ø=‹öär㸭ólýÝNã‚ÙIµLÍÜW¾S;é\¶°â9ñÀ<û¢ËuSÝ”ê ûWV+ü®iè_Éù`†·ßVÍK°›˜hpþ˜–G^{=ÙÓ¼Ía~Å ¹÷µÚ® á@Íg'/O„cÂêW¾œ.€ 7#P™½_6á]êÓá±£tÜõÕñ5c˜O¢ÚŽ›].Ùc­ׇc~Ñ3ÊNÁ;Åæ„ùq"’Af‚âÍpAøÊŽÌQ6ƒ…¯{²Òó_þ³÷>;n"÷ñJù¼6éÇl¸yÔv)À¦ÝWNgÎä–~dØ,‰ÅAþ‰_†/Qo^·ÅMF:O½§È_â rPD<=œ?XF j€ » l»$ íŸ4ÆEµâïãü§TˆA^ŠmÙMÄ­ÅÕLmçã‘_Ëâ3·¬-NôóìíDüZíÂ;mðå5ìÈ÷z83y¦:¸ž¹â9–ß_ÇAÓ„Ì9™°a…È×zpO¸ÿ¦Ó;[ÚAa;‘÷µ{yÅgX׿ðÉäµmu^‚,©Üy§¦ÿh®o£è³º¨Yàq·~jn$¿¤½›æ[ÚÌ=}ö=qŸ£“í=”²wÕ{Ð{-àÕb5ëID{<˜v›®˜·&r”}šèQf7 ÆWÏkG+J9¶ Ìdzì†OtqÕ9H0¸òÿo£šÇ÷OOáO´ƒü‰½¾Ÿ\atû §™·_!rà›nT8Äjk7X fÌ=¢1GÜÜÞŒJ~¼)l9Ú(‘<;æ"ß=ª~P¦±?É®©¶ÀbÄÈÀ€2†8\«vÒô[»QÇ7©apm¿ò €äÑ7”K6DÁ\Uíõ6¢<ÕéÃÝ#^?UÆplÑ?žï”aŸ‘ô±š¥¶± ±ùÅÇë*WY‚cM®Œ!íÍDý©©ÓîüÊl;=×þóXŸ¦Yüé Oõþã{§H:òÀÚ¥&mJàU%IæØT€)#;›àgÜ®Õ9 ã*7š€e†üà¹vŽ–¦S?Õ{ÖT@†B»ÂÀOÃø¦g³èÆU]æZ¯v ù¶p8Ó<´UÒ,¿OÃ]?4{@þÓGê§ÈÇHÇ–i(­4+èJ}uÞøŸG izÁ¨MÚ“ãüPÉûK²êûÔ=+ó•¹­þÂõBAl\ná!>âÞz“wîªö–7¿_ uN‰Ó$°Œðõ°?ìùbÛð±XìY@îÊøe¸¤6”fL±ƒxØãÝtRZ{Ü…¢À: o`N´žßË™j?žm!d,–!¯iªvÏË­±Ë8'–fþsØßý ©™û\a‘û<-Ø™ÎòÔµóv«Å½°™oç[š¤{å>z½[Uþ/ÿen—Ýúpožf®?=÷ñêqšø«å¯&ÈÎåíX¤¨æ û"ôÏSCé»dg}48%½ÊbM¶Ú¤[{»[šrNÖ<6m_Ɨ˶:/Øæ7æz±ap3gׇJVáÂ"ãs%~îqþ>þGöÊÀŒ*uÏí[EƒªÚ‹ìu&Y€¿0úª¸Røá4eopÈQüið´Ã&à³—M±„ ¨ùÚ$¡/YoŒsö›Üú>?w•Ø&ÓCF†\v}Ë:\„ìë÷ ›MÇŒz¯% "¼[è1R*wX*8ŸÜݬEãäLü4f‘ôÙ±ŸJNÁ4ü•G”ì[0‹|œ 옳Ý0rÂ5óGˆ>«Žu&Q/$6?-xÝ´qû¨aÓ¸k']lðssæ-÷Ãà×x‹Ð“9%e” wç}²@‹ ‹Ee˜[:xˆ¯õ͵ ÍߟÜT¿qïÀ”ÿ¼?m€þžfÂýÓSøßo¢´gïæËH¬Ã7»„-ƒ´¦B^µPE–ùŠýó¿6‚Õë1#¿ùHžøqÖÞó©U€'r—´op²ÔLÈlüœ§-,™§È³ß<êt–H«4 vž|»ré0°Z­Õó pf¢™Ëšð{0ºvœTå2ë#q—Ž©ì•þîi¥¾ Ç2<ãã\ÚQHÒO.ÓYgSƒ;Ÿž;ï|ùí¤ÇFÊ\’XÿÊúUÑhÕ0óârhø¸qIÅq+€=劅Ãï·ãÜ“}°üà5•{$¨B{µŸ—ârY­D7–H_›í)XJÍY‘-®“7oæÂìk¹G@ûkëÈÁCwAÚ §ÍjGA:&¤@iØ„t8ûðHÝ…ÅE‹VžÁ`’®4ì2.öOéJ7£]ï–_!¢5l÷x²­z oz*ë·l_¡ã­#ùÇ15°þ.EYq ÷ȲãhU­«.lÎÙt 9ôÈæÐœÂ¸ÇÀÒÔ·*\±7;ý”ï%ÔU\Š$Œ±éCaJA:ÌtùUvV¬œ‡Ñi‰)¾ƒÒ„Å`xÃíβS[éÁ*{·Î€€[RŠU‡ÖׂæÒrÖ©k…°…—ó—F7t¤Á^[,Þ3ìKK,¾ð[y]6H7=p<,^ ÊB3ça'R»y°¯^}Àó?«ó$Ë/nËÍB~zÊöR>ßÿe=Kö²£ý/¹ –„ª­&¬k¨ ûÇ;Í Á¾ÂÛÓD\ß 5ÉŸ‚àЃ…pÚÕÄ<ì3ëÓ‘ ˜5Vbé¦@÷µ‚C‰Ì¿ŽÿWúÉ¿Äüdz_? PWñ`wøÐa÷ËQåÕ…»ƒoÈDo™¯3Çp~7rö²,îδTÌ*ÖÈg GÔLPvqqi:;áU‰û–8“Øe``*˥ܮU ¾fµˆÝ™¨·[ô€@ر¤UÃkÿçm[dÄuªTáZ-I0|CÒ¿Ô0brEÞ?K¹”òª gö;„ç%Ú¼_䉼@ôõ©Zrᔘôò;][;€uWJC˜Æ¨õ}¬Ä2C6`ÂÚ" #ƒ»—ÿŒ*¸=Tµ RÊ‹¤æß7ÝâX:ÿ.žÐÃ&€\Õ KǪDùWüÓè/j8H`í°PwÑË&âí4:Ükxelg+ÕÅ¡œ7ª)MоÀNÜ;~”B÷³¦Â£¯¥ÅŠ:"7ýÄÙ-¡OS§ó˜úዞ}ëLtòd¤é{ ÿl¢_⊩­1KõÅ 0â9'ñVÊ駾Ğñ7DÅ¿Œç˜X—É«¢Ó+0–讀Fp/_äå½!`Ï‹¦ó[§‘ô›§Çx²§oÓº˜«ö:k†_–†ö[o%±g3ÒÎmõZGïpcXŸ{Pæøvn±i¨–ÀyÚë/jëº]gŒu6ðõ‰XIËc wÕ’‚ñB¥î€U< å,=§G<¦/ÐõhÀ×N¦/È“öϽ#t⟾êRž>DZŒkþA«;8Ž @´ìyuLEÖ,»i°»þë¾é‹ßkK\ œ$ß¶Ï{@Ùçs`3£(ˆÜu«ÚÁç¼3€ ç*›Tº9¢Ë/läFzιùCNÒy§Á:#²}h.2¶ËE•ÆêÌaã,™Rh’7õ6mMð*Øèyöšßê´@°* CGù ýܾn©ll×p_z;qߨ.ÜnðxÖ½ýa”¹îœÅâÓí–˰[cýêµƒÜÆÚËÂt1­ëjެy­ØÞÛ[¦p)\žÿâuËrŽÛ¸SÚ2àù?Ö¥Tvèðé…Wzè_QNñ†#BGª¼?{ãYCT•»Ò¤Ör_Zóå#G.1na3¼—töõÇú¾°_*å à’ w˜?Et)60b˜S¶Hóô¾/þëøÿ»üÖc";” ÆÏ}¯ßeŸµñ¦Áñ{çbïAµ=MaèGY€–‘¾³›,óws`sÂÂG¾/sš½ÀÍ.Ð7ÿ½fÔ7Ýûc„ô|# ËN¹{oT=»%NÁÎr-O.´Ièþ33»S@›ü¦z)”ŒÈ¶l¹_î 0'*4¾½q%IÿBÓ7Ü5ÖÆÛíÐÚ°r£Çº¬¥öTx /Iòe9Ýk<´úî‘·¾÷Ü®#4X$^ S…‡ë#úöwìºyªê>﬒i&oèýô­ƒž¦\…®q×'½UŠY;²4ñý…¸EÒÌÕs§†sØÑî³6MX6±ºhÛ†0¸žzÖ­µpæ¹ûƒª¦ÅG0‰sEξoç^•ˆu¨+Ï?˪;|ë\ú¦‹õ‚P9¨Üà5¾sž6á\ÝæïO§x/¬:èZ¥Ë{^¹Aa—_3 âB¿§>?$?UqÉZ͹U–Ӌަ\õúc û’~ÚÜí“ãy³ºa Wóš®f<êò*¼ OÊA¶–Os>¾“cQ3ªøÌf˜±a~ÿöHË—âÚkÜ„v7ºÖ”gãðý1^ï$* ‹¾°¿­àÐòúŠÇõÿòÿÁXû _̲37ÒŠSókÒ6Gφí›q±€k§{¬¼]# ç_N0?¢töÞÝ®4yý¯¯L½G 8ɾÆîŽwª5û1CΑ¡”j†;.Þɺ]4{/#{µð(ùÇÿ·ü.ÿ ®…€þîj|ïâMt%±X@Ká=î½ò4Z¿ßèJ¦ªæÏ²Nûåwàl$àiâfùF«½G¨»¼Ñ+]!] zí­-×FMK®ذȷ´pÊȽà|M¢Ôî4VÂÖý!?6þtŠ¡Òy·c©€?~ªx;hy3ÀñíE»D.Û¾lã"ús¯ž»N ÷öçeµø9Ñ'oOmgE~Þòá¹µJˆ¾dEP@+»98d;ý´w¾› ¸ïâ2×5ÅnnU’‹ºbe‡ó·à®ÙŠˆþ’έÁˆÿš‹«ëx]ý*µž×–ÎmoÓ ŸG 8ùÿÓè/kö^^z ÿ«íB‹Vg!2šNÂõâmìwæAC»YâÔt1€›ý „˲®p`ÏÞr¼Å¹›~ì^,âšœ©t]èë~uD®Më¦R!oHJVò1ÈX‘çªc[ôHÞbp&«Éªs:þÙáÁ%o÷ãë}¢|jÓꈺKõ·\’âtkæ[X«6 \æëîT¾3ãã¢ Þ Wº|&K!ú±Û‹vx*æE8Ø0¬ÇÊÉØÑæY›[ù{ÔZLN¸*·<×Xë3XæÖŒäÀˆÏÄ„¸C8ùÁàB›Ñ‡-Žfês¥wÍÚ{ q¾R¢ÿƒˆü¤d¿w\؉«ž°/‚J˜‹4 {y¡\‹s1L@´ò{R;À¾»"Pb¥p}ÒŘæ†mUL›«wq@ª•Å“"ÅÓDà‰}˜ƒB{˾ñ'2â³y×ì]¶œ©s÷.ú`éÜ9ýõ£‚L}]õ¶ôÕɳœ`ÿ0Jk^ë[•á6*!òá7Ý`Ãæ>ØÝ1: Æ>t‡éNÏåtwd –¯ððÛ:T©zÖ=¨Œ•xÔ%,Ÿ°H|Æi½C)ãÁUö‰®^!ºýÛFŸwjpfÔMXݹÿÃ[…ìh± |˜Ud“ô¬—`è’~™úp¶VÛJˆ~‡mÊ;¿6ÅýGŽèÌ‘‡­ ß .n=ëÌóÍdŒ>xœÈ÷8¢U LG/åBV$o°f\TÁlï MÚ‘1OΘ¤»—ضʸø†Þ€èo;'ð›Ä^1ÏYž°^^ÖœØýæSg}=/€«¼\j€ÉÿŸ¶?_³ ãüé)ü/¶Mbvü|”Θh”’Vµq¸Êœ2oË I³âï;â—¹U0“Ø{ù¥'G9"‰ÐØ<Ë0–ÞùvÀ J–%³J>áªÄœ‹ßƒ3p;ðÝ“g3“06âãù³eZ¨£Åˆ/i—…î!öโr<ýyÞ’ —`ýÆkA”VÀÕBZ(ìQ®cHúãW0G°RöL8)v*;âÚóä21Ïòý±»m·mÜF^ŒÇëD—Šÿ¸vð_â§ äý·ú-ñ›L³»öè hu–|Tàíì¾h¸¢ßܘ„+sí¿”ŽV¸ –Ÿ ÕêÛö<%%^Dépp÷•{¤ˆKþ؉Ö·ðœϰú×=8qÁlb`›¸§c†ˆÕûåKÒG™šFXy¸ø»_[ØL@ÖíÕýÛþi„C¤Ý +~~>h¥³ýÛo} ÊfÄ.­Ä´4ÞÁcÖvCÀ^ÓfƒUMû]И<Ö2î¯Q‹;%ùõÍ öÞǯZ11—þŒ½Æål3²‘±Mîüº˜nÚ»˜_ ²s,²È(šu#|åhUàœžwÊ¡àIþÝcv1n &«7¤[OLÞ{p9pO¡CíÎÓÐ6Ó|ݺáÌioá­k£E¤üx!ZÕÊÍÊ­ñAÀ+ÆÀϵÂëÖÁ‘"Ë<ÿ½w¨Å?“¸bj2²3âiçA¢Î¶|7óÒ–”JÛ(á%rÁÕW@{kdQ¨K¹,lå,YÀsF^¨ð’%@Oâv%}M>2ú²À¾3æ$TOþÛøïòŸò¿¨ÔË(»hß^ìŠ8ZÿìAKì#Ïlȹ~^üø­-/#Í/«DÜC˜½2nãŽg-\$ÿªLÄqͧç*{ňÔÍ(z½mr„p-Ò3¬NËkü˜¦I€‰å,|ºTá |ytŠ,gWвöú ]¾bm£$2±Œ¥zw3Iú·Vƒ|%Úÿª²<ßÁçó" 9ûl܉—Q¯uÛc}úè:·,NÉJÑåXþuÀŠ¢nA»ŠÎõšâb€umÉ 2µYÏ_K5ø|øn„蟣­ŠÁµÖú ºcœ4 ¢‚„«ÌoçN‚¡Jk;Š,PòŸù§ Ðß×0ëˆ?=…ÿ½ö¸ˆUý¶²”¬ÞUÙ™¾œã\¯4¼«Ì®Fðfö/BmTYP5—Å>Ží•\« ÚÁaþ‹ û ¡¬Ÿ”-!V0ö´'íŸPÞêì@ì8v)äÔ0éÀ:ØX2'ƒ×´}kRõ‡¹€«í|ì*ÁÛ²€€$ƒ ѸW.¾Hh†|½U»wÎ`°Ÿü$8ä*¼K&êVô·Dg?¬Q%@yÉ{Î=GSx]¦3‘s~<çM©_÷+‡á匳{¦ò¶¨šµËBó#_ < c‘“T`]Lõn-0=6çƒZºªèlúÎÇ„‹Ôv z8KÆ\ÜõN·T–{Ôf0²3Áaäú!ág„õ Õ–hý—ŸÎU÷ •eÈ+ ªö€U…‡OÇÇG,|¸jòÁ;3Žpóu;Jöœ¥æ K¬Pì@ðÞ-ÐI³ñ†:Xö£H vßóÜ Ó&šÈu‹¶y ïÐä<(®J OžRùü¨bÙµâ–Ïè‰ìòÉ+¬_² mÆî8ëÝ@Ô­hN\l. ø¨±N´µNñÛê¤y„[|Úz'Þàç©sêÎfãÓx=ßøëÊ÷v‰Ý—éN°oq'çP¬¦õ iסô}±K|;Úšç]û+V Ä>4ÙÙ±JD²ó´€^öfÔµâ_H“ÚLyÛz7¨h fžÿÓ™)ÙÊW§M'–½àÀ5Ñ3\€ÕRs|Aµ]‡K|Õ6½¹þú×ãkwÞØXÇ“é=©&Å‚óK£þ!Ç­ü}P!¬<ÿa|®ÉðÅÀ- ¥ûÙòÐÂÿëÿ›ü—žº/ò¦”€ hý㉫õpýÆÅ‹/»s¿êàõpXÆÉ`²ÿÙ뢀=pqœ|*mz¦7¨ß -˜å¢TÃÑ X,}}P¤É ˜{Ô¤œfµÐ«Î¬Þ °”Vc;’;ÁšǶD§æ»æ<¸°ß÷ÊTzâa80Æ¢;ÚôW›Gù-»BÒ¯o>:!íÿ°_U2ÜoN¤z7ø¯ø2k^z¢ïôm¤Í1ä9Jz>­ÜuÅXº›ß"AU‹¢§q™Ìx空•àÀ…Òøç0þWµª­†Xú“®ÇMšÑü%¾ÂÏ+ÂoÿÚ12iêaôܼJ>ÿHþ=ÿ´ú›#ðOOá«UßÍvñJÆøã3žVáÓ+“påÊ+1Òצ<›rÎ:ðI y ¬H3®vçVo`70î™ì‹Ëd& oéHþé@+mMrxWïÿ’À·Ç$Œ½oˆµûáıNÝ¢Í10)»yíÚ³jO€‘`óvŠ4öºÉ1Ïϰ¢-8ìÖ]9 XÇg×íÎ̪$€5FU2ˆ>&òQó Ìrn³OÏlÀû˜'³¢ëšF„±ßNÞ—îƒË„KmÜÍÝ‹žÍ¹ 0*CÚv£Á§õà±5Á“áôp¦f¦zëIJp´â$À‚W:ÙŒ„ð‰1¬éÄ‘äcþÀZv‘Ç.žµÀfxÇç¨ùC?¢õ+¡¡ØFImß¹ðlz»¿ð,—¯«+÷?{î;îÂaRðÅ£ %á,í³Àx4‘7tïÒ֊㦣Nç~½ï»Š·ð×èÃ{¶Ü{8Ù³qÒ¨ÆÈŽŸÊÙÉï%Öµ2² n–ës3\n¨IkŸE_P<^˜ÉÔL‰e…lNìzË}XkŨ¹•âÁM_¹;O¤?Iñí‚åÞ0D=wÝîêò¢CðcÏÔœ»¼ ÒbÌ.ªë)OÈüéâcä¸Úsßî/pôëñ—V³Ç {÷jGfá>­`2"]KÕ¢jÅ0ÉìB\åÆ¿ü÷¶øJÛ¹>V»»øiú÷Q'Žg`õ¹ýqÁP.å˜Ë‚G‡OÄÕ*ÈÀõµ‘9ƒF‰çˆ»«º®Áñ¦ÙÖ-9ªÎ÷#vúÑiû”~kªVHQåÔüKlþ6þ×þWùW‰8‹· 8XÓ”¬=¹ö;À"ä£AÅýø``Y®ú*Øwi>àŽyÕjVú@ÏJÒ(ŸÚ ×?Tÿøªˆ`†ë\9¡Ÿûó,àòt8ì8³tÀ¸}·T[ÓxÀžßö5å.}Á#žf²Tú`]—6³`Úäø’Ñè÷ Ñg·…„~€'éß/±>œ<ð:¯xÒÉg–'±®Ý¸pÑß)öøS…Ùnø˜W3Ê?ÕaSƒ#8lœ3ÉÑ™¦Ó(ùØýâÅkWl}ªaÜqlô¬“N¼#á ƒ ÛÎðd2µ&›_—N¯ý¥Œž¥[Gþî/ßþ›­ŸÇŸžÂÿN›É`´›¬ó¿º|Ìp‹;ûXrq×iû!XìrýZýÊ#®l<@¹^§QålÀf¡Ä{§oüxÎÖ‘ʥᛒÔ!7{‚÷/a`ª±'O Ó„ çêÆÛ³$Vû…ƒóÝ–Ì„5eS“’@t‹¤9À² íó@o~Ñ='KD?CÛàŠºtÄ9€…]îwfqûEÜÍ ’ÂwNª4|cÑ|Cv»ï‰¶6 ¬ö®ã0Íy`”v_†—"Žy°ìŠks£ù¡Ãõ;ÞÚÇûî†÷ÖÞ³¿Ô0¸ÄO¨ÞZðp*ÓЮgJîyWR?Je¿¯‘Ý=z6¼œ¿*- wE<¸Í{:v¯DÿˆÜX³@š_%5Hwdz5í5Ýpp„½ÑÀHúd¦íC° ¹´Ñ>hóQ ¤nÔ6­¶=°ÞÆÕ¼™y¾é%Ü‘½èlÇÖ¦¨ª¸¹NFZ¹rÿúæì¬eJã©Ìïñ­ÿò¿"qâÄg·¾åyCçÍuÝ^§¾Ü\’£"ì¸D¼Œødñ&eÅNÄ+’€{…á›ö q.ä©¶Çl½àÇê+ßý¦EUÌ®]ߺ䭲©ÆÖUº°îò߯ÿÿIþ­1»?î¹-ïÓ9Ô 1Ó}£æòÂŽÓ_•ˆñ\òYØýRülõ]u¾Ý˜TíUid Ì—ëï•ß½@¸2Ï‘·¾U—€¹Úd@¤& <T/û‚ËE6 ­°ã¼w‰&>‰?Cö¹Ñò½zþ(2Ë”ã"ú¥Ë/¨¨,EB8!.LíÔçg“rš*ÜW{€(Bô—ÐŽð@õÃsÃ^ Ünµ•‚íŽôIJÅë}ù­ÇÀ(Èâã»3ÕÄÓáCºwÁÙ.'C¦Í8—-4Æl€¯æCŽâœÄ”g{ñT`*T ùÿÓöç¯mä'C5@1:ÊâÑwÜ_Œ!鯯ÊçIvœÞäθ°¼^ÍþÖ´ ` 7]K›£‚œsó¹F™º› |±ØouÓû~@?¿?bå­ô’Ãîþ`ì³fq¤D±ý@Õ6ÈŠAÚµ­3Véç”’´³º&¯^—õVçÎhl½Ö¥½€×ÛXjÄË©ìqyfÕˆ¾×ÛT×q]ÃþBöT;ß–A¬Da¯jÀgÍÔ¶’Œþµ)’¿Ù}à ú¿{ù/ ãm7«™¯¤xÑÜŽð@øZmð4 ëÔ‚r3TÁͧàýXµ&UriÊÙÝÜ®­Ë|Á¢ÍO‚†¿¸6¸\5:Ûyõ‹©'ÚÞò}m·›0¦*½VL ’³¡Ù€}¸¿€e8~Ï—¬‚#éS7],–òº4H†øÏÜL;´ýòÁS`–¿=v®©Gêlˆw'8ÜKGx¦j;@ý³{0¤yZ·)†‚ªFÝqøâ9ÑœÕX¿·ÁÑ)èý²áãüPÞÃbvîCB¡–.h¹[ýb4³Z:ÒxLé¼»Gìƒ4SB¡>nŒ˜6?+ÀqÉÇÔ Âêðvê£ÆS¢BãKöËi/£IäÝZ$­Œíy ® Ñ6ÛpˆsÞ·6îìù(pö" Öïkíܼ«Ú×Ôd±T+½ÞxþGÒÂí„Db×Ç€véÌ›€KZ¦=†XW®ÔƒY{ÕÇl›“u¦>¡Ã„tfºûìØZìr"§¦&ÃD§«ÙcåÔ0º7€Ï¤g­²LAŒñõ/ãÿôÿQþ Ö»»øÛÚOX¥w Xo:Ž) {éó Ö_O]š^[ÅSs²˜#ËÓíÃÀ™íîs0¿ÅTŠÇ¬nÃRœ‘1#špè˜2¯xœ3â:ÓßùK³ß‡¹N¶±Ð<Î0%ŸÞ®=¯kx–Û2Œ|'Ñ{‹›%KgÕÇàâp+|vè…å1ôŸ•2ã—–Þo$5R'ºKwó}‰:&#g‘å—$ÝNix½§¹‰&Ö©;‰¤ðTmÕ-p[R¸ð ÙKÓ½d{Ô}é¨MV¡p$'k¢OÐçç qåÚû¬tgKt{á‰è+Ï_jûv`È¿æŸ6@¶á0 ¬üÿÜ\<Ð&hpr#È K¨·Ñû!μ¬¸‚¯©žüW½_&x…ÑœƒyÿÛ õüíÆIj}~#€ógâÂó|Ó3 Á-l‹`o>Nß$¨ ¦o}ôO¿Å&Šó»òGta¶û *ŽèëÈ¿™ß'ú¨ Þ‘sĬÂÑ•Æöý­c1Á-¿]l¹èÕÓ \ ç ™cä[–;ð_±€K`ä„1Æaóp4=wÀƒœÍáàl.Æe¡‹náè¹2ª›KàvAˆ&a<Àé,_Œ‹cjDr1èÊ"8tÔ›l@c“ËA¢Þlú·6Èèü?G }Äp@û†3ÝÑÃS0rÓ0 w†ÚT -šd¢‰8á†ùR¬@±”º ƇêJ2ÏN ÞÚr¸À6;ðò?σ‡\(¹~r×0r•äá$}òCD™¤E¶e9 ò 4$AÎuÁ¸ª#`‚ŽˆÿN!} m<¹·6!$+8ˆuÔÓÉ7šÿÝûwÄpÒ]£…#þ£}ß`S~ŸQ¤1$H7€òpÄô¥®óÀ–ÿø“·ÿhÛ`²·ÅíQÚdëÃ|½P®Lã ð„þ²ñ_^átÇNŸæfº”{?+ÑÏÄôN î±­"‰~¤PŽáìÞ¿c/A’ nÊ!ú£Füw3½â„-ˆ|ËÜíþÛ79‡B‚^÷žFðìB8=¶‘RxŠø 9C–[K+=€K°z !u'éî“Ii7Ò| ÕÈ%U/×Õƒ°Œ$ñ$Á¡¤›rü1.›êM¾ u©ŒÈ¯Éa‘H[†sqjX`S: sy”‚å’¸€2rÜ ô#ÚeÍùŸïÎÇühI3ÈF*—Ëö³C2¥E¢]ðŸŒðnO€Rá”™êBðÉÿÍ!ÿÙìm Ñh)óÈñá?ó#Úéƒn¹~OÒˆÚcÑ&×Iˆó;â8͉ä? V)sEñ_€ÆÉ]Ä{A=Xœ %PôùN²Š˜U¤þSq *Bl&â?Î PÉIPÛCqÐ*”?>øÛJr‰#p(f’žÆAü'YÆØ: å uÿŸÚ@ö˜íL÷ëQß½ ¨m都²ÀW©~\Á+ªõ þ+ô|Ó\ý\ÁÍ.ôÚ7[Wz×yÄ?„½wÄ~‚ÝÏ©·¥‘Qà¾Ð_ߌ¨K?HÐû± G×ÿ ¹N¤ù¶‚ |wŸÆqäÅ“ãæêOÐhD¯B ©ò¨7‹T ¤ù!p»@òkt6±œ‚‘OOj‘÷OHâf‘$¶B ĤÓOš6©(pWíù(Ó@¢FdØÒ‘!œϧ‚âdl›üšDú¸[$ô›@E¥Ñ8TWAÔŸÍC4(EÅ („çÂÕú ù“òÚŸœ-i]ÉHn ;)(MAS¾åD†ÇHdíàÇ#£A¢@`´¹=îBØ4W_/‚‚Ûå]à.<r'©q.•èËàßîACüGw ¢ä¶’~E(¹¸žŽ‚ôÞc♎¡‚ø?¹"~üŸÜ ‚ Np(¦²Éyã.Œ ÒsÀ7í-ÿÿ¶ì0ÉgÓò@ï?‘%^½º÷ø³ 'zíÞÿ¿#Ó•ãÃý}DÜ2T@¥×rôÁ¿ß"Ã}†ÄÉÓ½§‹ ÌK¦mûwÄûHÊØ00oøøïoi`~”ÏÍ5¸GJ-!.ºŸ°÷E”û€}’LÍÕ†~”øÐ_¿ÔùA¸žóyžêB©!J °{ìßh TƒUzçìåοicÙy>þü)¨‰ìÛÍ›T„dÌšÄ ló&ú#zC¢¤40® HÆ©a©8®¥Ñ€çÂQèÍ)÷`~ AQÙ}tAn_ðGüç¢Ìl~ü¹çFŠQüH€à"@czöÿòŽŸÓäùû²ûl ESöŠï 8±³­Â‘Y HŒÿŠÜ 0?`L7Äþ8Á`¡îe†¨|éb~S¯u§z£áÏ„+pò$c=Q²#â?ô¤úê&ž,@üï+'”n†þñ7× ŠÍn¹oÀÊÿÿ=Kòÿé6`&ù<¾ò‰ß59pƒþúú7¸…üPšUè—ìêÑÊ O¾’ï—ÆìC(¡ùOµß+9}‘a¾[ ÊÍz ¨#×—ÓX ~ä§ŽÞî= ý¯i`J“H½â¹ ÷ψôSüzƒ=ûàäÁ¡ù÷Ïö]þ™ìUnºqÇ8üp(ÂJüš)’®þ÷ʇŸ†dù\ð³ûYÞGð-7à6êÌp à àä`5=œzE†;öž¤¥ïÑG¦È>„C¡k‚ŸLÅ“Àžïˆ•|:-¹ü(¿.íÄõå’Ãöčܸïeˆÿ|£·h@`óWDz,.Í%¤'eئ+ÿÿ6ª P€)xh™ÛÃûc¾þðïw|×kÀçÁÿïÍ…õk¹¹rÿÑ%é0~Ð/±ÜWõÝ£öuÛý¾aÛ…õªiôðÛyùöóËûç‹ûF$Á鿞 öÆÝ‚9}÷1´rxX¯ éçù÷ÝÒOœi¸¸òÜû:öGÞ?+ØWº¾-%ˆáGAÊÓ§´XoÖ¸ÇhUR8©sæ—ðZGò+†HaÇ©²)‚_²#’qŒÍò¦2‡Š ø5ÂVá8ùühC˜¸‡ ÈW¤®á# vOÁsË¿ü?Ç£"ÃÔY€ž¤1Ô¤“ùÇøq:Å^_GAy9ÑE ²å2ôø €iþ}üÇ{åÿd!¨è§<£Q1$Ó@:OTG@üçð#ú½ÁÒh!þ“Ëzp9iÝ1~þTý ¾AûÙ…÷Eÿ=ÈÊ;6‡ÍIô”üûØVa¿•ônÅLZ0…º©xNß60åÿ_ · H€IºÿÔ#î¼ûŒwO1u¯j¦Ú?áŸé?ùÔÅõji`:ó|¸ýÀa߈Ž^= òJü÷¤YO9Yn†ùôjr¶u ÷f×þCÅ35ê=(²D+МCúƒÝnàeqðßåzF@Lóc¸!¸m·ÇóïëÝ¿Xˆ¬W%ìr+ =={q"O`|© ^Rs±É€%™/&y'.Uõ‹»!]CZF*Ë…žÒ_´C¤¾ÆÇðµ0Á?„´"‹Ë"ë“‘{¦ÁB Ò:¨'Hž¢â‘P‚¬#¦y#™9tÞ1àùïu–ƒõ–’Æ?þÏåè‰ à × Bp°‘ß‘ Ï’*¶'»Kêt2΢.\²êz·Ó_Çv?ùÏöæçùIëÔ‘>àƒs´*Áñ*zMΛ2ȈÿÔÄ >ŠG÷PÕühÊL'w Àó«Q2$âèå‰ñÁ9N‚TBpê€àð²Üùôù‚|_Ì ó!vž VÞl~\øqA¢÷ AÑw ¢1”#&ð zËØäfà4ç`noˆ†Ëæ:ïˆòß+äÿ¶é0ûÕn™Îæõb>Rz‘^o^럽ضaD_Ywï«ÞðïÁޏE8§¿Úç‹AüÞ»§BLPnæËèy†Mˆ'ôÉb¿¼/üþ–NÕ¨ÿ×40lºSHoü—ßÑô0$‡öÙ”~5?}¹@Áâ –cpßúûÀÁ?¢~ÿøÐnï9™Eq{ê}6'ó¦ìH€óóƒéCi.¤¯| „‹¨ÃªËâBOçQ5g¿]xT>F†F9ÓS ÁqkŒ2Hd.Ä|Ìej2àù2 ¹ØpÊ÷øÖ…§ü“Úˆÿ$$cÛ…qøçʰ^Ï__&8 Ø?€Ûéýuüÿ]þóÜù©zó|ÃJV“ l1P9cró¨J?rÕ,ÄÿÞš¿Þr;É~èívO•¿r³#×ÐS‰¿Uýc=5=çøNƒƒ/š.÷Ö¡ž¤/·íýP&žÿ ä[Ñkgp»§¦€Íÿ#þóÁ7Á÷vôü<ùÿi>þÖžÀìÑö6ÿ4Áüó ”mo¾–èÙ*ô”ö%qA®XtZz?ûLj,Ç â¿ëéõ ÀY„óÓÀt‡ ~йÇsÅá·™õ¥qûîÿ)þëæÊég•¨<òV€L/áéèõÈ~º³ ã/‡Áôý-ô‡õ€ÀòB×ÉôAš î J“p¢ç‡b¸=d$žä×qÉ(UõKÆd-"øÒS3!¨£ôlê<NXF&(¢Aªq´~‚_õ‹ÖëÈ?]EÚÁ ²þ—Gn¿ˆ.°6ÿËÿ/œ #ˆÿ½Ù}þÇeFÕ pÿ{Ôa®ÿ< (8é8Fßö×ñÿ]þƒÓ¨Óe8ðí.óS ~ðËôú*ýpÓïù1jTñï9/ÈOñ JòÐ2Nü}+èW@ˆ ò¿ýê “Íé EÄÿ@Oо Q€ <àÿlAßþ`Àãÿ¬Sï1@Á¯Pe¸‹k(•ªáÇÿùµNþÿÿÿÞšÀì§ÝÑóÀÔ>ÜO‘­?üûGx˜ºÏɳçÿJè…LŽ/÷û†Á8t¶OÏÀÿ‚¿‡uû¼LgÊhÐÜ‚¸ýÃÊ}–C°„þi`›Pâ7« •|ÓAwåö‘ÜG×Èåþ3þ× „ûê‚0kòçI¨—ä¯Îôtì—9Äz³ËÿO{×ÖÛÄ…ÿŠª‚Ô<õ¡R$;ÄNìØ»;;—Ýø’» A@…úÔ‹¨„ÚRÁ¿ëœÛ̬ªÒ§¨‹¬ØïÅÇsΜïœï›ð¤ï¼~…ûXÍBg¸³©PŒ¦)nÒ3˜Õè×( α’ ‘2˜âè)ÊŽkÎ ´å ø—Zu.óë/*÷QÚ{æò Ú`UQdK©”?z~ç³ýßW þïG`ÑÛP!»Í4Éà3p;¨'ŽXP¶e@n=ÝØ£}ëÆÙcþÿº¢y$èϘdQ ¨¥%°7›¤¿?Ø3\C‚yyÔòaØeêD¢4Ý?ÓMÊŠi€ L]„™¿†±·?¢\(xAh€iÿê>E‰›&þËX¼€ýñWoy±yüEËæÿÿóG»V™I~æðkîm½†i“:iújš`.ºSÓ}*Ž•ÁÛ¼·˜4û²ÖÅߟK¼“pV×è#~ÝØ¡›}X,6éßñ¥T­ù‚³ñ¹ˆ°.øoïb ÿŽ-sñc"¶ ýÑS~,©dÙ¹pä IÂ5âÓvçCEǽ'†á%Ž!}BæóHôJšRK0±†nÊZ`%ñÎk¦ëÎ… ¬  ÁtØ zpÁµéŸ@°C.±8o'"º˜óéÞƒÖÛÿùë: ª;Óߪ`Hõ§ìÏ+I7Ñϲâ\@ýúO F?|tÓìŸoÎÿ?§‡)4Qg:Ià(üµ "¶BÒ}ZQ÷ŸíÑþ8ûò¢° ãïÆìŸN(¸7i€ `IËÈ^ƒý‘£¡éü¼ÿË"õ <&6³$•[ÍŒíþ¼â¿Ê,j¿‡lR¼|rfçràõÑÍ€ìQìL®R½Ak¸xz©öÏMƒF(Û»¬øÎãqèszô•.-R@âùhäŽ@u&í7‹™õ–Áu÷â'ËÒð AVžZ¦i™EbБ ^l–(ìE-AP´ÔùÑR'¢àäU‹Ã…]PjæŠ4 f}PÝQ+p€@¢ÝÀJd¡>­ô–ü¼1ƒ/?ÛÿSÒãΘ@²$°Î‡gð”IVÝŸMDh€¢è*\@ÿd·ošý?6ÿ[p¦è!‘Ý—4bÏjëþÜQ¡@³ýa û‚°_C#È%#7Ǽ\6ÿÁ,ž%qM¢,ÝN;Óg.•$`é!#4ÀâÑôð²Ø_™ÿ1§lï”$ÿg1>‡ù¸QÙ½¶ÌÿÅ…Ö?Z²ÈMêÒ%Ó+íÞÃß×½BÚýe7ßT»Ï(³S££eæaã$„0k:(æÞ ©;q†Î’uÏóÉÄløýP6i‰W^Ž‹S9a’±>¾¬ÖWöæë>4/_¸µ5*¦h¸¾7 79‹£SÈPÞÜùö=³{ˆ´·ª¥GÜÏHøndP,ìuWUª ŽgNÚ}Pœ(ÁêpAË}g¤©¨€ê ¥ÝÀ²bZ›á¶Þç4ÖDXÜ,òZº½­ÖÛÿõ‹ˆ su?‘(½ýeg`äkë¢{Y%4@Ôh&+‚•I»uç›fÿò£óÿ¯ckú ÅŽÿåå@2gI}wEµx5~_#þuD¬€ª „@UUM}€6­T%Ü™ÚÁAÏ7ï€ýqÝeˆÈ‹ÖÆ.A¤XàÏïO (Â8{bCtü´ærÿÇ6:¿žîV;æÿß´~Þ+°tPxœì} \M[û¿)!Ëœ!”ŒÑ@!e(T•±"¥yžNgÚÏ>çT§yˆæÒ ‘¡’J…Š(S)‘ÈЀBå¿ö>§Áý½ÿ÷½ïÿó{ÿ×ëZ×Ýv{¯½žµÖ³žáû¬geü.ÿ¸0lÂþê.ü(£?FWãËÂ&;ÈÚ?dªGnMšØèÂᦇÉZ;^¡*7ƪ9 ±>ŽjÇ?Š:p[-öeľq‚6>óf?—x¶Ïgý0yÐ3³•±4üÑúöã#ÝU—´ŠOzæâ€¡ »âç;”m‡A¢}̽s§{· gøfE3û‡GîÆ5Æw«ÊQäÞ”sÕuÎ󲿯ŒûìÙÓ·ã´ô7E ­$èç…–¾¯g‰C™Ë¢€µv——7î!β9žŠÈ;IT€w{Õå뺉ûŒ¬Y®i0eÔ2jŒÂ±3¶+ïÊæ‡ƒ©Á¾û>`¬Sw¸Hðìî M®ˆ~ô† DZ'á蔃E‡G ±ØñÊñVû8 6œWÎt`´‡õ<ªØý(µÍ¡ÊGËcûì&óÊaÕ³‡úu³GˆÛeïð­·"5uU]Þ¾ìJ³é¥¨‹C¾Ìß7Ô-òYwÀ†Å¹‹ß\5õÉë7nÌÛžÆ.Xå r+¾Ä =C€Ái÷áöI ýÕMŽ6¨¦ézŸ±ß$; î]2}gp’·}rVXÆhøVi8ºtÞB±gBÉnÕpî %l9º ~Ê`X–’ºÛµýŽÄ–’üõTn? ôòÕLÃYïûC‹÷%64” ‰º1OK¥­¼¡ @nÑlêÔUÍ>E#ÖËÿíùŸ0¾¼p‹änÇS_Î@ãZ¬'ºæQÆB–ó,˜¸/‹¬lpÏ•j“5.lk›þÃaÒ{š~#5Ç!ìÎۅ˦ԬÒq:øÀòËôŸŒÿÂÿDþYL(¬wU_èØ Êr›ºÔ¸mª­ZýUãŠ.S ËRnÌ$[÷p€ר;Ÿ¤ôG®‚•fÌ%âb›V ŠBÃËfÛUßy pø]¢¢ºÔ àÔÅü®à`æýA f6ξ7cŒ¹y{bŒ -`Ñl€Öm¥çâæ@wñ U^0Õ±þTmÂã@À˜kè/e«¢ L§+ì®è¿|š¿ÙÑWNwDô’>}iPhÓæóúÁãU‚ ï¼U)K6@¯ãnÞ(…ªÜTáY3?Ø.<7R$tîµ< ¢0s{þƒe2×eý57]p´þÿòÿÿ68ÿEÅ™é÷Wwá?^öûÎôDÏ:³KíAeÕ\OpkR3ùiÎè Æž¬!LÛ¬³’8dºíf´n4R9£¦€MÙ5a[.åõxolÿÏ‹Î2_†3eã—¡ÎÊ뾦 Ù—xÙ}§ÆWp̭ܳˆåÒ:‰k†‹Üο&¡ÐÅå)“n‚³å§Î¥ÙϺEP~øÚ K}Ü÷55Э]È×áÎ|N`ïšGÄ5,ïˆ8*|Áwhyæ‚h˜² öÜ-{§ŸŒèëøà&`~ú”ó°ÞÐñ>X–Ç/x9ÌÁÑËB}0…Š£¼ÁµU÷VÓP—¢Ó3f…|Ë;F1{54eÁH]W(-lBã×*áøºT ²}ý=EµÝŒ1ÂÍ[ÛÆ”@¦S[`ãÐò+ÃM›GNÀD63Å9YV‰+|ÁP`D”3¯®…M_<-ŠhÂtü噼\õãM¸ÓÝ©CFÒ[Çâó^`LkÂÓIvë,éC&ÞÏP»1ÿ˜òW‰XÊàIRe`q-}>ØŒþ©Wz˜ã§Fï¼öþq³áÈS¹cŠ} Ç€Ú¹}#A¾z¡r‹ã¥æW@1áFY«Íœ£°U]©2 {J˜ãŸ'¥~/¬‰kj¦ÉË™öGüÌAvš“Lô]ñÈk ±‡äºApbê˜-º¡Õ5w‘Ð6šzyØÙ>àT0W{jÛŒéÑ £¸ßü|oâ"ÿ ÆÚ¹K$);oä:ôôâ~î©Ã§„Âú|Ãx`øM¯á€zÑÉÍ–‹†ÆoÄâ?ÅÝ´3t‘µJSy»œš£|^hñ’aïâïD‹üdüßôÏä‚ÛØeXX<c©Ÿin»4‚k`ÿÁõR¾Óý/)a+«õôÊqhæ0Kæ"uÁ ßE»²½gÛ‹ùkNáö9[üµ O¾­úÝqqb¯IÈPÓZöt©Ær  žº»éQa¼ Ö·º¨s*P3=^ó:°ú÷º]¦ÀóÛ„°$¥Hñ(K¡  WráTe¾r8×X Œóv¿ û9ÈÏsJëykŒè3†¬_ ö97¾~çï¤T:ù–L@ÛråÈXmš°Ô{þrPjêz pàâ©U`{Vtñ÷`Dß³U­ÿÒ5ù7ÿ« ÐO]¬9uþÃeJ@ð׎½¥{§¾ñ‡)¾ÀlÚèÌ} zp(Žæ™=ü‚\"ÀDßá}ó¿xYØmcrˆ +ܯH´+ ,ôcÛ8Ä ù<÷¤eH¾þº,Ë,ìY•w<Æ9©ú8ÍËtœòÐ]~$°íŽgoöþ@8›Q©eUð¦êPUtKkJú7"k;‹éuߟëaNÔ‘–gëá„\âú-W•˜š²,ϽM èÞÞŠè—Ÿ»v\AkqVM$x¤l¬ì¹{@†zŠT×Ó5þåÚõˆÎž‘p_D¿yY¯;ܼ¢ýá°F¨LÝqÆ‚óO’¾vЧë.øŽß‰Fô¿ú>Ú¬:™Ø=ç… Òn§!ŲnèüVdÛeƒqc·?¨£Ä”;ßo™·ÀÏæ„zfO_™Gƒ3.S¦ø±îòeÃ÷»”dl}jEÏDÙŸfµGvºР€Y4­5β0yæ7P]Ò” ÔÝ Û­|Ç1¾íß›`àšµÌ#†k-›ÎøN˜ rB¦§Ñ¥à¬àÙ–pçz„>Ÿi¾ú²EÑÚë`lŸ®‘xïÁØMã»Áè™Ñ 7£>áZxìÛ;ùË´qAÞ>Ü[dÒØp¨Aóœª=;Mf“žª’ Ûµ=nØ´ 2QËî(ÇÄI¼ÛoþÎb”­%ÁÝtƒ§¸nëûa…iC”i?/°8òeº9ì·œ; [gk:xA±€{åb€QÔOÛ^Miëd`šÓ{„çþdüOüçòŸ¡Æµ´²-èÞ'}~ðÓ Ý‚îÆø)J“>Uœ}pÿNŒ5€‰Ð8í±GlÚ2 uâ·’Eç&ÎÃa†Ð¨ŠóôЛ¸Py5úx‡.—3^îÕ"X“órd”¬òh(|oPG”R(‘ÕÁHÛ{{o:²Ô.o ͆¶"¼Ý»bÞäïÉ¡\F'œ‘‰èLSpÞŽL˜áRëú4˜–G1åÿ¹sÒ÷eK}fï•]ˆþñì!iP! õâ`n-¬'‰Çe•ŸOy# §ê–y¿.àÄ«‚³ˆþÁ Zj1qÓÖ$ýòò?ú¯6@?wÁ,"þê.üg‹aûx.ÐêÎoz°æ+Zî«?<¾`Ñ$ív[|TÇ®S„ƒ FzTP_Mô×£• iÇ%9•ôi$^>ñ 9±¬½¾ŸF³@±ûöÈ »'x=ùñ•´`¡’b°˜qfìB¸ºÝ ð÷½òq‹¯BP¨hÆ×öq–³zîÆq|ãÅ¢7¬Vü†TŒ–S{ð“Xªîº³ì:Ó÷kËuŒóÔ©?X¼%áçv)upû)6' Ñw=´Ðÿ €ÍÛäy{;Çz($÷ ¤—Y§Å,¼ß~]x2XäÆ ËáΊLp‹a}™æzcÕÁdpmnŽ =š´>ÿí×$‹ð™»}±¹«¸0¸dF£’ü!ø~&¥S„³êë8Oxðát˜#Ýå`*çå) MÜâ÷‡Ÿ‰píØ;õºïG  …ކÉM§ì˜à¨óz…6sÊà‹pÓ>}2Hu:XË»¶ }`mÚ'%Çzþâƒ"×eÆŒþÕwTŸT9]!°±‹y b¹[Úw·mŠ\è87ãÒÙÅ ›n)]Ìs¡Ý@á7­ÖÐïâSí9í‰[‡Ý^—ºK¡ùéוö!WásOàuéTÙÈ ðÚ¾Ó+×dd·ùÒ—Ó×|°.‡ÏÛX{ükN‰€máF ¤ú¾-Ð@zþ@…òÞîÄ”wñ{9 “oû·ç¿Î×I8¢“}•|áÀÍ5Àø<Ä ‡ëÏ£·=¿þ›,i]´ý}“‚ï«c:öM+a蛂c %es×BµÊÎpXü`t;lŽô€æúé³eìý\üÿ—òÿRÄÝø‘‚–>Ö~» ó… Á`+;N’™²HF «Úrß ë"T{ôì!ŠÏÞ­äÀâï·¦ Z-@ãwÓœÚáûéh;8›#Ÿ²‹gƒcþÇ'¸a‹¾úá¤R´þ6d9ïñà$À%‰Cå*t5ù¸”ƒÖŸ«£ðŠ]ÆXX[Áu%ßý#Ë-®2â·DÞU«õ ×C/$”#úöþ/“>Þ é±¨Zãýi׿}@KðÚÑÿŠ cx€¹ýeÑÛPóÁLxº{‹¥LF%1 ldºR)™*ϦÏ(Ø·1 ÑŸÔH÷ƒx™›o,ïýÅåÿwù…æòWwá?YÌ@æP ìɨYHóÍ“žÀ½¾iÒE‘Ó—:]W–W9µøÚ蚥SûQë€æð%{ÒϾ¯ñq®¾—ÖŒ‹¡—iªâR4ê³]ßìYÌîkzxTYv´K…gûU¶Ç“–duR, `…wÔý-Ùg4—§Ì.©c¦ížK;r£#f·ÚPß­èz °8.“Rq› ¿Ðö¾WsáÀ(Î"ƒ@"ØÝáú=S8šì€r9“ÈŒ~‡+}ð“í- ^%~×9µHõEKv4›sóI9€*|?¸¶;mDTÂð7Ô,Œ€—$ ›ø‰žðÉ ë+òò­LjÑø£r¦_Eô?¥g_kÓ! GþŸÀuñ õ1-Áe uJǬ  û•‡­Wl)>†è篺á×}º¼Þî*˪ T4FãÝv4Œ{o™5…¦«ØSÛšc°‚±k‚€Â1‰Ý>þTná–\á¥n>!šb~æe A‘©„gïìùÙf‘‰Ÿloeݨ[ñ¢­&kï÷Æg ú 1O‡Ï&ó@ÉÌ0EïEÄý[ /ÄóÍ×wÊoÈ÷¬×І®Ð^§0QþÍN»K¸©¸CëŠWà—¢Ž¹nè”Æ£+DbáÉxj¬=G½Ä Ó§ÖŽ{87Še|€®üM|ýóž#Ínek+œµþÍÿ ׋kÆ·7>»ôšzæ“dß×”„-ËR㡲 ÀRÁ±ßšà)Õ&™o÷̲çÊ8…•eµY›^YuÌþÖª°N°óýîÉó€¹l?VÂÜ¥2æù{bö1ksÁíV†˜lºüšÓ‹’£ªØÉ˜È©×]ëûÌ'lîÞ9þÉgÏOê”á€Z¨“&vÊ.P׆<‘Ø°à›¾ùåì$å®O0ÒÃÑ_óè`Ó¦»1i—á@»ì’h8\®Û,é99P¯m"¥/h5:²*Öá‚kÏ`¯[f@ܽè×°%8ÂZ+ÊÁš¾±(ÔÛ6ã¶Î]ÓÝ#/nân‹‹6ÞætÃD!üŒ[©06ᬛf·²®I'Ó~Û ð{_ŽÃ"ýwž/†ÞW/èºêº| ÿhçíì=qÒGƒMÇèàá_µ§&½ƒƒT,ß~z{*;Y^&ò«â¤^htœ˜[=ñÓwcdݾغÖ]êôƒÃ77q¡M÷ùVÛŠ¿ùÏu>߃Œ_ÞËB,ÖüIµÄ¹Ì39¾ë?eÇ7®—õ„ûJ}ÀúüØJ õ_vºúÑ6ºžu­ÒÃݵçm’:nðáBq¶¹IÖÏʼn?!ÿ•ÍePb~gJþ´t“õû ¬2 ôƈµ]ÈŽÆosrÒ—ÁÆOYþ©)û&NÂÒ;½@ZT˯ÜV$@»'Ãê»kǰÐÙüœãéåäŠNVl}¡µ·òêÁå`}6v¼Dµ å {‡µJÖÄëoªlèè¦1't¬Th¤8êÞDÙX-­'+Á W,ð‡ð§³ÏýŽè+…—p§ºâ“XåY{£=ÿ8H«½?®4qr0`åc`С­dI=}0UfÄrO?p»¨¤|rë çäÏ+N×c㾄 Çb•Ïd Ø;ÜÅl6÷æ&Ê ]†©/•Ëü•åÿÂ_m€þŠe0û¯îª˜]’ˆ†ÝÞû˜Ü8w2IxþÒE¦G_Žò³¼ »…ä.M©L¿™ƒ\éºtËŠž“‘ÜÀɵ˜Ñ·G”Bºpñ¤šÚýp€ÐR‰ôN›³—ìý±ÙgW×ñtÚp‡>+éP=îðu(޹»×Oeqv—êO[·z—?‚—ÞýòâÜ,:}í¢AÞª¾‚½û=Ñ D¿tªÌÞÔåtðñNÄmލ­¨–ú ¶Ð b²¶N«l¡’¢¯#[?V ƵæM0}îë%N˜;ôü<œ*_I_:ùô8¿e)ÇàͰ¦!!Ôbsª}¼¢C6€WmGˆæ¼»8ÜÈä†Ë—§r žã‡éǶí\°eIJ¢‹¦ò Ø½6B5œ>—#¸¹¦kÊi8þØc¸[kû«]ˆþ)iEahŽû «<ÙÔ[œèºtç‹þ4]e®í6Búri8l|ºã0c! ¨UãYÏBMÌ™Z›yù븙£¶ÙïÉôÊ'èæ‡`ÝÚÙ±ÊuÉëË8°s÷©ûo}Z6ò›¡ôX#hNèLºxÿYö)mæI`Ñ,=¯8¨¸p]¯˜(~tç$=Ç™—Òñ©àkám’š2_µz׿]#ERƒC£!-w µ`—«ÞYXmÕ=ÿ¨ß§n„ïn»´íó ªn~8×ùhì4вàoϵê®Ì `yä³À–H»ðêp´°çÁÝš§²´˜Ö¯27(ÀzÃ[èR¿{#Ši+u/ä»^¾F\†ëÕ$Z»(XðSñÝŸ’ÿÓ”GhÎo¸óìÆþ-õF~ÐÌÅ4Ú-[Ú!K›°°QðJÚ.Å·˜û°û«Ë©4<{°¿¸á$ä]éöÐðûM"RT˜·«ÆnCö28ë¦f>&Àµ³Èñœdj- t2O0hÁ¨m`ºpœJ4Z—o¬,@AìžÁÅGW·ž¨¾kBY7J×ê°çqE‹%€èˬž‹ìã®ï"rØŒëG X—$ƒ23éX +ï’`ö› b„á®]yÚ[îN2 ΢Ú¯}zù”Bcn@Oª×²™Ÿºm[çžß0KbdÜl—jO›Ýê,»ÎdÁ/,ÿ­ùù/)¿n€I¼â%g¡Ê—Â]—ª‹sapH=ÀŽËCž+˜AAó»½B6oW· p6êJÐð+ ¾À5‘ý$*Ñ€<ÈÝbCöµ‹—êâ˜xNÄì™Åôc°$gËl¿õ%Øn1ºw–.+r ³—ßì’q¶ô$ÕïΖ¸Ø¾ƒ¥Ÿs«hîÖ_&³7ÖMÿpLÓ4þÖ¥HDŸª;&õk¢o´²–†rÏ‹¦D>T`c™ìÌÁX¨…»vòÝQlØý"w³J¾ƒ6Lj[…pé>•1ñ³,§w³ߨoË· UÕ+ÞeãR¾®üx¸v¬”™çÝõíìéÖ¹T¿zÃýM¨Id•i\Ûrå ÇsÓáÉ\ùqTvî}Õ-*1æ§âÿ§?)ÿ;‡ÌUÓzË‚ÝïrŸeTróªÊùž—ô–[ŸœôöùŒ¬_½ÌnÝ‹Ó'¨ƒ™eÊI·ïJ{€³¾ß^U=Ù•ŠÏso®ª¼“¥³1X…U„CˆÉUE/ƒÊmœ±.f¢Æ¶é,6Gëï´b¶—®)ZJFŸ¢AMíE®ð‘ª=0gÈïcªäs•½°Ð868+Îyx‘é(¿|¡@ÅÄq¸¶Ñ1öNÖÆ'žà¼¿|Ê¥`¯•‘«§lS]=qÇLÒª,rŠð;š)òl0—Pö°¥±ΞØ”¼*D˜;°É‰¨£‡·LT¼ôìù¯+ÿ¿ËŸ)n.Auþ#¥§àüõUë]ç¤]ØÅíIcÏ“ø‘*”…:KÖöôw¼²Ýœ N­€]<`2òZœ¡NfPêÇx™ë<ƒ®µ÷ÆŒß0ŸýÅFÎ7²f¤.Xx)oËU'‰eÂißd4Ù¬}SN6B^¡ƒÖ*fç¶ ‘Ò*Ï©O€ù‹Ú/WÖ&íº’¿¯(gûJ|uÁ·Ñ`g2å)²Y²oÆ¿õÏ–õÆ”óî>·õ¼†ûêÚësÝV>Jçñ£š¸CòªÓî4¦¨ç XÄ:¡¿p*µq9Kž2¾ûMI Ád•‘•RÕ#/!ÀôFæË–°'0»— ÜÀ ض]õÔ-¿ùÏ9¬Í.x(eEy;RPC¾ãú¬SÁ4hiѰ䬯Œfu "#[¦+ª1[óв¥ÑÚ”‚×ïœÎœš‹gàî b?ÿÙVþS„nÂjv1ØÞ /¤¤ôhȬ/}°Ð™¹.í``DÝR'åy–%m¹9å±Â30•ìh’}”Þ 04ûöú³Ì©µ0æÖ·á X×¥r ÷F9À7%åmµ{F|ÈÞóîʧçóG3¥BK}Ø-ž·âþzbý¹šLN(·¡1馅™Vn0vÒ. d±zf\®©<ÊÍÈlǧù{;;ßãÁÐ(? • ˾‰èÓmAH›9µímšÏÖ“2Ëš_i}¹Ýë‚oJ§4š®H|m¬`RWç'´zžé;?Bôm«[/C±²h3”­úEå_à¯6@ÿ5ÅŽËý«»ð(fÇ4&y{È.E^üÇI@e,½˜ä«˜  ³€bso²0ö×çr†:¨/NƒÆº£)…™ÁC‘¼zjì§ eTB½»äÈÎ0°j\Î9SxÂǪ '¥/X¢þö "ó¥T†_™à  NÍ«ž]݆ƒY绥7±»Xaû:nÜšX ®#nY”ëð)qÏÐ\q­M• >¸A?ê¥â¤cl†~¯çÀÎE¯ö¶zn¬ä³B¬öŸmì~ä+–á *éwt5'ÌÌ´Ñ.D_rŸ­ìTk€kÍå‘ÎzkJKðPdÖûG¡?zz†&jè,…“ÜAK Vk'_wÒÕz¤c2VX~ƨ';Y‡…&#M˜3kèv€K$÷@^þþÀG–u (çŒJh®·~Åשn’e©^2MíCÎØKjÏgƒM")¶Î1NË[u?®¦u¨‹€Á°™€½s@—0¨ÙQîîQ·€b©äïPÝp´úciéú;Ø¡Ø#ôÛs‚‘©>üÂtÏm<%çµ¹#ôQpy|³¤Ï¬)Ò9tý‚C>³œãM8š ‡È†žÎÛù—OÊTĈúœò°P%kõÅê *8=Øp×òÖ„&”Õ¦’R·sÁ!oz–Cè¬f ÀÊÍ.š–ãV³À;x%mMÐoþo¹@ýÀª#± $oU»·‹™É*ί‰:ƒ¹&±Æì™Ê`C¸Çlòß}$ho­Ù»Ç¡÷ºŽÄÖ+àAý©øÿoÈ”ÂI¸p÷ähù#cI¯›+¶]~h° —‰äD08A¤ó¶÷œß›ìf›]ÃØÐÒ’ò½»Ûvú¤$ÌXþÆÌ.èÞ½t¤R\.}ýÑóÚØÓÁ¦m×îý”rw1VB>+ŠUÂׯ#ÖŸ´Ì• ¿aïGpÀ*+:/…ëU°¡‰±dgmòÝüz ö-½âxÙyi-î%Q¾ê.À`˜¿ÑO¦–ÜAìSJ·M%õTáñïå›gLytyxòM&µ}ƒp(o;—zõlÔ€Q1{»ý©J í«¿‘K<ÂÞŸ„ýšòÿ»üébÊú«»ð¿^Ì€Á‰:¶ÙæÎ² Àzž³÷_ìø”`®z{T£X•…xØÍ:O,B\Æ{—'•3ŠR‘õæòùgèMôÂ4ÜÏ„–-¾²v!`\ÉÆF‹J FÂ9¿å§ÝÏŒl”æ¼A¢K3hƒ¶¾.(7؃ŒðÓ=›‡¯- •ÆD`/£…ev‡›êGDäÛ‚UoS]ÂÜL(aý涺‡×3Í´†nðfŸÚqlvÑ©§‡ s³€z|ꜚ%èŒ*…‘ïðÝeÓN³"qÖ¶Úl ltúÑtÎÚðSmjb`ŸöäÁqÆ û[®U+¶­€µ’B~¬x^„õ4ÝÍ[|18ƒ‹Ð€¨ŒŒ;|¨œö9CFcÔ4™¸7/(ÑO• = “¶„êKsµNeèChõ¡Ê{%¬ŸUÄšªß…ßÒÅŸŽÍ:Ä™¬¥{fõV^},ÛYu ndÆwd'/òvñµmç¡Ã_ÔŠå–ÜõÂ/¯5Žn>«Ð™y.bkÀÅ•¶ÉU¶"žSޤ&Ãî6U8,, ”î¸W¬¦v_/‡õüŒÃ2Ì!¶ãJŸÖ0g½J”Z÷Ö¨UÙNzlƒQΓ[&Ñ7Þ·„õgÌ’|ì»®¼Ú­v©¢&fÚ„©ØÎ.·›û?½‚iÑHÒFÛv^_m Ìš –ì¶6„ù’îŒdÚædWÔàž8°¡;Öߟ)þ·çÿ3 çÞ (35DÕ­Al+nwÀûÑY…ã^ÎHWž÷n7f‘lŸ;×ùTàã–æ¢1.ÍAvÕ•*Ø,d¶)/múÏÄÿKþÃq]&Z»æÖäO; ̱-"ë¤]jÞÒ~srÄ›•ÈÅÚØÙD×<šü*•ˆ»ç÷Q‹Æ³ý‘ÌpÚNd¯ËR—5}]·ù€À÷]Gg~1‡%G?-:ËØéÑæâqgẪŸü˜ÆgwF´fŽ‘IBë£ÙGªJTK|÷ŽR¯`ˆEù0§¤AØ›ä úœ´½2ÃèåJª¶æÈ+?p‰ÍQ=(vñpt0?–§q úV¥ÜMC°[gåûž˜<V1¡Y—…½€>ýó1fM‡ÒƒX9v¹‹ {-¢?ê‹“xªWˆÜú²wŽøãñ_Rþ—?]˜Váuþ·KòzŠè¡zMØ$Ÿ»kµÎcglq¤¬4ÄŒ_• |§ð<öA´’ŸÅ;êË\ý7paײ/¸¥GÃÃç@µ:‚ÃòÙ !°Äú…¤z—æöšãߥw‚‘ƒÍ¦/à)ÖfgŽ }r!ÀÑÃ?P_ž}³'ëL²@ñ“¦­•ÀòVRgûß;4~<˯bá`Îr—Ÿ*©|Ñ—_t®hbÔbY4íyÄŒ N¹@{˜(€ƒy åbi ÅÇdv°;qXb6ýˆTbÕôúù3Ó8 tÌ ýY¶ú3p“ Ëq§•0_Ø®³ÏރřCÓ’ïÔ˜UV 0a|OÀþóƒß€íë”únSÜ»){õË06ë\}]I{w&g;Br{RÓe¿ìóØÝtÈÃçí,4[2ï4wŽ®‚ð £YÝ2jb]JÇ"Oìôk»wëLÇ‚\³Š¢¤´¯ô:aßjßqfœ\k“í¯)‰åó×jåFßýÜ ši'üt.Ùê°#ÏvaXI?÷Î9ÜÐÆ+:¹x¶3À9‹_*m˜gJ=q]óëzÄÖY)qȧˆü>¢Íw0ZWÞL:W”y V|:o5sÚõcP¨W$…Ãîðù},ýº’B)±»÷ö•R©àãº;¶?6iÃÛ ¸ˆ~›M‚løY¡ è °è´’yÚ½:¦ã³R¤·B‘ЮzT ,>ƒÑ¡ æUˆ¾õt±W`ûÓሳV_{‚Öÿ/'ÿ±¡íù/,®Ô€¿º ÿ»ÅtJÜË#›t­î5(SÎÂVß)²ÛÆtjwY0Je|€QZΡ|˜tû8&"0^4äæË—"wd׌¿€kÅÁ¨B+]¿dÿVè/zN&W1]F6/W—jT´ù-Ýŵ´]3}Ež‡÷¡[Õ%rÙ{1úÝ÷š‘5Ýo#€^ᤈï<\ m| ÐÒ}D;C7J÷&f—tgo¨h9¢ï`'üä Säö¬]ëCVŸ@Ðòñ¥ üGòDŒ:ϳJµ#/¶4ƒsçT.sÄ“ãõÛ>•',¼5³rí5×eN»–Xn`PO,a=œîwÆû¹g`ßö•¼‚&f3Äó3å±Ï³µ,7ÑŸîè–ÖâÐT*CŸgn׊]‘ô:Ž hÂÍ*úz[š’w7Ä»U®m}ÅžóF• ‹Ÿ™âéS€ßúv ÀD#Ÿíâúbça÷¶ °… ß—ËO ß+3Åq+> ®÷ä>Âp7N]ÞÕû¦ýÐòBŽÑ ë£M©âß ž >uÖ,ö€e±g@ÿiôÄÂoUÕÃFªGÔ¨AŽÒì–×1bŠÒÞ ¯Çï=‰…,Ïw½i1Ä©J\a.Ë­ëiê›ñâ­oÁBe½{,V(r§G~±§|¸¶b,²Å7sµâÆ}øl9°è…çD_Ó¸Ö!@£ fËk«Ê†ûÍÿׂµ÷×èYûD»êYwS|œ]MçúÃ"‡kÇAÏܾ °€mˆ~‚ãÖXWãmn!áÕQ˜óeC´»}œÍÏÄÿÇÿ¦ü¿qTÌw!~·¿Æ K#šåß<Pœ~,Þ+Ĩ™’i±-ŠIb€-8&{N­çº*¸?ÌßQݹ1`Ž`fvÊ ·8/p P“²œrD ¸9_\†»u 1ßoyðÀ%ÊvÙÁU£ o‚‹Úmúaw´þL[¬Ûªƒ«Vè(ÖÝ»pKZÚï¤É0iÀÖ7¯AôÞZéUi³zÊ~ô×-‰™u‰1ùJzÛÅ@Üü¹zUˆB*`sÅgÄ‚«¡ÞÄѧŽíŒHð{ä÷˜Ï¤³W[—‰Øö7ó0–ô[´þsî2ý¯‰Ý±\k·™“âĘ eßëÿW“ÿϵúo+Ö~uþ7‹E€µçöK0ç„€SµÏâ±×ÕZÎå é7èD*6ê”kIÈ,ëp¸bÕïÝmã•!rœkººVã!/&<•¿QX·¨ˆ 6 ¿ìãØ„ÝÖ¥é^GubšÆRËÔÁnÒW_öô”ÍïÜ%[†Ð‚]i°kÂd‡Ø’1Ç‘£ë€ü¶óE!À¶æUbç7úô81…Ïl!èPq‰p€Œÿ›Òĺ,P_·…{Â"·Ú­N—»Ð›ʱ»Q v×c=gž´ÚF­v¶;¢ó–XE ¡¿÷gÙMúòØÈ/b ÀwJs¬ÓZ· ÃNfÆê ~GšôžMËq«y¡µpÓ64þaɪã1x$v VFØŽX­%Û5ˆòæÖ~P{¾àíc‘ôz€ ZÓ!¤lîþYsÒC•U—<2u7î~˜LWZ›ß+ a½bãñèi8œ+Ø}C}ÐÌ›äÑSî…"Ô0uG;ß`¬ÒÄX8£3æ5í²¦5/­Â‡­>û:ícËŒ¡-m¦Ê 'Þ{ ;ÑX¶•òXß¹rMyÎÉ•¥¡Ñ@ Ký¯@ëá§BYI\Ú!Øx…£Lõq¸»\›!ØoW4 Me•LJÂ]úQ›ît¼Ei74Þ?th˜CZ¦î¹ÅÐù* EE†u‰ûÁ]±ZóHJK°(ÀÐ\;Ù†ÇuWa' v3Òó¿ë~cÆ€r·EÐØ¹¶Ñ+| ýªÍ°å{ÆËWÓ^ÑF®ÜJƒáM£G4$ç®͹)`}‡`G;>€Ö韉ÿmÿ¶üÇO»ökî‚yxÚļq™€ÃÁˆñ]Ë÷€Í…ÊQ&Ûëi‡N%Àš@¹à\¨¿¯]'zè¶t"[ŽÛl#óß·ž/‡•]š¦_¥oÿTOgC¾àxÖó×FÊZ•ða€ù½ÖT$ÖŸ–—°)ñ»ƒ… Ë’vË{€kÙfó@\5Ãк}¢ïíDuæÆw®ÆT Îoºh²ÿ’ݨQP.Ós3q¶Ñ€“è¡k¼5* 9ÿE6ŒËþ<#fHtQ²|óÙ¥ˆ~ñ’ ·àTÓ,#´þ; J|Œ']¡¯÷[–/T )ÿ„Öÿ²ÇŽ¿˜üÿ¥Ö翲˜‡ÿBÿhÒ8wGF+FŽw‘*ËÔ±!i"ÐÞ F™õFÅÜóéH“ßþªlzP­Ò)qÉŒ€ðiuÊ•ÅfúM'ù£ûë±)ì(r¡ë­ó\—›”åÃê¾sÆ4%ɈåM»¦d™sç7Ð?w¹KšŠaº¬¤jko²,EVâé;ŠB•îoùërÌkç{Áé’¼Û¸÷ªIâúÊFõýªÚ¢èJ5†™Bâû+fUjvÇ3ðež@}•öÀ3¸ûCˆ“>Ã+,qo:_?…ï·ÃÆâªS6¼È¿/ÍqX’}ÜÑßå¬ð¾3r§›Žï=°[zOÎ÷•=§ûG˜é{ù)k ¿j»NÏ»ðíÖ¦ó\K@©PL‰¾Er¤Å/]âé(9zs0ØL«¸X÷cߣ úæi5'WªÚØ}çhŽ…úñJ[…kJV5qÉÞRnÚ]AµëŸw Ù#:AåÝ­ïS³®ºùTÝøÜO™q6UwǺÅâIà![ýLÄγÓÁ_:å(,‘\ ¿Ñª°¦©yˆã¨{ÂeÁk˜uË>~êÙ sî$¾ÄÀ¢g ,®3м´Qrâùñ0·(”¦^…yÔmJE3 þM`eû–W°vÖ&;õôkÌòƒ‰ÈT[_œµ+wü3&¸/9 tO}ãåÃÅ}dŒ3y³„@ùK†àð{þ \½ö¯ÍœéŠÇÀ@¨ð`í®NSÚé‡çÁÚ(M+ó‹ÒÓÖéÌ w°;=<.+@j¹Í´èÃÜßÌâùñ¿íÿAþ¥îrbŒ4Üá¢ePk…âï¼T9‚,73¯Q:kgXg<+J3Rg„€áeôq¸Ãáù.v#À­jª÷|íâiZs-îtÁ®Ó÷JU\@§§Áþ±cªnLvW˜å)3n1LØy“XÃ÷¼qÝ"&Å0n[·Úéª^*kÓ›ú‚˹ëÓ¶E#ú–îyÂe`ñÖ]àPްç°l ¬fƒä4‹­á\ÓEÒ ÂÁ­²'ÛôHÛ›T9¡×ÇXÕ¶ë?=ýš;ݤÑþmë8î6¾ÅFëÿðšöÝI »rËÝtò)3ìSÐú¿4G3÷õ¯$ÿûÿjô_X趿ο \·÷+ýX3`Ô¼öŽ6üF2Àf…ïNìÄå‘ÇöÅxЛcS `ûÐTF”‰ûÎŒÛS‚Ÿ-OU3z°÷Õö [#Íc0ÀòÇ&¬a { ÀºµA­B A ‡‰ óÖ ³¦ÎíÏ{õ¨^?gŒ±h¹ÿ$ö«ÇA*gEƒ?œª24»ïµ˜ÓÏ$®_‘¥ÿ¡¶«j—}?ÔáÎBpOKgœê oÔM:»Â¬ªùÂÞÉÍGíb,ßf¿y&×cÒc©6äj/ʇI£5·-õ),óþ› Kޱ[p¼-=ì›à-§Åð5@¸nœª¸1úÙeš°<Š–ŠÆ ãìÍ]¥uˆ~˜ì‡I§`ë¢ ÷ü´W<ñž _ ´k•Lí}<žÐ–íTÛ–Òep:8âÉY€´V¤/,š†B±gÒ8–ȠԺ¹Ÿlµ'<¡f騦”³df-Xådµ¬zѰÓjqÈà,È}.º•Ýš2NflÎ~ï÷}ʇ[ƒãŽ;*WZ†Hª÷¬½_»‹;/‘Ëò±„£‹òÀNÎé%ääøxºÙ5lƒvS]0Õ~ucÌÔ;¡c²C’k;úÔ‹é• —¼ûàW9+ê”Ç‘Å[³ê: U¤]úŒ´ˆ  úk)j¨Òf¬·ªòn΀’¥n.­Ufo`¾ú8 h¼>·¶1ïoÏÿ˜e£|=|ÀæÌK×%_v#¬8¬‚rçg<تРpÄfÞ}ØÆžÇ¹ž$:®Muò’Ûó—v5w:ÎЖý‰øÿÿ&ÿ;¡ê£C.>Ýï%€ÒÙïÏïÿºiß™'wÛ÷´|ˆYsxrÙ©*rmŸ‰Í¶™ÌœK«4^Oó_ô €fP¼ÇÓ= 9VÍÆgšZj'®{Ð:•¢ÿÕľ¤ÓÊ÷ õõAª[Ù0½‡öÐ3ÉfÜyJ+ ¨‚A´dY(e> ýS„¼Ú¢j§®pLQ`KZ¶Âõ¤÷RkÎVŸ¦è¦1GÁpQºÐð‹Ck;‡у/ ™]€èôlMÛCø¦-ƒÀÝ ÕýŠÜívþ÷ g•,õÕqL±¦Ì93  Æ5ïsScÞ¯#ÿ—þbûóó ~!˜ÿ-4Œ%“…Æ‹§x?â8`Ìó,Þ-ï!hB˜¼:hnxÏøOøé.Dv“áÌöÆYd³}ë=;Ñ×"Ii†÷“F“Þ7÷¼›>‚Å1ȬƒX¼Vˆ?V$úHò–zÌk#æ ã‘G-"ö`h g’ÿlÞ bþQ³ˆ>“É":úCp }Ç££‚¦‰¹xz Ú¨2ÙQ6ÁQªu¨;Χ€:гˆ¥Ïk–Ήõÿwÿ¿ƒû-€6P»÷ët⎮9pþ  þxG¾veyæfàÁ‚>ÅÒ¯ìªXø:Fñí%ý£iè;^ïˆ\]ýÝ Ù Çþ@ ¯"¯qžŠïkýgÊê}K<Äpªu8ë•Í^Ò¼ïxÑ5²Üù€áð£.Àl}=úè÷ɸ+Ë£_Üûªö_š'B yF’‹&£Q|…E¨&Bº‰;ž¬l°æ×Æ5Hh@d¥1&fŽ>$d˜ø„°. šé:Bi`¤ÕÃ1šð…ŸÐ©TÛPš; }MhÂJãéb¾vgò•-úCèš-¿ùÁIØ&&¢¤uaàïl}ÅõµÀGzü“?2ø–ÝlÂÙ<{^Oèæ¢pï÷ùè ]êp¨­?»Ï¦°þÇÛ UÑØ,žuÔ„=— ¤ëNa$ÿL—³ éâÍ!+’ª€%$!Š8…êǃ Lœ´J ‹#}î>zÍ TúAŒ@mHi ñ»ÁæB}#`,'+òPúŽI"-¬¢W„ âÿnÎßžÿ¹@ÚÂ>  G:YÂâ?Åñá&^Úp¸Ëêý™ñÃ…©ú“ñŸùÏå?Ó‹…3øà=!g™08‰ù™d—Ió‰Ìo¢Hþûzàø‰@ÏÎÑ"X¼õ‡9¸{‘K5ój£Ç 2ÒÂ"Á9ß!@Fü'üpu }&Æk–_‘Hô›xœ\Ù½œ ;¤9Àó@0Šm8¹y†æ$MZ`rM#rÕúååÿ·ýÿ§å—whÐîý¼55:Ëù˜¯+K·Î{È0ór÷fÿTôÁ¿p‡Îy¿{=ðM¯Aè ÏÚq|y ½Üûqa_ÅÞ8[úµ»Ãú­ Í*Ô½XüñøŽ¼š€Øð‚'Èä'®àÝ+ýa#ÑÃyµyõ O¯·–ç=øñ`âBÂnÊ¡³‰Fæã>$ R}xh€xNÒ'Õ$zkçãŽ>D(ŠÍ$°T†¡ X¤"f“H‹hM$¡>Ñô Áw_¢þkT›׫ŸIÍIÀ œ§†‘v15üÛó?!ç{7x¯I'\%¼{Q?¢Ìóm0ë0/"@Çùa^xšð!0˽?ÿÿ¥ügsøHŸ0±|¤Ìßs$"÷Lž‰'燵™—‡ûÇŠÄ[éw–È]^ÔŸù`J8Mhð,²Y“CÔaÑ 6Ï}@~AÞÖݗijLÌÉËçmm~Eä@ð‚ ¼}èÿŽFaøà} ñ?Ä£?æ€:Óÿgðz†ºk¾ÿ—ÿßå_”_Ü õêb>€úAi#©ÇÔñóý^{Åtôáôõ”föÇøoß6p¿°3Õ2¼ù]ÿÁÝw£ø÷É8¯Å^J¥úöVíÝì ºî8íMì÷! ¼wl2P̰ ê5}î>)¤a„¤ŸòåžxC¸÷ œØóÃIóBˆ¸EáÍ“|$"±¤:Á‰ð4FÀ$6¹±oæåÃFŠ”Ø $v{57¨EÍâ<4ÂÀ1vo\¹j¿ùƛϨ^¸OF^©.,~\€7É87RÆnT_B “¸Œƒæ˜À¥äˆ'®Û~.þÿkùgåÓŒH‹h ñãdÒ{ødÛDoq²¢ÁœW‘ŒõÌ.!þ¤€XD¤÷Hš7ÛDŒØL!C†û žøl•Ésÿ¹à9dDŸÉÏ |¼7þÏ7ñ½ñ4XŒtC0†“;?À:ÁÙ3àHnÓá`ñc> µ_]þ—Q~i€Æûë÷~Øç¥mK ¨~P½Ú‚I¡øSÝ=~¬ø#ücl—¸£Ò|`ànïêðô:Ý:À«ÿg†mh_X™_±·…þøï@+…úkÖ›;Fµ c÷V€üûs~¨ÛÎrøýæ¹ûä;ºc@Ÿ?ðcâÖ…íÙ;…òˆ ]3î(0ú€!Ïr0Üs#"zärïæéÀ»xp¤øb^ÈÙ›l†±è¶Á<˜@DýÜØ²Y׈Žád³®a“ÁE¤\L¶eˆ;¡Ñkð³ú÷bI4Ö»ÏKh@‚ mëoþç° “ß›nF¦²ÿ{Q0’ytdH0g–NqôC=Þ…ªþsñŸù'ä?%„èÞÜ!n™|;ËÂûH¼ŒÇœoây¡o‹Ÿ5ç‡ìùžjñŸŸþ7 6H`þ)¹P Ä¢¼>Ý6”è¯ÈËÀøI„ÿ@z·½îñŸÍÿ»Ù†~.™¤Êú1þÏߣ"Cû•åÿwàO”_Øàçÿ÷Et –Ðé$XsÔËäþì/^•ùH£;xz±1›@öÿH#u*Öû±YÇÁÓƒßnmüÇîQ­B?¹»Ì˱bò‡Ìé¦92C„ˆ3üˆ UR¯Ç€ˆ8Oø™HÓ‘Û™6dv²­¯'y ø˜#ÛågZCžvïß À›óÿœ'$ã…•™öÞì¾drËxö‚…ó¶ÓØJîÍé&ø…Ô7Mã§â?ãÏÊh2?câ}‡Fyp›4È8?dOsCü'7 Üè\6¿"™;HV$¼Ëþ#~@‚óþ¬¦CÐ@ëÞ{hŒOw<þ÷Æÿ‰`ytb³xÇØd@oü¿7 €É;XÇ;݇шV¨¶!"8@Æÿ‰†}ÇÉŠ‡zÝœLø%åÿwÀŸ-¿¦@ûQÎj÷¨Z)? ½Þ0@!£Št'¶›/(N\÷ÞŠ½B1þ!ôHö‚ÂôÐØÀÝ]B 8ÓØüfx Óœ‚zõþÿíXßá3²Y¤ß­Cqºõ¿ŒÿBl(ÚȰÄÿ06·ÏÄ À‚#×ý†…°$Gâ{•&‘;FãའÝãBd•É>v$»`à“ÞÚ 2©šè/ÛÍ9ˆHæeÙûãdì™'ñlòt—;©Wˆ¤~ŒÜíÇ(^„ÏO· %¬-qj—ÅEHâiw‹÷«W~Ø´e#X§ù›ÿ9lÂÎÏØa®$ÿy[Åü¸ô u¸ƒ—;þÇc€ µŸŠÿÿ†üŸ ÀùÇCøI#@fõÿ˜4‚øÏòeã¼eÅËÑ ã};JØù½ÉyüÄ~úßÀHq´0ÞÎÔ@6/þÏÛ£"ç–ŠøÏä›êÞø?ÿ7 õ¦‹·GÁs'ÐÔ’üÿÿGiÄÊ$ÙKø"®Û~Mùÿ]þtù=‰‹DtûöglÃòníöœñøA_óÒsÉfú’¹4ûèÝØ«OãP)¼ò?Aÿ¥­»·;}ºˆ/C`ÏöÅûzÖÿ™í‰ÿ`†~ øþáGžÑ zÚ¹‡ÿÀ ü°‰Œáv{ <†ÕoH\™>-[è¯ï×}Ó:„5ϘçðøÞ !³ðÚ»¶Þ¶Š üï ‚"E”‚©€„h ¶ã:NmÇ>{=¾Äiìĉ҄poD¡V´Rùuì\öæ¤*Žx°œøÁuêõ9ö™³³;3ß÷ îÈõIßíâ§ÉÆ”‹}àÜ ™Lî†àÀDŽî”#!ÈΑöŒèCAÐ8‹þÀéf{Jø_ÙÝ·¨(‚”l"yc¤¥L*  I† ÏÓ‡·Þþ¿bÑš–ô–zn4é&1 Pb¤¦„…‹†Ø:aÕÖus~üëo—Éþ Í ®%BQøi/ |Zí¯è¶rŸ¬ž`1žÕzbF‘&‘ŒE{Uwa¬%:ŽAЀ&Ô¿³?ªXuˆ“÷-;$ â(¥ KŸÿ÷YP`4´ Pdÿ¨ÄG$!OÔ„FD‚ 4‡+9ÿïÿù±‚Ôÿ™Ûþó-~¥Î«Ö¯mr'';ÝàE«Ëé_†[5L20á‹%…à<ÜÑËGó*#jÏI&å…ã@„›…i÷žü/ùµFó £S•® ± Qdk°õ†þý0œ¦ÛžÄߟÆT¸>PÂG>ŠdÐö(QI×dž„ÎFF—äA`»itÌ"_C"‡à¼5µù±\¦4µÕ\$¡â.C¯3¡ÔŸŒ:ò¨´W[óy\‘á²0æÃ­Ü¨Þzûÿq˜þÝöADýG VúÇ…J³EsÆ€JFåöƒe²¿Xlþ¿µIQH>Q­z%ƒùÙþÊí{ÍY2Py¾ GôF?O7‰ïÎÊTõ‡ÀyXÝwö·¸Ä)&è)ZçUmVšt Á 'üy‰·’Ø}ô.ØŸ7m*|„M¢†³ÀíƒêÊÍÿ»üÿB•Ûô¢7…Ç•íîšÅý‹Ÿ¼ \ ˆ­Þ³0t'ÝÑ{q`FW‡R Ž|pßá›ÕéØð™³ØQiµynô\÷îü/Œµâ¬Œçç%Æ–“ó«øaq_ë—CŽ¡X—GŒWj˜ÑVãð7<í®]ëœFìâ%ÃN¿Û>¤ØÂUyA™@TNO6G"žò“ [tGx~FyDBs‰rl¥ÞA^ÉÚ¬' ·ÂŒ.¨J0%¼Ž PÞÙÿõPQ¸ö÷Zÿ 4@ ÎðÒw䨦¡^ç“e²¿Xpþÿò£Î1­N0ÒEÀ”€³ÿhÀ©$˧³¿HÂ~iHN¹}C]'H»×ýI}JÏîcgÿɾMÒ ~a‡õnóÜÆ™ `¤Š€öïk¾þ\Qp_†ü?.¬Bwÿ¯Úü¿[ÿ|¬Ø ‹¦èCF7x…ÔÏjÝþôrbo‰N\vš‡CΑ…Dqc6LñeÊ$`ò0ÏÝïÇΠº9Š@¸ál cðO½öDóPÙþìå¾(=ÈÓ€`ËŽûrc(þý ªÊ¬O+‡è³È¬áh\SQ¸üü²@³§ ì•ñ@hR»­qpiAuë¥Æ*ó{íVCœ-¼4›ºwgÿ¿Øþ>.L;) ÐRள?{zÑY["ûßlþÿcý‘{úP¿]gmº­Ü+gãr nþ4‚˜L |YÁûÆRÃ}îþ‡‰ÑLQtåx 9™Oy ”'ºšÿ‡Ãõƒ=÷§³?µ ò0úE¸º¢“ ȶpDyo…æÿ¿ÎœW=ÀÛPxœì½ \MÛÿ7ŽŒ Š ! K…B™e®•R©šçét†ýÙgè4σ¡"*Í¥Á¨4šB!2$¤¨ÏÚûœ¾¿çÿž{ïëÁýZ÷Êéìµ×g­õߟõÙÛøÓþï› øÿì)üCmy™ìÿñàwr0få¥%5b :  pjë%?çør‡]Á5ÉÓ9àñNÔîr”-†Ý2eÓºÛ™U3ÌŽ…j€a¥šÞ5ÏmÓ†X­lVoÂ/æMkMºàõpRMÆìôç}w;Ά}¨Pæ=Çô…­ÎfùõLp}/ÖF_Y<Ò|ëžå .=[Nk„Fê[Ú1ØŸ‹èOlu³ 䀩á—{Ñe$AY¤²‡¥kªß﵉Ԩcù³wL¢§4I%2Üž ÛPçùV(üž¿ÑÌ€ êóìpNÕ¼kþ³¸ÞÞC7‹ÇgÅK Gs÷ÌÛ>èUþå/¼–zÆîFë?ž¾Ú@0o]7¢o|ó5õ™¤yŒÍQ(µÚ`ÿy €3'q¸\×±Pk_ýO yÃiUÓ»Ýx¢<޽@…:Úzì ÷¦–O‰l†1ì;8­2 n¶œ d{†¾÷º¯ÄÝl[Þg±®àyám€ÔºÉ@)ÞÈ€÷#ŸM_×uŽã»Ë¶™LywUþì~ÇBùˆèñ·¾&2¸¿á˜î „ ÛnERçÃâë¨4—>"}#èr¤¬¿›D}„­Âä¹j‘—å’’YôUá™êIö×ZÂ&q©+T…íÔøÕkÃËÉ!úò‡0£ér«"ñPg*€ìðwê–‚§ÌK'\ɼ;v›8®Üµ¬µ¹-Þ.ú‡ÿ¾ ¯úܯuü}„%s˜rÛB)OÿVÕÜ®ÔUðø|uPÔ"2Ú½†Â^ýÉcÂ@»l§/}kö/ÄÿMÿuÖ_–ZuN 3á ¬òû­°PÊJéñå•>—WR¼§Ö[EÑ æÆPžž,Ifï½8¤8,Äï^Gtzef7­õ0lKVúž®š¿< ­ÿʆy>_’àSžê'ȪN‚ÉÙ#Ÿ!ùÓñN•|ºÞ 6ޏ‘x³dþ˜.¾œ ¦÷†–ˆ¦=Ø3XeÑ_´Ö¼õhاåzÍu/RŽØþr³a ÀØñ3ðáô-žl8;Ͳö•7.ÙW°^ÍO7·$fx†FæË@g²Û¶¡Ç‘ü¿$prw¨¢?|ó ë«ë6¨Ý©[¾š!üÿkôßïg; ß´Ù³öþ‘ö•¥R2¾bãJ–m¼»üç‹ÏOøƒS±x %áU“mpÆ<, î3í¾è{Ôyáò ‰Ê3/¶‚™„X¹›ðYÕ£Bg–Šy­Ô{@ƒj­DÿË\ôY0û@JvÞî”é¾^6îAµÒã>9„9‡Yˆ4•½‹ÛƒC?ÕÀ”Þ¾@|¹_r÷ªƒÐ0ëkŒúkÇ[˜å"¸{þÔ»ÒÑ/&ä¾ù¶4çváú/¶z¾yž ˜gRül–Йóê*k<¨ö××:v+·ÔLßè €º¸éÅ[ÑÌ`Ø7#öR8Àk夹›÷ÞØCÉÕиCá³Ðä˾"FFhýƒŸðØŠÖ? üÖ’ÀRʀÜçȦ›úø Õf)%+Y7ÌPþòB-i€#óÖµ+æ\( `É*ØåùXš»üË UŠ„ÂÓħTˆ‰Oc÷†;-¹4ù#hn ¿ñL˼a ´³.– •­.0`nÖL¾¶ò&ìg|ŽX¤ýE¹0Øc¦IJƒ¸Œèøª«Œ’ð;· „ ½q¡½õ0h˜ ®OÜ¡±î~8¼›âp-t –=¢MÙì̱úmÊP=á $ï 33Ù-¾q-8ÅmH<¢SÚò؆˜7‰éÔ¢¤„*Ÿ…©Š§†gî(0VÍ]e_½cN‹`)_uΙ*Y U,E`Ôvè.›vÞWûÍ"7òf„]†þ×óÿ‚䆊•](ˆò~Þ…«¶•I8%ÕÖÖÍmÉHêd1… ;t…!ÞùÛåD …SJß0û©{FÞÛ¹é×áú_ÕÿSA{&sé§Þ%_)øm‚jà+ι6¹&­°(Jð’ÿ„µeKM¾¸Ôçª+$©àBÝ8Ï+Ÿ¶Èå ù¯ù”ý/Ñ…Ÿé|~ç†YEýì)üÍKÌôQ¸y^¶Lˆ÷P¹i]*V¢ÃqÌtÀY¯Ó ^àY3Çíh]‡’s%Ã÷NM#_L<ÝÑP?Õ·P‰cÓ9‚Vvµ•Ÿ˜O&{cTS vû¾ =â@奺yžÁ ú8_.Õj¸0…òYãsºÛ« \èâLÚîä™Ð¨-+ò÷o3½xx!²¦¢‡®Mh<’ .ÊâF¨Üâ8¸ú‹F× ú#rý7Þœ±¹!Ê’Õ‰Ûç}ÁFMpÖfƒS×åõ–!ú°x…h jŦeÖϘ]gp»åÊL_3þ “qönc0¸½úàtìürß­'†ÍÙˆ&ú8|Zÿày®É§ Á!*Ö_tùS¸ËûQÒÒj5s|F«Q%’Àiéð¥‡^;0;Û.¬–ÑæƒY‹Þ_õ‚霚p†£ÖäÓ¶]ªj޳)Ôͳù*ïqj  óø/2ÜQUºëUañ™tC o®ã‹Kõù˃öú²dô»¯/+—f½—63²ÒÝÕl_Ùe}á¬(Yì‚1ãŠÇBS‰Ø:úD µÓ÷ðšÓ|ÉZis0Q~ÁÉš¾‰Ýݺ_*.±4y¶a^Aq² 9šÆ÷%NBÂÛ×·hØdåë{õâÁ-]¥š_CO­Í¡¥.Œpÿ¸yZ¢J–®üxà9C±ñLØÕ\½ˆ«‰kûÛ#»ƒØ›d­û¸ÎÂuðüuÉæµîݾñ_Ïÿ‰wwÍä´×¿\æ ÛD=/[E2³ÐÏœ¹çÁ¸Å”¹}àÙ¯Z HMÝ4O|åèsËϼ-Jùuø¿é¯ë¿tפc& ŸÈäë²Òt±U_Wª[rŒÇ!‡xöÈÕã–ŹMÛÊŒ¦°€ò,%ùšý;u¬û ܽԴ.ÿü§r€©úÎ ŽgGè‹™¦ª(¾—÷ë9ßhö‹ª8žvwJ &#ùKü´|ûÔZ€°Ta×â%ëA¨S‚XÜ<»£® чA«$A£küêñ“g' þïH–•ʲ[†´[6Þô:ãÝ*ƒ]‹ ‰íõ=ó6UÒýö৉¦a"òÀÁl'rHuÍ.ªì@QûàÉSý™³ÄËš *jsZÓ}Çû] Ýا ]æ…å>BxrüÒáÉf±öObvM¦ø;yaƒÖïcŸ27ÐnY~°é´þé÷öÌ=›æzµC§ŒŽ5MÆæ­Zº š_:åÈO“ ×CæàýÝ‘Kf8MK¼`‘3EZÉyPN.²a¶z)á`/VŠ:н^°4vZÂ’“ؘÝFÏ“¢ê yÞ _ÏN™ !Æã¾À´YG ÿIF¨Û–°@n"àÓ.°¶>\ÝNj©‚×!+3Ûà šZ3÷~Ÿ­Ñ¾p_š¯ /u¸4z9¶'Q²ë¡¤»ÍÊÆ“sñÑçÔ “]ÅUoÙt ‡‘öR%ÒZç.e%ß Þ_#˜CÓ7)ANPÑÇ!ŸÊöèd2À3ÜýrcÍËÔe+k 9ãjy_³± ·ºÊEHÛ§õFáè§øÿµ1ap†éã{CRõ÷og ãçLˆsWK³§µOQ¨’}‡WÜ[`3Oc̪Eôõ½=†Mú0{hì´ ŒÞëHDNÞë½xœëBDÿÜa Í›$›E"'ߌ™ç|xþÆ­·„½ï ú;Ã>H°Àe¿®I’ÃK&î"«áÀ~ÕR€MƒÚÉ„ Û¦ ~QžÐ²ÎkÝMµŠÙ‰ß_ÿÏþTïóÛ7«pæÏžÂßkGÇ7Ýéö6˲o˜0ÔÌ Î˽ܬͥ ±óRq죡F£²Ï;Õ ËõÁµru§¯õÅ>>W¶ÜSliÚé?»6ŽU˜v4+« U5Ì]1LðX<µæŽÛŒõ²V+-¹‹6Oû|~Êk¥!o'Î7k.öØÆå9íñ‡¬‚pw“ÙU!Ñ0òJÚ¬&ƒBc€ãµ…G _é¦W¹r×N\@¥T¦`ñÇâóë?>MľE;¢ÁèÊ[ŸQ\)LƒÁ¢Û£`áæ[3t'Ç»ýTŽx˜ öèq -yfRvŽÍªž'n±@ô÷«½d½Æ>ºæ˜ú SWå¹ÈæÎ9#~%m÷ØØ´*&&¡7à¶œïæÃ£²³ŸVÇŒ›Y0tátˆjñªu ü@¥cRø70G²®†XêïGë·f¯Ý,P'oïfß)kîoö1BVu_ãÉŽZ5 ÑWÛß4zSÞvÄž‚fS…Ä”cy˜z×çDZ#Ýw(wcmÁRfíîÍ›ÃmUGíåm0cì„t¬¢jðÞ± ž-/±sجçΰQ¡ô¢FòvuúIJÔKe˜µ‰_ú‚„ Ö›Ou™9.‚õ•vP'¸²Ôý(ÆÑ޽v+e]udV>¢;¹#1¸)OÍz›¡J)@ÓÌ»!ð‚²3°¶½o‡ …ÍB0aØ*åoÓÍ‘W87>cŽ@u'¾Uåã=ÿžûØ>8Ø}«ejÁÚõP¦rng­ÏM‘ëçï¥ÍfíhªõhÏu¥¥¥QA>ç–©ì¾óËðÿïê?ËÉÉîDŒaVÑ^¤`|ʈ»¯«,oLÖ²S ÐúA'*ïe'lÓzN©b,)åeŽ#ä:#œ~äåËÙj©D"èFòè´#š”bojí=Ñõ9ÖJ‹ìÌÆÚŠ«žIÆ,‘Ç›7ÔÏ„áÔ e»0düà½XI‚Öz&`šö]IÓ+Ú/bG o(Ë]pµîUMI:ö¼0;ºÌnI~ˆ@ô©ÓoZž,®quÇ•©ÜÚ£û}×¥H>mš€ÃMqã%³nEtîÚ§õ ñÿñ-ÇzÌ}ç„§'>Wi *ôjl’ª lÞÍ:7þpZEÎཧ…Gþîúÿ§ý½ö»—ìðŽÊœ•‚9ÎÙ£<Ñ¿ ëÇ÷½¤ÇžÍoó‡†ÃNåœvûJ*¥Äå¬6 Nªrå’oØ>¨“2Ù ±ãj–7ŠZ¸Ôã°·ëÐÕ#ùƒ.z„ÅHêYñ$] ¯)ÓfT ‚‘OÍëÆXc7ݨë`ËÒÎYÈ#Ô¨(ÏŸ–êmÓ8âÛ$¾,Fn²CAÛ6gñÄ…ÃÚq°üè²Ë_]ºÐùEy”ÔØ¸¶¤ÛÖ'ºMD¶Ø`Šy’mL,`3Y—`ïè!¯–MºÚ¨›.X…OÔUÔZsÐbå@f™LxÄÎÎý´ Ñ_9n@*ؾ²-ò\hcÆò”=™0m÷g|sý‡š÷ÉŽ’`ÉœÙì;«;nùY~6×`p¾)닾Ši8¸6DEëÏ¿: n› š4jO ¨áþªõø:ÑãØðJÚ™{>Åž~L­¿íËeȱlnçLx8#¸Foÿ¢¦$›X¡÷®ì3¤Ý’ÿìfµý&»#çd¦®±õ¯ýä”re÷Z–‚9³Ô|6´€~‚C8\\¦p ^^̫ğØxÔØai½ÞÙÖÐ*¿ àÉÅ{¸×ú!rX¸?ŸIkñ…… —×(˜,P‡ÓUÝã¸~Ð×E/Ê¡$iÔ´"§ã6ˆg{üÒDûÍäÈ·Ka&/Ú9rMZ›rgÞqP[ÿé¡«•»ø“c,èmÅm§g¼àˆ’2©\=ÿ›t鿞ÿÅŒ¯–uøçÏr,8ûð´Ó·äl+p0;4`(L0ðö©²¹·cÌ"ÿ2¼Í1zÀ/Ó¿­ÿ³.º ,¹‡ÃÖæÌ„sçÆ%EîÆÙS¯EA£Yá·µ^‡Rjªlœe ¾z‡¶È·1/Ë®ícƒó’×G¯òçž‘7Éj?e€‚p‚P(dÆ >wj ôkÍGŒ^.WêÜ(¬1i|’¿ZcåCôæ5lõÒê¦ã¹Ì€Ø:`]gÓs&<.=?w|¢¦ª‘všÎÎ\¿t> Ñ_%)ÙqÑ|Þ¥LOÏ ”—Èç¸Îu@b»á’Mõ J–פa‡lÐkÔBÖÜ ×¯›?§Ó Éÿ1¿AYq`n‚ä_ö<ô´Ã¦ì¾ô{ë?çg; ß¾y¸‡üì)üfíƒãêí¡¶JB¢ÄäæyqTš±i”sÄc€+ ^#^î+X3ZΡÁëäã>Ø ÕÊD½'éÞ˜Rf„º…Ýk‹8­]¾7@;OGwR{£IÆ›Y' ˜@ÉÞåcÒgÓý ûáƒ%¡k`îéCGlfMò®‡[9ÕÈ~‡»RJׯ-LäºJø…˜\Ì•“ÈUn± è{MÖÂʯë<Ìt¥8'D'tu¿<n{v§§mgBZG!e{‹/_'¿MŠŒÌ™{ŒÞÈ{5 8¼zžÎø$d3žOõ>X7R{¬í-S½}ûýÍ‹*ðˆý\÷=¶Ç#Á¤Ê=_&PéPR ä3‘ÇÐ!ç¹`@çyuX3þÑsÌ)çÊt«†Àâ;Ž@Û+ñuêÇ|¹+R0:èÃÇ(ÓšÏÛÐ'z~u„=yhý÷¤lmñ$U±’€§G¬£C´ß—SU×<¨+`ñÇo5@?Y1 Ò¥‡!ÒXƒÉð¼ÎXZ:N¯áã‰sI3r²;9­ÆÉÛG ¡Û´žmaœž ¶Â5Ø|ýÝG zÎЙ,îò­ÍDuƒ9’µ7]&Ö*Ÿaxf@Mqü¹ÙO©§æ$BŽ‘ÓŽù÷ÚRvO>© eoô[q Ï® ôœltc}‡Ñµœé€úS¨Ó Ý”Vëd^MSÕ=0f¤‰¹mÍ¥W@·¡Ä:^ÖÙí€-ñ¼á6øß ö8}»©ž¢óÞׂ2å@|$ì¯ÏÊLÓAÈPdo(Èaô_†ÿ¹_ÿ»'JådBÇxÿÅ:Ù짬¼ÃØÄÚŒvÔY_k›8>.…˜Ÿ­o¥FwvçGù9œk•Ï@Äápn.!®ë2Ñzsø‰y‹õîÔ% ß’°Qç5PùaúØù+µY­ ¦AHþ¶(î¹õå4Ø_îŸ1-ïâÞï2ð«â6gZm§1–m{ °kûbYƒ™32FÏY¼Ñw¯vU @ô‹zÎOWb|{²§/î 4(Þ-MÆýÙ§=ŸTÞ¼_¿(˜¹6.ÂU?ѧÜÓ{òÇ#[;‚ê¾<}“nW^ŒÖŸ<¬ÖV¤?̬©[í·×^bÄz…†‡‘o àÀMóQæÂ†S;’ñ¬£R…:ÓZ­ïJí¥ä艾UjÇѶ,Ä¥[é¸û}¥¶Wc{óÜn­pùqH(;å»4lšp ½Á;˜‰\¡+Ìg.U™I*åûVܰ¿á,ZL¥9‚è$©3 £ ‡ƒWÁr\z¾pœÂ8•Öyz·áÀÑ`mIòy÷§WGÏv€jN¬èº¶¡w Þ)™›¼œ2L˜ 9×µ-žÂ2‡x¿w¬…ãô§€ ow[3ä 1¤»Í¢µí#3aff*Â|dž-RˆòpFîSx…‰»ädäÃdÃ"»âE*•qØE‹3\yÿÿ©Û0çØñl‰7sì©Ú—í•уR–êG¯èX.„7,7§1ëâ63R—í¬àzþ2ü÷ú'ôõ÷Ž»e‰~ÞƒO0öTÞܫæG›©hÍrÄÁ …†={8|ò€æÚ±;Çr"þßSo¢?„¿ªdÊFó½M8l‘ËÝ4ÔvË&&ö,܇‡á_žZ®r}—!ç×gJ"ùK2¿%ÅZ7DÙä‰åìt&КåŸ_Ë‹{ßâ<ë^¬ÀØ\ùi:£%€R»¾D–- \´bw é1p G ¢/´ýMÕ¤E ­zîûç| OïbOxk›³Bs_îÔ˜Æî+õð÷ëü°û,>’·:Éÿ·XÚ×]Ù°â[§U^?çjð¦ó×ßXÿ¶úW4ËHügOá/¶ýÁ u. è›Ûõ$Kκk›¬núXÝvíøNûcw_³ÒñéíAÊ «J·ÏønßS4«°'޼ 7O}ÅB%­¶·^5µ¯*~Œlìî‡O™Gåá€WÖo[ሴÒ×*ÃëµÜ¨´àûieß{B6Gæee372†ëˆèÓ7ßY^kGKíQŒkÝÉú¹1«ªã}©èû䶃Î÷ø]y€¯»õ¶)uÃÖõÏCvV)¹l\×@D{7Á”Ž&t Ì6»wBŒ† ÃØð›Çoµ4jl½7%Ëþ0­¼I÷óÃh†ÆTÛm¶·á¬ûf‹Côɉ—Ø NÎÎûøI>½t^⌋ˆþ®c"÷\ÃÝpçà Íʼ^|œbC¿b<|›C›Èåzemðƒ•F%q€å¾«G6•©Õ ø»'¡¾7Vö4~é³ð¾†õN3Û¹¦¨¿;μ›³­ëiÊ9ÅmÜ Wæ^<2úÙ®/VÄÛ\±Zbbƒõʪœ¶©Tå„c4ÙÕ ù]SäAC$ýØu¾IKP:”¬Y¯ÚBæï%ÁØÈ‹a1þ3&œx2Ä"TKóÛ Ù÷\›ÄF¨bKù1'a ¥)ÀÍ—¢Ù¬Ï7DÖÍk9wÇy_ªsø‚#§»¾*m¸ôî©Ò¥¬*ÚÓ¥ëß} hׇ§9Ÿ`UÔ>äx¦½V’çœlÐ2cÑ•{ú«ÿëù¿8}æõ°0Éð? ã•ÏÛ‚#b·TªD¨NuXÒpúöbÓ™Þkv¥­ùUøñŸÑÿoŸ½ô–5W/¨Zš Ñiq>–[Þú¶÷îb¯ÑÓJ®™ÐÓŽž @b5Ub«J}74ƒãÚ›N’?lʦ](6@òG³Úi{IËÄõþí´«E\ ºº¨,Bò'}{Z—!‡/˜™àÌ8Øñ®›>ÌmÇwħ£Èú¥×f$€çJA˜–å…F«VMá{¶”4ÜÐ~QŒèÏŸSþ¨ÇjK>nú4›¶gNfñ6ÛR|ºëÃÀ¢…ÃÏ_¦kí¯Bòþ9Õg·Àý3ˆþšÍ.OÀásך"_çè·:>aôqóU56ý¶úÿg; GcØDþì)üµV<‹èÈòs}2H¹<‰áô-· Æ’2^ æÈŸXooWJ+0˜Ø|!^ÓßÞÓpìÕPWÃB€u[Zh‡e YZê3Cáó›m鉺KÛÁù\¹Œ‰ËúÐæ,¨?åÓðzX麯"ži¬„盳EaáîQkBê Ÿñð÷™6ÄÕrW ¢Béu>é À§Q¡é Oì@{ákAô]z¿3Ì›`Zæ´"éJËyXmUæÍ†Œ¼Alž°Ù¢o7¾p·"úZ›d´Ù@Ù- hX»S6i¦šÕu¤\¹•^MzëôpáÒIß4‡G÷ö´Ã|yÓ5Àz Œ6øúí €ÏNb,ðÍo¾ï_í½ÃÒk\ÕìMÒ®¿µºNÓr®•˜3L·Ü:î=´B¸Ÿ[`Ó†fÜ4Ôšº.í¿oh¾L¼APº!<¦kÆ:Ј¼q2¸¬Ñé` å¶²Òôä+ºîžÞ¦Ô…Ãù )K6Sš Ÿ±ÎD.u,í[9V?7¸ž y l•ÇûQô:÷µÛ‡‡Þ—îÅ ‘ʹ…šlâÍu]Ș,<  "ôMqÄ£G%(Îmdàƒ\³[tÞ¬¤tÌÛ³ëÈÊÚ=ÿØG·²÷(çmˆÀAGpÚ­ý& 7h½1S¶]|ëràîí_…ÿÃÿ)ý_°¤õ|cVJòü‚`5krá_—6 œòZØ$ÉÆoœ £ÚGœ_Ù Ìu÷ÍU`–£ðÂGÛ—Ÿ&äïÅÃÁRIiHÌîùl\ìt>Ü@1‰²«º}—,È-óywÉß‘¯Øë§eüeŸµ/‰ùôFWWjrA¬ÞÜ4«öFÀÛG¢~òiVSààòzû…o÷7,ÉiÔÞU9 ²uœŒ¢¿XÔÞÙ ±Å3‹»þ–9ÕÅeákœöÆ@(àÎDŽßÔõ mWÄÜ9™°äx2ëã›_fªÅ6žßSˆ¿Ùr\8žë†kÝz+ ÙïQBûMõ¿ôg; Ks£þì)ü•fÑy?ë³TäR»ÔýS[اG×N·Ra3€!ôà°ë¥áNÑÙàW&ôHJåÕDzæÜcfVΩ(”÷Ú»YF¦iK0ýÑÒ W¼3=(Ò×ZÕ¢;ôº/Û¤aaãø¶Ëè@}!úfÊãm1,·ÑåI/ØÏ74‚ó ˆ·Réû鬀Eu6C¿yôÕÆ¬Ò  uu†iŠ‹#ƒ°lõÛƒ«äæH9¥é–7‘اÃàY(?{Z"{p0Z<àL?t¿å™f‚¾XzÚ˜¸zܱbÜ/8½²™{´í…h åÀ¤ü8LàÔìä6µæEsßÖ¯è˜!›Í]+3.¥æsé¶{Êç«þÐa¨ç»…9âësâ)(†æ¯MÈÞSlÙ½öÇŸáé›õ‡¿ý¬à£Ôa®Ü×}b\[ °>Éñ‹uÁ³-Ÿ^[*4«a5¸th,£»WO„ËHÐYü"Ö}Î E­Î–ÛNÆAu]ÀälWŽ“áœ7záZý->LX›Á ì”ÿêyñèç$¸#R²=ÎøØi•°]Nû´î°\㛂ÐüY1n³5^§,Ï›@-È’Qo€Ô¤yP¸li¹HÄñ+®V‘é/_Ç^­^8îÝ£üôB†š޽yÖ•V“Ã; Ý0fXsðjIJÜã·JÈfß*zw]†­ÒÇ)Žuðàs2О æÊ4‡ 8l‰ÖÚò5ro0P.´.¦r9ïR×üá¿Îñ|“ˆ´ù‹Þ=÷¡£üèú+®pn=ÕÃß­{îeÜL„+ês<äü*üÿçôv>ç§ó!À"…k/=:“ËQ|pe§‹t[€‡?xd/çN½ÿL( {VÀm­l18·°/o-ª#äO0k§øvgBþfŽo‰ò¬œ7ëÛÍÜ€ír6’%m➯sº¥BRÇf‚käÞg“8Eò1@»’ªhè=!þ²Þ‘©.ˆþÜ‚òಎrØù`²/¤/Í £jf¯8àú¦Û9ÑÇV>«a]Y¼\2¸ Í1D&.Ö_BNe¤Ñz—*v×7ÚwÌœñï®ãÜðš-÷è>dl켚CE%ªa_‚êëÁO÷Ë·bËÁ>>V ÉÿoªÿÚ?ÕlÃbJ €}ro˜ígÖŽ †‰ÝVଠdâ´vÃ!6X]æ¦j8Ñ;˜öÄz¿’êD)2׊ՂA6> öøãäÝ74auqäÚ %fL*`ÏY™R¼¿¨Š•U87ýŽ'–\yygçGE¤ÒãOß„ÝØãÌ׎}ô¹4€ ?¦¼‚x ÜVÉLÅ}ŠÉ®h†ËfénÄoµç¬™ß]ûäÁ²¢Xg±C;4æ®ßr®cÓš°Fáæ9&0¶ûj'$LEô—z]`‚÷·öû¼ý3‘b}`n†U×#ÞÞû¤ÀÚxmŠôÙ+Ì©Ëä_ÁÜ¢¾¢e•}™&&ÙmQ}ðRÀ9U«o°>üÊuس'«I>m?ë©)XÝàmî)8õØÍ»ó²§8äôäsÄ,VHVNAÐBzÓÉ&ð~:ßÖë•Í-¿ ™;ž/²¨Ï*ú¨Hy1Âëè´¦P×u¹ÒSß4Y=Ö9¹Ú&`ÃY.å1-VVÏy—hwãµØº ›º6=HrÚ×Ò‘­pîˆÁ¼ c·¦7J/MUjB{"5v,ä ÅõÚ£¿¡ }µ] ýéÑpчŽnõÉ·vm–ò£M©ƒ¿I~8ò­x_ýÛ©[F spyv¬; ï'9˜<¾”jø%ÃÊÓ¾ø?»VM í¨øÌ0%¨š»ªÐv 5d5¯J=“UWV”[åæ|q¤¼èŒû¿ ÿÿAýßr} —»µ9ÞU™UFH¶h×úÔxÀp×îæqjUnÈ?7v‹Áìø\lú õHBþŒÇ¬ûpù+O8“– /¹`Lÿ"Z3|{°láVõÉ—ž óü¡]yï>9EKZk4Œo`ÊÊÅ!ž9!û}ðå™ÞPe¤/[m 0Py^ ˆEU¾ò¾QƒèOïC´fûX5oHý„¥¶LÔP‹yºÐçv¬ Ž@F]"ÀÚbë`0Z5C>Z:îiëžÿÖèjz¾d.@rgÑ(©rcÂûI-‚Ml4ýÚÑæd°Ò+þMõÿOû§ÚoXP)îÔÖg¦×&mG’VµiÚ³¯GÛ<8jÜØ·Jç'³™àvyzCâ˜÷‚þ@×]±x`Ru€ÁÈAž9Ó¯:ˆeJ?(2)dìáº>žA­ Á Ú‡a‘K'ÕeGòjðÀìÃK€ö—Ç×ÌàÒ4¹.DfÓU+ ¾op‘þHÒ¯gÊTpnÏЉq,9›ŒŠ0e[Dÿ¶“”sÅɹþà¶å¦-Óopu=GôÀ9³‘›×ÝÍBÚ·Òü~(¸ÞaÝÞ\&æ´&ƒ0Ef÷»ˆaêIMáþpðë3ÑßK[¹KE>c“"ó<^‹ûÏ+ü68**ª“Y -²Ò‘…èkùEë´p.8.˜àÖ89ÎÐç ¿iNÅÔ gº‚ òdGçøM=gvã̱SåZZû!­úö›^`åùËܤrÀšÄXÞ°l¿ðj8â]$âßþòÄçQ«²^ÉK–6ÜÍ9wãaÚƒÒ¹IχÜ»ýò‰¼VÝP™‹åý_é=‚µÞ-R¯ƒ•­&ä%úÃ"fNœ§-à¬7ÿluÆÒ$Øžn#37R ¸K™‰[à˜æ-§ñ]…ï3Ó)×ÕÂæÁ#ã3ž, Í‘ß@“v;µYjUöj–r¾+Xî%M¾[Uˆ!s.¯% ³ÊYs]”ãþ„Ýqî_DÖ/b¶ öøg ãââ VÔÔ!z¶a'ØuA:ðË Ä„Qb·òvþáÿùMÛ} úÖ·P°Ú¦û—šÁLßã´…Ë.‰ôu¯\å,uûõÔ_„ÿ÷ÿQý°áÚåê¹™ÔäJÅÔ(¡™¦*(œ2}¡²¹v¶Ôx|ݱ¶•ïרdéß{zËÜKŸ&˜ÔNÊßÄGF^™`U¾Ê›Ý’üж¾~@=’¿ôH©}µþ[#Ài»È¢Ð.$rÃêÚd62LïHŽÊ|ñ­: ú´ØšÍ+C’½hoëÎðøWÅhxé,ÈEô—Œb…K£9=o8’ïX Vó2·~îlƒQfÀ<Ûw®øÅ‰ñå t2ü'(#\neyV¹ÐþÌÆ7[7.ŽØ°ïÛ¢X Ú˜xU¼`”ÌFÕ»çFåfTÎ5þýô?èg; U£9„ÿì)ü_6 Ù˜3@¹çs»à¸…w0úÂ꺮¶¾ds.¼º1ÞgX¸Bq_·)ºÕ–5Î…U;¡´Is\6¨§{„¯ˆ«˜QÔ¹¥&>[àª4ˆ×ÛäˆÃóÂgÞæWå¡$"ÿõU¯!p7kt¡þ¦Ý™æGÁÞ pßÑ£ùÈšÂç3MmƒêàÅÕƒ•ÉÙòÖˆ ÒEŽGÜ^®1£±È]˜Ï“¿ … 6s˜d9¨Ò>CÙkÿðÿfû_E}CÔZ¬ä>r\Ðl° &¿à0|l†-^»“Ü~þý‡õÿÎ\(13d¿JCü_t!î«×­rhXåO/,ï É{ àwC¥£^ãµ)@d®~ÄæâOÆ0NÖ½/Bþh;ÕÚpHXsÓ32h À—9:9K¤‹À¨&™!4Éßö{ù­ … îGxªqà˜žåQ¸ÌT´ðY ±ªjPj-¬¡-ÁÛçkb’Fìž1ÖáÞb‘÷H³îßW~mê7M©ã«w«Ë¢§ÒØ—¢´±°Ü›wQð‘xæAæ·!ªwd—\¤ ³‚XÝõ¼ÐŠä_@2ê­æ:ÌX8zþ®§(}wàò:3æ­5¿ŸþÿLçó/lÎÌßë_Tôp÷§ÃÌ“=c)ÞÞ3õ`0ßmûð0§Ï#9Ȥz„º4=òø˜ÿ$ÕDaÞp€\¡S“J¬¿ŽÃŸ‰[ïO×61ýF·1ÝÓ9˜øí™ç_ȃˆÔU`µÆòÈP_ÖXlq`··ËG1/wÆýÑ,úé-7g­.0uÊ´)8¥‚¤_õ¬öè ¦«mû ËØ³oFûÀ>cÕš,øøÈ¢(irfÑŸ{Xèºâ·ؽ{[J–Cçök75oðlªš--› v#†;àˆ¾xC®÷瀲§ŒÛÐYÃ{Ú%æÛÛ:K½é¥[ŸvOµK(…¸ÕJHí®IËè—zhóU‚éqãZáA`ï´N`Ü“²pxWS. :¶­?GȪDÏäRülDê_ ÃÖÉj÷ç§"i4âß…¾*¹hrŒ('"µ å^ë§¡C‰Ëºö6 /Èò:X!æµ£äò˜_?íJsðPÔ]Ï{mê¬ .Ñ3`X=p˪Òk©Ï´©–ë‚n·<Þ1,ZéÖÛÓbQ±v³oß“sËY#2ô «ße‚oäîHÏÙj¡æY"©øÁÆo\+ÓjKà^}R½(>5|H=gFh`¾ãž9 ¼¯žµ²ÁyÅ…ʶ[êïÌiC"®d#éH@Ä~€%)ÃÇÁÛ“5•ŸÔ,ó9ç ÅÙ?5ÅÚf8tú\AP^{ósããHþï](lGôw¹1RѦí¤%o2´¿u2}‘üxcœ“«vÕÛùnø‹7‹¹sÍ'o «íÔ—þ›éÁÏv@¿eÃà·Kôÿoè6(hƈ1 çZ!Z"ùÃÑjùŸÐ u¡iB½{_}L~I\fx:{1ùƒá8ôûäÎäò?_’Ãó>á?RÁzn¤P¿ëCw£°x#2{.ð&ÐC cØDöL’œ-JÏZøãðîf8x¿ò×¼LÞ$ !ÞòM ›ƒ¹CÏ?ÿÐÓ‡G ßÍ}?ܘÞüÔ-ñQ8Fg¡ît&Ú,Þ'ô¨lþ'Œ3A¥ Lw6ýÅÂ{pò FCéè7N¬ }ÉDóÃXà‘ˆ8ÙõÁH†âtŒ…¤ˆÞ 6 á€Î$Ç¡³Ð›Hô€‘Câä^2Ð"Ð XÄ>1G0&1)tÐX´MøŠÃð_œz01‹NìFp‹ÜuÔAð‘Ê!º\vÃ}x_bÔÍ¿ÿiMÿ㣈›™¼[0:°Pb†‡Pš9!LhÕ8Ö÷ ñM'åˆX F.³Ÿl¡‘ˆe ="„ÖÃ3'u ^š;â?Ñm+š±å¨?“ 9,Ã6’R´Ä$Á ´S81"Žh‘ $˜‚ú þÓCë'äŸè‰F¤³ñc`8Ñ‘Ï ŒXºB&÷’¶é_£ÿÿ?öÿºý["OB>\ˆS ºC!ïo¾y¶ûÎ’ºê¦ûôY¤†¼Ý »{°¿7ì„ú2 ±Ç™ü[úmÖ;v¯ªBËs®n¿> Gf“o¥y½{æØ3úL¡ùõù²kŸâ{ ÞUºƒ?—÷%¹~^Ÿ Ø_‘ûýìÕsW=€<¤Ÿ=øÀz~ö á½ôŽ,²¶βx*ÎÿįQGþÎìÙ2 wáp’3\‚zì_`#õ%<7“ÆBš0¾@c–ÇìÂ(4Ùé:‹A˜ 6©ç œ°!èN³@æõ¥ã ÿÅDë'íÐqÂ*“}ˆ[pr§0r’¤d`Do ÆvÕþÃÿ³T÷ Âℳ!Ì0±Å„“aôÄ,Äb·0ÂíÓÙ¤ g¬ÿ…øOý«úÒ OZÐÿé¹áîéÏfö:véC‰èˆ˜¼} šÏÅ“Ñ%_¢ŸF(•Íä­-ˆ7,wå §IzqČሒkCƒ’¤iD¼Jˆaq¦ͯ7Î <7± !”t"Š z£?ÄÍö\’[8¹¿Äþ#²ˆ0Qcô KFr$ÑJAÄ(—mÿýÿwx±ŸÐþ%•Ôs F§½°éû˜ÿ?¬ùqßžö¦ótõòaýh4z/÷G=#òÌ._ñ 2úHÌ’Îùôév¾>dï^§Á7Í=†7¬“§g¬ïí~UºƒŸwÏXhýßù†ïŒ}ÿx¾ïÊþÝãŒÿî÷þÞÏðÇAtm"pâok“S,žàé92‘ȳIôHl“PežEbXF õµ a‘:Œ,Iä`LžÕèä’îÞlÌÁƒÓqÂ:(‹€[„Ÿ'aCh8Ó“Å"nf`„ÅGÇÐúùðß¡1óc}Qƒ4¬ÄûLÿëùçLx&ž³¡±ùxŽ¿ÒbðÁŸÑˆÿè ÓÚð×á?ý¯ëÿ)x’ðŸÄüÅ ñŸÁÃÜĬÈhŠðçdGšuÿF#¢KÒscL2ä#¾Çxé&äÚxþÑ*‚…bQžûf þ“¡(cñ‚2T ö Çùâ[ÿ‰%8õ¿Ì§—ÍFôa2 ù'ƒ6à3“øÙwðxËÀÎ"´ßä_¡ÿ¿ù?_÷3Û¿"ðäë¹£»Ÿ-廞Lh?«ÀÐàœìs|3Ì 8x3á;ÌÕŸTª?ÿnœ÷zGìË7öÜȖ·§mþÓà£É~ù`’´U8«ßýÀf¿ü/sôãöMÔÑ—ÃG–¼ñ~ž‹÷õwÉcbKÔRýyßô!F¬wÄÞŽ=+B==}ÑG7Œ øAú zoΘÿƒ ¼ÈžâŠ{©+‹Fä&éDOö!í#²s¤9"Óƒè‚]8‘Ñ@F!œÀ@#¬“A@4²uhfVxÑ?‹†~åùy‚ÿ<àÅÇü$ò!‘4åÁ-Ôòak7ÿá¦?–¼A¶•ÁGq|ÀH#V[‰”2ÅÓ‡Lžü:ü§ý ý÷9IL€If…x~–âäïC!â~ÐØó 9QŒN£ú÷$$Üfõdý‘wgñŽžÓÈÖ1”ÁË4`» &½gŸˆ‰1xŒÁ òè$„̰ åÑ?ÿOn=ƒ7hoþŸŽ–Ì%|*9=ÌчC'ðòÿž¶Á>ß]ù1ÿÛ;¬§sôó)= ÿsþ·?8åÐ?ÿÛ_“¿»â± —ÅGM¤+é ÈëÈ›bŸApñòºFôÞyßUôžòôšD7¼³>dù˜šÒj$è‰ù1¾å:›Èâ=s Is fõ;$ ù+šR|OŒK$9‘a'éìé6a„QëI½?£Š¬ ƒ²ˆ ‘æáõ?ü?Ã"ý™¹e/õÏÀz??9Àá$ßœ¼ÿ7þ:ü÷ü[úŸJP%EƒpÃ4ÄŠ'2Ìü½G¬%øO,'3ú¼8“W%@æè‰C(^iy4Å$ (ž~¤ÔñŸïwÉ)Þæ’' ^^CN3¬'ÿOŽÍ±/ÿOÌ–†øßäÓl#z ôžÃ~2®àóˆàÖËV2á¡ùûëÿoïÀ~nûí#Ͼƒ+O÷ èóÿ $»õõ&ËI?Ó»Ÿå¦:s‰Ã§ïP\?áçiŠ]0ë?Áa?h=p£×Ø0œüˆ7+a§`/r½å^=™ÉgÓƒLwðé›D®û.ÿËpôöî³q¨Í= w¶ÿGÇÀ˜}'&Áá~¿ýÂ{Àù7yÄjÌÔw>ÍÆùI>âL@Ö’# ™D—iÁlž½ KÉ™#O—É“Wï5„²3ܳ‡¹ñjÓ˜Äñ+Æ&8D³c™h2H”@¢8 ¸ó1$á'OïÅüh¶dþ•Å‹ 0'ÿzþ‡&a½ÞçèÉ2^] qDKüô.a¨Á.×·ÿeøÿwõ?— :‡Lß#þ;yûðP<U.žï؉cx¢#Ã.„ÅwÈ„Dñ:y ŸnÂz éÎ~^AÄïD_îÇ;™Âˆò~Í!›7,…øßíIO–aÐ8üü?Ðÿûgôqº{Q|À“É•~e¤ïåÅyüD=‹á@ßñ»ëÿŸö÷Úïxöê9’&ÿ2ìþ3¾ÏöY²§™e.³·p)(›üR¢žúj³ø–„îÚ3N¿{Ïÿ³FýgI”õºR‚Øýoó¿ÇŽ|\HX ‡VÏ?^&Å}¼‡îL._uÿŽù¾À•ÍÝe !}áþ¤þú fï`tÜ(—KCòs‹ &Yõƒó¬ ƒéÓ{JÈ){âX<\@\¤±ÇGª7¿$ç @œ%Ú‡1É[hÎ,¢\‰(ã^‰a xIG:Ý‹OY?n¡kˆÿ8/£‹ñ ¨ÈCS óL $€"+­0òˆ3Ûû_ÏÿäÂá“è’ôyUÿD] / ¸Åg+2Û4\ÿ—á?õoëÿ„½yHŸpЬ^Ï+½'ï¤ÓF‚ÏëHs~r€,¤‘Nš¨à=LÀ½žªÂ}ƒe$rÆÎÔ 6À“aho!Y›G+ð+ I÷øß“Å"0œçÎ{êÿñ¿7ÿO<#À$žQà(üP@$üh‚bðNtÜÿ÷þÞúÿ{{¯_¡ýÞ¥W^ɰÝ>ˆõCÌLA¯-èƒmýÀ™zØq~Wš-€ýCf–w’Ø’D‰íÀa¯Ùï­ëчîÌpaðpàwbý¯€¯7ëß{ÊÄO½“Åüä±ÿé ’ÿ¾^dï~‚8/‹À 1øuDrŠ8>GA#þcþŸ(’ïÉÿûyL ’„c%]º½?‡É›Äe| ¼Gxqâ?Yðëÿïì»~•ö;GTÞ_XÏC\ »0üû(¶'æï_¢E–ÒôÀ4mIAäwTŽ/‹?^ŸÑè+îwÄëâÍùöŽÝ÷ roQo,w:•åÏüŸ®ôá~õÂàéýÜù_'/Ÿþ NíÃzæÜ[óõ?óz{ºû:Úä1 /ÜﳕÿyÈs1¨]ƒ“å…÷{ˆ§ö8?×HÚ""[Gžî‘ñ¸y±=0.ï9}¾Þ“U¿„åÄÉÒ3:QyFh÷þ@d@OçP1ð¶•HÖHQ©¾Èr‹àU,áüÒ>ºÂ :›_;ÄKÇòcÒ–’v–ÉïM"=­?ü?Ãæ•ráXo꟬àŸÓû‰4.cÃ/Ãú?¡ÿiAäCsT¶™î ŠFp^1?ðaðßAÌõpõæIwLJÿ¨žÿ0éiü‡üygŸÿDo›wàÐS’Çäìó@ûÏ«lÇ(n!=ù2•E#ó2,~þñ¿÷0¡'9€ÑìÙüИ(ùÆ+7$ŸàgqxA£§»ÚQŠÆo¬ÿ=!ùŸöwÚïP{`Z8Oªßÿ×Ã?} ®ïF{Ó^Hi=‚9=^÷Ž€õ>Ožu8³×šöŒ ÐO…þ£2œf| ïçR~€{ýnéÃ…nln¿ó]þ׉ë }7÷BH*Õ¯7vÇû»~M8³4Ý1„|êÆÑÄb}—ûR=uAý †ï²8…ìLïƒa´Ä7:À{^‡Œô ¯áI À1›`O÷iLÂÄk§{DO¾[ÝGeILþ;AÐú‰ãgFï ›Æ&‡pð',¯Êˆ—¼ÅX<‡øOÀ~Þ³Ûü‡ÿúªÿú^ Àº‹¨+¶ßþ_ÏÿèX€ågá=o”!,tÏ;‚Èô,›<Þeþ«ðŸñÏèrgTy>÷2"Gñ…ÿî^rñŸÅOô“- žzÞ:Åì=u"ûÐvF>¿À3Ð4qèŸEèIðóóö¨/ZO†7"AŸŸÿwâúô%ÈG¹'øß[À‡S$ªéñžÞÿ 69mÿmõŸõ—¼ÆŸöCûmÏ¡í}ë € ‡Ûs¹Ìß ·¾ëÍËïê¹æ1iDõw¤õ}WŸ‰çíÍ%¸ßˆüÂú¥ÿúSm]"q~úö»ûP$þÝD‰ËvA¬ÿMþבëƒÃ÷ù_^WŽÖàŽûÀÍ–xÐŒ¸¤ç ÷Eúÿcê¯o0Gƒ“¾4—€ž:_ò…$¤aáeK±Þ÷Ç‘3ñÚºoIh0ñêò1 þ“æ<A:ÂhØDᤉ#¤b0킘d™™($L$IŠÉpóëyõ ?ÿŠ‘l„ùtf{ã=Þú½žàøPŽ÷J"«»Ý῞ÿ)!½oýáù0‚'9ûžî"â)ÀuþSÿ)ý?‹øïÈæ9dòíQ¼ƒ¢ÿÕÞµõ¶QDá--… •úÀKÕÆI¯“Ú{›Ë®½Nê\\'iÄ­BAQ¿Ž9·™ÙM„úà¯ðªJÜx¼kûìœ9—ïû&«£/=ueYE"û+UÓýWнE¨¬¾xŽ€ øÐþP¸·¨’cXEªšê´^{uAŒ.öÎkÑñ!€Û e~l)TÁr‰ h])gÄ@N4ЍþO=zŽó²½KíQ_î÷tþ÷tÙÚ¼£§@&Q¼ŠÈ?j°ªþ;棥núð۫Ѽ©ºé_ÔI ]~v¬›;à_Á±´«¼*}¹lò£³Ûù\‡çÕùùü¦ãúoRŸDÞ=NÕàMu+aŒÚÀòLù(døDñPëßg<ûï(ý…LF§Ÿý|mD<`åp!ö0HqÎ4 3¶€¶ðùÀ“i Ž  žZD±á2Sb²nŠgßXÒR16†" {;ÉÂÒ¥iu¥ü»+ï®jFÿ•F\ >äxÁ(îÀJ¦§Š{[ûÿ9Sýg@¬Ëb€;Õ²r¨ôÁ¦Ø}óÿÚß2hĨVеŒ0ŸÆ a¬g]†O”ÕB^‹ÅþXa—žÏ¨MÜç÷ÚÕÌæ{~Ãô€ ÿßD‘ÔÇ•Ž“|”ƒ‹ÚøæM›Hh@në8û‹îõtþou½Œ²xžÓî³^P¦¥MÇ!ãzºÁAŒž\~7µm‡eqÝDýìÁëiìöñÔü«•@ªÉÁr¦õaÝtÓ=?±nÕiœèÈû§©!æü˜•!‡Ä1ùpiînËpüÃpÞøêè ·ØÛ4 àä·›ª42€’EÍ ¨èa^’WœEH3Œ+`KǧB'õAõK9ƒùÉþpÿeû€Í+F¢„?VHÄ«Ãö@(„ކdú†êÿebOBýDqÓ,@€ûHh€´MÂjÒ+V¨,ôN«>êßüÿEb{|ðÑ·€êÿ@  á¿ÌórçÒzGîqYZ3UH‡»Â×ÉÁrj³G?^·›†ÁiÜ‘‹ºjBJx õíOV í‚Ъ¥MÓEôŒ¤içê¿þÒÅ.l¾½Ø×¦ÓI ä$ŸÿŽ60½½ltnZ)aöHë?êPïÓÒŸ¼ÛìÑ÷?Hš8š6F@UL".¢ ^í\¡#0¯J' ˨_)-Uù€Å‘>®yTõK÷¯uÔtãÆ³Šj² ÷C0µ—ÞYYZÝIˆ7y(‘öì.¡mÓÖ¯ùý­ýÿªKÊ"ÁG¥Éé x›ßßû—ëžÿ¿\iæd>A‰´Ç[K†¿ûREòûNi ,Yä—ìp¿¢rö7>/7¥ :aw!H|UÄ äÎþ-ý“T'*T¡a+ÿ" àÅ¥`¾y5`xÆÙ?ìåN‹;÷jþÿ §•:ÐÚPxœì} XM]ÛBRÆ(%óB‰ÌS¦”&©„J³æyîLûÞg¨Ó<)!%”‰¢”¢!D†HBfeˆä¿ö>çTžçý¾÷ýþ×û¼ò>Öõ\çÙ³öº×Z÷ø»×½7!øÝþ½Í)†õ³§ðh^Ñ^”|íI5É«ü«#˜Aú³gÜÏ–y7Î1횇&˜Ÿpú‡‹°Òqé€<‘/ýÆoù}€úð¦¦jÖ`o€Y/¾ ªÍ^+Ç6?ÀÍJËÒHX´nS‹=ê˜ÓÔ¤°Ð”¦Á€ Y±kXÛeœ¹3]Oe$ÙGƒvÚ*©&’¾­g‘Yt³Ã,³‡v Óa±îSÇ6D¤e,"|Ž úðæ¾ÙMóõn“Ôh“ú‰•î- £ßøæ-ÚEvØhÙÕˆ~ó‚ûƒñíW‡Œ–x0m­ÿÖ„¬B3æ<ÙfzrRæK<Ⱦ¼éÖ÷GáÛ!ÿ&´þ+‘!Í*â«RÚãŠö*yîÐu“Â,v-®s+Côø½<ÐÉúW_]\w\XÌü¼¢¢Ÿ ¤¬é·¹É>ÏŸ*z£à‘¢'Àöó4Èiœó¢º}Ý­¨¦ Y¹Ÿ^ÛN2zÿ"§f q«Ê„ É¥2†ÕON‰QéRÞ5Ùi–ÔöÛrúíšjevnÞP;áÑÂêî«&ÁÕyœð¢Ä0C½@Š5Ôö]“ñYLi/˜6÷ZkQ.d+ëÌÞý¶OdÝzÇ Ì5Éh.è¿ÌýÁ÷W—e,V¿}À0´Îh ¬‘6Ô*cöáaÁ®«ç.ì£Y{ÎämTéhuPÙ:¹ô@‰•¥ñW£_lAÝýPn¯‰*ž´ue€}¹7sjáÑq‰ú!Æ99tß²-ëÔØf‘±{þû“¾Òö £ó뫃4>a†jWW¤È´ÛoêFÆÜý´i4›fÐ7ø?ù߯ÿQ«ºOˆÊCûšiº|æð¡ã¦¯úÆ1¡n¤¹·3ÁÀl¶Ô'œEHþ¼â–¬R å/'o÷‹$ÿm9°îÐfFô³“ž‡oÝÝ€ø€â€³<üA©{öãÅ[ݧ›}íò±çm© Eh:É~žTð©Z½UVaN¢´«Ég¾êRÈ\ ‘=Y–S72y‰„¯‹>@Ò€ƒïpÉ óíïÞíW )êïg"9þ ù5Ñ?ífn p*`ç|P·¶½•†̾‹#úùßß ÝÆ¤BÀ¨cŠvEFÁ7Üe:¢¿pÄìØš ¿”þ+ÿLçóßÙ0ÇÄŸ=…½ùï׹ݓy~ ¼ŸŒ2_>8I:©ùe.€ÎÓgÎŧކÃðšÈ;‘o4¿„€ÉPlùÐÛg÷AÀ%µ X>ãHfuœgk@K’òá»®C8ÐØQ¦>`œã˜.&8^t1àR•Â&yøë±³ó7û¤×®wZÚ”ÛÙ;f¡™·Jv'éO¿ÉŠìösûqKç/€ Â:©QÒ5éP_Î>F9è³Þ ¸º“Ô N ùß–KFf¬PDœZ8Jv‡W(ÀF•+k^Ùîb.}éqÀ·‘¾çbåé•\oõ §–sÀõÎXÛ"Dÿžf›0;JžÞÙã2XdÄœQÃÑú—œŸpwŸÒ¬Ý:sä>ô);î/²Q%”c-ö-8 Ñ_Ùµ¸]Š#c·lev`'¬aEHÏ©~Œè_²ðF“É9¡áW˜]LÇÓeRlØ$/ tÙ™J5†ë"yp¹²Ý"ºÿ³ÀµúrŸözØ?;c'æt¼fërúsOe(j“Ÿ ÖÁ»¨0´ààN8ýýd8쟑6×Ös,isC+ƒÍåOÐ 'ˆÍZß —½V,ÿ¢ •Ï}šÛUv“Ž´6KK†7SlB}‚œBZV†â°5÷ÆŒx«9Æa!ôÛŒ¦¾\ÝìŸ ¹àtÜ(4÷Ñ­¸G‹ZÑ/ÖK=¶uʬ‡Ó:›Ì›UGÀÁDhí{ÿ•Ñ'Á;Ê= †I~ðlcÍš°(àôôEwûÓ„†¦Ê¿=ÿc÷:\‘`¹¿Ðå±Ób€fëŠ4ª^‹‡äÁÅû 5¿¹oðÿ/Ñÿ~/£·Ž–`ÃÖ@óê¾û­C¶fwúêò÷l1€ù®oË5ÇŽƒ€N¹;ƒôå²6ªï³˜”¿š½ñ-»ŠZÍFTª±:¾j‚eŽÜ’e/F‰€õˆ¡`í–¤¨ž2¶Ôl‰Í µ½p"ebø‰ §nnœ Ñ[­×"p¶îû³¥÷™Û‘}òS’¿ju.µˆ|¶®ê©°ðe'!ÓäÄ6ì»78p×Í1HþòN;MªAò7bÕЈx¬n:v-öA2rÚOÚ½¦Žô’þ³4š㈾·;Ę—YoÀfćâo 82á°Ä{Î4Dÿü-ÛûŒ¡°ÞÛõ6À¾!—çÔô”ž½ðx¢?Å6ä5@¸‚jËÙ éž‘úÚU½Ý„üëmº]ã–ÇPNFÃü`Z&ƒèO6a‚W|ù¢qÍ¿”þÿnÿþæü³§ð¯5®Ûk°5ñµ])UkÃfÎ{°Í4*`ÑÊ+ߘ rõÖ†ÖβâÖ•ý ],Qí_š pO5¯ò£±u @ºƒÞÒtæÌÑ,ð®ÙÖ2N>mì)xuòíØÄ’—·XìoÛøH€Ÿ©Úaö[©þLð¸$9µúÌí!ÁØcŠêŒ•Û8ôj¥­¥A"Í\zÁÎÄqL°™Ö~#Ö3d ÜòaÕ )•ýàã\¹0ž ¿úÕVŽSíȘWƒ+¿Áéõ)µeà}UcÛ¿ÖÁBý~OÁn€ä™“ ÆÈ_}ü˜Ù´.~[KÑ­=R|ãÀöÆ}w„?ƒÁ² ŽøØˆ´Ä™¦ˆ¿€ÃÛÒìt©\|•‘cîv~ÀGDÿÕµ·TÎÌ[ðú÷Ò£.—oW•M~ƒËéybA×þú`ÿ²-BŸ²¬}™œËƪýÅ4ö¦ÓsçhÝ6¯P“:¿%ðÔ’À¶öí\ó[BMþ»²-MYçòëáî×=ølWqãåÜá^mßÊ SÙŽ /WYÙ›4oa޽(&—œçîÜq(Ì4„F38‡|V¹hÞ¸d}µ37߆=¨Ò #“ÅÍ“\îËÁúW:€µIùû½ó׺Bjx݈ÍÐ)w}i7S§ pSM‡Çgl¾jЮ6V3£Ã[`E€U^×Y•7i&^.LBNÓÞ¼ˆ¾`D^Ô7¸4è(€µáý+Õ㎄qç¤{ Vcƒ3®-z2ý7ÿß }¸ú®D¹xÌ}´~YÕ•a#üO_=aòPÍ8µH·oð?ú/Òÿ¼1'áÑĵ&r¶‹VI´eË °±VohºÆZ96ز‚n}£SÀÚ6ŸvUÕ¦jÐûÜ»x‰—&ý"}3t'‰Ý›Qk̇=1ÊâåuæE€}zîu”?‰«ý$ðXĽüîkÅg&ÕäÚ‹×àÌåHM¿~à gèJ“ç£ýgÍž˜üàÑ3Ë:ÖC­”w’ûmý‡;:‡+Rt ìÚ›^m‚–zÅâÎŒ’+ˆþ:Û)­ˆÿl{ý³ T–½æª—cŠUâˆD?1!j-À±«vR€×M,lOŠ+°ÖÞè?ñ6Ñ`CòÔ¼(¿/ÃýÿEÜÔ¯×ã˜?{ ÿJó7;4ZèÜ»B— ì¾hòôéßäüÛæt( º†x_oRq†þqEq+…÷›qÀ<±ñ]S?ÏOL´.C^ØpÂû€€˜1W®ÏÄœ7éõ©Îklš¦Ò¦ÐÒ»A³çž«ÁÚ^íûm³•㎚§akMêëZhÿ +[vîë‚ÿÏÃ5²ƒ|úç‹,xmëÅ#‘4Ý÷ =úÐpü‰LÌM§3MÚS­ó1O.Kt¯0IßoMj`Û¬oàtö\G<\tV»fZô*`å×ñ¬>®Éø•ÅîÑ€½—|íØ¼”ÕM6г33Š™±Ð¤U1ÌbWáfÎ ,ð{'\ «½Iq8ß²A6d½Ó‘ƒf‹·Öm§š6<Ö±šÞþ¡ZØ•Ü'³c,\#%ù |Wït›#áðM°Mœc÷ÖE0DÖ·§ít9س[Ïߪ,\΄fŸ '¼ñ}¼EøÐòÝ [v³å˜~ìoÏÿ‰qýâÆîìqC%` ã šáÐ$½§0#_êü%nÌ——}‚ÿwÿ2ýo–`½µìx V9 Œ.¾ú„y¨å, 9Ñ9¸{·Âsmßé¹ cWã™(5^9:÷Kͽ!ªRVÀÿ^OËc `Úê:ïBãmÇ¢ ·îÈgˆ¾á <^èFÈß}ÿ¯íÓ)µmd:¨›ÜÔ§!„>¤ávóááÌ#º#o£ý¯Ì´»qg±÷M›#â^m@_Ÿ[u¯Ñ<بÅ«:ŸÙî0”ʆK6ÍRÉ­wá‹ýö£k¥EÆX¿^×¢# Œ¥!›^bqÿy6ˆþˆ¯ÛöXô+ŸiR^ÞìÍÆ#ú¹ÆÇ«—ï^ô±PK*ª¿ˆþÿlô_ÛÎ ?{ ÿBsˆ°[¥¯ªÆÖñ8ëC5UìM™!-Ï¿GÓ‘{Ì“ãñ&ÚýGÞ¸­‹m”…”ÄÆh¬oÂa‡ð —ܱ—Æ{ÊKŸonCP¢Œ;wb–fH0‡žpF"ïûU,eû«<´¬¦ROª³÷誜k1UyërêÅ:yV¤ÓõK½°¬®…W®£õ·®ûx:…Åi‹ˆè{—o;„Ö?YZq€”âc ÛCœpÍ–Å;šÙ‡ÀZÜìUÕ%WÅþ"Ytø^²©Wr²€ƒL ÆÓA#ÂìŽÙÂBm)•üÝ"Ñ&àdOàDPØj2 ªÍuCaÛ Oï÷S2aþu Àõª§‹à1¸)ÁºZgÆêkÆõO´Îì7,¿>Q¤ Îh•úƾ4oŸº¯æ2΢ZÊeì¹»ò8p0:S?2–»æ¬¿¤ÞTÐ|œ6Ç/D«¥¦?L¾ÎØb+_]¨P°‡Õs\Ÿ(ìu`ûšK«jú¾~0L}V@œGQú4€ïýûòé£ ¾Äª‡M·2ƒBâ#|÷®ÍèâÙOÒ³¸ì÷WÞíªy¡,Ï¿=ÿŸÅçETàm±›f0AÌû; V‚D€ûœ  ÂºØ'øê/Ôÿ]úc8Ç+pØ0bzgÒ>øK¿lØä¹]®Íöñ¦Ò s—U'mÉ"ä¯z³å³ïi{h‰?¶}[íÊMOzyT~WwÒ®²0¥6:±!ÖŸWÙàÇÊÚ-Ì‹æÜL¸è¸Ü,ŸËöÆ*L—ø¢løølhŽÝÓ¾–±NKOŒ}ɆóÞ¦8hev>»ü ²"u ‘´(¸ˆçÎY½dÀ6·¯†ˆ¾ÙªIk¶Š¯º$䟆MÊÍgù4¤ Cô‹6$]bõX:4·IKñ¾Ö¢6LÕyzàŠççjàú³úu®5Ïk–)õü%ôÿg; ÿâæïõ³§ðO[WÅ6ñä ¥¹x,­sü>\"å€Þ‰Î]î¯÷›ã¦ðӏ޹)Ï!bz^æêiÍsÅ€’k€Åƒ¦ åÓ'± æPJØá3K"! »¢1u猳™˜Å¡Ê´Š+É9ӞƊ>9ß¶Ës²b¼:$wCx°îEN‚1U™¡Ûö_JÒ—0~k[ˆ¾ŽÌÓæôÔù¶Î¥mccAå ß|…íòyY`­\DÐ?›¢>û(0R˜{•ÃY^L¯Ô'Ïöãã»±nªé~ºûЧí~¹J ù©K¦×q»#®F0×Áe¨ˆæÉÛrÆTÍp¨ ŒÌ { ¨Øµ%gJ;ˆõ;༓{>¡õgŒ1Yõ4sþ6DßGÂdæq"wdÞyºVjæ‡éJ¶'WìÇYk¸=3MlºeP›Ûa€ég³sdÂýÞ »2g¦m]|Ï'ko¸Bßãʶ&údP -)ãÞ^ûK¶và_*Rëçˆ#‹'žŒ‡—/„y¿š­¿Ïy¸Ý³BI•6êEчWÒÛ^¨ËÁñM7×m¾ÊˆÒŸÖ Ws¼ù&…ÙÖ 9·ðØ”N® ¬9Í„Qû³÷ÜX­ýÚü!l7T¿«‚\á%ÇèÖ–g°¡ŠB¹âˆá÷ÖZÂà][gª%žy_ 0ÛYóüZÕ3a@‹Vð{A¹•ÚØ*¿ É>fŽrÐy¹ûf†‰)i@µà9-äp€oxé¿›J=25©³JýÍÿ©—G> ÿ”Y¢¯Þv8j­Í±¥nz‹%±Êôúÿ=ÿJýŸ ]Õ¿ß#]y´ž¼Gý5@¿ÉFèzÌ–¤X°•5Ù *-•† ¤üUœr¶üÍ[@G.ºÔ7Þ(ÿœþ>˜«{rñ‚-ëü.ÂÆ€'êa„üÍ{ÿE0¢L®ØJ?ã8tjJ½Züì“«&I•gæïý%¿ ¨ûhPÙ^ÀÜìX¾tL —&ŠO*¹°•>Ž­½© &©†¡ A{ÐìÜMˆ¾¿ƒÇ!€jy–!’ÿXgm‡•Üö¯B}×U—Ñ/rÃé:x¢j^×ÂZ% }ÌÕð¼Jº^\*`µ7h[¥þúßþ³Ðus úÙSø'ÍΈ7Ìh¾±8@òÂ3óïGî°^p8zûY&,;˜Ø›êƒcðÑ;oâXTÓ  sOïgŒÅ5ŒÕ¾#Åò÷žÔkx§?¨ûVØØ§ëƧKÛ°9 §?oM‡ÒŽ"?{™ElÈ(šìé}]ì VïÙgø.rÀާ*ZЧÏ'ô—7-?¢‚+ù¨ÑÆÏº…,“ÃuMo‰HÌŸŠcqT8IQ‚þ‹i'/[Léñ¥“ذàŽyP½g#Už¦Ñˆ>~&éiö¸W¬0zålýô°2ÀÏúv>âîçŸ- çÂŽÜ®ø±Ùh+T3<½W<µGëi®|_GÃ¥sú€þe6Zêª(¢%=qfœéïz(Ë åuðªÀÒ½OTjðÕƒ¾ÙW€cÂWî[ÛâHß`ïÖRIænX¡°û7£H²TWzø²JÛµQ¡GKæŒþ¾ZéA!VÑ©Ýs››Îé:¶ï›ÇžÏPóþ‡.õÕÅ_j.XÆ„B3Ñ&Ú[Ýù¶;ô E¿^.ôò6L9ËL‚›œ \·¨Èác7€2ÚŒÃ+vû=´¾ºÖsµ{ÐȾÑå2G«l§Jv Ò³tIíLŒ˜pn%}KWýض*<ÎùU¢6uÀ¡»`»êÊ€sÆWe\*Xõ½nI½9²’ŒW’-ìœ`|aöæ)ƒÀ”žAV[ñ›ÿG6G\|] ë¾)ü¸êù‹â«g™Y2Ï,ô þ{ýµúÿâ}D ìá¬[ÂwÛgnòOcèçìÕ—±Tôs©ÃWµjuòç`{­$}çrG|~?ë6@t“_‚<óæÀA“Ú7Æ€­fíäÕ3^DòwQéþA̽fp³]]º£®'Ÿ©ÊXŠ9;Œä_(D[Ïc?¨;³¾såöxz2@q2íô{Q”Êzù[–\Ð7V9ØC²cîD]§s`öUÉÿòäu)جÛf·š†›¤/Õ¯ÿþg¦MAôšCÏ ùWl¿!”MÛÍpÕ€3»tçÛ»«fCâ¡E¢b¶ã¬°>¯ÿa?Ûý—7°õáf³Bj‘èûH|ã»Uëjììùh4B1ýâBí¬r«÷l׺ô!xV€Ì¿¸éÄŽ ‹*Ÿ%Íœ ;LΟýéS<,.—’<ÖO+ã@xÒTÙÓËÆ£°gº‡ßÀÕÚÛã©ù#;Z“eEb€14Ç()˜žuÀçj#¥ä¹‘-À`WÜF ï?mBÿ|zñ  ¸S0èÜ4(RâF#ú¾ãÎ^É*Ü Y}è/Þ¹SЇ=:F"¥-àusk:[ü¶™-Œ~ Ù°Í«õU8Gõ}dÆg¢õÓç~Þʦ;5cÃÒíZ·µ¤‡_\¯róŠWÏdÀdÊþMÃèÎûÚi‘4F¦+ÀÊ–iÇYçƒïŸjtó:Ãý›=xŒy)öÔ)ü„/–ãìígÄJ7OAÄ{Q¦ß²å-å…ƒ.Z',¸¿ä€Ÿ³e æ•3øÛ&Ö£ú±Ê ë é!Á’·að£ HКæ/¸@u°B Lzäß´kØG©ÕŸ,-ëM•Zà1ó3”£[ý½7è~«;WíÔÛ6ÿ±ÂÎàd‘ª™4ôáh±(¥f7°f{EÏËv\."4b¸µ( ÷é 0qû «]êI@{dS«?|òñ"€Ú‘wž+Ê@€ò »kì¯ßRßmGÁùò·ýœ=ƤÃ|þœÂΆ¯Ñ¿{áèÀ:„Ý&Íè'”¼æoϹçC‚k¢À£þò  {K~læêcá¥É’¾Àÿö¿Zÿ£9þØü‡óí‡(¥½=Ö7G¯ ¾ à‹§{ŽÏò9ÉÂó„òçIO‘xä#U &ÊÙe\†ìÑ¢c‰Jw‘Œ l©6/ÌÚ r$_@½0¦Óm²èç]( õ5|Ò(²›>~å:$iÁë/V:à´ÒúÌ*  ÎòKþø0–\¾¬^µÖ)±¢×€«_GOFò_Ôù∟sŒŸLÊ7$ÿToél†ìž‰/†ÔΘ&ê/r 26ƒøJêRÜoÛ‘¢âÖ‹ø7ÑÃWO´Ó¹mTN£H¨U¦MÝÆ-V¥}ƒŽAÐÇõÄÏu?ÿýîÿ³§ð¿µÏœó\¸BÂÐà=§nu¿¼Ã,Xët¼¶U»”zDÑ‹'»ÊÆèû¹s0ú¡›ú°{‹¦LnwÚ4Ô®ð-ô§Nó¨õ}Ë>ʱŽçR…âX—÷Á2ë&puѰ}œ¥øæ4¸pz¸Z¢–òŒv·4ŠË.`|eÜÛ2±7|ZK¾:ô繿 ý²Ç›öˆjjtŸî5À#¼!ÜE1È&F5:½¼y‹ÙÜwð®¢ÿVÑ7ž¾gsN1€þ£n3Vø|25RPÒY]9u-¢më%óa”òRÿipaRñ#…¸ÕmÜ$ã À‰{b‡ÊÄRU ›…„Àò~ûõ0P¸¤zÉ“XÿìKM3\*Z®S þòñܹ¥~%”Võ¨é3áÆ«·YKúÎÙfX †ûg„¼‘ø¦”‡HÅÁ2ÙØáÜ´«§'>°Î×ý{à»qñ+0ùf­†,ÞÓ/ 1F!uAœ}„àÖÂþêšÃfàð4¿ᱸ±°ÒÛóØäkîÿG_³€2œöòÌÂm üÉ×X·Qf±C3iÍ {RÌç{8T}ñÜ)>¯^e€\ŒC£Ô¤!#5 g ‰‹¿†üc²®é. Mc‹N»ÝZ©Íó ~¡4lnn¹°Ú§I½ba²y†…“ÙÅH¦\Gáè¶)¯mg´!þ·­T{s§ô3Œj11hBü­Xd]c‡ÎmrÿK0(›Ÿj{zÇV.§nl¬ÿ¾NǪbX3RùYõ¤µ“¬¿ýíù¿üÆó±.pÿ»\¨6hïЏZÒãûÿÿúo™ ÚºŽ72§XtìLu˜RêÕ:è»2æ1â@Ä^ÂÉÍyš!Y;îî^<÷ ÌjŸÍ²Lk[¹Úº‰ùRg²h~ßë=^3N¯‡îð×L$JÇ?K#¶*g6N9¸dmÐ·ÕØ½DŒ\¼b³1’?¨‘YWùµy Ô\èŽÇµÒb–Ž=d1àø–ÄIù¡"ö¾ö{ ù×ÊÐ;ƒvP{ôP9Bþ—|µE¡©ùåóÃ$¹+6n¹Xúùëæ‰¶GâåËXðP=Pä²hÃ2ãÆó1£õigF†”£Àv[©ú~X÷@5¼Süúï ÆîŸ'anѲ uÁÝ Ã(¨^:ˆ:šë˜ÚÄöz"—·¾RT|Ý…ôlšä'³½§TEÝ¿óÝSq3ꦕÑ<:‹ ”·ƒ,õåwKÆ1vyä•qûf+pÒ~{Y²°Y€eǸ²ƒVѳ8@iíÈ‹<Ÿ ÿ¾ºÖ×ÅÐì±»'¦ãØ•×ï‘ìÓä<>€ïM¹‰W±êÛý€úA(7t‘ A_Be¶‹Šè?œ)ý´Òy×ï>«ÁŸuŠ)oE#¨ãtD.R£Q½Ór¼°Ý‰ÈšÞWjQmüiŽï†eµ¥@)?÷­?`ù§–O» rè w´þIÁQßïÅV‡*"pl³DY%ÐëÉË\7õB3§ö‹ô·ÓPG+Š,&W§8iìúi´·nT×¾ÎwœÖqÁbÞ‰@¦èÇÙåph½•äT»“ö¦¢…Ož‘[<äÓÔ¯2æs[BNoIR³¾?!•!«0ú04äè*ÀâµKwopª M‘è‰0ÐGÌ70çóW§ßGl›1¦¢äIG­ÂQ“;‰Ìòëó–Á²Ñs!ÀÝ‚y|Ážý\ü¥h†É%¿¬™ßQ—º<ŸŠÅÞW†›-¸2Ѧ%íÔi8&öR§A™ú*dØÀñì3²P'™ Œ‹×›·2"ÛÞ–ï8Þ! 0Ì`¢ß¹[:´éà}T'Š?¸&\Äžtd¨Ðè#? ‘ß °†nQ?LÝm=²3AÖóEš&Z„ƒo‰Ê*ïö³ÒIö¿ùL-)üŽ—äDã~¯öÌš˜×¼Nò¥ö·a}ÿÿ ý/-ó-Öã 0ÑXXéí„þW¾PSéúÐ1|NJ ÿ¨¿¿W)‡fd!ùs³?õ3 ¯b]ºàï8þŠ“–øŸŸ!sÍjÎ$>2Wf•ÏØ ŽJìfP‹SˆlÌekaæ”ß’; ¯ËÍIì]¿ÉGbÂ- ñ’§ç¶ÏÍû²òÅŸµ:V·*ÀÇóÔÎõHþ½7mô}q|¹=!ä¿1lsT`ccâ×É]ƒN#ùÿdÓø¥îËö¡¯}ÏÃÄä€VÑu“tßFL‹j,zf3áL—e³Ë!<4ô‚õxûÕ$û¾¬ÿ?Ûÿü-šsûgOájÛ\â—²®lþ>;ìƒÜåÂk3Ý ”ôÜ' ¦k#<µßhçÐÉKŒ™^³÷æè«ç–Æ80½w2Á˺>}\¤WM¿cÊéó?7~Â+ž¢ø¾.ÖïØÛiUñ+ÆMO³mØ ¶C¤.ú<­Ý7 ®áÉ:,aý ¶Äèøs™Ng †ßÿ至DGŸ˜ ˜yŒçTô&“5Wq‰·ÈÎ~¢s.1•ïäh…H}ßIÐߨQ\‡°TÐû¬Ü½nõ ¢0 €V/£©(v^iãuõ<6ù˜ÏÒZp7ýÓç]q 7ê— 80­ÿÃË lšû>jؤ۶»<2î~8¢Ù)ãl‘˜ßFú[£ / (΃÷zM&ñD/ÿ×1mÁao›¿åŒ¹»Û>h—PýlÏžêxê”y¯Áû‰º;ØŠPÏ£|ýÈ™½ß5€Þ5w{ÐÝE¾ðÜ6XbŸù˜ã‡^¿ç¦=¾Ktäœ ¢E½±¥ý:¿ñ²ÆG©EqˆÊ™ÚÍÇŸ½kÝíšWÂ~ä„D’?®)ã²t‹PwQ?aX¦üô(Ú™Sºv‡«Ü¾-ò´JÉÿ¥õBKíDGú75Ú"ù‡O‰w}µ-Á [œÝh‹ü—>«ƒç«Ó’¿»n¼ëuÚê†ð®×­¯ãäʆA»Ê³ˆÇÙ’§ùŸXcæ/[8o 8æÊ\»¡Cú®þÏùÙèïÑúl€•–áSˆÉ_ŽBÙ·^MáÏìÛ<>J™„}õLƒ€7CCÊ»ßg }Ü]¢#ÖÆÌwiNâNg§ WÄ­˜€y¿T4¿éx¡öD íÉÈÁœc” ì òýÜo…"Ã2¨¶Îÿv}*Ë£q[gQ¥¨¯ÄÃWxûî,Gzçw}ád–*¢/wyÑ“Ìï€Ù½«"{Ê)-hh6¯Lk¥«`=÷ô\®÷ë Tѵ‹™€èÇwY $ƒ;]øü%ÿ·ÃBæ¯9sÅîM*ÇÏèÊ÷F•ûìTTuØÔ4}ìH#Û”ƒà÷n¸}°æÂQñ¶zØ[·GÐ9;Z­ßã˃H|©Æ¬šAO§SOWÈA€ïÊêPzó¦S†LÞy§›ÍJÀEXZ­ p"ÛEnû§ÛqKÇڞɛ´ÑÞC€úòd]بܶÇ=Ç‹_S.Z¿±Ã91Ë%j6Z/—ƒ¿*õ”§Ì¬Vˆ\í¯óîÕ‹­Š5£m5—ƒíåçï,í¼ã]VÙxˆzâi CÃÃ~Ï‘wa&«èŽÕ€aùMÖƒúïkÆ×Ä–®¤%˜&¹)ÕßNv€a¾úž†®ÅkËf|Vßd×´.Zs¥ÎÝYÑïKh©Ÿ!ø ?OÙÒh•6 î=8@ay»j«ìD_Cµ.ùTc x—/Š£X „³†Q>ìÞÝ|{Ç"³ŽÝð¨ÎR賎‘ œ.lÚZƒ¯) 8­“[=þ)ò×>Yæ–¦{/d/Ý©zÑ{þËΘi…p1×-M‘-,žh Gb×Óàt€j˜òÌ¡Æ]ë©¢œàVȱqL®Ížb}ý„t”ç«óƒ×AÉÙ~°`·¨üÂq«Ì'!4^wù!V±îtè´H٠Ⱥ&Ú>Ý71gb€´¼\Ðýä>áë³dígýwåÁ-wå`HhFÜ. 48nÂæ¹ÇÞù Š07ͺ£tÌÕaȈ˼6ÝàˆL|NÖx )‹ßüŸ"Ê91vá÷̻հøŽŤªðçJÿ_Äô‡œzܨ~Õˆ ·æI‹#ô³.,¬@òà+ÿlijñ„üÝÃ*kcÉ,ë?PcËŠTز,1ÜuqeI@J烢eª(Jp™]”ÁEòçY¹ÚÙVa_ûÉæ—v®¦÷ìVÁ`g\¼â¨è^$iuU™»7UÙkºê›È¼Ú¯™.¬x‡²ÿóéîxX ]‹Bü×ì¶Œn ´Õ¬38$‰´ž*&‹Gì0غì1¾ÞXÒ—2êªö+«€€uåLð^9¸¥±Ò^õ£w¶¯(”%¿90§]7 1A@4$£É?çÙÇ>ªÿ¦óù[5/fèÏžÂ?h¾£Þ”Ýü¸<¾urs²çr^5/Ä>}ÌÞÈlpè’H-5·7˜—‚Å~È©q!MŠ¢l°ao?¨ÓOß9Ηñø“N¢DÁe8œ¼´Ö,ëÇt—íÓ&ÙÞŠöú ^[¼}1þóãâK´£ŒèeaÁóÁß0¢n#[wós¶ëñ’¼FD(Çýcuæ± ÚIîÉ4Ãa•°UªÈK¼ÌéNÆ÷ðCÁqÃ1ý4¤¶-ôy-ôqãZ´£ŸE,«Þ± ÁF#L~€û7›Ð³«úÄÁ¹=«"4Ñ÷Rg‹ìüpà ©2ÞÁ|ö€§–ïëŠÞºÜ}ßkL´þá5×ü[d£>.ŽXƒ´»ÌHu7ZHăºŽp6°íBXyçRüìv…/=ÂÞ~*gø`å`º}‘_PàÉM|-õλ{LëæµãJÊ‘#X0[}P œ|ØÉDðynÁt_û’ŠàŠ&™%O‡_ˆz–sg­Dd"\ªŸ¼„Ûú¥D?\¨-Ê)FOÑ=á›þóDo¥M%ËåÆéyÖvXn°Âp‰©-­ÊÏE+›\ñKØqVN. „cþ›Á‹+ý œ/«;γ¬—|NÍ< ópðaî…”M¬H¡}·ãÊÝvƒAG/Aé¢2 Œ-Kc(­8ýè‹‚?²õ23Äü"€ÊuŠÙüýeŒÙUˆ³DüYiÓðÖ¶¶Ã[Åâåv>›­æþ6û=÷Ï,=pò«W°˜HŠn¡•³?¶Í| ý£$¿Ön£>‡º¹ø;åCÊðX]+¼-§ ƒlkŸÔÿç?ÛýZ_ü—Þû°çÉñ“Pݹ$ø•¶Ò(Ç(EëírÎ(Š}üa߈ˆýó$Cýæ4€›‘M“»_ÿ÷ÁòÓ?8G*¶ÂËvýÖ뎡îdmds¬ eV}l®Vƒ,÷”¨+ý#Vš3·¤Æ,Žô–CÝ ðýZBÒƒ½§ª€u¸_)£.Šº”£Ëèçœg­A·÷™ü,Ä>ŒËVņ–EM{Rùê‚äV%¶AðRÙ|a܉Kg‰á¡ÇË¡dJê·™§Ÿž„!‡ ÆíÚXUÔüOÄÉÆ úgÖ%øZ°Mlñ¯´¬óU×½– gô},ÛÕ^$e¾õÕñ“”¥…qLPUÌìïíóŸèp8G¿/„…¡ ^’qÊ ôC)‰rà)œoúäÍ^Œ{èVn½v³üȃ1œó5¥ûú ³ŒG¥¥ßsªËïj™2ÍÁºâõž+àíÚ¢[W´Á yya#€÷³·„BV×k‰ý· y÷YÐ&ªlÁko…aJ*õK;Ô¡hÌ¥ÏW³†µ®?Y°Rïjr`mRie¼IcùÚ5_­—ƒ¶•K@õh4Ú§mò>d¢w²_źÄz³…i›ø­2ÜFN× ïÚ"ïÛ´{ ^W”#«v$àTú çìb×!·‚Ãu5€¤7gN‚êƒjõ•Ó”ÖÏÞž£=PéÚ€C#‹K 93j“Æ€u`R£dðÁP]„Ú÷;¢u"¨S¸úîEÓRwb¦T<-°ªI=zÔe‰Ñ 5šowvæ2ÓX{þÏŸ9Åxö€s_³cáóÇŸÏÿÿ¨þ«§¶D¾BžôÎŒ7fe:„LŸ^´Ðò¼…"®KƒFÐ%äO^²Ôk‘ô¥=``$Ñv•¹ÒàuaXöÛN0 Û%©éelÐÆ.{¼o ÉŸAC{á!ð×;¾gþ­/@,mõÍmÖ7™—O–ö^$y›Ó·â‹òʶh„ÛNJ±¼Q§Óß\]—,dÚ8@ä&’_i’l¦HùXc­ØýnL|M¼²Z¼V´¦i>MC“Þ² Ýò”*ÌZ›nÕjÅ,Ya4öÀÄ(LƒÅ8 pÿÒédHÍ^=ùúª&¥Öö‡%6`m5àÜ:)Œ»äû þŸþÙè¿®aÐGúÿa þ• ÃqÀˆi£Áü‰Kš/²À ú0P~À˜¼+ÞbÉKׯB½7 ƺìFϰèŠw ]ccî8D ü« XÏäw Ì%4ïîã…¢^þ1DÞ A\ñ:úÓCxó~Æ€Igò¦‚:°1: Dóç²l: à ÀqŒ Šú0€‰£ŽÏØ8Ý' ËB#1h†hl ­?˜èÃFóÂ=ŒîœÈ¿…8AœX%t´Z&9y £úF?£[€ÆD¿ÓˆÞ ÀX8oOP/ÉŒä?“…cÞ›þöügžÄ£06±GˆK œàœ…ŒF#ªc}ƒÿ”¿þçs‰…ëg«ç‹š,)Vh¡Àd „f‹®ˆ)3ÜÃq_þÐLqô5!“¤¬±q#ª§iàÂÉâú'•˜9"±ëhX ³è‚Ž„ 2ÐòП~´´~4""Œz3Ü9¡8Nc!qb0yûFp ‘@ô‰mEcS|HùÇš`X:¹"ò“Awe£Í#˜ÈB=ˆ½õ4ø¥ôÿWòU¿Hû¥*)“ÎWþôœ°ÔþÀ…Þ–œ´€óO½1Š7—Ë"/wØäsºM…À>ôºÂº)0ãÐøßºÿƒç辑êÌ»â%J*ñ?Úyèv½LµÀ?`al‰G_zC(³×Ý?ºÁ-Äú±Þà ~!¾c8Ų»GÀxŸ`kbðú¯$èH~8› FŽ”Ô\äGpžÍá);°•<Ãàë4òE<ãƒìÙ(‡dFi,ÂlæAXE䤑y`0cqÒ ÷· Ó„ŒæˆèáLÂò¢îþÌ@Ò £{yÆ–4ƒhpž-¦üGë'åYYb:Do¯u÷F‰ÞàM<{Ex†{þgFæœdß+ÑXäÆÞCÞ„ádÒ7øÿ—èÿq ‘%³ûJbÒ1‹'D'}Í9‘ÉóR¤Û'#còBL"6A¿R£ƒ™=} ÈýñÃW/¾@·‘!±Ý1b$ä»%p6ÞíâÞBÞQуœ(•CÒ§“ £ ùG,bñ†%:qù—C<‡‰‰jÀ¤ã¶¿’þÿnÿþö ETøÁ6÷À­î˜ß4šÝ8Žg?½I4C~çïÄ7»tí,~oF·aé6ì½ÌG÷>a@¥† ÆþÜà_a·¨ Ì9Ý=''Úmš~ÀüåôÒ@ÔÏ1žÙ­‹ÞÖmÒzÜE=n­ŸO€7lµG³õe3+âMuehd‡tÓçÃF¬§#úðÓ?‚ ¡¯¤æbÿÂø™°@¼>ž!”i¼Si¨00Ý÷ˆDæƒÎdòzŽ›Aú6œA§„ò†E– #7•hÎñ„% qÌn'Å3øÍg„×gñ¨bÄØ8æÆ!1?º$ˆ¦•àsHØkd†ü½Â¹LÒ]ã7ÿóBxÉ ÜDþ‚Ís!$[1?ݾÁÚ_¢ÿYôg"“žÍ„4"¸K Ož‹G¢ÄsñÈYѨ¡¤«F]é=Âk‘ñZ áÝp ¸FrypŸAÂm ¹Å˜·{D"ë@ÞBcád@ÀÃå¦óH£pŒg \-y)`ñ]\OþŸŒHŸí‹’.žáCëÎÿÃö. Î'|-¹ó½;Òùž0%OØÝé2%˜›Ñ/¢ÿÿnãwû§íרTùîâ,A&üÓ‡ÅÜÑSÕÒ“ d`^Ql¯7ßn˜;g ±Hñ'óÑSićî%(DêyüI0¼aä[„{˜CS0Ñqàí>éSÈ_\¢+>ôˆóOŽýXAÝ{ø‡±º{wÿ@gî#z*ÆzœïÃÕ$?ç£RA‘+¥yD¹vÁÑ1Èž>ó‰¹F²yýÈr2 j ÄDGš oOìµC"‘výÓ á‹D¹‹Î¤f‚‹‘P‚o¥ÉyöºW¢mœ7+˜o´‰Ñ˜½zó‘V€w$‹g9ù•^˜™ÝßžÿGÂYݸ<û祕‰¬/æ²µOðŸõêNd«qÞ±yPDºOAq FÜÚ“Ñ'Öë)¨”›Ed€ˆ!þ³È™´'«ï؈¡Ä18ôäÿ § $”Çø‡I=yâtž˜„s4YÆçK²Ò—Ö‡?—ðà6ÒF+è•Å/TàùÕ¤¡Ž¹Ý/¡ÿÿª£øÝþÏíWˆ(xïx¾×)-Ïb Ì7†¹Eõïy­ÇrИb ª±ø÷ѵR™½{þþ£+?LpnÖ ’¿Ð<ÙaÌžÞ[K÷Žü¸÷CýwOÇn2 p؉%œùG‹ÿ?ºÌ­¿W=¿#Í3šIöî¡ßîÓµÜö`ǽôAyOwZ“`Ú Î‹ùJH‡ýë&Ã} £{ÄÐçŸäâTf Ïh‘>¹™ùÏi\EOý÷¸Pð¼FÄ푘/5œ% ð§ü/&€¦Ý_¢õÿy±ž(žæ×½lÁét‡ûþ›Ž3{ãB>8$ŒŠvà1à/†Ì(òrŽàL'®qÀ{ˆ$. ¡$2ä÷d]‘ð# ‚c"Ï 0(ªÂ'€ÄDðŸhò€È?’è”WŇñ±'Dí³æÇÑúI°$ÀüDÖ’ß…‘ÞÜ 6ÏräyH|7þæ‹tCD)§üçÅ0>Áì¯Õÿì²°#sL‚’@&_PGüüŒ>OþÐúq^Õ?Öã´ Ÿî cýðtqTÐ+hÀȤ~ïü?CPˆ‘(ySé¸8€Ïÿ?¦õÞ—G`òòÿ¼0€æMx[}žç¦ºÆL”þå‹ä_¼óy>¯ÿ}ö¦ù/i}= þoÿ`?Ú Q£ý hïHÞ}_wzw3É üq°®xsè©""è3œãz¤n£MsŽ îí5 ˆÌXïü¯`*Êÿö˜x6уäþIþ—ìB¡„ý±#Ã5<è½ÿ®¦”ò\Èÿ°²?ÁÆxp'8æ—ŠÓãz샗/å?4憔˜Æ~¸O.Œ<Ût‰dÕÒDGÂ,!«€ù1‰3E:‹øóNyÃ{ñ3Úhh~6‘u@²îê?òt#,'FòŸA>özº‹JEüçsf“ÿ¤7é¶åoÏÿ=)ÝUÿÀ+ÎâXÛôþÓÿjý?ˆ÷Bñ¼§ÿÿ((ÝÉÂ!þ£eÐùgR˜ Ý„øÏ¾wÞã| ¶ |p#JCxbð õùÏý ò‚Iœ ùOTÑq~^‚É;žÀI2ËÏìU@Öè“ç‚z:â¿ w@Çyn#–Å c†ëÖ>®ÿݹœßí¯i}< ‘¶`ŠŒùùçUÝ™@ïÀÀ^ëééMõ£‘Ö2áB`G=ÊñÞæü‡a{›ý^#Ò|"{L5ÆÏí¸Es¡Ç4“{ÿþ¡F¹÷½;vçI‰Y…E÷Îÿ ÜôBq‚ó:¾`øþè/À“Ôã þTéƒþУÀá°S¼Žž[rCùO‘&­×“¾žÄÄxw—ûW Ym¼§„‰ù¤4Ò}gâAt ‡<ˆê)(âÅ äÛ{Hƒ@VóN‰ï¸K°‰CSþƒ}d΃dd“÷¶ânAUâ¯×1ø¯`a4_j›x™ ÎQùaºz¾{þg‡“žˆÌV3ÈwÑ9Ä‹búÿÿú_ÔíÎIO\õ¼QŠ|wWzÏä¿Ñ‡ŠøOæöɇIȇü1Ìß=šK>ÝG¾"ˆ<ݼGynºs<“…Ìžü?//€ýÿ'ñcX‡Fy’½¸ @Ý™ÄDé<úd6@P€Ñýƒø¯þ!¶˜ÐÄ2•u?4Èçdº‡8ÔÐóíÓúÿ»ýå­OGÔ?ü lY @Z€9Ű»C`9T¯`âáïÞªÛ†Òµ÷ìê±ð½³¾ÿ’W~Ä[g~Änþ^‘A?Þ÷#Ü£úEüÑÎ Hýƒü/1ˆ¯eWw4þ7ØŸÝ‘÷Ŝ☽=ÃéA~½_×]Fçsº·µR6îO੪à N“XÈ„óB~²bœ¬³#ö04 ßF¦8™¼‚_, ‚¬p&&‚|¯pVϳÃÄ 6ÎëMœ.ƒ1X4§Df7ŠÂùù3ºÉ^¹ ƒž> Çhþ»]ø‘ï1@â?Î%ÿy-ÿåo]ã7ÿ 9ί`òkÄ™”ÿ×ÞµöÆMDÑ(A-jQ?!Q„¨P“6ÉnÖû°=/{7ûÈ&é6iABB J¥‚R~s_3ãm"*UZ¬6þ°J·ã±½×sgι÷žÙnƒý71þü–HŽÅãÄ ûÌ·L”¼Îì›#dÔMÀîÞþËYÚÚOš–t„ˆ ho%z@2°Š (½@®ôW` üq ðái‰+Ëëóö¯¸[’xÌÜÒý@Ó¸ê€2ü³B@{Çÿ›Î×Ç[-^ŒdùÇùZtÕ$@ ÞëÃ3ÆÑ+”ƒÃ³±KÚ6ÝIvû·…}ÍÅ4YßÚa’YgY¥>܉Áɸ‰K"ÿKOÐsSÁ{k~ÿ2þ×èlx–çÇ à³žEu&Î|bÙ=MÃÀƒÑ2\A:Žü/˜Ý†0 ËÃp¨¶Í+ª÷¡U|%n¤€1|p\Ñ0†*rE³*ÔO$=Øÿ<¹ „’ ˆëiÀq‰3ÞPCÁQ€<©©©8ï|AO-DÌæy²È¯dñ¡/„w„}£ ˆ’ЍÈx\ÔóöO굨580h˜Ý¼¶ÿ«Šƒ¶àÔ1Ò«>jƒý62þŸ-(•9z³þ¢Ð öÎá©ìœÔ¬„Ú½ºxû3ÜgÛ5¸¯{v昗²‘ÿ‡†%'ó ÿOtÙŸK< È®z!k9*C”1  {ŠÝj* !ˆÄ©ÿHTP\]TŸ²›íÿË7(®·9Z»Ø™àcäΤÅ? éok‡jf°Í}5¯69ÿüú‹õkPbMê%(ì[ï $¬Ü“ꪓŠ[3.ÑvíöÔÎyÕ¼1Û¸ÑÈÿÒ|1xäLw:Ök­S°§øÝ°XHs¿ŠïÚØ:å#Ìõ7v×üð4…ðqïË?'6‘„Õ&•‰+ýÃ0À2øõO(ñ‡ÉZ.À5Y«ûç•ü7æö[̲Ö&@ FÁ˜ƒ£©ˆùh„ÿθø„ÃIzû7©Êå}5›`¼ÔpyѺNÄßî}þÞÛÿç§T¦¾¿ºÛû?ØÐøY'á|ú‹§oxe(õÞ).à‡¸»·¿#ìn°uGŸ°2?eñE²@à¾.wÏqÑ /&—ÿÇ“ܰ”øuGd…i™Ái;á¸o?0–zè ¼^PÎÛ?”ë1%PÄè¨ú0Åîgmÿ-–Þ¹£­¿ôÐ`ºU2^ñ¸J”Fwg†RmÒ\@û=xnINˆ”Ù6Ùæ—Ò_Èèòp™|°Œ¤<¨çu³[I)O&µ‡9Ê—ð¿iCN Ëú˜5¶ó¸j¶ŽX§9 Ä0ðá,¨Î{«¸L#hle¥Ýlóû¢‰ {Ÿþº²I؄Šh‡‚CH7n>Àè§5;ðÄ^Ú1‡ˆR}OÈS)‡ J ÒìÊŠv ±,ëÂXH·¢"ÿ Ñ"~WˆZÞ…¤ýÉÙ„²¶ˆ£UÞ·¿Jãµ·4µ ðȇ×ö¶D\è(G¼Ò½OZ`ÿrcãÿóÊÊ6ÿ‘ìG;Drbü£ÁRÖ þaêé× <íÓ>€ÏEd {m`ÂæCúRþ_gýåÖf«ÊE5b¾ ãrš”ƒHçÃdßóï?1ªØ_Õ±µAk•(•‰E|é{ÿk~ÐÒñ°©£+€¡÷^˜µñj’MZRF/H‚î\¸ˆÊa7Ò—Áø+¿ñÓy£¯¤áU0«'rSùÞ|î.oݘ Gû?ù_Â%ýl…=æûÖq`¯¾Ž½§ñÏOß•»«DNNHNH˜ß0æEæˆ7¾û^ˆp˜bg±@­õ%A1/½ÌÀM¤b¨F%rÃÕeŽhͲȆ…@ÕýoHÿC)r05ƒÃ]B,±þìâáVI£…$Sœ ¼@HÏPªôÏO›aà°s6q´§ ¸"mNS 3ùÖµý_Ölg lo±Õû›ÿ¿œ[’õçÅYÑ‹¬SJ aŸ¼ýýããK˜ï{û‡òÿÆVA‡B‘<ÿü%«±PPXCÐô øýG(Õ7ÚbƒJ NÀ6j9 h‰AJŽ@§ï\P€.ïŸ%¬c„úoª“øa¾ÕÊñß¾éßÝ£+Ðÿ7ÔiV_! ?²ã ÕVfzQI,6`8‘| _vïÀΰúµ†ÑyJBž‰pƒ »¬ìþÖèV¯ó¿ÔQg:nt|5ÿ›=æx->¿<›rit3LÁ5’O/²%Îjÿ¸ŽAÓ¤Ò·1à•»wÌø¹±úXÿ]iªú5RD9ºuA…»zïE¼Cy°:XY^À‹œ&übª=ÝzgZ;Šî Ë9ꅑ˪¼Ã”  v‡ú+ì7}5·©˜?Ôk…-\…ž%I`Æü&ÏÝ÷=joǭㆯàžnU´c°îÞzïí?{îò°`±]þÿößèøÿc&R}qóšð#£Ï,å ¨‡PV/!ØŸö’Mþ8ºÀ9Ïܺ3­¨¢…IùÀ4è,…ûøR¾€·?åèýû"(ÉËÁƒµ4(0ôÓçÙ¯_îWRb˜*RŠˆãÍŸð—ïÞjáøÿ¤¾.àÆPxœì}PK÷/bL¨¨(Š’$HP’’s†sfv—œ“ A*‚‚‚E sÀŒ‚¢˜àõÌîîýª^½ý߇UÚuïÞa§§OwŸø;}f¯ümÿµ†¹nïë)ü³}íH³ U•#·r÷òVpÅf ø‚5æ~ÅVó.¢Zé£X"Sy±ôƒæ–Vwwªæb>šÚßYqaíG8šÝB>¯’ V˜ø‹ÛŒÆIA¼Ë!»õ“§=J< Â!Èf RpàU×­µ¥¼ã³Z pñN«4¯anD‹û5áuÌÛëgdwOžAÒw8dU) úôÜg=ïóÁ6Ò—íF a+ö¾]]³Rû;`-'ÕXS¢¹~¢ç}ÇÛ¯}îËX.|ÓÑŒæÀ‘1_ GônßÞ4Ãóª¢mw¶Šµhßr0ì¦[ív&°÷Ôh.Ôʺ—úî¡ähÄ#…ª]0)—]¨|@õ¾d2}.|OdK¥…²xë;»b`.öÜéè0÷[Y’birŽo<%7­?Èûíl.ø÷ßÝ óÌM¤qzÚmâî°S¢Û>[Þ4÷V‚=_JÓOu[sû.FË4Ç—Óü†·EÀb³Òðòk¶?è…ÌË?îYNK_C`ÂU%èt:Òžáù&0l´Dt´šyH_ÜZ¼åô¸gï´·V,ÇvˆÌ’*Ëy7³ŽOû”8Û“wCÊ=ò´oÖÔKp÷ÑMxÒ¸ª£ÿ«€— nG·†05> ªsŠoªÊÒ½Á%Ú¢à|‰£6图þ[ÌŸÕu0<°…@·ÍÄ-GmªÖ>1¡‹ÊLŠ¸Ç™fnÌF¿6|íƒq#¹ £1!qa8‡ ó uõŒ‘kfœO©’=ôDÊŒþxþ»ÉsÝ:8Ì¥E἟ [úžÿÿeý?.¡S¹ƒV'W )lLõút½}wÔeuŒÑOH åÏòu~bèé¿ 'wõ)8åjY¹¼~fÀûZúƒ'&À.¿e<Ž”¿e[Sm^â`ìxÁEó•ïi¿þ÷µÿùÃÝ?¡¯§Ð»Y¦'‡ÌÕ£[Ÿâ~þhËPJ d©0ÎÝ(ÎÃV\S/'EÌrúÈ2LÉíw;%"˜~wÛ Õª¦Z"9xµ³âã´ÛGáñ2ÃôœÖ~[ÇÖZd<ú`j)XÁåhÐ…ØtqÐ>¨òZ‰VÑ²Û KUäØ2ƒ_"‹µâ•.Ï™uˆ¤OneÚ”#úé¾ÿ4^xËçb^ÿÓ¯žzÔŠU±üîŽÚa³Äîa6¢?û(*ïi+Ð7ù„q»+Âê÷FOÌ¢sö¶ÈÜ¥)®jç½NèZ½‹ Rfkîâb'û)˜Ž†mÃÏ!—–§(0,äM[Ʋ\µCQ`¿ºÞ¯8»ixÞÖ¡0ïg¹$7Ê<2Ç•ƒñyûÚQ©v Z[Bz`µ‡›w@‘Í­^æ*í¸»¦ÏÐðôžÜ•×Ñœû%`Í öë±¾€§ÅG¯•·¤åªâ“öÄØÅ3¯æ8]ûu&0û­ç༄U#¨Ù¹þ„µ[ÊAObê²Û›'r‘îá8.¶á]žf‘ÕG¤> ÊJ]*±õjÙèF™/౨.Âý¸€Ù¶ÅO\”ó}ì•÷µ[7ã¥Xí÷\ð¯¾Óä“v=ad‘ŽU§)ØœsÞyÚè°•ÿ­tt£yõÈsª>ž…_؇Æ('0[¬mLYÜW ƒTVÔXœ=(ù8°¨QÁýósƺ„f½l¿g4é(x 6ïËÈöLoÄ™cŒ¹%€m >ÄVx?ýäv°ZÞæ‡ÿòßÉ;xk•áõX÷ȸ¾ç¿ìYÿ'e–€ÁÖ*ì’šTÙ1´x­VÂüš³Ú±Ôe&×JIù#Fëc¢H(•3ïGgϲ]zÛ'lðÍ’WסÀñÃþAµ:‹×ÍëÛHþŽ]–Û«ŽÂ¹š R ~àér€¬*ïA"æ«`繉Hþ'd×ÌŠÌyî»g!· ò%] É¿æ§=ëêçš_ËV*ß<ÇÅ$‡}¿:Woîdp‡=•a0úüšûÑHþ5Õ š+@Ö|0°¬­¡À>\"؃ò†`¥þö [êwÓÿU}í€þ´æö[Å\Y —RhÅñn–vœm²8oÿTâÙ°Û•p­}|ìIÌ÷3ÀÞ£ªþ¹c6‰à°Ñé*´E]bœ{±ÓD sÎÚ ~Þ³aÍN€¡jöÅÅÏ&<_Ö&am…4,Tj5Æ_¶I€ïe'Ž•ö»ð=Þ”OMPZ9y0@©ÛÅI/Ê.¥˜|.’1Ñ÷Ì=¡m½Ñßl¡þä„råç·»ïúk-« ù9â¢%â¯A€åÜ´˜Ý;Ú&0Ãl„jÅž#.g=`_™°øFù¡®åœ`¹òÚ¢JšäpôÖ¶!…¤c¶¡ë–_ƒ§Må«B•ú-?}XI°oû¬Ûd¯î¥G=™å—h‘ˆÁ¹ØC’ f\,{ñÛÑ…ê!EˆyŸ‰”²-<{¿Óe§IÉþz¥R^Œí‹o— @|SÈX`?SÛûb±CMʼnð#„øÖœg84öÛ‡Pä¹…{ €ñ7ßF¬Ñ³åîúì\T½êûJS¹©mØÕ]KiR²N£Þ ஈp¾Î«® {oæº6‰ÁG6ˆU”(eÝÍü2¸.|ÿ¼=O´ŸÚôݲüͳ/…Ù¯«KA"J[>¬Z´£%™³ ?…Û³“½m÷ª¸>C¯2 Xò¥ýVo”,6Í^õvºÜòë<€ˆ~µOïyÍÕh¯(Þ$3í™Êûâ°³ªcþ«Çávj˜ádyÎGä!?wÖjíñ™Ê;|¾k‰··U¢`WcóM‹ÊcøJ8á#¥vþåÿôÆrm‡XÎ1ï{þÿ÷õÿVg.”åÞ;:Õ9{‹Çó?­2X¬ –:'äÏnSÕƒŸÛ—"ùÓ(-yWéŒÄ»¤ª«¼ì28ž9ÿÝséf$ÚŠ'w{g•oáÀsÛ…ØÀÞ?·¢-pæÓ×ÙEפC-ccƒâ‘üV¸¤Mƒr>‹–kÌcýiqfç:á±ÌšøÃª.…âiî«M€eÈû´ ÖI\ßœ„ößVG}’ßh4¾¾‘›RQ¢ó’ÔQTR昣½¸¹Ø³<Ü®,µìýdè2×诲:Î(X¼Ùo„ÙÒW`÷þûÏ Øöl!œ‹ƒ~/ýïkÿó6×$¢¯§ÐÝœ1…¼|3M•(æ }ðr ×,殉É^°½h˜Žó`Ïa÷‡íltÂf­‘´xÔ;ºýsCþ®?°û×/®è'÷ú¦Öv”ϯ!¯>1}¸Ün,?hóŠˆ^cº#ççC„ì¦R%ÊÞ8kì s±™2>|I—|ÇåU`æu¼ðÒqHúðpUÄú0’þrÛÔûpxR"æ–éS÷ð@,®æ¤>(-ºýlÎÏ›’‡*¤¶L8‹´’]8'âüüDX+vö^ß’Zï »´ #D?œ÷ãá!“¥W§Lðwg¯­c§­ù)Ðyñ*`²¦3œq‡­׈˜~hý¥eÇašÏÓìGM…Öà-úðP8`Y\ lL9#ËÇ­¿ß©ÁLÿ;ê¹ZìþYÓúß›úm­ß÷cϰH¸?°Ò+͑آõÃ#Ù S+} šVÕWž‚æý { €ýÛÛ;ÒA¼´ò™tˆüƒWÖ,ï…ié¸oÙHy˜Ñï°™±ÑåkYõ϶»–bý=œ1¯- ð¼ù`Ìšº ?}¸ìÀàÄŃCV”² +Ç?|lÝTûÁì17@ÿ›.¨Ô(^·yi`ï£ò¬ßâ`CpŠ %èÕb6ll?¿rÜkL>ñ@Xy±¨aý¤ˆ}à{mÍ’Z£…' A‡8˜LW¦)&mÙÀ:7…Ž™q[³ IoMó­ÉYÀ½´®´­ß15Ý¡Ì #\lÍqÜÇ~øæ,˜E}Wõ‚ GÇ Óäû~[uŠ}(Àýõ'×L}dóÇózVtºáièØ:¥Ïù»ô_ïD˜y¹s(v~T.˜l3wacŸ€ý´Ö5—Hù{³„ƒÑ¤ü =æt5êsGxl§×Þº˜£ÞÐQyMzaó–뺧¡`ÀåËXôBs„™üº#,‡}06åÇ&¢¶9Åÿĸ©yHþDËM“íCU Û¯"àï*ê%ÅÚ3`pÀñ¡¡ºo6öÑê;G¥‘üÏÝ”[ 3>XÞƒäßþ±×²`Ãum¬‘—yY*’ÿ¬S\ÖmH¾ÍM^ÔüLü)Ý©™uùqŒ±ä °}ôOÀ´ŸDª'^8z(³L)üúš¤“žHþ§M^Úo +ýïkô6¶{J_O¡«9áàV«ª³q¾ùCåégTÚÆ:MºˆBé,Ç-ªL°6i½Âýß0mßåNàD#ïÁøäXtzËéQ®nòš'íÔÚ¶Õã`7dÔ&Û_›9¨£Äþl œû™˜Ùš+´6zCp¡Ó­ qæÀùs7qgó`ø&l,±º8é ‚V¢w’§ž'éß˜ÛÆÛ°c?LÉ|6ð:xµ(aŸ#>'$éûüš1`oxï>穸ÙDŽÇ´Ìë–m7X7‡Ý®?–…°‚#·(ß2¿Žè‹æ ô½˜¨æNø½ÄU"eSî-]žÃ&öÀ}ú¸YO?ÛìÁ{°kS‹¢ÿ R'!úî²²88>Ù2© ­Å£•§u“Àðä´F˜å9s‹=Ñd¼à¶‰Fæž)÷ìêp³¶¨™8˜N©C8øÂ’½P3+*ÑlvýPñ»a‹~¯w‚/ ‡ªR÷c‹¼’&`nIL0MŸ Nà(ÓšôGšÇ"본€&¯¹°jãrŸýõ,v)ßS†µ7ÑFtÚ(=8`;j˜Sü<È8ë0º"á‹—½ÝU=ëB¹Ì†ÿûR©ðìf9é«2¼VóÄ੸æì18lIŒ%èò#Å~É6#|§ºÑnçØºÖ}hwÚòžõ‹Ãâ_qgÏ2ÛDÏE (|&ƒ…*Š»ÊÀÂÜuùSÜÆ~5l\ÿÛ«qÐû°z^äÑ•÷QG‘¦]o½í¦"¿{Ìv¤ÞÄWÓÀ'ßòç¿È‰‹ÛŽÉ;~ésþÿêý¿ýRÖÛ~8hN“Y°û‚þa‚Ä;•£;T7,Ë0p¼ßLÊŸ~“Þº9CaRj­deä–K.DÀ󨯙+¹AOìgÉ䆱d{*=…-1µÓSA¿õC=ÉK‡¤US Ê#üi-°>.ŠäÏy’ãåèK þqñƒé\冘ÈàÛh˜òý‡‡d‘ü/×öÛ€¢„fî·Dâè/±»}ëÑugp0>²Æð’ÿQ×|ƒ¸gÁMÚn(XÍÚ@xÎþ2´iÔ0»GwânãK®'9ã°°õ×}€Ÿò¡ø²I¿,ÿc²Ÿ” £/9&d[þ>ú/Ý×èlAôؾž‚ •"5‡ÉŒ[F?hž[†Øïúêx@¤Úó{xÝŽšÏ Kÿûl¥ÉIÌ”»¡ós9|>êPIPð½‰16&^p<9»ð`ò¦ì¢ÊC©H}ÞçÉ~+Z¥1€ãùZ¤xa4°[ƒ|åìÕ¯ìÖ=Œ²›yòd º]ß*SuQцƒ}œçcåð¬µxid6’ôÙ/kêÜ9@»åÜæ§˜W6ˆç¼±ÒP `à[7„ß›‡U—ëLlZa˜ß‚‡F÷€¾Çts@^ë» 0È>ñ½iê D|//Іu–™€M¬¡…­IŠ? é‰ ïži”÷Sx"Çj¨‹üu4d %OntMÓàDöó¥«÷a˜’ã{&AÛdTRbm ^ù·‡ õ¿×4)`¤š˜‘ûpbÌ9‰ý7 úØ«È)¿sOÞ“ªZwoÝ» Æô §GG5÷ò.M竀ݢ;¨›¯5xõC€ª‰;ÎêÓ=+"V|ª~ºu÷ÀóC°RZ<.Î(àé¢}˜¦ÜûSPy!û ,©ÌÚˆ½™¦ Ù®1…ÃÏ8¾qÓo05È~qù~ŠñÇ7çÞÏÉž99y&ðÞŽHnþºªƒØp|Ô:¬X*‹vˆÑmå‚YùÒÃö-gó_ÉlZ×î§?6ÀµÑM+ÐÒóÎðÊg_@XÉòÐ/ãŽÑi ¬¯õ§›°|oÍ ÿÈ+ë\)o ¬> 0³Ù K—:¹è9ÁH1Þeù3?áʶ|ÅÔóÀVP¤rü*bÏ„{›3ÆlTBPIþõ‹ q>)À,U=˜*©w¶S¬þËÿ ÷ZDŽúö9ÿé}£ÿNû'ïž<2 À"²jÌ‘¦¼6ÃeN÷Ó¢ââÀþT6…”?Vàžër\8çî¬Q]‚ï 81nWÔù—¢n´É÷%_Å¥§b¦6ù;€=35:§eüSäΆ̌®{Íc³and`ÀCV Wµ™ÇEò7ãló`Kž ˜I´l¬‡Ž~×÷>:³¥iæ4…ôDßø¨~’ÆÑÙ‹ö±ŠE£ S×]¦Á9ç¯áÛÔ¬×ll†#×<³flò=šAv¿g)ûŒwŸtbù}`¹Ì ˜õøÜá!Ç “ïOe³ƒä"• PkÒL.ЋrÇóÂTÅ6¶¤íºEË«ý_ÜÇþçOmžQ!}=ª9÷gÀV?½8°Qjž6À”±ØÛy/ÚúF•¥"½K*"4A?×þ\³úõàý£¸w]f-¸ý˜ÁmÓ¬Š'î(‚WºoÀóÄÔª#<ìaÃeŸWG^%ãP”5œžL]u‹£Î:tŽì Õ(çëëÁuヶ‡àü°<úh僬UËÁE‘í!°ðH‚õ¬”-b$}Å Àþ6@eåH%·g8X{ÔŽºë·”-ý¥é{h{^;}&Òg€WÜâ ‡ô6m³i3À\ÑÜÝwF·¯>ji€0Ïëôm°~ý‹ô>¨f°è+ UÃ÷H¦][8vZ?}E%¾ó=ýµ=k#n\wzŒ‚1ÚMÆ¡Q7À÷1ƘŽè¿Œe¥Í.^°æ­$z¨4}€­Ì•ó^ ˆRÕŒ0¸MUZÆëØÉüæGº¿$ú²óf¾S«–¨xk<Þ?dŸ¥G†—p€Û¶èÌIsË|7k»Ã9_5/„‰Þæ²°b¿n,~èŠCAýï´%oâ• ?.U+á*¼½]ŠÃʽi ¨6ýðú­ØûXº{Àx'9h•)ŠÀ^;³hæä¼5Rãu¦hçùw¬-`1^½³¹Ëà‚§üŽðáÂIgG— ÍSâDçŸé¿û¶\`ÎnðÏoaðA’€í6[áÿ(·Õ3¯œCÊŸÏ I­Qýq`ŸŸª¡5q2ï)ïäëÛ±.Ö…ÐP½xD$LÜ{q²ŒÉ~#4Û9…N×ÃDïg°HHjx—½(6Ï=kÃÞ7†S¹Hþf¬6NŸ`¶m6&K¿£(YÉMPµmK(¢Ÿ´Õg5’ÿvÃþù0ùEܳò" 0ç!ÃÔ/:¤ÁZ‡Zâ7$ÿÞyù3¾îv²oâÞë!çëÚgY¸¼‡à;ç¿"ù÷YœŽè%iÌ=“:¹g´l™¸àõóSzƒ.}ð¼«ñÛèÿßÖ7Í%ïë) fŒwƒ}n:.,Á1Ù²4°ÍIJ»~ÆÛ`@žLBg™2‚‹´Ý+gððx`ýøœ»zãºÂǸ¦ã-¸= zcEÛ®¶°XIrùÚp½+—;F»3Ø?­{¨©qæ,ø¦s‹æ»íLÙЊœ ×xÜ‹Ó^¨µ;ŽÖ€wÁÕâ›kÓ°@ëæˆ±^5$ý¶¹yO6JÌ ™kî_2‘fºÝ7cÙ‘²;b±Ž&ñµû¹ÜØñÙ©¤êÍݰAîõi‚Om|.aߢÌ›¶%Ò»~NY§¿`Ö¬“Ìóämo-d€­»‚ €«Û¥še"ÃU‚¥§%#ú¾zC/Œ©Is¿â;?NãË9á.z„Ô ÀR:_D°O¤X‰hý gjˆWqÌù©ËÛѰcò.|Í<Û¤¥% gnM7bx;¥EsçÏfœ=0tí2˜•æ±|ýñ„Ëó"úFçÞ‡ñ—ÏÁOÙÂyÓ+cƒçŽ]ŒÈVqÀNX~’ 5Af€K¤6W|e~ô/²°6âÃÂPúòL 6'Á!¦: só[0rÛ_X2-\f¹îûÀDÂ11­èÑmÚEgkØt"O<Çï|,YüEÕð,轸#·L7í½}Ý/Åxh>«êubýæ{vñ˜N½Ë›3PÖù'ÀÁ ɯž/54ðãbŽýö½nè~˜ß=!Ò¹s<ˆ±Ÿ½±²-lè ÑŠQŸYÈJäA`Ú¸F…åFÓÓ€ÕòR¡´R4î À%ÕÍØHõCêw+.y7dôÏ1ÙÓ3úšÿ–}§ÿ÷¦sý -†Æ«îÆ‹ÏùNÒÜRä “ç×GL3"å/zA{ÚÅSšñ¢pý™Üµ1pHÂè}ôQ`wV_p/Ññ¯âÖŸ¸ÃfOb-æ‚o`M³FoÞ[€ðMHLº~vàÓ8›t§F·#UeOQ1ÀÂî+D/ŒAá«D¥Wg–iYá™!³ýlØï®•—ƒŠ²Èöf]|{L^y6€Ñ»›yéû®*Äh?”Óü¡¬BÚ–¬Î8úãç?-´¯ùß§úã ùKl×½”¦µÌÒH;UæÛ4 `ÿú—’»Hù[uðç´)6ÄOZ‡jãÂQe¹ÿó¶Íî ÝnJHÜ:ä~Næ“>€û“²µfÍ/‚®Ö„=ÙÞïJ—l:ëdg’?Û ‹ÿUêgD-¶ƒñ®£æT¼ÒZg”5.Ñùø ÉÿðOžs¶@NÚN]×_¹Éÿâ¡‘±Ó€yÔHù¿ôü”½Â—å Ûo*÷.]`>Wtž‡éÏíun\/ûÈX´lp4¾†èudÞF,¼´¿ß.€k±£“•UZ=Š_-¶‰\²úÇo ÿ}é{þøÀŽîë)ƒîüo^Ñz ªO"·rv_n<ãV4Rd7‹IÆ[X,HŠd?šä?”ø±ç‘¾ þ¬ÔêuŸ‘uW’V¨s)$ Îq’ãã*&J‰ $ór¾KžK›ˆtq_eþ« aàÑ -ÛÄà Ð>TŒK)b­½Å9«W ; àfºñFÇÁ*dÈ*ÚÍŸÊEôï¸EäŒö÷fh\aѽ]“•Xwñ烸ñ'cæ \úr„Óª¢Ñc€~5Y{[ôã‘ ì]¯²ï@°ýÏS2×t´ý è,ÍÎ÷}¡°zþò,¹ 5NXð˜Ù&©¬;òFÙs€uJ7E úrò>ã/èÙ¾ô†ub"~^5'O»ÅÆ$©ÑÞj“ëÿb°8 ”õ7§÷÷{y]oåËucÂ|·û>œ ÑarÕ!˜cÓ·4÷Ÿ?7Ьñó~_úísŽ·ÎíVÚˆpf›ëýZu´ÜÕ‰{ÎŽ=Uš×ªÚŒé¥4ОŽYð`ܳ°Azvšq?ãTv&ú]‘!2p…œÌ;Ï4Vë#íMÅvÇ®$2:RÝO™•­ñ9÷¹::àbàFƒ5¡ ®ßP±j=âÆÄ–?GÐÍesM*è0~ö‚H#£aê1Ò¯®O<ŒøŸ5ÚöØædUgŸ^ 2Ñ£M‘²|Kæ5iÌ£íÖíîçî8tdBÝ;˜:d¦¸OgôÐ}o6üšÖÑý1p†;¿¡ãé¢t€‘a·÷Œþà°tâïP™ù ¢Àù˜+Î<Ó^ þÅꉯŽ?—}ÃZSò—ÿ}Íÿ¾Õÿ(Ñh_e?HòZ• Ký…cTg½_Zµ9 É_õîÈ?v‚™Óe¹ÕW“ädÀUæç{IÂ+ÇŽýL&ÓÀõ”úŽáÇDtb €uªfãæ¸tÖ¯Ðw4®qiœÌŠ8sz$Žäoü²üÉ‘à·÷fðLÚõ)ꫤ‹®‹x½IH@ôïÏ ÉÿÔÏÇ€îÐ!3vå<ÑŒºÍ]$ÿ# u÷®’›Ê©|ä¿F<”ƒ]O Ô™ÿaºNŒ}ÁÌÁ*ÀXœx* FÎ`Í;hlúáIêÄ9[/Ø-¸0ê~¶õ_‚ØiXÚõÉ–Ö”ô=ÿûØýüéÍ=ŽÛ·à øòÅÆ˜ˆ¸Ó¥þÍ}fwxJöx¡-^ Cg&Ép]$fFs<üð]Û¾ÎðHöƒ–ºÉÙ-“¢iÙµ?:œ9ÛÎ_e›ä8ë0Lt­{ \h”(õ¾tØqn[éœ?Q1âSpðW‡%×í+Þ„#¯`eÒâØ¬îDÖšs¦©îGNÃ`DÝ\öüô »­S¾ “¶¨þžm(1sE¿q6oΆG2û»eÌh€ÆEs޵×þxiÒZ¸KÑ—“pñŽW:ÓûŽhð O}þ W&*U¿ÒÔ!<»ø‚±ÔÝp° <ÀrÏÜúIQY9À´ÔÎ?èÛZ—½õ™ÿ1Pg^´8@Cú<ÅÔù‘e¢ÞÇ–Íè4v0gHˆ8ñÐú ¾í´¾¬$ãT€§7|ßÊçïs¼µË4ÎpE»)ü<Õ”^vÊXnûÌØáŸ”´ÙvsXg˜„C`ãdŸä–ªâv£^¥…z¹Üƒox?Œ]ÅŒÚpÃEôGáigýÖjoÕ1s›5Ó†u´Lq%ù'’–ÊðˆÿÒFS‚á`Ãå"¨öC¸äå³Ó<*½2r£%’jÃvÆT:xÁuÖ¥ ¦Ãoe@Ó6O=³â¼Ê=Ñ+lÎg‚Ä,}$ßÒ’uk3‘9?x\qa½øö„‹ÈÄKUAþŒìhMÓf'û¡?Ò,9àâÃ'¿>M鱯?,õ–(^ç Ÿ‚˜žy}GÈK+s´ÕPI»4{C¸òoJ.oÂuì5´†¯9‰P̼£|•tI:Ø3÷þåßòUëÿÔ;I^–~Eß>‰ßÈ*:®ˆ\â*-ç çND±à} »ísš–·=n• ãÎiðu<)àÑ:ó]LÊXcX,?œýh Ž=øaЀÃüîYsÓ_Ûä÷}ÐÇ•tÅ¿Î}‰ä¯mõݧ7Üô`¹ˆ›9À ­æ†ÑåÒiËà¢/›»É¿·gëZäâ¤ÍÎm­>»?=q5’ÿ}âÛ/ŒóýV8’ÿY)ûûOúŒVO€°¯ØßM Š™¡i2äá§H[æ˜ྖÂ@iÕ0»ô‡[5õ®³×e@ý¡Åzà¹÷¼ °{‰­ãö5ÿ7ô­ûùã[_ÿ$°Ñøa°³öÛÆóAm#BÖ´;:ÒÎvJ4˜ls¬›“š³Ÿ€ÇyqôϧeÄ =¾¥ÑüÚ7…/%¬»û5øð< Va¥¬kH™œ~ƒ½zIxU6Ø}̓!–m÷2§‡€Ýæ…Iß ½vð‘úP¾’Óùøïõª-Çô ¯w#¹P’±ÿkíå„× ¢Ȉê÷@sRx\âº,ò•s+Rûo·fü¨KÂÁC×o>«fjÔÆuçìÊgiêaŸ}íÖ9oUÐåAàÇ}³“&Âr‹ÑH“kÝKR‹[JÚ?Þ”=Ú*÷ÝqãÑ¡ˆþ¼mÎb@{9޽¡âÚœ¸µ‹ø\hýг¤ `ÖôIQ4¿o;¬†D½• _}áæÔ¨`¥FݬHpð°½éüBÁ~·fziP‹×îA8¸úïAô·O½ ŒÆÌGùDc¿ã¾hýkû™Å­÷}5àÈៀjMoÀŠB@QžþÙû—k›Æ²(»j;\~wœ7 ÿãµ`[|{x¼»Ø^sËÓÀ N†‰í=LÎ:;—X2^oÅúÎã+.Ø|ž8ý£c¶Þ~ˆ]5t*ü›î_8b•«¤Å-áË££ÀhÇÜ’»@^<:4¯ß{ßXþ9>wã‡EšocÿÆW_^rÁù¦>¦zDŽybûN‰ .·Zi«¯t®‰ú^±ŽÖ#H…A¬7|«\¶B1ª;3'˜î=t‡ÁéeÕÎ]›úeg¶s-ê Ái ~¦6$Í‘ /^úËÿ¾äÿš>×ÿ%eĶç*!° »|C¤ÿ)Ýx‹µ‡¥'L[!‹û+p¦OXξ‡|¸í›ÁM’¯“ÔÁ&c:û}ÿ†äùŠb±žçT— ·[uA}rŠÕgE"Ú:p{x^ȱú;Z"†%›°¨6ÏéPú+˜ß?$ýÚc ù±±sâû!ú-I£ÁÿÔ²‹s³wm‡À’£ãÃàrÔ–›ƒüœ)òàíæ~p¹ë93éÜšX“O¦ÉÁ ñ.‘mayÁù¾ŒÛüÊaÇY¥òï H-œ†èÏʼAGí<£8y#ä½üÛ[-IåT¬ŸÂ<ÖYÓÇü÷ëSïó·0|ûz0]=§j4e„i;®€!÷Ю0Ð{ÀÔåvç)4ä¬w>ÿQêyi À«M+}·¸£þ#v…šX(¶ˆ PW“ G#°FËÉý(5mÄOõ®*=Xß¾™Ž©ï>˜ß2_°²‚{ÁÍ%z\»{ûY×%7&2Ç=‡¶ñ6v5Ù÷!_;øÛ´Çéˆ>$%Ÿ ’ÿÒ‹=ò·|¹óiJÿ×”™¸<”í9÷`|¦º,€Ã¾ÅëžDˆ>;…øô”b.aóȾhä1·Ýqø‚è5VOQ†¨ ÒsìÇ H^­Ü£ò¼K éû\}À»˜Ü>cëªi §\ÐÙ±èø9”«ôªº«ÖoAmýB§œ—û¼6:PI_éË~T~f?¬P›°ô„Û>š¸Än…½É¼~®Ž@i³N镘`™ìöcG×\òüÊ…¹O† é¨M™‡Ï<“¦0È!†_@ô·Nq6£…¢™Uüb ëÑ8“ˆíç ^×É!C–ùü¼ÏH­½mÎýabÖ%˜3ÿ~èÌp?õyæf0¶ðzC›¿YüÑ/Y¾dñíy+>fBå3¼ ŒjÈ¡Ÿ×a>÷Ý/Ió1g ”†,ÂaVZ!,S;ôbVÎ…š¼‡ ÒñÔD-îø4€ûï À°ôάáÏ]¾ ú²S'>øÀ™ò™(DZ/èç¥j ¦,ªÃˆM»†j©€…Ô.K©¥1o»b—޼S3[‘J®Ã¨ö)±ÙñËÅwÙ1Ù]¶;«Ýp@•e$ÀV§€Qv£_ àYóFñzΟÍÿ ð>åmßë?Ly ÛŸw&™ó6£ï¦}ž8{ŽZ?̱šªt ÉßýÝîx!j¨¾›÷ze–yÄM‰Kƒ¨5Òó±Ÿa9ÉsVlçz˜gý9XÕY] À%,hïmÓx-ë8ËÀµ5-ü2r’¿Uc‚”áû¾]9y7Ъ•" l>PzV^MÀÄù€ä¿qè{î£k E4¡);–ħ,1TR¶Éó­pró.¡Z±b VzÏEÅcËÅvÁ±h‘r¸ôrÀý¯P™0DLÒ%,Ölîì-xZìü `À¥¬8€¸æÏ1°uÉÉ<øž>\;qçQíÀ>æÿÃ>ô=¿ùr#úŽv›-²¹>6á>³¡’muë$ú^Çû¦qîÀm±Ïƒ¹àW5°Hª-Ë(Œü¥IkÑŒ•£ŠnZŸ?Bìd娫¼Âí‹°‰XyÏ( |½“?̆«’G HN% º.cßJ€_<ÓÙ6¸ÆcÏ¿­·*Îú6š A—ǶŒ«·ï̹‹Joe5ÎBJ²&×n'¢ÞÜ.-à9@,Í@eì^µPf–‘oÉÊo} Ú-'y×:m¸98Ï‹‡è³^-ÌUá€_ó¸aEŠõ‘Wu¯x^ *f_ư<f'2´ìæÀ-xujx—ºÞl«='cKߨ0Êm±€Ù8‹UjŒœÄ ]±¹—Ö7Α‰Dë7Z½A&ÏZX>¸úuÍEÓÝK–JhÖ˜'Â$­Ê÷ß©´«]²'Êi;O$Ý}óYÜ)Ü<$VÅìΕ ÙûV²M§ ·-˜É¾ Þ¹ŸÞg±Ç†þæf\ÚðMÎyýóåí3Òß+ŠçXœ;z¥UNBYëã+•m©¾Ç­Yâ¾aÑÓ‹[оë8Ì8Qã4Ç8ùî®Z¹~ŽS TGoßraômpÎÑÙ+¯DÁõÅjW*Ýúø®QgnÑKvjú™©p\.WËÿ:–½êP•&7Ü'‚ ~uωˆJmš ?}@¡æ¨:d4%ÏfKN“މ³}‰À‘KäÖ…³Ö úwŠôÙºßc#ûlìcXÀ¹Fä¨þ Fäl¿¼bslÛ÷n¾s*r§Êß<¯I-ªH½£pLŒXý³+#5²+ªÖ„O ¿ð—ÙŸÌ­fö}Èÿ ßAÿÅO–ÁÁ­E7NËxh3ø’?p¸:é½.ؾTJ];ý´¤Ð}Â\®¤^k… _–ÆÉo2Ðÿ’0# Ƀ¦sÆç"ÝŸÏSèQ?;>JÃê뮹½Œ­÷Ô蔑—×"ù[!'Ìûý!×Dg‰»G²ÏUŸ¸ 0dPÙדùòés8 (|ô/ÞЦ}ä›uµHþ•Ê“}Ó†ß)j5\q¢‚`b~jÔÞ£?jnPý!–”/.Ïi›wéðþÃÁpØ™‚-Þ½ú£wÿТZæÃq'·€=]|<M¯ÓÁ~“I+8Ÿ±ëcþÿ-üšk"§(+Iª¬ÿâ|:@†n xïªhq¹­Ã,Ø%n’°Ícì\¯Û<óóø“9„}"ŠVi³ê3”÷=ùµ’õUI³}õB¼r¼W|­hÍ­-î—k²gL9Ž[Ò¼ëëÏ;œSÍ·¡Ó¼ÎœÍœR Œ%ð2S¥¢p(Àò’ÁM¹Ånê _ó2l¼ž`-¢1cnr¤ð#§Æëñ–S’‰0y¼.sÏ‚£[ÃÕ_çXegìÛeZa÷ó_ùüærÏ>ãÿo¢ÿ?¿.ßž¡}àÖËk®»X"Hþbër(»év'hs™±*€éÔ”˜šØI×vAãðXÝ èû$7.ø‚’¿<3Žæ SHþjú8E.Ý‘ ãÇE-Œ,hûµd$@|Eáëäñƒ˜+ë­°ÕQß'µxWçJÏဪ‘ˆþ³#©\k$ÿÊ7|ûj×ÂSHþ7kÞè/*MôlÒÙ5º2û§?Øz)í x„)€åáþ!âO©_Ü8çÛÀæRÖqÔÚó¨Ë†ä_äÜ„P‘öÃIÏÇëº>®³ë€©fÅØÖ’}Ëÿ¿í·h}Và ußÅ=3b‘íµRoÒàÈÉ8¦‚ï=¥ŒOÃW? dsÀd¤ÎòËÌ ±0ææ³ ÷ËLÙŸ›æ*HŸ»hÈQs.Ð#ÞfçœRÙÒ†Ê ãï6C(j“ÅÒAÇ&­üD€û÷ÏffA Ör‘YYw`Õ“Œ€À¦Â Fõë] ÛÙwPm¥Œz΃å¯EhDôY!ò´³šî—¸wÉþÄ=æ íIJ7Åï-ÿÁC¿£‘ã5ˆ=óQyÿîùBçÖŸÔû]azû%ày¤y¢õ‡çm‹Ÿ7ƒŒ ÆÃ”ÄÒo¶|Èx su-7°e樧bŒÛˆp‘Æ» cƒú4m]ðÆh5ú8ô¹¯ªNòÕGvÀ®bå0{>¸Ê—Cë*WÒf$‹­¢‡¾ld´î9¶Ô+F­ÞŸ†¿&%ÃPYcn–£ÕléE{V®QÖ…6Öp`èg"©³2<ì>þøód€Õ_K^ªP‘ ÎÛ! ü `ÇRÃÊœ^0Ê&/:ø%À==uu±œe)`(5~Ó´½W²f¯³< “æWî¨W[Šý é² Ç¨EŸŒ'méÇ-wF,UÖIFB±’·õ×]º·,²\ ë&·J–„“ÎŽ,ÿcÍ þL{ñÿ·Ñÿg‰E ç×ljMÓ0s܃ä.™æuøRñÍ6——fËš3Ãï%tÈÝ^·ïRú¬P[óíŠÇÚŒäÏãíSŸ@òçÄ-“(ØsìeInLÁvûBümø±àÚÙ¯fhØ.ƒo®ÏgN´!`÷æÈ RuÉ+×-­Dôi¾HþM̦½¿ #tN~æ€w¢Ý5cDßôl§ €:qÏ7”ºúþþûÓÛ>:,9ª výæ‘ÿ;#]n«ÕBãÏEC†[8#-ºgíZäD\Ü3øä‡o°r'Ë÷ô7Wñ;_¿®è`Êö-ÿ‹úÆíü™ ƒßá'z5`äœ|"¹:uÍÃptMÝÁp4kÁ•à{êD„ñ/٠߈0¿7Gƒð{Ft]áü/íNqºn ;öx#ºè2L¯$’нâBøß±‰ž½ÉIñ'Ž‘³¤fæ´ÓëõŸ“¢?ƒüã¹ `J÷ú…à È`‚!#àÝßA89û^X÷6µ=l¢ûþœøƒ± 3?òÃÝêTŽ1¹ä2‘“†v‡Í&·ˆE}0=9Â?ÉÏX.P`lœÆ&ØEƒÍÁØh¶s ¿æœBàLÉ œþtM‘ìlàðû5,¹~6húèí98‘"ƒ¸G]±ÐÃ?êÎ"p $ÂI@ô>‘ˆÿü>8‚˜h:8‹ü­x6y #‡µ·ûãù8íNñ s·è{þÿ—õÿ4‡ˆ!´!” °ÐqJþÈe OtÅôN"ÿÆÿy|Ñc D߇”?4µlþ¶ÃNt‡I.£äí9,Ù‘ jïÑØAþq<¾È”üc¤ìb‹Ú\J)È>è’ÅÁ09Qõ]Av$ùcqÈÞd?r”쉶š$M2ÀXNv¿þÿOýÆßö?j¿]À¾½Â\’ ¡ævYJªuÛb¾vó­² àCÙYÍ?&D`¹»lqïç„Wìµ1‡ñÛ}ÅÆÿIíIZÿ¸Þƒu›}a_á8lÌ7zØ"á ¡! öKätÝÆ\RFJpWà‹„>º¤”êèC®?"ºf%è-ðÔÔ#]¾€½àx¿'†AÚŒÜ#W`Í(ÐCÙI€±#IÃÂ!ûpÆ AŽ ,Òlò™R³ù– FˆÇICIÃCÑ" ߆`älؾíEO` ŒÜ Û%çdd´€oRÉXu!­2Æ&YÍÒæðM3pïòAÿ©È ¨Ñs,ùAÚBd”uÿò?'ù´{l"РïùÏþ/ëü‚/V, äy'Æå/M†#?Dˆ’?´@Ä4ñ ÄJP™< Ü·PFÑnàT€!8 ó‹ï‹òo¾'È À˜rÁlâ?›ÜV6¯‡üó}83).Qq ¹ÿ¤üsÈ0€MÄËÉ?†øOÎu§ü<º@^™MN” $(RA °u~7ýï«sç?¶ýfƒú$u“îŸÿAÏ{Ù‚.Í¿d{ p†Ñƒ±Hn·-Æ„¾ 6ôtÃCqÿ¶ ÐA7vÒ§ú‡òØAÁÑ!Ѓõ¬"Àj¤rÐXÝ÷²û¤å ¨?ý’8 SøFð#qHOà×sý]æ­ŸÅÞ˜Oл'Xä/}Ð ò8|\ÈZ—C=ò!”`rX$|¦¾#×,&i]0Ì=çGú8.€‘¤•†À†"ܼ ŽÖôž…À3䓈9jÒݱHÏ|ÇäRË$Q†øOŽ(„d|ÏB7„±sPΟ4¢ˆ*Z?ºO£!þ³©Þ$Ì'‘>Ù¢‚2T   c¬ûËÿÄ`d¦Yl½¾çÿ_ÿÆá”X À9•f¢"°.ßEâoŠÿA1!ÜG^î &]’{ÃÆé&É„[À"ý>™ÅbñGðO"6? tߤžÀŸz˜ä'Å*Em5R$«øü$·žÁ#埌ɈŠÔ7SÑ©=|׌ècôµ¿—þÿ_ÜÃßö¿ß~«€Ñ#Ë(ÌèQ¹;ø‡uí­Ý| Z›áÎöëPüÞÝ_’W>æ9¡ÿ¹c·uZnÁL0÷ø,šè2ûTëѺŒV7ÜðŠâ ÿɱ Vwò^òø©~¦Ü~¯M¿•þÿ?øŠ¿í§ýNÿwë¹?£×s‚=2z]ª§± À±€XþïHŸoCØD”Â…¶v‹g>Ñ=¬Ð*ÿÎèvÛfš}R§wZ±×é.Õ¹+ÿKYiÌ%Y`•z䩎?CóIêÎÿò"×Ï¿+°ñB Þã˜Â‡ÝÏùúìâW‡Ã¿1ßöñA¥ÀZyÂá²£—ev´Ðh Ç¢Ü%ÖȬ'Ó“<%oÓcù7(dA6¹2¤ÝhD$ b~—Û;†ƒ e‹¨SKrlòX”ÊñüŽ|ÏM%EÑúñ(žQxºJù£Þ8ßø1q!úðŸß[€ê¨ô,¿T€ÉB)uìMf ¶¸þñü?MbN¯M}Îèý/$ºÄ ø.žÂå[˜sÈé›ÉÈãóŸ:gSçåݧûh`¢wÑßK³]¼Ç™Ýù\Ø‘ŸÌgÓÿÙ‚Z Aø@®_˜ÿ'ƒÊERž›ßG9~V˜­'ù“˜Ÿš5µÓ‚¢þÁ>?@y~Ͷvý}ôÿïû}Ñ~Ÿ€Ñ;´g»ìÀ{UÿôÈèa„P»»ucl‹‹áöÈÉ úöNæö¦ÂZ·3ïg]° zÁ^WLO"<²ç=ûü#QÙ…<èA±ÿñŠ òIæôºMPëÇz~ñg'`Ö«€Œ2ölw&UnB;B§Ñë¸.d­ A0Í03…_ÀC.ªpa¥‹ŠûìpœI î–|¸A‘ã' ùé@>$ Uœ_Ĉõ‰"!?GÈ?$ý6‡2vÔ  ÀÎRÙJòad4øçõXwõÆ?‹%¿¢–àЖ +à?»œQù$C„ó2FåVuÿòÿTôu}ÎfßèêáAF!_>.'zfý©ˆ“M•¤ øÏÇå‚c%ª7Õ‡E¦õ©@ç *u}G Š£ ´7,Ž0ÿßâ}“…ùò 6“G9M¶ ÎàG‚äú§;r„äaAñŸ+¸C¦ØqaÑ?/!‡_±Ç/ºû#˜¥AùŠ ›²|+t½ D&ëI¼‚;ogG ÊöºO >BÀ A¶ž¼úk4Z¿ðLUŽÈD-ÁÉŸLÂR8…2š,ĪnÛ- ¼*È¢lUÅDÎ $jØ]ƒ‘iUŒ©÷—ÿ}Íÿ¾ÕÿÌí ç)x]YA©ðÍQ&-8†Ç?´‡À¿4ñ·KÉßñáp©qªô9`’A”0 †üþÍ3‘ŸÿÁÏ ß# €éžBºS¢ëuòIÅ_RþY‚Ú ß#þS;ïžÌJ8‡Slågø€ Ä Bc4"ùÿÂîkþÿϼÆßö¿Ôú<àçÿ{Ÿø‘úJcRåV=p¿Ü¥7.CªËãC2–_Œ0Ò§àÁ?l8ô84~`r,¢‹´àÅ랛҅ØüXÔoÍ1«otïåäI]Âÿ"x]ଇ-fx&s{•‡÷4ñ4Fd/§!‡ìžÅaüqÞ ªË?¶{ÝëvDÿÆ…~› 9|p€S?ÎEžR5w¤ Äõ=ü’c.Qä‹ 8‚8p¶ÏK×ÖÝ3Ô!· `™›³¨fª«^½z½|µÉi4#…# ìÄ AÓ+ˆàERµÐ§Å’R ÀLcê?UÓ‚}(\KøŒÒ•åFlÆÿ%çç¼ yYέŒN/+"p¥¯^ƒóƒžº þ—&>êÀÜÕU!÷öo×þºåçÿã<·„£caÿ¹‰:÷N’ËsW¥NÎKéîRK”TSÒªóŒ{÷±F¥Õ`:‡s†)1óIýqBdÒ öë1yߌ’%í–¦oÎâ©)ß"* 4g€´Q§VÓI0 cÀý)Ý&½¾Ð'OÚ¶ÿ^ Ý­í i„öáy}µ¨jyAÜáÜÚ5>¾)ã –LßâÚXA;ö–l>ÌŽ62p¬ÿ§ ÍÏŒyq„™ÿ\S%AAá㻟§<:a‰=¤ayò‚º£09šâ?¹¯t¶¥b¡ôLB~ñòŒQõœ ìÏó<8-Lÿ¥)\%½röŸOqŒû7² Œ´AE]Ô–À\‘Òi ‚/~öíÞþmÚ?kýù'€õÂ~aB†‘zá´³?¥ûºá¯ó¨G@ÌÏaBöŸýs¸-kø?ÜÑ`ËBé× oU ¨ë³xúƒó¬l3@tv¸…ÚÚÙg^ <   ¯ØŒÒ|÷=cÈZîöoÙþ{ í­Ý ¡Sˆe;}aõhkcöOЊˆ[Gƒå¼ž³¿"oîk±¿+"E@aöÐþEþ0¦…Z,þ.é.—\ †/N&kÙE”îIû˜¿©ý„}oc˜Lîñß.ò¿£s ^ s´ÍcoxWò«Ô©îyés¾þbÞ~ã¹ ¾øð¥1ÌóÐ/„ZEìÈS]nÆgåš$?³\²ˆëÑÅ@‘h}ܭǦáîÆ90óñ/çŽPq&oÌËGò‰£e\ ËE] 'íÀèWÃ3gNàœwsNAÒÌZ¦A/æ‚RmÚˆŽPúà~ÛÿÝ×­Ú_µÿü—çñ‚(£H²ôĤ»ZbºOsúØÙ_Ä||wUû£€{Á‚Ð ˜u7Pžg\5ýÆ]äÿc2¯uÀÿ-2ä\v´-|ÐÀàõ„¢P{ëÂOßýùŒhy Ü@üý¡‹OpÁã–í¿çÿµ¿µ þX´ÃÖ|AÒÛúˆ=,çá_ƒðj{Ï¡:Û<òÅÑÐý'¼J½ÛÔ~§›©NŽ_/m|èAUÉ~wÓ½f‡8#º)ïB(äÉËMU;Jœ?â—ÒÞöÖÄO†P~w:?w{ØðdSÂh&ûüú}ú€$a©_’˜§PÏCE’ ¤:búðæ¬šbwõá~&¾(3T4Ôk4ž›4@¬4¢çéäècÎ…Y|òòÚËùsbI`„19ç ÎgÒ¬ ‘CÖÙÌù#üyÌ‘˜K]»v›<¸Ïöó>}Ô¢ýõ]xþ?llt£êïY÷îÜ×kÖîEÖ¿T%÷ðh P9|ˆæy¸^ ÐM’¸s0uö|Z‰ÔÝçfß´»ÒkþÏk°\?T|S@r\§Ü@‘C´@Åã‡-Ûÿß…­½ ©Åå±/ÀÓ ˆ5ÿÔ3-£Ò¡Y’n|ÖÓṉĿbÎOh ŽÒ ,ƒþ>ßE}à •t/gä9…L¬£Û½ƒÿ6{o9¥Ý1þ‹ü¯8Ý”?Ô‹Ú¼sK(Iþj€2ï®ÇÏ7ËÀ†ÏS=Êþ)ÍÉsñ«?à %1OýaIP¬¹O+XŒëwî£hXšsuÒl$·1šUD!î®fLý¥bJ(`Ñ0AFbÀƆù“UZ°ÙKgÚ_"Ìùwý.§¢Z¬;1ÉPHÑâ/HÏû¾w¼/ëó¹»w笽®uí뻾װÖüm¿EóóŽübµn³±~³!ÇÕΔŒ—?n¿ûe€Òš!3“F*ÜàŸ¢EÛ`Ñ5¹“>r|/}Y3ŸñúüH ^ƨ[~æ5V[¯o±»x¸úJ›zS4Ñ­kÇfG#¨ünŠŽxÉÄ à?z~­ 2ÀvÝD!(\ n¹V¯¦‚ÚþPb`¨ÞTŠ©€û°çK_àJkFÀ¬mÑ£; ňÞ^+ø|•¦®géŸÙ7ÍaÜåK X°n !ßõÐaõ `ªçÍçã6L¼œ œÔ’GåÈ÷ü‹Ë÷sHþXš.Cîµ\ç°­&lÀhÂkVßj>ÙÒ›p ö]öePÁDK÷f"ý—˾¶#†B™³Ø:T (ÖF7pL:»Ô ÄÈù üàXLv…{’ü ¡©½5Pïú.ªÁ3J0uHûp]¸úèRó!$‘ïÕçP¤ÿÒ/BîÖ_÷lA\9`…õ˰§wÊOë±öܾLÀËwmDùØ÷‰ÞžôØ ”E°cTÎ ˜«_““`•R0³ÐgFhÄuP;!õjÕ!!aÌ5}Ŭ« !=…â2ó–è}›^U²ƒ¼-ûb# %íà÷Ê\Ó¬rÇð¯j§EŽÏh}4k{0܃ah–®’Ì×V¾&n‡Ø“Kxñe™²–†)[iž_M¥>k³™°O×W¬Ìa¥6'ü:@”†k¶Ö¡ùnmÊÕ‹6Ô)µÄ<U!•àl`„êæÚD ûÁ'…fðʹ¾`S´±ÂW€%/”Uº¦~rX»JÔÙ³£¤Ãƒ ŸB°õÖw¡tíŸjÿbo÷S–)šüûwü6ëÿ&}n¨bD9ؿƽ–à_MÁ=f΃4`hR™ñ:oŸ„¿î<§õ#^L˜¯ìc6ãê%úùùI~þv +ô.áO†eú–ïÜ%ÀLŸ¿‚]ͨÔEå‹–d>šù}¸º’Ša0Ö­ZmtÛ¦­†,ÌŸ PœÐ$¾Égœ¢oÀþ×~zk¾}ù oñ¼ɺà}íåM›0uAxÔÐWð%õ9Àìµ™54²uWG­HÌó¤Ë1Âa~•z-8¯ÑX´á_˜bŠäûV„ÿ¡u®§Ñ-aÁÀp°Ï†Ý‘³Ø™‡Ï~­ýå…ÓùÛþ]s |¡:ã9K8*ê0!²˜ÆQóÏ3sÀ`ñD±ãe/æl{ʘúìzòx Ã!88]´™0ÌèNëJK£/H~Ð^­ “ͤ͵’aJ*¼>•îÞ$$¿{”ëÓéÖP ^ê‹-å˜v_f‚ËŒo>h•&ž KàãËiÙ̘d0W¹±’Å ÁÐÒúâPQáÑÅ5_µ˜`'Ú’ÆÁo6:UQm‘þ>ÖÞg=óÕÅJ½kœ”ò$ð»ýG ûû2ÙV1%S3¨ü«î¾ûÊÕÁþ|³S¿×kC±×n ÇžÚ=¼,V½aB¢Ègßo9W=ƒñ¯";Þº:Ã’i÷Ü{W‚SÖ5¤Œ¹½“æe]±ø>z$9µª3óìNoŸþdvÜá2ãVï…=îùø«Fi‘ÙÒ“²)K+@îÓà$MmLüõic¢Zº–6‡&Çip@òèìÑ ?t#%Lˆ“-g5d•$_?´ô=ÍMÂÿ`À¸+æªLÙbÃÜ]|Ý6Pk÷é~²Þ8mÒ’ Ð~|Ý«ðàÓÛ5U`wzù‡oôEÞ‹¦´_R›"-É‹l ÓéJãþ´ãà¡vÃoÂôàœikgwHö·Œvqƒ fp¼ù[Þ»bQp49­;’•síÀ[ÚÄ'ìó,—¼YÑ09%jnÏíÇÀ„Œ$z䔦ýGEU»UQ椩·ü ûÿNëÿ‚pk*Vj»»oÿ6áßõ¦t,îy ©p˜Õþ`rçÎHQ&lö–O¹‡Iñëèj7|‰6.û±›fƲ“ë󖼯q`&wàðþÂÿ­Ó,X2³õ¬ÿ[ÚÐÎçÌXúåÒ6¯áÇXª/€ÕE3œ"wÿ×Úð=Îßöß¶Ýqø`‹´·›~èÝ’EÝ!>±æ«×†ãmwܲÃ*ŸvF­ -Ÿíß¾œz_Þqî\Zø o=g–TVeöʉؘúýÔá Ój+˜þSÚÁ)Ò³¥sqÚÓÝF']Fnˆ'ÝQ®úÞNvÄ‹d”Å­‰"QY—Ø=® Êž$?ùôq'Zqõx ˜Ô‘(—²÷Ê’œÏÝ Y/`Ó5¡6K(fo‰âÞ²ìÈÆÉN‚ª/>çâ@ñ¶,º¼¬“i!2÷¹pRÜ1Ü÷FÓç? ½•Á6‡o¿¡w¥@ëPÙ°Å1`ºø‹[J-HŸ‡ŽŒò-£Q/ëš´äëÑ;SÂá¥mVÞMµ‚hp³Ó¼œ†äKo±Ùön/ Ÿ‚%ÒÛGdÝZâÕOÙÐย!ÆN‘ °^É a!ßzŠ1K@ç~z‚»µnðñ/@úÇ ]ŸÿÉ4ü·ÞDú/v^dêtw%;îr ÍÚùãþ¡Mn)Hþ¨ïÑ»îj‚ãr ô ¾7’fj^¤ò?¬ÐÇ܇kž{ª'Û5¶NÌq.½`Q0„WHX8|] Îù3ÅäÀ2²¹ôíÜ÷€yCõ ­§<“!¡$…æA&±@5š†Ãð ò8LxÉBòñ w2z­@é·¨]ÑÅŒ$' ¸òuwtz½Ò·ÐwiÁÇÝÐOfVíy¢ö¥1Õù?˜—,)†Õ»ÎðŸ…÷r«4GÈxªò ^ ZÒçÕë.z­Û0ãt&lŒ6sì{ÑÛ±(k’ûÚÒM> ï¯ãñÄîŸܧ£§ŠDE ?z„#ìJÛWƒðg¿â.P=F¥I­9¹šîsë"Þ¦ù,ÉÐ}°Kậfì²™ð#Ç=ãÚZayÀzõŽê~Zà¢É¡q€MœuêhëFÇK0³œšCÈ÷I²”W®ÚÆoì¯B½¢ð2ºR éïÁœø1’9'Ÿ²Ï¬¤É/K’†)bWoÞ^£œÍAú_\ì‘„äÛÜX§^‹Ýÿ`ç.Ï—[~TGUêíFò³$¶ú»m’=ÆÜ:R?›tóʆøõöu_Kê‹áY@OmJ ýÖv™ƒÍé=¯ø"Î~{¢—øíîXjêH€mAÍê´é/V—5n£?yÀ(«{³¢NÍe…Y¦Y–œþ}}[ξ£çJWÚ<¨Ù|äðœîÛ+“.iHŒÐòÞµð9Çwßa F~ù D‡Ÿ|ºlˆ ÑQ5[Ý\Gkñ{PW;ËØZqM|Cž^œ›ôowFW,›5÷%À%u,4U²SΫjDOY;ÉHi+»zïSð+XÆØ¿ÞÇ¡°YY|g#λ¯<-éÕ†¼©Õ3ãDÉñ†^†3÷ wO5Š¡{{Bbo^ºŒå:b§…Äyù"·LÕžw¼§ ŽúY‡ænpŒÊÙ¹9ëŸÃ>üóìÿð[hûs1Žð£ôÙþ)¿Ûúï‘·UéÒ¦¡´ù•É…œÍÔÍ¥ß$BWû²ÃÀn±y&íe[ž“ÎC(989|’¯cw&¤÷8•-…ð‡u›º«²|SÂçÝ—ÏÆÎÌ%×#àž‡"NàOf™J¸ZÕ¶¯ï›÷«úîuð¾_¤…ð¿[(¸'˜^:ûþÁùˆi8T5r4î°òöBq÷ô«ÿ¾?žEòW Ûg•‚ž¼Ìv€'&ß,RWšÓC¬|‘v“´ X,QÑBu~± Œ±åKäL‘üTùÙŠÀùª™#òá+.ž¨,R×ñV„®'øÜ¬ *$d^ÂZÓ)ÅŸ|7ß+xÕ®-ùaG¯Œ¯{¨‚ï­‰˜ÇX;õaàiåp`2¾/¢‚MõÅJSÕ¶¦Þ{UŽ¢x+ǢƂ±½¬‘X‡ ¿bt.ÀÆÛF‚ÝN×-(¶2C”EÅYÅâù°>aÈû£ñúó’ÓÅž¹óþ;.Iè¶¢Ò>mÆY<+M4@4²ˆÍšXyXæ5‡}9BfNš¨‚x,§l;Ãñœ( ØñÒâ‡hºt9¹\{B¾bºÒgÍé·O+ÿ[Û  ¬á[qéïüqù6ÐÔËß…ÜÉù›Ø:h¶£g>ÝÇòMdd^š¥ý@òŸ©iW»»„O6vV/%U*ŒüžuUG’i‘¤bëû­HÿOÓDpqíA¼ggWâ¸ó*bü0½ ´–VL†‘Š3Ú„¯`“Ä’6§Ãu†]¤ÞŒøì$ ³5»6ÞmZžûîF䲯7_¶¯˜í|NœùpWŒþùf)ßGÜ?ç‹•×6/¸t¿ÒޥЀÁúV&xÇx#ר_냟m€žºÍÇnï|£Sçj»¦€§Ùq(©N}쵿²äÝ7}¹æaÙ ½R@icÒ”‰5ª„Kg~¾Å¼>  iùnŠ%c”Î_ô Ä—­¹cß|àøÂ›)Øt[q@kü÷Š{ÚÏÏG$ÓfÌu}Ó£+ ¾èÐzi³î>òxìªï'sß¼˜f`|`Æ”ÀÉÂ[ô +éXÍi[,ýsÁqê—?Îþ›9¬š‡j`gηN—݃jÙßpýWÓü4oÀÌ…Û†Þ@ø³X4ùæ;“h_±É$ `þ€ÕçDÚWF„Åœ¸p{Œ3ÈýÈBøKzj4¿{6J΋W¶™íæÛ˜èÇRoÚ—02ü-ùA5X5©úìâo_[c~˜î86áßíNä—|•å·nŸH>…5Ù`Àìc&÷ rÙ¹§êÿÊÎÓ‘ü#SYŽ#F_ÆÚ)ñ%ÉðFDÙAšBó‘üNµ¯T ×d}w„ÿ²Â©°½Íd’_Ì8“û&éëüÀ×*FUïYp|¹DM¤ý—ÚŸ=ˆ¾æoûŸµÁ<à¶rsÑ0a€ z.+ü?z,KçGˆ®ÌZ¯:òvL(о}ßeÙ“»kîÞÙ{õÕÒgÇð¯wB Šï‘Cîcæ³Áï‘mΗ€q=áØ» EGúßWιECºógÊoîtó5 ß&ÉÀ‰Ôƒ Å@ÿ2$~ .…ÜÝί´ÝnX6 D÷Wïîu\åÛ§AnþîbbH~˺•¡F‡ýQ’)>ò´Æ± }€Æ7™Þ©º³&‚¶NFa,H-\¬0ç-)?ä¦Ç…EØMØôñS"< ;YášÓ‰Ò̓yåãí›$ƒ¬÷¬å€ÿcÖ‘Ãm¯ÊrásËy+¤¿¶ÿÃa³2î€eøáàseႳ¤ÿ“Ý3¢{å}ä£gÝÝòç÷Æ#ù>–Ë߇{­²÷î5ïÆâ‘õqv“BüŒKüc½€,Í\yÒÿvÁØEq™zYâ—%ý=§×¨íÇÝ/üÒ¹§Îvj©Kq¬]P$š0W\ö(wÀÔÅJ@/[°ö\x½p(Éw…qÆã)x0x¨œÁ}»?ƒöÇ@5˜ûmÌ-p¼ É9ù90ÿÛŠdènsÌ¢nÀåGk.Üñµ m¥ÿ¹"§¥ÏOæk8ßûp ÈLãP®x/L ¤tì´Vž¨ö®ºCjrçJ2’B—B]áŸðÁACIQÈ÷j¹j,Pnw?™°~Ýð\Ø}ñÙãà çO·ÞbÆm‰‚+MË“s³\ëƒÀ3c¼à¦_f$½åE× ;7uÄÍ·¿ä<ë¼™{ùv]ö»ò-Ü…^(9½¨‡\^÷US ÓŠBIËQfÀ¥öª-ÂÃ#þ0û//n«¹€wÅó˜Ý:ˆöö;®ÿµEl· «7ñ ×6"ü3_G7-Ûƒ¢olBø=Ñè(»H]pr®¤ HØð™dÜ„3ßV'zÎ$ð§’Uݹ^~4ìÖslÏm&-;‰åóê·9nœ•ªõI‰€ß÷Ë.ùÒ" J†!üKD8Îhh¯‚õVÌÛ8¸e¼ÏN@ø¯p³0ÙŒ"7ŽÂ~þ£"$ß­¾ 8·ƒÝ4Ò%¥køù´k£ÜÝAò/—_-„uóƒ+.!üož2cÖá¬ÉÛØ#öÌ;\ îÙcGøTŽÿú¨ñáÐ-ñYñ±%A¿ÒþoÍÓümÿãFs,Q]K‚DS¡Lì0ÀœÏ÷ìàDñõ'×Éʇ󛇇€Ú®‡€i†'Ý_ç·íšØKƒ¶îãñ•$-Ê5ô¯•†ˆˆ˜ž«§˜[Ò4&ÇdcU­Ó™Ëp6äÐ]vp"¿Ü£ÕNtªúr©ã=±#´6 (×¶t¦g×®Ü`€#ÃU©·ÍƒêBïÄ\oã˜äªÃ4¶ñH¿µH¾Þš[¿|DÈ—û¾_Ò†Ÿ¼ )ä{á3@Mv妧³¦›hŒãdHÈ{¸J®g:»“¿õm €vòøÓ×së`b§q!0¦³S†[Ñ vVy |`¶_Èö¨ÒŸ–³,BÇ6U•‹4Êç“‘þ K+Þ,séô!´Fwl’îB^÷˜}|ˆÀSM1CÃËKø‘ü ;¿L zM¼‘È„ÖH§BÔ°·­‚ á¡A°6PÐ - ¶'ßVVÃäùZiÏÔWÖË6Ç?Û計ÉÂI}5> Xùö"ƒø5(%KðòˆIœZ!® ß.ç@‘‹½dFž‚¤ôÚͳ>‘12z*3¿‹»‰¿iú§ð£–ß?yd“º³uÀ2÷z 5)xß¼ÈÔ¦G¿~y5| ¼p¼Ôk¦˜Z\›a¯€ÛÅüž:[*FÄ>Æh©c5×½ZæPŸlKÙÛz¢ `_ÖãË;Ÿ)¹p\¤3óWŸ ’0P½ÖUXËâo:ç:òÚ«XšÀتÖjÔïõ­S·4;Þ·ž ç¾ÁÎåÓë…áÈ7ÏÑ÷®ö#ºzѧB'jdÿ(ûǽŸ5Ùܯ~~PÝz‘ÅüL÷Ý24ûÿ¦ë¿d=ܪ–wZ*†ð§+]âÒýã¿ö]íGö‹]"ïGÖÖ_|ï2oÿ9!€EÏD]žøc¸]~óþ&ÿÇÎC›¶•=vâv¸t·)áORY}~›ö °3< %` çž ‰RDø÷ÓÉóK„z›éI± »€Ôûw þÍäsÞ—ÃÊ99ÿ5f+"ùØXâqeØ,g$Û}i¢È禜IŶH¾÷·YˆW¥^¸°àèÎÄÅ“é´×E¢{ü3M‘ÿ%QKÐRY˜ zNË"¿¡u´òWÚÿoû-›'„Ž Pñ͆b8x¼÷ßÄQ|f~”úftÀCz†{Q‚A;@ZšÕKùTÑB2AQìÓ[”=u´ŽñA°ì‹»Ø°Î£Á;"7^Ÿ€ÖBãæ6ߌ/3\_I2-§F4$[ŒüS(ùŒJZ›»ïëŸXÂ:½}Pϼ«Lp~3‡Õ"S}ÚÇà ‡ç®ÉÕâ;k?¥§°ü¾úÅÕœ ä} o<Þ'$ÝÕ¾ ä„qôüT׉諌ÎËóFE!ù¬Ó¦‡¿FòúÏÞÐ)ÀØ74úОN˜µ †Y[ ¾šõ8½ÝàÒ À¹²(ãÒŸY’!Œ\ÃwÖ œxßóº5Òß—É/ŸŸïUÿºdþhðÖœ7"É?$¡O;Æÿ»Q¼p„kÏñû€;ßSÁ‘üêóG^º·glœÊSͤZHÞ¢¬07´^⤵owmÑy÷Éc!?Mwz¢lÁ)•Þ4i÷%Ù=å®g56Uø–-’Ù«Ž¸nu‰Eëêµ®j ‡Ü÷¤ÖåY9Élуëküe=R¿ñ”5RÕ?Û²T›ýuŽÞÇE׳–d,oÞv_Ø»òK|ôØáиºFGƒåŠ›QãíùM™S íÞÚëñx6ÌÖ¯'|ö¶Û2awíªà…wFθé[¦XÆ’ñ{bÚZ?tÜ©w¸ôÀü•“Ê<Ží{Y= ”Â/ÍmOOBžc½E“ähÊжÝ_«pjÂD6;ni±M$Yf³BŒ„FAÕ•³êíÐVø¶dJÅUúKiMo¹Òv!6760A|âzÓHÿ¨S{âîü?ÉþÌ&q÷&Óy}Úéw.Rߌ<=Fm°ìô7]ÿéßµ¼\üþo}‘šv‚À_ZÙ¦Àuà|9yú¼ê›ª1@³x*2Go<#ýÚœíQZ[æ¬|þᯂyhJHµÆ^Úë ZãR¢|wyfÂXW²ÌAJëGE%Ueõ°qnbnBøgÏí 1Œßšäì¸TŽãÅîqÿù% ÒÓXoÓ „g½ÜðP$ÿZT+¥B5°¡óƒb’ëÇf‘É‘Paéèo»¿>$ëÊ¡'àÿCÚ Köl z©6IHþ<í¹…¤ÚÝÁ&~}€“‡Õp‰§üJû7ó·ýo›Cä lÍŒ›•ùbïX€Q?BXb]ÄK¨/4±…ò´Ôàxµ4~emÃ4-ôÍéš¹fÑo\©”òr)óIÍÉÔƒ,”¿¹nœý*nÿë§Çl%=óÞëih3j{1IþS2@ƧylŽD8ɳ瘋Hk£€V&º¤c^{^+À3|êÔ«6iA ®[ìVåè€ÍűÍMu$?5Zéb÷‘Í„üÙÑš5=R Èÿ.-¨3IzvidÚŽ[ü²Àà Àº¢XóƒQH¾MªÀ£p¯NŒ}͆6¬»7ùÁ<1Ô,ÎßÉŸ2Òe¯XÓî@˜úÍCú:Ïœ¾Ñõ!¸w·–PÖkÈO=¯žf9|õ4ôûv•úø€K5Ãf?s=Ù:“jŸºº°Â®×v¯ŠM .™ÿu\g<Ö–ÕQ0µkú¶E~rÏ,þmyóUYŽÁO‚¹žÆ§ÈÊÉú‡.Œ¾8AKvÞÓ<+ˆBƒ9\¸°tÏ>X"æ³ÌªK& Yn(uâÀõû_ñÈÊUVaŠ?’ÆJo¹Ù#Ûü@Ïõ‡ôLûV¢ß ËaRnT~ÐÌóQlè úŠHËÚ=-þó ®4Ó…’ÿd“p₸Պ·àñØ H¾3.njûâÊL˜{Þ‡P¾å‹²¿%'â0™±ª y°N<(vms9z[@‘_sJ¼©÷•ËÐÜ•S:}žÞãTˆEÙ×ÎBÎÒ=%Å &q…5Ï­G™^¨ÒÊzÿÌ(4“}/—ó5$½B¦†Ç£Uo–vÆ\BNc×cúrm'ä4¼Y·3‡”èt¥¿p¹5ü ýÿ ûúí(Äš”Z¦¡™A–]Šƒcÿžßvý‹¬Ý´e=¿hŠnÙðçÏü=m÷Èxö @øª{æ^‰!>'å¤Ê³š:-;Qº¯-£´áOW×þy"\ÕÚóÄwCù€ ÂS ¶ üÅhh$@ø¹'qß*®Ý¤…ðõáÚZ©ô—`ûÀ!Ñ뜷ޢ;ÿZ¯¦m|À:ÖáuË“j‘´K f#JÚˆŽ¸rµãí«Cð‘_ =# 5¯6V÷úú1·•ÎzÍ—]ë˜õ¼e+`ƒâÌÍ¡ð8q³H ®*·CvÁ®/çlræ1ù•ö÷ 'ó·ýßhØžøAÒi#½àÆä°)]du!!GÑðGÉäÙÁçÚq‡ïÃp ÏQQqßf™p`d=Ypâz‡&#í•Ä&-ûÊŒÚMG.ëî W!¶[HøÅRKW…¾á‚gË !°o/©™%…»Þ]ñ+:0t<ŸjøŒ~|C-àŠý’!£¶"ÒˆéÖaNÿþ%^ËšgõÈaô0ü²è³ÉãéH>æöâU9Ã^ª…Ëkdî(Ý ÚÕŠÕ¢p¿ÚëSk¬¦ø8}þ11É·m6»ü 41´8wºØÙJ¼Ã¶KôAâÈ'H¾‹XRXu€BÆ•á¡VHìêj½CŸ£¬za¨@@µò¼‡Ãè£Wª}ïOñZs!,”Qš ¥ód£¶ªéý\>e­Pn Þ}gø´‘ú§Ë±áÚÓJN„KÅÞ{ ½)×#é?“ÏäóÐÆê`D;Ʋ…gÀéKÀãžíïëunè|*WÛtRmtŸ&ãsûº›0Œ5ÅZ,VBÜÃpaÛ`°YšvÜ/nwš”üb€{é‚8”´N]"(C+–8(VÉ‚·»ö‰0ÊìBU§/tˆ( \Û|~¥÷¾.s§æãqi—v©%À¥l¦Ý]²þ–¡çtbœÕž9#ZŽ^zt]¢ùÒR}€ràs³ª*âY‹³ð¥G¼rwÏÞ4kÙî ‰.cV¨š$u£v^t_*_Q ´¥`ïçû…:D¦*wøüQ¯}n`ë«>~λó9Hÿ >—ôŠ6ÙØ“[uid’5òÑã¶ŠØläÓx”:kmTb´%´¶åþ1ö?æ²,í¼‚¬u6¾²MT¯ø$À“)œÁ°÷o¼þ‡l–BøcU.˜7'GÌá+Z'ö ‡av"kÏt7flþ,^3aÉår¦O÷²@íé"´›†óJáocÙ0­»ÏÜ//}9u?VøÚ=-“©×ÖLÓDøsŠO¸,Ÿz¥V×4áŸÁM= ϪË4‡Z"üAF]Ê{„ÿžŽkµ·Õ‚½ùE¾ú«¶N£1K{õĵûš»ã÷B·•†Ù‹/c¦(cns”aã±= à‡±υ뵓mþ¯ŽJ$ᜳæ€æ²Ø÷`õ€ñ²iϹáéñ!Iž_¡ýÁŸœûÛþ‡êýË\%`± À*i.kócïc@ܶê6ý| èä«w­ zfdÕŸК²˜)$tãÊ5¬ã^XêÒ¯v™·È5Ñ΄Ÿ}¢zt5]Á—1ªÉo?œ?Íϵ<€y[•IÝGó¼=ç¼Çêšß^*L‰Cy©tª†âÃæ5·òÆ«§½¿ÛÄìአ8X_œ+6 ¬’Y-[¶ë dEðXd)l·«Ñ¸°Kú1Í*~NL±¼ÒÔ7%Ó3±6 ]ø\«®4-¥­%ïÜÃøÀs°R‚ö¼œÙb½¯ì騦DÕ¯¶òãôWOQêËt?±àöƒ×†•>|I ¹knÓÞ?ž9 °ÇE¯Q |tË=˜-àÙè³°æ… Bœ•‹¤Öúw§.^žzò;ÿC³õ÷ëö¯i‡C{çeÁ}W+°í ò­Èpµ©«a´6é}ð]¶ˆ5äó]N®`N¨b1ç²¢‘ù—3¯M`,°2¶‚1ÿÖM°;±m,øžõÝc}µÌ,tý³\­ìü¼.·55óžžWök¹ðîÔ=о¿ZߣADy)CpÜë«M³Ä†[Aéè–ºžÀ®Ë)™*­oÖÃ…wË> |³§'fªR¸`ÇüÎÛGçHèšßsIYÞ¼  B¡Bæ†ty ÏŒõ¦,QýŽülÙlÞÚï x,üU0§‚•KÝ^Ü=¬ïü’=ÛÿûßðTÜ„–¯\fÉ]™õfÕ®fVɱA°¿Òï¼þu½+€1ºU˜¾ó([Õ‡´¯Dúùơ:ç:k€쇧̩ Ïhâv—JàOõÙ†H¾—ñ>/µÅfP'h]¦ 0eœÇ.„¿™ëNÆçá°9A£<jæyø¯‰)h¹q$…ÀßÄäo)ÿ.j ç°jÆf|òÊoXèS¡ èº,¢ªuülgâŽì@-º^ü<ìÐþž+_°sà“oI —P ÑDÃîŠúCÄ“ËÙW]¿?WÛ4É¿½À߇~FŽ|ëI1èiÈû…öÿû÷çæüK0ŠØ½)ìp(è¼=Q·ãœtœzÆ)å=”çÄCŒu(f—²ôœCë‡éõt<©ëxzo;E×.¦y4˰=ždœ>˜Ízöæ´MzJì‚BlcHÀè¢É‘•G5Zi^vS9&/ç²Å]À¯L©¬Ôˆ#™ , Ç •‚——”:…}GÙWø7f6³~ieÃxß|à’Ê|öür©ëû.…—º'ùÕsWUÅ«„—‚—¾­ãØ3fýÐEe[6Я½à'5ùõi7-óGo…Bù ›&Áv:ßi‡u¾3ÁåX\cGàáÍþfûX;·ˆçCÌýd©2Ì6%þZ¶ùÖ•Úó§w1ý¼WÕ"ù·&}»%€ªtZí€ëÖBáõë¼$kURK:ºãü—æäf™êÅn¼ äøª×ÒÝ@_|„]6’ovdìõd˜'{å[ôýëaÖf…“³ƒ›zPÏI¤f.Ôwy ‡³|•=_«›\‚«»Yµƒþ“l‰Ë†¸îbgŽíËEk· ¿ý@‹ û˜¾‘Q`¸S\X#q‘gv E3©Žá ùÛö¿)ȶ¯QÉòÙ®9§ìŒývñ’O«£l²‡—s¿uá ’2Uĵãf{z…?s\J_[1ôµÚ” ·àŒg³Ü/´¿þ?ì_þ¶ÿgmO ó_nÝÕ\èp7_µ<èäVN:ÜFa"ôìŠ÷+Lš±À{gÚ:–žÑ€uµ=h¯þJYTÎë3“J*&ïX¬ßPxe9ÍÅ*lWú0q©ð<€9GŽ…OòNÏ<Š=ÇTƒ¨B£ä½ò›;@&da*úð·‹·÷e®Î%N益JùüÒ›–jfå{llI)`5Wïú[ŽS‰™W=Î0I\—o{q§2Z¾+JÔl:®¡pÿ{kJçÉ }>c !™£Û5ØýSKåNBþžo‰"ç?aŸ;üZÂëjšlóÛK’~Œräz¥lë¼w]½Gö‘8‘­®“¸|CO/«.颸y+2<ý\£·ødçkGËìüJ€åÛZœ2}Õ«wR×ÇåÂåá;kañP‘6UÏl€ƒÂ7]ƒ=é‹Þ"ù‚£Î‡ìÜrpü…ž«l7­›ž€MwÆ;ÙæYBÏB1ê¬mårJrªcª\²Žh­ù–Z2Jà®$"òÉÂ[ÐÂ÷,;k (ׯ=ѽ3»«2t¤ÂÚ«.T&…O`©u}hH°ò€N×ÁP+ù`g ÇÂ$ÅáàõøÎmÐ*ÿîGÎqSÙÕô°.`•ÝÅ(W(8ac§Eó!BìpÞ¹ÍÕÕÐf·]gDÄ'ó20_†òÒ¤˜ã>yc¬PöóaâL¯C†Ò«úræ ÙptuBå¹np6T?xø¬]š3¢ïÝMâªUWž`s/2 g<¯lç6ÔtD칂Ïhw_‡'ñíÇ÷Nrúϧô¶…ï_BÁefÖyÿ¶ËÕjÎç,Jºõ•¾Ðê‹fgCËh˜®½ Üaÿ÷e×@Ó˜ú|S<|ŽM)AÎÎà^æÆ!*ÿ°ýWýîë?E嘷m õ üé³ v¡´¹òÜK=ýΣġøÂÀ´ðݳk×^Eø‹÷’(¸èIàÏì–Û•ï&Xªõ{8K囀Rr…‚mëF9!üy¥ÖÑ^CÛe³¹QÛ7Xl0‚ðßüÍrçdÍ—cNã.Ä|C­¢ÒÁw§`í§s•gþ•cIy°ìãÕaÐ);·iµ³I#uDÕ–‹ñ@qº¯Žäï>^™ÐyúkÑ¡v7J¶ôØy€]}ºå+(ì²ižâÒ{},»—ø´]ôÏÚÿëì?Øoöoû_¶øÀ¦8{>Q&\ßžu0Çr‚5àkáMí3JM‰psrC²›FŠ^ñи‡ÃŽIC;çÎjÉö¥E9+¶4—¹'ÈN]¿¬. ©™Ÿ¦¼ CÃmìÖ½?Jżޝ% 6_Ð¥°>Ò¿a¦×Ûa]…ìUy|œl*êŽ7æ_\…!z½E^@Eè°uòS‘r[Ÿpf¨)0IßyámÉÃå„üº‚Ó 5ƒ€F, /¼ûþ8eä ©„cQêvQ&İVç?œ_Z“ Žgýs%hlY^»”²«¤Ül–µtÖÈ@ÈÍ«fca£ç‰Ó—{ÚY`ÿô€fýäãã”dƒ÷¼~Yå âzleƒ4¿uTDoÖ¿7zÝCmA&èŽm¹4¶g¤GÚeõÎÎôà0cY† ûÕ@ÝȪÖû­Y9ÒºkÝAðM³PŠæÎh—raÍHQ¼êïå °4?æód5¢ì=T‡†‹?p^8O¾d¿‹Î<ÎxãÑž,ˆ{Þ‰l[Ø­RŠÃ)Ñ£,Ð[ÑÁ?Ù˜*xuy{;Àª€)ïjxµÜ¨«KqÑ¡ÓRŽè|2¶gñ?ÚV!9Iw÷&£;É3Œ…[ì ØšæÕ 4}½6ó,ÓF=\Ù`uïâ¨áåûžpÆI,ÖnnÌuÄxïØEô\÷[(9:/Bþà΢`ð“jRºw¯k#gÑt³s °Ê 0ª¦¬@ìJ1¢5¹ÈŽe¶[qÈò¼æ°{Sú±ÃÊ×´`ÝéÉÍo*ËŽ9Ì/Kؾyý× &òÒÔæ)ÙŸkþQo@œÕøù{DöÉF‘€ýD?[OH/³ä},,¼ew[ZHÂ¥·@\áÊÔþÆ¿ÿúßs³1K\†Àß5Ne&é/jÓhÞx¨í5X®¾"ÙÓjMZ{ZlP—ù¤mFCÊØæ°7‘²¡Âß)\Øq8À 9½M-‚ȱoñ«pCø /¾À¯r‹ ¦9¥ïîV™Í)+[÷ì+ÂÿC+'ÿ8;ÖNÛ²‘¯=‘¾ÌýV‘éKKYÌ8%Ãð_«)|g–Ÿ~u¹¡9˜½ }y:¨Š²žå¦W„ßê’Fø¿™UUîZ»ó `·aÞ¤a3ä•7ÈuK7û[ÈH™"»ÍýqVÍï`¦™Úëuþ:ûÿ³ÙåßöÿBóõøç5z±ô[…N`°iL`VåÍ;èÿ&°E's·Eœâ‚ì$”—>Ñu̘³aËwçoy;¦™ø^5¬E ü]ü³;Ì­à"†v¶Qv_É `ć ̼ L$€òæŽX,lÎ<|³6É,ªÀ?ÿô!Sl¤³!_Pò{µ¤P=™•g¥óË"kŸrŸ1}qf¶õ¬ò·òk-„üC÷ÇøÏß2 ô{ÊÏg#WÏÉÆ@Ul ·SÒ'Œ5 .ñ1LÂ$ëŒOOvu L­Ü¾ñtéŽ@ sR?<ÃFÕ°9ôøÓq¿}Ë]·Ot5ýÇqËpFÅø§I?B‹~Ïgt<`ŸŸ6G/PÌ̃\倣65×Ú¾ÇØ?w¬…Hë%SŽih4-m»B‹@„^¡µEmPÐØûa!Ó,àÎz¤ä¶óy@}#J*L®£ÎãˆæQ?™éá—óyxsÆ©¨†œSØ œ‘J‹¯š&‚…G[Ò†ŸÙ@wö¾©y•?læEæÕ›øŽÜ<›ërJë¸5¶ëxí4Xoϸ‰½x­s=öŒÐS™Ãovå]8¸4Aá>³¬h¦ó›Ï2³J«¦›Ù+%['ÐÞÉ9ÀcÅÜÕÀ÷Uç4ve”Yý¤Û- Å7jÙ–wªAnÂ:£û´áŸ€nW8á­Wù“€)2«Ö¼=<ÑDÏ¢4m‹­ç>IïiˆCë™)ÛÞ7ÆQ™V«uád…û´ÙY³ã`ÛIôÈRe«ÖÅІú…©¬ˆ48Æé:S<Ìê®kGЍ^´|NÈw“ú!µu–W²”훌Ê3õ8eæUØpòÿÿö_“ÎZ5Ñqv ƒý¡ä£XuÛêöϯCƒƒ<<}ßÒþ÷ÿ?±þÏ×øã7™Ê }‡ð§Ö29ø ÐõÒ­C¥‡l‚éÔx…ûÍg{¼åôÍ“| \Ä`JÝSÔi?æ3ÞÞ;½J[¡ á¯j¸7fiýd³²˜X`aæ1u„êÎ0Ç,`\ýXbzt)Â߈]NsDµWÔˆá©Ö†%³UþMc±Lã s©#ŠÊXs"c Z&í쌄3ùjØþ4<®»é"X6 ÁºýÚ™:Go|]ò¡÷“³`¾Y=]ÞzÍbðöÙï[ó}ýþ9×ò·ýoƒþoÿŠ$c8áÜY i—è {âÑ>Þ7UŒáëÍa³¸½Ñ8ÌÞ+çpvoo¬/ÂìbÀ`Ä×ÄcCDfï¨ýãð®Þ~¡ÜÏÌÞ‰âàGЛ;[bz½ôMún¡»£Ü‹DGÍ%ÊŸ;æOj‘³ãÞ„¾Á°ú£Oɉq»ro¤¹G°H™ä¯ÄÌ%ÌÀˆý3æÝÂŒøó1ÊŒEŸ1`@A0£³0&Æ`2XèC=cŒ…ctœÉý4ôƒá‰>cP‘þtƒ… HgÓ™Ükô€˜ä=€º ÇÜCXLŒ˜ƒIwç !©þè[Ô…Ž>Aã0PgœœÙŸI>GŒ˜èÆîx&†Ä™D4}&Æí‘öGºÓÙ†1Ø8qêçAH`âäìÑØÄg0Zè‰1Ñïtò>`2ÉaéëþTûˆ%nÆ6üû3~›õ…“@áB† B&(¤a[HG.ôЃđýq A‡?VÔáŽ@÷q!QÑ€ãÈþè9’étd¢#‰ÔáÉÇÐs#0JÌа Ì!žÉŒx¶‹˜<pѤ@:²?Ñ'%ž-Ã%4€À?Ì>ù9,ƒœ-‰”CC†òÕÿµögý{·ð· ~û%µÓ¸Ìõ︀ꉖðXaà:§øà!lø/Ì|K4þ3+ÔìËýÃ{¯ü ³Ãy· nrDº'#ŒÍ#éIzy<ýûÙ½W>ã¿s$íø2BVGWç¨nGü'V⹘^78¡/}“äÃüÉ Ðœ¢É?ÕÀý›î3Ài øâ_}MU„V.°ÀO „E,R´.ÑÔ]‘%1³÷~R4åà $ˆéÏBlˆxÐ#g‘«± —4¹Kœz3<9hå£k ‘ˆF&Ã$ùñףЙL®ç P¼"™“çÝ ˆ‡ˆÞ\û“ìJ>mÒ»£92À%š$d0‚Š€Ðá†IZ} ÜŽÀ#mÔóÑÿ3íŸ`r£ƒ_aÿßiý' ‡l Ü8“ˆIÉø€æ…ìÏõépÝèŽ!û#]ðŸñG#¾!#7z4äq2EØ ÙŸ@º¢8Ep}:ÿ4“*z`}áFLŠðO<2œëÄ MçºYŒêÍ&)† ãÞMuŽå h¡Ð OKD.ÄS'cFoø€Ñ´­ýÿ÷ãoûÇÚ/ˆ¨—|±ñÖyß^¬æÀðŸwÅ ¸‡³þMP.©”½À[é\Bȼ¸c½<ëbV\¦éOàH6ue‡²þ•/¸ ìÍÄÿE>—¸ÿCàJuåÒ>Å%"` U‘.¦¿7ù­;çD¸ƒÿ” Ò9ýÃô*F#ôóñ2î0¼ÉÿY8Ÿ$–* Ë]L!) 'YŠñ"Òñ’^”û9L´ˆ)žQ8ÉE ä{°^÷ÍýAð'bÊT€tñt×HVß×Ýã8È‘HBà¥?ÄóE7‹!}A±Ü,Þ‹€zr³("I¢³¹½)îÁ!ܺ‘6qÓ-¤)AoÈþÜüçeúDÍ€$V1/‹ÃúÊ hÒ®&¤ý ¥ÉŽ.fƒoÚoµþOjáÄ-¤³EN$¾„ý‰â -RžÓFúãLø9ÝG·õ"Š„5ƒæÏ 1ðˆŽÎ{‰Ž¤ý¹ɺÆ UÉêYýâö&3o/vFdó½Ån:N”ˆ’²?γán‰‰20:Â?7ç'ÓíÞaIoNúrœ¬0,öüRûºÃùÛþCü€: ÝúiÉÿœ0\"XW7ïfŠ7Ç¿û#}nÕË? /‹ú)mèÍ¢` ižc‹ûI&ï! d&Í™¤™ÌÑ稑ÿ’iðÒ»^?ÐGÊýîÄ‘ø–t´þûýCÿÃPÿí֙íhö&‡ÌþI`îÁýZ÷“qBÞ\$‹<.$õ'‹Y~‘T“¥?3g8ÂA)q/›õU¹A=ñˆâ9æêÏÍ"0?ïHœ$2  3 žcq-NÔ‰%NõáQÁ¢àC,º“ÆMeúÓ-’v˜8¯FÏõó¼äq\z+úDw²2L#ìÏ« F2Ý"z“I=a_cýe]BW2° „2¼ƒP˜±Åù´nhߨê>ØöÇ~³õŠÅ+Ï÷%ð-Èþþ„á¸ú>§MÀŠêÅäîVq+MDº=0 |q_ýŸÜkB {QyA:pëÿܺYè-Ô“»@&Íä$œÂÈŠ>7‹ç–z7ÙŸ–œ7PÉ ™¨[ ý̾œèÐWƒ #‹Ìô]L©ýÿþû¿Wì€Jâë[Ã}U¾Ÿ¹ûðéƒQ½˜!lÞ|nòsDKÿ—±J ú¨¹¯nª›”ÔOñ¼ä£8‡ÿ\£¸íëA{¨ÿò&Š ÌÉéѼ‘êΑÿ©þ‹ý|7}OB¯Ø·æÅ бŸç1ÇHö€Þ¼¡oöäÝ>›Òq^^€c=Àñ`rñòjtd…žÝ›X ;q³#Xñ@tô… ’ò¸C0{Y‰ÕŸ`ö±„³%ž;“ IŒF8Mî IKܼ¼CI. ´±;9°dO\Q=YÈþowŸHÛx½¹ ÌpDY Yå–uIDÿCȸåb”'š¼Âèëÿ<û§$â¼›‘ýuÙþŒßmý§%¡ÿs‹C¼Š>†ù¹ ûskÛL&7†dð€ŠºQ ïO÷1 ú7à•›zëÿä2òôÒ¿·¢O†©?×$½õ_aœÀ~ÿÐOlÜêeöÙïþÜgõsØÏ‡ƒ÷+3pŸQ¡?oÓ˜Ù ÷kâÿ˜­Ýñ ^^À=^ä`éû€»iHîBo¾C._î÷ )¯7Ó Û'ðÂ}òP™; trC‘ŒCÞŸ Ò™Q¨ØäíÅdžy©=΋zë¼Ó„ýɪ#÷x6ÍÛÙ¿OÿçÞäˆt=„Œ0^1—,&ó®x‡·Éƒ·Q@¤;˜ýóƒz"ù­ÃöA´?ýw\ÿEþ?'ðÈþl2Ó&ÑÊ-7ñŠS¼ƒìÏÛ¯çúÇõÿþrΫp7û3zkòÊ ¼ý"ñ']5w„þ½õ¼?r`R¼9}&â͇É}™€Ñh!?àF¼¼cD³µý•öÿ›ÿÿ†mJÿ®ÜÀs9$ôŸºÆœP>Ó»Î1ª7ÞWþ¸»×wF›\óAþ?é4*z³¸Ÿ?(²'•ã?àÔw?+÷Kõ íM%úÒ½^÷ÑÛµ¿þKvôÛv è§¼°7ÄÒ¨—ÉI^wŠd t)Ü©®Q¬þyÛÀ}G¿‘þýÙ^ï|l{n>Ϋß!w 8q&àXyúž,ã‡zK†½‡|(>aLž§&‰AC>ˆÞ[-DóÒ ¢xI0Ž3ˆ»sHcaLò\Ƥ;E£ì€Î;ÌO°kï¹< áÏ!£irOñ“pŠ"’n]Ùö²qî6,Á;}©<“›ÀqùÚ#ˆpÐwÒÇûŽ2yå7| ;âkÿ,ûg‡÷ÞÌ«èžýÓõ_ÊäíÀ“.Þƒ†ìOV‘¨lî‘T®W&ëÿÜw(>{‰7I‰tŸæ8™î“¹O¾ÝÊsÃÎ-Ôc„ý¹yç\È·]‰MîéÞAX·þÏ`øø`1ÉÍ,r¡ðŽPÜ¢ˆAˆ}2| êÜcÄÍHno:ïw¬ïõ/£_iÿ¿í·lƒPþýßÿ– èq½~ëèÚ.=oã’¿â×sØô·§na$ZÜèúwë‰Má6éј¨çùYÅÎ|lõÆS—ú…8—ܽ°+à0ÿÄW4jo8I˜åy™(1êç§ÍƇ/G‚í烣ƒŸ~`¾lrFRUŽïNá  Du„Ó…†´êˆ·«æižD/ÂûQŸ?e}¡‘ÔlÑÀýr *ÀÏ<’?Ù¡(€é¸5xúØwGÕR@¸, 2p¡*múæ½.ÐÝ~ î_ùÿZËŒ¸Chøé'!ÿÞ¯ÿ?žïå¿9ŸR.žbû%:ç–“ö’Lò/`¹éçÝ}JT Ü4û1@@ÛÆNyù+q\ °Q?Xäx!¢îç2'àÀ²í勨¡©˜ ú¦uKÈÉÃ{—(ÿ‹Øc®¯v]„Ð7eóÔ,Úå‰Ò4ÁŠ_ˆè©ÎÞá¸Z´ùÑÜ5˜ZúÍù Õ‹êüœoå[£ز¿õh²„*8^A훨v{ýÙ’»·¸!ˆb/šÓ1¬¦æ±d7£§—8'y¬—#ºOlâê}3 S ®ÎÓÀÍÙ`© ŒF²ûÎgýŒöIvÁæåÈ ý—ô@vŒxït i{¥®:Ò‰8 ¢¹5Mpcc> |a{2 aÈÖËßæ~9êBë˜Ø·°ä@avSsD_«ƒ¶—HÚ;±À‡ç(Y˜¯õÎÖЦH?àSa~×ALÚó¸Ü¸*òÿö, Ä4ðÊå_®óúŸ¾@ÖË¿˜ õï´ØÄº¯l]?ÿàî …A¦±°O"ú^þ#p†ǘ7ò¶9%¾s ¤¡d÷—çß wQŽ@µíÔ.ÎßEàÿ?ìóÍÙ°¨€Õµ€‘4ï^¢üC*æúZÃkõ@Ï? [ª.Yç™=*„£Å^4OËÎÁ<°‚%6RÝ“Q~éÍÇ.U¤:Mf ð­ë»Sˆ86Žjj¸\þÓ©Üm+ÒBã´GÙ*$þÛœR·Žh.xz*ó9eZ”].vÛxK§7«âèNžh{ô¢yþÙн}ûðgS¿À" xYõnóz ˆÀò‡ab¯Ž©å×–\Ì﵇ªÝKÀB  ËݹCT­èUìä¨ t·˜‰k/þÀËk ýÇþ˜ùWTØäå8vÂè²ûd9$XÔ£ÿ¾‰”¨•EJ 7¸Ð«±+eŠ›WCþõ/.‹ î§wkåòWë½þ¯µòÏŽ¬}ÂixoÚƒ!½ÿOêû±h/ÆÿÈPFKâìéP™Äÿ9Š€Û*óû Ž¿Ó›‚sŽùo§`!”›@U)ÜÁl9øÅ¢ûo^¢ü¯ùÖûZµÐÇÅÖ„j’¤4ÃNÛkÊ1÷7bv£É"Ïuˆ” ¹ür1iŸZï¾ëƒÝãñ‚Úš#4dw·Î2=“èýÿ…†åά&› ˆcr9ãFJT•í ªc'á—ý½£*N=‹ë8L¢áZN«Û}¤ü`ÖóJC·î˜³ï-!”,"ŠÁñÁ\ Ú9sÌÌäòÛ<¤$à–N ±['.҃ȟ5íÏ "HwnæèɪMEGiÿÌeI{CT±5d m 2Åíâá?–ãÿ1ÜT<޾uçJÈ?PÀ¦9øh½»bùë¾þ_yù·NÆIå±þØ…S'âî¾õ¸âø?ñé<þ6örû°f_k:Џ@ P¨QQEÀ’|ÿû®AŸ*¼üñ,øúUp(OcuoÿÈšÀ :†çÕíƒË“ÿjw—ëë__+6ú¬X7žÚP‹cr] Åü×V`:ðòö>z6«R›_íZ;•ëëýj,_S…\²s<»ûŸ½ìv!vœö5GP1 3ŒBÖ•ˆãþ›øoÙ¬k±¹! œzzñùçÅibyÅmàTå' mz³êTãl‰ãíjûÞ‹YÉeH%!Šœ¢ï=4?»ƒ‹µ ~à!sHæFCj…ur¡jG˜#åµ/*1 J(yÚxb¹¯Ä-=±´q?6‰ÿfºXþ šõ$jør÷XÛhxmÎ?ž· ¨/iŒåÖÑ8Löi˜¥ýì¶á¬Ød‰Ãçþo¾à @<Â÷eÁ•ú†1¯†–yÄãÉ º×¯™Ìƒ Á= Ù=?¤ 3rr(è†Ï\ÊÿÃ@=6í»€ŠáxÒTl (TwänéNg¶ýÜ%AXÌóQÈä’™X€6„Ú>rRXˆ¤k††J¸ƒaüÌ¿Bç7þÿòÿê ˶€“;52j „]üËÿÀúŸxùóΡþãé1Êùzƒ'—VòH±¾ŸŒMª:)[õ„âä:Ø=ÒH~ X16"ÉoÈî±”_j:ÈËßJÿyF2Bí /†þÇãöo]žüÿËVö,openimageio-1.3.12~dfsg0.orig/testsuite/texture-pointsample/run.py0000755000175000017500000000016512271062644023566 0ustar mfvmfv#!/usr/bin/python command = testtex_command (parent + "/oiio-images/grid.tx", " -width 0") outputs = [ "out.exr" ] openimageio-1.3.12~dfsg0.orig/testsuite/texture-gray/0000755000175000017500000000000012271062644021012 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-gray/ref/0000755000175000017500000000000012271062644021566 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-gray/ref/out.exr0000644000175000017500000001453212271062644023122 0ustar mfvmfvv/1capDatestring2012:06:19 16:59:32channelschlistIABGRcompressioncompressiondataWindowbox2idisplayWindowbox2ilineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?±.ñ ® -ŠÝuxœíÑ1€Ã0äD0t cG=zÞ[Ǹ¯ûÆýþoõßÖ[ÿmý·õßÖ[ÿmý·õßÖ[ÿmý·õßÖÛ;î?ã¾î÷û¿Õ[ÿmý·õßÖ[ÿmý·õßÖ[ÿmý·õßÖ[ÿm?c*»xœKkX 5Àötðl€íÿ£ñ?²ÁPÿúʲüⲚúÖžþ ]-TqÓH²ˆÆ]IFtbvIYaqLˆM@haÍ”çî\9´ §‰ºÎööÉø¯Íñüý🮴SBHn~I)0ýO;ÅnŸ¨øvu/b`Ù?ã¿&ÝæÍú’+ºÁaéy‰…¹ÕÑÖyî±EOóø¸°Æ¥ð°²ÈÅMºù–ˆg2f™•õ¨2MÝë¾êL[­}¸—–0Ììbñ_Wèr!Ç÷)‹g%6ÙÆžý‚ ª^N§Y<ììRñ__Ê4IkñGÿ*\*šfþÐ9Hfe å.ö¥ø¯/6\â\pS±Ÿ¢¶ÍjÞ„l£E Gû‡Pü×ç‹— Ìy^C@Ý ¥%òÉ[©ÃÒþ¡ÿuY,Z [„r몜ª°A-~M3%Î1ö•ø¯+zeûý„[j§ªÞ–³]JÕ®ö‘ø¯KZ¡Sp1›\Ë„ÆÆŠÊš:¤îÐ £§R†ó¨Ø ¶öø¯Kzãï¾æ}²XSߢ%«–Ì›1mÊÒ–†d_sјj„ä"/Î TsåðµÕÜH˜4Àöt7ÀöÆÿÀ‚ÑøÙ`¨Ç?êøÌ¿qû‡hü×ca6 ڃacÿŒÿz0®GKý t‰adÿŒ°ïëÑ}ß :ÄÀ°²ÈÅ=Äóè~‡`45Ð6†™ýC,þAÞ®Ãå{hgšEÀ°³HÅ?´äÃí{heÚDÀ0´(Å=¾o€fZDÀp´Å?‘Þ§Y Kû‡Nüƒ¼_G„ïhÃÓþ¡ÿ†qÞ§E<\í"ñOtÙÔŽ€akÿЈpÙ‡­×Óˆ¬EÔ ÿák?÷éïŽ xœÝYm,•anX ›¶ÔЖY#ÂÌTkm’jôÁ,–ÙšjȤ¡YŠsÞ÷9‡CÖŽ2áœB4,R– ±éG“f…ùøákrÆšÖÎ1¤Îáy÷˵ç¹w~ÜÏsîíº¯ûz¾ßúÿšã†¢nO,x÷¹&Q¦žŒJ]ïdßð¨nlðM…"õüL’jÌÞ o¸qy¢'U–äâO¡Jq“¶!ýS»:ÂÓL2õòeœ]gU±¦¨P™¤w¯ìªðTEH™ùp}NŒQ’ãc¡È¥8E¤© r:*[‚¾”)3Ó'Mì?çøáô¦#÷ØY÷ D`|ôO·*ÐjYíG¿‚:›÷Õ*¸Q’èÝÇõ§$L»Ió. Í$ýãT¶©Ñ¦¦ú`Ê÷D]‰ŒF%Ú¸–2Pø„»ŒÈQäH2>ú_tó{½ÖȬñÔù4å è `å4\Ê‚Ú_µ_-D‘#Éø8èo¯š„.ÈrïÒ*×T¼ùTÓMØÊ.›jA‘#Éøè/™ñpu…~îïøö;Èà_1êÖÈÇåÉtز¶Í›C"ÑøèŸP´”ýµWò¬pë[3*,>D•Û:̶œ áøèêçQÍÜkýóµ½yëÓ§é´ù sè?+÷rÙbzÄãc ¿Ûçç_¡+¿6Ýø$×tíu ¼{ú%ß#[Np| ô·Ë˜š†nîÑÑ€¹¡ÖºÒŠâ’¼,±*Ü×)õÐYãìŒ E¢ñ1Ðg¤™tåU?«JËzôÓ6³ûÇ¿© +•ýOÝs{¤H4>ú[Å.,±ÛŠŠæÆmþgR,Gjó^8%žËê· «>0Û¡™G"Ñøèïø´\ÊïTõõ[zù9Öq ú éCök ÿsç2T`|ô®~ÆÅOÎÁ-² H2>úó†ÿêàpãÙ$Cý¼Dè‹@¾-õ'  ý9Ëß }q^wDµ“Œþ†íõü!¶õ±B9ÉPÔŸh|,ô—pÆôúôù7% GS‚ñqПEé/ôy“QýIÆÇAÖ’dÜk¯0˜½"ª?ÉøXèÏÑ€õª)Fn;æÉø˜éOÃáèuæµ û/Éø¸ém¥€ycóGtþ& ýß¾Œ¿€pr—?€¨þãã ¿àë4ÀÝiÁõÍû Ñø:(0“xœKkX EXIt†cKB=‰®M?š˜»Ît6ÂjcN}] á4}»Ue5™ NÖö?£‚)DÄÑå ÖJ¬RýL’“ïöA 6ì(§ÔñT˜\pÛÓ“ÍTpâ°¶Ä™ä¶9ÞµXåºßäŠmºß €Úнßõ/'ÖA¥oÜ>NÖöøoȼþEõ‘e ¶"°¡ã}»îÜSí@V]ìÑê2`M†1š÷¨‘ý†·ýC!þk#ÏjÔž—ñÈ«Ã"Ù#ºß6dYSCCÁ—?¿7EÁŵži[@7gûoüוd&å4L™7½§©6ò×ÑêÛ]b‚übóÊÐBa¶“(WC­ã–V‹˜h«’Bä—VJ\62ì´ñ_—&ÿá¡tÃSy‡³šjó#utxEÿ ÉX…FÄYÙÔÁKæS¢—ïlJ[Ûø¯ &Ø|¨»gÊJJ6Bì¬ñ_—Æ”^|Z¢á…iÿô³šê+K²ÒRÓsb5N¼¾¥Ä Ͻ /CåÛxŸŸ<š ”–m¡6oo·Q஑bÿ`ÿ"wæ"a «ÞùþÚú¾.^_•èz¥2ä’j T¨qcmÝÚ<ÓB`ÞoÚâÿîŸ(E}ï‘bÿ`ÿÈÞCŸJŒ¡-f9KQ%«bÕš¾×1ÀZÄ]ò_ä•6+ÀºHM«½¿~ÛD‰»FŠýƒ5þ _ï_“f­J÷ùv ]ºÒ¼ðL®tP¤qgŵÑ/`ù¡i±Ï+IÊ‚ÄØ?XãŸ3“í3¤1Û¦e|C¾ÒÀvæ”PhèáW纓šiúFFueÁ?bì¤ñ_ûXÐÚÊ–×ÍxŠ©¢àÎR©gÐönãìS.ÑÐaï†6žVÑ+( þcÿ ÿÒï²’ lí`§›˜*êÜ}Zš  ©­ ÞÞÙ·< F 1öÒøÏhgl+„0›\g?€EIáÃåœ/k0„g¸p~émÄ¢0bì¤ñï£ç´Úœíʼ¿h)%uîN‰Ó3ÐE;dß[Π4øGŽý«Èu!•À$ÂJêëë°N}A#I¸J`¨Ô#Ô655PÃÝþ<ÊÝG &þê°M|@@c"м’¢Jøgû‡DüãÎÈ€æý†Æfªÿð¶Ä?(Ôã€Æ,Þo¤Nñ;¼íñôYî:° œÐC .Ô þamÿऊ¬ÔªGC„Ž^JRœýF†ýƒ6þëÁ_¸lk¬‡ˆÀ2Z0€K@ôV¥Ùo„Ø?Xãžä¡=œz$D@@¸Ä,ý(Ê~#ÅþÁÿõu`O66 øšê1…á?Bì¼ñ÷¶š¬=л>ö½FŠýƒ6þ­™FðºªñÏWüñ+”¹q=›^+65u¦¬5»*Q„g†ý¼‰U5i`ÄØ?Hãÿ·…,i?|rг«¢ÌEÎáN("·ÔúL§‚³FŒýƒ4þŸ|qó„2Ù¸¦~Á®¨Véúê3UHŠ‚®Ÿj¦‚³FŒýƒ4þo߈Œ†2õ"­¯ãМÜï•ä‰ÄïQ|ak8Î1öÒø¿z<%Ê´¬?CsÜåí§+àÜÆÍMe‹Ž¶QÃY#ÆþAÿWަe@™Î3ÿÄ¥;yr\„M=Œ×´)Q¦[|[åÍï‘cÿ`ÿÃiYP¦ËÜp鮑9µõr-Œ×Ø}].äxÖ·Ù”GÀˆ±°Æÿ‘´L(ÓyÎOœé¿ÎøgýA¸ÿ[çþ°;¶Wl ÅM°cÿ ÿ«'’aõŸëÂ/ûqé.z²„åM-’@c×)ƒo¬WQ#ÆþAÿWŽ¥Âê?—yßàÐ\œVZìQ"Ö²Tí§ój #`ÄØ?HãÿÚɤ4(OýW-räâùtÑׄ–PVûiü_>œkÿXTÊœÁ¡9ÿ@˜µF=†ð"ÇW2²“)rÖˆ±ÆÿK± P¦~œùUšœB§gb 7¯ u~s¿gûiüß{eJÊV¼Æ®¨^jå™;µX$š÷µ”¯Ø‚}М80bì¤ñÿABÏÊdf›õ »¢¢}¾°ùŽÙu™åð¢°Eô]ŒÂT "`ÄØ¿Š|7RLÂ.\__÷LcsVŸÔ7ÔÕaŠ665bWN1öç‘î6ª\ñä5ÜþG $¸bªÿȱÄSÕ7Ôbø§bÒÀˆ±°Æ?’ÏššpøXÖ£•²ßȱðÇc#.ÿ£Ô’0µT þ‘cÿˆÿ¦FœþGÏÔÊ~#Çþ!ÿ’U¨Ñþ)öñøÇÈ ÅTèû‡zücÔ€ MÔˆ€cÿPÌ!Pˆâ1öéøÇ:B•1öñøÇèƒuP#Æþ¡ÿXFÀ©Ñ 1öø'aü®‡Ò~øˆ±(Ç?Žâ¬‰Â1öÖøG™ÿÀéÌù( ´ 1ögÎPUxœKkX …]ø«¦²”ùæý&¬jêÕ#×V@9GL§ŠýL©‡É͈L½õ “|gûŸ‘ïFªñÿËBRÊ|þò( V5…×Å8¡ì6{g¶âØsauP~ã‡KáQKÉvÖˆ±Æÿ#Y(óÁãsؔԚIw,Ï‚r6Î;nþW‹yGH-T`š»#竲5bìºñŸ±®ÒJZà5É*¥¼OÆÎ¶-*ÛøþZµÓ4²5bì¤ñÿÛJ\Ê|úò+•ò¿Wì.„rf¦M;·­.ùÖ ÆËP¡I®í$ÛY#ÆþAÿ¿Ì¤d¡ÌÇÏN±a*¨qJšgMþîVØMm¨‹^1ÏT–% ¢_6‘ë¬cÿ ÿ¿ÂâPæË·˜1äk|çwÿU åMpöâ~ ¬ìj­õ —ä@í¸àØG®³FŒýƒ4þèË+B™÷^ĨÿjüV>t}˜ å5ÝÛU–nì]LP‡å›)¹ûÖ¬%·>bì¤ñÿÛF &óìÕ´ú¯6ÛfŸË Xow–·1Çpg·^ïéô£Ð\Ѫme÷¦•Lgûiü£§ÿúš²¼ôôÔâÂêŠêB5vÛ¿¤Â¼ßÂsÛÉk!$¥'Ô8‡A„ožXa7‘Lgûiü#Õ/Ö|(*ö4“–òqËqLÎ,Žpàq(ƒu­©®\s¼ Â.¹•¦( •™™¿qóZ25bì¤ñÔþÝèµÔ#^Ë2%-#1-¹,¡¨¤¦¬ªîû†>CY£=Њ®Víβ“аY×Ëö™-ðcÿ ¤ú¯cÍÞŽ”‚ð¤*ì*Û®ËX oçD$Zwg@Ù—Oî0'³>bì¤ñÿÇZ\’(ým—*ü7mó‹Nz˜ëBÙ3ÊNÍYJž³FŒýƒ4þ™9¸‰ÑÞ¼?Eêñ›.„@Âám—¡ƒàívÅb§ÉsÖˆ±Æ¿X÷“§µØ¥Aófï?Ÿ„§!÷rƒ}ý'¦C˜Lÿfÿ!¯>bì_E–ó¨&a®¯«ƒ³›š°û¡¨ Ñ j @#PùÓ¯#Çþ<2H-@Qü#)jll¬¯G€¦¦ "`ÄØ?tã-ùÕ!epÄØ?”ã%ùƒ:º(Ì4ÿá`ÿŒäßX !²5bìªñê}Hbj– ;FŒýC4þÞ¯G¨€Uvhy¢™vá?lìšñò>J]×iì Ö‰´ÀFŒýC1þGõ>¼¨CÉ”À#Æþ!ÿõ¨² u("ˆ¾n=rHA |ÄØ?$â"ñr}‚„¤‚½¤Nøcû‡@ü7Bj¶4_#É#†ºê‘»@À#Æþ!ÿ„¬ñÑHxÄØ?ôãµ™K¥xÄØ?äã­—ƒZÒ!ü‡¸ýƒ6þë±Wvè¹òƒè¤JØGc ,䄸òXÚÉqÖˆ±ÆÃá¢/…8µu¬ü<¦-‹uWFò.ZÏœe¯žtºt9Î1öÒøo(×Éfžò×·!ÒÜ=qÖüöÙÓæuw5µÎ~ëðoÿ”VÌÒ­Ž«îÓ‡z»7rá­d¹k¤Ø?X㿾XoIaû¿ °ˆ˜ºÎ¹=Kç/_¼fÅ–}}ÛW?_»´sêækon윌Å÷@à X¼¡Âl6Œ6½J–»FŠýƒ5þêK}ä?ÿ`6´¨š´{æ©‹2¿o,šÐßÒ×5 ”þ{ú'tµàhÙd.õ ¶…d€f_ç[ä9l„Ø?hã¿¡¾¦4;%)5'¯¾¥¿mò”åó¦¶×”®ø9›ë$Ì ð>K¦ËF†ýƒ7þÉõn[Juk€¬Ö«{ÖR߆adÿ0Œÿ†œ'ÿ$κ4LØkõé«èdØ0|ìŽñ_yQ5é›RÃ=®·õ–5ÓÀ†ácÿpŒÿ†Ú¨Ï[–~jà‹öá€àRöËøo¨Íñ‹oX¸iÉäþ¡dÿðŒÿQ@,ÿ‘ FãdƒUlÿ$ìÂõõuõÄholl(:êêÒÍ dM¿Žû /2 - (þšѼò=\k#Pž¬1öÖøGö.ÐèÞêDº¦&2äØ?h㿾46€}é½ú†Z„F` 3üGˆýƒ4þñÔ?ßcIݨ ™á?bì¼ñßö?,$]+RتÉ#ÅþÁÿ`×7@BRÎax‡Ï @²Ã¤Ø?hã¿KáG\P"·È.GŠýƒ7þÉÈ-à¦F²ÃdØ? ã)€†GèþCÊþáÿÀ’À*}tŒ.`(Ù?ãÒxn%ÿþ!eÿ°Œ¤¶Ó@ÿP²xÆÿ( ŒÆÿÈ£ñ?²;¿puxœíÑ1€Ã0äD0t cG=zÞ[Ǹ¯ûÆýþoõßÖ[ÿmý·õßÖ[ÿmý·õßÖ[ÿmý·õßÖÛ;î?ã¾î÷û¿Õ[ÿmý·õßÖ[ÿmý·õßÖ[ÿmý·õßÖ[ÿm?c*openimageio-1.3.12~dfsg0.orig/testsuite/texture-gray/gray.png0000644000175000017500000000355112271062644022466 0ustar mfvmfv‰PNG  IHDR€€æU>sRGB®Îé pHYs  šœtIMEÛ 18&ÐtEXtCommentöÌ–¿çIDATxÚí›ÛSWÀ¿°¸,Ä’Xˆ€ ) ÊMÀé(¶ÚÖéC_;ýOúoô¡¯éŒí´u:Ó¶ÞjÔ1¢"  dC¸¬Y’MöÛd7Y²'òÐݧs²»gùÎwßÄ„ƒ= @Ðt@Ðt@8à£Pó <‰m%…BºÄb¢Þ#ÇÎ-­qñˆ°µûIq…×g£÷»Ž!·¬8úr$È ©ŸRLM›“~làÖš‚JÙš[K©<°772ìi}çQ*ŸÜÜÐ|æ+,½mæ¼$G&Þf½êtŸ=O‰™Á`\ÅuõŸÙó½Éªsoõ—íyà\S}mûÅÒŽˆ[ºñT=ìXÁ…²ÜøØ¢Ò9Z(ˆ'’RY>,ë1’ànŒn¥Ý[Zb-s•ÙLFniä¹ä‚í¿ìM$u`ôÇÔOµùœ8úpóÃs’Å_[ÉÌ|›úí[º]iâþu‰^ê%·l[gkzÐaú˜ß×Ñüf£ ¨KHØ;Òù‘+­rAj¹X„¦bHq?ýÝŒüuT ü‹ÓÛM ! Œã‰¹¿_q]ªé#´bdÔ„Ðö»/ôgÈ9Œ]§ÑÌO :'ŽmŸžÌ˜ó»‰“W„Ø„8¾ìÍ’s9|È7xÆÎ¬W#ÛK²‚(’ð¨£Üš1ýN¬ïkuUhIþO°¸J«—I>Ø„§Äq !€¢T uƒw«E!9‡2V!€b¹Ÿ>}èèªHs¶±qÑØ 8©„¬q°«žT‚• 8.=FÀS”PpP!öãjiÞp{Sœ&Œ¬•¥S³?Mc¸µá ôåzBt‡²óY¾:™@Ï¿ƒp,býï)åü.<<³ûеÁQ|æ,C €éëp)îÂâ?;•*7öX©YšúFÉéIR[‚B¨0UÌ^—­½'µfÅŒ@Y¥•†9[,¬®¬óiµYÜ_ë€èpD’64k­ ¸À“ ÖÊ>Àh´ÀIH°¡É7s’*`uÔIø%I±ñs·F.pkX6 >l”Ý~Æï"ASK^˜ü?Ÿî®×Zš±–w”,P™f…n·ïW”omÞwnnãe»{T¶j”­`f/ z-ב¨¾‚ìB˜ž¾ÄR:¯öù^ï5"ÖWäÎp =cíξ¨Ž3ª[UŠÉ%¤æòâ˜x³0ƒ Æõ­2E€ꃙt±<£¥³ §®ÖuòÞ±w?m2E€ ˜WPå 1ê´¬ µ·í§MW "4)…u§œ¯±žÝG“.JÅ‹LJaºK¦0p€ÎÈÃtš¶\5@`mr˜NkAXúBȪ”o÷¥dþ†@e~¥¶öIççR†l~èÝÑxXrS<%TWbZ{°3J†¯þ0Åí @M]±Æ•ÚA’›Žt¶Ò$$P J€›L¥]^# ÈDÚ±:&Ÿ·wöC @©Ú¦D@îY£ƒkÚ¶eûiþò…lªþè6§À¤J —ä;èüÈ3’f¸¬|ûÔ¶‚ü~žÕ Pž-#àÇ­ãONÊo gÃ⸌‘¬õïcž˜(–¥ü]4¹øU^,éßÐW±Ï‘ª•Ôx® `ƒ}>ÁkPqDo <Å}¦õÓ„—Ú ³;¢g¨b¢j€î9ƒE0—ç-x5„µÁ @÷E^rž”ʧd«ØßªÞõpJÏ¡ýœ€-Ù!zþo¸…]Õ¸ÓDªö¢Ì~U -;Ÿ?4‰6€:±›‘; $4p²Ã]ýðÝ8ŽB¾æ½.Z˜&§c2"sÊ0[E‚ñxØ$êP‡Eô1x.¾©ÎÁ/~oˆÀJÇÖU-f¦úé=Ùð/5 l– TµR¸2(ÐD³ªb逤|·¢8bsWÂ"µÏ·œ—Ê™Fv;€Ú ÇØùaJÖìûʋܜêD`<וºÍèµú<Ÿ3@•ª>ÏáKijfBzøUÎÖ†ì"0µÙž®æzs þD®t‹+›ô}_ | W5ÙÐË… 6W?® Ù2[k]×,_´Ñ§FD;Ùs Ž~òÄ/á/2Òeñ2ƒ‡2'3ÿ|Ñ{oÏSo/Ϲ:¦<åM¡å7a ¬‚®-·ªm¿Õ:–ˆ”ç”Ùì†\cårrOjyLJ•ÚöÞ±{«Êëv~Å`®ÌöîÒŸZEÿöoò`,nîf¢ OÀ}Â5¤ôÿšé:€ è:€ üïþÉ3ÿ ë’IEND®B`‚openimageio-1.3.12~dfsg0.orig/testsuite/texture-gray/run.py0000755000175000017500000000020612271062644022171 0ustar mfvmfv#!/usr/bin/python command = testtex_command ("gray.png", " -fill 0.05 --graytorgb --res 128 128 --nowarp ") outputs = [ "out.exr" ] openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-fixnan/0000755000175000017500000000000012271062644021470 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-fixnan/ref/0000755000175000017500000000000012271062644022244 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-fixnan/ref/black.exr0000644000175000017500000000115212271062644024037 0ustar mfvmfvv/1capDatestring2012:02:24 23:11:09channelschlist7BGRcompressioncompressiondataWindowbox2i??displayWindowbox2i??lineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?¿ø18xœíα EA‡c0c8°Ãà]C^ò V¿©sCkÝÒQoý£çw^î´ÖZÏê ïñ51xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-5 1xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-501xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-5openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-fixnan/ref/out.txt0000644000175000017500000000363012271062644023616 0ustar mfvmfvReading bad.exr bad.exr : 64 x 64, 3 channel, half openexr SHA-1: BDEA744AE77E178C4F9C3462110F57923AB496CE channel list: R, G, B oiio:ColorSpace: "Linear" compression: "zip" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Stats Min: 0.000000 0.000000 0.000000 (float) Stats Max: 1.000000 1.000000 1.000000 (float) Stats Avg: 0.500000 0.500000 0.500000 (float) Stats StdDev: 0.500000 0.500000 0.500000 (float) Stats NanCount: 1 0 0 Stats InfCount: 1 0 0 Stats FiniteCount: 4094 4096 4096 Constant: No Monochrome: No Reading black.exr black.exr : 64 x 64, 3 channel, half openexr SHA-1: A29F8126A8FB6A57851C1A5B6BE928AE3B2490F7 channel list: R, G, B oiio:ColorSpace: "Linear" compression: "zip" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Stats Min: 0.000000 0.000000 0.000000 (float) Stats Max: 1.000000 1.000000 1.000000 (float) Stats Avg: 0.499756 0.500000 0.500000 (float) Stats StdDev: 0.500000 0.500000 0.500000 (float) Stats NanCount: 0 0 0 Stats InfCount: 0 0 0 Stats FiniteCount: 4096 4096 4096 Constant: No Monochrome: No Reading box3.exr box3.exr : 64 x 64, 3 channel, half openexr SHA-1: 47A8E8F3E8B2C3B6B032FCC8C39D3C5FC1AAA390 channel list: R, G, B oiio:ColorSpace: "Linear" compression: "zip" PixelAspectRatio: 1 screenWindowCenter: 0 0 screenWindowWidth: 1 Stats Min: 0.000000 0.000000 0.000000 (float) Stats Max: 1.000000 1.000000 1.000000 (float) Stats Avg: 0.500000 0.500000 0.500000 (float) Stats StdDev: 0.500000 0.500000 0.500000 (float) Stats NanCount: 0 0 0 Stats InfCount: 0 0 0 Stats FiniteCount: 4096 4096 4096 Constant: No Monochrome: Yes Comparing "black.exr" and "ref/black.exr" PASS Comparing "box3.exr" and "ref/box3.exr" PASS openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-fixnan/ref/box3.exr0000644000175000017500000000114312271062644023636 0ustar mfvmfvv/1capDatestring2012:02:24 23:11:09channelschlist7BGRcompressioncompressiondataWindowbox2i??displayWindowbox2i??lineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?¸ñ*1xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-51xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-5 1xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-501xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-5openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-fixnan/bad.exr0000644000175000017500000000116112271062644022735 0ustar mfvmfvv/1capDatestring2012:02:24 23:11:09channelschlist7BGRcompressioncompressiondataWindowbox2i??displayWindowbox2i??lineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?Æÿ8?xœíα EQ…¹T3˜Ê\ ¨D8·ù9É+~(’$I’~«®›™ù¨{œnéŽø—Í33¿åðë51xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-5 1xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-501xœíÊ1 @Á‡0„!Ž_ÃLsÙä^×Ôlh­µ>ÑùùÓZk½«ð-5openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool-fixnan/run.py0000755000175000017500000000101412271062644022645 0ustar mfvmfv#!/usr/bin/python command += (oiio_app ("oiiotool") + " bad.exr --fixnan black -o black.exr >> out.txt ;\n") command += (oiio_app ("oiiotool") + " bad.exr --fixnan box3 -o box3.exr >> out.txt ;\n") command += info_command ("bad.exr", "--stats", safematch=True) command += info_command ("black.exr", "--stats", safematch=True) command += info_command ("box3.exr", "--stats", safematch=True) # Outputs to check against references outputs = [ "black.exr", "box3.exr", "out.txt" ] openimageio-1.3.12~dfsg0.orig/testsuite/spi/0000755000175000017500000000000012271062644017145 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/spi/ref/0000755000175000017500000000000012271062644017721 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/spi/ref/out.txt0000644000175000017500000000026612271062644021275 0ustar mfvmfvComparing "fit_lg10.dpx" and "../../../../../spi-oiio-tests/ref/fit_lg10.dpx" PASS Comparing "dpxoverscan_lg16.dpx" and "../../../../../spi-oiio-tests/ref/dpxoverscan_lg16.dpx" PASS openimageio-1.3.12~dfsg0.orig/testsuite/spi/run.py0000644000175000017500000000134112271062644020322 0ustar mfvmfv#!/usr/bin/python imagedir = parent + "/spi-oiio-tests/" refdir = imagedir + "ref/" def oiiotool_and_test (inputfile, ops, outputfile) : cmd = oiiotool (imagedir + inputfile + " " + ops + " -o " + outputfile) cmd += diff_command (outputfile, refdir+outputfile) return cmd # Test fit command += oiiotool_and_test ("testFullFrame_2kfa_lg10.0006.dpx", "--fit:pad=1 512x512", "fit_lg10.dpx") # Regression test on dealing with DPX with overscan command += oiiotool_and_test ("dpxoverscan_hg0700_fg1_v2_2kdciufa_lg16.1014.dpx", "--iscolorspace lg16 --crop -2,0,2401,911 --fullpixels", "dpxoverscan_lg16.dpx") outputs = [ "out.txt"] openimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/0000755000175000017500000000000012271062644022313 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/test_imagebufalgo.py0000755000175000017500000002137712271062644026363 0ustar mfvmfv#!/usr/bin/env python import OpenImageIO as oiio from OpenImageIO import ImageBuf, ImageSpec, ImageBufAlgo def constimage (xres, yres, chans=3, format=oiio.UINT8, value=(0,0,0), xoffset=0, yoffset=0) : spec = ImageSpec (xres,yres,chans,format) spec.x = xoffset spec.y = yoffset b = ImageBuf (spec) oiio.ImageBufAlgo.fill (b, value) return b def write (image, filename, format=oiio.UNKNOWN) : if not image.has_error : image.set_write_format (format) image.write (filename) if image.has_error : print "Error writing", filename, ":", b.geterror() ###################################################################### # main test starts here try: # Some handy images to work with gridname = "../../../../../oiio-images/grid.tif" grid = ImageBuf (gridname) checker = ImageBuf(ImageSpec(256, 256, 3, oiio.UINT8)) ImageBufAlgo.checker (checker, 8, 8, 8, (0,0,0), (1,1,1)) gray128 = constimage (128, 128, 3, oiio.HALF, (0.5,0.5,0.5)) # black b = ImageBuf (ImageSpec(320,240,3,oiio.UINT8)) ImageBufAlgo.zero (b) write (b, "black.tif") # fill (including use of ROI) b = ImageBuf (ImageSpec(256,256,3,oiio.UINT8)); ImageBufAlgo.fill (b, (1,0.5,0.5)) ImageBufAlgo.fill (b, (0,1,0), oiio.ROI(100,180,100,180)) write (b, "filled.tif") # checker b = ImageBuf (ImageSpec(256,256,3,oiio.UINT8)) ImageBufAlgo.checker (b, 64, 64, 64, (1,.5,.5), (.5,1,.5), 10, 5) write (b, "checker.tif") # channels, channel_append b = ImageBuf() ImageBufAlgo.channels (b, grid, (0.25,2,"G")) write (b, "chanshuffle.tif") b = ImageBuf() ImageBufAlgo.channels (b, ImageBuf("../oiiotool/src/rgbaz.exr"), ("R","G","B","A")) write (b, "ch-rgba.exr") b = ImageBuf() ImageBufAlgo.channels (b, ImageBuf("../oiiotool/src/rgbaz.exr"), ("Z",)) write (b, "ch-z.exr") b = ImageBuf() ImageBufAlgo.channel_append (b, ImageBuf("ch-rgba.exr"), ImageBuf("ch-z.exr")) write (b, "chappend-rgbaz.exr") # flatten b = ImageBuf() ImageBufAlgo.flatten (b, ImageBuf("../oiiotool/src/deepalpha.exr")) write (b, "flat.exr") # crop b = ImageBuf() ImageBufAlgo.crop (b, grid, oiio.ROI(50,150,200,600)) write (b, "crop.tif") # paste b = ImageBuf() b.copy (checker) ImageBufAlgo.paste (b, 150, 75, 0, 0, grid) write (b, "pasted.tif") # flip b = ImageBuf() ImageBufAlgo.flip (b, ImageBuf("../oiiotool/image.tif")) write (b, "flip.tif") # flop b = ImageBuf() ImageBufAlgo.flop (b, ImageBuf("../oiiotool/image.tif")) write (b, "flop.tif") # flipflop b = ImageBuf() ImageBufAlgo.flipflop (b, ImageBuf("../oiiotool/image.tif")) write (b, "flipflop.tif") # transpose b = ImageBuf() ImageBufAlgo.transpose (b, ImageBuf("../oiiotool/image.tif")) write (b, "transpose.tif") # circular_shift b = ImageBuf() ImageBufAlgo.circular_shift (b, ImageBuf("../oiiotool/image.tif"), 100, 50) write (b, "cshift.tif") # clamp b = ImageBuf() ImageBufAlgo.resize (b, grid, roi=oiio.ROI(0,500,0,500)) ImageBufAlgo.clamp (b, b, (0.2,0.2,0.2,0.2), (100,100,0.5,1)) write (b, "grid-clamped.tif", oiio.UINT8) # add b = ImageBuf() ImageBufAlgo.add (b, gray128, 0.25) write (b, "cadd1.exr") b = ImageBuf() ImageBufAlgo.add (b, gray128, (0, 0.25, -0.25)) write (b, "cadd2.exr") b = ImageBuf() ImageBufAlgo.add (b, constimage(64,64,3,oiio.HALF,(.1,.2,.3)), constimage(64,64,3,oiio.HALF,(.1,.1,.1),20,20)) write (b, "add.exr") # sub b = ImageBuf() ImageBufAlgo.sub (b, constimage(64,64,3,oiio.HALF,(.1,.2,.3)), constimage(64,64,3,oiio.HALF,(.1,.1,.1),20,20)) write (b, "sub.exr") # mul b = ImageBuf() ImageBufAlgo.mul (b, gray128, 1.5) write (b, "cmul1.exr") b = ImageBuf() ImageBufAlgo.mul (b, gray128, (1.5,1,0.5)) write (b, "cmul2.exr") # FIXME -- image multiplication; it's not in testsuite/oiiotool either # b = ImageBuf() # ImageBufAlgo.mul (b, constimage(64,64,3,oiio.HALF,(.1,.2,.3)), # constimage(64,64,3,oiio.HALF,(.1,.1,.1),20,20)) # write (b, "mul.exr") # channel_sum b = ImageBuf() ImageBufAlgo.channel_sum (b, ImageBuf("../oiiotool/tahoe-small.tif"), (.2126,.7152,.0722)) write (b, "chsum.tif", oiio.UINT8) # premult/unpremult b = constimage(100,100,4,oiio.FLOAT,(.1,.1,.1,1)) ImageBufAlgo.fill (b, (.2,.2,.2,.5), oiio.ROI(50,80,50,80)) ImageBufAlgo.unpremult (b, b) write (b, "unpremult.tif") ImageBufAlgo.premult (b, b) write (b, "premult.tif") b = ImageBuf ("../oiiotool/tahoe-small.tif") ImageBufAlgo.rangecompress (b, b) write (b, "rangecompress.tif", oiio.UINT8) ImageBufAlgo.rangeexpand (b, b) write (b, "rangeexpand.tif", oiio.UINT8) # FIXME - colorconvert, ociolook need tests # computePixelStats compresults = oiio.CompareResults() ImageBufAlgo.compare (ImageBuf("flip.tif"), ImageBuf("flop.tif"), 1.0e-6, 1.0e-6, compresults) print "Comparison: of flip.tif and flop.tif" print " mean =", compresults.meanerror print " rms =", compresults.rms_error print " PSNR =", compresults.PSNR print " max =", compresults.maxerror print " max @", (compresults.maxx, compresults.maxy, compresults.maxz, compresults.maxc) print " warns", compresults.nwarn, "fails", compresults.nfail # compare_Yee, # isConstantColor, isConstantChannel b = ImageBuf (ImageSpec(256,256,3,oiio.UINT8)); ImageBufAlgo.fill (b, (1,0.5,0.5)) r = ImageBufAlgo.isConstantColor (b) print "isConstantColor on pink image is", r r = ImageBufAlgo.isConstantColor (checker) print "isConstantColor on checker is ", r b = ImageBuf("cmul1.exr") print "Is", b.name, "monochrome? ", ImageBufAlgo.isMonochrome(b) b = ImageBuf("cmul2.exr") print "Is", b.name, "monochrome? ", ImageBufAlgo.isMonochrome(b) # color_count, color_range_check # nonzero_region b = constimage (256,256,3,oiio.UINT8,(0,0,0)) ImageBufAlgo.fill (b, (0,0,0)) ImageBufAlgo.fill (b, (0,1,0), oiio.ROI(100,180,100,180)) print "Nonzero region is: ", ImageBufAlgo.nonzero_region(b) # resize b = ImageBuf() ImageBufAlgo.resize (b, grid, roi=oiio.ROI(0,256,0,256)) write (b, "resize.tif") # resample b = ImageBuf() ImageBufAlgo.resample (b, grid, roi=oiio.ROI(0,128,0,128)) write (b, "resample.tif") # make_kernel bsplinekernel = ImageBuf() ImageBufAlgo.make_kernel (bsplinekernel, "bspline", 15, 15) write (bsplinekernel, "bsplinekernel.exr") # convolve b = ImageBuf() ImageBufAlgo.convolve (b, ImageBuf("../oiiotool/tahoe-small.tif"), bsplinekernel) write (b, "bspline-blur.tif", oiio.UINT8) # unsharp_mask b = ImageBuf() ImageBufAlgo.unsharp_mask (b, ImageBuf("../oiiotool/tahoe-small.tif"), "gaussian", 3.0, 1.0, 0.0) write (b, "unsharp.tif", oiio.UINT8) # computePixelHashSHA1 print ("SHA-1 of bsplinekernel.exr is: " + ImageBufAlgo.computePixelHashSHA1(bsplinekernel)) # fft, ifft fft = ImageBuf() blue = ImageBuf() ImageBufAlgo.channels (blue, ImageBuf("../oiiotool/tahoe-small.tif"), (2,)) ImageBufAlgo.fft (fft, blue) write (fft, "fft.exr", oiio.HALF) inv = ImageBuf() ImageBufAlgo.ifft (inv, fft) b = ImageBuf() ImageBufAlgo.channels (b, inv, (0,0,0)) write (b, "ifft.exr", oiio.HALF) inv.clear() fft.clear() # fixNonFinite bad = ImageBuf ("../oiiotool-fixnan/bad.exr") b = ImageBuf() ImageBufAlgo.fixNonFinite (b, bad, oiio.NONFINITE_BOX3) write (b, "box3.exr") bad.clear() # fillholes_pushpull b = ImageBuf() ImageBufAlgo.fillholes_pushpull (b, ImageBuf("../oiiotool/ref/hole.tif")) write (b, "tahoe-filled.tif", oiio.UINT8) # over b = ImageBuf() ImageBufAlgo.over (b, ImageBuf("../oiiotool-composite/a.exr"), ImageBuf("../oiiotool-composite/b.exr")) write (b, "a_over_b.exr") # FIXME - no test for zover (not in oiio-composite either) # FIXME - no test for render_text (not in oiiotool, either) # histogram, histogram_draw, # make_texture ImageBufAlgo.make_texture (oiio.MakeTxTexture, ImageBuf("../oiiotool/tahoe-small.tif"), "tahoe-small.tx") # capture_image - no test print "Done." except Exception as detail: print "Unknown exception:", detail openimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/ref/0000755000175000017500000000000012271062644023067 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/ref/crop.tif0000644000175000017500000001536112271062644024544 0ustar mfvmfvII*èdN 022V.6>F(1Bî26=RSæ¼’»ƒJHH2ÈGraphicsMagick 1.3.6 2009-07-25 Q8 http://www.GraphicsMagick.org/g.tif2013:09:28 22:43:53AAGraphicsMagick 1.3.6 2009-07-25 Q8 http://www.GraphicsMagick.org/ xœíÑ¡ DÑc(–(C†bŠU–ྸSO4ù’JiîZDÔîýéF¦¨®­uïš÷ßs–s–s–s–s–;éµçxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô%ÜÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©ÅAEƒlÛ¶ Îúg]B9̓KÝh| .u£ñ1¸Ô«NÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô0ÏÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\êFãcp©¦µïáxœíѱ CQÊ%âPâPÞuZÙŠX!W]ñŠÀàáó3³õx¸äþæ~o)m]î=°ºXëú½º}'N=¸œzp9õàrêÁåԃ˩— [ÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô%ÜÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©ÅAEƒlÛ¶ Îúg]B9̓KÝh| .u£ñ1¸Ô«NÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô0ÏÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\êFãcp©¦µïáxœíѱ CQÊ%âPâPÞuZÙŠX!W]ñŠÀàáó3³õx¸äþæ~o)m]î=°ºXëú½º}'N=¸œzp9õàrêÁåԃ˩— [ÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô%ÜÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\ê€à?1ŠFÝÀh| .0ƒŒÖƒKÝh| .u=˜êxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô0ÏÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\êFãcp©¦µïáxœíѱ CQÊ%âPâPÞuZÙŠX!W]ñŠÀàáó3³õx¸äþæ~o)m]î=°ºXëú½º}'N=¸œzp9õàrêÁåԃ˩— [ÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô%ÜÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©ÅAEƒlÛ¶ Îúg]B9̓KÝh| .u£ñ1¸Ô«NÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô0ÏÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\êFãcp©¦µïáxœíѱ CQÊ%âPâPÞuZÙŠX!W]ñŠÀàáó3³õx¸äþæ~o)m]î=°ºXëú½º}'N=¸œzp9õàrêÁåԃ˩— [ÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô%ÜÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©ÅAEƒlÛ¶ Îúg]B9̓KÝh| .u£ñ1¸Ô«NÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô0ÏÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\ê€à?1ŠF}²ÒäxœíÑ¡ DÑc(–(C†bŠU–ྸSO4ù’JiîZDÔîýéF¦¨®­uïš÷ßs–s–s–s–s–;éµçxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô%ÜÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©ÅAEƒlÛ¶ Îúg]B9̓KÝh| .u£ñ1¸Ô«NÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô0ÏÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\êFãcp©¦µïáxœíѱ CQÊ%âPâPÞuZÙŠX!W]ñŠÀàáó3³õx¸äþæ~o)m]î=°ºXëú½º}'N=¸œzp9õàrêÁåԃ˩— [ÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô%ÜÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©ÅAEƒlÛ¶ Îúg]B9̓KÝh| .u£ñ1¸Ô«NÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô0ÏÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\êFãcp©¦µïáxœíѱ CQÊ%âPâPÞuZÙŠX!W]ñŠÀàáó3³õx¸äþæ~o)m]î=°ºXëú½º}'N=¸œzp9õàrêÁåԃ˩— [ÖÂxœóòòú¿ÕÔ”ð>}ša°ªcll„³ÿ××:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô%ÜÖÂxœí–±À ÄÌP^ åóPLᡜÐ$] ÷Å«¢P§‚7³ª²¢g ª×"žs¹ÃÝoÇ3ö€ònêDŽÁX°ì{1÷•Žõ¿Ÿ=Õ‹öî+¯ï}…üŽÉ ­^ðxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô-OÖÂxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\êFãcp©¢µïáxœíѱ CQÊ%âPâPÞuZÙŠX!W]ñŠÀàáó3³õx¸äþæ~O-m]Ï=°ºëú‹º}'N=¸œzp9õàrêÁåԃ˩—œÛÖÂxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô"\ÖÂxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•ºÑø\êFãcp©ÅAEƒlÛ¶ Îúg]B9̓KÝh| .u£ñ1¸Ô§ÎÖÂxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô-OÖÂxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\êFãcp©¢µïáxœíѱ CQÊ%âPâPÞuZÙŠX!W]ñŠÀàáó3³õx¸äþæ~O-m]Ï=°ºëú‹º}'N=¸œzp9õàrêÁåԃ˩—œÛÖÂxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸ÔÆÇàR7ƒKÝh| .u£ñ1¸Ô"\ÖÂxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•ºÑø\êFãcp©ÅAEƒlÛ¶ Îúg]B9̓KÝh| .u£ñ1¸Ô§ÎÖÂxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—:P|T4ÈÁ¶mÛàl Ð%”ƒÑü1¸Ô-OÖÂxœóòòúoºÕ”8í}ša°ªkdl„³ëÿ×:÷‘¢Îk4>•ºÑø\êFãcp©Á¥n4>—ºÑø\ê€à?1ŠF}¿2Òäd. 2þ26&(1BÎ2=RSƼr»ƒ*HH2ÈLZZZLWZZZLWZNZLWZZZLWZZZOLZZZLWZZZLWZcZLWZZZLWZZZO]·k·hÂh¿ g Á d ¾  r ¾  o É # r ¾ rÌoÉ#}É zÝ7ƒÚ4Žè4‹å?™GraphicsMagick 1.3.6 2009-07-25 Q8 http://www.GraphicsMagick.org/g.tif2013:09:28 22:43:53AAGraphicsMagick 1.3.6 2009-07-25 Q8 http://www.GraphicsMagick.org/ openimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/ref/out.tif0000644000175000017500000000242712271062644024407 0ustar mfvmfvII*–ê Úâ2ö=Sð¼ 2013:09:23 23:15:53 €?À À@x‰  hp2„=S~¼˜2013:09:23 23:15:53 openimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/ref/black.tif0000644000175000017500000000701112271062644024646 0ustar mfvmfvII*H @ðê ðÚâ26=S0¼J2013:09:27 22:50:00 € P8$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶]/˜LfS9¤Öm7œNgS¹äö}? PhT:%G¤RiTºe6O¨TjU:¥V­W¬VkUºåv½_°XlV;%–Íg´ZmV»e¶Ýo¸\nW;¥Öíw¼^oW»åöýÀ`pX<& ‡ÄbqX¼f7ÈdrY<¦W-—ÌfsY¼æw=ŸÐhtZ=&—M§ÔjuZ½f·]¯Ølv[=¦×m·Ünw[½æ÷}¿àpx\>'Çäry\¾g7Ïètz]>§W­×ìv{]¾çw½ßðx|^?'—Íçôz}^¿g·Ýïø|~_?§×í÷®@@€ P8$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶]/˜LfS9¤Öm7œNgS¹äö}? PhT:%G¤RiTºe6O¨TjU:¥V­W¬VkUºåv½_°XlV;%–Íg´ZmV»e¶Ýo¸\nW;¥Öíw¼^oW»åöýÀ`pX<& ‡ÄbqX¼f7ÈdrY<¦W-—ÌfsY¼æw=ŸÐhtZ=&—M§ÔjuZ½f·]¯Ølv[=¦×m·Ünw[½æ÷}¿àpx\>'Çäry\¾g7Ïètz]>§W­×ìv{]¾çw½ßðx|^?'—Íçôz}^¿g·Ýïø|~_?§×í÷®@@€ P8$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶]/˜LfS9¤Öm7œNgS¹äö}? PhT:%G¤RiTºe6O¨TjU:¥V­W¬VkUºåv½_°XlV;%–Íg´ZmV»e¶Ýo¸\nW;¥Öíw¼^oW»åöýÀ`pX<& ‡ÄbqX¼f7ÈdrY<¦W-—ÌfsY¼æw=ŸÐhtZ=&—M§ÔjuZ½f·]¯Ølv[=¦×m·Ünw[½æ÷}¿àpx\>'Çäry\¾g7Ïètz]>§W­×ìv{]¾çw½ßðx|^?'—Íçôz}^¿g·Ýïø|~_?§×í÷®@@€ P8$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶]/˜LfS9¤Öm7œNgS¹äö}? PhT:%G¤RiTºe6O¨TjU:¥V­W¬VkUºåv½_°XlV;%–Íg´ZmV»e¶Ýo¸\nW;¥Öíw¼^oW»åöýÀ`pX<& ‡ÄbqX¼f7ÈdrY<¦W-—ÌfsY¼æw=ŸÐhtZ=&—M§ÔjuZ½f·]¯Ølv[=¦×m·Ünw[½æ÷}¿àpx\>'Çäry\¾g7Ïètz]>§W­×ìv{]¾çw½ßðx|^?'—Íçôz}^¿g·Ýïø|~_?§×í÷®@@€ P8$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶]/˜LfS9¤Öm7œNgS¹äö}? PhT:%G¤RiTºe6O¨TjU:¥V­W¬VkUºåv½_°XlV;%–Íg´ZmV»e¶Ýo¸\nW;¥Öíw¼^oW»åöýÀ`pX<& ‡ÄbqX¼f7ÈdrY<¦W-—ÌfsY¼æw=ŸÐhtZ=&—M§ÔjuZ½f·]¯Ølv[=¦×m·Ünw[½æ÷}¿àpx\>'Çäry\¾g7Ïètz]>§W­×ìv{]¾çw½ßðx|^?'—Íçôz}^¿g·Ýïø|~_?§×í÷®@@€ P8$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶]/˜LfS9¤Öm7œNgS¹äö}? PhT:%G¤RiTºe6O¨TjU:¥V­W¬VkUºåv½_°XlV;%–Íg´ZmV»e¶Ýo¸\nW;¥Öíw¼^oW»åöýÀ`pX<& ‡ÄbqX¼f7ÈdrY<¦W-—ÌfsY¼æw=ŸÐhtZ=&—M§ÔjuZ½f·]¯Ølv[=¦×m·Ünw[½æ÷}¿àpx\>'Çäry\¾g7Ïètz]>§W­×ìv{]¾çw½ßðx|^?'—Íçôz}^¿g·Ýïø|~_?§×í÷®@@€ P8$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶]/˜LfS9¤Öm7œNgS¹äö}? PhT:%G¤RiTºe6O¨TjU:¥V­W¬VkUºåv½_°XlV;%–Íg´ZmV»e¶Ýo¸\nW;¥Öíw¼^oW»åöýÀ`pX<& ‡ÄbqX¼f7ÈdrY<¦W-—ÌfsY¼æw=ŸÐhtZ=&—M§ÔjuZ½f·]¯Ølv[=¦×m·Ünw[½æ÷}¿àpx\>'Çäry\¾g7Ïètz]>§W­×ìv{]¾çw½ßðx|^?'—Íçôz}^¿g·Ýïø|~_?§×í÷®@@€ P8$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶]/˜LfS9¤Öm7œNgS¹äö}? PhT:%G¤RiTºe6O¨TjU:¥V­W¬VkUºåv½_°XlV;%–Íg´ZmV»e¶Ýo¸\nW;¥Öíw¼^oW»åöýÀ`pX<& ‡ÄbqX¼f7ÈdrY<¦W-—ÌfsY¼æw=ŸÐhtZ=&—M§ÔjuZ½f·]‡€€@ð* P  0  " 2v =Sp ¼Š ÈÉãý1Ke  2013:09:27 22:50:00 openimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/ref/tahoe-small.tx0000644000175000017500000164610512271062644025667 0ustar mfvmfvII*>€r/ˆRZbj(1[þ2Z=B@C@D08E0xSø¼¬‚z‚ n‚ «ªª?»ƒ=¸HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB xœ…ZÝdÇU¯SU÷ö×LÏάw=Îz½vìõš‹HV„ÀRx@B AÿHHH<ð€! Y‹xBü ¼óÂ"VäÅNlÇ^¯×^Ç»ëïéîéî{«êpΩ{{Äd½™í¾]uê|ü~¿sªk3DPAiTHåÿù‡SÀ)¥Uú¡gùÕø{ü§< Àѯñ…òÀÆÈÃ(tï¿£•Ö!8Ä Ò²Ó3ýÕè-~¼|´Šö§EeYþå}6é½Ò½Ý=Ñ(Ñ ù³d$$¿t‹È¡5½Å΢÷À¶ ½bßåM1d›£“@ÖäŬ¡òàWµlOó„6N”AYžpuo¯ò(Ä-ÓÖ,”ÈÆ h[‡`•Ù¦s`{¢ÂZ>%ï²mM ƒbðì0|dô¶…à1„ν=³YÅÕ};sP6QøÿÅ%=ǩ ˜3“Ÿ«GÏÁäk~ñ®h¼Pj©Ðå“¥BÊÜ΢ !;ŒKEӳ籗ê}/BNÕKΚÐ÷|ù}Ãþ˜º˜Ö碉öóZŒ¾ª¦¿¡B¥ÜZ­>Âõ]3yTª8ÍÉÉÔ”é íŽ˜ÝÒÁ ž-ýWì‰&•JYËX=×üft6Ξ¢ÂAGHÁŒá¥j„-5ºav_WfªÚ£pü}lîk2p8mW*¬€³TKRÑB^âhÌà«’T ô39EL‰œrÉ‘Å:¶r¥` õb£4bò#;ª¬–~eUµ[ï~]Õ/x[aµÎ¨Å/qù‰RsPdÞRÐ@'d€]mF¯b8SdˆùVÀ›ó$îQ4€H쩎œ¤M¿:6}^ þ‰TêÔâ}ú§A=³‡zJ˜Ã)zmªË—ÍÉ•;æízù §u} Ëš}.˜ ! ©ÚÓÄ ª÷Jª£=$?6ŠþpÊA/z]‹A)I7Íþö#U(l£¾¬ÔP!áÏ\jzšè`šZîQO¬N²q¤øh9½#øC~$Õ&mT×ãý¶™!¹*â '!ÛßóqÊŠT2“ `#˺ôÊ5ÁU©Uuµzú”ùŠqwšƒï¡;ç¥-©JØø :˰ÄTkÛË䈃Ø#¸¸9Õ‰Ýyüb©kßOù›³ÁõŠÛ%:PŽŽlÐ\²W~KÁ>^¼.> àRv°#U®ò‘ÜâgãZrjÔÚä=eF+²—BNi¬àÒ–ìÒJ> kâš-Y¼W,â-çˆ5‹ª$G'9Jv¥ü¯• (?W¸–Ý*â2ÚB#»%.ñ;Á‘ÿ7UBÙ7G ³pIÈÊlã(â±°LÜ¢‚4˜‘6:´K·˜qÁ²^a伥‰~(W³jŠ~&­Dn!ú¢"¯£ß0b&Š”*°C 5”}+e§¼U}¸H&} _âÖäUEa"X­TzØ|$Ÿt¢Jö Æ(³5¬ ¤¾…¸…öù1œ6ƒœ²!¯9…ÂæN¢1¡F–|‚Ÿn!¹¤ûTQŒ S¤Xà2Ñ /â rš‰£4S°Þ{ Ã9¥€à!s.¹ÐG<$#%ƒ8(d=G‹².íÞ0ÉÕY*vúYhØKiñÌÖ=vΗX¯å€±î4F|‹õÉHJ† ä' aöÑ}ŠÍç2¦)®b”‹ö÷€ Ðr”Jl9 tAoYYɼDâù•k%Â$š ∢†Þ%l=æÏ2ª»+C.­¨%j|bRVkl‘ST2N-ÒZ§§>!§ÕºÊN~B=}Åð¨ÿ "AÒÔ˜ÄaŠœ¢*¢:…—öB⦑®·È¶ÐœANË¢‰ó¿t,–HKYT5„ÒT…” ’àÊu\ð'Áµêð'çB'ƒt/ÓòÑø§'ö¤ÜbÇ‘i„[±Ð]c{ù¢tLYçòa+${bçÇ€é9Z"Š5É€ˆÃ‚ÿ1„µKiš4¦\Ŭµtïr:UìéN]¹8ɳ$3“˜¾nnI(ÓtˆnfóZ‘”©05kŒÄ˜Ì7YiežˆÖb¤žÌ=ƒ,ÊÊÎOg_H¨¤É»zIT(¨zÖ³–¤b$æb‡±D±‚ºŽH?~$ ¥”D5õ/ˆMÔ3&‡§º¨ŠÎÝI’õ­…'ð³P­¼ ¥ÝåcñC×*ç?ï_“îg‰Å½pégƒlOYauµEGóí0~ƶ¨€aP9²›£†È’ÅÎrPÝ!Aò¤¤dw¾BÍå ¥Ž|bxªw²ÐJ3tȤDPL<½ëI‚Qác{¦¤ û’c‹©±"68t3ùKzDd ‰ñžÐ âzÂ#v¸–ë¨Ø)ù×|(v,f¨[˜‰¿‚6[0ØãÙEs ÔÂlê´H¶…t¤÷q#yú& Ã,¤r!$)Ø…,­FùÖØm mðsQé¹àä#=¹Î¼oì4¤½œP^¿ W=$s’8)p§1Z´¨®‘‡5èÄ\„нúް;Ãés"&ªâš<ÎrI˜eÙœC©"ÒIå5/o¹ºÜtév7Ž–e€¬;ªÎEJ ÎÕDxžgk€©ê±2¦YQŸëˆ$ã=ä¡*-)›ä M”—¬û²2ì ‡Üš©ÔaF©š°…’Výšó(ñ²Îا0!SIïb0SÓÿ‚±døv ](Kt>£ˆ†ùõŒ‚Y‚åŒí#zY­rº$Ù³ˆÿÈ80%Õæ RDJÛÇ¢©F„ xµ{ƨÁJl˜ÁRÒ S8²*(gIE“yó ÒÚD/ˆªÅ†h‘/»gðÙlç1·}üxÈL$W!‹Ãñô±Rò$7i†™€qcºº D½¬Þ8*»ŒHÍI 0Î46ENoÒÜv[cŒ¦¨PLÁ6MZšñÓ²‘:|Þ00§z^VmÒV‰#ïhì0ø–?NÔD'òô ƒ|¿Ø3!bì ex®¸UOµ2r‘$HÌ¥ØK]–mR㌷C]]R¸Rþ<ŽLyš‘…¹ñ,¼™BÿÄoyXTä™ÈDD(gLrBçIvHyÛŸ'ÿ ¸+øÒãò?á§žØáUßa{ÄöcnHq÷×ÉP¯*»‰‚L°:KhÌoË"`󃢲z7 9¶…Yr€¡£¾ Ñ›ñP××u5åß¡_@B<•š²$D1j¤ƒÅÎPŽÒµ9‰¦íµÑœ’âXL…ÚÏÿС¿£¥ ï|]¿ÇùsŽ‘g^Ó6„æøsàf‡\¤II—˜´óSžn`Ö‹e7=óÄråB´\³ftiu?¯¢$óÅ~w@ïå´Ò()–e‚ÓjÿÏÃòmhî*7×,ø‰‰lð+ô-äëŸ^Ž1m£3èí§¥¬tkÁ«I"Òs$wU¼ êôXÖõ2«¤ùÆOÏj•h>:¸ñ78û¡›½£I|rqU¼(OÕ|Z#'©ê6èÛŸ‘;§Ž@­SËX~ͽ|´–ÿ 2yì2{¤'è)’{.‰·ü—ŒAÈS»RÛ¦=û †9ÅÈT‘v™'åôX\”×Ì<àQÊ^“nUÉÀàBÔ{”Ò>\§*HcmÕ“|%aS±©²UB®=Ã-óîáú`iÌB›¥r_/Ñ7¢µ²‡’gB·lï½^ò Ô<*1Ïx¤áUìï´°™ƒ^ýöôJ!¯È´Ùur™E”` ~òœ®ŸÿkžÿûÇ+<ô«“fqÆL„>ƒu\á˜F7:Í;M㉤$TE«Js´æšªQÕqKåÂ/:Ïa"60ŠØz@­x»^Æ~Y¸,r\ož‰=zÈ©`_ü;…gd¼nGp²¾8 í*ò =o ­\¹vÉQ†ÔÚç¶³ŸD;q°÷Š,ÀHè$ZõXW»èg2Xöi¬é=_€Þº´·8= ŽN­ƒô¼‰³Eaw@öæí0{ÖŸ ÈOî$´§íúÝ: ‰’2Mê8»Ñwnåe& uœ»–ûÔL©VE…)£×œ{åÖ )˜ÁyÔ›–‚‹µo÷CF®˜¹U¾ù]Óøƒ(÷Àêýïš4²P2@fkB¾ï³±Íç1ìFª|w /9ÝOv~ßfQß-ídNép´8ac†œ Yç*Fóòw¬wxôý°ø¹ ¯B0]Ž˜P7øÎÅɼÐð>œœ!IŽb8@f’nè¨ûæ >È—¾ñŒ&ŸÈ—O§â×’çxCdëßÿêN`Æ9Ñ+ «#ÿø{ªùp8Á‡R³^ –ŒS­¨ú@:̪ ¢ÀP½•eTkÆÚNéyt<ÐÀ$Š ŽÓãÆY½„TCõ¶ eŸa/äøaQ&Ñ[‘rì¿T³÷Ãü}$ý`FÊLëáUt§nýHØ3Æ”ç`Ù‰˜5pªöÇFØŸè¯ÚæK@úã0¬bG“( ²|…Ý…8ª@ËtLA9Ê”> o]¦ÖÊ^ÿ JÕÞÒ&û »1bõòwÔr–gjpÆÏBsâO~Œ«ûJ5fx™ ¨yü©\bïco^G]íÙá3Íò”ß©§z0 ËÏÁŸ(·HWxÊJ‚µrõÖͳ0ç’¡šï´Î»Õ †655†Î­…¸5¦‹I5ru+vâÖg |ýÊŠÙJñÉÞâ#ãù‹‡«ùc¾í ¤ˆP>¤4°œ2¥'ËÁîPû#W?c]OÑ/餦ûå#ETmžçWÆ2©Å˾®÷Á(,¹Ÿªª1ƒo³H ­eÚ,÷[;WG“ƒG¡wÌ„*vè›…µUõòí´\¸ '`û…Ÿý/>ÅfN2Àl¿€í¡Ÿ}¸| •'Õ¦_sDÍŽ™¾Œ8Tr—šSæ¡=‡Ô<.UXË„N=:$Ð*¢@0Ðñ5–@”Lòy É· sëí½ý›'¿tíŠ>á=“¸6jZí­Û2!׊òdþ..>T~FǤÒ ž6Ãm¿ú›3ó•ì ÝWþÈ@Ó®i)3Ø}Ù­g~y íÃB…ûÔLêÉu*áõüž&q"¦h¹u Á ;ðÕg”"éFŒÉ]Ë`³Ä[ è]"tÆÏ‡¨ÕxgzùÚáýļÝf9³¿v[ g¢;ð‡ÿ«{]@«ì3ÞW̓°>V¦6“ç‘^T­ÝþMGÊ4Ç£[±èÊÚ%Å”$€oϘ?ÍÔW@‡Õg¤yصdA=rä8’ä.ùbßaEþÅ€eÄD=”±LüÛŠ”‰±”]d©Þ}æÖpû¹å‹Esqjo~WÃPºŠµÆGîàVy3¼ÖÀ.ˆ#W#lÝ€¯ûæÂ=þo°—-=¾üÔ7+J'­ZJ°Zz½š\ë3OÈ3ºÎWó«;ª}̈2.&yJ ®5ñ—¾>ª>A£N–ý@ ó¤K# BfÆØz<½våæïnßø½Ï>þÙñÇÿUßú{élfwÜñ;ftEU—øÜƒ§t½ì$ôÔÅwò3Õ|¦Á©êŠݰƒ=Nܱ†É-=Oìåç„öPÁÌà±¢*KkIZÙ(8¢ý‰£ä¶B%BQý!'/4_…ü¼´EU5n]¾òâëW¿ñ§ŸÜ½{ðá[ÕÍÛ ãÌdLݶ?ÿiXÜjl§¿ƒkÒQR˜WÀz˜~™ùÇoûÅç0zVí¼ŠMÀÕÃz²¯ÆO{ú8Ù3Ï/Þ<7àB33Š`’|P>8¾‰ÆýaB׈Øc5{;}Ñ…oñ˜kXVP`ªáëßþ+ûâï¿ù¯ÿR½òO ­å¬×ðœ§ëfõ0NB˜­ UtÃqñp ¯ÎîëzÛw\sÌ4çŽÔês3JpmFmsQÁ\”Bˆ`èã<-ëÌ·zZ&ó”^AÁh1v0!“œã¡:-«¼O Ä·u=þ?ûçŸ~phoý#è8ö62°¼±yKGM¥ù;K¤ÇøÒƒòjůS»®è |›ãNï0ë5÷•;%,0æÈØb¬å•YdÈ}„_ç®á‰ÉXHµÚ¯'{ž#Ê^Âú%;¹áÏ~DYÁŒ6qPFˆ1Þð“e»§b¬Eí9Ÿ K2^³–idl[`[DZj@…Î"8”ÛËܣÃæ¡U­³£—<Œ ÚRÍC7¿'±ÊW‚½;χuµoê¡w'Tڣݗ&Ïÿñ|¶tÇ?ñGo)7]7³Å¢‚‘AÕ¯üƒŒ¾×¢— ·{XÉ÷œPÏ—©oâjÒC mFôÍ_6óDdhö0¹’ái$.ïùÃ7usø iž»Nz{ç[j8õë/¨¦Ôú*Sÿ.gÈò>ŠÖHC¾²d¥Á_1‚ÁU·&õ»Ò$ 9»¬\3c"—™›ßE?¯_¹-ç¶Yèôí Õ€ºÀ‹OpÂꪙýzôLX“2Po˜ú)¾èts¨‡íúˆ˜Î_Ï?äiŒÒ!qøj5»ÓwpõXG[…hwžÆþñ2©Ca!JÉ2´ã=·<¡ƒšÁ>nêé×Üùv êQµxü^}ë [ûENr Ê«ÔêÌ/>²pØžþBñÕ$Q‡¥%Hªsò÷†FWQ[áÉ­æìóëÖ³0üŠ›? ó!0;›ÑsúÒ‹~ö6.îÈ’†N—lï4c€qËìZùÞŸ&ê´ÕÈ7sÖAÃìÓˆõ¾?þQ˜ý¼Ú}ž0™íçá^ºá½Z»eóàßq}OÊ›=ÞZ­WÛvï›zë9¢°¸kÂÊ7”œµ¼ˆvŠvD'#å0m9wÿâáÛª=[cóåÒP5*‡<÷JawˆÇCsA½@5œ‚©ˆFƒ[Õã½ÖU? ƒëD"Ô­„å/)Ãë›o(²nÄj™ˆsLh`ö~sø&é ÒÒ2FËß#3ê+júMuù[ʫӷtKRY3LÁ€ü£v¿¡¶®ØæÂÿ.îÉ4€¸çÕŽo©|D‚9„ÏÊ§Š‚ÜÛ}Í3Ž–˜ËŽöêÁÖz~Ð6§,ï,…pcR=õÛöÒÍöè‡þì½ÿ¦ÝÁ3xœ]ZË’\Çq­¬ªûèžîy˜!^À‡HQA „è°á‡^aGØá…VÖÂ-¼÷ù+¼ÔÂo¤°Cvˆ’%B$$f¦ûÞªtž“u°ƒytß[7+ëäÉ“Y%yD$µoüi/ÿÍ> ¢j ø£Æ(1jÑuHÇ!†ºÊ[ú”’ÚÛy ë{:‹ÌϤ¼,:„ÕÛrò§’¢Œ¡¨$•b xÐ>„$ŒGIÈö]C íe—E|ÙR£d7Iq³½a?º˜:Å­Qü|`ÐUŸ…Í ¿5ûc¥ǃ“ûÓîËýÅ3áû°*ªQç9”Yb/ãùÖwkÿ-5T»©³çaÈ8ж–*ÿ‹[k?lj‘†¸åv½¹#âýZù3ª=Ýæ¥¼Orʽj›=ý¬0_Ìç‹ÔgqRvE^Ýzùå§æF~Í·öX ¹†¡¦£åèÏâæ¶­œÆ.˜“ª];ŠTigÇ‘g)Êd+"°‰l*ù„ÆÃé°H¹1ǘ¬…ÙÁg"ÍÛâR]œÓì—˜ÔçÚVN†)Æ.§¡TƒÈÒa=x”ŽßÖnT[os}“µ-•a ÆG Çñ'|‹ƒêNB ×Ï$®adñž_OÀp=U »†¬ 6Ì¿z-öÛuæjŸ æ˜"Áo£UDMÌWæØçáLòù|ü½Ð­‚Á)­%Èhw…²·ïm=ÌUB!@“Aá×Áœ”,v-æ%šcF&þÕs1^suÃüÄÁ1*XaD«Ç»9Çž9s¾4Þ´€®.Cw–6ïéñû?@5’l–f›úÚùâFĬ-Ç€O´8oð³»ÚðIÜ?µ˜̆„˜lɪHCÕâlYì׆šÅ~Nq¬|q vM…ÛÌÈ<Æî¤¦öO‡ñTÍKi›ž\Cδ9‹NtÒlÓàš±V†27òÚß"…ˆ[#” ‹wÌ”^ JâáÕto{ñEæ¤cvDcj€'/1”:G"ÔeºXÖWS Z°:¯yžœFNÀèöp³<ÒéXƳП¤Íy6æ 2„ᆆ-e1"W¢3Ì«.…'m3•œY'Qmà…G«åÖâà‘Õã²ÌÀO¸@ˆ½ë€_"L’+o_¬ot@·¨X!c†t”×âx¿H?M/Ò¸Ö‹Ïåõ[²y·†–(Eä›Pàí0u‹M!á4°Ò~3Õ¨Àç#VÅÉÙ,ÏÅ-Â0&<ì°–´¿rvÒ˜˜Ë£ínMt`•¡?|¨:K´,Sëî"öçùæ_ÌãÛB’WsZ\MrûD ::ÆëeÐ|íAermTÃ(§+Ü¥dmò ê× 1¯-õÛ ¤é-xV3.õF2uÞs]ì®.Ž·ãùKÿ"ÁÌ„²28Õòpâ¶E_êhYDg_dÄEC-]ùd\›q{#{Ú¯•N¿¤×9óÿAËÃ"úsÔáäá©>B’¼I÷ãá‡%Ý£)¥žö''å`í¡§¡öb¿Ñ¾6ûmÐrF ªÇɆ6¤4•S¶X ^±EÚƒB[¼ØèÉß§v²M ÆÛ4ž …mß 7¾¨»¨Ó ‡IŒçÉ$®~ÄäÄD…cQOkÕ N‡&‡Ì7©1$àðØS»~Ìé3h6Þ¥Áuq~䢋« Nž©F‰Oiè6÷ËËl²“Õ[éè#]Ý€.ûM‹¢53’»£:±‡ÙÉZé¸ez€Hgº ’u!F,÷b¡fS&ê«\3 ŸjS†¯ÙŸüi¹;¬ó…yÛù•w)ÕÅn[CW§)vÇyû^Ø>š»û÷X'2¤´Ñ"Ö‚ xKX †9­0°áñU\á.†Z6^˜\’‘NÝ© úFN!Vm¥Š'Ó áU,à‰Nû׊.6±uûª]X?Œ·þN»w Äâ A´2Oá€Ï« 4Ÿ á! }§ÊbÞ‰$sÂL†1:à5t¡Ý¸oYOY2Â9u£ƒ˜ë(`9-µê+Ö_òÊsRcièŸî2§Uȧñè‘n¿SäÐ4U†šeÁaê $ÔË…‚$¼–3mPãÿ®ÂŸ=3W{öÄX6#⢚¦„âH)¥<‚…wELAõ: T)ÛGsñAb©e¢}C4‘yòY:þ8lîk6™È1>¹t¾åPÝÂ8 "h0óˆ6‚öŸÑœØµôJÏ0Lüò •Ìýê´Ì—^•hp„ª£Úå™ç_«YçgK› b¾¢¢DrÏëê½’ÞKX¶ j WM!_ð ý*Ó®O„„}¤ QdÍT÷Y]2ÙŸãHÿ‹k ämö×nuŒ%Æïƒw±•0Ld,€r–?¨IU¡éÌ(X©x÷gûzn -lý™;Ä‘A79L-+‘¾Œmþ_ìoŒgŸ²Æô*’¹Œr¥^'#&AgåÞ%=…DÇ› ´¦+Ü«%ºæwÜ`.v»é±W'{Ú¦ßOGß™/>µ¼ÞªéWê¢ÆQª' ò¶T ‰¯ó¬ÈuÁeOuî4É=áS‹ß6¯96¶sˆ œ¢Ï…jLÖ(1SXàÛÅȤš(×™­ØÀÝ*ÆÁ8 ÄQ ׆ƒû5­jÚjO¶ßtÍ£êH¨B1ƒj‹)ƒÀ H€¦eÁⲬ&>ƒ£¸¾ˆÍma›^A޳ h)†"mád'±k6€ÈGxÖêÝ•Hþ)!z\ñ‚ Kk­`ùòQ±œ»ý@6k)qu3ô–\Öˆ6G¼1 "µ[üVŒ»hN$…•I¦W³·¿[ÊÛ=EŠ@¢W³?I³_Â"I9Tmí Zëd™ˆÙJØ œcœ÷•µa@<s~Xò[šÏóx\§gez΢œ6^­Ó~hT‡·×в…Ë I^]”*¤þŒŒ¼„ö«ŽZ™^Éáš|—_‚Ç–4jöCtY‰€ ÷õgYÆûéü¯Õø§LIÔsHÅ€è„ûÂ?Òz;N ÎôȵÊËi„ͳ§€†Ä//fá v•Õb¿.Âøzšªä½Õ›$ÒäctáX9›K¸5—x’Ï~Æ[»OaË=Üùa¬~´0¼l (¦ðڋکîÈÙzR@¶‡ 𕱄MÄnÄÂ9ùÇV‡ÛL-oV”®Žy¡Ú¼†ôO5?.Bd‹£Â~Î Ir¼ºõ=#¥ËÏi%pç'ux aÒ%‚ݹ®©w¶4£Èmžï cL .Îq-˜«[Km ömµ§Ñê÷ëÒÊ5¦ …VñüÉì=XýÀ¥‰g:8Ò×b•ËÝ|óqïU3^ìëk/ ¼Hç3ªFv«Óû5ϯè™m°-ÏÚ,ˆ~ÚzWàúkû—‚E)š"EPme QKzû ‚¡ äÛÀ)1wšÖšÎºÓ¿¬ÃcQé6&ÑLØ““™S0\eÏA)~"…»IL=velô|ZÚÏâOD¢©Hʨ}ȶ¦^ˆ1öÿOØìS‚T(K_…¯ÚGˆ²$‚Øå~k¼Qê>æ<Þ›ôæîBò͆õ-\(t nfæ%²GîkMïî±*ô?hÓ(hæ·{QG¬˜¬gñRÈÐÀüåÒ{A :¿T ^½·Þƒ¥þ‚¢;v©ñ8›í<[Ù(Ãó4äãÓÉ£9ìlyÍ¡Ò:yæ@oÝØˆ¬¿Zâ% ÐŽ¼0OÀí¤¦^ú܉òè*ÆQ“ù‡}½¼”!"®U®›A¡ÕþKCµ’ɘ2 JFP#ƒI܆xZã±lÞ‰'ß y×u6þNê1á=ƒЖ·[›ti-ñöô®MÄš°m}i¯7˜—ɘO ¸^¹%Ñ-«çyAcòö­'¼JmËbßFÉøÖGcÎ9ÃcùXå$¯ï—|Tûó*§ÒæÙ_fˆäE<¸|MHºæ[Ϭ¶€JöóÙ~gñ;°¸J:wRŠè¿¹³Ùúh®3†´OTZxDÔE]¯{~ËÃуØßÚOS›Ú¿Æw$Ÿ¢ldÎÇÕ0Þ+Žà¦²Ùü¶°‡ç2‚üµAúˆÎKàLžÉ‡`¿,E¢÷O^ÉTŸÑÒ±ÂG‰}4×V|"nbÖÇÓln:J7ÿJ>4"½`½`>ñ²kxo¬œ‹xrq±ƒíž„|ho6“Preà7™4]\KØÃ›@hK}ØZµ‹õ¾4¸²øÌü.×1u5”t?ýMïZIއPK–n¦§ 3>´Í+Á7Âdiæ32iY  "2숄'LÓh"Ð~T7Ùì§„`× ýUóD^5™ø!˜×‚×ì6Zj¨Z7?žòÛÚß ã‰"Õ& n8¡ ‚`ŠÉ½·t!¨Ò£Ç&¾dÿDŸÿ>­ïéÁí‚ÖÚå’"³#¥íPÀWN 'c;ÕD=‹Ö³Š”y3T–ÚšÒ¬¬[t¿fÿ+Âj ݶ¯T—$œ¼9Æ:È”i -yò8ÝúI9þ¡qwœÿ0=ù·þä;zpnÚ4A¥Ï¯HEÑz%NBpiœ+c.ÐÊ+'i™µ<7~­1“á¿wok+!¡:/qàT K¸bbÉœjq’þ†Æ_Äúuì¶ñôÏçõ÷«¥àézñÇ|ôžÛ§TV¬Ð‹·>˜ ÆáZé±çSœÊÌ¿;:´åÄ–5aŒ8CቈHKD¨ïŸŽ6Rt dl44F½Ö¥ØÜW­¨_·i¼òX.?M9Éx{¬f¿'ý*BË­CXÑ9ŸÄThp‰ÞÞAÿÊCCœÊXÎkl­aîqzb¥ÅoMÑëýf?ª9ÖC½4ŽK1(×mCÆ/Û(ƒ(TÒÆÒ“Ê IëØÅ²ž6âÉãYí‰;HWY!Aw¹CðÂ\\üg² ÜÒeç9-Ù&Ã8+Ú¸_iJ˜Š#7.™Žʾ8;qöÀ¾Õ5ìòù9çÝ0ËQ6B˜ËäutH§2ÜÑxj0ô¡êÎÂpjÏ}7}ý$n„î&sFfíÂRÏzÇ›saS¢¸(â6¤Ç/PY´œEýÀýýà"ÖÏX®A*OÄŒy£F¯MÑY€€ÑMv[÷u•£¼ýFo [Íšzµ@Ö—)Ú½¹¦9~WÈrÙì±L­lAuåž’!4•2% å¹8³~¡^Rç¢&!¼rfZÉó¡!x³BJ;pw×À7™²ä«u{n/é(mß7Î*eo‚3äSÔ4Ùh£“´R‹î<ª_mÖk.åné¤åÀþ ö鼋âÍÌqé`(÷‘3wª—–]ëÀÖº;1Íšê;q¸›úcÕIË…ØàdKÁUŠ­/ ¨Û"å×:ܰ2†Õ½šÎ°vó¥ô›0ÜÕî(èKs7`–A^h½¥'·x!‰…Ž.L–÷É}âÝÎëm>"°ºhWv´ðªl–ÎÜP;ÅÕÇö3†‹2=Yá8Aµ‰\ ² ð‹ÈÖ2¤|êó¹öéèQ:±j}ËM®šþ‘½UTVMH5Bj`YŠ=,D(4¿Y‹…´ˆÞyNQóFYS^ùQ ô±åŠkœEZ ðö =¶¾zW6…tø€U ÓWR.bØC1Zì[xvëRÇX¾^:Ì„b¨ˆýÞß‘õ½ÐŸ › 1¿C{6n„¹mÙ·|é½µÊN8v´mœ‘šm¶2Y|ÛË7Ö£.ÝWJLKÊn\dëeE뽟Un„ëîsÙý^ʳˆÁ{M*k³6E6xâ* o„ñ¬êV§§a÷9}¤›7!¥îRاÎ4Oà1—«WLp¬ÞƤ æÒ}«ð,^°.<[…ý뉻ÕkÚïW´ÍžGò~Kß$P¥ýiÌ·ÿ!­o×ùªî¿ˆåYªÏÊÕÝúdf¿:ƒÐÊÞ’WwÿçÈÝøª±qÿ…îžFKRÝfÞ=×ù¹Ö+ìG÷½úLw_XbMÛwdûHWwCÎáòwáò“”úyoRù0½k!<öúÑ)å¡ô01ð¥Ù¿gW¡ã‰€JÜ圮B8éeË^À’Hy`‰|¥slQhòáþÏe|£ÚPMõ«T_èÕó{ªWŸá€Sw•—zõÇw–¼ää±lÆœëó_׋?¤ÕmíNBGû}òà¥_Ô½V$ïÿ‹Uô~žMW wÔ*—¨îa ‡£ ϸ}³_šU“I‰Y¸°×m%€!5¥áîÏÓá;Õjp›Îþi /À0»çuºêVGõâ³:ïºÍ7ªÉƒrÙ­Êå'ešd86S+ú½ô7C>“õmî°·69Å$÷U¨f@ûÖØÄˆžG‚,s]5!#R–ËŒ¦–BœilrÎf‡’é÷ì»ïY*/~+åeììYЫÅê¥ý‹ßÌLªåõyzQËׯB&S*»ç¿³Í7åࡠ甾3{i3ÕpDÏ}ºR‚˜„Ø–4ðIf"0P±U%;-´å˜¸ý´³“Ù©­G*¤ýñJÛó´Z•ÿ%ó×q8Ôd¸ª—OroÅÇ“²¿è¶ß¨û¯ÄòBÜOr¿[­ôꙑj>þ°vçÅ*Pó¼±Ç¼Ãftˆ¬™8ÙkXñTX@c¼#ÛÔ)zšºCѽß-Âéa!íVF ü¥cw gõî?ÏS‘ÕY-aÿY2Ì(¢uŒ–/B½2b û²ûŸ49o§Îm4Ú7ÙV¡è,aíÔòäYä$Öé8µ4Lw™£71 øÓÏ/~ºL°µ÷“¡õ¬ÜÎÚÚ§.$7õF·}?mß+«÷ëpªðå¯êÿ‘?ÐíûUƒA%”2Õ—ŸZa/~¯ÇߎéÈ>ÂÁ’ñˆ†À3–† lZe‚Å;ÚÔVa]©é´ ^Ö'”=”s…§€l"seqa6ïC;<ãƶqY?²ãïQ€ŸÁ+–IãárþÓÚÉů—¿ÈãJ7ßžåNˆkžûCÿ#\=‹WOjÆñ¼?©ÅTbV*P<[8±é‘½¹eY]:šURó¥÷ÀÍìŽÛÐ<lZz¯¬/b ×-¸†vmS µ•ç~¥ ó”⨋‡¥;?Å =ý×pùÛ8œ…ÃÇuõ0t‡&H¨ZGC¸DnéCšÀë,Ý ›0~¤ÝxêleÛî³^²dŕƨÈm«‹ä “°·(¥kJú“5c±<Û?s¼ÑU(;m5¯ÎtþÊ®Ó>èÎþ¤^ýFŸÿ§Îs:ün¼ýãb dþ5Ñò'3ò>Z42‚“ S¼¹b'Óžc1óÒD }¤Êuoþ,ܼ@ý²s!ªL6`Hüvà˜¼öÛ×c·¿„¤ óÂ0m>’8—ÝgafâëMáŸë®”«—ÝÉGrçGµ[¥ý³¸ûÒî©ëA×Tb£ “ÜÑx²\"Ïⵯ0Eà…ê®{öïÕ\´yP–›løÉ:Càà[TD3ØÀOŠjË%~–Ûå‹È`?¸u¨Òáßj>Ñð2N¿—ÿm…€)„áøQ)[ïÊ­ï¢Xß=Õ§¿”a#7ß.ºA}jÒÎV!Α½`ó$‚Ô¼j „ Ö “é‹òüùä_ÒñÝÿßé¡Ê‚‡uwŠ8Šˆ_åæ›Žþì©M¾Åv½QIJ¨Ãºâí VÂ…ÿÃ2‰hxœUZ‹Š,Ç‘|tMÏØÖŸ[º–%ÙW²ÿÑ,2ÂÆ,Â,,BsͲ,ûO ÒêªÌ=ÈžñØ\ÍtWeEÆãĉ“µýòO³Dôs”ÒbFŒ3J ýð«ZbýÔ¸”q¥âª(¼ªŒ¥Ï8¢žQÛ<'V(øiµŒs‹Øg­sž\œ ލUK=Äà"cæ'¥Ò†Yn5® ŽgéÜ^JõçxÆÄeó.¿úS´>i|¥ñÁ§ë®“–àX¶è›y˜ÂßµfáÓ#Ÿã,æÝb¶Ü{ñí—˜7zvU9&áz܈bE.’õß²zp‹¥ç#d[z¯^x í£t~4ŽË›?Ó´ó†íÛEüS Òà¡_îàS¸»²¢Ãm6Ù<†ö®eCO¤Ász—ÜË …ˆÿÓèÞf‡ÃnÄÇøÿl¼ŒëàÜÂë•ð°íˆþ˜5üùåÃ󃊽üÊ!¼×ÃÛH§A(‰"ÏÃþ"OÂ[íÜÐ^Úæ¥ðÍÐzE‹Ò°¶±s1Ÿ‘Šý±™\þ©cÜiÅŸ¼€¶K¥ÝAÿ·pÖm¿þR•C2:S9/'Óùé‘.eı ò¦\¢]è:Æ}üéô£Ö-Ρe+\@³±þÐNÛ† fLGå=·Ól˜Y;òŸKsòá‘uUÖEŽÏ~Óö·¾Rq„¢S_Ù9~Ù›9Wáþ(7äKX$äáÓ¹.Ó›.ûQeFØ÷2š½ðYÿAY–SȯFɽûË*ÿç6‹ÂGÇGUmÎf@Cþÿe:ÙÆ|àƒs)Ù@èéøOo´(“6D3rÈŸzP3°ð1ÁNÁ„—‘ò?ª&Ô’ÔãŠ;/“œáÆúÈ åáP“î.³‹gã;Z¿üúK÷;|5©Ë©„,w uaŽPÏE ±ÃÌ ÖMp§¾Â\-«  ¿jÕ¿e"1ÝN¹´”úRËô˜¬Joûa¨ëÚÓ m„ÑÏmÿGµÏ Sè_~.^„6á¾¶*1Ö~ã5ã¨boŠ{L2£x5c3¸–Ï­=ù€w&: 9#³Ïbè˜{Îó4 Áxó7µÚº¶Ï¢@…Ú{ÊüDZ¦–…%¬»‡Õ,쥞Î 9Xà̲ñ( ºhëk¥Àîª:Ú`?…n,büÑõÞ~ÍîƒÏÉ…¸ó‘»ã·…ö 7´„}¡ª^š˜— ×ÝS ÄíÃíÏ"K€¸6qaìZpSÖÝ´©®¢À£Þy-Š¡‹."3L\vÈÿ5N\@PÝêDò°ÿNA§¼mä¤ñMx%„ˆ_?úúŽí‹99à5©ò9MÚ—Û–½„>’yÒc]X «Æ[?Û¨ç™A”ljH‰Ãf5ëöFó §ˆ]ÙE׊Z0’âÿñYL.1¢‡7_gtÅ™„ˆ÷yˉ «'X°Èg`o$;½'UqIVº]'B©`L.;_E_ 7œ±“ÍH>= øzÂÁù^Ï8C®HòÌ'oËþ¡Öç¢ðƒj—TV€Š|Â…e‚33wÒÕÇhv(¤[Fu#ÏHrHšM#qññz紛ˎM1D¦Z KiP<ßÅå·_»ÑÇòNÉEãƒ$¡«O‘–ûÛž«Å©¾“Èɤ%™ÜÐëNÄ›²ls ªŠ xŠÁMïuÛÏEó jÓ|’Ù<tÔ#Šœ“zçÇÿžhž_ø­˜'‰f¬Ò˜a&ÙÐ,S6¶5Ïc˜öQ¼ØÖ˜lxÐô$b$‰²Ø¬S6Œç"NÄVÄ•…ÌûsJeÕº¸è ÞØ‚ìÁ©rùøÛ$Z,©3aU”'÷È*Ä笗*Àtè%rB¥åIJدÅtñ%ÿMì#—µñž’Ÿ]ùÂA;k¼¥ Iáðš°ëLlÜ~ómCÌ|^­Aí R—0»Ð‡&Æç .9Ü9“‘'ljp‚'ª"_•‰[üX!¨¤—¯óŸèÞ…CUÎr‘PŸv·§k­äÈ9`¿g §ÛdYzó„R©$ ¡Õ±‰9r(19>ŽÀÈ#P²2•;˜ðx£SôÎÐÔ²s6Qp5:ÑÎʱ£±è<Ý¥¸eÆÒûãäÕc{ómN%œ²êe&¼Ë@m¡<®#LÕΓpkcªx޶¦~QŠmë’&†Ó Vžwš„ç‚6±i6MýÇ3Cçó—‹fatˆÎ´ÑÈÌ •ÖÞü=ºÆ(uÕב>‰¥b)âIWà·isRMIu5Í#‰P"[/BnÉÕôa3òk¨áæT=ÌêY¯VHT©ÅïY/êõão'’„šÆ–\I*€29t†»±¡b”íc‘½£z1Ã×Ì2IhÑËÔïrR4‰]ÕU,ÜhÒ7Rë««1¥óÜz0Ì šçž5®¹@.~óæÁC[»¬±E9Æ~zï`m!ÏUîÜåY8ýZ4 %-Ym&Y¢UP¦=  Žò³bÁ h?ÆbbpÎf«ˆZ´ß…µŸî©‹“[dðKɹ“ÒµµšøÖ²_+6­D:\ Ûgß0sè—ê‹ýIù˜´CµLIêì›ÜÎ$Iu·’C"ê2’m90sxÍÃ#s”%«æÄT¥cŒ¥ßr2e¬ýÊz˜»Â+΀'˜ z\¶9~äs1æÿ?ý»¢§Ce÷¾Ä'%Àl}MGoš$Q¶¸®¨XȬ²ËÉPc"½¥çΜ-“4XÂò”VÏ |Fd9‘R+8ëT7ˆ§Rvu:ô‰'¡ê)GS @9 ¦àÒíŠÛ·Oþ#JIÀŸ±„}×Zx¶¥”W“UŒLj°¤ r§+×t”[á˦0¤–"pí‘J#26¤š""\ì§,1È&3°ëƒq³ì?TÎ*C5MuLÅL±c]<|ú½Àü.¯…yiþI«TéáÀ¾U´T¶c`‚ ^©(U‰c­•ñy­´ŸÇü?qpÐN\ufZrkˆ{ûˆgBbÿÅೆØþlÜèäÌ‘ry}‰‡O¾gÂhj3+¸ó·°ê÷—.v}l¯ö6H;ooó”Öm_ø³64‹÷9>4ñ,ôÇÓ‹ýÃ6²eõ;µ6I¸“ /KNf væôd—1âàI%ö g0þëgÍÑæf‰„­-ûêd>ËÔLe&vëäSL DÜxÍàœDnð±Ví¤²zE•i2œ°˜÷Ût53tbÕ‡)]DLsÒråÊüq£á‡T†åóãȾõ§äúQ_™bê2HqÙªNÈȃŒesÏAØ8o½æÆO }}šÎœ» ãI¢Û4¨ž×HP=JXÑè³oœxäÉãØ>ûϲŽç:ò°‡»ÄažÒ½,ä.é~—ÜÓ¤)™‘ÜÛ¸¥Røì=¹wÑ©á"TT‡`áèôœBæ'åACZ×°ÚFéµn/݈×Ͼ[šp¬_jré<Åqp}~PV‚¢ÎKü”dž"›j|I¿! #™äÖv†2%xÞHÀÁí›þ¥ñ,AÊÀ‡Ç®ƒKéZ±)\GA#hõñÓï5;3(™eyk’Ó£”Tù(…t¬™¨UÑÚÆAxÔm Yè@–} Wv«ygâN:6šâφaÕ«Ò© âÔ(žgª¿·4Q( ×¼Rl…CYè|P2ïão¿“ž#}Œ¾Ò±`¦&ÄS¼ 3)u²|©ZášÊ“¦Öõ8§µ;ŸÛþS鵞^’}‰‚šˆVc,Ì«UEÿ°Kâ>l•‰w®C#ûõwï,"ej„ ¼Uáö1/ÖÁ í&-®êp‘{œä<¹È³–%ò`Gèõ-2ù}Ac6{û^&I?’zZ3ìÉ7ÈŠwËÎB<Ï;›Ûßõ÷ïh2)æ^çš•H!v‰$ÀŠ̨J¾âùWCúã<%¡ˆ¾ZHqâÁ¥ðdqcó­ÞòR³¯YÕxH¶Šª"Ôªº¢P-‡2p3r;¦oßeLMk‡‡8$ðæ“»ìJ#ÏÙíÖç|6WÅ1Ùv«F²ºP˜a`Â:‰à7ʺÕ>„xO)J¸ûsˆ;JÍLÐ ‰†µšœAÅåÜÅþû#h¬®ÄÛtk¦Û‡Ôu&€ð™ë‚ãp>ˆbí~] ˆ ‰Ók î’¬Ù/˜ÊÇ5;i‹+WáƒfçDÂþê$:O‘ù?ˆ½"±¿û.ùB>"õL¿º+Yu·O×Y?¬ºØŸ¥¬ VsÔ1~2ß™¸ë]ÞDuˆí¶Ä”ºð+Å=å Äwϱº¸özŽ$a*:L9ž~ÿݔܦDÝ|è¶Žœ`í3•Æñžø,Y^Æ÷bz6û±z(’JSUæm÷¹ÿ•3»ZFžâU¹QÌx ¡1õºc¯’ Ж£‰±S}³º=iÏÓçß++Ž{ns.±d.˜ÊÔå 5„9’ü•ZjD˜æšÛ¨Ø)e_‚ðáŽÆÚœB{äf{à[?²fÏ#Öù‹O«‹"¬ð%{ŒÇ·?ÜEΜ ùfÈ…oÔÄý uv Œä‚š‹À%„!‘zåÎל®\òT(>Oy皘ï Å.Ýw÷èdåßh™?ò 8šÏèÞëçï´þ!^À×òz·¹©­w{~eqx§MR•c·ìnGIn#=ÓsP³ò,¹$Ž~ {^Y@¿{œ÷oCºHZ‚íOV›-é¬^ïúRX¹Í‰>è6-Û¿:ò± zÉ;:žëO€å÷vßJfå‘|-’oOe†:<¹T)<ï¯(µs|¶œòuîëëðºèuµŒg¶$®³ìפS)µœøÂ\Ô³€«Æ¯$mʳ.Ü8Vìëâ#ç)žÝó-‚‡AõÃ=a§hº±ýLäÿç?h/èéA§Hçô:ÔÏ Wã{.ª—úb¿Q „)›¨¹ûݾæqu Iãôû!¢j5‡îЦtÿv¦X3§–—öDòVÃÇVZì§q©$󱾊¶\,ùФè}ªÙ†Ï#ÖI67¦j•¶œÅØËýìÉp‘:%—|{ÁïÀX ~sF­¶ö:¤t•0j?_8Ü]ËU‰ääa2ŸÇãÛÿ²ôJцD÷´ /HÄ«sm­êõ-¿a"m­¬ƒÈ¸{¿nT²‰óe†9aÖ:/н_ ëPrò½¶´ÿ8Ìyr6©~1Ù&U»¼~ñß5;î'%M*x>2¹¸èÂõÕ® °üôNcîsqRß…ózË.@ÇEÀN«:W)/èó0oÉs%ðÃ5>Ìü_×fÍC¥tìû¾/*Ž4œÒ’CGÓaÄ/Îé³Ë¡åɲ2Õ Ä—¶u‚à9”ë·£KsÑm‰~1fIâ©8)ÓŒ{¢îÕjŸÒ¹”Ef{ÊG-øåúÅ~j*1òí‹‘û Wñ'30Ú˜yS=¸ç Ç)‚÷¨ZYcÚjµAÌuÜf¾pII|Ï)TáxQìIJDk¤ Çʱ<ƒ÷Ë]ÂOI!Vqœeìæ.ðçùý"'?±Ü zÅuª žó$eæY<®’a ‘º®>\Ça*Lº€„öh —ˆƒÀ÷ûKM¢…ÃS€Ñõñ‹æÐA¿µ¹^òYÞI'0>»wÓ‰šŽÄ@ûÊor†®‚Í=ß^&†¼÷Û/ÜàËùožRÙÿ4Û$¼n‹°§,¹IÙJ×p¬ánSxÑ–O2ZiÏÊÜK,Ò²Ò2Žïo/Çî’ûŒ§?þOXñÑÌ*ŸTt —kTtêòAi‡¤ã!gn®;KêXê3k2ŸûHÂê[ÇÔïC‡›Úû°†À/2…îP¬m7ßžZ ’üéÿ´VpG?“–ž›EY'’äö¨Ó0;…g1qòb&”€Ôƒün솾ÏC1Ä$¤»Iû€Uû«|Ï=ùç^õÎa,õû"¸¥Ú$ÂŒ’:ônêÿËè!„xœUZk¯dÕqݯ>Ý÷=wxFŽd;1(¯‘’|ˆ”Æ` È ~C~S¾ääƒ"!c,9ã†ã±y ÃÌÜWßÓû‘Z«jŸn}»OŸS»jÕªUµ÷Ö#Ï·V|šû–}u­¬|šù\s­f‚üë}rµ:¼jó¶ŠkäÕäߊ=®tž4âL¾hylqޝðÓÊ+’w¡ù\Cmò·O~Ì¡ÉÿS ¹Åjª-;\ë6^xœ—›7šWùKÛ¼€[ó!Ês¼þ¬›§×Û{;a¼­ŒŽW›m|y¼®xåq¾–•e`¥&ì}6§É"XZþ¿{ée–Ún?‰‚Kó4ßm½½ à wFÙuVùU²0X 䬴‰@ƒç <âÕèÖÈa:0êÄ0]$k¥ZXy°ÒªÑ-$‡5hQEÒöc/*Q<ÅÀTVœ•7KŸ«"Ùפ·7k8L‰&‘BgaªQíQy:Õ$øS®‘8&°³\R>Àþ€ÊûÜ£x\)R•<òJ£²Òt`,,ËL!kj+ˆ©¥L]Þgèy%´6i\cöÛ*ÚZ¢0£Uú¦p›”¥ì=ñº8Ÿ…7¹I*÷ÙU±šÝ·\–|§ÙÞMW«¦É»æ¥äL\…Z¬ßï³—ê;«XµÕÚzÈOBèþ$DÕùeÄÏ÷/]ØzkÉÅê£9“Zߊ þ CÒ¬l}Œà´µDÑÛ_,Ö¦û•B·›ôÒÖÐê=8ïŽ+Õ«’8Îõ¯vŒåÃÇ^«äÿ^P¨Š{Ÿkt7% – J]`?Í(]aДŠYÇݸþ¹7Î¡Û á,m½µÁ­Ò¤ª¸“ð´ÊB ëì·ç6kÌ5 C„Ò¤ìTéšÉW,³²I”†K;)œIGó•úS‘¼aí:³?TY{ßm².‚ý¥WLÆ&èŽû^†ë"JC 6]¹ÿj)H 0&Ò±=Sö¦1ÁJ§’†CèÊÊP§ì§¹ øÊ©z$f8Ç›Š/%/³BàkªúB7¾RX÷ï?ö•rì‹r‚›&?*ž#éB§7àRzT"­°Ô½¦tì){÷¹:VÞ'L$ã7¤”ä×eq19 oK ;¶šcΆƱûO¼a™…f-kÓ­-˜t(¿kåºRŠ™c%ùÎÌœ&%½†ÎIÚ (JÑåiíPñïmÔi,åM&éìÅçTkyÄcEÉÜéJeyjÁ› #Ž(üÙçxÊÌ49ÁÀ Ô†Ír‰fkêLÑžKÅ!h½Ù,¹Ð ®ÕM¥^¡¬¤zgsW¦’a¯©ýº®fyÔK¿të+y³ÿý7,ôVzW•£бÒ'Wh0(Nj2æÉKÒ~6N.Ù‰ý)(Þ¤@s†µùIèJlš¶©ÊÓíɊצýëë-5Öo÷‰+>f­•˜c2¬ù¢d˜íFQtÉô›B×Á~lD몂 ~Ò¢*–Ö|.z`IIf£fæÔ,Þ7ݼ5Žh?ýœOYé ö;Õ ª«åq qc@'Â`ãŽCÐVˆäãYP26¾îÎÇ,U«³•š«7 ]çv­˜Òh Å‚ÆQ|µÃù€xàÓ°™€79xê-B‚llÚÀqØ>À>,™zLE¦ hí%bØ*´/¬0'§VQ“¸°èÖ=΄ނu=Bàod E ¶EðG%$4ú@gUkÍþ“oK¬™Ö+Õ«£×Ù5晢r(Iœ_9ŒB] š™Ég¾ñI%°u{ñRÏ›ý¡i„TïÅlT‚6ʯ\˜c×C=Ž˜Ü–¬rÿû¿Tíá7ñÙ•¹iÏ^²p[-šÁâí¨¥Ý¾¶œ‘ÖJÑuÜb:šÔT4.ZëfãšFH8?S1ÎJpü$ˆä€töÜû%÷Ÿz‹ó®ŒÏ•O¦É€ÓB–Lê£sÜöqdCm2Š#ÑfÏ™SÉ|æx¤šv‚ÜVûÚžfoC4µ«ÅW‰é_MZ!ÒrήsaÒÆ tŽK8¶.‚: å0ÄU“u‡1S¬ÍH;û2TqœZéupuB’³J‘BiÕŸ”= hR†Ç¦+âÇÄížÄBç†iê¼W"‰ï*úYC}Jum&”xá{oÂ-Qµ7:)à(}ayðl¯X¡j轞"xö:‹¨6Ö¡‡Wií{bn,‡T„›0õÆ~_KwUÎ¥š9u@>Ÿ%±[3[¹T¸ ½öÅ'®H]hj*l¤)A;; ·tM8¿îUŠK Ö9¢»NØI´ÌÑz¤£¶ÉϬ¶ø‰gÄç„¦Û ØKAyŠÍ˜ŠÐŠ‚Õ\Oo”»×gÛ‡qÿOGé2â"Ô|Ï“W¸c˜©»ŒUB.ªöÀ/¦‚ÞöS\SÝήʚÜ>àm®ÏUTá{qe]s‚îbwmcŸ¥¸npY­;7ÓЦ.AêQ;þø‹_ýÛö}þÅ÷Æ2ˆšŠq¸øä[ºù^í´ƒ`Q³w9Q ÛÐX 64öµ ì>àe@Þ‡ÄÝ:Ña¹b—ÊÆD$¢`êˆ{²Md ü/z¸N)ìjnm3PœÕPÁ˜\\‡¹»ûîœÞøõÿð/nëÁñøÖ°}ñPê—ÎåàÁs dt]%7È¡‘°=Ø0-:g›AÎvÔuR¡q+¶w[®/4€ y÷§ŒÚ€|üé|ý3¯t ÷çb~k3©)³p—Ÿ•åÍUMéÂCãñmùñ…§ÿ†[jçþ€^ gÎíGk‘bwÈlTqÍ÷Ù`wL²Çê¦ ³ÛòÚØf:ÌÀ½ÇDÖ—Ï\ˆ…®‘Îk…6Qä¦pÿѵå_««“áâÃ~¸ÿüöGãWן|¯ùSª>y s³dœý(¬ÔÐ$ Dw{™Ÿi;j·5ЭõÑAY%9Š6+æf¸mÃÎµ× >=–ÀžK°¤§ŠPþŠÛ—°?Sˆ?·Æ/ß?¿ñÆxó—³ù^ÚÿóÙÞ·No¼SO?=|úŠ&’›†*˜bÉY)º°¥B9ZR|nÿH€ð_î Ø~Ñ{ÜXà €Á{¥Æ ~=ò5¶q›$^ZII Ò•„#n­ åä8´»'×/»óOÛj X¦a.íÁçïþà*gPYçoÞ†öB³ƒö¡:j6¨p{ ¶¥bz,÷!spðQÒíœsתÓ0ß ziQÞ‡TqÃ~öDBõ~.O/l`ëÙÍ;ÿûÂÖÁ…ùÖV>úä裷Êòs w4Ò…g®ºbó:ê¸õìEUÜtFÁi“"áU¿@e‘Іу4ÉÆ;¦OÏfô¶ÅÙ¡ˆ>2:NëbíõT¢ðF›»tèÃÖê‹ßœ}ôÒxçêlØÞ½ðͯ>|]ìO³¶ýüñÿºòpÓn¾FÔ]¢7e·Ñë¡)6 .É}Éš"ú#ùd ãÔä»>±±‘¹7’㺵¤ýÐãaÑQ s¡*ÃòÃ[¿ý÷rç·:’B,‰³}Ï_žÜŒ³ýç¯Zò:= 1mЬ÷F›nüÙ6ô‚ ©*5«‰Ž ¢éÛÖjy-ƒwÑm¼l\< ²@æÜ:sçÀ¡µù–Ïg_½ýCrmo;.nžã|ÜþÞ½vüÉ›‡?¸âºstˆÑ\Ÿ,q Ës;º‹„ƒ7ÅsódT1Á‚3LçlûÅé¡N~6ö/”-yPj­u ÝE¾\ôþV«'5Íá|´ºûɰÿí’ÏÊíÿ9þàGóy ó{ÏŽîÎ÷î=ûìW‡Ï¾£sËàlTnjÊžÉCt0 Ù ’ò6"c½Ð Üä½nÛeÛFÄ gR¿šÐ|ì8,ª6¿¶4m4ò½Ñ}áâÙÊoÕ¶µˆîä?Y|¹ýíÇÃÎÁÙõ/¯¿ZϾˆÃÁbï¾ãO}øÌ{9}êK&D ¬án5g;\ }m"â8 …@5È, Ð!ëP´¹·ÁŒ#!W:Ý97Q_sÉŸ¸v’E9÷GwÔ¾ºzòÙoVu¶xào|Èß¹~ëÚ]=¹ÿõÑÕçŸ}_§gNwéF^;ìÁ1©Ž.‰£ÚΪ_j1–úè†óÿ0ºs^ÊèPÛ¡1sÜÀa˜†o­Ö¡sú¶&F^çÍJÉçËO]¹½½³ÛV·nÿߦ´µ¼y}¶÷͸ýÀÖáƒãÍ7O?þÅá3ïÕÒÈ8œQ„s<ðÐÂ$]0Ñk{ÍŸ9?êÀéVÉ ÎÿE×èF¤o[à¹Øò4zZ<ùSmÁùõá@~Ìx¨ÐÎÝ~2›…ÅÎáí~.â¹ íû­Åý7Æ‹n6ÜÝã/>÷fŽuéÙúéGÝîiŽ“ãȳ ¬Æ;ND¿PK÷Ù×zÂÐËU„÷+ÿs3«f·m3ëÒ†H‰ÇÉŠÙ¾üíóÇ¿5âXOɧŸ]̶î:¯nñà_ß÷¼õîOÅ~=ä´âèÙ6•J;Z‚«Ž¡r†±ï»é|!+ gš&¬\S·™ªÕt6Õ­íeú™œWÄròñÇw?øi;û\Üç;ÃÞ½ó­ÝÓãEÝÕ¸8ø– ôâs¿ãi‡jGp1ú®V‘m2vÏ‹=Õé©)ÌÆ“'iµnàþÈ0Í»F ʸdÌöé„ë £Ë¼”ŽI"àÐvÇ|ZË*·Qn—~wç¿(«óoü}9»}öéÛ÷<÷{fFsoÎñ,ý‹uy¹û0¹!OæØ[øsê…+KšW[íûÚX´RÙº óýdguSTúQ àKb厊°\­…£ž³°¼Qï\“OW¢(—§î;¾þó‹Ï¾§û/<6‹ûÃ~¯@´1¡'MÇrÖØ›‰2iz.®®¢žvý`€î\x¼wæv>'q øj‡×k‘:Ù8¸Ã$³À!11‡ñ³Ïÿë_‡_|è‰/¯]¿|[ZʋϽO G«(ý=¶øqÒIûô0QDoKCÊ>‘O⼑‚aøJœ9äDÂЉ§üªíšT£Ü~&m­ ?’雷fà–GÂi BrcôÂ!®nÿñõº:ºð'+¶œÞ|×­î.v÷ÿxYyÝxœ]Z]d×U=_·ª«»gÚ3ÓÓÓ3ÆNŒ„|àd#bdÁK öØ v yà¼ñ˜¿À?àðx°âñ„Š,Ë &‰™(ñÇØžé®º÷œÃZkŸs«fZ#»êÖ­s÷Ù{íµ×Þ§®ÝùçR]õÁ×äJ .x_ªÇ• W|u>¤ê6ºR|(xïýÂ9W¦)Īã_Á÷’³?_ô¿©úTËäBàW°þë‚«\ÜÇär >¹ŠÛœK©Öâk‰~QýE™Š‹!¤ý¶`.ø.t¡h]q!ºž~ü)4Víñ)™ëó¡Åú2ÉU\q°ßàœÌÆ3ðP¬ãKvx(> ήpãÅ»OkpQØÉ+1p—µè¢.ÚCÁ®=ݸÀ|~Ó ´_£Uæm,§“?þצ"Ÿ„B?ð_Ä·\[«y¾åk¨ ëÐ| OÁ,t‰#^‘pe#s]Qù]>“[ tH¥=x\™6|íhW°ñº,„~å-¢‚!›â•ðtÀ¨†°g%yàBØÞ“£d„èXŽe"}Ù=b†»tœ˜µ¹˜¯ݸ›àQ+gz Ò~x9¤e&·dÖ)-éñO„ýL`†»bšÕ°?Ä…%fÅJžŸê€1a€äiÀ6" ‹F'ºG$¹‡OƒQË®«³?[ºG°ÇåhöqqY¤†hgI>´(˱ë¯ü˜Æ»dn¤Ï£oPäu ÇHÏ Õüh¡0Îä3a´–¼Aö‹NÄŒù?—†(/y²wÕŽ ³‚ƒý5,eÉÚ0À ˜ÁeÀ#Š2«ÊæZZœ¼üïL=šEi\MŠ#;=·¸Ë>Ø‹ÚÈÒG0ŒH3¶'¨|é±HÍóöŽ6̈^èR¾(º|ÉeX±\Â#J.¤t‘© ÿ›VþG°J:~ùǪƒZÒ;KR•þ+a²2Ñss…Ôw4¹ŽA©E‰œÓ0JšUIh€ ÌYVÌ`Ⱥ¤eÍcIÆ“™EÓF’¸§‘Izøßèø7OËAU­@Ø`qDs"lhÙ‚\͉é\{¬¼á?qMÕ2Àœ×ò «‰²µë* ²Ÿ–Æ™. °Ÿµò€ÉQ!¼_’UbhXu;EUpüÚ;¨tZvª(RJdðÃD¶Lö;¬caêDDª6Ä©–ˆÁŒÿ‘„ÏöS3pw¸R²e‚µ²›TSiØÃb¤Ž¨U)ŠÀäznòïøÎÛX$ºäfmƒ×yŠd†M…:Yý ~S\§zÙ¯¥íE¦£UÞ 0–DŒn»‡•¹‚R²lJ1í„CªÜJ¢[ðº•ÑÐX#´yqýÎÛ$wy_¤•Ìh•·áœjÁÑ3%FÞæ[ô'#|D'Oé|ó?ÝžêªúQ7÷,öÑö53ª%>ÒPÕÿ‚>„=*}0²'þF÷È߀íÜxõ'*—‰5¶A:• i'Ý5«š–ãÁ²OêTµ <°¡TnÄ–ìÒÏŒ,á}c ú$̶8w4—ÉrÌ{¼.ä|»Y0ƒk±E,H8?Çß½ké`ªµI,irîkšŒ±Åí…öQßR¾zá§’ɽd8¡tÿü~ÈudŒX} œÄ¸tÓ‡ÿ•²XZ47KŸ”AîΉDfè«¥EB×—vé䵟XÎ-l eäF xäFš;y×í,%5¥H•ø~à\1—ZˆM9»VcGÁlh°¹×J<å@2›j‚Y6$ UÊf°8äÆwô¬…°a:‡öÓ%¦:”ü\R§ªþ5 &¾H`®XÂhPxЉ¢ÒÕšDf«tAá&æuEº4¨K²-4í4ûœNXšs¸¦Ó×þ‹iÒ;»ÕIz=Hœ£¾ƒB³4aOK‹U|ŽbICµfô­!ù”M,Y™“Yž Awá­úÄ"*`hC7µlͶ47ãgûíõéwïj×RÈÐæm·ê\SVS•»ƒ ´í‘YY™Gdº0‚Á[2Z=µ6Mnñâ%…™-‰"y™ql†Œ}Àˆ‡óíôO\mùÆÀ`¢š¯Sˆðo2CN »ªq´.£“­êig‰¥ó£‘!¼MZÔ&Cy¯ùGùÂÒ@5UذtŸ‚߯-5ˆ E|MýÙMfÍ*ÅFK eÍ’þÙ]Kó›ÊžÁ‡¾.V»eÕu¤ÖR¾ƒõݨvÚ»-Íá›+ê›¶TN¤åÑê‹꒩ħŒz{ÞÉñyÄý­ “Þ<•É?oÜc˜Ji]vM¦ëÄä@ª¶éGëâeÞèãë¶ZÎlSUh&¯›¨À4p“lˆè¸¨ 3N*kf§VLüлÜ´žíw¦råù­6ÿÄX¥ün¼~Ï«86æ 'ªqäsgi…J˜!Qý E^ Ì([ü˜_±é+üGb Sý¹®Nˆ`AtÆ „¦AÓÀú³Yó qØ=¦,n3>t xpÞ¾~o†Q”[h4e,TLO“±Íìå‹$_!† äY²~ªÄÊž]¿“ª.šT¨Ù4¤‘6®˜÷ø‘oÓ˜öB÷u{)"×;ú¾—åŒB(äÓ7Þí¯…ƒE;&ä¨Ð˜œ6¥¿W“°1²À?JçiHüˆ5²ñOÍl=;¾ù¼’eŸdzÒRU±f³C6qî¶2c;°xµ·\òæ÷~ªêCf0û‹4Þ,·fehÛ)ÝRœ\ÎÊ©µªF@ô8av¢“5#[yÍYU)ÎA§êqÇõh¶>uÜ¥#F­¥†UÃf¿¹—ÜXK³ß&K*lD$TÝàv4IƒŠJ £âLšëègm …Uóv£—® Úƒ,®ò¤•W›|*hÖx®»6°¿…‰,Íá¥Ë]û-‰ âãÐã1ÖÕú\Ù qý³Ñ‹p¢,+¦ÐZjŸFë·bF£(dŽ…]¯¿!”Çô+f+O\ðÖ?ÝÊ Ö…ÒkL -ÝlZ«-g¿F¡¡ý6ž`"¤EBEMnÐ#F^‘êŽeÈ©ÌÃçêÖ€Ð#Â`F‘3‡ôÓ&+Uoe®;ÃÜ‚™ýQSVp#Ÿe÷š¦Û";#ˆÌq (Q%,kGŽHR`b6/ÍAúGÛœl q´ÄCiƒÄÚÁo©Ð—Ìø&Î%’´»±h+ ÕtÔÐö‘ÂÙë¿ Œ!0 ƒ­Àmëº8(š¼éAàÞIz¨¡ ’E‚_#…|ž©Ê°ÓaÎk••5ç6‰Õ°öi*ê‹ïÃÃÖ9ZSVɨÅm†6ô³fÙ ©'&Ï9‹¡V¹³ï½g“=oöv. ûc,E0|‹šÈLÏ-"8D?Ô)D¢%j(ê‡f¹>*õ #æõìqXiB¢¢9 ›8ƒdо+’ wŠ©:8 ÕD—|ösæŸ]ZMAóå&Ìýï4ˆ ßV±ûóÌ…Wä9ø‚k뉸51­%çH7>Ü–:bšR2·cu¾@@óºÏ¢)á™p¼kR®‹R.°?°å2é?©ãEXÎ)qa&¢ÑV€1i]l¨\xÆã[/?‰—µÍBƒ%{|…αšºoÉ¿®çŠúÅ®6 °K‹dHD@’¡À ˜¯CŠæ²¹Hm<þì/~a„)q™ɆØ´wVþ4¬Ø/ž{ÞBàå"išµÌ&ýÒ_Ú8k?¥JÄÛægòXf֖ׄPäöCºÉ­ìs".œÜô’M퓜ºl”©ì'i6´±Ð<êÖ:#p¸\ع’Ή6±,à®í °´~ÙÎ/ZÿBõMÝãv:'Ì“¸èv>¢¨'ŠaɧMÙäP-³ì󼃚zŒ\Ñ{¸¬Ž“ä• ó·u£ 9k©ù3lË1ÖBlá¼·iû¡Õ‹FeÛƒÅ.rX”ÅŸ6GJ 5Æ‹í± A=k“OhQpx¨p6#°«n‚jDƒ:¹ÐI¨ë¢ôì_º(@½äbF›;pôŠÐ¡l¬­¦zÏ ƒëöä¢GÁj¢„k¬þl£ÙT2LJ$Pâ“ ûÝ4‚Y<’Ò“msÖS´–èJËyîJ4âuξÿ±Æœ›bÙÌÊe•ؕá›Ê$º ‹'6zFæÅ·ÃÐÖËÇVÖÍo”â¶Í(ŒÚ æ”Fê°‚|g/vˆ ºôÙjÖÛ®­ áÓ §¨æÚúñÓï¨Ú4è@!W žÀ!0h‘ÑPÂYƒ/ŸL_™&Ù…zhE×út«ŽN P ÑJFS›\W¨ÍF¯¡ÀæŠH†'9GêÔäâü6ʳÿÆÞ³s^4>!x?TÎÇ–µQŠŠ;Lâ‘ôs¤LªY *Z·O>)œ¥¯í¼¸‚©5J¶iR¯¥™ÁÃÌà¶RGU‰d–Užl­Ú›°_ŒíPÀæ"Ñ›?¸}V• UÑà Í“×A)&I¼ š6ø®uÑé"øM™h":Û¯GÛáBtÎ÷6Kx-T[Òw³­<©¼ºyÎ߹˵^†!‹:Gû×ßþð?ßÌŽŸûóº]gß)<% Ð&hIÔ lÃ2N‹l¦µBÝš¨ü+¼ä­@T´ùÙ¦©ª 6AµVÈ»%ÛnakÆ}†õ[Ķ|£i6¹ˆkÜ~õ߯‡ýºž¸]Ê2ƃ<­ë’bB8æ=™3ÿ£ã 1p¼4y†boŠÌ~´K؟㬙e]ëϵùR4Úñd`UÒ@Ïu'ôAhlOuJaÉïO¿ù{«Ë«£“_üÇ›qÿäèé—ÆósJ¬¸ t±òê§6KØÂ( eé˜ÀÙà‹œÉ„ °U2µPæo8š'Ë4€œq>ÉmÓNïv Š¡h4¥ÑFUnÞ”’«ïñôÛÿ¸åô×ÿýOÓúãÕõg‡ÃÏœ¿ÿó£§~? GˆÅ|$)Ò2¬Ï©£~`C¾$S¹ cg1C¦ý%-3cŠç<„?´Éíw&¥Ø;p ¦."©Ï¦ŽÆ®PG};L5“@í–['¾¼þêÞé×V×Nîß{s…üò³ŸNGéô…ý[_L ¨=í8wý_SÝrh€á³CÞRŠU%#@ý¨A¹ã97›ú-Ú‹Åñ³«›Ï}òÞÝŸxòÂå§'è|… PaO„ÌA‰¦ñµ¤%ǰ8‰à¨=Lngôdö3¿G›´7³;æù¢>ÒðÚËùÄm¾Ø Ø~áGiº¿þøÝ°wåè·þÔ¯ŽóÇ÷=Ä©_<õâZ¿`ƒ_.§i­ñI«ñÛ´*”ë~.ÇŒ©=ÚÙœUa׉½[ö˜ý>lÝÞœlO([õ¤¾8ÄKŸû!¶:šÐN¦áÒÙóÁ] îr\]u‡ÇyÄ¢Ö%è%ÎÒg’—ý¦ƒk“¨Ù~ JÑ(ÕpÜú¦Ç`Ñ–šOdøGLõƒ7Ï{C?T’¸2û¿ò£õzJ—žö]þÔŽxð…áèKaym¯òEòŒÊ„CõÐóîüØ…?›kõ‰ ½ç(ßä¶•ÍþÑ·Ž¦h×?꣡F;µÝæ\ëš›ÿŸþ«ƒ[_¿øô#Ä¥<|ýîáSßNÇÏ׸Ç_à¸yœ0¹Å"çB…ʾq°VÅœSµš ìf0ÐíCh?Åš¡çU’zû0»×'*ºâ¶“É6wjÅ®©”íÖõ”½›o\ûÍ?§ ÍåãáÉoÇ£gòòJÖýÔ™‡é”:eãx4j$îÌÛ£ã†CGm›“OÓn=ꮚ9T7gøJîÛÿúpÈ=¶ÈœìÈ–KOýõÁÉ“nµ_âêàì\¼•G¼\qŒ–¸ña\gÍI,g!3ìi@ÎØ r…ÿÒvÁ´u]<’ªÛCFçÜvJlbhçG;66ömJé}÷W+Ç_ý›+Ÿ}þÃþ÷àÖW.>¹ðûŸY}¶\|4=üY>xð«»«ë_Ý;ù–j3Ê•OƒzºBP]›è7,Àyœ¬í³ó¼k‚á‘CR°™hêX¶ŠbKØ“¶0‡`uû/W7oR#§ÅµÏÿÉÃuYßÿyùäÝKO\s‹kõð·wÍöÛÊVºëšý­Ù vÎNöi;ÞìAÏd¢ký7´­u|póZ/ù¨P7ÜøÖþÙ7ÐØÕÍýýƒÃý“gïô«ÕÉçßëïŽN¾?7Üø†¿|+ó˜%ø²å4¡oçiØ­ÚCö°6ù؉AS¡ ý×xóQË#nTZ_Sgð<’ÈÕo¿è÷n3nóIž¦ÕÉ—ý޵ͧÿçóf\çÃgî,®=S¬ë awmãº"²Öuô¬Ò·açݵšwv§dl «Ùoó–¯tÑr©Ä!†¹}Æ‹ÅÑï.®>»¼ùµ‡þrïÒmï†ååÛû7ŸËu,› ?ì¥ý[ì «ˆ'3ÝåÂçØ®þæòI¹™ù¦»Úe»ú»?ý£È“-YãXò²–5¹z{'S¥÷Ö†\ßêºZ&jÍÿú¼DÅ?~e“ÕNY]–ŠIcéÕtÈirI?†t³…‹[Ó¶p“˜/£«‰Žnç·:ž–™ù]M;þ€+q•ÿןñÞ»¦/ëVð2¿Eýán²¸µÿúåÛxg—ÈáöÛZ/ͤÁBÿU[™/nnÒUðƒ{p©Û3Ä·¨-{múÔ&VÀîôZî‘4ÞŸÈëümÇZߺ[âûæOòÛ–é<ðëÓ“_™·,_Öü.·¡.Vã}Çïô'w‚M߯¯ ¸xM¬Ö6è7ª_onÀÿÆxoùß÷«ÚÆpCyÁµ¸l³Ñ»›w†–ÅúË7Öeξº[øêæþéþƒÜŸ>"^G:Ù¿·yEø:¶<ýKwµÀb‘q|÷Gÿ«ƒ‘r³åðmáz÷tØï.rçÂ3Í!Äà£Y¶p™âúI‡ Ø ËoéæÖºwg/ûév¿Wâb ç›uî"¿Ð7„O!Æfn_õp¯q³éö Êw¾ü?÷¶ŽaŽ.Ùv½´ñ{ûÃÛêOqã×E—>K;P‡¯©Ú=î§À‡@‹"M^D¤Òí¾¹6”@š¾qÇœŽ»Æ:&Ç¢< wûð­ÂþÏ6žÿþËOÂ~Ï£ 7éðx¹g08–þwC™MøÕ#uÉ~^†¼=}©9Ï®µ²†7Y<Ï3”áã ö?Á~µ0‹„€,öÍšLÿ±ÏωK˜&H@`ˆ ‡ý†ßÆÍÔ´©»Üáçp(#‘Çá÷.¢Â¡àO=S‰t׋CªÓ0¬ãßè%‘èR«JAJ=rͰ¹3BÓñ„B”ôsž:ܶõxÙÔãð ˜Àòþ'߈“5hP¹á±]Ý©žõ +ë¥ë³ ;¶íhÐõ-{‚ÀáHmMÞs3ºiøÐ/{"ox’Ò~³³Ï4•¤ç±L‡ýC "*ñÄD¿ÿúñ—ßH»P˜übgHß•ºWŸÁ âÀv·ßöëÎ;¢—6#i<™—M$T{–þìÔðu ?Ë—r°É`Ógð|,– ·RÄ{I¦±gD!¿ÿòÿá|É—YÏ+ýÆFΔþHÕÎŽ:~ÎÈ&O࿾>è4Ь!ÂG›õA°KZEnFž*­pm¤1îÆ£ŒÏÉÃçýO¿áÿ¯Ì¯®;5"Å&àçtŠ b&a?ö»FÙñf/:‡r!>Ëۘߢ”€C‚A»/_ ^ÅvƒÕ~ðϬÒàÅZð`ÿWÃþŸýeÿL«f@77âÍë#Ý^븧®òNÚß Œ|å'=Æmzú¬vÐþÌÐNd/áÞf: x¼Ü9X·“àòä˜eL—ûÓ"£­ì$JQwÂþ£.#ÙʹV¿ë>(U*¯!É>°Z@ø Šÿ•Gºöea+O•ܚÛ:éC ±ÁzçßÑ` ­<¥¢“>vÏí|ïg#`ýst ÿÁmÂ6¥OŒ¹àœ·`¿óöø'¼:ùã)û è¡éró¾m0øÇ3ÚÔ!\Q¤l3g0Iæûógµ­X>þùß!5N!·.” a™“ŒHF½¢¦Cöá›yÎEâü󬂔‚ý”Ö`EY¯^8 B(µñ¯U<‰3¨P·|‚â %(J}§N„æ¹Ó´s1:zcž\”Q‹ÚçöG¶‚&k%ÄC†µ˜ ÚÜ ®§‹À,ˆÝÊùâ’©Q à›UŒ„Ô^z·Ø ÍÜXáÅȯêñ8½æ¡¬óv¨µ0 S˜tGùá†L¬ïtxlS?ÐÀŒ/-£A@y¨×›Á<Ç³Ž—äÆ_æ B†7:ãž¦ŽµŽXmWôCØtÒ»sœÃTòï»èÆÌB/䀀íJÿ§˜™Ær«Ÿ¸ÿ+:[çE ÷Bá½ÖMÊžƒð@àòø`bXkºè?܃ þpjÈWQSâv>¤0‹q~`žOHF¯ò-º£ò<ŸƒrÑ5W[YzPn O~ñú&·;4UØŸW®l¦B_¹@GQ™“Ûøõ¸Ï%ë¦Q6DšÁhtp$ýîíÿq¢5âó=Æà®Æì0pÛd×·Sµá¤´G] )ó7ðì·"#Ü•À{Oºšá‚Šz¦C¸v Ynì0<…W‹vÉE²†E—l±€» ò"7É®´ŸBNÉKë^Ý[(ðí¡!Á#ŽŽ‘ïý¢ìW„okZþ›t•=Ö‚µK„ÚŠöíÁ~¦B´Wº¥l…(û‘þ'×9ý¶õÎ|¶vc%@°ûú¶—¼ Ÿ¬Øûÿ&~Ven8ÜS{B$+ß2Uþ:¼Ø1 `)Àb‘Gû-öо R¡%¤ýÑÐ(›7b¨¯y yF©……XôFoÂÔ½iÛáYâþ_½úq=6˜ßv 'òbXÇYÊ6oJµ,ÙÜÞ_Q>[tÓy[qD¤NêO|éö³8PŒÐähÞhµÄÓ•¥&>ÿ×kä©U½ ß*°•¯¨>èídZ œ\ø—Ðapýÿ+I2{1Cç'À$u…{¬Ú[ãL ],̲¾ ?°ÐΡ.”¬ þ|-ÁBôŸUG)Þp,¯+oGÒá¡cÚÄõ;éw Ç NRÙt7° ÔWFá¶VÊç«™‹å~úK À@)ãÈUÌ2-5¤¢cKÊÛ±FÁîA^Œ‹EfzÒ›Îö j6#Ê£p•j»4®ìá¶ü.Sá I˜©~ú+ï“Ø¾¡qÎ×­À9ðqÊrÝ›qyÓë©<8™å‰=ÚcPf2ÕØ$46b´?ئÁ‹Øãl69É*ÌæÒ½ÀØ"ÛJ9»püÓÛÅö+kÊŠ‘EÍ+šT£€ ¹.„A ƒlTùMNLr†° -¯²I‘t e£íAÄŸ¬ëN”Vv&x¤5’yÌRÒ~Î3ëÁòÔiI4/´ß†UkO ê‘^µÎÒ~Ì1²lHÃ^þ-Aèw R,N#•^sÈy €6…aäS2qüá;7ù×Y´­C²pÂÿÃÁÆù˜qB½ñó0#м ã+:U÷=ÑÌ[+z,S×.J¥À©–sa?~5o!¹Ö% ÄUµ;Z\£’3cd´©¸4óÝg¯0åQÁnùÖlšÇ v½í·rGˆ±Tƒ\oO„Z?þjæh±èEWªV=ŽÐ½ ƒ†Ã°‚o8ø8¼š¼·¥Ác§c%_Aº_@ˆã|]/^ÇA…ý‚Ùí\ý¯—ZzÒØÓ¢RÒΡ½©ì–'ìÜn˜Ë•\„å’Ä·õ †~˜ŒÉæ¢PŒ÷”¦ˆÚoINÒsgä(›°Ôg˜iHûmýÉT³s<öäŸ|µâ{I€Z%¼&P©µb¦×"q6Í.TÀ<Ø\¦çsyˆ‚köÐ £ÿ¥¨;8äy{뢴#Rе.×ÚX=h :ÜùŸÐ²ÄÚ>èé©mÙ)j{œ¥8A– ÅÝeúBdúÇ1N­Ø`ùÖ€0ݱgÔèÞXÂ|Õ#£ÌB[Óaòù¯öÀ¥V`(spMS‰ÙbÅ{’×e—]ÑÜÕâáHÒ|GΔlItV Jç„yxÁ€ó}Ê–Ö$Š1Á'Ÿ}µ‚•Ö6â“'QÖSFZ+V÷ ¯÷J˦*ÃéÇ®5”mµµðt‰*”Vy÷¶]× 4ÊÜåëgmšIm6$»­€t+U]Ø¿}5WÕy• (Ç­ÄCŒ å.‹W˽k)=ŒÝ=u ‡3 FÇÆJ@=nЍ’¸“!*#¸É5ö¢dþ‰œ=«†GJfÜ3²*ŸþÏßцӿAÙD7Ò…žœ1¥ýî´8ær¹Þ[)" v í1“‹RP7 •gìnî%rÅ—>)òaÀiîÿ'Î÷H¾äÄ€5H£}0ö銎Àñc%V³eŽüË ­Æi irŒ5ʦ21¨^ Õø%ÖôÅt)°Ê~mZRÍb‚!L•³¨âÌ‘j·JìñQuTà?ËA~b Ô)-©““„—E&$<$ÕQ„2l»“«q ÐùeLN=,œpƒ«{än¹húÇÀ#_úÍ™©ö1²ÃÌ=Q ü§·ºÈ•§;•4‚£jäÉN-Z˜*ë’ó½àŸ8Õí¥[ŒG©©ñˆt"-YÔò ³5-ûƒøïŠ£Á*×Â~eµåc³L)7O)¹eom—-á'ÛøjW)Š }–]Ž2 n{D‰ØÕl<‡œQÜ“lyˆÈðµHgÍnücòý_¯xttRmi|©¥¾lÁ5±Ò7™6ô>9¥èÆŽðФUÊ%úß­N‚hµeÖ¬>G;¢5úßããáýü׬™=%}{k Ü-vn§¥PÜçƒ1"¦@zÓÑEœm–ZM¢±Äð\gê+ °è€¤²©q`ˆدÎ{¨f“‹£‰úì7+hd1®ÁBú`p´º—œœ¶zɦ4í÷tîMµŠSκIEgÖ«w6z¾‡'[v1hôÊl\:sî„{¤ûe/‡ã”Îx!üþoW^ =§û¸Á8æj'1ï‚,:9ßQmVƒ|OYJÑÑþà¸LÉÔ®™dyTc=‹®ØZ%º¶OÜxyÁèÉéãu ·!ð”K>ÿM¼Îcù‚D!S÷½9UXç(ÙÃCüÚBtTz7«ÄÛ#Þ^ ׸y *³ÉrmºJ½ïtŠK³…©·;ÂuŸýöµ±‹ˆæ®fÖ÷4U. |ö:(t‚xe·xtwµ~™’di‰©e+—Ð2,Nº·öøÀþ(s›Õçû¡Ÿÿù’'“ÍP&ÈN;9¯8å& "µF-¡¨÷\kÛ@ü /á=ŸQ¦tO4ZL„ûý¥7!xlPðƒß­¬õÁÈa˜qÒuOòcʵǹ@ ßÂþ›´ÔôgÉsÂ49BX#uoh åâXçˆáã!ïžCîó/”HÞøÅ׌wNd,tQ2µ¦(­¢v7/«ºw£õzGƒeVÙ•š‘ö˜h`©ì>ì8ú®Y÷ãXo¿Açn¬"pÔ¿æüçq€OÓ8³)OŸdKýžÄ˜yZ*(fH|—)T#†eâ -¾\-5[£œ˜l'ŠzHšþa+ù8ÔŒé(C£YMþýë×îé_.¥OÎì¬L·g…3nRïSµ*šäº„ºÕÉ‚òÕ…yžý8®zïWÏ¢hyS¹ÚzsN±aó¡ýùšŒüð÷«½ÍúUÝbdý’¬C= ~³·ÜÆ#3Û·ˆˆ";iõÃŽšä[MlÌ’»8]vÖ·å"y ¦=<ÅUPpãnŽÄyq 9Çò4O×Í'q#^ß:8Âó±Ç­Nº<œ!âõ `åB z’ϕ¾¡êHì-é’¦2={Ø8Ë‹ˆ¸ýmN‹afŠmöéšöKGXðcöGù¦¨ÅTyæ ½ÝÐ5ŠŸTP5À7‰YPú?‡¡‘ˆ­cb *ûÛ~í¨?mÂ>ª÷gòThWU……ÒlqîÏ×¢2F߸¨Ø5²2ò¥2kñÏ 6j6¾NÊ÷ƒîäÕ¡¹¡‡\fcö€Ø›÷8’%öHš¤EzQÝ$“‡q•¶ÚAd£d¿Ë~'F¾±¾¾Ù xÇ âD‰Œ±|Žõâ@çÊ“)Ùþ?,©a2~ŸHñ Öž¨ia;!-y ‹Œx×|nYmãÅ€“ S¿ß9i5¥åEy#ßj §Å»9M³³{Ô‡÷‰\(szå?ÿ°Â3!5Nr{Lápã|žBˆÍõ"Ô÷ÀyDã7i“B¥³MÖÞSËxþìx[ÃÍÞ;°:‡Â+IƒVs³ñç.°Ç:+dAwûÑ =VÀc|”'\¯NäLgNBòmh#™¶ÝŽEš| îYc°j‰]{O\¹¿UbôƒÀϨžËîwùöä?˜g‡Ó/øâ÷¨¿ñeëÅùv¬ì"ÕÙIñÝ_¼ç¬õÈÌé }k„ñÄ)NŸõ|2¾AALòÅyH)2ª#½aªî³±Salj¼hVŠ6YW~ñºÙ¤oÙ-õiÕÇ3¸X}Y½CV•æÿ«ú%ŽëÅë…—Š“ óÛ?{£œëI܃?¥ú°|Éå/cøP|¸jŸbOźx¦ÐêW~öú™«õ?¡Ø :² š©!üP,pp.9ª˜Ý •TRˆB•Åÿ¥ðW—Ð¥]¿´žTB7–o“›<¾ü±½5`”“&èfޱßMÝýüK¿Z§vÆE›Ò}ö9ÔÄÀÞ5ùí²ýÕÃ5»ä§>iÝQWc™ –Õªi%|o.€? [—ü¾¤€µí g1„øªS'c3ü‡ß‡ÅÄñÝtÒ}¶”ºú9Ñ íù®®«#™Êñy¢Ò¼ÔÆpi×ôxÞáº*µa¼s¿[hš¾Þ*)$õá?|§Ó(pR”òãâEV—F[ [+GÀ½>.ê§C™@1¾À^¡´M~:2G(=å©ÕCûàEˆ´÷…ñU~õ›à2rXšÛÀC(Z‚èŽW‚è#Jc„ŒæòºMÑf`qPÙfý‹áήyG,í¤bo$—°pžËùèõð‘)ÆŒ]:å¿aO|’óû­Š[C€mºý숷>`¿x#—©5#§ ï({7ð½Z¸®þº ŽÇÎ@,ŒÃ1§ìÖ/_ öuµ'ÈãS#ÖIE @u¼§Ñ%q82H2hMCtÆCO¨1Öì´£vv^>Šö–13aS·çǸÉÿá—-~»ŠXòÖKÊÿhžãNÉ ëÌ)fÄèˆuq¿ ´ñÕã äé&k$»üKkˆ–'”¯¹XÇ^™!´X\zøó¿úÊ÷¹™RmL>6\áW(Ämó)ä|öXP˜2ùVªÃô6|`,°½^úŒÛ¹Ø ÄÅ`6"ñ•¼>±W2VPož¤ŽeG—?1và @~-§ƒÙi£V§#C§ª·.=c…²‡÷æ×cÍN͇J;§» ß·|¡PM»X^8°ÉÿÏfŠfe4NƒÆšØ4R€Þ03‘ÉÏt(æë‘äÄÿ"?:GZØáÈ=åtÀÕ㑲=â8z)··ìóÑ¿žëyÚ]ã`nnÎ}*ý½§ßÉ-ûRM~¸ëŽ¢ÁÔœ³·+¸`:ߎӒºg¨X,>Ç)îWÅÊE}üfDˆu„¢óˆMÚ#èÇLL’dr„>—º&TøŒÒ.uS]#T÷‘MxíŒE ?|£ÙwÇÓc Œ¡é™ü¶R ÷‹ÈPˆ,ìôËfa@`€Äp:×èmªwAeÆWbØ’¸³k¢ºßC4Œ‚¸g£H¯ÉnGÆjH‡nJ[P7ý «™|›3pŠ3dH§vÔ»EÚê¡7xë;Ï;®á~€Û˜Ý¸µ™äu @½´Hî~Ý¿!Žªt Pyš.ÝÓ¨ ÕðÒ:à?ù÷˜£Mò Á|dÑÐI‹Lÿª&~¤.¿¶b£€4´¦ç“x» œïœt½ð>˜ÏåìKáÔŽIØq@“ŽÿJa‚byÞ’ÒY‰Hor€±%Spé< tûòˆH&¯éAí΄ƒ1y<tƒ_åÎ’iÑá$¡_õ,Çy‹ÿ› Y©&ŽäÂZ22)^®%^$Z\°ŠE|@ôn23Q“["^·# Njó2‡þ^RÏEºäÇoÈ¢<ì¸Þ[èg.Gd"Ç]£Õ ÁT]Gê´ö)?ɵ¢°rñìä d@ìá_¦üæ0äZ2“Bk(•Ë4aÚ€5aîOÞØs Ô,T¯ƒ!òÇOÓp?ú”\2K* ?åÇÕbªeá^ë¡®ù)?ئƒaЧZP#…¹ûäNIQ(9ê¾5~ñpD¸¾zcÑ3êÙâÌ^Švq °¬ãОL,&²ûˆ~u"¡«j0y*c&äd‰Ô',g±“Xjé¶ (zR0“ef¨™•KvùŠ+h¬JYf_"»+Ÿù¨¿¦K³¨W¾Rœ#¯1k{ÄGžò‡ðˆ“Ì­>2Y‡®ü’“ÕB©´¢ß«¯ÔÉÀ ¶0¢|3ë»\Zªc㺒ðáb3U]Ax¥EdòF_vë;a0$ÔS©Py"ÖƒÖ­³ê_óÑ‹ùÝÀC2c ñ“?묡ªËåªfvöÌë‰Õ!Ù¤lh\Ã2 ÔËHTߨÅü2«¥Wü•‹…›’“Tx4jÆú®ëzeÖª5ú6Äkð ÷Y1ùÍÊl! ”Ú#°uxS¤Ò†¾jI]Bzãˆ68?Èy_Lì+e<,QÖ¨‹ÁÕáÎn—æÒî$­ÔÐÒ‹³AÕ¿1’¯ŒäœÕ Õ sŽÂsY­0DË$ÂÒi¶û<ìD:ï“LUM‚ŽŽlAÞ‘JFÞ‚ÌN´®à6§9³ÚPÚWÔ‰„ß|3"o<®ÿ¶µü‘Ë¥Mµ›ÿ–lÁ½_‚…ièþ|þL¾Á:¬‰mäë@r–W]"y) öˆmfÒ[÷ꛨ‡#3RÆYÕBlAI2þ„oßG8B€Ùº˜)~jo’ÓuFµ¼è–Š肎Ätáš¿üöë/˜:ütot´P£9YÀØ“¢ËD2€4è¬XE²•òOµ•Nš!¤"†d’º2—‰ŠrD0DôÎ|!Ó§•ìWÈXÖ—è mý[EŽ›½tíxÛd…ÊY`v–À‡ãÐgA ¬í¦ì€—-ßç­Ë3ì&?Ÿ5 1];S{?…\ÕS0ÒXޝîSÈ?fIúñ5ŽÇEâ=Ø f ⽦èm"¾Ž»õÅõQoIT™žŠîåüÐ[Û‡„ƒÌÚmQ‹êúïõ©üÔ¡w$ÌÍËl8ÐÄ+ž„êîÙšÞ„ȘËiÜãf  òÃ,…ºà<\°G_KXÂwwUYl$CVÕϾuý÷ÙR£Wr v¤×””i›¸Ú–Mo ?u>%_å:Ð2rjñGvVÙ)a¦Úh1Wò÷þîpíúÇòéwMd OÍËÜiÛVyÔãÖsè+Å÷¹¨øÂP©!?y,y8÷;ŠNŽ—^,+çâ¿®ú2Ä!EÄêl–ß}‹øÃm¦ô»(ÞÇÿ ’gTy› á½l1föü™{al)̵Pž(„%13 ò·sC-;cz*|õ]+š¸Œ†ù*ÁFYá—Ú:Ž›.&rúÍéR î¢Kþ’-µçÅ·²çÖæVë=²18G‹™‡•)¿«¥as6÷¯Á÷D¶t¬øEBr¦‡²ø‚ü!Ú²ê)swÿ±„òÖìºÀsËãêM¼›Ò¶~ÿÝȺ³¡|©Ó£Þr±oúë’?Çû¾; ¶[8í‘&Ü#n° •&%%ƒ_ì±D¦8d¹Ë–œ¾ÿñûüœÕ¨¬Mvê$] Êùï%˜‡î-èž!sFï²mUͨ+&ô-­Ô=óf:–ƒÎ+ÄÀgðß®·vZy ¬,´‡S'r_XAÖ¹‹Ãê^F'y*P2ú­>ê­™ƒ‰@ðøÌØ8¹}>ÿ¶yíÉÌŽÞjôjøYœóîÑ/ ÁÈé·ô¶KrÀûúqÛBZö E¼ñ¯ØF©ùŒá®0ƒ°É V4÷ß¿èEc{N³÷Òhˆ[º\9וuJTaÉ\ky:çõ¤¾5¶rBçw(ššo7p›Ø“z&Ç“Ò壛©0ÿâÛaÊy¡ŠÚ;»C6W«È-¦m¨²kr¸’›¡{—F5U‹ÖVõŠ'rßóµ$ Úiö)üÀÐ[ó(ØŽÃÇÑðôÅZ©Ÿ/¾·ªÒ¥íÑÉô¤@ì’ÔD%RmßT½¹mdüôèZ¢Dz\Kþ¬û–òxFžúÀ_ߊ3=9l`î*×<63þDã_¾¬­–|8ñmBöCæ\cÛ« €«,$ˆ¬ÀVú‘áq²îÈÚ€¥'‹ãÔ<<#½×ªÏ.a¸­¨ ‡÷çEîµ¾öø¡W±6Ö¾UåÔÜ·JzÀ.Íîz“±›#R­÷ý\Ê_<Ãs~ýh¹'Áèf4¦üûÒpt w£Ä¾–üwìÍVÌÞg˜’0ÎïM’L¸I·P9?ãèGßvRψÛ<\Ópc¦Bûü ù‹Û ¡:™gqŠ@$úWû „8LÅ`~~wlÉr~—6ÉýE}ÒÌEp´DŽp×?¯˜üÂÞUá,Èík™«·wÀ|ìN~µ êû™"®+éܪnöÒ[„‡¸^Ê/à‡urŒ\‰ø}S¶lXköã˜ñÙß3—‘»873HÕ<>tãçØ•Û®,Éßßè§òoÛôwáùFÇ+Ï`êY úϦ*ÍäT“g >ý¡qû ÓG(3á+7’ 9½Ö0·ò¾üÉ®Èêd«$Üijù¸•ö8ŽÒØáY`Ôcì19H‚"çNýû“‚&w6ÑyBqèîÓŸúe÷{Ä{rÄn¾e1˜Ì÷µ½¨luÖ±ÝRƽõjëòýÍ$ÛSþI‚òLB–™§ï2‡š2¬Sؘ¥Kž]3 Ú…?ÿU»'¬^̲]ÁUºF èÃÖ³e$d6ÏöÔÿ—Ÿhò*à…üuQzÍêˆÿÅié~l¬i毌6&|$lëØ(ýïàc޼9øôåšv =rPœIÈmî½muí}}AŒS”䯾«>ž¯òtTžìÚõ„¸ïŒE¯ã<ãБö]?üò·Ÿœß ïM¹x5g`5Ñ]ØÇ‰C‘%Ùê&Ó$^ 'ñ\éñ¢n¶×&ÙËálZµ¦TÍÞq¤ÿj¡Ï|8²Ë_æíè<fã#Ï!Æf#7ƒ­Äö©9Fïß7æ¯Øv\kœ;b/››’ûYypHOm?#ø˜3šþ6X™Ê'܇,4±ðÜöòÍÌ“K÷8e¼yp ¯5•-Òû,á×èÌðÔ¡Å»~<0ÝS@½²ÒÑ™?Vê1þú_Ô‡´å—ÕˆQ]”Üš¹WïmÁ'+OZÇ­ðFr"§ò’ð óVŽ8@"hmøË#â3õÀ‹8¢9•I°ýÃ\xœmZÛ®m7 MœÌuÿˆ‚Ê¥j¹‰"Ô"ñ5T„ʵª< Bˆ¯Û{Ι`a;ÙÖ9ÚZ—™Ä±‡ía'_ýå]«”xÙ[ö¦JãG¼æ°÷µ–v¥µQù°à§1æ=[ã“:Zø=>6ýõÛÄ~ºo~è£ÈÔI›Ü¥týu”)eV“s)w—V«¯Â×5Ný;îÒ|ÝñµOæ&~©BgVùmQH®#æ¼¥úî° íË!¾_}?1ÊÙOV]DDeÓ¯9ÛÀ®£æS=Ž»¹o]J‡S~+ª½Ñ C¾tú1ÖG[wޝêò›œ2h ý^„Ñ oLÅóotý.óŒ}~Û*Ðä ¬:½MÏ:á©—óQÌ ¥ùx±EñX9ÕòÕŒ"fîÔ†8\ø©š1™SþÓØØØsÅv(?÷B‘[—ˆP²Z?&6[ܱ¨*_¾a •ŸžóÔçãP@`žº5 “_õ_ ‡¦ÈcóÔ5í2ñ£°™JI“aîE&ÔBlÉmó«D Ý¥øw¡>mSË&&óÄ—å"…Åm»  Ͳ*ÆuêSü£:‡H ò÷?™d>~íÓç]çT`U…ûÙB3$7ðè6O{¸7Ó¸»wMÃy!ưЩØV‰Û Üûp3倧T ñç§«t.„ ™>Š^NìÂ뻎…¾ñé§÷¥„/äŸwìÂô¯zØ¥Ûüå¢K†Qª“ÃÌßÂå2Œ@BoŒ»i,280Ý#êð¢:j%|D\þ²éÿŸèî ­8é{§*¶Ö )ƒö7äWw½ÒBíÒæ¸¥õÀl&õôÈfj‡jÜ1cÞôp±umbžYs¨ØRž°_1šÙ°¢)'ò¦Æä72=¼”w~5Ó4.äf>…EÕän`i«:XC:Hù›²EPš8Å4Ü1ÁhC*¾gŠÔ'«,÷€ 2Ï0ÓÈ@™]åä˜ ×Íw4Köz¤æ9ºdª½3w7~šÅ’lqë ’{D]~êÇ­Ø…ù 1Á]#£Y¨80Xá†[]e|ó×wî×ų¥Íµ-J6GNbI¹Ë:œ3/'7i` ü €¹UÕ­oZK&sý0}wsÕ)(Ççâv¶PÍߣ!^ÆàT…Ç}w~;w÷Ü„Œ¥ù‰ü«^ø‹À`û&2J€¹2eƒ,AÉ…¡žòßV‡q¤6Ô–Œ]ÄL£Zò<×­¯»6ùŸüÉŠûŽ)\G€in;}ÿú,HÓ®-—‡…T;Œí÷ ºoü•üòœÃ-™â9"õX}w„Œ']hòØûÝßÍ’±K6íUGlB‹éà(¯sè‰çë⎿Tñlô¸JßPß|ŠFD7cdrQ•fÖ6GèñüÙg”oýæYÓ0ã"»=+í^Ï7]–ü‰®ºøÿ©”`Œ%ÿPÍP)ñ¼Älœg.-­\ol|lò÷Áç÷L¤¼ûÛ{G{Öješr'øuÐÅhb† ìÛ$ !G§¢Ju2Àä¼Ls’9<¹^¾¢pf ¼Ú5ùíßÍD{P&ÿ±âUpÌØ¶÷\‚|Lœw©•_ñn/—n²«d$Ôw¨àѳ•]ì’°¤ð|}ç³™xHʪr´. '‘ì*¦5¨§õdòn™:\ÆZ\%%4ö½‘°TEë%©‘ùã²üÚô·|M_ßþý´j±HõÂÖ­cø™Vm8Nr ‰‡âjÏX·çD-p„¹BñRb—GÄI&¢tìÑiI‡ß•ÖðïšüKžUƒÇÃVRþu“­‰¢–ò¬aÕVzvº`Ù^©ßH/eÕ: <®vÄF†±½÷Ù䯉P£•Ï<›ÜQ.¹ü^ΤþÅã’ÉßÔ‰$ÛM~cÎ$Ÿ¦OÜ }ËWòc¸+x˜¾vùЃÛoÄ œú­ùl”]VÎÈJm±â8öØ[Ê÷þt·©^gIomøØÄŽë6_tÛEµf䟒ïÕàu×K°• U¹A5é ¯¿yT¤¨Ët%‹‹?‰"ËÑ$¤ D/u©xé“™ïnW8† ƒã±B«l yP\ÛÅiq¯—£,ë Ñ–3Žï«þ£W ѵã¶Ö!ñ„˜]˜ï^Ô¹²¸h1üÞô8ÖqFÀX@wßû¾¼³ޛ罃æ–墂­­™!e¬ÎFYq̼©Û ¯µSL{hÝ0Êsé#jU{Ø@xì¥P¸Ô(³8„Z°‘£ø?øËd0±cÄ+71é°Aà¥n6c‹¤ülà6!%ú–†™ž¨èÈõ06¼æ}MVH‘¶¼­íþÁ‡f¥üI|D‡V†«…¶3 GäXw¸®Ä:Å9|Cÿ¥±Éë…üð)¿™Wü€cσÏGÚe©‘?¡m¾üðϳG“dV§–®›ŽÓ%ïC$úŠo5jyÂ@¢©El‘è¦]ìîu¶2Ær-b ¨°¨“D$Ž™ Ï~HÝþðOˆŸ8Œ˜üá TTÏï-Zî¡%ñ^=$/%ÛçAx¢Ì®—üÓ}Y·×¶ô´ƒŸgGlÁ¶O” p(À?ü+äçÝ~B+>ºß¡^vi×&ôéu“wB?ªøöp4lògéÞÁÆ éakT¶Nýz«ðœôNQ%Œþá_ïlÝÀ+ºí(jo4å¹÷ÞÃÝõpœd'•4nG?ƒìÛѸ±g®d¡ÔÀA¾v/Þ›1wñ<º16PtØåŽöœÊŸ`på{Êö>v¶;,TZcí`üOå—íÊ…AtêÝéôï#Ňz“jŸÖhh·-57Lutר掷[½ÏÿÌŒ?ý›e¨Ù¹MR¡¾ùiÛYö†ª7ü$kuÕ˜d;#ê` öŽ¡U£Œ½î5Åb½UÙ ANm*|@c7½ƒ"ÿìowb/+ ô I”%‘»Xç¾ÓõŠ{;²Fc`Ŭٱ}Æ–ðM’ü`Z³—9ìáj†Eê-¹ôá¦ñUþH:|mÅþF¿GÈÿXÊ_›5n8IÃñ€OÇ„±á¿Au-((=ÔǾ5wj„KÊ×ÂQg…ï͹¤ÿ_ù}ƒ}} MBû±QÕäÏ3²ƒG•ÿlW_n)s{òˆ¬T7òï§+aT¶fÝCjP3š0½\F¤ÿ•¿ÏKŸÞHDb--î`lőçÅ=’CoÜiãæÑòz–‹º”Ã4êˆÕ–\KæYõѼ)@ù?úû~þÎ\‰pº”oË]Ñ}Üaèö¢·Ö£½ð¢·@”ÿËY ÿ]u ]]~<oÞX+Gaw,ù5ªü{$(ÀÛÒÿ˜Û•’7¯)y„±úÄ¥¾,©ZÜc¡œ¬ û[¿P!ݹ7Ã&Ž­ý|]ÌKVÀ*£”d8‡õO,æ›l¸– îê¡ÆU ÜX–Ä}‰þy—ìgÆ¢ñwdk”µO‹’ŠûJ›šòŸGê¼öu.æDK¼›Šš·y†ÕÇ#üVqbö`€·jDξÈ_3œê Áù£=SÃÅYÃføm|¬h;Op”°r÷]«¥³u¦$Y2Ê+çN†O,[tÑsÔ[®xÂ=÷_ãß4ßœ§ƒúöãß{û‹/'wþ ¯Ë%kh>®Üx[Õn x—]>XŠ•»«z; N±[ÄmÅÏ¡ÂñìFQÖ|4¿5¾ÝI0–;ÊÏÿ³N›3ìÍ^*½®gVB¤Å%†° ã¹¿‰„“ݰn÷&l¡¨¸ÉŒ÷øñXo;0‚K0omÉäýX¿Z°2ù×z[ó ZFfRóÀ°”ŒûÞ*Éž65ö{²D1·=ÖíÙáwÛÄËmÜï¶ZE¥æe^ÒxpÞÃ'iè¾É/Cå×!÷åŠõK ~2襖ÍN¬ææÅ ¼¡´×†}ºdWj7®çî<¡ JQñi\}°)wçwüßvÂë­x…ZÜ|þ…êÿ°«Md|£¾¯²:Ãúeó7‰ãc•!ð|ÜÎ ­1•ÅOÚ÷M~+xÒ;Ô(ôå:w×¢xÏs³‡Ç4E”îë¿Ú ¿xœ]ZY$Çqγªúîž{w–{“"—\¢H‘¢%X²eX†-H~ôŸñ›ýâ¿0 Ë€? Y$‹2É ES"W\’»ZqÏ™Ùé鳪23™Õ³PƒZõtWgEF|ñÅQ™?ý7 @H)…• Ù¨E}Ǿ'-ýµÅ½wa~W ‡—€RB‰ tÔ@õžÕYÏO>õË}¡Úví…m¯@äF—þáÃü¦D&Ìv¶ñµàgõÁ› &RúRH%ÿïR’þ*^Pò8”w¥ÔÚô‚0ºT³=¨ÇRTJ† Èž])ðGÅþÚË.˜ôK%jIkuÁÍýÑ;øŸ’¥’.Ôsž¶(•’^ëtÇ…v=•­Iá¡Þ7BI»žž ~æ¿õÓÏ,¥¸Ùzªuú[Õä÷ðMŽq5\ „Hö£Khq©¤4Ão,ëÅ=4ª#­Dg°;>:Ð6ï¸ÅNص|ë7ÛÇ[Ø­¿PÃ—ÞÆkq„Æèà´xäîþk˜^“òŒt¡Uªv]È–0‘²–·aySÂ<èbCÊÒ-î ¨8°!ȶ(ž*v¿í&×ë½É0&¿“£p—ƽhz/¼È.ÉlCæk"…éÇV,ñÛÒiaϨÖ(o ÁÛÍ«7=fS÷Ÿ3›_ª/D%•ÄMÐRy1~Çí¿%ê±"ÇhjºúMJcƒBçª>è³Bt¦üì ‹P(±0Ú9W#Öx€öç—³Ýïºù-÷àß•?h§Ôä@›’Ò „(Ëlëb·à«}éL˜€««PÈÞõð9ôžX~~U3RfC›.¾SùY5xYöž!Á-%‚ćGïÁì3XÞW„ÿ:àÔ¡€Ø›J;2Bo›µo‚Y ÕݬõþO…Û³:xŒ¥FtÉä³3ß­¦·ýþ•{$1Nd?ÆÁá–ºðøg†H0Á9ÌJ¥ñ>S zÀŒ^2ƒsÕÞÛaz“² €Uv M&@°2?gO'»æ˜X ˆ¬ë{âèçaò!¸CLmëª8%ì ,>õFÜä#Ý{nYµ@f&wð3å0•@RZfh«(œÚÉÎ|Ç×{õ}´ÿH4ö³ÿÅÁ+8t 7ƒ òcdmÑ­–c!ÑÃ#5Wø…¤Èáõÿ•Ú*~DG¾ª6^Õ–Ê*Œº0LüáûF<”Ëßúr‚÷!=’­ ˜ ¢üL¸}wÓ-çŒí^@Ãüì†p”G¸2(kâ†N°[gþ¤ž~X¼#ýŒíG=Ž~QZPVhÓB–¨]Í_mMðD#x ]¤rm ¢K"Ž< ªÛOšÍ?ö”Ðá&ÚßÇï»ã»Bjò•TȇÒîèlƒÒÖà¦ÐcD’² Ž‚]¤Ð-Ù öÊ¢ÏeGw_ÐÝ'ê£`yK„%fD²ŸÞñ&¢ýÄWhW¦L¡mO©|9߇PVÑxz¡û%EDgø „¯èSYˆlC´.›µ×¡Ø õŽÞ…£·¡ÞG” Á7 Ââ<ƒ€ S+¢U#UÏ…•—‚ÔmÓ»ôHÿOé@÷.IÕö³;Âiƒ"ZBö‹•ýü¿æ䌬èîœ}êµÏ>úq½|DiBöóÅE×PâtˆµèWZÚ>¦¿YÿtŸšÅoüƒÿ‹ßJ(!îk€VбJY¤°¢QÄ3¤J>q„O¤,ù†îž•ã–å k¶C·œ 7•²‚Æ“ v¼hìg¢æ÷¸…Üà+_ωšBŒ]¦ÈÄ8P0ÇuŒÌ6íÆ7C÷… ‡B!Y…½Ÿ)·Ê*²‰€Âº¨ƒÃ£h@Wdˆ $WDªrc@ ÇÚG«+“õ…Ì}5ŽH ÂE· bZ´P'2¤È?t1]ÍŸÄám)ßñ…HK‘¤¬ÆÛôeû’~Yv/‘'ÂÜü\–7Dµª _…<®ÀvÇ›J§âWQÄÚ®á%¿P¹$íÅ çøÒˆm듦BÉB”"¨éÉMyªo™Ë–hðì÷±dÔ€ÐZü—âD ƒ•›#yðŸl¿|ÜÔæ¯ß·_Ê&ÑÏ%î 4iˆy†¹ˆŽ¤©QÃj%zeª¡E£i{ô-¯ ¨j(š.U1¼ž6èü§ò E\dÅ?‘ÈÐd{2þ±}Åœ‡•”Lž’[ /nMc¤\¹’P‘™RôãR'IÿEBˆöãË ~Àkƒ[0Wþ‡HP"ñHHçoáÄæ†àÄŠoxÍnV¹N~`2‰#Ÿ*2³šŸÅÊ·ÊISQ›ÜdŸ gàœ³œDŽ Ûð<í C‘"N^ѹ!m'Ö;Ö!D•œÝh'§†ÈÎ32bâ¦"uKHc4=œ„;e(³ˆ‚BSqAœXÕlŸþZN,N@J,—>©0s1v”&ûY¡,¢7Hñ’ÄIÜ?ŠˆPj×É~d§T·#761òõwÒt…GΙqû¬@¨d¯Œö+¶Ž*>÷/©­ØiEÐÍÖÙiŠ¡µ*#q;±ôFÄ(ZëIKÒ¢ÁvGƒÑh~¸¿œNÙB•¤Žð'·ŠqŠzDµtû¬*vÜøCQPûÉj¹¹_“7 &@ìé("‹·)ðÌùT7™€XÏ ãr ’ê‰õÏô5ø‘µyT•GhQÞjaëkÒB\7_ãO NÊ—P…Ì´<æ,”<· *¾oh؆AÙ$&N|u}%ÇM“Ž!)¨e XÊÇHÅ+Ÿ‹F“·E»}|tßW¨—Y¬9(tÍ“a³Ê,H鱫¶t¾ªÃà9 BDA*¬1‹5ñg¤‡Ä®M$@6UŽ“TúÕˆI…25‰—DC¿+&P†ôyôx$W.^šþKò”ì[ÇɆý]炱ó¾ûòAB1v“ò"…žíO©‘ì_QªSMéæ=<žÙ)Þd|Üf™$Ý5ÜÎ>U¬õUÒh‘$c*3/64œÕ’ŽÅ+jˆN‰² ±ýÈÄúŪ/‘ šœäËQ „•Å'¦sRñWB©†%Äj 2plÙqŠ]Eÿ –“­¡ |7TÓÒ´Ã⮨*¨yìXd-in‘Ó(Móɺ‹Ý•ª+¤:s„[¤Æfg‚:-ÞthÒ²á‡Ô¦Å) £Фר¯Ø›^œØro×n½.Ûënÿí0¹.éŒzyƒäQy/,xXÜâÏ,ògt„.{­2b•Û ]fŵMÂpíSME6ƒ†¤ec|²_$JIþz]vÎÊö,î‡ÙïxHÒ ç#ps2ý¨æå*4qlÒP6`KH=áû$€¨7dP5cw&¹Çk ‚ÇS½ŒE-æAs%Se]'CD?T‹h¡‘£lKÝ1¶ª=_îÓÔ‚"ÅÝMb`¼—#ûá¤J=f?¯–rêߊmQ<#Š+õì¶TÇPc (u{à§Ÿlo±LsGS3ÿ4€a[i"R`˜Æ+Ê(!ù{à)ƒ‚¤jÒL ¸ÝM9B"à:®4ÍoRϘR ‘(ñ‹D«3¢+ÌiÕ:üÌ ÖÝüP†Z–·ÝôcšçÓ‹x‹b/ ^ŽüŸDU¼“Šûâèg#ܳ$j8”©QÔÃãMwjyd‘#ùüUh¦†Q=@$ÒÜ@ÐŒFoe›ß Ê£+“õªƒOµ¬ýì¸Gt1úBVô-w| ˤ{­r%E)¸í'à‘o#˜Ce#hÂëâDFaÌä/!ö¤mø¿Ñ`©Ì%öPÙ ?: ù©¥9 Ý/„Å=÷ð—ZiÖ…íùÙ§aþyÑ;]—‹àç@ûß$îšá@òšRpô%«*ÿQ¤¸-e‹ÇT^sz‡8Tæ¾5ÍÔ‘ý±] IW¥zÚ\€xȆ*ÛôÅ“j÷ϼîÖÔüs¬vô,ôÎÖ“ûÞöÖÕÅ£›B-M§0<Åm˜=­Ò$ˆÆ’ë‰iŒÐ9î]ùJ²?Šajçù' DnôR¬8G1jÖŽA&‡vT¡èì¨ö¥¥ßÖ»$óLN¯»ÛoA=QíÕ;í*§ô µuuzï-á&íÝçŒÉNj7%QFCœvP<4³=#Ë T—–Í^Äé kgÇ+XBÓsJÞ(ý©’ÚgýÔR<bÉö‡»*R?í vôNFùWZ錇Z^¥üÕl+{i4n#á‡Fm)zøÍ|ëyz.ÕßróI=~¨Z§ìÆe!¢š£R j¹¼ûvuûÝî©/²?INîœÑÛ–­’iºÂÓHu°òŒ£9€T1Ðç”-™m«þ—ÌÎ7Bk ›?*Å£oz¡:Ø V{c{e²5dYAÈ’ä\Åxe%ž§É¤g&‘–ãiÔí½âA_Ú~¥r“Η2P6ImhX-°ö©¦-MŠ3Þ(fŸk“Šh¯_QÃ}ûi—Ÿô˜rHN¶b#¥M waìˆ/ýœäeTo26–2ã 8š¹`!jµé£¬ËCƒ…Ѩj9§¢EÊ‚†?Îù¤&iÃb#pÿ¢š”õ©‘à6Ë\𩡝´m+Û©ªt·µûu³ñUo‡ef2P*q=)™^¬µjœ›‰™àúJÆy1ÖzΈp¦§Ð3¨%s£R…2íÚ•<©TÓYMSjÉö£ò6HªÌ—N¤1œjJ}hzЏ„Öö¨ tšGµ¬ aÖUçiPëÌa^b6™jQ´“Ù;Ëúä´Œÿ•žŠ5Ý®»¦}ŠŽV”B >"[©e¸é ™)j"BEψ=ÙüWfBw1…Q¥àF?4ƒ %æÃI¿ŸDQp_–îŒD@ñ· ‘=!ô•QéLAÖ„vîb„Ê­qÔ$)-Rêè1Çc­ì@ÚQ §9m-.Y/§¢ºÃÊ‘.ÀŠà °<±'¾uÈŸ¸Lƒ²`veïeö/ïå-dÂÕüŽà²²šáDÖŠÒ‘Û:CO<²n¹í³-è?oÏþ)´·é ‚'dT±õ8vyÑ;ê9¸Ì6Lç ¸#:t–ˆCY¬«|Ý× ls2kñ²r1ÖôP4wÉ¡ V487¥˜¶¶}=ÕýLΰKZÖ ò]»ñÕ|ýÉêч˻?‘0¡5’ûXMK¨…4PFkºY+_Lˆâ4âä,ô_’[¯‡l|ÉBÁœIÚ‰– íÍWÝ Ö½g²ÑXÞroÑà‘¥T;P-\(Ǹt²=”è^tèÈJÖõ倹*¶„ÙVè´êSø¿Pi0Ù9çõšéžFoøÙçõä&= ”Qê¨X´F 7 ·ÖýÁhXLŽ€¨#̆·ç }Ñl^U5Àë/) £>¤jÝ}Efëº{A·FØlÖ® \䘡%*/6m” à'¡¦cº}NØÈ·•â‚nù@ê êyu|_™ÌM•Lò˜;u êKœiÚtØÀÏ„(ùQl¤Ñ' w¶ÏËÂîݾ‰NvÁd£/»¼˜/!ØÑùHS|h%Ž7Ê»çÿÖÙ‘ƒ¥X¢ë®iÕQ­sÚêúø—aq› ˆ¿µ­z9F2±ÅçÙ¤Jí¡¼ë$Ì å1'¥(p5A¶ô…fŠêØî%ïŽÃâ†Âë”4ŠRL=š"@Œñ”Ð9:ߌ¾hO¿¢ð$' ÍreÍ ëpá{Wÿ®^>ÌZ¶>úóºØ|ìnyð+wø®¨÷MlÖA΢®ÜöT¾²S²u^Û¸»ÅÀâ–B*&†$Õ@½<2Ñ,æbO˜ÈÊ—¨”†fð,rUµÿ_ÒRÎÏ)bwÉ~ª+ ,²¯í]ÖÃç½ÙÔÃK`[Ø­NÃQ»ÄCH.1¾ýòß×÷ß‚ÅmÛÝ1/zÐØ²ÁÑGP>ÀÚDr¦šÐ¹ iMû´hm…Э ª÷ŒÒÞíý¨ÚSae¤)J&í9)®>Â¥;›Ï‹Î•²ÜÃÊPp³v&¿R~ªóÔŽÑõ>–­³kõÊÉ­à&ÊÄî[Š*öï)¡L*ÓîŽN?q÷ÓkµÝ¿š]ü« úªÕS™§¢ªMçþ2V‰PÕ}íûˬåóû¿°bn‚EÜö¯ä[¯Ý¥‰°"`Ò*¹¬¼‡mVÑÝZŽo¢$VYìYêc$²¶½­Ä¢>¼ŽöÛFj[çlwcqxÃÏïÊ0—HPÅ#(ÂIßÒsðÁúéÑîå;Ÿ^¯œÙNûÉ¿¬³3 [˜³JRáC½OJYìI©B»ûÚ?`¡Ç}é0­Þóû¦½.ó ” 2ëÑ ¶w\îýëB–©öè™ãŸ–G×òÁ) Çõì~¨—Åè2.êæ{*ŒIlÐIÅ SØæ#W!ò3>“û>ÔšFôÐ<=ÆâÕî †"ï×aÓ©ù£›*ët.}Ûåç± )qˆñÑ9DÆ“å ÒE§ûú÷H¶È\#ÕYP¢Éçê°ØƒåTeÝÞ!.,PebVíIaÊÅÖAº‡õì3,¶ŠörßÍoó 1̳W .¶A–èH+L4CÅG/Í<š_È»v¸¶ÕZ;sÿþØtžZ|„²¤{ñ;aô¬šZM¤,ƒ¹¡`ªÅ!Àzý7¾Ç\G<ƒ%npÇõá'ÂͳþYÕQÊùyõ»óãE«-îr1F2 õåJíùœµ1ŽOl’¸B% ¥Û»H¹ª³éÆ¿v‡ ÿ+~,šž™ÿÄçé²ÛY[ß½pûÖ ÂÓ»˜?ñ­ÐGý™)1#•+{tW<ñç~øb}ŠF· ª4§“ >N6zã_=8#åI'¦èhþ€:ذÇ]a²XCó…ÙC¼¨€Žo¼çô(‡NËðᙊMâñiY*¯yïŒÓ3z-[ºòµ_ì©ÅgË;?•~¦NΆ4xå)ÁÚúéµíóŸß¼¶\¢}=xEm¾ª6ŸÄìA„£.†ølN°£ýyÙðï‘n…¢CëuM§q©ŽZLš‚£L2¹B:Ÿí-ïüªß„r¦hzì} ¦§Ö&Äã=<ÞAõ‰åúL0;η©A¬‘6©óžß“XϸZǧéy¹«ŒQ ‰Ú Ó×Å\z õó«`Ú"ž&0 ¨`†™çQ?ëâÿ#÷ξxœezY$וÞÝbÉÈ¥*+«+»«ªÙìnv±)‹¤(‘M-)‘¢4öÀã±,cìü`ó``?ðƒa`ž ?øÁÀ°ò c‰Y#ÆôP3ejšK“ìnöÂÞj¯\##îâÌ*Á&YÌŠ¼qî9ßùÎwÎ½ÉÆë"]/F㨳á÷ßöƒk2Ì„J¢Î³rý·mü¸ ÷ÄÞÛa²£{/ºì F}(e¬¤˜òÈîûb`‹¡©©°Vw:ZÜ÷³Gqç±üð@>VÙšHWÌòy'¥×K2]3ª!†÷ŠÃ{ª}N®\rÂKKÓ eä#,-C!èO,BB¿>(ëe”–"È`EB)!´L6Uº![O ³,ЇaôŸÞ¡2’éiÓ}Ê47Š£O…Šãµç½hÛGßw£û¼B^¼YeªÑÛ›º±Q…]ãwEy +Á'iÖ+Æ÷‚ñÒ…üè@fñÊwx]yQæE²þUµtÊ»=œ›:“]té -N¶ùà½Pm)öðIðx©”:`Þa{R&:=ëmˆ–¿(Z[ÎJxmï장Jè–ˆOEÝ-'ÅÞ0º&$žrôoÕLÖ_uÉy?ÆÆo—™&«O¹Ã_¸áÇB wTrÆŽnhc„lzÙmžyÁŽ®Íö®ê¨%t×,]´Åv°¡œ˜¿þU·ú\+¢DêFp¥4 ì÷n gIe¤7’<lˆ;—lž µœý«…hÙñ ^Ú?.vÿD„\IÞ íã Ø»Îd´fûX°»õ7§éóÅt†×by8Ýþ%–Ô²tÓ;€9J&xÃf¹ø”÷³`€h ? ÿaµÖ·ŠNyÝ‘›ßѽ­ ¸Nº¿ {gc¥¦ÿx„ðõ´¾NOÃ.iÚ0Rw¶ôêK^6üîOÝÞÿŒc]Φ2€˜ÊÈ«DªSúÔÓfúþ¿Å£lé ·üba{ÑRWÿ¢Øù¹p…1™Ë·E˜#’Þ óŒI2¼²œ$yC†`¥@BHMæEA6E²®Û—ýé+ªµéÉHx_väj²° ŸÃxû=Œ/‚6*îâc5‚·>Ù¼,[çüá_ŠÙ½(ɤi”£Ò$§3oú²÷›¦ÿ¼ÐƒÙûÿJLn(©BÒÖ¾ #íÁÏÃì^°¹ê(Á¬ Ä„†·Øl'5éª+Á¾¯Z*^s¦ozWôÚsV€=`ŒÚг¢¶QÁ"ø’"‰èЋUM¼ä=pLÜ´VÙjûúìàòðcöMËÛ‘ðcØD’t¿lÿ'ZùÙûoJ{f@ŽQL#¤ ! ~SŒ=¼Åq¸u íIÐM’Ö¦8ò]7ú$Z~±qáoÏt3˜H¹Â!TBÄT™˜Ö–dƒ¼A¼áÉ= ~¸D< `e™Ô˶,•‰D˜Èh^` jnªËÿÔÈÁìæóƒ÷”(è»ôë*=+é[ Øj x@)âßDXÚGy„è8 ºi²óªó´ê>WˆGÙ Ø\![Y€|²–ˆ=>£÷‚W•2){Œ<£¢.xÅS~Y ·¬ŒrdYÂéÖüìò…׎n¼¦·%‚KP¼S7·_W_ÃO¼9kLÚÛzñ7ï¼ÿÓÉÁ=•ö(q §­âU'R`^¤§usÃÅ_ ð„´xR?a4Â…ˆ6X[Ä @‹:Æjc¤)ï0À+Ø}…dû()#g¶°ªÑ×q«^~üû:¶¿à@`.ºùÊoý³ÛWÿèÖ»Æ¬Ø oOÉŠÂ ˜õ>6ÿåJÜÖy•zò9¾‘ÎA“çˆÐÈ~ÐRQ%ò—œÇÃc:íë()G·iXQ/ËäLºü¸Êoöo`#ÂO}9¢•ƒdxû…Û+û+äQÖ‚I¢¦ÒÞÍ Û”™¤ ¿é„ë(bä`jÜf—Z"vJmJݹÿ çXˆ:&Õ«YŒq Lj«E…¨úBtúJYà㮊¬'Jç‚I@¡Q = ã€\E=¬‚„ß"x `YEá·´ ÔJi Øk€ƒ› d³«”© ?^‡cª¸¨¹ýL#äÖð\Úûß K_ Ùj3E ‘"ó¼Pé ¶€)›ÂÖ '>Ì”Iˆ ~p²¿²»¦{YU¬Ê“¢ön]¡t³Ø¤0²IŠ6uµódÉ’HÖež ÀÉŠL3>óJXz^š,J”ˆu²##l(ÅÜäíÇœ¡ªFDMtÕržñ#çx© ÂïGA¤—Võ·¢÷ˆÁl‰–ꯄÛóÌ¥øÓZAS)5G•§bb(pŸö!’ñЇ|Yºœ^þíPHAB¯â2±“¡*éã¥DžÌüTÍ%Ñ1sÓ¶$ÉMA¯;¹A*v5çT›ssÚ¯â$k÷*Zý„ÒÜ€°ÌBk›övw‹|ªT‚—ÕVÙ%™®'Kç‹$Uɪél@ªi»-†ç;ï–“A¼ù5Ó{6 q TÏ~Å´¹°‘°s¼ˆ¤Õ"ä x0;²N`öTY8A/u¾0 9¹;ÐÓ:JRe1Aµš+½Ëûwo¢eSÉzÖ¿bóÃÙÑõÒNýç²pÒ.^áíDéê[Ò)>÷uÊÆÞ—Åöóf“veÿ¯Ÿ¬÷£ƒ Ž1·½•ã@RÐÏeщxðXˆ9úPB8‹ÙU\Ù¨õ8ˆˆTjÙr(ƒó˲`ÖÔò3ég¾-ý0›„ñ‘:áÿh©>£NF,ì?QsO( .\ á(ªW̲Vw5'÷5u„Cå€Ü×:D†j6(Xwô£…‰Õ@A:6ÉšHÖUç3rù¢ê>éM ÐwÈþ…î 'ìW¬—¼?Þ8.JléDÕvÕÔ¤æ\Y5øŽ%ޝç'óˆ†EÝ8æ©°xw2ªÖ!š0ĵŸ\®µf)Òj?ñwå™×ɤ)Zô#JLÕßÿŸŒ¨Š*IgrJy‡²ÐPÐø3çš»<ÄðI³D¥Ít²ˆËº²1‘úš%¸»9ΩjJ©"e2k‘V%ҼѿbÎÿƒ2ý¬ #­s!S!2Uî÷~´?Aµ6 ©¯bgsâÊκÃâi6Ï‘æYZùŽ“Ê0ÿ\­Ž95tÕ‰üKz^mãÊ¢™– ÆM›&v‡ôœ9û÷Íú«Bî ±'ä)–Ý£ÿ5»ù:^¦-.Lžç¥ôJôÅmï ß¡U¤.†¦Ž4µ–Å' – ò˜cÔœ^æµçÅlj%圢k¥HR5D_äœåoNÔ#GQ5z3Ù1ý×Ìéoúèt ^Ò¢r¡ü(;±{×LÖ§÷xŽ$HK9ŸVѶbü/XZÕ(êŒ(úN›8N²éhWÖbI- Ä1.Êw=T9®æµRûWå„‚uuqé0dÜJ—/ØÆfó7\z>ˆ˜AR`I\¦«OÃ‰Ž€F£<¡šîie•°¥µ(|:^!wÅ¿sÊ»!V¤ëµ…®6ÏÕA.äSíç¹”’/‡z2PCÏ{j¤pŽ3ržPÚ:n8´/ÉYµòJüø_÷:6Tà ¼(&Ôÿ¢"¬}ÎM‡žŠ H–/«¸;yô”Cš¨Tê¦ðSžàQ0T´FõªÒ`™æó^Ö^Vb!Øæfȹ®úþ¬x §ª¢î(I`PÓ=qýI[«jéRtöÛ®õ%+2©G¢„fÈ蜈–HoÝô qæÕrx#¡[2=ï­×±–ŧvú¨fʼnªé~Nx®h¹»*ç")ÌÙ±®äµl Y?A®nªyÒE¿† µæ~à ÖÍ`‚Ûó)íZ%ÉêçÓ§~go)¨h aö§¢8”!LïnðŽDS÷Dóieœ2¿YŒðQ™&•’ªQRsŽ0<Õ—yõ8î€CÕìŠy Q%ŽýÏò) yŠNí"ʼn£í`×}™YûJté;ð¿6)•:—‡8¦#_¨(uãaó¹ß+®ÿ¾Ÿ~*¢ÕÆå4<²÷ÿ«v;‚Žx*ª- Ó$pØa¤Ðgç$è½E°så#境®¥OÝžÿ+æ17oHó0¢ÂQ¿Nc}4ò,TÚ‹›}›çÞtÅÒgÒ­¿ΧYšw]äŸþ4ä)~–§_ú®¸óåÎÏD´oý®HÚöú¿G¿„puÂȨ§“3v6…MI»]ŒîH;dík7%—)¬¨©Eui­J•àa0@™›*©£=}¥ŽC%ˆ‚ЛæÊÆ—§Ñj™Í6ž¶{Ÿ &¹ôÊSÈD%Rï d³\ó{;šìlüòæÁ™Ýý#43ºÿײǾ4~÷÷Ää&Jl`Nëæ¥¤óØlÿç~ö©ô#ásr&Ͳh@HyzY7øórÅi Ï5ÖQæË‚7W¥O…3:üâR@zj¡ûW~G®¿6 =g¤ØAˆ;Ò“MŒaGÚ ŠÛ,§{ö™ô•è½ÍnýÐcÙx<;ýùÙö_ØñmÔ58?¨eAóÉõÙÁU?ùDb5ØOŽ3XœFéP…€I]óQÞ W:Ì®´i:j4=Mži˜éyô§¥né¤Wä‡J‚ ¦¾s¥yé;…ÜqŸÎ³ØWsÿúbpÏ&­Õ°mr÷' Ùì+ÿÞÝÿ9ú°ÜŠÒkKjœñOs3Š;åð¨R˜Ø4ÛbúÀO¶…(é™Ocp8&g9çëVˆ2”io ©#4îžÆš…âù|Úìƒym1ð~&¸ÝUTŠLܹ—º¹z>?¼aE7Ýø¢ÝâàaÜ}2]ÖëÔ ž™Ø‰°ìö;Åý_DÙší7m<ó/˽š+gÆwÞtÓíhùI‘]ÑŠtãrï—q{­˜ìúÙŽŠcQ‚rKIöƒ"JMN-’­øSÌ›ÊzFB‰6-ÓÙºŸ<òå°:!MÈ‚ŸÓŠâkUÇ›õdãk&Y&öF “t¥j)›ì£¯HwE¦Èo¾á†Ÿ6zçýåhÛœû]!¦¹6»óÃhõ ³ñÕmÈÙØ~»ÞL{M¤=9¹v~Q ïò±õLúHµâàçÊPsÍSR†2’ŽPÕñ4"µòøË“ý[“ƒ[ÄHZ¶Èv‹í—Šî:¤³_KWœîéÆ*è…Î0g¥ˆÝZ¢† 5K¦ŽhŒŽ‹ýDyhÞüHÎF§þyˆz2j–×ãþe—ž ¦g&wýƒ·uÖõÝÏ…¤çîüÐo¿§/[@”Y}±ùø«£~ßï¿¥ü€À©[HN„œ¨_ò)‰Gh¬INVbÒ\†š5Ùiõ’ÎE?º[>¦)~£oºWBcK´7`­Ó 1ÍÁý|)Hy%†âàÃ0¸;Ýùˆ&¸kÏ5ν, ð e‚Ž¡—…CÑi#>‘"|?A€|¿{ÿwöÉ÷Åì¾n´U¶®ÓµàTö7az(J>Êôt9È`3°7Éc;EÃCÇøÂ ³|££ýOPI•-B–G¤@Û¥ËL¨nƸÀýøá»þðýlëµrR„¸ïT‡çÞ6mN÷ÊáÃ&¢µLG”)÷a…÷#)2ÄÍ¢ñr¬Ž¶%Ö¢°ûN>þϲ|(ŠÌÍëÅdЄý|DÅìm‰úð-WV’}¿æ¬ª.AA×Ñ&C#­r:‹Ô‰F_LÙ@ÑT|z1’(©´`Ã…vÒ™¢P憪FŒr”ªF¢'•QPùˆRá«vÈS­ ãÖ¾B)ŸÜWÃkÃÿS°è¹RÓÜl}ý :ã#ûùŒOAñÁ„ñ‚I 9…4£2iÊŠŠT¹VÕ !ÔHnx!W"Ô êÉj<æ¾ØS-3´]_PMãN@-Ô6¢™~<6úÊ*|hÝhoòÑ¢4õGï‰rßQ—짨 f| ºz¡5\¡P8<í¦@¯ ÑåÑ«©Ç:¨V½Ç+ÍnÕqƒ¢‹Š,rú0|†¡ˆÀ7Èa:ƒÎó µ*â´MD‹Ú›ª_èÓGC»S~vøq ¢«}1Å 51Ÿ³+ÍwFϺR|Hh!ÀÄB¯ ±?%r¬j=O¢Uƒ%A‘7‰|xÜá ϯ³AÈ·ê‘B‰ØÖhÏ'7ƒÝk}ãÇd*¥Œ‡yŽ­du@IæÂ¥ªÆ3ˆE8¥ŸTÌøø•<æ,1R„|±\=yÂqãH·“« B†YTcù»6prÁ‡Õ%ÔR>†Çƒx‹d6 »$žr°ÈÃø084ƒ™Q¹šÝqûWGwþ´õú›ó›ÔâqWbªSftòž]MÄHDab7rNܽ•ýDà‚®WaË1­„üfS,Ž‚b0䙯ˆùo@rëùL¸NÐû 'T·Ñ&4ÿGEãÛs!GìVÑ@i}8þè»Åý·£x)ûæÒʈ<¸‰Õì)‘™t=Vâ¿´°çãW2€/zYJv“IàŸ0L¬!Qø(- _ x©Í%·ðÂó}Tìù>É<ºK)èT.`;HXbZjs(Á1¤+zmO”èg»“Ûßù§vÿ¶ôQö­Êÿ‰¬²€K7±v~QGŸÝC6h4†'¨q=I'v"‘eA×+PÝ$ hÀcѼ¦ ¢wQåËê‚i‡qN᮲ŒXŒ]ð¾c>mdEi Ø?™~ò?èFQzjüà½æ7œ¦¸Ððô >|÷5wU·žBe[Áǯ1Õ/XBí¸¡±$UŸÊBr_I—–±¯²‰Q ‘(â|­˜øn¯!‡ß¢­Ç_$ˆT ½¯Æ+ôÚ@êË\©ÃüÖ[öÁ{X+í]JO?Ó~ý-jEi{ý™«íÈ\úÔФ–f|xoAuP¤|¨.˜Îé ] äk&NlOJ#)= ¾ZYÍt«;`Ô VÛçÞ_1h-í—.i§’ºõ˜Nx)iàùœ¼dRôRFW¿g½‡Ž_‰Nmu¾õ3f 5 >fâ£ËB\ܽ ,¦ [ÝÖs­ § 3Wñ4r0•k¾2Á¨Ü«Øàj2ä't+ReÌÕ1?PTƒ¾ WŽæót½ˆšEL4³×”{x{zóÇIv ¯š}¢"ûü&‰¥KɪP^ÐeQ ÖS¡ç²Nµ-×¥ ØeVLoÑŠÏZmtëUŒGÜ´UMiÌϰ§^x —ä[£xû4b¥çé¥tOÅ¢®…,í>kÛÁíòÁ;ÊÁHVèÆÙ—@aúлŽB~(&{ÿß’GÒxœMziŒ\×uæÝÞRõªºz#»Ùl±E‘™’¬-Jl"ÉŠ#ÇÆxÆK2Á`&äG€ä_‚ƒ,˜É‚ ó3ÈYYË‚#;ŠÆ–iÙ²,EE‰Å콺ªÞr—9ß¹¯H „PUýÞ}çžóï|çÜ—?þ‚ÐJH%m)C¥tâ¥AI•Kod¨…(¥B)úÑK#d)è›è ‘ŠàƒVÁ—Jxéhœ¾ºà…L¥P’¯Ó® ÒãVz„t‹§Õ$î•ÒH•zOÏ¥«éY–îr&Öâ«¡•­àÿ`-K¤Òd[^x§DHMþä Âé %SºKãƒÊ ZSø@wÑ?Ó³DûkJØo¼#Ãø+=˜–•*HZÙ°§Æ]ÎâiÚ`G´2‰Œ§ ‚e†"ð,Ú›¥õk²_‘+LJÛÁdBõl?ý ‚×Wä‡`T穯ҚpNH¤Hƒ0ä.Øï'JÒ^SzþÑ¥ð—ºÆ>°Ôóú¼,Ü {ß‹õé™ô#ý“eRÑ"Û!ûmÍ`³ô\ YôŒ´ÁYa(î×Sè)èìsìÝ•RcãÞÕ1x´1½'¾Ja{芷`¬àí •­grÄŘÜE×ÓN[ç´1¶,x•7 ès¼l z”“ýäúNf+vEÀr­Cø-î6øw2Ä3ZØ!ø¯ÿij.Pðs²0–´;KáÜ|ÈQ´M3Ž6H_àÖ_SÜÂJ"òg@¼(î´Z|„æ p¤€Æè7ò°V¿ˆ…HÑã´'û±Z`÷⟀½×*ñ…#-ŒpÄ©÷ã_GV'9ù9ñ‘’ô,u„îµXœ>C‰ŒçÒ:ÂhøœÂaa0l YœP’°7É* c$Ýè°2Y@_áò ž<`¿â=9ªBágÉ@¢¯ÞÇ\¦‡Ê4ï>ñ<ÌÓ9`s’Prø1ï8Åî¦8'L«0 >AÒÑgz<ò‚ÜD=…qŠ,&°),hè*xž“š>Àùô$$8Á†¨!ó¡„‘ a¤j¸)C‚EÕ¼%}ÀæÑ–'Ãe—ñnÈZéꉊkRY3‚¿•¢­mHÆxYßÎ_ZpÊ“m}Ñ Jœ–„…*žzÌF˜äë±'v2ðùˆö@>¨Dóœ_V‚--Y襉xP‘ˆX6àô;n²ú€—Ì<+x¢åèÜ‚M®X.Ê¡­¶Ì®ìvDJ«éõH.ª¯d?(XÃ@9Äè+Ö0H[ÏVµE ¦õP €œÈÃy,Ç\ã?€JjÄö–à Îö·<ÖfV‹¶?#l0©ç«§˜dµ嘋n(x¸xòtc¥àLåFÞN%ŽH=²Ë®&¨[fæ7d¯G-Ž•—ØÒSFs}áß3'%©‚ñ¾qÐi¤Ö(ØãäH˜ÔíÞtÅ9 ŒÑ-[À_)ÊÞ21¶o+Š;üOöüEE!«o„Ý‹”'iÒóf º+ä[~.#'°(5]¨¡L¢âJ&ÝÀÙ‡ß):¸œìÏ×½Ê15 co¾&žäL$Z Y¢À·)gN›/Ö¬ø“ùÓ_Ro *0Cõ>ñ‚¨7ÜÆ›nëœIr/‰â€ÏçTw@ë)aù¡¤¥Éi:r—‡Bi`JçªÚ…¬"¿k”ÄVɵdÇ"xQ±a¿(PS˜ÖÝê@"‹zÏuÈq¼“ûh¿µ„ÿþÓ§½ßô»gÃæën÷º™9aVþƒËæ@SM%£ò„6ë²~`®«Ô"!ÃlÐÒKÉ C¡p½Ø•âºBÃ<ÏSPhשà\©œÔ,KV¼ä4£T{t ë^úsÝÊÎ]‡Ð{úe/öT}Sî½Û¬ŸÕý;ÍÊãÂʈ9¤ÒôÐf¬H]“h$nvS)æJæ\®ì‘Àá;€“¹”±ÁB¶ùVÍÆ"Ëtò†¬G DÌ–£ÑKªƒ|¥Û2ë~âeáÆÊÅî»ù¶*–äÂ1Ñ]!BŒy Mܳ§!lrŸ€%‚ãJ´åÏB¬â¾L+–Däš‹ªaûª’€ü“Q/áÓÕ’†(±¹cž”2‘ÔÕ¹2|€›:1LO¼(êUnÕ—þUØdvUu†ü€*VqÎ#Q3[z™˜À¼‹uÜIÁí¢­­\»[cø–VÆxدX“PaØôQÉV­‚õg9-š†ëŒ!‹}v'3®¹ðRçéçu³•„q}å;õæÙ´@uöûdIÍÜ#º ”°0•kAcijÂ"ˆ,£hr€ži÷ÓÚß\„¨«B_–Gª‡P1¦-UQÓâ¬7è«–Qا·"(9uÚŒ:A¨ ÆGýÿÌK~ûÍæÒ¿$´ZµMyäeGöïN–‘Ý}žû2&RîÜ•%e J1)Ǽ®ÐœË䯕ŠP̦Ôeaì™ÿY b*ÍŽÂ0ÍZ´<š´tËÊ-¨´\Šnâ6#òcjôž~)”—íµÂæ+¢ ÷¹î!×9hf×l5–é‚HçpaÙÕhKe0)´•R¡FC cÇfŸ¡ÂýZì…¹€z^NmÃ]” )˲Ÿ N™ÈΗH"BQðM¬8|™ŽQ£? žz®)·ýîS¾W]{9›=‘¬ý”Õ=ªxåµ7ÔìI=céˆ"f¤´ÓŽ›»oËÆƒõÙ™¾$#‰‹ *¸kÐÒ¶rÅ®CÙJ<“­"hC$')°Ím)dUË­šågiö¹c§!Íc"EwNý–Ì–•ÑIsmxþkÔðvÖžiFënçLÒ[êþt­ ‚„ S“yñ‰žìݦqŠâ»†À¢N]h6)´µâaÚé{V}àlÝk¹òŠ˜¿:D‘µ:{3Ò7X'¦0˜´Ó;þ‹õ¸4½»TرÃóv¼¡ÓY“¤Ä4ÎU>;œ¬~ÒwÃTÃö–[¹VVÅ^›ÛdÓrNà6™ù_€ú<«—¸ñg¦ò\ÙE[mCœÆhщ´nó§¿ÝˆÈEZNU}ïèÏN6.“g“¼Ð‰oön(•äY¯_«ªÝdñþÎáÿêÒcASŸµ'“}è¨Ë-Œ‰äÔCL®95‹dÃõ7“b}ŽÇ}kô3²>N„¸VÇF †$z8ŽÎÐfÉhæÛ„Ìî'R¾ãsn´•KÍð¼ðcdÎú´ØßL6\°fp2;ôÑ¿ßQÝÕ»J©®y§ w[¨yºFjkh[+§,ŠÁ{ۤʷ–L;nf!òš¨øk¬ÈSl·²gZò¦™!tk ù½¿Ö¬¿ÝßwT×듳ÂtDº,òý*-d63Ù¼š,ýh²üˆ«·•©µ(ƒœ%ÙKb@ê.û##‰õÙ6 Hiu;ÀAýE‹-y´¹5ì¤o›·€LÈZ˜…v΃uËævÙ¶ýÇþ¬ºù;Sv¼þºÎ÷«µÉ|9ÜÕ½UÓ]–i×ù±Ê¸ßyyìþ(!Rœ/5©~\Ü‚oCoЦ…ikI=ÔtªÃÂRGAG"Жڙ=ùŸ¨2¹µÍ0ÜÞ¢Ó¶3âtëÞý«¾Úuå&± «Ö•6½Å#Õ¤šìmîýo2”7^©7ßè¬>jðzÂ^N£sˆ[Ø–²òŸÖ‚ "ûÅG¨È/ÆŠ'Ðdžw©”‰1F•ϰ~ð|NZoß²?6ÂÓ@ܪfîã ©}SPb4ã‹Òn„z['}':ù¡'U:ÿ¦1©ÉÿÇ&½SéšrV±ÂGóHÞæeq¤SÈ0@—k´©˜<5+>H,ÉBp ËÀÊnj?‡CÓŸ°AD¹âÄNn¡QLg·ùCnúÄ<ª¾úZØaÖ¬xÞŽAx#“˜àaÚÐb‰cì[ªH€XâDFlâ E;å¢6Ÿ&(¯Ü,îÙ¹GC3Âáee"²È»!4#¿ä¶ßv£‹io%ë. o¾FÅ+Ÿ?ú:*[Dz4gG™9‘÷0“óÔ¤d$&ާÊ,fð9´óL4¹\ÅèOÊšvnÀYÏMJ”P5€ 3“*¶ù~È„Cþͼ!Ó:¿h Û’T¢q²¡f—v”óM]záB½ž• YMÆ÷ï¢h-xRSý"H¤ž'™Q*ðð¶-¾±¨ YŽŠˆœçÅ×'Ó샔Ú¦ÌàJ9aœÐ+Ìmˆ«8d?ñ îPG‰etF˜yøOÆW_3”¦úr½~ÚˆŠŠ±HÃìýÙÝŸ¯GÅ1í/‘{(Æ”'E‚$½Àب”0Ç£½DW›ðØ„ü^Jç"i{R·Te$a65)Á b‡ðÓ2|[À1u^M0‰˜Òh;4˜ð+ §úƒÿ£ìž˜\{3ï”îò—'Wÿ_–Ew~wçº×3ùOÙÒ ·ëªa¶ö´X~BÕ<ØA/ÀÇy‚˜?‘¸xì¥bß^q?ÕAÈF2Ϙ™F¦ª† ­iÜw8ÈðíI U‡ŽŒž!Sc{㥭ïÿ^ ŽÕÉJ÷c_”ƒÇêõs™?®þCµõU€b°6Þ¾¡3sOoáî‹ßö¾êÞý9ð'Kn1Sâ‚h@Ï!ôíÙlk•,=Ë”[f?Ï“In³0—º£l;8uuÑ'oó%¹pò5`×9$MÅæK4yïï: §<þ›#¹Ú{ü/DrÐ'ÍågÅî¤Ýö®éÌ¥[ªñ–ÎöÁ·ÕºNûfáT~øEØKžç…‚! ø8’ù›R5`Úa`œ·G´ƒ<©Æ‘$V:æ>ç ë#ŸòÈsáMÓÿܘRc‡j¸õÒï‰ñ9*Ëý­ª÷@ÿÑ?$Kêáž].fËËßp“«¦3¦¼EªL?ßwt÷êëéÌZÞ;8ºòbíãéÊGj¯¸•fÙɳ)4˜‘’é€4¡ÈêP´sZI#~@þ˜ðÜ›O…¦t_¾Â1fM”n>•›ºãò½gÝÍï6{×û÷ü—䮟îŸúrû¦™½OÍ{ïÚ÷¿â÷Î-<5²u5ÞIÒ¾Ö³rádMë4“°õ^𫦶"[éÿ¼3yË–ªã턪ªMäFBË¡‰?CEE'"GDñ,Ûó¯ö+t„ásW ç8¯PòР/ 6&RÃþjëBÇØÑÛ5¹ù–7û>ò¿²C¿àœQƒ“fÿ‘$Ù¿úça÷Ý$Ÿo(å}C•[«®YxT,=j«FÙa'ÛÚ¾ðF6÷áôàG|oÕ›PñmG†ù¹NÇsçL:>³vH²iRTAêvØ{<•s·®øP‰ÔEâ"•. ªãäév’Î`ýµ¿v¯ªúRšeÝw}ª{âd³wêb©^–öòäÜ×Âäj È„˜°4*k|×'+3'?OM]Qgò} ý£¾Ø/ò”¯p(YcJôBbªÆû¤ãiSX 5 êáØÆ‚Žâ´-f0Š µ†ë 4 ϵBŽ­x@Vß{¶¹ò 7¾äœßÿ¡ŸéœúmÕÜ,¯¿Jd•Ï®¶^³£÷{ GHˆT{ׄ‘¶7ùr0ûTï u;~÷]™-¥ËOfw>L—}˜K×g©†êÏu ˜Wte­)bó8*›¶Çœr¶ÃwNAÆ8Ô‹µ˜Ï‚£ì”8¢²ZTõå_xŽª€mÆÎ½úsaçû¢Ù¢ŽXwVC(›ñ¹¤3+Õ@¨¾ã4ÏšrLŸU6ëý0UYºô#®8"ï#Çòù1C6*Ç KT3©X 9ªU_CZb6å0Ý5<Ð6íÎV»g;ݪkzö1J _í‘'iÁ,K'ÃóÄœ:ë;ÛÐö)oœ,}6ÜÞé,<è$·¤K'©/ +OjùQ7' ˆsjÆ1]!{p„TÂíÜ7j‘sׯ¤,Ÿð‰vœ& QB’+hAÚŽFgÊSV—(;¹þŠ÷ ÕÐzû‚Ü;·}毸y#5z‡¹J}]š4'ž.wÞá7LÐÏ¡\RèêLßõL2d²}­Ù]ïÝñ°­K™Ìxô™lgYüúfSíË%ÀÉËB„x€…©¿ˆ üt†¬\'Zxç+ŽªÐ)TÞSàˆúš F<¹Ê’5V§©£­WþïäÒ‹:ݧóµdæ!/³ìŽŸHçO•W_Qå™zýeoûO|a{·t®IS%ö.6Ãó¶ºIɤdZxLôŽí];«’þàØgäàDm1ç×YæˆIORðCLk%R83Ýš8á$‘ôžã!g<¥æz× ùTËCøÅw™¨ÙWv<¤æÝþæÿ²ºò<:•ÝKùâcMí’…g’þ¼ê,ZµHÅRÕë+ÏR^äórù!g©nŽÄø¢/¯Szj£)Ô«lIä‡wÖ+ç÷.~»XûQS¬y*Ä$5’nÂg‡T›­ÈÑñ½4~å7½bmB 騄'ü©5E]Qí°A_™D—›oM.ÿpféøÍ—ÿÔí¾&ý˜Te28¡ûdz_v½]1 éÅ,ß±þ­ß$š•*•%Ý]®7Ïuzûídƒ’0ëÎW“K$´É“ÁñJ¯¤,™?Xo¸R¤ ¨tIò±Y‹× ¦ ßÀA!Ö– ŽPòZ_©´O‘šj>q@Ãůeš¶mÄ"I·ßÐà† -޲÷f€5³£3_ý’¨·T2cƒÑ3k~ìç7^ÿòÞÙê.ž2Ýuw%Y<9^?K½§ö¡¼æš=âÊ>2’Ðb:É_î?”’¶ÖøzÛ[â«ðg²/Yx°wä?Ëþa¼;š@‰‘tÔÇÎÉÓ6 EÍ“]›ÄRÄH¹‰æw-•^rýú«›ß¢†å|h¶Š…|v –½|í‰fëê¿)zsIÿ 58’,=l5y÷‹Fî ·AÌ/õ¢éßK¿×“°"ëS,ëÝw}y9鮸¦‘DøÚ5ã ¡™} Y|8Y×vDÍf­t^ß<“ÌЃU©f…YÔù¢,úª B0£ 'úA ÕGþ,!Í÷¹ bŒë²l)ˆWôï|¼NŠHpïCôŒá¤ã!dÊ/3»&žÏ&L9õ¹_i®}SÚ]¼£“Áã_t{×é½µÐìUoý…€ý©žýP±üH¹ñŽJºéÌÒøú›yÿ¤’ ÷VJ±ñÚ—ºîjAv§ûN ¢YJÕ4Ç«1ä̦IÞàÕÍë˼Ô-J‡h·™Üß_5‚ø“ ÖtOK¡w“uªÍ ÷þNŽßw÷›ñ dºÛ3ăÇo•×+$vf{bóôažÍK”;71°¥J{ÁT‹ç>¬;E¹ó¶]IÓÈîNW?§ña[š’xÒyj: Ô2ä$¸QdCöã<(Áy‡ç…ójÚo62£ÂV*QÎ%|*襩¼Ø>óÜîw_…’Zi={¼{Çc{ï~Åmÿ{~ì×ÉÛ³Gžs'Õå;Sžÿ’/¯˜—úæ…Óvt•<–û'{×ÑÛʄ҇ü”væ‚O‡ÿ“¹ógêÎ"‘0âŽW2¯l€ÍF‰™ØÑ@šBT·ógNØØs%Ü‹5xëPÔ¬úä¨P7Â$ 4Úðÿ­¯‡©˜Ô7ÞœÜ|cáèÇ®¾ò—vûU7º0óП¢h†×jÛ ÉŠ¡PÜøZ³ý¦6½tڦNS¹1U -4¶!~ÐT†MBÐÉr•‡>êÒ.µo†²ÄgÄŸñ{>Zû”Ï"Eû&¤a-ákLur+—16Œ'àšgzÕ4„­¨ð|C?$‰4üïí|÷÷üÎËŠ_¹ÿkxœmziŒd×uÞ]ß«÷jë½{º§»gå®b¸ I‹b ŒmZ$-.EE’ü#  ðÄqlF  v#°lØŽ'ŠYE‹Eš»fDgãÌôô2ÓÓKUuU×ò–{oÎ9÷U¤1è©®·{Îw¾ósßÔ¯œgJÁà‡»\8øO8)¬Í¹ÌX.‚[æsÌâY\à?W1†_Â7Îp¹Å£–Y&…°c9ÞA2ç,Ü~3¦è³âL;g³xs.ñ3„´ðtVY&”àyÎxÙIf.¹D5©¦±¶e³kS_\v<·íäp 7#…3pU€Ï…Ï<#%WðÛ¢ñ…ý íÇG;^ß0°¬pMu);˜GÒ­8ðrz™1Cü‰˜ÊϘӌ¡p•?ÄÝ ×ø™T%/Z#LÿzX‹'žZcÎX7\ ‚-A?h†dd?| ^•`-LNÇÛâg‡žMñK P M -ßðnD8nàê˜ÂKpup²fÜ0zªšÛ²]ÆûœÂE%«r<äÜ:ímà E`Óœ« 4:5þÔ2ù!EG U(þ£÷»%|Ÿ ò|„­õÆÆÿÉrüíT@aJ„ä¸?\‚b¬8à(ÁÏÿ” f X9ç†;Íq½€ 0ž¬$×"ï›îUŒ­.3U×QyüÉOÿŒ`& –£÷˜fŸúñk¸ @Pyã½ý©>yÒc@i.g)Ú‹ (l&稨÷)ˆŠ0‚ †|'ðÓ=¤¹âZ1ôÉ@·-r…EÚû¹„Û¸$@™|ëýî•oM<õ ¹àǼóÑjd \þpíÌ?—å$,È ©p;§Åæà¨€NÁC†ì‡»9›ð!k9ëQúó?3Ò6g¹ ºµŒXqG0Kiéâiº*% %[úþo¤““_ºT)8‘Æ?wÄùÞQø» :Ê;¡‡h! 劃)g>/„  Û5àü )–Ãyüœ&e#x.0ª#€q(A2´x¤7Ò¶p!\.BÌA–u—Ì;WÒ­Ó.ßìžxz™™T’7 pŠ& ¯`"V=ð+5L2€²’KË ú¹;8ÖÇP¸äÖp:$¸.òWÅ!æ¿"‘äò¸N–¸0\‡àaLç Ò%¶õÖw>ú†–¬2yK.‚‰/-a”!f‘͸Ò\)k0S|ýr”§œˆ•CzÄì.ðŸR|ƒb!ÃÀ§a**ßÖãŠKícÄ)0=wI!M×ÈÈZ… ÉSA C6hÅ:Ü^ù@×&[ïµOþ~(LnsY;0ñ¥5Ê8`ñ¢JЋŠ‚Ê.ò9Ï‘Á¦‰·&ÉH¸ƒ¤Ð!óNT  ìq®‡yJ¡$Úœ²—W0"ý„GpXdaÀˆØoûãåwþ zà!g›Éê\÷ªŽF&oùû“Ï\Ar ¬#Ä!óÙX Ï+À„àŸ+·E&z€=‚`Ï)£-û´M´"Œ”ôÆSÔl‘SôUϨ—ý”Yƒ€¶˜]VY¦£˜mðÕׂ(î7NÅq¶—ã¥ÚÁÉgÖн†Ì¦J#«Ð¥Ö Ÿ¤k¸Í=§a\„— ÖS;„Ã;·HÍ™¥¸9ûé "qH„ Cn2‹ö3 H6‰p”Gàÿ¼™Û[ùq¶ó‘K· g¹,9c&ž]{E^j‡ç7·ævÑ0ø¬†u“¤×ÐÃ’4@*¨'D±…“ÉBªh‚ «Ø³Ÿ–WøkúÊ1p—•¨|2“§2ª¶Ïµ>üÓäÚ›¥òÔbxpÙijKÜX éȸ¤ 2?"s(!(Ǽ¢TBe¡%oÐ$ëÓó†=ÄT*‘øà†!Û«ìÆ™C²RTàV8Eâˆ|t†é„•j§±¹™4u–f’湬a°óÑôSËÕnˆ¼À°þ DHŽ áøPi:‚:®°³Ê„g¬õ¼Fd\ží©€ †- k/`YïSiN àù’êÖÔ&Ð?DA–\}³uê›ñä±Òĩ؀ã7j3û“Ö¥é/­Ð"1+%ˆ4‡öS¢N Y°‘°Kª.˜XH€pdè8$'R‚¤G#§d${89ß¿Xꃆ-ÒRl¯öËEZœ˜pAŒwÎþ•ížü0^›¼ó%ÄÌ4òÞZmüàÔ3×0ã@©6…iíw”`¿$pž¢ª$:…Ds5ˆka´¾=E„`Ö£ý(sÔÝÂë:Œ‹?ÍØ¢þ"Bür$©¾„ª[‚ Q%›i(ŒTÂÁ…Õ÷þ«±ÉœŠ'zÛ§ᣠ¿0õÌ2 ’’d-0¡Ã'Àå{ö“%Òˆ„J¼ 'a-ÈÄö B†Å‹ìÇ‹Šlö;©?@=\ÁX‚Ú& n …øMn¥Lì`içÜ_‹´ÛÛY©,ƒ²A›@G3¸3.(^žµŠa…2‡Óô$…^Šg¡ A ÃÉ&LwÖßúFgéÕÆnú%Q™ôZAydú¹k˜M*.åðØ2p¸g„¢”å~Hh‚ȧóâB•ÓrLúÙ54ÄÚä‰Uh(ß¼àâ™ù@‹=5d ¹æIÕJ’¢¢£1i›ïÿqëÃoŽÎ>4w÷‹yyvkíl°¬¤™{öº‘Pj±ýÇÙ‚ë“IeÁË@VB'@¿.‡r!¾u"²5…íH!XWJDÄNA°µ\sD”ØTÅ’é÷ºÀJB QOÖdr/K9¨ºÄ€,3šI—ì\yÇ%vôÀ}­æÇy²Y?hÓ|úùmò{H—ö¹ƒÀ±€"… 3dE0ˆNÀ¤î [&€$‚:qèp ÏüŒHºùFX$ Õ~Š%˜s$É a‡¢¨:w:ÅUÅø¢Nƒ’ÐFCÄ W.몠 ™%6i]¶Éºt’ÆÚä ÛÂ…ž jHÊ!ÈlCH&A"ç+š±à¤+¢’Ô/..£ò¥ñ NÏ—³)¦Ž Qþa ö&‘Šy~±ÔYã–I!b3Zm1 e~¤IƒD&EÁÌîÕí“ßÌ;+R„Ó/lrIl>h׃bádàXÊýd ¥©r~„å=é°q"¸æœzœÀˆÈ‚:@#’:ॡ¬€€¡Ž¼oÃÑZ‚“ OuÍ8Ob}œßÂÂÙ°»ñiŽ"7f÷ÊÉÝ+¯Çc \³_Þd6¢‡B‹Ôޝt°E Ŋ¡¸Kƒ¡nOä.KPÛ©2nÛP­„Üçžg°õo[ºya?}ÆK ²\b—XØå>ƒ[P›!|:{8ªµyÞW\%;›Is%ˆ§JS‹ý¤5ÿ\»ès9Ö¾”~%i?ˆ)ŸÚ ±¦CRÈ>¶8´½‚Å.ËH[ \À¼4Õ4ôÀ¤uÞo~æ37Gs!ä%‹Äle ÷ ŸÑö'RM †¸Í ÑÝZ©ÍÜ}EΑõçžo3Wò æÄƒûDBO"8ÁF–h_¦ËqÒÞ°2ÄhðÔbj@{Avú½á÷MÑ‹vÞ€ápŽ6\à)˜›~GC Ï5ÇRGad ËAýíÝ«'K‚‘y¸e²æÒÛ3Ï7É«š†« ú¨ C y pß ›ð¬ é‚Bø$kœãy»êãHlˆÐßGÅ7اîÌó†è3/(Ì4,îll˜í¬ÿäw³í³3_Ùd2$ª,Óf.¬Û1jZs›6À;ª4…Až»4P€"›dÉ2g²»Þøè•©»^`3ŸI\ –Y´6 ›!C¬.ÉŒq%Ûcø€Ai–°XGÜîg B dxi?lÁ‘  í!AÂjÇ`ëôõ7?o]˜~¡©ð–1T±=„héÈºŽ ²î¥W¡LŒÝòDš‡8D_•5ÁfëÌŸ59K[²²P½çk¬zç¹/OYÀäÆßþ·Ú¡ûãùãý Ã^õj Š5m¦hˆ8|i‡ÔéX GI9Pö+Ìq„ÜÖ ú^;uWÞ\}‡¶f^hKK<¬ ž™„z îEXºþÚ¿ãœÜôd0ûYÃË i,ܹÛܽôÊ`ã½xtŒ§íÞÖ%'Jõã¿&ÇŽëê!Gû†PlãÂúß½å—kGN! ñ‰½ ĘcK.üö«¡ÑóB¼§ÁK€1Pº<@èJT¼:Ç>V©ö•w{WOÖ¦Žh!úO^ìá.¡¡A;+€©"l{Óõæ©ÿh¶V*×»;íÚ-_­zÜšUÓi¶Oÿ•rƒr C·uõ.Ô÷}æÅ4˜ËƒQ¶%YéžwzÍ‘›þžYàA™6ɉˆ¤o3‘¼"²$œr[Ê_ø$ð5vD )¶®ðçÐàMþ\’±öÖÊÜSoñh1W£Ôq§4ùÅÖ;0•—_’fK¥ºzkýøKzêÎÁî9­K×_û-·{Yb½î1 ¼xçªÇžæ4y(‘6N÷·NŠ7 Æn{Ü$hWÌ25Äz¢s…T@ì5n‚!iVÍHÕšÜî•Æéÿ•¬PŠë\¦¬R=öÔäCÿaôޝµwËBE ÎÇ9s%+­ÖGÿ¹·ú 7=C£7?Y=úlŸU›g¾ez2o§›ïÛÁ”OUªæPÅ¢YY;<~÷WY8¯‚±í3¯¤­ÃÉ9%<­yĉrÑa¹Wßø’uÇÜè3j/ #Eš£ìÁ‰~g£{ùÕdýý¬u!ïoªx¦rðWõ¾‡âÅÇK G‹_…j„{ÓÐK¬ Ûïý'³õCi7‚DP÷Ÿff4Ûkë?ùÚìqÅwç¿äªu5¨çî­ýåÖæVeò3Ê•³~ËØnó,ï.ÅÓ·ª‰[xiÂÿ¸Üâ4’ßD6Cxä8O°ñ½6§™" B(!ýÆ•þò»¶½l:ŸdËf°ÅuýæÇ~7«ÜªKûƒñ‡fþî7»Àuª%E³8Fxº•7~Ò8ó—Iã"ÃMã£zßçõü¯•äR÷üw;¿­t˜eyeÿ߆êµMÒîö…pôPeúžúü#IÈñ‰ÝÖåÁÒË•ÅG¬˜*cŠøŸt•Å=f‚òÀ¢œ q.Èi ‰„ü¶"ÈzW{«Ÿ@…Ê•t6­ÆÜmOÚŸ$éÖè-OÉÚ|4þÀè_—‡¾š¢hI”íÛ~§yþ–n Ó¬¿ƵRI zí±£¿Ô7µÝÍK®¿–·ÎQ7cÆ¥½ÏûжdiO×ŽÎø<˜o_»àØ®ª·sYV'uý˜Œ§p“pb2ÌD‰]"é ” ؘamîìºÜ]¹°»ôm-Ûç_/Ý)Âú`ë$x =’¤=©+Ð’r3@@C:XÓ­MÌl |äªvºÎdõ Užž¸ý9=v³ã/6í©ä8-ü&uJ¾»‡Î÷«A¹¬½ÛÛ8]Y¼_O·ƒþêÿý¡‡_*ï›ßøð{ïÿQÖ<‡z)Qõ»±e0 ŠâèØ‹#w¿(Û—®½úÏL÷‚"&J.«ø¼BΠԞµÝ6‹ÆKûîè7VLgr1®÷ÛW¹ŒA{H¥ÒîÕÚÌÍ GûÝ^eꞤ¿Ï>\š}¤ßÜ£õ¹Ã™Müë‚Ø3M;Æþµ:ÚË£6³Tm|¡yùµ©»Ÿ êI»Õøøofïx"o»öö ÖßÅRëëªö·TÚ¥Y6ú™¹GS®.ÿàŸaV&ò,Ov›ñì]¸ÙQªï\|Åí\àñ¤=,‚ºÙ]“v—»~Ök•j  ›ŒI³þ¦Tn|îv‡µ©jbÅâcjä.“ˆ°\ŽGg =3»^_ „ß»£i ½É(P{¤X ·/ÿHW*õÅ; Eêêÿh÷ÒwtX«Lï5¯ÄåJoóTýößꮾÌ\»6÷€(Ífé@øBZ}á!ÈèÝõ³ýí3ñ䑤ÛÕÏf¿kt¬Gob"ê_?Ͳmn{IgM£Aí&U™O×™Ý[òdPª#óªvtâÖ'Úkç]žVçnËi» J¾±bpŽ"eñ’’£=åTКv7¥®æÐ𮟃&ôì.mOÞöT|ä³íͥιïÇ^øâk­K?CÕYy+ﮃ0ÖQUÄ3i*‰;K£óéÎRããÚþ{‚¸ÔÝ>˶ ÒÊÉJž€ý“…¥(é\ÓÑH6t¶™¨VO :"(OôwÖ  GýÖØ±ÏûÿBŒÍJ"u›—À"–’v÷ú›¿×½t*d45rü  ÂÎÒß–'ï˜;úX8óXÞÛ*c¦ eP€lGr(ëÚaYŸ¶yÞ]}¯T›c¦;hŸD·™dI”&«S·¶®}¤Aòï6Âx¬¿Û”áH×òøM r;yçÓÍ+Ð4]ªNÌ÷›ŸcÆoJUç v±F壋þÅë"«Q…â $œØ¹|&ß<Ù:ù‡¶w-ˆÆEy>Ñâçþ1dD4u ÆU´ÀU¬ã1(uÌô„Ò:¨ Y"Ks'*s,¨¥K屃@1½æE—¬8ÓG1[šˆ÷ÝÑݺaÞm’’ÁQ• k96H:¨=p·-ë]?S›:Øo\†Þªvè«ô=t r>6Úô2¦Â”V)½©Hn¨'íÓÿ{ëõßvɶ<ÖÜ\ѵù#ÿ“A¿ï*S¦TÖñÀ\©6k³–MÛN©ëYÒGކc7ïvšº~8Ù¹V¦&|~gýRºþݬý v¸aMƳƒæ¥0*;ckûîM"ó‡6*œ“õ£•×ÊL3âÌè¡GzÍ¥ÎÚOÇîz:œ½?Å ðŸÐ»@Øš9ê_ µuæ· “,!/¶^ÿ½Þ…ÿcóAeáA9s_ÒmG¥ñØc䨔aÝzâQì¡¥›.mÐæB¬â¹éãƒyëçߨø¸.KšÓ÷¾Ôk÷vßÿYû")9Üï‚ØØ”Í2ÃJó,˜еœŽö™t[ð.5 gÆoy®³qQª²ÿÞÒÂ/æP]¨·¢·›pà‰› ÂË&Sx"e‰áåÿþOû«¯Ç“·…ûïs•ùñÅkå©Üôó0ÂÙ2èäÿEÓ v³Æ‡Üt,s•}'ÂÉ›³¤“ì^GU&n4W;×OÍžx±¹½Ôï߯ºœf"ƒCg@ž./übÒø8YÄ2~äfÚùõwW™¸ùYUšt×kûï³ÑAV™BÍ ý† tXíéw<áB‰ÓÀ$ˆÃæÙ×Ûç~rø³¿PéçÐW”%f·ÍE<Ùê„cçÙ@•çtiàȱ/–îi/¿×[}c°u¾ºx¾·¹§x*r/‚KÀ!0¹ZӤܪÄàNßZc€Ù+8x™ ?á¥)Œ;4ù@j–™=0 ñ)¤…s~6-¸¢œÜ‘ÁrñÞ¯­¿úww}„'¥ü:ŽEÀ†JÁ[_ û0F…îÖ‡ô‹kz A¯C·[ûɤE‹9 Ù!ÙY®ö_ëdwèløî$Ž‘'4\¶tï_^ùác3oùx"Jœûž¶µN™_„Ù…GJƒ(±ÏHÁlk!ýtö3mçØN·0îaÌðÌoÜá .ugÀ žÝ—Ùœ *3>Ó5A‘ûôøÇ:»[Ó·|(-̱Bä…‘T}.ýÌÑxû"¹e/{`æ7²ŸaœHIF¼áiކóh­p¹™3¹yfŸa¢M9øådãP:ô(ÆêG>ܺznê–GGÞÕƒSàý2ï<,„Nð{4–˜%=>«>sE:à8G¼HNš.–‚Ø ÜY â…Òý –ˆíGR2ˆ%ž²›)Rqâ|j&N}¼qéé‘£ï,¯¼³/G?’ Œ:I‘¯„TôLž(‰Q&>±_ìMrˆð‰¢á$ù\—ƒ )!Çù,âÐ:ž’ýÖáot×+Ñ0L#rþ  zøÃ:nTg³ò!oôfæÅ:}Ãíá=h˜†!9dì!”€i€0 ñ?E-_Ãã08#Œ¢FŸR˜1u¾Ÿ)¨;q,ð[í·ÑNÜPþ—Û?rò7ÒæjÚYŸ9úî4\ééBýè=À<­À«Ýœâ”ø4ȈF\· ˆaª†§‚ûh0þ˜ÁÄ1›ý ÿ ¤*°„ŠQÄ“ Áf(¢À~K5ZÙË”°h# ÊùGsGJ‹÷q÷•G’½×+ˆèhýøOÜ’ê®'Šð(p#™¢»)Mô€Ó3äI!R–0éKær®’„(Šn‹„Ü~J D’&˹Œ MŸŒtØðLN¶€'¾ìØÇT)õ“ŸPí‹IóÒøÒý±®GKx Zõ…8¤H©ˆ.| ÈòÌ„œƒM®È0¨ Ð<ƒøÑ–Q‘„(NU6×רïc?ˆŒÎð5‚¢Õ¹×dbãoí/ø`it¢Û¸xô¿»½ÑäÅi¯1“0Ä?a[(¢ ²q…÷JîsÊ‘f¿ý0pF ßšc²‘ØeÄ‚¹,«,q¡xC¨çö³¡Ü=¸nÈ“·þžÄö¥g<ð;ZN¢ìw=߃¦‰¨CÌ ØÀáŠ< ‘ Ñ“ᇞ)HÎÁ½6áEš yÓr¦u,á IGr7ð<~M–#xæ&lÆÇõ>Fã[¿=ÿï³òœ àÊ´›Ê¢¶Ð¥Xvh†»¼Äê?2uU•¨A,erÚR=CÖEª"04û‚ogG³lj¡ í¹p™Ý,>|€CãPT=öQ™lww/-ýèé”oI9ÈæÅmíià+Ñ1ÍSÒ®,oU—¥{ Ôïs&œþç}4T‡ÖÿVjfw,9†.h8 Å‹ƒƒ˜í¡«):äCÏÉ?FÐ5BŒ]ÿÑÆÅGeÕŽüsù½ˆ m–£qVú ¼¾HÛL×)[!%|,4(EáÒ+¥õ-Ô>wÆSÕâ_Q(ÔsϳL»oŒ‹MÊbî¼5'ž@.¤ÉÅ@Ú‹ÇOýGÕx©Û¸0qê_Žÿ°wtÓ½5Vš×_@á šLTCÙ i3…Ai%èiXž01§Êˆ„d ªƒL¥y&8ã™<æ¾ÓDù4›®VóÒÕo~Jµ‘¾g¢ :¯ºW µPcÑb¡² =¬£R(ä¥_0ΟœH†Ûâ¡…CHM¢= Y@‚öƒh$8XãÍóý(žHùÉ<¾a–ó±½ð5Ñ5>A¢@ §ŠFúÍËq{÷ºûþsZíì]­L/©¸Ûkw’T‡µ?ˆ ƒ‰xßÇ!HæJk‹$‰$’ú8:ÔàR( ƒhÙ§ä%D¥bã¼`Ä@9£óx·â„arÌŠ$€#÷M,¿9™}õ;Ÿ_¸é»çÀÏáÈŠ_?¢yU™¸06”Ç%€‡…ÒÃt`@$‹ÄêE(h ÃPô(xS€ˆd6Ébö{ù Œ]£„™Ë©< aFqXÒd?wç)Ì)¼Ð ,:ò±òÈ|çê:ÏV§L¼íõ>®xyå¡Ïí5šiÒO;—¢é9¿X­)y˜ì0…PÄl)rÌ;’¢:’S'‚í+£ suë@1"?«Jøp^vÆséæNe-loÐ5¥“Ÿ*V'KñÆSÕ¦ü°f S£'.ÎßÖmwe ™í‰Êø +”•?ÆÃQa›žfyD)R¤âÝN0%# 4¡ìGm‹˜!àô³;=H¯¶ ¶¯¨ÌeqMJU§J­¸ükËüFàéçÿ쟆¾W™8âMÝÞê+„‹Çî¸üô—û;WŠõÅ­ÕïŸþhéèm¦Ó– ŠüPQ« y ¬‘'mNBüÚZ’S]“fÖÐkã¨Km‘‡Ò`2j²¶icǵ_ðƒVóoù²™OzW¶žú¬î®UÆú“'[­-ÓmˆtÛ¤{@éž_/OÜ:vê½éÄ’ïõy, öu‘¢ŒfMh*1Œ/IŒa‹+p¾UD–dli`-Ï‚d›÷F„q3‚€«!H¤ª´‚ QŒßýÅâèx¥Zxõo>iz‰ƒwn^ù¾_ƒ÷w¶_öüP†ÐH©º€)8,Gs7)ÅÆ¾[GãH5‰&Ë(¨±ð¥k2’ëÐP—Ró>Ž-÷ÚªÍ:Š^X½84‘…|®¢5õ+~rU¶ÏGé¥Õgþ[·µVž\im¼l⦅BeÞ‹&ûým¦@ ™¤· /¥9¯¼X[ù‘úõÅMÄø.Mõ~4CšåÕb,‡y×: ¡í®XˆØvK]oÓB(kxf 6ËS†ìw <ïñh 5úŽåMÊåÿ´^þñtV¿Þ}ã1Õ½ÚííñÂlmñLëÊwY¼i8O•öËJµÙîÆ‹R" +—ÜÍê‡Â‘S•ñS~)ÄŽ:|ÚØ)"õ¨Ð\CAŒ‘@$•öÚ¸~—ä®ÀTÚ^ŠQoˆ njžÛ¶¼[#e f[ë–0üÉ3_m7~4^ô’½d÷•êÄ Ý$NU“So³X륉Œæýꀷ:}¯õz¿§oòkK•‰c"„¸EƒÀI>оQàÀoÑí#ÛfAìQ(KTÆöaH!S‡_P˜àŒPS‚t¦«ïìÚA~`ã\i¬üø“¬Rj¾ö­ ·±þü_ÊÂØÂ=¿zé¥o$Û¯ŽM3*Žë67nû¹¸·Õk¯ÑÁÉc÷6¶ÏƒL QÚ×0C¬$ïkœ¢XE’WHäê¬1°6„Õ.l-‘¥€¡\—õY³é;ðöÇ‚™CÉÞjÿµonýJ4yêÈû>·“²þÕKQª^·ÛïA ~ eÚÚ¾˜ª‰hrœðÞ>( ÐüFRkÝNñÑ×h5"(×f* kk0Ϥ&J—6„ åZñÿ¨ÁžtÆÓˆ’ú™¿àa­P-÷.üuëü#~õÀ¡‡þ¤ç×% ¼º¹³ÕÇ}Z‰%D‹QPC/Mhr}´Ÿ‡–¨1·rÛ•Âyñ,` ¶¡%NºÂ1¼¢aJ‘•ãöö!³¥C+î$'¡B¤4ýðùÂÄR »áî‹g¿òa/š9ùÓÿk¯ÅT¯‘t6úiN Bš˜ÙÕ"I3›j€¨™ã.Ô2®¶Eç'è[çnI[òåš CîuÁHjÕ‡r½ÙA™3œÃöÍ…àÙW3ïx$¬Owן©Juù™/1Y™;ó›­Äƒúà QŸò¢Q4Û4½0RÈX`-hQÀI‚ hÌ­ ´jH±„*sŸH†œOoôòªŸº¾Ò•Q~Û!Õø“@N‚Ù8ôI¢Q,Z]QæB¸zè}@‰õéC¼·Û¸üB’èÉÛ±vÓø 3Ù줡½¾V1­sEÊÊJ€;GT8êjFí%oJÈÁˆà]fŠÖ›žøþ„ü G÷BÈ!ûm©~M 0¶o±¦P;‰ ^Ò—@↧izýCŸNïì4X?öœ ¡€ôj!ªZ™ÈÄW^¾ì¨ ðð‚0(±)Au0³Í ™i3]aC‚õ§­PXž‚QLæ]J×Ú?Ì?l¸‘ÅX±~+„dPž)Îuv.ô[›…±Ń?ÊG¯3"ðÁrVJ;±_¦ŠZõq8$ò©[a)hJ@ù|í?Ûcôkw†#Gx4[YÚ}õÑîÆK•™ÛJKF‡ðÇ*¼ÛnÚc;¯??rðDuz´ÓBdÒK›WkÓK—Ÿýzgëµ#~¤Ó¦âNÒB@¦†µq ®sžõ½e¶þe‘ìÖ×ì¬@!c[y´Ú2Ü|,Þe!°p×o•æß²µqiúºÛØÖ“gÿÏ¿«xÛ¡w|ú×/Vgçýî•—ÿê#KoKâDÅÛ…r½´òàÈüòöKß|ã©?;|×ÎçÏçn~8:p:6!'‹iÁHÒÃÜ ‘m£ÙÖ®¶R´K9~¬L²BTÒ:rŽ™¡Ãåb8Y]ù ?qªÛÜÓÍ×B¶ÕÛ~&¦îú·Æv¹>Y ºÕ§ŒFÄ­µ§>Îß7çO¬~ãS\µx )Ì ê‡Žþ³Ow(9®…ÑÔ‘°[ÜÊQc2û™ÎY×â\PðäKûzžCS0øÓcßù¿ã˜Åݶi¿¦·¾×ÝyAF–ÞúïûÞüÎÅh^økÐ¥¼8A!ýQÓk¤ñjs‡7žû"ïmƒ J37ÕNõ”låŠÊAËÈ&‹e÷çÁûVTŸŽ¯lžû+ß´ZkO§I7š¼EŽÜ–%dzqoûŠ]×o7¶^|¤P­Vo‰{›»çÿvz~iý¥¿ÑÔÔé•WΨXK•xØù -lÀ~%Cc7{d}E øâÑ)c¤ú¬íOÎu•¾•D×ÚŸMÄÂCO´^{´yñQ @˜^i¯?«ãæìáû+‡b7)ŒÌ-¥»¯®>ùåÖúKå©#½Æù 0÷›Pf™´Y,V:Û«ÅÉ3oúWÁô I£PÔmÆhÖÔﵫ‡yWºåÜ®Û÷hëÂ×g²2{óè ?ÖMY¡´²}å9Y*–&–ÆænH{(x2Ê“(Òl|±>ö„$à›ôƒt uHmäÒùº†µÿâ×@mfGBßâí“wª*˜½½8󦽵W¢Êxer±46¿»þJ³Õ«¼©½{!©ê„©.îS¤í=($Y Ž¡r”Ÿ¸êÙþw;Ä`SÊ~`ï£lÑE<ß?öæßKö.1ÌÝó¡ÝVoùȱÇ?ýö~ãÂäu?Ò÷kŠ—Á¯:Íœ¡"c=% …ñ9F^ä«nÛÃ͈Eô«BÂ÷PÛã²)õâ<®¤-M·dëŒÌÊcëùA€ìçûñŸ=€s½6÷¦?Ø»ò|ýàrtví{_™X8Ü|ùÿµ6 ÛÞzè­¿ÞNDiúh"ýæÆ¹R¹¶úØïÎxpõé/ÕŽfŽO¸£Ó&öCú¤Í¶™XI^ô 1è~`Ã'uÖc!lûTÖ@‰‹˜ùÎ+;[ræµ0EÎÊL1óàcª½¦»ëÅzåÊÓÿµ:¾È{½ÍsP,Ýó‹¯~ÿïÆ½«µ~.¬L/ß|ññ?í^=§zå‘Yœg絛œ‘P3‰11"£]£ÏÊ0ObË’¥vŒ,ö©WŠë2™S÷÷yòhÒux„Ýï4Ôüa®‘ˆ,þ‹=õúãkßþdqt¾ª/‹þÞúù¿a¥8}JÉl-•Éå;››:›€RÔî*¤Þуo‰‹ó£Çïæ‰öE?EÙ Xò´Ê"µøX y¿€Ù»ŸRØÆn6HáùÃöçz€ UgØÃ  l<ßt—å‘­;¯|ÄxÏ\}æ»ÍKµƒ÷­zëÏv·_~X=pk¬£ÞÎ:‡D:A¯…õ±þÖY<œœ½ç×FßÈ¡"Kº~¹ØÇõSÊ×\€!nÐJq•[ù¾ïÊ^u fhçn‚¬çó´‹ÕxÙ^F‚Ðùÿ=ßÝ{þô6Ÿ/N‚zuî†Æ _R{?d&5~$Ë ØÔ½0¬Æ½8¨.ÕG÷.?—twüÑÃïûXia)ié°,v.­I/ªNV$Ú™¤Ôž÷8ûÚöŸ=‘ïþÅP—r9TàmsÌ“õû‡ÔÝ%tÍ¿ë«ëßùSðÔÔÉ÷êhlñÖ·žÿÚØ~ñË8Ù¢P^¸[ëžî®éx” ó&MÚY¸½×ÞÑP§•¹ÛßW™9–tº«O|äwÒÝ™]œ\ôê“ô¥NYÙhµÚÓ¥àÜ~l³{©—HÑ¡h‘švå‹î!yf8ño.«Ýf÷ÊEVkGOÃkfã™Ï›dÇD´÷š<Ý’¬Çd‰£ÅÉõ…Óv;é^9°r噯.ÝùÓ½µÕï|vtñæ8|”gîxýÐ2K»ž/RÚ]·r°“óÚ®šMF.7yÙ>=•àΟ¶¯({Ë@yréõN|²ã§,’E¸¤ŒWôןøÊ•o|’%»Õ™['O~@ñRóü#¡iwÛëÝ~ºòžOˆê xמûºi X²yö[^äi?*µåN7Xzó¯D“ã wÝCIéç³.‡“ÓŽGâš…ÐíÜs~¦¨,[X ÊvIÁçÿÆA$7xœ…ZÿÎ%E­®ž‡UQ(J\I‚Á°Á`øG²ÑÃÊÎ×ÝVÕ©ª®¹»ÆK¸;ßÜžîÓõóTõ¼ÿåjhÑšD4³ý#_Ô˜š]ȇíO½iÊýEtÉS}ò¤NܙƴŸÖ%W­q;Oùaâ®>«ÛT+æ”I–Ž”k¹)äRF¯©0š?ƒû,—.ª~þÇ›º„Í/Ö?ij-¹àØÑId])ô޲å9íÂP5}$?«Qù\»ïKVœƒûÙtN—!Dº%9ib66õ¦ˆîÝ/_a²ùê.„F&Š0`öÄœ?Ù¿Š«›Xo‘®Îý•þ¹ô'›G…¬hcAÇ ÿÜkåf°xƒY‚>õΗ¯dãe¬Â–‰ÇåøåüªV ü#ð«îD 2æ'cc‘ÃZ£g{¥ó¨èÚK°ås‹­Aì2s‚oE_ËT€Ánìz÷«°“¹Z¦~wÛ­>ÂW=ª–1ùT[œ Uv!jPã—bö†Ÿ §Ò†ÛðÔ yÛIrõ>ì 7Ý0üšžýiù Km×îMͽUG7ÇÀ4çU-Ž0ÙÈ¢óü:ÿ<íæœjXáS9Ç¥øY‘§ŸBhØ„ßD Ÿ2ýŠœLK%€0#ÿÿìkÅÝÊZ-¼&·¿µid5~Óò4·±ÄÄÀ_³Ý±¹2M2‚ÒÔ\k˜ÆÕï’×ÉÛ,ã·ãË·ÈŸ,¦A¶à·Ú5Çýe#–i*EGßP+bóŽñ4M ¬æÖÕˆÚaš%G‚8æ ÕhÈîPÀÇ‹CÍ[xyöÕ€•œ"Ÿ‘6FõA•¢ûŽ °è™yA–FðÅà®#']Î/¿†UDô˜ûú& *ÿ¶ÉG&ÈZîïÈϾ ¢0Ÿ…¹dL°›–nÄ)/ÉLÈ Ã#¢z‡ÎGbšb^ìÈ«N+þ¡0?‘zöÞ8Ü6¶(Æ¢&í¼óÕz¬²ÓDnϸÉAN²ß£«¹Š„Õ`ÌGUàÆÑÎfH¦¥G^ç+‰)ýÔñ›Ùð¹43,aÁSC™îÂvýì«WbTdñ)“2ùÒ4OiQLš3‘°Y}Ô†ò…„+ø)óW8é_\f#é5‚Ñ•)ÉrªÎ~È$ͯäØã¿øzñaÑ~î(²ºIÆåÃW3{®:‚Øs½Úu‰ç5²µTýWŒ7ۣʺAZšP˜Ü/–®vííëäÝ¢ÙX.åyÎm!vËžÂ~‡¯"XDcï&õÀV/+ò%±ÌóNáxzØÅûߨ¾‡yzÄ þ Üñm%ã.«À°Nx1×IÊ'#~•›Ä¦š4‚v~ÆÍ´ ë³zIL”œ†? ¾[hR ;S‡7Y¶ZÆLjŠ¿›6›Qè' þ€ùMíÒEç1Aª©@æ<]ÚV:¦c˯Q±MI´L©)oÐ^5†%ÁÐZÍ]˜˜®nÑMý“‚Þh0Ôÿfp˜6¯”®†¯Æ±„åâQK“Ç "=«rì`( ?…¿òå¾Cþ—<燌Üõ u+ƒà•-˜¡d¿%_–ìÎ@8þùt ã5j!¡S±ˆFË‚1«ÏšD.3õm RÔ\M &mâÒOv«^j!ÃIøcZG:¶Ë00/yœ¿y´g¾9…ýÊÅÞûF¤uµ~â&ï…vÝ—ÐåŒy-Ð6ÝÕ`ö¬Ãûðo1üyž6~p†EoÆš¥²£÷^¼RÉ“¦QðÉבoüÍ#ŒØx¦06~a_’jhã dòùÑúÿùÅ#iüyÕ"ºq®½Á SÔ7Nn-ê•Ç­Võ\~RQðÕ–†}=”daðMÈ!Ïà«&#´óƒoWe#=ËszÈûEÚ­ÄÞ@ Õ66+)Ú¾_´qºÔÙúAÿã3oA€êüòÅ.•9ÿdËVAšö–@ð¼Ç÷©å§ÇÉç¾l¸ ¤Èßë÷ã–§bÒ2‰ºçæ~»𔠃׬¨j]Ñ­=‚ßcìžmvæD~“ØÝ’)ˆ™ ¼•Q¯ñ¬ÛecÑÑnîï >ó$ñÖh6ØÅ˜h£L›™jŠF³I:2iôÄ œÏ|X#å£ïW»®lõHE„vÔÃÍÞ…†9Ìш'×ÌÆ7uu‹¯Ê„Ý.Pã§ÝÞY&¯X§kÄŽZÐ iÚÏÃ[Ö–d©üV½¼ÄK¢h/ÑU뮆FÞï]ý¿Ö¤ä¢@9¼‚‚®Hâ-Øï„aö<–¾°; û5Yk³É wÌ#Oeà%ªªÅ"?‰ÀÛ>P¨–;±¬cîŸfâì/¼qOü?ILÛ]&ìÅ»œ7^ORèÏ'~аé)Æ´?¢ÌR’ŸÜ ß“”hïÉùÆœ[8:›ÙF:¥T=Æù—Æù«÷sdjplz”Ú¨h¸w‹5‰ÁÖàtV0qˆ”yÙÌ‰íˆ ’‡ãpQ“ϰè¡ÿPé\Ú‰ˆBiÛqVá øÃ;J^ þÀŽºø)ÛÑFY]ÂܼU#à É<ï@q«ãh7耪ô<âSyùïLéPí¬ªÔËñV­%Á_2à>»Ô£-Ó9<[zJéÝõØ4;`V¿µZJ„·¨£Ü`ÊŸnV¼ çxºä[Фyºyò½h )ɺp¥á %?V6«Ùó°ÔŸ5¹‡Ç¥±I*þ¾‹…»…„–£ãä÷×nþç!WràÈ>ó8œG}ú½qÉ÷›pr-•¡yš×Á'àͨÇó…€?õÚ9B 6™PÜ2OωçSaAüø>À.mðÝ¿Jàà:g«,ä5Ï[Êð&@Aø@½ò„“ù»M”-¬=ÞCÄa„ Øž,Cgä”Ü„fs.ÅoÛØøÐ¦./L;í•í,7§Îq¥EJ¼ÈSQl¶¦g© Õ¨2Éy0"0œ=™J¬ý8ÏþšØ¹Ì ø»')·ÁÅdh èŠ ®7ŒÚodçxÎß@˜²ÍÕð›lYHŠzî`cé8R±soàä ´ôUǬVÂüæo(ôYFhrµN‹ð¹WÇß×L;åí¤…ãã R‚‡·2,ãý‰>xC¢À\ƒ½™æšíQ³W?Bj ÿíËNâ4YH²;ÔòmN¼G€o´aY·ü »×Ý医Eü™Ö{‘ÙðR Ûî‚°JrD™Ó§×ò“Q¹q„+ež0õ`JŽüÉiÆ„s}úrË5T†ðÇr2ŽÙöĸ·=ãÓJàʸßTÞ§E7ê\ù‰5 ‘wÌP•ÔO‹·†²x©MõO~XÙ$±\ÏJ0æ>õyèÕ¨Á÷ðÍ\ªÍ¾õ\¨Y3ð û·òD‹ÖÝí¯ü‡h‰GŸÙÁÇÇÍ&MTðC\ Sä8»´ƒ¶ûÑÏ®PŸ¨;ÈÓÜ-Uòñ¬âÚ¢¨çtž8no#x£>Å^’‚…w‹Òg/÷ÞV9[Ä+ èÔe‹©íþŒwH¹Vi˜Ï±Ãꌭ6ô(*Yz=)#”¶^-öõ×c~örmÅõÛ¯¦#þ>ŒÍÿØäô“W$šN{ÝÁÄ»øˆûÝ«éijñ‡À·î©p×ûÇ>oúÝËäo^m팉—ú¶OµztuãRöí¿Œ}­£JZ(Ÿ…Q˜ìÀËw¾ÁѬÎ9ÝMÈ+ìý÷_õ¥µêJáŧ}ýíý[[¸‘a¶mè1ñÚ3dæÑ ⼯îݶp;üöiaäæ›2Ïçjÿ™o}æ¥"ÄÞÞ”Jì¡`Ýf-«„t؃?ÒÐq±ˆäÑ¿jÑW ü#ÁW¡·LåÖgð¤dqøó—±®“ß…ÒõJËÞµS˜ÌU8yÊÒò‹€Éèt+®÷›ó’½¨Y?›TÛ<Ï_jý8{`»²Û/AÑ-%¹I÷Xt/ñÐ^öÐ÷¸Üã"Á?ľ#|OÙÁŽ‘_ücevnÑÜ.ñÊŒÓß–œùæ…¿©Y®G'Š_k)¤ü[ôÒc-Ÿ?¯}*¼»eô¼HC'n<‰ÿÿ\1Ã.pj² ¹â? %Â*íe´É‡F’aúÇ\7¡9ó³­-ÀÍôb<Ƥ Õ-XŸc@Û‰ÿù¿⌠íÙl´áC?õóíz„TA#Û¹…ä½ÁÏ·‘¬Ò*©*¶Ì¹Ž,·Ÿôñçÿ.•r”Ÿ¯8xù³k7ŒwÞYký1ºi6Oèaºy"©àë<’d)»¸ÅØð¢Ñ?®b„3_pÚóx·m¢iyÄ{§ë¸E3ç~9þ|2ʬZ0!·öudyWÐq5z»JFÀg¼ ²{ìòyþ£7ë÷ ꣼xã½üóé:íüT±Bñ¼Œ¢WW+Ö½ŸÕ>…ñ/Ú|Lkq¸¼?7ü5lïæàõ€’é¿sË·xœ…ZíÊ%G®®îsVsMAüÈš(‰Ñ£ ×‚BBAB‚,A¯À?Þ€—à/õ—fß™®¶¾»æÝÇøîœ9}ºŸ®Ï§ªçÕV'B@àkÈ ð?«ACèm?X7„F0gÃqaÇ&‰ïâ"j8W—}`;ùߣãmðMVà¡2ÿo-¢Éoq ~ t2BÔx´ÖyÚá«‘ ç'€¾"ß¾ú~-ø:È\=üQþ†ž=w™¡NÚªé2]¡ãº;–u)¼É0d–¤ä(°åß®VMXܧG3–¿h€ KuEâ¨ùW…!‰§?ýDSMÁ œqŠ×,ôÔfø9ÎtU‰d°Äèe•¦f?=Hî|ê‰L#L—8Ÿ´"€zzm?w:Çà‰Ã8ö§ŸI)„?›Û¶+íqAi †Ã?þðãÉ ¸Õ9šû‚ßeøQíŠ^¨›Ìmyõ45O1ïÚÕ¤í²,™øëUcÎvsšCå¬\Ó!ñ€×?û·œxªL:e‘uµ¶ªÓñÎc­`²ƒ¡¡e×°êìvˆÌfM© Vóðµúc™mJÜÚð½›®_ÿô>ƒIŒ<ŸXYÅ¿$¹Â8$g±_µn †–/&'eÝY0îþR- Þ mä뚬˜â,¬÷½¦‰ú`u.³J–%„_TÆá}Euïø#×@)‚ ‰Ûç%Xò^¼ôŽŸx¬»Rz/‘²Þ(^6~-d~)ë()¼õùÊ®‚á.M/ů«oósEhy¥‘™,p96¤€#Mf“`ØÙä ùJª…°Eìæ8C¯²ÜÁ°{az&6QÆ/f©µônøùGø!ê¸`V¾wÛ²%Lj–2'RŽ?]è¹W^„J¯ÆÅ&’‡n”Ê ¨›5xx)ƒQ>…0}SŠaªM©u»Æùp®#;])4‚²eô »ÎRÒ¢c´ìI»J5]K`uä7?“Ý9é²ÄJ®²0b þ†÷Ërª x[_K X;N!(¿E/•¶ñ*nQ[›<ÙÀÛ|?ú|*Ÿt“GÊ€©à5#¨Í°{Î…$Øý„Ûmí.¢t±FàŸ¡·¢hK‚5%t6©NôVC‚·¬="Laô"ºfOÆ[±ÀBÙa[Ú3oM8~ÃãÕŠ²bºt¨ŽnÕ«†\Æyª’ßNšb·=OCЦ©[g£*fd ‰ˆ®øÃÔÉJxÊBÀƒÒf´DÌ[Ø&%/áMÂMñïžÂ6º|‹å$ÐçS†¬µLÚX+z‰ñÇŸO“JŠ$x†«b*eHÁ[K욃²ç2l×úéŒ0h—e‡‘ˆcÎN¥(wɹ÷ŒÒQOy»xXÜ ýVü²“4ºy eš[§á\`uç‡Ò]y>nOL ÞZާv‰ÑŽò^ÞÂñ$´Üø=CžÊ׭êÏíÜ… AjÑeMºˆÑ†úÉgËŠuR§¶ÞøöâÒ´ò½ø=Xdº_Ôð„3˜#Ìóà K§‘U¹buŠ^P)ªØUk¤­•ùélAš+êP©t,\‹ñg€Mâ” A­™¬+âŸ4{‚y“±î ¢ædÎÇJƒÀ»÷®žÄ) +o ÉG£ŠŽ éâû77…šrÇ…ro$vs=›]ëZ¡P—ðÒ¢´&YJ÷OJÍRX+öµ,0¦vœžTÁgH{ó÷+Gö*(Ü-Ðí¯Â„i]É¿Ap^­ø8"Í$*áé.Ùj“OݲtòÕæÇV“ÿªv ·ü1þ‹)ºä¢:=Hއ´m(!H*7ÙŒ]º¼óé9ÏX]f|¿kû´³ Î8ª›¥¶°¨±CîÞ‘+Q™í[_\äoÔ({_ÂÉu;}Ú Š™Öè—öší¡c(4˜3uÑ©Óø2F¼EÎòÈsµŠ½ŽZãÛ_¬XÖ~îÑ`W PØøp½£%Í6·^¶„õ}~œ•ÑÕ žю ïêŸ.–ƒ×\ÃøÓM<ÈïhÀ´ýhô©'“1ÎVðW†ìq`øœj‚_H,W²r¨ê|À®r(»1ãµÍØË D;úg_È­Ú"ºÉ>ƒ†ü|o ¼‹’#3«ÖÖŠí/¼)9ÞÎÔ(Ü£“ÍÀEAýRåI9cs¾óåòFx„ÌcGˆ*Ã&7IfŒº4 ¬vÈû*´‹õ:þ^8¶,Z†P„¬’üèì 'c¯ãd;ûËiÀìèKË¢]<Ó0ƒg[œq<¼8Fº<ý´—z° ¸Zµ€,*Ëèj‘M£ÊÔÊ×—æçÂ@îøÓ¯–ÏLj6[à—,“ô㈇iºMúº>âL±gß½×Úý̧2Ž—˜!~/Õë 1ûÖŒá'-ÓÞy¶0Ž’Ç%ÖyµgiÞÃñŽ™Î¯ ›a¦ ¿I½àºêû¨£\‚e,WìMÌ ûŠYe¢ïêt†_!]*Ö½%w#j^ñP¼Ì¨ÜŠàrUbo ­?‚°®} —vF¤G6,’·ƒoÔúkžðîWÓÇàËñ+ZʃÙÔøŠÎC»OCD-²ZÎir¹²@ðap*µ•w¦$-’˳âÇqËEÁ[ ø[ÎEßN º¶²ss¾ÓoG>O ât[2þ™ô>ñc9~U›ßá‘ÉÒ{xБpÖ^Èo]7“aÇ9=ƒ=¯Âä@ô£÷‘Ý0H$é¡ù#¢Ãú`ÏlêR’k•ƒvÎ]GA•þìaKãÚèKD5‰ßBÈV©éÍå„e™ÒH^w! 1qÝôÎé/à{“G”ZîÑ@{ïë åJØ… P•U=O„Ñûe)Ä.¸6'Ì01Z"¹…Â¥íü¥àWžFüûŽŽþñnÁ_^†ÉfÓQÇPDfEMÒƒÿ…¿á–A>ÈÎ*~›íÿâ™+ù _èûã£zÇð‚\ü(M}çÄø»ñ§‚|%V»=øŠÇ;œu×)ÆXP-—¬ F;õ¦,Ãá*ÃÝÑ¥|aÉ`_véonh ‰s,Ue=UA²¸Þyö€W¶“Q¡Ô^ ðçÖ=8ƒ´ÄÛ8+­?Ù[L&Æ©£ª.V^¨‹WΊ ,h—öKu<ÛÏ£4©£  å@ÇßÎÒWP¬Ô¢’Á ýÎËJòŒä.ÛÔc´¯ÑÝâaâßošmü:€ñ§ÛVæìàµûQµœgX£LÒwÕžö¼þB§­5ñè%rª¦ + 9Ë3¾f?`‰À¹¥ò‡÷Tþ—º2è‡OÞ.¯¥­aÎboå©|u/$§)ÉÉ·°^Š_žpž9}ž”ÕùðüÉ+Oóß§Û.morÝñ|8X}ƒžÄZ‚ùW²ŽóEìoTüµð=Ú’û”®ƒ ~E_¶œ½Ÿøiˆm_Þê5^Øïbù7U9×?ÿþ_ÿy˜½"¾¢¤ðøë¸zÐÂð&*^á§!*:·Ÿl/UdšÂê[¾Ãg>¿ùŽÁ¦u üÿþþû<½ŠI£’P_Ta'k+þ#üã.“œ¾ÙÄoÑ>Ô¿åÖ®JúƂݥ³«ì}þS(˜<9áoùë|áÒ|xœuziŒ\וÞ}÷Ý·Õ«Wkwu³÷&Ùl6›¤HI¤(K¦dɲ,[,k„ÌddÌx,Ol Ž=ÉÀŠIäG€˜A&Lfvœ‰ÙЬ}±,R÷¥›Í^ØûZ]]յ׫·Ý—sï{UlPŪW÷ž{Îw¾ósë^÷BFÁ9‹Ák"axßCȧ4xÆÇHt‘D‚§©€ƒŽH$Ôú#Ê|ŠD‚às‡R +ÂÙE1¥Ô“pø•pkÌãß _# /E䉈ÙC` ¾‹Ùž ßÞ£°î·_óá·@ƒÿé ˆÒ¶iìá6Ã_á¶w¿x×~öŽË…ùñá,°á+ÀÙ™(ÃøÃ˜¯Lá5ì'l*‰l™ìÀ –<¾Ýo¡?|Íg+ÐB_ø¼%4Ø¢’ ´e$ÿ^¸: <~>Z'E|S±S×ÿ·=I(|Xä·$‘ÿ3@&xŸ¹ŽŽ¥}÷ Ÿ¶è ¡¯âñçÅpÛÇÁÁ/ÁîÁ‚AŒ$nLpXJ™ÿHÆpÞà˜ìtü/ˆ| ;œ‰#'%`S ‚""©µ+i*X$ðfðú;oùX@t0aø$Ÿ>w£Hî‚„YNY¸ñíàö^" à|ÓÐcí½öâîWàqPŒ–cyÙA$väÖ¦,%ƒØá= çÿv^xÛo?‰[ø­è/Ú g»ð³ø6_¶ÄÀr›D<¿×cB˜/áj!>[›‚i9Áe[€‡[&Ñð aRóU(;Qà…÷ÂÛ¶ÀŒÛÁ[(¥m×ñø}ÎxöÇ n[ÞÆRË~Æ$ 䮩m¶ŽÃ fp¥,ÕCÂÁñ|INûÈ-ç+ Îõ‡o{a@±ÃÚÂüçìç|Â.ȾVnR `¼k9ì÷$ mØJæ:¤Ð¯„#-`ö©'¡*[~–¹sà`œ0ƒÅá=¹ñ;oñT½Ð9Dò)Ë)ÈYß¾ë[È ‘SŸÛ"XäjÂl 3”Ÿ%°5øJË톈 NJxBØ$‘žûíA2nኒïË! Øšß{×÷ùÊí"x2T !ZÄná‡3s-ao m—2,…À#|SX¥0Û¬‚~‚DÏÐ8ä–;,™>yA¤ØcÙ*ˆ¢He4¬ /¾ï‹sû½ ’Âç®M“0›ïzž¡œ˜°dÁçŒoÿ ‘ãrn”[ÄønqÄìXAfñâ‹Ha¶Ï<ëH"‹¬Ôò9÷#²õ>g?ÿ”¶ÐºµÄƒ7 xµ=ïS‹?ŒÕ· A¹‚$B„¶ì3ŽsOL1Ìî|p×}>[f`;‘™QX.ÕY‚ úÝ9þþ Ý <ÀªO£‰¼Ør2k\›ç÷cÛfµJ·æ•ZÏ1…#áà,áßlÑ3a¶†5…LÚåÃ¥Ôì;úÿÙ¦@Ë*‡) ¶ÀÜN r7C?g¿€÷q¦‚ê(¦Êß ÏyÍž K`|ày¹EÔ8Ä@¸×÷>ôÛÕJÜ#DÛÿls K²÷Sn@ï{Nè1Fã8ü I&\“Ñ;÷-nI •! -Äto¶bâÉüÛmÉä5mÙ¿×ua¥-c¸n¼[…[õ+à¢6VCÝÛZ!°ös5RÎÅÔ#?_œ†b/Ó¥Œ—Ì9„'iàyä†ÜÂBÒ²øÅ¼½òÒw?O¼|}îög\LUˆ&µ0ÑL0†»Ûaµe2C‚ØàMi°Oü»þÝ¡tЬJÊ)T –Ù €½ì K2EWQ\Æ^6A¶ÂÓÁe¬%Ñ ÉÈÿì­2m¯b42{ —¾P>P Q*C”o;š,±zd=+¬ÓÄ”6¾Û#¥´&ø°é]ÙƒåpÐ?Ta¶!“ F$<¢Æ¡2¯J Cóâ"øÞû>&wÕo4‚ qx²¸VÐÝ^Ñ1ì€\0Ã)É Ã?%A€Â“†yÊ„½×²_ÂwÁ¯6JCmÏž ¼¨Iü¤„GÙ¥’¬™¼ÔbÉ8`‹‚rs™ýT–ôïèßÕÕœ ˜å´ÅÕÄe&Ñ`€RFÅžJlî7Ù•xvp©ÏhûܦXhh•ÜÖÏ-uè4IÁ¨ÍÒ<‹ ¯ð¯Êš%PšÏˆd@¨Ì#ÃPào¦a ìî}ÿ#¦?a9ÈM®â¸«¥ Ä#lµðÃ…²LŽñ'rSQä Af8 »ÒBE åZJkYÖXµüþm$A*x%Ieb€­®ËHÕrXâ2[àK¼]òœïŸ÷˜·a9°Öaè „ÙZÃNPaBˬ†ùˆÁú}±âËvAr0Îgá ÈÞÒKhOošÚ’åmûqÀc¬²SׯÛk¹ÎžŽD ™Èlš {ô¸ÂÛM™aŽe‰hýàS?pãFê ìò]R©6«ûn˜à›ÓVnñÚCÏ?èªuŸz"…NNC5»´Èçﵟ¡’ VŽ„žü{i:zë¿OçV7¿øÍÇ{Y*—«ÀP‰˜ §¨ºì‹Šà  tžáŸ÷@òžÎgEIks²&‹1I[ô®ßF·ßz¯«û`çPOf\‰÷Àé-^Y˜*“müÈ$ð’%R©m?kUöŒ"ƒÏ‚æ=¨_‰V¬ºã¿úËËÉø©ÁÃhßÒÒh}­®b½#ÒIKc»(\· ïêM¨P¥ò<Ç¥Š¨%Ë)KMIu/þo+7yùä™'§¯œë9:zü«Ä%ònBmÁžÍkÅ›Ô\†C‡5&„„âÄe‡Êòßs¯Å,–ÍâŽ1ýquóöv÷ÐÀè£z¹X2â‰Êº9rBKv#]e4K¸tùÁŸé8äðîUâ-¥ËD²,S™+C†VוիõùÅf­¢wİ’;ò¥ûLjMEزˆMW ÀxPª|¶¦Èk.në‡ö7fŸz²"¹¦ ‹ÏBnµ¨U²,83—ò¦kv õ×vÔh®L½}àø‘ñ³ã>Î IËÔýÇ—|ÔZ¹=Ò ¸ú¯ ´µö­çÑâùÍÜꆬô6JÛ]ý]¾¸2þøýñɵ­@ê1Bc)!Çö<$²¦0”¢¢Ü$” Ršcñ™•ȯÿ§Ïê9õÉçNJQ´¾ää¶Äâz½²vƒZÛD—xú™ÝÒÔ±ÒGF’˜ÖxÁ†æƒér÷˜»Š ËYNª§rVºúëߺEˆ q€„­ìñÃï;˜Õx“Âfk®Ê~_òd|ñ-éªS8Ô>1»§h¬XÛ–ãa·VÐ.üri{yêȽ÷»ŽU)àüj6iĬú¦b$Ž?rrc9wðX&•2µ(úᥤ»À}¨&q΢žKàÌEj\Íê—_½h K-L¾ õbìÔŸé–RL]þƒ²öV|A·oD |ÞóBÏÁa’†²\S°ï1ýCpÉt”Ý‚¶vÉZ¾²^Z_íî‰m[•jyðêÇBZÔˆ…Á±î]i€ÐjCñ¤cUÀÅD– è%«"6ìÊÞAWvëõjþ–K<þ šÉ¡x±|käôI-‚I»¤BȰDq¨0Y…Uph?ï%ƒ,€xA"†âð" ¡Ð4àUÓCZn½ÿWÌšO×;û;ÔX¬”_®W·Ãé&jÔÖ˜ý7l ¸öVD£# eœi3϶dUqhu‚Þ|÷UUïL÷Ž7òKÅÕ‰x²kèž/å³3݇†N¤Ô$;ãaÑæUƒ×eðgÄãCd¾8Åáp›•].Ë¥–l^ül-ç–o’¡±”G­üZ!;[–Q_vév½ºÖ50–îê*lß¡‰¤‡‰L¨;0üÑ5?GvSºy~Ñøð==ÅüÚ×—è]#®»­Fñ¾ƒãå|ò¤kPOtXûF„~&¼›UBå*C¦†Q R ß5/PŸ›åÏ]B3¿ÝìÐPº·§Ò@óŸõïìè©–èòìd¥Xëè9žî6–g¯>ðô}#÷£•kNm§ù“k¾ ÔFXÏ ÈÊ® ZÆe…ÑEa÷$òÉäü'õµÛ«}låö¯b]z,ÓSÉåŒtêð©ƒé~M)ŠÊë 6©¢Wæð€„-/,ÂP!”Ê,£\…¥ØüÄ4µûŠëòîr±^.<6f•!Ý®¦û÷¬­U€d9®D¤å[ïugÆNß3sî·Ó“/߀¼§.® X]“‹EY±Yk„ÙÁ¶M¨gKhúÃ%«¤`ÁkÖæzæñÝ,j6ëC÷èÉä+ŽìIĆÔ›`!!*åHaí¢ Fp:bÿa ±C뺀 •‹o ÉËÌ£.¸×jÖÕBÝ®¸‚î†ßÙ˜=óE§Q6¢Õ|ñ%†(”¬„h3ùJQ æÁrÞÇu`l ejY?yÏ/w¨–¹ã,~öÆþ‘³fS“ý'3‘}ÈHA¤,_ðX`˜¤z(r(à ¤²ØÒHÂRÐe€BÁæðCݺ„/W’‡ÜrGGG*£O^¸, ˆsóP`¼÷ =‡2Pg/9?¹â3åm ë+ØjªË9Ðe"YŒ"=‰œ2ºúæõº«é#qº¹sóÌïéú«Ó+Ÿ]8ð@½¶œèè2öáþÃ’ ÕªCÞ9´ ~Оùd¨X‘a„(ndsH‰N~boÜ.u÷÷×*hð(ë¤g.d×&®Q#ÝÕ'+ñÂöR¾0×{ä^ÅëU þ¹±aŃõà ^\¦Þåšù,¿p飯|çwæ®ä&>üY¦ÉuÜ|סㅕ‚Só;=zz˜jŽiÖÕ¤’ÀÃÅ6@Á’àæ(ì£ÃÙµÁ†’¨yŽÃÏ´_h qe]yw¡´ƒ;‡×ç?‰è u6²;Š,÷Ù\[@m,ß칇D;Aþ³~ ¦\ÙCDØH6ø¿JeuþÆÎüGkÕl1Õ¿ÿk^{ëƒìü<«½ýÇ*ëý‡žÚX½’ÖO|õä¾ý©`IT¸`ªèÜj“s2ï9ó-ÄBU fQè"AväÊrÚŽ:š›ªæ6­Ì@ÇúŒS\^F¦›îªT6¥˜±½6]/Û9|ÿãz‡¦¦µ—nxŒ;mòÊe—ñŒccZÌ*‹ŸÖW¯\Ëô÷ôì¹sá×Í‚EblI²•Tªw;{ñô·~wôÉËF Ì]‹e§í°ADD*¨žgSNè¤VM û`<ÀYä„ ± d™T“ðüÌîæJ3ï)¬¢âJ¶¼¹`5‹zGo43 ]»™ßª¬N{àìнý~ ½4øŸQ4Ôt¨ž k *Ç00ç;þªo©½cÙ;Ÿ±¾db¤Xœõ|WÖ,Öw—áYjDjÕìð¡±ÎNݦÅÔp†]I4Q Z¥J]•°;ÐáŒýE~›æµçc"òZ­ k“- h»\EvmL!«‚ªÅjewÓõp¬k$Óƒæ/ÌÖ·otõ&žýgOέÐ?ˆÃ[Shü)óÞÇ¿8§&FW¯/®Ü8rædǧ>;—ìUóÊX7m”ëݺÐ1qþçBD—TV(#Ѩ/zö™|PÉÎ?þûß8mPÛ¥Úž)V¸³öóY.?‘ƒ”–ëŽWSÊYÀ@ ¤—ªI…Md7P­”/,j×V˜vÿ3¿»Q\üÓ¹¦Ï!6€ú+º¬é(eÑÒ„5õÖÏñžLß×kb-RÝÝŒ¥2=½£b¤º8{îÈ#_ËΣ[ïýõчï©›h{šÕéžÞíÅ)³¶ýô¿•t<ÎÿÁ•¥@Bý†§³4Å|¤ÈãM;Ô2]»²RàJ…*r͹]«n ²UÎÍyU³Y¬RâdF‡_¾ ­¨ ›ò+H'ief»ƒ^ÍŸ»\Þžô¼ò¾ƒÇ¥­êÎ’Û¬û~]1:öù–ƒÕ©×¿þÇÿ¢võýsV¤û\Ïðáh¼;–éKô£Cé¾jJTcwÍ|Ú†Û7Ñ4œÃp‰Î^ ¦hA[Þ({-4Ð+5m´½M§?™-,×FN?†ï Í«ùÛÓ®URø‡Ù¯cj³9?EÇš‘›­›»õja[ôH*>°|ý­íÅ P tLÉAˆSzè>$»wÎë‘x3·¡Êš¤ª6…ªk¨‘‰'ŸüúG$Iaíº¤`ÐíH­Û,Kb9Ì;°_«ïä¨]1ÊKfo¿&E €*Á‹—ÑÕ/Æz¦©ú7o]·ësýG‡^¾ä‹d»4XÍ"¢Èo°…‹Ù]ÑeYÙ¸h­\¸R^»å6·b'H<Ýh©µ52ÐT”v7$"i¾-c¨B¾+iÑÔµjªžp\ëëÿâùd'»hfO—o ¬…->N¤ˆOœ<"ˆlîUrJ‹S´¸™0 ¹£'»ãÝU¤ËÅ %7…f.^î>¢ÄõÆ.Ú˜þ̬/Ü÷ä—_¾å;6=n+*%:{~ÒÐûcq©ï¨áEi~Ñ+ÌÒ¥?-,Œ%³ÿø÷zÇl-MÖ®©rÒ¶Qqk¦»÷°&Úfu›’˜Þu+j<–^¸òÚðø£]÷î=-Iô¹¶„u\¨áð~ŸÇÄä]X TQ£Š²Ûhñ&2@²t£¡c¨b›‹7«+—Š»«¹tß(4˜=Р^=ÿ‹§þèùßªÈØ/Âü['»óÒµWÿ>Ñžú'ÏJ9×ÊÌ~0»rýƒfeºûȘÑû;NcËHGÓý-]x/?ûAßða_@ ÓéÚÿ¨£ìòZ£´ˆ»oððNµòÐsã]£àø*¦ºÄX˜ˆ±»"…üúCa9«U5n|´Y˜Ÿ=>ôàÓ#¦b5«ÊÜyÇ-Kw&Þ„ŒOujVšÅÂl´[ùV…Rƒkpèb¤ìÚ^E¯þÐX‹GµHf´ïÔ·&ϰ3÷®&S=Kú®•[‘0é:xÊÂŽ½»¹uãu 9Ã÷•ú£ƒö.Z¹p5+™þq_Pƾatt£8SmŽøPDÁ25¤IlHÉveÈâ"4Æ CIµ¨åÖÑêí•üúüàØYA:£õ;wÌò:rª"ä9‘XÌt+˜à?›h8. ˆ®¾hÚÊ•_^ÌMÜ¢Õ]»º­&{ôþ#»ëÓ•­ÙT÷˜‘<`6ÍîþÃF²³\)ÈÉ}‰DêæëÿÁ«WzǶˆkô÷ÏW7³‰Äþ¨_¸ùΗþè‰Ñ“üêÔIJâP‡²Ÿ.‰’Ã$gŠžãIhÚð V,ïî Õ@•´½P7+´¼“µ*5"&jy[ðÀ´;ž[‚Eã_Nx@ø<:¢ìšI eãÓüÔ[ÿËn”)ñä˜M©ˆ#'¾ò’/g ·þ¬Ñ¿ê*²šL@}¼õÎßZżÑ9鄸:úàY¢dÖ§ît¦{üæîÉ/ö ¥Þ‘„¨ƒ`ŠM± SÒ ¯b¿0C|@¡`z1 ÓrÙh·Ðêl5ÓehQtóƒÝµÛ;±Ôh1wywçFDï4‹æK7š@PlšêR‘8>– —ï¼K/þ¿B®Ù7:ÖôËó—?02ǺñÂ{¬¿8óØ}4p¼LùÂáo wˆ¨NÙt‘Õ k:Ê. =Šr ÖöR®¶ë–wJ¥©x:¤½ugêt_lÀͯf@Ì›z;{û7œââѾ¼¹~µRªG;NºÍ|¥pC‘}#¹ÿèÿ×y´Û£Â²²èÒ/þä©ÿøËÿpìÊoèÅ7~³9{ɵʪª» ³óài#Áhüì Oûϱò*¿ø 2«.›ÒQÈ>ÂîØð» ‰†\B6ÎÃú¯gK[ÅÑ{ÇܺöÞ+V=/Ë’$ fe—éj/nËlªo ªöÉ+“·^[´xŒTòSD먖ªò%YP¿{à~dz„:üès¾cl\Ÿ^™øyßXïÑGûèï_1Ëž(ˆ¾ßåHºc\Hè‰ÎX,ƒÎúÜ3ûz‘¢"Q´>´õÃܱ®ÞkiTPñr)/I2Ú\aî\Yj–Eê¦Íµìò¹—f|ÜDaM]“ÿ\j÷šùðvÉʵ7·™ê:”Ï­:®í:eY&$ÖAHܶmKª­´¹!ôœúÀèY¨ÅÍzAņNœ8öHn3››¹aëYE9fô{dîúYŽ?öüÓ£(Ù m$#L‰_ìºí°)¤Åe ÌcW±Tš¹¯6ìž‘j¡•ëh{ÎYšx+½/ùƒ÷½ZÎR%Íèu” Èéö› ·ßyO—U·¾V/®ˆbÒ ±+–¦‹“îdêh5·_½è 9štê ²‹Ÿ6{>XËgj±Äà‰Çç¯Õ×7‰ zÐHôívÕô¡®^½Z^£þͧü4R¡hBV¿œr¡…Õ¹ßùÔjĤZfY¼4éìleÕ¨.:4;¿±61©ê-ùöOý ¯üÔ1‹ßü×?$©¬ŒâÅíÊ/®[å­úÎd9;Í®—$EŠêª–Z@†˜ÎŒê²±>{NÔd,ëV£B01K’¦¸÷‰Ún>·xC$2Ñ ’H‰¶W+¬v÷I§ÇM›t¸§éæºÇ2²nk‘¸©É.µ9:›ù( ù•øOÂ,ô@sc[–ž[b]Juk¶¼1a$Rµf£þì_øýÍ?¦»^ø‹?AѪÝÀù }æÃËëSïC;¹oÿýýãƒ÷õTkæûõoã‰S#?ÞØ],¯Ýôìšm›¥Â†¨DE,ñîµÉXg/†äkÔéÞz½T«ok€7ꬬ™fÓÒS±O?Ù?®ŸÿÕ'GOŸ8qF7Ýœ¦ëv]#ìWª&/F¬Ót]Gb/¥(ºu´µ‚²³(¢ J¶º5óf<•pl³Y³îûÁÄÒùŸ ;ûìO¾V°YM½±´=y½°rNŽ(é¾{?Ñ=ÜQ-ç/ýògvM´Ý’¢K±¸>tè¾åÉóÅ5A–DT%e–ËÔo(]ÑTEQE¢ÖÊ9!’R"¤QØ‚8ö¸ão~û_ý^q ûŸç ™;|¦ûðCz³Mb‚e¯â`KdÃR^gSèWëUºµbÝþd&¿˜óêÙ%±Ç¾óÑÊùŸžúò‹–»íF´}ãO¸ytû½¿®å.EÓ÷<ñâÊôd£ZP­°:)kÝŽçYæ.LE…òÙ'™ý¶eE"™ÜÒ€YŠhÐÇP§ŽíHvíô£åé÷þ\‹È¶U;ñµ—=¬ ¶»páïœê²‹«±}ªÑ[¯“§=ßÒ’ù¹¹†U¶Ì‚ïÕ‰¨‘´ *ŽcËD6+Yh¯T=åS[‰Äe5U…®[51s¼{Ä¢ãÚÎj³XS”ÌÑGžïGGÎѸƒí¦‚`”.ñ~p2â÷€®T+ÒݳsŸÞ¬¢…ièâÑæì‚ÈfItè‹ÿ¥Qš oKô¦¿ê­lßX¾úЦ& Kò|¨ƒ®–Ȩ‰®ZyÛ'ØÝÊYà[‰ý°*¬(*À¬²µÍœOk@ûñÎaUϤ»­Î^nÔ*‘( °bNÔ4ËZ¬sgsNO~4=Øë¦Ç3­ šNrdhÐxý‚~B` …ÊDE£œEü×éJ®é6K±L‡eÖò›«¥Ôõÿë35âxœMzÙ¯dÇy_­çœ>}z½û2;‡n¢(‚²D‘Th)p$@~0 aÃpòlðKä/Èc#p r!°8 ²ÀZB2W‘œгrî̽s·é¾Ý}–ZòûªÎz†ÞééîSõ-¿å«ê¿òï…J­y)˜—’¥Þ4^0+µg©¹\Ügf‡³‰wÆ,Õ½ŸÚºÔI*„õ®²†q®¥Ö̸꘺ažs7÷¾IÏɾ›B¦¾Þc~¦SÕ,ö¸7Ü3Á˜gÞ{çcœþ¸ì¤C!ù¼a¬s^¯¾áÕz:Þö’9á¼O¸ÔœÞw&Œ+æKá«á·þÒzÅ…öøZVámL¥œsfKfÌá5wrÛL®{S2Þ•ÅÝ\«æœ7Ü•á«R¡‡Jëj±¯åj(˜ö;mŽ¥î0Ýçù¥N±>?úBuzŒMû¿¾Þ2.°l ,VÏ¹èæƒ³Wn?8ðz5ÉǾšñlUžùN-ÆL*¬ó,g¬æ~*¼Cè†ßüŽ÷ïp_r^Z_³dìçÇîèc;yßU÷}uȽuÖ29‹¼üØ»s ézéE×É‚á fÆdžŒ_"kŽÞvåŽÊ‹Œé9‘-?ãšýòþÏâÆœcˆ%Âä)öô“RÆËçžýìÎ]®;æÑæä0í]è~õÏfò²óséL ïKe¤?bvÎxoôÚÁî{žï…f‚'~vTí¾Õ½ËÌ¡V‰Ò½Ú&3žtýäSë¨ÄséDÎõ(+ÆÕ쨱‰\zM$©¹ÿ·¬ÞA@-WBä^ Xº¥ûgðb³ÿ®p%–í²Yˆ;~âB(•,/omžâ£Þjyo•Pº{i!/ûñ+Ù¹WX3áBy–pV Y3oð ýW~(è[”’që«öðSÞœ v~§™ÜR*É Kº®Ù³Õ±8²(^¼™9Š H訤êòéÙìÂï3»7¿öïìô†”Z÷6$딬§V¾æ›#sð¶ŸÝçTÄ‚*UDËÇß±&„ìt†Ë«ã½û7«¦âôÜu‘ž)˦{ñ÷üèyâôágÕ. ïj©êâõ¿®¡ ¡.JXµc>¨>U1— ³‰­Oîq^ùú÷³Ä3#{N-£_„;a®q(xžËlSŸçÝMnv›Ýÿn¦·`pÆ£{Oñá3ù¤ºÿ–èoÆýfT@èbƬTÇû¹·ç’g›ùö÷êé^uüI2º$6~×õ¿*ø‰Sæ”ák€ É‹WD‘䈩æèk»PbbÝ\ìÿFt¶’ñ•òðc÷è#^ßsõ!B%°Ñâ¨r‹‡jW|û¿ ?•mˆÔ&ÌkaGKWH¥ºÎg 3Ü}ÓO~ àb®rkæ’rÍþÄGÞ8·œšñ–¨& Gm^RéEÿ @õƒ¿C Æg•vº»±hò£‡;B˜ìs½$OòbU –ñ!$Ò‹>â)ÞB¯ÿ„ûJ@+¢‡`+"ð¢D–Žž2‡~ÿÝúàÓfº‚f]3E’ xMtDNÁªg¦š+ÐC£ Oè}ã56‹P@’xJ ž!}¬› ?£øK™Ý¥þ¨Ï²µ½ýªq“¦zéÚ V²·.5xoj³N¡n3J°þk? @ ÑÔÄŠ2f¸¡2¨^G¸Æ+6ù¸¼ù÷n~Ÿw¯p;mf7µ ˜ßu,ï Öysøc" ™ã‡NÿLÝ×Ì=‰Æ[lÄaý!ø‚NÏBÃQõ+™¤*ŽWz«O\½úi²ñÝdëûu9©"Ú"¡’|qÃ’!´˜’ 83zõ¯Á"Ê^á±<Š%0'wÌXà2åæ·ëÿѼ—i.·ÿX”×f@rtêèá3å‚ñf5{@PÇ ‘ŒtÈâ(5ëmÖÕ‰­„E’lŠr¬êÑFÂÒc´ôÜ ¯þü_Õùyá-+/ä¥%ø·5ªˆ‰_’•X?}‹LIOCˆBüJ>¼ã›…yôNyï§~~WúÆèKYG"þ-À„]°ž7s P“]Þ:[ûJ½÷ËêáûH6qªL‘Cï,xÀâÑø¢‚j5¨Zºí uVtÇKK£s[Oþü­Ÿëµ—íÒ+¬EŠ ‚Á4e­p°$ ^ÿqÀz|J9Â,4šâÍCQ´¸óS7»/€8rˆÔ˜f¢%A‡±.©àÏ—Åå&;Ë;ýÄïœÜüû ÔSÔÀ­º©ËPÿ" QH5/õ5µ*H¥çΟ[*6~õÞ›`_\P+/¥+/Š|©ñ5R$XÆMIÿGùÛ„Û¤÷ÆjÖR?#FÕ ¥Ç7s¼ãçîÑǬºã›ÂI*´•,Ë“]†Í*¨½Ä{¥óUˆ_ØÐØâÑYÚ­æü1;ð“ˆL#ÖTŽT_@AõC½XŒäÀ  ¹½¼±²ýî¯ÞD-{9dÝ'»WþÔu7)¤7Ï Â„ €“þ^ùOÐ9Ø:Ìg ÅUs`>7ßýÀWQü¾ÚåŽ7 IR/Žq•£ò´Ð©ifèP*ŠÒ¨í… jAÉxƒÔd-ò ¥¨N{kÛ«™–7¯_Èðd=ÝúÜþmÛrV¢y…Ìd)‘Z-tæ|=úÆäY޲ä~a?bå=ù$úéèyƒLù#³¸S}fç$0Ü7!Ý,°týF-=Á8÷„Ðaáü1Ô“è%‘C‚€1Ä¡‰ƒ ―«g¶´æ7¯~©¢:çó ÿÂŒ_tYµ.s°6*•Cß_2¯þ%}âSO÷þOsø«$ÕÞ%zø"ÓKÎìÛùg¾Ú‡%än&°¨^`¾;ï„•.ÒQ„]tx¬ý׸ùÄš¦’–j)ÀÅZ¢(•,I;+ÛÇKËŸ|ðv]VLõ}zNo~7;ómždŠÊ‡®`ôT!)Å?VvÖÞ•²°óÛlö›Ý‚rK†/é•×ÊÉgõá[¨t„à õ8 [[¸ŸG N5ê£\£Ä„WR.sJì’¯dAîU†½XH3¤“P÷oxÿ¬‡[„â¹÷ÓòÎßH{¢“©Þåþ™×M¹{|çC󀬜39…V†c²FPÌe0±T!’Š‘·$THU"ÀDU°-V°:h-b ’£®!M°[F®o¬-gƒÕ[·oÔ‹9ÂÅH•çÝKÿ\]ú— Ï…<” "•?Äz9Ÿ'£×zOünmµb9ý°ù r:és™‘Ã/ ^Ïv«Éx:ê7kÂØF( ã–èÖ \ãÍ, ¢'«+3¥‹¦:ö‘<©\Ô ‰˨ u’ŸÝ\ïŽ/}vãóùɾ3' ’Odjéë~ðÍôÂ?…àxæS ²þóùÚWæ'‡@~_Þ‡–F|¼è²™T8V•dKhئÜw~GxÖ•Wýa¥:IqÎâã†úÝÛ:¨‚ÌÆYeº÷!lNÈÊS;@ëG—³À#¿ò­e¡†§³“Û<‚—'{—­êñKÉæë¼{Ž%KNåœxß_wò³€)ä† Ž4’OwÍ„“ÃÚ3’üEøCœ$YZÔ`¤êá½:®!·`ö™ ž+½¤Š3u¹ç7A"’êE#&PïA?“"ó‘¬ñªÎ7ÖFE}ÿèx÷Ñ»`2Qx®¶Šþ,Y{λB¨h­GRRE Ýx¥nšÐŠ"8b”q_ûðHOüKt‡à‡²á1rœÅþÕz•§T™lÏ…ÊPÅsÍ×Pj'·Âë=}<¡¦§÷fÆõ{ÚÄjgyÐo]8žNövîšÑ\÷‹Áz9¹UW‹tóŸužùW>É…˜‡ j‘vÖ(€2•Ä’ì™’p ôM+fAn¹  €ŽTÊÊ}â›)‚MÚK&ÉHÿBprÖ Ëë0rÍ Øa4*À¤Ñg’µ¯_ý+@˜-LtŒ úW™S:€®Bëb¼±š*1_4‡Ç À.ô·\ó"Ä©5ž?eêR Οý«2¯²N²â€xé’õ¹LÇZ;³øÜ-ve*z"aÁÙªÃ]ãlI2tZðÿÄV) Ÿm`U˜1|ím–å“•§´îÝŸq3!ê ‚ ù©Ãª ùK»KK«[ç.ÏØ;*°}ª›£÷$«•êÖ>ï?óGbõ«FOô B5ßùdùùÎù×ê“c{|ÃÎnÙr—›…'¯Jø†G‘šq¤-£éh§žÐaŒâOA)ˆÕ8XÅ(¢y¡ò5™÷˃«è"H O¶…È5ÐmBÐ*/­9s¡ñüêÕëÆÒá3ó‡ïx; Óf)áOÏ}GöΊlTÙ°»öF÷ò÷JÖ-ïýR–·Iª-€º4Vƒá¢9¤"xDÀZš¤-áw˜28ÂÀɈ*ü©Ê‰|A¤–±xò5® $G¹Ë, ZLrP±n€Á8„õËlmíìÊÒô×GW¯66gÉ…Îêoq÷ÌËýk®©d¾)ú—º—¾ ^Æg¿ïôЊ¤9ºêw…'Š‘¢£uÏ¡š©h£Vé)TúDÐ;dXB‚§>¸˜Dg#g+ðÒ"À–-ÑA{úð=×Ò'©~d`E³ãb‚ΣåÕñXªÎÿZuŸDU§K_Å2K‡Z ³ÿþÉÿ7YùzñÌút™¹¹*žDÅ'Y/ÍòzþÀTT¢ ŽRfxº…U¯´¡Ç(šNrEk#jö§©M¬‹ƒ}’:hÏàϰ؂ë5‹b±‡¾y(X˜G¸ Ÿ]4]Ÿ>ü͆ç|²n¼¨ü¢7Þ²óò¬äè¥Õ7þmoå<ÙÖóºœJÀQV,NîNTØ€ädT$ELë¯Â¬ ]‰Çâ!4bT1Løè€#tuðÜíäØVÒO@¢TQ§GÊø(*B¥½¦*!±)•ôÓ|m>Ý‘¼V8Ê#³ XÐËÃQy=[Û>xäÜ~ ô™êäsoîÁÇRråhùÙ?ÉW^Ú½ñ³dé©tãÅ<É£uu„óˆ^G¸¦®f¡/eïÒêA¹0p8=´TÀã14©Ç{"(ºØA$© ·Í *Eë.X-/ƒõã‰d¯X8Í ¦(zã¥õþÆÓÜêá$«f¶žÜ°Ð®t˜©C$;ز,Î镯ðîºî,…DÔÖHAŽ»f&‚¸ua¼ò ¥ÊKä¼m_ŠXœü˜0‘¥É/© ©!„Hähè •ˆ#;D£%//‚^ ø×,ï.–ú+V½ƒ Lïm|£žÍx¾ÐZÜþ/öð]Öœ0™ÉÞålóé貃W €ãCy“у³cÁ'ÆA7ö`ƒfDø£îx‚=G"ÕÆ!'™_Z˜£t¤½ƒD‚Žõ¡CCÍ‘‡îÁAA**~g"w‹ÁæÆV>^¿±óhæÃúø‹lùeŸmgkO6þ¶ºûß|¹Oçx²ÀºX£54–Rb‡o…ò¨áˆÊ»(èü¾%¢|z{ÿ5¸d £Œ3¶©cG„7Änî>$‘†W¾x; s‹p®Gc´¿¼¹Yœ¹|íÓÛùÊËåÁÎɃ7»+W +šr–vRûèÃfö€&Ø<dyßÓA4¼×ÔtYh+¬E ‡&Èä0îfN‘ü’Ñ.ºä¿ZF&§Þ²íÁ®<£ko]ÄSº(óØ—Hqýô:pÒùhmcüÔ‹wwÌþçW}u ØTii5bˆ/´ @Ù › )å.Ì¿ÅvU„µwõ Ù·8î (-ñ>4ƒ!ˆ Ô^ÃÁvÁùœO¯˜Ä Jƒ‡ãNÞžèQùEREg0^YMÇëÙú«7®Þ™>xßUw¼9&Õ-]«®>€'@ݤ÷d–tA LvPöAsš@æðÌ4csm‰ˆ›ÊÔ¤h[Ò!~2L¥|8IÞÓûVcÇE#4ð´¬ÑÉ cmØ.øE3:ï3!Sª×õ‹¼?ïÙƒÃÉøÌ+Óû¿hæ_è´çX‡&Ff?ÜÜ€[éAÝ%:‰Ç€˜èò𠈱Vd!4Ýx¡Ó0…}ØFÎ1ò¾=Iô§³qæÛA(ö'ã±/^JÒ¾ÊòÅì€G‚ ߯ÃhÚ†TÊ"íuzy>èžLf{»À}TÍ4œÓDI?±XCqí< /gãXÃ9C™ ‡ëCüýÛ$Ñ|Y,q®ßÖ´§Óä –©u$þb~ÄYl\C0àÐ;Y¯×ë64öÑûwC´°Û‘u¼k#3sg à. 뢌Ç6?…Bˆµ}üa‚$ Iùò(=ª‡Ók<±ÁÚC‰VZ†?rGÊ$r¢¢= ²ý¡õc ll ðȰ J¦÷÷îò¬ÃØ€…b †Ô\õ“|„˜$k/°8ÇqJZð Óà"¼‰RÒÉO×Ïã0¶=T &é‚4õ‚L.YŸ,7ü‹¡¡ Á) (G×I‘h —Ó/wwnÄéG Ç0ú¢¯%t÷x¹ /œtFä ›,;õ¬Elï\kO£jãQÅ¡-Þ·7XÛ©R„Zr޵‡£(: æÓ½HR”‘Æ{mØãûÃ÷èõÓӉ̓äÖÍëÞ·g¬ÖxœrÂ4Çìçñ0€CKìSOcØvm¤­ôãÔÅ3¤üÇò(¾ê/Ps¡\MVÑ©p #…©5p¡²ÛôûË}è©›×>S¦–÷°=¢ P"MÒ‘¢íÈÈ§í™ ‹°,N{Õ… :qÑΟvq;¾ô_b}{ãOSɇõK‹Å3³¨£âÞ·G`ªÛíçX?¤ÜýÛwëÅÔÚ2¬_‡'ÎÑÝŒkëXVOgú"øˆ„кÞÐ7âP?§ê¿¤"šÞ^ úR’Æž íÂvÂŒÚÇKb*6l¨åÓˆµäHÉI (——ó!Ý2:™³ƒ{Ÿ5‹C*˶ˆ,]½ è)¦:é`[¨”D¶”. ô¹„‹9ñvv:œ•âÁ3ýëÚ²ñ­|‰:ß·Í5í²?-ÆØ+"\A!"ïd¡ß£nľ¸ÖÉêêZÚíò|ýƵO`…`¦£ÛÌgÓ}Aòч¶L¹¥KOe½-n®ž…I:\ oè ;Ŕ֞""´)hï´tÒžÄDÎe±ëE+9Ú¯‰77"Jðxå&Þ 3 ºžš$ÉÒx²LtWM瓃êdO„jC!Ñ)jK-€Ð®HigD㦦W¤¢m¯7FkVGÄ-_¶77#Ñ…•S÷¡Ë"°hÍÚ[’m7…*†Ã·7‚Ny0¸¡$уb ˆzõÞ½›õbKT…UMð6ÞŒRºÓÔ‹D¥a).΂Zë 'a,ŒIñÐZ¢¢†vÄ­D a°Iò_œ6f›Ã¸{ÚõoÄÁ(ÏO/âF zè÷EPŒ×sýÃj>¡#¡u:¨ë9ä¥ £}ۆŤ*;ùq2EÅSNÄñx”Â.ü?:Û*32A¸ÀF(•æÆ4Ì´öŸ®¤µcŠVKóÅ·[ˆ”ï?NH¥F£åÞ`°yæÒ§Ÿ¼w¼ß[KvG$ ¾–ûVß²P„0ü4ñsñ*‘oÅ0U@ŒûRê°°…ÀÑA#Ä2ò­ÞaQ©âñŽ®"øV®6o èT´ãB¡ÇvÚ±SÊé÷ǽáh}cë“ÞNEàÊÈαëÉx€R8w¬¿ÊÝEñ˃UqPé8dÆùÇg¼1ŽñÞ#ó§‚-66YÞBn@¹ÇÕãOƒË$°|Ü -%Ïâ½éx¼^ô‡ËëÛ·n\ß½‹ i8vä­Œ`6hIê:²Ö*=Ííc¦xP}„òÖE´ XáøãÓ^ÖòV”®¾ ìi‚hüè|+WC}б‰L‚& 'Ñ Ð§É½Æ©»Rùòp}0Z^Ú8óÙç×öwïÑÍ±ÎæðüW§÷ß©>Ótƒ–´˜§Äüö1ðõxœMz ”]GyfݪºÛ[û½~½ª[­}µo²åݳ8¶…à!@ðÉÀÉ9™œÃaæ $d2™!œ™d€áLH°É Øã1¶A [–eYÖbYÖÒ­V·zï~ýö»ßªšÿ¯×ÀèÈÖë×÷Õ­ú—oùï+½û0a\ªTRB(üG ))µ B¥"Ê JIÊ-’¦†AáM¨P)ü®¤ŠÅá|mXJ¦ŠR¼LIbàkI¤•:¸ƒÕ$.E9.B¤Ÿ…÷(Q"%ÌO‘TâM n¨DÕÔ[æŽÌO2+›_¸)ˆ¤R5£Ù_dÊ*Z)½÷eBRE`ÓpË0,C¥”À¹êî’Hʈ!º§ã7I(£¸k8 ]QܘaØ¡ŽÅ#` à#ÜÎàú³x¾ÓÝ?žO„û‡›R #„ÄbŒ„³¯xÏÚ•mnïæ`ö¤hM)Óì(-ï%ù­¦› .þ£l#I½tÿQBcÂîVâàV¸2,K3pC¢ ò±Á8„š®,8œÄpɘ:A„ë\p} ÆaÛ°ˆA¹ÄÂk ÷†1§ ¡Ná †žÎàð[8¾J]’6-æÇ‰öäjõæ‡nô¯þ#Õ¿…Ïb9Áþ‰>àÚÊô?Bgî³ŃyLI“Ö”¿ø¶Ó¿ß.G³oĵwxqˆ¯»)n,ž¶GÄõ¸5]~ÿaŒ1§"ÅELhܽ¾·Ä aŽ‚,èèts¿Å 7ð2¬vÅ!ÔJ€Á‘!’Ð#Ð5F GĤàõ¼jÌI}’˜«: ×5‰kè<)&  LG¤“’ÚáÿH’Ð>˜r§ôÀaìS–apBÜ ]%s°„A‚Áé$ü`ÌsÝ}*âæ ìÇß°»…§6 #ÐîRvß'ºÌ ý×ö¯—0dlÀþu§cäát*M“˜Ú½*N  ž¤P ÄV"(¯N¿a»»¼ÎoO–„øS)ðRX*AÂ-aW,cˆŽî5(KÈT§2•,ƒõ aˆF$À+(?D¥kŒâ>Ð4ˆi)ETÁ#`¿`+Ëî;F7 p^X„;øyÅf1P%°²-á… 8`Hê3L‡c0“ŠÕàÚ ÞÔ/Š&œãå² ŸøQx{S`‹aÇap0ÔâOÜ¿ÂꦆŸR|uNð\Ô¡޷àa¬Ñ âàâÝÔk™2~ÝJéA§ Kq¦ ¾Äûy‰…—Ú¤-UaC&oöˆŠ´©D§ç¡—´¡€á²$ÆÑ)–YH4S¦¸2lR¯C”p]}ZìÙ-o¼XÀÉõg5ì@ACVR]fP6Ýú17aÛºÑà³k夥τ›ÐDЩSƘ„Ún‘ÁRºz–„‹2˜…ËYf°çÁ—–¶…Ô¡tÀ"?ÑUj ‰!$)iг0̈<¤[?˜}-°h^8‚Ó(ÄP3#v%¦Öа€QBÚÒ1ï~V‡NÄR™Ún¢BB.ýhá¤JªÜÉV1ò¢üðIõlçÒÓÂ_‚MÚ=» þ•„Ûq$)¤E¨ê ìj_ÓÙ‡8˜Y$‰û‡ët‰j„Jƒ€¯5)3,„Z,%Ü$E¸êv·ÆR™v›Ýø-ŒvE~*}aåàl$õØçÒq’¬βâFeŽ8C·&‘—¶'L›¿¯@ÿ¾Œ` ½++¬Äj\p8Æ&ÕÆ«Xã)¶-¹ÔI@`¤xhÄ|¾VQ)•Ít]RÖ N5LALðÊ5 äÿûCY(<Ž«D,¾Þ¹ð”/:Ùž8Ž-9Ã÷=[y¥ÇŸþU2wÊ;¥‡ŽchøBP¡º§ ”X†ø£¡Å n"îî¸l­rÖ •vË[¢}X¸”>£Æ|¹¶òoÿpÌ‹ÖWúŒŒ" ÅBp4¨;ˆEû⢥W]ÀS¤ÂÊŒÜà CµKÿ[ø Ôêqô<|Ü ñ¯÷Ï‘s!ìÊ×m•Ñw‘בE…‹×p#¹À9Ô<ÜI2Ú•Ý Âk.° º[í¢±A~sänf¡ì˜æ‚_c…â7p=À§Ñ¬üšX=o9å4s3½½…*l æ‘ÛJÃ" @Ä3ð¦1Ò"¦?·1“á ØDu‘%Ž/Þši Ð­ª)8v„3Ën¾ºÍ -€¹Ót€÷5¡‘5 Ô…‘€"4òÐûqõU[-ÖÏ?'ßÌšùÞ¸³ä”6[V¹³t:õçJ‡^î!FUSùZ{Ø› [Q þÂkßÑ@­0ËJ«b¦+8œ˜Ô¡w£€ñ(–"ž.HäRÄ :…w#`£þå ¦u Ð|m3塿ÅÎÜQQ}EÖß^= ÚNå†ÂèÞÕ¹·ÜV§¼5¼ðÕ¾Ðûðq  SAü-ìS*M5ÚÁë¶­"*"ÏæÑ…Æ:¤}.¸«Än•˜Š”cu-Aûò ‘-e‰.5Âk µŽ²Æƒ;8¬4©@ñèmW Ñ&£™~îŒ7þ”¨!*¡îˆ‚sZL‰ˆ9ÃÜŒëçÓÎDïÃG»5 ÁÜúMw­¡¶-ÚTˆ<–Æä ·˜•‘è ,"´x@ GØçZÇ †ArP‰¤ðk6®w Ì24M¬ûׂýcöQ6FLØN%‚xu2—/·§ûËgËë÷‡í• ~ ´sʰQ5ÒöL¶0Ð{èe ÛF†´ŽÚuFŒêwPT(¤NQ䀠å‚4a ¤ŒBQïŸ0L‚•ƒ@’¢6@ÎEͦ©ôLªe3ÃZÅ剮ƒA)¶Y,…Y„p%‹'¼ñŸÈ`E$3Wá–x«"MÍÜP´z΀1¼V9ñ·°ºl…LIÍ ™vЄe [AlÀèmÍPðƒ^¥!#É`ñÀf¨F'¤Ü zFè–KªE‘¤+{@’’D+c"áêjÌê÷ငN2!©—Ìžˆjgs#wA°¼•·ˆH¨™çVÖГƭò¡£†i—ü–u»†³@L´N€Óñîn±UeR¦!?TÔ'Œ²¶¶½B¸ ã¬) +´ƒFÅò7´)E‚0QS¡éN¡,w%=X€ŠFçóo¨¤ ™€ ÞÃx. bÃ))éSNK‡Ž£&é]ƒë•¡òµªákâUY×çP¾€Ÿ€Û¨1À‚á.ºâ°ä&†#µ¡TFKµÊF"5ÛÚ¬ÌÆâ3‰HKGÛèr7vvß$‘†)¥`‰OƒjÚ˜rK#A{‘Xn hPØ ›‘õKÁÔ ¥C'‘1³K^F ëÙÒ½xkC€¼‰ %l‡ã0A†ø+ÃD̓„dœN7>zj ³è)ÒÒëÛ&ˆù÷Á±Q{sM2 X ÒGœ4ò ò,R«Ÿ{2X>gÌ]÷±„Û¦IZ'ÿ>ž9ÒûÐÉ.=aÄ´øD¶!]–qôJЮga –ÀÍ û:4àuÜiOÏí&Å! m® ±¼M'"¿ÀTˆ[â9! ƒ®–U´}¦]¤¨†bœ«@Yq–$­Y*Âéï̾é_ü'-ȨÊó[ó[ÅaÍ«ÁÌ1’xýžÀù DlÁìcA h§ (òŽv´PÇ8T1Ìx ÃgÌ7:×j§ŸÊÝkÜÓ‚!l<¿Š$Õ9U¾âØ!ilLÃĉ‘ºø©na kXµ€@P~Aª²VœºÿKÒÏU¶{‹"\ÉU†  üÚU‡àÜ¡SÊïl.]|ø„.T(¬^m !ÔÝA :1ê`œqó@d]§jçîpá{oŸ´çÝÞëŠ7|®[̶iìéR!zBÔ‘ IªHË?ðÓ î”ØÐIÚ3¦šõà-ÎÒ%*µ+dz;ÁºÖÞyRù‹kHfvø`í¨=.Ÿ] p =nGŠc·ô=| 9‘::\ˆ~ð£À Ѻ^—=‚9VfÌõ #ƦjÔþ5iMf)»õ#Æú»¤C U tPÔ†hE Q¨C#€r$ÂZ.œ´ô¶•YþÔÿ ç¸fvj"íݬˆ¤ŒXq—YÙ‰±iºÔtüÕËqë*l¸üÈ1 iW„ëÊ£ŠæHOPºûï©Ñ˜¦6¨ Ý­–ÃãÆÑ¿µ·/‘ÒùÃþ)Ô^ÒcÐõJ¶ ZGnäÑD n‚ zÐED¡¸ˆ@y°>Ô» á_#9Búô¤Žl‚a°8°C€rÝÈâ:аè6j½‹•cµ³ß•õ ˆç< Zç·ÛC7™};yïV;!K/“?#qÝ,Œæ7Ý–ØVúà)¬ú^¡Nk{o(MŒw‡(>ñÄ Ä•æeð#Ɖ¿¥Á ˆÛòÎO™› ÓˆrŸ#8fÁohûÆò2  GÍ£œFšY r1I™våGjípþXZŸ·3…ÈkHZvFî¢Ù’¦u‰[¤&MÚžo?KÍ’Ó»Õ¯]è}ô]òèŠÁÈjTÓÃL ¸&Úµ@¾(TÒ‚¼ ®•cõ‰×œÊ͹˜ð"5…Œ;zZââHÉH)ΔÀYdaŸT”š’áx‡ëø@Ü¥&‰ÓÄÃpÁ6Ì|Ü©+ÑŠê=›nóW&­|4R¯7–˜AÛWŸ3\å‘S G—²ËÚ ù…ê0Pnºà‰æÝQ$´ŽØ2Ò*ÆK'㙟™†úÙwKq瓤B˧6hcC†Œ"Å(9Œ Nù Ð?&‚jÚTÏ[l#MPœ˜íE)3‰h]|ŽˆfP vYÅ‘”©U¹ÎÙt¿$.—Aëä7•?Uyd§À Y _O–À!®¹Ä%CO’±bÿ@ᘂ{TøœÑhuÊÍ)®ž) î EjÝmÜ RÃâAdq@tgcDš}3ΩE‘‘ÞD€ó!̳-i"ýYyšÍúKþ¥gÄÒÙ¸ö6\YØý'æúw±L6ã$þôÑæô;½»?>ðÈI¥zN»6ܨÑó­aÐ Ä8Ä2s$m3Q]~ùk¸u×´µ|9n\®¬ÛéG‰*ߤ »¹,P—4¦e¦GÓèÂ8RòÚ°ˆèYœaj»ª” õyJ³Ê’ÍsOp¶â”6ò̺å·~|ffz÷|8d¥0¬GK§“å“$ñ{Öíxätz— =EÇ!X/í§\¸£ZÚm© ,“V—ÿ{Èxe߇CbÓ‡IëJ4Ë¿$úî§)LS‚U¶ŽôÍAé"ª0 ¥).m”"ט¦mœ5Á}c“§\e,æ_ñ.?µzé§ iûö†w$I(“¶Sk-MÿÛ½£¦XiœýÇ´~±òèÛÈ~°5~诩ž¥hU0ûÐЂԸËÌ(IpQ“‹/7'_c¹ÑÜØMí+/°ö•0 *þmÒÿ>œÁ§ ÅXBó ‡¢ b8ûBp ø£b)€'K_ZKMQ[²c¨DysñÊ9™v²ëÆ2>dÐÊöš¹wt;öÖâ©Õ×ÿ§ò«½NâÌ¢ahòE'›³ À˜`œ¢Öѵé“mè NãÚ™ïæKý©ßjͼ!Á’vƱ±ßO ÿi •FžZawˆ¢V? @¸ãød§%ðž`6cT¤‚•$†P“´SS*°ó@|ÄíÙª Lô8*ñ m,ýFà»öÈàïzÜÚáV‘\"ŠÆJÿ©vß´;5™j[޵ôúßC”ìL)\:颜‚(5îËïûœ°à¾vÃyÅb¶öÄm1ä‘I×ì+â4 øÀÛèȈeipÍŸ9Q»ÕIÄé#Åu[ãˆÏ ™áý~k²þÎIä™î€hµ†zN:¥ÄI‰ÈÓ}DˆB€šÑ„釂p þÀP&¸2e+©]hMŸ€‹MPl³GA:Z¹ÑÂö‘Áûé0S?rR&Nq2 ýß}Šû¢• –¤™> pH™F8Á‚»&^¸r¹Hgf|Ö¬Ü6zï¾úÒ¿a,²2¹°ÙÌmz8h-˜• 2öJ›îö§ïÿ±Ê÷¦øTªÂzÜÍkÄ¡D¥'? ™D袴è¨Õö;OÚÅõV¶?í\«¾ót&Û RÙó:={?Y{oì‡Ä²RÕ$FêSO´ }61"¢š·D©Ý·ûwÁJ¨î“Nø½CV_ùZxõL@ýH;¿+e•¾mïñ«otϤç¿wè†OÖæ^£vƺž˜}|Ýã`T+w}V&m%8> þãÿGWˆã¦•‚ɘ æÈlão¦H(·\oîU"ƒÜÀ.Àa¨CæZ=û;;R86 ÛkCh9-Jà_vûíÎ¥§IÞð‰—¤U#n¢†À©éçý')OšpCð^ÜîO“:X6ƒ¬ÂN0Gi8#¢e`ÒÁ{¾i­¼°í‘6,p+©v1\é§œàžÐ¨ ”½~b : ôMÖ¡Þ¹Ô˜<™&Q¦Ð€h –³}ÛÓ4?vVßÊ­_ £*PÑU«ºžö £,“šë,Uýh­¾Ÿ Ù(µóÉÜÉdù´Ó»Þîß^ùImü7ß/ükI°˜†5fU˜U2-ŒÞ³zñ§ð~,Z´S?ñâÏË{Yш´Ìú{èÀõ$3`à°%Ňb8ÊÍ'À)vL¼¹`ú´³j÷ïÎo¼¹qá§ÁÔ«Nn,ñÙ¡mI¼ì_}Œ‰Ñ}–Í{´3íâ¶ü†»ªã?ÃGD«ÌðàžCKç4/9÷ãT?;‹[xÏ»gªb |oòèÐòÞÇRœÏäA$â77Hn‚÷tÜ•óO’]ê]=´«öÀMq¨¤•ºÑ{OâŒñÔƒ†ÈÄ‘ˆ«ÍS žo¹¥ÝvßÖ°qI *舘H.”¥7N£*¥ÏôS·Ï«NqžåfÁ°Ë´´Í[>ãö¬'q;¨^¦NÉÎ÷¹ùʺžZ<þ5Ëæ¯ûXvÓPEÄŸˆO‡ÕÉü¦ÌÒT‰ø¹Ävåêù¤~±0r]sâ‹WD¿:Ûò¾8X‰NËÈËm|0»ë)~ H¹Ë‘>ÜiWÆ×~aÓõË/ؽÛÍ=ÁêÕpþç9ÀФ5ツJ;7RØôžÜº›£öâʹ§Ódf$·ù®üÀˆM¢• ?¯¾ù=på w8û¿¬j“ª³L­rvׇyß^`"3oM¿˜´ª…ÑûYq§´3‚tã<éÖ.¼Ü¾ôÃÂè~o;¼kîüϬÊ6ð)Y®VƳ쎑÷'„òaž ý–ò€dcióB¾yü›Þ¹¿ùM¬žÊ-Ÿë›Í·¿g2ØËÉŽäö>V=ó¤j¼¸›æ7áÞŸ-l¸/·å•˦a`ò qîyQŸ•+qã<ãÃî†øŽCÀw¶S1ŒBjäÍŒO>Ó¹ül¦ÿVwˤÅ)KÑjð¢³ug¿-—^³$dÄ.m¸w~êTX=kñ¡·R…í°‡îVæ€be*k„†zvW4”iÉ™•_}.^:nY¹‘›ÿÌïwÇråµtîX쵕ÌÒBEÔÏ©¤Þý§ùð}43æ ò‡C(äA»3ý pÆÁÒ›<¨ŠÕ˦»›”öÐỳï´A–*ì>J=²p¤séÙºÛTy/éA8`t²ÊuITe¢,œˆªge°”Ô' fS3—ëß4f…º-þÓlÅ3"iwÎf°,¨hÛŒ,ÿÜÄ? œÅ³ëyåfe÷F÷%i²£ÿÔõ׿®ü…Íïþj2p_„~6@nf¡§s™?öÄ­˜o]|‚DËÔ¹.»ûÓ|óïRšØ)øVÞ |Ó¥bêÙ`ê0vvü¹¿ AóDØ ©B¦mʃ¨v¦MV®<ïMw c¹­^s1ò<«rwï/¤h9Á”ÐPH í5iËÖ¥àÊsÁüùlïAm¿±œßö€Ó·›—ÖNɸZ}ö3†¿àößR¼óKqf˜“€#†FEÁê?»rîÉ\O_cê€zgðýå[¿ØÛA¨Û¤an.\®ý²XÊøsovvß“ònBLÀ{MèŠpö¬òk… ›ãÏÈú¥pñ\ê-QÓav&[ÙUÜö˜ì¹+R¶´ý]-°2@e®@ 䙤NVÇçßøþº›>ÆQè×óëo3x>”-GÍñÕŸ~Äaø¤¦rÛ—(àI¹8|‚›3–¡Sßmžþï$^¤ $kâôßÜwëŸÇ™;@ê39‡CHži¼õ‹’ö ÉŒöÀo,Žo…Ò"kÉ…S߃ԌÞþxõÂói°ajSQm’’Ðq8ŽXϮ̦g¶>– šÔ(`#(!PæN?ó ÿâ“¢9e—÷õîÿ¤°Kàa@L«8¦N½Y 3OþÑ™öÏnx°÷§Œ&±A,\cåÅ/3?IŒÏ+îuwükgôÝ„Ô!}–‰ß®Ÿý®SêÙú;±½I˜=ÜÂÇ5‰W &~V/CI ï¸wæø?À»vÏX‚II3¶l-ž¢ÜNénx´tÝùõ…üæ{AÕã³³G¤‘òÞ‰¯Íy©Üž=¶,SAƒ³žþ½¯N¿.šoÒöÕÖ•—Dì÷ïý”¹ñ±ˆ [9«ª´ Y©O1‚k…¼9ì¿:™>nå$ëÍlÿÓÜî?JÁtp¨ÕT4Ço~Ë2Mæ® š~ÏþOÙ›EÚÇTã«ZÆMêfóêËnïN0âqs ](~e(ÕXXwgu ª­rÏש ®Ü–”Á|Ήk§Ÿpœr»6ËK›*{ßÕœ:Õ37•wœzùëÁ[ÿ`:Yªb¨¨ìº{CR.íú`qãXíâÑâ©¡-wL¼þƒüîck½þ7²þV¦gƒ4‡úþUlo¶+TÄÀKÆSböp²|A…ÒÞžOÒÊf™¶¹íòt.®.„K Bþ¯™ÉôŽ]¿|ñÚ’ö³òMÛrd´5TÈšÛþUy÷ƒq1'›TÏ´ßþ>ñ%¸^»\Þûƒ³¤d÷žW4n^{¥õêW8ŸR;?Ä ë ¹áƒ 8Éœü¨´G†üÖêäÿÜ7Ò¥W³½×…‘,íÿ¼½ñ¡0 À,Y¦ô/?™}…¥Øó åvý¾Ÿ¤—Ië— j§ÌÍlxïÙ q6^Ó1—Ï<‘6¯&ó/&« »ÝlI(+ŠBfæÓpU¦M°û£åí „³áöÇ Â—_úr¦0%”÷UîüËÄì#, ­sÑÄ3Ñüë2 žºá#óz¾ë/–'ßlŸøFïÏç†w̼ôçÊŸVIÛ- áL­3g»å0€Û•eê1ËQ¬TÞý‰ y ¦gçb¯̽n›ÄuËvVçÇóÛͬ>òŒ<–.¯œ}R3"œ3Ò:CÇa¥`Îí2‘^#SÙÞ=Äl-¼õ z ê¶•_c÷ÈïùlRØI\+¹úcÿü÷-¥à næ*€-Œç7ßÿ•Ùù…ðâœÊ®ÂØÁ sE6'’•sAí"ÑÏF¡%p„­lÅK™¡Ì)ûÕK*nÚý×çw~ >y|àº:ó§•ô’ÖBgòW£w|ž÷틈ۼvÚÍ86ñVßyFÅm^“þ4Ð X–Oq\QK¤±[ÜÉœJké¸AwÊ`8¡\A¸=iù€1üÜgtζNþ7Ã[‘4“Ûx·W½p oÿgêdØŽ—âêx.gÆî*‰f_eá5á/&QÍ0À+ã€WYCC·|Á²Œ«¿üNv}ï '£›“'³…áleduî\n`¬qêI›;Â0hi³aUн›Îþ ¬C]Í´g~©¢šeåM·? Þ(ž—ÜÊfn°6ñŒ“íI“¶•vse€5ý,Óe=Êÿ’K­“_ƒn1~kø U f^ ê37|F®, Wüwžˆ—O³Üz>x€¨„ÇsFãRcönÚŒЛ©`™ÊžLaÔ¯_SU¹ýsjÝÀªøÚiÓqxe(î,Èå‹\ø¥ 7­®ÌD­¶›_ŸÛzÇÜ…ç¢óOÈÜZ8˘ŭ"s{ ƒG^Ëí½¾÷†ÇžI@x¯ž÷±aÉlÉíø“ 3˼³ª1ŽßèÉn¦ùu\5ãÚ„ åòí) #Ñä³V´à-Oä6þŽ×®«xÙ„g~Ù·no³>‘«ú«wÔ.îÐ àînþ¸5v«\­ÒÆ¢ÉíÉÕÆ_ò§wÄø »”4—,wÈÜën¹³qä˙繪'þ2~_#Óevª@ÅÍ”oû³˜Ùàqü‹O‰ö¸ŠZ–UðÓ+,e w?x ÿê{K…D°ÄN’¸ÔÛãÍŸ ce¾›ÝUÞ¸ÛŸ|ÅŸ}³0¼ÏÈ &¡ÏƒÅ…ã_s²½àÎ’`E¥~•;»µtó_X™ub^‡ñ 5¡µÙ~õÜ©af7ÞÍÊÛÛÓ'ÇnüØôëÿœÝp‡Zz±5ù¬‘Tª>+5b–œâ¶$ ß[Øv_vhÓåù¨h¼c’@¥~ÆÌèq½!˜’âÐí_|Íù“-+?³R~Ý.ïÊ‹IsÜœÛwO’+÷ì|(ñë³O:ù|uÜòV.“•·þ—[ *NöŽ~¯½áÁÜí_d w,R¿ðÃLyÔÌô4gßÂaa0/êacqøöÏE™A»¼ÞrþÕïQž“Þ«ÞÔÏp¿á@m«¸ƒä¶®;ðx§Þj×âæd&ï°t©vå¦"×4ÿÇïÇžxœMz ¥WuÞ]ÿåýoݯ÷MÓ³kFƒ,¤ AV°ˆ0ƒ) Ʊ ØNˆË.ã”ËI\*cBR@bc±P°,,’ FH3Òh4«Ô³õÞýºß¾ü˽7çÜ׃QMµ^¿~˹çžó-ç^–9È9%ª—$&3óa™ŸjÿF´v\':Ú벤»Ai;"ŽˆHïÕ½KÚxÌßJ…t‹cùí¿œˆÉ8L&„l0éëXPeœ³A8<é¢ çš(J9'ðWM4a†éÀc£5e.e E¸„¿ Bà'eÄè6að #Âí®œhžý¦ˆ×¢õ³ŒhîzQXa²L'øß𜓙ˆªg‰nPÎ Rƒ7ç¶×J¥ÃÞ¤ƒ£‚,å¦Ë{kT.<¦Ã¦LOçw¾/rr‘‰˜ôH"©ñ(•„6 kS’1D ñj£„áOC %Æh Q _g4±¡»"f¡œpXVjákÈq{±öâçâ¥ç ÛÂ+ø¹‘æÊq.ò„ CeŽ1ƆÃö¢6=Ê¥“›V±¤T$ÝEcˆ·ó|âA½öS/•f½åúße´Í!·FÊÂ^Çý¦tƒ‚Ô99’@B¢#JBC›Ñ’0ù'ôz ?®âgöÌ9샂ÍMàO7‚*E\©©ûó¨r.=~{Ôi¸žS»ðsƸ[4„;Á€‰*ª ÁÃÎ*|tª|8V¾¡ž+NvÄÈ‚¦ù¸~†Æ5­A:„ô]?…Mý`û=îÄÔ/†•epFi( ß`%ÄE9VǸ4:„äC~ŒŠqQÌí'œöã×!“L%‘ñ Ÿ°ZÖ]¸P}õáôÔAÖ:­¼äã©É»œá7uç~\9õÅôÔû»ÍÕ`ôFh‚æÜM ¤^sÞqs RçO³ô4Iê\× éE­uMcµMÜbT8éXwÜ­¥wD*2"“Þ_Ÿ{#³ånoè@lʲ†ÅĆGúÿÑÍ6\[0Œk£ »¸(Eˆ ?c¢Í¡ºàe¾CÉÚÉ/v® 26TÆi?ÿص€ošX”±„Ï3Û×Ú¾K©›ËÇþgT›•éaÀLÇ÷h¼Þ[9Ó©¼.Ónñ@ÜZn‰°¢¸I»¹¤vJ­?ÏIŒ¸†:L¸2©îds£^Uæ¶0'㥻•+°C¥}ÿVe÷$´È´­Vº«¹^Ž3?X(„ÆAøä›( µ¢íóJQ»./ ]à9k cRÖ媱4¸ûŽ O†k§âÊ«ª5+_EMb™;¨z5€Pé£^]oÜuËÒϾÀTÕ)Ìhžƒµ›xmâ¦FLÒ0&ÔêžãæejH§·¹»ÃÀö³¤‚vsZIfð=›Tf‹Üö/£ÈЛeO,ºrdG"ǰ5Ðó†Iª¡é$îDw#HWûMU?ïx鸳1@1so·Ì;ébwå´ëÀËËê¨JTR-‚iÍÒI{¨p«J &‘H »!ÁËXš’¥7¥üA¥U‘–1b@[’‚®‡œCbqP½ÅŸ_ˆß2f^cüZ(øcf–ÈtØýë5jÉÆë¼v1^;™t–Û«§ý¼ô€7ü€JzÌuHÒTíeøF ÞºdT‹"É;Ü-§ËðÎdJ¿»|œÒ˜Ñ˜ÇAJõH:³íWÉè½Ýv•;4••þ˜qŠ˜Ò$fP¶06KÙÊé÷ñõøñ1¤:â‡MbuP‰d¡“¤uW¹ï¯ÿr-µ¯=-]àk®"hLÇß÷º1åV_w†§KÛ£åcåcÒ êîiíø£wòC­¹—°MLW:,¬œ ¦ÅlÁŠÜ 8l²[­ s³S²8 °Ã Ši¢Å´¾ŽýjÜGb“nƒû,Œµ› ]”ð8‰!ý"íV_{¢=û½âÔ-õÙ§âÆ%ø£ÐŒFÇTdJ÷?CWÎÔÎ?îÿ’)ìn_xÜuT¼vL8P«ÈáP?¼p¸tëŸ4çOG‹Ï«¨*Ü \}Q°ˆ$=L[ß®ö™^šÑ¡¾‚–‡%mH¦bÁ&]×}퀀Iúà£àYÊ$Á—(® ·ð  ‹ÜH³õW¿ªªç¢µWá½Ü+ Ç3QM«.ãÐ+šå2Õ5Q“yƒÙmïj®]Lj穪êh¾TºM|YØ#Š{5óâúŠÑ=¯¸K5»KÏ0Q‘&î8/ßäO½ÙÍQ–¡€™JRÀ'(ê"MqHÛõ²Ù Šõ+Ê ûw ŸÖ¤ hòtùGŸ ÿYu—!-N~oyÏ;+ç×_ƒÏ”KìâN 7r(æ4Ï”¶ßÞZ{µ½| Â<@ Å}ææýñ7óâö•§Ó÷Æõµ¨r’Ó:äâwïÈl»ñ2à1écdŒ´Euõ’~÷ ×$]†½ ai¸ýà‘¿°Y’¤ºZ;ù·½Ë_c°Ø>gÄ;M»óÏÐöU=C"–JËÌ›EPL¢;I§Îsû©Ì'µL­C#QYÔ40šØA†‘ÿºuì¥'n “ÈÉïRQ‹Æ=Ý]K¢šÌoÙiâøÔ ,ÿ·P¿°[~Î$!çyØËSðê%DÑ+@ÜÚ.€6²üFûŠZ„~Ú_>ùt÷êóž× k/ÆÍ9/»%lVãÖUæd±¡–To…Ó¤°ýcÄ´¢Ö帳n˜?0ó^77ºúÊWz•œ MÊSŒû*îÊâ Ú/œwseä‚ÉÛºmÒÛ¸–ÜÕš{ÎpÃN~”¹> KÈúk_ã¾›™~g0q$J@ËY_áÓØàY\i² |E!ÇÎt®þtËþ{.=ýÙÞÆ @ X£Ìl!¢a€H3*T! < ¤…7Csµáæ§e~WØXŒk‰ªar¸‹_ÍÃRô›7v¯¹ÙaPN~wkí*wÒ~:nœ5ºãÆ©ÌuV´ª¹Á¶ÁßkrûŒØ‚L”ÀâB"Ì øƒ6Loò‚¦5ŲÕãÛ=÷ÆB’l ÿŽY³Ô-2™aPŒœ:R¶VOaѧ÷‘¤c)$2ÌÑÆ1IÄ@4ª:#—™$‰àeÒñ’„ûÐÅ< ;%ƒ|ÔZ*ŒßX[>²ÓOykÏ€Øã©­J±$¬»AV' Ým'+Fn8ú)à÷ãAÇifµ(ç¸)Ø6•9À)t.ì];Þ¹ú‰V¨ô¨Sâþˆ— ëWÝ`"‰síµ³*i@ø·ýImáõNå43=ØžÙU:ø‰öÜSíËÂGCñ(è?ðM àœó&òê n\üމŽꀃs8K’Îw‡ÜÒ©ñ›{kªS5À_I ?5ýÖ`ׯ€ÈIcTW™„É6ÙM[! rÎ|Æ|µrºqñŸ¨›ŠâŽÌ z¦¹~öѤ³0…­Â*£Sc„Íe€îòè–•Ùç;5~×CsÏü]= –€ i™*ݽaãä’Nb–©|´q]jäט“ËïzGcuV'‘››$QÄÏÍ ‰â(-Ðr< CÆØh°vPýÏ+$˜ÒÊAÍ"Ý<÷„ W„/k¯=f@Ò$5èPòØþÀÝPÖn©£FGAÐ*l«X÷üz}ö›º}ÖIxÆl7 e±ô°H¸¶Y G‘¦ÄK¢.÷sny‡Èäx0 !`¥­°qÞ¨Nº@hÖH"  ?JBp—ˆ¼…9@k.òà¡›­ïS颌VW¾÷ɤrü•‚y)¡ÙáC°vgøh°ýmЙfŽ  ‘ŠÙiƒˆÁðR ‡¾þÌË\`Û“ßßxí“wýNjzïÚ…cQuCr?ܘm]ù =Õ¼ªu(ƒAéŠâéß3•—I¹ºvîëQõ4 <6/VÍ¢@äàh€T2@Ñ:àhœòÁ½ï¯]9dÆZëWqÔª›½%Pqk™ÁÍYªaá%å`âÖüÑ_kV›ÁÐâxÄóÑ+….,B‰ðh‹kØ–8„öÈü·ß­ª'¨ÜÒá¨WwJ[Š3ïÊŽX?õ-]9YŸ;¦â˜¹#Ay[¯z.½÷Týl¸~ ô3I8º$…?ЪmªR\zxÔ b;ïFtÅÑt1È0 ¢ÑóJ‡¼âööʉ¤9«UKƒµ¡h›˜”1Tjš.ÞøéÜ¡÷Äjxç$`wá‹bf-º'ñÂw?œ’о1ÍLÞòÛA63û£?ï­½¢š—¸ì•¶Ý^[x5nÍSoä ,’ñ" )ˆ“à¼I0ôxÊò— ¢„â”Ã3I¾¤O…8ÛD¢v5ɤÊ7Eå¤s‘â4Í€h5¿RÍÈ¡Ñ_ú+wûm!T8Gݦ¬UZܘ5A´@V²õ³Oø{’ÔèÒ‹¤}²vâs:\d4Á‰¼~HyJE<}PЮ +8aÃâ§v*fP¡xÃ.îÏýãm1€øq.Eñ@B’"<ËÕñÑ=j‘ß% Â-ñô´7ñöÂÁ&ÊB%Ä.†Oäý­F òˆ)‡¨0Ô½:ø÷•ç¾Í?cº—¨ª{‚ÎDɉÚ'‘$0Hqæ:•—twQÇu Õf‡Ì8üÂ+c™ È:šâèÕxt‚gÖÁ®áz1N&¢Î‚3$’.SšþHpäÃõ6˜ÜÍ8£…¢¤8ÒÅ츂/äØxz#ˆbcé…¹§þ¸»~Šâ)±YÂmµã#ˆXɤ¶}:i_ÒÝ9­c½˜h€,1½xT")7@¡Õ BJ?ÍCú3@Àõ’[œ»˜*Œ·—ÎqêS0÷6έ‹`7| Øývgh'´A¨±Ó6H?ü jš!ÒÆXÐXWÚ´IåâÕü-ݹ‚³kž% Ê íìÕezú/lÎK×õÚ`€G+gª§þNµ.™pÄë *ñp ‹Lrη8rˆ1×¹3¬/˜Î<Çã9F¼ažß“DÇgº.;õ¸yE÷é<@ìHÌ<вœÝù€?zczë­q,QX«B1-Ø@b`96N=²~â ºWsŠ{@t·½%lUZ ¯–vÝÖ/7æ^©A`Gã'¹à[>¥:K ^pæKk Ï];“´]Œ"û‡&œû°2¼¼¯Ó¨šÖå”SzÉ»cû}ýæ‡ÔÆ)<÷BM Æíe!8uƒ*áà§`o2nq⶯¬ñ\2ª­ùra-I„ ž\ùំóÏÃûò»~E涸5÷£Ïú™!è0‘®×˜ýgPöÝÚeà9ñÊËIcÖ´N Ú"Pгyˆ’)ص•ìˆ-•°`"?ónÕZfQ­]]fÁö‰›˜ëÚs ÖD£ü¶s~ «Aä’yåÔøÛÄàíÞðA@Jlº] ˆ‘$ÊÅ£DÙ.£½i¼ÞZ¾Àý±Nu•“¸rúaÕ]öðôP\¿ªêgq”Êʇyz[iæ—kKê6OŸàkqJÙ“[½/¸xœLL€ŸûGƨŠ|é꫸¢¢ehˆ '_ Ñ(ÜG²<·»pã§Mn?ÔºÌãŒNBé']xIB]¤ˆvÅ—¬9w*•ö^ÿÁŸêN…Êe®êUÜܘp‡*îѤ h F2à#™Ì>^Ø2?ª]4 |T) ¤lQB¢(Pü`ÐzÄv1Ž}œD!ÀZHðP, ޳ÙZÐa«–¹ôô»RÓïrJ[¡ B<Ù ›Âˆ”»ú“/‡ /ô‚g"H,Iª|83qkmé4wEqdzõìŽWŒZ«ÒMEíy¶@žqgJi#o¹ùƒË?ù/Ø3®Q;ß6}zÂóYtú¸ú‚Øòp²yuÁJ¦ëçºT¤†ƒÉ;:$Yù‰dð”ÈnÑö"Eýá­÷}¡K{ô€¯ešÍ=ù¹Ö«ò䥗»apò-ÔÍ5:uYžª_ü®®7½uPËœÌO‡•3x* à—ÚGÝAòN)Y¸üÓ¨r’ÀX3iïO+*ú£ÕÄ if‡°–¡'ðÆrJJÜ8œA;DEá@Ry¼´ƒ›ƒïԮ›½âÞÁ7}Fn»?)êj“È ÓÛ¸\=÷XãÌã£ûîï®-´7®ÅqÄ ÛÆïþÄÆ+7Ï}}“W²hXàx>À…0aaæIgµ»~6é,Rœ³aq0´™O\†1c(µÚÎÕf®ñµ(YûÃYi_/ÃKwˆÙu7‚âT§±¦“ž7”D©í¿6òÖÿ´›NKGå3?*Mî[>õØêË_*Œª]~Ê›ùãÞÈa&y{ö©nfÇoíà™ªçy8"ª_åÁ^­2ÓáýQŒ±w-úòÀNg,>S{‡ÄÞÁ8©•rv ðÿ \b—iψûo±:Û+ÆÕ²šë³é‰Û¸(JÆo*~0¤×zñ©¿0ñ Š—nÏ¿&Áôê*;3"vG!IjW’æëª¤r[ïi.7ªNQI‘ÒqHhÿ|ØT¡øé'Çeö’ ˆ0ã8¢4²ò¾x´4gOûÇ??NG b›&uð­Wœ¸¹ÙEafìÎÿØ%a~Æ%¯?òñhí'Èøhº%qÒx;Hä+“¨Îœ,s|7Ac$à^¹ëf&;ë¯ÎK/ 8Éd†Úâ`NÆÏ´+—T¯pýøûñxÙ2°@¯Y±£ Ö×hgúñ÷_Ùo_cÏ)ììøBxYHoØmÆ JDiäö?Ê£U\ùïYo}ãÂ?¨¨ ºxjtÇͽFµ¶:ßëvdnª†$­hãjÒ^A Aèzxä‚Í„\¤ì‘“äîäzÁêgLë¦^FEŠã8Û¼vBÐW¤ý.±}ÁnoËŸ¢æÃ±!”p!¢v ˆx`ïƒ&µwýõg¦îþý¡½»Në!Õ¬¹ÿÏâhõ•'þs²|Œ~Ö¼ÒnYÜë•÷w6.C¢¢µ7TkIÇhßè[Ÿ‰ÂÒÿ{gî)!3Ú\Ã6à럺‚g´Âô‹šë·,ì5ÃñA& @Gÿà9µ0…<ÍaßðîÛ­\½ÜîV‘JЄú@ Ù™÷„¤\}þ¯œý¹‰C^vxéä#$é¥G÷ׯüì0Ž^…ƒ#îâ–9òð¡­¹—¹j&ºìx /O‘ˆTŸû|íôÃÜ)>dX!•SóqwÕñ€—{õ˸Yd…ðî‡fèhŒÜÆp¥’û/¶aµ ÛÂD$iËnrtúÆæêZ£vÏ'ð‡§XÑßùÞ©û>KÛäÜÚ¨̨Aœ‡«`ýPfL¼c`æéÁí2¬¯œëÔ7@¿©ÊêÕ|&»õVòPnæPw­²øýÏÄk§©êù¥ÃN~oiË=áÆÙµ7þ¯ŽÛÚv0ò&¶èBíý‡É¼p‡£Îe•t±qmEá“þå*\,žDÐþtÍ.ž#ß¡‘‡_R „K?ã2¿MÊ\gî¥õ×u}?7zƒHf'Ž*§+©%~ h'Çâ:Yé‡ë/ h%Øy¯ 7¢…©LØY zR%8U0I¬¢:Ä Îôê—t¸†nË(,o¼HçoJ¿w–¡¹tUÔÓ mú k[Ó Ü[nýÛ&íÃWÂê˜+Ý‚2¾7p€”öåPd¤Š=GÂCÿb'‰ãG¢š‹Vgqxã;ŸÌŽÍîi®Ÿ5I«³pD3|Ÿ;t#w ÆÞc¡"ãæ¶‚RKåÇAYU®þÄÄ ‚®?KÁë ¤UF(-l¥c±lÞ6ÂýPØéý‰¾'Ø›÷3€ÒðZ€„j‰bC\š»Á»áÁâ­±7Åìá¯dPž~Òm·Cø¸úË_kžýšî­‹ì¶üÖ»]'3ÿâçÌxÒk訕:ê©Våœã¤ ‘+eÆIƽ¸žÆÿhUu–‰5Å?Or_äô¢AÂôOPì%¥>†n2l à¦}‹²‹ÇÓ;°Ógwl×{îåÄùI¼?i”ö9¶ÕÆ+ÿÐ8ó­îò³Œ9°0Lö¯OhpR¢$r»Fö=Ðríµ¯ U^Ù/ìj×®%Ýexð'˜?©zWTgÁ^ƒ´ÏÆÎµ(¹°uú8À´÷h,ØhûK°³f?²¤Æ(…“a©mŃŸÌí{@áØ&TQ— ¼Få…/·^ì-$qÃM ‚ê‹“ØšÚKåÊTZj¸µr9He«g¿ž´®É`v37|¸µrJG+(õ½2óÇ „¨5«ãuëLûBǪ«lA¹g{ŸÍJ:ÌñõÔ÷_‹ÏÚ{b¸\ây%üç–Œ»}쮿v'vkÝƒîø­µÅù¯ß«{«ÜÉû…QØKÓcÇÞ¬ÔºzÊÏ•»Ë+'ÿ$· k ¤›MÝuj€ç&¬èhC딇 S7 ^Àë_äÝ$'ƒw`¸ŒÃV$Ẋëýy#ÅáÆõm²<`¿€¢ÂÞCÚ<¨Ã⃢’‘?<ð¦Ï8£{ˆGðŽ¥rI·Y=÷Ãæ±O)•x{S“wµ»¤tËG3£¶^»ôØ¿«‰éèh 7­3wÓÁÀQèGà; ÿTeú„e6§ }™lSj›˜âÕ:F…°ÀMf³%oÇD´ïzlÉõ•6ŽIJqœ‡mÊÓ2½Ë¼yàÈ¿3¥ÉÐè°;ÿÄ×6^øK¦Œ(L¿ó + ¯Ó7•fnjÌ.WOüïÎŇI¼9%x~Ž ”‰ã ÁpH¥•ŠÚ=cL~^} Ñ¿™`IÊ>V¶¡ ›8iUÞ¦€°$Üg=›l{ÛÓl®Ž è¡D„$ÌUîøä»RÂ]yö¤¨ªÏ>¡ÂÅÜÎð±{¼òÄèž=½Z}aiþ©?$׸ªCS‚êé)žÊwWÎB:½Ô0^¥x‰@J~.æûÚžþÂÛ²°÷ðH_!E6} ÝÄ(J7eŠ7j]Ùæõ±¾À¶m¯ÏGDÑûWåÿÙ^½¸jõÕ¯w+§)Ëfw½ß6zðÎÎìËÒɪTyåÕ¯v.>bZ³(Æð³›ØnÂõ°1ŸØÑkW‰½¥…gõŒ¾®'Ù/â!~;^‹·˜ØSˆéï“}|]%Yj®ï×f?oª;Ôàdfhqÿƒc·ôg_þÃÞµÿ‡ ðhŒ:b'-Neö¼ƒ‚\ D“ÝGT_]?þ¹îµ§‰üüd¯¾º$6½ÿåÛÒxœ%š e×YßÏz÷ûö~½¯Ó===‹fF³HšÑjI¶$Û’¼CÅ¡!©¤0ªTˆ¡€`Š‚ª”‰1‹#B‘2L0`Ƕ"¼-#F£;tOOïËÛï~Ï9ùÎ-5R÷}ïžåûþßïÿc”OSŽ?l×Ú–Õºö½Îâ˵?îŒîÜ|Y›¥"Yá–ë ")3Ñ0Œj%RÑB}¦µy Æí:6Êå‰Ó;‹¯ùþ ÅÂ$\ºënqĨÍlßY,ïÿœ3ódš¶}×èÞy˪ÌÅÄå#$G&BH ÅT3I‘I$‰ÊB çÒ°•"T &!-„rL}‚ÌÖÆ%%z¥ý¿Ržÿ8ürã­ÿ®¢U%RD}d”­áC”ZéÎM*ºIó]¬Âl…¸Ä+ªFÔb–'Ó7ðÀÎê•Ù'~i÷Ú«»7¿à×”˜NÁq ŒYÍÖîø~-”nóÚ¼â@ûοX¥bžúœ¤Da3 ú‰)aB°„I¦„•B$„ØžÃð[”Ç_qWμ²ùöKÕS_‰;Û‹dóU­QîP?û„bFw}Q† 7d÷ME¶íý(Ë¢Ý[°ZNeL%›ì‘áÇqÄœa‚`v9¼¹0¼?ܾ–uVÃŽ±I뇩7‘µ6òÖ¢W›æ†všþ䣵/FBÊI&‰L`‚3”å±aSÕV*"¶ $"0Á4qJ¦ê¢píÚòk_á#?)ãe eMÄL)•R°UÌy”ŽFë—H´˜w®r§„¬ªYZ6ÎL̳nÔ¸l¾CQ&VÄüD¹e\äæ.efl›Ü‘f9† ÏJ[kqoÃp˘¹vy²¹~}úÉÏ㸀Ïbi `÷Æu*b™6ÛëD†›7þ9Ú¾Hu$QÄ{`Nd(‹v`5Pc‚•ä¹B2b85 GYC­Ã÷»vaûõßXäLå¢ ÚɸCÌŠÈwg¥Q³G8~yýÌÙ–yÓ°l¬,Í!|¹„\tˆ;É·»uÍ)MæQèצ;Û7¸]­Œïî, L¬¡Å…RÇGIâûæÊ…nŸÿ+×rJÅ+çþå=Œ ¬¹Yš’Ø8øQ³2»zþD‰r}’£Fõ¤0†ü¡9Xm%¢‰ÇM=¾uõ•Î{/‘¬íëX4{;—•ˆA(¤¤”âœ4n»Õ‰¸qÕ‘é®ÀÆÀf¥IÀ¼º"X„MÇv¤5À0i­^†‰;õýyÒN»«°òY”šþ(>2ËCÇ?‡Ý爦¯ØKßÿóÝ÷¿Y; âu–‘€;ÓyØ1 &“F’g–Q„M1J þìSa{±»ô/¶_/Œí6V©á3«®ø`%c÷?ïùnêd­+o†«—²ÎbŸu8÷¨7V<ôiT˜V)²a ÚRñA®ÂõÔžÄæ°S?ž6®ŠxE¡Db›—öÔ6Ïb*™íçi² uC©„BÂJa¢CŽˆ3œ¦–03·a;¢`M$ó¡PGc(®”ð¤°'Xå(R4o߀̫͜޸ýdamÏàu‚yÅ‘)FsaÛí›W¿[›8¬¾Õ¼õ ä~gêñn;äö¸[›1JCFƒÀ¢(aþá%îe»°ö³:ÝÛ¸-£6IÁ9H;ü(²"ë:«Œ¡¦c£Àü©LP+!°Ò`eäࣤӃÊn©´WAX l({tæñÿºµ|£·rN¤m«8!‰Q_x*Ízi&Ê{NY~ ÖG¤&3‘J¢Û¯ü!@ £ª»òzmþC#G>µrñL–‹Ä¬!…P©`š|4…˜¦;’Ë8Ï&©ã€GÔ. í]HR¤ƒMRæaÃsÝ Gl[µysð+Ïq‚#Vu¶›B]B™@6ÐWRÈq&³Ôà®A‚ídõ¿á^Á©Ôg 7vL»F,DÍŒYP÷ý…—;²x÷Üßl½õ8ÛÂ*‚˜ét—jA'Z Ä†(!÷„¥‡'€#$('y#ý¨l%bÌ”H•Q.×÷n_ûaи>tð“åýÏ Ê>¨ ŒÙÀ\*îb"ýz’(ü18 ð›’Pg šßAòÉ»o½~ð±ÒøHÖ ue¦'Þk¯1gJjÔOk8oŸWÁ-•6tt<¦5œ»Z6•€Gð1˜†‚7À®ÀœQ#ÏÚðsØ÷Úà¾öÖ’"fqò!oèäöË"Ý®Î=–„[Í[¯yñKÍVÔ cg|ÁdÁú¿bY%™ ³<ûã ,”¦ÍšÜ$乄ˆB{qØM¦Wƒp@ˆçQ¢( ÚË–UÍ$…­Ö¬€E„¢6 ¤WW£‰S˜¦f!‰6³pò d“©W‰ g, v•lмmº%€Šêè± ›dÈ5OðÂHgù5^7IŠÒž@.ñ÷²ÂPÜ[5½îb!I¶ÖºófžŠÊÜ'Æžú÷±Êâš ÀOhѳÕà‚E©„?ál·{ã;¿]_ø°aB}ðj÷As¨DÄÍÚÐþíÛ?@P°4ÌÁÊrÀw$ CFHýæ^–I[‰Ô©§oPêXÞdaꃅ٧ÜJmùõ¯vÿAå­Ä®YÛ…-ëæu7®ÃÏeW„ë‡Ê=e0´è£2ëï Â)Ëà1! %˜]äJ dënÖXâÞœLcb 8øsO9£w_ù"I;"ÚTØ…%là–Ì”GÙ æeö ³*y¸ Ùà*ûÛʘŸç "5oüT´u%›L6 M¯ž$³«¹”Ì©™Å™¨Ý`†Y(—Âæ`i³~Ø}°0ýǙ֢7¬ 2¨8BÂê xëÎåøBqä [ª­žûšíV _žt1˜){Èͨ.p»HF WiGaFk8ƒ´ÊȾNgƒ[UH!àA°`2릟&‘_?âk77ód'ïÜ š©2]<¸G‘[š¤Ü £ ˉ]¿ÏôjIóNuâÐÀÜS팑ÒÔ~à¡Û?üƒîêÛµÉ[Ý&+ŽG«gp¼ Ǽ1eÓÞ&ýȆ Óõ«`%º½Ý»&³°ÞNVœ:îŒ> Ø”@õææÕ¡?m¸$ﶠѢ™BÀI!ö)O”Ö¢Í ßŽEm®]ø†Y6œÁîÎ:¤!õf ÔêÊGËþÞÏzû>¡²•õW[ËDÆ ²ViÏB¬Ša•»;׌òQHç´ ~ÍÔ8G gôU1ìEÊö‰]ë6î2«ùùò–¾ÿÕ`é-{ôCª·–…Û¼x¨rúwSs”ËÝäÖ_‡w¾‹ó]0Ræ †?ƒ8˜•¬âþLlwÅp¿6ÙÛ¾·–¤µTXãâDqöɨÄíUÒ¸”hH`‰Q <¢À¢R D¥_èæö<òóï}÷KVeÌ©ÌÄívul¿r‹ûžF6‘YFZy뛥ú‚‘´ÖÎÿïîÆ{´8åìýÈžg~‚GÈŽÖ¬áçHÄ­ëå=|ô7v[àmrµ¶Îþ® n«¼ AšÕ!¤ CŽ åÊiÎà nB˜c(H*y³õ“Ÿóª·¾õ²½†WQ€³]™4ÝòTiò¡ÆúÕßÙ¾™…P6Êû>%ŠG2Qpk|î¾ÕËïJ(ÁƒµÆõ—{»·œÊ^âŒÂ§d¼‰aʺ˜ƒ VB$R£JN­ª7ö 3qÜßsкcÕL²æn§»X˜˜3Šõ<ˆ(·C BVí4Üé¬ÚÕ#öô3öÔÓvyÌDÑ•¿ý9oh¡<¾ÐY~'޹Āƒ°ìîÜ0¬šYšèíÞ–°5Š0ÅQÖ²,;MÓñS¿²9àÜÎå?÷=æL>Ú¸þ#Pn’·zÛ#óÏvZ͸»^,Áöµv×¹Sà8Hºwd®’86¼!«º¯zàÅÒ“P±Œ ‹©©s4Ï"`kॠ²VÃ?ä¸Å^û.âõ‰ü^L¹ùîÔ±]ÿöï,<û…°y³½öVoý /Óq:+o2lyõ½agEÄ@‰Žf„›…¸y ²atáùVZž9®ü(Ü8‹ì2@€Ì#“ƒ;Ü- IÂðÒ©íÇ…éîö5$¶@U®,wÒ®O;hu¯8~Ð+¸(Ó¨“ê¶¡6(\[ ¤LÝuÔ%ÓÙ§T[‰W:èî@Iu§‹6n@Áʃe«2nU¦‰é;…âÎõo¥›7§>Ój,öš+` ‰ež‚íÕð/R@(—ÚãP\È7H& 5ÌÒLÐ…´r¸?E c@DÉÖƒ< G~æÛiÜÉò 4ópaôe¨Os5¹ÌdÞô_@ZVeF­½†qWf‘é %qHÝñ=üõ¯ü¾az(mªŒÂUydléì×’ÍÕ¡}½Þ˜/¨j2îæñ.%&™îA¡\»ÃSÈL£cüD ®‚6å­ŒyƒÞØÉ4eFi?u¢8º/Ù^jÝz[Bew=³8WžÜË¸ä¦ U·ö¢234Ƀêö›Šñ>×A…°Ÿ€_dñ$ é Gî®-îyøß­]þ¶ÊZ2é@5Ì£†éU“`#O{ Ü. ‘Rˆy ‹˜?Uà«aA}0cðƒU'Œs2¾ðh§ÝÞ^ºòÈÇõíoþçÆÚ; KneÆ9f qG†ÁŽÃíæâ{¹Då©Ä+iT#R“0Œ•ë°W™d}¬–÷Z½P‘…&:f>xÊ`EIoÉ;‚íJwå2åŽLw€–aÝ€ „fÞ  «´’†? ß"€W•îgãéž¡‚¿‰Wݶ1ìn‡[û!,ó p=>úéÎâ7Ãµ× …šÈ3êe¤èO=–‹„âT&­¤Û®M?5~â10b)ø7)Á€)I$PÖ`“„˜ÀTói–˜„XþðužFÚiöAYÄ&$ä¦U\ÄiBÛ_<®Vo¨©Î@7íå‰ÍͪLz2ïmÙ…zõ¢0`mpñh¬G÷C…ÚY<­Ÿ…÷ƒ)bdÈô†WFïooßF¦e¬~iÏÏX¥JalĨ𤧸~5U} åöBX|Ž2ÕœÛu žGi‡¨”6?@¨ÿ¨aY°_i Bû††ž°ºïÙoxj”6¥2Œ?ïjžçŽáÔ¸ÐðR¯aš°hååñùÆÊÕ¨¹jºU¥e07ü»2Î ì»e»»»w‡?·{í}§>›qÛ:]¿ß²Lí•8,á0®le¢#_šð¥05f À`ûn Ä\'8,)Öœ#Gé6"–ÈS˜˜ ÖÃÖRd„ g8Ä*MfÁjÖÛƒo—fk{]_<ÃuK­Ò»õm+7¬×ËÊw‡ØsüÅ[¯ý‘L›~m"î6²Î–mÚ±ÈíúÞhíšâŽ5|òçÍê}Çëw†Iß2! ¡C ᜈХA»8 äw–`=)c®[¥Ú-B"I4˜ôº$tBÁ7rŸ{£@Â{åñ#$mv–ßÎ’Ž]3k:¡£ŸŒwîV<ÙݼÕZ×2f¼ÓéroÖJÄgB@ÖÃZ1ÆÌ$¥TNa8‰š•É£ÇvkswìÄsÚŠ}K)ÑwÄP¹RÈ\ˆk\9ëªÁà¸U·ü=Qç.B° ¦>È;†ê‰æam¢"=£dUšC'™_i¯¾™l_v,?iÝ–`ä5KsCظÜâØæ¨ÛÎZwüBŰ­åóHˆþ&Â2è̇dnÝ.M„­mê uQÜ¥­L7ì{Îð+ŠC F”Ú›—/F»;Åñ…âÔÔ§Ò}*ÏYÞ•yrŸå,j*)¨U¯ìûÉîîmÑ[Ì»×1±æ_ì-~3Žv½òLeÈ€:’µoéÆ9»xWª€€Â[ƒY¦• *££”Æw e Xtîa¢¶^È2Ó±kS’yiØ›š<*§\ú—oÄEf£2yèã¿èƒP‚Y¼qéR°rÇ«ŽÖö–ý³0£|\Qß>Ü]úg¯R-A˜e%4k{?ö§]eÃeó†ç×;[‹í+_ÒbE ž³8–´—u^÷¸tÎêîœîÙ_·îµ@0èáAÙ¥1,Âp÷¦üoœi#²ÅiÂm >™E‰iºæÀ>ÎkÕñG*ó§îÞzÓ© WÆ‘êe°Æ2Y¾Õ¾~Nħ>5tàQÃ1yù8ñö–ö>ß8÷eѽèjØdÎpÖ … Ÿùëµ®[¯xIÖ»ö·ëÿ:o‚PÜßk¯¤áѦsÂàÊò¸ßïb„º=Å,™ Ž-P/˜šW/ÖZ¿…ˆwÿ§þh;)l\úí¼m¾%RŠ5á"¥ñÿ¦g¥}¤µJmbýÆ™‘~ Qsí­r­2H4q]whJ6÷ÐÚ£¬0—­½¬‚Knezúñ_n´{;×¾ ‹8ÿ‰ÿ™ø<\iõÎÿa¾þ:NÛi¼’$)ã~žt´â‚;ƒ`À÷ºuº^´<"gÊ …J4A‚4e‚ñÂÔ©Ÿ[i´íÚ¼ºsák· i?a™E­4ÍyaÖ=9pä£;—l^ʃæüÓÿ±8}¬µ“´WÞ/OLûc•Œf ¤ÎÈGŠ~ÆŸxtëGÿê#ФQÄ=†e3kݾÿ3röë_ÈvÞÆñ2ØBLðOB3ƒ¶¦ýaƒå§úhXèV3 È(Q:#·@^ˆh!¥Gh¸@*2í`n±ú!^]èÞø>ŽV)N°6È÷ê¡nò,ƒŸ«Î>tùå—P:…¡½neù¦7öx„ÊŒ+H&0ð‘íO}BÃÃ?¼ýö—{°ÂÔ®üÙÝÕ÷íR)Ù¹<8÷øÚ…ÿƒD[%+"õAÈD·R £v ò«ãœÂع;ÂŽš×L«R™{¶°ïÙÖúû¶‘&Œ×õÍËß3Ž€|áh…DËœ›)¯æ¸ ŽŒ¦› åýž’ô^ÏÖNukÔ¤Fu`âÉÆöõ\©Áû>18ûa 6¨Oê·n\ªŒ"Î<bÕH¾¥â-HÊÂøÝö–-0é—Ì(@éaœ)â§çÔZ{ï¥ÁZ *t³ÝØ‘ƒ Ú;qã¤%sêºá8wݱC~©ÞX»S;üÓP07^û"MÖ |ROqϳT¦­Å諒 D9³Šy \¯„õÁGî–&›»;õ}/¸c÷ÇY4¶ÿCQs·<:"õù‰¼ò—ízˆ²ì`õ»X´ òÁ8ÜUù®0° ‰6MÃrÇ÷?±»q³»úUa4ƒ ΡT"FÌ* `ÀGhœ£³ ”U·¤M£4cú¥ÞÝ× ‰ »Kã§¼ácQ{©q÷j”*³O”ÆÝy÷ïÇæ>yãÕ߯²Í ±RiöƒG>V˜Ú„Û]ÛrŠuî"l£°Ù]?ÿŠ;vå¸PgðhÒ<—´.Cyõ+Ãî†-›¼ÆK'¸?Aòͬ}ÞÀy/ز- t« U)Íï©r}.\Jãà4Ì4KS$õqq‡lÛ Û‹B€€Z jâJc¶éú•^sË8P?ü¹w^û“}OüZÜ8ÛXúQÔ\¯Í={à…/,Ý~§8²Ÿ*–¶Ú…¡š´PÜ ’ÎFóö9·T¡Ö hÑAˆd[2ês|¬©ƒ9{ÿ¼5ù\†kgÿu.BDÁ r”Dq–¤ ºG¦€}°G† Ö‡X#Åá£"nôv®z®¶–t „ˆ!Kà_ Àu©4b2€ ê%Ý5Ó2A8lÕàaÓ›X¾öriþÑCýë—.r£àÕÇy‘\ýΟV†g©È7o½jU€zwV x`õ4Ý`¦ Y-N?+Kê>âY"zXöÀd1,8a)b¸Œ ¸ í]ô™I’%Å™MèKKïüE²{&^ú> )gú@Û4K ±(ÜEúšHVÞoÎX [°þHŸ`$9²üÁ”W93·WÏÆï9ö)bE½–”á¾Ó½ñÒo«—µ=”¹UÚϬÑü J° dzmX¥é,ZCyÏ2½4 ʽZ= ‚4ЍVNÅ SQOG$1|J«¨î„5 bÚµcIûfÞ» žê“BØQ |oz£`çò`Ó2ˆ>@ 8#ŽC• +ågyF¬ª]˜?›Ë¨©³~Y \™ù ðk³Ï}¶ÂÑ?ÿ·gQÖ,–ëÔ¨@òB}×U(ú7ÅýOÿÆõ7¾’¶®À« åI·<º¾ø&˜t•'V–E wÃÂŽ§#€gôI¸)â<5*Õ÷ÿxgãBÜiæ«OkŠ ¦_îµ–âö²Þ°:÷EŒ¾ã®Œ¹?pè u½ïc¿´¾tõÝËß[»ðÞÀìØÃÿŠWgï¾ñõöµï dcïáÓ̪Jdc«nûuœ5‚ÝEÿ‘ÿ»÷þñWQ¶i€º!ÖëÜ u=/Ë€ºŒçaà”Ä"íµÄúÊ—9`*hRÁ{2êíP}SfÝ2mŽâBXðtq÷NÒÛb¦ %Ävj{ÀÑlÝzƒ¢XŸ¡!×)MÖf?ÐË­Â ™K—ºwþßep·ÛX6ʳ•¹§¡ât–ߌ¶Î{¾Ë¬1I|ìL¹¡p)·Á“Í}øoþà÷A ·³yÜ+02-weº/šcgý³ `o]Ü(ЋØ3Œ½Âô'ÌÁ…4ÞUI3Ý>+:K”ZqÈ\™·Öý±ÃíV‡»•ùûy÷•/ëSWØ^‚'s½éÓõ“?¹uå|¸t&ØxÓò¼éc?¶tá-ØtwxFI`òUÇpíúÁÜ[ÃûÈç/|í³í•KÍ?ó[‹oÿMº{RŽSÉ @î(}{ ÐßµˆN˜ªTöÏ~$DÀú@#‘êIåzáë-@^“ä+—v/þ±Ú°ƒ†?e÷ œ¶VÏš– Û‘¥1’©Hw‘×J_3@9³¨W’Ê$§”¥­\&^ýÆ~ž†÷À§BÑ6hzG!Y´í•Š7dÚ…Øûdg{1iÞ6‡µšœž¿uûÔvÐ%Μ‚_€âØ ºiªo.1Ø9Ê3ˆ{™£þ‘ˆ‰QºÏžþpJ-3ÞîÞþ¦k+pU {#_™yàÍo|Þñ«~e,ìmƒ«Y“ê#’äð•VðïÛ³ 5ôY2b則!¶Ýb}ãú?©¼Í¹Õ÷‹óG§ÝÍ«"nk—®Ûž—¡r&VŸ[IeYB©a™eÊ”iá°×ˆÂbëž”N*ËÓ<ûéÓ=g†×§koÈt>¦@f±ã [›QóºW›œðꙿ—m@-à Ÿ™¶5ÊPÌIÒT÷êu~ÐTÃh¯Ž“ÄtÛ«ç·ǧ×ïžãöè»rª;š~u÷@{FØÍ˜1R©O½Ì84x h8àœÈ€èp'J?õÏõ¹ÕƒÔ[ ûè °vi.ißy¯ˆCµÎËþ 7xo}^©Ë$Ñ ©\ÿÖmš~éá¹ÈuËQåàæÀkÓºþ`¶˜]£A¬h¯I)/÷OØq9,°íU‚Î6¬žqË«–gwÖ–•~Ó3P¯±+Ÿä¦ßZч|ú¤C_Ùì÷Uîy[tï¡Ð™ã0Ö~±”& F,]º¥nËèƒF¢/ß{§×JŸsjO©ÔÄíQõ= ÏB¯Ì"Їp–¶)b‘jÜà½Î`Lš$¶Wâ–›$aƒ?2à—æ¥É¢LB­é˜õ¯zä°| ÈM°j=‚)÷“¾ßqíψPÛôªq°­òŒ> ¾îD¡LÊÈ0]¡°Èzð%ºžhKm亞êo6L_·_âk—š@ÕÃ|È®eZ}-×·O‰>ó|è±ç/¾{&Ž#=‚¢^Æ©'¬KQv1jÀ>1ÃÍ“<ªØo‰è6+c¼ï´=¾Wè~êß Ø`:³\€XÝØO»:¢ô}ËkêJ(Ž´ß [£û—Jw1ÈEœÁÊì3ví8„ŸÐg¸=Ã0D* $zã‡Æf»íN¯Û‚‡•¾q+Ajˆ‚ *¦ÓÏ¥%ØÀ+íõ÷u®)ý&}uVßôƒõ‡ˆs´;à«b½9B_KÕƒQ°M~•ƒ'âE·:Û(ïæÉ®åÕ²L™v œž¾0uR2‰áá{õR(}Ït£xƒ'²¤m˜v5¡’‚ŒÂ;tVö{XúAÄ)ZþÀ |‹À­,¸"NúŠEP¬ÂÏ!”Ð~>³ë0Þ,Ùæ\Ç’iy*×ü©M(„AžÀ„µrdºõœÈ¼³š¤[ fXg °)X¼,‹Ñ½¬Ð—¤Y˜ f¹Pèmß Ö0Ò}SK7À¥n×ë¥N×½¡ólˆ9ÌÝi™ìPÒÍÂÍþ‰‚ÍåîèÀüGY€VÁÆê»fù5\DÚƒ™ED™ ÝÚUaÙ!ÓûŠú’ŰY„PêÜê©o÷U&8“YƒDTv¼LvÝè Êö—Íã™i0wŒ®Ý™Ÿ0 xÞø’å¥EÏb^ò€‡ÙWðÊÁAHQ›ç½ÞŠNK­ŽnØQ³¼Û3ú^ü~~bŸR½)±úÞP@8½ëA-=â¯ÙдþÖáÃ;‹ÓƒMk¿P»ù¦™º&#ArDKB ÝYŽ×n˜¾*ˆ+¸öÏpãü½`àB³çãJñ7Ëj"ζ ,ù-=áE"¥‡åÚ¥·Ôlüo\°vôäî‹oý/Î,¤«±5”*Zò2ÇÑC°ò"/8ÄÌÇ®E±¶­jõF®Sˆß/‹aŠ ŽËÁ0o‰k?|Rr¸’‚óóyù òng“åžJþJ^P`èHôª–¹Y¢Í8Ú Aô&2Í¢c¤‘™0GÙ$âØˆh‚A !ÞD9YQLÃAb¢eû÷ã«×gg1ä` ‘€x7îK¡‹±Ii`0›ŽåÈ•L-•svÞ~÷Ià^ö¡R¹ ñ"̨ É¢æ½Q5Ú’=”¿ð¶¨bir pf3 #•T_ÄÔ²ŽmS*`5kÙ6uv7ŠÕ9^ÁjÜ×°9Ô±¹bI§–+Àï a A%?»!M˜ýÏñ€;,BJ1ÃAðÏÍÚ‚„u×l2—ÑZ´å¹ÊåÛu=#sFnäpòüa²iÅ ïðvžÄ *ÃÖŠ`nd/å©XŠ:œwõ]O{%yü93;Èq¶¨¤tÜÒyËWЉƒeðäs2Àd‡ƒ¬&, ˆÀ03…11³Ï)›#@¹²ÃÙ2.Àl¸ ”G¾¶o.Úúumlø­_ËvÁã«;·Ï,Œ’üˆS˜ä¯%u`"txŠC9^RN”#-•‹¯)¤Æ¤puÕ÷ ûðуÏ"ZU/Lª/±¢víí\Ðlbf`†„!§›¡l, TKçˆw3ÙqØ ?£3sAE0ïÆáÜóGûçöæ³wêÈóFrP ÔVÁ±‹˜êÔH³©d#ÁC‘=£8F°¨YkYÌ/²ß“žè“‚Õj°¾aùÇ'ú÷ŽÜ%(Á–k¨l_¥Ùˆ—-e²Êå‰Ç%›KöSâú¿ên"”ò—ýÍ®dãº#çò”wïõµ|i;w^eÇÈmžªO´qºÿÔ˜ä#xâœZ§†½°]É 0Ô:Ûaá„OÁâ ÔôyMöÇ£­›*Û{lð'µx†6åÙgðHHÉþÒÛç+,çš4‡<—G»ç—RYî-<ï¦ÏÚ¯]8ûÖOÒg_ô ÄÆjŒ*Õ-›¿>óÑï§û~ƒy*…ê+WÞg $7”ü“=ûó†àÕ®ÎÍŽmJ9Û.,ÙHá„€?±<в©fãu†aðˆÊa7çì§,CK–ñcÄ]û ËnÉÛn-¼ì(}uõèè¡Ýv?žh½"A 7‡6å'Nëã ¦N¡ªëÇÛh:Š>ÑG‹˜ -/…=vqœ F†E6¤Ÿ È¾ªD×-ÕWÜi¨Ì–ÂÃ$È]ðÒ¹À.¥j¹lá¹Ü„/¡ +»e;-ìVX—ëï¼ý«¦$;Û·ó›7}—Cç¹ñóÕNìÒÝïÅEw´m~`dÿ³ÚÌ),k®ü[\¹dòÈï¹Ôi}ìäèˆWDo ÁÑ’Ž•¡¼*J £ejME÷í¢/2;ðÓâìX¸ac°f…'R[±¨eàýݙ饟¾ê4Clð¶xÉþK6p®ýeÛ,Šñk÷ÃrÔ]²þ°çRª@týÃé;x‡ô7nÎ¥Ç%=WÕ¹åâ{OrV ;NM󳹬–9#Š6ÒSð:NòˆRDÏ$¡öcY©hYŸ~Ò#y¢õ+''ÎbAŠFÞÿ1”쉋±ÕT hɾxë:S7%<²¸GOMö¿åµÅ;¯÷×ÖñˆW Ù™XTD–˜šò¡„ó,¤™æSñ%û «YX©›§`?ÿ—ö—ù›‹›\séO×þš­Ï'º®&œ`ÚÈã ‡? W5]ØŸºx¢¶yÙ¹7¾Ë Þµ÷½N‚£®J„FO÷†k—I~*àö/?¥¥Òá%¥h¢¢a±4UÀoïòEkj–­`ØEØq€ W³;îXÅaR ò "縴̤çsÈɈŒ”E?Oðà÷Õÿ$)ÊŒçD¿ê ÓM,‰œŒqjêàÏ·S3ÇIáž{_"(¼îTý¬¬å³I^ò{#2˜1Ú{"ÑÒ}äùv¬ÙÕ·|›3íý¿ü2–<«îx´@бŽV³ÓN$är`w"˜ (óaRb˜`7 ’)’²X°ËN.ú’ÏçÜ_‚ÓU¦2f4)¢2ÆäUx\êÄžÓ/>ÈÛå=uî¯\õ)%¬‚À<5ˆXVQôVyÉâ̰1szêÄËVf\ÀEf¨®“Ô©ÁC¼ZÑ}Ë7ÄÀšž  ÆÙ®Š¡´\ø¹¤f3€/q³2ìãË$ä%ûÝô_÷åudeÓb8dpLŽ,’оǶعÀ©Î~ ,Þ09ô‘Vœ<Õp{Óª’„†ûû §x‚ò©?>¤Wä(r ÓœÁD‹Š¨ÂS¯‰¬U÷ý<ÐÜàØ .ã`\Y¡@i,›å,:Ç“á~AµZèüŠ’MÙÆG(ÒžM ì…Gkà"$ªù< ûðáŸ}J›èåU®èRë7ùj{ª;[¼•¡‰¾¤–^ܹ|¨FПŸýŸ™³ïRˆÛdý@ `d²¢Ë{d\M=þ•;~¨6×A"”å))AWWα2Ç¥CóþÊgó9²ÐøR­ÿ'bŽÝêCT&¼cHDÍ$s#}¯«”üð—vêøE5¬ûꋦ"ò–Áº^ñüýþÊöp23…ÙÁƒ±Xûá—Ÿ`Ñ*cvÐÑS"`'˜hÞhè’êêùP"ÛŽ(‹¶5WŒæË¨›YàOƒE;#re›ÝN |ÁýEÌáèU¡Æ8&Se‚A´s†8°ïùª57Öuø?õSG_€Y­XrÕÚ/þlxb‚+j6É…¬cúäà9 †HÔQa,952\Ѳb¸÷…™À¶î $*[V U5kz «<Ýï k@Â+€bKÌ0ø“ñf¿Å … –ÜË$ŒËHÑeö—k ŒbÓã:ÌuxʳÆкs{ÿi^î­M¨ ~ãùÓ¯}OெĊÎWçRU+o®Yµ5—Lz^nì¨éê,tê­—ü‰VÅWqf÷ã--Ó¼ñn!ó/jbtgdŒ —¹ r–èf0aÃqܰw_òü¼4Ã¥f™K—r ]ù+€P5Û«gðÌÀaQ%5+{Š:2f“#»’:õ;žcM?9ÔfØ¢("ìoä¼Õ¾XuóŠ«£ ‘·þãçJ¼~éǶåO÷Ø+(ñp]ëБ߄ªºÌ‚½xÙO¢Þ¤†èWA5›ïp2ɳ>ºHpÉóŽÈ˺9#o­v)æLA)x@„^ù5 HËÌjéœâ­CN2P¥ÄpšÈ£ïþêâžå‰ÎPZò¶^´¹óƇrcöì™s{d kF‘È•¾úÍþªÖš¥MF¾:éF3#óSǨ5¬ÂšÏW 2iðbÌ 6k©c@x ¶;n# æÁDzIž/q{·\ÖK$%¸0’®ø'jä¦UeT+ÊŽLƒQAAoI>Ù¼8vàß¶ v–R‹÷ƽ5kê×ÜmrJ¬¡óÄ‹¤_±Šc”—cÝŸIOO«•­n®[ÖpòõÝ#_ Vwm&sá}É_Ó±õkŽªao8–Ý 2˜Š\ç³?i©ífG(w' 4—ú·%ÙxôW×þpT/ædñšéâä¬_®QCØ@Œºˆyíý'oBù!ާ‚¯^¬\§C9#\ Ú˜9ûš•îQ¯CKD_c1›l¿áÚå= XÆûΊ|8=2ZÙ•<÷!âTÏâ5õ×ÝUÕ@þ#(’Å‚ØP9‰h±,+X—Ö_øK]ëù×_W=JÝ´(Ù¢µŠˆhˆ÷"*±&jTAo<ò 3uÂqôxûvÃ'•xu´¦ûí'¶â0¨67­$$Û®üz¡mÛ²Ã.Š H—¸¦¥m‰›˜:} ãª; P[=HQè€Þ’ ð 6$ñ bÆaNK½ KÕ=ù+ãççbÓc¦†‡ðËäF~è«\Á«R°.THMéÔàÛ?5“Ç8s’8zhÑFêiK´¬=÷þÿÕSƒ ÿXO3h¶Í¢/Ú&-¹þïÔºåAyÙú,Ðé¨0Lcü`[Œ!#Ùv€q¥Cµ!‰5R NI¹)j@ pî‚!ÿµåh®€ÊøI“ ‚C3æ‘Û†YÑvÅ¢•›õô”el²_E3ç÷ýXà­Ž´Ý8ÚûºcLE›ÖcQUc†N#õË‚±Ø¹wÊþxë–{,`b2<[99I KApˆ)ˆ/Èg÷îËM­ýÜÙ¼†=ŒB(a‘Ø$+Ò¼ñå5WÔ/_*a<ºæq˜:l™9Õïêýhjà@úôÕK?¹ôºÛ¾ülͪkäüéc¿ù v,9PÛ~ã7¨é^›;ê«n[zÃmûÿß  s¯ÜªŠd&€Ô%h™· Éå–l0H§"hVˆ [+ÄãÞ=?}2yîpÛM_®ÞÐcØ€ÿ"g*œaM§ÿµýØ*ÿv;«×=¦³¹“e@9Ùã½xèä±7 £}-WÿÝÄð!#u6 N™1f9lº*Ò²mùöë’Y2}v ^Û>~²wvôPëÇî49MT½¼Í:8„e##Ã,³ ”‡Öƒø¶-'“ºøÞ«#½ïUv^ݲí3BDæLc£ E l–ãç/6Á)­ÓQz©»~ýã&áE*…„&O˜9ùVvè„å¨ û²CûÅKÍ,¡ÁJóæ‡N¾¹â³?@È‘_~£ýÊ{Ïï}*TÓ|ýß›²‰ô¼!2¶"câòvÎ2®”‰>eÅY3³ý/?SŽÔ,«_·ÍSW‡U&ÜÞ]Ô˜ v ×ì˜Ûñå‹¿05×?ªÛŠœ/X ›&?Ø9øÚwId¯mé²ZiæÇ¼¾¨¡%mÇ´m¨Yï­¨J÷V÷Ü5ÝÿnE¼aêÔ+ª/kèá¼ñPÛ¦P÷2Û°dhžzÖtQô? È2a"d/€ú‡Oߘl^¾}èÌÁ–î«\ÚDM–¹"E6_–ö—s1ÃñóE˜"»ñ Ýâe¸ëô+¿.œ{Ϙ9áÓ0ãÞ`iš–™—}=7 S#Š5\eš³™é ž xcÑ,ŒëŠ.ð‡òþºžßx&c°’¤"‹ˆÈ`$1eýCCD¹-{~Ð>®O}45>Ô¸å+-×÷˜C¤ð0‘5âò†KdaÏ™›Sø¥?þ$ØOϽõ«±ýϨŠWK Â-’FrÀæ%”må¦`°¾Hƒ¤ÒÓg+ð)ðð| „Cц¼‰oøûêMÛ€Px8^'ȃ5Þ‘Áeüó©ã½'Îìz:ŽM]ØWÕ¾Ù›XïÚæ©ÂT€9r8S¤sÆ»MQ—úÒs´ŸÎÉùR NÖ}ç‚'\?;Ô?øÆ#úä íÄ,Rb«ºX×VƒÎ ¾§òfæÂ^¦JEoÇú»†N¿›Ož‚‡ ’[»âx^U#P¿7ìx2¶níäXN–%Ž“ÝÂIܱeÇ6HßΛê}3P±X„uC¿öž'¾øTdIkÛÖks霅•N¹CÅ_Ò/—_ÜœíÓsçÁ•Ó„©5¶ŸGb‚‘­9p”÷(˜X¹cñ¦;•ˆWò¸R…²zD$bÛé7òΓÿ¾PѶµº£' £üA´f©î8á¦î¦ 7²µl*ª%›N1q‰ˆ(±ª‡Û… ¹q@Ýæ ŸPÃŽÅkn«^³-U4°WžêëÍžÝgåÎïøÑ»ŸÙùÑKû‚µÅd`H×€;  ![Ѧæ%ô†$à –£‰ŽOç5'PÕÔråÖcï<Óö‰{<ŽPå7Ÿü–©iþº•+nÞñÞÏîÓ'NDk—I‰ŽÄúÏó£m«—å\ª Fqw§„èb¦ÍV dÞM ÛíC²@²q¤éKþÚÖÚµ7yê›òi4z|Oãê«^ù¡Lµ±ã/Q+Oì‚$«êÂ]º°§ÚÁª§¢ë)=;A[Tƒ0ËÈÛ6/zk;7}ñôÑßF:¯Xzûç‹5$È@§÷í>·ç—Å™‘À¢Û¿sìÅoÉNÆ+ù‡ÏâÝkî}¬¦ÁŸ7X l§ Û|à6R.­<–Èh)5`6ê¼áã#‡!2ÖÜöØÁ_»8= †ë@•@ØÛÅqÌ6aA Xz†£&ÄIj´KŒ¬øØ—ÿeÿo~8Üûx¾¶sÛä…C…Ô9ÅuÌ¢ì ˜zÁ_³¼vù­8õcôç_Üç VkùŒmxdtÑÊÈâgïö„ãªì°7]wï÷q‹@&$1]Ü•AfÜM$¥ýNsöƒ~tgeU‹¯²E§ÊôÐñe{ ØÖ¨•)4p|¹Û ë’J&‹aNæÝöu°éVŸWÎMö˂ౌ”WQ‰UÔ]1;Ñ-P×1{±¨‚SÁNѱíx×­$X¯çÆ‚Á°•ͶmüÚŸwÞŒ†2Ã{3ÞãxÅmNWh˜”²¥w¶M «5Ý7Ç×Þ!%sVîÂ{Ï'Ï~ÐuÕç%¤}ãç¦a×,»½ºg[¢«šSQi¯?·á¹[ž8Ö°††ÒÂZ¦P@»ïy#yòÌ…÷tSÞÌ'y^v°ä­^W»ôz+3~áØKb¸qëƒÏüñ›khaÂXö/²\šJ-ÙWï­ì‚Qs$cΛÅiÖç܆°Û|â9@&õAçó¼$…ZÚ¶§éеDGý{^?to¼y-—=ú0›Jnyà­CúIÏçîW«X‘ç÷¬bž–ö¯±£9å5)‘5ßòªAžbÞã÷„*¡èù#¯"ÕÛý©o„üþ—¿÷ 3ŸþÌ#{Nz§ïw_ç´$¤=ƒT,lÚvÜ 8¦”4[›¶­,r{ûåýúÆGù±~‘KNž{/ѱM 4Ýû,g¦îþéï šÑf%Õ+±2Y¡å] ‡Kç¶@cw¿n°fKõÊ[Óy½ýÆÿîóËDÏ œ2tIRã‡ÿ}æäªj@‘=Ùð7‹ÉÖôÆÔ]Dw[elÅn´“ÒàØ~^™âg­¹p8Ñ<3ú!Ç2B6Ö²yÇòOÜÿæÓÿŒ¶æ’½É³ooøÂSoíÔ§ƒÁJÏ¢f>Zõ7·åS– €ŠÒ‘‚Ûÿd¢Œõp-·³Qñ•÷új× Á¦¦«¯œBæô!Áö„=}Gÿ˜Ÿý(yæ=Ÿ¯RŸÕ3C4 [ü´ h€Ó³9eáí€X£@L™Od¶¯ø†(»‹À¼Ó† ñ;¶.G6ÞõÈ™^È'‡ƒÕK±R+¨ÞüDoòÌÛáúåF1Û}ÕÝÃÇþ4Üûæ¢M÷D—­]´¼U4$¿àwˆk¿Û™ lÉb׉ ©µê×òÓf¢sûlêD˦îäþw¦x)Þµ|:3<54رöÞƒ¿~¨0¶ßUEðrPÆ5`¿žg°È¸)k·3÷rœ—ƒ÷èZþ”‚KB‹Ö{ªº½Í]][Ú'?è=ûæ áúõrmg!;Ffú/عáöÿazû~çÆe»rb¬?Ú}åÚ»6š39Ir¥2¥4·xaó0àÉÒÎ:üÿ@bxœ}z×yæë×ïu˜ž¸³avÀ»À.203˜3ŽA%S2Ëç*ùʬ»«+Ÿ«®îT–®lé\§²-K6M”y I‘¢Dˆ"(ÐÌÈ@DØa±9Lžéüúþ÷ºgv¹<$³˜ž×ßûÃ÷ÿÿú¾çŸQ†¼0²e¤"aþÔà,§§/M3ìµ-ïB^#…9p90òá[2Cðw€£ð[ÀL™"é2F >Áð×° ‹Küo¸‰_á“ ¿bþEõ\É<7ü¿ H`ä_ß`ñ×ÝÏWdH|EøÏ  *fR¦2xùÿvm¼¿wË€c2Š\ÀϘ ÷á·‡«$ëÀ±‹$Ø–dXA—Â{!· ž_/E0|À\ñfþÓ€qäñŸáûpGá{øM؇ÿ/F¢M {¶W6ü»/îßs#ª€3æ\dɧ?Ü!ë鎵×u­nÇ wœ˜ßW¬ Ã.Õ=06_9`>"442ì¯//ð3ÃûÐû`X¶ ,„W„âVå+Hü[àypÊÝÏ—%I“…÷üEíÀƒÈ ð©ï¢¡waŨ•Æ{·<”]¦Ûf^QŒ ÀL J„}À68Œ è}¾ã ÁVC~p®¸ud[¹HxÞæR´cÆ-N„ßmXãh_l÷}ß °Ê=¶‚(•qi¼xø¿^zýÓ#‡ÞÌô¬Ï­»&¹4'é.õ`§>¿ “Á’Œ|À` Â/@ÌÆgX€<>–(ÄSxcÍÇ í‹çáÇèŠWzüÜø ö9?¸ Ï|¾,þ>2å€PYÝ÷âË4-µü%×­§®îÛú°3˜ïÊß›°°d£†ý¯@žjF~##î¸c`2ŸíaRÜ÷³ÒRø’ûŽ`ˆðšï˺–8óö/‹ƒï'ÙÂäÅîµÛlìõl¹ßh×™/ ÅãcæwŒÒŠç‚$A"Q¹pk7ï› àyÔA¦4ó7̈…‰Ü/‰¯…±‡0÷ï‚OÑCÏ|J¹½w¯âXMÐüóðóªbù¶bô¤–ÜZ.Ï.ßüxëzÃv9`ŽÖc˜p¯2OïE&0˜ÀÏÍåáËñ3 ^øì·A’>&´‰‡±yü_ h®Ðˆvþiþ²½_ž,øùÀËuÖF*§5XœâáÏöz×-^ Èñœ’žÌVË“±ÖÞÀSd”ì¼ñA™(Zkgº§K1ÄWĪ27‚Ëx©<Ä7n' ©ÞxbÁ"°#¦‰80ÂEŽÔ¼àrû‡;½çå ’g·¼¤"WÑÌ—³Çwþ@×huö‚–̺öœïÚŠÚŽXLn[ܵ~kÛÊzÊ',Š/µRH/jHΡ }qSø“ÈÈá|Q§XÃÈ üæf²HÍBÀ7Åï~qþ* ÌxR¸Pmz~ÏndÙ’SÿòmÆE5f;µ¢‘^&ËFzà¶U7ßg#dú•d.ÁC86àÃ}*!5\Â&´h1™…1À# Ò—ðˆ°ˆÛe֎濈¤åà÷_„=°Ý’T5ŒCâcÙCç÷|éðo‰¤Ôòƒ’dyVIÑ;’-±T‡çÖ°Ñ™ì\¡µç\¹¾äÚ5 … rK@CÈõ!W1ü‘ɼ»erhó~î)¥+™?„-Þà&þf%<Ï]>ØØÅqê¹®Âdl»Ù¤úùÎ÷Fý.ðK¾5%+Šbt(±Ep±ª)nûÓ/ö¼V*\\ûØŸ´öç\ ´Ì‹xOÀ“a‚ò Üâiá £¨É"’àvæÅ‚kšQÄ5‰$G9×<ü/O¸ # Â6'fGï¯Nœ—‘—JÄçFøvTK3ªÑÚ¾ìºdËÊ‹C{ôÜÒ%×ßܱvÀóL‚uJ°ºàÃ@H€{È/L§ÈŒþ €VpOf¡ÁÃ]4•æš*$«ËŠõƒ/‘_fW×Ó_ürwmú\etŸS8›J´Jóüz€ƒö%› sS®#/ÝôÄâëïÁ)$'á«®¨œn¸é8[r "ÐBôóháÏÏ‹O3°E4é‹|—¯Ñf-Ž´k““³ÜȦkzɉïyQbf:¡ŸüÍîKG?r½z,ÕRû{V"³¤27¢kqpЧ¶·¬ºÕ‘hïõTÎÊ-Ë¥z»,.;aQ 1À9TqQÈêà¤Ê€gLTøy c™€},6ÞPwÍÍÊèJùÑ”¯~. ÂjÂ*ØVŠÎ|öqñâAszÈ*Lê‰V«2«ÄâñL›¤v&:VÌŒöÖ{Í#KoÜà©6 ›‡vÃ"HxkÊ.J±`IFx?É©Až?^ "ü\ë6Õ ãpÁvÙá6¥t—üPXL¡jÔ°užc hpdób9,g‚ÛAλ`"ÔæBuŠ ª‘m;|h/˜°l9Ähß ?­ÏÇTbUF¬jÞH÷`¢Õ«S-ËÌJݪÏùÌ1Úû:Wß_œ™RŒø¦m÷øÂàEÒ {?h / u)ŠaÞbãFÛË¢LX2’ùÁ‚¾ ½F†‚¿™Âø/T›NBg¿xûlj¶ešŠÌâpeæÒâÕ÷´÷^wøÝúnI‹uų9¾5æF‡[ûoßpï3±VÞCCäûBÇR^Ø£øËÂÑxÿ‡‰ ;,äL$7Ô2Ïñyüdì+ªsóׇ_4|WÅhøÓݵ™üäà>¾˜Sâ}y½ A‰¥ª…KÉŽ­Ën=w@ÕcÐlÊF‡–éY|õí®?µhýã%Xða88‰›ësЉ û€½ø(Â>òÅÅ ûÑÇ,R 6P^C º¢Í|ôU nÈ e˜2»4>îUêÅñahÁÊc_å/tk£ªwmWÑsjÇU™ö‰tnrd?Öhך»h"ÛºœrªTLèý%¬CÅ„€ß‹÷ż9 _álðvùÓ0f<±µ<èŠW3fÂFæŠnôÉ×-×£ÜC:r=Sòõs|ì*:Õ]§RË_4 #Õé㺦A®ù~X¼•j©ÒôPº»åmN|u2Û½nôìûÚ†ã&sÀ³ —̆Ð<Où‚ˆÂ>vH’qá*¢%'—÷ï ` Vhäx3„à‚'w¼{żҀüÁ¾Š¨6bžúègVõóLMOF@û¡¨ q\£å*ªÇ­zQÏödõ|ñª·ôl¸½÷ÆkýPWåbŽG‘çq1@¨ ðcŸoð…øC²èC£pº¼yoòLÐ~ "Š\ +üÓ'_  íà)F]†= éÞúêÓ÷ saN>ðê Õ§ÎâöóŽfte;û$ªç¦ÌjÕHõøv LÙ¹ñ–•ÞíxP, TàÀ«" š Ñ£¼.Pב1ÙB]·ðÅ^Æg6Ç/ÒÇvðÎCƼñó™+µ45;sáô²õ7säà;C{_ò¼ p •5) ÁT4^ÎÌrQ¦- mIåVÙݶöšDïÒŽ‹a)EÆ^ÀÓúz¤pÃF㸰–á+k¨Ä4YøJüMÉ×| æHÛ^çšEòˆ["S7àŽ” dÍ¢ñý‡.|òŠU8ü,¬j­>„w,&ó™ƒd×ÊPžâÙU¹wdzV¥WwÕÈ·ùØÀûª ˆh¾x;I¢Ôã½i ebÍæûš…Æ¿b¨…I$þûñ_X’¾x†xµ\Tœ­AýÌ}^5âNŸŸñMwöä/“™,UäÒØÉúô™À¯íݦWtK†B\‰U[–n(Vª›¶}oôè{sç>ïûƒm~&‰’hÅ ëp‰QÈPÙÄÛ*‚'CÛ†ƒž„wÎ>ãÌÙªñ±²wYäüþ8®‰?Ì⯽ …—çšTƒô³{T‹ üÓÅsµu/«–í¹±áx:1uä hÛç@Æ>䲪·»^AŠAbݪ±Ì´ 7|÷Õ6Söj”DÑ-¾¦›3¨°{BÊes­&+’ÈaG\ÎǸ»\±Zc¦‡ÍÇ^w@CÓ!²_ø|¹±™ÁO¼òE¯<éXuß©bX¥™a5L™×Âê’õxëòÖ¾Õüd¦cÍ’kn“ºÉ"·nÇ¡˜ƒbÃ/˜Xú Æá“yµy™uñ|Âb9«9‘@"s›ø%boûu€púI§¾š.œ. Ö§†dæxæó-«: {“e“8Æ•DkŸ¬$d¬ÖJÓ]Ë·ÌMi_Ô7vú“lφe[ÿåZô‚VŠ%-ýʉkˆŸàù G^ó‚póN!ä÷ñ ð¢¿ü½ha@#T-»ÓÃj3Óµ© äù (ÜÊ¥ü…O ¥ŽUÎt®ü¥±½í½××*3é¶îüØP­4'+q•B@Zñlïê¿—wP÷U­É˜ÄDT÷ñ¿1|–/ŸA‰Ö>¢wÖøHLà›ó‡æ"Wâßö¦˜!ùØ¢–· ”€ÑYÏt¬ê\uîbuâx:ýâ7ªOdz§†ßWŒX,ãEBg@tÏ*ªªFõŽlÿCJ×ê·¬‰·÷›Ñ5ïrª_Hãä²_żš× ·-²h“yÅž™ù›ño?þ&$G¸ŽK¥â’¡=‡cñôŠkú>|áE»:‘J¦G޾),kNm’oê´‘bžï³@ÖR™ÜŠjqªkàÎôÒ-'¾zÃþqÇÊ–ºebM§V?BöãùR8W§!Õÿ›ø#“`÷‰_û¶mRÃðSÅzþËósCƒ±xêä‡Ïé±TþÒ ¢¨TÓÍÊT-UIÚµ1¬Äˆž$J 2Ãs¼ö¾klovù5zzñÌÔpjÉâ¥sŽÃýÈz2V¹rÔ¼p á©Møa4\ÁhaÎ6»³¨@öãoYÑ—=ªa<}tøàkÿÓÈd3_?•Î,5RLSßž;w$•êñìqÐâ±Lg½Zvꦢ’6­j¦ÿªÇZzúÖÞv''/®\’Ô¦ fQ‘ .#´`|ÎOñdBƒ“"„¢±ü¼Ù› üü0ÈÁPÌ ûä;ÿX/}U¯Žøn=f¤5 ¥Í÷¨½:v&“YV=ÆÍ¨PŸI4ž |½gÝóh¶£Zëè_•ÈhÝËI*òcÔáó‡íˆnˆqf±´ (àËn!,¾|®èð¾fþ":=ñ¦…‰j•YþôXPòÎîý«6ß{jßv«2ƒ‘⻎ëYXKb¢ø¥)ʉ[’yÜJ욦|Ÿæ–m¹óqö쉎ëê>Ê´# ¨€ÕlMqA¼:·N Áã†ãö°E›çqtÊ£¬á—…Óxùž˜‰‰qWÈæS;¢>ñVaöuòíOÖ2wn?&žçͶY+ä;î6=ôª¡÷n—K¢’01$$Z² šUåºWMN_}ï³EæåV¬lÏÑE&´X"OC„¢Q ”T$Œ¢ Ïÿ•_å7À³f@CǧÙÔ ñ-Dc|Ï1%LžøµÃx<.¢æÎÌJ>ùr÷?-]ûèÉ]€ÃÃ?šIwäçÂW¾ CRy{B–×b-TÓ|ß²ëUL4½$Þ·±}í–¥ýýÓ÷VÝòd׆Uªý£Â*Fßü,I4Má+jiÉüYR„Ÿ¥Âi<Ã\tAÿA‡öö¬ÙÂÿÓ'w¢­F®mK’ê×Qy4vÿ/d¶.ÛˆäNUÏ!ovüðK3_¾ë”gp,í»•À÷ø¤Ügbºžñ<èr‰‘]¢¶äšX®Wúo¹6”YœÓÔã–K5߃@RAs‚—­.kÌ¢ÃkR%숟F '¬‚˜â×տܽöŽ;³=Ü­vÝþàwÄÈô±GQ¢6ãšå‚žIÄszñ:µûêØ{æ”Wž‚ŠÅïÅ;=01’íž á%dzývµæZyÃÉjzÑšŸ\²)]·øè@i@å±$Ny0….Œ"<‰~‹ œ—qÚ.â=?ÿ×-wô^ªUSÑô§Þ \ÆoéÈWB²Qir6–hÍΞ~;öòõ©ãNu.: ǧFvéò뜸plbð`vÑFÏö¬òsË î”D7‰wlzìÙ¶þVš Ó[Û·—”à* /'â–FŒ7ìMÄtá’?#~ºž×c­çا?úLVÜ?øú=F+Oêo¾e¹„úb~K¹}e ©ò¹ü‰_o¯MMÁ]øí *3æ›»ºªò#Þ@‘b¹€Ä¬Ê80¯Œ‰ï¸ ˜ß•ed¤»2=W™6ª×ªÝ›¯Zqý­ðñ¬[Áö6ȇ-Ø…8 ¯!f„øÃøáÆâöŸ¦JûìY´û'ÿ˜ÌuÝýìC܈=µ³€XÒCØz5)£â™ÙÓûVª…Úô wæ¸ìÕAÇ‹ mæè™%È«ÛõY¢Æøxß…ÄcXÉ®½ßf´6y‘Õç´XÆ·«Ð~)JZÑ3½w}“ô%:×¶'pwñžˆ,˜6<6gq%¶äñœõs›Gœø5À6ˆŠX¿ñ¿~\?{ý×þóò{W°´ûäN‹+1qúà̢ʹKƒî¨Wg´TÇìÐn90‘ob¢‰Ã7 ÿš‘YæN½<%óG7< r¼½cù}›¿åA/ey^­Vše[bÝÙ „+ÎØÀ=ë°„kó³ªÂ‰„ÍwÁßij8?äóXŒx÷@d:\U˜TQ½1ü»¿ýÉø™z[×õÏ|sÝ}ë¾ö´%à\gFaE:øÁîá½’'žjsêÓN}L,«d¹uˆ`þl€¢0Ïð²$qAÑË9VE*ÞÑ¿dã-7L޶­YÝv}bðÕC‰veõí$ÍF|N(„%— &Ÿ¢{zøP²êa[EEz’”9õÀM¨’hIŒßõäڮn¸jõ]W· È_lpNvò”™èüÞCõ¹ 1M>»·­«obdŸãÔÒÝ«ëÕzKÇÀðW!G’íKÊ…ó¾YU¨ÙÒ6»hs­<Í$S¢z{ß­Ë7ß‘/U˜:}èïþjàîmk¸MMAÕ3èÂMÂ' gAØò“ö5NMM… Ôá¿úK ë ýíÿ~eìèþÍ_»úá o¿Ãç·¾hÆj…Ñ ]kö¿üW™ÖÞõ·Rƒ Þ¿tcè+?*dŒnò£f‰9&+ºš\ܵöžÙÉ¡®åý‹6^:;DÜÙ};°lçOiY±©÷Þ‡WÝ{9œÄr©Pƒèà‡õâQQª¨8å…}é’˜+ú ‹žzãMp—zàå÷&Ÿ±çæVßøàñý/n}öGO¿ë„ã¾ðÈ ˆÙœ01Óãtì÷ÚõOýüâáý[žéZºnïk^8¨'²Ì³\ß&j‹‘ìðíºkÕôLÜ3ÕÝã[Ð Œ´–NdÚª'm×ï½éé[Ÿ}ÆGEb‘(©¡ÂaÄ8)e6ç̰.+\"‰ù¸ë9•–Ö–—ÿì—öîJd–wõo˜™ê¼úþoî $ßæO_0F=?Vd¦Z™„mûxæìç®e%ÛW×K̹³÷‘2+ÅJyjɦZ:{/ÝeÎ^Š'³ŽçáX¢<7R†y¬ þ>ÂAR²÷–'nø“Çâ*20ÈR>?‰Æ)„Ïo!à ¯Ñ^É|ì‚ÙÔtdxíð¡×ŸoïYWš9ѳéîÕw<òßñãßçãMäãÊXáÜÁý#‡X%ßœól³kå]ZzéÌÈáÒèY9êé±6ÆUµU]ǘYÌ2æ#Ð1DVS%YÅŠf™s¾7§ÑÎÜ¢¥Dâö?Ö‹¹SY/>Wl#ÅdB¹€Ÿç/²òxʈF˜ šŒÙóèìgõ©sCŸþsך›êÕÊwÞ Ì:?âÑUœH¡ú ªLTNïÞqáð[W[´~k¬¥_"«2©ÈhlèãâØñî•[µXjäÔ.ñ°™Å\ ó!,ÄYØüD߯G¦GÏäÇŽ$[û[»7å çŸþÉß•¼¨`ñ’Äl¢ñAzøèÇÇâ9ÊŸbÇ¡E©­Äõ=?ÿôø›?_síSCŸm÷3–íþöÎÀ,‰'ÁühG<Ñ¡¢ô¿ýi-?œ[sGçÚÛ«¥zkûrC%_~ò¢mÕʨ-]z*S=‚] j@ÀŸzËóño|ˆ#ÕD&ÉtÛªZuÒóxáVRí[þã÷ÛV®PÚùð„wÍ£ ¦‚@ò=NDœ)™pÍ ……?TÄÏWú¬ÓŸîÙþã–lßì¹ý®[ŠerßÚø5VŸÅÚ÷½ö7†‘;¾ êÔÍßù‘ŸÌçj N]øèyÉž-MÐSµ‰!O *›ùKíÀ“¤ð | ð·ŸÜò'’°N”8c´rTO4h‰‡¸£uvê³sZ Z?¾kwʲfóøgü!Ø£[u s“Ù‹!Â!Ïý2š:iŸØýöÔÙýÕŸ?KøÛn¡ÂÝ%cèãc=Ë7œÞ÷Æê›ôc*HoßDs§†¡ÞŸùø¹êÜ—fé"8[·BE«ǵħ‘ÈLh2 ôÊ ü ~$Ë—–eÕõƒÛþÓ‹×}«ïâà´¦2#ÓÓ¨T¯AS0>ð*!®ËOÂhØi¢2Úó‹Wnzê)ûØqO}é¿ý™¸’?åZcDRã©È_™Ù«u~9›éhí\Šf¦ÑÄù|¦­%EÑ‘··«4{þø{µéÄ8¸ÇK–xÒØ–e9Òï’Â+U0¨8ÙÀþdɵJuÏ)‹›û~`£ç>úúþbøˆûÞÏþûMÏüÙ’kzÜ*hƒy6ST1¡u™ƒc„îüë6Ü÷øòÍFݱíYõدŽMF÷T¦½AòwÁN¦‚IÝ£ãçÇ[w9ùÙ‘ã'¯¼mðÃ_µ%•cïÿƒY.éè¿„ôìØaf»²¥ÅgÐN‚|ÞŽ ‚½ð–UñA?!*³ÓlÝ,° Pcfq tb²{ kíÖñÓGÊÓ§žyé]Ú ‰\$Ðy0#ìȈõ´j¿0‚>øé?÷ݰùšGÖØ¬VŸ5öþËo‘«ø¹S¦`¦>ý~@E× :*P8Ÿ™‹ÃŸ|†CQ•“ïÿ­S›¡ZK¢}íã-íæì™¹óŸÇS‹íúT1>ãôÆ$‰+o™jð'–^$ÑXynT’ˆB´@Ñ«¥™lï–ò¥ÜÎö]H WIw-¹iëÝÿu[½\T5 4ãÔßã ËÌ'T‚Þúþ ‰Võ‘¿ü:Ö;}ü튄K®9!y¾F³ßøÈ‘¸×#®œ86Ð$:ú«W.žxߪ$¢/]oKk÷ôØ©ó_ìì¾öÉV]:üÎÿQhWÄ| Žò$0é$B¥€RYÑ´tŬD×Tê#ÍuíŽUwº… ·4Ýž[39z¼\<Ÿ]wó3/üe¹hkšp5Tþ é+ž98ò‹O§‡Î()÷þÿñ]#‰Ž¾|ô“çþ²-‘kõP©pþKCïúÿ¥aÚ'xœEzt\×uí}½MŸÁ z'’»HJ$Õ›õbÉ‘mÉE‘˱\âÄYY?Õù??¶lljã8ŽbµØ’,K¢ÕI°W°@Dï3ƒé3¯¿wß?whçsabæ¾sOÙgïsïç>q¢F‹²)Z€×4Bx…vh–…Ÿä?]y"r0fyšsËb•lSHb, >â°6ÅZàˆð9!c“q,‰sLXJÔyXØà Ñ<ò°é±…h#ÌÁ¶Çc“&+à ϲƒiÙ|ÁÀ‹â3Ç3Ÿû½ýˆÆýÿí‡'ò°bh𬠥Èga! ´ ¤'‡P¤=¶Uæ°ÂÑ´6#$°°wdY°aYÊÁ ¢² °1° drlg¤€â4X¶Îú¤M÷Ü-FÁÀ2…x† ‘~ÅÄD;¾Y¯,^*¬Î–+9M©c{oè`°É‚©,§;àsö΂µðAp¶!a mÀ3.ÆCÑ##-{iÿü¹Ó¡š ž] Åëž<è¢ßÿ»j'Í^ D2_æb©k~µuúÒ›gÒ£}þp½š1ÔM1r°^ðÅ,'³ë³OÖoZã:u²ˆ¿F\ÃW\H{–^+ tœ¢j¢-mâ¡x]÷…$|Xh›¶È›‰¯!ÊK "ä…Æ<}âµ³K#§Å Œ­ €ÅçZ¤RHûaª ¤$¦Xb²9Üþ~¡4»œh½FÍÎS£€) 'r¼_ò%{v¶ïÙZ¯X•–P+p£IÆ`B3—Gë»X™K ¡¹þ‰üÜ…÷<*†Q¸yâDä À&JÈ %¤~IÚ›<С1‹=ÑÆNÒ3õ¨RÆñ6z¦=qØ«¢”KU3Ÿd~1 hLŒ§Éw“B¦Qjå/O˜faqôpvî„^H"5m¼9±¾#±£IŽ ´‹(#2š+ÎÑ Ç'ûßjܶsÝÞ[Žþüu-S•„KúŽº ;ôÊtïk•@t al² ^x‹ÂPÙÄWsIdM=1žO¢³¿ž{â WMu¬¥]µŸ‰AlÒ­J‹h¤ïDnfV]8cj)^ñSPðŽåQ°y›ƒH±Öµ·ÿésr Dš„Ll-¡–CãGfVÆOt]s+ÀS!•Zž¼Ô¾óѹ‘c¬LG[?µI”!Qlxƒ„j+4HN{1‰¤4Ì14KÙÅJ2)ýÍØOÊ–  lc_¾ $¡e‚þ€ôþ÷^œ=òE‰ …ü½J¤®4?h•VkZ6ùëZƒµmž¥Õ7÷JK–WhÜÚo[,¶iWÁy û튔Eã‡Núbr׎ۧGFÖ*ÉÖ[Û¯ë”#€±q$oRŽq§D@Nƶ IxN'>XÉI•ð²ÍJ†GûÏ¿š?ôïûÅÕ&hI2ß†Ö ö7~ddun6ô5Š¥|j¡4}Á)Î)-)Ð!‰±aÛ–C ì–‡?¿û‰Û*ší8œÀWŒ:ŸŸÀFšF ÉýUέ¬rR»¿¦qç§oˆ´‘lÇ”=2DÄ3°¼é8ðQ¥Úà×eÇ‘‹™ÐÅ·çR#ÇýA¤ÄÎWóäa«Z¹ ƒ¯BÐïàˆäB¾L‚À"’L }ðòGˆI$/àœRay{¤ÄFö…;øH¸óŽ=Ý·nq-Òê*’üÈÑuŸ" ïO–——(;ã+™ù‘@펵{)ªSu½á†îˆ@0Ù2érð'¬HPûUtÂ¥ }æó 'Ob=ëZIÛÎþÿOÎT›”ù{ÿ ¤Ø±y–+.˜É±1€,wì¹åþýïztHô‡CÁð̹·bí;Ã=Åô ¶ÔûK*‚|­¤Ë‹,š;?1zd‘醮µ‰–ÚråÊ©Ñþrò‚°B¤yÓ#³Ãû×쾦¹'ä‹ vhŽ!m8ƒàVÈÓiMž¯äsm»6û:$X$5‚§ŸXÞoVfž>ê¡j¿%hãT_U·Cö‚=¤rÈLéø/Þ\< a ùb6Å›ÍJÆ®$9É״垺u7ôý‡ìó‹ŠÐ{ÛCG»‚ÓÜÓrxqÀNŽWÒ3²O&Œ()¦çÎnØ{Ç•Sû‚¡õ±ÆMŽlØ´qûŽ…(¨;Ggx pìüfd£‘Æ¥ÉÛþèÏj·ÅL•rhù’}ùýwÓcGÀ~Š˜[u;®9²}’ÿ„ûñ:°ÖQ¦Ž«é±4¸ŽÁ—,CLt…ë:æ‡~Ëûjš¶Ý;}òu«Ø*D×íxø/ʶ޶¤ñÒ©´Qòy6»ºxD×XÌW߾溛Æû^6Ó½P„]{ÃíïÞ›+,™x¤™¦ØòòD~ìàÐâ¹ÃX[ Gc í½G÷~êb=M„Ê4öÑÈÌÑŸ:ìaÒ³ ‘-@í3W{1KÈÍs.ó²‹,ny°Èàú¥³ƒ™¹Ó5­ëU­ì¯]“=S^µõUÄÚÁˆu=ü]«4®ÛûôÝR\MkŠ›W‘&e¦’•¼ ØUN ¤ú³à¹¤ŠjÚzßSƒ§°Ž;·í>ñÊ Zf[9NæiÆ5Õ< ÄÈ‘ÖuÞ‚DщïÿX]˜}ö¸çAõAbÁpÚ­V1s•?c d˜–éÕ©Œ@ÇÌ,ZÏÒƒÀ!%ÙÇ‹!žç‹+ƒ#ÿædVðSÈDű-­X ¶m¿î‹_nê A¸‘†(‹Ð¡R™**'Qòò¨™ŸYR*Ò¸Eñ5Js²H±¬P›zò¥¯S®UÓܸÔеsôøkV%GQIJX×µJ¢É(Uò“cV!÷•ãЩtH8†ö;ÕžLѼ§U{O²hiОèë/-Le'Þ¯Ýy¢ck$Özåð«Å¥óVeÎCV´y›ëHŽÇÙfÑõ4!íùÔm»Úèe–î”WuƒaΰlÕà¬øõÇNn–¡5ZðE›¯«ïذ<>XL^¦xEüFz©0sÁ³u)5ŒJ ®à'3}úªÎ¨„ž‡([+Ñö¤GcD„ØA4!žu8"»Xâ¥ã/~´xæ,ãQ‘ºF±ãzz*?sIË\ueª)¬Ëc¦í2_³þö/="I׎*leŽ9ÿö낤t_»çì'/n¹ãÙìäìÜÅCåì‚H€?kÛ7'§Nšåä¶;ŸŸ›<ú_ViITB¦aê•ë‹EÖéÙ•Êê$„ X×m– ð…í¯ÈO÷{W™òÿ´­*#ÌZ¶ƒTA 8›ºrÿ·¿¸0®ª•díÚ@BmøÙ³â³«i]-`ÊeÞj±´‚k›×>š[™_8íXI_$úìi®ŠÖ«]‹%¬‘ð¢%‘•E9´g pet½óÐé—¿kï]¿÷ÎKÿ4ëÖŠ…Bf.PßYLM2.ãjEÛ*º`d¤xu8Þå 7ˆÁ†ÉO´|ª®u§$p©¥ »ŸüÛŠ‡ö¿¼é–‡°®ëéˆ4£É æ™_7²\cAV¢¬Tﲊ¦æ¡Æ=¾°íè¹ýO(Q>ðÓâÜ1è,_9íUÙÀ>ïV9UìñÄ~Kj |N_ÍLjèÝ\IÓ¾Pc¢c³¥OÏÛÖÊz±¤•s®1çè&ç è•%ŠÙ(ÅUzïxò–¯Þ53m•Ö–ÐÄÑó…ô@ã–[îëýí?½h Íë¶m¿ë†‘Só«©éþ£ž± “ºžé¼™Qê–†öÉþ€g©Žá°r\ 7WrW* §9žùÊi÷” P@ ßÉ~تæEhöTràw ³£ˆÒ"­Mµ-[R3S™ÉsŽžU±Pm{¤iÃÄÉw”@­­›ñ޽Á–õu=]•ô•¥³Z¶Xß½†ñ…íÑöÚ±£}Fž6Ë4C¦ ùšÖŽ¡_nžhê ÇÂÉÙ çÏÓfvšxš“*•âî/ÿbæÂá•Á÷#õÑÚÆXsG!·¬ÔtÏ ÊŒõìò3§-B~ȰýN¶ÓWå"Q Ê‘#-ê“'Žk ›«Éù³fYÔ­áIÇ­[û~ú%Á¦î–ëjØÑi@áP1´0’‰7Å.+\xû瀟®±oߪí.g—-}uëíO ühað¨ì‹ºFÊqò ;Ç£\(zć4Ãw\cäÕù1–öþá·ÖìYk`\ßIŸxÃ<ùÊŸ:Zöé~—4UµGT'WWI¨‹ÉôA>ðDKÖ$ÐÑW–ίoÝ¡fÓ¹ôpš—–ßiìÝ{ûsOS1¤ƒh)”}²D$¡|õâÒÙ”,í0s#±Fz×Ý»áA ÷GÏ™•BÚÎÃ^nìØ–œ;¬k+Pž–(¬‡ë:…pç•3‰Þ›ö<øùÁwÿ½kÛÍ]{Öqlb;5+\9:7áXfºï+ç,újÂT¹7¡@,HfЪЋ]ÐŒ3åTšgý•”saßÛËï0¼ŸèÚݲᶥ±£éñÃj~ª¦kWמûFNÊáÐ]ÏûƒžÃ’q%ä¾Hœo¥ÑÑŸ½™™2ÊËþšöÆÞ›6Ý»Ób[4|´ÿ·ßý3d[¦¶BQåQ‚µ,ÝãX³’åå(Ï)ŽcØz®}÷ƒ×}á³§ßúºcC×v­œ´®Ü¿/;5X»áº•¡ßÖµof\zâHkìÂðé©óûy_8©Ÿ>õ0„Î÷-Ï\,­N’q˜ã0‚XãÙkþkÃâKÙd Æ.ŸÊ. ]r-——½<‹]«¶ëF`Ñ[n}Hªñôƒ?×W][Եׯß|Ý#˔ϡ#¯½3sâÍPËææ÷›¥Òè¾ïv÷|ê™sSÕ0¨:ìÎú\Ì]•‘Ð…Y2\tLÇt±À²þòDnô“ƒSG?”¨mf]È4ËñÕtª© GËÐ4ËòŠçšàg^Š3lBf¨¶SŠ6˜ŽÍRç¶[-þC¿|oiðø#­uÌŒªåw<ô÷R<o’ò6:ÿ‹ÉŽW‚!×ÉSŒÐ´îÒÆkn ¶´Œû =>Ô¶ãþô•£ËçÞ¸éžo~íB 9ÊU³7…Ãd#._J ¥Á’ ‰Gz÷O^Ný†i×Uã=wi¹¼YHa}…ò4è}ð†U`P›ñ®-˜b,M³‹•Pý†–ëïôÂJn~)3pÕ ¹ÙHÛõuí×N|a÷Ï­¹fÃб¡±÷>Æê´­-ñ’h»‚Ç„,Ãr­ŠŒÉñFŠgŠ rÊ£¸Ô½û±¯^0<$T%¢-B! ‘Itµ—!ÇeE"͇ûNTÒVMý®3?ÿ~)y•81X£–Wys´i«[\ÉÌû£mÛõbÁ*§€Èyž äÎ1m2˜AhÍïúâãÿó?i+ªí5¬‚aâkv†B¡“¯üñÚ=·>üÍóÂþ+¾´/äÃàP1¹ %JX‹?©ä—"-mŽmLø¸¼|…c9üê9×¹:vƒþå 6ìÁF°—«M Ó*MKMùÙ‰¹³GÝÒ”Y™gå W}†[·Qàõ²Z\u\ãöç_;úÚÜ™·)lS°²(.J)´ç"£qóÍ#-Qj¶°r¡f8žkݸ;ue?€ðž‡¿5Þ¿îè#õ ?3¾ØÖǾhŠ ¼ýzrìp¨±½}çíéɹ˟ü»$‹,gWýà)é:0Öõx2:…]™%26ôóœBÓ§/žûåÿu4a ÄÒ°4%*G¢­fE½Y›ºrdçãÿGÓ—e%¾té„­ål5£•,l¥°™aÅ£xÛr¼5Úy­ý (v–®oh?ù«üüЖ;Ÿ?ýºÙâæ=Ê1Ô²^) þ¸œh‘ýÑÜ숫çYžÅžëQ²].HŠL¹¥¯ €f‰ì­î¸@{È¡v fqE<3’ŸO¹ÕÜä–c{w¯½åžR1tBÏ€øèõØÕcí×uíúâ±×¾]Ó±­ûÆê7®ƒbÉ/!SÃN,Ÿû7¬§= QLÔ£=>è«Ût­k 7÷úC5Ñ7ub¼ÿ­¿…îäy%ZLê:«R˜ô°%ùb ”ÕB’¢8P[6ªƒ”އíyð?áü[Õ[=ƒs˜DˆþÍw÷Íœ9Æ›mu)ܘ¸ã©¯³~ÄÕ"­‚d}oáÜKc–äP"Ö¹#Ö¶{ð½;F±aÃõéåÑК]º^ÙÓ–g%ë™ÉÅñ3’åH‡mfºvݾçñ½©¼ib½’4’çF†ßÿ™ìóÓ”¡Ù^¢ûæXËÆÑ¾C[Zdz#¦Ïj*Sز"'\dNä}ã´gñ„³AÓ%k´éÒ•OFh½a¼ÿý|ú’¿.qÍÃOµmö›Â4/Æ/ývháø '›,¯Œø2J$ѵgêäëŒÇ„íe5%„uÝ7s¬ÏÉ.— ËëöÄxíÔÅ3¢ËŒÚtÓÍ-×Ö«¼íYœµŒ~ýÏø|QŠu˜@£j.eK©ÏÊÓv-c†â ëg8É5K®­Ê±Í‹F%ÿM°Ÿ%lŸ#£r úÑŽUÆ?Z¹<¼áŽÏLõ­ ïÜùØêÊ@Ï=6oQó³w¾ó+—SP–®rþFfä@MvÒLäD{:,êè`AR¨­ió½|P*——\옃÷ĺÖ5×>°wôÒ^Š-\\ºt¦”ž Ä[ƒ-½¥Õ¤QLj…yš²rtc ð?Åñ¾¦Öž{'ÏþÒ¶J;?ó׆Y™8ñ›o#0A³˜Œ¬10rZ*8œ‚ª!WF«Sê¡þѦ½_Ÿ~µ~ÏÖ¿°mªÏ<òãÿÊMŸÄÞªŒŠÁF%º^ˆÕyž;Ý÷#–(Ê%ŠH!XͰðŽOÿýòÔéÝ<}&³˜Y FâcÇ_*&GiZv\Q(Pßå«íõ{uò„kæx 8T‘Ì•y/×ë6/š_w£¥—ŒRæ›ç,`ˠ䄈ØOÎOË–BÜìtzöÔŒh´ }òÓÍ÷}®ó®1Žþ{üò»Ÿ”’£¾š¸‡ŠZ>ˇZËÉA_Ã:¬gõô4Ç’>à?…p°½D1Hp–|ÑFšr´9Òu}%•zÿV)iYš_[ÎMÆZz…Ø:hD¹™3Fa‚¡=d9fYIqN±¢­YžK7mýƒu7Ü;qþpêÊÀóyøæ«gÖ@û¹«óž¦§.Ma_Oׯ;Nþê¯ãÝëv<þ(A§ñÑ௦D»w>ôá¾Ï/^f}5Jm㎇ž9ûÚ?¤‡Õ´î-eÆ<§HDÈÔ7_öçV—ÔJ’rl^ fyãƒ%Çš/¾ñáX+ˆÔöî=õòŸtïþ¬ß:{î#wX¨YJ‚縀ÇT‡¢ž 5|çs?Œmj5 TɪÏ—\Zñ0ÍþEˆœG•’3êà}Z¦ä¶iÍ–+gß’#µ¢_^éw]Ú!g»®V5ôŠÁPÃÆíÍ=ûþáQ[+Õ´íÖJI[ËÀb–§ÓÀ°l d!é+4Oy<†Rü»?“_™ Ô½¾{ûÙwþ1jö¯¹aåâûfa9*™‡°2bÇÕYEA.½Ò(9²Ïõʶ­bË×®˜F¦ûÖg8KÉ´Z™WW.‚@ÎaD¢@b ³¦yC!µÈp!Vªui™%†cÕÜB¢u{vö&Ù Kb9ÅÆþmƒý'ù%hÞÔ°­g÷‰ýdæÀÝÈWÀ,„ Õ*±KýÉéc§k:zv®CöèGÖw,g§â‘µ7oH--ì;–6³s®“¥%¸eÛ57=sè¥ohÅÙ†Þ{—'NT_Ulë9±YŽÜFð É¢åy²¯^-–£׃öçXtè?ž4)d:%—'ÓØ…ÁvÇr‰†gE×ån{æÇ¡õq_'ý|¿Çø&r,B¤ÙÚÿ“}FIÝñéϨöLn)ÉËëÆ½ï4 \¨˜=ñØßü±,¢ù‹æ™}}cG^µ¬©ïZßÔv]~%7~òÍâòYòŒU=€”r¢ßµT†åiPʰ^‚–­\´ùÃÑΛ9Ì/{µ¼t–cT€zV {c;O{¬ër€`P YC7~áÏ×ߺ üÏ‘»%mœwuìoa‰§­=9!…±ƒü1©¼\˜8ãªn]×v«ã§~%úƒå•E«¢óXÒÕR ]»JÙÕ¥‘ö Ï)NfõŒéxŒç8*¶4ÊQQ°¢/TÉLAè¾Á“£]{=ø£'â õÃÓ¾h›^)yžÃã ¼ÃOÍ‘‡¢:nEš×VÔü7‡ “RèbÀ(RÀXKåEÉ2è+g2‹ƒð\««SÃãk¶ßVÒéÉ‹G€vÒ´a–=×õlUò‡X^(&§yp ý;,7nÄþ_‰w홹ð..­PvÁÚk ë)LY¦iÙ@†y!'ŠÌ.‘3tAæ¤(¶ ëT"‚€’Q€þäp¤)Çùˆ¬¦0 |"ÂÊ`?(Dþ.m_…ªá,I¢Ñ¡_¾céhË÷gÑüÀŽáË©y«TjêÞ8sy 57̉"¶ó@þ”/Qžeh9– «`ÿ,Ä÷Kÿzeìbiþ'Dò³Cž•cá:ǵ @ï ¼¡«r²ŸãY£¸ §ÉiVsËŽša"M—”°$ùhrBÃØ® ­€"È“þú$Â.vz0i¾@@ÇLå§KŽ Ýº¤£eÛî©S#É+s3çýŠ/»ñ7vææf¶ßýõ ï¾íCÏ6,Åî!†s®¾çŸ\;Ùÿóú­;ïþöŸ}ð½g½Iy&¢*´T‹MòZàE–gʶMÓ1¡?²Ú´¦žXãîìÌp~ái×Àš(žfe™…Ä¡(Є`ÍЀý¼/Àû£Z¥hZm×Í µÁþJÜØ¡«·ËÈÝ-ž^^™¹ÒÿqÇŽÊå¹ÕÙó” fç†D½‚-=ïŽtnTÚ7I‘î±¾—®¹ïÁº-µ€Âg_:uþÕ¿ $¶>øÀèÑÓV¥¬gÈ‘.ËÃz€ „„.ül0"D×Õ6ß6üÁ÷(\¢ Ì84+@qoyK¯€¶…Áp䜚áýJ¨Ù1 ½”â|u´»ë_Oo¾i'MnNþþü‘¶9ž;yqìÐ9-e禆Â<Év $ØaXEP@Ó…ËùÅxû5R¼)´f}]OoM Š4 ä¸êã•Â8zão?縙M?µa×ý³ƒ#K#ƒKßò¬ #uL–§@JI¡5W£f&]s•"sWrmÞlhKÎ ˜ÅœgŠÚ@uk9ÑW^žu*y²Žà§¤hÏSom¾ûÆæÞˆ‡tì€Ôü× ¬#9ÂÑèÕ§ÿ)uéÇ)q .y(´@-Ksz%ƒQ¢Æ‰µ=ýÓÓ\+þ‰}é£/þ ?4ærnêú/þ$Üúð‡Ï»ºKyí™[ál¼?Ø — r¨Á2+Zif Ó£¶UB ÁúMP¹Ù~l (c-ÛAEfçú™êÕhgJ}7xaí§ßß|Ï-=· …¼-ÑC<£Z,:ú“SþûÐ-€ŸHÁ´!£’µ‘Ëq"V° ³~í ½wÜ»þSõ Qú~ô‹áw9ÇÅ©®çBÂãL[×=3ŒÀ Šç\Ï`Ä ×TÒ3,¹] ¬—²]€g€¨ùM³ ÆmÃåù ¥®¸f–|[˜: ùK“º‡8òBùÙ‰­ï^[ÛÓ¼óþ¡Ÿ6Ap‚„‘^ÿÚ K?á±–»6(¡ïJáˆÅrrVñ׋~”n{ú/ÎüúűýoÒžDƶ+@¯ø€²’„»db|Ø®¥• ÅQ„Yš D‡véÞ#÷cŽ[vÕk•åp1=e›%)¥)¤S<ˆNÖ4`VCžQ³î™Úžëz®ÿÃ^¨Ï¶ ç›B‚¥øÐŸ–§ýbFõÀCØkê½ÇT3Z1[Óºµ¸0âê,ŸšôÕt›9€Så!ùÒ ‰vÄÀ–ÁíaÇÉ ¾P´y³/Ú¾º4ªfÆír–‚¾ t”²iÂÐDǘ§Ù@œe›´ü(Cáš&ËÐËÙÄÐ,ý Ô¬Í0Šleƒ­°-?­_[ó@°eSÇÍ÷oxrÊœO·ï!”F~ï§«ÓÃQ¨\èM˜ê7ßUZœ-ÌçyrÔgXS+{˜§XÇJZyÞÁhâð3S1‚8+ëšz®_MÎKÁšÒò•Âì ’Hà4HÈÖ%èRŸØþìʹŸãÊð È“«¢ ¨ÉEŠ!WŽY¿'„- ‡àR´ãvÈ¿]_ú«ÝO\k©&b‹R#ʶ­Eš7! ðì"r{är¹®H#F¬Òu÷ߥÞ(NŸÄ–a“É´\"E)]-¯Âª Wm³rM¨¡'Òt#@Ã-Ï|ßÄÖmš7À{ÈÕ롾‰¾¾­›Áäv¯hq£¦±{îÒû,™É”(ìB‘Û–nYy¬[?và?]ƒŽÛô0¹.L2šû@¬ Pw"b›Ì(09÷tÈv D`Q4 †H)fiÉ5JhÃS„1+   Œñk™DÄ"CÎÖ=®¾ãÓÖ8_‚ ´ø›Öo½ï•ùý7~éþÁ÷ÆþøûÑX/Ç˶Îb6¹|©OfCŸ 4´ä–')„CËbbÛ .Â*•=áËŽ•­òÛ¹À`çì‚é òù£yž÷“a93È­n× Y…©^õ¦ÈEc®zK:»G$”<ïóÏ¢¿F#™…A´*lÊ¥hÿðG¢6xœ%št×yçïÜ™;}^½@°ŠM"EÉ*T-S¶¤ØŽí¸Ä^;‰s¼)»9›ìžÝ¾ñž8¶¯[Š%–›YÅ”DR$EŠIÑßÃëmz¹³ß0 3w¾û}ÿÿï?3}Ÿ3›Ó¼Ê칿¼rÕ5ÜÐóÌë¹îQÄ¡PÍ‘ìHcežÚv¢g¤S_2JfèPXÉ L2X1êUó¡ë0 ï®oÌÄâÝLÀX†Îˆ¼Ïº éF\¸ëÑߨ-n]z]Ñœ±=[·ß÷ÀÌ9k}öjïÖØýŸü&b<Å,B#ŽCȇï<Œ)凢ÅèüËç7æ®û^¹QžyÿáÏÔ‹ Ûž~w}æ'ÉÞ¡üÈŽ•«Ç|ÏôͺË!VdiÓÁdžvûºüÆ«Ûî} ôËoýµ×ª[:õ(,;ôM껜 óbÒ6à‡ÇÀ9NV]ß$¬¦f»‰š¶Û^²{Óø[v‘ÀFå›N»j‰IºçC)(FTâ0ë£añ,ƒqˆQ­a­,vÎ/§â[Y,Á‡9-_/ûz ®tË‘—‹7^E¡‹B†%¢ËÍåþOš.êÔVòƒCÃãccc®‡n^yß6j g^Kä7gûv/Mwôjè!²1á8AeÙ7MX,™ ™À‚ôàNMË­-œ’©üØ=Ù¡IÓ«ïN%S(l¢“?9QÛ(Œ<`´g>v°D£”jv‘ÇI,”Ý÷=ÌŠ|/Ø2ÐÆ’¡ëJ»‚Z%T]]m/¦¶}•ú êëDCŠ™0dëÝj;^_V•¥ ãfÁ5[jª+Ý;Õ(—íN Ñ0¤&&¬œÈtš¥dï6ê✨hr"OÔŒ©›±xÒ5 bBÝÿä§ÿüß96²c ×'÷î~ó_5Ê.”ëî#=ðô’|)>ôŽðch# ä¹® v„ã(ìLµ!{q±ºàJ’Ʊ¡¾Õ*œ ƒzj`RËŒ—æ.ûìN÷mVµ¼ÓiÕÕ hûE12Ãè4¤žm²¬Ò¡€Š/ðZ¶LQM5×o N|@Ë gGöUK+kA½’çV¥lŠWzûÆõv÷ÈàÚÊôÂ¥s"7$‹drïè_ÚA ¬ùvçó”b³ ¦°xsÁÁvP +\¥N.7* X¯­ð¼»ãé7–/<ÇX‹'Æû}± «¨ Úƒ›ïK¤§ôVÙ÷ë-½Øª·Œ&´YƒÂåxƒI"3a4WQ׋b¹Q;°'>yö¥?ÏöìÞqïç …ùJù¶ Ï(als2/'{©MôJÕµ;¹áíC; H(.ãã‡>ýh®O`d³ˆˆÐ0A6°C]D±/"Ã%k+¨VFNËC´Ó½ï¯œÖ<Džɾ)]7:åù¡­»zò•õ¹V­RžÅâìÌÐÖêz¹µQâ%UŠIFs…ãTIí²[E– ´d¯OQ«¾Î–ÚÁŠ ôšúå|ÎwY^FLHD‰–g{I&ÒãÇùv)7:Ô¿mS¼ôÄûG• Z)†©ô}Syäv_a‡@+yØv(nw”zeº‘¦¡þÃÏëkïñ’RóFõFïðætO¿ˆ‚6V_™i¬õ¼¶ì6ë%Ð6†hDâ×µFŒÝ(¦{wè½´t…#<ºa²0¢Š%¨×ºïÍOÜÓ./´Š77íy|bßþ÷_=j7×Ç·ï—ótû““é~„,X­ÃBÛûÙ…>Iò-ý¢*œ:IJw뺫W¹ÖjAp×¾íuæp¨G‰8LÝÞ¡‰N£Üé˜DîæXXß®®"ÌóâY'‘ßÖ;±¿Ñ(8z£¾rU ŠïyHVÍNNÃÁDCÁ³¼èÙPDOÔ§®Kô*ñ Óš¥Åþ± )jžßtçæxÊÈçc>ö(Îó|ŠCŽ0,ÔÜã ý€ÃP|Dyê ' Ò±/Ϻ‰ÎïÔzþ{»9Ë"D *„<'†¹®Ã)Ʋ™þ=ˆ‹wjëØo*b@”üQ5ßs* çx¢Ås›ôNUo×@¦íÝ{ö•¯‘çÇ ×Òˆq¡%”xyA¦odòÞ»ãý8¸k¡¥‹s©,OøG?³¿ix³ ì¦T€¨?s{r#ùᑇPÝð\Ÿ˜ºñ&*_[\›>–Ùó»,¦LEó \°ùlÈ#ÐEä ŽÍo>Ð7õp­¸Á±êúÌkNg=Dí ‘ˆ÷Í6£Dp<7¨¤Zµgdÿù׿ >Ô7±í‘O}áâ4Z8þ¼ßZܼ¿°taÛÝ<ø«Û#èÝ£åyoñ̉tà®IÚ¿ S|DX–Ù1Š:Çó9ª·h,#>¶1wéúèžû*³ÖÒÆúôéüÞ¯úV1¤MGIèQðAS‘ȈZ—¬.MÛà¶\"‚ V‹95¢6À¡oÙÜÈn†e7–®§º·•¯xvslÿü?ýáÑúµS² ¡Ð–bÂöèÔŽ-ƒ§ßxÉhàÍ;?·~óÂÀö±»>2šîC oÝVDŸ€D‹GÐW˜Ó¯ÎÚVZKdŽýü§Ùá1Ïn7gA§âŸb‚€¦å,\X$ò›b}ƒ…™ÚüYtÞµ©ïP@dÃÂ,fY> hàz`2pÕÐãDH²RÌóDï„ÙÔ›…Z¶[K«à˜Â4È c‚BRÙßÔK·.×óZVŠª©a%)îxpû¶HŽß””¨2‘PP³ í|ÿ­ª¦fŽÿè|§Qô*æZ-ß®ÅÓImìS,C9–õ}sbªojjÏSN³mµWfÞ±ªK„SBÏ AØ8|@›DÖbX9ÃÀeÁ„º„•âãiÝ£˜M®œEÒ²J2Õ7~GqñZŽ#ð 5G·Þ æt@. )ÇÕSã˜ñ6ßy×=ÛUmXù),D8É;K$«-øùFmÕ×+…³¼$»6C„mwÔMãXõó­¶œ´xàY’ÖÝ©–ôÚ2ñ(p1ÀÍ9>d°'ÅzµÌPee†€%Jvk-Ù³UTz0£¬ÞxGé:ü™·ÿî‹j¢6Ÿá×iB—Á0{V AßÅÀ§DÔ`6Cä ±x~tbß#Gn\©ç~ås;€MiðÏP«‚ ‹~eÅð†–‰«éüñŸ^™¾õg9Sþ¨Ïé¸í¦¤¦åTFЧc¥ ×j†Œ‡‚‰Æ‚Ž…ÀiŽ ö{NàÙ>lj,öih(™ ÆåÞaÂBRFÕóš 5iù¶¯¦6µ›«žßaÅD`¶™Ðáy‚ÇË¥k]N"Z¢šïÚßjW…X¬]+j±þÑÍ{qˆ§l¹E!pïfoÿ¬¶Ž‘‚"€§QÚ6ÚD!œÀu²QÆß´J3óA§ž™üt¼g´´pNëÝ©ÄûêœÝX}?ŒpZ&ªÊ`ˆ>Ë1RLi·Ã\ï¶\v¼¾±æ!Æè©oÇS]͹€²Zïdiá½0ôn‹ ‘ËÁxˆñî©sƒãéÜ`áæåÒÒ e,V z§1$Yºy õ§¾ô‰®A;Ô“àç@ˆ ¢˜- "/öXÔñÇ¥³WË…eã¦ÕZ›GN¹wÏ—áo›•ÅØÐ˜Ä¼FÍk—¨kJŒÓ4ØÏlŽ+ª0Œ¹ñ}±±ÑÙ·_’ånAMwÌf§UЀ<Ýl.e7Ìm¹¯¼2×)L‹<¿vá%B¤D,™¸«kÇVq±påL`¢¾±ƒõæE¢:=û¶Ý³kæx!‘híþ@wfôÇç* @XŸuÃVyáÚ» «óK~þªn^­Ïí4×rм<~øO sg1¯Œþ,tQ}ár`€éÃNEׄ­eYì)5°­S.Z­J×ðÞZ­Øim îz"“»yò_·xVH¦æn\S™[ïþÓ趇æO¾ £¥KÀ{†ÀJÃãÙðJW÷<üA€ÅÀåê·ö¾÷¾'r†ÕA ‘ÀÑH¤‚à•ŠÔ—O¡þñÑâÜÒÿdÿ‚4sÒsZdùʤơ{ÿ¤ºt‰ådN”íNì”a"­[õ<ÈV!â0v 'ù ‡=“,&øxwfxÏõ lY™>µxéĉ@;[…+„Á@Á YM`Å$ÂÚÀØÞîž¾î¡a$ [—/êåÅÂü™tÏfèL ‡&ú>öûO´©Âr/ËA«T\ëT{÷ŸÕ––µ»ó¡‘»?}×k?<Z[ܦ¼zrò×}«bÂ0"̺çé ã‚8cÌÓà›eY6öÄ mfÜüØAQë]Ÿ›ÖRòšöÝNmcœ€@þÕ×À‹ívÉwuùÐóPBÚwäº ×i—D‘ú~l|ù ߀ÄÉJŠðZ«tƒÈö¼ðÄ %žFY®²Ø4qüÇço]¸,ó£f³æÛ·îxtÿZY¢Í®ÏÊs'´¡'aÁÂP¼C ˜9"gd­—cÄæúV½ÛôæŠcVHbÞ·B¾ÜÈ^Vޝ^?6°ýpßøÖåk¯7×ç’=ã+Óo¢ÀÙ´e—·Üóù•ó§Ìæ:˜5X° a9Ä¢Ú¥%‡©ã ŽOh=G~ç!,Õe'à Žçµ|?iµÈ{¯s/¡P¬­œeAI(ñî¡XÏ–Õ™fiÕkW´¡r¼„)puLêÈaNÖFövŠ‹j,Ý;ypõÖ…òâÅÀ«„®Çªvç_ˆﮕêŒå½Ò }® æn0°JÌj¥TZQ‡êÅ%€ 0;ÂÉ P OätWÏØÞV ^éé¾ï×öƆn£`¿ˆZ®Q¯–?·qK9õÒ›N«¡eÜ®þ©Ýª7Ðüô‰v¡ÀxJ|äÈO`1å%Ækc`V>éò­uôìàN-;Щ­Y ±¾ãFNŒ ¥+=ñðãÃwgŸyù•& væ'º·—Ï2 ¡ƒ|SzÀqß` –äx`[‚’Â"Iõ·×oRW÷‚æŽ?šî›\»v=ó}ð0•Q¨9J°2‹~ú'ÿœíÚ#¤7òCcñŒ²ïÑàºW¾ÿ¾ç¤â›ŸU{¶·K+¡käñѓٮé•EЮÌÐD%é]ŸÔ¬gZ |½©&²ñt·íwH¼«Y)èå[@i¡o£ ²Ö=<5¸c wü‰¥ùE†4sƒ*òù«'®×7øh«0³zöU؀ꔶ8IQõ•yް¼$1ÏËZ<;hê5ÀÓTvÔ³ MªDXã\/À¬Ìr¼–ÉÇóCíFÑ6`Ò¡ -@útßÖD×®cWy1Àn}jÿþýݘ±’[? Z×?yO«¹¡dNÃn®Å]øV«hÔJÔs /.´zès_»çKãGÿqùè7þpTߨæúê|}£Þµåqµ7[ž=Õ^Y`Î1æˆWrf£ bœê0ëÅÀóYViâ"üÃÀ‡Ð„Q®ÝfÚOMå”tKRíõWÂDn`M=ð‘ÊúÍÊòõƒ®‘;ö•ozøÈ‘Å›ÓɱqDŸÊlÞ|ð7¾ b|æûßiܺ †¬Ü‡â÷m¹+žÌ>öO^_6^ú½_#\N”TQ ;à BLñ¶gèˆ !õAôŽâ¤p€`-¥ÆÓíjP "­Õ*bû¡bÀRÐ ÃhÉ 09 Ú!+ RB5„Xq†ðj~xï£?ù“¿)Ùqð>[o^9ú\*“ÇHê½ã+®m§ÇvÝñ‘Ç6ì7›èßÿòùµsï0Ô4-ÄôŽçîö÷ar§O¼Ö¬.Z3hDT u® Hª8:(Rvp{³º^y'€@iYx!4æÅh‘,¹ÁÐsä à Ç @e \aÆ«2A‘áDˆ»a`©‰Ì–;Ÿ¬V«ÍJilçá[ç_!ÎôõΡ ´› tô±¯¾Qª,lyüÉíäÝšy«úÎÿr ƒÝæòûŽËKp Û¨¶a…*§¨Ðœ '0!D4Àñ!„üÀ¶tÿàÚ­ –e9º\ Wv¢fõv9ô,ðVJƒ•Êa†Ñ`e¸&‹ZÁJà5 ™x)û7°e×½ÿ¨e£7þþ{Ôö™nˆÕ ä?& ®|@ÿ8Ú* ãÖâ¹ÂÕŸ^¨Îm¤‡èA)láÔOÚ¡”^` àŠˆ*!í1§)±~OŽe´‹™ÞI8(† Ê!!ž£.Íž·›ÕÛ·t5™Ï î,­ÌšxØ`¸$õ$¯ÕP3Y!ÁèíåжÀ‡l×Ùúà÷™>}´Z™ÛûágGw'þù¿!rqÐ/½]•㹘6Ð*-5›·ˆÂ>ùíFùƬײy™S2rÿ[n]}oë]÷^yõä…Ÿ}:“ú€ôvòðq• d)BbñtZˤŽüѾü½××/Öø˜^8ÏFJö‰é ¢tÇÒ›®Ÿ|Áo¯c6€ØMO øŠ°HääxO29–í¯­N—OIŠÆay|ïCBn$3¡½ýÜ?qȉ§ú Ÿm—VêR2‘è´7Ôì`nt_mõ:õ:wztç'ž$©º8½õà³Û÷1bcè휞ùÅ߇®hPö3¼}7#ÒRA½"<àžœŸØµýWžyûûÏ3>©ÍÅ~œÂ ©” jVÒº:•e»½ âïûn²w›gwò›¶CÎmÞÁÇsžå·–ça3 ³ç\ßN÷ö[­ÕÌàË7N(ùv[K¤­Vcâ®–o]­¯_‰'’ŽÕ`¥Øþ'~;ž–Þ~ñ;°Œž]Ÿ£Èºê?”ÈMÙ6,Ø_ž~‹å6›"Ö„I‚ãd…¬ ¡À CKJu|z}n¶µ¾@õCîvãåDö5¬ò­éÙ“ÿæÙ§€ˆIÑtv+ …zu!;¶ÛÑí& š¤°`ÿïûv,?²¬^[ëß¼¹ÒÒÐ3Ëh‚8H²’ûÈø=Oî}æãlÚ; ´rúúô¿º¬Ú|¬ëñ¯üå›ßÿv`ê±D.–%•ùfiÝ @{”ÔÀNjÔê·Î²± äGö´ÊóFsCŠg!¶ãáß|÷FýzÖa â=ã!“´; ¹.+ŠXÏ M»Í õ!_$(¬Öh‹<8·ÁR$ÛÿÔWÖn^6šõ\÷æKo|‡c/B”N¤»’ãB·=¢çŽ»üÍ/:&:ñÿŽÏ¿˜kZB“F]Í õ L/ÄØdÒ,)ð˜kböLÞ_ž=‹)ÔµÏõö ô: <Š@=Iflk­àMóèv(Œ+'{ø® 3•ÞnÒ,L‡vÄ-DE2Æ¡$iñt— Åt£f›u˜Éüï.ÜšÁDÒKË©Üh¶§ouö˜ Ký÷ÿ.$SiHvù½F­>wú§Ô4ôâeޱ0kkÙ. kÏ´C…e‘GŠ¡k²Ägy2"Ë%p„~•ú-5žw ÒØ«ã8ˆSBŸ ¨ ¤»ÄxJjwL.¨X­0M&ÇúwÑ]<9%>ò…®aeézõúÙŸõUßm( ŒØŽ¼°·w㵊«—»¹ûsÿ ÃÈójÿ¦ûõ†=sò¹á݆¶í{ë»ÿ]¯,cucÂac…eÁÿ6ƒ)VÉnÌq<è)·ÈE÷hZ¡§ÓÀä 8šÉ‹Õ£QÒtmä 0GŽåCì‘X"¤ÐÛ¼ÓjHûv‹º¸xC)™K$bbz¨gêÀ­so6Wo,z¶î9æÑÑO•o]AŽ©È²Ñ*[F#·û·åtïÄŸ,^»¤×§ï<òÌMüñܵ·_¶›«:Ôt¿ãP×Ò'ï~‹fgcîä«ú6hcÙ.22b–(AàñJÒw q`Ê9˜s‰Ì–N=?Ö;ë™Ä¼”éÞÝ]µËG;¥…Ð ¢þÉõwM=þYËó‹3'[ W¡Ú–Þ6­†œÊÜ–£”ïZN§š˜¬­Î:†‘žú Ã3b2Ëó1äÕZj²W’úV.¿KVÿÔ~NîZ›ïy4?ÚwáÇïnÌôA)CÊò¢œŠ¥&«øÔ6 #«ÙŒe¦Íb»pYT•À*Žñè—Ÿ[¾yuîÌ“}ÛƒTdÕ÷@B"+§ØF³wbìÎgŸ¹y~ÖÑËËg_Á ©d‘Š H$&|¸ç㟿ï×w¼û™÷¾÷Z¢k0ÕÕ[_»Q]¾8‹E^‰ ñtr`GßÄ¡‘Ú¥ãon¿ÿ‚vÉzŸüÎ7;ËKÂ7’½£§¥ºåvõ:p¯’–´ìÄ,΃ÂlØÎ†ªå ö…-q ÏÊ·.‡:Amµ@!¡‹Ï1êüëuYHZ•r§Zpœv£ºÆ j§ºä•ÞÁíµõYÇi=ü…?îߟ³td¶Ÿþï¯gòCÛjlÌûŸÊŒ:†G'ÉØî§~½{,!(ð*»ƒW]wÂ~áèÿY>ù·Æ‹‰0, >ñ[ß--­–N¹vÅsÌ'E1-aBfé4à˜¡­+Zzë¡O\»øŠÙZ¡®APĨHCjÃ~·úŽ yákóa³Eæ…ºª¥‚ÐÓ’04¨Unª±DcÕ–Ê`Ä7Ͼ\ßXö'°a`¼ %{ÌŽÏ @¤ˆM OÞýkÞƒìZGDÁh~ÆJõIï¾zòê«ovV«w¾WIôè+ÿãêÉ÷<}hh+² té(ª¼åç ×ßöLðG:zɵ ß³´1ã1QBÁ‡ú{Ñk‚ QTŽe¸¿)….üŽ€,2>RAH ¾o6¤Â½uj¦|ý|mñBä'ЖEÄŽªÊÃŽaÚ¤òX¾7Xsø3rš ÐTÍó[äÄ¿Ì]zãµfqÖ×K „Ñ“\.¤¡Ö5Ô5¹£g|Ôj,¶_[oíùäµS¯6–OGwƒz6ºãd ü º-@pC¨h€0~”&a)ûçë:'sn´A„²¶e-•»ðjóâËo•nž¡¤QNÇMd‰Åql`uôFs‚˜JÇóý@bÀ Ù‘¤4·Ü{W:?öƒ?øFmi$›õçì ´ƒÿD X>–ÌNîÕ|{eÖk×’½X멬ÌêW8>PÏŒî›Ãçoáèù†¬Á )°?Ǭ†Ô‡æD ’Ð_UBÏuXÈØ~tÃñmøâ›õ³Ïÿ¢¹8Ë¡+bš7k5¬öƺçRÌêXñT˜ 4d‚l~pïá'Òc=|^áeôþë§_ü¶ÑlJP;ªM†&ÎêMéß{Ĩsúêr`bÙ.'tZ•ŒLìÕ¤DOLþcb1føŠ…ÐꞸŸ5ë ¡]!„…ìéèo*¡&!ÁAð{±ŒÎ¿Š‹Þ¹ý/§~ƒCnô’Hœ=CÜÊ"À–l27`™ QQëÍ‚a66Æ\2™›Ø¿óÑÿüÄôÅúô/§;7{æFÛ„½ª!LÀƒ 3áèfDŒS’]“ûóãµçÕâê̛ۨò£‡ð¹CÂK¢š³¬6¤'& Ž¢dÍzÉ×<Ï3,$ô*f‡wj¯/y×÷MHn,Ÿl b4ü‚žÂXc]‚ªvJ³a`BÛ„|–§¢ Åú:¢>Ìxˆ×®!ßÄAt#ójÈ^M…`T è,pmN…—B}×A`@QaoG8škÂvÀY >Cï@b¢É±OƒqS¯2ÂÀÎ'-³ÄàÖgþâk‰Ø%ÊpFècÓPμ2çÖlÚhzˆ«}ãÌ_úqm팬&;¥§]UG£1ÖãYžk5¯æ¶8õµèAˆg±‚äz¾Ù.2¾ƒ>?yžN$K/Ã’ ®z†Žy '¦]ËöŒäök@Áí£ƒøQ×ÁÁŽ]0(>ôt´£ûšHJô´Úe«3ûÔýã{>¹ ì‰HØr ’m`‘C1 ýòytöç/ú¶^_=-Æã`€ze=€8F­øBˆcd° ¿X1Ádž¼ö2µ[‰ô°ç–eÒÏ µ²‰¾íÉÝLô:G§±rÙj•Ë QJºEvCÀâèð±1 @W4Ñ*ðKÎ?éïv.ð€Lx¡Ëw›Éþäùñ·`°X è‚Áñt]xýâÛ?¸fµ=£ HÒÔ=ÏÎ{³±: ¢]rVD¯Þ¹LÔN2§dYìçw¼¼1Îê4l£Î@›:ú®'¾2y÷‘c?úžY]`èêµ z øAô"Ñç¢Í8A ,øŸèe)ð¬ruô ®É‹‰fòH\lÆî>øà'¿¼ã‰'y‘yÑ›XÒN¼rñÂëúÆü[É|>?¸µS..\øesn·YNr çÓhgáø`~|"'(éM{>¬×Š«W…éÍ §]£`‘ë‘“£5 ¼À[b1(3¸&G(\°‹“Ò]€§ÑØ",>€Yj–Ï;w~ö'pÙ3/µŠ¡¤¼’ÞûÔèÎ=r¬¾÷þÁHŒÀéaý2aÏ5ÔÚ@¯ïÌÚÕ³¡ë¨±ÜêµV§´±Ž‰à†s‰DšÞîQ2=¼Ü“êÚZœ;gê«Ý“wVW®· 7ÙÈq©(ÇkGy)UÙr`¹ÈÛPÝâ çr›ØíRkuä 3~È6ŒÎú Óüî/ ŠÝ,p‚;àúŽ £[FŸþâcXƒhcJ ‘®YÓï_b=Ùlú7Þù…"§¬ÖJ£8 ]èG/¨DïÂÁ) ±£÷€£×ï°(kjb„çRësg9YÌMîj–KsÑ%d²"ØèmrÃ<ˆƒÞ ·ýþáá:@£$úAȱäÖ¡÷îùÐï\xûç7Î:õåÀm‚ ü@xœmZûwÅ•®[Ý=/ÍŒF3#i$Kèaû°„ÀÂrÎþºÂþ§»'$ŽMlã¶±؃mصq,Y²ÝU¹Ïê'ƒ‘43ÕU·îã»ß½UíVÛEp¢÷!:¨‚(b¬2\ÄWøµsø)þ h§ð;þ…ãçþé!ÃñÎáç8£zù°Ü{œ¹Ê“ꮪA^ämPAhrÔBæ³J*OÊË€'æ-@ ¢óH;¦ýåYŸïWåç¢ãhúµ%2´‹ãšŽBJ£=¾è ¦«½nüöÏ·!ï·»ÓX¾ˆå~ UÄM\í?Ë:‹$?Z?;2}…= ê8´¸ÈE2T²€ÆÀÕi¨“ÁI­ìB £üÞ“¥"»,oJL$ÓâÏV«?ž®Ì;þúàåþ>@|ãq–yôeðy[8ĵªæOÿ{8ØÍâÑáÎÃxü²*_á .!RÄ$ª¸…Ú™Q(8þÉJ$5ª (t¼sêCªÿK~ЋŽÔ`ü»ÕdzÙÊ_>Øyñ³‡<@ž]Ôy,<™ž$CñÑì½é»¸Luð,–»B(%ÐH9dšÓc$R\Ë&Äæ*?»†ŠÁ&ˆb;ÕÏØ9Ì‚@û¦½8-{~®ÝêàzýÑî˽—Ï#ƒF·¿ÂAùêgÜ?ª=ðÔ9`¼tD’èÑF4ë?Ñ ;/œR›4äò< 8s³d2q4 ÙjCý NÖ°wy^ £ù…Ùÿ=ýio÷9@ÓÞÉ·cU‘.=¿:Y‘ìK a"Q óÄKqûA¡e Iÿ Ö`¹ƒÄ8¹ ÎT*Á°hÊÁÌóEGà‹vg:­o¼þã?<~ô…±ÄÈÅ)<ê׫c°¡“wI<ßh°¡ú §’'Á~Bÿ™ AT~Mv™¨ó)5Œ!’³óÛÖÙDbŒ,oÍ æ‡£…ñt åÞÝ+Uy$àÀ±£Þ¦K;×íLŽË}Ü}GGHJU,万órACÉ !Y%Î WP(Í•T-‘¥5‚„ Ÿ!:µ:Ý^o0Xž­»½/>ÿ#ꟖàÀ÷dÛ ÂãCø¾Ó#ÅpÌ®àUÈ:âTcÑå5"›@¤oLÅNÂSžRgø’oyËÞçZâ©Uç3Jmè>½Áp¼¼²XdåÝÛ7ŽŽÀ·ñŸ‹¥«)×z_–•ÌÖn÷e«’ñ’˜L|ñ“hyÞóû`Gý%m“•·Ð¥Ì&>Œ®.ÉOöô¤; œ=²Nw8?ZôÛEqüàÏ_—Ò²ï’hÕ~æi™Šgi] oŽ"A—Äsαvƒ˜dæÄüá¹ÓX€F8z;hÐ#A‘àÊ¢…¤¨h€öõ½îp<ž-ŒGY^Þ¼y™“Há}·Õî¾Gܧb>‚†(ò.3¬2`àðÖlb‡Ÿš¥Ê˜BÄBQs·g÷Oˆi‰Œé甊æTù ìŒEñ;|ßi÷Æ“¥þ°ßíw¾úÁ’ø$þ£ùKV5 É:Éóf1ôŠŒ`VC h€`’j•ŒR €\ñ0¯©Ÿ®¼ ™r€1ƒæ™bg–_£˜#.JlzL]‹K³ùQ¿g7®_%©p0ÒRC)AEI5´Š9¤hÎkàj'ÌÃÄ -âØq „R¨^=i rvfPžu5·qæT3BZ ’'çMIüŠùˆŸë¦³åA/ôºW¯^)+̪-¤íDhEWsDwc+oàW&]4ÆÂzn€- œiTÕ“‚Ü”ÄhXšÆ€Pÿ9p(7üÕ‹Àüd¶RíŸZ}ïöÞá…š’fÂä«Þe-Ì¿–À (ê4éX\‹Ã³'kdgYQV%º´ð‰œE™„2gÙl5ÔÌ·¸‰,?û, …XÞhqy®×^žŸ¿~ýòÁÑ"ž¤<œÐ«Óá'í¼™y3ôqjŽ 7É*†˜”þA»h—¡¬ªÒ+¥ Ì@œòìè³hÀ'[™‰~L&G—öy»;š¬ ç‡ë³¥/.}¼ÿj/å yš— ‚hä?^‹kVd©ÇJÅHUÌöWy8H0ƒ¨H+3gÎ(ÂÙLÆ~D~pŠ"<ÅoVtF“Ê¿½¾þùÅó/÷vªV(²(6óBW‰"P iYÚ’S{¦»>÷#Çö^#aÇ3a–Ì.¨^…[9Ô¶@bŸØ-«“4€b´¾¶õúp0·²4¹øÙ…Ýš, H¬ùŒ[^X±§©'ćó þ‚…¤$ §À"ò{N»âÏ,u i’ØxW A¢'B`HÌ1¬VW7ÆãѩեOþt~gw×K)ÍL–`ùcžµ\ʶµÇ(ƒZoÞhQ gi9h%KC$(¤TßIâK²d O‹¬g¬ ©."@ŒXVX“ª¿&“ÕV'__›Ý¼umçÅ ,œ¹A½@À²•µ…'j5jžk‰VüÜkT³V)DSa’ ”cD_o­6:˜™¨Á“ò—®J‘'BJÓ™LÖÆó믭^¹òé³gOAü¸Ž,ótäÏY[0:Z¹ç,ÿÖ;­CU Õ+Àª/i%¹%Ò$¨ÑY(‚“gÚ†d¹0[K8zIDÔöh´´uæìé­µ ~÷ãÿkò[Ý!53+¯åê¨:ÙÇ„–J£åƒ¥FEŸRºnU%åmÆ7À˜ ­K]#_ض€y´™ð«|8šžÙ>»¶6¹rùÒã'ßÍ8YFè ä?¹³SÇÐp³šš3ÖÕÔŽ}IèË çd,ÂTAœã—B Ó'(wàä•TÚ ÞÚØÜX_þöÞíÛîa¨¦˜(AeWˆmSF;y…vÒKÒÎSbÚp Ð?Ô PóüæQ’óQžÊ ……å­­­µå…'ßýõËÛ×%{*D¨9<Éßrõ~R¸q–ãÂ0H½(½ÃÇæŽÀrkM¤ØH<,ƒTOx !ÉØ<Õ2 Ï}-b›½Þpcc{yyòóO?ܺsÓ¥n©Ó/5;¾EùEr/šKs/Êà"IjiW…‰Öä $ FŠHf½M“Ÿüku¯ÞƱ‰áN{n}ó æýÝçO?¤Ù8¡r5Ûâ§ô-c-¥Òþ¹“?÷Öò1ùUÿZ¸I{ÓYã…I¦¦MHÌZò—O-•’?2y$¼E~¡Ým·²ìÉwÿSVÇ5”¦¶1å6ÊÏ TÑ:y1A1kÛ‚²îÅjFÃ2u`Ák®´Ô’¢Œú0é_Ðôï ó|JŠ9´±*l F «››mço\»T•Ǥõã W¼ð3%³ä%.±-ŸöÛˆbR*m¸„‰p¾™ÿ„~ SvjróÁO*Ôp ¶RÅE*oónw´qæìpÔjywé³OËãcR „:ÙJ-jY@b‰ ¿Õ öUâ5+åözˆ¿@'m…‚(¥~jHfÚ$?1"Mä«¢½ÞÂúÖ™é´ÕñåÏ/žèXFíCFêæ©IîSPê^b¯Ùª†×ú /QfÝxÐp‰)kL1W/b{Æ»HÍ—u»Ãµ×NO§ÃÑ wîÜïôG°ægP6ò,y’üS³˜´ˆkœaW¦aÉÍiÃ(&'L­ä” °V÷Ë}–1‹ƒe«" øN§ÿÚæÙÉd0 ÏŸ?·»·£]>{ÜPåo;]³¦µ¯'Ú¢Î8¨ð’œ¥Wë#£É^ΠOŒÂ’#¯m.‹#ßi÷77ÏŽ§ƒÙòâï?|ç厧¬m[Ð~&ÍHùKË…'§>êþáKÙ¦¶P\OÙ‡n&&Ö“:õF ¨[èÕǤ=Ãã7@·3Xž­-®N7×ÖûÛÿØÛIpQ3kkåšLŸ`žÐ0€‰SÅ ID>³R×ÈFlÀˆ\óèdSVñ‡Ô5 Ö?V…Së§ãáök›<÷ÁÎÎsávR L“æmd\kwÇÆRÌJƒëqrcBõÚr·$-ÎS¡ìñ3é%r~Ò?¸VÑ[ZZ-Ž6·6/ýéܳgÿϧfÊ“‹$þf.Ñp~s•ZEtvଽ¢¸ÞºÍÔ©I«ù„QIÂ7—‰½œàs-v&,çWÖ×Ξ9ýÉÞöü©³XaœIIÌßR¿3Éog$®IÕ@ºH•4c“Ö“‹«“‡0p×-ð±’„¯W ð#ÁUÜùÃÚ OVV76Þyë×ç?úÍãï¿Ãø ig%jŒ%qN(\ ¦÷hº>k¹Õió3ô´±‘Ä]ÊbœÝÔ?9ãÐawv Ëý”\ç««§'³¥íÍÿ¾{ýöý¯Ø³ÆvÒWAE7 –œEb4»¸ä8>¡¾õeDÉ Rš­ƒCÙ¬Šb$>ÂðÂOT|›6têÔÙ…éâ©å¥xøêÜ'†X‡”)ÕàgòH_×Íæ \cé¨D°¨ÔÌV—Êæû–Y 1ÊPP댳¤zä£F*–×&Óí­M(?:ÿ~UUfSPàb9Õ/Úü¨ín‹ëõãÁ‹ßpÆ”OìVÉüß òE~ʱþ3=ªÔƒOîEð·ƒÁxn®ÿÞ{ï=}úä‹Ë%g¥[h@Ý¢¼‘o¢õ(›ú?‘Ì¢ep0ê›–µ¼eccÔÆWB`éÓÖ@N8vE~ö¡RoÙêaoƒzcè Ö5òãuÚDùœÑØ`@¥æŠàSO’ôOèy™tøŽeáPµÛs½¹ÁúÆF ʫ׾íLCdàk.÷­$´6™|Rä”ËÒȆbxŠs"Ày=^L–r`Õ˜…«”Ìÿ³œYH¯@°€Š+:pwívo0?yãŸ^/|uáÂG¬²œ„Ö‰Zå¾#Pq²`±Ë*TÀtµŽS_ ¤å¤ç IZ§s*Vƒ5(èAÎA20KM·¶€:œB0*i "…› ›Ì/ûç>þŸâen‰0ŠIÿªxÍlÖØ19½ù¾JۤĪ On»¥TR·~á™Q<’ó/ŸÅgNóÊ0ÕV¡Õž›Lf,zù•//s‹#آ܄ôIý¥%l]XQ™?å½Dë“$E;c& NÇ–‰©èÑ9SØÓ8)!½Âgm´§Ñí Çã¥éâdk}å¿>øOtãæ¡P2ºÊoO¦(æÆ†4»C/Ø4Áú§^íèùP0Z‰Z(±Eh„Uí·r"ìµ…"7î¸ËÑ‹¯^o8bž¾qöô¿ûÍÞþžvlÌÐò—à‚{íS»tÒŸPPó]´Û'ð ùiU gË€³Cëщõ+*<÷ôR\ÅÑq1´Zݹþpqivz{ëãóîíïóE嬱 [ þ’Öí.‘ƒÆ¡¶……ôm•uÔÍUgwpÔšÞ7û‰ »rXÀ×·€Zˆb>‡Â¯ZE;ouÿ·¶6.~zag÷…¸ðÆXËüj•'ÂâÒHÙe c°ÍަKGKr‡Rÿ $؃M®#ÀN¸!'æ ]-Cåyk4šÎNoo^½zñé³§ Ç( u†B¨ÿ\/†»ÙÙº¼§Ä£ƒC„ÚŸPïœ>H™'Áë¤OÈÑÞ/õ$ùЇå—Q¢ŽnH’”ȆýqwÐ{÷í·oÞ¸òðñC#É¢ˆ( CòKû¤†K íSqHè“:i*w]¦ÁÕ¥Ÿ+dÑÙõ9;¾¯Ènc攢ÌZÃÞe-Œ—§“Ù;ïþóµ+ŸÜÿæ&k“„êø@Î÷X4%ÓHä%bšz%Þýùùƒ^ZŠ–ø¢ù!ǯz„$%@´öƒ«=“Î GóÓÙl}{kûÁ½ë÷¿¹Ëò«k1·þaòÌ WÁ«˜b3uÒ”¬Úiý‰@cTϦA.I¦ŒâµqJ§ðrægÑí©¦>g…¦Ìͧ³7Þxûá·wîÜ»AòkïTÕ'øiõ…KhiQàìÞ‘©¼\çŽÑò®Ú,y9+ŒbŠ»£”ôS—˜'Ëoþê×ß?úæÊÍÏÄx”芮ýƒ#²xœuZ[¬]×U]¯½÷yݧ¯¯×ÎËqÒ$MâRµ4JÕT ©U‰D‘*!>A©?ˆ¢ˆª_üQAûAK>úZP›ªÓµ$±'qâÄŽûð}žsöÙ¯µ˜µÖÞ§'rî=gŸµæšsÌ1Æ\'Y6’ª§MÖÔSk]:¼S/=4X=;¾ùÝj|Ë =Z¼¬\1ÙI–ï¨ÊÊîüäØƒŸ=Èsi²^½sðÆ¿eZ8'j+Òáɺ.’Þ1Ù;Yëõõ§þÔ-Ÿ–EåÊY¹÷f¾u),öWÎV³Ãf²%ÊÃr|°x×S¶·j—úƒl￟߼øåÞ «¦×=sM®“a¶þXzdzK÷fòæ×÷_ùY씳#)°Kc mÄháxÓÔJ'RêY>ÒÈtE%ËΖ®žHWZaN|àÓ…]8þàÓ[o¾0~õŸëÎj·´ñàøÝä[/)Q ×À… ÕOz‹uyØ®»dA÷6ÔÒãùí¼:šl¾šÈ4[X«`e;¼s±\”S!t6<[4ƒìܳýÈß|¾Ø½4X}øÄ¯~qó—˜fzš¦½[—¿}üî§OûЫßÿÛdé× †K•Kç†îêîϾ\ì_Q˜®­yæîß|îÚåK‰ØßùÞdySºI¢œM– ¬³RIá ÷Àãd"“…áê¹éþÛFU‘CNdzæØ#ŸIrðòsƒ³ \þ†eck³|>[½oüöw†ƒ%çÆuqhëÒôÖOÿÊÌ–?4»þͽŸ~¥—å`ãÄS_T';¼ò­Q&³ï¾øµltBÚ|ºû?k÷~biõüµ¿6¸ûéɵoÚéÒN„«´˜l¥½¥{žÉK=Û¿•ÈIb·g{¯ºz,äà de´2Rˆª®uo¥C“Ž\±©ÜQÝÔ¬Ÿ¸ðGÓ&ËÞ .­,Þüá_Ùé -…umj.Bù‹Ã¢_W®„<Èlµ‘˶k9V9³üÁgë…Žn]9óðÓrróÚÿqížß¿T¯æ{WD]èl¡*JagRVZZ­„¤?°¨6#Ó?iå‚PÚï×9”ž´ØZx´P0Ýœ|LÏOo½\_õœÎÊ¡Ý?:ó±²i²§T±¹ýã/»rKó™¸zyùÔ¤˜¤kQAÕÀH ™­%‹w9 ½¶E9uï'Ôz^¥:µîèf¹cñìGŸ}àúý]=~×6Uoåîáêùƒ­«@}Õäz"³•°”ƒ®„õT²$Tjë1r£h„½¬ï¤Æ7•P*iôp탟«fjöþEYÜ(¦Ûðqë¤iºp20+³{í/fùþîKÿ’ßøŽÍßÇ"@"@T–ô7Šéf YNôïi ª¡žn¿$TfA-ÜwìÑßÙy÷b–f‡ïþÔ NWÓ÷´8b´VõV¦Wç[ÃÅádóRSaf!áÎ p I/'ºZà—&=ØŽ~–P+ûfx¦šÜ–.ת¶uâÑé7€Vôws±ì&ïÚ­Íö^ƒHqe¡Lö²·Ñ?qaxüüd÷½rr`ÔöáµÿÔ¢€^¡TÙ‰ÑéŽÇ‡£µÞºtöƒŸ¹ñÊW{£!ôš}Ý;­U>Û»ìª=|Ónµ6ÖV€R!±¿†íè_‘&}< D¯ zuÝàa\“õ†e9««Ü½ÚU±µÐKMe¥NDs ¨Œ…ò8\E¥ƒ½¥sy>=vïÇ•ì¿÷Ò7´Ú³Å®Â Kõ!H'ÙÊ…tåу›?X»ëâ9Ü~ã?Ì2ðêºlJ9¾R϶¡7T" ôzª©rB äÿxIsÀŸø»R X LÔๅ†’IL‰ÿ3aŒ2¦š•I²(̰,„-üÖ×a©A‡MÓ8at <¿(êÍÙd"!p‚ÞrotvV$ÇøÜí÷/ 7QÍ$ß}kùÎ5Õþdû{xUi\b€¼¯Cò…¥à% ÿU ñg)ò§Ã£ág”Äb0m! X ßvÈ4ÞKà|¦¡KVúëP²žn¾ÒÌnSŸ©ÊŽ[‘5åm@p¹­g°µÐй¨œ5[¸?ŸN7žüÂÁ;ߟ\û’¹²U}¤ðÓþp¥Êwšj¬(ßN%Ѓû´D¯ì‹x(ˆÔ+K§Ã¾€g°xn<'t´#"ðWa!v@ ¬4ÉZýÁÙÞµzrCÔcàj|FéÆõÒå Kw~*ßýY3¹ZÞ‚ø¥-¼JeÐNcf½µ¼Húw<“®Ýµûâ_ ^«–IOê´*a5¶ÅUÑ ¡³ƒÁ\}„»püt„ĤܿȳÔRkœ@Kƒ’”TÇ-¡¥$á?s6OáÛ5x\0Y?û‘?.j»óêWØ“u>GÕ@oø®Î£®Î4E“‰ÁùÅ«Þ}-¿þ-iÇp0ÓÔ³#~X JÎÍ%UЉ­§À$ ã1ÈÎŒÌ?6:&]R+Ó1,VÃ*Œ@–I J¨È`´4Þß”ðp=ÀÓá |¸nºì²þúùþ[ÍÑëÒõŒ(¡û¤B—kú¦7ª Iå°I€>ŸÜøÄ_îo^­·Tnþ¨8¸ÚT¨C€\3Ùrãj[Ùê€êK1ƒÍé-Ί)H(Æ/©›! ËyFúŒ5xtκ˜ÜCÝõV«Û¯k7£n1¼…~Àƒ!ɈD¬•¬(ˆþ–ÀZŽ×‚öy#€šª²ÙÒCÙú‡­^:uî¾·_ø³&¿(¢fL‡«Z½fgÛõôõ¦Üs”Ä* 2)æLØÄd/½BëX2^H>–ðà1RgÈD}¤E/Âh€¯9,4¯)'Ho»å­$,͈eu£â.–e¶>ß6Ù‚¨·\µXÀ‚&£Õ P é>XÍ}Å )ÊŽ­‹CA2­`vD§(݃E¥A&$õ‘^Ȧs2EBkf“fýsxʼnÀŸ±¨ð7Â–Ú {œj$<3ËD¨‘‚ÌT;à|4>†xñ <9›¼ãš‰Æ@â :.[¥Ø^ ñÓÆ˜4Ú’þÆMð’:‰Ô¡3^Û3›îC-²…“U>®¦·¡=ýxL'}`ø#‚’›iÀ7Õ[†4I©þ`´>lB‡R Âv‰Ôº2ŠÀŠ!qCm°‰©)ÿÒ‚Ìðb,/’¡ q#Ëí€äCÇcª„4娫¢`œ``ˆHZGxjãÌø_‘‘­e BûM…š:÷‹IM°€¢ƒW§jâ¨BFp‚i2¦Ž+:‚-ñ’!ƆvD cÕ’»I2~m `㣀o G…p¾Ñœ'a: ÏïÑ‹›‚ÿ¡ã[ZŒŒ"ë/všÀøzdðv?¢ˆjäßø!€vʸ½£ ~Xzåb‡ŽÏ¬L¶E9’rß&è\]ðŽÍ(£yì ¦,âx[a:š&¤V€Jb©…9‚c]Ã,¢ùцk±ôÒž´ËÁFžJE:†š+ªóµQñƒ¼ÿÌÈ¢L'`ÕãÀ‹ù"IR^’J‘ ›%¼s¢=.ÁQ¿8ÅÌkxŸi}~èQŸÃ' >¦Š† ÷ )¾@¾ïÈüƒ¦«4^–q‹\¢³þü2¼/ñ¶Agžýr~ÉÙáúP˜]lOfCï?¸¸JÊ9› >Ð Ž„£”Lhü°ñ¼-kQ‰4A1é|Kbá gkœL zfê ñsÐþ|Ry!cIp±Ä"PGÃLåÃ3B’=AYëDèäÒ«`Ý©¤kô€ Ë;ªoƒc»:ôbàâÀHKbr3´.Sº›ñ ˸0ÚD™´ÂôØ´5>à…JðÏ^8¬ˆõÆ1*´¡ "ÀŠI#H¨*^?Ñ*ìõqåiÊã"î ¼f^ÒóFe­õ-À‰ò(® hɨ‡D Û<õÅO#$@ŽäžL²µ@­ŒJ×ú²“æh(®Í‰üÿ_ž¡Êº€?/;ÔDœCOÂÜAi…©&ƒ˜­øÉ„øßñ0)ÚÙž€ dÑ-­ϧãÙtBµ €ðÓk‡·4þ Ñ䨱{nTU.D¬šO¨ <©OøÞ ì'B£‡vq­_ŠuàÿýðîmŒ ìŒ/YZ -ëƒðùI‰¹WDÉQÆù2ð™óŽÀoê_týUë „†Ó2xyåÙÜ6Šþ`LJ?*b~KÓŠdb¹âìñÚÙ MÑáX6dr0w¬^<-7 yÁ€§mS;oõŸ^•‚âA þ!X*P!Yµ]ˆŸ7R¢Ó"ðI°[±¸2¦Ûw‡k;×£]z}÷ÉÃí¬æ„\¥w¡¡Gº²ØÙc™­~Ô,î/ë{ÁyR’mÒü©œ 'jëíZûœOšðÝæAÅÛr„¡¯ÂÚ±\®­[·’€Ÿ>¿âã ‚ËëZÆ'±}+=‘4bƒ!gp¶í¯ 謵2ðŠO·¼ß‚qËã¶‹»ÄSø]ÚÂÒK&é‡[Kºeó‘ø¦ó‰õö…$)’$¯¡ü€ˆˆSÑÙ'ºe’á%¬Ó¾X°X#|…tøàÙL{Ö ø·~ÐËÉ# 7ÔVtÚïm+MÒO¹$ÄóÝ/#¤ëb²e&nâ²åŠð¢'ŽÐÉú7ø^Ê^Ëló:‡#yt:…-¾®¬ ´h_ö0M’O×M*^ߨ ÊÔÑøµ¬×æR…73°~MëáU¹Ö™ †Ù§ÌTãï{…jí£…3âSáÇ΀p¾MðÃ1b]ZBú-዆7#xy DU•ìYÈØ óíf¼­Eýmxø€øù"(†Œdƒª¦¡Nü|O×R7™ê 6êÿA4[ÆåGT˜èhØ¡©›Þ {fWÝ!MÁÜ<;áâU†è>&=/(ÛÎo„$>gÏ-c""è[êsƒ¥¿C`_n8è®ç[Ás´ODìG1'¾˜š,ve^dø m¬ð ÉóxW‚%¢ùKt 8gy<¹KN¾§}&:R.o¡BwwG1bÇ AEItâU¶s²È>.¸zÄñ×Ä"¨zwµÈC­wð;FÃçÂs¡SüE(?çt’à—\-íû½ÃxÇ˨NêÈÿ pak ÔÕ&ámC¼òqÕNÍŸ ¦ŽsÁitÕ§Y4™|Èkú>9 Áó[t•J¹6;¿jG‚i€?©R1Z%]è_/šøzÁò(DñG^Á-·Vt̼wÚAýu„‰R"^ý…çãšÚ¬j oÍÿuœÿpiæ…ƒç,ºš£»qîjxDà‹)Î2¿î½tÔ=I#Cëx™ˆÚêQPÞð„ëj-üÎ kM8¸ŒâG­WôŸaáV%ç$/LèLG4N[ÿzP×y¨‹ †VD,´m01vì„bz þ6¢~X?[‚ó»å;³ ðÕ!vtdŸ–Q\'„(Ä<Ùh6:Ò9B»¨ŒE’!ô„ò íŠ{ËÄa•ï°âøõʱ1F—Å„Þ 8m]œl¯é¸2.:.yÚÍæï:™íœ$Ì-^;§ Sj»†Ç+êâÇÃ0°9:BR–¹/«?>… bBs‘F]ˆDÄ™±Ã‡suð Æž‰¯û`ÂÁøÉnüÌŽâå9›¾DRatsê. z€#sT—&"@:ïÏF¶µ.àQÆ‘–j–¯klÌMZcóÀ †æwÇȇ @J@Äy q¥¡½®xÀÝr·Ý!ãòs%ðŸ’á[¯Sþ€¾ —“¢Uɶµ<§qþã¢D¤Äœš h}§û‹RÆøçÆjI0ó¬1×¾sÚÄ… œ&ø2ÙkÏ·^cs8™â÷_Â_ôµ×-ôE†ÿŸ%FZ“Úí8+ÚÉpr.ámó’¥÷#§ ª”5ü¿\j9üÊ~æûÉðœ_2Eÿ#ƒÛm;Òcž…E{4/Óxù¾«¥ÝØ®sâ÷UèøWN­¿â¤Áà’ô…ˆóSØ*Ã÷‡a϶0AêZ¡êÐÁüU„ß½ ñ.绹ßÚGÂìà_'²ðhåež™ãD¢uÒýÚÅÍ5b$->B+ÐJ¶î½å¸6ÎrŸ‰ÿ|ÔnÁêC¯ÒPfå„ä´ŸŽ¹DÚÔ* /Ådz³à—G~«9£ ó È'Þ]ðfsÁt+#ƒdÇn“½¸ØŒÞN¶gh—'ÿæ\Wãüm‚jI5²'ôù»,Ù¡òNsµ[t-Ǽð}N{Qàü¢èëÿùÉã81=:øý¢Ùrz¸ê®Ø‘+¶ïÑ!tñÿsñËî—çÕ9xÅßç Éïâý›ó×¼Œ _‡¹PŠ8uÄ8Ù«8´n¹EG7÷…Zwûðb·ôþP{ÁéŽÀž&]ðYÿ (km]xœmZkŒ$×U¾¯zôsºgw;;»Þõf½‰ßŽí9 AEQì!‘øCþ€„",¡ð åŠD$‹ü@HEBA‚ã ¼ ›—ë]{×ëõììÌt÷twUÝ{9{«j[ÖìLwÕ­sÏùÎw¾sn6ï›î^’ÒK™:—{_ )¼Wþ‘>”RKi”̬tÞ•R8 W ¸ ÿ†+¤PB*ï…ð9ÿ°ÜÿJú~•Êôº'pù¹ó¾ô¿¶ó7²ÁVås‘®e£‡³ãÇËêúÚ}¿6¹òüâõïOœ[9y×KÿùÅÎpm±sÑäôûôúËÕÞÿÙù«ù`Ý– gNGZ¯xWTËçRi4,{èñ· „Ò´G´ÜV ß¡Qh«gËñ'^ ßÐÖØf÷*Ü”÷Z¥Ö'—Å¡Ò—Ùæè®Oÿrw5“ÉRõF7.~súâ3‹kßôåDè\j£”¶ó7»k÷÷ÖîÊýÝ—¿–÷Æ`¼ÆdëÞg®š¹jOøR*ô—µE´Š,•h¥tJÞö‰ÎÊâmÆxUèjø ®‚o…Ç_1R`º†+À^Ø+¬«…JtwYÎá;/33|ûú;Ÿ¬Òñ±»ß],Ež:­g•3Öwö.>½¸üÌüÆD²’ŒÎ޶ïš\~®šínÞû‘üÄÙ×~ôoy>²à;ÝUº_-çà^Ø¥p ­¼­Ê 6–¯a¾š¸ò@xK± ¢²|PÎ÷ªr&ÑdálEÆã>½§½€÷Á^'ú6áºÆ¤I'í¼Îæ Ûß|Ô¬Ü=[g?üdi…Âè¥ øI¥™OLҙϫÙdïØ©Sû?ùúëßû‡ùÁåÛ>ò½»îIÓ±P©TiU-µî9»ðvª|‰nîŸ×£{Dµo÷l×l„b@6Âs´w•ıà}v¼§ÑÂO^‰ÿ:Š…g‚c¤:Ÿ¥Ý“&]ñ*Í6ÜzïïÊ~.DÒ2¶˜Kcd’Ìvæ~9¿ñí/^ú*¸nã¿sü‘Ùàf(¤Á5Ám*`FTàJ¡òüØ£²wΗ7–o>ëË]²A*Ð.J_AH“”ðLK¹¢Áïô']#,^OÀÃã^ç«ý­÷$óרdéÉ7:~ÿ§:›[øA'³pq"`NyãÚõç¾(}¹õÐ'6\ÌKcº`8,N8÷!ÊÁÀ´»zßr1MŒ*f¯8wI…‚ ÐÕhŸ†L7΂W!)€š …Q€ïJ{®,{¸€s•Ÿt€©j_úG§†[;¹z8ySå]=<1¹µ³þà'§ÎJ5D_ZL•p –Ú'½ž8œˆÂÏìþ•ç¿<¿zQ›œ¬Rq ŽL§LòÄ[K< îµÁÿx§ %¿ÃÏd˜­>Ò=õA­'o|믌rÎ`Ò[‡,rË[‚ÊëÍ»?•®Þyó•oØéËÕìM /e6öf°vïo n{(o»¬ãÁT•H»”"ã(hWj K¥HÁ1{?þ«ÿú9¿xCúŠì§”µýldD1a€vx¨pS¼GLØ S‘–mÜû™ìößXì]Þ}þ/ËÝïj,"¸²zº?ìݼ|8ÛOú[•TK0Oøå ­JX¨ò]Ãí÷¿yå…¤¿qúÑ_Ç.>Eâ—é%¸ÂdÊŠ ØV«¥ÅtþÊ?>¹|õß•,€ãÁ~¨Mœtž)¡¼-Œ $ !¼Dk1¤¸G´é`‚k½`ÈüÜÊ™¿þt±ó-<£ŒÒ¹ÖÙÙ ݼñ2lhÚë§Æ:eæ°˜\BfkÉøÁ墔¦sæç¯öÁ c„ I1(µH•0‹%Ôå 8¦|ñÒþþ£ÂMºã7‚€Æ{QgdÕð«[â%¸A¢GÚ)n éŠNH–ËÃlåL¹Øñ* ˆxî+ÒÄTÖÊdÜß~ß±Ó\ú¯Ï‹bG+ N™õGõú»ÒÑ…Í;Þ-Rg%¢“_RjBYN…ª”¦åþ|ÿê‹·~ò/ÕôòøÌÝËéë‰é²¯ñ'G¡A’:Ê £ºBFAÀÿDiD–fXÁÅùh§Ú¡Ó-„CkàsàéQ28±˜ÜðË}--¦éTz¸õØ»÷“v)tŸžN©öÊÓO·^¾íþÍö¯˜Áh~°œïî¤ýƒótO¯-ö^x51âl,ôDxRñB,£TT>¦ƒ"°E>çÄA¨³Ò|!©G®‘D±¸2Ô, *ÏÃ;Ph'^OÉÒñ>?ú±?Ÿg³n¾¢o½öì|±7¿ö]W€yºwöø½¿™¬Ü¶ýðI6®»/&fˆž#l ûX7xNÄ ‚­R„4ì÷è&´>6Õâ[ë”…„@Ï ü‰'°}gK,ÁX"”- J§F§>ðgÉù_ºúõÏéªý—U5­&¯Vó4FÿöñŸ|Ïo«~UóæO¿½óÂssi:V:”APß5X¿“™Xî}Èh%‚Ù*f‰ q¢€{à‰4@)÷Pá&p y_†¸úPëô)aWÉtíÌûþPŸýÕîxu±ûâÞ ß9xå›ý^wòÚsÂÒ|ã‘·=þ§‡“ÉOþîÓ¢ØÇ/~víÎG“´¯HZ.^²y”§Žk”2Ú)}H*ª{øB²Zàuøò€Ç 9/BͰ¤ñØ2FwÔbT¾6¼íý³™Ýñèí}úÊóß>|ãòæö©›ßû›[—¾®òñèÂÕðîjqP]ûïùÕgMÖ·^˜¤‹ éùA„jPôÁMªI®¶2”t¶@.$E ß录år‚#àHB”oêSD¨™%¥ý—’õ¹îëtÓz5<÷ g?øGóÙ²›¨¾ò™Ã«Ï\!÷Ù™õ‡ÿì{?öüSO/Í "ª$é°-äk‰EVR*“ad8u1 æe-Í$ŸžÑâ &)¥{E=\a«½ML`¬Ÿ€tW\Uz»`ðf¬òÓéøžªœêáöí}nçù/M~úT±÷%t%=öHÿÂ7¾ÿ”›¾”d¹´{¶¸•&]GÚK°bo°!¹ÆÒçäà W Y*ºr%WºGÙ^: Vƒü‹‡Ä'Èí÷ 7MÜ åϦÐR ·~ôŽ'Êr¥œ¿ÖÛ¸ïôý}é+0{õŸD¹úÙg§ÔøçÒµ²µíýÕM_1bo¹÷#ÒoÞG\ ‹ËË›$M£¦¸`kf‰ûAxg°ì¡`G~éì!—6D î«0ˆ‰“ز Ø ÓßÎÆV/|üø™wv†[/=ó·»?ü’/® 7“¦'ºoË·~åøŸèŒÝøŸ/wÒd%;üáWÿÄ`ýª­uQ8p“¢° ö»²y2TЙºC¿;ÎÀlêÒ’ô ‹CV­mî’¸qLªÐV…JŽg£s€»âà’ôséðФ³¹úö–j|χ>ûêÿþó•羘M³›ÿŸ Ê}(» x …tMê?¹¢ˆ¨èaæ?îÊ!+[-‰´íHÑ5² ¢ Ò/²‚ÆD0) Ôò”X’t×Ëåä8sPçiï„ÎóÉ5oKWΈ[pޝÐM&£àFÉ€è€Õ”󥧺ÃO'pÙ{LØ´)ÁŒ·¢î؆–™àM ¬bæú tƒ¡ÑfÔX>0rHSád㨓>@ÜhË="0V,ì ij1Ð(IÉ<¦Pð”° ¡ûÄP¸½ %MŠ#Éá,ké~R¦¦ìâ%KbOB˜@BÐ5@)Tíåò ,¦6J6l9Ô/pÏ`ÈTìÀ³I•("P·0Ôƒ»d PFK«tá^\˜ˆöS#†éa±åˆv€g­t¡ÞÐ5!c¬! ²aUÎÖ вQ0 H>¸Ùy‹ÕÐ1<·¢@ d¤Íç˜wqåc}±Säa—~„‡ŒÊÈ×aa\áàêú)‘yôØ Ug9‰7¥…FPar¡“¤…¨ÜdK.aãÈÁã=VrñsŸ‚›ä›Hæ”’ ''AÿÞµèŽ*‚FøAÏBèõ9>| X5é!ŠkÎaYç–26íÕ¬#T%ä~ظÕXüásî¦E¨w°)ªë•-±”‹YT^i5¼Ä”îÆaƒ€7ˆkBQf¹š-b±FôœÓx<(áxÅ9€% òèKÅRÀ0„%«xêB…ŒnÄt ŒtØPX‹*2  £ 4Y§ B'iød­M¶ií/“±ó !$/#‡™Óñ5Q̈˜°QcÄOdk‹ä5F#êÂ’%Ú€‰¸¨bTÀëU¤Ú8VmÖç't¯GYN³M¨A dŒ]:H„ˆ1XÉ7Yëe+ŒÒoøwÕ oCN³ýaŠx˜÷MaiŠs4ºáÞˆó:>ÁŒµ†´^ÕŠÉme´¦B“›x —¥&Y»@IŽ\T7, H( 2Œ YWÔ[‹^÷Ü/“‘.Ï€«Ê.t„¶_q"…õh’>Ž…lFúQ£Æ2*Âh+n£F=Yé}ÐI‚ß«ãjx¯&çÓw˜VJ¡#¢@Àðrž=JÅTƒðàø,ËŠÒeù[']ž‚QÍ p’òHÆMzzzy$ ÉD™>6“ÀŸaÏݨíC}ƒôÕ¬Cþ qÑœquë-ÃLce°[FZhœ¼d½•u¶Ÿ-ªÀGuB~;N|O§2Ì9M+Û2^ˆD&#ÝYså¾/öHo[ˆ’m¦ ?L9Î\¶SW©0ñÀü“(<`³Xd1;  é­¬’Zkÿ×BµˆNçN8ø-(Hj’]Ü5O´κ§:'½J¥;t‹×}5¯­mÀ'™áu bU÷‚†~Êd],öXÑJšñâ•ZgµÛ#½hN&ÑzXØ R ²$²éêX$Ê–tUwNI•úêröŽibŒ|è<…ˆmF½8f‘w 2êC-F0ô3š¥­lX%´·#ߨ©©*B ChäB¦M†Të*h{C¿fêZeÇu~Jd1}Ñ•»u›ÏÛçJ/NÙNP¡¶Üo ÔðNÖ2€FK<à~HÏ¥Lç(f8ª¶CÉWyš-`Ó‡åÛÆHíDÐRwLgÃU »ÜxdÐ’«Dq-j•Aa“Š3 èü Ä&¶“4û#—Ô^E@ãB“ÿÉÍQiØR²6P²)F>ð«»AÏ\„“ÃБïAS [NHB‹è툮õA.âïãcîàÚ•—˜70a¡yšŽÐQ°CjÐ,­åЃÃ($Ï š s*ñÃá1BPsaDÔ"·FçxvµmpÞF{ 6¬£Bï$åêÚÖÚÊÉ¿ð¨º@,x^á…I¡CǶT‘pÂtàº'tžù3äðm»þÒœ[ÅÚÑÌ¡²G¬¹DÒÐ{Y终ð‘a‘xä[»¾íE…øŠæKI’‚s@fBÄóNOi(Ubº?‡¯¬lݺuê×`4&þ ÅìçaÑØ)qÜDŒE™ wAïF׈¦É@JG$‚Ô¬ßd|¢•²îwÀÛ Ç>v0‚½2„™èZÝj{{ëÆõÝÉÁA¸>Ÿï•åaÖé þi¶‰Ë)CÃÒÌÔ]Kò¦q`I¸¡(ŸÅþ 5X)Z•PVX¿…]ñð¿¶h¶ækQÇBTsÑõ¡Jê:Y½¢ E¸”¤c<$÷ïTÊrOäü„9-ûE-#É~ƾ<ê¬_¶©™¿6»žbp:iÓšÉp>U“x-¢ Õ8ܰè(ì¯<£ Lö¾PiU _ ª)sùíŒV’‘„À7 üÑL¬T£Zˆzò{ ºJ….ÆG>®&_»M*Œ®‹Õ-Ísª²X A™Ì˜”ú@M`OCèè„g2"¨…Ú^O>…£¥YÄz'cëÏ3=îðx"í¥lJ´ŒÛn¼Þ)ªˆ­ƒ!wÊLš~Ò_w‹Ýj±#‰Äê®U¾…µ“e¬š>4ÔkÓ9M8Šæ…xŠK/ !WÇJ1$tä×ÐnГ,{4oÒ9Ê}îìù¢˜àüY$"e½cËÉe_Nù¼YȦ¬5ùËF;YåЀ:0X]ªø+-xô D½²/0“-ö×´1ÏgXä Úš÷áŠe/2M QZc ãÝp08¹½…³#¡“îIg®€m©Ž1rhû$bZ+Œ ß<õ׸½šBJÏóÙqsYLI/Yj’çy¾]§{œ‹ÊÀ×8eÅ–Ÿ6«]e©Å‘¨—u›¦ƒG¯u@¥Î@fK¬GÌ~$u"ù¦mS¦xŠN6¦û¯DYSX"å¡t$™@ød€åpØ&ê D|!!d]ȼ'â‹R4zÄFÇáË›Ž‹¼VL}+SE¶Òˆ*='¼ÿä¾Nˆb[-@S.*>à#§;A €’Öš3—&d¿‹GJ‘DÄ=Ê3ÑÌ-á P£ñlúø>8­8’®±ñm±w$ %˜|‚ì‘aòéx¬ââFe¬Ní0µda'a¦~V}h[«Öà«ÈàøNok-æ‡Þ:æÌj¶_DÚ-+¢7båávŒ9Á3 Eý„p§ŒŸK@i ·/qRÄÍøh_˜½Ä5»²ÅÅ‚´~3ÂÏFÉ/?²ìE¸DÍÏp ‘úØ·FÑñ¥ŽèÉýòl“f5X‚@£|—Þ»– ¸æ…×G}-©› ùfW_åM|ô¯lËžº³à}Óä„ê¥í[¸Ö$H­‚OQ‚´àaÉ‘:ÞÀ„6åä‘–ÁE”hUïðøOéð]YÐvyìWEÜ^lØã”&œßQ qt…ç¼šæˆ Oi}Å‹ÎIø"ôZ²ekÛ/µU|°ÜHî­â^CõÆdy[ƒ`³lt G+ŒIû©ô¶˜î¨tˆ!¨ö½â@‡ Še? ’Z‚6ð²!‚Š‹»k$6÷ųIU€)€ŸÐ¿„µ}M™ñåù°) 64ü?:wÕDˆ™¯¦Þ–2f ²‘î'âðªp ñÿ¹–mËumXM)ñ )ü%ÿQáûµxœmZ[¬mWY×yY÷½öåìsÙ§§…ž–¶”ƒ ÑQÔx‰„D_4c$’ð 11ÄÄã+‰‰1bb|ÅhPTĨPZN{lÏeß÷ºÍëÃïÿÇ\ë q·ÝÝ{¯µæã¿|—Ìdÿ½»7ßqúò—euÑ.ƒ¯}h… J­©´M2kŒkªÉÎþùüTçÒn-‹¦©fýÉuŸîWTÂùÙ·”_¡¼PA)ZáÔ©Ôƒ¶^é|*|㛕^'¹>¸ÆÉôÉÿéàÖsåïfõá•'Þ^õó¿ýØS»oüñ­›ï{õëŸÅáêèÓ݃UyQ.϶/ß´Bœ¾šoÝ^{ûéÑË“«o2ƒ7 ºZ!Bc­íʹ ÊH|“B§”ö!Lw¯®–ƒÄάʺ- !UPýd÷-Ʀ«×ÿMúRªÔK\Eëx=±½½||­¿ýÈÙëÏçýÑÖþ_ýæ|³¡:Qýý¶¡-ö• GמY½òùáÎã7ßõ‘¢j^ýÖg¿ÿål°íš¥MÒĦ¾©m:*ë&˜^Ó¸­ÇÞÕÛ{wy~ÛØÖ0g'/_9çƒ4X«öá)&•Þ {Ff½&ÈåÅYSÕB&fpÕ»ÊW³àj¡¬¶¹«Î¥pBj©¬4y:¸,¤¬‹S!q•~½œk|{|£m?ïï,g÷$mÖ¶­Ht‰° fÃ]ióÅÙý$§Yo~ô²Vš#)¥ÆÚ’|úX±Z\~ï'¯|IV'íên[ž…PàÖÞ»(~¸,R 5ªI¢(ðã¨—Ž¶wß«ª"x‘$òXáMÚfm]ÒG¤F@9k{i]ƒ áW\P'“ ¬ô^„Uð ä=MG¡÷øa’Ih—Æu⿤ß6•ÞØ¬.’/„-H•磃´?¹8½³óÓ_\|óSºx½™ÝF´•Öuy\, V‰¶)š @;` yšöúƒÅꢬW´~Ó¯ëõGµ$(QZ§PG _ž“ˆý·Î/?› yðò¤X Ji!l@¦U‚()“8S¯´iÛ¤ð‚)´´e|¿¶­nœ3I¿7Þù‘O„W>÷ǧÏÿU»|`ÓñhrùüøùàVˆ£GÓv-Zƒú·£%!‰Ò&vµœQ8‚¤LIj!úEШiå)à˜µŠÂxnËt·©VJÖ¡9 øˆÊtï†Ð[®>ÍYo´S/_«‹ù­wþÂýW¿1;üŽÆ^iUº=¸tSxµ:}Õ;qåÖsÓGÞ~û…Ï<û±âüåbv§) ßVh+)–”n¡‘g ObLS¯<…‚VŽz¡ÉÒ¬)K$—ÊBÅÈ#_ Y"h­°4‘§Ý!è! dã;~|÷©œ¿òï¦z}qü‚N'ÛOýòγ}õ_>mõBµÇç/þuÛø|ÿéÁîÓ—þ!T'FÙÞp¿½þå·=òþ÷­Ï-Ž_´½©¿A&WM²øãb×À4`G„Ž€îCs¢|Œª›¦i©~ŒRÃdf~þ¹Z-¨Ñ±Zñ ;Q ªoÐÆ”•xÊt‚<„f¡B d3Ó[>Ô&[¶¸=¿û¯¶?<þftóôö`o~î·¿þg?•ï½åø7Ÿýä÷¿êN^0¾Ò˜þõƒwýæãïûY´É+_ùû€–L¦Û?“®ù¶ T!bºw}y~äÚ†ð'ƒ°ÉF)‚Á¦EAM^U ›¦ÖØb9oÛÁÏ{¬?¸6Ъ—à·,\6¼•\z²ZÜ·²åáböz²ý¦áÍŸu¥N¿sôÒßé´—ô&@V\ä“Wßñ¡WþñÏõpïàÇ~cïm¿”ÔÅ—þä=¦9Í{Û‹"lÝüàø‘gZY½ùƒ?_Vs­Ï³ñ\}áÛ«Mrí‘[¯—_üÏ@"Êß-ÖL‘É€Þ)µáÕ›ºrðCZ‹÷^¢nEÍø–*Þ‹¶‘:Ù»ùc¿wÿåÏtX.N_϶nÈÞ¥fy!Ê“fu‘Š*œÐÍfoM0&e{Úñ£Ë£×Š/éÛÛÉdpéÖÖÞy~zÿé_ü-£Ñlç:½& 3[I–àˆ[·ž¾ýÊwg³3Z°ÆÊ[!Îè{cYI;µ¦ZÍÐY6h}¨üSPè‘7î…Ð"^Ÿ^ïÉý¯wÑ®E[Ùlì‚MWZ¬y¯ø`Ÿ+ÔžB³kÓíaÑMã f²Ý7¾õý÷ï|£·ý(rzxçkƒ+o]¿5ÚlëêÛ'?·<ą̀4€®ÌóäÒ•ëGg'³³éÛÄXGø,oqe²‡%¶užä¨œe¹Ä«Ø :«'üGÐÎh “ë¤I5 ¥ro+€n¾õxðe5’ýéc½k?:?¿¨O_í©õ‡È!.˜¦ýñÎù¢^.fÙà²ÍSÜá™÷¼(ç¯}ë3Ë“ïWE•n=1|óÇ]}Ï-o[Q5³»ÂU!´6K&g ÛSv%S–ˆ4Ž$å ûÕè‘4ï5mS×` [ïb‡t<}æW­É[ÜùÚ§EKQª9,¤ ]@Lt/Û}jÿÙ_iÊêôÅ/ºÃÏ+P/  ðÏPè^¹<Ñù$ïM.]©Nþûü>Êâ*ê£':Ì_úìïwþIÔ‚"ˆ¤CPˆ Dßb Ææ«¢G6€ÝÝ¥)Š(_ÎÏ=Õ ð_1v!= lÝ^îÇ/ü³;¿ãÊ®>Cm \[ë$ƒê-UŒìàŠ<’o^|ó“VÃý›ÃÉå‹»/•‹#¥Ó|rÐB§Mu¼<ú¾!%ã]Pe×~Fƒ5ëÃêâ{RT9 ¸D‹À½°ÈBEeðZ5=ÉP2ÈÔtûòÉña]¼ji7ÐDOå—„k¡Ž´¦ÿ©$…Lá_.¿ó×ÌÖÕᥬŸ ºÜ¦(Ôð_šoIêSP",VèÚ Ú°7†š//°MŠ,‡:Vâ!$©‰HŽ¢ ˜”I{žˆ™¯pG$¤ídàí @³¤V®.d{¸(àÍ¥§©ý³éâìWM¯d²šŸÜö&{ˇþ`úø“^;†Åˆ¹¦ò¥I±*Å57ÿd2€mÛP£½á‰£Ã{''wIðüÀâ%!p×{ÅõïYšòßIIsQß"¸]š!ZÚz!Øf@j$ÙU¶(H]×ÐØ YØñ“øÝdûêw¾ð©’ÏÍê÷3épïæ{¶žŸ2hd¢7! jðGËX.b?Jà• Ø:¼|éê¾Ùk·_ˆ­ÊÕ.»Í6+”0bÀ(@ÊÙ$1#L‰^rw¡xÿYÿÏñv`l¢\ë„)ŠÙ>“™zƒ4\mq‚¢ò@L >À¬I§¾†h•CòÆÂ™¢ !7 DdT‚«€œ¡M/_¿³ûú«ß–‘di›’ß‚Ÿ©f~#ü‚RↄP¿•]èbü>üÑqôÙe,€œ¦AsÑî!‘dÝDCØ&ªûkX ÐA0v@ÆK…yQ"Mñ»\ΙjLÓÖ\´\$ÿ|\—sÈxÚr\‰÷Qøñ¨Â„nà3V>§5ïÆ‰ˆÊTBÈtBÁ‘± Vý††oq­–\]Ööá`°)ø$ß~P§U½Äx@ŒŒÊ©Ä¯’b9‘L((±Zš,ß‚R‰°Ì€¡D 4àlð±zX€È]cÄÖ L~2UÑT†5YÞ ã} ñO¶t¿i/ôºR=nRG€*CJ:c¬×äþ%3$Ö­MÓ¬”µ°2mÛD:`M8ªá]Eë \•\óNDÎ¥˜S˜øhê‚h*^mì#îk#(޹^…Èqø@Œ-+!&*纤‚òšÖEI`ÅUJxŽZe®é ·ëŠf,WxB<ÖÊù ‰€…Ç«q’€dÙ¨jký@éNPŠ\óØ9€´ª°^ Qõkˆ-„2&á{Ë,¯BT}r!nF©ÀH+)ð4 º\.Ï…§‰Ëâˆc¸oÛN6.NièÃÔY¬6©›`»¾4>âýɲ8·š äHp ÖXÚ >B<(£"%(¢¹ u7-4Ј’ËeýM°HçÎQÚПçVæ¡"½DhøOT‡$- œèšZm¸†ØÒ› $Ã`¼‘ÇåMi¥é(a»€N@Ý# ÀOT;–O¾¯©ý­ðßwʇÖOЭXá³ëe>âùy,©ÐuOƒ#²F}Êf“çí þ¨FGs0d!Äžgi‘uEÑá¡8uDkÓñ`r “Šq!¢·”/ÒçpF Q?Íó)°(#ÌN¾}X0V™hY½+Îr,fϹŽÜ] H¥Šú\F#ÀK#-Gx…:èsð;qÃ*Œ^äAÊs\ÓY†ø…»€¨–ó{Ãíƒj9§ sþ’¬Jr4üsœu‚Â/vz[‡Å){ Õ)ùÎóF"ˆ«@î×$Œú¸ɤ%x NZ‚+"rS&Ò¤bz3Ê0ޱl#OHZôTwÿÖÑÝÛf9¹tcuqÎs`Iš2¿@`ø56v…€‚›d£Y[ÓXá7 ìŠ%ñ^à¹îºÏñU4­†='ÙÌo] fjư˜G¦ ÂÞЕYˆYs2‚+µ„&ÎU¦­ crì…† >Šá(EЭ)M੼±³6ÚJÖt¸uºZÑß%÷ÍeX«º£ê 4šÿ%ûßÀcv_¬i¹S"€ò hL…äc¿ËŽÑH*°ÆPoÙ8iZÔ?Ï8ì›”Ž„ËÉS5–‹zq2Ÿ.–|·Ž7ÅzÔƒŸ3$ØHÁBñš\TAiÒãÖ£óùñéÊ8’”Š+d…/;S&×j.¨n²ÑmKDì p­7ÖzIŒ&—š¶öìs¦£^¼'Ë$Gzb!âXUÖ¤Ì%@º¦³?@1)UCϺ‚"M*iL,ÞÚeéINKÙ)ÒX/îŽeÃ: ²›ÕùMVÄÆßÉîThž·z?ŒQÃ<&½gM]!d‘ÝÒ„Îá嫪.ŠW¢'¸Bk-¨ Ñj:vAéºnYòÇã¡õF4s%¯cŠùÑ&>Š7‡âS×5°JžÀ˸֎•is’ëBlÀ˜dÀaogY”žýñVo08?=)—sV¡-Í¢µr¤OQ,trÓ.ã )&“´2«bå"gò}‡£)!,•Òý¢©ÙÄ5θ…™g;w;Uu²%ĩݺd$‚¨D}<4 §£ÉöñѽÀƒ¶ˆŸI’ñ€Îźä8 :ú¬jZHeH܈žoS4°®€¿dŠÒQâÀôÔMÓpWéÄfìãÚu‰t ì~’qý>âR<3á—6S¹Ô¼d¸‹ ¯Ó|ÜË:1g'Ž8ˆÞƒÌ2ï‘MAý#x—lÊ×un@´M =øA­æ‹óšÎ}èÀô=èå«ò¢¡MÆç±’è ñÿ)ñðàUn¼°ØŒ7£èPq²Ê†IšŽ'““:©øû¦Fñ +ù4³ÈòýÞ0Ïûçç§ $|Hc#)iÖ/ ûËËK‡s]€wàpA_òááÿ|E/.ÿW]­•Xã¤Rˉ,- uVlœÛ‹Cg8.šôºP—«QŒ?®VˆaMÀZU0¼˜]йUI”E„4p.ЫtL{Š2•PÉ!MAêcãsã êJç!HÊ®'EçÀ6r}þÁŠ× Úᬸ€LO“"u›'ð¦ƒ+7ööö¾wû{§'ò|”Ù´(çÐGPÞmYã£Y¯_¬‘%³¼-Ä%P± ´ƒ©5ýÙÅ!˜ŸE|àî!6ÞG§KÙ1læ Vk'|48 [|Ö©sSw[G]áÓW¯ÜØÙÝñ¥Šb™AÔ5ôx t¦Il±\*ÇÁ&”ÑXdYòƒÖ´¢ã?Ù”pˆ–¸ÏÁðÖ›…ŪŽ^ ƒÌn*Ö“RzJTʇ¹NTŒ-W"/9ö&ïM:MRSW3VMZÆ-:jD‡6ô4©Nmo>›ó_l´ŠMU"ìp‚Žùs¨Ö$Á‚]]³µDw:V¦3A¹>Ø8‚î§X4þƼñE³6l¡ÓÑ]—Ȏ1ùDw‡ÎÛr=IÐìc2 º •÷¥6j{çÊÉá h=ÙÙp÷ûÖ¦ôP·«?›ŸšÎ— ×ü ?+»¡tˆÆRw'½Ý0Óp>ÖëïlïJ™ X:ź‡Vÿ̺üšxœMz ¥ÕuÞÝþåíݯ÷îééžééY™a6ƒX"²c މìÄPH1q\"Š+r¨¸”Ä–¹,ÊA‰%—IŽ¥%„)4b“`X‡˜aöžžîžÞßþ/÷Þœsîßc7SÔë×ÿûï¹ç|çû¾sÿwÙ]ÏLÿIϦý•‘ùr暑wæñ¸6>yÕÙsS‘ <üå…©~ÝÖÏ/œ8¨lÛ+ªQ=Ìëõó•dñaëŒÅ©1Ê«äK#µ…“¥ž±Á ».œ:Ô»ã7&¯¾£wýð… '{Æ'gSG^Wª|ñÔÉžÁ-"j¼ö·ªÃqÔÜ~à÷F'zæ±¥ ïÝ÷å¿m – ¦³¦„a~Ä<¥…Ç“ð†"eý[ï) lÞyó¿>úÚó‹§ÞŒ–¥­)«›BŒçã¨3ñÑÏï¾ÿ3A‰EGW~ðÅk…^0–[YÞrË®×VX4Û˜z¹½|"È•ZÍeÎX®Ð“&‘Tù|¥oeá” ú“$êßþq^èßùñ=ž»‚êûñ׿{þµ¿Û~ãìû;­åüðÎuûﲩ™}ÿ•|µïÀo&ÌBð‚IÎ,cŠ.¼£S?‚Øy*¹ù® ­5W¯¸>—Ñ함~¦Ó™aBæK£ÆÈ8ÃÑc×Ú«×þðOuçCk%óº÷ÝóDï}ù›wIžÉlª­I8¬Â ã JdmÊ9lȪ ×+m¸îáÜàä¡¿y¨Ð5V›=Ó\ý_Ó…™P€Aè熛ˆqxƒ ™óò-mâ´½ÈtKpX‚¿IÈ–„ª åã¶ÝvÙ­_<üÂwÓ2¾pú—•ïUÕ íw%Í–nNù/uï¹Ó+xø™Ëï~`tk5n)t4Ü2ÿ` ·Û‹Ú4;ô?(÷ßöÐgß~ñUcý|×й_>µøá‹ùq^éÝyç¿å«É/ÿ×à ?âRZ&{wÖN§ñ*„È /8‡÷Ëý[bäXN'mضƒW*ô=ÉL'Ö|Ó-_¸8»ì+Ù8óBcöméås}›¡Õûv|bóWoÞ>øã?ûãÅó'XÐUÚ¸íò{þEwwNQgÁ°© Bœµ?öu‹-ÁØòôÙêðtOÚù¾Â‹ßúËÙ7þ_Ïú=Ñê|qd{ïö»úÆýô‰Ùׇ ¬áÆz\æò•!“¬¦€OC¨–‰$îä+ãù\quñôTF[¾÷®ÇÊÃ[^}òóOZ.’ÜȺëÿÍЦ+ÞùÞ£ Çžîܸrárèª;nøçþü;_† Ÿyóï }å Û¯¼ÿÁ|IAÀ óR…,ÊR*è²èîÇíéwŸ»æfSí‘ …¸xþØÔÑ×EÕ>|¹·o,ìÞÿñ¾-ƒËÓ³Ïþá­L/ [á«ÒFÍ‚‰«íì«ßH³Lèâ ØÓ¬Õ…ÈUº†gÞÁ’Rif+ëw=뎿.LZÚÚ4¢0zçwwfÞ=üäàÆ]õùs²ÔËÅqÂUqpÓ•+Sï«£×Þÿ%[fA7+tçRæk…úÅA@ÞŒ·áÚ?:ïß~õô©w®¸÷Qø#PÕ̉“ýã3¯>}øûÿ±Ð=lrå}¿ó•®‘áS?꽿þ¢Ð«ÌDÚŠõ×<ÜwùÑü{gþEsᘒ¼!òí•ùöêY‰êKé':IM”ú´å vßýG “'_yÊ4B·šß•¾ÀJ1•@ÿôl¼ìÖÚÔ[,]íÝ3??³ãŽÏï“tBE²H cÒ NE÷ºëÓ4µ²PØ^ØVÙ:yÝ Ç^}nöê•©úÜqäæ–Ïl¼ý¾b޽òç6}ð <`ˆ_Gea`xÞ…~·æ@“4ñóƒÝ#;—ÎÊl7Î a$8M:a©;¥ÙwÏÿøæñCKµs§7Oì{ê+¿ÖX8*=‚×:•Å1áü|qtëUçßû+TqÝž=÷þÁÙ£ï*jûGv@x,±hbrÌgùʨ痊]c©õT®?a|bÿ'¿üM]¿à Ói·S™ß~ÏéÛ{`þý#µ³ïµN>?wäßó@— ý»â(10ɲ5€ù¾æÊÅbe,j×AxºûÇ.N½ÁÒºT¾µ¨—ºbu•áÆ«ïŸ›¹08yS„ï?ÿx}æ­ÞÁ­Q»U[š¼â¾êкãÿ·T@(E¾#$tAœ4:yð(`$ŒÕð.؉eay0>ºÿ·µ¹ÖÜá@ñÚÅcJåÓ$6¾Ÿ+Wßò• èú¨9fdÛ¿}ÙÍw~õðÐŽ¡þMU„¦!fA~Pê{¹0¢*¯ëΊ>pô#³í ìê´¥*OnûÔC¿òÐ ?xäkÓ/%TZ9ÛY959Ž;«\yiÔ*_Ú§r¥þáÑóo?]èZgý~Ùµ~ë­ŸìßÔï.@çJ "–xÁ¶¤6¨ ïIã¥ÚÅ£¹Â]–5Y|ÁÆ­ ·¡‘¨-w}nÿçn=ôÕ7|ï3 ;Q’T7}Êx•Þþž¹ã?ŠšËRÀÅ%íE dè.8ðK­öEÀ*ª,é…à+<¿\ìÝÒìtJíÕ9Û©ÏiÝ©ŒmjÖf%¸²8†Ž4"„í_ö‘ÛO½ôV}±ò¶W};÷ßù…û+I’ÆL ¹Òz((XP 4××l.øå ûh]|oùüÁ´3‘äKã+Ëwú?ì½ÿ¾Ÿí[þø?ù,6€?U´6Zý<˜%m•ô nÊ`iUPÏŽˆYM¾TKT®ÀIJ/N" BTý°«µ2Å,H³² (å~4²­Õ\±ÏD }>¢ƒêÀXsiI›pÏh»ÅÆLBBÀEËܘòK@ÈõÅÓÂ+–Ö]U¾bÇÞÛŸý‹[Óö€&”vÜn×&®û­-·?|üùŸœzá«<]e° O‚{:j)•ÛyÕÝÇ?ÛªÏJ»G:­zÔ\ r=q{^§-@ ¸RŽÈE½´¸ó‚¢ò õ¥óàh|?Ÿ »rÝÒ Áý§ÜNÔ³a÷Êù7}¿Èxê²ûÓìºû` èµò¶åû¥håãí®‘­aeóôმ.?0õÖ7ãÖE45p›¤  ^µ{òW+Õî/þ%°¢Õm™/¨BoÜ‚Nïn.¯ô‚B&QÀà‡åvsEÉÈq/[ÛÑ–˜›á ¥ô |Pö ŸW^®ÝvM‘FlbTÀMŠ>ú–å¼âhÔ˜g¦¡À[•úš‹óùž­÷|éIoŒu Ž»?{|`xòä/žœ¼ú†‘-£?{âÏú;Å£ëÐn&ôp[ÆSTGojÖuV¦B<q‚{%¨`¹¹|ÚDK@ ÔÆá˜"& —ïDàCȇD2ÂËÉ §“°w’°¤ÓQ Ðõ¹nnšLÃ4Êx84²çþ¹žë_š~³S_˜<Ð\™¹ú7¿Xž«NtAhû<´xî&t±{`æÝ-øSi; f6Î5H‡1JãF„é”~\½ŽÁÓ0Ÿhãz×ï¸iæô[°/H Ô‚võ ½IœèxUN¤s i=5¤%¨¥þæÒ9hõ Ûn›>ñ‹¨= Œ-ó}qãN‡†«üzp)=¦Û^¾è2šïÙWÞªY¼|îƒ ä ÂæD×)ÆÑ`èø ‘«JÀéVÇðäÑ idÔ&´p~šv@ÀT¡¿±²4<¾kéÂpM©{t+JšÍ¥óÐ0£Ápí—lg!®ã,Ñ:ƒ¡@ yPíÞ] ƒ³Çž‹u´áæ”'j§Öœ~%jÎsÕ­eá–ÿøÆë6ÅQŠA¸éÛâÀ‚ç ø$L \Œifæ Ä6X˜Kø Fǰ \äÀðäÒ¨ Í8¾qÏôù£±6{>ñÈÜéÃ3G^â´nÐÁÅËi}Š›–!û Ï+1Yô„Z™zÝÞ±]‰ìëÛrssîÝùžáZÃÙû‰O|á — ×Ki´œæ$$´\hܤ±H''˜49œÍ¡Ÿm d‡ Ûö¢!¾†@`†ƒæ*†'h^TØtmì,Ÿ³)Xsƒ“†ÌùAWÚ\ÖÍ÷lÞqÛÊÒ‰©7žô`ˆNÚ°’ß=†•Õ¹ù!‡A®‹÷ÿÊÒò|±:T›{ŒM»¹VŠp7l' ,´(XA 9xw §Ry@ÎV×)ž0 ‚ÀíÂÁÆ@· '`¿ Ê&©3ÁxkE˜¹œµÛ‹GÁY‡¥rߨÎóÇs#¢ÖEct¾g[¡¼néüËÈ=QÏ¥ÀqÂ@mâ°²ÞÈ8™Ö±bu|Ãî;O¼ûÓ¤3Ó30:wöñ«ïªWÞq¯çUábç‹€™•ŸïŸ¿pÝдb¡ŠÓiÎiÃä+ež9A§ÀÌ𸼠àOú¡€Gà‚|eýÏýÏçŸøB¼2%ì(ÝzýùS§ˆH;ÆÒd ¼†GR¨8ØÂvP‹U¥oë§ê‹gZ ïï>ðÀþ[?ûݯüfkþH¡˜àCºè•Fvx@yÝxÈ$0ù øMC/p…4ÈÒ@æ0•xh#á °ËP€®±}±µa±¬@«qº•&­Re(î4s…~Ué_ž>¡;«¹Œ:WãåbÃßbS‰ì¡|ôo´PVê쌞Óp‚%ýHì„GDP‡ûM±‹›1³.0ø)› •ÏP°@Ñ,ž"ZÊ9ašš‚ö‘펊ÅÈSìÿh-©°[H\#M@ÿf¡r÷†DtX7°–eoDüŒ©[‘ Ô°Yî]!˜{@å€(Á^C$Ihägº;Þ™kTsAÔˆÁH¤¬+¸räàð@… ¿!»¥\A<åw¹Âã3 æfRšÏ³¹€îh\ϺžÂŠÐäEüÁ²ÚÑkŠÍaÖn‚“^ž¶o°‘QÑ85 "•ÓýéWD'-ÜQŠ£2Üýu­Èø â§ÏhÆ$Ù–9bþ•ã‡911Þ”z™£Ð€û…ÅÖËZð¦3¤q8ßÁˆ¶Aƒ¡Š3f'º†S¿1ô„X2ŽºžRü$@x-m‡–ט¨žòª]SYº‹å.op(^¤ ¼á®vNÐsÁ}J´¥üÃLB¹—ONŒJPWJåIu£1ˆŒ›&xpœ7ñ5áÐÝ-c‹'b=cÎ.’ÙìÑùO~½XB5&@;ás‡)ÝΉ_;sŽØ1 ”ާp&"Ê%7-½"§G]6s΂¸üÉ»YÌ®…Ïhrk”#ÈB(7"™ËRÉéi¯;—°Îp:t~•nžq¢ÉÚš!½*£H{ÉÌ3¶6zá¹§Ó.öóCiÒ¤áÀ™máàG'$âRÖäâ—ÜÍã˜*È@Å 5~—Ïñ›"²”Dãkù:ü ±„;7ßQÇI\ZúÔ†ifœ= ‡¹ò†MÑçŒï¸}yîxcå‚pVy…ÂvÓ"ËL,øZãp:̤cOhÁƒŒ¨AÀÌ—Žn²1Ör–¹œpœ|# HRë’Mu 4›ŽÑenÒY ;_¥o3&ðW† m;Í%)ƒìP8ü»x5¡W-;w…®O"{׳£-‘ã~2G“c¢¼¬ƒ˜¼äÜèZÇ f”ÜáRíAV$æY WÄ k2þyËTªÂÀðÖvܪ-Nã:¢Ëžøa#¤î#Ùmð»O>$HrEuêµÉÐyš^c+w|Ä×¼¦9 Œ#3›™RçEiëB:›ŠEÁZ;ÍÌXöK ëäÈ„¹^/,$iwîÛ×àsϺ3.flÆodÚ3Ì2*ÿ–ƒÑüND£"ï"‹fÙ:‰_³Ì Ì»ñl¦æÎE8—&)~¨cúOš× ¥ 7•8þüÿužô1xœMz ˜]U•î>ûLw¾·æ!©Ê@æ!HE´¦E¥Ÿ¢ ¶<µ‘ÏGûºy~ýuŸÒv¿VÔVûu‹¶ÓE”C&BæTæªJj¸5ÝùŒ{ï·ÖÚ§‚E¨TÝÜ{Îþõ¯­}î~N)‹)›1.3)]`[¿ûÕÉ“»²‹Sýƒ›nZýþË*g¼×ºÏ«œ3˜Êg»f.ì7¸âŽ+ã %¥’J1CrË2eÌ3L‡Ù.üe–m¡´R]×X´þÌŽyiÁÚ?kÆM»=ÍÝwwô¤mn›>s2Ì Yly¡§üó_}Ö› 2ùÞ=›>uYy_ù}‡©,žJ·-^>~t'—ö]/´¤™ž9Wy{GíÌÑh®c.S¡i»v&ç×ÊLJðœ™ã–’‘ipÓ´ +egÚüæ4“Ât2œgB/ps ²í fG¶»©‚“i«Ìž¹îÿtóë§GëiÇâÒ2;bÌŒ%w¢ˆI.ÓãØÙ7‡³ã¡æÔ¡Þu[–mù\®¿·5+ý‰áÖ䩳{ jçT8c[J(7›ŒÅ r bƒ ²Â!`¿ä&ç–Ëí\ßêNÙÖ'”Áe,MžQŠK1#á#¹ž¥+·ÜqÍ_ÞÂRÌ”,ô=ápÅl[rÆ£ {û²[ÿ}çäñÉVe¶°°ûš»þ¬Y޽øòÈömþÜ5)=f°ë¾>Ylïž>[>ôÜ&g¹î¾¥›o6Ò…\ÿ’Ùs£.OËÊä…CONœØ*üc€[D-ÃtÁë8¬L‚@ çcÊÍ÷˜©"¤ExUáW$ ÃtU(,H„ÁÃV™ÃïÙB¾kPZöþâïï~aùæë.»em½)ÉcWJŸx}ÿʵ¾:·¼¹Ú‰?ù›ÿÚœßýüŸß÷äð¾ßïùÛ"š3 ¶þ®wdPÝÿó•7}|ÍÍ×ÏŽV:J%–•ºÙá7‹85ôÂ÷ÂÙ£Ž q¸ÛÁÍÚ4cöêÍ·ŸØ÷x؜䦔øÆÖ’ ¾¹ Q ”r2a½¬â&XÎ!W–“-õ~= }!ìBï¥}k¯v:ÙM÷ýe+¬Üå1/–Ü'ÿå±…K®Ë›Ý;ž{°Õšxÿ=6çÆÞøþçòíKV¾ïö³‡_+ñ÷ýR?x°cqûহJ…Ç¥3¯ìž:Ô¿âòé™Éò¹3,ðý©"˜È´/. lž9ú›ú줡}Á¥~m²UEü(@wœ Ôr{ ng”†‚ôX3ƒq¼Ü0á-†i§2ínaAuj,U\dX¬kõªãþ©JNAífIö<{òðï/u.X}õÐ'šÍ©;üÚèÞé=Oü(Ó¹¶2yº5±/š;sÏ. [ÍÏ›{é¡Gš•)¿5ë7¦nøäÌð¾…ë®lïêÜÿìwÂzCEg Ëòj“P;xÁÀ`ˆ¸ ´c <„XÉ€×ámðü1˜i§¡ÆK½ËEäùJ¶kU¶wu¶£ÿ’M×Lޏ2çÆ¿¾ŽµXÖb‡¶žm9ü§PlÕÏ+Ø–¸íoîÿÍ×ÿµVž[U¿òg»wLÉj&ۙˎ툞ù·ÏÅ"\µåKéÎ^áû±×à®Õ¨ž\±ùf96·í¡{ãhÄÎdýÚ8SX»LÅd›¿B%`9 ü€¯JÁm‡[v…LYùžõk6çó™½/ü{çâ«Å.ýȽË6.?tìàKO´/¼æ=·.É÷Ø}½ÙÝ¿ÚT;#áìzêï¡°²ƒáÜxÔ˜¡oÛÊ@ ‡Þ…ÏnW¢.£åÆh}篾YÛ·lË—7}æSp·¶65<]è,BΙÇÇß>¾ó‘2ȯO„Þ4XêØEûRŒs% t²€ÁÈ[F?FÀÛV[ß²™ó'™‘_zÅí —žØóËæÔ™|û%íWœ­¼þö‰¡ÃþL½95¾èÚu~8rÝ_}Ê?Ï~ÿ£§ KÏü]cæäª÷Ý>~lÄ'UìñæFæ†ß²Ýœa²O>¡f½üËé³{ÍlÛå·¥}ÅÂ|‘§ò¦à‘áØ‹g$;púÐËÏ–Ï ÕFwGÞØ db¹yzRD˜‚a+cXÍ =èÇ1Ý´ˆFœçøé¤U*Ž\§Tê¿´^ŸYyÝçÓÅNè‡ý]m K/?ò«¯¿yã ‹^äÍO=º`Ň¢æôÙ·±l×tÛ!@¹Ž¾Æô)ùLÚŸxÄŸØwäÐ3?H»WÜxëš›7B5ÉV*¹~,³ÍÙã#'÷T£<øU#“¯ž|˜`crhS™ Yb…*àÀO&ðM±‡ŽŽ^pü‚º>«¡X µY©¼= š¦+v-ãP1ž).¼ê×±¦PXÆËo²··> ÍúÊÛïX¼‰=ýÕÇëçjùtéô[߇ÏIe2•…F¿ìÊ[‚VõÂñ·>÷ªŸ’n0ͤ?Ëìb­”3ûØî£n®£ÔÙûüw·ÆOÆ~Ý)-°Ûû™_ç¢åÏžQlËu. š°Uj4 lg¦•ÊŠcà œXÆ{ƒacep#ÓÖK¶Z¦›kë[Y-‡¾Ð˜¹äšO~þç÷¡±ÛS^}výGïÌ/[0zðô©WG-«®bhèN‚ãd²Àhp/¼ásÐn £—ð¦Ã³cǧßzæ™°áuô VÏýaâøÖ¶Ëf§ûÖ/\zÅ…·›=õªŠ[a;]Œâ0<°–)ÁÑþŒö3â{D–„£–›ës²í׌‚A¨ JºûV}`åûþÜk•§†Dvrϯóý¼ÆtÛ²ÚÙ^Ãvd07¶ûg¶!l;‡^·àÚvª÷ýÂvð4bÔ „€9©tùD³:ÆNmiöÔkÕ‘—¸/Út‹HòüW²sÛÿ-®ŸkQù0¢G4ÞT2FÂn 66ð¥eAý¢ .DKÆ‘a@‹è±Üv(Žl±£>yœ3YèYVZ¼¡YoÕ.œT~àæÛ‚h*Žü®å[¬ô`­rF¨ÊU·Ý¿ý‡_ñË#¢5Ú*u¸e¶cIÔœùüÊ‚°‡²¤°,(XBeÙSGë»ý°hÈñCZ) „™ê¾¬kͧçN¼ì•÷r¦Ë´ |ÌGúG ´`F‚[PÛšÐEx)HaÀÀMe:ÐÂT®M†iÅém·Søq±o‘2£È[{Ó½§o_öÞ›Îìxbúô¡BïA­V~-•u}oû6 ù…¡š)‹qÀ n6È&¸SÈ´‹{îÄ­JК}kéUw:¹Ë>{rÇCõò!n::,ð¼‚þ ±0Ç`6v0#±f`­YˆTGˆ.p Xó,T»Då -İ3E+S2œ‚W­t.Ú7k"j:==[¾þÍ[_ŸÜ¹£z~¼V²‹½ýËëcê3CÀW@JL„_zC…)Ä%]7„¿šõb©sçþöÈs?µÝl÷’÷œ?þ&D~`]~ñ`{&½ÿéoÅðYWà5Ê6!UÅu&´¤Å h1ü…:Q—6¼h¥Jv¾Û«•c¯’Êõ w^ráfë“o·õ¯÷ª³åSonºý{—¬Úôä7Eþœ]èë^sS£|NF­°vž>‹ª&‹ïÝ¡@jKîÞ¶Bj6õ®îü“÷÷ä+¿²¢4D5¬l[º¸ Ð½¨|ôEøT;5!ü¾K®ž:»G„ †½{2¿Ö Ô ºB ,¬d!g`ë 3eçºVÿ·©Ó{³gK‹®Xtõm ×{£Q™(v¬<²õ‡m ×Íï,ö®˜;÷¶›ëŽ£ª[è[xŽ“AõžíÊÀnã2MÍg+fršýþ¡_T¦FfÊGÌl:¨MŵY ÕÍ,7×ϸh–_ÿÙï¿ó‡Ç&†^‡>…Öaéšj uÀ|ËÆ±!sPn lÆ|©ÐrÝõrç¡×žÈ·- ëã"¬I ³îeÙT_qÉ%]Ë64GÇþöûBúq\ï^{CsähXu²Yž¶69Kgr=~kæž ¯‡ŠË–4û(ŸÅ5÷Äö£;þ]˯bίœ÷Ê¢fE‰°´äš\Û ß(WÇEÍq0$‘øA:|P8S´‚3MåùmWÔ¦NË  a¡^µð ’Bkƒk¨@¦º³ KêŽÅ‘—é[·øª¿ûéÚù½nÚ j x˶¬<$ñ‹{è7¸øÏ tß·ÇÞ©ïö‰úøé¾•—™qex÷SÞÜ8FÏI`ñe[æFL mkNãÈ@(5IÇA AKÃå Ü€ c xø |Ç·Òè Ìe1¸ ýÀfXØÄ!&·L Ãê[yesâT­<,ÔÊþnèÆõ36‡‹‡ c Ùqó‹;KÑâKˆeØâÕ9èfO³ÚØéÃ[¬]xËM·£H§×Ýúùån|õgß©Œìmï8èqÇ͘–ë7æ *Á*„ k¦Ñޤd¸z@@‘ èÄW0Cu+cr;jÍ@5l×à)‡6ê’ âÍ6Û®˜9s&>3Ó#eÒfTõçΓ¸µq¦PáÿÜr„w``JÒ3Ãòµ‡¾;3tˆ/jŒ‡Í©TiOåÚ—®¿ö®¿- ° »*Çw¾û͸5ynÏÃsÀVªÔÜC2pÒ¤Á¤¦§ ¶ü™cgÄfòý~mBˆÀd¥Û 4âÖ´ãæÛ¬½pâtç%ØÐ¹z5;ßÛœ>#·!#… ÓPÑ—wùÚØ’1Œò~¶vš½þ“Æ> ­°wõ5K7¤†ƒ7ŸØúhw× 7S;~ñ5©LÛnMŸ`"@˜(U´þgý&‘t…r4ÆÎ T[ø)ðà›*±`úLÞ9°Þ› ›uÓ)ú ŒØ+#¶Ò!"˜©MW3áS xXÊxG5+K.ä n8ÁžzàæLæ¯+?qÏ‚ËÖµ­t'ϱœÃvÿäñ¡m? ýÓ±m7J#¨O)€YFH&BE#¿ Q‹R è JÙÁ*`,›.È«ZP¾³-ôa¬0ÁÕ°Õ<‡>6téÚn[àÕ àÇ9U*\ÿØô®XP(ñêÙæ+?øNPo4fÎÇaàû>ô¥ïõm`“ÕúxëÀ¯öƇëå£(ÀaT µ`¬o(2gNfƒu)ˆÅ W+ ¥CPÎn¦ÀtÀÝÌ‚5×ìQ3Ž ÿZ~ ªjTE¶´0 <Ö¿“«Dí& !E(Mœ÷ýþ÷ÞvXõHôÈ}·†ÍÙ ýG»ÃM²lýõÓÃGÆOîuó}C¯üW:[j–DBבŒK6©g$°1êSX³4Z:d¿bÉŽ(€Ù|¶R]v¾¥Óþôž£/ÿxîÄkNº 㺉S¤1 MzxŒŽƒVšÁqn· ±Cª_~ᆻojM{GŸßÞ…€ôn^¹àJVˆÆv9ðÌcË®ü´ÓÙÓh·•2G_üϹ¡½q ·ŽC"àЈc°Äh34ÜÐjA¡ž3p_‡hÇ»*oªjhjQñ/.»º¸èÒRÏâê¹ã5 #+à:”7øð›•‘#§¡´W]¿yÃì™o<½ï‰Š£9%QðCmr„j0½ÃBòĸhÁ¦KÀ¦‰^` C×h¨4 5®á–Ò½—æû/]³ùÃá䩳ûžª—׬½é®¡]¯Ÿë9ètkù  @„îÝÓÈñ4n rv ‚c¹fo `„©oûö6¼ÿ>(®ýÛ¾%[Õ¹‘wüê°aDÐD€ëL3 8Äù¡®;1ð0Í ¥2q©…݊؃#ôIŠÑ' œlº{]ߥ·,]ûþ#/~sìèo-7ã–Ú¥éâ`mäXX¼2æ å:„Þ"ˆÈ7à¦_Þ«Ò)¬ð l² LàÌ yÚq¡8+ÃÑKß}páÀU‡~ÿPsîdÔ,°q¤BÀÀw†,d@„…ÔucAcœmª‰D‡·Tº@LøÙn"œ\xá¤:¼™“*¬*`«tÉtraЊ½ðŒx0pBá+\nhÅ ×D¨>ýë©(œéY5˜I¥!66Þ 8¸ê=v=ºóÿï_]§P8€çˆ„ºa43ÅEÙÎÅÓ£osêˈp©Ëi\„oÐÀ‰CŽç.¥%(‰#«8p•´\oö”ÉÉH `0ž€!ÚÈX¹ÅàK b¯9E­*0î\õÅŽ5ï]ÿ™;òm¸õr¬Àmw߸ɶɷöï{>hZbäBƒB‡ V¦ì$ ‹®ÝtÇ?ïøÑgÃéc–éF@h *B4)˜±0D µ°åš˜wž2ß÷ÑϰfüØ×?!¢Ð°€äcÛÍ¥ÝR«yžàÍC¿ÎqäÔÈIgA«DNTDD"!‰§3 ®hÙ °PÂ\íá˜Ã&¹ÓYŒ:ÕC)ΑE tH&EQËE$õŒg:€ÏRß&ìѦF¡ëï[~íôèa×S¥¶B©oêÔ ^6ìö ´"´]8Ô åä!l"ƱþB­æ N’–CÀ@ðm“¤(N»Dª]N 4‰—„•Êã¦+…MÍ™!áÍQûæCbRC…ú–T JrÝãÓ¥È('¥]öáÿêÿ¼òè·aìjÎäÛûkãC­¹Ñþ•×Ök3qÐôæF±®úÓÙî UcŸ&t…«~=?ê Ós"%, AB2ƒÈûyG“LúŒç:–A$ È<Þ,ÆRˆÉ%ù„ijè¿x#ÓFÎÇã’A¦ІÎÊv.Ûô1пpd[íÂQh÷¥þµÕéá8h3`ÄUy hÚ¼“-¶jã(ΨˆbŽY0 Ý©ÐìnPÒp2±¹Š!’i;éÉv.•2öê ÓÂ6”‹98,“Z”@½àé¡ikÑëäúÊYv &¡Ì|ÿz7×Q/Åé°5«‹1Ý>Ý«NÀ™†Ö‡uÃ^@* ‰¿êØÛÚ =ý :•t³}x““Ê3î.Ýx늫?¹õ§ÿ«9u̶PÛ@¡£dÛ† ³ýºd ¦`TÏ”zWv ,>øJتàì¬B4 …C¼PiiËÐx"%ÃJìGöPÔæl\á›E+Uˆ£Îz–#C»);j)Q±XÒ¤["%‡)ÆÍpL‡²Ü\¬Ü®Õºô†/nûÁÿˆj# òà†"èÚ.žb‘BfAe´33o_T;,ãM.ㆱ2P§é^ÅbZ1¦u5 °Xïé¨4,Ê’IeM4‹c~œ*Ì-QAµÆ-¼,¸€}TPsÁS’T~1t @œÊxYº{Õ üð}ÿËÍak´iQ£w9`?BÓ^"fá Õ(a)ÆX1Ê5L4B"]hê\1¦É ZFÏoéÍT è˜O›w\ŸÒNÃf¸Úaº38)pkßH±ép\΃²ø/ÞxK­µG±ö€´cM%!“9 ×4§£*¦¸âl¢0¶zd$ <Ê—…©@>‚áßIÁšœhÞ¤ÍÚÝÊ$Ç9®‰$KâÀIöhЀ†<œòlGAˆ$ .À´P輤^Z³œé![&†‰Q–R•T1<âÑ«è¢Ä¥?:¤¡®S’|ÉjHâ‚ÐAþ’›‚Žú”ž Þy=Pã7š¯£XÒ±1–CŠF!°!Üli9¸MRDªˆ+ÁîóåQGv* ÚEj4ÈHŠª†7Rã*93pÇëХ⤊ÑY‹Ö-w™†u7l¹4“rä'TÝô:e€LÀU*Ç%ªCï–©Lp/ö‰‚ãg Thº72DŽ–ôÆÅ]!†ÄÒÝí˜A$C…íÐD¯áŒ“ è²4UbÑÉŸ^zi™AL¬A«hÀ“”Gs*¼;“HÀ¬Õ‹Ò[|ÖBê }>P¸AÛ%N˜…'×xZ8 `NQ (b2ú¢ÿOÎgÐÜQPHOj¿‰ë4ZÔ»£¨îè’Òã=i\Yº™]J`žÖDHøÔ‘ÜjH£[6Ù㨎nÑ@ª8…!RÔ¼„#!ª³!’€ë\"Pi—ˆ1è 'Óƒ9È#›˜=™ì„ñ :Mps` S¢8t7±.> @µI»{@¬º~4"›»&•(±rá^É{°¢$´‰FKÞFÚº*M“T@èEÂ`l~´'-GÚTŸÐ$‘P!&¡_&ê[(r¨53, [ê'I"´€Wš9“bLH%×öÃÛ@[Ð?Z„gƒË ÕÌ÷)°ßVZwÆ‘vˆÈ„Œ~4˜Ð ýÒ ÑC„¦S[eâº9áh+Ý•<^A£Ã ox0ëK’u2§ñI‰4ð4C³!B“†d‰ "¹Ã»æýñW²ÌeÉÑñ0BEÞ05oϧ{þXk–cÈ“4ÌÉö$h‘AÁ#-'²/ ”'ѵNI=Vé‚¡‹HòÀ40&\/ÿ“õŽ&Q&ôé*K@.õÇéŒI=Žkú%ãl²?%…§D˜d_`¾M¸ÿOrlgº0nBhà‘Zn!)DÑ|ßKæ»$`ºž´¢ ãV:Ô8ÄÔŒùÔDDø´#0(½š¦ŒWò„cßÅ™n‘T¹´ØPzpÀÜÙ†ÖæJ:™n=%ýƒŒ'þ’4žÍ$ÇZºçkë¤;îÆñèDÐñ„д6O×F"$ˆÉèX8=Q ï›< ¤ûµ[–,‹T"1XBwúRô×G`¿€ú¥ù‚”V½8q >ÖÇ|ýê¦ÂiÕ©W•) Z2à†wzaR›znM"cÌØ( 1c&R+’ ¥}i$ý+Çc?ÛøÜ#Õ:Ž0:Òø¸½•ê6.‚C·%#!Aˆóì-ň*Ë ­”•@2A•Aémá|̹"EôE ¥J•&.½¬Ó—´ôÕ³$c_æN*'DKh„KSi;8§;[`?§ÞMR9Ù”Q¥ƒì ”~È!É¢¶TèÀ*=‚jžÏއP£š¤1C]ljT#íaè•I3•lí¸Ö $<ˆñÙQUÍÞZƒ$deÚä3>›ì‹’žG5𠜵’£à›óÔ§c›/Ý¡ÈGíǘ¤$µg&>÷nG3èîV’C?³%È)óbˆØ¼cv:‡öûu}êM;’¤›ã#¾¤Á~TÍ Ç1Ó²éù61CkWöIµ’eæ»(ùŸ|ÐÏïÉJ˜%'¨ ­ÍX²5 $0utÆDÏyP5ðDnš&MŽ‚ÈƒøGDj>ëa";Ý…£N*…-ÁŒcK}ò‘¼Í$I 5ÙRjø|FŒùt02ɶŽ*4¢³ IÔFk‘<…H6¦8Oc¦MèºGè§q’ ú‰££ª×JpqñÉñnT€–Û1¿œ×‚9!L:ñ!UŒ-IûÃçO5TbR'øGýÅ(Åó¯ãöV%²$/‰i<ÿ¡€%‘IM'G?B$ãÁ%v%eDQ¨.Vf ;¦åt\$uJŸEñ)ÂF?ýbÌã‡Ï3›þŒ|— Ð; JáÓxÓà ©PL«š?3M¶è†–÷óK[êPx NÔ„# N xÀª(òiœÀIÏ×–ÓyˆÖ’1œSªß‹š€*é( ªuœuPl“;ˆ%Û~|{L}ÃÔ¨¦–d!`èq êùz¬æ´:¢•.Ûm›"0 Ó´LÓ C/yT?‰?ÞöÿÖ[‘‚xœ=zIŒe×yÞ™îô†z5uw±›s³Å&e–DJ–"Yvg`ÄIÀl …h#@A ÈÆ$ #‰g)#{!ÙŽd3hPâ “l=×üÞ»Ó™ò}ÿ+Š]$»ªÞ½÷œø†ÿÜÝǾ¢q³ý'?ó«?úî·Ÿúâ7®½ô™Ûï|ûÕ_ù5ÌÛ?x½p³~ø_?û‹_ûàÿ÷æ÷þ@÷‡ÉØz•Gk¢«jeëjñäòþ‡;—ŸêŽÞ~©­-ªéþÁõ›7_U¦zûï?¸÷ž5FkÝ/Oµ«b¿ªË:ÇcÐÕôêW?~cìÚ’Ö1¦ÑØ"ùs6ÖZg¶Jé2.ðø½ÒÚ”Z§z¶³sí¯e«Å¥ 'åÞs7¿ü÷Î_ß=Ø)¶ö‹ÉÓoü¯ÿ2)›ùDÝyû»¶˜œ=ü0¬ø0¤´ÑeY)•w{þüä8†qºµzçMƒç¹iCèNËz6ßylµzü°{õF{|§]Ùj†³ª¨Š¢¬'»Éš¬Üêè#¥œÊV›Qé¤rLAiå´+•qK«Š¬l߯CŠÊXlÀ(\÷žøå”Glkûúçwn|iûѧ~é×~6´êãÔü_}ï;ýÙñ¡3~¾spøðãõéǾoÃÐVõ¢,§CwbËiÖ*†¹Ûeð#¦M“ÏiÔª0e•;ßꬴ)’Έ)ƒšFWÍ”µ~è–•µ]•εI)x•´Ê…­ª”F•|£t•Fô´²:ã[¦a~ðEì.Œíc/ÿ­—~åú?~÷Ê3/>ñü? c‡Å¡öð…ÒuÍU¢©ñ$ÀÂu3,ÜR E¢‘üa…ñ'Iùb6«w¯Ì.=»wõÅ7þ÷ï&8'U…ÔãZ[$ Jd9+ÔmvAqìªf+Å›üºè±8xùàÆÏ¿ÿÃoý_~ëæWÕüWÿáî[w>û·¿y÷í{ù®r«Ç³<¬Túõ¹-fˆp #ªˆýX7XŠÀÚlÑD¿V)q&ö€¤2Æ¢qTL(¼ ºdñÄËÅä`XuËŒvÖ¸à‘»Ø6® q@E±~kKS/öž~åÁOþ,kä ;=øž‚iÓ¨hÜtñä+¿ô•oüÆÖ“꽪“;§íóþâ;·ÿüœC¨ÜŸ~ùŠÁ ,eAl OÄêùþz‰~_(t‡_cOŠ)C½á¿Ñ`%ÕÖ0ôÊM'û×m¹•}D;¯Þ‹ýaFZ(,•!áø‘J±ž“ݳÃPq[—ŸÙºt}våí¦¸ûÂÙ¸1…Ýç¿ü…¯ÿ“÷ßúþÖåg÷v®¾ö{ÿ,?Ìc·:¾=®q6‹qµ1.…žËB–ꈰ†Ç‚¡‡\?Bc=Q]*n6£÷­)ÊÌV%°d²û”­¦ÝÙcJ‚b:~`Ë£9£7E£Hb¸S’ËV»ÈP·¼÷òßüÇ«“{óËŸË Ô€ö‹EéŒr¶Ü åô¯óß¾ðìÆû¯}//ãúajÏÑzÃp wõ,ŽÀa„dÄâcò“Å#ql<®˜â[㪽Goö«ûýù]ë ì—Äéßzº} ©ëV§‰ðÔ:Æ5î„K“Ûzð/ò…f}+be@:ð“D(  ¸p1›ïÖØIR!ëQA؉5³1ø_ø‡ÿ楿ûéoýκóýÿ™V”_ãÔLbóeD^!~È)ª\c²k¦{×nžÞ»å»U”ìW“ê%“Õ0KÔZN SÄ ÏE·D†X—Ú8£]B¿ànt…~ÀÊy`¯"´ `…Dâúz~mº¸|üÑ_d0š)±ÙåÏ@ïä#º«RÈîê%ªøêßÿ§óG^þî¿ûmò±_ÝÕDK¨D*A¦Ä–ÑC0±„à×Íl9®O[”e½Å©zAH(QWm7 ãí‰u&ðP&8aýšD’Ñ;1 ýdŠ ÐŠÇa“¸2b¿*M·5ß!àØ"»Þ}©™nÇmµ øz¤±ÇÓÍd·œ?} ð'~\òiÚ1P Pƒº„óLW59¬S H”Sì­«µ­óaTŽXÂÕ[ÈJômFX#™ÉqlLJ°(Y-“[\Qa»>¶Ð%€ÔŒ.êr2Nn瀤—h3f/è_²£<ÉÈͬ™†úþTUή•“+i}†Ã±}À•€"5ž="*hLC„ÄêØ VY4-n àÃoÆ~È U >rÑþu–¥å kW܆æú‹„º²(Ï… õjŠª]Þ * Fšík®,–÷~l€@`2eªž]y5Œ2”î¡â4f[î?~éů¿ûfwÿîbÿYe×ýòá=L}'íCÈ5DE%Í¥ ×Dà?zD'W7àÖnu¶Ø¿Ù­ï·«È)"YTu­DiP *ú8¢³ È E–rŒ1ŽÑ¢HQwxŽ›\zr\ݯ&ó4ôýùC”àu>¿ú*£R3ªÑÜ=Õ$$ûô/üærÕm_z®¿÷æÞbºØn^ÿãß?½ÿ>äO€öÐŒ¸AÉ¢‚†4†vOmí<|Z­îî^}$ùvu´jæÏزX-ßà¯m³ƒrñëC£@mdpÒƒˆ®‹#RƒÖF•»×¿0x*C=,ó°dýãÇ)bý“KŸñЉU3+“<Ú9›foû©/?ñÜß8ûðû‡õ‡ýòyÀÝ/! 0Ì>5¦(5”ûlIÁSÆþ [«šÅ°>C‰L¶÷Çþtl×ÖÍÝd.MŸh^tÌ´ÀŸàÙƒ`r6xV%1B<ÔÖd'Àh<ñ™þðv{ô¡+ë}ò½qnºÿ*ˆ:y°d*êÕe4ƒ †|¬Øùjéìƒ?5©7àŸ=™žùìÈ"ÁÂàö+U¾ë†Õ)aÅš0žåž2eDW'”‰<-‡â£R…vêê4bK™AÁoQ<ÿKü€‚ªò˜¢ö݉[¶EˆÐíôaÛ×¾ äQ®¤¤„+±ÚÊXx(ÒŽiP¾{ÕŸß^ß‹Há@– DÏûÁ2Ýì0[O€z¾[ìäu:‚°¡m<ôew¤bÇŸg6;U„áMÈÛlå@‘mjÄEQQâÃá·®lA¾=¥aA¬<ºÒåÎæX\û’³h4à‰1'…¶MJØ¥©U•ÅÖ^3™­ïýDõ'hCYY`»!Œ|¬&ÎX¨ôB.P{bójÄ×|ëšÛº‚Õ€úãÓ@]§ í‰‚Ç‚`T˜üF9‚~€¦¦á8ÓíÀÍ6áh´Ð IÇ%C³÷bLFX¿ b²3Å0¤—ÂV„þ(çn~õé­ƒG·ÞP«xç¬qx–­kѶ \}KE L™Ì¼?OíY½}ÙT³a¤u€zÝ–8µµ¶¢h¦\ü×#›*B´*ácqеPF¯HÚsü*ç|åö§³èC^KTG‘V-€åÃ\ç‚ÕØ=h¦óƒŸ¿{ëGñüè%0 žšèZÜ„j¤zÄè ò,¥,@ÁŒÊñk4 \õÕº‡ÃéOŒ¦ä£n$ä: `¡ù€Õ¥³‡(ÄoETe³k« (ñů}óÍÿþ¯W¼V,^`9m³Tú%†rX±:ºmܼi犅rÚ§$r¦:-oÄ#ØdQ“ƒ¤nµ«Q¢¶Ú-›ß-¡Ãp¤µàˆÊN!M¬r $†r@ígºfV ’('—TQ íÃ'¿òƇoÿÙ·ª½Ïf–]A‡ôHh•ö$¶pÒb뢜áVÉŸ\ÙF½ZRÿXù5zÏ÷kéJâG\4U3ßmÏîc*¦×|{¦Ã`X+©á(RÌ7áWô”)Ñ|„TH"|¨ °ul4`³C¨ŠÙnFú¸¤«ŸE³ÑlƒzPÉt€#² hmµ3¿rûÛ{ª;²0uYÕuÙ­—ýF 1$ºQÁÈ W å ÉŸéb¥úc'v2$Ÿé>AVlZ%³l©jvñÄq8‡B\ ÄC„_VNƒÄ-x©§{Í(<¥\Î?-b€=Ä];ô;[’ÚŒJhœßN¶/ÇÐ'G¨Ãq…¥'§…ãÏ“‚šÍÎÁ£*|X²HÅhSY ‰ó‚3ôá$"¤Ø,y§×„|¶0?l€ÛeVãΣ7º¶ó=¤Â=ÂI†¥HðEåX@G_?øN¹õâæZ%ËN¡ÆO2耜âÈM¡í?‰çŽ«%¸Õ‹>ŠdˆÑÙʺéÐu S({HE„`–0‡FŠsä*Pˆˆ›ˆ»j‘øúOPˆˆ¯°g™Ô€o+  Œ“ïåØg¿Ë\@+_n½ í#Wé ³lÆ [4C“rؾö(ÞÄ쇳{œ®¡Ž?óýk³Ùöùáí±[—“­¢ /•e³ø Q‘ÐÁÂS”AÝ¡GŠ~ØÈÐé ÊãÛ5\u½øôõ&ìYæ!Tx9Šö óçݸŽîÑ4¼!±Š³>äσé÷8‡6ží<Õ®O†îÁdk1i¶Îosµ>?mOŽHMEáÇspyQLxûŸ ‹ÖÖˆô^Ê[VJ1ÓéJm…þJ\(ÐÝY‚ÌÀ“Qº˜,è'S}V‚)*ß­Ðq¤ÖLí¨ÔPoíäq]l=ËR—Ð ¸MÏ*É-k‰Øçä¹T¹Êú²šù}‹tó ‘©ª¢(ˆ“Ã(:.:za Îç·FÇŽA‘zŠvº>gE‰!¿>úHªÅÐ&h„Àà— ?ÔvϺŠÉ¹) ½œ4~XCC¸ùÍð¡®S›A‘Ñ4í˜cT!5ùÊÓÕ:ËB¥ø$CK3ímÑpÚ ]Ä—h„ ”ùIÝ!§·ŒÇ•t}Ì4ùZž(|Âæ3ðÂp–ØD2l„Þ3<}Íq ÀQQÿK¬¤¤L•v³©¬_Q˜Ž «E:@My”‚@¾“H?•gÂMó;t«Àfö/Q‰A*—N„fm£B’6!”#5`ØØàÍ”œÈAÛP‚L’‰~ qý¼Ôu¯>iá$Oó‚;V“ý< 'k‹qu”ƒÝx<@PÕp7ФQöaÖ_Oæë³#ö%Ç­™jEÀÇ_œ‹1¾4Ô`mLÝKÎ*8R/jöޏC¨ªy6•;™-K¬¨XüÐ-ËùM6¬`Š V#F2@= yÒÁ%¼€Y$Z.‡q [zFLš”Ä$ý¢9]á g⦄(Ílka"'œS0rhs·áN±,8‚;W×9÷óGUžö] ðâ²,êªÞ[ûWÓ}BUjSópŸX ¿4ÔÂEºÕræä¤¤#ƒÆ\Z¡Kj‹üc烈ùw‚Øæ¸ÊÍ%²P4Œ*¬!Ï¢Þ„¬ ¾|•ÓE9k|á4qÅÖ°¾…,"kPÚÈH±uƒÕEx4¢¢ì@ÔBŠùš¢à’œùB>ñˆçGÂÖú¯x Œk-Y¾<@AcûQ”­Ù´—s :x"î+çîk•ªQŒ ψIÔç"‰‚†ç!qö蕬G?–TUÌ?%Yš‹p'«ÞŽ”~¶äm‰AHkîe¢4_“ï¡'=ež¢'Œöœ0€¡úg{ýò”AЄ©ä± lU+믱xEÝÈ’—‡Ä žïh“ÁVµÝjˆ!I&Ÿ22¢=·èå‘þ‘‰—!˜h7Î}Õ0]ìó°±mEøQÀN·ŸèWç1,ñ¨Ébñ©W>÷àÖ«‡Çq4œ%r_М0Ó(9S6S¾©Âãh‘Ð!xz å°@ñ% ˆq b¦Ààò(•3%EL›,ïJ\Èf6}œË¡ÃALWÌž#•pü¸ù(.Á/|ñ—?~ÿÍÕéòÖÌvü¸6ºèW'ÁÙBx7Íö¢nŠÇöðÎÝq`IŸÝšÎv}€ý=ãЕÿè¡¥ C_ Í߯Îñh Z³¢æN°LËDCFr¸ÄjéÎÙ t½´z¾8öƒ›í±~ÂÛPf\<†ñÜlSàhs[΀5Ã] c»Dê.YRq¸/ÜÜÁÕgï~ô6j¬¨9u»ŽN!CέC€rð[Q–Äc׌|}£eé Û8^Ä—Ì¢2Gì`ÐÚ‘1æ¬ f‚¥kNB§|áAæùšöƒцmMH2E!ºé -ƒœ)°Ä"_8 éóT ÏO‚¬xè&t_"T8ÃÍAµ<_£~({WQr“éÞùÉíUwnÝ´à™ò¶·åÉ~óÀq¸”¥8UXPE!Q,-KÌ"¨¥6È­QæE¦äêf76öVæ "u„ɹ›ƒ š °¶Âr †…4婼æ‘9w J‡'Ø,"è=óKJ—G·ßBÇj^KÕ凖ÇŠ³H¤>‚ul7t*vÎŽ²¾X÷ÈQª¨² ìHËx %'Œ³g©N/&$JœÏfç6sQ:D˜GKG£™ãÅ`¡Þ¿u‚¼ýšbšøù é9¦‹òê#ÓÈc8 $¶ÉW Àü¤P½¡(Ý'ça˜CÑ¡é> ¨˜xt唯¦ä …M{É—¥f7„Ôà‡!S¡Ãr– „(R0í›+y%¾«G¢ùæÞ˜Ã€z«8©Îýîl—[tÍ0„´yYDqƒ<¤O¢µÜfæÃ÷Ld>#ç\¥¼MÅsÙÝ h§ÖÕк`·Í™ÞL¥>QÆnö”œ;›rº¼w§wdF*ÃSŠ Ol"¹!,áö´€B9==†.ŠÌ×#')ö¥*®¢Õõtÿìø.žœåÇ>mt­’i$â æE*#_6àˆŠçÁv3Eçûrò9ìÐ'\ ½âÌäžH‚d8Ïçì:+„Ó)Å÷'/LÁ³Yƒ8/¤ÐÌ÷¯]{âöÇﵫ3ðòdq :¬ŒPÿíC“çíu½³Zž#ìõÖ#¾;å%™‡nJœz n…ïÓ’,_]à/å<ÙˆNòHFÝÖÉ÷r<ÍWG6ĵy{Røúça ·!8Ñoébä’DË1ŸvsX·W¸º[w {²šŠ¢«}‹ûÎÐ%;—;9¼Ë >N3õ¶šG´…4ÇbYŠ=o*\¦<ã2\PÅ~3”&ÞŒ¹›Dxo ¤†t9FÞX°ê òf@ˆµTŽL" ¾3ñÚßrÐQ8Ø^ž¹ØYé¨Ò»öðyt¥- b ‡¥úÊ3ŸpëõЯ QH=Ò©rfª J_™9'¾¹ÔðO¾ždh“éÃù)Ñ’oyf™úRo”óë¸ðBû£,/TÐÅ™¬Ì",aGmÞ>E朼9%3C˜&îÚÖÕ$å>„1©FL=¼0gôòø×lv”ø"}KܼLÅe›Í<ÒÈË•žú™qæÑ·#~^PÓŠ€çk”Ò¸þÂgqýO_¨qOĹK1ʰWT‡úé›&|{P#ßÓŒÒÆoÞUû‚ŽáÜ^ˆF²:Bœ¼ÐÀhÈ&Ô&HtþAÐÞÈ)@ÊêB›I£ä‹>+e3@Æ3zy-ÐÒÊ™²œ=™EÐñu2Íiž¼7»©%ýÓ‰®pJ$“ðí®©•£n-Á§óüt8ʦƒÝKo$qrÇ=Omœ~üµïÿY6ÚÏv®„:h­<‹Û4æ–£vo¸}ÑvÅðÈ}O|ãþ¤µ®²É¬×khUâ夹YÞšo¼ù£òÃ7÷.½óæÞæûÙèF6ØÆµ±Ê”:]eµ7 @Ž‚ÈÚ–·“¤Ù)]öÙ/{¶?ûðÿ>ŒšJ—JÏ´ñIs±œæ&j9_x_zê,†A+í,ãï¢ÄN[þájx=LÌ‘ÓO^ûøÜÞÕ‹ÕxǨ²¹ü´wï:­¦ƒ›Úh„Z¹Ïœynxý›üVO©$Ve‘[幺ñÞöÏ_xu¼^üÅKÉü|s®·í¼Œ¬›j ´:ˆU¥ÒÎ*0™Ovšs+¹ã£ÁvgíDëÐá[Þ^:o³±wcÄ?_T•+ÆS%7v¾Ò~æò¢´§”鮟l.žì\‹¼ßþЫªÙ?œÏŠÑæE,R©¬}èg­1ȣû/j†©v:ê,u×ûÏþõîíÝcw÷÷'êêMõÓï¼|é•í4sª0iœ·>_ZåñÝ*Ž£ÖÜZÚ^š;têöÕ··.,­.X×í£vk2¸¼~ï³Î5/ýßïy7 "6;Ë'm_^?Æm5«ÙÀÔm>íßq_÷ÐÉÍß^XÞßz{xë¢Ö‘-U•‚¼ß^}\é†ò‘rHhéµÇ®4@µÛËwŽGÛ÷<ÿÍí~¼rÇáç~ïÛ/~ï¯ç¿týgß¿üúÿ@y–(^l×.Þ4_M#¥QW…iŽÛªÈ´½]Œhêvo¡¿vʇË×νZM·|Ô™¥“O4—V®¼ñןûòï¿÷ÃïNWÂf õøø?üý»~òåïüéõ³¯x;„µBÝPYΕ]gýóÞ"ø ï¹~eÀÈ„5q´ç¢ÆJ¶³™Ä-¤õÄ3_ýâ?ù­ïý«¶Î½TNn•åØ)l75¨Ù@ë@)¢†#ѬW•r•2‘s¶H;½…C6xÝùЯ¿ý“?/'·•›º2ŸÛ8}êùoþâ…ÿ´¸zòöù×zk éÜÒêɇÏ<û¥wüÃs¯þ ˜Nªr†¹lìŠ<ŒNEÅlä,Ö¯ZëÏ(yè0v*wå,€TU„íNwå®áås‘išÐxSuÖfûà›QhX´ ºÚEq(^¼«¢PWRPf£ KÇntŒ”Ó«'ž˜ì~¤}QΦQzd:–ÓÛZå2§LÿØY6žn_¼ïɯ}ë_þÚ'çÔ`ß½ûóŸø¢H›Íëç~º¿}u¼{ùÕ–ÕÈxi\Ù¿÷›I²à¬Jz«E5c >y3Iæ°Â|º©am¢¸imaÂÄ–¥+PS¦5—º ÇPVe±ÏÂáŽP‡"˜4›mUÕ$H°¦F~UîÕ,J;ˆY6½È)¨>­þñÙdßÃ_þqkïµwß¹÷—¾•v›8}÷•ïL¶¯d£ÛÓý› åa\'Ò&QПwO~ýøý_íÜÌ«™Nã…£|ôÒŸÎ/œl+³ÒŠÂ2žZ7«ªò´(j£š (Û(i—“>æ3Q´tÇCÖúås?8têÁéÎåÍ (•’Qºíþá“ñxpãr5Ýž Äž‘ Â8h÷V&ãýù•Ï~ñ7ÿðg/ÿÏkþsY1ºi4xÚ`9 Ý²`•j®?¥ aÜ/«Y{yc¶¿YN&¾Ê]…õ@W|6@Hže­Â¸-~f|ë‚¶Et[VEïèCå$›Ü:P€”µV‡-UUЂ¤=¯P&ؘI\–IèòöòÑ*Ï&ÛW‘.P—04·áI 6n̵Ž=ð…o]|ý¥kç(•˜bé9W•Ÿ6Qˆ/âN@G{íI­¼5¤9Ù»\à%P[àl†‰’ytŠ)Rö?óó“ÿøÕd70¸² ÝÙ`Ü=túðÉG>úÉ’Vù/b1صËÁC£ m%Ý%UYŸ£ ]¦Ä4܂ԣøA"€‘ ”-£8M[-¥ÖV6…Xhcn }ǪË1Žˆƒf»ïúª„h/ßýµr:,32¡×÷9á?:2ü‰aWa#™;2\Cнij¸ëãV;i7ï•ãO5æ7ön|rýìòýkF©dnaí³O 7/9öèÍ­wv.€ÂI86e>šMf09oK¤À£þ Phqév£×Û8޵öW7’¤Ùí®½ÿÆ·¯zwÅhG =œ Èk ´+'Ð_¥*àþI›€ŒªJÅ +¼EYLcñÎ|´Ç‹8D¤ Ç& åÃõ»žÚÚ¼¶wëŠË§ÙÎy\Etú ÿèÿs§³¯ô†›Û³ý=[ì4º‘-ÊñÎÀ¹ëW¸—¯P*ã!º¶\F)tí™ð»ç~ñê{¯þ%²1m_¨ª=2ºõqwáx˜ÌM§ã¨3Ÿí_™ÞºØh¯eÙ¤±tWÒnw—WÇ£×” D'[›ÞóΠ³´µÄŠœî°v~ðÁµU‘J¢æb·žù{>ÛÙºøöhos8؆))rýÃA¤Ê½ß,í°·q"ˆ­«ÊÖÒÉñ ݸpøè™ýÛï¥ Ë£ñN1ÚREÉb¬J"éDMPVÔíwÝòœn]C•ÁÏ{ôWÎþ¯?úü·þ8ž[{ëåÿ^n]Ë×`°á«AH°= ]eÀj Î…Õt—Ë&Ai‡ ’¼b' ·t6Þ®ì”íóìêˆpügc»R¢tx×Xy®ÅØ?zÏt¸óð¯þ³þ?z%mÎÁ–MÆ[­ÕÏÞùø¯Mw.m¾÷7ãÝ‹ŠTBæL–Åtéä“Y±o³<ßß….–³ý¥ÏœÙþä§ÍùÕfoÃÙÈN®M‡0ØSÜ<ˆB/„€Ç‘ña™ M¼§x´ú+þZ6N†[¶˜ã=UÂXd¸­«2Gw ¸c».F¿´òtÅI»wüs¿rþÕ¿Hš+iÚß½úz@CÑF`úG¿0Ü»¨C[¯ØlØ3¸NFªÌî8ó%HÓhëú|ïäàÆ…+oέÏF·JØH V½€Áí¸£ â7·Hu¨¼oàbA»¿œgã"«@H+wÜsìg ý·~ø_³ýÛÙ`Ë–ìP¤&Ô ¾åvÐÝ`-Uµ7~»Î&igtë’ »]\ ¯,l<µ»u%/wÆ·Þ ÁžQ˸Bä8꺗H˜ vC M’¢ßñèÈDi:MíD;ƒ›¸Ye3À8ŒÏfCtÜè³)/ ' .é@[Cñ „ö¡rÊÒ?´*ø­rÕX~ƪ „Ù™_ïÌmäe1ؽlâ¤;w‘yôkpóÖ¹éðj»ÙÛ½zýÊÙ¿ª|fÂ&Ê rð±åÐåcCH/¢ÑsÖ¿P±«’.Zd±-Hs4àûÐÃG!ˆÈ‚ÍÓÑö”â*l/€+¦{×Az^ÞFWDÔcåp‰pøèVx­TQï±FÿPÇùþÎü¡û§ãM˜ÞÆ#næWŽh­êǾþË‘Qõo_øð•¿€cwÕÐ#"r–J“0áo:ý¨µ<mãÛQ TäÈ·£î þ…!Ç7ŠlêØ3gH8˜vH€yÂàÇiwíîF:ÅsƒÁ…c÷­ßóø¥Ÿ½xãƒWl5Côº–T”“cÍwïþÆ]}åÒëß?ñØo_:û£ÙàÂlç\Ô\9|ß×—ï<~×ck|ùÈû¯ªïþ៌o¾­ª-¯ÐåAĀà }iQ7ŒÓVo)i-L;ãÛç“SåðªÕ¬„+MÒÆƒ_øúÕß½~áu ‚ðÕBËÔdª8¿p þ@›±7#í§+#®Jh#´˜pƒAéZýÃAÜl]ªØYÆÖÎ0ÚFZ©^RPF‹O†‘Y»ë‘íkƒ¦kxvb…qdËW¼ÔfhfÊÇô~ˆ<9ú†^Œw©l¨[K³ÝI:áx€Š-†7‰s˜dâ$ å–~­Õ™s°¦¶Âo9ê?¹4ÔGN?¿{ããÉÎM¼‹DcGð0\0!OÔŠðN@~‹û6zËP,EgÚ@€NQÛº'(JÓ$Ô¸‹.šclÓ°iÄNQ´È8 ]ãô]>o8âN IRô•§H/}fÓ±ÿÕaÚò>(3\—¯’ÎÜ]Oýãó¯¼PN†;ª–[S)aŒ’ÁwSo Y¡‰û¡7d‚+ø7ÊM+‹]~´Ü­;DÆ›>úÁÌ¢md±¨ HàS‘5ò$¨3©@>o©x ÏUð5ò6bDÈ"Gål‚>¿Á1Æ­æÆÿÒÙ¿µYæÑö"òÊVlyœEJd:ÜœQDLT$ºzMÈpâ,l•ã¬L“sAqz ¼ƪÂð #: , ׇ·ÍøCq2Þš™ÇåÉ?ø"'†øAÒAd3¶ Á´AÒÁThÀŠ«ÁöA£×¥‘YË–ÁɆ¸râ C\VQnra#5Ôq.¤y_üÙ`±?!‰ˆ ¼ëK-Ö“ZÈ~­Œ’¾[•€â­ fÈ(X‹ÇçkM"V7Ï" Ó¤é¥l‰Þ™ƒä\‘‰òÒ…‡%€N±›£âóçzñ¸¸KÐ,Ã焽([„Rô+˜cH\ªf³S^ãF'e6Ææ \R|‘tC–äi(Lp-d–| „¯@S‰OÓAF!ãS9Š×N›¤M.ˆ8UP²~­š+hCÐ*:¼.a$YÈ=€lòƒX$ˆ&„ Ѭb¶|^®¬¤,…¤” ®³vƒq®ì”ˆ§3À[´)u ²„˜&ed™ø0YíñC¶J&›£´PæÈš©ª©•¼0Ð!Ó­µGñ]4U@>Ò¤Ù×[+½¤&|Y,lñø+jQ̳¦òQîña7q)X©õ!+ט–ö ³kgü,ËÎ \=û\$qü}§ ´±à_VºtÂD%,ÂUe¢Ñ1Ä÷8zðÄy%æ1ÃßÕg«*wŒÕu`LDZ¦&I\Å`#ˆ¢Jø1±O$.ŽX’…UèD ²„"´\em®«Šú…3ÇZ J.b©ÂBâã,þjÉÍ!Ë%…(=ψܨ*ؼŽ¥tz²Šk®<ƒÒç#VR°³†ÉtÎËPJÉÞ¥4B)E$# y­ŠãCO2ä oÚ T1ލ{vèÔL"©ž9³Â΂¯Úå<*äøû,GaÒÐbè¸È'Š£6(ÌT öjz¤YbË4VžFN0´åx¥äу¸ A8¤d"/Œ0iµ"†½šY©'r²¦'_q/î¨Ñæ¨Á‰®òþòñz¶áåcŽ7å¨/€gÀ …twܲ” Óò–›§SBö)è:]~Z¹™f+¦ÅUæî<ä5ª¼‰º© y3€„ÕÄÙ£Ö­Ku0¼B¡jZàzB`€Úa9zæÙ˜ŽÂDÃ{_7Ꭳ¸[rQ`Wð˜!Q2\$8FãÓ¬IìÄÀpÿÞ¥ +:fUÀL˜„VÔíïO†{[Œd-g„hI¢!¡~¡$2Ú™0…8€x͘x™˜êdtSà@çj¨°é_êhp½PY€$ŠÀK´ô"ܽþÿÈ·uê$#d„î‘çŠÙ@‘ ºÃ™$`;…?âÈJí3a¹¡Žhö#¶^%‚ÞPÑ^ÊN+iRB–$¾Š-×7·ªX¬/æK üQ†t€>‡br•ê&;C‡ÉØ“ÆF„Œ+ ÏôI¥ëΑÏÛœ^KÛ]Ü*ŸŽº˜NdħH2Ó§ z6Ò°±¸LA²¥Ô6 t tÐÏ“DXßö¬MH ”jÅ™0l%i»Ùí¶/ÇÍ6”(oÓïñ>d éµþ$¶ªÂmWVC<ÑG˜(…|…0BBé¢opb “zÖ„üqFë[ÖÔ²ÞZÍ0qøÐõ‘…P }SàÔÁh&„Ô4^’9Á`ؤŠZ !´ªR¼q@}g¦cÏ©x¬Ã8Hš žb¼{q­µ¯7˜®öÅ<»Ì]Á"Œ-&ΊÒÉà¶Vt÷‘ÀmCF¹(géÂCDŽ’N—jÍsö ž|H“˜š™¥ˆV1˜ŸÞÝðTvKªc¥4:²y`˜1œ€4aÚÒælx[X‚}:* ìZSôè4ù‰8XÀ9«»÷—û;·¯žÇR‡Æü*îSŒžÃ¬©J>w°vXn%ØF9˜´–o™“„„(ZÕ$LÓëò)W ÓHF’”c49NŽ%˜_½°~ßl3߯ûê讑 ñóÒÔ]EÇÉÏA«G>¸­ÄA!ËíîbwõÈîÖÕ"C#ïÑÓ‰UH᫱ÍŽ,û*Ñ ²ŸfaCÄöSv"tËÇ9hAÅú‚¯}Yð~%¤1V‚Ç"ÒðX'4BïÓôeÒ«ñÄ-9}M^òê ÷Ú¤©Sas^—c¾‚®!j𤺘´Äi›Cx "å<ûˬò±~ >GB ±Xž|Q Ggš3²LE,Q}Ðþ"jŽó#ߨ„t-îÎÕöXqö³XøŠsµ¦«a¬8¬DË€Æ5ue!4¢¨vïH˜6‡;—yø+u".݃ñ^Ü?Åð+t‚!QÄá{%p²&T€’nÄð–>meÄœ)‘㺮;j+ Ö ]íø…”c¶,@ÔrÀÓ«Où\,Þ¥KÏYnZÆbõ:Yþ!Ó=EG@ée´ÎqtÚ]ˆ›ÍdáAÁ6G|brK)ZΖ L®[¢Ê†–Žrc£GªŸSa©j}¨‚0E…‚d¸7]±·Rœ¨Ð'ûJ¦qœð²a"°ãÔÑ…Ïd¶lj³j$Íi££ƒ$›!ܵ#÷’]·ÜÆÅóŸCH…ÆâZp¤Ð”˜(-þ¿n5!-Ç þÓ–à`ð"TÅ0wÌ# ‹öÍ•3"ôZì´÷coéŽAƒø7-¦C¡Y]÷#„¥3ud8xôi«$ñþžç茽œª“ÕÒf«ª&IïQÎv8 jÁ%éJÂ$i™–Ô¯¿Èƒu~ND2øòÒ,‹S•¿Ðº’f‘¬J¶[OŽëŽÕÔ >¾4Êr‚%á—(nPÀ*0-lô#S 8(> È®%^®8/¬nÜùÀã ã_R’Œøv[›/î‚tWŸ¸1ŸZÚ$ŽýÃzø#£l0‰#Õà®Äƒ“'Átyî"°$.Ϋ•hˆ¯=ª͆½”UÖHéà8c$,êVI*X£íÄRâ¸DÁʧ£îiqØ)Zë‹I«%óIy8Á "^ÊÎêT=¼ü€w[¶ÌÄ€™úMAAÆhaAT”‹ê/S£„“#S–§bÜqÏöüy6‚®qhÉj(O§xöE).•É¥b LXUÓxî »ZÇΚNC†‡âù]9)pBªl ™Ò]ý¬:͈hmݣꡈ–5yiw9¸c ÉY—Œ‰Ä•9Þ‘gÐJ6ÀôÌ{hÓâîNºTÂEÚõIÔQ¥½éÞ¦[uÏÔ‡)š#ý¦Dq¨dÔ`„ËÚ¥ð¦–ÎUðLؼ—¢BUsnÍVc§]ÒéO÷7Ù ²x2Eá©¢ ~$N&‰Tçã±+JQ®~pZ¦ éÃOµ‚´[f»Z&E´ßm¦Épaç4×O–‹$HGÛ#äÎé /&N¢ô ×´+`B˜I´lœ6Ãø"m÷+›ÛMG–a–Ðå:ÊY%'6i·cúB“FQ{²}…­R=ã­g;ìÓ)Ê ¸µXd{2D•ù¡ƒÆ%ô¢Ø/lÖÏý:A³i¹X#Ö½î¼:°ÑÒ³£¼ù‰=T¶w‚¤›íl¶zë³ÁfUÉ1\n ^ò¬á€1¶tòt<ÒÌú’Û ¬Ö*ìžó&gK ºá¹’ÌfdLaë'{E½i\¸¨ÕƒVŘd&éSÉÓCr)g2ˆj•Ç1á̔±ª màdµ2 jR•Ó¢X+tA‚Pç2d5¹º0Y‘øí4êÞ0À—Î? hÂô±x6ž8|Š¥PF |¶ÙqTÅÖXhÎÏ«ZwØ~ÈLä#ÐõÌÐÄ žV°šäStËy{/ðxȳ‹)(ý:eù¥µ÷ßþø¬<0Yp|AvF_ÙdÞ±ÊÞƒËÐç{b”´–uPN^8s«§÷õ„³~à0e¨;àÀ9ÿä…ïè->P†ÂAt.FÀE<ÿàiò-~,ð÷x=è¢^¿ñÎNÆO!€ù<Îñ Ž<¾‰tš'sðB!Ôz½ÅN¯û‹—^|tïÎùKïE¾‘5øbeQ'óÓ‘ªý> ¾@K<[ù¨çï®IC_;þ-;DíG{å\û’}[„‡× Þ,òÄ9-Øõz{8XxñÔɧOî¿sé´*ª¡`f¢ý5üD ‡d>_Ƴ{½õœ‹?Œàñ¾•Åy^Ûå5íüÉËbôŠäY²@ò:¹ôY k |‘ |•P¶š½aw´ytÓ‡Ù…÷Ïð÷ÕsÖ2Ôäâàäòd±—y'ñâbŒÙek7û*K£#88(A j¤cc(¬²\SÁW h„9~Õnôú½áúÆúxyñôé׿ó9ߊît'2³ÆöË%“?½AòJ‚K º±8>ð’·sö`Ì(( Ã.âŸÏCûqÀC,Q,(vœB½Ö`8X.ŒŽl®¿qæõétŠPdÿK éU5ÐÛB)—fìþ¹ÏöÓù l]!‡†W9k8o㜽Ê'KêËäD‡ø)jB_“áÿC»ÝŸŒWFË‹ã7ÏŸÙŸM`X§;‹ýà YZÉÐeüS d’RÜ|2cM\î2²xèϰý>Æíg4FN B'RSÑi:ÝÞ¡•µç{íôïžîï)ÈX¶‡²(•‰ÌÖ*–øÊžì·¨'çWÏ—ÄÍ-¸ ÷²¤¡WÐØû™Sí¢e`ë9ŽäÿΨÓîZ;¼±ºræÜv÷v)@fF¶ß>$ªHÀq†~J4ˆ¢%+‰Ëržxv8Å‹ÌÃÄ E´ïæ#ß- é::"%ðÍF·ÓéŸxáÔÎîƒO¯~¸·¿/,âŒpðm­¨ƒ­$zgH k–’ÿ=×аfÙïÌÅFBé—D‘ž(GW±D„7Š• %­À³).‘)C½ß:´Þé7¯}ö—ÇÛ=[Ré8¢²‰`ã@Óª+öÍKö ‘3g¨p—@Ì»0!‚JE†´oq ¢#p݉°æ&eÎáÅ\¨•µCG^úÙÉ÷Þ9wÿþ=I'…+ߨ^6í×û8%Xö¹O¢JìAŒÁRŧwÎÊ„áÇÐè¹XKdC®ohˆ@c$/ç>Gü#HŽcÅeÙXY9üê«¿¾xáì­ÛÿÀl0ªäU ~&Š0l(ÿN"mßjù`¨È!Ž Ò»g¢vùJ}z¦ “µÂ‰ÇÇ‹V³¿¶¶qìØæ§yÿöï?êku,çoðÉÿÉ•RdÕÔqœ;Q+’â r+Õ³T¯]!ËB 0³Ó‚Ï2qËÀ Æ´u/™(hE½Ñ™LV'ãÑ×7®ýûþ¿l,¤…šQ:¤¤Nl`€Å(¨ãÌ“ ’Üðv1Áž¨Ö“lAõTì„=:?ÇÀTÃä@é(ž£ÉˆÿÊf«7O:yóúÕ_oy±ŸÜ :§Fõ+¡E’¯@IL j?é7 ƒW% ¾; Õ8g@TˆxYhÁH‹,ü óŽl&`•¦ ¡›”|ŽEÙîõGã•_¼ò«­O?øbë*êÕÈÊÏ$˜Úo¥SÊ«<[Y&)‹2`ÙcŽY#Q¥™/jÙ¢À9Ë‹¬ŽíšNÓ†Ê-éäd“H æI&óV8YyéÅŸÝøìÊß¾úÝ¥²X‘*iù>Ùoõ´Ú'_Çuûvo -ýM˜´Ÿ8AxI’g#J$9ŸsjVì5EQH~_kw‹«§Nœºyõƒ/n\†‡$õI?—Õ‚+ 2{LÎQ™F™Š’k*â+$H„ X±”`?‡xFüìÉö汄‰"ä qWVvûãñÚá“/œ¼ÿÝWo_~ËsZcáHž@D¥nKíQ~¨,oBw‰,A}õDTY·1T<$9¢…\Y)]¡ho&ïÏ…~HÚq= ÔÛ½Ád¼º~âÄÉ'wo{÷Œc.÷cö³X±¤Zã5J^ÚÞ¨dž%fRs&ª5a“Ð7Pi‡–œ™gÐ3uæ'd?+jY›ö:‹‹Ë‡Ž1ü¨'kDŒÞAНE^ƒúß4ObBHöW°ç´üñ%|¢dÑÏRº%¼È‚"ó)…KPÕ†gÏ j )5pf¿;Õkåd4¸ùå¶àñ9÷þ|ñ¤2>­ «M¬ Ä~ÑiÑšH ød´éiPx³òS.eqàätúu#ÛŸÍØÙ¬Š¹¿&Š4õjµLàÉä•“/¿qú·ÿA §"M5ðà'á&ÙÈýcÔùIL+µí@Ê \;B"ÏT–ùË&"ºÞxðø~A )@%õÝS„ åõê·…åÉÒòOŽ9{öõ{¾^ž¢Xãù[°1‹ñ§*L %bŒOü É`m<­ƒÎ\ˆÙÂZÍV³Þ¾ÿð?X¿œ !KNjÒºíÑx²Úì4×Ö7>¹rñÎÝo™¬¢B"Î?Y½(UH‹èt`Âdβ#Z€ÒØï²ý*ЬU¹gƒbhÔkhÿÃG Àÿ±€Ñ“ä+Ø‚XôÚ£ÅÉJ»ß=úÜ}üá»·þqdòh¼Æó7ó˜:·ªÄ’[½et4#Óx(VJ¹îÚOAì׫xÑÖ±¯zãÑ£‡œ†ž ßFähIú­ÕïöúsØÿÍÿüïå çnÝþŠ9*©MW§ùsθƒ ÊÌ 4¿¼8U§R†‡y¨—Z$k½5鿍×TÊ'»Û^ .7¼\åQ¥SïM…¯l·ûƒþóâ׿üï¿n]ýòÆ'ry°|#ûTø3i™ –å6nì² 3šû½i´,‰øëIPð@ .W¹^F¸À"r¡/¸_Ãú»¼¶ñd÷Ñ+?ÿå77¶®o}Lõ—gïruæ°‰[Æ0¤lP•xL¡=Šf”v–7øyÃ`ðV}t‘âoIÆí­„}Gö£\ç–6 r¼ýù§ªø }á+W÷<±Ìþ ™ë’kH«€ DzÞéž?~roçÃÞU¶±I,Ù_×VÝšÄ"–H"³ß=kê ‚@÷l.!–Y,IK …ø”@ÁR½VÖ{ÝQQ+77Žu;­·ßydÀæ”ɘÿ!¯ÑSºRkI‡Ôã|Š™U•sj?dË%¢1±øß:fQ€Nª¿ Ù¡³7£²z½ÙíðþKKKkË“sçOóÔN[`/ø‡Š­ÿ*T —%q>›¢8±•æfDýO?оbÞ"³b(:*¡Îìxª¬NÑý­PªD½YÖÊáhpxuõÒå·÷©piŠ[+êæë,—~¬Ü jèÝ»SŽ1Ôç?UÙ Õñ‰ñXð.¤ÈȳÙÔË|/Ï–W± }1šÖkz³Ñí¶WW–>ùøƒ§{{Î¥bÄ:Ê-@ư7‚ÌOÊúŸñ#ëVL¡¹¤qòŽÈÕyè´ªÙháûݧOœl„Iâ‹@å=I< íGë;½N»Ýêv»ûòó’Ð GüÛï• õÅ•ûzé߱Řr ÐCiDåÑg%IE•잃¥Ai£ÙF7ììlë|ÌélLÅ'íÑ»Þhv{½Þ`Ø(ë_ÝüëÎî#s¾—þQiY'0Yøçº#-^œ&ñ|ÎÉgùÆXö¨7&DMaLÑï³Ù¾ÊR=‹‡"–˜ÿ­Vg²²æfpóÆgÓé^Š: ïòüÓ(©ZÄZ–(@àm{¤zBÚ\q™~}ÞÏð.é,Y­Pã%)oA‚·® dØNÇjP]·Z]äÿÅÉÒx4¾tñÍýéžóÖ„xá³'ë½/_ŸZl'Ãó„”4uËeJS4%î×X,luÁ©"ÕÍP!ªØ§™a/FŒQ·=huzãå•cG޼yæ÷;”/2B!pýͺÖ= ã¬Òm#üÛÔ¿Ú/$m$¨ŠV*¡ô!M¬ÅKR‚µ?Òº¤í9ðøev¿¿0Z\8ù‰3ü¿ímg»ÀxZ!ù›ÆöÆ*Æ¥…z—ôçT '‚ÉYÕ½ÕpÀþLiR‚¥ ˆ¦º¬!¦m`ÑÙ\£è)ŽV½5è/,LÿôøÙ?½þCû¤«Œ>¸OáÇ…_ú(ä£+ ær £¯d€8"õZ±’Ý^_¶r›+–LŸs9B¡<Ðÿ£áÂâÒde²réÒ[·ï[¥àþ—íÙÄqÇ T¬ûcûçd¿>xÀ2d;ÌpŸ+ ÍHÄèh#7¯QÂá§ <•±´{Ž:”Úp¸8ZX<þ“ã.žû׃;<ŒŠì0¬¿ [¯Õ/µ ²•ÿgÞæQ^wybz^ÃÄÌí!ƒV“Þ™„v6´„’ÉéAq`„Zhöú#l!_|ùå/ž¿ûý-¡ÈjÔ¿hô3óku‹ô‚$ëÏÈôñŸ œR4·11TRDb¿Th¯ÛÙz@ŸPÁÎQv2ÞºV6ÚíÞpa|üùã×>ùàÖío¬ü<3?©•6ÁhH_ÄùœZ¯hIbëìLYú#-|¨ðg°AP—ñ´$HL•éhÿ¬(ç¼Ñ†¬Õì ˜ãÞþûí~+ûL²r៊ñý˜^h}(çó)×hÇ;*2¡³QÅû†~ƒìzÓæ£JY{”§Ý}Þ ÉfXݬ¤‡^ÊZ­ÝÁ.~q}íð÷w¿¹qóº§=M­,èô•‘a…<àƒøóù,#DS Þv9“Ç•ºÌýЉm-¬pÒ^ïZP_Ìê§~ˆ²}I3ÐZ£Ñît†›Gž<þ÷µÏ?‚Êý´þæPfŠ~“þqæ2ž}ú>Å *Z¢"‹¢m)(Áâãµloƒ?ÎÁÃm™Mø²Ùè´»ýÞ ƒ,¸µu L+'ûs嬸ÍòRìgþÓ?&ã!«€ä|­q¦îbåŠÒJ–)ük‹m‘Ð)³‚ƹ¼£Äá(<â¿Ûh6†ƒ‚åúÖçNä,çŽèçgœn'¸èËOb>éPžM²f‹}(`)œóÙiZ ?<æEÚÈX‰'Bˆì¿hX´¶²4tÿüÑå92‰Aˆ÷/’é Ã:ö-¤Ý Dssj^ÄÛ9u¤4§&(s¹d€$#x­‡¡ÒêEQÂ|ßDøÈþ­´ðŒÿn§¿¹±¹´88}î÷ÓéÔéôâû“ úQ:Ùâª|þ6¡"í/&嚢ÚD§ëóÕUÅÉF-S>Ðs ñÞµe CЮÏ,û¬ñÝþ›¥½¨ “؃6“ÔæU‘4ótë*ÌH]õ†«ßDd›Ø¼Çmé%&Sšð¾.Ϋã]Ƈûj¹XvÓ†n.7`ŠÆ>Ųíø¡ê4»—{Sï=Ôl ‘`Þ®T:­OXOðsj¬6ŸWc<ôìDÔtÁp—/ë$Ã-P`èZç†NÖ€ó!æâúçTëÏÿþ±†Ðp£«[¦(ú]z»ÃW‡ïgãô’ÖO™vg =–$‰é‡)pƒ¥—óäï¸d3œò&¡Ý W¿‹lÊ ËNLÍbâÎ%»€[Ô$Õìeð Vý8æ/É{rd d£–e^ˆHû¯G¸ DÜÂÑâ q†‹ Ì%á&`=@¸ßKP9Wè #N"¾¸R1àXñ#›ó+La8—áL訃ٟ–PNs¥É«ŸiT$Ûð²¹G,°ok'åoDT…ì×íåå§××ocÌû0Ò÷¡]ec Ïc¼0&¼Qx ¾G·Û;P´#Þ˜üÓo H%ÿn%L¯ÿ'Yݾþüþöçãý$²k96Læ¼Í2 »ËÅÐÅsW¡¯Í¸q½ßÉô¦ÛSÈ)!¬™Ûuõþx¼Ó"Ïy–‡?Ž|ë\—‚‘žLþ‰äŠ·ð’˜<Ë6Yö÷,S J<ƒ7ó5·‹ON›?H$ì³rÊ€úŒ‚Á}}pþ™$ó)Ùr*;| @ã3úÍ3ŠŠÐ.S²Q½Ûb†ÉRa¦Ì7xÞ?B_'PAYáÐcC%?‡ ­ÌÃ%Hl—_€ÍR,Iy\åŸüs؉-í¦ÆÈ„Šrí u«‹\&ÏYÒxê5Qô¡ò7p0p+ÛÐ8J¶ û}¬EîfÌà9–4³2ër>°¤°dày²ãƒÖ¿· Öu‰¯îKø[6)´Ñf58½3ŸZ*X}Á˜ð |«%¬K.»ÑŸ,åU0¡Öç¯UÿL)š*îž‹‚~_²M´||w7ó½Íóò}Láµ`cdá 7-Ħ8™+Äàâ}+BDXJÚ«‘E~.*Cx°sg;?ES™“­cVF¨³ú_‘Ÿ8ìzŠÄûYæ(2qÚÕIø_EifÞÆÙà$V-Ç´Q™UYrÓ3k¿çŒÿdêó£y*ïd]•ÑØê4/oœr=ôé°Z¼Í„µ~·¬N(œ"‘¤½Ø¾:×g‰›w*KÑc5 ×EDܶäÔî›,í1±É?¨(Â9— ßD}z°…l.= Z`0Ïvi}®vÁR5 ¾úL4}Uæp€MxÿóÌRèçtUþfóâäÏ ½PͳpäAŽöZKÅÇJ Hª8)Nd‡´8^ŠLUÚ¬ÀK‡Gª^nç§üEhÚqI‚ÙËp†Œ\zIÁNö9b!qžÝŽªÈÁÿå£J,ü¤1†WðÂCexyøûÂ^L¤WvoÒnÆ-%BÐzϱ6,ÊèsÚ¿}â%I;jHQ·‘÷¤B1+zcýÂVxæ|êØr²áñM5*챹修۬7ßÞ^ÉÕô7ùYGc˜b”•ó†€$»|î\D Ž–~S饮\¾'f1NöÊ|ª«½Ü¿þø_~ý÷¿~[=Ì\ùÝÌ{º¥»Uö“×v!˜»#d&kýÙ- B±®ƒsïJëÊp`k ²Âf¸Sv“¹kÄ à«ß—PîwÓ}ªà!KX TÉz¥²ÿ{%ôl“Cäλ.¬D ¡4¶Ü2Ò"U n«È\]÷YÄé„gI|>“u¢Ÿ,…d8êv휌²P}Ô›` 7crYHj\ìÍ.ÌBzÑžÃããÝûõ²È«¥àá9ÕØò0ú¼XÒ&9¯<ðYf+Ø>dDe$\:f©ÞÎø~“˜°ù±–Nm•¾m… DgÄ` §=wsšÌ¸èîŒüàË”‡ü+Ñ°ŠŽFPý9W$VWß² æY–»¶È>ŠâL…Æ1E`‰AÙc¹Mû‡uåZfnXªh8¨/Pa#Ö²!QÕ ù™J'È©F#{ú`Qw¡ù`I @'iýÐ/.µ¤ìm¿Í—?çÞh,t5ùG^ y:@§n;riÉœÑZ#âËRùZ]qFJ”­ØÀlFF“äÀ²àèš¡«^!é9Ù.º$éé=K"aw•uýR÷¹Jc0|õ³øÍ™Ó#­£‹Ý"(È#HW» Ï“®¯ØnšOíÞrKWæ) ¼oí¡ÿÏ\ª /ìùH/eà8MNdý«ÐW¨Ø½ öžV |ìWnÀtTTäú÷Åèx/ W[åm#Ô”Ê'jŽx&3Ò69 T6 œ‚Œ ‘`l)*€B8Ëã"Þ!÷JKps¶%cœm½WäßÔ”Í~N•èQ v‚UË;O-/2J¤`– ´‰*­”2åÛÁµÿÛ×û«¬B¥C˜÷Ÿ"DÛõú±¡š'ðuë8¯óq˜à]‚ýqÀõ¨¶wЖýÑúv’©Ã T 'cƘ‚±O‰ÇÚc÷ÞJdœPLóá^¤›Iä»õÒ‚$ЇDf13—ÄÕ,'¦$´ë¼0·ðÌP富²U‚áL¿Loï Sp¥+¦ÂŸäuÕàŒbâ\ñimï 8P°2•*?ö‰â{xíÙ¡ú'â#ã"ën°:ëD.¿kÔ,Ë[‡amäÍÀé@c§«g¢1U}T¬÷Lˆ~)‡¬dÂû¹üâï¯nm^ö*EK8[Èk_¢¤‰lè nÆ<s–?ŒZÙ|^°‡—›né|sæ|Ðßßð50›ùÊ´J vé»=¶’’òbp°Vº¨Ûø4噯£2E9T:M¥P4,GŽ¢¿6k— xœuZÛ’ã¶E$¥¹®ã²'/©ÊSþÿsR•‡¼¤ì$kïÎÎŽ$Š@§ï5Õ^DŠûzútƒS>$@Lôÿ‘¿)Ñ!¡Ó|jNù˜ÊL9UÜÎ0sÛ^ }Áv’ë3ý©ÑåîÇéþÏëË?ñúÉ׋ÿ}yýNÿÝØä ð€öc¸5Àï¥ëR& ¡”ƒœQù3ë r£®H%ÏOeù±Üý±!ÔÓÇvý]î\Z}Ãísjk$’ˆ¾ô·Ô.²Æ(sî™ü Ò™àØø îmÙ?¦R΢5¶Rf_,«À|76U.œ–PžËá;:Äv­ç_p{-e‚iÞ®¯XOä@ÄXžîo"ˆ:°{:Y›/u‘â.p»&T§£Kj6GPÍîùõåc)‹(Žj º L}[%Ow Ž &Ä~Êóc½|Äí$ªq\Ö—¾‰xbC¶t•úõ…ª€~Ø­òHuIÊeª×«\eZÓ‡¿ó5ùéù‡Z/SYTn4ùUeZ®!'–“ªXwF¼ŠÀhö´°áRR$5»†Áî3ª£d…ù2q¹+’–ã}J[½®÷o_ßêÖTú;‘Ç· &Õ"/w%/É-’LbýO-‚,!­ßšüÀ^gÉ£ù¨Ð¯ojl4ØÝÀçÑÂûV³¿‡˜5ø¨ý—ÃÜêz8ÞAš¾¼|’x¤G凇çõr^/oôà ‰‘EMõÔèzðØJiƒQA¦k¸ˆ*.êM&ò‚mÐÅíÏç)zðp7/”\WZÿr:5¬9ú÷þáùx|üí?ÿ"û—i:޹,¾${„—Åp¤Šø3B·ª8!ŒèMþ—MD®Áž°ßŒ(ƒ à¸q8 —§iÊ¥´†ÛºÖÊ©Gö_w¢—Ó+ÅÈãÃcaùU‚ÂéÁA®y¬ÀÁ€© )Oo`È`¡¢EžäÂßHžÞ9Å.(YDìAZœ—…tdá1 *³e?5"¢»Å²ç£C¼g—¸ YTAg\bpÔ¤ÀÀÐ<Ñ#SŠ p°ñx#{Z‰HQ7“gÀ¸«PQ&Ò^·ë&H@Q´%ÆŸyàTÉó èïÍœ øÙ¸L¨ü£<æZ4G”ù@,K<ƒ#Ú»äE;Åqª¥äCÎ0ãå@«d?ÖšI’ÈbVÌŒ!á» –Å?½2G|¡ƒ-íÐТÂÓ'õÏ®¬tcó²Å),Æ€*"äX„áÁ*þŒ%Â>r6{¤¸:œÿnsË¥ßÌ–¹C´Œ²·n±^æl9ìÇ)=ù´üü§¿žN/_>¤Â䥿? Ë8ª0f“pBãÉÉÊ ×hƒ#O˜4G4 X¹‡ÍΖ!`t³C.:?ÍÏËr$:Z·äß®ÑBÀ‰úGÄÊu=â)E[W¡¹—j Öw‹Tì[ŒtTŸŽáØß Z·Fx\¡E\š‚¶¢Lfü¼6C.yŹîÚµ¸ý‰î3ª"ªuHñ·zøÜØ’+…ÆÊ$‰øÐ bsª·D <ÿáoó4ÿþÛ?¸=äšÛ%c|ù5P„  ïM£ý<šÅötK&äìi5ÝøzІ¬â¨™„^ik¦ HPS$Cš·)”ÅÓÝã_>|øé¿ÿþ{k«0ÿ6FEæNEûqÿv•ÂØ¬êJËéU Xî¦U¥`§½·Ád²B-Ø&I™1Xþ7k(©'X2—ÁÚdž¶g %¸QO©vWwÓ Aªùk Ín†Ýøq`kŠ``O/ɨf¶¸r¨ÌäJƒ3 ó”D“šÒQ‰v8ˆ—%~†à¡ò¢³¸ )èÛÄ=¦qu‘±Wÿ$]dŠE„ÀOÔ±®—/MâÍ$1Z%ùÒ¸cåŒ\ˆ)­t$}³‚ü€QVšsÇaÐ^s 3È6ÖÇ =ãÐV@H‚}c<,6L#Th²ŸÁPÝ{Ÿ+74‹+ƒ]¾Ù¹4'˜H*=7b?fÆZE™"Ý<Š|¢•0]SEQ`H!E+?Yô²”GôLC«.½ ›è#¤˜vìU»Òs:â^#¾${t˜.Òj$ŸÎßÄ”aJ^x(R–×/™*ë'a»U.›Ð&vÜ–õüuâdiÁYƵÏt.Dt8ô’EÎÒ]›˜WÇŒRàú#¤ðyi2Fý-%ÌTk»\NJCÆþÂM¡ãþjýK‡ž!8eŠ«ã)0;(9äò„ÜU5]WÉ;‰OH5QÌ@dÙÔŸkl†ÍD %ˆbn[5Ë„àv1úp†©L,1y1É1†Õ<ÍêDŽê¦;5ÿÍÁG&™<œ„ôá1ì!¤ðjÅ9(!ïî/§3Qejíã´”$ƒc•ä†iZ¸FÛ¬cl„K½JŽ6vö•l ï^Þõ&»‹“w@¨ÚÍaz=O×òáp¼^¯ÛzU†™|Jòؼò]Š»u#ŒsWÎßxÈžÐq5X‹gE€#¹ÏÙz@YQsò‡~*æ™ÊWл°º×Øït’2‹?)qÊÓ¥v½~F¼v—šn3‰ ªáßÅQ×<ú¡s#®ÃH:DHí e¶/IÎQªÝ.ÔZ…·OÒEŒ>k‘E(œäõ«³è’lðf¢6_è= h“lÿ±uñûXrrN“¸vÍ$êñx¿Õ˜êæbá)z®×µÉègœ‰=U~×ÇCKò4¬™ñÃÊR‘xª3´±šMrØv€×3t½’í›÷¡ß’tm­›Mˆ©Å×rÿë¸íF‰Kºë †®CS75*™k«/ò¸Ð ùE$½À5DÐv—ºE«ò`G»ðt]ð?¡˜•±¸lºs×l$.B‚ãgvëF‹a‘•¶1I;Cì]›~Hc ŒÒVÏFL¤([b޹eþï¤]"‡9’ä¦s$¦ £•öÚ$òû,Â+MPÄäC¤˜tÁà†Ad[œí8„Ä[H9¯ë*½X®2¸šwŠ´6Ü¿,d”[²¾¹?z÷Q"m ²Aelý;Ó G2#ìGycsŽNÒw(u;«³l0rÛE¹WJabòPj~¾~æ}É"ø3pŒ^BÝt´9ùÞ¶¦ š›ROÿ4åªZc<·5t¨=gò¶­oÚ×kí⪠¯No¯×õ’¯²ò–æüÓk“­éüÑRÁý¤m²#—¶øäÁæ`ãö—OAöÇBß–F°ò8í¾®'jسLþu½2>|ÿÃëËïëù$ó€jÕ¹ÓȨÁ™hÔ2Wl”?â§waþ/ö…:òï”wÀ¿韼Ò~P7Œ¸ßMµf×Ö®º»m­„LÝùÑ\?2ÃääÑãÇå—7ÚuŸ#CmJ>0ÑÁöÍq>ës:ŽÓ|xûòÉ †SÀ(dÉóñððúõÊ«RÑoÑìß—;IvÆìý¯*+² …vÖmŠ~ÑšhÞœÕEÍ1¦§˜¾®'ª§­®¾ HHËññññ»OŸ~­Ûêó5±liç9¨QÇèLB2±qSêðÞ 8äÆ%Ú› àÓ]Ü+¯#DV·°=e<‹^‰eÏ.}ÿÓÏýÅ'6µ£‹ûþE¤ê #ØŽšÛÜcC«&S •û‡= œä ?·¾½Jrv£ŠË÷i™çe"üyùô0I¿/­“ìÔCža'z°ÊákŒd+Äb8“ßS~_2ÀS8G!{Ç@‹Õp%ÚXF5 Ô‚ÜÒLùºn¢º¿ä Ó-A¸)Öq Ž•³K’’Ǹ^\•[õ©rTRìÚ+L ^¼Ö¥¡pì åh>½˜§…–~YH£1"nóަ!ìǺ ½èkûÑ‹š¡x´gSÐ>œKý£öÐÆ9UØI!6*Øó¥#¤D•G5wk{ùß|“w7Èò¢[S1¥cÆyÞk ²$*éšvv޶¸»¥;u8‹¡¤Ú†iãÏXßW"3¢ò7ŸKHt·+î#L ·fZˆþ|<,w…¨NÛÖõ¬¿ûÕŠÏh£9Üy§ñýJ Ê_ŸûØÙhÔ/1~NVRœš´ #~úç[òs–éÈBv‚J¹;¶m;_Î3á¬ÞÁ±9núÆ&¦ªÁ]Ï4ÔØðæÎvj[Ï_ð ‘ÿ›«Ø`‡µ)uG$Ò>O¼êå²n›M‡¢ hlK¯{:Ú|5·lÚ?.‹š0¾F7*í·ìÅÈë»Ñ"þûÛêŠ'TRg”ÓéÜÆ®Û‚Ò8ïzP¾Ï—7¯¼iXV‹;}‡|ùæÓíÅ* h"(TweÌÁÀ³™WT‘üøü¼Q~¹T3~Hµ#-‚…:zºý|~kµÆ[4jsa/üOßø8‚öûüº¡°ÅûrixuÿŽnRÆ=>=ŸÏ—Ëé4´ƒüË£ÒvécAÞ!Ãä-€ðktÍî™ï´Ë ~Šº¿#ÀºÏšQ + ž I»‘Êïämίüz“p Q>vƒx}…î§“Zú 󟰈{C!ùíåU§¨òË£awµ×—Bw´ŽŠ<˜:ïÏd|îA:B;Øõ¤7°,)<Í‹@SÁÿwy½+ÈÎÙr0 ãpmóad½7(#)þ,Ëôöv¢Î‚”©Z0'_YkŠnèd{+Oô²p cÍÃÓSÝÚå|úvªƒxœeZY›7rÄQ…:ú˜^¢¸ÒjßvŸýÿ…í}°ý Ï%ŠÔsôQ'G$PÕ=ë)ÎôÔ‘È#"2çÚUAic´ªëvšW”…-†qÐÊS¯4þSUµ‡Ñ‡Y¥T|õî¯:ª§o¿UU1û8M¾(+kb “-kïM˜§i:{<™wGÅ/¾E~ä'òTË£‡ Z§Ï5ÁoùyTùCþùüƒ å.>4EÅ[h¢Ža~÷îÇãáÁûÉÚÂ{ÿÝw?<=?tý ¶lwïO_åEªtõþöÍÐwC¨œ›g? ½±Ö¨(&˜²ÞŸ¿Â€üÒü…{a¿‰éåÊèü« ?ê˜>æ§òœ˜V-ö¸†_²¾_0ÆZ'¶Ût_Ûî†þèƒ—ßÆf³­\5öC?Œo?üãþ˯*NxëÍÝ«çǯcßÙ¢lÚmþ||ªª ŸýŒwÛ¢òã(¯‹‹ó£øÜ¤wEµ,bù•Z¼ª—[¢ ‹óר)cKþ"L¦XÕ{¼4hY,~•‘,‰X ±¦ Aï^ÿt|þfTwùèuˆ%Œô¾n·¸ìt|Ülö³÷Cßc9ÁÏËÃâüìÌdŒ,†q!1¨lA¾^/鱄ÃÈéÿº,k<`ìOxÖîî/cw ~*Ê2å'²6æÀå81 ¢Ú½ú¡ï{ßÿiŠâý?=ýê‡ …O«¦}~øR”®ª6]wò“x^lË9qqÎú‡O¦¯ƒÏÕ—à›õb…Z.6)!±êºÙùyÇóööûöÏ“±:Å®¨g?iÛf¯SÕ7®¹íž?†èwû;Wºãá0O3‡rèNÏZà‘?áRwK^§Ç•<™Ö"ocä_qÉZ…xm÷šÿ5[8\F´Á Æúy¸{÷ãáñæJqI)˜Hü€¼*¬›éÌßjSÐqfŒÃd†²*«Íùt€+ší«¡{ös£_âŸÊ3EO²E]ÒXìŠWù¿|®ÕU½¬©—³Î Z™¾ƒ‹Vêí»ŸÇçqì$BÑàãðž²,‡¡ãë¬f]lQjF\#ë¥ÛMáoÓØÑ3(ÚÉûP5ERG*¬Þϸ‘pF/–ÇÕD¯± /Îe —h&[ƒ’Œ3Ò¶wwo~øôûÿäDW ÈWÃùÉÈÂ\¿µmÓ¾óæÓý—ÓñXU-ïß¼ûý—ÿÆ¢<`ÔÉ—ðÝÛ÷§óñx:…xÙ+³´ø)=8fÔˆAÀÄ,Y´D$fܿܭŒJ‹\¢(êíÍëóù0ƒ­ (Lö}VKcÉ\1]:Þnvwo?üòëÏ äžäéh_•å4Í#kŸFT%œ ú eeçɯœ• 3‘Tª+±'’V2-áÒ:›ºp„NÄ)+—ï™–Ö9£ 8$´e`1öBAË2U³›Æ³Â5E-ï±&¤[EÛl€ÇÓižg$œsHÀ¿«·ûçÇgÄEnñ:óhȆ‰ý | ËA™°ÒÛWúV+G3« ÿ_ÖM˜ƒX¨cÂ^æ!1Á¤<`=×LȺAEð^ßP¾kFD§,¸ˆI4BmJ¤Ð&ä©Ï*"çK\ ËÈŒ „:ÙRÅfü_Á6gœ•'¬K@¢j—àFdoÊÏWÖ‚¹Ö׸f‹° 4ɸ²¨\ô¤\Ü^”¨eD€à6 bŠËlašfóôø-ŠñŠ‹%µm&&å³ÿ×4»€¾ò<õCÊ¢µLŒ­(HbB€ öÇ•o€0‘æOpx»»9wB Ò¨1¹ÒXKÜ*ø!!%Gòªš-Ò¬?Ÿäõ&Û¯SéJ2ÖqÕ?ô*Þ+峨‘‚49@°? ÷‰ìREA›æ9¡êØ.I‡|3̤·À£J¼LV \3‹Ì)¢–nëYç á&eö‚žôT®œâó"«ÿ_,ŠŒP&ÿ‹ýº(‹©ÂÈýî¶ëÏÃpF|MŒDG¨Ò–žeÃ%@W£®±ÌäC¼§(táxx¢ÀHÂxEΨ´ŽWîÕYª½0ì%…-öÇ›EµJYÒÿ ÉÃ…IbIÊ”4Í“sP•ã<ƒ¡¬$ä߬Eïw»··7ßýúñŸòjKXg-"R@\{¯.ŽMöKª¼pã²iÚ,ù¿ŸÐžI•!ø‚ƱDÿ"_\Ja¾N9 1%Ì¢P±n7П(J ŒDá··ï¤þˆXµ|‹!< wBH ³òmæ“+ÿkÑ<ɯ²4R@x!²ŠLr4-<=“hY7P¿ˆÇR Lr /¯5lGâ¦ÝŸP€Ñìnß>=~‚“‘àànè"8r\‡r9ò^|y.[ŒLª>ê¥rUî•`Úô! #f÷^QØ•.ÊE/!4S¶rÕQ€²ÁÞM$ŒAš)…¿µ«ú!÷7°ÿ7é×¢ðÂì\¥t¨ÛPúøíp€þ«ë‘ö>ãj%&fæÍè‡#ƒf/¨Ü{QþÙ~£3()‘Rq]2éîr¸Ÿö`ù5[ê˜X €uôÂÃÇ9ì_ýåéá#׳p(¸I›ý¾nw_~ûÕrÍ ¢I)l-zaEJÑÒa§\‚ëfW×UUOx‘+kq }ô8`½#Œ·¦*J;އHñ ü)%7R l1vg<{OF á:¨\q²L (%´Ë“üö=¬ö/ís ‰ÄbÀªv‡ÜÏÉw±”¥¦8ï‚¶ÝÕ§¹¯›·çÓ3„¨d¾Â]XnŒpà,éOàFüŠJÝòÛÃ4ù(*K<ÂvBØláN0`ÿ¥;ËÓgMÒ<*³v!‡î-ê¶®vãгïrÕÐqrÎG7 ÏCž!ÐÕHm0¬®veY öaÒRJhâ’0¹MŽF”ÙCª«º,¦)t]·vïZÜÝ¿ ‘i¬¯ïú—ö¯Ü!¤ /¢"w:â¼]Uv®i§îl$Ùæ@--)¦ø¢µIÐó¨pë š©‹øó$2£¤õæÍ‡Ï_>Ff¸´<I¶8Ÿû™èÊìå¢é•亖>­C`þ›…×â2¼º" k˜å3pe}Ý’ÀÔ³ô}ÂÃ*Õ|È@›é¥½JN; š]ÛºÂ=ýBÏH/ U7û:˜9"ÀW)–°Æ‰VZ%Pn¥1]j¸Ôÿ«€DÁ©åyÙ\Û¢a=X¹Mp \ˆà²™1u}YÖ[h¡î)&ÒüïÅ­ÛÝš+H4C޳8ôqu~!RZƒd8£]¸$Úã€ÄÞá>»ä|¸„à…÷`&®¾ÄEìgKmrDiÝÞ¾Å7OO_êͲáËo]ÙìïÞœÎß)j’9œRÁ~°ô*(þa,#Ì´Ûn?}þÄ)jØh‚êKˆ…(ºEí,MýŠœ‰Œ•ô)ú*©.½XþÆ °xÖÍfèˆ2ή¶vCç žýíÛ¾; ôÓØƒ¢‚¼KRDh‰5[Ž#@>¶›Ð)°¯abGS*Û ƒ,-­ÚnêÏŸF+$t¶:T/â&ŒÔÒ…$üÍ»/¡ý¹÷`‚÷•‰”ŸÖmÒçsTGð¥‰ßcJ3 W=I^…Œ%Y"j‘Û%dé]ï#dìkågUÓº/ü|åF³HPŸ>ÉŸª2¿\™ì_ bñ.íÜ^Èû!¤­…—þ"*´íÎÊ„ÛWŽÏ÷ó8ÀL0Öƒ¦ðŽ[K×€€½•k!ƃ»¾›},š·®¾Óa8~W|æ¬ÕZ°&Bì¢ßDž jµÍR¶ÿõ•çÓÀÈüY Ó.+¦z¯aÉ8KwKµ÷Öí¾ëxyÝÔèÜOÏÈñൠÔÝ͇®@Îdpè(_9ýüL¦sÎ!”(óõ!™##¥@š<Ó±ú àÈP%WBî]¤gŒ’Ü Òÿ*A¶Bt%»©Ñ³pµ6(xm»¿ÝÞ|ýóg( ÀŒteÙ6Íãó— J$j!C?ª%ØKþHn\„ÙšGiYúâr%Väzéßkù "¤ŒŽ*7’g2‚“–‘ÍÍ8žÌ²ðÃé½sɱnï\³‡:E¾9‡*žÀÚ*Ï "Z ê‹8mvÛ§ÇÜB—»ÈDFAü-½|© §9@檩ÏͰü>˜²†A0éNÌO};@›R‡ážªÞxÎ{Ø6sX$ówî D¨ÌП8À+Ñù„F>Ï4°ú’Mµ/]Qmö_¿Ü‡ßsðˆÀŸûjÿÕ°nÕÏÒ°,[ z  ¥j‘:d•vÁ¤ZÎ o2ýÝ1uÑS#qcYbü}1J2XúM - U¢²-5c](¡ãm>ó¤n<|ì{Vdò­–yHâýµYÚ FS¹G)ê4©“æÑòi ¯(¶C…ÌO„éáF4èÄdwI …Žþq@¢•Òù¸Jw<>§ý¢w0x±e—ÍYªn7 ÔîXvUh¿ aiáS‚„e¦q½—ñb)ÿ/u#s!YºôÂF&EÊT®:=¤Ëàè­iZnܰœ‘{iài]}<žÆátqcžjÙœ(7ínžuSÎÊ÷ç«”¹V©/ssåÿŸúmýœ›'B^iëBR¹Q0I˘ bæÁ9Ÿ ø±0Ð ä||§™^ò¢?ôÔ·QÇ!·~"J”0H Õ¨+*®{Î(Rc.ŽZÔrþfÕBVåšËä<ý©Úý¼lx°6m ÄïÙëé«ZG¢Ô”Óq²¦™=(i@6|Éûý2ß¶„2T¬5õ¼_W¹ ‰^d¸ÈÅ¢¸}÷ýýï_†óY­‰®^~«ü‘¡Š8êz¦Åïö¯Þ‚§XJRàÎAúãH¿*bˆ(Ù`uUS°Sãˆô.Ûˆ:ÏödÃ^öø%Ë%ò=³ÅŠ8ŽLÛ+WaÁåæöñþÞOÓ:YrÞ\gNL#ÄŠŸKEŽa­q„eˆu5§$&&1v”–ƒí@/¤çn„-ÊÐH?J^áq'€´ìΓŸ³1h„sKʦ©ºÉŸÎ¡"ÃlšÍÆ%â½ÌØ—¡Üe;‰×ƒ€R‡.»Uhè8ò£L¡äül›í+ö‰@øöîéÛ'•Z{°³ðD¹O³ôY²ŸÛÄÿ²åÇåkQJÀQ*Ïý@…Ì7i>½¿š¯Éô‹Ö‰Vú‚ÿMÚÚ3Ý*s$lH[kÜ27¯ìÎ߯þ` ÍÐávÐöÏ#Ô”FŸEl‡¶þm]—hg,ñ“CxÐ:êhCCVńЙ“?³ýqÝÌ Wu^Ø/«‘µ h h fÁ ¨"×(VÜ¥nnöß?>#"-X#Ú–ý©ri°j +ŸÛÁDÔ «FLÐÊm·j”qsss>Dª—§Ó1&µœEÿ H”2Íš-Æõ\G¸êˆsòˆTûµÌ4 #eL¢Ùí^ã¥ãÀq¢ðþÕ_?~ùy†U qeÓÜ µÙ¨åiì è@MhCÚ‚¤ç,>Æ«A÷Û´Ž}Èw~è»%%Rú¯¢¥²ÖÍŽT×õ¯r‡?AØË.†I‹„άv»þtŠj‚!èR7ÿþÃ?þóçŽ~2¥ÌnT‰”Ùî_£#†(ÅMSoÚíŸ?&ZçðÑÐlrƒ O­(Ð+Y¸É¶EŒë' p£àY­ÑdJ•¹âÕÑéËVf„J¤6îJúyv¯ïúãAMñ‡ïÿþëïÿ;³ïˆBw,1äDl Q‡ŽrBé!ý†ÈM4+"‚O§ *FX¹Ùž45C)&/&'Óª§×“ë59E W—®MØH•’4m>ÎDRm·›¾;…ÉoÚ›i‰¤ñÓHò(50ršãmÚÛóñè™öTÜHžºÝu§Ó4tâ̼'¨3!/6e·&æÍûž—> æ¿©AX êR6l`ë £ªÑBÌxè1à k¬j‘Á¸‰CE ±4 y ‘œžž7SRÚýêõûÇ?﹋$­tYU¢G¢ð¢ÜÅšE$¤ªüE)]LT‹Ž¸ø?æ`¥‘âÚî*¤Í^KÄ‘.³Ÿ+HžÒs¹(¢ê²yèžtnŸujsŒD--¡ªê8Çؕҋš|B×hõŒŽ1ä݉¤¦–üÑW'D~ÈîÃz:"m­ šyle.´¬oŒöœZË•< d¢ä— !©~üóãhÍãLAzzÒ³u‘|8e“=&ÏU‡/òœÙYejåÖ5­D*T‚%ûËø¶QCš“ÄåtŠ–i³¹H¬K½ó²¢Þ¡+-eØ7Ísš¾‚äÅ4¿ž{ëõM»}wÿÇ¡»BB4"xÎb/I©…n«úÐ né»™ã5äæX¸ºïf9Í’fÎzÝHbéq[–çðÚ¼…}\çy3Q-ÃÃ5­ò¿õv¦i‡Z¨W’‹Dq,5ôGÈ61§™ØvAÐD#ª¹g­eÒQª*WlšÍ8«ÃéÄ©#B1†ÂÖÖ'ü i ²”oæ'I6nÈtŠX©rrh­sçxi~cî"Óªl³»\ƒÄC¤µaz8hxe˜Có8J[åh”§Ãɹìa„ïfV}YÔД¶*ËÍ·ç‡ ‡†,@8@AlÏj=ÈvuÌN»È¹!tÌé4Ë]AÂf"ȇ!2ˆ-øLî7¥ùä",XU©™óʪEvP¸Cð+J£('1´1KrʰMª•úχñ*ÑæuUW…á3Ö‹—=qšœG’µ*7ã]1èt4Ž’ŠN©¶ôqQ°"ˆ²­©3XaO¨,WCQ¨â¶›ÝÝ4‡‘çÄäÉ¡€cåŒ\gˆ=À^ž‚ \UMÕ”û]ë‡óÓã°j;òi » ×<òc]ïAò]w$ÒDKjdi2à›Ì:OWô2Q¡º3åÖ$2òÚ²RYÕ®êÕ»÷ýðøxÿ‰0Q´”(…rmÑ»©›4y §ˆž#4»ÙíJž¿J Øt¨&ÌÞ9Ò Xk7ûñïÏÏËvα5 ADž»“æQ-“¸\ÛÌ=-§òRËœ{YªL'*ËM”v»›»þüÔ÷'k¨e=ê€û­¡šÙov¦Ð C7Éáä-É ,|8 §¹;oʺÞDBëT:î9BAcãùP€Rd€P\9.Ã-#Çæ|”(C&²f÷a{ûþOÏh2Ïáh™i¤»eHRÞÞýððð‹•ý$6U–MQq1 ý4Mݹã&¸ñ®4}×£‰sæ2ÝÙ§nMÉF”NEɹðœH­¬n(ê8NoÐÆØG2r ýÝßþí˯ÿžNŽÄ¼£Ÿ–a¸Ñ©U½{A33âÉÓÈ‹‹OsÝvû *B¨å‰Š»ûó?ÎsO Ó¨—m @ª 8Ï<`ÑŠVz8s´Ä4ùÍ뜗ÅÌQ’*ª-Ï/pwiu«õ¦''Q<øí.Ì=5¼1Ó<®°Ÿö6Ñúmn^çšçª‰ÈúŠ3dÃ!UËÇÈ“ŸÊ²$9³O@×2Ê‘6æÄ’ìäò†žÙ¢¸ÃÍ}a4ò½ð­Aò ÿ Q¹+oûn¹ŸuïH§Ø©ÐE,òRÔQÊ3Žã0}OXN)Ûl`—9ª¾¢6V7Âxœ¯Þ4í·ûß½ÌFÏvSsùóAÉÑ2žN„˜†ÜA¶?ÞÃÉ…+ƒìÉÏs:Å-FvÆÁ,®rèÅfnøòj9?†\-wÊw‡YN—ÁhWÙ«Ui|"#5F\†*öÿõÔxœmZÛŽÉ%™™U]}‘4#[ÀÌb_üàðÿÿƒŸ÷Ål¬µ‘çÖjuwUFpÉC22KëžVOU^"¼2Bæ{ÒNLŒꪤÌBv‰Xí›êJð‰t±øm~g™ŽÄù“­÷³f¯3Q>Oþl§íÇWñË~ø„ùõ¦6•_—I&íÕf/à!\fûdÙ«öÉE–ŒÚlE]âÎX¿ƒ¹üZ >tüÚŠmžÈïWT×ÞW&ÈÏ>§ˆ±vÿîC‹`:¬÷Þ0ŽäsÊ4-Ú1s-½ã¥ÉÄw™tºNó­fãPhÚ'íÐ sª4% ßS§€Èä?š ¥Ýj­]\9І? ±vŸÒþÄzÂÔ6šÍ«½Åõé%”+`ÐF¹èÄW*©amÓrâ0b@5õ>¬;\3_ù‚Ær#<ãµ ôy‰[bFÖfÎÙ·çm ØšR&,PÃÌ0nêL„{Ñ~ é‰neÞýÒ4ß`!cp‚V•c‚—åçøm›7øß‰§ƒ˜®´§þ=ÂÏá¬îÕI¡qsÄ«v3 ä8U´@5§°+vo…I{ÝG\¨Ì§Š³p­ŒXÿos-ýkØŠ·‹&àâ!¬Ñ®ÿÍß\>Ìç«èºÈ”rtÍñBóqÑÕ(‚`4ù)䟱À!§ÌwáÌ\ׄƒ2ÔbÑÆ2ÊÂ@1Ä"²àÝŽ%vØ‚5K=GØÝš(Âw@AÒöŸÄÔx Õ´ a2L.ǯl®í¡8Á¹b?ý:d¸, ù9Ц7(-EÏX“ðIsèæA Ÿ‡Û6@I¾`>Þ,³Ë`£ž¸ü¢i8hÏË=ÐK,ò´÷2MŽU~îØRòðpHÜW”CPÀ² ²ºBÂ>Ó\Þ)»×áJiBnm4™Ó««O7˜C¨{"F2T3o¸üPå4ü#uRÞ’PÄ ÑÐa|vù-~9<Íýùb!‘ù± ‚)ÑF)W„É| ñyA2êœY‘Pí&çà=r%Æß›—‡„/\ Ð~;„/ÿÏ‚ ˉfn½'jy¦¶°E=×{ÃÁS~ʌꙗÇ7ÃÛuÊ BÍ£Æ4-ëú: $‚b^ÞzŽÆLöa§är³ ×0*õ„z ë±–¡Ø¶žGüâÿÊ”é•i/?–>M®Kmì”aiçWžfÄ"¢ÏDr á¢J¨GÐ%ÐÚ¶5½¡ÀUXv/îîÓHcœX`43rÄ5îm¥!%7S }?xÈŒœ :d_]N‘ùÐ=$!|&<x¨—Ê5€YÇÏœI7ž4 ?Ñ&Ì2%Wº±) RL3)?´ÝÛEµ1¡uAÈèNþRˆ…:YǼ9À¶.Ùܤ®üÜlu«”_hÌPYᾋßi¬vt…AÝxËšó¹÷R®·|vs8 ­vÞ- k§U<¹Ã¸¥Ù#,¨™ëlaÆß<ö‹R_Y?Cc¬Ä;/ã0{ â) *Ñ¥\Q2º0œNèÞ¦2Íî(¶d¿` n±äÒ›EÓ¢ìÇÁŒmQü9òW*§P¹ÜªT/Z ¡‘ ùxtF¬‰[Ïw‡ î†¦‘+6ý†‚ƒc€ºóU6ŠáÏóâ>Ÿë¥MqNfÅý¿Ä*J_ºæâ<DIè‚(;˜’¥§‹ñ¦£Yw ÛS_¹–_h¼SN=XŽ\oxŸ´*æ }Ór§yV%mbÝ­$0#:^ìC‡n‹ô†AÐwW¤_C{‰Iw¥ïtG éˆ@™1(®ƒÿŒÊbE4ð(K–q{e”ʾ Z!ëÏCk‘¼` @?óÄOãïva]]þÀÖ:Wm‘(?3Eé–KV§p†Nݹ‚®P޲Nsù‡9ϯ•p¸}<_4 R—ƒÌ麑r±æø¯eôâcAA•Ëœ Mr)¶*ÊL"±Ò ,.Y(À‡TQÇAþé.#T‘ª;  ~ B‚k‘F˜[LA@=‚ÅáFpªÂöÄåÇáþ9|`ò{eäC^Ê´³•évýZ~.K1k®µ6AÈ‚ˆaë!Ê ¥í £0œqµ¥”¢]Âi¦tÿw!Ó3´õz‡»¶¬ÂâÂûå9”èd5šÍë,:˜d´ ºB±2ŸBÅ d-T§W\ë* ášíŽâÏ#×{œÈ\O×=©^ép34o©˽J›P B óÅž=êCè-BÝo)_ØÇZ¯®–ÝŠ—?WÏH—g¥ê7›á^ÇPÙÏ8r¦¡Ã„RwXStC܈ÄÙC Ûb ›•‚¢{Ï×:!Æ»D¶aÂ~¥pï~5Áš ¨M%Í È;„A»zòí|¼®èM*Ñ3µ¸ÿ{qêãx£Ù¾NI$ü‡²L‰1ŠÃlîñ…ü¡ZÅNÐ]×Ç!¿È,«QˆþYõŠHE¤dërKj:\?AÒŸ´1'4¬ÎúòûŒ§¡’âŸEþ_ÿ*lVù‚  *<Ì¥Œ-¡ÖÏ}}É #=Õà0{ßµôBÍat—§}Ô ”‡ü©kàlTÿäÊvi,ÿNå?•ßýjO_u¬˜# í›ÕM–Å¢¾ÕJ8û(ÕM]5‹_6%8+#«|½ÊÚYèê¬5“NþÐÊÝW°I£×ÇJì µÊt·¬ï€ÕÓ ¢U’‰)ÿéX»dÉë˜(1:®r3¿1±××ïµ=b³É]¨Åíš,¿WÃ×òSEñ¸/#kÐ6P ν)“ÿòCì¶ž/UV&i‡¾ƒåÈ%p¤n%¹Ìo½ƒ¡ÏԟãHŽÝmÈOÛÆ oÐ}þâHÿÒíkÁ<¸DN -öô„h±E{_›G(ú Œ4èÙˆXaógèÍ“øœ;ë‚Å ÍY´ýn æà?ÇÜï‹M]‘›ðåOСˆÂ±—JÅ¡âì§î¯ˆ´ß;¢±¥;žC?- ."¡Êsrî`åòˆñÿ#¬¶¦å•ÛìJkd®â«/2¬W1PHÈï;ÒÆ‚.‚fR¾gÕèSTÓ9¦Ó ®fAÕS’ízÝ÷5ˆª+Þ?hÝg½¢™È÷.³SVŒ›;¹ÉFhÇ"PÊÊ1#ÎÕ[#l $/mØ7ï_>ýà§eGŽú1v缩ÂÙ ì%¡ÇX–Ûä‡çhnIððÿ„eÕm·N9:áDõo‰…Ë!Û&žÄä7£ žÙÆ¡â­ÞçoÏI·^žÿZ‰l.†731ÛZjÍ ˆ§›8®P%jq©$u¡ôVÞ$¹©—Ò†]x,«YœÞdQï1Û#ÓŽëq¡ÙÁˆ Èf”öÙ€U±µÊ’S%0Âprù3›#&1HøËi³wÔ{Ø}H(£ÚÆJkD€¯ë]š—ÕôˆÊ=Ú#{qî9Ó ®Ñ3ÏÚœ“oŒT¥ 7 6ü§)v½ˆÀçÁ ŒWÙ®Hß oDÈœfu÷í$¡êÞK"p™·§âkôñ’rVPUÂ"?V±ž˜³«AÐáäÕÇØ×Nv‡$f'²/EË Íø-‹Éï»\‡ãùå)4͹‡Øòh„À´UÍi²ÄÈý2´†¼ s 'íÕe9y¸AQ3ŽÆb²©‚Ê K [´BØGÃE©ó3‘žlé®nvҲ؟n¼±_¸Òk#iiÆ’h¡¥*Î¥úç±Øâ7»œ³LŽ•{ºLJFZ2¶ŠkhÒåÜÇOý§‡ í2rø¶3&õ¶¼söêAn]iËDÎÊ¢e§%'a?èúÐSnzMº¿ê[çh7m¼ñÎð 2i[êÈn—“Ñš®œL} õ=¾É~ÖËyÏ<÷¶ˆp>€)Þ]dTÇÑHÌBŒPÈÓàùöÂÍÈÓ…q»-¼(‰e.Ì.nÜðâÕ:˜½8£Í»†¿e#1ñ'm ^(ǘº( —?TâÍ%T6LP¢Ên;b÷ÿˆ+ÕW§w?"5O­½ì²òÒò&€À¨+;;BÛ¤ƒûÑŽ8 ³†Ë%®â1JÖ£_T©u°p˜@G€u£9Ü^vL;Sº²&y—Ç2J÷ÌqÉþgj4âÝ£-¡¯çãÃ7D‡×Oÿ@ÙŽr>« D Ä–ùûû™giP5δ¢§Ã*™h,]ª-0¬ùó8J â½Pâåæa½|v•‡æ&-Îp [y¶Ätð!ÖÏq·u£{Ÿ1¬ˆîe ¦Ù¼Òóç)DÅîBÎèDe"VH¬ÝõfÈÙ`ôép2ÅZlÞ¾ýp~ýtyùÌißô!NÛQût†wxhçWˆÛP|Ïô^Y—3þ@™¿hœ«øý¢xÙz§ÕNGæAÔ¬è#ÙSm­2z‰ÑHä:‰:ÛBšw×½*Ù&‘¼Zñ &pôŽ«÷lá/ÑU–åÖt²ž?cæTòk¥æ@¡,ûúåªË”eš–Eœ=L‘Œª;sx§Ø<­XüŠ-û*ÑQœ¼oÄM ~QÄYÈ𰠬듟f1'8¾q'ZŸ]M8˜<2ˆt†ONá÷FáóÜŽeV‰,…,ûVðÃùpûë8p«Íìÿìy„c³5{Ë"¦Cƒ”,Á¨ÊAÌ…ÖWë~þÈâHæ»_s³¸àõ‰Ñà‚ÎÝQÛòoΦX£E9Žtäº"=û’ƒQèÝtµ{ïÁˆ=/wî3:/wNÛ¥µçH…Îd,ÌÛ/æ_<½‘Ã×YãCð$Õ×§ÿÑöèÊç£Óæþªë' ý»ŠÚ•T )|¬*¶.è/ %–à ¾ùè´áVæû¾þ¨í“ª™n{û‰t’ùAŽ_ËíœK=¼ùð[C¢yZ^>ý¼®—ùô0›­—=?>þóñ‡¿š¾ç›÷ËÍW,·¶´i6žcÿlYûåóÓtüpùü±½þ$Ó]:R&Á6ì®õÊÙ+ÈÊ{ÁÉ9åçÜ€CMpCònšßöóÿšf M‡ýò‹wÐNäð=êåÝ·ÿyÿõ‡×Oß=ÿòã÷|·^ý$-éñöÝ›‡·ïÿí7wïõòôc[Û?þüÇŸ¿ÿ{ïëñþþÍ»÷_ýêÛ§§Ç¿ÿé¿¿ÿ‹ùŸ¡Ù´|Uý‡æYRò$’©i½¼€ ˜ÀG¹šŸfÉ눊<}‡„v¯|gêëǾ>ÎÇwt|ož¬³hôÐt1]XÙ~<æãñôæÛùøÆ‘äù#ù‘9:¿>{wÖ‡ûû‡·÷MÛ?¿ÿhoœîßþûüîÃ7ßþüÃÇïþö·ÿþÃïúî/¦®õùÓÿˆ2xœ}ZÛŽ$ÇqÍÈ̪êîé¹íîK-Í‹LÐ Ù~6¬7Õ_ 0àK†dË–Š\r¸—¹ô¥ª2Ã'"«‡/.gúR•yâĉÈLý5Qä‚ü¡B \ˆràbŒ)ÍÓŽY>$ ò­\YéåòZÿQÔ[ôJ1­¸¼•ÿËõ„ׄ‹å¼-¸]~Eyxf½ ±\ Ï¢"ÏÕ ˜Õ¨ ÇÜOãA-©òKîJ:qî¯C4ÃJ¨roˆz ž%ó’k묶Ùhú3•ô3„É”W1«ý2H­lSÐq&½’Íð0uµÙ²>]ì6#}B!u]§·WÆÈñú'?½»ýzÜߡjˆš)S µß­•Ñ*é·,ßÅÜÕZäŸZÙ*Økü¦€yêнüe¹Ëö“ ‹»"V‚±ˆò6‹ ˜¬Ýböëh¹[‹“Å:Z g×7Ìew÷FFS§êÝYFƒýæ*Y´NŸ]§Ü bŒzë./K£Q§u•Õx]‘Àè'2ïþÁ[³?ÌÁçlíÍWÌG]nµ?<3®J2-V 0d¨(Ö`”;EW›µZY«Œ¶Iý•›/Þ³+£.K•iVYG»©ªWÆ}0@¨ýôÄÿæƒ^?¯…áìÒÕ¾y­OÀ”#×Y Péõb´þoÀyèC™XÖKO,xGÕY]ªSc*“<%«ýdA„lj©SIÝ)(’áÅM±øÜãâK8Ÿ—··N¢@Ÿ(0ð%0d¹2Å¥¾rá:ÙÉb-`t!ÀˆkªQb6š¯5îòêB¾÷ï Ö*™¨W( Šÿ¨-Ì¥~PûaÍsY"Ýæ¨¸ 0AWDžØÅ8ȇµŒ –¶j O‡)Gø¬A£”5Ô4%?3E!šóIb¹§þl:>Š3k9F…qÉý: þa§,:Ì€óÙÆ/†\€UƒÆÜÌcrþøv/¥Ný_¦`̉¨w)!f(…øN#QæÜ ÿòêmnrítñâ¦ïúû7o‹`M¯ uñ­b#æ öØÀ‹¯"ÀdÞg[Ûà"ßôd  ÀÉ= ïXW"f¶›lAcZ«—Ë.k«“Åzy˜<ê„á‚ "ÂJ…’rºùä“Ç÷oöw÷à± àdÀ^ì”fÄo‹M£u{05ïÕöYÄ÷]3݉”ÂÂ.–¤2(k2´q„©‘F>ì+Ñb#gC*Ò"QíW+1r÷Ì2H¢OÊûI8$®¶Ïw÷ß›ý;6Fòq±ü¬¾ÂøõÇÞO?NHŠõ°RЄ±"F(Æž:ǧ¢†<×Ñ•¸X8' £÷šo•;d’3Ü;wý:Ûy*ó<çáJÑà`¸Ú`ãØ®xá¢9œ~Ä:›…Å™YêÕSv³ë™#µz½àØR€Q!UÆÄ YLŒi™ÈV°J.“[ß½ qüÅ6R89ÕHÌIfQ náüÄ`d0Žm6 K”*)Oü/R‹ö’ƒ"?tm¡ç¦‘+ÒÕyåT a‚†á2oŸÝäaxxûƒ¤0Äï"±hÓ²~´¬Ý`Om¡¹I‹~àVØFé·€g6þa»Dn°õ Vx£³Dr²ßÄŒ’­J/]­œ-È`¿~,èë7[‰ˆq÷ºË`›Ãt J’sc§f¿1ó)À-ÇÞìç¦j¨--"éÒWPŸ‹÷ sçgÓ2D£¥«IJ#7éBË­¹¿0lã6Þ‡ó ®¦£j¹å¡¼¼$ˆ¾'IAsv†Ÿ€tYèhS0M :›—ý©þHèk¯^iTq«VQÁ\¢Ä–+¦áJ=·ôG®ˆ›Ð4…NöË.éÕ’ éR˜\Ek^Qùd‚[TZ‡ñཧ€—"yŒ«¤€J6 “¸~;;e$ÜT„Àþ Ñ¤¹Ãfk¾4û+¿¬h\T‚·¼ÕtJ“MJ¡¢ Žª‚¼ ¡XÔ’^²Ll(´ôˆÈÎO!T¢ÝÙ2Ž€,uŠ9ý¤züê"*‰±{‰ÎÉa?XÎâN/¶eŸ9,iËü ¾]éóÄþp4{`a\§–à·=k‹Æ37²¯çS¢#“1gˆ2¦®‘韀Ì(_¨8DÕÖ.3·ä˜0âÞPÞžšâŠð¥|›,ÞY¦¦*48¢Éò®V.d©„ñê !<£J]È#.iΪ0T|F”UlÔŠõ‹L<šrƒ ޤè*ÎBÓ«WsK‚ÞÌ@ðÅKúDM†fÖzŠH¸‰m__±!ÇB •ÕÓ4/Lg6yäFöö,RB’¬´®ó=¡Äf¯v*fšýdR UpÖÎEV@Ÿ¸,6Š'xÞüû˼ù ïæÃ­n îÄBà‰W“õd´¬TÎÞ¢Bú&èá0yŒgâINRcÕ ÖѤ£IˆN8Ä6§šì´-—LÚðP:ë6/çñOï|»:D|¦®Š¨Ó´ì޹ªÔ%=kýRì¼sle0ï5il Þxªì8zU®6T€1µ=ˆÖ"H<\­ ï»ÎDh×Äu^Ý”é^’£7§D”q>hFî­siµ°“Ôçn¿m”ªzêÕz’Ê‘¬…ˆh*-XVUk5»z1ù„cd vºÄGðf4»Ý„ºm-c)ûÐöÒ¬œ7°K•:µ%¿¸¢ðÕ™mCË/4£v*X´ŸÙNŠÝ×[J*?ÕòJbiŒ‚LÌCi =W‹xjbÏv¾,]Z oK ˆ!Èâ(²´·3`M‹BÑ“}‚DI†+i[”Y{õi-÷«lìLZH;«¨ÇÒfû|¿»U¡bùš"ŠRÝÑc·ßù ΕaËGh4ƒ£¨Å¸*ÜoûÍõññVj–¶á jÑo( ö—Ö¾ '}WDf^ ¦ã-%F«WMöxnŒ¾ÓÜÛ¶„B¾zà‰i©ìüð»ùø>Äžº«Åí¬*ªû‹Óð"æ­ûÕ¡[[s¬3âF«:–¨xj¿¿ÕuÒ./Ú[uÄŒÚVÑRìˆý+Tg¦ÓÓ+¶±*YÁO\É£Ñw®ZgiOR^ЍÎi¸ì¶/%£¥î’½AdŠÔu΂؃¨Å‘ikµÙ¦[‹v6 I™oÑò–/mÛR£eØï2 §kªÉý³2?JÕ¬§ÑÛèæuº&COãîàjóò皎çC®+F†<ýJà°°yhÀZß ;‘éjý–žlúG4l-Ò«‰|‚5é9MÀË‚¶šZãz8_\þ²ßÈ|Óêµ­ÈùBϨä®fÞ»·ýÅ'Ýågu|ŒÓsäv’ÍÊ ƒw1­*â§G²ð)¡ìØõIÛ EÌæî’º³Øõåø W§]å©Ô#OÂxšè ¤»Ê]=Ñ6öàêûú÷¿"Yʶn¾•U{ºáZ>ŸËQ>„Î)^<ÎHa+å^Æ$îÊ´ÓížÎ¬$uË¿jÍšd< ÇnuÑmo†³ËÍù•ðÍôxÜwû›Õö¢^<ÜÞ©(Ë.õ´]òlb@c/®Cè%FP«ífè6ëóë×ÿûïLJolÛa¯2_D‡žÞÔ““vÒ}¶c'*tú«u»_|ùaÄTѦ‘ë{í~Èëh»ËgiòJTMè‡õú¼¿?Þ¿-›m ÷D“hÎî”ùPÕþ—µ†í•°ÿ]ì.ÄQ˜*t8H9Û )Böwߎû7j€ž™ÈÊÆl½” ñŒóZ.`çB£i¬ó£x8u/ªXFkô'6Pe`ºàڤ̑D·B·á4Ä¢13O1¯VÛg±¼ïr:{öù|¬ßýfêÇŸñ¸;¾þæÏÓq'!yùñßÝ}ûÕO~öË®¿øÓW¿Šýsœ+”¬ôŒ™Ø4òô¨(¥§¦ê³±U­µ,JÄñB‰¸ƒ<-÷,ñÒ}ÅÃÚcîòú9é݃ SfJQ›I–iÔCŶ™dÈ®”2½½Ú^¯7—Óñ^h‡xúô‹¿þé_þb_ëo¿ú×»ïÿ0în»«¿’Ç%±M‚ۉʺ¬ªœC†$cn]Bb—òt)¯4eÊ3tDRž—|¡IêñؽГ„B\*o˜6¬•Ô^§Æ]•\”ûª'% UYÓ!mÏúM_ïo‡óφÍÍîö·e¾‡$áú矊Zë†óqܽýŸåx—ΡA4½ŸT+PV³4xu¯F¯êŠ»ª‡æéÛ†š«!Jí|QzGŠ ç×N¤¯L–kò ‹¥§#õˆ¬º¯œÒ–fùa~øc¿Ê¯¾øû?ÿׯÇÃ]àcB5G¤¤ÌÊ´²ð3ï¹îÒå/A>“É]žUj±QŒýF ˆúEÖ»pXa»Ó¶z+íÛT½ÀÄHA[„œFb™Eõn~E™2é|lY,dḠŸóGŸýíÍGñ»û§ÃÃ;H¢•šnªÍcõPß•ãÛ|ýâ|ÈHÕØÄ ÏÂoòü£Xž7ÏÄ‚y|ÔQèÛYMÏ¥¸ØÉ˜Ž¸%"/`3M7âSõÕDø‡d3Ú'{¬‹ ÷ý‡Ÿþ¬ßœ¿ùŸ_ 8$}T[ˆ^OPWã ðšôtÖ|üçÇÕ«ä’¬š¨a„vËØ |Žiu…³Ø’Ügø¹Óp¶lÍÖB¿@½ÙECÑÚ(ªhÑçâÑî(ãæ ©0¡vÐ ÓGÚõDmð Vc¾þðÕÍÕö¿ÿã_Â(´¶Vî £6ÄuÎ!ˆïLÉkµ[Çÿ4=†xœEzI\ivÝ7¾!ÆŒ˜d‘UÅÔnu¹e´$H¶` Po xá­½ñï´wxaÁh»QÝ]®b rŠŒˆ7}“ι/%±Øì$3ò{÷»Ã¹çÜûªÕ¿rQªh£”Q%g­½’_¥­ÖÁ_µ±Î8¥ñÉb4>œ­ó¾^LCN]N¦¨ˆoY[šfkì¶ïëmš±;å”J'TË'>ãØŒ³5§«¤þ%ébù2E-ŽÒ0Õàú%Ç`¬¥çÄ"¥Êða*øÍ¿Vøé¶YzoÆqœB°Ë×f$ƒ)I•à°ºRªŠA¥0àÑ|–ñwN‰“ÓaÈRü’‰„OòRðœÇ‘·×Ì:1eð߸½|•b ÓäÖ?Óx–Ê’E™‘äï—+Ícå qD\`óµ‹Gº„yœp>~!…lµÈüëv¥ó?« õqÙ?>¤Ð•/jå|Ã&O,~­éÖ‚é WÁQ9)2ËóY=n¹¹\ž]ìïßÁ$çÝxº‹I9ߦ©wUâPµ›þx€ëŠxY2GÍéÊìÆù9Ñ \Å7ZÄ+§ æ1 ~—ÉÖµµUןýÅþþ6†ÄŸrÈôÐ ³á¸¡-*NYdr µÊ gý"—€¢ÃGÏŸ}ž¦›Pª_«ÂÀ„WeZ¬/¦~¿:µ¿ùVì‡iËŒs˜®‚~HY¢ ªÕ‰ `6Xß$¸ñ«¿y÷ÝoN÷ï‘ 8€EÇ–#Ùi›Jו,½«~ÙÞŒý²M x\c<ªêvµ¹xùñ/¿þÍÿT¶ª6¯áÌ”‚¤|”Lgã#q”¿*Í E4JÑ!¾-» Á‡x !fUÈÉ`ý•‡cå+ãÌ£WrϦcë’¦íÅ'Úæãþ-+˜–M CAnãþŒòìS€±¸3\b|Š”*!.y"{>)`ÿš)“Ú³/ÓB‹=5ðî‚¥èt° ‰EÖËgÈù\3Ù,Ï’Û×S—Ðiž…ÔÀOdÁF#!jD´U'f`<±jÄeÕSÇj&"À³ûèìê:G@ΠñQò¬ŠáÍ´¾øc˜Cdó‚—ò¨uô)ìj®ñs­úЗâÄiá(6SÍòL)Ü?;‡‡¥çÓ8Œ§KŠ`…–WÑ&ÁOx‰C™QT‹Í&ÏhЇ …éxcNèïnÀC4®À²É‹³/ëvá…®¦ÁZ $ûõŒû’K…';€Œ´WÒÄø™oîðh´]ðM¿Ø-/>Û¿û6÷¬Ki‘ >ò“@ (¾Ÿ¬ß¤Ð£v G yÎÎ0¢3‘?Kåh– þÐI1ˤ*ªÙ~Ô³Þ„qLD2o\…G ƒ3@LoTwaùÓrðÇØ$úŸ@§¥× k 0¡¿E×®M³œº!œÌÜT`obØ­‘œ!ݰ ð Ë“rBáôL8ßëØ{Y,IÀÐÌöK¿v¬ åëíÎ[4wa#à?~ ®ÕÉL˜”øOl×ýi_˜Öé›r ©T½A†£'¬€<…ØÓ«<Ì´–pà‘É#€ÎV-‰ž¥MœFºEê ùZŒé$IÐ#²€‰›¡uî¯Â…„˜Á~]5Û׊æÎ ijñÁÏ….w~¤»ûœ:ÂÇ#[gÒO­=EWzb³~æ«]¿àñÍ:uSQHKXÂ"5L9+|¦âfêöò“/þâÍïÿGˆgÜÂ2CÙÊA FAfŸ…Ó üF±SÚ“äéׯ4/È~ŠYA¼BwBå¢ç5ëçÀ¦ãý7Hrkq;“Ù²`.ªÊ+—R³KØÓžÊLŽüDŠÃÌAÑŸä <-þN6èÍt&Î_œþóýîÍÿ:>¼ƒ)Ýþ–¨ çüT/íÞ>5ÒÌìÅÅÈBÉfa0¼š«íË™ƒ,·WÝéF:Ò $цÐБèŒ13FͧÑð§óÒµö ]-AÎñ“ðŸ…pžnú;¶AÔù ‚َ̩³è8JÕ‹]˜Æ8 ¬S“D}0¤M ¯ƒ‰í j¾Q‰Tï>V•LY„âÏó™ð/ò¸ž¦ LX£a¬Ó'-†f×Îɺö ÜPÚÒ)p‰ÁV …Ë" Û’’oD]üí4Zžs8§TZš:ÞÑ‘¿Wmƽ€CU£žA9 ¥~R<Ì«RŸ}· fë‹—ûÛŸ2qºÖ*V ¬)fœh< !v$qø@ä›3‘QHA£%bõM¤{´@pNý}èÐ@[2¥‰g™)‡2w¢Jà˜Ÿýêß½ûþ‡›¾( äg‰¯§:tÀy^IË ÔZ¤VɦLsþ%â“C×nÏQ@ã©ÓŠì(ÇÃæü2 -ÜbÓî®Ò0‡èô…ÔkΛª±Èh" lû0<úºã¾¶õ&Ž'…#TÀFÄ1ò¬v—Ãñ0œÐ&ªÌôSBÊÌÄx!ö¤“KS˜u®Ô0aq¯7¯ð'Ú*ÈN³>ëá! ÐÔ¬ÖOMÐ —OƶP·,svXPÁKð‰]@EÖ¨w‘$)ãñ6…qf4™È l¯, p¦¯Kd£nÄPO¦ÉVàežá’EBRhæ®ÈC&nåýâŠ5%LÀÕMA¤ÁOZcqâ`]XÇxbª€Yet7ãj(z7"9¬­[ü !y“ ãç‡Ç4à uQðóÔ!Á$€=Õòê#TGwãÌŠ®r@§2õGë–9Ä0>X‚‘#­ñ .;s(Öè×Чð–LKR#h@ ûãñÞÂç¿IÔ4Äï ¹töü£ßü_>8¡ëÅÕkWm33Ë!§ã;&¼u ì1'²ÕØ÷À¦ÎÙÙêòúö¿ @±Ð¥Ž=j¹3¬š34gH¡ªY…¡ ã@r¢eDP2¼* ŇéäÚW³:d=k‹& 'ÌæÞùJ&I«-sz@,:`‹4(²‰öÌŒ"Ùz¥}ËBÀ%»›ºjp…1 äázîw:“ääȬpq‚²äÌ…]+8 —­s!j±Ë`Š—$„Ͱ0rH;ìÈÞö#¶v8Ê_~qXâÁcqM„ :Ï´tïl½Ø ý_‹:s2"€aCzÌÖCüOÃbu¶ZïnoßÅøÄÍ]àÁ,¨ÙDáF¡™OòàЍ`žcv óy`B æ¯ëåù4„©N¨Í¦ÝœöwnñHó„9pºRUŒÔHÿDt¯ÔS°“xP$X@ðÐ\Öç7Ëó·ßþv ãsìa?Ë‹ÖYÁ8¸˜é*ç`ž˜ÆGBŸä+[‘!†â pª&‘±ÌÀaç‰Jl}ùéþÝH*Äþh–gcßU«k©ä@Fß®—5²hoLûøá½¶ÐΣL´àT´ïÊAžZ(€/7W?COù0íE ¥c¡`Lè€VR”X!`Læ¡&ÁE†Ã"ÄHæ @'° œtM£)ü™‡ø ‹ºàEAœ²Œ(½JÓ^~üËîpà<¡§õ€¬ 7ÿâOÿú·÷ßSó\F«âkp˜unùòóóýïÿΊÊa)9µ Oæ! Œ÷ˆu,¦ME*Ω …O&ÏTÂE¡kÈÜpš«Û±;*Jl'à™æF jЧUíÎUëi€–Ô/>ÿ«ãþEAB'-m:m¯_Ão·oþŸ´¹"ãa€F ÜoÖ»×ð»iè0‹š@ÛêAaÃ*6ÏJYjœ8FËÔ‹HE½ÜàËÐõHlë8pèsⓎ—b?:frÖÍât›¢«Ëå§9u{1ÆÇŒ¡¡KÔHž™29™EŠX›eÖGp–aláfý¥E™wzïê¨ßÎpªå8‹ tg @™¦‰¬EElwH`}|ø)Œ=5&òÐÕ™Æy 5ýã`ÁU‹Õr½ S¸{PâÉZõïÿëÛ¯ÿÿ$<3:4´vqqñâqÿnD‚Ü(Á8`!µsär ¹ÀĉmfÆRB?3^P"þ°bã3º‚µŠ¬ ¨’±˜eY1à‘ÊX8(¨Ü« #ÚJMéO28r |Û ¬ý Þ/ëröÉWiäl(—r¿=V¦‰ku:ÝZ6 z{ÏfK¤ª(D5Hð" ¤Ž‰”¦¤™®¹ÈFJžÓE1JËÑÐ< VçäÈB=UÊ!¦2z+ó- Jÿ)àÀ^"Û%¾DûˆÙמ½²èìÜ&H%ÆÁ¼1Ö„ g “ñU”!¶Í–žb©H\;Jb°Å (‡"R™*‹bªdN2¤2"{ñ/×Þx\B,uu—K” 6è‰,#Ž­’V*+|³zA  i h˜ŒÑpfZ4[]³) ý#òÁ.v¸R8ÝQ…Û=È/Ö‰”¸O÷`ìPOÓ_-cÒ0-%ƒ/3~ÖùUFHË!JQÏ£!ò~Ò­Îì§~D[¡*.Až°LB~fQ¯ëÕKœR¯/a^;0m Šlôw8#ºfìîú8esÆšcñ²ÖêÍ•è;u¼ùŽÓWNÛ©ˆ8 AùóYF$ª’é3‰í§îŽ|ÀBM ˆÒ°@NVq:Á"4”ˆPÉ«‰ ì}è{/gæÀ’bÛ+ôY©J\n$Œs2À óÚÍs@ÁÔ?@RÉLBg;6í’ —9€˜[Ó=¼àFä’‘©–s=™ã‘1â¯qHœ„iÆ 0˘A͘—„7Ï~VU«Ûïÿ¢ê™¡/ H×0/“4SZŠÆ»3‚5§ë‚ÈT9Çzuå›Ëãý9¥å!ŽÅ±“oð5ËZMý²åôð#š Y"€—.'}”¾—eÆeDC%òC5Os³ ìIfÛæÑ½æ¬ÁßP%S¨æE*2Á¸UÑ‘]•ë!Ô”­ÏÑG|S%nKØeb:â[íú£åîg‡›ÆÓ[¤t½8wí=¢ª²,x€ÿšT°˜8>‚üÄx$ ”gðd0«à·™Æ±2\™8uæŠ[$)ñ§ÍÿÏr¡8Û‡F˜ÆŽ²öóú«Û*N–d LO'[_4ëõj»ºw‡#Q'ËëÏ}{1=žÂp@£çžÎWR2Ñ’Ô€´° ¹ãéÃñ'k&—ÙBµ…OZŽÊôš'3ŸFáQšHáDšê¤gjBÿƒ7BçOë #Ã"–°Œ£ŠBé´ËUÕ4Ý©û“’Ò^|É,˜z#kÓ’[>Û½þóîáC™öZ”?àÔ^'I#’s¦7<Þ éXjEØ2qÙöͳt0> LËbH‰aaÞq|ò´6*2LðB­ðÅ4p8h ª‚šû£,[Wá7$ ˆ¼8»Z<ÿŠŒšöÈÚN°×^7«sÍÑ3¼‚‹XÒCtO2ÉùÁôû”™”AÉ¿JæªY—l?2û¥p˜I8˜$üüƒh:Î…—• =ghÄ(Ž©÷#¢¤ž~Pj‰sE·PqÚ_PqÐE"bÓú•­wh ¹@ðÇ.¢7ñY†Cé"|l‡Z¦ãéþG±­PÒsSÕà9ÿ zZYâ½ ±qž(¥'}͘•I` ¬ Hñ2®eŒhÙßeË@ädpQP¤#Ãh› á·Ž)é—°í¬^\ MÀÙçÙó)©;«¦ãЬ=ÇWýã[Ž Í¼d}r‚vŽLF9®ÁÆËVR‚€Œ‡Ë‰f¥ `\ ÀIÆ2G¥Œ¢nœT„\ì­Ö­´]pÂ/¯’ ºg[­^p+Kg_¯€Ãé¶Zî¨Ö9e ’Á …›!ÇÃ)€Um»~†¶6Þ‘ßÊ`XT¯@’Füq(†ÂÓ$óy¯¸Ëð• >8œ§q”*qR³ã*$ÃFÞ¾P`V¶-L›šDš\‹úEµþ¤Ù¼Ê¹Róú(Oði»}ÁQ:09ù”¯gÕ÷·$íí¶j7ÓpœNï¥Ð¸Øf³JQfåú dاPôV²é8dp^æÇ ?zp÷ A‡æ vÀIHcÜ‚Nƒ„ç!D™#ïBàÆkxŠC6Óœÿ«íó¯¸?E½iP}êÍsœ)%ï‡À.ô_,çt}²þ„pœÉ€|«„E7K-°ƒà²LIÏ‚pBh«5ûVì9R#”I)AóNÀÒ%Pòiµ ÆNVÏ> M—Ø÷Nù­â3OžýñÁ'ÃðÈNËR?BqíNF¥‰mÆ_¾0¤±,íNZÏΧû”¼ÝÂØ|Aì'«„`Ë¢èOÀŒÏ¡{¦dqB¸ùù%’-‹˜eâ9“ïEˆÊÐÄS_f¿ËūЙxzñ‹ÿ6ö{D3‘t!!Ñ’îÒøX/v(=ŽnPïsó6²ðMûét0~tÂLjnl…Zv ’k¯_|öpwÓáv"›*WmbØkÎ.<ØìØØÔdý¡¡ºdI/¹‘„” TaKƒ˜GFÏS&R]dygY<æâþ3Ë2œÒÜ3àpN8ÞBÚJæ9yވا·+R”¹±š2Ú7ôjµÀ·Év䜧cµ8«ÚÕéáë4ô”–ŒQëf}ñüË»›ï>úÅŸ<¾óðýïÑ#€~œ}©: }JìeoHô³JöAGÔG(až IÛ«×ÓxÚýÑäwÉPCäb+zcÆÃ[W-m³I2*Ÿ×7JÞh¢˜BJ‡8ƒ¬g–g¹÷Ëjy‘($“÷/‘z%ßwßJݶœ7{Ðû{kR³Ø"Ù¢Z‚‚æÂ÷ÍÎ>ý0?Lc jÇ!‰™µ«ÊÄK «D>ÚªAÜS?N ½lIÐ|ÍþÌ{´2®YꋼG4n!®ýÊGûvzø¶ŒwÜŠ*îy‘äEd¼)×F¹Z=o6_LÇ79î·P»TOî x8ú ©TuQÌBs×v¯7/ÿ-”ÉóQÖlìB&OªLâ1r²Z7Õr›Ný4ÜË{’ ¾jaI˜-^æ±/ý3’„3dÇMQi4Ho½Dî$Øɿ廬×ù’˜ìLxÀú >‡Û8ÜÉpd[Ø,b‚ýÜY£Ý^—j÷´&(.–×Ra¸G¦Fv[v~'ïDyj‘Býçy+FMý;¸ÂMëMœnu­ª«ÔíÕð½N|»Œ‹xª6é5*½D‘Ϥ}’ž¦øžß夲Vï^üÉÜï¦îÕÖt¢ØE™F7Øj©p«í'nû)3¿ïàØétÓîþÄ6;>‘)ØÄ²‘’3¥PƒHcinDâ)Ò¸g¾,^)w bÿ*D„ñß‘·À° ü?R̶¯@ѵ˄þuÔúd+Àáª8x× ÐÐ%]µÕ¶Eóà (çØ¹ÈÛ€è5#ò_fA¶Z?³í3`<_ï¡DÚÝŸ¡¼ ø3©Bæ<˜\ É–T@•«åA&ñU$S\×}ÏÑ*žˆPꥭ6©û $ðm+â #áÕmp×EçWö%>à[Íú2 =IùØstî-oqu‘Lœ¿Îçùdà®Q^$A(肃ô—Ê..þ åOØ0BWÈ‚J 3ß È®^r5ãÐ9»ã-²Þ´×vy­ý–3ÂñˆâÊá>…#ç‹g(á4Þ*³ÊøkUoIMÃÍ] {Ù?ŽòÒ RÔqÕ[²oçcOœp#ÆQÐü†1×ôœ&USH¦Ú¬®ûàÜöüåÏ}Ó´— ¾šçÅju”<…«ùf-T×ÂÁp¾^WšÊï>wíó4Œ:‹º%ÏénÆíR·Ø\.7g7ßýoîÙíŠp*/¬Š~íLV&ÜÕb¹‡ŠõreÔ¹¦r hç×Ò¨>ß"%ÆÚÅ S?‹=è+¬¨a­­¯\{©ý†Ù“™ªÃ׬¡Ž WœjxøNØð¶­Ÿ©æ:²oƒͯˆy)7‘J‡Óƒž€ÛÉ.Üæ§}°)t€Ã(æ8Ý=Ê‹sµòçÅl¬[ÃÎГ§ž[$(&J!Î<4wîÕ¶/snó4¬/Ÿ5{¸ýÿÿ$}óxœEzIŒfÙ™Õ»÷Ý7þCÌ™9ge¥«º&Ûe[wÛØí˜HˆAH-!X!õ† bÆ%{B°DB Ѱ.»Û¨é¢íªr¹²²²ªrbú#þáMwàœïþQ„¢*#þxï¾ï~Ã9çûîË6ßNS|¯¥í}’$Ê~ÒøHi•$. Iâùí•O~Iy•òJá^܉/—x—¨hÜŠ_ƒR…òƒ×>$A%F?ú¤Çµ*¤KóÀp#þ€ëS¯°,JK•¦Úxׯ—Å?ΫÔ`ñàm|6y]› —Ó(ùö£…¸& _)ÿ ëøD­ñ#vµ¾šFÂTlVxÖ¥yð…©eßþÝzkµ.o½ï°"ƒTŠÒZz{„G¬Æçt ŒÅƒSnByú#qÞY|‚ÈÅx¾«·¿®é‡•Jòà  /®¤SØé´6x„nnç­âr,à-íçNiCÿ«ÄOû¯þöüôh9{PŒ§ýê¤Ü¼Ü/æ¶=¡­|JÜ‚‡k¸‚2ܹszƒ+¤ž†VÃQ,¡k#!Sr¯ªwߥtjÛUp¡Á2ñàušò.|âqï ¿â9J.ûË80Õ´\# k¡L‘×/“Äš¼Îª­v~\\£ttΜÂöi.îÎqSp³Ì`.)nQ1:¼† #Y…ˆ¤ 3‘ñ*¶ßÁ…õÆ¥åáãR1Eòÿ ¦ˆ§VÞ3u :E‚c½L.Àþ#¯M!¦7œ³1Fp™Bn{xå–Þ÷ØUQ×0²ï[gÁ‡ºƒñ·¬áx u®—䊅fXi³~ótQ*¹ç‚™ÜÎÇ;ø¸_žEOÂ`f8j;E=ʯ 7â»÷>—Zæç¬ë$äå&î²ýŠavÈ.çù9–ϰˆfc¿©˜*WŒê‹×ßxüÅLJE=}„P!Å.Kž^X –ƒ6¹ë †$tÕÖîÐw¶ëóÕÎ[ˆ¹íe¦Œ¦–œóp#’›eºrW()c͸ÅâM|jòñôrQm|f]«èn>‰ 1ø¬#: Т° cÊ;i±_ì”%£s”6ý…*ƒSRKo»°®)<,-½í™J0ÞH]6š¤YÕžž ÆßÁݶ—„\pLŠæ¾ɽX/LA©6©?ÙÔÔ(òÔTtÇĶ-33-<½–0Fp#ÒL;eðØ)2¤_-¥Þ¾9Se›¤r)Íø€¡]ç$E“ø%v€J˜XËJ-«vßTIÙ·+"! CêfR7D×àÛ@pÀ¤4X 1 /àóR‚Ò¬m\¼5;øÜ ÄŸè-¬¸Ð-€Tej“›Óç0’0N4s‚“‘_œÎЬœ´‹æ+ÄÓ“@Äè´UE¬'k¨o½–ãp ÌP&lÝKâÿZ 8ð‰InÇòç”,l&ЙÉHòI·béz—m\LZo»SzМ€´\ɱ oÚ¹¼Þöà ¿ªÌ˜ú­jz¡žLºÕ#£²ÕÙË„i%7R ™^NUDQÖâ0ÄÍöò sX¯•IE!¼äIè"Kä½PÀ¨ÚØéóvö[.ÇS˜Õ­æ,¬Ê‡–˜ïE÷"”ùˆ˜F ökœ„ÿµ”úm@‚) àRšf^:™’µ%‘&QJý#…¸Uˆ+¯÷d/)5qžÄ¬ø³¶±FÒ DpÜ0°šïp0U@k'~R»QΨšAQko* Ó6¬µ"껼/NÀ_“GtN,E5…FH¸3áù ð° ¨`'àÉw x°`&“WÓýW¼]ôÍI\sv ýoFU??c Qà™P³ôžø5‡‘âÍ@¥…ð~OÌL0ð^É79w)‰¨³¸1-ÆLïàÒê¶„Û‹— XäAîÞëÖNfyj‰e¥ìEE9“[MVOðûh²ƒG,Î^Ø¡w}/E“ëYp, /ÁÒJ´šÀˆQë’”ÅYg½86¦æú¡JúQe^ ø#Ž©®“iyS­›‘(YY{‘7EÉË JÈDRz>‘å‚?⢼à^›I–5œ­ób5{Ê^·ÄO¬€(£,GÐóÈt²§BÓd¾‚Jò~*  KÖà¥$úœ‹nJ“Hv¥Ò8±ˆKŠG,z8:Ä„Qâ„hW’D ÊûRÑ¥¤!áSߢ`as&ã AQSüÛx¥„Cp˜å û‰Hié÷`Vv˃ÄN:'ñ•Öt‹)o3±¥U¢’#½²?uNĉD1Æ"UÉy9‹Ô‰(©/á+É*ªÌ1èüË Ê¦„·kFüÊ‹›¾LìäîPòâRÉDÄ@°Ò‰hÉ/Vƒ©_á:ÒìÄOXÈ¢v¤@|ˆ}ûW¡¤ý^Uɳ4»Jk1žžñ‘ÑÄ稣Ží*cï¿JT‘%²H 7š¡H BXB"!r= ºW¸ ”5‹NG,Åzi}SjGê—yÇ ~ :‘$"!”ü…F‡E±^]­yé„•„vý³âÖ¼±öáWþÁ¹ÖKëìªÔ¤³6nS‰Ø‹žáêùhÃ÷¬²ý25èÚ|Z_q¢ ±¶¥ÐÕÀJ`ègiå9Züß%±õ[çˆ)¢ »xY¬ö„¼«%Frµè% (@´¤78Ñ‘îÛ9|ðkäÁ‚¢’ ÊRüã¯Ö¡Ë0Õ”6•ׄÎâ$$‹)Ä]°ŽP{–âS+ÒIJÁBÄÓ ž—\Š·ºÅ²°ÆadœŸ7ã^fqë «ŒÉ¹ö³‘Ÿ99J„:œ{AŠ8Qt=•¶à©H‘4߆»I”„ŽTê…s$¬²D'’.Ës?,±ˆc£çµ*„R™qÉü$Ä6“ÊQx-–¶=Od©šp\´A¥Q„H.²Ö!ŇüO†dëb@( ;øH¾‘&ŠéëÞ® ùp÷е‰Ê‰' ©ü…Ê0ìËû=‰ýCDñÎuÛ%žÎ¤Oaž Å"µBþ«Š]k¥dÝU┎¨Gc’0Â+R°Ü¤ª)ҼƪC·ˆÄIKašÕ;ßrݬMšåÜZx,—ÐÇe£­««Ó`Ö¡› fŒ†fî%”@³(öä+·3èk¡.ƨsç'Âáœ4DÉ‹ó×ê¼Ëµ¤a¢HS04-&´Æ62=Td.Áipñt•OÞpÃYt2Mñˆh.ÊñV¿š7öûvÙ5§lÇmcëT{(0|R.Íd8ß3ÊÞÇ¡`²ž˜%ç'Š%“­Ûµý\µc%öéZ°S½V2eéÙ´OH9’¤AƒhºÛ©\QOD3€½š¬¸óÍ¿úäþ‡§‡m;OÎç„è{I^¨^¬^L÷¹Ýü@F.f¬Éj†„ÍHµ*òÝzð"D±Wøe­saÏ@j-ó±¨|S…‘Ç9(ƒFåÈ ÙJ¦Í>­®'ë¡«@”èc`mÏEÙ"ýKn®d¾ÕN3j4þ¨JSNQÑY±¶}~tW‘‹ýÃDÍ$™#÷ËTb=Œÿ‰.K¢ëœT‘ìÒQŶH#¹êµLt9îeܹN>}ÕÙŽ…о"“n—p]a¨À¥+Ah9AryµeæúÓ$t[_Ÿ½|„~AT(º‰|4}eè‡nõL§VžOÉáCddIËGÅY¼ŠÅ*ÚPÖsÖ•;ŸÞ3ÇPl¾B'¢Ý¦RiöÑÎæÕf6ºFŒb3¨‰xWkæÈù§ç0¨ëDYÔèi­í¸l–Ùö” 2Z–Ó dDiØ :ÑÛ<é¬9O µÖÉIÔÒÎ’cý~5“ÇÞGZ—~˜É]ºÚ}TUoíõÍQ;?éÏŽ@^$ß´Rf’OnJÈàì—I•ç"~’Ø9Röôïž "¢â@;Yã³r&ƒ Ï\oQQÎ5´Ù Ÿ²X2PÂÙsÈŠ¤Õ¹¬\Ǻ¶ Ø[×¾»:zÜÝ×)8Éçã+`Y4éýò%¿VõHZtšf|=NEÔy€-ðÜu 9 fv¹¨Nû´È/Y¬Ó´ÆŸœoLUì\yíè‹»¨ç[ÔVÙ3y=F#5GÒYSZ”¯!žÔˆõ°g|õa±XÜã¨6N/SäF™8¶?ç¥M¥K*­®ÆÙf³sÊø¡£cÓ<¶-T) „° Tw›K¿YO¯a¿«³GÁwì ÑžÓk>¶mDÕ˜ðš´R˜ð†“ƒ½?r3¶Ü¸TŽ´tÝ"‘sxÖî9ª¤(ņŒd°`Æ7ƒuqÀrÞ)É ö¶!&,Šš¹=ˆ’-Û™Ee[òÐÊÆa…-GShö¾YÊøÝ#©zvâNÄ‘”«ÈÔ8Dë£nŒCë5?hµî ¥· a/))ÌØ:»5÷¡Ú6®½•ó³8o\s`–˜\ÆQ¨úõÈTú‚A’ͬ%4!ÆÑŽXË*’3ÿ±ã•ë‡ÅŒ¡ "_¹w>¹`’JðE@úÈ N&ÆFô’]¯&ý·´xFúWË_…Ó³}•T~àdT¸'N29BáõÐlÛªJ PE^¡;˜_õ¤Éñ R_är–gã+wNßkO^â) /{Ñ‘–TõšÊxÂV‚S0-Y'È fäÌRÃ#¹¡9+vn¹Îr^AT”ÃöÅ爫Éè ˆÜâ\E.v1Ïä°+ãÉcjòÉ^wviç= ?-jÑɉí[`µäo"³—¬eZ*l É9DU,ÙnéäX2d&k1ž”ñ\ŸDQ:¸v^_úF{z‹k(öÀ~P$bœ9lrÄŸC1Ù^FatZšUÏÉ_+Yäánvjø'œ‹÷`mƒ+mãºÓõÌùIÒIeÆÈM‘RÑw°kq›êùÀI`|SNv¿ñ—þöÉËÃçO>o–§¢y]ß’ØÉ©YN¼ò<.ÕQƉ°dgŠ )a4Ï’ÁâÉ©W¦–8½×±¡ÌâªuÁ¿ZÎ4x–›9ôöð¼ÎÆb{Ç3¦8¢áè¬æ%…D®Ò¬òý,ø•€§ÙÙ³oŽ·¯,ÚîÙ½_ïÍÖ·AN‰kBTVÅT›QºÐ/dÈiLl ÷n|+(»Z7§/Ã0õxhÜ€–¡cë^›¼œî;{s°ôÜäãàKïVh¥9© ’K±6¹…´–S×&žû@Pµ#ÇAËò¼Uuúôc¨ôá¨7ò¢žîßi›pøàýÉ×~?Ë˪˜ ÝiÓœ W]×¢Í爳EÑ9ƒæ+H¤¨ýºØ?Š>Ø›r~G'v´sE—{«Ù™÷2‘Pðô¢L=†z¤rɵ7ïɸ:¾/d(ÓTžƒX‹¨y³«ÌˆhÞÝxç÷v®ì_¼ýîg¿øéÝ÷þ•(s¾{@ÙSLê­k~5ºñwà<èdž`&IsútXšjÛ÷ ߪЕ£±.êvyº¶“ð%ó1ªbêsôfàÇv²{ݧõéñKe*€…m‘f ºž ‡éõ·†åÄ*sߟ>ví©(®a} €­é’}®“l„ 4i fÕv¾y=qfñäOƒ=áq9.MË¢ÚÅÞ‡aU]úë$7aêž³ö‰ƒnïæ‰ ­$ÉAd2¨d ŸòLÆwB/YšML1*ó"ž·gÇMµ ´ï'@3¹âÂ’X€lï:mžK†ÅÃ2é&±@¹§8·{,&U}añô—i‰pL™Ùíc×< P¡2²3ùf^NF[—ÆûÍû¹NäD#O$'L±ñ3ÌŸ†°"  ¢¥ ‘oµ< “zéšßvg<õãñU<µä¹*õ6ºtXN²¢Vö¬_<éb€×;öTÃ*/v½»tœ‡6É2 °ê‡æànšï©|œ@ÿ3{v/²¢šå;åh‰oê7uŽ$lýÐæå&ô.²ÝäÓÄg¶9’É<Úó”žÌAs³à0³nyÍCãÚbw@rA†9§Ü ÙÎÿíêW9ý€¤ãø¥[=IáW£´uÉÓu`l†FÜéioUbG3 ‚€Ÿft!d5‹nõÒ­¾LØp Y1ÞÚ¾zåÛÿ°[ÎNŸ| —L7¯.fŸZߦ£Ý 7Ì‚¹Î÷ǤaXŽBKZ¡Nš„€ÇºÒù¶§?áþ•ÉʲÞZ<ñ–fÆo—ãÂ0§Íâd5û Y3ÚØ=ùœ]@°Y9!Âe›º*œZ¸ãC4zÂÊFçH]7ÌëÝßÊÊK*´gÏ~îÛC šµ·qåúþYwüàäáû@‹Ô vlê >©½‘øÂJ¹Ö»™·KlGÊM.eI–3XI‰üÞ-ºÅ!Z³Ów]œì6.gkÿ拇"ÿ‡fѯâx]‡T59 T¡N³ñæ`O»ãŽÐM¡‚ÈÆ—Òb£[UÛ7m3ëæB?#°‹¤H«Íüâ„Rõ=Ï>Pùõ–Ö§F!Û$‡ú@äíqMBi­TìktÈ7v‰ÌÈÝW'[WN_|2?¼:ãá”GN®.Ýzcïú7?ù³ÿ‘ðÔ‹q‘w?(ãÓ´°â5Šm üiÛ3 ¶Z«^ô×¥©÷Þüá<øè޾üY6½–×ûÍË[3JÌÆ7¶ ÝÙ?jãá¡uAO“üb TÓŠ‚e`æ‡NÞ^±ä5ÄY ‘Ãf{´®9bv©‚!5UÂ#¬åxk«Þ¼~ôô é÷uœ7¢WîÛeVlX¾·ÈI÷¤u’®;N8teߪóQVíl\~­¨«‡ÿ÷¿NoüŽëMs|ß7P<î`etµ¢Å²¬ïW'¸:Ñ‚ñŒœgƒ(ÐßÇðÝ—“4Œ6%zù&ËÚ¡{nû9â BÒ·n¢î–'S©ßÚ¿‚ë»°:;.ªMËÉR‹ ’t*Ò ‰º„æ HË-(®_ÿÞåWßúð'ÿùøáo®¼û÷Žîÿ¤9üuâ—±Uȧw¼]Qž ŽtîØ®ºZ–£Ý«oŽž?]ÎφîÌÀŠ*EÀN~ƒEøBHy!hÚ¤¬ênþ©ïêùÁŽ_FúÇšH¶~5#yeYVÖY¹e->Y€Äó²è燞`V&¦”ÑÁ ½Ô”;ˆædÿÎ~²Í£/߇dþîßü'¾÷øß/Jn¾ :DòGWªØñÐÏ>U=ÝÙŸîîí^y­ûO®VÍüðËD­ŠbË¡NO?Õª†¥Åîüô$¯÷Wíüy^©¼&ÛWWÍ043HöÝvà’Ñ¥ÑÖ­fµG&¾CìâHÚÕ,ÁeI-å IÜoÄ—…<P¦—NŸÿûÚ7þÊ/ÿç¿”iœ/.|ß­žõv/ß.Çž=Ù¾ñÂ${·Ç;»îýúŃ{è íl¦T£½î/UÒ!ño~ýwÛ¥{øÑ{ÒÅv2HàÉ1à&ö›y}qhçÖ.ã{_h.”i³•wM=Úºò ˆþÅÇ?%fÂ\öYceŒsÀe÷Æ÷úÞξ,&;õt¯,§ãé¥{¿ø÷ÁÍ-ÊD΀ê‹ßËËq7º¹»ÿþ­eo?zÿOöÍìétûòÐ/ÓéþÛ7_|ö¿¾ø_Â)ôLîÜ|w9›ÍŸ~ 5ä"E<‚8¾âáýîõož<ù Ì3E®3´ŸÙТ©ëíÛåÞ5·ÚEwüØ6Çûw}èAå+ Žróö·ÿî—¿ú©V›WnWãiêæ´ÅCgO~†ÓxºdÊkõöÍr²—W£ùÑýñæ…Ã'wûùQœö¾öþÆ?š½|þòóžÝûcgW@N ùþk¿}ôôîÐ6ìñYœ3„ƒòI’– g[yMÑÇw2³¼ªÆÛmrI9²[oÞ47äßîåãOÒœ<ÚÜûäå—®y&ËÉ…zóæÉ³_›bœÕ´Ap¥ó…¼¶lf÷,`zñÖt¹Õv9{J§¾Û¹4ÀÆu¹±wûïùÁ{ød1?è»…-–H€RŽ4y—€€‡–€€¡Îs §л··Ñh{oÿ­‡÷ÿÌóòÁ´º¨ëkÙøBªšáð“~y’Ì'Y°Gr ‡M H>$(X„Ö™ ‡±,x Ážÿ‡ÿàßL.Ýyðà“‡þI{v0ÌŸ{À¸ŒËLµeÀ¨>׃4'®ÏNž ‹3 ™+VÎo*@ÊÀƸ( ôÍsbSͪØZ[Œ ¦ {y%–o‚cØê)jĤzTW×o½3$ùý†ÄFsWm^AÛÜ7³o}¿ÚÙo–Ý£Þ«'Û;û×Úf~òüÄ­ mÜÖ[´Ž^®KAØ;—®ïÁWßøqµ}çàÉÇ (u8ƒ[ºöL,gÉk h§õæE7Øf~PO6L–Þy÷GŸ}ôçÇ‚²–}wV»×Þ:|ö _ñÐS'›nô{¢4Í¡ìÞúÖ^|úË?‚üÀ¦Æ;7–«Ù³­K¯#]ÚåáîåWoÞ~³m!­^<}tðåošÓG|weÿ/«l €Êó©ö«à‹Ãdœl\z'ÝPùÆòà“îôgæÞòJ:çý_ï*‘™ðnU£ƒ;N›^¸züüåâðV@£´»ÿ[«ùÁt{÷_ÿ·ÿøÏÿé¿øùÿHÒ²ª¶/ì¾û¤Òúó»wÞÿó3”pßåÕ–oO]à›W2¦ã›Ûè³6.\€´¾cË;×ßmVÝâøñüùÇ€¬êâw³ñ嬾¢ º}3Ü̾`vyäLYï¼Ú®æÃò q±ƒæûà0Î)Æ;4«“´·ÌËA©ë$2úF=åôZû­ýüø÷ßÿùžŸÍï\ºÓ5ÏóÒ8Ÿ´«¥í¤Š³Ð¹É ì7V‹cjïøÊa^^¼õu(Ã’/dŽï@4úæäsØŸoUâÿŠÇÁ Ôïº3ˆLå–2³qîMñÃ!s)ïFZö›ò¶§ "ä] y\Þ.áOY1‚õ“«¯½¼û~b‡?øÇÿöl¥nÿôÿÓÙñƒ¼Âã,‡Fӽ܄ñtkgû•£ƒ“Ö?¾ùµßùÅ{ÿåìøéÐ'ÚW›W›Ù4¼Û_9zq¯_ÄJž6BÝÿ“ià.xœUzYŒdÙ™Ö9çî7nì‘‘KeVeVuuUï^›»í¡-Y`ãf$ƒÄ`HXhà ˆ‡A#„yñ0< Ã"£ÁànflìöLã·»]Ý]{e-YU¹Ç~׳ðýçF–EVv+2âÆ½ÿù—ïÿþÅuf g\0aðÊhÆŒýeŒãozŹ#8ÇGÚhÎ|Êñ§½FG®µôp Þ7L*&5¾W_`¿M¿x¥qCVß—Þ°&Î^ Ž;;xö"áp¼Âó\Fvc°:X=¿¹zóև׮_ã\@VÜÝsCF2Ó ì ŸÉÏÍÙÓHŽ»áÞ’Ù{Ö n¥Ç/g¾ïȪ”•TÊ µ¨æ—ò3«&SÿIÇ?; ”!êgf5Hª²ïâï;®Å­Aw#ò£í »»Ÿ\»þ ’Ÿî¨=Ò¿®ÕMç¥×¦Ö‘UOý $t˜QŒá×~±>•JØ#—­ŒÂ×¹¶§'õXû¦–4Z¿qö® ÉY}H22Ùº¶ˆpÇe¤œxÐߌ‚xmµÿðþÛ»7ð223žã±Zݤë1L×ZáKsàm‡[ÿ©?ªðì‡ÛŽ#ì±H p3rDX¢ö#HhøÒ'­6ž©‡a­Ák3д¤.(ÁÀ¼Ž€SqÏ [í•áÊz·<Ý»sãîGŒ´DÚñ]igV;¢¦?è%iS›¿öTúÌ™MíÖ¯ <\i­ë·Ÿi›^*¶¼?SòR½K埽ÜMKŠ)îÔwƒþîâ­ö`ëü¥4=fUöñÍkË5Æ÷‚³x…„ÆZ˜Y÷³"²Jí!Òz„¿<ש*<:ƒ3@‰x­ñÄ3Ùk·¯}G?s¼Žlþì=†»@ã0±ûÌÅ„uo2)gðšÍîÊê¹Éô ö·?¦ûZ·Güò³ê:x­_™:j­¥Ï…ž*…’ßñx#Ždiò¼"#»¤d)åè亶ÍYYq­\öDSµ×Õ"ß\뢦ö\ wËàq¹ !ý vá+¾Ûk¶>¾þ"­¾w-­ mñ“³%hꥵ¡m‚©Hð7€ÍEØ8AžVdcޏ•ö¡WÔFú¥ŒXÚÁ¦agwÿ¥‘çå+c0ÍÔÑ]á^ä‘çûžçõZ­>ù™±Êdz|7´YÛûLóôã,s‡})<•æ`‡¨ÊÊ^†ÊTx&Èó\[/Zªž”íÀ÷Œ•åÌgž/¡‰œGØH×Vr€=:å :ï‡ø{emsÐëfóÙ'×ß§à°g÷Ý@Û[r‹øö<Ùú®ÅrJ`·Qê¸^í™H/•ëB1±ï²Ìæ‹Y%+ gHCFqŽJK<ðÿOdµðf‰ü5¨r]{UO—~-Ï Êªxîò+›û{»7n|hƒ›> \hÏØ\>غ °Afj·…€!‚Vçd‡Q" °•ƒ[´Ôub².Dêß®ãSt(›ø(wCB]£»WÙ'Àc\ª¶ {‚×u}YUkëÛ[é|tíÎ(VM­K¸µªª- £ÄdÏ¢¬K S°euº¯ü¼,•ª,P‘RÏ’Y‚¨ý'„[Õ&åä“u~6‹¹†U†tŽÃ8¬íeŠ ù à(6 ?‚”'­ÞÅË—…£þôGoë¥x¦ïøÆŠf(¢5ݘ‘ü‡óPB60­œø$ôAv€j~^“J—˜“)¥¶™ÏúpÍ0pSîÁ4Tíц<:áNB9ô_èjÕÙoñ%lØäCèMòÃðˆÜ(Nš/?oXñg?þcM¥³ÚüÃ!iÊÚf¥%k¶4¦”•±þElÄ÷é•p*Ͳ.¹ÂÁ€Öišì·GlÄJŠbÂõ…¬Š‘T•ðÚ"Zc<&·„›ëq•î1“[¡Å2OZ§¢þß‹=?êö‡ÛçÏk•ýøÝÿM(am…У4¾$NôUÇ22¦,*xa%*po¡™Ej°!ÀÔl~d&áªN¿t2ßõJ øH$+ßs«ìßqÂUáÅH$¦2j¬Š§LgäÁ"ËH-É !9`qGç“8i6ólµAå—•â. «KØEÁ%¼Äz ÂÂ'óÂXŸbÊ¡%FL©Š}¦2›ïˆNiè“ä·I`„’H$I# A£Ù¼sçž$µ §dQØ5Äá¡ßñb [Ã’Žhás/ð×TW³ªœë*sÂÊÇ£r R,…Q²8¥ZΣª,áΆã\AMÅmÎP”Ž„I„¦JÁLjy/ÑeBBòf‡PO¡8Bø„ýÁ Ñòfi~|4r»Òâ"ŽVÄjr“gã»F-lžAÄêº\²Ê§š¨.$'ýþ ¼3-òJyy®q½Õ-/è=x Ar'a"Æ×3s(¾ &x_L·ƒ¡«"܈À'„ü¬, ¥¡A¨Aø‹ åx~¬)l<Í 5 ·.Á<["#G<:ŽÏ ˆãrº›w“–!Ù’96e¡ª ~ëúI) ¾ŪDË-ß,ÅÌ‹+K)™Rzt%ÎI9’9Y¶®½ËŠÉpuçÒÁ­ï§Çw’„M]P‘.³,~-¡,†ÓôÚ=—²Y„§, jv^úµÙñS¸q¼J‹0î p[J ´æ@G)LË$Ž´ ¥œã4\ (Ÿ¨#Œ6í¶¯ŸÁ~ WÄ”„K8†1à ž®ÓZ]fR6áÍ•‹o|óééÍïÿþ?Ïfǰ¾¡ƒÊVIîY¥o,ïuzín¯Ù>šL^ã7ƒÞKÉ`õ“Þîô¶{½õ¨¹2OL\—Y6å^€ÂÔ°´¬27ðË|š„‘,t©Rh˜ÉPЄ^àÁvy 8 ݰ©Œˆ©®æº(¡œZS§/X¸VAÐèž{qõâkºxúÁÛÿ^f#[‚{–ŒT5±¼ÇapnP¸vÒì÷‡'§W>ûÍ ŸþÉâ%ÈÚàB!ˤ·ÖYÙzúàv‘Oæ#½h¥Ìr!Óùl¹ 7A=¾˜Í­"hzq—(D‘ê*_[¿(e9›“ÁE'hø¡*ËéÑtz_*ß°ˆjgª¹+$SH„ Äõbz‚Â.ŸÞÖrZ—J¼&óµê9E*²‰´ÛƒV³[(tŸ—^;¯rxþ°3,Œ[ä»Å+¸ö4/Ò°½5ÎÃsÓÑC¦fo|å7~ô£ÿ>XžÜ|ÄH$‚^Ø?4:›Nž>ê´ºƒõÍ´œlœ¿Üì_¸ùÉõ»ÿŽ_,NŒÊ™{á*ü³‘´:ƒUßwÂFJýðöµ2+dqŽoj9·¼Ù9cäóÚ,+…ªª\'Z]Ý®*Ü-t“MÞØÁíÓÙ“µÁjZVQû\oã5£¶ëh’Ê¥«Õà$a¦fwX5!ºI OÚ6ªS÷Pˆ«¢¡~ùUD8O¹Ý9ø›öqÙÊù/%íáæö§Îozmgë‡ôûŸü¤ta<¯1,fAMB”ÃCjߢ´¨2]™rl4¢È,¡Uê¨8QØXá7†YU¦ãS5_²šg÷g§'ðª“]%œªûªj®ª’œD§*{ÀäÄv=‘¹ Ûÿ¡R”Š|NA¤…<Æšo¤¥«Qñ«oþöJguïþþù«Ÿùêß|û?ý›§7Þ+f³¸1tZÛ³…âÔwŒï¥*©†L§‚/“•HIn¢lg$@i§Õ{Ñí¾˜qozt§JO¯6Ö‹ôQ:¡~å(*É9ÄcÊ9[Ñ@¨Le÷™šØöŒ¢Ù£ãúD'l•g[P.¬f;€ñWò*ÅÂÅk/;4E _þü_/=qððgã½ëé|ÞY»<Î=¤6‡I‡š3pøˆŠô|* Tf=Ë ôÔeêp?HvxóR®M¹8ÒÅŒn Q¨,H0êxhªâëa -—hص€ü\Í©«J>îMv†üœd¶-! þ桉ån¤ÜA!á<>ÐiãÜËEª°™ôÖoó“G2=u}×kG³‚ì_Ž|äœey&LAµ¼¥ÎÀ¤<$wCÁCî·5HpA ÎEQæQ¿u‘û†\Q·ÓPÏV@þt—É™¥¶ñlgX¨;ˆ>Sƒ‹¢Ëñ]·žðHºÝ\¡¦Žpý•—ßܸøóƒƒÇ»BÉôxo19 "ñR0—;mTðv° ªJA‰À™ËÊb…'ánõžÈæ–BñU®qp$y2ÂC%È1\½L¦ÂÎ1]ꓨ±Lw¹ZÔ“¤z¬A>’ߥ6dv5õÍ(`|¤Û“ÆGPÀÿ‡—®œŽ³ùñ£ë?5Å´L§µ<ÅýäD>T]e5Ç=Ð?ѬªÐfÉ\AÙ<Ñ&†Z‰¨…9¨÷ó™”3›CC[Œ¨º¢d–4ÚF½oñÎq"³œ\´ˆ1QÏ4üßshXSÙ„àÜ#Iøm¸¶6A>ûåoÃ<ÓÑþìäQ6ÛªxvTÿÀ¾°càð¢33:•ÚáŠb-TT SHÂKÀr · Oq¥–£ 1Ë©%®õìsÙ3'_B@˜±Êö˜^,gª4Æ6T<â»Ö]€9È uÀ šýÖÚÞXž»jªÉk_þv&‡o=þ•c»ÙF9–™A)äÆÜ‹Õ‰é¤FÍ ¸ÓPÚ7un·ãbª5l£ n 6bTŠ2Ÿj^ƒõ•WÝ13¬ð7nRE‘7yünµ8$Y)(¨³â¹>±êŸ{®R¿Â 7¶_Û¼ðãaÎxsuÛ󆧿õ/¾{ôèÁ‡ï~7›ßngóyVIcûšzyŽá ÄÒ3ŠjTScG,'¨Ê2u²¸bY÷wñdFF„v]ÆK꜈€ªAßwýÀŽj:ˆÚ"h—PT~4~ðC•;u¾ ¦0§î5÷üÎ`ç3_ü[ pô¤Ù[/çæàñ^ ØÝ–åôàÞ‡¿ý»?]=>|”´$éþÞ£»}<;9TrŽÐÂ1à0ZÔªpzjk:Îú>Å¥žŽ°lp†%è¦NuÏ"ļ ²3mDbdkyIËàv*çwñOjTræ5›«I#jõâÞŠ´àuÇû÷ZkáÖôè8Í]áõ×6½Ð=øÖ?þo+kWÖ®¼®âèz>.ÞýÏpç½?ž߇[T p—0:‚BJèa²zîI¡d[ȃÔm¦éX*„íü#d@wl¨D¯¨qÊD™áÔd;E3 ãø¤Ù“éc#gQÒ âv·u~°¹)=ìD§H§@™þÚöôôðé£ëˆ}TƒAÐÖA(ª~óþÇ Wþòú•Kn—ešm^bå„ý‡öOön~T–ºP.sÐ4Ò¥ÝËp ê;²FQf¤™ðrødQv¸«)é/l(YTE%! bJJö=ø*‡/µW.qÜlvº­¶‘rÿhW2Öi­*Ž*(G¹ï‡ÝFc4ŸŒ²ù´ÈE5mwÖ''O¦ÇÃöÀ Ão}û÷{ç^h.!v¢D¿ðú@øÙ“{÷tÞøàát.D0˜Œö'û÷ß<9¸ ŠŠ@¥öe½¯" ‚MAo”iø ž$[²ÓJg'Hešz_©m"·i$Ä`ãòΕOŸœÜbNÕ¬”ª'~çÜ"›ÍŽî®m_íôWÇOM)Š¢žTÈ›N£HG¨ƒ¸ŸNË"Ö!3}ýïþ»€uVW_tWzñfxéõ–Ïô|&Â&Rt:gy)ËS.¦÷®ÿìOÿ×;o½Ô¤5ð¸Àà^©Yă*cº$¢ÂX¦äTÊé׃Vw¦9y<9}º8y,³Mvh4OÕ¤ã†PU4G¤†(>xóÿZpëÂË/}zåù­ö€U9›Ÿ.*%”æ“Ó8ŠºýRÍì¤ã`<Øýè'£ý{²˜Ø’xî2Y;W4 wb ÅðYY¯ç¼ñµFÍîpãÜ¥—QÕ‚É”Y5ÏŠ´LZC8UYV{£Óý“ÇO'NV.¶»nð‹÷¾÷áOÿ'‚Zx>~hU6‹›]¨O ’ªFZ>bS¦J.¾òµo]{ÿùbÒh÷Öv®^yù {»·ݽ}ãÃwOöïå‹I™-àjL„vËÅŽ·`¿ë¨ öm{È`é›04ÿÒ7~ÇÔ¸Q´Òjm´›Y^Š0̳eCÔh·ƒ¼š>Ùýù||ÌÊreëSí^_±ôvo÷ÚÑÁžÃü"+˼*5\z`Û‹ã0'LJ‡.Ò®V/¾öÆ…«³|~ÿÞÍét„4t°wcr¼7=~Hq­V”ºphj}ÈÙmÂ9äwرC1e{ºDSßüæwð Pmßz‹üFÔî PåÇ'ÝÕ¤¹zz|;ªâ$ 7¼¨i‡šÈ¡òàñÝt´XŒg ˆ„Èô(¥ifZ­õ(jì} &òÊëoÍŽª²œÏ'ÆñàâãÃ;$³©çt¶ME›icõZ€²c;×®ÃÑp‘zB" Q«wÀ´…Ћ/½õoÓÅßói‘@iÁ‘5`áv#Fµ8ŸH鵺ší㦧£û³Ñ¥7œ>iÊjqzøåÕ|<-ó™ÒÙЬ$±Ëà¡#ÂÊÃl2–Jú)d•‡¤ŠÿËÄr"_ѯ©hDÚÑ÷—ÝS/9ÙÝ!x>²Þ¤2åk¿[Pèå8‘¬Jæ€ø_èô×B»Ltpð¨†x­Áê¶4‹t1šL¸2Fõ0.HéáÓ½l±«Q@øbáyȘ "?´q3§Å ÜU”%HJfć©xÁëz¡Ëúƒ¶›NºÞ·©ÃÖÎàëî°ÄoËzà d:—ú̯ÿË,=QÕLç(épÀII§ßé @'ã£4G¡ÍÍ>T·˜žÐØ”)ÔºQÒD^KÓâôà)`„(Nǃhˆ²Ø84Óg„x¥]æFeÆäV¡Úî Ô4JXfÙpÎåb¡%I»®I-¤³w¬çÓ\ÞžNëËŸû6(b‘Y‘ûSVŸÌn‹ºµz—KYv£˜[ŒµŸ:fÙ ÐöÊ`¸õUÇn×Pj àQÈÕT6{žµ¸€¢WÙ<Íæ%œÜÖ3®aÙ}E J’_v¹¸"+ÔϱòEÞb·b Le'º5uÇ®ÞN<Û³®w¯œºÆ´U|½½#–«¿õ5íx†Îâ¶ÞD9€Üçù a×G*î˜ñ¸¢©:IÔ«*8Ц¨*Ó¶Ècõž-¨¯ãžlñÿùžRÒxœmZI“eÇU¾™yÇ7W½WCwUWÏݲ¤ÖlÉ6–dKàp^8ÁÂ+öìüÿ ¶&ØAà ° ò Ár·ºzPwuÍUo¾Sfò“÷¾* J­Þ»7óä¾ó“GÊÐó¬ð¬ç ~_üˆêI¿K©§õ?çÖ·ü–°Â}èÑîô™´´™ÆÂ3^õ="„ÛNðg‚¾w_xVJ_œI‹Üîbq¼+ýXú1N,{þ„¼m!¤eùëÝc´—¨ä>“Ÿç½Jt÷†uÊ:[ÙœÛITü[ ¨ XÖ’;‹v&»“ŸNÀïSzÕñ-ïëÎe*­Ð",¿=/5µnç3A¿hâ…øN’Jô‰!å;#{NpQ™«^¬–_Tºú‚ 9ýK)K`XÔÊŒ5d;ÈoŽáLjkYˆWíõ¥¥m%ÔbÓÅ›¬"§IëV¬Yø/¶^Ýúҷ絩ùŸ§ƒð† OG¦7ƒ‘#Iå“Îq ²wÙÊ•BØMÎl*‡rGþ’Ü#ö ÛjZ™ÖEL¥ÈÔÑ÷R8p¡!}åã) á™äNã^aùi?c ïdlíõµÑ¿ rûeýx‹#ØêÀøÞÔž +áëçXøzÖ þ€ü S²×Iç$-¦µ®ÌU9[ÔÒQñ#¤Ñv!-q¥Ûÿã0_Ò¬÷%¿–å¯üß©úì`|ìs¶à÷”ôÏi¢¶‹AâëZx' ùÃ(Õ¾ëØ’žáMíBY¶1v9ç½çÎUË.Îâ¼Tü#«bŠJ±_2\Ÿ‹Wðcà^©RÔ b«•Hñdûçÿ¶öÿ¦+qkǬ@ÏER ×.¨ÜAΡñÂ<5òx²–ß|Q|{¦É*VB?(uÁލ,›£NIIø—R~¡¡þ’Ÿ³ƒÿ*ã[GŸõd} {&[uŽÿ×ËΠ–M­Ø¦%qNþ †D‘°ÊG¦¥TKæ ‹ˆ*Ë’$>'YgP„¨ý–ÐÎ0¤öŸ…ÊbŠE€ŸÅ°8÷”t‰:*ɪð³ ß Tè?¶XŸŽà«À½§„B.(M©­nÉ Ëð'œÏó+ájÅvØùYÓL3Îû€^È¿ÈS_ôa¬pVr¶3Àgœ=Èõ ÉoÏË/[(P†…/p C$8„ò¾,‹ÜV.œü¬–@²ë›sN`L­S[At§Þ9ùå9÷f“º'±¸„>+ À/Ïdõá(9:ïg1ÀYc‚OG;B~„0<Ù–% ­)?´:Sĉ¡¦‚èFR ‰^fµ•éK˜X“#/u T±o6âœð°'œVy2NÛêt`¶6µfV0G‘œ¤g6É=›asþP5`Ì7)-–¥P‰eÿ7ÅÔ)ögÉCRÙT4Ú×ÁJ¡@øp à3¤FíImؗȾ¥ežY½†Ü ¾AX¿é‰Ð¥QcÉÈ-±¾ç3œŒñ‹Ù]&"¯²K7R~$ ÇÛ¦:u‹4PÎÉâ@EXÙoa}K‘eÂ|%0ÊãpÀb0½òÚ[]¦ÓÃ{ÃýOB_Eªñ~Ü7^Húѹ1i™ÏpØ0îØr˜ÏNÙ·ä·"‚Ð#þi%œ0!…ã+ò†¾`ôÌØÌ”)>Q22zNA¡"A' <Bì¢d“ àGÄп :ü-ÎRpDÀ!‘_|a%ãäŸå¿-²ñütw6z*m*¼ ¥I†#‚É/BṚ¹±&Q6?Œ›bº;?ÙæJVóUØ¡°Â¼4 ìÅGº¤ê LÇÉ…Œ˜³#f‹*7~"Ûg­•×u‘Â@aØh´–ŠlVæs¬iE``tQê(s!ñTÔ ÃÊÍÆO„™Ã¹ 8W0~K3I…?T¨†q¿¹¼69øÝòÊå0”GÏ>êô·‚ SæÅÓ{?ÌÃ|”e,Ì„5ó#tdкҷP¸.‰~ê+ËŽëBA{É`eë=ãéFw§œžžäó‰%OF(E„*%åDÀ+h$~²†à+¦OuvHÑìù„]"qT…ñ“p["Y@ýíµ(n”Ó# ÉŸ{ç‡7_š<ûèßÿqÿáÍuJ†Pœ±H{5#…ì "J›Ð3Ed è\3L()»}ó?™ŒŽN‡»û?å²)U ä18 ¬P±NMAIùðÓ¶€h›œ’7z¤(ÈLŽ@D”dÉP5Álz·óÉ^6Ù-ÒS,"ƒ†Ä[xÔR&¢x÷ê"g¡àÑ”,ḚìˆqQõgHA>g˜ÒzåàÅå“Q1‘¿"°ZUùYæl tH‹¶t­ã¹B’À®Fp:¹£dÜ‚T ²ceDQ·¯ÒÉ<Ÿ’®ô¨ïà/2ÐÚÅÐcàJÖɽc…æé¾« þ8àÄR *ÕÓª!EÙ–0®¹õgºÌ)J4§GBæ¢bšó)$§V“o]ùîeH…,8œœpL Æ ažï•Y }sÕ¯‹©Â'+"†f6;Ò³=Ä‘§ZìSZYF"è D4;W ܃2At ímÇyÛ¹Õv8Åù]„I/\~›ðŠ<͸ºƒT-™ Ä‚™0W‹R"p)#8 Ú#Io šQ²„yÆûi/0(€¶ b…ÎNL~‚´nŠg4 ðÃ.Åcþ†Øš(.Q8J—T›„ û˜dþ¤ðâf7n-Üótzç«?¸õüÛa÷~©¬ò«Æœô¹OÅ•qZ¼h8Ý~€è@úŒ€«A'ÌŠ,ÏKJƒØTzÕó2¢š îêå”™ËÜ̇&ÒšÌï-®8±&¬H™¾ïÈ"?iõ/\{uíÂ+Ͻ–NŽ­—Ï&GíþÚÉîÃW^þöRw0Ëæÿîç­ÖàòÕçãå÷Ø×K:óX8¨g´#ä Ñ*ŒÃFÎŒSúm葊Ú:•ÙÞ‘ç¹6°Áª?ÁËàGàbnËpÎ)|` èÍhR/39(-P~3j,uúz«»ÛÿãËèö·¿úþ_,­®§)’× ¢ƒG“ýK·îÄ^[dQùûíÿ>ì?R2‰ï»ÒÐÖ1Cñn ×¼Ä#”Ÿ„Q®®mn„‘FÅ"Zxd7Â* ¯ ”CÝ ™x”ï‘FŽ‘€Áj@u>p‘ÿˆõ¢öÒÚ•ƒ°5:|´zéªô¦×o¾vôù£µ«Wƒ0Ú¾ûád<¼xù¥;¯¾¹Ô[~øÙ;Oï_¼ør`Ât2òcÿÖ›_ýÍ?Û{´ ¾`‘ž`ª MiB2 +€!“‡ù0ÈÛ:$¥§LÚ¹Ã@ßjŠD¡*rÁ²Ìt1 ›½¤µ¶6PEël¯ÈF­þußo ;)çû¯}ý»½åÑ|ä{áê…+OžÜ=ØÜH:—/??XßÊM1Ÿ‹ñhgû'×^|àq÷W?úïrY,]…^µ¶!nÈ€I`cìq¦aÁ:ZyƒE#òºéŒÜÄö´­S¤câܨ8PËE»þ7¾ó—&›?}tïàÙv¶ùQÇO6v|Ô[Z}õ­÷.]»=ÎÊtž>»÷Û8Žn½ôõÞæEpÀf%Jyóù)H½ÉóÝÏÁ9ÚÍX”i¸ô®õˆÙ y1N Lj;(I¡JàBu,¹S¯š¨óFÅE@ä‡ò~› YP_+úáÅë/_á[½ÁJ:?г"L†OÃXÜyóÛlìì£bãÆK‡{;Y6¼tåN îõÆG£íû…Ýõͯõ{]…|ÿø÷«Wn/¯o†I0=<<ÚÝ+u|ÿîÇÑÒû†ø°c\%—xe à µ‰KXË'ª®9ð!‚¨‹¡4mæÐL£³ÒlôV/m]}Ü¡ÔcÀçìäÙ³ûíîÚí—Þýp>Ûß?xðä³»eV4ãV~߈dw/j¯í=ý”(Y{Mf»  K:ý<;.ólyýÎÚÖKEv…”%Nžì|6Ÿ‡Kߪ †$¤äeEÎH䦵äùŠ[C|:º!œa¨“aÔh.¯?ÿúû7/÷W6µ.?rÿdo/Ï-„èÅ$˜íŸOÇ ó×nF;Ãáþ³í»ÅtÞëÞÿÞÇÃ݇O?Û;xöècj:¡ê›ÁãdMù±¢"£ „N‡ãrz,ÌhõÒsa#9Ü{Ô^Ùê .…ý·¹ùCõ³xrκfrƒKû)þ…ËÐÿÅ[o]½úrP6.{*Om‘ÏÒ§Gæéèàév>Oûnßxá¢<ŠÂþx”=ºûAšÁ×6o¼ƒ"-,-¯[›=ûü³³iJ‰ {š²Ì§º,”ß"4v¬¢`rʳ»´üÎ÷~äE­_þÇOu顪 úo»>–cHO†ŠÅgA>X*(TséÊê•ç–/¬ V®NgÇq£­§ÓrtGa§¿VúÍ,óú«—æ³ÃÏ>ùף݇îV§wÉØ`6=Ù}üñtx¨ÂV”´Ã´–zE Š®†u:CúC­çûà©É'š÷%È+:Mkpµ˜›ìtuóÖµ¯|ãäøtïéöð`5ZØÿCwµRÇ wA Q„àeq#ZÛznipyëö[I3ö¼Ñätzxô¨,²f²|ðøn§×ïo\ž‚þE*n£Îç³ttxx°so2ÚE~c;¢ ¿t™Q™@`«Pä•ÅœË7fÞ_YêäXQfsP#?ê"‰Ûrš´—/\»ƒêl:ÍF§³“}Z–éj²ò})s ŸÕDP¥Þ`[u—6—×®÷W.Pˆ-?ÿì7¶Ì·¶ne™nVÁËŸ=>=Üab¥†G;óñ´ÛßšO‡‹,CÁœçÓ¨3ðE’M÷˜t!Lƒd,©†2 %“š¤Æªøq“š¨åüއ£Ö 7¸ ¡²ôpïóßwï[ªJcf56i¯¬Þü«¤ÑH⤵¼:ظâ‰yo¹Õlu‡“ÓÙ|4zòà×ãGÍî Ó])ÓÑÒàêÕ[¯ÿîÃ9Ú{ìÇ*|}åN»¹¾÷äÓáѶ!  \žJZÝÖªkBjÐåÓmK-÷´âÏä$vÿYÌ`†F³¯¤<`ñÉÉSPÀ± Ä‹" “n½™Îê%ÄïoþÍ…õ›k+—òr6š> PÀ§)49<™<¾÷kÐË2MÛË›I»›ŽŸNOŸ¾ûÇ?Ž“èƒ_üóòêY¦,Oïe£!,Žb~© ŠF¢P¿a- îä)§tËàG~Üb’IæóÆ1ãÖ†T`|ÀQõ$uº “¥Õ+prd±V»¡³9ìµ¼~}2¿þ§'­¼|åEä¨y6‚cÄa Iõää/báÇwÙ]ºÈ ƒ›¶+ƒµ‹‡;îüÁÞ΃t6¥¶cªÐ„AAQžøH—2î®_;ٻ͢˜••«HåQkÕ‚É}_€¹Í¦Ó4ËhZ§ ˆDá Ý\¯·ºÕ]ÞJ§Ã“ý‡6Œ[¡/V.lô‹Í:«ŠëVïÝ?ÿÉþÓOâV'êtŠ"í®”sê@æìWõ×.w{Èž“_ÿâŸv~Ü[}~}óå'~><¼oJ0I‰<ÒŽzÓ÷ˆ§°ÑzÄmHÐhu§£'VûÁØe6OOŽ…vû[×n*¿Ø}ôéx8FIê7¢l~G”¤¦Æ|> $®Kå|<ÜH”•ozÀDÍÎÊæ péf³+½òÅ;_»qçÇy9ºñÚ·´gÆ'ð½$hœ=_\½ü|wpùÃÿü)xÄ›§zx¸› ÇÙ|‡Ëa*¥eЂ“SÖ+ P.‚ÛÆú(¹©Ý V=_‰l¾„Zës«a´ Âfv¢FO…aiŠR{Ùl*…öƒ†Ÿ´`M$2Í¢¤ ÇVt #ZÝÍ¥õkn³Ù ^yåko¾÷÷Ë·N'·å,¯Þl5–†‡‡§{ÓÉQžÏ” :Ë— á"Ϧã]eZØÑQ9Ÿ6Ü È&ÙøÀ£æX‹¿Áâ®E@½Gù¥@-ãµ¶|åã'lkÑ)õg¬4Iá( b‡* ÇÓ^ÒZYݼ"”ɦSd ÄBo¹Eê…×ßë{ÿÐ[Ûüô·ÿ6ŸNáíî…t:šœì€r„ÍÕÁÕW²Ùñh÷^µ£vš”…˜O÷©<>ÂÐh@å¼ÈfDˆ¨ÿ [—®" Þ,\ ÀŒÈ‰›tãF,·¤n?7v Aª‘2Aˆ  ‚j%C!UÝ~%ƒÍËí^g<<«i´–’fçò­7.]{õ?ù 0îäàáÑÎC$}:|˜äsdðÕ±Ÿ4ËôDBš° –‚œ2ƒ£€2@þùd——Ü(ãKꈇ,? JŸ[…6ˆ×D}烷Å1pw6‚à‘³ž«`…ŒØ,ÝÈèúš:÷Cd°ÕÖÒ(Ô fÛ[ºðükßY]¹Ý¿ö×~«z”€ð étew5à C¨O5- <¤Ô Î3jÜg“<!¹º€j8³‘ "† f¼W“CÔHضꠤ‘ÅQ€7q6=¶#årË¥AÉÙƒe Ò‰6ô"È£/»«WUÔ„Z–.^GªS¶ô½hcó…öÆ÷Ý}•Û8EJr—¹Çw’ûäR…Üe.¨ÃÙ¨g COˆoX׿¢œ. HiÒ]qòB=Öݨ‡¨Ydˆ0σ¨ g.Ò”›Ù–;´  HZk`‹ÓÑñê±Qe±´róöëßýüÁ¯fã#œåJ†íÞJ²úGn'Ô×ß‹| ­‚’œTÔð´_Ýq‡ÐP]F4Úcá5ójÉmgÿÜÕ¡r­.+è1nšIªF¹˜Pa”g¹踋92¢v×F°S/.´ž º^ÌkHvKë·Q|ƽ”SE£Õ‹—¾É–/‰Çø Ž€·ÀyøºÕs}˜jþ A n<íUš®ƒéî°BØ,.ìÈ“Ar<ׄq3tÉ×Ü£&»X×ðÑ|üz±¯" i("P±Jº¶°Qs)Š»Fs»O”Q÷ jý ç!§~jG»!Q©WTSD¤öÚY¢øO±o»ÛLß]¹áÏ]¢R§±äÚ:ç«%nÑX®ã„¦pUAHëZ îú>ør§ÚïRPÓÅʸVµÈå£0n¿JMu¢‚!]!ÉJ½×»‚[@Õ$@u¥ÅóB8¾k¶PÝëjO׃ղš4«šìD›Üá AÒ¸V2Ül×nB‚ ·šŽsÍWÃu×Ý|ÑFL†ÜŠÛ\Ô`R àºÚwœáø6ä›Þ̰;ñ€öªv¢smîË9ÕÙêrßÝʱ‡Ñ½™¨z¿ž»-â÷4+\òiàP±šÐ#±dx¨ªä¨§£yîFLÒå)^ÝY ƒ#eðµ™c QM¤aëEÏÍ3Há2 wPØk8ËTcu†x‚1ÕÚÙ¸‚»Mæ#xÜÄ8‘ªƒ§ºBU °Ô¬mÄs,®ñìi[{»àæ»â¿¸1 »3BZ¾.ñÇš·ù>‘¹©/dµL=‡0nF…ª9rrëBÒò=s-ÅœßcOv’ÔGsNDÆ%g%¼Ž;eÀ½íE0Ô­Õ|óο8¡xœÙ—øþÂÉO$š·ß1ÛjlÇ™’®ç¸ÿ©Ù…$_1@~¤ž€r%}î4¿_ñp%¥–ß«PȲéêG²mí‡Ü0rV#ù]ÿ|1/ÇÓ®ïÁ# Ü“d;wËLÍû‰/l=ÇúôªéL¾kåæ¹?cù)ñµéãÂÝ\Ô7ì>îb„^{ççgªÉG\v³¶ª>v×ûn¤¡rfá&b¸Q©èÁMßñÁ+覤¥ÂÖ $?éNT1È· ÕÜÝ4™zú¢ZÏp»i(—¡|QûX=ÐÃÃX^áÃ:án˜³—¬§#l=¦¤¬Óã ƒ›ªf•ÜW‚»Ê´;]cR]ÿo½D Q®-âT³¶¥p­Íj~I0øhžaÉÝ@;[-¿ Aá"ˆÅÈ3¨nèåÜFîcSµ]«‘vòzZËM< 7€ÊǤ„܉€‹f ^¨òM•wÜyy6èUOb°>{HmD'<…ƒ‹¡z‡ÄPÌ(“Ç@ª.F•l…K;_mЩ}'¡ó7×0èùä™4˜'-ϺЛ(NZÏ ±:f\ ²é­ ç´Õ n=ìe« w憊…8“ßráG‡W\8eb’åáƒÂž %ò_ŸW¨çþܽã'ßQ‡ðÇT4ÝoÞVUýs7êâ/…qq]º±3çõhíYx£ã@Õ­ÏG‘®¡MY»ÒÏÂ5ê¡8é,^û]B˜JôEàPtøÄÆ?”à‰æñ¬ð[7=C[^Kó߯£àñ0S‡ØbŒ³’BTĬÂÁÁë¶ö²N„ûBUtî l|¯Còª¨âb•Öa 0nžÆù)DÎǨ‘"ˆú3Rü/Y«Zxœ]z Œ%×uÝ«Wûöý}ëß{ÏtOÏÂ!‡CФHŠZÁR$["Ë‹D6AlÄHbÀˆ HŠ€8˶)RÉ"E‰Z8”ÈÎÆáì=½wÿî¿oµ×{•ûê÷HBƒ?©zuß]Î=÷Ý‹±€Ø‡PŒâ8yË=üÞ²×¾ç0Ça¸$ù&N¾áPL㘲»¸‡+°¿8¹ cX™Cæ 3å¾ëØp¥ª(„?’{Øèèþ£÷ð&>zðäAèH˜#ÙâÉ“$IV5ÓõxÊ/…>’drÉ‘üñd_ŸH>¾áÐÑF@~]߯Ém6×ó<’Eϳ}Ï-pXC=Üs"ÓDrøÈM„IäÇèHw$Y™;’žýQ^ = KqGúGÜCÑÑD ÇGw%+c~ò´Év&B&«QDIüðø^EÌ‹AàÃe'˜X+†ÇÁ !Áä9ÜÑš¿ú7YsˆŸÏ`Êç¸_ÀÄDA6ÓÙD°_þWLná~áHG¾Ä¡ø‡ŽtD'ÿÓð/«ºç:$ ÁqLDQát&D5bòS(Ñø‡~‹Ód» 蟰]ÿbc‰M:< ì;Ñÿ‘º7—xÌÑ–™Ûÿ2"&~3µ?Œ̼%BÉ@1˜ç%Y†5|×O¤ŠáXDâEE¢(F1…ÀºŠ$z#B ÁLZX‹¢ z¤–˜~€P’U$ôæ,ÙßÄÿ©}v#:2ØÑ7À÷‰¥…Ä(‘–¹‰cö†Lü>‚Û˜éTÅ®ãB•Nbç°a’"u:¸#‰DØàvœÜфڕCâüD•ª™¯rÇCpØD>‹¿ôãD«¿ð ‰šÙ" ‡ä==ú‘} É#xpkP0℘ú\Lx‰’È‹ð\ì F­²-`¾V­Ùΰ×ëcv žHòƒKq‰œL~,°r”(>²o`AŒ)ø$¸=À!° ”láÿ“?‰f8î(ú{‰9ÊT?4E“+±Ì‰‡eD\vAÌ…b.øQœ˜Œc@¤›¦1èw& RÊŒH(D6³ï$Ö˜ ¢ÑQ$r ‡EQH§ÍQ¿ &‹Xż¨á_ÁÿÄýqòŽ2àd”x&óv07ÏäeÎ0¹OvÊ1 â9^§”p Ž<æ­8AP‡(ƒ¹Cð¢˜jZZ’<Q–]gÄâ“„Qâ@ 'ò3C‡‚ Ã:àY/x~˜N\ì(Ë$1ŽörÈð…Õ%Ý¢Q”,Òt,"ÊJ„ïÈ"'ÀåH´½8$°ÌT=ŽBbv,™aîap‚s%CŽÚ8‚<š™Â؆½³l2ì(•$Iv\‰ïp“\H> % ·`^ÅXIäFÁdŽ‹¹ÄUX¤3gøÊ#æ'DV^äX^  ec zFš,‚¼ˆ'85æt޳92DÔeÖç³XšŠ©RQ2%ÅC.l"â¢Aq–réðÄm"?ƒ2.AHšÈ ÉŽ)œP VLO)fUÒj¼dñ y i8ò†Ûno3ôÇpÇË¢dÈÆ‰b¼ðß0MÐ.xo¿ÕŠi> “D+"1r™ RbÎâb¸Ëa ,„eA®Âc) ÁcbÌA j'8—£±‚nà‡y–陽aÐ# +EQ•#»GÈØZu&ÞÎ| ¼O3?­ªú¸qetp†cEÑêó«û»wGƒ¸l]’S°wEËð¢àÛ”8¢‡¾CEyË•€š$VŸBtÈœ#(hÁ^xA£žÅ|›ãµ§cæ!A0"``À=æÍá_šø‹ •«¼ZçøQ4^‹‡Ç •¦± sXA‚"q`G‘ >#òû¡³Ǥ¨ a@J°<ÄÀ|*F2\‰9›„#°‚(§Ÿ'\žÄ*Â"iêИ¡ Ž\Ô€ý"Ñ !’@Ò”³(o€Ûòh © ¿ËUæÞq¢ó’Æv°L}ö 1‡„<%TP ‡áx0 ¼œG¼Êb î"Hžèîrqì ÒG±Ïcp6 0`ÉIÒ@Q鼘%!„a#H]@Œ(.¤E1 s %ø(`äp¤ ¹š(Ÿ‰D%áÅ PŸÈ9 a_’u¬Â<äŸ ÌSŠnÈ’éô;7[jlBüf ØKœC'ù%ä&‹5Ĩc/ tÛp%ÏA¨zx˜”Çr*çù"A).Ž0iéJó²íeRˆy#]p{Ž¥XMLÀ-aàÌ^jDpìÑ †ÓŒ|yú”¢Y¼õÎä²I c+ÉiÑ,…ÁÈïïQo Ê9$šЃ”à³ô{äd×K‚IÖ†ä’C~âd•—¬Ln÷ö÷½q8BméÉý¶çÉ %Ž´D<”DÙ§"ã ¸ƒ˜„±¨bNƒAòÏ)%3S’8' F7µ7HPi""²½ ëÆòZ6]ª¶ÙÕú±TiÉy+;+¤Þ• !F¿ u ÏX¹Ð1’…5¦ Bލ7àÿ¤~ÁàHJ¶x.”•e…Œ°ŸjVÓieóÆ÷$£áE@«}Eô‚À‹P†òSA c†ób6•ÉŠþÄïÿ7‚/¾òÆÖý˜Qä¸ýM¸Æ*,E±”)Ï»£Ý`´·òȳ¥™ÓÒÀpó©„`0nÉó`hŽ1Ib3䨄*JI⃠~ %P>¥ r€Ù›™™|åTHÇ»/D3óã^7kÊÃνýFñ»¿ãŽ¡P^2}T‹øjŽIТP# Èkâ‰'?Ô\¿¢h•~ãC+¯!Ìè%|ø%KHÍԪǟŒüžÓÛÕSét¦¾{ç"(A”«T2SV­¶¤ (•Ö(|㋟(P@Âf:¥Ëz¹Óz=È èq$9=S£‘뺩Rváô3 Ù™JåŒ* H¶÷n †ýqo¼¿q7ôR¨ï»¢–UÌ2o=›P‘À¢³z˜˜ €e¡ôDHTT,5•.Ì×õt§qßLgHÔ67†ím¸[Ös?ÊÕæk3‹ûk7ûÛùBíßüôÂÉÙ?ýgŸð쮦ò„‚j€ÿ€gJ°ã3® ù7›®žrÛ‘×Ö­Jà ­Ò¢ž*[¹…l¶H£®™Ñ( 3 ¹ÈLˆó:íí»1•qêYÆÊ@¹° ¸Ðô\ÌE²n=ñîÏt¶î»vW2ó½ÆÚUÀÕ´U©Í¯Ö¦Œ´$§j¢¢yÞÝÝÃ@fl\«Íž{þô™'õý{ÿê­‹?´òuÙšæR{ç&û\ä¨fÖ,LÚ—¿såõtå´3nDa‡„ ñ½(ð8AΠ¥KÄmÉš <6[^Q1J-Ÿ;§eÔŸ|닚d é÷1;B(P˜ðR®°(˦š¯µïʲƓ ×¸ $‘/ª^Qµ4 ÀÌÜ©|!o¦R­ö^€¤Êâ#ÖÆö½×ó©j!¿…â{颸ÌÓïí÷Ñ÷¾ûÒ—{@üN±XLgrP”çOF¾Ó=Ømîm¹N0êÏ䛯É_Rß@@â¤N$á@Óós+ÏY£¾´¢ÊF0‹éç-%Ê'Ñlý˜•Ÿ:sæ=V¾²½ysëþ­þáNäõ%Á@•é™sª ¹Ì]>󨡚ãAÇsÆD{-/ #‚¢ÈBäŽZ)³¯ÕÏ.d3çw6×­BÑíµö7Ön\ÒS]8³pú¼ÈKÃÃßwÛÍÆîv·±E•*«éY].CÝHõ40Ó*ʪAh ³§ï“À+-~jzù\6ŸŸ?qrÐojVvëæîÚUw8è6ö)•kÇžœ?½šJÉåÒ¢ÊeZ­AD¥©Jú‡ëÛ«’¤lïÞi·K³g“$¹ãCøO–²QŒ÷/Œíj–Ð?È—r¹òj¯í¶›ÛzZ/Ï.-®¾ïp}mviåêÏ¿~ãõ—Àk(†ªH²¢–Ý;ô\0\Óð”3OþúÌñ3W~öƃË(¢À†8úí?¹`Û-ÐÜÜñÇv7ï6÷î÷Z èÁn©ÜP àÈm‹+[ <³Õt-pû«Ö>8¼ø£¯:ÃXà ïf¡{°Î|( |7 =QQUYæåœžÎå-ðß9üâëfJPL×Úgš¼´ºÚhlùH'îP”EâÑ÷7î\¾56‹3§ÜÖ^àuû­µ£’„òP”i©òg?¸vçÍ7/|rB¾²œ¯N— •vã~…ùú²=<¸þcx$ ôLÕ‚™ås£Þĉ§Î¼ ªæƒ{Gý±ÓUŒ4è,Ñ!D?½ôŽù3ç÷·/—k³@¾w6‹µÅ÷ýã„¶ïúwÜÙßÙ©DÏB®PËs’!¤+õу5«<5:w®ƒ×ŸzÇ{£ØvwïÝõã§ßÿ›»{åª,öh¼¸zöãÿò›sÇÎÚƒî·ßèµ÷5µ|ö}o_ùiÓ“½°²|líêK£a÷Îí+Aþ¸<õ˜ ‹Í›«§Ÿö¹~õ+!èzqj*ò 0+£!&éöþÆìüêâéÇ_~ùËvwǤ\›cnîLujÎ÷Û‡‡_{Ùó‚sOìþ­7\ÛÎO-õåe¡’1×Ü(LW”|¿{Ð:¸[›š×­Úí—×ß¾4³pªZŸ Æ-àDš™ƒ¤òŽþY¡0õøãX»ýfc÷þÈl7âLgØÕéÑ3¿ðk xt0´÷Ö·vî_ëµïB‚3r•R±¾|òé›o_8¾P«çÓ²)§¶ÖîÛ½ƒÛ3Kg­¹Õ;—siY—Ð΃»¦5 %Àìñs‡·ß|íÿ”¦––WŸ¹yéÂôü¹sï|÷w¿öå½ÍëùçÿH¿×<ØÛÝÛ¸1îï•ë ‘öö7››·%™O›éÚôªnå«ó«Z*ýkðy¯7öFGÌ`_woü,Œh®´X.V§ÊÃ0JË:²ÚXßøñ?|!_=Ùë46nü€D@­¡lV¡öìNØ„øŠn-ž|fîØ©ˆ†zº²|ú´¥‹Û;íV—"¼òÈ©Ÿ¿üb¦X—Ó©ÛW.4·×º{ë`Ù(„¤`c!Q¡1îwŸûˆ¡Ë4ëgúãÈsÇNëoèGàod•ê¿õ§ßì ÷×6Ú­ÍÒÂ#Š*·k¾3<ÿÂÇtz-/Ê­[—ÃȃŽÇg«µó æ½>HëÒÈ' ÄŸ€WMw»©B­T-Ögª½1>ùÄ×§1ïz½òTm÷Î×/îlA°Çí²¡1U¯ŸLee)ÊÆ‰w¯î?¸cÛú!œY<½¿õ¶;v#é"ô4Œ0Ö0b…ùÌ™OCjv}Ÿ—Jvëøåéz¾>kf— TÉdó÷o^»ýr’V¼8jãå±Jú7qè÷Z÷†lm¶Ÿµöšû®ëù`tv, |ßÚ¼¼¾ø.!cqdðØù§{‡k^èõºÝ½µÛ¢¨þwÍT~óþ;÷öw/ÿì{»›—] Ø€•6‚B‰‡9$Êf¾¾ ¶Ë–ë™Ê<``cs­µq5òz Ï%ÄãK3'Q<òÝA+^<¨êwYª¯œOeÒ¡Ýoï®wöï J&F™…O²²ÈHºnL£€†!ÔìI*JŠ.+R¶T_8ñäÖ½‹õ™GgOŸïµ6¡.ƒßõL^[ w8ÐÌ¢–N3ôí`ëÎOHr‚œk@iOpÒQ~5iÓ°Zs¤NÌÔOgWšÛ—J¥SKgž²2εŸ½Ønì‰rCEgh ¡#ªi - (ØÔFZºx¨ÅX“•ÂÌŠ¦Æ½ƒ†‘™Qõb¿µíô[ãþ!†bÒ0 •YÏé^8¢ØHB»%gÏqœ …XŒ"IÓu+¨ÓÞ¾¯.ý£O|æ`û‚@#+»ì¸BH‚R2c÷ ±wõg/ö×L-žƒÂv8ê56®N÷a›If§IÇ’=/º5;jß'Ñ é±CpHà9ùÚ¼ïöLkŠ'‡áüéüáZ 4–³¥E+Sºöêßû®]®-W¦}¯á/iV³±%ª™é…ÇxóK¥ÜÔâÓ!é JX™†¤rîÖ•7hèÎ?­Bï°ßm÷×î¼øÎʹwA!9ì·}o\[Zõl#}k{ûÁ¥qoƒõªØQ„S!9w;cQ’.;zON™¢äŒ@©,=ã÷æN>yýö•ȇ²”/ÖN¢È[¿sáp÷-À(vLy`HPÚÏ}wµ:¥ðä‘sÏ_|õÛ÷n_tFNà'ÞõÇÃv#T¨Í‚o«óF:çô;Ž7–ÔÜ 3F„×2­Œ–N4nƒ»š@¯gGΠµ{¸våU§×WdçÔe‰r†N ¬ !A¦^8éÙMÚˆ(öÁ(@æy,Á++C7pP\ð‚[‹¼¥„lmE´À÷Ç£–ž­˜ùbo÷š"IÓÓËÕ¹éû·oìmo [úÿ;—)äòY»@ym<ðÛkÅR¹üþÁv³qP™}´X«Õ¦jƒîaoÔ%¾0èìï¬_ëìox£!óð‘¨ÇΰæZ¦V_<Ë èpwÔí†ÃÊ HHºÙa) í˜ø1a­¢äà‘b‘”(éÀó!¦E)EDTS¬‰æ €ÖfÀÖýöÎÛ±dÊ‹$"ž[yêc7_éÓŸ»Øon‰(.LM7š{ýNßô#wOk·÷l×Ö­r:“²2¹NëpÐ긎7êlP¨UÇì¼’‹|e`Ù #AË1pú\»7èœ~—Ç4SÔîl»L0­Z`æÊ K'Ÿ½ã5#7Ým­iVÞ÷œAW€A¥ÆÝî¸Ûœ~r(èè·Á¢žœ“(4¢ˆ¢ ¹¾Œ%ñãôâÚõסv;þèsœ‚v7ƒ¦§?u ½O„~k÷ÞÅÝû×ݡ͚,츚$GììüJÑõ÷ÿ“Ïf«Kßý_nÚP:QâúN_Ð+²5GÃ.”ºvo×4¹ä”³2½<â¬À…‡Í]NÒ€yzžÛÞÛtÍ}Ÿv ŠKÚPÏ4P'8 4ÆN·Ø™>³“^ÿ÷ÿìÂ+ßùR¡¶j¤3Ï}èwÖÖnöÝt6ßÙ¾?hw·îÜ„4þé ÷€u0³ÓZü”Uý¹±.C&ê›Ûqä'GïìžQ;v¢è'PøGE9ÎVÎ>ýÁR-EÎîÖ½~¯@¶!´³³>níC]C0Ip+LÚ†P¤ÈåcïÅ‚ÔÜ|-tÁKy#?ï ö»o€áà¯]‹_{õÕWþïߺC_ŠÀž#fŽu÷nÛ»ÞxÌ<”uú¸I“…µY.?*tzÞ áŒy(C<ž¦Ás"óm è, <^‘´<7°‡1 Q22yDQÖíñÖgU:;œ„õY–0È Àñ“v¥’´5ÁæÞ¤ï ¦×¬B Ìüb~êüúåïÿå‹Gž/ÿõüâ¾úî^“,¨ö#b³ÓZËÀ?•œ3lÓˆQp„°‘.* š‘mlßå¬Uœ3r–Úko~ßwÜÂ܇EE)N­N-ž…‚º”Ë,-Á­Í«ù"5d?òÕ¯|ñÕÿñ—ÿ ËßëÛÝ„5Q-ÈŠÂÇþ.T7É©5áE,ñÇ”5ÑPÒH ¶$<Éx€89 DGA`E"©fiñl¶8åú<¯xÃíúÒji ÈŒxóê…rõ}>_Ì—ç/]x9pà pÛo÷ZÛ,KÄbvæ€-¹Êriá¤ïÙ–Y\9ñD*£œ<[^<,½…Y?¿ø¹÷­«o^·Ê'8Òpû"Ô³P{£–3j%¥Ÿ´rÉdÖòÂÑ0 |CxÆë°Êà @0æbÈÆé|­2wB1R@2ǃv¥~ Èx¥>§¤r.¥Ãžzvdë‹+aàýè›_˜^8Ïój§¹ÙøÛ÷~ /ÕWXÃuÔÎäJ«½wþè¹™1õo^·¯¼¾ç9¸T˜}çûÍ;£íõ>ûé ΖÔëoü¸ÛrHåÂbiØ虊j¦©¹Ã¶ Ô‘ ·¯½þàÖk€ÝP€¶cpîQ3&ÎdðñÇKôφIY±#@È#rч“­É¬oœð(€:(¨)5³§!.DQxÑSÀIIçJgÎ<ýñßúh®õœ®™žùûÿþâp€*õãg›¹õÖƒ€«Æ"6 r¥Že ÜY€#Á²ãá¨ÙÜV—2-SÎ`-ÚÙ¸±ª»»7¯¿±¿»E‘¬ç¡r#¸cφîÐx2çÈÅMÆ&YóeE ~s1òꇓ1ªÉH0odV€AÎ-¶±ã;&žzö£'NÌ®œÕF¥ýÖ—^–5éܳO醸­¿{¹7ÂÖÔJ¶X.TqJÊ„4 §x°!@4õÉ($&¯`Ž€r8HVö‡W^ÿac÷HùB3 XР¶í5ï÷w€¿qBüJš‰’™E(ë˜Ð=šL÷M½ØL›žYÁ€w’¡¨j*›“LÑqý¥Õ÷žyô×í-Ÿ—YUÐú[;Ë@aއúöß¾vãê]ÝZ03ÕZ¥¼0gZ)”Ž‘" Ǧƒ(ĺŒ\´ËU ÎcS$Þ  ¤ìvnߺÒ>lFl²‡‘¨kz‡ÆæÝöá:D?kÛa <ž†¬ÝÏqÒdè”›ÌV±Þ$ƒ IÏé™ÓlæWR4#£[ÙTÖR5SÌLnéÄ#S4ª¸¸¼º÷`'_¢çŸ™¹|­ýú^?Üë#)¥u)–˹\y&“/‹ýþN­\gÍq<—D¢µq>;:¡Édbà„ÀúÆc×Gª NóÂÖµ›ƒn+ôqH;»ëw››·ƒÀ§Éð'›´dãž,–±Ä/–•>ÛÙº ’›¹'Qì 2𼢬eÍtZWE+S3¬œ,á³çŸ,TÅ×~t»PÔ^xaæê ú¯ýÈçy%FcÝÐòÅòÂêB¦ˆúm[Å(_Ô!!Øùc?­È%sä!ì !Ä¢ç†iYŽ\Ôï‡HGõ!zíÕe}7ÜÞî4#¬!W œ¿qõç‡íýns=pì(S¨M¦ =Q6”TyÜ\#ÁøÿH¢Axœ5zi×uÞíÛ{÷ë~û>Ë›Ì` €$‚ h‘%˲iËŠ¬²•ÊEqYNR©r–Jªì¸Rv¹Ê‰+U±õÇñ%‘#Y¶VÓÖBŠ+@ `0 Þlïͼ}é}¹Ý9·‡àÔÌëÛçž{Îw¾ïžÃ±bG1B bà_øb¾g0†?˜áAF( |3Ž#̱a„£0dúq(Nž ŸgÆqŒà§/ ~†°8ý-¬É°Q 3ô!Ã;éa¨ð3™ÁRLFð³ô—˜áùTè¹ N‚×Å¡b>ïYIIÃЃU0æ#EQÖ‚©ðÌòs¼¨’ˆÀeáŽaYj—ïG„î"Š< Àz`'J¶Lˆê º9jµ1|²8A1Ø—¼ŒDD÷Äp˜K‡b2€'X0•.Fð$$˜U,`V„'‰oD0 ¿‚MIZųÔŸˆ¥–Ä1Qr ,,EIqÌ>X[€X^ ½¶ÄÐÏp°ØoJÓ8Ì8ŽÒ³ÓÉ$/J/¶ù4aÒMq8bÂBAPÓ…ùÑ ç !I]ЈoóZÖ‰ƒ‘ +ÅÆ¦ïù¬šÏrè³ÿäK_ÿ“ßhí5#6-Ê)ßn›“߃}çbQç&Ø@àåp||ªYBÂ[P”ˆ†h8ã(ôáEÉN§FÄec.€ƒ!ïHÈ)©Èk¡ Ï2 ˆ*–×óõK&|ÒÉ8Ó‘y%Ä‚çúQÄʼn˜Ò3rñ¼^^.WËgn]ÿ†¨æ½ˆÕ%íßÿöþñïÉqÛ奔V™)•«3ûõÿ5éO§R—±Œ¨¤Õl%[œã”2f³,—‹"'ŽMŽ¢=àxàÛ'`¿–*@¤Z¶…Ä"aó$¶yN¥4|, ,gt?yÇòJ6•_ÆXìíßJ©z­¶±¿w/›M.m±YŽåxÞ× 9%[² Xú„cìï,5–)™Ù @+gE%ü‹ÿñŸÚÞN—W•”ú‰ÏüòçùóÕÝ¥­»`ÖõüѰ½%¨‹°rÌæà)“€ñ­½ÐmAJq¬XŸ9×=Þ¥€Å§‚JÎUë I©œ4ïÿ(öº,{9)Sj\²Ç½Nó&T5]ËÔ.­žÿ Voìï© ?=y3  ó›ÍÃíw|×S´ìL}fiv&›«¤ò SϵÌþâòŠï™ßÿæŸÆ1?e2Ú?ýÿ.%K[w›;ÍVso×qF,yŽHÙ' #ÅD5”“bƒxcÌLˆ³_o<9÷•TNN©®g9ƒfˆ¢Ææ5S/åWuµ`›­Çß¼þ£¯½ùÚß»®?µQò‚\=óDeå¹©ÃøæxÚz›˜{¾Ó+Í­ˆù ®£žïZ¼’V´”®:v9N[8÷1)¹¦=ê›æ@ÏV½ãÀ³ŽÝqà;~[N/“É•+%!ÿ‘ cI-3¾ãN¥tQ–˜ÑÁ˃ŒÏn>û`wÛ]– E8R¬{êO­±rÉ=è¶¶àEžc²8Jž Š;¤ !üáUÑ0/ä#&ÇŠ=7C‚‘,ˆçIB ¦mõ¸ˆ© %qÈǾ¬¦¥”Î)º¤êÈu Ú÷úÓ±º[lì–«¥ýÂbõzãÖƒ½þ‚–Õ3…jkçžeŒ)9ŒúˆLQä%SU ŽæÁî¾` IP~¹X¡ì kú<Žl³ϱŽÁIèAHGþ0pŽƒ7àRó±PeÏó*A8«²ž¦ еí0`éÈTK«…z%_™ÕÄ rŒ(ÅžyÒÚ‰„TwÎgUݳFïßð} )@ÅÅóG\0è<‚è™Ï}…—8Ünßü±3ÇÄa¢nô¢Ð.ŸÍVĺCNÔ ƒ€4C±€Ê <7•[$Ý?(c !‘¸&€@è€Í¢œ q!Œ@B€ÕÁb!"e¤n…¾"GRT^ˆ ìÏ_ùD*•ͤrÈwß¹ñb„%-7Ï ƒ*‹ÆSÿuýƒã0LÑ3’šs}8öñ ¿úWZuáÍ—¾}´õqIäÝ3Ú11¡ž•Êgs…™ƒæ †c@uAž¥¸Nä½p6 \cr°| è"f oBXßc àe³40Æ.QMAV)}Ž,I–KµEŒ…BõŒ òÅsi6úë¯ý¡¨×]ǦÎe󅌮—T‹Õ³ }o<åË‹#ƼüÒï=L‡¯|ïÏ;Í[}²)~bÐGÑjÏÿô¯µÚ·l¿šÎ5²Å‰O×ñ€W ¼˜í·î놔 Ý8Pd*D€å1¥è‚XcÐÙ,ïtMÑŠÖd0ì·#MŒ1°}™Cíû×=kzöÂóœyüS¿ÚA:ÏfÅ·_^¿úÉÃæÞ›ó;€6ÀŸmÎGºO¢lãÑÒü:R—öoózɳG‘7!®!ÊyàêTûÄJ¯d [\) tAÅÔQ³¥li#^×Ó²J3%ŽÕ?¼wS×2gÏ?ˆ4ê ì±  Ü®oò™âîÖí˜Ss3«'í¦ª—€“CöŠu™ìQ‡$Q²W?ûû$âÖáþíïo^ùÌý»×[[ßÁ€–¼ÐÇëg±^ñܾ¢k)­èšÀ£ï:”>c#ˆyEHU@hù""”-(lPLá3ªVÂéHd…gÖ.gò ¬É^”¤•õGáû»wßÈ•—ÌéÐõÖ.^Clä˜Í3›FkØ) q&×oß~jÐÏþ ÐÊZΡ­÷·?ô¹?Þ¹óÆ´û€‰<âL@r±’VmlŒZoMº»Ÿ¥•õr‰ÃBq9Uª²Pmbæ™}ªTǯþèok¹31“Îs®µ;îl­/oàXAlñ¨(Tr9ÖCÆd¨es`íðĹ÷þ¹BeÜßÙ¼ô˜ç9ƒ‰-§gs¥ ñÔ.5‹b çŽF©t‰)à;÷¶wwG‡{…G&f{bY¿\›[sÌ0]ûd@l‹@΋Wǃ֠wOTÕj}©½{aqã¹l¹Vœ=Sk)¦Ð7þâÿºŽ—/žýá7ÿ;è8d5/ÎÌ;{îâ[7¾%颧²LüÈR¹vf~emnqˆÌ­wßo¯ž¿x°½ÛmÔ.îÝż¯¨Œ"Vª-M'†±ß:Ú‰9¥Ý|úÈóLwÒ–öâSŸÎƒn{qy3WYžo7›ØÇ¶oXá¤8¿ÒzpçÉ+ŸZ½ú/=×.Õ4]ôýéÜÙK¥ú¦=éw[ïƸÛ7wái7ð µpffíêêÆ“ƒƒ·>ò‰_ÜÞzÍ´,AÔ|Ç3A©47qú¿»÷n¹„dÁ’Ú™z±ñåÉû7n×}üégÆÉýÝãfG`8=Ãù( øüë¯G6(ô.Hé’ž÷Áüò#i5 rÙO&Ó¡Rª{Pévréš5jyþxýòO±¼àà •ßWÒúí·_>Ù{¸²ñL¯ý¬TžôÎ;?´&`¹g/>-È"‹®áœ][Ы›/~ó/Z»·ôü‚1<$­±ñD`µ×66[{ïÒ ·XÖ2³Èv7V.}î׿r°}W–rgÖ®VæÏ±ªjŽ£îá¶aŸÆ_}ìcœA4hïÞ¿÷êí›Ø}!•+=éîÑÒÑ+R„yøðRQ²‹ëÏÛŽ=i€"vic*&fe=SÏæÊ­7=ßR 3~Àkm,?šÍçØU* w<,Tkƒ±}ýµwï½â;ã8À~U/Ì/=~ù©ºÎ4__¸ñÊßuÚ{ó‹—'ý“ßøãÁtÔ3¦ðÏôþ·ŽÞ…ê µ¤-:< ì ÔN9•ËÏ®+z~®V:îµZíAçÈìp <ÐG½r¡×šùå+Ÿ:Þ¿  P:?“­-l6ß{…¸~ºØDt_ea IÚ™óN©¨½ÓþÁ×ÿ›ïåʼ*¥bI3'†ž©J™Y&%L‡‡ƒ'Ç»<ö3QŒÆƒöÃ{¯#„tzæðêÏ}9 îÉÑÖ¸×ö̰¨ï¢¬{Ž„ ¤YyÀµdµPš¿ä™ãtFd¹ÔÉqâT ‘o´‚ÖczËñ¬–ŸÍ×Vmc2jÝW³é¥Õ'@tx¶SÛÐr¥ÉðĶÝ{·_œìMûMEËþ­i/Wœ;wé9Ä¥ö¶¯ÃyyΔÕ”žãEáÌú“7_úz¯u˜¶’­ç+‹H²^µ·ýºëMǽû ,PÓŠšÏæ{æ…ýû·v·ÞÐvÌÉ‚¤{£CØ Œ€• '†1vÇ= -Ï­>úÑT%•©áöß»9·¸ùüÏêÆ_Gl.—ËV‹c0üÁ‹ÿ§{|МŽÀB`j¶*Ès Ò…†ïËkWÀ®/žŸ¶÷Íþ¡ ©‡ï)™J¹¶²ýÖwÕüLa~óàÞk¾eÔV¯îßùÁ³ÿê«Ä4Œ“f®Ãqø´b»±oç¡È¦³rFD‚¸±üÇá“Ö» ªl£¿ïþüÊÅÚÒÊQs¨üÙGž>ÞÛVRy×ô¹tûúwºí-Ïž†¾å¹'å¥ÇV/o½ùwæ¨ìˆaAys@ù½Je£ÈE±wö‰Oç˹[/ýÉÌÊ•+?õÅã{?n4ó(CG;®;¶{dp|oxrJT&¹;¥ä;¤wœQò½Ÿ,ˆQš™ß„`žƒl}÷»{×EQÚè;}U×3¹\{¯“î™Pòr3Kö 3éµQ$Øæ(ôƒÄ*ȳSÒ  *KAap¦'¾Ô:´rDˆïLè…y {A,Ö–6ª³ ¤¬k©¹Ú¸ÙéµïBH²¼êyCßÇÉe?¢—´lÒòÒåR¬` ;kJþœa çΊřG.\~º>;û×_ù¯ŽCdµÔX¾ eåZã0 ú<ëvFë£n‹—${æ[<—¶ïè•óÀÕ}kŠ G!È';Á´s2½]Ut°?ô}¸Éå?—\Ã[ýk/| @~÷ÝƬè9“Àé <½KžH{[T_°|r[aN&Œ AI•–2³ÏV–/ª…Ù7¿§çfës «^¼ùÚËŽ#¨Z¥V-IÞÙº ”H`·Õú¢1o_/DÄÀ,Ÿ«lø¾9wþ¹ý­—¦Ý#Ð)Lì£Ø…¼ÆZ?iyÐn$ƒ“ž 䀠@ æ$9 ßêC0$ ø7Lâ*¢÷ãXD{ TÂùàaxl„—RQ䃘[ÿð¿Y¾ôìx«+—}ߦ}®l=ò,@¦ˆå¤Â0 $£˜Ê(©ò\À@I©æÀ2ŽoJ£sQ KàR&²',í,*z™¸#YTÎ]ƒã:¦1†Úo? \4ÁD3k×|o ñÙOÿkžñ¦Ç™|m:Þ}÷¥öýëré£ V’õHDLQICªDaH s9 ªo‰å“v3íš±IäI™RåÌ¥çáŸîºã£zeÆ#~ç¤{çíWÛÍ»ž=oCÑq|êÛ%›x¡H{ƒC³3¦í`0•Þ~¢ïRqru ) ~ ½A±±>̯8“«l¿iô÷«WÔ|©P>Óm=òKÇ„áypWeõZ ò¾u7_;?êÝ<‹óžíEœÄøŸJîèštmvÅ´x× ‚дÝqÿ€3M] qH(æŸPd„ZIOóIòz´kH¡R¤ýeÈ È}^ådtGàœäçÊβBmþ¬3é{–·zé…l&eMÛšªéªTzžA¾ I(©hÙê|yviõÑ´š»#Ùbåú‹Ù;Ü¡Eò‹õD(Ùz(ˆ–Ê‚Œµ¬¼ªÈÕòÏ·;Ý‚°*Ì»¶éÛÁÉî»®Ù§þLj.ƒø$t"z—ÌuÐJJ Ò€8‚°Içu¤¦Ý»3çž.ÏÏ"íßy‡xFev©ÖØ|x÷ʪŒÌÁ{éR­r"çžX¸øluq˜*ðåbc8ì>¸1 Š|fýÊí×¾EœçØz®ì™ÓÊ pÆ·‡õ…‹3‹Íwhµ‰H¶8§¦òSclÙöñákx ¨C§G’#I†\ø“ ÁX8»üäîÝÛo¿ùÝɨCg$°È§¥áŸÞ‹"$A6űŰ!C[ɵ2ÇÁ>\«R{\¯ÆŒF­“Öñ,kÀ∠zÝ‹8ª‚L$€`m|ÓíKýâkÖøØ=œvcñF_Óʼ(ÊsLª–½}óG¢^IU,Ö+¹jz¦àLƪ¨·ÛíÃñà`qõ"Ó¾çzb&|èÛò›ž1Ž X ×‡€?%È„ú¹FÐAdDñ¬ œl±qNH«~XÓQlõžBºqRÖ1O(€ÒÌJ´({A„.I¹ÅµúQŒÃL¾œbvñùé¨_Ÿ9ãº׳A;ÌÎ]€ú§soýøëÄ'i¹Àj<Ð@Ï Ê3óaèOéÝê^ÿd_Ï×–×+ƒÐóÍ~²<®Ä+å(´‰?æSYZå=¿ºpu~yóþͯ=ûþCk÷ÎÛ/ÿOÈ Ð÷DÞ eNIÏ*]úÿ@h²$±˜ AìÑ—#鹟|äÚ'­Q³¾¸!«õÃwgÎïÜýcŽ‹¥•“½Ýbm D/åÎ^xîx÷a»ù>Ë1'Á*ýö›/2ˆã”L„Ñø¤‰9Íw\ÚƒƒBXÀó€JA¡`ŽÈp*)•Ké% PèfÖž>¸÷ckÜ¡£SP˜ƒ)¦$Y<Ô¢ÿQŽÄÒ‘$L9|¡c+à|(‚À\øg¾ð—¡ÑOZ!:–è`ÀLcc÷ý—@>Ÿì§vÝio¹U¨-/o>;h¾³½õº¿î><õ³"‰V/<1vÆHν÷Ú‹¾ô߇ª(gëÖ°X#(˜ S™¢˜®»‡tù™%£s`ûRª§ãÐ/ƒö!Ä„êÆ €¡U™·ÄÛ8™j‹(^ÑîeKpd,ª°ñ9w|Rš» ¦R'{7‹óë1½÷èvô,(ŽI· ΀ àxô_FÏL¦}t,ŸÎWµ”dŒ¶ 9%}&†=Ô7ôŒÜ¼ý}k2‚½0XV3•| Wôº£^‡•ioΛÎ!B‹œd¢ˆ¥Ìù`?¦%-L,ÄÉTÝJÂ…½€q”lT¾QY ù§é°ÐEðªU P x{rž”9Ð ô ŪV*Õ–ò³¿ê!ùOç1í2GåúÌÙUßswïÂ.´ ôê Ë©ßkïù‘¬dV|2rÌžï“A׳\âo 1i¿#1‹9•”ñ‡´Ätè)±6¢£}ô‹vCè˜VÒ‚N'¯À$z4ðy>÷ <‹(P'OA•OH#%kSÀeA”AU– Ù2¬âü…b½^©qhù¶·ûx‹´8v×.}8S¨·Zšo„‘8yŸÎ×Qžo÷ hbŽƒt`a›e’ÌGñ”“sÉ%tV)áH´Êá(N&ô"êO*TcN(|ˆ8%•Ž„'&âÅ] -:Øa@‹©.=•É Û7 ³ €´s×~†xÄšN%AŸš}QÏÁ²Ö¨?êìÃ8B9S,õÌAÂêãDØrˆH@[´tŽJ 'ªpìÓQ=œ|žõ%…“©KJÔ`‘dò2aV\î2#V†1¤¤=,@Z8M†ŽÔð‰²s•\#][!WÎúÃCˆ@Çè‡öTÍÔ@–ƒ4•¬ïö"ä~à›Fäƒç±â%¤P'ÂIQô)ºÒà9O’ I>ý&œSã©3OG2Oψ¥µ L–øÜ8t†SC«GniéÊåÿÊþ÷oÚã£ÄW°P:Ìʉzežöã|VΗí7ßsFPsÕ˜BD îaxÞH<7¹Ú¥©FÃ’Ñ0 ɘfd²…ä~•$gB}F 4µíô™èƒÔ §s:sùÁÿé0fRXZ9&öøÜ5Ï7žY~hÆtpâcaÛ˜¢Ðý[ž?:ãQÏ ¼‘ZšªgtŽÝéˆA%YQà@q¥¼)ÒéÍ*  bŽÇ8¤Ø˜ «F ÚÐÈG”Ôä’:•4Lá¸å)y 0á¡>TôÁ°tµª¤TàV¿K/—b_,\£}sÈ>&6øø!¥¦-u%©Å¹Õk¶?v›,¥­Q¯ô¾œ[À¬`ߣ¢\ƒipÆ”%bêL–Œe’2ŸÎ9Ÿú21IèGIàÄ;í€Ð¡u“¡‡T Ããˆ>±P_ÑÒi€žcö†Í8G1ûd2Þ)ŒgÎ=Ÿìím™ƒÐ(° ÉÖWæV.r±“ʦÜÈØß¾oŽdŒeðX`›É|;{Ÿ”¤ÑéVŽ@˜#¤ü„Ž:ÓéwF8°ÐpcÂärƒ¡£¾(Ȉ§5*ò¨ááÁÿµåÍlA ì1‡åÎáþ° Tj89øÿN|%0xœ5z×uÞý{½ï{Û+° ,:@HŠ MY–";”l:c9edÙãqMúT:ÓçØªeµ £M"â†,ß²»RtªYßßß[mT×m[÷À¹>ØÆƒ|GEØ.8Ê÷ äk *zù"90!À±ð â{^Bˆæ%Û/DzKÑ¢Ñ3 £é¹VàÂ;x¤g×iŠ@v¯0|ê™—þ}|(µ~oyþò+ûû÷]S#霋—d9&OÌžch¹¾³YÛ[ò}ÃsU^J6evcwÁpß5=φ炷hg’<Ìt°©¾ oŽCÑ} a“Õ„Ëp@Õ5žkrr6šžŠ&#ÉœOXšÞhW×´NÛÑÝ à|:ËwíÀÁŸ&Fã#“§i¤1,wñ“¿Èr´DÇöÖ–7¯Û¦Óët’¤K–©m¯ßíÖkœœ”b9ŠAZ»ê¦cZ®©Z¾Ñ ³üIPË@Z!×ÁðæÀÆÀlÀUß1hF¦c§â’ƒbYŽÈ€E á.L<¡öö;õ­^}¼L‹ `XRb%:š ékj ’ò©âèÌ…ÑɃ£±ÅÛ^}í;û¬c{<'Ú†ÅF㢜ôÛ骫‹7jûàI>ÚO1 ËÒµÖŽÑÝõmÒ…Àf0>¡`> 9`&I0$Aúø^#8À9@ G@L¬ÿSœ’¥XGcRXðmÇ6Ú¶ÑpcˆC.Ð,Eq+Gc‚$I,ÉÒ\‚‹eúÆrÙüÝòâüþÆ}ÚÓ;wŸýä/óÑB¶ŠôjžsýåÝ­yMkCPL„’F·Þk¬yŽî@I&ÌHLx4˜`á4&!á0`&ä:þ:l#Š™…ôwáů ‘(¢ª·ÊÛKíÚ®­éž«Á$EóIH€(ŸãcÀN,ë—†gâq Ž„GÐÍêöîÚB}oÕ²T9Ù—Näö–¯Žy> cše5««FÛÀ–0 ¢Y€ƒ£u¬Þ^à#÷Hð Îjì 2lð~@2¦h’¾ò„±`[‘(ŽhÁƃM$ñüϳ£ÖÕ^½Ï굄ӓd8„3•§…†„¥<Ž#çY†®õ4Hªá™ÇhJ5´öÞÖºÚÑÉ' ý©|sÿÊx¹¨ë¦iª>ö$@8U±Z.Ž0#c à: Âg°Ø±Öbb#‘`"…èHXÿ tÆœý©/¨IJg³¼Þ¦)Ît µWÓ{mCë®)JòÀèáTfÄ2ÌjM]¹™¤×m _•bêÔ7RÙ¬$–¡ím,7+›”ƒr€ÔÃq>A¸fØ“%/À^%|\Y¾Î£€ñI›€ çšP’H‚öCVüèD¡ýøÐÀʸ~¨çé¯y&18rºP(@šØN¯ÿUË€?ÝÔ]9ŽåAr¬ˆ’>¯75ÊÕýÍG ÐIß p[ßÀ„Ú­7k{P%¡dT¶îj‹áÚ@%\ìKüüU°£\\̸‘*®•8Á#»É’>6Ã,Áâ#ß\•$qY\[“ð1?õ«ßŽ'òŠëv̓ŠëÙ:ÍÊzWm’Œ¨zOmj4™ˆF- *^êàXŸFMž°vövjug{sÕÒÛ¶^±µ}.2â‚Û(AÝÄæÒÀÛDXCz„šnceU"HÀ@a Äû„ h \¨¡4¼/ìÀ3C)°‚XŸ}òÒgµ^ÛÔôB®¿X(þÊŸîW÷W³Å"M×õ¶Þ×?ë†ï÷t³ B%ž*± ™Ì$HÌ() r­ýhéa¹\ÓÕ8¶®V*­j­­i]×êPȰºŒØP`(l-AàaÃÖàgl<Åc á8ž¯¾Eшå8†U Äç&”h¬[Ûa˜øÐø‰Òp¾¹?(ÞG"dr.Ÿ9óy%Éɱ^{·WY“ÄŒÚÞë;É& Â) OiÕ]cE… H²ktZ[{ü%˪¦Úêhí Ì4lÛ²<ÐxÈ"ÛííÐlqi”(ßÄLN€Îp€¾RÆÆÌ©G11\ë‘MRöèéO6wçÙ€;yá…ç_|Jo£êVõî•|æ…OMÏ–6VQ¥j\¿òmÇWÓ…1‚’åHbkíz|ä³z§A²QŠáŽ<•Îõí/ÝP»•TñP«úHV’²«nΉÑ4Í‹NàJl„æhBò^§Z÷}ÁT[>Xœˆrâ1teÀl%1 JôØÌÌoü—Ï¿üwïÙ†=2>Õ—O®>úÀÖ´©CO­lnÍÏߎÄ3µ½e×±’é¡JyÝ2{³ÏÄR#º¦’…êÎ=%ÊŒOÊÿ²ÄÑ«äl³b,?~Rm.+ LHÖ5TË花¬i¨$'PŒXÝ|è;¦)˜ZÛuÁþ°úfXò-üÕ®»fƒ•p#€Za‚ìà8e`è П³?qòÉc‹Þ}ã~ewYŽ*vW“¥ìÞæ†ϸ’1>4ÔŸ” ýó‹Û“ºýöw Ì>n@‘¹ÜèðØ©ÝýmUS®½óèŸz‚.(Y9’æ$Iën§òÃÉLšÄ\a"–1Tm}õ´!•ò^£ºíAš5÷Xƒ¸X¢À$ Ûµ›4§€ð?€0w­&ÃGi>‘ÌŒûسŸú4 ¤C0ËË÷5µ-²ì꣱Ì`4–‡ºsïÃW«»ëÀt…‘#ƒ£S‹ïj½æÄ±çÏ>#°Êúêòû?þÓè‚ì‰ÆS–ih½N¯Yqóä‹ß„NBQ$E‘ù>h Œ^-—O7öW¡˜–¯i=Ó†ÂkíïîvêU×W}\O(Lïž È€JˆÄÆŽ?ýðêßÇÒ“…¡£õݹ‘écc“ÓÃ#Gò%©[CzO³òÈÔH¹f=º»QÙÛšcüÍÍÅF¥*ÄÓJ<åicáv`Ø…Ñ™hq°^^ç^–”½Íùúþn£²ý("–ã±&sl)šƒ÷;ÿ«eö*®×ù­jæÃ;—Áeñdša)Sï°¢¸·½¾:ÿ!üVŽ@½v@æê]ð<–GJdG8t—ý/~á?U÷–)Ù7P XT*¡òªÖj”ïܺ §öEQŠ>WÞ) ÑL»±'‰,°ÿòü‡õF¥Ý­éÝjàºP”ì£D;µÒwe%-ˆÑDzP×Û‚(¥ ƒÝn»6:}1?Tè©[/þÚwZ;ýìÇ.¥µé{×ß’d *Ãø‘±¸Œ"1DÓèþzpëÖø‘‘(TetëÖ}!’ìÕÖc1™dÜf§Y^¦ŠÏœxÚ´ Jb—î^ã(¦U¯’4ßj!óÑdŸïQµí‡–Ùöé‘ ®^~å@›“L-Ç<:s!)Ç„XFî+ݽùvem…"#ín»²s#–Ž9séáíÛ+÷XN”eù·þ´QÈ'êõÕÛ7_›>?}òèÚ½‰h†çR­ŽÁF£é&RB»é«m-URºÕæ{o~•ð¡ácjÏÙÚÞд–¢(ÉdZŒ$„d.•îmoTwX™©©eu§Ü¨múK¤\ÏVâCºfUö,+"÷ÑT$Yñisl¬°¿\ù›_I&J ¾z½­x¾"åÍ­FyÛƒZ‰äF³ùþlîp2? Ï1›¿þ_[4kŽLænð~" 5+µtçEÌdfp¢ôàá­µÕ+Ù‘FU[¾ûvºo¬opÐ3ôÀôï]­Ö–€‚X–) “£éžiˆñb¯Y-¯\Ïõö6L•AŒ+¥s“篭Ìÿ¨4v²²7/*±c}¼º¹ˆï.·VÝl76d9~áùŸûõïo-¼CsQ‚‚š¢fJ‡][ì´|$ÉG8Gk1$ïèj~ðP$™êö‡ÿ7¸wç5VQx>uøÈÄüõ÷ν•ÈŽÅÓ£–Vév–Íjm¿ÙØÛâxx, -6>~^³]­}÷ýoýÄg~SüÕ=]+—÷?hí-Gâ…ÒÈ C­µ+›(`}’mÔ+¶éùŽ*Ã.É’”V[›$äJÓíʶÞ-S )ÅÓžKƒ&QÛ»§^ø<ê;‹7#©É€–¶_gJkÖ\Ë¥YÙ2ª 'pRâ t ‘z½;÷Þw1Z,N®¯\é?tÖ²ÛVg§Tiuœ½Ýª8E†r¼0)Iñ1&`<«ì:ÃP J¢‘¡I†f¥h^IYN‚Þpoc¾½¿ýÔú¾™_ÌL L  2u4ÊGGÏîì<ŠE2Y ÅjfUJD6×îçúަ#ížµüðZ6׿2wYoïtÕ} ä—Þjb!™ÏõOšêîé3Ïon|¸²xEˆ•xAèšÖz*(œµ…w‡ð#ÃHîüQ×ÑIÚƒªjöW©hr2–””×1ôF¹¢·»/0R$¬©ÕXœŒÞiBỦRúÉD¾(ŠtahN­«©7@òÕw˶…ãË‹þÔ‰Ów¯ü—ûyehçÑMÛjÏ'ú§ŽòÓŸ«U«¯ü¿¿ØY¹‰H(\K™ÌÀ“d‹û«wÀÚOþL<;±»7·2÷Ú̉ǣJé{_ý‹^¯ @"Û')‰úÎ6hKh$@ ’¢E‰`£¶f.töºôHh* GÚ;óÐNã ŸÀ…9rñ÷F¦Ÿèî®Î>ö©½å½í»»ËW}Ë,ŸÛ]_‚ÞóðÙg?ó /½òo"*uçê+µÍ[ñüpixb`p†F’f4bÉèø¡c$É]yó‡|"ïL6z,¾óð¥t>‘Î>ºù£ÍÅ›5ÈeŠ/Mžâ¨àø©‹SGO=º¿i{v~ Ø­/ÍÏ} EË[•ù[ßq,‹$ùüø9×Ó*k7<Ë ;v—f(^ÊÙÝ:ô;œ$&sÃ…Òá±ýgE(h èpKÆúŠ “9:HdK‘äÈo~úo,pÃñ‰n§70u:ߟ;<²»±üèÖK7c1å±óOBÓÅ‘ýfË´P¯\í5Û÷îü8šÞÕõTºø`î½Í¥jNJ#Å‘éz}‹—ØéÙ“4aöŸ˜ðд„µGï÷ZF¯Z‰¤M}"Ø­W\Ë$i/1|è>@tAšûŽ-÷}Â÷@Ðá.UPb‰R~èH·Ò*¯,@ï]vPüŸú©ÿK¥>|û+íŽeª AHR>c«×éN=­Êöƒá‰³%F ý•òÆüµW86½»mU ±‚ ÄÒÍòªÑ®#ß–6U ¹H§Õƒtª8PZž¿ÇÉ N”x¶¹óÎikÝ…ëo :f¨]’‹G²ÃD #K%(šŽF+{ØÌsXÄG"‰|kû} UHSmB§š.MžøØÏ¶ë›+÷ÞxeæÌ õæÊܵ·Õæzày<Ÿ†–Dïl¥úFÍ>.Iq ô½ÊZ·³W>ÒnT÷ÖÖ÷7À$~òø³ VINªnoµª›GO¾ÉBª§»[[Ûwßúû3>Sʯ-ÝX¸óަ™©þÙN³N’ÔÉ Ÿš»úOõýø7V HZonx¶Ú—Âý§Œ}ž$Pzè˜ 0ÕÕë¼”n\ooÌ^ü™éãç·WïqŒ²òèša´Š…¾¡º½¼M‘Á¹OüºÀò;ßWbQÇ6HBLå&ú?¸ùí­¥çŸûENH Z©·ËKj»Mñ†O R|oémG+>n¹îÚÃ{©œ9÷YE!£I¾×Û¹vùJ¥lÚ¾mi¼*•˜e´u­APЂgK#i³[á…E2©C¿f©[(cÄXÉs¨hf”—à­^4Ú×Ú.k­úìÅO./¼.ÕÛ=93‰‹•µ÷$IDÒ4!pÁpZembú|6_¹ÿnqðP~hÆ÷É>H$²ão®>Ü^¿kjMø(%éìp4Ul6+¢œG‚.5šÌN8ä•ú’®uð})”6Ïe!žRâ1JbÛ™¹)ÃÓÂÞÚýäÈÏÑŒŸ*=DÖ÷÷YÌÅYßDnÏF~8Œ8·ºqŸfSé‘:;ï ´ã{ª‰+‘„(AÞä >Ê)ÉB>—èÕù¥‡sœ N¹7÷oõ +VUÃ0!Ï‚Âà¡©#ç$FRâÑz}cîòŒrûÊ·Á0DÒ©ì¤aX]¦ cø”«ãWÏoãK$’'Ï OÎÖöµngè±ß•9–JC;¨ªeø–Ö“Ó)‚´l­ÓÞ]uô´RzÀ65×¶=O¢‘‘]5û,-FHä¦3)’$}–îݽå÷K¥Áx¼O‰Äã1èyïÍßolßc¡&ûìÒÒòÖÚ\¸œUb™ÑC'gfÏl­ÞȦ‡"‘¾o|õO¤XisåµQ&éX@ðù43[" Nበ„¥Ñ#J*U«mçŽý*Œ'iFªí¬hMI ²xETâr¦8œë›h·4Ëõ{*”Žwt"‘864¡ÐžáÆŸcòÓ‡O]Ò{{„£Cô·–ŒyN‰¤òC9žt Cë¶Úo¾öL¤¤¶›x€bu³ÅQIbÂåhT·Ë úêÁû×–o_ÖÕf€¯{]d ¨çð†7ÞTx+M >ž9ó“COýQ}í†k©ÄfÃï DL^ìŸÞÙ¸â:¦’ꣅæÓë®ê­š‡¯"±®©ˆa¥4Œ޶Ã1ÒÌÙŸîu¶»ÙO9&ÈÑO<›3ÇŸ:|äÉõµ{Û»k–‹Þ|MïTy1òØ¥Ïq ‚Zpùå¿ìu+éÒ! r6;váç.ç+EŠIø¾å;jx(`°_"9ÓOø–dØÔÄK6(%’$@)2t,=Áò"=%–Ö»?à)V6­º¨¤>»‹7}¿I² 6ÞÔˆÃB"žªDr¡w¤(nowhððÖö’KñÉÄP·¹?0ùØðáÇw¶ï³¿vÛìá»#Ç49ʲB”®uÕ^Çóè¾g.þôÜÕoõê•Àc. p­¾F4<>!À7êx< 'øÔÞˆCCÚÚyq{í.ÉÉÒÄÆÒ5äc£ÝØYõ\;ð{ng 2FÁJ¶Ö l t/¼Ÿ`Y /<¢.^,NL äh¾à1‘ša·6WöwZM€[<7!ˆB2…D§§ bbþÎë 4âÙñz¹þàÚ×xN‘’ÙÙgåÕõ?d„œç˜®kÌ H‚ƒ°ÀÄÇÁ×òä‰ç~Ÿ$ÈÍúîr³² ¸Í$rSµ­½× Àt’ãGïËá¿axIÐOB#¥·Ëð/'ípX•e…ãטþx_!b8Ýz³rÿ꺵=ŽW⩌A¡ R :šh*µ·v—aùýËÝíõ_ÿ;Ãì)™©hfØR[øV¹± 6\Ûñ@ß«‡×~àÀg>÷W–Ù}èÙà&šÜ+¯©Ý¦Í‚PhÕY)ÙÞ]¨˜zݳ{Ѐ°b´oü1K-CŸˆg ˆG„ÃpL47Nñ ×ò¢±t¯ºÜÚŸgÅŒEr"1<{qîÊ[»;x®åŒÈ Ï<=~èd·¹526ÚÞ_ëu*ñDvdrÚ5Ó—ßúÎÜõ¸.ØVÝóm(÷ø¢ñð4À—ÅxB çÅßû1´ñj¥W3 ÕÒÔêÔÙç|øÝæþV,3Þ©/›zÓR{ží@Îà9žþ@õö‡x³ à< THpˆc™%ÆÏ J|ëþ#SG;­Ý©S—n]Þ_»ë»0ENQ4M‘v¶T|òéO†×n ®/Ï™¼páã3ÿíþìÚ[/{>aeQNô×7|_eCõØãeß…™Ÿ““yÓ°Í®k[¦¥í°"–º&à2Å'( ËWáÉaãI '?X#Ó-“Ð: Rºoxòä3ÕíÕ…Ëž­¦¦‚ÀvÛ UkŒN_}¸´×l@ÛÎÉÉH"øÝ±Ãg¿ô’ÚjÈ¢¢HÒ£[/çŠñãŸÿàýͯ}ùK­ÚÅɾ‰êÖ¢¥«x Fà1%†Ž3|öw ¤ÆJÓshvˆ Ú â ±î5›¶cøžiÏ6!ˆÎd)OÓðÊG‰” D%î»­Cgž9ÿ±»uÒwk­õ…ù O+5»^`!Hv*vóÿé&ŲÉ d–Ùë)± ê…çÎ?óR.ç4êÛ†¥:·ôhóÖµ7nþ S['iÙ÷©€dñU<‰§•xârß'Éëz¼"Æ24‚tïJÑ~°ÓÐê¶ÙéeªmW«c›qDdè³ð¸Û3 šp=ÿ‘ÐùrB9a°ÿÈ‹_øí¼ò7NÇ9wñç¯]þÎõËGóQ‚ˆë½®çj4ëóRÄwHφຂÈñ,©(‘KŸýW'ÏžØ[Cu+åtµ«uív׸qõeµÛiU×0 ‘:Xï H.óyâìsÖçOÞÞØ|pûe!•­¯/x¶ë;.&B¼.‚‹©ïÛOw9yúÉ—²Ð e2ÐÁ¥ÓCï½÷ÚÚêíüÈá^@Züþk_5:<òÃÎ$øÌÓÞx\L…#ZÏ^i´ÈI)–‡r¤£±D˜BLŽ‚ÀÆ÷þ(™H3¬¬uõhf “I‰IÑȆô¦Ï ăÇÚ^»ZÛ~8˰­Ýíy¨À*µõ‡4wlÕs íy:T–‹;®AƒãXRŽÆÎ¿ð¯÷wÖç®|KŽæ™TßD¥¼„ZÝZh•¸ÙU I‚£(~dú’‰Ì]ûºeô Ä:“¢Yx”I.š÷í]äùáìÛ%ÀkJïÔ}ÇãóOeŠGµÙk•]¼Í†¢`¾±Ä; ^‰ÃèÂË fJ~ê°H2 4M>è+ßÃk2<ôBéd>›Îåó“ƒc³MÞ¾òæÚü{ ,ž~εù¯ù·À1> Ø%LQ ú„ES¦Ör¼…0ûá"Cñ²ç9Þb ǯ!ÃA¸{GpJÿ%8tL P¨©OQ½Þ¬ðp©Å+/x!lðôŸŒ Þ®dÂ/œ\CPÈ Nä¡™-öMž™œTÍW¿ñg¼À±œpö‰Ï\~ýÛó·^õIˆ©z>¯_ÂW¯¢ÁcMùR4+§úš•uÛèa©Œgßá‚tÝ,‰ç99]Ûyí{6À«z¶ïy>¾ ÿÁù0Áº(ÔgØù¸æ‘á&M„â;!ÞiÁóíp]Ú;Œ^p2]Ÿ-ž˜]{tsþÖ»`æøô™™Ï~ñw~ºÓØS«¸`yDèÊ©Bnðˆ‹«O`šv»²kt» SáŒ+Ü#ŸÅh¼Ï4õns7^xÊÉèYx¯o÷ù~¸²n¡N%q<Ãù4‰˜°pãì ðçD8”ƒ\øH*7(”¦Í<öÞ+ÿ]F<Ÿ=½µ¶òÆ×þ˜¢DP.˜1ð£Èp³ƒÊ‡bùaèò(Ûë†jÚô_.Þ"pF†‹”á¶'VÒÑô)·—Îó!Kñê Þ ÂßCãŒû Ÿí€1v½°Å•Äb„!q£I:#"ð¨/™é?õøÇ}ÛÿðݯS"%Ç#òßýßÿîæýW)ȳÀÆb†¤½Ðu¡2„Ö]Âëp„®ÆI6^ÿÀȪÃÄ; àKø!u œï£p%܈×}QøÕ;øBàc‡Z/Ü£B!–Â}4”PŒãÏ “‹:Ø%ðê…ã@3—Rœ˜=÷Ä'Þyý¯A{,—/MÅxñ»ódØ¡$‚/!¬lðcq“á³`!\#ˆðï(ÊP+ðu§‡÷ÊäÔrö`É l8X×ÁõÌ÷I0~63\KÚ…¹v˜B¾Àð ã‚÷Ùp\À{ Aàù,¥ÈñÌðác©\’¥˜/—s‘hüÒ¥Ÿùþ?|qñÞ›pÄpCé`£ôVµÂ­&Ü^|”wf$Ÿ(×¾—ÄØd 4…ÀpÂ?`lçG—(DQ€aÏ,0âÏÆçÂÂÄx¹.\TøB»–M2}…‰£gßøæ—}—Ú}hæÈÄøÌ_þñ¿1ô…¥£â“p¡ú`/ácCê×°Â-8?”:Ýc¸\GÐbt"À ~˜q â<Àæ0úçSm†Ë—è£XÓÁA £pŸ/¡†y § õ%¼‹¤E(¤¼¨ NŸ~ìÙ·¿÷·Z[e6•Ï>ñä¥å{¼ýý?§ðj¥G„æb”†%x_Ë?®–žƒwøy–S92áAòÂàe,$ OôB,QÁG+Žêž:ؽ w½0ÄÀxLH­á"):H0×±åÔGÔj”–)Ïæ†Ž?¹¹òpé.C‹J\)–ú’Ñø«ßüìpò#@ýQ‘BÛ~¸Ç “÷£=> ƒa¶ÄF‘ÿ(ƒ2§xœEZiŒd×U¾Û[j¯îêez}±gƉíñ;ql;&±²H! ‹ø?@‘PHüAB€ø•ðRY"v¢È!‹Iâ8¶ÇÛ¬ž}¦÷®^ª»ªºªÞrß½œsî+»5²««ßrîY¾ï;çÞòÜÞc2ÊÏ43ÚÎmY=àž´Rq®˜åÜpÆ­–³€Åð'c³V2Ë8ësÅáJfáœÃ_m–±2· ¾²,bB2á[m­(_I¸Ï¤Y3i¹6β$ãÞmàFx¸…»ŒÆ'JÉmfÁ>ÝÓqËÚe†s/ñÇ>-ü)Ë8ØcàvÓgI^ν*SµðŽÏä%fø. ëA£¬M…ôáúÑŒgøXæÁ׌ÅÖHŽ¿Z¼‰ÅY´ãƦïzzká­4îfi,d,…Ç£‹˜0p»‰, –Í ØÌñGŸÁ“î™´cmÌ…D˜&?ÅT…ñ7–X2¸쌲ޚ Æ™¨Yî1‘0›ZëYJx—Hñ‚3ð“1‚͘‚µã-ÄÉC[À‘ %®l¶Ãã÷>32qèæ…×Wnþ*ÓšãÚñZx>\/„2°JxWqž…Ì€O!jÒÅ‚Yx z ~5:< ¦ž³¼`m‘RV ÓLhïUà¢f = XèrxD ,¤d‹¶ìƒD‚×§Þ`ÀÌ4†+‚ ^@~¤ÝB¹rðÔãåúìå7~ØÞ¸æŠý¤ѬX¸™¥ ®UòòŠY|C'ƒSÑ øTø=ëƒ;Àÿ "+‚`ßç Ñ{ M(”“\`¼ ·ÑHðžÅÐÀ#àár>Kð¿øÌœ`³¶5›\@âyŒùŒû~¥f! Àò¬mâ^¥>~òág›k‹7ÎþXxcœÇ…Š7uðä oBŒ1ZÜ€cÎd'F–Ši‰©JkAû)Rh ó`á¾/Ð"!F`rŒ•9ñ ÂË„O.Ãñ|½1À!B$“‡?zèôÇÃÂÜå7~¶³qK§]°¢P(§=²·³ÚZ½&}Æ*Ö`šøHŒ$îõV†'áE˜„Ü ¦‚{Yn³Å„¿ã¡®±¥€Ä¶¢8ù¼cð‡O°Ì$°^Áâ,zVX‘µ†[etG*p„bPi<ð©/B%(YÞÝÜ^¾y¡µ± "¥+÷U½1Y¨Ì¶V¯G{Ûœk!Ñ'YÖ»Û/•Ö¯½iRfCð íáµx§Æb(â˜>LåÓƒì o`LqúK€D'„p¼ F¼ãe`l$”.„E(?ñýâøÌÑÆÌáéù»Fê™ùQé±sožýùKÿµ±t^'=¼°’FWE“ô =ÐhPå!cHtIø#¤<¾;£,•øÔZ›¹¼Ç”F›ñúžªëPçÇ£ Ö™5 @+„µPª„~ àž¬Ï8~úÌo}õ)ÖaJ±ÖÎn¢½so½Ö\_)TÆv·Û7/¿ÛZ[LâÓŒ¥a¥<~`Þdº×ŠÚëkxÞ³Ö/TmÚOà®*h&K¨œŸÑ2ƒ™€˜#œý kYÓú2 øh f2°ÖçÛ¤=@NÈ.ÃÂÈô½í#§ÏøÙÎüüDPaQÂ6›KÕ‰±ú¹£¶Û\ºýl§Û¿qãÒ¹_½ÒÙÚÀ,åTe€!,–a:÷™¤+×®_M³à9€ºâ2ÓXÔ>@Ck"˜Ê8¡zŠq·nA= QÄä!~B"À×à•jY4sÿïÞûÈÓ•øŽ|€Ù¢¯õÁÙéµ¥‹c3;;ÝÎînX(߸qöê¹Wá%šõSí×wq¯²¾vµ³µ’i´Y@â S ËUåö[»Q´ $‰ŽI XBC°$#Ø{Ð~ £Zsù‚U‹!Cä›D5ò2A(¢ R9D+ýÎÏ ŠÝ±ÑÐ/zí>Û\1ÍÛ7—¯¿uòÌcauâÒ¹Ë×ÏÿºT-ì‰Ï^½~õÚåó­åA§?d½v3‰và!5P˜GˆÉ`вš‰Ñ;E‘ N#¹ÀQo@°4ñŸÄ„Œ¾wÜ-ÈóDÈ&%Ä”TP™)* 23øŸIùWß¹"U¸Ù\®Öçó¸wóÊíjeäÖí³g_ÿÑÊSÇîþȉ{îÛíµóg¸7ò¿/|§yûJ<è'&À†”•ù¡«‘Ø=⸠Ù×IKoD§ ¼Ø89eÊÕ°¥õb® ¢(Z$µÎË!¯ބހ›ýÁ_¿–ö¿ýê‹­õ+žÏžüÌï_y÷µn{£<:ÚÞÝètwï}ì Kïÿbrߘ*Ï¿ó*÷jëwnö¢,KIº0‰„¸ð#Ž ‚aSø`p™Áuh“û`™D“p-ÄEºµPÙ<–° á LOÐãà+üQäNµ‡ø=˜$ŠÓ¸WÝ7{àÔHc4(€ÒÊêÉÃ÷1å¿þâ?NÌŸ:ýðç~ù?ßÞ]â¼Ìlˆ¾E‘€o “ûDô>·f§tâ’R`À@™ I ‘Å À ‰p¢²ýïÈ7¯_NèO*QPÒ€BÃ$†YÌüå¿7;Í…ÞÎîêêÊÎöf킬=vêÑ”^ûézÅ}Ú°­Å󕉓Yõš ëqV༈Œ/Q`á[u»Ô˜ JµÅ;¨QÑiPÑ CXk¸Èðåœ Y&¦Ì·.åhù¤ýq&U+^dP›BÁ"ÂÃGÈÍæÙ¯üËç¾úÑvgacrfbqeýÊ…_¶VT&ï¾ç7~ýúËW¯œÕ,ìn/¡›¼Œ„ç¡ôÁNk!!ËRtÒÏH¢h!7Y: efFÚÉ€ÉÁÄa¿b®jò6CP2¥Ì壚bBä}¤Úó‡Ç•Å÷&gl­ÞºôæËƒÝ·8T©M„n¥µrUxå¤ß~'A’ùÄ”@œ,aÔ}hr¦®cÄøW‡œš»šåÎlîšmæ ß!bVF#KáÄZ®îÿªŽ;ˆÕÒ+ΤɞòÕÑÓvWA¨{~©ÛikÓQÔß\xo|êøÊâÅ,ŽuŒsY(I¿÷Ûq!°\ë𒑆Ψ4[±aþp2˜“Þ µàˆ‰F”INåqLN|4BÉ(.´7ÂîÌ”f>B›õtÔ÷ýòéGžŸ>xðŸüÇé??6¹ÿ•ïÿ“ôüúøÑ;—ߊû]å^aÞ¥u:hÓ8N¢¾Í qnf³Ä%:¹H‘·6v -°µ&µéZ.ÒÒ8Úb®T1Y|²ÍÐcÒ|f’ ¤‰¢¼B¢,Ï>ôþgîìÙK¿úAog=¼'>ûõõõï÷o}ö™Š/¿ýR¡<µ³±½Ó¼… Áƒb­räô™Rµãæò͸ßqSÂï§.†4€Ð`ùxÎbQ£;iÌ….)ÿf0n 8.sÝŠ :& í.sYÇó;h*N}Ú GîybzfnvöðÂs«wÞ?vêé_üðÛ ÆfŽ7×.•ê3{íÖ Ý”á¨ï&Þž?zê“Ï~ãý —Ï¿ýãvó¶¨Öä•E‘ÅåpǪ”ö.cñ’ ¨„?“æa$G±Ò‘ž¹ã2—rÜå“°¹Ò á”9ÇÊ(L>ƒ¯AË„¥*”^­qtÐkûA¡\ÝX¿¹»½PŸ¾[„…Ý•ëq¿_,KøÄéO¬®¯½ýÚ‹ÝíèCq¾´åê´ºfÊ:‘æØ>Á˜.ÜIdî†RxÑ1O];ÃÝܸA+wã?NCäzâ/ ÇìýßÚ^: _IÑ’³ô±Ïüéò­ ËW_oÌÞ“êhsùBuß‘öÆ­d¯m­R’audt~þè½Å‘éŸÿâ^‹’#!E)r¢®’”팄±¤fÎ*J0Ì£êvÅ µŸº™ ‰dÇ,Ÿ—å€ì†ÆôHé ¡j³_W¥ºçr–ím]¨MLŒN]xÿå×DèAÐÛÙä¬õwM†äÈ4èS*Ô÷m¯]ÓI„¾B1æˆÒax‚Ž58Hg‚ØåOAפz£ÕYf‡pjò&ó.±Ç!áJó ÆrŽpbŒ“Ÿ?ò1 ”j­Þºõ^ké (x{X­k 2)¸ß^½€¡W¥ööz±:”÷ Yj-_Îp(çd,õŒ³Ó²\æ*DAí,£±Mž.†@žn¥Ò¶G"R§@‚59ø“2‘T^—6¸ d²qø |ºwää#%¯˜ô{—ß}Y›T(îG S@ʳ‡„Üm·›{m Ý±¹{ÃRãÆÙ®IÒå7‚ÿ¤P'[ì|准ö&ˆÖDnž>ijõ'$UÎWÔžÑ"$U5·N A žóàs£$ô,#s3³B÷fæŽöS}áâ[K —&öŸÜÚÜ\¼ø\[¨ŒªÐãJl/ÞDiªìѬ^’š•ÄŒ9nS—гGì;LÿCû±›±yK…™ïÊÁ~@mȃ<ß ¡ïÔP«‘µB27Õ"¿ƒñ{žüfw»©“ÁøÔZ£±µ~ûé/þy{gkeáýÍæ‚(4Þ?ûrÜßó‚rP fŽžZ¿³Þݺj2>S[ÄqüH;¸‘}¬£1Â'ŠrK°–!YÔ«®[!5íÜ; ÎÃÔ¶SqáÞ’$û™+(xìØ‘/Ýóð—®½._úþ ·U®LöZÍѱÃ+ ï”¶š7úÍ 8öׯöyÁþ;ç^ÊÒ>N§É•æ&Û.œQ³±|°à†N¹'­#Õé¹ëéqá5ÎÆ)Yò$±Ôù e@!`û`¨ErBÈ«Ì=ôT›œO¢½þî"4:î :ÛЀX܉°ÀÕ^X ªU€MÀ¥•[w–ÎQÙ æX7–NÃ~Êuª‚’ÙÉסºE-‘#¢c#—Q(iäqÂO"åmUP_#I÷X%xHQŽð9h¿?ÿð7[Ëïù¥FcæXµ\­×FšËW:Ф¬¯hho¥'ù T-WÆgÛ­A· Í»I“ÜB,[¤“œ|ÝÍU4î#H2þƒ¡•ªSÌaºÈÑœ"BC!›Ïœ–@½MUìf¹Ì§!?0cLd…•ùçM›LC—[.7žxˆI±¾r{ýÎ%'Ðgy·ïÀ‰C§¾záõïe(VEÞ‡²<°ÅÃÂà¾!µ0– ¯Ð¹aŽ}h؈yî¶r¬ËüŒÒ ú/a5d¹^µ$¹QÇ2Ü- ‰|#Úå$'/{©Dœíd‘†Ä^“Ð}#GK¿uVÃÊhw#Þkå31š~î\MÆ@à  Op*RÍÄy#æ&!T¡NSæJ•çKQAäEí‰eÚtrˆfne À_ n soôq`â¢i÷V…ÐÅ3èªh¦íWfD0u6uoƒ¶} f5Õã0g²¼Ó SÊœòá „Â”a4#µyå6+Ü”Óé½áÆûJ {4‡ š–ç»o¹ÒF*ŸNÏk<uåƒ …¦Ö9Ä),Ží?ÉdyõÚÙlÐÁ6<‰¼c¨ãp‚Š•e9þà caHN;…pˆ„˵S˜˜N‚ZZM{»¨¨q{³Ñ pI5!qã·gí‚4Nô Õ9ìQz ø¨f²€rCpT¼ÒxÔm¥Ý&w æ:¤<Üî†8¡;œøœö[ñW°ù7!N2†Ì8!M¨ïNhœöcD2$”\¼9šˆm¸ç®p°Œ{ÒU4h›`ôcÖU wãÉ…=b,T¨4N¢m¸7mòæÈ’ß× 5tø Ú1É[rN<¥‰¡rþÊ$–çÚvªƒ4o-iÊwxyOdº’àaŽye>•PáÈc&—Ì Jµ8¿‡±:ÃC–²ÖáŒÛާáIÚ/Ýæ¦›rçiŒÍYX~Ø}0'€¥K!›ÅÜ=ÝIèˆØ–;í9b¡dùYÈJ?„õê¤ç>:ÔTãXt´RÆòmnø†6$Û:}NXMU†jÍäûµ¹¨c´qo\žÐÃ4Ëå;D,mØá® ÜP—)§X¤‘Hö£Ü£Èƒ_Eà…%ˆZíÖ&Ox‡9í„9;ÉhíúŽÛÊœŽRÐ.WÞ4ÑAã2Äm‹Ó 7Œ(œ„ œá¤ª1òã+nžfh»_àá.†Kf4•tµE$Äù³"T3BIéK“ ´–¢&­‰¹»5žOð‚ú' Ϫτ̣Y·%zçðºío^ ]-:–c‰ªry™>çczšžeÔ§ÐÐɵ¹f#Vt£qxN§}0|}œ¢É÷•¸bî^ÌO©@Mïï·w¦œY»sÕy̹‹ç ŽË^‘瀃8ëàÆ^8}²C%oÜ&øÓ "ÇeÚÒ–ö¶ttòQRÕAûê ËcÆÅíK2ÆO† 9%ÐhŸkãq·™ô»:MürcöÈGKåòêâ¥Vsìÿð`IÞÊqBéÆe6Ÿã¹Å_‰¤Ò|²‡" ›_’‘]uFbÈ,s<1ŒLPCÕœ«  ôlJ)VÂa¶T­žºïÉÉCg~ýÊ‹q´[(ªr¡ äÚí·é웫ŒÍ¬ß¾¤ê¹Y¶ Ö©M˜ëÝ® ®çÕŒT™È ʤÑ!Oá©1¨&øÕà9 Hvœ~Xì…IG œÆÃ gRâA«c¬eÈ)ËcÓÇO?w·‰ÚÚjzkÅbX¯O—k¯Ÿÿi¼·Z?xâã+·.¨ÚÇóIQ®iIM¹±ËPúZš3SQ(œj ™C–É÷:©4ä°Fˆ9iȆp쿜þ”Öa>nMR`‚H1bP/Ê7)eÏ+…÷=õ•Å+ï­^}S… x©Y}|¿ŽNWè¥Â³ –«Ú“ Ë'%§˜ã‘áZ¨?5NÔS€¹Í6œ 2ù–”sº—ÈÒ@Ÿ¡P`¨õ c0÷1@®ët²‡c—Q™:˜vÙÞÖeáÉ 2‘FÝ,êI¯d4º Êói/,MÀ Ù %y¦jOqäØ˜Ä¼çvÒé‘ôíÔ¾rƒÇ¤oè4ðmòâŸðp Îìž½Ézî<›Wµ¶H'd„NºÆ¸S ÇÜÞÛŒ†´AIk—È–@! Ïh:ÂÁ3(#ϯIY?ÌÌ>r耪=Jº.9Á ÌÕ-ŠRQðj´P(9ì&Ôë¹¾•†T(J$7Q¹>9â~¨³q¡#j[;7ÏÄ@:øVJ™%]å…au²»ydHàæ´Dö±òJ«ÂsjX#gTý!”=X8œúY‹ÇED,§]ô ü=¥Ù8"< J“;¶Bc”ÛY€æ…ãL)ÂóƒpbîDm'©ê··ã½-ð¿P‘ tã4ÂX”â^Xó‚b¡X/GêGw¶¯@ǽ³~›ŽCJT°ÒnƦ®sÇífßË55r·³ñRj@!ó9µoÄ陡РU”¢ÜT(WS‡¦¦ Q¼øÖ÷”2ó‡îúä§¿þ½ÿþ·­æbXiôvWUÌéƒÛÖ:IpVŒô‘üdB¾•[l9ð€o{Ô¦S~AÁŠü´#Iwa5 $à´s.â†=•â 6¡ õ™—OCqJ ©%ñýÂx”£þÚèÌ቙“;[ÛÑNs|jfnnŸÖ½ý'yù¥2îmßNzë€IZ§Ê¯)¯ô·ÝÎêÿ?¢#Gxœ=ziŒ^×yÞ¹ûòí³ïœáNŠ«¸H²¨]¶Û±•Ø–[' 7v4Ž‘¦‹»R ¿Š8(ê5Š‘8i(nmÙ±UK¶‹²Hʤ(r¸ g8û·Í·ÜíÜsNŸ÷|T¨Ñp83÷Þw}ÞçyÏ5ý!Ë)Ûî°’Œ±LdmÉûJåø‡aºŽ?ÄL[ŠTd;JèoÚ–Álfz¦SÁ“Ê0f‡Ò ™XÊdyË4³<¦Ïã®5Mæ¸O{†eYnɰË"7™iH^·w,Ç0-iZ†rEÜ3 ›1<0b†`LZnAš¾áÖL« ²Ä´lË2y¿®Df¦]°½a ód"ó¾à]¦8™Š›º%‰?ylZÙ¯`-}R0Í.˜n™1Ût+Ê„ñ!ìÅ •˜¦ÈÓ†_±m;®/†„YÒ1,Ïv+®_M¢žáV Û“IÃ}ƒåx˜T BÃS1ä¹Ì®˜î(–SDT%O¼ÐMš—ïJ‘á~¶û=Ã.HHéÂo$R gýÒpನ-à)¬@ŒYf¢~3ÜÛ4úMËbÊ”iß2UX‹{›*çøE!zRFþÐDB)'STù©þéýø#øŸéè#ØÊÒ¦<3ÜÔ4•Œ½b5Ãuq„Z²œŠLfýº¡:2«#¶:q(9ü.òˆ$Ì`þ*¡XÞSùŽaà+i[ˆ'È*;˜Uʹ”…w¤²@2ñÙ²œÀ <Çø·¾ÆML¤ÅAvxÒG/XÞ¥Oô(¼Üá±°ƒš´KÊ®*騸FÞA_ Ö’çż'©w|)QÌ6™-º ½£¤EŽ›á¦ÌrG Ë/nàUÏ* +J%‹a¿}ÔÕ.Ða§Ž…¹^ ‘T@‰´ƒ€Zþ²Bw©ê·ª¦–ZއÆ?,ü>Å É$@ðÊ£Ò* é†O¡¤#æ¾–i“©HÉ„`£¯~,Û5-ó)A ÑxT ²Ä¬¢W;É jRxDùÊû*ï*9¨¥ˆÛ‚”s«ðeb;vmò@¯/ »j(.Ò&Ov¨êcÑ&LÚ®mû2ܰX¨Ž´¶6 «hÚEÉ9ÅÄ2´Ëž£DA0˜@’’l23,Ó J¨¤ßFÍÀHdÓñÊÊð”ò™Qpk‡w‚>… CæRô%ïPP×"~¶(“©eQÁ*PRL×+Iõƒ xÄL)øN·MFÉÒãõ O3@-ÃvüÙ#çÚõFýÎeÓôð7Ò&¼´¨³Ð "ASá‚ÚÄ®<îtë+¥Ê˜y÷„÷›ZA· ¬˜²Ü¡ƒp”`ܰ¤†Dd!OJÄTÀ(Bf¸a âI×qý\æ¦áR$$…e¤ ×+Žò´CepN‰È4‡©–,Õ­„¨…NPãiªE5eÚ)O¨/Å,ÁsÀç{9óò}qŒ-f$ýDĶñP@–é„e<]ä‚åaŠ¿ÐH3ÀIª¿öëw(@^X1-+êl#ˆðalþL!DK^ˆz@Ç¡p -J™ä=ô'ê^æÂ´Ôr²ÙR)à2oótàyð¥ƒÜ,dý¦I}èp$Õ°dd1ÀÞHì¢ÒDózž?t’²’sÊŽ¾1ê@ð£Á¿ŒÁ•g ų1BI¤qÃÔ3‚°QÁ° C `ˆ !z6î Yó‚Z–E43ðÙD$)×H3RÇE9!0¾ëE.qN˜ã~Àæ (\›úåæ.4¾ Bó *bR‚¿hÀu"5»Ò}LdÂ4݃Féˆ(X䮆)\çX4 ”ì{awàp9Ëm·€ÇdYŠ9 xôËóLqòƒyB ÍÙç˜_¤qTæVŽRÓQ+ù'…¨ÁådFHurþÁC§B¿÷ö+w/¿†Jñ³$Mm·È9YÏõ<ÓE‡êê\߇Z¾‚Ò¡sA‰€u`ïi?"ùÆrR2ׂæ5‘Ss]™S+Š@ÙDœô' ¹²ˆ/ZQÍU”º[9>CÄŸ 8rˆÉ”²^ÝvÊ@f¯ˆ:I¯µW™èùï8VõÃÒˆªß­Ãˆ P„I” l4wBï£5Ü‚_“¦£Ú™«˜‡9K³Õñdº£ù•ЕKb´ “Ý–E®f£å1‡|ö‚0în)Ên[ÂR¿½žç‰[:ŽÙŽ¢'N‚8ä ñaƒøež¶‘  7„ 1j4…Œ/Œ¢æøÜB}c9çÀ@ÏÉy„F@À”4‰zIôâ!MìcvNêÓÑ%'¾AŠNCG œ •íØ–cP ÐÄbp3œÖÂŒFž¢=!—-ÍiO*š%>¸Ü¦‚„ãBc}Ât§@Æ;¾kïÙzñý׉–FšÆ 5XŠjG޾,Ñ•¦ð¤qHß—’ßÔÊÿ=¿’ëq >¯ ôai fãªeaº WÁ5¥™¡‹žöê=9Fl ü_Snò>E ·&LÀÛ‹7?úüo¿ýÓü¿¿û/@ü>ºÐµÁße±VÉ$«¯o’®¡yšë ¤Ô*Xèê5uêõå(§FKÓB¡ûTjóŒÁ DïšpK;Or‹±ûÜÞ¯<(i‰PÈZ cSŠ•ÔkjcæxP*e¯àW+“““ÃC#33þ¯o|­ÝXt=Ç÷Aß]I$w·{ý>†1Ï„ý¤„1‘-ͺŠïÚtÍûþ(½t2›¦U­^œ}°‰R«õÏî³bÄŸê3àc. 2•Í,KÌñܤá.Ü0ðKÕ…C¹"*‡EÅ‚§ž¿tþï/¼òͤ¿^*c¡ÍÀ r¨˜œ'ø ʪ2yU˜ ýT¡mfz­§É}EÅ Ý ½ mÌ–þ¾4îÛoR¦¨q$!)5‚áTNR5%àÔPTcˆ«µÊÈìæ­«y ånº…pt~osãÖØô®Í¦fç”p®]yǯLd½õ¨~#ën¢¢çBz|É,W±ªå@0»e„„d×ê^ãøü@úY:è÷Õ‘®K{¤ÿ9ð÷ƒ<é–"Èñª§ ¾ÀtHªÐ>Š\&†óGÛZ¹Ñ\YÄ-óGÎV&†o¼õl8vîGù•¿ùÿ©ÛX+–Š{ö,lÞ~g{} Sâ-Ã82¡x¡Røîw:ðE¯hÔ}Ú@௭Qzhif¬{ÓÐ`eèn%»5è\ž5‰GB+øÕ“’äEèL Rp´ð)¢Á.H *‰‚¬é¤^†hûÉgD½ LB f;ÌsñÙs¡™ªá &Àí²¸V§úC§žX_º÷øæÝ‹€xÛ; f÷œ™9xñï%q"²N¹V]س/ ªŸ|á_}ý>__½ìz jó5#iOƒÈCÖ€aö‘sÚ8F¼®+úÏì=¸£ÿliÖZ/…]€  ã¶:Õ£4©m!PsÇ/2õœùaÙô,\V¬íio¬ŒÏ.$ýÕÆúÒÞã­Œí½ôÚwã^‹Ä‚ɃBøÄ¯üÆÏþ¦Å ÿîwOØ6ŸfY*hs£«ž˜†k»ý~GÝLZÍ)¦§*U 3­è]¨lc’j°€…´ʜдý8î&q ¨è‡5¡S9Šàë9ûÑs®98cQ¹[(Á¸f[¡æ]¼42¾{߉…Ã_|ó'ïŸe¦©N>µçÈèØÔgÿñ¿üá‹ß|õûßÀ¼àœF3*_ hOé®ú‡ö`œpðT›ˆ>. ¿@Ê6U—Ðec¢^@ˆ„²{QÒïna"´Ï1<»r¿O-®Ë©”^¡Ê“®í—‡&ÇÝÍ<é‚Î$½-7¨–†¦G¦÷£ï¾ÿ† ©¢9 âãþ8ûÿƒûõ¯}é×—o¾Í¬Ü´ë ~‘ébgš]˜ŒEmè®:€Äâã´| ¡Gç7ì>uzQã‚SeiŸä¹Ô‡qŠ9Õ㤠ªÐmE~˜´ið‘z׫ø… ÏZàdíõ›u¶Òm¥Í“ k¸@9p=ßšŸýä§¿07úà×¾òd7l—JAc=bÏÁE 3éœÀqœI±Á·Íû¤Ó8G¦TJ«9½#g‰rÓÀÆã¤Chn,!Æi¿*œê1C²¸~Y‘ ïaþºAYê­…Ê¡|Tö¹ç¾¸uëê¥ ?֤ђ×Ì6,`iÿfZ¥JáÌcOýîWþÃ7¿þÇßýöYvè9h¶¤™¦= æB–X6~`àÓÊh9)/%¢è5p–˜2é íBm#º.b&Ý,éú#çôÅ<¬A¸³yÇ/ŒÂǹCg³¨»ºx!‹{Ê”˜¥Ú˜ç•»ý4j¯¦ÑW÷§9njyÄe2»÷À¯ýÖ?9yæéo}ã®-7ß;ÿ§´g$¸‰ûÐôq  8‡ü/ ºÔø@ kû”ˆVúzûJ Ç¡ïиA±4!„±¶| €Vœþ˜>ðŠ‹ŠÕ }±:cØN·½R[°Y!‰zÝæ’åû»Ž?»uûZwû.Â(¥T 婌ώL쮯Ü6 þÐSÏþöüóכ˷vÖ_|å‡×ÜZ±iO[æ€¿ÑØ´¤@5×t}ÐÕbpô SIù¢¯ƒ²‡¾6¥_*‹Ãýv´±r5‰¶ Kcçï O¨Mß½þÆþ“›œÛ¿¹±xåï0¨YÀŒyá¶ý!Û­ñní@“SeDkMê­»çä#^sm•GÝñ©éÏÿή,½ÿÊ^|á7Ç/Oüçñ’^gp²ƒàÁ¦= ÏyLËYh%"Òƒ= £‚!Ñç9n1 Ê0’æYÞÙ^…Ë(7×·g¿P©­/]9ºµr¦TGF`p¿×mo­Zn-ë¯ÃñÂД㔢&Iu°kSS_½&û ¥ XòÐé 4ÍÖèè®æKÏ}êÑýàûoþøeË5NèÃÞøñ•·_Fœó¼GkZµá€zSÍb]šóüRÓé?-c¡ÿý P‹v 0VZžG~{“n ò´X-MœšÝ¶:¶K™•Åw~ÒoÞÖžzìs;Æ{ç¿Ý ‹Uè- µ!¹C˜L¡$¦K§r@æ¡áÙÇŸýìÔôè¯}ö‘óÕ?Y»÷öü¾Ý'N>úîùóoþô;~±nÀ,WÆ··Vé&é'½6Ïâbubx|7ø@–Ei‚@Aþ¹¨{êÕ‹ò.‹Z’Ž3%¬ÒìS~8’§±T¬ß¸ãzÅc¾ÐíÖ/¾”§Ðõ¶T©å:ae´W¿+„¥´Iës=A‘jËñÂÃ"îŒízø‰<ùp§¹,¬=þbÜ[M{õ‡ûø^úV³¹…P ÃIÒ“’ÉBÂZÜov[˶Sœ˜;R[hnßé4×Á‘€å.¦ªÚÁ03KÍÍ[9oÓósCB”L>íÆ¢Ö2xúÀʤ4Áešõ›¤”>&ã]ó Q\E“ˆ7íœIå0–Nï}èéÏV ¥™¹]Õ‚»´Kìú½[ï¿óR©ìï;râÆââûÏÊHÛ2¥e”í¹ÁØÄtëK+ë÷…䵉ÝS»d  YZ­¥¹±]ou;±ÞÆ( L¹œçÅé§P¾YÔÉÓŽ^§ÅÚlÔmæt¯±‘éjzJ«fC ³¸^öR@b\-À›ò}½}ðØG¦§&ž|æé;[Û—ß¾ÐÚÜZºöÓÚpåø©s…Êì‹ñu¨Q?@(d’Ķ€KŽOL »Nmyùêâ•7ÛÍuˆë‰™ýµêpF'wþv½ÞïŲHŽcXaŽzê+¶47V·—/ûåÉ¡ñ™í[Iw2­ ¸vÁA™Ó'ã–t”)˜kÕÒZ/Þ=&ñO-pøä£·¯½—ôÓ'žùÜÂÞéÃ~øÝóo_þÅ·ßÿéÃ'ûîv}µ×­ONO•+eà 46V*ÕáÚðt§¿ÃŒ, Ûqßzõ{½–¡ÙçèÌÁ8ŽèÔ"éêÝ(ư?ô9×moÞM£u˵žüôW—®¿{å|žé®Šï²(:gQff -¦iyì;piºÞS‚Ñ{>¦=·ûDX j÷áç¾0F„_*—Gfê+wxÒ/T'yÜêµ–\’ÆL68ºQ´éUšfë×S08¡t+ϳ´×†áÚ/Z2ûAÙö|!TuhtjnæãŸùb·‘¿üÒß6¶Wž}þŸŠ´qñÍNï9øÀ™Fãf?Û¼·t#‰ù“þTšØÝëï½q§ì¼Ñî´[q‡¢œ´­ÔÓÌsh厜U<ƒŽïY®ÍsHB n\ž¥ß^¹¨W¾&½¢2âT´ÆÔJŸ–]Ô~qäèSŸ»üÚ_ó¸‡9bÐ)• «#Ožó\ksµ]¿wÉuŒsO~jfáÄðØ·ß»~õ•]ó»;þƒÿ<Š¢g~ý˽æj¯µz÷Ú;sçö¬ŒÍ¬¯Þ¹þÞÏž$Û«kàh†åð<ÒŒ]~nص½Ÿ@Öz[wyÚ·ƒt+˜æyedÁ-T¶î^Òº@¨Á À?8´ˆTjgÌ6\P ‘ƦÞ{¥¡ÀÆ'÷D1km^/Šû89½k“zlüàÚÊ4é@n'I46·o§Ñ0™(BKð_¼ñÒðø¬µ‘Éõ•N§[ß\»}ÎsŒJž÷Aˆ/çôBêüà'‰<C›·.Ì5èm‡pxz¾µuË Fv6ïAyAÌRÍÃx媯œÓt!.ˆû+´’°À é­ ˜Sµ?ZŒ¤ŠŠgÿÕ³çj5ÖvZ­~'Ù{÷Ö/·×oaøà‡ž>ÿêw[õÍñ©}Årqbf¶YßX¼za§ÕFw IïD’¢ŽðÐð’z÷þäçÿû•·_2ýRÔÜæQübnæÐá]œéÔ£+?ûaÔ^[ÛDPÁ@ •è½€7†~ñ‚h#„˜½[yγ¾éûDÒ£W# >=pχO?¾¹vgk}eï¾ÓõµÙ¹ƒ›×n/ž?óø'vÚÝ»7Ç&‡²4©ÖfÞ»ò‹;×/êÁ91³è°àÀè°†@›&Éôé£_È™è¶6DAb3‘•†Æ CÕ°6Q?´øóF­5­³h«I/AÐ8æ=H‡ºƒáBžõ¦ö?ÒilÆèRß÷“‡Aû'C£“s G:­N¡6·µq=(ø‡N>Â;]ϯ}ü“—.¾²xõõRedf÷ñ±’×hìlÕ;««Ë·¯þˆÈ•íò$FTè O–i wô;W¤ËŠ“5'‘ÈH¸J£L‚˜Q¿VUú=:ƒØÔôÛ1}×wƒ‚Wžèîìd Øa@»6¾5Ðël÷ê·h7¥7$¦ôlÇ Á±ÓÏ‹ ¯¿ü—¹ˆ‡Æg?ý…ß_¼òónÅVœZ8ýÞ;ß__:?:µë3/|um­óÊË»µ¾˜Å›ìUn€£uÉ5XÐaäTOÓê õfRÌî=519þÇ&Aœ¢1>Pã¶BTBëÑö«XØ}ð‡Ÿx:É µÃ[ï_hoo¶›ÛìQÔQÄè›J¿QŽèª w¶—‹¥é~«œu=otnO±Zn5·v¶¶‡ÇöuZ›®çdY;‡¢H´¶–‘DDë –ËhÃi¹ªŒû{.`î”Ò‰ª`þÂþRuøùßú×·®]ºðÚ÷Ðñʶûí»+(qÉzŸó X˜Ùµ–üúöúÑ3ŸŸ=òË_¼¼ÝØÚÚXÙÙ^rü‚íûiÜáý˜úÝÈ,×+Ìz~ˆ98·ûøÆòÕ¨× èØuhva?ÄTskÕ`~md÷ÆúõúæMJ5ÍY-ESý®idvôº—^ìp@\ƒ‘3ºðØJ©Zs]9³gouxîÎâí•Å‹Y–p eÜì´’¯xž=7¿ïðƒ')»~ñMß-ì;øÐþ³ç®]{ûçÿçqÔ*£ýn+ÝiÓ[‡FŠjã#û‡'ç¢Î&8ju—/Ì.yà豑‘âêÝ¥,sv:ìê¥×šÛ×¼¬E•£—†þ$µØ7ïÿȼXkûçôŠÏ@Mû¥àðÙ!e­-Èú¶f¿³•‹l°„Ñ'ªEÇu«µÑ£=g2ïîõ+kK‹•ÚS—‡*—Þø¿íÆzš¦9†»®SydAìGuÛ–äy2¾ûhXª©œŠïÙh~~QYº³ñΛ?©¯Ý2èhL+b:@Ô+ýÁ!Œæúý@]Cº~è$€ß‘1Lü“}zbrjddzñò»+·o5ê÷ú;«tPEïí„ìÒÐtžBúçžû½æÆ½ÖÚÝ[¯ OÌ=ýìêÒuÓ.l®­¬Ý~¢µP*„áýüÆÝEÂ?4ž‹b´1íbu||r?¢¼qïFµÓ¸m*½£ƒã¦ww¶ˆ3g7t«_Ò›Q:¿~PTaÐQ š[ØD^ÁK°UÊLp¥˜ÉŒ ¦ó2í‚ÒïUÑ{צÞ0 ƒ.d:™…”úÿøm°©xœMzKdÉu^¼î#ß•õꪮîypfØ$8C4|iDy¥…)Á°V^°½5ø/x¯ @KÚh¡…¼0dK⊠%Ù¦(A¢4qØCöôÌTWUWUfeæ}ÄCßwâÖ@݅̸'Îù'ÂMÞŒa§ŒÑÚªd]9ÓÆöÍ%þ5Æ(Õ+cð)*ŒJJi¼¢’Ö¿6Uò]J½Òø5Þ•²G~iç‡Cð­Jýí…SúwïO¿ýë_ý?yöW?ú?·7wõô MfËG»­ÿäó_Ü\>}øèñ£³Óú™×›ŸüÅï·w*¦Ð7)L†Ã*C¯RP˜M IL»˜¾S§9ý"vž¬´VšS-Fû¡_kþ¨’ǼN*ª¯àk‹1ÁŽ¿Æ“’ײ¼d^·õT…ûvtøj·ºˆ]ó½ïÿ΃·¾æFËÙô•¿ýÑŸÿüŸ~صëÐï¼Ç”0£Þ…1)tÞTåäàøúÙ?à¡J™à·ˆŸÉã­˜+?8«Ëù[Æi,!ñqLÁØrœTi‹iâJ#VŠuá˜yä÷©,\趾߆cbñïô\¾µº»jj’O¯/>ư'¯¿_ÎŽ?{úãb¼‡u›µ±“ÄH6JáSá•Wý&0°; il…9¤Ð2¤Üx¼„Í·‘<A~XŒ&}¿M!pœÄ7)S(ì—aƒ°m#¹Š˜¼Ñýh4JÝv»z¡]å[ÄÇZƒôóÜë\9ñÍvº|ø½ßøOçÛþî¹Ñþnu#“ÄHˆª9 U')Š×¹› ß÷›Zæ$VÇ40j<ãã»È|`à9|¹ú„[Ïç—ÖTÙwÛÄm²ø8BdŠJ[~%nÃã žâwÈÈéòôúò—ØŒf“¼v”U5pöä{¿ñÕìí?ú½ÿ’LÁ€{d`UÇe*§¢7¸êX73´Éô9™bÃtE>aó—€ôf&àfBǽãüm¹xý†¹!Ç$ùòXš3£Åƒí Õ„X– “ç[ÿn×6þퟅ~#‘Ôœ:wùùÛÿù¿ÿæoÿ×üÙÿàOÿÇ‹g]ÎO‘6:jNŒi>#&£+1bãdksqWò˜Ñc&²^IŸà¥~çÏÛòà[¡»Vq§±­)¼™ ‡á?¥q6Æö䯯.žmWWÈ!"‹vÎÕÕty{õ)~Œý–aGQHœG~ë[¿ùÕ_ùþþçÜ^>÷ݺœ>TD  ŠSÒÃfq2,FCL‹ø² ‘$†()†„é„€3÷cŠ- IB(Suø«,¢´ í­Š½1Žã2Œ&~JR_O– ßíPPEQ£ °“(߬°wJÖ‹÷ !¬ë>¥b|PVûÍæÂ÷0™LŒå¼²2NÂ3¤z{%»ˆ'K*¬_£€¾] Y|ãÿ¨\'I¢ëÅ;IcYd·ñ` „:/l^¾ˆž©%ÓR’‹EBý.\9Ú\žÇÐq&ˆ†­"°T«¹4]#ÛöNßl·æo«™u @G A †(€ðzbv¬b¬#s†€!$@ ŠE@4Céó7³ý¯ùØÄÔ³‘1åÓ˜.wíÆ¦ÝÝæ®á+ôÑûTÁ#«@³Bí#1lQ êÉ~»]ù®aW“¯½wuþI³¹tÕÜU³Ðí¢]âœÕ°¹œoŸ“›ÿ"=Q(áÐåw †.[ge£µ°ªÐ?úæfsMTq,Í…Ø"`N»µD#«ñ¤í¶ - ,ER1Ô«maœC¡pоk‹ª¶VuM³òÕíE·½*Ê©­‰)x¹Ã3'Â…,'©Cb ›ä¡nvJK²©LŒŒ—À]ÂÃÑÅþÙ»«—Ÿàã 1=è›-)¯kB¿Ä[¬Œìaˆ¨ øÆ7‚˜1‘#áë·ß¿[õŸ>ý;@éÞéÃÕçŸ}óvµÚÝ<Å"m9Åê…³º(ËÑÈ/#"Ëßb_ñPÇßv˜@)é!aôðW±èX›®Ë:ªÙãÄIþGBÖ=Ò !߈r¤b"Œo^ùÊêò¼Ý®At`4aô-Ê‘µ•=6¢ª§›ÛÏ5T×F—GGo¬ÛòîåÏ æ'O”*ן»[$Cô6‹3Ê!´ãO·áꌱ9ð¹.´$ˆr¦Z£S–Fw]ï½F½dE”‰iɽ€¬Á¦pG¸;(Ï{pJ )à“² r% „m T2-è—ùiK<õáëo¯›ñÝÕGàˆƒ×ÞE5­?ÿ© MQUÝn%tÄm…c‚H|CßròƒCÁâMÔoŒ†uãCS'U‡æ&´@¶“Œ´P?H{SL2AŹà"§ƒPLLß#SŒGoÎ?NÔq½à¶ Te½À‚öN^÷a²ºøˆXZïu›+ðoJMYרñÐîT–|ø×Rýòa¤¡ûÉKÖæ²ÕE=éê}­çIDϬBwiêrV¤N#˜¸±¥$P.¡'˜êúÝK(gaÙ$,%Ü¥`£ C*—“rtXMSeæÏ´ªˆW^Ð)Ô³3ä-•Gì%±1]W¨èv'¬'^@>ùEêÚ¿FE("mÅÍ6R“§Šýx¾œïŸ-Nž\œvwyjØÞ>«g`/dˆ×w·}s-›.q‡bl˜Gc¾ p7ž?2z‚o1+…ÔÀÊHxÐ¥=xð夨·”%˜\ß;¦K: N†$BÀ|Òй@£Åh¾ÔX|»!hQtï &Ǽ{Ç_n^ÞlÖ—¡¿‹ýÎÔS rd©†Xíûöt–˜’ÐÐT¾ß©T‚ú‹ñ¼k€g…!nx³ÃÇm5‰:k#¾Ýl_>;8ùZÛ7]·1ÖZWôÍS…k³ÎÎöB»m6H)ÀÓPfWÈÉ€QA…“Wž|÷×þýÿÿË?ö³G¿K¾±E9;}s·»ƒ/©ìÔ[Ûo.ûæ¥)jì¬-&©Û'P}³ŽÔ“F$q®ªGà°¦1Õø¹‹Eùö† Þ‹sPk¾}Y/öËéC0)«kÌŠÜÊR5³å!6ms{è5 Šj<¶væ˜ÖÀ&0™>9{¢uùÉÓŸô §4Ÿ˜—åÄÝÓo¯ºõgE=bB1N" oÅNêIª蔈ýª¡ôµS€¡†!/êñòæü©0¬ãôèi$]e—_³õ±øtn$ô#kRÄ?ÎZP¾ƒ´C(窣“×M1;þ²¦„ŒÔæÛ5fByFtjJÑV“}W–»]šK¿{YT3±Ëw¶pÈv‰d”¸jVh/^ áŒÛrë4=x|xü¥O>üënw-XA„Œ]=‡ßò~]LÎ2ÏÂóÁ\"E™hŽóâïD3Õˆ¡±¬ `œ­¡jvw—›&AT£XöÚ!ðYS@óëØÝDzn<”<Ã•Ž´'iö⑊…@JÐâ¸l9qãýdðˆE¿yéw—t‚°`@Ù±+ê¾¹³õ ÛWÎG~„¦Gd|Õ“Å͇j© h亠d€=е¬¡ío€hõ|ž` \Óm Üz!)‘H°‘õ»’ü YP!°ˆ¤iF’T“pV“ýFØi֓ȃ‡/GÄ=ÍâEP­¦>uš{&y%:rJÑàŒÓ€ÿ´ÏI¦Á+¡uàRÄ6W™¯±«#Ùv±[‹%¢!•Äߨô„¶àÝ@£­°Xv²bH€ç“WBBåhŠ\_|„ŸP€ÈvS2ªzÐãÔö¤Æ(½ªºÜ 4Y°¹wÄŠIá{ø( k‘œ@ ~Ä7XWe'‡Ï~w#QòR­Y8Q))3-ìÚ;™¾¤¤±¹‡Àº¶5D’.Ø7Ž&³íÝ…½&B/ì1b,Ñn)ú0Ä…£hÚHs ܱ»¢žÄ(Nž"í¬²Ô ; ï.ökîÔàD„ÙYZÂî¤CÒé{Á<,ïŒ"þKË·!‘ªñlwû©«Ï¸`lšu äqòY!]@"p¢Qf÷³§$*‹1¤`2uŒó@ÜLi%)fÐqV“Š i‡BððDaHeÔ 3tf¬Ø±–9ÏÙÀÈ—\5;{FÀ'¨la±Ñ2;|ÖÕÇÒ3ÀàšÂˆæGzö¼ëŠvÜñè äSð²#U\1Ùmo{˜kØ7鉊×K*g$ņä˜Èza~¶Dç¦d*Ž›õE{-ÊN²±}‰#¾‘òI„ÖbŠÀk@Ëj~FÞ-*[ÀVÖ”†ÓEí&Év}Ûl®3š–Óe×µ~»ÒLuèGá$¼™…“vÝÈ*ø¸,i&áh~´[]ÐVÜ K)Ï ù%ù¼4#ä—ˆX)AëÁQdl%ÀO:9Öïn—g_-¨æKÔx —À šʪ@‘l6»Ëçu»T.$r¦Çü±B[°+MÍ6@–aqhLKù £!DÀdÁPwi>d¸zRC³g°*Ùm! \Móãý#Èxq´|µ/w«+Ëì2Ÿ|§,*M˜ÞÞ&{u5}nƒ²«»»ë‹ç˜?ÁÜ„'*µ†Q±'Ý ;ÄœÍ9Õ%c¡Ð `´Ø|/.Âë’ýâê†ÉKÇ€íwI3°°?â4’vý˜Rn(l“å丨 ›ûö*"')Õw6ì Oª:ûJ”Çœµä);ªåxÚlïÜhÒo7†Ð{ߤ2¼S1IyŠoÈM€ s³rÒA¡c‹}¨¯Ð¯¨m˜ü&g»Tº’>”|\UaË9fD¼‚J³˜ÒŽËñqQNK>µÀ P‰ß¾T°KÕ<'€¡ÅL÷ÛO£nw ¥4ž.®^áÑ9°?¤«„(—Õ)0[2)Øæ#`²vÀjäç†ýÀ¡o†¾”¾Ì,vÙ2¢võk‚JO^ïl/ÀHŸK,3i’‡³ØBi«LôÌþ)JTÊ ² ž/‘ÊÇÍŧÒ-Q-–Ìl¦ …ðq< ‚ìÄcè.5ò0ls›‹Õ!X-‡ËÔÊzèaÒ¹‹·ðs¤ ©4 éèñÀ¦yc[Ørƒ<“­3ìs"åîúyè7ïÿ¿AN>|ûÉ_ýàü—ÿ{¶ !º¾ôä½w¾û[Ÿ_ýôÇ?\_} XrUMoÎäg矧l~M”àU¶6~(R‘÷‚‹•œž+áâ~ ýÅI A£áY[¡Êc‚Øj²¯4<㑇ôÕ[ A‹%ôð_¨ßéÑ×÷>yðø >õðÑ—Á™Wç¿|ôæÛ?úßøø÷à ÿþ/ÿ¤Û­i¬°}Ø€¾ÏGIì¥>ïTì²ë׃òÏ…Ƨ€ù…ÒœP•Húlü²`ÌùÁCWÖ/~ñ¡.i°ÍãccæJÕÊiº Þpp²æç߬úÝÝäø}ò,†ÃU05÷®œ@ã}úó¿ï¶Pn 9n`1åC¨(˜òü›Å9-‰±‘𯰒ãiTÊv@Ѽ3ù Kµ™”ðxlDG­™qQnS8# Ÿ=%í¸VEåÂöº]_ÖßÖrOkØ]€Áì¶kˆ T“Ü& üQ7BJ!GQPL‰]1a ä&98”˲B/ìQ¨ $`J)¡Îa‘¬ôb´ÄõlzëäÅcCIÁ;@ àÉ«HA7:Ö@9øÐv vV!ÔßTÃɵT¶Ë©¨½²iŠì¼¹ÔË ˜ QJƒÁ‡ÂL~%½‘>s Î=/ÃãH((ž™Òè”<˜ð(Bhèf߸z–i¨]_àåjr.0åœ×È ¬~Óï^²®ÊÊ @GR}ðnV Zz#<ƒ&ƒØ$"'YáˆH©MªO)oºô”ÝK–@N‰<¥$Z׎Äj¢:O @álÖE”¸3ñƒî.Æ{Æ€@ãà‰ÊjúÀ–ÓÞoÀ@Œß×\(rn“(ωn®š}E q%DÝ…¥ø¢Üçɾ6+­6^Š8¨*7¡»Ö1Ûê|¸–¨+$—›ÞzèÌðX„'kÙ4Þ÷Q´@%&ë+V³PgÁÉo‘NÝæ:¼œì£Ö' 2l#á•Aý’4U(Ç3ZŒ®ÁbŦ þ€ƒÜb“5ê\ ï)o‡~‚ôæøŸ+¥ó@y¡ó!>U‘g+²ßÞ»•ô……”3ó‘xü^Ji"åÓ(é–(9F”ÂdØU)g®‡b‰ýèè;ä ëŽ^{Uõ‹òí&ßs‘ïEß_¢Ê ì¦dNÈÊ_Ô£›8"àЄ”rÂË®LG¢¦Ýæå~ê¹ÉìdVË!¹TùUNf-›>ŒŸ‘ kBÕx‰7© tŽÞc«Êjhï±D¹”ðhšŒØº| k¥íäœÀ‡%w¢ä‹} Z׊“O÷=BÊ»–&ôñï å(M®KUÓ}èÞ¾ÙhJ§H§L¯PÖ“£]ß¶\\j°ÝŒA‹íSÔõƒo+iì 1”»AÂA)÷ðl# "¨\=buC~4— £I³4e?%t„ü$†ómŒ¤¢´¸_›{³oî™wØO6Ó&s¤=l, ÁU°0†ü®ÜòôË{Ë×Ï?þEÁ ž`=›M”™LN¾G·Ba™/ðJV™ü¢rÌ,F—A.Ó줵·‰óÏE3*Kïh²Œ´‚¦k Aæ5‘I_è=( ~Õ§()·¼5XŽÁzªó’m© ʲLSÌl6}yþ‰-f0_£Ã÷‡ËZ”ÞÆ­Ä* JgL²‰Ý0CsxJ¾©%Ù\>ƒË@‘‘ŠŽ Ïäƒ<–Ú¤A Ý; AE QæÐœ4Öùý³¯4j˜26t;i••œ7r›ºÛ·(ƒéá«ãÅ£zÿ[â'†a /ì"–ÙÙÑFqñIú¼_Ä‹R“PžÀó|Ê ¥,¡å&#¡TÜ2-3Š—!¡4tðGú'Òµ¦˜€¶‰©¿,ê¹u³ÀÓ[ Âû`PDÊæyÛ²æ*RÍSMŽêãï¨às)¥xŸ *RßÃg†õ÷7A’\€!JÈ1hÇs=àƒ©”4ýr³%÷ß †~¡ñìÿ„ûøg–Ïdî´šŸ¦Ý9&^”4PýþÑAöP.«®¬+¬gsýÅ(¸ïÙ‡>xW£y÷å Y«‡V†Íþî_Ý¢Ì=È)K&å9È5¢!-ß:€Ç`pB™—Ë€¶1ÞÆF ßÝpaLåâ õ½ Ô*Çø|Òž~«ªB ÅåÊjamx[U-œ]=ÿgPùÞ÷mS.¿>ô”òùTºoiçÛ9޲#)»'ñh©ê·ÐßÊý7Þ„%q낉ăò(ò2Þ·6Q¾k/7ýÒÀv>èû‡Kk,=>°OQúä¶ñ·ݨ+»ö¥o/gaâöß•¶vEœè¡‡“}ò©«=JnÖI{xç)«Ä³w]I¹¹|ã—‡íi—cÝ7·R,ñ¾I«î±BéÊ’hÍNÓ˜üÛ² c_¬Hµ¨óU6ì©jÌ?ßÑbH •¡fȡȲ²Ðé«  yç‘G׉MQÃÓÔ/Ë™—£8yP‡ Zn)|<õƒÿWÝ6#{x6!ûc Töp …('kH¡ûý±¶¥Kíªå;‚‘q¸]Fµíeä p'íÛ’U‰Ú "_ƒY´ÂM):øäö¾èpÞ—«à©ï›•ò¦|‰%wëräÙí/æÚL¡Iøþ$7%œâð¦°Iô[¾RUd·áŠªX¼=ÝÉ•™s‰žoËÈSxÄ/šÙËó” mã^Ûå;¨ÃÆÉ ­…”*°â@“Í­\› ÷È çw*W•¼fÐgá$ì. Þç‹nþަÚÑÂ,Ô"¢W‚º?d.¹Üó½¨#n¯¼R«H żË´¢hÄ0LÞbWû]Ï# ?Ü3Lù&¹´Ñ‘pnfŠƒ¤G*\Å5y€Œ8ï ÉU$쉥XµA¤bþ/Ý2Ð(€¨/¾ˆ˜ (1[42=B@C@D0nE0®S.¼â‚°‚ ¤‚ «ªª?»ƒ=îø|HHLüYÊ­Ól¶¶q“±R)LFá "Ë"m%C"›Z'Ñ'÷/ˆ”Š.ðj£ 6áZÛòùæÓ#%W&´­!ø+ws3ÌG–]Cs†‚–8§îÁ_Þòú£õ2BjQ°p‘Ž1±üÓiù¬G:¡ar‰ik³šÊ"æ¶@$nB^aÈtk¡‘‚© »úÐÕíÇ À)¦Dyh䳘ÐEòOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB ÀÌ/¬´¼Ä(1[82”=B@C@D E ÒS2¼æ‚´‚ ¨‚ «ªª?»ƒ=òHHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB xœ]ZiŒeWq®:ç®ï½~¯÷î™ÏL{<‹=Þˆmlva`I %R„"å?P~%R¤ˆ$H)ù•H‘ R”ü@BÈ„˜$"`lŒ‰m–a¼ÛãÙ×^ßzï=§RUçÞ7Czº{úÝwß¹çÔ©úêûªNeˆ¿=ÿü…áRý…õ œ^DD¢p4$/ ’£úBþ ¿ËWøf})¿øx¹Ñbºì«¹jcŠæ±Ø…ö!\ü`Ê7“‰Ëæ¡VFãG¢Œ#1V_gÞWú®þÜ0ÿ°–é´Q'¦W‘_/K62“|Ê>TW€\}£Lœo3†$¿ŽS?ƒG0‘S_x<ˆ5-gaùah/[…r]ªNCLäyÑ<2ßÉC© i¢6‘“;e\™Ïu#× À©U›¥Õ6¹Èƒ,µï03÷Ñîó0ü%[ü@×¥Ïõ~:"ß ÌïðÒø&0½wuѶMvØ/½lÁ$a«‚ åOL§Ä;‚‰Ín!w•ühê3aÖüI~„û¾Ô,MCÞ)`¾Û·RÔÂÑ×Ý®\×1ÈO·¦ƒ;ê ež¥‰ç¡}7,¿L[\’*âmUÓ3²"Tƒ±‘n¬+¨4ÎßLÌšh†\ Ñõëâ»êxÊŒ,4¿Í$kn÷'²¹l ?N£>/±PûZ™0Óé2x¤hÙ´R6Çû­[(ÚÃÿÆGÄÖ6‰ºPxtØx}¶,ž?©0c]>57×”1å“ò›À.ÐèeÙ2ž?8Ý kùœWcQ‡°&õ!¶@2G”€-³ï³d» Ïåq{ Hgìd+ù¥ ~ïõÓ‘¸!O•¦ÐŒ•ÊÒX]hêömNqÕÔ•P5x9ò?xqÁ%pâ´M 4¨]РibŠ—;cò=йæîf«‚,<Ÿa“Y/È&vvaÇBÉ3Ù6mœ'lAØ,þ•ÈTü¨†P*Õ·Q£ë¥EË/Rq ©KÖÐ`ÔÎÞ 6ørdñ»1Pf‚6Åx‰L>í5]'-’èaAv¾_æçÙ( >¤îÁ‰I½Áu+YÝ;/å›Å¼F.òû]ð…®J7Ôä:1~àDg¬˜/~&ëUôæ›JïjHcÌQÔÏ~J­C°çóÄ agã]³]!úþå}Â,Ôü·SÿWƒëȺ ØøµÇë¹ÀÔ,°Ô!*Ð  |€‰4kñE§‹LÍ×9BÄHz”¥Ù(¬QÃÁ¶)?Ž3÷Co‰7}_0 hD±z“ñÇÄb’ׂÿËøSï )B #_O[MØN5S4Ð*fáËÅ»|)»eâ$ü•’+%}!Þc8x˜˜¼#LÌM$;•ï“  Æ4>ÀƒÀ‚°µš°xu5-]Û$X›ê$‹ lN§@;ìO¸ÍêPl.NÂ󰹉-/±¯(ß<>ªýAPD{Nâcð§üÌÞù ‰+†Ñ­ ™Ü­°À@$Sô‚ùòÄ‚#šs´|–ß­vá×¾¦Y˜Ÿ®fzÁ@H(G PùjÀöQCõ8¾Y»„GÙJd[cŒ«4æß ½÷›(áÍ3ñŠ$YùVn%97Vc:VÂP. E”[ÛR”ó¿>ÿ&‚18a âí^it|ã?lLv~d3jĔ͜§T*2ÖO”ˆõüSrH$Ó½£yŠpñ}lJI‚ ÙC…e™¡Iô£ÉW¶['’°Ñ¦É®[,¬!A%.‡55ËG‘ñf³#¾w/¶öKÊu™Ü)Ũ$D)SÄáE5òqì2¾m'wÝŽbFÕ¨’)mn@&‚’ÚÇd€:ñyÙço@Û€íp±5õ•UËØê¦’¼’™}%tiþ!È@ä°Æ«ðÙ€ $ N.ΰÆK|ÎlÐÇË¿C[ß ¶&7ѤXÇ‚>ç†ùc"â 4 ¸"dÃ-›ð™®!ø`Í¡5@jÔÒÈ‘­ña1ìœØ½×/~„Ò91©u>-M÷ì[út'F‚H©ic[ËÜÒÛÙ‡arÒ˜#RjÍR¦sQØŠZdÚ¾Ú¨CSݦ“ׄ|ëÍR†.–T¾B.,U‰³iè.‡˜ì&¿ò{К3ňZ+Ä^±ÂNàÊ. ò‘àY¶¹cŸSh•§Äë_2åËñäÅÑÖ«ÊýÎO°ö ©.e‰¯sVºT]ÓÉ ŠÅIZއŠ.ÊCÙÑoXˆn„Uøuµr…K2¬iYã̾?®’Uœ…ù#è#õ4l²-Ô¤Kp)V³ðì2ÁMtðK¸ñŸ†.—£«Ê{—ªHQkN@ôFF¡¨U‹A¬ƒ¦ŽãÀ”L öÕâ™Á-A¦£è;2Ï™Š>ÓU7|†'ŒÛä™ó¶rÔ ÏžæëJ™,ÛÈJõ†q¯ÿœ¢4®ÞõéK3˜äP\ÂhEL뮿é[GE¡t{¡p¬ž"±´©¼ÀXQ¼TýÂP_)¨FšG¨†GËú’c_˨K©Ä¸Û‰— ,ë æœ³ËÕ¶;ó†ßâ0ë¾Õ»m·sB\QsDbÑA4Ìîb0 ­çµLºêÇgm¾+Ÿ€tÁl=CóïâaÙqû%Hç£8NMUlK+ˆÈ¾ùm½e©Url!ÿ‚Ù‘¦ÈP–û8^Dåäªßþ‘ß> qÇ$lÉÓ%G›;¿ùS0mìñ[O!‹ 5-8sÞfR$•=·¼Oíê£n÷¤Mœ¿ö?Œ–vߣ´ó,š9ØûqMvœkY)½Jy„,ËFM„ž!©%‰˜¿EEBR¦éO8V§m(è$G¿"|Œ¯2«Øy­¼øMð[ÊoSlß‹ï¦k?„ɳƒ0w{ì^«6žô£M†u¤‚–d#—ÁM’Ö|1b¤J.ØîmnûyŒ×¨¼åy;sìA<ðˆœ†8ñÉÀ6G¢%¦Ë¤â¢¹ò$ìû¨Ã®øŒ”8"˜fð·”öõ•—’Ôx9û+&!œàØÂÕåoºèv^¶ÎïE³Ðº&—%–f޳uÜÕÇ9ìüû}q…¿¨Y›šν~rJTqÜ®ÆÛäv0;@nd;k”¥ç¨ÿ²»ß,¿×oýÜ.=èú¯õq¼é‹‰iísÎãø9†&3ÙÅΪ‹íÌmž1K÷Q_€$EÞ N˜‘Ñ—T-=„‹4fDЂáÉêì¿(•ç4A¼ŒŒ¢ö&(NCµehËUL-¬]úg:Øùi#a„qav³Ež ªòÝwÂøU©E0äŽÎF³ïrÉš-^+¯<&˜íe¦ÑyöÛdö˜_ø m<닜¼Á«Óâˆ3­C4a>é ™·mÒýæ–/@¾0å‡RŽ`·— nCvÌîû´lûáî¯àêSyìŠèÁâR4sw6Õ«¸û¿Ìš¡`ᡪ¸ Û?‘L*I\H²‰çHÒ:WD³ÇÝö¯¾Xåi¹Š£æNˆçàÚ÷$S”[`gpå·ÁéÂã¸ø~fqÕ¥ï¡wäv…­röɘî²XÆx¯]ù í¹_ Œ&ôZ 4 áÀäT‹Ø¶«Ÿ„Þ½ÆÝæ“О&ç=ä¦uŒÆ¯d½9/Q\ƸÑ‹ ¨/Ðð Õ/! •°Qm«*by/|·ˆï7 ë³Qg¹bØáôC“ìµÇÿ¢zåkÐÑ×¥0‡AÙ1dr"ãµ<Ó¶vºÿónþÉ ²c½9EÁLÑeb^Q~È®}ÖsÚ:óP^{JÂÈ^›À¼3Ý[ý΋Èî:d²½ê$h¦zcwáæþöy_ kÑ.P‹–%Ã@õW©íŠÔöîp£ l(íÑTí¹vëƒ[_n_–­Ë!Y0½Ûpïç8ù@Å j…ar*c_à¬aR±­mE{~—ºwÑöÓì?~r @!J‹¶¨¥`^ûŠw¥ÚGÌZ! áÙUWZ¯énŒŠcƹ|H÷Ä o÷›?vÅp@…:LS3–:Eœ 5â§P)´Jèö2®~€*koþ‰®g.‘ò!Å&Ô¥ùsñŒiÝL“«Pm*ú‰è zˆ^ul¬E`Fìˆ{hÚjý ³Å’ÂTVWQ´ àEƒsâÌöKvŽ2ï†Åͼ뢩oªZ™æ„ÅÝ£næívõæQ`ç$ÜÌ„%˜:^l¥þ uy°®Ø¶MåœÔYÅzAW&̱MStkï¥SÃŒÂt=ˆ'ÖôtêPŽ¢ ^gS-ƒMTn‹ª\°ÖªKm2‹ó¿iÖÞÑ"FœdÙ ¦l¦ŠÁŒ¤²ÍTDëÏaja.åy-î©å™Uj7Á¨\1Ú¶ÆÖäT¦1õeÆøI] ó÷×kº‰š¯¢k¦éŒMI»9ªý4YEvñ]Ø:iÏ®¼OµR,r@¸t¸:5þGM©C¢.·j©D³vDUѸFµ¨Ù§c…‚‚ 4Õ¤À0¦³\Ú¾Rp¨5¾†šú,kˆ8N0›-Ó¾³5—ÏÚÖ ìü‚³|øsš¾­áÿ¿¡Z;õ>õÙÐé1"à†€’íJ´CÝ ðZVWTA1 Pd¯ ÔA#×ãúºÅ u7£évÉO’÷ŠqŸý0ŸYJŒ{~|YçâlÒí¶úq»ï=H† ‘{P‡ŸÆ©:i(újé@Ÿ¢²Ad$í– ªRa_Kj*axú hÚœ4µ³Êᄅ±4n˜vÝô2M»ÇMKÔáí°û¦Ä!‘À# dÄÃÄb•­ý–[ÿ$Bó-Û¿®U“Ñz®²=/ ÐÐt«kÏ’PGå¨/íñÿB{4¡Ë"“¬¸ñéiù—pÚû…iͪ™ð(e rM¥Ä´DS7Y­`)g¹’¨*N¸ñÞ‡àИBÓ9&¡÷Ëî2æ[­ÙL›Sd 6¬£ŽL ö ™K ³"ŽªmÅÚ”×£ k™Fu}¾ÞsmÁÈDMs'”§¥ðzÂ\Ê M…ºçÃöð§|3ŽBUÓOƒ x{¨³lêèußäëZ¶Ji {-d»½â¯=ÃÚݦsá舃ë“Ò"–VyÃᇦ• )™«„ÅN+wJåC•B!ËØüÀ§`éÔÙïÝ$¶IÝ=!u=¬ëFü"쫬ˆ“‰«xƒŒsu†UR`ÒÅ\eÁæýðe9¿á ÙÒ/µ-sUátMÌô,8”‰RÏr˜¦=…¶ë˜¦q#ØÍË È–ã»ÿŽrvûž;óÝHû×á(Õ´§¤Ùx-\‡Ú½wÌt56I €­{½a1;€jÓïü XÉÎÇÊ’tª&Õù‡nJ`˜™¦í¢¼Hu…´ ‘3©½gíX}Øìÿ1(Ìx+–rº©»käëz·4˜+T&€§l»ç¯š HÿŒõ—Õ žø_ò%È×iöž¥AéÝîϤOÄ[±ÞÄ}Õî)ô}9Þ@c!Æñß$çL¤^gë¦íÆë²¤öš4:øIQÚŽïǃ ­9„8 Ëadc˜žêÐepËb¥‘2[ m+žª”Î$¶5ÿŠd%Yh:³î?Fi‹Þ|ÌÎw.Š;{½¿â.>áÇ— ugd6ËíÄ-¥c¥]-v-ù¦fÞá\R ¬š#©ÚJƒU Í o~zÓÇñÈŸ¨·(búã?ÖÁ6—v<ßÊì #’­sU©\.®d ްi;=ÁÀù°Yy@Þ/*Œ=c“LÜ•Ø9Xžùvrô‹å+_eAÑÇ3ڞǕä˜ÌYv¡rC'wÌ7¨tn‡u›Ù›–w•B~3ŽúPAÄüZ÷HíÎV&I%§ÎlÞöy»ÌRʽù#»xVîƒ3›ÁË4s7Ǹÿ ¿õ Ø}±˜lE¾úÆËîõÂÙÌáß7’óK¤6±òu}¸ò,Æùèõï'Ù² I܃₉ژ­"KT7ö¬‚=O©í¥‘F ßyÀ´öøÍŸ¸ÉY¬ycH§±ô´Òìýxø™e!19*ޱì@ÿ·ý&?;«tm{’LÎ& /@ÿ4ëV6ª3ËxùÛ0‰aþ˜¿üCÚzÅ.¾Õ.ÜŽq›²)ßJ ¬-Æš\?û—ñüa°K ?±uÈrÜ|ÊÚÒÇ=ë'n¼eò}”â©y¿E>6Õë´{ŠÒ5ˆ˜Í^"–±štò«Ý™ãŒ…¯ëÝ-&=_*BÏ´•2ûºT•ÖGUœ–RÛ§‘7 ѳZOˆa÷¥¨»Zše2i*Õã ×Z@ßIÏHê3‚E8Ù,Þøfqþ;&žëÞñ5ï.Ãð´É׋Ë1¢ÆQÎ~BíÛ)Y(.ýLÎQ9 iÿ—`;ZVäeiz×H™]±1yóû†ý|­u×—iû»x¯¿ü[mT“ (úQï(¤°{{qî_ýÎ 2KÈécx*êÝE3w°‚§'pøº°^• bYgyà–ÍžGìÜ:ÅJ-/J)PhYkÅ’ë"†w&Ãc9€9ÉÒ<Ëlm‰J­C[:]ÃiÚN¤&®Czd¹Vš\£êrué¿{¢óÀ78ÌöIÜ9içîqé+ÝÞíêÚI­“-.GµÜÖ/më éÝ_°ó<¸-‘ê’ŽMÖžoÏíÝØ¤ä¶/R2f$ÕcËk©u3Æ^¿D³J«T„i‡[O7‰œ”e3h"ƒ·a˜Wòb t]2c/kIh2†23ãF/ýsçm_7Óð$ÏÂÄ*+Ì–ÊÍç6Ïì—»oêNûÉE=¬•ëV’R}¯RÅvºóQï`ØÆÖª9ð¨1;9~iÙ®â9r£×,i•ÚxË©4—4LŒu’&µ¦l”ógRS•\IZƒÊ¹L•ÐåßÅöðåoÐÎÕîÛþYëñW.xë†83Ç 9~áïmq™©ƒÒ-e¼ŒÉœéÝ o«.| ú/([”6F–Ì´f—¶¶&ÙúgÝòlC/‡ß´cE©œuÐIiKÅj(ñ§ØOd]RM²…v'R1¿1AÎÕ½nV‰Qá!¶Œ‡bé„VÏŒ~ù­táÐì;¾N¼Y–ÄP^N‰xÎÑW_óW¿ã¶Nœ‹«¼œIà-wQïtïó¼¢íŸSÿÍz4ŽÃ$ÏÚKƒq sïŽHŽÚÔÒÀc[k DO½ñ8‰—ŠÇ˜ŸÅ^$Éq!´L¤GR¤ÉË9S„T:eRÁBÆÙÄ Îáä*嫾ž†çÝΩÿüÌj xœEZY°eUy^ÓÎpûÞÛÝ·oOô@ ZÁDcª¨HYÑ()£æÁ_¬Êƒ&¾˜±¬ÊPB4•2K-1Q0tì8Û‚(ÐÚØ4ÐsÓ4}o÷Î=çì½×Zù¿oíKpàœ}Ï^{­øþïÿþ½õŸ•5:…¢Ò&­åßQE­ä+þk‚ Záº\ rUiÍ»2þF¾˜¨kä—òA.XÞ•²J7òw£6–7Ê_]Œ^ÉW¹(‹ÇˆÕ —‘h«±ŠÁM&ÈåsÈðY-b[rÉp«²ŽÊ®Wð'笌հíô/•Ž£°7•q g&Ý¡lÀ'üШLέ²^nrQ{Yûí ÉñŒöª1r];­ìU~/›6Êñ >ã.KëÊú1À¨x¿‰-\~íƒxž

cx\žŽµÓ±ÆCåvìÇZñLlòë¤íÏ•“at¾Wt„æÿ·–”/?×…†ñd÷1dNÌÎý§ˆ[ƒ›1ÉÑ|†Ø[ï°²øˆ—à{ÙJó(¿Ê6åÎ&üÀkU+SHÔ$ûåók¾ˆ5Õøšš–rçj5dð5¦@€_¬Äü‰ Náôbw+WI0žƒn+ÿf‚±Xà“ Å_Cà¥Jœ\‡–—5£GBrË>½J¿dù`x¬ïˆpbÊ Då0Þ€!¬ah‚Ä6wΆ…%¿â1‹Ü&ެ±Œ€¼c 4¨/°rcFóÈu_ÜôÕ˜¶#·™@”(Ð6²b.(ÊšÇ<ä‰ `¼ž<*á­-,PòP3 -6ˆ"y6æS”’Šô‚ÿ"Åð‡{À Xµ™X +º¢sÿÌ\¤ëä¥F‡n„³eÑ›§µNÆš³!˜Ý‰R1ÍHæUžaŒË™’«vÅé"r$!HÞ%nXé¸mEÚ¤B'š’ª áN—Ú'æ{¾"0•m! ½-ž^âP¡^ãϹP-á#—°Éo|(Â2Èß aÔ’M° Ä&À6Ì+] Fº:)a¹PQlN.dY·2½J¼É,ÀŸîÖˆs¬†¶ÐH)q Ù¢®¬)#ÖDihk.Ñ MÉpÅ2 »db±U©:øåÑñ}½o—ä,o{u“{`ÓŸJ‡|³Ë÷Ú7°Ô؉œ'«ØÐÃgj{MT‘Gä†^Q€’Í*­º(XbNÇšêÛ>”ÿí”ý'üGSç²Õ‚„Ê xbn @Êêøw‹×zo;·> «À)¤:‚Ee—µ¦OÊÈÆ*œ [³²w$œàF[2 lè·ÈA0PÅ.Ck¦– N3èœúHC”JíX¢(‰ËzYRT¢FQjŠlÃ6 àé®%Ò©Ž*‰ó‚]óBÕ:–¨ÈˆQ“ ®‰%^©°RÝà ›ˆ "ËÖu• uÁÍ$F¨“ÔZPT§Û-E Ρ֩åf‰§Ú¡Zðåf\Ÿ?ªV^ªÎü¼^9c›PÞþ${±S× ¨#A1 û“a5‹Ì޹D"›BK=*¡L²"ƒ¿lg S³Bô#yjIò |5DYmRßš,””(x¯qÐ4¦šùg—~ûES-„ñb̦:w|›ŒG§Ê¥S&}Ù>¶”Â@i’øFn?ä PÞ’K£°ºÔÉ'.¨V[ $exèG°9ósU ›fW»fÝZ¾íÚ Êî~ðãቨ7öU>$ëÜþß)‡@¥P¢ÐS“ˆš4ñI„“JœIBGª#ŠbdÐˇJT·ûQlÆ f_’¬{ð€õDËÓÀé t $WäyÙjëŸN.Oì*½ÝÔøèé©]n|jðêÞÜFÙ?…)O1&I6Diµb81‰bÚŒ<:Kä¹ ÔB""ùŸc¹Š-»‚¿:p¥ pNhU+˔т>Y6µ”œ{&×+KGöiŸ»™kü¹Ÿtî|’ÙaÚú‹g6t]1B,i™Q®ñ$‰5N xˆ¬þRá|c›Ë€iû&ð>³o9§$©„(lSú´‚< kêy’øUÛq¯^I¼[nñbš ¿Z}Þ˜º˜ØX¹~oÝ¥·ï™4)\Ñ2$47°À;Gåä™c´T©y‘§#ŠjR>¹¥¢î¤ÙγþRÙ"=sÄùa[˜ÌDÎn*8EÈ-Ë!¥Ûî[µ¤› NƒíˆñT3 ÍrýúþºÛj±{ç^‚ST­guj•îI­ Ø6 A@ŠŽÙ‚²±ý“n"îU~37ìú uÖÛ°Ö©‘C³¾ .g¿ÝÐËÊ„tñÔTXÅ’~“t0È L«–ÚáǧWNþ¸\³uüÚþòßGóƒVR·Ð&( _†¬‰@šÐ Y—ÔSrp·n’¡`&TŒ‰Rh²/EXð,ÐMÕ½ëûH=XRVR¦–=6&NPƒrL¡šò}é\ÄvàèB3ëRÜÎ(‘ŸáàT4˜¬’€GçŠ9l‚zÄH\- + ÷[አo%þ„V­ 7ÈÊsû?Û»û‡ ±f$äT~ê$&C;EAqíü/?ºRôíÀ¹œê%Wð(† Ž®é-mŽ" a3íGSÄڌý ÒÔªÒA‘€.Áñ£Ú¯ ^ø|9¹©÷ÎýÒÔ›0@îØuèÂŒ`”Pw4XPÌ.‘I¥Q =eUà,'J:‚ÌI«Ie\‚ÄqN&—&4Ƀ,y >ˆÕˆñœFïI)Þ$6¢[Ž¡tj¾VQH~VKËÀûò¥Cß\>ò-µrHêßý½pöi㫸f§žØÉ ,N-£'VdÑâ˜1Ë@é1Á8ÆÒ5æzÉ8ŠáS!Ò àIÅ¥ÖI)ÍT¢Å0rޝ”Ô ýØ^Ù›S±l‹éA– ’•q5^Zyé±8÷Rµ| ÏãüÏüü1·ëýЊᶆBÚn=lj‚4 (*RJÝH›É  |,û1˜BÊ1/-eI-u :f¨¨ÁäÆûa–%ÑÌ›±§vˆ”ç´¥"ZMª!Á –¨^Y<ð¥rÃ-YwCž¯tïù¡š{>,²›ßfº;ÐÅøá iK¦“4-Á3N0¡xákbfAS"³ñª˜Ï9ì¦=Û \é#ë¢ó¦B5ª(Ë|’ ÈD±4N3«…CZ§‘4¡ÐÃ-ŸxÖô7º‰m½»¾£Nï Žè5»ÝÖwÅ|Jé®2CÙ=UÙhB¸šàŒH…ʘ¤@ð1¨}9{‡ÄVÄ L¨[%öF~Ž@g°ÚXö»ÀíÅ15F·âO;†Þ"T[ÆKó¿úÒô5’¢ß¿ó‰æÄ£fé˜Ûy_Ìz±³C¥ªôà `‘)<Â@àq%T;¢àÈú@]Ò…¸–RWqÌ’±b½cPP¶Ls ›CbPèUå?¥4«l[â ¢ *–Pð§~Úy˧\>1:¹ÏM^fêsnÛ}qÍ[ ù·o<È–$J3piPÝܸ*!2+Õx Æ6½N-¹d”O'¤Eâ* T%uõ¤óèÐŽ‚Bâð•t„òM–«mê>Ø@à‡5¦;RÇbÔXZÏùŸüS¾é½ˆÐpA6ÐŒçóíïÓ›?¨Ü"ô>ë8¸1[’ˆ!x—l c‡P߆£Jc5•~Ì*ŠÚêXÔjâPh[¼”¿qµµ³DßH!”éô¦JO„0¡¡óµtª»ë]ÃáÉÉÛŸ}Z;ý¢™½GN×w;þHõ6±‘×­`‘˜W"\Ø$PNäu W”` „”^¬4aÒ`bŽe*×BWÄᜠL[A4ðR’†œÆ2 C†—Ð8` %Ñ¥wRmÃ1¬ä¬Ä§ðá9ɧ•Å—c3Ìf~×4KBB2)>›ÿP­»Öƾ)2±p¤‚jŽP!ÇIÕK@ l‰5Ë­R4Eèœ +u—*•Ôå{SCc:ˆŒ þìˆý-…÷˜¤ÝX²2Œ ´¶/‚c dÒëM Ô¶o>H–ÈA~Û/¼Ò¿åßÃhÁ¿öHÞÌ5n½ÛùP ÜìãÖ*+¦ëÄØ³ÇIÚŸžVËdX®i¦)Å(Œ‰ö—½ÍU3Pó¿²³·IïlÀ *¯:H¢ñá,Úp·bt@=çFÜ4‡…@ ÆUÀ7OHZE±Yz\3Ý{ç“þüÉxôgsö‰]õòéΕµk.ñnšµ#P¸F·ÚBR^ùxÐ3k=ÞCh ò tA̼:ñƒÁ¯¿0û®ó 1¶€8 ja”Yk¸É7˜[­ØzhŠI¾@#·(?)oÄLÈ=Μ”‰K9WcúaU]8ÖÙx©žì]ý§ÌàEµðËO³FO]  j–ó÷ê‰mQwˆƒ'ÓXÈ.u¯†o²iN¨É—Pnm©íÀÏ\9ð@yÉýÙ–=Ò“BþÁøC z`m:®—æ}àŸ­Ï¼Ô»òê)U¥‘‘OÎðkL¯‚T| ÏòÅ.¡âhÕêjþäŸèîþs³öJþ‡Íñ}R¼ÑÞLßbg®~‘Ͼ;n¼Bu{e…×e1MÎÛ¹ñìJÐz±kãppô»ÍñGûÛn3»îÇÐÎåÈølqáÙ/L_y,f内éñ«õÂÙÉ·}*ëïFûwxowãåqj‹&¥}Ra„4!l âË™P¿z07:{0œ{!ßq¿Ÿ;ufüèˆÉÖ+¿¬í´îΊ§²ËþDOîÐj"¢¬Kï·í#PŸ\¶rð_FG*Ö]:yógοø”^~yxꩼ³®»ã=åÅ÷i?18÷ŒS£þeïÁ¼&¤ñô4/+ ]mÐiÔªÞ»røõò‰-ïø‡löâð5fôšímŠãÅÎäv_\×ÞZl¿Cù,f}­—µ ?ÞuìC…ƒT€¨[NXЄgiú ‰I/ík–^¯ÏþLNÛÞÌä]߈z!,Ÿ çžY<ô²îî?­^yÌõ7Ûr"¬,õ.zGwÛ½•‘Œ8Tnº#˺_¦×<ßúküܫՅçÆóKÕÂáÉ-·zëûÝ‘M\¡ò­:,†ÑQc»Š’íï4ÛÞÝøNoÓ5¡Ü  ¶à)°޵ h_3*8 s±8¥Ì ߯Få÷NëÎÆÅ¥²¶»|ð+£SO©jÅ ë_òÇã…c±ZRAºì‘¹iêºOøj~tüõôÅÝmweèÁHÈkÞùŸ>4:ù½íwþÂËOºÙ‹ÆÕBuì×ùú»ó­w7˯×'ÿ³»å•t| Âø´¸Uõ¯îÈ)ºÛíÄæè¦pœÑÃðeúÅCvZ`ˆÐ–bXŠKgÏÿòoãÒálú&?8w/šØóÙ¥çŸ|\gSÝ9:0†Žîoñ‹'_-ÌÊBS!ÛýÊÔUsÝÝA¿ïÐ& Ä£Ð/½±rö`oç­+Gž.òæä÷>-ܲXry¶ñæáoD9ÍÖâUƒÐĸkÂä ù–£Û^ÌÞ,HÀ,%7àû°-K§ºb¥_6¡>òÍ…ƒßÐùšÎÌÖ•“Ïi[µÒ½äÆ/8W ηC6§šÍ^WŸ?‡'m1L×¹QVÌØÙ·–[Þ“å=5±.MolKhщ æ_výµK/í¼ò?½·Oý<_ûn»á†úÌ^5zU»Y½æ ã&c½¨ê3¡^rf§nè_ù 5±>¸L rp™/DžÕwœ ¨~XAÏK¿ø\=w0ÛtêN_|°³ù–fáÕfñ×™Œå®býeã¹Ã.‹þÂó²´Í'Uu^h•›ÚÙ™œµÓoiü–loýÄ®·›Õw¼ÒÐ/a4£¹g^|á_;oìl[æšîtaÇÇ«S”›ïëoÒÕÉúÂYñ¦Î¶›©µåú‹m¶ oÉBüï 2K·ÎwJsÉWˆBÏÐvƒ5i=P~T_xõÂ>–*Wd)?zÃfÓ®»­)·¨ö¦w Ž ºh‹®—r QY-߬ʎên*'·zÕtwßk¡ùã Ÿ©¬ÁKÃs/œyüÏúÛ„êoØtÕÃÔ¦ÞµLÏ„Åñ‹ÿh{ÙÎv°â8Î6Üäǯ7oÿˆîÊapì]¡šˆ%¸@ð,³Â|œPã,tBWçŸûruìqÓ™j¹éËãè|X9ZÎ\ßÛt­7SÕò¹‰Ý¿7·ïcR7‚êéê\œ¼F7ðjΚéjî7S»?lʉòÒûT^àÅ »-_ŒÃ³¿Z:ðÞ¿¿fö­rbïMÿª¿Ì×l«*3zñï;k¶ŒV挀n†±uy1sGqã§µVV4Ê ÁÆ#YW_ðã›Lt |¥ ocÇf¥:óÂ蕯ŒN?eM×ô/ž¼úãvzëèůۉ ƒ£? £ÓÚÏyÕ/%tç~¡ó ¦œÉ2g$°êùع¼®F³×<߰Û*KoapÌW¥ÜðiZ/þ üTxœMZ[¬]×U]k®µ÷9÷iû¾l_;ñ£!´©ã¤Ik‘Í£´i«$iÓ˜4ª| A¥RUˆ"…J !EQUB•à‡¤~P$D ?T4U ’Wƒ”4mÞ.Ž'Ø÷Þsö^“9Æ\û8Nü¸ç±ö\ó1æ˜c­Õ“ÿZb–¾ 1 QíOU)A$h”˜b r”´W{1ÚbÿÛQcP¼‰×BliñŠôbïMšc‰m‘©[zdßI:íc ±ÕcìBH1¤ %v")ª/k¿ìM[Vû4—ÊfQ(x;FPT7nÿaIÅÞ-f Ø·¶rIÓ“-föhÙ?¢v1&[Ai½}{Qüж²}·Ø~¾Ô‰­o_‘VJoû²¥4”²½g>à#àª`ÞI™d_NÚ˜©[ã/óVÄó“ýÖKȶˆ}É–KðR2KâÚÉg4lc9ØÖG˜eÛG™˜Y´Ùüa~³°t*›·:sr‚×ýwôß¶JÁ‹¶÷”bß©ý™²9QÕÞEà¾ã/ÄK{„mèlË,Tø“«Ã§fŠÅ‘~p€Dÿ¨Ùÿ„âöÉ.Üû¶-¶cl…Ÿ²ØÊv‚ŒD;K†læáE0Ì!æ§)Þ1›,¥ð£=¦7¯Ç&Ú«fB.öWî%‹%[-_D‘a,;3­H‡Ó΄]ØÓ™0榕½`‰cÁ³›+öÞù$²…£3"d&À]¥1Ò>Žè8 ÃèëùפÖ§’Z-m•l  c$]BÃécl™aµd‰bû颌 Ò ©eÏò\-öKfû)[RYFÙ÷ƒˆ¬…#¥ÇͭŸ|*ÂV³Ê¢ii<Åj¡AùZŽàѶ‚U¥¹®Gm[h¬ªÕ6kIaõO˜s¬üXÆfŒ`TøvÁ#,þ£‰:…ঠ€¨qA…G){=+ê…_öE{€û–âùãÚ]O[+œ`ÙiU¼HPH1À’›`#ÈU3H‡:o¹t…†òÆÛº"C¶ZÈøO]¦Âa–Ò‘‚ hhøeƒà¤¥·€üfžñO#·î½ëÙh9i ]ô¨‡™k?0Ñm %4»îÌ€¤#úÙ²0Ñû„™`»˜Ø®ÕrVh›¢^bêQ³Û( k²ÃϘlµ.Åù¢SÔ/7‰õÅÜPú~PlÑ–û îÂB´þ™ç±¼Œd‹}Ñl¶öxW[sZÁÎÇÉ^þ´-'’“Úmlƒ½AIÄÀáHB¾…•“½ì¥m¶SA^áÛHPÕ>:îìS–ÿðP‰HÝ ø+=Z3 ålß5/„ôø½wÿ7ÂƒŽ¼0³Ìq=ú—} G7Hêã4Y ô<€HWEªÔŒ¢K˜ä"žù2;^ ^¤pÌ5·Ø~­q„Î Óà] æš·ûÐ{°\H](ÄS¼ðüïÙ[ËÞÏ>gÀUØ‹Ìþb»C9+@Ål4‡£¡LÍoÅ=fÀˆ”@ô±ÈÎ)òÇÉîLÚœQÈ:^Xq†â}Éwä=[ÃTrë-¡ëi¶¨oàòˆ½õ•¤§±Ï]Œfi›Þû¹ ÈAK§¦x8ðÝœc}ÅÞŸœÑñ'ÞTÄiE¤Ã¥,µŸÁ‹ÄND ¸bo¡‡Ú¶CgÀŸk:w‚Šƒý:EtSs8ú£VP_‘DÃöh/¢Æ„ö}îî  gJ(ôž$£MÄ¿®1Ÿ€b0¥ì0ã©ËÄB=%6tà•ûÕVD^!÷K§â°!:ÐÍJB®úüzið’âKdaµV/­¯" íé…)Ìï‡}§^BZiSòÅO'jeO‘ý§~#Ô("v®èsÑ—JJKÐX(³„Áª|0Ú1¾¤‰A;«ô 8ÇL¼H¦o  LÒ%ÝåRØ—øÀµ'á[¨]k¢XVB-Ýê <#¸÷'£ *‘7ΊA&¤ÏeÒf¡´ l2Iئ™D$zsÏ,kτʬ€?¨W]pWm¿à¸ØòÀӄ̆û!'ò©µŽÜ_µ’ü@JÞûFP'¨–W–´†{¶'[ ɈéÑáaö±Ò§Ô’€Ð LóÒš‘·Ëh[Ò\Ëèš&’oû¤zëƒ{™VUéÖEN(Â’ H²0-ú<^‰•ެL`X›§^3¯iš0A‹/-÷>Žqb/&àaÇì´Ïf@“:…BoÐ2%Ôñƒü•½åLÂã% öIÌwð‹ Su³VäqŠ4Ë¡b ü“øDJk™,‡žC P»X×_ÂN‘,9û‘a· f(Âìã‰ÐüIÎÑ‘öÖ2aƒ±µ1ÝÛüü9ÁR–BÊ-Icô ÓQîLº i<`ˆÀÆ¿H°H‰‡õ Ÿ! ÈŒ9mzç¶Ö}ZÕH¶‘iF% …,Œ˜«¹ñà£Dªx:a\-Éþû_ΈӼ•¥"¦G•¥‹“"×{rÁ6H¨@†¼df.½Ñ("Ä™ T§˜ãûy@‡ ÝDrƒt`]³p5 OÁù€«—Í,mvïb¨YLÐ>‡}ÿG³°ÙÅ"8RãŒÆTÄÒËÇþxÏU÷†¼æw§ÐF× Ð «ÿœwYz€ùÒœ†‘„“KªÓ3M*ÄyÁSt%¬“)–¡™"ñ1@LbjØÇ{§ Ô ±¨“Pa™eg ÀV?ôõù«ïOí25µ†ç#VK4ð0ä'"Ò ÕÕ‘Í;j¬–­™Sj§ •¿F©ºl©`ˆw‘pYø£Bª$©Š;õ ¸ ô˨‹‡\=ñûºëhkÜPrnj-üàDÑæ™Ì¤s®ã"ÏBø‹µ` <Ù%\Iç²V$vgí¹ýg‚|¬L9ÈŽœ½Wý9nÞôWÛ¯?¶òÉ¿ÌÏuí2Ž <ï¨r>1f¢i ˆ‰A çM<ʨD×k†}àG§¿ûÐÚ­6ÙžH££Å£Í8÷8‡¦ÚÝS2Ê6ÕwØôž+a·ŠDsö²0K]/:ŠØp"¯x¹ÔþbœÍDŽÿêŠFK¾Vž7’rˆì¾îÏ»sO.̻Ѿõºð³çö,ÄÑÞ(-„k0›âbdl`–ã[OïÖó&jÒ5sRõ?ËÎ9smâ½Ëw¾C–5#?6tÏ»è§<cž×Eˆ Ò„üãà'¿3yû™W~мٌÛ>ýTÊ+k·üaž_6.Ø5V€ô\°á»PYV •• ËlT¡ÇëžîœQ„R?'U}ãñÇ€ñµ½ä<.ÖPEbÇQþÉ©¸„ƒwDZ:5ÖÚDB$º0Åg©$Šêú\P†®Ôsã±ö*1ªëåR[ ~’ÈÜöÈÖ«ßÝ~ý?ÛÍë»·Ú´ ²ü¾Ñžyq#­\¹¸ñ¡§<<ïwͧ?‹ôû@Áo¸r]Oá ¾giç3(Ùö ¤3#„^wñº?ƒH±ÇE\Ç ¼W‚1ÁÏ0Í'ºÿöGÃöËçŸùÖÑþaºµ5ÙÚÍ­HØêÃ8Ïó´Uˆá…Ú=½C%^Bƒû’¸Š¸,âå„¡¸Y·‰´w½ÇG0(#œzaf÷uxQ‚OžU¹Å¦ýP+ùm=øùçÆÝk¯~ïáCwüõd{+-­6 K@-”pC†‹â-•.ò0×`ÖÎUŽze¨Ì×a•ÇtÞú}<쮢砇ø‰;]¤ÍŽ ê'JêÔó“;Ÿ™ß{ëxaùâÙ7ŽÞó7ýü¼tÎÚÔ4…±5¬;GÞÌ š'¡´>×û"µV‡úX¼ê>Õ$†Šà*Ã%C—ö=,cqš]åñB¾VµiÁLé³'Ø â)Âxíæ…Íë.¼ùøÂå_¼î7Ú&çw–/Û4âXº aúN™lµ{Þ©fÛÊ^œê½+O~Õ?¦2»]å*Ü0}© Ù^Ç5$ÏÅA˜;-><—̪HçM 1päH½ý¿ÿ—þ¢‹‹Ýk̺%lœHgŸvaçÜË»Ž<ûôßx®_{_¾ìZŒ¡¸©Æ ; UªrN–œ\W5vàŸRå™ÍAcM²u”œ:5ë <†0ôî@ße?ß­ä#úE¹päîG/žþÑÖKß.ík|º¿ðBœ[ï·ÁŸµ?WÎ<9ôWVoü­4爱!´¹Š°ꥶa¬C­$—ŠH0‡ÒãD ¨ä©Gç'ã0³žVë s{™P¡øì}Í8ûµX;æ¡Ûyãßž›_²5>z*Æéù—~ å¼ê(´”éîÞ½ö‘ +:ªé úÔÍbO2S{ª§‡t´œàS™»«"’T›…ŸG¦rQà9®òG(GŒ®¸(ÇGâ lG’ƒŸúÎÙ'¿º‹ºýêÒ•÷l½{&^ø±æùÑÊ5qnW–ùõ~3#µ9ªÔoBJtчh’êCî‡zèÀÛ<¼˜é§€äNõ¸u[$9™¤š§TÀ¡VÉ[cBÉ"Ël8’A ˜_îkF»uçô…·žÝ}ÕƒçŸÿöxqu|ÙG›=j÷Ù½zĦYÈ€wXI#×òTy‚Ü&«¾wþªõË9ûJΨ…6f™ë<E¼Þ­bQ1U=©üœ†—§Þû”•ë¿.žŸœ}¾Û~½Ýwýëxõû::|óâÞÞ}ù_òxïÊUŸml{´ÍIËë.¯}sëlpÖe×Zã¬õÉc’|â ~Lò›ãÆÚlr0Æ\bLöÙæìåK¹Ò:çŒÍQþÍò¯Æ;ùÇZ\odyg½59%¹ 2I ÷ɯ‰—ÈúËf[‰9ä+/Ír½qò£©ä"\gbJF,‰é¦DÜ—å1w[›¸–XàñÌ Ól1Xn”›`„‘Õ\ʰÄú\v“a¡|…åJ‡ÏWÆDúÙ[>;€{¼‰¸dõ¿Ó0[dE0\OJø·öðBÅÇæ$[d`éÊ„õ<ͱÌK—Ó-œ2¬³t,/“ç6.âà c‹g²æ•7üŒŽ’?R1 W[&Åé§¿†qÈ<üêÔrùAL`¥I ä_Ö1½ š˜ ù¦Ù ÑÃce¯bÿŸÈ—ÜW–¢ÇÖs ηá áî@l6Q–̺S:Æae˯2*‹[F²¸’É–Á§3µ:bÛ¼ÕèÈÞåé^*H]*~ ¸U ¢™l[À‚gF¨=_ìû`ÌöÕ eifšÍ0§$Ù…‡Á‘NÎV—G€2ë:Á,w¹ÆqK4t'ÓŽA!° # V¾‰6à 3ß"1eáJ"arå`§EŽd ™V}‚+Z±.ÛÛ?”µ”±í–1Ңdz噫:®]J²ŸN°¨(5ˆ¼‡ÿ¸Q’Öx•U|fÖã‰ø ËN]ëçqW(x&rÇl—Ä—¥+YÂ!+S$Œ¬kÙ‰éþÁÛQ<ÜGR¸"š‰½¥r£”6@Éœ ø/¿‰ýp¦b”€ ñÐ"-8(o‚4•eÁŠEÈÊ´MAÉÆ àà±K¹—¬b›ü‰¨:_¡-Ú’¹ýÃ@>ø§XŠ­y}”v/ ž+”£ô¬V¹JT´&DÓVZ©@cZ†>åƒ"b- J‘µX¥ S-Mï –™Î6-q‡MJ¬ÓþBüt°=nwVQ%JJ™`'ëIÅ*¢ä Á°A¤®}ÁjÔ¾§Ï%72rÊX,aÊ Ú›lÇ ÁUеݠ¥¢‚¼SxÔSúÒ¡–(¤'7zÂÚKQ èIÐA <@ÏÀI­ÄÉ ±õåV;WF϶Y±.³{°‘;–‰…ÙìÇtÍc]ÛBf*t|z²Ò>ˆ‘>ú©Ö©/I.[Ú,PEîAÄמ½›ùFF@“îüÓÌ  Ù¨Âò˜TÇ$IÁœ¦X­L-)Jd½UH¶¬Œ–e>H²£u!>2†%£i¯æUÁò#£œÇ% øYØŽüX{EhºE—%6ø(Ü]ÊŠ°@fI"KÆ[8m&Ø’ÉN oÙLËɯ”_’®49GŠ«3¹«SJH áßä.ðiZhÓ h…v9¥4&ö@|lQh–U ¶Üþ±èµ¦4p‰lE9¢+œ“~0 !UžgP1 4J{Šl¦L‰ä”Ôz!yb‚‹zw‰},…8$åäX.hžè+äïFé7Gä[Dƒ“î|àc‰™ÎmÆXaçðH"YP‰àÕAO(›IÜ69G‰A³¥ÁÈi—PRhp(“’Ü”³l{ |93_´±jçÕ‘@ÐuÄ+ÆÎ1ÿ|F‡:ÏŒtdIJÈÓä[~"‚òBu{¬R ñTÐAÒš|’£'ÂÁ§r``kå#Ú‘£v%©Íj%õŽÊ¾Èá5.®#Ée8}¡lAû8²…[ËÜkí{jro% .»‚©Ø²çÚbsàU¬©&ؘ#¢_ÙƒŸL„øÌ&ŸU® :F‘s0úÙÿ7È— …U˜ŸU eÕgÆ5U“ÿ(ÛqÈI2I*&ñ¬¤NŠ¥òA!E¡Õ¢¿ÃÃnФ*⪕ë™Q|Rv"siRRp$ÓÜ–ò7ƒpTœ[tz‡¤#™ðФQÔVé4h£™p ¸‰$OX]¡ª32ø³] æ Â9«ÀIÜ#žœ h¤f%,¦ prÅúCâûÀŸç>¨<ö•Ø·lV)£Ìê––“‰21$’€Á–þE£"&)Wȧá.8°à]™,œä¹,TV'kp¤òmm*¢´¯±„dˆ$|ÿ»óAö…)?€LÝó)±•|a&y2*×dƒ³ƒGçB_p ® ÚUig…<†‘P"´÷é<¨8s||¥}ÜGÕÚÂL‰oHÖÌ^±<…Ú6êFpP¡Fnèow*g¥CÔ¯2úh¦èE ry …Õ1?ɸl‘ à‚YM¬† “íöHåO5»žg P…#sC­(ÇöÕ ¾ )³ÇUè¶q©ƒ˜µ©š4Âáà_(bögÖ€Ü;UÝ@:`Õ~\6â˼àm|y ¦žŠFPR®«Ð ˆ†:§È²5‚ªcõ'lÜŠ“³ú\úCEû æÚÙ!k$™´`)¬.ÍE.?ø—¹HgÖI2?Iy„(õŧ –s+‰R*š*’cPÑ“‚•ŒÆ¶"kµœèa]Ðq˜ú›/Ý’”r Q8qasÆb8†MV ¡ôj†˜–ÀÞ@Î(Q®„ Ûû>“•­•1P¶BOH•æ¢ìÑ~O¡V)°o¤JŠ“·tÿ@¿æª°GÇ~m•»-a•±WÎÊS ÌÛP£CN䳊éä̳%jJ+à¨4©ˆû?Óò(V%²,Ùr´ú〟û¼Ö"Ç¡ãx6ÞäÊ®8:!3°)Om)5HÜ »SÅÏs¢4j›UDäÁ–wP ͳ8$+OIðbì@ïât©Ö†u´€LIE† |) £*ÖUÁ¶Nbê0ƒ Ÿžé ‹×;-/$ ì[8òC¹ã;”¬ü¼ÌGPqޤ…acT¹÷%Žc8Îôiá8eHQË(†«¬„¼5^Ï0ؘ¨p¨Ô‘Ü·©¤¶/ÆWÌ),àCÍi‹)WfŽ“Îë8ìùdïµÅ˜à¹æC_PE1%ä<Rºpô í„`Ëc¦ n¼l­Ê¢¸Ñ À–‡k>%£ºÀ~ƒ-‡HMÇAh~ð‹­ƒ\‘‰jål7s¦J¥õÀøpYÔ¢²­/%q~ʉ»œ’¤ Ê mÉì]K4N<…–ÆõjAÅ?ä¥'CTƒõ¥©­ n’|2WVM¯‰ÂŸ»Ñµ#œ8ä‘oú»~å¼$¶ÇIÉ3+ÐEj5¡ JÔ¤³Šèä™Fg109’S‘£8k«’ÆsgT½Ø_sG:×ö×5POhdª ˆK.Ž6TÜu9Îà\œVcÏuÖù^?oî„„vßú÷­žCÓÆh@l(öäo¹ÈâÑ‚z<£ÌW®É%m”¤™ã¹˜ƒ×ãE¹` X‚ã;µdsæÐtè÷w д¦!¯ËM <Ci@N×D{Ùþ±§§g^ªo{K÷Ò¬ßä6@byøé1‘§¤8hÑá=)]ôTu)s•aPK={9Rñù,ás¬M;OÉ_à–8G±š¨ê%+™ëÛg¾siibvÓµ›î¿ª³>Ô}ahI°:øØ”ú­Å›É²ÿÊcWûk§ŸñÇ>=~ËØâùWöìßpÕ.·u}xë#QOiy Aµ—2ø¹¤ˆéyô YÇÖRÆÊ²EœrQ\U´td8$S7”Á¢U§‹/ÎýÁ‹Ë‹íî½[ö¾eWÕHQHWrÒ~ÏcÓ ç­ÒÉë¬ýÜÙùg05¾{û‹Ï¬,Ÿ;~åM;·]×½óÀð[¿”Ðl=¡Í¨R›¨Øî…û‹dˆ6†¬ò¸sƒÑ@x:O~É~A½ Ž¡-ª~Š@{”§`¿Lù+ç·/=Ù{åÜOîü­6^g6í\/>—&ky|ލ¡áæ çDR>ÊPU¯NžªøÙ£#Ý~ö‹)õ6m}}wý⛿’k&í—£‚¾~Aâ§ ¶ ôCLÚŠGrŠóÂjÇw1‹dÆ9Άͥé¹c7›·ÁŽ>1±qlËÂüÔ¶[¯~ížêí`v¦ ¨²9ÙÉ–<9 «d*‡œ®oïÜu”? †š­çp ,Y% IP¡;Cm·ì™<=»~c÷鯽°Ö«G¶$Éô›ß0~åk@[jаd8‘SEô˽¥#™¥3‹¡3TÇŪ¾pa%„ÞwošüßßöU4J&JaòúV¹¥ž¬cöUÝ>R:&·Ïå@™ioØ AutÄK—{™dEô«. Õ|¥e-ô›*­S/-Μufi²;zÅkîÝ;­Y‘ÊóÝ KØc›lxìÑÙÙSW]qõ¹Ó'\c×V§¯¿kŸÍÖ6KIJÑPöô8”·•¾Rö–˸ÄyJX†Z hý(ò;_Ä"@kˆý˜*ßéã)/OLÛyò›Ï7Ë£;·_znn÷í»Gwo¾æv×䪭]@‚®@PÙŠDû§Ÿ˜]¸8\ͼ|dv¤îôúíìüÙ¡m{ûÑ"§)w2ªjb"1@ò_ÖBU1C#P™š‚ǰîÜ@×Õ^Œscû•Ô‰mzqv¡ÿ³GŽ^uíŽÓ‡~,x¾ÞWÚþð¾‘QéÀ}é 5”…ˆYÑVzh‘0°Ì½¼zòxœ:Ö_˜˜¨7l˜Ÿ}¥›Û½ÞõÎV]ª(Ìy0E¶]ê¡”t‹]NfÊfSb›¢µ4Ø<ù ÚÖ­QS’]K/Í^¼°üÜ¿ÿbý¦ëª¼¡/Y;ïW{íP½eûöí×­ë/ÌÜúÀUõȈçÁqys€%‚]¦ï/\JgŸŠ‹Ó+KóÕÚÂù…‰Ÿ¿á÷~Ç×ø>} ÀetÍ倒R³åñ¦YÅŠÀûoÖ ˜pJä÷ÊÄaÅR‰M_ê?´ia¶wü‰K<_uMm~d¸ ÖÍNÇýL›ê/¿ÜêÜóÞ½ëvXžÃPæJ­ ümeÙÄ™©Õn9ùüü¹#ËÆó ?9Ѧ‹ïü&ß")ò¸-æ8*™ªl öé‹RĦP‚ ÌQƒïaÕ$Õ,…Ž"~ÆLQQ¨ÔÚü¤™ŸZšynéÔO¿fCW:Óðæ+/L>Ûé-ù&4#Û7]9þ¦Þ×B # <ŒT<œŸ›?óTµûÚà‡ü/¿q¾­ºó“+9÷×”‡"¥•Cv_ÜÎSj¾ö§›N"%°ìPör.qú)oªdij6Y³3V—ãáïœÜµg´sņC_=<õü÷v½îŒ›]™Yœ;uhd¤»~|?4嵋7>´oÏÁª"-7Ê3B ‡D?ñb|ú± û_?j7˜Cߘ™›~eóØÎùÅcïù—7ô4¥¼« Ü3¹Øgú¬d¾Y¼êº:µ”t£±¦æ‹¯#ßtz0š³°zß[1O|ùÇsGžØ²çà™ç=\‡Ñ«ŽnÜÖo<õ£/î¼ãÞáÝWO?wzdhÓÞ»sÛV×Öè¿CmUÕ1FßV½¥%?q¼abamnèü‰“«Ó³ý¥óÉ÷ßý­HÄ©Ór*¯+èé•7ý!ó 7.è[ûº2s€èÁ¶`¦/ÇzèÇ÷B;sÒþ×§??¼eäü©#{îù£ G¿{ýow£c/<ö­{^3~óŽÅÙæâ±#[¶‡»Þï·  ÒjŸ[*Ú>¯,·ieuøÂ©8{nùø/f.MýÚÅôÎoGêhV_U-ïI¹rV¹8Á¹ÁdEžL­òÕcôÅN[6îryñ‚g{™žÎŸûá§¿4¶¹ž[n{ ëG‡®½ëc{÷ùö÷^ÿ¶]ÏüôÔÙgŸjÖm½á–[߸k÷}Wtc]g¿6”ÛkRÁÜÃj•þûßÏ^“ZºpêÏËïúVÔ9\å&ebCkË«ªú"§?È9P}‚¼ú¥¯dË‘_ß-b€’ò‡”„ZxqrüÆŸýSïÂñMã×øfÇâä‘èzÍÐæ¹óSáî–+ojû3«+k×ßyo³î•}o¾eáâÊ®ë6×UÄ+18[…~˜\oòŒ}ñÐÒä™Ù™‰Åþ‰÷|;©*ûªDLýr–J ­¾•1 4ƒ£j;8Ääß 7œ­71 $˳±#7æ_ýÃSSOÿjuúôJ_ž¸º~çÞÕ¹Eë–Wçæêªî4ÃÃFÇoyàô¯~ºql‡]wÕØøØí5[o\'ÈÒÓ:‚»²j?yihÝ𱛞8ñ;ߌ8%•˜9mVªÙòM }£IOÍž‹ñšçokçšu¹ú+sÝÑ® Ь¯¸åÀm÷^ÿ̾ù}wl—Œ­¨ˆCRÈ9ÍÎ¥ÿùþÄÉ'ÏäÞüï}?ÛÁ;~¶$La•¯¾L ­Æ”iMØñÎU*R­de>1Ì\Ur‹Óóßýø?®Í¿pÃ=ï»xòg‹çŸª×m­†ÇreçÏžYí]êt­J½9I  [v/ÎÍ ùìowÃÅ™©ko}Ëïºæš½ýnÂÉ,š`y©9üŸç—çÓäÉK>uÿüË«°xœ]z Œ]çuÞ¿Ýå­³ïg8ÃE$%Š"eG¤$Û±@vcFܸMáÆn4[ 8EÜ6h¤M“8H vÚ¦‰mN\ÇVdK¶$*ZLK¢Eqß9œ}ßÞ¼íÞûÿÏ9ÿ½l† 9óÞ{Ïòï|çü¯íäÿ6œq_ža Û¹k·ÏZë%ëoqVg&ª¬u±‚×¹_…#&ÞdfÍÖ—á·Œ5𛾗Ëýð*à}ÇŒ 9 àuaœ…Fh#}É,³ð+8çLn™´ÿƒ•å\À·Â ­¬”–1|[ &qŸi¸—jξ(X£y÷ƒžÃºý³ym¼ÚþØW-/X¶É­hÞù–Ùy‡Ã]¼>Ö¸Åt…ó€‡}Iy=ïO–Ÿc¶Áü^Q>lwlå†E¯Áw^*w–{G——f„|ê×Yל儌¸­s[°ÒZ«„Dk˜U\$à“àµ\ƒ‚yð†“á ÷Á¼¯0Ü åà3Š7g«3o†Åúü+þäÇ’¥EsÏ—O}.4º–̽ÀMÝ4V1 Ñ]íhY¶iEYùƒOÔ¯ýwVc¶ãPsæÿr14Âj%*75 u¼ÍT‡®œãLsY°"dÑ*ØOûm)ãÒký[¿éM}Î>) ˜Á-„ÝH Öq² Àï,ÄÜÄàra„•`ü °–)ƒ¹„W8Ù öƒB¥E â%[]޶¯Dsϵ=ñoXž³V€ëÍõY¡7y4oœ± ä:â¦Êƒ¾¤6›&ØF`:AG"NÁ>¯ |¿AvúM\“½?ìÿ81cx À؃£áøëC☠ŸáFVÂ]0],¶Rá+Pð[³ƒ^ˈ5×l´nšU³3_¿þ5&¼Òß”¼a¸Ïµ£,BN'³ß–^cºÊYцxÙ¸‰fs0)Çô³ >jŒAÚu.ßÕÑ7º^ÉǬKuŸP½¹' +Jað}(C¨hˆ6- 8‹ÑopÖAQ+,dˆ¿ úf@*"øëéƒëÕÏý™]‹å†ü‘ŸÓl=ž~­íqð"€2±Rs¨& ˆw£ÿGµÖNK¿Ýˆ.ÍjãAñ*?§áƺõB¸åd ½ÂÄÔÑ›kž˜ú÷E¦Šˆ]åKn ¨=Ë€‘4Ö:ó¹ˆ ÷Š@@—APa¸‡ÚÐnJ bMÀ–'9[YÜyç÷…±AïñÝùW‚¾ãí!-Ò×<ÑüW“…ÓÌïcñR Dìé{ÒlþHWnÀ"­c7ÇìÃs‚ øÀþ/ÝZbc?ô½'A$x\fB&›h OÐVã‘@A((SŒ6}ø{ÖÓXÍX6à1”åèTK|«­ü8™~&ÚÞº&Ea¼1ý¶'¾Aµ—Ôuu)Zü[ÖXå¸b¢u'lŽQ€-÷‹úÁGH´p š( ¢<ÀÂ2y&Œèsx\h¢­háLcæ9 0f±ô;õÎŽS µÑ¸ûmžìxí&ÍéxýM­Y3Q`„`p]#[Cd°ÿ V=áÐl®üÑýo_¹ÈËǽƒ¿*‹] ,1À˜3¼hÈ#[Q`Ѐ · ªk`ËXjO{€%A+±ð:5VaóLB'E’¯¼ù‡Iu^z^Ò¨r]ßÊï{†ï,šÝ‹záû²ëÉ®ØíŸØd ‡cƒ%7xÊ|Ü1É6×ÛêÌCgžò†÷쟛¾ÚFÏMúÃ?+'>Là/rÛVL>1þ *Ö³d(Sd¼ÎñЬµ4ð^(ÄØÓ1!–‡ìh$¼DoßnÞzI”‡Œê£ø“7wþÞ.~ßë>ÅÚÚ7âíi¨™$Ù¬Ìãx[ÉÛãÉZ¼}žÉ®ÁÊ‚ø{Å=S{n_¿œÄ†ÉráȱûÏй pë tþ‚hjéÜA{ŠMe™·r[F…®‡É€ëóøLQÓè3:I[™Š–~²{ñ˹=O‰Îñê¹/µú¼}¯¾ó7ÉÆ9öyíSõó&…€H@ÿC„Xžꃛ0h^PðÐ$|qµÔÇ‚½{¸=;ÕÖeù ÿÐïzå·9dmL R8\15(´0>0žÞ>Ýy£ðÈo‚Áh*oB¿“ZŽ-kM¢b’v½YÙÔÛ—³§m"übywþŒv ƒ: öÆœ•yèV×”× ÐM“ ¿¿0ª£ ÛÜù)Æêz™ IcÁ{öŒ/®lÖ*ËÕyÜþ¸7t’š) 5‹ü†€^"ppÔsÏ×/~-ìójp/{0DØ!1êJCäKà#€ªzá‹ÉÒËqcÓD5Ùs2û­ÃÍ­ËAØíÍ Oë&Ê,Çñ¡P/Ú E3’T}ð­©/亟€®oÖ_cã*š:tŸÑÑÉ­zTÙ•^q¨±q±üèï±Î}m£ÂAB Õ/!<ÐÑüsÑ•¯vœøƒ¸£_Ä…ˆañB—ÔBÄÖæáñ‰ôã¹g›Ó?4, GŸò´A¾~í¹ê­ï—ö<–§€9­ m´¡XÂÃAæ•’Êu'V- U-¼^¨Òxçn®ã°‡âÅç¹5c‹Aqéõnn7ª"7«¤PÿGƒá“^×l_|°1'!°]&Õæå/ñâ¹}Ÿ€hX[…,°ÁuÚ'ÁiÃ*Põ…³º]IÊò£UíÒ_æJdïq[ßH*çEs…†ð9J2èøÀ@ÂõÀ€°ä—hž@áCÇ)àÒŸ˜zp§©Ö¶Âdç7w೪ÿ§¸ß£¤ÂÖ ¸·Šô’Or+4þÕ³l{AoÝ º'øÈǤ(±ËlTRãÝAP(a«Šãú’©ÎÚ¤²}á™\ÿ#þþ_HVϘÊFÛÔ/F ¥V_åQUr_› ‡t ìA,JcÔì¯ÍDk€(¿0 6'µihŽ4sÆ´ÁØØ¾Z=ZÚ.…ƒ¾ŒV/†{>ê÷Ÿ€{pä;TªÐ x!I©’Y}¡1N–·þ¡üÄÓ"6x1H"ÁM '™@¥h`¡JÃ&ÕËÿ H[ö>Žœ‘ëôKþÆé/„í‡@îŸ@匵(n›Û6®,sƒ¦Éå½±ewä%+ês`C500(ÞٕÒå½?^xIGqþÈçü÷ ²B» \ìZ$rJ˜j´zV/¿Ý\>£l%ô?³¾ .ÜÀnTE€„Ä>efË$‘ÞšfaPºÛd¡mëê×íÆz®<Š¿ÎF›‚Å(ïA{' 0iŽao}‘Fp•ASÙ¨"dú6k(ÔàÀ*ïÜ\i Ã…õz ^ÿGÚüDô–ƒBP&Š=Ôñ›¯0³ß3Õõhý]ÛX ö~*û¸!õwƒ\Å[¤,ò¶ Œ’LvÏýYõÊW ãÿâÜØ¼Vÿ¤öýüÀ‰Ð -DRXÅÛ€sƒ-§ x¤>üì—\äG»7àÖ œ±ý#ù‘GfæTcã’Õ+^i¯×~DôŸh,]-?ô XMtÐ#tØ ®yái üÆÒë¹Îq ºÂÔgx׫µaDg4ÿ sóžO˜­i¯TÎþI´önT^‡ »¡xm4§ÚøÅAÃhAh Ð ±ã!æiDBºJE" ÅC3¯ è)-˜, “ sd)Æzû†ò=û§W=éÈ®›Ó_Öeûa!s…Gÿˆ ’Õqøå.¨ÔÕ¦¹’,þÈ,¾ÒÜžåù=m'æn…£q‹œ¾þç6`¥©Ý3ÿM'M©¶(seÐ{ÌëÉ÷®Üø&3µ ÐEM²^‰ÝÒд ½Üà€MR']ÑŠõ€ªêÇFïïêFZš©$»·¬,s½k L”yn8ÿdnüƒP½óŸ|©÷ñÿÁ?¤l­ÑX©žý½úÝ}/@MŠÍ àa%U)g ¾¥‡0´4±nIFó†e_y[µÆÛW›s?°ÉŒÃÁÀ„c—ð&6Ìw6v¦õòÅpìýÆ…WÍÖõúâ<™Ohþ)ôÚ]yKåXgtÚ9­žZÉ0’¸Ì€m“&¤Âm|8:õ‘/¶ML¼qíBT¯ZÉX5 TGþç§þäî ÞÐû’Í+ùýŸM‚öèæ·eïclû|´ðH¨j@ö=œ?ú;{‰åtãöi¿c¬Yiæö>¹uæ÷õÖ¡or¿†‘Þ}±rýïš3φ©ý¸ÁÉ_  tm q„‹|’§è[Ú º/‰»8fJ…îñÉÃ7o_«Õ­W†’¼“3´U–<ý„fØyW—öñÊ Íz Ç9^¾(Ì7¹Ís_B›¸^|ä· cÓÉ®w¯n¿ûLû±ÏxÅá­›oÇK—,¿ÁýÎÜÈS<7QØ·ñÎáV¡‡Â¬Ð`?";8bh[CF8Í"!ʨ pI«§´ºA t Oœ›«›>Ë«lûAãì)¼Ds¿ëX¼{»‹¶±hñ ëØŸ,½n*·­È‹ SäЇ?ë{,ª-*Ä]TŸ}«<ù”‘¼ví¹Ý[kkWEÐÑyâ »Ó ¼_â¢$<áùe¢C»@ÉTŒ5§½Ù/Ü«nácii?p‰‚:œ¾}Þð"L»tOw[E~žÉ‡{„^aŃÌ+'˯Ùòa[[ÈuMTç_óò=ñî‚ð:ý¾X»Uþˆæ»vçç¥zm§mò§wf~’Ì<Ãâ5¯|0<ð+zãhñGqõNqà”©Îëú.Û©󚈆 Ž;*gCËg·òw,%fÔ²á åy}½Ã+« Q«° ,DD¥‘¨pzÌ¡J=œliÕŸýp¼úVqòCko¥tè“ÕËß êÝ+ú•hã\²v¥çƒ_ŽÖ¯ÄëWƒ £²q!,Lj¿T½ò‡,Ù•…ñöGÿÓÖ­š¥çx´êK'#Üp@óµN+à´˜u.êb&]Ñú«˜SB¨åqª©¼Ñ±ý+«Ë»»›|œ9,µr\àz ˆ¼Î‡âêšmL«Žªï}AçøÚ¿-’ML–ðÎÑ:÷:EØX.úÅ&o7Péåá«_ƒ1YxíIm‡bãJÜï×E–ì^ÅšN¼hHlÊEŽI2ûÝKä'™ © )…ùÒÐØD£²37w ,vÄDÓU‘ʇ}'㋺±Œó~a(7üa^Þ½ðç@þE•ó;¦@¼Øx)Ùº ‚¾ÜØSÑî&€!Þ½dYqݸ«këðè8 c‡:!Š@ŒØç¸ÿ™;Y Haåý*p™aTb#ÔNžWo6Vç¡oqÁxL–ðhÒ”:iPz­»K Ê$˜Í´0ÄÃøÅhû¼MvA©Â~¯ë½‚×ê›w@öëµ7axGy¯› ®$Üz*ä„ü´ÝY’/d""ª8á)Lð§Ð-Ä)#*T026Y«­-Ì/U`Ðqµ‚nzñ𤑵!Φưû`mé-0 Üñ»~ $·m,ȹ‚ þpaÿ?ß¹ð—’7¡pÖdñ¶Áv|tÇS9ZÅpwG;>m‚v¶‚1xši^c¦œåcÊ Ç÷î­W6fç1×8s<Kk„Nqær¨`TÑq‚—áW,‚¾¶©µsçÛ"^Å)Oåqy“ØÒáÏé¨Òœû›ìØ8± ¤c ´àÎÐRuä+Ÿ,OWá4mÉ´I9´Æß:r²&½O#""ðUCêUQíÎÌwàC® ñ ȵ<ñEû¹,à–ž{+ð}…ç8ÛÉô`)¯ýaU©-<Ï’Š—aª;ÞyטHÐéæÝóÉxN‹êÖ”¨˜…†ësã.N]ºTÓ½ô” Oz£“ye¯]»È2äÑ!¢‘z…ã6L1 Húeðßú.й2Ä$ z"W~WÔ=È뀫t´Ž=‘ÚL~<:ÚÄ0„Óþ‚TMOˆ¨ÓÙï^Ç9ëZ3$÷í?"YtñÒy·!IC "‘¦ã=…p¯$qÌÝiزÛÒ96³Ùá>ŽÚ2´¸Á_VØ÷AQjC¢Ø“~O*I·¬t’€“%én™jMRNàyähLÁó†G&s9~ùòEDZ™Q¤õ¸;…K)éHkëÂ튊ú¦óŸ)ÜÞ2ÝáÐu3ý˜ι¨tÀŽû8Ïdq·™ÈqQ¦³L†I{Y ùn¨›…© ||ï¡®ŽðÌ™×Rü³´æ]üh%Çèkçn¸¶®âñ¯%«(PÎZ ©rZ0×8Œ,àªäá±>çÙ)‹[ߺå!MŽÄtgîŠ)”À5Ä ÷ãFú;^~õe+2%’6“ttpÄÌhâ¦Qý¥©`é1Ÿ‹s‘s÷#0ÙVý»0¹é‡4®éIj*~2ÜC”›¼œwt®¢hèGÁ‚þ=Ý]mçÏ¿mt²@»‰8íà)‹ —n×Ýî÷‹xÏßiEÔ]4¹{ºv°hð„±È€¹í £Ãƒ,d<µ8mÈóÐé²ûØKÿŒ[M¡Ø682rãÒ9íòŲϧ¤¹£Fâ£AçfÔ׈ɲR2ÑÔb4¨NÁ»b$œR:ðÎônlÄ>~Ø@¤ OgY‚µRI81é&4%sŸ Á[ \Œ+C‚?ýC“{_åe¢t“F—¥-é‰)?Ð LâîÉÜ6Œ˜Éó‹ 0,QãýTÍlz•MÁ–™Ä8ñ§S[ÖUÕ=öpÕã^w»HÏ‚mš)áÝQ ÔV_ÿø¡¦N¿üƒ(‰RòtsԲřzš¨¤enYÖB3>äßè<‚sÓv‹×x*HsÜúm–Tšr›^mÒëÜ ï"'Äß [ÝÛ3zôØ‘ø½8‰[¿å4*kuïl•wïYD iömëõ–g†§ضž¿¼0#›q–»a8*K[p6Ћœ)ÊŽELGûÀá£yýåF³þÿÅÑmî²æêêßU}‡;Siñ½àgwáiÈèÕ–8Fü:ÿ™iåØ=$Õ™Yz]“[NÐd.í[°þ …Ž÷œ<õãW_Ø­U­Í®ÏRMEjEëfY¾yFÜ.À|tueæÎô-²-ú³Eá,å0Ú,¥Çk<%–¯¤IIGˆ¼"`VœŽUAˆ~ˆuø?q#Uù޲7]ǧnD¢”}HáúÀÔ?0ÜlVVWW¬¶kšYÖR t·Zcªª²&š1„MJë§5~´Ä˜!éðS±Â]“a†öÉîö©Øp›çtÀqøw60©|”»èŒ2Ý3±¿Y[Ÿ™%Êu#…¹¯–S*w„eÙ}Y¥e$­‹^ڑɶT@ZÖ*fĬë0Y4D¶J¼_…¦K»’[’š‚Ôâ s)üññý:ÞºyûvÖÇG\HÄÿ´x³¿yÞ«;Ö2(£¤¬s´`„ÿ!~èg:ÌÂèßµR͓ΎîçT(‘â³øÉHÕZyIéM†>;ñÝûôw „+I´›–ʈ’e(½_uÜc¤V.ˆjîiàOãÔKïÂîQ-ËÆ?ë>ûeSfp×`SÀa0H7*íín+.]:o],³¹a'£H§—Z ÕJJæÀ=G8O›/åZ¤™J…-ÞÕ£³EžE ÅÒ‹±™¢uêF¤kg÷Lú(‚$(É`cBö÷ôöt¼ýΛ6ÝQ0‡3zD¶PiåÆ tꌜïAˆPî`ïþ´„4öýÖç’?."YˆÛh>p…'2CöÓGHð½.pn„¤‘ž|åÕÒ(·Æ~/È­nÊÓq†e»‚ÖW«áÐä’.ýlöž½,ØÏ³2¢C7㈚$.úÌy:ðtF㱓8¡ }3ýýc{'&O¿òœe÷(ïžMœ·–wÖEÆMÖ.6Yí¶Tœ#¡´…Z‡o7µÝƒ›t`*o--–Ykv¡ú5iíòÌŽ”Bñ“Ï8ÐÀ­¾=“{'^<ý¬Á ª¡B—HÈ-\ÛVp[üäÜȆãû/¹ˆZÂ(ÓÆéåÿÕ‹)¿xœUz ¥WuÞ]ÿåí¯_¯ÓË,š}Ñlb´!X¡"\’2› 'ÁA¤œÂ©Tl;•Â)’¸"Hƻƀ"´ ¡]b4h4ûLÏLO÷ôúö»Kιÿë÷Lõ¼é÷úÿï=ç;ß÷s^ØJˆ ¦ï‰ç‚y•C:™%µ·PjüÚk:ÞØ»IeŒ0AM•°5B=Ã¥ŒF ƒß¥Ì·ÄÂ?ÌÂÏ5!*Ë:«O~Ñ6ßd’†·³ú^µr,í,&÷'ó¯©ÖËR†Æ*­¤ŠÜ ‚‘ÉêEšÎSn©7T9ü¥4nëæ…póáðw7¼4±š3«e†s1.^û÷'™Wc°Ülú5âm4ª-7}ÔFs¤ù:SK„—K7þ)mæbŒX¸$ŒSŽ—$„ÂÊ •¯žÁ†(åÉÂ\D½×ÿ²8swÿòšHÓŸµýYYßFKtZÔ ?£žçUw0“¨xAu/iVõ‚²Ê&nqÌð Üh–µXiÓèÿÆR.¬Q‚øZZJT¼jd ûK>É.=óP0ùæW²µŒÆÔjV9¬¢9ªZTx°]* pYmRYÛNßË×[X<,–àêe„ã ð‚èØ¤½Î››\øŽM;´z=U}áó¤}~Ŧ+~yŸx+íïοÄe•Š@Çk\µ¹_5p«üÆvoä@·Ð¬IûJ×½§ºýŸð¡ ¸VÝÞ•3¥ñ¡¥-—_'Z1ñð:ŽÓâ6¦—ôê – Ë!ìÁ–û©íIægQøâ¶°òˆeEŠKfÄ"²K-$‚ZH‰êtŽýïèʳ^©ÁL7m.µj½ºG"E‹¥ëÞÛyý›œuɘוýÁøÞÖñïQ»ÂdòÈe‘W¶gi»XÜöWŠÃ;ma¤qã'¤°W_ù±éÎeÝóí 3ØùØ~ŽèîQÚNi‰Vvq»˜­¼Æ uÒ¢$å¢Hd DÙ«ï–×?HyÍÒ„É:!Â2{D°[a9¿†t)Ë…Z•[|üAÛ;m¢N¿7š{têݾxìïi.ëþB}QÜ6¶EÍóº¿B©å®{D²H¦oŽ–ß*[  ›ïšÙ÷Î.üòÅWžf–÷~¬0|ØÙ©Ó«^ãL2Õ:O…4É"62¯ Ï:³P#”3Y=àÝðÇL |¡!µ@Å Àà[ÈÕÜBÎÂÊf&†[ëó?MW^£ÌKZ§¼ÒF§áˆíµ‰íX«¨‰8d‘ Z˜R´ÆÓ~qtª·økn:P¡6œ,oûÝöÅçýêd0¼Í=XÙ‘eiëÄãí3Øtµ¶ëŸE±;tWP°•¿žÌ½È»õ•ŸQ5§µ-îz n·I¶¬W_âÔ†Ûî·£…åÕ-‚*KŠ…ky•ààf%¡),ùٯص7Uo¨5Ü)|L6XaœD§ „xŠCµCµpæ7¨¨Xqª©,¤½%F´ j”â­¤´¥¸áöòæ½ÀUÊx@§Î¥cailõ‰`x´ÜØá—/l¦FyCû)éEËG¹¨ñÚ>9z“QJ·lï$º¹zès4Æ€3mˆ'‘Ê€0áOƸ/aA°T ÛöËÿµw⛢¼ÓÞ]x˜û\%ý™;¾6ôÿd‹ÏZÌ–dBBaßœ‡¢a¡™! GƒÆ!Y¬u¯¾9}ä´¾‹$+zí²_•iQ(9¼aLkþD}f«ÍDšµK“Îúç˜?ÎÃz<÷‘u?Ü w|X7ý ´m¼B½ÐÝaÉ–ŽúÓ7So’XX\„ÈW!£M6O-¿ô¬ý„/‹›Œ6™'ªMå(|LøÅ¬{•sŸû%K°q&|&G²hP–·†3÷ò°Òúõ_RcøÐ~"¥Q„Dyazê½_“a ‰žÄ¦ÚB.}TT[²Â„Š;4[€Ê†äRœycÌ“<œ€»$Ë/ËÒTÚK‰iz•™â/ÈòN"p¾0‚°8^9¿öÄšÞqê‹Â„ê$YŠ×NZ“ˆÂÆÂæ·÷.¿l:ˆ^!B“AÔ¹Wã~ÝDW€Âúní¨Öq©W‰¬ˆpLŠ3aÀƒñƒÞuï*”«Wf ~³håÂÃB’fÜš«l¾_÷çÓ¸_ÙqóWÿ‘ò “@¡>´bš­õ×›¬ïU·Ñòf«RØu¸ë^R˜–61H£Ä¢B&Fg£ßUé²Z|>];NHJtJ°5 oôp¶v’$W°zx8rðÖ¹‹p8U‰^>æ _omj:ç)ͼ°šô»påÚ®¤f´°ñ­¥M{C i•"3ÊÒ¥__øñ—@ÉX0%«·ª …dk/P9ÂýQ€âøPþÄí6jÅý…ê²ÂÌ)êªÂÀd˜¥ŒyDuÓöÙö±ï©æ¥Òæ»’ÕWUó4÷ÊÉê1›©ÆßÊš¿ê¼þu  ƒ 1Bi¨U§0²±?÷‚ÑÒLPßšÌ=§™ÕÝ ”H*ÃMoûòòê£^P¯Ýð~nT¼|¹uì'‹oüß­ý »2ëW÷ Od€´þE`s¤FY·¶‡– Ø ±5ýKĤlü}áô-ÉâH°ûã\i"¸A"ALv^ùf6÷pÖmÓï¶ÞGU·ùÂ×lÚä~Å* JU;ò§Ü›˜ì‚tuÖe¢XÒb˜sCMœv.‰ÊÆpç?Ñ<õ´$KikÖo쎖ŽAN¡lei4l쟸å³röîé—Ú'~¾á­6þ¨_«ðÂ&n#‹”’Af “œ&Öh+‡mÖò+Ûå̽bx_óÙ/C·—nxpŸq€’†’²‚­=óÕtít8rØÝ]y Krå%õM²,=/K“Ñ·ý§ 6Ö<þ£°>Ô<ý âþ¢ÍÚ<ž©Œ`î‹/þóK ³VuY0î{µ”Lÿ”ê÷ÊS7Õÿ‹âô Êï1àL`¨ˆÂĽV‚{ªý+Ê÷F'F5‰Q<ÜÄK{TŽ í¥-jé«—7ü;1q‹<"QŠR´jì–q•ÍþÕd¡ìM8q¨ðÖ™háÖôdy»?²§¿:Ïm§4y ^réUeµ¯´e`9Q"DjC(a}^c 7WwÞ£V΀§oð*¥Âøpš’¡]Aía¦r㟥ËgY<›¬¾í%ìŒ/Pã¦òÛþGÿÔ_eçæ¥:2¿W®ìý¤»10À<E—Y©¸âÚDMÚ:í×Ç–O=ß_xUD¢•“¬8»SÝùâØvcÂ,Z°Y¨ž_d>Q@@k©ð*”Khg8¼[úã+§ø2œ¾ Àô–¬õ'Þ­àZpG@8®Õ©OÕo{(>ÿÃlõU›5aßLxhÐЃC Çn1i‹âù§ˆiC¬D¸ÅÛxkõúX}R(iD ÞÁÞ<öýîÑÿL½#Ûäû©…åÁe ¬@ÔÁoCÁpf€,RMX‚¤Å$:@©Š¼ `¨ ó'ŠãÓk—^åé ¹2}h‹a8|syÇõűž0„£b[j„¼°êU\-I,¬ŸA»À±,!96ƒ;ƒÔ3#иI® z Y;0~÷CÄ+ƒ„XgýÊ2ÉVήž|29÷½¬y”m(zð@õ‡zp ´T°@6åóÂk/™$ž•»ôjÔ: Ö¨4yk´ôäÄÆ‘á>lthÏ+»>TÚB4D1[Üø‰dù—Vu4 xÁ ]P}ønÔ*bœª‰ûPÖ£Òä=µwý±±EÝ ‚"{Qžn-ÿøÓÝËO^4k ³Mîà;óÇTÖñjû²öqá×ltEgÄØ Ñâ+oü½œ&Ý«s~!í,FwëSÒ•€º•“*Zñ«[⹇euÚêÒôþZ%Ëñ™G–þgØ…ÊzLõáPÉ\„2ÂCQ¬3Ý÷+›Óàºlþ ÆzYªÂúö ‡>›•ªåáIÚØ°úêSRø£ûÞR{Çß&çž]þ;°Ž–$À'PØ }¢¾—×¶ÙÖéêžO®ÿnâÌ0Ñ=Á¯î ¯ûdãúZQe"U;b½v¦âï‚ñ#ÝÙg’å7¼út|ùi-y£·yµí½S þ|géÍé;¿8ÿÜÿÌfÎâepâÐÈ œ\+Ç CKÐ=sUÊ ,O©ÛÒÙ§Të¤EÃKÁø¥M·¬ÿùÖ;ÿelÇê[†L†ÕXm&¾òt–ÈH®†]{p{\ +Õ"¦¦‚†£4YÁpý–?÷§ßJüP’LsÑ?ùÿâ‹O6Ï>íQ:öC?ï_±:¥ÅÍAy¬wé±pêiç h^À ACXQ7êxå-ñʉêÖwkÝóËÕîê2N ždú´£Úg±™¥FåÕÚ–{åȶñ÷„cþüÑçX¸§²ûþþÙ¿6½sç ÔD¡KÁGI6À|¯/GoN¯¾È¹€Š ¢6ùÁïS¿J¥¹ú‹ÿ’^zÖ¦Œ¬Ë ›Z/@›Ž’ö›r"JÉò³AqKÒ¿@ä˜Wš.IÒ›gj-Ž34er(‹WA|¬'Ú€.ZX­”&묌"~ÕÕå“ßÛýð‡8-åR’µ®}"»#]{"X»1®Ý…ÀÆÊàH¾A>7ÞOTˆ¨rá60oxø_ƒ.2ºô´é^mù‘Ûrì-ªsQwΣG´ŽUóƒ¥`_•:Û6uË´W¢ ?"ªÅ‹2‚–ùÆ&µ¿ÅÔŸ}ü°…$j <_Ñ`ϸ*ÝhŒ>tWÞQ;óøC4nƒ‰…ëb’uˆ0/€öÂê>.@Œ:1pz½NXã…ÉâŽûË?•\z~éÙ¯€s+56Äq"Š5Ýœ%È =E”ÆÎ©]9Økžò8Ôh˜Æpb©öLÒ…‚Ó:ò‡oÊÀQ¤W¤,éÄý«Âtá:–‰©7î7öï¼+i^h_>1sσ­7~’\|’‹2˜[kAPRc€–qž€ãƒ…`@‘!gH”™B©žÆÊ`xµƒÿº·8ÛØy{öeñÚ©ŸI,l~_aü`té%ðá›?;÷ÃâùŸóòÒŸ­o½oåâ+>oeqOr¼Ll+ÑžN: ¼D)Y?,{t÷4é^68ô˜ Â"uX,µ.¿ ÝYyÓ#Ÿ\}釺ý¦æ£^e$[|5¨.ŽéÌý8@Åe.ˆÉ! }¨£S§PÔ0D†“*£{̽ë„7V_ý6ÕkaccqÛG »ât‘Ä|îÑÿP;ü¡xöÉèâ3`Oë›ooú~8´±»zÉÓÍ íN»V ´Ý(ˆ–•Æßîïùdtæ'få™ph/—2éÌë,V½‹ MÖHZÖPcÅá°¾7jýÚÔ¾ŠRXì]}Ñêá$C«cì7Á'ã—F•ÅQzœ™x%&F‚}¿W?ò:I¨ô4é/^ê½ñÑS&î^ÌÖÎC?hâ³pw· õ¬Q…š£0Íâ0(3Òê÷z~Sìt¸¨ÈÚ牸?¢Ò~©:Ô[½fP¨è0M3àiÔÂê&ëÕÓöbXϯ³`JŒÈqµŽôqÁ„:Ì£OAƒ(¿ Ç ¡XmÏgjw|ú ¬èÜSËÏC­ Á¨¬L² UÖ;û7ºw`Ýð ,ÄýmRy4êµ ¡´Q³Þ ¿à(X(B_ø"(®•0‰Dç8…¶Æ/ÔT I¨7å×÷ ¤­SàÃÁh)ìïÜ! ÞÉ:ÖD€‹¼„]Áéc²\Þ÷¥¡[>.0Y]¸ôí·…£‡ýÍ;pçÕ'¿Þ_|ºEèË [7Y‹t22>Ónõ@jÁ$‡”BDQ ”âü*1ɱˆ¦<Ø—%+ËDG@Ü«ª LNd ðYØäðîB}JÐ[«Ð\á6`ÐHƒu3ýA"ˆ›ô¸¡dl*”‰¬ºõË´>¼òèW³µ_ ÝúÕúÞ›®¾ð“Öóÿ–‹LÇ„étçŽDq» ‰Žçð•m´¸=kžÔÑ<šÛ`È¢Íëq °Ö:õpœCvÔ*”¥Ë ŽÒ/ÂfGö¼¿séhXÚ`x›Ô­çàƒñ&jY¾£|ÈLóm8*u±¢ào¨ìýtûÌý…_Êò¾Æm_±1•úÂÿG³5°`Iʨôt¼’›ÏJu¨ÓbÁOzÍ8Q…é;F÷}löñ? ÝkÎ p 8£€² óa¸]±T»ò«¿ñEœ*z)¨o´‘.Î×åq¥”Vt¶ìœ¿u<YeqƒÙI˜uYvU”D…¨î¤b8i¯ˆá·4ö}<¯¬~¨»tdÍ º[uNiuUu¯Ð´©ÁÓBphÝxX®í·º)÷¤´Y-¿ˆÊc3Î^š`&j-‚랸õ÷I¿×ؼköéom8ðOÏ¿ðm¨nˆ®“P˜²…?¬Y^v"tµ³ {Žð}Ð*v-Ñ8´tàq<Ä ëÍó½’¢^iËý¥}÷&÷JÇí(9óT’Ò°®žx¤qëÇûݾÙÏ’5ƒÍ„ųp µR+ê§Qfy ¸» s.áz1`º5“öÁùþôV‡Èú+Ðép¿&ŠãÒÂæiÝÿìÞeÒyµöšÍéŠcoÖÁOÝàŸäcs^šáÁV¸àП©í}'ÎÑ Žq£ÕîÜ#ÿ~l÷Cß·øò–žþÙ¸ÛPA¦’ÑÎ_á@GñÈA&>Ðk^†Æ ì €ˆ±T§ÍR}ª³|ŠH”§8àèŠÃÛÀiô @_` úÇ!ø §;œ²vƒQ˺sÊ"øFb“òÌ{¢æYÏ h8%;Ê;Þ[ºîâ0 ‚¥DùÒ±.?÷ß%£.ÔfŸÙ4~¾ï©, …å!öã~Ï8™²ãܦìI™èËR8s·ºò¤7´%œù ÕËËG¿9uÛ§.=÷MOGÅé;·½ûó—Žý<?]q{ÏT°9¦ÂÁÞYøžòæöN Ø{d|{§5—Ú@“ºÐK༑;‹Ó7ù]dhÑ€Ž3qzá;Ÿ‹æŸÄ¹êV‡Æ³(Šúüá;rîñ¤ß«ÖÇ£þšA6™©Ö·ß›,½’Dkм'—žEâ2:¹.i­LÞùùÎìÑÞ¹§¡Ù߆#w•G€pëx'—ÂCk¡ÿRn¦ŒßpJ ÈνA|±é KS·v.>íL°ãc·}Ù¯W ÿkgŸ/Že:WV4YõBþ~ߤKBˆ±±ñ«‹óÔEH»T¢Š~=I€¶Ð*RQ”¥-*]dY‡c°qb"^Ý•¶f…«UA’d8ɃReò`»y®8²Ý“eAžEås{q< å@é@UĦÀX T7(r€ò•W­î~ Øuwtê±ÞùÇÒµÓ¥Í÷m~ß‘@¬œû5k_Zzõ/ôê o~ê'@—ORw.ò|·rÊëÞø@ïÜSÑêqø ž2UÚøvQÚÚ~ó!¿:–všÜ¯‚„È¢¯Ú‹*î{~ý€¶ŽÁ´Ûu¬Ÿs½û/EÞÆ ÿZwhêtÁæºÀËßU9ðé >Ò:ñ‹Þéïòʶ¡[¿8÷Ó?œØyËÂë?´ÉœQ-Š'|e¸’£_ œöKôú±V©3- ;Q¡:†=j7ar£سŽRk]¿3Y}=íÍãºL,e!_‰Íc@2.N80”Vnf³NÄB'pÐÎÈÆ¡É·=Ø;ó÷+¯þ 6ÜôàÂóJ¢Ë[sˆJ½^Üb6žŸ1Ë}0„Ó$QX€Îý8©ÏïqYÐXìJÆÚR ß8ò–ß¹úòwlo¼1tøwMJ®M·íhè:.,.uÇ?Ø¡C¾ýI¿Ê‡×¶}´<²mö‘Lÿ”½«qÓ¿êœý™]~¦·ð,”ÐwœDxfVL,Užð{Iäî…¤¤ ·#8ç’Nƒà„–ÞÚX YÚØ_~Z]Þp‹ ÆuñäjaúÆ ·|øÓaÞ8û$ ^-ߎkd,zeldÀW»„ºïNÈöpR|lÀ©5æ• Ž‡7.ÿ I–jr‚@@ r¥Æ;R»ajÓ¥ 'ø$îßÁ°ç2¸))}u`Ë"(@ eNEylßûW/Í: àj37€å°ù"“âì d»@jÜQ“ïtð†c4<ÁÀ]ã”›C³6™€ËÊÚnwP¬Hìèz%C0+è'ÐY(–ÊíµÅ<èÝ©¦uVÛíÄ8.—Ö6ì²®¤2&¡ñ‘8ÿtQö S`þð+CÔ‘¤u:(jD¤À¾Ãê®  ¯±/sF€ÄqšëX E€žâ¦­Ê]+ZN<²'OúTÌŠ,*ôi‘÷Îü8Rpªï;ü&*s~Þoð'ÒŠð‰ñ°¬pn®¸¬!°±üÑc"ó꥘D§bÖ!½B`MŒ]ÉÖ€4A¤2|Sa,JX¡E*CËf ø¢®M ··i†Ó )$4Û9­°r©#4<¿Ï›wàäNµ›qáñTÎé(P^ÄÊ^ ~°H!éàÙrs™Ë™Í[¡<ÔEéÚÛÄfÃ!~ŒÎ÷í|]áã‡`MHp÷ÚP°Âc½~ÒÇ MŽähÞ¦u67/ ޵(Œ!u#) /œ/c41n ª¨¤]!à`­Pò70IÖM#¿ùÊd¯¹ÐuÕ¦“ “­ºdA׃£<¨S((|[xÀã@:«4ƒ|q(ÑTiwdœáA>V p~QpÞm¸¸`Y÷ÅÃ2·x-Ââ0š3¬N%|Ô]›fÀ3î¿ÌÇq"__{—ã#Ô™nŸ’t`Cplî n˜ ²4ÔÉâ#$ÀØÌ)± «"‹< ÜzÜ9Ô:D0œ¸ AñTK€áy=vÊù{!'ÃÒXw÷rDõ°æÝoŽluW¼° Ú{“,Çsî¯A¬btXÞ§ b¢> ¬¨@$Ng×$FÜ ¤‹Ò‹4 [¹»Î ×n±®»s/öö(™ˆ.ã^¸Å¸£``'c‘ñÖM‚[˜sqλ¹#€ Y«¾,Ê;Tï$t©¿­?NÈÖ›4Ü)GÂA> ±|ˆËÔu ‘Z¹ÒîE.žM°Õ(VPçÎ g¢b1`BÜ «Ë~„0œПäþ9wËÄ=Cs€­—°+&ø ÷ë*^¤ë…|­*` åêP¯ÝrejŽÇ@>‡D5ä©{–B!ŽúÀRà€@! aÍÂó‹ N \“J¥£ÊkˆÈËα”c9ƒIäh4‚@Ë8! ƒ¢p}Ëzµ®×­#!”/— õ¯rH9¾„A%R]Ž}œM“u >|¢X/w×Öœ 9)ŸâøÑp µ R< “©Š¡#ëÔqOª¤—C%?”Ìh'á\$\ñ3(óÁ’r†ê–C£âüã´à7»ú­—9Þ…JtÚé´p&À˜;]µ…R½lš&àsOë Pždè(RÏ`ý8}¥d½i.3¹1s×Mõñà1§]ˆw§„Ö̓ìo‘$u4ëõº»£ë›¤öíÂuš°è¾ñ”1ð ^·Ù ÂΚ(°uêkÀ:äW#¨-“%qâû•ÄN¨L>£¹  ƒêØOåƒÑüv¼‘¯à$Ýr²|«y·‚m—ÓwìªDêŠËÑj^&Øñ:SªÝpë¤T’q?ƒ²Tºïy^–h)=<«†F)CÿP *}›R”PŒ±Jñ1(6ЈÁ»…Àë'¢ÞÍ’kdèöâl€»Ázä€Ñçi¬ƒ…^sMhôБûI´ôùc{!®õÚümÍ/%=‰OBga ¦Ùó}e…Í€ˆð¤ïyÒ ¢N®0U‹¢¬ÙÐý%išÙuq$ëË"ƒ^"<_¶€ã€u–ÿ¬ ó³ :¨ý¼§BŠÓë×Í«ø·XÔ©‹{.7¯<§%hÙXµ\¯Õ—çfÁ¸0)Ó$A9-ö| UÁ qiåG…i$d0ÉCÉ u½&hŽþtÔzM¿ãæÐÄAœÅs=ê¢>h€ÿ‘ÓuDÙõNv°[Ð$áAGÌe¨2c|&DH¸WìË"(¯Ç O :ë$NMƒu':¨çÜ­¯i>N±øH<•¹~]c>»Î/„̆öߤKƒÅrh|znP“ÇÕþ¢®ZC•õd0L4¾k£fÜá&4-¶Zj¶—¥ï©¨µŒÜG¾Åx–B^øúq’pÌ)º…õáY>^süÿ*À`HxœEz œ\U•÷»÷Ý·Õ^Õ]Õ{§·l,d%’FDtü::ã‚ÎOtà7ú鸢¢3Žú©ã2(:3™„‰‚BKBBBB–N:½¤Ó{wu×^õÞ»÷~çÜ×øu’NwÕ«{Ï=÷œÿùŸ¥ý¶ý®(ØÔ!îàø‰_¦Öý;yVÓÃÍ7|’hd앟/ì1ã-Fý–îw~ŒYÂ)™F TÓ5¡áwM’àKÓˆÔàÊ …—5úBcTóü¨U²“V}*’t4jPI¹.aÆuJªšnK\ ^Ñ%ì+iœÀ‡à¢™°©”ð+Ñ5 ¯Áƒÿ†3Û|¯„²l^Kvß‘ºþcÞÄDiêPó¦RßÞxãŠé Ï´l¾ÏîÝnKK(#H,a8¬Nð»„WAð`7\ŸÂ·hM“–¦{BèÄ%C‡ÇéÞÞ‹²¢èRçp8.5hU@Aš:=è‰À?M xÞ! Ïk‚[ÀsN¼—P“:)éÕDuºaÕ»¹˜zý j†$,æMK3EiÕI®î|ïW#‘´Ðmίƒ’I°*D¢‚(ƒ¥• ðOâá>È© SãW^=87<¤›zÛÎâéFuW€õ˜@½NàXp ø?éB”*ð!ü¢ X^Ç‹hÜò=‰{…q_ø… »©¨IÔ 4ìhY²Lãš»§O=J™Yz{÷;ï ä°«„Å%ÿ‡Åᯄ=u¥_À»ø3ˆbhŒsÍñF›8ô['¶,Ñ»£ýmëðô Šæ°AáStAZ¼bްà 4KPÅ×áòÚ'ÑÝñenuàh~nç.¡ •Ù f´ýíÔŒÆ:Vùùùù¡Ã¡Lo÷-Ÿ‘&.Ž. £ÔÊ4%°&$'Œ*›A ¾e?>!L—âÒ¡ç¦^û£(H+‘hÜÚzý­N:J€U â£J½í\€J(Þ3Z&Á€üxT=†¿h[¾6a/H”XþÞüàŸ¥?[þAâÎæ.ícN“ï»T+è‘éîºå~+ÓĨæ K£7Œ6‰w ‡fü žXež Æ=w¡oèÅÇj¹Á‹–ÝÒ²å}ë·X 0ÖÇGÁ|à²(ø …5A <Ü.è;0S<—¦lWM[÷Ðäè_èáF¸°¹3¿Öõ2«_ëÍÂq­ô*?wQ”&ˆ±==wˈڰ (ÅÙW‚ãhR©I­–6Jñˆ°¥Î9·ˆQÓÆ^=pùà¿2N. Å[’íDÂêܱ‰úðœG(C?@óƒãý¢:ŒðK) ÝMe®ÊXÑþ—~𕉣¿1Sß9²ïËÕìjÅ¥—7cfª7¹dWaðyÉy´e}ãª[\Rušà²ÀOam„ À£ÃëÔ êT½hLc>­ygžÜ[;¦G]·I/6£=­×ÝZ¿ª|,p^T*Sge((“48x:Ø\‘>Õ€ž µÝÉs—ôZB +*^þ³è…xù‹ÄŠRÍbɦZ.—j^ízG|íæP4!™Î”t‚QË×<Ä8Ü#”9Q´P%„BjtcæN½þæ•7^. 4 =Ôr-·t¬ZŸZÝ¢ †*`\:*]óuXPá?Y5®ÜvQw±DêÄ2Üt³æNéF]¨ic­2^=ܼýþÒäd-7¤;¦ôYÓ¶“jÁ+OÔ­»ÉL„K`ñK"’IDFC(À3È:AM þà_猵ÒtõòÞα¨Ž¡FÛªO¯¿¥acGXè`cêØSK  zZ(^#£¶Ó¤ò-µâ3±ŽM3g÷„Òëë: þé+©Uï‹4^ã¹¼Zž©ëØnéÔ¼Z~ähÓš)3¥§& Ñ TEe˜\šB·@x ã×’p|Z“sýçŸü7^ž•Fê[\¸8î-½éãFÂN/m•†¡k>Ñu@F…–¨ÎR­ §C·"1"ƒ»«X¯k‹ï>d5-v'ú Ó.L]œ:ò­ä’[®í‘¨íÔwûÕÙÙÁþôš‘L=Ïå˜iÑP” „HÍ@pÀL}ã=:.5!ÐÐxˆÐ•WdçÞÜ÷ß•Ù+µüPªqÙÔ•ñL/¸¬4Ó«ïüÛxwÔ§ÄÂðÖ&$Cƒ „D_ƒ[ƒW`¥|]!*,}Ýw½ÚœÔ#:HäWæNþ`Wº÷ŽE·‰s·6?­Û Øì…Õ©ó`xpøúkv&—m´+ˆRÒØtGQ]€KÿÁÅñ›ÂF!øèá×ý¹ììÀ«¥Éã@V’Ý·ÒÖ-YN7dVÖ£, 8–‡+þW‹7,t<Š®/u§ÿß¶~]òJ…&L&@ãÄ#[B‰ÎÔÆO†ê¤o§2óSýçžøR«>OYHgM›ü-‹ÆÐ>¤òM5ì£`[ HSAYÓ ŽoÎçÎ?÷ éåæGß0 ™È¬&¦Ã5Ó0"«ßÿ»)f@ ÆXŽ1ªƒ¡äR…H.(\ ,Ã=×-ýº¯³b4ìWF§=93øäç5îmøüÓµb®’ËYÑn›ÍÍ÷õå²C3gvÇRÍ‹vümhÉJp"4rA8C†hH@!ŸÁ½ åtÆ[ÁWÅ}]úp+Å|–”Œ“¿þbnò”Á¢ºã`t¥õ-+ooº~s]w @^3àÿ·Â l¡B¹¢)jY}á$X¢Û¿ëÂoµ|¥–Ÿˆ¶uœûÅÇ*Ç̵f¼5½æNÛÖK^-ÝÔ4Û?œ=aÚñE×Ýi¤âLñX¤qD˜’úŒ³àb©R?bŸ"p>æ5ðÊÚèÅììOW&Ï–'^7b1M&B!騉µÔ­\fwÄŽ- d5 ŽÁ%dˆœ†P ö–ÁЀú‚iQ¥­_vË…<ž(P‘ÞÿøÿÉžÞ­ÇZ»ÞþEAŒá¾MBuvÛ½7¿çʱj³—ŠãÃkïû’‘4mÛà Ø% †B®È €qé/&*}XÏÌè›—«£GÊóÙZ~€gGÀÖMæá¶póŠxóúž{®3õšILEø‘< ±@Ô/C®þ¬ëmjÔßñ ©;%Ï'†IGÎzìòŸ¾œ\v·Ó¶yüµßùs§ˆªë¹sùŸ’Ë —fÏîeg¶îŒ2é1ƒ‘šŽLhàV9¡ÁE+šÑq17–:|¸<ÚW>]) …âíº^sâ-n¹¤d7ËïýNýÒ˜C…k+3WKèd!U!Ê~¨ZŸ,,­˜Îßöˆd²|éOO5®Ù!üÒÕ#¿Ì÷íŽuÞäVªÂ›g‘æP]›çVW¼÷Ÿô¨Ð tÁÕ=·PsKÅXKA2áꚘå_¾¨âZâ§Ô\Yçåjÿ‘}<{ÁŸ¬ä† Ûõ2;iGÒ‰eµúž4¦™*«ð¡–`¸C¾ëC¼Çtø¨yÍQ4Âo|ÄLLô¹zð?›WíâÕ«£û¿•êÙÙ°á½Ü6ÃñEÅâLzE/#!¸TyH ý•ˆÜùãC¯^ý‘Ïê€>†§s3È5ˆ· h} ì‰OÎ=õØÌàa87ul77MdÉŒ5ÔŠ•HfyfõÍÉ®îŽk;%eà;t#u}vTj¦´òë£I¿ã¿Féå}Ï]8@˜% c’íôÊPÓJk‘s#™öÆXï;ì–.â óeTrÀšÉ/Íž8Ü´ñ–Ìúk˜P´%ÐÀG$ǰ ›BVç¼ðrvä¥ÜÄ9Ü ‹Ü´¬MÓ Vcï¶OÐLC²»¥iQ´cò@03#%_B¤]à¿Ü÷A3È©¼ù_¼‰Ásý¿ÐÍ]´B ÂpüÒ¨iF5fø^•øÂNt­ûÜïL+–n@—4ç–‡žþ/wæ||ñM=·îÒ9òN.äw¨.Œb‰ä•™ÒÔ‰‘ìðÑÂäÅÌŠ{˜Q½ø‡¤ i†m²ì‘ìHo{OSKÜ®ÏDR!”‰´|+P¨j¨•¶¨ƒðÊ´J†¨ám~h|êÍgG_ù‘ÆEzÙÛKU^=È«Ùxzqaæ,Þžé˜á†î]ŸJ­y‡é$ˆѪ2uæÕËø­žhÊ´­I.mK-YËà·8‰J®¥ 4Š_sfòÌ ‰J>2yê÷S¯=.0z{¦Ñíz)Cf"EœÎ ÷Ý—ê®7Æ‘ †±Ä*eÑ!»Í—N4÷vÙ ¿qÇQ®TóN¬µ0sÑ»ä½Ê 2Y@_BB‘Œí4bm+î¼ßnï412º—_Ü“žÕ£–e;­«¶D»;ut¸6[àþ(DS% ÉEIxñ…™‹ùg½ü(ƒ¬ÖLEš–æ'úTJ¿oYݶù¶Ö-½‘t€™¨jʸ•æi(;ägL7Ë'vD3Ö’·u·nþç¦mSu‹ã‡íزáÜÞ_C ©¼2>ˆ«še2bÕµn¨eÃõÜ®DRÍúgžø©'â±$Ë^<Ú¶ãCu‹—è ¨œ‚\>]",àð:õ×,1ï^Ø·gòʛիà¿jÇk¥I3Û¶|É‹E#ä„3Ý]ï^ŸHpâÛÀ(<]ZèÈ‹8…o ê üïëoxþæ‡ïoÝø•¦­·;©k•¹³{ªs—)ÚŸÓítÓÚ÷ÍžÂóÝ"¬Ï,iØtk]ï¦ì©gGÏ<ï—‹©%7ԦΗJµm|ßÙ&$ð†‡ÙC'ù‘Q.jròøxÿ_Q^(dûX¸Î¯•E5ï¹yÞŽá.'ݺhݽÎ⺫ŸßúÑÛÈʦeꇀB™>妆µÁ pÏí=8zbj×îmY÷ÁÜäh-?#y™jEb¦Ìp¦6{^cq3¹Ú÷æ‰_v"Íu­íWO?Ö¤Gyù>:†å=•\~«ä»Þ}_lQ‹A"ibÄ}! Ø´Fr³…âð¬(” þüú~Ys'OÿDOÓN1#m^îìÊMÏæ§û+3C×?ô݆åËLp4XmQÝDzQÆ-‰ÌZ÷÷<ðmË›M©Pb™ð‹,±LŠŠ,ME:vØVxâô㡆k×}îQ Œ£ÇÏ{3¯æ§ût ´ ø¢#Ï…Û¶toû«sÿûͦå·™ŽewÞA˜À2Öfh ìnB¢ y~Ñïéh¶ÿDþj¿è˜íÆ0LÁeªsuqô,²¸ê©ŒNÖºnºá›á¢™Ä˜€`ÅU-|ØÒ½#>þBãÒÕ­ÛÌõ?ïUó ¦TÏ;W°RS'w[vŠ$z˜tC‰…‰˳à¦1ñÆCŒpjñºÿª:7qõÔAVç´®}Ç] ë:Ñw± ™cIDp«Ü•剾ñç.z¬cÓûÂѶѳÎ1§:Û'y …¢ÑTó†üÜ'ÙöÎoüÀÈ€?y:ÃdX:¥>p[ab‚arñôwÿ£<8ZÈ^lÜø`¼yMÝ’kŠÓ——¾íæç¾|w¦wë𡟠^¢ÀžáNáf¹_"A¾'@·Òkßß±õ#÷ÿL"Þ¸¸nù††ÍݺÕ!ª(»Òñ}ßõ-Œ]rËóYwâГ}ðkyÐ)¯Ì©œ)|Ì‚« fxÇ´nìv"!üPàpEhÙLßpý²E Öþïí8ö{pè¦UËlùHÓªõs3SS§Ž¿ðM"«‚çÁ?ñF-‰ò ÈíìŒW ÌÙöÉŸ ŸËæ¯hXvÃøk{7ýÍý‘ÕËLŸaK0gôƒg‚äxòjÙÔËóã¼xñÅÁãÏKž-e/ãòZk³ºÅ¬0bÀEÕ’4÷^—YÙ998qÃç?mG ³¤'¬õ={®eESï¼ü£—†Žþ;)ç¿ûç©·$’Õâ™þ¢ŸëŸ:ùŒ_ѤK­¯å±t„@ª3Ãð}aÆ—E»6-û­Ã‡_ /Ú:}ú‰ôâõ~­VŸî}ÿ‡Û£ c¹‹U&mŒÖ˜æˆé—Î^zå¹ÜÄ…xº§Xž¹RvÔ¯•Ð&©gXáP´¹T.™vÄ%!;”¡žW.ew>ô@×Öeº jœ¿ö»Ã™eñºæ¦'>õ ªzsSí[¾”^~ýtÿ‘ù¾'p}¸ó†Îî¼´ç_'Ïìµ7±Å•Ñý˜  %2¡Æk3«v¶®Û)½é3û÷{Ó—æ&ûVìzhðÄ“·|áŸ]1_7<l_ C WÍNLûÏŸ|ò·Ý;Þmí|éɱÓ{©ÀJ¹[¿ƒT¥nÇ$¤VBÊH¢¡£’.^yÛW?gë í|ß”G~|†Øþæ®Ýý÷_¨ä§JÙ±xÝrWf¨³V¤&pÈX¸cµŸ-\=nÚ¤³Peæw«š(Ë o„ÖÜn^=yö…Hã"^˜›ŸjßzO!WmZÞ“YÙ¯OR8À•çI­È/üéèȱǖìúp¼k]ipðü3_­Îžå˜æb C¦I£ Ê[\™»Ê¹K¤­ P€lXyݶ|¢¾«AOX@ËÅÂåç&ÆûG–ݶüÌÏd/¾–Ÿ>cÅVY‘TÝêäÇÎX‘4„¼ñ7÷,»îžó/ý ”h—Äv #€ö±|Ï—|žËŒD53Q×}kväB]SÏÌÙ'µh{fù.;,«~ÍmwÇz¢‚9\å1g¬ùÚٓÂó¾Ã‡æ/ì ×w”Fß°¢MÅì÷‹T1K äñ#½²ÀiÚÌŽs-ÚtͶw=|?Ù “ý/ŽÍŽžïÚ±màÀ>j5ŽŸz|ÇÃ#W_=–¬O²ºEã§fû´n¿79>|à!€*ÓJú•ð\j‚VÃ^i²~ÊÂÔ°ÌhcËÖ W_Ÿ~s·Ó²!Þ¶:ñjÕP´·wõÛ¥T©«Î‰YÓ9›<|ùäþXʰëS­õWî™Þ_+Íh\‘%0,ö,¤ÌXHô{ù–™«—×½kÉÖ—Ï\Øùwo÷§r§žêã)f‘ºDdôÍKIoú^V‡¼@L(ÿŸŸhóMknN´-:ø[‰VѬæXº½8z‚Yç ´Y+MÅÚVÙ©E•ñKfç áDÇø«?äµbˆ۫ÅJizdóG¾Ú´ºM`tƺliÚë{jÏØÅS×~ô³éž€tV•/ÿä§#'÷¸¥I¦‡8äöØ«Á>Æ+“é†ÍÌF;‘.Ï^I¶oißz7/å­Œ·òÆM/ýl÷ÜÈ·0,Þ«ÎzÅÙÆmÔ/êÚ~¯‹Oœxzè¥_-ýÀ—#õG¾q·ÆKõk?¤»óÓ}Ok,Nö”g/1­âAú¿ÜôqÍé)\86rê¿1ÿ ·ez6±lØøîÆõk›gà°f—Çæ¯¼r´ãÆ­±LxnÂxÿ‰_}Ÿ3Ó›æ ¿ir ®Apa"ÿ–àÄÔ[¤:dÀ2=×¾ëÛŸyõçÇ+¼Z¿rÑÉÿøŸÂØŸ%'ád›2o3C F¬¨zuú'VÏsSãâå­d¯_ÊZ%ÀÇuGƒXZGÂŒhÃr§q‹àðÔË~µíZ_É^ÕX8ÚÒ¹ìÆÏ¶®‰›a†† x„ýßÍÉ£ÿù|ö³nþ¢Ó½ bèØñS ÔPl*ÄàkÜ+NFÓÃDs£[î)ÏÏ q°à–­¡têÊ‹¿ÔjYO 'e‡štÃa‘V@pf%)Ÿ‘´}ç·räß/ô?S·ü>Q+Îô ¡µ,à˜Ïbcµ=Ù¾þÞ±ËÇ«Ù#ó+M§»Ö懎9ÍÛ6~ì£KÛ%5t€-áû!CãµùóS/ÿôÑÜètï½åñ7æ†HH;eM*n¦1õoÀ'¥Â_fÀmP Ü­>–Yä¤êí¸íâ¾'*%ˆNÓ•|?Ä&+ÒYµêÛ×}hôßø¥.¬­Ÿþñé§~›¿ô'‘‘Òp¤¡TžE]ÁÝzîà2³¸& 'í»%솘!ŠufCwâ&|K.ÛôéÏÕugò ß2q÷|ê‹åé©Ri®né–êøùñK ©’“²¦zQX‘”ªvK± cS'f†ëýJ9³rW$‘˜Ÿ¸’h\~ùÈï˜À¾ZiBçÅ%ïù½Ÿ¿”lj:¼·6wZãßH®Ñ´Zuæ"µmÝjñJã& š„·àžU.@V è&¸t­*‰àcDúfÝ5Â+ >g:ÍïüÚ/ †%Wu\íõßüqàÔ‘böRur8T×)…0X©œ›ô+*]Â"‰K1ÖCƾK7UÊ@?ÊÔ‰Fë‡ë[‡î‹w­/ž%´À}i°xëö¯ QžïN1mB•?,ÙŽl2”hq1ݘ•ørŠˆ*GéC@ôPFú<NÏL¼N ðwmf4 ™’¦BÝöõ ¥l@æ‹Ùqíôž—gûŸ›8ædšÛÖÞ5væ¹ìåg+… U¥ê§R ~XzÆò¶‹(ö4uË`Žo#SÊ]Õk“ÂçàîÑÌZŸ/NKåûª®¥ ˜…±·à”Q1·…d¢ŽQÓ±#,ÕVÌNx¿¹Ùs 3’¶‹eqÌj\oß2ñúÏõpË]?z,µ<ÃóKæKÿòèð‘'ê;W%–oîºfÍè‰ÓWß<8Ý÷ nPR ªšXôDÕ Ê,Å,l3¦m‡ÀÅ=Lú‹ð/Ï Óh:d@˜ Aˆ ÅÁrüZõ,°EÃô˜F<´FøuˆtAíVrqmʸ%_ú~ª{ÇTß>àÁF8 4ƒÙ)Ó°Céåå¹ f<½þý_Ztm‡eëý/¿rìñÝ-«¶oþè{FÞ¸rì§ßŸ8©S–C\f fVªµ©ê Y/TßS™›°O¸%^s‰1² 3ÇJC}.! JâHví)³Ã^µH0Oá¾_Õiƒ£Ù– ËêRíx]Ï–És/:ÑËh —s#ŽX51lÈ ,ÆÛWíê{ùÿjF*’YsÝçÿ!b:Ï?ò«ÕwÝÛŒ; ·^9:yf¿ïÍ¥'Ä:÷ªÖ<ß aØd4RîpóÓÙþCºMîÖ4pA@À\0.¶x‡[¼MJ·@tÀ+Op_ÍzâG·áX†iJà[Îøœ=1Ä63ÌIì@GŠÃÆŠ3± 仺™à¼`Gm›nûÖW"¶íÓÄ;ùØYÍõڱǿ/E Ì,V•¥\eC:Ö4ŽÍ:œ5!F¢gÅÍÿ8}zO~öRfÕÍWŽìsK#ÊS¨òwbFZÃÉ·ùc —âðåkš¯LÒY(9âyàv™ƒ:3Â21%Þ‰µ]“=)ܼêšRå|’YÀ!iËÎOßø‰¿Ž¤Cð9^¬xsâ_dü³^y[ÜzØÕ{•IŸûJ bjJg,˜]O¬ˆÆsTOð 7 JØóJð®Ðª‡deÎm‡›˜aƒÝCH *RJÕ´Áš>Ö ñ’p[rÆÂä¼(À/ f¦=÷*èÙ Xƒ»°¹; Ÿ¢³bж_¿í¯vtÆç&GŸø;“矅|Æ §x5OÌúú¥Û§ßxʇMºG+|‰À°þFBÌŽñjV"uiªÌÏ0'â–§7õÄ"­:ïW¦@V 0¿ÔÄé j8†€x)}©†cÔd ¶]TЪ8l)Ü#\$©sc;;ôLŠØ¡fâÄS­ëËÅ™Åë¶òß@2sw?¥a1 :˜¿~¢<'q°»dFq0{7©÷+Óp8! Õ v²œ:5<<„U „KÉÓª–.ÄŒ ÁЮL ¨†HôhˆÈR™~DU¹q5ìÑê@…æé@v‰Ö¹áNÍLæ¦.Ï\>Mwf†!Ž3#„eA¿G AŸEÙ*XŸ‚R©¦ƒ°ÿJvÔ\Wz90ï@N„t,¢k8àÂø¢¦šŽ€+¨A ° Z:ºnd*žò eëxO[èZ«ª¼š=Â+ &t3R×™ìÜ:zæ~5¤Kƒ,Ë›gFa•Ü4ÄtlzcY¨:ˆm »!”Âñ…îD0hâ5´¬±;;ã”™ 5¢4L¤jï)7”¾†c¨†œNy´¾ÁÐŒêõ®ñØæj)5°C”=€‰é{˜n[²õç÷}C’*æ,ÔÄ‘ýðð@<g(T>C° ¬ã‹jdFv€ Áq M7 ࢄèíh¤TnÄ á[SÍÔ˜„EÁºq}ë>*:#Ó5‚×Tc{wØ#Ä„ÓJÎ¥¡.«u ¹w¼åš©ã@óeÐëWãUêS2à-ªÐ̱_„+ðN”q«€†ã&êê¶ûÕ¨ Gû‰É É§t«-°ˆ A$ÐÄ9ð/ʯT’'ƒÞÊŒÓ :N^a±“cË»†Xu’  Î#ú> N4Ÿ{Dy^UCá’ˆƒTbë Í ¬… ešjâD †AUÕ±Á(“T=Å@$ 8®f" ¢©øA$P6ÎðrÑG|l½#ÔÀA¾5"ƒZ 9HI˜š'Ã*ƒï{j€&Р`ˆzµ¸¶¢2Z0;©—`”K-&ÕhˆšSPã–²Ÿ(ª]ÞW2¨y@_WÊ4”ñsЉF†Ý‚AI¼ƒÚ_zŽ1Õªd0Q¨¦Ö°) pÉr¨: `<8Œ„ôgç”ý |) •BQ3±©S`Ú¤vï¥J>‹ÈD£ÊT e8\j#‹BûWF#¹ÆŸ“GvI†b û55ö…Ôüá ¯ð¬ÿ20E5G¨ÀYñD/T(ê‹q?P‘¶0ÿ!ƒŽ”¯Ž‰:Ñ‚Q4L¬©33¦ú46ú5¯B>»Ð¼%ê©…‡]aA RHåp^daüÏ¥ë¶ZKpbÃAP“ÃŒüEW–BÔšŠU"@$rÔ–˜ƒsE p2–v0FÜÙˆÆ[=-µ"š™ˆø/2 ýX ÖC`œ×D[8’žªÑÕ`åÞûéW¥?D"EaŒR†`*ö‘E¹‘ŠhœŒ›åJTb!)|m*er2lÌÈ ""ˆ`l)aJšnuÉüÑÿ!×ÓV/-Åõ­T¦Ðwô±úÖv[G÷7_bfݦ =ËÉÆQƒ*"-b'Š»ŽÉ¸zôã‡ç/ó]Ç­Á}‰„A©a %E‹+ѹq#®×rmŸy56F^Ïð~WRwóÚÒ䛋mÅ®Ã?·e`"©QL#RÁuˆKËRF†Â”p=-Šƒq2dªù+¥Ë/žÜ¸~)j.13íd:•Õžkc=ÃK3WC·p¶¾1K`ªvFúÂI&XºË¶íÂð°²s»îî ¶j7NM>øôýÇœPp ‡c)kêô‹ÊâêsoHx'ÂÊ0°8QÁ¯Š¿ó—ß•Â9fFµ}`а4w‰š™Z¹”ï+¯NP ÒëP‹å ýwÈz¨É>ÌôeÈ;ƦTL ÅP•‹w´9ýÊÕÏž€ü x·;VˆÇÛSKç¾ù/N¢Û«•xi>?¼Ï6íHø÷þçgþvfijgÊóoNÙÎF­wí¿ó™ýtãÐøjGb––.'·¯]“Ä<÷TqSFPXŒ&ÍU·²tÕ@5j§e“vÇdõæ©G?ýÜäĦܚId'~ùñÓ''dmäð‡†ö?dBb‡üÄøÜÍÆ•÷Ö¸Ê,:÷ÜIÑh¡˜‰ l¸¦-œ|ozb!ÚœDÔ”‚ÿ¹‘§PŒgÏou t­\®o\}#ök½?<”È¿ý7ÿÜ\;%p.›³ŽÇbalM½€’¸àq€0G˜*)M3³É´™Éõ¤ØX™ºˆ,AÀ‘ÌŒŒåÚö t6êë‹ßJ¤r&iüÎ7¾@¡'£øÒâÇ7Ö&o|ä÷]^Íl^YÿõÓRiÑÀY›‚mqòo¿{s™öqáW¼òÍ8à±ç§ò»2}Å­©ëÝ£{}êÙ•ë+‹ç¦ûö\yåŽGÚ^›_¸ü®mŠTß‘ xóéBŒìµóßRÒ§@Ç–Ñ=öl6…žÍ… ‘W¥*µ÷}Ï5ÝÀˆ7Ë+×j·6Ò};Éë R²Ý;N×áGÆïÿÜž," :w-ýÚ×ÞöÊs»–faéü™_=+ˆÒ)^†4lÍV¢º?ÿöo»ÎÒ©°²’.Ú{?ñl®‡ùM¾¹zóõ«½#¸wl´V“sï¾ÕVëå+"mÝc!I»{wŽøžÕ™è'öEÅkœ#Ê+s¤f䤲Q£ |yø©÷ízòñSÿv±tíFäms¡"o TÅ’H‰ dÕ´³@c=ý©îƒÎ@ñµ¿}«½}ph_÷à˜Xº¥~óõ†P(1‚ªÍk—&æÏ^ŠÜRïÁãµÅ¥›¯ä÷ñØô±ùÅD÷1wÛÏßm ‰ß˜ºU§Ò=‹WO'ªìö§¿ô»…f‹é3ääÿúK©ìÈÓÄ⥅kXÅ}£Žö“§¾÷Z×PûÌŵLÿèâ;/(Y5Óé î¦2J­8rm;Ńš‚á1»}p4Ž•[^Mz¬¶¢þðξÃÇ÷ÿÆY¨ybËØbÆÚ¹³Ï?¿ó؃֖‚ŸýÝßÄþ&t ÓLÙ©¶;?ñ9#’Ê´'^=é6“~eþ"$<»ãðGÿüóQ»k•éëêêóLQÐsèîí—~ðÒܘŠéÙ·óÀÝWϽQ[Ú°m4\h J8ò$÷¡G g %‰€”z „‘mcš2d³T6Ûeعbß.f*·4Tê¿vNA ˆ‚¸‘<¢€¢„¹ ×tvm Fk‹ç3Åfy²¬é¤GŽ~‚$RÔâ—^ü¾e‰|×ø£­lÏOþàÿdººîüð§CV¸ø£í} ~éÅžûdvÏÔ«37ÎÍ5k³áƬB1`43-Ž•ãt·z¹ŒçÕÅY)ÙÎßs)¨p#1³R6¦étìÂLÍŸ¹UÐ3nsë·ÎGbZû ꀋ¨Þl–ÅËÿíK<^1sCÔ`îúE–è!´^!lzcǺŽ_93ŠJמ‡šK¯ùÈS/ÿÉ—). ³Û03éBMZ—ß93üð³¢îøÐ}µfõ­¯þmc{àŽÝ³T*]¸÷Ÿ¾üεæôi¤ÜTï'K·Þ¥ŽÙV¶2¹D× ­ÚÖ¦NYwæ.‡ÕR[~wuñ"¤lÏñ§·æ'~ãB¬Å›àÂD:{HÕ×¼—þèÏÝËØ2Å!h¨ Vÿà¯,ÿ±·u+ò#ƒWÓ½£’ä¬öCÅî¾­éWö>ñ jM_íùÀgæß}1•ÏV×Ö•¿ÆìÔÈñ‡غ5³yý-Âbd0è;Ù &±:ö4WpìËnë­WÖÂfÉ øÞOüwÍŸûÉ÷tMfǬB¶´4GUdHaeò†Š¨» £ûùKæ8°Ø’õ©µ·¾þ²¿=Ç#v9T[ª¾ý?/ÕÞ“jß'eÐyð°•Ù»|îõÊÔk1w #;=ý ±ÛÞûÚ?Uΰü ¡¤±zÉ´Û„À"¬kj²D¶}쉟y౟~埚 ?ÉÓ9zoueÅJ²ÒâœÝ¾+®n d»FªëÓ¹woLÝPbÓÉõbÖo¦²B5£ÒœBmR™L†Ë(×Ó'‰ÓÜZ¼Qé ç®à „¸úoW+[«ÄF»:\Oÿø‹ÿè/Üf¶õø3ı3»y£>|ÏGC4W¶îþàqÑ&'¿÷ÒÚä©TïååIî.È8DvG"Ývƒ§ÊeÓ™þTÇ>¯¾|ëoQÒ4@>Ç î…»†qŒHΈ6e hN9œD2"ÉB/I¦dlõMÌkf"=4~¬k×þ‰×¿Ö· ò;îmTZ»ú;çÿ¥Ž0æ¶®çbñP×à‘ßÿÍ?Ujƒ%»h&W9 1U*tÚû3ùÝ;äºû£89ñŸ‚Ú¤‰T~烛×^Æ¢®"o™žý7*ÛîÖõö‡D³±çØøòµÍêâ«Pì;pOuÕ_¸ð]éWÁ}&ÒÔÊqŠÐôÃ2Fõ\çNÖ6èdº«›7›kóPá>ô¡H±…w~x„ ¼N躟¿â*ekߊeP '^žT岨ÆW_|9Û9ê7Êãïæü7ÿÐNv…ÕY–L@õúî6FÖðÃÏÕ–ouì<´4ñ§óàÖµʰ(‡-"ýð±ÿòÇ݇Æ&¾3hT–ÂÈ禸wäÓŸ<2úâ}ͲIeeš »ëÀ=w>ñ¤élz‹çÏ.¼ùåÿm§â=÷ÿÒòô;±ˆÛ{Ö׿w«Ø³³^_ª­MƒãFÊ3™Ã9ÿÂD žÀGR¾wëÆæÄ·OoM¿4¶Ž?]›™w×NaYEaûØÝÒ·©­1B×IfRù>ŽsÀ©õÒrÛȾ³ßV5ÓvÅÃ=O~j÷ŽŽu»¾´QÞ0n¼1½|áÍÍ[7ÜN¤Ú‚X&Û;ïzú—ïúX·»Ÿ~áÔõwNT×Cw<ö̾‡wUWëK³Î“ÿ bp 4 TK°mH®ƒªùí éµ*±5]žzízn¤éÔ‰tïÎ=¾çÜ×_\>õ<²Y¾8ê%idÝíë2,™Ì4”°Ò)e³w…Í•`kÅó6KÚ:ö8Áž=ï»ÿ·qÇ0øÔTªV ôǯ®^~=Y´ƒ±o„>q Ó¡±ƒcï?Ôh ¾òU79¯#Ìò»÷Ss@ÔÖ³«ç$ ‚W¡ÌBÊ4Ì÷–Küî%e˜2L‹?<ŸÜúþÜ;çÒùήñ­³ó+7'Æö——×o¼J­ 8'!=Ö›o·eÆLw˜{ù¯M4Å£&(LœØ´Ƈ?òÉwg(_X$gr¡6÷Æ'L, ËlT7’I³B>?ö¡£¯NUV®gò}›Ë“"ÌLGÏÞ{±ïm/]sËsR+X@ÙŒ±IA…ѬÂôÿ §EFlFtáò´Wϯ]¹P½u½½ßõ÷ÞѺ¨Ø0µøO^i±4{ùK@ Ps\šV:ÏÝM3]ä~ ƒ"Ô¶RÀ³NgÚ÷ ¸ßw+nC¹µ‰¨FÍu(ßžCO”çN+mpÃ.vû^Ô?zp{z¦´1- ß74kŠ7ePUÒÊg‰ôØÑg&O}W†¡P±a0l§þë uOÞ¸¹=ó“ùr}2=°«º°¼vñ‘¿…%§m–™oßݳzõz2‘©×Öq“~œH’LÇ¾Ææ,JH¯¹BRHqº³Ë‹fõ$;F«Ë7‹Oÿáo€#,­T_ü³oK¹V[‰\`:XÓÉö†A eèáÇ·7£™Ó¯3âš©îØ-®³œÎ0húw6*åfeÁ‹[ëf‘ß>]MeÒðÿË‹ÿþî ÈæÚ|ìnÇÍ:fN箣ýü|®+.Žô¿ñçÿ7ëÙÎñ¹w~Õ—õj ­â#=õp.8×7Þ¨, Ï5þްZFÉNædyîSƒwíì¢ צ§¿nabbuê<Ô%ôÊ™îl+Žø•†Áüt!ÃEnõæY"k½;Y»uÖNØùÁ½„¥7fÏ+N‚z„²_ÊG¾tùè'÷âÔc³VWÿú‹¿)Ü*5)²SRÄþüýßÊÒWÿà››·®‘¤m¦œ­Ù&ÑëI›XDXU ”°ÚU¬ÂÚlûà=•å ÐF¢ ÉÐþ]Ÿü‹ßM:¦2¹!â›?«½ô„NÏÞÚüUÅ}øTÅ®®'£#”ÅqSE%®µ­C~ì‡v.)õë%%8M%Ed(€9"Gýë‡~ýú÷vFV4õý3¯å¯p"¦N–9 Â3Fì燷¦füÊFÄ]„-+ðºåYáE˜ ‰ƒ5‘(¬‚e,-Ì¢à‘â  ƒüÐ;ô~ü‹Ï(¬/#w±úÞKËÛ‹ õí os‰Ç ä´ÉØ3³CʯÙÌrÝ:÷¶SíýùÇüújeáŠBó4÷šR q$!t¨cß'žüò_öìIHä\ùö•É—ØØ¸•Ýut{ú<5ƨŒ@Ç2¿¶¬F#Þ0¼.ØžªË ¢ÎÄɵlëü×Á¶ ¢ IAH§ª5*ß$ ¼ºãþ_ûúçInÍnã~Äh“±ÄÚŸaîFœ€œaé|ÇÈaÅ[ ¡»™+öw>¸|ù--ê ®(ƒ‚gI'j¸ b ñçíƒïyàÙñ'?2O|õûÕ›ËV¡Û/­‡Í9èlØù}÷ùåfyæ„‚^6 ¦¬‡A+HNˆI@“$ Š f& –TRaöÈ=]¹yÚL8w~àѧï8Rdº5Ûœ>·yþ{/ÕÕêÆˆCª‹a3‘hï=º¹8™îé_¿vã° #°&ØðÚ BaðÈÇgßý¾ðÖòýÇS}wXÅ#c#ýãgÞ9Ùݼuµ²p!æ¾i;7 cÕW5ÛÛ{™Ó¶½½Àž OÌu2ÍÊ–aDºà÷Æ7 £i¥R"P +x>‰Dn€¤Ú¬­•ÊAi¾­ÿ„ȾÇ?“½§|óôúB½ºtBÔjqÍÈ5¬ 5Ži2l””¡¸ ð›Ày­Õl’D& âÈÐC4j-2…4•!]©L05l%;Ç?øÔð½mcNý˹ùwÿžŠ"HPÂJ% ÃõÚE >T¦³+ŽìÊâ¹t÷0 Ý4ÛªkS…¡]ýûœ}ï„t—c/äa,…—î½°0tôð“÷ ÓqëcW_ý{Yžn€Q…r€Þ¥­ºÐ ÿÐ2Pí ,¬Íº’LewÜÍ=é®N ‰Š(&ÚNsÏÊ Á|5^º’ŽB¡ ä@ßt  }ü}óf››“ʰ`¾ÈVLo>Q¬À[æ{v¨¨Áœ¡ÒÒ{€ä…Ý÷óúöÑ'VÎÈÒä…¥«ï6+‹*lrA ´RÝ÷iñC쑇ŸÚý‘_¨®—Ÿÿ£`s6¬o(d‚"•Àš)2À­`Ìáz_ld·›Éî7bwE ÊÁhÍÍtо×ìß÷þzm˜m$“©ÍLˆ`«ÕªDé­i¥{DÔ€rŠ犣ž»Ì#”Ž“KG! *+”"jå ]}ÈrÆïû¥™+onΞ ›2ò =¼8]¼G”0¨„öGÿÇßýÞwë“'¥[‰yÀ¢DÄy˜Ìu…ͪ"Uèä~%=*$"xN%¤‚A7 0(–M§º`*¨iS«HlÇ«¬Ê×ú '‰I3Ãw•§NcSš™A,"·¼Ð èj¨Xé7XºÍ+¯ê¥)§Rùî\ÇŽ­…K‘ä \%ôc2 2]GAh)’ $·rc›—_+zWRúºB€i‰ˆ|j¥ã0åÆÁÉ9T C¦iÅ""Ц!¾A‚)3Eèé5(ílB‡’T;~·R]N.Û9rlùÆ{ųC‡ã¾J·±±dY¢^ª ¬Kllfº{w쿯²¾¹4u5h¬KÃC8 Åœì8hDŒŒÉwInÛ¸µ"B GW4?Ât1¤C¦Px.4iˆ—¨¶ŸÔJÅ‹u ½Tà·–%“,•Q‘o· ‚ƋÆÞD â1t÷Ï—–oJI‚°—±“ï?6]¯2Y[¹¡ô5Žˆ›„šsÓÊ´^Ùo6Ë›K2ö¡ü BÅ»¤²ÀŽÀ’ýwŽ›Áâ­K/x²Þ”ÑðFdžpËÛNN΋°®ˆ—5²)Â¥ åw˜É6šíƒðq=T(òL[[×®Òòš©xŒ¢T¡{úŒ.¼$2V¾§¹¶˜êèSq9Ýs`ëúÛa}›0=…­ äNïkÁS:! ^}Mù¡Þñ­MLÒ]ÇÀ”ÁL€: kC©~Õ  œˆE)È…Ø)b¦ÃzÍ€8Øa쫸í€õz/0‹îpª”Œþ(¼’þIRm]ÃõÍUŒL€Ûdñ@½± ¼UROˆL×MZ¼õ¿¤”¯"*zbTÄ\ïF#$Óºw&*/\ØDÌÐîCèØAü {BA/bh„´ã¤sþÚU{P z4“íˆC›ËItÖ†ô¶ ×Þ9@š öÀXºÞी0‘Á ûa¶™È$³Ã‘ sűù°[Ù<ÿÝç››×@ B`UìYÉ‚ïÕ !`)ˆ(= ÝÃÃaJéŽ2Ž“ÝCµ¥i¯±ÖbMG,»’ïA±í˜kag¥òQm– (xH Å,cÖK¬,kÐŽ°2­â’Þï64¦`*¥h-c(È‚e¦{2Ãê·&Š»ä;vϼ÷Šp—ºÆŸ¸ïÙ.¾tyæäÿƒF–€ðÈd—Ê•­t––«%á…ùŽþ ô@RÔ„.6gV³tfÐL„`Ài床)ôˆÔËÿ `ÃÆA)F /Q#{ aÛŠ.YÑðÁÓ`y ­!à†ÕCÇ~‰¡ò™Œ‘^?N$£@І *š‚¶’¼7bØf #Ò%*mÆŒ@H¨[M"ú0€²-ðý0YÆ¢}xu}5ráF_„"ƒ–ôÍÌP!`ëø4àƒ—Ñ™)øåu%ànl8\‚F&0Aýã˜G€MBËÂ?Jµ L¤³Û„6¯ôV1­D®P±A!æz› °[G ò èÀuß!(]¬„ž¸Ѓ~…ïhk\0Á•À€ÿ^ÓU!¸€¨µÙ¢(Ö63Ž -îô¹’äÉÎ]2te\ƒûšRm5¡@`…~`Ù©À«ˆ@•€tŽôá…z ”C¢5Xë,@Z!ÆW†Ö‰ ឥð¹ ÁCwæ]ÁHW2<åö^$LnD ”00& Bí„øG¥ªˆ¥ÉT[O£4hŒ Š´ö×§P(#ºd™¥O´è+aèFßZõçšOô^!n• @<è>¦‰’Z¨uÖB»B½É*µ1´„I*dÁWÌÒû¿º(öuN•Æ(;»f/[ZSµÀPG…‚ú Ñh˜¿-TÓqôN¢ÄíqX‚ëAÆ@í8”œP³zæ¼Õ\–nN%M–ˆ8Èc˜`ŽÃ}O¿HïÐÁktÁ‚êÔÙi±$Œn$!šq‘j ÈÐÜŸÀë(ÕɃ¦ÓÑ€gÀs¸•W­ôh ¹ÝØXZ‰ÔmÑ‚±mZ01{b”´PfJ¯²†³¡¿AFa Ç}“5ZŽ×4²é|¹RmÍÍH¤˜ß A>µŠþíÀû‘.(Ôˆg– ãŒÁÈ"” ü-Fh€Ê $† q«t5h·L½Æ|˜*èáQj ÙÊdAÛ›©¸YOªL i éÚ{#›küiU¬ aüªE-ŨeÑ=…¤ÁµÈdƒE˜ÃcOEºôñÆ=í”$hv=¨§oj^m% €*EC[k¦&Þ€ªôjFí$´ÇN¢{ÛØ‚F-}«q‚¾ ¤7̹Ð5ÐtWÅÌ1(X¥ÆŒ@~‹ý#åuÐTY»ïíKØØ«FAЄÔG<¦&‹@~+ú:«ˆB¤€øLÝÌêvÃ_Ôb£…ÿR×) €Ù ªõÓEªF)×!2n×\¬aG›}'k ÝU[àq˜´øHO¤ÛÜú&Ì Ø´-Kï1tUh”7ei@® &@5%Êf;}¿­ÒZDU…¦>ñe¡ÐYƒ¢Ô­«‹VGUEº›´ï!-ÖSš|ZûS-ÐfX°VþRk!Öj#(D}€ ƒ¡N2¥Þ$bÚA aàP郩`%¡ÀeëM (f3áÐÔ¨Ž—†ßÛeƒít #¢Øf*Šj:1ÈG‰R™"DªZÛ6iÂÀ=©©ä…b†¶€™±†5¬õ¶æDþZR/l¶4À“ž†n_Í© ^õo ŸàÒV-½CD´Õ\ =ƺÔ54µòã7‰^YéU§dGÿ0Kíºý ˆÄ”­‰@CÁ'&±ã8Ðõ¬UÞ½öEZ'ú ¸ £†^}þ¯jƒ‚Öná\Óªy 5z)ž¬áàv;@Ö}îWÑéÐq6ZLµØPºµQkÝí6O€,ä;&BÀ8"ˆ™É$MÓn1 $T³Ü¹K%™F‚;ˆ:Øö¡xƒšˆ }XB¶Æ³Ž5ZêÊÑV¼»n9à8t›#4%µÀó¹f"=Í4ðºÛxÎ,`ZD>} Æ­qz%‰whòÕ\@4ñš:@ÛD0/@¡w(†[J0$Ô7"½6?‰D¦^o8mí \bo˱Aý¬„uDD p[ÀÛ’è²ul:Ö]ÀµìÖußå–†%¤ˆ[VfkêÒI×K"òÀ­+ÐZ˜ð0Ò«Üð!èCÉ’fØØÖSЩг€ñCeÂ\4xƒÈH -¦gÔR€fZCiE¡™$%• $ ܆`‰Lج¡…bè#«Jh#ø°è‘‘Ô¦?Iy û4 %†ž.\eÊØÕ-¬Á†¨‹âƒôZtKC³óX3ƒÖƱ^'¤F"›óëe}™N1c©!Í_0~½ÄIþÃLiû`ê³ðT«Ú,”¦BøÒ–¢aH†™F? ä´qະ5ÜÞ]ÏfÅqŠ®%JeK écº:ž­èé'->h±¦Ö P"zcU/èA—Jdµ{{ƒaÚ)È„^ëN(éÿÛ'²sxœeZY\Çu®å®½O÷Ìp†Ãáp¸“¢,YŒâÈð&[È¿8yHòš— ä%Écbù#O$@âE¶lY«EI–"j¡(‘"E—Y{zz»KUåœSUwšr  zºo×=uÎw¾óS7cÆpÿq†/Î…`FÇÆÆ5ã’Ã[¸€i…ÐZ .™œú9Ÿë.=uéÂO~ñ#¸’ü”æ^œ>ñï8Ý_Æ.kìhŒ½Æ½üçð2M?íÇÌ"Ä;Ó‡‚s— °wàoLßãé®n=ØÑFˆÀ®Ì™„7ÝÖ‘‹—.¾øÒOpóÆÿÔ¸»7¬qxg—Ɣä§ê^lvÇBø Ý…î¤ÍÁrxSI?ÁkC°ŸÜÁh†Ù]ÂõÂþE—in=Á­G$þƒK)&BA’´¸^è=îü¯^ù¹‚¯àœZC»1v|Iô¼Qx?¸˜SŒYuc>CûñOà–Ë¢ o󂽟˜s.þJÓ~ÏaA«¼Ñ{"‚ËÑKôÑÜÜ‘/?þä/_úi©Ð~ šÇss‚±–·¬qØevî"^mïªÉ›ö3‡1ø#!ý\㼞áx1\¥RݺËí>¸)Š—¤ƒE£Ö½páâ[¿y¥,•³ÕØ .7¢²ÌívÈtŒß¹É‚u&xÜÙë¼ç¿0QCb2b¶ Z"«ìUÞwÖhΰ-–Ù^¥5¾‹Ÿ~ú™wß}m4k23>räO¦ªsŸÎK•}Üçie<ÞóUjã üO?äÎ]亭&#8Fð _’å¸SL²E ÌyÜOÕ.^øÒµ¯€ýڡθhãíH+dº Ѝ0oáä)©J6lÇ"„¢j1úØæ/áŽÛݲˆqèçnÚD`ð[C@ž`ù'Nê?ñô§þfgw[sí@osV’‰Qù £¬Ð- CÇtIñ}”s]Öõ›9†xÀ!ùÓ_lw e„`ÐJroºË,ËM‚”6.ŸÑ8À•qÔxü©g>}ÿí½-í)ÎýË.c£3£µ)Ó¹Ál"· w3ç> æÓÅW ú®ª¬â°ÿp‡ÌÖ¥«Ú¦ýÅ–›\‰ãÌà7–c:ÚZ-m=ùô×7>}ïæç7õ «Óos–Á[ɨÄp—×Ö=ÞVsH¡3/C)PmÍý.ó¡C*Ç’„ÐÕ¼Z¤Ú³½ ·ïà"¸&äjÉ$üY›gÎ?¹»}ë³[7ô,¶÷¡t‡{ ðGîaª[V?¬ÐÎgtkZü8—ZêÂꦸ#Í< {Nvar;€íâ úNG±ü°8W¸š…{EA3f8GšªŸ¿®âú^kµã5—;)‘[,$Q2-2ðÕ_¨ ÀŸõÕµ³íFòÆ›/ÚÂåîæj¯0X1ƒ×düp'€ö¿•Üë‡ÊȈŸjû†²·Å,waÙu  QoŒG OKnqP_;q6i¤o¿ùKg”çk~ávdyËU)Ë_°ÐîHϼŸ „sw$"cÝd½„Ûu"„»W+ŸE’ʰM2™Lð=@K‰Âf·Û[[;ýêk?¶<(ˆµ6n ª†)§h+^4‡Vn7N}Y:vu?Hÿ;ÜBè­¼<·)Ì=\æ:ŒY@ã—*I§·xúäéW^ý‰µ”aažé§óÙY‹Gü8# ð2"¤ámwq7¬j!fo•ç`›&ýãÅ'ûmZ< ½‚U[ó’­V÷ü¹K¯¾öS§û‰ ;¼•zgh…е6¦‚Y¥~øì}gv ÷ À,ÿxéƒ÷‘ èTéµyžë*m@ B~!ä"a¯ dÔjÍDµÀIÌ8„k¿¯˜æÙ6ƒµi­ü#¢F£³|tñÚGïeöc5<(–µ­¼¦6Ì5†Ü‰ÿYÙl™–ÍìôÈYþw~÷_ j‡®]š}‰*¿°èJ)øHC«B‹ ¢Ùì,-ûø£wÀ~íú JlÌ_ÛœúÅ¿@;VñÚšDJÀØ,8¤抈±õ·*©¶‹f~òà‹“erçmÛ,¹îÈ:ÖAšúÐÖ‚^n*Ùt(*ܺ¡Œ¯Ðo³6ÄÃø6Á©Sû{ŸM„×"ÿ3Û AxêéÜùK—>ø¿7†£é §vìúÔ5Ûi»3úöu¼…"FFÓ+7¾õåâÇØþýVÆçoé€mªžá„ƒT$\KKö'ImmíìÝ;×úý=ç£][ˆr;½aÕ-Ébg¥K ³i3«¿ !ÿ–¸¼<‰ƒV)-×qWhTâvTâ©_VÛ@ ×—®õû÷nÞwýYUI\×'ì¼e¶~yúýŽ*RäŽcUí0ÖþGê²ó2ž£œƒ8Uf‚SÃØæø~’ÑŽÚù8lÎ÷º¹oÜ»;[f0FÄ8gjv¸JTeÀX¡å è‹Ëqê¿f 51 Ø%‰yä[n¾ z0»på˜yŠ(ŒÇVÖ9Ÿ|tí½jXà€ë' 3°œE¾ OÎv‡Qp¦Ìä¯ý_Õ¿» N¨@½Èco vfM$é#EÑ•và4j,®¬‡añÑïX gÁ튾W7Ú _!fW‡´ï¦¥A—Ó”¿•^¢„Ä©i%ŸL)©DÃÉ% ~ê}í[ÃdDqciõDM²«W¯èÃ_Wã4,ÓÆbظúD«Ø¤6T³–Ïÿè§àÿ ´£Š©°Øu—‡RD‰xíç¼Çnxw»Y!ƒzT_Z?ÙŠÃ7ßzÕãœyaFÅ ¾Áê¬=±ÛéD9ƒ'Sõ›B6ÿ+ú® ˜0ˆÝܧâ4«xmÓ+” ËB¹²nYŸüoUµÄ`Ð;ÄizüèÙ…ní¥×^03ÔϼÈ‚¾ZWMQJµÃCé*('þ§ŸC·„ñÊÊ™v=zë—µ«×¢JUº: ¸ÐüÇõª¬2žyþy4‡í¸¡å«©°$±«òvt‡:Q(Ë8aÃâ å@™Ššm/ |EG !p§RcC;vZŠéÇׯj7Xð`æ˜nZÛp£?`¿j MŸ¿Ì{çýŠÅ¸Oy ¼SˆlmGÙq%xƤI2—†ã,Ѻ‡W‚˜rÐÊi2I›L$µæÜ\»uãÆû—µë(Òš>3ÆÖƒ@ª÷·+3ÝMµÌ7«®&0ŒðOEŠÆe© Hq.:"­7Š|2lFHjfÓXÛaªt:’¸,ü´:½ÕcÇ~óöËZW€*ý¥]¾ š|~ʲ dP>ϱ }TªÍ îÑÊnüOT¦ýç˜,IDlɳ¢Ä^^)ò" ºN¥il…U м¤ áQb²0LÒ´uæÂ¹+¯¿€æ+Ð|ì(mÉC/IK€M J1ƒ÷CªôØó¶Q²ÙÍÚÄü’¬ÐzÓ¹ ^+†a‡Ñ´(¥)óBÙÝÐË~¯Ë! ;"\¼(§w¸Ç؇I«½xîü¹—_ú1ј†-K.J GK&®Q!cnmšhí9=sr:€ºœƒŠF°tÃæ(J ž…¡´SÕÒìG­ñ¢,K0_Fmh•hÀSù˜ TȆjrÄ¿í ‰JE{nùÜú‰__Áû4 eAKšBë)š)°ËÖÐàiPN4”5ÃSˆ'Qã„©nhjô5Ò¨>X”òîÖc¦T¨`³Æ lDÙ“ÓX6Lñ¼0häÜ.¢iº 0 5ùŒŽ!¸§ƒ«;­ÅÞâüÏ>T@õP²ÝR(TVü9€“·þ$\‰Øè‘O×H cÛ¸Ãà jµ9,³2.G»x|”­4éµ\Ö¸Qa€…RÄjº(ËÊV)•À#l€:P&1&Ò,&.*¤, ùÁ XMpÂó Ýî6:Íí1Ä"n®C@‹ÁMc tÀ|UìCN!á¨c ¬Ñ@Ð#­F·6"hb< ¹DÊTM ‘þ„ DGíÞÉ"Û7 ² LŸFu^ŽÁ3’9 +¨)-¥ŽM1C°M´ôoýʵۀU:ËnÔíVw¤d¡A}n:x5ï1¸»ˆu>QWò~9zÆÙ#åR‡†WÆÝ0MÒXŒ÷>‰âùƒý-ð6p a+vExÄ@µÅ-I—xö=¿t2®Ð¡.F…Ê%â§³‘Î!| `§&êËaÚÕù0ÏöJS©ÖõÖ‘/û{/þàoTYÒ\WÓì‚ÕjõN«ó¥gÿV×^ya8Úlmã”0 ^1%lAM•¨qÜÛ…ÆÓV6g“Mµ÷–0v%àGCU\Èvsî XÌ º"ËT(hÊHuš‡Â’TR†mõæ—N¥ZwñXZ¯ƒª›L·úÛýú«Æü$Ëjµdgã¾jV=ªÍ/[ïm}výÃåS°´úx¿ýCÉcÙ:©L$£†Ê÷ÍäAž÷›aبõ›ðšPQ©£½ƒ0N:@…Òƒ«Üä,ÄA5caœÆµ)ŸŸ©Õ’¨y†Õß“L!ÜæùÎÂâ‰SóKk»;wo]¿ºtü±f3¹¿±ËD;S“rý̹÷Þy}ëÁ=• A'„qS¤2¬®­E­¹Ñdúäå?®Õº­µ•wŸÿר¹>˜¨M¡ÇS㘔M°$Z¿Úߺ!Dš>K,ú ô&È£ôè}f2¬ªØêà4Ї4²p0ñ‘r:Öz¢KðaŽcl¹>¸ z€Iú€7@”„<(âÕ‚w’¸SoÔ:‹GW–e8§ µyÿZÅGVÎÏ÷v· Vz¾óà“éhRKç”ʦÓm]p’%H °–÷¨ÖèdÓíƒí@$ÍÞò×¾ûwýþ½ûŸüZg –tÔ ¥Å¦ [¥é –¼tìQ/òÊ|Tk!Œ@ÒMÔø(…öðtpŠ Ò$N’ÅÇÚËQ¸¾~i”m'Ac{s{oónÚèN¸xù·>~gãîÝ­û·ÊIÆxÕšg—_Ç@°' Š ÄFœrÜY÷çÿüþ+ÿ°,+U®…–‰25¡‡è“`ÅÃçhÊÍ ãjXèÃ…rcœÞ¿ù?\O°5”¡Lš«gW$õvç´hÌCùðúÇ•c§EaÉTg~usã“Ïn@ÿÑߺ†Š5J€Ð ãdÒ†ê…ìžît—‚ Ë& (ƒ¼,QÞ5çòá¶*ò8ì/¯ž»|úÔ©¿þÇ×K½‚ ~öƒÛúüjÎc =ð€aàj%·)ƒ‹+!Ó Œ°IYä ëËb„¢ax=ŠeoþTsêud€âz°»‡õ Zñü»h@ÚÛº6:xº(e9Í4ËLTÏò!(º\K!”Wês<Í‘Za‰ç)>#' ÀO޽˜O'ó˧/]~ö¯þþùõË_ë®ýï¿ö_ÏoîÈá`°uïúd<.¡â XWä3TäÅd:ªbÜ'õÅc'kíZ"½áà7š\¥“áþhŸÁpo“²×[lŒC#y‘å2>¼ò‹þÖíb2ÄÇ«‰jôè(>Ä怶ʳôÑÜ>²ˆ=‹Âƒ 5d&g¨Ÿ¡ý‘®‰uÔŸP'§Ã1>×$4í(É¡H ³|â2Ê¥é8ÓïüÉ?-¯_=óÕ\‰éTÕ›mæƒ׎®?Yý7~õE®Ð¤\ Ítºrt­ÕíÆÃ´±ðî«?ºwó=X ;,“:zƒA "“Îŧ8a%¯Çº(™;Y³ƒí‚FI°ÍÈTCL–c±ÍéNS€N2àãÀ‡¸,°„Œ’´±ÿÍï}t4¤bcáèÜÜ\¿ßîž>ËÆeTkO²Ýë×÷wïB! âî0ì<¼ULAeM9«&¶UG£)¡ápÇÒ†œÄL¢Ñ ¨¸|ásœãQ N$I?áè¬4<áv ‚D;˜þdHñE1&ͧ¾ýÙp¾ï®žï-Üx7ˆ;À”û{÷[­9)wn~ZÀ®BÌ) Ê2WÅXcèÉB´»ô§·(ÌHš+ìÔq$™ÑÀ™žyÀyJž.ÉNšÕ3êjYá†~h7¡Ê4Ñ Hx”$ø!M0A SC« A‹N}ù/²ávÊÓÚârT«± 8”ã Èø¤Þ˜ŒGû[gp}¨†Ž†aU•=»¡ª;â±gå}:Ñ@œ¨%wó=:àã¦ð EÔHÁY·ãW‚»3>妔t,âÏË$ÙÏÉu¨TŽŸù3šæATKâF­ÝeE¿¿²R ›M*öñR¨Œ7Üãt¾k•xʉ٠РÑf|˜,É©ÌÙQ!'ÌèjK-§#´ÓTM)ìó|Ô°Hû$³ÈÒpßrwœqäøEP;¤Lè’S%Âl´?žLp¼H¬|ùT—9>÷ˆ#ÃHÆ¥{p;ƒµÇ¸riÏäplGjâehºë;Ô±VÒt 5wG8Ñ qÊ…§QÜÐn@É×ekê&ûø#_Z}N$Q ƒ„Ç9+ËR:gÛȶˆ[ì; Â‚ð•B˧8¾ÀÇ5! %u¯‚r°dº 'Ï ¢—ŒP¨–%=àδ¯Ž, rýÀ¦ÕÖò@ûs;¤£Yeüc$t:¬i’iþµ+xœezYŒ$Y–•½Åv7ßÃÝ#<"3¶Œ¬Üª²¶®EÝUS=Ó3´˜Ó0,4ðhB !>F>øãÄ2l?#!`¤F­–`˜žéꪦ²²ª2;«²r‹ŒÈX=Â÷Åö÷÷=3ˆW¤g„»™½ûî=÷Üs¯%¦Ð„Ð0FB¤iÖ+ØZáñ!ÁÓHÇ>Õ81X<ÔxªÉ£à…æïê{x‡ÿQö§ü ~•?âB³,[pŽ¢º9ó'”Úq¸^Y\ð8ŽSB4L­(˜1–ª«ÂEˆº:¼§ÙßH^~à2Òb„ä„jm¤¬›H¯#ËÅ<î"ØóWÖÀ¹åð'VV‹ùÔ?¹šŽ¡–íþD­B9OáSÓ49ÓÌB3ò{„bǦíÆáŒ ‘¦Œ3X‰gÞ€½fQëbµX-”K` ÊÒbCú_®åH}«,Ö4¦ÞåwBúkç¯ÌÉ|~Â^H×Ùd—Ð #ŽCB p8‹Dcœs†¥%ÈöZ±ß)×f£ "4 §`MG¹¥³åay4Eæ]žmKE.C0&Bp¬üàxÁÄ9$$`2d® p¢úíâ.Ôæà‚2 Žˆ‚N²Ý’?l0Õg³1|M©P Î`S°4¬hX^…ëq4É—œeöHûÕųÏQ¶\†Qþ’ûŒ]mV“ö¢DvŒ<b¡v•óÕÎôÿ¾μB¤Ÿ™€pÀi ¬žRêPjþ€% ŠÀó8ó°vF*©…6§ M‚Y™Še ±q! åa_Hñ­Èx_^äÌù™jKósR+"™årÃ÷G,yÜ1¬ÕE×ãXPÓJ“*$ÕIèÏ(AI*”g$QgN”D4³d EM(Û° ›ãÿü… "Z¶ýBYåÊ Ç<¬*e2gg¥W yî(çç¸Õ”JYFÄ:†:…‰å†³!²è[N!˜Ma߉Ìqªƒ§À‹XÓuš¦ Ç\]=÷¿ m¶"¯Ô®†;šHæHoé™Q`€È%A^WÎ@(Îh'+ÊB:G,G DA%²Ln•Miª…[YJ!_ )‹äÙˆpæs©'t‚t`$ø"•^&>ä£ Læˆ=£G N¡1„ÌX¤Êž4E1ª‚CšaP•ïŒjМQy^ìD.!¤„’5]ZÈ Ê?«ªü¥"M%c(``—¦[,Š`¤oFÊŽé̼…Ó°4ŠGa<ÏO4ws†!ó÷‡gøÉö"”ýóS0ÊieRv æþÀXÆAnd_©0c•=\²4„Ïž †¨Ú¶ú ÎjåX6ìÆ° Óé˜J‡ÿÇÒ÷ÎO9Cq’äàœ“Þ9R¤14Oê9úQîm,íW›U–ªŠî¢Ìéó/¨®+é•E‹«ÿs²Í‚-ó,‚\5Èt4q¼rL@ð€ ]Ø€vÓM‹"ì‡ E†¡óñ¤ŸežÈEáyõ=ó6Qú9?Fœ­(õŒÂ¿ÐÎòòò÷‚7 =!ÓeR/ÄJš*Ö´4–Ðjè8‰{: d'‘›’ÑáPâJ( ãXÓ°–ðtG3å7¢´„Ìõ‘¦Ä€ÌhàÏs”KKîR¬•¿(Ò4DAOgJ²Í•¡ÌVC7€+@üü‚DR§µ# À'R çc)`/1h`×m&ñˆF¢$ˤ€4Î㎫•˜Qч$…"¨Ï}¬¸ZÚŸ‰Ÿ ; Í{‡¹Ö׿Ÿ‹[„L (=U‚AdåCÑ8Q…/g-ð5Ëš •,*Mm&[›’¶Û4as”Î&˜Á%O(‰mCNs‘©¸Zõ/(Ç3vAö£¬w’Ðæò™Ï{ LÞæP—)¤©7øÊ3£| Å’E†B…'O…Ì„ƒ(5Á0¢„k„²Íô A ô3iªD\^Œ²¤UÕ+0œhe†Êº€-i?By|!<ë}p–•y–B¹«ö ,–%Î Ö+­yÁÉô%&œ’$‰ì¼‚)-¨ € KÁÿ, .%2Aá,É¥aN2gÒ%(&æx.Ò8Rù¦˜Íñ’e.Ë: ¹?ousá¤å¾J®¤‚!Št]‚”ƒ*;Ô0mÈÈ8™ÈÌU!ô#ºŽâH2¶nIn@’Š£þHásÂ;ãVÙ/ëWF,g £˜S¨làó¼Î53Ï0“·ËZ8\Jhp>xY¿¤rNuÓ€@¨D‚|L Cr(EcBŸÀJã™ÂžL[ sœ&±Ì*ÈkøØ5u?J!¿óÎë¬åQȘñçyýRù˜µöòožÌOQItá˜ì{”§ƒ¬•< eñ ºå¸³É0¹ÌE]—¦ª §ºQŠâ)ø $K9ä²¹/±žÈªlJ¤€˜CaŠ‹•K2Oˆ³Déç<ôHÌózn?šÛ?‡ŠJy¤Ôþ¼3à’½\&VðNÒ(?Vabˆêš õk…j§ß‘e‹êvMlÇ™LFjbAÒ$‚Ë–™HuÁ‹Ÿ5ïÊó9ÿdºKÚ¡$«®WÃg ¦ÂOöâYú‰¹ðÎøIÙI$¸¥H–¬hZ`]À<8Kñ,‡'p°¤V„¬‚¥s=ˆ€§$2QZ@xP‹A¦ãϦsïž)[¥­ÄÌ©ŠÎÕò©`”ûNþdziUF•sÿ+Ø ØyC‡³~Cº´%¬Çd"‚PŸê;É2 l M±Fªzyé Ët߇–_æOÒ”Ïן7ç =ËM®Í_S—Ë:(Õ{ª¡“˜ÛŸ]Ïg5•6Ÿ½È6-+ZVyÁz0Jö‰ð./ì”–§Ã=`Ù$õ “Y…4…ì‡~“ê< Y®dÀ‹’¬°Š¬¢hx®áÕd!×oçê:+k(È3=ïß³$Û@䔈ÎËŸv¡;Ë¥,2M ŽŽAGjT7MÆbq3ŸÉbUthXÂ4F ¸+þ]›÷KÀ›§J*¨xa¢ áy{.m¡êA.Qf¿¬Ú±g%c®—ÁQ\€j‰«Šfž5ªh@ fv! « †Pè!ƒ¡ÝDEñø_ºNƒ ÑV¥–í¹æx0HdÑÅÊ0pž•$¾&âl¢ìÈæB"ë(•ÿÏ#DõØ \âbÉË,œo9°s’Îu…ªß†a§`Pìªf…~>PCFbÚŽ'@{ú>1l/©[K•' hSöaDv0¾Kr“.I¤“½¹bÅÜ–Ûøÿð“y,rÿ§ZÞÆžm kq+ì0.$N~•5YWÜGt³­ÊaDV»ÄX(§Uº)ç¡/a(Î17-GÒ÷HÊH6d¨ºãrî#îv9‰¦`—±à¹`ÿÅÒ:É{Jt% ŸF¨š/%Lª_"›kéÞ|2±tV8d~醑‘&‘ïT¶mfLaLžÈYÕ ÓУ(€k&1ئ€ ö¥‰ªøÄe%Ì4]u%ŠLdhŽŸ\Nà|„H¾™õì¬~˜mÓ×$’Mt‰2Õ!æ%âïºåÀŸr-[PfŸa¸ê‚1]™”JÀJQ]œäWÈY¦+Ít#¢E‘Ž0t D—ŒN])Í’‰â3Ï_4ÇšË!‘ë1©‰¢Àƒ:,'Mä¤Ù Ÿ1§œØ+f8›’aËv©aÍÆµ'ÐT7ègyê"$BC$9 ÀN£0‚ÌQcRð0‘Ë&Q¤!bF ›b#&f3¤“Ô’Ó0eÆ–\Þ­’¬ó+Ë©³ ÀB E¢+ä -†“ä<ýÕÄ ˜Fj˜4‚Ôƒtµ!ü  Ýt-ϤËQ?–Ôc-bq(©K…TO ù…Ù,PÊu PlÐj©9ên£r’† +Õ•pzN¤™´Ïzzp9ÖÈÚ ƒ²`3J@¨ÓЇœ¥RòÚ%8C…KäË!’ÔǶc ËyšÐAaPe¦ðHľe9-…ÌÕ° ëè‡ÓûÔ¬3­œL_P<ÅFÍŸ©„Ý*-^qŒ0áäÛßþÞý0‹¬REtïDØØ«¶%þsyœ5WDI’··"›F™r$GI@;nú¯0J¢ôÑAL8׿An1îJ—$Ó@À”‘±ˆI$•Áôi±ØH@´Fâ⥗O÷ú½Ït“V—nww¾¨5®-n¼Ù÷M‘të—Ö;ÇÃÙpxm£½rùqË„Œÿ×þCkyõoþöß¿ûÙɳ{¡þWj3kr™L&X^@èš–wv—†hºŸ#@šÝ"Ãу©²ÝÔi¬UCÞDšØ@£K•% Åó±FÛP{5«BÒ˜â(ÞõŠKë·¿ï¸ÚýÿÓúkï— ëk/ýä‡ÿb÷KË­/¿ò§£Ä>þon²â;qénÖëºë4M›Oû†ã„ /Bh´§ [­eB]\–Ws•ÐX}ìÝÔÀuD×ð( Ž>t\=ôGQëf~Òh Ø`ÀõÍ•ÑXhÂBl{ ·46³ô‰Ÿ®$Z…h¾b nÏ›bhO0+UêÅækåjm2=Ù{ø©?¸·ÔÞœEø#„=³Ð@IÏŸ 0Uq%æRêaäó’U^s½‚Y¬N{'ih(ÙAB±\Küä 3²iúÆû¿ôÕ½»´ü~6b·‹M–úɤ§éÎ9âYIsó‘ÒÂ¥ÑþGI0°Š­ 4™ptm,ô²åx<E³©Ð À4TáÙàNki³¸ôU::xüs-}.’~{ek0ŽÎ4\tëW¼byÔ{œ†ów5>Aîu`,¢: Ý4“ 6M±víúÚåÛÑtÔ99 9ò òøËÏOöwZ«7F£-¾/€ äÌ3Å’— LºTºZ‚‰ ÉmØ­¬pֱݎ;'£8Œs¡+L@5™–kÍ•Õo|ðÁð¸3<Ü ÂÍlŒû›×ß,¶^Žƒî~ÿ_vqÚIçêïŒÆ{ĬŸˀu¦ã®ÛlB/Žô¬‚ d@I¶\cqyãòÆkiT=×O‰†¯"ªŠmçF“”¿‰4%!àZXÞGÄpKÛ+•‹ãã¯äƳ֥U“÷¾óÁïþÓ¿GÄÄö Ã!tû3ëÄYãé¬Òl.]º¹±ùÖGÃépÒé&éx0œè˜¯¬^=ØùìhçAoçãbý–ݼQl­û݃Ԭøý=Ä¡‘¨éalŠtºÚ)U ……ö¥z©ÔÖRýú«oììÇé)Õfqj¤ñƒ:µ¤ÿ¢Vß ¥_Ñp T°ËD⫺Zçéxóê›7^yˆØª6OŸQ÷Ö^ywñÑŸ}rçAo4p±o— ·þäËG³i7‰4–¤;sÛ-/.]¹ýÞûÃãý½ÃÝáÑÓh¸‰ï÷¾¤FËmß,Õ\¯Y)VJ4ž¢B}“E»Á¡Oí¥fÙv­Î‹Ã0­n¬ö Ë®ÔÌ´qìõ‡Ÿ~îšfµi½vk믮l]­,_*zÕg_~:êö—¯\Zj]ѱ»þÒ•þÁáx2>î÷@+¦ÁÀ«,ãÓþ``Z|çñÓå—n--ߟîü?ÿKû¦ z'£Rk´.mvö¾ å¾bàãµ·G“ÃÛo¾ ò†XÍ“£ÝdÖ¿ýò»¢0´½ í¥õ•Z¥ ,”‹ƒƒYÄ k;8%fõç>M½{´ç¼±xmuë¥îÉáñÓgöb©ä-ÿÖ?øpçùÔ(ˆdˆu+ef29ô*írk¹ä§ƒÁ“‡?Ʀ³÷ô>Õ åfËq‹Ô¬Ü|õ¥g?¿;Œ"f_^¿b”  ÚãÙl4èÇ>ÝyZoUA­[NÍvmÏ+ÔšëO_<ÛÞï<}žŠäòÍom¬­ ¢4 §éd²xy£Toôž§½£;"Ú%(@¨Þ^ðGñÚÆÖÇ ½\m¶Erì"­xuõõ?ÿÛÿµìÕ¿ºÿ2«Pòù—>èOŽ>¸ß;:4m\y½3>]nU®žî?nmlí?»[)¸ÍÖ ³`þäÿçK«¯ÛNõpû¥—o ÛþúNmaéþÝŸ•<·Ùl/\ÞÒâY8eȧÝî4èÖÚ+Ñ(èöÀ¼ãã“ñÉÂ&ôŒåR鵯½“K[뽃gõæ°ê回W;Þ~Ъ·±YØ~ötœBßüú[†±àÉã/Âiðëãßí?Ú.-®ì>ýüúío¯¯lˆqÝûäNŽÇîì'9'ºá•˯¼ý­Öúízµ1 õŽövž}Á§Q±fqR8Ø·_©Ö«£iêOŽ¢ÉúŒjëÒÁî@*+«›“aÐ?ª(êNÁF~˜ˆpÒ¾ò’·àéØYl_FØ]»´µ¿÷¢ß?}üàcè—Õ›í­Jc5˜ôÓ`¶¼Çä#Z_ÿr¥bióÆÕéŒ šOž²xò°àŠõ…ÅõW——V ^y÷ÙݽÝÇÓÓ1õ8–“°p6îFfË.w¾ú˜˜Õb³Ý;ÞæIlêz­}[ öSÇ+-.¬8U»Û:nÍ.˜± *§}·èyî=Iý(æc¨÷;ïqË"ޱ e¬dµ6^k/7ó=¼õÅ¥'>ÌÒ¾þÎ?œô¶Ï ÝÉd B½µK,ßx£dcÀæÞ“‡Í¥W†Ãƒp=þù1É¡! ^¥øþ¸{èë›Å²»ýðË„»^¥è•œ½¯ïÆqä¢níêÛŽ£wûcÛD•f›%ƒñDvŒ ¯úûÏ¡s„òÍ™e«ÙQ—@VhØl­®Uê £Qtx’€|g²Gã)Ò"È}«þM¨ÞN¹A]^¿^©$%o]£&èíG_;^bÔ;98Úùº@è¸å=Ó‹ýgЭ%…jè®W_vb8Ëád88zÞ^Ý üþ4àåÊRøy×–—öŸ<¯×«ÝΩHÅûä„èxaqK3̓'÷eï,[—즿n­"‹#òÉ!‘ hʰ%oÊQ£º=ÉÊíߪÔ/×Ú•æâj0›yw;'YBØÖ;:}vÿΨÿaT‡‡Q9¼Ð"X®X½Ô^»6È7CùÓ‰ðJ ðAµA’A‹;Zb‚S!XU–_ŠƒSKç[›/wNÇ~ßÔbh g“©Wl¶†§Pé?“ét<6íª]®vq–(ÌÐ]"&©Ð Oáòñ•8qJ%»Ú²©Ðwþò¿ ‚håú˧'‡Áp0'þäàðñ½4…0%àèË×߆®mÿÑ–„Ô]„Þ:ž uÝzûÛßG$N`ÝéþƒûAØEjXê5®OûÏ¡éãq ›vû†S7-1£$ö™öÈgOÜÆÊµ×>p Ù³ î~tòâˆËæWÉì5Šò©ü8HDÄDµåÕïÐdV©µ¶÷§'ÿúŸü£ýG§Â4Âé1K´Õš„‡é5—g§{ÀÏN¥Œ^@Ýr#I™|Ü.LÇV ýDÝ£‘*DÅê–]iaÙ,—§=ÚÛ—P¬µÚë×X*¦Ã“ý'„š^½`Ûå…¶`AÁòŽO!éf£Élp”j8lXŒ¡¥Ò1ôL&Á¦¹pymxrº²v-õZ­'ãßù½Ã—o6>úÃ?üüó¯žî‚d>Þû‚s7ôg§êqT\XàëTL‚0wxšÝ`ÙÍMD°áT¢ (ÚÕ[oPHÆçÛ°‹þñTŽÛoþšð0íÓÎÁÈï/,®A–"Ñíâ´ººy=IÈïjeõÎG?êwdÇ-š\…DÓk›oÄãw¿û›_ÿŸ?öY†“h"ÒÞý¶~ý­_ýÞ7­îWŸ|ùùçý;?ýY*Ä ób6ž˜¶Íz¦m[Å‹ƒYO#D?jDd·&a(ÕÍOè.åÃÏD!Ç­Wƃnua ñQ©\+ k3L«8}›:åæ‚Hqçh' Q\XÅ»üû,4Ô—.ÔªÖª^©~rò˜œt0õ"¿A—VŠHÀDZ_ûÞú­.o¾üæ·¿ñ~y¹1û7ÿüþû>žã££( Ô@—CS ©‚þè:,­Ül/]y R¬Zq–¯Þ:Ü?¨x%2îwzÏ2›ë7ß,Á KÀ<Á¤MÓˆÖo¾·÷èn¯X°ŠŽãvGƒãgLà$³xæ”ÊQ5} ú\Ý)w’d*çoÙ„/{Œ%»/¬v}ÚE§X{ÿ»ëOýæ7×WÓÁÑþßþkÿƒâA8ÓQôÔm5Ýöêñ¤—¤ «n’Íë¯×ªEHχ÷>µ©Y]¹ñÓþûB©e«àVãTŒú»i2õÊ‹‚0‘Ê[¬P}Ò *U—n½õŸüðßÖ›õc4âåÖF8Þ™ÎU¬¤É¬{t5ÒœrA£üéX޲GKä&œÒUj¹–]ºñïnÝ|guëÆË¯¢¯?ÿì÷þã‡'ýN,gP&OÓ$ЍEu]/šº¶WvO:Ï&ã0?&J¦i8†²œª'$ Õ&ãé¸××8BÕƒg\D2pBæ)”[ !f³tëµw Žwôüy¢‰biaoûA΂Á‰ºK‚‘–͇9™Œ¸ËÇÔ .å~øºå²I,5«·ßúà—¿ÿëG'$‰ûVavÿããá`û`o›3 öìâ°ëGŠsx4=U·Â Å ‘rz'ŸARwÄË•4%¨Na›b­Òºr²ûÔ}bX•åk–nøáØ?=ØÀºÁ@ÇHdC{0C¢É ¥z\BâV2išß*’‰$Ó¤ÅÚmÉM´/­¿øWþú¯þ¹W?þééó¯ãÛo,?}–.½äŽúÏ{ÇcšX~*·äGÃg_Ý»ÿÙOâ„‹x4—Ã@¨ÌTÂ3$ tªÚXuïW#º](x·Öîì<€õA‘-­n½x¼]¾´ÑÛÛŽýH$ìK7(„Y*³A¦†y~«J=B¡žÌC•waܲǂQ¡zóÚbË*·~ã/ü׿µÜÙ=)ÕÌnoôãï®ßxíÖU¯ÑÐx¤ ûrÊ&&þx˜Ü»÷³§¿‚Z£Ã'Ÿº]ø]Žne‚«ÇGåÓ ìÕ×K—¦£“Ù  8O£©Fé¤{èÖOvˆ8»ÿ—È!- t‚ĪI>Ëïù"É;q°˜€x¨Ôj±h4ëu¼êk6’öfsiùʵ÷VÖÛõÆÂÊ ¾sdì[,ߺ}cqU/9fBA8àF™OM|‘Ì´aHNúîm?wöžÜýhoïi0sg˜»Õ%°ÎĺY]¾2î&aLL¼zíÝÓûG££l‚þ‘@DÞ°–£S £T* s"§è’$IvóFÈ=Ç-,olB¢í?ùŒÇÓÿ È Ô%xœ]zYleÉ‘ÝÍÌ»¾ý‘||[±HÖÞÕ¥ÞJ=íVÏŒ¤†Eæ€ Jš'˜‰„ðÑj\<1!‡•pm $´t²Áˆ ý´î‚‚žd¸'&%!6[Q*||@\˜Q-‚·‚· O*Çe®$‰-e¢d,lÀOƒLæd~Sé{ÀèqsÇÒ1¤ý^Xf”*æí¿ÙàfÙ ¾3u @|/í„~àô˜y•›‰Qà ™ÆÿAe©&§£äÊ…8šÉ¡Å¹'ÇvŠ„eÂ|™£ä+ßɈSFipÈ8pœqŸ–N @ÐzD¥k‘ÙdíÛx5Ã'¡Ž¶o ­Â/cj·Àb6&‚C P'€M,äJÕp àˤ›u‰üìGJ"ȃ *iC'–ø’Š0ÜÆA±àøvò6„Ìà6EÆJŒÈ*3Þ2¦‚—àK©)Ò-DœËzø#’dl0ŸÞ Å(ûóèCoÙ>ÒhÓ«Ñ|HXBÆdgB¢mâ‚ÌYE¯õ©&8­ÁþýÜ¢qwHFèÀ4ÌJéüŒöã°ÌÖða"2ŽQ´>esô¿&·¤¦!Ͼq ¡‡É¬c%,!È|”¬"3¢ÁYê^–½˜[&ŸÁ,Å Eu‡²’{{­3˜aíÁ\ä”’ëQ¶)|R³ÀÎÉeœ©-oÆEà—Ø(–rFAa)Bp!Mø1/„µ]¤/mj‡ÉT›œO,Ã]ükLaÜv¢)Ñx¶wĬ6þääp‘ñªNqBùNWÀ´—E˸ð²x‘ƒ zý U1Ñ‚áFQY¤ aÁO.> ŸLaA•mlÄôv•r¦•Â#Û¸É! ŠYê@ž­•ޱ„,Å-Q° r‘K=Ï.CN°A<3Fƒªgâ ø!˜+L äóؘO) ˆLÈ~Ž•B!a#X V ™„ÕJ ¡™œã> DQ )¢R€ëRÆH°Î’!Z¤5ª¿VÆW:em¼ ž Ás2™±3Æ{ !±TQhD EêK&°Á DYÊÂÙ†J°&ûÁihJ§2!h XV'VVOR“¬þ4ÿRõ°Tä¨K-ø¡àJ†äدŠo¦ž’î×Éðrÿ†-±ðižíòr];cT—Ž3²?Ë&0¤h£ *c^P‚í T©†L™ïœÖДj"¢(]«´ægœnD%šîÆÐÏ =êËÚ«uFn_f†6#‘ð…Hõ”&$2ç†}ȥıÇ4¸®Ÿ5ú-ÅcjÎ T—þ¡j”ø‡Þhê×eéå Q±ú#UâïB7M@â,4UY i!£ãm]ZÌC¥uÐhT†Ã°yžLEèÚ®W¬Ô9د/ 䥸LíOuHápr¢”1ñ¡ù ·¾RI3ñ ˜Âi¹±4dzBOq,(/ËJŽYC# *L¤©~ÆÝ3`ø~‡ª±ÍÝŠŠ;Ô&`G€RÌSý¬­/C ³ÊhÒŸQ]Žog*™d„˜Þ®YZþÜT†RSº À×&ê‰,Í3ª¹Ü8ÏPfr º4ž!›·cBYø55;ª´KB;ˆÿu†åTHac²À€—Û.•x42¢‚_§Ø6eÎYPI—PË‘iS…–ÒSÞ¬%È6G¸ãÔô ´b]j*r4€°š4¼ƒJ•$½|¥À©¯ðŠa!NŶïÑÏ’ì‡èòŒ"ŒÒ!–KMÈ<‡R8{ æubÚª4×i}4ï%‚‚·…ÂÛ™Ñlð”·¤ã¾Òß+…X ˜‘(ÊÔfÆÔ¯~éLl@ L.ä¥b K‰±‰ø3-ù` ¡Pä"S±¯$öF=‰ýˆ‘Ôôá_“”´i§øƒš1“)KÉýA·;¡^RyÅ‚ #øB†‡O#~Ô_âC¡Œ§"‡š/ÈüBûtõ’ J-Ú¨bìˆm£[5ŠU‹ìGÝ‹-Ñ}P \3m#²“$R"æD5X‚øoÄÜ)S݉N:U”¸>¶á‡eMŸÑlÒûb¸öó_ÐlîKUn5Ÿ&ñº$fŸ…=䬩aŽ3 (udÀ“Pµ±¾ãˆ‰íÝ¿÷§A)?8Ý/——sÕ R«”rv`;­§ûûçG‡Ýóöééy^¨É¹•Û`¨O¦Déž²"x£¥§¥…Åb{ã·ÝÙ»×’d¡×Ûsü²ãÚE¿¼»óñ浛퓋£“íÓÓ£«¢P<<¼Øþå{I<£tLÈ·O0е³”]©\Â$)c:¾Aä‡$\ TåÆßGÑú+_‡Z“//‹$ì?UBäOrÑÜk†Ó®¶"(ºñôPkØŒ@Ÿ¢¹ïçß|÷ã~rÿíw‹E®fö¯>ø?¥bi}óZ¬=;Xéî{Ï&aÔ::L¤^Z½ÚŽg–wðø…|õd÷—+h8Œ½¼6à  P¥½E™®!R!õp<ÞIp,£Unù÷: Q¿zm~¡øÕvç¬Ûï¶OžÃÓ! ñÙ6í ¶°¼öÚ7¾5W^¯,•ãé°uÖUQòbg{õöÍ…‚,.Þë6/ž|þ~­¾6žÎš{ÏW–+ ^¾t°»½\¿·ýô×ÝÎÙÁçI4tR¹%]ìöffÅb¥Ì‰!p™K[HèÆhrÜ G‘ ÿàŸþÒuUœ$Ž!0èö{ÏŸüz0ãqGF@¯N.ïÝûú7sùr­á-/mõ;­Q§½´±¹÷¼£’áÙáN«ÛöZLŠ|cU@þGÉ ×ô!|qR¿ºÑm–×¶¦ÃóDúû϶§Ófi¾Ñ?Û_½ýòÙþ“Qo\†¡¥Æf\h†L4pÌè%šœ„dªí±¤!‘þÍüǯ}ûw>ùÉ£|)øÚý»*l=üèàúíÛÖTgÃdÚn‡ åQNž=Ž$ï÷ºóµ•G?ÿ3·P\Üøš›Œç—n>/ÍãÃXûk+W]À ž|¶së•ÛŽ“{ôÑ/Κ§‡ÛØø•œB¾ ,? 'ÜÎ>I°ªb†‰q:Dƒ@pÓ{¹)s0í*=£ù®QFSùPÿìßžŽ&Ç•Åõ°X)­4[ç¶ËJ¥ùxÒuÝðü,ÚÝß½{çÖñÅż[êöÅÁQu¡TÈÏ·ºQu­Z´—O¿py|´{XÃ*ŧŸ~hóÎמ#fƒÃ‡g­ãg–Ùvàçmß÷Ï•Îá(z[™ÑŠNgÁŠØhš5á?êFmÎ2P¶Òè;Üò¯-{\*•¾øôýúʽg»ïµN»½ÖéÖí×Xdï¿øpeum«ÁhbÅáÜü¢–bòæñce—W®'‰>?Ý]¨×›'-ÐQ¥9ГµÑø4÷  —kõÓýÃp6ž[]\aQ§¶ú²[\˜ÎŸ~ú^<žææãÁ…Œ§ZÆØ†€Ã52qGÐ.ç;÷DeS­IÌH 'û~xvÖêì‹6Ö¯ˆ„ž´ 9;,ÏÕga8¿¸¥¼Q_ï\žZtÿp¢@íÕÌ-Öd<^ºv¿{ô$š^x…yà¥Õ­×4w_<}88;ÊWŠå5…7_y³×œ7·'ãølÇËÏÕ–ç'ûƒöŽpåŒ&-žÆq)(‘1(µ+€ß¡Š#3yOtª“õ7þÑõ¯½¡C+ÈÉGLNAÙbéäàÅtpÂe¸~ïµÿëû…òòR£¡ôH9öbãÚd{{бý°8Ww‡~nÞ/9ýÞ$ì·„Í™—„SWÔêÆ­ùùÅ(dóýi4à~©wvà¹öÛßúÞ‹;ÿˆ&xÏÄJ'æü"½f=+VÌôçæäˆŽ0h ùÊßøwÏÅV8î?¯-ߺ8=¾yëæÓÇÏ-+º{ÿ~k¿µusk¡Vo£ñY«ÝmùüÞög̓͗·nßžøñÑÉô£ŸýÈX³Qÿì= ¸•¹Z«yújîÆíûÇ»O˜cÇ€§Î4µÆ–å8'Ï?¢cSðö '1بâ(S1jvbÒlé}+½‡` á¿æ ŽW®ŽÚõÍ-h ®Ü¸÷ÁOþ»‰(¾v÷ÐCÊñG£ÞþçÛŽÏç–6›O—êË/¶?ßÜÚ:ØýÌ)/%³Y¹\{üѕȹ6ˆNÉs¹É`VYZ“áÉ‹G~¹äæë.çý~ÛÍÍÿ÷Ο$ØtÐQå& ‡q38l¢Y£Fñ¦ÍHoDP_†ÇÉåëÿ°P)©$ñ¼â­×ßœ¶û!°úñ³(æ¹<Ÿ«6l®”ÖÖ¯÷š;7^ùÎîÞ§ýV»Ýn/v®lÝi·¯^y­qeá“_>xþì‘íØÅB…Î ‚ùú:‹#¥{¥B¥^[¨.Ýüü³ÇGÓƒJc©sr˜€\„µ±TEéäǧIv©F¥ÓÑ´+¤ ª™9 yâ•×ÿpae¥ÓŽ¢ÙÐöÙàè(W­Ž‡7X«WýÚÊf½ÑàŹœY1t õÇŸ(ÇýgÏ_T–®Ý|Ýu“AëìÃ_üùl:‡v®¬¦`óZ¹µk¯Ú¾u‡N®Í:*œh$H‰pni£ß:œï¢<Ó1 éŒžï,s‰‚.BhvyêD ݆¢«Vé®NãÕ?ä:^œyneñêZy¾Ê½Å½í_ »\B;Æ‚báæÝox>óÀO¢ØXm”ò¥Ÿ¾ÿç‡Ï?«-®nlÝ8{ñ¨²¼)òsþ矄áLƒ ÂŒ•—6Âq—;ÎúÆË ’÷¶?}­ß¾×<Þ_™¡·¹}‘¹ ²Ü"´Ó] êµXzˆ&ñX×öIºOá÷¿ûo¤ŒâhT&£~ï¼­¬Él¤¢¨Ï&œç,缠ظºµ\‹™Û¿èØP„‚Àac›{q ¨ŸžìïÊ#öÙó$š*™à% ™‰=Þ¼‚ä@€I0w*#ôl: µ|Yæ~CHòÆeæ|–æ–Ê2PE?™ñZ’m<‘zû{ÿ:œŒG½Îj~¾}öÔ_ãåÚZ÷ä ¨ò¹JÕK¯âèÊõþxôôÃ¥jió¥7« ÏýÍ÷ýÁƒ{ˆÂî¾…E'! Ài¨ê+¶„Ÿ¯,X¢0j>ÅC¢ô,ÆŒèñ3TãìB ž,T+¶È{nþêúÆïþþw'CÕlòþÿ~úäá°ß%~&4=DŒé8RëìF!2½Ì”2&Ù­$ Þ€ÃrŒ#)xP ò\À°ø‹ß¡C(è¥p@¨\¬V‹‹õÚòUðŸíæŠ9=‰fBN—o<Ûß}øÑûíÞI÷èÇP:v}Úí›w¿ýÖ7~g<쟴v{í=½ûðÇæàzvº5–˜»Xt[Aj<‹ñ‘“˜Y¥6ò)»$º;Ž„G`>-NàåJ:™üW¶îއƒ þ-<nmíFi¾M;Õ¹5Pq«DÎU-¨÷óó«×nÌåÎW‹¡LºÞÏþâûÏNFM€YeîÚ ½¿²~ýú½7ZGÏ®½ôÎöãÝG?™ŒÛÌš¤“I´V!$±%Y ˜œe$ØÌÉ$ò CÀñDCÇ!8x~i}óö×w?,Üp¬‡½çÕú¦ßøv¾Ø˜Í†,+å†@âÙ…Š–Øäº¾ –¸öÒ·oß¿rëöÇ?ÿ³Bq¡wvüàÿ~Œ‡8ÖWn6Ar€REYvœ3÷¦PaJM§{16\tà h;ÅB¹†”<¤/€Z#mhžçׂ`¸}Òï2`-䫎XxUªt®Â*!™äéÅWËN/‰qºA„W€¨c ¿ýWÿàá‡?\¹qwû§ÿýd÷çx§ÃÜÅ 09ã7K”µv%ôYtG Ìàxaš›94KWÔž0ìÂpoxˆ€J• Üè·“pΟ_¿ãå¨Ý>=<ì û¥l„Χ¢ÜÜE¾Æ©…4߈„ñ€9`tÑOˆ7W¨Ý}ó7“['g÷ßøúûÏÿœaq£b¡s#K[Á ¼D—†m<CØÇt‘ÁL@ô$¾ŽNƒ9÷œÒüÒ¸sªÐ’·T]X^»QY˜Û{¼}rø¤P*ã\±wúݹÒu¬IHG‡‚:º³ÁL§ïÑ] ºîÅñÄÁ¶Kõµ[+·_}ò«ŸÝ¹wï|ïW{;Xz¢ ÍQº‰SœîÃÐ9÷5H-Xt¶EçïèFsÏß9°%Š:ACuH®…|¹°¶õg/¾þoï½8>9:œoÓµFžD“ÿO¦xœ=zYŒe×uÝ™îøæ¡ªººªY=q›I‘4%J²+D`‰CÈ(ÄóÀ_ù4ä3@¾ÄùHàŸ8? ‰'¶!Krhˆ¦(‰“I6Ù»ªº†Wo¾Ó™²öyD84›ÕïÝ»ÏÖ^kﵯ{ç¹`Œqú‡{)SçšNÞ¯ê¥Êæe¹*ñó8N²Ö^]O«¢ðLKYç™sÜ /s†{æ™b^{aSv¿,ŽsA ¬sÞ{ŽO ï sø,½Î1&ð† &d˜uÌr§<«a‹x £OsËñ®8þÖãiL⥪uq<@†?Å‹ðXElО_Lx;ëa€eVðXâ×$Õ >Õà´°î-ç1|À¸&/à'ã½~·i4l¶Îxƒ×áó°ßÃ4NÂè_ÞÈÂÑXkxPç*Ét¹ò¶ð<Æ£ð@zµŒìc‚\­œÁ#ü j_§/‡‡Àxìð™BPR à1Î³ÎØ˜Fr˜¬lÓÉLãŒ÷ð<ÿ’Á—8¥aÆ×ã,‹¢¨EǵM(fÈr®†ÓPsQŠ×7u„*ò12ÅZd9A–YÛçU¡Ü­„uÙà†£¤Š(ª¡¾^©$·º¡³2ÉEŒì‘ª زtvÅ„U*&Üài«}©\[ @ˆ*Ì,º¸Cê©NÒÎr·*œ©J£ï6 Jo à'›ÇH¥ÒLªL/gµÑTf¨f5GòÂùQ¬qç "“€ÄU¡:@0)”ÒðyÁ|"³1ùÕ–ÞV€açWäCÙ†ï:½*¢&ß Â.`!Ì@ÊaXࢄÌàZDœ ä6™ïñïH›Îør1?ª—+¤¦­ÑAàAÅGUÂCLkdhèÖÐPE pIÿJe J1P¼i Ë ’\qªJ!£6þ¡–ƒrÆëË%á%üÌ$lêŽUéêbîÍ¢Ô-lˆ)jJo$2À– ý‚º§vá7õ‹¡ây¦.¨lñ{n8Û|W¶ ¨‘ˆLÓרÆ-ÔOÒÁuj$*FõGqð–RÀ'[@R,ðH©>S¯Îq” CMúzrêj@Чc›—zL£ÆÁ‚« (©æqüç°ãYC*ú½ £ FOpÚ³§fa‰ÔÞ¥ŒQ^¦ ˜ ÆBar^)”uç;ëÅ:i‘g-âxmQ“Íô"Ê(N½Ð¶ñ(Ëu…Óé(ÍuYK)êu!Tš{Âå ÅgtÉ}À"@O>Ï74†2šÜ¸aKTJ&°K¸`˜“y6Ø}¶\¯ˆ#º¦·{íüóÏÂ3€³Û¿Y3@6a‚.…Î|Ôµ Mà*‰°9mЂ,õ3F}„hâˆoá8Èø$Fe¡t—Ëå¼\NE΀)#FçA¯\à›ÜæTÈ6T:¸ ?U<°3ªkßxc.=þúüìÐèºÓ]И2U("Åú—WéÈÔË@•5e'O ÕL’ ö6Õ 8¥5'CýH$yV.æ~Cqàn¨ª(NFîÕˆ–®q4'C8Ûº)ú&‘®Må áW¿ MÈ#”§ˆsÏuè|¦ÎöãFã%pÙè E`âÅØ¶1Õ†‡Ӭɯ®±°Ê úJ´9O6ZA¥ÜD„#N”h`U5BÕJ’“Š’(>_1$%ÑR¾ Vc›@ªe8YNÿe}×ààÓtô$ò³˜âð*¦Ý}ç,˜Eì‰ ŽXÌUkè굊Zqg¤Ë¢ZŸJ E„U9í½@*Âô#DHžæ 8?ÎJ™€¦VüO¹›ëðêk*j#9e„Ÿ5–à¡gá9d´š^FœãÞ•òü‚Ëd„ÒæXFæÛ N„bqLeãjù¯‹ãv’uÑ0¢´µš<ÄS“E†ƒÓš†¥ ùéU”¤KÅìTäQ¤kœ—„˜%™`æUŠb÷¦†W ÕÑ| öñ·ÒÌj8R¸ÚÛMèpN ü}8 Žˆ£¸ñ¤³›w{åRª[ƒÇ‹Ù9µÕ¤­uf½:bP“SàdMéB©–§¦æ¾®©ÃÂ>Iæ) Ìd¶q¡}+âi¤njáˆ2QJÃpTʪ¨Õø*'§ô.Ö„¤"šÁ‚|¡&Î)‚ð³ˆZ xè†éè†kÖQÜ<Š»Ü×ÈÅ3¬oÖSA”A„„àÁ\¢8äÛ@å1@4LQóAÿ‹3/R T³ž#QC"å‚ ‘ŽŠ¡7…­×ø<™ ÖAX–â‡Ì‘:‚xtõŠ,Ä©‰ùxR¾ûÌëäÛõ[ßZ®ŠÉÑp3bÉq?éîK‘7¶¤ù’ íšR×sÁC½Å  ÂÀÉÌÅi· ñ†~TÜÌHDÔc01“™ŒYЬ(õª)g%NŸ÷.W庸NjNÚÐ]×TÎ ÒQIÜZ߯Ó@þ&,º ÀܾöTÖjßùɃŸÚ£+ziÿúQ”sTÖuìtÅÁrÖ'IÖƒÿ^VX„ƒ I‹$5‡áñÂZkÒm„o.MêpÞf0=J”ÊD$L9#B^Í[à‡¤øÐ+à"I³~§V¥Èàf½I7ê쪰Չ«–HWä‹rÐWN¢Îµêì-‘ŠzI{<ºñïÙÚT“¨5‚¡ hÌVM9•I«Y΀È¿!&Tªp Í‚Š[£áÀLašÀ .p0ä'Ëö¹mðQ¼ ‡¢ˆh0¥)~CyoV¡!2õq~My‡rή1"C…->g*'I (‹.)¦]ëù©lï¹fb—·ñ²Noüø?ÐÍ\Ä®O‘F„Ò Úzj!¼ë…Š[CľÝ.3NOÏÁ ’öúhy|‚‚óÜTsb%J"Õ¼jáy»Ÿ¯M>ý¿‘Dµ_{ñÕ…Õg QfJÄ‘ŠGÀ@SM£(«æwz{¿Ý]ÌO/ªÅTÊXF=Ùé”§weÈ”´÷VÇÉÌJ&ÝÁÍoC&ƒQ88\eкàð„ ”«G2@g  OàbE2´zÙjuŠòÌRCî@eÝÑúâ°Èûתj ÎÓí|ÏΉ e#+v2mÈœrH ßð$ž§é¸šßÃ3'»×Ÿ==¼®‡GAÐÈBFˆ’­fÈÿ(ï>ó«GŸü…ƒfú.¸õo¡JMµ Æ¢K·-«”Œ‰Ô¯Oƒ;ÃX‹ZTÆ"Фs¨‹µy"²ËªÓÕ¸˜¾o«¹R=Ϋ,Çsúkèøâ3]¤b/c®Fi{Ÿót½\zWrhšðô’m¯ïxü¯0&Té¾"« ½º˜zÑ%ñè­Ê·{îõ“Ûïw·oœ}üG¦žw÷IˆŽŠMÕå H~ÜjÛ¢°¶$eM­¶8u® ‰x 2Û,¿B°L…,T/ÎÇÍê>àê›%Ïv½L\q/¥lÚqÑöøÒþhÿàÑ݇ӳCo¦fþ0ïÆÖe5ÚOu®B õHE ZPëª=h%óûïµSm xÞ{„¼3¸¢W]u´¼¸ÛÚ~U¤]âÛ x4·,l 5Íœ 6ºlÍŒÇ#¶þ Ù#TÆâm[Λ¢VlàÒöš˜©'Þ4"BQW€ÃtûiÇûÕüw‡—¯=qç£w\]n]{±5ºqïÿ®×ÚãkÚ4ºX¹æŒº‚n¡Û 1˦¶í½—ãþ¥Õý·Àä×ç‰(îl©®áchëó·M9im•E4¦pH] ¼ R5M9í‘í»òÂë3¡Z¨pæjÙ¢y…l>çR±³aøë ‰vÒ=ˆdCS—t$å¨3>¸´¿tü`vø¡]AÔõwoVóGÆë¦,d”‘®Û—V9QŽbètv–‹)(´•Ì-^ bV³; š¤ùhu~’¶:Ëó¶Y¥£/sØ›ª p€¨5¶zÑÎãÖ•¯Õ‹ÒqtÍš£,•ÕòT$àÚ çs4O@…ˆ;Øn¥5 اJ‡"ß·Š¥EHÀ¢$ŽV'o¥y¿³ûÚôÁ›–³AÊÒÎÜ2ÜÝ;{x¨ËMç¥o~ã¯ñÁrrtðij*î-§§«ÅÅâüžŒs M>¸4ÜÚŽÓáùéÙù½·¢öU™íx½2åÐEuömµ@\À¢ÞÓF #bPfÉÌ—G>î‰h hSX3!vœîï ùƒ: ¦MîÎTð-^ÏæIïIçÖåÅmênqOà6¨¬Ààb×4¬@%í¤³sëK_CÿàçoJU“Âå.’m™ÊÃ{ŸÔÅ,ïïÄqRKgE³:T­=•ì:37Õ)–ØX»ˆÚËŽL¶Ð}4Yan¢â¨Y1FG¥cÇ[¾9Eº9¶ @œY£á°dQõjÖ§è5Äâ½â›¹z7¬¥ÍcÒ}aÐ*i(™õ,_~î«¿ö½ßþÙÛ·?¿û!êøììp8ì,æÅñÝ7«ù9…ÓàÑRWe.¾@ɯ®™QžÐd ZêWÒhï̯qÑE“’|®W÷p•¶Ë‡$i–;Tº‚Vß÷ºàaÚ,ƒT´Öå©ðKf<xØ» Ý›ýÕòÜK*”Txï™åb%Òñj1¡z¢yÑq¤5I3 hÿÿ§ÃWkà%¤P°_ò0–ã‘I'ñåÑåH#[2·^ŒRÍT¯˜_Qwp+ Ø.èÙ4ÿoŽÀêI!)K?ŒUG×ÒNÄvÛ]ÏåôävhŽâÒþßúÛÿâ‡?ø?ÇG·9t$«HÂøÚ|§Y¼)Âø—7ùŸ‡r|™´™¹úœ80Í‹d”t@ç’¬åäÈiàÛÒ¡] Ú"@çÆIlDèïuøŠ©˜½ ÍO#Xx¾]Wk²9…‘ ¶Ð„6áÅâQqV×%±wz«O»Ûý­g‡÷dÚñaÙDÑZ ¼ÊŠ0翦™ƒ!Ðà>€£Ï@ãó¨5Mú’,ä$MâdÒGÅ‘V\æÒ¦ÕÛ1V颤dfx;²ß¢ß‹¢8/VóàIRš†¢,VðRæ-]ˆNƒXX·rÚËÐT ÂAšÆ´Gu¥I¦9CΤS€§nFÖ’ä'´)ÂO'’ºõà–â×ÖÎ,p¤(mëz… tF7Ëå# ˆp ô³ЭY)AsxÙ¦’=—2K’Èô’ÍÆÃ–ÄyšuËuòôYÔâÇ1Íç´saÌ mÛé÷›š‡±v·ªÂ 2tÈhÚâ8šxb˜$=(hâe¤¢4¾HZ„t¥3àHx6òÇPŒ w¹WµøHu¨BqªzðÓk1‰Ø–…Ð £=ùCóO™¦1^]•ðá&sp.*À²ý¨5©xE„ …kÃÔ%ÜìÕš‹ê½žßÒ%êÐð»AàJö¿x”«üºCÿꯗÀÐ/ ¨¥d#eœ„þ×Cl…<°Aö pØâ˜ÐéfÅbEržJIf½Ë ¾z½€”ƒ8Š:;ºõzAc^âE™0Zôa„LSݸ·£â]0%뎆Ð%!ñxs剗Ï?r[òµY¬W£á¸lÖêHJ]£Ýƒ‹Ósšaz4\gOšL&4žóf¬Iû0‰"hªÂèX“¸à ˆ)G«ª¥8ÒåŒûj<Þ3É \Ùº¼€{¹ž€oj8,€"=ï\Qù.²‹`𤴉{ÏÓº‘@X´Ú—¯~é+wÞÿ‘Y?DUr•£åÅ­2%Qšt‚»Œ²‹¤%M"<“`n°JÆ1ô2Ü‘d£¦˜&IVÖkjÊè)P¦v´Ÿ"âEÖŒ‡ÃÝŸþ èm]Q¢W®¦ºšÊ¸+Yc ³h÷G8ãY,Ñ[;H* ‘"3Ñ_’î , YfšÌW*îp³h· å×eA£ *[ä…ÑÈ+!’šD!Ø( oh*i­ŒÓ gƒH&ZÍÂq(åèíÄÒèÏ£4Cþ6e ]&£nQÏ›VÞYÎÎhm›óövUzuLÈO”¾¢9˜åÂÕ2¦Ýqšvç÷i B¤• ^ ñÅ{ Þ³:½Á³/¿úÓ?ý¾£¥@7ÌF„S±‚±´¬pT"¥XM%·i»«+\°.µub {š0ÅÓ€‚ÆM82í(¹Û ¨˜ Š‘”L¶6d4Ò²:ˆ0¤õ¡šhMƒ,JÚ"»j…gF­!Í^¬‹30ÒMµ’ÿiò£¨‘ÑÌ.RIOÄy”æVCAÛ´ÿSp… Å¢q´0D…×ñ™[¯þþïþK¥ê,–©“ßÌÖ=tút3§Ül{ÂdˇÑ.¹>8ƒlH®Ñ6ŠfùH9éhÝfQºð©m–‚f MøX} ÖmAƊÚ‰–ËŠùšÒ0NtÐ…ÌŒàȸÿ­’©•ø¼×+¦`õ¬³=Þ?xfg´½®ã~ò_Xun8#4q•¥qQ BJÚ¦ù0üdaPìV|3[ û,¼x§âTÁc2ç\NOÂî2!™–äøˆnag|@AP[¯6F†µ‘ D ñG4ÓC £ëEéÈš2î¿H«Oûëîh'ɇӣÏž¹UΖ7_úú‡?ýñö°•óéï½eLE;UÔ/R/¦¢‰>þ\âúS¯ÍWgÐ8WÛyùÕoÿÁþWà¨äCKIc—ªPÍa0¼±Yl^HqÒˆ¬•4cYWëõÒ6óÝÇnxÏVóbq"¹‹“´(Ê6´?åÄFàcŒ†&› u'…»1䮸wДHò¥T9:¼ˆ[¾*¢Þó´'Žh6Œwë Ú—ž:}tvøÙÏ•²ßú;ÿ¬›õÿà÷G›‚.—P;ÇÃ}!|ºZEqÚ"ZÈ|D“ôV Ò³8VQ˘µ7DL¡þ“¸;ØÞã©Ð]œ¯W³pÿÿÚ°>Ta¶œ[; § &ØÉd¶ekÉh`mAlÖ7Qï¹Ðñc|>n÷¯èj¢«eÞ»²¹º8FJ$yþ÷þÉo½û£¾÷îÿ’aƒ^‡Çq Š/Š3z­îA6;‡º© {aÂñ1µ€<*Ië²tº1øSÚŽ ZXS kJ~Ý lsA3ó/‘.lÓb¨lœÑ5 ü&ë_‡C´-Ìú<¾¢âDÑ¥.ßnOï‰DÞxúÕÛ¾M«jš6:òýƒ+ÿü·ç?ü›}|ÿ§Ž–ã&È"85"vôqUXå*ADÄnp~òÍ•h. CÄ3D§.ʦ‚z¥B”_r´e˜3„‰î5Ñ8ζ9ê˜b³‹¤=j‰Áãù††gã0Fãuñ(ßþf§×ÿ_~üþ§oÅjX®uvž\ßun©éÁ­Wæ¿û›¿UVª^}ÿ÷þ­„¼ ×, -»õfaNÉ(Ï[ý$Ëâ<ŸVåÉîÞ*éΗçó“y–<ÿú¯ßxñùwvhêk4A%° („èIôwEG ÷©6{{*m Z>Bè…û?x'¤ÕñÕþ~{°wøéG[—vgÓ“ÅÅD¨Fɼ $'£¶’¼¿å´yé•¿ùÝïýÝÿôïþýͧnþøÿëº8˲VYVåzždý¼3Öº¡Üataf½žërޏï]}zïÆsÓ³£ryQ—‹ñÞ3ï½õ§Öݧá—-=A}úT0˜†ÃœB~þå_Ÿwoÿ¨°ìô¬^ω¶ÒzÀ&­žP/.h).‡øpOƒ†NÕ)]GƒQ1ÔWXN¡¦×†l³(¤9ææzÝ¢KP)a4t®‹¼ä݃7<Ô_,DaûñÉÑ{Ô2Â=®°¯ÃÝ›«å$^”¶n>ûòÅÉù¥íÁk¿òÓÉ"Žõáág—¯>]ML=_¹yûãŸ=:½˜MÓ¯¼üÆŸýÙßÿäx¥iRÚVTÙ £3 $•ì§¶HSP³´zNs^Àæ7Bi±®ËiЛ(•oA%EX«Ó1²‰ÆôÕ´©+ðç$ë¶»ƒ§n½ö³¿ü“Æ7 üê+_ÿFgx¹Y™ßÿ«‹ÓÀ=]ÖJ©ÑþMÅ¢õüd´÷X’æÅ¦ŠÙÅÉr6ó~½¹Ö®J! #Çš/.†…Š ê@Š­Ã}™ÂTç"p~Ð(Œ÷À¬êb£g —èÔ2\6áÆ immJf4¸y:|Iªìòõk»÷>útòèAS¯Í¨îç_ùeÁóùÙÑ­¯ëÿãw˺¢ëdÌuÆûyg0¼t¥ZM_ÿÆ/«õ›þã£û¿ØhObC[6ÓàpisÃöZ‚ú0„eá Hß”N+À1xÐ/$›ò"\[Úઢ3‚žãi’Ixx…‚О ƒÝzåÝÝ«?ÿÉ›ÓÉ]§m»×{¼úøkGŸ¿·µ»_,V‡>Iqãñ§Ïf³‡D×h•èô÷˜óùCã6÷v€„‚.m®ÖºÍ öÇ›ûáè5 ͵]åÂy€PÈYØ(\ž"åɳ„¤ÛÁ«þ2\(rÿ7‡¿™Àb~/XB~J~R~Z~(1[Î~2*=B@C@D ˜~E h~SÈ~¼|€‚J‚ >‚ «ªª?»ƒ=ˆ€âHHcjß‚U!„"X%J© eÈ42Ph“èžÀ‰âá+!Ô?ê\OpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB €`fƒ/„FƒNƒVƒ^ƒ(1[’ƒ2îƒ=B@C@D|ƒElƒSŒƒ¼@…‚„‚ „‚ «ªª?»ƒ=L„HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB xœ]z p]×uÝùÞ{ßx’Aü‰¤(R”CY¢ÊŠe;v£N¤ºVœ¨±7v:Ž:“ÉÔ'ãf:Ó8™|Ú4n¸qâ&Ž•ØrÝH“z,{bY²%RR”(’âüá<¼ïýžÓ½÷¹” A ðÞ}÷î³÷Úk¯½Ï‘Ê·øeãŒYöŽ/ιµŒË2³™5!üE׸÷ðZ..>56ñ8Såü}ÎñÃ.œã7~_Vz ^±øShëþp²x x9|JÂ?–Ã;oÃÇà]Éœ)®UB٬͘¹eû ¹åwÛµc,‡GÑb-]ÆÉ6x^Àïc#G׸d|Mâ q/@;%Ý ^h$—n9h+7œ{Œ÷m´ZüEº•âºÐhf„¡Å+x$cãÀ'øà^´V¬M|çK๑z„©‹nZÓEcÐzx—]äżt›©ÞE6Hr¡¥÷-gмélËÉBÞÇÀ+$..ÆqQh5Ãë¥s³„WûèaÛËñiÆ›‹žb¹*ó{Ùè{É-`°Eðbò¼ußBý€ÁÃFX‰ñ¢pæ~waUÌùžiŽ«³¸ ަâ­ñî>®WªrGƒ- Åp030n%4·ÑzVÀ&3ÂE@(V>È7>÷äÎ{h!„Xq‘€ã(Üœ9o#no);ÐNZ¾þ–¯w7_$^Iñr8¥%ƒµÆ¥†C¯¿™eí:hò<Ì¡l@\eDÊø3¡ØIv¿—Õî±…üàIA6¼f œ0sÉP‰+Åèh-Ž) p5d•å) FQˆ¹[œåø:® äa…ö« 3½wm°&^¦ &‚ fÖ‘ %"`Lˆ‘÷±ê6ØHÜ­]x6'Z÷-d+8YJ0@3—Ó.1ÑÕ˜°”äÀ«Ð3‚'Š€;Iü€P‰Á'ÃnùÇfšü·4Ä<^ær‘™>"dÀ “|âSL–gh¦¡¥Ÿ”hø;ºš³ÔcÀSÐo ¾ˆ ŽcèbÄ¿äZP S6Á/?Úå¥áJr…IåOðt‘ø¿Oï”çuémÉó+\«‹ô«vð½vä>zº æô»cðšr©îhƒ3™ó'\‰a!χџw !MžvrëSŽx.Üý UÃ9àsˆÅLÚc묂†¤ˆ¹u7ÎzÆsìÐ+„Vxž*°É_eÅ­L)2IPÎë€iÄwÂAAŽgàyŸI—ƒˆwF(â¸ÎCèò†]}À(.ˆ:dcH:.^€pÕ›>ÊßM{ÍÜ0Xæ8˜ëY›`ÑÚš½osøP@\‹ Î6|„©ÓÕ~y•Dq Haîóœ”0#à}ÌD\[F–Kæ`ïÈ’IÊ~Š–-Gù’OõK9yÒ?œç…5ôÛ½d³e±Í«šáÍmFa¥Šk]Å/rÓ”xõ° ¦yyœãŒÐËò4¤üEo£70"ø|ø¼Ž0<¸–L‹Ê_àõT¿˜û銅®Ž#e)„¾ËÓù£ÿ§—uÞ4­·lt³O Aµb¦Í’eZð¼"ÚSʯ&©´Áv]BÊU^œæÃG¾?HåžüL®´ ‹œ4L ô¡$“så°D¥˜"ÐWÌi Ç–ƒ(¥+×’ G+µ&Zë¾õßÒµËÞÎß3+/`…-ŒÚÖÛ6K„W³áE™\Í2%R›GJ¿\¿ýñù9 ™eΡ ºÌ‚ VšfºäLbÖc2EÙ€Q¯ú<¯ŠÂé|=®B°¥¦’¦QôeÑÃŒ.,W˜;³º4ÈŸx9YøqÌu…y#,œC]4°“ò¥_y1 в‹‹½õ¦å&É0ÆÂz½œbœx`D¶ÝÚqÚÏÜmi F©+:¾‘®œ–[½Ýw¶Ë?0«?äÁ^ÞÍâ5Æ3 PÑa•„ô¬7Ij;DqŒ×îå¥ Ò JyºbýT1sš„–З $°ZE ºcZ”$å”§@‰f© ¢åðY’ (*¬{‡d„ PBÅË'ÓÆ½ýsBdóo×N ÄÃm¤NºÈeŤMÍ"ñ–öðd>ãe4¦0Á2XT›ùã,iˆ`£uO!K”¶`É-Žóñ÷¡|µ8³+T(êsa¸Å|Q„‡2ê)XNô<ÿ†…‘kTxd½6IõFåÖ'Àsó¯-¬g½ Þ{S¶§Éª¨È5,í¢•Ûmë  &±éÃfáYÌe 2$¿n§&‘¥¸x~`œ!;!*”KsT0ÒJ~¿t–²uZ.S© îDRŽx•U’v®Iˆá™?fæþ8™D)˜çC.CÃÒl­òJiÜvºÝ:'x£X0ÂëÄ«,(ד¸ƒš²´™oþÜÇx ”HáÆ^ƒ´§"×:ãr„ŸÖoXHxkꂜø´Ž»àO,^®Ä€8^}»ýÚýOL2ÀÒ5´ÍÃôBf\Ù%òGz7‘£ã\éöwñŠeùk('Š“rò£|ø ÊQŠâñO×Xy;"„¨£@ဉœKÑ&*B8 EþDÜ3©]Qà.6ø¯vTÑ:ûdxñIº':n‡p 'ks]R3áë &5’TÚ0:„d! ƒq^;ÂFïáÑ¢:ÄdÁvgYwVŒ½›àíÛ¼‰•ˆp†¦€ØF‡ÇXz¨ `ø?˜¡˜Tà8TÝ’êX®oãÖé¯èêfxè;D¦u×`žJa’ bî—ƒ,]í‹0 `úmšÍE·@™!uÑXàLè’Þó96¸ß.çsbË#̯C€Ï-´]¼àj®@yL ®FûÔk\ )]ã ’ëyã,íEºvIø>4ð,×›ÜÚ\À Hp“ bXpä¯ÍlÖu¶rÖWB¹R5yÏæÚ1k §¾UˆÉ‡Í•§l÷†¬n;>Ås´(jü,w ¨Ô’¨“Â):Š#EÍ([3j$%5ßJ{׿¨¤—À¹“9ò d°‰‘*^ÜÆÒÐÆsh?VÊAg±%Å‚(býä $KÁ¿o½a;óm/ñ‘{ÄðQÚÊ:ÀP)Iá;’Ï'$9¼ü–‚f/8.áÆi!ÑrDk¬ñÚŸ‚ÎQ‚†–.ÛáþÈé`‰X›©òSºÃ´ÞdÉ"f7,ÂÞ†çšÐå7ik/&Œ ¶<Ƨ±8{ûÚÆrâaUÝ͇ö’%à\Ü’C𙌠Wì*¸†2E’¯‘x8hªÈhRU†,”õš—¿¯ é\K‰êZ#Û€À{d–/øß›øˆR‹ÁŒÒÅ—PZ¬¼ÀU•™ŽÍÂwÌ[Å=0-¶<.F¦«oAɲÿL”·‹á»ô¦‡Œ,‘†dÔMKr›¢˜™x•5ÎxhÓD£ÄLÂUà(I{k MÖnH­@V 7ðRês;Ô/@‹Q΢ìM¦ÆÞ/6~ê¬qÞ¬4@)ibM“…WqFö+MÁToÇ'ÙÐA›EÙÌ3<5‹ÿ d­ê÷Ë`Xný0Â[XWÈnJ¸o:—’Kß,øMࢤsÁ«LfÝ•ðÊ7Ëû~Õ&‘ôKRû$¿!q ’¤ÍšgŸÒ Æ€f±O§’gº”¹Âd1æ—‡VÄØ‡Xe;”WÛº*Göé™Å—˜7È¿gE‘©€…³Ì‚CN>Ê*[E0`¢ÕlîEPéáñ œT7ÁiŸû+›i³òϲº8ɦ‘ªm+îü7Ì+2VÈ›wDQš¶¯$‹'ºç¿ºØöfÕÈ»aQéêqá×´7ìÕï•Ýþ¦; ÃÓ$õìêé';—ž«~bàž¿AžI;Pã·þ4¿1‰P%1þsÙâ³§´.n0Û>ÃvàÜ gPðL`0’ ËÎi!ÿpr"ÙFk^É¥ïˆÊDºø2gD¡lýE5ñ z§©°’)ŽX¥íœûFïüWÁ…‰#Ê+&¥èæw1qô„ ŠÓw> ¨ýßô¦„W¬Þû5è>’ùçmómÓ| ²¨Ò†7yy¶0ñšÖ^0´3|€m|Hà„JY qG9bQkYÒcXXqŒŒ•Q™îr|íLWÒå“Ùâs"2`¥­À?J ï¯=N‚ÁJ<¬üI»{é©ôæó<¨gY™Jg¿/ u›¶E0*²5]¿“û£•],Žî¢*™…×_­ù:ëͦËo˜æ ,I&…,]yN–¶¦Ís4H±J¶°[ïû  á(›Ñ<õž¢¡²r=5ÇRˆ²ÒÄZhEWÃóßJ^ÂÂ-âȳ8©ËL”Êwü:ƒ6‡37ûÃ?jø}*&^ᦫk·e“úSðR4§ý1t'Z•é‡~xíü áìó­™—à÷ §¬À,«gÒkßÀ8o`-° Øøñ+¡VÿWœ:Zg?gl½Eò˜+ýŒzm΢Ëß‚%ÄóÇmë"ä©…~_UlÖñ*› ÷~IñÐe`3Ôg&ëuÎ?Õ=ó®Êº<˜vV 4ª ÊN·8k0ÔÈݪ02|ð—Õ³K/þ—ê¾_Ü}ÿÀýO:6‹ÎѶo‚ÈgjÀ& ؼd!¶jJn:°ºéÓ¼0ÑèUZˆ†]K‹Õ_ÐÜÒÃyŽ5óg–߯™i8/t1]9îmþ…¬»Ò«ô®ßQeè”5޲8m0³öêƳ¯BAò·%½¥¬}‡M¨® ˆók*®îý¨_ß ªB%m¯D­¥J}kí¾¿K§lÔJ®ƒ›Èâ€XÚ¤ƒ*:D-Om¸Þü×zëûˆ±37ú )åQŸ.…ÃæºKCüZ/ÿAÚ›ç@ É ×Õ´yÆ9 «·‰â&ÎBclaò¨_?l ™,ëÍ|¿qü?I¿f›4ÕÀt²z„>QE(@þøýÉÜdm¯ÐÕÁ}î: °êÍ];ÿÜà‘ÿ¿ý%QœÎV~dâe“áÐ¥…í¶{}ÊåàÈÈÒr·xøOäÀ”Pàm„:ÍáÓ÷*PÐëœsCD¢xþd.TÍí¤dÝk½‹OÆËçåà./% Ï۬NJ¸Y ß¾Þø3 Ý+{~ÉßðnO8w¼ýú—ƒÍïIVÎF7_ä,=ú_×Þøñò냓@°‹;o0°ÐJ“®Õ}º¶ÿC¦=Œí Š2Â`·hÓVü"KðŠØŸ,£mD12¶e¹éñÊ–âO¿B'iD/£‹ëoxPT¶Ðh:)•%kÉÜ‹ÌÌŒ®‡’š®³1ð„ø[~!kÍ+ß÷=0…R‘Aq^^;ñ•$\1ÍËIã­`xOÜ]…²™µnf ¬½­ ãÞÀ¶´;;°÷—¤* íý=4JÃt[šú—¦yŽ…ó–v»p‹ElÚÍv.»qåÄÔí7ƒ¢0Üöq]A¼S—õf“+߸êÉŸ% IS Õä•hñŒºÝt.†WŸ? ªÆ‘ˆ’¥ÍŒ³Ö=tçè¿øá• ŠíóO÷f_®?EkXIQ¨»ùÈíà[=¸CÚ8‰›À&¥©6Ü÷I¿X„« Ó,mrœs÷÷hÔ Œ1²0ž…Kn§mrjÇÕ¹ˆûƒÜßT¹û³L”±hB‹Ñ¾žý©ËÁß½°¬‹ ®½ÎÙ¯J¬›Å,’…WãkÿhÓ&µeeÀ(ï‘SÜxWyÿ§ÔШáü‰¥üi e⦂ H¯Ð›ù Mçšð‡•.@#fx 5÷GßûÉLù_öƒa"‹=¶À6ßv÷‰ßq_frúеqËB¡=þ ?u„8߇Bûšé-–ïþ‚ôjIóm ÊjþT|õ€„¬ìL[½ÑCÑ•`<Ð9–·ê`,lœƒæZëRýýOúö¥Qcí•ÿnâ$m]ŠOxõÃ,žÓÃÓñÂ)Ö½‘¦5oh|D€ŸK›ÒÅWĂѻ6ú·ÅÉ1¿0" ‘ìn ü•ɨÉÅ!ý6n=8»Ð3IÓÄkjüg«w=‘5.êú¡´w=û +ø÷ zW¾mzKÑ—¡-•åþäýáÌsYûLÖ°xöY_$96Š&?Ð7^ÓlÁÖG–Wi€T öÿv°éHråéà¶™öÞÛ_M«÷ü±¨N˜¥—™zï /ÿSí¾ß3Q{ñ{KW^¥:Ê€¢à6Q,l~q×GZ§þ6íÜÔc‡OD¡Ð»öœ_† ÖU,‰’Ìf±>ÌÂ0Mñ “¬lÚ÷H¸|Ù†‹ž.Ð^²q»´i©Ç 6e6Ý8µ8¥ä„.îû úýáé¯<à^ΚW¼Têwz—ÿQ†uejõÅÏV÷}ÊHçòÓÙò)àϤ} w*¡³Î:/ ³Áø=Å}ŸVžôë»7Žu¯ˆ—^¶™un@o t·a¯ œâo|0m^Ô~Õ&kYï&2 ×…‘ý6nøºˆÉÄÔö†"`iç]HÜ<ß²°¼ŒG 9ëG¼=‹Ný™7ñ>›$áõg°¾ÔÛá¨ë ž›¯üG¨àÒ‚VËôfÉ  Ùx÷òlßX9hœ;þ¡oû›Í=óU™L›×ÒæL ʧÚÓ™…Æ/í…išôhP¡ÜV8‡†ÀŽ]“®úÊw9Îj:²"phE9LÓÅlbr×ÜÂt²€½DŒøËú;n´ñž»3Á*]ñT;Äéž¼¸œÆ yJ6n8þ­þùŸÿï˜+£­JÊŸõCPvýÙ3Ú-Êe‰^- g]^€Ã³”^”Aúú`Ðn#¡à‚˜ÐgpCœÑ)5<(‚›AÏ˱wÚoן‹;ãh¿ÖþôôŽÓ§OØüŒÿ‰«ú¨sXÂ-cÝñÜõ3Qý½2<Óß’Íï ¥ÿÙt;mÜN÷uç$*¹¼<Ž#Úl±}‡ œÙÏÙ­h÷3ÀÃS’TĿɩ‹—ÎæÔÑg›ÜÍ7:PæÎï9ø¸p¸ƒsî8.Í™Ñ~nûGí¨Ð1åyžJCÇ]dG×Vó é3É×ë¦îùÂ.ðxSǧ^Ö#ïŽsáSS[/^8³~Àaùε°[[’lˆ]0]aoÝ•9®¸uÊÎ]Æ%*L䨹Y†…… Tªqbii°6ÉrþÉ?‚§=0o=Ñ¡È­Ñ EÜ•æ|Û¶íçνÙßëe}‰déôÆú¡C—C\WlÚ!èæA·ÔÏX:¥Ëp¯ÐÐa<ŠíùeY’fG{TÛ‹¢À÷â81ưü ¾+(U”«_îîýì£bÀ׫*„a÷®ÛO~%ç>Â[ÏwûŽ\å·ÒÛÑcÿÜ"ç¹>!!äκrÒ?6«Ðí™Â/_á®{%‰ –ƒ2Eæ–Ö@s]Býu¬Íó@¸P’Ÿ¸Š[cœï½íà‰S/:clŸÐÞa­£»ýãëç1ó“2ˆFYb  L„³&:(îJÝúz±]rGýÀ­ÒO¡ 1YJ2‚œ&IZ’éLãÿ‹Ø ãxœMz”%ÕyæMUõò{ý:çžžÀä Ã00ÀHD““À’-+x¥#iecveëìZ‹ä#­vW¶¼’°lY€d!¢€`rbfzBwÏLçÜýúåWuïþÿ«± }Þ«WuëßÿýáÞú;ÞãL1ÁçF2Áá“+˜6BÒgƇ_w9S\HÍá%¸ÑÜaÂÀÏïp•þg’+#…0t€¥…1¿(Æð2\€µ…aœIü1pÉH?Áu|77 ïáð|x›¡ œKí¡ Ì¦þÎ#’ðæ&´À›Î5 –dV&Þ¥P#”H‚¢ð—[éPE…/%¹HüË[1á­ ßñƒ¡ç@<ÔÔ…m9*Ȥaø´Q´¶‡7ËãE´š”ãâ „ä¬éΣ%ÇÐB‚k¦>ã|™AN\V3'³ÀÍÕ”(-W¸|g¾äxI) ýBæE “ýú¯´'Céàx)¸$|5:‚“Øà G’ò?süÊ”ÃqTQj¼É àMw0¤7³£uA~øpáÑEAf‡‹ˆLÞs™ð?`V0æ ßQHÆLZ„ðWDî1àgAþ0Z 589Ík½®—ô¬Tè)\Jœf®(‰fGGH„b MÓ½§•h7X¡¿)ô)wÑÔ¨’à ä}º€;¶ø2MèB HŠ‘änAÆ$Û xX]É!Á`1Ç0®4ÞˆÒÂRWðÁ l…ø Ö—hoxT9ølËýgÑI(›O0vÁLa¨Â•@íˆJi U´¥$$ao´¦ŸW(¨Jè"R1Z¥1Úá64ÊðžÐƒÑ…Ž–»2º‡O.)[>1àb„EòŸ$<ЭùÞ± ×!(²/ÑBØ`áÍl‰n@5?(Ä+Òƒu"JÑFüÕ òÈ~ˆ î1 ,`|%E˜RèGY3£Sð" À4°¶O\àÌEå9EºSóŠa2ŠL| “¹X(9=E¿üBáÈø’ß‘Œý€4cc ˜((ŒV´Y¨»‚5¸•„:…^0jEÞQŒòÃu€Sû'ÆÏ‚, &5†š„øŒbŒ J´š°|F(ŠÍí½Æ*?‘5P¼% \†Œ,—”²ìF±¢8•ZIÌxéÛ x@:  ðÜãÁ‚^„DÕñи!Ìã:LapŠ¢0}!™#Ï 32¢:L1š˜ùÂìÇ-à  Vx¡ù ¹Úú}DÄÈ-«?êègD¾rS1às¤q‡¿ # ì"\w hÛþÉq¡ôáITOñMbn^¡-1²çÚŽÞRkf€xFØ‹0$ e%.CVG§ï oì -àK;2‚"TQx‚ö¥cP êhtd#Ð…·Üð‚¬[#c-–êá¯2°&*…8¶,dBÉ™­PlÉlQ`(< IEÅ’ý9q y†˜–C×%E=éØSDž ™ƒÎÅâ~r4(QÂs šÏ=×D€‡+ǤW}Y¥»b+?ŽAé ½*´á6v1Ñl”7‰ÍÂȆ~%H3ÊéŒÒ.qšl lla‘@Å_¡¸!zDغHl¯–ð~PYa F¶ÄàaÃ]©£®px„I—×mü¦×r…Ûv-x KÜNu #’ä…*šEµÕ ÕJVnDˆ¦zO“FAÎ,…6Ú$´0JODA‡òi G/{ˆ@‹Ž9×E 9 FqxJiH^Ë^þ¢»tmÑmÙ¢šàEI(<1 •¦¶¤4ŠÂ íkâªÇ(á†zÊÒšZ¤}LÛX–i[(YJA?.’R=já ©<< €ÈØ8, ©>ëÔº‡½w‹D«Jt B?AÜ0[ªq›ßmõelgùHXhY§ò† ÝôM„JÙ51+YoBíÀè:ŠYM-ˆå” ØN\t˜ À21‡{à R5\û¯±î[7‰¯¦³eXIØoÂÖäÖ鯯/©ƒr"P¶îµó0 1ܱn¥;%)KRQ… ©HÀš\PFŠaIU=‹Äª!þ/_£šŠE]w˜y¼ùúßÄ–ßOZ&¡Ô¹TÑ…i‘ÙJav,ÄéX$"V%•:oÌ2dBI [ÑáS©ƒüã¸Òã(uø¹£ó£}\ó;ÿ¨±ùŠïä.¼ŠVnfß$×?De9_*k)·.5ƒKvf¶+1Ä¢dsÃ?šŠ„¯-Àˆ3É_˜X©<¢Ž×4Rठ†­ÂöõØS*Ü?>ôÁ…»ÖõlMD<øNCÁè`ì¬â•¡ ZèZ¿¼åº_ú¹3Nf¥—éQu]‘l—°i4,Õ–æ~Rб%ùéNÛÛ†0 ±a{I sJ"@æ6ýYP ‘ÚÕÐò³¸&Þ š˜Ò|¥ïYÁümww&eôÑÜŒ¿ÿ¹¹¨6ó¹ùeëšwü/ÎÔÚO«d“ !ßÏ+JØßqjèXè7ÙɆU‡Úvë#¶'àhF4‚ýµ„Е`Íé kŽq¡$m3ëP!'¨gÆNM)OOµövlº}y*­¨´g.¥™ï†ŽLW«nœg7þ5 “›>m ó*U'jùXï5ÒvDÖàšÒÐRFá¤Í ¢§d‰a…Ì,uS™gó©’a‘Œô Œ±P„ÊÈSæ Ð"p^ô>÷au®æ¸U7Kd’ËÖÇ/ÙÑ&QGÄÛb^_8ä÷-”fúšwüCeè÷‘î[ËsƒÚÔÜH¤ãÖï0ê±,ª?(…±lqeL°±0¦JÀØ“SßAZS ‰ìj›—0‚°yÂF2JÄáxÇŸÅ…É¢_Ô‡ž|]zéraÖñ‹ñÆÎ[ÞQŸu<*'Ží-4·º{ÿm¢ZÌ×­ýZeò}·a3ób½wdz¯òš:‘aP,ÐâE±m¬ìÐÐÎÇì(ƒ’‘¡/4™Ã°¥zOTêàG%Âa‚Š\,u^A%&úç÷ÿü¹ŠÏš{6’›–Õ—çüí·57®É$ ^ÍUÏŸ4§ßšì?Ú¸å¯k¹‹±¶Ë¹—r›ÖÄÒÍÑæŒG&S|”v©N@ƒs[Õ‡ø‡†Îöðs˜h˜@5(ôAäI JdØä šYR¦ÀÑ N!iZÚÕŠþo¿ñSåºÑ÷Òm‰˜™ZwýŽ+î[UŸŽb!-øØdõݧ'‡ík¹æ§¥á×€ùy´µ6¦ë¦ÿ&ãQb9þQæå€K#nÑnlÇ vÂ@aáœMQ°ÐlGÐÐÌúNbúãVe@N8ˆØ^(œ|ð‹†¤ûÁ¥E5šjYœô”›lh&ëØpÍ5ŸlhiN—• fßëåþ·÷öÜõ‚__8ý2_v]¬yeua²íª‡¸ç…%¥$³„3I6æ(:¦xÆÃº›7RеóuŒŒ iÞ¥y·# \r%š²½KaÎ*/?òËÆ•[&?|ÓM5Ïö ^c¾Ž§²Ú×®[¾yÍ5÷5CÄŒzsêØëƒÙMÿEšŠ_žI®¸%Ú¼záØSB:=wþt<ò:Áx©É%̤üȤŠ{‰†:@m§¡l)`n'¶ÍÇÉŒ¢Ü4~v,‘MdZSÖ¨®«Ã±2QÍ?zû‡› í¸$ÙP?vúh­0'@©¾{}ÏÖµðž«ïnoHºEŸØ[8µg"»úÏ´azá,ô ºZtÆÏ­|ðÑxËÊpÆo)H[ªúg_üW/ÕÜûñi²H=µÆ4O¶çâä8IƒvpS­TÞý¿¥Ù¶ÏÝo¬3Ú?½OGzb8çÑ,7W<ôôá û^ŽÄ™LÇÂìÅriÑu<è»’u½•Âp]ËŠºÆÖ;¿º)ÝWÐh½w©eÇßV§ûËÓG#õ«ƒÒ¬WßËD¤k×+h7èØÞr©ÁâÈØÉ_}K¨èšû¿‘]Þ$¨lDŠà´´½Bþ‚ ûúó»Ÿyõõj~bÅÕ;7>psn$wîÕš¸úsÛbiH<(V‡ŽM¼ù£ðòb¬®Ë׋ËòÂL´®ÛóI¬¾lµ›j¿î¡e­ž° roÿº¿û¶_imfþ„©˜ovciHá½wþw/“¦a¸­*mö§ ü|º¯ï¹ï¹]—ÞÕ{óõԃؙ#¶'Ê:"\0ÛÇŒ~pöÌk¯T‹…X*½ý+Ÿ983}îòÆÛ6$;ß=”jj9òÚ¡ÝÏ×·­Í/L׊³‘DR¹N4³¢\Ε‚'}.#Ûî¿gûM-©ttÏK½y Ö´ÓIõêòX´neyþl´q­—hnÝùÉDK» Z`„^cûw ÞrnöðÏaåùxǶÕw>˜n­×.Îr´ '9Ì–To8< ÿð…C‹£…©“¿Ó&¸ò3ŸI´uŒŸ<ÿþ›M˶L/LžÓ~ÑI4–¦u¿Ïd *_ESsC‡3í±DCvYçÕ7¯¾ä2/¨ò¹ùò[ÏÍõÜñ¼ŸŸ¨NŒ6oŒ6ö:ÉæHb¬QÆ¢Ü I^RKÂÃÉ6›?{úij‡ã&/Õsíƒ;·@À›ì6\4ý¶5ЩöO=ÿÎèÉ¡ÂØQ/Þ¯4­¸tzh<ÑÜ\×Úpä7¿`^]$š*æ ã§ü –¬ïÄÒW›Î-÷Î ™=žéܸµBñö/]·yת—Ÿš=?(¼¶+©J½û˜t²©•;•#ϽômSíúØZ6_ËhxoÑ9uy’ëüÄÌ™Ÿ|³~Ù®dûÊÕw}܉Dpô-Í9—Ú1Êãˆ%ßνqdüØÙÒÂT¶§iùŽ-‡jéD0;1;{æÂÂDçÖ×üÉMï?»¿÷ï\¥*µŠçˆW\áÔ· ¼w"?ÓKDã ×U^<Ù½aC±æ{Nãú+;®þ®_Yœ›9ù|yìDfÃ=±lgejhúäïVßó—Ñl¡¤ùÇv„æ*¯<5~ø7ÞÐлkÕý÷fZ8®§ýQ;ù »xâ^—éB¡6qòœr£ïýìŸü¨׽冖5[¼úB2ÉO¬ºîšxÓò³»u^¯Ô¾ú\¶¹yazŒN4~ÉáˆØq&ܘ‹¥ÚVo¬LinhÇ#Exuiâ`ÿsßhØò™ñC¿XþG߆dQêýøí¬`Y(ÜÂf|hÿ©áwž.ŒŽD<'ÙÕsÝ}+vmã.¦(æ&*ï9Í1ß苜~ûï¿©ïPŒùåy°ºUW¨DO:µxa÷ NC¯ò¼ÜЙÎMW5]²~ÿÓ?4ÚI·qÕ¶ÙSâ-kç'úVí¸cvbDÔ vò~ÍTbÙæë¿_½¸ç÷’—¦öÿ,³ú'ÓÙ°öòTk¯R¦–Ÿ-åæëz{‘DÃq"ÓR/œøÃ¿-Žñ‹Ò­kßöÇ›?u§t…°€Ç˜×¶^å´ON<ðänäÖt}𣿦;ÓÝ«ª3³Æñ¶>p×{ÿø5ÍòãG…“u"^ëº-uÝ[û^þQ4Ý\)Wun¯0áòùXÃ2®’þâXÛŠM¹é‹Ü‹É ¼ó; GûTP^`A)Ò²ÎaÅҴæ*ÀíäÀɹÖÜ÷gTÅÊGÜ/VN?÷üÜÈQ]Í'd;¶µ^}_ïÕ›£™„T8ýAÖ¢‚ÇÔ|N‘¸==sn¦ÿ‹#ãÇθq'wþp4]Ÿi^&bm¹©ÁÀˆâè!îÆ/}àKã'û…(—¦&ÖܲëÌ»‡sÃv_~C}gúÄG¢^Ï•Ÿ/6ötÞ[+ÍK¦WÞýÌÌÉÿ'ÜxþâX¡]uãº?ýŸn2zê·ÿ µÉÊïˆ×7ãÜ@j»PY(í?<øêjùq7Ùj´ê¼êÞÍ|‡smÅãXQòÙÁ‰X&oŒåŽ=ùân/=¸·4×ÍvçFYu&Qß#cŹ :mv|é¿^uÿvVÓo<ööù}oVsãNÕÿ¿0 IW¹õLFî~ôñdkgÞBW«Õ±Cgvÿøÿ^ù…¿XÃê7¾ÿó3oþÞM6¶®ÙÀƒÒÀ¾½Ø©ià¶f^350Q5@ò·~í‹—ß½qÿoúö½¸ozà`µ<Çœ˜’ÑjðÖY+Vªäs8Ì ‚5ýºù’Kûßz|òà“Z癡s&ÒsëVum½©‡6ˆµoÛÞ¹i£Ä+V@óC³g_yi¦ÿÐâØ¡ZiÎq]'Þ &j\qYÓ¦µWþé]çÞí+LOxüïº.»j×Ã_xëûÏÌMäÇO¸Ñx9Ÿ¯¦$ð¸¯åÆ•Sñ¦rnX9‰*F“éTcÛ_üâëA-xü›ÏOœÚ—Ÿ¹(#ÑlûæÙñ¾ˆç浩8ñ´Íg/¶mþ|i~\(•îÝ2qøm¬ÎŸ‘ÔA·¶l¾yüä>ˆÛúK6¯¼áZ7áÎæ¦Î¼òló†?óW¥™Á –Òu /¼HâÒOÿù–»n†ßû‹£±ìÂþù´0}úõja&Ü­a2žntR›üO+¯Zýîc¯sgnüè¾òüÀæ{¾ðxßkO'ÎÑæ‘TËåJBg˜ö}U+—„€5ß@W§™_×½zÝÇ®=ñÖÑüT¿ƒ;2qh¥£É–Å©ÁdëÊÖe]…ÅêøÉ·*…â–?ÿmÓš>û½î÷øáƒéîùÑ}ÊÍr½˜î¹4ÚvíðžGëV\›n_qég?‰»#ïqžêh=þÔçÞ~‚„1 ¢¼D›Ínyà+2ê ?1²ÿ%4in(ÙܽþÓß8ô”çG¡’SÊÃ*Ö/‚5´ŒI'”ÁPD€BT, Î)ÏHå /‰c¯ZÉqãµj±rn"’lh[uåôÈéÂÔ 6&‘Y…©®›¾vþõŸz‰ÎÊB¿ j~uÖe³Ëo™|GÄ"©Æ ÷þç;7ãtšïýø©‰3ûª PŸ‚ ²G@°i¦s3dþôŠ+G÷½T-]ä~ ¤JtlÍœ®FÁêFBTk5õ tÊIÜXÒ/-J'†ó,¨8„Š×µÇê»ç†ÏfÛz+å¹ÜøI¿ªm+6W‹•‰ Ç„TÍ?M6Ížy)Ù¶zqrxD ‚*|ÀC‘D>…."ÞáFb·ýà—‰ú(ä¿þ홑>V-¥I ¸ËS°{ºEEÒu]›rC•Ü(äh„ЉŽí¦8ž›èÃV&’ÒµªP^Ke:0Ò•n"¨ä£ÙN©LÕüB57šh] 5³AinÜð@â,•§šzæGκÆLP¿úüðû&(ãi,#ÂjL)ˆ#p:¦4Îܘ—luSõ+?vÓ–OÜ3Ù7ñÞO~kHêšs~Ïc,¨1ªý*6S<'e o¯#ñVahC:ùdô)­Ü®ƒªÝ;áx–Æi¹ü¾ÞË·Ÿzùé¹Ñ>0 ½¼8ŠGé ˜T1ázÐ$Ô*Eî$uuOõ1àcl!þ‡=ô·Úx ªr¢~-om¿ \¯±\‰ 4nOJÑéJX?ð'{~ òûP90Ò—öiŽo:ðÕ0ž ·âF(›ÄC¨Rµoº}¢h\+çàFèߨÆçödªrx| èQKð¸ÆÇQ5Ýt†Ò­VJ =æ<)ä ^ó}x"¢EãÑJÙ‡P®–JLû¸lè6žÂJ¡FöäA'ÊM‡'ßBU=ê„:¼® _Dç €]7Ó}ÕÔÀ^¸Ž“qè{1öé0 v¿ÆŽz!câYƒž1ÈNÝÖÕ˜™åO{ê÷; N?©?R`c Ỏ[FãÙJiÎàª.ð¬ Ä2õý Îî¼t¸÷oh˜/<­«öt! Ë!ü P0¨š8Q€ñI#*ÚÕ&˜ÝäcvÞ5¨;±Û3U’ŽÒöqøOÓˆÃsÀ_Ȥ 6Óöžf„Ue§‡_€j;®”ÏeŸï[{}ë[ûp*<Ï#nxFÛ¯ž„{„PF‰GïÜúæ?6ÆžÁñìU8gŒ6ö®É=Ä{c¸KÝ/e¹U£-;FÇ„ £œ\1þä\h­ðÉ3ÓŒQ™ÆJ)ÌnÜ-ÄsqJ0¦rá¸øMö9 и qèí[÷=ùLk}›½€Ú ÂÕc$›‹£²YÖã®!fó8C.|—8ÑJQÆ‘d<` yšF*M½’ÚIÜ#ñI('„ æâ·ÓSÜeS´³:dpÄ>Š#Âõõ­Ýݧ©”ÙCí9jg7ZëGoœ¼™LëMO€1—°gñ{ÔÉ>fÄœJIÆ|_ 6£•ĉTv©'$ñ&¤qø»Ül<šŽãsë`á58ŽÙ¯­¾Õ:x>Š£1ДO¢²&Ì¢S¤ÍAw4Ë";4M×ÞmàT+|Å cÂNÈ-ÈöN%¥ã Çó¸5ãŽÿ8ao1rUvS¶ÞãúæÛLJÏ{ç½,z0÷E[4È”$S]²éòJí’¸_ü1¹Üç–Ðrbìóð!TÉÔ÷ƒ$y¥³¥¼’¶ñ“Œç‰(2媗2.Y\X½¸8=ëw®,ý„(.¨7ƒ¿¤y™\üÂr#ƒ„d·hoÊ,âêŒdŃ €g(eŠo¨_‡3(„Ù¨]5¥P†&&Ô¨ÇܲÁQüüÑÕê²QÑñIk?¹øëÑ“_Y·f ªÊN;® Ç1?‚G%1Ä€8\Ý1 O©@ø©Jq¡‘Iª¯†åÿ 93•°S¡‚R…¢öjÕáÓ½½mÝ%±ÇøÿßÌyS–²z7*CÆ}×./äÔ–f,Nç<>ÊØÊ§•HÊ :—è9î ʧúc,ø—¤Å´–š¶‚h>?_.Ïïìl3α€Sœ/31WS˜°œKnVPx„ÊæžÜoi-|‘&é@×p¨•Nh¿¥ã~šŽœðè4QfªðnVÁ|[ÄÆ‰Õ2껩°žx"ÔÍCüÅbîà`²¦tj´g}äê¼!ìY_q¸úÄØÍXýôø¼ÑÐL+”•}ˤLþ„ðmæÚpFã$¦NF ­–ücÂÚg¹øM¦ŸnòIÝŽãç !‚È……R¹²¿÷³ééŒhW7•¬‰\I$£%pÈÚ‘ÇL…+[›Ö®àìW)!!Èmÿ·y_0å±$Š'Bm2ý™,¹B홓1 ŠKÆö‹'æR€ÆOŸbïìÒK§MWÙEk»ð›§hq³]g‰mUvÍmcå„§:¦ž=ƒ¾iÉDHÇæ2û\‹&–í:ë›® 4øo¿À‹ 2,6–^¾üêJZ¨Í%à¸O8b¨7ëw2´Åsø¿qÜéžã:¾!~°¹QÎá}Ò4¶Eï‘&É$q3ií6lÎÄBÇŠF¼Iü14ü'¸__hìînO–h Á4˜I3½ îeQd‘i‹¿™<. G›ñ®Nl3f~{–º~*=¥b)-¥môFO|‰ÉúïÄ%Ž¥<3£N¨©ër$…µëo}õäSãM.Gûõø§é]ÍÄá ËÁœí§)ó\=ÚÄG·š¤‰> ?€s³\2*sÑèÂtX ¥Ò&ÍJ‚²€3ÅÔûŽõÄÖHÎ~~óæíGŸ4Ÿ:mtáMUñJðo¸‡‰?z:õ&")džÐõ ³æC¡x}?çœ\Ê­/’°oœ3ûŸÀÍ¡j”ŒmSGükHæÖ ¿^*uVNlßñýðöÍw~ñùLÏã²<¯òà3»å9(¨ÓOËÌ)„iªàì½I9{&rP€ÔÚ|Áô¸@ûGi“=¤Î£/"”b>\A w[éJ¡+3nÄö‰°RNÓøÊÊúË—µÈ1 ½]òWúïX:Ýçdcý{5HÇù\.IãTfm\ûa€öÄý<.°=¤(u€NLô9âlEÜŸ[ …åÆb÷¬Ó99&AEðÀm@Pñ˜ 9È^[¹vàl¨í‡ÈB¬_¿ùìéÿhëoY.³]’`gd¾¦ù.\GK3ÑÛyXɨMìÆŠaà©(RUÏK ­†Ì‹5o a±äÅâõ÷S“VK ¯w>a¢\\¸ C:HK·n¬ʵ½ç_ܹûþ«ý–à!ÃL@c}ÞŠÞ!)/x¼Œõc¢¤FÛP ,øwùä3oÜàÔmƒÐ6E»˜æ­7V„†U-0j/„:±BEš>M^iÓ`ÁÓƒ„nÙJ4ÃPT—¶DHÛ¿üçpn Kã~¡X+.?èµµû"¬PÁåæŠÝÎùÊêFàÏspð̓äŽð@IJs©.~TL:x¯÷Ø\ZmŸuYXSQ §ÔФC”‡Ý×ò*‹ýœö&Љ'C·Mð™ŸóL¬4”D‰拹œ>;zeȼòÂZc¹¹²Þ?}-u´±õà¤;xòóŸ–‹‘ç—Ln¬v÷­jÑ’Ÿ+ãÞû¿þmîÑT'Ý“Sž+V6Á.£G¶ÀˆµZT©_Kãx5Vo>úIV6µJ}éÎoîw^#fË#/†97tŽû•Ü\A°¤st` tRz´è¥²{pÎòóu¸ÊJ½±¼Ü¤÷ÖÍ~ö“ÓÎ) ‹§“+”–Wï€e•zí¬}x¼óigïaãîw Å:z/áyìöÃù¹¥¥Í¹â|¡‚Åp¦¯Úµù\óÚ] ¸è\±ˆ¦ÄqrûÁoíìî¼Ü¾óî·óÅò‡ÿð§Ìai~Qn_ °¢®ÏÂÑTä˜Uid/=ß÷H@D5@@Õ¦ïóÂ|­\©ÍÕkãV¹\Þ¸q¿{´¿{ð% øB%2@­œµ÷Fƒ‹0—÷TŒMoeñq¸Û¾¶¶Y]ª@––W¯÷»ÝÃÝçù°8Lé(®-lăã X«ÖoÌÕ×úg'µoTæƒH©ò‡ƒ¾Tl¾¾ÜëtŽŸü˜¹]14-áÊøYϹ²g·¥ÄÙÓ’óDå¹ò[·ï¯ß¸·Ð¼2œîì¶Z‡7n>ÀNé‹ÿúåa>Ÿ+Uë͵ëÅ|ùÑ/>Äž5˜›Oâø¤} Û9¼Žâó4–QÜmÔ—›•ƵFcY&z<æ›§'»•ÊÒáÁËõÛßMG­4ñÂÆ;Ñùq:|úy\“ð<ûòôçUHB˜›‘5©á÷t&ˆAÖV*‹Ëèõõ¥µ$9WqzÚíŽú]ÄY®5 ‹{ÛËÕòh˜ÆÃáâµÕÜÜÜâÒÖ³Çÿy´ÿœ ˆ_!­Ög>ús:ìs_¬m|¶²XªŒX–Îàìb4ì%ÑÅÅy7(”š›!Ïî½ÀÖ §ßyï÷’¸sÖuÔ“I×cyþíaŒ4œž}—aÎ?Ã6¶Êç"ñoð°Z®×ò…ò\¥Š‚8?kcçñúÕ—Ñ`ʲjW'(¡HF±†Ë›[ &õBiôÉÑÑ«¯>ŠFCJC­6,”¡ÛÀ|e}½ßí .ºp2ްܥ…%FLçäì´õX„E ¦Òؾ ">ö’¹BñÁ·~¸ÿäÃØ²‚j[•&¡µ‰Ú³=2,ŒŽþ¢XZ*Õ7ÊkïÂHÃÑ0FäÐ¥ç_@‘/:çnÃÑ̘ð1*µÅ;÷3êŸJJ_ïíÈt¸÷ì‘‘I8WCšÑ°W­/–ë‹'G­‹n‹òôƒ<¤^_i·[H!?WmnÜî¶ö^<8'£®3føñÃB¸ºu/þä/)qòoÿãv{tqѶ†Ë*ò`5šÒ|¥Êtw®¶, ƒ~7M¢ÐÏõ:íÑh üœRQr~Œ•5Ø^ÑR“Ä#gÔÊÍ{[ßøÖ{¿±ù¯ÿøO»Ï·»§-l­Pz ûFÆ®b«—V7â(’J–*µ0_Nµê„¹B£¹`Ÿ?ýêüôÐíM¾Ô\h6‡Ñªæ3óÁþ݃ßùÝTòø¢óø¿?~òŇñhæE¹¼pâhÔníì={{„ç<»#°oÆÒȽ2Ò  ØHP,†èaZFvëdÌ|m8¬o½ûÁ÷ÿ ^éÿõ_ýô«‡Gç=&¸N‡*´a~ ªË›•J•p_'æøxqus¡±ŒFˆê pýY·ÿüËOŒ’~¡T©®tÏöQ&0 ®Í§ïçÏ‚B¥¼°$=>žõÏ:­Ý§Öøg­È®ÈȾ×2̾Ž3=ÈvX»I<÷2Ä6)ûöÀ®œ³2nËCÊ}ì€ÀÒ­{ßùÁ~Ô;þüoÿæ_º“xÐa=/_®Î—kXeôš×»OsÅÒEÿ¶DjcP^hÖ›C–ŒûýîùÙ©õœ'±OÉ\çúíß„(.4ûƒ¡LP…Ñù v¢J&Pc£F¶yv¬§Mĸý¯t=Áǵ3™${¿š9pÂíî‡xBä*K7þèÏÿâlC"[Ûíý¶’ªs¼ûôñ§É°‡Ø<í¶B ”°ˆå…•^{¯º¼Nx¡üھද ¥}qCƯí °6äÍïåÃ< Âá0ÄCøTpðª47ìf6{5ªèÔÝ)¬³;gþí*`E8þ÷Êh¬®Ö$Û a®týî{|ÿ×ÖKŸ|ò¼ºxý×Ô†Ò`ŠÃΣGÏÚ{O~üÑÁÎ6¬=R€T–ÖG½^}m³{rx~ÒRPr’í²×¶{rNêKËÝÖ3o6fc6fc6fc6fc6fc6fc6fc6fc6fc6fc6fc6þßÿãoVxœíX[$GVΈÈ{Ý«««{¦{<ÝcÏøºk™õj KÈ€VB†•/,H<°OH<ð¿ ío¼ ñ ¸¬ieÁ°Í³¾¬ocw»/îîéîºgVfÆïDV›ÿ€*fºT•qâœï|ç;)‚†WkñÁxÈó¬¶~2÷‚î2\ô ƒ ­•çqÜÂk1MÑwLÂó8÷EàËJyVxnE.ü$Œ¤µ²’QÔPÆU,iÝÚ˜á™4iT¸¨¥!“,¶aìqšO3±…q{1,†USgž74™ŒûÆT°ª>‘>E=Î` &“ÍXžãYœÅÙo™ÜÊd~rã…Öh¬£¥ÄãBøŒsmXš¶qvC6ÛªPõ0Ç懡1 ÿÈv¦q$?ˆ¬VøÆ™%Q¹\z,ðwv.ȱn£@JE—üXÄ«sS.¬§“´m´®ª‚0¯µ, iwÊHƒåãfWUKUi:‘óŽg•K 8?â"­÷[áösì¨]gœÀ]JÌ’f2áݘèÕ¹JÁ Lí2›¯&0w?ÄÙ¹ 9`cY¦›UvÉ<å¢OþtTÀŒ¢dk±¶6FÞ ˜eW¡„ýX‹À£RûöÐ'÷#âS9Ìß ˆ»ÜtV9r «­ƒ:Mãz'—_¶þ/‚±öÀØ0 -O•¬|‚ã.áèO ÒÔ`hì±¶ÒR­¬rA†ÿ‘Gð-EöÐ^†û‰W›ãÕ,7E‘—d7ì㲇Uõ¤ß‘ñ´ÁGäæÒX¢ÛÄÀI³lRef©– .ж> -凪 ¼nÁOª’<5ÚH|øt$ü¦Ñ ­ëx[ëHS˜/ZÎþUò®`-À ÷¢ÆÓŠq`¥BìÛß«¢Pî®´„m«æˆ x%¤|Döj¥6a[U™Õ D އ¸tjÄX¥*2 Ä⪃ó³‚á| ¤Št¨™!êX½äabdyƒûu>ÒC(”¢†Ã+]¡‘Þª.0ÇoŽÿ#ëÓO¿åé Ì#Zñ‚86 ½dC«"JšHƒ2»¬·‡ÓƆU¬–¾Ï¨çК!Rº¢ƒ€?äÒµ*¿ö?võ#Óÿí ŠÚ׺Ã?+o;ÚqØ#ûë»—Kú\TºZFeDΣ&A¼6¶ákÊjq ò!P¡(y «ÕSÄrªG¹¢@" Š@ݺš»Úߢ[$9|Øí pNww8+<”WYh™[V™bUÃ<Ц|Œ½üÆ6–RÅÄçL;6? š[ÝÛßÈf2Ÿ|á³¥„`WÖ E˜úé°Yµ¶ž"ž¼Aœ¶Ê_vc¿uÄ’ ˆª'˜hZ³Ä&RâÑ¡ð¤R‘gJ8\Ää|$[E¡ˆ<”åóÅÈ€sʪZ²è¶•Ï.Y¸Íõ Pû!Hz"Ýo´Òb~Î\fãS8„î:9 K†/±â*›~ÙÜØg¼1?ŸíîÕ€ùø=:BЊzÒö–QE )y£Óùêó”&YE*”r„ÈÜ‘¬¨°@‘µAÔ }-ð LeA ÿû‚)¹ð“ öÈÕ©a±Ó…×,èWùi+Û<2¨V5e.§_y6÷ƒ4ˆ‚ªwï¿”g ÒO–Å|r!UÕìŽ/NüÖ‹µX\Ó© ?uwž¹:;ßÜÝÛÙ½ÓjnËüÑ£¦£±2½ˆ(LåžH«%„fNmw7w&ˆxMé*ÔÒ¨ ÷;ºy=YŒŽ@0¸µýü+©8y´Ú½F£ åûì ßyô賓ãƒÙxRæ™VK']PTìJ(¡DpÖhnÜÚÝŒ.®/¾J›érz…¼)s¸rºrå#0å©‘ áƒ!Q›PVÏB’Þ¥*¬&NÝ£òHF:=RIÄ)%sYf¾ùêéÙeUäÄêaÐ?ºBAA>~ÿÿ!¢ËÇgà»l6±ž__œ~’u‚Ç5_D›6IÓþ`kw§ÛÛ¿µ5ˆqxpøÖ¯O¯ŽÓvg>B2Öìd\•QéUª£`mS^ˆ0âhîü&R†{¥+‘R´ QFI9¢m.ùt˜´À‡Ê&øaTI•ZWp).?yîÕ¿hµ»ýá¶ï-óåü“÷~qýøDW”QÈíÛ{{wïÝo6’^¿ßì<‘-®g×ýÉÙ1‚òù'Î'—¼nͬtåÀ¬–¸þ᎚S—®Át!¢ Àg剛"b¨G(Q-u•=Ö•x L¿Š$´×Rù•̯wÈ,x5lÞF½øöoþUÚŠ[íÖgŸ~r~rÈŒ·sw°‘nl=±³÷<ÎrðéGv3m Î?Ev÷zZç§çgçJfÙ ”ŸTuùr)p¦J¯Ó1žÉÓV'ŠÃ|rꞪ8íUPgÕ‚ú;Þ–—TÓM…bѤ"¢Vog>:élÞ]Ì2`R.NœDi$Ý}´¡QÿäGïV¥Ý¹=˜LòØg§'Ç­ng:ºšÏ&Ùl6¸s_Wr1>Ó(I6²ùõÏÿëgŒËN·Ufòø²‹štW!SÖ‰1§Ø‰j­JhÌ ð{½äêüÈYÁO1ÄŽ [¸_`}p©qu™äÊ0NRom*žªrK˜‘ä&èƒÖ.®øQã÷ÿüÙå˜ç‹Ï>ÝØ¼­TDírq-ŠƒÏÞouºÈ­|6mtºI«?½<7ºÚÞBáΗåõÙE‘ó˺÷w _Aˆ)ò¿ÓöJC ËFkðâ˯¼ýÓ¿Mb–e…¡c:ÅÍÈ`ò¶'jùKIH÷IlH*úM Ú‘)+î§Ð$¨+ßúíÅ(6£i2ŸN»í6I@zAPÍ&W­öfYeGG‹Ù5"G¼rkwtuŽÊ´ÑÌÓñù#×-¡Ü»”Z­:PÓìn¯O>÷òøò4;{8_YëW•r²ÅÜ<†º¤V·ÑSN¯Ï(tZ:™D/jö_¿­€l@…kîtïÿa³ÕÝÚÙçÜ~uôÙpc¸½ûdU.Ùbôø¸Ûßèu7?/óy¥T§ÓC+Ýo5Ï`ÿlZU6}LlÓ¾¹ÔÕ.‘¹«ç¶Ag¸£Šrk÷©óã_þî¯þÇ¿üµMJô´¯ô˜^5=®«¢€li4†Ò.óé¤*s¤3ðIª-•Su"êS W™Øÿå?ÍgE«×D¯VÌÛ·vöŸ}±A9ÈwßyóÉûÏÏ¿8>ýòêą̂åp÷IôÙfëòäËÆÆÆèô@U±1)XRèÞª—³}†6\ÂIÉQÚ^”U9¿Þ{ð\¿Óz÷ÍÂAÐÂMôJTÜ|®å$Æ­ JQwd9ãaÒŽðÉC‹¶‚^7¨ã€\ÜÙSÕüÛ¿õ—Ùb0Ϯϕ,`O{swçÖ®ˆ¢Ùèâö÷ ¹ÏÏ.N>’eNM ©N›´·‹Ù(Ô9^‘Æó\ƒG¨–¥N‡ûÁÆöžïûÓÑ…A‰Í¦8]ÿö½ßý½?zïí×?xøP< bpu7³ëÓ½¿4n[££Y!uæ(ߤ~!‰I"r‡.µïY\©F÷_ù³e¶,ò $ÃÀÜ¿½÷Ì­Ý;øþÉï´ûÛ/}ë•§ŸÝûçü»þŸè¡\w@¸ÑÌ ' ú=™‚põèu½Ì ’TAYÌPXÑâôv÷µßù!°ÿÕáFˆÊR6)¯1Á‡*L°\U 4b(|V- 3DØRň^6%](^tŒÊšÇÃ߈’vg°¹9Üí nu:ÛÛ›Ã^÷âüêáÛ¯úÞÏÂßðòp÷Îx:{ø¯?¦{N¯2äu×d¹¤Ò(?NCÂŽ!‚»ŒÒtüø¢ÕqWÅÜiZÁXðÄݧ¿ókß¿:;Ùì·/Ž?Üzê­ûûYå` Ê"¡eIMDB~äÞ¨uàyØm‚¤Kºp"Ñ–¶ŸxM²ÄÄ{6[ýW_ûA¹œ~ô?ï¿ûÓ8é”ù$Hš²Xân±\8N±«nÅ¥nûhåšE[ⱆ0^»µY¡~:ßñÅ0E/Ð<Óhöá²_íóÉ55•ÅâÝwþýúòB)édƒæÔIixXå§hžQw B´Ê¿AÒÒ6† #fçÍÁ˲Zêúm½ Äî­_ùÞåäÍŸüMµœ´·îÎÇ9LB[ AlÐ;OJUÍ=tÖ2ŒšœÞ¦ø²È{;Oª¼˜\üF&ýÁp6/g׃­íþæîÅùÙäò°ÛÛj47÷Ÿya2ž¨²zôñÚ¡Ë©D'4ˆWÿKTa ÉÕUþ˜„£ŸøQä °­,§Içiˆ"×§ÐÓÐýŒZ’xëî Ýán¨Æ¿xøc»zm V†§‹=žÚ•´Cç¨PMý$6²Þ¹÷Ív»u|t°ÌÇe6Ç÷žý†®øÉïmnïolÞƒ}ôá[þ ,õ`8¨JuøÉCz§þ®n¡:è,žÎ¨ ¦v/”ËKWÔçÔ€HJgê>Öc=Öc=Öc=Öc=Öc=Öc=Öc=Öc=Öc=Öc=Öc=ÖãÿÛø_6Gò´€`êã/ äÊãÒãÚãâã(1[ä2rä=B@C@DäEðãSä¼Äå‚’ä‚ †ä‚ «ªª?»ƒ=Ðä$HHÊ`«ì¿†‰¤éÔÒOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB @0®è/DéŽè–èžè¦è(1[ºè2é=B@C@DES´è¼hê‚6é‚ *é‚ «ªª?»ƒ=téHHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB xœíYù“\Wu¾ë[{ïžžM£‘ƲvK¶äEòBlƒ1.+ãŠ+l†*0Î )SŠ‚ÄReIìø!€`†aìØ’7ɲV[ËHfï™Þ··Ýœs_ ©üÑ«QëõëûÞ=Ëw¾³<Æm¥|¢ ÿ˜MdxSpªˆb\Rc˜¬ü(á’PFüqBñNð?aBÿ‚kðÆ|Çõ’N9'Ïñ:.ÀúŠÐ‹9Þ ,Õ÷éåp<^(¸‚wH_ Ø ® X@Dü~ ŒPJTPjî°JT¤@xpêJ2xA!áWJ¨ˆe¦7 p•ƒð/r B€d Ág2Â$Ãe¨¡e( ‘Zd<‡5 Šj(XÎJNXï¥E( '6Q¦$†A O´‰Tl{ ²Á9Ø–„¸» ÑÈC"©M(•ZQ-ª¾3vAφðhj „Wê‹,¾· (´ p˜¨Z^»TË ŸÚŸh|Ê•ˆ¿âÝ L-B I¤$ÂDùA‰²˜`j¦OªT@µ3p—Á÷ªìÕ$6Ú@”Úx‚šQÉ„±,³Ôð1ô2ðZX›]°àg©µ Úò±%bM8ÑVô"Hb˜°¿ù™a(inPA¹5¨¼Ê7+¥Q¯´:ÐŽ®þ$qGHlv„„‡@Ïò¨£ÔH@¨hk„¤v„Œ$ZªÁ£]Çt°P¡mN— k9S … Úò¸¡ |`3TÊ²ÐøŽMlþ¨Ì\Ö øáQŠ*€”¦®¦C»¨‘SÚ¶0†èr-< ± ^è‰Å¨FÅêg„]ä‰ÊLÎc•uô3í -¿ö-¸‚1Œhƒ!ÚáW0»ÐòkäX&qjYʵIP4ò€jR~eëœT*$[Ùu]:BÀ/ém4³…W‘iáaËXÎ&â·FX@~XyÍÃ_‰î¦û¹tð_¶6S1½? Œ‘‹ñ«…8Šb:ZQlA%ðM,IL‹Ú–ûgm*뿤ê¯æ¨Æ1Ò9yef Rž$öJš¹‚8#T&! ˆ°)î$´"úÃø"ÎYï W¥îÔo˜™²Fn6œ~*@2›šÇqŠnTqØ@>ÕkpË–Ç8;[ˆ%K´pð3gÑ„¥äÊ©ÚËįbu&˜Ñ)EÍAÖ©=¢ÚS”z,µ‰}˜BØPsÙRYjÎÖüÓ#s¸ßA ¶f¬â¡¿C/ÈêËZ° ̃1+„f,¡Ðàð$à7 t„­©1ï€ýM’±IÒ…MˆH°ÎyiÀ½ }𱊤*Çxñz pÒ 'f!}b¢ð\Â0 z†ÝÙTgιävi9 síq#C’¤ËôHu"¿r´?ü¡W¥¾({äcóÀdRÒµHÒ!"òsI.`( óh„Ô¹1‡Œ I3‚Ö“<Ü1¯x8šú¾•÷í šsbªgšE)7u%ÇH£Ç¿ïÍ¿Â\vûGdª¨¯ó6F+ OE!uINS’!UCR¹€ „䨰љzqnÇÝ£À?†úUÙˆ<¡€SQ!óó;UЈZª3M”¯"·x#ßð©ðäc<½I¬ºK#D£Ôô+ÂÄjqއ†´òkçÛãÿ鮾Å,ŽIÓÒ•Nœž4«Ç¥S°\ǬN¯˜a ÀƼ¤–¡ Î´µ4¾4³þÆûÖ9id”þ½äÕ›RÚŒèBFJ¨°Ã串ëTõ( šªqTMª–X#7þEÔ˜ Îÿ‚)ß\w?Ëma=äÈÎßp7Þï/ì ª§œÑ[eb@Z  ÄÖ™Ýí‰_ýÛ)í¯¹Oû3ƬX®mt"r4T@r¡¯(€W³ ”ŸF¡wèGGš •BŸóŽ?¿ \0yÜ;øÔ„½â.Ú>©x!ƒS‹tÏÉÁÛÉê÷Ó¨¤&d›Ð§F’Ê”?þáü55Ȅ8oüŠ™YåÍ>¯¢ÐÌ­M¬¿Ç*¬ñJ¯·&žíν,S+Òv¥×l¨n\©ž „XàVšyQ3ç,À Šcñà·»OýÍ·³«œ”ù–{·Œ­Ï•JþÏþi_òª¯Þéï„Yj­ ­Æè‘‘»bª'½Äªs¹¢ÁÜ‹ÁÜKÔ[âéµÎÖORn#ÿ¨Nmÿ£Ú2½\`f6Ø«nMmº+¨‰Z‹íó{¼ê¹äØu™5;í¾!°<&ï}2y¡ÂÔ…-²½.•Ax8ÑÂcÍFÕ¡'_›Øû¼×m™‚F×½ûÁ› CÎÏ=™ÚùmÿÜ¢Ú4>”Ý#¿mú “–.Ò æ‰K6üÒïô§"½Þ^Ÿ(lžºåÚKŸ: Œ†$¨ƒ·dß•…«ˆ¼jsòùîüë$j »^}ÅàµÌ–Űøê÷[ ã4¨Y}—ômº)»v F¨FKЮîäÁÁí·ox×;uÉ3š?1ùÚ÷žt³fÿ†« •©#/™7ÎZN"5°¥U_Hf [nØxíöíž±³›ˆ·zU( á¿ì¤WDë4‹—C†K‡Ev37Ò$ Z§žÃÐ;÷dÔž©u »d0‘$A#]ÜÜt¶'¶| `ãOíæî*Q¸@gü§J8­×¿Ö^gFžùôå$7½·ºï«S?ˆÚ 29ò3aI3÷ö_÷‰ÌÚ·(¯5»ç늙C;ßc§l;Ÿ3®àªQ*½öøà®+ïh`ëÀ•ÀÔ€¼tê¹#¯ÿâ'a[qÃí¿tÃÄË¿€ô9¶óíã{~j¸yêÌJ1#帉º¦•¡ª ™Ka¥Xzðªj£ílþ¸‘ßàÍ>ñ ñØ™ÜÝz†»+ƒ¥WÂÆ n÷‡~Û¼!wã—ö~Å+ I;á/dö´ŸÜtíÂæ¡ëÿ´|â× ‡ itÓ½'9¯^Ú¾ƒQãüÌÑ>Úœ>0vË·Þ³K\H(¸ÛNÖ:öó×μøBuâ(£•i”Æû7l¾ì–›Ní=4òèÖ;Þyèé=‰ÜHmöD·¾`6´î ?Öœ°Ôv’­v+yÃãp˜Ú‹ÎÆDÕ³Q{^EAãÈ?GÝE¨ó Ó1³ë—ýIäµÚ³Ã¥W{Œt#Ù~T“Ùu@;ÔH´¦_6’C†“–Élr`Ýæ{? õ|}fîÀ·¿Ô˜>˜_÷¶Íwß1rÅFàÌ7~¹wË;žûæ¯g½(M±tæ(¦ß*™næŠ;ßWŸ9uöðQ»°ÂkuTØ ýN»Y5¥ ¡Ž.~€/e*;P¯—‘Ûi¤¨=ìÍ<›Úþ)€Aýµ‡á;ó/@°è[ Ó…·>æ•'›×ÍÓ†!˜Lu%¨7¤]P~U¦V\ýÞòÉçk“ûB¿•Û™½~óÝïI³µÉ¹c?ùáÔ¾cB o¿åÚ>jØÎ‹}gÓm7¾òÝŸ´+ ^£Úm5U·h¹V\vŽÝÿ­O|sqò°áä`w¯Sz4Í$4JPøè¾-—L÷7KL8<½ P°¿»ö^Êžû9ž·tj/¶âŠ3úη?T?ùtù•‡U{*m¯ÓN?øøßH¯23£`˜òÉÝ*hå×ÝÑôªn]{Ë “/8ÿêþ‰ç¾ŽS3»ã#•*Ž}êTEpûÙ=ß;pi:~§£(ÄBòοþøž'ž-OŸHW×K“Ùá±ÚìiZJݰ«xúÀe&“¯TJñ\…šÂ$¨òÌåÁâK¡W‹Wb»o¤¡¶–Ù …>¶*KÏ}6ì–8„¼ïƒÙ#¿iXIg`c¢5˜eþÈoÁÂfn“pS7~ꡨÛ>¾{÷ÿõ/a§&ÌTqýu©ÑË'ö>I‚JfÍŽ¹ÃOK)ÂÐǬªBaºÜÊšSU@‚AÃkVûWm™=½ß€úCtåòg³ùÅÒ,ÕãHê?p5EžŠº =EuÉqCEÂ*l…k~éeh¾½rû„•:í.½†`BÈ/Lƒ[éKo¹çê~è©Ï~¡1ûzcö0 @&ÜÜêfi<ôÚv~¬S:Á WâFÐ.c2Ón~4Õ?º0¾_f·µ{›n¡Y™4°øÔ½Šž™@ªÊç ó Ó8=ÑÅ?J«zãE¤Öb]aj¦4 QG"E B¥ªõcz¢%Á€¨Ö·ÓQàÄÔÐÆ[?÷ð‰ß¾pà{ŸG›`R½ÌoÎ{­&AîJO†šÕ”ËTÉP`cE³µõÿeÎbq`fæ¶ÃTOR°Öî¡F+C{} t—Pí@uJ„FP‚ùa¸Üòèé–žéq ì¢ô”Çnbäª] 'zíªß®âRébXÔ‘i̲Ì`¢¢(¦ä«!AôÀMO»"OB.$±0W!_œ›?O–^l0¯Xž4‚TQ,¥i9ÐùÀI€qX‘Šahö‹“É¿jeà»™ìë4€Çx„sW¦Õå”p¥eÀ6M7$TÏÀæaˆCB¸ÔMð9¡à&”Øýø™Ñjj°£ó‚¯P”‚‰bü/­¥0qsT±{ámúy U•”8´ç} v™¡îöô uÒÃIh¨é$8z˜ùž†‰´¨슰RÀG@—'$ÚŸ.sŠÞ®¿84=3qgzêÉË‹ó°$ Ú˱†4Áøà áhˆ`€Ú„øY°>Â^ÅÁ(B¿J|ŽFZ<µ­ Ë…V(z³LðÚè8èÐ`/!Bð²BûkãhZÇ)$ù›r§ÛYFfŒ vpM+=€¡:@žðŸ8 /^ŽÓ ú&ä°-„À‰ƒúÍáŒÆ?øEƒ GG†¥-˜™ »e ½ U¨Ñ'¤øÆ|€.×òk Â`ÇÄc'a£:’Ã…ð{ímMufVD†ûH!Ã(œüNÔC) š”ŸÄƒúeŠê¹CiAk&¸…ØújÏCdé\Ã@f!íÀG£ÒÞHŠÇøÁ®!) Ã>¨V¯#C"Æè²ýc{Â?®•êy½›üèùþú~¨z!Ô+L7tÈÐ8öÉ  ðiâô?ô +Ç¥íµ+¸Lác¡î #D ˆ ¹Æ0ïhû_ð2E3JÓ2reñMþ_vévùÀ'RÍD¿ ‚‰u5Þ°alÿž :Ý8”Xü–D{FÏãô[˜.ŒÄ °r^s6òj±þ‘âÌ*"n¡IT7Š'ÃvEºPß÷æ‡Ë;axHÒ_å÷äSâXKŒeý¾/&|Û!$XØ÷;Py^CÒ#B€õrгX¨-©$¤ø+ ÌäfÎp³ð¤À«í’š ÜlÄdÖÈäšnõ,Q 5 á«¿#?Ñn†B%ÎÌc ¦êM±—_òé)òjt}žë˦…ój`SLÁw¢0æÞžß¸Ã­<”îH2 :¤Ò!.p¾-,ä¿äuê$lF<  Î-I#ôZPÐJ#¹×*Ménf•)Æ-È_Z"]`òHÉt23_šF`(}¼)?_Pâ8»¥:aaÜÝ87%áˆÇÍb"‘¨7||s=Q®¿P®Ô»†´µ¥òâ,¶|D%Óy¯Û€üÑm• ®SAb<ò¹•£,AI‡âëiܸçÃÄ7mÇÍ­m·šíê¤ß®@ý¯_KÏs½œxéLn±4GôØ6ˆÉ|;¼¾¶‡‰?/ p©*‚&™¥í3†“Á7²î°YH:¦™ÂBZòÅù©SÇ^ívƒ¾Á¡|.—) &“ )øWžŸŸ9túáôã ¨òq€oЀ²Â¶~Ÿ @ ãQš‰&‚öR´¹‘M¦†1ó© ’?t$kxõÉë«­¨ÛâmE,cZ¢ÓjS‘Š,¡%r¡G^9tþÔ>Ÿ¤óý«SÙìüôéfé„;°-ò‰ÌàØÚ­Ùl¶¼T‚°,ãüÙñt&mÙ®Òn«ÞjÖ»íÆôÔéêÒl»¾¨+']x“„Ë4¬xÝᎊ ù²€bëI+ ê>à¯d8EnçWn3œ|:›ãöP£å·ÊãKç^´Rc­0ËôkDdø¨šÌ ]ºùÚD2Õé¶œDZöV»Þ?ÀÉ`1}âð3ºBRü–a§›µE¤å±Äͼ°²·¿ÿ‹û÷<Óht©p m3pigVÚN®^«5+³µJ‰K#”ÑÍW½µ0¿ïs¥é ÓÍøÝºa9×¢Ëæ‹Íf3“+6êµ¹Éqà±d®¯0°p»0; Yµn+£Q.ßﵪ^|F !X²êtWx:?Ô¨•üNcÇ[nºõÉ3GÀ7]/€ºÂëtj•¹°3§_´QýÆ„ßýÀ÷ ‘?¶ïÔÄ®›mT¦ΟDœÿm (¬¶ñµNRÅ˯½å†·íøÆ—ï´ª‚³Lß0£Ñ´]Û´à ÒüBi~üÑm•·P%2…Bq寭×ÔÊ‹{~óÄàðªJy©\šÕHˆ™,Ù‰Œe;¤ætÁn*·óÆ]ŽAg¦N:xÀ÷  ÂöÖÝP?0j¸ Ûªõï Ê•r»¾x-4ð±úMU>føJEܸQÇþò¡G¦çë¶NMœ9øòK§Ž¾в“9iA}´ª(¶.•mËnåœïûXâé­×ï:}àÉv»éûPþJh`‘á!?¦ÌBTYšI¦Á­¾âŠZm RaqhÕ™ãZrà*l‚TPá‚.ÒJéüâqñ¸x\<.‹ÇÅãâqñ¸xü9þ÷<îŸ@0Ž/$nv~†(1[š2ö=B@C@DçëE<S”¼H‚‚ ‚ «ªª?»ƒ=THHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB  2 /È   " * (1[> 2š =B@C@DES8 ¼ì ‚º ‚ ® ‚ «ªª?»ƒ=ø HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB xœí˜ûoWÇï{æÞÙõîúíøAÓÄnÒ8M“@‘(4 B¨E*¨" <¤ETŠ¢T©!^ªúRhmAUá‡BJ*5m¨hZšÆŽMœxµ×ÝÝ™{9wœò ? ùz<»ÞÙµ?çœï¹÷Œ Œ".Òu⢧0c˜Šõƒp—0A™Ë¸ƒ ÇÔ!‚Sæî0—à̹`ŒÆ‡ÃAÂA®‹¤D®@¿>BPš"„ÛLí RØ…F¿zž üÏå.„@ž9˜;”‹äÁ¡ q‘ Ä„…—.rRyä)ôÜ'Óå§Î€‰V! U ƒ¢Á‡!ɘ¹xž%äL0. ÖTä©ÛEmP˜q ØvÊ‘#’(\$\‹Ë£bõÑS÷¥ËÏG¾fšSÆÿ;“&¿õÀrÀƒC(`KU`’Xÿˆ¨r‘É5²Ï¯çà… Ap Ï%RÉ<êÊ¡R t££céò³â¸uCë6X ±‚@†ïû‘eæ9úAþ×ÝbšeæHÑ3Æ’´ÿ×6ëž e“óP¡€úŠh´.¥ìÊ &8Ò-èÌßøEê³ ‡ OíÁ¡ 6ÿÚ¿V/·ž»‚­§=ñ ð;pVHxH)”wb'jß=¡sþÉRåç\AƱ¦#‡ucÚ4®aðý¶§tå wûIêöà`©>û²gjW‚g [>¡z‡ù†çIæ%À+ì(“÷Pc¾êOU~iË¥?,üüèpªü¹‰caå¼}qÏ7qisIÓ\¯þLn;.ö‡ ç£ò9ÔYíÝÿ]ݸYŸ:Ó¿çË…»¶‚a,yÒ°,9C X|Þzé¯+3ó|ã¡ ‰ò©‘Tùó;Ø™:mš»íÝpSI™jÏ_h¿ÿK9~DmýJëÚ‹ÁÔ¯ˆJ÷Å‘µ+/«þ»7æI^¹zqhÇ.·   µo½y©oÓx¾›žýÁs”Òmöî{tç·v÷¦Ê¯†FÕˈp åãã8„…¨yíw­éßðþvïÿþÚ¥gÀóÄtÜîÍ>éÏ\pò=c–9~óµW £Û»üúk—~ñr×ÀæZeª6?#T_¾ËÝqpÏ ÇH•ßU}:¬#"dÿ^±û{zùZšl]?̾Ðûà³µw«ý®Y>ôt°pÅÉ{CþxϦ3ç^i-Mï;q’ó¸6_¹ðÓç¹P-¿<Ö©5Þ<}jpëÞÂèdmáß‹W/bséßÚôuÔir×™¿t:U~Û'öZ©‚ nw1{`l°¶ªaÓ*'5‚&é…ù'îP‰ÜÐæ;ÿì Â`:ò⸃Md4†YP–F;Í·1aþܹÿ ¿R¹z£O4F„!3îbxбéÅv8ð\÷ú6׫óÉÇx?Œ¡±­$ƒPqòk`glVÞH•ŸÃœy‡ß«×k0K×ýûP …f˜—Їa„íöL“aÕ¶ 1ûáPáȰÚ ” Jh°ôVªü0îØ…)½zÃG6ÿ`¼î"ƒ4¡Ú2Ù ;ØŽ©81ùúÈ ná6x#`¡®1Ä:ÍØoøŽÃ°ö~Úü–Õæ?_óW-¿-€¥LžC2 Ü¡À{ ³q£d!BIË'eb6ݦTikÛƒ†Eëió£u~™ók6s6É&1J.[L,~¤“Ðîø'¹q›q¨ˆÈ 訇ìàPŒÀG†ÃöJêþAI£)¯Ë÷W’Þ]oàÄì ®½sÄ8Š ·qr¦Ñn@ŽcbÜKJ.=6`Á$DchÙÛiV\U„–i,¼ž*¿€ûAb‡çœ’~} àa¥Ir w¾Åàèì.(÷†ºJÃÌí: ­•r…#nßšmú•¸½¤Ûboy|6ŽÆ!Æ`­ÖÓõOßФ* m®Mu謑œÓþÑIX6» …0l`ªQx=}cJ Š[õZ…ËK• ðçgßéÐ51£Z9m¿¶ ¾aðƒIªej­¼›*ÿ–]Ÿ+/,iC=§í–¶h±Ì ÝÝK•ÛÚ²p•T9X!æ¦ó¥~3”+»ŠÅ›³ïµ¿¶4¯u î‹U¾Ø]*¶êåV;€Þð—ËÆ„ÜÛЪ¾*ÿƒŸ}ffújP[¬U猆 4€n`ÂýôãO,Vƒêí[7g¯»^Zry± SÑ­‘ ÎùRyjmµfÿ!„+=Ø8£÷îš~ïòrµ¢;‹Fw¸êªWSåÏ”)S¦L™2eÊ”)S¦L™2eÊ”)S¦L™2eÊ”)S¦Lÿú»Vè j/JRZb(1[v2Ò=B@C@Dk E•Sp¼$‚ò‚ æ‚ «ªª?»ƒ=0Æ HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB  /¤îöþ(1[2v=B@C@DES¼È‚–‚ Š‚ «ªª?»ƒ=ÔHHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB xœíÕ»kAÀñyϾ³÷LâarÔ„óHQ£¢Xˆh§©µ°±°°±ˆâß¡…M "ˆ1 "DOñ¢æ.$ñ&¹Û»ÛÝq/Ýþá÷ašašïÌÀ &†yÙ;E„E¥Åu—kÓl®ÛB·5]è1,ä¸(A/´Pg{œ=M&‰ìáÒ‰úö¥•Õܼf`Í@¦…,eóh¨ˆîØ^ýLëU§gýgÄÐuaH=ÅH›QÏÚQ4LdØÝx;‹ò©`OÝ*ò¤“c4·¤ôI-GÕvžUõY{ׄúû©ïÐ9ÓAfŸF© ªÌ¼=xtèÁ©|ÒÉ1zïæº>þ5þ4ËO¬ÒÍ÷S¹ñ›a³6rñ¶Wû0xd´>ÿ1h´æ§§Ÿ?ùôΉ¤“c¤0‰–ÑößŘ­ÏÝ·†¯´*Ï;}Ò- _¸V{73vyòÛ‹—•7¯ú‡KË Õ_¯%#˜¤\ ‰=AͪQ8Ö^žef/×3î`I˜æÆòRsmµÓÜ0sƒV£þåYÒÉ1‚ .õV«©¢ f˜`F¹˜ðèFˆt_1a(DU´†‘·:—tr §BHÝó¢~…1E1.üŽ0ÙSÉ„© Ãh‹ag½œtr £Bvû[çߟô}_)L¹¥ºû³ãaÐÆT#„7Vf“NŽq3E¥˜×¢¯Örû)e„É\¡Ä¤³¹¾±V¯®üþÌPÝ÷[)„5om>éä˜ÝãWWk?•ˆ‘±ã?¿— 7êËU7•œ..|EÊ·ËÐÈÒb9 Ûí¿ I'ÿ½ˆ®Â 0"/Æ""" "("(1[<"2˜"=B@C@DGE~S6"¼ê#‚¸"‚ ¬"‚ «ªª?»ƒ=ö"þ*HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB Ô&/j'´&¼&Ä&Ì&(1[à&2<'=B@C@DESÚ&¼Ž(‚\'‚ P'‚ «ªª?»ƒ=š'HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB xœíÎ=JÃPÀñ¼——æKMMIƒ Ú N.‚“£àâ*®Î^Âݸ{ /à".Š"”"­éGÌó „‡ðÿàg»k²wêäÇAœI§«í®Üê[×'Òúœ¨/Ûûþöyuân”íäë›V¦FWGÓµFüd×ß»¬>î”þÜ8<Ëùäõi6Þß\˜®5âµÂé åI]¹+… ’iYÚnøõvkºÖˆ× æÕB[*Uk[¨eå.i­fãGÓµFÒâ`¾¨ÓÞ ª?LÞ_”—£éäÙt Àûé7h,/þ,H,P,X,`,(1[t,2Ð,=B@C@D *EñSn,¼".‚ð,‚ ä,‚ «ªª?»ƒ=.-´4HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB  1/¢1ì0ô0ü01(1[12t1=B@C@DES1¼Æ2‚”1‚ ˆ1‚ «ªª?»ƒ=Ò1HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB xœíÎÁ ‚PÐ äC( Ý<Ý[¢‘ Z¤%º¶„Š¢:©ðÞ/^Véæ”åE¹ —c˜ŒÍlµ¢i¶=¼ÛÇýzî»ó·d¾éâó_Ϧ«o}w¨;}6/´6þ5666(1[*62†6=B@C@DE4EoS$6¼Ø7‚¦6‚ š6‚ «ªª?»ƒ=ä6.>HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB Â:/X;¢:ª:²:º:(1[Î:2*;=B@C@DESÈ:¼|<‚J;‚ >;‚ «ªª?»ƒ=ˆ;HHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB xœíÁ1 0~`øØÏHv1Œ5<¶åXÕóžÀ¯'?˜?/.@x?€?ˆ??(1[¤?2@=B@C@Dû=E2Sž?¼RA‚ @‚ @‚ «ªª?»ƒ=^@¢GHHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB  xœíÁÁ@°Ãã|âË'Œ0Òè±-~N×[.Y I/¢IìHôHüHI(1[I2tI=B@C@DuGE-SI¼ÆJ‚”I‚ ˆI‚ «ªª?»ƒ=ÒIHHOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tif2013:10:14 12:33:04black,blackPlain TextureSHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FBAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifAZOpenImageIO 1.2.0 : oiiotool tahoe-small.jpg --colorconvert sRGB linear -o tahoe-small.tifx.SHA-1=C55C77A9E547836E2423DD3F1431FBB2C996A9FB openimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/ref/out.txt0000644000175000017500000000524012271062644024440 0ustar mfvmfvComparison: of flip.tif and flop.tif mean = 0.00687588584816 rms = 0.0511750114577 PSNR = 25.8188410286 max = 0.450980424881 max @ (214, 88, 0, 0) warns 2034 fails 2034 isConstantColor on pink image is (1.0, 0.501960813999176, 0.501960813999176) isConstantColor on checker is None Is cmul1.exr monochrome? True Is cmul2.exr monochrome? False Nonzero region is: 100 180 100 180 0 1 0 3 SHA-1 of bsplinekernel.exr is: D5826B66A5313F9A32D42C5CF49C90EC4E7F84BF Done. Comparing "black.tif" and "ref/black.tif" PASS Comparing "filled.tif" and "../oiiotool/ref/filled.tif" PASS Comparing "checker.tif" and "ref/checker.tif" PASS Comparing "chanshuffle.tif" and "../oiiotool/ref/chanshuffle.tif" PASS Comparing "ch-rgba.exr" and "../oiiotool/ref/ch-rgba.exr" PASS Comparing "ch-z.exr" and "../oiiotool/ref/ch-z.exr" PASS Comparing "chappend-rgbaz.exr" and "../oiiotool/ref/chappend-rgbaz.exr" PASS Comparing "flat.exr" and "../oiiotool/ref/flat.exr" PASS Comparing "crop.tif" and "ref/crop.tif" PASS Comparing "pasted.tif" and "../oiiotool/ref/pasted.tif" PASS Comparing "flip.tif" and "../oiiotool/ref/flip.tif" PASS Comparing "flop.tif" and "../oiiotool/ref/flop.tif" PASS Comparing "flipflop.tif" and "../oiiotool/ref/flipflop.tif" PASS Comparing "transpose.tif" and "../oiiotool/ref/transpose.tif" PASS Comparing "cshift.tif" and "../oiiotool/ref/cshift.tif" PASS Comparing "cadd1.exr" and "../oiiotool/ref/cadd1.exr" PASS Comparing "cadd2.exr" and "../oiiotool/ref/cadd2.exr" PASS Comparing "add.exr" and "../oiiotool/ref/add.exr" PASS Comparing "sub.exr" and "../oiiotool/ref/sub.exr" PASS Comparing "cmul1.exr" and "../oiiotool/ref/cmul1.exr" PASS Comparing "cmul2.exr" and "../oiiotool/ref/cmul2.exr" PASS Comparing "chsum.tif" and "../oiiotool/ref/chsum.tif" PASS Comparing "grid-clamped.tif" and "../oiiotool/ref/grid-clamped.tif" PASS Comparing "rangecompress.tif" and "../oiiotool/ref/rangecompress.tif" PASS Comparing "rangeexpand.tif" and "../oiiotool/ref/rangeexpand.tif" PASS Comparing "resize.tif" and "../oiiotool/ref/resize.tif" PASS Comparing "resample.tif" and "../oiiotool/ref/resample.tif" PASS Comparing "bsplinekernel.exr" and "../oiiotool/ref/bsplinekernel.exr" PASS Comparing "bspline-blur.tif" and "../oiiotool/ref/bspline-blur.tif" PASS Comparing "unsharp.tif" and "../oiiotool/ref/unsharp.tif" PASS Comparing "fft.exr" and "../oiiotool/ref/fft.exr" PASS Comparing "ifft.exr" and "../oiiotool/ref/ifft.exr" PASS Comparing "tahoe-filled.tif" and "../oiiotool/ref/tahoe-filled.tif" PASS Comparing "box3.exr" and "../oiiotool-fixnan/ref/box3.exr" PASS Comparing "a_over_b.exr" and "../oiiotool-composite/ref/a_over_b.exr" PASS Comparing "tahoe-small.tx" and "ref/tahoe-small.tx" PASS openimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/ref/checker.tif0000644000175000017500000001354712271062644025211 0ustar mfvmfvII*¦ê ðÚâ26=S0¼J2013:09:27 22:51:20 €?Ð „Ba(ü*ˆDbQ8¤V-ŒFc@ú7HdR9$~%”JeR¹d*;-˜LfQˆG'™ÎgS¹T¾y? Pb³ŠEŸQéT¸tÖID¦TjRZMN­WŒÔ+ºä>«]°K)Óxm†Í`¯ÙíU*Õ®ÝJ´ÛîQ[ŠÛs¼Nî7›äÆï}ÀJïxê$Áá1Rþ/ÄãòT;.Nù†›H²9lä;ÐBszI\Ìb#Ú}d/+­Øhö-6Î¥©‘ì¶Ø½®ïºß`w¼6ã5«âh8|›ï™xåóçœi;¥oèõíýnÕ«³Ý˜õ$χ¿å°ù=Ï?®Sâú½Õoίòû[5ÿ™ßà ä?‹›ë©Ä£Àp:2ÿ#P4¡A0z…BIü# ¢pb3 C Ô/§Pä@™Cñ #L–ıZ[EÉT[€B/F‰,gªx¦Gqtl‹GûýÈÊ<‹$£r W!¢²\˜¬Éšƒ)JÈ´J¤±,¢’ÜÁ(ÇÓy1Dê'/ÌÈ„Ñ6¢dà…MðÄÔ‰NSš:ÏHDó> ³ä%;¢3ýAPäËD¥”DBN4]J´šSCO´tH+Ô•-R´ûUQE• N!ÔÄõMOUTçV@5B]OT’=jÁV•¼›SP“E\×R¥‚”UÓ…`þWÓõaËUå™"Yvz'c¿6JbͶ¤ÍlLÖÓçk ÖäÇoLÁr=h€ è „Ba'ô *ˆDbQ8¤V-ŒFc@ þ7HdR9$~%”JeR¹d*;-˜LfQˆG'™ÎgS¹T¾y? Pb³ŠEŸQéT¸tÖID¦TjRZMN­WŒÔ+ºä>«]°K)Óxm†Í`¯ÙíU*Õ®ÝJ´ÛîQ[ŠÛs¼Nî7›äÆï}ÀJïxíÖCÂbdX«]°K)Óxm†Í`¯ÙíU*Õ®ÝJ´ÛîQ[ŠÛs¼Nî7›äÆï}ÀJïxìm"Áá1Rþ/ÄãòT;.Nù†’drÙ¸v79Ÿ„æ´ ö޹˜‘è´Ù½.¯9ª×dµ»–£Úlv{œvÃy„ÝïèÛiû…}àñï¼nUã“Ížq$Î…¿ŸÕ·õ;®¿ncÒö»ÖïŽÃâóW<¾™Oƒ!¸ö`}¿£éSùýä>è×Ûô¦?/ú–ÿ@J<£â3A ¨0d ŸÁðš%#”,B°Ús CÉ”;¡0Â/D‰lG¥‘DX•Eq|L‹EÑzQÆÊ£á¿ ¬xý ;‹Çð}"Àr$‘Hò\ ³2TI²œ#)JФ«,ÂòƒS,Kä·0ÃóÉLs«]°K)Óxm†Í`¯ÙíU*Õ®ÝJ´ÛîQ[ŠÛs¼Nî7›äÆï}ÀJïxíÖCÂbdX«]°K)Óxm†Í`¯ÙíU*Õ®ÝJ´ÛîQ[ŠÛs¼Nî7›äÆï}ÀJïxê$Áá1Rþ/ÄãòT;.Nù†›H²9lä;ÐBszI\Ìb#Ú}d/+­Øhö-6Î¥©‘ì¶Ø½®ïºß`w¼6ã5«âh8|›ï™xåóçœi;¥oèõíýnÕ«³Ý˜õ$χ¿å°ù=Ï?®Sâú½Õoίòû[5ÿ™ßà ä?‹›ë©Ä£Àp:2ÿ#P4¡A0z…BIü# ¢pb3 C Ô/§Pä@™Cñ #L–ıZ[EÉT[€B/F‰,gªx¦Gqtl‹GûýÈÊ<‹$£r W!¢²\˜¬Éšƒ)JÈ´J¤±,¢’ÜÁ(ÇÓy1Dê'/ÌÈ„Ñ6¢dà…MðÄÔ‰NSš:ÏHDó> ³ä%;¢3ýAPäËD¥”DBN4]J´šSCO´tH+Ô•-R´ûUQE• N!ÔÄõMOUTçV@5B]OT’=jÁV•¼›SP“E\×R¥‚”UÓ…`þWÓõaËUå™"Yvz'c¿6JbͶ¤ÍlLÖÓçk ÖäÇoLÁr=h€ è „Ba'ô *ˆDbQ8¤V-ŒFc@ þ7HdR9$~%”JeR¹d*;-˜LfQˆG'™ÎgS¹T¾y? Pb³ŠEŸQéT¸tÖID¦TjRZMN­WŒÔ+ºä>«]°K)Óxm†Í`¯ÙíU*Õ®ÝJ´ÛîQ[ŠÛs¼Nî7›äÆï}ÀJïxíÖCÂbdX«]°K)Óxm†Í`¯ÙíU*Õ®ÝJ´ÛîQ[ŠÛs¼Nî7›äÆï}ÀJïxìm"Áá1Rþ/ÄãòT;.Nù†’drÙ¸v79Ÿ„æ´ ö޹˜‘è´Ù½.¯9ª×dµ»–£Úlv{œvÃy„ÝïèÛiû…}àñï¼nUã“Ížq$Î…¿ŸÕ·õ;®¿ncÒö»ÖïŽÃâóW<¾™Oƒ!¸ö`}¿£éSùýä>è×Ûô¦?/ú–ÿ@J<£â3A ¨0d ŸÁðš%#”,B°Ús CÉ”;¡0Â/D‰lG¥‘DX•Eq|L‹EÑzQÆÊ£á¿ ¬xý ;‹Çð}"Àr$‘Hò\ ³2TI²œ#)JФ«,ÂòƒS,Kä·0ÃóÉLs«]°K)Óxm†Í`¯ÙíU*Õ®ÝJ´ÛîQ[ŠÛs¼Nî7›äÆï}ÀJïxíÖCÂbdX openimageio-1.3.12~dfsg0.orig/testsuite/python-imagebufalgo/run.py0000755000175000017500000000265312271062644023502 0ustar mfvmfv#!/usr/bin/env python import os.path imagedir = parent + "oiio-images" refdir2 = "../oiiotool/ref/" refdir3 = "../oiiotool-composite/ref/" refdir4 = "../oiiotool-fixnan/ref/" def checkref (name) : if os.path.isfile(refdir2+name) : return diff_command (name, refdir2+name) elif os.path.isfile(refdir3+name) : return diff_command (name, refdir3+name) elif os.path.isfile(refdir4+name) : return diff_command (name, refdir4+name) else : return diff_command (name, refdir+name) # Run the script command += "python test_imagebufalgo.py > out.txt ;" # Checkout outputs -- some of the refs are in the oiiotool test dir for f in [ "black.tif", "filled.tif", "checker.tif", "chanshuffle.tif", "ch-rgba.exr", "ch-z.exr", "chappend-rgbaz.exr", "flat.exr", "crop.tif", "pasted.tif", "flip.tif", "flop.tif", "flipflop.tif", "transpose.tif", "cshift.tif", "cadd1.exr", "cadd2.exr", "add.exr", "sub.exr", "cmul1.exr", "cmul2.exr", "chsum.tif", "grid-clamped.tif", "rangecompress.tif", "rangeexpand.tif", "resize.tif", "resample.tif", "bsplinekernel.exr", "bspline-blur.tif", "unsharp.tif", "fft.exr", "ifft.exr", "tahoe-filled.tif", "box3.exr", "a_over_b.exr", "tahoe-small.tx" ] : command += checkref (f) # compare the outputs outputs = [ "out.txt" ] openimageio-1.3.12~dfsg0.orig/testsuite/gpsread/0000755000175000017500000000000012271062644017777 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/gpsread/ref/0000755000175000017500000000000012271062644020553 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/gpsread/ref/out.txt0000644000175000017500000000162212271062644022124 0ustar mfvmfvReading ../../../../../oiio-images/tahoe-gps.jpg ../../../../../oiio-images/tahoe-gps.jpg : 2048 x 1536, 3 channel, uint8 jpeg SHA-1: C3B420EF8C20C4771F6F7BF89EA9D9D4002BA016 channel list: R, G, B oiio:ColorSpace: "sRGB" Make: "HTC" Model: "T-Mobile G1" Orientation: 1 (normal) XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) Software: "title;va" Exif:YCbCrPositioning: 1 Exif:DateTimeOriginal: "2009:02:21 08:32:04" Exif:DateTimeDigitized: "2009:02:21 08:32:04" Exif:ColorSpace: 1 Exif:PixelXDimension: 2048 Exif:PixelYDimension: 1536 Exif:WhiteBalance: 0 (auto) GPS:LatitudeRef: "N" GPS:Latitude: 39, 18, 24.4 GPS:LongitudeRef: "W" GPS:Longitude: 120, 20, 6.25 GPS:AltitudeRef: 0 (above sea level) GPS:Altitude: 0 (0 m) GPS:TimeStamp: 17, 56, 33 GPS:MapDatum: "WGS-84" GPS:DateStamp: "1915:08:08" openimageio-1.3.12~dfsg0.orig/testsuite/gpsread/ref/out-alt.txt0000644000175000017500000000162212271062644022702 0ustar mfvmfvReading ../../../../../oiio-images/tahoe-gps.jpg ../../../../../oiio-images/tahoe-gps.jpg : 2048 x 1536, 3 channel, uint8 jpeg SHA-1: 71EBEC73B8E8B3533780B15147E61D895C80E8B1 channel list: R, G, B oiio:ColorSpace: "sRGB" Make: "HTC" Model: "T-Mobile G1" Orientation: 1 (normal) XResolution: 72 YResolution: 72 ResolutionUnit: 2 (inches) Software: "title;va" Exif:YCbCrPositioning: 1 Exif:DateTimeOriginal: "2009:02:21 08:32:04" Exif:DateTimeDigitized: "2009:02:21 08:32:04" Exif:ColorSpace: 1 Exif:PixelXDimension: 2048 Exif:PixelYDimension: 1536 Exif:WhiteBalance: 0 (auto) GPS:LatitudeRef: "N" GPS:Latitude: 39, 18, 24.4 GPS:LongitudeRef: "W" GPS:Longitude: 120, 20, 6.25 GPS:AltitudeRef: 0 (above sea level) GPS:Altitude: 0 (0 m) GPS:TimeStamp: 17, 56, 33 GPS:MapDatum: "WGS-84" GPS:DateStamp: "1915:08:08" openimageio-1.3.12~dfsg0.orig/testsuite/gpsread/run.py0000755000175000017500000000012312271062644021154 0ustar mfvmfv#!/usr/bin/python command = info_command (parent + "/oiio-images/tahoe-gps.jpg") openimageio-1.3.12~dfsg0.orig/testsuite/texture-grid/0000755000175000017500000000000012271062644020775 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-grid/ref/0000755000175000017500000000000012271062644021551 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-grid/ref/out.exr0000644000175000017500000242020412271062644023104 0ustar mfvmfvv/1capDatestring2012:08:17 11:27:01channelschlistIABGRcompressioncompressiondataWindowbox2iÿÿdisplayWindowbox2iÿÿlineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?q3kj×§ÇìÚ9E‹Nß`4ˆÝÚT-À‰Óz(X~‹Õ-˜…Lâ´@UœÂõ“M£¢ÀóCÁ‘Qá“0 € ŽÏ  0xœí] TmÛN*•-B!%D )e§ˆH!ÊÙ³VÖ™9ËŒ,ÙJ(K–H%DR¤H¶ÒB–,‘Š”HËoö¡þï‹Þï©ç}›sÆÙžs®¹ïûº—ç9³ I4¤'äë OæˆßÜÀûgw¡ÿtcàØÿ €üÿNM«¦ØÎ{bˇë×Íåלn/õ[l ×™»ÿRýÉ=+¿tb]ú½Kô͹vJj–ç¤õÕÜ `.ºwæˆ\ÄcŸ=\vM=g¤ß—]ôT”œõøŸpÞ—4±ùóBÍ7–S}üÒ‚n`›Ô¼C«J«`6¹ªŒÊ…v²IÛÑšW™Bn¯ écݴγ³ºNÞ VV–êuߘ+ðpc¤ÿ£SÜ©«†K$t‹&ßåÔì‰XTÒÀh7{;r‡5÷ýœß7HZ7>ÚöÁî}K¦àùÇKŠ:9Í ÷JŠRܱ|„w'-­‰Š›Á°dc`S¶–µÌ¹:GÛbÚKBxËS [>ŸëÓ=·Å®]kIÉ ±yÙÃêY{îÅ)ky.¾Ü½åe\…dÆŠK‚×ò¢ng>'ƒôŸ'ÿ9@Eøéˆˆ13@eøO¶^Ho_ôïîÅO¶I¸ÿÿ-@`¢.`-’óÎÎeë°ýÀõcʯrÍ8Î×;J&6 ¥.’öj``¹¿1¤Ýn'â±z¯‚Ö+÷VR­#ǵyõ¯tœÛNŸ\ã+ðÜMj™÷ò\“n‡–"hU@ jŸ˜ C´:§ßà•¡vÛÔ„žêÜŒÎz±ªýÝÚîŠkŸo+Š/ˆÝ¾«–ïUånKýoÛhïxtìÿÀå|»v>à Åù[Mlm9¯ ç:4+Œ4]¨Ð L ç[òÒtÑF[r¯Yh>:‰®ºÈŠ©á_™°s°Or F÷äûÁÈ‘êgÂùÊÍâ]eJLU¼ýw¥?ÀÄ­ÍÓÿflç”ól mACä㇕ùW;Ý÷z¶AôvC¼p¬Ì7UUûì/[ê~=È!ã³ïÝ1æ3»TŒ!5¯¢p±U»òT‚®A^TƦ€‡ÏœZµÔu7uˆÞåÈ(yŸþ+îôíà35g“嘞e‡>Z9¤ð—«?ó’ûâ¸bJ’”è¿‹?ÍõJ6ŸKO^³¶Èí7ká¢)n]š|yIÒì†þ¹œ…~ øG·ø®Ök~cÉÅp—-BfÈ‹áL’§ÐÕólô4y‘žZ{vé¸Z†í êÂ_F;ÍßÁÄ–)nŸJoô’rí;n?½?/ÚêËuiÅÐÛÒ†þµ­µ¢jV6>œ †¶Ñ€Ø šÚ(ÿêZÁ烎GyPþ“o(OÀ×gF$@䤒?E@EU@Ù“Ùî÷žT­Ž´J-þÀµþìoÕJí‹ê%"=µ¯î2[÷áì§ ƺ3 ÖxÞÞBçª'kØså˜ÌKªÏèH–vÜ%V:Ïf%c1k¦Õ½SåÁV«ÚØ)qŸ›‹/=~-I«Fòhbmüýó·o¼0ŠäŽÏÓ«žÐìòZYqMÊ€i®Ò[;»ß "%Þê¡Z_9®_èQã\¤Ü%(°Ë±Ò„/x=M[ü-nô+“ï6ºhÞ xqÞÔZ!‡Áq£8gÐ…fD§ö`4bg·öë´ô1¶£66ŠéB+%ÔÊ3ý|ÊC>çYè¸2´n•æSöœgì°JR‰šÛòeZ/NÙKÂ6ó_Ön²‘oRUE•ÄÀ#,­}ng%ÂÎ+8ˆÔiÚô¹ÂPsÇíV÷¼*1q~^T¥¦‚‡Ëâùz÷À6¦œ]ô…k‡?åïz×oµ¯«ðõÑ:£ÝÙ#õŸ -ØÇöø–ü®º€£JõÕ¦\³Ûÿ>þ+´w½øZìn£FÛîMÛ^ÏëXÍgŸ_ÊÀ¬TÏf¦Ä+-;ÇÇb»V‡1ü„JùÊŠ‹Bt.XÀ݃”×6Øgoçp¦*ü?&ôëï¯a,µ+¡·i _ñ°!µÛÌãºÀ(zëG£ej¢®ëUÚäΣUÿ\z4˜ÛvwèÏ“³NÅDzâŽyRþSh Ò òÃÌ€„'—ªøÏˆ*“v&suÏù´¦¦â¸ºtÛkŒ½w¿TÏyº¯ÌêùÒÍ¥‰‡×ª¢91kèvFIeá¨ÓG¦K×}öÀPjƒDý¬›fó$Ç{ì„zCõ…U:fÃÃ+k+bXo_´WÔšSd¸T(“à S>–ªZfÖmeRoYŒ/*ÈèŸ{J/¾·^έkÓì¡emZl‚ëÊo+û\|àéôðíª »2„«ÙŠÅUBóZo Ž…òäq>W§[£´ðx¼Ð›ú¨'ºü‹1åÝü¨ÕA;_~¼ ‰âxÿœ®¼ì›‹¥d-‹–ãÝd–›²' fÛÊ{ÞdëGˆ`žÅ*né+2[WÆ,é³íl¸®÷š¢zöºð-'Y t9k:}øÚ+fˆŒ:„wŠ cE³ j¢\iç)awÓ-æu_¶¯½£i”T¤¦†ÿ,»Hä»ÞC;.ÚݼìÂï&'ý†w¥:¡{î·‹ÛK‡k—¬±ê’»ó±!ѹJÐgÎoÁßDî›É>S×!¹…züÖf*ìœ7òrçàãÝráG²Žø †Al”ø³‹ab¸BºaÕþ2¼ö¹yö>ÝRé)6'>sÛn&³ÇÁÉåBM þ@g{t?ÍpòJ:þ’GW2r·÷‰Î ©»=«'ßú°¦~zÖé‘j_v·½#ò>¤¢m¡y±žü‹k:?AQþSj  ã;íË@¤Ï$ø/< ®$À Û¼…ÕÈvŽ·% >,ßÌ#¥zµûœ8™Ãž¤Šfé—VïîÄÊÈÐù*½7_T‘²‚ãÞ‹µtã´/Þ/OqØ™æf,Ÿ,rlÛ ­×µÑóµzÃý¤Gýµ—íDÒ3óûàúæF&çõÁ/œŽÍÍpè|6»-Bžíf“†Ìá@)¡Ü{¦°2órˆÑªçÑ ƒ/+/Û¸¶Ruã" §Ä9¹§Ÿ¥ß¹ o6̬F]a\-$éX+#»<\ÃzáY² –Xè城H‹8¢©FLã”è×f#Ÿos%ßµ—eÍ‹âñ’aÊÈY»).”noðº6uÎÐZõ›û¿ ÿìE¡tïWð΃3…Ãfuµ²»Å½j›¼Yx%S–¤}jˆä¢ÄŸ¹1µæ0ÝÖª{'åÇðUö§=RÉjSò¼œ=^ *˜ì±Þëè ÛQO8Áò"gƒsÌëºJµLÐ×\©±‹"ƒWU”œá(‡Y;ø-Äh+Ìfe±b Ñt½þô®¬ÑÁ`°[ì'ÿ6²Ò"N‡G{ýñIÀ éã3͢Évð¿ªKx¤,Y_gv}õ~Kƒ®°ÁníG´–Û¼z”¨(q)ÁB~k:w‘Ý“ÐJg£5±|¹ê”ÚØHø¯´Khy6™ÖgÖÆAŽ6gèsn(™}ɤó&â:[ëbÁÄÅÐ÷¹ÀþÑHQ˜çÑ%’ëÒa¾°ð/ì}åÝ—äòš½ÇøÏ>D†õôKì>¼lwMÎ@žX=“çåý"é±kD«æØw+ ¤r1¾Öߣ𑖣âsÆÑB1ݪäB÷ lÏÃ.¸°òXCvÂÙ6í˜ÙQ·V¬zpÕ´‰Ÿ#™9Î/Ž[›¹Nº·ÅpÇås¦kÅšºÎ¥ÔæÆÁÂk+»ŒíÔc^Üy*^Xði ïáT¦‹sö}«?±q-êΜ˜¨áq#×bƒ¥iÀ°¨Çw¬ŠwÏÊ mºÁÆ’o5Øê õ ¼âcÂ\a*QSÇ?¬Ý⹪ÙñÔHU ¿°}(ív”î.|ÿ&­¹N£˜ksN{wÚàoÄßTÅõÉÍmÃ}Ü™’_Z.ÃχÅT yÓ…kR†Û>/ëjµ’¾×Ƥ^<÷BòÓK³†viÿyòÏZ¡w(-$64̃ZðŸjé^ &éþC?E €ZÆŽ0·±íJ¤I~k#Òr÷ê1ËUeœI²}Grb\öyÎy`ÀÈœZyòðŠÞN޹g˜ ¬™o]2غæŠàÓ["¬sAw]d7Ãõvôë+ÎÚžÎÁ¨¿åØÐÓ~„ãâÆ–eþw¥èuѧW©Ìòs7܇t«þ&wðÌ7Å}–½×ž®Uf“t8§¦\TðB&·ŽWYm7CÒÕ›6M…B[7*=½…¼q½V¥}K(¦ýûËgÝÚ°üU÷õF‘;ÇCßÈ\;”Ƹí­ûséF„ÉÞÛÌŠ¶Mí2-jü7ärZµTzØñjÜÒн}6–GhÈÕ;˜]¤‹4bvŽÑ)ͨ glbà|S*újí×­qbô/ôžÄªÈxW¨?Ó‹ÓÑÑ?nvt6;‡R›ˆ´r|TJ+þ¶>:¤’±@¿€¿¡Î@¡‘Ër-R•múð(w©Nrn=zÓm-v¸+ý÷â\Ø[®#@sX·áRN"ÿ¦¯7Ï/\­ÂÕ"¥YPêìùLé``¬˜/ÿ³ñøÇ·Èm å¼°œñÀÒÎ1ü›œ—8üõ(sÈ\˰·»²½Š…‘Ý!WWêÀn™ä'7µøooŒŸØ}j‹Ùóì\°(б%ÓJÒÑv‰\βÏY6O· ËU¿âõL§tè‘ÜÜÞ†“_ýf+Ë‚žüCûO†%‡ûPÝHÉ6éûNã2¯)°“Ÿ±ÿÔ5  L£JÓs@ð³ñí4_ß\ƒJêÄÁ³Î7 Ñýµ…‚×ø7Uê¸æº¥3-Ù~C')ëF*†ŸnKÃÅLz[x¯ål·x"‘äçigqM5ï„/ïšcèÓÝ;o$z§pñÉé)¬yuŠ/݈AZ/?þKZóÉø|~ö—.ëí1p[ò„¶…æZpžM·¯K_EÐïVY0‡þZ#úÝCÆ~Û®¥¯“¥÷gßòÜ™Ÿ<ÇþmsÒ~»[Cøü;òM †«êøÛ×f;éeD…¨b$À/áO3ŸáØóÁO"ÒyÜÌ9ζkè¨úIœ68똗Z$w¬â=ËÅ©ëv~tU_ä"ÑàÓ'^¯ód¸i{+{ùÈë8ÙåAÙ±ÚñÐb+‘ÅËyÊÂï¿[º—MWÈÌÆÁ”ëšEÏç…W $çÐ&Ï?)®Ï[î.ñòù¹ªÒˆ¡*z¹½3¥Ý¡ó,/~`l™ýñÆ Á’¨Ú³BOÌŸóYtDßòYwPLeZÆ+[—TéO^Zó2|èÖ%mô·›m"Î<—T#ÌÈÞ?T3ÅÝ¥ÀöjÅ2Áª)‘Üw÷Ø´9î<Ñ•¸Q剔/„éwú]y —F5¿/ “M,½Ì°æ펠ááõ­´=Ù7ue+ï;³}íÆVUd–½ïÛNic‰ú¶?·Á¢½¾÷\rƒ'=¨€ü"þˆâ[ Ç¥”.Ï­©+Ô=œ;—ÑèüG¿é€¿GêÅ»´¢ß^´ªÏy²´š†GìóûOHÏÑÝÞ®Í|AK €Þ›þçÆãÉeɰ̜ÝýóL›ÖpŒáÿòºt„~sÔÎCg=WÎPîò·QöR1Ô³³q…¨¡ `åIg·¯òmóŠäÖ›¾Ü“/púBŸB˜NFjwñ‡äØ{1n+R‚γìÒë(þ´v·_¡Cgf€ÞНårÀŸ'ÿaFEèÔа÷¿ež¨iZ"¦–œø9@=I€Ïþ4%L"™%WMÐï·T™ä䄸 \f‹—o=zåR¦©ÑÓœm\ñóïzv¥[YŠd $lªM©;É|úÕà¬dÉ®þ~ »>ݪ«ì+›½¶ÆqÁHə؛PEð«òëešºù‹ºS ̆]:òè…Øv¹ãEÛÇÑ7>_mîØï+æx¨»l ­¼ªMhXߪy×R«m9/ð„ú™ ; ¨3¥Õ,¿5ÐôNê¼È¢³ò¢Š¤ž^Ø6ßõ†â…ÅÏ:ý×·­6 xÞaX¶ñÓ—Ž:)Ž´ h+fÿ¶Ýæ«›}”GÎ í}šÊs˨(æˆHÚCs›=Ư ÊilrPÝò~@û-MïÕM<ïD¶¹Ôܵ1¼^!¾ëpë¹üioX߳׸`eÞØàøÈÂTv3ÃÕûôÈ`—ƒ‡ó="¨ øËø¯:ÓKò­ýL‰®kùñþBÓÿþÆ%³Ñë^|Ñ»ðæªzϾJ_ë—iöÏÓî_+¿¼‡cþ*º÷!ð¦×ðr€†ïgë›Scøwð½Ú€hp5IëÖ@Í7ß=\n¾Ù|½ÒíðŒÇÿ± ¯…r¾}a{užôë"!ᆆÍ÷| ™Ût>©Qjå|zï’ÅÈäÍ—{µßVÇШߠ+L»™·éÕhšÆî“„¿½@]c§Ð@”8-§F §6>á'í?q$j¦¾!O'~Bìº{k퀳 RÖÕ·½nGôÒJá°«fâ Ó3SazˆóFúó9¯ÓFóMXÛ.Ë­húvVgGÜ×; ¦‘‚Ýó‘n–A»@Ñõ¹=ײÓ8ìÞroMf{)Ÿ2ûõ¯#g«ê€Þ’+×Ê=o2¹šßûµ|ôÞ¼ó¨ [Êʆõ»V׿:»ˆ•WvÛÉz†¶U œ/nÛ”ÅÚgR9¨^Ô~Ès0w+§“ý²2¼§ä¬$dŒM4+4Eun¤7ß,h xâ‘ûò齚Ý`†·™õºÏ²¿®{0+Ôã>”é©_š™Á+|ÿ’ÙQã\ä{Æ.úИ¹ì‹7Ï: vJÊÊfrî:Y±eGT·ÚÐö“¯ò©´ŸS@uÅ-dêÚfÈa±¼&)i¯_’w©ðè?!دãof“Üö%vyG¤xë4¿ìˆ7S C©ã}õ=üqfÀ†{&ÂÙ-ƒ)Ùµs7¨—sh=Z‘xsþûR”ÎÐ%ÌáKZãαa ÿÕñÃ÷L$äãRžIÁu*«Ó5u<ôTÌôí§™n²zØò>K|½µzÅ‚Ê=›<ŽÙ<dà«®LžcÙÛ§ñ郗ç:¯ºü¦ÛÑéˆìÊ.ÑoW½½²Nqq;—Õn Ú<Õ?Nþ“ ‚NDDņFÔ4xJ Dz¢ýÐӀߩù“ÿNh¦—˜Xoo ey†ÑXfÄ׳àETŸêuaó ½Q‹núzîx×wœÿ P_¯dÕ¨òB—éuÛâ¦()“µEF‚]Õ,Ë«ïe}?´ÃUúƒêˆyZä„^mãùb¹AyB}g7[èë¾ræeîyfw‡¢•6Õû¾çã]qÈ7>qíú•k¢.[èûwä­êc7P‹]az–oËšefî6ŒŸ¯2ñȯãËÊ4ð-⯊9·Ã™.WìÉ­E¤y¸ÖT ^Ü©¤¥ñ"íIø h«ö{.å¡ǽ¶—ÛNIYøh§iå.¾—¾žKãz‚¢/¨Cˆ{V> ›¿.î®iÕrË)ôºBó‚w˜J†?©øÈûŒûºüxeoè3Ûõû“»·Ó Þ5ODÜzCNÁwŸÊÛtÌüzV¾¡¢:{7“ïˆ3~3|BÀ_ÇŸ'òh¼ßp—êôÂÿ ¯yªÄESÕÎÇþws6OyÝØÏàö΋†>ævÎ\tQ›KcÉVÛåð_æiòÁó,Ÿñ[¥ÊO§°øÃ\ÒñsâµÔ"n9”lÎwTáÝ|QÅ\Úä õ!gÈvf3À ú·¹"ÓJÖú >RŠ–åm‡„öh\–N)È>渕Oe[RÅòêÒrmñ^ïMn2ŷйO[Ó«\êR°y)°l— {ÐWÎ?Nþm;Iý›À–L»)½¼§Ü¡Ÿ&øv,à fæ`.GÚˆ”LÑy`XTñì“,_Èm—ʰój‡&m{½ûÊ»:k/äì•“ŒæºjÞ騿·Éq‘¿X_à’ÓOÒBó¸×Æo–ðŸ}öQÿ†š&ƒ¦ÿ̃KŽ{Òµ¾)¾k1ëRù€@7s—rëbÝÓƒHØW-×ÅN!,úF+©ŠCBv±óê…ú»x_ì™c1ût]™®Q>‡¹OŠ•–î¶”ÄÍzÙSü†4—?lscž£\õdG1³Ý-Á+™>=>g7ä›\9‹yÄÕÖß”aÆ¿¯•®cN ÷ŠÐ‘–§Û·>Ÿ5àçðæš‚ØÅ!$s‚Äã"ÃMµ•–Àîâv3½=Á%ô mbôó=Lô›obWÁ‚Çg‰¼Aÿ®§ öɪ—/~Î\Åí径“.w%¿ ¢²µ¼ŠÜ  €`Ï™Ì~ÿÓEC›ƒuBy¦þ™‡öŸäåŸk°©ŠùåáçJ¯õ=Üí½F‚†µSõËçYfp«ðõÍkŽå±OÄÉ? «O-ÛÛå˜Xqø›¨s4ôø¯ß–w·:ém^`ãPI¯¥³¡ÂCk[OÇ™lœ¾ìõn:›ýţຸ¾BwVÿ‚VYÈZF•ó.Xæ-üR¡os៙ ói2Žõìt0_JkâÔëþ´SÑðÖÕ#»¦þÿ{ù¿ è•í“è9“ñÿ'x¡¦×X@0ù±Äöój˜Ðp0ÅÚÜaÅV~åãø¡ÆW댪²n\|ÿ¤uÇú9±<͈¹ÎM”ætº­N+Oòžßܤ#I›Â(Æ¿%‰îA²†¯õ–ƒL"/ºÊ8ŸZÔ´¥ŸîÂÕÊêìÜÃ÷ò=ijd๪/ÞðBÔž»ä¸ÆÜ÷º¾÷ãò?ñ:ˆ!”º”ãê7¶KÊ{tû(²i¡ãj¶ù9,æ´¸o2×W·ÓV¾"ûæÉD¡yù{TÀÒº›¶ywڇ謺¼9•9wÙûç*¥'wÎá*cÊœZ!¥^Û¸\ùÊìA©×)Ä,ZºHËÅš^f^Y'ùÌàJð_ÀŸ{‰¬”áѬè͵ï- Ú¾L'üYÚå/píz¦¬=¨ã÷©²œnѺ— ܃wÞ¨6K‹û/¶£´~“øÎYÄÇ®q"þyîÁý{"F xº"4pøGÅ~]Gs7X™ h–ÙÕvšET³Ê㘥±¼‘¥Ž³¹â°ÛÌÅ?C£Î«œGXû¶|»foNøR9îd©âÚæœPVîU#çβ{æZ7™lã4´^ïô4âÆh±ïÒµ#Ù•Ç´‡­/ÍY˜8ñÿWä§»|:>øX8æïX@Ôôz3°§ï/ôeÄÎà$ÀãÛŽj¼»G¹“%èêbtÙ·ôsÊaç¼4¢¸‡k^ØšçgõÞòÁ¢þÎé=2UÇ5ש|É í7r w$¬’ä°“ÚíV(.qUI¸qkz‡DB|©ÔÊ¥I`W¸˜´PV!ï¬vÓçìÝ;:®ôv>Ûp0ù(iÕ èn¥ x/#ÈrÏ!Ø@·6:´o0ñU7M³z#B·¸sùƒÏEiÜéaò줛+ D…ÞÌÞ¦ÝWòYk´D²öÙþ,‘zþA…ú%«“®.òÏŸ´·¥¿Ë»§:ˆZœ-ñSSq«q6\î1zíÈÂÈ6÷Sõ,—ƒ7sŸX~ã`~)úØÑ¹5é{lò?5Ë&–é[Êz$óV–cɦ‹ðMGõw9÷¢²„jX2YïvìX‹,µ”³¨)¨Ø½#/Üöñü¢s{}Ñ™‡RC¢Ýfl`Šø¸lçÛÚ(«á§¡«ÌÐex;æ[õôÁ_ñžCYw À2Ú8SÕ7t¯$Š8­‘n ùÚâvøÖ®öÞQÜ#ón*-WÿÅÓ=êÖ;˜÷&ˆùt°7àð/~ï6Úl)·(7O.:$?V)èî‚a„©¡ŠžµÕQÐnÆ2@´ü7 þÆ5úÁÅ£ç2ÄoÍS 3p¢[éQ<_²ŒëGÞ͵²Û8ª˜ñõØî4ù ¾Ä ¼´¦ •z³IÚaÙtÅÿß‘ÿL=_ŸS^ !aÇgnàÚdvÆ™»écåÿ{›”)ÿO»‚„¥ò¯õgúµÒ]S<Ü‹Æ}€ ¶Úô:ˆ!ÿð‡|¿7ň„H¼pì´Œ0Œ?„Æ}àþ€ »' Ä}`"¯ØLX%3FÀ° Ÿ±5ìŸp ÜÞƒ©¡? áLckc¬ ã “/ €î\h4n¢Ñ aMÄÛTþ' üÆ6Iü]ƒ±µ>$( ïpœð@añ&}û`ÿ5üA ~Gw.Âu7 @xÜõqG“v±ÁÞ:LøŽý :ü¯Q@6Vʵ±C”Ÿ¿òOUíú¤öži`R±üÿ¸+éG@e  ð;ž(Ý8™ÅÊ"VH^~hèÿß›ôÿãØ€Dãg‰Â7'óx¹§Ô3eƒ‚Ðø ~¿ÏØVx¢Ò“ZÂUpÛ!4qoNÏU…&Áë"«ÁŸgÌ2á6aÆ0€`*Ö“ÆŒòƒ¬¯‰˜Aq$hsþø9³üÿ×ðǾ”Ð;\÷q[\ËE(ñ'Û~¢Á‡ñ#ªdÅäL0ŸÇßÃÿ¯üSQ›œýŸa `2æÿ¿îL à ¡Nr¢÷‡[p "Ç“s„è¦$Õ¤ãH*Ÿ|ÜVjLêpLö¿—éï Žßãdwí‰+‘ôþ"0ö*¸£aÒq CèQþÇŸplÆï= â;ã¼ì½i‚1'ïP—˜þ˜@4¥÷ÁßãSü@` ¬NÇü@§ÿoñ ÅùòM<Ö°Qâ¿Yòiñß @…  M$£L¤sãð'ü ðrGü•ªi“µÿ3‰€“ëçI.㜳ñ2 á}>œàOòQžn¾þÞ04Aøáÿï+³ÈLJ$hä~¢À-ÇŽMxâ>VK‘öÆ«s'Ã8Fy£±šƒäzÇ¥0‰ÿ“ƒ€ˆÁÊ7~Ïxµ€µ jl?¬1+€©àïàïMˆà\)x LF†Òžæwàð!¬0…݇(:Jü)  ÌP¸‚Ÿ'…ü” €¸ø;"¬„3&ÿè¿òO-mòöŸ 3€LÊý‡(Íÿï z@! Àjr¾/0LRùßÉ48¦±S>Œ\?~œ†sÿ°÷~ãˆ?÷• . ‹LIûw쟠 $„Фs£Ph$÷ä%ÙOqòMô4ÆV [q~ 6Z=v:lpb Š4ÀÔðw?† Sûñ8R¸’czú]øChü!!L ds† Pà?î´€SjcÅ8üÇûü ›X²ÊÇ­ <\ýÿÊ?u´)سžö`²æÿ' ÿ¨…bóøÚ¬À?öù(×@lÐè‹&?.Š\ Ù’`¥yL¹"l¸Ù>Œû È똪€)kŰáY4Ùºˆ>…ÅÁ¥&)ÀËCÔ\¸è®;1 H¡ pŸ8CJã$·#Þ'\,«!&Æ©FL Ø—˜Éýqè§KÇÔ>ú÷áò!®#Ø„°?±G(ð‡~`ü!ü-ƒu2€â±Çx£ñpáð'ò:˜äÌñÁHwÏ€¿òO mJöf0€IÛÿŸ9‚ÚBØúo£À0üƒ\ðxåOúŠB¸Á>ð @‘:Æóf e¡. …ÁŒ§û”’;Aø ÒÍö|7F“õá8l‚¢<#€A!½ ¾‹„&ô‰"ü‡_u^7Ä Nâq;àT.#ˆÁy"Þc=¡J`êø{§ü L¡É±ÿ¡Àß‹?M´>Ž h’üÂdžüâÉ ŸÊ— ü±õÿø““ãàùŽâ¡¼Ü€¿ò?óÛí?A<¦3˜¼ùÿ¹c¨‹\ÁÊݘl’ÒÀ™ r\Btó ÀUtQÂ!ˆ úÁ2‡ ôž(âDÏW´;Ñ‹¤Hh˜$÷d3’òº1À‹ü çÏïq„ŸÜQ²ç}b¯á< ì¸üý⽈±¿ƒØ5líÚØs¢Â±@¿€¿{ > LaðÂâ*ý;þ€ÑJc <îÒ¸úÀqøãùŒä@îjdR@=!€"üh;qŒD†‘´“½R±x¸yûÿ•ÿ™Þ¦jÿ§?ø_ÙêbWÔ@aÐã¤äGkãÓÀH _ÌÙ‡lAý9Çzߥ ¾"¾2œ,Ÿä´®FOÐÉÄŸ ýø>d @(óPXñõD þSðâ'6ÜGŸÄsÆ9xg›Än@a#‘(Ì8€*4À/áïuÌ QŽ¬Ç‚‚å÷ûñ÷ò†‰®#¾äqḮÀ„-”ø×eˆd‰¼ˆ"@ øá=t<þD;';†•€Iåã'Hwÿ¿ò?ÃÛÔí?áç0] ÀTÌÿ¤ ÀÌg… Q ñÕ³?Ðý¿“l€ð@Æ‚¶`é:F“ÂscŠˆÏ‘ÝFâèâq”v ˜B_äû…¬/°ç&•¤a¹?C )X¦ˆô’HÀ9†)T® ¯°-6Hm¥À¿ˆ?„M ±¹Tpºàaˆö‡¹ "0²w‘ð'ò € Òp6J0óñÇÏÿ†ƒŒás‰!ˆé˜ÛØ?„‡WÀ_ùŸÑíWìÿtfàûõ“´jB…øN†ð¸ 0Å£ú%Ey¹£½ £„@\Ì—HüIcÁ&j€qi@|Á/IÙPj©ÇWm¡ÇmÁÚ+˜<> H±ÒÕ6ÑcÈÿAâÜtx=àÇûñÓÜ=€1ý€ÁÎ'Œ~3]ü2þ¾Xüq€cþÓ ‰•FŒì¹ü\H‚ n0ެ u…Š!RàDÁß%Æ…þ)‡à*€—;ðWþgpû5ûOøµLC05÷ÿç#³À™Í )©iª®º{ß™ÂX0? n2U Y qzõǦHb#ÅäèIÅ®‚×?X1‡ÈÎIà£t”ú@S|GbåïË0¥ÜSÊ?n²/’²Á/AbOðÅA¸¢`\lëÚ•þuü=±ø£°)Óé„??H¬þƒH3Ãܤ>ŽÇŸâ´d’n˜ðH(–3ÿb’u‡±õË@&dî)ý„2”'¶ à¯üÏÔö‹öº2€©šÿÉIúÌdP@Òî¸G¡ˆ¡¶kü‰[°½£È¢ ‹¨X‰J„ CðB D(ø%o!k’òE¡ Óz“§jÃkŽïÇةމ,p÷ƒði@|‘î4ÅMÓ|1a\!HVþ¼?ÂcoÛalE2ŠŠÆýø£‚0~Ó „/! L¨ú'÷ ¯ë  ‰øí̸¢ 樇\#;ÇØÇƒ¢HàwoÃ)„¯cø{ü•ÿÛ~Ùþ~(ÓŒLÝþÿü¡?‚™Ë )t:NøP f|øGÊŸøľ5xAÞ0Å„pJúQD„Q4. 8!åG±´ qØÖ jr€$ž‰ÁŸ-ôÀÀ !ÙHá°§þ"®Cäù?‰WAÁ¤d#!:ˆA²€p1@˜Z4À¯â}ŸàO3ü=}±çÀ#OG85Eü"vÿqI²Í"‹;±¨"/f.þÅàP 7La‚»OÞ OCüÿÊÿO¶ÀþCÓ/ð æRÇÎüéýo¤ÛÆ×èŽÿ¥î'É€­‰Áý/wL€74~*Žq2MáO®äÈi@¢ @¦ÿX¡%NßFÒ!nFnˆ@äaòqXUOy²±ùà{:æÏàzE’xŠ4 îhÌ„Bež$ù%hâÄ(ö]!øqM?ŠÎ\ðkøh"þ~Ó Àï68üÇq¢AÀǨ¡ïñ“’Iå*¹Q2€‹?ÖÿÇü‰r2†?=> €vDŒˆ[Ô˜­DOOüÿÊÿO¶ÂþO?ð+ö2Süf(ÀÕMÐó’8ˆðGø»}Æ+è=&;DéAzzøûcÈÃqIö‚¬Hk €Æ) D L’døvˆ™¨9HoE“¶u ŠüF¬¾r÷!u…ò!NkC¨m&Ê?n“†d= R²ßSÜ8`œ7€ËXþà­`3VLv„7e¤—GÐ4ÂÌý'Øþxu\Xßâ›(ñ¿ 81@‚P(&…þÉI,þåˆ?Ò³%íHöU¹Óÿ¿òÿ³íÿ â¾ðJ7xœí}ú|>}ó‰ûû÷~Ô¹Ç9ç¾Ïxž×ó5Þ¯×û2`'¦n(¼'š Þ~±¡±î¿òuû—ûxg ü0X¬÷¯œs²ÚE-«TŽ,ã÷2OŒQFÛ÷ß·{ÎÞë2¤àìq§]¸%ë’½Z5ÍìÚV¡èN5ùÞ`¬ˆ‡Ûõ“¨òî°O›.ÝÈ›Ø$ngè”|÷ö+Æ–Ý¢÷¢Pιk첿úæÝíuCg%¢=Þ™]+>6äúq½oa_ùëÓÁJþÍ÷fæãù ÷íü£7cyfZ•©>çékz±ºbEa ‹“ŽœŽé£ÖNh+>ñ”8\Ú¤´ˆmωó3Z»ÞßžƒŠÉ:öy奫»1mg‡^s¾Ö«¹øFb¿…õçB“ˆañòÌ©‹ÿo“a”†?”è‚¥Oü'®(´»'n²¯n Êó— ‘qôÿ ¸1] ï8/ëŸ,[Aâ°h R*üzw˺U=sô gð½iþ‚ÿÓÇÚZ»·[0ƒó®IÍBð_-Vˆšµ svߟóŽ6zëò2.ï < c´ÃRã¸-ÊÑ.ñ6Çþ¶gô‹Ë§Ø»Ì"–/1à¾Öz Ô[R9­†½³&ý˜Á /C3öÄfá'vû%8?™Ÿ´:(6µñÿ}òC§¬"Ý£CC<èSþ'° ðð˜!ÿkü”€Oø`@:´h¾ÍÙ¿¿áÆþÌ××ßq~VÙ³æ· WÎ8aÅí¬O¹.›4†¤Ø¢Týì .°«nðÐЗʎtˆZ¨¸‡ûzèý¬§ŸöÕˆÌHö>—qI«9¯ÀÍhºêbÈ«î=¸Îìj½nEò@ƒÞ|PôœÏg¼¢unuqè \Ò-Û7ÓÖYBgä[é}µ)‰VGUžË8ÞdعñK&KÂ<—„oÔª—oHNIJ=÷ä2¿‹Æ²À‡‡F÷–ÚÂaö‡«”}Þm¨bßòý…p‘PêÃÀJÃ8¥c]EuŒ;ý OÖYoq¿Ie·‚ãÛþGßV;$Ì2¾þì,‡nÛÊ…'W:Õ^)y‹©6;ÐúÄhq'æ'/£òˆÓé’[«^¯½uø“†ÿ‰Ýa2ž¾Ýùë£öø¢®%ØŽ`Bu­Óhb6›£z©ãLó÷oFËqÒ^þÙ¾Ñþ§Pôèü þºøR³An%¿Ø Çé7o÷ÍýpE8KôNjgu付óñÂstÁ¾)€¿4Öݶ,Úqg³nÆßÒSXÑó–Í-x[óùµÙ÷d7ê®”ºï0¯òr§ÍŒØM þŠb±ÕÛ;òóö¹o[;œ·Á¿2¯¯Ðè…Æ’G:Š*Ö×N+¥Um¼~펼×Á=‡ÌL;nX£èÿÉ~¥6>®5/9ÓÓž…Ø; ^OöL‹_?÷ýe15ûŸ½£o¿-»ÞZƒ)pQíŽ)ÿo•6œ¼gdRHX@Á¤?ü'´W¬~²-ÀÍë{ èóŸ1È!Mƒ2G–½­É»Õeöû ÖCxÙ%Û™c¹wâñÒžß6-e¬ ŠA}¯>}¿¿9 B¼ÉÐì™Iz—ZîgÜŒ ݈‚­2Ó$+Ô÷I4ž(äð>•ºÌFtYØÀŠÝ/ëxs-=-¦‡»¾bÒñ/å¼Î"äî:èb^Ú°mr¬.s4Ç閲܆¢üÞô®âW×P‹›ïtßîëF<ü¹Í­wñŽlQ ’‹@ð¿-_ñ.•óczÕ/ X?s?µ.=Pßw‡M¼üˆÑá8v´ôðÑM™gÂ<›dümgÌ.oJ+O=›Á¿KvÇЦUOg~<kVOü’Û_Ò\£¶žvjáe½m´PŸábÑÇ¿â`M…|ñ¢­µŸu¯½Uü´Á_`î‘öWXVîë Ì|v¦&܉Íbžª©¢ibrÐÒØÆÕÉŽÞ4@Òñ%Ëd•Nd­Í³})/´"¤¦ÝÉý7Þ™uÿ‹œKZÖÉKÖ¾Ó d´>ljV¥ü»üO÷Þf^ö ö¦Ëà„6ŒÚã×ð/44àùëü¬’>ènÀ23Íê«Ð• +ã–>±Ö¨’ð`þÕ¾¢5øÖè`¶†Y™§j8EÍÚRgzÛøÌ¦Ü™N,Š~Is-õÙ6œ¿vu˜É„7ÓÁ¼2­»¾Lnã‰V§Û!s¸Ö^‰ï3N޲®8¼Ñ}.óçÕ&IwÕ²æ¿Ö5ó"CòÒÄÀp¹éî«ÙòÖ¾²~åµ½Ìi–;ï&žK«åžl`JQ‰˜.†ÿ"w«Nu«|hñ‡ûø¬8VÁðV_ÖÊQè¥Ã]Å–åûûäIÛÝͶ’±Qaš}ufg†û^èybS^Ù^•–ç ýÑÉև줙3ƒ­çÙfîú˜Î€RÔ[ŒÚžûÌÏ~£h„±bI­Ñ7iµ U\ìêuóêsEâKTŠñ?ïýX´SÔ{î§â½Ï w®aÞãÜr)*jS'n JÆCšMͧaóù>iæÅQÎ ;½|ΡQš¾àñg ¸w"ËRû’“N†Uâ‰ð¶3Û»åß°EH·Z6w…Ïbè ÿ‰o zºOZtõš€s;ð·r€Î¬ù«CsƒvEŒ\Qgܘ•›lËÿá‘ñ‚G—xnJ¢ûbìíb]¹}ßë}ä™fʪ&/öâÔóî¨ãøfú¬Ó•Ywe0ŸXnKÌÍ·O¦ÍŠ´­ÉÌàh®w–»¨!§ ‘¨ñ0ðeÀ½GÃÕz¼_Oó–q*›s=©¾”\k÷´þê6@LÍláÙ̸]fPßqôv÷Ê9Wø$ÜZÁU[ôn«-:f–Yò©Vê2È(µ‰[Ýxþ®}.·œ¼ýž ÝÊQ™éÞÞÙ±>½” ìôË<~÷à» ©,û=QÆæ…o„ãÊ£öÆún|‚ç7zùX%àͬÁ½ÜËÞXâ[DmRm,õ?]ôzu½èúzEÁï¤éõc‰'¢-yWòƒ%Ë‹4?ÙD§/-|/éÛ0|;e{ØH{]ªšfp9Z¡ËdnP³Mid»Vë¬öuÙëgù òÛ[¦Dœt¥«A€¿Å¿ê²wê ­š?ý¶o@çý#Æi—Ø,ßó¥=¹}‚§#n©ÈýRéÓcîxá†k55~¯ÒÎ$wv(ž<ü½>ïzýšÅw$ýÛåÕYGS<ºw‹,[$.¨]b¾þó‚ò +RûÖ¼K3ÅAB÷÷>ÿ 5»¯Å“;7•w©bíú´ˆø?M;´&îc´m—Éãç BD„çRv£v¾æ„ýšÚº&:Ú6ÇÀãt¥¬•㟧žYqÆð¡Àùž§Uf}j‹•²õJƒûÅ6hE\”“ª4£/ü'Iþ…NÞãcB‚‚ÿT€hä9YinX‰èfÜÀßd €®j­fÊ W8,ú^W¾ jØÒ¡Á2øðã¡ùÖZ±²g:Žd¼d5w^t¦r‘a‹&P2xvUu_+GŸ)l`·^˜²ûâ#­/?È~0Õ“Öþd—|ÇÊÓ`ª  ´þ›PѾ¯E¾EU~uÂÆGór¾ød™l6\c`,½E Û~kòí*ÿÄày‡\b¡ìgB†|FwI7TÔqG‹E1l8móÉs!Yx©Ä×[Z+žúNO’æ˜fðÎã*Û€Œ®«¡× US)¶‘­WÃXB3š¬\m a‰³PÀ]â7ë1ÇXR ä­ß?»Æ¥èß¼*À6§Ò™Ë‘ñ–šø†’¢þªmò3ÒÞ[}zà`©lìºì{}XŒî>ËðAýÓºC¬ƒûeŸq8TÉšgÛkª¥Ê$k}å®qÞ2ß0xùu°Æñþ±ö<»Ä]š%ú q¾!'éhà‡ø«6†~Š||¢çÄó—Ú;12ë’e›¹¿-LØúÉ+¸!EÈ¿vç&;̪l¹Fi7ák_½Y¬+4ÓFÛLdIð€Å>¯Ù“…ÿçÎÆgƧÁT›ž î+0Çø/qÕ(º»¨ŸÍïü‹î={1Ýñ\ö /¾Ù5XY¶ožÓ1øfIÿÝqð·Ø«×x`¡YÊZÇ¥éJÌìDücg­ÚT›!ÿÕiæC®ã¨ËЬù •ùá›"uµÕÕµŽšYº ¬é(  ˆµqß,åéæ¹§ÎÏŸ–È€=õ%è¼?-.·¨<úùÛtºÃ²äÿ¦íÙÝ&™n1ÁÁ¾®ÿß[€››»Ç/&áÿgFM„ûý ô“P¤Î*ߦ×ô,GV®êæþ9³çæ‰Îà›¾N"ïÚ‡F¥MúŸK>ÎbV‹oâÆ£žÜù¦¡¶8t¨Ny·™o»½ëÉu.nÊOοcÞ*l:çC}†g¿¡ûÃ6¥™÷6íÔ¿)ØÆÛ’’çñè‚Ëê牟…ín<­¹ò2ϾrÄß{}ç`ÿš ÓÝŒƒ4b*E“l × x)`}m;ä Ó·p”´L6rû {úW–aII—nË&÷Ì”ªõ¨é† W–š÷/+eÎ6\èâ!YÑ¿O”ãòú€ù ÕêW Ód¦9¥J[â¼'ÿ<{ß8Œ8_o™}¢TŽñ}Õm gTøÍà׋ÎI=W»o:Ëjƒ‚¼D§×öèîa¼I¯Ìêñð·2S©Ù;2½P)°Í§æ”ó§gDü/£gì°|ûÄ‚i>÷«CJ‡L/i¿Œ«ø´g¨Éa•æªVú¶v€½Ô6·Eúæ~w,Ä‹i´Ý7²R?¾åîñëÒþ- &]þÍ÷‚êÃÆp¼Ýø•ckûÓª÷Ï ¸1íö•ÄHèÔ›IÎ^kõÄ“Uü€C{À.¥ ’z¦×NYn>ñ*ÏÖl^|›ú^ÿn*Öø¤›•Zo©Ë^®dœ–+È” w°dNgö`–êìWÇ_Ô/Ý·Ý­ÚSäÑŸ¤óžõ¶@Ìüºx¹‡ ²Ô‡ç'$±;)+ºÏõ°Î¬WžÓnŽf³+L±e/4„$ÓóÌ·aWá|g=Nâ8|¹b^¦˜ïÞjæ ª¼õ¿!¶æêc±MZ™k›ž²5Ôw­ëOÍèR”p òz2ã\g/ךªãEÑËíRb_]=ý¢nï0«Ò³Îò«(Ó„öÇ1žÓJ›$+Ôœ‰fÙ“U¸gqÐ-GUw³ìŸt€ = PñÖ[ÎåÈÿ‰UæÅá’΢õ:óì9ßkîí¿Ì-ñÙgöùF>²ÔëódìȼUn#_ §¤[Ãì%öIsI/º‹©qnýú÷IÖ¥êÕš;Ҭض›Ö³ñìýÍø—q+ã> oœ]ß­ Å½xØÁøyyÙ«É®æôõÕ+™ÂZÉð‹-äNY·oÄl¥†Ä¥qñ[¾´+×ëøÎ´øU<ðΕˆ?ÿ]·÷=.Ÿ·÷=Žašuk `-/›kàúžc¦¥ÿq}E}Su³£Çl\OЃ81 ¯'Þ+Q½„7Ý­ž§µž^ñ?©¸zòåÿ³–½Î95(8$ÐãO- €Âàk€8µäöƒ€5@˜ò@šñžsPFï­H²Ý'ìêy4ù¬9¿uoÅç¹7û?×Þ7Þ9ûAû÷îD”è×UBu>Ưou}Ü­jßøâœÛÛs‘eÎ#ºxVvç%³<SÚ¶Óþnô¯¨ìôÔKV•h£DÇ/CsF:›ƒx¾Ì̵ÞÃ3")k\ævo½ßùS+ñwÀÜg¢ç‡ª`¶$€ï_˯ÚXÿ‚c—ýùòˆ7'6¥9éG­I¿Éü=©g%Ç2g‹ÿâ &'./Ö¾qù“Ë&ÃÅ6Ïv¼™ª:hvWÎp~oË#†’Ó bH’4fÉ™%Úr¯½]•‡¥7?bù‘¤zœ¢pñc/ï&VEà µ¬‰cõ uñV<½…´ï fZ`Û#c¾Ó?½VYlW²wðΣʧÄóG¾«cÒo¬îx?=¨êÈžt±`ÛŠ4@¹õEÑf®¡sË̶ˆ Ú»]-¢(uó²¦OˆY¬ÝU—˜Ly á¿îš‘i¼“êá Ö™AŒíN‚É¥ 6•+¤ÙVKdÔp‡-PPP_©'6Ë»/f<äÌù°Ö™ñKÂüJËijÏ gG=áðÓdØ;#Üsôfƒ÷¾ žoþ­ø‹ùœdÙqÚ¤‚I©¸Édõõø ¼[› ¥z’*0­^¬ClAñü¾—v—¿Ã8¦/ÌÑn³éÿ”œÇ'ÃW—lçiàG={õpóA"þþŠìFóïÚõ@/Š ˜÷Vö; ;¹ û–ýæIËI }‰cÚ&GÐÖt0 ´Yu}aŽŸZ;Ûó;ºšô‹¿FgõtÇ—SAþú›Eƒ§½‚ƒ1˜©ÿÛ)Ý[ÀÄÔþQ»_ÿÿs€ü«@tP û=³jOÑ•uøg ÷úyQB;ž<Û)ã›qÂÒÙïƒmT"ÓPNÑqa—´™/½ÖƉ­¾”ßµJ‰3ï|Cqdž¥Ë^~ž}Gÿrã’†ÖG_vi&„wx»+6Gª©•E5p·õÈڜà ³{W†ð [ïÒÛ}àà\wÑáyÊ_™ž³˜¯2ï}Ý.µüv¼Km侞§ÍWœÝ¡ýñÿÄÉþ¡Ëdr«3±Û'ÁTÌ'°2a]éV«°E¬_ðƒ®oÖ2sn/e÷Hýˆ—Øì&`ÁMKs¶ññ/m ,+Y˜ð6I>ð;_óE"þ_“Ž6áøŠWo$à¿™ç@sƒ•”ZSª³õÆ5=8¬ÝEƒ£Æê6FÇó)_ (è”S™Ÿz•¾ñÉ•2wŠÈ¿­"‘ìôgà·N Œ‚&¤öÒ~hü`;ÍÄ©Ÿ`?ó~QiüG<êX<Ë “ȱ€Ý½ Î7¼½9 žÿ<%jØïMô£eú¢ÑW¾hJi¢vï™1x Ÿžs2oŽPkFmÆÀ‹,&“7mÎežÒ/¸Îdä=Î`xÕ}¦ý…kÎÛµóƒ˜ô:ê4¯Òð±Ï­mv¹®ƒ:W®¶æþJÜ¢TÙË wÔ…'ÔãÈs×ò’ªxËyè®°a©Hà &ᙌ¹êޱɶ‘êOÙo9½z¿å›c‡ˆ»K®ú:•MŸ Þ½fÛ¨–Î0Ó4Unµ—*Ç«¹ÓL¸¹<­2üna*´Àg°43²õñ]¦ÞkAór*mv(Wð;—d¹Â7Q‚KV ì‘K›xlùAþK¹ë:N.í3[*¶:ˆùz¿RCe–teÇŒÆûÃaÛDü„”…òÞOHsyÊÑ,ÔÀZ±mÙ‡+ù*gJ‚_Õ/€>Q€í¥€¢¢Ù%iºaa{2ŽÇà"Ý]§ø €a‰Eµó…“\û ¯‹çuÚÊ‘œÎU.R`ÆÂî_í¾I KöÁw^¶Xþû}G´™$†Þ3ŠÍ9'SšsåŒ@Îi TcÈÜ;l™¯žKSÿ¾3ª`ÝõEODŠ•Sýª?>]m)™ó›ð_Ϥ_¥½û+*Ðc°%i£ÃËüÕ{¢_n^õÙ%pvqHq™î}ß·},ý×…¼Ùä^Ê×Yþ©ÞõGøûV [c÷snZàðÞð×+ƒ‰øŸ’Ìýöìõ›ÕâÎvßÎjuqGë¨S¾3ë+º?OÇÑ9 nhj|ÂÅÙfЧ0¤‹Ï t¤üêÑSFþO©Æ»„û…xý©Ðn¸ß3%ð„Õþ‘ÛFþÙ ›ZÀâUÍKY‡8º¥u]z2:zVq/ÐŒ{žà“ýj[šhØ­í˜áȸª“›ò–)Ñ`hþÖæèeœ:‰ºl*©ofû.9uaGQÝ#·ÅóºUºÞŸ[¿öexÊ·òó¾ {>g·Ôaé köy²Ÿ¼µE&b×… ¦!GGÁµ ­d H¹?»qÍA¾ÃòF¾É‰I{O…íûØκÙß¹6BUêëû%FïW­Ü ùs›ë17ʵl}øÈ «ä«rŸû.“"« ×¹¯bLùgyåÕï¾z(Ø…çì ‘9Ñ9Á‡¸ï%ëIæfâTÕmÝ BŒ_‹»v^¡Rt!óx \hÒvYû;Ž·£1ß“äÚ¾µ57 Ïù~!»ÚJÖºehAïìG¼œÉ‰Ø™«wt$ï52nÞUvOïëV‡YÕŒÁG÷×_UèÚ'uEcñ²Á‡±%Œ¶QVr\–Û<ŠtóÝ“0Á8Ì”¶*f/±Îx°+LçûÂf™8Ö&m‚x™Ýqgòtb_±aô~`)±8§ï¸Á=µìÖªÜi_Z-­v}Œá˜Ï^ë;£â¢l¼§üšë+n okÝ0UÞ.¤[»µØŽ·VóÛ&9¿›¿Á+Ûº*oulÜwæDk¶ emÆÇcÉ[›™{Ê”˜F×l6rí;£”êM5{"ØÑ}8ªâ÷™Å{||ü_…K•>ÅÌÉ^+èx]|ãÞÒÝ$ü™·ò›íb(Eñ쯿«¸äÂP´Ì!k ð¸jZW°«£±ìQS#uC[{´ÝÔ®|ùnîÿ üϪwL%ù·’ð¼n{)4Ô/;µkó'¨¢Ç;Ù?ýCjÿB=ÿä×ÿéÇà¦ð+眬–KºYäÉ ÀÀƒ6£¶‘ápx’cœ;"¬aÈA‚@7g7_/òHiHYŸ)òe,„C¶€Æá!dÉÐ"®Âkt¤%éÛ |.é–¸‹¸Àai{@xÒ%ƒðÕÂgÁ’:ÁRà…»#¬àIWKü@.Ä „CއOoàÍ8Â6® ÿqTè‘¶ë¿Àç¿nÿþãOÚƒpuöðÁc!ª¹%‰‘ nDb²¸Ì ÄÓ%¾‡¥õ ¨n“a Gþ:²ƒèÐaÉŒºA4§3"ú³Ñý#û¤ó i´“GpR@Ä€»&ºF€Çˆ‰°Fp €DYÔF ð“ø8w¢ P\;øþ>Sˆú=uü)^?DÑJã࣠’n¢ÙA^P݇ò‰O"Ì}àO±î‘;þXzÀÿüÿë6úªX¿¬þÉâ˜?ì•ö 7 —ø1Ö$á¹Iñ_‚ìc‘ ?±QþdéA»ºz{CXh”Ð"K¢A˜àãR ¬äN•f‰CtÈN¹s8bHø.ÄAdi‡ùOë `gOÊÍP„MèGKZdÝFâ2±Ul䃤 õC þâH€ð;N îà'ðà ?U(|MþÁå7ùøÃi@”3“lS‚?KÖd DÜI± hñGnš„ÿhÕ0Î#¤k  €¬gÉB%düIhÐþäÿß· ÕÿSÃøuý?~ÿ*@o@¥?Q6 f31HаxÊà–&êO”1J¨psAûz’Lf*kÄñT²kA5ÿ‘Mh<5³m輆Äiˆè+K ‚ u°¹'Oˆ â}Àw ažAäÄQï$7ª«Àg@„p8âUP"Çqã¸tÆÿ @ƒîxÚÞQŽ3HÀðŸdü}°Ô€.€#+ 4QÏPâiFGÅù  ¤ÐØ ä5ÚÒ~Ðþ¥Ê1Ò Xìñˆò0h‚-@/øÿ‘ÿŸh¬ÿIoÏd þÞ Û@M0oŒ=8ôXáeÇ{à +Ð*ª…N ¦B€rÆúzMk$Ò …:F ?HŽüh¢=`ðä‘<ªë@> ˆlòcÄr‡·`ðÄ«À¤KF{`©XÁá?ҹў¬ hnÄS2h8 Ž’yùB 1Â^¤&8"ñÅQ”®à_àOÐÈ(í˜Áh ¡Ð9ÆÍÙ}rñ‡ç#{ƒ HJS#üG´U»Q,)x<ò]JÀŽ^}ûÔºÂ?”ÆÇ’DŒì!ø£Ñ8ºÂÿüÿD›pýä8!ç¿—¿ø‡>C¹£Ü¿ÑŽ HL‚ì…# |Òê~,5ê?Ú ð,ÊÙÓO«„¢&Ê@¤¼]ª`#,`@x€ƒ$㌠ý‘øîˆ* ,‹ˆO@Q/ÂÁ‡ªÒ°äXâïA¤´v˜ÛNÄ‘]ŠkGÌ÷Éž DŽY3 ‰ DÏ.À?áOðy`üÇFÆx~Í—Aþ¾“ˆ¿“Dé‰N>–ˆ?€ãu¸˜j¹ŽÅŸ”8z€r£­âs¡ù¤#ü F?<¢Xk$ psé ÿ?òÿ3mâõÿ$[âþÿ¨›ñó¿ÄF7@Îh«žº)ìøÁÙ³Øqÿ¿(Ê6íŠòñ‚‡Ii´ ­àb) ’€ A ’×Ks 1ˆEÒ}H~%ä@ʆ£phìT:wñ4÷B ÿ‘zDcÝI£„d A¬Cé¤0â7 À!QH¢kÓþÅ ø;üá*?"+C4;Æ8ŽB àïæ?iøãð…ÍÉ9_äN`%Å(>‡?H) hhrÇBN üó±”§EãiCÈ䥇™ñÿ#ÿ?Óþ ýO‚I1&ÆýÇþ²@/’ÿEë«` w)2»àˆ­ãO%V,­òÇ’†Ñ~ iøÖÉ¢5þ© @øšZ âwHÜo„³mF}–fk¸ãIÃy)‚èèC1ùá­ä"6qÀÕà8²“Cê?&‰‡È$ð¼M¤›áŠ7âYÄ¥AR‚„ ¥Wøþ‚«Œ'V@Á©ÏxŠ=ÚH&oƒ‡&¢Þ'¾˜ Žz.ø(@ãq¤X/@|£Éž>¥‘”ÅJAj €¤ÉÆd  í'àŸOcÃSÖø£18úÄÿüÿTûoô?vÒBäþÿÐø{€Ö €6þK ³ÁN)‹!'éЃ&7Æñ‡E*Éi'(ÀƒêZÑ8 • (v8™¥¤›ATj ''ap$„(»á%>5¼G ×(iâŠÍO¾9ò*©˜&ˆ§x?´Ž@äÀ¹“Îb RÌáÂÌ$érÃS§%;bR£CætRf2ü K­Bz<éE øÁ~žŠ… @d‚Xˆ$N5:j%Ù÷^áYÏHg%q•4Ç1tX < 4䎇Èóá õISÂŽ&Ú£@3Ûqœ^%àø³¤·™ØeüÉc,ê…å{Ò£ù˜úøçuŽˆ?†Þñÿ#ÿ?ÙþCýO‚ßiL¤ú§‘‚1Ûÿá£^‚©nä’Þn ‚u?¢òÉódRsýIƒ´“‚ƒ4Ž?m4)‹%íÆ¸¹¢ý=°ä#y%K;B±¥CÙÃsÔ3fü¦T(Ã5@”iB1î°ç¤ð ÚJC¥ÒÙPf´‡'ïÆý9,ˆ¥©"6ræ@&6Òåà‰ƒ\(B¤'$HpFþª¦:Pð'VøvüF±=yª6 ÷Óì¥Í'âì àüVüI¯(Å¥y;<õÅ"5ç$C[Hl” ZOŸàøá©©ãÆÿ)Ïú1Õñ'ÎÿOÀÖ ©ð§wüÿÈÿO¶ÿTÿÿîÀ4öÿÜÝø½ýc€Ö˜â@.<ÿôpÇAHÅÕñ¥üÉS‚âþ2@k×ü9á—Xœëê‚÷¥”vò5„xà!42ÏOÁxd°©ú±ÔÁ8iÍÍ< H,˱ ½DüCÌÒÚ(.@˜€@Sä™L‰|5ÊÝ#ù|ÈU’© Þˆð qv¤™O4z`w„î&CðGÃþ£‚¾õô°iJ`ÚÝ£h$B8 Ïbü½~#þN~$Ý@1LDêÂ`’€Ë#à˜'œDg.À54G úþÕñ£ àG„à?÷Éñc\=ĸ¸úý6üñî”z1x@'‹”W‰EDü‘óA?Ài´Ó¤Œ>†n-€74öÿþäÿgÛ­ÿ§0Áîÿßtø/ Ú·` [Ù‰%;þD§qüá›(¤@!‘@šAâ@’WM P-vxRpxJ`ÄÒR'1GØ£È4Ùœ "g'aÑ£Êv‘8!ÖÉK6÷©?äðD¡3ÄáJâ/ƒ"5Á´¡^ }ƒDÃfðÌ$ŒÔSö `ÀC¤ßKS˜®Ž úþåÕÍö¤_»~zäqhLÚã÷{ðGùм~4#õ´Ž' DÏ~„~„?DÓqAŸ¬¯~ÔFðÿMøÿ‘ÿŸnÿŸÿ d=xœí] ËûnÒxbˆ^øÉ?‘8Á#8ðÜAwòç;¡W5‘Ÿ}z÷£ó0\²ùÒKY±ìƒ‡b6¤íê ÔØÈ&i’Ùx•yÓÉØ;’y‚¡‘é­«¼Ë ä‚àŠ7ÆÕÂúg~xÑö-˜¨Û¾£LïjÑ5ps ›YR]uF«òröÕ#QnÜMDɇˆŠËLôg]Ȩœ­ùpÀ”YWOBfÔóN~¢W5ñµþ>S´D-­z¤sÖØ Ùº±·zôÊ/¥küˆ"±üÑ{®_©h°9«’3k·RþíR ¥¥T‘ûD+á®P~¢ß}UMG‘œÊ -%É­Âܲšy0ë®[Ë1/ñêhwÁW©¶5¥¬Âv¯Ï-í«wžÛ»Ï·½8£&ýÜ-eÔú}àÓŶ3Î>;ª¿Á£ßÐUO Óþ„›õÑÞÄF«Ç.g½ù{=öŽ)OŸ·F‚§×s1Q,Íçúº¬}ZйY»V‡gçV>ÏD©Ë[­·V?ÎÑMòQ6;os",Ú Äþ§aþac瘷>÷èú©=á¬{8¦›Þ²Õ;|ÍÏæE¥Nó´ü5ZÃg$ìö޹JXrʇÒã{K—Ú ÝõÓ{dÒ7?qÚ•ü’e¹;žzcŽmH»³²FÛ`@z¹Q ›¬úú n‘cìÌÅ¿ÿšN™±\ñè¹›°:˜r9IëÉ¿gOu®”*%”iø3éõ……›\=6°ØÆ¾ÎxDëbrñ5£Z•å?Àß½(ûB¦jCJõž/áìYó†q¢düc‚ΘܲùXi=Wvjêê'úÚºYÞDÁ!o¦iƒÇÕM” ö¸iXX¹b¬Q¿ñÿ%ø3”ü'âUmιF‡…†x Œÿ/i…õ"N6@c|&|Ì¿A(°Ã2€Àá/IÛv›òTŸYdw5y•ú Oõ{;¹S>ñ°[ Ʀ5˜¬±•³Tt}Äá4ß$T¨ðÁf['ÝK»Wµ?ݱ_ÃjYguùèÖWl]ÇðáaN UŸÀ¨•’ŽÉqÇnÚà"n®é½Ço«&… ?èopµØ¥}:çz¥dqéÄ="ÌÛ£æ–KhžWn0ÐÁŸ·œY~·$Ÿ¸'ïµÇi¶˜­Ü*ün™z/f©<î[’h~{ø¼@qp¯z@`Óñ¶·þ>· ™ÓÃj„HEÜöˆó”Òsa9!aâ?Ò# É.¹zäû7.‘ïH2a}·‘5ŒÃº p•ˆ:ºp“˜Åå{6®³eçµ.µQv5íñ’ðYŠ«=5óý2ñ…ìËÖ,›³hd±Š»a% cxZ­öÁ+ë„ÂôBŽÇ3L„§ Ë}™$¿R•Åf'ß‘%{¹¦×w°qkÓF­/½¬Z·i±6›Ín054Êç1ïŽgX ÐñRà‡IË­s™”Ù·D¨ÝKÁZ\<\÷!d}¶Ôtþ“[erìöyê°¼C gÅͬ?ú±)‘I´IÝÈeny‡f¾ÞÝ#Ž­—™’n¬íÝ#¸Øg8Àµ¥@@·¢Cëé—ϼîƒ<ÓxŠ®Ëöá‚V­Îštü5y¢Öñ†%J‡–ÖdOÏTLñÑ‹hž-ž½?G%®$´TSë0%5Èeð•Z—–åŸÙÓ7h5ŠøþÛ0ÄKÚ+,Çê/ké/¸·¨‰Œ[³\ÒüWák;ùОw™ ß‘qßåä²îTÏûhGg 9ð¶‘¶©¹»‡-ö7þ¿Æ’Û½„Sa!þ¡~î8†Åÿ5ÂyÿØdþSxxO<à ™ð¿A à°X,£2€¥¯½ Õν¹Å¶׷ÞAV*êFmæ(*Z¦ä°œ]Ú<ÜÏ/4€¤ùsfîw1Š`~!:å-ÓÚ÷Õ¼ß_0é#<Ϋ“?ßœ.b‚Jþtýê{K­^³£Æ—­3rŽ6ãkn\{"»bª0sÔ³ÃÒ…Çfç—ÝO«Û°Y@WøâB–Ú‚"“‹›;›7)Dª} à,ºþäÈàSYëä¢Ð@}áU]½#ÏVŒ½ÚTÉÎ0[$Œ¥&óº¡[ò‹ÈwüU§í^Ï=¬u;Ôï‚k‚>¾.ç³Á®™›«å8À÷rÓ¢_ãÒö XUå_”/Õ›$$'öúH‰ÏNQa[SQÇy¨Úë»ûcL[eõžb?w¾3Wes8Ë´eŽKCëöˆ‡sÛ™?ãgd•L7(~ ¦èâÓ¯Ÿ¯}u]™ÁÉ£¹âs¯¼æ/}å3Oª£-Z÷³|7Àµ.¦‡÷°w¢üUÿþËši&æ—|a>A84£ÆÖU…\ÙÿHF`«é€×Âç}:¡Y³7Uan¤2u;³¥\“Ýnu‚·Ð¼oô飚#/§„l[ªb?SS¥cŽÑVö•à+ö\–¦™ë"ÞL¹³)iý33µF‡æ†lÑÓÛóy³øft?•h'Ö%%k–N2þƒÊý«Fçº(q>K—¿66ní+æã¯ŸOó¸É3eÝ®·Çù_xèéªsïÛRaZå6£Ãt´oz…we¯Â¦%?Ÿµ=ˆË§!í‰n×]œ¶ bk_Éøß«¶/Šmz×µ’„ÄÛTég¹ÝFVŠ© ·øûC«ØÞfIYÈ1W³6°³ót:ƨ>à†“ÿ3F¦VI¾ÇýBð¨ÿ÷ ‹Fá½ñ“È×t¼hf£λ<ã¤×qîøÆV ­§ë÷—_[ÞR1‡7¯‹óáã-»Ì¥XÃ]z›vb¸‡Wµ®ØRúúäSýc«¬Be‘ŠOÁȵ«ŸW­Õî÷cã:>¿9Ô=_U Ÿ¹(dõkâ*ׯ°ón»î«oÚfs2O¼VP2⨟öÎ"¹½¨Î2¹À‹ŸF­¯çí+‘œ?Òwj¤(aÎæÓoQBÎþ·ç ¦Ÿ«hŽîÌê¬Ý.¨r±j­Nܨo:«lòKù’yAº|ê´¸›Ôî8öœi¯•ލÑï•´qób¯+æ~ÒÖ;ÔÚrw`š@üuÌ£ ¶T}dÝ”~!Íx‡[CÓ´j·÷åøé‚G²?îŸ^¨Ã[´¦M‡{pÞ\Íg {°ÞRØ-7C$Cð‹óÏC'ì¯j^ÄãC=qŒ©ξ\ü¸D225ºC<ýpžcÀÒ —d¡Ò)µ tûA˱‘ÙO‡SŠsÖ¶ÙüÎiÏCóÊ…—3÷÷<ñTg_í¾FÏô¡¡úÅDší~aÎ3?©µ€W}b¡Œp®[îaû·~ë.Ë õN›ß3™ø³^™q°7oÀI53Ü"ú.©Iõâ’³öµ8y«—×K =ÈÑ »–É[,¹µ1¯¸%Zº¤fvÈG/Q¦Xö”­Yb?Â8†GLilZ÷éúó<ßžÜ!JÆŸ3uǧje»–“ðßð¶-`æ¬Ç%·¨@±+eýy‡=­T½ŒT´÷›˜Û:¡mÔüïàÏ€òÒ;á˜iuÆ/40…eLü]°¨É,ÀzN‚ûûÛ€LH Í fÏ}]û• #ÒE§8Çô¤¥*£}í•s¯W arÚÎEœ?©ØË&›™ÂÔP£­$r™åSÙ#Ýô–š5æÛ¬;òWt^un¬¶){.z¤ÔxÑÇ÷Šj=³‹2w»MY'ܹq͹ƒiöšƒ£JM;oÕ ¯9{3ëĶjâKNß°§y»·\9ô²½Zð­Ÿá…¬™<»>µ¬bõ3i¶AW<´=hÇ’*—¥6ŸëTV–³¯àHsºSCßžM;ATÊ[§$Ý ä釆7•]‘½pÞÀ;¿ÖJ"­¸}&Xwx5“äÐr·L%²Íü3g,ç?'&ðË—O98`·|ž­ù©Ò£ Û®6úÙÏwhàåÏ*Ø¥4x—YËhF:êÁ° —’Š«{A¼£ší¹7•KÅÏ(oÈØ¥t™ê>³‚1±-·žœÛXùž\«[{ÏÜ+å<ÿ©W8vŠÜÆ@… YOÊ–fNK[¥nw†IeÓµÃf¥2§ãŒ=¶t4‹jîÍëµe›þiãfÃ+½ÏZ8NÅŠLþ9n/ËEw5'–¸ò÷ÅDg7í+â\¼¥4÷D5Q«úKEpµð ÉÖSA‡ëBï¨j^0åá³4~d. ¹­ûãñ/•y·®XÐè‹·iWýÀÚÒ¨6i2þÌ×ÒRó÷Eig‡’ðï»èÀ¢Üè§u0mnÓ*¹Êû«ël¤ÍMÕÌÍÍl]ÑV˜ßøO&þ )ÿájÞ©¡!ÁÁnÿß T'« Àï5)ãþ8@Ú÷gSÐ+€aÄ$€%~ªÚSî×}Ìå÷OªÈcˆÆ< ¢âÔN–oõ»ï¯°å®Qî¬À¢.×>¥Ží=;3VlÍ ‰§w _U2­­È“š–==¥»¨í²Ï‹/sÕ9ÝmìÑ\##§ÓUÚÝY×^qÒ&¦ Ÿ¸XðÌ%µG¾+Ç EtÔ¡ÜÄv>»Ë®v%>Ô^]ø`ª© B®â«ÛÙ’U§Œ>y½ëã€|Õú#‰¬ƒÏÔ7‡^ß’|ž3Ì,ï¾è~"ª:V/È3ª¶ûFíÎIå¸O=(nÝà¦&këÉ­çUk–´ &ÇT„ܧÃlíÙV}fUá+-lË+ðÎ=—K玸÷~¹ãz`I’¾Û•ûLöõ«Õw­:õaãŒ#Ü=»¿,ãÝ8°x¹e‘äÚ¹ëbšpE<§ìVg]Ï®g{ã¶/Œç¹¥©°kõ•G‰7^–,L,Þc›“˜êbsVSÇñƒ©RKÖÒѧa QZçQÖ!ÎÙGŽ<èe+.Ùá_ô^/[åþñ=öÍ”GªýÃ+Òä½´³?Çïì_ÿ‚#M|Ê=㸺®—ÊWíøÐ\#0¶yýà¢~©5Ó‹S–$ ïà’ËeËX²Ê²½[¿qÅ>9ÅW$Ž·}Ú(2å?É(±´,ü7oAÉÅé ¾tyŽ¥ïÞ8M³M7‹âTOélÛj©}¼Ñ5á~é{ívÉÍN~²Çúm·m®Û«ó’iªÝºÖk1z‚?ÄßyŽ; þCº»â‹˜ô´weñ·–ˆb}÷Däd_Ûõ…‰¬"Oî_ÚÉis÷2JÑùh´òù\¦r%ìQS}9ëC&föî.ö ˜øÏàÏ ò­}euˆó öòüϰh4èE˜Œ$å3I¹…Ÿ¹ùŠà¨e ˜è)\__ÀÕêV˜°e¥ÅÆKþ•ìª5ÊÑJjË%4Ïð¡Xà×m}¥Ú1Uæ,æl¥Œ`tÙ1—¡ƒh½Ä“ƒSYÌó%Ëî`Óyí兽ﶛ¹Åϲ=™6šŸÑÞÌ&ünGvÔð­æÌÕBuËÙ^1O¹ÚÄÑT¨8u{(ê n£v¨Òô×sïä- ÿ°å©Dá¨þHX¸¶ºˆöž ”­1OñœM;Fêˆè¢_^ܨ_o¼ïØŠiÙ1I·¤×/îo ›{xƒêÙª‚>IË`TLíËR‘¶ð"c‡w„]·3ßÞÒ¿è鵊3ÝIwËv;|©¼+k”«µ9Øça!V|Ãñ.æ¶ekß±Ô>à2 CM=ÔþpÄØy¸½rïñ–à—wd³ Àê˜)žop6JZ+7›t©v¼YtBVƒ…[íõ­‡Sõ»í¶•;³Wv>k‘ßUGsLíõu%ï¤*vyI«ÅúæùÆ£8á4€W¼FÁém+óœ^¦†Ïœ£Å1?SªFz燓"ÃjZ+k1‹[p¾kÌ ¥uÂq›³t2>nç0‘t[.{:é§Ö¥“:r!ÜàÚÇ®%ÂÏøÎ®jõXRçÂ<µbÞ©éË.ßo-‰]tK`Ql{ÂÂ{{º¦ŽUMþ ¾Ì[öü¹æ5V­bÍò¨‚eFª¢áwÍJì3Rã_fh?jÕ=Zˆ+žú~sˆSg6›JT³ÇÖ9Aü­Ž_XŒþ©•Ž_ÌùóŒ>§.;ÖíÞ}/ç’ñgßq}äú굃‡ZWtÚÁV݈šçö:á‰5ñ(pSÌeðCÍbÇm–fF¶FæÇPö.¿ñŸ,üWþeöG…œ õ bÀ †ÿ¯nXšà5 eîĉžûGmŸÐæ’ÆbÌè)‡Î¨¯|+Tâ3ãÛý›báþî üü »4økK¸dXgU>¾·C'kÞ a”Õ.vÅ 7ܦg‰u³ÔíYÓ_"ÙqÌ8ü¥cóÇçÙUS6D{å~ž«P¹6E 3ßNúEÀ{Ï òKB¯Ztí<—rOW¶6s WèÛ¡Å3{ù¦…ÙOaI¬¸Ï)«´ç]¬‘ŠsLšo‘{ý»«œ—ÄVÄeVZ/ ðŽ¿µÓ0g_œ¦b{ëa±êÍqGÝSÀÏ3ñ5çå[†ì'ÿ ¦”ÁâÌ%áeÖ U˜q¤î粈3äÊ÷êé¤:ýÍ[“„ø¯‡V ±¿ó™©~.¨ŸçU½ð%0ûÇøïÙ³!+)ވ͗­²])êV×쮘édüï]Ó^t&@2G½‡„¿èãºì`á-ñ}Ç´ìLO+`{ºŽèxìÕnC 3kWŒ£‚ýWðg`ù¿¦vÅD;Ù-Òß/4Ø`0üy°ž“0…™<«ú³ Àÿ`Ĺ€Ç\íoÏo½^âøå™ò› /5ÖüjAw†ÔvóÇ@­`Ù~:]ïDz#9bMÊna¹—?s¢ŒL6ß.uܘä)õkVwÞ›kO³|ò¡¶÷å Û™òŽøíZ‰ïY.×7ªeÜ[¥;\Þw"áU¶×´±Ø¶Mygšœö8ŒÉ] àÕ¯`õ޾«8d4pÏs–ôŽT'‰»Bý{GŽs?™~%ü¸XçcX„šÔÞÄs ÐI-ÜJ5hæñ õ»B¼q™T?âl',,°œ:ƒÀQ2³;2+X¿·ÇôQÚÓõ1w31sžFÉÉpcLé*¼d¼fgw¦“B‡P­œ\MUhŒž>èÈBüc@høõys6,CûÎÕ\Ž#Îlì¬\éÝ™×gÑãï¬lãÙÁ“Òîºêú; Ý†D"1'tD’J V>ôœîÄ.$8ìøy‰SÒ¡Uɺ­—lXΘܕB­Ý“xM½ ïïÂXsÜõ¸¥6_™Ê;ß#0|9±'¬Wb鲦}1‡*Ž`Î)§¸-|à¥øêØ¦j—Ý×=9C#T-úió—톊Q&¢N’Qþõ³|/˜¹›fÜ7Y¦ù©pýìÃoZ7MsêV~+ú¬WL÷Ú¤nMæÊ¢7Ò«ü‰Çi,Ú@(ëéSõcÙ„Â7É'›ó´ÌŸùî,YÞš5£ÞÄÖ­ÄS‘‹@¯¸n—{mÇÛù²Õ6ü¼Ó?ÌdŸÎf–ócüzµ$gò§ÜÖé¿›¡ã=ߥ CÁÿãNM0Füáå1Ž$ü‰š ‘ÙøÏ’•†{AÛÐL±à—Ÿë…\$í Œö5qpw³c¬¹€ÿüZþש%䚦…†ùxü'È\@„2ÀË0‘ã}5úÏ ýþ, ×2Ú\À[×´–¢^ȸêoöÖìí°\¶¤úbb@&Ó^e;Õ‹¥ó r6rߟ®àë†YÍë.]ȧ[¯úHo,f»Û¾÷U¸ójÝ„Km°?5}YäD Nä>Õ°t·¯é! Í8™rà@AÊܰùæ{Ý9Ωݛæ K]š³çpó[T²-á;Èî¬tvU’jšõU¨¸FÖ«­‘ºÿþ”‚akÓšOé»ó±L<ØrÍàß,èwfÆ­ˆýÇól†;]™”g}yòi(ôÄËáõÊÍF+혃lRÓˆwŸ;;­sìñ½g½sõ‚lËC\gÒýwµÄæÈ‰{Úèš½àY§…´Ù‚©+æÆn©t7Žã]Ñb3µøžòmýhwµG í«©˜@µtLÍÎ|™ªb\U§ˆÑCKWÞ’-‹7×/=¯Z³cΘM3ëZÔ‡Úañ€ÞæYì‡f.{sæ½ÎÇ7[.8>˜`ü£äÌzuwwòdFª(ó‹–_qtpýÆ… ¾×7µ”®<â]m1oifÏ€Ëö:åy¯¦Q‹ÃR=xSú³ÆKf½ŸàÅ•>·Ë[¤êóœà6Žcë,t(øO•J¾%:ÀV+šN¿%VWª0¥V­ðÙÏî q°Cj¨PÏBì~ë{œZ™9 © à?‚?£ËÿÞëªírŽ%üž 8 e¸‰_ú‡®M· Ã0Ï•¯6¦ Š­ÓP~Ð6ÍÍûžwÛê­•¹y47Ê›·5>l9tr^Ï ’â9¬ë²~£¥ûž­Ž<_”j¾dðÌ‚)åé*øcBè«|å§¥V]Ysþ¬ÉÛ…,Cnî “‹dO)¿z#ÿFðÙÓ‡GY2T7é³/½Ep>9Ç.²2á>ËžÛ}8]=J¶(Ó²ìþR•+=Ôÿù¤ÝŠtÙõ ÈÉÇ~N<8"‡IÚñ)°»ßý^¸´Å…¶üª¹iÚ;*Š—ÙÄŽ¾RÚÑœ/ðüR} :w){dò`NrMõûƒwS·^㬿)ÞS\§¶ü<Ëîðí÷¾ŒXÍ·æ ÎaO¨ÞDŸ»d{:0(®r-^mm»Ñ¢[lØãd·ýÓ÷ î[ͦxÞËe±·s¨ÁÚäµe‘,ê•^ûå}:±Û³? Hž69yÇúÉ—‹6¥\Ûcç†?™£eϯß3;à†º¼­Ô©B{†j»|7­nrùÔ~Ä÷ÞFG)GÿÀP_Ÿð ˆ`W >8PÔ!^ºo°?oÕNìôsU¬Ìù39_[ÐqÜ[à\×T)Ú("6 Ë‚Ã6Gêì=:sOV:߬ÈiO71·nʈ0äµq3¼ÔRøèÎÞm'Øš“§7Ȉ£Ñ |:aïK6¬Õ/y¼|ñy¶²>̧msbùçqû]d¸y«¹zÿ„âOhNÊHɉ»wc¦òNq®ÛcD³·yK–ÅÔšË<¿k´:if®žÞ#§2>ía•Gyž¯çºóâÝ»í'z³Ö¼)•Àü÷áK¨»­oíV:¨=àåIwK¦à_ï´Ì¿¶„[š‹„ÿíî ýÂ+ùBÓ˪;u×°¢ZYšÜ5é+jYY¹`lh.àÆ—'¿PŸÐà€`Ïÿ÷sq4?q.ûäÿ!í§€? ÔÂIa¦Ö‰!ÀÚåÎí]*ûJt‰%Í*ÉfçÖ°æ•ß–Ü&vkƒTêðˆmíÈ•òa!%ÖŽÑ –ÉæºÓY‘þKoæÎ®ë±m»àZ·—sÅÚmkùÀó¼;>äYÎôµ8žø°³Q)nÕ3uÖ'g£Ÿeù¹)T>¾ß•­ý®.íS¿ÄËå>N_®NÇԭȦÙ**Ÿ™N‡eÁ®§2ø®‹‰›×^½Æò ~k<y®¢·æ¡ö%rômN\|7z«|ìQÂ}‰Ú=>·Û`Yƒ/ÇÇt›õ&«ç¯­_—xHÒ•,rÕ3êÚS-&ýáú"‰ôÅ:A﬒ßîÚÈâç÷/í˜Q~–B³žWªõØéØß»d}޵‚írÓÒá” ¹^7ó¶Åést¯ê'ŸçGMÕ”9‘pèN«+ßkþþco .9½+ë8Áy “|èžÙÀ=y×*å°šK¦ŸÌ.ÖÞ±'ZÜxðY-a›‡}Vø±TǨàc Spȉ麵µúÊ{ Gø-Uû3¯nN”I×-Û—ÕÙÿÅlþÑ'óïlŠÊ1•ŸÂ>¥B-XÅ·zýÅþEs£cEbÅzÌÛWÁ£TÏîyÉä®êž};ðqtÅÝjJ>8ù†_™«‡ª¨×ÒYúdA¬¯ç›¹Â¹QÎŽR)N‡ÿÇúºEœ-fÁµïìWϨH“o’d‰Ò‰2Ûé%¿KmË…KY\ªoN­ˆßzÊSŒ©Uâ]µ¶;^lfø‚©ŸàOLâQ|:cÕiϧör^i7ÓeÁÐZ þŸˆÅ¶*ÚpÚ@ø7ŽíŸkùøzX÷¾ûÑš.@¼ï¦×óü1ZGöX«[¶¶ñð°ÆüÆ"ñÿ7È¿j¼„›kâq\¤W˜¿ŽQðÿ§Ú„ÎtÇOÆÒ?tíçSýÿ·c%‚³¦ ¬3ì[aq‘ÝŸES?õìšv×·â ;Gá¢C*Š"ƒ×ï»àTFrOyË/­:)öyÙ–lÀšNå#»tâ*OéÝ’:$ýr‘FJ+Ëšš™qluRl»âÝ•"œLX úø=Óz#Ému¢žÓˆùzl£÷¶­J#= g®`Z6mý´ä¼Ï¨—B‘»§H¿ÌšqØ03Ìe3nÕÖ°(|¼et«Èî­Ââzâ3ÆtÓØŒ oG%°›¡×Jz¾·ÎÜy@Û—YBìâí ꥗ N LU Ìq‘òº¯ Æ›º„­Rl!¦\Eüè­„V—:Z¿Í­,›¡yá£}ç–­Ç=¥ü!îf‘×a‹³c¹€ð×\UfÞÉÖ´¬W²ÜÔìíÒ°Ûb¸^¸ZXîÛ§adfcïéÌ(sÿøÿ;ä_×=^ÿ„i¼O¤_(á÷\À‰[x2‹ÿÈm‚޶ƒ$ÂoJl?ñaû®…kÚ?ðzøLÍ,¯Óéˆ^Êu*uÌÊpözý û3ýÎÛ‹4”òÕRo¯6½ˆÊð/ÿœjÃUÎ’2OÄ ±ã¼Ìb ³5§ñÌ¡¯?¯¶JÝÎÿbJãûlE™ö˜f¾âuÌMìñœ/;smí?eì]a²ÎsùC…× Í<“ãϸòYÈ+•q?ÆÉ‹Í—âh“=›kFh‡e<áR}Þ<ÿ}¾V—ÉAO¯o;jµG_йuÛPM{ŸÖ´ÎËšºzã˜t91c™ý3.´û®SyÖ™€Ç¶§¤Ï¨É‘xxylŠ{Z²q¡ê`hûå÷nU¹†Áýõ鱋L_½a[´ù™(Ø=œzÈ”£KsSck’ ‹wc×ÀÜœÌ[k•Ë’|•ÔžÌ2\Z3¼sš/³£´yŽiU Á4»l«üaÅ,¯-™ÍžUÕ®5™n*€ŸòÁ%Ìo¯‚^jß¹žZÂö{aë• W}r™£è¶Þ"Gÿ 6* ôcIàçs{^o¨0hn-Wàð–f}1–švlu…Sc.ŸD®@¯‰Ç1g-§Në»\#ËÒÔ[Øg‰úño޵¯ ⫊VÜc³,ç™ÍR!ÉS{î..Ùç(öNrÅÖS|Ø%O·dg í”ôc‰{+æòbãê÷êÏÔæ¶ yœ©üWÌ2Sxm ‹*й¯–]ïà›&ÚÆîg lø\†ºôNðfdz»ñú/ÕûV%Šu9æ­>Àq/§^msѳ­àúP¥9Þ?ÅFM›ÂÎ/³?Ï‹_(•ì?âëôŽŠÿ9pªUý“;Ë ™$Iø_¹¿6x™de™—òšk§”ŽÚúúv¿œâŒÖW׳4Ö:blj팶cŒ¹€ÿ üÿ%ò?{·ëëtû,ïðÐÀ Ä€þ±6Ae€ÇäÍý£žã§€ÿPC 2ÐÓÝíx^“?ÿËYf%¶aÃ9–ô, 4ÇE(8Ó“\=¯QñíÕ|¶‚±áe=‘ûN†g½ ®n—v» vÇÈä ÞùÂr÷æé1.¼ötÛ##ùúâŠOѳ‡"ŒŸŸŸÿ w„ðh ÓQ£{Kà¶ðwŽ)œ7%? º½¶hE{™8V'TÞãlí±þ4cç…ôE—Ë4Þ× m}|È|]U†è:µbDxï–pc¦“uÁsÝ>74°L“”ô L“‚½ƒÂœ¡ À Ý=_ZNT¼rÏivk€ø«ðOÛÚ Vœ>UÝ~sÕµOO“«Tù[{°ùŸ.H[ûÙ$dAÜz¿tÌ!@ìÓAñǶÕ+XŸñó§%)îØ¡soK'N°kËÞ"‡ü=®ç©Ÿè#œÄµ,ÒIôî—xUðø¬ÐüáhžDn.gàÀŠ©€5_wâQBiM¯™[¼ÆÝ=—ø[»¸s°â.ÍP¶UsK—}Â9, ª3MŸ®Z`w†íÎÐþ9•ËkïÅÆk»Uñ8/qvö3üý}^§²½{¬àZ¾»3?R|'º?{h}>ñ=ƒy·šCU“ÒÃIø_Ÿ· Ëu»ÂDO$®ÌÍm櫘P:¯›ejd°o¯ó!c3k7Œ%#‚ýðÿ÷È?Ñ4 ~Q¶St _p#Èÿ?Ú, K þÝ2Oì/°¢°Øïÿ ”üÓ §3¾a£ñÃuÄ;×n¾Óú¹±R—/ÏÈûÊ3mcª:›kz{z}í`pþµ£Cwó®ÉJlñ21Œj+É:%¿ìB;Ûåû “Î=|s¤ÖRÝhþ>6ûLɶݑ±#¹©UÜ…¥ GʬdæÏ:$ìõlÚ‹­’?î­KbJ)<ÏtÐj÷ÜÍOæ†ÅpJ0K¾MB-:cØ<¼­T-zЕIƒÐ›“mºdÍÎÓ­ï¦+™ÉœšõæÃ,ýFï›.G…«dü³÷7D_Í>¡íØË‡ÍŒÜ¼Ü<£æ‘`™ßËöy«ùzsM ò§œZÙ-õê­„ŸÊ’O~ÃScDµæ)„sò¥è­?|ûülVëÆ–Þy«JýÖŽšÏžbøî‘¿›Z`ˆe»@J˜îs®³q1%S—FK[g¸v›W+µ{mv؉ÍÓøÖyËÎ ˜“¢ëWëxjkºÐ²æû#V¦W_©„ ÞÓã]qÕ#kYÁƒF~ýu+íÄ]R£ÃRn¡á Ì0¼v<[Ã}ìœÖ{þöF-Áâò–$ãEøŸ›÷1Iq¦‰Y2ù— ÞZpj¶ë-¾„4ƒW7–¾><åsð²ké«ÊŽW©$åWÏÌnz“Õð&c³óÈL÷-åÂ1SxúºœãWO1ÇΗOL}¾‘Ë¡»i—¥¡@º@ûfäºþ¬e}#oZl7ümüçö/Í”Zãæ—W‘ZÞ‘z*D£\·~\Uc–å“—%2#š.5\–Ê®\›6Ï ^ߨ ÄdÍí‘Zؼät×îrùwÒcGsfýÿ5Q7z_¢æ^Z%ãøþjBÎmO‘CTüã’,N EéG]Ðo'á¿©4læ9áÔ«ÉŽJ›¯k¸š½ì,šÂ]ÐFÊvGL 5¬õlŽº»2À\Àÿþÿ.ùßäž@ô öf€¹€E“ ÄÞMjåD}’¿ñó¿ýÆ® ºž‰o…D‹AøO½rJS€ ý6t €à ¼‰'GF,Äã¡AÒ8†£¼`P€¤œ:†ôŽÅà ð (w >!<ô´é\¤QáAqðÈÐHCá£áÿ.…t0à ” L z°J>‚ $÷°8 O‡ôB>͸{CKy…ÆBßÚAú.`Á’¾z#]-銱ð×'¬IhyDú‡™Ò£ÐÙ¯s>þä»L»3€ñ_óÐ>KÂïÿ ðwñ!âIÿÃQJÒCNRŸGäQàå8 üáÇ÷]üÉ—Ô½þ8H'âßà£í„ßãÿ+ðÿ-ÿÿ{»ö+NòkÀÄ›ÿ¿EÆSFeWÐPü€}:c}7˜À‚G·  ñF H]H޳øs@ޤ ãîAô# 4ƒ,$…Ú?!I¦lâ4@Àá)BIÒë$1¥C: V”’^1îÞ,¡ €ÁÓtˆ¡…™°xj‡D\x¹zzeO5äP¾RJXÑ x:Kº8bI„Ä’.‹¾VŒªòÑ”øYÏQkº'œNÛã`]OéÕ"éŽÀwð›q¨ŸÃx¸ûN>þh/†$Ÿœ>þ4Ùìã))¹tü!þdj@þ'<‚ÿø£©/´ŒëüÆÿ·ü3bû%öÿ—0€?HÑOô ŽmÐ=ŒÉŠqŒˆ8þ4”HÛ …©Ó`–€‡4-@åäG {Øý¢Ù}€ê'¡=Üý|ñå$áÆ4Á';…€h\ ï…©{ȧƒ!’64rÍ`Â× ’@íA¯4ùG\D¨Á—ù3Õ/¨×HQöHµ ëXß‘¤ºù€ޤÏHȈÁåJàUXþßUÚH£»…Ù®â°("e oRöЃi=€„Ð$ãï„Øk|Èù¢ TÈ=øF¾& òßÃÒ%¿Àøã¨Fâ;ÆŸrsèÞ~ãÿ[þ¯ý"ûÿ Àd¸ÿ?õOoÜSÀˆ  ˆ$3hH }Aq4'dõFÕœÐn  ‚Po¼ñ§ à¨éÒÚíçh˜tSãmd €*},ˆÇ ‰xª€„ ‹'K%<6Õ½OXA€,Þ0ý§jrÐâÉ=q90 7U^¿vê :íŽ$A`ŽBº>ø¯ˆBe¸þˆ—7ê“MîP}BšÏá+F,†€§»=”£¿©‡!=eî€ÿ¤âzÁ±(NDA‰*<ŽNsÃ[d§Žÿ'D“øCüÉÿ¿MM‚ѱ„¯ƒÇÈcxðÂÿ·üÿ…öËìÿd€Iqÿq›0z H,š@‰›ÒÕ€ˆ°“wÐü!=‹Á!É!Òû@´4ÕþÓø4€õôü …rw8ð›Ð,÷éATGNâ û!Ù%©oD}ƒp  Ò ¤ §'(A@ãh ¥)ñ?Ê#C:äÏ5Žò Q{ùjð`ˆvI_ .&ˆ'g ¡óbj ð_á\† "„?ò0› ÆÛ¦(v, ÿï ]™ÒÃxz&×*0}Åp1ä‚jÐGé"/h,úÇø“ÍÒWfÆŸ^ønüŸr×èÞãÿ[þ¬ý:û?É `rÜÿŸóŠ?UõÏØ!€bä±h/<-ÅÿMá½ñ§lb

xð;ŸÎî#"€p) ==¼|¨z€êQ UÀ²ñk„r£j IÔõð¦×»däB€&"u?$’k):‹ô£ëRz¤Ca¹² ¿$›…¯)‚‚€”SÙLRp}ü·¸…ˆ#„à?.d;î°ñN¼ãÂø{Ía?"€ñðð›,ü]½ˆ”G–ê!PŽŸÜ…R•ì¾&îÇøãè7©4€’þQÄ€î–пÿÆÿ·ü3Tû•ö2Àd¹ÿ?'Šà9€Ìÿ€H9–€gü)¹6Š?®€t8O"òx%J# ÔcÆ‘|$±çéêè âð4ý@ÙCð!º"Ð8 ï÷ÄÉü‘W7?Ï h,ÖÕŸüÄ„X>‚Aª3@­ÿ¥T *ë¥ÔSk‘h1G &Ã%ðÄcpH²™¬HŠv#Ò6¹ è[“À` ¢²1X"~œæ¯Ãi ¹ X püGÆu¿µ$üC'O?*…“°—G Ï A$Ï cKÎ@…`?ŸVFóô)øðT@u¿iãÀoü' ÿßòÿ—Ú¯µÿ“Ç&Ëýÿƒ¡ÿÿ 0(¢zGpY?]üŸ&bHªŒÎøc±„ERÈ4@J„€ê”p…CÇx´;&À èÏ ÌQØO d‰ƒ¢h åE@rÐÿ<½Éõµ¤+ÀR€½?5ÛGb½è½ú¹@XJ(Úƒ§ô`ð 99Þ©ƒk€qt7øÁ{ ( ´É ’¾Ü#Çà0–(DÞ ãÿuü÷;¹_¨Á1ßµßm¤Ï‘ðÇNþŽxJú˜Ì/²O[,žr25&#LI À¥\? Þz¿‡NÀÓXÁ¿‘üWðÿ-ÿ­ýjû?I`ÍÿÏC !ÀP ˜J£AJY?´1>þO›‹4i–ÂÑ”Ú)ªÅ§1 a¦ˆR4ˆõôý X-Õ¿B›œªÈ…»Ê“u Ê›¬0pžDö´¿¾#ã:¿ñŸxüËÿ_k¿ÜþO ø©‰ž€Ñ2øŸ% ʊȶŸœÓ‡Ò€ôÉÊš M—É14fÇx<ŽÎâ“gP õƒ!¡A{zxû’«§êŽ,퉦¦XÙ‹‰ð…Âqä©[45ìH•iÒÁ@GƒT @.‚­˜ ‘Z1 ¹šw\G]„Ƅƥœ†ãd3›<¤  I70º pyœ¿‡àOÓýãrÁÙõ£+ø†d •ï}dü?1r€Âß‚ñw ‚¼-ZŽ : › ˆC²t\@NG> üÿ¯Kq8õÔÐ\0ÚndÏwB”½Œøàÿ[þÿbûìÿ$0€Étÿÿhø¿`P„H*e~?#’i5½ñ§è>Ȇӧ`)ÀB‚j*+   = ^5 aX´‡{ 7RÅž<å˜:ÃÿB£Af„v`QЩ18uh¼øiÛô¦¢@ö>°ò\ dC‰ÿáÈ‘DÙy ˆ< ¯éõuK-"‡A:•E#‰CK@›Ð‚ˆ?qF ñ_Ú}@^à8ߢü‘Gˆè”!´ÁÜѸqN ¬¯ÑÕð÷™Pü½¼q”EZÈ…Ú"m. ñÿ(âèzp—œøþôSÂéÂüäËGýJvÿ¢$ÀÿßòÿÛ?bÿqÜ'n´I¶ÿσãÈkýÀÆG"­hx5 Š…'Ë"œõÇྉõÃÉJr4}ˆ”üè£A¥¿(¨ ‡£VeQt3–¼æíî Oþ…•5’ôô±DDîq”äreN ÂU ü¥¹@HΪŠ`]€ôh+’ÈpÐùs )@Wêâiß‹E–D%ÀÑKH@aD,¤”ßsDÐÇá]˜öØÏéc½äû íAjÇ~Ò4H÷;_(( ‚<ìéS¨(dìÉ=èGv?Å¿1ûtñah,Úê‚_¥èï¸÷ßøÿ–ÿ¾ýCöbC“ìþÿÑ þR €AÀøø?,‰XdI`ÌÇ);°0˧I<§êôÀ;´€Á¸å€@Z‘…EÃRãá úqÔIZ°ÌA®üŽq „ )5´‡7&ýžñôÅ“)?9‡‹|Ì,œ2÷‡ y¹/d.ÐW‘zÚwƒ6ðx ¡­îFUä \Œ#D€´ÕH±°j„Ò‚ ¢uB1Р:ÁŒëŒÿÂïTüé”?ª ýÊ݃õûwãÆnÅpÐ>AÂßk¢ð· 'PŒ;ÅÃ+Ä@3^ €Rñÿ å¶È1àOW8žÞ’¹óo øŸÀÿ·üÿåöOÙÿ‰d“nþ'ŒàÆs`ň¨RÂüÔ2pœñ‡í;­ÊŸ®ÖŸ"ƒ³û_/Hž*ý, m5 +@¡Ü}}Ú@ÀëgCçG¹ûù j$n@‘Y€g#õ¿4 €r÷ÇÑ"dg…ï%aÉ" H‹ÿÑ–Ç‘õ–²¾çxy…W¡°$j ÒÂÃÐ$aè#Èÿà¥@à:`,4*äÑ µËŒXT8.ÅKî‘W]¡îñ§Nîüæy‡ÓÀP|÷»É_r|ø+ÛÂià€‰ÁíÁÏHÆŸbU`מRÀ Ÿ†2ˉ|jüOñG‰§gPº™ H&¿ß7þÈí¥ÿÿoùÿ‡Û?gÿ'ŒÃ"þÎ9þ<øêøÇ@1ŽìÁ†›ÂÆ¡Õý¨0H€Á¯¦øQ´ ޶à?™ M›ñ‡¨_Y[J¦)d*@yzzQjiÈ©?Hv=оPùU/´C\•Œ¬  ˆòZ`XòÂn ]þ«ûOåõp:š@§hõ¿t?B¤MäBV÷¢¤G~ï‹Àq ¹L Ö6ìäÀ ¡CŒ+hBŽ‚¤¯öŸc ðMünX²¶ƒøÕŒmj£:yþߌ@øÓþ=ÎðGOþŽòƒI Ù’ûˆï§si¿ ˆ£ûM,øsüq4witb [˜¬þ8ðÿ‰Àÿ·üÿõöOÚÿ "¿ÀýÿÓüÕÀ?N¾ŽÿÃJ„Ó€x¸ –œõ£®Ò…£…ù©å~ˆ©'I"¨tI8›Hç0‘‡€)i?å eÚpìf®"e60€q ò&¹Ph60Y !À ãG£ÿd ÐDÊ„ÐÞt Bú¥À)z ü‚!Eañ´Š1z@IÂk}P]@(AHRšžº “Ë€¾÷³`ÿ¸¸LÓ“ÔÐ,LÏà40ä>‘³¾À·jŸÞÓƒÞ¡Yát;Ú0¸o@>G üÛøƒðÜ?Ú¯Á‘þ‡&?‰€ö¢.ÿKWõOûKxÅ™Ÿâ£V¸P_qô!ÈhàTÚñÇ!C$þ øÿ–ÿ¿ÞþVŸýð0èDxœí]\MýÿO ‘ÕJJe„h ”†–öÒÞ{ß{ϹçŽöÒPš2J"’‘´¬B2’”Ì" Jýï9ç®<Ïcþ~õøý}_ÜÎß÷÷³?ŸïaÁkqD"üÊ%€`2ñ?õ8_» }m7øÕ½_Œþ‚ àña¿òT¿Ü^;Ya8äôÚDÞï’8RgnôÔ/dU°Äœµ¢vå¼Þþ• Mµ½Ì`ç ™;ûQ@r¼òaaÎ韨¾[äGzÃs°#ûW~”UÝþ¹È\8= sës<ü°dÀàÍ‚Á£I‚QŠuufž'Õ– ÍÅ:œuÖÅ «<.I[÷*[YrUØ `ƒi³ƒ×ÄÂþ>ñÉçÒò®¯æŽçR_¨°îךlñÈŒîgï^¯{´DTq™”ôµžˆ‰™‹—Šª˜u³R1Já­;Ь£R,eg©öä Ï"£Åw¤åj6¦%c> ®Ø“èš³#8øÝ“ôšKŠs]î[&.éÉÙÅ–Ö2,uµåRšžŒ¿â§¸–ã Na›<ùöLœþp[Ô¡ÎcÅ 2=µ8fç.¿«$~™à”â![À"¶&þƒ‹œrgsêÀ¼â¥évï/¾ÞtÖzf}Êìîzñ …ˆ†ßã¹!ÄI;SæÌ° ¿«L1º5RßyÐú°Ó4‰ˆÇBøãŠÿI1®ŒbµmqÓÅU^ö ×¹êO¶ÞÉT“N(¾,.¸`öêVÌëÓoÖõ>|(ò$F¨'~ëQÅ¡²„ÓìW5×Äé\í´ª])Ý¿´îôæ<ùãIj—5÷9èÞj« ü|ø†à–O®›­bäÁOü<>]\ìƒø}æÛ÷z)™h2ÒZ¼þã/âï7ÝrÎLêÁ³]¥%Ò¥eÍ“¼oÝl™piiÑaw›{ƒr<Ó^SrIm±üqVÖ)U»ìåw=W©Ù«~àè"¹6÷Åýbƒ¾'öëø·Eq¿Ï÷_5ܼþ¶ G(æYš²ìk%µ23ž9¶Ò0þï„bgäðiæfž X´ón¨—³+)L'ûÄâW¼á&vŽV¶®žOðþ¿ŠÿïFÿÙ˜V±áñ‘Ña± ?Îø{°XˆDúéùE „BÿsOóÏ ¿®¥üŒ@¹(_ ÀÙ¯Àt9ôðrÅrŸ²Õ{îo³,‘ÝX¶ì ÷þ˜HOßuº½X÷±®÷í×– žYlFn.µÊÔÞÓ”_%ë˜-v „t°ŸÅ!Y–·ºðÔ¡sFWÂ'öp–jpö‰Fá­ZnxŸXÓTíæ~|‰\Yêpï»3ÕéøÁ{‡e¦év¬ä5µöcÓó‹x$ʺõ‰¸föZ-“* ©îN 'Å×Næ½|8½TIªè\ï­ýZÑQi¼¦=Ë<¬æÆ¨sÕhâ æ¶eÏŸxwå²»Êt:·Exrî”)þµ&w§9qäÕ kÈÚЕQÜ4[ö¶Ýʤ´éËMä­EíûNøïdÁ…­ÛÄ’¿R˜¿„UavzǹèÏsÛ¶Oß[Jôq •í¶ÞRY¬e£_ÎEä¼”åNJ´[Uój3{ò'›Í!Üf’Ý9¸Ü¯šß“Hžbyª}hºîÆYUbk'\_{èæb±€rîHýÓ^ŸŽš®»Üí9©CfË–é.ú{¼è§eãc£ƒ€ñÕÌ‚9;ñ…‡gµßžY³¥Û׸C£|ˆQ¤^I³ãPÿ4I­ £6¢·käPÔ¢½‡ ¼± - 3ºvÞð,kRNgû¼¿+8’s¦Kˆü%µ¤¶·b­½çO¨tÎð÷K¨?#þrå ΂¥Õ²¹Àæ=•Jçwžpf š8àS|ó—ð?0PŽß/áw¡H¤[åc»@êáK…bRÖkz[Ü0oÄ.Ž›?!¥Jo_KÈÓéÒ;Ïȼ¼}-F½Ù`[ƒÛšŒi-ιfç3ÙŸ®ú:þâ Ú(uôUGúæ¾M 0^^±ÿV—§Bü\`ü•'/ºÄî-ì[ug½pè-7¼q0àãw}A²ÓöH;í†&öN~8çÀñ•ÿøÿvôïjä›í°'9**:&ø¯à°8ˆLúÙ³±Ø_r|wñ_—ð?¤àQ€¢8üxje–ÇÖÇä—ï$ØÆß××yÁ)nKêî„©jJþ’õªR6ž½Ð¤ÂÛœ~¨0œsk2èyèã û„F'‹¸íÛÓ6¾%÷¸u˜ÛÚ.éꆗ¬Z]·î&~ .Èà{›³¨Wº¡æ"°jîÄåÆñÞ}”1±›”p«òs—gïŽæÇ…¥ нÝ[µN<¸ú„½¨Ã“í»u¤ÐgƒnE–O»£= |•ñª»d‡ K–®›Ô4©èƒ_‹R[™uT‘÷ÎsX‚—æ¶¡iK»n(<ÞXѾåuû,Ù‡!’|ûE>Ƹã¹V¯+YÐÀ%¡­‰ÇÙDòšx=Ùw±Ô|Þ¾Ggw9»ª¶x›îwâ²ñ`Ð|ÙrßÙ ‡ö-ÊUSIñŽâ[7ã É©Ñ߉çÐÛ@¾wræzƒò<%3Ö`›üã"N]>wÇf¾‡Ëúí%&špÖÃ>i|>”Pï¹åØf‚ÖÅi¼Ÿy –FaÏm*H.Åw¬Ë©»}{Ç #²m™G¾kBrX4žÀþš[²A„lžSí›4±î­+*ÏMo‹ú° à Åúùz‹î]Pœ4Ñ2K¾È"_dÑòC]ën®ˆ äŽ[Í¢Ç2!B䉳@Ý Mò‰®…B5r÷œÜ°ƒÑoŽÌŸù–tíÍãŽOêeÏÏç_Ô¯×ó&]• H êªÞaŽÍ\ya2ö¸­öÑîón†½?ÿ˺Åoç&–dÈéN—°æyã9CYꢱoñ† ¾«åYñ™Æ¸ a¶;F¹ ¶i¤îؤ›äº±kñþ¥Ê­3‹ŸlÓØ7sD¢£rÊu]¨Ú×ñ?<Ýò“)°"t2o£¼\·Í“‚ : üq¬‚õÀ½gÕ`üý|ø—öÝ òÎ=}zîÚY «#™¸3ç Ôëj®ÊŽö¦FÎVÖž.¸?øÿ þ¿#ýï×0&x…’¡ØØ0Šøÿ^ÀDÒO:ñ !ÿÙ‡ùÇöÀ* í0®A~ñöcé¢+´ÏÙV¿c×µË ,ª¬BãŠ.^Û¶´ümØÜýnåBÓÍWr¤¥w„6;ÔVspΞ:'$BäHá³ä¼ñŸë÷5¨¯]þñ˜ÎL›éӌܖ½¸Wñ¨ÓeiÅ”K-*Ÿøô̺ì탼¯ªcCö„Ùxä:xh˜C:²_ù’NÎiOÿÝ&ó‹Û sŽrt5K8Õ9 _»¸H¾Üw¸•jЀœwþñ‡ž©—9-ú(¹›pCnÆ>ÃŽyÞö(Žáû ó•çZ-#²¬÷ÄY“­±µÄÜö¦ª(¥]6#ÕO]îŸÚÅ{7Í[_œØ_b(sþŠà-Õ97Ö¿zoû(ÕçSû5åÁÛPcö¶Õ¹OŒOjÕ;NÞùLƒ‹ï>× ïáCNùÜ8꽤MwãT¶‡ÆÜö«»ƒúû' §u\óô¯?ëd«LYŶŸÿ°p_²ïa±ÅQÏ|E$ï%åÝÊ-´4ò2¤˜Nª!Rl¾âžSk»å&n–5‚ÌNz'÷E`ñ „ñcéj%ë¶Û¥>蟷ësÎÌSî ŸªŽ¨¤rK;.~o{í҈ׅ ±¢å=§& ñ®¿-£xšÓ”Â-•Ò±öD’ `ÚÓ!3Áî>[ô§üO Vz–·?šVþ&Œýe¸™åë»’ì,˜—üýSI#ݧ%4?•ž9O:‰ô€=Ñ,Ç~Iæó—¢OgduþYü—¬:[w:àŽdx²ú$ÒU¡õbÀ;óYC¹œnF¶Tqu:Ýʱcº¬â£ÃŸ;9?T 4Çj/:îœ*õÙ’k3~^éì‘+Kw±ÿ„àø wBùùÛ?ÇN¸$¢0tè´ÖtþU5[Ò7D—Ö–Âøó$…5ZTXÊø^½ NqÉL‹¶ vöÁ—ˆ¥zíòp°Øè´ÓÑÒÑ3ØÛsƒ¿=þ¿%ýCfÀÎCži¡!‘1Äàÿ÷ Àϧ¡¿;ø¡ö­ÀOy4€q x†qÏ~µ½”¿'Ih;çۢ癇]í}iOïB<ø\rhËà ‹Ë–ÁºbÛYDMÞ‚ÿ03ø¾¨o£Wýöã~‘&v>GoÆ °K&¯åŠë]ËvxïHwIx‡ŽjqTŠvù³ù¡Ø£ƒ¬ˤN½p•=¹¾¤h¢·sÃfR¬‹ºÙŒë¯ +û€÷—õÒäÏ{¾ܸۤp…Be/ûËUÂÕ “¥œØn ^ 'ö™yÛ®Ÿ*Ù¸þþõÊõþùØ µKäbjM}OŒ›¡èÔwQÖG(½®ÙaŠÿ†+øSÅíRbïYsÇ•)ݸwø‚˜î;Œ²‡öÜð÷6FR-aJ‹£:âVo´î]ób÷‚S+]½Ó¯y|\ÃÆûÆI¤„ 7Ô+ gqŠ ¤ ‡ê‹&]0ûX£)Z锣©Vú~qÙáÄþì’W§å–¯š½ÔFfù±îµ6EËf­Ÿüªi`†Æ¢¤çâÒj¬eáéª÷7ZÇûйzN ÛrûÌDÙ´j‰©ÐQ|Hhb 7nAK’Rá›C÷Gfv’D<·z?Ì–~Õ¾·;¢7ú‰ÉÜ–ãòw/°w µî:(2_zßšbU vuÕÞ•¦þE=é"ÏÃøï»?x&»¤”»cáKÅþˆÓ—Y%~è¨Ø5”ý&Æ6«X•¦ž[½6´µM›GŒ§“½b¥~b.7»0ÿ™áOßî«ÝW§7Qyèçð×™3랩䳣Éz*Gö§V×h-s³+Ú1ר×cÒª܉ͼ¾Ûåi]æÓǽÞ{,ÜÆTü^’®Æº^E“é“dØæ¥²Üùþk{›eÄmòè°¾²÷¢…¤v+ÿ­¹u üM,.uO¸#¿Á5Ë‘‚ËÌ*ÑÇû_•VƒúÒõHÙ9ºDXåůy9󘢷¢“½•®­³/ÖÍoÜ$ÀoÿoKÿ+Õö’²C#Ãc(ôÿÿ^€ÓÈÄå@0‘üßxœ¿mߊ|û€/§þá<ñÑ*tßXÝž[Ö®´ßÚQ.ïtò3‰€òÓµCŸŸ5P鼨ú£&±6ÕSnÖ¡79fn´›oßóÎBáô΄g¶]·™7}ÒtžuMíÓ¡äú¹Rž)˜ Ž ‹Ozp2÷̾ë†@ßý°-í¯^zªÕÔÕª§æóQûPëÖ¤È<ý,:=|3´Dçv*íº¡ò¨gò„ƒ³–;íó–ÍÙ¤¿‘O¸ñüëme5m Ö¿È(Ï:ݵòâõ—µž\ìb;x]sîBnãøG##ÇEìyß7´]Ñ.‹éü|êPãAEöFéîÀÂõ‘+DŒâ>y¨ÕÞɪPpÿöëž}ÉbKN¶™/).Ø-°îÒmGß§Yîo‡nNöT8û´X­¥~v j‡XðËÇ!ú3j®LÏa?ÒøN©%ËÛ?ÙjëÕõ=§JÕ7÷½žlý–O¹õæëS„)UØVbêõuºV)*WæJb=®SÈJ®9šàqê­œ‚ ÃëÃfå¦:BðÞD|vˆÿxìG¤\oÛX}U±‡}Š‹•ñë¼%]'f>㜶™5SØéRú‹‹ EóÖ7Ú’]·Nª\õPå`äÒf+ön·…rV“Ì´¬Zp5Jè¾¶ÑyíN– OŸñÒVìžîÈW¹BüîÔr±=%ïJžÚmƹZwöí‚ÜyâŽ'VGT<ÝÍ:[g0É"4ögðgiÏßkË«ïsð±¡Ø™LÓ®}WÏ9™¶Vä¤NqÕy«ô`Fåte¥¬$û'‘:¦^3ܪ7œÈíÚ¸tS÷íòÊÌ{¬¯8¬Ûu3¾¿È@BOÿÈ3'} ¶Ú[w%e[š¨œ@é|en?HæC»‚«Uɹ—|’Kûš*ÆžEÆNêÐäîûé­‚a%Þ,‰qF×tžÜÊTT>!Ù¤:#·Gt˵âŒZóÁãR6S>ÂòÝdÑl*gÑãä°Þ±%Cœ¨[Rt/Q†íÀÂ+¾˜ã‚ƒæ[‡.Q̹Ü\]{g™ÒÓð–‡ùõ<ô³xZj¬³Í/i™$²ë°Á;¨7:²äþ*c÷Ì)ì|™3m²>˜Õ”D§<âð‹œèrûx™™LµSÇâ·ÕùšUw3oÒY|A¾kJµä}¬h×Å—ïéE€in`¨Qwj㌢yË–…ìÙÊÿŽëØà%x‰å€ÇÓjLòÆá} Z¦ì¹¤¡2‰¹þW*wÖOX½hk@AnHƒ] óû›úÃnqÌÊ'®p/å Zkæ¬~L–çP"q•q…ÏŒ3?ymIo¾óù¼‰÷>¬½á±…ÕaBa!O<Çõç•yW3E ¶.b \R"ÃQ”ß1a{‰ó±PVòµ¼+¯ŠõÚ_om‹=Ýl+²Smg6—A ŸŸ–§rÑë@ŸÉo ùë^Ì=¡ðâÊõc;fØ?­hyû¼óe&WD¹÷œ„"É¥ÓÄ­:†ôEO oX újˆ[vwv«gЖ¾Në‹9ýbWGN×-™ÿ>Nqá¾~Ç™ÙÄ-3 LVÜ™z^9ñlr~òI=‡ãeRÀPlõ†i^OÊìò7:YŸÃá#I»wcƒÇ#`¦Ûšé¢øBñëݺ;<Æ5Àö—søŠŽt_q~]Ù 1|”êÕ}½±K®jnóY…3FõQYÇîNØ÷FžÛáÙ²àñ³Z—=YjïËd‹ŸO1½²}}–\fuJèݤ‘Ó·ù®¥øÏ Àíî‘I4¶Þ0ox@»(hýÁ!Û×jW0AÛ½‡¯8lýXxSjfæJöÃ?ŠOb7^â¾wœµè©²A–“­Ës«¨¬yÑ©­¿¹>Slyx [cý`è5ùæ•Ò¸ùâ7ï”fó‡,Ÿ,_á¿Â¡Ú«Ê¬ˆ¯IÉËödìòµ!ߟ\Ù¤¸bå3¹IÃzÓŸÏ#³œ^²F-‰?²àkÕ,žçw< ‡ñOi5HS¾m#t^™«ñd¦ëÚÍç³Ü]½ˆ7ŃnD7s[MëŽ6»œ}0ãR ø›ãÿ»ÓÿáNÎ9Äðˆ°˜hàO- €ÃâIÄH£Ú?zû¦àǦ Àx¤”‚RWx–¼Y·r²ÈÁºÆiƒKÛ BϯzUóV=f ÷Z±0[çöàò<émÙQÓœp$Nmo³çµzë“|6åi¬ú0kÅ"‚¨®Í`§#Iä-9¯æ¼xuísç\õj®W87YÍyY¦UÏý³=g}.ΛW8å‘ý«¢Y¼wÞ©ªÙ–Uùõ4]P{•~éè]M‹‰mum—ï‰ÍÜÓÄ#8㬽ç§Â…'ôy¤¦–¿ðÝõ0˜‹O¾7UµÌ¢ÁpË û³ÕWÚ‘Úˆ)é­l\e)åúÒŤ^šÌ»CGBÁË šî³sV µç{üQÿÙ¯ùDæ½çÞ>âpëFø¶·‰¢Ån@ ïBó.õÍ<6c–ËÚ‚•\ ¹óW ;´¿Lz|‹e·ÅnöÈ‘~€ ¾ìCŽlDÇöB.ƒ™AuîYI&jó–ð*¦?•ä[[\ÖJž£R¸Ä¾Ì}ÒE¢]PmˆJ‡þ§¸U³tLNm 6ÕÞ&»ˆ ޾LÚɾŸh]´½Ð+Ï7%"hÒìyw|:¼Íøæ"áöèÎyÕ&¦õ²%‹Wñí3ì•4[öRLI °MW]|0;£vëî¶,E‘ÊØYw\ÚXÖ¥.l³æç2á°Ö®jÐ×ÕÝ–D¨@kmÜ“ùÚÌLËê][Â#4ÑJþ–t—ÿÇç–ÇFrÅ“°ÔdLܺæ®ÐýÊ5=Â[ "Z³×c$Oδ¹0çrWËà_á.~Çφ8³É6rÒ-ד òœÖ“3&?®(ò»tÞ“x}ÃI©*[¾³ÎOÃR+dÙCר:{¾Á¾w9Fb$®Õ|L~±aöçî“™âßÄ_àåpôë÷eåO¬u{dÚ˜S¾«ÅéãÿÉ=¾ÏFÔOoeN„ñoâUc ÷àܧ¸‰&ÍûSù}®cpV8ÏL¼vÓÜÂmÎ>öNÛLu-mÝý1ãQ ø{ãÿÛÓÄ&0Ñ6Çl)14&êO- Àâðߟ€ÁQí½ýÜ`› ·úëIRI‡/Ìu íî¼|ÓzÝûLÿ¸U_áë?õ µ>d‹çËʦ­ÞžÚ-gïíYWó¹R|‡ê&™ÅwÕo’¦Ö±.mËÀ9úF«T7è}ø°"Mr)ÈyqÅÍùÄ/ûÆJ.ãK³Üû£,õîÉ'´õ7_õv–ŒÜõX½Ú€ÐÌÛ¿ý{Êr— Q;O?$ýr>[¿mÃ3K+IOýM‹/Ngë’†Ä;EDeò3T½û[íd¯%8htpݶLy­%ÓÙå´üý ¤é1Í~Ž„žsoÚCð™²Ù~’јåRj½nÒðÙ3<&ùTµ7Ü[3këöÀ½'*›ö´YŸ’ÜѨMÂp$l†áR•5ñ¯¦X¶¬9·íMföR‹^»z”ÙÊ7Ó#NCm?§¸o¹¨I‡ûo½u?§ìxYÙSS"Eð‰r¥2{ç¬ ÙëX&Wÿ’þuE/Ó»ì [ÓfûáBú"f‰ÕÊv Å_eàúbøÕˆÍe›KÉó*üž–*åk6¾i°KË*ˆÙYBŽRßí˜ß>¬g‡³Ý¥¿ÝÛ`—£o—×Û€¿5þÿ+ôŸ¬ážê·;:*: Áÿ×¾? ` kÿèíÛ€Ÿ÷ŒGàŒ%¡Ö­â˜ömùiÓù˜)új ¦ùS3Tý-U£%äƒß;¤à·{Ör³Ï·÷²ñ\Ø*áÎê»4eƒü§Ç{SéKo‘•LžÖz›Ãˆ¥KLóSäjÙb+O³å¬½Nýf܉Õy­6üq#ʪkêæ¥”@Ë…Ž¬³ãÛ¸ÿ£¶EïÕ¼Mu‘óžU9‰«¸/s}ÿ ½Ì*·Þ"®«ÉÁï¬Í·;ÔmzéV« ¾lr› ~í³ãe« Gx–È>Ñá2.UVZfK.˜vûzóìú9ú%øÛˆ¶„—ºÂžESÖoþ šÅk[Æfµ]UçNýªEy¯6=ä»r­h]»Žõ2™!ŒÛ‹ýµyŠ«>Ë×òßM]œ:gµۓÅ{·mÁâ³Þ–xûTIâE¢×ìZo©tÃx³”S÷*¢é¢º!>yr¿~ÑIÃÒéš=˜#Só*Èëž nN¡‚èûÒ=‹Œ8Ë.÷“Ýý&Ç ˆe¼`³Ô«m ¬ >¦ü×rÏÐpup9+Ý7Ã/,9pl§VáV¼_ô^7¬"éŒk?lN½¡ÀsÕx þ½¾ôéXâù ÕeosÏeLN9yÙ›sjûõ›·ÎøWÞçÈœ·hÒ))áµ<,ìæªG„Ê:ÒµÙwòq-ƒê¼ñtœP̱¢ÏdÂã ó¤pσ¡Â™wÓÌDýÒm6-Îyඈn'N?W±r"$ÏÕ¡³EuoW¶Í•yÙ CÃ2ì:N²Aái7Û¼6šLÒœU¢x7c5ÑŸ[ºíÉÍzf$Ó‘óŸz|82Âîö‰¯â¿a¢'pá:‰=™Å1¨ÿóhÍì&Vˆgr³;ÇçÔW—V¸¾œÛ <®}··—-ˆ[í4ãÝ ñyAïop®Ì›¿e>P¿0‚ÀQ,¬¢ônžXdž'F^Ë6ÖÔgÜÜm;e[÷Ã'ïuµ[/³¯ã;:¯²_zyy0”‘SØ4âø´Ä"áÒIƒ ~:¦>YÉQ¤1 4:? ™6Eÿû4¿6.Ý2ŸÁÀaï³Ëo«X¿ŽÔâè •¿â1Ü!`pÌ{P£ýÞ®OÇ®z–/¾n7—ST⃈FƒtçÙ÷ËkÞ¬¿ñ(j"ÃeÑ‹ŽeÜxˆÓ¯^wxÆ‹+³u/O™û¸Ö&vù¸bÆËÛk⊴nɈJ™ l²foŽ(Ù4á|“˜D‰u섉Ëí¦oržº`h&¿‹£ÿkî 6qÙäõb/>‹á—¸ž?Ѥp[ƒcÛŠ»]l!——½úü5ïdV4½ä‹•¨| s\Uï©ýŸ²X&ü?°é¸=쟿>0iŒ¿ ÿÚå‚êK§{¥a~êøþ5ëbsbpþQXë¢9&.Žê¶ö–Ö®®A.cY ø[ãÿ¿Cÿ>:»€xr|xTøŸZ@< @¤o¥ŽKÅüwD~ÊÀ4! 8†@Œ{‘RÔ}rzþ­‡FE$¬×iö”œ”Å¥"ìÑ…Y ·?CB¯x 9Uè8î{ F–\d÷\~l¬0#¾ŸP­Øw]e…Žêü‹l5!úκË”ú5Ì:•šÙgÞ5Š º?ËkÀ˜ú¯ C6(°¼I^_r“W:)ûäÈæ˜h•¢•6w_ø…§MâfÍÚâ¤aªÅ}V=`Kß¿êÒ{üA½UiÏtï µ¸sÜœ“ò(^×ìHþ–ãÍkëRt:²VÄȉ>Ø5\³i·¼^UÖ› Ë²í<–#Øüä’æ²VçEò¢ËÏkiºõ6(wb__UÓ4L÷>¦¾?..ƒAò; t®ûBK¡îÝ{7ö®ã òrs*-M~wâ ßh [Øñ*‚úù’MkŸÈeº4~¾È¥wò¦TKoúj¾ƒ÷ß\1Ï3MòØ|/kæž¾á)+µÍ/^”±ºæRb²ð–Jh/P×Zi>mPÉÕn¨£ÛCèíY±\RäÅ‹ÅÕûgp\é ³)é²|¥¼ÄÛõ¹wLwßò±u:S’§ÙøMüÃGÔÞß|yt×|óæ§msV†ä*I‹ÞHT4ÈŠ>&fÿ« =RXÉÍ׿H›ÜðQe8~Å WÍtµ«>cgÛ L_5®*½«ÿfÖ”û Oÿ ‹Ý¥‚O›*¯?çÆÇÎû<æe³Â’TáIÃLøtš¬s<…{34ôaüýVßݵ¶Àeš`seš˜ûå"?EãЯH¢IB¬aŽ®·Ùq‡±¡…“w ûØ~güÿ—è_Ë(ÃûyzLL\x*Ht±J=€®ä§ép¶_¼æâ’ >½q’¯{óçÊ>Ù'” Æ’ã4V-¨h:Þþ5¡Æz󊺌ÿ¹|[ ÷>É-"8'+ \Hªt]¤Ýõfו²°•°ñÝä³zKƒçç û~ðtÙQU}_ôàŽª@NãŸ÷-)‘¶Õʽ0q]‹ø;g‰ÂwÊ/‹öw«¾õ޳¸Â²ìÃÅâÍÇ¥¾K|/™•B5’—f²ì'¼»X¹¡§ùØ6gÜÝ¢•Ëýy"†î„éìVÒˆµâE*wBϵ |·ç¯Í8o:«L ½YnÁsRãäþç[JÖ[@Ö•îÙÄp(-hÌj _[dVrôû¤xÝ´ñ°åß¿0l“GðpÏ}±P­˜ÙEº óš—ŸZ3騋kïÁO“æ…¼Çcµ·b›¼¯ÄŠœ¯y-ªö²°CDïÌ®×GÞlÝûôòÎ)ËÙgØs¿|&–Å1yÊv÷—Osµ ‹l}ùNçsŽŸ~:yÆ{‡{Cúµ©û®Jå;ŸÑjåqÙ VeáƒþõiC½›Ø¾?‹æmå»;å’¥"WÇg…^ó»,høxOM±c ‹úÃwsº_:àkïçgˆ±þ9¶öºjµƒslŠß~þùKw–=e}õªý”èÝGûU+‰Ýë??2cÂÿðï¼ <íÄ]™‹2‹üU>™6•ÏÏôx®USç©@º—±c—Aj´›/&k{I"Û:ÌÐw³³½‘©Ã.Ÿ`÷1«üñÿ£ÿâ x·\RhdD4îO- ˆÅâ‰_™ ãÚ?zûŽÀÏ)ô<À1LHÌñzkúHJk{rpŽ¡¯Z_;a©ašåêù=ûfîÙ¿ÜdiË4‹‰øÝCõ éÞOkd8;¶ôî=v%¡vßmÎ劕u+Ne\³£o.r7¼\qÅùAKÚÞÕ[ô8Ÿ+¹1oÖ–»÷¬ï—éYºrOuƒ’šÝ ·vžÊ¾Ù{ª[âNú³BGŒfv,ßQ‰º µ#7Ïx®¬Û2½^/ü,¨ÍÙÒ~ä…Pá¦s›c ¬'ë}è‘ܳdŠXàÄš-F­l9úw³ýj,q{×Ý]sÃv{ï<ß÷1gÎ^x­ ~¡õ¶¡ö÷êSëòãç|˜§"å¤"aSœïåg¹®É.Ç{Rͺò*×^úêD(BÙ“§¾>s~òÓ£ƒ¢K÷ ãyy²wL¨ïnÍ¢ðRç¼³hYrÓÁšcþj ‰7ç©W…ÙåE˜)eªë(8°ØJ¾YrzOæAÞð]«÷Šª*.Mû<•gñ3¹ E‘‘d3µšÇ:­ïîçnnˆ.ßzÐUÞfu“aÙGåv×¹ù[í\ó½ ŽY…ü’ÃCÇ껀±¦ï‡®ÞüÛžbÏñޏi7þɧ˜dXç-Ú­ûPkß•Ûê׈ïeÎÌiqîO{E|óBMpºÖÑÁ‚øy·µž¬î‘Æäv4K'ç®”žä<—ïk‘t{¼Ø+“Úõe³w>$°gl¸õæÔ”e—CbuÍòÕ¹,å©-h7:ß>T›sOÃcèH#ì^ˆró®Ïp<ýÖ~ÇdI+RwLþþ©J™û'ÎÙl/ç·¦ú‚»<1þ Úäó Û$ b]õë›»,&pïK0“v8)hÊï}® ÍùLîãsªm·ÝUØDâÎFÎÌ^Æÿqv¿T°ŒZCÐ÷à_œPÞ¥”§p?ÇŠiG¢²/)©µÎ¹Ë¾Š ÿé÷Ž”Zé k¿àDðOVñY<ýóûC­ælwDò*I¶º6…nÞ´ÚdP¢ìààl¢âªgoîâê‡u ðûâÿ¿Gÿny^†²a‘‘‘cU X:÷øJCEÞ/eñ¿xþwßæ«wù‰ÏÿRÛæŸzœÿT+E^ ): ü† ˆx7à°dÄ‚$„¬B”Ý´½ðÑh¿ƒÔè6 ‘ T?B¼$È:07¢wAÔ”\p1‚HÙ”ÁwÁûE“à%Ö;†ŒÑg‚¨÷ÄáÈx DŸÉ+’úðÔC#ŽÄ!ºÖ†Þ="eÑÍ Òßù4#í“zWÑQ‘ׇà¦ípÈ„$®RWáýÿ(ïBé‚i[ÿs`þD;‡ö†hý¢øã„h/ÿ{R@¶X‘ ºŽƒˆõœQ?ô+€üC¿ˆ@»)[x½z! }Kyê{uå_ÇŸ‚ðL8ÒŠrÂïÒnú7XÓúŠyáþèüZù¸ÞÿÐ~*ØþŸ¿ÍÏ+㪔Á¢¡%B˜1P øo3þÞÿ øÃL ;4™vÿ;eiáAŠq¡'þë÷/dBY§àý,þî±DÄ,„à~E‘eú D…7|iÊ*|6MWñT0‚7ø þè&ÿ?zf…œtp3ÄÉ·|ðÿCÿãÒþòŸn=þÔ™ÿùÿK€ñÒÊhÂ!{Tøƒ°êHnŠüÆaa¤u´Óä?•@Ø·F—ì ™›_ØI4ë „ãµÍœ‚ù2‘à xø*¡4‡ÀùD’©~]ähʃa°!dz- Ü ŠÀÒôá%D`ÕÑS6A˜!fÿÄ ˆ„gÒ€¨[a' G*àçG1ä°ÑHçˆî¢tb6QÖAD  €r:þ@ø8‡gDwiü‘`´uÿ¯™Y<­kPüÿž@F×ÓÙ5‚pØÏá g`ÈDaÔ oÊšQÑð`ñÿÓ÷¾XúgüQ®RРôß_Òþµ.€ßÿ?ôÿKíß!ÿZCñÿ= À=Ìc`\4€R†G÷ €%if;ÝáR³§éF<4þÉÿOÑËáÄaj~ÝvB%>ÝV£:`)Ær ƒñÜC¦< ì7°ž‘A‘!P+ àc0>¡p°$Rùº9’ú"L™7R~pô™$`€'@ô£© Àðehƒ˜Ü»Cz¢_’¦ÔP“„©ïO㔓á$ÂhZð×L€ñàÅTS†ú®Ø@^ˆfQ!/ƒ!™V¿å ÓУø3‡£~˜˜(l¬# Ãø§þ0þá‘ Õí¡®]ÄýOdò;QÖ!>ê¨øÓÆ,@×`Ûðø3S ]g˜ûè,í2Æ_Ë? àwÇÿýÿZû÷ÈÿŸqŒ©ùÿ=âýÇõ‘Q£`ì€2úÀú4.„1ùT À#á@Æ*“.Ðóÿ©%ˆWuœÑ®‘SèÖ•@P5NŠ%€è:6FÀÙS%ûÄ‘ñ:O…IDV‚òcÀ;$¨I¿t–»ÿFs ýÓ)5ÎhïZÈ.48:Ae°bO¤êóTº§11 Y3,=˜›ÑXÅZ„k‘3ˆè% 5@èßÁÎ!¿hX€L%hlM¡Æ=©gþÅD`Æô"üuö¦Ñó`³›† .CüAüýiøƒLAÄýO³Î‘m‘î `6Îñh- uŒ߯OíÑg˜ÿ4Å–~2eü“ †¦üO~€ÑÀüÿÐÿض‘üÿ `lÍÿÿŠ0Î.ÄÿÈbxÊe†ç aTû®8¦üXÆ1LŽj K‚h}*Ÿ…˜¨žª 06à@5‹P.((4©†£mÁ ¤Ò"Å:ÃF„À;èçüRl7ÛøPØÒbÊç[pSðYÄ2æ’Fò 0 êõÃ輈ÌÄÃé\›æAa3©¯‹šx¦00ÐvSl øýdõÒMô/1Šéކÿhæ¾/œÖÍX¥wÝè¢þâ°ôÀ/E¾ÄŸÞhÈÐñG¶¸ àˆÁß1>V8©`"”C1! Má¤^K¤ë´xþTýOOˆßÄÄÓS飙þÃ,4zÆ¿\ø½ñÿCÿ¿ÚþUòÿG5€16ÿñÿÿ…0¶@)ZóTûÑsûérš>%¥a}–ºÊt } ®ä!Àóÿ Yÿj “럑E…j¿HB.@›±š°A1du È p -€¤mc¼£Â'†fp@82Ë64JÈt÷5úf"‘8ZºDcg¨aâáL)pR#Åža0&s¡n:‹GË€àë!DiB&Aû€¨i@poŒ1(¦Ê>œ±ÁÄ¥Gÿ…Ñ@Òº™Í=ˆ© ¨ÌC5ÿË—%`Œ#цXC ) _°ûûñÇ„Ãé\8Z¯ª·—6(® Ñù5ˆ<9}6„h{h€_ÃÄ3C·þ¿ôðSAð§« ÿÔF+ðÿüÿÐÿ¯¶™ü§Á÷‰Ð±ÿß#Ýÿrø­S¾c©Àþ8a™€¿èu~hÏRSaiùzˆt§tºÿŸ^âGíÉ0‚Ã^á³ ¨ð]!±Mƒ€2œž ‡-“é†Á¸X¸Î‡²'Ø+þQ6b‚#§u‹"£V†LdpÕê@H{-&¤XZ hfR¸=Ê£ËìÞ@Lxš2&@÷õ˜œÀ ’dï "j8…QýaŠCê pTzÜ9À9*þDzmܾ4‘†rwzû‹ÿýqÔhü™ïGþÂ=Š% /¶Áø[æ'þžÑh?­ ¼8´þšÉ@ÖT… PñGT•å#é}ßĤó…Í-ç©÷Bðg¬~Ÿ àþß‹ÿúÿåö¯“ÿ?àùÿS Àw]–¹¡PJQìA$á—Zùú…ÿ‹Æ>‘utni0*þÁ…=t¦ˆGzê ÌuxšÏÖŽ©ùˆƒfˆaƒ1øÊIˆKãŠÎ׉ ÀGPEÂ7” 3÷L8žJ„ð” H?B°ûo´‘1²‰æ'Æ£=j8ÊÃD<³¼ i*ô·„}wÈÝŽ¡2€QIÀHŠÊ`K ¢&¢`Á7% ¿xêd ãÌŠñÔ9ž©ø0IZ2Xµ;üi—¥÷‚?‡gbÄpm5ý@´óhø“¾0 ‚ÐdjdJXj&„.mi# 5*ÃQ.žVÒ²¾Ž?“4ûÒægûô[#Sãé;Žnàè¥?øÿ¡ÿ1jÿ>ùÿÝÀxˆÿÿ–ðå03 àùÈÓÄ~Ô€}Q ;˜ÎP¿“„Gçû• Hóõ#“‚£úÍÕ*H¤ù‡ÈDõ¾LPX™²%†8à Á? 'ð‹DRj½"‰t~ÀéVhWDf./ÑÒ¨Û¨9?âføÿð ‰ú6Œ`f1’„NS>Êb¡1FÆ}¦0Ø¿—2ÕJ@nJ@3ŠÑJ q6Nc 4ü™ÊÀ@ˆæÞ=–Ñ´núF.'( ˜Ddê¦Å/'…§"w Ãõ à@ „H½ˆ Šúü)@ª£ BðG×Ä‘ P]W&KË죢…>µ6Âhº)£ð+øCDºÜ§ë´ÔÆ”1†§HÿÝÀ»~güÿÐÿ¯·£üÿN àgìì_oßsןz²/FÁi%hÂ?HÍücÌLý ÄìAƒ)žzû3M Ài?ÌÞª[]p$ˆ±êÀÒóf)‚Á‡@$‚f!ìGáç@0láA»õ‰ £^:S°kh8žÉ¢@§*Ã3Ü nƒ%á™ýŽpQÑ­$È0ñ£çC_ ÀÑ'—afi´ Ψƒ3ã`ÃDgE& !¢ÆR „‡þ>8Fà -á›Éž£/|±ŠÈStêuúFôÅÿF=ˆà?êºTü©¬ÀC!´Sd7€Áø%~ÿÈpxöˆÚëðT• Õ»gÆ„0$:¢ÌòuÔBô= 7Á×ð‡L9€ Àh­€I7øÞ4úÎ1Õ~güÿÐÿ¯·§ü§ÁW¥èø˜ÿ?«€ßó¬£FÁØ(gÿZØGéÓ†ý»aZ'ÒAÈÄ L®Ú) ?À\ …š`íãY àÀ9ÿ´w§òL GÑÉ]@¬g”{|õô`ÿH˜Ÿcý©“”x"&ÓŒzŸ#ôOóòAôÙÀ»#3|£ëÈçJ¨tÏôêô'C»À@_¤5#þdæ$`xpÚ~Dý¼J-"‚¿‹þ;L€"úG˜Ìº/FïèuÚ”°4qJé$æÀ0Ã&dt8ˆcô2º6£¨•|´æƒÁ¯á»c°ßÀ?(‚'ƒ…¥8 &㙤= –HÚ\¨ÔG‡ :ۃ߅ÿ¨¹} /~¾P1¨.0ólÿÔÀÑKðÿCÿÿýöo•ÿßtŒ—øÿ/*_‚±ÐÊPÇ=Í4§ûöG‰}<“¹$\3׋€ðEA ƒ8ð4sûÑ úG0Ö3<œŒ` pH=¤p(‚Bð ãOF-= Bf)pŒ …û Âa 2­þø ³ûÊRFûÿ@n@4ㄺ›:µ(£* ü+À4á‡~Aäšh€ø1a†ß…@Xh4þ&À9,ŽL`ÆŸ¦-˜LBÍžCÍ7wýË"Zö8‘o«"NX 8Áæ–T¦JÁŸü5ü]cB¯5ƒ'#)âx´J R§W£Ý$à¨2ŽšlBçî£Å9Å4#~þ(|1üÿI@< 8ˆ) àïØ=µ™þàÿ‡þÿÛíÿâó¢ð@ Mxœí}@mÿe…”2BdµdD©4mM¡½÷®³ïû¬öÞ{“¤(Ii!"")¡¤dUFCÿsß÷9§Sçý÷{_½Ïã}\žçtïq}®ïþ~¯› üÛ6R(Ä?Ù‹!PÉÿÕÇa6 Mâ pâƒö&ÎC~žö×ÿÿøhÿ÷ævü{É}ý Ù,‡i@›Çg”ÝõêRî96ïš–Xì"(D8£’ѧ™Í¦®ŒhÞ±«nXÖºjCp —B(÷õÌÐ¥¶Ùk¾sÜgßø*·l<€ºË¥To×µo[°Íé.§r,·èù ;†Ñ+…«–8eÏÌQú¸&vÇ´ÊÇ9ŸFVhå?Yb\eë(P—ob±´ ¼…ÿ Š tF¯Éô¨Z2gâŽ'‰çææ œ+MµëH®-N–’ˆª[×û™l(Ôq×CåL ï,͈u¦©'ûÏç›cEÈÃgŒx‚ä×nNÝ/:Ö%ßkžÑøðNéÁ¼œÃ ±• Öǽ}t/óCøõ÷ËÐÏÊmbƒ’;CÛUV÷îY4ÈéùúÀs+Ó:Þ[ÓÃw´˜^S`g¿âwð³“naOÞ¶þáÍ3‰h™'¶-ÎãUÌè±(>«2±•*¸W•÷•¿ÉçøvóËOª¬ò~Ÿ.×à¼HÄðØòùÃ5»¨9÷BC?x÷°'OÉæÉÜöçVŠ\£•‡:L!¢i£,kÊñß)PRtGØórÌñ»àªë·ÄŸE,?”oYÛ¾yúY‘ÕOÍ÷‘ÑÏž‚\õQJVÓ¥M>/æïÔ™qÕúä«£~nª<æ ÇGÙÝvkß²ý¬dUp\ºiZáÈi7>ËÖ Ù¯wMDÕg)[˜„)|̸mz-ËéˆæòW2rµdü\‘®çÖE Í—·H[«vœ+«¨ä ÿ=]½…ÿ²®éÙ„wmS{„ëz/êgz\gFžˆð;ö¤AÅç=õH½LeÔ’´oùçæŸˆ­ðÌhΦ.`Ó}êtu×’¬·‹*žŸTyGlÈÏ}Sí¾¾Û$¶t2øû…Uä±÷}{¡{Äõ]¨„¥éÜ+l<7$¤nÚÎbÁßaŸ®`µD~¸ 5 ã_³ëô÷W 3{‚çl à¡”%úzî ÆbÑî¾hÇr‰dû`=M;;m Ks”·#î7þÿÿÿAúÔN‰Å§ûû¢Áÿþë†ÇˆÊwaI¾ÿå§a6øo)“ió/àÔk+¿I› R];J06fÎI«ì’¯ß=&ôNœ—£\Ú_í®O¹â#÷ðk[…Ѧؠº“wœÂóg^\t©í]”L8^¯À2¾ë®]|qÞœDçá›×‹6c>lb1ò…g–>BI½XóÖPì¥xUè¶XóB+—ˆV9©V‘ýί$\Ë^¥•ÌáxÛ䢦fË‹ á+¼æ­—,U¼ý#EÛFÕÔ–È·;o–᳡Ùcó½MÆÒ¼r!{ÊÃ:„m/­QhöÞ"Š£nÀc5Çdù²êì¨##)‡÷/ܶÍ7EŒŸ=Ý÷šDZÃ'Ôjo ãòxnÅeð9¹¤B“oe¦È·Fm1TM¸åêL[+þ›¡¤œ èwçôÒùv\5}Ž‘K¿f8¿Qû…墒äwë¿t¼c«¿þñĺ¨\펵Ÿ²–v¶³+¸)ñǯu]sc‰ÖWï¯um¹Ó-–ÜRxÙ¡Ü—+~M{N|}¥ŸåÌ´}ifŠ—Ò¼ú„„.€s¬¬û=jœÄ檋ègµm“Þ#( ß®¡;ä ªêáCóaÁ¡Ž8õ «æÕQÍçt‰Ô&'žEÏp™|‡‹"]÷nÍ;Ìo½òe†oþË4[ÓŒ¤Î|ÊK)âð››‘aѹcù^È3œöä=C³†³¤6SÛÄó¤µz$Žzt¿NQöÃ\TµE]ÐÁû£<F¾«…h^ïU’K—ëðå)‰Éàû:Ëñø¼ VU2«rØ,ݘTì¿Ü|Á^ÊÂLùè°¥7û.ìŸàïtjf€ãåC![»¦…^¢œ½»)•ü<æP~NxêEOMW 5 .ö%Žãâ´÷h›Í:©iÒš…«»Ý̳5çmûâ±[/õPÃùÕ×zC­|ßà¥ÉÏÂ&ƒÿJå¸Í¼Êf$¾5e‡4Ø6tÊl}bÇ™´~w þ§ŽçÝ‹\öPöŠÑáØhÿSRaK“ºIÝ·üÖÊc¶ôlnPÐQ¹LÅ$Ú„$jݦڙYiØ©xë™[:¸a\Ý¿ñÿSüÿ7é8£zå“è bÁºàq‰ò#; øNBOMâ$dû€I¹ÆÀS®èZ‹ $÷ßY¸OBùö‡ Z*ú… •Ÿ¿%9ÖuìÔ7¿þ¹(Ï;²¸}äÊ;~\’ôIoc`c*A8_æÑsœkåÉ8í¤ƒ·Y›¶¬^ÙNz‰_φî“S¤]Zc¨±$ø´cà]t²Ôºê 6ÕCK¼.l›?øØó‹‰â㌃‚ Šùx/ïÖ%?GÛ^{~Ïø-ñ%éÞ³eí‹òëC…ñä’Ç“B€-U¨PöŒÒÞ{Nó|ÖÜõÜv>axWÿ¨XÕ¯eÏ+¹"âƒõÖ‰é'|îã@álÚ~Õ}\v¦„uA嬧 ß‚°RÂ–Îø¯FZÆ·«´µLJÚŽŠ ò‡?¿ÖÚo£xxuÄ`Ôæz¢ðÉ-/§WŸ“o MVª¬8­üAgÙŒ¨ ÙÇ_åNx­êKËQ´¿<ƒ|õ´õÞ°µ¹_¤£9±Ëmn¿0uÍx)—2º|Dnß5LjiÒíÞ7õÛ\ë–ìÝsÁaù+­fnjåX5ëØû%ß/|]Ñûôlç¹M* íë²ÚÔ E×}ËŽ~„{ÖyX²!ìŽ>õë{_å7r«nÝØµ5;°øQ<ÖBͼ’øÅcÁûôå¿Ñ. ñ’”ŽquLÌ‚góÂ_`ã]ÑxjI ,~ÙƒFêS3»KŽ8«KÍø™Þ×G&§š•pGJSúÃUWKm¼<'óYÑ6Ïí±Cs÷7}INì{ÛÔ-ºs¿ÅqŨ#ÂO«†ÕNÝUé,kJ^«ú"ß*‡òJvQ÷´.B‡ƒþ!dÌTPx¼ØR Ÿ]1À¶èV/%¯õœ¿ç½ï–˜†²×AÃwÛ¶^3’å ‘¬ZͽÛnšÂóØÏ´'í¹rAû#7…Ç£&'Ž5Šs]W+/œ]ž¡iîÚ[,ÁYö)õ¢êµî˜ojE<—>o²í.øRà0Ÿ‚NrÓ>â~nå‰Îë±DãâÂýž²nY×ó-›ÒéY¶ÂIݶlGºù²[9åóï=›±eö‘×m€?Û5;ñÓ-Õ.>,š·°5j‹×Þ}jë_°ŸþXÔÜ×R›×—뱜?9®è´I˱Šìù+Uª›È2½f‚›e³¬çñ{½ZYܺzcj>!d§kÐû‘kÜíU³e&…¿ÄñÓw§åY)í°Z‘ª7<ϰÞíÉUÿe”•O¾ìbÁŸóEŒØ{ñáAm%ê©0þ6 ׌¸§¯¤á«hzàNçrr™Ž•˜dŠ':ù¥ª>õ3·>dik¡acffçŒB9`~ãÿCüÿwé?ÉYÝÓ1 ô ñGÿx ÇÉÒ4è÷ï¸×V›TàßWÆ¢„©Üð\“ºý"KýÎòã½¶pÈÅÕú,Uö>mBmQß‚w¹zòìàœ‹3zæ/›¾ Þ\©xVŸ¸Æ#‡]²ÃêîÞ|ìû>£§ú*D­ê.À9‡^?Á©üöí’Ýç¿ìUð·¿cl*³QEw¤J3O¥²“Gñ¢-ôìtÑ~¢_«ãñõ÷U†Mëvôèm\Æ7ÓWÎuÎPUíèf¸R¯u€£%_qȨée»KâPGÿ}ÞŽå<·­nK¤gbcßw.$í?ÝUôú±‰§Ã–ǸeN—Úv´Êï4îÌê×9@]qµOq¡Ò‘ÃYÛÅÎ\‹»óššÄqzï]I#üÈý”Á›ùQK/¾Ëž±9þ¦º`ʦ¼=n|‡ÙÈÌáÇÏâ[{0õ’íý#,†8 ¹€÷!¾|‚™>ç|KjÈÛÒàsJ¿-¢³ƒ=ÞòVŠ£c¬—zMz‹¸€ý ³Æº ¹áä=^ë=š88¯ti¼‚š{ñÚ«áµÃõ³Ä<¦Ð jÀ4UßX¿ _ã8¸Fò ˜‰:œ.0l¨8ßýhfˆ^¾bZX5.™Ú €×ãpåÞ5áo(¥%ÇnéP7é YÜõÌ 㸸ÄúÒ›ùrñÓEÌ©¿¿¾¡qç™ðé½É2)Z­vuÑ{Ä-Ú-WðÄ.žžØ»5V/K»mñöø7Ÿ†å"eë7zxx`®Á;£¾6…o~Ïjð_­+ÂæW+»YsFöŒh•#¸xØÛòïoÌ5HÜXôqצ [œçr=þ8oÉ«Yƒ­JÒëUãÏ–[åMÄ_shÉ,¯ýËdµg¥ïéìl‰8È=dѸVHüëÆWdc8¬ð¯ÖXPſ õj ékîþíAglfóûm‹[>·%f©_Ú´†«{݇òwçòø®Ló—F¬šþÆòµQýßF)K‹Ï˜j;Y³ã”šÏرâ_Ðn7æyïr‘G†Æ?KÁTÒ®»Ú\¾Ó1ûÙé|R^¦Š&ð@ù ó¢=(vº¡¶*F‡Œ,ì]Ñ.Skþ¢øÿOÓÿ±Ì`ý,ݸˆàÀà`Mü§k8ŽOÀâÿ$-à¿Ô&ø7sè§"¿S`Y¼âQ‹k‡Ì™¢ƒO.G\õ¡ <ìü\d²sŵùCåRVhê/þï*tУ1ëóãƒyI¹Y¯L®y%?r·À|“GU÷ ’…ãJ¡Ï#%¯ë0W ©^ß!m©Ë“æ~mïß°¸ð¢ï&W¸ Ôï¹°@|W²§מó/ßX;¾$HºVòÅhoN\Ú™¯ïÀ"¡—ÂÁ¤µ&‹ûE›ï(ÙíàçÌZ9òXM^xYpÏYü‰4ߢ‹gÆII¥Ý£Zªî¶8ØGEŒ¼¹Ìi›=Y8,Fmù—#Ý\ñ[W,^fV]œ„êÏu|p²ÁÃ5ºôõÞy랆2]Ð;{4̱¡™Zuky½nƒQ4§û“Ø 7÷¶·Æ<–i'ò¢êÜš‡ß­8kÓCB7pÏNØ£ì+¿I{ÕùÝE$òþû*³WÞpVãÚ•™žËRk ܉HÖJÌQXóâŒîrç½ýg]u/šôºØ±KoŽ–ÈÏ_¦“s™xß:a«!znîýÈÊps™§ËʪÆ+íÅe©°(@%ERñSê°™¹·`…O¥qk‡’ºä*²aA'™CZbi™AŠóÕ§î}ê3Ù{ÓîáÑ÷ò:nŨm+mDÃ8pIí63%÷©¤”WäM†ï]Ú¼¬¾>wS‘ û^ç¾n¿Í2=§!Å(/¾ ¤À(ÁÛOÞz ÿŽtù~‡ÏIo<îö¥l²°Û‰já7Xܵ麰¾É¥›7w¸¼–h–,ÑúJ²—zêo±]«håÑl…Øà ø7Éß©ÍE·äžmk(º¬åj¥þT}ïS÷¦×8o šï:ÍQa¾áŽæ„‹’¹¦/jú×ÝîwËHG{ð­Ef³Ø¦ Å×õnsºÕæy°\°fõì0ë"q·Éá?ì<—?ÀÇXƒïÚ­— ÏévB¢×”Eê,6±â_÷YáU ÿ«”Í×d3ˆ†0þÚ”Y®Þ}þMW$òwnh;²Ÿœ_é®bå–máCv£$kÝÞ’tÈmŸƒ­¹ž…¹•™“'ÆÙc*mÀ_ÿÿmúÛ»—n[àB ÂÓ¤ß?\pxÈ’@ÀýþÂÇ'ëø¡ðuLm€Ü›cêsãG,+JÁZlì*ÔƒT…¥ï•;s«íÑ®ù(»ÊÔinW7ùÎ~~ô YxIÄ÷+|Wq/æK«s>¶I‹™Ó£Î{®U@]ØXv aåý“'úƒâÏ´ˆ•÷ìos¡ˆn`¿^ºF•_\ìRw˜|óS㊨B‡ÑÝnGÙ¾øÕI•ÝÐæZüìp¶Ûƒ ;ûlʩێ޸ý¦ñ]Ë.U„K…Ƥ HÍìP}K»±æåc«Ž/èÞGÞ½í~ät)@&ÙêûË ù•…|ó”˶UÞUN‹–­ ¹ÂZŠëU>ýøõy_ã;w_—Å¢ÁgE÷‰ïQÚœbõ®óå7çÙƒüÓ×%zM+¾øì†kå-‡îÅUž|Ô=s ûõ­á+^h|Ÿ¿é[¹@Ö"‰«ç‹Í!ËõKž$~}ª„³Õ:²ì–áhævýµÖv-ÆìôW@æÁpèání¤a­â¡ï`lá䃵÷™:ðkâÿ¿Oÿ•.ZæN±ä€ ô!ôoÞ8šÄe¦ ¿ªöÙ¦\`I$S—\^òä€ëëâWømÕ'Ïg-ØÚÚ·óÑ™7«vSÁªíÞ†;3Mã®^{ؘ½@Á52Þ…”©Ëûé×;…Ó¨€w‡Òv®Ì­þPa°,å^†ÉËnéC-ŸÑwóCešÂO]§•U¡[è[çKðqr«9þ"˜êµK:$öÑkƒ‹úƒè¼ÎO}Ú3ü°W†´ÒˆµºB^=#–ÞFÆ6{ˆì‚¯ÈŠ6–J•>γU¯ÜÁ[{—"‘Íw#h@‘}ŽË´¦K)ùs:nÏ¿(fRU©Õ’¼6xº‚ÕM.]×33rŒ-„íWØL;£ó±uÔM•ãrŠp³ÒµÈ ˵ä»òš ï9jØ—¯þ*qéé놡™žü \glUºæô~M&%ÝáEóû=›×èÝÆpsÜàò òXèÊÓ´€‹Òìòòrz¼·Y÷}%AØÕx5)·4ïT›Iïm®®éÈèßxwøÃt{ìÙœü—Óôù¾t}Uö÷ö9Ö}×ì;ÿ&"óˆýÍù9Ûâ7hD$GzxáBAì”ÎíÞ^vôeeÒfÌ¡<¡ˆÓ5üž«¯h¤¼tÙÔOá}aüMXýÉéËÖ™ËÛßæM7ŒÞ’pG¾c³Ñéí³C¹ÚO¯ª6íÝ<ú•‹7|ðA£n‰lóî§\†ÓÐD«iú{…³ÅX;D-cwÔ»¨w;A¨¯ÊOœSªÿdæŽý:^ ¾XûŠW>ýd.‡»úUÊ×uí£yÒí¶.J¤~+øªvûJЪO‹‡žVîx'¸p ÿmû©MZ[»DWͬÌ:™¶¾™í`AHxŸ¼žß³ä³F‘/v–Ü÷p=xóóës›»7IÞ<Û¤>=GÚô¡Ç>¡Bãæ-¡B&¦üy>zò}˨ÐzLá Tl›$þç¢{ØQõÜO¶„Û¬±ùrͨd‹ÿÙ#mÃ<³Yñ'Ï Ðd{«óEdÚwTî!ÿ^ʉsië•ø¾¨+Î {¯¢~¦<ÈFÚ+ÇÃô!%h×lËUA)cÌLL´­ÍÍí]Ð^SW økâÿ ÿZ‰áè B_Håw- ˆÇ = ‡ûëjÿm’€ÿH`F¦0°µí5ñFƒ›¬ µbaºMúŽL‘ôíågœ\IŽNîš‘ÞuG'þö*@XK˜ì{×Ü0êéåâÊ[âßx÷ˆ‘$Îì~ò@Gæ,÷æœ=_O¿Y(j·íø ÛîuŠü×SGk0}[{“ýßy-+[›âë k³/,ôCeŒ^câTe‡ñ¢Òµ¡úzáMØ+½³ Ža—{‡˜ûëX²‰:ÌW¸v£J5oÙ¼rc…ËFgÆV—¶}\}?Æ!‰2õ‹yßù—€{¶}´¾aoü6f3»×ãK@÷@œê¬ ˜âÔÔ÷|™÷Åeüï-’VºFÑw87¯ç€2œ÷RækÐûò |s.ô„*,÷±QQ*np³^žSºäC쉇1¹ „Õ‡u>ô™4YÌÿX‰ÒîcWè<·Ô×ç…BþÂüšn.>×ÊÂ/³+?“fžPW°^Ó]²TýöAÛÎÑ É¢Ôz×M‘;FÎÄ]¯‰|”êÁžú,%»ãƒE–¦ŸÓТPR-%ü^Þg[bßÁãm'Þ† ïÏsôÓºÃ.´Okàœõ9G3?_BptD4žˆŸ¢ €âúõ ³W½ÒŸÃ—©8Ã%JI»+|·¾M&›7ð—5·¿Wä[ æ4Ð }Aú°ÜeH`Õ<¿ºƒ[gõ¹Dy³*Ý$xB¯Hµ¤AüÐŽ™ÕŠÏÝu6«´\9ÀO¾|5i$»K"´£b„t÷[#ÔuDÞÕmDykzêÈtãS¡_[6JŽ*=âÕ~¯—›© —¶³ÔéƒGíU{…—÷÷•FðÞYí½mËñ{B&M¯¤èø÷.{Zh~íöJ_ໞvãÝ/«q™=bË Õh ð«[ò"]•­;" KånÍ ¼«ý”óS|àæsjíž-ÞØªÍØ8ßöSÕçÛ¤‰ +nœuÔ\Ïÿ„×Z½ázÿ}bø$ñ—xlû®±»éß¾Œ-úRú½¤‘/3–V_·ógÅÿŠWÒHo¹^UÚçå>ÿ¾¶‘=n[E°¡„S0›9Ïó>hÜB±Úìé‚"&i†=ñ>FÎjvVê†ö&Nžè)«ü%ñÿGпU‰œƒ5ˆ ü] 8– Á¿®öÙ&éø€© ˜Doºµ)FîÉõ]ÂÇzp)j[eÝ”¤štN§LÛ+²ùe¼å´7ì™I›^‰­‰ ç ¸Q˜™«údFÝü3ž&‹f—[q½i©²=žv½píÉsðM²v>Ä}T·N©Üm¦ÔèÜ;´)ÉèÂ…–ýVóß\¸•,I­yÈ™)Z¹RíYKÕôJv÷mg«/žU¡|}½­^^Å*Åë)é®iunûŸ„¿þØÌ‡OS»áôέèñQ«;ÇCpg§éÝz}*ûbÇaÕG§–žÌ6Þ^&°2(AXi—r§üƒR‘oö€Lüµcç‹Ùw-~ox¡;bCà³×ÛΉJÛu‰ñÅ%¥å¶œXêk”X=#Æ^&0¯ÂMa;ÛùÈû`¨xèqJ¯VW«ÕÎÑ'=Ok¶<·úÀ\M°AåõŽ x÷Ôë+)[Æ_ݸö¥å ”€›xà±sN©FÉ;µ–!Ï;ÃËø³ƒ¹cËu-{e´ ¯6±ÉP¦ïßð&P§|ÛYÃ!›ÚSŽ™%¯Ù·ù*±ÿ˜º¼ ŽßîØ3ß,™¯—eÖù"¬Bp 1@h0~jòÀh¨ ô/5|î$¶Œ Ø+ªF1¿€u+IxÇ­Võ·¬Mu;‹š\zžÍY¾1Q­p~FC¡Ý .œÓ݇óìð–Q%Ö ÎhN9¤SD¼p”¼åøeóÃ’‚Új ø¼E3:$Ÿ â:¢Ÿ­Š£j‘›Õ¡ÏåZñoËï”xÑXªm²¶o‡Ô©ã}¾¾§¶Û´ ¬C6‚’pæqž%Jf°DaÉüFÊož#øx.}d³Íêû‚«ñÔð…b•ÞW®dÔ¿ºMõ /x½üíº+{•î7wJ/4H™ÿZwô{^¶Y6òc¼…ĉMÆnòRkr Ïß2«÷æo?aÃzëµý¯۵ì'‰œR¦\Î;¾¢ÐnÞ´p€ˆ¯â=·¹ÉBA¬øSÞÏÜP7óió·x [åç0þªuö•ÅFmg:JFâû¤¯í—‰»†’7£Ø0N¯B*GÇÉÓÞᘚ¹ž¹µ™“ÆÑkJjIüÿ!ô/&Y»PbýBƒ0¿kéiXü_YûÇlÿ‰ðwLU-`Hh_σ“#–ng5Ü*}ÎÏŸ±Ø““ð<#:ù¢¨ÇnÅ«ÖÙ}U’\|§4‡øè@Ì oãeNAk K~/Í)Ÿê+|v÷=/±­Ö‡õäd°}T0yèööàô&Κ*ýû¾´Ö&óJûk‹]Ï» &´åØ*j% ÛDhsïñ»Üú¢H¤Cëmnáv¥,SÍFÐ<%síùV‹,nË]Ú6¼~n”þúêt½ˆý²—GÚL[¿ú¿PZ!¦ôŽ=)·8øÜ¦`W¿ƒ—nÞ¡Xr o¿þU)Ñ@Îë>Jyß«³ÀꆜƧ#¤skvrx¶¬x{´ˆúV *MMߺk·ÅƒÂCÒ–a}½WEÕeÛ:çß¿}ª,þ–ò«[3žZÜrž?ï³ú昔éÓIR_+Î æEM½/;ÇÅ¢JRº-1Ç,JýâìdÕ¯¸L…S5n&[vÖî>yïò*ã½_õÏZ¸`sðF÷üÙû¤w\ÕŽÖª}­9“·x¯Ük|NÄÍóú;ÞœS™áÈ)Â$q¹…ËyºòW ¶Ý;Æ©£7:C¡…˜PÒõ£BÝ-ED—ð(ÛG¸^‹Ûrèêk(8¨(:F¯¢áLÕåè‘ ×{û?/ª>RY Ì2<Ñ鲄CEYã·Ó랬»Í½ë%wŠÛcïNï.oYrÔ àé#ŽÃÞ¶F÷·*H˜êž%F¼î+-©¶¨)aÉíD•0ç‡ÉÓ¯È ×Nÿõq³óÑ©ª9Ñg†v=|@·­Yøµ­ÈrVü7–í'tn“>88¯³7›ÆŸôÅVéwúÛXþÍ5²Ý‡ûï.s¨HŽuÛà‹¶ ±zAá–Î6ºÖš¶f¶N(”#ú7þ0þÿúªòqÜažî~Òèâ÷»N ¤¿´öÑ&€$øî˜ª ¡eI?±êóð £Â˜¹‹U}ˆ;>ñ[Nx9­~z·e³^R]ÒN§¤7%ß?¤*T›E¾ÙúêRš¹Úñö±‡Ls^={½^¸ê†Ì½£•—^s7tíjÔ[p»Cï¼Hõsü{¿†Š&Ùû¥§R>hõæÂ܇9­eVáò½/ÎÖ7/<Áß“å{â“ÊŽ»ÓC¶¨¦^ê{6R#“¹yÓ+!E^^ÿuR>ük|T½—œwÌ9|R˜Í%ÜJNNjCãGÝXÜ>cþÏ„ó{Ì]ÝŸÎ:•ˆºð«?Du}Þ°ÓéåÙ™ºœ¼>}¦jßž(¼o·˜™XàM ¹OÛ‡“sˆÛC¨~Ô­yäJJ>µÉGW?í²5v6_æÁÜo “J,Öñº¶/¯ZPRµù3—͈p˜™ìÊ5÷„±hAΜMz X”žìf‡‘ÛŽÅ5'–K¹è*. ä(Ðäýà®4”nÿ¾pó¼¤=vËêo¡dÓ“æ½ØfiÕ‚†ÅÜ+0¾^†gg‘çzj ªŠä6Ê_»~&¹Æ0Ê_«YãÒýiØ™ú»{ L¾†ORÕ©TËtO ð¥NA-` zµãUpQJmÞpÒHÃ}ë®îà€YçÛ±Ž­¨q8O¨Ë{¸ôþÒÒg=æç•Ú¯m®‰áø!^â±ê‹ÓÌõ¥eÏuçæÍî+¹òñ5Înn…ÀýF¹‹¶(­Ý5O“õjÈU#s†R/U_Z¶åņ]`‹” œKßÛM*_0<”‹WÅF©¯øJm?·0Ä¥Ó$2k›`íŽ#£à‰)`çˆãû˜7óK±k±ç¢Ú§ÄÎnÚ"YÖÛôôÄü¶[‚RçÉÂÝÌ$?-ñé¥HL_T*à *sþ£«½ö¤ñ¿ÆoÛ¬-1›ò‡ÍÞÞ*œuÄxï¼TéŒD3&¬ø7šwŠ}·_Wkö@óWŒò\µ³‚†ÉQbƒªº3—õÇNKžw<'6AS sñÆQGÎíK0µ"Û˜3>fdkæäŽvŸ‚ZÀ_ÿý‡g%ªéŸ1Š%‡ý®„ÒÐ?ÿ¿ƒüŸ´à?SÆMøó5€·Óp3§K“l‚[Œ½ìÏv¬â®¨o^c—¥`Nì¶SŽ'|:½ g±tà -%¥7öR¤k'Òî6$lã/Ü\wcTмÓϠ§±«pð›8ùR.J ëšyÑ3Û²7•Ψ‘úÇ\¼:Â/¯xY7ìXtZ6kJÈNöøž­žBbÏìdT’“´¢”¾l[Qƒ±às²•Æî£ÑWúZ.•½¿¸âž\_:§~F‰k@ý2Šåƒˆó§6™Xøí »Ñ}(÷½ÏÃf§ïªûêÈü>]e¶+«Ù"ç&{ÖGÍÍŒs+Ñy¨iÒ÷Å»­hÉãi[7/Æ´ŽFJ¶mnq>ÃéP^SqCQ mp(Èx³ÿQM°€M¡oëµîÎûæ‹îÍ?p«ÌS¸ùèã½³d–¸Íù õ°zNСMWœn³ã/õÖÆº‹•)V^ù¤æEF¼èî¨~Ì·{V­C³ÊUH¦ ‡ŸÓùÔt·ðü'`ðÔ<%·ìr ;-$^䔬þÞì”ÿlÞ%±§ûºjBfÑütW‘#Kƒëƒžª›®]pÎJK’sZ±TàŠùéS/¬#<Ý}߀x/-u}Ñ’¦Ò¬°ðt^²OT¤ îð¦ä¾±DyaEm®¯–nת+ºe¶E-]pøa’v^Ž”²KÅGÞ7ú¡}²¾«Â²Þo”v™»ÚsÇEÞx«üåÒ²ÃmlÓe%në8ÍéTïU™ÖŸx¹âä _wàP"NWët_FYù~ELŸG}r½uÇk©Á—ÎϨ싌L^_(Úð1HDuÝ@ôÈfÎïíÃ…"[ž–¾,ZÓMTÛ{*½$4Ëæ4øaMc%ç‘dlщۻvîB)4½qÊ æÞÛ¡çiP9Z½æýö5 {'§MŒqÎ^óx;“¾¼•æ+>äªÓìx£X¾à}L«î#O›‹“ÅÿS;ßç\‘¢ƒMBÓÄØ;»Ó¶HÚ4cØ8Ï–ŒÃ¿a´S>æÀss¯ˆÞ?¼ç%‚¿AŠBÍaw ¹›V«z]8†žuk)ç'¦‡KÛã|m}1¡Çü²uâM]zÛYk[šYY:zcœ<vÀ/ˆ?›þ?ŠþwcNèœã©¡Á¸ßµ€x¼ø×Vÿ3Ú¤€ÿ0 u6€Ÿ ¾§ÿM³ìÌ]Ui?W÷õz*w§_6že+!d\ÛÑ0ͦޫ*y T~g ž™“~EßUA Ç©õöîœç…Ïì+9®yM¿#.¯ö`÷ÆÄØf›¦þÍq{…FËç¸5íöh ¹máÅ;~–¬ïê«r¾Ó°×¤¹jýq™›y“¾úJ]–ž‰)·…¿ÙÀæý¦ëÛç}g¯¡ŠÍ×\K²éO’tŸA‡VçyÕ¸'‘þ½FCÞ½KÞÌ9™>{7E÷FÅåFYã$񯮠‹‘ú‡Ÿyo©P¾Í]Çž•‹¨F;÷ß?RÙ5˜«°÷ÄcÔsÙ[¥â¤Æ"Ý»f¦æ•a~!¡¡þ˜Ÿ\ ˜øiûÆeoMƒ\nëQÑóU,?ÚEp±ø&.jùÉò±õ4Ï@týb¯Žªµ‹ºüœP˾\âWéÜ\&\p¤Q¦{qì¦f™+Ýø‰„¼ï{ë¢Ìü¥Ë©·•W9;Œãð™Â‡G§I‘ícó¾¥dE§tT~&®Ð{ÔðQæGç‘òÚ¨þ)¯î{Œ¾¶|ŸÿÃÙï]TÑÞ˜ º^ž"Æ?ý$~äž¡§ôª¹²î·ºûG|_W붺Ø$IJ7Š¡TWŸº¿BVüÕÆ×RµËžb[§ÙÙß÷(æ¶5ºÓØTÖÀw\õÆüG›zÓ¿º8(õ]ݰO*$÷ïa‹ù¡'—¶¤I|yà½Ó€[P#Ñ©O ]iÒø'Û¥7º'ɬûZtŽçìnÉ<Î}÷Ú6µ=5ì»1ÿ8ÒÚ’Ê-7¥Ï¨/ÓDðsöó^Ïý‰ê†4ü³õãö¿”b{°ŸœxÒH ƒÝA\”ÑñC1ö[WUG+ SSs[gŒ=êç¦üzøsŸ.Üù¢ÿz}33›B×ÐÀ À€|-  ƒãgøËÚ¤#?§ ¾#ð“k¿Fm7àx²BÊàVÈ#œV¼ðÆKÛ¸#Kä··|S´H 5›ybuöJÓæí¦ “´†×t W,ÔÂ*ç×ô¯Æ^]½¸ûØ¡Ë{Ïjï-{uÁçÔå'ä3eEw^ú‰eaæõh__®åúeÞH£ñÖÔs’æ{o:uä|øù‚y–ûÝ·Zõµßí/¸dx%K§kw‘ú­W¢ó¶‰9ŠÍ)Õ¹Õ¢e¡4`TWr‰çˆF¢ëÍ'k¾Õ&Ü@_²·2ÛuøÔ~‹d_w¥Óý^\p£¬º€2ÏñkÁ×ït Iã6°Õhlõã±M¼<óĹw±kG N×J[å¿pãžÉ¦š¶ÜEâ1 í$E®<>#¶$¢'²Ø´3ÐóŠ«"8}%hÝ6¼òцÐF%üž¸¡§6yÔ™¸'éÙ–·¦k¸¤¬t~!`_•{ס+»ŽkEgÆyû¾h“wª5áqó1šÊ_¾?Lâ Yd¨º(?HÆçòÈÊÖ7î8Z* ­õûø¼Q ¥\½.õ ¬é4Y'_v8$[ó1bú–þS 6Åê*¯ ë¨uÇ€ÃPó}ÙX0ûb³*5Œ"ÿL 0T>bTt fZÞ'}ÇÃaêÅs_[Í7zµ`O¹oLֳ㛽@I¿yÂOo|4s4üûô@žë;ï[¾3I>~YÈV—/wªž{#cdಛêŽäŠM‹ÅÒçúË«‡èZâœÊ\G»ÖšÎ½°]iH÷ûÜ¥]^7¨õL\v•í²Þ1ªçvÌ·c2=64Lï¢î6©½s÷ÒÆÂ*›o½·Ý_Ê9¾ñÅ×yÕÌ» ¾Oåy8h5$áåÓàÚ€l²tßÎïº:‚¨f]¥xEëÝŒÙ:·xή¡9KŠ·wHϲõ2Ì)]o<Èyj,c\«Øo{iuÿÎÝZ=nUª&íìû¼ìá‹;é2¹²—'“Ø;ƒ·OoIÜ-¶üÕÕsï°>-ÙܹI¶)‘ãñ¿&Q1ºŠû£>Û ]/‚ÿÁµɾ):CÃÿÛâEá›»)cä}ƒJâÕm#Lýp¾Vä<Ó0úD{keS]ë#v¶>?¹ð×Ã_W­øìÇý[@ôïäšååø¯„kÿ 4€‰Sÿmò€ÿ4 û&ÀÏ œ1™‹½ZÆýù ^>¸ÝaGÜ ÏûË—dï\¯ñ¶rÉ–u•›KªÄÕuO‹ %l>¤§<8“ºg™Ã&Ÿ”Ö—¬£-Ö<¾#í{ ŸVTm¡¾øÑ"ãÙsêTÐí3.¬›YŸê›¸õÌÇCܽù·Ù…”9Œ¾ªÝU#q·ž*/1!*™´xëV>>[ºgKïqÓU/óžd†S>Ÿ:0¼Çâ¨Û£þÊ{žs¢Ù¸6ØIÅ­û´Ýš*üA˜Ãg±@’bL‚ÆëCR)•›ñ5ç?e7¾;~³ïÕ1¡5wOÈ´~YÓ±|>ÛÝÀö£_*bc¯,É[µ·6v!ï{ò@á°ár§¸skí›ÇdTÖ’¨†œµ¹Vì—J}¦Œ)ï7(Q&¶¿Ý»ì]ܺ…¹³«µwû®8l"âÓ•èÙ¶€oÀñ6ÿj#Sv‰žêšÉ¨9”¨<ÊÐç¤h oKGN´…’îó]özfàÂÔ ¯´OëB¢ü}κû% ±?±Ъ}d÷›ÝÇ÷& |òlé8µpéãQWË5—É*JÌTæ¾±Y7v]èt©õ覀esâ ¸kò†¯_k6½Çk¤ùÙÞ<þ‡K„Óæ5™ÚÄ-²9l mÙ]*µMMjAó“ä Ò+½íElîŠ'åíxf²Û¹úËâæKo ¹Inq~3*íVòû²†)aït*BHžkeçQYÚ:(9ø¦úªbÍ÷ÛnŸ+{ Ä?îR¸¬ù™ëÿíñ•o•ÚSŠF¦»Ñ*‘»gFÏÎHÕ/ ¨N ÉûN>K?P÷ðî£GÑævsÂD¤…Þ¹Y{'ë©tÝÚÑ=¯q±÷MdLíPÍÏH6½ò\kSÐDٲﱖ“Ç_õ~~‰DTš¯.Øè¤êézÝMQt‡ÛÚç:ö3ÖõŽÇíûD]ÏÝïPë« R£ü«A®_>}ÇŽšóP_½Ž2²&éqˆ6#ßÓÌÒ“äFĆ[ÆE¸ùuUs²3Ó´65·qôĸüÌZÀ_bûŽ¡˜Ž^‡ýÊÖõ§EQ)q”àÂϬ¬øI×™‚†X½&"Tÿ¯´IÍêûǃþoóþ!Mi²Ïôo·r€)D€Uf—#® €0V¡ÝÈ í=x€JD´ílòA$èhä?þƒ„,@™H$ÒŽ¡-ˆ$"ÜAÖ'À—DD. àÑ8…¶ @ˆ‹ ’@Ú“@n4mt!´w8ífD4Ú~D,ÆŸLd>(PÇëdеdÓmïý…ˆ<3íäéýŸ ¯hÿHHÿ ×€¯M{;øeéçÑ´4úÚëÑvÐ: ziôC AÛJˆ$ÚíÔyÄñØCmÿÏù_´R"Œ?½w`x˜oÅÒè»é]H ŒSèøÿ9™2®àÈ$úA0þH¿04üÉô;Ð0Æ©Týþþ!Ž?Þêo‡ñ'‘ð•iã°¤CFëo²N”´%&PD"2ñÄIáŒå…‰ŒaΊ?r"ËmðdÒ„Ý?ê®ñ ¿ñÿMÿSÛª¦üÿAChêÏvýeöÿ¿©LîÒÚTkÐàÆ’rfJ{"BÝÄ>ƒÆh,H…öã 4êgöŒ“aõQ?ð±Ð€ÆfIS|0þ~ˆú€¬cœ#üHLb#`1ž‘Ь0 È´=>>¡»&¸AE <Úzv<š"E´@Óçi§A\.ì‰,ƒŸ…ïç€$õ… ðƒN#ÂëïC…Ø`ZM >„ Âü AÜç ñ{’'!êLŒO…v¶ÊŒA ˆÃOHÁ“ˆ, i"2x2¤ÑÀzá‡ÐC€9Ä3ºÐc0a² (Wƒnˆ’“”€#@ÝE&ÁÖÌ/þr  ~r<~s&ÿfí-F' þäñGëf"SbÐ;„ aF¿ùÐð'1lD__‹aEà þÍü£ @ùøÓð§[ñþp_24Zßé:%K3Á$ÑÁ„ ›þ´ŒSþ(ñ™ÃŸÅD–x–³?æô,ͺðÿßô?…íï-ÿÿTø+Åÿdmûûó¿ØÃ”jpü‡öTX•®‡C*/Hw€1äú„xBX Õ—ÈÐ@†ëŸNý Ñ{‰´Ë“è΂7B§3hìÓÈŸêG†] ý>D‹¡øCN@ˆ‘ÀöÑâ<‚h<Ä»úBOâH|¨T:çp…ÄÒÙx«¾Ï|dþ¦Ä La30ÁH_‡Mû‡yÀc ?4@båøýÓ¹" 4vF[aÆAã! ü—i@^ìÉ…)å¥ô®Áá©$–N¼?6¡÷EðÿÓQÎâFsÃø3ܯ+þ öOf!Ø'ŒÁøÿŸ@šÜ þЇÀ0´5ЇJwD ⸠„æN J1ÌAÓfàO Cž)ò¤ð‡ã5ÆVüYb†:K ™?Ð&ôßø¥ßøÿ¦ÿ)kwùÿc øÃ–ÿn›b`â(˜B  ¡KHmþ³4:×dêˆÄ'àHd;dãáP¾Ê@ð&SaUÍ#ý¡;û Ã!ÝÅ=˜Æ°˜@$½:öpc4Ž£Œ5púüŒ½Ð͈°»ŽD‚€tV Œ²ö¹0AX‰‡c{ ȸâfj;€ð’ã@{š @„d  ‘1àOM€©ä¥ ‹h|˜±{Ì”~ Xþ,{&ˆà?þt¦I;ÆŸq4ýCø3ŽC ‡E…NÄ߯Ÿàƒ §] çL%1Ø"ˆ}"DÆã(¬b˜Çÿ™wEnDDÀ„æ¤ðG^ÁŸµM0üé«câN;ðO0îïoüÓÿµ¿¿ü§q–¿RüOöþ“Sþì¬mÊ4€J¦QO2µ_¦QÏé,90 „ÒyðxdQ–Yü ˆ( ¬>Vt¡¢Z{“ýa–;ÁúǬ38§Á»ÄR`Eƒˆ\ƒò‡\|xÇpšùGðikÖ-†éJ íÂBŸˆD‚j8(R0ôt–²M˜fuzKšþM%Ñ¥ýÕY= Öý@Ú;$;0)3/­±ºH Dú]IÈu< Yšð=ˆÈðÿܘ:PÆ|@Ó™[˜FHdýï‚P®vÿ#³×X· øãÆÁ‡äGbî'@ìŸaý1­sèH<ç’8œ?B½!ü X÷ái‚Ρ¾\hAøÓ‰û‡®K’ ¤ò2'ÄŠ'…?C ˆÈXúC¾+0Nh°*€øW ÀÀoüÓÿ”´_AþÙ£cë©øŸ´dÿÑa/@%È”¸P6 œËÏð胈ZÀêà§k¢.h”0ÑõØ÷ŒˆëXò,Mm†aò4€÷.ˆ Ò­À°þÇl%èžµFÛ‹Á€d"ƒkŽAÛðAEЈãíÂ`‚ÆÌ"«GGf5bÆ(ž~,ï€9O¥0^`äˆ3åÈÜ@ &^"‰…»ˆ¬4ÀôŽée<žH‚Ý€ ž@÷Ò}€ PÆ &6N)¤±AK7¦&˜€ð& ±B{ciÝ­=8ñ‡á>3'¸S|~‚õG¿"¼’æ …—`?è|t‘@¢áùn±þcÖÑBR°Æ ‚tD‰H ‚+”@_Â'‹?²‘Žÿ8›þàufþÛß"ðkâÿ›þVû%äÿD ௗÿS¯üA˜  œ%/ !ØK÷#NtðCɶT†ò›(¤ñ®ÿ?Ä=éú<’þ™ X ¤€( lD u\>¦ÅFטþ6"Æüü š’¼qþð‚7ÅŸvi(?0„¦ÕBçR ìk…ÊƨÁŠÇX~,[ÀQÈLºg¨!LO ‹§‘.“i²„‘* qe@À8ÖÛŽxÆ ]‡@þh€ÿMP:FT0´L¦9Ñ[…ñ'2Æ1Rò¯/Ë5™ø B+xláàZ8E¡ÒÁbâ\áûÌ»B2‹ÃdàïGƒÇ“‰?@¢ých©ˆ%"Þb‰Á¹!4IpTñÀ·Â“˜C”€#Nfºë„DÀ±!Ë"ÝÇ“N.ð_Ñ~MüÓÿÏj¿ˆü§ü Äÿ¤Ÿá?Q&ªS¡TÒÉoÌD'RX×Y]EÀnBV¢3¦ÉþÑ0‡3MíeêÆp50€…òm p dýeYð¥ˆ4:¡­ÐL(y€Ž?‘iÔ!Ñc¸¨‹é±"0Rß!]œ,þÈðíÃø3m>ÆÑ?ÐX®IpÜ ~Ð&(¿ñøMÿ?»ý2òŸN =þ/~– öÉ÷oz¦B¨dføÓ]]rN$±èÉŒÝîÁæþ˜|'à™åƒc5ÿ¬ŽBcì6€93ïD¥™þŒ¼ äp@£¨ª]•Íih¼K²ÇhtFšèædØú°=ÕWÌݰ€@j/ΠR 1Ñ ï<úÒÈÃ+€ÊÔÃñ,ÉŸŒõ€>ÿqèÚs¢ ûôÑ)a¸ŒW8I‡œm ï^Ä’c[$VHT{8MdLð2.!¤W+€t¹R L ¤q`–2 8ßÖ€ ÏXã‰TÄ=‰ÔÑLÈ‚˜ÒÀÏç,þ_¦q6. ŒàÇàþðloíBâØ¬+°éǰ÷`âÏÂÝf#¼†uiø™–tCðõ…¼ûT"ãv4ü}iø£)ð}høÓx4ù”Ñi1ìiø»GRb€¾ÀØ+ ƒ‹^å‚ÀJ 2ýÿ ô˜“ÄŸQ¦ 7Ø µ‰Á¦`ÐC+˜ÓàŒøƒ6ÁðÿßôÿSÛ¯$ÿǨáï!ÿ'­üDÀÏÖ*&”û#ƒ¬Œ¹‹ G À“VÀ”L`:@AX&PÇgA$Žù¨(ŸÙöDV“Œ@bQÆ…Z•IâÏTÝ”9%ð fà5`’³L¥ð âïý›þZûÕäÿ/©üðÈÉ+U€Ÿ©TÐ- 906–4¸»qPj,ó˜M ÛóˆÃ#HÆ“ˆã&Kg¹”p àºh¤žš¶ìå” WÒMÿ§ý"svЬ:G ; žÁPüDÓMÜý‚ÆhøXŠ?D÷Ì@<…uRp€ÈRñƒü♉G´sé¡BÆ‘‘ÕLÈ ¦«öÌ`ºÒ0¾kÄLfˆ Œ~™óÆCó@y`pò´êt(èBÎ`Jó€úo†Cgíð ˜Æc)d&Ïá‘Ó:þc§0–ö?Öÿ,»ìq„)#PH… 27ò!Cøûéá])$\,ò¦1i46àiøDâÖ'Iƒ,D H…;Ž?½/áü"ÓãH³X‘)€'‡?4‘À8iΨ‡0~€q²h“›¿ôÏÆß“BòúMÿ?«ý¢òÿo¡üЮÿ³Cÿà¬áçi•ÌÙ0\€1Ó/# Qµ™Iÿ0o`Õ˜Ûh‹Hù#Éú¶‰^ö7n.@$<@')¨–AD8 YÚ3Ô¾6€s £BòŸž€ €ÁBÆšN€Æ˜ÜCHÐLBd¦ñ€wŽ€Äx¬?z„´}–)AÇüô<™Å,¡3 ˜hÿX "ì›îÑËf°˜ÎXÊ€ˆ0±Ó¤»¡0è 8w Ê&B|€pÐÍ(¾U&7§U0¦Ù×0þã9>½c,Ÿ^s͸"ÝÈ#0&|g½ ý 4ÌÇáO„²À 0þ0xXþ Œ<Éþ~~Фðã&â<‚I 8Ëê1çM i£n†Ú!ü¡¾°(¶ÍOfXñ@"O€2K" i¬cXðÿ¡õoƒîAÆŽ?oã}ÿdü}ý X,ð›þNûÕä?0F)½0yÀý¿¸&°‡Ÿ¥T€ˆcŽÀœøqÂK `A8½o\U 0æËý§G™f>d~!¡F" ƒ,èZ 30Ê1Ê$x“à`8<ˆA4NGùÑ8w_¨þnâ¸Ã¡h ÝqéÁ¾JŒW¬lx†BÛè³}²L Jÿ(“àYW‘)@»Gbxt™@ú»ÓK!YèŸÎ=)ó™ †+}€HŸpùF(œÿ;æ¤W±šS™ \:žù3R°AF)R¢ãÏØ7vÈ8v€DþÄ1þã?á®LV [c82™.C üi¢›†¿?âÍ%Ðð§ <2ß­á¼éø‡Pɰ঱Vm ‘Ü~Ú"MfDBÖ>Á+ érdvKdHB6>ý aLðÌŠ7Hk Nè;@^ `Mœ(ìÁñý¸I&¸þ¹øcü©4’Ç¢|ÓÿÏhÿ"ÀæðPcQxœì½\Nïÿ?ÞBTÚ(£­ÐÖRiI% 2J{ï=îuîÕÞSC% %DŠö¤$%Úh’BKI õ¿gïÏ÷~__Ÿëñèç\çÜç\Ïëõz=_ã:‘Àÿ¨Áý˜w(G£÷ÕÀapä¿í ÀßÙømÿtøÒ€b¿üÛCÿcÛëy-GñËuŽ»v¦r²óWvxæƒvg¸P?¬£Þ¿%½ùHçîÜ1×Þ3ìž×õªv"i¢(nÚÀyY'§6:5=VsfP7ÎdÛC¡@Û™]az¥‡ç® g>›^ßuO˜FEP,ºçªó:oªmûÔ;À'å;¼\I)uûøáG,’Nñ/ì¯L¦^0ÖîPfvHn©°_ObQ¬y÷Ù=¥GÏu8®Ôz>»ö€ÓC"FvÝùšª¼ž·û‰z:k…˜HûÓÙ2úÍ]ï?D(^iØ$ôe.‚„ª}EEôH½Ú‰~ùq†ûÔ¹¾JÁ¯kºÃFž_þ(Ì ¶EpñÀΛÞÏrúuÙ–6¹ODït»—äùø…âyµÊnå+%î½fï[€M”ã©ûÄÔo‡ºÛ´ù4Ž&´/%ïÏ ÜåèLœNée£P!;_ê/jLWÄ£¬$Ýt].k"ºS‚TöÁ¾×Re)¼çjöíö¹ÈX}¼](a§ÒÀ…0%[ -RåJSM6¾öÁnv¶Yl["úI²³JR7¿—žÔÚ’ÌœûIû=ÔÓì° Mh¾¾n;$Üï|DÚ;oÒ þ—@ûŒ/­ŸW¸:àÈòú‘é›.›Þ¨ðn’Ûq;5ޝk]RÛÙòÔ/½^±Ynýl-¡6-h’töŠÆ¾éóŒóQ±ÛÍÅJL?ÍyíÜxxû ¡ÉÞ°ÅÍ•<Ù»¯,H»½1‰HÍõ1.´z9/¾å`ãÅÁg‘¶9/'&w4×ÊXGEWsm«TÓ“Àê†Ç3,Ξ í2òÙÆÅß¡¿\g˜|¬™wd¡pÝ2þIg8ùòÊÉéë{מ9×sSëÔÅ ¦• Á„Úí2ƒ‚ý"T$7úœ-•„%ö$Júï¸i8`P4m0u-r”¹v›Ðó½¯×[£3â¬d·Ñ o…œ}³ÿ)ËKËùñu!sÊÒ#<̼ñoÜwBÝ"„YiÄ®§µ^PÊžéÁXº¹Jæ¶Æ¹þÌe×¢|ÄÒH`ð¯la-ÐØ¸§»0^u=ÈÛE+Ö‚¶öË9Rqæln§myÌå´±±ƒ'ØÎø[ñÿlØÿ¤†t§Ý‹ôò¿JþoèŸô…!AAÁA (üWáÿ‡50å‹û@!põ›/k°à?E–)†À`À/"^¢\AùИŠdp£SGS­–ID£®R¶«^=mñA^C²ýŒn¹¶ÌGöÄOÈ„÷)ýcôî¢î…±S··íÍAÍž}Ìš]ZÏe„Ü2Wâ«ú¨Wý¶äD—ÞEè!ÊØ’€Ž¤>’ÊAš¬tÉùÁaâƒE§šÆi{ÂÞðŸé-ƒ¿¨:%sªßpȹd4¸Â4‘’>zßÖþËj›Øm/¢»øŠ› iîš´…}aÕ¦ÓÛ%$9 š]ÚÍÅ×þÁÓ˜¹h8Ï_[ù"´O©ñº@½Û hµKüÅ÷{]@úÅC‡Z…c´ñ{óm·—¬?rÀùñ™^ƒd‹$ŸÒ2l:cßÂÜ®vޝ§¾VlÁò²0ÞtŽ”¦U‚Š©ÉaV”cPâPJŒç„›1N"Ë6èܪz0þñúÀΣÈÍf[§Q¹²K€dÈ­Þ‰ì•é×9¿NǪšdöU]Â+톸6®½–ë˜Þ-FÓn‘§ ¸Ü€Üã>ù‘Z©“-ž¯.ß*Ì–*»Õ2ØÄrßm»)íçéÅJòÜ)—Ô2NŠ82A2ÊÖ_ýpãÊ.«¨lËlÿ à Ä3q~‰°Ò+‰[>dpÁØTo dµ‡f>šºþ˜%:å9EJ¢wµíðøžgž©DÜ£²/:ÞæSÊ ¬Úølhß:ä½ù«jöé2=¹g…ý­`{ÝÒîÐô¿/"†–’¸AVé}Áº½…4í7ÌKc}¨ü0÷´Vï—$58|r—ÁãÛ_ܘ§ÉšmÊ>ŒöoÉ®;¢áºél°nëîë$ŒèÇ™åswî;죮«'i]¿ãîc *Á¢,îݺ$~F?Øz»Nw·ÈtÁÛ}µqÈ SË6Τ° º'sNv{ò6s©Laç·tz¬.,·9›!éjßÜd6u¥¤ùmŒö]ž—yêE´ˆ5à/ª}­IÓãw'Ü©¦!ÂSóŒÚt6™ëôô :˜ÑÆ«ñ?½½ Åñùp¯E†Ð‘í´xüç[•‹jø÷¼Å࿇‰jLJ¾»Âõxj¾+pÖÑû„YG™B–§l]LÌLtlÎYXºyzÙûü"ð§á?::z2gðÔ±”Qù£•üóXGf:&ùúûü2øG5ŒÛïO´˜0(ŽDÿkÿûÿM[Cà§ ¦+@8€að_ÂQñ(ÙÁÝÀæZ› ³:‚%›[^‰±Í ŒoÝ~§L¶t‡îÖ€àÝfS·©¼õ¡1¯Õ:‡·jPif®j®Vþ×I_TÄ\î¿Ù©’Mõô z÷Öªaeµ¢}ôÇÀ¥=‘/™e\‰|›,¯¿5UÛGWZãmú€g (릓æµÁ'/ŠÚÛN6K ïµ ˆ?ª3q[©Xä §Ï¡Iå–Á (½»·©,T8ruMÌí>u¯ddiÂÓM [îøå–¯ì›º?o"þZ¨Q3´]Zkß­¾pA…VÓàÍwFå#=%̧„"u8f„ïYGõ5%ìèS°¡áIQ(®ŠÔß¾¾{}¼[[æaé×ÍÜ1<»Æš¸S¦2u˜öR<„ÀÂRnD$6±MÑWÓÞ¤®¤‹aÝ" öJîÊî‡yˆ®8²ÅëìņOÏnîñzb\ºè“Ø·{kÞ©  NÐo“LRòü¢uk_8¯–[kÍQí#}“0;Á×ûÝç†,xèÆt¿¥¿=ª@ÑV#*Ípæi$¯Äé“È™²¹Jdú¹§*t_â-Ó4ÍL ¬.:]òˆ@x#‰CÌÁuõrP·GúŽwD[¶EŸrˆ’Y`ðu¸H£iói¿mXTZ^§¾T˜DŸ²7ˆw¦„ƒ[šu>QÛístLIM+â ñq/YõÉéó;JQ¨k¯U¯ï¤/êM1ú¨ÁÚa0q”cH²?¡ò³IE[ÄÅ­›]˜úxXâݽ¢“Ø}5f)¦n\¼+!ã Êûúy¾mµGЙqÚõÅ,W¶?ÎmQ»¡£WXÛñxïÙ}«ñ»ÔÀøZpòœúB\ýñ¯©¥û7ÖËœ/³Lé3ïñïCΕUù>üôî¢ÕøËcÛ?^äŸ6[—4±îLI|5Ó«ýçok¶pJµ^³;Qå¥?³I’ŠõŽøð§»û`Íš:/õR¥BžÂ!Û¬fo襢x“ú*?öÕøc$¥÷`¡P`¾‚ ÅãŸ,Ûü¦ƒg3Yc ým*;šI—}´ú£UG- # þJ¾6(0Ú™£~Kâf}ÚÔÖDËÒÐÔÖÆÝÛÕú7âO»'ª{Q\äUÎí-ZOóýMòÉ_ÓÌ*Ó5‹ A€à!A}Wý¡ŽB¯ÁƒþÐ~ž|oã?Ÿøþ«bðTZµ…ÑÙÞÊgžLëKgó:î ¾Ò±\ÿ…—Í(·ÞÝu¶1ÛªŽ)\)ZѶnü$ÏsdeSô#sõ­‰ÈM9uRŽiÊ“ìõêOŸr¼g?:%b-aK¬ßx7/MDð¥V³Â®o2Ô[à>=óö=Ÿïñª5]äâz½%Û6âäƒF_ʹܘû>Š7³¢«wv…nTØã +Iêã_·÷ÓŸ‹Œ¨éìÚDµà–{ñ徚K–q¯®–rI¼ ¶J­’œb|ÿáøçjGÛû‡Øvî¦ØäÍw/Ô.–^â €¨ÿ1’´/Ç|ÉOTšWýYÝ&ݱ˜ÑžG«YùYØÊ dãu-9Õü²ˆí–Ov‰Ž‘Fn`!s¨3/'³b¥io¯71 ¦œ?ש4Ã|ÉÓvtÒ˜<‚y¦Ï¬Äõ°¬Kh+%Ó\tMZýQÚ;¥¼-aÏ®Ü-P”c;§Ø·æ0|ÒU¦Òºt÷fºtÖ¹[g)¤yáéÓuêI-Ÿ;“7¡æ 5ãU#ªxc‚¹[mŽ(ƹç¾î¤¯clÍ ¨˜ð†¤+(9ßc,e¼BZܧ£HJ=I²5%u0Î/8kðˆœÑýöÉñ—ŸÂ麔 ;Õß‚;T%º½=oõÿóQ[z_Ôi®ìSôóQ勈Ä;jGYÙ5Ò2²1¶±w9ºÁþ>ü_ž¬0.Ó¥¸ìò o¸¢å’çß%ÿ©!FiÇ·EC ð¿@ÀH¿UÖ¿· `-€°õkÉÀá+b¿¢ @)ÞØ,ExÝèC†í©õ;?æEE¤¡§7ž)vÒjj%»¾Ç™¼›QçExEg,J„!V›d KÛtõý—ûÙ·[/ÎE¹9GkçM-’£‹O^óßt{]‚|ô³™™ ëoŠ¿¯ä÷Ô’ö•™ãYîT†âco:û8[Ö_Ñ~Rº§-.{Ù5E}®Û~ðصzÖ¡"ó‡ÝäÇw…nßÅøtá¡=|•! †¤Ú#¹Íó^¥RQU!àL*Ñ7LN UÞÛ a²CKbd5:%=t†­G¢ñRÕ.åK‘‰›UëîPšš$˜éÐØü(›ÿÓäx¤T™Ü“èaoóæ™sæÂÅö4ŸwÅøŽ^°lx{œ5¢7'hHŸ)HÛL¦Õ.ÏðÆhÆ”=MÍî®ÁJ&ž6r§ç¾|$JgÚA¹G.§k޼;ðÞ…_ŒE”(~ly±êÓ¹ûᕇùú•´”æÞ”.©ÎQºE§¹à5Ó¶•ájÒÿ/«øÞ£ï#b¥Ãë.î~|]°\V<ímˆÂAæy‹Àùgö—ZûI Z¢Q•÷?;…_kHc+†GœÞ¸ Ù|÷ÔMEx£ »dÿ¨?´Ï/(8Öê$ • L{:Ö­]Rõžà‡@^ä»ÄŽðD·ëýg®h?y”»à[öTÏðn~"^»¿×W’¯I9ÎÈe{õƒçAAI‚’¢1ëhI™ÇïO‡QXÁE“É*`ŒG·ƒß¢Päv‘«-´¥|äÞyçx®/TAôœ„uõÉòóÞ&FׇwÏð?Ú>Rê-Z.iÞËÆh ;¢ªúhcšQãósÓ³íÜû…ìÎFÑ)&|ÿæÓÎÐÃÍÖ2î_D‚½,JÙö‡zm[d7{n ´ËÏy¥S“wT q¾V 4wkfþÐnꩽRŸŸ@ã.Å_„Öë*p~j¾Äq?ÒUÚ/ZìU0ÓÄZðgá˜ç»{/~OÏw>~ÂnöRÐe]|%ü"M ;ªu¡]Œ.ƒvJô°i¦Ç䃅¼JAF‹7 ‹Ø{|ïĬe²ß-ÔLr´ >á©ôÖißó,a|ôcuÐx²Ûn‡ ó“±bm¡£%^Lòæ8k˜Y¼³8·!íñ^nyŸøZ7ž¼CïB:?Ùxg¦ê¸÷±ô´Þ$kêÓg‚A#'ùæåæU6vÍÜæ– Ø¶MfÊlC²½™Õ£òYcN¦:¾‡Rï% ²îŸeS¹VÔküî€ -ÄÃŒÙÌ3«qHfÝ¥Ér_µ‡mžàMž# f<›´MrRwßÞ?÷JãøQi¸++¸"ÀXu YªÐ•õÇjsn3lBo𩼾®jƒ)gÖq1/æ7Ýõ¼®§YÇjGdY"NõÍ–ØÂ#N~JYœ¬8ÔTRÂ`¨BK•bÂãWkÄ’ÜlÍs÷»3õ«v™ðÏzIjïŸtsí(뉀iªÔHC¾¯~éX][Tâ4`g'Wjð¶» `q¯·M©ûqãÓ Ÿ”oàóÓI€1JÐæƒ7» U(©2$O}§ÅC0—qÄvÏ_%ÿ%nZ¦¹6‰Ðÿ€”üo"`Êï›0ŽúeÿËà'Êö:µ}²¢šÝ•u¹Q6œvî òˆ|Žòtôvþ£ŒÌU»„ªÚÚÝ”¶ÜÚV­³?êxˆôÍ6*ç’ÃïûŸ9 Òz–Óàu±=‡Ú2Jªñå`nªÜs£Ê7´÷æ©ÆI©ów†„KˆM8¾‡«VÒ(Ÿ?ÈRÐê²1G‹¯1[\ÖE˜Î”åKê3%½ŠÅùlÒbiu@n¯ˆºå]Jþ ‘äPþ»Íg6yÕ¾È8nóÍ+²>àÃCkÒŒÉû˜æ¡]g?–ØÉáâùiÇË~#dyî›Ñþì(»Ú Õë¤6i•*ô¤ÓOOuœpïï=ÚMn¯´^w¿ê𓾫MdæïÑO{'/º o©-h™“þ\±‡»i#ñ¦yö„=iýÓûÛ „¦A$7ŒYÖ±çŽñ¿#§qÝѵÃzè$ÌsÃa‘ò]6 åoÀÊ]ú¼ƒ:*tÖ…+Z©æòn¾výé¾<šf¹BR‹—ìÞç²1äÉ£ºL' ú¨½H×R‰6nV‹ÑlBE¤2õ[ŠIŸ¸i_³(šì-juõ…Þ.Uy†“»îŸî#bdnÁ ºR¥©ä ‰ìšÑÂm3ƒ°åõ“ `¾Øç¦¹KÊñUò¶ñù”…ÑéI²ñü$;%%ÖÍÃyÛ@£>ϼ{³Z§G÷çI eVîÚÔ0Õ”Ç:mœß—ò.Ÿ tïÔÆù1U†R vKÖt¦±FUÄ®}Y‡8wIîÝ¡°ñËR,Þ7vS8 ûU‚y¢Æ_WzEоÀm°i»«c2Å'úëI®ÌYÜÏOà†EÍ›Ó?.䵜;VÎX üþYœÜ/÷yÙxÈsVÕ8l½kyu¨Œ"_ý|å—P9Õ[Npg.nþ¢>&g}ú+ Æî6Æv§mŒúì‡8âXhè¨Yþœ.‘ZïuÔà0UÞ¬ìšðW‹'n+鼨ÎÖÄfËhîÀ’þ™'š²°N,ø+ü_0Tœ“ºNyP§B¼WãÄœ!‡åÄæ™q þV޳:¤ƒ1»Þ Y€£ÁáÉf†.poÀH=gwÚKÓÛÂÌH×ÔÜÄÎÖÍÇÙù'“þÆU™§ì(ª®Š§7Ì&‡ ½ëJ½!G·iûß$ÿ;Ç$„9_ð  0ðoaĵ_7(†Q„¿­ `M€_“ø…Isð…r¨)ã¾—T·™õÆúîk-¶A‹âíõŒt«ï‰oŽÏYl¨øò±Ë„ŽöÐÁœcµ ÍÏ¬ŽŠv$ÞHN—=ÎßVêkûÌÚÖº‰î¡ËüCîˆÃ7Ýù w¨žT6z¶Žyšô’ÃU×ò{6½ »W¾x¸Ì¦ZЈ£âáæ#쨜àa6åáÝå+Ù—ÇkÖÏ^ßw¾5¥mñ E—âÛ7»Kq™é«víŸ)>Þü9еŸ¿aÒõæÄ î„›5›ÃíèT[ƒÕž†lýT7]—txAq3”'~1 rZǧàþ9¦PòæM:š…ÛK>Äî¶3V°e¸Ýâ^ª9jû¡ðцcaKKS•Ùþ³¦o[f†7óÏMq(òξËfÝœ;¯·=†h´n6¡¢…„è-²®«%?öùdÿ§÷ìYÏ-ïIH=†î>/—,=k5B©2k×R4Öb0%¡¼ñfS¹Ê)ñ4Þ膽d°”ôYλWŸbo)GI7Ét÷ÏeÁi„X<ŸXXØru …1ªØ½2¤¨8Áç”<·`~]7A®Pi㓜ž±PH¾¬,Ö*Ó/áú¹$€ Ð(ªIïð)y/-|îºu¥úåS6¯SSj‘ ö®e¼n ¥Ê¸ràÆTOä)±§Nð[3}Ì=ZàÑ\®Ì‘¸°îÌç­ÕXêŠnJ´µSz^mazŸ”w`ß”ƒ¦>åØËfÜ!’™˜‚tãpmâ‹Ý¶#cëhìxZ¯Ä 'Õ‹Í̲S]׌®Ž/©vrA³°Š2¸ìy& ¯ú¢ÉZ³Xƒô±áùrà=ÒÍûŸñ/¨ç*.j‰ØÅ‘¹=^>9*^”9ÉP%:º!Ý,nîºO¹BÕ+ò\aáñ/c(Éò.ߦf;´WætdÆ/7õuÕÙ”»"o,詌­ {qÚv‚ÒÔPú†k§ 7>÷ fÛõÌu²sn£ÆèWø[øÁ©ž²ÙÐm¬ã P̪#࿽|ä‘G³úÿGz&£7uÚ½§oxkná–xÃÍØ8ùºùA}ÒôP®æ¶ºv–ÇÜO™˜Z;z‚mn-àŸ„ÿ ÖçVygœçͲêg¨úIUlhz¯ÆyãIoû˜i¶£ÙÝrö"×­âE½‰—4v^Z8 {ÒLËÄåßsÂühMLz——ã1m‰…Óüòe{ i"ZÐ ­àžt¹Ò¾þÃå\Â"¯$f­Â¯yw!!;„ºÀÆ&Ú3ê-#uªü‚pêB›´¸eºñ~)m«À>F­Ê^³_ PúmgÀqYÇFBc"2uëÝË™†5¬…žµ% ÛPmÏÕ&Š!ç.ƒ·¢‡!T |]G?Üòˆg~=D·¿|ádÃçU'Ô]y0ëä Û˽÷)M^¶Úáè$ŸË4»$/>¼3ªLî­Ý ¯NxÂÐF*Äg û#îqHïŸ!w¸BÕG#ÄO)°ùó<ÓW`SMG’w÷®ÄS˜üµ‡°Ye·çpÙ§w†á\æýæ!ºg·B+}ü·ÊP­Û5Yx™9†ÖvÛ™ä“A|é-îìyw•rÒS«]6Jño¹ß•«lûn﹄-MåL®ü³g“–qÆëäýùò祿³¨“üÔo@§±˜ÕúFü´äÓY‘È¡äâ.›êòáÚ—{Èê5Tê¦h-ŠŒ‚§Ñú ÿ ·LµmÝ[±È~f­öž=y1ºk¯™²ìâ­gYÚp~‡ÙW[I¶^En71 {¤Æ`_fÎ3Ô£§òÉ%ë ´€Úq^j¦)~7Æ 7?ž¬¿&üOÔŒOÅ÷® ’|üxƒzê¹m$!÷8+… ªÙ³xµLË|…¿ÈƱ& ýà¢Óswbö¿Äão)=ëæpU0åö þÖjÔˆ…Û{²Ì{%gï˜Øûd'»²Cy= :1‘¦Æ~ö†ÇLOØšÚ9z{þÔZÀ? ÿçy TÅe¯v׌$çknš;'¤¡ñ>¹çYyâüß$ÿŠ!ñþnè°PTo˜ï_² B|×ýÇ6ùI€_A~&ð3I€kóÊO _V*ùr}á,!I•:úªÁüú£†[ìD=ÊŠi:ÛÒßÓxD÷þw ºŽÒ"¤ö!¥íÍ‘^ˆøãÆÑ¢ÇÆûª5PÏ…'Li0‡˜£ ¹?·5ܶ5+Fý`¡ÊÙÅCÈ‹ˆaÊßdnþ!ΠÙ|C°·Ì¡ŠÀ“foÞZœ~7s v$Ô’´+ûqÿK{²’)VþDÛþ“#ç|µAz£ûX© !G„´„{àrÒ—™‰¼jzØkzúcÅ Ê}(Ì/ô|畦h­7‡ûÛ£{£ºò-ŸÚÍÜ}‘ß·îž²@Bî#¯PþoÑ ³Njz~»ê´­õbÈì²Vä¦[Ï>/ƒ÷¼Z—Gºnš%žóÏ‚êTÚÖz½<ý£Uf À/׫ŽÜ žà¿ÍJq‹2œ»ðŇ޽âÇcϸÖy—º±{›Q¶ òîBÃöÝOÒ£‚·ÙŠÎ[èªO“µÇ CI,Hät>JWÄWiíºÑ?qýŒûüâp‰÷MáG{­f$¯ì®>»Úd£¦¨ÆÝ²Mê…àÊ‚®Fòµò79;üNÆèKZ¤Ù^G…øC¢ÑPÈ'&%Æo\ÛT*1…ÔHU¿dU=û8áa-Õ9µ>íõø÷¹d/­Ÿ°ew07YG×ýœ5s‘éõ´ÜaÇf—Åǘà-E’¦vŽ~)kùìêÂ.°…úœçÃ)wÛö¶úÊ-ÌÙÐäÔ[„=B³Ix"b`€™ÑƒßËÓ›¼¡oô}?Tèg¼Tñà‹ß°ÀÏMsò ³2ÓÎÝöÛÔÛôøæïŒ RÞîq?5óŸñ1CùÑéåj Á™9:ç=/}ÎuIMu&žD¡¸›o4a¶çíj Õ1ÏÆ‡Ò¡§î°“ªí è$ùÌ$àsÒ”æÑ뻆 äîµg¯ ÿ‰â±¹}—rýDã=G3¤º«ÇH;oÌs¿½s³A¶èÔWø?â³o%+êïMj%c˜±Åãÿm\Ñ«âÎ^7̃ÁÿÓV_žíŸhPûg óf&Áå@Åé¡ümo©ûÛ8kÚ9X™jYšØÙ¸‚\~b-à„ÿÔÛÊçͶ¦ÊšÂG}´ÎV¹ñÐt‡Î™ªŽÞzNzþó_$ÿÑúÒ©.—|ýý‚ÿе€æû*ý±ehÔïa0øZ2¿ˆ¬*üqaN~j8=º‘òö°{hïÃ’VÐ=’΃2ÑÓÞ¨ÃV–lºmOòŒÌSl3tuîtGe“$pøÉö~†·>mWDÐ’ð»Žï‡ÊnwwòbÚÕéD§ÁÛÔ³«žÈ¸íØDstrb|v£8sÒ^gê‡åä~”1–J°P±dL$C‹ýLãÙè»—¹gsjר¸r³Ñ+¦>IÖýò*TêìÍcW„‚s¤K&†ÞÓ»­3tgØÐÞVãÂZ¤ì3y…«­}?'¥ë^žJ»Š®"V‡á6›GšŽ)…æì©ÀBÕsW>!ð]¦b“÷÷2ß±ôù†‘ĉÈ©pK7Ù[ R9fl¯­›êvìè8vD¹˜O£«v„Ûúär÷Ïõ$¢þ4¬×Æs¹˜ÒŸ^Ý¢3Ått7ã†Ýž¥G^™>šíÔ>”¬å6 >š‘ƒ¡'<³} ¸ «á7t óÜ„T_<ÚiÁô«@öÈSǾÖðÏŸ§HÓy" ÖžH—½ch·©Tà}Y¶Yêáˆ;ãÕ±/ù5wÑr²>þ0„"‰[Kæ‹üŠ‘B¬jŸ¥â&¨ii¸†^ŽfHbX p ÿ(°P¶Ùu~«ç¶õ¼Ó»˜ RÇ)Sã{sz®Á‡¥Ö{¹}ïã#;\B=ãÞë¾ã•=·E‘ )zy}§² "÷¡æ–ò}ñ½:wUé§7h'kY]Ðéܸ“×­ù¼X–tŠ—[¿ò#“ÂÙ#6áZÚå²(“¯=B÷?dd:µ¤cX˜¬KÆLæu>È…ìvpDºÜðníØQ¥MÔµš”’}†ô|'2ÿ'üŽ?1Lßñ²>(O4Z)`\}ÜOõ9Ii×þ]f…“ ô FèÇê#5ÛžÒƒ•T=‰l·=w³IëZY]µÉÈ#Ÿ<Ù¾çë¢xÒñ¿{;ÂåšØø¾GâcCõ Á=Ú2ÐGŠîªÑ¶_áŸÜqCqÒØ^"‘BÒZ"ÉHÀ?åiÅ&:6ç{dÇ0øw¢ƒw.è uÂ>ˆ¿AŸµ¾šèkjxy`QgÃ<üÍ|íôMôŒ lM¬<}~x-à„?½*À6sð mžœ"sdôË@­¾Ü AjÛÚߦ1[XMÌþ=ò3) ;v&õ\PLH_Xà_°ð›µ_·ßX°¶À/Ž`ßðü`1+1Rz_#@j¥qÓ‡Œ¨R<ŒÌœt¯v†ºìÊ<Ë#% w¢DЦ=³¡Œø\®¨xí¸§A—ø"ùí»goVÝ™ ±;¼AœÆé”åÇd!è)Hý^ü̺Gf)rŸ·qYou©4¼Ð·ŸŠÓõ@ý²êÉÝw-œNdñ—s…¬Ï Ðì~¯ðž,X´W!•Q‚ŠÊ‹l$©=m°åUIç3 {’ä'Kòe}O_7sŽ2ù$ç!ûÒl0 wÓÜÎz“QÉÍ­NóÌañ€~Y£ýÎÝe7>»ÖîØÏzªÍo¨ÜûߦÜg›rÆ'¬_Þ/MÚìÒ•w“ÄLJ l.°`*`þlH ©äüÝï:™ÎN-²`Û3/X÷õè¾PµQ›JÒ?v]{¥Ì¡Øòá\õL]Ò³£÷Í'> mÕŠ¸ÜàùeòLäáòÖãBœvã³g/d2 ׸–}*Hµââ1‘Ð×Y{·ñÉX~ô˜nãdËD2G¿)îr¶dih·v£(¿ã~U¼½Z°–å]Œª i3XÑ¿RF-õè['”sµíTÃ+·pÓ3r{Çr·çLa,1 –”½¢Tà–ãçîñƒe—ýòËés'}k‚“ÀöÞTˆ*5‹Û§}ùJâåÑ$Ëg§ÎÐ%sLêŠGqöŸ¸¿ø¦\Å^ƒl# .|(šeçN×På?p¿›Sñ>Ï®p±YSr¯$³­Ìçè·e2ŽRH‘?–¼ðà‰:µÃ/±Œƒ”G­Â³Œ@Yîl}€äÞ¶'mâœØØ(ÛøBÇi©¦ñõ¬=>w¤|×…)Z' 5ív^?þsðG;]òd«Ý¹V¿E£î9צÃf{¨ûm2>î%=›ßPýÉ¿”|DH–N6,æø}- ôÍÚ¿oò»Öþ"°¶"ü!ø×^ ˆPßõ9ÀÞÊ!Œ,«LÙ'wUñ•Ìâ€Jeñ±œ¤ÛILN¼cc?´.OZ ÄU’ŠQ;°^û­L'•¾¸ƒHà3QÐ+§áö .¨cÀ{Ç=#¨xJÚ Nž9&cÃU;¥ÜC=¤ÕV²ß¾ò‚¼ÁµgãVÇs\¤ãzÈ?=Pˆq-OSÉàó-8!^pkÚQõE0İ&öEïøèv†ŒO%Øv÷ª j¥Î¤Ú™fõ2$m«Ûnº›…ƒÁN,áÞ‘ N½îg u9åM­9¦ì»M²$ød´äIèJØ4eÌQÙÃ"½tÓ…‡.›Ž>‰ã«?:yröÖ­—ƒïúüúW®£‰œy ™ñeÔ»@í{G/´ä ¤*H U¶”a°™TP|6#ªmΟx1ù ×õIíºë;õ¥?qQ…ú‡¦¿ðéºDk¼öq/Œ³1cÏ‚mäè5mŒƒ6fö¤]ÝG(´Uî‚ý¬ºƒ<® ˜¦fx™rÞeÿpZëc®Y½‚±½AsT˜]*ÄÿÇV$sm ãºÍâÄ®ó6Ò,M&øæÛ~ÝD®YùĆxºEé!_«T•ço¨+Oì)‚×켞 1AHFŽxTûí|39Rýô6‰òÕÍÆHøÆI7݃.†yWq­S=«Ðº®|ú²…ä—‡+Ò8鎢s¾C¶¤ù®ÝE=å{L·kƒ¦·@S¡Ô!ƒ&È|“p×’š™» SëI} Áh”å¨xÙu´¶ÿ+ü· ZÉðFµ§‰ÚBÞ!zÓˆIyý¬rúUVép夯ÁÚ_rdž ¾ð(âɲÑ8˜ÂtU‘I„aTµŽ-Á£üÄã»Ä(LÉ+Ö¥ò®ÿ­1¾AÔ­óYѦ=‡ÈgFôu7Pìí =¹a~¡Þ™7à+ü½^ˆ>~ϳÝÒ jÕ}0RIÀßñT§P~ÒÑ;›‡±ø?“¥¾g°y†ÂCMõA½ÉéüèHS/À;Ô$Ðí5w?fg}ÚÀÂÂÀÆÆÅÇíÇÖþ1ø{˜ÏŒÅ’ÓÜÜ£8§Uô±Ê'BâÚ2øÄ½õvÜჼ{/é]ù«ä¿NÁØÎü¦g¸?"0(ú?]ðݵ_·ßV°Æ À/#?Ÿð¹Ô{­ñ¸ÒÂn£gÃåî÷‡í˜%Ú¹cT½dô)ÔŸY³_ ©;Î_Ær÷œ¡‘9ýñ0ÄÎæ9»‘ÉÍ¡O­BIÒ4ò8˜ÜØŸŽc¢5µŠ%‡n#7 à8óÅ•2È·M›Rý“ÁpêØäHAcSÙá Ôz‡U oU,4Uœ>ßOÿþæpGW{öÞ<>›v Ëwg«™=O.~¶‰)¥cH4˜)åÜtIÙ"È@çéÐǃ· o)sß™qÜ>!»gÀzʵÊYž3“ä3Õ¶ {ºOê+÷j]öȉßÏ·›æH&é‰õ½ÓE[ÅB%`^ÆiG²" ~‘A>°`æi½ä ïjÎ_™y]{%;d:{ÞõòCsÀ‡ÈfŇJóè“ÎÖ­=(«oÙ”šÒó²“qÒi&22ÌÒÞ¸Lºèøüjðv„j€pVÅV¡ËrL“žžpŽ?‰Ðï–qÞø®nRŸÎØU´(âÓ(yܦ€h’¾žz÷eƤ•צb¡ «-*^dø[ª²yKgìà½ëÿ–.‹üA²J›PÃŽζKÙÅÈß5ÿ ÿ…þçæ»ÇŸ|. lä8G¦HÀÿÉgSwŠÞ6£$ü›š Zl¶hSXÈî1É;- ;iqs@ÑVY™ZP{WG+s]CkG7'—(øcðyêÍ1 Sð Ì‘«§Jë2ÙhÄÒ½1>)º…m,ÁgÓ˜°ô4ÿÌ_$ÿ’Ð /“„“IÁ~!A°ÿÃk¡ ¸ÿ¿±ë¸2€ßðHà5þÑÒ¯9°ø±µ€ëÆ.‰¹]’æQ™ñ+//Oé¾eðy±Í-ÿôñgšœc†¡åð$L§7ó$.™lƒ&ö·ÄdËêcR¿H®»ñ$PïY[Ó|˜¯)Uÿž=­pÁwª¬îh¹gúSF¼|ú%O³Æ‰[ƒ_}ó¦‰ÒÂìõ–ªÛ> °òe¿‘•þ˜uMÏ.‰*¦VŸ&ÏÊ’¼©Aá\Ø™'1UÕË/Šc5âæiöUÕžO8œ¤Ûseï]ª»gO[3õ™wSIÏkN¤îQ†6GÔ45 "*îWtö ÛE4XeŒqÉa¶z¡ù~áÀ3!*x t »fÆ„™·LÏɼ›EúöåÁW"ÚCn7Y‡ÏF³¿uñ kwFpY%XhOŒÎÑ4«‚,’²Jú'î›wšzNƒ|G-™œÄ½½)lAYhÇnÄSõ6¡* ôˆû‡^: ÙeÊŸ2Ê餢ºð¾6xDš¢2cnyùáwÛSæ^ÞT“jÔãOH,8ùa R‰=‹_š3Z•½“¬ÐÉÜdγ¯öX<ÝŸ}!Jž¿À쌘; º{ËV>Í4Mº"%¥Ü°>ÁÝŠbz†ÊHþS¥'Tàd\¨Í5Ûðóàˆ/Èš“ôõ¼;:„Q’ª™-y^S2›T2?¢RS!³Û€˜+Y’*®Uú‰ðwîºý ý%ŸÎ –ôœ«ÎXL5NÚ>e]¨Ä*²mÒ¹™»tâi¥NÊ®ã5²âÓ ªñfÖ;\©#/{å=í°m5ËͺÖÐ)Þåž(TyÊ ŠÚÂsÌS»úrì™Ò&)ç3á×?ƒµ§5,c8Ó¶ì¿~¶hsc;ÉË@¹¥²h'b†¦–óH÷¦zZc„2Âç–ÎDܧŽkÜ¢´gzY*Ê9}Qj¸|‚ô|×Φ¾Jfok— LVÁ°pÃ’™¼1áµâ‰f2{º0^%Iù.k‡×§q¬Ÿ_U¿ ¼Èú:f~êküݬ‚iï›+¼0‡É’/‚,ø£OYLºÞÚËYï9‡Á¿9û ÜyþKäÖO±¾ïQ‡Ó¢Ã@Vή€W€µÚácidæhg¬mghffãè ²óXsÀŸ‚ Õä´ŠíÌÌY&se-s¶–VZ躟]çrV¼'eàc²÷dÝ:=©ÇúÙ¦|GšòîîiTÌËýä¾uèÛ±ÀE–ÊOÙÚ$¤µ¾{†ù×w¼Hí ›ìc»§.Žšú0¨`{KSã¡óÅû£ª¯j÷s¤VU¥ …$¾‰84²?bÂ{„c„Ø™x"ò˺­c¶ir‹bÈqëÞ/5ä~P¡šÉfV”;3ÕÞ÷:ª;[»mU}®å­ð(7…Íò3kÅÿR®êGÎÏ—h&óÙ§q"ÁE$ïèï]Ÿ=:*{ËM:ø5þâSë®Zo{¬Ç°‘‚Ì‚·”Ž€¿W®m…î5‹Ý\0øÛd%~!Og(a†œ_ÜWÒ£g™’`nãêm€¢Í/èÇYXùÛXœ±U÷ð¥CðŸ ÿ—ß…"| }`س€hž-ý f¦7þL¸žP…í ø@Ðþ˜M`·?Ìiàíˆ9æ€Â p“˜ì¡PØ59{æô(ÂobÌ Ž»(»,'ƒ"øq†Ñø ‰ë ð°@‘p @#ñw…t¹|wâ-`¯÷Ó0~2"gÓ0$ŽùC¬\‰&±æHÂb˜0¢(ÌÁp;°1o0‰ÀüÁaH’ošÊ/Á¿7Ä¡ˆÒEø @°øƒ¡~HÄòVŒ±ãò<†Ahøò­ ±b„V _: ñEâ€ñûa‹|AüqðqŽÄ€Å7ë,–ñG!p nn¬OŸhÜ¸ÙÆbÏŠE\qüDü Ÿðˆ¯ RË0ã`ÂÀ‡Ÿ]_ákâ~Ÿ QPW·Œøž˜/ÔWŸþNümb0Â…9äñ_ùÿùVñKÎò¿ÖVÎTøïgÀ.ágÿýï7ºá—€òe5D°ÒpvR¿B!(öÑJ„‰LìÇp¢_²î˜WÌ”£PÈj•ú`z#±ê“@;à ˆ„`ØÈ €|\£ÐÖÚCl£°\ Â)Z„g ?lP‚BÈ ö* %€c-±¸­ÎáØÝîG±0¬žÁJ5Š ‹ø,óXú é/¼|bOÃIò2A‚#Wjsè’L/½0̽!0âû•i€Ä.p¹B+`€±¶~‰3hpζ`ÿ`Ø‘¾§~‰(^1‡¿Ò港ü¿Ñø+´ùjý‡ÀêYá#Æ4cðG,Íòv`É@àNƒÃ …c—ø"pøÃqæƒ?V‡ƒÀHÜ> øÃCQ €=†Ÿj˜=fçqóÑ9 3„ 3£ðcˆÅ;”0Ôò…cA@¬ ¶0µü‚8¬ Àp<þ«¶áw,m\Á ÔFdÿ|ÍþJü¡Ah,* öù¯üÿtû³ì?Ñý'~þí `-{?K€o´Ã/`Xû`e W ˆµŒÄ‰!á¾ÈewŸà¸ãä° Lt8€÷®°R#Ñp¼ô¬¢Äõ&°4ã6 °'ÄNuä‚ý@L"#q~¿ :w˜}°?œÀÝäëZÒ(wß Ü@œ#pù˜{Ö«û.k‚¡÷ÑBG~ïÁoƒ¡K¶3qF"¿!þx›¡JPüÕ¬ºC¼@KB‰j››!vÄ*üy`¸_Ū4Î@âlöíÅXÒÿÄPqšÞ  ‹ÿª+oi× —†Ågp—ñ_¡õ˽—G‚BâðÇny‡à†j…õû_¼þ‡9¯Æ?Ð ÇMÌA1øãÆ âÆ©j÷Ì+싟p0ì%Apîlù¢VqêäZð_& +&7ÿå!&â?d”D€ÝÃâ¿´íŸÚ¯gþîAÓŽéˆõ 0â¿òÿ“í³ÿˆUßà¿›ü<XË |3 ~š”ÂñÄšÀ¬6}ÉÛ÷Aa$G­ô–Cÿ+¼&Üd‡C9ó%Äþ‰½—^‚ÅǧˆÔ–à6à†CÝ}1B½~~Øc@^þþ8îD-+ìì‹$èÀ9 ÷ ÏŸ‡¹…âKëFpÁ(†ZúŽ{ÇÇ Ê ê_Òæ0œdbô’(÷ø¶ ÄG¿Ö‡˜­$Žä¯4 0¾4H¢‹ˆSp,ÝÁèJŠW øàÿìü¼("èOŽXqıÁ°?,þ$Áœ­ ý¼ºU. q7|ì÷iÕp­@"hi,þ˜;‡x#ýü±»Ážþx³ï|8Ö£ÇÇŠqøc.ËÛ=‰£”n!ØAÆâgËø¯F?Ñ|Ãð5້U(c?ÂV'{ˆ6þx® 'îøÇ¬þð·á D-E1þØÛÿ¿òÿSí²ÿ+Ýÿ¥ ¿—kùýïÛúµäàßp€ŸdåøùŠ›€ÀR$ïÁ p4Vºðe+CÿD †þWFA ©3 Å’à¯|£%ÈðçÀH!€€BÐPüÊ lƒ„yÁ}ý|q »Dl‚ uô_ö°A`0Ø!À +ÔÇS nðP\˜u<Æ6ÀÁ«—ƒ`î '<$‚(µPÔÒ1ûѨ¥+ÅmÆ2üÉáþñâû+„? æ84þè¥8n…&± A N„H@a©?«m€¯\ø÷åÿ§5@1~ Vø€pâ5ŽÆYF\xÅÝ­¼ïÜ=î$ãÒ­šð_º*0„+b×îbw‚í¢‘€ÌÏ… ùØ'â2·÷ïàŸ‚™Xp`>~Xà07h$ÖÝGÖñXÛ FÃñÊ“¨pÁXüñ¾Ó„|žÎrúÿ8b ˜Pc§ñÕÆ¯ÑÉ$ˆüw”üYø{úa‡ÊÁ*9ÆýWþ¢ýIöÿóO”ßÉÖè¿ÿ,øvü(‡5Ñ-!d0BCcy?î+Š•e€(«¹À×î îƒýЈeO9ÔOÀ Þ?áH(Ä`ÏGÀ~H¶^ ððÅÉŒ:pÉ!„+!`<žÀP¬ûBÃm£üñAP‹Y)ì¸P°?rY º,—´! ‚Ï~]„¿„oÂY0b^Qû@ô —úb*`ùóPVôÎYøßpŠW\ö’Àßæ‹$Ž¢·´²ÏÊ×eõÃÿ׎߲÷‡Xsìû2þxÓCÀw!^¾8Kíð=üÑAØi €`Xü}Ðp«Øœ7 ö Aaë±PѦ€[—úÅN4œØëµ® `…$¬jØ .ò+üqFãF¼[†"kfþ!H|¨Û Ÿõƒ ÿ•ÿo˜ýÿÖRþvð¿L¾£~†”/çý|Õ!œ ûâÄÀ'ÿ`P¬X|U°Tò_Uá‹ððôM nâ…•@–ô’p4f3 ä‡eØ·…ÀG$!ñ‚°\vðà C  ‰ ä€9Œ«íò‚ <ðÅC|Ñ–B¯v¬f€á¸ùÒ°CWÆÿà0߯é NrA| „Bñ^äWViÀÑIJt8Á݃ÁVh?ÑÄg±yF–écŽÅ [ „+'_v~¹(†téÚ ÚöC!–',þþ‰ú  Ä·wN¸9(ÿå,ÿÀ’ ‡ÃW=Ž㊯ðñ†ãª? ïÀ?(;a1øÃoÒ5Ö7Ó@`lÑ8‚§…wÝ0~$`™ºB‘ðå‰ ‡¢Ö„?‘.¯¶éø1C~ÿR¿ïg€ÿõ$À…?$À—‘Ç€C¢ Tƒ?ò¿òÿ£í²ÿßqÿ—¶ÿFð]Vòzÿ<€Ã~œ`×bÙ3žé.Íx(û¯ˆŠgݱi@bz€èäã_‚u_R³X©„cÄA  v;åÜ?Þû'òhlˆÏŸÀ3B·;åažn±ø\«Ð@¼ò€ þxÕ‚#.`°W¨/‚P õtÁíƒù üØå_+|ÂØÁPØr£e纪†5$D±‡#ˆ:J¨e·™Û5À_y:˜£QÈÕÊÙ#öA —ü¼;„ÂyX)Ç*nõ¶˜hµ ð­øq P´äûßáøÆÿ3-¢Ÿ'fsWtþGG{\Θ€ÿ÷¼?‚n'ö_ÂÀºßˆUp`ðÇ] ÌîŸñôEÌ0ÔcÿqÕ©>ŒG‰„ÓùDñõÿ8;C«°"Þ:~àðàK’²dû °bׂ­ÆŸxðêŽÀÒÿø*ð—àïˆóNà0,µC]ƒàåÿÇÚŸeÿÿÁLâùÕÿ浬þõµüô?€µ]þ¯ ”á':€Ÿò„°>BâÄc9Ê3Ö0ì2ý%X¡4—üx' † b/g+u#@ŒzË5ذNMã.C# Ù¬l:úûâ:yy¢qQˆ·?ILŸâä  =AÁ¶1Ø‹P_L(jYΉ£‡÷Añkp‡Š _a(âbbÂ]t15A§ÁðÑA`E ð²!0{8ê«4ðj€Xvüp±¤ ·»€ëàb€ÿ]bþw¥ˆø5+qiXî»Rå¯v± cüRk‚ž]>Ñw¢ÀØ›áÿoî`|õ8á7¨CPÞˆxAþþÞѰ±‡Á`»H?ôþßÉá$àO|ÅÊ.[þpä*×~Å Öš]°*¶Ôqù`ìß”,ïÃ}ø+ð‡¢àDüWT!°eÎÿ•ÿjŽýÿ'÷Ÿ¸ï÷1€_A~W §Qñ‹p1̬Á}Q˶y¥»Å:çøâZ8!“–ˆ01 Šb-QA¡¾H¢,¬\f,Ë//þ0Q3bÓ€¸¯ÌðÅÕ bÙ1Èd{ùà.ƒúá‘Ø !^œÁh€ðöˆÄ^"Èw…ž!¼à| #þ«B!a7ø.€°ÎÇŠøõL߬‚ß*€¿GX F¼9Šü A &â‚-0W†]¸Žü¾ ðfá5>ÿK¸r<σ襘ùÒ}á-” eWÞ,œ@Ö–ìaÙþ`Üšë¯]@8bÕ|ÇãOTÀüqHÞšPá qýÏøûbW]cÆ{$æ8ÈwÙîã©*÷H "þx“³bæd¨µádd¢ ¬|ÿŠe€ß ¬(øWà§À„¿g?N€½1øc-) óCÊ@ à¿òÿí±ÿÿÉüÃ/øçÀÄ?tÿàÛIðC  œ¸ÞŸ0›1â…{ÚA3­Èøã¾ãË–biíV4p±B F|z–ûGàŸú,— Àá`$ N|>ùÁ%¡>ŠÈßÝ`¸ˆI\>¾‡ÑSPÜó°Wûøj®qá:‡°ì°ï ÅDØK( ‡'± ºbAÐW+€àK%ÛXz„[ „_´¬´a«k€W)Ü}®x ‚°â±R9àã)0ü¡Ø$ Š]wà8=GÁÿàÇ4@ñŠKÅ+ÜÓáKóqõl%àOpàˆ# ¬Ryxü—â¼+ììw½?L!ÑË¿,ù0þh‚ÁqCþOøÿí]‰nÜD~S„€ÒV@›¤ñz<§u.h•è  R}7ü3ów«¬Ûh£…µ”Èë{móßÇ\¯}.Î6€ÿôžš>ÏOdÚÞxC)ˆ?ÎóØþálX‚¿Ë 0~\â/Šø¼t¶ßwà€ðFlýÓ|ý;Ôuz½Rþý@i¦Q«îHÿ‹·ÿŠüT `±÷þ!€-*Àghw!HÈj5„ÿ¤!ƒG_{¬–‰~™øGG›ŠŒ(Pb»hEÖ(¬§ì°Ñ ÜsËi Æ«Hþš¾X5#46õÙÅdV}ϬÈ(uú¦gef2bôˆOÔô‰îÛÑÜC.º'SÍ—è± _μ«5C &n6<€™¿Y¬æ)ÂÀ2 ØÁè\0c¬QmÖ¶ž+È&:O6¶Ïà’¡F·Ý0þ³9šyà/ CùÐxR8Ë“'ÖÇËn]ù«ˆ:B£48©! á¦^í€ÿ;°Üðõ؈¿(Ë?E¦W>H&iíÖaC8z8[‡¥øÛ »þ´7Ç¿,L×r"EpoÀáà_3þU}¹ž °þ“쯺ûAqszs¤ÿ…Û¡Èÿ{Å?9h`ùÍϦÁrào ƒ±–ëuÕc¥o¹@üÈhN TŸÓ¨ñ*Üý77„t°¬L\PëÞ[ ä S €1Yp"±¯ÞQ °æÉí;ççWP¨»ZÝÄD0kj¥nÈA äß’òÑ ÍŸ÷¨á7íâó7‘!àÆÙÁL•±ð—¿¤˜®H–Dçf™I x#vóö^pðõå!!†¹1Hqö˜qI6öš/M€‡ÈúÀ-QÙªú.zvfßß, lå|ó”Á]¾ îí²Ýú›ðϧG×0ãŸ1ùf'üí5fˆƒ0¸`ü±n5UŒãùÿy2C@ÓfÈ€/Åߺœ,›­ú¬ ÌðO)ä…á/÷öÖø`ðÿö7¬ý³Í÷·—ÉyuÙõÕê%88ͪ9?Òÿ²í€äÿýÂñÑ\;Ý]1þa€MÖ°Tø8iߣغêpŽˆÎ$Éÿå¸)vÓ<“ªp™[9‘ÿ¡gßræ€u¢æŸ·iÖ>™n¤%P”ˆÏ@ã\ÒTͬ/džù·@øêå똼KaÀn„ò­‰GQÙOìm 9@ôÿÑ+„– Zt•ƒ;蓯hkc5°Ž)B¬8q’$‰î?S„­±Ég* -·¡Îa¦ö-šà_l]a¸‡rÞMø÷÷fÚ6Ða[×¶ ç§Ö6´nsÃȱ|?²KxHð¤KâÜÒ¹}œ¯êñ¡%,áM€ÈrŸ0þú‡ø­ÚP,ß}öyIü𗆋sÊÈÀ~Ò3ölþ_ €ÿsw t£N~í¨e#L½òGú_²ˆüßÅüãCX*¹?5~q `SX¦|laÉ £Ï¯ ‡×PØoŸý¾j°Uíü…B!­•Ào¿Ö~d!fCdna•GÇÜûºÀ ÖMæ+,#"ÒÕ«©áðYŠñèxç5Ñ0Iˆ¤s=€ÓîíbŸô»w ÓcÄ/èÊ” GtÎ*௧Û^'·Þs) xòDºâ¥VEnÿîÅÅ“I/O–yT¢Ä´„-dh«•-hèYµ®7Í?®˜Ë¸6WUaET käI@¨ÌBAìŒCg´<¼ZŽÏÕŒ³ÿtÉýNÑ °†Q·k神J‘y]„wèN1¶kÞκ1Õ!8tdxÏ1IyC¯ ªª¡™±Ï9ûöõÛfÒÇí›6ºgešCȱ•çI ut4 ¡àì–É JŽûo³Äª†$+T=~b°ÔÚž¡h®ìÈÃÉ\ ‡S„Êpô[¿#üÊÉ/Ä¿[“Pþù¤Øª×“Ì# S­Ts›i"¦¨qÊž\¡q¹ýG9t}OÔuËùv¾ãvMÓí®K’Æ^O»y\‰J¯þÕ‰D®\S{‰Wû˜ÛÓ®'OCÇSò8¹Ý—<'9_‘O:møŸ_.Ÿp'ïœâªc— ;«°øôü኷WLßT^ ÓŸv³bï Ñ*±Õ ƒ%ƒàéÀH·¨H¤Ÿ÷–d};þ‚Ê!dšä—\l®1š-#1PPÀŠMÚìž]¿­â£^Ë `޽UcÞ©rö ¿a—”Ú²™â× áK“*>eÖ•z§õ£»T¢H<}ωs*s-Û0´ŽSå %L±”‚‚ù/½×è98#«J{>”QûÎæ–«d=÷m­'•fÀ“د»ù‘ê­NÂæûDü‰Óo,®=n;¨šBre=•æ,ÍÜ„;}„ðc…§… Œž#ƒéÁ¨4ù¼ólŒEõ#Yv\Ï3^÷ããÎ.0Oªè÷rø@¿ þ{”‡ê?TZ œž9ëá8—Âä:î¡egû0ÚÑÙ8O!9îküŸ/]™˜~ü¼ÑµØ‹©9Ò×kÿâ÷ûä#82[™kÐøÓê—>píâéÅÞ+®óZÓ×5"ý2ý=ì!Þvó{wu˜‡‘‰–µ‰±£»«3è߈Îó㊔…Ž]öU^}Dž¯qÈ{…>„ím})žñîH†QÎu’ É<9ß—ç”~ºýŸ6ûûìÿL<M€„ BCáØwáÿ(PØù§ƒ@0¤ß·ê…¿¨@`ßyÃß¿³ÿÏjÃ.¿WLÒ@gn«ÙÄóœ4ðã5>ñfÕmF%û>_h?èkó±ÄúÐ7F©Òž=P>ú¾àfÎåø·¹3H•ÐÖ[8÷ômVÛ ¯Ü¸ˆÿ–b––°öeßæhô&ÄÄdž|õÚ ïÖ÷âø#j¶ô¨ öë/}Noâ›_³|Ìør®X§A|z¦ñtuù»Jå AâáUÛàY ß)4â1ÆÀnÏuÎÎÄc£¿ÞCÁûÞ'hÃàqÏE–„E¼®=V•·ižppå OÏNÜ vzž½Ô)l°Ä£6äP)˜b¨aWU#–1zº¶÷5ˆ^ýXjF”qŸé\[Ñ#ß¡OgÎh+Hš±]ˇ”jÊßL²Ì ¿CpFÀ0ÄZÚ¡oºÈDŽŸ\t?±U´­ýÁ†;†Á€å÷­ç’Þ ¹ßܻڕ$œ‘¸¬-o×ÊNüLQÜ|o€NÊ ¶ü}8|g5’íWà±SÏÕ†ÈËR†5‘³îçNƒ#/”ø/Å?NQy¡úñ-kÎÑ¢ BeCº f5mK“ì3)…x|i®Òß´L¸³¡{ùØ}4ßìƒá:ÙÞIÿ ¶ø+Äë–d¹ˆœ›ù«em7™[ñ㙎¼¹æÑ¿Î×ö ˆC¸Àr®—rððÀq÷Û=åü49ÝNtê"kNëÓ2zmûdéÞÉöÞÐþî“àƒnù é2Öè xY-hNˆ5ô„9êsèNữ’6§>­¼±£0OeI"·¢ÙgüSí¿çàßhÿJ®ùHõ(Ë@T,,$8Ô€ŽÿE â óÿÞ|>A ~j'ŠøN¿ý Øg €N@ÁèµoRóöú5™5H„ü†n÷|àd¡)[ía‡øò”‘0ʶýô Rêb4.§ãÛlÃôH*Üü(ŽSä¼Î“P¯¸r¶3¹¯/[¨ô¡Ëj5Îàå|Ã}=éú%º<ÚÌì×mø‡;{.ÜípÒˆ–3WS5¹r "™ï‘.hا1(»2¢³‘T³a½Êâ¿:,ÿà¾ÓcœÜ×ýóW®Ñ.t¶iäj¾{U¯ˆ™÷‘7 ñt@-¯4à“Ƨ–þ]±ÂƤ%Ýi®Ù±Y”ˆ½µ 7•×}3Ü67mö²jP’æ:»ëóõÊ‚k÷ -cV$廚$ÅÞ*Oî]ÁË©SzÀÄœC§ÈQduÏÑiyOÕ8ý|_ì”þê ¸xÔK[éLÃkatC–/µ¦çF’Z6h%¹ÈÄI6uÉÞ²T×3ÊICòÉ Cî?®eØßØ®4b¶§ÏïôÝÃa‡ðkK‹ùï‘5&®þ¤j ü‚ß!öUG3«õò cÖ mI*¦§‰ïöÖ¯ÆUÆ.\µÆ=Ÿu¾ëFÈ¡+~œ¢ Âg5ž« •øïŽn苨%í‰+OÀÚ†ôÒ*D^×-CÁ¢¬“# þßÄ£Ð]{‹#æ [S úyÊFò‡Oõ™…5H!/DG‰¿‡6Ù,æê†+ºÏ‡ï5KóYÊ{a|ŸÎe¾±r9 éÃÊŠª›•ñ§i²î…'9ÞbdÇó¯—MqŽûÄqPü±Óá³oDп«ëZ;c£zäDt>ÌB N…}ˆ™niç Š9“Ñ•»*Ǭjo'Ù)r*þ8îûUáø²J“>?†å*óµrƒÁi ¤GtN0ä…Ìô²ÂOÝÄÐZй³$ã÷IˆÙÌ7>W¹D-é'Þ<õÂSønükøè¨|ÇÔUÁ‘OpîMoŒq<6!$°8U}úÊ ¦|§¯ñO©Ã%x~~Üúè5B¦‡Vü;ø;%–eH^òö·Dã¿pÏéÈ ªxŠë”Œ– +s}m£3ýü/ALP„sc w€‰›Ž“½•™º¹±…£›»Ó7gÿø_1~XŸC°>È’~N;ÍËiÃ+#ÜÞ4C/Ãß2ÒñÏ+¥}GÝ#4Oér,ŠýDû_e­jøíŸ]!*Ë,å  F ßŠÿ?¡(Ôw_¡HäÏìøî€¿T@w­}G'@”Z‡ XºûVuý£¾†ig|¶“äó^•ÚŸOJúÀRŒóq]ÌŸ{ •¥“Ÿy ˜P²­®?#s‹-øm òT× ãÕúò’Ä G%{ ¢/¼Žæátà=œ­Õ?×V1kàEH6q …Ö)Ì÷ú™ˆ‰)œ—› ‰ÇµñÊiéÕ™ië é_Œ!dEµ¾˜èqöì\«R£yB˜¦ÙþzZu)x¶^4~n`Р_•!EMAüÄBhPxÒGÍXxçàÇg^ ëYåÙ&QÛ^ç§Ú/›”XN©)#HÙVtS}LÖ™çF nw‰6g»ò¬åØŠQ\oÍ–g»(ßhr[FsÔn2áù´Ç÷xM<öøÐ4Ο¥Î_^·Îu±ûÃ#º²+Q4ËÇÅñ5{EÂÈ^N²Vp?z‹}ŸÇþ¦+õºOÆKŒ^¤Ìr—íOáBÅ \ãÔ ‰Þ©˜ö€šc9º´ä"ÞÝ"Bú¤OÈz.ñ¯^-ίmØS|!Kho¬LgxN^}µ,Sêplü«@ÁX’§= ó¼NJ™œ¨|åapÕL+›¾oi"M ÒãXªž"–Ž3Þ‹ä·”‚º8ÜGŽ1ɼ8 0-ÖÐÒ-U‹õ ÆþuÀU¡®$ŽeZ=ÈqéŒ'µ{žè¨Nvð¿Úÿ^?\³ ŠŒþˆÓBâ>¡$-_Ã~@Åôù«µ,¦)ƒ~)þÃK¹=NÑ%½ìÍKB³ÄúéC¥S£¬õtÏÚÈx®n.²|ð½Ñ]Þ‘s×;„<±’¥ªÝÄ5Ýþô=¬eà&¾½ýüË`[ÉEjµœ!¤D±ÙÆòjü›¶bÇ;â#£èüAü‰ ŸdsÛwp¿ÁÚý!Gjš9>¹D"&ÀÿôÔÁ¼ŒÉývzÂã#9¯Øq]y#o}\¿Á;?uèÖ÷ão…«ÏT5y‚£ç€öáÛ‹ /k2ž¥±­ö ½_¥X]~{úküi›ÒŠö?¡YŒ?šo_ŒÂ¹Z¶ƒlªÌìKAð‰k÷/náŸGí¬H \/¥EˆÊ \mÓ"ápS È ‘~9[äcc§ålxÙÔÐÎÄÆÁË×Éü/ÂÿéÔ^UÅ<Ï‘9ÃK5þü¶šÆZ–ÆVæ¶Ž^@;ÏoðOÀ÷y¶So¼¬ð 1¸~Wì½/ÿõÕÙé*¥#éI€,$’ÙÆž,M1/Fu_j—ѸéÅz|dèª^ñϳÿêææ¿ÙþC‚Š×=SP!¡Á¾èà¿A|çà¿ÝÿÌaèww8üµ¶{ ô›†¼ÙgqhÖ ;^ßä³`ÜÇ{tÙ‚ Á®VDÁò1"s³ab4®,¹x±pÑ-ð9nŒ}ÓÔåb:oVvœÅg”ð…l¤krÕ¿mq~á0 9b qHü€›zü‰Í!öµŠ,h"Å~vDTù{Þ½Ï T¼Çm‹¦H2<¤[ ŒæÑ’£ ´6lP²—”ܧó8TÞºÓ£‰rÚ ò'žF';á{{ Æ[‘4$ Ä0#ïèÇÊäÆì^Áî5Í~A²ý—„)ÖÇ9»º_É5Ž7õIE<ÌÎ ï7=Ã÷¸Ž™Ú*/DPþAæz€tÛ ûìu+êXÛ¨â7mŒQBOÈëìö:mæwã_’¨óiìÚuEeº¶äÝŠ.— --d²Çs3‚;9†ä¡r<Ÿûj[f ç 5}èc‘èÿM `„hHúA\E&û„c_ g!õ™[ʰÑåT™b&ZÕøçâ¤ý ýÂ)†b– 5>KG…Y ó| T –©ã xþfíu‡Ð­™©WäTÅŸpëm¹TÞ6d0pe¾²6Ë'–Ÿ©Ë̪IëÅÑŽ3Ú?«uæ ËÑÐãsã2sòÌú·©bŸ ZTùY\=]—6ìÛp!¬ò¦vsõ‚ˆô?Àß6øê|-¹ÝjQÌ«7þ¶å¥‡+ç½öŒ¿¹Ý±§$§>mòòLþ!bö™DöUƒ«Åyù¸—UZŒq.}?þVÒT²¶ d¬!Ê´Âø¤ñì§Í¢+¬”òsz†É*¡ú·¿Æ_¸7INbM˜ö…Îã{/Ñ´müù>h–˜«tI”ë£ñÖKìJ€ßÓiŸÏ8k@#Ñ­égfëåë ñ½bhêtÑtp²Ô2³°30upõñtðý†aÿüGE/å‹è½Ã?ÿÜ8þœ¹oHÉmñSLf«]lõx¼N W†Pbsç W¶^x¹Â¨ŠïÃâÁ üÓìßܘãïµÿRyg¨õ=ψ`@Dp0Ê÷ßÑ  ¾yî߯ ñûys¿¿à÷À4àÛ;Dò‰¦ÁÓ9—••3ÉÅ@–¬_“¹Q¸™“ïJîò|8X'¡¾jäÆ4~Š;3à´¸¯Ì™…žÛ¹Ò1Ú!^Ö>rDëÍ*GI©Ä^ïcž²)É«þàS‘Nùw‚$hûS\<)òÍï&Š´Á£ûKœº®Ò¯V?™ÙwA™¨Bâù£`rÇ ‡çq‰.S¼Þ÷o¶å8áÂ/JK3³yý’%I ð† { ßRFábUl4€äVî+$¼£RkOûKœd°à‡|Y^JHÀ”÷Á·ÂétuOFZcžŸío÷bàˆ;˲<&7‘-c\§³¼Çˆ*2×ð4wJ’„eÖN+ íãí²¬œŒú·Ùâs´š%̲]À–Ã…áq{ú}eŸÍá5Iå8–š’LgJ%ªÕÅp̱EÊÏ· ©žlœÓÀ™uÄìÂy_AªwÝé=.§ ¢²w»Ö㘽 …ç¸ò¼8/I %(’¶æ{ôúœË+'ri#ÉEÜwûâq,³TšuÓ]ÊEhʃ)ì-Dµ×s4Œ&’¹õ–¹‰f®¼.è½xèÆf‚ž“£aŽø[KC¿¸3Ý ÈÌš¶¶Â3—Ùcl3T哽HFZð“9 SóÒu‹jyQ0`\”äÏ@î ÑhåC“œÍ}ÃÛe#È2_«%6ÊÞßÇ\u@Êûþn¬ý- åéòØ£¯Æk:Oyg|™í±<‡fPT?üpa}…»Ã#G»•Lqlñh¤ðe @—ÑýýÖ²*¯×yü8)ŸJQÊG*ÅÞ¾G$aLüÐÞ­[Øÿ¶'Í^ÎPßrµ’žh«{x)UTÝ|ÅÚU<DïÀûŸáß}çS·d܆@­"r N™Íÿ–ÐP†·¾€”Ž1éØÃ†R±‹Éc©œ£ñÔ$¾8'o¥R™9jŸÿüã.{ѳyÁs >½í§J‡Êà³P±Ý<åX÷Òz'™Ùû‰¿Âÿu=GZ=\6Iòþé61â7²8Ûø÷׸F°—U©]gxŠÆ?¤VÅÁ_ÅksùŠv‰N÷ꀱã5@–è2Øì ü}VOÉOUõÆÍØ×e¼B'²¾ôÂÌüBѳà Ja#ï4$“öKiluDá©Ü~¢_˜— í³#çï,žtsÿó2’ORªŸêD˜ØRz¸¯[KªIgiä©\A‘ß¾™'¸£l³‰.“¼&ÁÒobÍW©’C÷í?ι$öÒ^|èµLÙÄ9»´Ëù#WTèpößË-~ ¾ððªá,à)‘±ÝË5V_’E—§J¤Ï‹‚òç÷t ~Ý/)µÂÎ0 Üªi“FÕAÉœ<Óû(«ÉéΉÀwø9œÙÒ¯ƒˆÛdV 3u(¤IB©¿‡ÇÊÝ\ª«8~Ùâläc6éDeÞû“ì6jñï·‰ ” ‡dï¸Ð  `à?.àwÏýûº ç"‘?§àzþò ü3þ¬@¦ù†çÜ+/Šws¼7êƒcy>1FO×§ï«MhsäcÆÝ×ë¸nË7A° ¿ÿâQÔ´YŸÊ"ã+žÔu°R5Eƭ£óŒ{lpãÍEðå«z•—í=Š WöÎåÚµÕ:³/P‚';×CWf¼šãL ­ò?ÞLÖ¾5=tÏo©OïzßÜ^ú¬HÄÅ †|1È,äé#rÒœ€ à½ûÄo±T¤­‡|@›$Îy¥?@Ó—<_ÞçEû1VÝÉO«®€Ô€âüµ2Î`†Ã¾]—â93š;ÔàDnâµgÔ–}÷Û½ haË_æþ˜÷@¯¹²k¿&åèH¡K“ šÖÓ6º÷”ÇÉ#“äéÓMèÄ;ãððø•Í"sMX‰$‘lìN/™h7âÛø W„Gyö“úˆ€¤ÂY™ÒÈïqãÝ;!†K­”g?_Á§aNëWÜG½£Æi.æ¶h±´øŸØHaJ“æÅ'\ûˆ ^ž ¹6’Ä3}ÊÍ—Üdf˜—‹'Óh±º_¯äIF5u1ëÓÞOq§ó¤ δxÐ_î/Í‹&ÚÄ ·$oXõ<öÁ3êï1)\{“uÁ&t·ÊH&åbä[)ynµµ²PŸGZz^é–A©Wâ ‘Ò À¨=ªY(HÕ"iáë~Ÿ½ø7¨r‚da «hßG˜Èà‚ q7¬\´ímT=.[›Ú¹z{;xýq'À?þ‡Ò«§Eïk$%Ì·ß~sDÉeRï/âˆ|òšV¾þ¸ôÇ:²üh[Í>æ.:'_ͬE£@Í֎ܧԣÈ®jûRªÒiÂ~Šý—ðì?ñ·Û¿÷–ýz¥:„FÃBƒ|ÿásÁhÀš¿ƒÀÔ÷NÎû±ò=$~lÀ/:þd.àÀp³·ö<¨ã­sÙ}šº£W“ŠCè8Er¸Ù¿ìO&¾Òõ±“à>ZÆv/yížÆB… 9­Ð]àéÌ1‚|Q!jª@°ô%š—®åò·\ÌÀÑÉæïr•§=Ü´¤•õ80½ìA =Ëâ¨R+ÕtcH"C`ôѳ…Ê>cúºÛÃ`Ö|h@mÙ@T,ǧ;6QLueSß hBMܯºL>5Ð~êâ†>zI ’!nÐ{‰Œw´ÂUhå~Å÷P=Ð ÷ÕÍ£÷çJ¬5†Ç²Òú+U«“åÜ>ÖÖ÷CˆsÙ¨ºÛÄBZS£M^Žßd.i»: ¨6EÀ¥CÀi<æ"w=‡ÒŠâ¬!Áìðm¯xY78#¥0ê"‚e¹acæÚ»£$D¬YdþŽ5©lªMÖluÁ<5ò§Ä–UZ”x†ÏO«ó¶˜mˆŒà Ú¡§55ó3B”ïy šªÕ¶¯JðC-œ µE­M2ëמÒâE}ªw›_q1zÝí¿;/‹k¥7Säûháp¤å czÄkª»¹™mÖȦȯœYÇ™µ#±áV§\–j—íÝœð ΑŽíŒÇGsÈ:Duß/5ÊÎIiý #·XúuBw`‚}¸;"Ó1Æâç…þ†~—ª™€'¼¹ƒ|žÂéò%.æôÕó#º›ÈSA³Ga÷kíÇ|ôÜ\ˆL%^׺ê”W€ÌhDzسðÕQÓÊVÈïw-æÜÇu®.%—Ïîæ³™À¬µC ø½¬2Ë“VÇøHs©._d^‹!¥L¼o§UpµæÒ3'Ò”RVÊ™¡éBŠp&FÕ«ÉW‚•ü²$<ÞÖÃûV>yNÅ–2÷/¦xý%ø3);J¹O®2áLƒúT„l§ÏÙfl9Õ€ËÞáª>¤Ñkü´¦p1¤ˆÓÍÔ5ø#ø×4A>,ðÎOÑ8÷~O#Do·„l²fßÁ^á{ËËÒ¿ÂÿMñŸ² ¬ô%uµ²Täìàß5²÷TŠz‘kK0ÂÞ‚“‘ÅOr¤ã 'ÈQ ÖÚg¶Ï”h7k7O„g”IˆWˆµ•/ÀÉXÓDËÖØÔÒÑÝÛÝñ³Àÿõø»˜ƒpO×Ut¹?m=‡‰ÏbQÌ=µ8Ã>vPÇuÍN¢àá5žÁØ–y­µÂ§@*C¶Î㺠Âx6JyröªÞï9~‚ý+dþWØ?O@¢}ˆ$Ñ; ôÏž ‚Pÿyì…ü´a?Ðð× €íJaßÐ ¡b¹ÎOƒ-Ïuü-‚çÉý\ƒgÓ®`"r¥Á ¶¢¾ JÎ×J!(G!üÞVŠM‰¨Cé•!&eÙ®øŒƒxI5V è¦q´²/bLÞ³ÐNgäNüÖB<1Cí.Ι¤˜)2B8Íãàõôe]ÍöV_º}ñ"ŠO¦í€Àü>»«{¼¬Å±{ÒdšH&\^4_Ñ!š*dtí2- ;Nã/fÇ›_¦3™(–_MѾ¸·òß±…&•Ó §#@Æ÷?|ò>F+àìc“8Ëg“•‘™JJÂŽk'Îå ËRÚÛ­<¸Üº~ð½zQ#_|Á!÷S l¯¢9#?¾;ç,9¦ëxVCƉïÝø'cÔ}õ£MË•P?c´b PÒ—/Ëä»}<ó_^mÞ‡³BÏJË÷>cUñbóêV£p÷‹&O±+ºÀž¢²ÍIî;"6¯‡«Â®JšV—3¸÷äÀƒªýïTês¤gä†i]T›‘i>ÅäÀYhøu/ô-ŒÕXÇLä#‘€ß)©&½iÁÃÓ£ÇÉk»àòGn?AVÆ HMåöÉ]jäGwgööP È6Ž“Úí&™~,ƒu¿¡Ñp¤¥%,ÕáŒi´s ý~Ÿ´2(GÏ?31*×lŒNãub‹ö¼ý˜Xcè`ß™"î§CbV¹‚ýl +2ז܈y»ÍktN s¢üV¤ò—©ˆœ“µ«~¯ÀÛd𴛘ºÈ@òö0Oú œ {œ=q ; ã3ãC3Õ=Ô‡UI{'ÇîçœñÚ>2‰ârË+»Æ “-’°?MÛ•‚µ+yñPG¼“Þ­{þá? arh,¯FIZ£)Ärüîõ¶F;ÜÈ ‘ÉÔDÃ8 ‹âbs)³f^jÓ׊¬9jˆ‰” ¿RAU؇º3u´K¿Ÿƒø §Æ1¿.·“Èð¡Ô·R-Íå5\d¿ÂŸ¯þ{k·Nì2ì$Œt‡ôþgž¹-S"z[Ö ñwfãi>ª¡ªñöi±±ÆÈÊf]ÿù58ˆÒöuwwAÆXgë‚<ôíœmÍÕl ìLm<}]þ`.à=þé×g'Y´¤f…ª_\gœØ“ë…|¤šƒ0+Ÿà¹÷‚k5Øâ@mæ('­˜lTz;4öi<(ûÓ¥ÌOráØ—l£îÛ¦ñA˜Sÿ¿±ÿÇ-ûw‹AÂBƒ‚ÿÑsÁ¾ðšû÷uùiÃ~¤àÀ×}ßÚ%ð‹üù€®må8B´Ñ‰­û{¹ü¶¯ˆ+>ã0¼ÞÑ!"ÛÆ'‘Ò=1xb² tð¨„N<³ÊE8!E™¨µÃ@{m1—ªãh¸Œ­Úå‹,kýåÓëÔ-QK §=8öJÝ8âX‰×!>Z,tÀš½7XÚÏ}4ò4«›ž –þLcðFÔ•EšY{%‘ÄùõFÿñ¶3¶Ä í½Ñ' ßÍŸ ȇrÜg™qeU®ä%é+kÎ|eÅeá|LKÑ=nnBD—vïÒîã‹Ì¼m°‰½·åìóÌ8{àu“¹êÚÈThcõ³2ÿ ÿ;7œÎ"49rEÒ{œÀñ¯¹é}Ênð¾<âô‘3g<-­éÉKÙŠâû”duGpËcQ‚‡Çß…Õ–²]Ê]Z} 1KS}ö¨9e9/à9ékÜÚž–tzâ„}5áñ&{ûÔb"ÝñŽ]ºùtd/gâ³pÆî`/A]ž¬úTx½0÷$¿3†OYaàÞK—Ý,7òq¸Ò…óœ«ðP¡ ã#sRƒ·ï³7ýq»Óy³Uê¢/æé>«÷<,/ÞJ°§òÅ™,%öŽB^ÕFþÒ[M¬=âµzwêFc\{®ØÙ ½:â±·,†™ÃÝø~ÒEí$ÃßLïÐÔ`øü$°w-äÄÉf­;̱Œgh¼—ÒúL]3³.NÓºwùMè«.—°³¼à :Å26gc©¼½u>«ø(À¯¶+™žã­>ñJâÉnÍÔ’ ©Ò;†KÇ9¦Ô§Â•M ðFÆ…üß>¡^.Ýûê¬ós¦@`ú½‹´Š¦O7X¤_Ø^ÐŒ-‰›VšKf ÉySE¹äqº‡®0x"5‹ÝÝ¢ð¯ÃŸ äó‘oiR–€£Ÿ9ßnÑÔ›i=Ó'£\‚cCdÀŠŸ°Å¾¸ð… åó¹ìÁ?„ÿõ¹ç ã{Ö[ñr(’{Ò7Å$¦Û´Oæ¤ä zšé4ý ÿ=#t“&Ç&*h‡÷„Ÿé-¡qóØÁ?“UU–tÍyŒ¤©¿”Ä;â9zšÓü¥gt –;BÅqSž„¹Y§$l]]Á˜c /ÊÅ4ÌÁÂÐRÛAÏÄÒÄÖÅðsÿëñ·xWÖsÎl˜³j^oÁþ Ðû=ªQ”{ÆÙ?°›\;ÅNÇ/EpŸ3wV’¸’k¼SÉKóöN×ʧÛõŒ°5 }á†weûì_%î¿Äþ/^еAÁâá!a!€ê\@ð‡çþýªªŸô“ÀÿÇà»êÜþûGÂ"æOÈ· ñ}JJ-½›š­’È‘…?i%Xæx¨ÔŠfp­K¶~”r\ Œ ˜"5¼¹T{ÅŽžïD{®öCMǰœ<åXüåT¶ÑøyŸ2«)gñXÌã˪P›°Ç²¡¤ÏtÇ€Ë=¦ŒmJ<Êê¥O]ˬ¨ˆ”¾©³k—]RKG7Båb³ßr¸t=Ww¥'|Âì¦Ðš†šóð*9@ë“ÿñuÿ4±µDbÁÅã}ҸŽ')ðn¦âˆ«&-49t]q`¸ Í/RD5+Tó¼ËÒ¾5ÈHL7 Î$›dßÄ¥’ˆ{A·vðÉs$›Þ«*w}VD¨O›S»#¼«ép¾ôȱ¡?h!=ø0°µG},¥¸ga_UX_‹»8ÑÝÎ9îÑ® S±9¨H>%gû!+þh'2²ÍSÚ"|Ϥ÷íñ}³àˆ,XW>r›I*ßµ§¡G»'ΘŒl˜±µ'Wüî9©ègŽûøY’Ý¡)>wßøe½&?x5*M÷jAœ¦÷rheøô\~®Æ€n– á«*Ë”³"‘×tn‚#]"caHô8Àßd¥ˆªQCZ¥bÍìwÇøïmðÚ¾?cS¡Êâ„ìs9_ka>Ñð:÷ÔÉûiµÈµENÜ Ã”ï ÏQøz™¹õ<¨(^š—>n>ÄZÜå·/#[»ä•=óU²ùÇT¹FFO¥ ì# FEN¹Ô¡ãÆ=$dÄç#‡=u"Æ,ëÛ ØSa6A•|Iu*Ä2“K2atzšdJ¯ÍD#Þ¢ž1þ•ø“÷]R‚Öš“¨’VýðØ(?V«É-Ð=lN‡õ4àyêéõèPÏes>ÞÛã¶Ìö?†ÿÕxëC^*:”å㎎.G¹/O&;$¬¨_Ø¿¸®NX>›þ+ü£H»ã:/ v„¥ÒÝO<õ¦'ksõHÖv½‡ìrøhü¯H”³_=×ä¿@I}ã6êï†3èu¿m€‹³'*Ô*E?ÂÖGÝ×ÑÊÌLÓÆÂÄÌÁÍÛÓÑçw†ü·ãOp'-±E ;Hw*Ÿb£cäÅ\W Àbл¢WTgTóðÅU¹‡–zc öN ç0áôœJÌQzØüv»¢+©ö9‰~œ%˸ºÿ÷öÿ†¥ç¿ÃþÏFf§"B !¡Hà?sÀ4÷ïëò“†üHÀeúÿã>€/¿¡rU§ïÙ‹ ¬Ds[_Ùx²êi⪡$´Öh´É¿so „èÝôáþÀðHÛqÇÖtYªèçwÜè”q’ŽÛÜMµÕ@^ÍXÔsZsn^Sž6~aJ½òo)8jcv¼¶TÜñ´èíC)VT×LˆŽÎŸ;~boÔpµNŒü»6·ÄµyK#aÑŽ7Îv/§=MÍF”£šÇ›†ßNùSNDŸj›zàœuL[2…_ÉÖ{ï¿ÁT);! z»—¸«ÒòE«§Ivâ«be\1Ÿò34Ì/M¯ß Øèzñ´–‹4\Ô_ñ)'•ÂWk 1°d8ï,òâ:PåTM¸iÒÝ¢*3÷¢©¸,Dg?q}7i{Yã‰ú7ò·Åf#³Që¾û}}OÖQ°‘”ŠÆ·VºŽÑÌÒì u%›0lð’Â(Åýþ¹Ê$MúˆÜÕÝÕå¸è6n™ûŠ],pSœ­¨OÅÝ›}DGëЪdlc\¢ˆòG…ûz!~s  ±y±fª{=[sàði¡pQïÕ½V+Ú %kæl *þ÷WËÎ’H³;-2ì]qWŒÑ¡~žäyÛ“~ß”8‘›I {„à3O¥/úäwëo¿?½IÞ¢íÿVˆGùú]ÏW3„ Q3'Í«°µŠÛJ´{oZ§èý6A ÇÌQËv©V©ê{¯¼šn,NSqó¾À±üO^ÿµøMD΂DªÊ4Ôúr®M/#f=uB†%½Nú©ó0œ.šîtcb6DjJU—ÿþwCߣnÚ+L$ôXlM‘\yò³ÑøÞ‰ƒóOàˆ*Q—ÿ…³ãO|7yùyqNÓV\O& ÝÁ?íŽ~é©„s¡iŽhüÉÊâºãšÞ½ú1ˆ»åཽY6­oTÀu“RýœÝœì¡°‡Úyj8ÛšhZÚšÚØ{ú¸:ÿvø¿ÿkrRšòçRÙR2Ú#ø¢„´¢qìu1Çó 4ë§r?©®~Ç´\˜ƒG¼·n:¤³| O«™§l&…<ì,W‘yPÑ1í ó¾nÍ ÎÔ[F‡*îJL@XTlÎ’+ˆ·šw´®6[]–ŸÉÌn\ìU¡îØLGÙsx±;IÚ<»{|…N·:s×^™Æ¶ˆ³÷¼\B…“kûù8*R=Dh@—bu³ÓÁ€£eÔ¡q ≜ñB¿Ò{ ó÷ÈEG\ê_ÌtKEúÇD¡ßê h0ï/î>(ËDª¿|Hú¬šÑ!/5ÈdÌrÿd‘6Œ!*îâòô¤;Ãù¥F?Ãæ€MÉÇ™½ú¡+îdIF×êTY?5E¬¶¹•¿ õSé²<{8×ùœSúÄ¢1ß*p¾›bO ngXrÜþ+Ù²9%¤÷åÒ_Stô[—fö—­ŸÛ/2XÄ.ùA"=Ó8M¨¼‘Þ®=™°á/Ç_üÍ“M±öu Í\›‹À3—]Yl••=ÕòšË}įøF;å!í+?†ÿ)F§ˆ}bSWýÒZ–D#C29n÷…Åõlÿ„«Ð g¼-ÉoàÿXçUû¡þ×IBkPk-ý¥Ùüëª_Ñ$ #+ï´FãÿfbßÔ‹7çÁ 4Ïö~Ÿd‡Ý¿áàzžp äèâ q³‰39ú:Û·Ô´4¶6µsôöupÿ­aÿíø¹Vͨl5˜nÕÑîÀºÎìK÷à¥ÕÍ%g¹N9³ââç™zqŠéM©ç=:oõdÔiå«]jÚ()#ÓÒÈ{pîçjÞçt´Èy{…þcÿ¼ˆl ~†L²oB@PpXÐoϬü1×ò“ Ú“}«Äz½Ÿûÿýaÿ÷.øþûO~ú»È|ûµôƒ@½}Bü·þÀ·60€™Ç€Þ€aÞk{†Þ‡Aàè}`zDåÖ8tK^ ¶CÀ~p8³±uß^@ÑÛPèÖ*æLK¡÷¡ï"Øû¢OBŸŽþ‡Þ†m¯‚¡~pÐ%8ó`P°{øVp€cT zôÚÚÆ4æ¹Ñ °/‚„cÛà¿ë[ â·ÓpÛ ÀѺpçD( ƒoCºõrˆí5ls` ~n8æa·žûülƒøùÆpìÓ@¶NÆV†é”Ù>Þ°}C{/?̉ÐV£Ãº¥Þ¶Zj«úš‚A0í‡ÂþV‘ÿvüK1¶ÿ—ùòuB±þå ì:æBã€Þõùº/‹müá»*lËÅî…ÿ¢é0µná€Ý¿D@ô3ý15 óÑb€‚Cà`ä¶ìQ4þXaX0ý¾ÿ-@à;&òyùUùþðmã‚~µ€Â¿Ô³eZhƒmßÿw ô—kÿ>ü½·ðÇÒè€n(À;ÜÛZh,1(oáøŸýc©þöSÿ¾ò=îö7)€ïŽÒWüГõ|³¨Úúøúû`(8†{¶?bŒ¥`¶±æ…Qð/Zml?8æö«Býüv\>ì‹ýl3¶å·]Æœ~Èí5¬¶Ø¦jø6£ k‡g¿ ŒÉBá ï`4ëx»Æùaм“nÙ¾ š$|þ~˜vDÛÿ/½ òƒï4óöN0C~q"`øÎ|&dŒÑ~æ´Ùc¨iç0¼‹w“¦J8bÛK@±kXfÿÜDp ClcoÀž†€èvݲú­Z`…À[!0¬ýÿ|3”¡Ÿ¼ÿ.6‡}y,k~ÙÜi8(ÿ]G°ø&ò_4ûNE ?b7ÙcðßEûŸ×¿´ÿ€ïÅ?(ЊVÔçi[ p싳Ç,¶ð‡¢àÐÔAÈïÇCã¿tß»Á¯ñ‡!>ßÿË)°¯TæÃÚVß$¾SüCð DB1Qÿ­zÐø£›j ÿ $t§Eá”á[|æë÷?ûÿ¦òoôÿøËÀ¤~ƒ¾QTm}ì>Ht± °ÝÚP(ë·Uã÷Ñö…Ñhr…€¶Â¦m €‚à~Ø > ‚íÀ/Âͳ;›Š=s‡Ý„¸K@½¼Bü·…5ØMìP_@&Ô»íHî-­ŒØVñÀ; …ŽÈ€¨Ï¶ÿ…À~»)]@È­k;ÃC¡ÔçGcâW\€‰>¶¨±s¼;8úbØØ%À^nÿ7Ñh-ý¬µ ˜`G$A°üˆa©­-Bïøžà[ lþä›ÿ¦øB˜;[Xü±» hü?·èWß—°øïxµ ™¯ìásõüþQH¿­FBãý¬XFìþ;(ƒ·ñßv¾ ¿ïÇ‚ í¾rß;>}çÂ]øïv,_¬nûåw)‰­/€íTû{å«À¿ ÈþPL¢q 4x[ø£‡YAA®ÁhÖAlEãôùŽ , _Ÿ ÿÙÿ7”‚ÿÿn÷¿}ÍÏÐï¾ß_(`¿¡¾ITA|àþh¥¹EŒ ñ9æÿ*õæÍ]Z{ÙbJ(º a‹=Ði*ìÙŸ­d'÷ÿy'ú³Åð fæÿ•Û‡a`¯ØÙ[†úï Û$¢yÁ‚0âè°m×P/ÿ@—øí8 ØdlEqä.õ¿Ã)”ñçX„žeÆä/1êC;ó‚°¯¸+¶L¾8Æ&î~É–»\ Ž}Mt€åIôÕ»¢ÌÞíÜ"{¡¦j(x‹ÐitÊð7C€ßæ€ob€2ˆÏö Ø­fÙ•ÑÝi¬Ï›¿¢aG{J ýýŸ#»Ýçüj±u&rû(ÿÏ ìºí/¼ØöÇð¿¶õmB;I_L3aÄo'#°:#€Å‹%äð‡"¾8èßÉí…?¾ûÄ/ ¬!|Þ¹õÖP¿ÑðûPþøGàïâï¿ÝÊ`›ôm¼aèŠÆ‹#âí‰ t¹‚Äòÿ”ÿÙÿŸ–ˆÿÿ~‡øóSßøKÀ¦ŠÁèßWØqì ÈŽ|•úßå÷¿hLó‚ÀhÑ‚|îÙÇÈÙ]9ÿ_ º2„ÂìÝ·ãöwzv”7V†@}|Q`(6% ñEÿ–3Ô†¦°7<ÈÛX[® ù†`xaë>`_ ,û2áã €üva‡Àƒ‚!Ø E}ð;±ÛW$½ÓÍ Áv¢© ²ËþMp,QÀvuB·•þö±Ó7ˆ6qì5—²E[æŽмÿE€Æb'ÿù5¶ßB÷Ðøf!dgxìîæ«·ùÜ’˜-0} ŒôÛõÙBw½Õg?‚ý8Ð/‡Ö™è»að‡í:k׿/û`Þ Äß/õƒí„›ÄN¶¼ÿßþ¼Ñ.k (ÃÒð½øð_œøun7þ0دÎÜ­¾l~ðàkð¯ÁˆB§çÑ]üP_¿­ûA|€¡~è.ø-üX¡hüa`Ÿô÷€Iòø€@ÿ³ÿ?+ÿÿÿ#áÿÎu?UüˆøK¾¿*ØoI€?W¥Lß6·¿eQ@8&$‡o{òíPì <ôî­%ô˨>Œ ‡ø¡{Â~òÿbäßîè{ ز`|§š íåíT†éòsÜ2|0&…bò‡@¯ôÀ_×È€mºzûlåéï­Íæ¾drWKî0ÖÚw3ö·V¶»!þ»ÒØqÛý2LlûA!(6[¼ va·0}!ÄŽ‘¢›Û»‡ž”ñ¹á°c~0çìÀ}¡Û]ÀH$l'ø%€þ‡IÀû˜Ôòg²ÝN!òßåýÏo‰îÅâÿ9”ù\#ì«Û (ø3þ¿Èüîv_nrùqüƒÐT¿t[ óÿ; « ˆí¯ˆéÑ‚Q?€?zkwÞö« þWøÃ`ŸñÿJ*lïÄÚ ÚêÀßÕ ð­ àŸ€¿GPÿ-§ EÑ®ò F¡G¸E`ôñGÓÉþØ€ þ°ÿÙÿ—ÿ~ÿÿ£îöÓÀ8í¿VÀ~­þLTaä&|Ûs£µ%¹Í3ŸÃ}¬ø2ðo'‡o÷îƒ}_:vÆñmËð/4ûù*´’Ã@ÿ Žþ–?‡ü°/cqîôŸôzzåÖN/¿@,çoþ‚xßÜ"( ‡‚¶9l+&†£_1¦·÷«üVš`Þ„¾ :©ñ…¾ ðÏ\ýâ9>÷r`{¡ãü‚Ý/i]°Ü6À0!À6ì4ÒN(±=<}iC¦vtpú9ˆ` ì$Q~ƒþŒÊv?#æ]Ñ32¾¢ý_G4¿ðXüw³ö®Öþ“,Åàÿ W±Ë]ìº/ÄñàŠôßvöØ(£°ãÿ¡ð/Ÿ&:vÇ vñ#øcž÷kwþUù ÿ/û~a)¿ÞÆFš°¯å÷ÊW)€þþèÁŸèî ¬Xü=·ð‡¶|>ÛzP4þè!ÿ×Þ•-¹m\ÑïLòÊC\e-̓¥7䀳h$?¹ò ù©"åÛÒwín[xBÙì*bQ£/î¹ûÅ©7p"`³ªïÎüÿÔøCË•&/4–TJNú†ÛMƯ(_X½¼Š[m‹Á&ÝdžF\âWê”9&˜^ŒÇuà'˜XÿZˆ.€«¨ÁKŽdöxµÓ\⽸_ÿ4ŽR·¾FZ—¶~÷¡~s÷¡#ß®3ãpRA=XÕ‹ƒoík¨T„\Áûþ¿<%(Ê™ÞvYý,XÀ«²X`4s­Í³ø‹:ÕïÕ ¨|ÎÂCÜ( ñÓ˜-lÁ8…VŽ(ÑèÂóL€Ïûo-v餕žéß³—ý×­?ú±½Úm3Ø—Q˜€8ê«çÑ¿»Ã•àdKkþ¿jè1 z†³GÑ_«»ödø^@è/I¶t Ì/Ën†.KiOº¦À÷OÿëqÇK–Ôm}ùX½½ÿÐy¢mûÞ’Î_¯þÝ…?Ì8Ò¿¹=óÿáqòòÿYâ_¸á¥4€ÿ¿0£<©|U׿׈¿ÇZ(î¹ó]|® x˜{kmiTÅ7’Ì}‹Üé½þ²åšÁ·›„vü]V°Áýõ—ðfÔÜ#ãºÆø¾x¡\õögÌ‘mþòïÞ·Õ-+ßõÖÔuN`YLdöNA€vHXa@¿ñÉ3góR-r–ˆº-KF…=ÆÀ=èÒ}¤H€þ¦B`êÙ ÊQ'»ñ\ÈP³¾0@A³á0<‰ŸÕJ“p@ÿò!ä5å³³¥ƒÐ/Ì ÃÀ…Í3gýé°‰þ**t‰Rñ™ÿölúGû1p’©úÿ³n@à`!)>ÿ&â·ÓßR’Ž=Ù?Møgúû¬ñ€O‡h¿! ÀM6¿súÿý—2€åç' ÀÙÆ„¾Û 31.úõÅG¬+ª‘þõ.©ëmÛÔöÌÿÇ]þ¿¬p„ü_Zp3Øð„ð†SÛ Ä"wa?ŒÌõE‡E°» i¶õjµñýXpObÿY+ + \ ¬ÛÚ­xùSð߆„}qµo2!÷>(ì L¹ÕëáëõCïí›üXÍ€Õî†snÙŽÌói™›l‘ÐÞv™—2Š ƒ¶ƒ¢ãÈÝeðA(À–™—ß„.)E&(x¬6‚‡î;°3à7I*M€x>… D×9tJDϾrI㊠C†^Žæ¾¸íÄ.œÒ?LOÔW]/@ÿ‡L®¦5Âüÿ´Z®j7üàýlÛŽGÑßå]€æÜúaŸþûr>;qrµ[ºðôéov7‚L~~¼dÔy·Žô‡Ã Ðß¼ýØQº'°uSW›3ÿ§.ÿŸ-þý‹j +ÇMzj_Ø÷N®~Ît R Töý+Šè7.û£ÌÔ €Õã ^W±þ…uš°s i@êû'Y^[D¨þánä’.ÖO2'0±*ÆëÖö= øÿÜzCìì,f7UíÍð3þ?øÛö%^µnÛ%?<𜼆' o-fhM=€û£»'{†.r¼lìðCŽ·ŒR”Œ»݈Ó4 Ÿ•Í’ù |JS+6ŠZ°Â”sp©„þ$4SÕTælScÒ?ääI4d+è‚yµýíý68}¹Øìsâµ&ú§ZTÓE²áærg\BvÈþË„?ÞnÙ4€“§ÿOwcÇ B´03ÎK†$?l:è,Ð"þõê}´äW›­Çd ¡×TõxæÿÙqâòŸlÀEîò'Rø¦ù8¤|uvLrž^qM¢ }ÿØÞ™ Ga°6ò¢V hNñ4âŸqNí¶|XZ³u–"¤†øËf·ÉÌüÏÚ¾SL2—á>Z|ë0¢²jÁ»àoÈ—áHÓ75d+ìåÿ‚K07„àN½ÉZº.T–œtÇÕÀ6‡Ê; „’¢¤ÃÛ &ñåesg@‘© ýg1ÖÂë6‡àsšmzÙpË {v2}] Ú3ÍЧ5tI4çÖŸÅ–ÒŸ\±lÎé‘]ré¢;àëLô—,.®GQRçmwý=ß§hè½lí‘ STGØ´Æ,—xtÑ ÀÉÓ¿ÛmµþQç Òs9¯üÝàÜÚïÀÞ·ëæ1pc$ߣÓÒÔ•9óÿÜøäÿrûÅ4€£$öa`ª<ÏèÒ‡î8óÀÝÄõÏ&Q@×þF¥6÷ׯ=Ií‹J2vÿH ÷…bÌ~-õ³"[¶X^ãIÚów8Zà4O6¯wc'îÄQèšÔªË]úÛÁùwÈÐðÃÝûxqíFBù£k›j 4b0*”Ùh0(¡ Ø­ç0(Šœ.ƒa—øÓi;fŒÏú™O¡6»Nמ `agÔåê~Pt— aÎ &‹ €ÊÏ&€ Ï2>g‹P-žZµÍã>ca[”}©hj žj»7YôûÊÝ VƒOܱr´¹XŽþãi¨§²XI)*&d¡YøÓlŽ£ßϸþçG¢¿/ÎNï…è·[Ÿ:ýW»›Þ‰nÄk‚ž\2X½+ þ°˜H׸ÏlƒôdŠô÷gþß§-ÿ—ÿþå4€ßYø¦{NÆœðEl~â"ÍQË>£—´êËk_ûMæB%‡4Nú`µ:7üµ m·©×µMü²D@oßô»!wÔ±jâ\Û÷Ì©›(!ÜEx€ëÛWïoãWî¯iUô]S¯ï·>]”PKÖX2œ‰sL-a І…^¡šŒÃuÚ3@óåømBwdq' Þ&uŽ'¢n Ô¬£Ä_Dôg&Àa ˜C€O ü½¨:eÂÙ £yòGSòW—èÏR:“ÅÚýu_蟖H϶¯o–¤ÿ¤¿øÿ=?5h@å\zˆ3EßÏåö ý'€ÆÉD°”…[Ÿ:ýïv5 "!Éa Q‰‹aÿwÑßÕí«Ç]<1Ò‰Ù ÉòhªëñÌÿÓñ§‘ÿ/¦¥ @-€ ?œÜé÷ý¼÷¥e_Jw¥nó©ömf.Î_$ à´éÿã#Õþ±mìU €éoa‘fµë;׬»[è ¼nßãÊTÛd€@6`}mÏü_ŒÿÉÓjðp UxœìXÛÚ÷QZI%”A:¥»»»ûiº»»Dé)‘IiD¤‰²öñ¼ß·ÝÇýy®ý.¯k˜™gfÍÌú­û¾ÿ+f„ƒü¾ pñð€þgst…x¸ÿG³üׄ¸ýÌi`È¿»¯?þþþü Ž7¼¿ÿý|ì,Çm‡ÈÏ‹Ÿ©Ü¾¹ðÚ°‡ñòð®9æCGž D&»Ã*å¾ýž¤]ë̆ĚæD$ÎwïT”ËÕOÌIŒL†&¨“86¯¶ù”qÊ(«Žg¬ N6‘ÂæÙ;HôŠª´99†Aƒ0,{¥S²E‡×ÞÝš}jÝÑÛÙaBð>X:»C„Ø!?vXH–²HDæî–ÀýøÁ‹ÌÂù–ó&ӘΚŒØC‹»Déëöúékf"|ZÞá.Î^åöêƪR܈—ÄÝ×!/ £^í’Uº1q¹*Û-÷­ÐŠôuï{+ûMj˜¡v¿iRºX~8í Oláÿl2PoÝLËÔ˜+~èÂQq‘׸œok±®A@4Þ¯Óæ•ô*2p‡¨f(œŒ~‰Ú¶÷ü iA‚`?Uؼç—_,`Å¡RÃ{ÜCjº’îËËAh0йèl}ÚWdßvu·_&1\`Áìì&®9 o)©cÔ¶²ÝjÕq”ôi".2hK ¿S0eï ¬ýÒ–a®˜)¹ +BѨ'߇€ _{*¯–›QþõT"“%¬R(f@ÂDüQónª’(S’•.‚D“ØòDQíuº€Q6<\®ÞÆ3Ü&Â×Ç8ª8ißó'+SiiCçéºÁ„†©ë†ðYæzh$H½IÙÅ™‡¢âô­¯ªûŽˆ„0oö=}‹Ò§ÿpD’@œc‘R|m»Œn#äü¸ V4?~‚R_@bÒ^t…}»Ì è‰øœøÞ¡8bŒý9ëÍxß²›Cuç#ô n¨aÎgß-${XÐ?|‚?rG–“,g¸ˆí¦hpUAÀEÆ/à??ÚP×yÀü²7SËØ‚9TÓ"ûŽ‚'Á#âŽäOñì]oìÎM¹#©(›ü$ÿçH$jëÑœÕ&lÒDnoxo/1Ϙ„à~Âm‹GpNÓyPfCüþê,qõƒ¡nx1+tŒÎ 톟ùK\ºÆ³"}q Ø|Nà˜>nÞ:=i+ "k…3ªr«ýPC²¼Bˆµ½“3àb u2Ñ1²2ÓQÖ40ÔÔ2³vp4sý—ñGÖÓ Ô÷ݾ­«d 4 ¨G@É¿œÿ>Ô“Ó”ßͪÞÛs$åž÷”9²º+«¶²Á4«»DZtm€eúÀô~q'¯Ÿ®šŽ#¾ÌƒÉ'ÓóQ¬ÿûw½)¦Qèäò÷óñt9ÂÿGþ¿s:C¼~*”þ @=Ü~­Ba?sÚ¿*âÿ!ϯk`0x¼ö` Ü)õ½ w©¬‘ê‚éÆ\¸ÏHC;º¢_o›«FL4!N(h†ØUVƒm1|ƽLÖ–ó:,dT¡i´b°t豓<鬓á£õá§-­#Õè"ëîù%ØÂIœÜþ«è:\i‰ÂüžÔ[GÊIXÞŸujë\‘çNS&9@¸I¥Ûúq𮩖OÌe˜l{M2q/퀋Ȓ·Áû2>Ÿ–av,>·|8—úè"¢¥ »Fž9Ë#`È9ïÛ!/Î,õvo´E©RìIcP5#5’}§ö›—¯œïli½¹óñ|{ôåFÜ\RsãUƒQ“KæðYÚù½*œÏëLÔ¬ÄfÙ>²âÔ ïyU€˜µ{>-¥ÔïR€¯ß° ÛzŠñ§$!¦b +›Àú†,»»Œã^]ÛØ1³o»APEâÈéØ:<0û„}»=î€5‰ŠZG¤à*ÅR)òÈûôAŽæDA·JjjŠÁWåb»±’B5sI*jTIg™„Á\ƒB@@ÈïsºG—5k¦TÖ˜†°ï*…AÚ¾§`gŸžoÈžµeRsyeî˜YÜ4ãwUKàÔÙÜñ·×ë°ôÌ+“çŸßÏ$À~Šm¬Aß®°ÂÌß”o>q=„  MáfD‹«7Q4öÒcád‘A ¹iÅÆLÎ o‹¤u¼¶toyº4‰ä·>BÐX„^sÓE±_À©–°Ó=ý—ðÏb]Œ3 "(VYvêÐ8pš×j™†øH¾|^ÓŠÈžFB&ºµ\rAé'ù¬©aÙî§^>ìCå¾Ð±è{÷ƒ¡ý„…IyéëÏ’±J>þ€?d´ŽØ‰RèAžþò¹èpFù/üC¼ÃúRn_ 9æß{Á¨O†8éS„Ö}ÅïrгLp @/–¨23·†zûZ…ù™ë«[HX*khšÚ9ÙX¸€ÿ›øï„xez¦#®·ïÝs7L@àKuumW/‰ÍØA½ØNàSd|µYŠ5ÏÄdúÂ`ÃG¨zO3â«ÞçjžDzã0ë\pÔÓlŽ)Ñ¡GÊV/¹ Ê)4]lPÙŒ­2oªx&Å·¯Iuƒ-zÖFÆaÜ®˜ ›MÝõ\ï¿£&¹tÉõb'²¤£?Oo¸spÕ¦Ÿ(¥øC­–¨{ElÍ|šŸ0¨²RØý¥XÒžÄ5Ý9نɞ·Šãió%sЫ‡Y~™#¸:Di‰ó`Žkù0¬zS>ÈUf^š7Ãæ>¼U¸µ  Èw¸ök¦ýpŒC^®5 TàêadÊðÙBPpÉË µ6C¦çܳ.2z^|WÓQÑ©éëê‚yC?ƒ€JÒ¶—AñÁC¦€¯Á™ºGèµ:Û3ÖΦFŒ[ýÞx¯&žå¼“ÚUšx¯é¥©‚8ê6ÓôF¦6Ý¥½Š.7‡µ•Mæ #VÐC0Íù8Åa2ܼ8ÍÐ\K»/IDGt}™ Eî€_ƒÆ®½¶¸Ë·ªïqéÒ¢j•*ÓNj_ô6ÿ“ÑhÎà\LáŠH}_ù+·‰TÂûµ{ÓB…æ&FÄx¤3ì´ß™Ž \™´eõ× ‰ßŠI&;z†û¸8þw”xÔ|„×ý Ÿ©Es!CY| úodYvC² µ‚y üHc †¦«­Dªw±  —TÓ°•·„ *_ÅvÞÜêžèu^¤Õ„IJ#—à2%ÚùcEÔ¨b§…EJýö³0nB†®y¦íÚDt¼ÚäÒ|™­VÉLÂH¤´·}CxL¯Ÿ$³Ã bp}MįvÁ2Ãô.LgÜ̘j»$Š ò‹ø óȺõM™5-Ê‚ä쇀(‰Å¢—[^¦DêéõZ›Ã]Ü=?É?¤8œí}àHÿ¸"Ä ¸3{“$°wÀŒðŒCŸj?(ì.ç~õþôî õH3!OlzÀm\Ž{÷…ÿ 2ÊÁ+ò”ƒ÷'üù­Ò¹Gâ)<Â7ç.Æ¢w#Ûêð 7¨Â‚“ììmŒ®`§8m/s{w{m5-9-}Cm3; kÀÿyLlÑ×ãZPês$ª-:Ÿ«SnÑn3AVçë8ÇòÐG„c»ŸEâÛIX^-¼®?Y!ì^÷ŽB9®¤jæã̃çwµø°XîÄ4Zq‰¶ÞK· «ëgÐZã•ÿÙ(ÈO9äïãëë t…ü× Ìë§Òÿ—º‚ÝÝEΟÓOvüàßÿôÿ”ñéòèðûABÜ”‹Km¬M]¦ÃvF:ù—W˜©-T¢så"Ü8é¸ð8ÊcóU£Þ6æX™ÁÝS´´ÚöS¬»¢ƒˆ‚%qÇDÓ1c“:ˆMF¾þ@ƱœïqG0Òó[dƾŸYÃmo_[¶·¤RÖ¹š†½ùÊÈ{Ø?ñ™ƒ<4ÔSªmWâÂUé(…Yçìx¥e‰~¸†MÝÛM=5¯$,Ùnˆ‡UXä4_Pk‡ãñ ÛwŸáºÚp¾ÚÇ&&¥ëdDäåJ RÏy˜ `·•ñªçŠô·5Õ‹Ž)òÎeÀO ž¼Kœ*G“A™‚=€Éá}C)|–Üœâs\ÁŒ-Op.¼NbÉÒÝ®ÒÍ(½[Ïÿz:B…ºc ÓêÐ÷+„ËRÁÎq¤áPO‡|¤ªG#Á ‰fòÃÿ0Áõš°:íp³‘<Y¬úY-:¢)þd—ÝbA‘—®½£îƒ|Ô+Ü• ’†Ìkã@™G,ŠDyjºŽ•‚z7 Æ›a,±¸ ¸äérf}¼«Ÿœ-Û$R@èIäxa|(Õð/¬E+ˆ•eSä„m«õXÅ^5Ïñ/§R× ¾ ’嘳`“‚›ÉzS¶ÜM„{ŸÇAÇâZR9L¡BQ”z˜¸ƒ†r;!ÇœÞdO>‚äKŒÃk) ŸsEÏl´öUé6|¬­?›%¤ÄŒÐ×Ý™£Ò«~cóã= —µš×Žk㦓‚45oÞæ…‡íFYâ˜.¬¯g¦ôŒêíìÑ£Á7ö´6v¿@%ë Ô‡±¼²@®øuüeV7tãK¸ÚŸu=UÓ.XV£0%ëo†å¯¢éIÉGKŒ¼Ê~–?ë…Tcå$ÍÆUÞü›ÕštëÍÓ£^ÖUŸØYÆ®ˆ‰×{ÀŸÒA7Ɔx3C[ï@TJÑù½Ìþ!æ ³ ›ÔpRØÇüCs¥£¨à†.±I]S]~B¥rЭ¯ÊmÐb㙪54uBÌ<í½ì fÎÒV:’Öê:ºš¦ÖΦv ÿþ‚Ü:û¹w‘5;¼uuocƬ¦ÝÁÞ¢£·BÚhm)IƒHáBö MxÐQ²" mÆ:8¹R âH9`ÚõŸeÿöŒýB þþ>>ÎÇ}Àÿ äôrÿ5Yÿòi¿—øÃ ÀwÓØ4ÛÌËp¥Ì…^L«N„·ê%‘½oFð^÷9¸ö©´VŠP™ØS’Ñ4Ü â¡1øVöº'ûpö -aþªþ7•Ý‚ˆÅuw›ôاíΙ׮!ø£çYö1ÙÝWéõéÌ ®G62œE÷Òd¼Ž,U2¼vÙtu4—éÆ 1‹YQ²—R´çkU„l¯ydFßæé\«+N—¤Å©£zì—“Oë3ð˽FÝܲ|xwžàbÉ•cÑó•çõD¼Õ¥ƒB2ɽvA~ª‡éšýIÄ¢ìÅáFü+Ë pr•¶Õ݉^dŠËSÂ[ø4©½Ëj]³^7%Šcš•ïû¯¦Ùˆ¢¶Nmß¿¾úâ)÷ø£ÊõÕÛæ“æÑö¸>YRܪádîÑbw_¨N¼U…•£t`úî½À…Í(ø¼*³&¼÷‰ý¬æM÷ë™yέ#Pf`¥0¦RØ„Ô8¢ƒ¤í (­ƒ¥äÛ=Â^Ù§Ò ¹ÜœÏxa &Óˆ<¸Ï´AŒöÑbë2ù¦Ù…õó­y‚MïnH4# ˜ÎGúª_*Q­¾3¨'ˆ¿ÑJ‘è&`0›¤Aªµ’šBK¿æiÀPÒë}Iˆ±·u>Õd\„’U)À{à¬;`‹X/‚’0)å-(„JaV™á®È`ˆ=øg‘Ÿ(80ºc•KÑ)ããbâPdÒUr"b/UKè ¼“9†—ÇÖIb{IÐk=_—Ä2ƒŸé\aͧÁ,Ñh‹Å^Ë—©Àë°·aÐïöä³Á¸/»Ðâé6ƒØw»åxÛšÍääõ ;Õ+òSM¬2h´Ž+÷㯹n攘f!×p–x V£(uºJÙvvMsàKüRþ7UÏ]X µ¾M1¸,;z0ÝgÈÆ-@ªfAJm òoID_ÿiþ{¦„•Xg{<ýä¤Ç"`¹‡$%±ãÆt±Û;Ü+ôb?àÏfÇJ«Zú!^bwÑ£‹è.*×gþS½+L僊LÍúÇüsø`Ãdtý{׊Rî@/F9)ЄvX8GDBœm \m|ì£4£´\-¬uu¤Ìä4uõÌlíÌÀÿü÷Ưvø8âKww$¿ÛÙsLëãjl²-}ñ‘ïÍíþª9bÞÒªW͹SŽÈðÄõÏ¯Õ š8Ÿ³|s=.^W+™þí Òùˆ0¶ûº¤âm˜üüèÖÞkk“a7jÿ9ö,€H»Â¬ãmƒ Þþ¾nÿÓÀ@g7Ï_ÖH\až°_¦~vàO €?5)üåïÙ À™° žÉÏ6SÒ}d•«c­õ(¬NùˆüêCÑú×Ç„ ‰PCzžÅàN“)Ì(-7Õ}äë^TNÆe¦­4-ŽŒ‰àa†IªjS=ú’ t ޝ–eEæ€28ZÒ LžÐÝ×X‡Š k‡hŽyjMñpêÜ0b`ÔûŒåµ¡ÈFþ½Ä¶~S<%µ°¹Ñ{õ-WQÐ[²ÂáöÀë u÷Ú¼Î;,=_{—'—’Ù­7ÊüF´ stî­,}ÁÏdšUP9_kÌÐT™}Ãrøé{ø/)½µ¯ÛIæLúÇC/£tàó[_€ã:m³ ó^{mËrÊó8CÒ€‡%­›Ä`m¤)5UpÓa1›ÙSÄÇ’›I]ñ9c¯É=¹8?I\j¤:î %¿†H˜'U_஥ÔBȰcÓ®ø$¶\þ¼T¿Öç ÂœÁ:ÇðB T0äÇcvõª·z ÌÄëÞ}Y:ÛÙ=Ê­×zU ´ –‹ùB:sI+Ëo/v%¯øºPs?²É¹ÇÉ\e×UÐo…B!Ms·Ý½“ ž–³%s,C‰¾ð4Ç]0ςŵ#×B»!¼ ‰«X+hŽ4mùG\ʼn-–©Ý½Ï9 cI_hë¹µ¥hd¢µW â º| éM‹eOþÑ&#ÖXx¸™Ü#|ãÉÃMí[i@«‚ jȸÄr8u?j1ƒJÝ]Ù]&cówFŽ„À©GöÒÔ°ke%6iö¬,^¼ríDØ7w+IRo 29ø²ž=RË®wïÚé±bñY”r" ýàl: í Ó{Ê©@¥|=®ürZ[Køã'õ¨÷,õijH³8vÉ*¬ãÓ½èXüµü7\ž/`T|BÀõ$a?zÇßd‹·m;°¬7Ät£ºPÂòíÏò_¨¸˜p^½œZ½fŠÿ*¼8°؈Â:ÚŠÁ[¢Àt"²àõþØ}iwíŠx(Wrr£Â4™|<ß}æ/óܶÿšÃàø§þÑö»´ZÁœá}ÁB*"®s–¥‚}@Y&>z¦.@KOgllªkii¤-k i¤mdfïdeùµø7æÿÄCe%É?ÅŠk÷ÈöÝúX‡!Gš°c±€‘ozW6»FEØÓ¢¾ÔƒÆ}5ymìʈí{ÁG¥c÷{=ƒ î]WrÞ`M€± ÞE¸­è4ÙÒ˜­ ­þÁ£è65 Ö—ÙA™Hñÿû÷¥‹L°súø{ûúú@\ ß^€œAÞ¿p” rº{ü2}ñ³ÿc3ÿ¯L€þ«8̦¾“—Œ(¤çsûul¹? Ž¥·) S !¤¤òÉ|ì+YPÇçeª[ƒ#U#ÀÛ ÷Æ÷ÒsEœÙ[þæøž;¬´¦(­Î¦­íƒa„>ÛE–ÌB6ÈvbÂ5y©’nWÆhmRUÎðýµùñgŠÏ4Vi–kÍ:2÷ûL!ô—D;‘žª{^YŸ‘~xMù-KûãÉúè×Ú#9JÕ>*ÒÓ—˜}-Ši—çš?‰­}¤š´·ið¨È÷†D¬Àqë¹&YhØT¶æÉ^Áã?8DL7CwM^í|Ÿ{§âz?ߌ–ÓEH`U|o”Íe¾`ÕÞ­{¡vªQÙmºšÛ&×_?[¿ÊGäOÙï‚°cÏ<òvG×–MÒ–„ïþœ&½®ìúàZð2p1}Ü ‘|ÓuŽ~¿: 6âöƒE¥~X1[•¥œoÿÒåv塞Rä‰2ëËe5îWÂyêó\¸³C-×K :â(Å´Š@VºéÌüxuUî²FCôk]Y,ù¢¨hi¼ÕSóÅ•4|] Ñ`Ÿ7o€ëg‡àE›cm³âF‹Z)ЙO¢÷Ý"Aoó3|é#øÀn-’Á³Ëþ¶¿»íÐÞ°¼/oËÎ¥þõOÀ×oÇ,ƒì£Ô“5f®TÂs>ƶsÓÅ"„ª‘\QŒqhhK!.ê»'¬4ÀKy)îõÃýy¨ådxwo_¶UÍļ»jú`ÞyÕ¼ÙåI#²t¶}·ò›²šyfÍ“l4;Õ«Ò¢ô ¿œÿ¢ØþäöƒwTÌBoÚ›óÎ-©+'™Ã‘ñ†Þ7~Êi܇öZ€æ§ù«‰»j¢h7xá¾ô´>O4qû6Vz`ùc‡ÙéHÎ…71-¹?àßBŠ˜ÉWaC)"Œûv ¹lò…ÿ¢áÀö¹w …'ü1 óx«˜:‡øC«ÎÉKt·F8P¨µ… aÞ@€µ‘£­§U~¤¡¥‡™¡¶¹„½²¦†©¥ƒ‹™ ð·çïÅŸ[€Á›ÌkIç¹ém8²ÂÍÉ1+0Ee­¿áAÝÉÙO4eš(u“ße½s¡CÛÇ1/ùÑÀÒœw'o©èA«G‹á¯˜¡Y6˜bÜL½‘§¦gÚ‹‘xNTŸÒÚŽ(åÖF^ð?ÇþóÄ•´¼ Îná0ß_Wä7ÿùwÿþå ¿rôKÀ_™ðÝ<À/ƒXd×#F‘ãä4^±ÏKââ9csÒÈHÇ[Š.CD„¡t{DW˜öÅ·Pø`Å,…Vl­r`ftRT å2ßÑ/Ë…{@"õñ‹Ï®Óöó€7ñŒ[ïs1½?È\1ŒõÜÁz¥sǨmºÓõ†³.g9†=Áõt^ÏÐ ù9¹ñ…‘rɱ­+ãM ±…º`¨^º{ÏZ±gñ‡fF¬Ž&î’,2 Î+äšÛ²h¹èçI;æ‹Äο!á ]}Bo¯vï}!öV‡G݆Ÿ)´v„¼o]»›Xdž‹]YÞ.£É%m5õ1<yÖ#ã¦ú¥P¥‡a®µVLFC‹¸«!×v_´X#oßSå»uµT¾ª%ÿ­›;±ž€¡¢ÁëvÖ÷(=/gÖ' DŸ®.ßyŇôV}xÝô¤‹ÒieîFÜ+$¤‰ÔOÛÒ·@¸Ù‡0ŸéêTk±›”,¨3•Ý´NµâŽ0Â×YTd‘ï¶-PÌÕ½„:vU>Ȭ¶¾QÎúXí_©ÂßµæÑlØ«JÜé°ˆ/ê¢rž™j ¿mÓ„¦³//Á¼Ö?á쩪]ùh’pIœŠZsÞÈ?ƒX8vB@¥óÓßÀÿ¨V._9¥Ì¿¥kña¶3Šue·ÞÃÛß_KÀ§üçù'Gx'¼£8Îa~-å®Ê‡HÚ:û„Aõ‹pm’â±Ï ’£/Qþ€zkUµÀ°¢ÛV®ŽÎ;1¶‡_øßÒ$tº2&²Ë4·•rÌŸ›ìRã{,Ê×ÌTì¯ZaŒúçâ2$)|sƒƒm"õ ¬A`oO{å; U9#]mSG3ÐoÎI)¯ÍëÃÇ øý÷ç#Mhxe ˆæ¬Î=•IAHæcWåòJnDÔÙ¶¯˜I&di>iõf¹¢=nëÐP©—Ä`…´`Õ ²ÑªûÞïR«ÂΚËQà×eÓ)æºÅ[ä þÙA„n (äëïãñ» ÿñwÿþ˜@Äó½ øÓ#NüÉ¿~ àó»€FYÕ¡št±wU䥭sècéŠÖ+§GÁmn±>hýZ <’¹ú¢™/i` ‘ìé˜Î¤˜‰r2OHw¢[KrQymÊ$Í']EÆ?ØH¾1¹zî Aþõ(í÷Û bKÿÃÝ& ÉÌ(ùäD°ZYYyÓ:øÁ†êa¼ R#m‡4ëôè\¨<…å@·Iz- WÑPôü†0ÕÇ1¾¬à£/1î‹àåXÚ|Äò›ïxd0=gi€w6/2Ý7PÍ^åŠËýˆ±AêÞ¼/Á~ø6Ï#Úu'Wºuìí[—ˆ®aN¸/‹n,ï-ƒY©¿5¶zµÒœÖúÊùm•83n[ÔáJÐùO“ZÏ“^—ÕMßíD{%¡–èÀ^9Áæí$ß#ð wa+ö_0AçOb£D4.½ˆÎ?à ‡©:N¿E`EN_Bl3ÇÝ€RÈ$Üþ,TLÜu&+8=ø+6ÜÆD—Á–»™=›{Zz¼QÂ;‚øúÔ IrxJ&‰§lV—þn%óÆÛ±$x¾«”ÞÓj{‘¦†×ƒ19‡Èg­>~\ÚöŠ`ˆ[òÓ&–ÞK”æ¿Ú`GÚ×~'áÊÓ”òF‡;wTÈ”©·n`(Ô8Ë]ëš»ÇMC¥´Ú„„L£õr­C<½ýü .ÇU'-<Óïàu€H{÷N€#ª"ÍCãæD±§`å ¼Òai%àN,b¿g›á}ûÂÔ}®»…r®ß È1BRŒ¾ˆXŒl E⸣~¡TZnóaƒsOhÊ`(W\•q¬äþ h¶M}Qô˩ݫð¡aÑH‘ |^´”¤[LËZÏ÷9÷43$|õœÊ("®â&Â×ö*Z_Ò§cq·Qþ[ø¿¦ã#+YB±ªþ´ WŽóš­PÜLìmSú=ÂþÏó¯ƒiŒo%Q\õ¾Üá÷òð:~]ïÞ9«~ÔÈdõmùé%©buõñO0xÇIÆ^ËÂ3Áé› ü¿!Ú`¡3Q°[“jã˜ÿ3KÚôMía«+Og– ½Ú×ÉÝ ‚XxS3’,|}a0;GGgG˜E%ÈÆEÖÊÂP_ÚPÃèÛw[þ¶[®ÔTIemÇ úlƒ[wÒ¼ 3úÓ( îÁ“7½¿",‰.$t~s#—ç^#þEŒI\áiØR”_ïƒm)5¬ž‹_¸ [ê‚èÕÑhÎôÖ(“ÈWŸÛpÇNE·GI,BRäeÿQ&©Þ0//?ßßû]@+àW¼û÷ƒË¸yüši?=ðëøÛÕ³A€›Ó¥Ì©È²åб!XÌ‘˜®/xµtõ•^}XU¨*´åy²wÍYVâÕ]²»ù¡„ë® nó³Ü95Å“¹¾€(«ü}ýµ K|ògèn€~¤;£‰4—d®ö"9‡{]Å`©8¤^#û63¼È?ó–6hœ|îMl•çxxÍì¢åµÈ7U¶ÅBÄ,xeã”9ÏuŸÃâÉòKJì¶ÍiÙ~¬¹´[+%c ˆZð˜{øn­5dÝ…>wBnv ~YI¢`År,ª¸ðùòac™Ë!' €{®Ã ÉÌ3XÁlV.owù®9ȼ-È6`»ä–=¦ìþ²`/÷ûœ`çËRE¡7öcß#Î…4´À7u•yp/{bB†Ÿ–W0¤×÷ ðÆ&ÊÕƒ˜@&²dòÔýb)—˜.b©¯q,*Ý1lUÅÏSwACxØî±S.‘Øðñœè;ó!Ô¶}™ì?¾RaãØ×bº×evjù¸ÚˆÀû e Z®º­1Z读*ë)Í&«Þ>8X%ò¡œ.O®½Ñû}O›ùqUF’ž±x‰~›´tŽÍ‹Ê¨‰duŸ?<…Z&G«µ 6Žý›œ=åלL¯Ojâ{é jiRlÂqçAÙöf8sÇúK´¢ ª€2r!.‘žî‘n@Ç#‰j·oÂvȹ‹Üu-¤gÊŸO‰±gÙvÌxßçYƒg¼3#ÒÚ W·°Í…Qé&”&þ}&ä}ßmzi»‹‰‰W#Ü`ôvˆ ‘ÖŠ»z oɸÝKÄ{íÈøp7ÜgnÍ%¤LéÖ¶Œo=P'–¦¸ü8޼¤\<ëé¥~ç++¥Êýk8íwgog‹Æà>ZÓ|µý¨±Û#tuèoâßx£4h…hHèA!åöA„ïEÓb ™KžÚÄÄþÅÏóOl]g~q1=Æâ’ôRC™ýJíÜ.N¹ÀåeÔÜÛBm¸Ãw?â/‚§´©<’B'sµ!i¯ÏÍW×è ÿú¹ù1²Üü²VÙþVÆËª×Û¸ºs¯9ÅÎöš±>½·PoA®ý4\7Þ)ÙÀÌÔÙÆÉÃß(\hå`£j¤®¥¥£i¨ijîàlaøùo©K;½%õŽ~{ƒEíf dDÜæêº–÷a”ß©ËJOÌÄÃçüiY+½·oÃ/ HéÐ%+ýö@ ¯>Y0é–ë¦}f(w!!K¿£!¯DœeT|<‚É~ùj‚ˆËÞ®0jœE)[•)Íýýdå³%‚@áž>~޿󻀿êÝ¿?&0Èôk¦üüÀÿÜÍÿÓŸ:ËúËÊ黀åU-¢MÍUuj0z™nº´¡ÊAo‚–t_œS¨Ï°ë6›{¾Ã&GèI™k^Ó¸8}­\ÑÄÖñ5„V‹9ý2ð~kËEÒØ Ó½íËÈfà´â‹AbàtÍR#`Ÿxt·O‰bén;paÕ¶ˆxê ç g=‰7õ{Í."ÍqK<á6+£?˜±ªø@ãr;Ñ=©ïZþýù²g€ð4x@M£Ð‡ÑY#^›©{Fi¼}¹o(Ét(I”5#îû O”«ìénBÓJ‚b6I"ºV3tŸ ±”XÎË Ktz®d×ôÚÓ‹¼?DÞ“_ÒÅÝò—Cy㾟G±FJ‚Ñy%À.ÇqÀ‡™ b¸0YY×åîÑíkÏxÉml:ä-dYjN>·s5½wQ54"m…Õ›+?•¶1”¢—eË­m3Kðæröù±‹¨ÀXqcaðÓBƒ -åšG@¹öð+¿úr7« iÜ£PŠN^%s4jÚ2J jÊDJo|¢†{Ú¯…º®0e¹D@)K•›&dèd}»ª´‡”«MBÂoU(ä^§Ö•唜*°M9Kx MõË&bxu;Ê䎡„ÝË*¢Õ»ËZâ!•.ÜEäånêã÷2vìÙ‹û–£Ú¤2aÁiüå®ÐÇP_hë«b~]'MÓþÌïî㊹‹$[°z™(7Ͷ¼ɾGt.“’RnÊùWÊ|nÆ^À¬÷".qšÁô”‹µ5æädØl>GfKíBŸ³7! Ö—ŠˆO±žo½û!ðòFÌsÒíFÈ*ÊN’t|˜ ͺ»W53ûn‡¸r'Ë;h"nX»z”#K½ä’å‹ ÿ1±¿¤ÆŸ‚WlžÎŽõ¥°=w|ÛKÜopÁÒíà_ào#u›ðz@¤ ö¡ÚÿÞXm{ðú˜œêGÔ*„®`öU®ä©Öñïé½–ÜÎ^¥ÐÝ­°IBÙŽR°ÿ…ÿí ÷„—¹®¼±Û~»ÈÌ92¤Ú‡$y …RTúÆœµs$M”Ý)¥Öèçãc«cppÛx:yéÛiºšijªêikšYÛ;›Ù‚~Wþ׬Þ燫#îg±½ãþ0"¬ÔŦÙld@HP ¯ÜÊ6/úªûÐKá°•j*•L„ÔÎôûÚ¢b#{ZYéöV"ð5BX^ß¼ßï/ØJA¬ë¤~q0Xè*—ü¦½ïf6w³T»*èžÖ?Çþe“Ds@`??ooàoÿ'ÿýºÙùß%0ÐüKº~~àO €?Õý~äõZd“ZØ—Lá¼TʧÍ”n­ÖºÝÀ‡÷2/¥G¼T¥‚’½@‰™^Íĉk90¤ï _kTÞ–KgdÉIQ&H@q—Ì‘ù¢š7ÍÇæfhò&GË' ëôó;˜Dj“ø„Cv-Èu[”aùÈ4µA¬ÌµýÌb›ˆ‡7V™SÓžf³µš"ÇÍ>¸¢fù‚æ­VÍEælô;X—w˜M‘{¶[pÄ:@ …;½ìSçä<§ ë2¹cÒÚ\¼%¨ï»»Çäu)•Š# öÓ›Þ…k¥¤+¿wÉUâB¾Cü»+Eûdöv]¥)ç©(.n#±òôðÃ'~ŠpÅ1‹ìNõâDìõ]q»Š5—…£Pœ¿ÒÜï·B}Ó?–£!{£ÞrÁIðn0ŸHÖ< E—nójl&ÑZÇuwº‡¦nHÌ ™›ËÊ+¬Ÿ(ìzàáP3_ßÂë`M¾1Ëñ˜6tGà)z£Ðç—ù~b7+Ù  (/ø˜äÒÉŖB†ar¤ÏcYE0°?.ø\Þ?·ûˆK²AXúˆš8•Ð/ }½Ê‹s;b‰ÏY Énpi”½ãéA“häq[¾!NpO¹*ŃØ}ãåÃŽLZÒÒþwäq½ ¤¹kX‹ae€µ'á1Èk.1-óYÁr4ïoƒ£³n›«5¨&š†¹»†CœÓø .’Ìu·}Iн£ùĂທŸAíà9Ý‚Ø! Œ‡Jœþà¥håà èzÜcÒµ{»ãËÞhNÊ#é/Fv&\Kƒ£waåÌ=YË`*Wy¤wLxûí­ÉCÖe½÷)ìsòÃ6¯á‡4eP,IÛ¢Ï:ð<çïàªl˜Ÿ>DcK¨éô¿þþ¡•cÆkú±mºü¿•{]>]Ò}=–K±w'?x4,‹¯jÌ‚þ¹ Ùn|\G¤W~È Ý¾ÒDeT[¬}th‰Äîq—¶Ÿ|Œ.ôþÁFC òpbAo7¥AòFåüC_øcû4Üë ©e:æ?ŒÖ¼×?Œ &b@®ÝÓTùàxMä ßVŠß¦2_;Â)ÓÔÜÒÖâlªë 07Ò±2TQÓ×4Ò60µs´3ù=ùçuŠpcXö0Ù„#v™(Dë- ʥ̱¬4¼#Ëðfõü¶""ìíÆ­’ 7éLÈÄ6‰¨'QkÙw›¬í®9bXÌ0]—Ï17Ã"+2N« ÓBhÇÒÍ߆èe¸óÔú6'_Ô¼ŸW‘jAâ÷±ÿL>ccíbƒP—À㺹¤üéàô7¤_ûîßà ýÓ~òÿ8Nÿ³øk“¾ÿÀxµrý@6NB˜J¹ ÛõôAÙ÷Qò5Í5Q¯gN,LÜ©\´‚“Dx%T†xq-<ØZpƒÛ¹OíF¬½úŠ~Õ ËU†ÁsÅdò°ÎD¾°Aã^äÐ7NÕÕ€rD˜¡1 6?‘à ­jÅ¢qƃ9ê«@*³å<ícÂdœõ·ßƒæ‹Ú•£E4¤î{¬¦Ýy¸TãßÛ"ÿñCAëeë†ni_ xDÓ—.<ÉðkJ-Û1â%8L VšL¸GÃ÷€º®øâuêƒb¥3V}Ÿ®4Hš÷k¾öP¶ {÷â#C"6¿‡ „툅X…°íU¬Ç„Î^A~&–ó £Â‹Î™åç\͹·ÑPšð§Åè½ò®¯,£ù±¹:ÍÔ¬¼˜Y‘¹ÑТíεŌ3¬`ª¸¤¦áR¼ 1¡î—¨½sNïÑ5‰÷¦[Öì—3¯ö©t*GY8>wçRK4[Mzç[%=†Ã¯vӃÑ6Ó¿Ì ­¯[ðSR»ü<Öû €ò»ÏïzTó2”ˆ÷Eîj;ÜWÕ¦j<‡vпOQ­EÖy®¿0iF‹ý%×E‘wMõ¥̼ ï!•؃j…zŽáœ}ô–—Í©´2ü{ß9ãߌË—óYoˆwô±U„pªŸ»eÕ¿$a$‘oª• ð ÷ Z?á›@Ù´ B.Ú¸®ß Gêºç˜ñ¬ n_‚ðz´Ú Mìí;·)ÞÆ®~—S5ÿ­¿—¿CM~=œwâ¡<ô ݵ·°žØ€˜Ë¤§·þ 8ìU(ªpIºQuЂÓ;üº4:pö" A ϰÚÑgŸž—ÔU4øÌ1†ï¯_<†»œ…K¸Ã¹¸nþ…‘`øÁNWÈÕ¦’þ›S‰+ÑêÌ7Í©¬QÀ¯íÑñíjõîKB†]ŒBü‚t­]¬À®0ÄJ3ÄÒZOÌHVÛÀPËÄÌÎùÕïÉ_P¶c"]ñ9}´zë妨ð¨,Ua‹—•q![ƒŠ)F›ŠÃ‡ˆ´"Çðš\ÓaT›ªÓ¨Å²øt,7.K¡§L šfÀ•Þ–Ub‹âÒYh“ÑÄÚDß_b×À©‚Ú („_ÞÑr0øgÙœ`$Øïøƒ€ñ*.ýM äòùÕ“ÿ¾»Þñ4€ÿøÿÂÀŸ>÷/Eî–•iƒéú¢ ú —AÏ^Ü,¹„—Öy®„bÄ'-U‹x—pÅô¡ðèÊÒÈÖlDûˆ›ÒØþå€ù“éåµl©3 ÎhÀªâÓ´Dâ"gÓ2®0»ëÑŠaÊ9øRr÷ŠrA’K𪂙dêrê,Ë‚U-/ô8Ò<¶+™u†Õ÷fDY‡Å@·,ö £Š¬ïëü8M jvž¢0õæ<øz4*™€¡ca€EÚLéyÓÛ 1“¨ÁUŸ‘°78ëZûK}¬“ëRqÁO”¸=ºž#×µ. ¼ã';ßîmˆj>Qf1—1ßGËm³óºLzÓŽ­²»ý*êl|Ÿ"Qß<¸'éE[Õû¡¤&oßó,ÄŒ^Ò§Ô\æ|ˆ<¼JÀv~óSâ¡XO±(Pí½ñáÖò«Û¯Hð#/”ò¯:T]Ú˸ÖN9¡³ï&¦4ö<ã–f'jðe—:§ÂN”’°bb󺑦íSi6´`-qÇô[zÍ\ð`pü0|uööAôÔù+èEÁ•a—¼9UótQ".2{ÝÐõÚK]týa¬%Ü(5Â'ÕdJ,EZæzY¸«Õ§þ%¥ŸpcÅ¡šlA=íL~ºœN!¦iRhoæD™faNaƇ{Ÿ! ÈåF†Ž'BŸRMJð˜Gû+V˜x‡;ÄžòŸÅys¥ ¾D“l¼‹˜Ûd7Wêq3 ‡ ¹ÂºEYrêãQk*äJ8ø9ø-i5IÏÊ&Ù@wTå,cñ£§Ù|<`Í â;'d$½m–ÖbjpQ Ã>¾ÿ æ]áÝ«ú7÷¥ú q1Ù C3]‚6…®“×]« $w0òÃhæ<‚™»cݤzÓ!fýíüÇ^Å»¥ÂïjqAn<¦o–|=OO÷WøÇ›ì¢‰ÂsÒ¿zˆÊQ ‡c Á3Mºqž®ÔäêM‡~Ž`pGL‚øÕñ¶¬Gù)é–B$•rܺm5PPOõ ¿ù¢Ã0!*¢ßÉ aÅꂘµº3ùëÆ¯+õ&m ìh‹ß)xnì Ê´µ1·µ¸zYœí­-,´åõ tu5Ì,YKþ·.3àçkÇ_ö‡WLÏïÆÃ±"Š$/ɵœÔVÆrTcÄ.”•ØŸip¨Jˆc‹I2ë•™ù¬ÐÍ'ï>w4ZÒï÷mëišé ®Q’v}$g¥­?jÀÒ`‹›âžûÑ8Ii÷éŠÝö;Qä„<¦uLînùæý[DùiæÙøC|rþZ$ù% ìêâùkßýû—+‚\@ÿñwÿÂÀŸ?õ- ãU:ò.‹ÑÜDgÜÉ—: Ê7³¢éÚ \:¥N7â¦;{nB>‘ù4oLuP… ›-¤,Àœ•µ 9Üôy¿Ø×½D—w§ÉjI.Ø ‘P׎ÝuCË‹C›k³Qœ ÅWN[ƒƒàRþ¡ž'á]ŸhM7­r´•l,ºµw šœ,&^«O}çn,ÀíñtÚ/ã”]V8wó à Fï÷ªÙ¾]Í·¢¨ÚŸƒÂJÇ>Ùš{÷ÖÊØ;±ÁžQ’ç)®Mo+±õ9žÎŠÐȱû(¨1òOÌáÁ+=þ«K¦¨jÙÂM{×£ÌΕmÊ“ h§”xÇ)¯ÎoAØXUy E1wä‰vh8Q*0ûFßXŒÝ»Þ‹/>P\‰@fÒß>IT¦˜8q @;Ó€#ãóH:!Ò6 > ¿ÒÛÀ_ èvQ°k Œrqö¹¹Õ»æ¬ Kýfn,éxXQŸR|tCS¤îä·™ݳNÎ{×¼ÃUˆ¦ËÓ2ˆE–Õ·-UÛ—F¯ŽÓqÎu/Ñ÷E<®izþcAK=›=G>\ĵ¶)¹…ôiÓ×A«Q+·Ç{ K39c ¢syžtqM‹³©V¶œ!âÚ\‚¬”XËc=Fæ Ø~ËBgn=´"^5ñˆLC­±7×ÝÅÁ4|EÙ)€€ô¾Ôö+AKÛ&'yý"•í€þgþô9vïamAý«ŠÚìbÝB,€bùó¯ëZ°ùÓ¦25Æj²G6K.Ü<¼J„Ѐëq}&”‰‘ WYä MHg¦öÓæ|ǼKý¢Ò95EGêÕ<øu [ ôxM­’ø£+[KÂz’oËF>‘h‘‘_@t‹G/«ôToRöHwá¼¢ßüÿ¿WÑ6Ff¡}NÔô V -Iÿ\:5›ý_á'£Ïõ±Ž«gËV[¯j GV¸ÏRp±3$(žC¨åµÊƒ gÁÕñÉ‹«-a{ÿaÃþeÜr`%Ú\a%ð ÿäwœ/yÄÈæ9ß óY1wá¨)Ƭ>âßajéÑÛù\œ·ÙUýŽÊ Ÿ3Ø?ÚÅÄÌÅÚ µ÷µsv°³S´0·UÒ×ÑÕÛø-ù“{s\)Ò6‚}¼“§Wçe£CÜòjT÷3þs÷Y|Ò½0üÔÜB¦7õ‡ “Ó¬çüXQÖ‡;Ù70ºÉº¤3©5Ãï´(KÜÏÔ6 ’•ä–­è“Ê}Æ8gîµ]{KC~ºRÞÞÒ'ïÓ]øýË©æh%تÿLPú›Ðæý·õþŸ%ðÉ6øaà8HÿªIo$ž:žxAÓñÕŽ} R*÷…ä;.àQQž½éüÁð¬ÿ*ÃÓ8œ”ž Õ~XhPRðhá÷lÆçV¹@׿Ër5Å[“*ã ¡xnoæBC÷r´"‘Ð ëGÖT_؆IÓ>K¬Z`ÔH57¾¬Ö‘3³¹ÏÕüMŠ¢™m|ø‘üŽÀ6]¹n> ¼Êý—]¥R©«À¾ü•;}gËâ¤>õ':œ‰òÚ3¹.SÒÚ/+¹á-½AÀGBÜç¦Hµ7÷\ q)|=Q,wÓ„'»=ÎÜ1 I[Ž©›­.ç2ÖcbN3Ü66š+(Ÿ± >¤œaÉít¯òSn\¶tYH3UuVUiaΪD(D»%ÜÞ9’ F .ª®þ4 š´ËûÊÛùeW“akÁŠ>ž¨>ºVb÷ýB3¯9‰i'¤ ©>æ·¼ÁϯÕÐÞa:ù†¦™ÖwÓpÁ†D%b6–յȸ@Šè·,u][²'ÜžzÒ”{Õu’ÎŽ6’º]>(ú‘’BDH½¤º¥ß‚Ãýg¨:èļÔ8”­.9Q6Ý/_$¤„´'_½ÖX~®›ÝB ÙÙ^ýRB·§eé¶7RÛ¥Oç¢8è[^mq0¤^Žœ —³QÅàÊñ U¡Y8£Zñ‰/ÖÝWpx1§}Å8Ñ.ÀM)ÁÅÝä+Ëçç³½4CÔÞC µ œ ¬Å[k+]9*ÇT£¥ÝWúWÈTïmAP» (üØånÕ˜;½‹ó OMq‹ ´aFžœçÍýuxæ•3|z²äa4 ˆêÅ»u%aeÂÒÎèãÐ|&ÇoWFÏÎ(A}™PdÍ­­Ö§±V¬b"­3]šé@Äÿ_øÇÞ¾&(j™Ïì-o$@½•A‘®¯ÿKüÍ œºÙ3of!9<ñè§ATÝPĹG*Xca@B­ƒ4,н`¼[<–õ#þŽPqäé’¤µx§¦Áº„Κç¿ð·|êé/ïÎ6J’. wÂåAèù…¼°-Ž¥NŽk÷ù3äpr5èü»À°,gSgg˜¥—ƒ¯¡³–§Ž²–¼–aîïÈ¿åù¡½þa¯n†šmauÓÔ³@øÚrØ¥ú¦O#ÀžX[0Åvɧˆ žF³¬p¾ü–½sØ ³,=*äVÃXtoÒ¢ÓGî_@+N–ô(ÂÞ‹k‰ªè|yþJÝÞÞ¼Oy`%†õ^†áþ3ª msáûl|$t÷@0Ý8‰ýÛûCµ¢@¾þTØø{ÓIú†äÓ°÷‹»~²{þߟöÇ_~ò¿ÓtïûÍj( C—P 9Ö] zòÅÀ£ýÇ_b÷Œ€!`Ø7;]Áîn'™CO§/N9> <9 ;Û{"fN`Ww·ÓóŽ3„€ŽÏ­^Г|΄Ïñ1öN>ž§ùC!_.sv±ã]anÐÏûœ\ý `;û0Ïãü`>'<¾)±£#Á'o/7 싼<ýåháêþmÞǂРzzÇÈÑO§erö'ét󏨾];Z¡@ÈÑΰ}÷çt …AÏÊîóâèž`ØÑ³‚? û|½#@g'ÂNn :Þ<:xRüGª:Þ<oA` ÈI>ÿBþ4 }¿YñåÞ¾-`È7å}ÆÿKµ;ÝyÊÿsE<;zvrƒ}>ò•tÄÿ›²ÿréþ_qœÐrpýüý=Ý@°3˜_ëÔÕýìnO˜ß§çÏò?>ú˜ÿYÍ?½ ò @À|Œð_ŽùöÀ?æBO&I½§$ðÖþ«øƒ}N!í9v'ÎâÔI{à¨îƒN]ÔÑÕ ¶µ÷8¢r€ú-¡GüÏJëtÚó ÷ÿµÿoRíú-Ò™%þÇóüÕ à?.~þ¥¿U‚ï@Í7r¿¿Tä/›€›Û—è~j.P7Øg½pöËg}pœø¨Šºà·ÞìÄhA.ng§œ†~è‰uŸuêgŽ÷ž ÀÌ÷ôÐà3tV_ü <¹ãm³£7àás|@{/Ïr‡|câÇ äêâìó€~篎@·ï6cìT@@ØÙÃ|vi`Ø|Áçµ#³„‚ŽöËÿÆÀ oìóÔ €@'ŸŒ8•@_ýdóøk';a'EzêŽ\ è(j@ÁnУ“ÁÇ›Ç.äHLŽ ü­wù6}ç*~àÄ¿»ÕcX'ü¿yðwèò·åwÂÿ󮯧Aw…y|‹ñ›#`oÃÐÑ«_Âß%ÐÍrV·ÏÀÑ€°ÏÏèÏò?QÀGxþ´¿¢>±°å9}åéG à[-ðMŽ Ði$ûwÎþ¬d¿_ûïáoç{Ü|ê)À§A üÅDŽ8áRÞPà1 ÇQ…AAö^G†m+Ø©O:uL®G-€ÿµÿ/é7Žÿÿùæÿ¯Ìö»+ü\öBü™OÿÿËžoÀQü? ߟeÀ‰ >®o§õ÷¤R<À‰ŸAOìÑÙÍã‹ú¶mr¹Oµú±Ñü õóC¾¨\ði |r pÚ§pZg¡`k ç¿úýÏ›§†â q?³3ðÈÀN\¨‹]€ûñíÙÃ׆ÉÙ vqø{@¿üpVêÀÏäsþ ˜äÌÁ  Û‰ÇøìÏÊèä!°ïÖŽ‹çÈ€-ú¯ÒÿÔ'B¡ßó;mä€èçÌNš°/å턺¡‡uƒœ\ z"þ.ÿ}àÇêò½¨øâØ?;ë/nÿ›Í#2°¯Þñˆ¿»;ôÕüÍCBNø»¿÷äÌS÷ÿõø¯>õŒÿ7ZCpÀqô‚‚¡ß(ì¤vé8­›?ÇÿÄ ƒ¡_Où¦ùÿÃtÆÿˆì›v!ø{ýüÕŒ¾Égðÿ(NWÿkø{ñ}îò8kœ:0ìLº1?.£Æ09 ÙÇ¡ÏÙ>Àí¸Vœñ?= ;‘Çüýþ×þÏÒoÿEœþõ]¿Bü¥þcEøªªNB'µ÷dyÚŠ?íïú¬tÛó wØç¤ºÝ _:OAgòá‹£;ÛG^èûê®Ný© Øó³7ûêÒ¾v{ú™³.gkoïïúé>÷ñOG繺!nŸ#À™½A¬ÂOÜàK?ß7­š##qtq÷95èoÚ ·Ï›g> ìùÕžùL›@ÀtÍŸÍþóÚÑc7&Á'=ºßÀû¾ðxÿÛw èK£óø.`_®9ùXãñPØY#ãøÎŽžüÈ78€ÛøQhøêÊ?׫oZ)è >N Sþ§;OøC¿{ ï‚ÆYCê¸üÕž,NøÿÑõ-¤Óp¶×Ùþ×ñ÷ò=~‚³¾å3{|ÊñHÔYt~šÿIÜéÑÿû¿ÑòA¾ø&âÿQH¾{ðY·ÁO*€ß™¿³÷ñ7àNË㬠à³9-Ò£.î ðgþÀ³¨ =âH0Ø ó˜?äíÿ4ý¾ñÿW…Èß ~/ð#ÏðYTŸhçÏ}ýGaÿ3Nä.ø¸?ô$´»@NŒü5îuRŸ[ÿ§šrÿ: x"ŒAžÿâÞÀ_f |9âä \‚¯û· ýû®ßSÿ:rÒ À—NàÓc@–>~ÿ§½+Krã8¢‡S„ÏàùÖ2e‘ôR[/X¤|3lßÍ•ke0CaÆ¡uÄôt£WÔ«ÊÌ—™•ÀÝ^_+ŽÑ@bFް°È¦qoßÓi)ûxÖ‰,þ¹¤A4쬼œ¦âž+«Übð‰ ?䡎›"±£~¿oÆ<æáÓ3à«aÀ/ÒER¥$Ow Ø!ü›Ù°?ºÚ…: FB7™f¯)`–³[FÅýñªøÚÍÈÕàf =ÑÙýöÅø{¤~„¿P {ðÛžâŽóÉXÖrÐØ½i_O3ÍÖoÿ?þžB‚Aõ> &õÞm!DááðnD(ú%%½w(iÿ‡õ÷ñËÝê|ï«©è+[/VÖ—á’gœv²þ«‡ÀÈ d}J€§]q8º~FZO—ÔYh à@„ Š&+Íâ8BU'tžqð_:7;àI޳>ìwšwô”pÐã³½½LúQð½Û/¸ÙmEâÛfh Ýp\'#¢[šú<ùíAšûyoq1ú%ZQÉyt×EðÎ¥¹ˆÄV4Ö?Êï)wŒ<":Ø‘¶x–dÌj>Yë˜ÿÁý€? €ˆ¥Ño' I€/¶+‘òk^W9óýd'ÊízfªIâŠ!}äÂ-OÀÖXÎ>t×ÅßZ'´ØàK·#'¼ÿ8‹jž˜>¡Î›U¬2ÌmÁrYêfœð¬à¼pÇø»Œ?ËùQï‡Ä)Œÿ¸j“å®ßùý@juÛ(qMPüûýïãÿÎõÿÕôóoÒ8Qø¡ôO]ÐøOb…™“$ùCgD¿9F±Ççqúe69<ð: (û¯ÒÈbõ‹øã8"Ç÷19Ë& =>Εo1V²Ÿ†Ò°’ÍhàúnkÂØ!3ͯ ƒÐlÞ9þÿ”ñGU–d‡ýñ¾ØÅø’?nMVA‡ñ0SvG¿£ŒA+tà@Æ?[‰=ö“7>þïUÿ³Quí'\ëáÅw~ÖxÍëž±¿ƒü?í¾ØuØ´-VAÐHœóàv[Ê•¬ ö±“¢½JÉÚêï—DCîŸêCËgÛôó°/¡Be VD0|W\diƒÕþ~†âQhõÛhå¿4Žÿ,š»nAIA‡Ç9Ög†*Xvy4Iä>´ÒÁ§jäË¿”N¦%Ìì èd™b(Þ³Øå™@\Æa‚fCâ3%À—ÒSŒ29ÚWfü-_‹5F–r+Ò\0Ä_ƒ»e%gÚ["þáøïESäo øxÃ+ð÷.àŸŠ¾Ö… €SüA‰y(ÊÞ0ÍÆ (i—ºîÿy·³z_üQñ¨ÿQlŒD¿SrÿX×-·è°–&´Ø:ÌþÌøÇ7?þïYÿ_UýÇëZ/WÕ¸èúfùîß`AFΠßAÊYvÙû8{˜s]4~QùxbÃþIœÑ 1Ƴ‘±gãYšu?÷³ñÖ«HÖGrqf"È/†…¾¼_¬3R)G"G¶§»žaJY5̰+áÃHiÝ¢gø µYtK¦ ³­ŽíÃÝ"Ææ®D’yÌöIŒ“šùƒ¯ÇN‡û8hÌp&  Kì©< ø‡©|×÷-¯ÈÞWÝUüí‡*òkW69 Œâß@XØ_A¹\Ò}¸ þ¿ì“LÛÆ™dÖ°áã‹ñ“hüÚ£ÆWãCÆ&V…¢ÜÆZ´zYànñï÷š!f€HMüªý<̨°ˆ#b Xfü1tI# €¯¡I8ã("þÛ7>þïTÿ³¥{“Ç\ç9whœë?~^qìVûLtšç'» ð›yͽjÀ¹€V\EñÞ“ŽÙ?SzN˜?î~ê¡“1µ/`èþàŽ¥" ŒŸ<¸‹4 CE •_<£?XþÃt¤ÍÈiâï0 Ý•*ò>îÒœãXæý^fD³w%–ê=eí*€ç3=Lõå0 žg&‹ˆÂCˆ`˜ÐC³è4`òÏP€w«íGO¹€ñŸß, à¿Tï]d¸^US“ükaJ#ÿ·éFøûÏ+ZÅe¯ybØ#^ŒJL Sù%Æ£ß.Eã£G¿1Zo€mÀ¯3hónñßfüËÄœvcÕ5šTd0þ ô&:²0X‰zŽ7"ZIœù›þð¦ÇÿòtWù–Ë-è¿<ç:O /¿í³¦Ã…ŒÿäÖÍâ»á8WÐ¥™îsB€Lû–û¨s«Îä~ï'õpHßV‚Èa˜¶Ú‰Õ]¦qÉÿ—1ôð~¿åü›"!B-0Èýg›$3 —œ?¤é_g¨£Kêõs}) €&Y¢™„ÍÉE礒Úå:Ï4ˆ @¯^â9¿µ8'â3w ,49m&—Z`RDÌ£#=šcô‹ø ˆOç¥nó¨Å]ô¿·ï*¯ øÓà/B\DþSìÏâ߀aÛ¶ZŰy¸þ‹à/­,@pë+ð†À×ÕT‘Ë$€ÿ€’ @ãknÓ‹º¿8€÷¸SüûáOé~̦z> µH)’I#³>Ë'χÎSË ÝTýœ¾ïÜá ÿûÔÿ7¢ÿú¨k<ëå€ €‹\©±Rp§=9æ@íŸfÈ\ÀÞÏ =;AЪ| öO" ®žŠ—¿8ý©[k€.RZïŸÿyXãè¶I‹$ûE¹Æ4-A%aåÄ~M¿‘71þËŸ×mv{ð KC\p1KJtoŒ3¤Ö”QYÒƒ{…ð (¦kÀE>+?nDåMRÂÀVi-0á%NrÎG´Í0—#X Ïç-¿Ÿ«f%rÕˆªØðûÐAÂß\‘šíÒˆ¼Eø·Â>™§•«ò÷øËMñ? þÚ]Éîí·¯Á?–\1馕ø§…€ >M@ªÐ*6¾D-€ç–`¶îÿïy\e¶ Rk  M˜øhæýÁg0{@dɰFùä.Âóòp`ÿ?I·éæ7<þ¿ÖY¾ÅrCõ/O»Âã®f´/s ÔÜ\îãA«ò$Rø‰Zeøn‚ð‹)hçýq¡hw© «!lq®–ØàD˜ù›I<†°ð?Œ³º$h¥°øKå²#BWœÀ&5$ÃzÀ]ØMX,¾–ã6©„‚7s: ! çòw1À \%Ø£Ççpv cgqÕ,A.çú YèƒØÁ›;¢àœ°¦|CÚÞ0!þ«øQMÿ’¶&j‡ø—ËhZ‡!æe+8jüëÙàU~‘÷ãmñ»”†­æWá'K Å£ËûlëÆ³øó90<=e4XóÚ ê ƒé>ñœº‰%Á› ÞER±Ò&ðýÄ©þžÜópv·­ŸRüÿàÆóã¦ß¾Õñ·úÿfê?^ËÞ¯¸çeÀåw/ ĉü°9ÎÁ&þµ¾[päìc©¾Ù› `‡TƒÖʬѭ‰€ÛâJ¹ðmh{øþp$—üZˆŒûJöÃfÿZÏìÎ1Óèv:œ­  `ëuXjdÜŒŸVãLæ;úe2抶 î‚Ðò†åÇ?R zd–P T¦V¾FrÜÅ–ý‰›Ïór;¸Ô^€ RŸ—u~†Ô2`&ü?<ÎѾVó–+¾Özgi™S¬‚6ˆËˆcÎÐ+"µýf~¼9þáÓ6ËSšš^Š?U\ Ÿ«H~8?«}) PBÌ­ÀœóŒðÜ¢gOw‰ÿO”LXpR/ L-&?®ê(óüâè—„»Ý–Mi(2!hV\ùQe›îø6Çÿ=êÿÛÒ}âÿý‘¯ÑÓ¹*õŸ0^æܧYÕ~Â2d!jÀ0,«J2éâ4¨ÙmHå“PfR 4,ÕÕÚ»e ðÿÊÙ3‰K‚–¡YÔ@íþ¢B„0p¾5NÿÒÆ1º@󿢨×?ÌË!•qåî±Ëu¦oâê†û*– íR¥õÖsP‹ÒQ”†ù·¤(F ±.ŸÖg)€å˜‚œÍ«j%zñaÄÐo¨¾á¯WX]P€Â•ã3¡POâÊ™'dÐÿ”¾þ»å›’ÀTøåøV¢¯ëú¾e9‡?{”ê¹8øUÅÔϪâñ¢ À]â¿füÙ㆕Hƒ¸{²~fùAÍEByæüJø É(ûÄÿO-ˆ¿ì3q~‹ãÿ^õÿMÕ¼’ð:àY àU€1qŽ~î7 Qþ²ªüÿ™CörÆ}ƒãÿê¶*€¬SxœìX•Y»÷‘Fi )Q¤$¥‘PBi¤¤¥wÓ‚¤‚ˆ JJ*Ò!RtÇÇÂß3ï ί3ߺt³÷~zýžûÇZ ¹tóðñ„üïÖÃê ý©Ç±?ü?l úŸþ÷GCìpr#ëTpÛSîš ]o»NpDµcK!…+J×(´ÝëXàcóÅ£}0§«º—!ôªgjŸF6«n¨ÇIº‰žª ÅÓ^(VtÉ(WÊxi{5·Ò,‚™uÛížT–eŠEG÷µñÄÞm‘æßÁ×bºwï9%;ª½[urS`‚Ñõzy@ÐãJ±ŠøÒBѳ¹E†ë™~‚'¸ãXgÐýÜ'Â9OSÄûð7 D–¿ÛB/O<ÚüùñŒ ¶õ#}:­—jÇb#[¢u©G»(ŠK©ª]Ð d»*“^öަ_¤¾žÈIés4ô„²ƒzhîKã cDž2a]>¾ù`Îj©´™0jÙ>í’¢>Û“óþHFš¨ª¥¨:[Õ+;e«àf°è›\;¥$C‡jåMŽ#øä·ä™|¶^^ưåêô&˜R©ªK¹ý*h’T½^ÞÁ_ñ«Ƭö7Q@‚›€áó¦á¶ì7þW41ðvõ¨|œ7^Ë­Ò®2šÁ¿yYÂGkˆÄHøxÝömyÜ8—Ա旨Â7WØÚ*$o Å8;¾£!ž9êcöé Sµ×ÛÓ/eq¥Ýpdû*‚XÅSñZãÛ“ØJN1;>³&­¤-´ø yd{ Ç€ÌcT«ÿ•ž¡Âýš·>vNÚQ§T.öÒy¸ã§»¨ãéàžlðõÇv˜î%†õ^á<ƒ™µÍnËÒ—c|üÆõ'n?}í•?¾²1>)»qí88–=Û0¶¥dÚB’?9²^ïDŸù C"L’5~¶‡­ËKÜiöÆ Nõ€ÕÆóØAmC ÛByÃ®ëœ ä0v.ÿ6w‚ZÕ3›|–&"cú›‚'Y0'h Kx<´#üíÑ׈‹ÅsìŠ>Â.tý2Ÿ± -Cñ|i¾¥ÚŠ6™ú†z&œLàDf‘л^Í–û?. ¥ÛlðH̓šüƒcí¶~øú€§½òd”KxN¤c[.ûüTŽo‡Í¡5oGÝ@ðOP‡4ÜnÆ \±ø G\ñy ø¨Ãèמ/÷ä„ry;ù=Xݵ³utó·2¹Z›ÛÚ¨8èŽüŠü+CJ½¢Œƒßc6ã ×Êì9^FK|ŒŽ5Ib7»•öh‰ˆz g\´é±I‰dçaÒÙÌ—©*±Ë]P*ÕË=ÃqhW»õæ3Ÿqª*«åÏ™ ι×<~›7‰†È–E"Æ ëm_~}¥öº”K@ð¤¼ï=܈A•í‹ý‡ÄïØ¿£G’Eÿ¡½ÈÏn  3ÌúOy'ððôþ©G‚`}ã?€þ\DB¼ÞJÑð5½ÕsSÓë™7w?Æm[˜–÷ÛYöiql³úA …šª!Œé‰¦Ú!l@ ¥CfïÅ{&AŽn«eêXáEk§d¡¡¼ƒÑ®êºÎÀ®Ý·˜F8Ü.en32e½XG\}ÍùãÍÒ7÷p¸ŸlN+”œÖ°õèÑþd8H¹<œfSyu‰âö"Dưw4¼;ò$]b ¤Å¥K/–ÌŽdnfñã_«*úìÕy,…õ,æ}S IÕ§þËQâ ^csdOTâ¨E³/ dÆ}ƒäÄYž½›™/*Päî΃-?òþšç¹Ÿõ¶?-Ÿß…{$Ñò—U‡ÅqœäŒ Õ6à`Ýóèmaê&8sUú ©ZÔçczCÅrM+¯m­V¨ŸFÉFã'„”<¼^r¶Çú\QN¤qW$ÁåãYóôt޽ËVK;žI9ÈØ–bEÐ}n"ó«ÄÐð§© Ö5ó×IMž¾uá.‡¸®ڌ9õ94?¯b9^[(`£qŠƒñ,î úiÊ7‚SüÒZƒÚ%/ÏC€êü÷ÁˉϦ©ø¹pãò«T OKߺiv{ôù]f…þ€Û§6ê9ãš$iú"ÍN»ú¥óÎ¥Ï ¹¥¢+ù¤q:]ŸêìÇ4¶àwZq¡V‰eÈÆuÐHI»¥¥}Ç_ ˆ¢{­7u„š{0ûNØX†÷ ýGU·Z¾ ç/“K8_}ÜæÏ^´¦·U SBð:|ƒÜ0P ò.:žtìÂ^ö!øš(“9bt~*Çè…0`ÿ¥•G]þz,ßPÕmlZ`MµMXO5+¶]Ú"Ÿ¤MÕÀô´3¹Þ?ÇŸ‘Ѫ [tEº¿ðrøX–Ö¶öCñWÕé"Y¢ÝÔ]V®’oÆp\.KÜö“ ¸,´Ä~—»†=?„àÏùCþo›K’„.ʸp¯ì¾[¤MÂ>[Rµ‹=Ö}g¨+Cü'k—Î%k4]ßáÉèö,ãt‘ çb]”ÕY³×÷¼íAfnöŽNž.>¶FáV¶:æ×lý~Aþ,ÍmrïìÊ´Ij7èDt5ïµP¾Ê`²‘¡ÎÀMKK½~‚´FíKÞWtvyèK(¬ñlÎ;BÒ÷sÆï2/2dÓâMç]~ýK×¹,­/éŠì}AW»2Úq™Ž ½–+’õzºbhDQa¹ÍR­{^Õ•ãE8Œ%àßdÿš`ð»?é”þþtúýÜ4ü¿n  ÐËëg9D<ñ7ˆŒ-¤ZÌfpÒë,x= [‚Ș°µ™«Ï­ˆ1¨Þ¼!ªNwÝ]kûk?Í]H™ãÛ 3ÅÕÇä`oIaeótž80É—¥c”í_^¾a`±­]%’s¦Ž« ògJ@/ï%$ñtGό۶ë¯ôb®öøÂró4“rîÓŽ–ùý1&¦ùO]gΗ$ a—½¸Ê=Yšþ¦]=ƒ5hÛÐ2Z“Ã^k8’ÖO)ÏÇ+»NÕ`-½¢ª¿yFøš× mdÒö#RHL…BÕ³‹’KøÀÓ¦àµS®½çÌît:]Ç)?LmÇSO¬.k l?VÅ£w~úˆ.õ.?§ÅÌéöç÷©$d>ñóÀå¸_kÅá–2}Òß籯š¥HMœ¥³ä‚mŒFS&ñ©åO'‹æŸª‚ØÖoÜ.Tzš!­^»=øx¤çSA U ¨×‰õ×4³”E# ñŠÞƒQW£_‘Iø>½¼‘e .ÐU¼g«šØ´É¾èßOÊv…°l„Â×¶ºF1ý…ØõèÜ<xkºÝWµé©$EæéüSŸÖå¹Ä%¤Ês¤½^=¶ñ¶9?ôDåŒ[MÇ5Î’7l¡qÙó‰3”Éd8ó$Û PW•zõªãÛ®°ÛNRÑúý’ Ë«Š›Ç’í®^t K¸ôþÓÞcÏ$ÝN¸ï}Óž™&…ŒãUÝà6¨ïÁ'‡\©¯^ñ¢8äuGÍã7í¨<•«JC7“yRÙuyÄÛ©Îp“|ýHZ׵⚶&Bã¥pç-_‹Þeùí&¼`>â"¨téYeƒ‹ñbuaô9J_R/xdzê|½Ò®Ê1£åyæ½hÄ[¢º”€æsË'ÛêK¶¯äZòRŽŽÿåpnu&>Ó#î·md‘ŸÞK¹Ùjºø‡øÉºp^ÌÁ89Ýt3KŽIü‡ü¥å±î?\Á¯Ó®åjÁ¯™iÚç¿xïõþׂ=sÓwü‹O¢qûs$dñEâÏ/³™éÞÌäuœzuOé|Ì£+XÔÞÙþŽ5ÌÛ&Øââ¤íhoe:üëñÏw?ð•µfŠòg}"Ë­«9&¯J6RÓ:ýBÛdÀRÙœ"õìê›g¦+92žjµ?(¼÷Ú :Òeš®U­Õ(vû¨®ºLëž;Pß3+,Nõ’fÉ›ö"¨ÌSû‚wïyW§‰«?éÝNåyMßxæ±–£GÙžj( ÿ;ìß.qÇþÃã›ÿ¬Sú»ÈÃõ''áîènoØÏ‹5ð·;ë§:'–á‚ûUn‘K[«.Ç>bM¢î"דn eÚxjóaAoµkHqÔû¥^åèg¾I)pnã\c£‚GÅ#SäWfßúŒ+ï0¡DãüB2oy ´Ì€xs]_äQ’rç®Æu·…a2ÇÖÕ•‰=[x³Œ>ÉTN÷ñUܦ§ ¾&zRÍã‚KlnŽ>äÍÕN%m°,U#}Ì Ÿ>s&Å@KÚ#k'/ܱí>2tÉ^îÔÇt]:PµÒ Ö^QSu•Ù±qÇÒ%‹èÇB,Ç^‡=Ï—|¦"ïþ8׆žkÙÜ™=ƒuìS )…³ŒD©¹®ÉWWíw[_5 ºþx8^÷ëý9ÔRÏß³v»Õ.e^'ÈR5®ÍòÂ[y»HËÚªÖ}‡¦Ë`üú LiëwüL£ñUt_ÑB¯©+P¸|¡Žbìçþ\ï&¥üž‘d Ò¥¤(À(ÝqêN›Fh„ËÆÝgý€ó8³¼ôdš;6Áe×ã°\ºM›W€àELi³ S©™)ˆÝ…8ŒØ`IÚáPèQv?g&6YtN¡§¦ÆO=Òoã½&Q¿†¶xlZÒîHÝ^=Õ¥4n½Þ-öEgC® :H¢ø–#-х˪䭞§Œãn£4~áè®*º§oYÌ&o‰ª OÖHz<³l{ì’UHÅÓü {œ´þa» éËèÂ@Ұʼn”nŸ¦øz¢°xÈ´x#²O ë?ŠÞ¾ýà&®°5‹èH~ð)2¾a'›ê8Ô¬æÊlÉi»µ¨¯Uá'Ɔ³‡Î)ÝièŠr3cL ¸ç’cSmôvD%欻òïù·èë±7©îð9CÍŽ3[œŠc>€ç› z}òEéÙa5&ÇDûÞt˜ý“™~#—È×éiX—Ss¥èÇ—6\YÃû[*´#ïI›|Ô¹`ñ®ãá|LE~º»5Nð|s†ÅÆÅ3yõk)0hœ¡qxUO °×ðæ²†þqþóºî˜ËT2îPW íÃñWjàÕÕŸX3Qµ¦ÕZ»Zã$33~M$¿@\ë#?‘¶9U8½s3ù…íòÿR„Œ9¹T‡õ¾+þØzmξ¡ú}þÏ­,ºiY'ƒFÚ–„üMˆ¬$:L 8hºµ c¯¸×Õ2r¿å©hÊÑ”p ˂ڥx»:;Y:<ìü­ƒM·=c~9þœÆT:ošSèMð:êÙF¶2èÞGAè‰p¶I׃¢9^FBšž^°Ì,\Uë  ± ¦4hhĽI¯d7@Ukmt¬ñA{ÕêÝ5µ¹®:æÁí૨ÞN–‘Þ£OæÏwÔ+Yè¢Âå3ër¸2$— xaFóLý‰¿ªS&‹iªÇýÙý·ÿIôw7›»÷O­Àÿùp÷ðòúiˆCüapèvMâ= 3Ei/µô4¡püïä8¨ª7†ý”³i IuÝ`ãÕ/U~zJ¿*ÑÕ™ðç½¼x Pð@7.BËûÙÙM<™Ö˜9L¥×!wxƒ ª…ÊDðÞ·n5«ÜÓË:×…ÊaN¦<5°Þ*ë»Õø†vBý¼ÁJÁ‘P‹»&[ìBzB¯¦mZjmKNnÆŒ¥rKN_!'O—…6ùI–±ç7RPÛjö›'yH“ܦ! ŒO ÿ‚õ!àqÔ—R° чU‰o™`Ó K­†}y‚Ù¢ºª•YI 0~§Y;¾\7Ýõ4ɸdú1´™XÒ–F4¬+_®ÊU¨9_~þÙœÚil1ÝšBu؆ùÂæ‘,ФH6M]å¶Ö‰Úg5× b—H8iðâX€ˆ&2æ{ùsùI=~¤Ãé}$Ei!¿YÈMž×Û~t£íôË4qƒ¸!Œ5ƒ¾³éÏ„xÀ=åw$%*_é)ÜÀIgQº}¯6CtYÊÉUò£ñ,õ9-µY5i× ÎPhþC_èØe;k³-K Жå—Õ«Ï©èžiUkdŸÎ[„¡«¨Ÿ˜6•i<7“-gJh?õÌŒ=ô,dk¥ƒû‘:^Ýxè¥oô ù«*§ÞHm¶ß³¾¦·‘C¢ycj”@úê\[Àk—3ÄÃC¼±ÞX?âßÁr×~Úχqj?ÝãRòô—êîø vLñ#nz“‘Dvo’Ë’Y-nc’FœË\ËiLäN3hÑì»»”ýêQ´ö[ÊäÐzk©ë—î+”¥èajŸ ³TjºôâŽôZ1UÙ)Ú©} Èl¤'ÑtˆÙpž‰Œ[øø3{KÓ}›g¥ßj =$éüzì /’/–$ #2§DÄ>á’©g`•j®··$©Qp,ðë°Ï7ÿ©©^3_†T¯·5±iõ«¹£êûü?EŒ©”ÞlÕƦ#Gð°ªøÌÏPÊO8¾~ Vb}¯Ñ[¦±#ELÑ=9Ë<$"àèÎGW Ÿ=ÀÝ:ê—ã߃γQŒÙéNZ-\îrI ìúç„AûN+¹çAÊò*çcѳˆ¿„;(Ž_˜„\w»Ý.}žf^àu´ó'êÉ I-ŸH‚#+'MÄ9¥ ænUl•Æô`O@®±„œ/)¢‡Ã9[%øßµXk¶œs“Ç5ûÈ@d£¥=~ì9{æ¿ÅþAÖ#ý½ t†øýcÕÿÝ“¸¼Ö À¡†þö€PÌôÊl¬Üí«à°¾›OiÏY(f:l­Ñ•É&cä2Óéa”rE¾Çuy1ôbV-júé}~|m÷Ϭ¦^˜:ü3ÚU1ÉïjQäf]d› »¹`Ï妯mU~·':È}ëºiÔq<‘P¦XŸ/AãxNºI7EšŠ…}fqeHùOQzÙ,YØsªPYsòBòL"¼L Ÿ¢™Ô|×ÎQ~%÷Ž…yO³}\fŒÁ 3îjÅ ·A蟬}«yÄq›@÷L_çŠÓqÎ[Ê@%uÇ/ªl—Ó£ÙJäÞèÅü6Zûû«wç‰eƒÑÓO/ßÕ4wغv_áøñ;a²®éV’p²ž£/ çÔ¿àÙj•Êþ —Ð[ÇÄO.Rã»ÔãM\¶êçÛš¸¾Pµ­e³9ík³«É”-¯øµ|"j¦ ä™KÀ°ÛR\¤˜#ú½•(Ú~9žG+åºùx,—RJE†>aTW²ÈåêF-÷—­­$/5ry|..rÃ0uy:Ûå4ÌR»ä¤•J–® “+élÐбGLzš;«ÍŸ¸[Ö—p¡³ÙD¾ÄãÙPl @ÿÑðCÔ“1vš·Ü e-žŠ…Ç¡M m)îo½n÷–ð$'кù±ñ>Ôf>»ÜXaÔKföÖý$*îˆó_¢)1%|¤9¿j»)D¦(ò@š¨¼tyáuâSõÖ-@Ø«XZ(ç¸)ÝU¬—´7µˆoz“ó\([é¬&rëïÀ¾d½9Ϧ¹ý&¡§·0¼H_:]Êëz„!òö qR]•㥳@/±q·r ç2‹.ìko<Ù3Ü þNýC2D÷3Ž æ–ÿõ“&—2×μÜl¥k}L•wŒløˆõåcÎÝV”ÖeŸUÑ|¯§ù¯L—ù!ÿ`Uò;ô­þµ†¬R^‰Ùì*Ô0¬öùwƒaܯ³sÏՏРø¿4•Æ\&p¦_Þáß!ÊÜI)~;&@Ô­­ÕNÊ̦,À%ÆäèjåìºãéìçȯÆv++-õÙØe/°`UpÄk#F\rú2ªb:"M¹kR™zÎ1¹Î•Š3''ƒç¥Y]ή[X°g­¸·L½~=_„I NLÓ£ ¸!ûš^êiGgÔ9>«‡Sï„KCOÅb”މ­Ö.¤N3>\Ú ¬-y<]Lí|Wí˜v­1þ¿Äþÿ¬Cú{Ðàû‡ßÿjû™ÓàC güéàÏEÞë&Ž˜‚sîk½Î›mI$s>ìY_÷AÊ9ëýíÛÁQO8èp»O÷¼WýÄ …¤~eTT~7'ÛS8ÕfɺªO MÊã·•«k9¿ZÞG]ÃO­ºôátlé¬:Âä!Óyµi{qV tØ›OšŒ¹}ÊsQF]í§¨êæYŠO§weŠgMÞžÙRÃ%¦H•Ó­ä<Ÿ¤ìÏY¡¬OEïPvöë˺⺔¾¡ zÉÑà‰žP«Û"Å•¤¯b¾ðÇ· ~ 8²RfÔl[±ÂëM ‘˜8J{нÌ<)kr†Ö Ój>–ð‰KbÌê;`{·Eúâ}÷ ´¦á…¯’àÿõâµ½B0‘T†Íš`ÙœQA͇Eƒe¾•Ç ¤±5||)CŽyêµQ®ÍÀ{½d¤ŸwžšS²“×iqë„]Ÿ°6±Ü':šQŸüDt@ü+¥U—js‰|CA—=³ ¾qºÖ½÷°K1Eú%ÜydŒ´„ßš»o%[°ä)’ãC.çmrÞ¦üvH6·‰‚?ìöù嚃ék§Üp©Sí[™[Ézè¸.túØF]LmýÞæ-™ûÎÙ‡žýÈþˆqÜ+(S_#g…mi¾‡K¶Ûcp=<,î²þclés'†GNH :Œ'PR+Ênº˜ŸûOü{³s6‡Î ù9`ÀU¤ö  ¬”ˆÆ"oDɯ5u¬Ê]›ç~£sò±gÞæÔ´ŠÚ™ÔWži7€ŽÖšõ_ÙP+5±: ¢Klë^EÖ‚ÉB¢zã…u©”±x’ðkå^&ÚÄ0ajs”¢Ï½ðýUø'§¾‚ÂÐOv&–ÿ ãõë”&C <å›"éX¾D åNEd§Á†Wx „i):†ˆ¥œ/müÔz²âœpÖ³ÑÛ,XÌLOfÓm¨÷ùÇoje•°•ðк‡ü»Zk$eô>-ÍKO„Ó'}¥ “"ý\¬ª£ZlxjkvÇÝË)ÄêÁ/Çâù'f•ÙùÇè_ý'×J’YañfBâóÌzæçë.õŒ¤ÖD@ÁáG¼›(®ÕñÔâ ±a?§e¨[ ™U”fYÝ N xHwSóCÀ ÷‰Îœ›…IdÂÞe?Ï”Ak%`)SÊtlÕá<·t 'ç?ÈB»|ÚZöKIbÜzïÏIpÎ`¿Áþ=þ¼Gúàò=û÷ÛtwÿYÓ7ð7§“܆­o¥L®÷M¶ÜѺF:*QÎKŒ%=M }Lt¶ÇØ*ó‚»hNÏ@2ªüzÈõú¤îøw)ÎóhÏœ šżñâN‚ëÜ»(¼4‰™1NÜö)bä›Ò¿Q5i›p$­òÛósr…f4WŒM ž€íÅÁÒTÛ<•ü 8ؽÌeN÷¿†D¼ÀhŒzet'*¸(²¹iæuâz§ä¹TA¸œ!Õý‘n;ù"’ZWúF}òéÀ[WrÞže·Ê[µu‹?îˉëáûˆü éqõýØÀ´²®ªk45*ø^oѹ4Gn‡öòñÙ^*iÁS˜ñÑ̯bÐ Ù£Žò86z`X+4~‚ô_®ÍøÜB»'¡k¿9ÝNÿ€kn8¸ÞÃËÏ:è±­®mŠìˆD/zYG²^âå­ÉÓ{ÇTÈæ#§KNÞdHÞbeY; S½`[_ªÃþ*©ð:ƒKAZÙsž*ð%“…GÅ9唿Üókª{Ù‚'ûm?ðqwjµ^kÐoVÐyë Ççþ­~®’‰Êe•Ö«!´üÅ\Ì XuOÆ¿ú@î2õ2gµi3*Ì?h›^ÃŒ ›,§mc5ŒN¹FÑä¬àÛ¤²Þ¬ñMÆ’|VÿæF%4Ì£¶xÙ“)ñ“!i~æä?•àLrÉÆ&òó çR‰ãƒzÇVÝ`Ò¨)3Ñ¿ :±H÷؇U„àvumOãmE üŽc„>j¯[;Ñ`¤…yÎ~büŽóНÑ8Ýèë—ù^HháÊ“yÐ &j› .¦8t”ŒøËú¦`{vñx¨ÔNÆúëð°gã×]:,ÿø"ª%“¯ÂímmÜCö=˜˰mòÖæ4BùK›ek¯ËÈõ1øfM0Æ]ãõ֋áWõ«OÞ·ÝçÏí:ƒ±©ÚÈ)<èûHÉÿýÒ™Þ8~“ÑþäTñ•ãÍ¢åŒåÓþ:© ^Aþþ.ÎöGXÚ/Æë†ôا¯ŠÉÉ žÔ1^N\âá>—Ô¤OЧ6)µŸž|BP • Šº²Ðà»IKŽ>©;‹}îî¢kઅUuùUB†Ãìz^L%U‡v'‘\êQæR¦,E¼p÷ÛSíG¼?úR5ö¤æ¥'1f<òŸ^´µ4—onøY:Êö²ö±0òÿ¾ýÏýô÷µðÙ¿ß6Ð ðs¦î€? 7°*q%A×—ïÚf•”JãC_œ´Ym1Å(q±àò—5 °w!æ…KÏD“ÜÛ~þÜÙÓŽœ¢ þ®o#¸-ý¯46EÊXSÍÖy£~ò¨`Éö6†=sdÏ{·>×Ë.OoÜmûjuI~òrV{áŒb’ûAÙ6ó2Þn×Ìs&Lø ¬Ž^@±”¡Â•¼ð(º$߬Èodv®R¥ˆŽŸtL=¨£_G ,ÖÜz¢òè)Õw 1ç¯H>»T^/ðí$‘Ö6§7{ëG÷¡")-ÑÚ{åö‰çžåqòÐ5‡¤ÔÒ±F1¥]„}š‚Øû†žgò40Í$®5ÅÏ£›èù¦ü`³cF—|ñòóO²Î6>¾OŽl±WûH'¿æáÝt%Í B´,¦TÍÁ¬3·ÏdQ®Gr½^m~{CLâÞûBá>WTÒhO~‹{ùÆ\°<_=(46¼Ö©Ì  Iþ Çtñ+Ž<òÞ–“þ”ÓÈ¡¤]$ƒ7º]Óu Á.ç ]ׇ“)Óð8ßO‹ëˆL÷ôÄKŽÊvDè’yL=ÉZHaûb7L•_"+…ÿj¦n¬Êñdåë’"SÞB‹+á8XRLÕ_x©Ý©_ä;ôˆ%‘üü'ÀE—ýâ”Ä<17Ýzu㿚ˆAtËú™6>n³ÕãÏeº*Ò›šŸ˜KYU‘W?Ù)Í¥TU¾š:Ëûb‹Q¥úÊ |J#w\ï[dâúJ=F1– ›wZ>ö·òŽÔq\}3:ÿY–PgzãcÕ/Åÿ„<¾oÇ¡ùë~Q&%„ÝŠð «9ÅüNgã¥ß¼Fu¯eBŠëóz Kå¼É7içÈßf›ë‚ã–-7S¤à뇼 ,OAWTðk²H«t©c6FðÏ&l¢jâíð·åä[ayPh™²"«ÖÝkm¤iSî qó¶3³xÜøµøgÔÐAÀ€böfRæiƒUšáúÌ4*´ÛFë…l|Iðœ–Þ:ô%z+×ãÇc§5]ÂÅ—Ï7£CùÏ÷Òm½©'R p2RâTÏN]è''|³v§t ÊnPðé¢ühá˜í™ÏWgÞg¶¦qžy5þž!{=X:®}¤ãjÓÛ ¼BÏs`Ÿ|b…¥ ÅMØÿyûù+éïj w·ðÙ¿ß¶Ÿ6 à#!øï#€Öšßtõ5,0‚qðÂt¯ŸzÎ,±‘1\×Ä•ÆÊˆ×G%oüøD“q«~Á‹s'¾¾=}ì^ù—s2î²^Ú°éÔZ Œõ üöxÝ+ç7è bä¾mf—“HÈ÷nÒj)„H¤½d¬z:³+_\×/ÇÃ%s³ØûæƒÖ뀈c”¡iz..iÛ•äêN™ê¼ ÀüKС»o™,óÖ’¤o†e·ä²<9 ¶ Ϻ·šnÑó©i6¦ßœd zDï,5ûTÑ/ÆsUšÇu&õ¨€¸´ªÊ«ó·2dŽ$Þ(«ó4mJÇ­ó $?ZC‘øÄºã±®÷ÉþÑ—L#|Y¦ê£Q–UÇ¥ÁS„±o™çž^Ô1 ½ÍÈÃj 4<~Ÿ·×÷ªô€=L0–£’_E¤ôí û¦çÙ®XÄ'Ë䕬²3D8Z“6Ƕœ‹@0ü§(ZØBVçä¦|Ïi<ê4z#<Á¦@›¸&ã÷*[:5Z$’%™U4HŸÏ$®²°ôñ:5ZÁ£#:M¶cã®M¦Ÿ‡ýg òΨݷ‘ z÷lÖ°õØ ªû×m|"\qm %Ί“x ^ÊÁ‚5gU‚ç_L5Šîl—Ê<úÚŒI§‹3Æ »æÍÝ.¶Véì’(õ¸þ+ªÛXïÇ5ŒæÕêµvYÿ#ÿt/ÞfæÞo¶xÙÏBŸYU+²e"êÐJ+êŸ4h‡Ë@Î!ïÒçAÿ¤>p‡¶úSdˆƒð¬dvxš§”BöÂýK|¾°ÄÚå=eé8}?Pê-ïã3Ê`^¥, åÐóç},8}¥d)°Ä`A€ -5³S´¸íÞ>ÿÑ£}2nLUU‚.Ü[þ˜, 7'Î’9³u×L9q ¿¤¾øâ.¹ÿtºƒXà£ð _ÄÔÑùÙ¯Å?a«¯S›>7ŽQß2ǃM GÆH¬}LlötÞÛz@†™>0¹Çiµ{”Å·b…àf'÷’”Kƒ—`Rô‘¤H»SÒ¸¬×žÔ©’¡ ~e;VÎø<^šX;? õ„ý¶k$n•öêP˜™B»K^•R„R•Hø=C~ê8ý³˜Œ$œJÏEž´`ˆósôa¯ªQ¤ëVÿÛ×_òHS:ý÷FÄ#PŸŸPø…€KåZ/äÑÉ›EÂ}?•ˆäâ6ô‚ÃZ|[Þ¬6½S Óº1áÓy;WX óq¿ðµ'—°K©Â­£ÿ£où,O`B>–Ó\ ût÷Í•9Bè›°.²íx^ÑûÛxV¯Âß nD„$G­…¼½-KFßmýéž[ŸëÊÊg×Wf>$éåÙ"š7¼E7LÇ'¼â²/çÇÙœr¸ÐW‹ç³ÌŸfùÔí{’çæ™æ3NŒLÝGÏôݘHŠ«gQ`O©:¢DíT·ùdèÿ°4Ë–y™ç,g'ÓÁ-ÍçW.œ^;.jiËåæîý8ECtm§Õ†h¶°%ž<?,3u›F9†H]~Àó]÷Û´qެ¥²‡¥à£­ÜŠŒÜÅ fͲæÉgµ'É›ïí¼”∻õr'N ^$XÁ"*,"£^5èCç!²y‹½ôÒnÔE¿"t FÌ4Hì94©4¨¸•N©WÞhzÚâ9 ÓiÏçug-;æØ.éFÕ÷ïë6* ¿ä.î1YeåÉšd–ˆ0”¥¼¾NœŸ’p"xÒ€\RüJë&ÆÙxl3i¨Ä³·:ÚØèµr'ÇM7qÇ4¦‹Š¿ÞxN˜ôµ…ìÉ¥îÜ+Aî47’ú¼?_á’òŸm¾Œþ|ÝCñüíì&Yéu’ú»Õ?àï\dø¯½ú7oÌÊÞ™êÔCÇ ;Cs§Y¡Ì׉’üäîÒã'K`ÎUK¢9*“ò@ÝÙr‡÷B&·<ÛÁ¬¼!›Ë5ŒO­9:l_:…¯¦æ¹Œ$Lˆd󺣉lÁ«‘<SJØÜ ™‡ú ÷¿\?÷Ëñ'4xÞthþ=}|SXjn´XžnµnYן0Æd¤ÀŒv¥AgkMJ·Üÿ¢‘Kÿ þùÏ¿è¨a¾†CÑ}>Šñ²ÔèÂ{R÷ù;ˆ‘^ÏN§?b)‰ä¯bôÔ°M¡éñÿT0¶Ï‘Àml«6—ñOg‚]tÔ3BBýC@ +×_ŠÿY™R¼q¯—¥Úôb_ØuùúqÄ£0GË"ŸDªijr‹ùÚ¶@4ÕB§ŽkÍzÍt4,g+½<ÙbXaåÅ”^´Z™,G+M~_˜˜êS ®„»;¹zké¼³àü`Ö»3J‘ˆ/7cëµu¹NsçcYÇœ„>™xõz’jTÑ}¥Ÿ+OÚ/²ô($é÷¶×{þŸ¶ÿØ¿æ‘þ–ts÷ù‡Ÿýûmû9Ó€ÀCÎ%üûÛÑÌÅf•VoÚåÇêi:…ä{¥4¾4:ÅÖgIÖé€ÅÃO…1æž’0“OšÒ>ã=(á_ãí§Õ#äÆA•¼×Rƒ¸\ë¦K+{Å6¯aBë’0@77# <å¯/"³í4=G/U ®^uN !U”3öXÌ⯱뤜ҚOâMðŠwT+§¥ÕбšþbÚo ´K=cÄ$£û5Yu‰¾,FT³‹%ˆIhÄ´pⱫËc' ±=î%|.Ž#ÎÊ Ê–ŽýxDÌ ÓsÊÉSé6(Š‘«óù+ÿ¾w&7£|úWCÚDg“ДtÅ$*Ö³§ë;›2n:§ÝÄ/t¥Ó< ì½Úq=¼‘‚»tz8W°j¸nJ霼¶ô8«Äˆ*Íòø=P z’ñSC­^;¥º>¹Q¿ë±üò—ŧe¿-Ór¨} ¼B<º£•ýKÞÆ0÷(œ«bÜ»¹Z‰Ó§·„›Û©â½ÆÀìQ9c^ëH)©Àžˆ¢)€:­W‰’ÂJÀ•õ+žÓ!|VîÄÜïŽH[ÝÕÄ4Sª&Õ æ"yB¡‹eú1"Ø]@~ýISþØÑ7~<…A¾w﻽ÿP¥M­±i¡{gÓvÄ´*L˜*oKãÚ;%ídGîd3ýñ6ð /wT¤”·T+*Ö£UɼþGüò8‚+{tvD{aKS»ðµ’†6P6+&ëë(Éf½®³,oÍ6V–€UÆD‰(\âºt~›ëôï~ß»>mZ·¨‡í>åzMÓBԹܙ3?šÜÂþT­9Fy÷…L‰!&kJ_ÓÙQ(ë¯Ç_™ÇíðüM¤’p–YæCè¾M,;No ¾Ze7¹¶f”"¥"yœØSü„š5v±üÇük´.®àUˆY6‰|ú"H¨-^rCqnŸš„oX¡ZL6ÉÉ?çÝÍxšÖ74å;ü'ë WJ7 Û¾Xžu‘mz´LzèçåéþKñ§n?^? bª ½‹F﵉lùhÊý–Ë>¹¬j-óÏp„¿Zö†»­'v /PéèV\ÚD)¥»¤?囬¹]w<²­2_?±YÏ«,÷ÒÃ+§õŸ¤Ìh7ú2^½ŽGxâCÀ†Ç8~°>“‹Îa‘–pä·:rË“fM89˜Ëø]„Pq˜v’øÃÝVÅ3C-·4åËýÖŠW‹Æò;Œ¶Ç,“¬Ðæ3é^Üv¿9‰žüº5á.äü†§¢k晈m}HòhžZbâUñZs]Ñ’ÓôÛÄ™Z[ÃÎÞT»fÜNWûr¥žwâ>VãÀ¼6ôV_P–ŒÐEÞû"ɱIÃ+‰ñÀ ÑB/mÏÚ3ˆ·5RT.ѶúðÛv+%©š‘ß[õ›Z÷¿dÆTc-~ÝçᘠäGÉ §#BtJܘ|KÜ;å!>FǧËùs—§¦œ¿ü¼OØŸ|#š-áb·¬á–Æ*£F<Éñņ†Ïo¨Ò¶ŽlÍfIˆÆw¤pß'ÓT‰•¹}f;WY™<†BÅ0/]‚ç…¸ƒÜi^>Š'ã×O.±`K\lž¾*-Yˆ!/ΖJ5ai Mÿ3àÛ[ÞWV¯¨gŸ~UÜyßüõÚöB¼zWI^ ú0Ü-’ úŠú:ËsŸµ lU8*] ï\çoŽ$\ä’u¦sÖ×ó~ÏÇ3xU$!ñ¹¦v7È7èùËŸ¯¯ñ]÷ª\¬rlPLÐuV8—("µ‰M)&4¸Fðj¦N']§#dÓy ăoÛx¶«9õ¬.¹÷™`8KãAY}ÕdÆ­´ÜÂuÂdÒsôr˜Ä6ÌÞ“P›1i©jþù÷q⨖¿åi"â,’W 'J®bŸÏÀ|ú°‰öt' µÓÕÚo´Š»õ„3Do Œx6=üü96£¥ËœVñɦ“CÑâ±1ßÞŠPŠÛçïN 1ÓøÈàž@Uz·‚çÅUGª…J†';üWßbÓ}‘sN+«Èæpxa-éäã¨ð+ñ7£…Q)5ÑV`&È o›ÐþôñF¡®ç­Ën=Ç.,ÌPèȔܚ©Åß•¶»/óRí 7Ì'Y¿¥÷z:íë…QöÔ7œö½4§^Å ©áÙñcnkh![gÝr£ á'Êo\êÂmµ|4ÿÚߦv¤fM¹•¨þ1ýuuk¶üñ PõÎ2傸«¢º/Ïÿ×µÿ¯Ñ!ý èðûžýûm\Á>‡=/ÈßüµRhRv¬)¤º[*¬¼À¦)M–èº ÖÎN çÇ=öQ“íùâÒVÒZ²‚˜c\â´†þgŸ ²”;Œ€’ÛFö^íTÕò Ht­h­‡Aáîgú#H m+—&'&2š 1]R¿VU«Æ°Ì’¼?ØÖbÒWÙ\ÇJ€ó)dòSëõ°PüÔêFÆ.‚ÙêF^sñ~ÚµtO(”À”× ˜Ê^ÙWJÚÀÎ9AŠãT\¯ùlSÎ$aŸ(£4lŽ {í÷-:XÜð†Szs=S6‡ÒƒøÆÓÌŒ¢éE.ù°–ìÆy1èâ&%¶‡ ýxå$aà Ãò¯Ãa¯*lcÏÁÞ€ƒ/_ªèt’¬ªÁ+íʼn¹GÆ—/1Ĉ*†*¶o ø´ÜfqÒ‰³Ž5GÙ=‚xs†5ÀE'SÛg¬ü™ˆÀó}"a õZ/×1û÷’Íå^FfÙ,w¿[’;yõÖõbk&Ÿ›;³Az¯ã½#ç¯ø2ëG´U³ðtÝRì~£#­èùx{\ÇtR1¡ï$:™úÁó› ¬Õ®æUr éÚô¶ézä±a‡’Ákï«´õx’¿d´[`è˜ú¸\}ëÙj”,æÚ ÿ…vþbÁº“üqë©lš¡ålW“^×Ý%*‘ýì‚×ZÌÃa1¬FÌOœåAa(w'ázýU`Ši‡ýÃÿÛâW~cîâ9݉pß{¡vçH««ž±c ‰d1B鎹bäJ_,rl·&hsŠ"§4/$¯yŸpæ½fóÙ„ãÉ<Ëã­kédkr\ÇqfCB©Ž8\%îLyPžÏ`èß8ksfø—äÏ5…wn xHþ×Ê\•*¨ï˜e I< šA‹"I#>;»`LsÆ«JvAWrór„’1ô?ð' pÉ?ÿfÅÿòÕó-”¡ 7N‡†…àùnÞÔÚ)W²– ÝHþ…1'Ì[NpœØáÿÿáâu¬ b~-içSl -ÙaÊš°”$¯+¿ÿBýmB22ãÖ¥vB¯pÃ…[œï[&å}îtÄœ©^™©4ÞøèÁLô̽KQ¡A,8–³/»Ür»r¢]ôú¨Û²ÑL²×„çhåJ;öRçNÞEw ÊŽê)µ†W\d0ÜôlbL”±x^Zn%?ÿ/kÿ_þ²GúÙ äáâùk<û÷ÛrwƒyÎzàÿâï_ 0)MÞÒÝG{¾u/ĽرGa=»Ô”øi¡®KiƒÔtT$¶¼Ï°Pê=ܰO¶¹IqŽfé H?°&×…†÷6º) ‘ú¾òÂgœQXàÅ-ä-·( HQ‰]S¯,¶ ÁÔÙ^ß ou»ŸtšI;oÿ pñ\n{³qɳ1‚³ ÷“[ÏÚ›?°T™3¿:1WaTn|盓>ÀDú„1çh1…vfwSG šìŒ%ú…¹ÖÀ‡ògÛf.ÑÅ-¼x c¤%_çùZ‚›)—C‡j( ×$å…•s\ïÄ•êõ…¾QŒš´Q+Ï?Tâs>çd0rt+²À©4ºÎVíXý¥ñÈ…•/¶+ö­&§Ü_´Ç-Y¿Õ>ãúÇiÁòi­ö+]˜ÌÕ˜ÓŒF„L!C‘èë3–ä8µfMâ æåbÆU:iWØ«³DÛÙ‹ìŸyâßY˜Z<ÛLû£¯˜ÝgG ŠóÊcËÑÖ bŒA™_%èa«‹_·^̾îö3àryRh5X´dÅRÓLØQ ˜côy6C”ªbYù_ñó»ZÀ©´Uïîûø|˜*Úgë×ÑãêÇ;ò®r¤.è]’{ h 7£Iû*èýÁð\KëÈËK5æc/Bfæ#xx4$cmõÓž8·'afÖÍþzá>×%À»7Ä™Eןzö•X)gZx#ÿ/ÉžÍðÄV™ÿèáøófc) ºµ“¤¾’û¼)4|·ý–Zª^í– F^“£/-s†±¤Ñü:Uðc=áÿÀßÉÈ€Duò~x^ب3בޙ7Ÿ¦à_®ÀkÚÈlP—øð蜒ÿÐÇiš‡òŸõTvø//‘èN€)£;Öcñ”ó3ªÊL•ïxæIýBüe=4ø`räO?,÷¶xÔÇðÕÊm»gv42 ¼©|Ø—É òġš9¢CG[@Èj­­þôSчN¼Ö©™:kôEžYùrju‹³Xæ~²ö,ÞwÅ=·gÃ…¾ÇzÕ™'ç›éëgßbSŠÑAäYfÊr¨j1½iôÿ¹×"Ü7-!Qç3ãå ûeçymšÚ…ïkýþ¿ªý»ÿu‡ôw5į$ü߯ âO=î&í}ã?ŠþË#€!À@èîàEÄ @0 @;?vŽtyîD?ð•‡Ež´«= žä~@ð`Ôλ@môØÙ± ‚‚`(‡ÜjuøŠ¨¯ZÑ~û#.;çrÃ?ƒ~·óèá½û‚êÄùÁÿž 0 ±¹ÎþÛ-AûKö–Ý€þÞP0dÿ`oò¼!¨]#åD] ü C-ÞéGT× :j瀢´ËP‚@ »'‹Ø/ Aõà÷/@ ê‚; Œ¡Ð½CCP»ÞÙqŠð•à§ ÝÙ7ÁžÐïàK;ßÂyìœüÎ Ô ~ñ§çAþ>¨ç]A»g‹øtö„óß»åö{z‡?9°d¯GQ+Á_ÈÍ‘_ÀùCÁû]úÄ @+îâôÞA‡ì`üŽö€Ž?ŠÚµ[80‚xom0äÇüQ»ÙaÜdo·»øö,iȰ@ ôs)øš°_‘Òä¥AàÊ€à¿wi»B±“0z#–"´¡ (Hðí^;òBÜñz ¾ºÃ¹‹wŒ ‚8ïþ¾ÿ>ûÿ£›ä½ýCîÿo9ò¡¼ôßü×ÿP7ÀÎ}†T©Ëtw ð#Ü>BÁ“òpõò„îÙʱÃo[„Õ<à1Üšº|ð€# íñÀ`dOqÁHÙutòó…îi3â?ÈÝzà3òbác*ë>(ñ»â]}`¿—~ÄÆ¸gøÞÀ7q¹¼ û Â<*ÕÎÀ~„wi¾û¿!ºÇrP3‘‡ÂÕv_CÁÈxhß!ìIx·óvø£:젳ݗ7 ûÿï  øï3ûîÅÃâåïçë ÞHݼÉ^I;°%ìpþ²øƒ™ýAþö¸çgöWÜ[ú[Ï ²þãö«ñ·Fðßq:ç’gD¼´ãëÜ=!»*6‚¸ëM‘üPð^аû²ã‘{ßq‡ ÝôÅêó¯²ÿ_Îÿÿƒî÷è?ñðÿ³ ?ÜÖ‡@H³G(ÂDvDÕÁ×qƒ ò{Пù€JÍÁ»¦‚ Tê¾ÏË€¨ì% î±ÜA^{„²E0Èì Ù ï¿{9¸ùyCö ‰ÈÿxAê<àýæì÷J \½AÈÐd òå`ý÷Àvn;Ї««¯l¯gÝ}–‘pàt%dpŽ-9¨Àð«ùm%Š;™ôCôwÑ?"2Û‘¹ÝCïèÌN¾è³ å a¨Î€P×&²Þz0vS€Õ`¿ãïéwPÍ] ^°õ}އüYþa÷Ò =ºÏÉÿ7ÚT& ðŸåﯠ0ºy’?â–G¼ƒì'šðä •¼"èÌçâQŸá›ü6€|÷î»2÷nðGÓ– ¿¨ªê¾W@Ü­Hþ@è>/Yà!{tàóÎvHþ`”ßG­ƒP¡þ@¤ôèØÝÍÅëßdÿ¿¤ÿÿÇÜ?ø§G‡*üQøð{ÿ§# ª¬A Dìä…ôæ;ߺxzBw#]0B¦@»·=¼:F pÏÎB†*À7q{ïÉÂ8Ü1<Èîpjðõâjå°[ÜWd1 ê ï-ò€Ÿ1ä@MqȈUÜ|vNà Ýw ôÿ`íîžùÝ]Ýáó ÇFdU ïijSø™Áý jd>¨Àß'ˆ7ȸ|Ïþáö›@ÄÊ Ðþ‰ïx€Ã@¸Š]£Rxšÿ "ÅþÜìÁ0d¡‘øîô6¥©pd?àïçµ{^O¯:u0‰ÙûÝ=Œ›Ôt¤ü—Ì£ *Ú×D-tµýÇù‚vrM¤k@üíŽCñïÎ}Ù)¼Aˆa`ðw°Àÿฤþ›9p =8öàí€~9þŽpþÀÝÎڻ›×^G•¡(þ¨Òá.DR¿C ¾Éû}—ã?`Ä,$Ô.à© œ?äîâêÿï±ÿ_Íÿÿ³éÿßp oð»¥6"jý¨™~¨xÖÕ 1ÿfGb]=½öÇô÷;Ò8Q3±€‡ü·$÷³0â.†¸‘w{ÃÀ½É€ýi ½ ¼õÛ…Ù×~äçí~v÷Ú•ûï¯{Wí‘õaTyòÝ*ê¿û‰ €"®àî ð„  5x±«.ˆ4n_öäˆ,5ï¦À=P„ÿ@VôP;ÿ­JïÊRÀH{ÝÉ4 P(ô@ÿA»g²»/ä° B%@¨òáŽ"S|°ÿ÷Ý?äGüý¿ö5ô»ŸÎ}ïöµìLο[oî@ÌÊ¿×y¿ÞepÇûàïCF@ ×!ù öÁ¨èÿÎÛÇ| l°s1ÈLj÷v³?pp08x”öƒ¿ÿñAÜ›»•yT ~s#¦ c‡×n¢¿_@\1ª€âï†!¾«ÿ=A{Ý…ÌLàà€ÿ¿ÅþùXúÏn¿€ûGÄÏ:‹?ðà‡Üüð¼¿q%#(òæðp…øÁãm ¼ö·{îŷȪ?j*,h×8ð©RPÐwAÒü÷ïßý¹¸ˆ.>` Ý¨ÚÉÞÏö[½ÞÿŒFfƒ{sÂæ‰ûBÚ1rĉz æÎüÇúï~y‘ìÁOàæì ÿ3Ôð®ðý>w`ß}Ü·s²jˆÒ•=-Ø ïÔsÿ'|Z/JÝÿó$`x¢¸¯«pÑð„‚¸·C(*e ®>X¯L‚w+6û)rJ<̰Ãä¶Ãÿ€ÆÿH÷wÅ ÁòÝø ’?ä·8QÝ(ö Gðwú5øûÁ bÀaù ¿qÍ»…Ð>ÿÝáßóÿÍ‚Ý|þ·n¼ï÷.ÿá4è¯Æßu§ç‘U~Ô•#{‚(ýÃs"!ä¸xo© {å È©6ðy‚ÿ¯½k[n9¢ßꇭÊVm¼Š½–Hs@‘’vã<äwú:=iÉK&AÉaI q%€Æœ¾n²Òæ$óÿËÕ*€)ÊHt®»”ññÉøŸ¼6¡ÿok\ø~àû,ðq¦¯Ê0×ӼËÓL*laøÒ4³™€– J‹MbRùÅŇ«Ï¿ x'4€Èá÷á«Ô~é@NÑ |A€®(¨.«P¯Þá³É0ŠJ¡=ÎÄqC?Ê·ôûîx„ $ƒEg3päOåbrÅ|á§U°‚&xrƒä ä'݃pfÊ|# /ˆ~tÚSu'­  ¥@ù’ügÿÔœvR¤^¼áTxÞú@ªüN^¬ÓÀî§­È¿>‚§ÕM×Ê÷f™fl-à )dsbAhª?›“ˆXrv ÒÆäÿó×Uá]oŠè’À8gf‚ ½Ìùs\ @âBQ|dlJ h2-Ÿ1:P¾¿ßï„ñ¿-ÿ#ê?ÞôL6mxŽh%öXrpydîïþy¢ú*z>…ÙGQvò™ ùÿáY¶úßOSóLãÐJòì¡%ßÊ60ŒßO;­ýª°S¯“¿Ÿ†íÈ?¼ÌJ¾Zþž1¾ÆèÅ9Œ$ˆ£#¼^(zÆÒÎp—¼ÀoÓ¶%ÿXäOj?ÖÈ¡(z<Ð!0gCý·Y. ÊåÃkÂ"þo ™Dà&ìú]wúÆÿÿõÿ…×íB¯(ð«÷_[ßaø@½~ R@B0ýè âD®*ŽÌÿ7 Rç’Ýל¾OèóTWŸa3úŸŸž&Á™ÚMÄÆ›§‘¿.rÑøø%ÃQ—`x²¢N ~Ï".zÃ(¾{OÅ~y$d’´_ô&k‰ö™â(Ý R\14*pb-Í5ÜÞ6O¢ƒŸî·›Gã!PÙØüèß õ‡ ƒá "€£!« ¿!ÿñVÏZõGt†ª€â‹üU‘зð ià)ëêîï›’ÿái Ãõò¹]F¯´è€ÀYùÃ9%‹øPps.B ÛD +óWAùBÒmÉÿOµõOUûµPˆhÝ\äÇNŽ÷êÉKùýÄVF ”$üHò'.ròµ ?à2ÔÞ ÿðþÇÿ¦âÿRÿñ†À•€¿`¼Ýpœò T„OmA½Ÿçèîó1³Ú뺿–€¹ÿbëjDß÷ñ1ʰ]p$®Ä‚i@Ø¿º§CVL¯ «ÀP e´Yâê0² Xþö-ó= ¾-5þ[oLºÙ18ú“ŒJ>Ÿí|[Ñ8)k¨ Á´Ø@}¯ÕÀØÉëŒ À½(;ÐMi4AàÚ $qnyÄO(¬µÀê|SþþÔ¸.·êCÖÌPF‡° ¿ÞŸzäF°üÁ/û5mLþOÇþx½ü£l#ËðÅ8ïw …çä_774€*ÿv—h" uïx¶%ÿäPC©ËßÚ蔿çĤ0j¶.òW[ r®‘“ÿÇ ZH9èf5'á¸nÿ0½÷ñ¿9ý¿õoglØðÜë'a Ñ#s48.ûóý—烘£)jÝ_VËWÜ{J"wÈÔßw¢uò_–óîãñi2¹@¾B¼Žÿ0Ô&o…/?t‡E‹7ç&&ïz?µ»ðÇa²š¤œ|¿ÛÏ_sð[ô¥¤¡Îà{q;580­.E)¹¿§hëýÅH<ßæÌ|š 3œÊ~x€ã2f£ŸC?A+ð.@zEþ‡$ð½€úµ÷GØŒµP‘+¿¬_9‚ª¯% üðysòïç?®—ÿ² zèì¿SrÖŽÙ…üëBÙÙ…ÑÈ¿~Uc´À…$À–äÿp<Íõ2<çÆk}pmoä_«ÿ¹9ïÝØë +¡È?µ X‘/Ë'½­!dûa·Ëï{üo)þ¿-÷_·9¥×ô÷Õøë@ˆDü!"ð \•á?BÌðáe"n½ÿ: ÚZ@)Ã0߬ Œ‚&ÿƒ>ܵ' š2L>üñt¨˜^Á}}Y~˜úqLñë-À…ÐÞÌR¤c4fךõMf"àø vŒò Êíiz€Ö Þè±åÈ8ǃàšà¢ïF ìHˆ s ùr§•f'‹³a4ýÀµ')3˜ ƒ=6+×_ÌþÖ_“ÿÑÈõÜí¥œq)£ƒò·˜VO³„Hþîÿީüµ *ñ¶7TÆûJþ¶ iC6ò¯¶8 m_g,€´)ùÿû BR÷Wì?åúI¢ü õ¿òŽÉÅæú“È?a¤Òó/ÀÕ£n¦çF6˜P¶íîûÿòÿ7¨þù¤®>«k¯[gÔý›,ÃHØ(öÃa¢ñR“â 8F€&êÏy/al °ùŸ†0k²Ÿì×–Ø@Âþžéóýñd“kÄf°Õ¨éá–°Ö1L¹Ý¬7A‘äÿÚ»£˜Äqa«‚ÿ”§ÓdÀ3ÉG܆˜Í,µRõc–[„k”tèÍÑÈ5¾ÛI­ô­,lîûÅ W©Ý@=˜fa50Ù¼K©qòëòß?öÔ}¶çmà¿:7 Ⱥ¬u÷–\Îùçn‹ò¿‹Ç«å/ çM@éÖÏ¢õ·™|;YÕ÷#ñ«Êßì©ØÕñL mIþît«š÷Bs¯ØBN{Ù¾Gì9èžAc;~êµ ›Ô ñàB‘¿qAè ’XÊÝ´&ࣿ^þÛÿòÿ7©ÿodü €õú·•ÿÏ@Ã>M™lÄÄ@z?Ÿ0/Ü¿¸ þ—Þï`ÏGõ£îÈb´k¸Y,Ö‚¹qé—Ð6ü†¨áPnJÿ\V{€²s"@ªy–NÆC>ôðTõóÜkýITbÙµ„Øü:õ ¯ó¯«M ÆU8K(Fi“@«zþò‡ô3S@ÉÜE‘³&Ô|) r^oñÇ¥…ÞÜ|÷¥•a4Júj ý_`Ld«^™W #ÓÀ¢¶ô¸x19÷¯Îw.DÓq8"ÞS#yÛ*ô¢ÈÇžÞÑé a,^Ñ9h›³n^9Åm;“=†Kj5 õ¤R/ÎH‡C0˜šþð6)Ë¥êÝ ‹ß&Xk]URIÆÃù ù?芎3õ›µJmÔa[‰¦/isQ>#"IÃÇ?y.ª9ïÒ¯ÊJ…Îõ¹·®Inà|¿þ ½Š®2Œ­Ù–ÛácÏmoo¡\ÛLî'c®êÇ«‰bhæIÂmÇ ø–ÓšNñ jxOî}û!¾xZ Æpßw4uÏB¸-!Q^6NJdn¼žIþ“¯Ôh*§œë¸©gÚ˜Y2 _Üb}þ2S¥¶e6ò6‡R™6ƒï´X¡ËÀµû´ÿ!ÿfᆙÛr)2|Ã84e`­áž^,OàmRÖcдhÎEðpU‹‹£RÉã÷mžwìj«Å%(‹Kï¿ øjÓ@n¥L—p¬ÒÇ0ôù… ¼“_ôÊê¿Q¸f2@<Ù½?ùì®9kAr}âÛñ8ìøjs€â`à1M‹ v/‹4ÏéVŽµÃ±îgHÌg-7Nh>±UzqMtõü“ÙE••®[QÖ´žIQT1¾p¸d`@Œ¯­—Ä»k•Œæm(þ$Û±ãØ3‹åü9E³ù¿—“)%e¨›÷;kæ¶ÄéÊšöíþµ³Î§_ËA* ëªkû%_éH]õ{2q x±¼‚ÿe²iæk£ª÷‹ØÉô iåÇ%‰æ´¤©ñdCòù|û¹,€Gê ã_®H+„>)±¿#®_rð†ïR6éõõÇCŸÚæßõK=PNþ5Ëì¶zÇ5ÿˆÚnð?©ž d_:Äã¶O¯0žW·±Î¥½={Ù‰w3 |rIwí ®ˆ‘ëR¥˜ýE;§€áéœQ1Ÿ7J!x¹}Sl¢:ᛚ¡o=Ä-ÁßäYªhD;éz-†©,c©+•}£ ºdäQ°ˆo–b¢êIc&ÂæÇúõܳ0.þÔØãáBµ[RÇS4üÖg]iˆ(ÊKVx9O Åðåì†ßiwQÂwQ—[ì‰kXѵÊUN¨–é>Ëã£ÌJú¸"Ü/¯Ê%Êúì~‘2 ؇öü‘€89Ó{½™’‹±Ñ#ß¿.hÎ-Î å_’• ‰ËŒª¹G·òA£Ç"+(QºøZÎÁ¨¼Ó|JbŸž»3—{–ÈGyÈšOs–3þVõ†[ÿ7mÞÄ{±Æ%nâõwê©h¬*À ë%ù¤óƒ-ýjsDÍì7ŽÅ2flŒ²´c¯Ø1ÈèÊõÛxaß\8dÝ%Æ#X»ÕïÍ®&D¶Þ©Õú‚¶PRƒ”UVyûé÷ܺñ*à£$þŽEªÑ錩þ›ÊÃöÝs6½&½}ºõjÀòmlµßf]àH8mÖè°âÿà!A«.agß©Õéox‘ÅŠR™É\Ô8®3z¼ÉºÐdÉkxa¸ÌPÅòÔQû³,6|Dë^\jÂöm©¶zõÚé?æOÛˆ/õ¦ 7ÜŒ‰ç|š§*k–h¹Ñ‚î+‘/×’íK™Ïw³;²ú’˜O6Å»{+Üÿ2D;^­ÎïZö\úæ[OÙ¥\?…R¼š0>VÞUýFÉ&6Óeþ`iŸ›ï÷'ÿÑ4Ö^9+:©àŸðO/MH?:)t]ËW çPAwª²ï©Ol^‹w†Œ&ïLÅev ;RNu?õWüÏ4 œð^ã«QÔÒ£è0£ù¤+»Ã¿;îYÖúlÍ`Ö¤$u4±«ä' fIN ø§D_zBv¿ãÒ­0• {jÖÅ£–ºû‡¿ÝÕÕâÁeÒG#ú¢,¯˜‹«Úñ™:°:•0Ü‹ÑÉ#¼)“׿X-By| ëêêÒå\‡ðê¥JÎ8Îa~S Cƒ—¬_±R_Õí‡òä<,†¨@•.CT¯êNâ³·%ï*!©¾rãI‚òÃ~ÞS™a„-cô4Ïõ Ç“›‚7É$¾ªRû:NÏSÖùñ®‰5ç ÏÌWÕWö‚ÿ>•ÿ™?1H{X@ [ˆ×EØÿÇäâqƒý¾þÁÅ[uø7ÀßYûçŒX¹"ÔH¡Tì¹h·qEwË•8!2zýUp=Îa¡×JŸ:8,hfü ׌˜î)²7^Ï7Mc]¥R¶ÈRȘÛ'§3ûŽâ~˜õ7 =_Yõkx«‰/Óç$‰Ö 밿˳¥Rú>æXu§Ò¬˹wcLμÏú ýhS}‚d ó‘sõ-O3¼3­FÌ{ëýå‡Vžál&{ž²–`·è[ÐmÛ!^v PÎ}°°_Ý&˜‘V¿pîÀÐ-•‰3Æ^äœÝ¸yg¹˜"ß“ñ©…ä|TW¹O°¹ì9ëçqö¶³AÛ‰ufÀ=…q±ç^þÖ rŒqn<…7ª3¿œ¯î¯ãÏ>Ó9Û˜j=ø(SX›AF›p³ZLâ}<’—([ñüK$^£ŽÑàõÞ™@²qóè¨É>„‹ž„Ô˜H[OŒsàYÖ)µ±¥N®Ôáú/‰…ã›·T8æ·Ë,‚¿k4L¥vˆí³¦ÍT« à¾]ãä'aØ?¯õ”˨ê^”Ã(Ū–>d?ÄHÓ“ÃÂñMÀ©8Å=‚æÆ°ÓŒ:å[ pNôP‚Ñ•ÏsYs]Ñêÿ€¿å™Bɾ•˜ê÷X!²‡ºýŠ`øµ8 ÅD´ß[J“Ä6±G¬o·èÖáÒâKáØÝ¾×\@§wÍ¢$à(¾ÊËJN¹ùòæ5>Šìèr-‚ì)~{Ùt:lmú×þüã¹7êª ;ò¡sîó·ò7ìyî@¿Ýˆ·sy¢çû¥¾×W&vþKEÒè¯ø‹µ6 Ê}ݤJ5|À©Ïo·Øäº¶‹¿œÔŒ{ùÁx)šÿ}aëƒuvbþ$Óæc<ÑŸx_)Þ$½f?Z·oø XP±ò°]³h#8ÉVš<¶ ]jÚBÈ~+„AïÌ1î¬~ûË/3f,A¶ç.:ŸÕ°ê¼à5MV|òîGàÇiì™Èžµ¼/o—…’…h¯ã*¤¿¾üÚñ…ïä¦ÅóCÀ„Á‚ƒÜ¬Ôk·Z@õ+÷®³û}ýØ!ûÁmâ­8½dîÇ ’ï"¼Í’&áv½|h¬r]¨ÝísŒ€IA=á¿OåÿÌÑ^ƒ‹ûÅ×ÿ÷ää sÿ}eFþà¯'üëkÎ5j\÷©† ƹâ”à2¶QjWžyë&±©˜V–§ÒäÁ1W®QjM©¡vÙ‰t›±ËÒ·û¨ú-å èÛnJUÜÐ-Š£Mü@U×?]›kE , š»^ͮѫáJæ÷¢Êxìÿý)ÿåh‘ö¨€öPÏýþ£ ÐðÓö`à·€™`Umͦúgt<ò$íž8ÌûÍÂNV÷ùÝín›9žæAËd¿4ç*º†\ÎŒ­žT³og]%ºHe¿±áB%¥XŠ ò*KkñÛ©·š’n¿rÅž^wyÒÒ}~XÁžè •ÛGr2¿l²ƒJ¦þCFôD«´¶S švþFwJ"9¯z‰(û’«2›õ³'×/]*=GBó®~šN)9eìÆËë$A¯õ(qëÊ¥›”äÕ}ްcgŽ_HþôöìσxÇœ"Õlî)ŠÞ<ÚÂÜ,ýBˆñ ~%ÛäšTQ©ø´±[Ju¡ͤBÖk L ¸x/9”$É {ýWü“*fxj+¤HÆl´ò©»O{f*Q^ÌA9ú±üÊ:8ŠÇhõÝà’3#‚?SEe9Ñò4sÔ¼û|оá/œW1S '×&6|~J®°á€ÕÍM®ÚƒÍÍ¢ªm.¢åŒ¥K€lŠ0­3§ûŸ>ü@ÔOsn,¾ž›¨…^h¡¡¹{`ó8CÊÁ‹æÜŠ¡7_˜ê‰Wf~KLt í˜= >äzÌõØúä­GÖ÷³õðtAi:釉MÓAxäŽ_î˜l/µR2˜…;J£§vi¥™˜ÚhÀ´3›¿söÛ9»=á¿/åŸå Ò =ÐóÏóãÿçpº»þf=÷b`Ï¿gEÒ*àSJMµÞé¿[„=D힑ݓͭ›~ó‰pÊŸ&\î£Û°ð=o‘Y~ÍðËOedË.û{Ý_Ošqœ´ýêï¾Êz.ú†$T8tµJXŒº90]Æe‘îä»M¥—OZtá)mØ7,k ¢yEqò¬‡ê׫öŽîqGC¢§(¥]Ü3µ˜µÆÓol'sÌå'Þùø ÇyJ¼Îrq¸ÏÔá 'éòJ(ƒŸÐmèãÈÔ©èû&‹à«#þ°ùIµ?iôË\|”;5ÁÚ÷ŒèZšúÊÏý×õ».æÊô-W³¸$°ÍDm®:€jYŠé|úyyœlçRÝä‹ñ›jÈ®!µàSG%ŠÈpr³t.“vªÞr³½ðaôô•èƒ-+Ï’}>C—µ8“P¢«îSÎ'PëNуw 2ñýû±ê Ö”á…9Î;ÁXŸ„ù‰Tê"‚ËM”GÜ熥><; ¢Õ ”Y,íôçTÚp^)¸ k #ì‰Ó‰•ô¤ &…Ƈ¼?]¦4!Ÿ¢˜ZJÒ}üN÷e‰Ð¬ûìÚéK!ßùÔJôß”±Ò6’fEPs^ ‹ž¡ï0„h—÷ñ-ø¦"PžÃÿŠyÄ fç¹:X<†«p䈜üQ}À±~œŠò¦Žä Åÿ”ÿ[o½ö„æ1ÉZîæÌ楜ÚêWƇ²„—ÿ9¡©,z÷¾«!!a”a_Ï­XˆC³zzB] NÐøjäâAËZCê’Å?%Ìð[Õ‰`êW$´oƒ&F©–gJwñorˆÌîã Æª¼®wlÍÿ}ßãÎSòÓœþ㔄O‡Ôq*VMºÞ_Ú'ü ÝT…<]¼#Ì3œšÚÞ_º¨×µšÊ,@­®w󬺎£¡[‘zPl÷ 2X§Î;¨Áȸ©¾Ëty{qÝýÕ|)>þoIìçO¢˜§Ì^3úi ÜW$õr0_—IvÐ`½‘,×»Ô#KM¨if”kéªÿ}3×øµùÈ$¿=‡{µ‡o¯¸¡Â§ç&£ž¡"¥Ô“Ž!Ýg–ÉÁÊ"Ì¢gò÷†ÿ~”ÿŒ?5H{R@ÎŽ®ûßüƒ‘Ó¡î¿ÇïÅÀo:¿¼¨òTXRFÆbÙÇäë¢s‘)ìëôJïg>¾Pëþ266ÇÇüý˜CÕžüÚ;¶ÚE\ÜS‚xXèTÐÑÉ>eÁ,ãe÷Üåc†ÖÊÑSë>÷ÒjƒÓ“寿é59~gtüR•btQ€­I®‰«H’ö­ÇŽUê«•~Slñ߇…é'Ø(„I*|¤y|>0ÔvŒ8[ç }3Zzçæp¦(eHÿçó%„3±…c»7PfWÀ8,ÙU®œìav{ÐŒ+x6*äÉKÁ,}ý+6›EÆCu¢ æM;ýÕËo_à±DÊŽ?M{Ôˆ4æ^Õ!#18œ—™(ø½N"Bö5®))3榢#A_ÐFÌ ŠO¹ÍÒêMU–òMôsÊ`6$$ S<K‹—ü¢hÓRîJŽJTÑŠ5ѸgÈi{Q£ê„ÄœyžÁ ùRJÙIŒ'è+û+<“0-Ûg)çðí)^GðßÔ3ÙÕEÛò§61æ»&C©mB?®öÇ3µ¸5¨–ÐuÎnx3ϲv(”–§ø>ɉƒB1ÓµhÁGµýas2G]Þ4|.½ûtwÚýø±ž‹ ZMÂw{ÝE’±%š•º›=±TjG¾,÷ߘ_ëФõèV´ßå-…“[–=¥šÅ;—Y}ëŸó‡²hRÂ;¼%#*—o“:q. c¹ôè<ÈÛè T‰ !"2üÂJDG’€[tz"†»!Âðþè!øøSÉŸãIç^2e³dû«çÝyÃbÓv'$™-lóTaƒŽˆºùöO—_çŒý=þ×W»–í{±µz±>ËÎÝi8¨Ñ_žÒeÙ¤ŸÍv Á›‘,`NcyíÆæuÛqÐæØ¯øK²«sÜëÒ/ïõ?­)uh•«*®Ïsoÿòlnl4Äà7,DøÚgÐü½™Ç.w¹Óú« ø‹mp,¨¬øá¿J¾uØ'üu^éyJU¿~IäÍm6$øÐ*s³!Köhs*›À sW´Ìš,ˆÕpfù˜ŒÙæ™So+k$(7—}³ë-Œ²9‹0®©# ˜ksBŸ]„{³%j샢ÅÀâØ∦ª È8û «Ä¤¤›Àç¦c­ãÚ±\Ô^ïdJñ és9&æØU熓B üKx˜IŽ©•fg&7ÁœÙþûQþ‰þÜ"íAÚöí·? ³³«Ûï ¸@÷`ˆãß:ÿ(P®Aõ„?6S²ó’ò£æ ñ¬¿/¥A¿ÜPδ ½tàÛ!SeíÅ JeõÜ â™â ?ò/¾•A”¦Œ‘K†4<Þ­®µ/ôÀë•&ÄNËÈ4Õn—4¹Ýdqîö§H'ÏBœ&YSט2Ucîà«s¥ðÅ®pgp}×iÁ?”zã„A¥—KÀÀ˜UR1øôõ…Á¡Æ„uŽ{ wõ²ëÏúá·Š0 ÊŸNPÀ‹ßLå£w^"B}ñå ¤EK–vÿKóO<Ò¹£T¬q·|crk¯E¾èí’R5'úHG¨:פíN^ù(STøe~úcµ©|˜ì+ßÚ¡ €Í*÷Ö\á d×»^%÷E±=è¦~:õ—è„#I¸ú¥#Eª9§éF8Éê2ø‹èÆkf´b’[ulé‘4x{#BòÄõƒ3ü­R·^R™9Ìû´DÚ¾’MY}î11´ ×Þ4 Ñá“”v­Ï¹yÙés¸¿EE•b ùƒåK°„sÌMi‰¥Ž9U7Àj*iózxüêGãàÓS>|³ïçÚHƒaMàA–‰:;µšnÉ¥ªå…›œ‚¬TŽÈ.Ýé\tP{T*Eúœˆ.'âTÉclÐèâ6ñJ–å·Yg-?æQÌÕù=g2fÊãÏÔ_Ü.lôUzMšøÂæ7ø?z£ûjCWÒXÓ¡sÐÝ㛨¯eÔô•¥ü2ž¾¦×õ‡—W®éfü-œî1ꎶŽó¶)|[æ2›1‚‡~¼¨36‚/_wgæÒ—ïì°Tû™?«cM¬Ñ¡XF’S"˯ãVä‚~¿püÉãÇÝpz‚OÇQàê}_9 g4ÍCä^lOîV;oyàíø]ð‘‹i倿â¯IH?Ò+r,È~%‚†2X°*‡e$n¹›ø‘Gñ6—3V ™{x¢ø7à_·a]~Áå¢àï}çØÅ…Š‹T¯Iy—ƒ÷¬Ô7˜Ý„† ¼Œ8·™¹õN+?”—;Iæà³Û¹_bnÀ£âôotô­s¶R|:I+ÀöÌ)ÈŒŒ'Áw÷Ìm¹VyÚø)Ëîb„ç¹ë^Þrj̲̜ZÇtûðŠnOCÞ½ ž¸þÁ§GòËm‹/^aöûÌØ÷ªšlXN`5<ýƒçu“ßÉûzô2¾0hùN׉Ïë·¶Í”)ÛþûPþyÿÜ ýy9:¹íßoÿþR€Ž€ßûpOFöÖPþ¦ÃÊ›èâ-¦9ŸÛÁÎ~ý~í{ÁŠ#6XÞ?[÷D¹JÉÓ€ KÛÙ XI´¤d0¼÷ÜÈ3mû>m§“uŒA½C¡5’_læ&1¨.KEû朜r¯M!—R-¥ZG¦N0iÈ,éÊ}ÖÃÆFêN×l,’ÜÚˆ®Ì¥~ ž?=cÐá‚—,ÉÀ$ªJªK4ÊÓ6ÑÇåÙOûa¬Buº1K÷Õ)“pÃ7žš·'ZºÃÞsÇb 7v, Œ¤ôò¶ŒÉSß·,uœ8\e…÷/Ç}°\å¥+ÂÖà5Ãë$9ÖØ¸˜ÏÒ(™éR“ÌÂ…Åøž ŽXGP>‰;nuŠ[[|¼Gˆ“‚Õ­Råþg¼¶ÏW‚«¾?çÀµ™ÈQÂÓÒ‰¼Èœ\à{rÑ ò|§ƒèÅuŠƒ¼·[ê•&rIÞÐz¨¦.ƒ– Ÿ¿=öè6L¿ ›òøÄ[êQÍã ƒžy‰ª®¼ªA}ѽM®‘‚Rí±·L%›s.^S¿\—½zw¼å k³¦ôàM¥ð¤j“.íâ1Ø<ëù!3cfþŸÕÞ5èµòVëg¹ñú¼úªXGNOóÖì͵k_«Œ?›˜ˆŸÄ¥¿¤Y]–ÞEç9ëËŽ|PÕ½ÆÖÜëÓÚy§=¬q?Óƒva¹¶yìÈoñ‡mdƒÁA“ÄH¯^¹í>cSm©ŸÊèa“Ù%#Ï ³®EÛêµf;‘Ãë2HRs#×]»y°†])kõ·8Jµ’âºÔôrÂN%Ì(…œ3(ÒŸŒÞÏüÙK‰ž(œŽhmÜ4¨ì7~=¨·ñ[ü/׃ —ãèRã“3󌡨`»(@ÔK ÖëÈ9îñ~q£Ì•XìDç™swÅÿèbo…縔<÷[Š'¥W'¤N¶=ÓûZ(¸‹ÿ²Ó%Ž®ƒ—`N"S’.š?'­Éçè';.)ÕE …ëfžåþàÑC+™†ÿI_¦ö²õKËoøW[É>F¶er\ä”!¦–ìSŸWyáåëôýž4ºÞCêÞ/Ã@·³>>‹|‘Äñîb¯ÂªÓ ý9§¬eºZM‚X·&V .ëU‡ÌA½Š¦f-tžGÏzòÅ­ç<†sü» ´rÂ!þ.µi›e÷7BƒF+ü´w/jg…(Km2r0½¼¤¨l½Gü÷Ÿü‹þ¹=úãÙ@÷õ·?Àìö;ÓödaÞ÷n  ‡™ÿùUŠ/þ𗂦=j>>õã‘1°„†.+8å‘Úhåã0æ{=xu¼†êƒx%øpÆ è&k“\’14lEðEÙ—t|‘‡>¼å3§~?-Š[JrM•ÏQ6¶AËub”·É‡49[©ìbÿ¨OÜËD6äƒU$J‘!TÔÖ,¯U4%!2ÂXiþ7 ±æÚ9û9|›J­ˆ±"NGÍpjßêÍš÷þ üA€¾~ÖÖú˜¢ð¯ÜŒ%$ŠžÕޙߗF¢#ãCå(èþjÒK&AÄ/ü’ì}ÎÚþìꕈ´æÊ4v»®¹Ù õ·õTõUï°%¶Þl‹«Ú]ák׉Êt=l_ö?nêô6iê•2UG-Šúb‘´5ÆK+IŠ`^zÕ"äWÙ;¸œz-t’Kª d¥C"r™qú(ûéñ”ÕrªÃ«O;™šHÓZFŸƒ¿7·—ÌÑ“ûtÔG\LûªULls6}®ª´Â–õ~\OQÛ­ÒAËH5 Ö‹6Й»}ïoñ©6ÐaCpªâ4žøòAéš/_º#²¡•®gf”˜bÀ”žæI¤/F\,_§ÔjÆ'¢‚m®²u:â)ÏØÒzá¶RP>ÎBNèÝ»D¥ŸÜ/œ°üKÐÛÎòä©|†›‰Òªý£¦¼ð©¶‘3·Ÿÿ&Õ…÷!ì'^½9Zª‡Ÿ3vª«AŠò°Ìr#eü—µq—FÓs€R§»(!Á"/›Â‰®%ÎÎÙ^]ž÷_픵ë!\µãžçkÜßü[µúÜT'H¯8™˜Fr¶+¡‹E'YKé7ø÷~ùòÍh\#÷hWÔÉf6èØ•¼PªóýEdIqb‚«ß.GcI +.® kª’þŠ?Q¶kŒBoÿÕo¦X>Ïù±E_:Á½cÿ§‹~z4>ózl¾/»æÿ2X¥YbB±Ö Á¿ Ð—÷ÕxŸðO§€†©æ¾/Å0ލ¥¦Æ¾y÷ª»:ËîýQEÚ³Úq]lÍ=xxz®Û$Æzøï?ù¿²öèO ÈÞÅcŸû÷s9;ýÖ4€=øMàoSN›qg2¨ù Ýëho(*wwx½þ$ÈE¤Fê§óõTÝ«”rÞ¾ ì¦R£ïàù¾IÂæFRGˉ“f§lš²ï“švöÑj(‘©çEÎj’ÁÜã©oo¬Ê$ész¢èÙÊö¸ÎAÅNgÖ€œ2ÛšËólÝÃ4I§6¢IÂì5.*Ö*ˆl>þ@Ó[¤zÈ$IæÞ;øÅoUŸÛ˜'^5µŒ»srðJT+½€xÅö>y>«ÿEoöÁJŸ×Ù†;Æ~ý7»×ÛZ¨ñ%µˆ¹æ¤ÌFœê•¶ú©á¦9CJ)× uãlJœüNVyóoj}HdS•ŽÖsÑõ^?ÌL\ºå#YIÂýì~t½óôObÙ“ÌÇ´:›Ï𡏬gç˜|ÉÌ™*+Ac7Éøi´˜ßÏŽ¬ f/‘ä)hÑó;Ÿ{ò¸*™hÎ+­f©ÀO3ÚWƒmíäWq%´úXO²˜v$÷÷¦€?zÖ¤) ß¶Þæ2~Û¨FoµÉf¤ÿ¢Ùˆ±¢ÓÐ’ÛÔÿ–‚ã  !2áHÌýÎcËp5¹C ¼@:ðí%m]K½9«†gíÃ8­>;N«§Ñìgug ˜í(* 4éMš — ª‚úÝ/ ˜Vä°Ó›Z§ rMÖ.ŠS¦zñÞV°Ó^²>†•«$•;ìwù›bõYSã›Ú~ÝѯoÕº’~ë™Ï]ÿÁ2>U‹ç„( 2Ð’”¥Kk£Ú|«_æbÆ·\,y0üžRúÝBÇBÍaçÁ £â}Îÿ‘wgÍЗ— ´%F_›ŽEgn…¾ùçüªÃ|´¬Û 1H÷¨Œã]ú`Î3ŠÅ#_xHõk˼‹ÞŠfHœO7[ ïͳ_ñ¯šÇU9cì9šr;íl÷ÇAúu‘‹»øƒÎF 88{õ8…ÞÌûûé\ƒ¡¼ÚÂå ݶjiœ¸ü<§íëeR„à=wÌ[¯ä'þ0öþ+Ö!†Šª™RîµôäzXuJeÍáK9´0œVšÏÍÜ56Š©ª6‚ˆ9±zÛŽZ.T´Ÿ.²÷ÎÞœ¬Ð͹îŠ]¡ð¼ù‰ ¼EÛ,ÉE‡–LiáüœP!A`ikç‡ÜÕ×Ål)“'-´Ò Èûؙ֖Ûº“ýå¬ÄØel‰3å¤Êù2(ï2“·5c«å1Þk·š¤áÍÓ(Œ32¾4¯óíººH^2ÙgŽ(NùôÞÔ‡ŸËójoŠÔ ™ÅÝè!ª4½-°VFÇñ1–XϨ9:óûüo\¹'íA$Rër$¸’uFl*,ýÊ'J/‘Ë/Ýí;¿Â]²ƒË¾‚KE7„|Ñ20ãŒå[þšíB“£bÚÆ2@}ˆŒ–ÛÏ_d¿óOMxó¹™Õ¾§ì‚È e©‚WåqE‹ íÿœ¿w«gY4î+.‚2\GÂæSG>%⾕%%ßY9Kn|}ðØÕƉԂϿäÿ<Ö=¦ïv»‚|‚ÁW¶“‘X Œùån»øŸ}øýb­†gÞ±‘ŒK€J4_鵇Lëñ¸Uþ«éž½âÓ€}Á?{Š:-¯54“¹È@YvÐ}Á‘®™:º'1*wDöÂç §%,š¾ ŠåŒ&B1<Ë/¡ªÁƃ5ÜÓ«®&F?Vv ™Xóà wO&@ ½šœ[+¸bSØqÈ dµFl×uêæûôþ(á†pߦ*›CZG¨¥ÕTÚšº³,·éò‰¿\Æ»_­M-ܼš·‘¹z’±<#9òüƒÑqø^ñßoò¯´æèÏ Èèõ?ðíß_ àwþ$ðÞŒüÀ8PP¹tSxî‘Ûk¼¡ï¼š£ÇªŸÁ­|C%m^–/!º‰õrEAñøŒã‹1®ËGº\?³u»ÏHÈPä¿=~ÁdØç¥‘Ç1§×–ý¢Kœ»’ µ„5þÒZcôÅ´¸(ÏÜZp`õ¾¡•[* d´TL}ê‚?ÖÚ(°p”6fKÉc©Ñ=÷òf>Qc¼¬Abp˜Â)1’ŠOU¤¡ü–Œ=bVsøçh__ê>ÐKí蟢ÿ\ML´°L_XÉp¥Ÿ±èð{[â2þ„GìÖbõ*ã®YîgNá Ì,y1•ô3|O»Ú‘6HÇ«§×®z:MtÖ)/=#àp½j=“ôä9š#_û¸ƒ:Ä6X”3‹ç¼ûf — äãuᕯVœäWÞVéõœ·°Ô÷—±Ô¡¾¦üL%ª )çñìÏÜÚ=ÃLk*ý0µËØÑVƒTžmλ·ÙS÷Šž£ÝÀã!c2æK¢ÆÊ¤ŠaW¬Ïíä3Ψ3ÒyäPüÁIr Py–‡‡5Ú^™, Þ“h#*î“¿ø=¶îƒ=܃@ëL‘hšhØw,O¦ÑU<þ,¶€¬ÐA~ðzý˜DCÞ}3wÈt–/ã±¾‡´«ÖØôË/qåUâ¿4­ ¸‚ËŽª ̹T¢µX<’a$:? úºž3&¡v²õOøKO¼ûúkQÂ9g¦8¢îP­¯L!ë­®ÊX¶þ—XïBG®Â#„àÕ»qÜrt‡Hõ·sÐ.?}mùT5âÊòûÿ˜ŸXJ™xJÕìä]§îž¯Æ^m Úm†ò¸ÿ”ÿ»X®wË·[7ýYÒ¯ÌñGy3ñ(1(ëBòÇsMoë–ZV/Î×ùŸ8îûöÄ¡ñ_ò‡E3Év²£8X~¢ðS¤ª[{”åeÙÝüeOàË´·ŽFÝtúi…9šÿîŽ.̓ xþ8}—ÚôöÿoWî;‹×Y¯:Í™]RÁü¤\)õüùç¢rË9`ã«LƒRBñÄÃË]b¤' æ+¡ƒ=ê Ç¬×Œ ¯…>ž¼Øûž¥“Ãù¸ÑÛ…^l‹È‰¼FÜ økع2«‡l:2ÁÞQ_ïô_k§¦8~6xåæ5e± ΧjÚôÝ 1&Š‚›£ý åGMŽÒUZ‰î“5A‹Á´²Ä#ODËøÅ2Vòº#ü9÷Šÿ~“ÿ཰FT@NŽðÿoÿ~.Èiîÿ4žß›€ßuþ’ø°øý"xPpDÃëè$Ó‘.ë_ñ$H»}»+w|+áŠõâ5»â¦œ4м™o`)òªQðòq½‰ r¬ù9 ‰ä‰v6«Æ3Þ23+»uei±§×ŽSÊP:¦{å°@êkbâܺ fDZ†³z9<ëIùÚà]›™ž9óœ˜ pV|ÁxÅ]¤¢(m“ ]îŒN¿0t^ÿh·~ôBå‘ ÊËöc™‹eåÖ}^£Í|™ôC,ÀòYŠ6ELÝnÏ>;bÒau —…»äˆø}!B!ý‚æ›! bÊ÷À}êuÍ­ò@Y¦œ’sÅqM¬œªGb²ã©¥ }²[˜Ïa;òŽ˜¨k<³ƒD:ÐÐåˤÒÜš¹ûæäª‹'\ñÒ±'PýúÑ»œÙWx•iÞ]™dxôÝϸåm„3<µøM ûç²Ë¶’„z¿àÖWZ}RnÈùÎçÝùYœGmýØ 4þ4æ]Ýa3ðá µrW0³“ wñÉñœƒ¥^¹:‹ejG ÏšõÏ/À(ž¾±'•û Áf¡%~[Ž7ä¦ ƒ­kE‡€=u×»4#=,îÕÎÒŽ®J#ÿñ~Pê©Í€ådKÐúy}zÞ.øwZ"íAVprj/Z2Çp³WŽ‹³HUÜ3þûLþ™öÂýI­Á>ÿ+ßþý\@ÎN0·ÐïÑÀ^9‡å7.?3…X‡s2V^:¤£mÚÙa~—,Ùi£¤ûbgXëäõQß ð3ë5â § ª>ôº*Áú0ºSþ¡ÊBSOÍžÁ±^ßëæN:£ÛT¦eît¹ôÊëÖ¤YìDö—y&´Qy%V, H•£E|¯ ¿»–Õyà·KášaÍ÷Êî\<´ªÏv´ß{sF<òÉtº ÎÍà5ÀðÀ­)Ÿdº³_ÉÓí¼«ž¿"{wkÒÃVŠŸ"±.“½ªˆóÆÑÄëEqc|OW®˜¾ ü2ÇC¾(?ÀПùEÌ ×,Ž[é9Ûä_wŒÐ)x=¥ÈàÒøu3Y‘ÒpµM+ËåçG®&¦‘Õpæ?½Ù¾*ˆÀyó6¼µ‘âÍP†’e–ÈW%Êø˜k¯:Þãô½övéˆX³ƒú‹æë‚³Ïúð¢9A •s¯7 ?V—Æóà¾gn ÔÊu#ªµÖ=\¯s7uŠÄß9{p»J%Ÿ1bâüaæ—äòxüU¿ºqû5¯ I©fkÓKÕ9]¦Z˜Î[Æwkøzs7ÀÎZMŸÆ»äËø1ôi ‘Zmí6‚|œù ÏMÜ ï’xkOòÖøXxݾÚ2ŽÉPÜø>dúýýX‡¢Ê5ýOã¼°¡¿~ .Wû™÷ºÈXV#OªÄ\? Oɸ^Ñ…ÿíOù ˆXPV¤‡{…­„Éj;¬ú²¸}AúÌÙ˜³²œÑ™¬üqL°¬dç~½®QÝË‘W5gÏÓ›®1<´Ê ßÿü™â2ruÈxmÕ^ é¿Á£×$œ•¼dÄ%,V,YÂÊ÷Ïøß¹ô&Ü‘6«Bø¬ôjÿ¹U…¯òØÉïZç„fÙpVŒËÈå8!‚N™CÉÉß¡?_ÿäü«¨âÂF‡g¿§Üþì´›ÿ}3Ú[ÕÆM¼Rïãd1üYø¨¦7_25† !ø«ž»ù_çߥn¬õmc¢r 0Ú•òá ˆtÜ) *çlkûQ<÷}šê7ó˜ÂJ=×âSnŒ ZpÄw\ eo+f}wqiâV·:uô…W^¯r¦˜» {©Ù'=Mäd©RÅcž½¡¹Vn«ßtæz¬—8j ©ŠvV/øUqljöòÍöx–cUm¾s‹)B!Ö|ŒŒ“¦}D®‘\>Þžª9Lö5~Ïøï/ù×ßcôåìÛ¿Ÿ ÐÉÙÍíU/þ 0²ü¶ðÃN…'a⟿\¸Dá"^2hpÒPtïˆÆ‰ˆ€7ºÙM Ö½§Êàt߇Á¤sÆÏop¸ri\{5ZÔO?¤.lèÅÞ6[Ò4»ž;#Ó-©tÒ0XsŽÑÕ¬—àØaÛ“Wc*28ò"³D9_?í~æH§pŸJ¬.j4Cš…Dƒï`žHq§UøYÎS`øõ)¦‡·Ö1®Ë [üüîSÕ°ýcé€Fw6ûë-FO3¼Õéu_ë¬5¶~¾„-åðUΡÍ)¨ã;ó­È«n·ê¿›ÅUK‹êwöÕ׬—ž,d½Ÿùàû¢S¯™•2BüKlÜó’7ô3Y©í¾ºLó4N>0¡sšµ¿¯jŸ<ÿ‰}Þ×US–Ǿ‘¢°hàṸâïcE/1¨Ô6:Íùy¬ÏP1†£C9ÂécÆÓµ¢FaÁ÷Ïä{Iëøy8*ñ—ê˜Ý”‚{OÄåMóÔÔŽ¦ÇGðôLšw7™Kç#ȿ߅o åàÑ gÇ­=nŽö[O8yÕâ]¦„tÆ‚ö`©ÞˆÝúë%.~#›ÍûBõ›±Ó–Œ¡&œ?™¶õ=žÔh­Ï© ÇK2Uzn¥Ò˜ y"œÏ¬Ûô[ºt\¸•pýkâ!ó&Qü4­[ï|J"G3}òæ\"Œ"L¤"•«·çÁ.Ù,ú².Ñý1ÿó_Íú¾ψ+á›ÍÁ©\"ž‚¸8›ùÆhwz¥³ÙòümT ±V+péž÷ÑüÉ)¡:š3¡³½­7Âïé<Û÷üùålE©óó>×ð1Z­(иWÐņå±v|’äñßxsfÝÉþôì•ä’ýÒçDÄä/®¶40¬w;SÈdz„Ñq<¤El°ï /‰9vú/ùSC9*“¸î™‚È\ ™jÆÝÆKT8´‹ÿÇKóÁ’ÑÞžK–áe¾@ówt¢æ¡š"ÛüõÙóÌû쌉“ž@/…èYjn<Snϼ꾦e9QÎçÝ.ðÀ#ÉúŒ ¶uRÌa‰·5\²½Ò ¶¥Z 7Fl¯:ÇœxÇVÐïc¶¦x¯kT>¹ v¾½ô™+ûÅ;zï“ߊ&ñ.ã(Ôºzeü•%u$Y°ü3w0Ü@£H[q“È›±¼¹óó*Ï¥>4D›“BXFMY¾1%:Zã0ñ}Ïøï/ù÷Ü[´„\ìSGàÏëöï?Úÿã[üÎÿþ €¢NP)‹ÜFnƒ¡} tpôuEöºëly1âLä£A¨ÑG\\\]ÁW(bˆ>Œ8±ºu"æìÝ G3w/ Šlóƒ^ÙÚ³ÕÄ3†i1ÐÙuÛÂDÿçä E¯l÷j¹Án[÷ßî ÔŠ“Ûî³Ñkˆädñ„ƒ!蚢vo× QÈ®MLw€A@ z¤ÝB`+ǵ…iÛÃì@l½ƒ`ž²»§P pW3Á¨¶!W o:Ž®Š~*¢¨›#k"«C p@¡Hº ?ÐÈßÞÛuwUwýÚÚ@w%jk‹?ì‡ÎÿámüË^ÓÃ}ÊGxùö®^Æ ÅœÚÞ‰Zß4ÈGX žû“à Ç wøƒ¡˜· Eô£˜mm#~€Hð[ÍÞ?ü­1üw5Y; d§Aè#P°3¢Ñ Ô‰@g˜+æÈÄÄ)N®Fó oÞ‰º5!n;=ƒî[ôÕŽn˜ÇczùT Óžðß§ò¿o>»ßÏæS»?ªÞ>uïòM@©È àŠZZÓ@¶Lò½9€¼  t×Ù(©B ÉÊ t eÁ!˜ˆ 1g¢·AÛ‹m1{»A€Wè.Ý»«ú;Úñdg7ȶ¶ºÀ¡ØÖGȦ¸Aþ¢ü·6Žpd—òÙ^8Ãwk$Ì\Ü Eh@7WŒÂ~p]ý±kÝ;È5R·Ž€Ð-J?ÊýnuŠQˆë¶Hþ¬ìAÀ]Ân+B°ØÖS€ í»A¡h¡E)Q Z5€@Î (BÓ‘Jþ?æïìýIýïnf‰Ú@ðGVÓä Ý}`K_þpöÖ€™ë>åïèŽãhïùGüQ/?ƈ1'B¶€-[´åü-0ø‡í­Kvøo™ýKþîä‹ÝyÊ~áïáí aî˜}0š%x .f'ÈÙ å¹ L:‚?‚9‚rïÐvÁ­ ¶‚­þ@l!ø#)h@$Q ÆäBœ]Q‰ˆSÐdP‹=|/øïSùß›\ôŸ—ýmþÁî€ö yÿþoÿÿsBˆ· àƒÃP*ñš _'ÚËDÚlÈÙîÃÄ à-CŽ1çÛÑ?r à qG·äA: Û?ÚÿA…mÉ5ØÖÊà †TM W0ämþÁåEþð­0ùlD„¶ÕÈpÎÉíMþƒÆ¹@0ØÏʱpÙúe·ÝqBæÈ–ÉÁÁˆR±@è–¢@èn… Ún!†a‚„šþ9Ø `äy ‡B¶µýϬ@?…Ä(qFèŒB·û‚©Bon+$„І¡=üð‡x@¨.dׯ®–Áî`L?C`à0€1!øÎ0mÙÚíWþ¨ qƒ“ÏŸðo[iðÖ¾í¨¼m¯¸ ¿ä9sǺ£n±‹?Ò›ÿñÞ»½‹ímd7cü è¾áïäáéŠæ6àˆšaLüV¤€òùDŒuA~“ @l¡³ÿã €Ñg#㤂¢ù£dˆñ ¨€Û±ûß u„î ÿ}*ÿÿêMûÿXö½ýÿã*îAà?pþz¿¾„ô9¡¨× ààêŠZC«´ ^9”ÿ p¶ó…o[| z'pÇÀä'AÎ`8ã«#®Ah”bþ]Ù¼áyßõG„ ´Ð¸î6[õܵp†B· J?¡.ïV,ˆáç(rëj¤Åp¡"Í„>ŒÑøálD㆖. ‹ÀE4ˆŠv4Jínm¢ FÏ"“€˜Œ"°åØÿJ`Ô'…n{þ? *ÚØÒ=¨zC P´žA›À¶¾EK<ò"d¤‰8€>‚h¤aÿ„¿­ü/ÿg[€ .Ü·{þUÌ·kÍYoÿò‡¢] ‹=Èçøƒ·­Ä¶míÎõî2Í¿â‚@väfëÈ.þ»ŒÏ1ÿ.QCïà @ö C¤½vAÂDú'Àm“ºÝ]èðÉé£XƒÐvvÛØ£øÃwúh'ÿ‘üp;AwÁ©Ù~@´goøïKùß›Éè\þÌ?øOkùßrv3-À-é;9ÃQýê!^]0F WP©@ÐÑÉÆÜŠþQ¢FçÕ0ŠÃ èŽ À¨Àà‡üøo9 ;®rÛÒÞË‘¡3šàõ¾-g˜ÆíNÿbÚ·5 ¼m£¶;ÁdçJn\¡gÀ]ú-{Û÷ݾrÃhN„õDÆš@Ø–°£— x§Ž¨ø‚aüþ- ÚÎþëw¡3z£ÆðÀÛ]Z¢ÆdÀ»Ü}ŒÄ£{­P¹~d}0— TŸý#þöÞЭªî2л£?4ÿ#ÈŒîýùwödé¼ù;»c6üÝ~Ÿ?pÛØÓÑ}ýS"`û’¿á¿•;ØÙ‡Nlóߺã.ÿ`WÆ`·³ ¯!û‡?ÈÓs+‰ §l…ÿ(]ÜrJék7*{ÚNø#ý Ì@ÚØ𭳡à]‰ôÂŽXAóC¶¯C6º=´å€¶f…üÿ})ÿûdüÿÃþcdô7ë Ú‹îµ€ÑJ âm@Ê9Æ—E¿ûÈ75-ˆ—Æâò wGÿh#ŽQbÎ@·ía~0yo “ø›qôÂÑÈËÙÒö˜àì'-©ÕÏéß­vl£ÅñrïtÆN`ˆÑ6.®(fgîÌöøOÑòΞ ­t ÀÑÎÃA'üvLº[Å¢€³ëöt#: rÙÉþäøï(´Cô9ôo”6zèvÛbÚ’ó£‘vÚãG] ¢UzD„®°Êà ýÈv­1OÅðßá†JÏ‚è®]H1ÅÑlówtߪ‚¿½÷oóAÿ’ï¬a6ÑJù%ÈÆÿ/‘æOwÜ}Û¿x¶Ð}ÂßÁŒ¶øÈJlOmW{Ç!¸¸my7ÛnÏï{†±’?¦Ð-qq£Ó®;‘>JÂüw’˜AÔ€½à¿åÄÿÿ#æüg5Ý‹Ào:¿¼È†„ì`p× ¿hw²56ˆ|‰¡(Ñ‚¶žn´u·¢ÿ-}ˆ"n°-뎙€#3¨ &Úüä¸x!'l©bäkCþ’(D{Û˜Ûý¢ã9´l@PíÚ>¼+þC/\0Á!5w£û‘§£&íÚF­:#°wôvƒ¢S¦;à¯#€Î øV[.7J4¿Îþ¤P v’€»;³|·ú‚šÌ…„¡ÒÃ; }é®PyCtÆq"&]ÿ98:Oÿsä¿cE—!€í ´Ž àð>æï‡nw5ààäû»üÁ°-ðßLÔǘfä<À¿ç¿+ؾ3Ä¿Íÿ'cÿƒùØZl½‡@ð>áïêéÃL† Í ´ËÜý9’?hÇöoiä¸#†?b Á'CÜI ÀB GWÅ÷Œ$ÿ­”j´±éÙ#þûPþ÷Ç÷ÿ;öÿêúÿÇø{à9ƒP©PG83vÞQ‚Jˆ"µúäÇ&P0ÐÙÖýMôš¿ ÙJ냷FüÎP8xGÛý ‘Âf÷ÐÝgkÐÓ  Ôu·îoë{tú Ù¥ûÑ¿AÈïvéìÝ-ÿ¡ý¨ü/6¸B¶ãN„ú‚Cv= ³ÝöDyÎv@o(|+lÀÔv÷ 5 ÇõF£œs„…úÀÝ 5éß‚‘ó²¶ìFá¡å|kÚ® 33„šÄšÆLB¦æoð·ñ„ïêÓݶ„à¿óÑ×N ‡úJë/{1xÿì­ö5Ðîší!¿ÉˆÁñw3õѾmÝA¿ä¿ر󘋷‡ÿêüây dÛö;ÿíq~”¡G}D´ë+0æ0¢™Nî˜ùþÛ ŒÙEóGiÿmÿhÛøow¡³+ÊGŽø#ùƒ¶“þNðíg¶®F~θ7ü÷¡ü»÷Aù_2ÿà?¨.hOZ¹§Rh`Î.0WØÖÄÙÕrD÷Feý¡ ggo:úÇçV–ÍÅæþ!DÁD)@D¤ Ýìßv¶>ÜóFÄÔ»”=êÝÞQÍ;ž.r•þݽo§ÑÔ·@È57(F]ìnþVhç‚þÎeM¶çŽ!ή˜¸´«* €û®QA0àdöu…lm¢õ5d·B!Úê ‡¢¾¦FŸ"œsà_3€»Àîߨ{¶4Àq28ÞVÿ¯½+ÝmIÂïºûc 0;›Ø²D²/’eÙ o<¬»š¢wbEXÓÀCñìî]wUó˜¤.œ5ŒA½„ØÍA¿Ÿªè%dmàü÷/dkµvÓˆuÝpt´Ìyˆngô_¨TøÇ÷Mãßœª–ÍøßoÂ?Yàj€a -{z×â óÂß… ú(¬–3lÿ/S/ê¿(º)Œ‰GÀ1Ÿ¹IŠ…« ô'þÅDÜeãÿGåž²”“€‡ €É~£½!ïî…ÿöæÿüÿŸŒýsƒoiñ] ?!F¬ «71|§‘„kø52€¾Aªú#L@ºÝðœ—Ú?¤âŒº&òÚ@ølÂôN¹@ñëãóE²©QØ\óézñ%­™eò`¸ü®Ò¿kºÃñ_rÌr½\†úÁôð3ÑŸA44¾¾>÷æÌXóvñ˜vO?³Ûõ}è}è_€™]¤²– À¢^Î`è—pîÇ ¦f>6˜—²ÿoÂ?=7„ÜŠ0ãïºPz1ÚÕÀ ØñëaÛø¦âžáááûMøgÊv¡ÿðçyxÎÂߟï©õÂ\á¿T÷… š.-OÙþñ'š¹R‡,Âb7 ¦óËÇÝ3¡pCÀŸZMcM{x7:ÄþÊ@žs„‘unѬ:Þ ÿÍÍÿ¿ùÿM·6ù#€U@Ìq?ôs“K÷Í–÷SHMU Pl¿½N$éšö›<©jC9ÿ.ÔŸr*Ï‹Í?__9¢»Rô°¤ÕPÍx+îØâ®Ô’>»“ò†b[>ñ¿r zÕ4c²¿‘v›³F]3Uˆí¾½L¥¸_Š («/éÚáhÙÀ »¤ŸpòŒ.=Eh™§=Hfá“ÛŠ„ ‡„¥=L°äÈ¿±ùU™nÄÿ|*Öxbˆ¿öc¹ .çÞQ®’›mÿJ ÁϺÝÇ—ðOEÔFüs|ÿªhÚoáO ¬”üT<þN¸Úsß1ümÿßÌÝŸpV??…PO™Çÿé§³E¿1$Î…CQÒcUýŸ¬öÿ$rÀ&€˜ÄYSî…ÿææÿøÿ'dÿùÖV߇ÿßQHía<õ;’3×+F²²sF&p÷Ü>½Ž\6”õý.MYX¾ÔýDHÈ(œ…gc2Õ%þÑ\ÎýBýê»pCfO8gúÒ;trÁæ‹ìX½ÇúŸÊò\–HŶi‚$N÷ÍVdG4ga¦áÐ]ðGÙ„³VøÉÙ;ÿ³fú·XÔÇôùéËóëQ pºÑ¹æŒÀØž–µ¡êí§3‘ª[)íч ÅúŸõIóÔ@I»•€ÿØÜ%þ_ÛûØ<žÎ`HÆþâa3°"륦=úâ ¡í͸¤+ÀQ€JA ã€¸Û ED# •¡g©èrú qBñWð7°¾=¶„¿{ë‰cˆÿB|ú}óøÎ I‚ñ¿¼ÿîhe…‡¯$˜€ðþ¹¬p… ÿÿÍöå5ÍðÿŠøkj°¦û“Ø1ë> ñG‡bIZˆ£y7&ÄŸSå…ãsþ¿ùÅʵ'~MøBd~7Ý ÿ­Íÿÿû¬ìÿS W&€Ýp¤ ß™snÙʇ4ÃÈ@ÄÁØ>Ÿ•½·q2[?YWØLºü¡Í”ø%¿LRú91)Ò,Ì÷ú+6§¢2¿ëMòs!í‹X"ñáË®í¿ÄZPNS¾~ln.ÙJ‚’ï •Ýááõ,nÀ(ùkLÝûÜ€ê2k–ÖW0bgj|ŒÔÿs•;0Ö”Éâ5(ê]q¨}(R ”a•`~rûkø—gá&N½~aW„_›)%aµëñ˸yü÷çâº{a§î°ûþ^ü»¢öX+˜¦¸Žÿj.êüˆ¿¿¥®ìΦ\="µ¯ðÍ·5q&4iéü7w@œx¥Hóußþ3ý÷hÚÀ‚*‹r6Èì“â/k´ß´ÂÃµŠ¬»RžØšý×6¨i6Zëîö8f D’¥ˆ iì»gvÆ"Ú©CP`ØL;ô~æÆCæêµ†byE(KW…ñZ øŠ @¶|_Ê¢%ià ¡X pÿUüÏ” ʼnßÒò´Ü+ üõhzxøø÷ÃõÕ0ÝSº¼ÿ¶×Ua’K¶sœ\¯fÏÀ:þ• kì Ç_ë6©zW²ûPü÷3þ)‹ú1o‰ýÓôáP$ {ð!8Öì{OzfƪûvõÆx5Àv”C(2¬3* CsÄ×D U1 I÷Ã[óÿÃíÿŸWýÇ¿÷7ÿÀê`äZôÑt™'M¢0¥H•ÁIR¦yoõÀ‘6ÄÃWîÂ8ŠÚ@uÿ–ÎÁAÓ`ñ:•î[wÑܯšþ[“)è[ÖõæBôl@h?Ñ™ÃTU‘U±"Fjÿ­¹@ —¹:®£FIØ„ªÙ• Ló"«‚ˆÚjæ8_ãH‚¡Š`ó G©_o`±c WÀé|9Æzò{±$hŸ¬Uü€ÛY%üUüw°2lüuØÌz[3YÒ4édîâËöñï« þ96»ã;ñî²(Õ§{É›õ!` D5-æ ÿbn•acø?–ˉソ§žMö‰¹†±ê8€=ëår5uŒû3âŸ9ñ¿d‰ jdö­LŽ…]žñw‹hÕ¯ýñßÔüÿÈÒ; oRxœìXUÉÿðQI) ‘îiP)ATJ¤éæöåÒ¢‚t(%HªH§¤ˆ ‚ ¥¤ øÞ Ýø¹»ü×}ÞyÖ³÷ž3'f>ç›3sÁ‚þÜ;Ã`?ù!þQ¹ƒ½½þJ €pøžÜ…þÏÛB~¯ dǾWɧÉjB…NPª$ËšöýçSØj%¤J“¸õÖšãbË#Më´¯fuªYgEs|ã¿tùÌŠËP¶¢VMU3£[Ç•_.6Žk²y?•Žªï÷îY$šoÀŽÇS¿ÁãqäªíÑåDCpuJ„Yz($÷D`pÂŲ̯¦Â³ïo^OƒsŽÈ/Ç­”(MdÚV«ô(œ¥ºùúòC>Çzý{N&4òÍÏǺ÷e¿»úHž/·÷ÀlèócêU³.Öþž‘d±7©‰;×xå4•Ög銚 i)œI |—ÕºàOx¥JJ^%’†áÕ[A¾†ÎÎUÙî«>ÌD”Gg¤Ýí¢ÒÅÆÉÊß/>\ßWæÒ;^|í)w9LLPþÅ­+ÍÇ€st]ͯqW¢É?9è\Ô½XfØV~$û,)ÁëÕÎ¥VBøÇqòÖ‹•.œ>ïNô1U0(ÅaßTx‰#çÿznêñ×®Y‘õPµ¶»#ÚÁz¥âebVCÎ:Æw_ñ«•,hÓ\ˆ¯Z¯¼Ís9DÆÚ©Ï¯¸rNa‹•c%"ï­ ¨–v|¾crLŽeê­GÂwý¯]‰D²á7 –”±Ng‘©Ìóó¸XÇŽÅ)ÿûù?¼^(y ëuøI»/½fæ’'}zôn\izÙ\=Õ–ò…þ¯ðOCUj8× ¨ëR«d“†|zË¥Ø+›ÀRô9?0gV< ΗÙ3Û‰ˆ øCþGü¥÷Üê;'"ö~M«ÆŸäÀòpIBA€ìNþ>ºôïÆŸt5jÞÄÇð?ö؇§êÚ/îÏçÇÓpT»#$/%†ØÐ*xí$ e7‘sµì±¯û¥æL‰ÇØÉ/O÷ÈhÚ ëÔ¶:`×À¼t–Ûì2dlCMõ eo1?•«Ü{:j›b~•Ž@RéDOF‡Ï‚Gµ¸Ñ}…¸oÇ‚n]L_ÎÁ~‰O’Ò:vÔõBvh+¸ÙÎ$ƒ¸ŠÝöù/X™öŠõÅEèàa­Qlì÷ï«KVkôÓd)6{x×Î.ìÿ•ü›î‰)úûâ ôCüÒö ºÃ|?^ù •ÿôÆ{áœúx{äqj¼QÊÁþqçé&¢Øˆòu(¹¹­ÿAo¢2ÎÎ ÇR[8ÕÐz‚~‘سq“J&¶cãÐÓåûbfU­F¦d­³õ–ŠÙÔOVKòUÛÛæ=§²ö|ôjšcüI‡þ§ÄÔ+DGŽÕ¼uO¬/¡ãÝàj¼+kûЍ¬Ì”üÌÚœùš×±’S·pœWJî6³Âªêð‰«ð£Zäs¼”UÕ¯áî²™µ(Õ1†¶âr.ïV/|*Y¹œW̽PNjlF9Hˆ˜3ä““ðŒ{]/ìËËçÑ_`rS76NWÿ„—h½œ Ìc¸êTòñiU÷ë«Îr·äÞZ'Sò_¨„‹5)óWªÆ ?yßô ›6y»ô™Û= æ©w;/FŽŸc¼ ëõ1&!½zöz kXò5£å&|²šKc´ëã£l+íÉG® ‰Ù$rãËNÌä„Ä´òZ†¹’ çV<[9ÿ!1#Æ/©ÛIʹ«ÀPÔ²¤Åj¼lõúM»ä§ï&†ñ›<ø¬¦¿2 ê^¯ç/V­ƒöyñɽßî±¾¾­Ñœ“þ Øu¬x{á¦yRøþæñ{´J‚ñ`Úk‡ŠXHâ’ R°½ó?Õð0ÅÝìË­5Ë ¤îc³uIœ·BzfBCgêp5ž…JGOé‡_‘è»zÔμëªFØd¶!ݩ۪†+K'?÷PzuѬ—w2Ÿ;ðä!„ÃE‹c1Ú‚B“dT'£Q$Šð¢b#¦?\‘øTSà—àFg‡Ï]ðØyaB¹¶´„Û¡ø§YUß’ˆ³{Uì‹NëmE:Ô£Kl€ÎúYI_êš³\DŽæx˜õëÚÞºQàÏ$H¸qJràÚûyÐE'žÉìÁ—·…ºçÌ ¤R¼¥æ¹”©^c ØJ—µ—eS=T‰Å¶ Z9'|jŽ™õSZÏù£„…X¬n©¦ø­ò%Èì"U* /Ù?i;1V»Êícù8°÷¥˜ék îGÇF¸/‹†:­È¼šò|YÐúâ,|>ª¼J›œ{€Æ=)Áùø¶mïÎÕ€&*JÕ€Ëd’2ôgdg ùZrXíDê2ö¯=PT°×»ëïdÙs¶VœÏ$áll”ME‘¦ÛUMúå°kùr÷ñk*Ý9Œ)i™l‹ªÕ Í}bp–Nw™ƒx"EÓ' è(Z'íJ‡Í…u^†'È(Ÿæ½$coV±¬ %äµêì ws奊WéÄ Èh¸?À}éë! Ž&yQ¡tj.Sz«š³4q,Àq£B ÉUïþ0€¥ÅHbËòû•; =n7ÁÓb&O³^ùRyQV„MÀ¥V_¡Í­‘}±æXM‹4t}oøÃ,ØñN2±3Ñ¿ÀS5Ý—„=1FnÆÙwZ殯ƛÐëÀh‚Ð>Â@üQ\ép»îó¤ ío’“ï´øÿøB¢ê\5!½üp¨ÀˆR³§Do-ˆ5È™ä¬+^øT_Ãó²`$ØçQ:­~ȼ#¥”ŒÑ~f(/aMå Û>ÃI­£ V=‡DpÞeÆ›Ì:UóÓÊ ÿ!ÿL˜üâÚ]‹GFO¥KÜÞ z1HÓždÜÉÿ€›¿Nóâˆìð {ÛðGþ£8ù×Öñléþdþ)*SyìáDö†!_È}?")j ˜dAP'®Z×O(”¿¨±l+ŒMV3=Õ¦çù™†4Ö'0›îѽËãìÀаE÷gÅVi,ƒƒÌ·KSIæl‹î^Â14ǺaA‚VÌ…Ï{H_püLeLžfûU©Õ†ªWïöõ¦ÄÍuMÌœô3õ÷xTž“-øñRú•eÜ$nùóÎD½KáŽÍ.æý©ºý¾1×z°ž÷Žÿ¿Iþ÷ÆýÍ:Aü=yû…‚ÝÞÞ?ÜŽ½øûÀ–à1kö¦‰4¬ëeåh†Rx¤ ì}S¸×é ’ÈÓ—•"”ìUa⥒&ã×½“Y|òç+äŸ+=çQ_Êxm¶ÎI£,  2 Áw…µ™upÏ8¬ò•x%£ed×”&ÝÐJ‹® ;uòÞâ—f|½'^=¸=ŒÙßj»¾àMË:³[ ®1\@XÌ׊P^ÊcB0]çõOó1ƒÊÁ2_´¬–ë `¾,ÿŠôr›¢¸Mxê󵼦:ÓþúÇ̲“ªº’çK_Ûšvt-×Üö¹]YÈa!LÄ0¡ƒúó’‘6ˆLpÙgÜ+J£;?i`¦ö‘qÿ¨aÒ§ÅÅh¦g”+7ºøún3y?ü(Ncq-;LhõùªCó.ëN‡yû¥ -‹­|I=]šjÙsJT à6Ñ1§’ß÷-Á<(­ªDˆÂœ‡»Í3ÍëH OQtá>¿)y¤ëÑåÐd}'çª7ÝÆx:aû_O´eÛê©Ù8Ú&S´ú‹hDô5Ò ÝkºÇ¯€[°¢ìûô±DL¿LB×õèÃÉI½ö©Ù¹ºÎùÉ©*ö7æVR¹ºWpÜöS|•%g•8˜9@}g5Tè\ca€Ù Ýý’ÏÍ[¾¤‘4 œ q}NÿÙ„2茒Ób4[æð½H«ñ³l1Z¦Uí}5{Åøè½>I’ ;¿’éa7‘gÏÉ‹LÛÍßvGÕf<Ì˪͠~%ø)3ÜGð«œ%3Ï*Œàèd Á¾Åå_¯¬<¹Y]Šˆþáæ‚Û«•-Yºå E#ýx^‚¯$¥~˜?ìh Q§×UY{K'û7Lxaë\‰ôKóYëÙ_Ù# :SY‚çßÊ…M¶Ÿ~üîùC¬¹l-xÏQOŽ…m;FtïÁ¬ËÑW#Þ;ùc5[¬‰Õ'†žO‹g-º†á/uæð¹ùƒkn?—?•_Î…xINì>ÚMé3IL/Cnû.1%{\EäF{Ð?w»vÁßp’ÿ Ó2÷ü¤zçaC8ÇË*­™ŠµKÇ$Þ|•åúÆÑÕuê¨WU6·¥…ñ‘@³¢Hˆlýí(]§¨Bµ'tdjA0P®ð©ñSWåë×_XìáÎ NûûkdʼnÂoËÖJ²¹m0ê%åØoécþ±ðÔiv¯„3Ï´oÂ'gje ;÷ÿ¿Hþ›öÆýÍñp÷òý˜dºC|~t cÏFþ¹0Ae+j¾ v…Ÿ˜wßgÝ›‡5O.~‘:eÿ(S÷ÃÓÖò:Zã01‡ñ”@’ÄÓv7ÔŸ"ð õØÏYš©]j«›‘, ^»,,3+û¬Î®VáìZnœÍ‹Så´.-d&+4MÒàºeÛÁ"ÜH™DÈ—¡fëTE !Äi¸!ŸPs?3Ý—+‹ÇW[” KŸ¾­ VL×ï; \+Óÿ?èl«iýî áûë)½t¸€‡ýÔžó1 fªWò~Jqñ J ìÓóúuòœ;|JçŽ0\œë=ÙûÅâÙ9ãªèE*óÞ³i¤WÇŽ´×òÔËY·xéWJ^N¨z’4vÞ ÔÀÈÛ;þ nbf55·¯%\uO #Ë}áp°ÿô,„7U "ðn*\|Ù¸` >ߨ{c®*iªzðDù¯Áø²¿dáœäZå]3YZÿaZ nQ<ÇR3é¤8`´u2}ò5Ùüòÿ\TèNv@ãd‰´Í²C÷'»õŠ“~ÏÅQù®ëŒ0ˆ.¨ÇLS×ã\©]ä-{àôÇü-N<,–ÈâmRîi) ¾.?‚e³³ÞÉŸ{Ð;¹÷à»#Øw–»*ù«7ø»…ÅϺòSù“.]FÄ9¨pdFõjËeÜ;Àä¬y%Ša ¶–öÌ=aXÌà±¥åÄH&ŽäâºsÑ4²ÀsÓÙ/éö'ÎÊÏç~²d ’™‘½ð¢í~ª°‰[Œ (9ƒ>ÿ±å©o ]e·‚Ž!îeÝOÌM ¸E+x¹§¿©[iÛÀzrÓ…}-ƒŠË<ãý;3·s¾.I(Œ~a£‡æô÷Ì}0ºÉmŸóêÂáàQ«1QŠ¥iSz*°]´äƒÚköeÖŠ~â¥%ÄnxmÆ@##KXÿ­k|¥þAw<ŽØÏ¿ä_U²ä–à"ÝßýêmJ8Á‚úHý Þkô) Ã_Å?7tÄŠðžÜKþô¤>¸D@íP1šb"sÝÃ.8µzû%Ý,¤ÌSÑ”ñ$™?Æã(B±;£õé’ ™m~ þ µÞöSð".‹^NÕd‰‰Ä3‰±é±MK]!Ãñç5˜¹ÖýcüïLi>%?o ë=Bã?ýJ’è;A` ã…Ä僣©k? ‘|¼ÇâüÞñöù§=ŠsÃfž€½²M¾3 ´â+ÖÿÓ¡]ü—Œ˜ºÁ TëÐ,ú× þ•B|áks?•ÿÊ£—6ˆ§Âùu’C|ÃU‰(oæOš“&²œ°­8>ŶüñIñ=ª+ÒÎç~{Çù^2gG@ó8÷ÃÈ‹Gïq}!P‡PºO„Õæ¹Lš“êÄ#¥¬NRïxØñ#½fÂÏwWÄ» [˜íœ¥rfâwà}¹613ßÉExQØ$ñxz»TËcýnƒ05Co>Æt§êC¥ƒ-À³P—Á)BƒÝ{Èÿß#ÿ%{d‡þV¸}~vç$~¶öRöâœVo¬€Œü 1˜ò9JóưýX’š?Õ4Y|tq®¬hµ@æ àažžLA}š§ðÑÂDkš0:3¯Ȱ ,´G!^Ê892Gº@ÒãLj´¾-Âàõ‘`ù«›oGBg$II¹Î¬w°ú’t×qÊt ÍŠýÈ@°tf@œìÉÅë€çå ä 'Ù/* õ]-"¥/E5ÜÉTç”9˜SðdfPªôœLÖÖ¯QøÌÄ”ÐnÝfÉ”™díÛ¥ˆ¨•†ñ)¶ëxQ‰¯cÆ´ÛëŽ4Ä•¦9œ1­vH±†:Ÿ™­d%Ïæ2~0ÏÐwO¼§ÐÄŸÑìT×ÇËEOfÄ=‡gØh×ÏZÜ»vù‘³’áH¢·Éžò¯"ˆ<_'CVœ¾B=<„HÌ‹%òs9ÃA~RììߤgÖ5½fŠKa£/#Ö]Œ}Ø{]æáÿå–mü±¥ÂfvÝC³ž¼Ê}Q]yŽQÙV“ÑV£ó¶Á×>I]ŸÕócüùÉ'e'ºˆZu¢5œðO%¯çâ„)¹‰ÒPG¾ê~TÕfÇ4|ñ¹Š‚žx´”¼.ýg@šùŒðµØVx(­óÈ=.uøËx4iOê/~)¸\ðûœL5>ˇ±Ëç‰,Î >™ÙbUL®qB0oL¨¯y´V²ƒEc¸C%“Vל!sß=‚¢d>ÊI ¾Á'.ŒbcTqO\ kâÜëŒJ(6 ÍšÝcþ·†"ì§ñÎ@¨D´ZÐuDj`WR|Ëí u«iÇÓöÔ¼ã{å¾òê$Á8±Zð/Âß…äÊ!\9±×OÛÕTÞÜpày–|{xˆR<³«„^ÆIJÑn*^üBzéÔðW‹ vH=tò­ãWšQߊF!·×ºñ±œw¼þ¤¤ƒ³÷矖«!sà~9?ËëùóÛ°‡D?=êî|wY‹ž{RYø¡[0içNþɧG«ããÛ8³FØlðw#ïò3ù›9™¦zyt‰>Y≢¹y‘=O•DæÛžWþ‚½:?™–£ ­græÕýsuý]Ô2µ«×­b]9Áõ¹á¢4®ª"¨”ŠVœñ ÏÀÃþæ3G_Fèr’HçÁÄÝ -¢/gó§&:¸1NõÞšì<%b¹€ÕVNÙv¬SÞmh™FÛÚÝI{ §ÉÌ%tAÃ3ÑÙHåN71eYÔ‡u9aLŽÐ¬›åØŠ×^òÿ×Èÿɽ2C£@œAþ¿øÚ¿ß ;ÔÛëGêíÙÀ?sîñQ8X¹UœO£úÂ}N òÞ*ô6iVTÔ¢\.\¯ùÂôɯû5EúÈE<ž†É=žÒÍ–TÑ„R¹7Ä^çè*&«úÆ ®°í &ýü±kßà[›€Ï•—¤s/ÄìW­¹Á0àÚwÿ¼'ãR~í'ˤ1ãESÕ}m$|Ï+ƒóŒBºåI^¼]!_Nof$|ñ@Šýâ~’EE+ôƇ8·4ÉœE¦:ÚoØîÏO xÔF$å}|õÓÑóŸœj®˜æùÌ«úôŽÙ\Éùzò©•Y…ÚõI1H‰ Ù9lÒ'sØRÚ&ž8jOĽ­P=¢Wb³ ÿA×ü"›¥ö¶ÄÐgÑ =°óCð·þ'ªíD­WŒ†ZŽ]˜¥c†ŽŽ\ˆ§yc‡+±0¥tµ^æÄå|°wTDð¸Ím€Æ·¹ÖœÏ¦¾’F¯ KñJ…ªg­±¾¹©]Ïçïc‰1©Ò‚?=c =\rÑÒ•ðü\ê„ hBDï•~kÿ»Äw¤œsž²]Éjq¢³Šcpšºvû•7[£«j³€nÊ}±g%±_‹¿ ÞsŒ{_ ñ©1):ZkÃEû‹¦¯í—uler³Ü®ŸèYc:È=&ÕS„;U-AÀIûÈ ÷¥w¹‰cøþç Ù–+ý}n1öˆ—¾ ú¶Þßsþ–ygöMÞ‘>Àc”gB­è¦ 8¶ÖT7â›=s1cBmëfý¦p—°‹é´oÜš—„*"ùNü1ÿ±Ò¦ºï‹.œ&ÅøiœUMÑ´ª+nµ“hzÚZ]Luû~FàP÷ÿìO"ÿ{XoV«Ã£i‡‹ˆÛ.‡9i7) 1\;H-ÓÃ¥/ÕDLHŠU¥>ät° )ð&Ò?àÜü²+9N²D÷é‘ÃêoF. ®órhXŸ•·]^Æ>³ð¨äzŒ|,âªñ£o œ¾eL˘õi¿Ò$÷±Àçôª1Èól"YÀ:¡ö@HT@tо*üq‘–SUæߺ7Ç<²Íâ ”úÍ„ü+<ÂÀP2Íû7—hÉfwo”ž¸ä!",˜Èpí)ÝM—s\ˆ±2Aª$A׺£ùHË"†Ô¿½s=f»~´Îâÿº548öæþ~íù‚‚K¼¼„ÆÕL cíÿø‹­“NÔ> ¡/y›l2Œ“ä¬>t"×ÍÇn\óæ‹.l ÏwR}Oâ¯Ãÿ€oz|Y›ÿm*ÚœÆ Á¼7¹6Ûͼ‘ÃÑ5  TbVmþÁ±SZÇ›¬ó”ÒÔ€ÿ#!ÉgÂÐYý¢5ÊD¯Ä°0>vÄÌŒöcûÑù“G¼V‰g–\Û÷©\£RþìqV>«óù?¿*FIÏÇ´BVfìšufRB²1&Í/ ¾“ÿg›ÓÈÔPL˜øû$Ë þRðŸÇ?áƒËù·ÔÌ“¥vjbxn-V‚ÐT›gYÉwßudY¯¤ÏÄ*?brd£ô"âî0j=qãK¿zÇT‡1nÒÅ8Ži•÷ì3·˜˜%¨ùŠŸÕO˜Äú?¾ýô³kì)lÏÞ΃+•w /šKhX¶®ä%Ó¸t-Q Ÿ¶æNÕ$ckå&TdgæÈLÁÎm#’଴S—Œ~l>­ æ.TÈ)«\ñÆÅáÞÑÒ”=忇òÿ„þïËÿç½2B½@!ðÿœý‡BÁ?2 `G~Ìø}àž6OkÿÍÊI½ÈÙoµ«g"‚q·S4®†77uøúņêé »»*äJ~Ô|jê0`z.êm×Y]†O½í6,N9¾Y :ûokºªì©¥ÃÅlwØ\GTnÔÌWâ5¤„æ3‡7©'ÝeÅHñ˜dÝGaíÖ¼oêO§3†?©«b\•Ä“­yLÏQØ/–Ét:(曘¸m÷‹S¾Å$¤BW±°»  +)"MÞ7i(ÕNŒ9tfe0Káž" >n›¦ñ N[à%wªäMç+oÇܨ><Ñ|¹y^Àçu²Ì†«§ã‹¯â÷VÈv U¶I4,†‰ÏT¼µù$x³b•9MÏÔYžr”‹½Báþyö'\×9 ŰEVÔ¶#’xÍ õîäù¾bÀpîE‘Ð}«5>¶¶Ø#€*Él5Í2o©"ú+w­ºUÁj^ÿz´ys ON1yÑ®ÕÖ8w´iUV×gÚ&êÒFJ¼Óê¬ò ‹Üw­>¨hóz>¨ ¿ÆÄ,(¦EÏCգݔ#HØwPKZË©¬Œ?ÿÖëp.ëe%–•]ü}JDf—µ½/ET²ÔãÅþtþœ&á4÷<å:õÊÕyFϺ,¿ÄQðÿœ–ŸoÆÿ¯>˜¬úH:¦€¼@üùùòì‹þ&”AÚ'"” }ZRo¹È‰6ò.åòÕÞ—(×(o5ȧ È~‘F]\© `Í'P§yµ¢=·U±£„Bé:½p•‰c»‰°´HRˆüÅ9#h/ÃTèx‰8–\h.ž‡,´lê-gúy¼“^ܫРkä>•¹YZ7$äš,üeîTî)ÿ‰üï™ úËâîîýYû÷}ù¡ŸÞÀàÌdÅýn;ÀÈ"ˆÆ®¶-¸JÌpÜcÓ…òh;@i/ãRŸ}mñA¯nÕäLذ‡m®m:Ģ݋.qðªÍG±$€ß´£mõ9W([tú¨;»ŒJVØÕÕ¶s½Mü–úþòÔT 4{4äqÌ(¸-õ=Öâ¢QO ¾z‘ɨކ³† ×]`Âî8٤׸;gcÙ°µhßC½»·ï20²„>붉¤Rç+”{&ÿð=0ð‘VíÿàÏÑDÄw@†…ã9‡_%Že¿sä½¥1ÈgVyE«aC-ÁìòÍY3¸O¼§|¡£>]KùŸð6öÇ{c9OpjØÑ þæhy¨EðvÌÝ]ü³ps,"b¦šŽ"0þ¹üËR|¾ž¥}eÿ±Í{¦v%x¢åIP–dÓÙÒ­ò$Ì€ÎrÚÇ*Õ™¸r« h>?9žVÙyîˆv#acÇ‘/Ï…ÔÓå[H)é…EÖK^«41×yÞêŸQzÇüÁ¡ªþ7Rðr/õô£ôÓ1ÓGÆÉå˜"H¦ÝeHdf“ |o;P0)ØÙ´Löˆø·(µhÁ‰ê+'>~xßNxë!ágɾÂX+B =£˜5åYÏŽÓk¼•{ÌåÿèlK¾åß’¾=3A±@\€¾ÿ¡µßÔO{ÿy€¿—#4¾ÿ?+9Ýé!ñ#£2ϰ½ú^¬äž_ÈhÔÌd -Vá|MZè‰Ã HR±ZÑ æ€†µƒ\¡ïÞôÚ>óüŠ-[‘ñ RüJÅZúø)D W» ª7÷¸ÌÐ0¡û€ª=à£iª6Vp£»¼~<ë3ÕƒrVΰ¬¸k÷e#›è*j¢]ø ¼ 1³³x)G=†é‚b¡âwúR¸emg±»lØçYÞÉ)­×…c³˜J¹:¨~‰éôë—7.}įÕ*D0: ò^›Ë)ê®R”;Äyu5[Ñâr˜¼ ±iוHá ú í…眓Û[$‡f(òC3b’>‡ÖoÈ•2YõŸY! ˜ðµÒ2’næü~W¶ };ãFÖÎi‰¯‹o¯XVŸzjv‡Ízºû:Çå÷Øà¢k VºuŠœmîÌÏ/æ~ r>{û¥ô{2Âý9§^;fë ºˆ„«¿]Åņ–( ŽLã½Û̬‡uæç±Ï¯îöº­O±”ù_õ= 4+Iezæ5a%Êv3çÅ¢ûN(BßÍäi’‚¸WýšEqµšÆ{c’7Òî©-í«§l>NFËô,êß'BÎÄÏ´gâáh¾h ËÏ—Mô=®Ý™â~^¯À´4Ø‚ ±^IKÎè,¿|ÆræC_Ή8å4Ò‹ä×EÈÊ@4—ù_IŸMü¿ãßà\yîã5í»¦31šõŸjÝ÷zT²ý«›—ÅÈï—âopëbÏ¡ž¬f%evº§€÷øLÐãu®X=¹®»÷>)}}a`•‹ë}l6±ÓÛBÊ?ão«aUZKÀõ¼ªâ4u NE¯ÁÚº‹?àF·¥þ²rëª‹ŽæaÏ";Å'ïEðê¯ÚË(a“Ù7ñ›,Qlj­§³àFÓ˜Kĵ93(FÍ¢*{=uDMTR‡qÕð‰ö :¥°3v«Ž‚!ý¡”R³Gœ­YªÞ³ØÞHQŒiaÔ^Ëœ“Q07RHÏâ‹åSé´^:| ’”ØtëN¹ !®ê‘ÈGfO©hÄ[.f6¿ÈÒÊLóúv•cLêT:ÖÁŠ'z¡ª.’G¥jD4³¢òÎP^»6~’uVªñÌÞòßSù-ø{òŸ½‡&è/€Ëlíß÷åÿ$ð^Žü ð›ZÊa©<¬=(Ãtœx£{÷¹M·},¿4ðÊ&ò9ÍÊ=ù+Ö+o÷=Ê•«sIë/Øá+:nx½Ñ/”6%š$å«®˜•?’ùàa„UA˜–f‡‹¶Ý`¢ÓI§À‹%"Œ§Nk2z¯"* 2„$73K§”¿÷¼¼fĵ`ÔÓf¤Ë ~Ú>ùÁCýŒ‹·à9væò¥™ªJQ^6­v2¢îVÚE…)“~Ùû,WÕÚ‰J–ØÄæ²Õ>—tE¿,g’):rK“Ë‹AWò¡êÉ;L)½C_¥ñùÕJ[;>˜ÛIèᛊ?9ùí #ÑÛô°ç^d§ÛWÞÖ…Ýy~‚éCY´ÞMµoÒü‰ÅÙ-\èšK©ó‰N{ZO®(ù_þ–!£hTΪÒ½SëmWÊ_8Þo4·2ÈLÙ ÿhò!c±àƒÉýõ$ fgž.G>RcXE¸ó;›)Þ{æ¡€b<"?f0A_›øZ¬.?÷íQH‰¯!ä¶W¡š>ài±¥£ÃÛ€cÑíá"ú‰cçu`­?Òg%9­¬Šî§ª-?BXì:¦(qÔìälã\×Fšâ¯ÎDÑQxºøËÁn¤˜ɇö< <]Ï@ÅìúĸF"û–8Î@æ"Â-ÝI¬/"ØrïhÚT2ßÿ!ÿº—ÀÊ·—ëàEŠâS>uµ¯ÖxÖI¨¹ <ÚSªIuÔ¿±ÃÇÜWøº(4 #H-&üÌ»ÅæÉ²Øñæwç,³û·°8’·Rœ(‰$=ÿsþïëS/Õ¶W#“ˆ3Rü`÷qÜ®~‚ÜTa>?ûlî‰úX‚¡6Ç8ݦƘþŒÿQïä"‚@Ľ~}ùòðÒ5BoŸßÅ?­ÇC­›HKö´+"þX‰ÅOã#Åú­j?o=]HX@?ÐŒê…@A?^÷çþûi²Ý&´‰Åü¶¤f~FaôŒþÝ]œŒ¥ÂÃn™WÆHòéô Ïfe-{Iç}[-V 6:~âœÕÅç1-z„¾Ü­ê6e'vrW‰Ö†Ã‘²ô)»7—[É÷ó³g7 uq¸P&FšT(+s¢ Ä]u˜Â*„cÈùòt9ž]ZÅP7{çmÝÄV‹CA+__R±ã]"ø0?0¼¢,Ìðz@.Ò5¬i÷ŽÅ~<òmVƒsèÇ"'íÑꈳ‡ ŸY_×$+4Ñú‚s5Ü"3JHMŠØ·’2¿ÖÅCî$aRvZã6Ä©¾y*½$cOd”të€%¢íõçœôYÎÞPeNjפçIj Óqeû÷7ËN=¹_‰^ÓÄñ@‹OIÕQ=âžs¯bàó÷ä…gÔñßßxGÊ%zºBéqÃ\¤WüGcÐÛFb\›¡$[rÙYÓ¤é׃ª«Vf´í·Ò©¿ù²ä(•2k+=<žë[}S$¹¿òBᮂžô‰>¿ú2ªf]¶º¸e‘Œ¯TòŸèd¥HU׈¿Okß’J"óëý×C ¦?åOý&~ý#@·?©®R…{8ñk>øëÀ;-y‹úUç%Öý'™TÊ?ßñd$á}0£˜ð>‚ùÏø_ðY3u(KVº¨9Ý,È©NEôe$BÁ§–nfÿcr—‰yB¢ŠßϤK¶ÿ,þ Ù¡ö….À &N f¹pús®øÈd}d¢Æ¨œˆ9Ñ&æœ|¶;ÙQ„y~âe± 42Ö´íRê æÂ“W\’±€Õˆã>Åêù“ó¼†=݇;‚»áå7×¾CåÚ”Êt(­‰².†6¸Ü|O™Äž\_èòù[kŒ·á‡CØM¯'ö×½iÖ°2Åkžj›ÏŽOeaÌ©‘=tƒÉÓxØãiê¾úãÔƒ_Î|ŒÌ½´õ¿»×ü÷Tþ5uÿŽü»ì¡ú;‚ÚüÒy€¿Ü‚³Ó?tãþç!È/(ŽÜ¢zzB¡ †ü #+Â`0ÄA×BžŠü EÕ# @ìñ‡žÞPLäN0²ò usdmäuAðÍÔ%@`êläÕÁ^þžÏ„~–˜O[ì ‡ ŸÊÆ9¼yt£9‚ B<¼‘OzÁ·÷m„A=pèö=wÞÝÝÛ±o³þ¨‡E¶ ¾Ùï0ý´°»“ê/?`zkã0óãJ@äc@žž¨}ËH/8j?ùdP´ç·MgóÓ&Ó-¶pL?!;ûÎY„@À°­“1ƒ ¯‹éZä‰B²Ñ…È‚9€¼zòz°Vÿ3þ„×v3vÁìo7uC$ÿ 2`G ÷/ÀßÍÛ¼ëÆ½ÑüQæîø—ø#ûŒâêoØFmT¿¢?A6yCÑG!Ð?æ¿YgøÖ¾-þðÍìØlßõ_Áìëöv ÕÈ® Rj<á`8š?z'FQ°qæôQˆ2îBòGxbzŠÖHr‚ᩈ¾úFkA=à(ZÊÑêk‹Ž‹ÏÞñÿWÉÿÏ6½¿¾ýÿËMØ+û¿WJâÐo2ù¶ABC J²‘/-'¨× †mÈ=‚¶î(¥ª8{Á=½QÝiò·¬ýn‡óÐ` ܽÃÃà ƒîVö»ûÖƒ¢4ܨ Ù~÷wèþ ýŽ<ô' ±[ha˜ãl§z‡mŸ B==¿ßÔ'~[úiÀ@QMÇÜ¥P}ßÙdo"µ ª•@êÄÝÃÖŸ@Od¿A=a;èl¡ÜV½©`H©…Á·u<Ýw¦ù]gãd—íTþpئj£k£4|OøÃà(÷o‹ÛÎíï äGw'hà/Àß}kAïve°'t“¿[Ð_áìf0ÆذöÛvÕß›VºËø=þ°J¿±îÛüá;<€-Oaû”ŸÏßèÇ( ÌÃlv´ ÓêmþèÃ0F§lËä¶AòG¹Y ¤”ÁÐ&uFäWbÃáÀt ²u3 ÿmgYu{7Ï=äÿ¯’èO-ÿóýË­ø79`ô%ç¨÷ýº Þ˜·Ù¶æÍ·å÷#koF¿¨“¡@g—oL³áLo)2´rÙá li 0)0=À×¾qíPÕßY„ ¥ð„ÿN•íVa®{av@0l+ìÛ¼¸©ÿB€^ J^w¢ÃBèŽgB>;|ã+pú{£âŽ:ÈVƒ^ÈFÁ^h}yÁPýB*ÊŸ‡AOìú?¾é¶£â0 ¾¥´P‹VÛ"Ž>¶3æƒÀ›w`& cšµùóÿ˜¿s¨÷ö#C·ûn£·MÁVƒQü‘]áòû%øC»îо |óà ø üQvÍ+ÜÿÞîï0ç?á…ý^|¿‹?ß´û0Èïf~*Gˆ¿/ód˜ÇÛx‘7ÂØVg"?@hþ˜ ¶#æßè²m7ÅsIlãÓF s Š?æÔÓ ll @/ *9¹«`â~h/ùÿ‹äÿçÚÌû÷ËÛÿ¿êü|`ËAa›F ¶¡`(mƒ`¼(:3 ä»P/1¾33ˆÒdH‡äãáè¹I`übÔvSi€áíwvÓ¿‡‘®¼‹ $Ð ¶C5üF!ïxV¤|z€üà[R¸½ûæëuŒgà›úë¿ù_è¶ÝA_àŠ4¿Oƒ!Þ8F}¢µlCð6=°‡ ¶§ÛáêAÐS<ÑJ ¹õ£:ˆÖT`Ȇ<îÆô€ÎèaÄ Ù!ݨ; R€;$;ã!ͶØÈb4&Ø+þ.HþÐÊ~Çvgà·c?©]\aA¿€Ï×ó Ùü}ü~˜?j4 yßaÝ¡» ònûü‡ü1¶Ë*ì ž!`¤ÑÜyÊÿÍ:àŸÌßÝÅŒò)ÐJßø´aá·Ú‚ŽÇ1ü7³;Rÿ›û6¾"ƒxè†É£ùï4þÐùÿ-¿cã0âáƒæÝÀtÄu/ùÿ‹ä/— ýõòßÿÑå¯4eÏìÿ?wÀ0Ȧ÷~a1ÀÈ7vk°­g6½´½@+°MÙ@?OÈêï¹eìÿhðûÕEÝ tù{ïÿv<ÚÖ·mõŽrì=bR‹[u€ÄV—yn(… ö’¿÷¶’„îìÓÛmn¨ëØzxþ*ü½à»oÛðk·-ÐÍ9üùƒ`ž³ÆàÇØ è.»¿#Ëÿgü·R¿s…-þÄ®éu»>ýTþ@/$ÿ3ýÐ&½Ù=pcÄô„£§ w¢›¾©u·ù£;ÎÝËsk¬c“ÿf Óƒ^›Ziw ùÝà íçcøo{Sîð½äÿï‘oèO,ÿ¡ðU~¼9?dµø¦×À¼¤›æ-Í$ Ý샠­ö¦ ß å192ЩƒÔAsL0üíà?æè†\€þ0oÏï>è÷ß¶4ØÝ)È@¤wÛ>²ùòoÚäW7ï­ sŽØÒÿ˜øoçewnС!ª„€oß„ô”Ñ)È­À¦¨m§ P¾#jAv#=€1¨H¥DÁÀ ©G‰¯ç)€­»Ä­`›]ˆÖ!Û€7ûßäÁ@PÄFˆ€š¶ó æ~ ö”¿S€çöslöêoLÁf¯BŽà€_…ÿ挂­»¢rçð]'#ߨòÃ7†®Ñü7kÃ6ŒØLÙÈÑÿ!4î?Œþ1ç!ß7ÏÍi»=èOåïCñÿ.±™ø~VÒ»ù"M*Ès˺£ç)b¶Ãâ»yc¢ ØÆN0À±3ÿ¼#ÿ>‚ÞQ…ºãl\ä±§üÿ5òÿ3ãÿÿ˜ù‡þ…í]à8m‰yfô;¼µîŠN‡ ·qS+€wfýб*¹òB@0J »‚<¡Ë1ë… ;ƾsÀv/OØsc"ío‚¾]áj¡‹Q`§ÎÞn"F½ƒÞ›±Û¦QcÖýnþwë2hEÝ|0h{ö8òÃä·=d±¥º6Ô'ØÙÝ õ'­1ê“P"E †ìJtE2@Æ7H…´9õ3­}7¤m°±c·8· ÙÑ’Í@hkµf=·¦Á·B0 ±ÇüÝ=·žû7߃€>ÅäóËð÷ðýÞ„A à£ ›üý~Œ?Øs“’ÿw‹ÿ¾› °Åãø£ïþ€9o›ÿÎiß;?¿=Ù[@4ÿÍPuÝ­¥»× †@^¨FŽØ^$€‘Ë­<Êš#ùƒ7ç"cT è‰Ø0þ˜üÿ–/Þ @7 ‰Š>†æ¿)Û»&ìÿ‹üÿû¿·óNýH½‡Á˜âå¾èu?Œ@J©47'ù ecÎÏæM‘;8jAöƪ ¤Žpñô‡ac;¶[«æ0.ÆzB]ÀA^ð = Ù¥ ;r¯;B;zmFiÂ75ü¦ØV4ßéLC7~s}m´“¿Óußþˆtû·vbæ(c¾zøC·ã‹Mùï1ô­P7§@ŸÍÑE´"ÂQË›(S‚Ž*½`¨‰?À!T(f¾Ò–;¿ì’æïÖm-Ú­¶£ÏA*jÏMÕ Û @^{ÎâÛJðîîÜÝáêê ûuøïž€Ù€¶þ|éæ> ÔÝ)äGøƒ [*¼ùk¸`ûÀïòßxG6=€mbç9HvkÀþ3ù»ÂƒQü¨5ßM÷ûnƒY‡Êü`fý7Ló–Ýß1Fßà¿-­¨:¨A­µ€þ]ùÿ_@òÇ,€£ùÃ6æøA\½÷”ÿ¿Eþbþÿ¿hþ¸U?d´ü–ÛØÈ:¢^ðî_ý@ö¡†ÁÐÞÿöj`ÌŒ!0j¤õRÁ½7}lT”gëäï½%UÐÍÜÝï,ÚüÑ£êHïÔ¶ëYv}ÛŸ6Ò¿Ž™£½JìŽö@`¯íó¶ŒÇÿëîZ”ÓÖè7·I𶤕lCJ’¦Ÿ|µ/íÚäÁtÈ@´`cûÞ=@Ÿ&‹ÿ@ ‹ž\OÑmÝk8 Œ6[Ø,è 'g˜â»[?í4 ˆÊˆÆ{˜øu˜¬Ö+ªÝòrx´Úƒ´P44 P k°5áÇOl €·1†V9oñµ—ÿÝÖ©ÿ×·¸é†Ç/„£°ÓJS¼=‰@ô÷ýóø³ïXغGië6£}Чïàÿú ;{ÁŠ¿pøÃÎþÅÂøK¾•û“‹üK¢y~LÿËÒ´ Àå¸ý¯þGü¥a±5ðeÅ÷Tœñw†5u€B‘±@ï’òN‹ÿ…Èÿçÿ¾§ý?v]'LéL¼úŽBÿÜv| pxâ¾Ìa»zÿ¤B—vÜ&dSA6ë§±(/R›3²VÌËpÕ¥?“|_‰ªm’™9aˆaj± pXV13©ºÜ ‹À÷"'ÁZþWé`fo¸ÞÍÞšÓs)‡<Ù`³›f1«!`W»”Q±ÿšCWºŽØ‹ƒ£Á8¬Ð2 l@º;¢ŒúCÞOgàp ˆ_3F ë ³jîSã÷8¾¢ø=Xx†ÿºò•ðÛÙ¹h{Ñ¡F¿Æ#ðO£ì!0ãः}‰ gÒå÷þ¾Ð*>Dü]ÓÊ9ñåe’ò}è¶Å²Ë ÜJºJÂ}j[¦› Dü™rL "›ýú’\óÿ®û/eaß2gšPÔ×'Æÿ2äÿ|ö÷»š8ri—áí9"÷^Õ¹ûدìK¤4Ȥ ’¬R›8—9o8/ZÂ*î³äqÎhø¿þžlö 8=ëq{ fÚh›FO(X~‡ŸÇ£×ã ¯63@ÿd¨ ,$·m¤ÜÞ‡:xRê…Ødªq€º *ÒÕYßîö+CäûÀ’b}g^9á «2¢EËGˆiÖaüžh­¿6 ÌÓ¸{81þ!ÿç‹ÿù‹ýMoG,î8›}üûý›ÀöXÉ¿˜äÓ¸¾)£—° 6£öþc°Ô¥ÂÄ}A¤)úëݾ©%¥lš ¥9^mjøçT ¥©Km6hÀÍ^DvÉc×=î´´FL lù…ÔÄ^c‚Ø× áîaÔ@È»gXµ¿¥XhÇ7ŒÃ4…g ´>‘a69”Ih»cý$ü÷Ó,~w1 jÛÕ |1üyPknþj8$Œý}üÌ ×?ˆ¿Ëèz;ïwÁëøÃá ÷$‹À¤øB…“ΉÿmùËÌ| ¨ø3U¨6Ù=rªÿ57²? ^Åy€à¯^.P‡ÿê ÿ¬¹d¶©! Ïƒ>dªÒT†M<5þ— ÿg‹ÿ¿uø·=€38GŬ,K5€èŒX 6a‹´VRü“Ì` ‰atoãfµß’§ÏÜ+ !½iøÑ=ìÇ™ä hôã!ÍŽFv’ˆuêž$0HO8˜¡Ðø/›Öw÷ª‰ó¡sQ5|·~v{ì"Íœwí'ÁšÅg! ¨(”VÀÐß–=òŒì¼cè§‘÷tx-ûRú8`°^=éÔ4ö(¹“ËN·i`V>Ê¢1Ñç N kÙ@?ÿ_ûÅÌ´ƒ:üû/†8˜#¯Ö%2á!] ÿíûøWß%Å¿y hÞSEçÞ½ðÈiðøÓäÞ¬ àLø_¥=v ÌKþ¡›†V(t€à’š|ý‘?2âÜþÇ¿þ¯åÿYß!þ¼ Ï ,W5ÆÁ®2·ü`ï äõ©ñ¿ù?—ýÿöæ>öÒi/Á?9Ò¶ã“€­HµØW¿4B *ƒ¿]Äï³£- @\Ÿ«òº†}q¿²Û_ée*¦TzBšòBÌD¶RZýMާݘ£´Ä¶µãÌR˜ H›¸›Ûš‘ÀýirÌÓ…ghÍĪq óâl¬€)l®w#‰tŸK—ÙODÇ0 ‰eϸ‹r€Ä(~9¸¯G»Ó~ÀËét›f`Œ?¸‰Æ 0—sÑÖ®O¿ßϺṳ́›{øûÅðß<ù4ìñ°â(+\Šëë—wñ£àŸõ×¥o÷ó"õÿ&þîÖÜ€þ«K›Å³à¿þN9[“?oB¬øÏÓïÜ•—°«æ·túAqBŒ?z ‘¦_ÿ—À~Xþ«M¯ø«Ëã®(ûÐO-ú/Ñ>E¿?5þ ÿÿç`£-°dRxœä}<–Ý¿"¤Œ’-e¥¬¢a–QJʪì½÷³îgðØ{$²e„„$‰$EvÉ*22#BÊþ?Ëê}ë×ûÿxóïÿž·ç¾Ï¹ï3¾÷u]ßë:ç<ˆ€I®.(oøÕýûÈŽFý8ûIæ?O0àWFtm)6q“pÐÃä±äIþh¾­áqn q޶ë.%õ·Yn“ôJ±>ï)zåþ¥µT=.çƒ 5¯ºxÚ%žYн”±᛺èÚÛm‘eÉÐ ÜéFUW»ÙE†(ÛÀ7mãDÝ="^¬åôv꽎ླ4¤¦-°"^ÎÚêv¡EV:zËðkû™ŒÔ­K7U¿Y@±ïðçÎ!#ƒ™en»ï "±1§£ß¿ ”DI*—u_{Ò˜½ûX€î6ä™bÞA6É¢êwX¢¬ÏÖèÇ«ð‰¿L`¦|®ÆL÷š‹V5ñuýùܤºZÑS“ÀgŸ<–‹ Úúðä%"ô­§}Ï….ÏJ XB‹‰ÛŸ|Ù>\yiîLšÔèëñ->;_­u¨•uÒh›&íé‚*yÚ;y½jƒB¯…Ϻ^0²“º''Ä©nR¾"Ü›Œ¾V¼óQšÒsËSÍûkÙn D×°wñJŽº÷šfæeåm$#K)JI¾ó:aQñÖõ„rRƒXZ’áõx9Øãlµ»ì$ÚÆwÒ…x“LOX &sµÂ¢7ï®êÚÙ½ù¦Â‹i•­ÍLo˜§Û®” ‰MßêS3”hx)¾<\}€ò¯Ï³+C£^9‡¯Ó<—~zSÇEˆ]‚…cœ ¬ööñ+I® [ÏÑHÿËøû>Îå©mýB5ÔÿþCžú}Ûâ‡ÞY™ÑiÄþžÏÆŸˆdG&k¼,}({áóˆ±ó9{©B­#‰[¸ +ëL?= °Lô.ÔOߪ»[5{x˶$Ç€ŸàOw­Ó¶¶ZÈÊÞüíV3b¾§Tªb¼•<”˜ #M=Ä™mÎí’¬ ÌÙ¼éÉv ²ëŽ|¡?ÿŸƒ“__ƒ î½½ûåã©Ï·BtÌð4ÒØàAÙÔùÙ«;"måÜQtÿµëI#‹’5í]‡_lfþ²·t¿›úQËîèG éŠN.G6‚‡P†%œg8Š£î;ó0Ô#œ?;Ÿ”dh Dz~pŽûë½—>~owLèÍ3¨;¢˜…^nz3Á!vŸm½©ƒ^¬Èô.ê­%±ð×y/hqÓæl»½mÄþé§S*:ê· öFÊRœ¤Ç@þg7m¯B&;¨Ïr—Àï×î7{PùaÉsÏîä%ø³ÛIÄÔÅ2°R"¥9×Ü—*4Š{¸x4Ÿú‰¥\¬˜‘Ï4Û1 ½©Æ?¶EŸ‚’µr²Võk —Âæ«Ïwj}°ÛôЉª)ñ®0#YšRiÊž©a•§).þ6Â2ÄÅ9½ôeWÏ’ÿÛøg§ždŸ“?2v”-LÏ›dsB5‘¯Á[­è$£? ÿOŒ_ÏAÂ/ &ÑÌ'D^Ê™RQZìW‹Ï¨ÈVTQ®xûà••ž,m›cm¯ˆˆmiÐM–„àŸàÿš|‚ü½Á¨™ùsïÖ¹scšo‰ÊÃìÄ_£:‚œ~t£Kh`ŽÎuL•µÀ¹uá@—`óÏðO{×¶[b™ÂžƒAqÉR=ªíL¥OžC¯®Áÿ 3 ª[ù´o®Pm(zcðE©Ú^.5­ŠfþÒkÕ9™`Óm>ÜqéEäÆÝIºfN¾×*ÎsYÝ}pÚßÐõÐË+06†|’¾,ÿÝÝPñ^V"Ñêi’ÝóL}á}3Ï^É:-Däºt$xk¦]¼Ë‹s‘ß^|Ísz[ÒÝ¡spWØV—Ï"’ÌT WTúʼùFŠo¾nmÙ¿PÁdɶíàNÙÇ'´¹âÓ»‡:÷%ú܈åi½gqO¡$’iZoü×WþY^þsùß Ü äáµ15ÿîu…¸{üh”aÄÉÁÿEúç bºM%â}B÷¦—¡ ®,yˆç÷÷© TÜ ×¨5ÜŽÓ®-y^{½Ê”’]‹‘•ÂõAÈàibøÓ m”žû‹úOGüçhã6±Ýz‚>¥öÁ9@^ÊHúî§Ïc轩§,»ßp“×Õ(V-ô¢l«…È[\bÑ`Û-Òr3ÄýyÝÄ·š›«ªO³"fÍ?ùÞfyr…–"„=Tmêæpút©c¾XÖÙ‹õgÆá¡|JQ´ õäæÏßb|œUN2ï8è*°-4½*ïA\»Ù‹Ó]ŸÄL\ÈgLU#ÜúcãLr½ãí³‚¢>2…úäÜÞϱéÖÅ êçžÖH6Âsé¡&) ]BDâüГÒS_ɲnpÎXÈG»@Ý!ðWÇ †tZ "ÏÍûúžåB3_OåSt˜5 ÷޽9]}œ ‡NÉ=óóë eˆ–L¢L—ºŸøX†ïîÖxžÁrª,ê :&„‡¬J͆§šÑ³Ù|»<Ä} À0Ë2ùФÛ×gî'¡!I‹þ4êÃêɈ9WÝ9¼oTÌtþQ|cÓÑ„Âp wâÊ΋î/²j=Yg(Ù"$>§íA– éÊ×ËSaÿÈô”›Jø¹¹«UõìÝ,Ìú2êá·„fæÞ4Ïò8©q+–/WúÝÿ}ü)Ïwɽ’LÕóUÞéÌRr´‡Û˜.ªñÃÿ1Ý.fs{9õêŽ{¬¥þ³PÎæÄù>Í©¡;H¦}žßÊZôçkÂF·¢“,{ÈÄCzí<õš‹Ž_ËþÇø{ZnF\E…½9šn¶köÖ¦~æMf$­Rüßjw}»XH5ÜO’ù!{æÐ-¹÷aǼ§ë’ïÆ$ÿ ŸFÏS[c¸*^î÷j)ÞÙ:K¯àbÙÿ~ þÏåR›ž¢‰ÜX>^ú˜²!ø›§9³î¾”"<é-U^yúìÙ&}™ÆS5ɉ[¼#Ÿu‹´•Ê$¾Nº”†*³"©ë¹hë"²~½èDb—ƒ–£sHí¿ kþö—OÆ•åFy¹›|é Ø//Pö œ»ñ9š×6Pû`š‰ÄƒoêÞÛ¯Õ'å«8û–,þuº®ã™o—ó¤Ø!ŸÀ/>ó°ør8ÍÒè™\’]éC¿Ä[»Ï8Ã<ŠI=[íîu]p8U«0ë„°R»®;þë+ÿþ±üK¬§ùùåvüÿÿþ؆vÿAÞ:Ïü"XUlÓÉ,À’/;î¹Öyî\z~ ˜c.Ò1ñI÷جï¤;éC L?Ÿ¥·<)çÉ´ÇqO#|'µáÖLCªj[JÈ*h竦Ü!jÒt·ó³, cžƒîµðÜÀ.€eBÄ |§YMùeÞSíû6ÇÎÊä¤:$>Ê‹¾$í<k»úâ3LpS=­÷AWÑ`¾+¤§oË :N¯ù”Äçµaú®¨vh"½Ë¥=¯ª¿^¢o–Î)Ÿo S°k9þA)*Î8Š-ž‚H’§$ Nt×ÚýËàÃæâu[ ç¦÷ùrÓ Ö•mžEFfÉø;.Ú“ÄÚ(­ê5ɾàë!¨ñ€«"£<Ó¸Èï‹åjÀdÙŒ"QƒŽe‹=’ÕÕ¶ìEOÔ–¯TN()·ä¶|4Ô[u…&ªæÔ™{$ý£¼¯”êÙ$g…{ÛY²©-æµ:J[æw´B&!nåTùÖw®Œû³ Ü?=9غOjðÅ7væ^#®ó‚g9/ŽøæDÕ‘× žµAV(¡_ö˜·±[ìO”u½Ûã´hšX:9ÇBÇÄmÑÔvéLKr§Á(ä”lw*o¢ìk.ótÙKŽºùw—«›G¢)L‡®5L\üj=Ô Á–rÇÃÿ¬×HÌʲ6Ýδٮ÷SR”í|‰œ¿^súlêTÈɰX—~“Š@ü,ÍôŸ‡ÿ–/ÿÞ®¬È,}ãÍiUÓ1õœõ*Q¬Ç€ìJºÍñdMuVê_k…8FïïÊ­š·0i—N:Z÷t(ý¤FW¬³@êôŽ|EKÝobPýg¿ê„¤¡f_7Fgj˜äÙê›IÛs\õÍ7sƢ㡻úË{ÝïùQF›²dñIbjºh>îÁ~Ó"­H n¡´h»a€žÊÑ1ã³Ù‡ý„Öÿõ•êæOÿPþÖÕüüjr{¡7¤â I0ýƒ@ÿ:Ïüc0¢Íã9ÿ–(kz¸͕TVôL}SósÉäýæ‡wFXŠûr¶½zÒÞx0ôÙ?f¦X´Î~1 TX¸¬?¤ó¸¢]È×ËþÆñíNàtÐì3p+ÇF —Þ5B[Ø:úúi˜r¬ÑâXç‘êYôΈÃEŽ ýŠª¯¼3DïBí$Uÿ ƬÐÄ(Àl]õÚl5Úw‘: õ}ñDüÔå÷Û»_ñ8s dÜר{ö=â9rÿÝnÏ€êN¯i˜È›w¿«âF&í9'9õ%•BÀÑ8б9T,$Hì\Ø:£nñ”XK aÝœÊ>òàuä¥Mwžïñ˜ôfð}‡óÍÓ~>Š —ˆ¥¤[ö ^FkY?FGìQ#·Ïjwà6hC8îå{ m]B¹ó¦Ë¨ owîˢĢ› ·ßÏQ†Ðµ³oÙ•¬DÇ`~|Š„Ìr„Oçù¡³ÚIb«È½oæR…Þ™®'+ IHI~¥°zò¨B”õ"màÙlÉqʨ„¤Yˆ±¥b¾\3—EôÇ጖ý®5ºçM»ÞÒˆ#óÞªÆÉÎ(\q¹E¹ÿ•òËió¯MŸUP£×¥:òô/ 'ÏM—Wë†Ï µïÿøÆ±·qPúvës2Éú8@ïl–FY¢fò:epØ{ä’ÌÀPÇSó*íôppŽè‹ßƒ?C[Uy>8ý𤌯è…­‡ÿ@üGJ†‰eo*^õ+vè-ˆiuJ8Hnì‘DÆ»)WùˆœðÕ×)ÃA;oÚ?þ`A{¡è‹9Ñ¥±˜NÓ¨{l?À¿¸©³ùA˜²TЃ’gqç “_¨ø¤X M× dõì ¿ÇT ‘Oí~ˆ…©Ü¬mŽØ¨î‰ŸánŸä7ššÝ1Cd“[Š *µÈBí)È«ƒ¼×âo׳`á*q?[dl#ð?[-áÓù‘Þã‰Ü¿È)ÐÝ#|›}µ@S€±æ¶óW|à ;õ¯¡ãƒ§…K8œí°í TQ7Ž¡ó¼ OyìZÆtFH¢š "ÂfDœv>hpR`°_Ô°kóßZ~m8žÞ(Ï.0ùìVÆæg6)÷J"vETŸÈžŸ{Éȶ=¬0I>k&îÕ'zý©k$…L¹îeÕe²*#]:5˜òROôI‹×~µòò74dâÐÏTºêyýiÂNºuǽåèÓ?’Íuµ>¿˜Üœ~Qï†%¨åñ·‘þõžø§ C¯lqÆ'°ä²Á™ÖQPä}‡U™•“"­å|°ù“‘‡Éôzóã A‘wR|ˆqô9òH¸~ }ôs,_x¥­)%|ð¥²ìã{¾ÅU¹]nª7Çáo)¦Œ/“œQgŒ9:Lel³²LS¼«>°ÿt{æhy®žT*Ä(ÓÑU,|èî„ÆûÏo×·ù1×^U=«+Ï4ÁUVìoú›ð¬ÅfÅ"n{ûôÑ•"þ⯺Ñé°ð·<7"3×à±aýPoó©)Dã”èö'þÖ\·êSç¢ëéïjÁIÐ%ý"ÜŠ&ƒ›Ü€€™àï@‘KR»Óöê^òÏÛ²Mw²n_ž¡r‘*q95Ñ"¤.D)–Vÿ&¦õ+ÏgJ.è@zäOñ¯#ko÷ÿrýI[Ü6{PøU1ñbŽ@•úkð'=xµº­–9*pð/CjÔå«• m‹ñsI7¾ìvÜÛ ¤Ð!P<Úc•Š¼Æ™ûìÝ Ëú-ªyŸ"$£‚½…,Y˜jhôKå;-š1ت7n|=éñ­W%‰GŸßž8/âF=SÒÔhx ^ðX“'3Eô4ùÞ^©Õ\׈â±A)5k’‰¡J^¹JÌ哯«¾w<^j?Ît¿ôd.u:\6/׿ ?Ùåûi…,~a!f`¶†”bóÖ28ñ‘õǽ埧ýÉÿFÄÿaöPŸÄÿM7ˆ‡ûßYæõžÀXö²ÀIð”+q¨‘¤c»§wÙx¦ Ý3ã*fó\ðýóàO/ÜZúEâ›ÚRe¬‘wøÏùiö–½Ê;©qÒ–™.3gBÂ(ËÇuz×e‹¶™QjF›¹,*ÙðÃÇ«QŸ }nÅ ¢ˆæak°:ש®í¿÷zÊ£AúQ¡£|3®ï!ÅÅRÚ—b÷Ó°FŽWîÔ‚GNÒäIì^pµnó5mVÒ\wæÇåB'ÑœWcWýõ^È_}Ô“Q!«7}=àk´"‰càÛÔÑ{%;#¨fnÞ8š´_ìæ“EÇJÊtå­ 6*¹S N~í‚|û½7M5Ès.Ü»(sýb›w¼ÔãíyaÙMÃ-ù´ÂvI/õ‹‡±;cj½xZÃ:¾…ÛU· ­tM]ò¦êµ½¢”*ü$E™D+c~ ˆßѽjøJcƒR¢|s§{TW’ñ•Ä:2¾O(îM5Ð gQ6“–~š“ +}NqÔF[lHì(\6Å4ðVÁýó~¡äNÍiÒÜ™“å#E·…?„}5±‹Ë]h—á à¼ÄR&¬>!Æ#€æW¿UÓJÇ’Tǧ¿÷¹‰³|“K¶Ñ—Ïoh_nçåÐÑ{ÌvÙ¤Î@*v¯¾-Ô©–áiï§)‘õN«ó~ËdâÎ’ÌýÔ¾EÅ^8Z¦Ç*7~HŽeóÛð¯¸;o;­hCVÙy÷߈Dÿë€îô©Nv·áÀ™Ÿ”PÇ.€>¦˜äf×çÒÉý†vgã |?š)NQÙüfïnóã-Çsk“ùïaÞ,›5¦ó·ø1f-|9(Ròâõ#ò„$‰è,;ásýÄÄÉ—µx“²Ž)ÖAĹ5¼¿ˆ¥“Ìw}¼;“3|Áóü§ø«Š&”ßÊ d ½Sxò„ÒÇ.Ù1}ZŽ¶ÇžŽkðn®S«U §Ûü…4’»á»¡[ô@#–f(ö1¨üæ×C.ã'Ý7¥Ë#Uhvúë9í*¡‘¸ £ßÇBeRÕw{Ñ•Kô›'QÄ¥³³m§ù¬Ñ ´¾¤QžßšL{™*ˆÆ-É@ÞÅÒÇ@Ø>ÏÈ”‰Þ”GÙkd!X¹W£ *ã4g‹á °Þ.hK~µÐ•ÐümÉR©ÇóË…NPÞi6½çéq/]4=¾”ïuÔ9§õgw í;mÁºí I,Ëüúã¿ÞòäÞ«"ÿ©ëk|~)9»ºûl@µœÀ®€Çß±žõžøg ÷Æf?£þˆÌ¦<<bLB8gÜÄm…´ÚGhÞqÔ䟓عx¿%=s/*ŠŽžˆ·•o?#°>†3áÝ`Dzέ/'×úéxEêq' A3«&Tߣÿ†F85í#¿Ý\“þHSwÛYråÍ›,“ˆlvëXHC÷f)¼Gî%Ë_¸ËI<}~áÀVêí瑞³pê 5ŠëçîF=uæØOV€Î«w½Ý˽÷邵r¾Ü›=e·(Ëß„kSIë~þšJïvy²åU¼”äé-LñõZ…0û«%ŸŒCȽŲ!gú…„Â'ªϵ Ié¸ ÅîÙ®_ÜlÙÜSÏÏ}À9 »ÄjßâdŒã\óvFâAèý¾‰O~2£±‡îU²•Š<Ž¢ÛN÷樘”09^½7î2çWƒü´¨04AÖ»(ÖÕ(wâÃûƒ¢‡›.Ž‘‡èží=sáùØõó=»S"ø˜†r+4·¦RÍP H±4ó…ó‹†&öu¾Ü^0‘|Ö;°Š/ IíÅ—o4I9ª¾%ú¶Ž¥ÑÑzqû†ÅΦݗžj€R©,bÛ]¹ÏÜôÉú`žâg»¥æÎhÉ-Á›²¯¶0ж_`aÏhÐ]бÙÒSîvì¹;ÊR¼¾á§ãhëž] û`ä=·g`ûä6MÖN?0BäjWéjVÿFü“˜÷$úeJÖ\¼øgâ?M ýq?ØÄÒvaL³ðÈÅaA#ïÚéë"Ÿn4s«]È48¶Çòëá"Ò´ízß…N«´ß"JbàBKg»ÿ;üoL :¨p=5aZÈÉAH KäˆË @»×ù¹ÕÝEnmüt¸w@â³Ý3#3oƒ|&»áóá‹?Åßý„b°Æke£ó;Ê¿2z 7¿£Ê¼¨yHx þrÎ_Ô/ÿ~ü¥v:ä4í½TíÅ\ïôj/g‡ûÛlÊæÎÔýW>æžÚl+ò¼†Ì»%ì{ =²iùð 2Ðõ~~í`ÓÞô‹—ÁÍ´-â9vß”rN9‘(*y?¯Ø'búâ1ÕùZkúv†–ó%Vl7#ÅÕŸ¤[ø,µºi‰}’>/£ö‚é[Õ¸÷~é¹€ ¶Qfu~Ê‘ˆeŽãS,w»-.3r´ï)µ$¥üæ{¬§æÌBÞ®™›â÷ùÓQ9¾ç)/öR÷ý øo¬ü¯¯íù•±üþ {ÿ¾O?Xƒ ×y)ä/ÐsÚ'g°ÓN(öãèö/…ŸÝ\é´X løC>A2›Ûîv<£©!óêýbœ£ÞžäAbt p¨ØàÉ›ÆþK‘ v$÷Ü-E«”å³ßØâAÄÒvÊ×B;¤Æ•èùU ÀöJ(‡êE À•wÿå–ð+îö¬ ÁqÊW“ó5ûübø>$±¤<û´Uà6÷a™fÌŸMsU5’ ìRÇ2k gä¢w{¥lÓ´xúþ8ÑRñ®å3R®Õ CwÆ*Oï†?|R-œ¶Ð ZÜÂijXY-úí€iò¢ÆÖinöº·Ç=bõ£­D®*'¼HöMÞÏ0ëkqháM×á©)*ߨØ/’\ºûwŸ+qj&†œu¸Ú©Urÿp“âøÇ»Wô[ï²Ø^c žºî&d1¥É¼ßï@ªG[çgºÆ›»FÉßÜRÓù¸#8‹ãEᣫQ§U-ÜYËi  %ÏEБ[¤i H¨&*1S‰ö"nïfŽæ4ìxˮ϶=?Bõ9ú&cªJcJ‚xÕø€èЧyz“ÝïiÙ§h_ÄÄN]¿Û0ã?w Ü !yxGAÁ¿¯–æ2£VYg¿9­ ›¥èW+³T†Å÷ð­ä^¯öD«ä‘¹~zôèjµb½gàp "[$IÀä¥b‹z›ùÎS~è0Ú`š¡<×ëï8zï_Ò²¥´¤ÿ­ø§õu›¡zOÙÿgâßò:lØ‘˜Ñ§àImsi?C¹rpCô¾âÜùãR4ÉM{u'ûá'K$ôº-Îżª·'64¬O¤×úŠ[@F ArRìïð?CÓéÚô„ª¦w‘VYëM½=뻊Šìþrš7æåmÛ¹¦A}Õl,Qœ£Í$Ȳm‚²g³ŠYå£Ùƒ©ìÚû8 Y<Õè׉Ö%ßW×Ѷù‘>Ç~?þȨ{¾ÛÄâ”BCõï‹r–”‡˜¤UõËÕ$Vk2Èîl±0†uÏ"7>t)Hf~Ãn-c¤†(Î|¾ðyÞ¦21e—ý&íûÎïªÜ%Ú¬…¯©/βžgƒÅë?2;\vøË>Õ 5 ½Øô·g˜j¬+ŠÉÓÓµ'ä]wv‰ÜZŸt!)jÓàìE¯BåâÓ»>ì?˱ëRŠ(Ÿ‰‚ñ&Š{ïPB‡·yÖïš;«]Ù¼O±&Ñ—ÆvRß“µù‹ß¿€ÿ†Ê¿èúšž_IŽ ôdïß÷éï—€užø'àÜ›r™£ÎV÷®}¢¡opöÌ e€½?gël1Ï~Ý¡ÙÌ¡‡N¦bۋͱ× Ž9Ä<á:~çÉií Ë±¡”‰¡Ív)4ì´l¯º\ ›e¹2•ÊbÎ,‚öšqœ ¿¢È•2WHÿzaÖÿÁ·°tϧ&ÛBÏŠ÷É¥µ+™2òf=è•ú*aíòØÿic^Z˜Ð§¹ñ":wtîñ$"KÓƒ}{þñ¯Ó“ Ó¹ëò“ÍÑo<vêO ˜A¦›>¹Ø£ÓÊ=®fæžO>óჀ«cþ&‘¬1ªÃ1Çcƒ7¿¡¡¾µ HnUÿ ñ=ê¶o²óæ.oCã{ÉÕ¬Îö·1xy̤h}œˆ=QÆ6¾õÝéÙ^­òté?ËÜqØt”ã•n½îÞ·RÇ]Î4ßÚzÒh„ÿ`z3\êœ2¢šŸãÝÀ)±›ä+Rºv†>-—¯µ xù‘uü]ôâk À¯Ï+í¢$89<M\øœ’OÁG±O©~&ù¼ Sü˜ú¡ ýgëhbjz.ÜÒŒm‹V3-Ó’´È~ B@û]Ÿ¿\%%ðfNõàeÏÇéÃF§;Þ³2Q<¥¹±Ë¹&„áDs.ÕžÆËÌÔºeºñ’݉WYž£vmþÆOìÚ=¶o›uѸHÇC‡©óÖôÙ J[Ù9>Ú(Ͼ&ô{ññ%ú$ÂýCñ¼Ëš××qâQÑx»Ðs Á ½ÓóbÂD¸ÐqÎb 9xß)ô!þÔJ—0^—ÏI¥­Gv{UVœf„÷/Ïò¢|¨¿ýÿL£ybs@äî¤'›EÇeM¿T?GypR¿yÊ3Ru2U1~k%Óð~µÅcž›å“Š?l\0G_Ü>ñÅc;Ùü(\p¨iº¦ÛFÖr-þÇXõîÿvüG“I)-lŸ¼ç¾)HåIkhj(œ$ž×Ì’¸ Þ{£ð”ÊV Ôéw1­î4DYF{‘϶*U\*ð´ÕAˆ–ù.Çâ–Ž¨+=ôn¾úÇ šª²øzǼêÛff#xÏ>ûÅmþü÷,?/*çØ›šR0Wù’;/¤jæG‚A,*Ž'¤užlWÞ¢³SmÇÓé–½fgœÐ›„¦v¾Eæn?â{°¥ÚKL¿1ðÎ3°f»¾qœªÔöÓq:{…Dÿü×]þ¯²þªü_[gÓó¿ÈþßÙû÷}‚¸Bÿº `Ýgþ/N$‰d1:qkô³ã+Jçò8¿…ð |RÌV8WžvˆG‘)бKWEá9Ý×HrÃZkM{ ûMOàÞ‡È/ïªV`p¼FÎqFœFypóTk4¥•Ž(]%½j Ü•ª${*8§°UÀ&PÚ%p³+ðîñ®·Ï’’?üXjþy7G8ø3𶉹nXŽAú¢¼Q¾g¼| BNŽrIYdœÇ‘4“Ï !ÂNÛ÷/~È,R­z{ƒ…ñlyU—5XEã$¸ôÔQI>opü›Ú$[¶y g>ÙøÅPÁúm<^×îþ{xÊ-Œ›_=uë¹'ÀŒ,%~LÏ$ÖDAñéÙWÄ]’£w/k¤^/b“5ª£©<É®Cœ©Gn DìK¬9{^°>`V}mö5„Ÿf¨‹öóÓ`Þ&á9 Ïxë'q4$Í¢IxúØÅªjŽ©‡#d£ó;¦¾´¦ˆ† Ë0ÆH½!ß–åRãÎhû€XÐÝÂjðA¾³ßXæì¤í“ñmñZ>’ ÍÑýh*k‡>ç¢Æn&Ux…?Q¢4ñc¥£ÎÙŒ zðýV~¡§KZ  ¹í}ˆ}œïÏ¢œžˆ†¹×Þï8ø±òùfÝcÚÎ[’}Œ˜ÄÑûÎ%1„4h6(òdû]”}>u’g׿R¯óÁêt{¨…å/†ýnü[u­s{þPüz3Ž+†3BDBSŸ•PírXBøÚÈóσçù¾è{ß''ݵ˜¯Âš,U*Ëö²Ÿ ,»Ã×$uÇç|™Ã…kî=ežæ0\Èû7ð_wù×rùeù_gÃó Éò_Úû÷—r¾ÿJ`(µÞ„è— €¦B°s“ý]ö׌”W\M Σìj=]ô·}J¾É”8¿±é?êÓ8håäÞå]©u[O/.ê%(Ê€Œîê‹™Ýïõƺ:.E=?v)’þ5_PB¢¸ ï®"ç„HÎ/'Ç/4d|ûíH\"*¨²ç?±Ò”¦0¥Û´¡™CÅe-ôûä«xæªkŸ°nRe+Sœþj´-‹xGÆŽ'<µ½oBTƒo£Q}ˆ´—9ÍÅ;<Í’c4¯Nº=ÔtAwT4ýʵm]Y¾:äMþº–—Ÿ°“_¾eÖ&NUÂÊmà•E‘ç '_n`ß‹ë’vs²…:Y~±"¥žeÝz¡(£ÐKF0Åêõ§±ãî—Ž÷vl.|!]¸£µ½²Ö6Ž˜[$>˜˜Qò18÷²Ø¼‚Ÿn§ýÛMä¦|bÙÕ™‡‡´ù>šr"jêÓvjž™;­#øÝÕ" _#5Õ(„\‘ÃêçgHîˆRm‹Œëš×OJ9J2ª;h°·Ûr‚è\Äö©­P5Ôõñ«cÆ“ –dŽ„qwøxÂÍk²¡Þz#ÓöÌû®{7Èæõï{G (Ã3sk>¶¨6:äH¿óâùr*Í{"-zöä²¢=ïOif¡·e‡×Åv‰÷×ß`Ï{zÞf¿÷x+‹O_ ÍÁ—Ñî¶n”Ý<Äù1Þ=*ƒ¡éóm“ÀrôÉïÇ?<üÅÿ”²ÎÝ£–øÅúMt‚=jZ¾IÜÕ=×á^5h?(é8Ýç>1:¸×˜RÛ—ÈoÒ¯­‰útöUƒÿby’O(±Æë9&0™Ö÷øÏ — ,fÜx' øPH«Ûy-­"n÷u6Å‚ï½ÇŸ˜{¶\á†×´Öݯ';ûÕö BÙOñæ²o—¿´Ì2Ï~t›`¤¿{¯Ái xïÎáµøóxþ~üå¾<2ª¯¿ÿÆûE%#C¹¢˜émΑ³—ˆ>¶éˆµshÜDë&Û¼Œ©¬5±ì¥à§ŸLùÈ»õ„ƒ­]sÇ ¢õnóä»mw¢f§ÜÑs0-o©»Ï"> ìQ‘MÓ«Jç×%­Gþ:ô`‚rík‡F&Å®‘°hi’¾Ô`›J¨†$GþÕªÜÉ!²ÓŠtš“ž¯|(û”´¹gžÜ ¡#ž~P`Ö“7sS¿¾JÀ¦UòE {èxÄè¿‚ÿÊÿ:žÿ™\ÿc{ÿ¾O07Òc­Ã¿þ3¿LX;ØS¨×¾æšÁbÖ &åÿúô¾aj&'n{sŠcJÀ>Ý_vRðN¡²¦Sä¡*à{jƒIo¦Y´ÉdÕY’¼t#ëŸvËîR\ü¤£vÕ3*„(;cæuñUIT•÷AÔgKú=)ÀæûCèÓB ÷ËÐìÓw¹ϘXµÝ´Í6—K„½ñs¥éha.jßu›ùm?ëQÏ’ác@ûð\£¦2ùé胒"h«A5;ˆàl´»ÀÈ—+[…øë]ÆÏu¾TU½Gÿ¡±ô§çouˆ„öŸJ¤l7!žƒZŠ8!#áάšaÇÿ…³J¥K×ÌÆ>'©I€Î-îùáîÜa7Sä…5=8ý¼Ÿê_@UDì[HMVK’M¾m`©t[;'n\1”´ ”£å¡ÀS×d[Y’¦Ï—;[õ°ŠNœ¬…¼·†ä°ÌŸ½C![*Jxù;†5‰JåQPª6g40>‚ ›¼uH£Œã«þt£«7•>sÛ®>õ½ðkPn¹>Ã4ïßÔHŒæ¸¡]ža¼/Ó¹j8xÐ:ÞøŠxȰaia(µkëf‰á˜y¥‰›qì}D­‚æíicW7ÝNî3Š»ÏWcÎðyðY8p:kz2äÔ²•Ï6—]Å4h3­Ìáw[¶, ½Om´Éï%ºSêžIzNKî[·ÏÞôô™‚·êaSZûv”Ñòsø6þÜʺë‹I}ÕcÍÙTDí×''‰©SP¿Üí ¡û«¡×Fߗʾ›4–¦'þ7ðß@ù§XoÃó?ÔöŸÛû÷}úëWƒë¾ ò ¯ÔVðÄ«[ÀV÷FÇÁóOù‹e¬C&æ.äÄÇqé1å‘;úëˆF 'Ü5_t ¾Ü?^ÉâU¿SÝRq#BVt3!ŸQ£t†3$.%Üëù`Ä]]´m‹USï¹ó’Q£©NîN·9v^U,@±¡hŸ†¸Ô@º\ê*Œ„Úˆ¶]zçÑáJb”T#‘W€Wæ†&x«°N%½€ëWßËGÚSàC^å™ÉÁ…‡î¾“°?ôBÌó»—Ý&E©Â³;¡·¤¬ZÍ-¬CBx5€]çb‹b‹i»Yä½|y‹õÒɦ쎔&óvûìÓ& q~£ßOv‘ÍšÑC¾”ÑÛíŽÉK¯J=Ï,¥¬¼dE­Èñ½%_ý4· ¾ïSxF¶Â?ùj¾@~K°XßU3ësd–w®D?S>@aLÁïèk‰|ïµøò¤îÀgáqÙƒ&ö)§ì»ææ)eÞëÜ/0kМes÷Ýöf|´©hjbmîíó#ÝÊþw^Íúñ ×wú4M«¾H8;ÔS/d#åê'!f‘hìÐ{ìüቑðt²¾É¬Øµ–Û“pýLͽj¬‰ñI‹KΰLCãHóÞË­o™ß ¹’Íøäà)Û®Ót^Eó͇¬»|¬Èyî*‘¢ycšN…su<*Ö¸/þM­åV=üb­#3‹¯ní&ïdt`½?Æ"ò¤0©µ[PRº„·îݘ¾ûßõ‘´.}™Ö ¾"êÓê»Yü˜ÚÒ ÉbʾO½É…y tÔ‹p;Ķ;]åLó›”*0÷L87Ÿ˱¸Ø07¨?zŠu÷ù°o¾¢BòA§®}•ƒ ŽÓ’3o~;þ6ð­Þ·…¤ þlšwg¢²“/¶>{ÅL[wØ9Ôkæ´•ªÚ¶ÙZ¨ QîpÈÙ=qñÓÛ¯¿ d>ù9¶¡N½´2›H¡Â^ U®¸,ŠÿdèH8³C×™5øŸ³¹X•eÏÚœT?ô N§Õ!=z]0uM<éƒÍüac5Û€½|aÛ  ›¶X¥ïuâÿ9þO2½²Ew Ò5º>œ18EšÃO}>´¡øãå¿“æ úæ^Ž£O”Š!ZïjfuÃæ’ £¯÷ÓÎWˆGg^¾93N²Û…ÚõVM`ÍGŽÒjj§âœkZ6v‹â¶ï³µßž©°¢»šÌºíLuˆLoM7uÕnGyï½Ý‘Rm!!wäÈ©Uo ˆêu…iDôO÷8Û†Å'æ=gkS_Owåü€k¼ °Êit^ ™JUÉ ŠTÒY¶°†©Wć·Èë‚y”-i¦óõ¢ßLÆB>ü;øo˜üÓ®·Ùùy;ü7÷þ}Ÿ``7¸Çª ÿ¿0ðkÀàæ6ÏÂèHéXs ¹»š[Ýþ_m'iSêBgü•<¡™ÙÙà±OÙžÜÁ6é즱à}ÙÞ›MFQ ‘¡Px'Ç{ÿS¦E@ù3PmCsc:ˆXÌQ¥ Æê~\AêƒJºÁŒ¸#À]‡Ú[ @ᕜÞiÀœÚà³àæ7Íîç[zc‘‚|‹¹<×û$Ÿ:\Uók€Þ)Mï‡v©/t ÇöRÔ>K~XñQóíÇóB×a§]¢4G·šÑÚ)Qî¸h•µÅ F²´±Èyxçr²‘ÎG©Þì,Ym>éçÍÎa¾Ûš>I˜›Û¢‚1ª¤Ád*çÎ^1†¸]óÊ»¶`x'qB[NNÑ›¿œwÂå(êsùƒ#íƒ\Î5Ýu‚c·7¿-T¨¨§qSg°‘âRk!öq§.aõÝ=ViÒÒ=¼û¸ÚqÇ]^­ÕŸc ù™Þ“ÑDZKÆéÉ?nÐ÷¢o¸í©²™1ÐtúA0ò¼p¯såÙwä»D%ž¼¿®{*êHtÙi) ï¢þ ¨jQLqt‹þpÿÍ–ÜÜCé­.<úŠ –šm¤úOå×]õL¬ˆåQ¦=AeKÎ<3½I5ß5œHœ¦’|üá‡ö€©Üy±yþ»jÓçD!=w%xàß²iùó9@iïyÕ{¸ñ¥36ç“þvüÕÃË'Ù‡ÎíTÿúâŸF̧;Æx'õ½g‡Oº‹,ï>…ÁIïÝĉGÝQå‡©Ü»ë• ì>‰GÑ_Ìè@ufDiW·…vj Ôy}2øP¢×/zFÍ}é¾ ý-òViåqý¹’ÍdOUjŸòèMÖÌ7x?¥qQÒÑG¨<ãÔ~«Ì^3fs„Öóñ≊ã?Ç?$b<ƒ›õ™\±€X;ŠF(üpxÛWœ/Jm$þKòo²ˆTÛµ×'û½xaÕÈ‹-Ÿøk&Ì¡Ç4¶ƒ·œ@L,0!¦òk‰™“ ÆœÃG$ç@Ò‘V™r’ÊZ/Ì  ð4¤ß·uJ2dlæ®<:wÓ0û£³W;=œ{Ì-Y³`Ïc±¢Ëz—yá.5¼(¨ÆW3w=ûí·Ò*i}óØóT 3»Ï§…[Þ6Û=TÈ4xÑzÂmwµº”÷«fœÚ¢§×T¯JüÌåÛ3£íýšýÿþ&ÿºënv~-aŒÓ¯MPÿÑéôò¿«÷×kûÇÿþsƒ"àp `~áæ @à aϱGìeÌ/ uG`²±=”‘îØû`pæp(æ3¦ þìwcs°£§6ƒÀEpÂAV`_O „aÛ²rÀa 86‚kåªæö€ÿµØ‡cضÜgL>êNx@¸ºTN(BÀ (ÄÊÖÜÐsspvÇöÓLo08¾K`$öW n`eñ=†B\ýÜ‘L0vv÷@`‡×@  Ø«p„ €- C"–°!tv¹Ó®~`©ü Å‚€½u©öåqÃþbà«JC±cÁÖ°‡”¾ÒÂs·ÔÿÃŽÃ¥±ØA,/åÀ`ˆ¥[``ÿŸáC˜ ÿ%DñøÃ–Åe5à˜óŸáÏ^ÁzåæÕøcqà Øþã/nþÖ@ÌX­ê&¾¹ 8±rŠy«1Í0À þÐ岄.až€Ç'˜¸săMx4œðb@q’‰yB-Øl(w V–1øcz„À0U#˜:A×ÿ—ÿ rÆÿæßÏŸttã o®b,©¬TÔûa³qŠ«°Z Fz¬* Å]ÄK þýļgÑ€¹Ù¸9pï!6j ‚Pˆ5vY×CÀ(䊦XÖÿ0Nà+aY»Ã`8¾|B —Ë,™€ðÿƒ)#ðï€ûàúý¿k&”#P¦_p¾JÂ0Šc™Þàe Š\Q_P°#ÔÓ§ä0ÈÕÓ+ªP¦‡P0 ‚"¡˜ #‰Ëµa±$÷kæ^þ•ÖªxŒäcU^¬äàû‡Ó kJC±°bôæõoãoçëþ×j Füqøƒ`H ÇfW®á¬'¬© ºJ§BÁNðŸàQþ0þP,HËð KÆ oí–_}þ7øcްïr€¿);…‚ vvcð‡¢°øãïÆÙPÜ _Æ×Õef€µÜüñfÇðZŽÃG9ðç b™àYt™àx æUÂá%x;‡®Œÿ%*, ¶ ´îøo¼ü{’~uyúŸŸ~ÊÖ{þ9€âÙ?‡þH ÀáËjCha8Ú ‡€`hAI¬p^¼ªÀØ]…¹¹ù"W<Ÿwµ„z¬qÿ-ßCÀîˆ5×pÊÇÅ{•î_Ý\.ö‚ÑpÃêøêÜ•Gá°ß¸€ÑaËìw£çæÿïSê‰ï`i>rÉøAq. ÈÞÃÓŽÓÍ0¨›;'û Lk1 ÓcºÀºêß@aÉùj¯iåFÀWéôetLlY,³\98bKˆÑ¸!ƒ pä¿¿“ïê!Â]­€?7O‚Ò\i5 ‹?|í# Àjb9xýÌècì†Ä™‘%Ü 0X#v¼ŠÿOzïïB„›¡ ‚m þ6ð 4‚PfÅÆü,þ+!Xq<þø`XEn>?Ü©«;r©Ì ÀÉ,ßVŒ5·0Žg.UJ ÜÍ}ÉñðÞ?€§üPôºã¿áò¿1kñÿ+î?.ý¬³ëøÕç­ƒ`EuÄ«5A@ìû‹iÌ»“~ì 9‡ÃÀ ÀmÃÆ—ðàBØ[Øg@î>Œh:!ÑÈ%½ƒ{¡nô{= àôŒû*'› á=à+j}Ùõ[6"o#àâŽ\Sd5A_Öÿ0|ÿ®j¼Ÿ±z¬–²a®>X‡IpÎ"†ór€5“Ä*aÃÔâjŒFÂñ †í»zÂá`ˆÇ(SŒ bÌŒQ HlK–\,Ÿ_ ÔQÄ)€‰Ò• Æé€ïÆ ›Ë ÄV€E‚tÿøÃVí5ˆÇˆ¿³ÖmÆâ_y.ÖoýάĄqÕA\mB~ˆ?†€AØY$Ü.Š…c­§·ú‡?Åÿ¯ ç»Âákñ_ª‚„o þÚß`ÍñþòŠûóÕA€û’ÃÚ58áá'ÞVBÿ+·@a8ü±F‹?l‰¥/9þ·sæÚüñvž`ü1e0¯â#¸{qÓ€#zýñßhù÷6"ýwÜlúY`£ €«;î5á¦ïþ^ àØ?§° ‚ ‘x鯕ÆûøÉ?lô ëÀ„L†›£/>pH@ÞÁâ¾&úû½áÙ•kPÐRTöýÛM(F˜†.žðï\D‚ÙXÒÿØp1þ18;C° %Ñ\È¿iæ+‰SšØ ಷ¿L–…ÿ»J CÝÜœü=p‚ºaI·Ö¨_€Àh!(æ§/!0ÞÁ°H¬jY`åÿ/®@pàüì°4NK*±’ÀÇ@‡÷4¿Ï%sŽ;:ÚÀÿHüQ8“YCV‡{ µb†eÍÝüÝ~„?¦›˜…ÂðøcüK¼ñÁ¼VpÄš©û¥Ð?¶‰?À¯u§Wß¼Úràé¡ÿ¿;dæïÃB¸} \‹Áø-Ñx« ÅÇÌ ¡<+–L:îfl°øc›‚ÁÇ–&Kà„hÀÊÿ`§á0¼Øcß\øš ŽöËA@œž`nnOärL0¶vòcX°Ï!ØF ŸwÂmûÀ1rbòõA­QâPüú¥ÕëÆ-—:{!–4õ²N^k°]¬uC¯¦ä¸œµúé—±=ÄÙ™5† q‡­¹´äBÐ¥µS—s$¬\ÍV¯À)(ÆòA¦x±Ø5JX*áŽQZØ…X3€]±õC” .¢·ò~¬(ÜtÞŠ+·âàna•ôò¸,_Ó&,ÆØ äoÂßÁ _ò±ÁfP¿?¨sËÍÀâ¿,Uø‚Ð5«ª`8ü‘?ÀÇ $óTÌÐØa™2¾e8~Åw‡Áÿâóýþ¸6üœ¬Š'`Ðàoø{»«Üüae1 .€B¡±qøã2p2¸z¥#Œ`ì¡,°³ëüWÄ÷üÂ?ÜLÀRüŽÿ ¼ÝLJ`Œ–9ÉêÄí_Àƒå#âÿø¶ÿ·ÒÀz~•Q,Í(a5 NÑ`…– pºVÔçU@ ±G70Â'šØ·myæwóš…@l0 +!.ÂlÔ ý±û·bGñk” /2FVVV­ò×þbœì¾¢üW+þý¥øÀ’ºÇ:«õ= 䱊;ÃV&ƒ¡`oB$„ DÔðŽÚr4€ lØÕ\k‚°˜ÛÜìÑ^(ü°bØ>c†ë‡@À˜ÁAaÍÎ)9ù"—œ3( AÐÒ«#,^íÏ­¨Ü¢kœ¶[mºðñ8b¥4VBqMvÿmø»yÜj¨)ñgâïâMx*GðõC6Xo|xu—°ø;xÿ=þ0$æFá€üPøç`#ºø•ùK^.As?Ǿ"ýki|-þËKë~?þPT¨;.ð¾t7¾a¸jð.7li±¾‰Øµmì:BÜ;Œ©uMècC,/ÀØW8ÁÚã ;¢þ8IÄ}‚ˆåñÀã7ñøÕ€`ÕMY5dŽ^ÿþ+ÿ±þï?çþãÒXÏÆÌ»Áð{A@‚€/Íîïátν‚x pB#L .ß , q\FXÃGÝÀNhìü Üͼ²÷ X“U¯-¡‰`Ip q‹ºV©ýÕ]\m Ø÷Ú}¥àJ‰åOÿoÙð`#zˆ•SpE/üÎB¹x-MöãØRà˜8a}éñ¾cßYüïB€¿<Ä ¹d¿åhþ_/bA à¦þ6I!¢ïÖð‡.M,/ÀGñœ©]:‡bŒïRÀ·ŽÑÅk°W6.Ýÿü7Vþ7Àÿÿ/ºÿØôƒÀú³¡_}">fŠ]˜Š9 ?"zKò ÆoüCPHlQ¼zÂ1jÂn`Ë^Ö0üÄ&ö•9øbª‚á+{¿¾×ÿÀêwveÖþ–Š-—\~Í—é.ÔáÿŽýÔÀŠÿ#8Y5‚ãC~øk®ÿ‹÷‡9¸¡0ÂÎŒsŠ$ÌG‚¸ÀáêIÈw[npìâìý÷ϘúPÈÙ£ 0..Æ™Àn^Šb—áœ1<=#l [é16ƒøÏ°5Ua5€ÃWƃß¼Æm€`BýVü=±‘O#òÅß)À?GpÁȵ,€ÿš~ðýþû‹#0~!v±N(‚°MŠßÙ½„-Á,,­üþ„µäßå|_36˜{~ï°ÚÝ_ñçW‘ì‚y\6ÿeO©#Kfy? nxpøãç€ÕËà«âÿXI#¸û8ËŽÃi¹!àæ¾Vx—¿ Àø7ðßPùßûÿ_4ÿÀÀºþ €Äp%Hàó Ô€‰ÆÝˆ!§XkŽß샓%Að“«ü BÔÕ:åd ½áñ#÷ï/-\Ú „/ûÎýûþ®¥\W GΗË,)ú•OØ%^ËÆ×n0µôøš `«}G7ù8·çœô%°,pø1ƒ!W7” Sa0#€›Ä®?ÆøQhŒæGa·`×€ÿŸö®l×m" ¿ñ\CKš'ö¬vœ¤§-U‘¸­D¹@B Áû1ÿ:ÿ8é‚Ô$::XЕűgæó¿/vc¦.epàùã¥Á¬ªÔÂ*Ñùêÿ÷“¦û‰ €Ròq<~äÕi¬ÿ²»/‚ÿ é¿iuqí‘‹ÿxÎðéÿÁ@l€º{ÊeíŸÜzK' ëýžõùL?{O}<8(.{qÍ?¹õÊ÷ýñ½ã)SÙWlIåŒaèºt\Xzf ö—ò~‹á_-ì Â"Ÿ¶¼ ÿ7ß)Ñ’>_ˆg>í¶ó¤IÁÄÂðÉnT%[¨’#€•‹av7ã‡u?g=ÐA >P>6Æì^`@RV€c£Z kohbzº0d-LPÑC>± ¯Žÿ[ÿòÁ⟧VCÁ0°M÷b¢’¶põhm SðKü!= ñçÞåƒO¹šûjÏ‹ çx7þÐC0ñ1Í.Þÿ7þçÉC¶ùk ÿñðÄáïº|HmÂ?Ó çÝH_äÛ¯×ç‰]DvMþEŠ G­€ô¬0ÌœÚ+.éÐûËà;ú¿¶ü?cþ>ºíT¸€µ"^âEØz›ÈDœ€Uû/÷ð6ìGc xsA/M<Ú‡e5°*š!±ÐîãŸÓ¶{™2І=Ÿa»…§Ç¸ËJ`­hx?løô4¹   ‹ò§þ_ø:Q–±>FúqéæÂA3Š™ˆ %¨›4& œ+õ»šn¸x¾¿ËÇ)óÑ}Q ú˜ ÍS&D!>iDêý@r+N b5¿Ï,. ¥ ‹¾*þOÛ§ÿþ°áoOC«ób dÍþ«}‹ÿ0æ2Ú€æ “(€-@¼Ëcä…˜Þ?»ötè©Bqcü ý/ñæ&ù‹-vuÉhç'üµù_ÈÖü—ç‘°/°·ø›4€$ïõÿWñ)µ€ø ˜‘.Ïwû‹à;ú¿üìâ?žj—X•;§*ùè²KÔzÝìáeœ€H^¡wóHÞBÌOæÿùÍnJ¡¡xîÿ!µ:¢…Ǹù2þ~¡%ðáà‹Q#‘ÝÝGl=^1¢3rwÜž³)ìjÄ>€«ÑØ…J¡¿)=äœ º{hLô @?øY»0¿–¶€U! “ˆ=×­Žª*dZ €>ƒMRX {  €†]¹ZËÑäÅÊ9£5‹ H¿vÍ–…Àׯÿã.¸U|˜øß¥¤ÍHÀÿäh¿Ì!`9¹Y=oð/’¿àia€.žÛéª æ*º—Eçð—è¾læÏ·ÄŸè†n>dó/Ìÿf"ç÷ëû7¶ùŸéX% þ´fѯ„Íÿ_øÿÕÅø£®I­ÿõ_ŽûápüoFÿWÆÿ›ÿ´*Ÿ~U>J¨ý£3]vƒç¦àAž J %׻ݮò éô pÀ4\â¼ ÊF@Ô ü³ÿÚÁ¥Üê8GÃù£îÏÉzô'xt—ÒÁ˜<[¨åú,j3ºæ«^NĶX¿´bZ¢ö5\L@þÌ ­¯¿(ôsó_óÃ" y,wÝú~-Aýf_¦ÁCˆÝ`w8pðR¡àÄ-A 0$_Mý®à‡q×dÖw¹)´¾6þÿ@ûTçW»‡ˆÿzÖ °úgÆ¿÷Æ«“i †nûÜâï§²€Éa7`XÛ"¼»€°w®B²Í<‡$G}l~I­˜½>þBÿ/ È’4ðLñøCÖü#þnÇäµ½±ÎFëH® iªiûåKeœäªà¯þ«pþžsþjj/„ÿ­èÿ_Ì#<;ÀÁSxœì½ 8UÝû>.2„ QBÉœÌ32†2W¤dÎ<œiŸsóL2“!T¦D2d(S !C†¨L3ùŸéúþ¯ëCo×ï]W¶sö^{íµ×½ï繟g­<`G‹#ØËgg¯øo-0wÒ ±ù Gþï/ðŸÕ9¬îèU §>vðä%KCÀÏÍ¥h²òþ{»K锎µš)uý^Ï£hÏ}jy#žMPwøêª òŒªr@p‡õ™ãI¼{e]ŠÞ6]-ò*6økøM'üƒ&^I¯\“•òÑÅOe.µX!{jÔdͧ@¹ô2­øÝŒ[tZ@±êùÂø“*#Þ®S g‘ê~nnß^^O8i )õøÀ•9ØÁ{øí*d¿èåZÏ=‹Rrš(£~—d’Jôœ0¡j\ø¥tU!%^•g bkv„Ê# ½5ËÁ}ýÙ®û©«ÞIÜiüï f:¨>‘,¹}@ú®Âo‡;¥vø&)‡-^ìשÆËì ã°Oàû©‹w3'V‰q‰ó›6µE[„}¡–y2â ™­Lè=}ô®Öð¸Íóªk{/õ½²Æƒ™&1@-¶à?)zÌ)ŽÀO„µ41ïñ ý@KwG[6‘¥]«[—{ǪêØÇ›ngâl-kóÁOˆÏFŸô«ü3þV&:=wTòT™Èè/ Kæ٘_Û_ÉøDøëðÿβOüj^û]äZ’¾ß® x©wׄ´›^Õ»ðJ„lNaçªZ§U“Œpd\¼O¨SÜRÆ©ôSÔyâŠ\räär_ÌÎÞI&×MX¹éyëde{ó;NZÉ,zÙ²:}}ÿ«µlÇZë~¢\˜Þz8vòR¾V[±¥ºe>~„X:*êBmÎg±ËJìtûý=Òk(²^A™H¤W›XJñ@dNç\'íYã=uj£¯¥(×EÈøéªZ Ûüÿ‰ÿç^矊»3<ð§.éÿ•q‡ <7F ñøßÌÿAHs÷?@™e²ž²}”­Å*åMv«Xùü«›×njxE]-p«0îñÐùÕˆÐ[ÒÂOÊ y'X”ˆÎ–pðB‰÷ àÓí|+'r¹)ÊÄW­ÏÈÿœ呾s7£Jñ/j›¿Þ[“Âäd|ŒÌ&\†œÏR_4l_dòãËØ›%Àm"V]c] œN·6Ëhp"¹l&…ÔUMõN¿p õözÖXÈ”aݳÚùT“I^§´µÖÌIõDöMåE¦1uû­£UܹOñÞeM–[–?šM•%O#nÎù€7™è²_]í|dëôÍÚ{K™¤Ò_z5® éô|ªóäÖë_]Ôå$iœï?IÐK/Y™vTøâ®4y9ï3]ãƒn©DÉRs×±¢£œÎË'îOjWlâÉêVÿÖ}àmÇã7’›ßgß”Ã5̇_Uý›áÏ(WºÊ:ÅÇ&Ž ~:j( cÈ)i<@¢C¡b2PAùœ¼×Yµ²B‚üž»¿…ÝcnÍ-£zRÜúîjzsû°]’gðìÊ;ªïø—u1‰/¼<ë£l¨H™5è8ùd—ÞCIx{¬Õ®G¦”0Ø¡J”&ì׋îŽaùgü/è¾»ôðƒ¬¦ÙðÁ4ÉŒâ“iÂÅlý{Å¿eþ*üàÿÚæ‹0®æúËAxÐ}Ö™žû‘ü6eÚ5Ší¤ ‡.ì‡ÊŸ=Çÿx¿„œ¾®ô¼¤ú¦Áû¬<ùkJV”NÜÿû ü\¤Ì|ª0Êa¢u°Ê'·î]óóڙ̮⳯[‚÷õ…‹Àšì­eŒÙC ÃÞÝñÜ@[;ÉÑLáë xyçù‹ÏŒ3%|eS”+–H ñÏ&ï •‹'q²<¯îZ¬m°'ý#m¢xpѨÈiÀ{ÐßJÔÓ9ýù”<Óд<û*ã§‚OukwQwZÛ¤}ýÄx|)*sâOïsµÉ@5Ú¢†½ >š ÏÍÕ8,ŽõE«=;ù0öëSžQ™#™Îpî-ïøÓ$«ÂµáMBE²oòÉ/œtL(½Íòm¡ã¡¯ÿ^÷O-ß¹ebišXë+_©rõîÓ×Ì¿oÐŒpSJ‰F%uö;< ßC ØrJsŽõü¦Á¥âåñ.ž/Ç^”ÓùÂ!ÊÍzëÖdsÔ G#û •åV¯$ÆdÜ®©ˆ†êÁÂäßnqîËõçg¨”ñkçÍew>L¥v”>Äîf½<Ï⋉Gɧ/Ý[Œ?6(êrHoÐûkÝì‘›o¹,#ß jÄ5Æ[rÂ_X6WY‰CŒógrKnˆš®ÄÑ®« ” €í£Žì¹µ¼ïÄ”zLP"eR\CEÿTÏà•¶ÔÝ)ø“çP&S×ZDv¹Ì¶²«Š8,rÇþÛòpë#ùÆ¿÷ Á} Úó|¨®†õÓß þCK1^ß4C^ëP—ÇŸ:8øôSдOÝãyމ˜Úgö`-æö½f¤Íižþù—øôÈ‹ ¯KŽé¾õ‰–Pnöp7½”>éyT3¾Óvé|§ÆþCQåú¹Ç¥GCâù)ô­_‹ï†*û°WÑJGFÍñ?%J×ßm7Ô›g-ëq<øö“:Áe0{Ø?ãoߘõ~ßÒ9È¥Æíé"5f»)ø{SÒ" *¿ÿ?ð¦MÜSøRè°íq‰8™n ˆë]Þ½‰6¬â'‰n$ ÈÓKÆëZõxûîV_C%éEÒ3XË ß´bkjÇ£ ôjâÖ8­¬´üx9Y–)œNl¿{f"oæi²–k¸AÎHfì}¨µ¥á×åTµ•D/ý½æÓ=ïWøŸp®Õ%v_Š´ò ë´qH8Ç×vJ­²ðõêÑbïÓ_2æü†=¤/"Úr¾y?â`g°OvÊéÞ&üÿ™ÿ÷Nçï‹«+2`'¯÷¯/0ø!þ÷3?çî…¹÷–sµŸÇå £,¸²¦ r·Pã7î¢ °=í5+®×B§5…èŠÇ¯eò©üví?™Â– žQ0ð“m*t0ZÌ|W>ž©Ø;júPž9¸¹DVIg j‰Â/¹Ø1æ@ïéœåÈ…C~iò“ ÙdAÎó< ålàÐÅÁ,ž—.SŸ*ø• ‘{,^ݳúœñÙò>ŸÁ½KìΙ²s|ú¹ÒËÅWa6ü’}TyºzKs¿÷íá´‰j²c·Ë|­³[¦‰w“Q ¸Ä˜›¥¯F¢'Q#fu\-=ÌüÆUW£‘Ù»s®¬ª]_%}¢·G­õneÞ1 +E¸;ˆ©á›«„…ÞÛ5¶,øtÎû‡jʧ/Æ¥ì†#9ç5›˜¯ èÏ”ÀÏå+IOìsÙݶ+±h`ô|Ã…¨Wwžß‘©6ˆ3‰ÓDpT )Ö-Úe¤F±i?€åˆ”áßFT°Ç¹&'NöõËI¤CÅž™d×¼Ud3Ð5{äNq÷õKJÕÓ9¶ßŠ´_^\ã^=³|fÎöXÆ·¢E‘ø&À[úÑ[®+;Ýäå’žãÝ^âÊJ¦C8—<9»Û ”•‰Þáu±@g©CS§¹)ž¹Êǘ !ý§ËÓ{›Š"† Ô=HWÇÄ©w=NÙ#ÿ&×QÛ:"N{‘2ï|~`ÓÎâO“—.Ý,ÉèÒû n:^–•;Pþ;áo㕟®(ȶ÷D…\‹ïác¯iB*=(&^ÅÆÎ¦í\5'x‚*îö‚ÒBD”膄Î`÷µÐçeÁQÒÇ‚¾êß/•}c¨ØeŸSiÒì×éA•uü_Õäy¤[ ·WÈU) 7‡·\:ØüZÔKš®ƒÌà‹Fû¾ = &ö+Ǿ3²ì:<eùüÏøL ¿…“®õòñ׿y?zèEk¾ô •ñdù_ÿŸùß¾»òÅhdJìü>%M…‘Óñ·Ë½OZ…Z¾é ‘i­‰Odó¥œPÿðô‰+O†Ÿ¹‰öHe£‚Kà±cèçk5$Œ9ßž;Ø[˜²<£äëÔ¾)N³úõRFÇîÄcno‡Ì˜§Óáés„ëÚ³-ÔKˆ>k¼ýá63`ö"ŽËAUyO~ܾOÉúˆ¦2:3þ×6±ªÏQIa£êï÷Ø~ —’¡üpŒ}Q§)w›ðÿ5ü'ûßûœ¿-ÀõójÿO¨;ØÃ» `[f~*§b«o¶dˆ¶±Ãûhdâ•UâOÂ>w>-÷ µ}|¿–YVßö:L2ݤ$¶Hõ‚¹Æ“êEQyŸÉ9Ùˆ÷c¾~©º†a‘EFîIt ¾™ÓÈð+t»”øŸÜ«u#Žf\\üªOq_Ii• “å^m\ý°³Þõ½Ñx¯«ø]ØÃvÿ|>–ºGïgžÒ¼×½'%J|ƒq˜xhMKÁAnÏdÌÉÎ.¼bV4BÝ;ÙÇ+â5¡¹¨Z~ö‘á-ªO.’°„¢¬ì!³6™^ËõS‡?yh=Š$úð–ˆÛ)EþZéÜù¦~Â|n’c}Ï/V¿uj‚DØ[Å&ÖÐàï!¥;« #ék¼ñü©ÓÙu¾×ZŠõ™;@*Š)ÞüfÇ+2N<{z}ç[H~¡¯èY=LËDç&MÐa/ÉÏ|º\I¯›G¤’2YªnP¶»Wt¡—§L£ûÓ;‚SŽé³‡¯êtfB ãMOÉO¾}hÛº2Óȼ>éd–II+ߕެ/¾Tq­TöIñ5n5ºHث犢NaSaó÷«‚¼¡yñnj¢Š2Ñ•Ròyš—ˆŽ¯e( `Çc§;|â£ið‹ Πú5d]P¹sø¸lQ…ªPÂ)ÎÉ•¤5™­{„Óqgñ?o«¬wuø¼³ÿœ¹}éa¨Ð{H>ïŒ·ÌTçBÛÊäøaà1$ß_B~ÏšÙ+YúÞgTíœÆÇaäóÞeÙa«½J#JVÄó :v‰%o¥ÙòWÊ’“ÞizLfÜüôQ xt«ç¡|p-¯…é‹·!ˆ{x«å'.4_4¹æÝ}ömŒ™ìú q§{×^â'†8¾]š’½Kœ•“ØùÏøsqJkÇÌÞod¸õöì dáùø…¸òî †Ç¿ÿ¿àDk>§ODè{KD—7¯è2yQüh yê]¹¸§“k#‹ã׿%•Ûó¬sîˆYŸ˜‰P©g’Ïíë”´ðt¼NÄ—'Ê浈6öˆP–½ûyF¦õÞ'cÛ,«%Úý_à'¢ÈQoÉB*{˜EÍ.Ðê7 —[| ?,”öÀÞõ°Í«§ï‰c'ŒÆS¸…ì–Njç ádeç;<å/ó9Ÿ¯Úÿ,î*pL–a»ðÿ%üß÷¿w9[œÝQ~;x¹ß¤@Ü¡(ÆGoË ÀÏ€åmá CÅM¢ûo›½0JÞGSEÐÕÅ)’ðàma"Ÿ„3#- Á„Ê}q\ì3·mµ¬ažà,W]3Žõȵ·#ÂÇ kÂiLa73®욺Püî½âµêN®FÚƒ®”¥*Wƒ¦ïU¶ô¿–®eÞUóqh½J\Ç+tF²™WÖyA$ígÝF¤Û8µì{ýX˜Z“~šÐáØ^U‡x?©B­ÐÕv:vWßãú'°Ñ›üæËQ4¤ÅDrЯ¶ û,ÄFÚâÞó¿–+¹Û]|µÑð¸**•–zžäf\s¼å U\Ëìãk_4£Ë5Ÿ#/dм2çsyôõׇWâCóeÞÐQϽ·\õÞ·Š(&«> ©ºGHë§4Wq³È¦žã*ÅàA=bcÔ±{9]¯Ôðj—!?‘&%è×|kFEZ™?DÛ龩Ý~yÓŽ’VꔯK.^x’Lgo²q¿ýDB=v0òyæŒÀÙøY>úÖný5d ñ‡$¾1Án½D;*ïÑy³l3/VÚ;¥¤,³R{v‡ö^¡wHœ9èU§”–î¬ç›xa•yýýcç€â–{óa#'íSZ t‹HbgÅ;¯»¤»Z,L×/Ž“ó+âʰ’0)UtÂËpÅKÄ¥ŸΜÚqüÿšÿ<ˆ/…º#¨>ñ˜YrEtÔŸ¿n ï}lÈtsîîS–LiT|7I)r®Ühº„‚  vQ1ã> ÍiÞés÷–¥!ßÛEæyƒ§ÆØ?JXÜñió%ëqÕJ»á;G]žfÉåCùyÕ(+Yäx,ʧqÅù•ãì°Hgl,«R¡GDjD… g%³"Ûð Ãʃ¼p•);gé[è&c‚ÁÝ¥Ž^NJuQO_>œÞ.ü ÿù·ÁåüM9Ûâþý ÈŽÂäE¶eà'€Tä @Œ°ëAï©“'ƒöš—_Ì@õWzá$~½ráœÆâó>s¸Ã¤®@.ôÑ£Ë>bû ÏrZ÷ìyn’§ªWE¾Çª& u7M\±ïð™³ý|œÑ¬û¿±Y[ë Âc3ÂðßjÝ[™yÐ_,K 'N—%ñœ§šhÛçÜ3}þð@´Ã‹¦3(m8¢´æÓI»X§Š«5“ºô¯PŽë”úl„Å£…£tõ„¾‹¢c£ðýš³pÝP¨÷q\·ÆÁN™Éð–Ùö†Œ}÷çØ¢F*vE ª’/ô¤,]XZHØG­¸;ôá¼P·%DÅÙgvO¹¹˜Ü í^ç»n'_L‰Ã%{>9Ëk«}+a;6z©ù«õ¨Sª‚›’ð|†goüå"s‰ZƒN •V7ù6½ÛÖ+dIÇ,;'ò>˜öó€;Ê{ïpyÔʳK~ùyL—’¯~3òiÌïå½ÁU¥÷˜ìuP¬5åÑnÎã ãBô—»(š®¿æsï~D ÷|ý†[fMü†±¶Ð°h¥2±r²Ï “ô^²N¯å‹Ü_•¼ú1ï¼x"Â[$.Ü®Ò)Ìðô! :ï•<À´ [»Ouf)Tô±üÓ&ö¾DÝWL}> #òAi7 Ÿ¤¯. ? f,©5êé*õ®š—²PÃ/ð10 fGñ•òÛŸà4äN¼[$ËŸ„tæ@UÅ—¦+¬ÁÀoƒÿåbî,…g¤y}c¼#‰ïý[¢ СïDÙ$ºwå¡Þ¸§˜TnxÚn÷Ô‰,&±([½Ú™ðêÏW—î®\•X×Ó1noðòÝÌ€Õ¯4öUÇà¯ÏÅÌÇMz½seInïµI¥ ÂO4-‰:2¾suÀŒLöÿÑ` ´~Mèþ¢[å]DЊ“_ÉJK˜Ì?ã_zë±$Ü´€^ÅXF±RÍÚèXæä±;’ïšš}vÿ¿ã¿É/×”ø(-ïøœ‚8° ·O«Üå]æÎâ}†“ûãrã¡’Àí‹…àS¥Ÿ5|Z[^I÷g±±Ö1Q.>6*¯-òDju±£eá6. â»h47åìûà¦aBKACwûëÓM²¦§wÓQ0i’$¿H¾Iþ ¾ޏrÌÔ…‡Ö­ëo\ bŽBÁÁü²5)S±u„‹l,ÈÈäm2]ÏK «Y©Õ#I®Û†ÿ¯à?å6xœ¿)ÿ½û÷w!<‘Û4ðÏÀ*i¼w¿­dÏÝIÇêÒ=ÏEf+g$?f–zù¿0†È¦œœuŽîI³9©žÔäÂ`ÀpŒúUÔènX÷“â®Z¦qqéÊKY+x|å`ÓÛ!¯OÜ`KÏ|KÆ·p¹T’ñÜ5]Ìø†ÃK›ÜÚÏf ¹:yX2Lz lu>¶æÎ¦~‰L|A¨,^ók­/&Ç|+^ZØm~^Ôœ-}VÁx÷9–aG{Vm“J1®ø’‡G=Æ}ð»õˆ÷â3XTu|‰¹5Â#¥Æu>Ãv…]„1'l&Îßå¨y·¹ôfûý V5¿«‚ „î•°/.ÝOÒ&QéË‹B fš»ó4wgå½ì€ê)]xgº¤WœV¬sâÎù{iégÌìè–ômÏ{ªÆ¶ßÊ2.˜qX¬.ùûkç}èãíÎ tW­vtJý|3ÿ2ë¨]Ô­aΓÍÃbxVdtnkZ/÷9Ë>'x9ÀWq•rèl©·zPi’>½lksp^'9±óábeuG¡ü>.*UAüË'ö…å •]’ðÍP¼å70Ù(YR{YÄ2ë­¹ƒ,ꓽ€Qzu9…›§Ý}M8i ^äãøÁL×1#&R³üî> 4_ßzÓY|¦¼o8–4{„ZäÆÑt£ù[kçRµ¥áAWÕëèôß/Ú‡¿“ø?±a+f.T¨#³€Õ'ífR›•šl2@n¾¹þ÷À¿:‰P“ÌôwkÒ W&˜´ÈeòOµ¾‡ŒlÛÆëwŶ۳Í÷ñÈv3¤Ñ¸Tü\’’†çÝ‹zw#šú´BMªS§¼Sõ*›…ã-óõ¹´Wß\ Ï gË^EãŸk!ú•ʧ±¦×œ/½Ë·A4LÏÌ´;8õë¹5£& +aç£&ß+–ºØ`1ܼð> ñgøsOXÑ:ñµà,L r]€«A@³åÂÜÙS0#ÅÿøOÄ»ßSAµ%&t†°<^:úª±Y©aHÅD½®ï)¹W±™fÙÑÂw“äljâöºû×k<ÿÂðÒQ*µà¦ÿEƒñ›òÏîßJ?ÁêµÐ0Úá’é·,nª÷Üj¬\iH÷ ÝEq ^}ûì0 u9òªê‰{ÊDžú«…Ó}jŽFžÜŸ ©ƒ¯8 Ÿª§—¿ 9Yçäòr(‰Êf0u雇¤ñÑs'æè³$}‰:™¶ ÿ_ÀÿƒÛàpþº¸¹ þ{÷ïo ÔâBlÏ À? ­L[I­W…Úf.ž:b)/L­ßØey=£ z0UkWLšÞåz“ó§BÒév™ñ7¨ÚÂbÎhFø‚.¹Pá ÕîG›cþP¼gÔßN…ð‘ùp ÆÔ X¼¾«#·Š_ƒ¨˜—Ȥœ´"ÝsjB!ÝÍê© k²Ã`ÜŠ»Gñü%XzÙëA &óÓ+ OyÇFƒî/DŽÐüµ Ò¾eƒÁ>U ¢ jØe6›ùË¡¦ãäÓí &Wuî~WÖ±vÔ÷ÕQ›S/d¿µÍ(6ç²^³kfDi2Íkëò5‰ȸÛ…V7 ›+váîÓ}z"—Ú˜£Û5a6shš¨b616ÔäþþJÀôîÐ\Öë{*MeÞ[¤ôÜT´Ø÷Te(%ÚôEg6 ,9þ ñÒ݇Û?zêµß—b(x÷®¬û«4SQsE¶­Ï+H›­v9kV+·3ƒbÖÒ“ßÌS›òµóÛ˜~Dðî¹âÓŽ ‚~²·$”Ýj«TÕ.¿¨•—4|”¾òb™”àuÚ6{]å¹—+]§›¿hÈ uQ°êò™ÐliÆcø È½÷¤Ëd?½“8‰÷ø×d5!ç\»!Ë}<+~GØ~by¹ƒø›;Dõ¼ðª÷ŠË*hψ|9ú[þÄC㫲UJ¹¿þýÒÌJËóüWf²½»­Öî§;Œ½áà2Ô§oK[b^ ÿCzKdñ!)ò@ô£Y–Ëœ¯çtÄæ‹.Ò©¶éüžV ý¶+…Ñåë=¢ÜjÛµB®YË»‚ë4¯F™§¦ÉÄd³æIκ #_°> ‹ùFÕNÈî´0uŠUúóW62­NS‰<Én3öMØÛ°Ÿá¨û¹5þ®x6¢, 1‡‚Á_Ñå±PÙzÄâŽâÿüo¨¯³âW«m*Bè;9’éžqJ¬8X¯Ý"½ÙB¬ÞA÷ –19áù4oQ{ˆ‹ÒÀ¡£LýY×!Šˆ1JÒ.™ùןf \lÿZâýÖè´-ôX“‚ÒpqÐËtâ>ýeƒløÌëÅÆŒª¹nñÁ÷alT­¯ËÁ¤LgÎú ª°×”Oz” j$z~ªAªàµa†ÀG7‹f G(xÂíxÝ8K?néÚ6üÿ¶ÃáüU:Àþ{÷ï Ä †B·eàŸ‘,!Ú ßÒŸY㈖¨w¼ÃK˜Šᵆ,¹°óo¸ ¾”UÐÝšÞµô>‡Ò~ôáõY#AÐSy/ê£F&ÝF¢do(í§îTyRiˆ¦BsT-u*áÈÖ³^µ×®­J0’õO>”n•H9`â” l9U >¡Ê“¯Ø?KzDBt€,ŽðTX¿ÅJìX&ûî2-ù^±OîPñÕ:÷'mË.2sbÉ.bºic_»L¼*Ú—«¯7?¹â*)F®ðéÄS Ü—âbÈœê\h]KÐåáLÑãÐÖkKÙ¯éÒ NÒÇÁo‘Ò¸ÇÖÃrWoß»äj$)“¦WH51KñÆ']qÈKI¬Ò—à3³ôàêüÐaV³¯&Ôí´‡†c ŸKC5•ŠÅQ‡DàËk?мEù¦oâ@hlP­`¨8Ðö!AÇtÔ%2ýEM7¿;Ù¡0æÔ·œL¢wJ¥Ân¸ª=rr¹^of}®Ç%|xµJ2¬;e:ot´vAû‡ã™”ÅcÏ'ªßF·Š¼¦‡ì¢pvgÒ1HìÞåCNÅwïÂKTßm6ï'¯ŠzÔÅIjûµ¢èÏŽÊ5HIW BÖ “M4¾oŸØÓâ|ŒŠX:’Ä÷¦7†koñ\awÒýzÕ9»§K¢‚: Öý{ÌÐfíé÷-!L;ˆÿü1 ëÏÌ VN‡#ÉÇYyšÒŠ/™ ÛÓé_q[Ùû[à.£?› Õ§„˵0k~Ñûâ¤üq¶×JD‰wäbÏ<<  e=š¹øô飑>}b7Ó½.¤6™Ã°wIzWê_T—_~ÙÇÕr8‘S:dÙSüèÓ¾4⃉‹uA/Œšó/Ÿ æµeÔÓFÁX*'n,Ÿ÷eKP ˜8B ¬‘²Âõ±Œ§>‰d“œ®ZùþåWîpôºÔ0ÉWòhÙì/QOÕƒeˆÏ²¿ü÷ðŸ\úšŽ˜ýåü[TÉV37ès¹¯‚+L*4“º<¨ö_±Õ›Îp£ö\ÙI½‹Ú¾ãôÁ M/s¿>{Ç:Ï\+…èhËWkîëžó®ŸÎ…èÊÏwMAõ€|O+›ògLÚ‡4æzEåeRmNÏ‹u¾8ð¤9ˆ”Aö®duzöÛ‚ÖÕ¸'ÃÚ\|¡¥ü"É»U8"oÃïÇÏÜolÓ‚KƒL=†#·ÿçÌvø›¿*.nþ;u­ß²ÀÀîpø¶Ì`Àß´ë¥EáÀäµ)¼æ­³VFŽËßS[¾ù(׬|mb7ƒýýómã,çM.ú8dš>« ‹…ܰõ‹£ƹº?Ü?ØEmucÉT}.½v¼¨L ©yÔæ^ãƒGjtvÈy1ØÆÂwSzþ$YeyMKJl. ˜=],L¨J¦‰ E€9ÔÍuÜøZI ˜)Rßc7]htvêA«þÓ ñ|>Ê•ð¾i§=à§Œ"cR¡=ºçìá5ö‘Ë2=EøÂÃir' eª)Hõ,ój…»ÞFÍ„8,+ÞOâ .g8ØñôžLÅ•;Š‹©iK„!“%ød—ž¿8ÚéØçîèª7A}êžKåÇÅÄÛ%ϰ^¶/#å¸[–5(çn%ÖírýB‘ãO‘`1“2/ Õ ª¨3æUZÊý_Õ·^ämñŽ?“ÜíN^Z;ÏOPóAúÓä‘jËź—¹ñÞd«×¯x=Y ìÎÒ.{2l3›mi¤â¶kï!fÕi͉] §U§¬Ûè¾óq.ì¾óLpØ]¢ü8ˆ¨ð¨,· ÞãòÃÆÚ>yt»ÃQ{zå®·Nþ½' ^¼š®’[t½¡jþ…‡Öé¥-ËCd›føÍ²+ö_œø†2.XDÎJèñÖ yœÿùLìš{#™Â7¦€‰Î5¾×ÉSŸvÿ³¤·(Ý^~¢Xzô\scjˆPº_@o¿ûqî˦~ü | õ9²jA–R®åR.üXC+ye":3P|ñ 9âê.½ë¶Ã_i(üÎ×wš#Ä>ÕD›S%ï;áp¶Ç%ÚÖ%—MQð²×üÞ„ÓùÚ¢•÷Šãåuûàôbƒ½J©ýMr¼L¼w_¶2Yuì¥ÓŸÑ}HkõÖL:¶|=š¹&3¿@Ñö¾MbTù¤kÕÏð?u5á]w-GøÁ¬vJ"ͳ3ÀWº©•ÇQéÿ&þ_vÑrl¹/éoQ›pŸÖ«B“åÖdká²ý(ãBc}U(«l~‡ËÀc¢ð+ìNäµT"s }±ì>Àùá&ý>æ4Ïp Yo ýß÷Ç/ÑWå†q{56§‘nü˜ir®¬¾$:LøÒAƒ´¬·®;ñØ‚åá{ËìÅ5’D¿&¹í©øG?—-3Ú2úYx?ˆ’⊋ÖìÛRrè]Ö¾÷ƒÎå2mV^ÛˆÿŽó¿g[ÜÍŸ Øñ¿wÿ~V`î`¨—ç6µý7àÁ»Ž°#/õ@\=)7£2ôfD™¼™QÃ9\šÊS+¥Ú #Ǿt¥4˜a¾ÌÈÒ`u.©WÝÚ‰;Öõbþ ËE8Ëu÷‰ð}™:lçÏü¡ø^ºýyv÷%¯õâû°WÓÌuˆ] :¯ ów)£o _š x¡IÝlHw¢ŠMCœùŽè%É»)ÄÍ×b"Þ8=RaËh·¤ô¢ðiô <8߆Zq{“R—ì¸çHŸ•è:Iè¯`™ëœ²÷Á ûýÑ©‹·Ìï‡ÑÞýdxw¼W}¿ž.üi8iÖœŒQ Á? 32Þê)ý›;ŽºðN3@×<™µÓU}†Kg<º˜:ÉÖŽðd½#îUoïoºÝËgxi«Ôšsê îï?œÌ´•“l{ø¶´–ÅĹ·/]íÏ2ºÊpR ï/ž}Nþêv´ÏÞxöÐ}œÁ³J>Ÿ»jeéûÈüóbcnœ÷ìâ>rŠæ/-‘4ù¼WßšÆØBè!ÿ>G|IÛ§ÔÃâ”+l)È¥ ÝW=q"Dµ´[ïš ¼àØÜp\€Lî­>P”ÎÒ$R~8$³QŸ«Tdz”Ë%aØòTЃ¨|_]Gw&Å…J|i¸jS)û­‹¥D®ìx <)¶)I:z1鯂MCk…{}ÊŸ±9a$œÜî]‰PpHôÎáߎŸù¦uÖW(zDêYïD‘De!qæ~¢Gæ¼Vÿ~ü¡áâOžî¥˜xÖ]l‘xü~æ©?T&»Âv蔾¹'ý)£ö°×~,„ÒÑ´oÃMeçgÅ/½{£sŠg(8*wG¦ä%ƒÜU®l51㫟‹L(Z›ôö"^»?°šyaù†ýµè8§ÀÙ«âÄ=1Åj£ÙÆD{PµDÎÝàRé‰&·¬ˆÏ.E'.î‹®Ï|.domõU²ägø?8êœôUá£ÃÇ^è‘+¼¾\líŒ"¹êì_Åÿ^umÞ%T@Á[bíh¦çÇs¢o“¿@ÞÚÓ\ay¸ýúû—f\y‡cßs>{H-›ø"`¾ÈθRïÅØrÜ|¤Mc9_ΠZä^ò¾)ϼ°:òú«—!k¯©e¹õÄn¸ÚµIH^4ÀÓ%{ͦ]ñ$)Àvü ½…ÙGmç§I„çå—YF—Mªßs]a±Í§¶m»vÀíÅ"%£´ædÂ5.ÖíßHy‡ùo»=îæOÅÉÝËw‡.õ¨å½£¢§DI£*a.xªÊ¢7cfŠþ2oÞK÷©{ôútÅJÝΊêñõÏNY?ö‹1å}{¶„v¦æM8÷<ƒÊŠÁq“k´ׯČë<çÚµG†8îVdάãâYÑÓ̶Î@ÿÞÞªlÕÝäèRbÏ«',h¼®–§;ˆ˜Ô8ÑU4'<\N¡T³Õ<=dNéŽËvüÜšCåÕÞ7GN(K3ærPTu%~ Ð]È(83=xçŒì½á\ øýÎÐ.æ§KÆÙsõйœžñ㵚o˜Áç“âé9T‚ÜÛvy–Õ(ùðd—B’3~\ã¾á/œ-ãÑ%{pM Ÿl|Ól:œÊvÃÅ®si‘WêÅÉád*–‰gz#qÔÝzhE¦ÒXÚ†\‰PÍïG¯:ݹÃÝNÀ¢#óæñÚržÜVýMYˆz…èÍÏtÉv­Ì(ñ”¬èö®LâBµÛÊGK9sà7¼ZBHüî”™%,¼|2±¢BÙhNâ*TO¸„8ö޼¾„M­ïrr:ˆE†šÐ„ݸ e¨ k‘¼o%¯‡îæ#qÑYˆ§·3“¬a‡ÜvQÑ{ X§KQ JTÞqñPÛ»cøHŽœ:ØÊÇÆŸK¾é«$¤Åæ¯,{ˆõ‰ê«·‹ÓÚOJ눕"þÛñÂwã®3]ÐÍý¦}šBé~¦¥þÓB"%AÛõ3vœÒÁŸ²zl8û+Dê¾}“8µj¬(¥’0hOÏYz/U—ôf6ò¸ÐÃö{â áL1~x÷céÃ… kçëíwÐcV:+ÿA~­ØÌ´çM.‡Jï¾S|KrÅ"kÔÜ;óÔ åáà†Ý‡ü/ ^‹+$]àCý >U!pJ‘4Û£ø ßl>ní™ÔÔ¢¨}ÿ2þ³ÏŽ‹\@^É2’¥¾ªk¼­Ü +vײ¦³î.E®i^ïtDuËÕ€'‘‡ºmMeU†}]¢>³Eèß nVçµ>Å-ä—{F•{O¢{£{AuÃþÉåçƒZ“GY¹ù¥Ò S!kQÜyP©š(ÛÏO)ÒNž«jÔú¤ò>Á‡Ä3822O ÕÄwk÷ËrÈi|“ç;áÏÒ¤/zêM¼{;ñGî,ÿwhJÞÝù¿wÿþOäŠðÜž9€¿ÐOÇ.€žWŸôXÞ»J¿´[:È‹ÕgUEœý€á•6ùKŒ: ®hV•Oäo÷”­œ3Y&6–47¸}J`'‹'M“ B®ußn¤¼¹@i¤ÄìRÇÛ˸ï +U<ƒK.‡ÕíéeC ¼°Øç5J¨‡¯ª—A@ó˜Ü×ñ‰}Jû˜>Q¥~Œ€• .A<Ó°uŸÀżK‡äsho, z, ÉL¦óùˆÐB„QA)œÎýö¡ÌзH_j}Kj¿^KótrQ#ã×~™¢%zú6š¼òI„ú3Ô=w§Žíz eyΊTÐïÔþœ Qvj¯¸§`1»ÊþôÁ‹·Câ WSwÖÙgÀ¤KÉ[ÓOó.½«82çÒ3'X&|6Âèã·IsFO{+R׳·eGnæZ ½üU>Eà&¡ÿ޶‚®†C`9Ù1…û1õävç›xá×&¯‹6=ŠyÓpxLIÒ"”fùr_™Iݨ#*Žñ„OÒ•7ß’ß3¿?þâɜֳÉvR²0-ÍXæ J<¶c{^1/Q‰ß¢nR[Ñë±/zïÉjÛ¢¬ÐÇz9æ¹¥=üt•óH~ÒÇŠ5íoÅ Pãy{¯”ëÔïü‰ã’N§Ê—N«2ôö+(Í“˜€/¤]Mƒ8Y³óó]#ôµS­ÖÞ1üÉ´zlSˆäÅ“Ä-ç«À;v̼#Véf+Ló«„»C¹T[žÿÛñ_V¿¾·+~•÷ yÂ×!ÞÙrOî"¡({-˜!ña>w°d«]ÐOê³Ì'÷t .Ťú!³!Ù<_Ò¬¢²}æXòóiwÉ„cŠ…>$­“”)Ü,¯_y¸Pš¨Çzðô›¼&bÚ7\2aýüƒ·CÂɺã¾ýçrÉã$‘YŸS§54O|‹›µÕQäøþÝ,ç@.½‚ ÛYBŒZ}©]ö9“›-¡çéAäs? hl€äü½¯² ²¤}ÞDn41ÚBž)¯üö¬ÈßOdÊôºöj1Ã#›§‘¬ß$Ç={kMê&móì qƒa‘‚QWí9s$TsÄÄØŠF^ý’þR[Ã|yœ¨5Õû˜‰ïÞ†n¢Zn”W¿Ô'Q›<ßmÅ¿Žs'ùi;\ÍŸ}#ØÇ{G®ôÛ÷ܦ×þBìÿâ9¯o ;îHè¦7^kÛ×Qo~0“Ð43-nOÆí‚„Ô‹ âCò‘uÔ{Šs@Ž]ªGZqlþ¹Å=—Ž…p@Þ¥ñ'¼†äÒEÎ:TÞèû´˜ö|»–./Ã<;`ï®ññAl/› ¬‹•µÁpÁj-µz&Áz¡¿&ë¶BÖ‡®h(~ðéÖº\¾Ñ&™Âê¸ìVн§¥¯…$]s‘x£n•æ’ñSˆÞ(=0§IÆJº—Û™¦üòAvL€þ´ƒÆå´‡Vø^Âé”·ï=ê6Mgš@°vÑçÐå"ÒO_]+ë?d•+"bæc„G¸ßkdñP³aîp^ì͈w©ü¢=»Vù»ßÞ’‘ l2PsŠë¸Îá”]fså|Vƒ“Í]uW*¿vºìƒ4N|"ÝŸVªu>ɸ|~ÁÄO'láC™ËüBމç2ÇS¶¬s¦B·K£n€4Í9™\#•úÏpËïþ3Õ’>ñŽ1"ñL±_ó4“ɇ"‡Ñ{uÚrBÐòÉîá0]±µæDm¤²8Ó¿ÿýq#zŸÉ“]Z5ì4[Ò4/žã»qòÖ`_gâó¼ØšÌ(D§ÎåÎ:ó.ÉA/_Ó ¯h¾ö+}OàªÌ]QHFßøëáD‹–…o_ké´Û£=,ÓZÞßêÉ)ØáJã«MBh¦˜Èø|zä]Ðuד Gdçì k Z·,ƒéY^ßêÕϢቦ-#42×>ú3üƒ ^iž«h×Õ„!"ŸpŒ”¼@°ö_È* C òãÑ„W%øB¥â£gztO»:}>4BŸmRP¿Ùû‘ž·¼æ²¿ñ¢Œ”8IdÓÚˆ^U°ØÊ¿{E+m›Ó±ž^¥n ’Ó}æÎºpö°•­%Ç={ÆŽ¹2蓎ÊåLþƒkŠ ¢W5tF¤úçÙÒ_ 0».\Œ¢= Ó–‡ &å,ÈßÇvÝÒ)ÎÄôHd5_|xñžNéÊÝ9þ?ÙOó§âê‚üïÝ¿ÿcP0ÒñóŠÿ¿Ë_ 9»èûG½‹l ua*-:øÂË^{Fß<¬-»KÏ ŠüãGª9™¯iDJ#AA£O£Q¶6×Bim‚#Ÿ›4¼i̹yç(MGË(/­”FjÏ8)®ë5¨†ËVÔ%FI÷S¨Ÿ¶eç­DKà:JÍIéÌ[â³é¥<ëF,XÆh#¨Gïž‹qRbËéqnh#aÍi8õÐEwïÕ3}¢“û =é8/*(‚sD¦Zl'_”]Þª¬áºOØÖp°ôLFA.Ô³ÛhþÍ«P”-ü&sºP¬YbRC¢#É­[W‡‘&}“a ¼ayâÙ õx>sÕØt®‰êS„÷é{žçäæ çw‰ö¿Ó_XŸ™” xwU‡ÙB:{ X­ÌÔ ?8=žùÍOÍn®Ò±sÃOêšdû™ŸÕ©dä™öcs@’:-•Ã/ûã-0…©NÒ5í?«÷x·aò9Âbj³ÓeFK.õVGH÷0æª6)ÈXIÃO°ùß8x¿·0HaŒxVt`J®–¬‡ŒlDjD…¼uwNm©ˆQæË0žšÓûÍ¢Ý<)òÕW’S¦¤Å¼ ªä¸ F´©_ŠŸéóÁ×¼ÚJíSÛ#¼gXú•ï¬^O5¤í]bcÊ¥÷<ˆzéK¤ÜSAÀݨu|Ek4¼ó³¿½Eϸ¸5{±N’—±½¸ Áá¿à_’,,cæm´ªÖOWœ2ì¹ÍïšRÿîFu–5dÄÙFMÍ<µ]•¤Ì{˜(>óߌ¿\}÷q6ù,µ«tEš“{’Ó!蟩 Û-~ {—Ýt¥5±ÎPLL”B‘â8QÄAÇ÷'9åx¯d-_¥Qœ7ÈA4ÉFæÄûßýÒð\‡c wYÉþæ2Ó&SÚœÚÒ¼‹Ä£õI_oQ8Ž7‡p}:Øñ•dž<¤{žq ¯ç’g=2&9­Îv±­<”OcðSü¯¼s$¥w£Ä¿,5jódkË>a÷oä¿ì䨹lrpøéëõPßóÜ”o€BmÓ€+Ó2 u§gÏ—ÙR­ìW‡~x}-"¿RÞ:*¼ÛE;>àµwÂUFH‰A±·­i²ZDrêžË/æ;Ã/å~¾•6ó±WTè< ‘À«*‡6Å1û§Õ“ *»žú¾3±:þ¬a­Ô9€eaÄTp¢w¥ã -+“CŸÒìü1Þb‡‹ÄnËE‰{û˜n'þÂg–3wŒÿ mð3ÿè‚~þ'éÿß(0̾åë/ùó¿ƒÁ±ÕпáØn@ÀÌ'†@…Ã è ¦1‰ýŠ¡Û_(ú ö0ú+ŠDÀ1'C±a÷m´ˆ®…9‚¹Ž£&‰ù{GèP“¿çæÃþ²£{aîtp(ó»{Úæ†Û‹ýèê‰ÜÒ}3¸cßk¡oŠZ¯³¾ز…‚ÁÞ`£*ðÄôÄŽ* 38˜Û‚a†`è¡ÀãF‚6>â68þ½ËP Ä…©†¡{F·E`$ 1#E¡0Äw1ã…Áðï m †½òú.ìp¯_…¡O`kÏÐÝ…Ã7ë;®—ºcèÊîŽ>¿!þ0O4P?ìÅü`ðGüÐ@ßëa·Pøæ)˜»[ð‡ÀèQAŸј§?fÄ€ ð°ç`ðßÕ àþì)hüa?Áø‹ðÿΗ/`½Sp(b³"ŽV›=ÆÞôõ8üaZ`7ØË`†sUØ:ÿ0øcöá¾CÁpî¦á¸Sà˜OP4þØO¸šØN@qw‰®†Á{û¸»Y߬j{ðÿUüߎ8óï ®wÿlùAl‹0ú?4Š~FÖM*Žæ«€‚‘hŠ6Òh2àªÁѶŒôÄZDÅ1äÃÆZ ´Ñ@"±G`̱Îx8®AtEôpWR=6,.Ä ì‡Ü¤°A© ;n'ÄÙýñCPˆ?¸Œ nü¸¬Ûÿ kù_7þ 7°þ?-þ`ü×yù­©­}Âqìàª~÷ë1€–pøÆWì´IƒÃ¶ Œ}‡c‡uý«»³‡7jÞp€€AhÃÀ¸(½ Ûò„À7ÐÚØ‡ù¼iÈ×ËÓ‰&?ZÞ}7›Vc6¾ï0þéHœ½Fߪ«Û«|ëyëÑcB ¿_S ˆ?èÜp¬ß0¦c 'ïïø£?zDa`ŒÀTƒávl,>8ü7Ü7™Âw F4l­‡m9ñWò@ã¦u½€œº€ý°Ááù‚¢>çâ±TDÂUD7æâ‰Ø¤'fÿ:þèÛ„Âàë2 FátƆ ÀT„¯s%È _?lÙ`zâ½Møÿ"þï¨7þÏýÿX¶ŽÇv$þº.òÑO bó)…à `8†â±f‚{b<–â–2˜ç ÅÈK Ñ≭ À ë–_ëæ Ó¶²=,ÁÁÎ(OÄV[þ½ã?Ø^0ÄsƒKZ¯g[]Åú K]¼[i`-À¦8Çõ AýÑøo†{:ƒ‘`ø‘4¸z®~ðõx}KˆM;Eµ`$bC`M ¹ÙE\;ØæÑB¹a†!nN¾^è8Ó$:‚Ð|GÓÝ9Ìq‰åG€ïuÖc 6´Ûbþ lGüa°pVSg‡ñÏóDW‚a= q‚ÿnø;û àO! YÇ‹Àxô-ýÄ4‹8AĆr¸¹øoâÀà€âð‡aö!¬[^ʰãÃÛ)þü1ØbðÿcÅïu~-ÿ}°ÎÀê…BW8|CÀáªãÑà˜ðxK,‹˜ ›@àð_ô×o‹?nð±ÎŽÁ¶®Ö?°žÀv‡ÿæ‘­ãæä¹]øÿþïhü¿-Aîï\¶¦~oUÿë2cÐtGmš ôs v¼1ôƵˆQ•ÈuõµLŒŽ<0éD.ð…bÍz‹€áF7U ùÕpÃ@¨-æõOñ.èrG!¿3 Bzl­¼y«¸v î^ð­°û 8Ÿ ß°õXûl\ öã?ôA^00àñƒ»ú ×Ý>°nR1ÁŒ±xØHã»ÇÇæû·*Œ"€¡CÌ;7¸„B\Üü0.3è‘G;´Á1ë?¡˜8àÏmàpøFðËíá@úѺo1ØS?ÆÔëa6±ƒøgú qqs¯è ÒÁç7ÃõÇ´.vÆX?ó}ñãÉ8C¼àýCãÙÀ'àh—»4¦5(6žÞÈÖb?Áp£·.€ŸáÁrÿ­ÁáÆ);ŒÿŸù‚‚ÿóŸ2ØÌVÀ0øofpøãÜþÆL6>_÷înÞðM-¸.Ý0øÃÎÿ¢b}&`#€Á“϶Dÿ0œâwAlþ¿†ÿ;éÿÿ ÿÿ\¾+€íG?k†{,¶ªìYè';sº>ÙE{-¬¨‡¸ŠëI@,ï×Ì´*ÆrAq/°nYq1ºD ä ?r vðø›ý`q7¾Cü[´+úïï’n„q‡1©½ÍýÀOþ0 ¼^é»CøCèæ‰™Äœòƒñ0£ÑkcÞ—²ÄÉÌTœb –}Ðï+p£ÁŒ2ÄÉÿ»‡Á@΀/&A‰6:Ø “þ!1÷‡ÉBaðïjcppsz¸Ûb¶ØÌ-6k6’ÀðMŸ C ¾ÛÇÃÿ1 ËÖ®çˆÑX:úýVøcÔÛöaÚ‡aÜ —œØhŠüCEì`Bœýßo röXÇ“÷G+ØÀ-sÀâ݈ö·ö9}8Û*þ`C4 €?ýøÿÿÝ=°mÌlüá˜TuôGlñøPØæ:ø÷µ˜Ãè‡c³µø}ÿuf~Ïÿc[Û’ÿÇÍø£ÏvõÚÀ×ÄF†ÍpçváÿKø¿“þø¿ðÿ¯Ê¦Ø–Àφ pO=°Én\8E«Úub»C½‘8Çe qa–<8`3…0N#(.o[WÙèS5€‡^›Oñ†uÇ-Ø|0·v ·A ž›†·Á&¿k=ˆÃÖ€ÀP[©¹qÚ–iàó¿ùcÿÑ=ƒ`3zð ·€w?`Ýúm8z¬©‚xàBt¤±™DóØôi¸”F%¸x"×ã2ì)PwG/oŒÍCØé´c„`ÝæÏAýq ÎÞ@¡ÈM°™æü‹L &Œ›Â…br}qöÖ7 ÀNâŸãé=‚™–01&ééæú;áïâ‹=o³õu©ÁÉ èüáÀ×ç„]¼¡¶cîN¾Xü!0l” ƒ ÑøccRÝPÌ¢‘ O½~Q´W€®£·ùý=þëã[W›9€õɃÿa~8ûC÷q³Áà¿Þçõ|<ÿõÔÿ¦ Çž P›RaôbVB ß —ÿßâü-‰Ì¥°øon ÔÑg»ðÿ%üßÁøÿ¿ðÿoÊÆÀü Å¥±ËŠ vXñŒÑÒOìÚí³Ð nÍØXú‹I®Ëc8.­ ƒº¡<6MN?ãÖƒ• ß0§0øf„†–À>ˆ "ý¨˜±áŸ›çŸˆc–ÛmåàÆ;FèÃÿ¼MQ(nÓ°ç3„ËWnþCw®ƒ°'ü—vñƒoY´)À«lÑFc#Yuq?(Üí¢-m'·,pôÇh0.ˆp.FL`wlªôÍ'3 ˆ¥. ±±˜ }O›nìÃÌoÜ´ßæ°Ãq³‚;‰> —8ÁZYì)˜Ýá¿þN>ð?t¾aÙq&~ÿUð-`¦;ÆC¡»¹eØ9ƒ?6€$! #ÌCÅáÿC¸_Ƕ~ÿŒÿ†vÚ°ö›áôпÿÞ>ˆõÀؘø>û ‰‘ÀºÇo,·…­?Qؽè÷ÍõþÀFr]lY€QëïÀÊÿ£{„‡?öÝX è„Ú6üÿwÖÿÿçþÿ²lh×í lK_U×wê×+Ì\$Ì â‰›/…bíÃ:Kqï'ážýï3‡èØcg±ËTÖ×aï fe°þîÏ2¼˜_ G-Oâl½nÍÝÖƒ˜Ä¹Õ6oÄ€˜ Z`ëcŽ;þã40 ôçüï÷ï˜,ÿzD …+Å×{ìîå±ýÀÆ!€Y¸‹µDh?C¬þ`ä.bk£ã]ÄÝuµ öo‚]Ýü=1W8v ÷‚y 3wù‡ € pëˆ`X;°…ò˜òãZ*t]}À°•a›ýAà`Þ1üs½¸yܲ1(ÆzA1-½ü‘ëÓ¸4nÕ>¦.8ƒÁq³Â?ªÌ 0ÄíÿkïJwÇŠðë!BHü™‡€AÝ7‰ãålÞÒ¹Ë Ì¼H€Áûqj=e'}oÿ˜xÒÒµº#_Çvl§êÔö•ÿïÎI~/ãßþÙE…©Òum‚"Ä?ýªÂF {|ÿÀž0^†ÅÞÛâÿŠü?ÄÅ](í.Kâ/>~dÛ!㟒†ù¹ü/ïSIé2ÒÙ>èàS|3Híî*@¶ â¦AG½r=Çp;üùßnF~wÿ_Y$Zs“ôš‰¬ÿ°"G^É–v6œÇ¹ô·ìÈAÀÀÉ?*÷Aj7QXE]‘Ûrü•åþØO<¸>ÿÀúxˆs¬_wþ´d±4µ¯Âä–‡Á…(Û¬ 宩O“Þ¤wí.ž‡ê!+€êá‡c£ùD”¾Tu…Ãí³°Ô” – Ä.@ÖÛáÿ×—!7 gò1Å{Ü=}%ø7'¾eÅþ²Ï‡ãSfJ™\Á¿™§reÿ1ã{2ª?àtxx¾¶e5þâß¿Š¿~#\@MœÇ-ñUþë<84[ ÓæêýË<_Xm;)0 ÐU§B44@šØÿlàMñ;ò Ãð/\Àö8ßÿíå3ÿÿ}ú}aä¶6[ÿZÑ+‚ÌC'ë‡c5}Jœ%´;–þe ‰-}Ø–½$©ú%eï»ÿœµŒ‹<4Q¿(•{Lkߥé8,˜µÆ¦œ^Q÷ ýoŽ);ñ_û3ú«¼Ƈy£wÑÓ“PÕ¦lÁ'ŠT’E. §W0}¤l*4s”ªfÍ ¸úãiÆ_êbêŽi†/FQ+”‹S ö|ÏUNÁDýx‘*`Ï£ £lᓼ¶Áÿ?s~]¢Tqò7¦L@çŽõ×ÿî|…FtúgÁƉÛ¼{Ä?è…Axöcb ÍðR@©\¢Lþ|Ô¤À+øûRm²è€Ãâ^ä?=&žæKøNŠøÛ& ê’éø_‰ÿ£|q´XÃ"þ¿nXÍ¥$žµdÀóÔî†øÜZþ7œÿß§ÿ7—ZŸ1:êî…cÐTñ0ÂR~N(›ÔØhƒ€Üë÷fß kY¹¿ Ÿù¯*~©\]?­H³¾šÖ4í]Eœ‚:p`ªË ¯ÄIÉ»,€ ÏOõ¼ü«ÇRN¿Â\0(ðýLu’*è›ÊÝXua@ëÀl£çêȦrõ)Xƒ=BKP"Cdª(,ðÏ(¦ö¦ëEÀâäy«„ ŒwÖo†ÿ¿fj‹Ð›L&Aö÷ÿQZ/ì ªí¶g„I[>ÛË!ð€1äŒ\Ü tC˜Ï½LöÁ”kØ1ãI›¿?!Ló+\@gòïžhþSùü ÛF˜ÈáÌlˆ•&ï_ü—yñGói5ù2ÿ™ñw¦7 âm|üûmå ›,ïîÿ.·³®žÕ/@hý#ñÁ·œœ¼ Öå œËmòwÍ/‘û³’öÂ* ¡ÛmöBêöá%ù¹â¢s&º½ú—J¡(}; ¸j°MáY’‚2½Ñ5_ÎYÏÿâOÈ$MK $$˜IªÙ·‘©Æ‹«éfØØ0WÉ”uwû?>Ÿz–uh ã¡;RÃ?£Ú‹yðr\L$.‘r€LÊòÂ6Ãÿc,­„„,f¨%@üÛ{Çw¾`€áºe[BµsqXï.aãWØÄe¸#ÿP·?¼dü顨ÉPR߯Õhá =ü|k8i7y@w$ÿãvÜÁöý€?uÎó‰ß6´Œ  «ºJ_Žÿóœ.o Â*Á¡tˆAi€ù 4í? ðq`׌¤÷÷¥ü{­ûå?þÄ/yéEïX?î—Ä©Ìò~ø’/jìK ‡<½ñ/Œ#qþØiyÅðbà¶Ã—´ÔÙÎÈ|s"µí\Õ=rwhþ‡ïÇ´fË*¯ƒ(ýPThòO6Z³0LýFøÿíyêø£·J©bäŽK& ²×øp¾küÝ|y5ðßi%BÑî8\>´<Ћð–?<ÔÏ%O=®Šg|3,ºÒíïÿ„østyåßÑšw]êßÄ_šÓ¦‹ð½ÉõÒcÌé ЀÆ"@Òàs=ç= +XÇÿ ÿ»sï—=àAåaJ-öˆM}Sü]rÕq3ùÿ?áã)ÐéTxœì½XÛû6 J(ˆŠÒ! ‚ RÒ€t§´tíº ƒîn¤SJR°EAB”æÝ{â9ç{½þÿW¼üý¾óœÃ83kͬ5ëžû©µöÞXß @Wp ïïhè¿A€ È„ð…þú[ƒ!¿é)ÚIAmB“ØÏö×âNYÊÏ:Ï3¼óZ,W÷8|æ¼›ÐÂ5<ÕˆºËöU‡ý—OŸïÔEDn±I$.84‹#h_WD‡JžR>Y©Uxዤ Á;ÃHŒ—³ß—80£ÖÔÈjцsÝžü(„>qð§0ËÚˆŽ[§/±zÅl / ×U°+ÏŠw±_<ÇÁùêÀ`+î)ËÅ'OçÍt‡Ñn.n±ŒÐÃÖ¯*xVQÈÃ{ \ŸÌò°ºžÆÏ¶I»ÕÅkH?ײַ}‘6ƒ졹E:kiÞ­EÚ-8E«- '–ü”'C‹‘Ò.'Ê»ÄEœ„wß}òã$7…£aG÷F°¿Ï´ nhP„³0‘E­—¹óü^ÿ-“ ÿ( ‚Û׆8"z• "=±º:+f –ÛH"–NÝŽôÅÕâTuyUæô3ìáMVà*Ý3¶–9‹Ï-›ûªãj‚B?I¸qTªrsÙâKë3õ嶈µZ [Ž–Í×̺˜‡C)ÇÏI¨¤_Xzj†SÕòíiÜË9èe‚FiŸ'é|Ò]Ž2ùÒ|)áöHç y`FÇ}©›f›–EQ¢ mÙ$žu”?<¢éÈaL zÉIXF²U»5‰%¿¡\Êi$u,|=%ÆHs¿'caçøUƼôëmiËïX‹žTß<.wÛkuk,îÊ'ÆB¬f¬ÓÓùÊvgàdOŽ“Ï6! Y݆„õ†øŠ¿“Õ–1•§RTÇ“x²“ Êb?ý™üw¡Ì³Á%Qn;ïnØ›ëõìÝš‘ϧ®ªxrí•·9/b)Awäx@î];†ŠGÊæ.¾o—ÆêÚÜÓWœà*9wmí¯1b0Å­Ë<ª£µ@ƒ‹Mƒ'rç](Ĉ¿p-žÇY½òôØ'Ëõ1–²2yLŸ'¿ŽÅÝçhŽ•›É°€x]â,§Óoœ½~'`ªáæRÝ7Ã{×”Ì4# ÿ-½IΣ¿‹ÿ¿ÞÊü]ܽÁ¿£ÿ@€7‰øõÀß„›j€9¹¤­‰`#"¨¤8ÂoXzʈɽNyúj´õ SY!K÷ϵçlÈî¦[ÍJ´B°C¾‘|ÙÄQ¬3ÝxH¯xïºmwzLµŠ…49޵ÒU¹ñ¤7„oP[ ²ìzØþ2œ9ïØ˜!6é·»bC¦º9΃çÅ& ‚r)€n‘´ÒØõ¨$öëÌW“ur_V¡ÖLÀÐÉ—º ú€t“̳ç9N“½gtœàL¬$P÷xAØGK _Ë[©d?Zò¤ŽêðíáQ›Û^†÷€&O"æ5p6è2¦Ì YÇ%Þ!ð®ÌWFËV!BE?Ô6:Û*lMœS¿nqì3 –«lÃÇòÁËE–Zö¹6Ž2Mä6Úªñ™î;ó†^ÊÌÁ–Ñî~+Jñ/“ô°7‹~±›g&|ÚgSw2,®ÔŠ«''ö¶t"{ò› EXš‡úðø¹«*ƒÊÍœˆbÔ¢ÔFÞ?‚¼½F·Û[LÌe[|Œ‹Š"Þ%ìɱ©+ÞdË„L§Û¹Õ²ëðJ­²6êÜÙìËcš‰àÃw¾0†–DëIåÈbÝ åA+Ø "F"/!’"S˜5 ÆQaþ§Õ=¯×Ôsýšë³ÈH ‘êyÇ—£c®ï5k´ŽÅb¶¢ñŸº‚£´)~ëntKÄýÌ·C°`f­ëvS"íÇüæi½I3R‰'l!›b«fx¡_ÂÓSŠÿ°ý™ñ7§‘ ã^Ï ÉÛÏwÿ©üGÚ!]îð²Z¿ñs¿ËÁûa ÒÆùñõíÅ·õë‰Ï{Ò—âõBàÉí‰Á+-’eç0ŒÉËx†å׿½ìÀbn2„s™x¸«›³Ë’@’Õä4cÄ¥hkŽU2?ÕowxJE^÷œÍR˜mÎÊðɬøÀëV0xN÷ŠÑùX@YÒ5z€ghsz²l¼hÔÿêfjÓ5Æ5h}¯½öâÿVàŽ{ø™¤¼ßÂÿØ_ncþ.>n äohç¿E|`pØÇæ ÿå·þ› ˜Œ ¢º;${3”¿ySôcÕ&­k®ö×’wÜÌÈòá ‘¢ïÝ3X7OöÜ sá“~àN+–e9ù„È™€ä>_={ŸbÿÊCsÃÊ2Ýóa ýëž"•fg«ÇßC aw×Úäù X´òÞqçÈ'‹šÎ\‰w·eI·6¹g˜¯tS½¦’[mÊùØc1GY‘u=†ÚføìñÙF9&C±Ès®ÌîÐx½JRçÕw‹sZý¦a ¢Ú"÷wê‡ËøÚRùêŒôª²þNcõÈÙ›^î¦ùS%çWZMYŽå=X´ûPwúyV‘µ_pc_ÏišžgVçŽû_ˆš£kT§/á"â­©¦ž“]ËŠ1¾™½é'e^÷õ…“«ÃÃCGr‹%çÇxš¼c:®bóëаûÝ´aÚ¸¶H§×'×sæîSÖå»ÒÉ«­ì5¯Äß§„V­-ÛBÞ¨õ_ÚT¢Øf;‡åv†Ga=úYK!á‹ûÕòD’_.¾1m‰õµîåÄ-,xšºÅ'×=+Õ º©…%ïihË/.C¼²Mž¢´¤[›Ï¼â‰±©nô3sûì¶6†vǰ>¡÷":å玕÷4`¥|#ø,v+A,…С Ô ¤ùh£¥Æ{ºðÂú[MÂË멇n¤‹þ&ü“[‘®5rønoûÁ žJrœ´½ 6Èê‡Êy[Ý W³ßAŽr®eç(«RüÿTü©:ïæ~ôä‰Öh_a÷µáÍ¢R£M·ë‰:|9yéoKhÑh°S;5Zë½vª?û„å^Æõžó+ÉÎÜ4þO zm™XVóºŠZ¼¾À{ô.hn½YŸ®¯8jßÓh§b„Á_8B窮_ÚXË)NZ¦4ùêè¥Uí÷r&äj+†ÍÇ …›7ßë%ÅõSüÕ×¹f×£Òµ—>”• &2‹tÿ\þ_ yÒÉC¥ë|•È›8'dç›bà`½ô¥yQ¶§ÐS ‘Ƚ«&zÂíÑ[ûÉgÁáâ©„ìôB¶^œÊ×4 < ºm–ßDGà(MÕú¥ÎÍu_ßÐc:ÄpäËQ®J‡ÉóûãÝWf^Ñ们ò|ô÷¾G`mª\ ªlL¯fI‡WDù>Ó‘øikØÅEqÁ\Ç2éWêŠ?WÅÔûìù@àoà?Ç/71W¿ÀßÐÌAho ä „ûÂ~õ½Á=Šy<›\1G[÷.¶âðeª¤¸ÙÖ1$]gν°H?G5«çG{ÖÿpIÜ ~P®{4c£ö¤™AûJcŽº½›UMÿIë¸2ƒ«Çž`y4­#ƒb{VOßi6±wO>ù<1‡Úf²|ÎdÎ{!öÒ€£e’Ûç³³@ÖÙˆ3uò‹z‚zõ=ð\±!AÙѺ8>ðƒ³Ô"ÖÄ•³¬DÂô®wk<ÚÌ·Þ:~Tê?i(õ¼øªà‚Øu:lƒ9@'Fis¬™`öØ&ã hcÉ2—X%ÿÍ·O*˼˗&yW(šOÈxJåЗ=r2RŒl¨óȽèfV_sMÁ½ªÄÒB¤¸ÑøŠWB¯qhx”½ÐfHjOrH¦«+søËÇ áR€ö²à,™9žñ=_DG#ÚαD¾iŽû-øÝ|ΕAÔY’™—µžxŒ´ÞÞåjkpøYþ3]?ÙÒ¢¢Žø<1$¶Ñeµì‘ËÜ;ðc·¤ÛŸ‰¿Íýô3Ý‘šÇ¼èìl)Ï™ÜûH­ÒÞ¯Aíw"Ù*¤ÿ„ј–º¨ÛÍ ÀRêmXŸ¡¹¡ 59‡ŒŠZêˆèºžðØ“-%™ü>î.‡¾ !ŽC Kå÷óžâCq}ç©nlã×=¾)óa Kš¢Múþ—ÒI§d,¼Ä£秊“šŸ9Áà09©ÅC9²,†åUU8öSü__~Ý_@:}¼+~ƒe 1¾þâæ£9OzÐÛ™[ÁË&\f-‡²žG^vmAéÖgz’®÷¼\"¤ í_ã%¶ *ñ\ ÍOc(W=£j>oÌs*ÏÖ…¥G6‹FDý&Ùë¶WÜqÔŒ÷4»z—|OùÚi}+ i ”]p"goßb‰(ÄWëÞÊËas¼Oíp¦¯i-šyõìq†·` £Z-yµ³]ÒÉN#ÆŒÿëN!˜çG“¯Ïÿ#¿ÚÀü]¼Ý!!¿>’ýoô J€Þ $òWOüŰ—cèy½Þ‹ƒÝ@áB±éòÊ ™t›‘lÙÕ¸V|Æ;úÈæM*õGl*§}Kš¸/¿ñ±3¹ì&ù6ÇgüáçdÎé&°Ú "N^ú’ɇ½ ~ÏhÒk`ÊšÈw‡²W²Æ§&¡ "ó°fmhS4Wµë £éH1Y =…Nnà1Æ/]î¦"*§!‚—_„gªÝ6û&¡^YÛYôøý–»un¦ˆ1`#>{DÓì>;«ÉMU‡ÉkG€£ªqFz*šªC5K•RJ­Á2Ëùë 9ý4qEº4ú7´LdAƾGÖ ÓÙR5R3¡ò5Ìâ<Øj®é'ÄÑÀ% X·>¥cœ ª8ÓŽÔ.Y¼¾‰?[r…Ð&´Ÿ`oDT4P‡üŽ8a³)ܦD&D»èD ò y9-h¿JÚkvõÔbD÷­DTÏØ†¨Ðgòŵ 1r!&`ÊÛ åò7Š%_hÓ»C×#4{"M<‘ ª‹ì8îí“N§DÊ.Κ´]Ž˜úl‘ÌO‘lv%¿UsÑAÍósç¹ü­1J ñ‰ Sþó~G$èë!ÝË[*iÏ£˜a½ÞÜAÝ ,FPØ·[DàÎRiU ª›Ïš WDÚïè¼0uÜkw· 3=˜ÅY T±¦pbZ~ÊÀ™ÞŽf((NçZ(ÍCÔ²Cþwàÿd•«gÙì‚Sií¥Ù!ý^8Ó3g'뾕×:ž…à Ÿ6håy+£4ÂËþV2.ší|öÃwyq$þ‚­2ñ+öÄd9ej Gâû%Æ&‹¯}À øÌUy(mA]íY þÒÕàG²Œ@y…€£_“L=æÍ/EwåÓ:#§ñæ‰-.¾ì›«”Õù<9$ëc(ãñ¦1ºzŽta×ÌÒwð·b!ÜÜÔ>Ò¢¸ÅZÀ¢7™yn"—§ž4ñ37äýòEüÈ£'e! ôœý~Ø=T¼!ïuŠþçââðâø3~îµU´B•­4ÿ‹Týro˜•]ôl±š~-wsXJµép¤-&¾vƒ®oÓøâÖËKiõkéÅÔ¾áú÷^†ŠÜ“p¹°²ŒÕ î È hóñ¼„[yî=¶øÄÿÜÀ§×¢ŸË¢n·]÷Rúe ýpUô¹4½Vf1ÇóÍBóXBûÈ$ê“=aP'–ÔÞ2a„ÎûfŸl¦‹¿%ƒÓ•÷\~Þ4ÿ ~±yù»€\þÞÊ— g0ÿú@|¿øÞ?::µg¢ocjï¼£Ö¥[3Þm–$ê–&µá±Z í- IÝâN?ªœxû#™Z&;t4¹ ™øµß2Çf©ú¹{*YÅQœ”›§4 ðÍç IigÛŒ”ói7;mÜh¹Ý¿ºŽ€è_êh1ÒÆŸz–"˜÷bt^æy b$oÅ£©Döæ99’^½zŠ2ƒ{ .EpªK®ÖóšOxDx—U޲º†i_étË3¼‘`Úãf`hüÁ9˜âö˜REwÒåƒÖëGRÉKE®–ÔWY¡ŒÞŽ­:U—,»x ªÏd´?éЗ#þ:ƒO—›T‡oiLsßO„s—¯>4ž£þưéÊ Þv‘}‘'û=×aF™‹×”ó…í묎½dt?ñS½œÊvòTlI-«iy¿=³Ë„9~ñ­»ýPÆ[«nã]†“÷¹lS*ÛÃÆz~ú++)’uá=žq×ò§É»xG½VæÊ5Ãð$WdÓšÒy0¨¯v’–ÙïÀßšH¨w‹\áº1ѤW"‚sÔúéUz³úáÁŽPlÆÝ×Õ”ÅI¸«s¥ ×-LO¼›‡|Њe©~µõGâ?¸ íä³êsæºð0€$/1ý¦Š[WÓCŠ7­osƒólÁŸE|ò ]mdgžâìd«‡™ªy@)")Xí·~¿ŒKæÛËŠy½’·[ËËU‡°I ²ú¬à[»øÏBâ($¶ÂØU–ÉokñèŽ[Aj=k†W¼ w3—6fFU3 PJbÈ] ûþàKc°%Ø/fï¦/ûÃùO’q#ŽóÁeåM¶~Içòu*»Ib>Ë®.CfÅ6¾u.릷FtÌÔ•ò¥„@“ÛÜîÝ,²¢L«Gæ)æÃk„ðN¨Ï±ÕE~ (W̺\9¤+¼ÅCpÔø¸^Z-I^<õ)¹ØÒèwo´²F*8jâÖ´ˆg®ƒÈ_<7\íh}”“ª<Í›o‹·eëRGùy)÷ãhÚ£YçÆ~òêc“²EãÛêƒåÿÁ'æ==Á°–ý¿Z¶gPrË~p܉‹ztœ×y#öôMå~UKí7#ž´‰´62æKËww0¤V¿^0-¹J,È| ÷4¡!ÀhmpæcxOQãy7·ó&Sn¾Ä1 êc! C5RV|´é­œ'(~µŒ ù&²ùx@jØÂŽíü;©¦çRó3úxéj*kOúƒùb=ºô>}šb¬ä,Uõ£K$·”>2wXìÝJ«”¼ì±“*v3±§TÛ[y…Ø ã6ºŸ) í4ñ›%hå2ªÒõŽÎßò¦¾®ïb£÷òNHO`Ã?!¯ï˜ùJmî…ùª,·¿=¡|~Õ´çËžª€w^&"-—t—'OÌÆXäg½î„‘³]ÊšŽLã-ÕtYÏéÈö^VªEŒÇǯ$DMž=ëL6u÷³µU€q£E×=7© Ýø&Á¸®D'Êæ¢…9…ò³„%ÍÁO/É.®Q¦‡¥ÏO¼v?ºÞÑâ±æZ¬#ÝQÈ_hã§ &|3äL"XÔ8ßlzêÛm|·g™®í3"_vžbá²jô‡tËä¢À—ª»œÅ”šÅÁ¯ßx",îØT£$˜q«Ø—Á§à©WýMË~n¯ìKß¹k8cæ'õ7Ö_”|®<Á?5µÄ\µ®Û]ËÛlIŽm°2ÒIM-`Eû¤Áñ¦`ŠÏoÀ?2–¬Æ‚Æ„x˜‰f:¼“êtQÏ¥¬ÈI_XbÑÉèµøBîâP§KéKz³<—MÎ/ûéœl.󳦰Ãk’„xýyøOè ¿ JÏʯOúaom®†Ÿú¸u¶²$z¼¤º¾;U”8m±`Ú¬>öYôYìñ·]‘½÷2rñ$XêÔúk_q–‰<Ú;ü²˜þ3€=ÈgC_†;°_.»ÚÂᓎ~·fW‚éþ×o:ŠPLX‘2wç¹CäCšWÈIM—97êïõ˜yõH,ôûGl¸ÔžÑ×n]þ)þÚ÷Ò±qt.oÕó) ýéü÷ö¯Ì>qÞ ‡…‡Ëa€.KŒ•W[N¸ú•9¡ð«Wô’Gí¹F°ˆýsÜÞÄ<>Œ‹ÂVNUÔ=œri§8Þ肘"×›) I³cèzàãSßBTÍþ¢ŠŸkQD›¿Í_F‘´¿G¿ç‚Ajö”ߟ`R̬ò¸9aAK§ÓEÁ‹£ô«ÔWbøâ{}.¥¶p0þób€÷œÃÏ<®¯:Hþøº<€+äßÏþýeg‚Y€@þÚeû€­oný“š`[ªéCµD®iV•@ÙC“8µÍ <ìÈ—‘¥Fq½¾O»78æÝ}u±¥#™Þ²äÛÆi¾ýtÁ·´•Ç‘uàë –Wt\äñçü©¬­tŒpN^jqBƞѳ½è)8RÀ¨™Ü â8!CüM2:üÇÞE µH9G@%îÅ8™l™dÄo"åï¤Ù,~ÇÇ}OÑrDÌçÒ=öq•ÁD|™;Gñ£!0ûÕÑŽ±Æ1f²7ÏÄÌY–ºíqÏÌÉ^{p_¶¬Èì«·ƒFÞÅ\XéÚ<ô‘ (%K‹/ÎÀýð/)»ÿà3ŵDðç:ðK]-Ñ@"GCIcƒÈdç"[£ýí²<Ûh©IFxÞ i,ùûš*ôúת7þ4üß¿ NÒ@ŒkèUºg$ñQ¬s³Zûò8œÂ4Nó!lóX=¤ùA_K®Œ6aõ㉰ESóŽ[ ¾ïòª36¼% aõñk‘8ÊŠ¦…GÊ_ÁêÝgn)^l ˆ2-Ì(Ž÷tá<¹{7•¬/‹—­ç’E än<þvDÒ°eRðà5 Éíñéž§³9vÎà :š~Š¿ +î4ižˆ75SòŸÏÿ÷Ä$ð‘\2džè°^\V¶£ôó:TæCÚŠIæ0¶ ?Á>bVÑe·;,…çf "à Ÿ…JN7‚8ÛK÷DWäwàš‰wN€jhXÕ¡Cë]”óë¯-_óªûÞåf/eé¼¾ì¨>W¨ÛNŠÏ!c¼p5såQ̼ª<ù碣žJú¬ú¢wÜ2è‡d–y¿Ï—©3¯^á0ud 8@þýRËòâîåtÐmü÷ ß³ù0â×.ØçhÀõ[=ltlO!%ý±Å®@ÿ¥¹¯vÅ Prc—Ö0¯B**»wR$µM…BÎlDn]û¬l¸KH•d5k…ƒÀŽ¾Ú¿Vþ‚¤NO„}Ë=@[A\ñ¦iT¬N¾O„JHžêI÷€ÆŽyrGß~pU'!D…߈$Twb-Q=÷ˆŠbŠ=gµ ôîèD…RÖú%fŠõÊpìÉ/ÖãÏÞ[®Þ¯ø†{¢tˆ¬ÿõÚhãkBÊ„¹gXÑqmó¼Ñ«$ÔiýùæÅ+ŸJg²…­*­¬Œ¿ ©`¦)ª¸þ¬Û—B6o]Ò½qÞÌÚÁß”¤üÚ*±…«ßjžC‚"”2ÚŽF¢ÎÏ“¡3òü¸p9D”ÈMÒ ?~ùtB{i¥t¡i& õm>0€)p~™fHœ+Q¨î%`ÞâÝ G¾)>2¢0ek佂ÍãE¼4ÕsJ~¡SouÕŒê˜ô ÁUå”õúa'eë:‚.¬±k ­|`´?{ìéç;_ˆ¤©Ô[¸µÍÉÂâËäj_zœZO}‹¼jf;’C't×ëYEù‹Þ\¬t„‚Trq{½Eä¨?‡qxÏmnõ]w-AÌ&ÞU8§m?”¬Žðk]¸~Ì!‹RËÝFü3ø¤ä«§²Zñì mw?=\mY½ìÛ…çàñï#þAùÐ7¥EYI#óï}®´°ä›C8´åi¢Ä}2ª?vä3\G¨øfŠH…vÛ›sr2=0Óä‘Ô„d^PÞºpxùÃ? Ùr0T[ÆË­ÖVJ ¨qŒ”ßÈ®Y§±6'|:}ß@¸„èÆóäÚ.D€Ú»Ô!ü¤WCÖË“äŽbWíÈ@œWÌ•${‡n(¹ŒŒŽ±V4w‹GðsZÓXu It*C¢ZöáD>ö·Ÿ!ë"–eIJÞòÑÍ8‡8Ëz$~…§ðp¶Ù­¥æq ¯oužþ¾¥/–gÓÿOàÿ­±¡M¾~ {¨NÐ[µê{¶`»56õþuI2Ó¥§u ÃûØ•þ 7ß=,zêwa²Ï5µ\]ÅÅ{›9í%%½ßEsýÓ–·,œtü€«yêñU›x†vÝB-‹Øh“%÷±Î£eƒn1Šd8ž<+Ý^bC 6]O‹Eu? °ßøø…÷Jh+‘û2üÍAãß'TRËìDY‡¡ó"®Úáãÿ…_iWþAþýìßÿNöf hgàW/øî€VªÙba&ïS5ð^&¾H_¹í`“ÿð(}„þs §«-¸ç^!`6‘RLg(TI·LæÁ̳ªÛ)swÎM5¼¾!“Šš¸¤5$Ä5/ÎÑ–ƒO2¨óI‘ΛBNº‰ƒHªýC.v-äXÒ,™×<”Ž3A£²Å¤5ÎZ±¦]À‰8ç\jÝ÷ô¸U0YGÒØñž&aÔnɳñ½£Z"~öŸœR^®6Ñ6â§°¶lœ°0rÖ'dtL—Ǧ{S[7Å×ç·&übQñdl¬çÂ@ …¾ >ý%¡Tgl¹gæ‡/l&dãòB{ ‰•â–×u:"ŽOLeåѰIÝ›`á v¡ð3 ¼ª<{ȸ橖ipsTÛâ¾Ö¦šHAÂGó’¤b@÷»å•+NêŒgà³£Ö:rArwÏ”ú•äŽ\GGߊ÷ºÞb^âüH Þè0»ÊN›EÌ8¡t÷Îs‰šH…âó‡¬ä€ù’æ•‚—¯nðˆÄCqÂζ.ôŽJ¶O|1&½).%¨á›â•òDKÓþ~5ƒ–ù#‚âAÍúìpü„;'N5¸Ö5ØÐ»§%=ÅJ:­,2 Ò’ ‡rþXìGµRºÒ)E Ä«×pQ’¬S,G‰n›" sCL<]S¾çÄùÔD¿’Ít‘ )ÚbA3½ÐþÛŸ…݇O¾G»);Ïê¦z`'TÊλ0>RnËhœ`½õH[ì‹`q:VGáš1÷xixÅœ˜õêÙð‚i½4ê'¶­hÞðTtŠð0–¿ã€õ[YÿáLü¡â¦sÍã¦).ņ›Ó·÷ã/âåUvúí׆Z­x]õ!˜Í§i­wÇ|¯œ|ޝH­éXø‘Ó¹¾¶¼7+öñçøÃs{ƒ?¦×pdòšÿgðÿØù¥b{-¹ˆù”ÊI|ýzE1Ç­ü ãªÁ¼1×´É<­Öàûj}r²ïìOò*Ü— øœû…láÊ­«x`³L¿DjÄùÚ夿kPûG¶7V¿Á#jZ^€g­Í§ƒ¬úu¥ZQya¢IÝWÈ`"33‹Æñ¼DÅ6s].3·:O¹)³ÕºÏÊ>!$^uàø;¾Qp­ÆÕ¤0ÈÃâ6dâûp@ü§ú•få ›ÀÁ6ñ_*>Ð}ì €#å2€=ïk>¸†FëÞfõh¨Œñ{ R-K~ð™+1B•ô*‘yfá'³Ø /e¿p(±¼u=wbà0— N"ŸFöuaÜ`9B -c'0<¡ÍºWŸÒÿ¡ó¥3†½ö‹ôø CÃ|‘N›d'®ÜdN•Õ9Æv?‹»,ó|þ«NŸÏž“R·Y$t¹çd/dø4LŸëJ|C°¢k*”äUs8"QZÆ¢ÿ±OP¼pÔCzÂ×ìÌÓ-È£îg´BèBJBï^ïŠsË_»ó¶”øêv«‰.Ü‘…ÏÜÖ…x„û:B¦î;| º@yȽ|ä´›/ÈÛ+à®u´ ïÆ²H¥<2üRhJŽJ‚7ÓÕÜI°D¨Q[¬%7ùiRlͧøÌ Ó—ë ý¯yÈMº¾)ËÑc7ŠNª(ç¸ÈayX  è½Íbv‹¶1o+ ÿB u2Ë bý/|!3Öî5êk¥Ê5ñæ[]nÛ:O ê<ßùE§’ŸAÕ¯ƒÌAiÆcÏJ™6e¬¦XWWèX6ìádoÎ oŒx‘Ÿ"ç„HbßårO/~â§:pôL¬ðÁãï¾¶`wX3©ÚBÄ#£,å~–G²¹ªç;oÚ”¯O¯ÌÈœž{âúU´K¹‘Ö'">§ü¡[¸­ÎC¡O¦g‡õ±Í û¥‘Þ€´EåM‹ú0Ù‹äŠQNf>Š‹ôŒ*ßh]YF0Èh±Îø)ä’™DÝ¢)h€²S1…úð{Áß¼ŒÌÕ–ç»Â®Š  uHN‘›8=¸f—Oöï¼Uf)ÇÆ×Væ#p¢C£R'õÝ1îÉN{ cš£Î7 š¹Êñ5j²²z܆8£ÌHžçcíp¤,>­Ðíë™!Z›îKŸq?•©¯œl¤ <×ýüm»lÁ»²%b/Jÿçç»§®©ÈdÄ#C“×tÑqÁ3‘qÈ9™Xb¥&oñœPµ8r$qRó؆)«xã`Ÿydw·Jè|ð<í’Ö O_ EäE^äñ¸ |ºvÏQÎì#±¹Åb©Úwi%‡ÏÖ®É'J*åp5†Ó-ÏÞü ñ×§¨y;N…ÕzYëXíP«^úÔÇ v¡Ç߸¦… cŸšÖqáV~SÝ—§ÌBz·¿Š(ÕrÞyH©1>´]V4Û ¬¦€»iõÄòŸƒ"^Î#áÇd½Žî@¼î·£Ó …ƒ¨" U¸Ë__z‰£0dKæ‚#F|;’}¢µX^bc&‚͆ùNËã×Ä‚N[×™Þ¦‘Å·t—‘‘nœÌë„0›I)-=|Ý”ÉHZøÿ6Ã’WŠ—¯(L©~y¾¡pÿèƒo,³uNVà™†uAZÈ¡|FÐÖ0£t7ßÏñïõâ²k/^,ùá­ñqÄ‘^L¡ù1×|žêùúl9£E2>Tº†â¢ ¤CÚ ù—wIͲÔïÝ;'šÊ™S%Vb‚'òÞ¹,{ÔoÔl1ŽdïªÇÉ^â¡ézßÔšQ=}Û‡Þ×ÙA¯öl…ä|Bºƒ—£Ú·Tx¡Ã„?*L¥¥Ö|zD7ydüe|áÒóWY uDé´ªÓV5 è–·Í=¿zcUóÀ2³!ÃÇ<lC÷l† BRN,U-#“hiYô5ÁÉÖÞ*à¢ä·÷íúÉÆ!BîTúø²ÚžW(†ÀÇÌÒ>@®p¥|óA|ö0­<åðôåê,Í{5êÕxRÔ{Zê°Äµµ!ùRéÞ¢^äÄ«™ó±sX*ç‚Zð5,Üæ—ž’õ´±K”ó»'?±ÎÀý\»=èÇ1B^ÂRW†N䌶ù½îh•Í•ªiè³î²8äÕ9 ªG73E¼)ʸAwLÍ¥ù”«ju¥« (®À Çsp~S0–âšd«åB®•ž¬(£6ë-—,ó½§j¾-ΙßWCYâz‘ØYÿåáQE×OmNÝ\æóÙ¾¤ñ¢ã«æ%§y©¼Ó?þHù‚ iÍ.ŧ>¤åÉiRNÕâ"nV~M‚¯>[i$%‘ Å¿vÔŠØCA•Yù1¾¦ÕÕ–£fÅ«j êÌÎq'GfÀïÂÝŠÇÒÌ7ôÃF]n97…­ºfØ”—4×ÓTd—Û]ôImtç7Lì b3€"™ªø•N_Ð¾Ï Vh9ılí~c¦¦v`i^ Ž!ÿôª§›ÜóëçL­ô55u‘³óFѪŽ¿Œm»ã9_ÐI0®²7_¨[Ä ¸)wœleÚ *÷ÔíÒàQÁûaî7†¾üêòãRQû±> q2pÕéÓÄŸß.‰þúçà?ô4ÔoÚ §É± >¨-8-÷HyÄè•T^0ž‘×¹ ó¢z–?é±tíœá4…ó,Åç¢Ú7æ÷ØÅ gŸÎ3X6’ÖÉ7N/½cÂÌëß+F}a9ÜŠ=gÜ^XÌmFì‰ìIO¾äÞµ¿à¯n¶Æ+ZŸ¥=YùFÿ›KýšÝ²Yׄߤ\(«ÿ»*Å Âñê¢E®öæŸã~íL èìÿ5èYoIS/ÞÏôm >‘×ê<ûNøÖ®òÈ>lÑî¡Ñ}FXëÚµÓkÒ—¨Û©çÙ_P\WJª«¤ áÉðtM Ñø y9˜‡ÏÔ©3ÜPaØ|î ¿±IÍÙo›e­uÐíÏÅ“ÝLJ Ž}+£:q,u)¢yœ?€”@õœú[»…‹£ sæÆ‘ƒÇ¿ß–]²-Üòƒ ®±QÍ+Ë©_Ïÿ_fOþQ<<A¿ü+ìþÿ"?Ì@П@‘¿nÀ¶°q|…fF€ î4ÞûE@)?‡$XÁˆFcÄ5dYyW±èžPn—M•õÆwöœÏ;rXOåý{QܹƒŠ§uW¢¬š©ìê ›(põod=蛇ð³žO×®Çaz“‰iìÄÕðÒ˜*¶¯à-ûoJa]äç.úÑ3{ñU®¦xƒãú©ðKrÈ$sÁm»‰{…ãþç%ÚeM®,l=I§»2ÓR¥¼G$K=ŠÙ—‰oø–†š(Ù¿õ+¶] úœ%Ä”h/–I¡¢@zʼ–‹!çq…0¯Âû•É0Íœj.è‰5ß ~{ºÐŒØ®°­a›á Üd‰tð§ƒÐÚžÞ¢Š\~ÂznÍàOW°“a¤°3‚Ë÷àâ³í¾7Êy{õOzÔ¶mRÑ<ñ¼ú’œçP­iˆdˆ¦ècßb©³ÞS64i·á&¡ÎØFJpÛ–Áxþ3Aº7&šÜa®9ÁÁ¡ck\ï²63SÛÅÖÌôzÂÚü4L¢;p¢¾ÔªækŸ¿H~ê0I)¿›…–\¸$¬Äñ‘¬çuœN®&ú§Ws€C≅úcìr#4 Zˆý?q¶¥© ùUWhkš%õ›\p¿ûÜ $uÑFðVòsbgäºb1tb ÷¹ø0G»6™ÈI»¶ìÐ{Iy›,W˜Ô¸ž]?;`üÃÜ–8âi £YbžÕ•1Ź?z÷ågFw2¨ª¯¯"Á¨n¼©žÛ1Y é÷Ê€çAÓ!„Â`èm¼˜¦áµõž·C·ì†ÄuŸcý)ø“®¼hX Dl‘Q夈ÂôFÔ¹º¥Eš¸»øÄq³µHœ3_¿“éEÀiHÒ $=/´Dc_5nxåÏHä@Im|®)lqø+©M“T¡O²M›îuÅø €‘ 9s±ªöï)–"¤™ŒÂßð¯ÇnSdißpÌ9Uw?äã닲q’ë¹'TͮӪëâšURÉ ËMýSE?ùuoµÿ$þû=ú `§á 9bIfáq¢ì~Ù{™Òžö£ï=zTg–áÏjðÖÚ¹¬uE~Øñâk^ahtüTZÓm&hÓõ/«qÔLÞo¹%-ë ï²jUtð´àÛŠÉ/ƒä®I.‚ujœtÿ@i9j‹˜x¨¶Ùù0}eH·½/ÑÙ‚Ï«µ:õ¡šö1¥þÇÿ°ë#‰¬Â‘ȱÌihì[Ze_ž_Íí_fOþAþýìßÿ‹€}ñ@>@دûJ`ŒÐíœ1}@‡“#7dK0'ï|”Ö*Z]³Q/çTõ´¹ ìF?x¬<ôÔ…ñ$wœjkë\÷~Õ†h (T­MÕf Å÷4Q›u°qhmÑb¼W#}ÔøÍÔI "äžvÙ»¾)¨äÛÙÐï ÒcíŸ÷f÷Xõ:ßÏjSrïIU`üy@d|¾gw÷g7('Ö ûQå9âu³®ØNMs 'k{›î[ uµ=n8–‰*¿}6*¼c2× ÄÌã5—÷©¬Nzvd…u¶« ìôžc´»ƒwwî†ýõJ:uÑŽ÷±Yb}ü¸á—X_õ\²£º ra2·ø*$ý- â»Ô=ìó1'©Éµî¤2£hù(ìË#l¾»^|íþ/ÈpZ¢;šåK(O >’Ÿy–’6˜ 'm©å§&>0 ’•;âúzH¶ Z´)ä™SÒ¯×ëZ.¨ú$Ç]êœw£J¹‘OÏê¹çpó5]½¸VhˆƒQ¾a>whg5E anßÐ3ÎÚ«J‹«×ƒ” ?%ð¿~¬APv*Æô×±Ê ª”sBÖðRµhÏS©ý[ª_*z˜MC"Ÿ„+Eõ@xï=©¸$ZÒäu̪¾SQÚ£@ëÉéÍ.B):%Á'} Éúºw•2åk°/$ÚTx\량aŸ]8I‰uÜôºíãŸÌlÀs³½Aú>_µ0ËH_½¾ÈÄÀ¶àì|çÍGz¬“½5¥Ï+³mž;K«ˆs§ãµyÜYƒ©kV¬”³Ì­¦ojW1_àOW6Õn6’ÅOþ3ð—!P‡ˆ×i­=£@”¤®æ¾ Â%ÇϷሚ£ ïM}¢æ9¥KGPxÏœMNÅD+Æm¨´û%­¬Þ9fÏeà"eÃÐâZÿkÞiµÍëŽ6MMÚ—£kïœróÐc6ÞÄ{šöwüm&–ˆŸNÒq9%cÅeNÅ=ë.ûå MäÐ7§‘ëopÏ8v‡R‰þUŽdžÇÿYügv²Ëñ¡¹ðÒêÍÜf‘\R›¼èsS{\d‰5n9­½Qv銠»›€#÷Yßàr«ÿ L}{ñicŠø áY£•)–_>ʤð’çç¿Ñx,ºÉÓ_ü°ÕÓOXŸ-&^ݸÿ¡ò.™ Û¡ªÒÈ¥@ÁG˜~X¶®ðÖùþ§ÁÆ ªÕ4´ì|çÄ‹™®Ujp íð76N•ä XbTœpͯå?㯲&ÿ$nÞÿ~öïÿAþ:€>åý ? ˆvVïÂFœFb,6Ìj)ž[Pé>’Ð[;ßvøŒÖº&]¯'j‡n®h7®:ÅŠ]»êÀá`~³“àÃB,Žã(Ð?i‚9hËŒ‘‘,s‰qú¨ö#„}w@>ñˆ¦99d‰ÕHíˆj¹*+=뻋­aX=øªG–©¡²“xUÚˬ8×7Âú ²¯„ï ,/ÁË$W2ü:è¡(ã³6ƒw)7Z³OѦnkèhØ·ÊŒ0pÔºçR‹PÛ½O½IëÆ¼pxÕé½C8³a‹®^Iúì5ŸåR„ëì”wøFÊ4 1G'7Ç<†ªµ~Gޝ‹¼ò_ô¾Yñó/½¾Fðöð{Wˆž‘õ´ø,^†éRÁlkqŽ·ôõ%í7‰]wmÅÊ$¤^­6’¶ËÝ­1Ý‚qãEÖ]þ™ w]tû’—…3 Á_¯¨\SÚó­ˆ·.ÿ›_XüëÓb€¹sù­.þ²† ~/ÜšY&Œo‡Ï%7*G^Šef9¿P"F¸Ú}Ž<ªïÙ¼åDd¼Kä{¹)¹#9ÓÍgá_äuN,4p¤?“¢”]x*¿ü¢ÂþÒ ]‚ ¢m‚7–%ûqɃÜD§ôj!“Tù‰Pö˜Þ0&ý{-…—„ïÔçsê‚ðqæì"f¾’SMeŸº?@öHÝuÀïØ)ï×.t3”kú÷¶x¦KJ¦:øŸå f,þ™N.2ù,œÓ©#cÜØbi„Vœë°$g«e²ÖƒƒñÍ»š=^gÙ2ŸŒ صV¸-«Ÿ¹å@ê?í}±žW±øÙW/þiëŸä}y¦sœ+™ ±rD¼ÄÓð—òßúÙ’Ÿšøåùå¼óï Øßþu C¡`( A`Ûu@(êìD Ñ— ê KP` AýGC  Ttç:Ô…`ºu»í›¡ë Îø€•À|ô·n·ÿÃÓ!0ºý}ç^>Áðíc K(êæ t˜ ú·Íöµ Õ.È#ù~³G„~ÿÛ>{û¢6 Ìà·ÿß×/ß÷‚}u€¨K@>Pèvödû™!Ûc vNbŽQ[ôõ ¶{nw0Až~è{£¿Ú Ý{x0ʯC_ òAµà†ôG@Ñ-!0O¤/ ‚£qú»{` ƒ~w0”ûë! È^÷P¡0ßß„±/|÷ÜöÍ0½‚¢»±ÝOªŠº ==ÿdü=·ûþ×® ð‡îa²ûf£ñ‡ïõrw0ÁžÛ|ðBÂ1°àoù‚(üüÑk}ÐCx"|á(|¡hœvÞ:è.¬àW „@Ž?äû‹»ƒ?ìÏä??ê•ßÁˆ^C„¡ÊAоo@èæ bÿÝ:Û½=f ÝЍNÁ0¼C_‚zLÅí“;#…Vþ ÝÈÞ.ê•!@®Š? öqƒþ.þC~ƒüõGçþ•ÿ›€wð:€1û»‚¢5.†/`´@ïa˜E÷0Ü­vJÀ”%ƒHh»â6Å1¼@¡4ÔžvßÖ0è7UÅE’ßãÌz¶»»KL0Јyo _è~–ýåyöÙ°yùÁ~Ð÷ûÔ÷®ŽßÑÿ˜fÀð£²OaªzùC¾_ÙW@xÃ@èGFo0ÞV3Àm;†î©X´&ÀPFýî ¥âüÑCøaJÀÅŒ<½Ü}Ñ}C©5”ió @€ ð}4ú»@+e òå¡ß·•ô] ¡Á`¿ßƒ̨aÔ0Ê^ajƒà{÷ùî ûéþsñ÷„ýƒÁ Ï>Gc»dÿ}ц èíÙõñÛîFb0Bÿø Ï`”Ç„U ú·À½(+ï™oŒ ÙÞÛ=Bû™?ÃÇØ9FáÿSùùÉX( Œ[÷d?nv]pôŸ¹?¦ö\hwSŠ:‚m¿õ¨~yûb¼¾Íám ¿í9`nìùÑ+€ì” ðwó?PüH4þn~¿…ÿ¿ãÃùÿ†ÿÿ3ù€7ã6¢½x0l‡`4¯QožÌãqîÆ5€VÉHØÞ!úB¿v»QÄ^ì°Ã$Ôåy$;ð/îÿvÎ@¾«…Ó`×@50qò?}ûTõ®· `P€ïž®ßï‡ï·àÝøý¨ç|ÛèüÀ\/ßï†cÅÑ:è‚ÜÑ?h²·A üÝÎo&ªßÓ!h_}{u'º#pLû( B¢êÑÑ  §W/ TQCŒRºhï¼·øãªt_¸KùÕÀ £ þùp´ÉÇTD‡úû(´E¢5J‡‚À8ÈÇÕ÷OÅß=ùÑꈀüpŒ¹€@‚Ãöù"(£ñ†¢|þÌI€·?Œ@C¸ýÉ_þÀ ôð1I†2";üh÷÷ö@ ÈOñ߇m§áÏåˆ?:àÿk¼¿oƒÎ`H±òà€ïöS£Oî˜o ¶;NÂÔ _(&ð!ð¿TE/ß=‹Á|¯…¿ïÁâD (›Šžÿ~ƒ—Ãÿÿ™ì±âÆí¯X€€@|'Q·í±ï0ð`^ÚmÚcLLß@(EŽziѧHîXhu°}dnÉõc¢[L‹Ðÿ}’ïjäåŒ:‡Á~ Ù_Â4è@¤ß>Ý¿ïžßùˆéž×ö2JŒ*@ÀÿªüQâ„ߠÿ|¼ƒ`0L»oƒ~rÄÎ%ûÜh›ÓèHs×ñFØË=p(‡Q» OŒ@*Ä€¡¯óñ"ÐÑ &&Cg¡ûžêfèaÐÝøî»ØÉ¢·¨ˆì»®Emá¿ÿB þ{?d[îèoÈn”ÞKLZ×Ó#èÅß=¾ß+ØÛìá¿×êøïžÃ$£Q‘*ºyîVxøÃÑ™ŒDlãGáÖê`´nÿƒ°íNîžÄ„î?Áæï)ðÌŸÐüw2ÿû©¶ç¾n§P!?ú5Âà¿cç¿'âv„}ùþà…?h{”÷þ¨Ë|»©(ŒñßæÃŒ™óãAçþŸƒçÿoønÞÃÿÿ©ìºÈèͯ¹¿8¨ ¥`» ãýcx Øù®ªw¸·­@8ü;ï·Õ ¼wÙK!¢ê{+Bn' ÜmŒÃûîÿÞv'bÃ(\Tâ ô…þ˜þý®ð!ûÏïyà{šøBöô;xÇ©ßÎÿîDã»ÓÀÝbÈ÷_`ÞëÎ÷N£lvm4þ–‘D'wôô»„cÔÀn¤‰n=™@ùÞ¨b:퇎ª€~(=7 í"ªcÞî¾~èîðÑú÷ÿ®0AÎÞ,ñ¶ì ¾+€½Ç…þü£0øCPc¶kç·cGÐŽ‘À„¸Ûk ˜ iØþ^&þnû.Ù·AÅê?TÜÞb¦xÿŠ? 8º!0r»A tLÌ· ²mç!P¾ÑÚCªŸâÿýèCÐÍúèxc}÷™à6`Ì{³ã% ñ‡Bv Ù ê!;ÂŽ‹ ñÞI@v×4ìÌìÍxÃwv»ŽÆŽ/€™1u8`ü1«‚Pø»Ášÿoÿÿ5ÿÿsÙEô ÆîGˆ";ýfAw¼È6sÞ Ô«Þ¥=f&ãîïNßú á{Ř$ º§Ý1üß™ ª¹CòÐ1.ÄúÁñÿ®UTäÛ‡èŠÞŽÁÐýªáŸ6ûìØÃ@yÏûŠ¿îU‚nß{á eƒwÁn&5$?²{?ÑÝC`>`ì¯ÑJi"wm?f ¶ŒWðÝÎ`vÑ,÷Á¨0*Àdo½”ÖÙNóú@·—R¡— Æn§£8ì‡`wo½ž „RUßãÄ¿˜À ô݈BQOùð/B?ˆÉkbfü1±Ì®BÁvL“jÞ]DUñvôýñw „@Ø>×`gf€ü‡K@Û`B€ Ø®ÑîâÙ ÁžHز¨÷ €ØÅgƺ£G²/…@þº‡*þ9þûèI‚ÿÑü ÞNÌïlÐI†íéˆÝ?º3ƒ„1ñhüÑ`~ŸØËÿC1Ón;A½·tÇâ£Ë þnç¡PT,¾ýïÏ `ÎÍï€ñ#·  —«ÿÁòÿà×ÿýkÿÿçÞí/½€íµÄ oø¶ÒÜYéù€|á» x¶½L²  +‚@=»£0 ï$!{j­ÜU i!ˆí{ Hýÿrÿ¿³hy€Nn!¾ó³÷:¿Oõo«owøÿiïZzǪðïã!,XÌŠ«A¨©$Ž}ß~äÙ%@ ‰‹–1hþ ÷¼î=vª»†šr+%•¥N;‰Ë±ýù¼¾ó0ThÕ‘Ó Ý/5uŒj“záyiKg¦ú~)Òûqòøˆf.ÿ+/&IVV,V ¼Æü›C+×Tî7á…ŠÀ¬"óÖÀýÉU7Mw]4ë‡0Sq¹†ݘCs꯼Gã[@¿þŸ2þH#þRߥ)€´x¨|  àºCüsTêÿÅa™>êÀjŸÒÀŒ?0ÏXñm,Íõ¶í!ÙŒ?8?Ö Û.:á_š'T `˜/ö<þAJã³õw-ÿšˆùçŠÛYòBQÿD9lN„ù½í¾ðÿèò䫳;pNý (¢*øÏ{4Sµøìç³kàcãÖÆ? „VÆ·ªü¯nÿßÍÿKmxí ¨L ‚¾ËÁ)R±x£»ÎŒS,‚TPU@²¾Ô o͹@Èîç!ü]D2FZZ—ÊkÕU!øÎO¾mà’?.ô[lÿ" ðþ74‡¨¾ñ·iàYØÒXw„d£Mý¼Ô?¹ì$]ÿ¯À±Ðš³œ:¼L¨¿Ìκ0¢’èJ)‘5Ûxþ|ÇDå7IU1Î5À2V-]r€Xs¼6þ?Œ‰M¾8;:ð'ZYûH@&ÀÀs¾;üÛcˆŒÿ¬,_‡ê”1þˆxÁk‹´?°u¶ÁY>&dHÀ¸üÇÓ@]¢€¿”ðGÁ/¸QdÜŸÃ_µÆû—ÿî:æÒžx¡+I 1ûù¸²’âàê¸TNÞ6‡PÞbP]Ëz.C,Æ¿´Òúd·«ãßt%² lÜŠòÿ5ìÿ»ùÿ¿—¥‰~Ýk¨öîÐAŽx7Rp´“áÆ_æck\ Õ@¾Ïº4*°ä+ èÿð›ðé<aÊ F·Ÿ;þúÔTƒ eä§iÂ9-ã¿YèW´»o¹†HÀnþÑÆXÿ¥ÞâE°³#kõgÄÏ—·a÷J¶3Ôœ¤C=ÚåDÏõ…ŠäH3”ßvP„?lh÷§N°±¾‹ÒìëÝ~{<ôHZ¡¶Ç[à‚-5«´ªúõñÿð§œ~´lå$@ üåJqÅ•ÇPiÝÝ8$ovöÞð¸âJø«ã!ªg~| Ã«U40Æ„‹ ðƒ¯ò}@Å[¸.¦×ø_Ž˜pfˆº„_ûå Ïã/Ô$Êï]þ‡sREÿäbHNÀ3õ?½6"깩ÐÏôœzà[ ðwDƒHU€_à?!á Æ«Š£ÿá²6þn,.ÛoÆÕäíüÿ{øÿ²E‹Åš€Ô¹ƒá…©à·ëú©‡Ï¥ñ—~İTÖe9“Á!š5Ðþ2„ïǤ…½Ím7pѶ|׺‡G$ñÌæ8͇¿Ð±+cO»´‘ýœþgþWﯦi‡û)Î÷¯L€ß^©üÏ97$ÍGš„zÆ×"\øk—TUôKEJ úó|-”SGn`î†ÙA×õõ<Í~{:6ØÐ+ì>£°vB2ud 5 Äa}ü{Χã†ÀqªÀŸ-‰Tÿa©s¤.AçÍf¸3ü=÷©CXíÇȨ½u´ªý›ðçL6æù3þ¤…Û‚Ÿ·ªÏúÊøï?N ò!A‚?±öq¹†?ôþŠxò{ö!–§Tˆ˜„øs/`ÂB8éûà ávSd2%T|ù ¥ 0ãïJªEuàÛ͸:þ ø$ÝoN+ÉÿÊöÿÝü¿t™ûÅðòš×±ÜD¾°uè§'“&ÒÍ^j~tòýð@>0•¢jÏo¤oÝ7߆…ý““êh¦K(2?çsu~âà¬}xœ•ÖÜR¿ø¯CzÞ£7ÓýÂý²þå£ÂÀ’ÎK;$%ÃuWÚ~ ÜO„eÍ@)ÑP|ª><Ñ£n-¤¤ ­ƒÞ¿ñá9*‰ÆŽj;ßSÔ ‹3;sA5ZTéF­Ðî øLP€üÿÚøì=ñ¯ù¤q?ˆÞ/·ˆåâˆCà2þÉãä³öÃõ®ð÷ùUÄ¿„]” â ÑãeØ F=m€?~ˆò~‚ìõ„~&Íñ‰5ë@ZbP«Rß÷ þ¸û§oCþÿìâXå^þÌjöWá™»ÿøÔhß’€Ë0ËíŽI4¼m۫έÉ65°ƒ‚TZ1  Εîך~Îÿ²^‡€ÆH¸f`µà#´æJ¤A¥l(v£/–̳àK;G`¼Y~KYq _€„àÏuHÊrÏ—wÝf8qõ”‹å:è *{"h0¬ÿ?ÿ:¦Â#sÞ?@´þ¡ô²×㣪®Œ¿xS¶ÛÞþû“ܱÄhónÿz—ýÛTöhb8ú1þy1æ¾åiö>VûP¸\òõ—ñ¡¬½ ùw×~Fhsæ¾vlëÏøSd þÂÿS?_Šæ${Àn•þðÞøaVõïX‚ÁOJv³>þ8e ;Aá²ü‡5ä]ûÿnþ_¾øÅ•{e€ïÏóºŠÛn:¨iq0(f÷àVeÖOÔ‘‚x7;]BâŽá[Ð&?óá»I‡„[ô 4×gHÀÚ dEsƒhnã¹pm5ü›Å€›ÃìùÈÞx¡çæÊ>4¥$IëgéO¬9` £“íÇT›ÿd¾/Öú«Yÿµ½Þ¿qù,á¼xs ®ùýßà¼b0&+¦6 Þ yŸð¸•î¥'8³u—!…¨]C­Ê§éf$,+X˜«À ­Œ?ôþI¾ØFzü_Oô0à_x In¿ÎÛ¸æØët@VýÝÃåNðw“8øâ¸rÀG=¶´y˜ÍYļ˜1ÚæÛ¿“™ÝQ Tú{¨[âŸ.e¾áÒØ«j@èêy´×oKþ›Ç¾ã\ßW‹ü*‘v¬±‹…àÚ€'øÿêPà¿àÿÕÛ®ý øÃ èh ',ÀŸšmûÊò¿¶ý7ÿ/_–@xe€Ä“®¿#ÕèzšûE5@ÕÝR-,j€‹yõ\K |ôÛßÁs¿æ®°v¯‚›p+ÿôèÏ9Õ«ž Ì‚'uÜHÞÉÓßê>#G3o\øß QÝÌ x<ÿÄà Aæ·®½‰þI±xl wy¥§Q%u )­éŨI"ö\C»ßn8&Ø#ôÀt²Q€éž_¿w‡Z€OV·†²ò)t1Ý@õð¡X‰Ê:‡õÿ+â½² Ñ%¼š€FFƒL<ŸH©þó€??4¯“ov÷ÿö2 âßhª·þµéoöCø£iÈŠð‡‚ù™ŸCöî[üñÉÀ·5€3‚Oìyü=£þ–äŸ Œ|ú‹V~‹ü²Í¦‚‘=øñwr ’oг4ãÿÙ 2À_îGù}å ¸‡óWÀª1» ìí‘êþ3þéUåÿkM»)àÖUxœì½\T[×?Nƒ ¢H‰” ÒÒ©‚€tK7ÒÌÌ™†I¤»»EB@J¤•$D@TBä?C¨÷yî½Ïû»×xßÿs×Ç9œØ³ÏÞû»×w­µ×9#ðãÄÓöùõÿÿ^¼ ÿ>|Þžñê‡@¸=t¸©Qàã’=³AIo‚чìY«kÌøÞͧ Uƒ’mèÄò‚@OˆþåwlŠg8œM´áTž"RÆá«¦ ýò”5×nò˵F²#¥’Ûœ Ú—dÉÕóРØhj zïXÒÍ EÄuŠ]S½¦‹—•<2 ,×Lªò¬á(2Y$J&Ä„»öÐçñnÙ`3TYLEÑz5œ£¡èÚ“º«ªOÀÙ¬¦UÀUÿw®TóZf8©xÖr6/ÌûmWI©Í+[ã4ñ ãx*FÏcâ?Y®Jj›¬Ã2OZ£“1Å{|¦OÁÕ_1²AŸ¯íØŠÊí, õž§x""ª¾ùJ†Ô\^ŠïÛW ž…ל<Én3L~ò_O)L|uôN$ ‘Ž-&ŒžfeTLÊå%IõF´B€zòÞþ5Òh)6vFþ¶suºîK»ƒãkn®q‡n‹ß¡+`ʺìº<ÆYX«ÊÐ[èb7`Eq)ã…ÛÇϲŠOq©(z¹¢Ý¨Øñógm!È“ãë<îciÏßM• Lƒ¼Üœ=†p¶j‘§5âE›W²X ž¾\vƒ*麜oeþ 1ï!PFŸ3«YÂèBó{á æ1¹æ8Ò5˜éëåŽ×z >æ]}>ŽNG³’”¨Œîœv÷†Y`×ùúø~å›Î+zÊê6!1 Ѳ°ù‘пígÏÛîStë„WrÊ^l.Ê ?⶜̛u©Å“ÔÞèñââY{ó”ŸÊÿú†[¡àšôÕÝ"D_¥Œ€­Ü¼ÅñÛ^²½l¿‡ÿ Á™XõNÊà‰A'‚² .­'­Të¹ÂëÔKpà“êÙ·Îìügü“`%þï鿚 à,ÎyǦÊÍÀŒx² Å=ì¹ÈÔ¨g§:¹:W@L]ƒfFý¡·"‘Áó4l"3@­¢Ât¶ŸNn>±H)6”{õX3æ£Xë‘´#$/^‚¸Âê<¬Ä¶"…]ˆYü’±EæW?ï°z²V¢áÃt4©zCÃàÊ$Ÿ€¿6Sã±ôɨÐhí£Ì×Ý¢gƒóÕš ßQÿW¾“)ù»xûü¸êÿ âåû“ÞP_øwºŒ^£y1zÿIÓè ¹ð÷„ƒO#Iò#a,îÇ£íAVvþîZ÷#p“†R‚˯Ò'Þ¹NõÝÙ ¿¢x_Kâü¬$IÏseö±¢êMRö¸¨3–Š“RVŃ)@´:‚vÜÁ²´wª¯],mëï«+\à¹ñ%_Â.NI‘éï_YDòTÐ#"ýÛ·ÌÙçB/Ý!ÄŽÕ"Z%“Íf¶ç#–‰‰ ¯Ï¢gv¿e°x™^Wáó˜ætÖF57¤yŒzt8¦×ŒˆpÕ:Å5r å¼x“(Yy’äK »k¶ˆXf5©X¹Ø$ŸtnEfWt4Ex›Õêß{ÆÔëxî£îFåHÕIX§§å;µ¶Ú¤Kħ.P°nײÊÙã<[ãó:¹+b¢”"Z]ñöØ„ÉÜð1¦Öfâ®w¶m/ÂÏ3[vzXè\N|·Zš ~M=;~U¬*q,\«CîCŒæ"-zlêúÓÝ-éæ2P¹Q{ÃU\üâ|Y„IÊÒÐYM t¬M6ºt*®€ÒÚ¬5ë)v¡°Sç >y4‡p\éXéS¡MIrY™ë£ %#Ì%„û_V‹n»+)Ùz“Ñ£ªSWˆ{ý<¯MÞsfïþÒ†…h.¡óêÇîYÎŒ†Éå¦O7Q7ùñ®±ƒ.£Ã-[wÚßüPü“£ª¦ÎÖžo<Î¥.ÙT§]¶[9q¡b—ü€p·7c(ÉØ 8ešUñ¼ïiŠÔ;h/8ëî‘ù‡´yâM™™ÑÔnxŸ€gØC.h8ËÇwRšçTC…Û¯Ç?#{ƒDP¡éYeJ?Éy4ÎIóÃP쇇¢é'³'·)L%ܑ۱>±þX>lØeäe «˜PsWN¦©€U_ XñJ [=zéåãΧljWdº_‹%¢mËç-ÐúK/"(ñl8~ÿòˬ#OV㈹2v ORV¶÷ˆ¿ò˜ÛÀãáå\ÝÕëÆ¾¾¤~}ü€?ÞX×ÿAý¯õzñ¬±=*ûC ¥>w²ÎM[{} åde··=× ÿ¹ÎWº™ƒ§Z £îˆ•”\?aZN,•éf¤{D–§G®U'7×(l]Þ˜ê5šÍ½ÐðÝ¥>Ý~Ÿgþ³mDŠüÂ#•„ Ôt”›³´^^ð‹âÞ;uÉúcÝÔ òš°®w?ÿ¦Gäãרë7äY¡D ÇÙŸ•gâ/ŽÜÉùnú?ù} É,ø;Ù©ÿVñ†ü^¨öÃ|ÿÝ1ø+Êy]½ó„ҪοIWó–†ä 9t9îZ6k&ƒ§ ý—É}3¥mBÖad¶~a%x¹ŸÎThÚéc …÷\¼ñvArã´€?VÕª~áHN™ç¹œ¦&÷««,½ááÅ@õGÃîë‹ì[E·HiÊ`”\§;H˜ƒç N‘_‘ÈaŽfÂ;ég³ËW¨ºYJ GnIB¸È~y£I3óÑÀåÌiQÚ0žèw3ë”9"ð¥enDˆ_‰5ºBj¯ÈÙ¾P[î©fk9 [åÙáŽE÷MRX|2ÉËI¸#|"!\_#É^¢¨£Pœ-«Ž*Vß92VË1Õd/`žÒ Ð.-N¿, î*xˆÁ¨." ´UË"9YÑÒBOþ8÷Ó;£àˆ ¥•cÌÛ;~¶é¶wÊ'‡ø¹"~(þå¥ò´Åº[G†m›ûÅB6îv¿‘òyèÒ´¶$dlbBØhÙ¬Wç÷ë]m¯ÇmÐònòOk~„ׯœIjØ”‚ß•JS.H"å›)Nª1XO"T8gj#˜ÁúéWãæ¢<§h€_´W%ôÉÜñ ô¼1 ÑÄI§Ë·¬Ž¿ÊÏ ‘Y¶{g"¶Q“¬f£kn­#¹ ìØÁûCX v É;5ss‚J‹‰.g:‰ëÉb"ëKÆ£«°ú°èáU=ÄBü.þ:*Çà„+&êu84ë΢*‚Ó>Ÿ»pKOéiáS€7_žÁ¢þøƒÿOê?]*OQÏlÒ´«»&1Oo6…ѧ%XB¥y­J×#7½?FœWœY™‡‘yØQéGÂÚ¥ ®¬‘|j¯xÅËFµX¥‹»®~GÓ¦ZÀý¸÷ÂjlfÔd@N»íãaCöFâ˜Å•þ‡Õ™V›„;÷¦×Á4óu±ÄwÆ5Œ´]|Bí\ÃbõH~þµîÜq/§¬+XCºæ˜Û?÷œXiš¸žºüÝôÿ»˜‘ßÐ-p ß«ý¿D~/€'Äñ] ‹Ô1Ù¸NŽAï1¯VÒN~j`ð4zNÙ‹§`__åÁÀ\€Poåëô?IŒóʧ*šV?KNÇ 4¶UÓ6°–‹‹Â±S-ë˘¢õћ̘D!½É”2ºŒ >?€ canŒ,¶Ìt$k]ß\{¸×èZÑfÃ.s¢âã× ëí³nB4½Q©åZe"~Ò³´JÙYð¤Æüb2KÞȨ■ÙB‡ðª‚±; û†•´‹aL²åÌÎÝ2Ÿ‚‚ƱåÚÓ˜Ô«ºî™É…Æe{A±Ÿ<(4–·¼›øK“Au­ñÂ[§kr3‚¢â¾ù42„ ESݰÔ¹Þ帲GDïÚÕŽ‡@ô–‰ôÀÕ›äl¨/Ïè¢fê ¤„¼eŠTkwøÉóHí[)~ t»Z<µ½+]Kî CsS…:òì…¹lކFUuÞ¥×—ÝxK-ª–š”Ëç…‡‰^™–¦ÍÉÍÔv˜ÅǼH[ö^*#ñ ß–À"ÓHf=†þÓ‹4*1öõ˜Q¯Žâ}LJ é¬^WíVä“m¼8>Ür4¤|>FÙÑÙ#[¢É<.ÖûÊôœcF±à-4ßšˆÊŽ0i™àùˆtÉæz=>—Œþ;K"CNÜöñïémÚVÃßhÄ:%‡«ûcÜxGDGªzÖi^ƒæ¡y-!×SÍW"RˆˆÿÖä#`’B±رÿ´ÄC†xªÃWž{ÖYK0½ú HcgmlU‰®=ï[,È? <Ò³ú‰×ª—ŠÄxP|èUU·—(H­:_}*bd!$#aÓ]`]¡ZdqA(çéZŒ6ɇjuc]zl·õׯY?¯[<Œá9.DßõèŠ Îš¿ŠQYFìõ[žãªÅ—ïµçBøÑAŒ:.µ™/ï=rè>B®wÆt°Oú\l‰ekZ:Tòº•di—«°JÒ–Àf¢;[ðªoÑ(pjÏ5I„v¦M­n¬k˜VÇN~¼™Œõ6TØ?ù³\¶lg"GðàRóGXHil]lˆI‡JR¢¢÷˜w5óéÍá[I«Ù$i•´Înm™9dlV+†â5î—*U8H¤è<|ˆcè\ìÃÑÅñº8¹èÑÝÉ»ìÞ“/¥@Î6Ùw‡ÕÞµyŽŸa ’™šd<ÐŸè£ø’÷î9¢G½ØFÛ2ët¿éî®Mü;=™ê?šnÿ ÎóW9ûÃòKãÇ_œ/Ê0ÌÖÒKªØèãK”}ã÷ÇøÃs×® |ޔ×yûÌ çjÚñ¼i™tŠî.–´…á->…$\Õ_ˆÿ×ÿªpF[_åyE߯Ïï’^Ü Ðyü~5¢²6tF™P‚ý™üAÆí­ì»éËî—Žš’߈7Ø)BPÔz?¼]zú©›_—r¡Di3DLþí'73Ð#y;nžwÄ‚[/ÌUnÕl½eÞ[ï%ANóÄЪ%='É¥^ÚëÞ³²Ÿ‚»õôý˜:˜æN÷ÉQ´¥…ÐalêÕÙ“p<¯†¿­ÿ$Ó~ü‘x¸Bÿy÷ï{ÈePâíõ· 9÷°¥|¾`+…žÝ_6+°ÅA¢È¾Ï.'f»Ë²¿TLy5­µZ5ê"‰ÁC£îK/¯ é‡ 9ÆÏMñò¨b*ø¿f¶RÁtâªÈµÓ̱4J®H@M#ÎÆóS§°Iú{;P•yXáñOž»õ⬢;]ØAm¼«¶Á8S¬<À‚·£²€ôFø“m¬¤ =ƒ37…ˆÄÂÒnëï>°æ¸4 ÜƸ?÷Ó•NèŸò¸æó>8É%Õ½rŒSHC³Zë;*Ðs úšÄŠûõ ¶xþDÉÃó1Êåk+ùŠï/ÀNX•rR „]k~6÷vf²FÌ«õ–—Ðã#w9Þ¶­PÀëv¹ŸÍÁècäŒÄ^‰Yºý²i’ìq”ÉÝMN’[–¢ä=}÷¶ybR—‹â Ü_-Ÿ{¬Ë!éP=r´±EíþÓ³ê/iè7û+íÀd\kÇNÚÐ9¯‡4å/!dFÕmbšÏb(>4h*IN0ï$®„1i¤ÕËa)] xKM-–eý6:w¦IÃO·PAØ $ñR¡˜ü¸<‰go•áÐTé Z™×²4ÒÕ„ÖÚöüéí[Ê$e-[,9¬“‡àçÕÊwõuïõ2N@ë¶×¥¢ë'‚¬v„Î÷³¼ìbL£ëx'Œg—–#çôãðoN â2߃BM2†¢“P'­Þ¹h'’ \}Œ¬‘‡Ò@6BUô!Ñ?µ¥©’ÜÖ: %£o>SȳÂìš5Ç×ÍVt3ó*¨Ü2g@·í)PÞ›³º}p:òëðw©HÖkȉ¥ËETŸs¢›ÓÇLŽìÍÌݱ/ÅñmÓ…4MAäÜyÅ]f¥RfÆ5-›•oN†0 *<êɱâÇ‹@? óú°DuÍâs:Émê¾·~™õçMµuR…—Tx²Ìß—Ný þÉØ`ß›/NQﺴWukNyÍ(.rI¼U(=9×ãkðô×áÿ3ôÿs«bÝÉÖRî3³ð— œ ç]Ôð.ëÜÜd¥š™¶c¢ Ûª£ys5V+)…1µ)3(Ì8Ñx?¸±°¨ f6¡iûxÎ]Û6ïý%PV¡ô’Óö®YÎä‹Ó7wø9Ð"^6Ùuf§dÞX´}âwùŒjÃ럃¿ß´7¿Âû3›é­v–=LC¡ìA/EFN¿Üõ!Laÿ›úß÷·¬Ç ÈôÏ»ßGþ0|Çr=E„°œ½:Ê®¯]¡>5¿CïIÏ9¾go{ÉdÐåè y‚g‰ŽÄ?ÞõŠEA¦?oE"€]Á‹¯z¤KF^J$¾xÖƒ\S2Yê…L{|¶0y{M ÿ ßÕ#¸ ®¼ Fz£…I¸PKäÇ÷Þg‹)¸ù.°Q ùð…‹Ö5Ô½=µ´~Z–Nu|‚|¸-ìnz7öeV=C×wrØŽ™dŠÚŸï‰)GåßÓÒªW_+p:Ÿ‰µòI̪Ûè‰Üø|ùå˜ÏöVLÐ6oÌÈ»7+0H•\ðZ½èÞö2–.™Zôš*Õx¿ As÷6I3¢R:ÄÕ@hßh(ÊÔO[ßÈG`†?¨:ZÕ¹`,ÊSïod…½}-Œ—üØ)·Æûvè"7¢ºŸt¹œÔ=Ç©¡ ÖúØôà †›Ç[cgŽHK)–ÝŠw|ã3K:¼6êÛE•@êþypºeƒ YJB(1ÑOW}צСÓã(-®DÑ…î{\\ªòïXÊ^ èòÎg uéòõ ‹jηîщøà†àsÎíhæ°§¦3¦6ºŸÎH¹CT«×dYÖ“Ê¢\”Y¨,Ë}dðâ1§§MA·…î¶õ†Q%´:„ÿDäè›ç…nµÿ$P >@Áê~Cð‡ákI]!¯ t¦´èž½Ô¸bâ ìú+ƈ#¼KGù“\æú|ÐГf»#lëÞ¿"M[>’I]X0üÀ?XÁôÙœ¯ÿdE!¹ ·ýÝØ*Üú<»ÉèF1/îÙt>™àŠ¿j*¿Ndf掺ؽ_… ïÇU!rD©«z¾—ÊT/ú²™æé$ÅÕ@ÞhàhÕKÏ>‡<‰..:œ8píóâØ f–Ù ¯Æ³ÌÙ ½'ôuß„…¿³ÅJ°áW, –àƒ¾‡i-X=(›YméºvSÌæÝ½Éü©á?ÃÿÉö©Án‚kú™ù½LÇá×¥+æ¹á2hZ]ØÚR½”Ó¿ ÿŸ¤ÿŽ4ŽÉ*ÉËJzõ¯®;“xõ%7uø>ËJJ?•åꢞº5¬Œ?nÖ9ə䬞Û¸”Ÿå—…kQݪ )[N“:¿|äåø³c|›ü…Âî \¯.²ŽÜ2Øyfìÿléì‹\榆ӼaEé£ý—q*¸æƒs»<¦–›®Ø¿ÿ)ø?oê³w{pÿ.l’¸.¢Ï¬ {„^‹…MaT~aFŒgntçoé?áß1,înð Þýû>òÇ`ÿ1€¿ó.à]´9%?ýŒ Aš‹-Za¤X.?Ó¹=l–Í}ÓÜT\lŽB–f® .µGÚéå2¬“Òóz^ o)‰ÂŽ›˜'Ë{J°ÎÓµ”T2°FÕ¼RŠy^>L˜Þåy"Õ6ÏvœŠ™ªpšÖ\ÒöƒŠâ×ÇÍ O úÏX\ÏÒíy¿ÉV0bX‹ÃÉiÆ`yû…B3¹ÔÑÎ4Œ<ïà¯Ýã+莛yå¡×«úGF,—Ésúö}*4M~&ÈŸ×güàCÃÛ£ôThí±©ðh±wÃ3§¹#i¢îÑÎrÚKÔòr/wñvOãf¥õ…5¼teZ‘)U(wæ[R¾€Í…¦äøÜd»lÿÀv0s¸AX„1Ýh‹7UËA¾KZuy:4\8£~»ÿ,OÕ˜À-ºE6öÐ×£¢gêÈÀëó ¡œw4ä/ØŽ³tÞŸŸÏ‹ã»Y/ð¸åó§Ï-ͤ=>wÜêÇö‘òÇsµ4›móK“ŠÓR×,ÀT¯Vç.?”t’à¸èæ–ìjtÛ¼6Ê4š¥ü‘ÚÊy èÖµYŒ±¤ ¶áý 5lï<‚Êù¶ýåsÙ5»=®ÜßfÇqa\ÕzfFš÷˜E¯Ò©-êÒµ˜¦ì¼¾¯bqï†ûæ~ã;ìç¼ãžÓ“–žQ[³=þV§2ëÔMƒ&Ûó¶¥+»? û8Χ²÷øšv·š9,\Œ±p¼$„à‘Ø­ìºV3 sN|ÕÝrùŠJEŸ¡ì`QíŽZìõžßG´+Ru k–¦Ýo=îᬛ¾‹é¾ÇI¯2Œã tr É[áݤ5êÛ+.Ýêb—¶ž\xõ‹ðŸÙ—Ñ˜Ë ±6 ¦xQ£$”WÇçl«s¶ Ó_7–•wSå–ÿŠA:™Ó‡@ªÙÜØIAô±ø»tøïÈuÞûH)q4´À–uR¯¨z‡NØR›Fvi¹Õ¼´Â~ñà˜9¾5;ëûs–øçLŽvb:ýf7ž$_¨íVúñ )¯Ûª ï=';í¼²hysrô×àÿÓôÿ¹ÞMüåwß+;ŒtË¢ÊÁ©»SÂe:ºô¯«_à+äÞxà¨\®SŸÌd´cã{2|ÝÈAøÍ™ÎÔ&ú”‹oÀ¹âzæbÔ†¸}K’8-iØ›1˜Í3îZ8ƒ·Vßêg5¶pJ=8ñãMÆ¢õ Wê‡w—NáÅ3>¹²p´ïçàßAC7l^fðhPûe%ÈcG„úœÔóRŸ7ŒŸAÀ¦ÆUî3CÿgÿºéøñvùçÝ¿ï&–@ È ÷ýËI€Ü·'Ä£Aì\£–p‡Y3¯…¾„b­®kjqÞuº‘² †â¼bøÔ“4¡1]tXüØ—±Þ[ÅókŽãl«^¾(#œ»—ª|&üâlo ñÑë|²þ"s?ÏYCF®çeÕ9Æ Kgƒ5…¤XC ÞŠ×VŒ\ý°¤1¥36EúD‹ï˜ßY7ß¡»×Ò¥º‘(jxC4ž‚цgÛ©©ðÓ” Ñ+ÎFÍŽôb?|½#SxˆÑ¹³A“BÌÍáÃ:ÓÆIó´üÞ³¦!ÜcëKÎXæ£l”Ã8/&Ÿ;… ¶IUÜ4h*‡hÍø î'>gôaðÙ†2ŠF-§E¸{ò½H”/!u®|ñž¢²Dv68ŸÓ$Ã®Çø´BVgæÈh‰„~߯j:Àš*(Z\þ:q'Á8iZ@R¢eÞé¬Úöú.óÇv “$W6;WÏ^¢Íy;×¹¹ì™ÓŽð]ȰQªW^wºíL¾A«Í¾ÌH@Ï?8ðézlÄ$û)G³mÓñ1­yÄOÜË®xƒ:ÅUs`Ô¦>¬)ÄsÚB7ád;wq;ž{ÑW-‡RZ~tu0{ã‘¢2‹?Uÿù|‹(náiÖööf4Ê“ÄdÃÕoGvòZœ…n¦t?|¾½1Í£y/¤ñGÐÞ Q´"ª{“†t.;F¦~¶Jó:ånÐioã…¿¤5Ï}M~SAS›–Ð)ÖT‘È(á+'¯DËžæ¸Pv^5˜ï¼GƒœÂ»à¾Ê X~ñ‘êkø2ZÓnSZ16cýú”Ñ0†%o¾¢tŒã£»žúŽßˆ_Â=Í‚WôS¤DĬÈï]mZ>[ 8öWàošË¡lÇ—›ž'/KXª–m¤Añ@¾ÃöîÅZÝ$ûqãâd….æw(Á”‹¤;ãtv¯–6[ì•NKX÷ÖæÑ»-ÇŠS€õÝgóžº4ãöƒp7ÒžÊb ÕùDïI¶ôçø ”q¾˜ê˜ÒZòìÚ¶ÂR,ÇOéx{&ëý%?’ð¬_ƒÿOÔŸÕ.L4cŸ2ù´ 43ûð‹9¨Ím‚-ÄFOËq?¿s©N¶ÉÇ£œ*µ¡p& ]øÜR–O‰[ÕFúÎJ9kvôÐ]v¿X]`ù„ôz¾Ä<é-¥÷7â}°Ñ¥ÔÝØ¸Ø»ŒÄž“öj€E8d­%sé'áï³s­ ž‹l¦½ªcªŠ™£›„¤Ž4µ9c—À½³#‰ï¯ë¿À_5*®î¾ÿ¼û÷ÝäÏ2{×½ Ÿ¿è€m«Ž¡¯RûÞ‚ÈÀŸ–=n¹ tTþÆüb+†Xê˜UTË‘c —‹5|ßÓzkÇÀ,6¼Áò‹î9IŸ:tñ 3wÐY4÷qfúùìâŽ7èÝ‹ÊÞ—:S›,ò+cÏ _ò `—r©(ã~ )?¨×5 |ŽŠ„cÛ&sœ¬“gšÕâw ˜½d­måï‘g“yÞº“ô³Žö+‡*b;t#<¢]Î#ùú¸Q»òqoJiôO qh¬èrO=J žiíéiœ“{¿Ó`y딎;x ÅuëLë´ÿ´Í? mæ/vuÏá)lT|wÂÚ¾NÒòcE„°ýÊ…èМ=ÃÓóR%÷1vüšß8>óe¼»ôùÝÕw1ÒÞæZWex?Æuˆ¨ãò”RvÏKâ8"_:eZ>Ä •-Ç—nŽ ˜™6x‘p…~Ÿ¡4EÅú3áy!‹¦ðð~‡æûêJ>¯>÷*)g½/åë÷ôž›W:aâÿ¸Pv…™þbº~1ÚbEëê.wf¿ØÓã5*e=[ä‰ébÓ« áIíµOp/fnØy\ ¸éêö¤HŠñQŒ×ÕH2nžý¬2‚žE¶®®ÛN×Þ«¦ROìVÎi¢Ø çž!Ÿý(ŠŽG)¡âIÜ&žË"=zŸx­­8yõïÉ4ºkoV4‹¹¦Ñiœ*—¢ºÍßÛCV$à÷édIÏÈÝΰ_?•ßeW™:Àÿ¨´Q£âC1í bµ-&íÅ[UM¹ô r¹]â\÷ÖI±k“¥ŒÞh=[.ŸôÖR¾PötÐ|Ýÿ4»a²­ÄEa{œîûwId^äÈ_8gZéF#žò.c›mh€n<‰Ûúð?îÊMè×|úÎ!ùq ³vQá*ÿ*›U¤.â_ÿÏÕÿTwÕ%¹G?^ò½·xÊõ¡?]©‡Û#]{AüBÝ·ju¢Â‚u”œñ?9/œ_Ðñ€ÚWÈ[hL§ *3j52‹I'{<À–E,¡!ìM3M–4\NîJ¦¸¨_¨‰qé…3Gc§½Pׯ‰ª^²EX? ÿ³ñùnE'æÞX%|²s&_¸í¤}0¾ªÖ¢r»‹¥†ÂãåBš¿ªÿÉÍlü¹xºAßë7êÿ‘ÿöø/>`¦S¯J:ÔNR›Oå5È™å˜þÉzQŸX«‰ÐµuЖÿBóö¥¸R©ÁìU}zÁçh’ðigg»ØÌ·þWGUö~v‹ç5 Áì`/䔨¬9Tdü ×G´Ag,_cÓ)6kþwÖÖ¨6¬Á‰„hƒV»w^Gí†Ý‡VØ o׬P?Ëê:MËÅÁÓňCAîÒÂ}ß­ý¬Îã@PÇý‰0æcނɯ†ƒ@Á*ÿ±@u`ÓŠ×Ø–ŒdçZ JwñJŸò’eÛ 6Éi?ÅCT.ÊJéY„Ãn1І³¹ö™ë™7õc§ŠX"[u”‚ïHgʆeÇ„<´a3hù\J,ú|TAI&•˜!)½#õìgV¢š@:bƒ¤!C[¢Ö‡ñò]îeôµîº¢þVÏpçÜãdU–:huMʦÉgÉòœ >â5¼¢9rÙÁÐ_^»©¤¼ä³¥ˆ>ÅÔ)šò«ãÛ¹ŠŸÏ—}à<æ=Þ¥'g÷«:Ïr]’p]ý¿gB¯, ­œ#}°­Œøô“ ž[XÏG‡h&ŽöŸYó^±Ž$ìxn†gÑtŸ|›Üa9D²S OõUÑ3b'ýré`Íä¥bJ~ýIbjÀ£òk@ê ·ÇÇ]}ãûhª‹Þæc誥؉O$9.î-3÷ý ü‰XÙ|yOFI¸/Œ9±„<Ë]‡EŒÊ–/z¨MvÝoCW4ýÞ‹± =­ÀÍ>ÿ1|¼º‘ÉÒyQ³³æ‚[;O•âØî-|>ý¨V)TVá@ÀÎ ˜N¶}bSªˆ€8}íBÖ™[¼?5>msµ\4L¢9´Î»GÄ“MÒÏä¾Ã$ò1ŒÅv®˜5Ÿ, &Ytf¢ÈeÔîÏSu^_¥}E­¼7ëƒeÈ;[èzÊ3~™vÝ+‚ëøaE]î–2Š®ÎÚQ1ñÜ0Ñ«>øÉùcÿúÚëW˜‡6“Ÿ>Ysœrl‚׿OËSå-ð ðÿÙú]ì.¶+]{¢P?Ú¿w5ø}õó39-Žý•¹ùÏ2 î|ŽK8CèA½M2yƒÐÄÄT)øcö™‘ÆãÉ»ºñI™EgÜ[½gí^œ§ªkœ¶m8žë&‹ÛY7Ñš`EIR%UVßq.â\ÐP³Ê ÌH#e;#%Ÿ„?Ò]à Bç{†‰Ü»'^sç¼MJÛhÐÝ¥}9ˆãÙâü×ôñ/Y?°«§ÿ?ïþ}G{ÿiUÂë/>°Ðq•ÎáBªXcº¨‹Ž#0gäæ_{ 8nì{q%¨sèèç·6M;Šho¨q®_¹¼Ûà&ëà/o -N-Uã3£ï|q=]»’ÿÃSÓજ”$ÈGL@šøöç-â[›Žã×7· v/Ýi ™V_2d;J¿Ȱ_§Çû(Â=Ã)ÜàÔ´$Þ*ÌB{…1oÚ{WDÍ3£qÍØÍ¾6khÉ„Î'O`]µYîÉ`j¦O þÉÝÐ|A3߈G±ù}\±Ç?çpÛœjgÚ®'ÂÌ£‡³Þßb‰Ç¾w Úõ‰‹Å!/–%Âö¾à¾Å{t§“>9' Sõø=Ž1 (Ä3œŸ 9Iïv–aüQÞÏÁá šªHZ#òvõFy®„˜,ŽO,ç­TTcZV—­p­”Э]ûÏ ™L\P†¡óO#É_Ôºê ÃØ‹0¡½"Æ2$Î1“sŽWÜhSŸ¨Ë~RHûЬ —A¼Ú9‹ñj‚Gõ$9|¦v][½‡Ñ ÁÕÄÝ,–ÉÞ#Ùãóîø„„•“ªðÛ¤õ7‚³ç×1Kæ`¾ˆÈ¡êð¥Z¯‡Z—zœç¾KªOâ×Ñùp%Ô¨åp½ù^F—úôt…'÷Íà¡ð—1ìŠQõ5\ çæjϰYö­œ ð$ÖgÛ¹Õs‡ìXÅzbqàƒä§É?Öæ<©$Qr'|Ÿ¡+›¢·OÚ8G)pH^¸[«ëiòÀ$êUÕã«Xï¹Wñ>š¼“Â:™ã–Å)ï÷´HO­eË9õþ«¦É ÞSO©¨‡­G® J%‘¥Zé t¨LÍx’¯2”†S”«Øu¼4SóQ…b5Aågão†­ pÅ{q‚ºv:(» âüª‘^]éRa¬%ûzéS m¬",Y“8 Žz†#wÇ> {W}ÞoÎM’9?ÛühM[CL#«>òU¬©‡\-GÄ%ôaƒó¹)RaqóÿŒ?ÿ|%éêñ:·Ík1w6*‰Â7™S§^bž£“ûéøÿ|ý½¿Áï0`EéþæMduQÚ‘¢w2ñyif4Z9Æ·.7dË e–áXvq¶ÚQÖ×ކË3Õ±äõŽ¥#—K&ª#3žbGÒŸ5¥Ô}ÞSîNGÐE¶8ÔÑUKW¶×J3 |¨h2Å5ÜC+±«’âúYøÏÐ?†©¸ø !:’ÚŒ'Dzq<ÚïråíWU[M¶‘›ì‚ýýçûKéÏÅÃôÏ»ßSþSØ{ ௼ ¨BKO(ÀUÛD˦-R¸ÊYB Þ6Pl2βˆc5¯sÎŪ­p,¼æePyïf%™<®j^ÐÔ« Âú,3^£ú—#}¢8)Ϻœ½2ÀÄXiš1q&ôsP![Ãöc—Ë3òfå§°üº”§Š7Ľó/øÔße¾’l6ܳ­OK ‰x?8¦ !ÖÂ`0uâ-dß1#ð:CÎ$¤ÙTæ¾ÑúÃçz!dèr<ëÜ4îXêö–¸4V§y¶—¥£=‚³›ê1îMœ=´~QçzäVÎ[تA1?9¿éû.’£mÏŠZ:ßÖê¬ÚKÛÓM>¡z‰Q?dED“ÀÊ%ÿ<=\¤Ñ5ÓR)@u›2w„6ÖÇ"ç¦ç‹d*Gp3³ŒJê Wó6G¸ƒ¯¬œ%y+;s»ïeG¹j9|è“Æ “Г×yÎæ3ð `‹×-6f:<ƒ¡»Épƒ0Öuw¬O6.``)µl`çT¾§›¥É. ·®ÓR¨bN&˜ë?žÈ]qæúG†cÎçŲI»Ò~"”¹T¥‹EgµŽš0¦¹Tg«óKßð#„ôsn¾ð½Ã»0±ñhŒEêm–Oû§”Z#§ÔGN$w§Âáç Ó»C)ìŠlŠ'dvá8¼ÏИBúÅy«}ʖ諊&?ÿTLÚAF„áIY{–´ª¦¾Eû¼&»~EhïŽh¿KÛYÓõ*jÊjoʆ:½'DâQÛt½ WîöÖˆöì'²Ï¸ÍÅøh*,ží5¥-FÓšx¦Mq;âb„dÄ}¸½Ôö¨‹äÖiÅ˰*ÓÑÇ?„6¶_³SWßѳ”6J—L(Í?`šeœd|mâ‘®J/ù| Ó® /áåÈí_~Mkž[ý‘’ÏÞ4 MzøœNWþMdÂæ%ccâò×ÂÔ÷‹‡?]Kê:¡¸mHÿ>žÙ£î¢dcÐÄÆßþe\ÉžÒ% óû»æ“ecƒ%j°S&ˆ§·¿?þ7¹Mÿ—é¿ùp|£[G ®Ë«Ïa—”ĉ°óAD‰’»pìjéM ›"²gˆ:œèœ;|M.-©€Þå¸Rë±’’¯Èß*À8§DD6–iþðÊX7·XeÍ8•kûëzÖòû^§ zø¯“ôSÅ6ù²ùªl®þ,ü{ZwTJÂͶÂÄ!$Øéq“òpÂ4³Ì ªd <æÓ›¯ÿ‚þGü%{ôç–Èàÿý«ý¯OØv¨¼¼Ÿÿ笋SCÈ]äY&Z²IÐsF.NHµ˜ö͇Ýý4² y'ÃyèBÕ{Hqèr…Z%ðçp@‹;ñiU4£ P¯¶âÎÓ Êyÿ;Z0îrïyÿ¢Ðà,`ÙPêYâàå€(7Î]1*«,ðúC‡V-mš®‡Çzæ†ÐWp×ìq?'°„+´V0AsAšÒÏw04=ؾpúÒI¨ØùçK»Ô¯|.DÒaļª{u#S2½ú>´W†ñ1€;$Ûlb v÷ð:-æ\Ù)WÐ?áÏs¿ŒnÀÛ’áÄÜÀ¯þ´-JB î 3Çxw3 ]IbÉŸ2›;g[ÄÜèôìRõIBð™f4þÈíÖk6Åo×Yr—n ŠÌÚ]¹äˆÅõ1,IÒòÊe±í’Ð*tÑÅéœÝ¨ëyµý°],í¬¶tôåÂá¾9!^ñç»iL½ÄœŠ8$· hoÍHE°læ  ‘”ë³Ï`¦UD×ù¨Ä/5ª˜ÙÞpµ#nÃÙÄö°Z”wqÞÖV"ÁN.a}àžB&Á°Eþþ¡üâýS·x›󘢮šúê”+–F¦.¶>Ýõ–?Yn9-QèõLX¥ U9óˆ<([е+CFί¬d=± Ò` dSð˜…ÓÉh×sÆ,thæ}ÏJÚš ÄúY”0ø#¼a7í‡àkóÔÌ t‚¹µ''D(ª Ù ¾vx“óÛ’67â:/.žéobgZþzš¶r̶tËu"âäý¥œ5º‘ §.S‚Û‡º C¦•ÃÏûJ&†[çX²³|l=±´‘ýÒFÏFi¨¬ Ãî¼sGØ Ð ^).þ• ¥EËÙh]±‚g« hŒÁ7:+yè^úˆ¦ eŒÎò?ol¡œ‘‘F”©”ÙÞ¿*@7º9Jç?g¡B˜Ó…çðaÞST˜¿MRô«î¹“®MÏŒ‡ûñ”3±|ò奰ÉØóvæ™§Bf«ýXÿ'øa á²’c6QS¿Z€e…®ËciõàŸŸSFÿþø³@Õ’<ÿ7é?Ï™¥-w±Yóngh—Ìoë&ñ_O°>ºÔu ~$èú)o¾ žˆ³é!¤ùÖf˶´¤pdßÁ0d²¯Tƒà{ÕÂP o‡ì ªy/-CU †}Á¯ µ#{{»ÿðw†}{T{ø#Gñ›‚ó9"ÿr‚ìÕþ0`_0†Äù‚?ì÷ðw >ÀÿPo€/Ø~ÙÛoïÄræÿ)ý÷?À =˜ûÚÀ`ïÁhB÷[ö8JÅöNÂñ?PϽۣ¾¼_²_Œ$û¥÷ñß›´À~ÝØ9à'àïíG*ÿàø!Ëx:ûGýÿ?Ñÿùÿ»ù½Ü7Úßíû: Ýc?ˆ—ܶð†ù H ¾Ñó=Æ@Mß½I‹š^_/#§>Äç++€Ônùþ¨øÂÑû·„~»|`ÀWÎþʸØ5à+7|³xÝ ò=,ú[Cà øÒõ7d ´ îó›v¸ù¿؂êxé°>·½t 䮀o "+ðóý†ö9h/Mõ†Á€/zvà wÁppÈs{¤)D2|ßê¡òð€ù€u€=üŽ€ìE’vƒÂáÉfîžÈø=ø:aýÚ0dŸ¾XØCA¶êGâ_ŒÄÏÚ£UT›! =_‚¬¼ß›½7W Ò"Àöw‘$þP0@šÀ=ÿ+¤xÝòûõø»¢ìä·l¾g4Q~Æ>þßLòý]0ü›oïïíã‡ØÂ=ü 0 v?Àyê÷ðíãùBñ_‰ýujHÿ3þØÿEýCÀÉý¾¢šŒß=üÁߌÆÞ¼Cyß(üQB)*ªÉn~ðÂ{~ÐW7v`¸øû˜°}?˜~‡®ÐŸ?9‘N Ø ‡ùt ìíáúýôÿæéÿ±ÿ[~oà»z=ï5ýP4àí õÛsS‘±rž{Ã᤽¯öô0”ö”èßiä½Ç³¨Ò`W )û҉߲À.@‘ì_.ì}t+ü+ 6`O÷`ŸoIá°ˆŠ$•ì+_ïÕæý%A}Ü÷ÿë¤ÃÐî7m; {7û†ü¿±È­7Äß|¶bo @ ¨’(èò5N ì+-6 ŠQü ‡‚oüšîíåyù¢x @µÈc$t‰“+4Ù¶ÿHûÊ‚ð· ð•ö9ôG៎ "Êì¨ÑÙãÐ=_e\öð? üQ—÷¯¢ðG6„ ?÷¿¿L€ª ìáôËñ÷öûfZnÀÞHo9¦¿qö¿‚êëW‡äT¤ Àþ 'd‹AH~þ]üHßöÌ}t}ý±„:Š?û?©ÿž¡>ûfÿK´¿7gøïkÝב9(ÐC*îîÿRpß°5ñ{‘>j9Šãß3þÈCo÷Ÿ‚?ìO?”#|hͽ]AßMÿ%ÿ˜ÿï ¿ï|Gr ®¨'ÄßåC}Ò„ûìÍŸ½™z¸ê¾¥}wHñHu†Ã÷V½ Àï«ûÐ0웃}Ç©4>¿Qô}fñ†øB¸øÛèkŸÝÁAÐoÏì\àÿb¾?oö…ì¿]ÿ…„ Ðß2ÈÛooEú¯š¼WâÝ_€<Œþ÷×"Á^>`Ä7qØcísøzI³¨@PøáJ%éøC€Œ& õö'ÄÃÉðCú€€=]üØÿö& µþýº$qÐ<èÄ¿Ä~XÙ ?H ÃÈÁ¨¡Qwð½Uf”AÚci/(â XÛKŒñÁB¿»ç¯ÆéüöÜÁ´Eáÿ¯áßÞäü¦ø^?Pà¿WØ|€?ÒŽ¢ðGÿ¿?2ô‡“ üu5àËbÀ—s¿ÿ¨ÿ° =k†A²E¨£V ¾Yÿ‡:x{Þüï„îåöfÙ¡§þÅ ÷À ß}üÿÝø£Ây§àŸ¿·/‚tÇpTñÅð¼åó}ôÿÇýJÏ?öÿ;Èïf€ïèìé4°—ööüö)foýuÏŸ>û| ’Pàwh€ÒŠÎ}drÐ2ƒWP/®ï·dðEKÀ^Ø¡iü¢H®þ_X û¶ôÞÆÛýz¸¯èNÁ|óeYrXõñ„!›€ŠÿïuÈðÿbÀžþ¨àñòÿjX\Bà‡Ñÿ!¦ ÁÔâ=t?3Û»ºh€3rßlö¾Jîֽ`$…ÀÀîPˆ'b/€<†ƒ¼|ÔK _,ÈÃ5ÐïkðpÈ~{¡Ðƒ}Yúûê›ü0üsQ)t$»Ãñ›$p Ø[žÝ{sºOÜÈ!„íã «š”4ÎH$g!†ÙÍf³OÝ÷¹·¯?N­„¡M¾Ï5ê«›ìU-£ ͦhÉÝú×f—48©! v3ͰˆþÙ~£V,Ê%›ç- •è1«‚œ(W”+§]Qøn*'8Gïç‚ʘ¼Ÿ Ø..•«nÓï-hüÄfÅàÖšë£$`®Å? N‡ÿçšê”iŒ\ ¤*«û;?v„@Œ²Õ©b3i”maK„O¡[Ý_ÿ47h´‹Tñ?0 ĵ°å̤*ŒøójDz/R¾¶y.áwÁ?<,öuaâa©ÝÙ²_ÿSËÿwS%úa"V÷É ›¬”Ìî"§õÑ`CŽ•¢šÿ/v˜R ÑÜü†‚ùâÏ…’e%`ãσšñ/0 U º7ÿÍýëåÿTñÿ»ù£Ç³ÀÛxy¼)º>ìFöâ1æÂµÈ´ "ù¨øMskù°UÑÁþ ?ÜÉοõû5 Øž;s´«»;0ùj%¿‘·¸íöC»ïn…Gÿ1 HúÍMó~ݽší̼X¦½¿«EÃ&C]žºÁƒòÿµ6KüÖFÿüƒ¨Nï9ùý$ì0¡ú‹8÷±Lêf¬‹ûÀ†[g,.û3rÉ8U†X(æTít*üº+±£dô%£,»PÚS3Õb4\*?Ž3¨Cø³¿À‡€zõØK€n}Aü·÷Ç*žÿ$üáàLÊw+ƒìû4qŽøKñwq ë}Ʈ߈ågñŸoGI ÇJ÷£GR`.‡ÿéå?ì9 •˜œð7©c· q@waüc*ø×¼@â³ÏÊ” [n&)ø?Eðëóà'Œ ÁñŒ)Ã4€ðjù·ÿ_øã¹ €l{íUöìÚ§ÐùiJ• Ê** §Ô ˬŸpµª “¡oŠ«ßbïO2ùJ 4[Ø¡2$UÈa}[u;¤…üÛk÷¹Šq¼F7äI)2Ýã¿6ÿ iq:t~[:ªz.Ö}Hro;õ)Àà¨ÐR‘ä ÿ½þÊpƒü˜ˆ‰rÜÜ!ç; ›qNa;çØQPv%Þ@~5€daîvCj/êâÏ¢r{bÀþ^k*âéðÿyRêŸrSÈ5™,[ÚHq#þ ñ­0ÀœôòýÚ_ÿ«Çí:/”½‡Á“°¯å%Íd«êrÐ9+«¯X@.Øv¨ðAðßa2èü7û‚¿ßxè PÀ~)üÏ!ÿC±’ä4âu$ü36$ɤvßzÿ þ(™ÛqÔü?.ʠ퉲¼¡c¾@È- @jå‚ýõá<øÇ©€³Ëè¹üAE5ˆß®æWÊÿ‰ìÿ»ù³Çó €·p{ÿ¾Gñ§¥ÄûgwžÔ RQ²,;içb9'õ‰J’*rÚìáS]ü‹ê^lÝÿf‹w£uüøõãBNeŒ?üêv§Š¡XÍ©¯‚(Ñó]ÑýGù_86}ó·bñQFïz?Eí¬Ñ?åúû9kš T[ߦl.@’2`Ѷ36buù!SC¡ó#¸0Ñé”`pÀ…}øí½[ïç¡U±ÐºŒ¨ø¥²ÁXäªN†ÿS’ð_ŠâqÑ4ŒÕ"žÄdåܰ~TÎÉ¹Æ _«Æõx1üoÇöeû…n* 8FõKÜ˽ ë ü]Ø•#tÝPð/–7ÑxÿíÃÌ4eñ¥ÆÃÿLòÿ°ã–‘ò“è6)jíÙžS*Éòÿlò ln°ýÐfýÅ žÂÁmøÇTi×ã™ð&¤¡ ”9€Œ?ž„wîúîUòÿnÿ¿øÇKÀ«=€À…½Þ ³Š/)dŽ·È/erPYHMñ/JÜÛ¨9&âüþöMÊ£¥K[÷ñÞbKa’ô+§ÿ‚Ÿrÿék»bEÇo¦–Jâø?ÙY7bŸRµ ¦]bÍÿb&~6­óD¸fK¶‰i4ô¨‘ƒJ`WGcl‹Ô¨s—C7£½Þ|?ƸEþ/VˆT” þö«ï&ÜýßùаÀ«hšƒO„ÿß¿¬±r¬aˆjÈ5O\Ÿ­à©áã¹Àø£j–5]B«þÛuÝêöBøÓx¨Æ(š:¼èÍÔ!9b]¿°ÖÞà¬ÉÕÍ÷#Âxÿ´‰Ð6Àqà™ñ?›üovò­›qjRÿöÑ5ˆ¹É0þ‹ü?þRâç?âo1¿Ñj@ן ìèòHTPOtÌî+l¬Åó‰ÿíkäÿ4öÿÝü¿á㥠¼Ö ïÝ÷.︓Ç'¡þÊLЮǩSÚÀ-„®F °:gÆVÿkêý +g|ŽG²þ„À£9ÕauŸ[áyB ²ÁªßÖí¹™ëún€F Û=t½G£¡òÒØ‡jðàý®9W+ƒìéÜÞJüMô‘j¹6Ä(îQ0¹øOÂæ¦Es2=Qß›yÆ«áKóW³¾¡Ë™¦ÀãHmÌàVó0*ó+ôëánT…w¸dŠVSÇŸ× —#ÿõ$øÿû–ðgV#rŸSS¨ö‚ÇÉñšˆ +2•OJ³•ø×8MÖw³½ þÛû';Àpp 8ãߨ,¿ðOd ƒv¹ÓGp9Ðyq+=áO=/á¿»T À±¶Àeð?£üÃ~ ¯¿¾šLO•°W‹g;Os:QžÚü×r‹›°ãLíé€~u.üÃLÅL1…[ÏK(ƒÐ¯ãçËÿi¬ô»ýËÇ‹ x€>$PçhñædY¹Ñ8?em–åŒ9*ÐŒ®ÿ’Nw#9ôüüóÓ_¾Ÿ-)y¬º`¹%tØšEé¿V_˜ZÖ§Øtƒ¯ó~Í×¹JRëx/ò¿ôÞÖMv³¤ƒ“Ššÿ‹[»‹+|?'mùÃÿWßZUXêdc ‡ D@ô °0˜ULÅ%O<Ta ¬mºxEãv’ëÇòö„Á@%àØ¥õ7Ñ‘À©Y'M,`mÃ`J± zü,ø#©l—Ÿ)(YŒW†úå€%ä)&ïæ1)ñ#}‹èŒf)ø—[‡Kàÿácn:ÀÔ?ù8aIóðb˜_j/ÿÚíD˜ ¬/±ŽìNžÿóÊÿŒs&¡àÏ˪¶ÿ+ÿŸFs49€­Ç\t-VÖ¿¤ ÿÍm“ 0üyŸòÇ_Ï„?N*Æ?b÷Š£ ‰áUŸ‚ÿõîsåÿ$ñÿ»ùÛÇ €"ÆÑuiÇTˆ4žE¦~7->LTw@ aÊúÉ8+Ù‘s¢6¿©½?Ô@]½h¨îÿÒñ—-$Î~LØä°ÃÌßv§¸«}ñ“WûÅ(QÝÜê}KHÝg!›:4Ôf§¥u;‰ÕÝ5"ˆ©¡¸¬®ƒ¶iÇ Ñô¡Æü8ô§Tî Ò¿¢“l“Æ~¬¢$gl'¤Œê“ÛÍ~Îí"hY†ÔŽ„%ö]v üÿCñdH8θݟƒü¶`e"ÇOðçðžØX26˜ˆo»4D@ŸspW» à?O¦÷֤̀üõÜX÷=vhæÅQ¼ŠøëÁ¼›¨ð2þÝ#^°–ÙU9€—ÀÿÜòÿ ã/äQË~Pî^ì¾o¸Š¿¾@úÄfGׇ¦ÓeƉreÏU>þØÐ#æˆä|?QFf þ«ûÏ“ÿSØÿwóÿÆOTà@Y¡ óØPS÷IZÔÀakïÌÅ¿ÆÝ²¤@Â4÷ûë¦÷§(¬Ü2T¯Ò éŽ.lt’  X£ê“w7©Û5dð¥DþÇùzL7;Q?`*¾S¸ù÷8ÕöîÓm´¬¿¥XïøAß´Æ&ŠT™yÓ¤ðM\óêHàr]qxèÆDSAeƒËåì#Þ,ˆí!E<ý&”ˆëÉ»‚ÄÖÑÄ%yòè)ðÿéÃkªÊþ”QÖAÂ%+ðpùZð¾àuº[â -Yƒóú³±gÆ¿ ·‡‰w,ÿ¼)úöæCå\sóùf¯¡¶"&ÝàôÀt9ŸÄ?í5ûmÀÙñ?¿üo?üSM ¨¡³ü¿ÖùIR;ÁŸeš¬¿túã‰Õø³+Ñ똊²wß ÿ8 þ à¶âVyœ'’eÌ“w›î³äÿvúÝþ¿õãS øl ‚߯¡¤±¨ãªü¨-ÁeÍ`PŠâS¨éý±‘]ªgŸwÿ[çø'UÃG §ƒ¿½¹?nÿ¶¸Oô»¾æ;Å,9ºÑBAytÃÐ*Ú‰îW¯ýöQ[i•¬v>õ“ÎýCÙ•nÃh¿ÅÜ ãX®„òl×ã1a“0–€cÄ™plä(¡_M·ã“w»õ€²íèQb¥˜†ÓàÿódsüÁw3Å©lSê4`¨ã^'5ì„¿ÎeÄï^“'Õç’'¿½:7þ+ •þ¥¯ûf43øØOV€ãQ³8áÏ/û€øÇ_€ÿúëß•ذÏŽÿ%ä¿/ø×¬¿>Íਞë`zts ‰¹ÀÞê‚à?œÿaäW‚GxGü ¼NŸ!ÿ'¸ÿÏ»ùûÇ/p>ïºw¹÷Ù'ÚR£(!sÓuÓò¦ ÄÎ:äÉ??rokÛˆñKn¥Wz´$Ú¶Ä"ž#:çµ*ØîRå߆ì’.Ú\íÛ;ÃêU±ü¯Ìú¦wº4qp“xòÉÚ@޵VSþ¶—çÁ_Eä®>¢—ÏÝiÂTóäs¥€[ b$#êÔ&yÓL!þ(P€¿¹£¦ÀzQís›†‚ùÄÙª«8xÌ£oé@‹{˜À2`< þÿÂÙ½BmÂ;÷QcvÓî/.SøëÐYLkXI$þ› ^ΈSÂæjw^ü¿~z_èUu.øÇdd¥8¨“-‡5Ž8 û|ÿÍÃ4(Ý«¡þ7·xCüàK“ÿoîSP2BCäöÒA2RŠÙ£Kt“?­H¸/«Eð·[’Ù'üy¸;þnÎØ„iøÓýŒ0@Ø4€Ýÿ-ÿÿÃyx)ð+Wxœì½XÛú>ŒtHKw HwKI7JI—Ò%ýÂtwKJHw‡¤ÒJ  ’*ñºãüNè9ê_×·`˜wÍš5k=÷ºŸX3Pà...>ÁÞ?¾Ùÿ_ ÐÃò+^¾ß©ù^Ý—!¦Yey¾ýæÓîFáôQš’s¢ÕóæipF"<Å{C;í Ãÿµœë6ïŒâ‚긟$æo>…GÞ¶NL ¿³šÕÿéÉ=ÀŸ58ZÇèeË[D5¡…ÏiŽVUp¯¥ˆmËL¯Ê‘<O›'oõqj)† ¹®ØIb‚?Üeù𛣑æ‚F_”çÜžO)uˆG[v­ ñ¼c˜OIÔÃ_Å æ-ÏDzfãp¦Þ&,@¶€ÈÁµÉÇ7“Ç•­Ç0¤|k(ŒŽâN§F9¬¬2µødÉ!bn?ßú™ÎíJf)~Ç4nšÐ¶1 e†ƒ¤_,ÆÝw7Ð'®77«ÁQíøw=bqSó+]=X#£7ÒŸ ã½è|ÿÖ[»nÈNåI&‹T“Ýa’ × c=:n’a~]ÞLìÓQæ^óŒì:f*ø;·Ý1Œ´åV=XJDhCüh90n­êbû¹XúWaù8]ßãêú,«P~zÃ^鬿Þž'x¶_Ãæ?ñÛäR kî·B/‚Œ9-—`d=…/yÝQÌuM‰^çù>–ä}øÙ‡ÏÆ$$˜ƒxö8úMI}ÃÕªÏxmÓºƒDâ;ßL¶ßì,“V±oàh—_9„:o[¬Úô¢<‰ÝõS¾v¨å›?ÿxC~÷¡rf“,ZJ:Qc!‡ÕêÈbíšØe@«ˆ¿ilf9ãA¼rŠ»‘Û3 4C{H;°r/pX0ài4€W/šcÀå:ü~à‡›(\£\Ïã0>½l*ú`á¬þ”s»öµ›áõ†æv~¸fõ'/ (]YûUÈ~%þ„t#óŽëåÚêqjVÓ}yË÷ éÑëí9·ï4 Oâ eÙ5ê[B¸[“®S<’ ¥UzÓæÞ1ï=æSy(mÔYeBä} X¾/ôÉCdQ–£§¹]:†ïÞå¼<PžõMø?ȃëÂDbÒäcÝ€ž" µÙ0E5.úÁø§'_àƒ´÷Wâ¿ê …µ)_×BÁŠ×hXÔŒi-ö-wžDtöÐ’¶–©5\[’X²ä>JÏÄ“ÙI»Ö½Z|ƒ „0ÿ÷{ä¸ñÉã·^Gý6Ýè^î¹Õ±¶gñ#‡R¾ÄÏbo-t8ºŒtY#60™¸úþ¾9.µlpÀ®{:çUåÏ#h.í|Ü銨$Xèô;Å–¦»’ý[¿“ÿ3ÿ¥Cú×pùÿðVÿÿ. ßo¨tzûz}O»Š‚î6’ý«ÏªcÃRÉftRYÕŽu8 ÜÓ®cJ©ž·²ÍÌ“ÐÉŒZyîñ›mˆ–ÁäeûÛYâÒŠ *[ˆ&•lÑÙ Ÿ7Êä¹@ÆVNa‹ٲ$7Ú”Œ©çoÂ(/m1þØaÁ '368‹& &¶Â³êч)û´B6Ìð¦ÊÄ·¥ÃH¡Â|®úˆò€cÚÀAHƒ©cœ¹9jψé~ÜM¹@Úv›‰YYÚ]ƒ”†ú]=¼RfCé©Èæd&}öžž+“rÀ~;U³IiÿÁͳ=ŒºX¡öþÀ¡y÷þ@´rs(võöv•-ó8›Õ½ £A³“òOo2·å«Å÷ÕÕ;“¢¬6ûhR\¦ÇÉ †5g‚?eØœš‘fÅÂ?¤,×KikìϹPœ1‘æ¯T{ãõ+úåûÝ=ìûÛäE‘×ÅwCVhE|â6#ÑÌí· Ê53uÆÙ*ÅRR]д fÎп†çNrë5lxúªæÈâ¿÷ ³ëFææç@Ô• Ë6AEiõÏrÌNÚ-^ŽdiµÉk¯ß 5›„‰#Û²šOè".Ï쨬—ÁH¼Ãý¨…ß„¶ßÿn’r~§¹ qÖ®ÔzIðX‡ŽçgÌ-wàµtêxöjr—¹}¢94x·fçŸÿµ‡OfG>Ð$"]kxÏaŽò¦ÞÝJ/£°\ñžeõæCk lNLóã¢´Õ ÁE o݇Nƒ{õ1¬1…¾=(|¥íÉeÂÚ(ÐmؼCáãÆžPøYZÅÍ•0‚WŸ.DÌqJÑ ¤'ÝSÒˆÜWW’jšÔP>µ¶ÑÌæ¤µ³¿ý×á%0¹d@W7¢}ÄU$×M¢JkB,ò>¾]"–$P ¢P»ó!\éhtÁ^«MÒ&æܦó’¬Ý¶˜9Ü0´9­'ÉhcQèu<l’t&SK5ïƒæ¬1\ÉèѶ²–‘:‘mƒ‘ÌE6% <Û.–æoÂËžÒï3tßg-D¹Ñ» ¾±Ø…û2`á'ãŒÿ¶ Å†h)ì_ÿ¸r·z èyÐLJØqÉð˜µS›æ³¬ŠåÃTæœåÆ™§4Ö+¶#›åqztòïçqGy“ö×äÆõßåUqö§í¿·ù¦NH­(]Qn2hfI~†Z]wíÑBKžªÒ<ʳåkMj4G¸‘ÂÝŸþóX^(ýa‘òå¡¡¦Lnú•Ÿ±({ôÖáÔ0ÚO#›®Cl‰Ò–¥¿‹ÿ¹ÿ¥?ú—rvó ú.ô·|‹¸{ù|K5OwÏ7,ü&½¯Ɉ¬¹YGí³ÜFgoÒe<ÕŽTû”P!‡UWóÑ$P:jMì°›¶ Ñëת¨ò)ʱï‚-מ( †ùòäß™D76LðO2–#øP¾Qœý!£ÆCŸ¹ÅŽ$“òsÛÞôÍ:={F½z:++Lð0ÌÒ)½W¦ºoERïtÞ?=­ÔqÃk2è‡:ˆ<8Ê#0ž­ ÙBÕdèžÁõ ðAjlB¥OÍÀ!wŠ)Mò½ã‡ÉèãÁ'‹x0†LF1رw8…‚¤"œËÖ7“ VŠß}&+Zº VhYÂQ÷ #°}Z ƒ#ÙÔ[d×ð3¨ˆµØŠ¹ã7áìÜöÁ0Ì„rä~ÓIe}O÷µÇ`–oŽÜÛGpÔ›'ù¨CSâdt‰‹L»ïd.ÜT¹Ÿ‰„[·"yÃë°N†aöõÃ[¢Õs3ëî—IéÁìñ ¡“ì³ш”×Ò<épO“xiŽL®ã§0¡K¹]œTóÌ7„|®?x)“ß\|óäh$KÊ%Næ@ÜÒ½k3DX®[: Êñnñ`ËŽˆaY¨ú~ém‰Ûøx{~-àpzÞ]‰ r…¨†FʹøŽ’ÖíŽÅšâŽ©¦’É *k@³ýÞÝòDÉ=½â!×^Ô yZ¿„ç½ù𧉹÷ÂöUËÇÒ=“á³E¬áí(êe[îGLf †¸0Á«ö" ³ ±;¨¥N7„ÅïÎñÕö”â<ú½Ɔ†'&W%%k‰[ÅÁ3ÌSÃs{ãŒê„BëÅö AÉÀÂå’3Q)7˜.~ÂL—Ûn ^¡÷y¨‚ˆVì ôCô—á¯Ô^±”ïËgE5áu©y´dÌHªæS\¥s‹/xâ]²ÙÔý*7Òž@ gìâó ¯÷f} zØ8!VÅÔà‰àºQâbÁbÐ=ŠÃÄ,h™îçU°z.”zÏ# p já̇Äyº#Ĥœ\¾À‹¤äúÇ#|8æ×Æ´ŠÐ\VƒYv0þ/àËï–…þåø/á_—d9"äTYxgÅ•»›oy—.’LXqÒŸÙX„—%qïCðÜzÆÓ©šKï/,þ¸'âßé,ÑV>x"æ'FhÄzQNÇ.ž„/ba¤ÇîeÌÉ<}«×’#ö:úå}Ø™_‡ïüí,lÌI"³ìÍhä¡Qõæ4~{¥|¥:^¹ì©ªäÃMºŠÙæïáÿÏÿÝ Áß’ªþ-ß'ßtà\@`ßo .E úžRDv–ÉKÈ–³‹â´~2áD®y¢"® ܰdƒ_ñ©(x ×0$gÛ"w}I_<ák_ÈxÃ` ©T2öqVVÔçÜi¢¼S™ÎŽ}–xâÅXŒˆZì1Ìڮܠážû¶/™6Ey<îͨŸÂ6$¡˜zX:kMbZH8^@o&e|ܯ!ž ýl‡¾Dó=~“u:Õ+v«HLslÉÌ"efc˜“í•”“¹}çŒ¥Æ ñyäP¹¯5¨s{‹O¦S]¹öÝBž‰¥E~‘8’t5jÔ°škH·p\i½atUÆXg^w5–ß ³>~‡‘e#¦À.Ùò(<²ùpXhsnBñêÎG £¸¢šiÝ¥ô–ò±ÑvG‹?¿!´,S¸ùLéEî&Â*‘k7¦#5Ó~_=F*V^˜VÚ _ä$€! ž+Êøú¾Y‚}—×Ú$q¥dû`B¡u†1ÝCÕG9dnÝÇø[$üÖ¶CÖé5 8‡kŒü*Ÿ>Ÿ®+åEB âcVÃè²õïç#' ²VJay͉ó»%—“Mã*Å•ŒÇa¨ñ…ô ñÅM§$ͤÞV j(SºíSüâƒÝlë'h§RJƒÃªî@Àž^6s.wõ'àŸÇB¹[ãžX`ÀÞkê1úHA*u¦ážc=å46öèMé*øngRåžv$áFUðIvlŒ–g'vïÓ0>9Eûð½Þ8„Û]B Ó’/ ©¯”›ùg¹õsøeǺ½ƒñ›|Ÿ&ÝuSgâa7¥Z§þ=Þ}žZ²ƒ'¡í«¿ 2Ã^C»,.œûµÝë<±³‘2ëØ]½,èGF×¼ÙüTõµe§¬é1ªØU°‘Bp™d$ôrE¯=~Åh9ýÚÒQܽ"€i”QFÞ¹h.*ãô®(}Ó0vŽäó֨úåì» ^–Ó+þ°‹*idU×é ·j‘|^ìݹwúƒñ p(dÄ6ý ò_I"šˆ‡/x‹Âo¥G>MŵßrvöšæÝ÷u>˜zë3ò*«vuë?4Jθ†xÖ0/Êbˆ´eÄT>}¦_…8Ìù®e¹ÈÝÂhfnÞ§JÚÃsƒÅ(ÃM^Ùw4ÒŒs7ðf©Ød”Foèí'Öu†"€Þ1õ¢ò@V¿â§õñ ª쎄cËùOž´åd½Ò|è=¢CYéq­—á›tÿÁ u\»÷J쳺Œ¶˜8’†Ÿ[BAŠ£“R”Ïwð$5h™h›% >!ÒÞ•&‡ËOA6y:ÕU¦wûéË$-•»4 ÜûãS7‡Ægß­NÂCû~Nj›zìß¿Bjr,_!Ë[žYaBa<ƒ|ÝsFwcõ:/TÍ*¶•Xóñ½UÙS[›Á6ïf¨5ð{À›°ÜvNà{µÐ¦[uÄ¥LSæn'†c9|*%0FññX°…¥žÏÐà+)`ã~hPz›€rgŸ#¾q³G¹êú-jéÄq_&»ú¤$Á»q%|–¯B$phBÛ>ÇZœòa¹TÇ¢²ÆÑþxümÊw;ŽöÏïù¿í_Üh2Í®WgÏ(tò,Àìf««÷rèܽvó GtÕºW{òKØ”`DïÉÜÓ)Œiþká ’n#W4ç4ãuEáÌæº“à!axé‚Ý>g}Nqf'x7òþx¯Ì¬Eƒ }¤_·+F‹K«J$\–› —kWˆ"Ù¯Á?T_ó˜ÃÇu–À™ò yÂ2Y†ç5õ}cª/èÐà¡Wõ±”*\:µÙG´R£X¤¬jÑíR±ƒÝWGEßd¥¶L;¶?mýDgLäSHß~C,biøñ(«Wû » ê‘hâ£c@ÒŽçÛcÛ•§ž¨ìߌÿ*>+†`nà¾OÏ“æ´7ÈË¡M?ÿKŸ=îûâÿù ”Ÿï+Ø8Û¬ÀaÁìö)Ú%³2•£òUó¿³X18k  äY®æMƒê¦ jäð:§!›Ñå}(Ð-S ¢¯ ºîŽM”®uìªÆÌ\‘ÁÙõ4Ã<ƒÍ8Ð[½þ±/)ϬÊ]Ù™@“{¿ÿ(u!špÁ2ÁVê’þÁnUI|ƒâ:ñ† ;3/£`N`¬Ö«;-Õ'¾•ÿÿµ?úçâêâüíÙçßòòwÀßõpƒº/æmÐ ³ºÚ)+6ÄyæÜÏò‰äú[2Xu©môè#»HšD8\:jHå\zw #LyfkÛ”H¹ šŽ%j ýz<À`Sáêþè%I駆§RÈ‹îCžlóE•4’o*Â=1’©ÒGÙT£î—Ãcß [ðkÙøäl‹ì­½óÜMöÉŠwr~žÖxR$­Þ˜iÿkYûW}в§¡¨%-®áD·Þ§gŸ¦t MÏÍV ¿8ÃIƒÊ ƒë}›2¬¸¶ÅèŒÌÿ„ŽoA½$È o–àG x¤²ÉÝOùÚWµ·–*üs³8j‚CO :íª y(În"·®xØíkRº3Lxc[tÛ95˜OÊðKR±¶F0ó¤ÖU¶ùDï‘Y®go–$¦…Xwn¼zoXdùzå8vNâÙpˆŽ }X;ÝàÈFê658;+DÃR²¼¼›iéåÂb{’}ÊqÓ œ`Üœ^áhµê6kÏïÁà­1DšÌGÝ Šã7%H‰ŸÂÅÜ 06»]y¶ Õt+âµ<µñ¬ò®ÙM©Ø‡çíÊ‚a¤R4¥&ƒöû­¯e%1ö4¯QÉÞ1®Qåµïöu‹nM{«@•ÒÃj• è𥿈y(_"öl/uÕÓZ—z ^Üín½HMÌÇßL"Cý íÜ3 ýפGÔ¬€=3"Ÿhðd\ØÆc´§tŸï–¯§ ãg{–$Û-€4ÍõÜ{µeN€‹ö\~^©ØÉõ‚÷wÕ3DtTåv5-ç °º’3ìŽí¢£W|ž5è—ócÒÓÆ’:íwŸèÔfHs•K ønåÕhâ”ÇXGéý ü—f<3â«u³Åw_¢ÊóBDi±wàž)'“jK¬5‡•ä®û%!7*TдT¢,±ÎyÁ$hë§ „˜Þa,C5dv'êl|V¼H*.w‹iûaé´”ÀtLß¡Y0‚µÉžI:åCtŸ%»9n=þEW&Ç¥¨ÃoÇÿãƒç ×* 4½@'nP5'™ “?ÿ>øá Ø19ÅÚ,ÜkßàO¦•§ÛÇdzºrP`BO—öz•©Þð¶Ï #X± àÍîgq‹üHôäg^ ^‹‡âaˆ¬MbÁ&÷>Éèùè‚ß;0,#ªÓ¶HS"ª§[ 7«k‹)Ã*§ ×oµHf‰¸*< z5hÄ;’h„{C´) ®‘ª°5¶G·¹ªEÒàˆ°s$;ꈱ$™¢ ìÕÿ˜Ë?>vÒí¯êÀè–Š!£qäZùËV‰¸§(!ëfý×_ÆDëaº&öµñÂÚôÍú-ESg¸±oë2ó¹"F©a}š›BfY¿HÈR.«æ søÜ…£ŠIg‡àÚÙ€ÕbËv›@fö­$Kž´™9ük¶Ñu«Íb#Š•“®˜IbsŠÕ"²0(Îr‘b÷*ëi?ìkpz ×8”ÞðšÉ®'!„úWÖ’ÔUd„Ó3¾Š4gl,I^¾ËMâP NeÓ (3m;}½©.¨oжÉïk½cÕØVÌŒd%ùu …Ö¶OñÃñ'ô¢ôAf GÍg)‚©uWÓ_ØZÖFw}ÍÉÒ 7ëg%6=.ªi¨°¢îm¶+§7M”Qÿ P×ø”† —C•®½Eð13F|mpIAÄW÷™<Þ„ôõI?°›ùh[.ÇîÎÔ«JîZ|L^”8]:i¹øŒ^0dP¼QfF¿aÍÂ@OQ¶˜•nÜÔV½ýRÒêÕ±~÷ÔûÖ“Çr2§pØ5n¬½½Ë¨2Ó!eÌŽcaì k·ØaÑÕHîþ挬vzpæA0k~›ãa¼»0µNùprò–¡€P †Á´@0N®µWÁè°Üý.÷wàŸÆ×¥•8µ¬êB¾¶*‰®×smõSóÅß¡Ïõsvy¿¿ÿa¨D‡àzKï`»LÌ–YoÑ:©¸o¤KPÕÇîÏY+uÉ (.á5úì>çQ-‡—Mÿ” 'YK‡E¿üt"gØfï«U’Ãöízq'M‘Û¸‘òÈT橨ˊÀd^9uóÙºF‚ί±ôïX&z4~@s=cšÛR–Èwa’EŸüèŠÅØ ¾QêQ®àk!ÊÝ uŠjC6Êó Ë;×wRy:ÁÀë´—·‘;Áš@µŒ©TCšå/쑚„ CÞf笯©“; vq¬{ÅŽ ˆ+·vKâ`™ ïÁÜñseyÈF“%GE]!º¯ E‰/†ÊNÏ(”hOo‘P_Êä˜ÌÉ]KÜnÃKÖÚùL{”^áÒ †i,ÒàJƒ/ÊG1QJŸ*ü>·^fBŽ‚¯‚G\`>$Lio‰Ê[ü¾¨9‘E€öé$þ’âËÆ÷•É–l6¿k™u©xqÁ±P}[JÕýÞ7ÍÝ2ÙUfuû©³ÝK yû—zs¥”=RJY‰L{¸Oµ%žGÚWÐè®.ººÿhüé+ê¢fl¬trM(¼|(à’ÐrLè8R­¬?¶]BçCÑ‹2âï/DQ5'Ö?†×Ÿãìg‰‚>qìãh¯Îº‡4Šm²ó¤µê”ð¨ª&Ü÷”¸y\-‘|WlñIz@„†]p:ÕÇÂê»tÆ}`2÷¥qðÆk#ÛG„Õ uœ«ùQ÷r~>þ*ÑÓ›« DXêÄpËòô/`íTµÒâú ;]²vW›ßR̯,‡r\_ØÖ”ûÌÜžëLœÜ2%Æ&ßIy”°ÆõptF;‹HVœì]CUÊl¸6sbú‰¡Ìfò¤cÒ^µ×;³Á¦aòäù˜ë'Ô¿ ÿˆØUàÝUßÊH˜NB&—'ñÇ?ÿÎw"-þ{^’§'téAïöÜÉ%·@±/ÃSü¦fXRcûD‚p|–#_MÕkøé¸D{íI±é´ñªU æ‡VÍÝÊÇÆ,^6¼ñcÄœ{޹ÓʼnvP,Íæ Ì6uo)‚]^cpªGFýBü¥^‡î(â½y…ÿ°<.TŠ-ÔN°€à‰YªþÚ{ëÖ<œï’jÅ+VÕáÖ°oáÿïŽþ‰œ@Á~?´Å¿åòíwÎðôòû7=`¦y>¬BP‚‰ˆ²݃n _¹&šæš'C‰hãm Ù‚™ºBÙ«Á<ùº°i¯0euüá´ý M¥ízT/¹­;2}ríÖM0˜{í)•õ{—åö»JÄýhw”ö»@Æó Aâ(ƒ­ÕúËþ öÉÝY¬Áx^Õ¡U6×=MûW´‘BàsÅ®7éžÌ8âŸFj}HÉpk’§\±…µôkß CúÌŽl´‰ZªŽ'Ÿs‡o»ÅMñÅ“¾D*Ÿ™µ†ùœB,ŠQÛ³1,œÅŒºbÄO‹×…ZJ)K¢â‚Ø`΢ ÈØÕn˜ñ¦`Ò£ (y§-¾®ÐY7ã÷W WÉU$o­;¸;+Vá{nãö§—Œb©l¢,ö§×$ø$íd|-øHFÐä†>Ò3½ËIe\)U±ßü ö<–±9K è™@ÌôB£–àlLP»S|ä}gÕ‰ÃC^ŒÁýäuǧ¡’lòyŽ]Ë*ë›ã8w%'?éæßÝmÇÜŽ'8Kè Ì6w!Pu— ¹ÓöHÝ~ì»ÄûFÿd‹,Àq@/iªþ`\½Ý¼‡p“¨é³UØ~§çù²¼² =@ºÄGíM†|÷: qåˆX3³‡' ˆ[+YÇÇr›°É&Ýq^›E¤^)bÍ¡Šèß¹†ú£ñ?¨Ä¿­ï[¦ù ˆ.D©qè¦ 0Ú¢‡9 ·Py+@Æ3„j¿‰+ªºkImÖH¶Ô ëÄAÌlÖ¨ƒÀvó‰¨<áÀ; :¹T¡7’V%&Á[¦F…zr «„Qï«å9JGX@tÈ(RÇP7ÉOùΈJĦ ºÝ_އ:DÅk ×'÷Üm…~¯âÍõ³ñLþúyã#âè±Y…è§ÆâìÞ(þ)œÞ)ÍûGô ºë‰÷¡ʳëì—¦KŠÙè*×â߃I•Úš¸Îâ«Gv•uBÁ™r‰ Å¿çD$'ðFp™Þ1ì†è£º¾e>†ñ~Þ«JkÕ]¦õxT½›æûðozK»ÿšý¦B.FÖ‰2g¼ÆOÁŸLœ€Lû¸á/Æ|©0»Ttñ£“8YFQG›‰¦™8¾‰i­‹ýZåõè…P»~GV‹ý‚ý(ÕÁ^‰,}œ•uL̆0Ú§¢9t‚,`4†9`öñt"†,”¸FáˆM© 9î£U«É«®úWz¿ü•øËvÎà ŽíckmÃ?éi¢ÓJBñ§‹‚ qÜî™Ûi@–5=X“‡çD<{m¬ÈY]TCUðùoø¿ø£ÿãr\Üüÿ~÷ï§É÷Ü8OÈû?Àd‹9pFÑb[¤è‘ýpE…8Ê/3åÔÅo§ˆˆäU±†®v"¥•¨Öv¼ñ¢eÆ_ùj¯ºI xcnÈcÎ ¢¬:,l>šÈ!xBMfN8‘iG¾.…†Ž¡_ÃdmÕd®U&±ÙƒA*OóÞGÀ‰¹ÒÇÉèÁrß[îB"¹v(yº(…¤:œa½wFYeã¨[eíOÚæòˆS‡0NœØjh|Ý?Þæ×ÛJkè‰Ða¾7E¯0ýÈÒ‹æNLAÅ»ÊõX®t„>Ô(véF¸¦£~Zµ–žM/ 4²Va-x Dœûmç}‰˜Îpì¤ñDÓD¿æmðæÇX^ž;åiͦ“)+“M {wS€šØ?*Dùç²ëtg~~iªˆ©ÇñÑLÅÓÔîîµ@F?.XöSŒîƒÊŸEÝMÕâŠÛaŒ´œxÜ5¥ë]ä¥Sí; ´S&^¦ÖÙ™3ÉÆ¾%z=‹9£ê0e%w*N0<ÕîÚB[‚“¾Á\³,†4Œ0ôJ§£xŠÈ–»È#ÉqÑýP(xéá¤îÕ›› GC]·ÚÁ± ;ÄP#Mª‡ÑSƒ–ä>´èQDÑvŸf)Š0ÓâÚÔCLô'óÄ-GÊ^Eu%¼U„Ób÷;ßËjµa°{2`É~¾ýÒ0îén™©%ŒbàäØÀÆŸ#}­{צÎÈÉÕ%Yr5¡T6ãþvÖþŽ(|Ñd”€ÿõöãÈV]-ó\A¸¾"î‚•´Hê“[ È’AJØA„å}(6Ï]é­·OÍž¶æÎF't·ŽP­Ð§Šì HŠ+=Ÿ“¹›r|—Åqàõ;õt˜ˆiÇbF‘@¸äG—[E…ί…|ŒZùwZZ~2þá²|0«ðù~³nj¸ÐmðèïÃUyá¦Ië?×ù–¸§>PZÝ,ÝÔUÈ´k•Å@:¼–¯Lœ¸A¡#î‚VÓ5X2@Hk)nså¶ „rî­ñ`×Ä –™BñȦ·ã(>1J£U­à ³ù>üc?ØŽÏí Žh¿5nBpùПj;ð“ñÿkñÿúiƒe)ClŸP5ŸÄ´æ^•¢o”ÐhMï»°ÎFtÜç[žáwÌJ@Ï¥éãÛj:"ÙÈ™uÃN÷“['`¹XDn쳪xuV€ ûº@êbneÙ3Ý*{ÈQ‡3Í¿ÿˆ›ü2ÛT¤Ôï½eŠÅ¦ÒôËWSéÌs˜ØºêY5•p:q´Ñ'£¢«Ñõ‘üÿÿ)þ'‡ôâæü÷»?U¾çÀ…üçÇ,¥çI ˆ“–[¶63s4øežl¨y!$㨊í[T ¾Hwnœ£EUaH×€L¶žâÁaš@>ïc[d("HQ+g¼q¥Îõ™ª‚Á ù:5°„ntg¯?ÀÜØ8ËIÜÁJÒ>णŠa¥Qœ/¼´ÈǘF«8 Ê&P_æß®Áø.4›>QcUçHAìÖëB%Q a|A™ÊS8Aíÿäh&í¶û}µóœ¥;Ee®ë#û&J.œÚ‰x~0îŠjuÚbáŠãRnjNž”ú\e·ãGì*QjGÓžì©fWÚíìÜ>Ÿ¾ÿ }ÙVLšûB3™«÷^ÆÝB1ùÛ±œSŒ{ra×» “¼™,qžH!Ù…N3 Nnr …kV˜kUŒaɹMÀÁ.'YÜÏ'É'é"3xÃ7O"»ìÒôá%æ2×ÏÅ¿Z†Ò¾ŽSý‹?–Al-Ò‹ÖCdNSP¼îTÑqžECj3¶_BL$ý¨Zš|GS÷ÍåªÁ×Ûõ·š1$ÄçÙ›'Ÿ7GºÉ¡Œ±¦;qIF¬÷A`°LDÞæ ¸¼Õ,Øñ%È;ûàÊ„T¡ð½øÇŠæ^ï›™¤Et}ùF„ZzþÇãïD&õ—å¿Ô³ùhœÏ]vþ¢+z­Ô<ð.ÊIh˜ca£LvÏe4Æ?ŠÀìN>Eˆ¥”t¼%%éܦ7q‹ÙV8OGmm¥ÆÄ“AÞ9Ù[¥}lÿ`>~—ÊÂ*¤ònVéÙ/ņvãxŠZVÛÍî#Ônd=Aåµ–Yömð›ó³Æ^š»¶^艟D“á¶‚ˆæ>ù¯µGÊþ{þ÷þOþèÏâéäøÛû[þ|×ðÅŸö„üÛw?„XN±i\·+OÒLÚ`ž%f{€@ÔÄC]òXw<ÖÏeÐ"•¨5þ:ºûŽíf±é^hÉ–µÛG›©Tzð;KŒÊ’Á¢M±[%î{¢ûÁà&ŸeI†Õùõ[Ü ÖsЈ±Dpò^‡ÌdËÇß;£»å0¥‰†Ã¼M6ðÉÚ ªý-ø-Ñ'/´MZ:¿ÕWx±‰bGßD X d=¥ƒ3­r]o{!(ôHL~r ªIÞ‡x>äÒœ’>BŽç|Ü!ý-8­÷7Ã\õŽˆ=Ÿá!†e‹ìÁEæ«oñʨ£p׿ƒ– ÃóTb¯m {Õ¤–ÞŸØ>é@¶®RG›†&¸e Ï9°‚¬/“RšV0SÜrĆ#5b»¢eÚm³Öv]Ü™r¸m)?½¥†×T¸&çît€Y#׫¡ÐGù3TQ£»÷³÷tà‹EJØ*ÌP‹õÕ“4Iî©ðÕ—oîÀ`)áJw›ˆi k{ÏfB|éìz2€Ó¼HxÔ¹¦ò’é$:XûúJEwëèŽ-­-ù¸yo¢Üœãà'b´äÙk¼Ç ¢¼  õð]¨j1óº¬$ñê;„PFSVÛ‚nnƒòjqõ¸4ÿuÜBrÁ:Ÿ”ÎhQ¥æ4ñ–˜éW7f>…®¢Ãã°~Rú±ø?2ÌB~£ìÙýÞ1ÇàéT2ˆÖ¶ÁB÷ÿÑrgÂÊG2¨4 —:X“Qh©¹e<`÷î8AKÿ͸&¢! ’4Ù#¾Le­Vý…ÜTÊ^fã–p„õ°ÏÑL˜yE6u^câþ@ˆcŒZ=UõqN›¯µ~,a±Fðz¢ÝNڢ݇Š!ÿŽ©ð§RhcÊk?ˆÁÛájáN[ŸHÏC€C#Œ]¬;g-O`„mi¬©JV)Û3æîòƒæ}Ë÷LU"¥–SÏÔéÃ6%Õ‡f5j¡5HC5”tðÞæå"èg´¦)ð>BpÆÆqe~#Í-S³z_J©®3H–3&ô»ñ?–} V?~‚I½]#è…öðeøëò_sFöñ@NÐ^l…dŒlÞV_pl ëŒwEšÞpáS½ôV¾±èúK®¦Ýäéì2©^¦pÛLÃñy¸¶)“ŽÈ”5N¸‰ÕïÍpáÛÆAs:?ªY;VŸ?b½—â¿öKñ>ñCâÐà|ÌŠ"ÑÅA*‰°,—r<­@‰G$,S§"æ ¨óÙ¤çÔJzAä ´ œžþßñÿÕÿæþ$®ÎÞ¿û÷så;ï\œzý›wM,¥µ0䃸úΠåéNeÓpÀŸdÛ`bÌîZ™p[ˆ¤¶™?aÔÞÒ+¾£¦óD4«É=j]þüŒË57йîHÐcµØ»ê&íøJ0ØiÃpÖt‚TdÙ•<õážM†åZï‘Óµ;‡¯p͘§^:Úr‹PDêÔÁÀÂ"¨S¦U øy’E®êY =µ©RÅûð0!O@¶»Ù¬Ù§=\oü(wó}o>Il Ú´¯ À!áFDf!F‡õŠi4‡5LððV@rIÀZïá0y~þKŠ˜,]¹°ò •©@3C0I¯œM7´«—&ó”Ó´ rSù¬ÁŒNŒ$VƦѭ˜2Y°× î÷dK‘Â~ƒ”1Yv€˜­pº\|;\P/²r0ŒÆû>sV>kšW\·˜h ÜøU–eþ«qž Ũ“„Ä|彜ù½”QW÷g°3Ф&r¢õr´NCS[¯=V¥zEevÎ0?]—f_/"¹]íô!]§Ž Ïij¤±ÙúÙ‡b}"=´ÕÙŽïy{&˵xe˳üsˆ½ÝKØ—i ŠÆJÒ¦éU~üàz?³¹îØ©E=Îü¦ ]Æp–’(e×ãaðw_5LŸüXüqöäíôµ¢úâ*ÂaRêuœiö¬ ÈïYö¢l“[e}îKKá¿™ù0Œ^•ÂŒ*Ú=:Þ6†¬£F“É—^Áà[—½¢õ§Ý¬§þ-ûia-éÕN¡qÛ“²Þvª¼L@"îº^áþ`àš¯œoUòRZÀsu¨2,¼ÕŸR‡½Ó¡N—rÉà™¸QjLö#7-·‚;?Û¸£à]h’áëL/LÊ4?önfääsϾ3.6¼Å­°Ð"Ýj2àÕje3e¿m¢,–-2™†&æ¡CZlÕÕ\‹±  ×¨Ã w;&“Æ¥y ¹Àð½Õëe™ÏžS±GÎÔ𯂩âý«¾ÿI-™žç!h[å¼3e_þŸ‰ÿ_‘ÿ èÚ÷Möº÷¼['icÌç„Ê=UÚº7^o;}ÿ&d$rc¾È%<9P¾Í"ù^Ÿ«÷‚|&šfÁç·ÆïfÂà÷Sã*‹ }D 1l½WŽü0_×T$!³LJ¾Œýµø#a8t Ú`‹°+ØV; \·çBûCœê¤£‡Òt‹Qît•‰LéhVÎuE'Ù|ísþ¿æ?Áÿèþ NÀ¿ÿðÿÏ–ï½þÜp€Z×KÄó­CèáâÝ-æ®+OŠáÉö_ô¨É¸šëŒ”’{‰ªµs€|ÀèüáAÙY¢We"Ÿ —T‘¢nÇq#¦™ 3Ãyø/I”{äTÈ$=íØ‘>6Þ…,ÂØËK¢]i>Dk†©9-(°°r<úˆ•†‘Èò3‹ÔR.æøÅ*²Ö7hyd¶÷ß}‚ ›„t¡4ÙEVÁì{Çl†ƒiâó3oZ[ž3blWï´Ð¹.‘Nâr×,›ù¼Wnž=ÕÙ%vï’8 2ìÜl|w³ÿh‚}{½rá½}»üˆïÝ;þíܰîýýÃ܇˜qgYÝÊǾ,`Dä!(Gï âSºfžT5÷’~í'#@teK¡ju‡°ÔS³©Z„hãE3*èxOïøÅÛGG<ƒÍÑoM¹ãšÃh¢´ÜI€¶ÊD:™ÂŒºVe5È@¬Å£|•Ä݆ÂmmnÏ']ˤìšà¨AÚêÅz3D²*ÍV»³Ò^âèy’BÚÂßB=&+±¾m÷Ž ú1«·J´¶5Ö›û öžt-èOzx†®·–Ûƃ);^¿ÙÝ›iBG÷È. Ëì´ÑŸMPå'ʼ­áÞY)· KÒZ׬!î”5âÎ:šéy"“ù (_5Áè‡âïŠ]7u/âÅJ@c$¹¾Ÿ#–æ±-6×Qmp„(CAG¦zÝÍ‹îPFÎ(eËšó]åvÄvÏê lgÂØÖ£1æ·mX'Þ*N‰Ñ¿3_¬;'$gÈë—#pP:o/év°!Äޔ،uã†$I¾¤°˜Hñ•ñãòýˆ¢˜Ì‹‹âÝŠFƒ .òøî'6Z¹•U(ÂeÄŸ‡¿õIk˜Ä£¢îzpÙž¸Æº9dmmŠÕèÌUÚìÔïÄsm øžt{·,r»¤ÄDN••0î½ÜœÎ«¸t³aÇȧ©w5½•+ƒ³+F>¯u c†ØX¿ñ™ ³r¼aØ©­(m4–· Vô üúò?Bj3åfõê;ÞÖÏñÙ~þQþˆ{”¨*’Ü0“>Ià}ÅÒqè§×"ãWÀ—‚f^+´FÖ)²ÒxÚþÇÖïv¦ÉöµþƒÛo—¶Íæ*¤UÒp å$b¹°Æ³óÙ8#-1þ[k7„Øyîâ¾<Ìξ3asè¢/ÕÔx¿^öRðšM6b<œ¡*iâmÅûñè.ˆCwÃìoÿKþwÿþèw¹¸þýîßÏwïï×1Àìó/ÂO•rPÉ'!òÇ1Ê’¤‘ã.Ÿ^&¯Nj>nïÞž`.y ýO}ë(룀@…½8¸É¾×8Mì%™ùq|ùI*r¥À­ÌVì=Ù4xÐSÐöE¯ŸH7ñÁˆ„­{ŒÊ ±@u²¿ÝÇѳ©z×8~Îá–~6¾¯RHJ‰cÚ;Ü— `ºÉ5aênkûºƒ5w¿ÞÜãdîÔwX¥špk®/Üݽ9Á´6Ž 5ݵÜÏÐ< ï´b?l ZìÎ5žZƒT•å3ß—ÛeIÉG„e[Ù¢¤áꫬÆeßÁÊt¬H¤Ãú³ê ` Èâ<)Q©ÀO@wö¦îv8=T Ê“Êg=9°Ï_Ìt³1?̃7©;†;ˆ´ÒÉØâk™–‹ÅW2óç}À‡ÑÀgááSÝG;¼ÙÌpºWWX.o_Ÿ1<Öûži#úÁ$´‹N\ @§«ËÙr}õvþ›­Wb|÷f`š*ýsÑëדqmÙ„ôåú§9ù`Ç©&mµÐx:ú„É·Â*±·«@µU¨"$,=²Rð”}Œ†ïnwŽ€ âw§Ø?ƒ ^…‘¨f MLÍÜvŸ«*ßÐß¶{!<àÁìâ=îÕS´žêÍøÈ¯Š¿Ag÷e?\ENwÖ%ŸýEm @œà Ó=Ôý®‰ÿ‚;·MÁâÉìÈÙ˜ð°žÜ_·ÅÕ»œ+Á‡¥T¯”Áb§ôN3wU¬=D¬(¸ì&\LàOä×t£6žmË¿‘·‹qjñ?ê0¨,åòdƒb!‡ËÔKÔ‚WrƨsÉM«îóZ_#†<Í xŒÏ»9Â_\f<`‰¸KŽ)·Xooµ¿à,º{ôŠ©¾žüÆÏÂU,Ù±ëñÓÇ0ú´l%šwð;µ~ê-Ö{c™ñüNùD1nñ£€æû·êSªôVŽBGИj·A‹/¡zoîréæ³L¦¨O±Ö½–¸‰V»m|SEº»´OߘT#cÇ_‡ØæŽbî¾>ŸR骕VAtý΃¿7FçRTáY3.]Àýçá? ÿ¿.ÿ_*Ì1ÍŠY鬴›(ûÌ.=ˆÜ}8Ó­cêlÓ~xÿ´ä~ôʈ íYïB‡Ï\k4eÔ9(z7#>»º?îÔ†ØW(arà]ô®‚ÃÝöQÈz7œúÍ_ŒÿSøØþyòÃFš¸%ÒLíÐs#‹×½1›¦É»bWÒ`ì÷]‚q¼Ò&¦ŠýÞ[ïËTxQVý þÿ¸ûÿîοû÷ ÄÓó{ï€ÿÝcy|^“É<ùÒ³0ž$òFÌ/$÷,òPØo¨xÑ–bó¨*<ôiÔÇÏÔñO#ˆNR&<Ŷ̙ì^?š$±@ÔrïÓ’H(߯ƒ±¥¼oG†u2â°/Të™eÏÁT~ Öéla-•…b ¶ï7»µ™4cSá0‡¯ËÙðÀÌ_è£IísÕÚýZö0[rüŠî *¢Ÿ-7ø§­î$®X×9€ñ4qkÍHbL¼ðÖ^«²¬ÓÂK‹½nÏg&BA!èœ6C(GnZ)}­¬òÅH²K©SÍôN0” ê©¸ŽÁ³¥®kHüË]³û¸ñ~A¸µ†ð¯ÞXÛzªãÅïÊÅŒ‡¹“º¼ñÀÝS†<çìN±È³—…oSbþx»Ý¥/ŠøLͳåÞƒC-" }†þ-z]5xb++„–CɵX$êòX[óÁÔ: Šëïo¶+ðÚf뛉~$2n°šÇö.œ1'ð=ö7‚yïtGÞÇ—«Ð aç(â=m\Y£1‹MY[Uß SÚÀ' ç+è†Ö¶Z¹A¼šDÇyøñ¯æáÙÛgÒ~$þtâö´M™ûn šE¢,4|*šØÚ‘¾¶}êæ©Ò°$°$âCÁÿÄe‹ŒfÚàa¿øs Cs°k:|3ošÑ7ÞÙ …S?yAÓÀ?ÓS=~èÝÏG3ãäYpð4%Ë’ß¹iЧ¤ÛôL”iÊSU^Ê·òàj4¹¯Qø{†rÎʆÛœ·z‘RÇxû¡5Vû÷)6Êe!Ñ‘? 0!ݘ‘«V_qµÜ³ÊuÛaýh‰pùI´›°wøŽ7„šIƒw‘OW‚„2Ìî«å¸7³ß&¡¸ÿÈSdÀ’ísO÷à; ïíɇý3Ž òÌm·ïߢ·)M @às")È䥡‘¦çµ™{ú€Âö}®´%ÞÇýÿ ÿ÷ññ·$ž!D\¼qÊþ“ðÿ óß0i›/p]:éà´ECƒáY.l*û›xYêŽ'!ÇTLy´éЧ®H•Aëf0¦¸¶äaÏ{J úÊæt.W:¾ü§Ãº,ýí«È)ÄÇë]¶xÙ[ÈÅ×U¡;Ä÷ꀧ‡×—2Ðï½¹Úõôðÿúéß@/oÈÅÙξc»T:ðR3à‹ ½Î¯ðý½ð¼ô|ü^çŠò½.ê\i ü¥g—…¿uôò½¼.*ºúø\üO//ÀÛÛÓÃ× äîã}q#Èìq^á 䪓@7÷ï¯úøãœñúÒðÕ¹ìóeÇ@?ÿœ0ß‹.] z_âöú½í‹2ðåé—Í^iðòÈe'<CÎñ÷ðö/ú~^ï\CZƒ€~ïûWÕþöÑÕ ìðKñ÷ñ}³¿í|ià÷§>\à±{>ð?õéªñKmüF‡KÍ€Ïñ÷¾$‘ëÅÒð¼›ß‚?0Àßë·IwÞÈÐ/šþ…øÿ¿ãÄù9_Éu>o@#ºØxzA žç^²ð‚N¾—û‚ÿåî•/_Ñèáyà+­/ð;ÿü—3ø×áò=7"Þ^ÀsüŸKFã®ýs»_vôpuù^þÿø·õÿvÿ?C@ߤÓï€  §ïå?ŸEô}™NçSËre®hQ×ûj¾zzúx_¹0—fàÊr\ø7°»<\àý{—¯~Þ>ÿXög3ð;ÑAž.Á|ô€ø@þ*ÞýÓää tw ñùÃ)W›òý¶Tun¼¿RøU.þBÀºõåûÒ>y\˜te4€vòÊh| >à+Gÿe:7ç …xzƒÿèû¯‚O/ð×Xàë ×UÐpNtOÿó<<}À@Oo/ /ä œ›0oŸs¯p~AÈU'®Æâ ¾th_fÃ×½só÷ðÅt_~þø—^àÿÕ»ŸG>ÅÝÛ÷Ò®]¶}©¢Kgÿ¥ì«æ. 4øä þ–te†A—úËî…uÿ}s~ý §tw þ…ø‚~›~ Èo»—ðùó¤þâ4 Þ?x‰/G=½þè/÷.‚&O°×ùX=<ý.Tòý6ü½ƒ/B 4ö~þ`ð_’ÿ€PŸ¯Säw—þ»ß¿ð´… äJßð¿œzWÊü‘žãº¢ñoqþÕx=¼.fÀ-ð×áï}ÁŸ/øŸSü<„ñ9À ï«€í²@gÀ÷ñÿ‡ûÿÿ& ý[þ³|[ðÝê÷¼à9è|²A_ò Ë™ñÕº_ìÓþ÷¼|e‡Ï-€××\|I‘+ŸöÔ¶? òùCøÿ5È]Í?•ýqd ÿßË\ xé4Á¿å¬ÀŸ7 ‡ó¤ìá ú}NÿfÏ/›õÿ–žÛÿßOôùþ‘_ÊÍÿëµþÑRy/Æïîõ~ÿò*ç6öþ-û¿Ú\å3žàóà‹‰ùÍÙƒ@Þ_Çñµx™ºxB¼/r—‹Œpžƒy/b~ïóÞû‚/½ÀyèOtîý¾äZÐ3Èë*Äø-ðÿz)ÐOÀ¿ Èr¹~qá®|üEµ ü/rLð¿Õ•¯Yäeöy~Üûb ^ø!AÓ¹O\.|íòUíó͹.½¾n.êìs>cÜ¿‡0/ÐïæüOžé\itO ¯øõ¡2ö`àÿ)¼¬ô¼Xò¼Èè@ŸoÄß9Èßòe2ý†õUß~þÿoùïÿ¶.ôÛ¤¹p§Þ—óæwü/‡äu±žá þºpµÎt€Üü~Ëù!¿9ÿKÀÏñ?Ÿ•¶¡¿?ï+ü/ò~ïÕ«`çørèKp>@wGŸïáÿOñÿ»ÿ/ßtüÝ€çe„ì¹\¾Ì´®&èí½.‚æ«Uì z\æð—ÐñrEt•ÅA¼@_cK%0¸Øÿ’þšƒÀ˵6_äw{ü—þÅŽA>_Nºûz­ø'›ñ[ØýÛät‘À€<œ}!ÿÔ@\­ÿ^~vûýîÎ#ùËLãò"¿§Œ`ˆÛÕÊèŸö¯âÂi8„y±—Fâ7óq™"ø]E¿e# ‹øx¥ê•Ѽ¾çå:êŸ"€s­þí]ÙŽÛÖ~Àh‹¶w ô"(Џ‰£ÑŒ¸œ¤Ö‰í>@/rÑ¢·é öüÛY¨±-’2†ÀPÒá2$¿óï œ5.¨ñ@«"8]ðF<€®7 N›¸j–‡É—ÞVüFÁ„¬ø;‰[\ÿŸÖ>‡âð'‹BƒN2<²8lø»FÑw[.øuÄ_Ìÿ‚Q< ^!þ0£—îVø¿ÞÚ\Yt†ÚŒ‡ý Ã4™óŒVÎçÿ@ßH{$üa +OÃõ8±¿×$E‘ºþ?7ýo7èÂg×?>¸MˆËirî#þÉC` ªŠ…Æ •UAðÇAT„ ¿Üx¯'÷z}Cü͈ DCš€PS |Cµ‹ÝéôiQý"þ¯µœè8S04åT‡QfK–UræUÁ?íivbº+ÉžX¼³ÝÆþ{;$Ïê?‹t–ÇæŠ?“€Zíyh­9Øx¤þóB9ªÙpT²]>Ž3ž‘ A>OgÆt]ðœ€Ùð“ãšÑ—,?{ù@»ÐlÖfî… ÷hTj­Ìû–rž.T ÒóÇ/ñYÛƒK1Z VX&m¼f@9în7ú'Ó½¸~yž\ÿ·¸$¶$Ò#Çm4ìò˜ÍAvPðU¯öY>)C¬9E 0à‚_AAÈ«ˆÀ}L³ÜÝÿa]K¢bvö~fZÁ!ÊF{=Ô;Òó÷µ@ÀG!øÓóïÍéøû‘¾µpü~ú¿;¦Àföÿ“.NuöàÂ_f¦èçíèE»Ïj@rôEüí-ñ÷#ºÁŠÐ€?ä0þ¤l‹Ð/ÔÉôiûÿEþ_m9Y8GÐLì•S"ràÕZ—Á¿"Ø+º*ë×ÌÎÍâ÷Ö¾ŸŽÔÿÚ XNþ¤ñA㦂B0Ó%SG±®W½"n 7ÑvûDPÉÞ(e@ÔÞgt?„´Å8Ÿ`þ|F7~ŸÌ(‘ûÄ>Œæ«Éö©säõ×½*@ Ö~!ûñ‚ñ"­°YÀ‰é=T€ üÒÝIaœæÉ ×aà(„˧\0€ûÅirqüÿ7ùdÏ“¤æÓÂm¢˜ º IåËr]·n’À>pA±4 ‹‘NI†°Šø;V³LûpüõÞ•|¿äé30¯ÿâ·ÌfÍŒ¸ø(wB#¼x¥]8ÿ5*a90‰/‹N|Vô¯÷!M,ñÁI ШÒ=…ä üÉð—ã:;ˆk¯Hñ‘­Æ¬Ú[â߃ÎñQz´=á€6ˆ Z¥Hÿ–ÿ/âÿzË©Þ÷´½I²€â³uðYs¶ ,±¥0Íw„©ÔüÊÚ6Á¥ywüÁ ·i—Bñçµ^|Þì$w¨²*r£y¶e²ԃݕfÑZöÿbþ—\ošÊ¬¶(5ÉÑ"Ø«‹5_½›œ+¼þâ¢öÚ¸~´³ ÐuàÑÔ~Vµ…Úÿ/2n†*t aÚhÁDKÐ6`¯ArÀÀ¹nJÿËÝn’HƒŒzoKÃæÈÅñ¿\Ò ØŠ$W?D÷£l‚äûXÙQ‚ '-ÎsˆŸƒÃϘ|¬*èÎM™Ù«‡þøÿñϳQd×cÅûåC·SìåY¬³òÁƒdo£qøsåïÉøß"þ¤ˆ](ß®‹ÿ3¡ÿ°ç €æ|‘Âÿ-{³Î²ŸÿZ;‚Öš}ýˆÎ ˆÇiúï2ýÌ—on‰?ƬâhTˆ°R@ *À©‹ðÊ"þ‹õIôÿ"ÿ9Ëé€s$v²§¢¥Å):äS4¹Ȱ“If¥¡c¨wŒ”£þü¥ýþ»© k6KÄÀN>³e{é Ó7û’:ÐÒÂŒçbǼwZ=@LúiºûíT«æéÏ’ÿÏ2Y&A9ºb˜­™¿ Üg±w”Hl|¶˜_@œÖ‰K ­âz5x*R*2ØÚ € 6ã“Ò€@§çG†Ü¹€@ð Gî0š,Äš2ª½?DMÕZ£wvÎü¥ñÿçw“㟖ꮲ툑dø‹$§û£‚@6Zþñ˜`¤äO({£,s|ÀxZ P yS1àxü×.åÎ St×¢^ ¡Ú‚+ådÌ ©PFÍ”; ÿö0J&8K{üŸý?rôÞs.N( ¹t0[:Lªg…E<àïSñ¦ìõ¤%ˆå_ÌRá¦øƒ¨¿êá1ƒk$ãŸí á°åîú·—\^ÄÿU—s€5pÓ"ÛÅyÖkr‚usðϰ1ÊŽB¢W*Ú‚ èÆßzõëYíObGÕ‡‘êb,ï î?Ü 9‘Ø(H¸Í÷æŽVPþS™îa?,¿’½ZoZ°téfµ‘«{‚ùÇ¿<7xæbxn³‰4½ŠƒB˜IØÛ>¤KŽ؈í¤7À°Þyª§ëB0 &X=rèÐ?èÝà]ž4ÑLv¬µ)ùà¢øÿ'šÿ©†Œ+ǤܟµEüÉž—1Gœ,Ÿ6k>7áoRVdzÉŠ‹ï¢ÁßHÏŠÏf¹½:þ&ã_MF‡- \1”7#þb5¦ãúPìiÿü ³ñºpþn?«ERJdB]þýÜè¿n ¹Py"Ç™ÿŸøh0Ýk€˜ÿ¤Ý[ õeAÓßÿò:¡ *€Í0FÌ00 ¸ƒq™Í ˜í§éÿ¢òÿŒ¸óËòË9{e¦ö$×SU ”+¶3c‡AÅÆ™íÿpgÿµ‹y]qbPÇy[ò„‚ }wÇ—-ˆÄt©xNm¸Ò‹C*¢ã•^õûPeÍÿ³Fž7p²f“pµÎ&¤c$I¹yŒ¢YqÓ.S›¿m6üÙ/€9F:Ò« )á_$ü,yjþ©£…`Z°HèêÜ8€=–Ú¡A{7ngKÀg4’n/Œÿ»Q‚ÍœõŸ¤;'9a“Äß§r"ç©\ðOœºõƒ“´nÇAÒ,(«ëÛÇ`‹„o”G«kã¿|t,³!+ÄÿhžÆs«ˆ¿¯üCI+8(ÜŸT”‚|þËͼPI*ä"€káÿ¼èßB!Ï÷Qúÿ±©†”áJr üt•æF>â/] ÿœ ^ßá†Þ FþFú) TaÔèß}Šþ/*­_Ìÿ+/g9ì)€ÕÞQµjã93þ1Ùcɳ‰}kP?£bºüµ?®Z}À§ât+ᦉRLßì’{|ÄÌt©êÉV{g¡—»T)”äªzð»bög–Oî3›ý¿:¹ä:3%#¯M)E¼*êÃðèoþ| ê±±µl¦¬µÈ” Y+0y…=@°0»\ÀßRP@‚PÿƒÌø”îß§y…€ÿa„T»ÜMÁºü¼œ1K…‹âÿßuÄGÎÀA´,U‡…}0ìÇ&fØüŦ6?”BIZ9À9 @üÉÿ¯9=îe¥¯‹ÿ«wåÕ™á8 ì°ÕCÊ×`/—Dku.œÂOÄߟ‹ÿý#„›¥|R[{eüŸýO;C5úÉÿӱǀ‚(CXd/9~ˆ?û°wÄp@ ü‘„ó×··ÅÀt!Àÿí䨦R*ÿÌ- †ßÚÅæãôIûÿEü_}¹¸ qjQˆç°nkÚ©Á‡©ƒe'Ú±‹ÆYû…åÚŸ¹úOŸèËKƒP ó”Ð4>ו„n)ÝhFQ‰1ëvíó“CL`Ašò'‘ÝÄ|Šä0L«¥cÚP¹ƒÝŒ@»Ûh õ6êá¶´€“Lr×¹}-: û¬ ˜f&±9l}S ˆ5—¿£¤§¨èîëÝì6( ëõa¨sÀˆƒ«fµŸ\É8I>Å /ŠÿÛ[ÿP6žähv!KA âá{Øp=ôè™ndžIºsn¦›ÌË;°€ÿüñ!þÓUñ_øÈ"þ"¦²$;.ç ÒÙRa¯rg˜<³ë²°Èì»íÙø·£ssÀµð†ôÿ¸æúQsìÿ×Ô%C›še\ ÏÓ„¥Ú,õßò$[†Û⯱Dž‚d W‡=¸v"öˆø|ލš5À?Lÿ/òÿµœ°ŸÔRE%Ëz`‚¢õÅ@Ó>˜Aœƒ¶´˜oÒÛ¯þôdíÏ“xtÇݽä´ÁôâqÞö»`¸X÷2ã ´‚Žž3õŸXSÓî‡Ìê þ_ðþzc2N°Ñštõ%·nKӞ€u•tìñeë:Yõ àbî“ù•ìk$(ºïFé­Ó·›-Z{,†€!X³pÝn¥·C*FF ÿUŒ‹â_µþ‘:?éH}èŸîÐ šMP*åüÅæ§p¾É¥ìX@ÎYRàM¾‚NEù/®ÿ²ëËjµ»"þŠ[À>Æ ÐŠ÷óåzHKX™Üópã¬.ì3šÿú3ð÷Ûáø¥×Áÿ9Ò¿: F’F¤ÿOßo²ÿ_ ÿ¹9@4Å{(8ˆûB~%‹|îX7vM{cüb)BÄ@üí pp‡l‰ñ#ĺ_µ¡ÿ Êëñƒå\€ý„ ¸ÎÇD99AňÁ´Sèo*Ŷ¨¢iX6þ´Ì€ÍýoRí©4ýJý¯x7/L¬ÊýW’“¬QhÎHW-J†‚Ìä˜xg*»ywöÿæK)d|í ¶0½&3¹`j ÷¦ õÇx5Åç%…ÿuôA{^…+Ók€ŠRw|h…`úû5½|„éíè@óÇàà* ¹×º[ºCÊž2ÔPL,sQüßo Æ¨¶ôs.Þ‚tÁJÿÎÌ7DÎpÿ;~APîø“÷üSÍ?šm`ê­Á‡ZP‡jšëáÿú óxÊQ/­ÏY x¶ kÚ©ñ'Ÿl5™‹ÏVý[»ô‘ÿÏø~] FéFô[D)ç ý7õY©@4üSà#¿tO®Oh ,/,Cb·õŽ–ß P Ú¶®HêUÍÊá~À\ÎŽä†0àaíåWÕ \_ÿïÖw¤¾_ÚÆæ\™pF…ö¬Æ²+z“¼™/Žƒ#€6ç”ÕñOYie¦Ù‹_’# ˜žZ_ÿ¯ß‘OØ×–›»©˜§¥lêxG §°Ïó9 ¯Ù[»¡ä3ð_~—Þ H»\ÿçKÿÛ­£?ªï7âÿÇ÷l¡9íØ90ê-¡£Ê¤›-žô{è1áð÷;BÂß7Æ?šúNZùÆUÄßêàà9¢³Â,DR<´n¿Ý~€þ/+ÿ_ÄÿÕ—ó#öcºùM™º¹_¯G/¤I/ùªŠ×ÏIÃo¤YàðËßFõ?¤\;cD¢¡A*Òžú%—ȇ$Ò@ãŒv‘èº5‹ÝP0‰rÌ©[ÆÄÚáßtë‚ÙÛ¼Á¤! ç0k’ågбå–Z„XÃiR¡2°wAr¤/`¦9%u¤Z±Cª×ѳ¦î«Åéf0ôfPºîÎLZ^ âŸÈÃÞ ¼—jpÈ;H‚½$þï#þé}14Æ·È¥è2¿˜•ØÝ¹–ûÕë7exùJ@ñˆàq) Aܘ9ñÏÙ€…ÿß’¹·Ü\ ÿqÊ3“ÞX—÷¡°¥¾ ;R²·!üåc>f ˆã³ðWB¨Ûkáÿœéÿíh]ÎÿøûÊÿo9@‘naàÏÕ;Ž„?=§¢Øwéo¿5µ'Þ™Ñ@E ÿœ/dRë§¾¹šþÿ-â-ƒWxœì¼XUKû÷O‡HIH—Hƒ„ Ò)%ˆ‚t Hwlö^°éîFº»Eº¤ié’î? 'žç÷{¯ÿû=çyÎuûÒaV̬Yó™ï}Ïڳ׆~’í½}ÝVmÿØÿÑ\Ï?P ìv÷ü_ðÈ—Ü ¬4'¥È«,¶Ê¯ýrAâ¯Þ\H9í°“üÔ œ˜¡¥Í“ˆØ@Ü3¹ŽQ#™Ú¢€²æëgR*n/¨ß¤h„!4ÓÚëeç~¦D¨)2ÎYØ*§i;1ZŸÂ„n½Y¹“l÷š.Ýä¢ÖÓñÍ]®&ù/[6Õ»»ž>ÒLr¶é5š âUÏz#®¨Æ,Èß*2ª9xbõô}]"¶v‚pÇÔwg,hÓ–kö¥Ã¼g­Çê°{öDF¬6Ï—žGû¢¯–= F¯ïªÃ¾ñi™1øsáVàû¯¡s2a^Q\ =uölSw>æÞÄllY<$wwü8ßKGª§øÆ-Ô·‹I.|Ý»Û(-4ËtF‚Íguç æc`ŽàÁfšùhÞvîüæÉÇØlVc/ÆÚ0çm]±ˆ~5¬%;‰ ÅR“þÙÏEYGó‘Fl²:´ˆF‰ßoêB¸™":klOŠvŸv®‹ðµ?»˜;OëVH¿C3aýæ§SòÃ>"¤*'ƒ*ÑOVÛ”pœxO¼Í7 ¾JªÊŽÚOÓÂäò9㸠8Ȉì{P»µ<ÁRœ15\^À;Kì•H”8ºot»€S*¼7^\Io0ó¦Q|w±Wx–ñýÐ3%N˜ênS\ËaÏ©tÉAÑ@káOä_tˆìcz«¿iɦÅ5•oº&G ·5Æ!$¸ðæÛ—±Õ/²¸‚Øæ>À,±à*íKð‰‰×¦pÄ È™ÅÜä2°5ë/Xëʵ5•Œ&˜\¶Û£,z©ÜüM’#5”ËÒ´cÙÚ—q_ºJXMû§Í,e…jñ‘pˆ€ƒõ*Yfl„»§ø/¤ÜÈØ'`"òØ×}æ„ÿÖ7•àOá¯Óâ'B‘¢ey§7÷…Êÿ¨i1 Îì¸þö§†êó¶„ÜéÐ<Î5öXSåþ$‚šú»/_ ö<{›¸V•høÊ`@ÕNA±>Ì{Œ–¤BêÒ8Îý\äȃÝiÛL›ØÃËôÔo7^iÊJþñ¯Ž~%³½?…¨1‹ Gÿ§ðÿïÖ¿[ƒÚ;_ ‰móG·ˆ³úßϽ’›ò7 %—ÍI‰ybÿ™71'6ËZÕÅä]¶Ê9¬ÂÇ æØáêì¡lBIqxBmÌó•lA%ë:}}ïMÁ”ÞÈ¿š:û'™üŒÊ’Ñ:mƒéùœlþ_ô/ýÃñè»9Ù»ùÿ‘Àôý¿š3úGŠ@¨§Û¿ï¥ÁãñŸ ¡¸k_²ÿ"tG ;ºîxçè RŸxºL Oø†åë:V>‡>BŸ,­¯xrHi¬£Õ©p!oUÖ ÐÌ‚÷0’hÊoæb ·Þ£›~}ÕöeL‡ŸMl,'νö1 B½—’šÃ¿#â–y|7I¯m U.š˜1vjôpe;ËOÂQªãÁ'­@€K0ÎpÍp²û–»Âf&º{À”åy¾rfrŸ¸ƒÍÓ3`De å ÇBÐ+Ú\´j“îâ,sS˜TgìQïr6^ÝÃD!øжY·‹¸9BÚÄü96‚%¬­†©‘J†C‹`ŠO{Ȳ¹_}î¨ëI‹¼TT~"–!t/ql7dyÆYžA%b=¾f0@5]V‘ãíx »@Nâ–qÃäÿrÓÛ©¬fy ø3øÿ·ëŸfúp³¿[,ú¡T¾³zÛñÙA˜†“4+ÍKwxUž¯¬cBv›µx•]&Ø4£Ê] ƒ8ôvÖF«Ì‘ÂüÀ:A Ž‘¿LäNÔüíð¦ö…÷¼;9ÿÓ[±jú]÷Æ^³8I”.!W;07oŸÆ>ü(®6†w GmÓÕ„4ò D9æ¶¶1A]"z¼cÝûÿ©ÿ F¿F{¯Ïÿˆ.ÿØŸ`®®ÿ3Œÿß<=þmçËÙ7×ô!BÇl„ûoàÎEão•¿‰g#IØèß’öwpÌšºÍYàü„Zëdqê=.s¿JV†XWœfæÍ4Ý;Î/tr5ŧð¤ÄåÈ$âVý ÙT@¨ΘöÏUYaÆË¼Mí¦!ŸŽ3ÚDžÓгÓ×Bi_Óà ̇½)BµjC>f¬wÂÂg˜(GõÂ>¬ÃESË‚§.#q™7m²0Îïò_Ô‹ó—nÔÏr½ÃBؘøÄö¤¬ ðêüÀ+­Uý1|,N7e§µ[¦¹=H¿žÂ~V²ynúH ¹2¢ÈCV‰#Óh<±Åèüãœtô ~Ç.å”qn/AA†µÉÚò|ü€4ȾãÊã{ׇéeÆ ¶$Ì’ü‰f¬óB US’# ®Œ'Ò¶ ý¯-=Ü9õž½ûìꦦõ¹›z#sè¨Â¹ÿ$¾Ãmr[qó1ÜýlÌýŽ ,“"-÷ =¬1áÁ%&öØ”(ý×xúd"Y*“•s´Â*~…ž0Ǽó.âe†°É¯’T3ƒÊ:¼ëéNÍ,’ì5Öujì-éPuÔÝj–u]ûOjÚWËïŸvNʾ•‡>Qá&QØ^p-lªÒdHôir ‡ÊDѹ~pd{ÀZ|h—lß;x˜–³ó‘„Öj$Bûçñç æ {ºGéö´ÖÏ·ôB“w÷5ˆì: ®IÖ®ø§_Lš’zÆyä…uv+ÒÅcÑj-ÿz‚ýó½}™‡Ù@ÉDf/°¦K=ȇæd¢×\lø®BÇv3ñ,uŸòí{?öš#”:\ÝÅi~¶PX _¦ù6ÝEœtå}¿Z7NŒ¥©Âi7ֺ߲Nn˜Ú|îß#ßÊëGÚÝÒûø+g8Jc®™YSñME'–0²+RU…ÉáÜ likŒB2ÏmÅ4ZU0Ô°’l©TÖ³Îé °àhEté>’£“ܯ²«i ‘±8eXb.ë-«_ ØQï˜×zLWvbòŒÙGH“á‰æb²#¦ùfvÔ¢Qo[®àÙå/ñÚ8Þ6‡ä(~äçóÿè_ux -ÊBež¢½‰RwR£Þp{‘×My¡;·õ`âD¿'3˜¨FuëëGòŒ½…¸u""C}>–n²i#·€jÃ:E•\½w¡;±±ì_Î!i÷Oc±&á´FƒOKèLÃøWž÷ò†}Ú4kLAûŸEó"O¬}!ôVËÐ ëýç#Oß9–ü»þ~B@ºŠ-Ž~ÿ[þ±?ÇþØ À¥AœÁnžÿúájÆÃh‘=ˆD¤|@›òû­Ûv˜a@N&9…cçUã¶Ô—vÑ4C »Ëû,(´ˆÇ¹¥ÌEqw´4jHOÇR‚Ó/~H Aºȃ‘{fMGæF—Ã’lZò*_Æ|OòÔ¾M”³ˆ1"vÒNrˆ\Ÿ¬ëõŠ^gLû™€S ¦ ¡ÄkþI»¬s8%—µ¬>Ë›c0V“SZy"œ¿€¿¥É”ÖôÍt‹¸Ï5:|ÔÚ–'»[Z1þX™1¯.Oº˜©F´pXí&qí#âPQî#­fÄ¡ç¶Áâ£/>¬‡ŒMT?³c'– zÔŠ ãr³a¸O%Ê(„üA¬¿cÌüXL:*ól§´&Fnj·ÏB+·Ç*~ÓŽ´H©£Ò}òÌü* öGœ;}LñJvJÃÂôâggóaAÎ-C~¼w¡70„QÚ,ÑœF_íÝa¤¬!CúD%°93»P[¬xe1AZje¾]¼”×C¡ýÞø~‘ÝZµKÚí®$®MÞþŠ{ä0óŠ3]÷¹Þùg4«;¸/:úPZ?ŠPµ´HËÆž›0È&{Mã0T!¡ÎŒ®Ù@®»Ôèâmxî: =Ã!™M;•)ž@+è|ýä~@ù•E¿;‘j÷ åÍÊ÷½i+cÁr,˺ÂAÓ§‡ ˆ§Â­?¿Ú¦²X\Žú½ ºT\ŠÖôŽü7šÄ)ÞÓºþÏÞìcæ÷b‹¥êQ[–§ÜJ@(wP¸T~ ·ÔA•©jåG¶’D|-…o —· 7œ$LkwÀ‘½4Ž@ÿ GB#nRTC[h@!rÜd()ê|‡¥àí'5WÖj 1¥Üxq‹¡-&)•I·»¢Åçò닼LÖäWÞMÔ6&$(}÷ÓùïÍ¿UÆ_@Û}gâýب ï™§3Á/éH pgµê³ê(ú}Ô4cl¸R;$¬V6*Úy; ¶%T¥tfóŒýäEnÝ0dUB简ZgMª'Ž%%¶sõº‰ ³yÀ‰ƒ=\ìøÛ§äÖNŸþ8"ÚmbŽÆ,o¿ŸÍÿo¡ÿO$"Ì7ºÎ±Še8wepd(¦{›ôeˆÙœ; 7¥#˜åX~¥{ëP 8;uŠØ~ßwëHLçsÈ™œ2*?ËOùÑð0ÇÙ‡¦–¤}“^÷ÆÜÿrþ„CÊØ» ŠOÓGÅév³O#m1s6wA·x?Ë-$m@ú. h/g>±7TH… ïzíqžøÊÝØu®úø¯ú_û ñèÒ\ì ~Þ?§ªìÿ×þà À¥¹º@ܽ~ÿéó-{ëç}¦±øc£YMÏsÀ¥³9Ù¶Jyó¤¤]S OåóXÿk¥¡gÐ- ì·–ƒ/wª2^œÌ+½EÒ¼CIw×Û_Áý¶Å«’Èf³±–ÐÉÐóx|EgЍaíx>/ïŒ8E±]ÿ§¬Õ9~ÊíY~¢ wù&R¨ßê)TpÖ‡Ñr?˜¸÷:?Â^Éý޼嗏Áu…!b Zõ»”ÊašÞ¡wb‘×ÒPH²Y=ây™C+„‘wëÆ“7âhø¶<åU²ÅÌV*S¹ô凊òe„G¬dsY`_|@æì ìÏ]ÜŒžôîfhTô{eAÉ‚éÁúÂôl'>ƒ'Õ `láö$B‰u3øV#ÞÂ× š)¼fU NÝH]XÞOüŒƒx>(>¬ ã¥dÁ]ØÉß"~·;6@ÌQ+Ç—ÙhðÎ¥/a,©.=ñ娳 /%JŸ„¡?![µWO¦ºßSÔ›õº Ñ2CD 2õèÑ€tÐsI3Ý®Y½îÊ«:x— ŸŸÆŸÏóÙŠŽÉ‡÷8ôÛ4ít¶Lˆ-ö¬“øÜ Æ#bÊMQšƒ³ïüs-Qáp× ò@·áe·ßmÒz’ÔLÙ1ef '£˜›C¼ëy,´P--_ß~x/ÐÀ‘×Eöñâ¾XÏsfÊj˰žhžHÞ75ü–„Zïìg”t>'iHŸ­Ï»§Ÿ¸o»- • ¶x²Vo„ñ<^Âx¹–‡q H§b˜“pùÉüJÌ5AŸ»'¢m/Tñ“u-×;yßOïoˆº”¡Ì!áSàiËcyÏY=&[ËäáãÚÏh–^c v! ãuš­Ñ¤\ôœ’º¶×ü¾ÉzËù}ø=Ž}œv½× õ0Wä–%”„kâîI4‹ÝqyòÇùÛé$`nmC h~6ÿ¿‰þ•Þß{N®Ÿ!2ÛAµ³ÓõܳÄÈZË[ ,=´MfˆZÓÙ:¶áöèwâ&#¼a:Þr¡Ò—ŒƒøÊ˰–}¢—þYn›CkÛ´ŽÅ_Ïÿaà nˆ{[J£÷ÒSb¡X¶’ÔÖr!có9GCì@Ûµü"<š8ß I(|uÔ»Èz*0z:úkÎtêéÑÿÄψGØÁÉË÷ƤìÿÕþè À•@ßJ«TDóÁt!œ‘±y…š}©oéÄØÝ7Ì~‡yËèÛýe‹ú¹´'rïJÛ†DÎ8½ªjz;±_qL¾Rôš3ÆÒ¥ô]­Åj¢‡€Ì©]Š<ºÞnŒ·Úa’/i_oâCÊ“ñ~íÔþÑ wÙ‘°*î —þÔ‹—CS Ôe¯Nõ$!.dûÎGÚë¯ägû2|íàŠµÎüx&- €twµ?Ò«cEN”CRñJšŽ*X¬H{t¬Ýˆ‡¹È;'Åm¨&8›'LðÞòe†\À¤>ûˆYÞ_Û~r”J¸ É~Š>‹YØõйé4JÅ(!¨xH{¶GŒé±ú°bþÒÁ$†OÒÓÁ½÷o¹OëŽyÛmî<è»ÜAÅOÍÛݘÆÍ„÷—xK£Òj[ (ð|FnÓЕ]dU‘¾Îc"W UÂåSþ¢Û÷Ñ\ö Ò0(Úú©ò” ?‘“É (˜Šªã`Âû@óZJ¯=")éÔ÷ÛØ GÈ€£?Ú³æ"|ÅÊNã>MŸÔ 8hÜfµlâü†F%eÿh ¥mïÛ¬½š„-ºôçA¡9º¬%™É†Cä^ÃwR²,¨èg±-8˜³,„æJSñMµgã]ê99)Hy÷õîX×·Zßuöi ­õeyå1ÈþÊÌ¿þv+å°ÚdìNc7äÓŒŸÅ?ËÐÔ‹1Íú¾ù|écù/þÊTé¾Ã²òª³™Ô¨ ÈDêÐV³Û*3@ƒJµ®¢‚QVÚ§‘¡ý¬Žqv)’ða¦²óy÷GdÍÖa•Äzà®<›²¡fȽ3;…~¼é)¤¥ ƒôêñ Á#¬.cÑwË9Øö˜ÝJÙ2ïn0ºí„™DjÖuób»Mq´ü£ë!œC <.tˆÞŠÈF\Ê«r¦™®?—?¼M7mD¡ë£€Õ3j”‰­Çƒ’ë0crû&`åÉEûÅp¯AÕ‘MΗk‚Åü¡ÇnI!ih‚©]Çýœ7E^¦ŠŒ• àF,³X—Ä3YÔ>¾gts²¸ IÒIJÞå¢)YôñÄÓÙb.)ö«Eá'bÇ—D?ÀÜ´ô~‘¹ÃÊÏåÿ÷Ñ¿zÇÁ£×»îw 8ýFá$¦Ñ'«ºBŠQ‡w‡·7žÂî(¶•¡´twÏŒj+°¢{£¸³aSOcÃ;á]V¡O1wGs:ˇÕ_ŸYýõü©9,f×6™H]¶]ü ànz£Â×2Ýôpsu½¶†ß–øl<ûÅøK€ YN˜M)~ØŽº7qÔ‰NxZf˜ÕïôÏõS’³àïõSjúÇþoì¯\ÄÅÕÍã×¥iÔ›dxd}šQ‚êÜlo\!À{¾Yg~QR»¬/ãSFGnðáÚ©Œõz3D<‹Š6™²â‘íÜf+@zÙÓͰ`kÝ J[%¨MDÚƒP©[æã@SBC³Ë^%j –RƪE¿kiûÓrt?ÖƒÏ(…+RR=h¹ö=yíÞ•ô<Ô51ë$¶@t}$ü7'<S™¤#ŸdàÚÃXn? Þ#†‘!ß½ýšŒ%u§S‹‘¢‰ëîé7°sÜ‹,A 'îç«|tƒQáxoÃÆ…Z8 âkPï`+ŒÝkpmo-°Î³’aAä£íqø"HV¨‡tç!‰‹^Î|aÆ‹»ƒÞŽÛ¿ÚŽö1Bàcær礭XxÓ÷F‰%®ëb¼0¿¹9ª¥•yO.PþJ‹,åXWm¡*È&ñe`xß;Åêéx¦êSˆ‘HœØWƒîtذÊYP' ƒ´™ž§õùN…ÒªéÁR‘¬vîA;Ó™K7XUõŸ ½=Á|ïÔþÎpºwÌM¥+âHp9IÜÚ¸7üë.ï®òç»ó¾{‚kÆ\/r;ÓM‡“±Š'çc W±Ðsh&ï’)îíÕs²ç?¿›§¨ë“ÒñŠÖ+zÐ\E ¸v^f¾tÅ'½î.°îgñW{gRÏìY»oÝD–o-­mùɵõs3aÃ!†½‘¾7eÍå> »mä g¼Û%eÃ¥á{rŒ¹ý<ø‘§ÆïÌ7"K?AšÝ*°ïÏ.mìO Dê¿ ††ŸÐ5J¡•‡I[Êb9íbÐÕ‚†ÜoŠË Iè.EŒÙ.rá­/.ÇqBq»çT€å¡…RK•›™Iè°œX¿3¢žü` K«GÂq¶–êr~*²­éõÞÜiy\´DÍ.ì8x¨%7iø*=¿ýƒÅ‡!éÎCÍõ‡S¼ë2† §cBS‡Ñ“‚ooÌ –ÂsU´æ½-Jj{%6…uH^1ñøþVê»üLÐ#\+’¥âÊÅWY[)Ì!›6Äí-ê,ºÕÓpæ?ÄÎoZ!÷§òÿé¿“³8®TÇ2¢ß©ÏT‘Ž:UiéÿRè“Ü^l€ ©žHÎMKãrƒ<æ˜_ Azåɉb&ð°@M›´%+ŸŒR?ÎÀÒÖÁòßb¨Hœ ÿëù'hÓ©Â>긙Và ªFWàÀÁ&²ãŸ¿„çD »Ø:?hê],ÍØxŒì[õUcÞ?Këé×=¹Vq_õ¿û3‘«½‹Ï?ïþýuqùÃ+À¿¾ HT^j%íöš6I1õд~T÷¢G)\ÚeÆ[ÕyưøTZ1bséþ—ÀÜe~,¡øl‘fÏ$:Ëem°î%~üxÁ€¨AG¤SáYc²EÖµ€{R ÝK aÒGzœäêdãɺí¬Íè0¼‘¯éså3–±]iðn§øIÝ¬ì¢ TñØÈÚD>Åswáyp‘a:7 Z°Ò1š0ˆ!áòÕZ~w°:¸¸áR;÷?^¿Ððe´‹}OˆWRjŠ»× rIà¤Æ'çSåû^„ Ü3^Ç~!°ORidNJ»ËèKÉcßHÄåA ¿Î8ŸÀ­Êf×x ¶<otºZ˰"u«eêù@òøæ*ó|Þ‹¯hƒ}óQZNUDe1×Ú Ö>¼„a<‹²±“kÍ“³¢0¥bˆö°iñ,ÅèŠ qRÈY†m«P¨ã…æ³S³Ðx)övÅ úy‰\¼,ÏfòßVöÖ9é/œna óùÆE§Œw-ØÅ± XšÃ›Rð6+‡ç@¾SÓæ;¤ ¤5/‹!jokå陘^&ˆÁ¡¤ºH{+Ž›ÚEÇÌUÀþð¹GM²î®z#Ù,ÞDè§0Á·5‘²ü‘æö¢voåî…UÕ?z® ŽÚÒ¶,HáM´9}ö“øSú'ÒæÆ2oó⸵æ¨ñT?ñ´³Ipp§lN¬TÑg¥…yçùÈ* µ¨,½‡öÜñ™hº¥³V™¬øÃÏ#p•’5øsr_S9ØÛ šVÎc:6².§H³”æk:Ìç^Vqë=ûEx¸JmóÆLÀF Ëžö‹tÔÄœ‚È65ã¨Îÿý(6ÔIc«vö‹1Q9¸B^|³fVuƒ^NgM5wÖOäïh@7(+œ¬Ió©Ëæ4T´:ÅíÍ>ŽUÕ&WŽM¡bDz ƽZØV< OàC&uÉÂæØ&¸_ÛÒ]T©ŠrFá€]µè»ôX´öÖ¹E¸ò}nSX aò1¥—C’¿Ÿ°ãxf&žj~U Í£ Œó­â mòåÓüOäÿ÷Ò¿XAÉÓCi˜ÃÑ6t@ÀV;€ ÒÛÖ«Põs‘lRk•ž'w¶þ°ð–çb§ÞAíñðÇ=i© †‡Þwƒ<£P‹ðºìŠ(-ªË ùýþü¹D d $­5§m´(öj Ó¯ ù°‹Yt‡××eQ}#¨“ç±'—ó‘b›÷8 Mwgéw“?¯rÃÛ6ĺG­×ñ~×íÏGNvîÿ¼û÷—š«ë}ÜâêòË»€nühÒ6¢¦¹‚b9†qSúynN;™î†Wº”i‹e¶Ý½ ýÏM²ŒõÈâtq +‚اí‰ÎȪ²Ò}¨H:&ˆŠ È¹c®EtyÜøÀ¢»*¸õ“I¿î´At@wøKÈû8zûT2Š •`|zߎš÷ À;W¸ YÌcƒNºPQT_^Ñ6¾? àÔ§ˆØ‡OE‚§zÃW<\*Úºû1zdIe¸½|ò•*ÁñiƒEÖq=æF‚1õhÀ¸âT8g Ø—t†šÛuÌ7f¨pÈîç¾Wq…åÄ.ë¿ÏéRÓÁpQ‰¯t¶ð ks«®+åÃ.|¸¯Bæ±Qç¤ÝÒ}UK›ÜÒ×efØÁ:ÇÿA#×Ћ´Ñ| •ÇòyP/gᣲJ¹„ Þ:JÄxêŠ÷¨¬%ËB¯nµL3;TbÅ­dH0¾}¡aL;ƒP«tÚËT` Ÿ”®ÏÔUÿ¤õÕ „T6D>ØÀ¸Ça_dÞ‘‰W¶µµÇ<–¶¦UXQ;ѹhÞ4ñ’U;¯Õ—ƒç)k8·©þxxx«ÿ3ÙèüÏ<£.ýäˆñp¼?‰¿ÄÚbG² ¹J J£6ûM)œÐÆ9Äbu9ݹħè:kU•¡Q1¼«žùá3g¶ÐGÃ2ä'Vs3Ä·’‘Ï|a„f|<[åƒýø‡C‚î‘£˜Ö‹ØŠ)¥»2‹Ûs«édLðhü¯ƒ>;ðêD<ðνq'èÕi"‹TXOˆVõ§%ø{Jk¼c‚Ni7åeçg§”ƒ^ŒÜÞ—TÉÖ\áS€¶ž|@ùiü „lI\( nLj-|- Δ#Ï È»qÜÙh/5û,†§8loM#èâ<ìAäÒ’„îï9‰oÊ(ƒÎÏÿùóž#ra¥GQÀrÆ |T÷lÆñˆŒÌÜysˆ „)žðVŸÓ±_.ØðrGõI÷þÿ ÛƒØH­ŸÇÿï¦q’×;dï½YÄ;¬H‡1¶[šn[Gu:½ î]Ý47t‹&°™Ž0üÐû^¡L‹cš3؉Hšï¢ŸZ÷sÁ‘ÕúÖmôä½ìÿäÚš±lŠÁ4ÍÙeí†wœ}[›9÷¹z¦=žÜ»µ‡b¾O¡¼/Þw¸Ãnkæv¡ùœ¤™$¶‰1{‡·øí7ýãÿ„`²sõóþçÝ¿¿Ô~dàÊ@.€ÇU öªâݤò[Ë}D”+xA>KâÖ´ˆ†yã~—š*ôS{ KãbŸnò&åµwåJ¢±Ú¯à>ð@ª:ŠŠYר(K`¸%Bc¨äQaŒ˜öæ¸*šUHéýh¡µ1…hÇ:p ñ›ª&öâòúXÏ p»XÈí\a1×¹Ò €Í¦}}€Z÷(6ËB#ŲÀðé³û;`·\ñɼPŽÄYà-wÐý)ï4N²Þ1@ú~blø^·Ä²œöšZjCÏ—†gmm·¹ò½×/ÄäonáãO7±„3ÃdêJÀÝÏd“€Œ.tZ©ûœé…YŽÖ€.{b±Øérë!r‹+Ü–@/wuz3gXpLØDBæœfëS6š©ÌžNl¿ó'Æh®i7‹L”Ìè—ˆ¬½F­uA;päÞV_}È•5uÄxÞ–XÅLSÇ"Ÿf*ĘÆ'HÁ¼Ç`£(l9¶ˆ’{Cç6…‰@êP&mðF©Ý,G“Ûu4žk ¨ÚïÌÒKO›.EZl–ÓèNã:KÀ Îq¹2¾ÙÓ—C¥m„ôOÇɸ‘úX[ï%l9êÅ~ÞT®ix.FÛ=攈gO+pX:Œò› 5J2F¤Õ¸Dl"ƒÜhÐøž©ø~±rr™Úè ´Þ'Ÿ€¶æŸÃ?6вíƒj`ÇŠ^A`ë9O‘~ï»=ážkUv‚N ³æ†ûŽx#+‡vÖ;% ýî#e2×~KZåc°Qǽ!Ç/ìzŒ‡ÐûQ#‚0× é:Ê5ÈG×Ü.ŒA…a­¸êw'kž;y™÷ÂÉ칑Ðÿˆ³/EÆ/ª¶®Ùx—Ö?˜Gô¤»½ËÌ÷ž WÌmf'ÉŽ&ÍŽõÃý"àŒôl ˜/{L˜J1“)~>½õ³ø×¼¨”Ó¼»%ùÒã°í¾­WuMÈÓGì ð{䃶#‚øîÃÊ 3/SÛIñ(žbPi‹`¢~@%.ëÂ_²¢›~P5ïݼÄP0Ýá4XWo‰ßÿ`#]¿@Í?Ür^!ŽªkAþ:c„[Þ¤bô9÷1ÒåÿÄKeÎîgñÿêŸýÙè;|píz°–C›cÝc<‡íG½ˆŒâAxù‹±zI§`uç™Ä%¢&EÚÔ²)„dÛR<2ÚŒH§“n‚Ô'Å_hàî‘mfÔM›ÙÐ-…¹Ì{»‚ö4ž+Õ·=x³îФ´È~¥ÿîEWïþùÿóå¿¿Ö~løö5O(€¼ê—8¾Fá €líVÌ̶K/8K<ÀY¨ZH†ª‚j>÷¢®Ü:Ö~-MŒÌá°£æÜ€UR^ JWDØ=ÉÇ^!½(oÉÀ½s&»Ð׿è/ú‚=jI„ Ý+!ÀXNA× Œ;œÁ˜7>¢¡˜_ïï½8KòãÀvŒé)…1 \j•³ÀÎ/:%¬ØŽ±Í¡i€,OÉT7α•ßò¥;38¬sîÓÇo;I <ã&JVê´ç)6}ª€|»›þ½@ïF/Wèâ1“ÇÈŒeM"§>æÀ›Ã…¤Ì\ên\z/ŠWú>kö]EN¨.F]˜öv^Aùý¸³h&ÔtD³@,±/=É‹¼4庘§‰2¯û—{oȧ„ïIŽÝ‚dvÚØ6¡ûs -f)añ:Gf Ê)mÒ7ÁˆY¹L÷2܉ï­¯`Ïn¶MÎ-®Ðƒ2ÐÚSù,ß@4jWJçÊiÄía­[¯|VU#]ÿrO%»2…Q‚ÿÓ pMÕìÑØë‰(ÄA»ŽL­þ=ä»õ¨„\ÔÍíÙ¢?MÍÑ@XÓTŸÁøºXb8Œ¾3ƒwh­ ¦ð{´LåœßâEG×¢d×êxsoGœ1f"\àAny¥u…?B‡.=(·]‹uæãƒ¬¸Q,ÊâW ©'?…¿+LŒ2¾eŽÿtqcóÈÓLSTîH\÷õ{5³âöEvE¸IÃsBH¼Ä– IÊ{aØóA&Ž÷{¾‚bžÛF¾±?­ûoåzи/ïÚÑ1ùö8¶Cõ Øå%]ä'÷¯^ÆÓªòÁ[6(Ôq^ª•Ói@'§/}ã¤SrÊ6 r#êý;ÅxÿŽ‚…j~wBE¡ÿ\wáŠfÄ›ùÃïUG 2å?¢'Þ;8I¶|í«‹‰^J}=¿‹»L‘=µGR¶rS–„‰mnß\Òémc ö°P]¬TçZMßÙSM=LT|xý¾²ÔˆoÄúê›ÞÁ‹¬|§GpfDwl†‹“}½üKgR²àµŠË+è@‹†ÞJm?Ì?ÑÓî'ñÿ[ê?‡O·ED&"¥_D_;‡S¯Ö"[¼–Ú»6ßJCn^×þ½Zd=þÁ¨¬þ€'ã_(ÙzšøRÍŸ«P|â^Šq¾?yGD”[`åÒ‚ÿþ§æ5¯ÐŽ K-6p³ï‡ ™÷ï‡,lÇÑ‹;Ù±Ü[Äÿ’O–Ž…Ð1ØïXïJîA»Ž$÷ài-¿Â*4-£l«‚¤Þÿx(úçÝ¿ÿ„ýà ðýk)¬úìz¬)a0ýÏÈ€Øÿ ÖÀûpѼK­”¯EN9-u–幞•¾âYǼâÞÌdWØí×IY  ÷& \M˜p¹Í&q±J”ez˜kÕ›!¸í( ×9øYˆ#/ÒæÅDÄ+D1ÚÒØåà ÷Ã)]4Œ•—:"ù‡õNº§“ÐàTzާ롟&}5¥ÆuÌ?¹“&&1=zm¨%°hº»`Xu›Îœ;–‡ ­œòh5%)£nʇ€%ô4b™uœ`Щñd!:|Dðx->jß·hÞ²”8 ¯¬43é£7ùÙÝ £ÑŒäScGäÚTÁÆd†(_*”L#JÅñRc0zMi¯Š4o õi,¡£ñWM+‘È‚ð™ BS~æÚáǰí”ZgY‹ëÉfÒ«¾¾%ý|ŠIOƹj+¶F¯O²[‡6/göJ0'è΃E!BâB»ê%úñÒùŒH9¸1Úg~wksÔOLÊ­E‘”ßæ‹;#Ñ…ªÛ ÝÄNÊOŸb“›B¤ícc‘W]1#A1—ˆÔ*b:@DÑŠôMWâ늪Ò~#&-°Z!`¯ꞟ!Ì⼓-Âlñ‚ÊÇ5\{líhýÜ_VÇ}@yÛ6$¾ô®†¬DoÈ6ÆT‘ùT¢F -ùª•Ý^þÔ‹J‰MÃË1o¶u^ É©í˜>PÒ·®1Ý(È‹[eÆn›eŠÓ3ÿî¼Oê‡ÄÚ‚€;Ner8÷51q©íÛ{zIÍ_ŒÆ1¨?Ú®lõT… µL»ÈÞì§ð×|¾i?Yº–òr$€*ÊNt‹îhY¸IáKõ4lréâ]S›À¨@õ—DoŽ&S­OßÙ¬jÖÇ«ÚvÐì…ÄŽYbš-—=08G¨˜U›ÐérÓôipœ›Ü»½ï±øÅvnBâðúë™þV¯7õ^0'­‚Ÿœþ÷ðÿ»ê?—U¨?Þ²9*‘žŠæ–s1{¢ÈÅLM&¿\ž_+v²°Æd¦ ˆµ=¯9‰G ¡è 5v÷P]¯µé|"Sœ†–nãûgÑì*ÿþpËÍø_Ìù»¨7t¥Ü¢£Ý 0mi›ÿøt¦\éK„¨>q w™ðsßrÊÖ3'ÄR"G„ÄOLíxqÈí{¼œu«ÊÉŠ~xÝìàèí÷Ï—ÿþrsvûat®.·WeÔ‰* eÔ‘m9ð@ÆQQ2'¶@ðæ‹¤”J¡×ÑÑŠ3æ•÷¾)ŒN„é—4y3E´?3ÉyxCÏulÛl"“W÷#0y‹¬?@h¥i-Tw®ïAr¤öÉ»«ÞrÛ CÓv³s÷Y)ËøçŠ%Wéûõ†¢ ž†ÉÕÓxg;Ù_“4?ÙwÊFÉ”£l!¿¥áÐí`VY(ÚÇ=yƒ˜uþ@®Þ1/L'lmš^mF€ÕÈâÌdý ×e Ljòl(5Ç1ël¨ŽpµÓx.HÐgŸó0»eâ1g{3×S4&dìlŽcy9A£âù™Ë‡I3WB$|0öãbž{t"ØŠ÷½É½®VMP"4JÍÍrÚñ•óD¸ÁW ¢8&µ˜’&FË—Ïÿî`{’p\G.Þç²ÖK–7Ä6ê­r$Ã…„wüË©¥Ùn¶gL~Ì•‰fðêòúrÃ@Jac.”…wÎÛÑ&ÑNO'`…I>;nØl r?+ g|AY€g÷!ÜŠ nFÿ<„*ÀåÚWˆ“¯ZÖnGÉ̳9,ôœðXQ|s‰Úa:#iós´xµ¾žçz›‘E´G#nе6ncJl2a-¤0ã¨ÀêÇ/ªîsò4(4 \ÿüOø»Óã$n)¯%kÝ8ÐWPXÅŸ€ ˆZNöÊ/m?¤²ú, pæF§œÑÔTne1>Ô¦Œ 2éT„Ü ¤’–'ÚÒ‚S?Šë–V¢}_XçÆšQ5’{y«¥bà‚ù½*èæëœþ¶eCJBÏ;Xþ×ðÿûêÿzû(É.Iº¤ì#5Ô08±êA7 º½ÑsÕÎ…›²ï>/ôÛ½§C„×"yűOå³Ëù GWoýÙ›=&ÅÞÝ2ÑŠÆýàýÿÿ`ÒÕüÎ4Êì¹GÞôrnŸ<“`IR°ê6îgdš2«Â©|’C<;³Î‹‡iPÅhÚ‘$éŒÈ?/Üx˜:yx_ÙÚðùÁîíþùáÿÿ„ýð À•¹û°Xi£˜l*áW0«è‹gÍãéyw©ûš] Î6våÖE/tÙ5Л,—§žº>RÂdã-0EXVÆ3„f©Á•…•,kÑ ËbüžÝûôS|ûñŠˆUþ "ƒQ!{–hc@a9…f2a)KêÄÝ“%uÌ»(OLâø“öžuñr²g˜Çs:˜Lï %¢M2GïãøS–½dB»?¹À“½±¼÷6z œwbˆ«ï‘g¦×ÁXGÂOÅÛàijÐpŸÆ€MaÕ{9ahI Aõ„SvÉ›OÂÉØ»ÅP¥ºÀ-§ìÛñ¨‘4¼÷c¤¬ÓgA¢d__åµ9UH€ÊÌ\L´¨Êö×»<éX€)¸!+ x°q£N¹&ùÑZ«;"Î0‚?Ñ>á ÏJ»&û“üÆ­ø¬Úƒ¯®{Ùá‹ëz9÷ïö`Á17åÂb_˜Ë•6›Z!‘EÎóY‰°™ábokiµg3 •³t4m¡›9…?q”!È5¹£•»f7Ó2d(J‹ÿ¬ŽÄôeŒåΛR ãÉLxaHA–êÂéû(žùýº]Bw9OË*þsƒ‘^çÍ£x ïvòEYJ„ÈmÒïw‘õ÷òÃ}´¬çgèÏPd P]Y<£Û­hüýMnùÆÎ‚tsÒ¹S%£XœÿI¿Pnñ‚Q u D/„º Q†¨E¡„%&nMp8/„AI\ߊ‚E…øömoÿFÃ)Qf©›½"PÔóGdd̺› :Ùmì8³Ó¶„ŠWåé¶9"=@ø$±t¹õWºónQ+Á…ÇNu4xГ.“±2ô$¶e×”ô™„áù—Q·VßyYŠ,0J6qö‚>Y͆>-{à´i( bo¡·RgPŠœú+Q0G[á¨Åóï_ê)¿Ðñ§mq•óé‘àAN7é˜?¼g_Ú+ ÛŸÍK™¾ÿ(¹Åâ|Ü+lQ‹©—“÷ͧús|ÍÉ„‹˜·(oo YjÈ Ð ì¼ úöv (l‹¸Õ݉'Ô-'ÎÛVÙ”Ê*é¾µÇr9yVùßÂÿï¬ÿOãh°lDÉI“¬OŒì³S±$Ä•†4-3½{‡‡½§ÈŽŸ{éïe$•Πöè¼Å­”»mö Ùü\dÿ¨—9À´žR2Ioû?Â_9ÙûÜË·’§8V̈H=ÔwsøºÍ ùöQÑÔ'£t±¿ÜØŒFkeߌI`}² äÀ½š‰A‡Œ¿HgtYoû¤iáâý¡ßíwµwöýçÝ¿ÿ„À?á'ª°âš½‚îy‡tk˜HǾÉ(‹N Äl‰âõPÿØã3éz'ÙjôѼðÉóÎÙ±­Ã”k0ÉŽŒCGÚŠðè¾1Ïg´Ãµ¶gŠÈKQ…‹w˜Vg‡EÃÇ4,€õi†„Š ïØ¬ãâvé\ê¶>̃øpöÜ™Mi$64ïÓržr6XáQ­ ½ªÝ—EH¦´²þb%Æb¬°mí€HËà}{-ªœâÆ Y\‘Ž‘³)ÈÕpúÄQs²u×A–d)SüÀÆÛcG½ÏÇ•v Ztô•º8ewù²”Ão¿Qeyºã3c32Ætë4ǽ¥\{ä,e”žŒ ‘óHóÛ#ˆë$®“qòÊoD]¡îyòÄxõ<*'ÄäÁ†PŠ&Ž0rrð|³©‹/»ÍYÜcB\o, ¬Í‰ßO ‡Ä2Dç¡EeÞ„C–´vÈî/`—=ñ¾B7ìî)ÝNÛIï.éÚFx¾L|‡"ƒšãLšš‚éQ¥6Óí;/*œÂ,µüp«Ÿ+F¦êObv4ñFÀk²±åxÕ(¬²0>nWoŒÉU/Wc¼Ðz'ñôç þ#“önÖ§]z\â=8ÖëFÔ; ªÔçaÕO½³µ¼Æâ¨„K{ RM ˜ÕÕ¨±ù&èÉ@_¨ó:;öï’ý(8V%HxÐc‚\Ô¨é64‡³šO·6kpÛï0Rfª.- –Ÿ•k|(Ý£àjÒË;xaùíÂL’'N¹G‹júý »ô"5³Äï¦ÁÆP©ƒHaù "<º„\‚G“>b’MÛ®ia•:Ä'•º ˆw5ç¶ã¢ÜswÖ¶5¢\E­ygÚ(UóÍA2¥{uNÜ]–,ó~ƒ¯JãœÄÞ—€àWwðt7êOœôÔœtñ>·W×u›µ=lüaþ4ã§Ñó$ryf7xóía‚KÛÚ¡Îtõ®I0[jd¼Ê7ˆ^ Ó9záÇj »7€Z;‹G%çGc+¢ªw“¦¥sï…r€¼'‰ù9>š‰Ó¢ë¼ŽŸG¢)j·°Âc´ÝXµùpì'A0¾øIÈøy…æçÒä|ƒTÌS£å7ž/*%ß&dö™L›:`¨kÄ‘c ]LÖ´®±Ã8T+® ô{CõA™ç \xçv†R¼úàÇEÙP ͯtþ؛ɭt!0Šú49&*|E ò‹NB/ ±ÂÚ`ŠJ&Y.­f²hÞ˜¼>fïqäÊ®+4òuÎ08ç[Žw3bSÝ1Ì2Áf3„ª›oÝUªc"¥3Â#pãÚ°lŽZ mßG} nÜèt棜ƅgUÑ ñäÑå'ý\Éô¥Å4ƒ¾&üÅlHy_œ'Û®Zq5…CN¨þç7gåúšÜ噜¦Pu˜§Õb%aܧ,$ði– áÛþÝ:ˆ4|/¢Øñö^tÂL¥)ë¹¥EèäZè—ØQà‹û[êb°Ÿ98ÌrŸtŠù¥ ŒнßÞöhÝâAN³ôḭ=4×̲LõeCžâm4gÆh.ÕeÄK gOëÏãb4a¤ßËÆÙ¼iCåJ,€ ÈQ JVÏS¿¨ks0^·dOÒÔË‘U-ŸzZ]ËÿÔž[ž;QræÇø?ñZ§³Jÿ·š+h•ÜÄü<-ZÑuäèÐ¥ŸI7…ù~dŽ\¶5Þx‰ý°Í·,Ô ž0pckÛ#›ò~ÜD•¢–)±M樧²£ .în!D,œpüJ+NƒÖ°H|&©»áYæÕz BHìÓ‡ øÃ;ެ”ù“jõ¦ÇÁ?dEz¸¹B‘ï¸tÒÑN]ì§™ÃrÛó¾ZO—8zÜ‚%iÚ\±ŠKŒÓ—LT/ìAM’{𚆤 rxëùãÃG™²°36 ÂnDt ÞØIó[LÕ…ˆ>Œø„1ˆÏщîûƒÈ2h-½‘7¶4Ÿò éÔdÍRÉö×kð*L¦Æ„<ùïàÿw×?×Ì—8ð)¶ Ÿ–&þvÎmg,»>ƒDùà4ýÆ^õ­UìX·$=¬•¤ʨÃO&áð¹«E#³»)¶pQtæÿþFðIUŸ(G‘ àêZ`}?×ÜEz´Æß~»)5ŠUnŽéùô£Õ3ýIå\ ¢Fì{êû˜ s«hìæt?A¾ä*ùç%À?ß ¨—ÿOx n« Á€›Ûeq´õó…º]žÜ]]=ÜØÍýê4rùÿêœË¼ä*ܯ _py ²üîÿâÃÿ%|‹3öÞ^î¿ùÿßó»'…ïg÷öÎ.×.ó_ÿïsÀÿ×Þµ¿H®\ç?Ð’€Œc’{÷îÎôKRU*=ú1³;³¾vlœˆÁáÚ&ö˜:¯z¨{Ø–gî໚î–Ô-é«:Ïï½}P§Cvò[?©ü¨ÿCÒ&ІB‡GfLÎi\wHºšp¶#ß‹|1àÍŽÜ2D øè\߆è}ÅŸ®€H_ZŒi×wM}D ¶‹àÿÇ#9eÆø¦ø2AËöäx’ØL®$ [:¾CÁ…öâ€mè¬y9ÔÇ-ÜÚ1xÃVAü%³=¢TÆ-VV|õ´·!#̬û¿þ÷C¡ô/‚9¨ï¼:¥²-yƒÝXü*êÙÔBy: `ñ¡éÆÏÅwñW`iü_Àü¿{QñÍ!°bÞŒfF:pD>G»ˆ?èV5Œ/ñ?<9þnÂŽø³öбˆ?ÆEØPlÉìañ¿=ÎçÿB*ûUý?áò™€‹(9Ðx ÎiëÚÝ-yôÈp¬Z0Xf ûÐ 6–’pæG?_þr/³C’z’¶²^Ëy_9®sœt]sÊC¿XŸ‡£†±c~êàüz}ñϹY½Yšíöy÷™Ó—^:LíЗ[ ãœ~}½ß³gïØ%P焽Ûf 8Í ð«(g@§&JÔΓʋ®lJ Èy9§Eµ: D ÀB#Þˆ! ×{ V8ö´õµ3ÛîŽè=&ÿiüý«½êUñQJáÞ9' 'å$žÏŽñGõsÊ>?I>¾‚KI€ˆ?é"ú$âïsÈ ^!4( ›ÛÓâø÷ûù@åˆ.Yíè¡Áº"ó¨ÐQSàµÙ¾<ÞjgmÜ÷³ñ‡ÓèåÜÆÿEÌÿÍÃÈñÄߥ1"1™¨4Zø-âß÷bÍ« y²­ÜÆ==þcOaC+q|Ä¿s°;õ¶ëù.$âŠhâ¿Íÿ…âÿ¯Ñÿ§\>Û8·, Ï=Óÿ;=޽4‰M4έ¤¡ròÏg¿Àm¾ðûCŸÆ9§ÁéÓÏïæb€þ”3v¦$Y?9ÿ“Uß9^®!?¥Ú\®Ò´kÚ;<3Êÿºr³üO/ùL·'ËUWSNЮ¹N“„ªìùøÍÈþ«+²r¬ñ‰âÐ$ö9 ž…ž…°Š£›@'¤i`åëv·§hãcXT0S˜l\ ‡!žbÐHÃbøÿϵR ü{g^ÌëúÌ`e­'›]@õ¬ÝF]ÃúP$TSeÿÕNg' Ùþb*ˆ½P&0 ÁèÚíiaü×÷A]¿d‹„¿Ÿ9t²rf¨?Cü5\ æÅö)>ŒNùøùø¯÷‡^çeñ!óßÝaêÍ5)þ/+É (Àð[+øÛàÒäN¯ðì|÷îéñ7H^ñ 4è¢<èšÛÇÉ  …@¦Ù ªù¿ŒþuÿŸtùÜ €[íXb;JÕ‚Ù­ÿà·ï§Þ“艱” NØÉ¸Ró¿ûâþëýXíÄž?·ôéïÙ€Js€·!ÍÿÊÚ/®·N¶ÇWëq¨ºIHä ý!@4ŸECðMóS¤í'ã«×ß~ Ä’¡£qÅYü¸.@¦0ÀhþŽ E^Ò€ÝÀ×@£ag æþ\·ò÷:ëp­"Èíí)ÂëØQÀ¯\ÿß½§x¬äù] CP÷?q”¼.@à°2ãïEgk€åG ßdÌ(Xò>ÙhÀ¯Yѯ5 ,®ÚïáCè`̦[ÿ/?Q¤Å`Å[†Ìƒø_T&hþW±¨ÿ<„½R@‹9`Ì5ø¯ïžuËáÿræmšÿ—‘åmO‘6¼À þÖ¸žóVŒ~…Ñ€à~ú øÃÄyCIP/Øv ½\är®×4·ûbþ/£´_Ýÿ§]>?07´š®‹£i·ûÀãNшD9ž8?êÏÑ›2ùG²ÆÞüÀ­ ú#”›™ÿPþgÎ@´aÝ)Ûºå±çN€ˆíhi“¤¿=ÓÓáY°c¯]&WÆ+§ÏeƒïÉŽüDÛöCáVjà݇‘Cÿ¶vÓ‰àˆ$ÑCòȳŠ£ ¦5×î>Ÿ~i¸ÖJÉ­HR•¶‡èà¡Ýñ «4$‚Ákúp!üÿÄø3q7Eü'ä•õ/a}Ñ!ÀR¶à÷Ù½3P–€l@=cÅTüÓ>1ÿ£NÒî6¹ÏRè_¹]ÍÅ@u±\M‹â)…zàÑn<þÛ)í˜5]¶æZ¡ ÛUZÏžEiql]{ºÚ/ŠÿKšÿá0 ´÷šâ×l¼6·Ã\{°MÄßòÌdê?²}8²w3=þc/Úñïˆ4ÓŒQµCŸ < ærvÎìV§4ÿñÿ_Ýÿ'^® ÔpYÛî¸.ÄÆ±³ý"nø%ÿ4¶ÇœOÆ©r!%Zwû=ÀÚŸbpܪ !ä·¥ðgòìÜÚ½šñµ”8[Ï‚€ö¦.ÿùTüþÇë<ØÃåø/‰÷t“­I2GRŒ/Íö]8ëšTÀ4cBïÛ^+ÔJ®ºPÙ |[;ã ~¥¯ o$‰Ð(j‰¾!Ó¾* ùµí6ö4x¾ …ðÿöŽ\R¾lDü}˜³þFôÅ1U.X½àÏabe !e9 `ß½ïµ^p–н)þÏå.ízZ{”ÏÒ?¾÷‚ÐÏf³ 9Ô«_h às=Ó‰É1â¡çÅ)á üÃiN+ýUÎÿæñç“Ä+Òø.þ£Ñ‚µÁ2“€ÍÖzÏ·9™âõîšgÀ¿Ûkœ„’’zÄš *Ú¬Š$$ ˆ¿²itþ/¦ÿ_ÕÿS.× ´¬õv×ae°uMó/ÿ&É¿ÛÃ1D%À˜ZÄÏ! m™æÇÿŒŒ¡¸K9 vyÞ×óŸ¨}û€t#7ßðI!À—`|ïVÙþ/ލw„4Ñìvý8\”ý¥lÇ?»¡—˜víUA¤Ó3›÷©0KRññ°ƒê}¡!+L ˆ4M<$L8Jæ<[5·Ø]æ>E Ðbý9'@ñe`½ÑÑÞ÷RÂÿÏûÀy~ú 1ºv”Âïá²ÀÎ ‹a÷öÁkÙ[lLiÎIaFˆðE7€Â®âCIŒ×º}·þ7ªp1ìÿù¨”U¼W®þŒF&ÑÍòЧ}xCÔò×á¿>î‘qºþ/mþ7C‘û£³=“N jw üP¤Ê´S:_™žl˜7Ï?LI<Äë!K‹$°fAY@#çàù¿„Ú~uÿŸ~¹ÒH&[‡âµÛ ql›Ýí?IòMnÑõaKÛŽ% XGÖöoRíÏ™¡©ÿ§ùÅdG»í8_×¾¬LÞ?O¹v´”M4€Ä @ô«U%ÆRK`9) P©Ù µ}5, Àþ@“¯|¾z°¤-DXÿÿƶ‚9_,úAÍkOÅ$ìƒÏ‡ð½aü…;È> [ ™þ§Qlè Ögâöñ—çdO'€¶Nñÿ¨‹°Ý 3Áîš%ð÷9Û®ØÀ÷½üKM&‚f`^cbØ&º¡lµ¡@“~¢ ßü_îüÇ ñ[<Àymìv/z^j¬âï¤ÐÛ¯žÿnjC79 ]7…Úçç%G4jÐÞüâjÝýêþ?Ïru€¾ä櫟±„L·þòGìÝê¼Ègp\ì»Y=Œ œl Òs?ì›híÏeóŸÔÖ¸úÓòÌéí9Äœl,ç¹\liù§ƒÝÍq,«/ÛÿŽÓƒø6î:³¾0´k]€ë]n/ßÒ„Á;‚ýêç£ôŸžÓÒÆ™ÞKÇúín`]Dõý­=(õšÁ j\å(?á¥íS(’Üxÿ%þ໕_ÿÇ!ÈÚû)ßFt«@q7–N]ÓHëýPj¯,wúàÿ’çÿñÈ~­ÐsȃÄ¡±¶£'5ÿHH)Å¢¾|ÿ,øK $r B¯>¿šBg@>ĎתïW÷ÿ¹–8›W›ÇQä†ER—ñ‚ôùb½Ó¼ßMß:I’‰äŸß§bú_œÓË_ÿÑðïYh”æ|é0¤Iæ¸ü;¡úÙöbþ’Ä­â«¶ë{MPÎ|þêfè‹yÍóSŸ×!ËjO4Û“òUöØk¤Â A^u}Ðx¶öd»œzsK`¾tðs `”íXœ7~ öÅ/2D¬îñ9 \^¶·Ýµø{š‚Ó=âèCbýs_ìêÊKc ´Ÿã¯Þ‰£‡ü9í¹" #þ[Ó(ñ,^’Ö |Û5þ¿9öü ¡vu¼ÿaÚÉT/9ž{ÀŠ?;–¹¬ÏQÖ㑹°´{ÁÕæñ¡ ß ü_öüß<  ºŸ!LÅøv7ò€¸(…æ66ÜE¤oσ?æÕJ À!þ©oï–ƒag@zë¯Tà¯êÿù–% €8Xš7áab[ÑÚ¶9’Ý Úø±,_ÿûQŸûá¹È”_üð'Zû“žôuY ”OÆLÏÃÚšœ×òdÌúr +:;ŸþFÓMZ‚Â…U8ô×a¾8ä ¥hÈ’ ?kü¨ï³ÐZ0þýÖœr}¿<T~§]Û@J£¦`Ÿr¢ Æëc€Œõ}ÞÂÏJ†Eܯ™ˆHtÐà`A¾À£Å6_×áÿç}'üæ÷¥ÿyåCÓžÜß—žþgûô_ÅÿµÈ;7ˆø©¼pÍæx%þ»S*òÎ_‘†+—€sNëv]ŽX—jKzÃqD_ÆêƒuÓ¯´ýwÿ—>ÿíqàb?Íëƒÿá¸i`Ôä~ê/ã/ñ(ß®ž ÿý¬Pèÿbó™@Âä¾Ôö,zXxœìT˶ qÜ-8w‚{pww'¸óãî®Á-¸»»Kp‡àî“Ü{žÎ¼÷î9™5¹ëÌÙÿâ_Õ]»vuÕW{í꿺 àéìèøcâîàèý ÿ%?%^n~>?kãý’öâ¯Åþ¥aóŸ¬h‰—*À ù0XCb¦Á‘.ë&¢Ò…îœo §¾êK/#UÈ~]—ƒ4ËýV÷ôÝF.Äxu6â[‰§Àñ÷¶¡œ]T÷¹°%p±7ÀjN…†pÜ„%AM%#y‹aœ~Ä5ŒòD,§ãó"s°þ-,ÝÞˆꫳ°:ê×Ä ” §Ï»`Õ|½O<‹¹‡åŠTL6:Ìè4  åN žy\%oG$Ûc®ã)ÓÙ7!xá_À˜¶ bérÖœá]÷“Þ†=òG¿ä—Á¿¹ï¢&‘¿Ï·H¼½Â®îëgŒ"“> ÿ˜ËUHMÒ÷âcø¬mÔ´Np¨Øå¾œxmwgÒ?a»Bȇë«/¾·És‘;÷í8jñÈ~!ž’²Š+v6âñ<¸»8ƒˆËá!1k¸€KœÍDý~té қ葘rpò€ÿ»z>ZfÊPþªÈÑ–tz#íH7ô… ‰%›ÙWÆ¥vH×´ò®ÀgÆoQ/Ò=”Ò8ž¼…}ÄØ!õ`k íïÅ™A©\Å7 SML„[1Ññ\rbâ.=õ¡eÌ?J §žQsôô­Ió%5>Ë$z¯*¬26ÆÅè)»Ï &tu[ ¡†Îä4e’™L£¶©¢8\V‹ÿ þ#œk5_¡}\ `”C%™‰dÂÞ„^Ç4Z}N»»¦”«„ÙÚ¯þ£“Þ¯¸ŽýpœäkT¢ eÄ®˜Ý~ò¤D·oU.,Õ6w&!ÄÿÂ)=îXs$78¯+Ä>ˆ @Þ¬lòMõúÚ»×"”§ÕDG]‘Š@Úê([lÏæT “ÉR_ŸD±ò!ƒöÒÁÞÁªFÇ>¶ÀHB¯µÖ@íŽ%I¦3CYV$0+›à ,‰ËÞJ é+~·ûsüŸ^XÞ?‹©¹ô½Æ œŒ©'Xæ”ÔsX³«òÆ ô’˜Uû˜ªµäŸ°ÏžØ¸-– ÚhR”~6:L}J•Xˆ‡áú–v ÏB÷±F4êà5æ-Å"Âà ¦`óº—2Ü¢>0š@åd ±„=ŽqðKèhMàcö?ÿ?ÿ7d¾d.€èrøHŸÊÌ8²¦;Ûqh6ØJ\¥Jk¦£àðGHZ0Q µ(Ú¼íoDªÜÃŽ¯?ÀæùEü}[ÌmŸÞôqDßÞuМBИ8ø[|ót¸UtäéX5EYÂ$b‡~ûì}ûU½¥ºð1tËÛ;ô¾ÙQî…6 ¶ò°þoQÀÝÅ;Ð÷„Og'ÿÐ?Tò/ùyq÷ øYö]ü_§×JÜ]û,qš•QÊ.ÝÛ’­–™?E¬ª£:æ~‚¸€30¹˜áù#ñ‚LÝR¡æ•CÁŠSÄҤʓMX»Ýè—ǰÜ_™ïÚTiù®V¼²r*ƒÚ–Ãò5Oµ£¿B-ÔqnÌN<Ë’_ k,ê\Ž£æ#‚„ו‚ÂÜ ØRÈêëé/°ê!q—8«®-´#–š·7ݳ­Â-·é-èùgš€·Ðo´e›ò'ãŽö€÷¶?˜8ëEå¯DŒîȾÑÿŠÊS”R–sÈCu»« $ÈÖðæcB(‘n_{>H´´M5uÓj×Է̺ÙGöx÷;7aü<¡«Ùïù Zd ]£ÊÚô¨œË‡Œ½ÞÚX°˜'.® îr1ŽUGÿaþêYÊÌ!'ÎV=!.Y/Ò´*‘>º}0†Wð#èñ±ì_)´ ËÛ?E†píÏþT)üÚ# pn­|A“´Ýº_Q7…ñ&q6 r½¸V(Ë‚Ö.ën7ȇˆ»G9«˜Ç˜®ßÒ¼­ãÆÆnL³gL‰ýc­ïÇ+ :²SB+‡N½‡ß è²›‰ó¯¾l²·ÇUy2?q=&A¡wGzS2;ûµl™‘‰j”¯ròä— Üýzþ ÿ?f÷™‰¹6ÎÁ²cªE$»ó1%ÛÅ…íÞ(:³êäëºdQ/Êä{@h˜I*ô7B¨U;زXöq(öü"þßæyw·˜î}f?5a™.á<<ÌkôßÞˆ¶ñY¾=ª¤LÇ€%m?Fì9&ïÙSº¶îÒÒeã­õªQ€M÷[puõû#·ñnö€ÐŸŽAÉWoÿŸ´€¯ç ß2Xø>‹Æm^–œÈë(DXÁŒÜ{[7‡é¹OÜ2U5¤­Àö¦;¾_XE_¡õЬ±]w~rÂ/–Ê Ö_—¿”¤¨6!Ê6 ÷g3¿•Áÿ&¥ORgÛ oæ„7 /ˆ$Ù}®Î9üäÀm²OaÕK ®@¦êpOUh=˱Bc|÷ü]Qh}—òž/jd#TDÒì9Y_l¬þU»aõpÛ zÍZßÓ¾ªƒ¼ŠwܬÅU“"}.÷f >®ÏžFtó“ñÓeƒEQWÒõg ‰Þ¢™ÓŽ$‡ý©´ 7;Xƒèä(dÊ·éfÖ³T…Ÿ¶¤H4#-îOÉu²de ­k¸îånzlÀƇã!Àb»62G”ùRŠlÒw [ÅYW"祄ˆZx(e¢äœZ¹ïÜop‘DÆ€ÚpA®?xO½Ž4+°¼d¶ùaïÊ9$²ôo!ãu7Ò6}D ÙBºï›‰Ao'$ƒ8°²`qÑT²új¹Ô€ªŠä„+™!äÀ‘?pã.#–F,m%8 S@jæK]ôŠCMiìÛ2 ÊuFÉ~ .xÎÁQÓT … ´¢°ž-¼Z®Œë?^ãÔÏk6o¬2MÁ·´¸FÕBË[¾gÅ$™î:j á>P &n3Pï>"EÙ"Á€d­ EÈœZJ÷åò_©ß£O sû2¯”ܬ´4ÒÓ®M'ýi^2fÑ„ÞÌúÝו·ÝÎ×FÇ!¸ÓÒJnÛ÷å¹\Y¡ÞJ…½zj’Ã%F±«ºÄ¥º”rÕ¬C±4 :ÄàòÅÒ!gõÛ`ÚêŸíéìdNË©M£¬ªŽ¿¢–¥]{î˜âGO-6ºçpÐyŸÉ:^7Ag°RH:_[EÈQöÚS¶¨×º;7·ÛÁ…^=Údt3ÚZTTé!¦wzúà}ŽÎ×üèîwÄSÍ-ûîð'øË^VDŽ.KœFŒµbÜ|¬ßÚ= —,åf¬FIòùiæS }ˤÞÊUdpžŠrÄ1|á­5¹2òÖ1ÖpWyâz8i¹Ö–RìÊÛõ໩ÊuHîq!+# é㣈¸~L'.×3¢Ë¤|œšaxûëùÿIü2‚Ÿ?ÒíåÉè|ÊK-?¬^<ŒËÖ Lr1QíŽOv´Ùxmú™’h:é}åá&“œƺݼòXÇ2Ò­Ä/âoù»²’r!–p’cÂ|»ùú°CÄmR]ªã›guîñó}ÌܳîIÿä(ï§» Íûo¡ñÌb;$p!ëÿ¼\Üüï ÀÃÉ%(ø§ƒþKþ¨x¹úÿdï7KÜ&ÆÛKB   ÑXkÊnŸׯËÏîbL¹þ ‘ˆ¦õÖÑǵw†è¡ dsÍê‹]PŸ ¾È1_k.@qÔ[²JÃâ43,´Ûù`¥r× «˜Q駦»ÚW-—ˆ˜g–ŸaI—ŒÆÖ†‰0™ŽT³ã"i”$Ó縚Þùµ~³üí¿kóJ‰ÅÙ-þƒ/_½cbîü®Uzâ÷³PG’‚?}®âª6RVÖZBz}Ó ´Ãq‹Ô…±~8Í ^dLl\iSã;ÊÒøm|öˆÔ6ßåy ÊÀÒi1¼t#›oÏÕ8’Úá~`cã“°ÜQóxû¼z­~›JaÈßæ–¸(Ë8½(7‘q•¿PðF ˜‡l ]wÊјt^…~¡~À–NÞD'ÅU€ÖÀÂF4§gì›ͺ¤Q¶mo‡Ò iüZ‡Cìã˜ä¶@à6gJ×®QžÂ“¾À™ÇZ¡ð„…J\|:­ðÅv·-„½CŸ@¥kPQÚ!pÚH@qAF†”—/¹ß½e1°|š.G‰3ñÍ·ÉÁ®köÎ%ReÀ¸j} Æ2AÏ7:ýáŽ^ÄnŒUD*{݃Ÿ;v?–•ÛWõƒÑ}è¬é ‘¤Ó|ê[¬[pM½ òÀŒ(x3›!“¿õt £“Él”~þ×\ÖËë¶ Þ‡08v¤ÏeZ„?uCâ^ЄÃ0¶Ó©B‡Ì¹Yó=ïŸn‹ËGâÕ"û6M4PÔª’î—Ó~„ÇTÌt«ÎM¨ZIK»k¥eGtG0)m«oê=êÞq‹ˆ}ðßšô †h›+³ íR¨0f0h{oŒY˜?tYÕØåV0¦˜;5~X'–P•:ÂÐЮ6ÚÝX:Á­¤‹Å!©¦qÕŸO$Rž +-6#Ñ\Ç\â{ŸÑÍSøîª¹Éè®=Â8'E] üžu¯zwìóoßÉ+f (öɰþxâåËûQé#|3×ôSE°Þ>ã.Eg–9‚£¡?{ú—ü„üô À#Ì›~øNÇÕ8›…xÊÕú]0´–”™üªjÊ'2™apBšQqŒÐ¥.“”Р³¼ Ü‹Aâ`.ž>&ê5pßÑP€ØÀÁPÞN@Ldcˆ4Ýz" ÆˆXwˆâõVÝ5ëï¢>M}é~o„£®.¿3‡T?­’BtöÜ—d@ UÐ»Ž¦D­ß¾Zoš ¢›ÏJÄNæã‡!†SÔë|Ý–Ú¯Dä¸üŒ¬ªÊF%Ì'²âôUwHž·›©ö“æÌ)…¼WrzƲƒ\×;™ò)ªòS‚Úýõƒà=Ýw.mݾoM+¦¢0 ”XØìÃgáŠKëí¹ÞͨCjÛwð’Ï ZbzP˜±¹¥ô{ÓÚW»*Úú,ÚîWÁ‘!u—.z»øÌü~þ ó¤–|ü&öôD¾ý(F#v3Ý(Ò ä]ì~g4\›é‹ÚŠntWV‚ØŸb—Ç̘ i´ah…Ts#½¼w³8«`.’ä”XúÅbmüç Ëø7qŽ4›ŠÃlñÎ2©s½Æ¾ÞtT†M' i¶µÞˆŸµ ÷:ä9"ËúsßÕG½Q+½‘¬ƒÒ¬üØþI ~WªÿBUEB{ÅÇ_‘ÞÖÏ£~2"wrvßhÊ ¹ ÝÒK@ä3ã9Á|fŸ‚º³ÅéóóWÿ£ü+õ¾¼JFú¶,ÝjÌr;E*Êëþo9T‚ÞtÐ)†ç › _5ÏK‹-+ÙèR]ØËt>qëjׯ}°ÒÄúû›ìƒnVð/ckÈè¥ÀF{Òϸ2.x¥ÆªÐÛiÄÅÅ ±>OBŸÐM 9>BT§S‰&·7íƒÁýbþ*ÿ÷T·B½_æ¿> ˜óäSTwÓÉx†Jx^çw05Ñûv()[ÚÓ4¢.Lª«³îÅÿ¨« õÑÁàøiåu”©u®•€îeÔsîc™N1ЗaKtàšª]˜ °ìå MêˆGƒ¼í(抵p¼èÏ-<¼nn0”Ðçê Øk€Úlv)V湡.žÊtl^" \\´6xîp@ùs¢…µjmž/¬7œ¦à—ô ÛR³¯DQF‰íŽØ|íWÞlEÝ2/Q½;0}—B¦$ÐK^»Û»…Ùx;ú0I’бFið8ïô)¥Ì§x‰0åÀæWµMŸí1÷¹¤Ùˆ²ìÙE³EYe˜pe‡æTØ1‡ÒþUz(:4[óÇXãªÓm%.áŠMG•—´’Ó”‹¢:¶_ËÿÏåÿ=å[èÑBðkh3ymc¹âI´F@püa¹*ÙbɆHS‘™.bbùýÌÒO‡¦©ýÆ­¿Š?ᄼŸôr0]ÝÇiS‚eÑáK!¡=óQøtÚî^?Ü÷©2®Oµ3È#ôî À­¬Ä'[²¯rSB»¾Gÿ!x¹ºýŽÇ¼\}CÿèÆ¿äÿŠüì € ­Ùpóûg]ã2WÌȨõÏVLH®Ë~­ŽY" „®ÉÁ…ÊmTkE²éÓ¬l$¤j,Œ­®“6[¢#ø@ -„Köñó©dáÈ;5$Ë-ÛðŒù OáB‹¨¬7]`Àõ’ï_{°½s5¿Y Ð ¹§¿f%Ÿl>PxAXhéû™bÀ oÈ‹˜ò+¤ ]ÕÒV ¢}ÞÉK„‹sw“—Ù7ÃÆ/›+º y“P² ûÃŒ™<èÓ_F7Å”¸³Pä¼3 x¶z‰t—0pý€cun©s©Q3P •Ï,3Ìðw ‡ÀZN`¥üŽøðÍë:^3ͧ?Ñ}ê(a¾ð.4•$¤Ú# †ç -"'»• õ AžÍhZÐýfOˆŸdUö¶¾(Öµ ãýþ’‰¹²s‹‘ i|Á'ˆ:ÛÙK5±–dsÝœæ3-¡ñe _LªÎ> J\Mwcê¯SúkcÙ¦„MäL|ï[‰Í^^Æ„8 a+êmÝ«KH°0slá¯1¨â8ÏÇß–åñL¢ñÆ©¶K4’‚ lîo’–pÈÆ ³Kx,TÃt=<´ðÐ[/Ç¢ [ åŸjâ÷Ès7,Y¡¨öNâÑô‡uGð™šÌ– ¢ëå |^a‹°&ÓÝÎ>†ôDùüûø£•ê‹Ü‘_é„TŠ%¥Ž%á¼C+çXÛšåü_Âc¿ ‡K,{Ì‚XöÀs¤‰ƒž( ”"ÓNp¡ÒJ;Y1ÏYähp×lq:„wkÝi›T­Ka‡.o£6pÄœÍI5ZP»Z&ŸŒ(@GÔlå(pí•Ö úŠ),.Yž®í1ª¥iL×p«lõ¹Âêâ -’d ¸‚ƒ€G„E>7‹½,6Ã@0?ÁN‚xÙ¼&cPÝé”=œ†8M&i`q`Ö«g 6¾3ÚþCüåŠR6“µÄñ¨·æ˜O8Ñ¢_ïP°×—›òÚ-„üç˜ 1¥pª$Ù !µrh—@|hê]†À“Þy-N8í9 "Ø©ªI¢º :0Ðk¢Ÿ÷:L$©æ­I ¥ °wo†ÌÙ÷€V¨‡dÁÔb ¨ã›åvn°ê4PÿRþ6ÿK°üFŠ`÷ ÓÂŒÃD<èFÚ[šw¾ a.FÉM¤©OóÅf¶!8Í!=Ç~­'€UäJM©_ÆŸÞao 4ì}x/8‰=ò×ëÜ äW]‚,"+3¾€S¥7§Ü2KXFSœwð´7Éñ7)èÊŠÐC¸¯¶J™xžÿ)xºxþ£w”nžíýûÕò“+Ë©–þéPG 2£,ŸË­É ôHáY”x»ÂLAš9‹†¢oð€J˜eö0}¤áÄ¥ž£Mð6P@φ~¿ˆ_1[-‘–swR—X»ä8„ó8`@a³8â‹ø8UŒê‚äB&TÐZÕJ‹-,$×qGÃæÎp9 éP˜ÀuA˜jeÁ§^èø›mñ¯ÅÄæOJ"á$¸ŒeÄ^]ñ…àÝ©nJ=à˜øßyB$´Ä€Õ/Œz!ª¾Ïæ!Ô¾”²Ü ½Á6\ш$I\ _ÓRA}ÚY)v/; ¨>qA§±Ä¶åu.yÒð+d´ªƒ£!PPª%âpz-%(×’˜|nsòpÍ_\»ãûJy(~l’§0ì×¶Cƒ¥'È%)"c§º]¾¼Þ§”}æ-BþV£D«Þp–Q\ˆ ÎàîýÅR ò`¸GérJdèúÝrgîäc€ñÅ6È  ¹Ì˜xdn«y—]RBª˜ì53˜v},¸žùQ$¿Œ…“› 8È4ÇÁœEc¯?WfH´È'×’ú7õ×ûûX²T{k-n …ޏ¶mø¢}cáïÖ‘çCX•lE2Ó¯ó§f,¡úB•dÔ'¿²Ñx¶ÉeèG†·{±Ø†OG6ôe†Gv™iLkšM )¾¦¾ÁÚÄêúüÑÌ!K…E.dxÏAYÞ~$ þ å"Üíêø¨ gÑUœÊ ëÛôÞ¡¡úSŒ6ÛÓ¡qU>lûæjË•ç.™r,VáÏxÊÜ~2ØË›CHòm÷ôÌ×ÌAÕÄ”ÓåĵñÛ¯YN‰b!wÉ>Až/¦AaóMi}a´a„a<~©UVòê¹/ç¹ õTO³`Éõ1òÆì±%ÆaxJ£ªº„&C²£ÎþO6™¯#ZCE«Ÿ<–1Òüå°k´0{*âH½LV¥É³Æ–HR%îÿó ÃgHVóLE‚˜›ü%6ûæN, ËÉ2 ÔæL^™ûêÈ„eÚJpœ y$:Õh'Û"¾ C.=HG[–uè#Oœ§§[#Ñš'—«yçÚ(,c”ø GÓ.nð<Ìe—ç)Ÿ³×>8=&ck;ïU®gñ³gõÔR‰èžÚ^ÿBþBÿ?Þ3ïñ¢4.Â’ÂECÛ‚m=e„e* øà]·™«HnéõM3Œ|.¤ˆÈÞC'Pl×ø×ñwhÒsÀ²š499 [Ä=¨xN„ ËiÄ©›UÞ4´0†ó”ÊFÁsæv›î–xî d••¼W-ý¿EgÀ?ö€§³S@È_{ÿ~µüÜ ÀW­µ0ñµ_§+—ïRÿ œÊ´çpq¦ãξñÌ’R,zݸ{³k VqµÃ³0D ùx¿àeõÖ‚v!`âŒê(Dæµ"ðF Æ\l"Á^ähÎKlrÑí ~ÉØ,*ÖÂ_N £Pâ{¸®ø±´{ïÃdÙ=˜ÕÚ7Ø7>Œ†&‡»0‡¤z£øm¡¤ÀÌWñ/%·ìšÐ½0ùüêÁî«Iy>dq-t½jk8ªÅž›˜›.æ™h;Z·ïàN)t¹ã?cSÔÙ ˜ûÍjrrÁw"IŒÜ.Úì«hº¯§7²Å7ÉVo¨ß2ͽ%X;#a ^máì‡kmg`Rè(~ìÜkúŒC Å$ç핸IÊ£»Íà½HÐ%§9Kz·s ëñ• k´ Êb⨤ñTä-UAö‚k-‰&h±Z~½EžXÉ=y°3Rǹ»yÓŽúá"t£ƒ}.–¼^&ìG×;ù¸­³(Ò*l@›!5z@\Ù°‚1Áw‚ÞV•ŠSŠ«>e0›³N±ŽÞª÷>ÉîlNÌ鿦m'@5ÎK˜ë…°,ËÑ{¤AÞ´§Ïœóc½Ï"×ÊŠ5D_ÿ‚a¤ø»-þ’Y_%¯ÅR\nÑFy1ß/µ†‚ƵÝÕpIK^oÊ›ÔC>£û¢Žð,¾GããÿGùo÷@i}Þ56œ~¬P#•2´ÀãDõ4–^´´¬ŽŠbƱ%¼A–ȧŠN«"¡òEðÊ•¼oGkÚåPƒÚy!?•GýL MÇÛùó¡ô™›YDÀñ’ù_`B .û<#9IóO;ÄäƒjžŽRøÌ"¹˜­ƒ(µê}i…¢lEP‘67ב J—´õµÄQ¨P®¦€pc£|:Ú±‘y«¾€ËLtшh[¥²["')èÞ/I¨³t!)lj8Â&xåÐ|M9G—­vZ俟ÿCÈè™§©=#ûæ %?¼5¸«[:u1þ®p²§ÎlvQ¸!NÈ›¼¥â‡Ü pHè/Ä€¹õXôB ½EØH ùýò\cdßÈÓÄã÷WntŒÛ]GfH:*‚i)¿ŽÿŸÓÿŸl]VQÒf“ !ã®|d„¤ßÄ1z[K2>£ì¾!¨ óÊä eÚÙ¡ ?{îYãßs×Dÿeü‘©õEîPßxnå._U ˆ7$Œ_Q ,VÉîAVETx<Á§Qý|ˆ§f¡?!@ âŒ­É¡IÎÝNYnýb‚›‹ï?²ªïêð×Þ¿ù¹CUƒU%æü\BT%)`ÓýŽ–˜gØ ÿQwâýâõ¼ý¥Z¦Br2O*YFÔ%î8I× 99šR»cûr«( Ú€FÐ5*€éÎM@<:“¦ó`ÑéLÓ󑍯Â&ãÆþ•uo6fLuÀ¾¸…çc"%Z:‡6!{Þ½¹Æoš³Ý‘OÿˆýÅéåG6ŠÆR%±>ÏG6±Pw\8eÆ0}´Ö¤¹9¯Ì‡O³¨xì°6'ñ»ésE{|z(ìC)‡(T:rmZã•HÙ›Yç¦îð(TyŽø6¹ÍᄵY¸:&úÈŽïr 5…Tº%0WWÁ:`¹}Ò8ω“$ g§^ôƒZ¬Àºp‹úuó»ßHdÜã»}஘3³A¢% ;hbVK½/¸ &ìhcêL'm®çƒÖ³b®,Xx•rI9{õ©¶•˜cC‡5AœXôi†žÎ«³Vän¦xMâ§“ŒýïØHµ)F2üj.Þäöñ5¦¶Fg™Õpè451zñNÏA~ƺ«dà.äSÞ4€6O~ÎtºRò@„iÏ‚‡§ Ò™‡\(š±ƒšÛІ, ba©RKøñÄá(WפqJ$tÖ …’Œ³ØÕ¶~bä[®6Óú¤´MéšÒFÉÖpìH€‡%ll5”©(gÜß‚šnRgP¯A‹oíx3d—èÎYùÿò1u[=9b8Cñçž#Ÿ¨MÖ9nN;'‹˜7©™7ÏaÒJ‡äó~4§Ù(Þï©ÿ˜úÒ¥j~åDQãl2óTˆ©Ž‡=xÈÚʤ¸X<ü”­ü•×i±“TJ¼ó¨XÏ£^M_>!,¾Ÿ¸Çê.Îù àê†l éå ñzqÕ¾Ûr©í„Î:ÒDs!¥íæP{:l«|–?ÙžÝPk¥ëe“ÒJxÿÖMyršÂÆè \o3“:l.ûl@MR ÈëCå»s06Ī–ËûT"ºÖóßÍ?;<‡B¶ìkq|fûùJýe²ÏQ9¾«§Ô,ó¨" {:J÷öò–ð-g7UWy\‘ ~-¡&‹ÃŽ:ìŒÕŽÏQEøPÂ\¯Ã*©Æ×f‹Å¨G‰@ú‚¥s¯1NÔØñqnñ0!¡U>yV(çÖ‘€ºKYaîÖU FU¦_ÆÿOêÿãEø qoœZ2·Æ×‡bq1éã‘×*¼f¯ÔV2à >j‰X¾ˆHËŠ 4A²w®A± o¤þ:þd_ÆØV«ÞàÏcnä r%Ü®Z<#œ˜™«î“%UÜ„@ïðZny)•c+ê‚4²¼—{óø?‡7ÿ€ÿé‡}G׿öþý3ÈÏ­`§Û‘fÜæ9m®ô¾Á@+Ëq V£¥·BæÕšä·•V1Üoབåá*!¥º Ïc›{‚3Ì(L”ÆØHÊ,xg&±›E¡U\‡vƒyåɰÛå¶“·=#/ÂÓµCÇò ½wÏ ŠáÊt[[¤å[/ÿìàÒE“Dº­9!HÖ×·¢NÞ3á€= ©\d˜~³Xgk‚°̬y†\"WeTÓ@]r«GÁ´µêz¢ƃˆ°ûÖsÙõJP±ôv‰jÅ–gâÞþ²äOæ§o§Q¸½øêËuT&îž~Š¥€×Ò˜.Ñ’Pö3•éúHo§ 9@r±—‘Å™¹´Z$2vÞ¾§žš^OK öâàú"Îip¸ã÷ñ`²t8GúFÛåŽ{…ç8­Í²]¬¢A®fäXØÜctÃwTS¥,ó1÷NsG‹ýÂÍØÉ‡£jÅ{åÖ€­\1e¼(Ú(MHD„µôÑa,½|/Ù‘3ùh'gÿò…gFƒ²µ©ÿÐÌ•@ÏÒòJ°ˆZ«äyfhb³;dvœ¯æÊj gWF’6m”¿E“.Tc§^‡§:˜Uá>¥AÚÂ[ ›¬Ïœš4•¿EtÁgiêŸiðˆ–áÔM´I¢dr@^%X¥]Ÿé›ãÛ$QÒVºÄXÑp]q èx‡”äKx” ˆ ·zB(d¤6 ]4(oaí7,c«QÛ+••îÃåãA ¼Óe*U°ÞÇÔá¶âæ¶ jJÃĪlڣŇý0Ëä4Å’®@Ú ½œHË»’ªIîÒWÛ@JZµaᓺê‚m’ÙÖ¡,x˜HÂä¸P€ÉUuüV-:¥9EIE»¯ÚHOïÖ @šÞ TPp²ã²±¹ëŽIš6Vz ƒú?ñ0Góàñ쌔œ‡ÝÝ–~‡É¼ÒÇþ… ÷²2Eª®}»C Û3Ϻ‚Tó`ŸùVÇᨑ0ª±ç>FÒ4HŒF,["7AÇ qNìÅÎF…Rܬ¨ï ".EîÉsN =«Ê¦>JáíH…,v¸å×¹ì”×È+Ø™œñ˜[«0ï~7È•¸­–=Úð)šQE<Ø ì4–‘&¯¹|«¿t«_ˆï¨`žÕ­ÍdÙÚÞQÌ÷ó‡ ìŒ]†0CÍž;–’™oä/áÿ'÷ÿC5yGÀ¡ý!»…R;à baïêžÒnˆOÓÃÙRÄðúl‚uÄO–¿?ö¾({Á—3˜,¢ ¡MÇçõõÙ‹a<«ºàR|ÛYºÛÅHˆà7—Áf(Ãs,Ì’eÛ¬,"/ ŠJÿuhpuõý¯¼§‹£ß_{ÿþIä'VÜñÝ5Å TT œ :œãÄÔNp²¤Öô–Û› ¾®P)Yûߌ´„Úç¯_›ñÙî¤97Ÿ\K}Ÿþ7°­ó£isŸÏ"õ8 _¬2RòÛÚ5²÷‰'i\ÃolLŸÊ¿*„Vh´~1šFgb$J}IÜÒwC»ìŠÄ₯š†êÎa•Q%E–I´ºÊIY±¿ûðªmìÏÎR]Þ &_m7•(*É|Ì•¥k 0•ë€ ÿ)d¤³b›«ÊfȵŽÖóÜE/òAì·/~¢Ã4ß1<¯Á>™zƒß"o/bèÏäÓ ë2_ãÖ·¨N—¯žãÑôãbVü¨Jq´0ãÚ2äveà€Ž5™•Ýð Ó—ÖPe ’f†¶ëî Gž¨w(ퟋ¡M›vaL(ø£›33"0ç‹[EÏHiXRra¹ü3·ÞùÚ§YŸP#Kä,õo!ŸW G‹=¯}ÙÀ>9ðzÿþ ¶ßEâlTã_Þ$âBÒÎ(j›4™d¶Jìcˆ © ¤/üöÄK[Dœc£žI¦¡¯V Ôn]Dl…S7Šñë ý­ä‚8䣀BNîŽüÓ!—\ñšƒûç?AÞˆÔC4eÿÅZaR×ÁY)°¢Â¯^²ü¡ò'Ü1UÝ‹ÚÅ|¼Âõ\úÅöõwX6 ì §ÜîtŸÛ…-ÆïfZëmþ{þ%2KÔ¨n51t·kËþ³†å¾îŽ—ËzÙR?MÂD0夈Zoé¥e‰!‡?''S‚¾8MDzªDAUÏc¢»½ðH("çÑ“èèE€­™ÇAk„">”ͱj­}û$~°:—úèö¦A« 9DYµÃÚiâåãªå ´]cè¬a…&ýÊ;®…çt´ÞØ9&D$·:ƒ9i·E®È@sL!œ4«·òh`ª Ÿb샺:<G.¹î©é:$«Ö Ù+= {#ç¼ÚãEæÔ&‡‰Ï—=tm¿ƒ¿ˆDf™®P¸T¼z b¸¼¤2$ñþ+E»)ðá}UQc/î¦ïÝ5Gèhc^¹‡ª|GkxL©å9…‹`‰žI_Ô“ËspüRür•ý….–iõºžå>ç°î5~À\¶… ð¥êb—_æY €ä‘œsÑN ½~õõ&‡„øÉ«Š_ÂÿÏîÿ%/ÔÌwûRøƒQ}ÜFOIä¯I8 ¥Ÿ22œë–‘m˜fS{mòSb5 ò[›ø%ÿúáixªR[*jò@ øä-Æ9`_Ä5â=§xšš¡´<‰‹6½dãvd¯¦2ô”w Ôv¯ÆÿMløï^ ìæàú?>"ð—ü?’?¾0H@5 1*ýö ค4Õ¾€"Å5£k£6Á݈2l:(m>TâÜPªçrù >ýrY—Q¾ä0 zò!Uu·¨9#c'!'$O›»j/j1Ì«8Ë”Ñ÷‰éO{þfwÑažóO np.×Ï'mï »˜+fÞ'sÚ(Å“#.–7u”ÈšB¼wiOäßåÃÁ‚xÍUIúvÓ/·s\&¼cóXª2»¹¿±ØÚàÅPÐ`¬y4È÷@·•<ÒLÜ:>Á€½j`áSÌv,è'&N9žÂè- >°Êlµ{瘂9µ¹ù¯D¬÷³L•>h#¨Åx@|A‡hSQÛ¶Ò,¡CÇ_:…¹žq4<ÔNÆEGã¨j oJi.¦Jy’&v± ÒD7«‘ºOTåWž4PÅAê pPŒ¹W|!t®(ÞÅòm$`r «9øÝ¨Äë£ü¡È !ˆpaç`®y·:¥¥S™{¼ž²é¡ÈkÄí)Aš_9ÿ'?=R·ù2 Ú­cGÖQ{*øSO—«Íl_«éw-}ã¹FÙ9y«¦JS³Û[Ë}¿µôXC=zÿeà•ÚUz&#Bx&PŽ3íÅÿ½½.Ü“r¾„Î^h†±ZJVF…Qi'í'‹IƒÛb@ê95¹ÓWòUù»e_’éAt »KùÃÐCн©*‹‚5{‹¤.„œLiKöó“0Š"RðÀ½‚PµÃi8÷²á'pKÒ£ Ê“¹•”ç}%Ñ‘9„!¶³>÷½`¨}ytKòÍ|œ%>ÔgŒF×úàÓ~!b1ÜLxdWˆœ»Ð“†#×xxħl©=-êz|“Zéâ²÷¼+‘jþn}yßYÛ•¬7mõÕ‚Bf8ÐŽ5>¾…È`›þGùKh[™¤Û(1œ rãɨñ´l~ª1Y=†…kø¬ùY»ÏÙHó¶mU<•{ã³A×»Eœ#F!ÓH£ÙqŸGæ$­‰ôQêG]Æ|ŦŒ€Q.Ù sGMc*Ãjט9’:ÛY…WP$R7ê¤ãé×iœ¢« Zî¦.‘«ÿçüÿÿðÿØÆ—GÈu}D T@™ÞBûÝ$[ê´ˆ´“ÒB€ÇìBi[·q`©æ¯äo!¯éK7ï¯%³äŠ7&tþ|,£}.¹iq,™Æíßë„N˜E‰çfH+£ŽñmˆâËò ­ñîŒJÒ÷àõýïÞÊÿ(û‡ ÿ%?%^ÿzÞÓàåæfò}šçí ðöòp}ŸØù¼¼¿yzùþ­gã¨?o/¯ï§~œxyxúú|O;ÉEÁ~?.ÃËû_,þ=ñÛño‡ßmxzø}·ú·KöüG“Og?ÿ³ó÷ow?ßß´ÿ¥±^ÿIço™.?Þ[ý·¤§Ûߊxþó×o‰ŸïšŽÁ>¿™õþñÆ‹`ŸÕù[ö¿¤Þîžÿþð·z½Ü½üÿUßÓ.ÚçG3ø‚—çS^^>¿¹•ç÷^õýÑoO÷“´ïŠß³ÿòðöü»ÃßZéåõ÷^ÿÞý?zùo-÷òôöù{.à_®ÛÓÅ×ç?4Óó;6ÏïzÞ¿óòþwããÇ%ý[úßåx¹»ZGÿÿ’`Ÿï9^?ö݆§÷¥ïÕýÏo—ò7þßõ|~˜|oÌS?lýVÄÃÙßÿG[½þVõo/w?ßÚ?ªòú­‡tÔ÷Üí÷ù~Î㇠—ÀzÞ?Ìü2ß+ÿ­Äþööüžú»â"?ðy9ùüÝâ÷ê<œ<~Ž¿u´Ï¿È•ÿrê{þíðoãÿß Ú¿óÿßê÷köúûþ_í]‰×yÿ[-Ú4’¤McY«]-—œyÇ÷Þ$wW’%YNZ#n´ˆÄ-òö}×;HJÖ°YÚ;â\äp~ß}Ow&³gLjNc«ÿØøßþþx¡ŽØ1ÝžÁ3 þÈÖÿxo Öú‘ŽÇîã#áoÖQäÈ ¤pEdàjÞ@€ãUdVzÇ4qk àAýóåï~ë“ZJ4`.N^£@Dbóf1M#³Ñ ª®å£³¯Ö$SAhØšaýß-à7/×¡ÈÆüïŽ 40ÄúÊUžÒ?öäÓööX7…¢ñò²}›ôÄZ;-¬™q_ÅQz`–ä‹$ä²ðýÅfλòjûM%;*ïè_qòéDz]•?sj1\uffs¿2$çÝX±oÑî$ðm’ƒ²ª‹»ÚÕNz€' À?Ù×Q¡šZ*Ó/Í\<½5þ_½œQ}'2Šž-.éjË*ÈÅ'üTÈž.ÄüIø¿ÀŸ*Êžö¤}Š?ï +T6£”& Æø³å@v–ˆq]ùEYú…ôn±‘òécÿñNø_OE4Ëÿö3Ÿ+øW ñ/«!¬ r—ÅÐÆš”i‹™ÿýàÿë™hDô>Yóü‰ÆlŠCF+!"w¦Óz˜¢#£×ŸlŽ„?L|ëU(8b”l¸Ê`0‹© {j*¸…2¹Kèàáuç×Ý /DÒŸu/¦­Q·Šs€,µ‘.NO?…¤QZM8ÿÀï·CÅgYäÔ¦}^uý0V—-ÿ²ùoúËò9…Ù³Ðhvþ§“W0W,—œ“1BaïÂöYÿ×·¡»¸œwå?ý¹Õ&ä”Ãñ|w1l©:”jn{ ém±¼‰£haÆ *Ì‹Ä%ÎõvÈN¾ dåÏ⣇Á7Àu1_!«øô5qBÍÍ^¼|Ÿâþ/!/Ž.œÔ™‘߯áüX…| ½]†9ŠU€÷ÑØ o6ÆH_‘.¢Ó‚$9,Ö‘?‘n8@·Xߨ„"ùkáO'šå,—ðÏä‹‹~¬)3 vÁŸÞš0È׺¸s ï‡ããOø•,ï&™?ÑÓ'ü™PÄ4„fæ s,üqN_ý+Y˜£½Br$­Vþ$ö‚F²x+OþÁý?îëîK¡>¤œåãùùÄÂ׋ùIB‚<­å߯¾y6©Ù(Â×/þà¿®9Ù²t5•ä¤Í/Ô|°»˜¦°³G8¼ÏAÀf·/oSá#ú0Sœ³}þÇ?²ÿÎYÚËaOþ§_¿ZžÎ.ƹ(}6ÔëÌ4ìiìsrÎñ?ÙH "xóôrÊÂú·Fý)¬w±Bž&œ^SŠ¿(ÿ¨Qn² (KÓ)1Š;ÊÅÐò0P ª-@BãƒKz¯Šÿ§;?d ËRài—#|ô{Z{?mYôq3ÊÝLø_ÜÿofœÊÅIPÂÞäÊ>]Õ¤XÒ½J ! Híÿìø“ùàXåÓ1„¿¨sÍœÀÔ,ã/¨ÓÉ¥BÀÀõ–ê ÑÎ¥j@ŠÿσF[ðc){ðŸo‰ÿf£ ÿ_«$QÀÕÎ)‡UÔYD¾f€…þ ÿ¬³ðÝp\üïÿ?ŸC•û'Óñ÷ qÊ¥×bêÁZdæ'Ó±ðïç¡6b¤@†,Ä_3Ë_Õ P4`'|„‹÷V(êÿø¯»f Ø‹‹§Ñ²OVó™}6sî)œ:cò Àï/ÑŠ%럓½æ?øv kùþÝÞ€ÆM냤úWTm·CÑÛµ­Uæ_…'ôo` gdþÇ?ÿµ›­Y^ •ì' ¦|1ÕuåoC=³‚-ú4ð—,aÖø¾›Õ¥c¼Ä  â qt› 0ƒ2-K‹i@B(ÛÈäX - ‰ï- Q¥øÂ~¸s1­£Fuû³p3üÿÄø“¸R';”`uÊ~g6«fй’Á-‡)’_䒠ޣä& @Ç$ü#'m%˧XÄ¿”þ×ñHøk~@*М°f±½þv«Žg½W•â_‘ᯚ©!å¼0­^üsX¿~¿ó÷ûÅÿ¾ñ%Ôà¤;$Y«À–¼Ä@K[êˆÿêhøÛuâšACZwŒÿn `ØS7 <èÿàuÇÖ ®ºÄ>"ìòdól¢´«H+y³ZþàwÛu„ŠaÏÿàëí$9íæb2uÆfµˆ4Îkþ÷öäåP>ÀíUüÓˆ°(GâÛmZS_vùóšÇ³ 8ßÔ¦tù³+{9TÇa1Ù:¯ûæ¹Æäœøþytì°7€^¬‚n‚ÜÈÚ=ù3‘ê’e¯yYp°ý µrP  ø¡¼h3>+[º†à¿&±$Üju5ª$°«Ç×7Àÿ‚UÁ}h{˜Œ?`ˆ•Ý—ð÷¹lä\í¬ OJ#—ÿi£…DM¿‰jD5ÒÎpÔ× ì‹ä¶º\ Ày_ ÝŒÛàñ<õShP ¬›r?¿¬åxà PQb¦]u ó':Æ?({¬;&þ÷ÿáj¨,âÚžký¹ª—HØ@ðÆû³ãá§Æ!¨UmCuŶÛ6—"Qâ¡?ù|„úÇÜ` È4Ê Jnók:Ê'ÿbôy$ïæ¯²Uk HNoð¥.Pö¸.ìÌá’–;º2Š„WV~›Öj±ÕÉ‹µJç.¿y_ü+ø³sÜÇž=ì›Ù ñy᯵Ú4ÈÊžô<©œ„?»¤ÔøÞ{d„epí¥¤Û0Î’ó@ü|¾ïQó¾Ñ›ópsü½³·×Xôƒ ù"âÅh?Â?VŸCŸÕÇÃÿ~òÿv+I úŠ„“ü·,effúýìxø—NFQñ>ËÆÚ&€Ú§€C3üÞÓx(þû ^wËpÇèòÑ«­Ôm'zé‹O±èÕÙÞôÝê†yœÆ¤È”¤Ø»G?*½?À­]~ÏÓ%‰ìÓ5ï¹úw嫳ð0™º +%:Œ¥Ú*‹\nÔòRéÿÍ›uÍ™ó+T‚œºÜÇZ0_áÙpU§ø¡žÿƒJ¦[ƒÎ&ÍeI9¹b±—NLöWŠžN6>L-³ã움Üz­ Ô=XjÀ’øø?Ê›’íýyÿžø{IZ4<„¿-”^@ªâãÀ†ÎãÉf€ôr‚ñÏž=‡9¥Ÿ?ßPêRõsIDã¯ëøp w8þ/Ÿ¹ªÐÊ  ä›%åpSüÝõP$¾×Œ:¢sK› •>pwØž`ÇpOià ïòÕD®û€ï ÿûÊÿ/Æl¿\³}.Ã8ê_Zˆ˜Ïºãáo×uŠvÊü©ˆ¦ðåy³O;ùÿLðÝJåÁýÿ@^w x*üù—/.) K¶¢ëOàÙšìeo1 RJ"À„–Uz|äˆÖ®Ù/ ¬×W³F‡Âo•Ô@ß8c´XÌch,¨8Dˆgû¿ z•é.ôË«1 ú\šŸPÉÝ:¹²vøŸˆŠ>Æz¸  ÇbêÚ«XÛ«C€Šå BC-Î%¬JvQ ¡¬r༠ÐÖ€ñpç?ûò²UþãûàÿõõxôO ü=S€$öCéd1,vØ P£*9y5€ÖìÍÈFƒw6Ýe.2$SÛ÷ᑬ’ðOøÇÄÿÁ7ñ¯¶ƒ®?¿¼!þ«¯Òàzû3MöC,e›¤e€ÿÊ>ßâŸ÷{,üï/ÿ›«±4âl‰ª!0Ó@õlèΈ˜ê¤S”{àœ‡Ú"nšêa¸Ã»ª#Ôÿñº‹@BÕƒ9ùùï¶!Kn°‹'W×c&ˆçÍOÿà›ª÷Ç[;5ö~1ÿkFΌ梦Á@Ç ÿ–¯‘dc%O/Ûößêüž:Ò2W•ÈÌ2@åƒYÁ6¨üŸ†Æñƒì±aŸ¾Œ=õ‚Q/yÈáAà‚€ä…¶%¬ã(sj°ï­©`ÅNКöIš¹qh·A·Å«|<öB%; €ï°ïþšC§ß³>"þý,µÂU]¨¸ÍÒ4–õ>p̘Wþ_޹@æ¸Æñׯ+ N9mìc+Àž_ÉÜÖCñ^þ2-ˆâÿ³N³Óø?° ~Åkï›à±qžGÕeJªÔ@nW£{ÿC ?¦Õm6Žhê5þ(øßwþ_>ŸðGÑ€hUÌ4"M¬ñn»câ?LCP¡%ëÎû"2øÅG¿Kq¼KÇ?èÿéu{ûÿ¨äç‡ðÕ‹ uødfwÝãá¹LÏÏýàdï“|³©Jv„Öd¾e}Mj¼îˆ…"\?X» ™ wz€+q‘—mÐtùé_•M¿ÃNåy-ÿ›¦z§n®W’_Õc}“1°I¿lštxgñJä´Þ\“âàA%ú 2À÷S~@öþÙÝO¿Òá¾ñl(2Ø06¹ûC ,Wz °3؃Üô,4Ú©p˜ð<ÿ|ùéº*,ž>™ßÿ·%·+2þÚ HMó_ÝÀLôÄ:PKB’Pz{éU-ÛdspÀ`@@t8ý²|ü§vBßE1ȰÈñ(=–\˜{0ËÍ{㿼&!nœ6vUÂ6Sãh–·„ÿ>¹â›vŒ.’mâh$l¡ÖC=ÿïøÿð¿»Äî‘„¿Y9k†õHû%ùߨTòÁ<=&þý:¶aB¾Enx`üwjßÿWLk–õÿA½nŸp(gí>ú$|ñúR~ òüI³|ü‚ž Êã@Íÿî/©÷‡ù´åóƒÓ½öÿ­÷&Oãª.aª­ÝæðŠÅë'ƒöÿòåì± ì’ÐÈ<˜ùÿpüOΧ'»ÕÆ_œü ^¾ž7¬‡b¿W¾ƒ}òz¤á$g-uÓA:¸<Póü\yÖ%Ñt¨ <¨ êò˜Ï´°Ë·N)ëüdØÝ½ü=«NáWŸ]òVgu¦Y~òúmøÿöÅš —mˆž—bl©ÞÏ£€@†ù”h€ÍT2þ¹àŸgK}Ÿ @vXÄçï§A: Ÿ,ø*Ð$€ð×øÿ4©¨Œ% Àº_ÁûjÞÿG<VžX·CÈžðÏÞ_E¥¬¾C=VåºÕc`*š&·ÐVO†Å‡­¿wüÿ<øLø/· ÿŸÀ›×s$üe q/·†2øHøÓ“€+ãgwîñmž Ì,õEç< ¬\xœìÜcfÛ¶'ü´•¶­JÛ¶­JÛÖ“¶•6*mÛ¶]YiÛ}»ß~»ïí«³wÄ9ûDìýÿ¸"Ö§ß3ž±ækN ÀoÿÐÀÙÓÙ?2俹õ¯üãâíû;5Î^agœ%‰ä€*'PJ›Bœ=*s–|3çÎYãŠ8«…]ß&ÉgxÖÃzKåRâ,‰HåÞ €¶s÷q7¦¹fæÓžÓRoRÂa¤•ƒA’Úxn„z›½ÁòÓ23°q—ï£üÒiàôÓ|¨–ï?ífø Õƒé`Éß`ã`IúšÓ>¶½U—a¦C^Ñ…x© …ÛÈU¡æ¤uì­>üpËu|w„ ìÏ AÜAé|Ý9Pb P&¿°£ë  oÂÀº‡rÂÞùck_Tpõ1ÈAª\ ø:=½SÞ…¾®<„€N_@´Û$oÃK›Ê6ýrF*ßByéOµ ÓŠe烿‰ÁÒ8U‘ ð _‚§€z«¦É*ûÑ¥YÒ˜ø\ÿÓmÓRb2ŠØÆKÍ1èíbBÌ9ãõ’ ×ûi¯æÆY~f8hµ¨å%´€†ò2Š<_˜2Hú~ÞñvÂ0àÌúû4˜Ò:ôÍ奆 [¡ûWîQ®Z«ï„zœTi‹zw†Zà ‹炳·<§…¶_Ü„¬‡Ýׇ§tX¸MLÿܾ< ®tÙ˜£}Ü´Xö`õ¥•€Zú\2³l|Gù4a³9‹øÒ„‰ÜÒ´ÊÁv²Æe!§Xýµ/ô—› n§oSµF,fâ†R·š(&0¸ó_1A2Æê–¡Ã(JoãâïÝ<ê\ø¤ˆÃðòÊIá"ë[˜é¹9ÿ>d»¼GU•iÃ0§™!rIÈ9¢b b}.<±_Y~=¤¬!An¦¡mwöØ|c†ô#Û”µ¯3xßÃK›Òóû¢ûÂ`á±%&mƒ%‘¯õ}À, § -J©‘?^vŒñöÔ–Å/÷ŽÓ0'ûø"2ßj"²D ã ¤†Ônk³Îd¦xU—66ØTàpzïTòÆ„R21PZ¾Ó;#ðãÌ Àö%˜IúðoôŸê8ˆÆ"8Ê$ÜÕà}{¸ˆ­kŠõux9)µ3Rvk0:!ËWì0(Gfa¬×;ßßðÓÞï÷ÄF—"Ç^¦9¹ý1…uš»Èkkv+Ì ZG€xës0E Ç6ö‚•ó^ }Ò†÷uR¿®÷㑼K/?põÖâÊùGûÿIêÿhGïJg ÓëÌYŒH´á¿8æ]‰Nž‡­²KìÂPûÎìÛ-6ü‡úÓó'-ñ«sTa>ÒdÜ÷ ¬âl+¾‘a€¨oPb pŽê’^–ièý ƒ#Xaw=?Dñ‚±S€±øï„Ÿ—gP¨ÿÿsÑÇÕ3<,à÷uœ¿ò÷ˆg@Ðﺉ5¹í«' €Ûy†9Ç¡ƒr¥¹P=i¸Òr}X£I€ªÉév…ø»i%¯ÏÑlzƈqöD´, ;α‘Ó-!å_iñ¢ÞI9,ÜáØ§§Jß1¾Þ¦“Q÷œ¤èsÝ~ê~iws"[\APbØ4¦ú*·ƒõ iÀÕ¬sî#€ 1‰Ðtô±qÆökØ£‡fÕEźw­ìôå³³"UØæÕÞ˜ãÑ·l‚0‘êŠÎ!Ø,Š•¾[Ú;T›">o¥-y©ŸæZ7VYõ’E‰êeê\Ú¿ü‹£ùÂs9¤¢Øs5ÊžP;\Óçö-Œ<µÚ#¦kcË}| X8±Øtû¹j¯^ éÌCd›¾áÒ.—4GÁXÅÁˆbƒÃBÜ&x£¸e ˆð)RœI<}`zù¸ÔÕše9-Æš r;rP7V¹Ž:mïÅÖèÂ༱ö„@%¦U>³5ðX—­3Ä{M‰ñ‰õ_° ÚÈ"Xçkœ@à‡éÒ&V:O¦j¯û¦in}¡/º¶’‘VV+ug¾œR’‹#ìÏaä÷Ìê%¿CfqWÈ¡‰òÄ9¢Uñ„ƒE;æ£@i·Ý·oñ'VnšjµHãÍê(6RÜhÍå1sý«ÃG#²À&3~sÀ²‘ÛïÈczA£ŠIm.à@{ ¦G,”F-NÅh„lÄÉôŸ©sûdûüÅÖ)ìB»¿šlñMj¤r®-~yš³F^ëÑAu$•,ª|§Œ-àv 6v¤ŸNì—Än{N$·±› –s½r¨àèÓ’œ‚Nc‹½AÁ¹Å+sÆiÖߪSe®5tšÅ S¶ë3K»L8ɳ1ƒtIÖ•y!°çñ§Òý ·ýF&t}®üéǬá=:¦v72}vÇTÓ°’1¸&À!NûöÿóÔ¿m1a»Ö @-˜RÌ’Ær­Œ´¨a(–²3$Ÿ=©+#EdQЭ_õüõçñ{;5&]u­1†Ù ^eÚ‡C­AH¿.$@hSìè{Aì3ù7œ®ý¨²…ÓÂ>uÄOKá ¶@›9j™˜¿kªÆÇ‚Òö$ufëÃ.Š£foÏLÎãPœðïsí W؇l!ƒd]æ,4‹¦^²¤ó:˜½C0Ž%{°"½šX_ ó\+:ÚÁ«B4W™ŠðIãÊßô[ª%áCdÌ_ n!Wቌ”Ä8€ëî/gŽVžM¡#oËÔHÆúU…Œ+üfAÝ*'™éë¶òIÈzÆ”g×£¯ÕjÒ/Üw|¹ü«,}uK«kõxC–Z-€2m˜™ Zغ õNI®×|%twi. ½8&Èíܲïo®¹eˆÙLÁ1P±fTH‹Ãö'`ÑlG'ß:l45)¹wªY?~GßxàúKS4 ãj§ ÜÁ愪[à§™mÁWh®e‹LkVx% ®áU8xŠVµäÁPBC2ãD£Gs³è²ø,¾$RQ i¥ÑêD{þU×4a™·Ìä}ZÞð8_'!S §Td½Rsu×yGG-·à%gúöE›AüÔ0uýÈ{¸¼¾÷5Ø V³ƒÂBÖÃîÃu~Zõð²¶~¦²õ¼‚±à%=Œ&‰#äg|¿žºM£mÓ5cÓLJp@Ø­â¦Åœ´½xÇ_ …QþÏö,~0¹©¶HÐò£ïêGŸ5f.®©9GÔœ>Ò¤ÝGEQ×­ÕžY½¢Šªzû_€‚°í}Fœ+W§Œkø‹—%•H…£à,eíjÒÙ~ÁwÄ[UWglK\¥õ=BèÌÝ™|©dd¯ŸDM+ÐÄ”gÍêÆÞ“ üÇúÿ™êŸM¬µà¤ÌU†`Ó«8¨\zŽF¶„¤7lèx[Ýóâšôä íõWC›P«‹gëç8´}dÁš^ÜΗš†Ì~zXÁ¨ýuöøéÑì$êTsé?«êyÕÁ Õ3º(kü·4 ¿Ð½¼ôvñŽüwïþÊ/¿ß5à205è˜H›fòR\¶¤ã†Ð8f[¼zDMþlÃ\>éåd#UYÉD¸ÍzT¹0ÜÄ dÓ`ßµÇöý•³KÔ1 'ƒMA†?‚(‡¬9Á‹@(ÐÊæ¹PÌáï#¶È¸Ú÷öÛèü±~± h*"ÍÜ@+ C°¶¤ÝñCKHßMBÞ¶ú-5¦†Á±ßŒ0Á&Ú£luÒåAùoDà{ùËo?9jB»¹z¢ðƒô%À@®SBä4Dœò×ÊßÃÐ)4ÕÂĦaãêˇl¬¦ÐÃ9ÕÞh&ëê ‡]ƒq];‡®‚G™L'®2Ÿt˜&zúÁ)p®3Âîå•*ñÎFxp5R-š—;·ñ²è›½/ ŠVf¦åV¨[¥àDÖÀÊI’¼àèȧ:9:C–a¯bêiÓ÷Fq†ªŽÔ; Ü^0Š,W‹ëþ8¤u÷z˽Ëñ%ÀÓiÝ6§RkÈÊ@öþîblðç.G=9Žùú?¦äe1…ÝX¤ú• ''i¼]*VÄ{ƒ}LW >{ÞçWÛ“à÷ž-Ù¡gr‘q#‡ÐTu£ÞW^-K»Àhh4æ!ÕT•†þ 4¹¼Ñº´×AhŠäÚnG"÷Ü©$2Ên¿*éš­{ÉÂ0^òJƒ¨‘ÏŒÄb“v@Ž»ÊúnÖ&V ì‡f õuá·DfË:ª/çV­æÆÿ?Ö=z8)M`„ßmðÄ dX²ÉëNȱ 7 4TM·Ñ!—ºbCü 8ñOدûFNgÕ2Sö/ïL°¥^iž&@Lïwz„å f»^çr'N;›í‰€ù¶h5“^BfÂ×.K=€îb"{0†C2+5×»úNXsîl‹b{œs`/¨âÄœßÂãº>Ú€v Ûœ6e(v¯ž.åJÁ–PÛ4ÕÀÙ„Ù.à.u9›UyaxmçÐ Ð5í8±ŸWvQi)œb1…ûöîbÃ7¡7ƒ/ò@ÛM8‰ p/À%¼s´ÿïýk”y«»¯âŒyðQa•ŠÜ6X —F¾ÑtÔ½ö¹?ü”tIH)ùàýenȦ<XÖ#¤s»ŒÍC6b#46~®ñ‹¢Y B—=Uf-00ßotÿ‡¨&º½…åså¯ÎÜ~ ¢úGŒ]á§©EGA„4\ƒ°cä™>ñï3ü±þ÷‰‘%;ôS×£ótÍ×UÚm;… —f[vÕŸEg×Ã»îºøÙ1·:â_D£_þÆîâðß÷ûº»Gü¾×ÍåïÀßCbŒÅ©Ÿ2aDSIP>J!UæM·’™mmܦ¥¶¥ÿñÐF²­î¡´>µ1¶M\ì0±¢(Hã8R‘nõç!WÕ!{Ÿr¦SnPº7ã|äÐâpÑ0©æÂ̤l4eÆ/23xtâ¨Å¨Î3žƒnŸd˜c–Ô°‹!kô+u¾µÊ8i°é;÷úÌÚ¤$Å$ín&3+ÇÞ RÀˆ”ä0Ò7C¨«’";á|8o))Àn¶"—ü=©Š‡£DÕÃmeœ˜á¹µÁ¸C‡kS˜KªîñôGIi·Z¯Å[Š(Õ7þ¬­³½È„(m?,ù:Öô3»‚¢`ýF_Äæía¸a J†ƒž¦¿ˆz¢^&”©Ú-{\‰¡¿‡0?-ŸÝž!Wlº—)†Hnûb]ƒäˆÈ¾R›øq;Âìl%±“Ø·O’éu:rª=`&ÒXé··¨+Fb&¼S»…[K@®Mí¹¿ÑÍ1ÛÐÕQ‚ÈFig(ŠeÖ[’1䳩 Ñ`$Žb·ö%4T²gTên¦Q»Dímu7 ã‘aíÂàoq¬·5¥ÞÌNtá/¬ðí°2P„M½ÐÚ¨š ÜwsK<å&|XMnXSËåJ<ì·(ÑÄ ·¨ã%µ©ÂÀÒ0s.u;éæ<ûàãkp? Ó%yâ¨_%N¯Ê›¬G1 :Á1¤›g«WQ?^¼Ï»@}‘×Ü(6±ù·þO3„—É’0yŽØ–7Öɕõ©ÛD@“ÐC²Kãs—G‘Ýá(ãÛ-¥# iû8ðiwx>= ˆÌ9›# ¨‹g¦Û6YV$†¾Xˆ>46U?œ'* è©9cûâöK5çX=rŠ1Í|ެ±"@L¼`HÍ;Ÿh`°T Ë8³[ñ­ý±™j^“¤ŽF‰Ƀ…¦àCƒžö££ž- ¡ÃðrpçžÇÝiµ›íŸxÍFŒ´$î+³y&žØÖÔ8ËMW’ÄÇ9úiA6h©èúÒš,ï·àǶ¿¯_|^|˜wfŸZÔ÷J)=ibøßûÏîZ6%y墮¬\ÚØ6Ù•~ •ÑU–ÅFø†1Ó¦•s€£œ­à¼7e‚¾òêlc[Ë Òpl£~bXŠaÏÚh¨0ù‘»Àr~™º,#çq+[F¥…üÕpgMbµu¬¡ME.ﵯ¶4Ò¡é’HYjË#F_X9”Gz0ÚÜìéÿç«ÿ·/îy¹ø'ÜG ƒâ%‘4œ9ÙÇÆÁÚîÔ&ÇÝxc¬ÿ‹$³TSn¦2¾Í!I}y'Ã\ãqÚÛç|æ(_WºŒxæ‡Ií© Ö”Z FþyÆÀߨ'ü<½‚Cþ÷’ßËÙ/2ä¯åÿ?Y~ßÀÂfý´ÊM€¸%iäÀò}†_!-…‚‘ÐÍ´ÍÖ+ÄÛ&9vzUöÓ–Öõ¶Ž2ÈuV ð„j¥Ü½Å‰1“îܩ݅ àh¬6 Í#“Öˆ"„WÁ«â'÷ÁmÂôBæT³õ\¸×Á™•jžº}gõÂLg|f *±½Ôìç½T±‡ú*{¸â{E«!¡¬ˆkï´Š–X—He~àSe>{SoYp¡ù+ÙÒšë­Ž${mÃþî>û¥œÒ.šÌUÇk'"ßú€ZW©ÿ—‘ 3žÚØ&aûÞe4f·(Æm¦‘ëv€•‘Öšç׸+ßH`:Åo‡7äʶ­'ŠÍ~´)(ƒóÊ .¢„¡ÄÅw.ŒÄ3ûo—BNÄqôö‘²¶måÙÁtâ•`¿9iYܽ)¶à!e/³ïQ•Né×ÉNݯ‹‡eXæ.àœßG¹áC†¤!/7fôeq@ƒQo"‰º•B;"é»ÔFÝ9/è"Ü5_ =S¯ÉZž(jÓñ¬ñødHÀìó ­.¼ˆ×ãÃFuk€¨{ü™\A@n:ïf¯˜;vPè@âein½,øÝÄå'Ïホœ•Aï,#°iFØ UD¡õÀ%ÁÝ]L­É:µe€®È½µû±ç¹W"X;-ŸGÐ6Ál}(Cžï ½N`ŸÚ…A²˜‡EºÇK¬C’Т幭»“ÑïéE›½ÖZXõä95œðÂýœJ+ò¹¸òõ¡03zÌ«Dë'çÚ;ú‰OOŸŸ¿­¡¼É—°ÎñHiñ!Yóú·Dk »3¿T+JÜkd[/Ûuô]oX½hF¾ÃìÉÑŠo×ñ4ü]Í|Ø>p‹ç®5G²ô&btÿ8ÿ?cý7ÔÝ-s!‹¯jÅr­ðI>Áæ»îŒÝ»4«ÛÄÃ8·°wÿÁþÚËŸ‘ààøÈJÈà¦+J,IÇ>giøÅ@¸¡o7`ËvgÙ/ñäM™ý2žÓ—¼f{ñð ý_37Ððÿ`OÀ_ùcóû&_•ž‹0@k˜¥øêÚèhó’¶”x£g‹­¥îsbª-ÒÁòô‘¬}hmñ§fœ-m>¼€uéxWž_þ‚Ï33W_oWöD¯¿]é  :%=Q qäÅ@äøºG3Ä—}á«AZUÚ:ñ¹°‹,å>lWÞµ#éßC*Ó Ñzí:Á¢ùîò]`lv5üˆ»’´ÛÈUµ «>?gƒùÈ< ®Üô©‡•,ø|58P)Ûo‚P«óœQ":WÍIúñ/ãùt[ÀßzÇÙ æW á3jÊÐ웬¼Ò‡‹Â5µ'Ì,®ôf öž ÒM]òç§¿‰Sš¡¾CªæPx Â6bKDP×ý¬½ˆ?6üÅ×S½¤ú³þ±UDî_Ö0¹‚tÎwfÒ€æ*Eéœ ˆ:a!±óØ@¾ò@“¯Ú9Átlk!ûž¡ËΕGâJ†ó\?a¥lVúĪ?›!Ý ‚cpë3BŠ:i¯\„´Ä@Ó%qã‚•¢Sn¨†:-¥|™J‘ùW²ëº¾.OÎGžP•QzP¼"øvLK|Ì ˜æ/  ÑÁÀ!%°²ë“î8¨@«(žW°ÇY²u’ˆ+ù®–;ÒŒ!u‘*Oé·Ÿ}6Î1ÑëDm[:çKië~ûee·˜œªcš²èz6æ×5Øà“rûjàÛÎR²ân|Ü»üûuêvbï:L/t ' ‚\)òº.\ÐÿïŸcušHBæo®‰$ÿ¡›ÜN†‹ñºKýí~¡íÊýC2դ׿.<¿±¸z®!‚”˜Í÷ò›|’ï.µ#Ùî…yº%‚ãëwÞä1 "v æpÉϽ5Á½FXÂoœðÊãšo঴xÅ)ØÓyïÏR^¼¥_7{éyžU Á× %¸>Fq0õ£#L§f¯#àS3«¸™d}$å+7QŒï†#ÝŸ&ÝGCÐ"²;Bq…ÄT•G(ß>¬TCGã+Ö²ƒÞŒÖ ÙSx”\«Ú/Ѧim¨o¶ñ|Ñùã|?æ+ì÷?Wtu¼=Ìÿ¥Þ÷ìšÈY¼ÉÄÞqéÒˆ7Äž” ¬pn¼?-\°Ë{Ã+÷hÞKýu¼Ûi¦˜ˆ>ÿcé‘CDØLnÊv…„ÅÑ×IJ¶µ:I.SIe燌×TyàñÔI¶–Οƒá‘OQ¨cA\hÖb•Ç€—R#VÒ Ðù½gq3(0· Õƒ˜ÿŸ³þ „Õ²cZñ7Ð5Æ…£‹¬€HñõžÐásõR¨Í“‰Àðþ`W¶–§…qülÞ"ºoªŒ»·Ë#ƒAx#É °©xÅÉÓÃSد(ñ…g›¯7ª¿¡Uø¸Â~ž.þQ}ü÷O˜ß3(Q~hù¢rÔñCµ‘ݯ(°Ž©K@ún™Ì;‰‚…Š~Ûað³kué!Óî• ‹ ¨}':­2„‹n’ØÛ8c coî%†ç±þ;¥î}$…T“”'„}¤R~ÅÆ"=#{psuìr)L—ŒŠ¿¹cÎI¼4sj©Ël¹ÆÛ:[¡ë1jG›¢œ¦ø!ALsèö:åØõ-‹c¿érmaïéò3°G¥"E>s ¢Ñ¶ÓÞÕJ ºmeSKbOå€H ó¯gB<„x—Õuï&HÔ•ê-;¡ºïç5y7|ÛB°½]oÝ6‹0UœjÑÄÇ–û‡‡@*±‘·=¹4HƒMZÛ¹ÙÝè J:¾¢}\³Ÿ¯ô¶m^‹ÈûWü^Õ•JGdž»©_bKÙÍ?ûyC–ŸËµH8»_[`é4÷©UdçHü;Ó!Ѓ®ë)5•Ò.8×Í8ê²Í Ëß©Ô<"ƒëpÛËVobr¤æ0' Ï?äX UÕÝ”RXh 8 )ËcåàÞý}šÚgG¡^” ^ ³A=„)³Ÿ=……¢f[»mwËeùL—ºôi Ûæî¡Pc÷ü0Íó;ŽMn6‚¯<ã÷ž‚˜P„æ±4 Ò^²Ô/O§waõßWÄÍ(é3l…Ž÷”öx´ó Ñ—8ù?ÿ·ÿ÷F ö9é’é¬ïO9ÄŒø~üoµ>ëÀâ·ˆ§#È5d=ˆýs­;t©TgÌݹÅäàDn), .Q•á}Ë„öJG{¼Dª5µ´°á,ÕN`壒 Jen‰é¬€ô (òóÁ¡òO¦£N&T]gEnÅ ¾È<ÛRÊ[3‚mù†q·n¼lÍö¥-^«:q·Ìq®ñ¸S²¤4Šë¦û(‘X›æÛúPßEGÑì[–š¸[—ŠŠ}rчÈbÖÜÆ¯ô{¦{_Ž"k R¯Ê ëøÉ šÌ°qI‘½)æ ùú!Øb1 53þÿ•?[öb üñZzžj7(PD»GœÛ‚ Ä@ê¸÷eN~eàÎ=¼>DšñÁz=R¸YøŽ!q–&¥È@H€ÿ{DæiƒíÔa¼^/g†È›7vbð÷5s ¬„©ja§/”£ÊßçÞÜžÞÕÎëÔÔÅ× 3–‚ŶGêÖ]éÿQþÖúwbÓ»QùêlX,Vq}~nHç£;p¼Ñ‚,eﻚ¡úûó[¡7§KÕëY¡?Ö(9# ¤}zZëÓSB(bý|T8@€ï9Lþ0¡Öq j; âO¦þ›º…—G`¨¯«×_{ÿþ)ãëõÛ§2qÄÌ8+úè®>[‡lëtW¦u4I;–G²0dÉÔ5E½× JoæÑ ÷Î-jù$˜F}“¼Dõ-ºð H¶É³Â§‚.ÄBª} ·g Ð’——§í¬Èwí‚So69O¦ÖƒÏ4‘í]ûâ quü<œfÇ#êï†Î •CgÏ4”ðSÂH—ŠûaB•Õ¸å‹<#Õ×.øB”v¦]"µÖ™“‰˜.@È7bŸØ”{¼<Èg+ð(ױ߾JÀEv•q‰éE<'M©WžXnP]r†°R='Ó6àN¿.`µUºt“‰5ÝPe¼'ÙäÙX “ú…c"pxŠx‹b…®Â^w‘FóZƒºÐä¬ÒjvNk(ßãDœ"Çà ÈŠe3m3‹y0ýúQGDCÇ_}EìOÖ¬¨x3¿U ½2ÅG‹Í·wušB„³& ñ Uô'– èNº!!ž&^ŠŸÆû¦å¯><é‰owZ6fMxf‚Ó8+û>ðÇšm}!e&µ;iHÍÕ²ömÊíjÄT.Õ½™DCš+Á!'h¼>ÈcŽ Ñ(½Ôª˜Qì£v‘ŒÈ]<Ä+iõæC-,§þÁPÔoL´=°ßòzc%äB&r4…Dw¨’í›×d1 ³ }䯜lÌ¥Ž6ÈfQ|pI;¨WU€¾ËAƇ+žÉ‰CÞ1>*ä€vE< ;Þ08¼ÓQýO˜=ŸÇyÙM¥dÓFéæ\]ü­¥Äȸh”I/"¯]a©NHûÊ7i·Y+_F–£—cšo?9-h ›b¨}‰CR;£·-\YÍÀ­K¼hî×­°@x~}CBÀ“Þ™åîc(Åš%,Õ{2¸š]Ð=—Ñ‹²ÉoÂã›._ÉpþÒ0*€Òêx$“·ä‘mS\ÓÃEÜ$Š‘àÁõ:í½¡HT }ãÂz!÷Tµ<[0à[Þntâ@õaÏþ.ôÝÿâjsî&±¼ÑmRrŽ8¦©ó0c¸6ø,­[4Jô›ò´…áªÇéâkÜ-ÿõå—}bÆo¢c望ÿ¿Rsœ¤%(XÓ#¼é–ˆ¢5,NH=t‘¤›ƒ«ÂfÉ`ºLÔiš:Ö±Þ lB0*äy8ÁN똻:®`uhò¦×°]ÛW<€PÜJÝçE¨ãgÒ†j&Mìù ¢”b¤¹ÊCt]$˜ ­V<ÏÝ(1为¦u$\¯|#–W8?ïÓbÑ+>a‰Ç[S: k¿ÿÑþP.°‚dÈœ”ÂËæ·ÁýòÖQ9­Rm÷éx4ÁÀÍ|˜_ýÕ¹-p)GûêgB“?ø#¹~[»ðóôôó Œúëã¿ÊüŽ €™a2%j¸«¶¸Æ™iczt2($shg¼S:JˆÍàöF19õÄ gOÝ–‚€_stžÿrKN¼;&c7À à,ªB|çRÁ ðÓ³¤'ξ@·!I&ÝìÐ ]Í(픸í¥}bÍB…xjŠ0«š6Yn~£;Ùg?È‘vìKŽ.4é»*Â¥góäí`M›öÚ;|‹R+Šô–œÁòyê+D]?f vL¶éª¯ªÍÒé«4Î×4Ìm„ t–•/ÈV…¥RÅÐTf=‰Yº9;×ýf7*Å„6hÐ>Œ>ÕùáúÙíIZä™)òÛ Ðx™ÍKêº{^٬Τå?.¯‹œYæ:”“Àz¿i×­ìUKò=©·Ï %æÉ¨R=pº¶ÏTl1ÜÅ9az˜FDÏHb,ùºø] k"±)Äx×jn•ø~Ëë<­Lº®ËB³eÌYto3ÊpýË„d³LÞãÅ)'“·?êã.'ZãÌÕ‚V«óè•Z_JÝšf¤tàèc{©ð‰èéÞ7;”¡!‚0}"÷±*™Ý‰9ÂPZgšLPN’*ö-èŠ,8/kùÁý}¹–—Þã9ÉÔÿ¤Å€™29ð ãÈ ßŸâÜ£@2Œk}*P` ?Ó&h¾MïpGC`çÎ[ZÆ’vüZ²§w¾Âº½ðºœ«›M§oþK;Ø3Ï»°ºÐ$Z&Îf¬êCÞ‰+ý†F{EHÁ÷‚ FÄnMJT*_P½ý^rƒ,R¯j9ym˜É¢±5qKsBÚ°2“îcæZXˆÛX!wÓêÝUù3íÖ VèÎúüZ-6Ô9ݼ¿ÍžÄû¶kÞ-Ž(òGlž 7N)o&UÁ0ü~(#ÁÈgâÔ¼mn©!u¢;¶‹üÒ«£ga ËÅeiM(“5¿’½a•\ÉÏë±ÍÿÔ[âNJ§³+¾ÀC{LO}µÎBBŒÍš±8KëŒ&{ØœãŠ×OBXv­“+Âì!\¦…çüð^‡6Ðe%5¥#ã îŽNÎÖ¡¢§W< €N=œÓ+wˆ\UN¸ª-@XJeÌ®Ê;=U<í÷˜Åõ²™¼ýah‡óyP]û=ïþãÿg®`¯˜Ã²ÒÓ_ñ"¯h)-’]Õc¢ 1Òb£áÁ´Y10Úüµ£b¡qQݲÄ>Nx`Ð,ŒÛÔ¨' ®êœú» ‡àÒ%ì÷«Ò›Ø‘3‚ßÚ0<í¼c#þZþÿsæ·O*tÔPB¦Ó ˲Lh³(~«7²óîöÑ?¤N €e¯Ó(&^çX¶»=d…–ƪâ‹Í™¯%£Â6NÈâuiøÏ€À "ò~ð¾M]õèDá_Tü^Eð© žG5ký áHÄ úƦ$‡;jPKoAÔƒÏQÂwÉæ!ê²ÔÞÏɆ/f;¯’ðª×VóÉýKmÙ…¡,cÂã*:'C-¾rœsð~{+ô(þòûlÎyÆýXŽûüGŽÉwŠÜäßß½Ág¡FFWj-{a¾]-⺼?ž!&¨¹½¿5&3>_,”2Μ¾‡ûF¯"QÕãXú÷$'ýлTý,w’c}¶nºòB ‘ûê4Ÿßpg¸~VZ¨5>y7ëTÃ&©‚±Ó<)ò6:Íù²5e“býzDžoDs…+Šƒ¹î]©G?ˆJ´~sºn1qðÈZ-|¦™î$1»˜Ðið¬>>¢8~bÌËì.Ö<£%b$îOåól8áá¸Ùê+#™MŸ|07Ô”j^´ŠºxB·:߯ƒ.H8É£†Õ67Ÿö1ÆÙì2b6#íÿåx†Zÿ01ìF$ÃN§`+›I*c.›¡!Q¡HG̵±ÞÓ¤´-•†GhžF*ÿØßÝz–7\¢NQ¯A]¬7Y(Ê­ÎÌCºÕ^÷ööÁÝ5¨3å—þgMÑþs$= ü<=€ª ù_üÛÕŠ5‡L¦q.Ì;±Îq˲SÔˆNíà ®¥p*î´ bo8L“Ðü®0zë MÜü-¾½i{´¯ÒJ!ÈoQò¡ž+D?¥ ÉË£Ev²y[âÉ™\à‹ùÒµ´Vê¿J‘YÎzýú4õ!ˆü$ìý8?r då7Zì–@×ÒHÑ)eYežLBšÑ ÎËÌœù¸ÊŠ\÷ö¤ºixmÓ -ä|'ÌæRl­¨»{z#)„ wC%à™öÅ‘!¼.×`GwÔzQø7€¯hÜ–¶9S“þÃ¥sæ¸ÙRõ#˜OYKÒâmB‚ |Ôdx>sïþ€â¸²ìÛæ?ðx…{œ9u“,­Ï/^×4H$áÔ£ªÙðú$Náŵ «ÙíB0*bRqšÕ¹6´ž'ÿÇ8Ô€¿Û-EÅôûv Âýl¼R¸4õ¦caQ”ÝiÝûî"iþÊÒdÙÐkð <~íææu(=P® ›gÙ¨#žÁLo„iõî=¶n¯ZÇ?ÄÿÏ]ÿ’Ÿ!9ŸñðZ¤'J…NÙ‚Í?Òeo¢‡þpÿO|oôÈ#ž™.âê'Ò|ðz “Lš^~ëõ p¹Ñã’K8sɾ'Ú6ZŸ]W=ÓX¦®ßØ/|ÿåwø üWþøüö €ê'lÞePhI߃^aÚ-§ínå j¬õÞU7Á·J6|Þ«(ND²n‹)•öÀÙ{…Á<ªq–‡+ö®Hǵµõ²#fRÁ¡èlÙ l2–aç’Ÿ5Ð'€ß•¦Ò`³t¾ÒmÒwÜñQÆv­A–ãmE`Õ|Ó×Äã8›é°ƒÿ¨wñ)|£H M†¶I§žBOØ¯Ô xŽÑÃ×gp?(5_K<â´`щoñ­ïBM±ÿNÑ3Ý(rÏM {½Næ=¢¡qÀ‹ÿõ¶@(…ø Á´Þïê¬q룡™Ì‘å‡ôçWî[6¨÷ó¡±[ó«¦s^0s¼Uøí ¢¸ˆ&?¶Ï:°ä< .1Ô Ù'·]44æ EjB5r¤\$¶Výú€ƒÊ®²È€“!{ò¹Kí,lû ±PLJ.;ëŠ^Jë÷Eéž×¢j¬çÇ›®'˜uŠd‰%Eÿ?¢þGG¡XÇ÷Ûª¢’2ˆÄŸt8mµ†ùØ.XhßK=ž _•v¸'°PÜ}.K+$+0qÄ/`›byi7%‘á&-ùd Ǫ¥é ¨¥ôÁõEºwTðJAsgSvCÂ2ÕSASñš]§Z¨kGñÜtù“år¸E µ¦Ë:c^”<[Ë*L®±ã±•4¿ðå8æŸ}Ét”póŸÓäóAK«f[Îú­h¾ÝÐ\g rÞ?3ùt€ÿ§ÿ‡PO âH†ì€`UŽgµ>Ô;Wm'žgi‰­­jÓ-”j(LdÐþŒÃÑÂ)È™œ²V®wýLÝo‘4Ðòh¸>ÈD>”§Á<áS—L‡*L'H"Ñ.Ó•ä•-©~mâ%ÁãÚ†g-Aœ~‘ä3#K7}MÒ‚—¸¨"wÂ_ávnÌxüë ü׿cÖ‰y t°ÛOË DÔ£ªîÇÙ—øxÇr ú¦Îí~Ï7›­z‚¨n)u$÷Ž”gú%µ‹?—+]Â¥”z shºHô ZÿOü•/‰&2Á}\ YÂN¯V“S(¸šé™„^.ØäÂ4‚˜©gŽƒ`UÃizh‡« ¼WIÒNµˆ²Lž«H£ U¥zö— ¿`ô¿ÃÂŽ¢¤…Ö7£sl ”Ô‘˜Åø«†ßCæ$HÁ…ƒ•~‰à£–/¼ÎM…¤•áxð-|ª5MøûûÇxwýÉë?Á9*Uø¬VPXÚÁŨq¢xºËQú÷7I G'Ÿ… YæÜË©âÜeã7l^f(‚;í› œí__U^6º¾ :‡ÄüÂõᜠ·ü7œÿ÷oâéâìåö×þ¿Æüæ €3âõDÙfv—äO&ùFÕÀ™£ûÜ«äàé)…t~çK°|O‰pd™*>À¦%XxÒ+‚r\®îψ×Þe—ªe’ X¼ÕÁ)œ`õP®³yµöÐMSY4)˜WâU` ذ"µ.ùH ¬¯5½Ð¶Y©`V NU]‹ˆT´ŸG>nC¦GÄ(L!ßÝð²E7E5®„ˆŽéˆ¹Tîý€3“£ ozAfúaŸž@9iu¿ƒþ”†M4¿#ŒªÛ%²"S‚—Ykͤi4f¤ÖN´cPkˆ°Øç¹Äóàú&æÄïGdúèÉÿ­)%SŸ«%¥ÐAŽ߯R"8¥4¶ðù§@Ö'\º¸L7¾ÙOAnTŒÌ®UõçúŒ[ ;¥´†n¿¾9Ó¯Ÿ’8nèši{áá›÷ÌüÚuÒpw²pºŽø¥_\®@® ?Ûáø²^¹s=)¨3=è½+Ž5ƒ¾$m‡åuQÌfÈ”e‚ßbøhµ| «Ê È‘3xpÒ¦¢%¥Ý®DÐú ]êX¬-U ´]ÌÔä%_µ"Ϟʙ¡ïSÉšã5ïb€Ù 4ŠlšÈ4¿ŽÂ—kZ¨™ÕöíûÿÌ×ÂH‚±yÎóñìÝÒäÕ+=f=XÍ™óâVKMb—‰m¯n’Áë+Ô¤Œî©UçV"*\>«¨|׸›Å 5òEÃmÓˆ"í3h0eà6,â–Ýk§`§8¶=PÂüþ/|þþ·ÓÇWYq5M!áã:oŒIâ1âŒçKúY8Á÷—.ÝÒo*ÇÓf´6®O™:½úipÔKU³ªQ‚†6`ôé5ÂŒîÆ9ª7ûõγˆ*§Ôä%}°ÁŽ%{û? Ó™³¼´©*°óüë'L.ĀͳÌÇáÊ'–£4÷P;’ÀdzOjnÊg¿+,7è÷õOÒ/ˆõNý²2QEµËs ›,¥É3'#$¬”‰¨m(v˜SÁé„jjÅšN¸}¥g÷9-X]v™q»Pˆ’gÀ…ò¨ã^bOÅ0ã²Éc3]m ¨drݨl%ãIð¼ Îiûý‘WÌnÛÊÎÉrü?‹iÂöɯø{a[ 3ó.A:¸4‹¼ÍŽÆ§ ñIZ{ÍâB\žEÊ*z÷¹+3œ]õË\‰„lvqh¢¿`8@¥Ü™·9QË›Û ÒHÓìM9­å÷TL9ñ@ëöåZÙ Œ”Ì@X»9dÍ6×U–åþýý´øŠwÿÜõ?VôJÇÓUy EmâÞÂpQF "ÏûÃýk É# ”Z\Jí/ÈXaD†ÅÅ‚k|`™‹‘ó!ˆÓOWû®P®†Å-‰Âs¼–þ¶váãêø¿Žþë àŸ0¿uÀËuó´?·"“ám~´"Ññ kí"ÓÄ *Þ2e hÖö;øÕæXö༣pvÔ.L¦!úÙúÈ¿<Ê:\ÊQÚ?IØ››òK~"& _x]•z\‚P°Môí®Ô%esÔ¥5TÕlR»ÓŸÒÌ&ÉKyN½ÆŠì_ÎGÈÖ’4Z5:ŸÃ§¹Æ¢[näýj²~RøNZ-þs¾?í¬‰qƒÝK¡`]u;  rµ¹™ü´9¾5 7ÝÒì¾Þ9*жJ‡aÜ[i#ôÕ«Š5è™l$ ×÷¹ƒ${| ²ÔÁîä|0]~{þ Ó«¤¶mIÞeÒ)¬tH\ð'~²câvbî‘ß±u/̧f õÞ!ÀÚ÷ ÷-®Eâ2#Öžsï ®Tƒ B“)6"úð-Õ}ÔªCBH 1‚qí+!ÚI×"¿K©nçûÞ:°¯OZ”2Rn¿3•®Äî[io+ï µ¿ Îf@ÉÝÙ†¼V„:µÁyë¶sß[,šÖË-plªHÝ¿K„¥¿åš²D“‹N«o'Nî°S†d*ŸÑ Kj¸ì餢#pöb{‡ÃÜùÛ,é3ð‰£÷©ÌÉïHê??A">:DIÆöœ-f Í”سdÆ Ç3<‚hÁ>q¤žš¢{&@N=L-3gfÁöÝlüš bk· • ÎE£éNŠq%a7‡.ñ‡±pœ\¦Ðà6ú?þ¢÷© rgÖ­ˆý…º·½OÌyLDƒ™ØQ^Q A]&¬˜àQ‘œ1³ºŠ“†«k<~É`ˇé®k>Òi¸¼Í…t"²Ï~9P ®åÍBêþ5JV0ôa9Ü/ï©ãXLè(~ç<›ŸMtÞÄÌßb»,í =)~²vø—RŒ*ÄUk§–lZñØ–¬]Ö)B0;ÄN¤}E±´®Òˆ9+‹p¼¬ü“OúÅ~쇣ÐÇ-%.ò×{·¡=“Ñöƒ0/nûÔn}yó¿Pzž³ðŒƒ=‚q®«²E¬ûX·9üsíbtÆ3‹v»q†h“O!𶨠¸ÅÍy¾Œ°'ýþ"b-@˜Oq. {%£p~r  4¸4”!¯]#!¨ˆßô;¤HD– `¤ÎòÝæ$|ù DÓ½%Œ|ÈC =®®‰•ØÉWÄÖ$yL1ûS‚~„c]'ÏCLÇ¢X*ØâzÀ£‡Â¢€ÓK‹ý*ˆeÌòcáÉŸç»ü{ûïÛx9™f¨þ¹ëß «º#_våðjð$`/1àƒdúãým&wÒt÷HàÛñ¯çÇ5¹q“çq÷—Êë.ý®ÓNqk*ok';‡ð1´ÜÓ¿©[üß½¾îÿöHà¿òÏ‘ß:ø•–>-É.Ü*Eз q \Ñ2ª*ÿ“"˜9ˆ _ëL9$¤õà'#p:ì$î =#4Ù:u~6SÅ¥žóþMÂCî©IJá1@ˆ¬vë4(ZvZ4€Øm÷m¿ð˜m8T…'÷6÷º2XR™Òõ£Íh¨ñ4–RÚ‹‰jÕ¥MB?V„v7úoê$sfr‚ÅF@}%ÒÅÒ1ì»R‡%–LJkÖùÄ5q­z_£g™á]qög­OæGÆXLÑ]^w—ëj¤¦ŸŽ¿‰¥fä˜EŒ|*þŽÂ¹kD³óNø‘‹C€ŠÀÚªK5%Œ~ËH:žDÂgˆ8J½Ã‡wìV¦·ëb…¬¨ëàqkNPÔv,ŽföhܫᒟH‡ 5\„ÎTæ'ÃÊš±Á÷<"ÒFøšsÚ{‚í@Êv¥aÜðÁpÐå_tŠT¡%oè°§²ÏI†%Gâ4…ËzìÞµ¾É@Î)è«©z pYÃzWÞÈv(}Z¥Dg˜A._¿Þ÷L›&2ž‰-ñ+ËÄ :¨t”Ç_?óÑ•/Ã&ƒ‰ªOÀ°VPˆæ¸NÕºÎHÂ=Tñ%ø*C`äâ-ª*¸;ðÅi“–·BûÁ• aéÑ«ËCy„dèu…çu’þQ âÔe|[ÎdÍo1QU÷»û*xYæº`ùjS³2È‘¦@œ2+»¿#¬J+,cè×(l†Iã’2zm_Sµ*R×÷¦‘†S¼Ù…®K‹M—“‡å5ÝãÁUµ¥óÿ½IvÏ,âóÖvöf»É@ø_wó©Píib— •ééCÕ'”‹ìÈ#ålÿÖ1H¬ñGA-\©Bålî ûð„ñ.äl"9W_G†E!ÔFº¥ê{þÅΆ_Åg†@à~JÔÜÍ£†P‹3È”*{ ¬ðÜS#BÑÖ¹^7L8/*ÿ–_îûpWgÿJÄiÝÙp 1´?wý'V#´XSC§ðÁ¸*É‹îòd7ýñþîS:i¼Õb»å3„9êþø›Ï=óˆ`™ä DàvX“”h¶ÀlþrQ)$Iãü Y´¿©»x»xÿŸ½Þþmüç‹'à7Mhe—M™‘–'^¹»¤ÑÇ‚§Yx?`Èô[1£-{©6­•6I¡½xÚ\Åm€CPqöS$¾:bôŸ $Yhþ0š lºwê Ö|¢¯=n]-yHÀO"ƒ ê„"Ì–GV?Íét¹lS’6’J«‡ Ç¥â+Á[ÑíÕÄiÏ\£]bJ·ž'~¬ƒ“±ZôÝëZ«Ï)˜ç£ŸŒ@‚Ð:Qx¶0cN“NÓÞàÌ*î>°XG\ÜŸ+$âxEíÚ9¬¾0l“ƒ¡¨5àMI‡,Þ–jY£€5V”ƒ°WØi<—˜^8«Òfpª¢|MT¹ý ˆQ…§ {þˆ­?Aåà%‹áIKÿŽÉT‰\X¦;òÔ€M$Q…šÓFÜ9’ºê(BFë£#Á<\ÈGo?¸' ‘ƒ§ímw0Iš ¨ó«®¡tcÌ2üboÀծĨ•ø=y/¯'¶A$(7ÌU{)fi7³W" WþâF‰ç»ê¹’U¢`U…ié¨ÿfq¹Ñ®³WšÓ7ÚÕÚgïj¢‹…ÛŒp7ÝkÝÌÃ8ú‡ÁO&A»J.lÿzôzÆúŸ, äQ!Ñ»$Є#Ò›FŸåº4£(ÆÅŸêœ‡Žé%ᄆ±«Ñªîb’@êFìöMûJßV ÄígW_ ’$Òe÷ú:½#±Ï'J,éâ!ÜÙ·ˆœ^šôZŠ1B³ÇoUþÔVvé¦ãzo•D˜žð&—B /µN¡Æ›­Æ(È“` ìèc`z/×)êÿ™¡’$Nu¡3¢–ñŲu2ñ‹ZÖ@næ)”ë[üAš{Ý¡­Àò<íW r‰ü“ïel(àA¼­°»ÑÖΟ–ñ¤ÐžåW´žãƒ? ¨“öv_†kÂ:™‚©<'û/¥ÚÐñjçðÚ}øjȱ“rácãÒ‹  oÎâåôö3 }zëU3£.QP^oúÝÛQÛ1óÄ}•­“…àЃfëAT-Ð"8©ÿ£½+ õ,¹êFÉ゘H JB4A#("³23™53™î™ÎLïoû/÷Þª:Uwù/oÞ¦—éžž¤'3“Nfb b6Á˜!BD‚`4¢‚Å`ò!Äjsj»÷ý{zî÷à½ÛýîÿîKýêìçÔ}á»ßúá½óþßíoüûü÷¾üãÖ_þâþáµ_øãgÞùýw½ã›Ï¿qþ¯ú܉§ÿz<ýÓýŸ¯ûÍ7¯|ý»ã¯}õâ½åßÿÌ}¬ú›éÂO¼íso=ú³?«ôžüù_þÁ[¿x׫¾6yô-k‹û¾þìÿþåë¾þm?ùwïͳ³öÓÿö‹ÿùò—^ý OþðÏþÕ^ýžOüóÇÎ]üöžýÖ÷ýÒ;Þõý¼}é§þöútî_/¼ùîéwëò>öÙúÃwÿÇÜZü/®üÁ{ôãßZÑÅ_¼¼³éÿÏÿû×û¿6÷«/þî={ÞŸ_þ^ý…½§~¼õøÿöÃò™¯<÷ßüÊÿê¾ßyÍï}ýÍ÷ßqú«õ·ß÷ìžúÉwνéK¿òúŸû—w¿ý5¿ó†·|ëóÏ}ïòAÙ¿åU6ïN[4©›ECIe@æ‹÷¿8.µ¥E¿º¨Ñ›;aÕ<¥5ßC‚ÝS<ö(À'Ç•Nî•Ð¥ŽëíÝ~]š¸¦Ä‘Õªò§´OlmSÉ\JY»S}Òø“sÚ3QT¥;¿W×þî~¦4þsG»*ï«lTyàËöEÑîøôVGÖGxlÍ”@KL%¸ÛŠVï"±MiÑî–…†Ê.ÒF©y o ð³Óy~QhDC(º"o+òºÓ¨äå,‚kíŸ]yÕŸÁâÿÀê3cN냲qð@Ñ[º þŸžTÆ‚­€öb?ÂUû:@øKUÒÅ¥=ÉîÆûSÛ»ãª4ôàÜHâÈZi/fOÁþG÷² ù5hîŽæV¡©Ûêݮ㽠Ýϸu ¥Büñ{¥¦æ£%¿ $Œm±o¤eÞ«¯ÿ•†:Œ&ü}Š=¹Ð%Äþå€q‹Œ·?þ:íónÁö ¿4$ uÛñß)ô¿R-þ¶}>9µ7,rÛÙ4÷ü%bÆÖ<2ÞRüË:ðž)&™tñç¾®×_Sl Û$\fnܶpºY@`gȇV±‡¯Lo‹ËµvÄnyC±ÖhÍý•û[ÿƒ—WøsR·èœÖeQš[D9ƒºe.ÆP˜Ê+õ&’O‰&ŽB’Bªé5‘x:¤ß%ñå,îè—µNvúëžVT>ÐËù¡Çà©3 &‘™†®¡â›ØÕ~9Ö,Ÿì9öe ²¤#³†…=rH+šŽXS8E–¸(Ÿ¥;Qhq™Ð6=) `Œ[õÙÿð>»øÌ ×õ*%–kÏM-þ0 ÿVjì-Rjfƒ^Σ`GüQÎã£:5€ÞÔ©¸Ê»•,þeé.a™^r ðû‘öÀJƒ,Y°øã‘–—7¥vÍÆý‹^ߺ"nT¹®4]ŒñmKíe?w4‚£òžº.üÕÄsw‹Y&»é¿ÊšŽ´I¨Àâo›Lwz«½¬ ÓKZ€¶* ™Õ·ÿCÿÃÊâÿœ?Sc×6bPþZ«ï–˜í#÷ó-Å?—Þð׋xpEÔ L2öá™\®Ãƒ¿ÙÖßÿÛnR7 HFà €‹“ÕÆ _¶ý:›ÛÀ(ö-»>W‡ ´ÉZö0™4ž’°†Îáº=—9f;Ê…åj‡H'™Y=9 ô«:¥ö@ò-Úç?±¤ôÃ}¸tÜqUä£2eþ´˜g«Æ ËZ Y9‹É™ûZg–ód$ÝYè8›V kœJQ–~#8™dMýT‹'ûÁ.I4m‘ÄQà½rÐ蓈޽<ËP+¯µI€ˆÕðAûXç¦+kyÈŽm4Á„³ø7ãÿÒ%) YIv:ÚîQ°‹¢dÎE†FGî“–`‚Ò`ñÇO‹ +°ÿÙçVÎBqæ¿Ó’üµeÐþó+•óCðNª;? ÏÐm@lË) ƒªvÍŠÍD—%ºV\SãѬ€\̯ÿÞªqkö¿Åß8¾ë{dV_Åú#ÿ´¯òm’Mº´áþ/Œq‹|t{ñßIô_êGæáòñÊyõ²b̺ª÷aŸË¶9ö® o%0÷N²+$j€q÷u ®°+ÿ·ßt“€Ã ³lpàÌêʘÍ&k±ÉÞÒñÚ™[ÈðONK߇äâ]ÏO+²¼Ñª )Ø£u5õŸWél%Ž=Iw*”'èpˆ«ÎeQâÿW!¬N@™#Ÿé—M—9êõdêB–Ö>zê‚qëÖÚöîÊØêòð)oó“ dIÚ°œG-ÛŠ'©ª`’:à-}tß[ã¤Ô.&,Èì¶*Qü"Æ%)KÖç!Ï»9²¥Ü{èÀÀPÕ0-??iñ‚Aö7‘·[üÏtð¿2­¼¦­d}GÁBèÊKW/|¼àd8MJâo¥½°Æ;êQš“^ä ¥£K %Ý¥ üKöÖƒ³ô!øÿÑëtE?Sh*kÕC#Žœ¤´á¥QU ´.Köb¸`ÿ]ÿ'gìÃ?2m«Ê©ªÃÉ“½^êÑåSì?QBÚ?ÝL:¶ø;su[ñßyôá\ Æ…Œ†·–Šãx¶UöŸÜZü£CËÍí´×5±  +]ÛÿïáKþ®øßŽÓÍ)Gû âèòâ¹âd¹LádÛ·PšÌë5ìc(\8 `áɱa—Rö>{Þ§Æ›ÕÿÀ¯i]’¬ÃÚëNýÏ䘽Üsmõ†IàiÇ2 Ó_63I¹@›Î…UΦåÿKUþöŠŠ¢z?ÀÓgM:0cðÀâOvgÍj(DS’Ä?ƒ ðÂß9Tx©î£ûÌ€ðOüÿÊØ ]´À­#þ{®¿˜êÀüYΊÓÅ9f€¶;q앪¨™±wÃÀ Z`ž008 ÄÞ-onþ;þO^‘«.â/qEûŸáp‹ñ—V%MÌý$ÉÏ«Åàb’}þÿ±ö »âûM7çPrE72õ.¯•CkÔŽiãdé~xt¼j{éðV^¥TŠ]Bùp¡ì×5˜¦njR}U!ëÎq-6À)»ÅÜ“eÜXˆÚt¼:Ày–W•·4. Úëí™Z*C¼,%û6í»Ýr8Z¼ޝ/ª°S äóiLxØ¢·Q:w ÆùQ¶i|ï0RÔ ‚×ßGœ.@sä~% ø (ÃsG5@©2z„DÞ­2Ñ­ü”0KŸÁ´=—"ÄÚ~\Ä£n&†Ç–=þ—/‹I@[Í¥.ê¡Å_7þŠ8ãïâtÕl=ñÂâ¯Bt¿(,ÆúÀº€‹(8]#ÆŸÜ29PH=œÕRûÿàÿçvÞ€XÀW”Ãfé.8½>zeüç7LdþÜ›¸3»žìðït67Ïë7 ³ª忣­¶WúË‚Ç?ßTù{Ëðß™ô¿ÞÔAST}9Ãxî¥Å‘­ÆŸ}–›p“B  ¥ØÀõO1j¹+þ·ãt3 )îàݳ÷Ä¥áÁ¹‹Ëìð iùà®—&rßã›jÈú<¤&ù¥ºB¯AQ3ïPŠ/[Z¼S¨ˆ-$X9d%`¦Û¬¢†´ìKR|Ü'G ÝBvñoíTEÿ^‡ÿKãÒÛåØw¬4QƒÁrñGgD6bïªäZÀNñp†?eúÙC1I|L”`Ñ ^äƒ+¥@Õ”•W×G‚}hiͧPP鞘å:x¯2 ø'œÑÇþQ¯ö‘ß™•ÄÏi‹¿~EüŸ¬[ÌŸ Ð>kÐ9€[]8®¢è–b˜ÐÈ+ý:bÛJ óø×· ÿJÿ“1y6Ð9$‡jFe†J]ÿk[Œ>%ÆnÆYþÑ|ðYÿÌ2LTû®sR~aWþoÃéf"®.Ø«œTZŽÊ=¿Þ€Ë!?z©{͇­ù·ÜtÕÿìa9—¦#ìºÞ”ctFÐDö²Ïî¿HÒ =e:¾Q‹lâªg™ @·©6Õÿ#•…UË4¤éF3 w =ϰ6 ÷Âó2L*O›r¡ÁÂh²Wé “‘OwV=ýºvš3Ö+á[»"°LÅŠù Œ( €}ÙʰiØÍ01(*ÒBhÄ îsÇìÖn…„a —¤‘þm!_Ìÿ,þio±‡d{å!ýñɨ"ü1‡ÄeP-÷_>ÄO# þ$¯Ùµ†Åß°BÿLHPQp›ÙhÖœ”Ë¢˜áÿG‘njrϺ& EäQöé>çrИ…»àŠÅ¿ß¼þõÈÁêÍ@z¬uÖ ŽàØáÝ,/C ·ÆJ»gF­<\Œ ûD6º=øï`ú_­Œë-ÊââY4š}E z«ñã¶ÃßíO,ºgÔô ʯìŠÿm9Ý„€Äº‹ÊúÁ\sr0/MLzE»ø,æþ•±7zø"RËÞ=ÏN&F{)Ÿ'†g±ŽûÏÝžrt;ü"¡—˜ÇD{®¹סù'³!Œ¸xí·8îÎt|ôô3F©,›VŽÄó'Æv±XXæÂ¥¡\ѱ0&‰¢6lìf ¤é¸ÛŠwöS ß;ý9 èÒD’Hü¨°GÏZÂÕÛÁ¡—´›OÀ'ؤ,ÓfNH‹ÿ}e’xb7_¼°ö"޾·Ø7R½{ð៰ÿY¥«SƧ‰–>{d>ÿd ^^{}VUÎׯ‚8‘I¿WRÌ/SXšðoùÿý0CrF``™µÊÁ!„‰¡@4I"`u~è#g/!þƒñUñÏVÒpBBp¬}<ÞÖLº§góÿ^FwDÚÝ=B*¥ 0p¡nþ;™þÅråh»xâÄåûâ´ÆazÔ°¿åø—uçU]Uìl…ñ¿á1üwÝÿÛxºq Àª(í}A©ƒûûO?éòj)Ä #Çî8s‚kÃР‹ù#‡ËOG­ÇäË…=]õß‘@&Æ©û‘RVsAºk/ «n¤¹Âñ™MB—ý7¬œ—émgÐ>N¹jdïnø,R—èë yü¬ 9|=$K¹8E½˜;Á©k:þä.$>k¥¹¥œ~··O‘9øøšVžâlÐ4 Qï10]·úÄ ®¾zð€é©…3“t„O…\ñxvê‡iÓ9¼Ò JöF‰ûÏ ª¨¾J9O›A$s±´ìåc’;䫺Úd);Cý ‘M„#t$Ó¢[éþá+ËìïUï]¶ù¡½ð©‘5y·ômh\P.ü'AÂÑ}ƒõítʳ<"løŒò˜ ¡0 zÆ$<ŸÁ¬dˆmì…ífø :Á£…ç·ZüýÜZÙ‰ «Áˆÿì˜X’«éÃ<‡ÞðÜtBn{_ݧ|ñ8üeÈþ£Ý\@ø+ŸÖïÆ Â> ÛÄÛóÓÿÂÑ4GüÝ1œ;èoC?¢2x×?°iÏø[¦]TÆK{<SdÛ`õ6øßûò2UÈ^yü×ê$–—€<Úšs¹:¦\¬6—8Ö[²#§ÙçMLjŠ+I€¡¾ ø¯Ÿ:²ÃéÚ :Ïø+Ú£_nL©O·JPJ­‚¤ÀݦU ÚÚáµ§Ý €m=ݰÀ’ºªM¢hw-ú²_Y¦îê*·ìºØ¿à…1,fI‡þPý} —V2éí#Ë]{ó Ü‹ù²»ÑŸ¢«„Ø]¹Å ŠlÊù”Dß—¦ubêÿkZʹ§ýM†°CËV³Ê <®·ÊûS¬Ó‡þϯY60÷œ]զ׌[€Q ÐT gT2p´þ]œßZ©ŒBAãÒ¢«_¥Ô-ýØ€IP /ê¶ÃwFxb"ÓpÆYÚyd1@7ï‹T– ”bÿG¹Ñàh†Ü[ðþ¾ùgW‰¥ú =×eܸ!™%Eª˜Û¨\ªø”@ ÔÞÚ;pÈ Ö÷D6åÿ<êPò>Úgø'A‹¿!Ÿ¿¨àØ ˜¤›ƒ‰ÅÿÑò<%,•/gâoÆí °„_“Üe€µy@‹½’u_ØÕŽGó>¦€€d·ÿOYü{;›þ«4NÅàŸ\3ÿ{àÂzÓè¾Üzü+Ï̃/‘©®£„õ›‰ÿkÿ³;m»éF‰fÎÑÆÔ+ªý“yþÈ‚åó“‘ö£Žsö:62›+WÂ7B°;esûž:]Gâµ?B ™W×S:ã{ºóp$PDÝ&lH•ó6HI:#›×oŽ|&QøÛ¤O³L…ï$cº úJiÌ/¨ õ=7uæ…À!kìÏ¡c&KwÃ…S¥´æÇjÉuj†€i>ÉÏk$]üÀÊp9ÆnÁ£üÆ4g”-Â&` ê2íJw=Àž=GcÏ+ö(J™ô.OF‰iHÕB‡ƒø‹E­QæsûOl\ž(¥“¨BàS±pÑ?¾âŠÙügø´7ü}›(DUƺ?Æ&÷é¡üß¼BŒ¤Ðæ‚™ª½WsÔ•!8Œ ’²Kàh?ýÇÎMJÖDf…Îfü‡« °t‰ñOÆ (8Óm÷\á È N|ÆD1Ìo“}«ñ¿Ìø«Mÿ0µê¼84wa zéxöd©hè-Ç¿®ý°->âßv†Õ›Èÿ×~iWØ~ÓF$}éL`ùÈ ƒšxk6îo̹å f¤qïâ¬üÁ#¾öGôoL“" qlÿùUV×]Zo1úã²ZnÝw†uJìÒ¸N:pK½”€^9o«ÌÉa–ã™”463Y3Ôÿ7à/vmöÿ…F`¹»ê=ÕxÎ 01°x÷…S ö=s®²òøè©º€*FüsÛ˜•+p´óÿ‘u5‘HµO 08†RÆj@ð $.Ù«À´‡é€í (•J Ű‚>rºwÜLq$:÷uþfª\üP¬ý‘E¿ ¬=¡e‡ªQ|Q,Í8=jrkMéø,…ÁSÆQSp!ýhJå<¾m{[K¦òŸp-Pâÿ›åÌp´¬¸ŠÊy¢÷'4Ò×lä¢Xw5Ãè¸î›|ïáç6L~hïésÝttÅ^tS °×›ÒÍŠI0L}ñŸ[ÅX4ñ,~(  “àÉY&)€~O&«ôË 0C´<ÀÎ8cüó| raŽž:zÖâ_ê„Ö±‘ïkáÏ_†uÉüŒ?ZÑ”N"òÞücçšfX3þ8$0ZšNĻĤb~½Œµ€­"T˜Þßë Îk„‚@þ’+Ùî¾u8­œÿŸÆñ‡ Ø?Áâoü(˜9€‘cé“ÓØ?íšš*¾ä:"„%FKõ&üÇ£0.sÊü]×tøÏrÓ%zvø<‡]˜¶%3|6¹V®o-þXû‰×VÜáô¿Òäûq½Ìí9w®±›VÛÿºÄZà”[¨óhçþ?wû,0`^xœì½UpdY—f)fff…˜™bf 133»˜™CÌ 1Cˆ™BÌÌÌÌÒÔC÷L÷_U]‘f•=i–¹ÞÜü\ðeÛ¾{Ï>Ûððõp Š úŸ¯ü¼<ƒBýÿÈõÿðÀ ÿzÑÿ Ì]€`Š—n/üÅÂP-i_B’–oÚYðŽÓKÄy7-¾¹Ü$\ [­iÈé媳¼Nò¼6Æpdñ 8©Xó¡$¯?ÒRÌåɒ J†FÖºR’µØT´»®Î>ÈŠŒP£ˆ–þðØ!E‡ÈDo|ÿÈ•€MÆ·Ÿ´š~µÀëû`7Ç«°çCí·§Âž“ä¢8Œ¯Î)ܳö æ”®Ÿ ¶ÅÒSãpÃ+ƒ(¯–Íî 3Z[›Ï³n>ôÆf‚Ÿê'Á!ÖÙ#5d‰*Þ<;…óß ÏÜE¡[ËÓìx>xbNgæ¦}fWœvQ¢f“@ÊÅ1µI)É1ûÝEò¼dÃ)›é¶i±Ÿv+Yw1¼QTð°e”c@5²Ö¯‚áhBã:—°E‘fÝ÷öd‘Ö±V/—`⩳»©¤îäu@ÔRÑ®u­~4oã‡äyƒ ÷qdÁá²§ÑžKªÓNCÍÑñowRά ‘R¦EsÑyÞO+)ăýÜ®æB-w+¤‚=¿J\έ®£ZÏPnm¾Á÷ ÊIºŒ·è¢ºU0°ÉbãõÙ0IõÛ Ï´òÄ ©éÞ×ѳëÜaªÞyæ1|÷ð7fIÀHS 63¯­‡ùuê&GÍ›=½vû¹z“½hb÷/þ½y¤ŸÃˆ½÷6>:„™õJhW/±„b šBŽ×}€ýDí”Íšßf}ݦ¦þòÒ£$5Y×½.rÙ<ãö?çlëlC3–;£]=fLKu„yÞ¸àj{ôŒ=¾·…\Xý!¨Ì‡DN5²À;ÄOCH1K<+Hù"kX°À1ÇoñÈ´%t¨¡ƒ=[zí~Ü01gÕýÎAGcÌÞiùܶ;fÚ¶ñÓðfA“÷SçvK8º˜9ÏÄ^º:̾ sËØé ï«ôòT–¢YüP8¢xt{Ý~u°²{g/ƒ¯‰-¤¹é^ª¿úî(òk:t{٨ſøÿÁ CºlV·dˆZ Õç9¾9|Õú#dU›Gä+ÐÆQtsm£2!_Õ)zëݘñ{†©ùó<Ýrfè¯Ö˜R°¤Äì8auÍ(ù¯Ë`æep!fYÉ8ZW}h\] ¡³ü¾ï[:R˜kAàÐŽ-&þð:†Tµ- BéÁ7ª q‚Åo!;a¶tz8†ïúoL˲é÷è}&9€‚ÊOož¥þ øçÈ}Æ:«£@'¶Ù°g“}€P¾’]Qx5¼%û|4ÁzíeLÇ瘾‡ý#Ñâåâù¿&¾Ÿ»Ohðù€øóññù7e9è³iŸ™!^­Ï‰ùÕI¼Xþ³$†²òOghCºœ¤˜ÅZ©Ä8¡ 8ötëÛF$)×#ÕûÆcwÕýuÆsƒ} Ùˆ Àð'H]4šÀüS”zÓ;Pás‚µ"Ë:G˜­CW ϯ6ÔH-ÇbõMkÊZ•zìì,»Ê“œìàµS\û¹¦ÿ˜Y’Œ "lÕ $ÅwF(°,šö4ò™åï#åt‹P§4Ð3—1Õ6%TŒX?-g¹‘oSö¤£ ÙçûàÊ ß–¬'·â‘üí—-ö„æIbsGÒqæÏΫê>¢ Ö#ÍëŽñÃ<Ÿæ:{¯‰âÒûÛM ƒt‘^´ð\¤ÂMe^1áË‹O±úâÛ^9<Ä{DßÞ{pJ±K?*éC¢ZÔ\ŵӮu|8`×¥^`"[È:2ªSzib–d&•NiMø n=t%¯¡ÄçØK€Ž-^¤Êì´áaÒq Ñ~Ìc'8ãQ4ðè½áæ¤{"Û–†LC–5•‡¿Õ¾?"X×·SY“Ôá¿¶OL`“âLîî´FxJ3KN×ßh3îuÙ×·² u‰ HfN_$V‘øi$M ¦@8s)a¿Ó!"f2XoÎ/ßß&ÞÙû1nË¡R¸çók©<‚>6@ø$=2«ÒàFše†õ‹ï%µµl0§ÆÚœ7øò“;%ߤK­ç¿÷ͼ>¯²nLæ4Bs Y÷uþx I<™7lÙ0Í÷.ýZçbÊPyv•¹µw (·ß€Õ]¦ÓÔ¬Gó¢±çiAz¡{ßüt»Íâ|Ù-bØni÷žyì£X^‚ä"ÔÐAá u1…Æ¥[E—ÎÑà){u­?ocnÒXl‹-D~ø]A\|Á;3§á9‰>K‰Aåu~*¥–¶”-9T+HhÇv¿Ûïk&ùÒa5kh‘=ÄjÑÍþÌåZlð¶ÿ,)®š»G«@ã†Ã8Bi^Ý©có„,t¶çîµ3§ÿào•ײ0ÆúÉ#,‰}\Án²s"ÂM'^~³ê U>²‚ñõFoAiÌ~#ÔnR™-ë:Å«Hã©ÊÙÚëzx`&êci¦ö²óñ§b{Ö-!´ªt¢ ÚL®LoÊeŸˆdÕh6´®×r€ŒÚÀxGõ\7iõÏõoøm5þ ¼h)`l[ûÞíboë\Īèô˜S¶A­Bpµïæ­½vCZ0λ®ß±é©J¶¼µþCÿÕ%uŠ$st7xußé-Ë‘¶ùxËÆHЉÃx ïêλŠO^GM¯ÖƒÃ4ÒÐ?é,kÑ3÷WýHû0JdüçXÙ9`wZ@üîïÐ.ÌBÓç:yüZy'D Ur‹M³ñ€ÙDˆeëþ;8ªgŠp\G=â¥TS®r¶Š‡V2làߨ\CµOZ¾ŒËV;Ž€·õ¯ F#î,ƒYõ^ïXTË™zc:'d¦ïL¶)&LŒ¤ òFƒBf|ß&GX¿]7g„$æóFŽX/;:H¹ Ó\™C4dÌ8Ä:WmnP¥Z.|3ý_ý·Â¼t1­Á àË}ìîXóv”»8yf}zøÖìóx_¡:hê9¤Ÿ¤ÆyÁv¾fé^=4|aVýe­tÝ¿(7,.éή“VVÒ†W¬Ýc!2-Ré ±aÕ<&à® ” ÷èýºôÎü}Ê·l­†ÁøDPNž"¿/×5b±GBQnš !úÏó/@K=<9,¾$eÐ"_¾Hª¨ðw¯ÿQ“yéBºnüì¿€â3#aì|‡Ôxä,âÉÏúZ©A—-–°ï7 30°k3H†à`ó˜ù¿~^΀¨à}¶ôò øýù‡?Ÿ?ÒÐTš×HW|Õ=(’yoj”±@¨¥N¡rî_r[kU9ù¿´+ Ö@g÷P\ß‘)*< ®sxN¹€ žLÍbë2Ð]>º óYq6Ú¼^—­”Û-† O IT© Ïu8cAyöÐ9Z#ê 2IŠÌ÷N1âßTš­± X‡ï¥ä±‡‘zZ­P†½Á£2êËð§ cV¤Çޤ‹…¹ öhT4Ï].o¡4n˜p÷)ˆÙ°{ÆâDp!&h,Ðcí +ø@àhÝAU'ˆ?Ķ:˜/ô`qÈ2 ”ÔQûYf3ÑÇÜÜ3•§†÷™Ý®ö>x à èætP1d~ŠbxÌ·l §~sûnƒ®h΄Àñ†"ÅW@³? Èô¿ÏAŠJkyÌ| ûÉíaeäÓžíNø+Û`S&³Ëdë¢qŠn÷M¶ièûÇ'{ ng¶ŒoåxŸ}z,‡½ PÍ „î#áÞu ’‘\?rÊý®gp¤LÊáª Ë 1šö£PÑYnó3k†.ÿ x6ýW£zJ‚ó±·aW iL7æX¾ÍÝ ofêÃaç‰Ê#F8#žÖÌü… …Ȇ3§¯ F~]탖ÕCpÈd[t=Ïó}žðÖñ€Kfùªu7…ìéD>þLšU…ÚŽâoôµ@õæ&ó*ñ·ý?;¤#ú;×ïw=ÐI¼HòŸ´Û/cxžÈBFÁè°Wëþcÿ\ §??ņÉhfu.·Ž<-{TÝ4ç¼¢%î(·@}™%P4ϾÂñåÍŸ›»'&«‡€Ë,Ëb,i•ž8bº±–6dÏ+’ItŸw‡’íÆÐ¶¡eØŠ\b"`n`´ç´%ˆœ[*›(ŒDËÝdȧƒ”ðk‰Í¹È—çx”L¶ˆõ†Žð ¨…ldÉBÍá]šþ9ÐÍjŠ(‡?Eµô‰©ÄeÕ8z\òdÙç¬^GYÿ7ÿfv¥ætmþ~°qùQPe\¤zÂôD…Žï‘~¾RcHŠŽö”XަGèµD=°W÷¡¥Smøžþh »æ@Eî> 4Ëàßb¬†¥Æ_fšÏ¡ö@Aì={¿;^×úžF]†4ø:Ì•©<˜a7-ì“Á:t¥R8tö°qÛS9uýiþW11¯y”žMD¿3ÂY—#sêæö¥üÍëß¿Hl…û˜–¶ž“µú¯àŸâAÉtãVe½/ÉõÚ£Ýø$aþ–fšØŒ¼±ºvQÍ|ùp€ïìå÷cÅÇÕ#<üßG½Ÿ§WðÙqþ‡?›?Òxíë×ͽ8Gìk’Ì‹4«¼Å&®J0Ô^úþLQÖŒIv½™ ë©3c ÌÄÁ~Â)Ÿ[Ïu©SùÁ”礪«Û’ð5áx$|'«LL *IN\Äé~Ž ‰htŒgX/ê×t  ë X/“Á ÆÃwOwØ4ñ3à dø~¦c%‰Ât-eèÛ‚÷¹aºë»ƒ²åZt7 r§ ñ$`¿·’NÎÌÌ‘ODC)wMLUÙΠv7:ô`ss;²æ§§üa'yÞm¨ qzãÿ­|u´}\ð+ŸýŽÊêIØ®ÝZèè‘=æ“ Å;wen9[¶°í—s¤Ç2L}¸özté‰ÖÉ©äS,ûw5¼Znoú¹<妠<—=à„]?Žœ%u<êñ Ãm—G\Æ ˜$ @g\‡|®´žÍH˜ f<”~§ë<ä»÷§œ?œÂv<àËåòžh$÷è ·+R~ŸQNó·¢E¥ ÄÅó[rRYñá²ùtÇ.SÏ^¬2(*f=ï̉}ÿº]zVÍK¸—›¢Ïkß_½ßc{Ö"õ€V·\ÓøÜ'¨ÏßÚ]Y‘ßE “ŸÌ2Üü1œë ÂÞä¥ÝÎ3uÈê­éý;ºÅDWDñ³öjâEþ˜³Äðÿ!eÔOí®A,‡L¤Š/Zb×| G‰NÎ÷,y°ªç´`q"†Ýè¥ÔN2†Õz‡üOý÷âôÑçŦÈ4}CÞ“I³Ä>MtkTg)K­ž{tJóyxÍ÷-®2þÒMÕµ»GñÞò½× ÌÑ«)wÏÇ}>­þx„Ø…8Æ:|«ҥß,jËÑÙ_†GôÓ<Þ†f”.w¾-¦•suù´£ó0xI¹¼Iëmų¹“¶Î^ +˜’`ÌbC4ª̇>бe3¼¶74ñ01óÌ฀í¹úTu{n^3Œy²S44o‘uÜò•P]øñ{ej{F%ñšÌ¿Í¢8¥€‰ ±ÓÎÔh”º8Ciåųͺ>wI 0^æhx¨µüþ=¨ã&3(^å$:šnx•ð:®™›%t Ž)´Üø­§ºÚ¬fžVŠ"1·„ ä{ÛevÍžÊL·‘î"§ÙìÛbY¬÷™ù%óR÷_©ãä„í+½t—Ñ’·ßù¨ë+\E (“š1ê7FŸ{·5ÅÍöûŸM2éñ^F ì$¸¡Š¸Á|üIþÇ¿bóã²Æ™+_ÞûÚ*<ŸÞá›ã þø{׿Á$ÑlH7ÑÁèß_ÂÿGó‹¢¶´yšÜƒßÑ-áÆ7VpŒÅ¦ÃžÉè!l­Ñ@.È—+±ÒÛ)øßN?—ÀÈÿ°ÛïëñÏ1€¿ àæÕü–fvf ©x6ÖR>Øþ¬çNRáiŸö>=fÒ)œJ«o:*xHŒÝ“|DxØûxǰÃT¾ÅÞbìAAÍë/Ä&¥…¤ŽÇÜñ–cÏ»¢ .¯ Ó–ê ë2ÀP é¾v^²ÆzÛ&XÍÜ>VÎGCd†ƒ­Äè%>õÈ– ôcl„)*8Í…@§E ŸØD6^7BãÕ'¢¤(¥@ÃØ"2 ùÕ2Mòù ¯ÞÀËä"D AJ#¿2ku{/LTÒÞß-Ô½›?ØO¤œÍй®ã>R _p^Ü. …‹o…HF(" §« ç¦ê¨–ïrÛæ¸<»MFcøÎú¦àú+iÒbq xÒ]—jæ4ƒóT=¤PÝí}±ÕNÖÿ¨sšˆ|Sx'€.뀨—.`›Ó·Éj@¹¬Ï)ðìC^ÛÈW/Œü›ò;N¹»8Z­Qb8éPîÛ •ð†Ý°Ô_ÄÁ@ «]Rïx–Jï+5 4º.£öÍLÑåç,L„Ï6áÅwzåîà@ZÂ!êpÉ’øÛao’¿eÍíBä3£"|cMÔR,«…ß1¥H1ßg¦:êðÞ^{8±ïa'á˜,â ×#é”ý’ùy,™ÃXj€-‘¿0Š <-”ÁŠ>Ë‘æô­—AÛg‚µÁ Id @aý+Ø;J†ž›aÃÍo,îëõ6XY ’§û)ÎÃînɇ“%pùðßqûDA]¼«íƒb×…ºQ rŸú°ã°7‘!ž~Êÿ¸íw~Ÿ•Â+ìブjÚ6{\nR›ß*4Fíxb§’øi™Œéeä)9µc7‚S¡í_NX%ê¢ßø„êWÖÄ<ì/F‹§p9v €u¯HÄí1â4iŒûe 'Äb¡+)‰Ö¶ "4†ŠÑɯúÝÌOOùÅÔˆ®Å3»(…sØ4;ÔˆÑé<•Pª9|…W±ö2Q úJ D+qGÌÕ<©eèšRz/‹[½mQ@0…El.!("Íe%oõe¦Wb¿*ž hÄ@;¡€æ¹(3ù?ü—'[±¶dHi£áí$.´æIyÔ%๭Ê=äèõSJÆ—^TÎ(W 5Ñ—ÐÂ(&vÜCFj¸ À3u¾'^‡ÅsUu•²=ÏB~õÒF0¡Ž¶}­.‚²x°i#µ¸ÿ„šþ ÞÍ+àúûhSÿû~Cíãu±º¤ædyrØ.ÙŸä_n®~æN%~ ‘›5í³nRs5"„Á m\?£ãï]ÿŽ €ˆÈ ­Êâ¿„ÿøã&ªãÙ+6FoÂÚ8{®w¶FÒ•ÞÂ7_ð-ŠM2IÝé¨ìÎßo¯ÈÐÿd§ßÇø¿õÿ÷ñóü퀚Ħ®Ü³ÞÇ~32 ¾‡ÒèœB“ɱÞþŠ 8xÏŽ†®bU>õúÃù¹ðÙo<ðÁ1¼ù¤|¼í‹6¶m¨Cˆ½tê/>”(§àEìôk øü¶B>"Ï$Ó‡Nàq“âÔ]YÊL•>’{;*ŸÑŸ-8ÞÖq˜´%"]Öþ³…û#œã’/ÌWtÿ™WŠ"Æê…94}þ¾ºðA/ßS'~й"PõBúË»Àžôz†ú6÷lÂÊäâð"ÉGŠ6·Ó¹÷ød¾açMRì ÎB:º=Ç[X˜z‚•#ßX[ FÞΪ@Ьž%\Hò5rõ¡'%´€œM?·¹TàS®;e–×»µ…Ú·‚0çÃnƒgmÙŠOŠÖ<´Íñt† w{‘K×Zù‘ŸKÒM©hR¡r t$Ï¡¾ÒqˆpV8 Ì]h´à“yágyϨczž–ÇfPR&(–Óæ0šaûÚÍwºæ6Tj†é¬õ´šÔô}”íç‹Í¬¥K5.ÌôÿÑ¿‡›ÌוèΗõ{™I e¡û¬öŸéÔõI4…<¾Õ½Œ¤¨BšÕz$‘}¥þg#÷¸ç£ep¶Ý™™Æùä X­ùïÜH;¬Œ¬~Ë@ñá1C}ÈQ=n}¯ˆžùĨ uÇvÏËÂM&Ç£Ågàî&[ÂpÌbM¼ØúòH€R‰¸7-«)s5m%ngi  ȃ²)òúJS-î,Á—bqqöï͵_ùž¸Gh„ÏÞÎuZÛÏ"‘t Á#DD~FåF΀ù)ñcn;Zì);Ò•=D©ÀæŒEÏþP¬3ˆ³úŠâCÍ¿’?]èÞlÃ&=É¥“O!á›øÄÉ•wÿþ'PckŽÍÁmóçÁ9gðÔ—7¡þë_cëä%Ð"õ˜W¢Æió§rg¢]6*j‚Å“¦À€Eòì랇ŠN$ï¥å¬]~”% ÃÅš]ê2ŒÒk ®°ÐŒTq’ºŒañ*æHÜEÞ~tj¹~ {ï&ǘJिÍ&®!+ƒçb€ü)þ§Ãš‹º‹ ïYØ¿øô‹ZA/N` x5ûèüÝë?Áo·é08Jû/ῃ¬ŸŸê¸æ¢#«²÷çd%‡ÿ¼FsÊ•¸Ö×Ê(Q¬…_Ș¿›)¾î®Á‘ÿyªxy†ýÓø«ðûÑFô‚ˆ.‹©4sü)Lﳤ¼ü¹Ï§} ‡†ûºïz¹Š³“åïÿ¶¸SöP¬Ø}sŠÊüѸÂò@œµßáC.31±U'¡g¯”=z§îÎYóˆXöWRlË!*¥:F)µ™mɤu¤Ì<A¸«G詈œè“Q7\ÝG¸4¯v¥ýiØà²Å­ü˜Á‘ÞOi]Õè{Wä‡o=¢سŽaåOöLk&j¦Ån„óöhÛÓƒ¯pÁeªôo îLBÚt¦S<Ë‹e,_cÄ*ŸNÛ-Nœt$¥jDUfž)vz:ß©ñ9ÐÞ ÕF$QÐ|ukˆÔ\…`å„"Ï8˜G›¶{'«¬#”ú—_„ºn~¼#—ý¨ñïÔfò…̶ùp{2ƒ+8ð½•õ²ˆæÐ`à»Í”®åÛÅÈ §6n¹À=¡Ö•Æ>jνÊú®r]P 3@ )¨B˜ºÀÔe‘s"ÍKÆ”$Îûš¯’'€¼gigª­bß#›ã¬Æ“!ß¾OáYAÏÆÌ(¤*;¾«Ñ¹æbÇ8WzÎÛlˆ»ü@\bm8©^:õÍ4‰J±½!B¾hp O@ l€Hki€ÈtM¼Šœ,=f6¬–u&õlˆ9Îv; ØÌŽ™~Ñêæ+Ù^ OÇÎYÑæ{„«ÐpX‡Ÿ˜Gþ™V–W=¯ÒݲèÇœýlO©ŸZö_ù'Ò ³ç×sÉÈ]ÿYSøTFâíËvÌÜ¿—mä‹©ëë8ëa l7¸Ñ“+'.zi0€ÝÐo`sÔ¦²ýÐo”Šç,)Éô5fŸ$€_Eʶ=†ïj{q¨:4b\ï-/ÂPײYÕ$qÀjèùûâÃÒVSž‹BŸXþÕJ\?Iˆ2ôÏùtøô­}ˆÖ»u©Úé‚„”C›Š³¬³…Z‡ÂM®§©ÁÑÙú²ÂYÛUój2\áððׇJ€3·®£cÀ5I+´E•yÝtjßq Ž`xÝ"вÅ·ÚÍ §ùþÍúÈÅÎvzc®‹ðÁ`›@ÍÃ~–õ?ý‡5`(¸|f[àýsõNÇJ£b=V¤‰ßŠ“¶a&ÇÀ/óžƒ.Dq"Íoü ޤ~†ëq±Ç¿B‘Œ±5Šj€Vm–ÃiTå.Ù³ª¹j%xÚß…_Ë•)»%ØÇ´c{¨rZK›8Òe¦‚ o0I¸é#‰r¢”˜ëÌ: Gù €Ÿˆ0¥ˆü3ü±&ªkvÊ*9©'*ëüÊt^my4ͦ®}‡ ÿ{׿i§Vƒe=ð_ÿíL°‚]vH4èá¶žj´‘è®ëñ¥%Ü©I·ìƒü‰ÈçF@Ê>ZÝïFŠ—³oÔÿ)Tü<¼ÿ9ð—á·;®}.Ç´k“z)ç¬CK]Éö)+.·?S­¬{±úLCòLN9*€¦F)x‚®ZÁÙzÄxÉ÷/w²ä/!ˆ9*2W°e”¾J#Þð»nhp%›×g=±¦ŒªÒwq+ÄÖ)ÃÛb³¹½ÓEû>(jµæïÍ·<¤ìÆ_ȃ ½f@{A ûØ‘“äʃ©œb‡‡gݲÑóP¬GCkÜŸ€›Ç‰iWŠöýaå;°š“î±khRq»Sz·žNcV|ªÏY´?¸^&|÷{ ¡öo=õtõÀ2ø¿ÍDS À€‚r-Ó[3-7œ¸<œÊo½×²}`¢Ùò1Ǿ룧0õ®â0]¸05ˆ …ö¯ëCqÂïC N¥®Â؃„àÝu–áú×.Já¯ö›™Hç;t;ÏT ‹ i@n«ðS^¥–a~º¿Š@¬d6BBù•s oœµBÅù×½xã¿*&us ‘c¨‹ ±M…¿½;]%ÉŸa Š!–ûbó«8G¥ßý³IB[Á)î—Ž?ÔÑ*>E©ÿ; z}ü[Œ’Hw+= ‚îÄõ–v«ý;EHd0Zƒ“ÿšÂÍ_»6•ÖªSéN¯Hn»b ðÈ…·pß›¦Ãú€8—ÙR—6ð,¯ô²Ì$¡7Úa±–~-d4eë/J$LÀUã¶$àdz3t‰˜ïz=u-Üaôí?š¸rËÌË¡¿§kèíúö|CEp¯ñ±ƒ,::Õ$Õ°„ê3Ú!p>ÎÇÃ)v_Woïn“^™ßhg- бè@‰éªÖ©˜E¤ÐÂ5ý‰ ǥѿ¥µDbÙ8¥¸8záˆaÝÃJ£‡!tÝ£ -º¤ôÝwnjqÞ2k-ÍÆg<¸‡š_(ރ官Ìü‹`¤´S­kÃb‰0Wïl©ô•6¹¢ôèªo™^ÎÉ–àá4*^º/¬Q?emÝr”€>Ëù¯ "úëÝXÏQÃ¢ÊWKAº–¥Üa$¦®½ ÜCafÏp"½ÞNª%ÂïŸà_íÚqvkÒˆ~É3›8g7|?;-£‰Õ*ó™ÿ©Ëß»þ9Ua¬0þþïqiòß1[΃<·×aµlË>UX˜¯Ìð¡dNÄqP3y]qá ~3P|ÜÜÿuöï_ñu÷ûgð/‚ŸgÐïõcT…S»á]Q\[PÐÛŽ9Ý,¢WVægAÚqïÍM`[ :?ŽA69Sä@€¼—¦À>87ÍÞk4ò©+[´ïô4ÈmYvýÏ?¡vK×`ªpòÍÓ_‹îÅQÕºga‰`xûîtfÏ‚®|›Gi"K™ å^èlZc§©„^Ó?=<U“ƒ¼šÏïü±¾ØÕ_ƒ-½ÂŠÃÁ@†±çй½H]×Ç_€j•#z&™þ0ƒd‰—í‰.~²û·,YWœ ø\ÌUœÃÿ&:¦6HöÕM2oBå#J¥ZÉVÜŽ‚ë,”¿ûýÄI‚±IÎÅ“t èÛ¦ý t±vùbøbˆÉEcɳVÓ¥ói¾®>þ9`Nagùš¼ü¤|=¾À Ô M¼óé @PuÑ3Á®ê`.%+¾úšÐdÏÙG©–b˜ ÿqⵋ¤ª¾VૉÈ÷*ec)¨¯@Àc=C“*ÀÕªüù®úÑÑ4³]üI[ucí›uëB­syëëV¼áb ð–…‚sº¹¬ÿþ~þ–(ò™ Û¤N#¸\tÐS¶:Íw]¡CÁ.‹:L!k²Âno‡ *ŒOg3S5ÈyxJA=ßr¾w¼.tùŽhå V^éÚÁ#N JÃ_•7SÚŒã>ëó˜çI€2ÈtŠÒ©øz&£¹²`®¦ø³/Ü1,aü`VóÈ‘ÀȈkkÃÓ›ú4ô¿Â¦”äöNÔ¯ù[Ÿÿ–ÿ˜¤"ÍþX=ÏGÐ1 lD…kVI ®° ]ß ÐsÅòdï4ނֳ¦LŠÔRîð,ÝdQ§vâ'·ñmª…:TÙG;[«èχsfU²ˆù+þ![WñÄ”_Ê¥bš{=AæB'Ù$Œr‚ùwR)7n鑞Ñ1X=.°Ìa‰ÝeôDä{¯œmÇ¥LãàMÒn ›Ø:!d†fà|£àvÑ=Œ®æ+Þ[½š<¤¢f¼õP+ ~F›~8aYc>c¦¹:s—¨¬9ëxNøŒ:*{„%çy“2[ŠH V^@a®DìÔ"‘4s5ßzÓ›o ýÿö„‡±Îè+ŸœÓ¸ŽÀA«ÜYé…4t#Ÿohý ³ÒaêItÃÁÆ{¹´R Ž]Nód›¾ö?­›¡û7j;Câ2KîñïÞ,ýîõɃÈôœ@­BÁ9ý<9TnØ·öÑaXª§wGdãà"XDr`¥“ö³?W|ø‰mü1œy×ÿÛýWôŠŽ=Û4ÕòÕ nÁˆòXUÄŸuÖWÜJ,Ÿ/é©ÿ½ëŸ¥v40ô¯á߯Ô‘éKþRºR‘aNA<Ö:Þ¯©o;Õ["Ýe§°{™HwfÏñˆ›¿™'ÿáìß¿âíáúÏ1€¿¿Û¸/höU¶ñy5Ý`âF²·àþºûˆÝã½ìs+Öƒ=%¬Õ£dbh!†Ýó ¬#ƒv¸¼KÙ¶Ë œ¯ºƒÇÒ<Œ£ÑíïÀyó¦2¾†Òrò+gMW÷~ɦLzUܳªI‚13ØêÒÆŠ§I6n(ÕR«¦w»6\Ê‘‘ÍQ]";5‡'b\ׂÂ@ã}¢GwÔåöB0¦µH„TߘOxúXu{sVÜ1¿m@xÂn/ ÂÐÍ-c5<,€\n×IœÂñËgš¬¯t*b—¬ïäœ_6&v8.Ï:»LÅȈ¥¿V~Ô8îì/}'6µ.5_¸!¼» ¡¼¿Ug¯d œ zÀ7¡CŸ¿ghe•­»ßI¬ï4Í çR'kŒaìƒÆãD¾úÔ˜óVçÉæ: !¬ôéAé’^Mbqy9G¬„$~ÎO¯ò o1‘ðI%’WnR4ø)Æ#hVÝDCõŠ‘Ѻ-!*ßÜìü"t7 *¹æŽ#ÛpìÅ,“»ÅÝ 3 {:7Šæ×h±~ÄfBª|:ã¶3 # Õë¼wö]oyÞ‹ÈÏò÷üËãG=¶$ßCôÐ7Pô‹xÏ¡e¤²0¨âTBP„›°(gŠ3C¾÷x zo@dT.ÕO°'û*ÌiÙ¤yñH…fþÔ¸†’–ÑÁ®¡ôÅ÷2{žÜŽ‹›—TØm#VîÇþ|±÷N\˜ôÍŠŠC£AƒPyó©ÿ%WÓ‚Žcµ½öþÏ;:TJÎô÷.´O‘UÉ–¦•–[ÿ+ «bê+€DÂqòyÚeQˆ¯<;'‹Z¹ˆÛÏ_Àn¥d ¹xˆJ›‡0Œ{šˆ­Kíš0ûè'wø¬åOp3·Ë¡´Z1ÉQ“Äy8ŒP¹•ÓË*wö\;÷§¿[ÚvkV‘0l86ωP}Sô¶fK$ƒá[xqÒ0õò ÷o,â4°Ô¬ê þ+’öÒaIpÀWyÒp½ï¾AìopWBqK1½dìbÚ“þÈYš4Ï~¶EО½ÔršÈY¹…ÕÑÿïö¯«lУ€ ðÅÇðÈ&“Döà ™שlûlàˆ˜ae¤ðï]ÿ˜Ò ÖÿH·Is¾5Žô $°{RW.à߉ÅÿÖ%eXÈH&ÿÝÍ¿:ùÛ`à5Aôèx¦ÎŠÁ3~åGîþe,Á:ÉBaV$€T6oÓ³‚Ÿù•<¡kP÷–U¾‹^–ÀsþŽ»ÍsÅÂÄÌ ßrvÊ¥u "£*”MIŸ*köeV)Úñ®t)ÅýIÔ4š”š FrCú¡z–qû×qÐØ;\JO¼ö²mÙhºèNX‰ŒF{ e`·sÛHð‡÷I¤ n9I<^*J(QFõ;s)¾3« í ^gƒœi« qwtB }í£/ E´aÎ;–ÛàC'¤ãeÍñ”wÁʱ=¶a¸¤ä…ôkÁæ¤Ù¿ü¬ Ñì«ÕšKe·˜êi›¼Ä牳ætÓc=YT\Ñb2­*V×,V3¼Át[ã™ÐÄ|]¼ùGçå¹§óÊ¢ØF»Q¡©ïß¼$®Hæ(«G“ÆlxàãYZ%@~MÜ—S`zE„9 ƒº—Ù¬ÔIÎØ9 *soó~BW•á"A°Éæ5v ;¿«Ã@Ù€{â“ù5L¨pøÔÍk"dä-â®]›’ =Û½hH¾W±ÈÉïåø[ÏÕ¨"§qÔ_C4w¥uF iEÔé`_O/A`bž~¥'Ú4èÃqþŒ¦5+å<Àê½Àsì¼ðä«!`ØàVP­S'{¯ö mç_¹Ý Óxuá‡Ã,¥—¼ËtЦ¨UYª ó0t³Ÿ Ì™XQé®Ý¾¼Lâ$HŸn˜õÂÿ¡Gá›·ƒ‚Èa3‹ð¹tÔca»½¥š¦MZÏø3<«ìÁ§y?#Æ*IC8{\Çrÿô0eñ^žè—°ý)"ÀLÇò-ų{ ‹Ææ”6ü[¦B(wëkåH¡b!Q:„óÄçbÒ-£+t÷?à¹4ýÚâÈ2Ï#y„Ø}ÐŽn,.\‚¯q€˜z¥M8§£¨±Ï ËK³6˜_éè*­1¤;ç)oϯ•6É.r4¦Ya·!å°õª7a ¦¥pêÑs\X|sÈ¡¼h˜-W¿‡äµØNÆÊf´Mû¾½Z@Ï¿-{ Å\Ìñö´³…"Ô5¼ŸèòéÆƒô‡âwgøP†7"¥ÞqïO±Æ€'ÕªK[9Ì£zÙÇê'Íl(aðyÅU™J9hoDÆ{BƒýWÇãæT‘Æ…¨EÝ¡5RV>"õ„6ðç¼ãI3á<öÀ(ò~ÿ¬ö\µ1=#Àâ#yààRÚu¾>Üá@V¯® _"?Å' LSƒ$ÀŽ“tt‹9” “ÍüzQÇUs¼hŸÖUå¹<´6Ù¢‘úîLÁ+5±²)´(;…é)ü°9®æ»y÷Í Æi*…—‡“k/GHÝÏb§–æ·O[Iv¹Œ›¤¬Ÿ[6ÿ½þ·H…»yxß<Ä|°(|·ön©é¿$ÔI}àH;â1Y“…œD¦ÝVEýÚ>ó÷®ÿ¿ŠÿNc¦Ú–:•d'1Éf _"_¸jX­£^ºŸ»1tÃ${!HÇ'î¿&ÞÎÞÿéìß¿âãñÏ1€¿Þ>¿Óèêºdiò”L—Z1|aò¨ #_vƒ›¾q>¾û¤Ðíw”<`ö^b4j%@í†Ëtå­/ÚvÜú¬}'ÜO ë¾Þqoë\~îŠLQÎ}s,{Á¤¢’YWåE•N@†xlAÎÞW ”rÂ}@!XrÙ!_!³> ´?.E‰œ’_G¼à†!6ÇP–Ü–g=ן<3„‚Xïu±J_jaäË×Ãß 7U:’´Y=—"ß p<‡€û')~BÍí%'Fìƒi$P|C 2›ËÔ|“8{°BË««ò%¼èAC\Ʊòc£zG?ýFÿä­Ây 0"O~sã¦o‚´ZN©FåiûˆÀíÓ™3˜‰E¼RÌ1¯V–Û܇çAO0ÆNÍ$š¢F.å!e|÷óÑWÝìÕÜc+|bÂypnTòòóJï,Æs=Î2(NŠËÂòöõa߃=ªïPß-4¢”­t„¼.W3–Ýû fªÌûª~Ý51JÊT‰ó?€+¯Êë– ë³®—äHY!ÆéÎÒ¼¾$2k_»˜‹ŸàYO½é««iÎÉ®BÏÌê{.r³2ãæ=¨UbêÅ;9Ù}»c­»‚Ê´`w$xÁÎÎ<âú¦Þ_­ß?ôS´bú,F†=õ&˜Z-ü&_׿ä<Æ=ò[¾<¼ÏMÌt Æž7¸ÔVÓIY¥ |0uïXêÓ3çµ ËóÏ½Í \ùÍ23ÐßïÕ*‚¾k3uK‰+’£˜¸e£*>ÜÆ¸Ó‹HDÞ¶D)­-’æ»&§¯ÕÔxµëo\¸Ù˜À1ÓÁv#Qt`˜‡½‹™p Íš·ôÇIÔê3wãô¼HâW†‰¬íƒF¨ÿPŒ¸lA¡]­H¦7áX?{ ›ÍD•jà‰·½WÐêzÛˆr› ãæ#Ÿ@5Š<ÉäyºMþ>O¥å!ZRšd]¿U¢¥g1ׯ:Í-4ØåFœ³h387¿ºÿ²¦§Uí{†9…M7jj¹ÿH0앺"aãO zé,¸S5ì¤jow^öÇ[ )±*ö»}Å„ü›?¨·{Ù;gxÀì{B¢í„¯ùsgf"Aq3òÙ‘ò˜®úyé±ΘãGXÛ_‘ݯ~y5¬s¬Ä¹j}óv|R²¢K¤%ÂéÝ fÏ‚Éý Ia—èÇÚäûD±ƒèVOÐ2éÉU¢Öù24˜ Ú72òé ˆ[FÿßéSÈýúž¢Ö\h„\KäÄÔ¾îV¹ˆ¢~°»Èî¤oô‘„×-:¦ŽíòÛ ?š?Ãß»þÿ"þ3pJj8Áyo6s+¤¯ß†ŒBQÇí‰>ËDƒÎ¸¢x‹å ¿Ò¦ýN”ü³ÿ.y<üÿùIàÿÿù­@ò/A´cÙØ÷6® wÒ™A±Ð³‹µt±Ó€ÅÑ\°— ’Wÿ¶Ð¸žøiôÑ?ØÆÎ/Q 9ùîÌÞ™[½€[¹ÑƒMS‰wÝPÇŽç¼½fDÚ‚aÑ’hæŠbô„ÕM’¨ÑNòHdð‡¤Ñ‹ó„ฦ(’p;ßñ:㌵¤kÕ©ÚÄ¿æd,òÒ6Úw–˜~ðsC­z|Ìy_?y¡¡¤}§¢‚ï£rGM}¤'Á·Œo¦MõXäÀö‚'ãûĦ˜Ãll¤-,¬ÍœÚ·¾”Y¾ÉD.㿱¥¬óûùJ•©Ì]3ì}£XŒë=TêŽïs")DʦŞ"z‹Sˆ+¨ƒÚ­ÑEQD«ÀŽx¡i£ºg©‹tæ4£ŠXÓJa .?xÄwϺdüƒÒíf¡Ì1³ø°§,À¦e5G+ˆ}úóÞÓ`7'ï¾£bÎÙ‹¨¢åDzª,­^,Šé¬#œhÄš€•÷ÁÈ!áo ɀMn–¯‡\2—ó-?äM¿{äJçÄ;–£›ÎöÜôØT@²à欀«ÄãÄ- ¤ÝxóàÃDi:,ä„ãçõ¤N´nPw Ìt胇2Ý–¯DæsšçDèüc ³¼_ʮ߮}ÌÉlrÈ×ÒpYüF°ã>€Iãú^:õ®D÷ŠŽ¡Yð«ÉͰÃ0vÞÝ…¬âÓõäÃ8§9ƒ,ñ¸Jc}X§=|¨_ë$~ ¤zòäs|¨ºV‹€¬;òP¹ù‰®h8{}—üŠWýo÷Ù;ö^”ýXÀ9Ð,ï5_\u…ÛcK¥ÜFFÞtSoúΗOiÚKÕ€Ü%¤Íã*†ŸãÚ\Lr“‚òšfô&àz·÷ö Ú@¦êYT–°ekG;FÌFafñŠV]Õ)˜3\`£Þ<a¾zð@1%z¦W‡bÖEž»~àŒIÅõN©ù®­ñœEµK‚…ö; É®‰ ·,¼å÷ùmžYäñ9ö+:³*¬ã&‘d"…DŸ»àcFpÎÀ×°OdÞN€"Aqnf$çm{G•)¤Ì½5Ms¦Oì·kŽõb+C°£×·tÀâ˼„ÉÓ³ÃZEºðÛÈ[ç†r/žŽ_þ3§Á±Àb$=L¬Ä'ÄK“Ó§¦ó&ÃðÊ[O=ÊçªL»`hÜn£unœL@ÁùMNÜT|{>"ªÝÿþÊ·j>ŃV«ðxó±Ú ä ¶¤¦›°ÔtÑ‘öèƒtÓZW?öš>™oô4ÎxÿÞõÿ×ðoËRÞÁ°êÃ×`ºbÚK5»‡i“7mtøéÚ®õ¨º¬öüAâçý_Ìþý» <½þùgàÿßù­€]‰ºo 1ºý=Ôhýñæÿo ôÝ÷UÍ;ÝÇ…ª)À¶ÁT$ûQ¹ßoÔvqÍŸâmä{}ðÈ¿Ý=Ö Á¡ì2`ª¡q~õ–…¨¶¸á~ï6tµõe²ÜøÆOþK\}áè’w»Ë ÐßÚD*G7òÃôÖã¤ÕõQ ‰ØC.æus¼ÔëŠ#b % Ú,‰J(ÛpähÚ:寸¡­¦WŸ¨–ç—š~§šÚE€#ÇK †ž‘ú‹*-I1i ßkeû´4·Ã5™€ä#4ó¨Ã´ÉìI>>LE«vknÒN6×iÀœ\Oþ°—B£?ö¥{C@#B©õdâÖ$µ±Dk›Cîkœjý©ÉÆRàÖ{“Z,Ž>ŠQRS–ƒŠ±dŸqÓÙèÛYP½^ÊQ‹ÌnÌw~$?ϡԠÜe¾L‚pþyQ8ØÇ¨@:»ºPÿâV5ž¢¥®o-=Áù–b{| ¤™{¤“LŸÀþⵘ£‡ ÇĉÈ#äÇúE˜Ì>ujpÖÜä|[=ê`™ wü°_‚mKâßyB¶ÜHº¹4œ7 ˜lOøÈh6?¦q°w׿¢ô5{·\s™^A‘²;X³÷”Øk]iveãè‡i[ÒTV ‰EmJÂý$èõÆõYìS¥UZžÖ` úôû”ÝœãS¢×çÏ¢&o:ÑJ>¥4¬Ux‹~³ú¾¤!½ ¤öÇý‡qK±Ì¿wån†øƒÞ¶•“Ñ’¸˜ÖqÚ¿o;ü€õRŠneɳOât_kØKP&ÌJì<{ïO´4×-wTX‡´nt&) —¡˜¿‘ˆ˜†+9x:µòú¸ƒù•ë¯ KÊ‚6”Â-3žÙr$%O3÷Zf{Ä$tiZòÿiïÊcí¸Î:jA,]h -Ðõ‚P"þ@…H€(UÛ8'Nòâx}~^Þ~—™9ëÌÜíÝ·z{v'±cÇv’6 M T…BU­J[D‘ R+ŠDhTPr¾ï;Û\?ÛïI¶¸Ò{Wö¼¹³Ý™óûöåÌg_÷ÚŸþÍûÿá­úÏúÏåßÚç¯ôôèžwLoû‘=¯Þ÷Äø,xòÎ÷_úÒùC?ÛùúÄß>óç~éMw¾þßyù¹é³Ýyæù™»'¿°Xâ[?X}Ë?<ÓŸû«}˜üþ³wÏÝw-üÂW¿|U>þÞ‰ßø™«?õsïyåê‡;ûþãå—Ÿí½²ýý_ùàÿÒÉŸüuÙzìò»{ï_úÅO¾›ýÏ…÷¼÷ÛýÁw^|ô•ý_ü ¿ýæÏ¬~ç;ÿû/>ò£ÿþ¯üŽòêèÊËÅ¿#þÀ»v]þü7Ä•ß|ÓWïxƒTÿuê•»¾÷Gçþµ÷}¾õÍ·þàWwŒÕ>ø†=Û'·ýû»þòŽ·üÓÕ—^zá#ßûìçÞøã¿²ãõñ[zèÍ3þ¹ó«¯ÿå½úc·ÿw\½zàÄêÿùå×í~ämïο½úûÿ8úÌk%o~íwÊÿ~Ï Ûkßzàà×îï¼vù-¯öG67ÿþ<%_úòïÛ{×ßýÒß½îëo[y×þ?üÁGÏíýZííß¿óû¿öö7~àÕŸÞF…ZûÛÖgH>bC˜dZ 8C¤¢ÔRpÉy¦y®”Ò.¥ð‚B(³H>lNx¶“+úžN³…–RôslæÈjŽúIã!ç[«EnL’^Kã}ñ,W:ºMÞ]<_¨èÞ+xŠ“ºmѺâ¦DàO&‹èpÜ<°HDÅ ’‰ÂœEgÚÃ1”"›)zÊïåi£˜Ü#_hñÉûçúæ°ZÞáÊ á 3 0À#*ZKXK+¼$}çJ l†X‹´æ;âÌ\R²Ü}uÏ€—¹9ÑÅݬ™çœK­Ã³®ÓâJžãvMd¢€[\dJh€nE¹áë'ÛñW‹¥De.ª þs¥¹˜FüeN£ghK Äߘù*ÌÉæ.Ž2=àW”HéˆãÑ ~ÚâTçFA"þv|ÝÑLUF5¥j»0øh.Æ• WMd !þf£¹Q³—e5=€¿èp­éÞ-Êʃ€ÿ,þž6}šU‘Å$ˆ'˜cÚâ%®üGl›­ÛŠÿ' þ‡Á¿¹¹ù?-§Fä‹>¹cé‰9C µlðO;„ÿ í[^¯ŠÓj|!· €¡ûˆ abÄ0H_wÌ©. )ïR¸(Û=*åå.5wrÇŽ"«Í.ckˆ†åÜñ}8Wj/étÞ·ÒÅÈ-­› P*T g@¤²Œˆ<â4éjqr¸ãe,õ<ëã÷”µ®uÀÓV^½FŒÅ›¶ûEðFQjé¥DóÐ>ùì\zxÑuf'çÛF‰3rÎR±@k)óŒåBÿÎû©NsMÛ¤ ¸@€LU!Uú§…ч:¸jÂ2{#G‰È¤v.“ˆÐA…!g /Uu›Šl÷áµñoþ¨ þæ†P*×÷–Wæ¬ O’N€?:çY®‰¸›.1J›cÐm±ºñ×!B@™¼{²áO§PØ Í$Å•Á_’må“ÜÁ?Nµ™e ­B¢go­Pùð3ŠËHÀ_‘åKÆ­àß5î!;Úokå|À üq-SÆÄÈÿMFÄœUUYƒÿ s K "mÍÖmÃÿ¹n nHd„!V›ÜäüÿB/=üÈc§Á.˜h þ)Œ©¢$KjË º’B¾[÷ç:ùþ­2€aûl$@™}”ÚH…TçséXb}3ÆüªOó;z~:K'åB n›ÑsV/ðÚÄ>y¹W(w/†'õBnÏdåôø@ø¯ú'æu£4ƒs/ÖÖkl§‡¦Y“Ÿ ÿ·Õ `–¡øÌñò?±³lªÒÝdzhloÍ>L ບ3Ê©¾í™ùB‘ú4Üj&Í“$’³R£‚“q€ÐFþ Ä©½‚J”Îãп½mî;˜Æ!!L]\4ô«¼~ 4°Œ1¶k|fÇuñ/J£-ÿžDÉgðß-Ÿ#ü%yñlJÏ–ªXFáyƒá]rÔî.Ü„9z$ ÁÕ”cdÞg HÏü]ß( ÿ¼ÿå™9-Έ’NO«…pPŠŸvš_4øÛcTSZY©'²CÈÞ¹€?3øËÚö ó¥òä ,‹‘Ç{¼8çEÅ÷t pͳć[ÚEü#Ík,»]ø_ì·)ÿV f_:•nnþ¿Øž}`éàïd„EPn$þ}=¿²ÏBòÀ@<”XzAÑ™loHyÅÅúœûgKÎÆ;óÀÇl6·¯é‘ÝËÇ‹8˜˜ìŸ_ÊíwΰÜ(Y$}b·V¢’•˜ ùÃX¡cȹ¡[N«ì%>[+þ—f8þlut΃¹­ÔJA[œêœz¶wTž8â0›Z1".;<"Ÿíå¹Pþ¸–`yÈYEÞ¿3Ð;Í Å]Í¥÷þééÍ­sµ¨(.a¥bœHxIÒŒû40ÉûHH8Æ¥£mtÉöìø÷û-³ÊfUåºWGGV— ’;øû*Ù?·Læ ¸€Òãï8+bpIOyü×Úÿî.ñfˆ§eY'Ú -I2|¼~Ÿ”O.µØäCʼn%£‰š¬oØ,ÝS¼˜Sˆ9MÛlXK5uã‚øÄH‹¤ZAÒóÆ÷¾n˜6Í)<=P²Ò±VZ‰9à °èXÌ”« Š èóÁ4pºôæø·r­èŠÆœ1ø/—¤Øíï6ÇGž4ø ¨—Y½ƒ½Û¶<Ýš–­GA±Û h 'ƒ¿PX LJ„\Š/Ÿõÿ)I£wcA!ÎÀ¸,¨£ÀŽkÊ:Dpöx ÍbŠ×GfäÓ‹->yçäàßìCX{ô€ú”«× TDÿRíBÞÿ ¹‚•ç•q•:Sà㜤} XÀ2·¨ç´¶˜T¡^;1¾¹ùÿX¯”ÍÙáÀ?- /#l˜f"–xÂzýÿu¨÷­Àð|Ö0¼L%ÛÈØR¹5á‚€Èì¼v”gVª½_ƒ+¬q´ß/¼†à³N÷\¸™*™9y²ëR®°Ùx®ÜFÞD x·`7±Ù9ßþ³FüVÏâï7äZáY(¸…tTÌ`PdÕ”*›:ØYYîæ|ú~ùÔb¦:bbÅ8¨|r‡ütÛ–þ»™€pâ5~¥Ÿ@Ø^@,K£i‹›3‚ÁNµþ‚j”…SMB²¾.üç ª€nÒÙ«Ø()z/ þ;OŸêjTñšÂM\À(s„ÐN €÷i³ô¾ Å:õ`þN}aÄÙ&¤©ŠÐ7H=!böIzJ–´t4¶ÔrˆƒJ!À?$$kv­×„C¬Íø0Ä_e¹“‹éíòÒBÆ:âð1càðɯù¤î°ÉaÅŸ‹"ºv‹Á€T=\(èCDß-˜+&NáÎ-ÇÿœÅŸ;CõkRÔ°q¤»¹ù¿ìˆÑ!Á?íj¯ìm‘DómúÕÿMUÊ–04Ÿõ+Èl,ÍkáÃRò’‘£¡÷+ˆý= Òúøñ®i±Ú‘ÕvÌÿÍ©¼¸˜û3„5N}‰påò†ÄLÔ Dë¶ÿȘעó¼XÈxÄ,ÖâÿjùYGDÜäŽW$É+:F‘¨Ú½NÅá³-#kÛäóóNS¶–ÊEôÓ–ò>?x¹½€܃J@¨Äâ 2BÜ +dĨ䢲F;X‚‰\Ûià‚söAüÇkQX¤O­ÿé”ÐáÃjcglÕγ£.¯,:G[ :‡40\ÕIîJ„²ÝÿÎý—Ô HúÛà¯ÝÀßÙ.ò: pÚ$80ãšÇ®{€üâÿ®ÀO£Hˆ?6‚í… €Q² à='ÌDøß-Ÿ:‘g yx&j¨m—Wæ¥KîDÂ_Ú°§NëœÉ ãa c•Ù´4°5Ÿªª,Ën9þÏöʨ=Cú°¯AIãÐ&çÿÎáãC‚¿lDZ~ƒ?µµÄÐñ:Õõz£û[À°|Äúp¶€iÑFk]»C ÞÏÔ}×ö~yn QCCšÓébË6÷¯¡¶ò{‚×qi¾U§nØpáó_ðl.2]Ø#šÒ¼o+yô±9ãnyX¾TBV\Ò„uÁ @ OÙ}TñX¡æ{¡¤\+¯ò…¯À! ³ýáóûD׃ñó¯^„Yßáàʳ:ë èÃ5Ü¿( LžFóžàß)aI^5gæA<“ûŸB ù…å¶ÍÅ».rðçš902”oò—¡ï4ÏN¨2ø+Uñù+ñ?‰ yŽ×ƬٮÆÿqµmÉ^Ñ”Àˆ?·ý—Üú)‚³£.Ÿ3ƒ<¼ÚË;²K~ªD +•ôÞEÅPäóY=ãˆÏM(×/2?¡9çNÉq} ÍKÞhßZüŸï¡ûIí@0¬@dˆ?D—áÎ0ëÓœ”››ÿ‡ìˆ,À_Kÿ•¸UÞü q–"Ö­Õ·BÃñYŸÀ­g1¶t½¢YWdvp×µ½_ üYO3E™ôÊ¢]h2&YýÈRÊzÌùõ¼m£V¼±Ýl;~®ðe1^ @SŒ B—ÿ Dár j´%ŸmûöŸˆÖ+RÀS{Ì4–ÿ×`ýŠH`¶BϽdïíP(H^X6lÈÇV¸nÃŒà/ôÀ·O™.J¬¦¶>ά*SØ©ÊìWõ"”:-e6†×q(‚w™ÃÆÕÚ^ÓFü N”ÜLÑ&‚àºUขJÙÁ½ÃÿxªÌƒÕ5àê”7àõ1gÎ6ZïÛý%¶=*žvÙeÒøÖýwþ+¼,˜e-ÐÀ3˜äÍͲNá6Èý¡á‚é\»ø¿ñÿâá ñiçÀ¶Iš˜&Õ¥YÿýlA˜@~Ñ|z»¼¼¤ÍÊþÎ þ;äs=Ðy)×y™G}ë¾<C³Î8'®¯û.XáöTÒÀþ=0á¼0 Ð-Âßöþ9£Mâ”N€ÿ¬nüó¼é v°úáùÍÍÿC‚¿(„ÿª àëÒÿtê·,€¡øˆõ€ÀÜÌàÒN¾æ×l›6gº ‚ûjÏö~ùbaÞlî/&úsÔ°óºKÁ$žÕ§°T.ÌÓZ»„k62;ŸYÐaòXåï“gZW‚Šˆßÿ]ŧæ|ûOå Øò÷,½âãºü?(l¹]fß2à#øbm»|ì³]jeµ6Û&/­h^?2Ó8Ó*U«ÈQiØ9€UõüKT简…¾Ne­¦ƒ!s/¬Ã ° ÑTÅ E@D×­W†9^ªÀÀQ6øoß(þµ]H…ÔÚ”+dIó~)»çlºÒîoñGùègýŽ©ô ¬.À}ƒ¯Ô.= \¥…·¢†@|§fŽñb¬ÑÍ…›ÒωI—ò'Ï^â”Àá @ö½€6#”û^¿[>‰¯ïüs¶]^XQ„»ü#@.LPØ)aqàqX®(›¶Ä¬‚;¨Aú£›Å­Äÿ=ê3uþ‚Q@©Áÿðr¿Oø§jÎpÒúø&çÿ¡À?i‘E„"ƒ‹| p=ñÿõÿ ž°eü?ÖÈœEl'nW¾¬WÚÎQß}DÊ‹sÕÞ/ˆ§Õ@—O—’)B¸‚a# ¦Ù"½‚€³yK³l|LÊö±þµ,n§ÄŒ…Bô‡6’àð¾a5ÝÞó5`óÇ\í,e(·AþÙöÕM¶v¿åÍ:âßRu,c Ù;pâtÇì¯é9Å“™¤út‘Ní”gu`þø¢t¯ö“ŠÉl;€ôy~cgQY€y¬Òëýj€9ª°kÒ–ØÄ"«L @KÖ(¯án–åyü|ÑÓFÞ_Eü'7Ž¿Z„$*Œæ¬îþû¥ì;Þ¶Sñ„vA¯žÀ©ú¼êÌš¶Ÿ×¾0tÂË„ þÒ]‘G§Ø~Á(þ/ ”Xnv£ø?(]î=Í,éQ¼_ºzN?ÎqÐÛsæ”AZÖ8à?½SÊ‹trD®ï@ b^jO‡¡<ÐfÔ fß#«I»¸Wé@> Œ5ౢÃ[‡ÿ•^‹FTZ¶†èϦù¥v›¦¥”’Á·¤ÓÍÍÍÿCÚÕ2X$ÿÈUø?Òxô,@™[xœì¼UTeÙ¶®‰Kàîî;îî»;,ÜÝ'pwwwwÜÝÚu[Õ9çžu2óV>d~¯kŒùòµÞþ5G}~o÷а€ÿ ÿ|ܽC‚þG;þáOÇË;Øï·Ökäk sË»¤öyò|˜÷\ón ?Go– ÕßAœ&Œ:ú48³!ôpYªbK#_ Œ¯:ªŒ@ûÝÆà7çt{×p1 ³ÝS‚à¹!zòúœ7ít&ºldÓ/5¶{œ!ÀlÂ:¼C’è'vø­éV7-À’ä£|àI*¿V~L[Ý…‚ÁN…G¸öšP§‰Gúœ€™xû–Í/‡+Þ6M¬¹Ú hAû_ýRç¨ýeeÊCœ—Ã/iÕgiÏ~a¤² kœ¯V›&‡AÄ*Ù .nÀÊÝÙƒdw &Uh½³­š:yBmr<Âøe,\¿{8]îäîW<þå»AkÉ .Â$P,{XPc’ÌQ2]Ä›@¦¡*tãÜw,Ø5wÇ²á†øc½eohùÕeg<ÐmJ",í¢ ´fW®¶ ‚áõ¦ù§RDš|èu. ?SJŸ¾k[·úðÀé#Cï—›àóø¸G?°¯ŠJ'ÖpCx‰ŒGˆÞK4ÏPÈzùêY‡ýRMP¤Gì#A§ÜÙEñ0¥8wþBåP'ˆ°’™×ßM‰Ó¬¸Ü]nÈà$èø}êyKlÓɸHÆÊ~ŒÔò<‡•»À9h`öÑw±¥ü‚'ç¼m/i²ÄvÈkþI—¯*ñÃ?Yù û2ÅM’AK4T ð }O†Q4ÉV×´nBI ¾h’¸:X…ü.ÿBÀ¤tç*+Vã¬#ì¬!ÊÎ)R#ñ¼]ŠÇfºa»ú$äÀ#fùl–º#Z€ðlõážÌ™žÙ'Íi &Ðàj°Ïh'îéx¤rj©¬†Ë)ˡö8ó&ëæAµóP°v2,lþæ–Þ&Sf#8APà¦èÒ…v©£¾Ð-C^oÐKÖKË'Jïm=ÙoLj¯‡“dào&ÉÂÛ ø?Üó.€àßZÂÙp»¹¨åàã‚«Î×-[>P¤ªdá_ÌÈqúäÄfb8VD¹ž©°`7rŒoÍ|D‰ÂhogìˆkJÕÓ‚üA/~íai°øcáÞFˆ/Ýýäå‘mÅ[å̾’Ó²NÝv®OnPmÊ3ž~´9ñE¦¤C©·"y“Á+°‚Š`ƒX \;= 'Щ¦Oºï²ËœÖg‹‚&óýŠ•B¶rÀÀÿDbmõž@ ž›Ôûã)4ðÙñšØ~^4À/°êßÅ·‚‹*Šœ»XùYuŒ@@¦õù‡°'Þ}*ÏÇ€ÓûƒèîÄ7ËÓù&é€7Ài€ˆ ÜÊ+”TåÑ=BY´HþÁ¶Ɔóc˰×ý®Õ™‚þLhôB „ÐÌ.Á”æl6žÅ1Gfµúº Ç@Ao±¦µóu€Ý²,›ØJ‰ºf'欀ÕA¸®Á~tmÁè .TŒKIÈðI®û=Œp J¿UsÞ!œv~†ÀéXŽ’cÖß,kºja(5¼ÓР±zïÄçàEâØ>ª½½ ©±ü0I;ãîÕbTªN*?‹À¾Ì;¿œ¨Vò¾¦™"Õ˳^è®§h›xéðœì^H4Á ÜÈ3á°ª80 7Ótñ'˜v|ת9aàÈaÎ¥%¬uÛQ\‰›×‚½OE·7‹ó•?ía–S/ÄÖE|áºø}þmU ›O넨vùÎÊz~¹ è>zGLmŠTJ`ðûu_w¦é¬|ªSbõ`¼ÕY„/ŸG✢åÈÞ_IAw'×m¹ßÆVîàÐÉ{$)ú­–¾fßÔç@Ô+/H™Jë¼ô~ ð{žZÑèãýÔÇë F *nF¸tâCÐÙ6ZÚL8XVdjxO/bmoE\ã˜î+™¹š2ð;‡‹X_vj!ñâ¤Gî&)1øá<ý$Ê~•­$9‹ „ÂýÌÃb-üéü³ü“û^k\Ž=¬¨À’|ÑMéûf9žÁwê’¥¬&¥PöÊIàIøÔÉ0¾Ôoƒ)õ“ö@îï]ÿ½ÆÈUÔ"Åñ@Ê.¥wÍIjá#eÄ* ]ø/ÒÏSd Œ‘O Mg¿"^Ξá¡þÿóôñtùÛþáOÃ×=è·ŽmبqlšÐz5s1¾…^¬F~™­_”iaO£K Q3† Hû×_DôAõ(ªª0o¡Á;¶ùC/ËB'ŒB] [ Z…t Ðr³6È‘gåç>«ÌØ ¡PáË 4rÖ…óŸÊäZµ˜þAÉœ4L[™¤ÒßmJê5%áZ-¡MV&œ@xýjK¬ÙÀWøÚƒ¶õÝÞÓЭaÏÈZ+ÊÔ#¯ _¿FFsrÂÛ¾!ÙõKÁùÐÀUp AÀ¸`¶¼Å®®“ªRÖ‡_¨¶8冡»|s– €àü<g@Ü*‡ßG¨‹‹+GxW6×¥è1lÖ܆(G9 ´ÆÄgñuP7Iu½ÎŽ$üâvá‰oI/ý0à?ùÂB)¯¾XP=3p„ëëÏ9t:Ã¥p›sXÂꙇ‡?äÑNÐK.™ÞŽZvÀ'N¥¨Îå:HZs· ÷)ÞÁÁ™ °IÁ÷P±º½‹dlAöèsŸÚùYÞ‹­ÜHø…ËÌ×^¤Aój½zäZ™ ô?µ¬¨éâyOž:Wg”0í‰ðû{ÍŸ8 —ŽT"NüàüFÌ"‚%â­›cÙ}ùè–¿#¿U&!N‡ý hKõŠŸdBÚïg_ö/ÿú|R¨­ ©£IßXx]ÍÙH}0iD=R4À÷dp:Ð~TX·,„ À 2xQEAÂÚå ÕÓ¶æê,Ñ­ûÉî²wºà1Â1âkcžú]¨æú¨«'çêÀiqìá}Z‡ >€RF1H× ®cbÇócÉGüz×êET:Ô.ËÌù¾bµÉ¯ôa˜˺aµ`'´1ÀÀû>YÆ@Vã²²'+݃ ??¥Šã(q™èB 5÷5í…VŽ 4ëôÞ?KÙ?n~Ú{2• åýY7ؾ… t÷ÞjPÞc€¹xWÛÁ; xÈ£<ì:1÷â dèÒ}Fê|ú_þK)Ô–iÞ­³ÍÂó¾þ=íŠWlÍÇ/ê@R/}9)N^›#Aé;UÌfZ™>Y¨0 ndJ)@¹0'YƒLyÂ3 Þ»«î¹L„½\¢”Àw(2ÞVüŽÁ¡ÃøöÙh*“sm“ *Üf‰î7D¯LHšÎîÐfÊÉ' 21õaõX°ÊØòŸª·º{‚3?‹0’Q¢ þÞõÿ×û/ÍÝáΰá¾ZyÛ¤2– È„žùÎiÓÓgêj0€+Óô›!âãîù»Þä}=<ƒ~ûúþÏáåò+تĦ˜FàŽŠ«Ù™¡…‘Y”·/NM4rÝwD¿…ýk¯g8;ác©ò:Vƒõ›nyn7rÎYfXðYë…z hl'Vœ_ŠüeðÊùM#fá!¾Øô×q¶¶ûL0ܯ}/˜¢Ú“±ü µë¥’wñ=š?ƒàòô¸áZm¯¬ÒœFUä?;:‘ÛBÁ×iïÁž™?Ë—OÉz{QóX•­ÇêôÏ+l‘άPß;8]ajÄ©%GÌõü6&ØìÌ~%9ÑG cÿÀJ†’——Í3r=‚­±ý³s'XùŒä„ü1y©¸·*Ó%6sx¬±£ª‰ük×È¡‚ôÐÌ2Qð^ý½£râë};|ªœmHC’ê³V d÷–åÔïu™×±jI}£Rد¯³„ì-Ñð‡öáÕ.1zOF–§¥PœT:ò½îÙ5îå5 ³hKüû™U"‘ËDÛÖîšÑ˜ÈHÓ{øÕ°¼Ü½‘b…ïKGXä£ÃãµàYëšûù¸Âª„BÉ+bañ*ªaµÉ ܰuŸ¸M%>B8}¿Œ»Î/šU]·è@TQ[hæ:Ù)S]¾AÖù‹Üñ¤Ts>1‘ê „W=Ä]êÑÌ•"Ü2›DáTdŒèRø/ÔWB¹ß×+yÍɤ|Q?˜Ð­ê:Šl¤¢ëLÀ%o8 £qE¹Zcêš7ª^k‚Jƒ¤4+T¾Š‰Š/q¸qRç7ëP>ò&8`º’Z÷iÍûŒ@ÙÍÓŠ=8êËU?Ë/û^Áí±d»ZÝ¿öäÅ·VA§‘ÑÆy "pÔ™4¡ˆ45wxӉДÿ¨îþÒnñ‰È½êo ôãžÔ†«pЧDlþÕ´3'QÄ$d$\E,++Å Bº^ëSd"êòÔiMz­cö¯Œ\>Ͱ>—)z „A$—z<ž•Ä÷-^XRu­$™ÓgD看”7 Ǿä|³ àÖÞ @ëTÌ è¶'¬ò$ÏŽz#žªeÉY»³‡>Ìn./ÍW_%ðbS@m;;—N‰·•jË€úˆFPËÔ$x3ÝR„väXó!qaù(/t[€ÖÆ<ÇÁãÒî|6Μ¯•i¼ç7…/öµHB¾Ÿ+7ÿz‰?¬ÁRèE/éÆeÈåÒZg ¹Ö¤*hÜ2dG¦»YüE?6ýlÇ׿šN@ ωÛ•51Šœ®íÒ¶Á·ÓúÖiƒ(^üFõÕoÀµÛòâùgö÷ÚéRs EFîA Ì¥KÞBâ‹9oìþ øøy7‹ÿË4Oq0®•-2#ýÞ³äÙQû2åì†Ã{ÙñJl•$hì¤T+¡¿Åñ5 ßÝåޅómúG(¸sø&O¨ìÛŠLOÜnÅ]tŸò!„ IÈN¸ëI†ô]ǽ©ÿ…[úµšQ_¼7¹æ¹Ö¾Mf`S±š•£a:àjÂ)-î!åÌ)3?¬4ŽÃ¾Þ¦NFÿàÿá¡1L¸Ó !ù”öâ @9Y/|:Do,>—è²#ÿ”^'Oož™A¹¢ŸÿU*8Pê6$ÐÆÌñ?øgL±‚>eƒ”p½Eþ:Ž™Ùú(Zfäô>’f{gVÞÐàãeZ“ÑÇ­n¨M >Bi–Mxbi˶^c> =H‚.†,—A—ìUS´L¿AF¨„Ö»‘, >uªËLw1á2•H”å.¹•Líè )ÄÂYø¡œ|²y¤j‡¤Á÷óÏða½¥S¨ãŽÇÉø9YUgVHb“[—JéÆÉûMŸçÔ¡jÈ VxçE޵%þÊöq ,@f/¢ëœ¸W0Þço^ÿ­K©.½Ò$¢-6¹m ã-!Œ!Zy¾L–£ 184*ÿ§ßJW×àˆÿÙå¿ÿ7Þn€Ðß¿ûþ ¿ÙàÿBi’r)©-¶}«Ø|u¿Ý¥Ý™¥Pu/$6ê)ÆÍú¯E•:þ;l›¿B^q@ð 'Ó, @ÆîYÚ|¦Ö'PÆæî f-T'¨nx FiÓóR+GžËeHæ˜?Ïàµy7oKu¡‡)¶Æî¥Ç¥é/¶} ç–^àé–Jñnè¥"?ΕƖ~yg8Gÿ›j÷Q£™à'Ò÷7†C'-£SoðÀ[Q1z6çÚªÕRÇ…ÿfÀ‘ц#EÕ8úª?à­_}è'">Ea<Üfœib³ÝpJ̾²…ùçö÷ VŠÅUgË}ÿÔ§‰-ðùûýçæÛ«ÑÇó¡‹Ð†ì¬C¹ ûܱ& o4 ¸  \kàíýQ‡’L¥Õ»ÊØœ;²æäÅ]Ån°é…»Æú¥âýó —[HÔù6ªëa(nyü€¸‡¡%-@šBpö‰„Cª·,t”X&ŠFûµž¡:Ü4¯?ÐR+™g¹1²(/÷rKå»,I«È*¤k§ðƒÜË‹çFJ=¶?d ° 'Ì/l78Zzð¤ü}gÐÈ °«¾uåVÛ»V¨äýÕCÔ.´6ñü§Š†=—*^Gús.Š8-^äÅ‚ã-‚iñù}­ƒ“Nö6k}–ŸÖ¹’-Þ 6hbhV…C>g˜U¹j¾Ëq:d eüÖ;Æ#uÝA±·]ÒŽ”‘¨µüvº{C¸/bmgâøO~aÓÓÛŒÜþ >H É,fÜ΢>~˜úJ¥ R¾³¬±!¾S¯PY´'‰vsÚäƒ2<ö þÍfÇ'´ElWü ѳ`vä…M9ðµ­@“+PŽ(ï¦2µWÄ7ª {Ú^äh ò†0XB–-Nz¤ÖÆ9ñ"¬C;ͪ|M±òÐ"Ž–Qìr7ÇÊ|N2»<2¨ÐnòïbtAißðž„2| $^÷b‚@ÅByÁW±naTP#DÕ¥a@~ëü¸‰ ï˶£cþæìPnJ¨Þ  ÊYÕÖµËÆÐÒXݨƒâoCë/|Kïß…\r’›tiT}ý¸ð#£+ÉÈ6‚™Ýl0ÈÿãþC-8-¿ÐJŒmJ…¿xÞP”ä¤\êãÇ&ñ†N!ÿ2Ì‹ŒÊQ$¡`#nЧ1Á#+K¬wÍ͵ N.2˜ÒKyi¯ Í‚·ðÝjx‹<…fíw'F/3¦þâþZD7Æ;¾ÕnÓG'¾Ó,ɱCKè\00F߰ȵŸG$|ˆxϽ›$¥*Ð'fQŽ….ò¯ÜdvJ?.°8):?è–,;n˜¦í¹laÈDµ„¬ktÑXï§µÈ*¨‘‡]«Ì-q=Zo‘ºÚJZªŒ¸€IÐLÃlñi û%í¬)Ëúý׊FxßJFèØb!å&ãX‘MMl²­â[vØܾ—*2Úû=w+kY>€o©—ût|Ü%[èìv‹µ½Ý8ïŽ9µ#¡atJ*á@bi¦Øà¾‹'qFo3U²þœ"ð šÆR/oÙs5j¢´XyüâŠÇª[ðàØ?¸Ÿäïc4ý‡ý§¡‘@+¦q¨”kâw¬F§“ä W#‚òµ¬‘·]~LN¼¢‡Àµ°`:¤ÔNA+öF€Œ’Tû¶¤3²jlPt§ü½ëÿ¯õφ̙»dæE¯¹:»~´J“);<»çO&9ÅÅ#øùñ;fÿþ3¾î^ÿ\øËø€­'„)‹4T͈·Á»¼V:ͤˆÐ“ºÇmãA¹p0)йRŸ›­(õÃÿ"ýÐÓ*AµÌôe¾¢¬saÜ g£ –ƒªnèN¡0o¤¡V/1$³à®·ÚD§ª,#¯¨³ÛýnÞï‚*›L\‹B–Ã'~z8¦qÑ΢³ ý‹‚ ÊðÍ—üÕep¨Ì+u²RÖ­>BJ>U³Ñÿú]7 î§õ…K ‚d3¦ò:íÙÀHnù@Ña+ÊNVæ<9:µ&7òý~3k1بéûÙ4À9ö2âh^߯Fþ’GÃA·?S;ãá®Ø$âþ#ÞÜZ¼®Üb^bÐà‹ÔþâìäÄCw–IÅÃXF:.tð"ÎXÂBaÏ/Í|·Ü³q”;Õ7 –8aµy–„šZ¦Ž´M„¥Çóü¸º€ÆaUF¯_p ÇL³®ö:µZÔÍ<§”ëðÃIrfõ8ÖÅØ› mI¶«rIz…ñsX¡ûJ’ ¬ŠXÅ#ñ£„¨U_}0;^$Y܇J§¸^«ø–Æ©ñÝæ3 -ÍePU¿Kè#3‚º8΋Fã¼Ûí¨®ïŽèX?Î;Xš Õ+éÌšæDŠcG® ÊKéô´xc÷õú²À&_¶ËpG® X$…zòoõÞëe`ø—ªÎ¬$èmaë_öY\ôҶ¬aü)þ; 8Gv1Ÿm»àâ”zΔèd—œF3£¢Ý>_C+¬k( [?p¦t*ekuÑO Qã½™°žo`Å4­“£6y”O.e¼$cjâ±Íx>_ä@Ÿæ2ï_à‡È™çÍVZh…Zo-¬ãµi*]~U-dù'=Ê#‡5kNÁîʯfÿDðki“àJ8 dãµ´±’b-¯¯¸Jo’ÙO¨QËÃI˜5£…Úü”~^d¢mU€–%ïR›¤a„S«úyYâßo¢]BªØL×ë#ä.ˣ󞉽štg2[¤–· ýŸýsäñŠ®z®Â¯l¸¨§©XTè æ‹AÛ,V$¿ÂE¹¹}7û y¯8U{`™R€F%ÍšÂ6®¦?¸šA⌑ß+ûä;ËNרlãL<­»Á˜”½‚h­/Éó¡óx9 E™Ü®ãô¶NÕ6”XnÔÀî80XX`›ulüQÿ©^„ezUö?!¼¶LÒÈÓŽ˜có§}G•R:/侫°áAÚO|Iê:±ã°ã⨣¬·.Ä›xšå:‰7_jóÿÞõÿWú§ôºmM!x%$–¹=tR~ºöýÜ=`!O!46j ”ú÷éñûfÿþ3>n¾ÿÌþEüF  {4Åí›IÑÙÜ8Q"v~sq~cÜ×—†±PŸŽc®(/`‡ ø€¥‡}»¤<}þ³^Eõ= ÞŠg+{¬€Ê(-í5_Wf¶:ÆŽJ-Hœeþ$¸ë[¤U%|„¼ýI“I® ÍÀË™ö‡ ê•úË8+ä¨ß÷IA̤§Æèä+ˆ*û%H# V~¨°o<—ê¹_JT7ƒÞ•ÿ.†Tu­U»9H< ©*òëÓ¨„ÇCsZUìyï÷OŸ÷Ä1€šùý¡<¤ÀmƒºÞÉ´˜ž‚äöÌÎ;—ì§ÎØ——é·"àâ¢"·3ãAÉô7^D¡uJî¢{v_æZÎ%1ÿñ/¡ÝÁ[7íëî®ð÷Ü[i&Ñ÷¶¿S>r@°0^íOGTƒáÂ`Ž{pCÅìÍTšÆ¶mü˜ä•Ž8A”YÃq£6Ìh5^âXè š±«×R° ½­sŸÝb8éä tS¡LùJ0Uwö‘X;’þÜ’°"’ç̆þÞÖ¼ÄC·ÁzrŽ–Bƒ[¾ù\—ÀD“(yðÕ¹!å=@ÀçOòïû~fY¤Ù-bÔ<ãÇ*EÖ`ЄÉά&‡yضRÌ‚½Õ] žn…uÇ›A¶)*à¥:Æbd ìÛóÕ.g­dü±J¥À§õ›~ÔÃ[ˆ{4&~a¦víDpåz2ˆD€€]{S³È4ºQhSÿvLÒs´øúxøÂg|šÏ•b>Û\nsޝ*  Æü=|xŸì5Õ™Hö(Tj/‘DÆïApÖ?då{LzÚí3´ðr‡¡ÉJ ô°£BÑ¡e<„é¢Åw–ÖÍGØÉ6Þhr$«SÌãá…ey[Ú‹€°ñD¿ÒþÿVØïs²·SGÔÀ¥X:ÝdêµØÜ5“Z.í¤Ò¢± ÜÉÁB[£¥eÔúèUWàñ2 ‹ñ£ZR: þ"ö8“ʘ[˜‘4ÚÛ/‰èž–`.¦0ŸF68ó΀]$mïS,1<]s”úXeøn…¡¨–‰Vi>aî|*†Ä­åv}ìq?³ ( Ìm±ßý……¥(PDòã;–Ûf™Å#üñrÇ GMŽjÜðP÷ÕªÿZ¨2·nöf³å¹ˆÂñ‰‰S¨2©/>7€¤ª¾—™¤^뎅jÂÇ.ü0LJãR&_V)ïG2‡œB¡Ç¤7t¯õš.^‡íPR½CæÞð€›H&ï†÷çú3ÕnU^'ñ-±+\¶¾R³†%!ÒÏ3=˜v;ü±Žð̰C†° ©Tqõ~œF·×@œx!ÅH|Áþ^άÅ"Sx}¨ o<ç£×L£öôáÚÓ:=7R¢q9L†m˜·þ‰Ö¬U…ðó[÷zIÃ’ —ÔÑ~˜2Æqñ33ܾy¦ïå”ß>ÛÞ7q­÷åæŽ~Äç‡)Ø–„% NhÕ*™Êƒ¯õéK¤B±éì)¢³øm,]?,‹ é ŒD<:Vo˜Ë³g÷‡4žå4w0 ‡sS¨;œÞº~±½Œ¬Óܶ{ÖÞ«ß7ż’%î9ÿ3ý¯É*”‹õë\L/e¥+t~ëYŽv‰•Š× ™ò¼­óŸÖ(#rlG|Dÿ¥³•†Cøq]Õò Uªl­t‘ë=ÖÕÔ¦ˆê¸1ªßê¹pò:g6`û(óÙ-N¨9};fþ ÐLªåBó5.\8Þ¶!†%û>CÀV›úK`©´Ö§£Iœ+Žá㣤–عÃ&ûËðR³¥Ð õ­Þ÷HÑSÃo“¬+f÷¶uO®†eC”Ú’Š$»–]tL¿º4Lß¶ÙÂÜwÌšZRü"ipEfö+Ø/“¡¦ˆjö¹ègŠDœþwþyòMÆž=û0ô½Žæµ^ø¶ún„na˜¹´àѯ^©Ö!`/†88:¡ÃmÀZéqû…P¸Óô š…AÇÐoÈ-Úºð“ø(ÖRàùØ‚o ok)ø³¨5Khé&©›÷µ4óØM/×\ª@´&¼EgM™žcÈ”dvmé…3"ÉÔ÷AÑÅJmhöS½xoúÄLî².TÍ"bó°3D ÷ÀqáˆÇ9¸…Â,Li˜½|•nŒ„•PcÏß»þÿ2ÿÃóU¬Ø¸h‚׉?͈4éßšaF|¢Ë7Þq’wþ]røz9yGþY©íëîü›Ÿ£û‡?_÷3¾ù^#ZGä)¤ QzF ‘fÐÎÝ1‡)!âÌ­qÝ“î‡àãL"1 —€Åt) ÷9M²7¨÷µŠB?ô@„Ðg9S?ïÔÈ×ô슣øúFÞñ)drƒ\™Ëá#dÊœ÷–HaE4'{{®}êÃ6Ñm‹ «OSˆR]‰?§ž<«]+œWÑãC b*ëæR®¼Ö‚¿Ñx&æÕ'7£GÐ!Útëì¶?å5‚'Îð·%­p:F*øÂjè®÷ızâw<5æ¾;‡)†+5Ú…¨¼ê;²º\þMÉz!ïž¿ÉæcK\ü|¬¾ûz¬Ë%|ñáä¢î=çóö/8äEx#Vœdª|´ð/c­êG?¥h³È¹<–õÒ‡ob®¥“(—l´[¶“Í’û«Ì“=lhž‘M"¶»¼NÕí—öçÈÌ~Æô¼lÞÚ¬ý»µ¸³Ä±€ !å/I‚N2•¼Å|0_¼cן­©Ué—•§§§D”*Mb&j×aŽàRã"¯¼š7ùI4w2yÊÂJz¿M}I–¤7ýqRú.[W·úÁÀ ä£à‹#-‚ùd½ ¾€Ò´n}.Þû`ò¶$9OþàýѶðG×l('¹u®tԈ܉٬˜¥­;°;š‹ì·˜]¯#PÏ0 ¥ô v.È óƒÆíqw§hák®(q!–Û“÷ûz½“ŒˆBi7޵bÝììp´DsfÞ¯e¸L(ôÿ{ÿW\ø ÎýaK0nlCQβ\B>@µxO¨x¡¼÷‹õÕ< ¨í-z'&Ýݦ1 =¤šö‚³CdDç ©AÙ=¨UÂÔÉ] ñiٯ٩չ7Þ+a½Ûj82à›K;l8o&9Å[cùÓ,¯­#ûçöRVÕÝÀÿÊ2X«­ÿBæÂ çÝРI:ƒ“OuÈ0G#Z¸Ü%ÛÝ8jb ¯ ßS‡ W´/ CvÌh.v첺"‰A±Jд’Ü“½ßœ Öéï]ÿ•ÿU§éâÐã7ÝÀx…K‹e<:`DÖé\á1fw¸ä—>.®!`öï?ãíþÏ5€¿‚×0ÄÑ8ß$Qžuþù5Y±±¹#$¼DÅrW2§özü¯4Y}<0f'f\=`ÀKþÐlë<Ìîã 4æR2èx¬bìÓ|"`¡ÓÈ“ø" ã쌛ÁAƒ_{÷unÉÁNöÚʯ²_<ôù§ šÈ»¯UÆê×H9èh¤¸·¥Ñ“¢.8Øl„ã@¥ú©Aß:ø¢žÀ#2=4àlØÚ§pÏ ú3¯sŽñÅs¢×¯A[ñ(€žu¶2CìÔÏ(Î<zÖ8Z+»?e÷Þzö ã“ßÕª?õ÷ìÆý´Áo»=‘j0•Èþ´4<_Wi¨°KŠXs³:ãé-zÀMÍÃ2o!Ÿ£’ h^R…–Èf×Õ(޾u©> †oj°4¯°Œè¤™ ߆¡^,#«i$ºtø¡?jןÎÍrZƒ@¬i–$Ÿòp/‹Z[mEˆ!Ð à Rs¡©ðBïi w¸'†?œtfr‹Á5dŠÄ>ctŒ2Èžˆ?š å0,,l³åaÁóÓZMïåÎü¨Æ°cõý/00çÅÙéI®›*¯éo7CÑ4ÑD‡ŸÛY' hŠ@8ãn冸Î¥¦‘ÁíÌOﻃMØEœ0+‡  - ÝF:²„ÌJV¿ª¯h¼ì©.–Ø0éó§’4_ëF´øë&|xàüéþ‚ßׯYüs†ífסñ£k‰ é¨òeDƒ§§@Äýù(•›“ña0ze(ÐzÏØÝwÖÞ|OÖ ÞÖä}?KígÆ’Ñ'ÀqÜ1\Ø‚îU }ªˆKÊüPëT²š‹) "iï.K(„LK¬äüýè'üN“†ì>(ï0 ¼Ø«ëí¢È!ïË÷æ<Á¢ A_óE+ÁSÅ 6)š)2#³Û1r&fYh‹àQüUP±-¥Ã&L>e‘ŠUØ&ùɰíÞr%‚H>¥ûGŠ÷ãªSbßÊHbEô"p¼ÿÿ¹ø½g:# RÖïv‰?NªbÜÌË^Šd>âtx0—×åc¥Ú5z<¼ä¡AkfVœ™Š“ˆà¡éÆüdËj)À÷;ø†«iuTm™RiܨÉBxíñÍ¿iq3ÿ$Jšê…—‹^ž.ÕÓÆÖGŸšrÕXú.ùüïÏÒÔ(s*Ê<›è¡û×}Aµ: 0³ö]£ ‰Äñ³1éÛƒÔÆSù xQÝŠ_A$É‚£‰o,YM¶S…©ø—ÌÚÝ yFÿÞõÿùWÝç Wî@ÖŸÝXú,“Ö²²piµÄ®öF‘$Dþ7¹áëéèù‡fÿþ3žîþÆm‚øŸáîÿß~„ d«™Ã[zJ1„áˆ,tÚŒݪâÃÈÜ’èÛåM»Ä ² J"[d“7ìüÜhÈ2ŠqV:µ¾u÷›Y†)bégðqš¼ó£@D‰QØ ó‚Ö­ ű% ~Ò¹¨xPjìÐ/1ب5濜 :bêÒ"¾L•5GéÓ^=œgr9«rzÒɲm´î‘TÓàùáÔ9p_nû†¨?˜¸x¹a£ªÂD\3ðš~)GƒQ“èvys]èq9—<㎘éèjºÙ÷òQÆŠ©Àò(ì•æŒ°&Ýsô®’V%¼\äl¡¢Ë@Þ]õ­”aÚ ‘‹ÒX?rƒ‡>pÔÓ }J„ Å96œqàRù¢¡A]Õ›GœšäÝÀ-èuÓøUÍû¶H%FL°‚¼Ìa{É ’Ýv~S£)¿#3ûÏ÷oWOØ HábŸ˴—Ïiù2£™$VÛªMføÄ¤!îÃxˆ…ç_·hñE³'îVÁÆÎ° $ž½:AŒ·£WÉjyðõníÊ6½±Ê¡ ©›ƒ+NýÐ}{S˜Êm.ã>*a‚]ìÆ7f€/MËÈUÊC/ì‚Öè¤ÞÊê ÏhU5–GK®á×D›Ö ø!¢ôX•m}HÑ*lû+GB—¤¾çÌß\<µp1ÝX.«H#Ûqše½šÒxug-žÚ¬.ÑÝ*BVŸž‹ç© góΠԠý¼ nî n€7°*§1æyNÿ;ÿH¡ÇFבÕ++ —­|'uäB—%?Ǧ$Òs¢Ð÷fü†R¶È3½åNõAKµº1îO—õÛø2å~Œñ©X„=™U7céZ 3|{ºÅd‘x>¤Á2BãMî~Ô(žœ5Yi)/ 'Ñ;Š^+ÏÀ ?ˆeýnÿ2íÝ0€bü:h/ØB[¹ þ'H ˼¯Üà”Пxë“õ. ÆšãàBWã´}ÉC-,d¶ÞSÄ?¢¾Iù!çÙ¯{£º X%+@²"eËìý½ëÿ¯ñ?Àr`L |Uâk¿¨ÀÃ8ùܳ5R­¸à ùobÃÛÙ=,üÏë> üWàãñßvç ú§Êå¿Ó£‹#£«ýôUiÿå…Úd¤)X`½ 0+%cwòmCÑ\(CDqÁ¬†°ÀNCd«½8qOFÆÏ_Ó$ø†ª±<¨ÞLJ ‹/vå/qÕ×í|&Êï²Ñq¨¤Ð@«^£V6Ì›]»@ÉôBcõ÷*Òì ŸZ{Ë!Ö«¬J3تQ¹öTû~?ŸWy¹³¼—Ë‚ H¾v¯É9iàœ}½öÙƒ”xÈ0žÊF ÄHà´¦ÆÈ{µ²éó^½eÝÈÙ–úØtÕ=}˜‚=¡ïÃÖÓD?ÕßÅÀßö:³aÌW¹øþ¬ÜL¦B²)Çñ€h–¯x;;*ÙÔ÷øµtªO’Ä‘urŒ(ü¼’(‚’ÊAÕJ^ì ‚ø–À2ÈØö,sÓø£¸z¾Å–×ÊFg{¸Üm¾ïëwt/òHîoŠês@Xs!'…¾yÝIñÞÍ+Nr{,t$™£‡ü_ÝíBïh-Ôvö+ÔDÊWÝ"š¹p/¾¶èeŽ0^±\|¸ºyZì’²_[Ãbí¸}Y¶’>Фq¾;—é²fã|ˆòzôÓ±„Iƒ¨–#<.bRôEF¬ãÔ¢B(’ ž”1lÏ\r’¯`oaFÙÑdw¤äs™¸¡ÉcGiê Üc¦2FMv 6é˜5$6\¨’dáÛ=tUûöM¯èvÊ£¾Mª ó™ ïK>™’à8´iFÜØÿÿ“c"³è²¡n*÷¢ý>Ö÷ËŠ„Yn³œ1Ÿ© ZÔ2âò÷ß*%´ã¨Ê‹óüðÏë5s‰Ÿ‚Föt ²ëeeƒBr¤t‹‚Û·‘c_">ítIJ)Ô¬½À¾q€ÇðÀ8pI(Ø^cSˆ¥ù*é³´¸ë0¸ïº”Wð <äJ°A¶„U1— `Aá$ݽW¾ùr¤¬ãª@áÆš\NÍ;’@—ï“ÊU»Bd9FA›÷4Ô\ƒÎn£å2ÞG¯0ñ3‡',äÙÙÃ-þ¬ƒ™ÛpT¾“.Ò’ãz ê¿÷_ŽúYÞ>ã?W¼24Lƒ´Ò[ÖDµßÃöåè,µ¥C¾Ëyf%Îó;“¶DÅ CÁ©c¾¨‰‚÷Oœ‹ÓÏ1'£·Fvð˜M'31ªý/¡YÆ~K©9꙼ç/û/vÄ'YĽRÕe[‡Š¨•Äò”ê›<ô¿Óÿµ]¡48]%ß¹U Tk7öÄ‹´E#g²Œ–ýüô-“lní2· (UDw¼Å>ñŽØ²ÒZÍ\z«ë¾ŠØ×(¢1è©(ªÁ††ÙñõïúÿKü?ó*Ó½ÉÚ™íh I¬È`Ï+ <³Û³ÿ›Ó}§€?>û÷_žúÏ'ÿÿÇÓç¿ëŒƒš¢RžæŒOþº—dzí‘%k)e6¯ú×Ï1Æ¡£ú0ò“¡nŽR‹+>è5Ç>ªäøï‘óÒëçÆ?‰f<%pY/3”_Ež¸s_S’AÈyøá9¿NhĬ{ +ãUòïÏn„ƒ'ˆÌ¹”Îo¦ÃÀf0"n•BM|ÙÆäÚkw ž¿`JuóšvìªZ©,‚'°x|+Û×}ðÊÉìÍröµ¡d4$˜h'n&°ß•Ôꯞw»‰'¼¿³Å#|ä §jŽN’²…¾˜™Š±+Š8PåHµî‡1"EÎóÀDIRLÖEËweã ¨L¼'éßÍßT0K •0r‘$#êûŸNCeò£¢Î.Mh¶Í·µVE/ÆÏߘoR;ûú¾=Èø30‡«T‚„{©< :ÜÍÞÓ G§µÌ Ñ’j‡¨Å–ûc!†fiµN‰Å­dpB[ß:'ê–M1@†Ý±wõa»ÐÏŒC‹¹Ì{34«1®¶{¼5ÒÈ/ùs«f6V‚=ºáJ1áŒÏ=¼–iëZhºDЄذôè–»vŒÒìp'?°Ü&í×PÉè1aq¾`*<áôÎP?ƒ/ÛÉÑWj¾He/™–86žœLMwþí 2I·•ÝË›â:ú —ÝN Ý¶öœŒ:,ü D§ŽÃºÅ­8``E 3jdM+Úh Êü?å[ÏÄÚ–{"«Lªñè}øƒt¯9N8þý"°½&Ëq׬ÂÍìçK#j“P k#Pòž­S?ïg"’ß^`þæOÐÈ!l0|ÀÍ”´]DbFã¹Åh ¿ŒJNwt‚’2N?Û÷$E—ºË…B;ÕD}“zÛbZˆ„Tº¯o_o9Tóß$ý!™¡s‰QF[ÁW º ]ƒ?2Ф‰¡t@¤žÕöiÂS”Ò ŽÕí®Ü8?„$œÂdyžAêq#{»Z8•âp’Š3J ‡¹ãÊ B«"êcË]‘€È{6ÉC¼ç_K{Þ¶ˆC«rë16½†Y) âžÂ®{ì¡ï~ ÜÛ{懈±á{ó1Æ!¶“¬„êÊ¥ÞÈ©Ðû^D^«•èâäh@lkmÕÆžÈtíÔ²ÉdíBavEkOmaîˆ ­×§šÅbiÆö¯¬j¬ªÐ:ˆßéß•ËÖüN¡ŽN*ŽÉ˜ÏgÓ‰óioaC3IÕ†ðÎ9pÎ\ßͺŠ508É ¿·—×:íùÃðµw%Mr×ÙWÿÝ|pøfûâðð"Ê-J)A„…ÌÚÓÓµäV[/³c%Eˆ&dA)Š’hìƒ]í»Ã>øîƒ€ß’/+«º1bFjGÌT5ÕUYÙUùåÛ_¾þóÿ¼ù§óOþçó_}MüæÖÓ¯}㟒ïÿ×Ç¿ÿ{›þ—ÿ_ýÁ}ù‡³Oþã_ÿøÉŸ½upsû_îýÛ_þæŸÿý¿ÿ÷æ+Hƒ»¯¦˜¯|Çåvî›y 4´qZÇ­?“.Y3¸bíîM ºjÄ‘ M2|Ϻ'Guåï“/3p Òµñ^íèŒVùp4Z÷>OJº.íÚ?Vk]ü¶ýãûŽOFçT’í•í…þe>C‡á³Îª‚îœÈ—-Øñ-òIçEiù-Kã¢ÿÐÎ8¥K—­]Ýýx^8ß>,Vkß±_NÒ[×í³ã ÆÌdÙ¸„Á´…ÑÎ¥¨UÜw8¢L-¹®à~8™•ûÅ“|Eã@Ò./ ¸Î;o¥Ê’F^9ÇoiùíòÑØµCÉG n.͊Ъ $|ïÖ·^ ÿÝ=€ŸÉä ð¿e›ôñ‡yUð°ẪקðØÚ þ0(Ž'¡‹Û¸Ú9]`ßx¯‚?´¦5M\hÌ£÷iœ4pôà¸ÓY Ãk4àߎ÷`¥ vîŒ*  ¼oü£COm îÚ¸ÜE¶öîÑÇ»ðdù†àÿÅ$½}Ó~rÇÇäYS†IœV…Ì v.yüñrïÍévøÇs[é‚§?àßï¸åù¹áÿ1àŒB›Âñ¬×&~Û€5GÜÂãÈþåE§ÿåãodÎÚ0Õÿvæ¿‚&ñÿ•¥ù¥°üÍœŽ€—üÀçdb1{¥yOÄž\I­ýÉÞ¤C¬È,“ïmÙƒ'ãÊÓ…v²ÎwîÞ›•^2•g©+ÊqåÙGÔUûÑä¶r¦{qˆ[¤Û³ºèÎ{Óß÷YÊá5Ÿ¥èñ‡.ÙG¤gr—MŠî¥è¿É”Y»nr¯4Nßþ 4ü†ýôPݹ û’¸„ÉLÒ§pY]mEø;mD ÐÊ–°‡3‰xß&&_“WñGèÉ”¤?è²=iý-6Õsî;x4­ËëëM•Þ‘IÞR¯‡ÿêÃYIÏhq̳ԖŒ¿Â©„6 rˆ?žb‰ïâ6¨Þ’Ê^T{¾FøãQ…—^¬ Ð}Й"B¤9 ¡‚[òѤ‚ î žú|¥»Óôð¤o1þ¤¾!dtY9ˆô7Äÿª}~Œpã±Çÿàú_pø3‡ïˆÆ˜9á?7} ªy]sʘ€·/Ü™´8/ü†øѽk“ï­íïÞŸ4Ü+nÁ|üï]lúÿ€SEïÆLðwAx…ðþk˜ÿá¾K `™Û+8´P¨³í‘Ÿ/t¤Vß±öénm« yZb#6¹sÃþÝaStȸm¢óíáñ¸pB–Ä4#¦³ˆÄQÓ^@ñ’'ÃKæxª·D×çYE_‘FK£Ö Ö£2bê1[PÛ³ª=%|34Q£÷ß·TÃ¥½ °Éì¯}>¾¾ê^’Å-•790Á˜@©è¥áƒ¥‰tÛUÛØü¦EŸLp!q¸¥( [mK‘ýí}zTñÓ˃ S¶èÑýKÙ¿U«ß}müÓc4š¼¼Ö g‰ï´â½4OñWrkQ¢6â `*4œF»Ò+ :ø ¼¹Ï÷iǺ”8 Sþ…ë VP©¤¡àCÚá/²ŸU1zJ¡©÷ÑÀ6ëSÁÿY}m ù¿p}œr~Ú†¨Àâýü/ñ©²ÚÅ2ž¤ ÛéÃóÎ2ãÐçIí4½ó hõ&?h¥.ô‡Ì/Ûz×¾˜ÊúÖü}æñ†=¬ÅÇÔ‹Ù@®ªr®qG³™Ù)˜FÌ%jþá”ñ<èÿÑ`té¿c$yÃÆ‰i‡ âN no?ŸÀ ŒÔ>W~÷=û+·ú}ûÉ™‰ÈCFãŠ-ýÌ•.vý‹ÁŽAàh×_Úø† 4U÷'È4¼gÐûÿýÓeYãú/‰‚V«¢ãŽ}¾]þ¯GW΂uX³aX¤[ï[Gë,{”KŽ?‘oßfšì9–á†G3v§³d}¸Døœ×ð«¹eðícߌ¿ ¡w&ÐD é[ÅÀøkçC/‚™¨ˆÿÍçx×QÒÁÿ£‰éck=j*ž[¹mÅŒg'Et`¨Ûé캻¼nu?pÆŸ¼*Ñ-tëóÁÿs¿×À,˜|ð¶ýtæZûtE47|Àl#¿ðô¿\ü‹ÆµÖ¿Ÿ²üxºx>‹¿t,y;U0ÔF[O´K‹K »qÝÚŸÎÐŽc÷TÛ­ÜߟU]2Öh„§’µÙLlÐ.ý÷?i¥( ÜUÿ;ЬÚԤѣ»W,ä´Ë·öê‰÷v ÈAjj’3kèþnçŽ ëòÍûøüƒ+ö‹ÝÑöƒë %tZà»™Bç ¹þ­¨!ÎOïﲺkýó«Ó!€2$ 7EiTÙ*ù! ENÒ›(Á%À"þÏwe7n ÿƒK€`’g^ä~ï#1RôhjVŒsÑ-äÂÕ€MùAƒÈ“G_´+—)À¶¡ÙŒ?Kw[´»¸¡XúÈkmæñç\„€(|.Øn„ÿjÿ‡?®Ã,üÙ²üE(ØÈ ¤vŒÿK#À­¡×žÄ00Zäñ|å9™–çÿ‹zyÿ‚|Y> ñ¿7«|0ÇrH[2ò}àß\pú_2þã*¼–Ø <éÿWñÿŸÑˆ¿Ô–ºÐÄÅæçø^ë0zø&œýlÆêªÒeé»ÅÛÒµÑñž?ÁNi­³oâÛO m1÷ÿ«·íãû»¼Þ˜Ù©²Ø1Ó͆Ü~©å _’`Ð-‡µ ë}€œàlÝ*äÕh<7ظ¶ìN’žùøÎŽ~„JO”õíÙ™ïýƈÿ`:­$·?+*NVbí Öh˜XT{üQ‡ü X‘é’b@þzçàÿÇ€=á?—$¾ƒ°Ë1aÜà”‰l~–ûF´;Ð*ÀÞÚ*»øOë À@íh4Ÿéhbæß²yÆ‘زÞÔ¹Bꬭ¯9ò61»Cמ³5{D™,ž_¦›£›Ö~`l‘«é„Us0v7ÊýÚJ|©È•­¿Oƒ —gçÏ*§›uyÕö®X ^9ïp‰9+ µô¬Ræ3 ý¶Ã ðiZ’=ÚÄ\*³Ušï¡Ì€¡ûõ4»sõÉc›M*ç3ÒôÖ }û`ˆðo]ÿ¼€>¦ºqüÿ6Àæ>@»Xf° b_Ÿ§x“¸ª?|ª6J'ÖA²x«nã;ç‚ÿx¿6’õ²[»RâŬà)•nïŽç‹ùµ`,´E ô?ïñ' ¯²º ៟gÛq#_äz‹¿÷ÈnqÀâ@|霜à!] ­Ò€øúø'cÉszSðo=¼Ñ—ÙÄø÷EϺ¼r=À 2þ=y¡Óê¬ør„Y„„QÁøKàØÒ£ÑÙÖèÖþØÀ†ø“y‘n˜‹MÿKÅRÍe¹j¿PwJ=þ³›ÿÒË¥°œí”@Z”dþ3aÉïñæÿÎÐäù¬ŽèNÅq¨wîÞŸ¶Úu¾½Ž?ø|LA®|§…^V÷£Nt2Ü­…¹pl€­™ ¥›õÿ–¨M–MC2¼g/ñüõ ƒ£FÓú.5-0ð†¤á·ÑYUvi¿c˜<Þ¯xЋc;¸rütªF.¤þçw4½xùc×TÀ¤…©ÄýÜfPsÉh•zÿ1³¾@¬îëá¸è „†ËøÿèÍóÂÿȧ`9áOÞJ)…“ô?ÐU6gS2üÑn4ìÑ·¤Ÿâ¡ö%h- BMð7¡.) ¼œPüÿ…¬´sþ,h {Ît„=é >¦ÆäM. P•bü‡j­3,îÍyü•¬³ùû³` ¸vÿYð_ |غþÀ¿jˆZ¦gÄÿçÓ†&žrVÒ„áÚý)iWÔa6\¿}}øÃû3þÄGÿéŦÿ%âŸO‹O¸Øhxù’üxÅíRXÚv²@cîˆ×4Ceq ¨ÛW­}º7aµÄŠ¢0°ŒŽ›ðÙú抵?EÚ&‹)Ûž5ž¼óá:H ‘IÉÚÆÃý:žúÞ ®Gëd6¸XΈàé¤ÿПDMZ3ÁÐâøò þ?OÿŽÒmN¥¼cTÖ§ԉN@½ro &RúuSÿºJo_ûôØ™lL‘}Ãõ‡FߪHø‹ëß[ÿ0zyió‚Vµ·†¿qVºh“×1«ÙEaPñ äé|Ám^ïAL8 8ûY`Fݾ~nøPSà=ðpP‡d~Z4†Át«’ý‰—û˜nè|~DÜ&ÔúqYìGøÛ9ÿÉ Ö'ˆÿŸt%ËøËRÁv±Eð~ÀßÇýAi Éß x PmX9X€)ëÔwÖJñf°/ !˜þ®3%Mî™tñïõ˜é³áÿ —þKÎÝ’kÿ.Z “£F Jøc² áOí¶§µ£™ ‡w/8ý/ÿ¢é¤Ì2–Vœ2/ÛÎÑu©,k;Qö¨œÞТ)Nkÿ†cií—ëtƒQe_u©õz¯ì¯dóöÐÚ_6Nwµ£$?\åƒôh, 7ùæ»ïÏʶSÑíur­¾7cŠ^¸8GÙf‡¨*VësWµÔ8¯ÿßžN¼ëÏäF–Ûö(¾ëLmúR¡Tõ ã?ok4v²;Wí?ŒuòÆìçheɤ&i®éq‰%Èáï¨ gúE+þœÒ5ð™¢tÞúwQ€Öe»*дi(1ª—ù"ÞºMüõCfcþ/cô·ç‰¿>;KØæ›ßúèÁ´ ¡§ âmr½>ž•œ=èÓ­|(ý/õ€¿8áyÏ/#þ.H÷é9ÿÿ¤ò醙ÅeÛVhwFÂZ§©­E岤Qø€( Ûé"üwšš¦Š$Ç•,ï²êh¦jUãZ°ÂÅÓË0­«&+N+…¬ä d“”gÂÿs\âi¢5B;U2¦TëÍnÁe¬N·nmZ÷%y h¨Q>«¨r£Qj0¼Øô¿<ü›ZøAؘö´üÿóñþG]*KØNŒh"΂ù,Çb¥˜‡Í®ñÚ/×N>º%g³I!ößÖwÀ\¼W¶!E=6þn¬7TÓÈFï•öÇ.ªï\›ä VñKìÑëýawø`R÷©ª{Åê~‡þ[F±3kl}Ý9Š·ñ}˜“‘|V„0¸ 實ÉȳñŽýž՛ßüå åé)úZm¶29¨@-'!çCüv>m E–†‰(—3x%zÏÒÇ+{4m| ElüNŒuxp­¸ŠhßüË®­œ/þ³ý’,r8M=ÞkÄ[ÔeG7W3°8} •öÎ).ÀqÂ_„½w øµ€Qª€TY0]ÿÿXž“‡L‡¥‚agÄȧVˆ¿xpa]é$P`#Ù£“n/Æ?›PæVvgrXFKÀmùó¿% â/'Mˆ/ˆ‹\ øG'u2Wè+àÿÂãÏ¥æÒ²é´ð‘™+?;®Äýß2Ú:"o€ø›þ—…NU€ºyÁtÍRÿçœ3÷.5€ål'9ˆšÑž)¢"@|¤¶PýÿtVu;ô«aó­YãµHµym‡–»´j½­<Ë µs÷t{½óÞ“Ùn[OF(ؘí·;ç\IÐŽÁ 7v[úüArtåTëÿ‹Šÿû:[äìpƒ<›¸ˆÌM´`)œägS+j“×íÓÇ¥Ñ+ùƤ{žC“à‹]`ºMXèäÈI5`dÊèÊô%AÛjÀœ`ªž>ïY6.bã<ö¤ùâ*0íÐþí4aƒZm}ûÜñ¿·[ÃFß?šáÒ½n `xþáW틽ÚWò£00¶hÛL§ Çø‡`¿õ£‰øëè®üKmØ´§ü;“(W$€ëúÿMXéÏ†Л¶Õ¡kÀßò/:tË‚sëeøkÀßêäM$¿\F¼+ÈɃFžÉm@¦œZW¶?Y=á–¾$¬ikÕ`åÙ×ÇÿX÷ÐF+ƒØtDü±ð¢Í·¦H«Íë–„~?h²òµªN£F+{›þ—„ÙØ®ÿŸó»OóÿŸ«ùz¼Ô~çÛ €âµ 0i ç‰Ö—ð6É›Uþ,:]±Ä –¥œ­]Ÿü4ú…‹ùî›1M¶=¸æ¢J“lÒŒ‹.5Qm|×~x<‹V™÷¤´iiØè­½²GÿìÑó…jbÍ?ºº þ?j`”jëˆ/`È¥˜ª© švDûÔÙÚþBrë¦ýrl‹ôÖÞ1Ççm¾3n@ Ý]{Ú*ùã­r„If`Y×`VdiKœŸ­Ó¬l(ªd0eTºi:qÕÜ»y ÈÓhyßš\Ñçÿˆñå„›ào©°Q›wV?<Þ«ƒVø[¶}½@’æÎüƒá/Q4N}¡RÈÿÏBºïÿç[JP @øUÀŸsýYKpìžž+ ŒÖ¦/È˿ôÝÕ§MÆ.ž aòø†kÀH}W¾*6`V·wwGrÖßf¥NêׯÿÓÝZr0ÉúoëûJ@6œ4>Ad´vuïï§e[EZo 6Îëy&l\lú_þédÞ^ðêòIöÿ9›ÿ¿¥./·S·"¹(±:sµìêËWßµöÉá4¢ÅN_®(~ÖøKùÚÍûGÓ2´Á›ÒkÍ£&Ü£óM}Øð¯?bÒwvìÓ½±ÿN>Ëtè?º#îÎÅù 2ŠÆ™?­ Í„1wuhª"ú2' n´(vóÙ`œÚ÷W‡v‹þªíìcéØëM¼t×i Ì-yçñý*shÙz‘¿ 0.’¢Œ20ÑÍÿ Ï dý€<ëT8ÈtÓÔv”&%# ?ÃãO¶a`ÿêîÕß þàm ‘ÜÖÿ!ÞØÞzºÇ¨Šs ãª3ZNŠ5 ,rgW~ý/^øoia×Éþ3lªà5q4Ê{ôã @¬eá6ˆ›ßÂNI`©0Ì_Ž?æŽÞþðç,úvþÄÖNnç3Óã0°ŸÅ\ìq€Wf¡Ñ Ó€×ÂÿÄŸ[sD›`É%¦ºõëg^þ3‘Ûìzý¨‘Ä"mò­äbÓÿRðÏfRÖ-b ˆèIþÿó7ÿ¥×Kàw¼½Ü ÅæG]½ð,Ö¡¹C…ÿŸOûæ_è‰Ø0§!1ܦw¯ýì ì4VƒÛGGá7â «’õé®O9žwÿÞ¢ð_D²øw¾$(SL–N™÷øæèÆD?ïÿ“5¹L| ²…ú?þ5eÿ”Y\4Û>.9J¼=A§áhýQI¿ô‡&hbÆî‡×>?0Y#+Ǽðo¬•%ÂÄ4ŒŠöÈÖR>1Í/þ“ÔŽr޾wøÙ<¦Ö[.b]x+ÿ˜¨ð÷~[øïÏÊ‚cÊQ-@ªlG7îªpîëùb2$t@‹üå×øçÿÂuëÓ ù…}¼TЧ ÌùÿÇ›ä8(M ‚A©`ü±ÊªÕ­”nƒÿxG¾qþÙÄþðæ Ä?£`ú<™ã’°ô;ÐssՆ߇1 ¦\ÉÔkâÿ—~jWqYPVW0þxÊÿ(@¶rûéý¿ =àxL ì;üë‹MÿËÀßù*@Áÿï‡ÍýbÓ-PeYxœìuX]I¶èÑàîÁÝ îîîw·àœƒ»»'Hpw÷ Á‚ îî/陾oÞLϽ3÷{ù£{}»VÙ®_­³öÙk×øOÅÛÅ;"ÄÿŸëÿ·âã øÿßìŸò߈‡Ðo+< ŒÚô™ÖÆœ>bŸ³õN @Öluè\øßUªÕ®±cªdÂô`NCM‰xIǼ_ñL!µ©F/lâ ËmnYâŒ<¢øS´ôW8͵¾ÃÆgmµ—ÉÛ¥žP‡HøZµŽE¼tØéÂK¾›Âë-qZ‚Ÿó©t_i‹0ðñõƒøÖTÃEñ²¸`§ÄÂL1<øcó"êªx­on£[Î,‚Öî¸YÈ {0 ÖÅ C $a›‰4óšU–eFeŒÕI˜Rƒ !ÌÏÄó}›âX£QžnûÐUkmå\õ–þè°û"°tTbXÒÇ&dÐøsW4²Ï…®lOÖca=º¸Œ‹.Œ=cx`†ÞqDý 4„øóu†ÇÝ4Ñ#úTM;)ÖF¾Zf½5îtV˜ŒÕØéÜàˆA +lý ¸“{·zøy‚å݇‹øöY8ói쎰' (Û´q&“4ƒ´‡×`Tê°£¶ÂÃð3H×Ss¾wÓJý­¶Ù¯ˆŒÏrüê“6ž7Q_1èða¸i1+í†á˜,-òe[IïíÆ /§ãŸ3<7ÐÞÞΚû÷?³nÌÖ hÑ=AùF±:LY½÷ì]å\h%Pk—j/9sü#÷¿ås#´n‰9Wàç{»&Ýàm“¯,½# ƒ€Ñþf˜¤6!°ßã„ÔÃç:­ßRaÙŠAV»˜\"Xk(MàÂǺôÛuÐáa6>Cÿrœå%Ù­žP™]=‘]5ÝPN €NI+ \–èNlñ=9™I“Å)½" þlÏ-oqÎw”ˆ†~~‹‹kë„‘»†—ŠBŒ}±ÝDÞ¯h®Xy¸LЦ/õ"/Ȥa휋0ß“îˆmÔÜo¸òæj¶¶Ùƒ3…}³i½?Ú¹µ´ÊÕ«‹‘®ÉNcä­ŒØ{|€Üü€£ú ¥IQLJÇ'‘zÿnõ‹ŽÊÇ¿QSj5 !±âu‹…qb ‚!ŠeÍG&¡úã..‚ðW î%û4 Øž9¦7³d_´Ç¸’`˜iOmíHê>1Áê,ŽÓt$Ž’RvjïÞÜÒÏ"åyP ¦HÞöñêÐBR–º:5FÓ©g!Ñ“R…ø<ÈÿŠh@(_§v>¾õg…‘Jcñ˜øùÏžåPH {éL8ÐBц¾£OJ¡}ÓÇ…Ìß&Ì£†ÚötJ^7¹ÁBÂQÃß+{½Fž'æe«nMKåuJÿCÛÿ€¦»2ô.ôçPÃsN©ñõ§ùјSËÎ¥o¸g-J L8|×6 ¿ºòFcÉ/Ȥµ¯:‰Ä{2džô*3)NA·¾Ñ?o·,œjøØ )µ¡ž}° °%J×D:àÏ»HcJ¾/Ež›ÎнÈôtÙ?˶ŸX“Iž50êÉ«'ÛB›)àpÊ.ãqx‚°?]ñœi5ÊXÔ>;‚‰ÝR½yKºZ‘Õì$g–„÷/QE¸·G%uóÁIöÂu”w{ùBÅ<5†Ï}×0†3sºíµâçNê6ÿ&Ù6Çá¤ÛkÔóFãJà‰ëÀ®—…øŒ‘Gbpvž¨÷Ë©TJç,R¤“ó2ejb‹éäNŽÈ"i“arI#=±Yœ!ô¥ì)oÄø +6çЉàˆã¾ÂѲ‹µfB©ßøøGzJ^Œ1lcB½C8òšrç&”kOÁ*ó•Á‰CMN—«ÕÀ±¼²'×^ž`R–Üg‡ÉAF+}±¢ÔAìã:*~§Hˆh^÷ Vüd‰.÷[ŒØ^¤å)›½ÎHO%øËTJÒ²¯ªõ¦ãkyc´ð`¤Ü¯× –7HÚ >l äJ ±Høh{!—ÝaÁ±l³D.Šó&°äH±³I|ð¢Öj^p5ý:éÈEc…%£Ót•,Š˜1ön«ô#ƒìj­ÓEýqâæÃïÉ?’²4Î;š&ÇahTîÃЗ‚è&¹d´Ê ûÙ ¤1•30‹¼\4•²Å'9tS)jMUFŒ)QÂ?´s— c¯oµóáÍV×§óζ@>”ßÁÈG¼UZÃcw3üLû>bm©Î4RЯÛ5 µOf$ ‚§¨ìæ*4ÆqÍ/”¼"ÜOeáNwÿÁ>µÞ’4©½ð~öäƒ8m-öãHÒ,o¸L\VQ¢l­d'Á4òª×HÇcÆ"J‘c”Ó5‰õ^í)ÉûñáÃDDw¥$Ù a!·Uô¦F¤£ÿžÿÃG`Ø—xûñºPpÜá­^ƒ¥fÖÈ}mñ”ê‰q&%Ö ‘ÈõRŒ(ÓÛþ>ä¯$ú-nÛlkTfµÊÈÐ&pÍ3$™ÿÌc¼‘Á~¿;xzý^mÿ)¿%^¾!¿™¯6GpOé}ÃÈ儽ÕõÖÆÆŒ¬ºÅ))´ô»ùß–|þÒn£V”nìƒ*6½(Ê¡OÊ„UzÔ›Ås†œ$þèí¦Æ{ î·~A•>,’yþÒ×ÃEÄÒó±‘ãv©½»}­òìÚ¥1òV1&ßàÒõ£¤a¨¥ùÈ|áè4‘î›nÑÆ.¨í‹<6*àL’Gg|â­ ˜s™ÕTz„Ó™ÚKUFñªý¹‹×ï%Â@gŽR=x3ZQ²šB„y–e±ˆn×"ªltâËRËôŠÓ+³ÛÖ …É!)ZH yoû|pŒwæFòÌV MÉåä´ýØ…Y²¡ÓК`ç@w> Ê%)E]s‹¯G0L£oøÞY|{û”ZsJðöm X C72YÜšEìÐbÔ0 ÛGLê/+QºA  ÍÕã86±œYÕ”ÜJ¦îsrȘ¶êÙ¥ÀîTzQTð1‡=Vý¦=nµ•¹Æ»I5ýð m4Ó"¢WX¸3d"¢ÀÛå"¨SßdÖ~ ÆeåyÓ¡…¦â¡±9ÿoå a”óJ1¿Ù:WenÁÊØaÛQ—1çÕÁ¬9Ct¯~‹\Šëð¬¾Pž&¬ošðZ îdÆcÙ# x¹+UÙ7pê*X~îHaµlXAóÄ’ý+n/Y*¾°â¹ Æ€ª5VnSÿ¦“†ß—¿ëÐø Ñh²Ëç§û×À!Å·*£Â¤ˆIH¹°A,ä'xW!ÎÝ#z/÷NëÑBÕ•×ǿ岡²¶¼u±QׯS^5ƆnÜ!áèè“sï$Q¬3œôEn¾J+jyq5ìòGnÖ[õ =Eòñt‹%šÙ>{ÅÕH½EÛ…¥®HbY¶ÿ‘?°öjy«õàÞv?ÜÑÁqí³øt}“¶Dz}2‡2Àd‡wf !*‡­Ø¬Þî±$á5– žðëö…ù½LŒ!ôUËô FV8Ï*Îg¡M²ÊDùIAß¼õ;+ßì‡ÒóƒlØìˆÝ-k"Ö ßì)ÿüàSmjU·õƒ1Í=;°Ð_c ÑèfDÝŒ órÝÔó;Sæ{Z¦d|æ¾…6³?3Ân§8#" .O¾¼ê!ƒT&B…»Ì¼êÆìv¯*]ÞÐ茴ë‰%\µÔûƒÛÿÏæÏP}Øf1Õ _ÇÆâíÜ6ÁññîµÈ?s>nn¡á¿ßmz_ŸrKúOù=äŸDpVš$aA¸>¨KPùw@öOÊP· 4ZÅq‘œ®‚Ðé#’µgM÷Eoá­ØçÔ{4¾Mx!~…¯& í»Z/BUs¦—Sc–3“£Ï–y¨>®÷‡¦©µ¸Æ4€F©D•^ÆçŸ:!·`웿­‰æÖ 8ì&{ï­a_úPl:iR<àqk‹e¸¦ô½WÒFfÈB[H,¥&¨°z̓èÉðsãÄÖCJd³±XÕÐo)ôöÝ£×µñüäw}äJ/=à”!­PH‘¯MS‹uÁ=²B•l/‘*ÃKE^¾^éÖæM>)¡Ðž‚…ÇfÀGÀ'ó×.«ú(Å›Íuš:#'^øQ#úP%AJvKËʰã„‘Ôü)UÈEÓAÊNæ †Ù…„Öø­ º…7ºÎ]óŽYâÞ~kWFè(_neÃ}#ÓÌ?Z^Å'ð‘5<ë2ñG 8<ჾ†Yëà“÷ð nOQØDñðö‰*[Ai.dö_ËäioÊñFP!emÃWýÔ5„g9U4YlGx«F^X–o i¾-1<—9åu–ÉàÀ?m3bgç\H—ÔŸˆƒ8\ÊMƒ–¤xö/·,ðC ¦sΔÔõË¡wIê^°Ý×¾ÒM~±ðºí¬›x1ð€sáƒð´j4A2ãì{8_õGån/âã•T'쀘!ùýùwË 6j)*äË;vˆËé‰;GSY Ù‘ §Ï¬Þ”tkG³¬™ú9×äöMZÆ+Üg‰Ñ›:†¾ö4ùô‘5²ü0Qä*óv‹d®ìÜdyôÂÆ5éküºé¨ g¡³KT=ƒ~âCCDž=ñd®LðB‚&#T°Q욤ŽUüË»Ç=ÖFæ·ŠêÌH)V­þ‡SÉ !÷ÐŽ†ÃcÐxBðbQ06W“·œ2jö€§âîÆ/R˜tˆzj}~eèŽì/É‘–]Fê^дï^SW®a|ýŸùS¼*w’6QW »o zq³sMyPJ--µ`íp –É.¡ ?5qSß,ÕÎä'ê¢Öº‰m^gg]æ7ãÙ®CŸâhnŸ%êí¡ƒíC"ë® Jj‚)¨Ë©×$ÒzÊ } f‹ÌšÿmþýAq¾ÈMÅOöÂËšƒ¢µZ ZWîí@#SßÅÍs¹X“Ïo mi¥Þ‚[«­–Ö’eÖœ"R3h.ªÅeN@Ú~ ‹p2 ®Ym3  ù‹,¾Mƒò[½óo$ËrþcÛÿOæß=ÇÆ7_*òQGÃ#a![ÄÎÎÑiˆYòŸ¸ €§‹_dÐïùÝÛãÏÇ~¢ü“€\£|´‘Ù<Óèä;îUûÖ·™ƒV%U pC‚"æ*Ëe›™ ü>T glJÞë<³h¦2èö$¶.ÊkYººôt{;›É;v „nfÀ“\7™»¶,šSbsÊñ½oœd½/ ©óé×F„Ü‘6¶¦­fÌËnÐÙTŒ4ÆX5Ái\Iø€÷1ÑiËOß|VªÓÞ7Â3 »ŒßPÚšù;ÞKzßç´;Áz·mj\¹f^ð%yœ›‚'ÃÐ;²(R«éri;³.ÞqM—ƒZk¢cuZ÷»åX”£yanNžg¤=Âç¡:­>´dä:Ü9þ¼r¦|‘ÕpÅöÔ~ê*r;!ìUª‰“ýúrµuëdÛ/>åp,·&à³.3AvÒ‘>šûŠÑ·»GµÀ­øìP4Yb%ªº³MiFâ3Š ™È3·;Oå{ ±³GâèöN£ä«Î%áR½îGÍ^ÞÎÊP lr™"_.„¦—gäe8¡:ÒTŒ-Y;mµ²Ñ}T42j¸õ7­Ã‘¶TäоܣÔΙºgñ>Nl¥e6ì ó_Ÿì…¿.91oo+©ÓTÇä˜õïµH¾æç-9ú @Tît -c8xŸH$ZyàeѼá"IUº”‡îÿþ&žwy¹þ])ç~ƒåÞBk‹Q%\3ð÷çOd¢ÄX4©Ü+º—Wr'¸cAÏTLÈw3“ ¥MêiŠ]ä±ÙpùhÈôF¥•Ù4¥5®¨ÌÉݬҙwz‹‰[&/Þ›ëk«OR–†aJÕ‰áŵÜé­Ã6¦ŒÖ+7RÓ*²oµ[[Q¡Î~Éφ›En×'.ø¿@‡­²Ý=À_zñÛ¾"“à_(P—­ÁK*SÚ‰éÒ¹éÊ5Jª¾I“¢ ꧤÍ}/u±«b¼¬Í †í°s~ÁËÏa+$ŽñôŠæÉX…;úâFHŸ—‚tš×?Ékñþgþ©wÕâ~Ö&Û¾‘j¦ºž+¢VÑh6±®çWBTILÎ’”!y@_•%óbì-œAè˾$äÎ47‹ Íõf-’¦ >×ɳÈz·åý¸.ãÇî–äॾ¥"2V}Y] :‚ (Zv¾úé\_˜DØ—ÿ‘豟ïXɧ–ë‰1ô\¥Æ>4ŽÚwRuƒ`«7ŽùøÚ£”d‡þ+<5pÐÒ€V·5X'òêP†;±ØïhÀ —·ú|Ïm§ÔÚÖ^´œ6‡õËøhûÿÉü”æó°Æyƒ*”6iŒð†(w¦ÿ™‡÷qñ ûcôžž¡~–üvÀá3Ô꣘Ö{£bèé"øñ‹âô¸ØÏ<ß/é”1Aô¼™+àaÝ…G;HZ"ßàËû꙯ӗUýÊâÊæ®JýZfNãÚadÖ)“ʱ’wpØêÕÏjyÈô- …Žx´ÁêîÕB΃úm¡¢¶~wAÞ…(â\ç†Û. ãP~Ú0¤Žq¹ØCíACÔðw/KðrÒg\±Ž"vh—a\ÈŒ!GŸi‚ (*l‚÷˯AžõQ0¶QM`ÉWûöš®MP^ƒ0K›<¯däÛ iS|¶»/,vx¡ XH¶¢ÕåPxÝ ÖŽÑ¢òF.5¿9ÿZg8Ë© ×d»áN8ßí[û økíg0œd"ò$Ú]°±÷¢^Åa RÙ‹LÙ)ßXvT…„³ZM§™ ½W óaß2ì3c¨©#–†fê‚í%*´ìNaœ·wøõ_×ÉÉ]éÔ#4ô¤¼ |ÛÔ…«ŽÛë²k<]8>|vMIå—¡:Ú¶p# ’Y$"‚V\û¥ñ(#¿e$ˆ ”OÒž5um§DGÐþV´x Pœ3 ªååòžsžQóø\Å® ¤& QE!( î]É"¡nq<3OÓàÈô,h2/aÊ6¿±.#0&jXê§ð·m¢×±žZEïzFW ’š\uU¨- —B P®XÐ÷ ÌA¥KÑ'ÎË'Æá‡7qCA‹ø*×Í•‰‘iY–aÓø:oBoÐ'FÎ%û£R[»àÅá—+±ulú†Ïž_ØvåQ&\”ŽÃ’›+«ÚŸ½õàÜ(¹¨¸Bóz¾- AÓ}A×Ù{øÐŸ#pkîkgA ‡÷oòĸÁ½ã 8ïj‡ïÔ„ ÑMŸv¿ÃŸ2Nk‡NØ–®Ó&":Žm˜¦¯²È¸ËCÑ[ŸÉÎs2ô`E$Ì$–YB)ÝgÌe嘊€ Ò‘ìÆKÚ‰•†š‘io”à4ßÿ±íÿçòíºÔÎŒçžTcÿI„zYìáDê·…¯‡k@TÀïíœÞÁ¿ë=†?åoä7#(Š)¹S¼[hÜDný½=ЮñW™tÞßU¬ûšUd9Š Eú+Oï@«Í»Âk³‘§Mì++Ã(ˆš@ÐÄqbx!BS¬÷’7¿Úì *2ŠÖwâ¾` ÂöõUú‡™—óåNRjéÂŽýÚPWnUNä.¼âÉθ¼lcBÿ iÆÇ¾1@-RHÆž,G1¡þ‹KŒzæ"Á‘9A7² ¼à'<Žñ hBÅ(&$ì€<š›Œ§Ë‚¯9ˆHÿ›v¢Ä¿ðRy`=Ýh yŽþ´*Ó4OZ]3ÕktÅ8![ÁÛË_eKÑǃìr0ªbJÛ®—WÝÚI>˜nUiQíú…F;]õ4¢¾í…^Uð&ø'”:Ô¢2/Ts&x­çjÔ¡úü±íÿgò:yÿÀ¦jí¹0ÉY*$`éý~èËoº €³Ïï²÷ïïÅ×òûì1øSþ^~3 ñQFàK[õܦL›!}70†–UÔ`< Ü"SÌ¥i¹Æx½$Ê–ÿ\U …ò”£Žà“SGg¹5â‰siûLH?qæ¿ÿî]wªP‰(Ž/–´h†€™X!Úéó§oëß;‘© ùLª?9xÀ%ªj¦{ÝsþÂv:1“]cÍêª×™þ§ (®s´è—‘ԳИ޳)n±!CH™–È+‹Pí…WB àÛð¬¤ã…/]Æê•Õ˜Gˆé|œ¤þÄBøŒ6' ù)uqɲJ ./ÅUWb„à…å[~šNMLˆ˜Úx&þ2ñ†Mdü™´ÔNt¶üöm–<ÑKÚ•·Ñ}#/‚õã¸$ÿÝÑ4 $ Z讯/H·ÖÁwQ?,ï>J íÜZ{u¾Ï#P\qÇ6o À"~åÓ‹ý\b# ‚Yò„]Ä e±#o E?UciýÌóvÚÅ[+øaf6Bõ!lb„SXãk4ú7¶˜T<“”;¨¹rZ©Ê ËäÐe´š>ø½Ö`wº0B9«HR…=Ájdç“/E¡²Åº›_ÇiÎaóC>ŸÜŠêqŒù̶B‘’LöÓ2=·¢3tw?´í:A§/ C¨ºð%²¶‰f«Ã$ŠQ¸rˆÊöu0k'@“/µÃéÅšPì× Ž ¶.±rÀ\~ÿí±ƒšbíNÖ^þâúØ*ÉfõT^l6m(:´åÈÕ¦lµÙnvô,éÛ<Û¶è2.Ä’(™<â7”|¡t{ü!z|å‰ëù­¸“"%w¹z4zç–ozX'í³©µÓRFdj:¹òýŽF>͵“oW =¿ŒåBkÓšã8™¤kΈ:‰œÓ$”÷Bhm¾Àè!sœ¨ó´œP ¨Ivàét@ÓÑÛtïn}>ZaƒÕÒt½w ²§ÅSÉ ¢*64Eió™ä­sŽwîèÜÊý‹ü(^¡2­ ²P¯ác’5-B qEó ¯)I^Cä€ •Y7f˜ñmå;72 ±XÔ„¿‚Û â:ÇVoŽXE?‚¬<¨ÓÚò" 4¿u¤ŽÖ}ô# Ix›Ì‡Þþ-e,ªáó˜ù+…Iø·£–ñƒÿÿ r$íý-¹Ò­˜´‡¾N-t\wŽzÇœ—…<5æ§ê‰h=¨Å«Wa­Ž……ògM£k³HpfüÖŒüõbC“_¿•XjKUB°Ê‡¢)_¼T‰û $0´_gOþǶÿŸÈ_~ i¦²A%æ+ý›¹h÷$ÔrùÄo» ·wÁ‘?'8ïíáúç^ÀŸ"¿pìœ9Äp§C™’Ë‚éál±B¥Üw`è}פ­z6&dCñ}øy Mîy¢íͽ ¥¬¿ £ð>]E’G ¾*ßÑ îr¸S=4Wš^y™[YX–„âÿ¤9sâ½Ü9J3 C_-f)ÎŽyð¹ÙEûÈ\¹äÚ$[¼ƒáÙS3§/Û\I¤&®ô$ÿV?”`tMÄM‡NÐs&ù >N¿æw;aÕáPÏâx21Ü«{O½¶Ïyäͨ¾þAù Àé%ÏZ^MÃzTCÈÁõÒlZ×i–ºóþ®›`iG?ü[ÝI<€ý:ªH9׳K gÓó&¥ × L¥ð,…Ú_íÂë/T+x]ÑuÖD9ãÊ´ï6õªi$ö]úlúT1o‘˜ê")i¢ y™oÄÁ€¨$H$ìPéç Jn ^%|˜&ðͪg.ˆ1¬5-ë6!ôtÙB»X:clZuÛqu ¥PÔ”;&fw\×ý"¦Peõ -KQÂ}rMÒ5ËÎÎg9IÇŸ:ùKðj˜ýÉÈSTŠï»Ü0Úv3ÞÂ+\«W.êBJ!’Γ޿ì©ËÚɰºè á‘Ó0¸@P.—cÚy½R3ñDgOTÇ×è'9Ò;pÊC6žc­ T}æ–ѶE+WËM‹­K™nTxiާ»Ø;†FD#Џ"Xu˦ïl),Ê!Ñú™ü“ø¼S6À%%…c”;4ñqGbSxP;NXüa5)«Ól¾,²æ.íœÒ²Oavø‰ø„Îw÷W2ÄGÖrœJ)è1„o™š€‹èZÓK½+Pä§¢¬;ØJ?Z dJ%þ&–ÇïÕ Üð¼·²xøŽ ÈHé–ñÐ_á^@rG )¸ïÅ8ÈðzóÓëÏW äø“ H^n»6¬Ụ|µCÚßpµ_/ÉìDKÝÕE˯°7­º¾)|xYe¨Ïa…C‚wXÇikÝ›Ò6ù¨rªDça”qQÕ¿­ø¯ò‡V/ £Bb?‚jdÜ8_}~fdrBý‚¤øPÈn¯Êëë^"pÂÛ*ÿªb„$Šbää¹Î›fÙ¸uÕw|'4ã«Bžñ=JéÛ݈§:3ƒÅó{›¢ž½šŠ7d6|æºôDœéíàÖUþþ¥+ïš3’*àäÂn(HoÜz½ÔÌÅ(וã×:ÂÖ<¨šÂd¼Îî¸öͲ88tƒ‘HÞâ-}™ÂÐ÷…àEp¤ØHÝ¿S/þþÑ>à8Ò_·Ð9²wgVz±yÉ5Dq¨‚áàL*¥~-”¼®ûǶÿŸÈ?ü–·ü³È™^B{‘L‡ŒÚ~Ôsšßr¿ëÞ¿èÌË30äÏ ÀÏ÷€ˆ\l×¥„=C>á>ˆì Wï%˾®#Ó@;µáª—Ù)ÃÇÍmNÃòXõ&Þ½’›wvðl‡0¾†Aè'Í~•©2·j˜] çùœÇ_(””Pvmt–ÔóMí³‘YÞík·D)`e\î*¦~»ªÌô¼Ew;õÊú•ÛÌ:€¬ÁY{ÐS½MR–Øá}S¼êÀÖ£^Ð;b%NŠ’jCU‹FÄ…”ýN­0ïåg¬‚O|#W5ßoñ1O|O.óÇ#¸9¹ êÖÃi Ü_Yø1(V3àvp;–à]únWùd£©Þç5+$àaz [gîçœÚ­·!›ávÑ’è“ïZEAƒ×ç ,oê‚{ã‹Ý¿DmMÛ4ÍlÃ"º$Öu;!B¢,¢ÿ²º£æ…Äy}³ ’h3U[<ê;„¾BEÑ€XžÈœ·uø‰`L)OÄÿåªUè@ƒ"hõ¤–vÕÞyU/Ã7ŽÐmðò&(p—¥;2¯ÄSúN—”cJíÍ·+óº4^óꬴ"ë°˜Êx¨˜x¾cpCDjEþî°Óëo—Ö ÞÒT[L¤’}†w/-ü~…_“]Lc\WD•nCÐWŸQ&à\å/ ß}¿µ¸yñ„Ô`dŸ´›:Y— £­ óÖo@ Àø¦—X樚F8ÀgÿsùÇ‘‚I¿ ‚9Š&Á4!zOÏï¤ o¡ÛDÕèc¯Òßjì“AmàšŒ) ý¡/qP¬?al´p›:{rdm.‹–Œ¬73¾œÐ:cé6-‚¶-kŸ8 ¹qf<¦ $F=ï,Vú’šV̼ŸÜtxÚ««{êå"fhEãçÐ8¸P°ßp ·™óåSÈ«æ Ôg×¶ËBiiU—TÝVmäj"]ãªÁ÷ÆRÇ›ü±å$·ÛTø¿x@g˜¢…Nš«Ž}3…AÝ¿Îÿf7?vkÌmp ÂR«†Œ*P¬ wÔscˆl¨ƒ…¸Åþ­¤¨7ÁaÝKŠ?f®:/N$'FÉPÝfG¤m„ž%<åXìó|ÖÝúRö+¬õgKíEøè3ò-Ì·èoZª£X¾.TÀüëüéÏQ[uÐj×Õ„òäaUÒuEV&@[@aìJIq*¼º Ø£N"ÊÛJ¶ªô*ØL]U¬jßé}""!Dž¨ˆ—zO‰1>Æ{˜®ÀvRó… ŽÒwž3:ÚžÐ-zËê³b­ÀqI´¢^Ô»\ ·?¶ýÿ4þÝ(h”Y%*3Mµ¼ 6™É‘÷¿å'|Þ¹ÿž{ÿþ^~<üÓzûËoDÄewqЉj r%"Á"çÖ¨¥3ßó×ôðÆx¹‚©¨E,3@ÒÄa9ŽT‰À‹ôÏGñG×áµ×?»Ô „$ãS÷Þ3’W‘&r"¥ÖưT&¬Ñ?å#} †ÚãkHŸ;yÁ0ÜÌÂ_?£¿)$ˆ)„2RwƒM‘{V¸ï¹3c Ü<ð}Óç‹ØÕÒ®a-NM)'6÷Ü`}ü~&g’!MƒIû¬ÌäÄk{¬ÇKRt"wøkXTþ0x4ó®ªÁv¹>Y-¸²s1 JªÆJr¾Å‰Ž½œ+me {^jšYÿÛ»õ\;§gg±ÙhÂ)¬gë<^* †z…ù–uŸò.ËRM %„°W;¶Â£ÔÀ=”nbÈ3¬³œ]ëqü«œÍ0½Ž²:*†¥¯o²|¢¨à °‚Ý”q!7g6ñ\'ÌÆ5Ýx?¾¥>ú€ö¤ã€Š >r>¥´~Ü&^NÿKðB¾íîD¨tÍ-¡Ö2æ—h/‡¯l—(9YP¿y‰k´ÈÚï3yR%P+:¥î…}êoY rA‘z„qÕЫX/Ürj‘&MiŒü.n°[5ûS=¶X_ÖD²Xw5…°‘ÆsCCeEXðÆ›¸œwøQ#â"i«Á6à%=ÓÐ^ÆÔ’T€È»Z#H½ îç!Ç· ±?¿0âž ýÚ¼b¢ {k§©Ìzs.yA?Î8w_\/à“¸Ô+/c¯2>.çQ€‹7´·6¾˜À'“cHì  ¨rÝo ä»QÅôõyÊêOÎÅÍïTÚµ£ã7lÛ÷ñc&[ÑÀð¤À‘žá­.’Ãã‚­æÄKEÉW[h ÁÓªíýEŽ ô ÌÓy "'¸rÚ‡&·*Ö¼«©:vÎfsZvçŒÜLá˜ÃO±’7l¥pAoœC“‘l½£Ú¢L›5¨„ÅŸ Œ/þþ^=Ò÷yUÀPð»qÛ¯sÎ1†•ôàQ_¿a1Búø†u§ÐéE<àž.Qïçç¤ôȇ+I™¡p‚'Û?œÚ£]ƒmÙæÃ†gT=ÄçT^”$/!)gVŸ[ݱ#¾O£¿ Á]ïÏwb3˜XúWùË7È㠽QöPÃü¢YaPŠ[÷âË}µhÜ',3ÛÂPÏÃi£%®å7s|$õÀ;6–žÖV2uLÐVØÄ½ª–زL£[)¸-ü0ÀAÓˆ¡O -s£Š]Ók)§ÁAïXH™A.•&ölAþǶÿŸÅ¿ \’ÆÉ-ñ»:\;øµ¢þ7ÜÀÓÙ?*ðg~%÷ñøó1€Ÿ!ÿ¹'R´…›j×êî^é”÷.¿’øž/8š¹º4£Di¡²‡Í8pâ,³äiJ‹]J&÷. :A1`xòSPÔa¿;‡X°“ôÂfÀm•”m9¯283Lnå;tN˜Œ1úÜíYär]¸…lj5Hå£QJ£5d*Û.ïV‰ó "É%¾RGÒŽå墇L m'Òãig$:Qþ•]Eª<ËKà ö\\mN-ì½’ÛeÏ«À×è$I U5´ý&;;¼xrkô"lþ9ÁÙÍ„¨!`‰ˆC8iµ0ÁOãH÷yÂwò¼-îT_™Aðá[~hfŸ0tVМÕYÝàôô^!õͪù0¦Ýˆ(Ú¹_„§(ÔAæÓlöE°‡¡l¹1šñáòe>õÃÆ¡e«€ÁMJ‚ <\ìúy™åNÕäWÅ}š BL4Ÿ4o”ßyÚ/9vjW§à‡º›Dƒ÷\.ïèˆðSžq–ÙÒà [Š÷»É»]ñã›)zD‹«w¶½¯Úá‚ ?-kÆ’Æ=äŸÛ‚ៈbFÙš6ÛH2´XÒ¯í¸— ´C¡ÇQhgBë°1°¦ÓE®[,D ?ÍíƒÆ‚,®Á<áã~ q¦l´?XšWEæ²!¿¤³½4Zó]·ÅÛLùt¦ëJ¤Üðµó}ý]j?aÞs0ªÏë‰ý¡”v®ÿ>’kÔ>­º.@ñg×¾èÚ¼ Êk&®T… ‚‹¶!0üjN2çæ!‹°ñÆ/ÕÞ¸xvòl^ ¡ Ä×fMêE—á.Û³ÝA…`9­·*>ç-Boà\4»ÐV†ö] èØó‚:¢ü>ÓÝÚ¦÷˜0v¹5.ðHX5\ úÑ?Ôª¯ë8ÈO;çÓó’4ïQŠƒDÂS?W?ùæ5o|ìˆ,Ké1a-oC‚ ϼ•l1ÄXâÀŒ³ 'Á ß™ – ´Ø ïqÒ.åþwø‹êÀ÷ßÂøµ r¯WÒP#WžïSÇ5¨xß4ªWã×=)Gvùñ]ùÜWE›Ä‚÷·èËét‚Ø:ŠT [~Êvxñ|Îô …<ÖœÙâJÄfflt¦–Šèé YË^Í“-~so%VžþUþä' ¦¤x³Ó¥—C"fF¬8ÑG£soWíMÅ­Ëi‚ÀåÄDùN­J^ˆê„,‰ ã0 °$”@¹î ¨Ž³A1Lkެ‡…+Ms{)Ë™y ‹)½¡h;wß2±ïÌÀ‹‡CšuV9#õþ¡íÿgñ‡´È·üBûa/N2ÅÎb–u“þ7¼ÄÏØû÷÷òç+ŠüC@$ÜR7…ˆÅ­ lVyWñš)^ÚÜ áõT×{tíÕk¤š××téÚ5Z\uƒ£%ªÍ ë<2ŒF8‹£Å_•`’v¤¯8?˜\Ù IFºz˜ýV^¶÷< wr'Q™ðêÎBPU¬ñ²ÕÁ}Ш _Úm矜À¤Wo÷œΆÐñøQ¯±¯ºü›v¢a°‹¤M×쟴ûC-|e ËàOcನÛL8`˜ÏS¹irfÖO«i|ô¾u²+ÆõõVš]üFžßý¨CY®U¤”249ìMÂ~SLcŠ%.Á{0$a¨ 2}`=ïÖ@® lg2­{¹|茚ªèãk^K¡üd,#˜ð’l–:@3S,=¥’[H¶ _üÐlÿ‰{‘F…þŽAöBòÛVAK¾Ö¨6/¡[ɺ¡þóô-wÄU÷køªM¿©íýl~rwTìVeÜz6—´!ºâ›€%zànî|F1†%íKXÖƒCõ…ëCÔâ–72wµIÂÍ—Ž¹(ŽÜÃÿÿ.IÜæÐ3?’7YL6]Ô‚|êɼ—K¯´æ«¯ä‡0Œ¥öèZjïÄŠ¤ó«ÐXOo˼YFÈ2ÑÉÍ24äg„ÙÝ*˜ßË}¼5 YˆŠq,_A{Û¿BÞ ÷uø\J¡J ÌFÛA®šœj8p«[fî¼Ô‹N"Ø1†pÏ8¬2ß}qyå3‘¶L³@ë{!UèAâÒä„9bQrevÄÂ숧/硳S^¾ª«ñx.E(¶¶À:­M2_®Á€ø£«xºWYŽÝ³Naû¦e(÷¿ÇßBäù¤@•"â‚ðÆuhü6Ê kî:È’úpGÃ_ßuæ’é…lP笪IŠ=Jñý®aÏWXƒ²Žóú—rËÓjo’çiQæÃKzn©IŠáe#ÍÕ‘ùœÛÚ\U¸(€<5¾þ>è¿ÆVX¢ÆN4Ïî$ ¡ýá«q@!— #“‰ …SýñR9°ììH"âJlL•¯#[®s€þÈ–Ü2MNÒkõÅ)¶½™VO COŸŒÞ¥ÙªÕãyaI<š9¶áM±w×¶>Š´î£Þ½¦E> UtÑë7°èàQSlûÿ9üUrÄ6êuª[#:·áõ&Hÿè#|=\‚"÷½/¾øgÈ?D –ѧl›Œ¹d˜ñº«ûú‡bû@µ€ÀœÀ­o÷±¬ÚÇHõ°))U|Ôm¤úO®7MŒ[“ŽÏÊÅ>)·«4ùúï…›@¥(„ oðƒ ’È:%Kƒò®í_ŠR“l˜?»@ñǺ9Ï3ö“®fËÝ&m:!FÃh}ŠåL3;ó€')Z^iª¢`Æ0wY ÃËn'ñÈh½JçȾ8V9 VÆÆáˆ±V¹’r,·¸»ýÖúJÄ Sp „¡¡Aä6N,ãUá®Þ‰¹z*1ª Ìy F‘N—²K…Í[;… *^õÜ8íkÇ¡\3O»Ñ2ÿ­p÷¥áMÑöŒœøù6V¦b¡ •Äë>/K>Ÿ¥ ”+×çäÌU5l[ Ép›Z\òyo”cÚhŸônR?~Q—ÙŽFöŠÎ~ìÞÌ5¹8ƒÊv^báØZÆl,¨o”¨ï—`îsŒey:–&v|¹NÜ ¾ dk"ÔÊ/8Þ~ÅÖÙÎrššSc4ùfËüÌä{^YÖ({IÚô ŸxÎÚõý²ÿ}¿ Z÷æÊ°ü˜tn“m™§á…ûI4þ[´$X¿ ¸¬­Ïs”#ÈDqØîÒ×u RÎK%–ˆ|Ò"å(&»Õæî£.»°µ@ã°u‚Ø®@œ!öÔ‰<¯¥Šúc”RKAW‡ývãîêÂÑB؉¥ÿÿž&܉8EF‚ýÅùµ%Ðóc…4™3n¶ØèVVßu_ô©e’1˜‚¸Õí"œ.AѵW èß|™QIÂy( âRd*Ééñ¶~µ.=ïß˼9¦¨’ŸkÝ9J4»3o%Wäài*gÄâ¿þXš©†LÙüž¥ÆV—Ý‹·<»þÅóãÁ-–•"ü œB)ÂiÇÇg ÖvÎ8óØ.å(=²»â4ÆÏª[ØÔðèëí4W!Ü'>;Š#aŸ:Pƒ¬‰ ä'ñàÉA;#ð—¿Òónm¯ŠCÿ̽F{+æÙÇ!) ¤ûÔM2XŽWd0í¯²ü ]TAÇ¥ì+l£]bOjùâ(ùš‹¾áTxöqµi»×Ó¯ó"^S Ùw2ÎùâÀµ ‡¾BqÈç ^ 0õ%þ—ø¿4B¹“K{މ,‰­ƒIK­ÃÛ/ȔȰQ\/ãjž‡5Ïg¡Åx«B´±Ý- ö)bóm.)`1Yu&Ì´ÉzŒq*;Ê@µïæµüÙ¾ ã}+ êÙ=WÌ'ê¾Zªø|Öa3¯4Ûv!î•^cÕ ËWç2ªÝlûÿ)ü£)Äóéž2_µx¼›˜êLûñcï_äâ¼?_ üÄðÿFÐ+9/ ÊQ»ÓQBŸ½¹m3÷>”3ké ¸ooPäæâÙ ÁN/Iq|ö[ñ?ß7>'ð ó| ÄÁ¼W¥,”7€7Ùíuøæö%¯‰ˆmøXÙ_] «h$+f‘Ï:F Ä¥œ‚0ªP[aî+Š#²Êš”)ÁÀÔvɧŽ,†×1þœ™žšDI D¨‚$­ÑÊÑlŒUV{~«|[Ý£-D —áôq ¡ShŒ¢~Â5ñ•–Õ¤‰b¼»)Õ¦yüT©A[_Žª×Q ìV"óxwß2Äû¶ †H5 ¹ßÞݽJ㺰g©¶ït;.ª ‰he3AgÌe:ŠÑ—n7¸¿æ¹ëÛSÖd¨E¨ýè÷|J ¦}FwÂM,v£z¹¢²ø*ü>eüåÁ²÷Y§Nløl¦¶¡/t +#ÐìÎfyÖÙGÉvRJéd3eD|ÒAëé î̘¦·Z‹ìó›„ ÞS¡Ž‚Ã8}±nÌÔܽ×XmnIžKŠ›ÛÊê½gr~IÕesý"æ¡ i)ŠA‘­·»OHoÆ^°8>”œAçÊõBo'X8¡¦9Ì»|KSõࣽÖ;võ+{Õr¹ž œRS‰Ýܳ?YÞ~;¸[Óž¦Ó^b'ŠÂeOÙ‰H¨¡§tFlFµ‡6–Xµr#µ£+úœ±Û’.„;uöûÖëþ!‚ï?ÆØ©“æcõ¬V~zËã—„W¤GÊ ñšÂq×*ÄB³‰Ð|Œƒ³æ9˜Ùq©yÔ„¦…ÍVY8âŒq„¬°^øL~œ±¤êí°núÁÀmF>â;ÇeYÛ*ˆ/8 óFŒMXø§9rà­ ð¼Iåà”Ú ×e˵¡Ä]6ùws³¡úá{º\Ò—{¬$ië©Doª“’ïÉkõÓsð¡ógŸŒg˜2¢½†›D”c>.a[uÑà"âø¸r’Ý "jò“ŸáfÔÿ}þTîÀ‹eÇÔ‰w¤oºÙ„}8ìÔbÖâ& Ùx’ñ¡v'h>d¶{H?Ìaª¯4ÞéA^R¡@ðYø¥wÁwvµl>Ðõ· B³¾ç <åhš©Y1oèY [Q½l ćW–å*©ýWø?š“Ÿ¶“ dÈNè‹KR øìšj€©­içBw†Ã 1ÓMëß”î#oCÕËs^›š5ÿ[]x~á£OŸ½/;êÃ5t²‰£ø`A™”¾lÒ-4þ0la §HŠyAdŠ\âe´kYjü‚”7Ñí—‹‘93öZ2j¿êmÿ?ƒÿ'$Mt|?+9Ç8‹¬O$ï ·w!ÿ™óþùŸù»@›í Ú §w—‰=Œt…÷vÝ5ž8[ä(Þ¼Ì"[ Ri{´éƒS*ûÔ.°Ûdá6•·Ô0ÔáG¤rÔ&µÈ>L“˜dìñz·é΂È6<ý­¹>d£H»a|Óéëò³V"}èR»Î­ëÞz/‡þlN-AÇù²L{kC¸ôhB¥«­[ÊŠÿå¤K÷FC(yIc é•N{¥0W€)Äe! í2© íÀ’ÁˆDBL§üq2ü·pV’ÚÂ|J‰-†ãg[6ùMh@$è„—E\šØÜ`œÎ>AwÕìk6UãèóÚ&có¯3£À¡÷jB~PmfmðŸZ±ŸtiQ)*ä)ÈçÌàà od_ç!Dçâùñ›fÓ§ɂ~Ï‹kyé*M<¡YdF®tReD&ígZ_ ­ð{xvòÐ;ìÓá£=sˆ×sŠô²äÒ‡·ºgm³7PÁÛ«Iÿ JÕªJ¾îÉž\ÕëǶåHŠú­ýIåêê…k×RæÄÝ8¾«¨ûüËB ºfØA¿Q¹×}À$Oõlýol2°´þz¯/x.q@…Úì$M£‡@Œþ}þˆ†Ø19¥3úC«81IñG8!ò§APØ7šeÐÌ0Ù^ÝH3{ê¦1‰HðǾ3GLZ»Ò|ãÙS¬—éÜy•¶¢€Õ˜Øc}tÙWʸ7—_'Mí§jˆoC ¥\µV2,õ?ò¿ÛT—¶Õ“,8Lj1,ba‡nˆX#ðézF沦à?ç¬ÌkÈ-WMµä6§²'¨sØm'zÓÝ)±yg¹4—ëó™©ßà›§Þ‡^µ¯ò½™xrtá/ÅÒ+/á—¹ iÜ»¼ÉOÚÑà6Ôl¿(WŠ«·sK!—ë†ýCÛÿOàߣ«ODëTˆ®³ÇŸº¤)ûÏ=àGò;Üü>Íþ)ÿþÙŒûúýEç ð÷úøø¾~þ?veš›"ÿún_?¿_úµ%À/¿}½üüÿ«_wëð˜×~¿æ|¿œTFüßa|Ülã"~‰/ýuTÿ58_Ÿwš@`QxÐßvõKo`€ßß–õýÑ'ÀÓ÷—gF£ù¯àøµŠßÿ«ýKâúã^Ó_sM|¼ƒüÿæðï¿à_ûúkÎ÷Ÿïçð׃_Oú{¦Yzð/Sæ ôò ø¸#ß~?Ö¾»Ÿ‹.°6Ø+Øï—sûK ðÿñ×ôûØý~ÔöúýþrøýüÑú}×|O|‚þ2?ÿøþåôßÏßÿ×L€‡_àßÑ÷9þM(è—‚¿ðÿëüx™[ünüíÔñý>)ßK|§ùc¾¯<_WK`Ñ­Ç?ß;õüæþ@Àÿ­âëÿýÈ×âÿË\ý²‚Ñ|/ý£E€ÿþ?j~Wûÿµ±ïÚ-~_êß“ïü-ý}éoÌï{ïÀ¿_Öÿ_Ÿ€ƒú^Ñ÷ÇP<ü‚þÚàÿ_˜ùz}¯òÃx~iû¯™>&iÿ7_`U°ç¯ü]K™ÔÿZ“>À€_?øûý-½üÿRÚï×ä¯%ðÿEñ ÿ¿N;À#èÅ¿à;ÿ_Æø—Ï„¿Îÿ/M|ŸÐ_fÝûÿ´wÝÏqWúO<Û’¬“KgŸ(Q"AƒDÚ0©Ó„ÝÁA‚4}–T­l¹î_¼~©»gvqT…åÀ9˜œ¾~ï{©{œ­ùžŒ#ü5ïC74{¯úù´¡{ M9{tv«åÿ]àß×AGÐ…?ÛËkînŠþͰýŸ¾ì…+ /׆EÁVGïù ?öíPB“iî¥n\ئf/V.ÝYÍÞ7ûÛ2=Î'³óé|\Vt„Öåî=ó³c—*R¬Š;ˆè d ZÜ" ^º…D¡0mجíhã´‹´‚ª¼œ%Jb ÿ˜:Ñé6¢3Õ¸ §¼r︷,?*okSξæù|ò¡ùá\ÙÆ ™‹@Êf?ç¼Æ5EÇVªf[[Ú)¨´µNï4>‚®IÍxÁÖ¬Nt5]º5¦l”~~K€?"«Ž>¼Iü‹ójZKÚhG›òñÎá?ÎN¿ž€×È«pšÂµD)øÔDÃ3»´Ìclqs¡c=þγ;X†N¦øuú âOOA'ƒ=Ti‹¦‚ oZßz!æ5Zôü°æÓÞßë~ÿžkoÓ‘òO¬óÐ ý‹.."þ xž†`ÊÄã/sˆ?µI5ï þ¿ô$Aµ¼Wƒï,0ëè> ͤ ¦ší¼XY‚•| 5ý½ùŸ× ²Ê,=n>9¼õò¿eüËÞñsEWLÞKùoÿ¦Xúm‹»ßÆße6Ò5™§`Ï›<›âã=c¾=^%¯£ûgÇ'O³ r¦fŸ/ƒ· ÷p÷¯æ§lgâEúÓïÙ3ï1qäŲƦ›X˜·«¥K®€ò½eëØð™>êÚ`ÿoÒU%ÆùÀÒ'ZêB$qм rõºPá!EµÉ>ÏxçÄ WÎ+x`&vÿzPU9awï/>þS÷ï._ùÍ\ÖÞµT†O㥵=ƒ³àÞ–ì=šTè5ãŽ@¬–„½(:Ñ·Ñ…Qn MÏ€ø0ùÇG7‹{Öà`å<ɿ8¨MZP¥kâÿ¿8xѰ¡=×½Ã^ÛéïÌ÷ç î~Hþ3@A†À†EM<ƒä®×¥d%˜d‚À¨:ð:'øjîêôaèöÕÀUçu 4«½oÿ³¾q¸‹2åa¿¬=ÍÌ>ßÕsFbшœÎŽè7¼\~ÿpû§-3·%/ž²ÄEx á¯CŽ`=þ/Ö ;,“§‰ö‚âœ÷« b(&€sŠ ù1@0]óø×ñ{ž8ŽFð—9œ)¢ÿ ‹È3Âáÿ Þœ]Õ‘·”bjÒóöúøÿrL2BÁAƒ˜p¨YSnÅ_Öþ’™É÷σAŸ¢œîjÞ¼j¤ Àœ¨ÿÅí–ÿmã¿ ñ.¬^å.óÿoÔýW¸³¶ö»$ ¢4cÓ@u¦\ö$±µ‰4¥scÐ[ÚLTÅÞéÒJÃUÙ俌yöM—MWª¦»=§ýnS¯Ë«£?™ÕWÇÍ€tT1}Z“áO/Jò?°üÇZ@Âө냒1Žÿ%Æ>2´ý‘`æK1óÓÕxPš¢@!ì¼\`Y’Ð%«ÑÐÅÃOÍ×gKÌJ „bø.j›x{Ó(¾ºìÌ% ”¨ÉÒïÓ¸QÛ€‹þïmÿ½—}žorùÁYkÔуǫ¯NZ$âpO»ÅÌãTå‘©Ñ‚Vë·ìŸ6P@ÃT‰h8ŠHxÞ9ë$þß¶6P¿‘p&û …´x—*[Ø€¨ßß›YU͇@¤¸Ÿ ‚ó+à¿Zv‰¿:ðiU|›'†§½)Õefˆ+( ¯qÞ_ÿŸtúñJÊØr¶qäœÖ`0á>ùþÓ…3’QÉ&sñfŽæÿÃ[.ÿÛÅ¿\b,` -”¾lÔ½mDèï,€mþ60þÏî?rÌ©ùÎ}c¾|Êc@oÒÿã™4 \Í‹¦p~ç÷Œù¿&!‚{2?ïj¡ƒYÕë‡Ì—gýા‘̲§\bd BËH뮦+N;0üSq'Ž6PÙòÅÿ(!ƒåvf$ì* 7›Ê>߬¢ðuØõTÏg‰Ø°rÝŽkõù=óób~‚µršÉßÄÐ?Ĩ•÷xZ)àÍ^Ï:Þ˃ȔÆ©±l uuQ@î †D ҜڠÿAÓí<Ü þåyw ÿ«Y~lv÷÷¾<;iH 2‡;›?m¸ÜŒð'cÀþ&”b0YŠL¬¨ÊºÆÿý‹3jºø?WP¡K¯œ¦ˆ>–JJEÞÊ¢~CB̼ Û̹gÝUðŸõ-kð™r•gÚ¡Ü,pñe`ÁßiP¸Ð×Äÿ à¯Ã 6¡æVcZ<]ªPàEyΦ%üÿlÌ`Óq„Ë=ñ´Ùtr»å»ø×ÅÿýßKºÛݼû®rglé·ÑÐdˆÉI¼éïýÂ÷«Æ KÜ?‰ÅÂpÍí •Á¤öÖ&øEÙÎáÉM<:þÕù^sÚ’N;?ÿoÒÉÞÕ¡=µ¢ PÎhc^ôÑ´ß dóhJ{ÿ¯K—SÁ6!¢7X§3è:9”Gta+ Yqê$:l„T¾°Ìóúà£òÛ‹jV÷@aŸ±€%‰Uà Š.°_—chÛŒ ÕÀªWµ¸ÿ–ý9fÏ›:ÞðPßV“?n ÿ¥wû 1w>ÍM«·«¦óTúùç9´'ôâ<5#þêý¼8†½ŽÖs $öuY×1@‚5éºaüŸfy¢JÛâ[0ñ/°ÜÝ t’@ü% Ï®†¿Y:›´&iJIxä¸Rxg‹üNb ø“ùrü#.R<×üñ¤ ²Í”­1Tn {ªò¨õRìÿGGÆü²jbQS½’ï™Û-ÿ[ÅUGò—8Ùfþßýó…î €íü6f”øü,š(áù½kº$4•«Eƒuר²Ü{à—^_ôΤþVóÇO{¦mŠ'ŸU’þK,y?x¹ }ybÇž¬BU‘–™œ‡) ¤ 㿉„ô¡Ÿ–*eŸØhà„pÎyEõø¢Ã«Î‘w ª|ÏÓ?–_¿®‹:3½Óš}þúç 4ï»s‚Û„NÒÐ@ T˜õÀpãÔÊ“ædéÌX_Œ’º»=üÏ{bÿzÊ½Ïæß.èæÉýG3 xÑ9ÈøuÄŽ}YåmPþ'ñjÑ‘Ý+gN¯Çÿ9w@¥{± &…¦$€äpÿ–M*å‚©àï§æ}â»–®ŠE3ô˜¨)©›HZ.uìâРÍʤrÃÍøÏûëàOîBñ6„ q7K2ËB‚•€?wÃÌ÷Û¦uU±÷™ßøå”„b\š¼ í–=þÇ·[þ·ˆÙ‡ÁÁ¦Ùœÿߢc~glí·) ¹Oµ! ëU‡ø¥uãÒ£’š¯ în£ð4þª<Û×Ë'0OÝÈÄN—ƒ©µ–Óýœ™òj#»ÿü”?)»ƒ>š>ïâ1ØKËH÷Ÿ "¿¾ŠŒó$þGöÔkŠÑû3ª‰Sø[H ‘ìåiCÁ±Þ=[Ú$!Ì$¢«²s@4Åáýƒ¯_µù”ÓeG]ûÙÉ%þnÑÇgB:¯ù£2€2#%€¸ˆ¹i‘s¼ t` .81@Ò,Åö‰ÿÑÅ’ÓÅFe_œœ-è5E‹¡§¿ÇÿJ!=g8Äß`î~V/‚SOn:S¾1±;g›s×8ŠÿûÿŸµR?aåõj‰ÿSÀãoÒÄ â?(ó7AÅ“ Æøz»«+ãßtfƒHsy+¡ÉJIþƒ 2‰n¬Tˆ¿¾þÿ"ü#Å'd¯¹BüÌ °Åe –“Py¾¯—üÒêM4Æ)űŠW•ÓÝ[.ÿÛÃßuÖF¯'©wkî¸Ø°ß@‹³„ÍESe(ùçjA½MC¿\:“¤½•yVeݲY6÷Ï ÔŽÊ'ÅÙÂq¯&zÕØôŒð'ÿäù³Ô€Ç ˜:Z¤Ye›ÜÈÈŒÆÛ:öÿ†øßP ø‡ ¼“2ïƒø$²Ÿ*í-væI}ËúÙí„Ù X¥6ÅÎ=óöyçÞ„¢9Ïob¬²ËÈU1' <i@Ï6ºÙXKåæÐh°6«Ýøí ZûÀÙûj»økä|ÔMÕ¤<Å—N‹œrÎï?ìùA¹ã?ˆÿ‡¢ëÂlKÀ?Æÿõ¤YðÐ?2d@ˆÿ«š&ºTM}?e÷I€hhQ¹!d'úêøÏÛö² pEøXí¬J7ã&Ë“A s¨wã³ÅÕñÿþ„ð'ŠßDöæÒ2ÚÛߥǶ蛔ðÈLÁ°“Cª|:»Ýò¿5üsª·Mâÿ›ÇÿÙ2%ß…¶ôÛPÔt©UPX¯|ôgcÎ_Cß/=/Wÿc÷f’40¢`xÖƒ*òõ¿:Û[œ4¬St1Y,ë°™þ”ûG/{›®¬ªÆì¯’ñ=Ru1X¤&8§¸fÚŒ‰Z N°Ü(,b°(‰cÙçÄeógu4üƒW¯¤ÈŒÍvw_??iuŽ7‘U}M2—š8Ø_±V@Þm¥ýeŠš]Ï$ùO‡J€b/ƒeH`QÛqˆ/ûѽ­ã¿:i4q“*¦-”…S?f‰jÿàU/¹xŒ þ ÓuÚýÎKAhÒ‚ âîO›ÆÊkÓÜ©?ÿc$ñÅÿàÀ›‚£1£]ÿ|)Õã#À !™ÑzÆ?vLF%`tœÇ_]ÿ—¯aHÀÕC,È€W­eÈ;qåÃHŽÞ¸ârSMc8)¥kRHQç?1ìÂ!þåd{õí–ÿmáïz{…øÿVÝÿpÅm^ï¶þÖ:íÉa=5ÿ‘ŠíPp‹{®+û38$f²fèî$•brÕl÷YjN‡§h§jöÁ›2˜·Ü²œ=M†ÛÿmðÆw+Ïúëñ?:JU1¨²Åšü§Žÿ°v¨zøºÃ<|ìÄCÄzYyi»…g¯¼E…\dMë„Ý%Öoà¸Ò4:Ö:…‹õ°<ÕP¢žN°{"çtÞ2sÝø×’¿zöþ»ÀÿbÄÈ$ºØÚ9òô¥§ÿôß¾¨Ùñ$b'üÑŸtqÇ0ü¯›HlÇøKA_Œÿ3Žÿ'ã*xü„UTn*‚Ieþ@%°v°º=üM[§ )LK+µ\É\Dü›áÚ0,Ž™H¬0ﮊÿ'n(K¹±d ©âÎF^8m¢2Å1};  Ã2ÚÑãr»åKøs¤áÿÿ¿‹ˆü°•ßš Èç‡B¡V]|~ߘ¯N¥ø Fë–'¾ÞF@³YÕväå­»}2ø]½<šœ/ÃØbó|%adjß³OV}’ÑŸÜÓ„5C‘Ûü£)eÎÈþ¯» %7(Bv™wu²õÒ ÕeŸœ,CÔ/5‡¨aH›–{öÏásÁ j+ÚAA@ {àWu²ŠƒA Ð~Ð3'Ï?|aqÖãÿðàŸc$9Ô|¾jɤº}=û´÷øK‘{~pÚÙ(P4P½ŽŸ À=ùkxÄïœ:Šÿ{ü' Ô(þÊÑ¡GÒ âÌù¢ ´bti´4¤4 Tÿå5ñ¯;›4eÁˆKÀ7ù€„lÁƒv[Ö›rÃjÖ] ÿoN{ªW@ÜŽøš3J± €ºa §‹SøcØ#üm‡`4H€‚‘ÆMª±<Ú¿åò¿üãGAðŽ7øÿÛwÿÃU·}Ñ[÷[ËTZd˜\QÓÿ@ß/¶Æ¡/TGžÏô¿´±~ƒrOzƒÜ½ËÂÀUq¨Î:I–ÞS±ÉÖéîçoŸ‹WÉ+ó¼3õhÝP lД97AþÁI|åÁ…C‚‹”‡ÇÈ>¢Ô¼9±¡¢Þð±Èp'•uŽZ¾*rêøò…døû Þ¿ŽÔ‹¸p'öQ4®‘<¹°¬ž,Û0æ[ú‚à ðøúŽðwg ‘«Y‡ƒR}c§»÷¾÷øWÜ5Ù¦ üw …F Ú;ÄÿÑM%üáŒu+uýiüÐ i¿¨k2=ð @Z‚وà'€Ãð7×Ŷ ÃµÛøÆ€ Mq¨ì ÿM¤f[³iCµ|%ü^µ¸¿lTbˆvŽJ…+)A€ðTÛ7Üi3-à}däÀ00ùÁ†(ËÃüvËÿVð?Z5u2À†øÿ»¡¾ðpÿq 2ÒUŒÇëÌöwÌ›“¥ôýBǦrnSñ׆U2£0 ˜¨ýAÕw1ØA–«l¯_5¼(%¬´»::¸ÿÍ™¤Â¸5gji¥Fw$ò©2kBfíÿ±œ¬É Ž£o¸8ÜA´ÿSG€7«lú¢IzéµÞÀçyíÄC(s½à¡oL4ógFܰ04ÐŽáóÆ@pÉ‚€öA^4Ô}JôÌXÿ{ü¿3üOWµ%7QÑX¿ò ÀÃÃO¾óø£“/=þæz)5úqÇÿ—ØA° UöÑGþô´Y L':·,°_ʯS³Ñ@_’>ÿ‚‘êuNd×Ç¿\±‡Ç^^—¶ÊàýÑ8Tá&ØT×ÎõUðÿvÕ“§Ë)±žÔÅã‘é8>&@Êÿ`Äì”ïÓ0Jd9¨l¯½Ýò¿ ükÄÿòøÿ;£¾öp³¿‘P…VBôª&÷ž?þa5ƒ3t M×%îßXÿÃ_î Õ~bVº*+ã°c¾ ü¼\™ÿ¨ýƒÑÛt¥žâ'5¨Fw¸ÿ&-6öÇÿRYY÷èaвO¤}]öÓê“¿÷ɰI–˜–(DUêQôªy‹ù@6ûs¼$Œ ¤CRMîLí6U@q`º(îݬuÒ8¾#l®=þŸ¿CüŸ¼ /'½ÿáµwpÿëKCCsȘñW]0˜ÂqøE_Žp-€“¸€­JÆãÿáÛ@Ü@† ©ô'Ë«>|ÀÑ'p*)TÑ"À}Ô'/þ¶ ‰ïÄ4±yx ðoä†OÁâÎaÈÊz¶üUü_íükE6BLÚ—5ûÀ‘ìCŠ?é`%GƒÕu¬ eq Â_·ˆ?ž¢œ=zv»åÿæñŸ¯}G€íÿ­¸,`ÉWxœì¼uX˶ÿ»&@p×@€,¸»;wî:ƒ»»»» î Ü]ƒ»¾ ÙzÎýÝû<çžýîýÜ}Ö=ÕÝUÕ]ëS«¿5S5 âñtµõõõüÇÃÿ?™«³·¿×Ÿtí¿‡¹»úÿ®°ºÆJ… A´ÈŠ/¢`ì廡e'íò‚rÊ!.¼L%à5´MæþÊ+/P½/…l=ó."¡^Èt,;îä Óyþ>¤©g)ÔÖlþ(·V·‘½ÉoùÚÓÊšC}©€ûóŽp«…»(Ѩ8!v· RÖ—¶Ö eƒî´ªA˜7^PÇIoëÏÊv+J’´ÓºËžá–ŸÐa†åjOÑË\î2Ë-p°³¡µXßÕÚA¨°×CZn.Ìex)Ø1±ZxD÷«ß1ˆ#@<ÊCâž>¼Ç¨çZÐluÚ%ßErxv1~TG…k:·%‡’Ïyª?ÐF1Ã¥N¢WWLT|ö¦QgÚ¥ÃÎ |°ÃiÐslÙç–¯å2òUz.3/O<“ûÚâÊä_Õs|òŽXá>¬\nI® øèµIŸäà*ãô22DõTs†ˆ{tv?.äÒå©Ìð˜½HP|ËÕð¬u¨:qK¡T¡Îá€çMNŽO•Ò S5¯Ïã'VÛÔux‘VÏ¢ž:HíäÌ}\ˆ7ÁgN_àe¡ð¥Ygœš4 Ð'øøÞ~TK äÞ\UW³ŸFãèù.Wœ~¹ˆzSÀöNºdÐ?ã(»Ö—O~,—cô3¸´?—^<î©Ãk ɲ±e×þ-ϵÌp¼Á;SX­¹È¼y¼5za=õõ?•¿ql–·ÛgôÖ8Ùq‰ˆaoÑfQ÷koÌÏFj¾z…f^@óÙ²êÝw3S¿KÀo¡J²j7JÌÝ:A_1‰û¢mì297¬b@%Ûå ¶u½N–êQ`ƒÒV(™ZU©Q¤5_ïÇý.z•Ñã·úÍ]IK‡ë.,Lïøÿãù×6íÝÒæ\œGuÆÿQ€§À ?O‚.®¾~Öèãoa.@ÿßì=Ú.äÈÀMèL?ôøb K¡$”Ï$í3™5á„ÆÒo˜ò¦þ8ˆî¶;ÞxÜÍW®®ä®ÇÌüƒ°y%üûÕ¯0Ô ž„ ÉÙÀ©iˆ0.P5Ê$nÆ X_¸+Ü%›ˆ;„ £J=;ˆ;¨†ª¦¡uï)^hsßU©ò‘|ð(24Ï Ç«>žtk­®““ŘlCl¡ƒ[sK(…êrkàak4¬gáp¾ô!´ðycÚ©I¶—jv=ò½.´m'ƒëþ»ž†±R³(ù‘ï·£;UËÉ‘MÈ>>Ï%q{Un]2îBo9ÀÃ[› êºc,ˆ?º™v.ƒvbŒó°sãðBÑPÔà&„ÏHf©×n¨ý½6yîP¢vióZrÄD™õc /öœÃFlÙ5¨U¬t×> \yW)°uæd&É41—„»Ü9ˬ5yWô=Â2ÝÅâ$»2¸ =„¤õ„Ø“¢äsS±¼kŸqD’þ{„ãXÿngLí¶`ÕÔAŠ$È»žÎö‹ÛdÊYLî2//k5*BsY›ü5̪xÁ@â†hMd‡_®íqÎ/:Lw?3¿®˜Ö«>â‘.Ió‘5öújpiì!/¦¨l½–PkAÉðš¿-°W?s¼ø£,Š6,–† ¨ ]ØB±#QìMºÈê ¸m*çŸÍßã]“»ÖºüP/´OjOøËr×&áPÑ~dºhXkh²eàÛ˜2›vèþË|ýD>Ka¡e/ê .!pž7aÝñ¨¹/5š>ÊzfG8+ág층­oQWL`L¢=sšÚ5žz‹ÆÛ £á,‹š„ê–RyØžðnZÊÒß³À_ÔÑ-aFR)Iž’ê“*ÿÞõQÝåÚòÞbÓÆ˜Bv 4MVx 쩳µÎpd–©·i©]9—û×ù«·t_. ùä>èÕÎá’û×øÏy Šôƒ¨BVf_¥á±­ÀƒŸcŸMBe:æøj^•Ȭ&”×|<_¨AkÖÅ=aÏJ©´ ¤90x¶{oþ‚r>T2søÊáåñ`ㆂìö9¬'Dô˜qçÏŸ÷\š‡½mͺãQH]ºürU4â(‘+ç--.Œk 5 †r¥bŽ£Æ(NÅÔ{\NŽýfåi¯é‹Õòk/B\Ýä Ž­Êþ‡h‹äÇOì~£>±&&£Åä77o·­?l(ïÞ@3ø©«„mã(:£ëÒÅ|ÖO¬‹\4Ÿ—± ·–6 Øpü{ÇÿÎ?’²a–ˆø‰î:OúÔèbëâóg 0À àïû'^ÿÿ¼9ùøüº¡õåbš$ž;¦(§Ì8C-°SqrNÊá¤r’¸n…¨0=1£¼â|s^I Éãdž{N•_#\G“ › ¥KðÚDÓýkƒÙ餄*$×Äúûœ$ ýlܺýÔKäZ™÷ 8oNí¼˜Z#6׬¼‘47Ï^€ zx™`tö©ëÎ74ØX qož-TÀù¾ €-¢EË×Í:àþ˜yÇzï¬ìeEj¼¾‚ók²­Ï³¤^¨î“0A},Ó$}žnFA/³®5Ú¹´i  íKV?[Ç|èt=mª×J"̓Ä1{|]R× ùµÓQó}£~Þ‰-ó» —%ôí Ì_7%¨9Ϥě¸÷üçǬnmÛ‡¢àdšÆs±Èç '‰¿"ºC$‰1O²Ml´°7A_ݽE3"ÅON2™9SèÄ”þ²çòB¥†“y{2‚9ßÅßYBZÞÜÏåa×õµµ#ÃI¬}±9¸]õýò¶à4~°_®9˜C³D9CO*­:K³‹îÄrV|X!¨ÏÐ[½BÌÀ©¡~L4ÜYºõãpM‚f0_+l’ê!JUçéÚíæòBŒkn?ÍY,^ÌÚh9Møö…””e7Êì.„¡]îj‚JFí‘ç fw*£¡¬X°”½fç¥u'©dߌk®ÜáÒWï2ë°ûâEO¯£àŽûóùó*:»fx÷ŠqÇ\¤ŒäRÉ…ú+¹&Úc¡!c8ª~I’½ f¾–9‡OYÚ 3§Kq€vJÉÀ+™MJ+9S&¤v@®ûr$ɯÅ9tc9Àd¾Õl2ë0Ny„ˆâZàÊQźÆ,߯¨õ1já¼|ÄÍv½!”:œÌ-ÀhH/Ö˜½=­ì%ã§Öþ…÷î[Mhcw1ºäKàòNý_aiÊARž‹{<‹XÁÔ·¬JKy!ó–Ö›Ã,Ùy~z Td°µˆ.ç_å¿,×E4x´²œÇÄI÷ÿ*aØ>kJ[Äxº>@“îô)ÑTô¶•×5«®Í\± E°jd«â¨Kø$,J Ao°VL^ÕMβ YèãÔ‡æØ Õ!‡yÛµÿ–?·ÎgïíÆ;g±I6:½op0Þ¹“³ˆÃíWÑÜW޶„($ž}êן/ü _@^%µ†ÈïÌ»õ.@‰èÁlõ•2ØÕ-ì‡ùéfnÜ]5säÚл ì*`YL hy\²E ?sÓI˜ }P«‡ÇÍ—½ fÙ=‹"~€›œ©:¼ýß;þÿ`þ"¶îÏ(_µ¿F4Ñ•Fÿ½6¶®Ážîp7gOï?õþOÛïfläè  n²¸R×wòÏÛ6gS¹˜J|i1½z¥ÃNsUá%÷]ÝÞiítFŠ[}Áç›^s½onyùõe߃ó +^d•0F܉&ðíË— F šíÔÈá'Ó6÷Í ›è5VPW9âæ8l=Çh¾†'cKß–dÄŸg¶bz¤Ú›™–ðÞ€ LÐĮ́ÉEªAêOMÜœ§4ÞWìžÖÒø\“˜ð¯FSl’l.f ög]Kuû_¹AwÛ¡¤Q•Ì$^’ ž»¸ÁB2 (B!+iß«}¹Žœ»œ¸bÕ„]tï—›G ®. åá©\Ÿr rº"ùG¼. n•Zªòª½Å4‡ œ³‘Õr_ôد¯n¨G€$¸AdQœø2¯sèî¥juD³µ†kúc;¼"¸;9 Žù!ÖfVζçøDú…õ¡1ÜVZa‡ˆémšöB—u»&Mƒbw®o+7á+ÏŒ.Åêå¬HŸ>~µL4£§ÆÐiPc8Ù’ƒñUç#¿ÐHÑéû€R½>ìC;m" ³öB S….ÿÒÇ,<ô„壣×J·‚[Í¡+ßüÜ‘õ~¯ '{ßï?ý÷wÿ?ý&þÏÚogl_×ùʸ¹_#I0¨¯9ÀÆpù&~%ÚØt¶t3öN%£­: ‰¼,Ì’€ ztÐR)zûhbyâĦnúÙñJ±õ3IÚÊŠ!¾0 Ê"WÁi,K㔀¢Ï;dú¨‘v[ôõ¢ä{ égåÚ©ÜÝÉQ­¾{ôoZgg¥@=òÑá·ž!ƒP‰»Š‰‡˜â¸Y^g©¼>9FIL ­oDà ¿aè)ÃíÆÑù”s£‹‘ äž;iÅÀ6xO…°£ŽO}â'| £ÞÖÂÇ%?7ȬþþHÝw£QOHß»‰Dþ£m~ú„nù’7[»ró ¼FÎéÕ»Y).i¬E«qbSU‚l"¼ÑÅøƒQ«ÖôÎͤ¢øô»¡ 8k·ÑzÞÄðæHq/Vþ¡µ(vƒ©ç‚ãöĨƒ¬°†¹IõH·^19•ÛŽæM|©*Tå±\¦â·énE‡$[(dS%œ/ñ9u»MEMãŽòHuƤ“#ÀÝ_äJâêx7àÄy]ëxYRFŒQîz»ð‘ƒãÜÖÍ_Ù|qˆ÷äÞÓA§å˶á‰Ä¢Zwm7Jâxs%³æïx_Üf\ÔXнžÐmî²JÏooUéú%²¢Ìú=ʼnƒÎ~…üŃ}’ÈË›òË•2E$﫸]åîÒÏê>®þj ™ þuÐ:­­cÕlª¯ê šÙ7°”ímqEûÓ^žýí\ŠòM¹‡iNæŽùÃÓ"ER.^½É`Ô¨8Õ vt2EâFŽ™Ï5‘ TlšÀŽS ÙÍ­,úƒYk°oÀ½û:q,Ãs©» Ãè£iMšðÎu”#¦™ Ú&|Ù ‹¹p¿ì‚õ²=ëƒgtÕÑrËÛoÅõÒ¨h p+µ\˜ôV œ.—9M6Ÿn«v;Ù»†u›p·¼€ Ö÷¢«,ò ¿t4— ³ÒÀ[üXøyb˜›CŸæÌR >' 3„R² EÑòEÒ½¤$Í#©aæT kÈlHÁ¦½TèçðŽ{‡‹Á°hƒx¬v’ˆ–M°xdÿ ‚†;Ÿô‰©m«Qù«—ަùãVZò‰Ëã4ÜzõÂ!´2u…ÍÄÅÈùÁŒRY/û5Ê)i<¦ÆñfTp=âyd𓮉®Ú Ï ÖcNü_‡œ—¼,"ñV¾­}˜ÄrÁ¹]H¾+~áQóÔ Ì¶·4zÁÁ_ˆ}<ÞUW~"ú¨Þß;þÿPþø ¸WD%s›ž:¿S ›- 䯠¼@g7¿?mâÿu:ÿ: B€¾4k¶0„ Ò†uÖC8€lµæN„Hìø`5h ^¸9`ƒ*•Ôûþ•oÛ¾9™ÂŽW¸€–Ž–Ð#vÝé´/T‰Z“ßkÛhx£ã. vgBl޾–Éth„°×ð‘h¨ž"qPŽ«aÉöœ›ë»°Ýèkzs•Ä>§á¿« Òõè% ]fÎõquRIðÔÚögʹԺö[Œâ\¢’s¨¤ÅóL8WST(ÜZ®¾Éž.D ç»z3Á(s¤éŽP>dõ¦ÜØ!ÕljàrÌ oÇB ( ôƒöÄ›g”,lØo?pjW.)díÉ—Ëíi.UEèvÕBåk(fE&‹‚žÄi¸Ë÷ ·ÞÛºÑïÙŽÓ]Ó…ÛÚŒö¶~¢ŠÕ±w¾¿©3²5|Ï‹iá8w]^Ð5]Ù-:@¨áÔÙ"o—Á¡g0òYŒ ÝÛ+G9Œ'œllÚŠƒrmYN÷õ—\I§4WBØŠ›øp'¦“ã¡~ëŒYÑüÌÈ(0ìœÎÒÜ:Dq‘P·ŽôWÌSWÚ, çîKx ±V2Fm}=Áa>Á ÞfÆTûžl·š}è¤$v„Øfú©-»ûòK¥þï@5X‚OV³éÝÐ5$náÆµ|1"-ºùò¡ÁCÂj t$†ƒ¦¦ð££æÞ&Ê©ãQgºìH& §áœ¶Rº!vŽ[Ø×Wî†çæÛŽ~Š²è£…‘:$å\3"­*:Ä…(Š!~iPMÏna©>0Í<ÕO-p3‰T™Â¬ùøüô¼ ¢tuˆG æCÙšŠƒ#)Þ;SNvbâ.A×&å2¼½—Σgp‚®Ü¯ƑΒ%ô¨Ðpàÿ7ü‘žÏ¨ª.ð0‡!m¯° E*>LHâQœ-^¢F:Îå§¼»4Üòè‹/­Å²ÇÿxAS¹® Î(2f8@èžѸe³ÞÕÛ ¨¯Úérì}°ÅBBÉÊü0¶ùòWûÔòFð-—VŽá}A™a÷k0£œªU¾ÇÜA‹ëoÝ 5ä´Mõ1Òúi Ku:ØYæ+I²ªd„a}¡ß$† ÁÜU&õ6кý˜ÚßÅE–o°°ûêàÍÔPÏÌëîä¹±Ð;frIJì­k67Þwë`5­ÁÃä¬ «¦…ñ\±AøÄtj<ïøÿ#ù§”JÊÈo³„|Öxó;a:8ú{ý%tàô÷ùŸ³ýÇþûÍ @é\D¦×Âå–pN³J©2í£JÇý"d³Îz5³ JÀU¢Å€‹œæò']½ªº{ÛF¥DÃäDÕëû/ 0"øP½ã;;ú3Ž« @È»LØÄ×]ç(äÃ2PÉ»O¢!_rsD6“MEÔ¤ñâr ð\ºVbœyËŒN{i¯5`cD&Ô¨I4BRMCÆÔ$Á >†¿Z¥CÚ{[äß,¸’Y€övb@Ë’wîw º¢ã´FÐÞ#ÄìÞ‰0j-&”F}Å@Þ\ФV9Š™Ë²µ˜»Bº~é‘ïÜ ïKYuŽšAÎGt(tW"…êâW;µvµ’ÿÕ3›ßì3ÅSrÂ*|+¡/ žŒ®/“ühv¸„µNCšZUj¿Y¨ë‘ñ0»tÛey_ˆ?Šé½ üÝ=سTðžGyQÎ\7ú×(úè*P¦[Íû± ÇZ–¢a[ýpó‹„÷ù—Þí€_u)ÎSUÇ/ÕIèˆã×–!§±v¹}½¡£ ™ÏT×÷ƒuk–LÆmœ Ø£?i Ió*ŸeæàÄÙ'$‰¯#›ßöYF¥`,ÐOe2LÄ(ÎÑÔ<ϵýtÛIb‰ÄÑh¢â®ò˜xRK|ŠäP¦’)½w5ò.¡} ÿEúà—ˆªV6´$—Û~‡þ1Z­É¨ô¤ð¥°go<êYþ¿ò=G ZQèxüœ»Ê+#êûn7lw–{ÉÀšžƒâ¡Ãsƒ2÷CÓ0µÊ¥ùнêçL]µì_d<:!)Q¬c(…0š?Xna‡¿­;/DŸ^ÃËüDÛÉYŽL\ßÜ&”®Øåì“’‹'l"i¬äß~›pˆ½ðàãŠß(—Zϱ»e¡™Á*¤÷­\m‡›3cŒn}®âp£¬¢Óy©¥fßÔêyQÛ*Þ >ר|Dèî¶©*¼¯gø¿áÈ«d #øÐEk1´ =nKø0$:±=H‰’`5å:s‹Tõ¿‘ÄÍ8sïóaÖêп·úŠk Xs>dv/Ôöa£ª”YS‚õë3NÐ&L:—‡1}¯þë™ÖE”«ã ¶î”¦c®®¾’©x7‹²—h–cÐð,` Ø®t-Ï©^p aoƒ-FÑYȦÜäÑ „'Å–iEÑ~ÀN;M³ŒÑ_;Y{Ž¢%IKupÁvw†2‹°hÅôæò±•ocBëº:Jî5êþ„žÔ+r%ÜúåƒøR©<,²&åô¾¹õÝq³jUÔ)MdA²ÍK‡Ö¤X.cÀÉÄÏY÷èè2][©y^˜-nº‚¤Y.3ê&Ì~FýzÔ/yLëƒWÒü‚<“Äd¦öòÌ$lt¡H9e‡*1ʰÎdQÆ´º-Y)þfñ (1[BÜéNRX"cáp´âyÇ^á)ögLjoÊ8”†s]@už¿¤71U…äa.5²õ'S I–Oé¬cÈÂÕÝhaP‹°¾5ô?Ù§uØywàw…_ÚóAgþEsë°^ Ï m(/7½ ô"5ä(ŸGYœ7öÂ/#ÖÙw,6Å`™‡ÕL¢±×LŒð‡m½-@u(CΩs{vz?˜{–—žçJìTG‚”:'æÔ~$ûßñÊð—É5ã¼3Œ^ÀÅYV[ç)³œ;« U“pôï$&ê¶Òy€"ôÛ#^_3Y¨_Ãa‘²µ$ŸÌË0 4tJÑÆ¤r`½Tl|Á€¦> þ¹d¶)ÆõÿÁ¿ ±àâãÐè—×%JeÆòJÀ­õÁñfÎP‰zê:ŸÔ‡â\ ÿ†QÄ1ÆH5 å‡VY!Xd!—¬eq5ÒÑIgÞ‘z°}á\]ÆÉŒíYA0ã<Öå|jð˜Ýq? ¥Q/û‡žÈEíaò-ØE¹ºQ]js9Owkç{Ó4É­blaðÆª»ƒ7Œž&óøÿãøcŽÀtžÅ64üF€{ç À?yñßo èúŸeŒý:É%DjÔFÍD_”Ö»ÃhéóKÿµM煮¶J}yÒ"ÁŸˆ¥i/#èp‰Œ 6Ê3ãú|ÉäÑõ*mC}ÊêBo®µà†ÅûŒ›Ó ú4Žý,g¢Øï26 q9¦PYÞóœEν5àaò¤ýî9µÄèÎ'Ì^d•Öð%¨¨ø1“Ò^lûh3‡çBJï¡âl§£B ãͲ{<¨û6…`Ho"eǼò˜Õ.™<0_ê£ßâø04[u$:W#òöBÓvÃ÷Q•hl£œÇˆ¾ªèK}÷uÞ¹ÓúÌI¶›¤ÔÚó™Ûµš=?ÚûhýuDí6Ûõž¼®}ê!æsÕÌØ™Æ–aT†ü‰Ò,ö$ Æ;ŒKU;š¤qïDÏãuããËÑ÷Ñ/*5àÉH;æ`F7ŠzWÔ £î½0ù¢Õ‘@h!¶rýÚ@YitlL jØ«RÜÖù6S½Ò³<"._ëæßÍ3Q}1nGS\;:Ë ¡“™;]P¯n‚a¸ŽÄ€UWõÓ-\™Òòý Ðv2æ…Á—è HD rÂa_c¤&K²¨_Œãã ;ÍyïE§–^ ïÛãYÝ4Ý£GÄKàëêÚï~¶oßûBS‰NàKêüD|Û7Ï„½â–̱·Ó‚¸Æ_Ž?6ͺÒm„ ÷Á4Q%Rþ“{3W4Ým Ĭ¤ë` sÝŠFWëL-â]1§"i7µi ƒ«T">ÏpQ9_Ð{@…a¨V¸rl…¸Ï0袈ç Ãõ™é Ç©W¶gs#••9‘ ô!—VtS)çó ©ðæ0®°í(ª¥·e= ƒÚò¯ç’?}Ê®qö†¸åhcRH‰×r `¶»SvM†…{·ÑU4&ˆ‘xeP õz•ާ›1Y•¾eùËj¿…êY®{U‚*4'øÅá"M=1È!bLndµŸ±ºÆv­Œög¥ð9½HAÍÍÞVµ‚:ÕìF©Èû«¾,G0U1œsbïæ1÷½ž!uÓ8aTCþ—ü¨èZQ% õö%ÃP.ÍŠ¸¨°¬‹@?ON?ìrDôNG¡ÖéF;ÙömJ¥;ÉÖØ¼k}À4ˆ–¤r˜1~OæÒ™Ûõ¬[jV8&Ñ%(9ʨ¹§³NkLNÞí pŒ LV ,SkTVcÔûÂ= ßðš[½,ƦÀÌRZCPAÖ¤}‰]]³V×ÕÎñïÿÿ¦¢îgh5Ä Ùc¿S;ïÐ?ñßo èäîç÷gßÄÿEûe ŽîTÀ¸ËHÔžƒÓÌbˆGÜüÑ—*ñ˜™µñÕ«l%P; IÂv3$•YS=ùµ] š2çÈñr Nv ëƒ@AÉdÐ4é½Gu®c|›‹¥êrËt¡ñéWT\Ðd/*èË윳Á 9uöbŒ@Ba¢ì»ý‰+ŒÞb¬Ìz- Á~±IŒ®C„œ&×\}”Ï@ê©Ö4!;ƒZ'£²&ó emËEÖ¢¦ÀåÍì !ÁiÐø“4ø“Z›œJðr˜¸EÆdÝîEx…/:ô¯=íß®}‘ž\>ñ/. tÁN—\§e^×_¨P@Ê\Š™×/Õ!ºŒ-T›½Sz{rÙ³Ë߈λf !)Û¥ñž¡—õ2_¿?¾{Íf7[Ø=Ó$V7œ˜M›Wà­o¢Ú¹^2x¤4JÖ¶>B<¢‚…R– ìkÅ0ÝåÅs-›RáuÕá÷_¯s² å ÃÇxe#FƒD˜ÕuPøJœ¢­Ém“q\P}„èGöÑ|J›YR)¸"ò)_$À÷j§ &è¹8k[ýg#»g9-Æg™ qò¼C™9MT²BÄÜβg\R¿5Ág”?ê†Ãz{nÒ-~|0§ ]¥¤FÝßQ=à<äõ¸©2ã÷Q£â«Ò»×÷ŽáB*›’Áríï ‹Sä¯m È·¢ÿzü$ÐåÊ×™4š¨ }l.H¦¢„£òYbJW‚M¼ê?[ÎÖ•‰3Z^oªÒ]~â1}…à’ŽÃ½€¨—„Õ4J^Ki} ±"h4ÂÜlh™ËÈB•ÏáÁ“ƒÎ/¡:ëôÓµMÀD9M¡´ÌÉÍ`\ÉÄ+åF ’h•¿lxeèp‘êjI´2­zÕ#Á´÷Z+$ÊD/ÕÆ-؈:ÙpÝhS™"­·ªgå%¤©Ò ©¬+"Úÿž'£™ò>ц]âˆUOo•.=Õl7ž‹÷@n©Ò­±Ó…átLŒÈFsRøûaŸ¡ b/®,kTÑg¼vêúÉazáÄÊ2nÐÂõbtæ¦/F‚²>g´½’rú¯ø'—ã0µ£ÈÍ—‚ðî”–´0fÔ8}¨âŽ5êYñ5Ë¥Vˆ|†OGì }¨+yÁ{C?S–k qO~;":a(µÄˆƒý?§åùözF›NøöÈç[2‡=[fY˜çb9q¦é•¬BICÒ§ÝÓUÒYä0ŒÖâ“2w;«hìâ?7E²Ìupæa§%`èsåOþ½ãÿâ¯äHHÆÎ¸Eáô«&Ýí\CþjoßswòøÏÿýæìñcÀñ•– Põ~ L˜Ìŧ쪋¯¾X„ÓÎV…45×´hGtúW/¢oÒå¯ë¯`Mû‡Ý-èö^äÎwÔkêÛe’·žˆjq©¾až2±:üâËm‘6ŒæË³>Yéƒ àéqK mq¿ö Ù˾ó_øÐª!¢QQ/I(݇z¤Ñ\.;Ý|Å.ÀŶqzXÄVO=qzHcrÇdwën’¬Îw áuegzxx¿<0‡NXQ“Ù¡#q‹ñâV¹Ú y¼ìèà£v+rnùôõ+Y …voß2ÍÌ‹.\x&Ä‚ø‘*Àz½Z©ÜØ¡@r¢ï†"²nX»ØÖb ¯œ0÷NœÏ4áß¼y)ºˆ |ͺ…hB½´ûàíå~|^g`° Ñš­Ù½¹•‘€þ1K™jâMÀz}+Ñ>?ëÞNÜ¡DsïJZ=RÚ¡^ÙœñÎO+¨àŸzp†äqê±e^6ÍÃh) õŸ1•CB¯4X‹G§ä´I£6¦Ér…cr$– M‹Ì1_âÂÁºëûq)1”&ÃïCP¸GÉYUÂöž@­jãÿÝλ=+zw²´›u_r’Õeð!»×}YM‚yzÛßdôÁ¿u]ë<ËŽ–x7×>6‰uL‡Â¦,ïkm–ì\¿z[e5j¸8ä­Ý_‘¿Ò×S+œ%ÕŠ7y1‡$ò¢LÕH/pro6dð?z·c—|™é(¥Gùj×eZ嘽脖n#^#7\Wÿ*>õ‡[szžDÜëèk‡–×Ü †Ïit—ÞîcÅѽå¤þšÍ‚Òc÷(1 ç»ë!L1Í—Ñ( ·´ ¸š‡õ´ï•EÈ4ý›rój—3Ò+ðB—4Ô³´ÜÓ§»ÏïBð{—øâáZW^÷@ûz¿ÀÚ×á›Þ K5\¤Óøßó÷Ðâä\†³¿ú ³¸Ø€Õ+\ïb&N÷U˜åä…ì{Óù i‚ƒ2‚•i..&ïý˪mÎc¿÷=—J»µ…uÜS¹>9M±ÑÎû#µD¨/CUEØmwtþ þAšë¯¹Êì¤ü§ßÙ‘ö}Uˆ8l÷;AQèËT¨£2iN‘(“gº¶Rì×Ò­ÅËߨ% ¡h\\;ÄóG~èÌ‚i©@³”õDV.á߈)e|ňHaå™l?ÞET¤yý–bgÐ_y¼uX+Ú —ª~ÌžÊÅZÄCg(0Xœ )ü•Ÿ÷ˆ_©ÉíÝß:þÿ þwÒN}ž³±¿JÀÉÞ/䯱øï·öŸWÿöó @(zD™p‰ž/‡9ÖDŸ5 [·éFËWæ“;7XñÉUl·XwÚÚSbI£x¨Da´¨#ZDZœ›".Í”´Œ£Ï6PúÈ Z“».È'W[¶š$ÅÇaDHûCj@1ôgWæ…!ƒ•`¥Mu}nÉún8 c6t+Þt " ÆæPž·^N5.ÁPi¢(è‚MØ%n’Œ]д°çx2{;n4ÄGñ2zè &{C7øíiEÐeñëœp}vk¾„:‰ÐŒHÇUŒSã{_uíU„o½sõ.sÆr.¤õ+ à:dø!ú &díã4«ãN™üÛ;Bë¾·fG"·¤$GüQPùìsÁí¤¬7n©B$wMøiø•s„Ô\ÒÒnúNÂç ÏQΑx"Zïç\ìUËÜ;2‡ç,dCyæ [¦ÇÇÚÇ͸Ôè´a¤ÝÞ«žÍzE²‡­-¼§Xˆ×c,6ÄÔxy¶­y\‹¹Ä³i2ÕÒ¡£"A3Ã/ì;ËÿøñÍ„ºÙ¡YÈsÍë…ñ(„wJw$¯­õëðו °0én`u}U"¸^ ƒíZ—zájÕúï'NóŠ&¾•B1N ¶“XºæF`RŽö¤ùç,ìDæ¤{+Ь‡i–îÞ¿·ãœÔž«ÜJ©š:·9§1á7Å]vü5ùßLÆù_³}<ŠÞ)zÑM°!Ø"Ã_Ãô~úØ´Çáþ½ù@š_ÛÆ[ëû½„‚Üy ÅàÐô(ëïøÿcø×_ÐáOÛ•ÿªn¶€Ð¿â«wÿóJà?Â~šË÷š· CÏ FX—”ÄCi}_)«¿äÁotZ­ ®ÿY1×hgКü0©„«{Ó›jQô…ú³LËØV[-vXïû":E™(x§KÓ‹œ%{ñ »g¼=ú"IÇLÈ“ü]ÅWQP{jg.£¬îovèX2 Ú¬Î“{R( OÖ^±aù¿¤†×¿Atz³9r£“+ç&¬ïÜLé‚ä$Ô¸hl~ÁèÛ†bBøflÖ’ºõÄÚØ€Þêsb1Àuï‰`fãFXbPëE^n†.p1¶³Ž&HÙš5ë¶|N·äFô ÌLC{†å#‚„b”¥7tK¨Í ]ÿfÚ¦XGÅ;^žnΡusÞ.“3ÞAEAË ë46¬OŒâöáËj4Ï8ŠôxÚ ‘ÑmJš·±ÄaVÚ;ö3:öóÏ»YÌymn´ÌDwå Ì«]©ód¹W¢ÉS;8wosüYš<¸1©Ãíå‘øã­»p8ýó?¿.‹^I+-{„uøìÄÏz¬­Zp•ñLØÍâµ´Áû“à»”Äô#‡Ix5âŒð÷6ûÕé’<Öóƒ¨áYþ¶VÛkÊÌnÏ'/žµ¬çйðq͈õëGYÕœxÙªe%ˆÆÉÁËà”šå Ú|\¢º?4 è?çŠÌ’g½‰ÝÄläòæ^”÷³•èu ÐR… 4Ç7mD¼­GÑl¿ÃÈ„ úœYh»„‘¦GX³EÚ±)ÑPÙbæ£C!92bZeû0,ïõKÈúBš:QNm2gTöÐì± W}®¾îŽQ~áºEÁ҄ΨvšÒ —ÿ=üù^¸sðÓ3tu¼|A2ÎæÕ–À£¢l޹‹ˆÞËï蘦yŒ·ýlQ/¸`Ó?ग़µM€¤±9Û)ÖÒsâ6aßzeM{ÞIJíZ§Iòü‡¥¯–KZÚqZÞ§t#Eg…r¥úë.ÚdÙ MÊ 6‚ z®Vó¾ FùûêõÝÂBRŠ*}ßõÚÓh:Úļo2¬ œ§µiG¾´À/:ç‹zèR'HëÍË4½ãú`…'çÌ·áÕU¯±¬kIÝ–p ÑÈÜ(zW‡±–‘¼ÿi[ä=ºOôÁÂtÃô}cjØÒß;þÿþDRAÉj?ëhïü×Yü÷[8»ÿç•Àÿnû1@€°¸Á7©oxÊSRž¶â|§×uéb'¬f&ʸ‹’ê‡ É:ç‹]1DÔ]iGî‘[H‰¢Ž@on¿cm¬ÌÍ æQr ¯I‚ sÿT(&¸+³ò'“ ŠhžòÌíÆ' É%À`ËãõYù {éª%jþ2_.‹ç èÕT̤æŽ-}Ÿ;SÅR” ^Š­û츣YëñëÀš„`ìð>’q䳡xXüE :óó>ëñ¼Ä‡¼„ü¢ÚfÙIÏÃÂ8‰â÷âeþ€E®ägù„r(ÝH7ß¾…*ÊF”1Õð€dÛ¥v\Õͨ#ô›[g ŒL·BûðgŠö˜µb¾&°šÃyC«†$ý°\¬‡R„†™D §ÌΫŒÄȶ„wÝxÍ^yè;â7˾Kˆ,‡ËPD£æ†ˆë¨éÁ6`’xgq˜®DQÞ“vj÷õÀ)_{­Ô›L`бbodò.$òÐuŸçÀxffæ7"Jæ7>ûo⿹߶*JŒë×TïÄCþ¡L‡VÖ«ºªOòž?Y`/Ʋ º@ òvâDÕŒ>êR¾j\í=sìó a¿×DØyRæ4hÁÌ–ÄürvÊXN8±Ä¬Qwá®ZÿÈ¿áC̺c í¨ëZãçÌýL£JŽÚû³(’‚XíÖpµìm8ÙZ1êÓŠñBRϰ+è>e&o ¢£/åÙhŸPδ ±rE9qÜFùc6<'‡šhÐEGÙ¬B&ꇉŒg½ŠÜ´=ÀžÑS—•»a+òsµÒuVZbòÒAót%×»×43£Ozø—ÕÄ_¤ô2 |L¦‡ùòIïoÿÿxqà –_ÎÏrt±õ ûS_üÿßÙ–üÛíÇ @•¿t+HÆ<ô=‹nx1ö¶nbˆ|iRìuüü²:gõÍV[˹)Y[…IVüM‚ø3=Œ}N»³6ëKô¶—>³:#MÇYºׯ^ [4{G•0¡‰œ!d«Â;Ø;„e(ôã` ûó¦°/.‡YB®`À‘†µ²=Â߃gÔ6ªÀ»º½¢Vz<úê}áÞ,Š®\DˆXq=ØÏ>"Ñ—òÙÕ•ÝÄ<'ñ)ÐËé7ÒÛK`€ý°¶æÚâg(ŽD¡&Éç@>°<½…òéÖ¿´…mQ€ëmù HbƹA¿!Ų´3£0sd â ꉒYðöâ \V Q«µ<ì±%i#úìmKF;íë¥z–À—K¨>Û”+àˆ¯G£¶®¥Kiä‚:sÕùÌBºž³é½«Šæa¢Ã…¹;BôÄÔ:v0"sÍA–¸ÔrتÓ³ŠÁô¤ÈûAÝèàLÊÉûWe[1%ÏC "3=9ó«Àïò“Ã2E¶&èQ|æÖß÷Úw:~¨ó ^/ј%ª8׎!2h¾Í*Ùy£LŒæ'r)|ÈiþæÕBÇ¢;º£Ç-FH&<çm™lµr§ p–·1±¡óŒ/òXÒç#…ä5`˜3ßi‚aQ°}}f#xÿ–>$àG)lø/Í?¡öÝ»OŠy“0qB½â»y¡ ôo äuçèéÝ©Ñ瓚ÖYI¦í6ˆUílÀ•Ò¿48¬²WtEòèg°Ìé»åÁÓ_Ú,C‘1‹ïíãðé/² rxvéTï‹Õ;`ª`Œý€Ÿ-™ ±wWzvEBÖ±GÞ̰Œ#Zgtœâ¨B1"Ä'òy õLîæ q]Ç<+:Ò´2Å'ª±Û$ ¤3Õñ²iC‘¿âÍzq®é¿‹ÿIjZLð–~vÏ”˜¡ÏH§.u°“âÆ*1|¿Vh¯^|’ûvÖîC¦<º "ÉøK£Wd¼t9g=¡øïj…^±ïŸàkÞL³oÇß×½/šlÄ^ý=ÿºòJìUí¤„\ÆOå*ÅxäÎð³qaGû’þ Ë¥8 ÍÕ %$Í’]>—0º<»†‰Ã¼%¸GF#õÞ·â{MÔþ·Žÿ?€v(L1ÄÏj°sù+ý÷ïŸì?ËþÝæææïé±ûÁûCdùç0“ LŸy'Ç¡O¦ãÜn–‡MS“ *RÀ”gœŠ½†ž¿nüê5)ÜÃ…•zç•é­¦X‚ù–µg,YkÈL©}/õ`à †ryÒ‹æÃA+§ð¡(„´’œ“ïƒá½.%èÌAñçІÕ)IÇ›èäIŸÖÝÝ@æ™ ®~ä“×åë:YY•6ÛÈBœ“e<²~òLÞýÒI!@­Á1o‘=´–_ÿœö´Ú="’-ˆ±ŒæÓüQ/M7ǧ5Jñ¥yfü Keø $šÔã:2˜1¼äý®Ð@¤â<aX“ ÕÁ¶÷ÑecãѮً¼gÈÛå¶‘Óž‚¥obx,‡»ä¸èa²Œ]§Øk]ºì'NB8’Þ!V±øîŸ$7ŽþÕù Rí\ü¼æRæù$KŠ]%ëw;³¸ð×4­^›"óÎfŽÆ%d™Ï/vèÆ-XH)Æ5 9mñÏÚU£Ùg “È4Gâ³Ð -[iœæÉkÉ|9&Á ÙCæ‰àÜZw²mÔ-m_PkÇ”,ꥒLúæZr†å1>N‚cvŒ=Ī©sP¦|…yÄ©e§8’]Ö9Èš‹ùê‘8ð¥,=äM8q¡LùRÍö¿?™B„ú4æ[ûÈôÈ5ɲq*„ G¨xãÓ‚˜©óNˆôSG ]›™°íRKB‰\ÛÐ4:ŽÃIp{3Ê•ýjrÔKü»]D øjrÜßòÇŒ²¦ µî5l"ÉT7â\§Ï½­rvdS™ËJŠc…Ü^жÏã-ƒ1S˜ƒÐW$í ÿåòlæS[ò,Gx(¸VË^·Wx%=©íÇÓ¯6£¾û |‰àrøSl/K‚ ƒ!ŽÂzÈ’Åwòú0ÊÇbŠÏBÚ§­ó D|÷(Ù"ïTUG¤‰†%=^„]%Qv,˜´4vkßW›îÌ®¦³ü½ãÿßÏ_ Éþ£Ê?ªðiûg€âµÿü½ƒÝŸ†|@ÏoÀïK?޶ŽÑ?½x øK^€»ÇO?ýrì¿I<¥€€·§Ç¯…ÜÝ|¼Éòíàjïjåð ðóþqèjçéÿýF€¿½ÐÝÊÒÂ;/ä§ÚžvþO«BÜݽ½Éøsí¿æóxýzâçã®^ÞN^ßKÿ¦Ø¯›Ù~¿º}k¿»ów¿üzì—Öþ´ó›z<Ö~@ŸoÞxz@¯'Ç÷ó·ä·cž?Íèàü¶ üžÑèâð­ÌìO¹¿¹ÉÍ÷;²§~«âg¶Ö¾ÿ '_ßé—. p÷ñø¥³ý²ý9ñƒ¿çÑq@ïèÇOææø?ðþàÿýÌ·§ÃÞüVÄçé*O¾ýÞæ'_?Uôðúq}€‡§çOè¿ûÍý»ÊýíÀÿ§,ß {x¹»ýÄ? ÀÿéV¿{ÙÖîïÿ<÷ oþôôúqCÿ$¶®üÿtýÿŒþ@þνÀŸ£é)L=Ül­ cC‚¼=Ÿõ©>=4~¡óÔ‘_ã/'77 ÏÏBò­nGÇpߟÿ_òM¿\”¿%|ãÝ‚€À ÿ¯\­½Â|==~ÈîÎV†î>?ÿ<õ£vwëß]ÛÝÝÇ ø›GÃ?Fû¯üù,ÀÕùééñÛÃÿüÇ ÐÍËóŸãèñ»Ä¯¾:C=Ý€¾Oqý½¹?ɹÇ?< \¿=Wž„ýI9€7—ßùžäü»Ÿ|=ˆ¿Ç-þ$öOõÝ}î@//ϧaÁ±ÁQû&`žÀŸw>ûmÏÅí[ÃÝ^¿ŸNûÉKn¶6&6¿oü? ø!äNÖ.O}ÔóICP° ­G>NÖ”µ¤nŸ_y© Öòm‰Ä fuMƹãeᕉÙð»ö—ÇÿÚê$ÎAþ'G«o[‰=YñÄÿÑl·øK´œ¾¯ˆ-wtÐPI ü‘åzËì4/Ó#éîL{+4E~>YTNá‚÷î= Vܽù¹øË®" :àŸßhÕâïÆoØJ‹š~&gÝ'ñ_#þ$´`§%À-{T“$™ö¨‚†?e4ÎA!ùéïÜ´ø«v§Åÿ¿´þø[ƒœðÇëfgÝó¦ÿ=ã?·aÐ9Gjv<‘øÿ…åï‹°×)‰H&FåÃóï>¬—ë*"£hɳs­#óÏK‰ÜsxŒÊ¸·v|~<|¥õ·H†J‰Éªe[ALOß®ÀµöƒÝTÃáøâîbUó“G¯œÑ—ªh¬—Æ1·)¡ùmŽ0·æKcúþ¿Ýª¿Û­¦V4÷H*pÐd«%죷 Çé•¡P{Ú¼Àȼ­@šHÚ"¾ÈZð”:[Rg ²By•Þ¼4düZó@C r=žYY$4òž°fbºD4J]{ê燷øŸþÃ;àQöK+£ k”žÝÜ^¬ÁŸ‰ýʾWÄßIs+š+tOsàßÓãþW80ÒðèÄõ”Æßo“ðÓiÀG×?ÿjQ¹ñ¤ÿd°%V˜‡`¢G7ÞaŸ@×鸤"[}ÿÓï×K">ÚÈK$â…¨ÜÏXóŸ¯-)Fc¼oßGoà}ÒHÁÅbðÛ÷ïo]Yü¿ÔúGÂ_jŸ´¹éÑ3§ÿýâ/VÈìÿžœýåÍœ^4€}N±€¨œiXLF_]]./Ø«þ³¶1Þªé1ÿØD-ÏÿdÔÚW²S¦eÕ'ð øÓh‘.‰xÖ³\Õ)ãm–0Ò¤Ñ9ÂÃ×n(&§¯BüÁð|sªß[üS!þh†þ“çMÿûÅ¿mqŒ*Ôæâé@Ä¿vzÒË´)v”µÓ,EfçƒÁÃzÅ•–[æ.ÙAƒãlWô·¼£ ‹²,óWó,™”Óÿ°æßEëGµµ>.[vãÉü|á]«­Z3ËŽÓàzfRÎä2dö {N4&9bKççsÝqJZzø§fªP$¦‘RûNk ˮɊ‡`颀 èy%GòJWhPÒ OçÑyk$ñ 1lq²‹ºlIVÁó–JÌUí¼þ‘Z ä´eVéÂÀôì2žÿ•Å_‚É)­ô©+¶"}t_g²«¼ÙŽ|V jbHÂÇ{Tœ ÀJÂ\- væ³èŽ\ÿ&M§Ð;ïØÓ‚:äü¥A€lò9øçËŠéFYüÃÈíÙ$>Œø'#v; gr¶|ÿùÃjµ"š@¿vìÁ-iÄß>;Ò#èT&ÎþÃ{RœÀ¥ þßf?.”{VÙøBë¿_¶¤ªÁåóáEK?­Dqnž7ýïÿù†_¦É×uÂûÏÓ‹ `S¤”$ý^ŠÑèë»Ëå†,¼ˆÃG†`ÕoóÿÔüÃ-dœÚA-õÆQœœü&×?nêh8çÇ·LÓ;Á00¬ÉÄÍÌjVw~D3eIéfÛúÿ6/ÈF"ñ”ݤ,f?+ó•!}>ÚÑ#{¿U½Ç5àbh6Ë`FN@]4ì4:Jò™éj6òK|áò×äÀüò„‚@;¥lªDf•MßÿO¢w²ò]ÄŸÌær4z}Hø¿]Õäá—Ép²/YºO›Žü# œÐï¢Í| ‰!û€Ú‰xì$•,þའšPt“ÐOâ\jàfþŽ‘SzW”èí;ñêóð—­ËêÂo*À¢Uïæ•RE}ø-LK…Ì àü"0å¬xÊ Rn ’-ÈýOW0†ÓŒ‹ø4CQi«"þóLþp¶Åªÿwƒ_sq|³$´ à¿yÞô¿GüÅÊÝJbÿŒùÓ‹°·)âÞJí¡Ãs:<.ï–k_ûõ˜a‡½Jÿ‹£t ðR“ž§L"*?ýÒüpÙDgÈÙÙWêU9=¿[ùì±þ?Iå?^èÐ"å|‡æq•þW²G¯Oú» .“˜nmd¯Ãš:¹î {>w;1 ؾͅßc\z°Ê97½d ¸þ]@%q5oÐÜ>.L×F)@4#5@çeë1²øæ¨çÇú ðŸÜ®1B)¨’‘ÝÊu D‰ï*þJÌmdSžÞ©Bÿ?ŠtŠî“°üñ=þÎh÷^R)œˆçƒ|s¶ÉÓ"«HAðÈÃÓÍçá?k<¸ó6ááѨ„y¾p«Qa­þý¬±`7þÍÝrµâÒ íJƒÙà]€¿ªââ?’áQö€}5#P¨†Up{?]ÛâÿÛê§‹FiLs‹?¾AÁŸ“çMÿ{Ä¿i™Äòÿ̘^‚ûšb®m‰F/`Ü•Ãá·ï6ËÍŽÚ/·äÔÅþÙ_á ëˆåøWWooQÄ9AQ†—~”Ëb(nÚ¥´Rçö²Šwiƒ÷¨=¡ÖÿeçbšqîPJY»é_qîLDÿŽìck@Mª‹Ê—„Ó€,ª ø“tª  væ `ãgå¸f¥‹ªr{wdXÞê·¹ÂX ´•ýªS àm÷üÅpøæÐð77ÈäIÄ àÖ˜þgnãû\/ÈøÓ=qZ¿6?é$Ø DÆ>Låt/’O‰âðæ¤Å×¥®0Û â*•4é`cõ¹øçmƒì¼¨ê„ùû?\µ\Þï²bÉŒSHK†²š®vãÿábIIôH$i{¢ƒK@fAKýì?MŽ€ ptðoÜÊ”ã/nïo c4öÎ&—Z»Ì|˜?oúßþóME#u[þ’À}qìiò €åaJÚÁVk1}Û]ûÚ¯üß/I•DÓ…íMÌίÇQ˜Ÿ¼~x¿ˆ”Ù©¾oWêe>è.š4ï‡.Gl:ÆÒ 5mјhÛc¼ п&弯ÿ‡YØ#çmÃKEãòŸ½ÊÓ?lÍÇw£stã»j`&q,ˆdiã °*U.,£†SÛÈúwÏâĸù}_Ë›ŠMSE]lzÑÎWŽ80Ådøz}xøo.¬Ø ’V01_—Ã«Æ v_øo2I92€þÿ8€ýÿ²s {ºàÑÅìr TŃlÞGü‘ç .k@¹GõÝìx!ùYé|ðùøçKpýʲ˜xj£Â…›V€¿Œ¥€•ÅNü¯®—ë¥ñâܨX°GKö !þ®2õ,ã̧ ‚Ø Ô.Ttè‡d'ß=<,ø !È줲ø3ZðüƒúyÓÿ¾ðW+­Éíë§ÃÿúEØ×äY,ªéÐB¦8??~X¯«ýÚZBîó/ºtºKƒ«E,4Ôô›ÍÛÎÄg”§øÛÕ"¢ær~r»lªäºø¯˜nêpj̈ÎÂ6Ó›Ó)™ †¦+ ÷;c”:MDHrÖ=sBÿÌÄ«?¶œ©=¾ì[.›Ú‡´ %‡-7 qå.=²äÚJ‚(°Ïn~Î@¦«hZ9ß~Z (19 ΠYÆ5ôˆŒÿàñ?½_R’LÔÆŸûþ!Cu>èR¶‘ÿ_÷sHºdjé|"†ð÷Yÿ©ëßDþ ]iI*‹ÿîâ?gó‰/ŸÿŠñïähð÷ã‚Í¡Œ²Ãƒ5 WüÇÊ)Þ¥Xü/[ß N™þ:œbq8ýݠבža᳓ËçMÿ{¿EÇKlÿ¤üÑö39+MQÕ¼ÇÓ¯o.—›¶Ç¼w›HëTØåvšôÂ[üß²Üb£T]7²ýñºŽÏ“Óù÷AÜCl2¾]V©ÓÕŠ|µµÑ]hGKÐ-.‰¥×ÿ ¸:æé ·çøÑD¾;îºáôÿ-k@ž]‚–mtp*ÊÑÕÁ f´•“.õ—öÂO˜/-©Bà4íŸP`ûdT?DÆ9W6&8°'“ãÎ5€Ãm€ÿëÅIÎVgç±Î‹•ÛȆ¿W¸ŠZþyÿ?©MФ»Q„¿tõ‚ìÑס €J.(áÒ)Úâï2ý .«r‡eTÎVOÿ¼nÑÔ~`Åãï®c%†iwÙÄÃÓÏätµÿýewÑöZÿÄÙNÄS_`WØçºslÇeÿ¹ÞÍt4¸Ròb£Yi¨ð„rü àï륖“ÓÙŸ6†57Ü^NÏ›þ÷ƒÿlS§þÿÿ|cx_ÿ¿'åȕ㞳Áñôa½^þ»æLRø"; \©r²è* :E^©ñà}g""“ã7¹YP:²¡H´ÌFúª­zô?—«Pþ“Ò:¨½Øw«¿'æ¹þ? ¯Ú2üA¹XEǨ¢Šû¨oYSuY±fï~JÈÄ H@½@~Ç&b›y¬®..Ò;3DãBü´G@×4}-pÆkœö]€Ü8ÿü`ño®Áì&Á²ñ÷fÙ[Íjµ¦^€´g;Àâïýÿ$´óEÝsýÇ¥¤*þȺáZ9¤BÈ€Z—fÁïzR> þó®.š*aþþWãñ${EíÊÇÄŽ0ûüe¾…¿xoͪˆH’Ö¯w4ü—¥vÙóQëÖ0û/>:௨“&ƒ‡¥áˆü€˜¾yýכà ‘ñWæ#ñ¼é/øc @«‡–üO/.€=LÎ*#^>½ºY¯/û­_7ÿpwˆ¹þc ª8¿¦VUNh¿Þµ^@Ò_‹ëï7¸ßJ(Ê—*;[CURLÐØŠ+%阜¹¬w@ dÿ‹v¢G7:d+°\3Éû‘ŽÏ8âL¬bp¿tnØáWpýžÈ dV•ó)ÏÈÆÇJ²¹©«ÅŽ ”uÀ%Jp_»Æ¿`¾†Z@LŒ¾E•©o˜df12þW›F‘`a·>âïÒÿ¼@¹þ ÎKI¼Ù½Ï¾ÿ?—+ÚãcÕwýknôG"Þˆ|x~Y±À§ r$@ÇO…¿µ˜£&°Ñ äÕ‚Ý×ÁtµpºçöD`ÍÊþ÷ˆ?k®ÜÃ%JmþÃöÁ ønÀ®U KÉôiª<¿Æïá`É%© •œœ}hC~§³ÿœ_ÿyCUˆ? µÏ›þ÷€Öu…zAº%}˜Ó‹ðä IœSLÏôm·ìI¨ÍE‹[‚Pá>â;Ì¿ž(çå†(2&M1ŸÜp¾ŽÆ¦®¿Òú':NçãKNÌUbvz·l"ú—£eˆÙÑ‚×ÿaVÄi½[\ /ÿÎÑ£ÐJüèÈËÒ/€°¥Ñ#{Ofò«?ÛȹV‘Ъ\®‚œ¢×ù¢òê¾s:âG' œ«ë8çlü$€¾`˜}`\º4ØÝ.JôFd¾cìCøŠéð¨>hüÏïèsìV¶wߺòã”X$,ÒrlUç]:öÿkŒ„Öÿ¤51þ‰ëŸû)ñLø/êÇìð÷ßpŸ{ƒ;S_}x*ügå¦êâh4K‘ôˆÇñWR-˜J¾™ˆÓuŠçðW¡õOÔÝÏ¢wéÛJÔ@ ÿ/ö9&Ãç‰ ð•ü(À|bµ–{—ú…Öÿ·¡˜P6¾jP-°ÀÌÞÜ>kúßþó‹:øÿÙüÇéExê I_`tOæÃó£ûÍjSQiÔÜí“æu]Q®6nÛbÿ¼€î?¾&3 ¬bφWn»U„'¿Ñú¨²G©bxÍeF[_æ¯yЍܧ6¨òµ@Dÿ±E€DS˜…NH%µ伫uJI”nä@X°ëµOæEQ%©(TÅSP¢xã݃ÚÙpP>¹l4Û÷I(ŸBîhÞÆµ€’û%3¸ïÙÊA øŸ:þùXüš? 8¸hÙÕ ªY£§s-)hÝóÿÛÝy £É5 †Àfµ…n½ëßTüòB ‘u5׸ʟֽÝPº§ÃŸ?wãÙ~³x…*ŽÓñw5`Z÷Æ­.ŠÿÿÐúljsîó‹x2àÿ´0%¸¾”¯aŽ(È ²ÑeGþ£ÜêÿØ,Е ËáUËUÿÑó¦ÿ§Ç_Yüÿ ̲ë-pUxœìýuXU[×>ŽÓÝ !HHw "HŠ€´tww³ƒM7Hw7ˆH§tHIHH((]Òñ£<Çs¾ï¿ëóø\ïã{žq]Ì=׬5׸ç÷˜k¯µÝÐÕÑ'ýç ÐÍÓ×ï?y‚¿¸üA1#›æ÷uñçìæL¥°Üâ´õ£‹K‰ßfá_>$ˆúP¾ u\ ‚à1¹Ì°~Ôn -_žžíÝ÷@ÆåSóþ®Bœºº1ÎÁ*ul¦DKûIèËS;ø×b¡õ[V˜O'󱿦W}Ï`ƒ_'Œ@7 ½$âØcòøÄ–㘈þÊ„µæ~¿ ëYûŸZ‘ 0 Äø‚Þ8È­Ây)Öï³ÉÇLñ ”oÆ-L7Kp0a¿6>tñ±^pÜ  ïbŒߦ–±Í>Šùv ßù%[PÙ¿¾Þ|-sY('‘!Byžnès9RãIdzj!vô33Ädµ‰¤ÖàÎ]g"»å3ýI­WÏöÓÆ§Þ†Gn‰¬á~>A‰")`$|Q‹ÃL!}`ý0ö¡à…~.Z`Bp«¡ PuD1D»hG„ÿö¾î„ûåø±tŸÝåúÃ-e5É’õúôy)œã^d&JLïyøçFÕ<ÜW¸ ÚDë©ío­Q–‡j÷jû‘HŠ4“êˆ<à>ÜkÓŽòpnòE–RJ*9ª“¥7¡<6¶µ4ÀÃêPM1»;Oò>Z`칡‚ø!nµ"K_×mátq×iD]‰yjFEvæE½™i8úÉÚ‹MiÜ‹G ,W™û Hb¦8»Q÷ü¥ÛìÆiI¸M42ÿóñw]ÉjHÈ[_킯o4-+æ©ò(7;—<ü+=]Sl¶è˘ëf$À¨yõècŒU¿ÔTêâ74_Иw&mW•’Ï¿;Úç±fMQ– XfsDU{Ø X•÷ëq'?'é3—+#¡p¯É:–šG W´Íé([w,²óÑu+cÀª®…—ÕAì„’qêøö,tŠ ¦ºˆ°¾À5xýqÑä*À=äKˆaXSñcãø2ä @"OÎþ•ø“ WR&؈0Õ‘(¸x¸}jx %åCz´ñ…6b‡\¢¯™ v껩7´ô|Dñ9):=lªÉ gë;|õCí;z;*'Ý«ûK³c;'ÃÒP;Æ?[lT±ÒOŸ¼¶·¦JŒÒ,±? h¡£ÒÍ[àrÏ?‘[ú›NñÃåxx7"`ìĉ f4Öw<þÜù‚g>܏ބ]à…\\’‘æÙNL‚¸iÃ=ÒdÒgdo²·ÊòJúí³$Ðò/<&rÎH ÍT&ñW:™P¥öã½ ¦! }oé´7®NÔ­pv”ðc©).ÎŽbœœ‰ÿlûÿÕøß§#:j¹¡ —ƒgHÀ8»\þ>ÿÛ“ø?$@7_ˆÏ—SßuŠ"WÐùæÒq{ÊÛ9Nfé"ëÞX¸ gJŽÂÙ»[—5âR¤´Ô_é¡[.µ¨D¦¿|‡&Ô·Ðg¼/ˆBõ âã·Ð Lœ>Ô¸d~ß°¸³4e´Éö y3ƒƒ7ì»LÝn–Pc ‡bØÆŽ.â…ȶžî þìù~5î¢çF (oVª(úr$Uâô7Jáb¨¡!œ¨ÅSHÇ äI³«¹x¹ª/ËŸ¦gË®ùyIMmzvÛ1ÓQäkZ Ô~(ò¯‹„°]ø8^úžèqµ/–âi„€i† Égäx(E°çÄ9Içh›0­Jb»ÃÖòÌrVnS+ªá´tÑÆÃ*}ŒŸ ±?„Ô=b"þ°e5¿Ò¡Y¤XÝâí7èG“ÛÃy]"³)ÆîxY#âòßS8¶z—˸2mâ3éÍOMüÏGT½x]Qºó•4|i“£JZÞAîeäQW°(Ç…›È9ÔÊ9ä&+3ܰ7'ªbó…Ö6¼ƒ,»‡½àôA$d8ƒÌ#‰¬¯Ž~±óç*÷œ´j6¯'=ÈJ<*)?´¬Ò¡ïJ;óÛdôäÚH%Uñ ªÀXQäÙØ3Õ?HïË™ìY%½¯æ9:dR=&Y9®ˆqè=™zÚêKMãоÞ+5ðn>];é·ÀŸ>SœÛÒþX(­ôSš9á ŸÇ¼äƒ’—+/'[´‹°0ü–W¬¢*?:uWÈ’Ù8ã:Ô±¤ö‰öî’.€êF•Ö‚í†Rñ!#«¼œçˆíšOîÉeën W åq¬T¯›ÆAWÖà!ÂW– Uô<{}Š•: »Ë{¾h¶ZPƉÛ+–‚C¤&©Ö¶Iw‚fÝÛ¦ÈDöþöÐWtö Ô±¾YÃZ‚vhL š&wë/Å_ópú{c¤ eXz2+»]ÆÇ9þsò2VÒ³ÌÅÙÙÊcüýÄÇô~æM Lˆ0™±~‚c r Yp©2Ù+=)m²g]åÜüAsùœb¸àg1(VâÏ[—³›6(tšüZ9ð¤lwÿ±o³”§—0ÕübÒðC†×ÂÕ¹FeÔ¼‘gaO«4¹wx?©/dWâ"1d÷yÜ™Y˜"ñŸÓpuI…kÊ)QåMÌSmyôb\*[-Èùüí‡ÖlÂÞÍSç4MüÕç2Š;u‚˜u&+$m¦ú¬á eü03;1Pf¬É³˜öOc•ÑyÖ¾;›rÔ1§ý:Ì/`Ø0ÿÑöÿ«ñ7œ弡€‹“ˆ÷8ÿƒ@žn`Èÿö$þ§ÿÇÁö4•1̵ÍÃmû0Eà*ǃ2èϬ`ýÏ)AkwŸN¹ Iu68 Jí‚îÐ5ÎÕêDͽ!ox¾>¨´„’·Þ¦’IʃÁÇ –ÚÂ:sâôЖH(\YSFSèlAñµ:œ•LŽ]8_wW#Ú¬h?kb°«Bv©üÆŸt‡øj¼ä «Üi µ@MýS’¡È8QrA?‚ZSßZ(“ˆ(ƶuWä•wFaÖ'ÝÃwž]xùnb#½4_åK§ç¶2E¸Xè<+Qã–èAê_Z­mü¢>]©sÚ[g¦¯¾›ô€¼¬k.!x5ãè÷ÀŸÊp~®l‚f>4†T(Çb%"…›)Øî k‚ˆ©ëëòœ†òž­;©¦¬OÖ¤ìü>–¿bUöÎþ žÆìôÉ#þûjUÄôÐŒû®‚‡ÂR¢¨fà´±#E!…ñòwÜ!-@Ÿk´øó^©¥Ú|©ùîVwë'§m^Ž€Ñ†fœ:ø´©š’^Ÿô™»S¶˜x§+4ORb‚ļÉ5K±>¨Ñ/ °þZüíd¼L Ó×iê¢1×rB]:cÁ·®íÚb&>}ÝÖOôX¦Ig˜¹Šª³ó+i?ž‰¶‹ŽF¨ÙS ‡µ­)³aŒ9®mÁAVÜŸøŸŒ…æ¾WŽàGw^ŒBå·Ë’¢¯|›!¶« Å8a~óv@Ô·½DÆý‚])¯3y«Ç^{TqV5ƒMÛ'©su4+=«ëm²,Š€SIÝ9íéÊÔ¨rÐý)úŠ æ²éÉ{ÅŸvÌ“p?¯¢–Ò“J-ºé ®wm—ð=fíŸþ¶·#‘kãùrûÉ,ëªu±Â/Œ§>ñCIfdtÎal°Tim#úgÛÿ/Æ?g“⚀ÀÐßâæº»»ÿï0ÏßCÜ@OÂË6»-׫VºtýHahˆû„Ž,qÅ"¤pq.øXÝ+táî®7äR¯¿w8BIä-Ââo[‚à 4%ÓÉßÏÜ%ÕÕH^=&ékœ=Óþ7=7^ÃoÂFwF‰1—û*Ù¼¬z†épJ,È娃 Ä~¥»o­¾ÜA1¯ŸW`R&äÈ2’ÙFÚÂ_¨'£dÉðí!ì=i…÷,<0?w£ÝY=N-/S„[ Z],Í–Ú_¸} GORüÜx vl¶2ãÚâ‰SÊþxÔ§ÕñøêQ:ë¬9fe[¤ì¹ÞiÑQD|Cq²žÉYŽÎÒa[;î…”§*7›8 Ñ¡B‹Ï»éid‰Ï;jÛ–|s¢gbÌ%O6Uè2¼s¬2uLö ¯õúh\¨ÖîÕ Ażˆ"yAÖWh¯Õð© ã…Ì·„l*ëš 9ÝÁb@aq|åOF\î+ñ°QÉêƒìjµ#…”ÖÊæ=äèù8Ű(š°MN÷Æ`ú*ýíf㳕ƒ§îq ™U6.ÈYŸ=š×xþT¶óЮV&•Õ¹oKùÙŸæ}ÓEÝ”X˜QŽŠÐøÆ³´>¹8|ÍPGøŸ±;L ÇU!¾µA‰ã¶Ìuç!4TTpÛã:–T´×å%îvœ‡Àø …ºý6øØÎ>zÁx¯Ø ŠŠXë#iUÄéüPæ"1V•M×áÐÓkpGGhY?͡阼¤‘°#T…SJ±G5uƒ™øêYQ‹Bð¬Ð Z2…ÍÃŽSRÍòŒúŸšà)¨ùh¥­ÌÚ¦ÄSµ¨sêïνë|ÊE3«R€gõDPéý”‰^¦ û,ŠN É(˜F&cjqŽ¢Û|lÆ æ§<êøÎÂKNùñWãBùÅ'èí1GŸïÛa,îòM’8hõ/ƒK…´RßÄWÛƆ$mß•0½§CâSWƒšMÀcÈ O™`±|›pã@@ËL¤=Ã(Hÿ?^d›¤Øó°ùgÏa\1d¢) [š5»d§$s}ÖÜ&ž²¢˜§ÔT»·ãžrú5=ã6ËašlË´{MÜ×8þT€àEŠ[ Áš«.Žík¢œ×Ë ÄÛ|Ú=_Áh's´,[zöHƈ~û¾O²`ƒžÔÂò±¤ÝÐê6$©al_Q.F§òDÆ ˆÕ1â(Ø©®éH/É­4XE<ó϶ÿ_ŠÿÉ+\ƒÁ¿¯Ý<ýüþ·'ñE€®zÊiçz”QRýÞ ¬S½ÇôëúÈgËèh“ЏZ:±ìÄ©Pn`k@†,jTP1OL­´Æ×Ds|nœBÁJHfü—h1A½Ô:m£dèä§P˜£«]ÐÄ}­¢I6 %¯8<ŠÏïÓ¨p¢£‡â©ˆRy} &(¡JxØz'MM€­—exÈi“Êh@HAªòµ1e¡3\Ù¹Ö$Zš~ýÍÛ“ T,}Á8øÁ«#ÉŽÎ×(¼ÃŠš²xa.p$Œ¾å´Äß±IGÉÉbÎ4š’«`ôÜñO&aÿˆJaŒ<|0UÀÕˆàÇ*¾é•,ë"›2¤þ<Ä?dÉ™ìýÃ#­1íMùm¼·ŸE[»â¡ºvD4XË JB«³ÚP}}ôîX¦ÆrJZ.;¦)Ò} ñEÛ­îVM7ÁO§Ñ›=æ Õ®Az9®ìåTdN@ ²qÐ ôrdv‹®fŠ@Ý+)£ Ñ•„© e_Ò¢‡ä ‘\¬ì›(èÏËÛtÆV+Âû¬H¼/ÀŸñÛ'žÜ+]ܰ\jEìF<§À { $ÚSuâŒð,W… ¾åe˜Yñqû{ãø•#ѤÊy ÷‚´ÄÅ ±K3»”(iýßGª‘-•çt™ìsä°Aõ ¶Œ¦ÅÌÔW@Ü”̇{Î¦æÆ¿þXCÌ*X'8ìINÅÚíààxŸø‹-{Çc‹§xÎ)6¯nùW›•¨[dÕ*˜‚c ‡ö¾&ðí‘7LÀ×ÁŠZà•/éÆ<ؼSUD[Fãˆ.¨1ýÔÇÕa®)]òn¤¯ïx¸BÓñs/!OmY r4Ñóè©9ÅbiŽWÙ-Õ@Vç^”߃"|ÝgR¥I¤å_ë—‘§Vi,í—xèöÉÄ’¼+שâèìB™Gr/ ž^”«vêj1M“)Ç QfU.Ö­¸½•|o7!@¶ˆÚØ…ÁäÌ 2»Æ'×ÂR¾fª¢îÏ"ÍZÅn%DØÃ{&óîÿ³íÿWâÿ¤ÿšÜÀa>¿ý_Š—ÛøUâÙûMžù±<µE/e{TõºÖýRűÅGæþòP¾ø óEÇTø-JSÖth›¨ð±„t2­v¯}?z¡ð‹0Ì`“mèxŒïîô ž»Ô”y3Ò™¥ÔÇHì}8ÔÆè{fŠô©'ÁëG À"oUâÂ6Õ“2@¥ÄDDÈ„“Ë… ®LÏÄ”žôÇÙ’îá›>ToÌÀèóYÅÒË‚Š=ø[·Îƒø.~>ÇêNð·d^ÊVn˜E6žÅe'û²n¸Qn•Tsfaiœ%ÃEÏA©7x€l°.‹ƒàºv)ñ7£“CFÊ‚®«xê>Âí©;Nh÷µÔmßI”×?ÏM( O¦DÔCEi¬ðäÆ[Á š>›X‰Ê)~øÂoŽ#èSBÕ¤*¬ģ.ÂÁl{Ohq^œÞ"vü,—Žná¬=„í÷‘¡&ô-¿m+ü¡M9×'~Ån"V„¤ˆ Ý€nsŸŸ»ÖXŒ±¶¾˜=Ÿ¶7Ð- 3?Ь" °¯CÃÝ|×5‹&h!à‡%’ÀQÔ´&'{¸]ð*&“2)sPN¤B¼$*|±öx´£GZBç}ß—í‹·Ï%—žWF£Žæ¾)˜k)Mb°¯­dVi‚Ð×¹w¤Ö®~i` g‹l£^£_¬ùmâ t Gà¯ÇŸ_I$&m‚S?áb™iÿb፠^A[ȇ¶#%•Z¹ocp S ™Úã·˜ÁUŠŽÇ(ݶðJç= Ká8%j›Möa1¹onð?‡¯“Él£m’3ÔÞquçXt­žžX·ãUDá5ë˜åP}’‰X™VƒzÀ4\kœAT|*~ä¼í$¸ êÎ.M­ÑŸˆjÀ%gç„a`{[HƒqÉ>+z§·Oò¹•Õ‘ú›¸«Y{ØÖ±<æqw^ÕúTœaš\èB‰ðÐ*Lò¼ŸÖR›'×—û¾~ªzln ²ÌS(7ö /´Ñ%ÄZ  ®ƒŠÉ[nÕò5—ôþ£íÿWâÏ}I@€ƒ{p ÷ÿ6ýÿ/žnà€ßhºÿÉbÃÂó^Ù*ß+V]FjP¹þØ3Á€Ç¯QŒ4jXãxág¹Þ"kVWdh$?9­ ÷]É •£ëLMn ’ÌO’¸"o«ÅC^am5Š5ÂÖ½è /mí\¦1± D݈|õˆæA]3'ËZ° vÈp6;wøy³õÁJëéÜéó•¾°OÅ4_§‘yó÷2–5Ê;ûyimýb¸‘ïsì·R¡*2—}_Éáv>ýÖ.F¥»6áœèÑÇd#=½ÅÖ\[»-E‚„r”¬4XbÍèsª^¾¶®~ÖDö˜ðɰ B²çTK“WlMß“ïVÞžþÓ ãb‡5”zÇmDz]A7)!q¾uåO0z‡ÃM[(‹«®kçw6"Û‚CVËGTæé"Ã;œ?V~víÎóÅsÕ›ŸØô¼(yž‡ðÙP'ÓQ@ЧkXÐ Ào"µ¾›3˜Uñï) ø5¥>eô÷'|y*«•¢Áµ, Î"¬*“Â%±çtüNü‚QmÚE"š²@-«´Ã˜3) w¼%+X'ºîÒfwL:„Œ“)Ê™¿ƒ–_,ѯó‘Ç F­¥Áø²ý1‡ßÂzÜ{ìþZôâšÊ&;¨lÞˆ®D*ÑD½º³;ê$áóYо ¬à«3f ˜±gÒ…¾µŠTŸêO«ù<öèþvø_Œ2Ù­ŠQÝÕvP{Íùç^‰w‚Ȉ«tÆ#Õõ÷êï1ló÷<†’«Ž¾ö¿üËî ñÍè9¢Ï©Ò._$þl)Àª_ˆnEúáüCk£'¢h|¾–ÌìU¼…Ó¸7ž©çMŽ›=N‘ܵ·‹¥±Œ v ÁaÊuŽë-:s›7x»{AH˜ñf™\ÀfP›&Ï¢ïìš~›Ê]ÅyõEd¤€¯¸:*žÿü—ê+ÍÅ÷U„CWæPî¯ø½)}›–“íñr`äúÒ3[™¤~Jø„6Û¬ Ü’£:é³Ý©\Ÿ§‚É.Ž |¾¢vÆL5¼ÆŸ§Õ.ás×ib£ä:þût‰Øè÷út)¹öè“ýMJ˜Iï?é‹:Xvo¼ØWô†ðŒ”Õò1d‰´&LKeà¶ØVÐ츇P%²Œ<&`q¬Üò®Ú]ýBÀ9u1“*Yƒ¿×– óY',K›Ãƒ¬=g¼ÿ¡á­OóÃGKD¬¯ ùðøM©hPöÂE R)!yô°ÖLbÜ$I’üwm¿ÕµDÐX‹ ÿ³íÿ×ápÉ@§ÿðwÿþ.@wÿ>ðKäàå9…Ô~ݘ’åS<0Œ|~–JòÀ˜‚+OBï&d&Œ‘åŸx\¤Šè\aùRÉc§Ëú@>6oÊæÃ' 1%à`É^$Ïô\iàŠfz›šþ{X(Ãûý6_/k©[Ø ŽñÞ¯OW}é&ë¤Ý±ó€þAäi {^Áö>é=«\aeE’Jѧj_ÁÙzû{Ó`²³J;Iì‚2¨ìo^«@Ê(³]7صîháâI®¸CÕ˜°àVöwólÚc¸°Q²%Ûnwt‹+L¤í1 }çˆjmúŸÎcÙ¢ŽR}þŽÕÿ,Sƒ¤fw)_"+f@y¡¥X3){Ù`^/:ãPÉQ„ôÚ\8í‹n¾cÛŽüe¢¼Ð,ŒÓ1ŠÐ."©“Ð9»ðíI]ÖÙf¯õë’þ÷RŠO‹ bö…RƒŠYÚw1Í@K-ÊÔ ²ëÌâ2'áíSÉÄc•D}»“;ÈÏÝz:{BŠžcžÇóßÃóÈ,БE‰)½û!µ†K„áƒI'䣉߂‰Öêþù¯fTr=¹:ÏS<^~µÄìp!àÓ9î©Ès½’ì†]:¨¤lå 4ž–€Së ûÇèˆÔ­ºƒº…ñ¢§±GO"W³ÃÎãµµ'Çd¸G ¿ò£õäp5,b‡0¸ÜuVüýðçÉXƒ·Iÿ˜àtϲëw×Ó$ mÖAKgâÒÚg³é?®®è°ìjT†¤–澉Û[m¸ß?ÿÔóÃkëìŽuܳVáéïsŸi½ò(.|ö*JÍ×5§Ì2¨ø«|ûtIÍx$  دúÙþãµ'Ñ´Ä0)ÕgßYìnQøÜ÷](¸&kÄ}=¨2I‘wÞ¼ÆèÍÙ ®, ñvbÛŽ~þo¿×Ò£õîŒ §Sº“pšÅ8mT¼Â\\Ó‘­—¿OŠßÊ&>ì(-„’ao›‘Hm?ñ wìiÅàj©M]ׇ’øòÚ·ù±Í£×ø MÖb›:J:³µ!ø8—!rxOžµAå:øKYbµ$¿Y6mªVz÷°ÈöCZášÿ‘~"{Î*ˆHÿ ``fñ¸uP6åÄÈê½¢QFc¸‰ÎóxSÉ•Ñ~¬á ‹œá5õÉnÜËšôs\µ Z^3ŸsCkùã<âêµ¾® î ÌìfÅó²z_<.II ¢ª%kè´æöc§>56§¨©ÛXšru_ñ”ŒÓý³íÿWáŸwõWèïÆ¦7/ßÿíIüàÓzž±!qÙç…2fÍ>r~fóæ/Ò7)_‡KÞüÀNE’yy?Ï›B;.“Cs¿ÏÙj£†CFÛŒ'Þ7m:ò”€ýÑ[òùlø–‹X! @Ö†43.&ÍeZü9Å ¯-Æâ¼Ó~„,áoˆ+`ñ@Ä{‰¯”9”õ菉أ`ãÿNlü­ì.µÀ£Q¸¦½1¬!“X=¸ž§pðƒ‰/ BÁ&ØÓ¸w43¬°”Kò ÑÑqì¸nò½àEðã#«Ž"ÅOK”îÞ]ENP¹ØˆÉ+ÐÉ5á*¸#(N<ýû#Ð4÷lê»ùÍÙEࢠ[Œ,„~=O}>Ìî‘Ö õÁR0–ðžo%ó¾ú2ÏZÈf®Û|lß:‘ƒÔ£êPhù¢¨ïÀ]7á`IT¥/Ê;dX½lÉZ­",PèøDúÏX‚?”~Ãô¥R†E}‘hÅ?˜3…oÖO,ç…£‡É K:¤fôDLútÒ€=Y8eÏÂCží»&íimȤ£Ë]¸=îNñ˜òÕ¬Ÿ5´Â­‹È+2î÷­mrZ'èTˆû·õ²ãÒF sÄaB@L”¸ý5"H¬ßƒ©w06Ʊ75þA´AüT)›ûŽØ‡š§°Õ'Т©ŠŒ¹B©$Ýa_^G*ÞÇÆü»ðwS.¬3$__§¢é4¨“! Çžö>5'|\޵ 75éd‹% 9wÊ­«`^¹; ùö¹-¥¥ ü窡ɇ÷ÀŸ›¸„v_>zbÀ|…?b¢€v$­Hž\C.¿èFPƒ ݉šúB¾Wè*­ÀÙJþ®_SÑâl‡zê$ÌOaM¢fTLB‰ákíG ¦âþ"x¤Ì4ôWv ó&øÍV“­\¬:ODž÷'‘ú¯ ”Þføçâì'ÜQãoÉý‡1bkŸÇǵb‡ÞÀ –Q—›—£c<õ}Ãôñ{§ü ‚èh sW/žk},:kæ`؆ô ìŒA2JÁó¾̔ÏwPÿÙöÿkð?¸¤RgçßáÝ¿¿‹—+(à¿ïþ«ÂŒýÕ¨éÍÀ…2j3sQ½DÀé'¸‚ …oeEŠYji8I’ûóÝ%Où\‡¶|î³TWˆí =ºãã<8×™¶]f'ÊÀöR]céC[YË X„нÝ»Š-Ä?ô>‘oò]5'ò¹ZiL[X±L›­·NéJMúÞ/%êè[«$ø"¯³fÜîwœ˜—”êÈEI ƒÌš#Uœw­dFŽÅëËÐã²Rý’>/ÚR*åoCÐí½˜*yá{$ùx;ÎäR6²Ž­‘•íÉÄL.öx²Á­yaÈ|+ÄàØÝdBÚ¼ÿä}WþYøC¿zX€ÅïÎPˆ¥ØÄVâÂzŒ}¡õˆF}{8–³ˆ`&•³@lò„;JMî5ªGñ”ÞÞóϲé]ÏýmÃÆ+Óàä çÐ7ÒHæf1c™šÑ¦Se½\C^kRÞaéL*z¸ÌîQxÔ÷Ý3a¸ ƒ©ŒŸÊÝ1†x×Wó Nںɑ¥‘‚&¿ƒ›X'V¬êÃl/Cñ¬Ú=rÒz²s÷¹š[@ÔYS–jÃ“Õ§ð‡¸®÷‡–{¢V„,ò‰½¾ægMi¦.JÒé¦KÑÌXæƒ8;:Ç(ÑÑ}aªÇÌ:Ÿª-%2™³U¦|YnW«™'£ø°ïcíCè2Ù9õ)öP‘¯÷rîM¦KõÀw;#?þFñ›âoc:š^x¬YJ¿rSÕ+æ0TFã‚zÙRl"®° ëùb.\ 2¶)¥‚vت“ÚÄå…(6ä ³o\ø‰„þMÛ‘êIÙM¸0FkE8ÉŠ‚rR]°Ô‹×ͤ¾ lÏ—9¾*u€¬—ZÛçV:ö—vcÅR¤l›©[Üó£S@ªdÃ"tØ×™/Ã8!ÐôÓ3ŒïÓ:¿Z´-LW;Ͱy‚{Ðb•9ow|ü(ò-´@ÑX!-7ÂhÐåz9šf×r¾ø·ô}èÌV°L{9AQÜ"U¦Ša«(ý=Þ~ýI!úQò'«ŸïÄÓ–mWøUï8Ù°«×î=ôÜÜ€'ãðxÓÿ„Ž20å¡ À}¨ü´%ŒÅÚ¥ÒC¾XÛSØDå‚üNU¿Öl¬Z²F•óoÕ’‚=ûÛgËGàµîéÀÊ6•Ys¨—éŠãùõ9€‡M°:êI…¼ù´¬‹˜ŸX1#dòv­}Qi^?œ„1Ÿ–êõG©ôŒ¼?¢SNƒÂˆCnFÜ¿<ÀëÌGÑ}OÀ"±S>?§m PR×ý´$fÅâ·Å¿ðsqÀ­Ã#é<äÅY;1Ùa÷|[\ÖÓO Æff4iÛzV¯¾ af,&bò•rc‚ÚÊS£û…ƒeV÷PÉÄÒ86Es7©YÛû+´¶n´ÄªÀŒØ¡à Á£Z¥s«T;Èþ»Ð¡ûå܉½ËÅ»èœaåвõiØd÷zy™zV“G%ïµ£ž?ù”Ó®fY¨+Ûç›7þ÷áoàãZC—)õ¥cñÑ©W~\“ï뻡ÝÔ‡w׌7J÷gD'„Sdͳ§'=ïas9wóâöÆ`œÞY1d†Åjö¢Ç¾St‰?›xbÒO2=‰EÚA¿­ßöª¸ÏDˆüÜãÌÅ×’å$wXMsÌŸ– Œ=¢‚]õPÉÏ¡'…ÑVÎÛÛpŽÕ•ËEéÏhÇôêÊîN(#HîcônÐk>ìC?FSöB”Bù=DÈk+¨—Ýõ]úÔTÌ”í¸U’½P ¯Š1âàÕ¹eÓÕë ¾˜m7ަê=k/‡!ÆkJMŸ¢PÖõûò-ÒS„7dœ+Uò-™V„«ª$c m("לSËÊ©*Æ}ç£>ªôØXFqµ|£>@ͨڙG+Qz¯Óâû‚‡ch³`*Vgéû6HC¦£ÙH´„ êç§aPþkþøAP<;Vó!켎/FM|ïÊòU<6z³Ôz€×ѧA x0@ß+;AãªAŠÑÁT‡Òhê¡H^ó„å»r‹Ã+à‹Š)„a  [SV†—³½ áÄ ºÆ¤œ„òúB0wíÛ»Þuÿ¾ª0bäø¾–Úš7E™™ßÓ¡Jª~gü݈F>JCÙr^Ü9Òö䓎Yî¢í§‹Ž¦hÇÛn$VvÛö°¼·ÓI]:H¹xkB“€¾5u¤ù2lcUë ö8»K^Žoãrµ ‚¬7¦žîKòÇ1°ÕˆºŠ³KÅ(¡úEv¯?ÅäØÅtÆ<”­ù|+f´wz¹@§e'K·…’úí@Uñ´ÙôÐŒ^_ßy§ŒÐx)‚=zžQ\ùå¿ÀÞFõú’K<ÞÚSKåÁí§RöxIGY–çÑ GËc†ÏÉß™(S)¢>;ØE—ÛÅgs[Ó>v 'ÊæÆÈ€Ž¤áƒ*éB‡ÎWëÆ÷„ÿuZ,Œ~žÉ&Ù&®$ c…: ÓGÍTäô]©¡¨P{&¨‘á5XÚú¹POÒ¾j¼ÕÓq?; rç´wHB™•ûÏ^µ*í½ß|4˜Êéàû•Ã7Ý^#F²ÿcHi6Û×w¹‡ØTÀ™RšI„w]:þ|VÏ?½¥Ïò{wô”TÇ€›ç_^¼¨HN„›© ¦=”ÁK:IÜw—\F†Ù˜*þ(¥¯~¯5±ý#ž¡›Ÿý³íÿ_ÆŸèæ ýmÞýû»ü÷1€Q¶9öLÇ«‚ H¾ÃF±àô*ßÑÇ¥?G8J{¡í²Üd†*½Ðb¡¶8ˆö@Ðò‘²ô(„ “q2Θz–(¹¹h§VžÝT„¥8=cãî8)v*™Á“›æ<’k^ÄM5Õ&Iþ°Îb*Íbµ  ÁwŒÁWE-­Ü±çCP†ÖÆÊ#‰‘F~7Fj]oÀcíΊnù(¤* ¥?†•¼sV” í,dŸzŸv ¿d÷¸‰š-:4fÂ]”ßSFZd¦ª emÏŸè»–W;Â#Ü^ó³ŠeQü bä0;hgØÛ·üjÑØiylŸSéøCQ{òJátÚNdiÉW`" sàÃ%NžiÄiEí-¿±Ø“ÿ¸;œµö–¥ù~©lB û\ÙØ ÿÒþ³{Â{ìÂóoâ`_lyOOÍ„/u:$àÏ;«xqì|É׸ s[¨Ö¿WÛ%€W'î#OmÆnvÿÛ([•×ÄZd?êÏÞ̳Œ•"KÇy~øSÌǹ¯¦Ô »slyulÛìxqSŠhàÌL=ç'Ê¿‹G¦xDάŒ''ðð´â~˜¯'žüh%° ó²«õÝ´Y‚‹ÊÏÂúÓâÙ3&¥¥m[Ý‹}ëœ*=Ý5éD÷¾²º‰éîAÈ|7Š©,{r½)ü½ñç¦wÅ‚è“ÊW º¬SáRMódXr …N,ñE£¶7ª¥Lq©û½ì³Š/Nº§×è`"4¯ãÛ`Š¡ºx°àü©?¹ò¼ñŽ©ÔwERö$ýxtM‡D’ÙÉó’' a[Õƒ\Æ¥F’löÍú×0é,¿·“ 8†,ÄáÊìäyó‚û&Èäõæ×O-¶›„(m€õbõrEt”„.h«¯(ÿ½øßmÑ6¡ž7fUùÐhKæ– n¿¨"˜­¥d’­gBNrèpaBšúÉy3SgÒ“%jAÍZåÛ”rVi]ØÎõFok!Ác[=e·I„ý1Üz¶|5CòËŠ3q®u•×ðîàQ…Àå†eæîÔ{k ±õ߬lTh”õ?ØIL?R&mÉí«gÀ#1j¯éé£8KDåÄ~Tª•rkTDÆ®ô+eŽ¢U›É­PØl;3ÁvkF-Üc>‹ìÆkS£aa“ì«O È&”£{–Šõĸõ”‘mûˆ ÷}òH6_ã•ý‹˜ºïI§½j[Ù̦?wßûgÛÿ¿ˆ¿ ÀÞ#$ðw¥Ðø%PÞãˆôJ=-ü»iä{“Údþ$œUßmœ[iã2‘Fþ®ë9ÛÉaüµ]Aðîghñá¹g÷e#胹šWyäLõØB¹ˆÓ¾b‚‡ˆ‘ó5QÞ{@h|6z2s-wúôÆ1ûQÅs˜ÚN¸»]D>Á 3pl6uÛ­±é5äH¸x¼XQº{N´} †í fh/Nu;ú (EðàÍ7V_9—|Ôœ7¨'Oàß q/ç¾x´$‚j4a‡'Dnß‹¡þóÒ½@ºÍéí’|³ãÇ|Lúë´3_-r¿ÙCîÖÇI[N&\VÁ â]¯÷k¶#©B-3}î&«1šþ1èß‹Íë´†ÓÏ|;$9€÷"3ÛæÅP¤8*jŒ8§ŒîúŽò™‚•´n2þÛ8éÚ|{ÉiuÙôF±¬""ÎI´pÝPèÛú2­øÍã£ä{¬ÞÕ1 (a;K7‚BÖ½ö3qð Jq ÙßeÚré³x $q"Uaþ³íÿ_ßËÅÑ/ô÷{øïgqwÿïcÿÏbÐsü™*Rွþ¼ÊœŽžýÜ€‚¼×TFpÏ*€„+öÑÞ¶âoæaìƒ( îà‹Wg: ¿§àõkXqa2ÒRƒñ/î˜wЕ3<8J¶#9ûÇÙõaý¡ãÆçP Ð*4ÃOÜî8\È)ôÛV ,zÀƒ8©2ùˆ³v9©‰Ï±3•Ž%'X™­ÊÍ¡¢SËÊNWëåŽû-A}Üêxt—R’±,ú,SK€á¤Åháy+~íQ+ó)‹^eÿ`sA^}ÅpY•òÌèZ©A[V‰ú®aPÝΖÞa/« fÔ!ŽE‹´ËF­3.­v‚X‘̤ڎÿûÓÇi“øéÔÊ+¯õ'T­ ¾òÎùÃ<„¾ÃŽÅZRÖ't¿¯w¯Øz°)zÉ[K¾3ÖÎ÷.÷ü…,±B&ÝS<î¯w¸p¡ ÷¨?uÒçÆ•Y ±ºé¾‡a~8õ@ñÂ\W»¹[l¿ æK‡+d†s¥¹ÿéÖËJ׉­7Ž]AhüdŽ*ÖŒÇýßKãùƒ|çQ-ö9°¸âHLQW™ÈyÌ ºÍ]gUƒCïËö„>ªíÅtb,Žš¥†u)áû3qdXlI÷â÷µî²ë€‚*¦È<‘1©s%ÍQÞq½x¤ðmxýž´tjâõuj¦Ó‰ù;9­jþ” tÌßqÕ%°æ0)'žPÒPÔ¶YŸÐK¥O‚¡ÒÞÉ’åú®Ÿ)Ç=ï~3έd µî^§íN)yúE'ïÉ¢6ÊÞ{rïªOÚ^}Ÿ-e g¸™°<„L­¡{͘ãðø¦ {‡,¤êY1´_"]ß=g}ºPvèL"?hGЉW¾œØ,Ha}W¾¢·Yù¶ª¤¼a¯Ï­š‘Ò¿ÿ{•™çmFxfÅAEÅûb…EãèÕRKfc¯¢5 [NÕŽZšg w Ë×_TJј¿ )JÒÏÙŒL>Oÿ-î†=üü¤œ×DÙÏ„Ũ”ÅM-~!9ÍC¿_³Ý÷Ô#­¡äHmàI¾‚ßÈØXðB/ç.Öp̈4!»sCGõC§Ã÷b)GO*:ŠeKBÕË«ÎΞ˜fˆ»û$óÈ™g2±ˆÝŸCGà€·À¨5À 4H²ûËÛ7‹%‘VíhËÍI»¹³~ÌK>Sˆš}—Fý,²j3}é¡^éX¦jÈóœ]…ðƒ¸mdIÅÝÝ…ô£íþ¡Â‰¶ýÿ+øÃØ~»wÿþ.ÿýÏÀÿïÒ·I »y7®‚?*°Xú~Ø,®ß·"Amd3=7³…NÃÆô‚ùíHNp„Ú &+”P©‹á5³Å-ƒO9Ë„.•„ßݱFÔÙvŽ~øñƒ;)-L·#Íë#¿/Úhe¢È!}4sæ,>¯ägõHÂr¾‹ÌèåÔ)Þç}÷î„ö~ÝŠ­~šw1õÅþÚyP…b†| ŽBIxTT,‚ Í:‡ÐdvXüèÈž?Ál¼i¸èá–}½É^⤂¢e8bІV¡©ãjÍt2ÜGN-Ælê"ô¦ú²y·rd‹»;ÛH‰è)äiZܱo²ÜOÇ]ÎýÑìÜHÑû¥`jÕu-e=¥{ë›Ê ¹ö«V_†<–åP‡í¿’T[7¬Y:aq½a\ŒIB¦^+a=%´†K› ?õÝæÉCœpz8Xlà:1q¡ê=Ýp¦~¶Ž©¶oZ+-ÍÍûØF¾ÆÖ e7ÍÞWË“·Õ«_¬¦ñVïû©R$Ñò<ôNÌfQ×3ϤŽmÓ¯¥Þ“«h§÷Ð'ܬçóßæÐušQìØñ➀‹Ûh³ŠäI ºGc&Ž&˜D ÞôÙÁ¥lw”Óó–EÐýTâ§ñÝÿOàT†3Ïÿæ´i¦þIèX½*|qr¨M–RX ±ý¶v¼eyNÕ±m‡j£&ùê|4ò'ZüµàºÜáúµ|»^c}RiQË’ZlóØ*Q‘¼˜FŧõXøz9S.÷Þ6ÛçûìtÒ'aŸôzplû˜y踴¹¸2T÷Û¿—KÖIf¼kUõ’#Ä'»3ü¥&ᾇT‹ê™”Ö¿ÿ–ÚÄ*c ¬á¨ù¾þ6? 'nc¢ÞXI‘èáv2WM¸TäXš}Ì a˜Í¦¤Ü/Ñë.*E¦²1Ÿ';Ô©ÆßµJRA¥{$ñÓ¿äªC‘2Ó™<Óé»ùÖÒ#6Ü‘G­5¶+“M)6ôMÒìµQ*µãú&κº‰Òï‹=Û %,šÉ`·NÉ$‚g»(+S¦Ú;-ÙîeVf§ëuÓæÃ‹¿È⢛ÛxŸÐùý—Ý¢"£õ1 +?gé1‚×±P$RƇŸVžzl0¥Œ¨Ð$@§·tõ¾Í+¯‘jy±4ó…³€Ù§Í1,â“BOjä´›O€£Åââ?Ûþÿßño½åàuúŸL¢×3üOžào'ÀKuz¯”êéhoîìï xy_ÝLÿhò‡Ê–ý­àööþ{û¿7xØGÜz:‡@þ<Í«øËÇ•k¸tç>Þ?Õü™º{zÿÕaü¨üÓiüLrûþ´ï‰×Ê€¥ØË¸Ê*Æ÷–`nŒ¼e ðš4oÊÀ`÷K]¯ÿµ—¸å®ëB/Ø ìï}ë~ ®¨ öôö¾‰nËn¬å’g/ÉßÓç§Â?€cÀµ'¿Æßá·À?2¼ž¤‡KäÚcÞ0ÕU¯güá3A^ÞWtîåë};ç›8é–™/ñ€üˆ®k¯ô^ Þ7Ú½¢/ïÉõ°n`ßÛxáºúÚY_uñ†Üºñ66{šýZü½ü½^ð7Ëð&½ÄÿO¿þCû×ø{A~4¼­¹IÎAâïw…ÿµÞn.æ¦ ØûçÜ5_ßæn‚¯›±<½| 7g¾jr/\9–ë±75WÛÜ5d€Ëðf —§}ˆßÕåÝ]UA ´küWmWø{݆x—,iøÏ¶ÿ_Œ¿kˆ÷ïÄÿÿ~±oÒenorû%Ê¥k¾}!ä§íüÿÉý¼ôB¼ÿÊͽœ}ýÁàŸjnvZ7^îv¾`€§£§)”qû¿(®ºÛ„‚Ìå’Í\l¢®çææùy°Ÿ­â/e·Þìg;¿N=<üÿào^è ôñþkÕÖæôÿ›ßt¹ö3-¿ruæÑ—ÍA?¨|ãünmÚËÓçvspI^~?ªo¶×ò‡ñ_µxø<Üü| ?í ~ìþ¯ª=ýn)xÃX· vég®ô–öž#ÐÓ5ð:s‰¿ùo‚¿CdàU0s‹ÿíæõ…ß²ù²¿å™ü¯w£ÀÛ{×úºÄßüGààý㺀€Kýz|/7ô·}þL®†uùÿDÁÞÀ«.— xgüy›à¶Ð<â×â¹eÿqü·=à5þÿm®ñ÷þŸ¸ èáù'þÑ7ø_ï´½À>79Àu°u³•{ÿÈyßÂxuÞ,¦«Øìÿk<®§sKû·C\.küÁÀ?jþ°²K½z¹Úù\âïäiå\3þÕy.ñ¸^¼×áÜå"²øgÛÿ/Ætû_~úý7øµ¼þ¸ØYº½ ôþaEW7ÁuçÿSîO÷e4à?ììçÊÛHènùçíßÛ&7¤q§»»8z€-A ¿8¿?¬ü½ÿñr«èáwé¢]à?Ìóüøãèyu{öïöÿÿÅdþ4u€§·Ï_,åÃöðƒþfH73ûAšÀ?´r©ßË=àGÌÿÓák»¾ ί_ÝW ø9Ü¿%ö¿Þô𾺡íès»3ý£æ¦úr?ýÿkïÊš7Žð?L¥üJRq_µëÕJ"¥¥@sá ÁCÖJ»YW\~pRI9qÅù™¾æ¹¶Ë¢h  „K$¾éé-`“HP<ª1½\b“•÷û°™ÿ—õÑà¯n!_Ið7a-f»à¬¾vˆ8O|~äˆÿ§_†V€ª[ÿ”ÑñT!d€+ÄŸí1 ( -¾””p—ïÂÿ«Eœ„5n£žìŒCðïÜ> çàoÞ þHö#þDð[ö¾CüB 4üoÑüá zÿÈú;cCŒ€ðG€~jºM]^½š›—N_÷_ ‹p¢¾8}7ÅKºš^=nù?,þÂeš¾Æ,OÀƒ#¥<¿|v·¶Ü‡³ÒM›ÎõfŸû—Oö9Þ™þ™#ú·Éä#( –;]×e]v]7tm¸…ÿnö¶OÄ€ý¶·³vÈ„<=Ť°VÂh'‚S•C›_˜M:‹é%·šÍŽÑA]ï’€ó«×éÚ„ .¢±5“€¶Âxx&ñÖIèvšr1湦w_Ê|¡9rhªÎÉNcC$æ]ö]ªãÂ×S—œš/NŽ ÿ•àÚ"Ð6òÿþ9ü©:x‘„Îÿþ9ÿO(ñã4ªk„ú„?Ss  ´…¤Nµ0W¦”½Vœ_$.FÞŸÅp®¯¢s øÛtdÊQ5»füßþ¸Ó?KÂ_|÷ð0³-ìÙÒpq–Ò *mÿSéÎã¿F:ØÀþp¸DÕÊãßönÓÑES¶œèÛE’âaërê·üÿâ5K²=­údn ]_Nžu·ÃfÈSe´n]æá¶öìÚ滩W˱º4f¥Q7­¨HóÐ6‰¿gë³?}·N"xð}‹—7ëõ"šïácÏ4@¾6½Ë“üg’’m =ýä?È”ªû&ߥž v};Êò¿ÓÍÝK%U‹ONfÕaˆ¿.›^Ò„h~ðïŒÚŒ/6¥Êb„¯f‡ËÉóåqáÿ†ñ—4i|ôC‘͇¼Röâ6Úž[áÿË¡qvÄ Xäÿ‰ÆönS'7‹Ù»L ë"YE\“îRŸ>þ¦oÇÞŸ_#Ä;S]†fTÓîU[UOøo<þKV»–Í'Pô–%Üÿ¸eEn)æÏã¿e·YÔ¾•A=Vgtþôñ ^+BÊŸq yë'°õé‡ß¯)0ÃiÞ”x¹yÜò@ü×öØÔ¿}²¸Àt:™ž¼]¯¶í þeèÐY!Ó+ÙÚ£4…ãø’Ó½ñºOÕKüä ݤÎ_l1†&Šy³Ùiÿf¹“׳w`I0 göÉzR> ˜J ÉN],rf0[ùßòÕi’;y½r£à_ä™ñÇøß‡æK" M˜ Q§0áÒ4 (Hè]¥bÙGí.¬¿©y''$¶€÷p0¬µùÊO¸z~>=?6ü§T6åÿÅ  83óÿ¨]´WhàÙÂÿ³NnÙp֞ܰlºF¢ üŸˆ¿g†E=eÆÁCvrýø_u=ese#·êSf8S\þ·¸}Yà <þ“/VÃûŽzQi'9‘` F@[JÑ [#`üM¬(0»i–­ úÿd90þ&\çoèñÿüqËÿáð'Ѳö¸*[HO˽më‹Ég×_,·i˜•pBHXöý€#ˆ…ƒ“G¼±w›˜þ ¤qâ*Ó¹ä€Mÿ¥.N?ý϶‰ÿÇ­.>º¾[ŠE;’øÔðBD'SB=ócS&¶M¥”ļY¤§îˆ2zÑ%xe¯Û„ïÛK¢§жI`Ÿã…$üpkgË®¡éCWåªi"=H¾®Žâ–& PÞ;Aü£Ž VLà%ÇþËõKú 9ª.Ÿ÷eCÏ?öÍkNLއ«iwé='îåži ûÀuÍŒžòŸXö{7%råÀß+ÿøc*®…ÂU9½ëK˜‘Ÿ”åCK¿ò¬\ˆ+’…\Z l²ê%î¯K=´YÎi@b ø-Õ{]/1ý¸ªUq~>;Jü¯=þš03RÅ¥üŸæ[*å'n®ålãwO- äh«Ö®Ÿ™Ç?WL€ÐJñã/”@yúPøCþúÈ{-»À‰§ƒ¦j)Ýr\øõø“ÇŽ^=i/ ‚ þ´Ÿ­iäûM<‘/Ç€Ð@€Øz‰„¿5o%¢@i€?Ü+½Ë7ÁÒ{ñÉ?‰íPÁàß?nù? þý‘êÿ' à0‹®Î/ž½Þ.¯"Bùln`Ðü û·ëÆ0°É»ô/Ûåa𝥿<Þ ?õÕoëþÛU3ñ²Z™âåíªÍ©ã}Ó€KÿK`ô~ÿG68ÑÓñP©Vòhö­ð‘1£ÈÿþBcbëSñ ¨µS}#ÂéÔ`Cß_èçˆ0u¨¢§GŠ>å®:Œ dXÚ„è Ÿl;벯\yüOŽÿÓ·«† ØÑåb3€M˜4Øo)2 «¦cï‹ðÏøæòQÏ„¬ Hka\ÁãhYIÍ?­40Ú|g£>üæÁðw!ÚÌÃWëŽþ42Ê£z‚ôp çG:Ëþo·Ëí‚îjú‡õÿ$Ó/&ÅŽˆ{+©\?û4—‘0þIú€¥`îdz ±8ÿbõ-Ô\Óƒ¥àòÅã–ÿCàß«ú·OÀ!–j6yQß­6«]¢—7c£û#Ñß8·£œ%{”Ðãé=Šîþ0°Ñ³ßXûݺ5™¥o ½jL5»¼¤9½4ýOÿÃ]‘ÑþwßT±3!(sÔýª.‡Àï‰ÄË ó„TÃ{1<Ý®C=¯}? èÔ¼[ˆÄÇD Ô!¡Ø(ÛÅ” S–Ë® ùÿpa•føÛø™;¤óy=ëB“:8R¾š¼°G‹ÿÕv0Ê5¾h›óÿø”,ÕZàÿ‡Ž+ÿcëºþ„êIÂ?&ÔóUcc¥’gsµ€ÇŸgv}6<þó®kâP¥p³g(Ó€^šì¬Dh‡ø“†4á°”ò›:éî'‡ã–äYØ4s€ì¬ì×…æVCr·LMÚŒ;: ˜zöµÿÛ4ˆ#˜¸güÏ·üÿÅñª+êiùùËÕÙôänUñϱû‡K’ÖýÃóÜ]g\pÿlýj1 /G]Á§ sêÆ'èjö{kÿ½ér¡6³î§Ë‰»á†ñhføg×ÁZ=U¤ü_ç±ý›Á9…½{ €"ÏÆÑÓ˜Õ7ÔOV-ÏŽûôUÏLaFâ&)&¯ÎËž#€”T•«ÎJ€?Gé^þLƒÿ4ã* Œ–˜6¹<›ž3þý ~s—;þ‰b ü?“ÇÌè;?ùôÖ±:'“ö´´‰F?W¨™v¬çye¹  `KiÝ€?ü¶YñøËÎ&3¾‚8ˆqÎ!âŸ.<þï1šèHÒðG©®å’?“ÿÊEsc`Ä?ûÿäœ`]H9¡¶X@3/Pý÷ßMÓÿ þ`=þà—õ¸åÿÞø÷ǬÿípßåtúÙòfµÍk¿ìHXê#ýSÝ?³ªiyr÷ã4íýžœ~bב^’Èzvù‰½ùzÕäÙazºB¾Ú¨òl³î­Ín>ù|{šdÿçæþHôãß\ØcQþ—©üŒå?\G}ĽÛ}þ¶KmþTö£#¬_i-ên š“€œTÛV„«¢Y4I×$fÁÕº€Ybt]¨<™>Žÿ›ug©×|n¨øfáÿI¹“§‰ø'‡ÙZ¡®ÿƒÏ¤Í!¦™lDx½ÑQ)¯a², 6û¯TŸ<,þz!޶6D€Ù%ŒL°¢.p†ÃÀtÊÙôù6àO‘}zòBÔ£:'ü!­ŸÇ6tŠ—˜H4ŽÒ@À†€sªéMGäõŠ­ 2àÙ:ê:%Åô<þ¶o¾†VMô±Ç€QÓ5öÒª:[>nù¿'þTôsÄ*ôɸ×òÉùùÛ4TÁå=ó?*ÎýäùŸ6”d{[[¯ÛÑ9;z€…†.Ñ8­èª<¡š¯n A˭ϱW-zµ³³»! f»òÏŒžº$[vtRÜ“L¡hç q.¡_ôÞßøøëå>ò}Öî€þ£^ q.Ù?ÖÅ©BT¼©Žª„d¨çí²1B]kÕ•o$@:Ô¨žs¨Ró~4¹8vü/î–]ñw!¦ï¨9/ëf~"lõøÏV»û’?À¶@“œú/þ¼ÓE»%d'ºP\ ÙUýíñ·‹&ŒTÀ_†âŽ~ª;:Ä­êpç§“Ë/ ÔsŽSù<BæS/ÄŸJòép( ÅF¶85ÀãÏ­U¡6-ŸÍ–š¦Ñ@@9õš-&¹M^ëw¹0üasvrû¸åÿ^ø½þ²îµüáÙö‹åõžÚ¯ñ&äèæ¹á£ór÷7* %ôïîe#?PÒmê¢ìe&úåòêïêmLzš·ÿ¯;‘MS]^Ý.¥9¹_±3 ƒ›‚ä?=0ÚL% ˆQ´J—E‰9ŽºŽ˜ÉrÓR^XnóÛTºq_áymÈQާ&÷±ÊÊTm+5ÿŽJƒü 0t| ¼ë #л€!ÄõA4¥sWgwò À¿òøÛq>‰@+[£o€ÿM½¤ p׉pA dþÊobC mè·(—Õ`jíM…IûÐø=Oçäf.mìb©¿3l}xòúz¸^²Ï Ï‚ž«±Bæ[CúÈ ‹ÿõ÷åKBëÿXâçþBÄß%Ý€ãëÀâØ“PE×)3­O—ÿü5ýCœ ø3¬€ÿÅã–ÿûàÏ3ÇQ/Oi?ùõìÍj½åð®Næ÷Ýy¢÷íwÿ¢&Àq¦œþ;8rX«º¼²®Z,š¡ÅarZyµÁ¯Bƒ\Ï'Ýux3¨œ“½tgPózÝYkÍîá}‚AsgJ3¤Çßë œùKŠò¦}oP°ôagÓ…Qªô„dÐH’Ÿö€qÜvžõ¼. 4'm%¯ A€$P7ò P ø«òÿ€ìèø[áÿ™pŽü?SÿMäÿ£¥”6ü'î@ C@­ ÿQ@†5O„?UÝ5Åìáñ¯òƾ}¯ ›˜f™ÆКÔÛa³%ç<&ð¥e€´D¦v ²§L¨ï“Ê×Þ…?xŠØ@@—òê_#‰œ4 iýáÅÞñǵReá.Âø¼7S ˆ¿á è`æ·üÿ|üÿa¶7€Qxœì}X•K×6tHH#”‚€¤€€RJƒÒŠt÷Nº»‘’i P¤PJ¥Cºë‡½Añ¿ï}Ï{ýï9×ç9ëºÎìÙÏÌ<ϳ瞵îµÖÌÁU'ß@(øÿºA>žõKüß”F—uìKKÄ>˜×ãËÌ)cëVX.¥ùÇ9Ÿë=Œ•"ö{¿uu½ì>Þý{P§•¨"/‚…Ƨ>nûÒ³¦X×6õ5„‹âTûÕ¼ÂÖó´1¤™´9t¿¼ì”ô^è‘O{hè|΃à*u^%Àš>;^úEYÛ'‡ÅòëÂúÏ–¡Èb-òïg?,zŸÙ]~$.ÆÈ¢kØ¡K}·›Ì@¼àEøS£S ›á¥V|I -?¦t/xk²X>Mz°WÍ+u1·EðI”f BFf½õžø0.<éÜãÄ.ÝO9(Çù¤õ)&¿Êž[ÜSªÆ"<‡­@IO\RäŽÓZ'o/Ø€P³]‹öˆs;&úýý­lÆ«·Iã¶TZËmx’twÃÖeƒ/úÐã%°ù2&Ñû0åû}µòÚMKbÃ\É L-œnû¨Ýe÷F9ûn/Zß¹u ;ä§ë7ð²Ck%ìtª>ÏøæM­O|U¨)ª”Ô1åzD‹Ø€W­àW¡-+¸•ØpOK~åbÙ8ÛàȇŒ*Ý¨Š¢¡ìWÛú/A3Ê·ßØé»ÞxWñöÃ'yàg'Í\„ËIëÈ)AŸ)L¾14p=RŒêÆ~ùj3!¶øfY’,þ]ýë#)ƒí±µuÆ Ï}É¢šmÞ”ý*ø/ù O]ü"™‡ßlbæz¶µKsÙ/Á4R+è3á•ÆJùÇäôš¬fΟWJ Jž¶[°kYÜ&_k6å”Ox÷·¿£bͪßÿj΀º¬G_¡6m¢kÂoòdËY¥ý‹ÄßÉ„/¬ õA¼~aš±£(³ƒÆÐ­Bꙡ‘€\Ñ{Ïw>YË¿ìll玢•ÁÓSzpïé‡?G’‰Í¡¸^àþå;—²­>’ù“>H…4‡_nÇdÔï3mA`å¢a®ZËÀ²PÆÐÜMÎèl•‰|º2²K¤æ]y>‡éAxÎü­ðÉ™ça³vv„ZÙd!üf]Mä†ä*ÔÈ%œ÷Ó›*Šðf 8x¨ƒ‡'+ ˜¶I×´S0ËÝx ½o¿Ï'ÞÉÜÿ*L‡ïöøÞÇ*»Á>Ùl!>‰rÊõ¾·ãÏï§t¦R–õ³U±•YHŽâ+ÜŒ<#ߢº+ZL.Xoÿä$,¹Í<ÁùˆÅº—ù<+Ò8U3~úšYù¸pEýì†Þ²˜cNè—Ë ’»ÕÚ?Ä­ôÿ­õÿ?Æÿ*8Ø òWsÐÿqwøxüÕ/ñP!-[Ä.Yú,¿Ð”je‡«Ù;h¿žxÃ…þzÝ*äÂÄPCƒmâFÌõÃ&Šób2浬cOÅŸžWí·ŸŽq»(ÚúÕáƒWôðsê´MŸö4Å|U\è¦ò.þa) ’¨Þ”¢p|Ì·c ú ÿÛ]ßi*¯kd ùJ^Ælä|y‘æYwNu¾zz >6>úQ´f"æÊ›9én®‹t~ŠŒõ;æ×ײÎ_¸èVm÷Qæ¾Æ%ïÙw’·Ÿ\ñGÑüÊk+7ò›;î7¬ù£ßf}v÷œèãÍö-µÃn¾ ÊëÝ¢»—…†\QL&j ØìäsŒ4õ%CÏHÕÓµRÖvò¯éT8·;)GJØo“T­ßÈÎ¥/^‰–ï&ºö婱®óÜŸÿøB6­–jY_ ¯]lE¨-Ê5]Ð]Z€‚ßåÑb4ÍÝO«î9I¡tù(;•ä :$ó¦ƒ Û3å]ù.Ìl4½«K‘ѿ þ›Z¼t6K a9ÖOê„s1÷7 ¨iàùqÊá╼¤uÈIäŒv®Y'éú29¼ˆr˜D¡ÌÔûü¦f÷žÏ$㪭=H¹Í>í-ÛÁl."™°CÃ:BÈ'L~'üŽîƒüA¡ÄëÆ<ƒÅ”·2¤Ñ5_æ`Èê“<¤ÈâÅW Ueý¦]véï{²3¥Ú$´)ß´îYaÎõgàß.um}cBˆç–Cc+x#÷°—|˜T^G3ªƒ§;\ÒÌŒsôÉ%JÌÈä¢x‚"å!·Ù{ü;„|;çòž §å2Ðè(rªÎS˜.ñ?ß“†¼±5™},7^"ŸƒÀ?(k&kP}é-1u óKzSûYGÑ8×Íu:²?~YiRôc³Ÿéá.s“”FR´Ô]t Ç­6£zÔ¨Åd[-¯¥ÿ²ekOA£yøSXú›Â^WÐr¶|·‚[µìB!Ð8¨U·‡íS/ÎXtú²€´úõÐå§çzëCØÉ÷£î4¿Ä‹åär%4pï¾0¡ã=Cvûºû¹:(/KfÿÞúÿâŸâïÿ?ü?›«§Ï¯àÉü¹B»õÄ#¾ï¹0UL£*ðàÝáS<—)€™ ñk3½g­6—µ]ðk>òNí@×TLnJÜá%y*Ì”­Œ˜“¹2œi‚dØ#Ó÷uë³ë9ÁÂV3£Š…@î‹S8mMÈ!·ëj徚Ð;¬ç…GÙ\nuÙÔ.-ß‘ïr>ß[5¶*J—¿¢¦g$À˜¤¶g¢È¦)ë¶—©‰ì3ž¶m°¹Qv;dê5–ÄtM8;C…µ»¾[ÊÁ£Wå„QŽ^‹fŠÕV‡¥KFÌb©³†Ïñ}섦©€-œjáXåÕü÷I¦+î-f]C¼§FÜœ¸/ld-¶X*»7Ù̾<2qo¢.h­Mω&†Š¥lÐ<‘ú ®œû0¡m§ÆlÓ(âŠñ‘HJðÞk^ìR'¶ºm²¹”`m,œ³Ê,(CØ/Ù;AHM=Ýd7µ&ËìJ¾¿Q/ÏžÛõäÕÌ·^ùÝxP›¯(cœMÖÔ½mÃe;&òdÙü”{eŒ‰›ºÏ=|Íž§°íÆq5ÎVâ™aXe’VÉÓ8Iÿ–÷¦öfäÏ FµrÙ­©R^DëI¼Îe N¨íOô TG§Î-æŽoñÖ£cùX{¿[«ÝX‘Ì´q£[~©•q Õ#ê–sy4{ä…½é¿þˆ¤xì Úlò6øÃ‚Q#j³¸#)©­ïù9í&_—VpmŽÚεý¬×q‰gäFZÞ„ãÁ„XË»íÞŽ¶¦¶DG/ƒÊ[ÏË–gߨ­HLêDDò¶˜Ž{Zõ¥…[¦KK_y`ôŠ š©…ÝÙÆKŠ Ž¿TÔ.ýøÀ!íý«¬Ðáü&µFô®*™B$ þ\•Éꟃ?²à3ï`±»â¯8°•ÂH©P e;oñYú"˜mÙ ^Í»7’(C>ÍüõKêî'‡§ »Y_}ï¤S½DÌœùèê¶pWÛ_ŬÖ~å…¨{óB¿x~ú’K+þåz½†ˆ¼þ}i~yDº—Mi­WŠ\¯Q׺¦@75ž(à`.ãÝ¢µ«$ì%&¾ýY,rëÓ˧så©ú÷K+¶e–U^ZÊ·™¦+Þ6нñŽ 8ÄBÌhVá‘Áì”áñTiIyÆ— Ì:sÀèt÷õÍ,̴ư(©Ø+HœÊÕøÓRgF>™Ö ºUjºä‚±º¼-CM®ÄÆÖë ‚#ž¾Hònÿ½õÿ?Â6ØãW!M‹»·÷_ýÿׄBªQ!¶wÖ=lû1«8wöN0ꀱî8CèZÆm¤ˆT»…zÃ)êÖszw:‡WÚk ×Ò… 8PÖÞîbŽÜK–ÿ`^•åŠXªUw#ØÌ_å}¿ÁWß7êK’êJ±ö1ê׉ŒÖ"]©Q²ÕŸZ—ꚮǧå<Äés$¶›¢h’®ÝôÙw l¨ÀO˜Ë ÅpÍ«3>ô}_ä·m³ãEÛD°ØdG\»Ð@ÃæUté|!i0£ªÉb²J°‚àÍpLŽó‡x™Nq„ÄBùO”lzç½øØ=;R§olf¬ÔÞXHGß–NÅI5Ç @mÖ6j®''¤<åÅnìÇYøÚ°J«¨Q†ÈiLׄeÀ/Mø„)›$[—«N¯É±dxˆß·­½4.h\•)å¬ÑsÛõ^KŒšVXfœÛ†mªû¥g¼÷Ï‘¼Bm›Xèz§ÿ8ØÅ²W·`$ZÄQ $¨Áº¶õdäA*U‹DÉÓKUbeOù<ò®sI‘–ñæäï˜ù¤ÝàÇV/}Ùäôgá¿¢t]¯«›X8õÃküË×Ú¶G†\Í ¯Å!j¶fÆ€“éó®íCÇž|}ØYPWî‹ôâ¼H­Ì  Ú@Éd¼]6áÆ+µø•l-´+# ò —rv3ãïï› .¨åPwÝb•¸„Ÿ6Q{Û%£µG7j婯ÂÞø“{åd–Fú -BU/W_&» ßæ'ØçݼušbF‡]â=ì&¥ $¾wQú5.xá†Ûd5³’”Ú\åj×§¯:I&i`¢oO¥`é¬Äçì N qPÍxÝœ/ó¢¥àfXçÄ}N êF>Ð1þHN.cv»ì8RB½°¨"*Pè<ÞµÜ${EaGFÒÒ}-'9_³-aóvVß³ye=ÆGqh ”kWX$‡7¸¤¯õï⃙[‡×ë0‚ ÃcG‹·¬]söYTlÔ¬Ðܺ”¬HÃ{uôÞQjÏ´å¤.{oúíg—gÛæF‰¹‹rÀ‚Šë†Œ9¶èš}–¬~»VW^þ¹fªTõ]ÉpW‰)¦ú0š…–©A{KKry÷š–£Ãíñ̼ƒ-A.j¤<±µ¯ÌW7,߾ƚáMªaMÌf¥¿6 1Æñ~mù,·ñîyiå·.¬4‡)}ý_¶ÃmM¬¿þKTÊ™4ïÊù ²S–ªŠ„„öz•±xhÖBù}_ Gù~èÚ[_mœ0·ä'Õ»1b¨GACTE·x\uô–µ×L_ù¨UQvìô< lüŠ~ïú~§ÎE©ÍB&’>q?MU6£ÀìÝV‰}‰N&ùUý$/Òöõu=¥¦gÚÒŠX îØ·&ä2s>à"¬®ý³ð'ráå|5Z¸Ã£Š;Ƽ:ysq*ŒtœzäJ RV_½9~µÐcӋ©ÓÖ!Xð‘íavÍ Èe%sGtàñ®-ÕÒnÖÒ˜¡)ÿ‚n†\ÅwMúJY„Ò‹–+ü–Súz!W. uï3®–ðZ1 ùWŽ<ðÚ™nÐ̦Öü[ëÿÇÿïµiîæ ñý5ö3þ$銓͸.…Ý â=Í^.5@•EQ¸™b:Ôe‹%ïòÉüŽCûˆ˜ë1·K$s#B˜ÒSÉg7g?÷!ÂQ˜€_â4ýÖU€ìqwpÎ •(é±,CîzŸ2Ñ$y|¿rä²Û·dR ßD ~zo‡Á¼óh‘L¨oŵã’cô•‹•lóow3´Vp9õVqîï×±b¢˜¼ÙÊc¯ø¡P|ø“c¼SŽ4˜ãbúWSÚ˜yŽ:ÉOó5Þ7w®"+,¥a ½wØn6ò´Ô1©27˜Â­Y(qÊ&‰WF‡2,w Ó"žJ«ìUë*“nt:¦#|¢Åéam‡±&b¿Äï V*VˆÛNðf`Å«°\q¯±VßvDÊ í†MR?ÛDÈÈçk%AêI ˜CÔ'1C‡ùn6’@vÁ²–Ah4,ë’HkA%_Òf ‹Z„Ñ%"„ 7÷Vî «½ïknMÔ]–V¸-Éj-±m0£}Ýë.²¸y¼ž í-2 Jˆ–ôš ÿ°aÚ„2U¢ØÞû½Í9Á=$ù"Q¹ê1ƒ‰¤-xé-Þ/áÍq‰ÆÐû?f¨k³nrÑšfï/шNº $‰;¡9î¬}.©{·ÑŸ?ªƒ=ØP9èêxq”SÕêg›÷+ ù3 ÷KM‚°žÑî/Væ)æ)Å8üjøgò¦n~•!©ûrå¼Êâ׊UyþÙ“ê²ÆD—‡†å{tbZ›Ò°XáÍ[…Ï.x ùŠÒ ‘f«gtN¥š¸?ByeÕÜØ~FÙ2/é¹]áÁÑ¥WÓh±x$=^Ïß´¾˜ŽÎ™gØQP~ÅÄ_2IÆ4žÃÞ'zÜ}XR»(¸¿Ø™íJã7gÍ£¦ž¶{öÏß;ÛøÚ â %ÅäÍq–s¦>³¥˜ jäMRñ1ϱ-È…¸eº˜ÎqÇ?8 ÒÉ’.æ‹ *¿Š!Ç7‘”{J—Á8\}Û¸”ÑÉZ{Èä@ðf»d÷E¼ßËÛ©è¾¼³¯ð •RE蟂Gm¹ÑŒ2Qö{ÉØš¶í“FÈv+U+Ë–êÈ7;*óÏOO{³VR¤ª¿%Åv*›xP[Fïž[¯j´Zy8Áeª˜5Ûí@„ù ]^ãRå¢eÚóûÒñ·Q½â<½ãÄçêι‡¯>Ü^`‰ZhsZVÃ.ô §âŠC±®»‰…¹«ã’¡öUŸ¢‘‘ €^ßÄyÕËY$ûzœ‘\ÄÂq•·Ÿ Ä!ë¡· Šö4—Ÿn,‚°°#µm±+JÁ‘ ËÖŸ³¨QÍ’ªvÔHPÑ;ò =ÁÖé((Ñ[ 2¬\ˆòu0q–šÇt·Ž<Úð¿.æÙéÛ€F«é*줡6a1³¤<îÖ¾ª?m7þÉxˆ×lRþl¢Í:4j.ªþå¡}šºŠa„<$E3‘¨q;ˆ;»ÐÚ»3çªjËë_ê—´íS)Y,¾v ‡nô€:“¥Ò×£–Ái¢åw-q¡ë&s¤¾_ò µ;Ôô ð¬W7^n¬o\~Ð=`HÄ$îËX`£»¸ï0L*‰t¯T“Ÿœü¦'øàV{¤nÎcžÝžlH¾€/6&÷Š]ʃ”–UèŒû«;ý]Æ¿þ††öÖ/\æ¹08 èñ(wÓ““’ y»E²txmžÍï=´z—q)²UÍÐ|=y‹ý zo½âùîžeååãQÛýnÄæûnõº\Ðv¡ ä~½mlj³°î®ßH“5vem½[Î×%câÀšziç‚Yf%½zʵ»LC›F›B,FCØ›ÜJ¹­z¹:º&þ—{¯ ´“¼¦Þl½ŸE5ˆÎ¨Ôò,¹‹yqžßX™óá;yš·T&Ï·ݤÜÓ±d°Gf\D”ÃÛßÌMú:U¥FS††ÉÜèuó5Ò«›úè¹—”n›™Î„ÕSp¹û™v^à舚¼¥÷dX½i)©Ã±ÈtÚ$ô½°Š~åéa4J™¬ßû©W· *QÖr½w£Íø]_Ðh(sך ¯Cy¾Ü˜±É­GzþÏÅ?òèKôúùwŠý¢ÓõÊüŽ÷ªú¤FhJl¦¼u¤_5çòâ”/ùÝ"µþè«»¨ß8Ï`(®ŠIï\}á‰Ç¶óÈg¥ð©©’§û¤K*Ï(ëiƒHPÊ Ë”h^Àu± êi§P=¯óN€@;èóX–2™ÉÜ;íìóîYµQþ¯ÄŠã¸c,^K0Îû$x8Z*`ï.Êš>1%»ue«³ü¡—¾g¶^áE€@^Rp¹µRK†í ¦/.6g±ûÜÛ½X½“CH°ÒÖ¦Kµªaéɉû£4¨¤"¶½ä¬$j–A»¾Fœ ®íò݈'Öò }(ψD²P Íö bãÿ½õÿàÏüWÐAÎ`ß_k[ã¿'rW9b·´õôD.Yá;MÖèzÖ㧤SëvZy¾ö„N¸zч)h¯Gš6)\p)%1³€Âm>WJ»$gá¾ÊàGû‘Ô{ï©›¾fI…Ê3) ѽX&}%ïàßíÇÈëþäˆ$Ǿ2Í,Ôðºy7’úJkë–칱凣|øÀNÝøÜ}·š:Q¡åF-Àúì Ö{}BÙ³mRBÏZ;Ì=1“S·ðu¥=S祽̭ônÐþ #æJ~*>ëÆ×‡ä ¾c‘f -q„„ò•ø»¼o¯¯µ¼œl=quàòÍMîvÃEö.Œ—ZF¯C(RðøƒÉu¤Ô|¨ÍB XÈ”jŒ$òäßf/º§ƒýy¸aýKaµâ‡Aó°e)v‡â–T ï'ÂÞ›°!hÿ95#½I(YRü¦'‰¬)«œ˜^p}ó§Ý[dÀ¹§3Š…¤Kr‘†:+ÁqdD 4¸ç[i?s?¥kfðÙï௮xʼnÑ1¸ÊÛ³üFO©†Rõѵ¢xŠ,{¼:ë€r úKâ4_N%i“Ë™˜À¼¦˜'ëv)WfÅÇJRˆ <Û‹.í+%14–=2ϲÞ|Å%Lknþ:6ŠÚ’‘ÕE àc-LPI€oUÝt¨$úë± #¹¾ä$éùä)¥ >;)*ÃKø& ¨tÔJÛ¤‹râ ØÅËËŸ—j<+ê_Å´_¿°XõN_[ c'ôÏÅß ˆ›£X#ù i3‘Ÿ)rƒ†[‘M§Ðç/O¨º%7»ï\è/‚>ÇI×ï"ç7šyª‚ýºã¶j÷ŒT§«Km!½W„cÕŒÉ^íi£Ju4#eZ©áÈ….oE߉IPF*k×^¦¤5}¸/1ˆÔƒ¶.îlORX?1ØqßO $ù¾˜µZ>tjͲÐ4iÕ»ÙN¸±§)úˈE}÷ôÎ-J”`(BS¢ˆ_ª[Þ—<ÒlyÓžòòµ}Š|nFx¾*9¾ªôð:ëì|º¨–ÏÖs:cÃò§®]*w¥éîæ$HÑÏ#‹dçŽÍ)±ý{Çl{ßã{5{Qäo­ÿ¹¿š€þ+âæâáóÏ1€Gʲ =Âë5v58M…è#«Sè÷W÷r5°'ÕÜYlpṴ́´ûê?…‰Ì»ãŠÖOãcoß<ÎC—4M@ Å]Û¥ì4' ñ¾ŒÑdŠ¢3Ȫj_<;æŒ(–dɈ¨\¾ì]• pÞ/*ií §¨Âê+.ŹîÍ:÷çßX¡(‚ü£Ã4>;­ûF&½áa.¥l¸€št÷ðn?‰ ¡ÅAµÚÛÏqíOJ}}5 urãÃÎÑ/™ [„{VtK+Q­wžÑä­2îê,áì&_=‡÷Úvº$+‘3HÊr£­yÊn{Lp1R6«e¿ÃpG’@zEï:òîn3ÂÃŒìçbP,BÉ)¤m¯;Õ¬L‡›°Fï÷a:àd(8o/FRæync‡ÚÝâ4§ùŒÒ+?”Âú²dzW }{Š·'öã<Øv~Uó•óÎÌýG„7‘Ŷ(ñx¦®û 1ZÀe/Sbá]ìtYí €/»AÆ=P j ´9Ôïį¡w‰:Æó3›Ê$´#e€Ûî³h­opû]õÎÍŽ"Güñbf[#g•–€é¶Ã¦sù)¹^~h–÷Á¹™·´däÑ$½L€`Ygw»ˆºBq‡©o0b9NXÐlìX¸¼P™*2µaáùü¾™H‰ŽÔ³j²SSrVõ/Š?ˆ.Ô3Ïl€ñ…T²81†L”¢‹é›YýÁ¯¸R›kZÈ"Í“Ft‰oÛ)Ì·ýŸOy]ÏÔRi1u´«3³S~Äš­˜5.ÈoÙ~ääîXƒóJ¤z2½ç"nv ï`WÜ×TáÁ"¥¶ñ®2•V)73‚=]2ÅtJïlêåö–¶ùgäw¡(ý³ñ¿ m|G»“pÂÇE¥9ýI„†Š@2.$u.Ó¾`›% ˆ˜¢;ˆFlÓ†6c$ñ¡Ñ^Óá3GJŸØÖ—WkzfÁ-ðb†ÊA«Dœhî.¡JŸKþW®×x²)[ƒå×ÞÇê7~¼žns ¯- Ørõ^¦Ä…O^Œo8èìs‰KÊ•Ç%ƒ€Ž,þÀY©\…ç_U™Ñ™ä—z^{È ‰ f±F5#(9ÛÓP7Çû˜ß¾_÷5-»’"¨¨nÓW|É3%Çÿþ#ì¯ 4¶¯§ 2£5’WÜ÷S§ä2Å-¼Þ(‡Í$œ“®•W [;´rC4q ¯³fÇŠ·ú{ëÿ¿?×_M@ÿùçÀ¿)òNSoM,uÝ7§4.N.áUî^6»u%w'˜åt‡2p=óºzYVƒý×—f‡R‹¢AN:=ÃnXÐïLWE¿àç@ÜçM,gÜO•]õªè÷GlW?0 |£bu¨V7‰es ü’þr¹ÃK´ ¿ ÷f‡ç¼2o¸¾[ݵ^}¸íjiƒ‰ýÆKˆÇÌKàÅtšÓÚ1N5úÚý” t?’O|s\·lû&…ý6ë8&í.¨¬ð\}ÁþÁçJ b𰂘ѹ}Í+ï I!XÀ)Ƈ Xh¦"oX<»Ü­¸önxÅTal5€‡v¯(\níãžÎ†WñDèeϸKTEZ!‡¥‹5ô™›Ì̬šÅbèÅ›/˜×§UeB°ð²®øb«dMÚ¼Á&•Âr‘ä'\u·8×¢Ìû³|8•KÜ‹„Î]1®cÞ¥qÝ_ZD*!|;^oõ¾Ã{)íµÛÕÒð”øò¿µŽ1§-Ô&•VöŒÀ×]·¸W¦Ùý­@CC<`!EªR³¢×1‹A&–Šïø*ÁÛï›òhlKØöé¬(#C6;nØŸçf+Äjϸ”…®eK*Yf&<Ыá£e[[aü–Ç‘ãAx`÷ÒG±ñÞÌgŽÉˆ-¥7Ý0ÃqŒÊ/ƒF°‰ýÅ„îlqÄçÛU`#¯ÈÞÕ#˜îÁª`X7z‚“{®¬þ樗ú«­d”p%ÝJ>Œ‹•³x—ýÞÈ#©õªR=ùxÏá|&çHöõœH´ôpR¦cªq»Yma„·H쀸²åfÂUËua¯Æ\ß·-ï«®ü­õÿßÿò¯& ÿžüó'ÿ )jÚðÅ ãUdOÙ¶zb:D"z2÷ÌYExÀ¼Þhøêͬ´» ã—³žWŸ¿–K®8à§òR˜Üz™°”D­=#+y§À~úà æö´ÖÍöi ɾ{€º}ù6šS›p†Z+mà*ÄfBZç°¯]û,p>º=§%|¿}ñah½¡Z'uVi¾ÃײõÕAÙÁœýû­™Æ6—l…—( îc \´ÛÑÅ\ábžLÚrPUS:Ì3Ü›‘lE»5ï’•Ú´6â ]ú²û[6_ïu!óJ Ùס\å,å~5ª^Á»"ć¤}™ÝÕ~êãËn i .×”óe¼BÆŠ„Ûk¦nw(ˆñ7Dzw7×ÉZeÌžRwÚ,ºOS+c_H'L¹ƒ‰Ëùv B&Õ„°™©ôu¥X@°­äb#_ï«_ÿ+ž.ŽŒÞ*©´CPÜù‚ZÏŸ0+le'£” Þ¸ûÁ9å‚zyïÛË4×Ä?ô6>iwzNÛ“-=Bɾ ‡øó ëMð†Œ[ÞÇór‰5Ñ•·Øï„2lç·iy9ùWéı °Íbñ³¶iûÆâÂy£jIUÏrïc48ošMÍÞÜ+ö#_ú+ðïm=ËaîÞ_ß4V$+ßÚaïÉ’ãJ½ çãÞÆÎ!7C¹·pëþ³½yû|™(ñ¦“\ó6Tè£lÎ,ôYEÊóÏ.ÖJ ÜÞwì4µ« >ÑŽAêó¥µRÙ)’n Ðy·>Ð~Ÿ Ïâ)~Iòâu*4^÷–èÙQìéÑ»ç“:¢d=³­D}ÇõR¥&ؼ[Ò;‹óÊrPùëæQÄU?òá.%-õ6~Ä5—V¬â½Çþ¶1SNbó|6a"‰] ¦¯íŠDaÙ£Û aÓ§1Wb*”­]Xæ ;èò)…­P^ìÊ\´µ) ¼Ñ6Žüê&ÞDéßZÿÿüþjúoŠë?ø_‰<Žá@àeû‹D î¸7ŸÏôDô䯰¦¬9#ôßÁofKÍ`Ñ €›øÆÉŽÇçBqk9cÕM¹ZóW,› ÎÛPDeNOÁ;‹îzDØþÚFf² ™&úÙoG+ô”R¬ë ò ^ŠÜC@M³zÇ„+œæ/ü¸ê0™?ÙÄpóQ®¾»uèƒöÄ[þ½¼qZB7^ÕSH8‘Ü£QIGót¯-GLà "-êX±LkCÌÍå²@|Mö\󬯹+j¯0m»¨tœYC³nÍ’‘‘{E™Ë´ò=£^VÚ¾¬€ÄÂõ†"þ^ùã¡&D’ëªøÜ6çÔœ0îÑ}u$ߨãM5t宜Uúµñ×Rë¨p%dQýú _$ñ+“µb‘pTV7«~±ê:Q›ÈüNž&æµm÷l´± kŸÄÕ{óýp(Q*)Jψ„í{9W“Ï &÷ÅRDÝY©³‰±B>ÏQ ’{M…äÙƒ~¯X™YYÛW8\Es(`ç^ æÛŸz%÷@øàÐG(Ïó^ýd?Z>ùíL ÁíísI-S±Y ȯ]ý>}Ó¾2<ôL±­Zšz‡Ý³y'ŒŽêšVŠÌÊ}±k©W)lSùÙ(+“¼·­ˆ=ž^,ŽÕó`šsÒé¹¶U¸ ˆŸ´4{†$(¸ý&1Ÿ¹€ºk+›8æÖt¯´Ç¾ôJÉó~Ÿù2Ôlsž*ë/ê{ ë~h¬/ û{ëÿ¿Æ?á¯& ÿªÿIà_âŸ7ú¯‰D†Z³ÿÓL½ š3šbz¦lk?‘t*wý—ç{þŒ ‰½˜ÀÊ­ä›D_6Ý)Ö‘«‘ÍâÓp6û‰dªM8Êå.]&e N´ N=ˆ—ÄwÉ)7’oÒÉ0¶$¿CŒ·[ƒbC(„›g&™í‘Pïèñ\‹hó»…”¬Ð“Ãhäsè„×Âxó5Þ­ô–®Û­³~ä{ÔeiW°FÄ&†âÐ]f‡ ºo™íݧ߰¶°¨zôF&GÜL´[M£nÔ"ª%†¨s ;†„ð …P†Á¥wޏ JUÂ%ù±JáÅhû²oŽñ{üàëœáJ¼|{@E'Z_TÎôÙ:²TεG‚Ïz|gHº[hº°¯àlµøÊl‡5ß~r7JŸ>·Ëêõ¹\o•dB#ãëT-œ#é+®Î%Nï¿Üe6ø´C=_Š%Pç£-)fõZó“+Ò Ú΄þù l ýËø½Ÿ‹™%¯]®oþÕñïѲΰÂë^$¦›²ž%ß &O~iK´ãùBœ ÁÎ6q(øÁ,ºðg׊í¬çŸ\Dªæ_ôÝ®:,Þ¬ŽØ’»štýþ ¿!æÕ×™†=ŠTzu ŒSZýholHX{3Qhu¿B`c1jC´>L#il9¯AÅÎ>>Ấ˜áfsù_…?9céÅÏ:%}m,¦&Œ³ï…æªÅìý^­V-Õ)¿¯K篧Ëåø¢¬3jû¨žË7žÝÍ_%ÓÙÙD^³‹ÂòåNèÔD!NìsÏÊå”>Ñ ~²†_”ÒïQ ÌÕ»Þ¾`õ‚fZ=j‘‹dücñ#íä&­|ÒG¢èÔ¥ ä ¾Ê–ÂûhF sD®È_¹Ü)µ ÔµùÙ1îŠÑd–1ßÁHÅJ³ÖÉ’I@3¬¢®ZÏÁ`ÝçõîZ ö¨Üo¨`PºJg0ž:z;Q„)O)P÷IGÅܩԆõ¥XÐZd^(>ö%ƒ0ýzÒ(KnŒµ_µ±¶!=~Þß[ÿÿþÎ5ý—åŸø—ª‚%¢gj|qWibwcÖTÜŠIcW}%@Ï3“‹Ð4Þ}vÝwî—#ç/[ò¡Á|üÙÀ˜ru}ãY%pù™öb'[ùAcm^EáÜýûdµø\Õ+>-Ô¦Aéœ4©n ¯·ÃýΫã{ T¯ËäÌÖšaŠ£]F¢–z7µTù¥ÝŸŽ½j–R¯““ ˜›"|YN5|?íf=ä5¶ÁDì ãØäˆ;ú×§œä,«i­˜‡â· gšj4Kî&¢ aÈôíå|͘tNÆ”í¹9;ïÝ?Ô³Ô  £È´(($®CöÔìÌ3½Õpi£\ [­å#®úÂÕ0±©P'ÓnŸóá elzLn>èåý"fÚ V¨<y˜9í‘[A³Õ3Á˜WŒ´ d]‹“å¬hX[×n¢U_Ò¹y.A"†Ý#¤;‚òÁÓü®"9¬à~š¸¾œxθ%W ´-猪K$©Êï2L+ñZ?Zÿ¢"]±¬yƒý)Þ³Å"tÊÒ¦ìbÕ®NY·)2Ï«õ¹Ä álîM(—²›“p*? «Ý3e´šºŠÉ™Â2.m©#QÝY@^÷eùZŽnkßHéA—Þd ¹Ôd¡’ìûÊËâþ} lõƒ6Ñ)«[=Œ}ä¸ICƒÊ/]ütZHðçµã¶ª9H+²qeg‹žžÉD^²ûõñ/·¥=97"VrU¦'±œ“iV“Ž-Bqßÿ|PCwªÕÈ|±Ä$Wþàù{ØÒùzæü)P¾w¼tìÝÓØ|«VüÕ|ç†gr Ô^R®ºèP?Í"M, HV×lW|KTQ£ü©áùn–zÓF»[‰?æ a]„«8ÅÛÌQØ?ÜÉ]ü«ðØšb»ü™üQÖ@n;Q‡ú¡—H n¢›îµ ÌoâŒz$GQWësŸªgÚ:†Y'¬øHq`–.µ•`Ó;&:?oûÜ:"ÔWrÈ"/¿—Ž$éKIÐë&9x¬¸¯ÜX“Yã•(Ë7Ù|¸ x†PùÅRÝ»ø”üŽzfŽç~äÌþïgµ‹0ów1?Pás¬¦ñ!¡³|X˜àïðÅ+Äm¿£,Íp?¾[MËÙQýX¯DæJÆ` ãEïj1¤°cjU†oCHVy ÿ¹¶7já}<ŒnrÍ"/wE6‰³DÀ!×{!Ô›á#Uù>/Fu´Ô«Ø’þÖúÿ/ðï9â€ÿû2ü+üŠ¿B$C}‚½àÿ¯$èû‚¾Ïç÷«@ Èã·=ÏÔ~wé¸B=΀š~èr¶rü@=Ž_‚À È‘üÐ~$.®þgF.–Áþž'ï|ò" 3~ kØúyCOêg¯Ÿ-OŸ Ð vs;þ'3@?´ü¦€ƒÜí¢ŽÏ¡BA ý èèÏðQ—£‹GïüßÑuWŸ£Ž »‡ì   ¼7ÞÙõÈñãkðäñÂû¸C<@°1'CŽË£qÇ:zOÐñS 0àxjAÒ¿ þáÇWŽÃf÷x `(MÙÑïz°ß}<‹Ç-GøûÀê°N°)>êz< :½»Åiõ¨p}ÃÿGz¶€ÃzŠ-¼‚îVþ(€#üÏ.Ⳬ<Âÿ[¦LÄ)þ Ø3O–0^=ž0à·ùÁÐÓf¸~_?­AÀð!@èÉcèYüOo{„ÿ…G`†À1#ÃSž£9ó„á:¾é)P#üýŽï¬ðÛ]¬üþÞúÿŸâï þ5˜óà?™0ß@ÿã 3tðêû~ÖÔƒ`ÈÍ?¡‰ÓÛÀÕ9ùzC gûÀVýÙQ?òÀ‘Ñ€@x§ûA~°öo:rw²÷ñü–ÿÌ ÀK€“7êù¡á·}~PØO€=.¾?ØŸÓa°7{íù®ûàïŠ ×ýï¶èzd‘ŽmÁÏ@ÀðW;n>&sxïc3ëî}laíã3vwòñ‚ÀÎÍëÄhÀøîXë¿û(ÜK€@w(*ûËàoîãë „óœb`ÄrBÒp¶9áùüá^ÂQÃ1›ÏìÕNúÏî‰ótäß Ž?äÄ»ømó §3 ÷>ŽðÿSð÷ð‚‚áøÿtéÂ^íñï @Ä¢ Ãþ(ôd9èêd0 =­<àøÃ®tüI FÕ0ÎÜ€oøOoû­ðÄi8 ¯áö8Ûle@ŽásÍN½‚£Yv2ÿ›ëÿ†¿ç¯B›'ÞÐ?òÇD5Ð7ÈëÔ¶þĘ·æðÚ‘s…ü¯öÿw€³]¸ä‡'üqà©îÂÞ?ØØÀÅÚ'Èúãų*ÿƒ18úÊw¯ï&ãwåO­€»ƒ¿×ïõü¬ÆŸ-ŽÄÅ!ãKüÏIÀ£Î>Ð[:RcxåL®è¯ß*?Üh€\>GÔ €àñüf§©mð1}\ÈéÛ{Z¿þAGö ô* ðóiþ ‚gH`)w?þžÇÆžV†ÇY'sšú‡9à3^À1þGwœ1ømñm£à[q<é®6þ®Çÿ¿óqø³5 ûzž]ž  áþpŠžù!“5rDâ§5<$=zü„c ÞVƒž,+àiîD9PGø{y|¿ÙI¦åÔ!€½#ŒÐÀ§‰˜ã… ÃÿÛmO’ÓÎþÇzòõÄ 8Âßãï­ÿÿþ>¿eþãüaÑóò9ÝÓýYTú1üƒ]syþÖ~ÿ4<ÑCw{?ï# =s‹ÓÊÿžlC~¸ü+À³þ¨ÖG‹ÛÙ"ÌÏóG]?ûñ£ÿï{ì gô ?6ÿÎ üX9½<¡¿ÕóïÍ¿»äþ0Þû(Òö€o¿9ÿ§I@È·ÜØÍÃãÛ† ࣮bù¾èâ>åù£ïîΞG†öxðÛæ?ä7¾€;ò½á¨ÐÿÅðòó€§±OÜ8§Ã“§ìÏÿáLˆ'äd¶§üá}N§î{†à˜õàøÿŒìA§8};jp<ÈÍèÏÃräÎÀ§;À¿#±£Åx’>-L|}~ XxÌœÄi2ÿ$?~²È úÅŸ!û£—…žx—@(<·ïæp‚?<—ú íÿà4œ¾Ä÷cðÛžt<é° ‚qÜ^Á±[ábô÷Öÿ?Œ¿ç¯Å—ÿxPŒ‚½œqÈ7E9–ŸWßÃCœý ójº]mCŽ´õø¸Ùo›ÎðÀ–üÄâ«?Ʀ'íî¶g6¹NGwG»0³ þÝ—oúïk€%ÏjÊÏœþ3U+ØëÈhü Uÿ«þƒÌƒý! 7ˆç‰ÂCàË?$aÄr4I@oX„„%•aFãlÎ@@çwåÿ±8ûxÝ<áið“0á¸z¼_K|?{;ã_ §0oÏ3”rBÉðñ$Ë ËÿçaSsßÃn~ð€ü6õ>I£ãñ€Ýøí”zÚ|Ö¦ÃÑ3÷ÿñ÷8Âÿg;À ØŽ€ý°:-Nð‡û=pæ†}œ4ø$™Ãÿ´áÿýÌøôì$ÎñðPäÇÄÕ&ôÐÙ³´’æÿîÀœ#üApÕ]¼?ß¹9ÀtøûÃa@7[@¨÷™œÞþvØX¸þÃbÀ³Û€?Œû6øÌwW€ïñÙ¹i¿5à³…0øX¥Œ&øLð¬gÿm‹ï8xb ŽM¡;Øó4 :9tD:nÞ''û~Ü„'øÝ\ýÀÇÀi$zrôÿô4 øÈÚ}߸ƒ,=üÁaÞÓ~zÀü÷ù€½¯7l‹ÿ¨ä$Ü?=’v ,­ ÏÖ‚NØüø.@?0Ðâuº­ð›â÷§\ÿLü}À`ÏoLô»Ö =3Å ‡ÀügbþÓHÿdOüýâi ŽÿIþr¦öý¼Ài(Ãÿ¸Å?×~Ds“,ÿ7‡òý\ ü „ß8}38þ§G5¾%àÇl]þÞúÿÇð÷ÿjòO àˆ=,•„Ç€pùWçÀNüg ä'þ§áKK‚¿éáO:ÿöó§ÛÀ ·ÿ×Þµ-·ÑßÜH*É®äXIsÅ…”´»rÙ»•Êsò›A_§-æÅª¢„²A@à4ú~ºAõJ+ȇÛß>=iÁòÖ´Ìÿƒ2)éÃãg˜Gt €Ï:8¥æs»*'Î ãó·‘°ci” CÈ—AÀ6õ, H68Bƒ¿¢»šã,H[%•­Øµ.?J.›¥B,1„&5þ¿?ƒØ´ñ¸{qí¬wñšyÔ3âî×µ€b)•ZÀNÁ3̪®@É ðÍ¥“Óâ)I4‚…€îÁRZûüÉ–fÝBKÁa„¤*þù•¿”†öþ„Yí™Ë‚-83`AË2@°^ŠÔ6`DÿÀ³¬d¥ÙúOï›ÿÿú_ã+r>,€Ë—=IäùÑ”HÿÛ0f©Yô«£ÅýãsgƒüEÑßÓÀÊâ¼Ðjز;ì©_–¯Þï~ùú˜SÅÿfë/‰ÿÑ9”4Bb±©·83,Š. öâzRµB‰ôÓOÄÒP@N–|\Š^Ð?ÛëŽäFiÔ= ›ìK>—DuåöÔ—ÐEbÍUÒÿöYE£ª@-Eó¾^èÏÉz¶3LüŸ*%ÅéÏb4PXöpÂø‚CIõ›•…WàÊýôŸLÿ8Y'Ï>’‘‹Àå@¢Éõmמ~(@ ë«.úK9Ÿ)þ““½À0fúÖ„è3Â@‚Aýóm¯(óB×Eú³}ùîü#Ò_ÊÿÙh4 ßýüò¾ùÿrú_£þÿ°._¡ê^æþÁBqÓzßJ¶»½—úra(åcçý@û< Þ:%.ÿªK|Œ˜}އ/§lX¸vPZÜ'{Ò€f”9o)Üž €BUm™þ² 7ÏÖ ûêä_ô‡c6%Áäoz5Óa’]îÏeIGí›G‚¨±ê‹Åƒ©£ì¥¬»+¥órêgé nãÿ÷GÈ!Ö@HÿåðºÐkҟó€jC…L -VáfüÑôߢ°§ÙéúTÏÌŠ,%ÊèØ2Àåö²eœ7ÑÙ¤(Fô·Ú_ 'úËh‰€/.à~˜( \Lˆ0Ó¿?Šq·ˆÿSPa¦ÿ?ß7ÿ_LÿëÔÿb},¯--®) ÊÎÙ–øßðhjcpSü b«»;)Àùnæé\YJpƒ £WçôZ·é×%w£¬ioÓ‹ ”Ë…Œ0˜ùLÕ.O¯þ…/v£x¾¾S %æöнdò Cö.Œ‰ æÊçx‹ÄÝ?¼* sžJp¦”x Äò%ðï©; &5H¹m²ÀoUç´»Zúvàø?û“(&6Ìô7JôLר|t¾¸m€‰è£¿¶&¾yߌý² `(¥R°Ûÿxú7Ó°òþXóYØP|~ÇÎy)´@®«³ý€0ß—8>¨·Ä[ÒLHè¯Ñ—ùÇP‰!XÚ †‚ ¤>i À­â±aýÝûæÿ é¥ú?ÆÀE ë ¿AKÈMùFB£ 4è/Úç›»—ª-—Ô\›=+÷O¹V”ˆ'„w·Ø²dé-ÿ>ºÃí3¤×ü_Ûÿæ8ûsFH,8Ÿ9ú¦$W nÈgù_–æö©Øüøûµ(JŽÎw¤¡R!’žôRˆ‰³´ãРà.s,ÞˆR5Œ5@¼/º+¦ÿËó×ñJ€÷pœ¢$I± F›ÿ(› /Àaþ癃ÀÅ™þ‹€‹6€øù-èï& ϧÚ$=¦TÊN>?Ò¿øü¶!àF Í&Ò¿ tÒ,X:ý†™þÜ–Q¢þ®Ý€õ¿êÌ~N5‰1ÓU»d¤Ó3·"@{øt|ßüý¯ÿ§Ë‡pÁ‚ú_1²4ùÐ+îŸðö‘_U…ává©_ Ë4ðB,ð¼Ó4pè>ÿ6¤êèb0}¸‡›o§œìHÃìkûîÌ¥~³yoÒª 'ÝËAà%ë×1Aÿ—ŸÈæÇöŸ>`a›åû¬5¾ÍЗè ÜEXá÷—  o'9ÀšÜêùùœCÛŒ h²HЍú¨ë“h3wÍôÿüí”rÑ=‘`æä6úûi•£p?Àh'ÓúÇÖ¢bC@Ð_[þlÕfÿ+÷×?ß„þiÌVîË&AÀè+ÕQˆÏ¯Î9öÐ<‡¨e€Án±Ñe ôbÜEú#éù ½™³c«ÿI“ Ä@úûÆŒ5 lýq"([°6à«þá_ß7ÿ_@ÿ«õÿaù°^]Hÿ—iRŒv%ôϺ¸ËbÇã ú[Å4XûØGü’.0ú¼¦›‡_©Ü–Ü—OÐ{íÝþË1›Gß0ûÿ#«Îº1ëÅ—¦?í°oÁSò°äøz>¿ö &Ç  >ë䟘ö•+ïkp–ŸY‚€³}OOÙ{]ec )Âîp’¢cIp¾Ø]7ý»—SŽ6þ¯Ú%óÝ 0Ð\šç¤—üiíEÑdàĦºá?ª&쯠…}Esý£Úx„¤„¹ÖnÀì¶.»‹9QÃboÿ+Wd/OÍJ&  á›_òûæÿ×èÝú?ÆÀ÷—•þO„ѵ>¡†‡Ïˆ uDW]»­ð/ohxíî-paz*9§åío Çoã#tÍ™7‡»iRþ¯TÇ«µ@îpYŽy7¤2T®K«ùû÷ ï“xŠò¹6ç|ÊKAÕˆIZ‚B)3V¿­@ߣ¾rM<öœÞ.e€Îü—WúÿúèÿõiöÍÀÿGúW-P{G|ÍíüûùõA9®ÍJíØ‹å€NO3ý)ª +µ¶à”öooG7õ«'˜ `0 `œiÒà ìœO¿ê·Êq‹èáŽðÉn矹  ˜ d¸eŠË—ÿSÁq1´ €ßÅGjøŸåï{E[â_ msóô¾ùÿûôÿgPÔ(ROxœì}w<ÖÝÿ¿½gÊ(‰ˆŒÈ‘QvÈŠlYeïyíËΖÙD"+ÊʉQ„†½÷ø¹†Qw÷çûýçûé~üÜçñè\ç:ëz¿Ïó¼ö9€üÿž^Ð@ØŸ~ˆlºA|µ_Æ%Õ¸îø˜D:ë`ÿìË5}_õÉ¥PRÖÕB}|ñ{êÏ(Zïàèv6 q¨®ÃÈ%k¿Ó©‡Xœ åf~<-a+çLµt%¼°‘xþ4V‹ý¶ÆÇþF•ž!¯¹ëI"Þ³köáJœ,å“1 É$§zKÍ7¬§ÔdKƒˆ ]Ö¨uþpû|·âE gùÈwûëÃK *L9_?mÛÏ–Jª)´¹à(f¥'Û‚–’Ê2¾y™ŠùFÁœÓ©Ì% C÷ó”ésÓÕ›7&ìÜðs&ß»OR¼“ð$…dºgõe8.7.„±11’tˆ¶IèÝWõXÎ,M\[ª¬ÿ¶~¬Ï¹ú^Ô(9^Q׳'ó ³=T–òð%ºÂKޏ/îhno¿ ¼ÈÒë §¯{­qâuÑ>·«çœÍ[(UÄ€ ¶`¿wæ<ã1¡ûaÇã‹në¼×§èq¯¶g@R†Â”:ŒÞ•æ€ù¨uZ'âe³¾ÒQwÒyí*ŸJ¸q“Ðc™‘pŽXlg±L“Úü™›P•Bí•*¥óÜÚ‰§^?Vô¡(‰µÆrâÍÏø*ò=Ì~¦{Š‘®Æšàsû¥Ef·ÇcXÃVßÞì`4!xïâ;Õ‡Cu‚–]B…î;Og2Þ¢±×@©¶‰[i ŸöVî (öÀÿ[ÊÓÊëJ÷GYB…KEž&”‰8<XôÅ3*Oð{Ý„œ´â×Ow­.f¬àÿò¾}D]¨öŒŸ2Ÿjm“±ö§<- <ÂãOÒÚ¼®¹¬éÖˆ)³­b7LMX ?9Lÿ¨é3Åö»¨ÅËŽ@Pµ¶³Gx±º›Ù˜,ÄM–ú’›“½ÍNןÃ_ý˜j|êq·¨Ì;OÒXÞ5½ZÒ’í¼‚€Ïi ©8*å–EAµd•ŸÎ^ùvÃÊ# ’À±×á¡jÛ¥"'¿+î­ W¹¤1X%å‹Ý}²äøù¡2 â´SgB f¯ú= Å”4Úº•%Îl.ÝßCsÞí!ð ¼p.»ü‡-—™ÿÙ¶´k/ hN×~Tl ¦òêÒxä½<ÜMâyN2a;«÷_SÞ öq{}eSËg-¤¢M¿%?n¡ñí#þ,æî¢ [ÐWØ\—§r{F.wØÝhj —tH­tÀHm!AHTÿ¹Ù;)J[O’×­.›žg Î>n?ÚôÿñßøÓèÿ>}¼} ú)þ¡I:í=ûf誱ͧ76÷KóûHÕÆv°39²Lù³—ã.“Äqž ÞLUÄ5î‚:˜»}«·ÆPfÎ0ïò¦àæÛÐ}w¥`VÅðJ¨<•*'Uõ›:m|,®ËŒws-œÖ•Aw¨ç½þ(”A°Ä^Ê1ÿéF¬Ô:éT ÝñÜWål-ÙmÙŽÇaît€ð.bYg)‰ÖCKã$qX1ŠØé¼JÓ¥fîmMw‘5;øamøǾ#~+S>á”ôE‡ç¾Ö47é³W³Øn òMÅÖ#¾vÇû¬{X89¥)ö½«ûTnÙ§zë­b˜ç¼³é aV7LÈîW¸¯4§™,j]V¸RDiH³ˆä„é”¶{Mp£/‚o.¸Í;)k;P²N¼ '?W)t^´†Dûʉ7–_¹hû}Øš™¦”?”&Š[:mž‰×Œ{G÷o¢Hñ{I ŸˆMب’V5¯òÈ\ÊjxY`céIÈûGLêi‡Ä}mq=ùί•ˆò*{ÐÔÖe'g¬°ØÑ8÷‹öÕÆŸ³W=>P—:öÕOÈ&tÉz¿’µvg½ê_ \ÄyùläÇÜIùÊ9EUoKc¥~ÕÜ…¯ax“þ+Uø*Àª­ëœä#W­Î~ñ;í‚I¡aÚï¿n°¦7$;ë™ üóñX]™ïœÀ[Œb‰k1H¿ÀZVždl)-ÜðÍÖ„wŒzÂü3gOÆŒu¼œM#îkøi÷f–Ç=r™ ËÀ©h{©ªaA3@?˜0ÁKöEý‰ÄþW¾Í -Žô@F¯ók±Wµo4ץЯ˜hgÞM?ø :Ã7p5bÂÛ«Ÿ î]ñ'ñg*Óv2(è8ç×|;7lÍ ûô²ÜµxéõÁíÙMö›:ê…,؆4÷èËØW0V¥úiåÖ•,6‘×ê§vEjÔp(€é®Ù ®é¥±´oÕ6]#ãð¨š]y´Dp¼G^W[d+®¢)Ƥü h–žsûj†…g}•¸í+]›à-nX׿'cÆ–µ”ãIU‘ÅLôyCD†nÊ& FœW¾ÇZÚg¬=1±`® „ÔF–=¢({6”"z:Ì¼æ¢ø™í:æçâÖӞ鯛õ ©j3=‰(¾JY,Ún<€Ì¼üˆ˜™tc êm MóEz.Ûmúÿø‹ÿiôßH`/€¿ÿŸ~ˆfªµÊJ<ÊXz(CÜÛö¶í,V‰ ¡Ãð£oß»‰òª(¯7 ݺسÂtêBî¨JP:ü¥ÌɈÕ|ÙØÜys<×Ùçz皉=)4:z›¨»e.,Ÿd+ÀÆÀçd'¹'FN»Ü‹uÚ±@ó6=u²Îíñ×vk¥\y'äÚ'$ÈÓØ/ h?$Êíy…y_vƒJôö[r_Ò î3Å™]æ$zCnò;¿ѨÞÿðŒýTîÇØà–ÕK›¾D!ÛCº¸¦µÁÖRÇËÈU°M§½Ü"åCùpõSFïã%â“ßák"äÄ ª6½Øf×lHsìú°x`̕„w9Cnæ4Haè2mÅ.‡!l]ÛÈË’‹ó/êÕ^¸Ëh1&2\ãK%7e"§7^)Þ£jþ´)Ô“!ç Øj¾õÁ¹’/¹Lª’™§Z})¦žK¦Í®d(?]á96W1H¸ü)ºVÁ<9)DÙ û¾ ³œxØYñ‘©›¾Aú~O"ðúbÂtÉm8*Ê„d+Äy·‰÷A¥;FŠÒª#œNÊs@ Nˆó³º9öri*迉üxÇî½|·ïx’‹QØ •Ïï¨Ì&u Ké»Än^¶+¹k¡“®6Á•E•@άg“-£éseï–†ÝKÏþ죉YšZtDðo»uÊ㊆ïKö „ É /öt¿ª»=Ùu)h‹"E¨gàa†LP<Ö=•|ûšqg¢ aCHŽ!tXÑÿ[¿êh,¾»Œ”[ÀZÜ,Àð½1‘…ª•æþD“Ç÷7•ŸSRóW4«»VJ»»‰w‰Æ©—®:õ^<ëxê,úÏâOaa&êûXFÖûÞh¾.õîùÕ%ƒm—§c¾+j-®Q}Nõ&ŠNN‰(Ùø“Â3örséÀ²â—\[L2ÒF;iá=‹-ª¾’ªÍZßµ'j>Í5L–W϶–÷ýZâäü‚‡ìd¦Ì´ôr×x—aAZ¦K*^Õ…A‡vº†6áÇZ^ûˆÜY2Žd~bÞVw|KPÁäµý}½øÑ;oi'LŸÐÅÕìÐUû›”/qôyÑèK°ïH<³ eƒ´Ù<éîÛÊùè–o¹‹{ÝÚ%ã¼H 7¦n½S¿òádGH ×rV•ËŽbE×ÞÆî”Já}š—oýòAɦýå5>¬ˆ£Mÿ‹ÿÉ?-€þ; èðýÓñOLÖn®r‘Å42¥3~§:ûà0ŽÇÛQb´›æBEް“$!Òº;VŸz½±ä‹ßÒ ¦4Nú2¤]éèûPµ&DJy»”´”£KfPÌ䬈HÚ‘í+wjœ0¥…±PÖ­X¬O©=[|¬xìîªÕ5áðÅ"KÂ;ùvdcV_:ßV>¥f¶¿ÈÛ0s ô.Âɘû\ž/;{+Z[EÅÛ›Èf"ƒtnþ=˜¿NÅä8wݱ·µLñ|<øc)UФÙXìz£ xißêß@ð´ú¤*ù\ÇFÁ•¼ýl¾§˜$ŽUêÓÖ/÷Û‘‘tH‹»?Ô&ÞÁ¤r%2Õü²ÿúv¤a’ü+ô£«™²?#Aµ';a} ýVö„J—™/Æ „@ú÷ÆÙ^Cî—œ ×¼ýt¤ý³LGƒYךêÆ.µŸ4 Ä‚¥R‰´9X¹·ÙEãvóŽF’”ÛµÞ MHúD¥ðfÒ{>ùtϲ[ör8›·ü'2æyº¾å`ÜʪÆyHwþÍ=B¥NŸÙ¹Ö ëõ‡îLIó 2 w|ö[ŽsÑeÕ6‹0í§³8^‡aëýíëß蹪g¯½eX¹'{\ÿ©æY<ïµçØgÏ;×ØÍ¼ÒíÜjL¯ÉãtK_ô>Æ¡ƒcÉ[4«ç­t•ò‘ö¦j]Ƃ٦¸ºAÄ|³¨ºwÍ_j-‚GCï>GWæ«Éà—¦ëñ×sY¤»‹7ŒmÅdÅu×AaE5ËíæœI>Ÿ€¸jg#N³”ÞÄ»Ýã}Eý yxld+±þ v÷-¬È°û/p£²#.@:Œe3ï x>¨+ùá6¥[¼FÍC iëàdy-N¬ÊYÍ¥„)PÏäµÀÚrÊ‘‘ðãU¦ÑN.F ®¶\‰´ç‘ÓÌ:6dPz5ëÊr‰‰NOÛ÷*z’BŸÎ²xÒŒd‘€=mOqÑ‘@OÝZ™È´pÐ%Ÿ{u ‡ëݹb.¦ç¡ÎÀˆ‡óãçÌ^±®íÐ/}Ë•~+ÅrÁ#fYrNŸ:ýÒÍ©î‹ÓöÎ¥+QžjKº7”–ÚŠ€µBÚçwŠL*.u¿Ý¶˜ê4õò\fÐ^®}Û¢·€u÷"•‘e¬|JôSíÊkà¶ûjF¡7ôBƒÓ¶¦³k}ˆtûgX½Äú®U†U¢½C>ØR#‡58Wb½b€û¥æ+ H{˜ôêÃ¥Æaźïv[BÏG+.Ÿ›… ½eJÅ}bÊaÕ³»Ölª,9* “i¢¼üŠ7üJø…ì>­…Ì< °­ÌÔ2qÑz¼"{¦¸¨:ŠF£ ‘ñ ?²éФ1Ocí§œxææ°í BÝ¡®›ß\_ÙS[ŠÛ®Ç_s©–9ïÞØs‚›RÂdML.|%yM߬{ÜÄs°R\¨B)&¾Çj›-¬hÂãMVß0ï‰àBÅðÚú®Í)W½èý7=鯂¼çN’öÉ^ :zm†—ˆïtÈòÙbè±mðUiÞãö]º–8ç5R‰âj‰“—.ŸÔÂ,p2í{õŽK,¦Í×ÓLä"tV?ñǺ“Q#xP¾Îü“÷06Øð:Åç±öxÀʳ1š"p¸hÊzE….’þ¡Þ¶Süäm¦äÄœÇ9-ŒÜ)>Nß=-Ì÷©P<®‰U7æeßžÖ÷Âñ£É™TƒcÕg-¿Ny“ê8–×W5ж¿&Ÿi7v½œÛVÓÞnÜØI!ï¹±AjÕmî½Gw¶OÉu\ã×â-dLTÀ5ºÌ©*©â|Ч#çææŸÇ_7æÑFŠ(ëoÕ»Þ·sŠÞ˜ú* iôÞ¿þ’©ª#dKžgQ7C¦-2AÈ:üƒ{ÖÆñú³orÑß”b\ÌP³)e¨óêi/Ês›TËÐgÒn¥ùt“Þ¡œi­ä8v$¹äe~û{2WŽÕ¾0Ï¥ºbË\Ðã9¡Ó¯Ì…ýžà¾¢0¡rýk‚‡^ÍDK¤Ò}sâzñ ®¹v²ö9QEÜâéô€‡öÊ¥ôÍü—¬Òl^çGQ°ûŠZŠÓÞè«Õš>cöÈ&ZŽ Öôq¶øÊƒuø¸ó¯šïÕÜ! 2š‚àMN†UQƒEùø$æØ²æáø{‘¶w®Å½ºýF‰G³+ÇR(âåѦÿßáßû§Ð1¼€~ú!þa©Ï„…tF+–·dysT0,C”ñÞB[@{¢³‘ûijë¥kw±)ô:>ƒ°É¢/Øjˆ/2Q x›½âH\K”Ú¦tÆ`„¬ê¬þ(ÆþD§ß×ÕÜ|Ñ/Žˆ§üƒ™QáÎ)Cú”Mu pª4 ÌÀžbÈÔ +²KÍuA¢šýÀKœ8Zÿñs‰¡ƒ´ÄÑb@l/« ‘ÉZfM†$߈ÓDr{{€ÇbY›X¢bbWE•õÃÖA);º÷W? Ï×᤼)Ô€QhÕâ Ò›öý€ûGÔ0ße#ñz®Cš½QÇOÅ#zSu2%tè1Æ 7rý€lÚ°Ôï×ò¿b-®ß9é!€ùiãŽÞ^¾r6w ó‹…Kæ->»o7§óÚ]Õùxkù‹¿ëÆ]Ûpã5*5ìf7²# h}~"©ËºïIüÖÒˆ^ÃÃÆufÿTzÄmúDëG ÿ€ZåÒì˶¥’ÝI®ÙÒ§¹£vïÑÝó·’Ìui2k†n~É~æ°$+åg\<®Êë-³Ú¡s…YFö§à^­ØÑ~hs–Ò*QE00JèEp`¼* f²¥_ŠU)G²+aöÝ-æ7k²c“¨‚j]_P»ÆŽùÍ<¤þàgÆ9-ùX“Ê_µÚ)‡Û½Úܵ|ßà´«hú8¿Ô­ÁéMQ.ùúVUŸZ¾ÌQtX5µiGøå%—'UsOix?ª„÷Õ˜9MçkçS>L¯g4h¨t_Irç``n¹|šª¹H °­[å3ã'0µ|Wq“ÇeMúœ5+œ’°‚>PfL³„HyI›“”Í[û¾…ÕÊ€og»Yîº<Æ«pKuÇ_I¼U"øXKW¹H]¨«ºù­Ïëñ‚­Ÿ*¾ßO\N3ì´êñçg*8;]›»ýZê*Kù¼œw!#Bž„'àã÷‡ÑQwÝb„_4Þ|}ÁîÕÚAYŒ#Mÿ¿ÁÿÁŸ@ÿÕô„ÂÿôCü£Rp(Ý9ËÞ÷.øš_žSÖþ€ÐI< ç4Ĺ{‘1n†ûy &hþ6…×hA’£ªÚ ;žÎ»NjÙï¾Ô¯~È' ßçbLÙ±a¡L;“¢~ 8eD5òÙ ƒºµD÷ùKL Õ%Å|µ[þL½aÖa¢”1kñø8ýªoÚºr¯}pµµ¨ˆ_–¸Èærçw¯))®ÄFúÚë ¼ï7ïÊ’—‚Jî»ÌåzXà½ñî°\ÎÄ»ýqø¥€|2=%+!n–ÕºÒå Ðìxµ'ë[Ãpo-/JšÎ –«—@'˜¾ùž=ÝY|Äÿýt0çÕ>¬Øëƒa”‚_LÝè•nHÏ=xj]îwr&Iž†œ òîf¢$ËŒ¾Dö|%ûuñd¼š›Ã²©#»ÿè›w#K+ß¼Ï1¼Ä÷®‹M%ð#?WÑ›Îh (àš—t=ž£¬Xä½]†#ÔÃyÝ'ÛiÓ=ËcüüÓGß´Ws›XG©½âz¶HŒ_U¼Ñ¯W›áõµÒáê™êp0ïëûnº™Œ9•¥Ä{UÑõQ!3|³KÛ•ËÑIJb眼”Ž;;sÜUÇàrZµb,ª°7.wqS7M€_óòP‡òÑ Žp”¾¶-øÊOõâ­äW’ÂÔEŽg¢Úì)×gt.“\O(­°0;×§tSöˆáŸæà—cõÖ"›#Á $Û‘'oÓ>*L£ød„-Çl‘Yå& ~×íÞÿ¹úE•)~qOü;³WdïŸZ™\WÌO ¹ˆ/益*à¶<8ªéÆ7çc-–ê€ößUŽÂ~gø‚sròágGü8î¾ÜóÚîcYl7즞\8UñOÀß®´Ø³«Ë8„Ÿrck²Ï^Q7xè=å<î;}þá "Ð7D‡¿/ÐëG¯~Ê’&Îãió[–éÂݶY8òƒÉ1G„„²Î GÄ/ žx\ôØÝ ‡â„éOå:ƼÍÞѯ.¼Hiˆòr.ÝöK^;¡ö‚2ö» š€Y§øæúWÕ !«1yü7ùZOrçs¯Î)ç³R}!:§…ÿü Ó˜¯µ!™³—AŽé³O}S¾Ã)$7“O¿`†$>)°–{[bFqÓÝÃ’åqN9ÿ.ؼ×àyÒÁçyõ´7›¯ÏÔ´Ü)æHbë†=¹"í]­,Içíô0O Xß‹O~°‹üû«™ªã£Gšþÿ‚øŸ@ÿåäãÿ÷À¡T¬.ž®pÜ!‡Sí¬—‘éÁVëé¶ùXUÕÖi 1Çjý«”CS¡3Ö9oån†¯diÞf§aË~m°ÆÓ0î^ŸµëÿÀµv†‘*\áe™ÿ–È)-n›§•=É òž«¾©÷¾ßWÿËû1<×KÓÀã'}ÃÌ.~áf•‘$“`CÀ«Síª¯ë:3óÐC¢ó+¿¶â³%æ­û‚»Bh´›êáä¦ÏW=€¾BÚV'ƒœ¶§ô¼çÆ"›¶l#‡r©‚”?ÖÆàFÀÁd9SëmeY>ÚC>ótTÒº®$ï"OßnPZgÉk;ÏlÎ]v-É[KV“íô°—çæ‰3ÚåV¦ô#ë…Z|—'D¹W–ïÅq)…•,b™äV'µSßziUDÔYZ€p`(SwŒ:»ª>–.'c‚KY&Â"~äð¿8)ù<›_ÉF¦ÿA*5qþù8ޝŠ÷R´®%7X™ÜXÔ¹uÇºÚæ £cmGC–š`_YçYªJc¯² €ë¶9 ÖàÓ¾Ž)`ëEG„Æ8—4CeNÖ‘ ¯{¿¯iue{“ˆ.Æ÷v ‡ôm¥® à?ÿ[ä¬ õSŒ›v;$JRå€é¦šSõ¡JM“w>ñ˜”ÞdÆÑƒ*‡êvWrmŠz¿œ¾åûd….ß­ÍnÃã¸ï%TëŸÞ«Ïxç-°~3碼¡–ÔMr.Ï"BýRQò1‹‘@è]±àO#)ó/œ9g'=#Õ.~a‘)ÈHÀ`x)êõã^Sb¿B*y üÏT­¯vYÏòø5Ç´ë¬ÚÑDbÇm³Èº;¶æq·ÄìI%m [ü¬Ê™kB´<[©%ÔœªU1<©}äb"¯dêZºeTSZƒ9)zåÛ–Mk.GY¼_”•ÉirwOí‰ë”q˜–.©ö¬ß¢>Úôÿ þnZý·Ó¿Ç~JÙ¥ºÅóŒ|É·SïQ´®'JŸ —³?ÈTc†áð­š­ïuïHÅ'+ÎO~÷d&¾Ü5¿YýGeŸhÃV“YvÚhmñÜç«´¯ŸrÅQíúh¹r#™ž.¦„&©~%¯]œ*º.ALCK_ø•ÛA9ª.Çæ)SDª·¿~\èCþ[ÍÞÞÍéa^Í;x&“£ÍáóõùæLÕq¸lu°ã,ó ÖL3a†wE?G`Ä–]·É¼‰ñ6y~yÀ¼Ü{Ãó»þ3‘º{NX„vQ—Ñ.ªüSðÏ<®Á2V¥½m—ó¹­pHl@!´{­\k# ‚u#ÿX{„}f|ÄWåœ[“ãùómÕìØ‡ÞµÕps– ®·©ùBŠq0´ÜW/ý’Zp#ÛF⇨ÛY†çb^ ­~QÛŒ³”qµd¤Áì Ÿˆë“g°›ê4߈eK÷Ç,}1¸ºdâ·.þ£¿‡‹Ï˜‰.-qª·°k@Yáª[àùûO“:r< :Vý>ŠÌ¤K-™ÊñÐ2øÀ¬¼ãÃf:ìhäÇž{¥S;§;J,l’Æ9:—jÙ%3£­žàT|¦ç%=.Ȱ_Ý5–4—Šß\<#Þ43G4ȵâÛZ@zû©üѦÿŸðÇøÓ迟@ž`ÿ S™=±qÇG¯þPÈsô2%óþgèH–l±.>Úx$Nº3›Kå|}çt`–ò_#h1ÁÊqo>³ÝÌxõ'4÷ÝT‹€Ùgæ1–7ÖáZç,ïòfòŒÄ‹ö–o”ÉÏFwŽÜØ ºGfI½ÃRœ¬žDXFé÷Ã%섦•St™ÆO®ƒKlãH«íÍ›q¥Ú7·iö{ÍSŒëA{Íhƒ¸f¬ÝE×­î¿ÝöÇfäÌ`ËËóÊ¡ï}IRÁÿQU´öšeè¡pã[|«óYF˜%#dz•ΚùòÓUPˆè:ý¢[HÍ­7jX¯ò óÝqsú_ÚÅ×ïŠ|^Ù0\ÕMmNá-/¿>–Ù˜¬h\T§¦û¢ óHâß“b!¼MÓƒ]¤Ol¼ÃÆÖzŠè2»€aä®KäišÏëŬyUŠYÍvòƯô• v´ØYŸ½&’Â]¹{!™û|^EYÄ+`*eÔ áòH&ž);Å=l¼‰G0±ÇÈSãIIVy\ÇÙªªfaöø†"sJg¿¢ þñ‘©äK?šÙè$=oÊ‘žq2ù ¥ŸÞE9¨ÒÓZCc8ÿ\õ Q h'µ/Ö÷jg^¨†„oh+•Ã3ö©µ XW •C;Wê§52Öo¤bµ¥njVå¼Ò®.uxhó |;-*Â.®”u‡\> Máò”èäP«öƒˆK[„Ï(KRÌuYàCåJÔ‹(¸©OÓ̲I^±3ö¤ø>¾?ßQ{]Ó¿Ð,‹åJÕí)™"s)QgAÍó„VWŠÝ_çÌ-óÈŽi_×›¹´–~ùJæ>ŸÀyËbÓñi«b9®‰W–"§Ïø1±h…õÖ0$³N7|šuÎIl½5+7ž4y¤éÿ'üÿ´ú à ø÷2=OœÍV?ü|"ÚOœ¬ÅßäýÛcŠW[N©d«ÀC íŒÙØRVoEàž70ô¡M>»9œú(²—ôÖ@§óBf<ó¹ú Y»?-Ïù\Ìà F?ÆŽ«ž!XI‹ [#6­Íó’¿òÑ‹T®Å邨ð›E( ‹ylàG{Â…"ö$ž3‰5IüÂ-aOÓsüÚHÌ{F¼%bá÷SŸ¯^™Te;¹"EC=ŸöŽ 4°Z`7¶bîº)‚ ,8!ó¹?_“n˜|‘†ŽÏÆÊ…ùå¼´Ò¦íx;awÇeß'³7fßY'Gx‘â”UlŸ¸8¨åÍJÜîL£fÃ)_9€kB¨Å›£F£1§)i1ùžSçİOŸj;€¶u…Ël”"ð>-Äb"{²SçB$æË…üg™Æ›‚·¼Êâûƒîµ™(œLÓ"ía _%0ЬÒýæna)i|3e=Œ5¢à"y<@ÖN•±Á†óåv 8ð´ã4Kähæ÷È&k½!QíÓN-Ÿæ9/óÜ‹PSIhªô6s’“Ô‘ŒÒà=šø¿…‘JRhH¦ã+Û(äñ®¶½æ•äûQ¯-I·:5?ïnìPããÙ®!5Õ2p)±¸Ý]wžÕ}EØÑGžõÅ0à‚âÕäå+ÌØ3ê‚ÆC6÷d\Õ"º”ïÍ|WÌÃŒnÕ¨QaÍÆê"clDäð_¬‹ûçàO®üz²i£IÉ—mâªò9ÿúsp«7†QžÜ1Òš;t%¡>5'Ç/»;1ã\)ý1ñBË5¨@‘ªÅ¾ÑW¢[Üv3ߘ¡D™‘Ò2X:Ë"¾çÔº D©ÿle²EïÞzè”íuˆë\ÒØÐé'²<‹T%§]JNa‹×^–…vŒ©oÈQ¬Tj¥îPk^¬5yî"“Ï»Rþ÷îã̈²oNj´œÕ 9tdm3Ëê`›”Àqd ­@ÒRMÚ4–`¨m ~w`ë€Î0Ó|KÛ¢­ÍÇoJw0îëL’Ü\ID®©²4©×(aóf uWÆZ3üÛÃ…·ªyb+´7“ºrÎM²{4ÝZιwè&îÍxaÏåÓùž æ"l‹ïMÝÃ{„üIëßV¼ÃÃ[¢÷dPÓ‘ÅH˜˜tHò Àtœ«PØ4¥~ç² MËúÈL®cä‘]x>˜;ómm73N cÆ›ú+kâ2wÙÙœy€ïs5²áV¢Pãt±Dg9ò A—é*dÖn Õ³è<®¤Î+»Éu¢ú|Øe-ÅžÁ³Þh§ÂXàþ9/tæ81ïͺ´ë$ËZcB„è³7k˜)-º=‡Ïä&õð Ûc3\t#}]rv¾zkÓzR?AôÖNÒt²,ÉŽ$–تB·Ë{·J#–‚è@³°€‡Û¬uÀŽŠBß­ËJ½ÅÞ1’ ð:+ZzGÎ>9,ZÚ—¤à‡¬ò»Ï¬—¸šVZ°ÓuŒ î?«!²Qg¯©~þFÎå¦ñÐKîÆM¿\×Ò΋§±:ºW¹¯¥~ø’WújË.*ñ!fÖ=šUó« ø*åVWíb)¤°ºÚ-Ùlæ¨M" ófÙGžbú“ž|ᆱéÖ´f;AóÜ$“Å”ÀãìQÅßYEuŒôsoÙ©éûƒÁ~Bsémiav¤AŽ´ú&éˆFݹϸäa;vD?æÏŠâSx¯Èà>¸Õ˜~5ÖÝ%Ï=ØÀ’ž ÍP<È ÷šášT½c2™1–:ƒÞÀã®lëc=©’Œ“ê<ü/U6MÈÞmªnü“ð·«°úÚÑyQúV‹âý©XQ#ÃðÍ,5ª”B]'Ý..j>SÙz'¥v’”Ó½ìÔ7"ñw‘BœRÓ“eb95~¯ÎUAåÔjãÏÅÏ«<Ña~ÙĆÉ9{ó¸C¦ŒdèXÛ#ü4É¥¢ DÖg9"vØÎÊŸ”üu´ûÒä¸È®U7=õ¯!]#`Ѱ¶Ö¹¿ÓîÔúÎhõ¥1^ú#ä±¹ü7ËûØ,«¢M#.J´$€Ï £2¢×Ê›):_´Sè•mñT>ýªœhQŒ±fpὫåÃg[‡,ª‡2kExÛ¼Þ=ý+êI4yïŠ.*Eƒ¯¤0Øõ}_¬_œ0Žõ‰èxægt´é¥?-€þPBüI`¿5ù'²M=­nÏ}èü¨/=]‡¶;9ât‰2E-<¾2eÑDæƒë9Se¶E˜d­Qý–œoòöÍô+eËAgÏp®Ó2 Æ­=¼J®¤¡|²ZrkëAë©›;¹•V[lôžd"®4Ú莥‹Û6¿F^€—ªFÜÍË“ŠQb„+6[¡{]««ße0ðmÁŽâ¥÷©˜íÆÆ²”°è¬þØigõ»Íqnk&Qð|§V.ÜDíu®üÍ¥¡yÄaüÏÞ垸¸òãêh^–NYBËlÍÏ*2Í ]n¸­Wƒù6cÍt%¼ÖÑD>誧—¦½ÂÙ‘z~önâø¹@Õ²– Ò±9è8Ž@Ø¥1§¹iy §Æøw»oÁ$©e¤- ;Ï.áo ×d»ÜЛ‡÷S¯c$ÉäbMçJ.€^á©®õŽùÜX:¥R{Cpm°Á=ð)Ž–z{|ÂÕôšä‡‘’¡¯ÖÊðœpGj ¹o` 0…”5êr¨¹iߤ¨î™²¥9ÁýX*¤Ñ†]°ôû×ä…ºÖ(ò¸Ìí’{-ýº§¿KM§]2äÚæÀ¬ó³Î~Æ5*BÙ%öÚ1>¢*úè>0q †âÒròÁEb\ÏêNKÂòL髽DMRN@ìåŽ'ד’…5d2Þ½çMöðìž:utñŸ ?™àœë–ÎÊ2,àÌz î/ï“G (_¿rú±•„ÕÈý{Çä)`î´w¶ ú£ºË²QbÊþ¥üé8t9ãoOÝkLµb1¼È/Ñu¶øFÌêƒi`êŠUwqCCºlîhGç§r]ûæó;ÿ,ü_ èŒÌ'S[–ïÐ\Íí hÄïÒ†)皟<Ó›¬T~Â;n›ÅµÐYd\-µ”˜„€ªàzcCùH}§î³JØ`ÏDR@ÔV–v!õ úþéÞù*éO±=î JŸ!gyqJ¡Úre€šô¢ŸÆûŒµwúJV wm^qæûÓ,`?.½ùEû ôÛ?%£µÉ;ÂØ7ßÞÉ=Å9mmv¼Êo\ú%ظ–Qò-ãõ A¹ÂfJyÐùÌuZáoŸ6ŒN¶Y?Ä¥W‹–šáYñ³"~kU/¼m\ zÚ¥ “žêœít­JÔZ¢5ÒÂg ÐI÷‡Ï´e3üôhäÙŽ6ý£ðýÓè¥ÿ$0"ÕÁæ nPˆOÙ«'Ú}ètÇÖyÂGŽ[;9y)t|Ó‡o;Ž—!q.×j§›FMåÏ˨»é޳³OÝp0[!ì˜È‹o¸^§RâEæ4ì0‰’H£9 ]Õ*\J¢Ö´ÉÎÓoÛ|IyoÇ(q/s,€Ì´Ž%b„bI}‹lÑ#w¼W°9ßÇàÞ”;1g¶5±¸ ‡Ü;wöù°lfv„ôvFÇ srïÒŒ1ý¶—X>ØÇb^1Rt~™ò"%]Øæ!4¢.XdÒc˜Ç‹—_•~zÙŒÄæ£%q§úè{3¬×ößýŽÏäwm02¼vðzÊUƒyB©û½*'Ù´µ)‰‘‚ž·Þ)%Ÿ/c¶ï©ø~3Ùé²-g7. yU:â< *—ãæ²ÑìN`Ýdc½Ä~Žx*|Ël>ðuàÓí Þ'ÔÁ pž1v.álõ›µêµ éÒ¼ÈPO]“n_Ý“%3ŠÇ’„U¡wä—e‚™Çb~. (ìé/}Æ/ŠäŽYÌÊ,PŸúéñ÷0Šf#]&¢Mj:èO˜(s(ô ‡ùJ˜†:ÊÐÝ‹Q€|ˆ}‡ÓÑÍ4/Ó±Zm9mmº*éÛJÐÅá<É_ ™´:{ÝßQ“f±7† ~±Ò¸ÁRÏ1_‚Œ–+ø°7ºoôŠÃë–ᬹr½x³ Ê‹ål•.9–Ù…¼÷,‚Ÿt%Þ>Mˆ+ ­ÁÒ™øj=;¨=îÛDDr±©Èò~Šº€–D© 3õ^LÌù4Ñ++–¸SÁÃb—R‡{ÙõRÌ¿š> JÀ'HW-õ ©&ný~Ñ!¯~.*¬~‡è|h9À][Œ‡–ß2ùJó{Ù^_ÿ+·²X;®ê1ǹ’órQ¨~_:%ÔàK׬ÕÛ³hô*äÛèMz¥Ñ^õ#MÿHüËÿ´úƒéßÿÑæIYó‰Ÿ(l“§ñŸÊ×z‘¿üÏ¼ï ¾Xbø¢°Zã4œXÌ6ì8±Uîê ÿVŸêªøùì„.å±g¦ßXbé‡8:¿S\Ip™g°|ºâO4ëÖuÂt¢q!dœþyF.¶ý\£!Äf™Ï™ðú‡N|lMéMÿs‡ôÕ’Ê•pqP-=|­PRBêÓ°YMñUƒêO݉gبP‹¼Y”c„®òwÓjÒG=È^zJ< Szm·¦|•ßJMgìmŠû—éZ–#[Ãò­:¶³ËQrØÖî7 p<º\è‹ô—Ø.KwºâøÁ{—ô2%¡‡ß`®ôæµ;,k!¥^Ôh¨•u׬Ïiè†É/U‰?ý<õÁŒ¼Wg 2ÍWÇêÍøñÃHbà{O3Q™Ë¬ˆI¨]× åmRf ù…h})é†+;ß>ÙäöLÜ·¨+™ø|©.mrí=ü=ùÚQ_ÚmÈäUŠFâOºîÝ[Ÿdò+ ¬I’¾ÎŒÉyó*%%KâA„ºGûsLŒ±¬oÞãõöŲKÌ"Ës\4ÀÑXçmmŒ¯=}OÏÈþuðE¸ôyÒîÃÄÌW5:†¾\½€­»#}þ••ŠF5‹f¡ÐØß²â‘Qÿ¤iöÁÇC1YT~Áæ\ŸSí¹•6¬Øç›yécm®âÚiü+ÄK?ÔŒŸœ¡z¼ {î|õL¢²Dàd<»ÒìµÖËÔ*X4‹¬ÎÁ*ɱƒÖwFßøw+U‹A‚Ú¼Zx›X—Ù´ªfô˜’}Ûd.¯ë†óyX×yLpûúê Sâ¥JéÔ|¼i<¬z¾×ÿiøÇÒ®F.-–«wMŠ&àn –ìâ9O›¾ÐT }ß(wk9w‡cMðŠÈp ì¨þFËÔÖ¯zÞ6—£Ð,ôÜ&ˆ+3<‚Ç8O¼»ßvã6·{ʼn¬J9¸z¿VH{u‘ÐýwÊÙc8˜-I7.¯^}›O\x;Ÿ“îØÓù‘J5@õV¿ Ö¡IµDü¼ü-©åv¹V*Ãã·"èÛ«å–§Ï1Ø¿Æ99úKîÛýËš›aW<%<󕚟àë™5yÈ~j‹–S”—Ô'E7…°¯bJ.ÆÁ|bEQ=âá•ÚÔ” KÒOœH³#?Jªl|]­{Gj›« ±‹.Ž®ë x|´éÿ±?-€þÏx÷ß¿Žþ¿K>ˆÚ_0j©@@(zP ïkI è~%ä§94=ìã솴¡ ;\ñká7ß 8 äG©m`èïz£?A0ô7€»sT vЄÊAî¨k è:(äPŽxÈAÍ¡aÈ äéïûÓÀÝ #ÂIàÃuÈ&"¶»x(r7‚``Þ}øîâBa`ä #Ö ƒÈßm@öFþânD3 ‚Á ˆwý ˆŸ…@Ñ9UBüƒ‚þˆÒîû{ùûí~jÞÍP8 ààïåX5ôÓƒÁÄR€wñG.tw™‘  Þ âýwñÙmF@†îBu„í–<ŽC†^0hFÈGÐî" ¾B÷²]üCþþžpôÎ<´ÉwÑB}ë…¢7*²ŒÀ†xZ(zÃÀ°½]¾û è)@Èžû%$þ@(to(j#öñGŒDB„ÂPÓA8zÁ‘ó Aý EkˆuÝ‚!–Œx+$þ° ÃãÐO‚‚r 0àn´éÿ?â.Âí-â¿é7Éç0O?à¸ÀÝ·Çô±ÿ_˜þO¥]¢Ù²7%ÈË-ÜúóðSïŠ!è_ùÿþ'ö—z0 u ò‡nþbÉ|\½#I䛿ÿ!Ê?Ä<óýM5*ïSÔa®ÂᇾÊvŸÚ CÑ+’²Ñ’ìõEðJ”PFdD¥gl  )|PÔ½Ë4üìÕ{—¼Á$ö¥ûa9¿»¶¨È‡!}‘Ýp¤dÛeG`D tOšCP¢‰?j-ö[€H9DpXÀ.2h´Ð}@04³…‚=aþPôKd@€/’›ï) ûºÖîWˆ èOâïíç =$3|Q_}Ñ2µSQEäf†Âà{;|w½Ð»yWÆ"µ0ª?ªŒR@@ %¯ÁûÂäåúé}Í-Ü‘ò…?J‘Bô†@‘r)É÷Ú}0êWÑø#u1üðï£59d»Ú ‚¿ûѦÿÿ€ÿÿÈ¿.€¿M>‡89äÀHCè³¾hnþ¿1ÿ €Ðg÷Ûµ”ÀÁ°ŸØò/¤¥ñ Ûÿ«øéäãá@Ç¿òÿßÕ½C|a?5Ýúÿa–ð/ðA¾ÿaýÿ€Ü½!û‡¨ ô=¥ Aö^nѾ(Bߣ}‰ƒ€»&Ð/tî³kI€Qb Õ r˜ XÓ®qöÙeP } Ýgw ÐÞw°·JæíÎê „ïH-`×@Gÿ$ D¯7ß”L9 ¤LCÙ“ÞĆAŠT›FvÜÅO!@A-*¼‹?zyÑJd[Oç?‹¿wÚÞÛÛèüEø¾$GŠȾÍ€ìí”ù>ÐKº_:höù‘² ‚p fÛÅ?Ž,¡d8âÕÁðCÓ"ðGÔ#]+h¥ LXÚ‹€\$0Hu?òi©s`(šÉƒ‘΂=ßJy:ømúÿ[ü„üÿWøÛäƒÜ•¨t˜ýC>¢ŸY÷Ϣ⯕ (ðg.Òýû³ ÷—Â®Ú û•ÿÿ^ì}õq¸ÿûfôhìpÀË.2¾g± swß¿õÿ!s0â =Ts¨£(úýïñO¤GïwFÀ4)­ÅïYˆ`”Ö4PtŽæ owâP´ E÷C>™WÀOÄ¿?Œ¶Ð"e€<}}QVÜžPÚ5 üíïÃ÷|ÂHìáë·Çá|Wì M*±Ê(¿ÊÈGùû¡€@°=çþÞ]4'‡ìg»­Ã?Œ¿Ô =,ȨÍí{`ó£}ô¨ F¼0Ò9ƒ\IÔ¸=|àࣖ¹¬»‡Šèð>.wýa?k =¥líâƒCëû-HÁ~0dž=ü÷íÕAG~Ö Ð1ÀÛ.ôHÓÿßáDäÿ¿Àß$ŸŸ™þ~¹Kˆ`ÓÿÚüCn;”GoÏýëíæ÷wÌ}oZü ?ÿ Gߣ@`(‚ÏüjðýN ìWBî®ðrÞÿê÷SŽà0Ø¡@ó©ûxÁ ‡Â~¶«–á?3ÔTv!»ìåF»ùö¬Tä´ï„€¼ÐÀŸ€û¼ŒˆþùÂ|1ú½HnòkÐe&!ûìr@¿½¯ÈôC°GÐÑÁß3ÂiŸ¡ýÿî~ñÿ#ÅõÞ)(" Œô¡¢,ýC§'øï¹ö £»¦!CØËP<Ý.ðOãïó?,@ ¤ƒÛï@¦Žî#‹(üAà}‘¶¯*ì‡êÙóÈŽ(üP¤SeW’¹„£<åhÏL@){Ò}wÈaÉþA(ÚÇA9øô´{ø£ÝÿÃ18*¢¸;múÿ=þþ£’þ=ð»äý[óoß8Áà‡Yýï¸þ/%¤GÍ‚ž _Ý¿ûÒä€Ýƒ¨0ð_DúsOœ ÉÐËû.¼kiîÕþ/ÅÈÇá¿Çàvõxô ûï¹2¦û+[@ü7’A!ñ_˜‡ÿZ‡ð6ƒÃCQ2Ò®B¾4ÂÚwBaˆ£dHɆ(þÈÓ@‡œ€@ qÀ5xÏØã(6û¢Kˆ>`@²ç@ÜÕÿŽþH(dÏÿïGltðe1íQPt°yä>Èž•µ+Ã<ƒöŽr¡ÌxמCé ÐÙ+àÏãïå–M¨MŒ<£Å0d/º|(´Q¿‹? ´w¨ïà\Jœ#ó}ã|¯„Àé1Ømz@ƒ`?ûö÷¼õèòW!(üÁ{¾î½ã~ 8ZA;ø_ ø#¦ûé¤ßácèDê(0wñ÷:Úôÿ;üŒý@þuü5yÿbóýRD{´Påÿýïqv”G QƒtÿýÜí÷ÿ‹ý·?á/œÝGš?Ÿ,ûŸ?€žŽÁwýö”`ýÿNó?”£ŒÓÚ>’-x°…¿dè÷ÿ¹ÁËùžßAˆ­ÞCöô{DLï ò „îŸú{' WüwÀ½ÒnîµDm} '̾¬Þe3»Ôçhávö@2^÷Cþúpÿþ)«}éŽÄí@Dj‘‘ø£ä‚£2ôt¨ˆÆ¡È‚§{ÙÿðùÃ÷Y”¶/¾wU—ŸcúÈy€ Ä1´Å¾@šãhÁŽv+8€¸/Jèù¸ s0**B88ä‡ò4À÷uнC†{އC~äI‚]ü‘'fóA3:„sØÿÿ‹€ÀßÿhÓÿ_ñ?Jòÿ_ à¯Éû`9Xùá"*>‡¬š5ªê¥hò„…ˆ”3{ä øÁö)ÕÛ~@÷ô' uÌÁ…ÐÄ¿Oâh;]Ú5Ðvyiòòõƒí5ƒñAÀÃß):iòB@î¾È*Ê{ŒÒmPÇ~ Ås½ ôôõßSw@Pè¡xÿŸnõ’þøCü`{ûa‚a°=yˆŠÞÑ{Fýîwß³Ëwùoÿôß~øqy`ß>J‡Øs7>°‹?ôBpø!ö|h róE^æØ]eøOÇ~òÿ£ÕtŒ}rò´ ?Úôÿ+þGÇÿJÿj?§ùÿSô÷À½…¸ ƒ£:ü•Õ®<ÔŠ¼@x@‚á¿LxÀöåöûÎÿþt DÓ,â6ð/ ÿŽÿÓ‚|Ü<"n°]ú‡À:ü$4~æ(åüp#Ø êý¹ßÏÙ®Õ‡þTv FÝ‚‚Ý‚X»ö,jEve 0àÀVØ#~ÈmxA`0äÉhdÄùÀ ¸_‚øøíÝÜ‚ úìNîãˆ2hÑ­òÿ¨àïîï‹X4þ`Øž|ÚóƒÀû7ý‘òã¯w!»øï) ½!?ÝDàp p·vôûgàïáß³âwÀ`Ð=):ˆ€‘E”ðEœj„ÁQúÁAxŠt½#nïPÝ~`9‰¿;4>B˜òˆcþ‡¼þ?]D=­òÂÅÞŠ‚ѪÂ`ßû}þȇ@â¿ } ñ¯jZ5C,ÄÇÍåhÓÿ/ø-û‚RþÕö“Ï~é÷æšÁacþ„sìî (éþûiÀ*€Ds¨b?ìûÿƒCPwÀÈÛÀ¾ßÙ}/@ÞNÐð]]ÿýΘ  Éøó] °78ùôøópØá:°; ~ð·>~RïQ$ŽƒÃP„¾ ùÏNÀÝ5öý¿ö®d¹qˆþk>Œ«&ñXÖ jqlWÙ®$‡ül€ÞÐiMrS…âCQ éa ½¾~0ˆÒJ‚“€ðŒ.W1jhûÈ_'`·@ùJÛ ±×ÜâFÃåpŸ {׬ªQz;w*êH»Ç]”?ôÀ;öžv×"ÿ&ú?ð–’üÅLA1Ÿ^å±JŒòçʽnÌNC•H0Hÿç¬Îí; ÌýÖ -7Áýöc¨§FùžÊ–ÚØ¸x“G#—ßÌà`vhúeÏÿBþ‹³ÿÎÝRjû?¯þI«Üj6èûú¨ïºí[ ½ûsý®½Qe`ÑäRÆ™Öýx=äï§eàKúÿ°Ío¯ÏÁ­‡“LÐbÀŒ.ª:u¾éά ó®R¤4øëæûGLérNÚ€à¿I2ƒk/ˆ×FXn ÌiÉÎàë™$at`$Š$­Ùy\ûÒ÷nè)ÿ÷ç`7Qþ9ÿO¹å#¶îà ØhlŠ^À$Í(i~Žì £›ºá¥  ùv=ò7#–ê£õ ôZª˜Ÿ¼nþ¸ËÍæÏY)ìË%$òÙøÞÜ f_éÈŸ Àà#ø>uIûøzÈ"3½ :á?qR†óÿÄò´~8/{þ+ù/Ðþß<µÍÚÿ™Ž/œgõЋ`»ò/¡W+÷ê^1;S_ß›õï£þ|± \üÃCL¿ùõóØù¿ÂóW³™/´W½@ÝîœÄ2®R¶sŠv«¿û“(@ÓÔœráôí\Ô3‰ôàñdéø[j²¤/úƒP‚z_ I Äެg°Pü¿ll]˜µÿÿù?FùÃâ”ÿÇ(ŒRÏ=D²È.GåDU70"Ûùnw"ˆ_¶ðÔ2¨ °¿û¸"ù#4Šw!ÐoVÙô)áØY32„_7ÿ±a7ÕQˆòG±r,ÜSÖÚˆcz#~·æF|~󔨜¤îÏ0€ª nKTT#€>ŽøvÍæ~áó_ä¿´ú?m7€6¶ÿEø—Eÿ'Õ<ìë±³úŸ²íãy¿ßkÅ«b9[ž?+§öŸÁçûŸvƒ×fÀ¶«Mx9ÿÛü*–.Ãz\gý&Y@ T]øÑ<^ÒóT÷/váÜ'Ãb|—XT¥Ør„à9]¨“€@ñ•”fÔä/Ô@†¬(Q˜Z»S€ò¶]ªüÛ(ÿ"ÿŸMŒÉù„÷á0-ÀÚÁžÇ×·/RÿVZý´‹w©Ú°áâa¸&ùoÇ„þîÝ‘ª‚ãwŠðGªô€·ß“A¶™%aýt¤S¶ù ÑÏ=Ò´ÇQ¼“ª‹íØÏà;Êòx‰m¢üx[àK̲dàŸÎÿcM ÊÿqÙóŸårËÜn0ÜfíÿœúO?aS®×¢-ÅTÅ›íæ- Ñ˜ ÿ¾>àö±/ô?PŠªÏ¨4üþr¸8 Nõî>|ŽCõÕŽ…y†SV€©ã„Êÿ¯¿B°Íö=ªG½Unü{ oA<þRZ+€½ t 7ç1hRˆ ÑhY`u¶1©6ÛNcúÅÈÿüÜ4Óü?,â3ñÈ5Ã’äÏY­ÈyGÚ°§’ïfu]òo’ü»3¾ø›ÙYWþЯàãÄîÇ`~ÇÌ<¼Faþ{ÇòO·Ñ^‚@€Dñ9© z|obhD¢”¦\ 3üƒü­^÷§Êÿël,'”äï–=ÿQþÏn©Û-6²ÿJç©ÿ=.ò5ô©#ºÑߘÑýúß:,~ÿr´úWu!ctó0 "õÉÂ6Øõêéó¹BMòå>1j ‰V™Nøbç¼RíÝßGÝ”»I=xkƒÛ¥³ª¨Û€RðˆhÄÎ͵µgÇ9Lw‰" !ˆ´„t)‚„‚€”tHJ§ôNºCR¤CT)I$QZi¤ócaœ÷}ÿúôºøÍuÎbí53kÏš{=uÏ3[ð . OÈßÅ_-%‹/‰ä=F4ÉÊKx3»?;á+à$ˆŸõYHx·PiˆoóµÕX¤=[-_åíèRÕ…€{ly‹!ä “Eî‡ì¥^+R­ÓµÁqœª³ñ±*²òÞRûð€†~Àš:HŒ¯h~´ÒPEÙE†(¼ÿq/àáúS-컬ËE·ïÏVÛNZÅRʾÑ´F e ádÌ«Õ-Ÿ)„Ôh\ê~âµV¼F%n[k³f™ÉÓ¬ò¹ãÌv\Ó§Baæ|±òcÌ>Ý›%úÛ€ªÒÒúÁkÞÁÍý8Žª¯EKÂÅ:‡Ì§oÍ„ˆ,<ð•PÞ+3…z¡çŽ2•Ý“/”ÎqìLŠääÕO¾¢ý>æOF,#¿h)®ô4‰ÊþÃ}+üCFºpã V.Gë¹’T>ŒG—©ö’¦Êµ¦i;l¿w<+^°Ù;G<O&Ò|UÕòª/…¤–:£™mxF{7kµŠÙ;Qõþm×®,IM:­Ö¯Ò¸³³Óq¾«·û1YD-¾J{×ãä•S×¢L8ä»d«¹®f³5ótá]–®²0ûé<û‹1¡b—°3¾)á¥ár&[W Ô>MÚ²ÝÛtý¡\Úü³Ïó4ÅÍŸ^·°¼ ¾sË´ÕžsI÷5ŸW¬ð¼ 6mj{d…yÒ Ç_übuˆ/ã²3s˜opõ)©žtæˆ2…7WC¼Ü ó‚ï õÜ5.P]¡Ñ›ÁÇ+È ¾ Ö¨ŒjuZŒ1‡Ö“=VÜ¿ÿ…µŸ¢Règ?ô 7ÿ;gâQãøõN öàžAáP>Ýü"ãþÕ.Piø¿‡¿¦ýÂËWŒŽ&‚߆¥Ã‡6ªO˜~2Í=Ývã™Èè-¹ï²EL›7õî¸-„_Úæ\(vê²NÜi•n™«ÙßDkTRQƒ^ìè?7ú¡Ñþ$3ô1Ï©~â‰÷¾Êa+}Ré§’·uOW>I½5±Hä›Ñ I&!fRkÅ‘î䊎‹gUò1m²äˆwû¬±õâaŽm{ìÉ–M¦¿m€þnºüüþö þf¹yÿÚµ{}Ì)Q„ú}θ¨CQÕ$ʶ|Î]‚ U«'®$ŠŸ *¾Q‰Q¶R¤g÷™`T²È;­ŒD¹ñA$®Ò2š?%GþDDD`ßnœ(åƒ9;,ñÕ,íõ!Åö@,µ;bEޱŸ= ’yò©HÑVªÔ¤¬¹ÝuòD!ÛÎÚ"W/b™=ýÀõu¹ fTÑ0rTîp¹¬Tܽ"L‘¤PfˆBIVLxV˦‹ej~.i¸¬¨Õ™¨å Ës*ÎÆ®(¾ÅϨ¡Ü‡n¼á»YÇ\‡Ÿ¦Þ-ºGeˆfؤ§V¢Ð×­€?{k6€©/se 7äÑp>s³`›e­9)Ø…¢bIá$¥ú%÷ÒùǽߠÄ!úËAÜ2µ¯"Åа\¥QC–‰±V#§-ù=·ôÅ«Xd3š¯€ÝÅÌ·‚ ‰Ÿ1û^ff²Œºîl_+ÿd#E½¦hµÆàcAȶý|¶ãTG—ŸÏ[šnZ´DÀûIŸÚZlîKèl8< á~x $f `+B}?{¶›¯D6¬ ò–N°ç»úëZÉ8OsÑâ”nñQæR¬Å³óJر~p³6m÷:wzÐyì Æƒú˜"®ü8 Á‡-¾ZÂ… å‹ùsw°Z3Ñ®ôPÅJÖ ñMç1´à,{ü ëz—|9³Š›KÜ =!O!„æ„ãošƒac®Õ~ñ,7{½@lá%(Yì¦zÔêݹ¤dÜÇbfTÑÁ¶† ‰¼E…úžzRJù䬷ù“eׯÀ'ª&óŒO@cK%K9[`ú<›÷A‘ ËÆÔ-“sZ&Ì¥´™J EŸw¤ÿ"þ¦·o~Š×ÍpI-‘&¤¶~ža›XÁK>¢äß½ìGMø„¿àVQ[D¯Í„ñøÍÏR/ ©Kí} ¢ž<+çÜL/þ&©йÒÂñ}NŽFï1Vkºdn~ …jóÕ¤8²z½O±øF¯XV¬6ÐIæÚ½ç*ÀóƒµÚ©5ÜM­Ë ¥qš÷¸ïžöÝxªÜzÛÃpžÄ¾è!^\à·ÕqeÞg ÔwÅŒŒ$î)/Y—NåçH<Ѫºâ–“½„aUzÓêÖ‡žµ%¼Yô”FqË&#‰\&áœçÌK…ôt±ý ÷ü–úéÎ2m\û*6®µ »QýÖíuáÇ—æÓ+Ê7DæŸó¢žhùwûÛèo€;(Àûoâïs?Z1Õ2üåõÅ3€É˜‚{œqív zû-£™22Ág¤Êg gãzªÙÄÙ3w"ø6^¥[¨úE‰Ð6~H(ÒšŽ|rÝ¡„p&2]«žC³5´QcÌݱÁ ߈g¸´šÃ£BùuM+NºÊëô¦‰Ú˜¶h]" ÁXÇ’ïF‹Qôuñ'¨¡|uÝ×µ¬Hó飂`‘6—Åj9")ýgìt>·Ò²T/7A÷P/¼¶.öûñ0/8½ÁåÒÌò-®+ƒ}tÆ ²+tçÔz³PÕíˆô¢¢GJ|µ|qYÿ~Ù}Ùô;³-,D×G!x•‚q”ê‹Õ;~Ø‚¹¶TFÚ(ê»ÔðL_ú|Ç3YN*™ì}¸E711AËó¦6ÜeÆ  Lw6§¯öèv_Y|£?·£ºROÁxÈ9?X½` \®?%¯p­ÿßÃ?Ñ/®e^ÜC^é sƒ§@EJ–*‘qÖMR*y(зŽ|üªOãœnf6él•ÖÃÝHúRöÇ!±^¤*™q‘ïGßËÓ’:¦wv<¹7CöÇ-ã)ê™ËÓ-šÏ{'=“ww"å×Z¦4ï<*s{>‡úÕ½ôÌæóóVl7FîܳP&h2‰ÛáWêBÑ-óº^n¤Â[¶k—u ?¢J\)ýkG]ÖµO˜=ßæä%ÞÔèëD,œë)_pÕºõœ¸ÛÀbÁìÉ ÂÄ .mOÄÆ€âÒëÓ#â³*„¥ZzIT^‘EW ¬'Ÿ¼C™D©*f„V[¹å¶ œ)VÄÄ”—ù¨Ó‹{‚å¿øo ¿_<= þп=ˆ¿UvûÆô‡kiFn >Y¿Ä$³¤i½þDøÞy-)}´Æ”À¸;…Y÷*ñ7¼›5ß—ô ÍÈ®«¤°pÈ›ý¤ž«âû®§×&k5 i+3”›pžéã$5…:•Äp)?Ε· ¨¹|vqlUØq½Òdq²er„Tk¤Û4ö‰©q8ÞµÖ¾‘Ðó{Á¼tÁ,‹±ŠÑ›O´z¹ŠUe sÚ% ø¥Ñ;°n¢*‹^ïy§»ãn=±ÉÎ…ªdŒ]}LÏ6èÓf¶cè?Ç ¹7[w›À¥½G œ°â}¿ 5GÍ<vu24›UË;Í5UÛåõM&f£½³z;I±ìÓ¾*1! ¾ìiÿ‹ì|÷âŸOÄmZ_•ŠÂÔÛÆ›áÑZi.ªR\췗׆ÌÙî¨t t†®wé+ðq½lÞo¸‹¾¨nÁŒ¡Z“ñ„åæPŠ…¾ÄT+J"ï'ò þRe|öx¼ªž[MMjƒ²Ÿk'`9U¾L³†[%§š8Ûʲ©ÞÒ¯PiÀž’\ã8uÁ:\ʾ¨·fCÏœÌ!¦ PbÖÙCgC’ëË:¹ˆµYðuÕÙÌÌýUÐÓ÷qÚE%ßSµÝ®Q) RÝ ’”æ¯Y èbrê?/¾ÍÝÏé+õ]Íߣ‚Æ%4bðòçÆÞ`Ú3 &‹gãùsEß~v`Q>tÂñ—$|ˆ¥r%ì3OÅé|æ" nu­‡ÆDgõó%ï”x–^‘Û£àÿ*qZ×EŠ[Ä)¥<ÍAmJ®ÒŒ¡py+Ò-ÍRrK#ZRkSñ Ï®ß8ýÅu"I.5åg(gß'’m°3»NæšvXŒ\oõï៳/ÿƒ|LÏ¡½UJ˜ùJ.£&ûP¶ž¥Ò ³,æÞkîUÕb…3e\¢—]_ÒÏñûC?žöW”O¿ÀËT-#ñá-{¥Ÿl™¾Ù<ŠJ¾2æùÛ»Ã|ö •…¢/&øÒ†ç[rš…- Ñå——]—qÌo«Dù+N1U‹±œQš$ Âø‚óü½Oú1úQë½Q£Œä®˜Þˆøªdô´ãŠ#ÊGS³üóYŒ‰xä¤dªÝ2ÞL Céyçù§ߪ¸(ƒ¥–(ëzì§quøvï[í3rŸwý:»Øb4Ÿ"Ó®?Ľ?Îá~PZª{UCs“ÅÃrÃä"ݶΗT-?è˜O®ü³ýmô‡§¯ß Mèpd/Ô§ÊòÃUk×òHÔÎ ¥¾R´BÙ¬Z(Fº’$MºÚAÂáú­Ú|OiGE!ɨs wš¿îÖ«•pF¦ÀV‘ç7ãQ®’¸Àúžs¯TL_ Å'u}øÖ}·q2äõ•Ši.ÂàjIU¾3 Xž:­—ò”ñ@}1—š7ª¬¶eYe@šw>}v]³(jÌÄY¶IñCƒÏ:挗ׂ4¹÷vž »ÑX³ùº¤±3ŸË°@›ã’áLYðE®ò\Û±¨Q‚©›™èš¨¾#E¤×¾Røf:£Û¬ëä󠆿(|öÿ„ßåŽÇ; Ò[±®_}pp[eÏ ßm{uà>Ï%³À㨱 •—»†}\×BdBˆ7ß^'ï³X…:L?ÛpÃùÎ:êžôHh £ŽØŠ6²¢Oyõve†"Í1ß–eƒÙ,yiËù÷PçÁq„‹·Ÿ1ÌãTm~éìºbð…ôé [¤%Ø$$ñµ‚r5ÎIE½·j°T"}×EœðÑ¢¬º«>9«]‚į.dìàiBY‰¯„ú4hŒqËtß77»Yôª?Ld±¦‰Vú¢s1¸Æ(ÓtÂY jHÚ~öª­\ÒGµ”%U1íl2Myƒä;KÔÁ‚û }rœ<ƒ2=®}”UÅÞ®7»H†‡÷=ñ„ãOƒÏbË÷Åé é)6ÿo]ø³}5Ä œÊ û´Â}|‚¢Ì½æé|¬‹¦±Ì× â¸Ÿ¼ƒM¿8gr±‹œù$jÿ¾ê¦ s¬SÙ[‚Û&üP ç¥?«rW?¤0;pq¸ñßß.ÿ~YÐB¾mN±²Õu¿ØN¬Ž[‘]ò€Ä넟“”_{sCÅmÎw^5ƒ-–}²TŽ¡w”7]¸TdT&bl2DÂøX§€²ÞÉ]@ÒMrTìô™Ï!€bÖ³Ö…bÎÊ]ïq¿_˜ áÑÞ{—kâ­¦šÿ޳H«òT~WuZ;ŽjŠ\êŠ •]pò`Cã—ÙO·:&flîyÄQ¨qv4ùj¿£æ’›FQå-J ’Êw#t åMI™Ÿx›Â×7¥—‚²ãi.œtáÒå|qjk´â º† ×[ UPÓQbທ …¬+áîˆR§e‡W~lˆ²9ß0ÅêÔ)/C÷>Ý‹“Së¤ÊÛß6@ÿDºý|ÿö þJ1Áÿ,ô8ÿã{¦!";ÿ×Wt³>uÚè¶¿QyRº½ 9-˜·`B,”}$x!öG˜rÙ‹¯š$ÓψòÆóOét ¹–]p,Š!(ÝònÇ¿‘RÂs>¹÷ü^vß¼‹?t5Øû•O%þÇ{^OúÎ} â KøÎ ó|3”s­ò»³EÂn,™ ¥C ÇmÊ…·ñÔfGås_‡­ßÌœ h¤ã<ÿ¤Ù:Œ$k7ÖÇÝNÒkÓ™¾šz¡Ö–gˆÃ(ÒÚû=wk;ˆi»oU8I„Jm]én7^‚B­k?±.®}–·e¤æ— %† Šâ·òé ¤C5‡ËQôlì¹N£¶KY97ÆA¾á2’Là-‹h}úŒ©)7¾ئYCr¹x>Iû¼q–ÙZ”Š “¯¡ÁT<ÃU_”Ô¡ž¯Ù{¡´š`œ9O›|øiF<ªFØ&ô¢…ÅØãLiö%E{‹‡zùÉ{zÑ•/[ÚHOL Ò eMˆ¬jðõ^Ÿ!—Z¹Î@Šæ¦ ·LE¯‡ÊÊÔò2B¿+ =r•@rx¯m§jÝÄF²l>#ŽW±å‘ϧÞr7­DJƒN·Œñubêî JUŸpü×b³$]Ók¥ËÂ*…©hsƒü×Ãå½òÝbVi,T_`?í»m©”‘Îh1âÿ™K2Žž2ßø%‰í©<*!•å`5õ“»ízñ8¼×M“À¾Þi¯ï«J¦bow{r”5§ ü{ø—!䟩®‡«¾Ü(˜pµú‘q‘èÞðT”š ¤ »ó†:ƶ@á^ÿã›ùv¶_â9D+î‹öÒû]§ʬ¸FLm~‰‹Ò7£}P9T½×qhåS{¿Þ´Xˆi!D)î-={ɼfñuJ¥*Ždðü‡êí‡{b¡t}ªqó,¢ìN-ùÚÙõ^µDbÏí„M$w=äQ¼´i`­]§~ݨ>Ã4û©i/-Æ«F/gð»á2®òŒ§ª+ëHÔw_=3¼j÷ýŒ+¾–¥fÔX¬‘ÒT¾ðY­pû]|³\Vñº>Ïk/ŒkÞR$ ]Ân£ aîd•|5Þ~{ÌðßgC‰DËB(a=÷Ý“)ÿ]Ûý#à>‘i+߉å M„x‰ôr¯Æ´x*QúÎ>¿ƒË`î½7ôÁMY!P}ر~töjÖ¹ïsŸÊö‚¸˜âr>Þ•±2&uﳫ˜ksÜÓø¸¡ZÛ58½®bû¢<üÉ)6&­ù$+k©J¨‹íXáv­5º§W³­CЯwö1ñÖaC)ùŠ"Î7í…\Å./n¡ñ_ÊÕ¡“\µßVn~ü­±¬‚xµÑH’»!¥ºÍñ¦{7™UTäEÄJò’’€|½Ú ©›÷nË~ë¹)è¹€…ý–UR‡¡m‹ŠŒ—`+P¼ãQ#±*!(œªg¶ùf‘2³ÏóÁº…ÆÆKÏPZÛ„»¾pò¬Ý¾á$ý.5IU¤Œkñ ¯PHf -c=בÔx÷°Ö£ô4ˆ2Ë6õ¯È¹•óù­8„7¿ã;%ÓÊ}ôá] 'dŸ€ësŒ”i+I ~„¶š‡j ÙÙãÃv•>YoX#åy0¤¶¦ä€_æ¨Ë1ëîTM¼¿!éñ¬¥E;0¦kÇ5¶ÚVéÖB„ÄÕ—ï1ú&"ŠGÓ~(Ôd8µf]`º—NBÜÔüv0ËôG1¸Ú;ðüô w÷³'ŸÞ< CO3Ûf—ßòyŽñÍÎŒ5E€Šf“½r&Ý3qëžÉ„Ó¹7óñX¡‘Z C4W¶Ý¯¿­.7¾É8c!œ|Âñ'â—´As*fzù˜¨ôL#“0õü Oàg]aúQ\]n/Áò8wHªËÇå`ÆÜ¶ofyB/ÌKè¼.‰ tûmI¼'¸?Ç íÛ[`¤¡"ê>å²ÃÌéû¦ŽËÌtÜ¡ûmå?‡ÿæüOÝ-X˜”“çbm ¼Ö%ðôcòžM:³<þË_¦éÍV€M5-.Òô£:Q?F¿ŸÆttœ‘¬r&·y)7Îj‘-J·øm‘„˳¦%4¹`Zk25*æûŒn/U±Œ5ÕWë½}m¥¾•±NdáE’s#¢ëxÖÞm›Ÿ’æŸJÔ`]ŽCí ‘{'~þt›¤I†½€ñÛšÒŠˆ+XË­Ë› ¥edî/óÖZõ—äÙÛ“”Šý,kÆVuÓœ>GÅEÍMF£É'ƒµy;‘^txO¡‡¦Ô^+ŠXa¹Ô»öÎ^R^f)ŠFë.¹«bѰ˹l" b®ÅÖ»a'QþOfÔû§âáá}Óz1™Î ;¶¶”²_‚ÐlR[M-]äÉX\Mž”J“8¸‘-BÃRÇdId=ÜdÞPö¤ OåÝ”'zÓˆ!εZ;& Þ]שAÒðÇ*sªÃÙ¶“…/¥\QZ$=_\”Ó½iy^.êÝZéĶŽåm0Ù²Wÿ€ýLÅØð›àÃûßZìVFÉ„gä?Í›ùz7q²±åPÕ¡Tl%ßÀh“xì|Uò-Ý®°€i£ÍÆŠñöc#÷ůnõŒï$  y¦U|O~$r;˼üb°ãPŸ9Wìº\&t±$§ UÕ¥ Çâzï-3;õ÷@þÖìÕo7ñã¼¼– ]°•.]»ûÞªÿ ‰yЮRìÛYÎwcÉiÀc¾ïïFI$|Õß–í¬,ß±®µ{&pwÓ^Ÿ!|½ ß¹{%ZÈ+Áè¨&%¾²Ø«¶þ˜MÏlK¼Ûe]¨oèѦÌDÐG)¦¥³"Šq2|,ªn×CŒÑÔÛHJüUÁaZZ28c+úɺ|Ë—¥ôò÷BuŒGðž¿À3ËŠ˜(0´Òlﺭiû½Ôœ”â+óƤv2oaU™ùÕ`E£sƒ>ç ípgîÓÒá«7æ­f¬A©äIlìxés™ì匒YúV9âœõô{ûC39ŠNm»P®Ý ›²-âÿ°-¸àùDbÁõ‚hkÎp›9æé¬ëÙ'ÿžž´æäÜAòQ®©”† óâ Ê™cQºË¡{rêf!1 ·wÓKÝSIæð3eÏâºL\'ŠÙ"àOÃzŒ¢–OÔaûÝhäY<•»U:Åø­€f4æ'Ã[ã—ey(´þ9ü/É!Ψh©˜|ÄÐzµ¬£"Êds YsÄ­Z<Ö…ÜtíWzÌ;ê²ï¿žzɳÇïòXÜó¹T£%—ÆJü+á÷Šq·ky‚ý™¼)0K_p¼þý“8)‹}gû$À·s·_ú꽄z`O•: b˸K*GQÒ¾þ© ºqˆÕ[a÷:úӼ꽽e/"&'[Ù¨g5K.å)’†½º*ÞÄ.SI²¡ÿhàx …£ãu§í_fZn³½¾ßtëùrþ¹$Ö‰¦óØ¢ƒNrcM-õyé\Výî’_êe~&¹)Cˆu™¾(ɵa¹ÆÖHK>µ®c€éI•š®eãË]yåÿo §€Ü½N^€i«qÜ3"ubq‡ 2¥1wY ï´ºËÛ+ ‰+W®Pð<Žb\ÙjÜŠ§šXzôšµÌÓþkxtå=æþâ~7þVÓyc©­ jî½Ó3ç® ¡t°½TXP˜óUÃ¥{°“¿qâƒ-Æm_è™ó7ÆÉH‚öæDM.¤lGÐÝ“zº­J¸˜R|G¬ÂÍæc¡x Ãå4­É‹ËBU³`~B-nº†˜ûNhQ56;f47÷ö®\pËXj°F«»þ¤•I¨îMåÞg”PÞ§.Ëa†b'ó— .¸[›M‹®4ŸÐ$ÃH›¦^õ*«Q¼Üúî:•ïì= ×Þ>%BºSóA4Ôú:oŒ¸Ï+îh%åï+ZٔܺèIfì(Ý %©^#¤›òÉhöÁ '§f–¸À¦õPE33<Ë àrV­ÉóÙŒ«¾ŒÌ¹/~Qçî4ÏèoMgwyªâRxœn q~D©†¦²~QŠ—XØú!¿ž“žÔê)v‡CÅ[½-Lá: —ÙKgSX&SÆ]q,Hòð(Z€>:–’êeg³¿¨šcéVHez¨hóžš®ü‚@±¹Ë÷ŠM’ùöëù¢ù'\7ðÁc/õi+›$ÊP7gÏ6÷¼¤Nì’ËŽôà«t¾œ|NíÖ Ç¿´H±ÕJR¼lCIDZþÀK:¢“ }ë!¥sã”k’˜Û½¶ð¨ä N'!ñÍ›;]ßß…ŸŸx>`ý@0íº”YB RVæiºœõ§\à—ÚuâÝ»ÀEÅÓ =-T/©žË>ÿþ Çå…ülNíu<:Û² úoß±Éun×§\½©²¦ñ”¨#ŠÏo~®èîØ<3¶øIÂTªWÝÞ¦µœîÛþÝ[ªÍ¾¯ý³pÚ€ üɪ}£Xâyv§Ln¾^çÄ0.âón ¡Ùà¥Ä½¿Ä¶.3Raœò)ž"Dëò«pÕðUšµ·“ ‰:Ä*ÕLø¶5ÝÉ¡…s;ã7 ×Êä_޵㢹=Ídaœ›|ù¼Çå 3ÕS<´UR;æY#Bó‘SÅÛýÕhÂõU¶Ú“›ŒA$w¥³vSD¾ÄÓDÛ`y,?[^ñVj°!Ь ¯Â7lÜ$Çld`I>UûB/ˆM6KàI¸íß{¡ê!?~…ŸÔÇϼ<[¢›Þäô­y÷]dší„ÆÐ£¤^>ýºªJàå¯ckéœ#Ã¥1f'u«¿U ض˜!9ܰ†’u®~G0<†qÇ'÷Š“û“¡ŽÜåΙ†Åx: ©æ Ü¡ô-írö"5\¶ÄRÒ«|ñnU&ô“ç,â4<«ª«%Ì9+±Í3âLžŽãÕÚ<]Ü¥Qå…>?{·~õ+YÛÜò“‚™Žìè^§q,»ÚðØþ{(L<}ÕŸò#2j‹9†Ÿóîœ9Ã{á´öeS)dOraÑ/ªNÜ’>o‘j£þ4#ãšäˆ|êòxþuU*)Ï Žj€ õeñwÅÚøOÖ±°~·›F=Ã{—z®éfD±ÊüTú;ç+FÄ”S ôžFÅX²ºù‘_×踬:ý‘™Ý΀%±CuqõvÆnÀ¦6J§1ï›Y#‹âFæ‹õs/ÿ5üñ~’ÿ¯¯NE×yˆS¡UÍÐy!GrÎîAÓx½UßÙ/Òe"9Z—Êc4.Ä,É6Ï„²,ѪÑÙ /ùª*vŒöŒÞKË7›Ægäû\7CØŸõ¥&‡×¯=”= r¿u»Á¨‚Åyü‹ˆÐÅ;ƒŸm"VrIÅßgFÇ–!ña§J½œ™fù#ãÎÐ= ŠÉ÷Ü º¡„ìöSÊ’FE‹÷s¿œ2Äu`QH\yD£×n‚jóÔÓõÎÌk •ÜÙ‰‰Ñ!‚;Üí?Ю anøTç£ÊŸ t|§wÚºû=+pîþä£a¿|áG³ÌD{»?ã4‹zá<º!  iãY}ÁCך.lm—˜©²òïšQS|t{Ñ#E’$š«¿ÿkjæ` ­¾¡jË»T4­ê‹(Ò¦ÂYèB™m%LËmŽ®:ú9çÂû"÷æ—UÂwÉ[mZRêÇâD\xi'´¤+pF?’á”jë¦eÚmÒ&íŠxš)i“HÑ…'h߯/^-½ä¾(–1¿nAÉòZs†4{ +–¨ìò*¯GíT³×°¨ÂW¦“ [ù ù»$Ь&Ñ:±mG³†T^&TJñ…'’Œ<毦¥î»~²»g>Ò›>üÆrT¤˜Káõ«ì+a!Iò˜NE8Õ²a “ÀWó?z–f‡Çp¢n5ŒWþ5üчwL8ÓÙ¯W…‡ dXjüJèuMA;ºOåÎàÙ¹MËX{ÔÐÎ ß|FÎÉ71_©zMW {„­ÞÿZÏÆ«éHý,y2Y›-Hî|ýù]°1-·Šïçùv l,µ•ÛOϽ»…(LËx-£-ß6Œ §4–ó{Qƒ·É3µmÒéè·8P³ƒe«—,WÍoúhGÄ:ME¬u§“n6-åÁ©‹%h8bz•§»=|&SK-r.(v€k-p•²o¤œ¾à($HdJÅ ñmð«Gè€Ð*¶L¦F•¹zàý…ò§7Ëýwo>{TûŒÉÆ}ö¢ü³—èÏ …»gi¼…ÆO–üçÿmô¯õ“À2‹Ãt[¥ÚÄõ˜7¯¢ûN¾fÜõyu•F$o)”•¹/ã_äfŠì 4þ<À·<“€J’¡Cî8²/¸—cYkhøX9²L¥õóVo,¡”º0‰Ò–ßÅÑ F‹Œº¡žz¼SC.T5ãwL¼“á*æäUºìôR Ës’5þíÞV­ºŽiÒsÍ‘Q7c†ò( *vãê9Z¿®ñÓ+w20'ËÌÁ¡|9âÕ‡ÅÊ͘äš’u9û~g·>áø»N6PŸep¦(ÜŽÃp|û(Ÿ;Fðâ]Ù£±Ñ¢#õ’7NwVôUÅC7ÎÐeŸ½üìÛ4?Í =jWKÁµÂrÙKhLãJ–¯ë®ëHªÞ9ûiÏq'z©ûDæ¤|ø×ð7üMþ[‡X>e|àð3èÂj»7ñÅ(×éìvšzñù:õôíš6O¾¥¥pM®¶§YJÎ÷¬‹æ˜×3ñNÌÕ(›­.µ¨žO=Òn4}Áf\._¸'E×Wú<…}^=‰fj7Á´XpÍ›’ï.ÒŒZŽô %ŒC|Ï]yƧvõ´–´2øQ35¯Ð3:V@]'¦—%>pY©<9÷RÍnä@÷˦Ҷúüû/’Ô UjM¸OÛ»•pè7uoO½^Ì¢ûq3•‘뽎H²·Zlåµ(µ³)×ä˜xm)3u®À®)WÐ4×E¯Òr½\¨BÀs‹ ÑÖìˆEq"‚ö{ÑâzN¯‡5ôN’ü?üÛèŸ+ w¯ô“Àñëޜք/Ø‹>çX‹\PØê¶÷'ÎJõžø`O¨ùnPl6.ˆÇŸìÊóMï7fõU…¢—“âêîB-‰<+ L3°žxn^Ùˆk$;½xZ t™/.íá{)þ„ÍD eóŪ„Þ›ySkw½ëMÐt³/IÍ}]ûÑsš/ë¬oJ'ή|XMÔVŠðýI’iíM×Ýì¥ÔF{Îï±âõß}ä(Kd9™:;b„Ýœ ;eº Ät’÷>MPiG‚ÆÃÈ!ÙòMGs/ˆÀVÇZŠ #D®õô­qtíüw'H\œÆäÛ-Úä™>PÿÒ(m˜Î™H~/"Þ,mÛ€ó‰rO›ÐÌUÈó_Âæ2sW;²gD:ýüks±Bùœôës®o-ôiØì)TE(%„,DàZíZ%ñŸ-Ì é&±½Ò´iMCôÐGÝŠšàAÙ'ÚøÂ\Étr²\üÚ¯×Tvo ˆÒÌQ–_/Ìk¼œB:\5ÓDÊI“Êxá(H¡ºHNózúlÕ¹â~Ò÷£i£pf–|­ù®¼ú\¦ÜE÷–š¼d!„WzV›ÒÆéÇ5ô¸ï˜®nì1øØqt7¹Ï ½ÞÆ©°ÍÎö JK@×íYý¨©`Ù%ܳ¨½¾ºüæŠ€Ú M7ék2|#EYÏ¥¥\ŒÏf„Ô¥ˆ:o|JV<áø7ކE¸I 5É12ayÖ`  ^q7ˆE­PÊ{w6L»e¢w*[DØOhÊ<\_Ëd¤PýLiGÛëŒÖmeM*ëK6!¡w¢ï§Ðé7=ÈõýðöyQY[®šÎË ÿìßå¿O3i\&#pʸD¯9ãVip=ÁGU_‘È¥| ôÁ ù—{SbØ¢·K]EÇälÒªèZ:KLëª ¢igÛqG䄌E{ çòÕŸç8ÜÆ$å,Ë5A&·5 ¥/ÔKÊ´KplNÞ ¹ì÷Ù0vùY"vÓ‡TÍ—(OôÉŽªµ_ªL¶LÊ9—½´3‰VÄüÌ“enp3¦g†EÐGìT³½ôìíƒ@γzeY%™s¤è¤™þUÊ‘ ¯_,¾ðú©Ù¹«Õ~ÏZ%'yv…dRLý±ˆ nGÓZŠÓ6ÔéêW=À;%æ"Ùa1ÎÏÏIâ'h&âœùûÛè,÷““†­³æAx³|P°À`æËÙ(ˆŒcܾ@ Zx¦vÊ‘%Ó¹ÒûsÇ}4­ ¬Á¡å÷ÓPŠ+/^f·©®ïÅsÐ'­ÑÍq íÅ­By,–‹4ÙbÜ"®éMVÕ 'Ž ³X“—ø˜_>Óïò‰õÚèkÇ.^™ë©í)¥"ñ8Ú 3ù¨éÏw¢k0tŠAó³Û¶ÛÊ.ôcâžü Z4t_—Ë«cpk.žpüx¿.‹P›HÙíÔ‹ ìPbQ0_m|v]ôÀÙ/D|ÅÿÕ|2$lðL±?qêÂË5ψ*ä?­ø Ÿ¡æ )š8‡A`ó(RņaïëùóÆóÔ›XbJAŒ ÿ’ÿàð±¶éž*‹9ìóc¾´YbÓY†, 8W½›ñ{‡°&ï$-È ~zR¢W¹ìÃùvm°ÞaÏ8—GqV”ê˜T7¦U?8¢33ƒóí•BºNÁÅ2‚1±Ðs¾{Û+b‰…48\€V›¸Ð®ý˜õCï05â7›Ìʤ´£n×ñ™¾©4Õx.ÇΚ*ËwŽa0•QpÑÄj^–nÝ$z±ÍÐ0Sr:K+38þÞé…BAqw¯KlÉ­2ÏKù¿Yvà²3zw•7­YL7“Œ™‹„¡4Ô­riü®x½ñ €OÐ÷ÛîÚ™邸ó×FĆ5*!}'EþEþ¶ú'‹—;$àdì¤×P¿?Vg„o^z6xƒ©{ÈXµñK«…æ¹MÝËìI‘øçÂÞíÈSÌç«·?¬Kh$´n¶ÂXÝŽ`Skž…à]šÜ9c)ôtMÑ"h ã]|ÌØ V¸9ùhòÕFi96žJÇ(àËÝH¶è3¼¥Û÷)+îÅ—êÃ̓·È_±Îqä„LœpüøxlUbðp}Îuq~ò£õHTM·^à—e¿Å*žÇ‘ÈÛÌ Õ—hwý~'/Îô½ûVÄbu†É¥_"W5}˜5ð9<óóKœ‚ɯ>à×ÓèZŠ´¬þ1ü£ÿ,ÿ Lݹõ*åä"ŠØr ­aí<òsóv;¥ÚLh:£œ5Ô'yvx<Ê—<2.ia·©è@sÚYØgbeO]íí å âÛÒ‰f«Ê´.ä"`w¾›¤Þ¼;¨âˆá œ)ÅoOÛ}Ký÷Nêí2éçº@N\³ÌnºŽµ*\ÖLü€/S|¾¬‘krÅLeÁ1T÷„ÍÎ~9$’”Ë÷*…½…ƒŒË^&•,¹w®Ý•E§è½|îæxÂ(‹äc±áî;’;FʃÂo/g)ºH@&}EEÖg“Ü«ët½©FE× Å§D¾Ña«ÆëA Ð\ŠL¬tv‹„ÆÍNˆüÿøÛèß,'æ_ NãfŠÞJi.øöø´ûØë»f´òhœµ-COqn”KËÑ­t/ø_àÏžùèÿæYÜUêàpt„¶e¥!¾ýxû׊Ž åw_ÄCPDÉèùs5$Ø6Ód¨P„o›˜íø_(ÐÆuž0$ÿ&:Õ鸧^ÕJ¬ jù¡c9OC6dãrÔçE·©’¾ïVÚ&±îÝc ‡ÅMw“çSm1X2˜mù„_OA,_grF\EÝÅ(rîQOj0©ÒÞ:c¶í4¯b;ѳùÎymˆ+lŠöjSsKÕ•‘¥h‘õ›ø•·"°‚ù ’wI·Ñ}U‹X¶¶/êИîZ'x47™Ók¿Wãq*N\•ƒ3 Û)ˆŸ$G·éþüºùŠSÛW=KÞÊ@¬‚á Ý©¯ó\­g£ek2FUçÄxï•­¨l:œ*uÞ–x‰ï‡ñZOg¶ñ 9ÅWü›® ³áýöiÙðùÓ¥Å;­_踫<¬1M_yÛ|‡åŽu+O´·åœ€‚Àî¢õw£ÈR§Æüùl%½þû^K÷{?ê2-†û¬~ÉñKqI‰}-ÞÅ–á)Úõ*°¸âK;Í3žµ5QLý›ÌŸD8¦Qèmô¹ÃÜèô:¾¶Ä‚ ¤j5< äØÌׇº°¸B b8mõQ”Ìù=*ÄGëhX°“B#˜]¿¤á’iá§©–­Ž¤iâJ²FMU×8_ž•q£'’5 xó„ã/¶õD:š‰¬FuSˆ;ÌGè¹W*ý•SKTâaXkãJJñÛ–*8í‚t'®ê_Áª]G%]2³ú"ùP÷Ù½{y „g_T2iœ¦î/æ±Z¸½š½£Ì¡øáoñ_òOî\Â6CmrãÌõÐþíú+wÞmNø>!ꈒó™_!›’)6fûñ½~¼Œÿ~7 g¯d^¥å™ÏÛ­?j\Åú ‹.4Çk*ÇÄ+>ì+°â'çªàĶÈø®òîÚó­§»VÆÍ^ùÞÚY¢¹¯üÕJB ¶±×²tDÒZvÚ¸I­K&ö2h7ÑfE¼±y½HÂyAv§Úµ[?ù4‡7j°f¢…(Wº…2ŠU¸ù¼†H7þ.Š W=«Tf¢mÅ‹ËiïŽ8¾Ô­wJÍrGèšRW ˆñã%á[]c€æK®Ä´ÈÔgar—,%Û˜ö •»¿{µ¥¢ª§&ÿÅØŽáDÈÿÔß6@³€`‡“`åÿ»¸zÞtl€?œ‚@§Ôrpú[õáÐÍ5Ì‚ìâ …Ÿ¾å=y½¡?„øã傸‘ä烎 ´ßåðãOµ Ÿ.aw¹‚ÀžÎžá~ÞGUÿyD vxùxﻇÀ²Y÷óá§Ï@/Ø”½C½÷§ ÚŸ7â6Ø‚ø³?… оûyPsXE¶†À§yÿèé AÖÀ¦ ‚h„ý…ý;ó„zÃÎ`ï:¢o ûôôò>áøÃý¡È9‡6NºŸD 1m`­cø#ÀÃgq€Ï?q@b ›f/( :þ=ü݃`o&|š/,lLÄÄûÃFL!E¾ï/¨1“ð‹ðêý)ƒŸí߈lts óE4ôøxï×ìhæamö@­A`(ⶇ_„äòöFÜ"ºÀ†¾3ûP?ømˆ[Áˆ1÷opÿ«`2EÜ Ç(Ѹ?Äý;"ðw=Ùòï>Ñ1+'¸8‚ü½©ïŸ,è§@¸žý¹í1ý¼¸@´þ~¨÷Oíÿóäð¾Ñ@lÄ<ÐÝHcãéê ù½üe@¼!Çuü/fàgÛà „‚v!>Ðÿ”öãÒ<@¨§G ô§J„<<ü¢àJÃÍé\ä!@„ô‚I÷qñ† èâëãý›ÜÃ[#¤ÿ~°§·7L“Àî`FÙŒPÍûÚÇÓvB~Þ¯‚j¦=›?ù°çGâ‚5@¾ÁaÄ9døøÛýƒø»xïã¿ßû@àùFƒ@Þï6Â*ÃïÂ]3„©>t†Ñvvˆ?Üá]€ø½á6 r¬øÀ“801,„c·ážŽÿoÄWÃæ øý‘n2èQ¸opà|àoë{¢åÿ¤ä¹ýg9á€ÀÝÇr4ÇMÁñÓÃlØ[³ÿžA~2Gjü ÈÃ)ÄzX €¯æ/íµøÁ•ÃpŒT¿†®Áˆß¬þ5þƒkn/d¤ùçÀï'‘vÂR<@^n¶‘AÞàãÍÿ7-°ïiƒ<¡Wþü¬`Î9P/-Š{˜øAa#ÜÄÚ‹ñõ„Bàa3ð°öx„=Ð/ÿC¹†EšûF¡óŽÔ€\+"!kõÃþ,»O8þö‚¼q("Ї µ%üQOŽ2‘¾tL°G ä ÎG :å~:Ô÷§ ¨“òïáïðð÷mÂF#& þ#Œ-Ò*Ãýþ°æ‘†ý˜ùy8†úA‘Ü7ÿ£{xAý!€8µÂByèÁÔUx¸†À¥õà39x;Ó·¸Ðã·Eºˆ‹Ï¼?¬«—«]è –ÿ“‘åö?–íxÂ4 Ÿï!‘û_áßϪ¸¯ Çìð·3 ›+"N; /ôêÿ?ã?W¿ÄyîÁÞê€NÐzôñÏfÁÿº" òr¹éü&í¿©„£ë@÷ï_ÕÂï‡cöZFCÙb¤Âú)VFºÃèHð¡V€“€`ЗqGþ Ó€.>'÷H?Â4 L>bÆáa"t`Ñá=bþ=ÝB¼ÁÇ©8ë`árìûÖ}ü#þ=üû]<ü}½c~0ôÀjaìø'{}°<ÇIÙ#mñÏîÃþô"ð?ÆèC   {`dì>\-@,Î:¢f‚!8ä%@îîÁ>Ç"8Äí`~&Àn+ˆ'@ü? 8ÎÿÃñ‡=°—‹ÃÉ•ÿÿgÿÁà“œà¹ÿ?Àà\Óý¿„ð¿ ú{øw¤½\èßîõù¥ý¡þÿ- DP€C£¬º‚hÅŸ5üÁGbô¿ò¿nø?øSPž 0è/íþG-tx¿ð¿ùÿ0±sGÀ¸vè[|À.ƒÎa²é¶?"Øb;|È£0„ £º`¿‰—ßax Ü"}|„°ï‡kGÞ?ÂÁ(CðGèåéqÒñ÷󇀸ÿع@}è tîÇróuŒõ‡̈%^ÈO ìtòú÷ð÷‚aé ðFFÑÇV€‡«ûð1#^cøȾ‘9î4ÀÌðáø|r@O¨/ÂK€]B$ ÙzðÁªÃQBÖ{ü«ÖVÀ $þ‡ á¥ìØpà¥çÿaø#× <H6ï@gÀ» I@»ô@º‘ªa_à‘‡/ôç@! †k@ߎ¿g„|µiŸF‘DÄœˆí°ÈÞÃ3¶pNá Û ªòƒXÏÎ÷ŸÃp$ÿ^ûóñ§˜ÿ§}~‡Ë°‹üÙˆp‚ŒçøÿLÀoÏÑ?Ú{áà«,È,¾£íƒ`äR á4ÂnßVàâ 9¶ÏðÀ!9Üù) à€EøƒÃ¹Áî¥xÝw:òÿÿÖÿˉLð<iyzùù>?ðOáßqUðxZ÷ÿLÿ0¸¤Û|\íÿ¶ <Þ®4žû7FTü¢÷ Adpò{cäÑÃ+Àû§k@h˜ï±˜ðxë_µ€—;|ÜÎü&õ`ÈoxÍ}÷(8£}lð ü·m@^?D5 Ÿ²ßH@ä6 /˜z<¶×ûÁ)b±±ÛçslðH ì+E02“ èévÒñ÷ ó;J@< àWþá x¹ÃØcÐþÜC²ÿ÷½€÷ïÿsø{—ŸÏáæ¿}{{ðF ‡›ÿà†|xÃð?¶e`¿%°#èD—ÆÉúá»Ô@Ç÷î%¶>ØG€t „— öpÚÇÖ=f÷ødÒ’œ:ZñÿÙ €]ÜÇžb€Ø3¸À'ÿ'ÍÞýåRžÇ]€;ÔIý_Â?D÷g|P pw õowì6¥ùSå1Cp Œ~Nû¹c øví_õþìbøÒ¶ÄÇúÜlÂ~Ýä¿´ât_ÿ#¬Œ[;jþ ø“𰊃ýªl1Œ#†‰#ø0 ¹øw ìÁFüêÈOÛ€ ºàpyï aØaZ‡Ä¡§ôHìAÇ·AG¹Ý^nà“ŽTøÀÎ#÷QÁ}ÄO˜ 8_î `÷ñG¶_Xÿ#B÷HÏ{˜ÿsø~–?ÿƒùÃü;1È·ùø h}׌H/;V º¹‡ú»€Ã-~ž`äŽû£ÅþƒTÂCp° aö^PxzÆ>þÁ¾#_ì€^úy ü[aäÄ¡WðþßÝ+èˆÿG®¸ÙŸ0ùÿñÿOåÄyÇž×>?§hýÇé­ §§~©öº òþåÚñ¾ðíßCÃã'¿\@D ` »g0rß/ô§ú?Ez°õãµ?·ù…ÿE=Ýì@AǸãÿÐ@WÄéþÈ|ŽäýWùÿée˜ÇBÀðep8qŠðô¡Çw÷öåÕÃÇû(ëöƒx?­"îK¼'‚ë;î?‘€ ï‘ðyÿ È1FÆ…ܼO8þÎûø#¸åã?ýs9øû¦Ž?Ïñ_[€w:Ú4ü×ð÷üÿÚ»¶Ý¶ ú¯}(Ðná1%r¯\Q§qâ}é×vwn;»¢œäÍ(C4-.)‹£™Ë9³þW hkÌA=>!éWÿÀM3—g,Ÿ&ù7—H¥>¿± )òÓŠAÕøÞã¼/NCþ–•¬/ò—jN§TB˜ãùÿñ9IBJN¸iÿ°-ýßÔd÷=ÛÆ<€fþ/I0ý@¾þnwsƒÑÎj¤Ò¿±¿•fæšb{îÞ„Å’-@tƒ{^§‡xûç›eà5û_ÊÀ»ñë’b7ZùÿTþÜCÛ$4{†‘ÐMœPwlIýãñs/\8…—±à‘<$Ï éã) Ha‚ó¸ñ;p$¡—CÔ6ñH‚âncI× §Ëß}=eJiZÿ„Àlþè‡Tp«¡ü1l B$T‡¨å>þ1¼7ù›ý·—c”îz!¬‘ÿ<>6ü‚{°»# ÿ°œ_ä¹ÄÁ…ª=‚ʽ19C5},+(j^Më³CPÞ¯ÊßWæ Ð)•À€ÿ€=Ü¢ œ­0NWîü,}óÙ=mIÿÆÿý¶-`Ô&Uot繉 V›Ž±¥ÚÖ´j³ûý ú»}kyµö+ð¯úB6ácº¬Ùÿ~¾à_έ”Ûü¯¾Þåµt©GëuÝûC<Ë·ÇY«>+|o †ŸÈm·.%øªA9™9=:üpNdˆØS’à úËþü8')ì Ì€Ëö’€Î,âýë^`^:·‚y»qܺüÏ¥s=ÇüBâoZû1ž=ÃÍlùv0áêÜÏ»áñ½Éß®èÿ|žË'¥fƒT„ü×AIþâ4 ü=”ø‘l§8UCäî+ g,JG„«IþsT—Ü¡~  ÄÿâÓ1 »Yþa;úÿÿ»mÉhæ1ßór¬¯V£¿zˆè§ÒT̬yJ×¶kã[qÑ€î¿ÚéñåÒü›»öÓ`”›ÀÆŒ‡ç•øüùááõzŒÍ™~¯W ÀÂIœ%m·»é×Ï5ÞEë!Ö¹?†zq,bP ?ãŽ* ˆ£ó@?Š0JEåÇ8€Z‚“Ú ™IÙ2Ì·Ûºüÿ¹ƒ´ MK²ÏYþÜæ3º°øÊ Ðצ.ùöæ—÷&ÿiMÿKZpú¯¾ä^7üÿ Ât–åÏ…‚`žækŠj²ï2Ñ´HÄBo-‡ÍzñÍäC¦ å/ þPi€~%ÿßÂB—ÿ×òtÎÿS>çéáe+ú¿•yîǶíxcý˜ÊTOûËÒ[àf€ž ðHÁºßNÿÖ@¸`ú\½­»N|ºªõºîÙýÖœ÷e` 2Çñ6þcÞ »×ËÜûüb÷+€P¼óÿ» Àþþú<«šž_fYŒ2 †è…(À¬Ø¹ã«™‘ÔTù àˆákOäóW3àÈÁG ¿u÷ËÆå?¼fó>óh†iùJ,ò'€?”(²æÌ”¿É°¿½¼3ùOëú?>s7ËôΫýúôò…ï¿ Œ·tã‡/ Ñ÷;¨{1±—’ÔÅY=`…£ÌÃ_W=_×DôÜð'Áà ¸ÉÿN7X;ü¹ý߯,÷ÃyQÿÿMæeÒ‹ºMæÜÚææpµõ»¬Ø¶šþ]‰ñBYb$éA5GÜ›wÒ?óáÓ F£K÷£ÓÓΛ“ÿ±N7 ž-àξœ$ÆÑzM{$é×K©WøÎø]øÂ8Þ²ƒÊa],¡¡).s‡úbO¬S}ÖœtPh@Ø<ü˜§Y…SFCW ë„»1_0û­Ë?~>écþ›–öpª >Ž©,Y+p5.`–¿ygò7÷ôßcK`íºº2p­Ô’áx>Ë¿ôþW‰;ý50èB%lžSÍÖ+ ÷ªAtDþ‚ laéSþß߇´ùrˆç³ü›Ðÿÿ¾é,°ˆOxœì}TU[»6--Ò) ˆ*% ÒÒH*Hˆ…” »7‚" %Ò)¢tJ*Hw(?;õœ{¿û{ÇñÓoŽábí5c¯5ŸõÖ3ß¹Åÿ§üe:<Üþ雸¿/i>³£RYM&X†˜OxÏ„.F­>åTTngÇørT;H}»½Ç†˜³ÃÇ,H¾hFϯ½jb¥µ&Êèvëja´ÏFÖM<ëgB²!Ô°°W;¾ÿ×ô <[p:>©Ï3Â1›ÁB$¤Å;•d>;ÉZïÕycÝðîÕ«ÉŸöæüøžLoš÷Ù1J5ád˜ò†› ² ÖÆª“=Ó6Þ²jE}5¼¶æ„‚÷{éО•4 lé9Ié­9ˆ áp¯ôgé›yiUâzÎGY~qt‘2Ým *á3á]à•™ûÒ>ˆÐ qÅÍîò oöÇ~¶PÓÞ;Ý…ñÚUÄ<•ÙßTaçú"Q@g“õ8ærÈœ¬„¼‹R1ZÏ0zi,Y>+§'ZÖ§4Eð‡ãŸ~þó}·ªAÇ3‚Ü/®zrœ;yÇîú“PÿŠõ¸ *ƒz‰qÜ©áQÑgX¾åØñ†^ÓHÓ?¦£Oö&fÜ`Mà…}¸®1±>cØÃBi|!î<>Í›ê_ ÿ+ÿz<’ã> à –:2:“Ü)ÕÇŒñ¬cÊn­ë—‚õ$ TÒÛܯ˜Êwˆg§|b†DÇ&Û%54ÈÓVöhZ£²­Ý~­õ3?Ÿròu z­àxîÏ‚ëÜ[ç ÇÕ“&Û(t>¦Nà¦þŸ>$‰÷Ü2,ÔM£.˜+|–3x[ºW]ÓÉ¿‚)·‘e9{)èú\»¾áË/ c¼ÇÕ%lO²ø)ßZùæÎ“–*ÿJ ÿ–8=ë†ù¸ÊwÇß'Ÿ5½ˆ%:åcï˜ñ£¢êœ eHz”U¹õ~^ذ4 Ð¨#HÀWv<ýq`Áܺu›™£59ŸËÞl…$_#¹±“ÌXç9Ÿ8i¼IjÆ’fé¼FÊi/j(~*Ž–Ç‘©˜àH†‚ÔœaÈ } ¦m–‘Sc/>P(ãWð¡ÌËòó)¨#­=¯Ü=U\ Üžsöcã‰lwêè<ÎÕ ".Œ¶9ýäÄ åe²*ÿ”ŠÄJq•þ›c…–wØä—6ªì=%îo9_}zu„Z¹õ¨:iq:#ÉÎgUë$†üÑyÛ‘"¶+ÃâFÄWMpÎ 2éæ2á…ç9»dÈq/^TÓ6w¶QÉǺ#÷Ç¿!!/Ðm©[æ|ÎÕ zt¯ˆÖò½YE»?ŠqRt³2hƒýŒ®•ºòTneae0Å~.R2Ëâ–wþ–A7Œ?P¹`IN|l¤¸ºØ®c$Ó¨&[áõƯ…?É!ÿ±kž_.ʼ ®d« w)º`Ú*ÜIP¦¢Qªø6äâ_Ã0) s>n::½P¡óìkžÀGŸ1‡èdÀ5š•Dù>Õ“¤×CiÕØœ‹éW…/Þ³\xÌ·È~Ê ³K |óøKCŠBÔ{E_Š(GÛiÙl¼GYêp¤L^¥ñ»ùMö¼1+îoLÐÈã‚I2y¥M›ÏB¬Ì9óaLè$6®ˆñ•lõóÑîÂc•¥RåÚ/'‚uS1¥²nOð†A…¬°Ô]DA¥ë];bº¶Ç¹ØM×$4¼×™¨ÜÚh‹-Ä1+äJyž|uqXÀ~˜R¼ÐÞoî>J~e¨Æ™F6tµÃ¬ÿ·—ÞÚýÊÅÅêý§oâÿ¶ô.FŠ2ú.Â_ZÉ®×Á7l¸?.ÈK¬Ûô¾]'C]v6åjÚºÇYØöI¦²ç‹ñJÇÀ95sŠ Óå÷ˆŒ:ì¿­\èŸâ*Ôµ3_VÜX–zzÔ[²M£s>[þ¨{u>‘Dîbõ-¬ûáƒç ß¿wÆ— ïv”®˜ÒÕè\SgX¶q»­ Z6Àq]s“•ºŽSk†«÷JIJÊhxønĉŽiFÞâQþ—f+¡RSå®Ñu¶mÇŸ¬”þ¤å…}« ;h´Ï~& œWH'XQp¤vþ‰ø„*>áu,ØÚƒ„×Õ×&·fG†K üQ4—>láEÎÍ×êb–ƒ•¸.Èxmú¤Ì^a,5êSÎ;g‰qý„I ­â„Õ¶ò „}àÜ”'›0›YˆâN²Ø5‹å›'?Ò½£4³êÞ°”b’þfþýÕÉ»Ôï-oóz)]fH»qKLá³M‚^èN_™i]ÜsLËɬs²vkÕ-{Ö/„÷HÞ|[Ò޼¼º¬2÷Ø×@°¡ÌPÔÓ¶Cˆ^J@ã.>$µÊ¾uEuð4Ì2“¼ó²¿Ï‡ÄƒdÑŽ“ºÒÂJǹ¯Ú—×Aß*`mK­sÚ¾`ÜÉP7¾F!à>4ûSð]Øsùå0Ò¢KwíñBÇŽJÂd-G^—™oß.|÷$Ãh£oS6¢¶H‡ªÁB.—¨;HÚ'%Ô}M¬øîéíkæqJr.n³tÜ`øÃñÿ,­ý©2ý’ÿ|$mK$qS‡a¸tÏYÿ¥8æ~¾Tùʰ.Lq2ªÎoN'¬üWd4ÙU}ÀÏRte%º~ò¦±Åí»”¯-ˆ¯˜¯®±ýZøWÿ—òßçºå[ÃøV%ôó <´7x.M¡œµÚ/âõ~]pI5WýØÝå:NÛlö%|>ÒvÅkÒ—CÜ/'Ÿü$ôöD¹÷SfWŸø¤JºFrg’#Ãà ²fxý¬¼éÞÅ­)î¾le˜þ[n2©xsYK¦“5Ý$‰.-ºYzv»´¥¾ÖË+ŸdˆE‹é®%S=ß‚š`97]k Ñþðê¡k‚,ÉËÓ¸³LP\ןÞ~›[å´Þ¸MbétÒìBL:¦EÌAeò†7|‚ëe6|p|÷$Û©˜owE…A¥©ë †ï¢X§ª˜«¹×G®›:…¥Ý¹8¤}ã-+¿¥YHлß]þÍþiôK³‹›;䟾‹ÿ˲$Ÿ7 §¿¨¶¢ D`_`ðšÆ\¾Çÿ%ïæQçq%NY§‚룎¹N-%MŒW^-{1ÔÖÑ$jr¬†Kô½c,§tž®yðõ(ÜWá´Fûûj›ØnƒÈ™¼²9O–Žš£‰²¬‘X¡¼©ãÒj$€¹B²Û½›ÖÛ:•uîÇ$gtb9¶ª}Ô-"R—ÉÕsôð™=·ãTòoΟ½ç8“­?©s²Á’@äôj§dýG‰.IËz Ú¸é‡î,Ÿ a7+J<Ÿâ9nø`\:^ny~K•C¦m»ß‰xÞŸ‡ÄCÈZ‰(¯t€7Ç—¾SólÓÚÝ û¸þÊ úz¶»ç])sÕc¸ž‰É‰}~ÔöX/QÔuöçª[ë¢=¶œM‘aSžO'*\¯‘¶;ÚpšãÁø¬|£²”ð^‰‹mXst2l9¯ËAÔÍp˜:X,§öFL®röqTÍÈ ¾!°¿ úFé_2ÁMþõ‘ã»úžP¢%LûqßñjA"ªí XTF_ƒK§Ã¡g| MèÕOÐ--ý¾]±"å^± –©ÕžˆW6Ç- k˜Ûªâ<‡åâëÜ(ÇW¥½8—>EÅðiÛ gèU5NZu¨WðÉzNbI6üümê4ÝŒîá6mšM~'Ƽ¸ðF§ÓÑoŽ lšFá,ç±üÂ<$áÙŠq>•Û1S÷%æà³‹Ï‡ˆsÅEóÍ8Š«¶Y—þpü­_¾³(¸PÈcIzÆ&c‚ø^Èzjˆ]{‰ÉW%–;ŸhŸ„Ùª˜œå½kÞ¡¬ªØJÀÏ>ñ5ò~äÒ¹üí»¢<ô a,ι¾!ésCµï~-üÏý7òOñtÅ>Kh‡Ëš!? …¸S! YTÊÃ…k8V=&Ý@SöKµÝ…iµøÊ÷ ï&¯1WǶ? HOHùj Øz0u'é¦cÍœi?Ÿï,=DyäZ½ìƒ—WY—„Za-¢N$ýæ9:}Ò’Õü§—ŒG´_sœôØLQL2—éƒ:¯=ß¹—Å«ÃÙMAñõœD=±Þ“&¶×Í.ïw`/x=ÎVIµÑêk œ¹=ï®ÿå3-)ËT‡øã•ŠöZvöœ8Ós†ù FñÔðÜ/Æ¡÷½*Hß_•m¡sŸK1uª`<ÀXéH d}3–dõ‚ÞÄ*ïbEòÜâÕ "mõSÍ¿·üÿÓè/@' ûïœðà>©Q{—¢]’v¥/žlñ:”œfO‡;j9TÝñ:ÿÕ æRûžáw½”S-Dºïò3Ü%Ä·=Ž]JŸÓÚ¹QJzõùf˜^€—qªìQ@SLJÏt>…õ$o«ÐëÍø ÷¤< û¸ö˜›%¢€•`.;\ŠÄëöµÎÓe¶»Žˆ·êx®ˆ“/Ô  cËØ¨½i¾¼$D «¬Râ}Œ­éQôšû.ñ-ïvøs-<0!C:Î’ìÓ òª·Ž?å§µ§|v–?'„NdúI¡±9ìî áõþžG³Y.sî´gæíJdNdo¾á3½TÈ|®P¬€}¿†Ž®º1¥;ýã[‡í|»×ù´,)YÒõt9[_-%ÚvèÝ5X}s“'J0-Ðÿ¤… ÙOÄd4wß7l[™›³¾i¥ëÃòĹ ü"~@à9±M5Œ»#ðÕU*Š,»fÕŠXO3“w×¹ ÷u\ñ‚šzU||˜ª‹ |’)š²Vxáa´‹jã¥éIº¼áôP‹öõæßFhî9¦ŽÀŠëÂo­Ÿ4ˆ\'¶x¸Íhæ(­–Ðtóf"½¥™]à|[(Ä÷>³RÈv* Ç ãt?Sâ¨<ÀüåùÖÏ9QgHMU]oÖß8ô‰óÕŒµòR,n«Rdœ¹0Ü¢*/0òvŒZ£‹Úi`üZú1j¶l’©çÁ™Ì#ʰ†Æ·rŠ ŠÉ˜ýþAßàF/þpüÍ=.û ˜ò*ñ¾.Ë'1R¹&'6yƒÞ'8¨oÐåE&Fæ¨jä±dÞ˜lóX¨r„ÃÑûmÙ‹¸,zÛ_»#èæfÝ?¢ž_yÌxü׿ù¿“uîœÓù¯-¨îI‡ ÝÎÃýHÙÑØ(­%êºz~J2Ö&qk(U).`F³ý|±ã‰¥žIvxuaž$%ŽàÓÇ—¡åG>RQÝ;£>?=zæÁÅ·7óOç݈Uš¹n'üE3T§]7¥Í6–G`°ô¼s¶WMF!«ƒSçλ2ºøüNñ…6¶¸,•\…®mˆô5O)`Q/“îê4\žn=^¼§1[批ßâïÄ¿UçVŸ’λ ŽìU¾pâ˜^Û0ÿï¦q˜y"Ýû^M–³Ú`*šU¶ô‡tòsŽ-W5Hž?ŵ g¶Šjzûñ͉ÆÍ¾QÍÉ ¤ú-XDXXåºX¿³üOüÓè—/®Nß7  u)þ*ƒ«[>×úÏõ&÷{›{Þ¸9S.„t™¬ˆg“P‰º1‘VãÉä1—¦IÂ>çŸ*b3Òj‰­r]/±]«n H%ùÄ­ZÀ.eÃët[oÛõö—!ýc7p¸£t-çÞ=ÚaË­m§Tz7êJÐû|†ŒC0w¶*×”S)ʼêâÞar>‘Ýh.Å/É,r¬ÇSºÊ¶XEòÍ$h’ïtzРΜWI"ÏDâR>\ü¤üx©üòôtPÇ‹dhØ¢AÃÎq—qÇÑØÆÓŹf³•ù[ÞbÙÁ䟮“8÷_Ço1šm°¹JÐ>íL$*3vët† ±ßÑÇs›¢‹c`­lʧ&˜oÂŸÕæÊ¯·ŸR¿ñŒ}Á²³Bޝ¯YèSIÛ¸¹æ›Ü».ÜëÏŽ.‚™9QjÈ(Ec*}õŸîIJ¾°ñÉU]ÔcÉ+ŠÌãn[ïÚPAK>¤‡û\AÊビO ‡c ‰4>n+Ïäxàûã¾¥†ò!G†·Ïª(~lᇮÉëø?c$z,d¶2V9Kø$äŒÎr ­´Õ©oîf½¯ñÝ=cËȨù%¿Ïs33>é)–лÌû(޾魲Ç7_çáâÉf‡EÌ\¡6¡Ü bl%¸îìO½oL0i„%!…™• 1'ÆÍá@–(ruxÏ|ÿÕ ú&ŸÓs³sk:‰êTx†éøòÜÖ¯Ù¿\‚\?1}„6ù‡ã/Éýõ\óaêɠ·,«šE®aÉtí‹G£r_«s;9JK¸fóZ¿.7ûV¥‰¬Ì_IXmm3J¶´Ñ*JMå£+h.è²Ìsmïý¥ðçýï埢žÀdO¸¤ÙÙá'ÙÌŸ7æ ĽÅvän·P”ðŸkyd×bºyÛÇ“Oq1-Ûƒ%F„Ê„Rgœ¤oÛ6Š?½VóŽï¬c¦þæ¢Í8ưìñ­#ÏI:^*:¼S£Êne1yއO”ÅEa‘Á&aþü4%¦ ÈñrœO\ÏDŸ&í‘7|ÉäÚ†=«`± âÎ Ç^$x+dÙä)y­ O»w~íŠåû2x#âÕüE‹y¶ÌÎVDšW¶Ìô³/Ûæ3¹è‰g(Sò`«)AÚ0ë@ª£Õc*E=”’„Ùú!óàà)P&¡™vüñµãøRÜŸI.÷ÙÎqÿ¾òÿñŸ6@ÿÅÙöÛ¦lŠ¥/ùâÄuÚÂ%΄oÆJ‘ßÉæXW³+»EjÖ1鯻8VŸJ3TS Ðòà˜'‹@ü’k0˜;=ý*ÏV<Ï¥ ÎEãë<× u ÛP×ç‘Óá½YéáÜu«`<[Š>p'òÓ¦rR–ΣÉ4à w¦[ ­&+«šÕ¡/@:~À¶‹„fâ’‘s& ˆ ÞÉPèªÌ¼ó`â¦ìòÖh·Ö•«\™KUý]B™Ú`giƘ“ú©¡˜Ø²VOC°L§\ 6¤›­6G{ÂQ‰6‹¹Lñ£³’ø.X!.}ã>bŽãð›—Ï5(V{験N•éBßúˆÃ2ÓOóé&ŸeÚ.ÝÀYå¿CFxJg¦3•êîk}_Š^BYÜåÕAeûÜþk æ2Ÿø„åŽf“ ?»²q²à!Ø¥«ST¤Íóó]K—k4˜66Ë%`뜣‰S(¢­U=9…)hÍ7-[ KnM‘æ%‰§Åúð‡ã g<ç©l‰¡¸âb)sÖ˜€¢ßĨºª®Ùî ÔQœÑ  Iq^¹ÈƲ4 &H¦Ì¦Qj,¨aMž¯cx8þlù—Ÿ÷_‘ÿm<Õœ\Rjÿþ­jyÇÉÚL*ò¦ kå7AzŠòEw8¶4—ú§’.àœ=¼ÇP¾RãÉ«¬å5°Ø{´1\=Ói¶Ï¦W<ËH¨¹zSô)õý$a\×_•Y®›7Bì:yë }ž.éàͧ²–ƒOª&h]ÕSÑ:GmK¿Îpd‘£‹B3>Ããhó«ažùÆlŒ ç¹Íà—ºB¶UæÎZD&!%7oÚ¼=†ÍýPÿ¼¨XèNÊ« óœÙÏ®‘´E…ët+Õ±²1‚c©oˆ ò­EU‘;× ÎÙœØêIãK[&ŽÓ uº’aÙªÌ[½¬¨vA¢55ò²ˆ‹µ'ñýßVþ þiôïP@N®în¿gÀƒ‡„zµvnøVG&A”r…› ÜGƒ¡œ,«/ÄgR³¨]'Œi%Õåßíè³#Us_ 0|Q±îA}!)ƒ´U"~#X„ÉÌï½ìàZŽ®&ƵˆyävFXšsf£jÆ›ž?JʨÈ-û1?µeBË]¯¥ôîëÇLÆëïçFR> ”«~7«Sôø)æ„ÖyÁ¶ø¯2d«Gb‡ðA«Y"§ìûZLñ®NAŸÙí‰19XSp¾¥Eµ?|¤@$FAÉÞ‰Æä•¿Wò`GŸïs“ôµÞn­™ÍëÓ0væ–ôW ”‘G&íõòñ³c~<ÛÖ;wd¤f¸f6²æ<(9Ûì‰ßðמâÈœÏf¢‹&»¶}qˆðÙU¶†ô˜ë_?Ý‹USjˆ="wŸqVöêï½r³›i ]J–ï‰éSÀ¼HÔê° #«å_wjƒ Þ[y»äÓŠa÷^OúMÝãvxþòÈ©ºt|Þg›iw$¨$ÕèúØòU9ß›{ä~á´fgÒI¸€›ç n¬V 褮æÎüâ¢* Bûv›ÍQÉ•‡Û„+Õ3LýØÇ¿ùK÷š¹aè˜]¸—t§"¸ÑØ7-³'ùÙhR-¶ñ†ÄÀÖÜImIèä|[ìG.ç‹E‡·7þy ‹4\ID#;‚†y»Ã¶f2˜ ƒjhz€xSg:>'¨ä…F2Ã:/<=&¬þ‡ãŸÚkUe)éâPàw‚‘È•*XÞã^£ˆUÖÑ;¸Y^bU= ‡—m„ØU~SR”¥¡îþ*È´rbg£—ÚèêýQ̦‡óó×Û*”H)üOüKò/M¹ ø,E…”ɬð¼_þ׬1¯&Ìê&²#uuÚ)Ïø‡ ;˜•%Ó”‰É†ÁÕBioÝEòx•n-]voÙÉ¢J ð(ЋÅi¹Gr÷Èc¥fáÐ{›—4J¯óî¨_YDV2~=n"t[þøÄ@9ÁÇüú›™t%_¹°¾¨t°=|O¢“q–;óAiô)@³G!îÜHƒA×αË;Æ\’rãv°~~¬hÇ×OZ‰2;r†3 tkÔ–D<>õÉ5±Ôdšó×M&c+xÈÔ¢tƒÀͽš½ &÷dÒGYbX££cõ^m>Vç×óÏX¦0°~õ-ºi}ÍU¢†Tá7•áÚý{ #ÈþOßÄÿEy·ª¼2¾d uÜâý;süû9Ñ#Ùá•‹@ÑW³uÂäç9×Ûî–=¦9™F œÍS}OT%2îëwX¨zÎNrT*ÊH`Ìçv;fíq)•œ#x9–ÖöëM†9"£NÇ~»‡^‘¨^txGiá}†3yÍJùØ-™R”þSáŸ0·ónßñ°y®]SQ€ûɃŠî\á’›ZG€¤ÿyæøÜG©xÑX¡g[Ý-' ·¾½`é`‰™5÷ÏKÍ¿]´ˆà8íí¦ëœˆ$~‡àë;uRûrM•Ü»ñ MÃIùÏ™a/[îé½×ãÌÁkí<è6Äe [‰úSf¨²Æ lL!<Í‚3Õ.% Ê7|óíó)zczü®›©™6TSZVÕ.¾0ø˜*Î"ȶpû\…М>]Ú® ëÝÁÖ_lÈãZ¿àdÎ'S£›8Á,d®d(Á±ej2ë,@ÚÞ'‡_œ§wÅ?ë><úNÞ0Yòµ<™ã8A—ZOd;ÑA=N«ð«8°*ÈÖéˆöòtÕÄû_3{%7 `dÙ쵯"”žuð>¾.ÍßÎ,¿]ÒñJõ!Ser½Áj›j–áQ’Ø{‰¯O쨾ǰ^/䕬<ݵ^w›CJ3ŠÒáó-ƒG–Tº2Mþv;_: èeʶ`Z{¥ÏIºVÒô‰I*F4A#ç&_)Xi¢øÃñ74;Cy]Ck©ÒpYP9[†sTº„òÞyñÙò«þ™4ð—O¾|¾ØþòkÆs º¬DÓH^QUHuçkŽ·BáïqµNÐ ¥…’&zùýJø[ý‹ò?PX+áUàZ%°Îƒå¨PÐX>¾²©hYE?&åÙš—-¡²P¢ú"ŽY9hЪXCqKŸ¬ít®:3¡éý×· ³s©ç¥\ÔŽÑkŒMÕ«Ý7.ÇïΣª Žû"p÷ú€\®¢{‘auEDUÞ+§wd:v&ä<ièt<[ìªH¨7.¼ŸŠûXe4~€ûŽÐXØø­'4Îi”÷ä|ë6$)¦EÊNf}î+hžs¬¸KQ@H,X`±`7Õ£xë¾(Fœ°{Éú\æ4Åä´"\ªbPAoÎIÐå}bA„ûÝl]7¥|£–WLb†6€ EË%ý`¯±u‰2J‹9`ÖÌçÎï#[kÿ–òêŸ6@ÿ.å7MÀ~¹ÌªË.õBô„÷Lš\Þeh£9ÎÃÍp„#CúµŸ\Èå"§V¬çÎQÚKpE¶VÄ^ _ŽW¢rŸ÷äÜ) h0Æ1ìz÷†IKuÙ™LnW¶Mž†ìpr'lù(Y}?ÿµû¬Yåíår“»½LZw*ûíIäJk¿šW/C™h7®‡<æŒZ{v1>òë<¶’}>{ÎåàËMÛj-É&LÐö.dãvÊ´ü¯ßÄVB#'Åè½´÷^q_Í× L‹= O-!ïí«ùøÁûýÔÌß›çõÎu·‹s6Ù|×ÈÜ&"nк.TXØçãÍZìÈÛúš}3Ž8åwìÊØD1)ÌæðVGÛw)âEÇâR«O<Å"&˜ øÏ|)%†¬mnÜÿð._s²Wçîs©oMô2fD4×å~è**Wš®¡ÃȤS\·»bc:ï:®SqvsâµÁà·÷›+¡D¶_¤Uï]Y^ëyRòA@Ú¶¼ÈÉ¡Éyê­{‡æ‡Ä¤¼Q—t®úEV*¹Ò\-áìäáiÐ ¬Ù‡ŽkµSrä.¶G u”Z1wŽaXÞÁæ¿‘È j²'êuö9aÓ ömôŸ({œh%Šs3ÝŠrŒµg¦ÞàÖö ʾ*ÜÙqç4ñd8$¸§c;ûØø¤er5ƒØeò=ÚÌZs{žˆ71Òª f¤ÝfÃÑÎ!ÃLÐp’Úäv,cζ|V”¡ø³ñ_ëÐ((øšN!ø^/‹Ñ_Ð@Kê¤þРוmzVž“#ª¼ÕM©%Âb m}Šr¶S¹f1°Õx¤l̳õn³ámþJø“ýËò/5A À˜ËÆÀÊqQ¬b­ y_y`²®¡Â@(Ç4=!oWÊü™wøÂ‘Zœ±…JÍö{ÇŸ:žªõá#]Ø›ÖI¸F9ä‹9ËvÜ2ÿxÄ™Í[·—äàío‚yM#§s¯¥lÅ ÒÀQ6Ï9Íl •u/ù®ÎSÈ1NûR;IŽ‰ÆµI¶È Nì·«¤o$ûêhaR}’Ë”ŽQ>Ñ9BÌ›\ìVñúàiª7Û²õÆI5‚p!™Aùœ%…;IÍÞÉa&1Ma3ñaùöàó³á›f NíÒE–—qÚS*­ +½šÓÃ63rRyRišÈ’¯UKÆnœ²®BÃE”}õw”ÿÚýÛ‹3Üã·[xàˆ'À0%yD-wÞãøåÄ^ógé+ÛÏý·b3øžŒèÙ|¨½Ÿáÿ> cµˆâÉrON­ªhÆ¢ÏNk÷³§Bw"¥(UÉûY'Jõç=_?^þÀ³ýÑ‘ð*ßxõÈ—Z®Ó,§£¦Ã1Ã¥7Ÿ€†BHæ n¤…iÙ¸cµ_‘O9  /mÏŠ°^T»¯*&~$DÙë…üôCÖ`W¼G³eÍj":M6[´Î–¬x®Ÿ äOé’ùYS§§¢FŽx¼§¼¦àÝG谔ثgÅÙd³¢ÓwZ®{€o•SpÂóxµä/6=ÄTRqºCÕJX9_Ý<{©Ä”cCýè{z;â~qÿ?ÿ³ëGZ|Ïž¸_¸€}'Xpà–À§è‹üÍ@ç!§f$EjÚZ/:î+«¼Òˆ ä"ùø.Õž œ{WƸEÝí^ôU‘‰~õ_ ÿOÿù?Ý@ñ®ÀWoðQ›lÐØyþåØÏ 72LeØ” Sra~mí+axB§¬³é6¬TÁË5'8G†±?¯õ¦^Ï Zp°—ü H2»Ìá“$ÇBLbHâå¨&›Æ?†Å~Z^ÿÖ5^϶'¥ÜÀ¨ˆ;Ž)÷%¾(=lØÂ3~¾^CÓ$w‘Zþ©Q¢ýkoÕ¯VçÌ";[v)rÉWéúÛ¼ûLL/×d’…âNwÂk!ÿùw,ÔÎgŠÓo8ÏTÖŠã™ê:‰’¶½’œ½²žîó°ô¤}ÞÝì”c£ÍßjpŠ´|&OX™”‹?ëüüE9è³I{÷S Ò|B+Îc¿Ÿüý§ пQA¤¸ÿÓ7ñ¿\ê>g¯iH±ÝÆ5ìèyDˆ­;YµbN.ü¤œUëeòFˆkàpMI7ï7™õ¬NSó4¾ï-Htß ÜU{‚#ávT4ï+¼‹© \€-xæ¢2ÆIÏv Z×ùB‰³µüÕÙ‘j˜ÔpòË¥ëªïó˜}9˜Ã'»²6p±^ªº„f¯úΔY` w§Äóª5ÎW–Eœb`OÞ"ïS8"BÀûÑþ¡çfôöUŠÌ(®³†ã)v ¶Ÿ»høHô¡æ²·9GêMì4®P¹Ýè‡Ëûa'«å5z¶ä‚“à¢.0è[\htÒѰ_»ñ#+Uêá6°†Ë/ïƒ_ÖˆWb|t;¶:§%µ5/Zµ&±óðWÂßú"ÿ…åð³ýáðkt·óÅðXd,¿PÔºW’½×ð4þú$xáë‡xÎh Õ*ñ® Üxe£y‘ýCez°šä“,Oñ0³wäÒ@¦Íuã»yŽ/™{ÔžŠ}ÑL;r½Ýiå,ÛBÿì$§H×T‹Ɖ“xüºðç ýµÊl¦Ñöj\|“d½Lo[·R(yõæ×~íOn’„Þį÷¾/ÎlPr†øEáš\’A^ªD¤ÈiB-%'aHç\CÏì©öº;-„bw…êX›gà™â fŽ:µÏ}^goå]&*êZû0YÃÜÜdäð¥lÖ(¶’Žb<ý”Ï8®†¨)Öï&ÿgÿiôoUN¿[ËnüEúb#ö %øK¤¦Ã±šûÞÛK '*¾žÒï¼.q ˆ[N ãñ¥a|ã๘¦Fᮣm·þ¦ÛBv_µ§eD!˜ÌZç{Äu**5PJ&o+h¤q£³PÁiô­5æ Ë;±¹úï>9Ÿj‰upº”½ìØ= •c ;òt‡ /º\ç¨Í8œZh½:,fCN¥Þ6W¢nvô‘ÊR%ûé8›g«É!‚©$j»Lœ¿ä+kˆÄ|â*VÒ@j`Óƒ¸‘—fJN²­ð©Æõ»\íÝ{T• 2ìéOjý¹ÒʪüÛ<GÐ8ô˜È¹ÆaoßóÇζ®xcKPD†%HXø®EІ“Yb©É@p…ô7KÄη×)Ͻª_rÕæõÙN†±S,‰œÕs&½ò<–gÌð‹… õØðÊ=…©Oà‹–Æóîë"ÉŒgz we|ËßÁ|µ„nÝ÷Š:´Û7½3ÜÄ<¤D èl¹r{4å|:Ý–ËÊ&FÑ Ðºðå•]7ñZˆþ)Ð}¬™&#/og¶R$ÒOÚ§%¿[ÍSy›Æ_e/AÍ¡7ÀP вŠTƒ–Êpw›Of½Ë8ÂY9žžF7d,kùúêÙó³Q§«Ê<…H³{_Òq#œü4Hùg*·î@Ffjž­òš®&œl[UØ´¦–yƒ’Ò|Ñ¢2Rrê³ìmǨhÆV©JVÀNõŸ?ÑKºÆ©QqÞø<áÑæ'ÒçïÔ¤˜q2‡&µ _„IÝ;&åóTæï?‘ÐëˆoÈL0…±ýj¶Ò63XU½(³å™]D§rä/„¿íÿLþŸl<®†ZøÉ¾;_aYçXµbÁðR ·.e˜„ô¨æHÏCpö)…â3ŸòÞ ’÷ ¨eL5N¼oùu;YøvœE‹†°âƒÂk>Üå'ô¶‚Í'štc©YÏŠ úxþ6üE"Ë™+g)×DÝŠRNã.~ªmŒN1©äÓTݒ¦î¶f·%pÔsI<³X/êj _|¹A¸:Ñ?úQBü¹ÑœA0±Äh§ W”£%Ôñà’Q*æepîÍEòL¿S `¡)%/µä噩Ä-·‚Uóîz]ŒßN²{Ë홎-š@¾H²nv¥ý«œ£Ëš˜F–ëÜøÊï%ÿ“ÿ´ú7+¿ÛOctç™âNMûêÁÈ¡bLºüdþ¥4½ï‡ÇïVË ‰Ljóìûݾٓ¨V ÏŸ°ó68½Èž{gáš cÀjºÚòí¤–|ãÕŠäy<;€Æ1W¼æ~-{6‘ì59MvW>IÆÇËi2·ê¶iM0Œ—qO ܲ#Ðj«É‰ãa^Ñí¾ü"©™«O/3ñ¹UHmÆ-Ü1ì*ç2Áº3žt—^ñ½ýæ3 ‚1[Ç&h•Š;&D9²íé½å¼åÔ[“ÕAÏ|\¬dëÞèbwÛàKôôDÛñh%¨ÝùŽÅàû+S=žK3x¶UhyûÜ´ñ¶Çò£):¿µ±+óÎ䟧ӖÏ3'C|¼C#E´å×3Ms|‡×-¾JuKq⨌à1 (Œ¿+pñ¸î=–"r›ÏƒöúsqCâ½éeë¦9î¥\êó˜\øZ3%Òùc+ §'õ(6èfU)¹n‰ìO_H5ʱϨ¡Ÿu¿hÝ—"1y÷ƘÞ<êäÙ3÷oT— ©˜QèH¥Åo¹$U£‹ ¾"¡Ô¨ËvõøËïG¾uÉ{þ¾õ‚>fÌÒ‡æÇ< ç5”¹-W5®CALÐNæ   åö„³Qn|Ž÷°îòO ]ƹI~û”h^Jô—˜Ôù³<7Æ` …\ oOh“qW“½ÕžgÆ‹–)£{ç}|úF–ĵ…|¦5†WÌr–g¹ÇÛÖåþpüá¡Äùa+3RÛj"ÙÜ·“‘ºÝ#³"ò/gÌD'ô˜yN¸ÅlòðH3ʺIè5^)yÌΈ+­a jcîª<9ò áßÿ?•ÿøIóÉ­ µÈaê(Œ1ÚÖ'Ò>–´-ynŠqüp9®¢Œ½µY…™‡«N/¬=°©yÓJvÆZ§† ¦ÉÝ©% ŸJ[m}Q™¥©µ]qŘ?½d_TFb¾ùº"K{æŽöëàâaÖôòëKÓYM,ýqÒPϱ4·÷OnÂínµËËJ¥ôp­¾ä¯š/OÕq±¬P Ûî† ¯¦ç©ÓÕ±ï–æŒ Øl숽ŽMª4±-S¨IË•¾ J»©°ÝÐåx±3”½ìºEe5¿©*"cÛ\íñq\\øˆ¢æ9÷¨ôáÅ£|¯ÝÄÜWrᦤÜb¯9Knœ"¾u^N®‰ ò†²S& Ï1/KÊ~*^;ƒ´SÜV´¹Ê?)›cØqÇÔÍ„æÇÿädz'yHÇ -(ozW˜4lDÑ^åãÒJœköØ1N<ÎçÑàDp…Â¥‰6±KªýF%…o\“ZæÎø ·’~û áÏô?—ÿIúç¹ç—ýxÝ.Hùtc¼Qú\©=ò4ž =pÆñXJbJ%çÁùºùÅfiü¸¯˜úíñ»1:(îP·âëÇiz úl|$U©U8=CKÜà<ö=oI°F5óWnÐëŒò·W/Y@Ä@‰‘´w^/a7æ$­±—¯‘x#ü¹äè‹«¼S~üŒlÎMu\ð®éV%¸FŠ8$šs "'' mœ!×¶nßÐgtÒâg¡Q ¹Áï>2–µø…·®Lw€’{Ê(ŸSûIE)™ÒðuÏ—n6JŸÚ´ˆ-³½5‰§ûæçMžex«yBÄc‘y‚wÔ»J"ĵfàoœõ OŠ÷Éÿæ?m€þýÊoõ“À'nŸªÎ<¥Fjóä|·>´¯Ù„Ô°©–—ĆÈ䬃ÂA#%Íç9Ö".Uç—jåãÇ^ÁFW¸I1M´Ò·‹~_úLgJxzìÆíÈåb¾øÑ}½Â‚_K“'ÇÇ7ùM¨(;V.¨x|ýS fÓx¬ÖÜúÝä<Œ\Àð9ݵ“ùë+¡ãïôƒ°Þñ1À÷/ˆ¡÷öÁ~I‚ äxmNUêGu),z²xõ ;uÎN@ƒfiD÷‹Ï†#ùƒ¹Ò' ‚h’dÃF³}ï- ¸. ]ZoñGœò¿5ì ¹240+¿½ù<ÚCÿAOÒ'-ÃÓW¡8^ÒÍ’ôœ•1y3ÅÖôTºØ’¹‹ Pßáw¥·Ì,JœדO»@îqMUOÇ]H!u¯d®Œ#þsšb6ÞÅÓ³JJS8þÌE<¼-Z8U*¸;;¯Kв;ŒžÌWŒ±x¶Õ ßœ@â6ÑÉ<.*ñ®bÒ™†X_<á±O´Ðd)ÆúÂ_ÿÛÿò/ÃDv¹/c¸hJ¥á%¥qî9øó8Ï ÐZÌ/á–šÉ¸ÞúeÛ—â§õKÆ‹ãBðS°d“úGUÆ>zwë…_qMsˆ#¿ñu,úÓëž´ßFþÿ“ÿ÷7´ûï÷ óÿ¶¸ìŸ!û CÁgb¿#è`þú¸¿A°ÝO W{˜‚j·×Úk·ÿ=ÈAÀÝ.ûÃW>Aÿ9ÛûÂA(lo”î}þ¡„À ƒ!ÿ8;yÁêˆúƒ8œ-=}áн֠ªÁGä}¨w¿²ÿùPÕ^7G« wÈîÝíž¡ ÀÁPÔ<¡ (âêîñ.@wTÃÝYFÎ â"ƒ!_OðnKÙÐÑm·ê ‘ÿ ÈÁ5È÷€ÀÀÎn½j0êû ˆvèûC Aß) Û}~W÷??øîŒ!¦ rX$2ÀÁ ŠšÍÝ.@  2TÔT£ß=8>üÅðwÝCïgù‡íÊ?†í½¾»í!è†¢ÏøCS€üˆÿnCdÄ÷¼ûi÷vÑ€wŸ‰ÿîS C ŠhBÎ b–!P$` rþð@‘ Qó˜6ú‘hýöÆÙ­€øïÂB| ÑÅÙÑŽzVäE$nHdv§ùü–ð?@þÿ÷ÿ[þ`Ïþƒ?+R€Np7è!­p ôAïÍ^Gœv-èbåïý¡áßé„l¾¿òÝÉêÝÑÙŽPçPô/~¯âiu Bi ¿u+ÎNÞÐCb þQÌAûG»:þ»Šƒj ƒ›ûÞ•#ê †A÷¯þ(ÿ»DO”IAi®]U¸¡9[ûbŽøtò#~WD+ ägÔ5Ðí #âk!{5 ”pAwÕhOì¿W»Úb_s"tÇnW„Òtÿáø[íâDzA(;ƒšO”nEá@Œñ¬ W íÖé`”JF¼:q¿þ€}pÿBþ=Ý h¯Œt÷^mÔ)r®vMþþÙ® Bâïl½‹ÿ‰GVœöF‚‘öB€‰´7ØndÏì#±@;»ø{ÃNt×-AÝ rX´ç€ò\¾ =ò–w§?ª1 @\sÙÅßs@~”½k®v–{ùÿrÙþ×ËàìÛÿC®àž†¹:¹Ãöóè†øîôû‹»rvtòuƒüTû³Žß‹Õ\!ðšÿ]t!#‹]= ‡nùCœ¸•Žêv•ôp¥³£ì`„Ÿõ?âÆìí= ïD|ït‚ºC¾»ŽR ®°½¨ùpÕ^=ÐÜ׊šàýЃACÖ)£»· ÜÝŠ NPž=„#À®EœNž*EJ7hOøw/ #„ÝàÄè Ù öÕÀÞ!T:"BêTtÌru€ÿáø;z€‘½P&é0íâêwဢ£Æ]0á°ýÖ¨Pn¯â4÷üµðß·ÿ)ÿ.0ØAÌÙ‹ôQ–9[´x@Ð6‰¿£zÐsï1H"e†¡¨÷èqC$Ĉ©…P¤Âw6ä þˆ›wº¡dŸ08°Ü{&~×{Aò ÈaPN#ÒA"ŠÄŸ @tD(wåv=Àß]þÿcÿÿ«‚v¥~ãrÿ<æAÌtxÂ~ÔÅß©ÿCáºÀÉÁã¿ ÿÊ$ÐCªøPëýÐ5@¸ÝÁèý¤÷÷õÿ÷ü/Jþ\An‡”¼‹ƒ7üÇ&{2»wÜ eÁ~П+vN`įA} TýAêi[ç@7··ç«#ýy‚®#%)› ”tƒ\ ÷BOÄô]¡0ȾB€‚\ÀnmPM„åÈ"Ú@öc~´Ø»IR¥#=$¿ò€Ž»àÏÆîëq8LD|;’2:A<ÁûÔ?tÏ!ƒ34£¢yÁ{¶yS¶ö¿þ{üÿßÉ?Ø ù1æ? ð÷h}Dÿ=sŽÂ|¸!Ò°BQ H[Œ^pB‡ÊÀÝZ$3t¬öÌ0òý}·ŽØ"ðGÌ5šÑGóhóv´öM<Ú_C#³ë4¸C,¾‹ƒ—xŸ1@áˆö@Ðk è.þ®¿·üÿÖÆí¡üîÚþvÿ©‚]ùv‚¸£tóa¥@ÿþ|èléçû¡ú/ôÿw'ÈeàƒµäýdO9£»¬<=¡è pŸÑý ;ðÝǽ«¨=˜‹£ì™>è·ß àdéãO*GgW/È÷â>Ýg´A/ξü;Y„¸APöq@¯C(Œy”uÙUCˆèèEÊì¾Ôî³|@T<ƒ^*9¹#Ý}dyˆÜ~d4à…£5÷£éÙCÚ¼¡!ðwüéø?ö£çÏ ÕÙÅk-ä2죻Ûg×Ä!Ô/¥ƒQ< ¹ v6ýµðwý Òåß͆²¡à½—úÐJ|˜àG6ÚÃÿ»†{Ôû!JÁ |0‚¿F¤Ñƒí·Fµ9pöðGrãÈ40ÊUEyÖøÿ€Ä•຋ÿ>˜{ih?•çp"Nž¿³üÿζí§üÞÀžýÿK÷ùÒ Ó¾Sÿ‡æãPöמæ::ù@ ‡Tëwãÿ!@ ô'Ú÷ǵbW+?÷ØK·ùIÿï}Ë÷úÏh nÿý òÔÿˆl&«'žèeÀÃZÀÅÙë`©ï{-€Ž4ªê] ¢¼!ËyûT…¼O#¬ ¶ïóD (•„Î@Û~X< Q4#BËBQ¹C$à>= A¥ ´$ôð:/àùÃñ·}ê ;´>ŒRÚgO(dÆEÚdЉ8E‰úÁ‡a»êGüRø~˜qð_È¿'ÿƒ˜ßrƒ‘AÿwH'4þ‡îg— #zä2µyHãŽ0š È÷­÷9‡=Z?òíCvÞÅqƒ÷ù z„Ãü?z‰ÿ=þÿïø0ø{þ•ÀéjoøûÊÿøÿÿ¾üÎÊþÿû’Wg8ä/"½ï´ùÞE«Ü †tÎ u ÈAß«ôƒ •;óUûm|ÝééCËÀßzßëñÃV„ÈÑE~BóßGŒ?»ù»½\mÝQ g‡¤ÝÕéçà}-€ÍY@¤ÄYºûÁ- ïKün Ž¢èÁ2¡ÎÕó/e­4ÀpÔzàn àâñã àO$ ÈÅŒ´³àC$àVFÇe ØÞÝ¢ö€\Ýþpü]ÝQ.ð Ýo×.Â@ßSÿ¨äq˜HÕŒ¦yÑ[ßo ý¥ðüé_É?ÀîoA[å}Êz[öcw;74þ ²KíP~&Í'€Ñ©@*w•õ^B'ì9ÎÖ~H mØ÷Óó‡ 4m°—%€`vñGe ¸Ú{Á÷ý³=7=ðÐr°µýmåÿ?öÿ_(¿qÚþé~N"HàŸ"½ïN²¹ÐÙßÈàì òc¿ˆ QBsèÊAÎö>È%Ü}»³Û ù‹†?„ƒ‡uüÞ2ðnü÷÷ü/ø» ³ÔÏ}ßÛGGŸŽÈŸ‚þQò÷. –A?^Ý=Ø9ºÚ†´À Ô2ÈÙÛ ´§ @0*9:œÚƒÔÙŠÞäŒÚÙÓà¿ @·Ýƒ@“€H] ÚO…G„ÿ(²÷`«ÐÅÉíÇßÝ×c2´¾vtw;0‡¶¢Drà^Rº·í/…?à{ôÀ#ÿ]üŠô‘Ùû®âÞ†¼CøƒöL<¹£ä€õGfì¡)ûƒÄW†´ÕÈô¿ÃÛ‘œøîé>þ@´uu¢ÒíöøÍglïg |Ÿ຋?ø0ÿF¯Öxr¨µ0tào*ÿÿ±ÿÿRùm)¤ý?,þ C.á*8BÝ÷Ötÿ*ü;h ptòC¦sƒÀýäñ¿ ÖÿÈ ´ÐCÃþ":º Öb-£rǾâþæãÞU$ ø7üïwñßÁ€ãÃLjG‡„èwÛ7=Á"V vp6 óø~ú€˜V€«Û›}œÁn(Ÿÿ§m@(aG­"r…ÝQ–ç;ðÐ6 Äí9!èÄÝø †Öth]ŒÐ6è›ßuöãÐO¸:€ÿtüŸ"šƒÐÛš# ÁEìSÿûöm4Ðøƒ%v#z;ýRøPúßË¿›Ç^¦ß¾½F>+úÍ¢sëÁ®ŽÎ~päãîN3|¿!Ú^tFoÜO,@.BPøïï ØÛ4ˆÞp€ÄÏ΃Qv‰ÿoÿ]Â?ho¿æ¡m€È×¹I…?u3?¸‡·"¾`GsßßRþÿcÿÿÅò›z(ûðüm"ÀÉŽN½:ÐÜ?ëý‹º†`´ ?ŒôsüwpBo ÿ9ýk/¶tz£#ă £ýë¸ïoô?™n„æÿ¾oºgh ‡»!E×ÅÁê)"÷h_ÄNPúý 9ºßU!4—ñSïwÚ „Ø Ú‹‘q•³ç!™F 8Bt$ŠÜ „øììÝcýúç@U€»m‘q28Aµ„ÊÝ:üó,‡mAHüa8þöO<¡è]H(vñG+Ñïx” A¨hüÑK¼È4ÁÝ©7~ü+áïúŽ/ÿÎ^¨¼ö=¯|˜6ÚÏô¹ÚÂ½ÑÆà C¿ÿû{þQ?-|£À?,ö#øï±÷û ÑÐàC¹ èÜADþbE„j¸·_pàü?’E@¤ìâoç…´ß Ãüÿþ6@èÁfT˜î¼ëþ†òÿš´ÿ£ò{. ìÿ÷îÿÏôª* à{õ¨ú õã{þ_{׶ܨD¿4UyÞJ6¶å5æ„ÛŠ+É{ò§QߦgÙQª’R!kk- Âj¦¯çô0±kôuÆ8¥–y÷Øšfv@ºn艘èx´3Þo]2_Ì@vÄûú±>mÜå+7Fû‘8ùiÕÏ ÜF‡ùûæØqAXP¾¢2Ìâ€Ñm÷\/Œ>¿­Ýí<Nëe4 ¸§˜¬;ªs:NH.²òí¡J—R-—oÉ+p¦n\þþØ·M´•=4ÞSþ™RÿAÔ7§@\â3œ†ÝÛk’¿Édñþü·‡H¹£/ÆqÚ(ó»úáØSÑþqrÆIó¿˜Ñx òiÈ?¢þ­Žð”ÿØNì<6© „.ÀÛ9—ÿgÉ?:m,R0‰øõä4@8Ù…ú±Xßü_Aû_kL ýÿØý'Ðmíö»T+,¥‹êEº¹0ܪ]Òÿï‚ÖtúX–&Û‹þ?üþÖe H§ as—ô5–;†ú”!œ%!lê€ÔêÀY’€Ö´3v(%q%yÜ$B  «ª[—ÿá¥oÄÄ“ü)b$S‘`<£®4@uqMò·¹?˜ÿí~—ÿ´§Ÿ"ýHþž’ðÜßwÒüšLxFìÉc–m³ë¨óŸŒæ}0÷'ùK˜‚ú"ôÈh^€-÷rþ{_‚ü½rR'̽6w¢n|wíÚæÿgþÿ’×ú<€úŸºÿøî¶»¾M´ÂlÓ¿m¦QѺÄ+WÿI ÉHðÙóÓó¸¨ÿÙÎÌâ>¿ˆ§›0›a\¨§#gÁ -~|;þ]°úû„Q×  úþ/Î襙áäW>E0>n;j×Ù ý#³›”F×Z3ä!Šb?aB ‘Œ•†?žáÙ}ñõìÖ߸ü¿þŽÙm°îH˜§þ# \(Ln ?ªïþ¼"ùÛËæ9ƒœŸm¨iý“ü±c˜—¢=È?DO2ò'„@ür£á “Ùøb•Aþû–]±óôùž2P¸Bdà šˆü9]ÎŒ*=Ø .m‹^×5ÿ?íÿe¯µyu¦ÆSðo¦¢ž­·û^r­IØUw¹9öm~¾çtzJ¢Ûã–ò¦‘Êi2Ø×BÿZ(<Ìög¿¦VÁ<­‹ÏL†dú?9âëbó6’²Ã`òA‹ZÀ™]„I‰ýòúÜÆi/Ž~¤¡¶ÁŒ^ˆrUÏ,ß8=ûI ½zXªâ)*6Îôrö]Ë–x @øgM‰Ii  }\ꢻqùoßöÀ21=œ§þ5Á %pÛ¨ƒà¾ü|Eò÷—Îÿê04SˬéS>üÚK-^P|Æ÷r87öšõ‡-+>ÄéFùÇÑbÎAþ4õšhçñó n©+ Å^„ó6€`YþÒ#ˆ¯8¥ žJ`Âw«šÿ]ø|]ôZ  h›e÷ÿ\&ÐÃ-aÓ¿Ûê9¦c—‘°é…æñŸnà# ëuȉ:®¾½ôÙØìˆ-S»ðŽüOÐÅg23½åG|ýàŽ§+€,¥þtÊ€q¯ß¸c—2€ÏÃ4 òôi[žòÆLà•R!»ò âŒ^¹ïdpÔ“ ànwbêßE;O ˜¥•iÕÖHÌwº›òÖåß¾öÀcùSy?Mýϰ—^ ”Q›êŠäo.Ÿÿ~¤–À i4âûlQÿÂÝò¦¿ ̆GC®ýœ¨p—@þ^Z»Ï—O/=^[\i÷KM–Íé‰mÅ»Hi€y@^;ð$ÿœ†Ð$ù&’ñONh€¥zS®hþ¯f!ûÿﵪ@©]WB>ÑU A;ÅÙx¾à :§ ¬ 2z°&iRL+ Èš½hשðm..÷›²2ð ËW怴͟®$X¶ÈÓnXÌÅ×+’õoæ‡-*â@êŒÈ?1ìpU—û49 ÈHä žªé˜€ò‡+:FÕÅÂ>ÛðzGŒC¦²W&%þ<ÿoG(¬[*ÏÈÊœ¡vPV^Åüÿê-À:Oxœì½\UKû Ò­€„ `ÐHH#Ý݈€ˆˆH÷nº P%IéFB”DB@$T¤Aº¤.;=žïï9ßï9~ãq;{ͬYkͳÞzÞ™}Ð ÿ+ÿŸ ÐèóOßħhÝM0§¢¿ºqüz«ÿ‰À¹ 5JñÛŸnX¸öµØc˜ç`Mο+·½¾iŽîmÌã™+úúR’2%t2ŸöN-‰Í†eG¡Ä§dV^"Ê•“ÀÇÞØ­÷ϧc¼Ã¯ƒV»t©| Zolšd];ÊE9äE¬øÜ$þõ\ãœßÙsÀ—uêB GîcéRÅŽ&Ó©å]=o£éõHû¢÷·Ž‡\J2NV­C^Pu+Ü" Ïr$(½7›eúáÉfPäÁØînþúú:2ÚKÝT§8êVû-Å77ý6¢Å\ÔŽ…ÎôV™ÏV:¦è1-{£ £+ýÏtµ†V圢8=úÅ›Fœ4«T(øRäjüÃ\OÜ<›i£P9oÌ ¼ýP]zפ6õÏ<Œãœü€Oêš[Ь*‘›˜£.•ÍÊ“Š.Ùñ¡õ¸‘úrscîÒfKAý:UÇ|O|³ ¹kÿdÅzôé]Ó¹Ù·¬ùÅî§ÁU…æìІû‰[>¯­©sýêü'òï§¼hŠÎ`Ö^y%óæ³yV¸@(¹…€Rv©É@£MØZç×ct·‹@µÆrqa¼¸@‚q»biãö­¬˜/¦Û§É$Ÿ›Ô¿c]}„6áŽ=ÎJ«'$úÒIž¸tªYÁjÑnMFLÚ¤såiüæ¥lFc¿±¹¾Xÿ5&¾Nìjئ´ó‚ÞÛÒMLuG§Î×°£Ç´xªøÎê©´W5í§cò)æGô—Þ.þæøûeú»W3«³ÚáÚ-4hÈOâÑI+æs3yöÈð;è»¡ÉøØúF;ûé'4 c#RuÆ4¹¡öîH﯃ÿæ_’ÿRz¯„ ³ ô*†Ñ÷[Í’m-“µŽ/pÝ/3Œñ¥ŸõÞ,³nL51Ã{‘ý¨Ê­Ë{Öô˜ø<ºAšîé–ȹ\®%tc‹ hòAÝ_ÝÄV>`_LÞýöeUË­×·û¦W/Ç¿16Þ~ðµácy”ì¾­[ÒÃf$y ¼ºáBÑ jŽ„^a.Šn¼þè5o?ê*ª¦h¯R3;ôúµº=SqÞ[×­1¼Y).ð—JR =ÝÜ“ô/‘…ÚÎâí €ýÓ7ñß(V3–¯ÄðO6T?Ü€µ}ƒçMY ²u¶ò¯¡ŸOU)y2›Oâ8TkExvNã¹í¥·u _8 /žê§®„°pÅ;sÉ}ÊŸKP$&«×Lo² ¸V»]@3Öþ|D­HJæ~^ñ<`¢šxù-‡¸å8bÕöyi!ïÙóå7œ§Ž™öv;V*y‡†â‹¿\R):ª~þL| â£ÿׯè,%GnLxM gËÆ6ê¹áýnxìëÔ’Œ)_•¬üDñë£+._Y®4-´ÕzsKŸãh²ºr÷ˆ6IÛ´+ã²äˆÞ‰˜¥ó´L“Éã“,6hW²j9µŸ¥Çƒ$[,¾záàF/~¡e.‘í¶—}2çs&‹ñ[ª…ëìrãꙊÙ4ãÖTÒ˜K_RŒä^s•}à_ `/cx“­xl(>ÝfùFÿ™ëÖUw£„/ÎcŸ%Ö™I—büÚ]´½0ü½J'+¤Á9m²|e®äSäC´ë#c—M—A•°y­b„ñ¶˜ˆØÖqŸ¾\xOoªô½u‘pü{XníW ÿ¢v"ì3ƒÐÄÍÁ‡ªO˜#é_l —ÜäÈ¥Ÿî øÍñ ®–(ü­Ó¨Û¦Ÿf‰ý0,û)}@Ï-'θ·sÚ ï׊ÄX>*ZXÇsËxžúf㤿ù¯ƒÎ_–mÑAÛ\Ñ#,ÎY¹-‹:G»J%Ûgߥéå‘;œñéÍ,uU»1yÎ"+]šœ¦¦H¡›•»•dH p<©Ä²jåý3ƒKO|¹Ml%Às}&3Trs“TnB’3$O»×uJd¡‰ª• ÷W¿Rõ„¨R”O­‡›Ó¹Uì¶óƒ8C‰ÉP³ÜZ§¢«`§TŸäü®ÅkúA8¦ {@>·.½¼ÿãµXóíê‹4Ò¼Øæ1fŸÅ€]kbó\*=†²Ä±â*©ôÆŒ3%¬rŠ`}¡ZÀÅ.‚êþ¡å«E–…“oÛ¶ÇO‰\èÒIÈìtyÒ‰…;ÇŒ›¾r)ú’ZËe'è¿Aþþith Èäï÷OßÄß.›b×cRæd ;GNM™×ѦȓCg TÜýÀ^wH®uv8àP·fÛûi”-@Ž‹A)ºõªŸ,Üãc‰}3/6~² ßiÔ-L‡ä¾É³0J©ónÉ’³Xš±þX·¹®©IÇJR#MªbÉ™&]"4«ßü¼ÝØ1%qZ¼Ï«—½ÎF6C±¦}p$NÑéÉ1b]lÇ©pŽ>ÏëŒj‡M$Í_,xDR_ûB%R¿¹k~Ë=+‰ãcÖiàà·oX˜o¡&Òm…™/ttÎâ-¸õŠÚ°0e­>{-о%:qã’‘ï\[çeŸ‰rÛmÒMhžù”\õ‚†F”®ª5ãùO„z¤ñüš˜gé˜ ®x.<ô&–³moPáiìR()Zƒyo;ÝâMcÌa®–aï-¥ ~Phkyu,G3¸¿u"Ó?“µ¸´².˜BÎíŸöH´£'eHcsü³±©ígéóNßœËË|"Öo¤N¾Tpé^\H xG„0Š$¥UH´'âfªr\‘¯×?±ÝÛË¥KVí€ÞZŠ5PhÞÐ@@FámDüíÍ7ò'¶"•:Ò4–V…„ï³( ÀBì‹‹…8NŒaõ¶¸Ž)µ#H7KzüêU0ô§^%ȦÔGi”÷áœ(ôÁ {IEHœU« ©Ý5pêTÆ3¿jºF˜X/׫>ž„R½ãÇ®ä6˵0…° +C !æ“S*ÉI”žÄ‚Ðß¼ûh‘ãïhT´…îH| ¢£ |ÕÆ(êsQ Cãn´<$èÁrQ:èþ¥Ëþœ,ѬG¬ínŸyòÚÇRé×Á÷¯Ëÿå†[té•Îü!oMzâ™åJÕl>ÇJ®%y/—~#SõZÜâ§leúõb¥K嬀 |Ü…›ÙŽ>òÑ7,1ŽòAË1­ƒŸV ´«?¯„vz¶¥ä*%aµ+¾qáSÅb>nZ‰›.¡}‡Â¬Š·úg`o¸ì·z='çÛP@æñ‚@5½Í«J="´'ðÆÁE<>·EŠÎ*Âü‹†‡ÞjÉ—5N"ðê¥Æb+ôSÐ7Üð09íÁ¯ëVzl¹$ gF™åZjÇM]s£+æÊ<:µˆ³²»2qýÚ9¥JŽn'.ª–Ÿž\;êA?<¢åSÆ=ööðm³YžúÃ/ÿ!ÿ´:Äà 8ìËtU+!¸†5ŸºÖÍD}ä¿È笇ÐñÄuËÐ-n?‘¥õH}z8ieÓÓ~-õ~Î|Æ1ª10þušzYW™Mœ§Ië‚Á3éê1¬Œ$Š’àÑ–›8jt+Ö/tê¿ÉD¤øóÑ™èV:*)Z–†Ë÷òï—àÛÔ]}ô„÷n ¾Ö›~>Ž:<_jáòUã.ë¡#!œÔA— üfÑð¯Ä¿½}© ‚ùIî‹b¹Œä2NåÆ%n˜`}·0}âÉ/ÉF§»Ó±Ì¦j¤Nòa§åJu“jú*Gþöâ:”ãÄ„Ù'-ʨr¿Ü¹ës âA èê½ï_öõ¾ö-] ئ!½Ÿy‚…¶4C xõÑÊýkÄ×¾eX4x÷b@¶…é´ÑEúø¾²éöSÙ¬Q ›—bs/QκC¢Lêý¬†ÀñIb2ŸÖ41í …±jÁÔÁ/èªÃóV²1"^5VäÎOd×ò>tª¬]ªÜ°ßv|—âvÒ¹=ÏŒÕ) ó¬õ=ƒ~uµø°d¾¬#\JôTþR {7uF£Až“ÌcÏøZV€Cá˜\×/ëÑ•L¯Â?%V±* úqf‰6cc²Ø,c\Øýæ"H¤32«zZHk,Le%{N[×ó™)&›häk¹lc(?¡ðÈ»G%âËì= ºÍž|¬ÔoÔïô~+ uì.S3)§h ©Û,ç¹)¢—ª‚Ô²k»©Œ}FT•žzÎFþ7ÇŸòQqÀ‰K^ .kþK9VUÛÞk¼Ò¥ma´|ó7Xj˜Î%‡õñŠ)Y×ê¹ò±õƒ6]bÈ~Ý+óËàoÿwäŸ)Vúáñáçx®ÚhwdšØÕH¯èòÏXsa^Îdê =>ϳÁíUIø!óF‡~ØxoÌ•ç6¾ú—»y"Æz®}*²äYÕZÚ*°ŒÈåÄ?Í&¾’ïmÄR¼sãŒÉ=´®[š.˜üA²ÕTlW“oÅËP “¤|hYƒ•P7vfŸ^÷-=Rz«§äBY?—‰Qí…§Ìes•V‰ÍÅrÓ‹È¡ŽÎÔGÐ¥¨°‰Ðta__ƒ”yê“T׉¥;äÞká~&Æ&±tÑ-_`8•¶úåÕ·×/æþ=Ÿš¬9ô 5Ó‘¾Q‘yÞc~3Ç9ècã–_wíC_a£cê—˜»üÇþÓèP//߀È3˜ÉQ=æ6PBïy-ª4ïró¨7f[„Ó%M™ì…à³üN#*´¥–ã¥N¾^á)7%±ûPÙ°ùÀ¼&;0Mõ ÑB–Jƒ@Ê”´êè=6ó ºð•ÇTúœÃè&DCµÊ†ÅTÔîÛzíã–¸”¯XhNÔÇœúÆòÀŒ:úõíññ”µ­­,c|ût×QtOo\0U@Gîó(6¸¯ L–e±±§Î£½sl3MTŸwtu² X.µø¨hì‚e9Zø‘—`Ô“Œë<§M”@ÎŒo§L/Q;,ù—à¹ðKÖ_G³HŽâ*ÕÿøÁÞdbpÆ‹žÇ0’ÀŽáéÂrî@Ê'†½9Lf^[Í YÖT•îQh£.ÜŽ{8ùù¨À+bÌ#¶õM¬d ·7Yf [§ßÞݲÎzËmk9} ÐÍYùáÝ‚å°/Óyžë’ßB– ·¨™;<Öìöò}»^™qÚ|rÛ©ÐfÆ'³ëÎûZg­¦Sʺr›×iâcªebÂ,4ÒÁ†FRŒ4ŽF1X‹ŽÓnH’´g¬`õ zyñp‡ª.(2{8ÏÇ' p=¹npUþ[ÙC59V²S·j´bUC.ñÓ‘WŽ>¹ºôæ5úÓ,¾%/B܉Tr\¦ODùIˆž¬-ሴ-ëhE3ßz̽}}â¤hWóðìðñ9²[Y&3ôhÜÇÛäïôoØ82<ÍW)$m£õªJŽÊ”˜œ3YʼnÁ9Fù›ã/Z^½½€>à³dîñGÄQž«ðÅw|iuŠ2/=[tßxtØsBEðÝ# ÍCšoã´1~üŸü=ù—]Uê"ŠòÿÓ³]+£ÈPôØÞ)¸3F«¬ÙcjæŠx±ç*·èzŠ—Ngb"3yÓ}¦,Ùh¡ÏðÞÄóz ˜š´‹æYT^0qfñL9ÝrE}…a[%)’ôvl¼^¹Q,ÍÍä)k´weˆÆôQÕϪ6VÚ.ɲ,#ý7‹\_..MžHÞ|'ë§çÂ?Rt*ÿ6Ì!4/¼”ä¢i—ÑcÕêá¼Qá³'-|=Úä =K_yL»ªbñêÒÍž‹š%âºÅY¡+wγVœ&¸i)ofÔa±¿ÙZ,žÙx+'Îih¨[Ìiy³ Eé~æ§—‰õ›•ÊLÕÅžsíf<äòøì´€=þ~‡ÙÐ ?ÏŸ°ÎÆ$EKo6.ƒkE Myc*ÿÉ߬¥ßáν邗¤rKT í®-a碖ŠÑÙ¼:7¬âûÕÿD`úéÑðö'ÂóTêpÒ*áT¿@¨`áz¤0}D™ÅU˨…“#®%[xƒMÞ†L–:L_ŽC)NL[?p>ÁŒb©ñjÑ& \Ìd{)ü Írëêgî×T£ndJ2½ŸsjpÎÌæ}ëöÍ$Ú0¡9¹ýT‹àÚl¢¯ûb™žç\Ü RõWºͨ¦¹ºÌ\¾Hc9c5qê´xµß0u“m÷…·ËF®3U6ÏÐß>«»&Õ™ž1ù"7S¤ÃÐ(׿Jûý]*éÔ ÉŠs/—+j•RˆoñòÅ*~znwæúì¹fíËs³*÷‚#§^xiûº\hªd'±Îßa šº+?Ö0¯µMõ€}3ä#Á5s+n#aÙ¶ ú@&íÑY¦K–•<“•qÓ&Èç‰ø‘¤G›ÔÑevêìsܤUQRõƲ<Ú4y(Ì —žbˆÕô{à8Î'ä­¬«©¹Ýž¼ïÝ[ÄÛ¼Þ«pŠOýci{žëñÒy=»±í‡¸k…µqk«©µ’‰O˜ïy xö³$ÿ¬–˜ã/»‰V¤“°4Bxéó”¡Ä WöªK+=ì‹ä1O]é»·ü’¦W)´9ØðfåÝ©4ümáÍqZ€`.=ù¹ßÿQ ¦RKÕ+þgNØ’O¶‹‡'Kš¦=Àï™M£ ìKÕ9Wãó <“{&cEìÐCÂ6ûËà/û7åÿd®ýö}Õµ"²Rs}š‡W‚±‚_C^~ÐOÆìЏe†ùDª[<˶Ïð¢YÐYü„†èåÕcÒóÂ>­5?Àìó‹q³"¯*«¹^D¨¾(ׯÖ|jÂwƒ'è<ÙÍ*jÓàsõ˜ì³Àº+«!m™F¢åà(ójÎl­ÀŠùU{Õ1¾b_×Pç æeþ†/ Kb¡}´ôæ-†Šrf@üÐvóBfÝÝ1‰ÇŽ š!cvKæLÖç.»4ã±×)ѰõèKÂô[Ã≴eq±%;bZاƒ,^äL-|1ÉçæêM¬'m8Ö255"#$ÛVs3ÖGC±$‹Î†…á‘\â¦û¼òÕÙÁC-ÿŽÿ´:ìè ðý§oâ¯[¦OlÍç³îÃÜB7…OºqŸã‰¤ã»6ŸªB¨¯Z!{mƒcÑÖܧ^íG$ž7 ®'”Ÿ;i­6qÛÿ’i1x6§µØšÁi×Ýé¶ôj9Bî˜Jù4„|È9Ý–íÜÓhŽçWûe È|gãÐ[¼]ïõ5pʘfcñUëû;ù+gÏe’fg`Üå'£ Í囸Ôž÷/®tóÆx,%á¼æÔÓ·Š/Ý–^ráxìxã~Ý·tc´9¬Á"ó/m¯D£pG¦:ÇÜ[FD9K—„OÍ ®Gp÷Fµˆ#ÖÏúå~-¸âm×ÛŒ£’7^ø^÷õÔv ®°¨‘ís,Yêì1rɸÈíû öþÏ.o¸JÙ9âk«lÏñt¦)ð‚æ¯é¹Éc…œï“Ÿˆï /1‹Ñ¤œrš|œ7ùT¨Þ[Ø5ÄÌm68å}QÛh-xÆÖŠ/ìl@Rä#ɶþ–ú#ѯޤ¿{¶àT2 &ô¢‘Q>´9Ñ•$¢=Å~=®9Ëa=¶&>»6¹Ê•¦ùHµ‰‹._ëÅÆÌÓ$ç/Ðãòýœ®:y©mq 23ˆÅÕÓ1ÒÞA•°ebÁÆŒËNFutxXŒuv2ù5ó¡¹7¹Od½2þ›Òëixa-ßÿÇ„‡`|@&+’Ã9sXÒÓEJ×;•w‘žÑunêÛÒí"µ(…ÆF¯Uö>o¡#ÆÙjG®8/Þ4÷ª¤é—ñÀ~ÿ.uj*_­;>qÐô7Ç_ ‚8•÷ w×U ^”ÇG[ªjŽ^™f) ?Û†îmhü±’ûŸš+,óª_)ÄB{PÚø«àŸû·åŸ“R/!±*ù.×üÊx  Ëˆ’üF¸p˜þ‡JÚ1iÿ6…A”c3•Z ó¼I]/BÕ*Äéh¿ ôOoÏJG^瘣¿¨Çg¥Ñÿµù.±DC½QÒÑÚ&ë fõÙ‰l‘e~Y5ÎqBŸ:ü`¯¶Í2JÖz4#suˆƒ†°_e Jûz¬k7‰Åeʜő5Ö±â˜i3æ~ˆ=÷E‹Fö…~ôJ¹¥{Oe´>¦l‡L¿†ê—‚¹ÆlÆǾ³¼GDU}²çW×Ó $nnæ8õ*+óò3‰§ò~­ ÷òÛh­óÙN¦Œ×o5xä€0ät\\zlîbÜ«8ÙvöÉ!–ÿºÚþð„Ú½€Ì€±êKx7ÞœÁ”ãkŸÿ5ndx˜µ9À=‘úBòzs{éÿ¸3a_ÓTÈ4ɶü{Œ¾¶ÂºXµl‘ôªþ“×1Í—o‰­Í+±­.œ‹$²øÓ©PúNAMü¯°-{ŠKyRÏö»“¨Ö}‰²÷>ŠáCÉžÒ)W|–Aú™ Ì»°y.tºÂ]eë쀠qw+an+Å0¹LõÈ!ÁÏ*ðcÂDf«è»ùˆ¯$eù ø¯Wäq©ÜñÕ;ÒT6†¦Àä´ËÑ~–¬é+€§1Ì Z$>gGÞòÚÍ>¿¤‹« Ë5Ê”};~Ó`±ÈÀ¨ñ€À‰îÑüû“‚$üÏ̾d.{‡o›¼Ù’¸ù©½Ñ¾…õëØ1Vÿ86rŽ*°ÿ•Ë)KêF ÉFiON¶Þ\å}yo K¡s Ðf>(Þ¢dUÞ'è~â €—ìIëR‘$Õ†}–¡ÇܸšYmÈc)Õ‰sË´êÃ¥ ¬¬¡Á¥ghË_u4†T)̪Ž<ÑY¦Ò}óð.Ét‰ç¢6^bü´%ଣ"Aè~ZAt",Æ2××-T[Ã-Y[שÃ!Q-\A6d‘Š,0úpRÅz¨&~m¢y¡]JÛTèG[—Z‡­ë_ºÆ™Ï&¹YÝ _B·â&Õ!Žæ÷ã9ª¬7‘?¸ÊƧ6÷õHüНžø¤'û´|É%ÌOëïKINæ<þ<õ–_S†½´»Zÿþ¨&«Fa”tãÙÚs¯žHç[³né¨O%¸Ïnq¸–Ÿ=j‚Nû›ã¿àvî=§V?Iý#ëp|‡0þ ª ï¯?'ò-(œ‡ûciO;ÇÙ £ÖªâNËZÇ~ü¯þäò¾ãÚ|îWP ·m¾à©úQ@¹ wå¬N¦ýgzEH܇æ%Æ©v;cÿ÷K¯HACO/ÉgÑ7úxžÀR½':¢—Ę4Þƒ+EuâFÁI]A–Wdsò äoòÄ·æ>•’*Ö“+eŽ-È7ô:*²¡‡kG}Ç9—•´Î¢Òðœðå›Ûiªšã ˜ƒÖI¥çJ@Ÿ= ÑÌÄ'Ì^{Q>¾›ÉáG¶ñ–Š@Ð\nâ=0ʹvΦ#_eäh±ŒëyGBáØxIŒx KsV²ç]¹ß>VŒõ]yØ=5 m!V¨Q ³?³¦úJ o[Ã"f[á¢HÇÑ(‰2“OúJ?#›©zÍá•ÿ²Úý Øûð.0Œf=ûí!ߪ“Ëýã á̳oó·1‰³ßõ¹aT¿‹OübŽëwR,}οÌåáòq†[%?š6¸’º~~iE@ç$i?gQ¸]9× QÓÁÚ1ÌÈ%;—j.ýPŠÜ¨[¦‹ßsüùe|íG%éÌ{Þ9cŸ;·ÒEz†2mîŸ(Cî}bæØ… e<Àl®rã­“µ7ÑM»kOž~ÚöÑ“”µóv¡oÎØçlç°l ÃV×ärÖ²M°uhOX6ªÈ¨'¡¹Éœ¶°) æ²åÆy)NxoE@xP2¡ïzip’Ä•­›ƒ]Ç&;\²$pÜ)EØî îæÎÚÙ +ŸˆÑ˜þŸ]Ì”Kje6©E޾tDÃëîxK*YÿÕR”»d’÷”IZ ß©Ÿ,õ™/ϼCט/¶)Úo”‰˜¼#WË&í¿·.Ä  2lÑXŒ¼Ãb°À³5à±j{®•çfúœ œåÐö­zee¢J#â'WNõ‰_¢È¢Ï¢\ ¢«VïôØä›X´©yÚ4«=¼ÕÄCW8Ø„.eKYÒr‘à¢ÑçLÐeÀàúµˆ¤#ý —Rõ µõB ÔŸÂH>&Ù¼T£Ô˜%/¹¿AÌ”rºnr>`{ðÆU è9õ7Êaœ-rs˜\hÚû”ا:ð͈ìñOg»&Ž/>SÍB‹)T6Ì~äéaèÈjÄ9ëÚNJgŸ!0O¾²ÊKp#è-~“bkN>ÎÖöûXÝRr×;˜l7*ì8–4sÞ–ŽP\ÌÿÍñ% –ÓALc#­ïn·‹4gŸ ™T¹‰–Ø Ž4' Î6«ñ©¥×`޽½Ê~G¼úWÁßñ¿"ÿÀÌíÊûÛõ·šb¦–î|œ§ö«& M5̤h”6?ýfÝEhT)‡gý³ Ž29ƒCzC|ŒÜf; C#¾ïÅJ‚¾lƒ'UÂY‹Óe^²ï®ËkÞZ1JV£èxXAÄæV=¦w?ŽcµKl2Ó‰ªG¢ü¾rœ½Ø€n»xÚ¦ÄâíV]>4CV€¹cuoŸ†Þ°Øí™¸%НG+“.ß¾©—øI¹Ó»Eó¡9ÓÅêV+‚t—ì½›0­z žj ¦ ¸#A™À%NÀ8oQ.áo/šu¼j¹ÅѯÇe_l%ª&ÞðU®Ÿý"±zú¡n:&w«h°m‹À½Hútáà‹rÆì%±¯«üGÿÓè_QàËüÿ雸K¥ªzJ¤R<5:Èïƒxš3fþzè=CkJèD±1W_´nèõwöÄÆ©4IÛDMk¾$¢Yss£ÚêkQüŒwç¹XÚ+ކòj…o .öF’^zóÁœ¤ò8ø¸lñ&¸…Š~ð.7côRÌÖ¸`R³6–çlf«.¹×;@c·SȧçŠÔc 2¹Ò‡œ è¥hÌ ¡¡Ò·WŸ(¯‡Gâ¸Î”r²ûÖ 8(ò9§8ÛÒ/SÑŽŸÇÔ:·1.$嚥@ÔðÌy!þ[öåÙ2‡îbƒ÷í7?^™ô¥¤õ¿@£d­üA‡t;Z³úö°š/¦(¾ÆB‘EáÉ‹«Š9«°UýŠ%ǰ>ÖðsøCÑ^­R¶>NÍB0ž0éjf]Á-ðîñ&W½žg'ôú£¿îTõ†OyÆE®ÈS3 4j¦8ö_æ=ï)Oœ™ d|<ЊcdøyÈçæi¯íPB&O„p¬RF‰Üh)öÚqÈCOLŒ²×WÔÄkLšqMúýû.¶%-q2C1ŸÈR9Ә㹱ØêXˆ J<_VÅј¨ø|Ž‹fÆáÁg¼R¢zÚ ºF ñMýžëÖÇ×/–TÜ]ó0}wÅ{Ö ïsú$ÍÙÈc'å‰fT^ ¸Û2aK½ZÀü$+‰ÛàK§y|´ÖVºž½i:{Þó9Ó>@i¡ˆÅ½‘•LE0T3‘¹Õú5Lp@¬dörÊj¬1)©y±xý;cç%IÿDo$ÃßLŽi?]ÿ˜¨X˜÷@’Øs,TçôoŽ¿/åìDñllA6h–0À¤·Rˆ»4kúTÈ箆ÛwÏG½ô4µâœôúUð_üïÈÿ=z«r· !FŒ€ç2øôzU[Ÿ·ž“õkƒ5é£R?g¨?‹Yê¼ÂU–iQvñ9OéõbÀÁS€q0DPEÚ÷LAÆð“áý¯ï Ï‹×.?{ÿ9‡÷“ [©±9nÿü3WJ]êÓo^;µü¶Ûg˜÷S…q´›\;{ÛÉ’ˆMBk•BƒwŠ~¬×Þ>+¤%xì€'Èë×ú¾ëõku»(µ`Ó ŠÁ¸n™ LÑ&…aý€õxÀB-mG„¯‰Ð¤’ÅkÑ{ÑëŶy:’7 ó,+Þ›žèÔȦsëq{q6ís¤Ùæ ݠعi‹PfbŒœÇó àK|i†n‘mL‡Sþ ÿiô/)‡u€™Ë‡7¶˜²l¤W jÆ]•‹’šsòK©ÕÎð&¬ßþšß*Eëû5W«1ÏþK žÃ@—óÖ…F²“† e“PJé[>†é31wOé§ÖÝ)bº–®Iîý¼ý³Pûà;—­K5¢l^=ÕÃ@ré<y²Òõ°SÌ·)qÏÇG¯F yñtTÞ“vªw^™I[Ä"P}3ê1´i}ï!­@Á¢æ3òp~ºèx`ш¥ty™o¤‰>rù¾Ìt} <áçNàãyõs§VÚI®«|ŠvÝaL‘¨s̳>:ÍvâµÙÇÚ€Ïoë˜ÙšñÕ̸ê­Ub†3SkÆ‘{]'ÓùRlžuy!¿.$S»•qã´}ÿ¨#¤¦ó4ƒkÏÕ#ü4e­²´‰©›·2nÅ`?5ž¸šæŽÎYp=ï{·âEp÷Çšòh¬~$¸O=µ¶²¨ùï¾Ð"ø«›Oð¾VTm¶ŽyõaˆÍlû«3ŒÍ|ÛwÆÆïœ:neѹ%MÓ,ã±–°Åë[NÇa›†\°Õ6ÀT¾±ãÇÏ‹Î7ê älî¶f­ èY£άyž‘w,¦({ð~k·5©ŽX\H¶•Ö`¸ébÇË‹ÐÑϹ‹¸[šgÒIÜ7' |*$¯˾*!.Sa:/ϲf¬Ã95[HÖnŠEÝ©]mK‹¦›I}tšCOtžÏ­’y zÚ»p™Qcp£XãVû TÑñö±wÒt×FçóŒ)^B¨RAŠuRÚ@?ê3ã[¯–<ûÍñÏý “3þˆw•­Ðk°UƒIAxYñí)ÎíŒÔùÓ¼–6R×^Mãš@ =¶Ú ËùEð7úoÉÿ­Å„êë¨ Ø_zLhZÕ;‹q%Ia‘P’‰bEô’ü=«%ÓçOQccq/3Ÿ¦k§xn+x“^çX1}àO¾h^ÆŠÁð?z9÷ífŸ ÛdÛqðƒ­öŒ’Š ë¥&æõ5Š‚ ¡ì[öB½ÍZ R²)Ëòà® ÅàÞÛš®'™Ú_\6~/ì÷œ§Ì^ú™ú„צ|5º{këÐ6 }Mê†÷½Ç¦áãœ ˜dœ†Þ*R­é礟ÇH¸gLÉéÐ }•‘Ê©ìëýíÎ/8·‹jLã‰ûm®¿u{)‹ýc_.½-ƒ6”âÜ‹‡·]ƒJ¯ˆg»›h+Fùù§ п¦ΟV‹`‰˜Iª]ê«Õ%výüÊ«ªù®q/ac7fð'Ñ­Îâ•€S|‰Có× Ü0¥i×Ò6¿LN¿1žú¾åz†¨ý½GÄÚ¯úÞrF‡²¥­Epô¾h¨µ¥»³òL}*•?ûÆÇ—ÖÛ@¹ú£zÍŸ½&ÌSÊ;iDr–¥I³Ì ¢%NÞY¸ûÀªŒ·ÈôˆýWÍiƒ±±V{<ûDévý¦)YKkGzŸq}ã!G‹ÈIP\=t¹ÊjáeÆÀ1þvf©\—UoB±¸¨€löB(}ÅË :oJ.ó)Œ›Usž2­ãIú+s:ÏŸn[OÒfHAÆë T‰Mk[pYó-ø¬Ù A¬Ž˜Ô¿:ko4¢°9|s¸À'¿ðÝqAVQ{Õ"Ôt û´.%‹›r4¼] ]Ôad¤oðQÁx,Lä•NÑO¨ãc™Ç¤½:‘PdÿFö[kÅù#Êvè+Q”Nfex¯3›óKO©9,”¤C}‚7™½D}¿•‡”½Û¶&qæìào9oV.èÛÌ›I:é©ÌÊuóÞyŒ¢\úFôLΫ ™[#±bù¢½Ï[–ªì˜V”ò5ôG™qÛÚŠÏE\Á¶ Ðÿ°YÊôèýÙkeäoÃ$k×ñMbÉ›2`éÒXäq/³5e²ÞþÍñ7ò(y*Âi…ž3wÆTBèøÕ/΀ž%»)œl)ÆC#dÁÕÕØÑKatîÁ_ð¿'ÿLi§½†ÏÔhÅL›q¯•›¶ß“«g÷'›³È̳àX׫¡%þVÎÁé ®I!mÃèДëÃw®Ë l—šIŠÌø —a%Ìûaž[ß"[ðÊZ×1!4à ÅÁ‘é†ó—Ÿð%¥DÈ­KsB|'tî߬ 9[!ršdH¿‹U˽·ð–gÞé÷Ê‘³'Çó{OVER™XB5ߊÍ:CR% ¬g{ÅO09°+ vo]}pOÀ½QѹêÕ´•Ð-?Áøü8}þnÚV´œb¬ÙöúÜÉã\ɵ[[Ê l,]rפª •‹Øúrê° |.9G—.#X,Z÷püÖCBÌæ£n‡Pþ¯ÿÓèßSåOWMÀ¨eÂk»ªãžlDr°ÜY³Âå³QNß(?£® {¶šRŽ}©ñ“!ý2KBŽBÞLÝ…XżªhÑÂT~cIqz3 ¥¦„¢]M2 Iwñµë>ôX ¹.ûžÍ[•Ù„æÝ  ]t™ ²#-0"tù|]>òÜö;'ƒWζ¤’o`œº5Ρžrä?ÕØ»­2¿Ågz™)ªÖGlGêʯI(v»2óÈ y±Mó êÑ‘ÓJ¿ížl!™¥ï~§j©:ý¦+äHZ(–ÒÛNŠ» £¾,Ä^@M ª‡h³o¨‚²Mײžô^Cs[Ñ;æ™±TïðÉzž€ƒJ&ŸHû˜iÉWïüG¾ü12›G©†¼·|Ñr—/œ{Æ »ëV•ý&ÚäDÞ1¹Ú¶L¾ê‘£¦Ò½ëÁ”ŠÄO4ª°ñ´l×Ý\ð@^ Êé­ØW`“mn²öŽŸüŽò†Ü’L™FÏT›¬8/ruMPÂ6kåštð3ŸÚ7±ûØã] ¡Q„r‰C— >—$Cz¾F{Ö<;²3¥QÔ÷ÎÏ/„/ŒŽ»­ÒÈáéÝÌtã£:øù´[õ<É ¸Å/ž‚è¦Ø?Âf7tð&;¡¤ªPü¹íiwÚ;5¦Ûèl#ïoT@'Í•ùØŸ…zðc¹¿vÒöš2Ú%}Œ?J”…™v7t[kPÄ·™üŽ Yra‰fâüd¼š1ñ`×j%ƒª–Å"e¿É ÙmvûâžÛSöoh{d»Ž$m9ùL¤§ãußÂZ—T–Í¿âÃôºíÕ‹ßvËgöX"Goššž:T.!™KFˆ÷šÃŸïy½vÔÝ»Û:¤í%QôÒ9¿þ¥ÿMù)I /àY=y1ˆƒS=°«Y‰bægù.FÓ¹5ô8øƒh¡-›‘IZÎÅcמ .àß» Aƒ±ÝŽ~ß}C…ó…AÜ‘·kÂÖ¦`Õf¾·¤ÐÏz)yV8î5ÐÜ,E¿Àš¾¤)y[¤³?™úuŠEø46Ñ›·Ü¹ö ìjãPñY=ý^C·È|öcøGãî“ó}).› h.4{dkâX(Iõ¢C?ñ¦>{£äªU¾’[ùûB.˜ÔŒ õ¦tF"õÓêÖ~hrð%ŽÆõvVƒ ã)‹˜Ðjw ݪú»+‹/êë'Ô_ÐW²>šk=¸aQ~¡îºa… ^ï±C'ÿ^ÿ´ú7•Cø“À Çl;ÞZepH.ÞÁÓ®Z€K?ÓÞ´{<¯çX“¿U6ö…-SƒÜ{,÷£žß»µkÄoÞ;}Ñv–ÊÇ“)Z÷¥Ä³^Lñà|¸#PblNˆb˜}„Hë(©ÿ«]„Z†vÉ=ŠU+02^µ›w§¥/G žÀßÒÇ<´’®»Ö ñìuÓÙ`ÿøFèí‘xò ó ÚÁ!_:–äÅä¶õµXIR: Ð5Èb&3eEÍ…øË{Ú#"é¶×zIÎ'r°Ú¬‡³¼ìp©’Ý[½¤â/<ÕðˆXI’îòÇ×ò¸VŸ¡äü…±ƒ¼Ç °“D QHÅSãÜÆ6.´Ñ¹]`¾^óà1©vƒ|¤u\®SÃpšfÅš©üMÑæÞT,ÆC¦›’Ù7Sóªn3LË0m~uÒØ¼–ÄžáíÁÙô~ê•ØQý.%„ gG@ѽÅElæ«C¥×ýg{?ÉâË,­øF~6' #¾IdÅŸÃØ’ÿQbšOŸ%e ½Â:Á8Qõö«³¥ÀVô”À[ýÓɦùcãñÆE_ßW«§oƒŒÑÒVØI"TóÑ‚ÞT+<>»¥¤…QQºÐöF&ýfìãPáÞÇ„É5µà³ÉyM Ù+çtSq¨ôNÛ Ðà3Ô3Ö{¹ÒÇgÊãéÂúšxê°+¯¦‚—oœ?Eõâ")¡ î…ÖûçÇ% UdMgÆõL+”®\¯KÿŠîÌ›v±…£Ú¯ÇÚ¤©_¤BH{õºÇu÷w…'>h´U=QØÏå¨dcø\-Ž8²Íõæ7Ç¿+|Ø.LõVÊcMî/±a¤§Oâ×)(,ºã‚ï?öÄOÚ<>Ròæ9÷ñ_ÚÿªüŸÂžám)á*+UKСÇṳ̈¢Oã6w¡0ùsd´–œ‡«×†"ÔùîHáGœ®g Ó÷³©Œ.dX2»¥çÞœ¬UAcJÕÓË&}éß™ ®Tm'úèϪƒ+E{ÌÆçâöû—Õ³Y=ºÑ_ø, ˜«“µd¯ÃZ½^‰ek4õt¼SdÅ:Q~ƒø¤ €¤.¦ÿ6 ËÓò1FɺÀ­¢3û,Lûæ^å(ö ÛÊ Î-Úó9ž›À°'q‘c]÷Õ,_*­(Ü}$e™}öDK­T q²i™P$)äÎloÐ6†n:™Íݪ˜‰+«Ë„Å<Ö¼œO+®2ù×û§ п«=ÙOëÄŸñ{s'êÑøçZ <ûÞNùmæ‡:$z#3¸Ÿú†Ð|ÅRW#˜¹<ø*˜¦ïΧ)S¤—ˆõ'ší¶Í;û?,ˆZ {“)—–Ž‹y‡ݸÎ3t-›ÜÂm®SÚw*GêZ 3µÍöÕþ.[#X·ŒD埃ʸ£y8Oúºž1aè9Ès—E‡`f"ºùjt›­,6h×€ŽxyB„¥DùŒ/ÖÕ+‹UìL2zsÃYÔz5H÷£§ËʬÂ>óŸå(·uϸ£s-Ai8]ßžåÉÁ:Ý'–¢BîW¤ªTè6Vé’XAŸYz%±6DM¶u Ütfž%ˆŽ!ÞB2œõ xoXá©Ñ Ú²JL“É+ æ>Ãn1õ8¸8wí'ÖÙO×Uh2Ü+ż÷0m#N·؈i‡¥FÝ$Å mÏ\øqPšö Õ"GÐëô½×’!”â”M×I|9®ØÚõ†¨º)Ï]-X±y]Áøilø‚î‡â×SA¤"¢&žSC}oi,?O³Yq»ž,—sdkk½¬ pÕšBñmNIë—ÔÔ Œg¾%ü·£\¥×¨ûÃN é^*²ìc.#¼Ä2×uûèxîùRGß§·/^{Ù®ŽØ½eQ+ÍÔxºt©ˆ ?mpÙŽŸyV¾È‚‚nuêúLX)ßßZl·Tb(qFôè¬#_œÈcÙºSàÓøƒ^#ç¶Ížª’ÐÙ~y‰gî^Å0Lð‘ÐâA¼ã¿9þŸ¥ q^W–øÏÒäiw`×cÑ¿ÂÎò™K€ëˆ­-ãqÕ¯¿õYþûdo> ±Å&§y ÞI|ï˜*Ôð©ÞÉ£—»[Þû??3'dqÅ“ 7ºg¥A\¤ýì~ÛŠµ‹G¸ü¨Nš!®O÷} é)ç"Böbeâ YÿÌûJ¸3Ó q“OØÙ*=ÒyC•KЬ}Ýëú»J·æXä«ÁÞÎÞÐ~ȹÑv9b¨´Þ°þtuÐGën}½Òµ‘“‘c}›Ò²’@$ɼëûa°½Âo ªÑðÅi1ú•hbòû¸Oé’\Z7¶üÙè='—Šnàm‡]ÔM›\»•Ôc¾‚6*ø>¶ð/@·›ÿùÿ—˜±ÿ¿Ë¿Æ€çvÔþwzQ=¨Ý!?VÁÞ^>{öÔ:äîêû£>Gé[ý£Å8Ðk·qßH€Pè~³O0êF¡?e終}÷ìÌæá{t òCJ'âùQòú]—ƒÇ¾³ o7÷[þ@@ì‡NÐûU„Aè>»Àp¸.Ü™ ÄŒú@N/òaM @( ®n¼á2¼óþBuDÈwÂ{ùƒ@;JaØ!“„¨"¿Â{ÃÕ€—t×ø#µ(ÿ¾@l÷¦Qêá ì*ä}]ööðûÍñ÷Þà ۘV8,rÀ!@Êÿ*ÈÎ÷×Áùkòô¢ì5ܬ#Í0dÿ_ä{³k´‘ÍP$þ”½FMü‰ {^ eˆ×þü;Ï wH‘s ÝÅoÄ=;r'ÀˆwŽ?üUƒ{ðG„Ï2ü"ûãaðK#ð‡£w`pÃ?äƒô8`»Ã"Ά»)ˆéBy;ø;ÿ;äÿð­Xÿ5 j:}ñïgÿoÝdÅÛ+ÈgOOï†[Þ®þ>?°WCFZßó“nàM;JÃgOõ‚‚?´ø½ð¨ÏaáOõ¿k€?JDáFã»®ß)ûŸƒGöv„À‚} ßÉøNÿm  /Bð\½nû¢"ï?R½¯v¦€í8ëþ>H7'»>ÿžì£„°{ùúìœâE~ßëƒjF…¨ÏÞAÈ^pA¨—Ý{…º;;p%…Ô^²òòüÍñ÷ÝÁn³@û±"ÒT€|öìJñ"•50ÄÅý×Áð—åì‹z[@`ör €#´kØQ&~·ðñýÁ»Ü9†|·6a´wf5, ŠÀ·È10z`ì½øaäw‡…ãBÞÄÎ!Æ!›÷ ¿€ÂQ€ã î €}P® 1"’¼Ù;Šð`¨ÞH¯ÙÛðoÿÿÙÿ¿Zþ€òvä = ÿ?wÿ¿ ÞPÔÑ]¥àå¶KÿþD±ïÒsÇùc ¸oM 礑Rp €~ßú³A€;Jã;»þ¾û.ÿ‹ÒÿÈàâûg*ÿO‚A ç ß»ðþ/êo¿Š¢§=o<ð?àÐ÷üðá ö…yƒüú!â(™F»aÊÓyÀ¯²5 IAÐ®ÒØ'wT·?’þƒ+G¤Gàÿ‘„ìŽæÜeo÷b~ »×Î ðwÇ?ð®?¥¾Fúpë²H‡ &܆À¹f°§Í¯ƒ?ðoÈ¿Ÿ?* Ý%ówñÿ.ŠGÔN#„¤ç÷ÉÈë÷P¯*ƒ´î@xDŽäíø# 9òEE ¿ç|íqô@ ÄÉÿßîÁ~Âÿƒ\‘ü?âîA@x®i/¾Gº¨,’E@ ?† èi>üò¨«ýbåßàxîÊ9pGHºÿ?ñù¿¸ _pPa=öèßêO«À_½ïÝÿlPÚB¥½œÂü¿Óÿèº{•9þÏñŸK ÿžpî§ÿAÿÿØövpÚ ‚ÿ ÿÿA œsàåØ`ØrŽ”OÈÞ2ˆÐ^`(’Üí´W"‰BðÐÓ†ˆ4\óžÄb­_ÔË»Ÿ¥î\ ñ,5¹£a!ˆùôF@èoŽ¿çþ¤ FÑÃpSþùZdNÿý_ï¿%ÿ~0TÀŽx=€î€PŸÝt>2v>ÏÃÍ2£³Àx£PÁùÁ ‚ÌžHÁË1ioA(§¦Cv ; „0ê»—”Ùÿïùÿ]üÁ»€¼ *£€<¸» ÀÙ] €ºb꽜"»üÿ/þÿ;åð{^úÝåVƒîÿþÿwZð ðÝÀÞ.þA¤÷õ?â-<Àèì÷*¨xìå‚ü-ïå›wÓ‘{è^èˆd´¿Sø?êÿƒñüæ@à½4ðŸ3¿ÛAî€×-ØÁæª{¡ç^ÛŽhBà `¤øá¼K"lRbwBm÷PŸŸúü»lḉ?Bõ—íöùY†Ò À};ï öÛµî ?dPíw™€‹yøýæøƒní Û½'dúEý\ °Oê"ð‡ü2ø{ÿ=ùúB/  #ñG*(êEÂCvÃv$þ»ùzdGAòÿˆ„ü2À]×òÁv¼/÷?ä‚”Ý ‚wÝ5‡Èu;7B,7Efî‘<>ŠY€ìóÿþþ°=FŠÂÿ§Ëüÿ÷Ë”ýþn‡\þ·õúÇË¡_àµó Bhàå ý÷gL R{öVu¡VÿlÿYm'Ò€ý¡qßJü!5 «Ap¥ááâûC ô‡Q {ƒÁÍÝûýAÿÿ„ÿE*#Ôç;‹òScp@ÿ{Bý¼üBý`?œñXÀO À|Û+ÈÈ£lÅþz`oϽº›üÛOì\ê»›âó €!¾ïij°Ý,!dO_ 8Á¥À{v~}ð®ÑDÒÿ(ú‡LB ‚}½¼~wüƒ‚`Ÿú‡@PÿH‡²ÇìTwð÷þeð÷þ»òEà4m^.a~»; P”Ó‚@Q.&¢†À²G ìå–P= Ü[b²·3zDrC‘ ܰ#‚Ý´ÜÐÃý Ä÷?çÿü“Œô@FêFº!?Y€ìÀ20è¡–ÿÃl»~‰rÈ)€}ûÙiÀýOÝD9ð‹wÀÏèßýåÜ»¶a?ÒØï·¿²èÇ&„ï ÚZ7P*á ý±ËÏâÀ};ósþ÷úAÑÓ?ªü?$yé ‚=n†ïníù¿µB=¯Åþé ý•Á½Í> w?øíûò¢¤pC ¨ŒäŠ"@ˆçG­ùAF3ˆSདÀ.¸H;A*Mø=înþÛÐ}®À^Ðø»ã'î–€Xõ¿Oýï"º»ìyå—Áð÷åß7óÜ€¡¾È„ü¥¤ ïkð«@~(¦å¬ÿ.;Ù%P´ ÿ`dòÀïÚç}þ»™`wå|µÁÿÉÿ#!C±î@Ô)(þôg˰‚Pøbùÿÿÿ·Ë¡ö¼÷jH‰"öBýGŸQÝïxù#³­éßíûú¯íêÙ4øA+±Ûy ;JÃ5 ö}—?‰wUõ®ù)ÿ rñøQÿùf_Ø3þ£þ‡xyÁ7л9Ý DÅš¤þ~¦€×BÃ}¡¨ˆñ;‰GùôÐ]¶AØíˆª—Cìƒ}¿ r`™/‚Û󀳚Hî‘9ßÏ @TuÏ΃q<ÿ=F²·óï>åþ¬¡ž¾¿9þnpüÁ{ç=êB>¸8›] üUðBvË_—ï _Ä£¢ðGHÈx û~ F˜&0²/Ò¸îû› °üH§aT¿»Üåšîž¼Çÿƒ‘Ö ‰ÿÞZ„ïù‹_À}îD$Áö—@!»Ùнm]âÝËîú\í¯üÿÏþÿýr˜“{öW©‚›ÀÈüvÿáo$àß ôrŽðƒýxÖOˆ`x+óùyãÊ}¯âm‚úóPô¨åF?˜‡]þ÷gúÿ»4ðM?ÄsÃG¸xßòƒB¿“ñ?V÷s 'H(ÌÇ„0 Üt ±·+Ø@äíûÃ6 ýìŠ „‚ýö—þvfy/j€‚ {Û€<}} ¨EÁHFþ#”&¾¸ ÙSßb~ÈnNwß+€wØ ü~süÁ·ü¿°· ‚RÕßíÜý¡ °àWÁÙàïÈ?!ÿž.~»”=d—@ú®†ôŒà“„ĹÎï±þ{QdþžuGâÞÛ*x€!@Æ÷ßñÿðŽ»? ‚/@ˆÊÉÀù(tŸÿ‡ ÆX°kìîâ÷ ¦Õ{¸¼ƒ¿ûa•ÿÿ­ÿÿo”ÃKìÙÿ}‰Fî…A–ƒâÿ§òWýàÐÝ;l—þýIø÷ÿ´w%ÝAøOÎi~Âï’z‘dyÉBB€ÇüIºkëjI6yLÖ3>xÚŠÆ‹Jµ}õUuÆ#®ÑmÒÛØòÞÂU_º];vÊ…³òwä9êçËÀúEµ9QFQÌ]J/Xøíëùo]Èw^þÕchïÀ'/]ð°˜Ï¤>áZÎÁlû|¼Ý¥Ù<`Ó¨!|Jxi«ŽKƒ¾ççm应óÇðBôÙž²:S”·.ÿÇÓAX\Dtý6Àši«ÙµÈ_òÿoÔÿ6ÈU=ÓH€Þð?¼Z†{þ1zù'H€ù/ÈÔ)òî>Èß¶ì|)ØÊ(‚ÿ/ÐòÌÅ3þñŸxwnì ߣÐÛþOxœ ò~B1k§©ÿÿçÿó˜jÀþß©;!ÂsCW«ÿ`éì¦ñ«ÃI ®rˆýgjœÌ»@ÿ’Ó‹ùs§9ÚÊf_òƒ20ÛÿåîÐ Ž¢Å/ì¿]w{:dÖw¯±:yúƒ|Q¬@ùéïrt}¦ñƒ'ªúºð‘1TÇÖ^Múé±@\EÝÉëøÍÌ®I@9½Ü5Ć” Ú¯éëëa)/«]êÐÖgÃGÄ«¼±7.ÿ¯¿Äi0Lè_1¹H¬aY~úëJä_ù¾þ£þo» ÿ#5w†ÿé^¼{ÏÕ f8§n8OE{,»3m0É_H–ªƒË@ìÄÈûøx[”? š¨igøT\H• ÿŽ„kÖ?ƒþm¢[Æ'ûåx%ògÿÿú¿¨Þùÿ4žqñe³#§ò9ýߌ†ùo—Ï(¸)Uº/Ëæð0g°¦Ïí|ìÎWÝ^„åÿwšÀ=ÿ2 ˜}3±õƒü=×ëËÅ|‚ú?=uµIÒÈÿëðßÑHÐ&#iõ޶Ö³\><éßW’i L¹úFtÈnJàÙʨ6•÷ótÜØlêŒäÇzp2{gÝNàñÌCè{Ñë<*Èi; Ñl-4K;@aë‡1÷åäôjþꪄÐÿÍûÀêÑð,°åâ°¯p$°þ{3XeŽ€FbÍþÔµK‡í_ƒ|îßò@7Z¶Ëö8Äékº¼ |Æþû­Ú$üÁlg§‡T ýñis÷û®º³U¬ióà/*ãSÆ Æ h#mëé'm"ÂVÁV{õ°m>BÊ+€e‡è&¿äç=íæò·jàoòFK•éÕ"sëòŠ#Š(‹Ì¸"Lø…ëï®Dþ]õÒ œo¦á@¨!q±7_Rc™õ/%’ùC|é¡êÄûÂiÚÏKˆi;1S}ߺ<Í÷ÁóQwL%û÷ÅLFÕËÜ\w—‰Â3ϧ¬Ý—úÄãåxÂs¾H5ÿáœ5–ÉXª)ö§w>è/ì5…+é^,‡žoó9ß”~%Ç#^TSœ²ÔÝLG÷¶í»§ÖM ÿ™Á'/ØGš8Á¥\ä «LÏ7Sψ~Å D·úxƒpwrÌ“vÌõž1•hÉF*«’y¿>77þ U4¡ª/.[—L$î/VGÑßöM©F½ÐêJwJr@5&\¸fÖ”yêôz¢P/£çz».µ{ŽMo²€É|#Ýó‰ÙÂ>QɈ7Ù”þ\kÛw¥šH,M6Ðl:w­œ$MŸõ£ÀT#ôõ´³Ò:eñ—Ôgrz)õ£¬J«K\ vиA{ýê--t[¨âÕõKÜ+œ¶8—ZÏ?;q6.¹·àÛµO0‡þĤ¯‚ôY Ø^¤†eD2 wäîóH`Ý<ÑÄ¥šÚøÐtúÚÁƒ ..Aî>x‚æ6AªMg=5â«î,án´c˜É›+Ïäúì ÝÏè—s$*±Æ¢5‚M5&øß 5YÑ1l<_•–­òº£„®§C>ù}·4X¡mìŽl#}‹yU(cE¹¢âòƒïœÐ¨jø×œþpüéè…. ƒC–¹OWP”^qFSH?ŸC»sOÍäô§7ŠXª¦\Ãg~ ü-ÿÇåßwë¾ØìÝJÑo¿V}üÆ÷L±Š¢-ì|âÂôÈÕOrez¯—]œ›HéóY¯ÛfHNÊñ²%êÂìk?(“AdôiMK]¥ÇO|쾪—/ÇP¶±ÆËáñè¨DÐwzC6î£`½6M:ºDŸ·?ô•L®"cþÆ­kœØº—²áeÑᣔ¤Ó|Ÿñk+%éÈVMìN#×{LʧL[ä¥É«‚s¥ì©ílö`IîËÙÑXÉ¥JæÚ²sùØl_žÝµQG½×]'ñ94IëlvaÖ"?k|ù)¼‹ËÊÄDÙÏ‚µó½Ðe­y!©Í9ºh Þrâ‹t„4<_: Ô³'ù§ý§Ð]yyûùCþéYü§Åˬ³ÞÆ"›ÿ½Ïi¥Ò•m†±KÉë ü,RSvCt‰ŠLv.Ýô~U?MØahµó} F‡K•o†L¡yÁN½–T…Éà1~.Âãû9[qSx†=ãî8(®`(•Ôãµ J4㦘¯I"—a^Ä€ÏUºa•Z0¯¦¯‡î:ÝÞùH.ñx‰ú™)nUR¡Òç…ŒµL¥“¼¯QLOºÎ•6WPkÓOѪ ô _ÎXùDIö ÃCü>jô9?ÊÆ/ªDþóRrÛ»Uækf#øx#ƒÌÛ|’`úËgH |ìJ¼¡´÷S%¸œFœzÂg·@fîIm‹í××´2Å.ë–覅À²G áü„¼#Ï£±B0j ùîôoÓ?MªqØÚ|KqB¡¥bõ‰\ç›…²ÝéM÷+!…ֵʋ9jRÚèÐ…INLm…Ê*&ÔÊÚÌ3]¼4ZcÀ‚êû!t î)m³Þ*¯½³4¤#Þ¼K£ª«ˆ%·ÖYù…øÍb>ÙÖF{ëWF4׌h"XqþjôI’$1ÀÇ:ZlÍéàb-}œÇ8ƒU8¤ñôýWCÕœÆnžzP÷ \ú·Ìœ'(Úƒ‘)÷hòŸÏ–ï-Á€hµ·jŸ¼rþ²×Ô»ÇMeÂ`¦¨´=Æt"]¬µsVV™òöܽtp=G+ÓˆxP¦ÿTiÒɵ‡êy»S”¶1®)òçÕ«oíŒ vM\¤²,Þ`øÒžøÔÖMüL9Ú}ûr;áÖTºRqø0AßÜIAgÎ,zù:ÐŽ?qÒÄ„¨Ú&ågmfÀiFkè×R…¤Þál¬‘Ö¢'¥zÖ  ü þù—êv);ÁäX˜R-.ÒwjT>´?„&qù]®V!žÊØc)·zoÁ)W´‹²ny2ä§ÃŸ(jSMuœ~/öô>j¦UÜâë¢+Q±:µæÇ;V×ðí„Þyœ†½îã!Â5±W¤%ʈæxr“¸ÆìÞÇî®%öêq²›ÆJZãjÉ”)mvuB ''Ç«‡ØÁ/6z›"ýFÛ®^OzçÌTõu[¨8ßS·S8hêë쵈«7\_72 ë|JK]¾ =HÄlB·kxPsCÄnºn•Óæ…NÚ=gáÔŠókçd·¨QX tæœZ`鮌NŠ¢¹aÞlX0Û£,g£4¬K4k¿ü?ý§ÐazýýþéIü‡E%Oú›3j1ÿíW'oôÝ`ÈãÆœ÷&P._róÈÚ,º­6¶FÁ»0,PþælÀR‰þME­œ·†ŸÙã˜õ±‹}þÙû´¨§¼K<“`OÍ%–„•»XÀ…pâNB—¹5´¹2ݶ¸æ/Çæ&,ÔQ€¸‚å³c–ßÄÑ¢.°¦N<É?rO…Ü‘¬l‹6‰À7;›;ë¢Ý÷Ñ÷ymª0 OÑjhµ çý¾3 dm3j'¬HwÞrßxÓu7ÓY˜ïžhË‹‚gW6‚YhÅ^få±d£Æáµ¥:>PÁòˆ²wO¸5Ýbç]×BÄ+œØ¥je¥À&㈸@Û1Ms‡( =° F3Ç‹|+mØp4ùŒdÎË~/™«D@´¬”‚nF:¼F70rñã׈³9ï©®g~óp'2qß40R0]È—½¸éáLè‰ÂdÕ“véôxÛ놋Vò à”/A¨ÍG[mçɾºõ¯S3ú¦w/¬ÁºîÂůž¼Óƒ3qã>Ýòby‡>@ZËG·þ”»Æ E³P-4’€0Ã-Ï(µ~«¤’&­Ôê•z§š m/†×奌‰;ȇ‚$Zh˦%Þ3{n¦}Ω¾‹#;1ÈÔº_cÀÙÌCˆ|yGèR}Õ¬«+k"_[ŸæcጽýøÂ©f”R¤¦m®Ô<Õ†v[µF[ƒ­£ä¦ˆgó˜Œc)ºF|®Â›…sÑÛþúx1ôÏüÄžs7ëùž4&'4-’ÜY´¬%–µŸLr´™pÁéZ›ÌUžðÿÃñ§xñUM@OàzЇ› ˜‚IœWƒª ÔüDw$ܤ4q~ üÕÿùOl{H–Úä~¥‰î<ýÝ,ÝPãr²²uƒIF©sN%Ï] NÇJÇ$4Y–S©+Jt&Ò·*:.ÅNi7”®·ÞÜH¯½h.ö»È?ìŸV@ÿ•ÅÇð{<ÙÖü-G §vßXn¶ð¹li¢\’ T.÷7–x7ït]\™6þtݽm¦éœÍCËso7 S„œ÷ƒ8­ÿç" 7ë7£8#ÏluÁš5¦\öí¤Wy>õ¼±,»¡pÖù#Î3ÕÐÅ\UïÕñ.G·é‹ê³Ê¶‘SÞ'¦Üš —¢FÒ¿˜\OswÒïR¿D¾³n†á0Õï §4xGëé…T¢—íŸ@[¸iO?Þ-A ¦”4E/–' ü,~~`¦åŠÏ®  ª32j{XwB"Ññ`:,µÍ£%å9±EøÒdñ庹 ÛÙ€Þç¡9 å’²¾QCS^f×¶YbX¸Ê´—é슾ù}6RUÉP'ÐM¬ŸB½ù%›«a|È-#¦{fn,-o›Ž¯·’CͯføÒ7Iq 9œÀ £æéë!Ý÷ü㌆oÇ0įö~˜^³¤9¾,®âƾÕN¯+CjÛô衇7¶!Ÿî˰&éDÈì ë ÷2©dvY%£ÂÉ«hUŸ‰/§GHÚ|’ÉÎ~ûY¶~>áPÿ|gëÇD7Ó3I4÷ ä° ceó@:²ÏîÐ|cŒäôÅ&KA{ „wG‚óœR© qúÛ«ÒÂÚÔ§åÑõBD¤W…DÌ7Û«"5ø8/D\·Jc‰k½›‹‚bõå©ç:–á²V»Š¥yB§Ä£ÍIb­”5ÄN&ëŒê¥:bóJ’ø¬} ÞŸél뉌ÊÄd1’eL…§ÝçnHu.°ž»úF K“L%žYõv×3,ÏiJ\Ål« ‰ËÛmµ±é/´ ŒŸ`Ì¿ WzÑÝýê¥y.;ì3çÅ ¶z4ç…/ùU—^:­¼R¸ßM(× Ú,nœ ([Ö&K‡"îËì ü‘ØuŽm[J0âB¾ÞôW}ʟͳ[„ÿPc$çö5€à\!3ÚÎUhb¡ï¦,1n]'ÔKœ°³©!¼RèÂÑÓ9ÿ7‹ 'î»>¯Tu÷˜¶xð‰ûõ«‹¯3oHÒ¤ë‹`[…PÑ«©·c:5û…"ð 0’ט,ÜfÎz§¬(¿° OPñJNAc2³Îa!%—y&¾ÁÃvóK²zú†ÆG1bþ˜×mµwRïy)ÞtM/{%‚Â+û[È¿È?­€þ[ ÈÓÇßÿŸžÄÿ¿\y,¢<ïikÓÿÌŠHûë §>¯ÇŸÀÄ2EýÑý³ø‘œqK®VOrÁR&dÀO×—kjè·1 ûFoŸTßmΩ6-[ò§Ø9•ÍÊ\ïL,D–]H&×:kŒþ…3¸oàÚîà°nGø"Ù«/P<‡ñ†õ˜M›±üô¡6…ã+± E×±nðæ}4¶ïŒîu–§KæPlùB“Êïédd°íª5Åž*yJ£æÓ ’r‰ Ó]iÞIƒWƒ6É)ÒXëCÄ3¸š';Q¸ÐFad³s­R…×6\-scœÍ¦»ì-ß4ãySŠd¼ŒRæ(E‘¥`Ï67“<=Ï¿D+tgûNo°˜h™9ãŠí™öHëÇW½ q­½ Ô:#ɹ§âџ芟Ë{®Áü.9ÿú&&Ú›{'tŸ4êöÑgÀÌk¿E}€IGò}µzƒ"…ëÐÖ€î×Éxa°´Oºu:m¶®zŒÿíóëjÙ¼KS!š¼aìÁA9‰Á”8i©#iâÉ|i¢—³½íRª*õQj½>Fw~Ô…Íá³÷U5ÓÕÆÖ¡HdMæ'nÝè.MÁ¹ìÈê(¶Zû6è9{ŽÊ5^Ü©lÉ\¿ée§«£ÚIÅ`#'Ï @9¡³Éž3ÐêTÑÐ]ctVû”|Gøµ 7· SŽTÚ¸ÿœz•á)ÃÇ|ñ¦”X®À4¸¯UÅú]Ó–æ3dƒ8Xí,}Z»ëÖÒ8þ¯fÄ’ÅfÏëÕqËÚvTËÙ=ÿò8av0 \dIMúKà_ö·Éÿú©ûv½_MÈO[V\ÙIî·ó!‘ðmÃé{übµ¨›¹;wEùžä @¡æÅ[Cf̸v­|áó³gWù Yº=Í;o>7\³w=,!mºFˆöª¨/dT)‹æé—ni"ýÙeƒâÅ—xÝ ÜÀm“įUÞ û·ÝÑ®që{ÐõLü®ƒ*¹Å ¥‹¨¦Q–%ÎOðêÌc†¾ ëª|1 õ²"nE‡àm¿O¿V$;8øô•Êý±ˆ3úm—©_rœÁºä[‹…Ç·ÜÇÍ®£9ÛÜdeK.ÿ%õ…sré%%¥U" rôó|VW%ûdCbtøz“1Ó2G)JÌ„µç³·mpK~ùßú§Ðox‚|ÿéIüÿJSjƒC`Ë·t!:ÿÙ\lB¿G,Ö§ìŸ÷Ùb¢öÞôÔ­Ê&K*¡+RݺÀ™ºv “§“:K’Øg¦JpW§›ÞËbàUÛG| ŸrÕ¢yo/q†$WÎFÕI²ÁÕ' EÚDãEskä·F{\vÚÖ|ù¨êç ¸÷QsYع²¶â ô.\l?ü5¾øÄ \q ¾í›¨ó1Ko|°b‡]%¯W-Aû²ðñ(Þêg¢GcŒÚ†gËá§VδÏÔy—Ǭ¥…•{òñ¦K[#•?-gù-ñ »"”ÈKÑýŸ–eO®tŽ_É™©±^¼¢É?ÅŠKênͦ¦Fô ³dÛ?§vyˆŠ®Jé’«JhU*MEjõ®æTÏúÈ(tJ¦íKÆyÍÃÔ5YA¼#b‰1âj’ÄFóš…'!6ÑÛlýO9Z‹‡ç€›¥êKÂ,>Á¬Ø9q’ Mä·hõRüëRκNÎ[õ:MÞIK©~5FêÂþ±ýaSv`ä„_?Öîž•kB“2@ÑçÌ»$,— ®?ÜæÎÕÓKÃruXLŒ¤¨ô6^PxeÎ[å'RTù¦ÑéÁäûºB÷‹ÙQ!ã2è¼ÅdÃ.ž¸¬=]ìòÿ9ïkâ)Œ£Ûq&…*¡MìN½nநe ˆvª–Ðó»ö˜\ž‚*fKé%ù ¼±‘þ*4ÿÀ{zõf§q>ÐǤôàÿ(âÓJS@ùØI]›Ñvv題øÎΣ€V†'¾‰3eñæEj„Tw‡UóAŸ™&Ä:Ü!dKÊ]Éd¢ý8þcãë8£ÎYLÚstqÍ/.Ìœ¥i*º+°}¾?æWÀ?éo”ÿ°El§¥n?ÉAÞºåNÊ“¶©"‘Ò ô³¢°â4ÿÌÙ•fµ”ÇÁ«Z_HŸDªT{}U5W¼QnÀt÷|f‘äYÏ"Úz7^ÊNIûÇ6Þ¡Ë#©ÑO+ª$”kcm€°ûs†m/z>4·ÎäMί](ò04dhyD×4Ú¤K7y{Þ`Yž¶!\NIJ¥M轞_ Õc@>18_ØKcîfMsÁËo“­† NO®Çe82upV©ÒŽF4kp½>‰ªÈHsÔûرBxÏÙÛ%›!Œ8p-)ŠO±¶˜)é’:¡KÙ¦s ?c“/çÐ)~ÀòÛɰ.µtÞèé\“°FªG¿¼üëýÓ è¿¹øxBñoõÐòã¿\#–/Ùô§L¹ètv±yé®cð§xHþzô¤!‘ã«n«ÁÂKÝâ³…‹oOJ9DÏÙ ¢gKñg=‰Qµ˜-GêÆ­‰!W`+ekù²ú˜ÙbÊã¤Fë»—%¤ßvÌøÙî| `ËçÏ’¦ðŸ¿cö\AµÅÛz,3 Ïˆâ+¡jÛ# S£¾M(W?ßì‹Yûr”\µÚ,TÞ Õ­þ'jØFýZtù ×{2‰¤[5Û~ÌÄ/½â"¢–ý Œ•¨íP­û>mËCÆœ±»Ù* æ-T°ÖÀÌ̯íªíiW¼Ô®zm›lSEQ‡3w½¿Ý]q=1F}oœT¨½Ä«æyëW(ÿrT¦< $“ãúíåX®îµÙnÇàsŒ'ìvè$¢C¥sWíb½øÃñ×8‹ùÄðÖaçêU`¥ñìì½õ×Wv/0/4oÿ øü­òß#n¾ºZ­Æimh:Ó"V¢7ñyEµP‡¾é©z“}åù/­&j«è*¾Ï¿uàû¬“ÍŠgžyò…míþ»è„º@e¶÷#I’¨Ó1õÐÝ;5äó9¯YǦ´Bg» \n$½HSH–;=áп§‹ã“<ÊFp㡘ÁµU”WïOÛj@ÞM˜d]ïÏWts&<«Ò¯1üñêçö'X°ê.Ûåšôy³u⬠ÖNãͪ†¿–R0h o„àÝÏ­¼%uŸU]ÝâLc¿MçSz Î'øø/´îÞÿ¦tëù=tÈý9ÇwžZr¾aqd%%¼¤x º›3¸,5uEèφ®øýêò¿ñO+ ÿêòòþÅ—°za– Ù£[ôN¹Œª¸¶o³*ÍÐ^5˜t"+¿·–ÄÇöžÂÞ D”Kù¤_ÁÊår)¿ šnÛg74臷œbùK¡ãYüÍ& äU©”Jè"ŽîSæxÖ6üQnõs¸2Q–xo•.åñlÊäqHÞJ¥”YõÌTŸ N PÇ2}í†b)B$¼‰9‰O™èlã{‘1u›R»Qn÷¾ò‰g¢Òï†&v›ív6â8^`j>ŸÔ¿ÄJ@Ï÷ÐßwÉQÎAd½%³×°öèVəǘöL'¶W@©ÃÑ^‰È–½P¸ón³ŞáÂÙÓ¥Á6©«ç-/ŠuØ}åùÂÎK¡þ¢ÃØ€üÙ´?3߇ܤ+§ZI0ÃPÕD Þl¤Kâ­—NZ—iôÁÃÔxÉ¿ºëù¬/5íBè9Ï;%7g[ìV€×Nûy~[ß!u_ ÛX›} õá½¹0„\ÈUÏ-SüÜjÁ¥ê¥£bywIKÖq>ÊäîÍØp]à™l.Q œwÞÏÖ‚.Œ]9sÒ®˜é”¸Oìú˜yŒ#öEµ;ìÙxy–²¦ù*T˜u7“”Ýù+Î8)Ù§\Ê+™ËoKuz]æÞ×±– Co¶$õ(­è¤%Ï«“ò±ÊI£h‡†¼Øê © 3õPsƪ*²ªòSëÚGD¿WÍÒ«qce£0³¸—c@ËÑošéT¾ë=ó¨%¢ž“….Ç™8Eé)0ºäÙÖõèõÐüÒFNÒí!Oð[9.PVsÏhn¼éu&íf±°QGeßXꫜ&BÔ»‘fÎxä)^Ïøé²|¿:Ö»AŽIד¯¶È¬<®\w(¾É³‘ÛVô¹YD’ëÀoíéÏ%¯†×pd\/QÁ®ßý¢éAPgÛ1ëRKÂÜÖó@(Ƽu£ërÁ¦ç•XÅ-ùó±ë Å õÐÝž‡mF¿ë¶ÇšÛrÍâË£7É &S3Ò¤S¿ÊMÚJ‘²"¯‰ ^)>Í=Ûh»p{®Ñ›DþY Q¼oí—ÿ3‘RÃ3ñÁõÔФTZ¥žÄ&Ct³ÅBK†ë|—ߎå7sC]{íjÎÜß™\¸^îV(Íÿ*¦Xyç”°1E¥Ä×´•Ýï’¤§ƒ^‰V01öö-7 žä¤î¶Â‰¶\$Ä6!ñ–]Œs.z:ý„ÆwÂ=Å}ê¤ëSs Š'©RÉÆL_ “„(Æ Aë×ë~IÜdcÉŸ{k}óž” E÷xÎT&·ð cõéã§BSônð”ÄĪ×õÞ­e:³N‰òÉtüÎdVr[Òôxi•ß2Eòás²"×­Í7[ÀâˆNC^„aXÅQ–öË=Å!·ÄÌaè€~ÌN_Œ½ÒK÷Ì֪Ƒ煩Z§‰M®œÎ2dºêü¸Œ_Go|±:N±œ‡ïcó,•ÉGW^ ÔÜbÏDaÆ#5®G7‡•û”µžì×…R/.}Ê’¯š¯ÝÖÄš°.$úÃñWçÞT”yùóÒ‰Þ2‡ ö‹©ôÆŸOÞúðü»åßÝCFv‰R«!¤¶¦Mh®&ŸPó9]¢^õxqº@%ŽNÌu³ç\ T¦|ZˆÚqÙ¾á‹YÄý¯˜ì^µÄ±$h›½ºPTw[!Åë ,r¥ÇY}°G“®Ý½ˆbšNbÚš?)ƒn…z 9=QûÔÒíìC½"òèæ©KÜY`ŠæÊtÁ%X‰pž{ÓÔPÀ÷ê¼¾¯ÅòÍû²ÃØâ^+²Á2}¨ú‚hD†}'p£Œ• øØLÇ7nüÍ-yê½µ†üFÔJWî×á*W«žp×î;ƒj³ùŒI ÜÚ28&nYEm³~¥¿Q£8M“GóW–´Zý×€'(ð×ý~‰ï§µDî×XzÒ“´vñˆ¥L):h~!Í<öÇv ëþAÁz>B¥ªÌ“‹ÌW2·b/0SD¸ÐJø-ªcµÚó¶hbj 8£U2äÌã¶Ï€È¤JšŒÖRž­ƒ¨"gcn/mf+“Þ­Ç.Ît9 ™´1¦Oôý· ŠÖôR òèuWEÝ‹%fx4ALOw4ÇÝ9@¦¡ÓƒÄQÛ¬ìÛ£n-õ`±9 åÉû¯¹Ýfu˜)7æáŸ|VÓq‚¼d[î'°Er…³ ²`¢¦'Õ¯¬$tðoMá7YL'‘ŠzûR…Žé#d^&“Ù—áU?yÕ V‹æÝ^®Xú ܳ †žõ Óz5äÖÕ¢Ï8¬«.…N2 eÉT3¾H Ñq½y/Z+l1“ôý'ÎrÆKmwWI´‹ílLEmm;ó—ŒÎh·½œômImgâ{dSœ(¦¤K¨kߺÀÙµãE3 Âa”HÇÏ[èJi‚¼¤(Vueì)à+‘kÑJÌQLYÉ{ºF~Óÿü¥l–äº}xóEAÏHZe’_?ýªf½Iœ(ÝD6ìû”p@ÒoS­DŸ€°Ø û^µKÝùIAÜíÓ¨°ã»Uï­|è_8J"ÚÏQ9¡ÚÄð& ÿf¦Äøkti—o| 6²—3©¦»Êq°HÄŸ¿‹—ðý©û/&_‚楴¢4¸†¨ÞCgü¡¿ü' …©wÒÊè¶²´.FMÊxîš>PØÁUTÀàñn$¯n¥tqRŽ™šµÿŽ–®uàVH­ù‡*kÎ?˜ç¼ ŸÛœ¶´^„ô ·×+ßìÕ[UN¯û$J¡H´®tqN#EÌ$gÄFë›GQ‰ Mw'Ú¬ø„Rï%ÈÙNÁÊÕî4 {[^<™¥¢§/åQ²xéË.E«†Í÷×ÝŒ1º>ýùãÚ¤™ÄªAäBœeë c]Ð{Æ S¡7þ;ÂÞ@§epý¶.kŒ±ÿÆÉ° #LíHàÜt6¥}E•©y™¹¿¸†(_}G" Ëå©Ä;<0¨‰WZÀ¨¡:÷-»×_Wþ'ÿiô”_ù'›§S œ{ŸÛµXÙyåÄçO*•»L÷¸wÆ=—)Am/Ñ4K9Ó¤g3x¨ç¦Ø‹ˆ#Hø –h€žŠ>Bt±¯r—ø:¿L6Œc ÇLõد;…£Åà©ô}æEë7Ä…½˜&5É~oŧM>Þy÷öZ™Ì' zç­ºÜbÅTŸO8p3—ah¸ƒŸ·ˆ²Þ_NøºU'”«ƒ"ðAS%e祛 ®Âˆã Îõ)3&™ç÷›5_΃Ù@²£eâQßÜmÈÁk j7¹¾µ[4,l綸/ 0Ë çx¶Ö |ö F…_™Îy¯ŠçŸ¸¼f9 $K3],”©žø0 Kxábû*3µ¥[ˆ¶qFÁì–¼±Îzxõ\AüÝ·¹õk(B¬„açÙR 4gp[“¶·,´M}î*Çž¹WbûrÝ¥EO°]]—™¸ÀBH+mÙóqÍCÙ|§œ®å»P½+ßL܆-o‹ÍÎØpßnkÕgðÞ“áÅ•d”&¯¨ÉàN×ÇÑ(À­>[ÑeÞÓS½f@Í~5MüŽçýóXš4Ö‹‡´œl°IMj$¿œ];Cÿ8´´]9vøœ‚žXÒç4ѦÓC&¤B ØóË2u†' zZººË¹?_µ¹(æ|2ç%J¢²JUW7>év´xÏEkf¾vœSÆ]GM=sF-—¿1Ù¼ÏýÃñ·ñ íõجèN ÖðÇIŒÇÕëbþø“ýoÈγFC¬µÄÏýÔvjscɲ-L‘÷²bû “¨G‘”™¥¬è<øsĻޝ—KÈn–&Ö(ÅÍ‘>>yã­ü+€ õ¦Qž€›½ÅI¶Óì¦qö>C_£¯­¶O>VÌ O­mÊeŽËØ|)Ûg{{‚Ê2o)þ"úKjü³8"ïɤ‚æZè_ŽžìJKp ê(e;j•È-è o\Ϫq‚|†½e j*ÞúHxÕc59µ= Õ÷%{™Ãý+ÉÆ—ËÅû'ÎñÑlfÞÇ^%ÕâýeåèŸV@Bù…˜k †^ù,lº\ƒÜl˜Ð-?`à…=žqkM`÷ê5T0…죅ÀÑгÃÌ—¹â¾%ó“±zInW–á;¦kV²e?qÁÓxÕðàmv•`Î*™žYm’uÀrB9Õ½›•׈<¦Ã(„œ0”:Þɺû³ûR ¬H+^ˆ?ÍË»¬AyÇa£H—Àý†$ ÷ã€Ã–Ž„g«ÆéÕM*ò–‚2uެ 54…ƒëáÄ«¡§Í]6[bØF –;¹nHÖ¼ ¿Z;ý>ªÈRAáYT]¼ »ÿÆ%ý'¯0n?T¡ƒ||âøÞv· @!ÞFTµŽ˜ý„¤‡÷!]1eLøFÞ-ÏÂaÛ¯¦4UÌ:}ýÍ–ÇÁ ~FãœÔ ëé2§’ñŒI0–P"©‚ y|×”P©É‰LUtÅ_Œ¼Ð`^=÷ÉŸƒÿDB¬Àn>¥£š/V?*h!æU¾ºFXlËåMGˆ å€óýÏM©+¦Kè¶àGµñ/í!—ÒÔOËÈ&67YE}õÿðàK¼…û µ}{ì§Ç°&("ø\Om,†Í(w\ îaì=Å>>z] E»y©µ‘ZªI†êIªuý¹k³âÔ‚Oîׯؼ ®×'2¾¤ËmaÅfîW­÷Ap ‡ó,úZ¦m\Äyª`ö…™MÌmÏ·†´£þÜc\JFgŸ†™•H­~è‘RÝ6ƒtQõI…›ŽLõ%.Ïg¨”â=yÛúaªïª¢¬y¹YiÐdâclV»Jn¼õ‰†‘•¨¬v¹.oYý¸lÌWñr䌷OMˆ•ßdiÞBûüåÇ_ü+WöpÑÍoÁ—õý[ŠŒ©Þð†ýø[üïÈ?}°„oó"妋L^@v¿¥Õìͬ´Ý‘4Ev²*í¡+•—²¬/ìpàZå ~½n}jk­·SàI×B‹¦Á(½ë6Öö¥8qÖkïr îu½¶ %»u‡øäªa¼OÁØ~Kß =EçÒ/*ÿeÿ´ú3Ê/û“À‹Ê‹×I¤™ÓzY_mËÐΩ‘¿¯RtzÞkMdZ«dn<³%*^³Ôtn¦z³»®P,É+Çî6ž×L¥Œ:ÍW°[ÿûþÎØ² ßx5kw`¤<ó¯›íRW’˜ ›XŒÑÛY‡ð\Üâ6—_ö;àé¾ê£0­_¢àŸºœñ5ö2]ºêf$IèFšjnˆ¯¥v­LˆW\ÑŒŽÌM<¶jY6Õy¨‡(-Gê·;BÕ™™—Œ _c‚^h1´Þ$ЇeD¸šx~Ä ›J?ÃôpÙ‚Ÿ±s#N;§§È'lÇIî–öR¥>…ÙS"Í‘Â÷°.Jly;©B´ù#¥L§*Ðî DÍ`u©bŒ2ämÞ7UÇ›}{î ¦c©–î¦{´1ÛtYSÑÿ²ÙÄR¥&ºüjÇÁGoêLßô$|囚ø¥¢Ö˜Jà<ý±6A˜$nÍ‘Tp[o:uYõѧ̩ªÁáó﯋/Pùs‡WÕÐëÇßN4sKígÌÍÜP.|›G÷†â…J;A…—÷Ê{î³NŸ™EÂÜMZäªÒYœVkâ‡u(ƒ»KOhÀWðö8÷vñ}ÙÐ…æ† y õׯÔ/ ½ËÉèØ½~—˜@ Åx üUa„ÖiñŠÙûÍZªn”¯P)™<Š›ħkm©dÞ`”Kå(] 3  <ßÖéøæCøÓ8zÕŠϽPÙ¹$¬¥PÔ4öá™öÔ±á.µyãÜhóæŸ:OºJ5tÜCDy³„öUh•,縊_/f(È5ïZ™âCô‘T‰Ý©§l¥8þ×ÎÔ·§ÈêçšR5¼Ë–.7õ àŸù¿$ÿ^Ÿžp4ÖØÚLH‡S˜—\‘¼†ª8/iÛ$YµbÛªSÍØ|ŽÂ‰Ó£ÚÊ}bX†Ø°N*‚Ï—#t»”>E™K9DÊ;ltÑ·¶:a¥Lë!ú`•T9T9£_÷kÒªn™Pà ¶ÏV·çŠÎóÔWÏ IG ¥ìèdb=ÂAW,Œ»nm©³$;¡ZÚÙ/YuþÔÂ̹!C{ªÝSæ×Q1^tŸ¡šò7È;ñHºu±Ì[Q™Nw™ù#¶©gEGüTâÓ¹{—ÑÇú5­j‡¬„<³a±?^ÿ¸ÝŸðüG9Vì…ÈRzöà'z¶fQo¦¸>ä,·º-˜áÔ%'KHÌü%åÿò?­€þ”ðø%X›gflw«µç”vî玙þ… J‘Ìoî6 hYBÌA3”†ˆ}9)Ý^÷Û`»BA^ ÓïÑ5ï-¬<39…cäN¹[°nN™ärò¡‚Y«AÈïÆðè­NÑ÷¨¡§”†œ¶Â"ê¾r™B'Kß"BUãŒÿ\¡¢o‹ƒ»#†õ»a£ÛîK¼ž„Ê-nM8çÑ„Pr>Ølõ¡£Üñ,r;ùlñ›ï§*Cÿ'_šÕÙ½^Ž9<Ç»çáK"Q?½ ÍDƒp²fÜÚ=™¦Ð\¾Û/+䈢D–^¹¡‰¾òI´ÏØž—OÅð=ËzùNˆ2~=qëkož!¾…æÂ³É“íæÏ¯5Ô±aÇ…]¹Ü9¿.jÿy×÷âãê­aqÒHƒgAržó%òœ¶‡¼æ®±Å¹b ‡ds©ÕðìJ mL¯_?}™×¦N}ø‡ÉI°ñçdÖ³*Q—nÆ’ÓØžðÉKì_Q$5z‘ŒiD\I=ÉØ:É|#†íøÕð;Ùk4ät7 …Ø\ô©™;¬ˆ „ùCQ”“Yõ·U_,Ó¤>–^—«»Ùb'"¤`2\¥ƒ¡ªÍª/¹|2‘Rã½lº±‚ºÉ[?Xí8;·fÓÇKÕT}¡¯û©uKMèæƒÐû—yZæX+1|Š(kÎWävâ–Ö=ýÔ¤¹iÉ?‚³ÝÓÜÀÛéGs@*¢ NÝ!™Ã†‚õ6R°ÉW¿Mìa§%–a¡Td}0¿Ç÷Ç-;ÉÕ6n›ÅO~)øVòÌøÆõbù(ßø8/¿Ã0[˜ÚXÖTˆ2¶žé£0¬)©ô©hFÚŽ?…Ø-é.û–<”–€dcêQêÿÛÿkò¿b~­€îÉ ƒOœ½ÁbL]¼´ÜæÙz ¸Ò•Í[uU¬«¼F¥V ÿàÁÍm¾šÄ@Ã5Ï vÏŒ2 ý8XÁ1w9S¹úÌå×Ðr×§%b(ɢ䎅dLRÛ$›‚†ìtΖ#@ •#…ù±#Ÿˆ•^‡^©À8·9ÑÆmzªª?å¨alnò…›Ppkû¯^æÅ¦"kMWR¥u’ÁÀcÑÜqŒIÕr¯ ˆ'ÂÕsoæf]ãR6]½•Þ†Ÿ¯ËÆ-SV‚YN«‰ž[n}™¼ÐlAÕo©MÐ=áO A·ýå?íŸV@Nñòþ—tƒP2&Û.JKxö=+zNmÑ5ꊭëðÚl§¯jÙöjæ§³&¬I «¹ü‰úõ‘:DÎcMÆo2ªT š>pMå7u¤Z6ÃX/¥ø§ªJ7®È’ÀÞŸ=!Äú®Ñ”Ðæå#T£[O Ίu羜#_bäÉ|QRsýkš4Mðp~sHöL…¾Ý£sÂËž/Æ]7F¯‡ƒ¤j–ÎHœYãa½ói ñsñ¥Ø>+Ú£ïg[n`éŸ'; Mx}dwåSó• à$Z·»K,ÉOÜ.VÙN)yi‰iÕ“íGn7:â1jv¦H|¹*ñTb@þR´Ÿ†k,6¤$¡¦Ç¸ÆâKÓû[húN…¯Õ_¿£X·$ž‚2õòӥɎƳǠ$ÙïÚï” Ü(#/ëa@Mæ×æ­Y4’œuIlIE ây—»Ú+C ßW\²íÙèï¡b¿æ$+3ß‰Í D/o«†6“Þ9;æͱÙý`Žÿõd3uÓ¸’¢ß‹dã<ÉŒ4 ¹…\ñ\…ÔÇ\C&'øNµß“ù –Õ|ò}²ËôÇkc‡:wïÆ¡Li*nÀ^CóË× /êgÙ_@¯‘ágP^èh8«ÅQ;q2'î4ž?i©ÒYÐÙ4Iµˆy'ê_>DzÌLøÆ*³õÅlBFٰݺו’G¿åm'¿´Ü5¥0ÜP’gj»go ˜Ê›âOȆ â7ŽE}0m+E{›(ц±vGK¬Å†aÕðeáSV‰u¯RIÿ2ܳƒÊ ïV‹Ã–Ù_/ÈÕRuø_|‹Ú”Å3/_©OÕ?'ާGRÀ‚Vô‡ãßMA çF)ýs‚,à*VE9÷??Ïÿ¢üwcÊÓùå©F¼þÖ@y†±Ä\µŒ¤;’ˆBB¢ãê;© ãþKMΧ©ìó¤ dÓÒèÇsœ7&KÄ&n¬ï¤d*<ÅEªvEWµ }ª¸!uòœ‹g]CcïÊè¥z嘟ïãZ÷Ȧ“½Rú;ø?Ÿ´igJùÏmœ)hDñŒ“Šu`a×KöFAošu°œÁØj.V+·4ë”Ö¨òµ»±a‘ùµwE0ùiìË"$¼9­¾ÊØ]þêx ‹ªVH>vøÎíŧ\L•L-Ûî‰m ².´D£XüzòÏüO+ ÿ¶Úûÿ×Lõÿ´xÃ7 äû”Aß§€|¡­ i ¸û„úBÀ o¯ä°-è?Ù Ѓ3ù>2rp Bþ˜üò{]`ƒ&ß›þÐ÷Ø1Ü¿d5ж?ÞÑÆÇºtùI äÖÛ3vüÈËÕ#rÏÌûÞfÿä÷-|´ Û{L@ø“‚€P(±Ýë‚Û¡ðWj? ùäáè ƒßÿ^=|oˆ<Á›¼öNìŸß;†ã ÁÄÐÞ{×øøï?½ èþÜÃC“ú€á÷?³×v0?½7$rBˆJŸ½Æ o¿?Ÿ=üPȾœ d ‚à°ÂÛÚùþøOôPþ}à²ÿ¢÷š"^ÈÞÕî!ú‚ÀP„0 ð™!ßD(ùní½ð»Úb08þÈ= ‰?ü |Ľ{G¾ŽÈ§¾wgûò·?ñp÷À„!Þ[Ä齇à B<%ò}GvFµ Øàwá^Cäló‚÷¦òÙÃ~GðA—=ü]~'ùÿåÒß¾ÀÅû÷±þ¢ÿ7\öhÿ’=ÂÑGéÚË%ù™#ÐÛÇß÷ öûÀGˆü—=¸hþØ r¼‘·CX rŸ!…@~äð‘ߪ( ò]ë¸Aüÿƒ²@ö= Î3Ç(ÿPÀî~àDèí ó…þ ú ðá•á[‹W´ß>Ùì=#äÌ<ó— B¦! Ÿòñ €AÁ"Žhˆl8§€=ý!àª@\Ñ©4á\€ìç ñ°ôátûp6‚kw8ÏÁö9ôÓÁð¾Òƒá†ò ^·ƒaæôöøÓñƒA€Ú( BUÁ1B< ‹û¯¿Ï0ýOÈ?0ÀrT#÷ Ð}£ñÈÞ¾¾ÞÓ³¾ûÖåžÚ·àó…_‰ÿ^d·=üá*¡ÉA0ð¡Ò†w9¸*|°?ô!À"Ì $iâÍÄUsí½àp5Pöˆ' ‚ •'ò‘ÁñßGô`¢@#è÷‘ÿßFQýFåw Àõÿæÿw÷ ÁT(rLü*ÿO—pÿ}÷ à õÿ‘ÎìýÄÁez¬üCG·S¸ÿt¾¯4¦|ØçàZG©ñ„Â(þ€ÿæøQðûeþ£jèîëL®[€§Cpˆäg¦ÿ¡Gài“!‰Î äÀa¶žV¿þðß!ÿþþHO©ªêbxâA*òƒ<¦„°$Ç/!|VÞNaþÈ=òmøì ûó?Ôó`tXÄó?píáOŽÿþ!hÿïÈh÷#f²?aXý›ïÙûøÃ£`Bàøûÿ.òÿþÿßQ~ àGýÜüGÜ!4ÿŸðŸ; Ô÷€fá à{ŒÎÿý|ûžÖáØ?:‚@/·P¿hö…©8ì úǃÝÿçÿŸ¹wûÌD0àOùßpäÌÁpsŒ „Bþ"ÿß§0M 9*½Hç„ì‡õÀ Cõ zA}ÁàC¡†ïøÀïÿ@îüö¸yâ{ݾۀ¸ òp¯?" „!ùÎEzÎn`ÂñG0"T À¾·Þ3øï+À=šõ€ýáøßŽ „+ˆ£¡$ûˆLc ü}À‹ü{ù"\[ t(‚í¿Vˆ?Øàž÷¡²GâèÊZûáù=Ó}ϦBì÷cNÄñ€÷Çù÷ñÄõø#O#ñÿ÷ñxªaïþ!H`¿i A€ã82Ü·`n·~ùÿ=´ÔïW~ ¡ÿÌô¨œÜÁžÐÆZ7ùIøoŸÍ}¼ößÍ;ýl){ðWÿï0ëáâw¬fß9ƒiû#ï÷ ÷5Š˜(È ýñìOÕÀ¿NƒCKñ¨ùH´@O—¿c¬ ô@Aÿÿð'ðÀÓúÿ»‚‚}Õ€Óã ~$ÿ ùk87Ãã†{„‚äÿ¡üwjüi`/ï ïšá‡4°£_¨/ì°æ¹¹Åød÷2½Ç'ȈÞxæ‹¡ˆØ"äCJ÷¹¿'ß@ ò]îÿ’<4ü÷W¥ ‰>‡A@Òý?˜Ù÷õ|Gµû ¿G¾·Þwåöð÷;ˆº‚‘ èõ§ãºç_Bÿû`º9ÿøCþ>ù‡@‡¦âw£¡…‘ËöÀƒŒlL¸n:°á&¸5‰ ìá;–ÝGxìpüF<0røùDPÏB.àCàíáÿß_gpÜ øO–xy#¬dk ì{ ÈÛòÈÿ¯üoÓüæå·°¼ÿÿæ?¼ìÇõ?‘°÷Ñðß~?€ÔÏ÷/-ÿ½"ð†Žòÿœý‚‘c QñÿÅ1™t;àÿãÄÿ“#¤§ û± F,>l}l»GMöáÁ¾ðQ½ð¼®§!ås+$yÿ߃‚Ç7Þ@ÿ#k„‘ý^?€ïq9G,Oò‚ùîû „q<„g÷FD¸üû}Äþþ$¿‡gáK¬@Ð}§ê€Z#*½Ý€{øïÛû<€:þQ!ˆ–Зn_8àwàuí—Àö7Ê¿§¯Ÿß_ŒFàO÷ðyC}‘ïß‘@©ìáø %ì/ëGêæƒ7ù¶"ïƒaÄÿ‘ÀìÙÐ}ûïH‚a?¯\nˆ¼þ±e0„¢>º F|p`4†{ =üƒyùÿ_ùÛÊo`xËø“ÿcnÜÒF®Ðú¡Q€ÞÇÃû{ÞžŸ\áÿïÌþ#ÇÃEèÇåF{>NAûcýÐëÐ99táþ]üÉ â:ÂÝ?6þÓÀ>¾?T}ß‚|ÜnG¤ØÿÈánF†B¢…ßÓ~pmor,ú—wø9Ï £é<ðANÏŠüè0à7ò=‚…?d‘d€ˆhï`H÷ÿPϬçC¸ÿwÁf{ÌŠÄá~4ä`¶·KÀÁ—pÈ /bÏËÃïÇß}d8úè€ð€/ðf诀?èo•¯`¿cª ùn>Yx ìáïß~F…ì›wû)€#Ð÷ìþafÀ¹ à»&í¯ B7Dêtx´áþÀãñÿýdÂ3áÙÿ‹e>îA¾‡­÷M¼ÃpÏþ¿ºüèÿWþ޲uù…Ëqýÿ/\}ggÏ݃þÜüü%ü‡(@øG+0ȱʟy}Ǫ˾“È>û8†"=éGvº€ßéz¬Áá§A> OèÿÝ¿ÿ¿¦ˆÝùØGÓÀ^®>þß³ëGXè‰ôýþÐw÷€Œè!AûyGäRlØa`𻹿W…øîxÐkþ á ˆÌ‚#ÝrˆU~…Ou?.°ï¾!ðßão(èGàááw` €÷¿Æ†S”ÇŸŽ?8Â|¸`ìÈ@Gீ?ào–P rø2¼V?¾(Ȉ><š½§¹GÖèCÀ Çr,»¿¯Î‘þ,ìçñÄÕöãÿˆK L øå|@^ŸÆÿ‘¶ÈfrÈ>hˆ46îþ~HX¯¿îAžöróøµåÿÿòÿoùÕCÞÇ>þ9òeÏÏì|øÝŸ&„ÿ޲ùÞ{ð¥óŸ. ûKD®3~àn/çýÏ¿~üºûˆÒø|ÿ—¿ˆ?HÈ÷ôÜ_ˆÿgjà¯i` Ìÿ¸]ÿƒ.z9†øA×#6nŽ ûI»cÉ>ø‡M~Ð}±Ü_ÕƒüxŸÎÁi@}‘ ÈÀäÿkïZšÛ¶ð¿Ì©½v¦§nã‡ø€Y¢íÆnO^:ÓCÿf‰}aAJv.V8‘™‰L“%z‰}|ûíbúƒEfzîøóä‡ÿ‘ÔÕz]Ø—ÂPšÂÝ’<Óø®á˜_· @øŸ²²‰ßQƒª>wù?ŒCË6D‘o/Ö óæó¿»Óæ¶u{õq÷_Môäè[Mb ðß‚¹ÅQCÙáE"ØâP„çXÉÓG»òæqVþ•í¢·Ð÷™—«ã%ݦ‡vyöE30O7¥ßÍô¿òña׿< ±«×úÃc»ÌóªˆÞ¬Èt3M± Düן]{ãz)ùÓåÐiÇß{—Ll 3‡)‡Ÿû÷S„”Xò÷ˆèR؆£ÊF«FA¨ÍméÏ\þ—Žˆµ8ƈ£ú®?ü»ù›·ŸÿÕݤÒ?=j¯a¢<¡þ©U_Êé—7[ÜÃ6|RÝG;“ü=rAô¹/Àÿ‡ë°üáÿYàOØÁQÛç"ì‚0 µ‹' Mñéq½ó½–éûÙÖì”þˆû˜k®“jæáÿ.à?>ïL9ô_œ>°'_ ¶ýÙͦ¾Ï³¼j'äßìµøz»lš½s=Çs³èð þoLi`Ðn•9FwßÕ7·Ï»Î …ýøøØRñUqÛOLƒ{99?0}«¾O½ð{ð³bpš‚µÎšmëÒdŸe* ¯ ûˆ¤MØ>ÿy&jã˜Ét¶)¯ ¸~Ì•–BtfÓ¹ü«IþN ªüy\üÝ)潸­Ùb…Ö§¸\ÁLÇîqt”>š»ûQPPþ¬°Àÿ©ÄÏ$ÿý\ üé[/Ý¡´!{’¿SÕõ‰I}×W«ÿïüÿl+¦Ü$þ+ÜÿødÅö¯3ElÂI4•Ù-Úˆ¾¨ÿ¹U[ÒÙ×î¡ËG»ù'rC¸×ô?ÍÁ;@4³³¯šLò*JÚ^^•-°õgùñÌ,\™çÁ« Iö!pJ-AñW‚ •“bḀ|~"Bq‡ïrhƒ°–@àÿ6“¤ñ(Åü‰Åç)ûO©Ú,µN}Ü'ùK¿³œßE°nQß¹üû/}èÕðU±ù—§™ÿnÏ}NÚ«…Süzø‡tS±á =šq{ ÷¡‹´&PŸ:ü0•à†Iþ÷m”ŽÿS(Ÿ»GhÓèºào•Àü §É˜äoV:ÿßù'ÙV ”õlÜŽ¸ÿzJ#‚D-aüwµgøO½QkW†m—\ÆqêPœ=ó!{Õ¹þ?F.ûÑÿdü·0ñŠ€µé³™þŸ™ú.t‘05ìÐkS^ŽãGŠÅÇ¿v8SJö!ÝŒ1Š7wmBð‚SíAà( ú|º±±_NR2ù½UaŸdîQ‡Xtë­PþxMu—æÁ;å Ý Ü›ÆVöÜåÿû8$šwœ;ÅO+}¢ù_õ[l÷š(%ia©xäO=‚|3ÉŸ@xxÀpŒg?“®ˆNƒ ¢?Ãÿ)X®¨¡M¸E ÀéD?ÃQס VJ‹€DS7`xß$ÿí*çÿ;ÿïDÛJ=€[bÆÝÜå׺`¡  ëJ‚ÿ4û7Å Šé5M¦HÐìaÅðNÇrÝ¡èFÎþº§ò¯œ,¦ÆgÚº>¼ÿ5Zÿ'Z÷¡Àïˆ@ºYü…W€Ñbñc»¹|ÞgiÀú‡Ƭ(¹êx“@7S§§ƒ%;xI0ñêÚŒ;|;V4÷ó ®#ù«â¿€ðX¶f¥ ]W¶ ˆ…î×±÷?ú’PÍßâ§Ø"œ¹ü?ÿ]'qóãßß^þætó7´ÚitìC¥GFöðQŒä†:óÛ~¯ûô&„ŠMµ'§¡™Ý^|Šâÿ·c¼<æ d4{ˆègn½Fs.÷oowƒ—HÜ¥€L ÃIþO+œÿìû½oo¾­Ò¨âCŠˆžrÿgº@äu«6³iî_‚ÿ(Tª«»ˆ6ÉÀ—â?ÖÔœùúòa²ËŠÿÐh´³‹Ÿ8Ñÿ7Õ¨4°h|¿-ô?r”Á´-W€9b\}]Ð3TPÙËßLò—ÑÛ‹áÛË¿>áü7ûÞIÉ‘þœ þÓžåÙ!–ÛÝ”ä/d%GÐRzJ-Ê?𺀄ÿó39ÇÿÍ=.èAþ0š/K]~+HnT=£Wò3€øx1W_ݬoþÿJš-àpOxœìýu\[û ƒtwJ‡4(¡ Ò!%Ò‚‚¨”tKíÞt H‹"‚4Š‚ %R ÒHHø°aÏý{ßçŸ?÷ò|f3׬Y³¾ëêkæ @þ×þ[ ìðñ…žö(~mߣ¤Ó¶5t'R(Zí(xÉs•éÀ£•jîm ÙøæÍÄÒŒßðéMK–(¥_tÜÏz>»ÁϺà- ªœ´Ä0šïÒeŽwáÑ­¦1wô7ÓÚ.¬òå[g©{™"˜CמÈÒ [Ã…!_ÍèôÜšyµŒÚ‡2úè+”®…S‰•a‹Þx$Ù(3-kD™+V$v*Ä´Â4éoB±~Ñ7B!’·EÛÿ¹ ?ˆƒã!EÜÙðqÆêŸÆnß¼­äåv›íqÔ4ë €jo¾b9uûq0¦._ŒFÍÙIººþý¹6pÅK ¼Ö`uJÙE¦Ú2àÁvÅ] ãÛ[c¨<÷•ªésEÛÏ®ÕñWïl9•h¥9L¿£d—åè÷¤{?»[ÎËž)@æMoÅúŠŒ²¸5Ïæ¸÷”üæ´ÕŠ*LÊk¤CBþì”RPÃ$X%&‚EßvÈ­Ë·õ~ g)çpéÚÖ[-´Æ[¦0£A«„à3áU›ë—ˆ0Ú'Ê™îa¢¯^ðnh•õ'šÏº/&‚3þzeãIe¦yÔòK¼ËQMç:çúš- ¹¯ÙÄG÷±¢4& ¾ÕT*”õŠ|ý¦È+JŸ´<‚ÐþMçISã{ò¤1X–¨IÝñ&oƒ.~ˆ"íŧàȹ¡Æêu=!ÞU©|F^£e =•J)œìõÜ»©Ä9ÃQtÕű­DÁ¬‚xÐ×)@}XÒ¯‘ü-Fµ‹ˆvúÖd¼Üã÷©ž&J*•öçÆŒƒDl‹yd¤w83.?øÆ?FÞ¥ÞÝf*™<™z­”´ýçsÉ’¥¨5M¨þrüÑ$Ã…Í~JDxÿd1«:}üIþ«ü_›ÁúZP—É®¬ïŽ_¼8õˆbPË‹5úÊÉlÝlíAüÒv6]Ñ jFÖ.D&h¦-„s ÇÅâ.2£¤Ë3À¦ 0ï•«˜[v¸îâ9_hbR+_I…¾Ø $aôäÁ¢ŸÚîªï»Nîñ%4¨à†z›-¶ÙÇÑ+?¯ÍˆÄsV|ݵ‹ÌŸœç‰Y>úIUBœ+]UI­µÂ5è£XÜŠXâI/4°†bm†òp?©QÊÅ,ßNR¢°ÇfÔ\¨ ×u(]ÏÕ‘©»Ù9íâyo‡F&\ð NÂ2²!Dk°6$ļ™ª]0‡fŽo9’z.Ø4á]—Ÿ¸Hù÷û¬6pÔ°ó Ö±E£±·&Ó/çÂG*ä™ýkô×¶fë‹Ì u¹ŠW$¶ŒPcEf,&¨®ÙjE¸Ì–£›Ðu1*hY#ñ„rz{&ÅÊW*¾tI™l^ád$P UªMÂò˜Ö>Ÿq¢ÚÈ”`h(}ÃsÑ—Ôx=4ˆ•0#ïçF6& ÖÓÄYô3Àˆ ŸwTLˆïR•Ð ñQ¦©]} ÿ>C#´¢C?æ740ÞQÞ±!N¡@+;vcÜ©ýüso—§Ûš+¦—z?¢ôHÊhÅEUU¡¸Òè<çG(ŸO3:c=yu+o>0>ã…Ñ•~šÖ ©;%@ª~þqæ) ٲɟzb׉Y晨¦T¬ó¤f¯Œ®Øm—dóÕÉ'Nmçô}Í¿št»Žº *ÒŸPóxøz¥>¥iê˲9Ÿ8GäáïÉ(úìH9ü6§´Ø›ž£olñ6¸ðÇvQ¬OãßοŠÁŒ·Ê=é|MÑ£\êBòre2Gu^%¬ë/ÇßÕÒ>Y¬ Ëð)ïÇéãþ¿Ëÿ-K¼õ^âC!&å\úª$$CZ×å½*(Çå8Ô¬tbg¿¾œ7ê´û¬[Ìøú^~¿ÐùÚ°›·\[1-¯ØˆcòÙ6$ §@ée­¯MäвÝv%¾f.B·†fšqÍT£D³”ñqâûWs}-4 ;*:L·äMâ¿wæÔ§™ä>m½ë}é…Ý$ö:ˆž[j~W}{¼D˜ä£Ð׫(S¨2úOv}ž÷é«ÂžÎ'YK~N‘ÀÇrÊ»Ð!û¤r÷ƒ=Ög•#&ó Z²«Ä²r`vµÎ…om7:€Žˆ°\pM€ŽVÄHžp«Ù!F^Ÿ™àûŸÅÿE§­€þ²ð€úÁO{'Z‹ßd¡Ë`C~ƹ‰¶ÃÚq‚î‘u[gŬÍfÑ“¸BÅ|š£÷tj„@ªsã=lËžæE—„s®ù¶/ a V†ÝÉÜ ãå”úááy;à[ÎurOàUY|§OíVè5 –)ï>I• hŸƒ0v€W¹£ôsVV£—2ÔÈ=ïÞËIu™j´D»ùŽkD÷Fó˜ñzªí ñ’¾(F ñþ^áç>ÚϤ€xî¢»Žµ¾ô h·F¯íq”¿önڽŕ8%†áBötà^ïfœµ‘öÛGƆ Fú#úÐo”dUê·Mx뱕ÂÈø_¥a==Yºÿømñ‹,B@qæHµçL•=ŸEr~&®r´{ƒLëÒíVz©e JL<—8}ìSC|©hš;¯Áa)¤)+UåIgŒ5þ5ê™§^ý~ë’¶7ýø)“X,4ÉèL­ÈQwYLfÚª³õ'íÌ$}¿z I ´Û¶ ,¬wµiâ]Îx1 IhúøyoE—Ð)…“¿kÝš†Ùieœ’´½ÕÆea;n”zÇf%ÏvåR$„·³GZ¸d”#BBíò¹—„¾Óúe5O3ëj¹ÞÊE¦5ÂM1uš /Ë©Û(*®ù,'r ÄþðÛUTQ ™¢àÕëØØ(]K®¶üÚcYº3íP;ãš­µ¡ý.[3d·–Y%³ÄãRªk¦ÆfKÿ^#|%FÍ»ã‹LE·¿`þ´¢ íÆµRÃsê%| -ë;­tTÁm¬õz KÓ„ö¢rá’í¼uÖÎMV÷™±o)­l¾Á/ßô¬¥ëéT\pÃÿËñïùš-h·²,Ò—³:uüÅþÛü/ÑÅ Çþ–z ïªúsÅ7ìõ¶rO¼*lù7 ²åÕ„.£q¹V†ÿdؘÃÐHõ6Fmƒ£™Ûîø4+ÊåÙ0ér‹Æqà›çá PrQpì\tVÌq>ï]i¹YF­•CýVRe¡•#$RÁz‹Þ,KtkÊã2Ÿ» <Þ´6QóÓ"°F3EÆtz¤*°Ì}}ÑãÊüÝäò-O ˜’ªòMÉЯ\I÷£ þüdÆú9v[VUÎ.È[¡ÃUúÅ’yØ Úƒˆ\¶ –25ÆI1È’’{œ1ÑRÈvçÏ8"žÚ‡ÝZToÍeRÕİ8iÖÎÓß}„uUÜ%µ ŽiÐ:ç%û'ñÿÜi+ ¿®yzÁýþœ$€»xò÷Ç|Üæ/E¿ñ”)ÐÞ§qHðü€â´heÜ0é>œ‡Y!k!ˆõ¢Cε*Ó˜Íä+tþ3•Öò˜ëÅ?Ax¼Î)t=tÂÄÒ®ž³ŒÅkL`K_~HÏÌ.v6x3Cé‹wq ‰Ó§wë ¡s¨ÙÌÝ(‰dÕÔ âÙËÁaï/}¡Ü}"<ý¥WÈu²¦IAØ¢Ïõfg¬…†jÿ >~æÂøM‹Ê¹ø‹x‘I+fľÛéì$µÉÃ÷p¬‡o€ ±¦úÝ0ÄI9”Ä+¿ù~ÿ\«{ÓZ—‡‡ñû@Ìî3­¯PúDKL‡¨Ò#Ñ™N§X Ž|ñ׸¬5°<Ù`¡ï•º†D¡ó3DôyK¶C×>ÑY¢ZtéªgŒöê2ÑaeÅÓ °¿x¨Ÿ£‡ö@÷Lw4E^Ú)ì‰o5!®õJÁí•ñ—‰ôîjìñ ÒódÍî?ý敺n°ç ‚V‹ËFÙÑ“#oŸåu 5š±=ï![ób¦È°t bÆ‘a=§£¿\ùÁ-ŽOýe]Ìå´ õ¡ Ôüw´‘Ϩ,IÞ†áôûòm3×÷ˆ)†ØíÖQ)’fÅO(y×í~GwsŠ\sÐs¼ôéÓYÿÝÝ›r³Æ4~sIT%5‚è×™r|uVû>A’Èójgx¯‡ÜUVgŸh ¢’=#ý#ÃÛgüL¾\î꼎àÙZÏfY&¹GÆÜ’«ÆœŠ&¹JëçÌÈs­&úi>ÈF í‘óÅj¥©”ô _ÉmµÐszP }.||&笔i×”su^úk夦¯²Ñ8]¯cj¤FDTZplë†ÕØÛ~½ÿ—ã/á _ã£)ò8[S{êø;ü÷ù©¹;y¹êEpV«Ò£úÞk÷…Îô=Õ-Fý˜ýùì¥ [¡9)£W¤´æéRQ\_hʼnгfG5Xâ0ÕRv«fóõ^h¾[ÀXô`VË5d­t¤qxùús#'É×+Þ5©?lÌt˜Hôè3nÕ]Ô†9ÞÈ2‡›'ðãY&•¾Se©¢ØÒaw_ ‹^æ*ÛªH”$ÌÑÉ߸~Ûi4ìÆ3mBï¾·*œ—¾0ñÚr­Ã–F›â`P†Ìé$8çàÍÒV?úû=Æ×ni µ?z$ŽÉ­ÊËS9pŠ·èkÞ›µÊzç'è‚Ü´'ó¼UéíRÌ»¼i^×ýAütÚ èïk` ïiâ°¡º“ܨ\‚xkÐåBeP¾1û\äá™}&8Y¤AæÙw LëÆðÑ‚ðî»áûBƽáDW‹øRS8¾ Š^rI»5³Z¶Ñ'®¼o_<ßB½ò±ß‘èF}ÙÝÖßÖ|ÈÄ^   I‹áƉ²†-špYÝ`WýÙþÐApچ棾Áû»ÞÇŸ—áDWŠš†¶¨^®‡ ³†Q,èÆ-æèàÐ}¡1&·}#¦x°Vo˜±œ¼Àó§çN¯”ëøVø#Aš˜’È`²Z(oH°>kŠvk4XÚ>²²\…UÎÓõók°zŒ¥^óâ,¬þd¥r“3±^,)je]=ÊRÑfÛ>LLœ¬‘Æ.*¼›”ب‰J?︛è §tŽ8ÌW)Ò Ùw< ÄŽÝ¡ã+³zns-u×Ù\M’Ü!?Ê'Œ ‚ã̘®Fà¸uÙQ ö¥‘—þþpIí_ ×B"n§ ÖЀ%axÈŒŒxÀFêÜê˸{ò sŸÑ7 Ì®©™¯¹Æš ª|éJÁSŠæÐ}æõ É†ãÈ©Êz >I¥Cï)ð­q¿Î­Ñ‹OU‰Roa§¢Hb¾F Q©cäýÓ4‚ìžtBj=V|tòÛÆìÕTŒ$’‘]ãd¬Éß=·ß?sÙ4&ý0µûj†ì–­…d{Cäù‹\ŽÕBŸ$@=°Ð€º+hSœ›ßf=*Ks"øÞ< 9×Ðv.œP¿Be—YE ýýæՠ¶–êÁð„ŸWŸ Ï¿ëU”1˜T(¾7à-®JDc^~éû@ˆ>_!à-V£Anmc½cæ™ÁEuãïOÖ;«ÄÿrüŸ][è’#ø¹têø[ÿ÷xø©5>1ª^:§•ncÁÕJYÍ{,wV*1_Üw9W›X[š¼Ëš8ùƒùåcÏ7œ\‰ªË·‡%ÐçDƒ–¥tXy%åjYœ×äkŒ;Éb„Ø*¿¤—m´û«º@gúq_)¦~mHÊzÜ‚*õ¥Í}‰oØ™Ë _%¬ÝÕXÇÜ'Ad-÷Ø“a'_ýÅOCŒ7­PÑáK%S£ÑŽM:$ÔvéÜ¡­áŸ%}>àî('9 ¼ºVñˆBJâïÆûl'µU)†êiã/t*üÿØÞ£ç6^ BÛ…Š3Äj–Íôx–ÏžG/?ne[¸-ß©Þx{=;½Ü9›°5´ä̰÷ØÅ»%·Çu"5nRлeæ ]nš&š”{0»‚ÿlv¢‚z÷éH¿AKÝð;…¹Js¡ÙsÊiI™©ÏYžŸU4>»,åëdñÄ#âËç÷µ¸Và—¦Om¶±,¥½r˜%éátçĸµŒ:ÚBÁ–dß6«XI$¾¹X‹í)Mÿ&•óõ+ˆB÷úVñøºõ‹Ó e¸³òÚ—6¹t#µn)Ê ¯2}|sæ×›§U!da=MÄkÌú/qh’÷ ùD]}Þb?ÿµó<¦Üv6•ÐÂÿã§­€þÎæå óƒö Í‚ÿBÄ·T‰ 7úˆLFÀH%ßgï%GÐ÷ÙŽA'ýÊÏ·¶#íÃè¯<ûȼl9¹z‡=x¾@•Âõ[_Ô ïž3"åײsO2œûB V>ùÕ8Û‡0äoâZ@Ë#Ÿ ÚÀå©YÓ <3Œ;½æFM¼‰®×Œí\vôuÖ|¶ÔIcüLŽ6ô{^ m±úë;¦C©²hý.šÕLeämUëPR»\íÙÎqÑX¹Á÷·Œp@ß èÏßï´Â¾ÓBÕŠ[Õ5æËÒWõò‚ðËmX9ñ¸È£+ôQÙý½£OÑîw»H…9 Ýù쫜O×7ôóû4Þ¥é /ãPÑWXv÷Iý¦xàTM[ÅÄy-1õú“_ü¼Õ=á,,ùdÀÀÖ8!ÊšÒj>Þº’C…c{¥Òx­Ûõq†f µ£ƒý‡ûW·¼0ÉCõ ,4I×UähBVË¥qó¯=LVË-5qf;t¥Ê4'\ÇjóÑA¢ÌMõ´Ð©®ÛHû¦—Ã2ˆŠS@ÁNeRÓ6ùpn™ŸÃíl²¡_3&œ4„3+ò^"(ûÐPöšŸYÅ]d+¹§¦’&ŠÎí±û1ßAYŽÿ¦q‰z‡,VbÔ,Ϩ™ÖÓ™á-ú%%Tç|da_ÉÝ8í;Ôù%º%ßó M|W•vF×’%ªqxÊÂõßözrÌrŽùUdhk]&b¼_yyæüïÇFgC>àW«'|òNE»:%ÞÂüÞÖÛV»Ò åzÅEôûó¹V#¯8ÆÏ»û6+»?_/R Ä0T|M×ì'ÞGÚ­×g¦UªG‹§“eð+ã^ܘ[“üËñŸö›ÍÊ>{Úø7ÿ™ÌoVi=T¤ßr®¢ø&ó‡#¤{Q5ÿ{ÍÉæg­KæüñgTáïäjž¬vÅ‘Ž'õ”ÏÜ”-Hw=¢/%&¾™«„Ѩàµ]+¦Õ–º˜[½Ê¤÷ÜÇõéQòÆØˆñ¶R¯KBΗ4FrÏ;Iâ _›üÆkk5²TuŒù3øÿúÿtØÓëxpmD¥šó&ÄKÅ!³êÌÈÕ‘œÂ«Ð'¿wµ#KðÑžļQÝÙ‚uçÞ¢ÌóïQKäYëBL¡«)mºPqòîrªb«˜TÝižwÅRJX.Ï Ï] dÍÌÙüI]ö3Q„ʯ+„t|²ú.®í»>R ãÚž Rµ`ÚŠäa‹7‹M‰ÛJVEk½•QJäúµRè|PͤÓO½.ñËé¾o'¡ kEcjö ̼¹*è‰J„rmRü¸‹/©†I7Ún”`l7…5¶ÞP¼ï„æÇÍ*¹›Fv«SV0ªñFXº;šÃ·v6Zð×UÖ×£^ä| 8øŠ«„"^l†õtESµ]¡Iê.Æ]^¤eŠv«µÌ)hÓ­öÚ±_ ,I×?E S“tiì†is9£ÃV†µÞFüˆ¹H¶x§Ûå štyNÖJ¸p7l•}p°ŒÒc}œV d“)Kò¡Ë‹}x•–bfðÌ“ÖÔu‹B«>‘ À‹¥ŸXƧ)ú!¹ 7¬Ç«§†Ã RîçmÜwaEøŽ­¬-ï4e|'S-œî+ÆYÐ äž¾\¯Æ¤÷¾(Ūðò7Ret¹€’Ÿ@ª­˜Ÿã•«ŸLJ2äÝgS6yPÈR™G4¯¸!è\Áñ~Ñ/®C!rh§²qÉÐmèFIg0ÉÇ1È7å"£ #NÒ÷¿PãùüÓÆŸÿÔø¿Á®;õ%wž›Ü—O²!}»UÖ>öw‹o¦áuÒQD7 ®ŒÈÆ’Ñ×’¦©ÓbÈrz7=¦ùA3‹ãèO—¨3÷%[´ÿÕ‹¯XÒÔÄ}F*lĦ7%Bc¹ï§‹ê»Eþ„} é5Qv²º¶Èß1jQÈTA¥ÞœYè,?ö:ëÆëwS¸ 륒qΉݼÉn23@oRÒžmh |íS|‹LÖ8­—Sº©„êhHÍÈr0Óýõœ„=×ÄÜÀ¬EvB£A’Aå÷ºjAÑ{Æ.wÞËËy½-3#R©wØÎuÛü<¬ƒo4s«å•x…@Zœè Miˆ²‘ðöSŒItøÍRï î?ÿËN[ýµ äòõ9íA@†­:[MɈ¢\ÜÌ«&A×óKx”ºÏÝ᎛ODõ]°Öa€+×!P®:·`~¿½ËŽÈðüy2Ò±y/2¹Œ×4qq¥aÕ!Œï¶L•°t©<§êuÛo~Àö#¼Ý<ü¯)â› ‹tþ ”a+Í×+f9Iz³ÂTVVmžJf÷ÛsRÞw;{wù_oa+”-@ò´”â’x¹¯9hb±=S!¼osnŽìFBíwÛ„\|¶­Ÿ¡¨YØo7™Dò7î.AÏÇ^¢x ÌÆJÜÍÔ=óqšç1ºÙçwÄh²×ºú™Iº]¿]*Ùòû"ÉŸ!DŸM— FM-Š7ßüŒm÷¾ö0Ôn[å&Jv!£êá®oŒéd8E´$ñ'‡J'ÌÀþ^…Ð"}‰†÷ޤrmx˜«#ÐKwŒ×|rïÄ h>úq?|;EƒÈë;N=¿ïLí®ºÙžÍöÝèþg[»¨²8I9L€f”‘·Øx£f5YásÆo9­…Æ™ Þ aÒÑ›s{ØÞUHÅ u;!<‰ðIÚ‡ˆÀ©üõºrö€á³½NÁòNþ+EŠAr ê/Ød“X?ªâ¥”4žÖÍàÃ>Úʆó_E*i<ÂtâÕ‹-jœx]—ËeõÚó;óËÕ¼`6á™.á©gÍBηæL }Ÿ^6š‘b]¯­™—dvÔœ”òô zÔk«_¼ûu;K¶ ¥-Ü‚§.8z±šõâÜ–Ö <ò;¯dV©e=\˜àoÈÞRQx^}ºž ¯ñg{F;b#\åÀ¿(­ëOÀøRƒÕ~Ïÿ›O"ëÑ ì‰›¼§ê0õB¹„8’[åü*ÖÚ_Žÿ}ÊÊÓÆŸýôøßpˆMú³?q«é»Rj«DÑï?>”žý¬îMn?l]:ûµðº™}ºvr k¥u•|ݰâÀê½” . LN÷4¹å:};º¦¾²Å™(OGëß™dk6\Ê6i•ëómWNwL3}ìdÙ“BÔuÖ͵y²Ù™ûŽHЯˆ…Y±h¶äÝÛåóÖð`Á7æý ÷.ðíökáᘨ:‘(7-ï4‚*ó;/¬rêÝÖëT1¯Y;K?„±¿`1l`>X?eAjh#ÊSû´¶§ÖëFÑÅ|±¥$k=òréu†!=Ú·ù›æÚ¾ªJh7¤ˆS¥Í§Šv¡þÐþøÿ´Ð_Ü€SÐý›ïL¼…Ÿ¼ËW} ×îæûh³s_Cd¿ô“i¼pŒ9w{åû#‘ä€w8Ë…LÞSEZXþ‚]«4¦=Ó7±ïïÌH~Ý!»àâ-p¹f'—óÑÅúJŽ:%`¢P%7Z¤Ïa[¿åÓÔ¥¯Nh Å’9~ÅkÉ4[.oX¨ S)Nš ä+¬}Luç½ÍέÊD’‰¶ ÉU@O˜œaþw¿ucò״q±›Ð7«/fÏÛ¹Nçjë}€®“ûE‰Ð0!ßÉÖ3»p>ÅÏÉu/Jœ4À×Ö& 8“£|ÛÈn=U§'øZû™Æi0ù–5ÕƒHÅÉw*¡AW~ÖŒB\È!S×,W'–îo§5WêÃQd-ÞÍÂ>Í¥óec¡h¿Í˜²ÚZn±ò\I*-¨Íæ'Ó¢=*±,«øÌ­Á®Ï›Ñ9ô¬\ñ’ó©¼Dš ¥0ÒÈ2wÓû PqâWK-W7/³ŽƒZÜ|Ùá=\/^3½lýÈv}®§ÿVcõšð.\dV¤^K|Î+ŽW06.Æ´[÷¹„†™“ŒR4H]‹ðZõð˜v}Ê,ŸÂJýÏóÒ ü+zZu §‡ìýÅc&9n½½X™‰Øüiðj…V¤Ê…RåeÖ,‰™I}êö‹ŽÄwE(–e,M¶g£Ä³;Z9E/¿±¡DÓÉð )ÂÆÇGêyš-?o)*Ä  k„]ŲÝ%í÷8ŸÕ»óZü£!1¹éC}tçÆ¢{b¨x–~áï®'ÍÏ>»ò~9âËÕœoÝú¬Inf‘š=SÄ:ç*s™Ãðšö“Ìâmö!~v½uÿÃÿ”ñ÷Ú…Ö'P® ¯®´ê†¾¬l~öŒ´%Ê?‰¡ÀK¼OQy›Z¨È¹d…sâkæÁÎ}¯Œ½ú;t¶ÄáãÛÁác#oç›åÞ—)k í>Qi¤×ª¹~æî‹^à¹{Uäf ¢§$çÇñŠè8™ÆÖÈÇËךÎû%Áj“'ŠñtœåajÀ!Ñ]¦¹òHv€nJ’ï½É õÞvŒ›°³M§Â)럿»~ÀæÙýÔGió‰Â¼¡3 Ë^œÀvôÖ9¹Û¾«ÝëòœÆï¦€˜šOñ-¢³W¼Å’–”cœÏ¿¸Lï7Ç£?Á1rKÖ¶·É³K¼‘2D¿q‚Ç;ÿ;R(í{¯°Õú棵TEÒ¤?dÊcïÌ ¯w!¶x×Ýw«k,Ê^V,c=„‹OòÞûÙóÑ›Oep3ï¦w¹LÕš”’”qn¶DíN³¹¿'/žV_Ìsveñ^ÔÓ¿¸–}c2¡±(÷þx)¦í„'¶FËloeÍ:„¦!¯‹D„õñ ÓLk`Ï- f‹ »¦_ß0öB/u:c}ÐJÀlž7Öu' `Òœ2kgˆÙŠ2Ʋ%LãÒC{HY…vgJ*ˆÿñHŸ[bH;©7•×ΪwöX.#eÎÊNÙÇÊ»c\S”¦½CYOrB³ÍÈ<±Çí–eB¥A¬Ô/\9Å‚ú¨· Â?ƒ±#\·"ï&Œ®¿RŸ•í´kŠ/\Öq‹Šô<“$¾>”PhÀQ+äR–ªë€Ê“¤Ž[T[/í´5»z¡(nõ,óÄe1ôz9Êt6;¾™îãûÒ™|Iš…»†·Î»]Ôø DMÍ©gáÁrÝ÷~×\"GKh~frêÓábZá•$¤3eé1µ©èëL©4´8Cç9»kðfJÌÔšš·Ò[ßâÅÑ7íu‰vÌʘÚÄ}<ûYqǹø|Iy†M‹Úá3/™Ûž1ç6õ†Š«ˆØ o(Ìß¡Fó¨-þ¶F^'¼ ~µè‡.½NåÉü7«Ft2ñ8¹F®j›ºè®)wŽ-­Ò«|Zü`½m¦6ýï¥ÿÃÿTñ¯:]þÇr¬¨¯&m¹3µ@[ziù±r S1®2”è••Ð’:{—G ¸@«åÃØ…ü÷oðDKæ…$œQü¡¢Ûò*-bÎ+ßã nð®×1šÒòÚæð ÀîÉ|Sòî¿JÞ Ø*T[Õh­ð”ÊXUEÉȺ)¶Ö‘*UM|?û…(®0Cæª=†0b¹ˆ‡ûññµ§Ñ…äo9 \Ì^v§+‰v²Ÿµ_ïkô|ðnw> ÿë^ê`›rù¤¶8Ç”ŠfõE±òëd÷ªÅÊC‹É Ùîq9ßÐnzÏ•Žú1Â8L·,œµãN²FJÜ+.õõ kñ.¢;R+`ía]ÏàSÆ_þTµÏ_ßN½ `ì~Ûè=½PݰRJíâ¯pj©™‚âgë&ÎÝŒvà©7K4¨=G›ŒÚ ¸2°n¿ýdO¤Iô6l“¿àO+ê`Þ„þÙ…,Uœ-`VI–þaÚ%OBçO EÑ0íÑ5ë§¼^ÑØ?yF+ù=WÙ¬G”%ì{ÚePŸùmBׯ|Òlø4^èšoÇ=C7“àþ•¤KÀ¼TX‰áù]Ñ€µnëõSW¼i&¥tÙKm‘6Ÿ*QŒw†€þUÎA¢¹ ¤#óË œVÓ/'Ÿ™k°‘5 ï÷¢õ{RãÇÍ8Õã#ëË•Müµ!¬0dž?·C~2gìý°J˜ÐÉôU„ž÷G§ºùh”óÌÔ³ânÅ»|–R2Ò`‘Žr­`’¢‘;é#…Sã÷i\1hÊü.C”JÝO¤‚¿q÷{’´Æ!nЊ•t¢=K:®Vy½ÒdæbÇÿQ&1CnÊ,+®pïÍ&QI÷©ççæœwX`¢èÌê!_t>½;?xþž†Àý±çp­¦ƒuŸ=;û!Þ&WæïÒºA9õ…WpÙVò׋2~” íÀŠHoihö»U†õé¡]žó ׿t(?pM­^^\¾àÎAIëTÓŽ×t=ºðŽî3ŒOq*557”Éå_Úp½ä j ü»ñ;UücO›ÿM\= ÄP¹\^>†5t©šàa‰¶ÄÿNQ/ŒÁiVk.ÁB…Ò\Ã0yÁÁâÏG®{öû|ºsKÎòØê[ÍóÆRô¾9¤M~‘½m²ŸS;œˆSÒ”˜HÅ×ò9<‰UÄ}ï>Ε–u»ZiœAÔûžÕWûXß!z±+QûŽÐ} •^ÞzäÐZC&ÕwÌ*#Gl·¶¢T¾Ò!/¨2’–å ±«é¯ØV“Ž2{’íNáß㜽eý%)¨æ3S²W€Ëe}I§2/Q ÍFŲے»†·Ôoй¿o«È ùÖõ÷]yÈ\‹C×#A‘„¡c¸A]1÷SÆÿÒ)êžÿ5È©—¸_¡÷ɹ/Æ5µðƈ¶­SÃxœ*©W÷åâQ| = «äÅGÑø(¬¦?rU(ãåb”,µbˆL›Ô¾‡ÁDøß÷®øÐ_ä[÷‚¯ô2>“bõÃ☩ë0^.3Õæ@WËÂk7ïÄ™åÚ>”_ïïp³¥{ê}؈‰WøÑTêƒï1gmòòÌL£F†Éü\ñ&¯ù««˜ì_/»ë?¢Öé Eòó2åí7ÏuÓ˦툔ð² /ÈU0$Š]—Üñ®rM¥U·ÕŠÌ*Eî>¿L¸=5~¶ðrÄ:Ûì’ß´êGðB¯ €ñ,uºµ2} WÊƳ@v–ŸçÍ"‹T2oÒãœ_ãÕGM·ÍŠJ/¥¯½Ñ4üì2 ;/‰ëô”)î‘é“Kg¡TþÂÁôÜ¢åÙ…4†tÔ¦¾1r‰Ÿùk<#7çdÅ_+·¥Ò¨æ'¶ÒZã€_è­í˜É„mi«X±Ëòeñ›†À Q¹šaZŒo`yRýþ­ÙøO…¥×dnãóúYúº÷\œÛDÈ1³5(“K_Z~ÆZø=Mµ•½Åw†d8£Þþ•:£\©jz,7$³G% sw9$ûQç3¬á `}³´ðËŸDk¬˜Àá¸Üìf…[©†2äÔà͸06d›MÔžÿ~Ê4ùFA4ò/Æ_š“…çñ¿têü/–—ÆV\éÀ!/ÜÊŒc\(ó¢Ä°$®GÍ«æ<³Y-Þ˜ZäùKç‰hÍZ̾–;b%þBæ¯4èóÙø6Âcׂޫ¶B·FÊ´xKÜ ¥ìå>ªV¢ß´8+ø¨ «\Uj¸$¿] h‡GÊÜœyÝu+y“v*—:RzÄ(𥋄AÔðñ]Ó 4µ¹¢r‚-w!vl~ê*ü›‰[ÍBúSåÏq¾¯\o“Àæè½x·œ¾°íå²IÒ§¹:T¸Ê=Dß\ÑÊB”¬þyüÛ7uážVEÞ2c&OÄ$1lˆI²äk¨%¢{ú;ª™?¦ÏTš~ä¯5Kù,X'¾´íëH~ŽYk¿®CFÒÔÏ»¹»ô˜ùˆ…™ÿŒä%v‡}Jb†Oëᯨ\=gÑÓeC;œ”¥®^õJÅúViH]FM5EXoð£#ÿ|Žv½ã _8ºõp«áõ™ì+n¯vݶ6C⨄ó{çæ©_lÙ'»Ïšs‰ gJ*â…`hF}-ÓÏMz‘Ê¿ŠQÕ,ßñeù²"Êðh[c‰r>™Ù&¨XvûÖXk‹3ÿˆ'qwŠ•iÄ·ê[slÀ9?AzãZ4ÖÀŧEÀx’*›¢ìéŸÙ©Žàåžö/Àékwmüxò tv^&˲“|Nä*ds}•óþ¾êËYåÛ9¢©a›]Š>Áw†^-%{oì0i”úšeL)'+U5T‰ _ÀË݋ֱìŒçÿbðµÎ²TŽfKû /ït3ËšûÏ8™}áu‘4ç–Z›ïœi_Éœ ,ÍÔnÎUz—Ô[IWéc¾ôR÷Ý„X*zv}RÂÅYY2²r§‹¿ñi)žÿµãæé÷=¥2€1Ë÷²Ÿåøð¤ÊÙˤ™ßÈ]€ÂÑsÉbç Ž9„éEWE](zꉖ‹FwÝÐ ^Ï0£+__º"•¾ƶq†"ÿNþt:hú»‹£ŸªµÇå„2òÊпzaª½ú.ÞðÖçlð9¡§Ë&%ª l9¿åŒ~ý꺮ÛD6ýÍ|„¾ã=O)4ϱý™/¦//«b ÿL”¢ êH!­ž/1ÜQ,ñ$ švßeTkW —¯œ§Þza 6àz2ÏhöZ-UÐY''ÏÄuºÎ UŒ´"ãfÿx¶­>é,ˆZLnÄúoú²©Æµø¡\uLHk9Àn¡â‡ŽE“´šQÓOLïî/n“ö$Qœ|éZ™ñÊO·“HfFA(Ò\­ÁüÖsqªÔÓ=nýª7Ýq¥|ãR¼ÅЧ0£qÇWcû–lY¸oa)¿{Ú¹k·Ø|óî3¸¬Ø]¼¾Ÿn§œ%K{¹qþœÿKpE‡p|Ÿm{ŸìÁÍ2z 9¦Ši±¬Þ‚güOÃ_†2§kI| êÍXø/d|ûžDß¾†õThÀÒ1íJkqºhž|eWxC<\¡o°æL¸Ðè(;Õ$xübaã±ÿ庯Å%:›yI?Ÿ]ìr¡£÷¹)a ŒŸ"Ô"Ò¸£¿[7.èÄ«t§)‰5‘z1@³æúz·µ{sž³W=K‹|X ÄØJ—.Cý ³b:¯²¦ ©óö>ÕrAÏЦU¾ä¼˜GÁÚå¬J<¢× ‰cí¸Zm1=¹ju´m°zÉÐ:.öEÍ~en¶0#ŽqEÒ¨MÙèÑåÊ‘aŒã—[(ß^m2òüVH¬XfÈ€þ-ø#ÛSJâ¯-þͯù}§…?ñÁÿ”k7ž:I]² íÛ}­äkáðòv>Ak4ÑviÃ7ÉQéçW—ÎXµÚ3RÙd º”~h¦™–g¬À¶[ž,•é‰X{eRÉ]f!Bײ]ÔHPóJ É'c¥*üá%ú€Nfzk¶^Õ…%–êB>O´•? d+79É-Èp‹5Cv7aÂÖBÐÉù¹—ú³‰ùzNj †¼ëozyÖ ·¤×éfŸfJe™'\À³4w½¶àôŠ4ÕÕõ“pæ´#ϵ¬òZ¨Š”øS%kòtSyM =š´À)*{‹·TÏözŒÇË#\ÜŸÞ>CºøÜyÛÅ¢9Ò¡Ó7Û¥ðtñÏ;µó¿öKC|ØçTÊî«ÒIc¿fæÞÙaNhú.ÑkõŒö–ùõ‚yß•¼IEÛŦT .O“ÈqŸ©Z}|ב”³ø¶<#–D†õE|–ÜšºBÏå³7i;š?½´à~¸«Íu”!-âôœl0Ÿ¯dô°Ù±ùÓÍ„Ú4¹%kþg/Å*m->Þx,ŸƊå7gJ,®º¡ýæ~[¿ áõïL 4Õ²EÌW t¸oºåù|{JM [*èI0j¾Ƥûö“Rrö>r™K»*õÒ?¨&Îö ÓDn„fÞDÉ»‰ãI…¥oõåmJ`¾;™JteIï;/#ë˜.Ž yDtÛ¬a^†ÖV»÷ãd4Çy; ¶¹6g‚¡A’³’¯kð%‹2v4ŒŒÒ‡Ý•IL Èâ{ï„_]Þ.3º‘pÉ•HÝõÛmüë)ƒN@j4ù2¿G¢g¤2±õJ½ ÝÌ<~F˧žY­4–Œ´? tEø°0Ò_‘¥s·~£‹‰žõíÉ^dÁ³öÙaØÆÂæú¿s/Ž_p³>òzX­÷ÛÁ'+¯ˆ1wbz8/Û¾Ÿºråú»etKpèV(sàe¬EDÿ›¬ÁÖ*÷Âí‡}èYWÈtTýÛ‡_Þx*ñ2]Èã³\ˆ†­˜í}²Ê*v–ŽÔ,½÷Á¯^Yײ¶¤&}Rw"!Ö®Ôø‘[bºxãž»[&П°†æºP™Ž9å´tûœï±júWœ5ÄÉ<÷*¤W·˜˜H#b·¨[®‡w\S ¦ó5I>±"‹ÍüÙ™sU#ÿk¢îO6»J¾|±°®AÕÐŽç ÔúÊE׊º|üœSïB…ÈdWþRü¯Í¿¾ö®R~øtðþgð¿¤5ñYŒc¢³VeÜ¡ÝR5lòþÍYÜ»ñ"_óuýýô xJVÞÁ${²ýŒÖwod]§Ôì§­6ìí¨'AMÝ$ïÖ o^²»H‡ÙõT3²ðíν6Ñ<§ÆW&—õùQŒvhm:Ö0mùòGTÎó3Ž?€IXîtf.¶n¤Ùm½9£âíV–b.–®—(cUlh±· sv†¤®³ã¦Áõ¬I}mmW©¯v„´ìú°¶Uèýr—Wœv^ØÊUÿqýˆwFâ/k3IcèuK5:Xµ\o¥Ý*»«úMîz¦¾}i¾á•ÐOÝF‘Íïá“8òŸ2ÍJņ ÔËž.þÛ§¡tþÒFlþ€oþœl^û[ƒ€¡GcŸÜ?1æÇA¨÷Á>ÈË9Àþ1 ûÇU /€/üèà1ááÞ‰+ŽAÞˆƒ`O§ƒÿkÒÑ1 rçðð†ÿë ä/²°»WyñüPð/ýƒO^sÔôèA!ìæ·wq qEô³7ç`Ĉý½Ñƒð°»/â©'WRB@0äØöñGôºwkÈÞf¯srÔà½00ò@{#„ìÓì ó>èä鸇ÿ>Í>xŸ †Cö;ïÝzp‰ûߎ¿_ˆ7±€‚]\NÀþsý·øâã C.+0äp´·Ö =ØÛ{Þ½a#ÜÞ,#V"d_ØþÒ!—ho}€A²ø GÄ”íîŸØïvÿV'Aˆ ÷fÇ+=òùß_à Ø>Œ@ØÉKÀ°£~ÀðžÇyÀ}ϼ’zo»! |0¦ÃÎGðŸÆÿ˜:úÿxCXÖŒ{!{\xœ‚ø•çaÇ»'EÄ»"–û ¸„¦/NPüÎÿ{wq‡ùIŠ#Iýmï„l‡Á{:äñ Ä÷×nÆx$œÏ€@à}5óä?ò6‡òÿà0ðàaŽ©@ÿY ð=öòü&íOj“º`O[؇øñ0€!gt¨ãX€½rtHãò=àὂÙþ˜ÅÃKÍ †xÀýƒÇò|,)S¸/4÷îÔáûzþÐ@ªô“¢)lj}_^à´ À°£!päÞ¾\?8æþÛñG࿯ž ÷N rêÿ[üïãGN8ôÐø<Ú;X'šAz€¿»Ûþ¿,&d¯3Š\¨Hƒ`o-#ð?0'§õá¾–ƒ=¼‚öõßþéƒç#Ïî«áýÎöfìX±àE¨Ö½? øÞ³¸ƒNèù}ê;ãà®ûÀ!•ïÞ•vÿÿ¡ÿ‹ÚŸfê„=ë}ì~#ø¤(8æÄbÜš{àåò†þvá¿8xGÃÃ÷à6'NÿFwÜÍs…ƒÝ<ƒ}þIôŸvö8cOù@ÿ£üGJã#ùð'ÒÓüUâýuØóÉS{ŠóÀŽ;ù]M€Ñ`€›C¤?R.îÅC‘ÎÁ¾Lï›æÆ>¶ì÷&}ïù=í‚<ü]AÅ r,ÀG,ŽpŽ.’§?ôˆäÃÿ„,€úóPïCŸßýG|ìH„þ?ðËLø#+8 ÞŸ«I·/Í÷÷À{øÃÿrü£üóŒÓ&Q§Ž?r8ùÿ%þ÷ ðÞW<ˆy9±P à_BHÙ׈ø{„øÌ Òi=¢Þ_‰Hóqa—Böñ?4,úúˆx@·ÿ‘Ò>û‘†Ã(ÂÁÅÈ’æÀöC¡ =_ÝË3Ò¦8˜ç =TÊǶÀþ6ÿÿIºèïh–p¬ÿ÷V7‚iöÿÕüÿ]€÷ŒsÈÉðß¿™ÿ'<ÄBxúyCOJ‡ß£¾ÿt °$ý…è?ÆV7"¢÷ïòÿð†îAÞ'O#ä ôß¿¨#ɾ§4@€øÝïÛßÂÀ /ÏpßÇÃÞ;Ìû¤½àEoMû½‘ÁŽÈÃgÿd´p?xxÄû'" ÄÞS¶ÇBéDˆð@ @NjnèPi„ÿ¤+ ;¦ÃÁÈøÿþ÷–Ì^g^Nˆðÿ¯²ø0pQ= ðh@ß¿p˜ß¾äÙCNÿCÿÿ¿Èÿ@oèQ¢èØm‡‚÷Uî¯v&Ò•á̇Q#hNšûZÿ¡‰\G„Á|þ‡ñÿÄÀÿ¿Ÿ‰€$q|Ä1ú=üÁ^°#Ÿÿà¡EBˆLÙ /g·?ˆÿÿçÿÿ×ÛeêÿƒÅ<ˆèýjþŸÔ'³‚‡Bäõ ÌçŸ1ÙÿÌÿˆ4(hÿ£‡Ðþ›hG Q/ÿ ø¿ý~ÕÁý€ûìü å/çÁž'⿲ ƒÿSâü­£ƒ £—[°÷ º“Ôÿ*ÿ÷d‰§ƒ_7b¢]ùB£~HNFnN$óøÀf àåÂÒ?°â!dXï${p8ÈÃz2àwä& Ža‡òêPsà>?ô·ˆþ í~” @âÌ9g¿föSÞ‡òôüÛñ Ú/pµ?uüA‡sÿßä˜ |´<ŽÊþ:Ù !{$þ‡Áü_²û¿Æÿý{ 8?¸ú áA~²‡ÿqü_åîã¸ú¸ÿ?4ŽÊÝBÀžü}þ“eˆŽÊ NØ` —#ìáÿÓþþü_Ùþ àHÿCžBþÿ®þ9á¡yº@C~ÿý²ûσ@w¸ì·Óÿ—#°÷òž<÷{°øèÌa×aDóßã¿{öð?äÿþó#Mâ_ÿÿ¡€®pø?åÿoÄ¿D! w»ÐÀ½9óÐÊ 8ÉÈ¿ä6ÌŽ(·BЀÜý`ÇÉ¿ýˆÞ/É¿ã ip/o8RVüjøŸ¬Ø÷´ö3þHüOVÿí‹ È íŽŒÿ#u:ôÿƒ¸Ò9Û/ÓÚ7öý2ðaaÁþÄÅîà¿ÿˆÄS#û´ñ?ôÿÿ»üHÂŽ rb~‰úŸ´8!P€½O ÏI…|L}² ²o½Tî ÈÚAðïñÄiþÇ=î÷³÷üƒJP¤ÆG~)8ðØ‘Ñz$þ ȱÏX=¶éü»mÐÂÿÿóÿO¥ý1Rÿ±6"¢ýwžÿ7óá9ùúùüVÔõO£ÿw¸ûfÿ¯ò¯#±êåìwPn‚ý'êcÿï¨é ¢ûâ¿îÈâÉÓÇiàÿ,ÿ‘ì 7¸7¢Bé_¼½“òÿW]ä0_ÿ/ÕHŸ |˜Ý⿟=´ Ž%7|\xÔØËÍç/Çß5Ò´9mü‡Sõ_æ_è¯ åÐa†ê#sè'ñ?ôËËh~‰ÿï«að(¢œL8Šÿ{¸#tð‘ŠGj`dÀ?d¢ìØ @»{gø•þõxn8ôÊ¡‡É„}÷ðÀîÏàÿ?B ý…í !sÚ£ø]ÿ#"z£—´~1ÿO°ô‰] »k˜÷+ÄÐNÈ}K‚#§ ø„gÿ³Ô?!š=Cý Îéù?/;Þ ádD÷Ÿñ_Ï_åÿQD;¡4þýçD w¨?¢FúÊü_ÀûrÅË æíyèsdåðïá›C¿&÷O0odpÿ©ß“G,~h߃Üü¼îøÈðG^wðÎYðTÒ{sôæÞþ`‘>ÿ¤Fz½Ã¤-Àãÿƒwqsdß@èaáQÈvÏ(xüíøÃöðœ6þHÿÿøìßÁQÊ´¿dŽõG*z¤Ú‡åŽ _<êqOïïãÿŸâÿAð*é»#f10d·ûÖÅQÀ±€Tó{gøCŽ_ <,÷;Ðö#í~€€<¼þþÿŸÿZíÏèÿ_3~ ì0-ôï6ÿI¡ x€¨þ=¨úwóÿDX÷¤„z‚Ÿ=þÿ£ükï×ýA0Â_í™î°Pÿ®,Žü@dDöO‚ƒŸ=ÿÏû_ï[ÚÇià_Nþ‹üï€#Êmþ]Úÿú=qäiïçŠöÿí  Ax"xÌ爈6âàQ¾ކ:'xÿ øÀÏþ'ßïKBÈAØó`0GÿP¤€ÔnÇU|ã8>²úo‰?¢b ‘E¾4ø[!à?î‚0<¾9þAž§?ù̧ÁÿpÄ»€û)è›òpÉ/ÄÚÙ7Cð‡A޾4?¦@NX—ÈO ;DdtŽãÿûËs?þïãþ5þ¿ï¶à,ò;aüK4z„ÿþ× ¥ÿH½¾·d‘Iü“žþÇxÙÃOŸÿO_ý½íO°úÿ׌dOÎfAÿ¥OðôþÇ_`H9û¯Ä'#ˆ¿xx` ‡·ì_¼¾ßE:èðõ¯ƒ¯nü2²c±¸s88¤ü=Œè‰ßÃø¯[ÐI™}RâApè¿9~ÿÙ=|ÿ›º[Yç jþŸö®\Ém#ˆ~¤'ªrà@lË¢V$À\x,WgÙe¹JÕ˜¾¦g®íD³U$ƒ€àј>^¿~Z1®`W ÿHÁÀÑ, ½ß£— °hþ‰P1„|s˜wŒ¼±è&’Ÿ õPy ýÝ‚ýGò@<éM²ÜIò@FЇBÜ8Ûßßì_Ùþÿ+­ÿÓ~àÏ—ŒFô=KO™]Y–1âü;£úúè‚€¿6 ú¦ %þöOò@TÕûìOlÎ ÖÒX3]ßÔ @¢þ«N>¿ìÿ²¶ýkÇŸë~ÔϸþWé?\LÝ ìŸt|„ÿýëlÔC‘ƒWá¿â®¿?ÈkÖ Añÿwk5(íµ/×rBDôŠºpÿ¦ú/@ÐGµ5ú×7g§¹Ò¾ \÷“ÿrüê¼3|‹{¬±ýY4½§qÃAIƒ9"uþ¥ê†• nC?ä“áð?Ø_ÿin¿Ÿ÷ÒŠöG‡,„kŸqþ’$:äô†®ßM7ûWµ¿)~ño¼þçØ9º$©DjD_€{gcüæDÔ©Ò—U>¸–¢¯ñ¶?Fó€!w#­쯲‹6†þ¼OiÀüfÝýy„ÔÀY¤Ðð@NÈ(Dðöï+Ûÿ†ÿW}T§@ü_#üÚ8 ¼ÊøÕÇüGGˆ$¨^ÿOl¬ž w½ôÎn¦³ŒApÍÿ—ø Ñ-ý=Nn­Õ¾lËÖ%7ÌlO{ü3nÒ{Vþ{Ý›ï¿>~Ø{Ñý0ÈÂf× E€yûÀMüù—Í9bUÙæ4@qú ûE'Ë})΢Oó£#Ú>ÎlÝy"ñ?Ó³$pšÅJ><)¶ÆgÄâ²msºnûùXÕþúzëßö¨4þ“{œ/ðûót_7Žñ·%U@´?¾kLš.Ò‚jx±Ö›ï*Ûÿÿ+?*C}†•µ39òiøÏâ 5[Uª¯×òÙò¬ïÂaÌ_²¬èúßÎ ÃåayÀ¾k!: vÛt`»½ˆÿÂçv:Îè–o~¤ÝM¢ÿÚÀàóš—Ž›w§iàâ œJk_&„}·}˜óyva)JuA<ºõû_fÐ •~€V|"ë©\ÀÄZB¤ÿ¡²XH›öÍã‰^OHH-^H0­;¹æàºÞ\³ýœíÿ©¢ý1þW]ÿûTÚr¡pê…OŠöw¬öOªÿÌ9¹_& ÜDƒ}é%„ÿ·Ûó^´› ãa2ÃÿY:Ó,³Éþ¤:´¤0°š 4?T¶ÿ-þWTÍbü×Y¾ö õYF¯Vw‚ÿè4Tœý ûW<дÛNÕÆu¯ÞŸt7 bIq·,÷òñÉì4˜ÕÄøoÙÿÍÂF4ò0 ü¸ÝÇ »tx- ¤2žv/þ~t»WŸÎ#U¤ @‰Ê›&„#ŽèvGF708Õ ju39È»ûcÌó± ¾èÂ7 ¹_âè{Žó®·“Ôü„èƒSKŒþÙþ ý.™Ú_ßH$J ÀÉDéuÞhšpÅöÿ:Ûó¹šýMöƒg¿ç·[ÿ§(n³¸ Ê3[´¿ä³ý]LiüŸ –Hù ‚fûE1$ü‡²ÕþÏŽñ4,hšñ…ñ3ÙfŽÿÜ´ÿ4ÉÚÕµÿ-þ?ƒGÅ  Œÿر$èzúïº?OÙªŽíaþ»DBIàœP<3Œÿà餧ˮiµÜÓO¤ CDWœë¿}ö.y@xÔCv®ìt@Ów€qöÂ4øj°??N®»k>¯rÑ $¾.UQ+ÍÔüã Y÷©ØŽl„ïïä2|j’û-¤ÿZwšâ×Ú­ýlÿ‘òDÀþKñ?ÊÒ}|:­ëšýÕÚû÷µìßûç°þ£$°º ëE £¿{ýá@µ;÷ôûqòþO„u?¼Ž !`DŸñÿömä” _€Èy€ÿ{ÊbÒ8+R“¸dR@öOw"ûg4 „Œàí/¶®ý+…Û#{Ô£tùò_@$ šûynÛÍãâÖŸsM„´Úþ+Ö<9ÊíÇ–@°m¶ïÅéÊ›¼-ñßEȈ®à¿g¼W~\8h¬—°‡ïÃ5Þh?¯ÿ±ÀÝmŸ#›¹ßìßí!hÚ¬H ;ñ{àŒ3çóÂ÷Í›€-:š,2í‰À"w®è&¶°’ Á ¢N|aÒnEûþÊBs¥5ð·bd–žánÛ¶‡+µÿæC4Ñë‡:öïŸÉúÇ œQ‘`˜íÏQ/TãÀþ ÿÏÊý”ø„¢/’¼áþOƒ…¤™ò4 pLŸóˆ@,Ï Fû»% ¡ùhÈüݯuíÿb– -ðîPxœì½X•Íú/,!Ý)’J—tHIˆJ#%-ݰÖbÑÒ ¡twH ÒJ#Ýiíwïó?ç|[½ÎûÞ\>Ìzæž™gžßÜ9ÃòšÓ?ô'ÐäáúÆ^2eÖ2«g½ã»ôVèÆÉ~¿³Mßm4ýzÛÐAeÆ­ÑuÛàì1!Ú1Š{1Ûqô”Þœ*àééSµ“/´Ã M`Õ?V[¯Xï»àÜO_%YJâ‹qb¢‰Ø{Íö û€BÅn¦B¥ÅâðM6¬Fû˜ýü«;MpBkXå~whéã÷ZSèXB… í ÄiXrnë#h÷ôa1%Äí9"‹xŒ°Χ= ¢5£hv‹†ˆB‚˜óIŸô“¸6ø<°¿þ´½%ÏÝuc€ÁöJQ‚3u'„I‡üóçû8~ûè†0û«êÈXþœåïC+thלQÖ±N²·îÝ–ô¡\XFP5TNë©ë¸‰xU†ˆÀTJHá=Ÿž†ŠÀïáh¤ôÝ! Ûz#‚™cNGw=Ff0ÞÆ¹3´—€Bi¬ÕŸ·wÍy­„Œë¾6 æ~Ôk&ÜÐÃþeðzzíë+µ†>Èž®™ÞI XDÓ*wÈ쟹t'ëxqg>}þ)QjçK=€#Kζ‚ôkZ„&wSõ>¡·ÌC=6êgO](å¥âœ+ˆ,_5ȶ‚£äˆ«´OhSžž¸/oÒO­w\›o`ŽC\:H–{ylµèä ¡ý`U „;õ‰ñ8%q«,Ñ=Ä>N=òݰ€¯4ÙîÁ\¨À¼±H=®f8Råòû ZÛ9ÜýËàX4;CbÒ‰k9Bé;ós“ÕU<^샴¦6Q´h‚êø4³D ˜3hž‚qÛ…n¾ywD Þ\H/€6Ñ‚ än´eø" ˜¦ìÉ–€#µrX›©4«Áò­¢˜ÁHZ™Ï~øùͬMðßã¥ÐÖ’ˆÅ÷äïþTŠü?Š7 ®òŽ0œ½RÈ~„…SÇQb'm_Œ—KÅzo¬./bv9O‹î_ÆÓì›U™6Êøï&}«7s?úl•Îw°•å¾k3Ô; ]¸Fé˜Íð/ÓT˜õaråFD ÙžæUTÑ£%ó»Ôe¢AÑ÷Tw?¶k–½››|½Z%}§â³›D­¾¥ïŠrÒGë—…Dðè õþï;c燓|ÊZ[ŠŸp½Ö©bU>dK×*¨üˆ‹6ÈŒq4³ Bð1”ŠŽà’ÅýÂyÐY˜XXØðæÉÿxå §Ë)öWéKÆ1MÁp·ÖÆÁê5™'•f)0q;wý‰(ÝQ†å²§rOßã<ª‘`À>G¿ÜäŒùéÒ]§‡‰âe(íž\ãßHh/ðTƒ1dáHÌÓ†¡±˜Â8?x…kîüÒÌ\¦¿ÿÌ_nqþ¡C ð/TKlØU?àeÀVùñ”ó~séŠ žHê⋊!©L´ÁÛÞ™oJ‹±ŽnÚÖ¨¡¿6³d/oµD’s÷É„'b×»EÊ•°æ_cç73ÈMí»‘*ðÙ4çšL¬ ],<®–™ƒÜûk4ž1í¢©ëTwY7k”ïûï&?BÜ/×Åfù¹NQ Ù-…\‡„Âm*Ä›¹æC7)ÈN¼Kô˜‚Õ)ÃÝv6ßÌ·üz¯Å±JÓÎ8EfÓ4ì8‹öMW–Ô@L])äÊûh^…,è[Ejðú#Ö>|#ýVÑQ’˜•NòDY«4Èýgî#ûd2‚•-¹ÊÇCO‹au&R<ÐDv&l`ö}ÐúIØ GišW37CùkEõrή e[¯ç–Z½Úk5[‹M®†Ê/zTU«ò S$‚3cv·áá5‡×:Ç'[½7Ì^å(Òò¢´Zöhõ Û"aÄ~i§¦OË¥Þ|]’m{\¹ jäîΗfî¦íð‰ ‘!$÷Á=ªÛI8ަ·ç¥ˆzf>ñ0,×YÎ$r½ýWÄFjU´!§©L‰)Ç[ê ϲâñ·6ÃïúbßäçG½w*Aûà-ø0S˜ž¯\M\ÈÛ-ÿ|p÷Ù´¯¬â¼ì±ÇÖgRTnp{ÈÉ H{8]m~¬„jEh|t^ÚΪ0S¼noÖóe猪®l¼O{ 7õH¤Ãòö†P峂œp4fùŒÙ]ÉÃÈrQäC°å"‘ly¡ëpÂÍF™£D†C ¯ì–Rœ Ö.ûjDMXŒ#‚ÆQs+Gî«Ò„Í Êü ‡†Ô»2Ùlm­Dr¡Cü›Až·ŸÓfÙ¾zùÆò—ã¯õ'É¿H>rSEÑx=Ù ÄNÑà¡úý'£oäX¯“ç7*W˜±göDé#j% G%·±Ã¨‰wzÖK¼ª 'œ½Qç/ýÂ6,õY([^ÓDCœÛ¨mÍpʶsäâÓ%ª¬t rBS ÷ÀôN#F” ³ÓT¦ôݺΊ!RÓÂØIÜ¡£Oäì\RIˆ¦Ò#Uœã/Z܇^ˆ—<ÜW„nÌ'Ò[ ½³Œ©RUErÃþpûnª-<Ê“»‡ÏæH²sÕÛ¤ñ-¯JF•¿°®ùp0…3·èlºÛÔ]4‚kh®ÂñdS<¼®æ·âïð‹íÍ?ôdpsÿµCŽø?Q,m§Þ'u/b×_'ñ{…aØÞk€ñDrVG"¹bÃI,scL7Sîž#CðROš‘…·šÍDµŠ%¾¶œÀþ9ºü;¦·Tuûþ¸\I+(Ûæ»&Q…ÜL3É4žfíJp#<·ä^rY (6Œ›‚ãs°xs Ýú©§–î‘­½Áë¬~¶š>¯,–@Š˜0FRùø1:^€jŒÁ½¨ƒß0‹èÏHî]©–Êæ³#»í•Y€dÄh Õ«Ý(vV“Ö~I$— è@ìÏ‹å:ð0Uo1Ðd[G2ûÇ_áãMŠA·úã&y''iq%Š!b[™’s ÇìÙš^ J½¾¡E!Ô0õ¦•¿wŸ“w¹KÕ„ûF˜qxÕˆ„ñÛ';ù­®~(Õ§"á[>ÓJxÝèÈ ¥Å&  œ~**©nàáÃ]yrP(EÝ¡Úb 醣éƒO°FÊÊ@â A]‹–©ÝØŒÑôWehPæp4éðTR‹­Ü@ï4E×HZrc£‡÷|Ÿ6Pùz^7~2 ý‘ÕffÙØÁÁ>WÆë‰ F 9#±„øèkÄÃ/+ÆD3w2§hÊ(OtÄo © Y†,VÜ*un6•B¬¡ïuŸp(mDä$·ßˆ2·‹â~܈9ìy÷óI¤G¸R~ †R+•Ó¡Êq.çrÒ¶ûPâÒÀÍ;rÔwDÜž-vÔË÷©Ñî›ÈaãÓÝÒ+go>€ZJÛóúˆPÍ]9÷œXÖ%¬ˆ›aî˜]’¿H‡ì‡MµN¿˜kŸV«a7/4º±EÁKƒóÞ~ÙñXœHu[„cäË• \Š¿þeTÁÛ}QšT·-1þº”üç÷XɰÞrḣ^À ½¾Ó™Ì ®D¦ãÑ}Û?¥·ýù%+'.X¤…!~ÛïåhÚÝUEìÝ’Ò»{Ÿ*Ê ‘$|z×U¬Û÷—sdÓ!xŸ×ãR»‰¾v'çY’ÍÉ`Û—2Àßvô‚›¹qÒ™®bÓªØ]ªà ‰ÒXIT¬øÁ ÀVºg Š¡êèY ”'ìö>ã5á\9~¶0</Øæå­”/ŠÙü^m"7aÄŠ˜ßáx«}†¼ý…lHF2`Røî µkÍBN ¿æ@Å[ÕSzæéãèëÏ_·x"wt9EUoz'‡l´Õ§·ÿVü­¹ù‡þ3ì~ñ1€/AÞÂO%Þ.ú‘ðÆ„„ÝÙ¿y-Ž“Ü}>‡Ø³[8ÙÓ¢¿ÏZæŽÝh{þûù=ñÌ!Ë×OˆH™"—ˆãICU](“¥ Óeép†}Ÿ-¡y!‹âÅò—0É0EŠÜÃSƒ©É"L2`Ë—òä°¬kf›Q6ûû¬áUªž“’!—.ñø³<¶´çŠ÷bƒÑ­Ëƒ6Ò¥1U6ÄÔ†[õˆ¸G·Fä+gP„3QĬéV¤lVôaÜ„þÝA›ò)dVˆü½Í¯pÕF†mëe@H¼Ò쌃›Þ”Ф1o Ã#&˜åõ2Ð,âr˜ð“ÃUn,ÃSQJ$zpË×=PŸŠñâ>à<}¶ÞHS{ç6?G|NI’Äù¸wH Š5~þóá¬;E$wsìülž¦ï;Åu¨“DK©ˆN>Ë@ÖÏõ±´z25˜‘&3?cûI2ñ.¹EQS QLâ]Ì„½ \ä ­ØŒyVÈRugzï)§½×-±~M“ Ñ-ã»@ /Þ‘ÏuYp1u“‰oÈs¸wƦ­ù Eµœé_/~©#Û»ABŒEóÄñÜ}s1‡½² Àˆ§”Døùü³óxº¾ ½,J±5cÐÄô/¿´Ïû)Ôy4—g·‡ø?&!—¥ê‚ÅxB]’¦Îï;|xƒ03zº¥8Ê96‡C[¤—…¬‰/l1/qêË“­b¸IÖž¡Nù~ÇÕZȨª™LKõïŒkj66H;‰óôâ¦÷ß ÒØ|þÀh®<¤›æ4»sìgZ$ Cl”‰žÆ°\N>Ì‹OˆÍÎ.Â_-•r8õ6¾ÛlŽk€¹ÚdÛšðË(‰{Aš9Ün‘Ë¥­;pàú¾‡;ü}ÚÈÙ@ÃiJ¤E˜o cp¢~)þf˜üGؽ½u°#ÚBû^À—@õ*¬jûݽÞÌ ¤›·V †?HS@Ðg'Ãw…a,nî|ò TÎCSÝWmÅÁ7^œ›ö¬Â˜§yUxSòåÌtRŸEsW²Rº±Àzg‰~¾à[?Ì„H…Å"%1ç2ŒIiߘy1ßâZÕᎮ‚}ÚWªhèƒ^B>ΕžÁÒãÞ‚G–jÞkV%Ô^è5›$anUoKÂDåQQÓò™EÈwõ›ß»}‹x˜‘ÙÅÀÐöÕ-µWaô Cµ)%1Jr~´M,@²«x>÷ vM޲·¯îÏ}­Law°mV»¿Ý¹!w÷iãð¢÷Û,—Xfæä½ #9àT«ÀMŸQ%®Íøõç0£±Ã}|Ÿú,dSâ á-«¶À7Ð+;Õ\ƒ‘îù\çm«+•FoJôøö¯Ôj@ÉfŒØ²<í³¶(ˆaq‚•î•'ms̈´Š@(ì¢.LWéMÒÆ÷ + T'xº³äƒnó í6eÚ:ð]ñF´XôÀð‚*´¥{„áˆC½&ÿ±)IÜqÍ^+"Gƒz®]ù:[·WY¸àaˆ‘Ð3(€u~)íóÙDº‘ñÉ–&âænøbÙ#L&!”vn²·½œ²‹Ô9«E›ië*è™{™ d‡‘‘>L †9Æ3­L&ÁUéKt!p}ú`Ú³©p‰’ááI‡p£¸Äâ½aI((«9ù껎%Z[ûˆ „º|Š÷¬©3Å?ù i?z$(‹©‚¢¨¾Ò„V\V ‘×n‡j„@q½ÂëæµåÏÛÑêÐñ™šÌ÷µß¯1Â.ezZ%µMnø†%Ô[†²MÆ» %# ×§ËP  v2¥µ[,†í%áxì='§ª…6JIy±e&ûâí,•£1Ì®Èéý žåð]©¤&Â6–¡Qæ&yɲ§¨h!ÅvÉ8Ëi¦ï»VÞ~ˆ‰sP(‘²Hg™SÖæÃÓÃõ\ün‘!œr?4dÝ:íº'Óß ÿ޽‰7‡Ïìx,&¨>™FýJüIþ8ù,ˆ9»rø^úÕ+k›5X´Ž`FË;)¨R9ê”e0mwqõó™j7Ç-Œ—Äœ›+aî½ ‡åóI‘…M¹Sæ$@•&„Áµý4“•„i •Â8À¾Xw}ÌÍ3¾öa<¤±®y£è®ÜJ.ÅŠÜ+£/8E7—a…W˜móê+º,¦Ö»4t§LŠgßZSãâO5ö_æ'·nÐ_›¹Ž©ŸË±W¹_ÌÏdNŒ;eûõJ*vÈA³`–­ƒ÷úîfR*Z˜ôJɸîÖbF·†#ªBì¹f˧ ôi|3Ø“¢MkV£ÛÙ~'þÿäÿÿ4Ù;ººÿ²cw[%± |¿d‹9Ž8šl"ÍÂ?¯Ÿ0Ûî›…ˆ{˜µèN(ôÚãv™~Áž•ç|¦élA¯iylËþæœ6××¾¡ÐÕÓö|„‡{·•ßm“°F„е=Šß‰åÆwýBº&±ÿü‰'Œ^o(‡RrÑùQÅl1£×˜žDìÇz2ÙÃLÑ\¸.«I£ )ªž!›€ƒÅ æßG"J×y› ~\v¿…·PØ¢¯{=„ÿ±Lò-§Å|Åiú HánV˜½éUÊíì‘ܲí * zê(‚ k¯á ŠÚž"ÙÌn”×N¶šAîT}D„nœâêV¢\ºÇ#A¶%Ëv-¨ )ž%‹¨KG÷’ÙjµFpŒHgÄFtÞ8Yˆ·rö!Ûñzà½áèʵ>}aCÐv „²P“Æ.fXò(èO ëmãÆ‚¦G/™'Ýà§ ]†ŽˆàÝöÇÕqK()ÑëMšž>±‚CœŠš gq€ˆ#N)Sð¦j̨ãí«­+îRíC„o/ÈÒ ™üPU²S*lWÑ¢ˆ³@‡êô Eï©eÀ¶‚㽨uälÁ·o6h\¬ ¬ó;*/µÅÜcy~¨êº7^¢f¶€¯¹Áõ(ê>´'“¨aS@.Z™}ôŒ§.j7ÄÝ“)^¢ƒO꯳Xúóœ”?ƒTCYº‰{ìIì_û[ÞäTÌ’:¤Õ R´Ó4$¤ìâñíÂÊð`š@zèæÑJÎ8‹Â×&ÊÀ^g„k÷ 2+ Çt…Ùª µ7L&ŽïƒHØ0DJŒ(ôh‘D)F¿'ûÂøæE“<Ì­òo&yÍJiæX´•¬œ¯UKÉ;‘´de õW[l„$,‹äi'†>þ[áô‘Ö-Œrÿ8—[€ÑUO°zô×á¯öÊ¿uRUXýV@²b¬€wÏ4mQ£…ZL+äÔææ6uËVL•!@=bô0:=G³ ¸6à2+27·U/™Þ£P¹? w/ߔś,fç.´Î›—¬i¦e¤t×¢÷øÙÄ  ‡f’Ôã¸ÊæÆ;óäÖw·5Ù×ñJ`ñõ (=5ì±–ïeꔫˆ¿:ÒÜ|§þ†ÇÇÏø¨gxa·móIt^¥F!³Ðý~õJ(Ob¢'¡¶ý8ä7ò}ž)…æx>µ³" -¹×@/a¾¡%‘Ð%oVZidz÷Ó®í›îÒẾO­Üc×~'þy¿ÊÐüCÿcÚÝÝ~ÑX…4Ö‰ø¯7‚ïСU‘…Ìf> }2 ,à³èÕÄÒm0>ÈÍ<D|T¸ƒŠu—ä¤H«0m%šõŽ«ö4›a~à´*ŽÍh-곆ÀN}è†úýŒ=Wú®É××Û +… ž}ôyLW¨ èmA›µY!>õɲ¶SÍ?tÅcðtsR‰^Å{K%C»OYr‹abNO»§‡»J̪ÂK¬bשq©Þ €š&vS©G.QÝ%1ºèÄg¾D©©0wÉW¡}ÁŒÈì†Áš;I‚VµÌzsü~N†ï~Ò­îóEhÝî¬påÞ¾Diˆ½eì{YæÙ¨Q9‡$~7Wšøq"F¹Q«ü!Ó §G¾è!«;d8z?lý,LðYì[Û½’‰ðMûÂÄ„ãH^Z´§‘écš‹TÏû¯ßÑëÓí¥dZw´öûIMÂŽè]ñ¬﹞a0 xx"“‡§M­Ép7CÓlTì†iMM7/ÝGWþÝ£©®ü½”g¯^²PâÓÞ5±]«‘B1†Pkä3NK{ ËRjG íÞ3àÂôPçÍ&ç‡|ž1Ó•ö°¥¦…›à°¨()2C*Á»Xn‹lÜ×Ô{=\(w»¤ƒ#9â㲎맥V²¤Ú,æ×7ÇxÝëæ|7(nTta‰¼ž_©ŠXHL‰bí¸Ùº£;y»‰ CòýSH< \BèÆ2º!1t F^!¨Á÷³çr7ð¹ò[ayêLHw×€HtJ…÷©ÍCﯯ·×á~” Þ{j¡7E^‹Ó#¼¶c\,—ÁV×׆#6*`p¿eN*4(ãÙ ?ãÉÌŸ%ž‹Ø#€Rêc©5ø7Â?·dšìÚ¤À¿í[~­Š,ìˆéWáÿGÊ¿ GA‚M:äÇG˜XtÃöo‚Êï‘ÌJ8‰ö¥$Ì.Jíàt½¨ |ï^º4¦ñ’ýËÓ «ÊÈõFx2‹M1ÂLÏFˆ^Jæ4ÀŠLüA‡>FDqm¨tµ û1äH¾rÞ£à$^\ÜD1¨Rݺ£N pnï“èÁ¡þÝcÔÚ³¥H¥¼ÙN÷žŠØ¡q‘ÃÝÁæ“ @(‰tg«· Aϧ¬D93çQÞõfvÑ»ÉöÇ7² ’žb>|ó–Ï·+7´4ãËt®Í¨Zߢ´Bœ€KR©K áú‰rÀ.Á½näùVhWÊý߉ÿ/23ÿÐÿìœ~ÑßêÓïd´|6AU*›•’Ù%ˆÌ¿)”¼HBKq dèä¿”*H µ'C)ÅoÕ†ÕïñÍñÖ ¸!S0ï<|¤Ñù!ó#Ý^0-]€Ö¡®¹œÇ¸öc¯t¢*IúŒ¡Õ>L<]c©`ØGæóD`lž-ì ¦ ß ¬†Ë=ÆN—ÊW)?ü`s¢ÞõÙbô:ÛûWXŠ–\?ò½ U`.4Ém±¥<¸BŒórF28y> SÖüÉMTåRTî¦'ÁX¤¾yø¾ƒ­Néö‰ší,wbÊT—å5v{ZTâõ³öšm Œn·2ŸËfÆA¾dÜ&“ÆÝÉ \ö2 :Xº¾.ÖÖÓê÷tmÙ™€Ø[SŽ$fLïéÇÉQç865$ÓòÈÅÁg3]á¨þÔš0(ÒžðP±T¼·,­¯>sÝ EŸÙåŠb=©_ól®aÌZúhÔqJ.’ÙûFT6Eá~QÖzÓTúvPú2/tž@4®‡'¼“”cþc-k3|ý梾æìd£ðÞátiއÊPõÚ—z^_J—ÓúÌ86ÒòLéï"HWúû«÷µoÏ–’o¾?<œjÒoÊÕýj̱•»?˜/ïS©w}.ÆÞ}—øb^CPÿ$,­ðmY†IlófN®qqDÝÐǬÔikÜŒ~b­Pw´+xg©LƒŒ‡ÛoÔ½XœKuÁ†ó4`»Ü© <ÎS†!𠌮EÚL?Æá¸öˆô3 GúõÚJd$Æìʽ>š&+’7¯Ž¢ýÑ4²Dïð&æC^¿ïŒÉÈcÌ‹4¿œ*›1QÒÝ irdœe§öI3IC¼mhzRžžýþÖ8¿§Ðã0¯|Åþ£¿þDÌ«ˆUí8ôw-B¨(R43'(e þF¦üw“XäSVW(ÕÝúà2N ›ˆÁ®œ$‹Mp¤6Gc]v‹î“jPÜ¿W‡qŒs,å‰/O¼Ú#X‘23†"y“Zrx£T˜¾¤Ò=V+?Q‡"ϾÝv»ðá–Båx¤¯h*íáå.ú˜yF8¦èÉVß¾Ž&6¶$"àÚÑ9x´³3Þ¢n–9/G¦ÙhY)’§¹°Â~ó>¢§æ§˜ŽúÊi̕ƙƒ…•· ‡Ë Rõb°5s7K*š=‹ht0_×ÉYT¸moj­Ÿ‹tÝzÑ{tb0¶Éh¤ã>Í ãG©8$—zCåxÚÈ\>³è¿ÿ_ÿçÿÐÿ„~Õ1€Xf= b§‰RéfÚ-¦;ÓÝ}ƨϪ¦ÄM+hjcoò'¬û‘Ó‘º(Ió…­½ã¹å6ÓËö|HWŒõ¢ —ÏÖ©ÁœO®lt½áó­ðûœñk!ôÔ2 å ܾ뙘ŽÑwvð£M&ÐoAô÷¡/‘Åò*_~‚Ø ¼K5…xC˜q/U ´*ÑÁC°\§¢Ó}Oº¯³é,Û°íû¬Š\€¥¶hù^’J_K²Åt™êk÷P%;•Ž]±Í º@¦9¾"• ½ëíÉZ ºÏAãÜê«ux£‘ÉYºÔ>Kè/ïÇááùßoÞûðˆ|ßဘYÿPÎÕ®aé ƒJé3h ñ¸ZãíjØ‘‹vׄEºÛõèŠ×d±Æ97Bù ãეÁ_^k@×1›qÛ¾2æþ‚Ä'Y¾ÃR¬ühôY"ž2ëæ»Å€gÐίB]ZnÄ=ˆ„[¨ôöåN¬z¯2ë…À% h#Ë”c>E¡?OLT4à³%ÚJ*BssKIj°PL;~‘c|°òˆà¦Ñ 5ºªL®\'T„Õ“ªåY}?^%FÛ'ñ…˜šÞ7Ë.YI†¢¶[ëe!Çb¤a 9ųÂ’6Äšç‚$OÎØ%ÛÈ·Ë]Ö5·j>¶)Œ6?î âpë}°•îq\¯Ýº;ÇÐú\’G[†W£Td™ž$•ñmvz~­Hø§¥þÞ“¤®ZÔ!o=SB ²N­Šäº}é‚É<ë ?è-—n &L©ð›õY*ÈE=Ô—¼­”M¶YBܳnâàºÜܺ,&X×Ñ5¿šMûîVO²h-Ù{å»ßû; e0O"džãݬ9¡ÿÛàŸÙ¡JÐð¢Î Ã¯~ÓôZä²ýàíþæ_‚?ÝŸ*ÿÊ“ŠÙé[’!“ŽVVä‡uâeøÕê jï+Ù…÷Z´-rñƒ4¹‘%«QÛ H]TØõ ]åA AMû$Œ¡d«™ç4ླ»×þ¼kY&|1öAÄF1QàHÉæÞÁ¦àxNô8qø B©;ð|oØ-ßig)^›d¾NU+žŒ’tôBí^†3ü훨õœ22f„š)p–¶ÍìœO8xz¦‰±°­èÜ„rý2§P<(ÖH5å\÷hð.M+xÃÅ3T‚„ÇÌ´ÓûüÅž2Α¹—}ï‚â#þh¿ÀÆüCÿô‹Ž$õ1Ôˆ¹¢·Â°Ü¯QÙ¹‘»ŒIã™YŒ`ß›ì™0‚S¨ü,Ë—1¢éŒ+™³å‡{ËÝÚcaÖ™ Z÷:¢ægÞ“5DÓÞÄ×1TÚ“–hOËgLÞp›—½Äã~{ä;Å´Sæ1‰ÏrÀHª%E®ÅH‹ ÖxÞkAùú) ¶ãÁgÁ¼C_bÚ½7û5T>›‰"ØMä!¸Öz]®Äbx¥£…ðh]BˆT‚Å{.¼)s4´¤/צlÈŽ¶ÓeЬ÷²dZM´¼8žnšçšP§˜YTÛÀö%¢Ïl%˜[J; çŬѭG­ä~¦7’­38Q¸_.Õ>& /;gH’\ÚÈ™žÌ?67+‰æ2`аUö<Í`ŠP N>?aB¢qÂT‚!z/ôΨcŽ«ð¢x9,YÂ~ê}e³øNõ]IìJ= é .¬ÂÎa@XaÎu_²£ðRvÄH ï“çVöe”7‰JõÞGF£X"¢_Lq¹ [;‘Q×=Ô1V °H× ’ìUÑhùЛy²rÜÊ‚u¸=¨Foš>LvkúŒÉ»@—˜‡I›ÒÒ6_…Ë_4,úiÏù“t¾\5´Èš÷köíf»9%RÝϱ((c«žsì,#¨ú ^ØæÌâý2HGµf-¨8Öó¾8RKoi \ÏzÛð!6Íû“ûÝqº#½Æ*$ÕRÑUJ*Y¢A8—&âB/;Gm5¸¶œÉë0{nðÛu¡²ka–ï­'!1”ß›gVÝ—§ˆ kC©}1‰YZ9É8ÊŸÙÿ:̼UŸB9­Æ Çs›Îºê ÊݵU*dt=ëúôZŒD9^=ßgm±Fš *U`åßÿ4weäîyÄHožœcˆÔu0úsηâ8¿ÿŽ?Wþß»/äò@“fu,ïÚ` ¢ˆ¹>C¹5ž$a‘¯üè#CÙ ºÇåý/¨!ÔcÌ…çÃÇtÈ–>;Cœ¸ø ì5Ÿóó6+¿E~Ï,›žRæ$ØoÄ8±®œ$ñN3$“ ôáà)( ¼·¹®zíµ‰[Gú+L¥îw‡-îOËàgújds M›ÑÜ>¢ÑÑY5~¼Ðjl÷ÆóÁ†yjhù“L'=[d±¨'‚›*¥‚äqŠ®C¨$Ž ·}5ý§ß˜B7„¼ë¬ R ßô-GmÖôšØ5±5(¬Lâ`î†ñÔ»ë<.šZùñOû¯[˜èÿ~É1g®›H-ãO²ƒÝ! }ɸ_-Ebft™Sz®ä‰c¿ðT}iÑÙ¡ªûqrfÈ“iå@ÁñK9Œ‹ÚÔà‡ðå8vnHyÓ—Y,³Ò9¯¾¶1[X…ú O'‚6WÊ:jœËòÓv²Àõ¸JÃÁÊFY «‰ZVnè#xö9k²¢éûn÷ÞmÚ³œØ<Ž`¦]eWŒÕˆf:¡ ê¾Ùe„ ÙÂcaQ¿Ba™äŒ aOÙ ¢ [N#À Ø-‰áM§I÷öP‡vsîv¸N‹Ý(Ýpxô%–Òÿ.eœ©•~tD¬H/×½4¬y]¶= îÍŽä¼y¾ê¹uuî£=J‚²ª ¢Dˆû»›‡±ÒTú(úƒŸ±„ FÇl€‰‹0k¥îZ4©3:§áZBÒSëÙaht`š~‘“V|9Òa€V¢5犑(2ML­ÒlÎŒÁ jžpÝD( *þžZå‹*íPÎG¶~÷?ÅGâžûψËMkN…7•ä²éAJî˜Ø9aù¾SÙZ5ìô2k)Î~‘MÖÌ*¹£Å×±À¢5ècÌù: 1Cd¿‚³q`,‡¹'¡±ûy‘zØ|.z æSÃPõQo®>òN]/¿Tâw(ˆòeR{äé­7¹ßîªcÍz4D̽ñI(‚ƒM`dqÐOsÔé|6oÂ!ÐÏáY¿3EVôhG®Ý^Ó~ 1#œÏ‰—~Ì\ó‚zc[¢žXI+Gà˜Ö”‰ñSgJ‡˜OÝâ»ýñ$ñ~þQÏ¿þÌÍlF³Y’Ô„–xäÍ:|oOx8=äÂÿëø{þÁòž|3µÊÆÓÀ›©A5Gxgß`›XcmšY/;½rKÄj‹’~Cj¥Ú0H“åéç#àƒm’Õß,ô¹uJÜÆÈÁ<1b~ªH·þmò“<"5…“´{%/0 r"$wÜí®kB^fól”—žl£Þñ$ëÌQÀ[«V/¡‹,J’”/T 4ªî‚sÓ¬áË#¸•ÒCôý;sœâ–&pŠo¼†”Pä‹+ö©¿×â`·ZEŒªt2‹ÀìQs w7»žGÉ;Çœî@hΰPUW¿ÁD§âØu‰xù‘ÿ|킹PÿoÄÿÝÌ?ô¿C¿à+ س·Çh”A½0'RFZµŸ­0åó#2òïJ¿ÄæN<D‹Ö€©ü?þwÍË?ôGöÿí¯n³|½(o¼ëà¢q Ë­ý¡ãXµ"ÜÉjr”®AÛ¸¤Bq±xkâáªÇ-„•—Gw,û0øH¼—#ꤸK 1“MÚhzI5 ˜-«.ˆ’ùÈ; Aûþ”¬1›qÝÛ÷ ;îãç²:•+[éN*°¾›|-Ôtˆð¸| ;öP±%¬‡ÐCqɤéÜðÜŠ6" @3nÖŒ÷*.óå­Ûœ£P:Ä÷Þ®T|¶†‹aÇ 7á¿Uµš§ˆªÃÒÓíï5_ÏÆ¹]†(\¹ˆ¬§PI#t—&þ '}ã«ýx‰ë)5H–óeÃ̆,+™3о‰Råyœ ”™ÓŠ® e6;×þÄk¦Ñp†%EÍøD¦¥O‹B¾fÁ9êe!f1¬;¼ï ûÉA>¼Y~Q<æ ¨¢ç} 4:sÙUÇ'íÑñŒTý˜I÷µ³µP+ìdLq*ò k9úLKâÀ¬ƒäX±'/¤9KmJÈÅÞ7ÒåµIÉÙªÓh…G««ô).ÿDÅ1.P6m,ø“B‘GÄêÙÞ0é~œ#R/DÓ!û^[Ú…¿£Íí-rÍ‚©³ŒÑ ×õÊ ?&€õµäkNé O÷h>µ¨1Œ±¥¤M˜8V2ÍцSR;ðd³‚‰rßš\Zf™¤6(æÓ×=bÊxƃ ÷ÙÞ^æÌ|íW¯ýXæ€Ì8ûÓ¨¥œ¥ê}¿ô øW †õ&XsáùUÌy­POòc©²§µ¹Œ|®l6ÅTƒtÅSÜ O#'ò„ÓäçJÝ!qºÝ¹úÉkîœ09 ©±FÄšì£UªäÞt*~ññ ËôQ…Xâf¢Ì‚…d›¿x3µú«(Ýè (…“q/÷\R´¿þÙF ª¯5©¸¯¥sáqr”h6}0\4*]JÍúøßÅßí—ãI""Ü(FZÃkbJ¶7‰žgÀvGÒ§a‡. s—ˆ¥ (Èáaéyã6L–.ð#7ò-.””?(>Α)&{ ^ðªàǬ– zœf*ïk³Ð¼Û‡ª¡ò`—«3“;DÑd“q° Ê­ørÌM”–XUÌ…-Ö­âé å¦p¬qº­}ŠrŽ>î…§Âò* –Ç.{T„*Oj爛”ƒ/:$J IÂñ™œ\ƒ‹y-bw8\:øQyÌ\ÞŠ¶ýÓlWláQ­¡ê&ïØH%UpY:+$)Ì”É~†*?‡ä߇ÿ½ÿ¦qù‡þ¯éì+Ýþ‹ÀC/,Å¢™/¨f{×ù¯g%ïúS²„­èû%`g4> q›¨–¿†àÌñŽR½~ØC¥üÉݪÅU –prrSØæ þÒ~ÿ…TÁ*ãÊV ÀT³&¼4ntMɳºÏ6è²jÏÇj<°X^Oø #ߨæÍó¥ÙݲÁ{¯‰d>RQM µD“«šÅ©“Tƒ÷Äa‰;@¡žE~ÅMì;wì:Ȱ¤Œ|ãÝ•°YrÀå‰Cô \õ–:¾ç±§]ì~©²Pßœ–ëR°ûÛwX5Ï¡tÚ4†v³6ubî‡æSßâÌÛ³áG ! b%ÒsyzmdÈ÷±-òi^3lÁŒµrX£Âu©å#õâ%Š¢a#Ò¡-Ó®êaûíº­-’le¨§×øÀi|ˆDµ;qÔ³{Ü¢²ŠÖ­.,NütòõʶL¦Œõ‹átù2îXm“M–+1v†7=A›ÎËkØF0ñxb¢ì9êó¼°^ ÜžLèÅÀä!¾9¸5þÈxò¨TµÃëFгܫ­¬Ž¼ñgš«daòm¸±%7Téädئqûû鵌¾§dq\…Ðr\̇~œ\ÿþX.=·£;&Èw#vª½:°^úèfŠŒe‡]yüH`êÒë%H«Þl‘–vtø£Åh¡Dâ-ø¿çgY„5É2ꮑ~5s”Ì'? åäqp«x{‰+¥¤³ÔvYö„P³Jà ËÝWŒÂžµøõǵA»Öš¸ÅHî,UF¥ „S⃇Åô'ÙŸEw¨L+F»^BÝ\’òïƒ,¼Û§iã-–]0Ïmú¶‡ÙgE2WåÆ'=ωa)Ó*k³ëຖo+dµr 5Ó'Ëlø¾ö¸zü>Wü™ÔÿçñG£À¦¯Ò`M8örí ¿.ÇCY í #ÙÂsí¿‰ÿÌŸ.ÿ7½ @î8zE¬Á<ФL3‚î ÃýJR"+ùO’†±úîÝ®õàMhG°µZ•Í‹†n©“ho®Š˜‰L€xl"›¯w8§ÐÉâ(ÞÂ$/>_+•¢Š)è ·¨wóEIæÃëühƒ»7éXÛéFî6¹í>­‹ñîdò•ëŠFŒ/Í£Ä-È@"±S‘H*ðZ4A¾C¨+"3gF©©YÜZnúÞ(IOÉÀ~CŽ}ù‘=˜Ë’/屢ûp#*rófGöBGü³j0=EÂtùóñªž"xÝÔòFÍl1kÖ0~þxÿ=ÓòýÿBÿݯnœ¨”Ç3ïlà oMaÙ†W.Y´G•‚ “¬N^zIÉ·n§fðÎ3ßq¼D)¦†Þ¨¹ßÆdÜñ®€6.žðÛÉC}{ßQ,´!»qˆ¼7noŠãÙ½WƒÐ²5‚ªñaØþvz½•‹Xæ %ûV;Q° xÄv‚à-=Äö¾çs¥Jè&tVý!æýc–ûÒ8kZµrE«î·èV¨›éc7k]Kjª— ”–òäkI„  F¸¿”yÃ: ‰—5Úa ŽnøPÐ;]£‰Œ‚ˆæ¿ÎÅò;Ú[à&âcÅN3hÅòöG V5K`¬ºŠ­Ûôï¶wóS@†òìï]çÌKðZÍÆg[¶ø.ûÈ*ײbëo;„åNÄíso‹!é À¥0€,L |"·ÕbÖ•üÚâD¯Ý¿Ùóþc¬5P OQ·‰/R(SK6ôÀ}?-2ûE3rÛxÓ aÙÈq'”ŽCüp Z§Lk_7XÁ/ÑÙ'Fú–w #™•›-s7™ßïe=«»ßz’…°&n1²ß®Ñóe†d¥ƒ–ŠÄóKÿ¤à˜¤^Á!GO“*<»qð·Q‘™CBÖœÁ+"ŠFb4wOºyog䥡râbC>.Å:|„¾Xq]Ý º’6ÒØ£à1X#zpµOb‘í%Çœu"g¼t‹;õ"[‹.Ú5<“à;ÑØY<“|6ï ©’·‡kâ&¡Òx­C“ü°†éÆé vrt×”¯ãéd9É©ø5‰?â5ÒEEYÊø¾]_NÍ/}Ö)ñ˜ºÅŠbU8!žý³JüøŽEÎ(Ò.­Q— æÌëw#dï$ràä‹•?(90Oñ”kí·Ä?C¼e‘B×à†¶Ç:zß»kÍ}’j#ïa—}üô»ÿÇñŸì‹×Æ¢hêüÇC§CÌ”ÕOš{§Øë)CÁlçr`lïÿÉ?_þ÷6ü1úïq@~z–+‹ƒ×0/¥o[H4{œ_ÕO.<±NžWÀ'ŸŽ“¥œãBzÝS¤h÷Ë.ªNϬeÉ‹u>ç.6ȇ#ë-R·£›#å“PrÆÊA²ž=yøï"‚r[÷zYc©Ž¹,æú|ú6rÆJlÔ/ì¬ýÝœ¿¶½j 8»\±|×îkýw¥«j€í×£ÿÊ´±ó½L‚¿V çï¹Á?¶úZsY8kž6ž??ÈÁÚÇüü—C\vwÚä|þ_ûøþ×E?ö^.?Þœ¾ïô³ÓwWðYzG;Æëôq€ [?ÏÓ9ž¿^.^4ð_/@Ogð)0§£œ1žMìô缋 Èùt®`ðùÅÉÎÅ ºx@€‹ËE +ÞÓ±ÁÎçÏ.íò逧½\â:¹|ì|É}Š¿Ÿ›Ë÷éPΗ³8¸žâ:{´ó>.¸ÏëÏ' ]uvQ}ÖÄð÷Ä_=ÆËùì=Ø¿üøþù·sñt¹X(Ëî|Q\¬('Ð%þ§³<|¾OŸýl•/¹/ ç5à˵u‰Ûù˼¨œá¸`´·ñq=¯¸èá´ðùK¹ìx±2§söÊœœ¿ã:ÁW/âÐZçÍ€øB¥ŸaúæÅ|/:;»²Uý½øÿ¯šÿ‡þ#ýÀá{iük]p®4ßÝÿ&ÿÖ`oןÔî9è\iüt÷/åÿª/ £½»«ó_ó,|\/ù¿k€]Àÿ¢î¯õëó_89_ÖÛ[ù\œ~ýØÁÏtä©ùkýþËÑÆËõç{€«óÚþ{+ð-pÔõu9›ÈÑÆ$Äó¬‘󕿏TgjèBį.§¨¹ýÀà3¥yÖä\›\\œ/ßÓ…˜;Žgó¼¨9ž™¦Ëš }qöáÊ}õÎA<·óçøƒÏ”ÉWž+ý r°rö>ûϞé·p¦g¿ù—þøœñÇ›W% ½½ëßÿ ßsgè‹ß€¿ãŸ#ÿ^§ï tn\/VÔùk:÷OñwqúfÓ¿ÙYçóæÛé¤u@Îßšœáºð!.ð]Úç+«|ÚëE?ð¥Åw:›ÿåƒ^ò\Àré8ØœÊÈér˜ gÃx†ÿ•Óàü­Û‹êsÓ|Ž‘£¶ßoÅÿ×[œèßÐ¥BþµäðƒÈÿàÿï烜]¾ã¹bÚ[x{ºüËíoÁÙ÷/þ¥ N—¦½§ ø»Ú¯•3WŸKuòUÿ_Ô'`矸¿éð_µ¹ Μ¬¼ÝÀßó]ª»Köïô9È|e4@?èÿ‹g°öpÿùÞYØàâü¯:ÿ_®@§—ngó4,u°p t‹./௞ý¹j8»ì½.ÄèxåÏ»\˜F°Ó¥ÏZ¶sw¹¬q>3M§¾ ¾7çNFü'_à¬ò,Ÿg§Ÿ_y€öæ>ž_òi4úéŸéYg§¯QÔÙ<Ϊ®F¹J \•ΪO ©Çß@ÛEãSü~9þŽ’ü¼®úï’C§ø_çç‹ðÒh€çð›kpÆ}égž®­óxý«Cpi{@wç³Õè`åå~n†.²H—Ï ^¬è ã~nÃÏðwrþ6þy“¯nÀ)þnzž!A ‹LÃÙø._»ýæ$\ú@»ßŠÿ?öÿ¢ßpø7"ïôc\p¶hÀ?ó€¶6•þ»\ŠgÁ øWòÿmà%€ÐÃåÛ½¯ÀÔÓë§pâ«Ò]¬þl~ ÚΜó3¡9 ^.ôÿÏñßåø?„ƒ@ÇËŒ&è»›WÅæâ‹š¾öN¯gÁé÷ÿpýÚÈÚ,Ô|©ÎíÍ<|]ÀߤùkžÐé*™w‘ÑYÊ‹’£ÓeFû*ûw$œÇçqÁ©Vrx|‹N~ ³óUŽÐÙéÒœƒ.R¯W&ÿ'_Àáô-_ò³<þ…ùv´;Åÿ2/pnß/¹Ï4ðþgÌ1ÿ÷iƒo;À¯[gáÀÁþï‡ÿ‹0Ë÷â°3óùÅøÿ,ùwöpù¶ô5€?Ãßùñ›Ñvº9³×g<ùÿsŸú|é]Å÷WŽÈÁé,!~ŽÿUÂà[ßNWÛçv÷kÞì ¾òÿÅ Úºº_µû:êYB캰óN?yiÓÏ]kýߊÿ?ßÿûGÑ/÷þîÿyø5£÷?Hÿ]èà™ûûíîöÿ/4Àö, ü³Žw0ñóúQGW%¿¿ó³þÿ‹Àð<8q°ôùKýÿsþ÷Ò¿etÒÿ¶`Oðwí¾ö üñÉþzØN&ÃÛù2.8Õ(¶ÆþžîWÙ¿ËmÀï¶õ®Ü{€ûUšð,ð>ÓJßoþ9}—<ëÙÆÃù*8Wç“9¯ݿСNW9ú¯áÿ™9å}Ë蟃z®HÏÒÿàK…|ÑÏy(ºØ=Ãt†æy_Óº ù<Š»ðÎ;œÃ°uúÛáÿÖû›Ï´5 ú¥øþ0ù·óp=3z?d½é)þòÊs¼ô&O—Õ©<Ï]„ûNßòÿ—ü7WárŸ ¸XÌøÿœÿw_çW/#v#èÿ«ä€3èÊŽŸúΞgBtþæ/\nO8¹þÇcgØ?Jýøÿ³ÿÿ‡Ñ/ö~°ÿ?žþqúQ¢/3ºß‰,ÀÁÂÛÓùßËÿ©œ7ù¹»ï#çŸJ G[w·Ÿ¸½©¿ç¿Õÿg‘–óe¢ðœþ%ÿûsàyFÏÅñ,ÿ÷|©ÿ¯ŒÆ÷QÜ•ÔÚ¼œ¿k÷]3Gàÿr çàòM-€­ÍB<®¶Þ ÿ>pÞ çö;ñÿ…¦æúѯ=`ÿoÝÿuÁ¹<þ”Ñsü.ý÷cÓ¯EÀ©µpþ™á?Éÿ™Vx¸ü zvV~î_U÷O}\¤ìNƒ“¯:ù§-âÑä—¹5€ƒ·;ø/êÿòã¹Ð~Íèþ ÒÿâøWc‚\Áÿù}$š;¹_è‚ y:˜:ºÏ3sÀï÷/ûüXÐÖÝÕé¼t±§çèêòÝvá×#ÄW™@­§ó·ÃAçZx¾s~Ñ¥Ó×sygÙú ¥ úÞ¸P»_3úNæÛÑÆÖßíR§žk—€¯"ýSè쾌¾¾þyÀ·€³Ò·#%€½ýß Û—nàïGq0sùÿÚ»²ÞÆ‘#üä!؇’ÍŽ/Y¾HÝcÏx0d± ò—ý›a×ÕÕ<ìIÄÚ|(²y©ØÕU_}U}>ù×3ìÿ~Ù#âÀ£üÛ—d46ãàÚÉâprKy&49ÜÄÄãü?n`P$üŸFnÎ:`óÁŠUåˆ~wn @WèäßðDÓ §¬CFp=[ÀÝ..)ÿwÿ~Ë9!€rÒüÏà?zMѵšÁŠè£S…È8Ï:ý8ý'­ÙÒo[ÕÎ.Ë'šAņ³‡1-ló*þ‹_ÅíÓNëê)ý¯¶2¢›mtõêØ¦ÙÐðzØ-¯þ¹÷ä`o­«ëÃGª AõBà}]í®ÞGŽºç_ç5G6ÉÀ Ó9gSÓcÿi[€oѱï.ˆ>H§ZúkR]ŠE¨=ýN¥’sŽçöžiÝ>7ôš+ë·$ÿ¿ÿ²O"ˆŸuyýt.ùϳÿ¯·@kôÖü3W^H~tòh4|þá)”ÿþ‡n4ê({öÚÚoA -‰H$(Ž-Û@|~¢±W4 `ù×KÊß¿/3\ÎgÚüŸÖÒ£MBôLy÷¸Kð߈Q«˜@lGôÃÈ™b½id¯¹·T)ùýë"CG·è>†ÔwëŽéænÿ'}!¢—f¹ß¤ë ÂÀÆR¸¿(øïcÃ~G^Y]}‚ĺdàN±ì1Âñ#²çP£=ë ôrIiØÎÐ}ßS.PëÂá` 뺓LBôYþ½è~jM¦ol²$@¶ÖÉß¿!ùÿç±ÑºO³ºy>üë™öÿ}'掚{óHyÆöá]„5K¡[5h‹FNkÚÃ/aÿ Yþvÿ÷!µ¶pA¦i‚g4÷‡ [ LÐ4är.ŸS©ýñÊå¿^Pþïü¿y.ç²–mB€^`ÿ¤[IˆÞwÀ✵Aý~´×ëc\ 0ªJs;LÿJ:D¼;‡.`öô«ûÚ¸Ca¤ÝøÏnÌrët|š‡Í6)øá…‡1/…ÍOûç5; €ÆGUS-ï¿ì?–üºÏ•íÆ'Hs@ÏPßÇ %8ÐWÀÞÒ ªæÈžvœní'l8$Ó½;ã`4ë~“üÉç—hOÙ} @ù;I- ]Ì#pÕjófä¿ù¼–½ü7WËâ,ò¯çÚÿëC ÿ&ç‹h €ì1ã©P‘Ãÿá6ÚìšäßÇÿ ÇÏŽî3¢¯7’?Ý5¤8?¼Ìf@ˆÀX·Uµ£³Wׇc3ÑL9‚ÑÓl›aüw ÿ­‡-pÇ&Ɖ^8ÑÕƒ‚}ÀIšÆ<þÀÈéxØÞ_·¬¥¢¾ N[^·Ÿ6Abz’DVBM)ÀlÈ9MyÀÞ§ -÷¡G oC~yP¶Ãü!ÃöÑù;åßRvŸŠî‹+Ÿ<ý¨Û† p`•T5¢´™Ðɵ}#ò¿ÿº ÙvØ\ÞlÏ ÿr¾ýßîk÷ÕÕñØÈ›ˆcºmz5‚âòOî¾yª ÕàõÝåO§à|™èøËˆtCxmÙh·«Nþ‚Hº?Üž'@”?F T~?&èÝÝ\PþïñÿÙ.g*,‰J×7ù•Ao zþ›8T­ê’ ¯ôÞ]ͺRuõxhòC‡+œÎÄ^c>2dÿ]ì·F4_vüÔ—‘`3vÚ•;„t~­ùEϧqFï€ñrõ·_ý/ŠÄÕñ¹c­ŽLHï~Ø2+U UgöÃ{®èüiö¤2H4:¬Jìh;³¬Š€ŸŽò/üéaàq‚÷åˆ+WC°‘MI1äDœˆç© ÷6äÿ—†ú?y¹z>¹üíœûÿhžåŸ³þùEe«û90Í Mÿwl*0þ¿Øí¾3õ¶²½`ÝZÂ-c 2ˆòo„ó§ãüÉçW4€^5÷ðç ÊÿÿŸñr   œØóûg°éVî{á?ZµÃ’ ¯¬u= æ‚u–ðgšyHÿêkwÌ…ÉOùþG·­¦‚p®×~là¾Ia`ì®e5BÏ~„ÂÀÕÿŽ%€ =µÀâÕó±¥ ×þìÕ•º dÑC='!H1÷M¹FiÐŒòÏ ÿ¹- ñz<(dògŸŸ¢û0Sµ¶:(਎>¸N}Ò€ª)Èkqp*›ÿ/*LÁ<Ü~9±üͼû, l‹ÛÏ;ßcý³½(5‚𵊥÷[Špd`ÿßï਀9’ÿ>ñv² Ð67f£À|’¿ø9h¹p“P®ß+@ ¿³úñÛåäÿ>þÏz9¹PÅ@ô¦“røVªjµVÅ?RûÉË8?&_É:ø8ý'ÓÖåníV÷Ÿ8ýk ÿ‡+âÏMéý„ÿî‰ÿ%dú~"ã¿cn isꮑœìy~²)/!“ô¿ý9æûxÉdD/æ1U‹Õ—-¦é°U 5@‹cH?‰Ÿíû¼$(“‚}Ê:äniÓ(LþÃ;õ £Ï+ÄêùènüÛ,hŸiW² <Ú‹Í]•*ý&•H€Áþ\_Nþ'\Þ—ÿ{95  Â¯XG=Lty ¦~jV7ODZÚ߉ý›‘zpœñi¾?Úëûž€-ͦ(Ÿz³¿éÿD £Ruý8pÿ5‹íŽ8ä¨÷<½ÇOE…!± w Òd àå+4¤·ÛÅòÛ΃žÉë~Z·ºÙFò³<ש̇.ø]€”ì¨Ë×v‡ñÂ\5b…xªü[ ÷â³z}(§yYZ»z—G" mH™þ*<ŒIìB›"N ô»—ÿí7);ØYÜN)ÿÿ’÷ÿ ý_½[òNJÕ™À:š|JãÿU  èùwò‡8W²,ÖÂäò@ÝçÉCâÓ @|œ4$îAù“‰þ´.'ÿ÷ñîËi!€Š¯b¬ÊQ}´§ D›ÕÃÇv=˜²U÷ÿ$ЙI%÷Š=yZ×ÇOƒô¯iÿò‡Ü:*Îaü÷~»… å¼Ýþ›´»„yO±ç ކ‹?ýv” @ð s„Ù=¦üðyaÀd nXïõS ý¨á:­˜ÒÑ9ˆ5Ã3öG0¦SëBÆÍb ħt<΋Ç^$3uöË(‚òô¥˜JÞ Äè£cй"*±ËÑ|Aæá¿wùÿñ7UVô?‡Š_O'ÃèŒûÿ¢“¿Ó.¹²9Éß§éÿ`ò©6HŽ(ÉÜ´ÃtòG³$þ;, íé»ÞO…ÿ3¢O‡°ü©T •¼¦¬þp9ùÿþ;openimageio-1.3.12~dfsg0.orig/testsuite/texture-grid/run.py0000755000175000017500000000015012271062644022152 0ustar mfvmfv#!/usr/bin/python command = testtex_command (parent + "/oiio-images/grid.tx") outputs = [ "out.exr" ] openimageio-1.3.12~dfsg0.orig/testsuite/texture-width0blur/0000755000175000017500000000000012271062644022134 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-width0blur/ref/0000755000175000017500000000000012271062644022710 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-width0blur/ref/out.tif0000644000175000017500000006700612271062644024234 0ustar mfvmfvII*Úâ "*22=RSFNÕm+^:vIU,`‡D T ñ£  Ú 2012:06:19 16:59:39€+ e·ð „BaPp .Ãa°øLN‹B£0¸Ä^)ˆÅc‰ n ’Ã$‘(d¦5.FâÑÙ$®!*–È¥òiľožÈ'T üžy¢C¡¯úH™5„Sá4Ê\‰ÿOªTæõšånoªÕ@@ c‚Ú+ö{0Íc~Û ¶ëÀn´€.7K½éÿ|»^/·»Õˆµ`­V«¾k±¿ä5Û «)–¢Á«4ŠK9 ÍÓtPªe^ž‡ÕõMN›YÕh*zêÕGi¨Øë75­ÝGg«ÚÁö˜ýIÀâjv{íÖ{‘§s£üþÀ‚qdý©¤~-ï÷ûsš„{ÉA Ì%s/;<÷û|½ßƇBñ}©T©e&Pö?É Dü³ìÒšÔ#nC*¬Ó$­2¬º²²«¬c¼¬°Âú¼®«k À±Ì$DÁŸñæÂ°ô; 1Pº¼Å±èiü²*ô"¢Æéœc= ëÌÙ@ŽÓ¬êºmkŸ6#ŒèÁMûdÛI­ë¡)@ΤÜ:M{„äHîSO,ËÒÛ™%ÊäÀÓ¹j#°‚»Òå6À/ ½$h£èÌ£“£êõÏ 3úЦºg=G#ã½SÌå<ϱú„ò¨½"ÑÁ0;îä»rlèÒ±Ìw ÆÌ|- F¨lW ­•O\/5Ôw×p– ËØTìzÉáJD»dÈz»mZn>'\–íÓ[ÄÇ,jW;¬ÛjóuÅsKZ„‹§9[˜é©åj6h—æ#‡È6>!àtùxOÏvý'·üù‚GIËá{Ñí?¿tfèûíð-)‰Ì3Þ/dcÆ4¯A•õ=ÔyAZDõnO˜åY…feÙg9Ðóµµq›2Ys޳ ®{våk|QQeù°ÔÀ›«é|mÅý¨¤ý”{pŒ®&+¿Øh\+°ɹXÍàRsPv ÇÈ*çÝ ¦e,­XÁ‹£ó7W°‘£uv°œ«³hDýÛ1fõ!ky-e¥=¸k&¡ÛL]LnÂèzö"L1ˆ+µè”•—3ÚJ«®IÃF+‚à\mf5E¸Üùc,h~“ 1¿SëÄÇ‹ó,™/æîC Xì6)Ìðÿ¢my²B•hêå§ 1±éÈ–e!Ý«Vr Ñ2ÔMàƒªdP†=lj Ú:X†ø‰ÉXÛâ\™zòÚRÊלÅ(<£z2††&rõe…•’®‰<–—,¥L˜x±*[Ë™vÄŽäÅú‘¸8žzfŒanº•L¨ÆÞ” Ï‹ ó¸é­%ÉôÕ_­µ7$5Š´pbÅp¬B5Bæ tŒžEÚs:‰×<|ª±V:X8…Õì"’q@ØLÇ +*-½ÈM: /+c­.õ2ËU*Z‹ÇjrŠDh*(Õw¯4B$Vêìº+Å…ä:\Kªt¥)Ušš1>góJé•-‹Ž˜Ù'ã›ëü¥q°£¶ªJ¾iõ;±Ž,Ñ,k£„üSõOz‘kê[§Ff©N¥^­m´‡ÌÑ[T£Wjã;T6ª}œ*É ­…´ŠÐZ)(RLÛxÇ6¹Üãt(Mk¯²zMÑkw®¼´ˆ·6ÀÖó+èõˆŸòüŸVgï0\ ±ôØû>ÃÝ3/»í~–zË>(Ï}#N˜–ŽöJâ<ÒÔ¬‘r1ÍNNp„‰sÖê©ÔùßmÐë)‚UBÞ# }W‹]¿¸NÊÜ2' æåô´7n´W[¹[hŽ0‡O"ëPùM\¢$<¡wеDxßwâD¯Å—†³ä[º+Âè]£òöl;‹?Ô–L™7È›8y‘2Å(¬Vƒ-_l­•r–Q±Wò+_Â9XnRnÀr¶äíl¶J>áH+† 6x·5J@gIÊ‹±!1®ÍžfÉ%‰òÝaÌË’ÐÜ«©w%ž=ÆU¶C}-®Å• Æú9B4ÓK®÷KOš3ž,2NKɯû'ӬŔ,å$йa÷Óu ~µÅ˜a62YÚR½©ÒçÂÛÛbÎ7’WmåüÓ×ú—x“ºhyÌkçhT6®>‰¯õL§hկ׃ND¶¶Q^ Úªâ¾-”²Í8༠gknÑKµ× ‹<>ùöm^=¾ã K»Í••ÞDùØÜã6Gt(Ë­„ ð–ï áwEÊê¦Ôñ¹þr_#ƒ±#²Ñg1^ÍÀ|ϨéñÜýÕ]1ÆAé»xi_\ê.´ê¯XÇÎŽÔ«Jöd—mþNnê±NÕÍb¤Ëã ®í«&ønä¾0 §‡ Ì)¨àNìâoèhN6ÍoÚÙ ä<'&s-šûˆþª,,°dåo0žªŽèîS.v¹ü:ÎÄýåÀÑËÀÅÏ<éoí¬i M(éí6ÿNÿè†ÈoVï ð´ê3"€`¾ ïhî+H@0‰M^âê^ìkââ/râ ýzùn2çð;H×gzãV„ê†ä ÂÍÈüä0Aï¶V϶é L*æ.^¶H4æ…rsm²ý¨B0~Í.x’g FÉëJþä¾èï>ÔlvÝïó +­ ïä»oTÞÌ ¯œi ðÂã'ð×ðÅ ¬ ׯ‰ Oƒ ÐÖì°Ùè×ZPä÷HØ­8iëXŽ.þgÆtµ ´Ì,Ь«‘l4ûîTEÉãOsLâF¨ h*o0€ú,ÀŬ}qRÈÍ&Üïýô£œ¯´ßPP±‡¤° ±p§­ƒ fÊ ýl¦á ~Ëzᑆ±® ' ¨¥­ŒdúJçÊÀä‰íHœ ¬ël2ñM¢Ï û)Ð_RY¦#0ïp0ò†Ó íäÒêèœõ1E ÍÖÆj.é² kêO[) -+P …¡l Á1èöÑ–ÌnÜ×oy 0ë#ß-°4²’÷’ýòD^›$ŠFÁ |ÍÒ„úPxÁðVüŽL©’t¨0ñˆ3‘'Êu0_'ʵ'å.C(qàòèR€=‘jº2”“ññ ¯6ô2ÿ¯9ïO+«³PþMÌ!ò¿,1zàèÀŽ$øÑ„â²Ô½²Ý#nÓ-ìUk×.o‘’Ó" *äŠÁ#5O§/îo2$4ûS ¯0ÓñÄ‚Éß1ó1*u±.œø¸j‚* :°368°²Þ²› qòô4ÓK3™5Qi ’+Ž‹´à 2ų‘òA8³pQ’;7l(±}7ìË.oT6ñ9(óõ<§ˆc3èr]:qÍf³çA;Ò{< æX-¸ÐÓÌïkRðRËÌÞsãl_4P¥ éA)ó@Ò³ðÝ4ŽÔ2´ë0¬4aq@46t þå$M|Ê”šò3Aï}7°ó@Ï6´´4¯JN漓0ت‡n?:-™DnO:Ó»”O;é:²sóWfqʾý+‘rƒ6¨G.“Ir—=Ô‹ j*Ó2· uGq\ôÓë*ÃŽþ4›RB Ä T¢ì‰3L´ÄËM]74½ÕOK°%LÔÃBò×Lî½TjA3ìKC°£CÍ‘: ’©EÔêÓ¶å¤90ñfiäçL=W“ÉFte­Á"QíPÍ#QGQO÷R+¥®p“IU»Qó;?u-5q !áuSµ>ÜPÉLÐÑL…At#Ow8.èmÒ˜Ðí õTPØC´´ÒõMS*5Õt¸6æoÆÎÑȶ±É1QÊap]2M ïÏDP'î8ãÔ (“üHSÛ4zl‘I=ò¥HÌÕ3ÕÇu#I5ÉV“^4Av `Ç]4 §°?_´# Õß-ÍJÔ­g¤ã_*G.³]–ˆ¹mˆµ12̨”ÝO“ ¶.d4Y¶jî`åœÚñ&«f9bôkTxµ½r’H5Á}yW˜Y5ù6Ô¿ WKW "¦_©U·%.q{#Õgp4s3·M‡‹Cöú´ÞµÕŽBï±t5~Ún[&£ÚwçH`©)~çiFØ„© VÞèpf$€†›‰ jʼn•·[öXþØeõ )~  Ë‚okyÔ&÷IP˜Hì¦è?õïŒÕe^W›˜‹h÷û<é5sƒY9Š¿|Õt‘²v©N‚òsaÑÆ÷BðÏD–¼u—X„ ·‘xƒBpŸØJ—’Š’ZÕ§’•¬ˆi8£CxžóWƒ€8«”X–Þa‹˜¼wOŠóGƒÊî ™-8ŽÃŒµifíç9M8É¿Ø\æøaF%“ a“ ûÓt”Tñ±Ïu6B¸‘lFvøï2ó„qN}¶í”—sxöC”‰¤¿GÙ1”5¬ÒoãW€(€0 Ægð„BaP¸d6ƒCâ@ŒB+ ‹Ä€1¸œR5†ÆaQ¹j?"†J"rHì®[‡J¥ò©,¶e/„?ãÑ9Ô>užÂ ÏùìþF Ò#Ôª.@ 6§Q«Ôª•§íj±[©×@` ’¼±Ù_¯ûMrÑf¶Øê6Û ¾¿e¯Þlõ9Õf¬£Upå>…€ÃBhÑ D¢#ÅÈã¹ÆV_AƒÑ'™lFk/ŸÏO³“­ ;1ÒiñYœž–ª×ë´SÍ–O9 ¢l2ÌFS·àE¦òi´Öc'ãÇçsI\‡ çô9ÜÞ[Ðêv%=ŽÞŸìl4ôß áÃ`}1êÿª³ï°|kµ›¥Ãåoµ~?Venâ³.«’Îú¯L+àÁì#ø©Œ<ȼŒ;Ì8̤$äµîÌ4Ó¶­3Àœ·M[,Ô³q§-NÄCÍ;5{pÊ·.¤PêMêbŒ»°ÔzéGîªBë·èzY ²R4ˆŒ'äƒ&:’\…(Èl¬ž™¶Íœ‘AÑKÐÌÁ2ëX¦Ì\ö+Osã¾ï¤ÿ>Ïœâý?ó’ç9ÀOäó6ªRû5©Ì*þÁBoZ+2µt;í<ò,“±‰lnÛÔ' ÆQœML¨ñU9KµŒÔQP3´³[RF ÄI "fÎ3·Î ®ŽÉÌä{#¸‘ÛŸ)(NšlæÊu“²ãVr÷ZU•ÌLË•MDÙ¯KÍ2Á³=@* Ýø?3u»<\ ¼èû\SÜÙsÍ+:ÿÐÐ] EB”E1ÙW­UY4¬K(õEQ/DÝ)µ-W-3tûAàM:†˜•}cYG˜t¶â»–†‘G•õåX´YbbÒ5€—d²„lãÆêT¿wE0Љj]¯lп[yÌï;-Ó«÷pÜs“ó=¯ÕÐøOö´vf—ƒª¡¢÷•zeYD®ó_ õHk”åï~1U6µ‚aÉÆ5&R»;ZbF'”ÞryG9¸Ì•»Ø(Æ<ïXx®é_¹RnS_;»œïÆnü#BÞ™v—0Ú·M³œi+tŸçyìçoh9þ†ûÜб]LE®¥uv{ŽB܆/×&ûã¯a±R…l{³ ´ÜV³Ú>+c–ÆÇ÷ÐÖá¹d8¦ûÀcü•`¹–>§c:É—£a»ÛÖ-¨ûþ\EØ÷<~chæO_#iró7-sS†xúôw-ÁÑþüýé\Úƒ~n±¥˜•b݃}jIlñµWʪ—ó+y¬!ݘðÛÂ`¨€Ý6§ˆ†TÜphxcÒÜÞä#dJѿ“¶®áƒÓ^Ï]fB¨\­’ ^nÚ šgÔkzÐZ%÷@VhµÇòafÌá6?×ôЋ³¡@/íÎ.5Ä›š9[€Nµu®ÕÞ¢ÒéŽfmÙ$(tÖ¡·_®ý¶¼{ ´ 5°M‡›g”ù ¤wkæXcÂhPÉ^û$:Ìj±ØdÕY;³†Ñ’@,XÎ’!äpdÆÊž$¦äjÐLñul¨1ÿÔNsÑA3è¦ÿ"©ÿŠéÂ,´¦mâ30j©y8æðƒžÌ‹RQ¦7ÇvÝÌ»n—ñ€ÌðÁÛC ƒNö8‘‘¥Ò½CPâÈvê¯ZŒ7oÓ]ÁÈøpp&ô;œ0QíÉC%%¥´Di϶Nº§åʤJhÑVS¹ç;)¢¢ŠÓÚy´‡RæeƒL—Ò0©ØÄ“ ·jIä¼9˜n%ã)—òú ¦iCâY˜³‘‹/ùŸ È£åœr)*¥rhà•ÚU‘‚h¤ÙHáYÒ¥±Ö˜™ƒT…§UKˆB¯F”z§‚‰.n}OW@ϟᔩ½¢Å9Zº\Äÿ€qx¥’Z N Q¿¡2!ÂF¨!CªôÍ£TÍÜÕøå#X¬p}MV¸õYYHÉ Aª?Ó5g ’µ*bò䑸)ÁY&Ý€šÍÑòX*i%×½Xj®œÅús+ç|î/OÆ¡¿iC*gÍL©VZ§OÇ7?ª¡–2f´ãÑ m}°êÞ‰G6¹Cã]°Õ´ŸAÛd¨­¤Æ­–†A˜ÞN+•taÑž¼MDw`Ƀ J“~Ùл›W.M͵,6›Ø‹ûì[4§ÕNv¹™@Uäýœt‰¾{ÅIë*Q³¶}ÔZ*~»`Dµ}‘1W¹ms˜rÿ£7æ×[ Ÿ1(ƒ»4hÖÝG™–Ø+¬Uκ¾7Åq¤"V¤óq”MZYðÅФ7þéà ªã/¤˜iôõùEȵdIy¼.unY‰QRjEâ©«’~ÞÜO@'u¾2Êù¾Š j¢y„j^Š2\‰0íí†D(uµSkm’hµ¯¬(ŒÕ`»…^–€¥ØR…HjM"jîÌY ]&ëMœlu«²‚Øû¹ç”ÅsÑÿ^YQyñ¦0¼u=g EŽŽ]ò’µgݯ6¯åÊZ&`Üü‘€­õgÒ nÜå w¤—A¬5àÚ"ÑýÅÑ âäaªe s©dyƒ%f{u± Äx‰ø¹Z‚{3› Å³ë­ü_Œ¯V4½‘/?g 9,PšÖznü©v…¿F5¡VhøÝ4v¶ÏŽ‘îêí½%G2Ž–†Ã/Niêɨ^ò¶ËFêU»ß¬°ZX­c›,së½÷w8ωy%¦×ò‘ g‡õŸ1D 5RYÓ¨¿dcPÝÐÏFK½©Gw†ÞÜß'í¥~ÚìÂp{“NÒÚïºoÆëµŽOñž]ró-³Þ›vúñ IO5¦Å¨¢ðYNeóÖvà:÷Ÿ´GMSV8€” dãø ¡éŽÉây…|ßÜ ¶ÎØ¢;ŠÓFÍÆ­åkì€ËrMÍ™'(¯ü±Hê±—9qí|Æ™©r‡Í#+ëˆv2ÄoÍP“Nsç×®ñðN…ž3½–èÑcôš¥±äÍUéÕ^¬ÐŠù¢-–ŠY}×¹`¿Øºïc°ù2Im6K{7S‘¯[=ª÷…r-ó¾Ï ÜzZ¥¡þ=C3§¾fÅÙ5Æ}ð·ÆTlòÿ¸.Ø2Šöxê£ä 32ª×Ó‡ìÕ›6rÎSêÜ_¬{M#Æð7ßÀ¾†¸}Ëc‘€ÌܳvGsY5ü¿®ê?{ú{^ß÷MG¹Ðy§ýÚ?z€®zÄ®g'û®†Øˆ×ŽJžáLr=lLvDj´ò©ÎjhtGª&äNdþ¯Îì.È­.<Ó Â™/2Úd4ýNJ|$|píXv¯TÃpcÐhpÂf¦ÊZpLÿGh§hŠÇODÔ‰®~×N ³/Å‹Ä/GJÖª¤ÄΖï¥Ü´°* çÒÍà­ðF°²ÃHôðD@·n³c-Fæ’/²¸p^dÏdšJWι­@ÞNªÛçÐãÌÖ÷GÞ÷–r†oI\~°™k4Ÿ„Ÿ‹FxØe´éLÞ鈽 ŠúÍ ŒÐ³Œ9>oǪÞÒL¿Ì!ᘠ€ØìïìËPnîâÐÎàîhÛŠíÑHx­è÷jtÿ¥Ør1L« ²nxà P’³m|Š.‚Æ®‘ ïüi¬xç±±+0dÃ0µ jÉ ¬8ã¯Ì5ÊÕ0¾ãéñR°‰¢Ý°ßol¤VÚ±i±ZÚIãDòç&gçPçÏ~‘ï  ùqù±œÐ ú®$B)Œ•LÅÝ M«ÎBaæ×PIå“ÑTâˆUML‡oïÑdµ±ã&>IìЭpy" °Í¤A*ø ¾~‘‹ Pðë2àñ˜ñ¯òpú1¢›,|áÑc¸Ñò,ƒ ã Û#M-¶ãqÆâ°SFþnLËpg%å)­ÔÈrZ°ô&òc2fæ®ø´æ !Nu/‡' è±h ô+=/ØñÏ¡(ð(ˆQ(ÕÆ68pü’¨Ìn²z1¹+mEqÃ2nA³$RưÒM,ÒȰ0ÞíU*2Òó£#¦XÒPxßÿ©cpá ¨ò÷/ÒúùO‹0æ²ÿ.Žq L6ºkîšnèn‘³Ð;’¥#3‘fï?¯Ë$Ï+ÓýÑlÚ1a,±­4RÑ4«žíR²ôòÙóWÃ!Ñ¡66PŠñSj³hŸ7 Y(iý ÓªjˆQŒ@þnV›Ó:p½S–CrÛãHÒ³É °2¡›+Î_3³7;“·%OZÓ3Àã)yþÖF_p$f° زî‹3g> î‰'¨/ù7òäêGg!ô0õço ³Hô³•+…)*Óœ¢Ó¡m/@”"t#î]B“CBѯ$òW;ô7I¯´·4>}´Cñv0É7p‡>Ñ oŠOŽ[ð”Nîp¡2Ðeá"Nó1.¨›“+p³%Ó0FÔ„ìŒ üS›HIr¿L-Ió‹BòÁ;©J­àX§œ±ìǰumm5ówLIWÏ— ‘—ðÎo²D.ó{D²éDeFÊkÔ+G4{Pp¹-S©AiA„OA3&ìgH` €3M†Çð „BaP¸d6Ãâ”R% Å¡1˜lj/GäP×üŽM'”JeR¸ÄªK—ÁãÓŒ#5ˆòù,Þs8ŸD`´ÔþsQh@ M N¨SÚ”S©U*ôêÕb¯]ªRl Ý’±bÙkõ[e®“%¦Û(@}J{J§Ô¦×‹½Þ}œÞïøæCŽÈ°ðiIJIŽÈL22l\£,àäùyÖfœ‡è!™ìfNS8A4Øì¬/ ÖËfQŒ®ÆG¶Õéw;½æöO¸ÍcáèU‹ÃÎéx—Ê5D¨Ï®=;ÍŠÙq·Wº½«g»O´ÙûUorÍQºÜivøåÂñC¢Òo|øOÓŸÂLñ‰£–ß80]5Ì›DË&°;F’$©ã,“4¬â¡-J ¢í³^¸ ±,Œ:ÓAPÄMÃ0ƒB¸ð“šïÓ–úFŽkÞ¹>.ÛÐò­¯Æì;‹2Âî<*ë̵¬®¤ŒëÆî¢úº/.rõ&ŒBˆû¹I´e¿­ü[ ıDÂÞÄiƘA0{CÌïÂ%À1B‹ NQ A2̨›iÄS”Û:ÐÃq1¸Ì½ ÏÆ0”g*QŽ‚ŒõG1ÛÍ%G±úó$GÒ‹!<êÍ9 Rt»¶»Çr} û.ÏįK ÄôÃ6äÍ7ÓüO[5qVÐRw4³p…@€¥‰ O \@™7ÌíWv%¤ÕÐuœ^…ÐìeXJ²•½ºR#&T7-8ì¼”±ûMÓ[­tS®³¨§=Õ-§½µeW_RÚ7U¶V{„ÙÖ¶š?h²•ÓW_ÍSE†‘ͳe§cP6F•YrÖ>ÌX6=:Ú¸)âÉN§Y“ã!±·:®?µÖ:ÆEk›ƒ;“ÕYNí•Ü9n}q]Î܇tÓÔÁýMæîþÿsÇ—†{Ÿçû΃¢_z-ý£ON2ز­ЋíU»'Íê˜\á·î6Õz—k±6¿Cý(Û£XÏ/Ïö.«ÎíΖÉw.IÁÛ¤³Ûï…ê£ïo‡$ñ4Ï›gŽgNç1çQÉ™Zê›èZ>íÉQX$=/õüÆÙà½×HÛ÷=¿GÎAtDãõØ]ÂMÕêSÝseU½—vˆ«h}ïÑõ@VÍs¾[ à¾Pñ³ÆG Iä*`¨ž™_paÄ.§¨ó\;×eÎ5qäžÐÞúúK*µÊ¿øY  [Jið"C ÃÛ¥jÆé5Ho_Á¾v.º@rÿ¢+ü5Ñ¿±kÒêÖ|ì–ø·¬>IHtÎເ- é™AÕ>xãØoâ«W‰®œÈ ØøC" Ô|fš&B##Ñ,ˆi‰Èxún[sO’8¶[ºûo Œõ®()Y“ÐpÊV38X>òÞ´k{ BgWêü…nQ¤É_Q\Lb^bL6¹!$ìƒ3þK!R…äÄcŒaÙÍ'^û*Ó b¨]&ŒK¿UÒ~*JŠ¾à¤¥‚‡xð¤t‚ÍÜÞqºz2÷ eª©9ƽÈG2ý/ûåm¬^n¹›7T »‡öd¿* d,Û%r%±MgöÙÐòv“eÑ)9B"/Oó€–Î"ý9”ZFÐIG3ÙÔËçc̃ΠV½ë<'´³ŸÑí—Éù gòVrô;Ð9°Àht…¤.@¦j='UõOŠd®Cš(l(±»‘´dŠÉ) (õ˜•f‡Ô׿lé1¥¢,¨ÃK- [Ž‹´åuÓ)Y<™ÑjyÓ¾AhDöZoJuðXVê«QE} 2®ÍvÔ+Ln¡^ÕÏD4;%”QL(F(厗ÆR²6ÊÃdôD4T’:ZNðç-*K,º¸ÊIdT%Rñ„žU½YW*§–OhæSÔiOçýDŽ–Ø´ëmt6¢nºz¥fšËõT• ÐÚf„0ZUnСú½hi§ºêU8ìëIAÒíE¥+a)em¶ïAs[ëy¯ôd¯·œ¯kð£.4·°×*ä¾÷b¬b\³È0ÓÞ¸¡Bª•סxU‚Ýr w¯‘SMWØ»Äb­,—½V£áË/Yh <'gêûÀâl×½ù‚wòºJÊq+«Í{ž6íž¼ÉÒ¸ðM‚h–ÖÂ,¿®n&¹è‡&¼]…ˆéÀÃÑJǦ{ç•«+½²uGJmXTÁ9okõ¹«xêj*€¢f¢ä/ð{}Éœý?©€­M¤zÛÍQŽGsÂýsYòoéýýÏ}™*/^# Îÿç°Ð. ‹êð„Øù ÑBÀG$b®¨O¨?(ìïGÄõ‹FÔûh óŒFÖ¦ ÜHr[NêºÏfPJÄ ÒÍi¼¨ä ýðX¼O`ö$WÇX˃¾LÄÌ-z&¯ùÏ|ŠËìÏÊX‹ð¸Fú®­®ÙMŒéf‚ÑîšÉЬ/ê~h©€‘Ð4©bþJ”Ëœ}Çâ¡H~pLÊä05Ìö°nòð_(dDpfÖG‹2æð*¬å Íz°êÚ[P†‹køoœŒ+rðŠfƒŒPŸgŽžï¢±- Ç,ê&±O²Þ¯Ú1HýdÓfµ ÎN“‰‘ è†i ªB08’00íŠûJÀä±A¬œ t@,¿ MúP¯ô‚)Ðñ°¢\©ÚØ­ jÈp’·Fú^ÈHé‚ì{¬p¸ÁÎ&ên1‘i ÏíëLu1läq{°3Ž8D«¼5HñÚÂ*ååÏ0öÑÌ}1ntÏ/HçÏ‚éËj¿H¼·ŠØÏ•qøðùªr¸ªTÉÍ åX¹¬Íf2ê­µ«Ý ˆ»‘R4l7îºÜpò$Q×mè´»è—ohþ?=hbµ…`‰¬ï .NÏ‘ *¬xf,á çLÈoãÓ0"Ÿm¢új¾úÌžâÑæ—‘·&²´ëϼüÇã$:VmFüb>€Û’bC‹¡-LHOCZǪ̃X‘Ñ’·,cOwPþ¥(²œ‘«ˆxÒ‡m™0˜•ò‘!¢ÈÒƒ¸Ñ©S%ñ|Ú’¬†5rë3rí'Rñ$SA3îéíÀ%rÍ-Úë<ÕÎÚY/^ëf£.hkÎÞ8Orα‚8/zŠÎxÇÿ² ø“Ø’’¦¯ é2ŠG²ƒ)«ôŸãØŸ©q2‘R4íj³ 8YBC,sFôPB»3jXNI4ÀÝ5 ¬H6¯âcVaPQ$ÑÀæÒo/úÆ17“ï Lþe®‚³è‘›8¬ƒ0Ó†éQ#)òœú´Ád¾òrª}730á6³%óg6D3ÈtL"p¢G:ôfÔ €2ÍÆÇð „BaP° .‡ÃaÑ(TR ‹A£0˜ÌZ7‹Èb±wüŠM’ÉåR¹d¶Dÿ”ˡӜ"S4ƒÎ Ó„"<œÆ!2YüÞ…DR ³ú= —I€çü6 R«Ôê5ª“ö·Y‚€ÀêèÅY¯X­6;5²±mµÚì ýÖÏu©ImôË}æ›~‰i˜8>5PÀÅ#4Œ )—ÌfsY¼Ìâ{'I3ó¹D¾i¡—j3˜W—ÉG1²ŒG'·Úíf[¬Æ«_©ßðu;éµBk£B¨ª¯‡MÒQz8Žu*ÿZÂU/½ŠçvÃnîÜ«wo~Élµy|~¯M¾ïÛ¹öïU ßÓ©Œà:˜|e,Ù²oà ‘£lÛÀ £„Í8Œãy¥pj†Ó¥­Ba B°šU 8&R‚¶ t‘!±‘·*DB Û}E±Šjà&ÑzHâ¾è[–©#¦ (±ìrìºêz²˜*Ëû< CØð<‹»Úô+R›¾¹½îô”ù©ïš‘/2Ïë ­¦“ U3±L*’MP$؈D°DÏN“ª[7­û= Fî{F—¦P¼ì‡C{]AÀñ åÍèº;92“ÃADCq…)¹é4)LÓ‘¬ ¹‘ú‚ź K›.©²$’ý,ûá%<ï4˜ó¼Rk*V/RË,¾/´-ºêªù5KóCöÿÕ3j}4¿”ç8Ò rOIRð…‘jÙQœ+KRÕ4ä´ü2ÞÛˆy“CD }¨Ý²T“A7u°Î[·›K[Sê>47íÁfÇÏÝÁbÔR ¹bÉ2%^«UÒÓÝ&®•Ü–ôÊX†)‰áÒ«».L‹­‡a>Ór©?–DÒœ16R7“DótYxYw¶e™ÆI-Å}%¶ ßsäcnÜô=­H³6„á9Ú4v‘læ‘u5;^¬¾¢ã8—ìq«gj4„âºQÎ êÔöMUàõ†^ÖX”ŠÖ’}s‹ËÍ{/Ks3ôùÙ¬6Y‘d¶f—–@™A:V›Ã¥v¼©ß-4a›Ô5žß ¡8hT½ÖÚ]¼âUwé)77=qÕíÆ9É 7S¸tœëTä¿ØÈ¦æáÕ†¹ì‹–ÎõË/%[íò¦ã´WXÞ=5¯Û¾;“¿6%eN~SÂÅ\S*‰·WZ;Ññ ë›\½SOB\‡S§\ˆ1Ì]-_;ù7p.—£ÁVwÁ¦çÔÇÆ¶S;GDé¬*c”䑪B`‡ÝÚ6%’’ãcnJÁ&§Œð »jb,i´¥¤²Ç ËÑWï:¤Ç á1ûXËHÙ²¶ü´^Ó÷2pÅľ'à ¤gF:ÒfêÙâ•uGcÖüTcšeëMg=‡í _Ü6ˆn6)Cã:hŒó¯TÕO>´~ë QGw Œê*ƒëB¯;oXô¬] Ompxï=8X޳Íd'ù’@ò¶ß^«y…/aë¿wA a”8‰ÄDÞE«#×¹¢ŠŠž£h…’1ˆ±˜:&ŠoÔjÏt+NP¿HøbÌ;|N¢I…ý)â³µSrÉØ5ùdØL$yŒ¥}°Æ¦0Ücb³y*Ý㤤®ÇcÔLéfÇÒ~Þá[€š-ú4Ã)W‹óNÒ:8"Y7<­‡.RLNWXNÖûN‡¦lb‡)8ŒTdàšÊ9h=æ`ˆç”Zœsè–JÅæÿ`9ªfðªNc?âì vrاF%Tò›"­—ÑΊL&ð ä;ðåL˜ìóÏ´ÍMlž?½šH³&•(Ac(ù‰$TN“åÊÄ÷å‚Þ“/šI£!ˆçzu¥Ó~O9øi>!¬K¦ŠfEêw$ $”Ft¹*UŽk¬'‘Ž[•QCÒäc>±¦:×EÞL˜ñ½^<”¸cÅ „qìÀÌÊ@´›ä¥(jH8›K},”h¢¥Ó&ˆµjj‚Ÿ°þ )8ºÓטÕ%MÆW7Ú3-‰ruÁ§GSiê”} sÕ#9å©Õ€l…½fÀªü a2íVKÊ'1 ÄÀ­1¹‹:án™ m»xK^<Î…-ò½Íx_ lÊm†/~ÁÄÓ#a—…ŸŠuݵ=i”ÅÝ»ÈA›Œ ëe.Ì2¨·U–Ýç{ìåÖtŽTÕÚd%U©µž¬K · m¬«ŽÚƒÐÖ>S¥í´nNþ8°ûu[p…UõÄùQøôÝ! äP±dfIsq+ºWFÀ"yB‰1» §¸»÷i/Ò>j/’úÔNv½ Î÷Yµáªê¾OåÏ®9÷‹l5U§æðZSIMêvkv¦[ÚÈìmŒhH´4¼Öx'„íìÀ·\(>°+ŒÏÂ÷ ’Ü£ñr¤F¥÷9](föZM™› Ãb¼üp¬Sþµy+Nˆ‚Ô'áßȼXþŒÝ—›Ú:øËµ>í+jttå*q•ývX Á¸íèc¶)w/KªÈU0‹Å˜¸:´–Ú8Us>kÂë"=H =ˆé &&Y£HYªöÌ*„Ïv˜^Ìÿ³ï½_jVñ)Ô5~W¡+ÁãFœ,÷ô¬žqQ%à ­.¤ïµŽÉn–‚í8´ÕŽLªúÔàÀ¨§D¹vÍbÆ|\è”­µ£«ü#Õöqö×i˜ôMžØdS8lI¢nM.ºxs!4Œû|6…~¦[Wk>gË”)Êä˜Ô‹‹Ðõ·a¿ä¤ÙM­ËQ,DWŠY7AdÉ"uíÞ¹Z-ê*½ „·¬Š3¼¾G&>`˜¼Žæ}rÈxVy—aþ(±úýÎØ¿g2…±û>“i•;ÄþCÛáæ3Ú÷ñ§ò¹Í?h*aï˜4;5¸1öâÅ;‡™8D[ÐY¯)ª®Æ•Q¨ªÕàÀ¸ Æ Zu¥Ìc;5‰²ŸÔ-ÇTaä—ƒ¤Ío­“'Y¤¼K_·‡³Ãó†Â׿UÀW³só©2 _fqû;Ü'£2îÓv,-½¥hM/ÃФÈ\‡ÞûÎ)Ÿ°ø§ ¨¨¹ä¶é¾f¿N÷v®÷«ÔnGRèL¥åÕ/IŒ…S};¿9Ž÷Ÿ‚¾…_k\)„Ї÷£~§^Ü6ðáI®ÍÊô¥ ”ž®ÂöÇ´e æªøÄÎlÙ®þø$å)Ö[¤.^¯ù&øâVàþÛ­Î3 {,†æ’°îÚÚ,pïÈî~’Í ªˆÀ¯Âò†èÐk®Žý¥Lß„Šýë†éïèá ŽŽnî*¬ÖþïZ׊Bâ ’¯Î¼YP¦ìOh¯¯nØ ì¤ ÙO¤ä I0&j† D,´o”³îò2áj (OÄÜ ‘¦ï©/–Û-Øä°VüL–’°üŒÆÆÞç¤ÞжŒ0tÊðxý†FclôâÎþMh/άyOôÖÏU øØ.ëp ¥  0¬ìïjã,ðMQM‹ím¾h¯} gNùI\¥¿ ¨xÝc8aùë­-̽kÚðC5Dò†ÐZçFq BÊ/$\O'ñ 4èòÏÎýH¾ßMü„¤ŽÕ¬ÑŰþ¢Äõ±:õЙ Ïþâ¯c ¢·© *Qäº ¦YñTÄ¥— ÎÙI‰VÑ1xÆ,œø«’î~5ab±IàíË0sÏÊjÅèÆÍñEî Règ׊ ÑÃø`mHŒQ¶À8—B`¶±,WÑ(ÿ1Åîªhñn¹±<#Q>Íî¹¢1ÎÒ÷0 ìí(pohÏ0¾÷ï‚”è kùhäÕ"ÃVá!¥ðI Ö^0ðð¯€Ðˆª•'PˆL”éfñϾè±.1ª&Ñ®‹ê»Ôcïäl„½&/÷ rg&±Ë²‚án¸#8®³¯R„öŽ*ëò€âÆSg¶ØÎ8ã)J÷ˆ™h«/! œˆqÝÉ$ûÐ\îc.+Í(~³a,G ñ‡6ORï´}“r¼frï.Pc$KþÚó‡$2æ9ñ%O3/Rû1[9ÏLÿÏQ%ó ¤°’¯Q9óõÌ?(B§;ð¸0S#)ã2¯ew3n6íSlÒ3@æîG#²$O‰4m#3é$ A5ɶEkáÓfÈno>&>îvèLZCÞ93#±¦ rLü’PÞ­ôß+dØ& ëRþ)“¯0T=:re9r^ös1³Á'‘Y ž° ÑM2“ÇN7­—4u>S= ?M¨åS+Ln“1l&ANÔ@RœÒ,„ðrć‚ÏÉüÓp7#I\›´(4)BÉk8q­.®‹s‘CgrMjèTÈK9ñÑ:“¥ó &´M'3­EÔß10¡;¢…O”TD®!F”q<´e<Ã3KFå!G«È…#J®ý7 È¿zîê£+M*„b# ÷íÈø'ÀÏEÔ}…R”²§lf€(u?2Gˆ 8¬¨ßsˆL°sCÐERVé‡¤ÂæO/INÔSN•‰Xs´·ôUOÏWOWPµ 2í<-…YÕ¦Ür’ĵ'32¢q2À¼”’ÚÐ*äÒ´±ûR£8A&æ?,4 ½M%6ÐGIó^³ÎY^Ð553AËö|ò=Kµ]Kõþv.…Dxµç¤`ÒJëçg'¬Ù&4ëb5‹NÔäÃö+1±ÏOtõ”WZKPS$?î-ZSÑ2´qQ^ÄS8ÒeÝGõ»IÔ„EÑtøîy”\…æá-I¶a’‡ðÈÞ³•ÚÝ뱦~Ó„^B”»A‰*€…ÿB¶VT4&0Ï4`NM•…E–¸ Ó² ö/X4Uc(ûbïg ÅŠÇââùlv?"ŽãäÙ‰~w=ÎgôR:4Zo £iæSmTNƒ­×G´²­„%,ž‚EòÒMŽ ÞÕ¡‘¾o…†ßryZIÖkΨoµ“Nw§¥uª™üæ©ÚÙÑ«êU>©I¦?ñ•¿?#Ùh÷?îv¸5ªæÿû[>‹=îò?/âîý¾òì»10D *°c¿8Œ"Â2 ã$À¹Â3 CL3(Ë¡¬:B߸. —ÄìӤ礭kfꧨ[²×Eñle6‰1&P·/r'+±DG7ò@Ñ8’$…%¹‰4pí4R{PÓ9²ƒ¿*ºñ¼bë6­²ªÚÖúµq«««ðÿ¯—5ØÀjJÕ|.7}í^ZÞ°¼ß8íIÑY,EÒÓ´EPìE[enâ•e9t=»9q­|éÅ»ämˆæØ¼¢Ñ‘eN?YdXUy[å\W…Ó[ÆóbG4ú}_Ùoš(–|¯0ó¹j…hË)\Ë¢[O^‘õÔá®Ýz²¦k:› @÷çsë×…ùP{fË|Q;fϳl]þãC8F±$;›ŽÉñ—­ëóU$dÕ¦ÅNÒp‰%gÑî±ÿ§3?_Õ"×~Æ}^fŸŸ¯šþÆ{üEéævv¥{mïžb®{`:IugÅD•¼Ö€ véÙ;–®í ‚éjŽÙà;Ö¼ñÐ, vêE­™HF…Ðkj`©]Bf¥›ƒŠdQùCU<ÎËã(ï…U¬(¨ÎP†Ïœej§Ü|EVÇ‘¤¤ –RMŠJu™¹‡>þXÔsÌýR&¼çÚÚLÖž„3ÏÜuE¨Á8.ìàÁS*q¼½GH(£Kr0uÛµ÷~ì$"Ap©}/÷“ d:•mêN’)âR;ìŠM%¢Æô÷™e°þM™æüo„ °ˆ‘1…«„‘ Ø)‰1º"†a å|W•ÑM0ªeˆÿ` Ptj–E¨ NÚ3-&4(¶—æ$iÑŪG—y‹\Ì@@ >Gæ¿”k¾Pª5åÍÉÙa"û„­ää?*Q*zRªJ+‡ÒÞ JN{æÊOHt±gº¡o¤HA 9Fo§{  2±’Ähž¥åd“–.U›Ð©;,ŸÔ`‹K:†Ë†z”%€èÉ3L5°ÚDÊŽn’A3#™x¥1ö“ÌÒ½5fÒðQñC¼%îñçŽy°¢nÈiÒd<2nñ:vN¹ÛQÉ<8©4MCÈÄl^é/¡d4@ Yþú(2˜Q*D²WõЍ2éæÌe¬QK’n/z$ÍÕ;ÒQ¶†Ê’ZÎä¤Ò í)tØN6 –Í7y`šœÔ¯ÔÒ@@Ûá=œ²¨Ä(h)í=nì™LÃJ´fá}a´OŠWÔ©éS¢Íeg(ØåáoUÕ…X¬J¼P…8ÈÙE£€i1̱¸m%íÝ JtYS”B}/â㘑ŒŠLHÌ’kÛMvq­n×äî¶ì$ÑvWf=R»´»níÛšÑʘMøKéËÃBëÕBèUfäB”«õÛ5eQ­ÕùJ“äO“X”­4>µt0ÏÁpáè¶³òµôYתã‰ Š•™ìÜ…bÜš€u¶¸KÜ7‡¦ÊQõÖèâ8Eui-€±­u]‹aîýÚŽ¸ËÞû í›Óeæc¶Ã{l£n‘6ZÚÙzwg°SжH‡ _§­<[ë{žµ6Õ;}†ˆ{VÂ&Ô%=*è:‹}ò’„²yg•ܳ”aõœÎ¿ìrh½©¬Xs9­SQ] ߺ²Ìk§J †.÷†Âã\Y)m)ÅsSAµ¬u5æÞ‘²/&öS§•‘Ðåñ¾’0ÉÈã*ú¯Å·ÉÒ«&ÅkU&({‡™³ê™9…‰xy™r%¬ÁVb^I}2?QÕ*—šŽ„•Ø`Õš5†bþ°®Ôajß;Ÿ×åÑ„X«@Þ¹Œt%Ú»ÑëDèc ¶é{]¦r»M¨Qdñê§’ÍÎŒ¿ª õÁu2kÝí'ª|ö{ÙË _íQ›LèxºÒ„jYO™ugÌx*¯k\/••Sö·™½ðVGòÎÖVlÃ×.¶+®9ŸqjO;I´bíÅÈöîÜÛZEAN[µ¬9Ò‹JîJmLÓN@Ý7­ÕýÝ‘o˜Ô Óƒ7mC¯mFX­» ½¬¥Ä§—"aØ_£ÙßÑo¶¤É:ë‡p]î˦hââ+¹}ÿpÊÄ•¨ó] ŒåðÛi$OWòN6(v;XÕÉô†æ,ìJàØ–·ì%ŽÜtÎàh‚0ø ¢ÄïˆÚŒlîÎø¥*Z™Ï˜åbÅ.îÜ,hÇ Ð &Ó+Ôñ ÜñFÛ%0ÓïÀzhZÌ/ÈrXý^ÿìàÍ &ìÏÏOÜÕäNa„þNÁïëFäá4ÿn©üˆ *ìŠÇJÔìÍYêÔJÏrϯvÚ%[®D™ ܯŒðWì_¯”å°Ôæ ¼ŒlåpMÂÒ¯ÒððAªðúÍà^ëàÞ'Ö•l$ôÏ,üÏZ߉nÀv{.’Õ°¨éCDA‡Œºë$–D© ü#yILÉОØ1>ê .–­/ÞÙP ¦„:(î'Úî.DiÆÑp)‘lmîXÐÐÚ?Îù Dú¯¤¤ÜnvÉPTÏ,ŒÈM3õ¨`Þp—±FE TÙ s1P—Q O^A‰‰Jo rè”8±Þ«G.rn¥‰ôßqº÷HÈÍ\Œ‘ZvpöÏÈ#.ë `ŽqrÛ0=ýÏšúÞú±}M¿ ´¦Ðê`ǘӋäH/V‘ï%¬˜üpféÒó/5 ã¶c/6ʤ˜!‹Ì—ÏÄ« C*×q´×ñDâjP ìê(¸0¶9°ÓÈ"˜q^ä°Â¤o‰êþæÌåR°qs ²Ï0@ø¯ " ©1Ž_ÈP¾”È«jò.†àíé$o/% 4’Ì g,¤ââDààÒ`þòEð‘ÇÚõ Ë',ö1àr³ fRv—1ç  Oy)ÎíªA3&¥L])²¢+Å·*Ò¥+5+ o+I©)°JûOFQúq$/öôÑ®Ôr@Š‘¿,oMŠöqOóq'âT//Jÿ“/κm³Œ«rC'QKí‚ÞÊ#7ÓŸ±è6‚Bãå»)22°½’ÐÖÐó?)äã3ò§`"33 ‘ pé"’–úÓì§Ëèñ®}?q¡F0rØeÑÚ¿…FßÇÆ)Q$° @‰h"ÀÞ‰ðQ+&μ Îëì1 (ì1M:ªâÄah™Nà÷³'ZÏ‹>5=Œc=tbï²42 ¥SÝI±"2>òÀäRÄÓóZyÓ•H‡&©Ý°¦zô“ðz¿q4°yp³élI`Ü1Ìè¥rS£.¶dP™9lÖÂóL‡°ó¦|pIëT«ôàáP<å4Ó-N±uFÔ_3Õ‰F³ÍoP,i çTyPî"±_Q°^ûh‹6²÷KÏ4Þõ°Í³xU:õ¾‹Rá\3{0â Á•K/ñ‘×/Ž·0i[45M5íLÉ*fk_jµEƳŠïW‘a‘„ÚÓÉNò¦ïÕa3ÓXîù3µYNO eë>U ññ,o¹¨M4ÝÍu^T•dm}SÔK‹zýRsA“rìuÔ I&OËBp8ô3KT+9Í}V5Ðâ1ð¢~rŠ~F+³¿,ðÂiŽéPS5Fõ40;O4ùXÖ!!.÷bTtú¿+ƨñQŸ"ç›cñ˜2΂ÓvqdIm6OÉ(9mö[^óJ‚L Á—f ÚÉ´ŽÿwTöÔpfíe1äW²sh3!ƒTmUkE2—i‰—+33Ok¾iö«a¶r²¡ka4ÕžlLO#S&ûÓ+U­Z6>z5+oô%gºÀX{t uëH$àÛnöc9•RHU ‰ñ9R2û@ '–trOeRÔÔfÃ1W4ÝyW2¶-N—!z6Ÿ=/Xò­zðÓX´ÿw7k->¯¢möÁHglÓùw¦ãT·s]÷ IJéöWJÅRf´dÒ}gb €Y†Çð „BaP¸d0 ƒÃ☔L…Ä£xtZ ŽG¤R9$–ÿ‹J$Ò¹d¶S •I&2øÌ*g„?ãs¸¼Î?ŠN£” F¢QßôŠ=6F¨ShÀ:©PÕ*ôÚÕZ½Q®ØjµÚ~¹f¨Új´€ ª‹NŽ­´;¥I»Ehû½Òq}¿Pã¸UöA‹áḩv76Æã1øù¼§+Ëæ39·üÏ2ÎÌ#Úž-.A2r<”w]ÖŰ’DS'€ˆlezh>“W“ÞoøZ]6}àÇèPî^"y?æÞ.4:>áÖµvk”»=‚½[²Ø¼ÿ'†Çhôv½X*¿¥wëRq7\¾qô_ößœ×f‰§íÓ‡¥ò#@+6’ÀÎK;·¬óG AĬ5(+_ µ¼ÅÄÜ>šÃ­„%ÎL9¤ðäTÐ$n;•?ëÛªç0*|né=ª«°î;Ò Îñ¼O:Ä++2ÈòÈk›Ö·-nºœ¾©‹êü.¬4Dé@ïëç¾ñ3Ü6‘dÍ3Í$Ý´|`и3ZL”@Ð,Û ¦kU4Àc?CÌ+d–2QE7BÎ>M TÝ&ÊzŽ£¼Å1ܰì.ŠÅ8õÈ’2¾îH®ô‹P«rZÔñ­2s¦¦G«´«)/ Åk./¤»0Wm³`ÅOÔ3:Ñ–-;Æ(Mˆ›NNE•GÙìs?e¢sÌ÷3Ø |È•¾ %·nL65’ÞÜTMÊ–Î)+§‘4a2ËÎ…p÷»u_(ÉêSÍSI5K!߸ U|GØ*åXV’Íf÷¿/”®çËSx?“)a^ÏØt[1h¸‰Ë9‘R,Òdãc×{kCW\ÇP¶õ~?‰5¿Ž8Nq² m!qÜ* Ý]øsõySnšßY«Í÷€_‹%HòHø½Us×¥áTëñ-/RÎŽâ1Ëç¢\/ýÝšÝYÝÉ·n›Š“Â¥•¦­™¹ÐùM6™Ö¼ŒPI-³h:_q;Œ/GqÓæõ¶íô–TÚ¶¹ÿ1£ÆZLyzÞúãµPÉõEªôÝF¨ôê&˜©.jMc¯¾ËÍ1³° /‰wl.Õfœ&@áçW…âÂ;燻ï7| 4¼šeh"Ü›BþgÅñXÌ7‰ÛYåÊù s{ãuLû´¬k]9ÔÕí+Sò½Òuº}ý$ßýMD¿Ë[`ªq[´¦¾Øà)ú/ŠðÁ("@Ù[k7n+Q“¦g´«•9A”AÆP¹ Ûʃ*„½fZðLDŒXš¨h% —+催•ž¾ÌÇ—[ÜyŠQ¼;ؤ2›(NÍ×´â¤ýŸÓ«jñ):¸ë¢‚P)îÄú;7l® ZXlÂ,Ã倠ƒæ] ù­Ç… Ò ƒÏ64¡ÖÝ£kÑ„ )Bg ŠáTw}/u/ÇÀÌŸ42d(ÆA!¸Äh3šq1ýÈÕ2¼Ú󟈱Eÿ¿’¬ÿ"sV“/ùѺȤQÚÒXŠÍMÊH—׌[•-±ß«øó!ä!ÂPÞ7§8Ðòc‹—Y­õ ÔÒim„è²WÈiˆÇPr •§ |x’3C›‰ ŒLáù4˜‰â4KuJœô918ç)é”'i®NÙHíeDð‹qn¾öÙ)ÈÌ­™“í¸Kä¢%Ü ŸÑÊ\¡9 I¦ Ã@“CÉá s”Ÿ“5aÑDù («f“fˆ¸¥4¥ç„kÒMÑ%¥gL¥).–Ié); ï¤m‘Ü»IW*"òÝ£®}Q:|Û¨ Ó  PÎT9{-ÓÀΘSF¼Ú(•PrÔþ¨§.¹Wj+¦™µHÊs5Üõat´ÎoĘžTç;§¥U©TRúÜ·b³¡añq,Ÿiç1ØlÊ?Õ>ªWÖwPd%F„FjÁOõBjcÙ‚3bdÅé£U(;²,¾"Çeié¬؞ͺà ŒH­Ê®tÎBÁZ_ìM­«æ¸%x­)•v¯)rÙ±IfÚ«Í~·PN¤AØÔô¬%¿ŒvL‘؈ñSl]š•JÇÓû&u™Lö^|»6Å+¥"žÅO¯‹EYíTLj2nKº¦Ài…ݤ•Îϰ€ló¯…îÙXmUíÝùn•ÂÃUŸeµÄ$WäAe$Ìlm̘ÔNA]t¡¹·¬:¯;y·7m´kêðÞ;M&§E«Ãw®[?)”Æ(Vææ_ZN£uúÆMæþ\$[Œl69Q˜X«•C£,-ªsó߈ń,±.¤YÂÝzì¦" ÃQÒv§ˆo ò[*S2‹/lWi2º›×ww‹¥•Õ°οf¼m`[ænƆRÞ @ØàGöH²˜ùAæ‹—NèkŽÈ¸ ¦PÅÐö•\¾t HëBÂë•ê`a«$œ=–_õ)˶°¸æ ?M§•µW˜³è عÓ^09Õèà «.:\YÝëà£W¡œfB×TB½d8&Šr5~ÏO‰™ 1{Ê ñKÑYM^™)¦²Õcœ™chi¶ kt†aÄÖÒ1x©uî§xšÁàë‰y5v7Ö9ÃYKóC­(VÍ;Ï&Xê7ô 1Ø`ä•}¶"ØÚ™äí>írŒŸ_;WL^Z×[xfÖ*zîeéU˜búñ[vqŒì=ŹÓFªŽ–G9_³-¹9,ßœ˜†o ÀÆô×q÷^omòãØÕÏ[ÿs_ë“ó-šÙ\bI@='K©]¥j•§KÞ 7(glÞJsÓ1ê-½¯o¦¦ãõ ‰ò&EÊ÷_ å[§v"ë{˵¿0¹¦ßy>•…‚9V2›÷C¼nyÎ(‡ë!¢ð~¤Ó’Ò”¢µézOÃ|ÛŠÊ>©xâÛåû?u¾U実(Ö?²yzµ¹;FixZãUž_¸sü$ªÙóz>Õ ø>è0ÿnôM"Zü •ʵ²ðí<9ÄZ‡µÞß¨ß o˜¼Ÿ"ãÃÌ&ÞÁóoþoì}sv±ÖuèaO¯‡D·Òö½ï½d>ZTÿ×F~ïE¼´ï×m)NÂ…âo¾ðדàDšK‰8·Æ³Ÿ#¬q¾øŽ<ÈÈú|óJŒQð ™Ð!`ØOI†ç¯Pæï¸1kp2.´gÄgÍĆÍnô§.ø›OÖÿ'\»è é-¨ð­¢¤Ê\þðHø«ÜèlTãO’ã°.Ͱ…¥*„N0rùÎF8PÖ°%È`ßâ§®Þí­ôõtq®fõN_ê¤ãDöÐ`iÐL÷pP÷‹Rµ.œøl¦ÊNŒž­ÿŠrÿÏ'Ð ó/Ÿ j è˜ó°äÎоðŒª0,ffc ÀEÎèöà› ðöP¦öOÒ/ЯpÆIð¶÷æâè¼ÂáOÛ øä®¤ m«ë'"å1 Dðâ—1På ùð†Þ.ÙÐøî&Ò²§´ùƒW*5±fÂEOþýP°”Q2Ê‘# ðTÓ.”ñ/á°^øfa”Ì몱ÍIpvÆ®N°p€ú‘ZM1^±1ûñË©¤õ,ú4qM‘´8KrߊºàBö°F¬ª^´NþLµ ©:UÄñ‘4¶‹N­Ži¯*c‘Wï­îÊ¢ÎÃq·PòXªåÁ!q æ­!Îvç¤m ‹«$q‰' Ovþ1’áñ%’ñÌèn.»2nbÑBæÅ!²A"S‹ý'Ò|Îe‹eÏ#1zçím ^Õ~M0ö.érMk_%(£N•p½n¥Ññ&‘¡ ­¸‹F‰òxÌÈc.̆N½ ÍÐúLã(Lcrg•ÎóòÕ*2’ûRû*±ƒ‘ìöÑñ%Ot÷±*Ãé9& ) 2aq¢ê­»! õ RüMRÜÜpÞO¤G(£w.Í_ѺXª €¦Çð „BaP¸d6 â1|)ƒÄâ¼>;B#òü†M'”F$±iL¶]ŽKãÓ®‘M#3I\j}1ŸÐf 5D¤QiTšCþ˜Ô)u*&£WªTªÕšÅV•]­T蕊}>J³Ñ¨;E?œÐ¢—;\~qt‘Îï0»ÄÊHÿ›_¥ø  ‡ÄAð’|\?ä%,L#) 63 “¬®V÷,Ïç#hÞ‡CÔjeYÝ>ªO8ÃÎ0°†ƒi<Û\®»¸&Óbà©Õ;%~Ãc®Vkv/"Áeåpm»ÞN…¾·\/[Égrã´·Ãv³ ¾·€×_ö~Ÿg·/Žô|>9žOë‰÷È39¹7›Ú‘¼oFÛ¼©üöÁ 3ÖôÀðK¶Ä6IƒI  Éë¸Ý:î«¡ ¸n[ˆã¹.{ŒæD# æºMüTÝ»›ÂïÃê„ïÀН«óóGpt|ÁG¨\‚„°Z!È»$"¯Ú A 3E&ò¤iGòÊ#KRœºÛBûÍ4PŒ/3Ã+S© ¬PìG«ÎtC8NpôQM“S¬¶OQ\] F)¤g§+\ªÿ@ò&5Ôd¿GÈRSé.1Tu$Òµ2“ÉÏd”ÊR”«,@° öSu=>ÔÆéx1@p¤i F5¬÷5ºJdÝ9O|M_93´A^Í“õnµÅ¨ä^íÐ+ìÉDÐËåòJð­%.Òõ=µJÕ6ãÏkËwÃn½MM;,Õu5j;©JþÛi•Éx£rÕZ—UóË}¢u„a4EÕs\¸qF 9Î8DK`¸»cY62ß@Lôùh§xÅßzIw9Û6ô!Òù 0×<¿tÔ–¬$×´°6>Èæut»{¥·Íc®·õ™€'öLó‚W“}…NUþ“aèØ êâV[sŠ£:“½BÞùÆkoëy®LšåÃ,Šä»ɳ0ùUé–ZYå¥tÑ5^ØÕ^zîekIFu,VVf}©ÖÚ~†²à¸^`üDé‡h¶,ùdjz}«p/)hk6žìùsxæ¾Ëm³që‘×BÄf`×'å÷³c˜íõaœÇû¯;½?üÒe½ö7\a¿è>…Ük£¥éW†)üeáϼ“³Ù³ÌZ{Ïo±{}¯O³Þo̲öÝ´Åf_W˜mÍFçÑM'qööL7ËîßÏÞ‰xv\Ož•M.AÁ¦×ŒâSªÀy-):47w‹”x,Y˯W2þ׋ŸAQ‰š˜4¹Yãt…ï²(6¸KëJÑ›B×ü»a!n/â:õXî•sýPŽÌÜÀƒÍüy£ýåÄXòö¼H–¶I”Š›kñiÒØRë T30O¾5CÙ"ë40±atF˜pþH¡³‚ïPÜCø À¢ ˆ‘.$@‡‘;L,Ñ5È´¡Xº3ŠõŒÇ¸â÷!;÷’B7J¤àô\!1×BÅÔí,WwqÂ,“Xo̯–RºE$Íž”Ž1D@¨•!ä$Á:FÀBë$ ©wp ¹»Øã%—%±”$Y>¦¢Üš!ò‘mÆ×êû«šè X/)hÊ㹉œ°îYǧ³$cì¸W]´g ¦G‰0"@ÌG£<ÍäÈ…ÂIÌÇ­+ÄÐdój.ÍEÉ5Ÿ.‹T(††±• ›j›ÍݘÖq9TDéHSîÇIW:©¸$sºUAYi<–<þx6{¸¶>§ãM€´Ê =52æSW èÊwδy(¡ Òšr‰òP÷OC’Õ££.ʆ•—…œF²¥>êS ¥]U”’«ÎÄf­#ôNWÕ^SZpóTÁyÓFOúc@¥±»‚ŒiÌÚæè¤ž«¤ª¤BcÕS¢ý°³`„U(ÐÞ*ä¦P«ºJΚĨàò?¤6^ljfØå¬ð5áLZÙM =qŸœӺëâº_ôe¿êýd—¥°Ö/Jb¨I¸Fu¯†¡”‡õ&w5R¿ÙÖ3Fk˜·–j²ÃbýrªÉ ¥“’¡[H­ž…3‘%V·Kè>iÔIÖ¾ž§ú„À+ÜRŠ×r,ع1no±¨“”Ž0ØGïDïÉ C&äF·[uéöDô/@­š† ¸Z»æ·E-ÕÚÀ+b¦M[÷4W–3#Ç[qƒ0v Â×Kä:š¶Âj²aóhãõí¼L È5‰jœ4¿Ë3÷ˬNv®û–gˆÛ$ÝOŒ1Õ‚¡7ÙKcxAŽ£a C#ÙL}ìšðcoÊp`ºÁ‘ÛÖeÁ.Ë dÜ…PàÉx8o)•l­ˆ±r*õbJ×1ZŽ`¾ VJWÍÐN¡—Ý»f‹þÉ*~©Ôy¨Ãg<ëréD¦n–Ugûé7\Þ-…nÒXVŒ]ÖO­2F”\=>ôqŸWŽ™Àü¥P\©"‚Zv ë÷Ï›6Æ«%8ÆkÍu2’3uŠÛD€4ŒpÓcóκңk FwŸªýuös#íuºéQ“¹¯ý2Ãêa—©’º€·ŸdÞˆ‘³/]áVÃ1(¯Q4îÒ_[ÒݺmG·6åKâóWV$}U¸­ñ'Ü»žÈk|í7ó5Î^·?”ïcW·§1Óü¾N”¸ö¯–¾áøkbp-‹!±Àpò ç<è;]8^ÿ¯‹ˆZéÉÆ:ª wqíÞ©Æ£¸f4°Ò1¹&ìA›ïtï*¯Ÿ2ðì¼—UYa½ãµô“RXŒïë»ÏÑ‘jã¢åžs:&[½6œßÕ”iôUYš~ùdMAÅqÏÔýV2ÉžA1•¿ÎXä€Ð1ƒFèÝXKšo´¨sÃ-&j‰xÙ¿I¡9Sú³Äß»oÍþG…<µýöÕϤþÅá'[¥û{ã∶Óê «Ê\·z¯òr‡ñß›þÇ—3¡ búo»ýW(vÌ›×ݾjÄèù†Žû §Ð:f;ï÷¦Ò)­N´×ƒe¦´íœø¨üâL.VKnݤ¾ÔO8±:ë§ÌâËn<ònB" Ð¼ìK#X毖âfdZ ”׎ÒÞÎȺÐâŽÔ¿ŽèÑxîÆ$—.~ÒŒªø/úïé„Êpbé0þŒV¬på¯,ãOµŒê/$AO¬s޶¿É²=€Î`αîÞ²ÏÎ ÇæÝ®Ðý0>ßÛ b»ÖõoÜJ Vôol6r錤фòØðq.ƒ'Òêìðè:ØLÈÚˆªõÒêožóPޝ‹¼óo¯ Ñ ~ÉE 0¦íÈÝÐ5 êÖŽ] iX¤Ðý‰b»æüÇìȬüFÏjçkJï.zWc¤ÿN„ïËXÑçšÒ€1Q¯(0Å*öÅ„§Ñò0$ò±ï³i:úq‘“¤ Á„ ÏDýpPÖÇ|ü†ù ¯åªÏK³ñ§ðÀ•¬V*µPþµW¬ØkôêÅ–Åg±Ú,5Ë]Z·n¸[ê5j\«u‘ÒèÔÉ<’CßhTYä‰ÿ‡Â°ïùæ/ˆc£y)ŽS Ââñ˜[›Äç²yŒÎ“9<2¯à“ý=ÿ !Âϧ:ùŽÊm~ÖO%TIÄëw¹ßQvÒ™†Ë‡Ükc.‚Y´½ôsx íó­x¹Üªû}²ÓÞ³ø,Þ;m’Õàô\}U;·«±Tºm)WëÅî‡ùt03 d·Då?謆@hŒ Å4Íœ‰@èk-¢jA @ÐJ3 B0³/9HXÊ_5mì;$Mû‚Ý9-¬TÙ¸‰üLЏÑLK¤®;øèÄ‘Dlå:ê~¤G«êý»*J»¾ëÖ°-/$šµ,À¹(.t—(½ÒJ਀/c¯/¾¯Âôý¶é;ôêÄsK; A“b !0”å7Aä 9Ó„ :Nó´'>M³ô+A2´62£!ý3Í/»EñœtØÅqë]"‰lcHFe<™8´ëOHÍMsŽ SOÌÍ1¡ÊCÞöËÒEa%ÉRÃÍ&«Ò£ÄóÉ’«ËZX’𸣝¤ÁU/1dÑ27”µ™RϬý¥Oô$ã@NsÍiжµªÓÏSÔßC[©EZË}T¥•Q7VZwIYÍ…ÛzÞHÙ£Iœw1RLåI5(võßá‰cÖkÄ•‡½rœ­]Éò¶*ð׸†5bKje„ùÕ–<ËSdŽ‹OÚ0í³o²3fWÜsö_r³—3ƒföãKœ5£x1ÑwJ1|]·^Owhãg¹qm,šà*Y}¹é^ˆÛF´ôvëuMaR‘WºÖ·)ãu­‰×»eoŒ,•ËÒî˸î-l›ÍÈnEW¯hSMÃlp“ä™ÁÜ-q™­ÉÄç“_#˜ð Æ]è­ÿ|êN}ßÎà:e/Ðiü÷KQjñ.©xk‘¼O¤ÞÑæQ%;±áˆ=]¼w•žÕ‹îr¢»‹íÛ…|ïã’TŠÝï=Ë„¦H-ž£ªò¶Þ[oq]©ëg>æSîæí|9ÝÁñ¢#t1h8'9~iÝŸäèu7w£Oú}çÓßZ=úÓQ[ÿtoÅN*7挳Ña ݼÖ–]ñêVϬ·&ÚÚÞx-¦7h<È ?Yû‘ÇW Mk6ZïaÅ=·À÷܃ä†/y=¹U Q7pnM ¨Ä._b#k­ ù5‡Þ¼×‹%iOÁ458¿¡æÜú'9ˆ9Nª˜¼œ[|cÌq奦ÚÌimï6+Æß„e)l}è0ÈÉ—ÊøŒÕÁBØ{ $2‡ÑÊHDë ¡t}‡Íò²ÇªC¸ /´Öµ˜¦éšÒT.¥Äù1×»ôr‰L:7¬Iv *ǧmãÍlÉM"ÇãkJ°Z7Æ¥‚S[¬rw*½½Ä¨Ã"ÌG‘ð­ÆÂù!äLƒš:BÍI§#2¥‡OŽmȲ@E¼“€ÒVeEXˆ¿¤Ó€€nz<:‡Ÿ;¥&Š(ÂĹ7=džišM5øÁ1¼±wG¾:Al[åÁçbPeŠA¨$¯Û4có0y‹¥$zŸˆmóÈ 6&• š´Ã²êLÌŸD×ZîfÍ“”°`’’v€Nµé&e55‹ '2RQ%¦CÏk'ò=ÏI/O  ¢Ÿ ÍU,˜ôVˆ¥gÊä¼–ô2 ¼ }AÞMaKЂ;Â"þŒª„í8‡nÈèa3æerT†ºRT]©mn‡4¦¸È×äCµ¦TÒqʘ™çL©k©2SùO(牰¨µžt)ëF™5~ÊÉýŽ›Ð¬ÕR±,2¥%íÊê®Õº½X*«eŒ–‰¿BJÍP©­J™u¾¹R:é\«Å¾·ÆzàÒ«…ëÜÞ·³ZÞ&£<Å _¦lž£ºIIa,Í‰Š–.+(ê‰;Ô½Þ®¸—O9ÕfŸ½š•tnr¢«?h[ùö˜eñ#Ñ)jmuùbt,ò;ûïiMݾu‘d@ªÐ£/]Λ‘ú‘\Êçqëšâá,!\.M¯3ERÝ ¥SiÕIŸQ&ÅEjix‘ʤF«±üÌŒUQ§ÍH§6NPÝ[Ýg§ý¾6ާœ0­…ùžxZU¼µV±ßpß~óÿã|y ¢Ã£ë~¡ÂuÞ1áÙ©Ù^'wx}àêÖB ìh¥Œúbͧ ËÀc›¢1ÖOUÏqKú±/žÝ¿¾ãn1¹k€ çvï)†cå.!´»÷‘ßx_,øl%â9ïÏÞ¾/ﯓõð¿'tWù^ç5\×2sÎþ>3çŸh~‡aþž·×¿èØ3ÃÍc}žgolÊÚ¼w—Zoü÷æ å ðÈ­¾ÈÐ,0ÿîèÓM8Üå"ì¯`»ŒrÖLÂÁ¯¨ç/˜úo1Ï ùÐ6æïÃ.…p(& ¸à¸éÄÎxü,Þ±®ü¬NáÔ·ônê®šþ-„ëOHüŽ’}Ⱦ´òîî@ÉBâÛP x.Lí®äÜ/€ÜjÆø.? íˆÊP´hLÈÝÍFÔïÐ9P:ðjèJ£H] ¸ÐRà«Îó`þ°]+ÊóÏÞô †êØÅÐhõN¾ààéPîͯìvK>#øÑ‘ ‚šÛF6öîÞÒ‘(åCÂmê–ÍŒd¼>Îì¾K⨠pp0ºðOšðíá ¯¥pÉ0,Ý©Êqc bA °ÞT©ÐØp„Y0àónŸ®oDàвÅqy¥kÔõmˆ©Èk©VöocÞÇîDÿ̃±¸ÛÍ"Ü4ŒÉƒ¦ÓÍñ¦þñjïð.Ô‘aðÃQà‡Xú1eCBú±h4ัs¯Ìó1ëP_OÐáòpúØñ¯å‘Ÿ!ò'ІR^ïNÍÆ<–‘9P¥§‰ð xÑÂnæøLš· ± ¢Íp+ðϰ31[që'04ûRxçÐÕ.‚"¶ ·P´½©)GTÏËÌê‘‹ ‘•Q×&âÒ)ñ{ȵò1oõ#†øí ÈÓ¥ ÆÖW2E$¨6X Éoúøj/#e4õ°¶ùr}Ð1 Òmny'Q]/±êû2ò›QõÓ1 ¶’ŠÙî+} ò +²šÆpÿ…›!j‰!±Ïoæês?"²ïh ãm ³mÕ‚;hÉ3],ì„å2× H—ðeŠÿ±­%ŒÀ®Ã,‡ ÒwRÿóçPÁr‚¥Ò9å¡1s2Q2R¯2!)ÎГ¶ýr;ó7Û2ó»4%0%pìæs.dÑP±5«däh4å3hµ÷²ÜÛ«%“%P°ýRZÎO0ÍYrnæÓ1/ÉA³ /83¡&3š!“¥(Ó©pá:óGC“(ë1†Ïcq3°l!ò§ÓIDðÄsDûôV•†JrsRMÓå>Sèn.JÒT} },Çâi.j¦>QÌøÑÕMòkÔ!AíQJ48R{B³ K4&#t2ZwÒ­.Å!.ÓÓ4YÓÁ!ÑPtâðvÅÓC)s±*©–ï´jL‹àöP“?³l"ê± ”~÷Q-H)6îéH“sON`Ý3{7ñó@òõR0Å9qR”¨ñO± 1ïJó†0 ¶sQÐ%Mé3<ôçNR 3õ<5X¼*ÑDµQDÒ"üqE²³DINÕFoŠÇ‘GH;M¶÷sò—RÐÒ̃7? ÓTïU+wSµ1&t¤•-ZïRñOA)9BÓTŒÝmC´Ä’´É“#UtcEU;Õ[N•e]T=SÒØÔË+F…WP‹TWÓç$^íÒL÷•‰?P•“v.±ÌÚ´æQG ñb²c[u¥9s[5±J‹[”/d4­dc openimageio-1.3.12~dfsg0.orig/testsuite/texture-width0blur/run.py0000755000175000017500000000026612271062644023321 0ustar mfvmfv#!/usr/bin/python command = testtex_command (parent + "/oiio-images/grid.tx", "-res 256 256 -nowarp --width 0 --blur 0.1 --wrap clamp -d uint8 -o out.tif") outputs = [ "out.tif" ] openimageio-1.3.12~dfsg0.orig/testsuite/python-imageinput/0000755000175000017500000000000012271062644022033 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/python-imageinput/ref/0000755000175000017500000000000012271062644022607 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/python-imageinput/ref/out.txt0000644000175000017500000000706112271062644024163 0ustar mfvmfvCould not open "badname.tif" Error: OpenImageIO could not open "badname.tif" as tif: Could not open file: badname.tif: No such file or directory Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg resolution 2048x1536+0+0 untiled 3 channels: ('R', 'G', 'B') format = uint8 alpha channel = -1 z channel = -1 deep = False oiio:ColorSpace = "sRGB" Make = "HTC" Model = "T-Mobile G1" Orientation = 1 XResolution = 72.0 YResolution = 72.0 ResolutionUnit = 2 Software = "title;va" Exif:YCbCrPositioning = 1 Exif:DateTimeOriginal = "2009:02:21 08:32:04" Exif:DateTimeDigitized = "2009:02:21 08:32:04" Exif:ColorSpace = 1 Exif:PixelXDimension = 2048 Exif:PixelYDimension = 1536 Exif:WhiteBalance = 0 GPS:LatitudeRef = "N" GPS:Latitude = 39.0 GPS:LongitudeRef = "W" GPS:Longitude = 120.0 GPS:AltitudeRef = 0 GPS:Altitude = 0.0 GPS:TimeStamp = 17.0 GPS:MapDatum = "WGS-84" GPS:DateStamp = "1915:08:08" Opened "../../../../../oiio-images/grid.tx" as a tiff resolution 1024x1024+0+0 tile size 64x64x1 4 channels: ('R', 'G', 'B', 'A') format = uint8 alpha channel = 3 z channel = -1 deep = False oiio:BitsPerSample = 8 Orientation = 1 XResolution = 72.0 YResolution = 72.0 ResolutionUnit = 0 Software = "maketx g.tif -o grid.tx" DateTime = "2009:09:12 0:53:24" DocumentName = "g.tif" textureformat = "Plain Texture" wrapmodes = "black,black" fovcot = 1.0 tiff:PhotometricInterpretation = 2 tiff:PlanarConfiguration = 1 planarconfig = "contig" tiff:Compression = 8 compression = "zip" IPTC:OriginatingProgram = "maketx g.tif -o grid.tx" tiff:PageNumber = "0" Subimage 0 MIP level 1 : resolution 512x512+0+0 tile size 64x64x1 Subimage 0 MIP level 2 : resolution 256x256+0+0 tile size 64x64x1 Subimage 0 MIP level 3 : resolution 128x128+0+0 tile size 64x64x1 Subimage 0 MIP level 4 : resolution 64x64+0+0 tile size 64x64x1 Subimage 0 MIP level 5 : resolution 32x32+0+0 tile size 64x64x1 Subimage 0 MIP level 6 : resolution 16x16+0+0 tile size 64x64x1 Subimage 0 MIP level 7 : resolution 8x8+0+0 tile size 64x64x1 Subimage 0 MIP level 8 : resolution 4x4+0+0 tile size 64x64x1 Subimage 0 MIP level 9 : resolution 2x2+0+0 tile size 64x64x1 Subimage 0 MIP level 10 : resolution 1x1+0+0 tile size 64x64x1 Testing read_image: Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg @ (0, 0) = array('B', [40, 35, 57]) @ (2047, 1535) = array('B', [39, 55, 89]) @ (1024, 768) = array('B', [136, 183, 235]) Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg @ (0, 0) = array('f', [0.1568627506494522, 0.13725490868091583, 0.2235294133424759]) @ (2047, 1535) = array('f', [0.15294118225574493, 0.21568627655506134, 0.3490196168422699]) @ (1024, 768) = array('f', [0.5333333611488342, 0.7176470756530762, 0.9215686321258545]) Testing read_scanline: Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg @ (0, 0) = array('B', [40, 35, 57]) @ (0, 1535) = array('B', [84, 93, 136]) Testing read_tile: Opened "../../../../../oiio-images/grid.tx" as a tiff @ (32, 32) = array('B', [0, 0, 0, 255]) @ (160, 160) = array('B', [255, 127, 127, 255]) Testing read_scanlines: Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg @ (0, 0) = array('B', [40, 35, 57]) @ (2047, 1535) = array('B', [39, 55, 89]) @ (1024, 768) = array('B', [136, 183, 235]) Testing read_tiles: Opened "../../../../../oiio-images/grid.tx" as a tiff @ (0, 0) = array('B', [0, 0, 0, 249]) @ (1023, 1023) = array('B', [0, 0, 0, 249]) @ (512, 512) = array('B', [0, 0, 0, 255]) Done. openimageio-1.3.12~dfsg0.orig/testsuite/python-imageinput/ref/out-alt.txt0000644000175000017500000000704712271062644024745 0ustar mfvmfvCould not open "badname.tif" Error: OpenImageIO could not open "badname.tif" as tif: Could not open file: badname.tif: Cannot open Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg resolution 2048x1536+0+0 untiled 3 channels: ('R', 'G', 'B') format = uint8 alpha channel = -1 z channel = -1 deep = False oiio:ColorSpace = "sRGB" Make = "HTC" Model = "T-Mobile G1" Orientation = 1 XResolution = 72.0 YResolution = 72.0 ResolutionUnit = 2 Software = "title;va" Exif:YCbCrPositioning = 1 Exif:DateTimeOriginal = "2009:02:21 08:32:04" Exif:DateTimeDigitized = "2009:02:21 08:32:04" Exif:ColorSpace = 1 Exif:PixelXDimension = 2048 Exif:PixelYDimension = 1536 Exif:WhiteBalance = 0 GPS:LatitudeRef = "N" GPS:Latitude = 39.0 GPS:LongitudeRef = "W" GPS:Longitude = 120.0 GPS:AltitudeRef = 0 GPS:Altitude = 0.0 GPS:TimeStamp = 17.0 GPS:MapDatum = "WGS-84" GPS:DateStamp = "1915:08:08" Opened "../../../../../oiio-images/grid.tx" as a tiff resolution 1024x1024+0+0 tile size 64x64x1 4 channels: ('R', 'G', 'B', 'A') format = uint8 alpha channel = 3 z channel = -1 deep = False oiio:BitsPerSample = 8 Orientation = 1 XResolution = 72.0 YResolution = 72.0 ResolutionUnit = 0 Software = "maketx g.tif -o grid.tx" DateTime = "2009:09:12 0:53:24" DocumentName = "g.tif" textureformat = "Plain Texture" wrapmodes = "black,black" fovcot = 1.0 tiff:PhotometricInterpretation = 2 tiff:PlanarConfiguration = 1 planarconfig = "contig" tiff:Compression = 8 compression = "zip" IPTC:OriginatingProgram = "maketx g.tif -o grid.tx" tiff:PageNumber = "0" Subimage 0 MIP level 1 : resolution 512x512+0+0 tile size 64x64x1 Subimage 0 MIP level 2 : resolution 256x256+0+0 tile size 64x64x1 Subimage 0 MIP level 3 : resolution 128x128+0+0 tile size 64x64x1 Subimage 0 MIP level 4 : resolution 64x64+0+0 tile size 64x64x1 Subimage 0 MIP level 5 : resolution 32x32+0+0 tile size 64x64x1 Subimage 0 MIP level 6 : resolution 16x16+0+0 tile size 64x64x1 Subimage 0 MIP level 7 : resolution 8x8+0+0 tile size 64x64x1 Subimage 0 MIP level 8 : resolution 4x4+0+0 tile size 64x64x1 Subimage 0 MIP level 9 : resolution 2x2+0+0 tile size 64x64x1 Subimage 0 MIP level 10 : resolution 1x1+0+0 tile size 64x64x1 Testing read_image: Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg @ (0, 0) = array('B', [40, 35, 57]) @ (2047, 1535) = array('B', [37, 56, 89]) @ (1024, 768) = array('B', [137, 183, 233]) Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg @ (0, 0) = array('f', [0.15686275064945221, 0.13725490868091583, 0.22352941334247589]) @ (2047, 1535) = array('f', [0.14509804546833038, 0.21960784494876862, 0.3490196168422699]) @ (1024, 768) = array('f', [0.5372549295425415, 0.71764707565307617, 0.91372549533843994]) Testing read_scanline: Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg @ (0, 0) = array('B', [40, 35, 57]) @ (0, 1535) = array('B', [82, 94, 136]) Testing read_tile: Opened "../../../../../oiio-images/grid.tx" as a tiff @ (32, 32) = array('B', [0, 0, 0, 255]) @ (160, 160) = array('B', [255, 127, 127, 255]) Testing read_scanlines: Opened "../../../../../oiio-images/tahoe-gps.jpg" as a jpeg @ (0, 0) = array('B', [40, 35, 57]) @ (2047, 1535) = array('B', [37, 56, 89]) @ (1024, 768) = array('B', [137, 183, 233]) Testing read_tiles: Opened "../../../../../oiio-images/grid.tx" as a tiff @ (0, 0) = array('B', [0, 0, 0, 249]) @ (1023, 1023) = array('B', [0, 0, 0, 249]) @ (512, 512) = array('B', [0, 0, 0, 255]) Done. openimageio-1.3.12~dfsg0.orig/testsuite/python-imageinput/test_imageinput.py0000755000175000017500000001753112271062644025620 0ustar mfvmfv#!/usr/bin/env python import OpenImageIO as oiio # Print the contents of an ImageSpec def print_imagespec (spec, subimage=0, mip=0, msg="") : if msg != "" : print str(msg) if spec.depth <= 1 : print (" resolution %dx%d%+d%+d" % (spec.width, spec.height, spec.x, spec.y)) else : print (" resolution %dx%d%x%d+d%+d%+d" % (spec.width, spec.height, spec.depth, spec.x, spec.y, spec.z)) if (spec.width != spec.full_width or spec.height != spec.full_height or spec.depth != spec.full_depth) : if spec.full_depth <= 1 : print (" full res %dx%d%+d%+d" % (spec.full_width, spec.full_height, spec.full_x, spec.full_y)) else : print (" full res %dx%d%x%d+d%+d%+d" % (spec.full_width, spec.full_height, spec.full_depth, spec.full_x, spec.full_y, spec.full_z)) if spec.tile_width : print (" tile size %dx%dx%d" % (spec.tile_width, spec.tile_height, spec.tile_depth)) else : print " untiled" if mip >= 1 : return print " " + str(spec.nchannels), "channels:", spec.channelnames print " format = ", str(spec.format) if spec.channelformats : print " channelformats = ", spec.channelformats print " alpha channel = ", spec.alpha_channel print " z channel = ", spec.z_channel print " deep = ", spec.deep for i in range(len(spec.extra_attribs)) : if type(spec.extra_attribs[i].value) == str : print " ", spec.extra_attribs[i].name, "= \"" + spec.extra_attribs[i].value + "\"" else : print " ", spec.extra_attribs[i].name, "=", spec.extra_attribs[i].value def poor_mans_iinfo (filename) : input = oiio.ImageInput.open (filename) if not input : print 'Could not open "' + filename + '"' print "\tError: ", oiio.geterror() print return print 'Opened "' + filename + '" as a ' + input.format_name() sub = 0 mip = 0 while True : if sub > 0 or mip > 0 : print "Subimage", sub, "MIP level", mip, ":" print_imagespec (input.spec(), mip=mip) mip = mip + 1 if input.seek_subimage (sub, mip) : continue # proceed to next MIP level else : sub = sub + 1 mip = 0 if input.seek_subimage (sub, mip) : continue # proceed to next subimage break # no more MIP levels or subimages input.close () print # Read the whole image (using either read_image, read_scanlines, or # read_tiles, depending on the 'method' argument) and print a few # pixel values ot prove that we have the right data. def test_readimage (filename, sub=0, mip=0, type=oiio.UNKNOWN, method="image") : input = oiio.ImageInput.open (filename) if not input : print 'Could not open "' + filename + '"' print "\tError: ", oiio.geterror() print return print 'Opened "' + filename + '" as a ' + input.format_name() input.seek_subimage (sub, mip) spec = input.spec () if type == oiio.UNKNOWN : type = spec.format.basetype if method == "image" : data = input.read_image (type) elif method == "scanlines" : data = input.read_scanlines (spec.y, spec.y+spec.height, spec.z, 0, spec.nchannels, type) elif method == "tiles" : data = input.read_tiles (spec.x, spec.x+spec.width, spec.y, spec.y+spec.height, spec.z, spec.z+spec.depth, 0, spec.nchannels, type) else : print "Unknown method:", method return if data == None : print "read returned None" return # print the first, last, and middle pixel values (x,y) = (spec.x, spec.y) i = ((y-spec.y)*spec.width + (x-spec.x)) * spec.nchannels print "@", (x,y), "=", data[i:i+spec.nchannels] (x,y) = (spec.x+spec.width-1, spec.y+spec.height-1) i = ((y-spec.y)*spec.width + (x-spec.x)) * spec.nchannels print "@", (x,y), "=", data[i:i+spec.nchannels] (x,y) = (spec.x+spec.width/2, spec.y+spec.height/2) i = ((y-spec.y)*spec.width + (x-spec.x)) * spec.nchannels print "@", (x,y), "=", data[i:i+spec.nchannels] input.close () print # Read the image, one scanline at a time, print a couple values # at particular locations to make sure we have the correct data. def test_readscanline (filename, sub=0, mip=0, type=oiio.UNKNOWN) : input = oiio.ImageInput.open (filename) if not input : print 'Could not open "' + filename + '"' print "\tError: ", oiio.geterror() print return print 'Opened "' + filename + '" as a ' + input.format_name() input.seek_subimage (sub, mip) spec = input.spec () if spec.tile_width != 0 : print "Error: tiled" return if type == oiio.UNKNOWN : type = spec.format.basetype for y in range(spec.height) : data = input.read_scanline (y+spec.y, spec.z, type) if data == None : print "read returned None" return # print the first pixel of the first and last scanline if y == 0 or y == (spec.height-1) : i = 0 * spec.nchannels print "@", (spec.x,y+spec.y), "=", data[i:i+spec.nchannels] input.close () print # Read the whole image, one tile at a time, print a couple values # at particular locations to make sure we have the correct data. def test_readtile (filename, sub=0, mip=0, type=oiio.UNKNOWN) : input = oiio.ImageInput.open (filename) if not input : print 'Could not open "' + filename + '"' print "\tError: ", oiio.geterror() print return print 'Opened "' + filename + '" as a ' + input.format_name() input.seek_subimage (sub, mip) spec = input.spec () if spec.tile_width == 0 : print "Error: not tiled" return if type == oiio.UNKNOWN : type = spec.format.basetype # Randomly read a couple of tiles, print a pixel from within it (tx,ty) = (spec.x, spec.y) data = input.read_tile (tx+spec.x, ty+spec.y, spec.z, type) if data == None : print "read returned None" return (x,y) = (tx+spec.tile_width/2, ty+spec.tile_height/2) i = ((y-ty)*spec.tile_width + (x-tx)) * spec.nchannels print "@", (x,y), "=", data[i:i+spec.nchannels] (tx,ty) = (spec.x+2*spec.tile_width, spec.y+2*spec.tile_height) data = input.read_tile (tx+spec.x, ty+spec.y, spec.z, type) (x,y) = (tx+spec.tile_width/2, ty+spec.tile_height/2) i = ((y-ty)*spec.tile_width + (x-tx)) * spec.nchannels print "@", (x,y), "=", data[i:i+spec.nchannels] input.close () print ###################################################################### # main test starts here try: # test basic opening and being able to read the spec poor_mans_iinfo ("badname.tif") poor_mans_iinfo ("../../../../../oiio-images/tahoe-gps.jpg") poor_mans_iinfo ("../../../../../oiio-images/grid.tx") # test readimage print "Testing read_image:" test_readimage ("../../../../../oiio-images/tahoe-gps.jpg") # again, force a float buffer test_readimage ("../../../../../oiio-images/tahoe-gps.jpg", type=oiio.FLOAT) # test readscanline print "Testing read_scanline:" test_readscanline ("../../../../../oiio-images/tahoe-gps.jpg") # test readtile print "Testing read_tile:" test_readtile ("../../../../../oiio-images/grid.tx") # test readscanlines print "Testing read_scanlines:" test_readimage ("../../../../../oiio-images/tahoe-gps.jpg", method="scanlines") # test readtiles print "Testing read_tiles:" test_readimage ("../../../../../oiio-images/grid.tx", method="tiles") print "Done." except Exception as detail: print "Unknown exception:", detail openimageio-1.3.12~dfsg0.orig/testsuite/python-imageinput/run.py0000755000175000017500000000011212271062644023206 0ustar mfvmfv#!/usr/bin/env python command += "python test_imageinput.py > out.txt" openimageio-1.3.12~dfsg0.orig/testsuite/png/0000755000175000017500000000000012271062644017136 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/png/ref/0000755000175000017500000000000012271062644017712 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/png/ref/out.txt0000644000175000017500000000174212271062644021266 0ustar mfvmfvReading ../../../../../oiio-images/oiio-logo-no-alpha.png ../../../../../oiio-images/oiio-logo-no-alpha.png : 135 x 135, 4 channel, uint8 png SHA-1: 75ED9B183E083ECF0A4881EEE0B553457B698CF4 channel list: R, G, B, A oiio:ColorSpace: "sRGB" DateTime: "2009:03:26 17:19:47" Comment: "Created with GIMP" ResolutionUnit: "inch" XResolution: 72.009 YResolution: 72.009 Comparing "../../../../../oiio-images/oiio-logo-no-alpha.png" and "oiio-logo-no-alpha.png" PASS Reading ../../../../../oiio-images/oiio-logo-with-alpha.png ../../../../../oiio-images/oiio-logo-with-alpha.png : 135 x 135, 4 channel, uint8 png SHA-1: 8AED04DCCE8F83B068C537DC0982A42EFBE431B6 channel list: R, G, B, A oiio:ColorSpace: "sRGB" DateTime: "2009:03:26 18:44:26" Comment: "Created with GIMP" ResolutionUnit: "inch" XResolution: 72.009 YResolution: 72.009 Comparing "../../../../../oiio-images/oiio-logo-with-alpha.png" and "oiio-logo-with-alpha.png" PASS openimageio-1.3.12~dfsg0.orig/testsuite/png/run.py0000644000175000017500000000026512271062644020317 0ustar mfvmfv#!/usr/bin/python imagedir = parent + "/oiio-images" files = [ "oiio-logo-no-alpha.png", "oiio-logo-with-alpha.png" ] for f in files: command += rw_command (imagedir, f) openimageio-1.3.12~dfsg0.orig/testsuite/texture-skinny/0000755000175000017500000000000012271062644021363 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-skinny/vertgrid.tx0000644000175000017500000003114412271062644023571 0ustar mfvmfvII*€. 4<1#D2h=B@C@D|E¼Sü¼$‚&‚ 4‚ €>»ƒ @ø maketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11hÁsÌ%~×0‰â;”íF Ÿ YYYYYYYYYYYYYYYY 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³MxœíÎÁ ±î¿tÅ|B2Af€kwëÂÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoù·ü[þ-ÿ–Ë¿åßòoýø?ow³M@  $ , 1#4 2X =B@C@Dl E| SŒ ¼$’ ‚¶ ‚ Ä ‚ €>»ƒ Ð èmaketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11ø tðl|||| 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíÒ1 Ã@AûÿvŠÔ j.&0ó±…®‹÷=Ïshù¾ï£û_ú‹þ…þ¢¡¿è_è/úú‹þ…þ¢¡¿è_è/úú‹þ…þò›~ÞõïÿÑ_ô/ôý ýEÿBÑ¿Ð_ô/ôý ýEÿBÑ¿Ð_ô/ô—Óý1—g\xœíÒ1 Ã@AûÿvŠÔ j.&0ó±…®‹÷=Ïshù¾ï£û_ú‹þ…þ¢¡¿è_è/úú‹þ…þ¢¡¿è_è/úú‹þ…þò›~ÞõïÿÑ_ô/ôý ýEÿBÑ¿Ð_ô/ôý ýEÿBÑ¿Ð_ô/ô—Óý1—g\xœíÒ1 Ã@AûÿvŠÔ j.&0ó±…®‹÷=Ïshù¾ï£û_ú‹þ…þ¢¡¿è_è/úú‹þ…þ¢¡¿è_è/úú‹þ…þò›~ÞõïÿÑ_ô/ôý ýEÿBÑ¿Ð_ô/ôý ýEÿBÑ¿Ð_ô/ô—Óý1—g\xœíÒ1 Ã@AûÿvŠÔ j.&0ó±…®‹÷=Ïshù¾ï£û_ú‹þ…þ¢¡¿è_è/úú‹þ…þ¢¡¿è_è/úú‹þ…þò›~ÞõïÿÑ_ô/ôý ýEÿBÑ¿Ð_ô/ôý ýEÿBÑ¿Ð_ô/ô—Óý1—g\ € 1#$2H=B@C@D\EdSl¼$r‚–‚ ¤‚ €>»ƒ °Jmaketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11Ø‘¹¹ 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíб Ã@Ã@{ÿ¡ „\ùx²VqÐóß÷}ÿß÷Õ½‹¬ü{ï"+ÿÞ»ÈÊ¿÷.²òk¬ü{ï"+ÿÞ»ÈÊ¿÷.º«ÓÿÏ¿÷.²òk¬ü{ï"+ÿÞ»ÈÊ¿÷.²òk¬ü{:ýÿü{ï"+ÿÞ»ÈÊ¿÷.²òk¬ü{ï"+ÿÞ»ÈÊ¿÷.º«ÓÿÏ¿÷.²òk¬ü{ï"+ÿÞ»ÈÊ¿÷.²òk¬ü{ï"舾hxœíб Ã@Ã@{ÿ¡ „\ùx²VqÐóß÷}ÿß÷Õ½‹¬ü{ï"+ÿÞ»ÈÊ¿÷.²òk¬ü{ï"+ÿÞ»ÈÊ¿÷.º«ÓÿÏ¿÷.²òk¬ü{ï"+ÿÞ»ÈÊ¿÷.²òk¬ü{:ýÿü{ï"+ÿÞ»ÈÊ¿÷.²òk¬ü{ï"+ÿÞ»ÈÊ¿÷.º«ÓÿÏ¿÷.²òk¬ü{ï"+ÿÞ»ÈÊ¿÷.²òk¬ü{ï"舾h@p v~1#†2ª=B@C@D*E‚S¾¼$Ä‚è‚ ö‚ €>»ƒ ¬maketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíÔ¡ À@ Á¸2göwö¥E uH@´dZt™¹Öº†sÎë¾÷ž#¨ªº{îý˜{Düô‰ý,ûYö³ÒÿGÙϲŸe?ËÿgÙϲŸe?ËÿgÙϲŸe?ËÿgÙϲŸe?ËÿgÙϲŸe?ËÿgÙϲŸe?ËÿgÙϲŸe?ëS&€ Ò Øà1#è2 =B@C@DŒEiS ¼$&‚J‚ X‚ €>»ƒ dömaketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíÒ± €0DQ³QFH&ÌHÉIP°„Cx¯ºò7ƨµ—½÷³{ïÇÌ9[k÷^k=»”’JzEÖðÿ(ýYþŸ¥?Ëÿ³ôgù–þ,ÿÏÒŸåÿYú³ü?K?À·NhíÀ "*1#22V=B@C@DÖ!ETSj¼$p‚”!‚ ¢!‚ €>»ƒ ®!*"maketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíб À CÁ°ì?Æ IVH+Ò]áÚzUÕ{?ç<;ç¼þf­5ÆØ{?ÛZKßy­ôÒ?Kÿ,ý³ôÏÒ?K€onVM`P# V#^#1#f#2Š#=B@C@D &E4Sž#¼$¤#‚È%‚ Ö%‚ €>»ƒ â%>&maketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíÎ  G±ªG1†sƒ´M23ù©þ§üoùßúþà—EÏd' j'r'1#z'2ž'=B@C@D*E/S²'¼$¸'‚Ü)‚ ê)‚ €>»ƒ ö)N*maketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíÎ 0  K©U•2OP@Û$oVý¿Zÿ¬8Àn t+ z+‚+1#Š+2®+=B@C@D..E.SÂ+¼$È+‚ì-‚ ú-‚ €>»ƒ .\.maketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíÎ1 0¤Ì¿ªIÁ/I« m“Ì[}þ€‹øs‚/ ˆ//1#˜/2¼/=B@C@D<2E(SÐ/¼$Ö/‚ú1‚ 2‚ €>»ƒ 2maketx vertgrid.tif -o vertgrid.tx2011:04:12 17:39:11 32 1 2 1 5 Plain Textureblack,blackA"maketx vertgrid.tif -o vertgrid.txxœíÁ1  E±*£XcÐ6É 4Popenimageio-1.3.12~dfsg0.orig/testsuite/texture-skinny/ref/0000755000175000017500000000000012271062644022137 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/texture-skinny/ref/out.exr0000644000175000017500000053115312271062644023476 0ustar mfvmfvv/1capDatestring2012:08:17 11:27:12channelschlistIABGRcompressioncompressiondataWindowbox2iÿÿdisplayWindowbox2iÿÿlineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?qšë(s=^Til4…^Ÿ¶»4×ò£ –%¨>ÂVomf‚ž˜Ú¬mÁÖÙéWþ¥^&297Kî\mmkr¡!xœí]iXÇºŽ‰[ô&Æ%æ¢ÆÝ·TÔ¨‰qˆ¨Á}Ù·f†™îªž}ePYT ‚qWÔˆŠ ‹hTbÜ0FŘq͉æv÷,Ì 0 ܦë}‡ê®ïëêy^߯«¾ª®y " @ˆ…Ïéû¬òÄ¡µÕŸ/Ïyôð½vó]&ô{ur½Xoð¹è÷Kï¸0çW¢y LT|úÙ|¶óŸo;/žu÷ü]¶xKågó„‹{_ƒž¹ÕÁ•ß«·˜Ôþ§gèÔ¿¿0s8u&çšñ(Îí®“®ÔÊG5§GEÅ;Ó¾÷Í„pè0Þpˆ·üÇ]fñó¡wj±÷‚+÷ϼ’¼Ù]4YªP'òÂ2©ö°]¶ê¤¾Ø}®/žŽ/¹6JËn—Bèâ\ a÷ÌaΧà¢l‚£Ø~ˆƒË’ê²ÒLu)»ŠˆÄ?⟹ü#0§·8øôè¹pö—^þ®±nù’‡Šiš)Qmz‹lo,-÷•R696¿*ÎÄoS@ò«.mM"â%¾Þ»RÇw6;Ëu¿U¥üíÓBÈ»8øóÊDs§˜W}Ù‘µ‡ D?~«ohÕ5OòÚ}¦S–w÷[—v¿€ðNìk-üF²Î+ˆ¨j—´ßÏ[Í>piÂý^'½¹)Ó¥2•Xé¿cÅE¶jŽã'ß„n9_¼Zí+ þÿˆæòÀlTÌwÛãa^¼¸qS÷"\Þ®gÔWç´áiyÓK³Y©3Åù†IÔ •4$DÅöœ>hð<Á‘’ýv–Dü#þÿÌåÙ×72… ¼êƒ¥¯c]ÿLmÌ’Û7iÖ€Æìðýµ_æÎâÕü¾žšËkttl+›]þ;wM½µNû|G Ý}AžfQQx_3ù6OãX eÏs_ëÚÃ=fíòÿôxÖ³aäq—øŸ üðŽN=*àÍ9}7pݸr¯KÙ™ßw3‹qŒ»,V ”K"}¼FtòP•ŸN·«$ âñß$ þ튄&"|‰sT‘ä—¥þò†m°i‡– •5îT—{E‘•³ºhN¯ÝAÌŒzÇXYqŸšæÏl0ÅFOpŒÉ¨¸iqzÁhÏΦ ÌŠ,Å?†ºý¥¯t%˜†e_]«yœ¸@6sp'rD1ò>œ±ôdmˆÎ b©ÛñúÏ=ØíÝäõîçäC‰œí+÷Ï RF*Á¼¥£N ÞVZÇì$ âñøg.ÿL‡[ÉÐ “¿ísïïz§ñ€û­àÑɎ¨²ÈK>L¬Çbåí«*+/<¼Y§&À#õäù#ûžàìú(º÷âý–5aí%“þºWÔ‰óø—s5˜[tüê RzC89Ãìì°ÖàpÎ2Ù­Vš.­yâ;)3€5µâ›WO.Ö!V'Ï 1œÙ£+ö^\ú¬½®Ôç4î>~~ÿpÕÇ>:aÿ5gà¿W=€Zç-páÖ‘çë{:(ŠÐ²±›ÖFÉ’ÔMÌOPªXQ‹§öûÂ=öÜÉMôiÆFÄ?âñÏ\þìõõÏm¿0ߣºÆ¯û1“I:îðŒÙý_»Ü•|Ö»þ®²êßHϺ.]ž¬4œœ=Q•LXs Íýóî³dibðóõ‰gt×Wä.ŸkjYÝãF/ãÁEGŽ>Øú µ [ÛyjbèÍDøSBg‡œˆƒN‹jâðԵsåÜ}Ç–l[ôÉã)¾"­`™|›Ø{3/D! öq›Øfж³Ç´T°åGÄ?â¿9@üÛÿÌFÍxÛö⨃ЯîˆLßõÍDº޹{ ™Ûo¿Ûo;¯gþoº ›„E{§¹T |ºÓ¶>îI‘aÇ{MíeÕó‡êuÉÇô&7ŽžÉ~7%™V}I·¾ûŠM-§v¸PaÜÄg¥ß] ¿?4Dw÷u˜rãJΚ™ãæIŸ>^žÁOKá¼åBý·ª¢ÒV{ÑÕéÚÆdÉšR‰<ž‹ä±ááçÏFºñ~8õ½šúâ-= þÿÍóDüÛÿÌF«á›W7sKÏÙÛÎ ª[Qô³×Q£wÞ~=näˆG=ÏI÷ÔÁãIJ4Ç÷2 ŽÀÁos'³Ž¬k_bÕ>0½Ëþn”ã.Žö.I“ÃêŸÚ–ÿjf뜼Ãx ~yz·®Y6.Ää¹@—MÏ—pãE§¶Ý ÂÞÅëáô|Àw9½SÏ-t_ç¿ÛµhÂÏ©)^ª„¯¥2…\KDn ”DpÞ’i½¾ð\[üÃwª–ŸDü#þÿÌåÙhuæ°s¹ãŽÆ ëxÿÃø¼á]NEK¹?kä²5oÇ7íúå†ôz5ìú…ÊKľëÆûn}¹wÝu³)ÅÐIåšåÞy‘}ûλf¶7ŸíÔFµåã2õû€-»’ו.¬fóÉûä5äå“Õywþ€mydp¸…QŠ“cD©[ÇmðݶàÈ×WS’WjY>j ”(BÓü4\/bÍ?ÐÙ?÷D¡–N&¶ä€øGü#þ™Ë?³±:ã}×UiyéMÞÒ“Ïiß —½L­|”;~wß$¦€_t-Ô:w†ƒ×|™uËUI×bgÔÜ´<=µ‹ƒöyVÇœfgAÆ“~Ók¾Ýj“ŒºÛFw‰½3©øðÂÍ/Z23ÉK¨…]Ïl†Þ{à¤ÀK1æ<º-Í^\0ú^òø9…2‘ÒU¤ôÙæ«ÐD‰ {['7NÑñ:ûÙr#âñøg.ÿ ‡O×ôñIŸÔoP¶ô¤€Í»â3Ä»ÊcÎOJ–¬VŒíÖ õCØï-ÿ§‘ùK¥'§Ü·n˜sùîÙ²ÿÔ÷Æð ŸâV¾û§™mâ~±üuíQ§Yùúbë·]vêÎmÙNýªHüê3þ•¥%/û ­‘t„°ÛÆ’ ÙÅpþV!+®ˆ3mûü‚.×mpOv>äb…›Hî¿5RÀRÉXþ«¦ ¿"ñÄÑÔžDü#þÿÌåéø¦üaŸ"å¼ÍÀçp**êðâ¾SÂõõU›Ûzž(J:ÞÔ†yEùÓ2µÝªFá^ «aKåNoM›'õÖ-_Ôz–¬X’Ѧ6ßÚá€ÏoµÿŒ Z¡/–õ×âtAÑ%ø%ù'h÷¿ÎäÝ 8ú¥/-ÙwÖÜ€á1 ì•Û\·K3ö”tr9òpDâ†éJ¶H©’K  Žc+a$ôY8vðŒ€]Eù-= ˆøGü#þÊÿá7}ÿô?@BB ‚R”AUD•D›¹Xàü( –Ç©Ëë.nÃméÍÉ[‹ Çã¤BS7ò^¡Èü:ä)aíH`†€Ã˜@(‡€ºôÉœ B\H~i@€úïÝΛ¿o A¡þ/âñøg.ÿ ý¿›”<)Rù”ðIU˜)ßhˆñ#ä ±m­¯!Axð: !¡°Í…8}CôÎ Vi$ÆöÉZ($¬ÊŸ2ÐqJäß8µL§HZ‘µ?`ýÚ7Ü: {Œ…ˆÄ?⟹ü¿é@x£Àé¿NfT¯Ö£|HKnD¬LÔô@,¨ðÂŽSÙêOzà„ÐdÀAF (¿õJ±î U+²ŒQfò'ÇÆ# ЍáÛs“ŠòÇ ú7‚4ühØ_8ŒøGü#þË?zþ3Q€ 5f™ìk8\TÔ”$  ¥JjŸÔ=Ñ­-þTâ-º÷€‘¨RÉ; ZÖZÊ`„Á‘Dç ´ôu @(ÔÇ€†3€Ð~ÀÄ?âñÏXþÑóŸÙÔŸìkç³ •ÄRy šÓ½xZȺ¡éI¨󧜠Ð2¹§k?&D¸ZF` NçŸ 3BÓUÌ0š\ß"Ž XB­„ ôOéžN˜5 ˜‡øGüCÄ?SùGÏf4u=€XL„–i@:é‡JÇæI<K¥´æß°úéZŒã»VMˆë„Jþ¦'Éî¿1`†‰@²€qCbåôB"cÐbÕ`_ ñøo ÿvÅ?zþ#4¤¨¹Z¹Õ$žn‡tÒÏÂôç°Ö4äO%þpBde1ÎòLmݹ?sù›wÿ¡>`P  :`Õ>^ÿ* &%›¡Ä?õøGüÛÐó¡É€+m@£º ?:é'¬¥/éÅÓÊêIÒÙBa‰=sRØ|{Ââ] ùSQÄXi|H·ðÙ|-yÿµ¯Qƒ€FWÙah–þÿÔâñßâžÿMÙIçGˆUuspú ?RNõtüMÍð˜p±É»<ú³'õÙPâOoƒ‘:œë/‹—šXâ˜ù„ ÀL^ ÆqCÓ € †-V‹ Ó@mÐúW§a/ yúGü#þÿÌåÁ^š8ýgô£¦ñ4 ³wyt~dÿ]Ôø+¾¤?74ÖtŒ)¤´EÖ7@@ª„E-ÛH-äÑÁRþ¦ïþ˜Lÿõ8yÿR‰P·È8  «Ë€¡yhù ñøoÿôg‹ç=ÿ™ A“Þå15'Óûj+œ…³á𤔣Ãצ©®?8¬{ Cà³Ü³Õ:Õ㡹üͺÿµ+ôï‘q€Ô:Æ Mé§ë,¦Œö4ÈCü#þ›Ä?õÑÒùGÏf#HóÿÙÒSÀÆb%ô‹µ8Ùñ‡"ëI¿:þ †Í§·ô$Õ/€bë‰?:bÓ”#éÀIQRÓw–ò‡.ªP£þ…ÔýGcj‰4¸ ¸¡q€ýD€Ä?âñÏXþÑóŸÙàDÈ–Óp6@<&\¦Q}w‘ I¿ºÀya2„ŒD#Ó~ТóoðöˆK”:ò'ϘŠÚ•ÀFýë67ZJ½ËdÈÒƒã^ €–ö!þÿˆÆòžÿÌÀ¸á±òfléI;S{r¯’ÆbZ1%«f\ƒT`DÀz¡´ñAcê[o„…/ÊÒˆÅòÇq“3ƒbc…Aÿôï€PÛó"ÔRêÂô2€8•Ä´6h'Ó€ˆÄ?⟱ü£ç?ÃAmémÓ–œ~´Ê0jÙ '$ÉúÛÀÖZÇyçµYQg3/KCL ª?JžwÀV­ydÀ1ÓÀjÓuôH‰ 8¬)õVPÝÀm_Ôb@!âñøg.ÿoúÞ4ô¿Ìië–žP§}²?NuÈ©4ÎgMSü—¡â‡Xøá@+µæO6†7Ô.€/~º‚0íðÓAíÛ?d¾¨ß”ú!0jè§iñC¡! ØØýëÐ’#@!âñøg,ÿÿ(‘BÿIxœí]w\ÇOѨ˜§&hÌ3Q,QÃ3*–Ä»±aÀR…9®ïîÜî^/4i‚,€¨ "ÅXb‰ÆÄˆQ_Œ‰Æ$¶ðŒÑ÷4ow¯Ãœù'’ïG™¹ÙùÍîñõ÷sæ÷ûÍì ‚í@ï6ŽèüÛÐuíÖ»Ò›Ûw÷Ûݳê<~©™wHöâ/GDÓjÏ4æ<Ë]C‚ ]ò¹!ÔdÏïväD _¼_ã¤kÁ™ÕW^é©txMüÎù¢'áï§£§úšÛNþx³éRUý ßTÍ™{úc¦ò8íÕ8º¬Ù0H¿¾°å«ˆS×{Àã: ¼ø—²#”¥ñ+´SºEv||Üou^Èvy‚2Õ×( ×ÇÊu\>‰öµP|¤®D/§‡=Ë·žù‡üCþÙË?ÛÁÇ„šw;.¥¨[î'štpIÿ^˧Î\4é,úk†¥=kÙÑð;n¡roˆy<]¹n¸ÈÜ!$ý=Ùïþ’ï}1Pæ o JŒýâ 7Ç¥ÇåuºÀŒüÓ :·÷.eÚFê.M(µv‰¼2ß\¿òS ºú&]>î»L@7÷™·&ŒÒ9©˜è4ú ¦vöåÛ“*¸F Ácó_±é³:ø÷7ÍõÞ;?|ÄTÐ.oÒåž'&SÅu©?î~bpM‡Žãtµ Û&á9*„(+—Çl6ä.«^!ÌœM*(h㶆k4Ü|~r"'ì½Q³b+êª Œål»òù‡ü³—¶Ã+È7½{B\â'®a1µc/ï-ºX;qɯGB¾v䨛Ö±WÕG»#w´v£ÀUãíŠé†ý[ìšC¤÷vz”ðÆ¬¶kõç¿Úyp?'C*J^:ÛüŒ÷O-?b;8ñpÎ-[s–û¨«¹~ùVìׯšÇÁtÈv¦ ߯qÙU·æ G\-ÄÕîU•`iÑð‹¢‚N#5‰šœÐ“þhÁ´Ã8®ñ%ԱŠ­&‘/Oˆò÷|Z·¿X§ Çk»òù‡ü³—–¹r ¤þÇ-ꜽ‚$Ï’Y½ÎÞÏÒÎ7èÚç;›ácuO®û}²¦VßÂM°^ÿX:ùâá¡Ígô·ÕnÝ#$ ­½ñýu#çg4ëjÄ7§®‰€õqx…ñèËS~üÜ3˦Ú3°³%t˜ë©«0Ö&Æ_dÊ~(õ“ÿ™[äÓK¯wÊF§¿F­øpÕŠÇ÷³ª#"Sg©EÊìðW;)Õ«…¤F©X Ó„•&R)_EÄL÷œ´¶¶vŽYµY ù‡üCþÙË?Û‘éž;â¦WôlKOäýEhÿa1nßܾ×ñöîñ5-Ç÷„èχodìA½p'Rj÷f^ÔÀè{ uª‚$?Ù}ÏôyNÌØ2ÁØqÎnwç÷ù{ Û–O¿Öí²Ävôî[ßµ|XPhJ¾Ðޱ3ýŽFTQÅÿ‚þÀÊîEnç»%çËKÁ„ùt7k³RTS"‰¬ˆ×ž¦/üDªQ/ãoñ4±2G£ÔqʼnAÇ̈ÚW[e`ÖEm×@þ!ÿöòÁv}y}ù¹×£¾½AÕ‘À_…CSÌ_®ðø"á‡4ä#¿/øÐ}ã“o¿ttqÑ"²Áãn8•ç÷½Z÷ B|A»Ñ”=ƒµ…+Ö8ëû’{ýæ_š&—M}µýú`ÂÆ´Ÿþßý–]+w™Ö·#ž0+žÕ9yTq6àà¬E¹ú¶»›ôýÝR¯÷ΰC„]É%;Ž-סYQwßÎÏ!R}ärµ:K¤‘p´j™/FÏ8q!Ø_³M߯€È?䟽üC°FÕwêÐsƱ9”f¼[0ÛóC^Ï­ÎfôÍ0惉Û׎ÈRФíñȯ‡lÜ"3ß¡œÁók²ÖµOúQí½´‡g'§»XYÖ×Ьy;>vmñÙ«, É3–§Ÿ”›¼‹œÏªz2•¨s3éâØžöÔÏËõ!£§nÉzyó}°­÷'ÀgˆÉãe 6u{;[¼:öó·*9†ø(5Nj• mô¶Hµð•‚• ÃGN YWS³FË,HÚ®€üCþ!ÿìå‚å@Žg¿È“”ý«Ýú׃§Ln¬{²•MAM€þ`˜YrÿDi;5çí+ÜUõ‹Ç¨Z _ô•vÛ®ºw]Wž(tÚkàè»§ýóš5{<Áï¯û~U-¸`lˆÌyÎ"ÌðÞnúðí4ãJ`󌺩o—驨÷ï¬~0x¸âü¾:໓ûîáëŸöX™X¿!%“S9w/)wæ^¡ñ%¢ìè"N‚Z¤R$Å{ŽQSS™jLŽj³òù‡ü³—6C4«!¦ûëÆyÿ¶rõ%äa®+ûyš@½ê?ÿ‘ÖÎ,ëçKÌþ¾ÇO.†V\9VòÇWO¼ÔøÕ3Œ0dlõ‰˜ÔMÔ”ÛüÎÓ[Èïc·4í²lûg 3_s »¸òðhÔúñffAÚo»zY[ܼùosý£3ËŒ•ì¸Ô/€.õ™G'-×5Üà­¡#Ñ7?Ú\1,¡ãä8ðKÝÀÑâéü¢Ç£Rq5¯Ì¯2!%Ïû¢«ýdŠÐÝ‘jµ0›ËW¦HB†›¸yoe¾–É4~Þ äòù§KvòÁjÜ{¿®4P²±zÅ„³œŸsìu.1è—àYù'^¹»xéºúåœÅ÷>KØä²”hr66â´)î(¸úôµ‹óæ ´_‚D)+úÀ‘´|o\ íF%´K‡”Ÿ+î sƒ×­iEæúI9§˜ ×£¿/]ÿrè9ªðo˜O)nGéÿ¨_ZþùøwïikÓ¢òÇÕ'­ïãnPtýÒ Sñ =ŸÐ‘) P½%†ÐhSÔ*.ÇoÈ„9qUíóï„üCþ!ÿìå‚Ýè8¸ááβ¯~ÊëµÓ‹ëtù£9‚9ß^LÆagÎãoþôWí0© {TŸ©»ZßõàÿЂèÂã¬O|ñÎK±/ žcÓ'þšúô¡Ž¤Ý2Ïõ¶oòÛuitåÃæ˜ìÚK¿pÌ—æ!/˜ŒÈì”O™²\¼.*¯Ü9\ö:ßõ÷¯~ë×⣻NHÃ9 ²àgONÞ”zC²65æ÷áÛ0ýbWdаÐ&*t1 4¨++¶êßû9¶È?䟽ü×þÕñ—ˆ8I¥!e.¹é0€a"E ‚Q2£|¢Z뢼e E‚À)) rt:¹Syêv¸³ÑQ) ehò‚µ¹ ™µ´] a¾„!¦*†âL8ýü•šQB(uê/†áÙ¾DÜñƒ ãÓ[ëý<â€üCþ!ÿlæ‚í ZÈMS  ft•"2’Ñ[™µ]*\•®nUÞv TŠR£%(yþŠ­cyª'FNFÆ$€ÖuLº*hK†Y·¥2Ûî"³d£¨EÿeŒ‰@mW(S$æ¦ÊåŒâú/eè?xk&ÀÖ´E`ÔÈ?äòÏ^þ!Ø “ò…E ŒÑj‚2ºˆÓsgûŽ&á Ò”¸K("¥lˆÍ”ž’ç%g©ðfâÔäÜùäŸRuTnœêc¢èè:FAì¦ÿ˜Ôzx3ý7­P@Y ^&õý1jA@/ P£ pÕ´U `ÖÈ?äòÏ^þ!Ø •ðd:ys FݧæÈR” ÍN?Gò\\ïXÞ¾#=AâMtCÅ Dš¢Yk “õ§‡å¬,QQÓw n'€ ¤Õ3hÖ€Â8>c¨e@%É2‰c @ÿþN@«þCþ!ÿöòÁrP3mQ¢NÝl®m ø!8‰;˜øÛË'è[ #bt0%IG  Ʀëå6W¨!%„ó)õ'mì †&-Z›« ôÝnúOiºsýgæú´ñ8ýüI& È(?ÕâZ°-[ý‡üCþ!ÿìå‚í Ô\d¤þe£Ôt]H‚IiyrOÉó3[#ÒŽ?‰LŽ;qb@𓝵fë ÔüÞéäŸR¤Ér“Æ/ÛªUÚ5bRÜzˆ˜5¦ ÌäÄ™û‰“R”Áa<€Ô"0Z5m× h§ÿÈ?䟽üC°&I§*•0ü¤d“lŸ–å“EiJÇN@Úñ'!›9þ컈¹Sê.&HçþDj!ÑÜÛˆ ƒxeZÛf±y¸UÿMzovb“„ ?%“úþL°9 ¨uÐf—Môòù‡ü³—¶ƒRº$R'—÷çHp¹£lŸ–ååúæ{yÇ"'ZÒ~£¼0^E‡éÛ‡ã%§+]?Ô»éȘ0L£–ë] û™¤P‰TÉD1 NŒ[¯mî¤Ör'vQØ´câø°bµ·í`«ÿ¦‘­¯±.èņ‰…)i óyàÀ•4 ¶µ8ù‡üCþé’üÿÕñ—‚>ÝC* ãߦ‡z£’$`páHO 3~ÅÉe?K‘šü‹HË ) ‡å¨š êDý©é¿ý³Rò‘ ÀF¾ÅWX•™Ý€¨”'M—À.ç·) P ù‡üCþmJvñÿÿg7R$R…ó-¾ô‘˜«´ÏúfOÀÄ¥"jE!C…½ÞeyëäßÒš“®°Sj”²ÇÃ$ éL’¾6Saþn_Òä(Pë€~("^¥ÕàYÎgnd*Ÿ{ Pù‡üCþ-,äÿÿ5Kôð €xœí]w\ÇÛGcb‹&–$*)úFÃïšDc,hT Š *`CDÚÀµ½ÛÝÙ½ÝÛ݃“Ž ‚ X¢ ‰1Öèk”4{‹šXbLŒåݽW€#¿?w¾?;³3óÌîùý<3Ï33ë ÄŒs üþþÒû»„šêUÙŸ¼–ê5Zã|ŸªWîvÉ=´°ý»i°Š§û™qG¼MÔ-'ï3x<­¿ò£Ua§ŒƒË@vÛCæûÈgúÓã‰ãgNQ§lÊV{ï|eV³ýþ.g ·Ç´øÌ\Uñ }‹1÷›®ü°ÊW{ñ‰Çåi }»Àîmˆ)»}#N¹OøygÕÓÒ–˜”:·2>54“•L^£ Ó)g³”†¥âµÌ"­6’ѱR Äú÷í7ÒmiiV-ô¬¬ûÇ?'@þ!ÿñò!n\Q?YIÖÚ"ì•ïv “4ýÅÉC‹ Æž¾yn}þÑ/ ÷Ò;—&ù7ù².ÁNÝ4§Û¸üÀÚã Ak޼l¸‹ygmhþ.‡òé¾mõ?äÓ¬Cés\ß½ys%›Ö$왹ª—¾í cîŽäÖv!EÑÊÞBZtî=ôÏn^[qjþÝ®œ›‡W1µ¶Ò5¾$Ú?!êp\öÜ‚pf…_i„t™ç~RCÓ).`C8‘OK9*&fì§îc$[JKt†ÿÞ†j ÿÈ¿xù‡€¨ ž³6˜sáÈÄ5u7ÅGŽ‹N¥}WL–m)œ^‘xŽoÏ”Ú$c»w¹RtúŸÛªä›7vXzôî·¼"ÉŸÈ½ï¨ Ñnx§É6eê§i•@ž÷º‡×À×þáÀÌÎ_}k®‹ð:hÌaOnf2'»E oÝçÖ,;±1ü¿/»bKcZMÛuxQ¸*P½J}£[=mûì,&ôܧ4™-Ó0 ­Ëøo &õl§ f¤ò^îŸOÖ—”äë9Cç×@þ!ÿñò!rà§ Ñ4wµ®övˆËï-°±C\‰QïsVïf¦•‡¸>]BÕ(ÚöÍůxï¸ÖO÷~î)‡Z*g·<äÞÕ±+ñåvš‘y6e®ý¶ý%[ûˆK7¸ÉȈ}>šŠA´‚ý¥Ý‡÷ÍLÌœ³DÆ-Ðñ@ÃÅ‘dd*BKǢјû@÷É’Í›·$è áÓÆk ÿÈ¿xù‡;‚/ÎÏ™ÛÓõ»Ž«ñ¡c"ˆg+›¢™›6ˆis¦Ò-å£}êšµêMô•tHªíùxLÑÅÓã½§ÐŽëçvÚú­Ýìá‹thSVÕQ¿+ã¦N°TvÉØjòQöz}½Qÿ½‘.]ù˹ЌO^öêË_¿ùê>Þ»ƒß‘Q§Ç¡6›åæ"Ú'ö3/ý:noû— 0Ii :Ããk”¡±é”¿•,¥—)P,d`¿Ñ>º-[¿òù‡ü‹—±cpÏcÚ&ÒüŽéöUŠÇ7ÿ öù8î×)©5ÊÏpß}g¸ßà˶NDI‹þÜ_þÁu=_z¾oÄew¹Üaåý~~i!¶… Ú÷p/¶Ü-9±÷?ô¹©7Ýçÿ”~Ý”½]zÎÆúÝöÒ7þž#üŽÂ+ Nõ`‚çï sÓœ6¤/s ÎMŸø5ªÙKÿçÀä]£Ž–Ï×lô]:¹BI±LLzÌjñê`Ž“¥ÅH9¥ø ä9{íæ-ÙñZÃ#¯€üCþ!ÿâåBäÀ¯#ßô=ÿÒ$‰Í|a^n¢_Ž_óp{™©µƒŽ³þ>Ïuí+'âßÏ®vÌ[óqFMBf`§÷ï˜Yò«Ë°3ö•êâ?ó´Û¢T@ÖWV·¤Õ£š%“ {}6f¦©"ú¤ë*Cf½[–`ÞŒK­ùdÆ)_þz§ð ?8^2½ÿ ?½çÕÓëLŠG´{¨!ÅÓ·;تmVR`®^¢ÑaH–ÖÓ`q^°–c#UœŒ–«ûî¹ió¦Ä8ãs­€üCþ!ÿâåBìP,:}àÿmŸù ªs}x‘{›Ï©s/ºüÔo}\3~erx»&{Ü‚Ö0Þ/%`Õÿcm/Bž¦*·“Q=‰”v·*™çúM³x¶xÄŸ)üûw>&ÈTîw0ÀÔa@ªá(iÚ•v|rÛíã,ºÜ€ŸYWڷï”ÖÒàEe³ €œÛEx®š[2ñÀç'¾÷Œ[ÀF†•Še¦mÐÚE…¡Ú0VÆp*9á=dÐèiEÅ³ã¤Æk ÿÈ¿xù‡;ú€¿^(¹ À’[üý[Æ›]~>±À÷AØ:%ªÛ Æä– ý¾I‹>çÖ°‹³Æolü8-³cŠ&:+0>„c•Ëä Œˆù|è0/Ù†â‰qÆ=P×@þ!ÿñò!r`§G-éÓéé»AE .ÿñË·kX“[ZvÈë¿ûÍÏš^º1¿{z«àõNˆxMœk9ºcêñyØ¡{‰Û,µý[儲zëýü®VêC#–ürßm·WNxûšå½Ë&½qÑ Þ|††§_íÄ'Á”2~–³óÌ#®¶ã@Ï)Í€|Ò‰¢¹ûîîñ,\ªû—¼íIç“î¼U¤ZŽÉuóh-«ÕI“ÕI‹t Uª:–S ÿþ£<&$oÌ×ëŒæ®ÑZÈ?äò/^þ!ÄÙØ/··(,´¨G`Þš­»œ¾[¥ú\vWú°EÖµy~µŸ>jD ¢ãл«îoŒš¿¤ãÌ6¦ÕFøÀÝ¥VÛKíŒ}TiUKï&¬ÂUŒ©ð½¾®y«¬+ZSÍÁ†ž6uöÉ^Ã>¤»-Ãôj‡ùüÕûáÄüÐ-ÌxÜ]©~Œ¿Ž4÷ئۆMHݱÖÊࢩïü‘œÌ$y,ݦ“­–CÐ=«D8)ƒÃ‡}>Ú/¿¨xy¼ñˆÓÆk ÿÈ¿xù‡9ü•÷]Žßºîv9aîòÕÁ’²““‡ÎÖM^ºÕ™ÖhžkZŸ§VEo¸åºxd>Û~¬¬»×^jÞË­{^±*YØVÓ¸×.ŸâO_þÓ¼”86»ÝycnßÞƒ;„t~æµ÷„4ç²pbø©ÞâKºì’‰zųßÚ7¿÷¶×Y]©zrjxùÆh$…î·‹H]j8‚£'iX5ãmƒPJŒ6d¤wÌú¢â¤øFî„üCþ!ÿâåâEAl 'nÖô“Á f¤mhpé컣sjßñSæœhò׊_d{ŽÍvbòvÒ'!ó=›Bù ¯¨õ]øÑ<Ù7a§ƒŸQÔ¬ï[Öo7¾hˆeò[_mÕ…ÞsÊøYðø]?ÓGÅú¬Ý`H¯½ê/|l©|,o£ï:ÿ€¦™¼=y8q0±|UÓñO\¥ã[mÅ•¨¦&K,ç"r¢é¬9û¦ K®Õy14¯SkéÃDj¥‹+HßA#¼&,]_”¯7~äù[È¿ñòï4 ÿ/ÿâFIÎÇÎ8àª}ëâÞO>ÕLš¶Ó£=9«eyÙkõvÿìÈÉëGoŒ”Í\qðÆÙºZ5Õ1O<íËGõxW±jÛ¹~‡û:zÓô‘Û¬Kþ³à†Þr£^qc®~‹N6[yhú2èZ¬…ÎθÑCHw$¡ÅÏšŒã¯GÂÇüjG¼÷(™Ú¼ûôNÞ·+¹ÍÈŒ$Éa6Ïg—Ï…¼tJF¢„JA2¥aâ)"ˆHÃ#µ 'S°*Í`!Þ³×å4' äò_/Èÿ Åÿîçü|ˆç )¥!Ô¨Ã8PË%)œ¦æŽd0L…hi’// Yç”<Ž£JŠ&­[âê%37,ÕX qLIQMŽ!ZÛ#@p„ªÉãjEGISÃÏ4¥àÿCø+)¼£ŠðTŽ '…ÂOræFÆçŽtFä¹`+äòù-ÿ{ž÷ @8rÍÕô¨Rko?PµÖ\ÆËG*’8­#ý7þ̆ úÀà4¬ýAbÕ ¼Â 6#Õv 4p à´þCþ!ÿñò!và˜2’ÑÓŽÔÔàøSÐZÊÖñg-¯g„q\­ (¯<Äå15˜®µ«ÁÕ ÚxŸ~[íùfy&j V­"ŒÀ* )£ÈDšûW7uš€†í¬‡þCþ!ÿñò!rà•‡%ÇQ¶:.8þ„Õ’µi¿¡!*]˜©·‘çÕJYwhÑ0€Gé_! è S8˜ZàˆÆÊ¬àê¨àœxóó­ôßìt4f€áŠˆD†ÏÖÇ4h Pý‡üCþ!ÿâåBìà‡êÒ%©lu¥2:þpVØ·[·Utx6WMžïQN1NlÔŸ%*ln¡Þ~® , ¶ïUÙ„Q5ˆ•dšÞ¿jÿ,Û‹M, PË¢“ a@ÞÆ@`½ç ÉÔOÿ!ÿÈ¿xù‡;„0–hÙ§cpüÉ)VSSØÏ|šj#ò3 •’sèR´“3læõP1Oº^g#£JÖö衵ñ ªq G¢ÐdÃû[é¿Éhöš&Õ–Ý€¼ PE’za7ða¨¯þCþ!ÿñò!và˜"Bg âüèQ²öû}j——/Ö'šäü +yÓ´Çb§feY‡1mwô‡$¬Kq§! '¼µ @–`ÕY`Õ&U@ÃqI(I a@ói Få¯Ë4P Pý‡üCþ!ÿâåBäàí²tepü¡œÃý>µw€Æ¬>…"JåÔÁb˜JYµyG#g­M®¾²G­b ‚!´õ¤çÕœÞ_–Æ¿? (KSÜÆh5¨š³Ãåá)ecêþÙ¦´AY€¡ÿÈ?ä_¼üCˆ‘ 1©ZÁñG9ö³“ÈI6‡É¨Úw[€©qVAG$xa‘Þâ„Ää¬}HÐAøWÆã@puŒ4… šI1ûÍK,gU; ÄŒPK¥I ù/ @C þ+ý‡üCþ!ÿâåBäà(" ,wÎwç°ù¬"ʼnSÁ`jYœ“O!6rFÅÌîäO¡XÙ„ÿÌú/˜ UÁTuZ¬ý0p㦠ׯóO­—h€S€§ÿÈ?ä_¼üC¼(À믿Æ¿*Opbߎã>pUµ8)EëÔwÁTvê/ègÌ´å™ZÃ:9çhø+m5jÈ£Ê}œåý-;€,¡@ËV »³À„YPyËÿþú€gÊ!ÿ@þäÿâþý7ÔõÁ +~9ÉÑ$¡–†d8÷eO»>PDGcѳ×9ØËc×Z%s¸çWá_¤!08<µû(¯ÿTÕ PK%iæ/›Vm6‡LLg € p “…§óSç? f|¬ à Xù‡ü×ÿŠÿÿÿeÿ0ãxœí] XǶ&î׸D ÊÕD£I.·5šˆ+‚! Š €+ ‚,³ÏtWÍôôôì3 ‚ˆàÊ"ˆ1F½ŠQáºÆ$&.1n×øŒF[ÌÕ“×Ý3Ãl`¾ïfò^×ÿ}tUW×Ò3¿çX眪ˆÀeŒ»•õèóf׳ssŒìüŸÌlÓ9ïõ±êJ<äþîgsöÁ÷ó¢t«ŒD‚fýø›Uk~mj Ì]¦/þåÓ˜!„óCÉÓðwŠžV…ÙÝ’3œ6oæW÷îÉ!l[û(ÀRÛ*šmŽ»–ùkÝà‹#s²çoIãçn7«HrÑR%µ rT ”jН‘Cq„1!¼²ŠŠå:’FÜôö_âñøç.ÿÜÆ×á‘WF®nV]Ù€‘±SµÞ™u!*`[¯yfÒÔžYÏ0"öéámÓãVì:IçÓ(ßo÷êõÒ}õ3Iºë;Ýjˆ!Ië†·ÞØÂÅ£ÞûcÌ»íÚ½³Ýí/×B¢¾y<¬`æ¬W×¾c-Žý‘I#ro `ÒKc˜Òƒ7} ôö+¾7óGZüùƒóCŒ_,8sïÔ áÓ¸Žq“wL;ðþéí)Ò’…ê¨ýBR—¯1ÓÉ›)Œ‰j5S´¤p昉S²J*J Z‹Úò¦@ü#þÿÜåÛ¨[5²Ó®€B-ÕdÍ´ë—¶õ}åÎå¯ü;ÿª®/í©q÷??_]äbî3v¼òj¿Žg7i,·AÂ+/¥Ì]ÔÛ]õ›kDž?*wÛ]úˆë™¢£W/:?éÕvH¹¢q‘¹]î)»Û°½‡ßºº©Õõß½U›óÎF^•¥8¿ú· 6óe÷¨t"ÒtºO'¯vœA_¯Ô\€°eÍnØQúv*üúöÜ“OÉn;âqæžãÃ+gì›xâW¿•Ù õ)Jcœ (¥A6Ç’:•LÂÓ.?!`Úìe« ÖoÁ{ñøGüs—ŽC¢Ô|~òüï’vîeŒˆÌÊþ®Ç†ÚÊê#¤ Û4uÂãö‘Æ›ÍMVµOräªOÙÉëíÓ¿mW•—}â²þ/çŠÞ®óðjx§ÙWF?WùüŽÇ'{ŒÉ¡EÓ;>Ÿkw+<ù¨VΟ}:0òʉÀÞ3[­¼ÍîCl&Ôü`(“=œ\H'ŸÔ¶¢¿ˆOµ¥MÓ‹pÙ ï`^ßÃBÑÀêÜ3U…mš­m1»"rßû_Œ8·c©Ø¨’d’û õr…zAEÜ–ù„F*4/Ó©–% áo*_®W±CyO þÿˆîòÀu$^ñÿ¸GþàOw¹­!í?<ÆŸÊì5)@šRìô4Ãg_þ¸¾Ïms~â„ÐRŸ]±k ö…ØÄ;ÇkI½sýö­öÎ[7Ô“mq}=ìÀ…¯{vžÙXKÄÕýØz˜Cå.}3bìïßî4ÄᬇÃËÆ‹öw®´6nyÊfj»Ï9ʤ¹1‘ı'ïÑ  †Dwþh€ŽV„I vÀ~ê[¥Ñ¦§µyÙ§|öÌ/¬ù,àÜ ZæÌ3L;,&5P#—Ì!”º¸ò%•¢‰)ӣߟn../1è¼íDü#þÿÜåëx¿Ïâ}/—o}šíòiÊ¿¿-ò}ùÞ ÿ‚ѯ™]Ö˜> w÷Û-zŸÓxFZúÑ”›DŸ[?:>H yÙwÓ Žó|_¿ß‡ MPyè2cVË%þkq^ûVßh#ìŸlÛWñYCíÇ_³¿¯ñ«eÒn¾'óµ–ŸÝi)öï3{› ÔÔ›¾j¡Ñ%/ݹî^;„|Þg7>Ä“10ÿZô¿.…]v¥eÆ¿Þ×p~ÜµÛ ûøìb‘ÎÓ‹‰9“¸™NvŽåÓËïHÃÁoáï9ÖVŠzܲ¿î’ú›‘–­ñË;R»ã‹ñSZ[FÝÓm>»8z×Üd&Ùt¼}=ðø0„~¼û>–u€C¾€pèÁ‹QÄžïïF(ö¼“ZUDj¾zî_}ì&…y’’6mR¥WbIªlQ:¥¦ø*©\>6hcIyŽÎ}õš@ü#þÿÜåë-î˜+%N„}ߨTÜgpT{iÖŽŽ¹{nš²ÀŒ»þ]1úlÔw$ùe¾}Ÿ[ýîFEœëU5¥„µ¦¡dhèžÉK‹?,›…•Zü†íwë4àA„ÉöæuÂM·«¿»oF£0ã1cÖ[³I=¶ŠÖœ÷È踴êáEli€â÷qL:¡dòWtÒÿÂã¶Æ×¼pÂë7¶Cx«ƒú¼~Í[1üaÔ¼WÇ3önÐ.Ú½N -,©Ëÿ…A’Ô(ÃåšØòF¢ÑP<5%‘J? 7o,+6i-+ ½§ÿˆÄ?wùGà:î8øÔ8¬š,©/Iþö¬±Ó†Ôè[Î+l²}Úéñ££þµ~I®Ë§º#V¤~]é¶=æ{txdåè·Hëý{ þmZwÎ÷8æÊTPd» º2APtÿ‹~é]>ž|àXýÖ‹x£FÉ'Öß¼ºÌLT|[Å—>?o)ÜúR*küÐZÁh–ºWÑ׸ÓÓèë‘ãwà›]!ì¸g7ô?CµúôF̾ÅzÞªv@Ÿï?Ÿ\¤HÙ²€H+ç«tSäZRµf)_™„ë“ÔŧĘjið” ¡ÑëŠK ‹zõž@ü#þÿÜåëv{=ÞNš^£enðPJwøNêòÿ¿šjÊbÚ݃¨ÝWòœwóŠ …·—¿ûóß_ô¸Èxi+im¸ïZ‹@eÅ`ÊFvúàÝã~ £‰»NÖòþyvÕOßáIï8-(*€Yb„WFõ«i¸û(yÈÉauʹýª`þÊ‹å1JÖz “ââS#™tõ©®L;ýKúù¡³>>¶y"_<ù4\ñ带ôé\|iÉØ¡ûÇŸ<e(š³Ú˜L™ÆQA¨HMʪù›(•BŸÊS«Å2Õ̰€©!‚õÅe9zë¦*ïiÄ?âñÏ]þ8üôЇ·¾öí@¹Èo@äMÉ2Ù¶î?íátÔµ+MÊLoãxÇ(¬ò¨(±ºGQSíG}Öúç#ƒ&×B¶öí*LVå±¶ô»wÍWžØ—„îšµ‘/ÝÁÞ'ëƒVšØŒé?fQÃÝiSÀø5}JRM+íé«´nxI žN:üàÓžNJƒÍ´½Ñ½/„Óÿ ç xûêOÁ¹—\psóí"†÷ý rÆÞIÇFœ¯Ì䈥+&Ö@ ¢Èp9™Xº°4^©U§R¤PÔ¢ÐàÀ ÌJŠMZ«éã5 €øGü#þ¹Ë?×!œhNˆ¯Ó ZâíîÖ „óHéVSvGÈÒ^k“\ußjW&€Ëk:dF½ý†Ç¢Õ ÔW7Úû,¬^õhÉÖZÏu‹ý[ö2;¼Þ™a/¿úmÌÓäŸ(_§µÊØ/kŸ³/HͪkѰâé²lüÂYW ¶’3ï?ØÓß²˜yˆ ƒåÈÐÀžAzû &éðü´BÍ~áߪwÃÛîÃÓ—OÀÈ3“w]ë’÷æV=Š)ŸùéÓ|Ú=ö[¾jž9l¿D¥ZE6€ª% £X­J£@¢Iœ2%(,zíú’"ƒÖÛN@Ä?âñÏ]þ¸ŽXÂÔ¦§r×/¦~#M–÷ÌíSЇ´[_íÿj½ómȲó£'? /m^{ÙµüA/÷ßÉÓ¾ü­çšÉþQ‰7:–‚{ÑÁ±¿=¸^øMã#áæðA—í ð箃†£O®ü¢>Ï?f,=rÒºðheWŠ5î_[˜Ôt®}íÚ— ïµ›S¡¸ÿUhXÃî'zÔ´ï[1rÍ¢Ê>u•óJ£Ïü(UP,äi/V«H‚¤4 õbR©¤D2`æ‹ä„zVðÄàᚥ¹Þw"þÿˆîòÀiº¿±múä° FñûOÚ?ÔŤ-ú¾½£õ1ìÌœ—!ÞÚ³÷¶à±Í> &UëÙmñà«?5QÏ·ôÐÝÎ.ÊS¶ßì™·¹ø“Û2eèÄ ‡•¬ÔøØ)„Ç¢#G ”ñzõÝ7·±…o¦¿h‰î}ËÌlÓyðKÛŽtR½«=„’Ý-ŽCxîÁNºè$ÌŒØ §të·êÖªúØ#í×$¼/Ò¼ ΧcvNŠR}¨5ª’)…fªŒÂ ©,8dâ´pÓºâ£ÖºÉÊKñøGüs—.cá—Ÿ§µ¼;ò?±gÛaÒ-ÿh77SÛÖíû=sž4naöën{–æ‹OïnoÙOekj¿Ýo­ËGþÏ>˜Øë¦ã‘¢s ã%•J†¥u n¸{í…¿ĤIcÒÂ{·Ô/—Ý©¬ïºœ5âeÙÓ@/âÓWYΆP¿L‚p\w퀱üJ8nt›ü¹ù–ä¬x»ü´«ÍqU‘¥©Šõ³+Óùþ Uši@­Y¹ŒŒ/N"(1Fñ øB:}é‡B¦Í-\W\äÍ_Aü3)âñÏMþ8 l’LUùÙÕï󿹨ýë_m&'^ö¼þÆ=¤a¦îïõ ÙgJÁŸØ²é& Hµ!vÖ ßZ^Ü:Ge—¦8ðeCï9‚oÕÍ®25*ÐMñ|ã_:;”sùXßÿµ³–ܸ*Õ–o†}9ˆ~ñ>Kü¢ÙÂÎÕw˜”¸ô }­œ—B?ô{ÿMWe;·†äÁѱ7òæeì]ÿó0Þ’_·ßk9îØßM|ÁŽcØ^L¬ (ŠPixÙñ[b )JJ­b6cÒØÀ©S…EëKòtÞ9 ñøGü³àÿ{ÿ„1þºX˜M)š¿Â@dšRÒäH39êghoíHJ5!‡@’šY i¢=òu¤ë*@¿´R„ZW]LF9)aï†L$2S (gj+¬Ë“.·äpÀv p6Á¡‚ys9ýÖ€Îát‡Rž(K¥Pú»hÞGg°¦Ö—›Øü–ÿ¬Gü#þ›]ñÿÿÿj¯ŽŽàmÓ£JÞ< ¦¥—‰Ä:R©°þã¸8Uinn{[/˜X¨'­²%J Vxld<-évå0.'7T®Ú‰ÜQm‰²‘üËP’¡Ô3Ê àÐöƒubS¬ä[Dß’g.Œ ‹pI ¥WÑe¬ƒæé¿øñøGüs–ôÿ?·0Qr–VÙ ǤB¨¡ç»°¡6À„ 9z6[0“BCØ?zÙÍüZÅßÃÛ,%¦0ßU{\LMÈ?F 8&^fÐП¶ÚN`ÞpµSã§é JyƒhŽ ¨¯âu °ñøGüs–ôÿ?Çh L]¡!I†ŠÐ:9mû%@63ÀêdÿäÌ÷§'Ͳ½Ú2ÞÔ¬ü#þÿˆîòÀqÐ’)X’£S:Ë·ÅñÇWi˜`š§0á*½‹ööuèÉ?¡qjXfd©ÙA`éNÉ&Ì \ )vnŽ¥Emȱo‰ÔNGŽà•Kùg>¿h™Ym3Ll+€ Ç Å ÈþAŒŸj2(ŸM8šÞÐÕÖAü#þÿ\åë@ÆK_¡v£YÚ)ìçÔJ3RVi܇£'ÿnãŒ@²,¶Bß(0ˆñ•Ml.2¾-r$Ió+ŒõÕ&q ÿALÚXþqŒ°ÝÓŸ_(0Y_N€ÜÞذئH„i+Ø0àÿ©½@6ùGü#þÿÜåë`Âxx–½wÎâøÃt*¥;ÇŸCû|¹Ú—ñëŒ%ÈVkä ,P4µ7*öþà¢q¹VnSÐyWùgt‰Ã'žýf z8zY¹oØ Ì„¥¸YIü1à- Ð ÿˆÄ?⟻ü#p-ÕÙ€VÇ©!݆ýœÛ &Wa@fòÏ3ºŸüÛÚó£V­°ŠmsÄHE:{}…óf¬^i â"•‹%Á²Æ:Èv>BŒ±aÔ¬ƒ²~ƒà´)&Å!¥ju¶!žu3°w4€½ü#þÿˆîòÀqÐbÊO\©U2«XÇ_§&›rü5îãůÕ9­»¡ûâ{žü×·O‹*31í&Mm*¢õ…ºñÎ_€¥F—d)™¼PãþæIþqœ 5`¦"§žÕ0p0ìW9lfÖA?5[Çþðˆe+p³T€7ÀäñøGüs—®i&o…ZÁ8þ¤:ªÉ°Ÿ‹öééùç퀑*#ÕÄäßVY’<¿BOË’Ó5µ§ˆeN$.¨¤ÛËd”SøÏ…üËíÆ`Že€bIàÐÁh¼Èåa`¬Afë}? MùGü#þÿÜåë¸8™2`NYDIÎg‚9Ë?”öò/'˜˜§”¯ÐPá`¸ðÚ­‚6 ÇqYšÜdÙ Ô¼OÌönËüÙÀIþÿˆÄ?wùGà4³ìv6ŽmÌ"ŸqêßÐ&X¸Âd=LœajæäßÚÏŒXMæ:‹¶pt^âkm_`0;« J¡~åŽ=@LÂSj'ÀÍÏÔ+ËV`9c¤ü™€·œ€ŽòøGü#þ¹Ë?—Á¬ø•Åz•xQa“î7ÝÈ2â7°ówfò¯Ð)Ÿí'ž¾,¡Ì…; ’it{jhjŒ‹#A:Ê?f_€[etVs š}äÏåÏØ­²Wr?u¹Žøc àÏ5Ë?⟭‡øGüs’ƒýy/ -®*zR,Mþ_ö¬ï H–ñWje˜ÔÏ2ùgã"¡_œ¸Yçi|€ çŸí¡$3#cƒãÏ‚©ÜÁ¨ÀeJ».X µs™HªW²/îh8‡]( á —{>ºÌÅ[Û2¢°“Ä?âñoíœ+üÿ/‚sÁð@xœí] |LWÛ·ÔNKk-Õ¥Ö*¥hQB%Y‰ ’!ëdf2“Yî=çλ̖=‘M"‹Úc¯zµâ³¥}-­¢-ªúCcWô½w’™Ì$31éûÑ÷gÎ÷ìËÜ¿ç™sž³L#ˆ€ÀAÜ¡—ë%s¢öÞ›)Ðú¨ì߯»´Lø›Õ…G}pkãÓÖ—;ÌŠÚÕ ’Ñþ$¦ûfý5$¡©Æn¶û•3 Ó vûîý÷c—¬<þù6•Eì;9ù)ÉVùÜo/ ¨ á ¾eª½w•óOGª—\ Ñ!ÿ˜1RœÉ;g[½Úžs®ú¸rÏ6݆ðƒéAøÔ}½#~D”/¯ûòë^­®ü²ÏÝ×í Ï}þïÞYúE%ra‚«z?d!1‹ Ôzu0KEÑ,Í(cYF)ô™ú¹»ORÎÊâD]Õ YÞÛ Ä?âñï¼ü#81@È‘£!n_Ùµ%d×™ŸXc\Ù‘'Ù׿ñS=£¬=ôoâM5îH #Ù‹•LJÕmå]èÿôóK…Ùmg‹ßúiéæOíÔöî<ÛÎ÷þ|Ïã՚軣¨ÉÖ å`Úæ{A_vw4ù»í í²y$}om·…}棲ßÛaTÇF`¼“å÷ü"Paãâ³Þ:TûŸ—ÃVlL Lh6»`ÌÉÀSÑä¿õÓ÷¾0üÌî@2UÄøï‹'iA0M­ˆšà¢HIafœˆee U°ß7· ¬ü•y­ºª/F þ@ü#þM~§âÁ™¡/% TFå.à Ú2³¼c…½Îîé< ^ü;u‚.“½ ½ WQI»RNœ¶¼Ñ[í7¼¿«ÛÕåͳÒmå£O?êÙBm§’¹×U;ŸBø€ÝüúÅôä­¦è/Z«È{髳-‚ÑÙç»™üsV\#>.êîÚLMuX[5ÈðÊ4¾éå>ÜÓ}Ëí× ô99l-„ç;¤@üújؽÏ8`_FêÜä÷Ëhyß‹~Ÿ‚>!›Þ½¿Å³w—ÛE02P .jͨdæm $5 C1á*Š”ûzy¸»É² 3 ã;x ñ_ Ä?âßäw"þœÂ6=G­UuÁzŒúÕsbžuÒœÑý^Î]ÑàJ#ÜÞhV¤É/Uº·i‚':\Nºé>ÌYpÁ¤ƒÛ×}C3™¨“/ø)˜ó]¥½Z¶)ð9·‰ |4P–T­Y×ø°õl&ä­qc,fî7åÓÌO6}¬2wõØzR£a ŒQÝWõx‡w÷wíôç¸pOr­÷<|è;¸3„íãþ„}O±)iîY`KÜz­ôÌñܲíKtWä_1^°ŽLù¬ € ˜é€d‚Kƒ6ÌgÕšJÌ22=ÃÝÓÕ39» (IWm‹|Îñoâño8 ÿÎŒy‡¾žÙèæ€£ß mÞ´®œzwru®õ× ³áv£Æ®ùnuÑwaC¦®üÓ;7ÙA#bü‰)=\ß2G(f½2hÉÍ )µ3V6½4XYW-TCÙª£oŠÑ5âÕ”®ò¤e$˜êw†².£8E6]gŽøµe‘É¿»Í“OÇû~½úÃÌïû´8nŒ+~’w÷jœG|‰Æ=Îá¬ß>¡à‘Uí l±¯ öþHòÏ\,)èáZ™8|EÅIKçoÈ—ÊWû+K'íÃiÖƒ$5;¼IYò¢ÅMÅàIbNiæOóž<5(3¯ ß ­~ÏQ þÿˆœçF¿¬­M?Ízxõö Úf†æŸh tÔܾv…­.©¬8sèþ™<~óÐÐnÛn„wÊ¿ãHAùïáE‰ƒ§X)›¹G‰vg]ßg•qèåû!ÖQ<îÐñš)0²ãîæ{J´Í9oË{{&×ÊñJúc‹`žGI´É 4ŒœwÑåHŠøI~ '\x` ïâQ×ð.Õÿ÷Üwò„eI#¹Îö{aã»ZøÎE˜8k¹"°?$ éÝ^ßézøk×ǽ2h¥BX²P3c—B;• H†¤ÙEÌbRÅr €3¬‚’«¼¦Ouõ”få¯Ì0hªçsÓˆÄ?âßçãÁ¹1ÿ۶“őíŽÐ•Tú¦SGR§t°Fü•O†¾¶òÄþŸ«TØõ6.:¨™\ôŒrÜh¼eR¢ì{\_+ú©~ìhlÿhmM 6©ËèÛ¡=¼¥ú®À; {üÑW“¶Â{ðWjemùï-ÑÁ-½ójšù½üd<ç¸]|7°KnÙ5!¯Í&Å\[ȧ÷ïÞ™sî<ušs–ç¸B8dÄ[ » ñFM¸>ü fæBß50h^Wœ3ü’Þs‹Ç—ãŽÿ4<#qa!èÝȯ­V{Cµ&lE˰ªhZš!ŽgY`Ž÷T7/}NþÊd]µ2|^ ñøGü›à|ü#87þºÔvŇý—Õ›'æP»»˜@0;Í‘ :Y:¢íÌÎ;SÍQò;¤Ïû%sSIeïÚJ¶¦ÖM¥ ùø†9üãÒýÚåÕÍWþŠk½OX„ã¯zÊKS™ÕÊšS©¼k\|ºÉ³"œ¨ó€wñ‚y›ßR¯Î쨆P›eTk_¸èxçQ{~ ðÕfþéœ?ËþzÁQ8§wˆõ¼ õ3V@Ÿ p±pi?ïE“\JÕ[¦þëñ«}®ì $Õ$=w+FÒQ¡*FË`TèŠP†”*(gY© žî=mêü¥¹yÝs5"þÿˆœçÆØKWnÕp×…ëù•­ÿ}:{nÍÀõ<Жí8üÜ+{aȯW‰ÿí:½Þ¢c’,úëÆr[i²'Ï1ºïߨ Y=iïè/7àß÷æ¨_­,g_|2þ´Ÿú(U{ó}ï§ZËð.Ï®Ì6‚¾5z¤Åϵխ¿0òQ~yZS>Jz{ïæ¯É=GߘÍ=O]ãÔ˽‹«a—ð¿`ÌÀ+Pç³z~ÃÒz÷Z›øÈà·üðAßÂÐU~ÛáQyT •0¢(’¢µ±é‚ÌZ&¥ã–ÅÉ)B%™ëéé:=.3§`™ACV¿…ú^ßßâñø7ÃéøGpnŒü×3eÚˆÛWu¿«>ûþÑ͈ žUÛF̨¨3¡èµùàâ×{³[÷m¬]\¿b;É^Ä6¹Æ0ºWWÎ*?a9«Ä=w¤pÊà’¯;<ºë!œårj½J Ç¸xá¦mƒéÃÅý÷&e2¢4\x~¸.¸ˆH¿-AÍ)/Hi):j#H†¡Å ¿x‰¯«—·6;oEŠž}ngÿˆG€ø9ùG@pŠV­wù4[k? v³½öæ›s—Ýmfc1dÇÿvtïíJ;FD}3!§ä=Ë+@gl R,ûx]Ü-ÉÚómÓÈjï-·§ý]×¥Ÿ ¹5¶ÛD>Füp8ï–»ùPÚé^žžã ¡äôû:èçrv¢®@Æct+IŠýa8þë‰caš.k Û5ùðŸ×G+Ö<÷(ôn*Z¥V±´–"KBi2–a)«ÆpRì?sê ÷¸Œœü,ƒæ¿ ñøGü;/ÿÎŽ±9Áfï ™aë,ò—W|ÏìOxðjW[ò]…¹Y┲ÙgºÕIYÅë[\ÿæÌ3ÚËp¨#1´Ó¯nÔ“éÑù2©­>È–nÈN¼ÖGTcòŒ+î§°ÚØÜA6ås 2ê¶É?¦Ã•}ðµ%cu^âQnŒ»÷ëλÄé÷¹ç¡‰±,„· á[Ã>„ð³°³°rÕeH»o„®ÚõÒ=ôá²M&Š·´ >0åðÐsý®‘¥"Iâçéë†R«½uØÊ°L‘ Hh†Š£ãYFãïáã>]Ÿ‘[¦«¾ìÔˆÄ?âßyùGpr€=ž6ømw]Aõk$rÉ?Òñ`›’z+èðç½§£'V|Q«Úõç'Ó=¼õì|²“bn WÔs¹Ìéh+A˜6áàW¡}>nzªð‘¹åqº=,3»oW:WÁ–W{¯N ÁmJºL6pH&•ám\æü¨ôä ÎiòN ÷¼'êaé¦~ÔÇŽý©)[ kØIX4'¹tâF¿™xŸRWÿý3ÖÎÞåzvŒ!/Xëy0žfÜUMkÕ˜.¨x‘J­–,ˆY\ƒãò…^~nÓæ§,ç€ÿø…`ˆÄ?âßyùGpvÈ?·Øzw¶U¬âìýÞ_÷ýË«ïÀzìrF€¸JomŸeµëv—Ü7Òf·q¨Z5«lÚÈþÝ_pço¶·•°èadôé;­+ :7-4žŸ2Åê~ññ±šPx˨wMþ!*Cðfîùë¥óÿ88ž“ŰFó)#×'ó6ѲåüV¢#å×!œÐ¿3„]×—ÁÕw~‚êÉÛ¡ÛÄ»Z]D=GáöÀ_ßvÐ''h9«Ùà³!JºB&ÖÌ”S¤šÔ¬NM¬ Ñ“ŒZ@‹J®`cçÌôqŸ&IÏÎÏúøUÄ?âñï¼ü#8;ù¿Ý¹ìäúc×…ùTÎxuâäûý6:P^ª¼~õž@JŸšÞ¢y@ù‡Zk6&=nf'¾¿©¶yžyz°ö½ž¸ü9Ùuw‹UË€¿×ßµ*Þ¿Ü›9$öÚ`9øãøè8Α}5åÃÄc>޼BÀ9ƒ{òIÅ‚pÞÑ ú†{®™ËI'6¯(Ú. éR§¾Ù=](Û°0*'âFØñð{C~?vç¬L´Õ'==LãIÀh†¤Ho‚* ]7aÔP,Ò‹XZÁ,œ3ÓÓcš6#7?UÿÏ_†øGü#þ_þôãL//˜2^¤ÑR¤ à²(*‰&pí§uuxüb6…zµªaup-Ç%RH|“sû÷†¹Ä@Ú«—Ò*i°.Óºÿ@®R[—À•j‹M5ˆI¤FÍ¿ TŒPUuÐÆ¡Êô¬zpmñÎ@0E e ¸xðüìÕ®©—.Žû/°·¦iÄ?âñ_íu:þœÜÿ;“K% Åýß®¾·“„¥ë)ø·5€rIPRzŠºpâ/Jâå`ÂYi”Òih{5¢Lû Ãd…›öDå‘…Z{åùêµõ.2Ù‚%ëø3¿ê›J¬»aØØ€pYíþ…ʪM«@€æì÷W&×qÚÂtHµÐò,Pµ°¶à”÷*Ä’dÍÿÚÀaùGü#þÿÎË?‚³à²u=gyìþMéÒPõ2ÛˈœvˆetϘ^àoÕF–R¥ý«?8`q¬Í£Á‹Œ5¤ÔºT ­¶æZ-švxVJ V ¡õ^`Ë%@ãÖŸª{@`@àr‘ÄŠjÀ… Ï[4@þÿˆÄ¿óòàì˜dáÒÛW‚rƒ¹$Ðd=E€‰} Sl'€ŠXêÙ7… \{ù(µàD‹LÔ©‰Ýö|5@ƒäñøGü;/ÿN•Â+lÓùÁt²Öîàß”MP÷JOþˆ‘Ú¡‹Bù+A³R õµä ­M+À,TŠg[\i 0ÌÚ”hµh¹È8Üœ‘ÒLõF(@û …`qQKYË;GÀó¼¤aòøGü#þ—gHG’Yû”?ø‚¦¾Á¿¹üAa­e8 ª ^‘‹fÀõúz.%m,ÿñ­(1†àÚO«é?¦´:d½hu!¸ñä]b¼Ì 6~P³ØþA0 €ÀR$Kªçð²Íž›<ÿÿ ¡òøGü#þ—gÿËžëe4nð/áÿŽ] pi`‚Õ/s¥&8(þÒØŒ„"Öî*$.ÔÛ® (pÆ(µ²H&ÑÔ>¦°>Id}#¨år`µ´ó?lÂi«_µ÷ƒ`¶W^C%6ðJÐç¦.ÿˆÄ?âÿeáÿ?žD÷ðPÃxœí]xÕöGTå!(M¤I”¢¥J‡@$’ÒHo›ÝlŸ¹w¶ÌlO²é$„Þ õÑ ª„P@Tä¡üg¶e7ÙM6Á÷ñýÝûû`æÞ;÷ÌÌæ—srÏ=÷žm‡! :$w)¾×ÃTœ¼ó`g@^þØñ”sò^“åäšù“©Z­ƒÝošåœì„oκå³qeåMñI»¼«¶$½NØ»2²r݉ÇL¡møÑ¯KdtùõÍÊ6½ÂK‚´55í•ÏÌå^mŸ¾ð¯£‰¿>a=YÕó ˜<¼u+ú4qý¿žAÈ^Õâ „WCø°ÙCª dÂ.8ë¿ã‹¼©½°rbw‡Oï^½ù[¿ã_’/‹* Ç3ĘTᆓ¤œTÉ À£rXj’Œ%9$Å*ľ¾sܧd/-Ô©¦×8÷ûñøGü».ÿ.°¿|[¥Hdзë_¾×Ž}á£ÉÛœ¿Á“¯îžW-„ùLùþ±7AßB¶]•­ƒiú¼¢ ü ™Üß'0ÉN­^ž›íÊvp»Ue(aºŽQï%¾ü;„keM/Ší¹¾¦Ö<~ùsùÜB®±44r礪õ‡þ’†…½ñÓpù^—÷é“PJHèÔ?H áÅ[» ¼ã?†Lº‰qÐý¼Ïú/ÒÚÜTïõñ+o—å?dbõ¨/O ;rrJV`†É5eÚœ8 !!UY€Š ‹àdEI ²|xÌòHHË*ÈÕªäÆ·xyñøGü».ÿ®Aëf+Ûf—Ä'ó÷^9RºvPõ¼ÊÆÈƒ©Õûgt¯þJ›µHêÓïY¾Ä)1¼ðo×ÅéèR̸×öýëZ âÕob.ÛþéÌóçûLåè3Ggõ¯¸[´þÁ ï–¤u¯yœ ÷­VÝZc–ï·miò9Fßÿ‹Û5ìÔú‹qC nÐf¹Ì«TM ¤³®xÒǃþ~^-{½=Ï@8fœw ü‡'áÒô‡í“¯ík?¤SòÃë~¥Þ§>Û‚û}3ÆìÁd*©Íœ©bïU±”„v¸2 H7ÆÓk®»™™S˜®QJ¯ñò,âñøw]þþ!’ ÷±‹ÀŽs»½Ùi‰¯Î÷šp ±òœ¡¢ß×üÔüò‡7žÏò<*sNèžæ/`(bX§†yUû¶ÜËßÒØÞÕSSn©k~wß舸5áW lº‰+w=¬©k¹¼½¹|üs’o*º-:?÷ùÔ÷»v›¾j¥¡A–Àœò·÷§÷~N·~ÿ „ßÝßgWBøÅA¸`3»ßÚ’‘.ÙÝ÷Ä£½—½½”Ké"wN+’FgNÝ Tnb¹B&#ÕR"pßÊPŠŠ‘s²¹ ã…Îõô˜åŸœ™_¨S›í [Ä?â¿I@üÿ#øGpmôÝÙ¹™·ºèÕªøä5ÕÓ€¤žá±ö5®~ÌüéæÍÓî[Q²ì/'ï6ë·k¦é/èWå=uÆÆ6]:³«EéÄ‹‹ÛY©:¸:mÛÕ±ú.º»mzí¸ø ¦:èt†Å8½ýn{“°ç¨ÞcŸ³÷è9‰_1 ÁѾçèÎøš>í[ÿ6„A•£Ò¡ðbœ˜p‚‘‡¡ï*,8úXyÊóSÖWOß6êÂÔe=¶ygRQå‹•[`ÒDév…”ò€ÉÍ!d&Ã(¾„b€1~ <Üg³õ¹yyZ•ùGö‚ñøo¢(âÿÀ?‚k#OÄû|WeÇþÁ¹6uÿ°ƒE§šhB®|R6í­~ä•“ý—ÿܯtýšúïþÇ®ý7°‡ÚªË O¤c–Ø—žpqLjšuoFõÒ®e¯<Ù¼þ±VOYUý~ö4—÷N5«›°-÷Ù°3Ÿ±W/æ¯ÉcFã’‰>×èÓ+7Ç\¢O…}¶CøtäL=^áHÉA>?²)0c  •î{CKãKJ‡\]ýÑèSg§'-)ærR&ïÁ OªZ¾W”ù© …<†¶’/"©Åžn³U©9é¥É,½˜@ü#þÿÖ­®Å?‚kãçåÑÁS§ê› ÉY}HÔüîkåXÓ{+înŸ²†{]ש¢qÎ~},åv÷¶‰ö ü|PŸ¤›y¼bÒÅÛí‹?&ùª–Ÿâ§;Î}Ôãá:«¶èÕØÜÜšêåÐË5áÄgíº›€q3ªr¡økIúŽ×Îå<¢_à›áÙ†Ït1G”óÝ ¤¶‡°õ´~¢¯€ø°“p‰R'ï€aÝ }G W’äë W·wnßõî.j…ŸÖm¦tÃdJ!§Tr,byE’qJ„S8Ëxþ¾^³=üu¹…Ij¥éc¿ˆ@ü#þÿ®Ë?‚kcò1Qõ¼N+0i#åÀ¨Í¿®%ötJoÝ­ßÆ¢–MñF&'íˆÏ¿rn+UGgúwš±wi-g…{mýÃ.côóÏ,ë˜á`6qã&]ó:;”ºxžgŸúæÚ锚¦³7»ÕÔïY¥e‡ÐŽBSñ®ä-Úê%¤¨isÿ¯¾›!\rx®¡O³¨Õã€û|ü)í5dõ†°÷²íü%ȃ“¶IãO”.\¹³Ró ­[â¹Ä"ÿÃ_–Çq3!W7UZ¥$É ‚dd¾z±\…cRœÂ¡xJ‹´pÞlVrF~®Vmþ8M·ˆÄ?âßuùGpuÜ­è}þÕÿm”PBþ.ï{ƒWe)H7¥ClÛ?›jôƒ'”½ëyö´¯ïÚmÚâîe ö9°ûžKu—öNš7¡Ÿp{7ãÊž­“4Ç:V´§®™»Ú¼„-=3+yFM”Ïý««íZ}ÿ†¥r¿ýÇ&@ÜGuŒq{|úðNM¼?°8õƒ‚µ†È#QÕ‹>F–ÄÐǧ1´eâßí açõ!>è,LˆX'¥­¯öI]ê®~~nsæò½Êñ¯ˆÒ©¢öMÊJ×ÌØ'”i&Ë$r¥R†ËƒÖøëX¡‚™¨$Eâ%¾ÞžsçHS³—fhT/> ˆøGü#þ]—‡hþmQ›˜a÷Kœ–CVguz¼wÃ/º&á‚]ú]ÏlÜc§%7¯ŸÙj„;oÜ&…þÝÀ" 1'™õêÝB;W*ª®ìf¿rÄ…«\³¸§ƒt,Ý…×Ýfúçï=ölsÿdÈ“[&æÍ³ÜR«~óÚ<˳˜õ}ËDæò5¢sOWȇçι1¬_¾ŽÙ:Á-fœ„߯0î@Ué#Çò.„m÷®ø€ ¿p-œ:÷G·’–½n„ÞÙ+Ç'diƒûTÌͦ"¿Ž%ü¶ò”3©JåR¹J¬\ã«`A’”ªØÅ(ÙA> æÍ^¤MÍ]š¢Vš^µéñøGü».ÿ®ŽâÿJ›c¯:¹'.eÃð9Oï¼±Õ'K,¼{¢ÅQéwNîâ1ÀýÖ·-?;3iSÆì“ýGvQ½¿˜Ñ/˜g÷~ìlËÀr"áÑÁ€Žns@Í]wšò»¯rÆÍ™»/ût?Ý£Á¿wóˆUOS¦Y*?tnÎ;6}Xù9C¡óƒa‘Þ «Ä?©;ºEì¦O»³˜J÷*!ühþë´]9½‚>!˜¾Î|{@^d×4Q9á‘6åêÐf·RgŽNOÕ‡HâÔ34› L® äP¶,'”Qr’’(°¹@©ˆ\èçéáÎJÎÈÍÓþ ÁÿˆÄ¿ëòàê¥êê]œ3vºa<Ð?{ïˆãWvµ>ñ¬f6m®|Ŧ“îé]~ W‹§÷wn™· GK¹¹ýþ|p×±kûÏÿŠ[d/ãƒHÉýž%òsé¡CJ{9H%‚'\Øý¸nó§Ï¸­÷Ê.üöfxÀÎd¦iÐ;ï•[õØбfr³¤ç6±©ØÂ¿E†±ôX;©´êØÈMÇŽ8†©ßkf¸OÆã{ô±4,ÂÖâ? lv+ ‚^—¡jxœ{Ú÷›Ñ©ï]Qôˆ(øöKЗ?`B›}ó¿¸ÃWNá”û>ž\;Q*‘P¤WHJ£0*\%§äŒ @@yŸÏww¹>37Ó’ì,âñøw]þ\àL¿Á%å«O7Ô1Z¶ú}m¯‘ÃÆŸ¶g?­Ö »öÎöMÎ=η÷¸ ‹ØÚïjZdDœ?Pu0Û‘„ôkAqFoÇwì¹âÙ—»°)'nwÐAÔM±ÂÎÊàà·ÿíùB^lå­£ã¾\4†öa¼¿ZeÕ›Òé—šŒ¢ßw˜Pi*.ß8ÇÛXò‰Ó´ÊÍÏ{üp!SÏ“0‚p…?“³ìz3-» ៯K!è~ ¾úl‰{åÒ2a\fŸ+¢ ÚñYq>ëöTe¯~¬‹ÚྚÍY&`«fÔV _ˆËdʈü°•„ŒER2‡ä)¨8qð¢‹4©Yùzõ‹'Cü#þÿ®Ë?‚«C00<{`ÒÅÕ9õuÂ{ªÊ›g+>ˆù±MíÉ>ÜûÇŠ.Í&9“ dñDÊ#½ûõ_m“Lé{¤w¤ýá»÷“söœ¬7Dˆƒ¸—‡;ZÈ”x,uˆ¨n³àÆ®æ†å>‹—Tœ1¼²ެÞÒÓúSÜlÙé‘¥RØíf*†·)¿`|Û×õ½'õ.HÝt¸§è÷NLSøkLÖ°Þ•ãA8íÔäeþpè?þÖ/ ®7 “‚!yÐGXÆœ„ä oŸ‚¾›W_š}çûíIù{£GzZ˜Ò­°Ê©9@™*À¥aËB%PKP ›ÂPˆEFøzÍ™«ÉÈÎÓþ ÁÿˆÄ¿ëòàêžòtcû1º½r‡="¸EGìŒåÿ²ÊÎÕÿwô‡z¶Mmp1dñÙ¶ÞG¶¬ÕŒA6âP‘¿ p¿üRóÜë¿­`á“ï÷ž˜"±ÿüè%UécíÜYÚwÛXü¨‡êjÇÝG”Œñõ~תËçÔLužxÏÍìŒlUiš±¼Q:åcѹ‘Ç'І.õÞáðLCp[J[ƒËcƒéW:÷çzïÌž‰Ž?Âû/Àx˜ gm€Kð|žrÈõ˜²Í7çÞ’¿ëóVç"<.SxE\á.%( )W®Pú/‘kB(Š”sHŠ'Tƒƒ,ð˜“2ò2ÿŽ„`ˆÄ?âßuùGpu ˜|/òAðÁÎö¯bÅ9§£ÇEìoÖÓÁ@|Ú°!>#¼y¯þ§„‹û8ºÃ´Ä[í¹++?ü½K¦.4ŠSÌ$¾•™L1JÉÀÒÅ%¾Zy4©&8úHH¬ EÞ^s|•©YyzKB°°ˆÄ?âß•øßÙp,Ñ?_'7k €˜0O¢¤ÐÉ$ K˜¿"¥F^ÌÆkîÖpAb²‹÷.Jw ĉZû’0>Ÿž®‘^Êm÷c¸ÔÊÌà¸Ôr/ ï .à¨))A@„Î|ï'}b:@_€8¤[p¦ ]@”造ïċҫd„¡ì,,]Íï3ÑyÙz°» 2ˆÄ?âßuùGpq(b…ª¥&uñbô*9ш`@³¨Lc’sDI¤“¶ˆãtAËG®ÖIíɦ´ï'!4ê?óþœ¸L#µôˆ¤V #,5“–Z…8_-§µÝÔdÔ|Ú4l@?„Ÿ®h\εÿh’þ#þÿˆ×åÁÕ€0Z˜©¤¥!&`cI §ÿfyÁ^‘ŠV€qø)θ"QÕøÞÜu*;b8‡"xIÏ„,,…”@(µ5#@LX7` ®À(:Àø¸RΨ3al0¾£ôæ£Á Ø7ÀE âdʹo=·¼š¹ð7Z€&ê?âñøw]þþ!R[kAœ’¤—C/Z¯–9XsS¯|¢WN&1/…tÖw¢èTóçÌȨ̈j Œ•d×/°ÕFž£ÒÊ !³í.Ö 8.‘Ôˆ˜Æ`b®ŒÂGñFwÆ@Ü`àÇ*µ²—mv!þÿMâÿÁ?úûïÚÉ7p·ÀØ^%Knìàß"ï½R'à¤:¯þ8‡P[L Àâ.O­¥½@È×8˜W|™ugÚsáF¦«¬HÄÅÖJ 0hÏŒ.ãB®’$$¦@S°Ã< áÀT ÿÍ€±´¥áF¥+eúÑÕ1/j¶!þÿMâÿÀ?úûïÚðÍV6~ìnÀÙžP³\)iª ÂÀHÅ*{³xú bÓ¬µÃBÊlWûà<‰ÂÁíp¾ÜVÙsØT2eûú¶@› @€I¬f®P 2Ãû›B€æH Ñ˜%&G7t%²Ó˜uS/oP6âñßDYÄÿÿþÑß×/¦RYºcùcaêqŽ¢IòÌ-0NO´JélôcQµŒÎó†ÖòOP;ZJŒó¨Ú3ƒ±@²ÜƂ،ø¡Í Jé.扙Ip‡€0¤$Ͱ³@©>ü “€fýGü#þÿ®Ë?‚«a,?SQŽü‹¸‘z-YwÏ/-™˜ï\‘VÿÈ”ÚÆð£×ªL",žl Dˆ BÃìd«¹OmÇ6LL™&!EL"rúµR€B³úJ[À2ÈdùóÅr¥1Ÿ æø Aå·ÉfHB0?Y¶0¹IÐÚ/o)5ÕÔè?âñøw]þ\´V†+õõ… ƒ¡^Y{ðo–çj3œ#\ig¶ à\´B» /ÞÑ7~YÉsæåf;z> ì- ¸Ðœ†›.²Hfû0†Û<ªÀœ”q N$Œ¹Pm²825{Íß &Œ¥´Îí…²¼›¹ÐÄI@kýGü#þÿ®Ë?‚«`œE…:Ga(Ãà?‚ü;Ì÷É„áV¦4Æb–iíîyeR‚.K³£ç@«i8Oàspßuö›.Ú׈ ,Ko™0`¼N)b¹MO›@V€Õv CÉæ›A!ˆ`Hb° iNLÂÚ|.s¡IÀVÿÿˆÄ¿+ñÿØe<ÿ`"xœí]wxU×Ç‚€(½ J{A@š J/ÒC „„HBI6eK¶ÎÜ;;;3ÛÓ½Rb"i¯À *vi‚%Â7³›í»É†÷yÿšû{`öN9w&óÛsž{Î=÷lˆ€`øÌ¬û`O„*/çâàÓ1„hMY“í¾;øihՉʒ¥kk¹GR1¶íÃq-¦ÞN¶¸¿-i]œÉõ¨bÒ~y¹¯®§'w6Ót[UÅ•x/÷ŸÚkíúÓ^„ªZ5ïeßIºìÙsÑœã?†:_’9iéaÇÞ¡öÁßÔ4)ÇãÖÖŸ«ß›Ì~ÌyÜ[þÛÉôŽó™Ã}s¹ã{UÓØí¸“ûòBx­ð ¨nyöý S¶Âúùž™º}#™”[SƒWjÚçhE᱊À}ÁŒ8K\¡'˜™¡f´&%!,Ž(PPT2CS"š‘S*•0<4bÎìTSî²&ƒ®æ•ÊëzQ>øGü#þùË?ß!­þ÷ÆÏ4ñQ™nDZ)º’?®oÝa˜¶6y¬÷ÝœžÂGѾ.H©¼œøË7Òdµó!mýuH+—cRËÁþ u=zÚcóÜ{Gû)_5w,ã~ö½üî¯,ó"51Š>«qìävªwþ¹GN—H;~Ôx›}ÏÜæÜÖŽú%«¯µufÏôþìèØå•}z~´®M÷wG’´Â'¯®©ëÆíÂ{õÞ­ƒim>Xéæ_4i¶cF’©}7N¨òöÁKÕóÏ-í´Ùq¬ò¦ø–Ó^Çh›0¶åÅÿÔˆMT°¼1ù×MÓããFõÕ~ÈÙ LåüÐ'Í!”ìéʺNç/_€š&÷alÿ;ð³Ç`èÙ 5Ñø®Ð´ ËÇç NP›4ŸTì9»iʾD°%$?+‘™C€Eedâ zñæèÒ’–¤ZÄPj\Á¤Å, žªÏ*\–kÔÛLÙ‹[Ä?âñÏ_þøŽŽÿ,;ôú¨{öªF‘rÂ&|Àtƒò#¿[]Ö#ö”—S¢Ñ«þrðª6ùÃTdZ(mr/îõàPPj·ðŒ¡¦rßo>Y?ÿªËÙïòú­çEªcÙÄO¸‘e&F/½:ϵG!»ü—ï0‡š–·íÀí1]v[[—ˇXn“Ñݲšw\¾Ûc÷0[Ú5b?6=úÂ)¿NÓ³®Â£*H5|¥íÿ‚}™30¾\p轜çÕÔþ؈e÷Þ·ÍYE´qózyš,y¯“’ºÉšÔhh½Z-#™@f!A2R­‹\˜hÈ)Za6èlúâñøGüó—ž/ø¿Cš§iïl´î.š9î÷vD¿7{Ôë¤'Žè;ßù«e«\÷ã’Wu†qŸÃ;µ†YÜé3¾¤ibCk1àÔôF#ffÕuOÕÁ/®ùÀÚÞ³AµššÑq¥Óéò'Ó;y ÚY^ÙÞíØ… ÍšXµªQ›—rðÍ—ÛÏ‚ÒN› ü[þ¼ØÚÜ{|Ö K£•iü” ¯ÿóîð£ ØÝãt9ìGv€ðÕ¾ìÛ=Ýjd<† éC¸dò·PJ“CËÖ*Ä9 ÞW¬yý¢-e-/—T®xÔr5™¼‚hC2´{h ™Ï:zˆÇoŒÕR ‘QH½F%…Ì™yÅEFƒí徸@ü#þÿüåï=55sà…öìwIù,09»9rå„(³ßòªÛWƒ¦ŽÜrå“v®ìLö=òޱîÚUSÝE\Ú ~|dÓ Ð­N‰¹Ç÷v,«ÙQ^›Mü«©cRÔ¨çG^ÄDU1±îNMÊ'ÚÌ;>ÉÔL:Æt8Sé8­|ã °µÕ« 5‘NÕHõ«½U6‹y°ÿaÜ:æ»ûÚ_œFf˜o¶„p_Æ,¶y¾wÔVW³¾ÂïuêàR¸´@âËø¹«#O¤=^ù{Ÿ}-zm‹;0äÒPó³KÕdF8ÔjôœŒ. /#IšIáò€T$&%E†…Ó™ÅyF½Í»zq €øGü#þùË?ß´ïçWδ½6¦ÇÁÖ÷ÇF?ëçàߊ¥‡BöÚ<º‹Ó!ÙÐëÅ¡{£æeû#/;ñzeÎM¦¶ˆ¿MðÈçñ@eË»äÇŽLžÈÏ'V¼¾ç·É¶‡:ø xÕ‹ÔMâ>þ‡÷ðý}~èJ¾žÛÜx«Ì~¬zKzÖ¶ó¯V'ŸY[‡÷Œ˜fi¤ù}©|çÓO£Ÿ^™Ü•¯ŠŠcö»8{;„i_M†0îúê=gmÃÙ°ÛwÄÚa[``!˜ö•RÓ᥄ÒCа3C;NÒé±Ò¿5^‘§Rª@’Ö0Òèm¦¢=dHšL“æI25T&$G„ΙŸ¬Í*\žiÐÙ—·ˆÄ?⟿ü#ð Sz^Ëo'S ;u)HêÌ« }GhÛ|º¬ÁÛ¾bz˾AÍži‹ü”ŸÔö‹ßŽ™i߆øµîËÉUïÍt¹¬uXUa§ÔßÎY÷þ”OnvÄ›ÜÃu;+ÝõêSÚH¾àëÉǶOÃ9oEsîä÷ŽÓÂFí@£î kîK.¾oi|zíR!ŒGœI’3p=Ô>œ=º²‚u‡¶áŒ'à h¸ÿ2û’Ï”ÃnWÝûv7\~ZþÕh²Á?FñAm¿=³on~-è^ÄË‘™…QË IÌLò Fih’ $½aÉ–’b(%dhR©ÐfÄ. _¸`®JŸ[Tl4hÿûµ@ˆÄ?⟿ü#ðxÊï7Ì<8¯áùàŒï|­×© +oÝ ª[¥³ì(#'œ¯úS·¿¶µÁn8dþãø¥!xÀ­1uß=õa‹œ§Ï\Œé7wT_ÎílLëYàuárv‡ÇîžM‡È^3 `àÉ™Mv|õS[V—}mp<žó6awÖˆãj¢Œ²˜Ö÷ßoÚáøê¡U!ûo4SÇÿ=:õË4vÛtò@´ ¡ñφ¬Øz ö ¯ÃÈǘ ÃóJ'ÃϘW²sÜçÞ¿¶;‚ŒYO†ìÆHf:A´F›^HF•G­_¢f´T +)$¡8&2,8p!mÊ/Î7êm¡ÏÿbñøGüó–~Cv£ßÛEŸÃfåø;fwƒ²ôîÞÒçëØ¦J’‘=· Áƒòzup¼GÁÙ‘‹Bë,ýa›@zàŒb·ƒ"æöÉo ŸüÀê‚=;¬ó&ØU7¹‰{>’üùÓï°¤õ2ۯŠLM&9Ê„À„WÛØÛñW×¶Ò[›ÇÇX[D»ÅŸ· èIn&d2¿Mb÷ïŠà¶‚®6û5æY`¸ {î >ü ¦VÄlZ"Ý*Œ,:Ô}uìÎ/’?¾Ö ;Õ#æ§ ¶ˆÄ«1¡v®’ªÈÕ†dj&ªŒZ¤ÉQj(*E#2‰H-#ÃR-ŽX07I›U°,Ë ûo×!þÿˆþòÀkÌéþvZ?ø“žStÑÞ2gýBtÒϳwn/»§Ò•_+iûž·Êbµô{ÒüÔì—l«lkAÿ?Ÿœóœ¡œšöLÜ{ꃉWåßæz\¹|Ï-Ã0mÏþ±Ü§¢âôíÆCðë¿„Üâ´ §ß1Ú€'®u­iü°`¨¥1&´«e5´ûÿ¥\o^òè­>BΆ}%ú˜Ý^Ëká­…¬Èüµ)„¯Å¶…ýFÀ!_‘$À¿ílº0D¾M;µ0áy¥õ‘–¹;ÛvÉH%Kƒ ²t3ò*EO£´tyÔD•,-N&iFcÉ¢¥ F’¸8&hÁ\™)³°Ø¬·{1 €øGü#þùË?Ÿ!ýþ½–Ã_ÊÚúÊŒ3û²›¯_·ëE;j‹íÚýfé×O ú®Sô‰z ıøó:©ÞšSû…ʃ»FózÍõ«w~y¾àéæð±îEÍ,x9´gó"'?’\™dÔ™³öKí„™Û§_ºö÷Å)×ú¦Ëb6k"ve0)‹)RcY ¬ÁV$l‰Ð1T†*£@¬$äZmJdÌ¢…sC(c.|ñ‚`ˆÄ?⟿ü#ð  ÍéÈò¸v†ÂÒjbüÒ.JSÝbÞ‘Ò÷µ‚Îß6~òK·ÜÚ \öÝíã3Jfá}Ϭ5ýxÖQ›Gz/ªìß3]|åüþkÏtÞNOËký‘ûÁñ‡w¾i :Ž^5¨áÛ?Útÿœã<¦èVhwŽžXS^œ:ÃÚ¢;³”ícO¼¿ùöÊÉý.p€éùßìö³ß~„póZö¶¹W[BØ´M»5Žèßñju ßÓ²ÂËeU†QÂwŸú°´ìÍUïL] RÖ`é†iä@Z’„†$c*Š¢èˆÖ¨H5P'/^² t^c.(Ê1è^l-âñø·‚ü#ð’ ]T Ûðë ìnÊĶÆe¥WÌõZäé^ÉBêùÂíÕWðqÓÉIÿŒÎÆS~T”m ¨åÊÿ|ÞõɱÃv·ÿkÅKÕ^‹—%Ó%ƒ=€ñ›CíWãw»Êé¿1ð¨ã‚ êŽ·1¿¢$¸¦IßXø¡¥ «Xci$ŽJ ï¡;;o«¥ˆ¸LÆU2Ù܇m“LJA˜w© „Íî0 k#œøï¸9Š]p‘ R2è?¸ðªÞi?¬úy§s@£`[ 1àÑ(‡1¹ó¤ÿÍš&y}NMðeú/ë½MY0âµKG/¤üÒó}òÍÿd_JΗ½!œøÆ ‹Nw‚°ÝÑ0~þQ¸„.„¶ä«ÖG­$¢‹ËFe¦ŸKžP1oï;×ï*nÜ(xPmŒ[ÒÌS*rH­b­aÖĨµ%a9€¢i€Ë¢dr­*>%24(8VcÊc§úCüCÄ?âŸüû±°?P™¾t•žôè“§Ësô¢–0 P¦D”½Ê;ú‘'ëÌôz P,.ÍT»¸Dš£©3úˆ‹5Z• ¢ÜëýR©ó¶Š—1Žß"@%gÑåòód@¥vÚÇ€½{€j—+/“šh8°ˆàPíØr/ŽÛ ¶ÿg÷Ù\A‚• óµ¾Íì¥Hlõ±ÿ²ûÝ»Bü#þÿ|åïà´+Ðzè8€¸R’˜mæ¾ÛuÈÇ+Vê|Ûö“éCý!§ÁÒmzWMe­Bž¶Î KÉ¢ Å+½Ý(0¯]àrÊÙ\öÏÄ€«±tº`j{?´™*XZìk’ËqÅ)¶å* €Eûk ÄB<“©Wµà¿ðÐÄ?âñÏ_þø€Kc²²)W âÿi²<UÛàß&/ -Êc|\Ǫ •Y[7Ï+Zá,0žY«Oa½L!Êb¯bïV˜O» ÀµÞºrÒUÙ!¦j]½#ÒÅ€¤½e5WábZ§!j<ë‡ÅP‡ g0¹À`¤ê•kõÂÀ‹þ#þÿˆþòÀw°ú¶`‹ÉI+,ƒÿ¥9&¦ŽÁ¿]>-¤$Ók¼EŠÚݸxʧ„nÈuÈãò„b_öÄ ¸·ÖèXz°Çýzí(7]P•‘šÇއôíàÀ-h±@.22dG€[>ê0@Íý³:¬HÆÒïAX_°€zZ¯úøGü#þùË?Ï "U°Jo‹m±ƒY:;ø×¨ýRNB‘]ftŸÆ³¨*̦ët"€"&¾ÜT#°TÊäÙ—‡ ž®·i8P6\d€Œð®ÿ*œöv*d@æêÄpgkˆ»8n@K¨d2IºîæÔÝj\ T»Ö(E’<¦^Ó€žÀà]ÿÿˆÄ?ùGà;%Œå;Ë þrÌ~þmòÒ%êîÓˆ¬ú§a¹u«?äó³áv5§F*(ôPQ/·T >ûüqê"çûã2Òk'SÑî³mÃI¥˜0PvÝÆœ3€pÜá8§ÙLÆŽõqe¤µ;aM²Žý] @ÍÐZµâN6— a¦ÇƒÕþlz¸¾ôñøGüó—¾à’ÅEY4§ ²ôŒ|½ÿƒ›¼xÞÚ<•c‡µiÊ\Æõçä…A+ŠYy L6êþ³|©sâ0{ÿˆeÙŽi@\ªñ¡ÿ ϼ LE˜B¨ÓÕLº§ § ¡æ¦EŒuÑšýSüƒîÀf¬™À8k¢€˜,Ùlø_OúÖÄ?âñÏ_þø —™¥˜ükÕþi­«|jè§¼NýeùŒªl“OŽØœMâI®?j€‹Õ®iÃ@•Rf²ÝÏ ½÷‚É<×ÛàJ ÉE=E¶?Ü5ÈÕ°¥9"€KÀ¥L‰M '_`ËâŒNFb¡Þï×e±·ü Ö¦ÿˆÄ?⟿ü#ð(Åù2IžªçàßÖùbA˜«÷ÃøLå6ÀgŸ_ Z¡³Þ—0Þõ—z>Pª¹Lb ”*L4÷·áËpN‚Ž)@K°O•a•ÇIÀ6`Û¸ç¥@ÀUéò\úŦýsjÕÄ?âñÏ_þø ÀêÆ\—WkÉZ{áÆåŒuô« uõÎrZ;®*ògø©y)³—Åkó,Ž˜Xb.£=å0Œ³%ÜÔ§˜ÔkÔ¬*:g¹;@ˆYœV^&åä¡S°ÿ€»Vž¦1Sÿ»iÀÚí?âñøç-ÿ¼WÌ*]’G„®Ë®ß4”K'˜(h}.Å~™•ÂÔâúª?g@(ü2¸Té-I`’ˆ•\¹Ldð®ÿî €-ÀTV¥“‹ Z’.@>· åS¥éu$Q·°iM Q£Ç˜,1ËXwí3ç?ÈÞªÛÔÿEü#þÿ¼åÏà*QIâ³³R•VGIÏÚ;R "JͤR”´\Wï^€*•Ô "·ÔYþàéZï%ÂX¿#z½Ä…&ï}x.†Ü IÚ–˜LbbÔ¸soÀ5h±€“' ¸/b_A†  ~†Ó –ü/Ä¿õ4âñÏCþø îk'Kr•,Y I”.¯÷ÐÝ\›¶KXY¿’–ljË([(þÄPGÍUbžEBÜ4 ¼P#1ûÐ%î¹0¨ c-®’ªŒj¨q2/. ÁN)@Ž Ã¬cFR]‡€j{вÈQ W¦«²ÿ7%A}®ÿBü#þÿÖ6ùGà5Ä”ìà?Sk-‚pi´9ϯu»Þ»ÃSCàºüzE±¬‚Ê$ƒ‰›}“æ®­µ‰r|šöù乞Ӄ֓*•§n s̺Y¦ ÁÕ ñ@Ç ç`QÀ9VˆhÚšùì” äd ÚÅX3Q@\–ª5ú±Úé°·jµ>ôñøGüÛwxÇ?Ÿaü‹ ´=í—›ÆóQÒÓŸþTâˆü%Î%=ýÄÅÂËמ+)º>Ï·<bh¬e„ 0qP‰Yã-‹`r/? †+œ \žnöYÔkÐî p€“7è9yçr`+àd,石nTÒÄÜúaý²Þë¿"þÿˆÞòÀkpƒ17øwIûŠÔ¨/%=ýéO%Y´Öˆ'E–ûQÆÓERžk[  KÊ̾ä&0{ýyûª¥*é ¯˜Tç¹Ä(H—k¹_•™œJ‚º8NÓž@K20—L•a))j5.‹ tùMÐ'€›TJ„yõûeP?‚€Þôñÿˆ^ðÿÿ0KÖðpPxœí]w|Eû§¨Xé/]zo1”„TÒ{¹äzÙÙÝÛÝ+¹”K#¤B€B芴ˆ¾ €‚€/EDiR,4AÊûÛ«¹²wI|qûý@nvfž¹ÙýÞ<7Ï3Ï̵‚8ØL}P6,“Þt¸Ó¹^*ÛEûKyo$ÕÒovî¹üóÔ³sÇ·žáóÝÙW±fK ¸º»kìË¥W]ͨ‚w[±Víìõ‚*æ7mù«{Í˯‹¯Š)v,ŠŸ½»ˆpÌ _Üé«Gv·Ñ:ê§I ;´[ý7^Ëbú¯?a)”Œ°ÝœÝ oncÞ ãNî8 Â!èå%ÉkX¹ ›y†ée¯A8ôÃ!–|ý.„ïnß e#¿‡â°:8ï£Ö…©èž¹ÈŽ´°’oß ÝÔ«Ueh]âÂú>d­ˆU{ï—Ñ‹‡4IPM¨ŽZA©I*ÏåÓbœË’◈蜂:­ÚrƒR7ÏÈtŸÿpüsü{$ÿ<{_-l?²ûÎçîvDz„Ç(êEñâ5埸õdFE¯.ù¨í…›)‰¾ÞmÒšƒ£‡¦üõËz‰äÞ,u‡\zÔ1–vÓØä[Y=° îÁ¤}Ñã¯oMÍqØú4ìž}Î{Á½¯ç·95lèãåôûópk±LŸeNF ]qÒ¤#cGÉ3&nlºÌÜrþv«7´ç´oÎ?nèé”ÃÞõöœÄ<ŽÒCïAØgõ¸þþ%˜7¼ ß9²hêæ¼;ÝÄ[r¦•Æî_¥]vàzö¢Ê3Çx{b¤‰nŽòs #TÉôr,^0Š&SÉL•¨(1šÎ‹ Y´y…E:Ê¢wÝkŽ38þ9þís<‚ž tüue÷%÷ο}g¸–¥|ØQœ€øðc-h²íÜ“d-R•gtÞ›ÿ~íñËÞ[›%9°û½ðësöÚf-®zˆ—¿p“cUÙçû£Vµq×XïÐ ðI«}‘ß¿q«³ ‚ô9½d›“À¢Y£ís¶LÈ™»GulAäèmË™Kið€Vv¼|u€9Éÿ5h)µêÔöÓÆD_…þ[æ%3}tÀë? à]œ’É\=iŸ¦°Ó¾–ïgþ Èû Þ^w þüí1_!ŸT¾Æ­€2êÄ¢eU·ü–MÙ5¯TµÙã \±KÓÏþ\®’ùP$£T8G¬‰- ¥2”šËhiRZh´@¼R“_¬ÏÒX 77 €ãß Ž–rŽÿç›´­­x7;Ï;÷"Öa¯ 7ÝF´4áL|«‚æ6ùzÄäˆMªÇ»-sóÓ=ôÈîc¸›ª›!IÒí˜xÀ¡_þqbåßäçFžÐÙ]kONú¡"nøÑÎûZ¿±Ï¦èz‡nè'»7$ê*»iÿ·wž;qh¼â½Â_g3øèÏÀFàåk­_·t5þiäDSjÓ·9wŒ õè/Œ¥ñeïéÄÄø——0;…Ìß–õ„°bïþ œ€C"îÁIIg!šZ}6ÄeŸI¥âjþ΢¾»>{aÓÀØ]îýõ}y¬vþ…nNm.ÈX†3: ¢6 ÇWÅᙦä—ð帜¢ù ±‘K—,9Å9ZµÒr'.Ç#8þYÁñÿóÏÁ“Ž8—öÒ¬=%‘›ÚÍÊvYKöÝ5Ý~YxÙiÅŒï(6Í¿ôñµFcÙU¢#ÓÈãChéüýÖ®–*x±ÞèõgM¢ZÆ[%ÕÏ8 §ñˆL‚¢–§¢TLuN¸Š12)R®¤¤ˆ(1:<Ì?jr ‹²´*‹ÂbÓÿ¶àøgÇÿóÊ?FÊš =¸ßwÔÆÿí6F'rƒpíŽWŸôjF›ïBõÈéf·¼–YßýÐDbÞßîE“¶öî¼®K ¿¾Óñò~ÓŸ5æLWøë·©|võ )9f=seÍ@¥e0j`G—œ%: _oŸ3ÒØÐ•PRýðÒ×5÷/tÙ>ô·èF vCîìRs:úfÌBSjpÀ+bcÂÏkúûÆÛZ,ké%ÆÌŠÆ–3ÏçQ “w›èaÕ¶ÁN ¹ѶÏ0øîyÕã¯öÁgt¹Ñey~yg_^¿}u«S<âO/oæ:,­pæn ©Ä•$)i ÄB7EU¥!*R!¤p-#d”4%.zÙÿBW”Ÿ¥±NN€ãßÿ.Àñÿ\òÏÁ“ þfÉýoŸ¬¹ß#XßTåÝžþtËe§!G ÙZ3uíœ;ó òÇݘP}U}·ÂlF¥oí¶áì]wSÝÞï«-×É÷ÞT»ÁmWb vNÎ7§Á‘œS×°½µ/˜Ôœøo¢‹ÌYbÚÂ]Û•öY7ÊöƼD"´Ãûz'/hØW'­…ékA–tP›¤É¦”wï'%ÆDÍå·–^ïîíûI›v_Œ £àýQÁLÞÏ…¯@¸zóPçÌ»áoÁ^ÇÉ[b6øc{gÖêg&žŒÚ½`ϬƒAS“¼©®CÇÅéæïú©«W‰“ÂpH$U+#U8F‘dš2³X(¦¦ÊLŠ^â—©ÌÖ/ÏѪ-jÏ^pü;‚ãß%8þŸ;þ9x4KnÝ~±@|fÚ÷xÓÕòÆaߣ’Z¶¡FŒ>vaèŸçseåÎE°Ñ•]O繞²{? ù±WOWÅ5Yòª.p¹ù³Üqf»Yð²Û¾ô;T7¢¾O7NézÞè±¥µ¥}œ-ž~>§â¿µÏR½Ô!ÆXqL]åË>‚aéÂÆ;ÇßîùÔœ^ЧîGóæ)~Ç]&»ãÂî­Æ J!¡åõ Œ å>o\»‹ óbò~XÛÂ5†Cè;ú1„­¶…ŒGÔRâõ³Åè#¾±U ‡Únžõý¶ðì­;2-êÔÑ yñ”=€ž¨ÓjiV³B€SJ2•ʤ(B†àDfT|TX€Në ŠtZË^ Žg Ž—àøÎøçà™Pg¸Š÷f_í#{ã—1CÓŠš'(ѵ:8òZáÆS8é×·*/ô¬_ËVˆ®ïspSù¿Ä.d‘_ê><_£rQÌȯN¸{ëýßLî¬g?ùôi¾Ëº\èR¼w²Íuð‚Éý»léÔÅ 5) ;YÚ]·m£}Væƒa¿´3õïú”kít6üçY£pø¿³ïZÒþ·„Þæfú­üÒ”J øÂøúUÛèôQà虾oûm9@ŽcòŽîd†ýºµ£ãâ lËëÿuV GiTM/‡a«az^èÙ^tveÄþ„W†öYúċ%©%é*ñ%7ê ÚW¡$¨ÈõÉVMQ¤H´JBLžîC¨s ²4ÖÇ*åø‡ÿÿË¿ÛgÆá¹Çä½ a¬îJDzo¾+~òSóÂz ì6qîÒä;®Êg¾ÔeçÍå¿lqQž´hÜëÛΖŸf-|kWµOþì+¬efÄù|+“ö"™i¿t߉ïËI÷çŠè·í|Ç.§³¨oëàE©$ü~@Vâ,+™á¸,X§ôCÌÉLävÁÌê?‚v4êˆE©û¬jdÞ‹Ò ¦ÔEݶëÏ3NX0Üë@×ú»# ’ ‰qÄQ@+U+RpUø†P-ÓJƒP#ÆhRF R££Ã‚yDV^qN–ÚÒϱÿÿÿË?7ðlí¿@µpëÈÿt‘}ñFúd²´i ´‰òö¬Ï«d-ôêSº÷»·Útkp-ß{Pnÿ̤ü<çÁøÚÒ‚!M(£®Sf&Ʀç•zm›Iå¾îŒ¢­OÙg)ôc?‘¡R.Ez<ä,¢™óÇ0‡õÇ·^-Xf¹hã›Ý1À·i¹©Õ ‹-§€Ì|wÛUó4ûnÆÄHc¢gŠÔ´äÿoCØORé—Q>rf->ß‘¹Úõãu×—‡pÕ׌NîtM }È Ð»A„ÎÙã¯$?™­¾Ò%'c¿¦ï¾;ç¹ôþùɧoôÎã§zDR)TŠ‚i#•Œ ÂÈØª¨õKµJ%™JòIŠIUtJL|ô’`\©Ë/βvˆãŸãŸãßcùç¾ÿ=ò¶õ?eŒToÖ°¦7ÿ7eÓv‹ßåù·zàO:-št9_¡ õ>î¶1ïèÂòšqNS÷ÏS@Ñü1ûØDì{8ýXñPÙÕ?l<ྦྷ¿'íξ蘛zá‚:éÏnýõìÂ[Î2^çúõ{Ó¡™…¯Õ5^õÌBò#ÖÞÜÒ×üà~ÿtBoKá¬ßè¹–†&ÿ`ÚÆÝsÖ$Ã+š× †×Íï< ܹ÷pÊUæb냣d"„+{@Øý‹j²FèòáŒ:=R]%L¬,öÊÙo¶ÿzŸcµé*,ý¥ºú9ÂÛK+ðtÚ›øQaTf¶Ê*SËð0Z(Šäa¡€”t:Á_Ó9ùæÁÿÿÿË?÷ýïÙˆ=¶F]¯‰ç'—ù•¹Ý?ëÂéß!5—»„;æû û ¬?òsòˆÿZõIMìûÜHxôË^#ö5ã¤p鼸²›½ñº •ûP$Eé­Ýÿíœ?½ÃKOµñÁ³¨0”Ÿ{¥»C^ø)Q M·d ó»îøCØáic¦¤üco«?sÜ«ª±¦TààÃæ£ÉWÿùµñ)¿V|7Ùðºüa«†)ƒÊow18׿Áè°úæY\õ…°ÿêO!6ø{( Ù?î×eE4ñí`ò ÿ¤êõ#Kcw×a±&þ0¿Ôðñk²Ù7V'ªÄ"iŠ UáµpÙæ¥k £RÉLZU¤U$§†……¤cÚœ¢Ü,5ÍÜÇ?Ç?Ç¿ÇòÏ}ÿ{6|O§L¯ƒ Jß_Ÿ¶ôw=ÌXðÔ+u÷–ƒöóü%ä¾§w.n|Ø´ü²ßu—~Þe“¼ûÿY=hcu³Þßïáß»§^áã¾–tÖí¶ål¿®úëÛ¦c‹í³û§6Q:(þˆOëg¶m¯Ýy³Ý ®³4F9‘ïY‰ãÞÞe9¦,çX^SÊ[ø¹ñU<ýÉð*Ù±¬òך¶‘WþÐ@XõÑ:7åN‡ð•E E'_†k»€¡ûâ|©L(,Z°û2.°¢×{ ãöx5L?2fÌ Þ|ï ÿ½í\lõJœÆÁ§#Ö˵ي$ÉTR $U") y)±‘KB‘¥/ÒiÕÊ9þ9þ9þ=–îûß³±áË_¾ÙyÄò²SÿÉô߈ËÛ>ßêuyœÍRY˜öÂø"g;5ë·¾Z §,àŸÙë;ñèmö+1Í}2bÎåi—Ç9n2¶ÿ·-Cz¬c-’þß\•4ö7§’¯kvŒ^’'Ô§Û^'woå%ŽÑ‡’×Ó g¦µÞð,ÐR4êÏ’™æäªýüÁÆDÚ€ßåÆÄÙo8¬Ãߊ_ÔtÚ ‡¥KÕnÑ΂pÐÀ¡Έ>‡Eý»çŸ„|RŬƒqù´D5êoëª×¾ Ü1ä×í!ëüÉ77žßõðkR¾nΈ’X„”’Ò¢±!¤”O4Á‚bT 4‚¦ðbÃB–„C*;¿ K[ÏñÏñÏñï±ü7?Ü“Ãóˆ-O¾ öê]úVÀª~ÿЀè;myí•Qm,‡#«Ç»·à»ÑC𱓨ˆqÑ7*¥O®š¯d;‚þJxßý~ô?s:?dÝ©1íÝ|˜ËF”¹(\úöÑ_:þ1Ô;äG!èÎd‡¼ûÛ÷±‹~´óðK¼°í3j‹;ð•M¼­–Ä€Ž%#L)0 þª)2èâŠÍgŒ |‘ñWLÄ‹©-ã¤ËýR̘ó~Ûè9ÎkLjú͸ …oþ%ƒ/À<ïj賞ʸþ!v§-=â»&øë ‚·2¦ÜçF«û­¦ÿOe{ïB4^(E¨( ÇIuzqTEBm$¥4FÓ˜\CHâÌĨeÁ¡©P]˜÷Ç?Ç?Ç¿Çòrà` BÌË,Ñ’´›¾ I@V¨±æÿ~·¥A…0¢\GB —­k‰<@2äúÆ}=¨8@¶YîS€,¹Èí i©hÊùý±ŠpÊ `ßs8Ô¸ù©6Jâ– Äš´¤Šá†¿ È"q  †l =aä IÜ”²þÇ0­ÿ éD傸•-§›+Ï(œè2[}P¾I)«<*–äâîÇ¿8 GÅ Ù9¤ã¡bÚyüCDî8Ô®ÐÖƒ¢˜Íá_ˆõ¢Q0)œ0*ˆHù*€€ì À0ü7(€þ™t€I NÍÊjb£³Ãm[SìÀiüsü›ÁñÏñïã üsðd˜&ÿ%ZÊaòo)Wd׿°Œ7M"˜¢ló ŠôµúfÊEž«Ä²B×ä³ÌÖÑ Ê…e`©!“f1cK!ŒªÈr¸7TJ°Œ)TF:øÇ™ ‹Æ7cg@X/P€á–n™S(0ª€Ê9†á2d7­ jøg6Œf€B”\ mÙó·$X€ÃøçøoÌåøgiŒãÿ¹æŸƒGÃ0ù0“53ê\|Æ€,%aÖíTÛ¾>"ŠÓÛ̹4!fcVsä*Š/sr×i\œ³3°ªÀØ4ƒh*¤P‹‰†eÀ­a_2*¢Ù‚‡™ÓU(­ND€Ê„¸ÚV½!€Íh³hU„Ñâ’dèÅ\*ˆÛ¸ ÿ춬«|û¨'8;åÿÿÿËK¤9<ðZ—E0Ÿj1/©B×üÉ¿Ì ]ºAçbâmˆRA Õî†%'E°ï&¨(ª²É£Â€<%ܰ É´“ïÒ’0á«=„ÊiÅj‰’MÕ©Ó )ÈriFÕøÔl÷Ùx­›€¬š1oÿ‘Éø¹4á¨ìs ²ñ…0½ )'¬Ã-[`ú˜ãŸãŸãßcùç¾ÿ=âdé R.0LþÉ–LþM@'Z¥a§ÌðO“.g9XÓ¨$”¿™EÈ’UMÄ™ä¥ÑüuL’RÜD8,@35Î+„ÌÌPè)œu03¼P'•"VÀä6£G‚Ú…5z—-ŠEP¡Âp4š;m÷ÙGœˆò<úpJ8þ9þ9þ=–îûß³P~P!–X•E->ØÛ$/ *.vÞ¦cX^-×49„ G‚®t”ˆ ¥ÔíÚb£¼Ð¯´P®hJY”§cã3jJ…blcˆeаØv¾ »BA«³° ²óZ–€%Ê2) »PÖ“@XÏ5¾‹4UÃzg®…%aêÇ?Ç?Ç¿§òÏ}ÿ{6PTš 5ÕÚ–OþÍ0,ã­Ís<* •¦óKšuP%@Ò—TçÛÉÌ ½+¿¢³>fC¶<3X…,6…Kya ¬®©ã?4Ge- Az1›§ÒùPÀØÇÜbˆTjùµ4›cÀm=€ÎK€6 (ÄÂں؅€¸%Èa+rafêŸí’süsüsü{,ÿ-Y:àðü!1V—¯!1Ihö‘žÎ@…Ø„ë0ów^r…VÙìÙ%*ö[¬x Ž(k>BE.×;{żäûmÝö=áÙï¢ËñQÁú!Ý–»„lñÚ-Itƒ$æ!'ò˜".&Û;A.U)ð„(’#W*„¥8†âã³ÌC,MLvFøC„?ÂßQñßQ×ì"ú Éû{çWñTáëuYkFþÑùdC;šH‚ýYªÁÛ! «,¸›]Ô²SQþù±’#É)ãÖCÓ<Ðm8/?Î^ÎiåéÛÞ£fžœ{®ç!+f.˜Ÿúw¢µ.ÊVæ ž‘ÛêØù5SMÝjÿÜßÌÇáTrcºÔ¸âIñú}{¾CçÅ›[ý¤ÀÄ1Û ·¾~±ÁY_×åòE]‰ßýZ*}ï6޾žt rùá¼sñ‘xhÊñ¡îÀ)-À©ì› ËO6£i¹×aßW1³ŽÁ¨-¥øÞ¥Ìâ´©7"\6/øáÛW‡V-Ûy}—ûÑëý…é“ö@Õt¹4^*S$+[R@Êä)ÆÎf åb‚D²<¼|p²áþáï øŸ²c‚}¸Ä~zg—î·äDïv˨¬JohWûÛmÉ îqó¸Â¨kºOº²žü—χ?Þ_u^žÿÍ“óU}îÙÍWrudúþ×nÙ{ÄKû)µ6úvá¹Ce­‹1·½†œêºG};¾é£únÿµß| î¹DÇWÆŸLù·’Ò ûÞ|z½ó¹ÏVÕØ ]:” Ö¯ýGWš±O{íÅ=X¢½ã[’ áòÜxµºÿwM¶‡p—h„؉ÏJáSØ–²OFƒNƒáÈ#Ê8ñù/YßíQžšZ¸ãÅÏï›v]É'¤q¡ÓÏ®TÞKÉ~ÈÐ(b—¯,ÁäJ¨\ŒK‰ µD€Lž P°ãE )‘$ãrA~^ž‘‡þáOÂßñ?kÏ #ú`éSÍ¢X°ëÌ”Óý]µßmgJxe‡#G¶GT>¤þgÛ¾øúwP•ØleùsÆd×s^}í6pIú×z® Jâ£Ø üöjûÞx,a­MØýÑ£àl¿ò)_ò(©®½áÒóœyã‹>0©¸“óŽîYr×Ã9»èVèNÆøþ†[_µ¯h¤÷ÆvNý]7²cº„i ©ïÝ»Ð×g76Ó:¸å—E³8‘î’‰A¸›·ª9úô2ŽjÓý†ºnJ‚ãg¾Ý6¨ú¬L ;Er„9gµï‰´,÷}.Û2â¸o‡¨Žëûÿ(÷Ô„™¤‚Pé³!h?¡ˆÒxGAJ H)Šá„úú{ÜAøC„¿Žþއÿ»æчJÀĕ啯ÿTÓëH÷†ö‘Þçú I»Öo?º—Ô~NÆ'ºmt—ú°›'ô™ü]$Ó–ýÓüz(øx7ËVW…ùüϪbké·yç&j2Þoú¾JóKâŽêÁ3kcÞøœë’i\á÷~æG•t Z/ìñú0ßidõ¬vxõãX}ñTÜ`\WÊ?yw³¶ð²øàZúZ:.¾üõ3ôµw¯ÿ]÷Æ.¡j~:ó½ûB n^½DepÖ)Æ\¸ú»UµÆ{ºi{œ©»fžxjøEˆð7ÂßÑð÷­{‚9µzùÕ­Ü{?ok ;ëzÛùçGÌ™àd5Õ¦ëýf—ôÍiiÝMõÔlqûšØð©ÃÃÖ]¬ØiÞê@»ƒMYít:{ÜìItA(;“;5;‹9B¯*<¯»»ç™5Ï^oúzWã:ëù‹[­jÜ®dPDç\ýO:ï6XwBºë«¯d§½ÕˆaÚ«L§OœÙ¾`Á´ð‡(7ªæhi[ˆÝn§?BÞÔŸ`@ªNÛYçjV-Òø6‰u&frÙÒ*]Ö¯ØÀ™ÇßöYhèÄékVA"8‚ËUé,©Âoƒwq ‚ŒJBÁ"e¹R$2ÃÍ^áðGø;.þˆœ@Ô­ÏsOtÌIh3g²XÒa•|íı²z%ÿÔŸÈêß«¯Ó®Ý  ÷¥–ãž×8éózh_U¾™ý¡þü™k‰Õ>ÃW/™ ó_Oõh¿äòUí§¡a.ÂoÍ[]ÇššMÍû´Rÿøî«ÎnŸÚâÉž©ú`c‡6ç[üŽ£NœÖ•–8ßÕåÍOY­½úô¡/¥¼Gž„EžìòÛ-¸ŸáIÕSŒ„ðæÍCp±G%¤xoîˆy[ç©»sþ± ¢þ&nåîXíò#¦œT+eX¾4°È«ÜO%&Ï"å˜Lþ_mÓðGø#üDŽNϦÆM¾÷^XP¨ÃỂ+wAئըÍ#J­çcä™—ëâf_ÀîÏÛþ~¾¿ÐŽ$¢ÂÊSWÖM0¯½ë«¹ðpSuEQ’öÚz/Ò3ŸÅ ÙsVSÞ›üµ<¿Ë©±‡Í[—ΨjmºMêHÄ,ãíNÂA—ÚÏKº—Fç 5m}õ3ƒ0mÛ’`]iy“Njmacå Åôµ‡úc­R‰zÛFÜ®ŽnrxZ°?Us¶Õ:S}ô\Ö Âv;wÁe¹“ÖÁ%%rf›&ø ñ¼ãì©…^·DÉ’YL’áŸ0(bÈÉï¥ ÓdûI$å T\Lxå2I)S¡ › MjŸ„?Âáï¸ø#rpÂÇ6»Å4²î¦zª§w êsDÖü¨ö£×rï&NT?'âÌ¯Ë ^;eÑ[‡Â?¯,ûUÑ«Îq Vå$´·<Å ëÇèñZÿY2õmckgƒPÔÞ=)åqÅÒBΈ‹Å¿mZýqJ[µykn—-{Mw7/º·¬‹±¹óöÂÍœƒ×®£ý‚Ïþ½7Ä0Œ.^÷KuÅÜsÛoj íø%gèëög ­Åå3鄳¸Ÿ~{4èÆ_kƒ¨š U?BøúÊÙ¼5„]'„ƒ£ï}U´ú4ï®Zã–^<%ñKùÓ€M‡˜·:»ÐáÍn¬bþƒÄÅo5;"B÷Éäó0AÊT*…HXäYÊ&A(ìLÎ;kóŠðGø#üDŽN±ýN¶Ùïò2;›‹òpepUáo£/*F•ºø WGJ^ÍÊ‹ÕäílÂŒ÷íÀwN¶Y‚ž=S9¶¶³Â»þ=mºj£p`°kÿeµŸ ¢¥äæ«ÍÞ´Cã63|¾¸ÛÛW´×¢ù¯B3ͶÛ;ÈX#´Ü)žÔìV_õƒ9¿KñG½.©¿ÑtÁÝ£úâ(Ÿ?tžÅÄö¿jÕì”°­´Á%vOÍ£Fì¾t5ã³/ÇߦÇ¥ò<„w§tÉË\8à< ÇÝ …Ž@îúà²eâ¾áëò'fDœ<8wß”ŠwŸ~ò®ê"'2aÑÿ>z™ËQø0¥š-$3Èä„_¹\)” ‚ 9™¬æV§áðGø;.þˆ&?òc·ÉN8cO[ñ†í›]Kš ~TSçvuS¯²×…{ì~`§Nó®=îÞÓà,ó¾ðà~e™Í#ª›Œ»õƒ‹•³Â†þû®ïêþÏ©"v¹ò\~ˆõnž·ú«Y¸XĪyqèy«dóæEt¿kR3÷†ßWÆÀšâŒFcߌŸ‘Ûù^ù›–w:^jÐg;ÚêJ!/èý“ó¹ºÁ.Þ9BK»ã¦uñÝ'õÉ8é;‘R,7P6A›Ìk¾X]'®\æk 3÷T¦_|ïé#Ž+*–¬9p¸©Û–~¯ ™ ’ÄØµs.DzþôÏ’ñ³Ô[¡Šå®$Êœ(¨ô.ö/óJ±ä)ij}Nþ„¿ãÈÑél~ÏûÞu *Ùóço]…×þMmd²,®ònUÖbi7;òf-½r~aG#7Ý뙲ïnȺX=·Â/®% þúÄÊMPþ”1¼Ï™ÁÅP$eÄ_p¶ÒŒ¢ÑÝÖtåXÔ†¾8ëtÿ²¶A2ó;7FO3­)Ÿ‹3ÐÍ'í¢ÓÏ.w2|Zÿ"yöþï†;‹_ªô6ÍEÓm Æû\Ж–æ¬Õƒ³ûÐç‚M,mç#mºzðâ¥ðnyõ²œ'þ;~t = £6ù—¼Ÿ=,„þù‘'<Ä›Qà{,Gã}bôéñ[|SÁôË¿.»õîõ¶"r6®$ä¤L&#U<5?R©’Æ…’a[þþ„¿ãâÈÁ {÷zõùoþyc!fÍŽ÷ë:FáRº·›y¼¯ûRçwÙWízØ‘ã+/w+Ýmò¬¯‡ÍʨØpÉ wgŸÿæOZkµKÁ• c^¤T Àÿþ"ÆÆ±fþ³É¡_Ö«ta/oE6UÅ7«—¶õnlšÜ4ãbhãa:7ú3”ÜRŽ-Ø/|¿«þFh⥞µë„É maúwíî!Óf!?º@-õaûã9˲ƒúv$wÃÇ+þpÈ¢F6» …ƒ®Á‚N'`h:æm…aÝÿÃo÷T„{\¾K¹Àu÷tíq`ûH•ÝÃÜcò“\·Iå*#iÍ"\®ô, ,ò%…ikësBÂáðw\ü9:E\¹µöîk« vq+lEö7ÿŒ´|šZ¤”S _œ»<+¬ÿ‘z8gq~¦ž3¤@­€öwpö’œ<¿8K·,•&AÎ’ü <@&·zãx”Z­š¶¸ˆ4×hÃ2Ó HµÁÄUËOé¢uñ2ûå_¡‰“ ÓS÷|+˜©Ö_ç)^Tz¼Ütи°`ÂÅ Ó±á˜LN½4&âÇ)©;”XW߯TfQÄôJàºZÐü|–FEudª´¥Ú€^èµÀxáYqõÁO˃ð‡ˆðwPüÑßÇ&‘Bªÿ•P±¶rgN@Èܨ–A Šõ*N2_KÛÃNñK0‚L©ÇRÂVÐ+Š/¬(ÁÊøˆ•bCþr’R~ªÒ„ˆ¤`ZtpL NPÈ)±®±°jÀ¨¨_øW+Ep±@¤”ÙPz% ÿgbÐ݉ټԸú4Å*AøC„¿îÂßñðGÿ›€Ñ‚~0‘­¬·àÖðó¼U«”bÖ²âD¢!½à¼²Í*œÍXg?;e.ðu®=jüäŠÚÇDuÕ„P)¥Ý}±òD¨À$¤…„`´NkÐSII°T¥F€©P_4Ƚnå«]‚8†±e „¶™Vìµ2¯S” jÿë­ú_P=!SšBÔKHþá¯ÿ€ðw8üÑßÇ&`¶”å,Y—Z¯0’io{éJrùúä‰?-±ny)ë~¼Úž­T$Ëêø—lCþE˜Š^pCLodº`B¥EJËäf³¦—x@­á¹*9<€Õb_S2Äq ×]€©Ž“ÉÍ€>h¬´‘Âêõ?íÔz1AxJ|½ðCøC„Í› ü ÿCèƒ$:ŒW–Øà0 \7qBa|Ãmqh ²¤>ü@’W³à3k?mÈ¿X¯‹ÅŒÇLSU‡q‘¢/€aµ:~¡[?FÀ]P¤|]ž}t¤c§ÖÔ-ÿ«ã€††Áq#³âìwâZz7þ„¿£âÈÁ ƒUPß Sf1Ûc/rSƒÃˆç{A¹Ú~€ó¢³V¼ÔøÃÙùã|±Ú†üc\uµ‹9" i0(ÄÀ2©Ø"ÔäüJDjEµ1òš„M“€!¦R²,æ 4J™±ÐÅþ(Á§«jÏ2K”¢²×¯g©(þ„¿ÃâÈщA¿Ä,²KxZv< Rþ¢Ì¦¶.㨫û Ã€„Z·„˜ÈR”,2€Œ ]/WÉezÙ2ÚT³ ¨ºTí ¬Q”ÑÁ"£Ï†¨ÉÒ¯ÿõ>@ˆ ˜Šd;Àµ¹Jþ„¿ÃâÈщãÖ'WÏ$l¯•)JÄbÝצ5$ŒpŽ{‰Z†1= 2ìã∤ó}»Ôø‹’MøqH°!ÿ8'Á(i‡&Ç˵‚' -‰@ÀxÓÖ‰(L åºQ5@£ Ã. Ý•Òôó™Iô^0ì6¿V@™i"4öJŒôx…=óWk„?Âáï¸ø#rtâhï êú…)ñçød¥ª´é«âp¿„iç‘JR¿êâ°€Ò${ø h¥ÒÒ‹)Žñ-1iˆs¥ñ6VÄ8Wi¬.¨WáqR”rJ¦„rK9"¹ÙÐŒ ú£D…ñ„LgC˜(C±Z’€ WÚ¨~¾‘ЯþÍ6ëLƒ€´‰ÂÉTYžÆfAVfáðGø;.þˆœ†óë± ‡Z5‹¹þ)é*Cf‹À—µ±¾y@c­ÑÅîpÁÑf["«çÀ¹œŒZVºÔøÃÅ95ãÇ8 [[cq¾Â4Îp1£hÌre©@=—b§Ð:M=€5  :ÈRÐNH.žD餺@íA@: ÈÄ5Ê:çÏ>„?ÂßqñGäèDI–GN†åÒÚZs(á&¦«ŒÂhœÅ9¹vókY€ $)E/Í4檺ø­¨}cÀy)i„Á Ç&måÄÔüIƪâ \XË2Ú"ÈÜ õ&áJ: hlÔ„kr€jvÉtö‚V‰„z¾BÛ¼ZTµW³D 3/ ÎQ%ÕåDµ~áðGø;.þˆë^¤±+Œ¤ÿภ“(ãY˜j¿ŽAÃÌ­Y³S²½l]šm~ ɰf%PÖ„[I’B'S±ª8‘ÄÂ< Ãp1B\Ë¡š@͆enàô©Þ¸ˆG‡­… ªÀ\­t¥£S( "­U@ã, ZŽ£HÂËŠ·íDµuáðGø;.þˆ€(Òw£}35 ¡„BdšŸŸ D¡Alì»5ëçûå˜ANIw°m~œžkõk?ÅDäÓG‚Œ™`+£ˆ…µ¤Ña8–8´”‹ ˆKäæ%÷˜H¯ 5AÍ—‚Ôl2ʪVÕ_ ¢ý$•ð¸I*ú‹Tl)“ãÀLsØ–'˜‘mhþ„¿ãâÈÁ ~\©ª+ŒG‹˜4Û\ü!í„r‡%vJ DQ¢,³ã;qþBi¹u~j]/¶ñ½^´G1fR’Å$Úr% ·V5C‡É‘ †¡šgYR9½H"€*…ÌÔh¬ÙM”âb¶8•~¾‘Ð ¿q°•ãÀhOe´,Ù2‚YMu‹ðGø#üDŽNtnµ­oÖ„ZO/ ω¯í?éoöÌ˱çÛ<©'-)³È9¶ÍÄ ¶í €s24$©±)ÿ»öleêÕØŒìx‹oÅ0ó!™ÔZ^J+ \Â#I9Ú šo®Q2´ß j¢Lö饿–ãÀ葉‰V¨uâ‚ðGø#ü?XüÿºAû-Éxœí]w\ÇÛ·Ån¬XP±‹%FÔŸ1jì¢DQAÅP•ÞÛõÛ¹~pÀ ÒTD ¬KìÄØc½F%¾»{ýnï8ýïõæ«ÜÌÎ̳»·ß{žÏ<óÌÌÖƒáäu`«ÿŶÛÍ6Àox_]òøu¯‡˜®zÚ¤ 5ÇâÖÕqÜýÐÇÉõ«L*œ'Hþ9Èî^D'´êœGäðå–OÜL¹îÍ>¬}½ì›.^=N²’¶ªßÃ'¥ sFG&ê—®Ó¸›À ÝäSßœ×;>®*%Òy®…·Úø¤âD_MÍ9¯ϪrÀÿ[u–¡ÎÒFdаÿŽL}Â6'Éý^ 6åÇ™âyÚBûÌÂAâ?àœÿ½ƒ û-øøÌ^èsÒ}7Ü?•·#Â+ÿàƒóÞåÇ½àŠŸ·zlJM y\vëÛ›¦ …®¢½B1Kçâ /YîµÑ[^ßò³#øGü#þm—[ÇúF®{ùœ£Iôµø“x··.ìË{™R3ò«,s‹­¢µZŒ~3úL†¢uMÕ¡õ¡¯ß.‰I–P¶vàðë–ïâQyBßç¾o¡Ç’š£´5­ß9üø"‰ý›Ï³¯„ºÒV¹·¯5l˜íTf`"fß¾þ€LA·2»¬ S~·ÏNU×ôë¿M­wã½.TåV<¨Í%ÓÓ3N“i‡ª-¤e¸ø}4ô¿ßô;·k7ßEúu‡°bÍ 'yߥÞ? è^ÃsòäX‡š¼x,­÷mÎ..À›Í§î›xô»?o, 辸Ctß½¥øNƒžW{ÒË×Èþ]°*Û¸|ñãf·¯œ¦3†ˆŽÚ1¬ã„[oÌßáƒKÏ;ÒÖĽ>}¥óŒü•‚öjKñ NOG6w8ê» zÇã§ænª¤rœcžWæŽc¶QÇ#ûmz¡¶•Ë)W›‚Ù‹TÞC½Œf”t®åñ›Fx£bÏ/ÛƒÝb9Børáÿˆ/Þó?e܃ƒÞ/‚ÃWoZ=q\T£b 1Q«æ¡e›Ž´tÛîr¬jÞFÏŠÙ­ÞQ·ÏL_*ý‰/_Y ¹Hº¸,iWç³#øGü#þm—[GæY·Ç¿ÿkRÚ¥ÍÉi±/Å’| ïÊèàê·Ì6x_ýºÑøGiÉfª£y­š5ïû·QþÃXa‡ãBz}ôá¶ úùèÑQÓé,‰¨ˆ'#ÍœgêÙ>»ÄG«S£ì¼º×š ù—¾L7l˜Òûˆy>b†¦Eh@wåSöÉ(ûß©ÃÈßæàêš³œpg*zýRBe–¿¢LÂæ1ÔÅöøæcô…œ©o"ÆCèd7Âí»ZCøu{_8qóR8þ­Ë÷Û¡ßÀ×pï$ùŸ}Œ3þ®Åž‡×ðV¬ŒJR„o;×5%u÷D—•®«Wd>R©P¦ÀÄÛ¾îgGñøGüÛ.ÿ¶ûÕöƒ]¨*4,_ÿúc_ÏØÎ{éôbZ|‹Ï«ŸÞeÿ2úÚˆ>Â-×>0/?XÜdÆÓ{rõË:ÝÚßð¡‡7ß੟·ôðš?—ž£opþй-è«bªž(ÏÃh—&/ä,¼P¦*õ«zý1Ú°á¨ìIú3ì¥ÄQs0õÍbùöëoV¬"¤ëG®PWLv¼»…ÊÌwtô¢2ýãª6‘iFu­òXo⳦å)»smZµÜ#„WG$öî]!ì¹ôŽÞç‰á”]V©Ïê„ð"‰GÖ±Ö¥•eÒ…Žg'ùþëCÖ&0*—p{údÏ—ÍÀ¥r¡ˆ…b™7+ž ˆÄ?âßvùG°u°Ã†$ÆÄé‡á@ç᥹‚I:Ô1 ‡DÆ‹˜æ×&úÑvÁW§Œ|3ütwsD ÉvË–׆ˆ´ 3æ.<`Å­_Ž­6b’OYû3¥´Ó|ú84°„^vTêÚ2"ýiëÇÎ Eщת/Ócñ×F_EÐᆠ/ʧu*ðÜÍçeÃ?mœ¥ es· jKÄjºBíÕ*ާ2»œ¥b¥|%ƒLŠEó‰Ïs wW­Ý¶£Û–3«n^ ý?ôÀQI{¡xp dù¯‡3¶Ì󓬇óæ^†_e݆»?þý·F}ui5 ÎlùûN‘[V;n^TyÌ#U–Á”¦„ouc·|ß4éÌI Ÿ.‚rL(njÅÃÓ= Ä?âño³ü#Ø:õJhët¡·fm@½ú®-ž‰Ž\o¥|½Oï»0ÖslpØ•«==­3’çßý~vnø ÕQN­0%®‰¹ž>ØûÆÎÙJô»ûLqû+'÷[™˜ë{½¾RÒ ç_;J÷㔹·ôŠÞ]µŒÐÑø‘õd6~k0Iºùôkå:ËÈ,ïr¾À)Ú)qXý=°[ÓLuù‚{·/«rûŽï§2RÕr©y÷¦’IZÉtâóbÞ̵›6W$Hüá0½‡Š†Ï!«ËS¸hÎY( Yçn†bÝîJ¹ççÍ/êÚ«;¼fäŸW‡GÂßžÜcïü4Ö·²P*"éŸV<<= þÿˆÛåÁÖñáqYP¢Ð?“Ìí2½rì³Iõò*¬—o{0vgðf?…Aaÿc×ç6(‘š€3@ã+÷FN?ìGN%æG±‹sìaÍUx&_IFÓðuEJ¡g_ïãF xâ¡CÞ–Ò WØñë¢Îu:±gÔ‡©R8°ô»»FcPzμ‹úk‚V-ÔímÜîb-6bÊ%‡3y9Óî……¨Ë³ÊÓ¨rsÇ?T­’úß1ÊD©ŽÔ¬déîqÄçeÈ%Mj¢ükJ›£ØÞ™¸ÖÃBئb7t<”q¼~\8ꙸh~ÖJ×´³öYá{²n½wÝé|ø‘Ã#º<Ùæ®Ëª‡|Ý]*Lr vÖ<=} þÿˆÛåÁÆ&:¿úXﶃŽrJ3Û¯ƒè÷}Ÿt‚…ÎÇ6×+ado_¿É ¶NÞÙñ¿}λ ¡ï£Ù?GÆn´Fæíä§ý©4+þÖÈÑ›­eL$‚`@û±f»ZÖ]{ô½´vKëï=7Üw‹ŸÑÆx·’ð7í ÿ1£ÊßësÛLýú!ß÷¨¡zz7¯R+âb»zª)D“œs®‘©çÜߨ™ÕñwȩĵI ÅãCîÜÐw n–¡aÅQŸ]ß ‡îZ§ï–•e,IY‘’šô°oLyæ˜Uþû ^Úvzz~di¨$×'üll:oæ’“¸Xò—5OψÄ?âßvùG°uÌ<|¢×õ'·ðY©K½{×µý V-ǽ؛UG/ÚžsÚùKË2úøéà__YýnðãÛÌ_¬iÞ»)ÖýÞ·oüàzƒözaÀµÕ÷͹Og(ÿÛ©wœPèðÍ–¿KìÚ¼¬1jêû`°ÁÐ&¾>&PoÂôÖF½Eн_ë3÷LšPÕ¬•ºüD¬XUå*×èVî× dÚGØr6™†Õ#G¯µ&CnDtó‚‘ÒžBØYtÂ×ÝáLl Œ_gü5ÿÕÍbè·BºV®Ló]˜ã1å—ÕCj_·u¸W5_¹tÓAûãMg7wVLé ?ˆÄ?âßvùG°u\² ÜX=þ÷}Ûf½´fþ v]áÕÍÿ?R5¾àüU©Âšy¼Z\˜™™}¦UÿðÖ´ÆÚw^=+DïFù¡s{7ëY­-ù‚¤qænv©°­áZß…÷óÒŸl¸à`Ô´{XUÀ%ý‚îN«Òt‡r»ù„΃žûܺÍ?ôSøu¹]¯jKòd“Êðĵ%Ó[»gQ©zÄçõÖÂT’/vžÔ'îødêþ¯ž$è±çaf¿Ã0x© ÎÜ#®”UNNºn§Œ=™P2÷~Ïe\)®ŒÜà±ßU<ãôëš‚ò;Çú×ýðhøGü#þm—„/ýš—:1KñÚ5ž¶°b÷-Z´»+»p=q„ÓfK/ØõøÓÄÁ¿ Ëÿ;ô¶þ¥FàîM«vþÖ (4¿zäËÎùÓ4ë–[GwlvÃŒ) Þ58ßh“QÐӷڣᄧîɸ×N1œÛä–ù®—î(2×Ù©yG5‘«–Gßå3@½+ºßí­êèÉô²çT¦ÿ¯dZÐ@Fm ºhÑÕ‡7Zˆ{â"9G¡œ3t œ×µ„]ÊvÀÚmáÖ˜âR ݦ>T$…—†D®—»eÝ)ÿÇ{ë‘ÆæÏÛý1zs€"-0ßeWã+™—ö þU@üÿ_ÿûë~x_0F;öü±y…7Áܦ£; ;ù5©»5=X®ÝÝ}Š÷¢^ÓËÓ+Å]­ŠãéCÖñ>§MÞú]» Á ´ ã•Qáw•å7ÞTŽOQ Ï9§¥ˆÓÍÜhÜúÕ=c÷„÷ÛF~ÁüM6w\p"ÂÀ׃_£÷^°ÂFNŽ”Í ‹vjÚû¼gΰ?( ‚5 ®¿TÕijÇKjz5\óì& ôtÝNîÜÉ­&"¢¡_É;o†ëûÊbrètãôïûÂn‰íŠƒAÛ+Ç({žKªý6a›lZžßYnûK?î™ü»ý“>·OÏGLßöñk Ä?âÿÓøÿBøŸkÅÓCø‚Ñå‡×Û>YhÁŽÆ=œMÿ†¹ÁjP×›=Íbjcñð7ŽGþÞ:¶ÙË#Ÿ*Ì »9åà´µåo·ÔÙ6º]~÷†&û„S¥í=ø··5#0d[…×xs›˜o|ó‘Ii„KgfÅϾcSõK]j~6ÜÄüå¥Àz‡LûPµÉtn|{õÃæ×^C w¸¢YŒëo¨2AÓT/ m½‚zùßMA›Û„Ë ŒËn|·ËˆŠv[ÅÿäD˜ä1/ lx¦öþ¹!~*‚”qakaD†€/~<(dÓ¦›OÜ·w®¿.2•“µÎó~)_e,¸ÁK“-_XÛP‘—jÞEÁÙ™ó„±É®3ƉM–ëÙ8œ'26<ÆŽ 4Ç€°L™LãèFµý~+@kŸ’(h €Ê Ê…ú^€ªÿ¯ùÐ{8+,=ÙtˆÓZýGü#þÿ¶Ë?‚­ð¢¼JRó¤úG§Ô¡þ”|¸ï¥¹Î:À™ÞyifBpjùcyœ¸RnÍOp¢2a\`Âìõ9ü$3ús…„Ý!Ãp J™6 0Ìx@ð¡€< ä¹ ‰P Öm­Ðj]IÐ7¤wÁŒK—Š„ä­:7@ûGôý¦A@­|fÄrk½þ#þÿˆÛåÁÖs‚¢×'(:©þQ‹‹S, ­é³½cÊô-7‚•+¯Ã‡`ûGÈ<–µÌ‚O¡'ʉÉn'KNïb.Gaf)4àa”kp>“Ÿ"Ñ âa<ã@&€f êòY—‹) b0¨ šL T\ÀKà)ȉnDR²Að“ôñøGüÛ.ÿ¶€Å.X›¡ý‘¿çh¿µJ©U:¨’YHF€*È¢Ÿ_d"¯»>áä'Yezp6ƒZA0†~ ÍB%â‹™›ÄY2íDŒ›"§ÂxãÏ‚fìèO Ì’KIyƒ &[§ ƒ­éI"j¨ª­€ÑZ íH n&°Þ áÌ,ýAÐOÔÄ?âño»ü#Ø:7ÂwcŠf­ 'ÚwMšõêOɇ,)1î´~Ü‚ÉVLä%åÃýJU]uÂÏ33k×8‹¦’¼¸ˆ<ÓÕ°‹K1}6ÔŸÍL•’ƒx8Wl 5vp\ß ÇÆá&’a@Ý" Úë‚j ] ¤5€ÏLH—‰ Ð7Æk ƒ€£€€ÏˆÖýdýGü#þÿ¶Ë?‚½nÎZ²ÛM¨ŒÏêtÙ§¨?$ûâsù[ &ÛÀ TdÖ¹ŽW+ïË)¢®Ec–¦ éÉ0¹›7Ï0¾i€'ÈÍÝàóô–œÏÀ©A4>n"aÙ Í¡§|‹©˜¦Jg t«€TНIUŽ95à¼L)j·±`èÆ »‡+5aÀO×Ä?âño»ü#Ø:]™—Ÿ-ƒ8'Ö» ÝÌ„š:äõÃxð¢ךÝ_ÄÜõ€œ–bž€ëZœš¢4š±l~0Ù^Þ,€/Nž(à<‰ñ”!@ ×à@Dè(ÎgI¤DF÷3˜T· !“$P·˜fÁ, íD “Q@Œ–š¬„ýýGü#þÿ¶Ë?‚­ƒèy{)ñX¯UKeVÚ™ÈGþ¬ÆÃ>Ùæ¶þ0ýtË{M¢™E;Fíñ¨¿ÀŒö+ÅÙÐìþ$8[b¸°àìø™ˆ'4ñ>L’Cv8—•H|am•nmN³ X“ê ¹!7*°Iæ €qÐÐ O<8'‰dîóôñøGüÛ.ÿ¶À Î ^‘a¼/¶ÕòÜ€`u‘‹Ï7¿õ‡ùÐÅpf¶uƒ†ìBhP\œÁjX €‰‹#ß>‹…&3€LÓ@!¤¶åò¡.€H3H·#¨‰ Ί3˜i±ZïµÊ¯] dy7ÒåbÄfÉ>“<ˆøGü#þm™„/à3ç…@¢ÿÙ¿ œé·’ÝwríÏz¥uq<½,ï¸ÕYÖ‰Àbä&½{B«CÒR5[z^¼…ÍÉXrÓÃãÆ%&o{^— Ý„ 2dR‘z?½Á˜ñKÁÔ©zhPm€ãDKÓĪá>ƒ™@_ ¢»âûg$!þÿŸÄÿºù‡†`˜j~KN €¢¼,¾´®Óð#¼‹ÓA캷þ ÆAÙl/«î`Q ÓH!€|Fp®BÕ'L„ùo‚sDt[ŸŒÁH“ -€‰€cBýÝž ä›A9r©Z^7H; X›1cÆ Ë&\húJÊhâ€fv!WC»#þÿf¾µy þ)ù/€ÿÿhÉÔ –xœí]w\ÇÛ7(Æ &±kìÆØ"ILì{¡ ‚€Ò9ªpývg¸G¯R¤IGA ±‚Q4± ùÅ bb{Ãöîîõ»½;ÈonžÜîÎÌ3;»ß{žÏçw®¸'ÆH[¯C/¸§é–³Ç÷kõ(üöN5„ûáÿ0êá0Øõ“‹4åñ[î Ne€kCÕFßç‡?Â~WoÄt«Î³S]ú$-ŸõVvŠ÷,ëv5×çh­ @R!\!+èv}»ìlvÌ>êØp÷ç²+›ídË;ï„™òïµÜùí/OÛGv=™&†[Îv‡°§Õ$8½Ào–¾¹sot ØÏ½8Mü W ëâÚ•¥‹¯'§;¶l˜¹Ó552p«sdßw„?ÂßdñçysˆþÛÄÛlîôdôÉ’ˆð¸ÝZe.ìuû±DC|þÅã@½&îÏ}§õÝÖaÎGsCÜ|Åñ¥M–ÙûO—¿ãÔù#ÊýèjÖ8º|ô|ô€4¼Mä[ðZ؇­-hnһ˟’î»oÿäw^Uøý‰°8VÑéì(ÕeŠùœ1Bù9 Ò¥¿qdx'¢ä‚óìTYqåž ¨0ì—ê$wt yðu:Hþz‘MTÆžürêÜzOIkäü–Î{áàeŸ@8¤!Ú‰ËáòXp²ÍzÆÙl<58×ç§‚‚Y ~ZP7ýâ¸f=Š™lN„?Âáo²ø[|oˆþûäê5±ï®úägífXÿœc‡WÝu¾úšû¯otkåî¿ùïî¾æDéåa?Ü€?ÿÖAFÐóíï.éã…Ðݳïõ{bÛ 5¶’>|m>}]ÿˆú-Ý’³gÆfg}¸è´¾˜¦ü´Ã›»·Ç7õ>u·HQöþÔÇÜ+­^[ýÚ¥çP¾™òb@‰dút÷jß~‡ œÞçl«¬TxÒ|'uðÙ™í€ÛS*ÒÎïñ*âð÷K˜Gb mñ+ECoô vú§ªdÝë/…3bBÞ÷§`ð†|¸È¦9-\)½`ÉÞÇ]•Ýgƪe;¬OìuËK .p9÷UùC„?ÂáoÂø#2uê…Íú¶Ì¢¨ }­½{ìxUµåþðºdyÉðÕw¼ÜKÒÿÅ­1Ç ;‡Mºà?ÿVsY²ñæjZ¹µË¤•_“§½ëú?©Û\ª¿ñ¤æõ/B†ëCö¢º´ pÈ…ì„ÿéë òКJKšòá?Í4yð”—“–ª˜õOٯѪ秧®ìW]®‹´[ªRW3býºÚê\fKQFh[¤¹Ü’úÇ#f,u2vYžL'xÁlòð=öÑWdýS@â•ÀáÁð¹Ã¾ª¾m_Õä៵סˢ«ðíæ[pkÿÃеÚ÷þ£|è“9Òþm!{“¿-t­­Àüw-­Ÿ³Çi“€Õ"üþSÆ‘‰X?ÛuÖþQëÛÆóÜÐ?~€9`´¨É»àäKç'Å+„úÙôÐôWLxôeêñáVv„sjQþRëý2©nöþ{—·úKõ5þhå¯G»wÖÛWðÝ?£w,ôëÄÕ×bÖþV+šrp¾2¿ NË\4Ç»æûC½eaÀNC»BM ¸õjŠÚ¥È|Õhå»r¹äò¸å#'³»¾é2ûm¼Øëõ?{¨““EýdÝ®¬ˆ$ÃÒ§~Jî=ÄKˆCÒªÍΟÞè·0­Þé¢x®-ÜÛø >iŽö È?Únƒ_àÌ"¹Í3]·Ö‡¯Y½ðè¬3¯Œ»I)E„?Âáoºø#2ubÛ¾|:6f’цŒI/¢{%±o³ÈU/¬l.ª YÑÑÛ^¨ª º¾^š€ûž´ï”Љ˜ŠoÍÝ_‘¸Ä\¹ô÷¤î]Ùz€ëÖúeÝ5ЛՀî}Ô¹77UO=1òQ4\á“Óukú<å‚•MàÒzªpTE‘¦à>ºë™1j×6#T¡Æín¯›7/ŸY|µÐܹªq÷Xyñ0Ï—2¹wíÅF|w9ˆ<˜íZAæµ¶`åÄ!mÌ âõ/ЧÚ\šP¹ ¾¹´ ÎùÎÂþÑ7áøÝE¿=Ý ×Œè"ÍuÎN¶ÛxhbJP{f¥]ͯ óƒRCsÞÉn†ðGø#üMD¦N6½,¿´¸{Áp«Ày£Þï›wÌçïYÚÞ6·ÎÎóSËÍŽuè¦/†Ÿ±jä¦Gĩ绛·Çv«m''ߣÓåÅ—Tò¾¬ïGÉ~;ßDÛúä²݆Ñ%ð* <\yk]±õDG1}ý>é0‡Ó4åÞ×°Ò°ØÀl¸6³jçR-¾è=@rU£Ù\ç!óÕr„0§§Ê«3ãOÍvšñé{ŸíØ5Ëì¨Ü {wø¬ì¬ERw’ãø¾”‰ÔtÖŸ|Ìûwù•Ä!«3y‘ÿbŒ]´ù°¹œ¨³ÏAøìÁ&8º‰¿n[‰Í9™E¾»‹O}Ï«X“wü[.»ë×ó‹mÎ߯Âáð7]ü™:µürÛ­Çg‹i–É()ÄÆnVX£ƒÓ ¿u+Í ‰·¹º°k‰üfØu‹>u lbÝ=mãÙwSÛ™Jìt÷iù«ÜnêE´Çíô]–GÓ:Ó­sqÁÃ=:Îý¸ØÕµëpóõŸ+=€À¬[Šøâr`çVÅÜÉÏåŠjÈ´¯ø²³˜÷ÉcØØÕPƒi5‡‡Í\†¼fÒ–(wì<ýæŒGß™Mu{áƧp^F´ÍK„sÜnæ­JñÆs`XüÌÓœ#aËòxÈîÖ¼°vî)µ &Âáð7]ü™81cÿØß–ÐWo/ÔC쿨ӡ®©ô egï ÍvyÕîûòPË‹TùÁ$ NŸ9·MPïÿwÝ´s :µxÝvO‹4lXNØÐFù9ïhï6ŸXÓ;õ¼VÖ}­œÔ/™Þªµ7¾q–—ˆCpÜôwé ãªnËÝ,=Üdgã( ø2–„“+ÈõFO®³È ¨Šä?ð÷µÞwÅŒ¬¤—“*‡@86«ži¸Öœ‡¼ L¸¼4ž³ÏzãF‡ôß&º>^n»uô{q½4‰ðGø#üMD¦Nó¶žZ2êöÌ4ULáíÆiƒ<^»ßù¦VN«²Ç´ò—ÐM¡µ‰?¹›xþ§ç5\‰6YMS–Ö.­0Â\~ë 3JWLáäFùñ£Îk–þ1üh™c¸KÐ²Ü ŸÌ¨O±Þ3Og;²îs_Õ•ŽoÅ"æ¥kÑEMÞçÝ­& zo~â5f3Íìï¿Q»öì>LehÆ'T&ŽÝÈw],-NçSÅìKçe몱ÞeÖõү©$)wÛ¤£öé•pÒÛU2Žø¬«}Åßl[ö¦5Êåþ—.±¿ =G?ƒØÈðç· óÕÅùžØÑ¹Ø¡µ^Å[¦mò>–Z=aÖÓ üþÓÅ‘©ÓÉ/†÷øle«N•Üßâð/ŽœîsÏàf[W_›ÞôªÙøZ¢áïü3¦¿ž ÕÛ§aRÍŒðO,Æ^ñ]ÕÎmk‹wo2ÕŠ@Æï—?6Ø$émsøÐî0l|Õw¬¯÷½¡Uûrç¨}´{Œ8îÜzYmó”glŠÞ |>KÔl÷Ô½ »ú£Nœ²Se°®~ýó—ÔPGÔŽèž>àŠ±¸«¬‹‰ë©“M…S>»Yì#d‹g¿…’ʧ:‰ ä]Ìé oW|Â`y‡”Âħ¯ ½µï0pŸ;óÄ$øºœâ‘ ÏÚ¯-®‹žM“°ðGø#üMD&Nø5÷»sÊK4å’•aS¶x§°áù”îÅŸ çgø§N¥ÉÒ °’Çï÷~–«SóòĤåÞ“vb–¼®f&–gÑÖqëŸ $>x Ò Ø’sõM;h¬ â EŽeijÙe·¹þþh¦¿Ð¯qmþ|«€$¯”å»Ô’–p³Õ]Bï±çZä^×hîôÃ?êÉÅ‹6´(¯÷«,SY¼ËÞ.,îr¥¯ó€ó²D¾lé›"™ù`7e eÝ Ì=Nv÷âbð âpŒ?ølb‚p¶yv<£qvÈ(8С„Ÿôt…ßžÀo¯ü8±:ˆ7 oVÂëÔÐìx†ðGø#üMD¦Nþ¥Õ–—º PÏ®e—„w;Vâè¹Ü~(­hPxyÖR‡P«Ç]½|Bºx¤ßxZþìÅiÓçé_›Â[;|Á‚ŠUúFâRtÑúË}uS×ü/¦¶2Œ%_¿(~`O)žU‰Sj–Ø¥¾71 ñm QÓÇs>˜¡^ÀÊo»ó¬þ´YÃv±ÏoSßÄîýÈÁ*à#˜bƒÑ€uCD#Ê¿Û7¨Â){•ËJ++û˸{‚säΰíÈqR¿ü5ègâÐàMÎåŸÙ|C ÕòöÆœëSÇÅ Z»%ÀÉ•ÅÐY°®8¼Áa?ô¿8/!{ufÑ‚$³ªFOÚ7ðGø#üMD¦Nㆰ®f4—)®9»$~N‰Q;2˜3ô,Õ¤ï.-*«ÛÕ’­¿…{¯¯Îi!NÒÃ/»rO×6‘Ãß‹> ÑIóQQ¯¡Kš«í.—]±‹c¡Û¾CF]­ÚÝE¶?í¼Sø7¢‰j©Ðöö=±§ããú,M¨×,r-J½à}ûÓM>ÇW3Ë4¶ÛøõQµÅF_m[«L0ÚÀ©SïÒp°`œ¬p^Ž,1ëÄÙ?)]v¥‰Š;¾j`ùBÖkˆÏÆ-&>÷Zµ4äYŽÉ›,lM2ƒvî 0~Lܰ!.öý%0Z­Þg•éKÿ.þ„¿éâÈÔ)­"cîÁ>™² [Þ¡ŒÌùï3†¦Ú“"mó+\ÔçŽTßZ"?ìéÞ–ÉÑû³#Á£ŽL=K?Åo^–zvb[m¼ÆŸj«( ]1ËsÏcŠË¶uÞ[…×Ñÿìr¹[Ÿ?T›†|>ÿxs-ãðŸe×h•MÙ*­nz²ZŠrχÛߪÿÌÉ,Ÿpüoå•Ë6e€ñÜ%Ë9UÛÂÍO9²×7òXæ¹ÄŸ/S'‰Þ |°G̨۾þ™úù±›3¼ˆÏ­ŽÄgÃÙ ÛÝÕAkmœÑñ#)š¶ À¹A’DBý<,:R¯üclZ%0¾ G‹Õ+1L¤iµP¨¡"”—€èF‰) ‚•Ÿ)5D²k¹+bؼP1¡¸T eÿJ@ >%ûò =€ðGø#üMÿ=sCô!€…Ù§èúÒ0~¸»tS¬X&tÛàP°±üšáÌ5ÒüŒóÀ^SC~ëÛ1~À÷O•êiAH oZ¬¦$Jo';JLW‰óÄ"Œ#©4Ž1\¤® 1 T]âØQ‘?ŠAMÈOä–€†I7Æ JŒCJ3…€JéBu ¡þÛ÷þ4á¯"„?Âÿÿ9þˆL?È¥"¾½SpRü=„9qbå7ðn[ÿÅžò$o–¸w˜à‚²ek|ü€ï“¡W¸ä33¢…l­×ŒÜZãðA$¡A8¬øH‘R–0XËÐë$[ƒœÇ‰‘ÉɼRÈ~íP$ œÐ)eTàr@NýÓò@þÉu€¦ê áðGø›,þˆLœàz‡Å´Ë H|Û˜žX^œD½5Îu ú±}üZ½“÷’d ä¬fíˆíð„©òy61~fûžO¦þÉ=©…BùI˜PÿŸO«Î#à6« ê8&T×ê@ÒÅ'Ä\\*¡¼wŠvJ[Àˆ „èO.H‹„ … ÔøÇUq@¨*ô€L"üþ“Å‘©ÀY†DDÙ˜^¬Âx‰¦°œi“‘Û~íÞ8~ül©0‚äO-è?àx¤Ç«âh8Ë95#Jß×p}³ô÷düœ ï’½6ÀX1´•8ODÈ:€8?\-’ǘ é$ÁÂG‰„@T)¥)€Éêèx!Q1‘BÕì_+ Há”')¥¿áðGø›*þˆLºº$…6È¥ÞŠŸ’xÝ|]€…8§ã×f„:–'RL v*Jk7?¡0ÜŠ£ÕFAŽ¿4Y?àúe‰BŒ¹¶0V¬O p¶„¶bêI¥äœ% Òš)@êúÇ…„àã<¶4RÔB€ [@¡– >qN`|<1~êZ7 X+¨¸·Ê Aø#üþ&‹?"S'À p«ŒúFâÏò (MÐ&Ãò|=*:²àlOiºT.Å€çãÙn~B]°25§ô€èVGËØF3Œ€€Á”¤Iõ˜€ #i½ƒ8W"’;QNœ, ¨kàš)@8®å$$xÜ ŒP)…-Ð.A`œ%"T™Bh¤Ë<* óª+%„?Âáo²ø#2q€³^Pm ŒF|Åü% ‘z„g;rwèO¢Ñéò‚5wp¶5þcL»ø e“¬%«Äø}°lºñãìt£¦ ±$Ò?p£i÷"!3€äú âˆ!À€¡u; ˆ0줜ˆFˆu€b°a ç‡á‰¡Lh¥  ìC}Œ„?ÂßdñGdêðpÛ¼ }‘20–¿_± ‘ñ‡ÙmÚÔÞ0À˜kÓÓÔ]‰$Vv»ÂlçBÝ}GÈÕDYiºãÇYaF]‹ß…scã$4„è™>(Ë’ŸCŒ%GDèÚk€´=€"ê© "ŒR¾_e䯽 bÜà˜8q„b!°2ªo¢îÔÒR„?ÂßdñGdê!NeÚky!þ ߤ(C.: r.Im×ZríoI¬fÛvòÂê—G»£— ÔQw-ÎdÝb„pr°€°1F¤+8GD¯e@ŠNÆ #Þ® •¤áTš$X<Á/«RKV*Y‰rC0 @Lýì TÂÓR:Y@Š  ŠðGø#üMD¦N€ëç±&ŒF~µ>IR¡á/ àzùÐñë6ÄÂì‹R"µ{\O_£ü€ˆëÙs„Ð* -Ó€pNŠQ‚³`ŒZÞÌJ‘êš<Œ~3sEò^/V1m@+ˆÎ)'"ÆåÇÈ·¥YdDZ•ÅNŽ¢Š4iÀTPÍ y„?Âáo²ø#2q"}kÒ<©–ŒN€WARÍÜX‹pÖ*éV½¿ü¡º Ç—“K·­f;øÇ3Eߎ!Äø½Å™QnÅp~’qùç(µAn©)LÐÎp&Œ=ûœcÜHÝ= Îg ¥í à xU[a@¦H*ÛT•¬T § >@nJºA/Ú€r#@÷yþ„¿éâÈÔ‰ Ãh†ÑÄØžùÉRãâOyçìs3 .¸%§ð¡N¥Iô‹j~ýaHªÓ¡Rÿ~c:å©m Jô‡'µH—•(Ÿ„cœÀ„X±FÿgIéCˆ€µ‘!Æcr“µmí M <H5$ÆEER÷ÿW Ü x)¹©¹Æ† t;‚Ó¿ „?Âáo²ø#2u"Ãpêa4r—é@¼”v‰?ÅÏp-78å&×þˆ³týl þ€µøj0Mˆ cª2‹a|a¡OÂØa¥Ek<,Π¿#ÀxQZ¾>B‚¹¡IÊ0žœ´R€4=€W8&ÀÙäv4«€Ô€ú†`j €¨ÁYÁɱĸÕ7UÛ\Ôó.þ„¿ÉâÈÔ p½½w(¼s¤ø¯ËIn§øSün~~°Ë–ýI¹€ë —ðü" ï5B&…åF+æó!bà ›©V‚ Õþ'äoœñ4RŸ§gi’F¢5.`á±b÷¥mèó’]’ûy¨0 êWÁ:¢ 䇳SˆñÓeÉ‚€TPÿÛ@ø#üþÿuüÿÝ`=°ëxœí]w\Gû·b!SÔĨ¨±FM,¨±`W,±+* **R®ßîÌ5î轉Q"Š-ÑĆÆ[|Uì%èÏnŒåÅ‚õ7»×öîö þùî|?p³3;ÏÌì~ïy>Sž™«10Ø ËÈÌšÛ®\ƒ.¥ÇÖwÜ&bÅe^œÓò èRí1mz„³ßÑièŠÉ×¾ÑÚ–_÷þFùΦ–[ä»ýåz&Û­ŸÇ‰ðvý°OáÒê|Ÿ·EJ }9¤×˜»Æ¨ç}ŽÅwŠë½Fîþö˃ l‚cf5}pß2‘ rV‘òV¡‹+寴ÂÈV1óŒj˜ûµÂÛÒÿEKãëèöøY­N7šmõ ¹‘²a뗺Ĩ÷¯²é‹e£NÓá†Ö;©àÝá  (xÒŽzÙ’5‹Ðçõmý"Û·k¤õè[¼özáW§ryž§¡fqô.¡½n­ïÄHl¾Ì?æóÏ]þ1¸Ž€ .“>ÏÞ”žß][$ù>õy÷´¤šÈ‡xý;¶Ì8ÃrKìrq¤[ÌÆs§ìÉ{õj3Ö;î¢Õеퟟ©V°È0á530¢hgëæpîÏMÝ—Éd—äý¥=Ðw’¼ƒµ£2õ6Oz3»´’U²çUk­ #¸¦92ØëÀÂĪRCÒ¼–™mf0ó4RqÇ;ýödázÙãˆÿ&6zðîví«iÝë”èRMz®{è©áåt˜Ûw+|8°ð \j‹Ñçî™”¨’7º’#ï;Ñ+ä6„ïÿ^ ;´{‰Ï?¹¶ Îýº±6ßgyÖ{/óùÇüs— ®Ãm€¿9÷Ñÿ zUp¥ë é¶ôÊ·ýêÅ™¨ÈD뎺ëñö]âŸÜ«²/ߪ݅®¸$XVÛ¥ðgÿ£GÜ×_™™ß,ÉU¥yCLqu-o ¹î’ŸôØâDõ²NJ‚ÜòyT‚×3WÀ™yƒÍ“æîœuö•Çö£èzäm×¹YH”G߇¿Y¥’gæŒè'>¾äÑ–Ö:C'+½~ÈÌãÑhc3S‘=Ï%µ;aˆüT®à‘VÖî°qˆü?ºDᇋ[uWŽdÒ!á_HuvùS†dÔVjâñŸY(±ïgáì QwW¬Ÿ ¡û¾ä» òḖ­‹GfFñò¾Ì?æóÏ]þ18Á¹ÚÛ¿½Vzí\£êü‘'&Á_æ5š7€™öfIúôÓ<ÜÑ ‚lÜ_¡_ ÍHÍòZ¼w.Ö¦ ‹;zl_çrháÓ?fõyÙ»u¥e“¾mx)hBí¶MV@‰&6gèjVɧÛÖ(¬ ÀÞÔ²µ—v9±s¦¤ëø³´šŸúmÌË]Œ,àå¨Û7LÑe}Þ*´ ·{Ü­lÛ¤G‹%ºÄqÍzGÐD³j>}¹Š êîœC­A.Ѥ¢Ï…«:\Fcƒ  lwçåQþØGÑypDÔqx¢¢nt;ƒVK†o„‹‡[O®ZóùÇüs— Nƒ|×èÐé;ðvÉŸõYļ»#D‰w+všRfÞx|xgίOØ•É~»¤/mòç~c´ûRx¥|“£ù<º5½6ðj¿Íÿ8Ìx qÅ»$«u¤UGÃ5piu´9Òå ϦŸ<üüça´šÃ*ßbWú"ìËA#é‹Eê,*¨÷‹ï¿(ˆŸ›…,ˆT{û+ï÷AíïðK¿>^Ãò–«£ÝÁˆváÒa`Ú¸B8}É!9pðN0ÿ˜Ì?wùÇà4Èßxò÷ ®œs1ä‡Ä-åýâm÷´‡»Ö¶d>Y­«ôþƒ³òω—Ùÿøõ0Ôÿ÷Œ~·ú5xátõ Ïnížì´ÙA¾¦MãÁ+¬Ó#º1|Vn繪½¾e¯áÍå¤Lëñȯð`ÑߎºÖr̺ð„Á ~ü|@gfžo]÷75Y2þá¶&"^$5£šãy¹ëè’}}Þ̦kHÝÞRç’<®‡¦.}á›K»e¹lñþ/ 6ydS/Z“ï‹j»5%ÂãkƒþP6j3î¹[8ø"áìsºl9 Þ1ÏÁ+ÁüCÌ?柳ücp Éê/J¿K92úÜÃØŒ§Îv¹­à1ÑstéÓJ]äû Ï]&Þ;(Os^¾SÖ«9·suõ“Uƒ+ ¯q$cÂÖænÊHèrg°} 6fóòÁ¼lw~Rö÷éøïjÿ—ë(ÏäÂIÏ:[¥¿ £’¬6}…¿,ÛU _<¸0šéõnýÄ:¼x´{@±!²Û·½‰xéáYrråkjr°S[éPúö~ûè‹IÕTÐ`ÓôW(8Õ$9‰3Ñ€APìv§Äý¯½Ïu¯¯ÚôâC"ìtI=ÿâÃÅ«2üí;tcþuÀücþ¹È?§š8ùdü†c7<¬*}>¾øë-Jò$º}ôoRSWü+J·½YÕÞoj"/xøp{ëk[¡Ëàüó¦Ü¨k ÝáÞ¦«£nM,¨Œ´·â¸è¨»KimÖ[ ÞßqÝ?¼½Wò5«}€Ëêôé»Á:ycø•õ•tó×¶ÈØðrßíŽð|ößÁÌÓÚ;uÕuS´}qÒiòlÛDú‚Ÿß’ÌÜѶþwÔ,ꎜ:§áó©­úbT¹Œ n˜úÔ\mö§”])ØÖ ÂOÃS®~±ú鹯a- —v  —æ´ºeç}`þÀücþ¹Ç?§ÚÌlv+õÓî«ÛlEߤQa’Š{C»ot,ÇŽIóžþî±>%Õé§þÆù£DhŒ ËÚÙ÷Y×Ͱ}qU«-š°ˆŽ*¿\;mÇÀºÂ²glg,«Û`‡¿›â”1eéÓýÇ>Ö°Þ.ÿN´Ôzs±i¨J?Ê™ßóØû[Ë÷|¶·$£òê:f¦/>9çÊXõV.2í žµ)`¹îj^× ??YÃo?§^­|:1ãôÜ!ôÅÀó´WPã¢I”ýr;t—ê£Ï ããQ¡ß³Ê£A畊Õg/¬„ü>a~óc0¦Ú~˜3`þ1ÿãƒÓ—ô ñV´pË:ÿˆþ~~y}ÄâÓì3`NàÜ‘»Ä…+›'7,ÿwȈC5–?øœà_A|ûöZÝþçk Øhu£“)ψˆÃד'^ÛÊF¸ý:rÍe›¥½ª?cdáƒwÕl³ -VÔ¯f9ÌdÿÓ•úëÞ»þ¹Þ Ý™S<õcæ!ÏLoÀxš9[¦5úÊþëù†qÒ¾ÕÛkíšqg€všV_wšÙäYõ苞ÿRëº .(è^<–êØoÞBí‘þíz¦”ßû-kpilÝ4þöÛÇ`3ÉSè?ê:ÜØÊl(bÌ¿90ÿ˜.ñÁmt“þ´­ŽoÛ€zÕµô³fàÒ_3ekÊm*CÜ…_·Ž©ûùŸïYµ¿&ówzçï·ùÅJAtþÖ€,çÅÀ¡kîZ^0Y3–šc×…²å èóÄöZÖï7Žœ^:oäõ5nMܽTØ.ýÏÎúæß˜Ì?wøÇà4z%×^>¸Å_KZ67œ–”vÔ³ñ“-4:i‡×—îß=3ëã:ž!‰®o_ø¬¯u¯£Ó¼ d›¯fçQGxÀá)MÆ%•yMc_ì#~³«¥#ÉÀ³-Zøl«?õd†Õ½ˆÁ7ÛX‹,ŸÔ°Ì´Á7RÞ°gUïÑ#Z»šY™:n÷ë3*N2©¥BÑí´áúÈèð:w®×ÞSQ/»êš~?TùÖ‡ké‡lß™>»´ÉÊÑMQ0/Ê¥ Î,‡>oÊ[C¸ødÕ Jû6äöïüqð³Á}`ß ¡í‡Åü[óùç ÿœFÿüX¿ˆóŠ÷ìaÖSÿ¾´PžZçÌÇž%¾×®Çélj¯µNýÁŠÎ“–¶w6Á»"Ò{Ÿø~¥;Ÿ\õ¨J˜’]z-ã:Ïê“ÇìýªÈÒÀEÓ£Šî4ö™`9|™wvTèJ–º³{lbnøñiúÝÉû;ÏúÃH$Êg·8mŠ’Ž•c§:ßìb¸~¿4&úyîlÿc§þ¤.M]ýŠ^I»mK…nËG4CAø‚›?¡àÎÐÙèóíÄþèó×Cõ¡èÓ¤ïv=[QÑAÑí×ÕЗ´¹©óÏÌ?æŸ#ücpž[K~/{/˜þ¹ÏhËY­¬)''þ1Zðq üy¯/¯Ï8ÕeÚÞðÜKDüófXU†ë~…óË¢+çºT¥~…CÒ“vß\ò;Ëþ¡×ý6=J´7»ù](ñÓ󣃒÷´8ÿÀâ’6Œ™Âr$iê6['|AÐzå~ríêÝž G¢z“Š6_0E{m—÷1ýY‡ë*ït‘/g4ºìò¦LïŒ=»×馄·_F¯6ÍÚb¿Ý‘(pi‚>;Bùï)ƒðJÛã/S„n·ŽN[pf„ØxRÌ?0ÿóÏ þ18OtìquÁߨùÖ‹eDüžA^Y»D¹!Å¢û®¢¼­ƒ–θmËÓÖ>–,_¾|$Üö–G8+ÂÓ.˜ÿ¤W18Îky½. ®ZØÑoúÔ°›ö‹¢½Ò㥥­º\žŸê6¬ÌìÞëQšWX‹Hâ;0Ÿ-”Ö¨]¯wàC“yúùÛZ {þ㌅wfWޛ󠬱ìòÀ ’îã…yKôš ñ×íâ èšB{žîIÍD’³2¨_ õm «<¹«öÛHᢸ̪@„id§r…'Ř2R¡NT[ˆZ¯d-Ȉ«Ñ²PµZ«R0^I(Ì–-IRÎh 1ÊT¨ ä0$PE@]9$PêšJ§“PÁø”ëÛ ]J’Ë©ú'TŒJ°÷þ1ÿ˜Ì?WùÇà:Áó^›N}ƒqļœÌ8¥ue•œµ&SÍ®Áâ% ìúäP¼kc6ѳÖ%#y@„Ä%8ÎNFÆi™(«šbzhBÃú,èŽ8ÆúIý“üX 㥨Ìò@Á0$iŠ¤Æ¨É“°F€VvÊèÛ¡Nù ÿ´@¤þì¾Ì?æóÏYþ1¸ ñ/IRRꟕ«ª™úÓòKÖ'³h9Ey¯IqT ÏGõ[æÒPINŒÒˆÀÂx%”-KŒwBÿ£ÕænI¨/à¥i•:5b a_ôÈÒ •+H±0>Fa¬š$äf3GÀÜ ûbQ\Œ0 €ÒüÂÂÐ1¨ )‚Ú™ŽžÉ` B*ôvÀ‘Àücþ1ÿÜåƒë Åa¥ žFN\ÍÕŸ’Ín޳T@Š–F­‰³ßý×ËûG–ÅYÔLŠ%§:!¬gHr´DpŠUXê@Ë\H¢eÉ1´r™0ž}õ~$@ÊT R&$ãÔ†I@@’J³,fM=}J—åH?I™ˆ¤¦]•Æ@²Cûå ]Ôø¯Ó~àÄ;Áücþ1ÿœåƒãd¤wŒ$%/Ný1êO÷ª§gäkÌd”Fú®Kq¦÷ Hþ´œfò(iz©ãõF¡2ÁBÊæ¶ ­ßh¡MP*åz{ _4N:z)˜Ì?査ücp¨* €I±NêKD¸ïºt¦~R°P‘çl‰Vò€ˆ]©uú« ˆ(oXæDÿˆù,s•H…a©±J¹œªlL:²zÑ%R7R,ˆ‹Ñ/„Òl¤`>hµHk1’WÅæJ]À4$!MÓ Æ4#àpRóùÇüs– NƒRÿ¨ÙÚ‚ RGþ¶öJ‘-bÈ Ÿ[”lÙ†U~ɦ¼d©’ݭȆ8ú¨ómÌÝ™U‘ÎÖÁ§–Ñ¢S5J(‘ÙER¤a[åDZ ebq¼š^F´r²œ¦r Ó”|xFŒaÒ) ëÚë'ÁNÕ¢LÀä ä\÷ó1ÿ˜ÎòÁi õ—ðf+ Tâ9D‘c[› …“áƒò"znj¶¶&ö„Î…úú‘:ÏËes*² L*2 €4,ݬRÕ$ß–´áDè×(ÂXz/)Sš•a1h¶ ȰÚG˃8ý^"Ò°È ¼~ +@Ê#SÔ¨ÛÏôÒ»o󯻃ùÇüs NƒRÿ(?X”ˆ¾9dÔŒ•NùÜÚ( É箈ÑugÅËKYÌÈëë$ϯı;/SX´B%\žbÅ¡)¶&ø¨-Pñ*Q²V³{´¼”¯Ñ¨ÊÀÜÈjPn*ˆ^4ÈGiµ:,†0lÒec1º>> å„8<>^%7èÄüæßx óùçÿœRi”/ü9‘ö²°ÙEÎyݲ—& ós’2Þ¬U™öŽþ°!¯¯uÓùyššH“Â%y(‹ò+J´×~@DÆÙ:¯½ ™04¢ØV³I‘šÍˆ”ª ž»ÈDâ4èMZ¸YÌšï & Ü0h²("^Cï%2nvÊлáCíψU½òÓóÐn÷óϼ‰ùÇüs‹ NƒRÿh_P˜cp^mtÖï–­@q`0’'EK ýaC~ñ"$šocžÎHAHnŒi8o¹¯#4ÆPÛqFò|AšFÁ:†R’ÅÈ4 ‹'DÒx•’$Tæ‹@¶%@úZ&!$ *jÐhŒCG€Þî#¥"Ãiîdûy1ÿæ·1ÿ˜ñÁm Îkô\éº$Ó7ž:4¹à£º‹RÄ)Š2U¤_AšÃ£?X[¾ñ«bÓ6$ÕÄ ÀÏ¡ ¢`U†íªI>´;¯ˆ† Á¹ j¶ºmy™:ƒJéIÈ͇ 3€–K€ÆIB  –¡q°ÁÖí”*æ)U †½§Åü[„ùÇüs† N}uùó…k“4JF‡Q3ó³jÔù¶(4Ò;U¦\åÌѬò¨þå1¡k-OqP)Ÿ§o3R ÙIjË€¤Pj×ËR™Àz)Q°½ Q0w.Q/U«„1æµXÌš-šNü ”•Ç×jTò2Ô™Ÿ2QX2² ÆÃ@í=,æßª Ì?æŸ#ücpÔ7uAtA²™úSéÒÖ#=,uá…é«ß½kU€4x~JAlMÄ%ÈÔk!ÒÞÂ|[?ä!â§Ø}2R 4¤—¢UZY@ˆµl@ÌGù„âLóÃT¬gQæ–`*¼ Ùƒï¯ó€Vw@ÊDáéZ”¼€lóÏÌ?æŸ#ücpè{Â_™ÏúM.+«‘ÿ-S˜ˆöNŒ&69þ9[Ál¾²4®€€ä‰Mç‡P»EY¬»Ðt»nÉ@*LP)_j\5ÝÈb@OÊDÒµ™¼Õ 3J0–i¥•‰dñj¹Á5Øxß9€ì %IFÏO{ÙzZÌ?kI˜Ì?'øÇà4(_—Åá«SYÔŸºÉŸš±Ú¦§¬ýrÅ!ʼnâi¶ÔQ dÔŒ…Of <€)cìHQpl Ë2 ÛdØÛDT‚JH Ooyª- ‹m¤Œ#AiXϲ/7¯”¯BÌ(Œ@©¿iaä Õgú#;“Hý.šíÑ柽$Ì?æÿ‰ÿÿs]ì.À xœí]w\ÇÑX#ö.ØÑ5ØkDÅŠˆXPŠ"pH=®ïÎ^£G/*MQ‘¢ c7b‹¢ÑXˆ†Ø~ö5Ößî^aïnwïÈŸÞ¼?vvgçÍÎÞwßûÌ+3Wƒɘœ/=Íú[XöÏö ’Dºû+¿{(íºqU;>;uUôò CC'ƒ‡í~ñ9ý†Öµd¼]ÙIyåÆnÇÇþm gØÔu‚gk)5½]“O•ïøAjØpiºKVS¶®2¾¬‡Iönl˜ÑgôãíI”[¢dÏLQ´)KÌÀáå7 «;ö÷>b³üߟt5â2ß~g(--fé/~sªcœöüõ ö'°°³ª*ní^ ©ìwž,g9•ÿJ”m’Fõ"JÀCøˆ£ðãÕÑüm¯ya£~X3}×ôÌ1îC>Ó¿&ÄŸ þ$Aü¿lü!Y5Í¼ÛæÁ¥S”Ÿf¥24iýrQþÜÒZíÀLîÝlžØœÐëtçøØg­ÂÕuÇéä¹fCš×oçÉXg ‹wÍÎë!¥)Ô*´øø±ç˦þfÐ0lŒW½ÕQl]ß¿r’ÌÕCvoýUà÷õ÷~ü¸¨ª½)‹ëöGšq¥ë¹×³[ý¹å¡J÷û¾™Q¾ûbíýÈò†·BôWÎ¥î»tçÜì"g ›÷~X/ß® Ž©cÉJ»Ÿ÷“åp—ËEDÙVýC?¢\:ñ~<©ï¬t›þtŽÛ®“Øæn.y³³ÏÛx¢l7l Qzwnˆ?>à·C²ÛàÃßô ÒiøÒ­c]š] ñ¯%ˆ¿æE þLôÅá_;|HÖH“ßL5®rkä5nÒñ_Ðêõl¬â¡+žöÆ ±üaCÓ‹.§'ÉwÔWÈðï^:}[§ñθ÷J8´iN ~é8áà“iÏ5Ë3ñôë”QßÄWϳ}·ó\FÍ®ZŸ@&œ³EÆÒ•(ÿŸÂðKšÆŸms>NÚi_¨»¹ØéÔRS~dûû鯕o‹F>—¬>ôÏ´jRì…¹§”}Åÿèõòé«MKt ŽîN å¸CZi»†n#÷âõ{pÉ›ŸDC‰²Côà¡Dé÷®;~±Ý…ðÕ&ìaÛ•.¸N:õϱîoý*$âñ7$ˆ?3}qøoeyYHV@JTG *<:D…µ²Ùôæð‡B}Óß:TðFfï2ÓLGÜOnÏW»×¹Ø–Tnû¦GBîÎ: ·*Øg—Öí8íÆýçgîcgÍð 蟱/è_ÏÆ~`YyÛ®ÝõrÖ¼ÉÔÓócØúº_v$aö\˜tÎsâ\ušÖ´¸öìë»ix"[xï½eTæá”znÌkþçÌýö׋‰šÎ‡¨îÈ¡ 9Íõ“ž šëâƒà½S“ãÄ gá…C‹ÔËNÃt IÞ­IÿÁ(;*þ@”A7FàÇ2;®Y3{†õl47šªü\ýíÜ€øCü Fñgëë‹ÃŸíe!}ñTØŒSbÍw¿&ëŽìp#5A'é7cˆ2â„3~¯®œÏàzxGëSv»º } ñ‡øCüµ×Ö‡O¶—…ôÅhß?xà]݇·|Äww½s|xpØøCuÐyлo7圷 åJ0òjÜïŠ!G‡ŽçÝ‹Š-Í$^™ytbÛSQ9ú ô}õøÒÇWÞЄ1õô¤É¡zWCè[p oÏì{bŽFèÿ~ÈiÑ€n ¯'ÏÙYÝ(1áœÄ‚ê¾óTäÐ!׿@ º‡|î76À'§é˜äQ`øÇ½÷„ê¶ Œ¯æÌ¥¨Fl÷ýÿ-ÎÓ_5»¡Ðçb5íðò‘æ ­Úþlñ®´·i·¤UˆÆÚXjO”QljD).s'ŠÕJBËïÝÕ?çâšÅ&å1Äâñ·fü!Y;…ž}jÂØÕšÌUŸ)õú÷þ:&sö*ï3føtÄ¿´Ôãº*­¹v`[Óe––ݹ[lX/¸4“x9ÓÖ¢‡µ/MÏ™þvŠ’RÅ9Çïé"œø 3Ó¯jaÏ+NL‰J£nëö`Q áìý~òJ—'l@>]œãÚ’ZqýŽÃŠõ‹>mÀ°±£«·Ñ1q—5±Ë0®l–< ÅÃÂ⺟ðxÒ÷çA•Ò?¬U§|öVÓÿýXüÂ[“M:v4znq–9~‚ÀŠÙi¹Óê-0¬èjïûĵÁ&®u7¾rô¨Ïø>àò‘6Î]úV4“bó¾/â=u#Ö6®oPá»´|_ßw¡ ô¹°Å©„†ÉûiâÁÛÆ•…˜z*¡ÈÜ;ŸŸxºáìGó¾ôzJ&z7¯¬²ö1wûUŒÓ]Ô«g÷\{ºd[õeߊgîã=>cdÈó±ÛHÚÝÝ]ˆ2^FÖ¿mŒÍ •ÿ…AD5Äâñ·^ü!Y;í¸æîðàÂÁ`ïù‡]?rtðÍ÷ë²®;VÔ+Ô»“Í 'šÑ%£™½ß_rº%»' î—, -gã'‰;ñÚùÇå˜$üäØ)îÞ9ðÙïGÉY6¥`„½mT»Àçû9Íw´o½u_¿shâb”K´à¢ó£.¶MÚíÉO}@'ÿóë÷0 +.m“p–œßƒe6Sg6~tlvl@ U‹}Ÿ:¥Ö®j× £ÓÝEðÚÄ@íéÓáãÖm(ì—toÃÌŸ?‘U†î#ÛGv#Ó£Óƒ¢PŸ"¬¤Ž½ðãi; k>|<Ùâñ‡ø[/þ¬œC§ âªþ:SïÀkU½ïÙÁШòóò÷Òxæö<ÿöÿöÚÌŽþvåŠy ŽÐ-Ÿ¥Ò÷‡íRõ4Ý”DTâ|fx›ŠC´ÃþvxQßo7±vìéÇùî²Û”NGƒÒÖeU}œ&­î]ÙoT :O‰ð´ÿÊÆ=¤¿§'Ý" k ~11~´O»¹E3üßÌþ­ÏÊñGÕœ¢nŠÞ²ÿôÚßTÂmj«W‘¶Ÿ¿Ðž*Š+ÅÓ›ñí£ªÒÛ·4ìö *!J‡ðΤ±”çA& eçOÂÁëÃñcó Ã0Œ§ÝW âñ‡ø[/þ¬üyÁå2—;iz§…»jQ(w½ÄùÙý†Û!—}ò~qßåÈ´cX(w{PNöã2 é×ÈKò‡M_ÑÙ ž¼;+;;f47½%í½"±vŒKLœë™q¥%èÁ†5¬/<ú$·÷4©ï9{.kÄýU]§oiDÃ6íã÷&€¸(8U·ª—ÐvyîõgÇ60°¼¢oõˆ¬½:×ê§PÝùêjaï,íùͶfÞ[¤ä9ßži¯q£~Ý —ööî°˜(K&ÈÛÄøñÌW”Õµ[ŒBü!þkÆ’•SðY5åXÔ…Í—m{±îÉDƒ‚_„guØG¿篿ß=›ùÙvãfþ¡#yº×$Q¦–$×’‡e\tïC·ÉöÅO‡••×£[v¯Q¾€Ž…JHáƒßxœ´?–À¾)©$¥ÂI@c"pœ:.j!Ù9çq׬ó*LÞýüÈÆ!ú¸§½Ïîy¼£èϽ”Ü¢Ûk7.=-9¬»èj{±¹nŸuSyÙ»t’ {Ý i_óˆLSîÔf9Qîs$s‰»áÇW|q{¨Êu9åQˆ?Äßzñ‡dÕ’q`QÏcÖýà_cXwÀ`¡äK“^ó Ž% Î}¸Ú»ßï¬]'Üê èØl)£ÿÍ'õY—¼üÆL t€gy°¬w•LeX-öÌS¿Zð½ÙÑcaoïð.5nÿŽ}1Ò5 .K¦»3¥¨óúO6NmOã… ûvÊ“Z·ÌFÍõÑfé—n®]û"o9e«²÷›7¯üCµì†sµ~ÅîF¯ºS7scØÐ¼EßžI·=ZŸìrÅKr”½Z® ÊÊ&äÖà×ú¡øÑ/¹ãs óçý¯ˆ?Äßzñ‡dÕ–:¡Šíè]rÕEâõ_{A…­ßp rç×#ñ—OíòÚâ :. ?oÄ®'2Ün¹ã™K|ÿ£ÌQÆkê 6Ÿ 4ˆÀî ¯â)Í?s˜Ò̧>F9_|“ÄÒ†ëûûÆSho¡{Ο¾y§3M*òä#¿51F]÷€²–‰¿sò€[ƒ_Ûy>¯Õ ý&ð»Õ:$owÿ©×ÝE—êݪ§9OîÜÀæ»Rãc_VÍ"㓹7ߊ¤·ß×Dyï©.>&¢¬@²Ï·e²´@ü ‚øCü­HVMÛ®Ÿÿ+trfpþnO‡sæYèɯͨYõZ|g¸¥(6êÒí±¿BcÍÆW´lsjšãIº{`±¿¯CÁÿÊØòs¦õy¹¾zÖÝ”ªˆC•û§K?X2z¬e.­zÉ›íÁ’Š\ÖòÏ~îñ£TCÍnVTaì úþÕSà_»åÔ¦>Ó›½ë·cÔ»ZgxÿŠí2%gðýûdžø¯×žÖï=‰è=©<3È÷náQ"Ú§¬÷†ü½ûø6 &ÊFI½4)Ÿt *çQbCü5ñ‡ø[þŒ‹&!Y1 æå&ÇÈ¥´ÂPü4eÖi%á ³3¢e8ÿ†ôÿÀOü›upXN ¶pSŠ¥üøhA²\jPé“¥V`FÉê¤hÖNQžo0Dškøã”#§a"™Âø9@¤ˆ‹¦ðȨ^C¥\“IkÏå8?*âÆ)äº~L®½)•iJM{„¼Dœ|&ñ4¼'â EAÉqr)`Hó†ø3Ä_sâÿEãɪ ~';%–Aü‰&âïâºïµcT࿪$ÿn(À§8QVw € ýbÒ¢¤@´lk¼eÏH°,ɰ)ÀÄáAY±Fü¸¢PE³ŠJ∸ó#£åT ‚Šdt ¥‰5ˆ P)eúßà2LaÆõåE¥úP@5ˆ€¯T)´üì @sEQø)ðÂRcäô âÏØÄ_ÛâÿåâÉjÐ}±øÇÁ ÈJQ0Š?N¨`IÄö8¶4‹Ã¯O&™P«d{\]¿?€FºmIÄeÁ ዞOë£LT ¢`IZ´A5@#ì#®Z#˜•pQµ’Â$¢:·!*61pqGeˆÄ(e: ‚"2êX õÕÐ* •ð¹iZ~Ò*ÐŒÊR€kàp41ŠNCüYº‚øëÆñÿð7»å¤/š¦þ.BüƒüצŲŠ?ñUqç¯Éf÷—q <_þf•öÃ&ø3rëÂOvºdkœLóÑGºegXÀ$œØSEP~`|¢’ò’x˜ŠÕ&Á5Dœv’K 0<&Žò#!‚hZ €JdrDÂSF˵ÀÔ(­ ÕˆOö5¯‘J-H:¹× >ÀP)©4 @Šc!±*ˆ?Äßh¼殾4üM·R‚dM4¥ ÙhrJ¸¶‚Ve¦Ç™¢)¼xSªÉä–±9…xnJŠ¢8½êÄO²ˆ8¢µ:†Ü’d–ˆãÕ´†ÂõÍQQ€(_hÆ'‰òez! K¬ ㈢³ ."^l”–ßȈ!€9¨•q€ #â5Ï·Ph'ÿRRLÌŸñ‡øŽ âÏB_þLÛ1A²zo‹7p<áâ¼2=3ViVü‰Ö"¿•[ie‹®1ÂuOÎ6ºÑJ?‹ùÉÑñ½S(‰?¸:ð2?í ý“èÛ [[+Z‚ˆö˜" )a* ¢´a@€béÕ Ä2¹çŠT MÕH«ˆñ‡Êâ•Äóë®ðS€J þˆ¿îÚêð‡þë&\ ¾NâOòûš ÑkrÜÔò{s̆ñˆv(Ï}ƒqÂÉ´9މxå±z‰±ñÒq Hˆ*†]&€˜g¯$ÖK ˆÜ† zAý‹¡ˆP§ãs|# SP—L¾ÀÇÍ«”òÿ¬ þˆ¿õâÉÊ žkJ^* õ’oŠª£ø“üsU[ØD‡XûZ¢bŠ®¡¼¹ñfD#~iõþ|Ÿ˜µÑô“|”ïµÁœT£Â`ER” WšYR pµi0Ÿáse*…Œ!ˆÉé–Bá Ò…5ñ†€ ç”»«2)r0 íâñ‡ø[/þ¬ðïÚ=O¹+P×]üuü™Œ[rÛm,ËO‰b Ã…»¯Ï0³¥'q"³ciû 2ƒè·Åuƒïúso„O¡ýSãe‘˜37A”4.B€!ÂpU¬T¤ }zEú0Œ– á> WTk!DEÄÅH¥–(ÊN ”Bü!þkÅ’•Ÿ Û¬Ž’ÿñ':s–3†á€$Ò=>OÅäcåבï«fLõâ%¹Áz®ÈU9fåŸÈOŠä¤!2Öà„Š$´&䪽§‘ÖЦéùE‚X The£ `TRâù‘j¹Bn‰Ðnfð(ˆ?ÄâoµøC²j"&°¡Ë1 ŸCÿ7ñ'ú, /£Í´%×þlNdžþkù—…Ðókïãs| Ûþ¼\@¹AY–l3†ó‡-É7³W3\†}Ï*á­NH6ù[ÍÐi ‘(jGK¬ •*~–`í* í)þ|¾D©Òªo‹åH þˆ¿Õâɪ‰ÿˆ¥X¾|IfN·ä¤ö‚Fº&o¤ÙR”Xû“±Ž>9Öˆ?m=ãóñ¾W1cšÉÏ÷JÈ0Ò2YkÙ;”· ?‘}é3@"T nJ\‚EÊ8Ýé ] Ž‘ðä±rªÿÕ0h˜\ëÔ*" ‰©2V ù;0# â¯i ñ‡ø[#þ¬štâŸÂ<ê¸%§aGÄ?ƒšL¡q¹ô÷/T[°§Á¿1þùýS’ž?ÜÝhKP€†‡¯±t}±h*Z£¢ÂëåÉÿ$ $„ŸB÷·©ô@m ŽŸº%(Iû€ª`°%(»0 ÿAüµm!þkÂÿÿ˜Ñ.Ðxœí]w@G'KT4&ö†ÁÞ jü vMCEQA:R®—ÝÙ;îŽ;Ž.E,*ˆDc»Æ,ˆ±D±E1Ø£X"Q¾Ýë»w{wÿ¸ùý³³3ófvïwïݼ™7svó@Õ§5¾’ŠN¡1ËŠ#¦_öHªo[möÛ‘dº+ ²Ø}>pÅÙéwwY!ßòظšÊQî Æ%Qãì<Í\÷Ѽ|…ãýU®ã¼òt¡¡QYö­zø©Wö)}ý¿[?=¦­s Ù–žï¢éJ÷̽—ðéŸ‚Ž³c(ÿ+ª:]I­áQt¯)gì±1•Mù#)]“áÝ«·‡¾,ù²U]ûÞÞ'Wv:ø¹|taì6š:ßMÛ_:s ] öàÑÀ¦ö}¯LÊN~àþ/WdUO|÷bØ-òãcÕŸwVHÖ “©3Ÿ¸Í,Ô ß¿@²µ7Œë>ÝiÒ“Ëz•WÐ9RqÜeÇ#æíôRUÖß»¸þt‚øTNÙg¬Æ/ùû4Æò¯äòo{üCØ48¥Íy?<’?ì—ùáx6‘ÁíèÖ½ã¹êAõmPØí×ÖAsX0¥SëßZ)Eë­”çwî7ããš”죢I{+jƒä&e ÔØþš‡,ÔO­€‹Î=Øþ©íq«zfby ~Œ1Ïö}±e’WY¼é§;òªEíg#8Ôã:ðézþŠ¥}‹H%Ã6Ûýbä€O‡9—ȆÂnôƒü ÝJ§ÝSÜ䜿«¯2ùnÀ«fÚ›!è¥u4~Ÿ$ Q%„…œßb=#BúìÀ~œ]¥Ê°¸%®“ŠÓð‹]iøiür ¸™ ÿDäߦø‡°ip¯v<|àί⳯ÇßÙªÉû©¸UU‚×ò½õmsÑÞÖ²çí$ÒàdNkמç/=ko½ü¼ƒ§‡ûKÈý Ê zÌ·ÿšaüН<³}›HÏœ²ÿú€¸"K"*¿ÊÈ샖;ýb‡£&šœæ³»÷,†Þ6ú]. Ú1¡¢íI·ÜU=îD;-¹%O³6vk&˜žU4&øã]Õˆ>dì­/þyìå>kµ7‡¦÷¼§M‡]þRúø}­4eüË×%L^r_•3нFõ.)vMû ¿Üœíù7ä_ È¿íðaÓàÝéÿ±ëçÆ-™Èÿ´GŸ}{Àz/EuåÁ6 ªÚÌ8á4÷·%N×Nùk£è—Rù{½¦¿1ìß'Ñ¡fL›«V‰ƒ­Û;|Wr¿M†9e±¼šÍ·Nìà‚6ò³©Ær.lÔ§|h×›&*=‰?uŒKׄû¯]j]¤óïçñþ¾åûQR}IïŒgÕßúåa,ŽœÅºð9>¾zö׿r’ñûQ›1éyY—Ï;´*z¾Á:)çí5w“TaJ¨rÿ®Ìž^›êø”¾¬t*¥mB\&ü¼ËcO¾—é§îüÚ•n4~zϯ[t{JÎZ:=àBÎõ@Ù¬nA?Iºà„U唡/_Õª¿î&wÆÄkš$xº¤o²:©È-‰)›ì1²“œ£^ú<¿Z5ŸyåBx |·½ªAÈ? - ÿ6Á?„Mƒÿ÷¬ÐÀçKÉ¥”1¹ß/yÕÖ·mNñá¯Þäuë[Öäü­Yÿ^¥1Óqh Ëgö‚Æê;tžèÝ$çž%VË{Î=réË;ñö® Ëõ äpöWj\ŒN‡£2EîRRê ÛŠÝm/ûúï\„_ù‡Ÿ+×¹}Ù\HÔE>䜱0óÜ&û£ä¬U-]ˆ²û=xµ½2yP¹SîsÌÒ3¯µËÖ/~s­H;~#§ƒ¦`Æ_Ër_0Þ&u±úÐ9UÎ׿UØëK?#® OBþ©€üëùoøüCØ6ªI¯¹¹­Å§®^W£sÇ7býx<çcN}[Ÿúnswúõ?wîqøö·zÈû|gûwÁr‰täÈ©÷ž­fMª‹|ËÙÇ'^üÐÂé÷•ÉÖI|XèèißWs#Ì»Þ}òµÔÔþbr¥9W^Ë¥eæH„—Ûm"RÁ“ÃGVº¸ŒŠMT—,kqø˜±Àßöüz:%où™¦e"ì»–å‘1¯ŸœÎeæ}·O_Üõ‘싺þnLûâOMzüË*­/a7<»ËÔàæÿ´N¬È?£Êöýs•l?Iø»Ä¡1äŸÈ¿! ÿ ÛÆƒ¬öï^•4ʘÍ(6U^¸j*ïÅË,Úí®–p¸cTqëWQ[ܤ–+›ÀÎ «;lÂ…Ç?)é.Is¬Û|$6ÇåU­Ï¼]CLÇòa§ÉüHýrÜÊÆŒ’ŠÛa]$UjßËãÖãP-Æ•÷>£P'§â€S‹£nôT{-møSKÿ2ª_öUþùþä¬Åß=Ä­.úU^ë„~ßœÜïÓBšÆý[_.u}Û[gÑ&Ü_?,M“®ž¶hÍ‹nSfÒK1‹>ù3Ÿ–ÞÞÛªÊ+ç6^6|›¡-o“ÇEŸþ;ú¬ÔHw÷S¦›Wì{³ÏšäÔfís0nvù½=«:”s#§ßW\âírEeÇ!ÿ$@þùoÀüshßÂ`ÿºÛw¿Ü¾ÜMf®’ã´æ) 9Ù«ÌÕ1 —/÷”{ötþ=Fãóê:tסëÜ¡þ¯*g{nWgaÐz@óÚáUµ)Ǭ¨Í{½¡'ÛñÃcf›çfùµÓ9Aq;çþÖ‡þ#»Xþ~ýlýíÒN#[„vÝÝ%"[üvÝûuÆ g>ÜJΚ78¤FSÓùYÎq§òØ1[ /_~Êé¬îîD÷¯[kÓ‡gGó4ÉîÎÝc1̯W—Å_õí\ü‰¦ÜÙA”„9íPm®†ü“ù7ȃåÂÆQ½¦ÉŒçÃj ³O8&ì˜^×Y@Î,‘ß­¬$ïè¾×ëÚTÄMÍ›6Ýv÷t¡åº ¥IN‰>[ ÄÛ+e–-¿½Ì³UE}sáù8¬?xJs?æÌ‹ÒÔ}TY"]kÖ53 š–þÝœät§bûè>ᫌÂH=‰ƒY•^®9Û©I¼ß;£Êyl‘Á®£—o7õº¢»û¶P¾¬=zí³ v„Ã4nmŸ9Û¥§Ÿ‹°Q“oª>CÎàh•›ù'׆ü›ä¿¡òaÓˆ´KÌk>#Îb=Ä»r²ðBøÌºµÞnuQ‡–ƒœ½û§¢Ë #^ÿ$œbYÆ4¸ŠK#žNËëNÝ‹cBÙŽ›¿|S=reÇéBÁf‹»‡ÚOêuºé£ìámwŸrØçÖRõÃB>Þ~<Û¨’­œÿLÚ „ÜqL¿ç>!`VÖÓ„¯M8IÇ×§ØQò&ìŸqF›fäLŸø¾ó7“ìÞêç?ç…8tÕé<¿¢ÿ˶ڛæ¿Ô,¡OÒT³„è‹n×97Ù7n76zÂ5Õ\#2ÐÃòoÈ¿I@þ&ÿ¶7µµK¬ú¯¯¥52ðÛ»£–kê|ë×yQßH‰Å0ßv¾ûÓÿC‰E)“X98¸vDià£çë*Ésξ2­B4ÈÑ#å†{| Õå•Ó[üøÆ8½veX+—£TÇmŸqô~½74Êamp/rÀsdÄ…ÛÞ[“ãÃ¥eÆj7¥Àž5ç›°¶ú]ËžcÛ·ÿ+ï®ã?‡tYÙ­Îé÷TϹ&R I +–Y­N²îœPÿ“+ÒÁëñ¦¡[·'_NDa`ðÈ^* ÿ4€ü7Dþ!l/æŽf§Y®¦B£¤N Þ›dõ9àêÐ{ùÕµß_º¡ö/šÊuuì8ÑÒ\£IŒyÚìÚògÉ=ߌu©Ó1¢Æ|yQÔçm!þ8»g-œsh6ý¼û-ÇŒ^:ËdC.N·»׎þ ×ûÓýš^ͧ7›h§N\)‡zaóÿþ°)-åñ¡Ç›ø”–³&SwHùÝ8xù€î .‹Ö¼æü*­Q@^ŸŽÔÏá=èPÑ[Û‚oy®£Æšx?x£>þëüÅ–Ö½Î÷>nì%õ¿¡Œ°Ÿù§òO ÈÃ㿘ö lCø O,'1&Z„ñC–nO×ûß??З"€ rñº4¹U~ÐrÓý”í±.Ej¡À÷Ù¦ŒÖ×H$'Ý’”¶®0$QŠH—GÓ×<^ý› \¶„› ‹Æ¨5P~´ÄH ˆ”Ñ PáJY¬T,éª`†ƒ¢b½‚é "U>B.[Ó¿¶ ê+ TWÍ-Šé‚ükëBþ!ÿ¶Ç?„MC£þÙ‰ø×^D|…½™;cEõ¶(×-ˆ5ør„½Ñÿš5Fý~HD¶5v  ,Ÿ´U2á:¤½MK"QR¥·@¡qqRšžð·SÈèõe+¢#F!¡È›vP¡DL5ˆaKc¢µŇö†@¯ó ILÈâ«û·Ê@þõ’ òocüCØ4põ0½…ë“åƒ1óÊÅyÉV*©6‘0Ïܵ<þud.’mVÖ¥5¢­¼.püäÖY%ÂUØš é_&J±VÿQ&ˆ‹ð„’+1í° LA¯8(“‰ÊeÆÅD“,@2€P} ‰Q>G!Õ™cƒ!?ÑŽ9Àotmêgq_CȈ'ú×w€È¿ä_ÓäßVø‡°iüËZÊ]›B°~€ßN3ë\›åùîˆ'äq][¾)YV· EÀ÷_Aî L7«mÀøa!9JUÿ‚PIŠÅYC`sU“{˜¬U¦W,Ÿmf œXÜ‚!‡/%-št0TMm AÅbáóc%êe@£%@½Î“Ö P7ï5oÄ’ä_÷’›à¦¡R_Væ*e¾ nÏSäšèZÊvÅ b\¢ÜSÖÅZ©†ý/”åÊõýA¸g,Ü€hÜ]A°ÜÌ‚å¡9ŒU·åGŠMY-€D$š1C(GŠè‰e8–H)1X¤qŒB€ð,€?/*äbrµW!Ãå©K€t1@@;ÚW¼FB &¢7ŠäßðÑ ÿ œÛ"`®LM5Ú®¢àùíRþ‡e@®gT4’Ÿ`<жRžç¨î_Òcõ8^+øaÉ‘™ñVë¿ $%Æ`Î\£Èe<Ó܃@ÚU¨#ŒÓ}¸¦ã=@ª@µw†ð„ Â<—É1@´÷!~¼XãÛ™0ŠäŸü ÿÍ?íK@ظìàÐäÕÆ»Uu€íš¼1¦¾_€rýB°:ë-©ÿy)ðþ?4 ¯î–ßPë}€„) ·.Ë€áÒxò2 nŠâÌ8"@ÈÕ¹ªùÕhíäªiCŒö©g5ò\qŒD ÈK€¤ ACk ÕqLDÈ3£er:À‡ü“«Cþ)ùoÈüÀm#<8$a­õÇÔïkРÊ{@Fà†ŒúÉ«ûZ¸1U 8+$™1õp#P¶gK¢Õ€DJÉF`74)ÖÐ(;ZN¯9åÈôÝ©–c5[«i•P›CP±fÖŽXŒ‘EÊ 9Ho ´ç€`šx`¼^”B©î_oÔW4òOé òoôtÿË?üý·mx)×+eæÔ#&¨‚—Öo¾C}s’Å¡õ”×öºd›’ã¶Ùâ៦„Ç3 ج´ª€2õðQ„ìˆT¹Á2 ù#@qW14 \v¼êHNÀÄ Í  FžÏSHˆ4ˆƒ[Ã]@ºs@´‚py+!FõüTù§Ô†ü›xÈCå¶1-&;Nj|X5(Ï;¢ îG‚Ëgî ”Ñw!g·ò?ì%â-I¶âðOSÏÀvÏ— Cy«­97Ù¨ø a’þHP ˆL2³H¤Í@…DåeÑ9F{€0Ñé;ÀP!2Ú%@Ò– ƒSÁ5I¼6¢^†¤È?µ6äß ÿ ”ÛÆŒÍq&þ«ÂeÍKÛP×#AñgPàæ$ÀÊš·*ç¿)îŽm³:Œ×P°o‰¡ÿ¸+Î A9‘i¦4å…ËuG‚„¡0÷.(OD."dJøˆÞ´`"Ch]MBžË‹1tÔH›‚Iî€á9 êp b—·¿z‹7Ù@þ)€ü›ä¿aòaÛŠ‹±Fý1â;î±ÉÚs´5"€é™¶F¡Žd©»¼aS(Û›n^Uwy€2—mRàaºç&X”Ü“[žq ä„%kE9Àœ7d¤ÍÂ-S‰ئãcÀ gÕò|V¬ÌðHQr 9˜jˆIL/žX†$È?µ:äŸæ ÿ ÛK¿;Õ"Lü³§ùúÂòØ’ 5óüêûÏ¢DR®2|Ù«wòè$Q†¶\µ™†œe)‚ðW›ÚãÄb¦h–ÑxìsJŠÒËs¹ñR1éQÁ ¦Â ªîÅ0ˆllˆµG>‡øgPL«ø¸äŸZòOûVÿÇÿÿƒ=à¥xœí]w\G¶$vM4±`¬Øb/Ñ({Dƒ€ŠŠH=ú•½ÛÝÙëwô"¢‚]Š|j‚%öÞ’èg±|Q4–ØR¾½~»·»wø_¸yþavæ}wfîaÞß̼ïÌÖ# œ)S2V8.=6ëÚ«û Ÿ;(='䨰c/ö\pÞ”3{û­°ÍÓZ¶Q‡-ùC¤Ê6Ÿý½¡gJSYm4£ o¾;å¡Ö%…Õñ^Ýz;=C¼[guüG»˜Ë¼—µ¯Õû+u71Sp¬IÊMö·”(RÕ_Ñ3Aû„î¿ïšú¢üüo¶ÅE7væÑäû•/Ýoõ,¹Ùº·—Ì?c°Ú1å‡ÙO,µ„ ^§Mi×5oŒÉ!ÿ¸­2¤ÚÞ-ž?§xà¢Âôá§ŽèsFÔ„Bþ©€üsò_×ø÷cï„`hÉšÚˆ‹ëï?¼6äÖçŽÈJTï.XïÒ²–Ê’×`óÕ§Ÿßm[ËVȾ§íJ×'yÙëãvÅ_ÖB5xvr.}‰áaîݽ±uO19«øÌùH«dw)Ké§w}‘+È£û©W·8½–½Ò°NîïVÛd‹÷5W¡î)¸ÿƒMѼ6š´<÷Ïb]3­3¢Ð^}‹#n¯64ð`“ŸFî5—ÞxU=É”>7túVcò¯Þˆ±÷o&Yœ·Q^)>á}ü¤>gœòOäŸ ÿ:ÆÿAö>@8|‹j©0+©ÊdM,¶/éödYE›†¿¸D™MÏNܱ¤Ü£–ÕÎÕÊ_û&/ ÇDþz ͺÇaÕù Rݯozlz%o‚ìüŸ/ÙÄC»âïÞQ±K6N™^za^NM—Ëë.°[âÚº{›òçíYQ;hk½dŠ*k ZÞœ×Îï°ÎHÈ?åw³ËÛåúç/´3+Ì¥³´a•¦tœr§1ypþ¡.†ÔõÀß¶,{<÷TËnÃÎe ÿÜ€ü×)þ! j‰«&¼Þøê¦ÂŽXœk@¤Kõ°<¾7m˜\{øÈsí;»ú¼=ØÙ5Ž?ñg]ú«ïç=>ú-ÙAÕ;z´ŸöK7ó3&¼ëvF kTÂ,.øitbPjûû"[>óŠor¨jךëÙ¥:U¶ÆØÅow;ƒ„‰ªÝÕÔ|¤4¦ÝÚº´+VR-]½`—ýg?wu9[‰èW!Ã.6¢÷š]p7=´¸×ó1©Èla´,ûÑŽøM´ëË韕{ýÂÞzN@þ!ÿçåÂÙñbÇ•_½ûØ™ÂÿEÄxNtS…ÚŽ’—åW+c{9°„0ûºâ~דZäž®»»¥OK=Á¶IGÅè6š¯ˆhb•½êïç½/?c´ ˜‹šÑ›¸ÞøÍâ·»]«WÕ‘]­ZÔcä}Æ"|wQ—æCÖ~/}DíÀ…×czzÓdG¶äJ¡ä ¬ *eʤoúc”Á?õ[ávs¡Ï™ÐÎ?›ÖÌQ˜LŒû…o Œ™y£’]|råºìþöW'¹ù‡üCþ—'Gš@7ñÕ‘%»=B×TíÆ0L֫𹣊tÝ.™s¬ÿ Ó„:¼`×x>Ö°¹#ºÝEo—ñÞR«úfõìÃ+üý‰@Ííþ•¢sœ¯Ïlzù°D“ñLPŒîÉÈ\4騅öaUg/ÿÒâ{J¾Ï¶Pi*Mvâžzg·QrÆœæ‡xŽ eñ½–®ûbZ[ìЫ†™5ö§‹ŒÉ¿Úi>@ùŸ8É ÇE\ ¢9 È?äòï¼üC8;FyÚêç’û¬ÿ@ØÞ—NwèçÖÇÆÑeÐ?ÚêÉÜê|ÇjTã“|¶Ó=«°×ÿ™8·ëÕRûºï%ËzÉ®Ñroyõ‹¾½«¢ÊV~i O·²Öv^*ü¶W{UÔxÖ]ÌE—¯YÉ\öS½½ù´þ.{ÚggYe¼ü:é1Mo´~ývJÎÂðÛ£W»ÿu1sÄð×o"2;Ý›hY®à‹ú¾1Ü[›ú½kIeC*ðRœ/Á›ü5ÿħûÓ6!äòùw^þ!êÐZ¹á¬Qâ7£Ìõ²Œen²GΔ¶CD¯Ùô‹ý·L³_îÈY°asåšÿÞÜg™¸­{—“YyZ{Ê÷}àóé‡'èÙâQË/tèxäè:zÁÑ£o¿­äÙmÓ‡n=§ RoÜa(j{ 'œ¹hÂ~ŸDÏ¢¼?ƒœì¯´ä¿[ìÕŠûå’éJÎɑշ° ÛìWœ,Üz¿Dyßò+¾¹´7¥EgB†Ó [Ïm}óÊf¹4´¤ûé­”œ;] RüRßÈ™D¼ i:8`ôKiDÀø¦ôœsE_šì˘§­RÝÚlêNþüÍ/[Þòù?@þëÿ,3gAÇlÑå÷ÕJ»²¥æ¬mÉ$»eð4=8ƒLÃÇ¿ hŸ%½h¯/uE."ë¹¾Vð›”{4Â{6—’ –‰]cö)g*êí¿·ÝÃm'ÇQ,Èø?[ý5VÈq´Ç´{Þ–‚£‚Ò[.S˜Dey_w½Í¬<¶d^A4ùŸ¸S}^êS³IÏÿêI_š,þ¼à`%{Øîàxòï¢É®šÃ‚1/_µ>•j%ÿ¿­æ“G¿yÖÈ”nÕ§W¡!Ux¥ÎuŠlªœ¸òù·×W6@þÿýüÛë'DÆ÷ÃsûìSfÙdFç¦É3Òªè“üÈ"ï¤GK?ȵã_rù80î\%GÏŽglï½jhcÛ’úM·æxȹî0Y²64è‹ÇËÀÖë7Õ“ ¬-ÿ‹ç_†¸ØÝV$òO ;¬¿||ÈU¾LæÂïÅ~Ïn ù:”î™så19?ÿg"öÛ±þ %ÆÉðú§ïN¥ÿd=ÞÉR-߈™}yAºæ¹½6Ò÷÷Œ—enïÌ¥‹y6©ozØ5ÖóGSú÷yý’ ©[ó.é7CÚ üCþ!ÿVyÎÅ¿YÂ9$ü4;dñ0ÇÎÒ0 nÄŒæ» ¨“VP1B.œùáº3 Ûn4ðf%î=‡ âªz FT[ÊÀÔ¿K¦ßëÉzaè÷ëˆC£ÊV±ó_Ï{تèI²¥§UË»ÿÔ¼ûÁ4í»)MÊÜÁ*o?O:cá1|ÒxÄžÝmkÚÛÜ Ë2”,Úk–K¯êc}Ň]÷'I“¿œlØE-ùö{ô fìöŠ[›©Y™ÓÝž†rLú”©ƒ¼–žxuвɞب“ù—ö{oÓegqç¶¶4&W¯y{Ô‚üCþ!ÿÎË?„³cnõ³ó¡_üø£}IføßlVQråÈNÓ³dÕþ?ŸŒÝÔ;M¼™KÍ ¿ª¼>ƒ½ö±®ú>-{¹õJ1ÛaÒ‹Ì¡ŸŠó™Ý˜hé —ö“†¤3и{׸Q= ïÇÊ”/¾ëÀÝ×…¿zÖ#×’Mò¤¶wZíÔ$Ѫ› YòšÅ&BŽ* ÷¾ÙuKÉ€ÉudnÛ&e éÂíŸ'ò0JNüê æõŒé9}]ºê¸³ëËøé6µåаf‘j™1é{ùÖï¦ìƒMM6òù‡ü;/ÿÎŽçÑ~ßTñz2O°ÀŸó‡ VUô0N¡Gôä-˜Ï'hgGwÿ}úý!Ký —ׂБ¢Œ¥z\¬8\ô‘Û@¦ÓÈÈÒòøËë^qÞŠbâ²,ùŒ†b¹?žëÞ„åêkœŸöÏ}O}\Qx»ÀÒ%]FvúŒê¦‹G^Œiʶ͖Í/½VcL{\kÕa{Zî£@Ò‚LýnìÆtáOR#Rw?̈Ê1]›šs¡Ñ¡,ó zt›~fÙ^'/Ž1&û?kܘ ªjcvŠBþ!ÿçåÂÙÑÿXôûûÇ^Ø0pLøƒUÿÕ%ã=îî6 ±QŸZ|Y´gø‰Q JgÝ‚²!Â…&(äPÇê»Ú;øRKÛÙ6¿Ó޲êÛ?؉çáíüó;ÿõ}t¨(éPË¥Ùö›<»¨Ûó=ƃ7DK{FÝËL9F‘ø2/aÛ§ÎDD])4ÙGüƒH,N[‘ý¡\´åͬèÝœ]þ7mqð¾H¥ùcÈ%á§=Çk‡ ƒ¦š/wz|òИ~ÕÁÏ´˜QÏÅâ3„üCþ!ÿÎÇ¿ý ˆº T&­Eè.œ#ÙªuôóÛGùçgk-w„àÂY <±VŸï6½Ké_š,-ÆÖjkÓb]+âÂW«õu€D€l §>„gjXZpIHS’ýhLš’ã5@ŒÙ¾8**4IÁ ‰Kärú×?pLnXLêK¢’4 !5 +—Ê-ª„Ü& 0åƒd¥ŒÀ¥†ÆaRòO‡ü³ò_×ø. êðÚ¦ø9+òUéBÂ÷Å‹RVUèôóV:¦Oy.ùZ)'x­Î©•>Àb£WªÍ#Fœ‘®"Ø_P^r"ë0$:I7~ñ•šc쌟Dκl“$ðVinM¦¤¿`€z?i€„„R%7Y@`k “Y$­ €i”“™@¯Ñ*¤ù§‰Cþ9ù¯cüÛ½ç¢NÔv(4ÊoCÃÿ¶­$.Š ,ÈRSÿÙ×§ha Þ…ËtãžœyÏÛœ^ }€ÅÄç©ÍòŸ¿)…]ŸW&³ÝjªÁ¨0*K+"4‰]Š‹"™š©L›¦fXuá™ÍºÇ¤Ô–%0‘FeÒ'çüV­À€ÅXk %0$.U#Æ,È¿­8äŸÿ:Å?D- Ð-CÄ$$ñs5ë“ôɶƒúTIÌüÍi†ñ°ÀZè,J˜kµb Û»B˦ð8<˼ú|a† Mà4B@‚$2WAêGË“•r›ŸGt ú ~OЉ%Z…ÑXyê~ ›T€¤* ÙûÈ?äòï¼üC8;pÁ,U)›“Ì€ ÃB×f¨FCú”w$9ä)€1Xr©‘ M’)ÞÛ@þ!ÿçåÂÉðXŸU¹œn8ı~™ùI6ó\õiò‚ÅI¹–¯s#®áVºžMX-'çÀLM‚Xº¸ !Qå¬k½ ‚³†a"Îר4 „¡6!@ŽÊhy9–u~@•š,êV‡ f1¤•0&.“’íÇj5ªÚù~­{ù‡üCþ–g@#q¹á c6¤±ýÙÓ§Ic±¾ë3¬Ç»ÎXĹOg–GÈ–ÙN¬Ñ¸À5L!:. ϳkYÀøyFãfj2c¡ D®ÀA²Šêd bÚ”ÉtnDD«ÔéÓc€ì}ŠÔŦi9ÚoÈ?äßyù‡¨¨uüEY]Æp$Ú?7GËa!»>U”ó•ЂvÂÛÄâc£È‰ÃTY¶'nÈõIŒ ‡!—|/¹Ò°ß&IX|fÓPΤÓÅÄjÝ&š¤¤l2œbØÔÏøc¦Q#˜D 6—XlÁ HR8ÚoÈ?äÿßÎ?ŒÿwnøWgüÙ©˜õ@æa›S”[L:ýŒµŽÔ€0) o· XºÂî&@Bµ™L'n.ŠPgØè“ö"Ë#Îä’D¡ˆW&³ö=H·P(tïÐX»†*m¤í aÀCEr5i(.@JD§ ëWh ÿÿ÷ä¿ðoçË‹u×Úî9 €ÅÌ]Ãè,˜ˆ¸*‹ÓCfØÖcÖ§Ëñ}ò—ÛŽt€Åù¬Ï´ç¬C‚S3˜—!ä{óRhn@€F&'Ù÷Œ‘Ö‡ÐQtj¢œ5HÃÖ4€JÔ2)¸8!Qm¥Ïd»ˆãú%йÕ*¹g ¶:lcônLOÈ?äß^_Ùùÿ×óOÿf„sA¾¸8µ¶§q-’°}ýÙÙædz„ ƒ¾#õëNÿlLg´3ÞÂÒdN} Ìds4B‘ŸH)X´2ÅmI€ðÓäÆg¨™Ýh¸˜5H¿ÐoÂaˆ0Éâ$´Ò¦j–@}ón@œD1˜”Ýè–iÈ?äß:Ï©ø‡gœ¸È?ºœýÂ+ô½ú•žäÄRZ˜©v`á"¿x;õ  *aå KEúˆ–³ ‘ïŽB—Y7౸#IÊPJŽ&`©¶ƒV'€%°Z&Ã@¿ ‡ ñD³ ¸Mã qÀëô@š™u¬#‚(Ç€m äòùwfþ!œç——Ϫâˆ~‚WvEŸœÆÆ,H)°½úƒM?w%Wý,Qæ³]ûM¶^ÎrV}Ýaá•÷}‘úÂð¤t‹l!^ˆA/^Eù‡üCþ•gÀ¢ç­wä_žU?j¾µ> P~PÌz®àØZÕ¯só­ÉR³qS:‹>‚yë¸÷óȉzàÊd“±"b–;âÅ…h²a‰¢Ó5¶n@ ³F™ú q„Ÿ¤2è UÙ~8´Þ™\€F}±H’nm¬?bß@þ!ÿçåÂÙÄ¡¥Ž8½Xõ—[ôõg²ó?] Ä!A¬õBµÐtù'›~¤?Ë• äâaN±ÛBuîʘ\S°. Ësd9ıƋÂ@‚t½¿ã'²¶Ú¼0è#H’áJP¦kÀv­¯ýÐ RV§‰­O˜Åhe¬Cþ!ÿ'æÂÙ }±R‡¿ìɤïI¿ j8û³1µV×KáBoÀR¿îôOü:‚‰|¦+AuÛ‹ö€D™†+A¼‚ëÛ^f4:Me6y’"™îÄõ®96m‰Åë¨wú+A™C€˜v­> ¢ÓÔ/ƒ2Ÿb3È?äßùøÿ?øà=ðïxœí]w@Gû+1]Qk,_Ô€½$ˆA ŠÒ¥]/»³× GD;–ø³ëÏnì¨ÁF°G`ïÆo¸c÷n÷ÚŸßÎó×îì<3Ã>;/ó¾S®ƒ÷pãû–ƒ66w”/ü;xÄQþþo0ì›=!»ó»|}ñÕÞúÇ4X×Âü‰¼²c¤ŸW;¥E~ÄÍ÷åÁŸ'4M¹ôÔSWGn™ŒÃëü‰Ö7Ý™Jì=r!«©‹Äj‹…¯uÝ6©É‡¾ºW:qàRßærx†Ä¡%ËièÚ¥eÆ;naKŽºëͧîG/?:)4kmÓû9">9ég¹¹ö.‚5tCÅ‹I#U7(ìÄŠþ†‡±Ç#†Õ\ïŸRè[s9̵K’±¨?ÔêÏ\ý!˜Ž‰³ –f÷^ï(ßû· ®§x¨Êû‹SWG6ÿ•bgýuæ_à¶Á4ýniã‘¥·ëN¶ÆïƒÔóuîÖì95T^ÿN¾SåV«wJ~û4ö|ÓùÓúÖÙ¢°ÞàÞ3\eɆ;2³¿x¶O̵1:¦³/ËŸ†íæÇ{’O°2 zõñ¼Ën–·ö÷ÓÜNXêѤ”¹‹vMúÂýĹ¿¶s͸Uv»¸ê¶ý]ÿÓ†gc.m¦14JRѲæ²Ç .jBP¨?ÔŸ±úC0§/mÞÓ_qÒ†OŸ—÷‹ß>ŸÑH{~@Ç‘ínÛÍ?u5êÝôùgÈ£_q§.¢þx{Þ:?×ëõ“º—þJ'¦Ívx Ó­ö2ªŒssڣ˻ìä2·©Ÿ #ã/·zÝò¾V{?ÿq/UÛgêwõ½úØï¥^OèL:°ny%1aðþ²mü¡}uk°+=ÌÚv ½½‰Q8¸«øážst@—ž‹w ª^À‡CŒÄ;§·FÏê烃.×\¶žÜ•X"Ôêõg®þ ¸‘çÖ"ô\‡ ¸ÃêûWt_Õãàâ²õìfõ_Ûu9P¸¡˜ì2!-$úYi¦ |ÁŽe†w=YBèí>ÏŽ5<ý©Ô¦ú°Ùm¦f•î<À©À†ÜNûG'SܧNßøwtØšû¨ñ¬VÏKiè]½°O¤0#òxFçÛ¾ßÚö×rÓÜNgöªY䤇Wïú%îûe Úò0£§“Þ„÷]øÀø,oüÌS†ëN±5—>J„úCý¡þÌÕ‚éˆUõ½=íHƒ'Žò#Ÿlý¼Ã{ì‚ßNqˆ­â§w~÷áymJ‡KËýÜ®Zàé¨òiÙ±l­«1ÁS•–Öuç!ëÓyÕè‘1k^©vçÖ†'¬çE¼Ësœ·’< äâqY—å?^]V}_çë;g:~|s»•ä¤8y½ïÎþèºpý3ƒõœµóp)yz¸2œ˜÷ÏîÁœ•  û5ü^ÝêïÆgžË„®wM^?›¦MP¨?ÔŸ¹úC0²nÍáõ8›å»§s‹ÊéXÊÞQlG£ˆ}WíÜ>pÚàƒÕMy{À€N¶òo÷z5búÝ5·îÿ¨¿Lj˜ikÿÇÐ!‰É;r:ͳ!ï’9ƒ:å“Óâ¦;_ kzü×™UQL÷zǶ§{•új¿-0m˜ßwʳ‹& |lêïð6%[FN>ÚY@ –¾ç^ùp±èfypÉñµèPvÓøìú'÷ºÆF.½NøƒúCý¡þÌÕ‚éÈê¦@ õ‡úCý™«?ÓÞcqS¯Õ~'í¤ê0§óWÞl9&¬ñ”å¾§¬S¨±À½ïdaœ×U »þðóø³_“ íóF&_Ýn{Û/ÿbØŸ[­v°‡\þãÓG·óÛ7Ëò²aPðìfÙŠuN›†Î_s­ô÷´…-[\ø³„Ž?ç‚äþ Š‘¢~7¦º.~¹…˜ÊÎNü-•œ‘•÷íH7bB£|ÞȘÿOîIc†ïÓ¸nÛӞƥ¸¤WË·†ªïO–Gÿ—Aý¡þPæêÁt´ù3¶à»O‘:{8âmcï«z6^¸}NI›?eÉ­_ÛÇ'â›×£N4y•Ô¦ÍÉï¯È­o/¿Ì›Å^×ÉÆµe §žÖÚj§É~É}ܤŸ6²Íœ¿-æ\ÿϔݛQ= ï~\]Ù±ŸûÈ+ "ž|¦ã7«—ß›ÂÀ0?ŸDÖ³6^H‰þÑò¹äŒõ‡ú®ñ&&D×û7x z]_%yõèí¥ÐôAÍŒF,ä@ôÈ5×¢sìÿÖ.›êõ‡ú3W¦cáSOö{NKëå7 s9Y/fƽ4=ÿY̘Oq­®ßۧˈ¹vEÌhòö—­vÓÅ?LxÐðÁë)ÂÞ¬î}±‡9Y.ìô&üQ|5ïY”" 9GõîÓÎÉ—ú™gò™À’õ¯ý.þÝÞ%0mÛ†‡T6¥ÏSd@£%ÜÃ…ñ½s³?ï^KÎ8”£È'½œƒ™Åïñ/,W>cøyñ-GkW õ/)ö2ìZrl•‡E§ êõ‡ú3W†éßrô½ãzÙšŸ´¸GäÊéçÍïUóûµéèÑÛÑúù=÷­óÿÜyoYÛñŽ UÛK£œ<ún¾cyo‚EC‡×?>l 6êýÚÂøMòËô> gǵ¤ïÒ,tB_×Ïßqáu‚›ÇÔ t8Wn¶†ŠÏÛªð•uÝòôë¸«Æ qÚ„Ó71¦÷ÁkÄÐzÓ#Æé/¢dS|ÆÄ{z¥¨öP×rç?2O;wÞ²[õ‡úCý™«?Óx"’Ý/%m›m¹[Tºkζ¨ß`O¾á}R<I±¾’–>sÇíÖ½^¬c‹‰=žçLtþéÈ€÷Wía±®'oä\LJçåÃ{õõv}>’vœüb§ë§m´'“peË_¶|æÆj~nŒK-yô’êÉåÛÞäx>ó¹x«´ë5ã˜ÿ†¤}ábrƹ æ!ˆ 3uM?¬¨ºòîØ­}Øç™ kw )}f]1\÷xT—²êZ@ý¡þPæêÁt¼ô¨xõûÆêÏgà©¿n÷›±u_Õ;BX6ô¢ÿøìÜÆ¶ð©Ûë`š=gÔ+ù ¨§tÛ®ö¿Þ·‡$Š\ú8p]{ý%ß{ëÙV¿ó{\§Éz3nʧôEÍ{¯™P©P7ò¥3uoî[HeÜ€ÿ›¼‡[‡ë¿¸aÿ[ᆨݾ©·’sžð,8ÜŽÔ¨Í+fWÏ—¢.GbÆßžÒíñö4ÃÞ«{Þt4ñq*@ý¡þPæêÁttø7DóÍ:ë+Ñ›ÉS6ëß"”ÔÛ]ñ#Ú䞦£Y†—lÝÎ/%·ÝÝî9¸›X öX_\ú¡±‹?t^¹Ï ÚÊ«¾™ŸBú þ%ˆú<Ðߎçç~²87éºìÖ‡žZÎþô˜r>äú§vó0äyè¼S[ª›T[h&Áôd•Çê¯|Ò#?ýÐnÍù)üÜ}˯5Y¬ël`nا™!ãï#­sõ‡úCý™«?ÃÁ¿àš7Ø3å_+Ù|V5=SoëÆ6 ÷ñÏÔl8£«ãHÝ+Æ~Ê)ÚT\èâãL8zRÞàï©¶[°ŸP¤Â¿ÛQÿ>?®ün³–"§°é›‡ûÊ,u†€A褽áꬦ|üéä©i”öåŸ»Åø0>>¹]v‹‰£÷®ÞLu6ÜsS9£øyhû4RŠbÅEC™!a?·Ï*=“ù㕚ÿx•Ñb™ÿÒ¨9 þP¨ÿÿ¨þÐÿ‡¨@Y3s–+>´KÏ_‘­ç„µhE¦ZfWYôõ„㟑¥–X. lßUéæ|¼\ÿZ©Õ¶”–’¨Àk°t­•Újj”k ù†cµZ9‰Äí[@ù yí3œ/â¨T8ˆ0¹Ù|#cr“‚TJ*€ŠâtJ™“Ô4ÔÖ PÌø*1”Ž`„×õ‡úCý™«?ÓÄÑëRíëµdþ’9kÓdxÿa`E:… ]Ȧú(.`MªuËÄqþEɦ|€°æ¯µ©;cbÎ✼O‰¢t ¶ô ”/H$t2ÜîÅ¥¨eѦò´íb‘ŠX Îrµx*’›¿T,5IínØRµRZó§D"¥4(*¥6P¨?ÔŸ¹úC0@°(l³ÎñoDnÖnxøÊtµÅÁâP³úF,Üd‹]‚¨ˆB“±>@âB 46Ù"€[n†ZŠD+’li=Ƥ)H=XÄ$©¤µ…ô®"PÇôEø¢¹EæŠÈLÖ#½ÜD¬–×X²@$F6ÉÊ„úCý¡þÌÕ‚á€;-±Píø±(wšt½`®zu‚ÜÞá¿¡þ”rýø z!¶Rc“9€·H™¥"V ØÈ•¶õ}]‚hyŠ”Rl27H¬NiÒVKª“×Ûv‚iÜ®6³‰ wAPO¢‘‰eæ$Š ŠHI|Ü# |‰J^mP´¶ÏÓrÿ‡úCý¡þÌÕ‚éH¼_Þ2…}×À_ˆaù©*½}ý«2I£j„å»2SikFØ3×Gå@“kmòÈç…%ˆ•é´½–˜åb¦Þ>ªKÐÊÇè­©™€UMãqÔ¨œâõQDQTF6?&EE|¥Ï(!õsò Σ5JP¨?ÔŸ±úC0@5o½Mã_J6Ê\„­X¡Âý€hÉ\Â4À„1sÖ¦Øn‘€(vöÆÚy9 Žfe«lwF&fdà ò¢ŽÙ‹¸a¥¨j¦-®2wªù¶8Ã|ö”:(%|È/ˆP Q胀4ÀÒÄÔêõg®þLàÏÞšàHüN?Æ @rÂE[tñkêŽ0Ö?,d}'¢jƒ0‚“kâæ„·Â¦Þl䣜™Ù¶80@M±.Iÿĉʪ î"(éW¡æ@UPÌéRS ÄÀÔ ¢ˆ„üb€7EˆZŽ[ Ò"`ý3Û Ôêõg®þ ìÉkÔö!ÓïýÉÊTóãŠA¹Ó—åVwZ€p|3VØ·šH?e˜˜Q2Â(Q–]ý_oTˆ.Ùúf€Ä«)Â{x²Ú*>Šè§.)€ª·(ŽNPËM-€yÐ| P?ä×óù2•>6HZ"„¬åP¨?ÔŸ±úC0‰õÏϰ{TíýY—¨”8Æ'Ô7kuºžDñþi¶NÿÕòY¾ëRäU0Ë´o[3†¦+a™ r+AL¸âDª~¤ŸŒMRË$Ë+€(€ªÂV%#ÿÕT@Š)@¼“ë§«§É»€j qGU þP¨?cõ‡`:€0,xC²}ßÀļððœ¥úM°ŽðÉõGmL’êÇïAEI¶,Ç1á‹b‚Ö'È$@.˰³ÿ‹"u:‰˜³ÌÚ&@—FÝ4ľiýAñ›´€Ì-´é8ÓÆà=_¼\ƒ BÕKísD€8Z‘¤?Ç$ISZ6’âèdºØ"@Ål SHE\ +€P¾’Ú~ "L†ðš< H”˜€ª¯ŸFµÄ]@ö¨?ÔêÏ\ý!€²Ë\iûÜ>æå.Š]•j˜¬³—OUv†Ð/'Óöý;d>wAZ*ªK³³ÿ#qHš~ò£-M”%§=[L¤g¼J+áªéÝ Ó8¨H!EÄ…ZFX±Æú4^õÞŸ¥ËM‡Ë8_²Í>u¡''Ûx€7U€ÀÏ^fW^HŽa÷>„Ž•¤(h,î èè—÷TóE,‰ŽŽoÉ@ÄJiÕ4Ó÷‘›öYº)ÀªüúÝĨ–°—ˆlä–Ú^êõ‡ú3V† ñ¾Ù+¬¡õz¶6ÉìS×óýeQýT¡ß*;—ð*çäÊeÙBDÁÙB“•¤£>Ï l‰•ÅI¸ .ÌÐЇNë`¨°êpý4"W¥4ð©"€(é§@1’¨šä)j”tjƒ]†úCý¡þÿ£úÿx÷ø¶[欰æ_ç‘ÅÝ'–R[޾«l£mì”ju׺« -|î^õàîñ/k®_œûe>çˆé€úCý¡þÂÕBè8’9:lbðbÀÈ6OÚ}öqù‡kj¿]92,2¨ÄÎ2ðÀ·MbU–Üeû©ç»N’í54ã¡ÛÛ_Wù/7‹î\î¿ûì*ÇH­ÿžáß÷ÝÄú‚åo-‹ï$?üà˜]S§_%kÞçînæ…êìÍõ¹×nt`øo;ã»NÅÄK‹\¸FO~}Êî6·øÅÑ9&_f,´–ñu­¨²-†é)®»BG^|èEÅÅ–ï$;2 C3î!Óõ‡úCý…«?„ÐqÌ#Ê8½XÃV5aü§nÛRߟՆñ¿Œ?7¸pLN'pÛ¦ïWüî÷¬4G·þžÕZÝ?¿a|÷ Ñ}Ò#²–›œ;/Êsº¢s„4ºO[Û*òl‹fÍ­>Pº§ê“\ZÓ .£]ð6óW¶bÊÖSG‡'Å¿(½ZaW‹ö5õöc&ÚìÅÀ]5£Pþ:gDʤ¬™±ÿÆãû=ƒ¶úК®(7Ù”ì?}³þRôÓ:må•ïIš“&Ø{OÌØýœC¶Ôêõ®þÇrQÀ¡·\þ±TÿÏ%ÿù/èW™ÉÂióÖ­=¹·Äâþ™èÙ¤0ãiv‚£ª&¶÷Øý a£öìù|Hqß—)Ä,·Þ¬Kóèɧշñ†´}”2à”Ñ9gâÔœD=¥]âí<ÏÏÌý5Â|F¬½´åÔÕßݶ=¼²š^}'ÿzÈzF ÒÊûç¾}k?GDµþØkx;UÛ½xöˆ¥ ¨-c×–‹fRJš^2-µþÒc«vCåP÷=o"®ºœÝþYç˜íõ‡úCý…«?„Ð1p‘ùæ—®Û˜þ8‹*“w}6¸YUa‹?Øùýïi~ºµ-Ãኒ*kþ½×án5—®º¾wŽ”æ7dÌîš{]tÔ÷ºvõÉmóð’"¿\x)ôÒ}Z©R¯:ÑãËÛqm)sU™sjò맸û;wwÐùÜŒÐÁÝ•ò72RkÑNÝ£ï0:øæ—æ^³^L‘XmJ½õ(ñ1ÓZ:÷q=E)™vóƒu6—7ÎXÓÕäþ¼ª +q¼Âåå{Á\f@ý¡þPáê!t$Òâý9våàXܸ#cï¯,Ë,Jââ'½r²_“yÜá²zŒR_=w¹ë%{­¢‘cGçz‡hñ ?|®4¥fÊ)?éÞyÿÞ§™l.Šò1­eퟲ+_vqÐk¾??xÀ¦¬o‰¿«»„»¿¨ˆq¦¾Ãp||aïcÏ$’ï^R§^eÒãfà ׎üZ×sÉ8˜;FÿCy¸»q'}ÏÈÁ+÷|k[ *,;i»®(fòí[úèùæòñ<ÒÛ§!žX- þP¨¿põ‡8@ìí^7‡æ|N+ž¦©‘‰»Üöõ n>¶ÜåµÇƒì-#ŽþmÞÞeF¯%õq,YP¥ë/…S°뱗Sï´ðµ¦ýBÆd¿w`MB9k³f”?\8™?+Ÿ¡fTw³û½ÉÚ׳êJ"c _jæYØäæw~+Ñ{âæßœ-ô Ä‘VÍ2ïþÅHœî" 𮿔íÛѹGÓŽþ‰E´á3W_R¾V{°ÀÃö‡~¸%ðÏ™²V5ó»­j»ù;ú*"õ‡úCý…«?„б´µ«¬KóžmËäñ?&G ó5çG"=ÏŠ 7>ŸtØ·Ûan%k>îðkæß4Û>.{u pÚ«Éÿî³ñÏG$õ«Ÿ'íZü&'kÒøN ÿ|‡)@®ˆ²¿±ËMdµ(`Wß'[/rnÂñ¡Ów(LGÉOÓ>óù£5‡²mª/)š!ÅŒ€dË•ñ¶×%3šž¨¨Ny¹[­é¢ÅN[Þ ”(OW¡Çm®Ã>º­X8¦K—O$ëÇ>)/vÐo8 þP¨¿põ‡:Úo^] žc³Ü´w÷Ãà9¾²ü˜ð_/Ï/º÷‰g"oCï–eS><Þ£ë3jñ_—œß»×w^63‰†óû¿Z‘Ùô¹Íó9ØÒî“—½ws°Šw Ý·ƒÙ–Iæ÷oøÅkâ³Ú »ÝeòóšrrÇE~®æ³_‹Ë]ü*r:L«ïyqkÏ}fàô™Ó®÷(%£/y_/Ûþ°ûUzðû·2~A)9±hm?™÷w‡ü œ“ºþ;tâUý\D¿o þP¨¿põ‡:f¯w»9Þ½Úz)êßrK‡ÜwNJÄW³bÚ‘É£Oôpâkæì R¦îΛ~¼<µhÖÜÑÝÄÛ?+ºµ?äGÊ£¼ô^±â†Kç)¬¬Ç›ž…¥,d[!»¨¨ÉðêÓƒÓvX®&ø`f5ßÑ"»WúÁœ^{Ñ{Úkzñ¢{uügB:êÖ3®Ç 6u8J)BŸ*³¦>ñœñ -úçØÎÙ¶K~pÌ¥S ÒæzÎ7}£¸ò¾Ó°þº9/±ò— žq3êõ‡ú Wétríúa-jÖå‚{œ‡¸SØ'‡g…¢C“X}À“^œÐðV›®çµê×ËþجØV—ÃŽª¶ã¿“áJEBÀ>úêš&­‘ýà¤g³ ýŸÿzz“bÖ^{þÙÿ¡áÓî×H !>1ôÝymŒ¬m-X:j•öͺ­GÈYçûûði^}¶Õ(œ¼üà #sÈyÜk%møq+<>½cö•ñç(È£ö“¾¦”,P_|füç*Ú¥-ŽG%Žj{»`ìqDßÁ…{Ü,€úCý¡þÂÕB蘿ùZ—ÃÃ|6 ½ï´;`Z+Çùžå¡™s×ÏßÂÑ$ÜðpæŒç½U~L™± ‡b¢&~ËPe àìuôú•]mÿº¸É¿ýëϘHăòÅànMšŸdïýêóƒÖý]ê©ÁÓ_'º.ÙÃ3GûC¿)ªÂ.uwz±ëó¢Zã体‹™7äT‡¾9€^è3à©ÛìçÉÍÎRlÔÈ+©ƒ¾©Å— ²¹6 <=‘t[æõiiŽŽ~Çym±Ã€úCý¡þÂÕâÕâXÄŽ7›>}gú„û¤b_04DÝÝXzæéÑ+ÌÕßyV¹Muªfâ‘ÀzåF†Þ `¨ÁªCÏÝ^Ñ¡”‰*YèþxNsívíÔ«å«ðk«•ž˜Ì9 ÷fEu´­µšs©øÈ*·žÔñ7v4}ø7#sÙâ{1Óì\ Я_ËUßÅ:Ùž=¢ý»÷jXõ³ªnˆmR¶MÚ¨wH_ô<8üø¿¥™ þ €úóêÿ*è7 Á¡ÛÍmQQþçÓШ¥W?Û?uI}íFùÕOZÜÆv%8ÐäBˆ²ð¯ù, ÐÊD·ð6+/rcüqcGÏ6i˜ê¢7´ÌoSùnO†ËâvÙJ)‹¸ã3¢~Ëtua©êRÌüƒî<§i(^ºÎžKÙ:ùü”µcÍCÍeÒ9ùÎ}Xöæ>Ò‚®<`p/f}ÜnTè­‹ Ï]˜LµÂñ—mó„º6jÞ£¢8³LñrÁ9¨?Ô¿‘€úÿ÷õg^u!|$d>{ÊH·çŒù°ÔýŽGæøèÖšøTÄmk_qýÔ쌕’çžsÂGMάd÷–•uþ¹¤WÇÎìw—̼èÓdpæZMøÈ–Š@»y‡¬Y²ï·c<甀æßœóÉzT²4fnË$¾SÍÒg,*Ç©+Š;ïšJ<׾èùÕ}3;ˆÓ쬛[íËÕ®÷ý:­{‹Õ}ëS|1E VH)­äç'åØîFÒ'|Xó1\Úg÷A¨?ÔŸg謀úÿ÷õç6Ä«nÛƒ[üëà{±ì1áo;)ãC‡fîú¡üOÎG7‹ÐÒkAh€}1˜Õî@ï+#Ÿwz´·îlùv…3ÕÊŒlÕ·ÈæÚoëÍ›k?ÞÆêõ‡úÓŠ…£0ϰ! p€D,ZŸªæ|8"]¶lE–QÛµˆÈ—ÏÜ)PD¬OÖ ‘>Å)à=`qó6˜AŒ×¦$Çù@’aНkN|5qD–‰á‹á8&ó}1bˆFl6ÄÛ¯B²ÔÊtÆŠh-ƒUHMºZ>¦TÓoP ¦˜€øú’/IÐÕÝŸhݰŸêõ‡ú W¡È"6'Æsüm¦Xî‹'i™ÿåòÅáÜ|–N¥Á%‰j‡—&4˜Oö;è("crŽò2,1ɶ1ÊXYšž”é:žn1…Ò€IIºx& ”JóÀ€h-³à*CL‹(ª¥û QQ§4@q›‚¯Xn0hj-aj þP¨¿põ‡:0Élý&ë*IÐò¼4ãSr ?q;Ÿ¥W4ö‹œäô@òEZ®¾Áï¬"{(!æ2ñ˜ªËÔ1'{"Ò&Ó&¦ˆÒ˜íù]n0òô Ø$ ¦ŒS›4L„ÝÀÚÚQ3X)7hH  ¥·ÇÐøx@t¥D•ñzMÞ`S õ‡úCý…«?„ÀAüÓ½ÖdÛýój+qT`(H`~ü·òó³Xø, Œö)H«™uäL.Èh¿æ®Þ%Ç bß¼d‡øFÓhs’ø†²ðT“†öý&A“x&áŨõ*âŠ5Õö¿‡€ :«ÅÄô$Ÿ)ˆaÔ Ža*Šƒb*Dª×©kKUÃ}1¨?Ôê/Xý!„  ØÌ:"fjÜBtm Ë™—ÏBÀäaÁÌÖ™”‘¾Í ]SÙ¯¸6p”1E ð#É´³d02‹îà`ŠètæÇw¦BJÆ0*'éí$v€è\]_Cðå22 ˆ3EQ@ë*5¥®Â2“Ö’l”€úCý¡þÂÕBè2oqY‚}Žx8–Š‚SWÙ=Ûñ}——%8„#›£_U¡©~Æbò%Ë×›æ“] ÑK ­kyÈåDòNUÓGæèBu@«LÕQø@)JehJå¡qF2I0D‚&jéi@Àº¨æ Çf$øJœ!HORÖÕ8"Ç –ûWŽŸNÔêõ¬þ13W"¿„oÍMã¸\Ê]€+£ÃòLœSÈ—f°í6Ǥק\dŸ+¤sÈ@ñu|™4Ig›$ªõ, (1uš|…\íó“N넾ˆŒ¢Ba$¤¢ÅÔêõ®þB&…o1ÕýyÈ1äd3ýÁÌ—Í—ÙðÙ@<ªÏK_m\@„äóíº©m+­4P›¢Í2pð"<‘ÝÂ~I –b5v‰LâÝ×T³Èz!b`›är”𩲤c’íÏ#áMÖlüµðQßèmÀP¨?Ô_¸úCä©9¹µi8rgLd ëÑÌü¸¹+Wò¤ñ,»òÓõ ½’ü5Y|çnXZÊ—¡+ìº ¸—¤¤pìURFj¸Î˜,ÊT»×‰ø-T¼'›4ÖT?\âSÆêÛ´$«@YTÇGÄZƒš¶ˆ1H55)A@.DÒêÕo¤€úCý¡þÂÕBè¨È§6 GŽå¯N74äÏdÃgm‚ÉÃÖ'k 2XœÌ›$õCU9 ë}ˆ éµÁ.´hÓ;¹«‡˜Qº%ß €TœÊ;L†Ù:2Ä ”ÅÙ¤ÙSÄÛ‡ ¾<.QGÛMlŸ¤¯²îû©M#âªÆ¾þêõ‡ú WˆW Ñ€@j9Y G¥ËBñG°ð—.å< ñÆD6«a%|ÞȖ겘 Ò»ˆ^Ųr—°âLn÷‚à‹%©–£Éá¼+’ëWÕñ©ªu6oeL²òþP¨?ÔŸ^,ýÿyÉø,4xœí]w\Gû÷5–˜hD{ïFvcTô5£âÏ" *R„å8¸~»;{£íPÀ¢1°{ï±ÄM,1¢±¾wG»½ÛÝÛ»ßÙùþá‡}¾3s÷užÏÌ3ÏÌ5À!XíQCŠöK“;I]rôŸ‡øºÌ'w–¨ª L7*¥ëÁ,•Í‹÷ŸnîJ]õÿ Jºì»Â¿F¤>çô°v@HPûN\ñþþš ;|‰ámãG¿‚RƹÕÈWÔñþmþâ å€ÖOõã, ¯…|)ŽI]Á ûø7î1S¦_:k½»¦Ú†óæTÚcÝÔçÒî ¡Mºù“G¯ng\4¶å1w¿Üá¾攋k»ö_ö¾š ¦*÷‹%˜}ÞÄ+*ßâ9ßeǘKõP¨?ÔŸ½úC°‘^ï'<‹/»àuZéÜY·ð¦SÇ=Ûè ß Ž·~ëÜAÙ7…áò/^ÇoTuÞ`»2°†¿ß¤¦x—ð·$¯³KËw‹¸Œ¼yô`¢…é( ,{5|“ÞãØ¯®Bìâ)«è— ÂctÃ÷‘½H»:àúó«[$s^Q,¦½µ=Ö¶ŒmÚ:eeXÀ“¯6;»¨ù^sáü Ò[#ˆv~%oXz–Ë:޲p«P¨?ÔŸ½úC°}6Ïë¹5+ÙQžÄ0=Cž(Ý"hö!gøµè2–;êP‹ŒåEnJ¿&·¾kÍ„ÿÞÆ›I# …6/¼½—rUöÓÓÁÎgË(/Ö•x”®o‹qï0ê<Ž«¶d·¹ØlœOOÚhZD“wÉÑ)do¶q}ŸÐA4pÌæò?ôZ¸}mùĶÃp|Âã¤^cÝ ¿­5/XN<™ÿ™ÁŒ»^p¼¿eAá­Œ[–-Aý¡þPöêÁvN!O¹´ƒ¬/=Ëåçqt]˱­8ë¢ç׃Wìù«T4©î?%ØúÉÀvž»‡V0¢ƒé3'uÚl=Iöh9%ø§¼»v'òÂÆÁm»vè±<·æ9p²K‡'Y}v~ÀÓ3¦ö>ôõŽ“4VÓ¯œjt¯;ù;·´IÅgŒzý7ùûsç|ö#)9ëUþ_ã¤Aâ‰óÛ?Ë/gúž¼¼e;Á¬SȈi–ÏX÷ðÎ P¨?ÔŸ½úC°ؼŒä®CbÆ9‰ôPW–Ï<}çöÓ;&~·ÁŽñ-!ójÕ#õgÏé5ü硽í>‘éš"f¼WM«|â6à°³7¶J/+µÏ÷íÒ±“ëävûµæ'Þ­Âe%ö#s§ŠŽ¸œùñyï6¹”VXrÉpmÅ´¹Ñ#¹pÊÂk‘¾þCÊ}ï’Ô9àðÓ¬_P8¾·`Žú‰÷Ÿ y¹+â7bßcó/$?±xæT>HºI¬ êõ‡ú³V¶#è)Ô'Ó«v0&€¿ëuÁË6~]å ß þ¯yîs>¾qÐü0£Á˼Ì.ç 2æaªIM»ÚÍÚFÈõé2&¿I“›Â<&ü–CgfoÊóëkò Ò˜ÁÇ¿÷yðqìdpVie™7÷Éæ›@GeöçÀù)ãvS½åEž8Réz,úH6ÙÛ¡×ò^^$ñGcšå~?×ü×÷Oîx2ôùk >zЧíŸí®õIò³Üòë»}ÆCÑêõ‡ú³W¶£‘´©lÜG_“dšÂÿÑ•Š©×Ï\T˜è ߯2Êwœ­7þùÒåîá»ão\|n—dŸo—OqwS_ÒðMvsñ+ÑQ®È=‘ÿÝaãˆ~%_»¶BK’sKŠ=£Ns ášåß~BþW-(SñÒ㠽˩kñÚØìãðÔvæ}Š[rýHʽwcÛªOó€!çš.su¹kˆ=ØáU/‚Öýxð–ýÚû8Ыº þP¨?{õ‡`;Üê"ãZ<`d‹ìÉ-áŠÏYê¾éœ3|2 Üçæ–ZôN.óíŸò¼ýý?”8DGšþ£—ßìV7nï ªxþyÊÇé ùÜ­< ;[˜‰/n¥~q¥/ÓàãĤñÁ¹J|Zìwk×5<™ü¹Ù„¹œš:£sî\(÷Ëy™ýÚváÔë‚äs íÞxik#÷Ekо›x©ý×5ߤ^E°[ /|Kï“=LÚ`]Ôêõg¯þ,‡ì­þÝÏë. LÇ%ý_Ø\=#êOë Ÿ—íЪ±[šÈFnÜ…Þ24bpœ?·~uÜdzæ±rÛ¼Ñç*Ï3OLö¸z¤¡¯:kÅáÞ82ôh¾}‚‚{+ƒÏT× ñÝïⲃO2ÉÌÆ-ŸöòLGšzÒ.÷Ú‘}vPN·~¶iO©¡îOH8CßøÏª}ˆÒ þ¨ÍŸ ËÝ5<°š¸ y`Ypx³¨™·Ôêõg¯þlÇ,©rsØÿ]gÏŽ/î¹úQ(~Ûî%;áSa’öÚÜ'WÆW(wÝ8Óp†ã÷’ ,˜þ]玧ÌS¿ªø»mns:xXõRר"xëþ¾”ƒLIíÆ´yPa>¼+1xU¾üá¨&˜dh¡#>å 4›Š¼ô=í¯¹%öî1¤t¹Õ;¤qå¯_#!M,Y¿ùëº'¯®¯õï½¾C½7¹[e=ûT4Yþ³e§Ç|Ÿd[Ôêõg¯þlÇÕ+iëÿ¹d'ûµí°¤ŠÇø×ý¸‘ßZY2ãSãhãî)i½{œI¾ê MxÞœ7þ2 °äåÞ=7DP¦äA:{Ðó=×ò½ý.PœÆ±ÅÃÓ];í©þ{ñ{—ªoß5üÛÖw¼p:(]‚TÜámGy'÷¸þÜýÝÝj÷±©Ïê{+Iü!Òø/¾¢~½º–uûZNuþ]«ÍÓ¼¿ŽN´xæØ+nNÒ ¨?ÔêÏ^ý!ØŽ§éozµë½–Î$´Øeÿ_>Îôìk{ó¥‘ß³==Ÿà¤ÊQ\Nñ€üUöI Ù}ñ­|óßTبàé½þ3|´ƒa®PòúÞ¥_®=œÄ”áóæ}£ÝjÝÌ7~Ý*߉„Û;æ=Q¶¡ÛtãÆ%(Þ¿iàýbЄÒmàq´—qºuDBêÿlÃ2O‹gÉé é(CËÈ‘ž©;齪"‚']4¸Š´P¨?ÔŸ½úC°‚]Ï÷Ý5ì!¥v纸‹+~?iïà$sRÁŠnçúì¦áÓcêÓ¿D×âKÒݜݟš—‘ßl×ÁŠ^­ÙãÙ±¤…Ã?MâºÒðSzÓWžL‰R÷kƒ/ «ïØïû<:% 9•fe÷EŸwÚ Ûöc§Ëœ—ûÊ>ÿýòÇ-_Íî8w±'Y(sXæ…²a–K–ô®¬¼Ì;—{Š GÈå~—- ~9s'Ôêõg¯þlÇèmhÚµÒ[¤y,FL?sxoÆÁ—ó¿K~¸ÆŸUm:ý²ºÝÙÒKW˜fàØà“F§zwŸÝnèÈë;[ßv<)xáß`æ«+yoÚû}}o¡~„àLwq[4…èAn}hÇç4õDb»?¼ÃñÀÞ|éÄiû:'[^:í)Öl' IöìJ¼Ð{Rƒ}!ú¼.÷wa‡"â㿱,¥<õ‡úCýÙ«?Û±þ[ƒ|äi)iŽ$?mºÞ¼øî£WÔütœŠOéŒQÍc'pËüq?žé\k`a;Ñv˳։Kv8~×5zrxA·#‹:žÚÄÈÞeñÑÁœ¾–íÌ;yÉkÀ›ï¯Þ·üdýöþ6•K×Ѻë?—™üÕ¢Ä+Ù²áÇûÖ{þhå}²ßYëú`;b«Äš­ú§½LùãfËC#“Sö0ú@P¨?Ôÿ_¯ÿ.;Ÿ â_ ™Ï-‹W8ûûßxc¸a…N…;W-!m |ïÄ5qJ;Õ gYAUÿ&ôËIQS×€4J˜kÍ’PC“/_¤®ÐÚs1ˆ€Î¶F€!"$Amdc"­Š¢ALª${PT-ÇP1ªS)ë¾} •[}eÅ %–Ï@õ‡úCýÙ«¿nCüë fÅ­urôâ¨xiŽ—&:ïA€`VÚj›ñcX<ÿìåZ»õ ŒÏÔÊIíÆ÷.H¡W5&âmІÈRN‚Þžë©åKyì; ‹Ñ“tà˜L Ô©¸±qCµ6¨LCö Cä*ã¿2±BkäËkºƒ*­l1ŒÚàP¨?ÔŸÍúC°åÍ]½œf’LCÅd|_)8"ZޝONñëÛXX¬·š¤ ƒ¢Jì Ý:~d@iIû&×`¿c—Åp²-C‰BÒ{4 Au©±Jú(&“uÑĨX˜¨F0Ê&ÑQM@…™/‘Ä©Õ ¸ÊÚ—Á%X;¨?ÔêÏ^ý!ØLì#ÞDõã””˜4z¾*U«Nñ-Ú—,ŒÜW?…6 ɹ†l’3òŽI¸(7Îf ÐhŸb<¤‘²ôú`£‘ÇÏÐ0ÿÈ2J„$‘é,úÂK ªÒ´ ˆ*d*wdéÚÁ”›ƒˆˆ‹UW1Dao ÐÚ!@ý¡þPëÁrŒï•¶FëЬDÊÕæÇ«ärgøÄö³³VÖñMrÁê4Šm=R¾p~ZºÖj žoI"“… ÀÄœøºp£ñÓD¬´›ÓSÇEùx‚\ÂÓÆÓ…+)2€j^â(Â,¢zot´*Ò s°†/Ri•&@²hß@ý¡þPöêÁv”ë—g`p«&਄·ÏKªž7;Ì·i?Ê7?MU;Eáá…zYŦmÄB«4@¢üHƒ¤|APvBu³Ñ›­Ö1u>Æ‘ÍOUá¨xYŠŽfÈ¢“©»&á&k)øT)@5Àj¾TT½ H²hñµÍ‚úCý¡þìÕ‚íÒ°=ã!d?4u¥NU;kvŒOÒ>'¨&“Ø8¥öQ2¹õüe K ™¸@ÆÇ 7·Æ—EG®ˆ5µiѹ”§Šl™’ˆt­Ü´â§h)·‹ -i¯ö=.Ž×«Éù˜TAºY4w RiœJa\Œ‘lb »êõ‡ú³W¶ÍÀÐ1‹ ™ÎþDáz‹‰©#|òö"ã¼Û|ú'+“*†²K@†­°˜·Yd`1óÓÍH"9èˆIB ÌÏ4„gÚ|˜,èÕT¯Ž;&é3m 'yB³±×¨9ËÈt–‡§¢â!<=mR1J5ÆEB,Hùñ¡º n"BF©°¿Hî þP¨?{õ‡`;²,  IÊ,*ŠË¬¦»LùÔísý “åÂ`îzâ™\Æ|žoÝ‘ YÊ]Ã4‰¸š#‚ì²TEoÄÜšÌF¾˜›¢# ⋜vS`B­ •´ ÛTfŠ3@8&SXtÔ(‹T¬Ó(Œ£Ýf Ð&HNr1:Ôêõg¯þl‡éJNû›fÕgrÒl½2ãÓµRü’VÙ½ü“‚/]‘gžô ]"ȱ=DO2¹250¿ÒH#ÒjÓ…|¡8IKÄ“ÆÐd™ X@D²xÛm@€ ä)@˜LeytÇP ¢S¥uKjµH‘ õ‡úCýÙ«?Û gʈ¥ý¿Q}öG¾žôÈ >}ÝÂÙÎäòO*¾h±:CkÚF”p¤+çñÖñ1I¤Í`~š  QšúmF㈌VX¯‹ªÍø±t@FQ¬ùJO¡B§²ö T)@„ nöˆH®PZ}¦ %‘ˆ«H»õ‡úCýÙ«?Ë0žON&Í6^ÍÙŸ5Éäé®vùöš,àë×:8q·¬x祪q +b¯Ætûæ@ûŠ-î 5};Q :ÛmêÌ7zT"Lз)®·ŽÖ´/å'ZñIr€(#P¨?ÔŸ½úC°@À+K Èd­>û“¯§ Ññü(*¾–,Ú/=K¾Ñ‘Ü]ëJ¤1+ñ0Sωñ„I8Hcz È–&ãŒ&)MÒ§àÆu‚‚>‰Éj~ `ˆ‰'Lá)S€¬#€xõ6 ñ—A͵Ûü:(ÍG‚úCý¡þÿnýÿuÌ== ‹xœí]w|EÒ["Rø U@A¤)‚€˜!éýÒ®ïíÎ^oé•$@é % A¥iÄ€4)%t©jÄLøö.å’l»ËŸßÎóÏÝÍÎ33»ÏÎû›yß™9;‚`³aÝ都ý).9 !Ãð³¿û¸,‰‘ê%ŸÞ‚5¢+ýóTc°_å6ó›Í[yÿøÄGîýÒl/,Ü:¨>ËÕóƒ«C¬Èï·ÂÐãã Ô6i£œÎÍZ\=~þŽVieŠu›Æîe((,fâßvõ¦oèíÏT6Lx_liþéS—ó¼©X£4v%“Ú¥ +ëB\ºVt°SZƒ¿ÿ†ÖŠû1êõ‡úsW®#ôÃmû·÷–Õ´Oçyü[²j‹ýYz‰™Ÿ·ŠÏ‚wÔg÷.Ķeú͹¢­rp»a#¿Ó¾UQÖ^é€ ÉðBv2>³piàüÔ5JÖìhÒo¨ýˆ+meßå=ÿÄQÞe‡Å‚l˜ôüL×<¦’xéO/ïl¬0 ¹³áö $ñAQÓ5à~:öp ’äÆ*QzûÔ±*îéÓGZ’¢vüÍ‹õnšõ‡úCý¹«?×1â…ýùâe ®M"è4"ôq\úäi¡ÈÐ> °¼ág#Îÿûýž8Þc´Èãͳh–Í 7ûÚAêì1Ô]Vn3õÉÕ/öê\rïž~³yA÷Xó§ÖfŒYªiŸ1»êmØòÑUS¸_ÚgqýïèÎ+0ÿýyaʦ¶z^ðíÒÐòSztT…Û®üi 6_ô çíͧ`‰~¹~6:­}jtYÙµ &ŸIpfÅã¦JÔäàeŒ÷ÒP¨?ÔŸ»úCp^Ïÿu´f_UÓÏy{¾®î¦{ïU­ãØÖóOT}meuwÞržÿøQÜÐæ^²üÞ™½ã6·µÝøŒW›&x4¿ÊÎá`umøS[¨~šŸžMMf÷Ÿt#¬ÿl¦^‹ÕÕ*zõ§º$ÉŽ­8]Uo¶ êuŠ¡UTùš±N4øvy«ùN¨ë:‡wš»äDñ#Åõz«{ÕÓ¬Y¤Ô^=ߎÚ=ÑþÉ¥TÏ^¿jlé$ÅC›¦SP¨?ÔŸ»úCp/–ù§bû0sä‰o4nýz8®þ4jÔHkÇÔ&þEùÛ:kòJ}ÿPpè`îcKÚµX×y[‹Ç$ÛØì‘E¥µçžá»ž¯*1ÔO.´ž3xjçO‡x6Îo$^¹ 馜g õqœ±ñõJ£€¾Q·Æx¼6hñ¼V5üwÜ_™LUû»ìÌèúªuÊ¢«¯ý^]QôØÃ€#Ý–>òüŠfç»vËXRêBéÞûýÉk䘌§Çuæ ‚v®ãt¦õ‡úCý¹«?×1a¼~áܯķ·¼æÇ€w©é\p?×&~ιŠ+ìqÏI÷i³«Æ*i•º_ívøG‡¶9ñz Ÿ³yÀ5מ°Ï½>l eìŒ Òü? ×;×5¯ÔñÍ‘t-©ñÏ¥%|zhæºEƒé:}#óOJÆÕà ªKÉÅÙŒ ¢œœîW´¡c¯‡ÌðÔçI}¥xÝõë¤ * –ààågá©íSó‘™ÒË1ź5.Æñ¦%JõËf ŒL  Ôêõç®þ‡ä¦ËÊ¡“Ë_˜i÷Þ7ñ!ÏRn7ز¯Fr™pÍëÍšqˆ¶Ÿw¤Ý½ÑÚ¾¢—Öy ô x×–6?Ìvðßoÿ‹é»ÇÉ®C»ø>w³²Í؈9¾µ©¹- N5 OÞ=s;¼ê56Kömy¿Ý~Y[SüwËËðÕå±Ý˜êöY¬9ÞíUÛ4QQßÕ¾Ë_<sh×ÒJ‰;íß û¢÷I©ž/?":}˜tZ_áå Ù3¯ÀWV_ú‚©€úCý¡þÜÕ‚ëXúéäyoŽLyïó·Gáw½Ý†—“›,üEÛN$;²8áЬw'Ìç\¯[ؾ§N÷®úÊå–ƒµaDÇG}p%»úzÓ"å~ÉkuóÃþ¾lWõu¢t锃–ì‡ÇûÜN¥íImAÀ»ZŸê‹«é D¯ yzcŒ¿ßѾ>=V3Nd>[3ïqEûÏ´=ÇW¬­†OO¹§Ì ¢=qÑdŒ"¥ž>pÛB|.ðgaÜ@»ûç¶ãxåùºÀML- Ôêõç®þ\ÇÉÊá¾ç£+³Ç·k~Ê·ýXŽcGœ>_s„Ê{Õ‚ð+¹†>#w`žÈ×ÊzéšéwÚÚ½< `÷Àê„ëÛ÷4ýÆ$±ünÓº»Åò…OÞ- xÜ:‰?ÎgÅÞB‡—Ç( Ïþ®žõ£ ÓÂ÷ë3*#2¬{uô‹cRÌUlÙí>åÇ«CZqæEi Í´¶‰®><‡ÉM§º5ö™âsÙW,püÜíε¹½;ÞLdÌ÷Ñ’UT’M úpEÿÝþÃÒ#F¼q‚ŠöT:½²ý1 8Ž4 ªxßìLÞ ßÐpùÁÀ¾<7vW,P¨?ÔŸ»úCpS’oÙƒ?/=ìG= fC„üÍüë(W°š®Ðw«ãÛñuõÅwFŒ{ãPWkêB—ý-=ò°jaëó6—¨>,û~ý V 2÷çš±jéôñþY ù1ÏëÉ­“¬ò\-dÙd$;zlsÖr…Ã6'Æ@žSçLèщâB´¶þAqqîÑc9”Ä« *“FRgOZ+]ØøÕßcÜ‚»~#F.L dn+ þP¨?wõ‡à4xQ¡ûÊ\ˆ!ešÖ§£#á÷Øm߃jš-0¢×t]¶å‘tü7÷á/ûâÛRöšdCûö«þ§Û1ùoê«+œv°í&öXÛíXÍ»¯“á²Lu¶àZ°ª'É‚wö)emVÄg};Õ¼Œ?œÃøü¦Î ®ÛMéK\Ó_ZÞÃ5»çE²£(|Ó9'oò…xqi˜_Ó÷9u‡¾·æJðÆ•eרÛP¨?ÔŸ»úCp û’¹9+ÁéÆr|:?Jú{H'‡ÊìÚ,ÁÎ5â3oUÓóyù? ”#U¬»‰%7+N~xÑñJ»?ÆÍ™Êvó<Ê54–JþœtÒ'‰b¹oø“Q[^¬>úm»ô÷TƒŽ³ïq^^¾yÙÒOÖ1<Àuㆺõ¢š"8fçü×€ƒ)_»åµîÛñääBôêáÃMßÑúÌNš×¾KßVþÏÛ¨«†úãP¨?Wõ‡à6<Ç~sÐá~š[Ÿæ¾ßµ£å @ ÆÜM¥ú+K{Ý2tøÐîÚù¤³jQPyod궈°È~u]ÿoKIoyðç{/¡7·|Ãtz©X¼?¬XñéHM>s»äHU϶  ýƒ—ÖØÍÒ( ‹¬Ì­ ½úÉú<ãÞC_POˆÙש Ïн‹<®‘-HÍÔZÝ[¤Ô¨rWû?Zî–_ð¥ûäèÉ}\þJ·Í†Cýõ‡úÿ耽µç¸B•‰ÂwÃÓ3 J9½aà³TŒI½sS´@è¼1[kÛ‘mŠùñ¥›Ò5 m¤å±ª ×&XÇh´"NÑ6'À¤Ñj£º Hù J¦*Ô«ÌŽ!•N¥À[ò¥~¢Pµ/à¨$;A—Ôx˜ÀeÓFø­JBcVç'+…>IɶÉo¬`â0C¼š…°”2²Gô`I´Ö ¶Ü’ÙºÍÓ–ñ5:e£I¨DKÙ}i<€ªT 2‘Jk b¨Ü&õ‡úCý¹«?×PÞº|Kt‹Ò Üý6[Ÿ á³gç{ŠJâÔ­†¬‘n…IVó[—íZ˜¨Æ‰’xÛøD#‚7ëÌ7Hô@AP†‘9 €("MC™ÃLhö•‰€yPÛ €¹hL"06…ñ€PÇi<€(¦’L*²„fë ¨?ÔêÏ]ý!¸ õØÞ´¾•xÅ<þp™p=¿ˆv¿­éH¼ëŽ%úhPaÛù1´öÚ” f42:‹ÜÓ*I2R…&ä³6̼wZ%Nd™ÄÐLpó‘ B5b 9„ƈb*E i5„ùèØ1 P¨?ÔŸ»úCp žŽoÞhõBrH˜W ­Ìäcs3l32¬¤A"Ü­;RIHiÛ@¢×° ИàÍq:S0<]OÄ$ÁìÿVbZ?¦IcÙ;M3häK¢ä©Ô ‘h<€@†·>RT*ÑÓ„…€¡þP¨?gõ‡à4Lþ'¾žê'ÙÛ±#9Íň½Ãv©ùæÝ?-‡R“†–ZÆ@$Ì!Êir Š2éÂx–†ð½ (+!ø1Ò$ò <#Õ ä’exóòiÚ @£OŒÄª)ùÔÀ–`ߔۄú7ñ¡þPêÁm˜þÎ",ÏW‹\ó:ðÏžÍå`Bgš#A‰Ñq`ˆåðO:¾heæF–𩹢@d3E&øA–#A‰<ž¹4k•LFJKrQ3ÔªåÉļÄÏ`>>~`v"JƒRÚü3h+ž’ʈÉT–ÒLGŠŠ•Z WÚh þÍ× þPÿÿýÿ4 <0¢xœí]g@G¶ ÄŽX’¨¨ØhLŒ1K$ÖØ@¤7¥wî¸~·;{\?zo Rì1Ö _0&Fƒ]” FcôSS45c‚ßíÚîÝB~}ì<¿¸™yfæöÙy™÷r½0Š5¾xk¥¦‰i†úCý)ꯇ¡0…ÎBô`zØO¤XÔNZ~¶ÑÖ9¿¥´ø§ÖdÊKß.ð öT¿w´)àòøc#öÎȵ·J'§u"Þ¦Ô¢äƒjO²|ÑÎ9–5OÈ,„o/¯ƒ^ŒI—æöò Z¿¬ÁÍDûoýñªkÄõO~ìèkìÑ»‰MzäÞÀ8îÔl±ëæ©Rív–±´µ÷~R Ÿû ûߪ?ÿ«­õÂóz9a !F¿ˆŠÐ=z¦&Né<{0ÔêO¡Ã@ý Ðô§ÐYˆž‹‚ÅeîüÄ=TІz.94g&ÿjvœ¤#èäu”:Ÿ®ß¬.ôaów|f¿¶|ÒÐÕcÊ}‰Ç¤!>¼,»û`ã)âÜå1úç·L8M¾”8¬×¸Þ..SzåÍ*¼æ¶ÔÏÎÛ€Ö/?öéO¬ +ÛZ@6[fgSè7°|*½ùd[´ù†›mBaOƒµ¯Ô5"ƒ~j¿öBœó) §'“Εéæ|;¹òôcBÃ徯ô“\ÆN…úCý¡þDy´Ðþÿ§9šÇU/³ŽïKDëúdö„úžtæç@E1Ê|Üž?êö_Vê¶OëCŽ4¿ùF;ÖôÆÔe¦Û•Ô! º}0cÜÕ&VäPÕМû>Gì>5Îr!¼v+é}Óߌ5»)= ×kcï´~:›þÆoÃQ*ÏÂζær‚» ’=Á[ “ l”uŸÏû‘;«ÇÜ]{¸Òé쀙a‹ßÜ »[=l߯˜ñׯ§/õ“€êõ‡úÓW }…èÑþP;4ïKsÅ\”ÔGŸÆÉ_à®·¡¦•Ÿ{¬»Í«ES Bæ_jýðj’òhyÑ ï‚jÊ|äæ°I<—ÝÍÃÄ'<òHÏ”™Ü‘Ã84åÆÛ#\6 ‡×±7–õ?A°yXëÁ±÷7̶ ÿ{iÓêô¯+(ôš÷ºbóô!šA;)¸úÇÂé ã°áÊ^e-ƒ-H«Xu[µÙCž„¬(¼7';ÙBû‚¢Îc®ÆTaŸç=7ü@ý¡þPúêAsðN>­Ïx(}aºÐÑ߆r]°ï‹/4N¬éßާ:…:¿Š¿¡*§–7Ònî¿Ø•mÅ!_Û=ºïäIFå3æÙ.^jf’»â󓿌ȉ00¬U^_,üeÃf³í=¾Wž»ÿ摌m›¸Î¥ž|Ë6GýxÝù™æ/ÑÙ{ŸÏød^‹‘Ýh¹ó½õR€y@f¹ñ>þø²l˜—Sƒ¾  îéîâHcƇo÷®Ž2N†úCý¡þôÕ‚îX<¸Êâ¢d@±‰"³ê¿sñ9v[ÙôÊ £¾IÌû²ê£_uø™kg9eÛÎéZ\j¬óàÔùCžØ%ì‘å~7þ½åfùÍÊpËåÃ/ꆞ˫ùèïÃ$ˆ¶<ŽíÿUtÖ»â÷š:O;G¥ó^ö‡ž—Îl+çøó®ÕU+DÉúe–=UMÒ´Šóg¬[š4Zx;ð<:Múê¾¢Ž¬«`Æ cF†hÑfh¨?ÔêO_ý!èŽ/“>ëà ® ”ÅJ>sª Æ%Ï ¼¿­|sØ{p×}«¯7¾(/Þûó¯§_ê*?«¯ÿ­é»¦ê%^L©ú+wŸjºyºpíA‹Eãl~Ð= ƒ~ÔŸÇ`>»M¥ùè>Y£?Wù6¯œt&lÇ3s!C @chQÁÝŽÛEVë6ª>ê܇ê?ÀÇG­_;Hê ~ë‰ýZ+›ºçÚQ§]ýë—+Û²ü|/}B°…zûÜûW÷'Cý¡þPúêAwwïýìì*_xéìRy„Ó³ $\˜ä›z°pÂÊN;ü¸…úvÝ“à—¼ku‹[|@§s`Ï›µ‚' §Âg¼å*ÿTk“Š'¼Ü;žZû/w¹W!Kù9Ø-Òé(Â+Ÿ ´£s¯0¸P–(½rR¯ÒñKmÈ€é7Þß"-hýSxuÕ„ ¹Ç|ÚÀ®GϾ#ØÄØ×wöëDס@ý¡þP:ëAsć.¾{÷âU¢<¿…öûe–XÂÏÌmêŸ ÂÃg¾l¶Éìc=·¬;A*ïȳqq¯ŠµÃ(üpwü˜£½¨ñßå>q¨™nµ¬3z÷ó ¶<Š¡Hð¸0lÔSiË»w6/¥Ržug÷_¿÷Õ®sòwž»ýçÌÂ_oè.8þ´é݇È/õo }Üþw,³ŸÕ›rµÕ¡ÖÞHŸ§‡÷7f ìi*qeP¨?ÔŸ¾úCÐŽkâ†ÿg§ñ…X›“þ~Yb™#Ìÿ|<ò)â÷ëa§°k³KŒìÞ±‹ü©s™ Ê;®Ó@|=™×í6y< HÇ_y¸ÔÀŒïÚ?ÛM¶±>ŒÜ¥v•ë´nÛÀì¨9”(Üñ÷§>ÖIs|-i;}ƒv‚¾ð¶{Ì0òýDÁ¡kú »Ðñiu/Ñ5¿Æ>Ïós𞫾ýÏ‚cÅ+ìW³×Tõ‡úCýé«?Ý‘Tš³`Ê€O “ÿ¡¼üe5væ›?ü&C|$|Šè›ò¬ÔS²3²»?+Üó&WJ¾aµñDŽ–á±ó¯ZO™Ïµ‰v˜¾e]i[øq©¥ÅÙÁ7#”ÔÛßxf½…ÍWó¬¯S)¼òÉ1d¢ž¥›W:áÔØ Œ¯Z:¢˜àϨ  kwEqgÈØdíòŸqýʾwäVÒ4îÁݬÀÃ5aÏA²ú þP¨?}õ‡ 9@ô¥¥.ÓKdm¿ýWI(–úç´Ñ~—»Á§¶Øió/—§UTxv‡¯AªZŸš§O5Êÿœy—}âÒ•3]àû8Ú;ˆ·¾wR3賕–þÝ¥5Í‘ £?[êkSh¾(Rykï²+ú›©ÐÇv>6§ŠkÛ>¼úÆ>[+Ò:¯lçN™¥ýÌûbÎË¢¨Yc=n‰ãÁ‘@kcŠ_Ìê”&Rêõ‡úÓWº#Äâa•çåau:IöÕ}—DaØÉs.3}’I‰ä|Š>y¥¶ÎóGoE(÷‹çÍ—'ÆÒQ…–]~Å0ö±ozŒzl;Ú%þˆ¹¾ç¯XqÄXü¸żùy•æ9ZˆE9íX0×’o~ ³Ùíp#D¶¢6)HÔ\P—×ú4¸©l‘ß(fánsp•îFß0—çe©«~_þë.—5÷D/Wξ÷y¯ þP¨?]ô¯5·€ ÀA‚–—«’Š‘xÏÒY·¯8¿<˘0!ËÛ–"›® L÷­™R3…Pnˆ¸H™HP ,Ÿ²TS|¸Á9©âø“àFf%I1±ƒŸ#§òH€(>QÊNQJÈ¿%ÞA5ùã‡)W+øÉ¾0@P©îÖh€ ¹rD%íÒ-¨¿¶›P¨?Ýô‡èqèÒйa1XeŠ<AxÐö4¢±E±2A䆩†|ñ¾™›Ô$ãN·¤0Æog²Érøøß(/P2ÜÐ0ÂKL´?<9ÔB b3²•] øÙÄ­w U.'M®Ç×*@-W{ ž å%áCݰ¡Dž¢"±îw¸Eàs¤É]²àPÝl¨?Ôÿÿ^¹ùÎBô`°ÔÔg€ø¤—ÏðÇ6eªÚæ(o ø´ |C <ß„=jý ¼¨àâ,o¾¶(à…òJM7€r’ó•$%ð#Ê%ËÕ ±( ‡¢Ã0Ðt¹NO(NžBÉ"âV.C†ŠØh2>VIºgÚ@y²D„ TÆ|T !°ZIôŒÀM‘Aý¡þõ7à÷ý'‚Nø8·XAu P!ÇŸ‡U'w˜ÊZ×>A…¬u……º|€‰8˜[ÓäTfÑ8ŸíºÅDÄ ¯ß7+OA>ÂQnHZ†ŒÌ>c…9&¿>cÕÉZ>ÞÏ\L²½$Â’©Ä"d*Ôd¡N3€H LDDl™RbPˆ4ˆHõ“nVBý¡þ:ÜZêoÈÿ¿×¿ ‡ z D1>Y”^YüuAxq±-é:ËN¡Î'¬‰õÖ]Æ@˜à™¸-IF3äÇ{V§‘µ2¢\S¶ žÕÉÄ| Šg’Ö"‰ÊVw,Àʧdqß…›&ã#ÇL%ZÆÃÌ9ÊO”‰Êç¨å| D@ †Ë}xûP¨?ÔŸ0úÃõš‚ÃvR Z|BÊöÄ’‹“ô¦‘”ù¤í‡kùøû—¯2¿ü§åGìN"nAn[²MúÄǪ‰·1ÃKÌ-ç b±²íý‚È µ (.Uc)p>——B¼ hÆ@xJñj™>Ÿ8ˆ¡¢DÃç ÄP¨?ÔŸ¾úSè+DÊ]ƒíU™jÞÔè0¬,Mað²Rä“×Ëu—W´ó (ÍPtÁžàü Iá2žf“pi–™X">gÌóÊò©"´ Å„ñâ´¶ˆîŽ$’m6dq@›ÕÂùl,‰8bgÚybë2Óläë‰#€¨HJ õ‡úCýé«?ÍPæúMf®´ŸýÉÎW­—Qâ›l?Á­8OØíV§-É‘ñYëʲÚ"¦Gy¦Ü\,‹ÁÙiF!G<Ù·”’g„ðcR’4Ëxe³²©m©nÝÔZRód™*Á2 ÊGM9(O.m}hˆ­PèòÉ"€B˜ õ‡úCýi«?ÝDÑ~UfÎÒˆ4g¶ƪ(ðÍ´ã[®‰f >É[ ÎÕRáÇyoK3j™ž %øWž%Ò89Æ•Ñ1'6[%Áÿ⇘^2ìä Le‡Óp ’ª0:ËcÆBQ›£„ó\µ\‡OBŒðÄ/Ôêõ§¯þtàÄìJ61ÙÔìTñÇ ²‰æ©øæÛ Û”ˆò¢ƒŠr”]·$€Sa¬ÂxïÊt*óq„qì<ý¥;€æä ª{£„,^†"F'“,F1x&„k¯¢8f!ùý`Æ|€°cÄÜ-”®Õ ^F†žµÔYvŠÞöj€$$QsÚø|^Ç2 @„r þ= úÕAý¡þPÚêAwžgO’ѱýìOišÒø¾i*|ª­#Ü Xì_l$€Á)î¸RÿÑÛ©Çéà âø93nÜ¡ /QwÅ@Èô¢jñêUÖ "¢{%(þ…L:@€èœ•Òœâ¡íW‚’GM,Bý¡þPúêAsh®ÔÌ(7¸ÃJšbù`…†ëSùTÛ"¶·07² èß\)Ê ÈÈi[ÆÃOd™Ÿ1æó"Ôéí|„å]Mm7–/bxR<¿—ohœZ-™Î+sÊ“éfãJ‰8R¥Dóû,¨$hx¨~…P¨?ÔŸ®úCЉó*ËÑ{s4g£±Šë?(ò©¶¬9ý#­R²=ÿÝ•¢L÷ªÖß퀾­kã_ÃgnNÑœ@Âm™oYéø PеW‚š,+ŒM7²t ü„äÎ+AÍ:"¾á®eTÀQi®%‹Üª— õ‡úCýi¢ÿÿqa.@ºxœí]y\TUûWÉ%Ê%—2Ë2RQ¤´RQ´ü嚊*È&û2³ßåÜÙ`†]‘EQPÔÄQ”Ò¤,µÜB {M1—qEwÙæÞ;sçýï½çû×̽ç{ιó½çùœçyÎ9Ó…€€èˆ×rð‹Çýfë^~ ßêø1i¯lçû‡­à[Š1õGçÎ?y"ìñd—W~Yž•uÓJ'ö5õÚx{w¸OK2÷(P¨?ÔŸ»úCp¢m qõ–é3ˆ©¹»çdzH¢mâUQ³—ܳ¤¬oeÝØ™wË}Yßz-¬ä°Ã…gÃz³m·£Fx¹íHˆ›tÚÚ4¢»ÛgãO§O•²ñ„wë²æ@ãGðð»þá‡òÒŽ%Ó”ïÕìkø‡®*Ù®:,ÉÝ~÷‡¢¡ À˜ËI6û6QÜàÕÎ=7nþƒÉ­~¯ ²YÈøF@ý¡þPîêÁu¼}öêG™Á„°¬ð±ç%+ø.—êÿÕ×ÞÏ6_òƒúë}y=ú‚cÛ/ûux¶nRƒøú+š&Þ¸éqÃ£Ï ïZðû÷Öð‰ÐÑÉAgV\¶ÝÎb 0p{¤¨Â¿y¾.ÁŸöÉÞ L§± >. N}èœà/V9¾6í~õâáû‰ÝdÛFSÞYô†6áÁ[žîZÛùμ½·ó£P¨?ÔŸ»úCpȹ×Ɖ)…½ßó¥XIjvîrú«_‚¹ v`ldͼõõv6¿v¼‘V¾kYæ•‚Xö-?Œ(|d/ŠÐŒ­:¿×šÝÄ"dXm¦?ëVÏeç·[Ìzæ1djbÁËEÇ~W*þLNÛ}å eYé´Uéj›¶'‚g»fQïa¯Ó—ñ ®}DÎw&?N:ùÊõй¶cƒå½Õ?ýÄÐp þP¨?wõ‡à6fõ«ÛÑÿ1A>PmD²Û~ërÃg–™ÉfÔ°ôwe33ïÚ9݆¤êS=0—}ïBýðþ7]oÿ&+O%½yÐòµË/>pÛ'ÿ,ùê‹^ÅK]ºYjþnRáÁ»ÄÊiÅT…K7ö:åÅTþäó¢;`Àø§éˤÌÏ®¦ÙšíuÀ¦ôô’OÃtÜNíÅ{²£‹–©eêõ‡úsYNC°÷µ²‰súVîUÛ”ž+úÍÚj"æ^óžÏÈÿÊsèú¢žyÇSLßIï…†ïkŽFQœ”ÁP¦ü’˜÷uI¹j¶Ç‚Ã5ãû³ã“5xW=Øë?˜ŸûìÕÊ}î–Y)ÖµÌkoy›ÃƒŸÍ«üpwßq(éxÍ>¨‘ù¨4Qʹ3“=+®Ð.¿–ÚJÞÖúPßCG'ö'ß é¾¿Ãßóÿ3ÈdßPG@ý¡þPîêÁmŒªò«[éOèg¼k{ÑáËì”Dk+zÿí#Où >uH¯óNÞš7¨"…¯.:T;°ÜϦMûà•ác}H© ¸ü¸¦ãy›`ùs=àÒ×ím· —{k£ŽPn¦šw©æ|M‚ÒáEÜÚ÷|§wÙe;rïÇÿ´È’1y+C›P¨?ÔŸ»úCp’sSôWuD‰T85±ùë¹í¯ÐËŽVìÅ!Úø5ãLùØÎ E•Ÿ¼’Z8ñOÃ.—Ϻ&cbS™V/(.žy~òµQm—öØeÝ_ó ÕY”ð?>8úZÑãÊ–¯HÄnIHÃÓÉæ,з¾žY)‹³L®‡¿·2i{IäÈl¶pð†>¯ÿbîÏR1É‚_?J¬ÿ‡¿ûÀÐ. (àí»¥;‘†í:ktÍ-‚øäôì¿>Ö¹ZÏ#)]@ß$Ôêõÿ×ß|4‚k² €ƒ¢5N.‰ö&2Òuj¹%gqvæ[Ü..‰ðËÌÐ)ea>[ôìùmíG®,IPÈÉú‚y…ñJ–‰ŽÈÖ)åˆüÓ“XÒ4Ô ‘ R´JÂàEœéc€JÄzM `1ñjúš*ÔŠN—P™4NMVŒ5•¯‚£rSß þP¨?wõ‡à:pñb{\Ë»úŠˆ óï4ßR­Š,HÖ*ä¸d¥l£Î"cCYãY:9.Ä[aˆ€4¤jå@”Ì0ø(¹(O‘(GbðDµÙ†q?…j$‚xrìÊ›žÄ2Ô0Il'E †J€N¥À%MõJf«õ‡úCý¹«?Çð·Ìmó ”|Å¢üˆœ”X•Å#²=ßâ6ãAëN95^œ›¡±ÞÀ…+2Ò”’,—b†m _œhP!¡Ê4– {.HÓ˜”§K0÷{ŒKU£Õ5ñ*`rHãŒk;×AòQ¡F«ˆ†ê醩˜¨?ÔêÏ]ý!¸€F.ßJNï¢À“ÅkNÿ;ð-gà²(oCn¼ª©ríY”lý4 ÑîTAªuo:@…¾¹*>š©aç†óõÀìX’‚Š#SuÌie=õ#’FW*H 'þr³.ÖšÎòI¾L¬S£JÊ @•ï êõ‡úsW®H‚·èäH‡ù‰±J–#¡™o1‡t3B‚rÒZ£Y@â¿5á¿I†ù«³­ÿFw„ˆé×° CYx‚±×$_(Nf™Yd Èß]ªW+IK“Àä¡°€À1©L (S}8b>õ‡úCý¹«?׋¾!JcT°œÐ¯S³™þ·ñuN4É÷]è%)Ll‹X ^®Í£ YV#é‚(Š V¿è—DlN`»ããIMƒà_¡gJL ¤O6å]q*…Y@J9Ë7¦ÅaY±Tà¨@¨?ÔêÏ]ý!8€G/ÉNGC‰uc,Ê~N–e4dÑˈM í×Óˆl3pmlL°„…ÉV§³„(6¨YÙ=€‹"3Z2§&Jˆ£O ¦\Ôr›Àd1ºX%nÆ0]ô²zÒ‚hµTí £Œ v*õ‡úCý9«?×d!~†h"-SgÝ| aÞÅí¡!gÛ‘¾iÙq§«Æ9ü¦Dë¦ðYš“$]^B“c³ KÂe™Ê¨5¬¶‘c:0#®eÈ€‰ø)”Sð–.ò♜¦4 ^‰(˜—šsAIÛ Òk(L7Ž–¬l†úCý¡þÜÕ‚Ó仹’ Ö,ØÏJS…Ô+j›ùM8ÆÝ?Aáy)&/:­úÖºE¼h´{nº Yk]àbß =àKÒ‡_gÛfq@²$Êe¸Í-Эj-Še¸œq9È)–5ß"0ß S™¨gÙ& ¨?ÔêÏ]ý!¸ ãYù«­ŒïnŽOŽž—¶0ž:Y½´0…mû€@øžäè’LàV”ȾÿÈB”iZ‚ÀDAé –¦É9}Hvû-¹ä¯(‰2ÄQ.Ÿ&…ÊœscL#†¥2-¿¸DM÷xä«P ¢Xmg>@qs)@¨?ÔêÏ]ý!¸ €£’ˆ@"7)óµ6 ×TÂÌ7Ž‘Ð@ã។£ ^lÓx€ñ–¯Oišx„·‚õJ^ã¼:\–IeÒ”³tòqYpjÇ1mÜË“LB%] A²ÙÓ8Éñí±ÆÀ°— Rê%@Æ{¢‘cÒ¦#A;Á…™–¡þP¨?wõ‡à4À¥1+ˆØ‚xµHÜd¬ôlœ™OŽ‘ éðO¾t¿(ŽM$jEa²¦ù8 “e±ÞË‹DñršH¤+ÀCSh{ב…Fª:Û:ãáf˜" HÖ›ßâPPñ´[°ÈÇ“Ó,2ŽsB-7 Û‘oLª[…úCý¡þœÕ‚Ó0fžÄ!áDA¢1vd<’3-ŸÝ‘žjcä7ïþi>ü“Ž/Z¸6ƒEûd•‘Þ’4-¯<ÀÅ~‰©ìÒ€å¬o™Ê“sðp]¢%ÿ€0 Ý$©GÚR¾6Þ„O>jÞ±@Œkp¡Z§¤[H„‰iÝ€ËTä8ÇP‘Z«lo†i™…úCý¡þœÕ‚Û0n>á¯$R²t-EEy®O³>dÄÄ'GW”ORNËáŸt|¾ûFóÁ²Öâ@îS”Ø–¶3nçÝd`Ó#cKkØ` LƾlX˜mêj4¥u&i8i¤™@M¥Ðh½ — âMÒx-ÀŒÖ;1FrÒ›“‰tšö|€hŸêõ‡úsUN£éü)?!Q¨×¾LYà*kþÙ³µJ:> PqPX»Ã?éøá+->Ôòó+6´_dQÁëXü!鳸ol;@ 4†—a¦MÍ„¨zi r “:¥­1¿=‰´D¬ ‰ñHPŠÒ¤{£¡]ádŒ*ˆ¶m-‡3t¡þP¨ÿÿ¸þÿù;Pvxœí]y\GöÖ–B½O¼E«ÖBµjµZ?D­((*ÈMBBÎÍÎHHH€p"‚"*жµŠw­gµ¢Rm-µÒ¢BA[o´ê· WŽÝìBÿcçù+™yŸ™Ù<;ïoæ#]0B|üâÚþ±²:·ë®Õ񾀪nÂ-¯ïp¡$üÁa„·®Æ'î3K–Ó®r+ûõ¦Q«à×ÃWî»÷ÓKüùŠ]Qí`G¯µl—†º×ꆭ ÷°žÚ_´Å,múîšà¨:¢i¾ÔãÍëµ{4ßµ%¡gæ·ýö6US,'½ÊûÎ0V¿ÍýK_lz,51øáBõÒdb²°§›Õ¤'†<à¨>v¨‘¦Ž”5e°4ä5Bý¡þPæêÁh„mí–óEù¬L|vRk²è‰dà¨î–-¶‰ÙÊ0ÕÑmö'ìs/åKoP½a÷.ý²º {uMAÁË—Ÿ;²à•AªWÕÂboûšv /õöäìzËN/é£?œs3cm‰Â\ï>ÒfH,Qxyçä5w^ÉãìÖ¤WY…÷~NÕ$Ôîù”#rѱ^4¢¢1cHÖ ÷þ ö˜GŠC£Tøvâ¤ú¯±ßΨ¤ªêõ‡ú3WF ûÒåù.GìɽӬ1ßëç, þ9-~ÖöŽ–LÀõé³”]r\v>õÈ~šzÛæµ'G‘½ê­ð±¿vã ¯æåŸFé÷iŠün”#nèli\ßÒ' ý¾®¾Òäîvf4yB­F÷L$v¥ÛëÚJ)ØâX7’<{l¥jKïuçÇán3hQ‘¤‡ÿ’i;R ¦ÜN½í¢igëš°«ó Ctú¸½pê9‡<ž‘ÿÃÖDT[dY;ÌÊ$¡9½=¢bEå`Òbí]íÇäÐôÃ~^wxí_Ç•TméúææC]Üíº¼öŸÈòräwƒÀ;0¢úrö»ÊÊaÍÏ!ª\ëÓXÊu–¼Mê¡þ:@ý¡þŒÔ‚ÙX4i±pf2æ¼ó’ÏQrÓ|nJ—ÆÙÄ{-ß?ìѤå/„ƒ×ß,6îidðI²z\V1ÀŒÉyMÅϧðŽe:'ë‹ÝùÕ s]XTñaÓ~nçA˜ê®‚à§ÁÁuŒóº:µ:Š´\ôæ© Î\.§á_ô³Î•;~¥h &vmüÜöXS…¼Ü‡;9ž7»•è[$;o»5ˆìm­ø¹uv®ÙüD1â,‰5Ô¿©aP¨?õ‡`3“¹'íÐÇÛz`£=5ê£E„&3wº^hÌø‰˜Oz|¤xæ­ ÏþR.O˜@ÞeŒ1¨Zœ°ô£ e¤“—MÛ4°D¸è+âìûcF÷lt*¿d¶‡áÝïdþšIÉ“ìŠgw»Ò܇h–Æ^)Wô$Ù«g]ÌÃÛ{z,‘aXõœ·mË(7伬»8l»Í_¼Çm-»82N/ *°Xyð7²¨häm«ŒÁm;™ºï›­±¬õ7¨?Ô¿Sëï@U)D§†ëÁ{¦ÖýJSY~ßWÖ,H´ýýŸ]‰ùôÐʲÚx^en•Ç/?´‡Ï¾l3ë½ÁYdgyýgk»æ«á»Iò‘‹Žÿ3×¶,ËLkò/dóì&\!Êcu¶¬:cûeÓè(†uQéÛÇé{‚œ6¬:ý‡&d›õõzi`Áí¨ŸÒóÍZã9UÚkqØï~Sœ9çü˜¶ÕÉ®nË${ÞwÎæÝÐ6;@ßÍ­z(êõ7Ô¿^ÿlc¦`ÒSo“´€øÒ€Oƒ0eõô’sI© ƒ%"äÓD öŠ5ªw¢nÙG^øì§–þ5¶›ˆsÿ¹t½â™wC)?hõO–;§•–‘Z„¼—ë6¨ßâÞĹÎy'ÖîúÕ"Å$ÇÃó'-ÏÝlë1lø”:Ä;làg¥?ø ±]@aa<>wbßÖ¯’š§Ðн*[RÀ¾ºW‡¦’9äw{¸þ‹Þwþ!§9ç þPK¨3 ?“a­¾qûnØyÃDÉ[ùÿëþ׬aDϯ]î™ßÙñ飉¶ÁãëG¥NxG™;UK„åŸôJZ1ñ QÞo«­ÏlîzÜÜ.¥ßúrné­Ñdùüíß–op]N–ÿŠíxÊ)8tcŒQº0aþ{뼜ÈKÄwXå½\ðÔûˆU̵ý”/úôdü‡Çô6-Eˆo¾c[\Ê->ÎiÌå!Ièœ*ûÖë§ø.ßõ‡úCýÉò;½þ¨ê„èÜ~ÿÚ¸‹¶|ƒ£ n+¾+·Ù‡yU%{+Èø˜) ~{ë¯s{Ž;¯Š»Eûc‰æì?üßô428~/ñ|Þè´Tó+”'·d.qžIrn2šÃJ˜¼—tYR$ž\UíÛàõØ(]fe}¦PêÅBí}^×kÝ ‹ÿ™Òúþ‰Þ“ú꧸u™:ý›Eóú„«›¾/ùéµè&Ù¶æ®»õ°2 —Bý¡þPæêÁtYLw»¡Ñ– ¸å]5ý½¬pO€Ë(Â¥/óüöÖßP‘þ%6ˆ“Vp¬t`ûÞ”#.+Œw⢛Aý ÎÓáAæváàôyýÀÁ7„eÄÓ.°õ¬;R2žx›¯g«Ô§[9{ RGÙÙW×Ì}N£ý ³Ê^z(ƒ^NOþÒû íw–M?nнÁ(¹KDü¹ž¥ïè–iÙ’àCÆýðÎÕëÆ‰P¨?ÔŸ¹úC0’ÙÓXs?ûoË÷OØ%¹ä`~ك˫æÓØóÛ‹!#êÃRoïYù0½CüðQã¿Æºì 4joDUʬßÓ¨øk­¸VÎÊ0âiqæí.Qšš]‰æø3_ÿue¾'ÿ7}#¿²Â±{љπ.½83l‹ó‹Uy”¶wKöJ'÷3L¹m|ÕáYsÏh¿]:¯<,#[Fe½ø®e­q*Ôêõg®þL‡WÅžqõŠö뾄íàn½ÅügsÍ}z#r~{!ÙmWÃÇÖ­Ú›Fµ^F†Ùþ®©?.ÐßÜ‚‰OYÝ}~«×PGЇY®Éꑱ ‡iNÏ·zs,›‘g–~Z˜q<øÖ£Em;¥‘Ý· –«i5_¢9¶/"3à)¥¹`bµ'Œã{ÁîWïLvwY|z³öðn{ÅÏÈøOã~ÚÇ4õ‡úCý™«?ÓñÌ‘½êlÎ`9†¡#¯¸PƒÉl>v,µ¡»!§ßn[•¤M™ë”iocÝáeÄG‘Þ‰¥ô¶ GF>GV6|HçФI‡ºîè=ÕäßÇìŸ'ºŽ]r¶œ‚Ï[tŹÿdÏÉm—ŠÐ|"¸öôÍæûþÑÏÕˆ7FP]Èõ[fqÞÓ;¾V=9Tyõë¿\•ؤêßÁ¤A¾†ªA?…t¡þP¨?sõ‡`:l†}&ýóÔel½èqúãS,Év]Äñ=ÔÞ|;–)'t’Ú_•£Çâ°ÄXÏ-ÀQRœ/æÆ*bLí*Œ–‘9f 79-œðäòh"bÚR¨?ÔêÏLý! ÝP1ÔËIR½l õ,LŽî¸0åão¥ Ø/-KCãµË}§†º~¼§Å›â#éUE ´Ú€00w6†mE"3UÑfZŠéý3Éã8_ÀJR´ñqoªi<Žv Ã‰0Re ¯$-cÍÎç‹øqrS¾q3¡þP¨?Sõ‡`6>žäxbÑÛU2“W}‚JÔA0seó@xÞœ-É zea°w©ŠÊïÿ~¬= `¢0ÖfÒ`™¥0T˜i.@̉L5×V U{œÏ$ƶÁQQX õ„¦y ã#|1,¨Î#Z"€º‡B%Bq\Œ9õo¶„úCý©?£¿$b~`–—KkÂPÞQ{ÿbЀˆãŽ&ÈiJà¯Un¢š”·A¸UEÔ q~ ,•:è¦Í±rL=ޛ¢5ä­¶(EfÆ? âˆhUË2 nKõLšÄáEé/Ë6—ÃW.$i]¶ÔÎíøR…1ßÀê¯3„úCý™¨?³¡2±×a ›T„›Mð7˜í¶9óß,êóñ±møzåV‘«!áK¸+·™ëbZž7È‹#†I¤WŽÆ,_g†°} ˆf@"LR“µw=ÙævL"d©›#«¸7âihìjèø"®ÒØ5B>+i‹êªÄ=Hll4¹ƒúëÌ þP&êÁ lÕn3ámàb[Hß ^GgŽ´æ6>À~@PVº²=!) _cvïâkå¹q¤{b¶GÕºD¸í&4Ò.gÄ·a@Šù%î`ùš¦e@ ÕКŒpâ[=Ñ2 î!bÈ·¡B™ÁNf‰H ”“¤“'µH8ÜtÊè(þÜ2^:î‰RiÄR &º,ŽŒQÄè¹ ”’?ŽAPÇ— ÎP¨¿iEPÿ‹N®{ÿp¢sa­ÎO3~¿uûCÂü±ìª="@Bħf¾Dâ›´IÕþå(¼Ÿ¹’ôOí9Ÿ¬Lªñ=wu™:|?µ™Í¹@ÂLU™žZ€ç—C}M‰öÜ;²#l@(_jðÔêõ'Íïìúw| 'D§ø/£i׆8ž¶C%§\‘#â··þ]*/+'UÑ‘)@æI¸B0qÄêMéTGŠ€˜í·•d“n@•nf†ðY+]azÈX”@#¤§;Ë™+åóiì‘ 3–JÀ×»¡›Ùdl.êõ‡ú“ävzý!˜T°\²7No Ørö'WCtÏ5¿ÝõfûcÔ—ï¢ùy¦cm¼ÿ³Ýs¨ïúÄù¡H:I¿@"0»“Wk–˜\ šDk^P„‹ªPV @Æ€æ¹Úz%(n!'¯IM÷Aý¡þPæêÁph¯ÔLÛ«·Š¤;û—KpÇ~»ëGB¼0Z—’ÕÏsÙ’j\?bÖšÜ4z½Ê/1‰¸v Ë¥ÍTg´x‰ÿ&aYôŽ3ã=X!ŽÌ¤5]0™è‚ˆW®ˆnj$ Íl2‰6·êõ‡úå1@¦HÂ< RZˆy¾,?ðêJ~»+ÇþÆ`,+›FW%­Ÿ½j§Ñ2ÞÿÃ=ó茪1Ý2`¡ñMáM9Ë{;ÕUgø/Æ J‹Ó_€ï›MzöÈ”/‘fÐp]e¨0R%×-â£ÈvD‘F¡þP¨?sõ‡`:€ÈÏw¼öÕÐ aù`)Äÿ3EÅoÕ@Ìõg Ã;Èo®?t­á• Ú¿êòÊ7»»WϱÂ7ôWíàbÓ;ÄMÌÂá¦ÆêÙQˆ‚äà!_ ’©W[ 'Mõ DMÓ5 á‘.g’G¡þP¨?sõ‡`:Zþ™³åìOº}×CuøŸA›Nÿª%^QÛèý³'a)@à+ݤ·R§íRë¶%Ñ¿R‚›^ ŠÏ Ü ©Nòê Q1 Ó´ý³'°D4nõn£óW«SÕ2*ˆÛaDáHí2 ‹Ón×FE(ùŸ<õ‡úCý™¦ÿÿŒª%=`Fxœí]w\G¶Çc4jŒÆžDcbIÄ‚XBlQ‰EAŠéåzÝ™ã \¡÷"UD°¤Ø0ذ¨!~šØbA£‰DEMìíÛ=ï`÷Ø=þËÎóìÎ>3»÷켿wÞwf¶D@0B|nF€ü\ž4aRw›ö°ãB›ÛXWc~QG†Í‚«©þ‹7×;;àqõµ~_†ü&ø“wè÷AÓÃw¦Ü®™ôǸtŸaAå/­Õ[Â"MOú=—/*Jƒ?ðhb-ÏãÍŸôƣЎû^ËOCI÷î “®Ë()=ú(×âugÔkw}ö.I°ôu{a߃3ƒ·™Lů ùwd-Y Òéôg¯þlǼ‰x¿fà ûý0.ÀöÁ”æüÙå3" Üý?á _ÒwFâÔióví¾æÔë;f­¾Â °o‡lÖ¼¨2F=Nêà9üz í.Èwô›wé¦É)®¡ç;—ë0Æu›]1~$ß{åÏ·:Ø—ZѲ¢ì½KžžŠ„Îýž”;_UÌr¤ãº7!n˜áópo{]ã1æÜ¥¿àÓ7—è,²^á§ .o(ÿ˜–ç«ÑœÓnùõZUzÆð9îÝîsûí¥¼Žßi¶Ý”}Ñä…òz‡¾Å^Ýw^¯ ªàÂÂÞ¶O),,Òéôg¯þì†öÀ‘’™XQîj3ࣞóq¼Z›ÿÍËe…;Û:N9.ÎjHœ­’\ŸpyÅ‘ûÖ´M`©,bwe‡+©/Vt»5™áSØ*_×þ0|~ƒ 6ÖìLMÿôl*]:è3ÃcÙØ¬T™cÝ—þ%|ŠŽÚϧÿtË鄬¢ªèÌöi4¾Õî…wÇô¢*åjTÍúÚ1É;˜r qx;÷`yÒéôg¯þ¬†¼ûž¬í/Áÿ^ºð¶[¼•µ|ίJ ¶ßC™2ƒÿk»êƒÅ}&ýà1øå ;0õbÈžk;&_áéqÞž­Wxîpþî-KÆÔŠšA÷§ôvÌ=c<º]QØYôAƒ‰$*í©wÿZþ­ª&®ß@¿Ý9=L©QÀ¯Þ~Û~žÞÞ‰4ɇ÷ðGc]§í§¶+.=ƒSf\«J¤¸À× ØÖ¡–¬é‘þHÖêÀn8ùÝ^œ¤ ‚³`\Š«Uþ?Ô³y·9ÑâOX±é<,È:ð£É¤±‡w@{o®ÚÊæÃŽOYåGRqå‘ o3狆ðæy<Ö¬'fâýeÜï³ß;„ïq¶¬®‹ê×úÐqñô›ŸÛ½hÔüÐÕøó¾ï8 –½Gþ汽©+eÅ€Ì^ö|LñÿÂvÖ}² Òߤ?ÒŸ•ú#°¢?#G÷ã_†köæ_¥|óɺÅÖÖ°^õ´øà÷¬0CwØÔÅ4à% ðÍñ~ŽkÛX0¥¦x`A×B»[O¬á{L³°úÞ’šh8{É7[î%×>eÆ·¶=çµýÞ]´­†öô#YÙH‡²:â_ÐeØÐiµ'¿ÚJv!çfoÅô–‹Òê”âiu¿-r>MjA@YQÁÞ}-Ï#ý_éôgŸþìÆôOµ]O@è7zyÉüÉs6/²=`m]«úÒâs¸ŸÚ¾¾eÎ!æÎªó´Û©â>ç¬mßþQù›ðÑãó‡ê¬ãœí7ô†wÚ(Ï“5»ºmÏŽÕòOuzÞcÕ¥ºڜۑ%§E± Q?QÎüTû·%‘\X>±xðç},Öuàç¥ÞØ¿óB¯“•zÊÝþ~v±Åi¤ÿ+ ý‘þlÓÕÝùõ‰áÏÞƒSäuÓôÜÝqÔŠòzk«£Åÿ¶ÄæJÔç|hó¢yÑ£¾¡ìãTr¥…ÙüQéøq–#®\>ráT‰ç£ÓE=Zþ€`mâñò]æçþÍ€ôGú³HvÃS×§¯_ŽÜ5Ê]4÷_ã;#z“éj¿!ÖVÙ*_’5uÖyCFáòö§Èf«òÞm'~ôäð +šÆrÿ~õÙç6õ[.ÉWZ;‘iáý#BƒKLtSÆ2gûVö;3(õÐ̯“ñH0¹¶R××3»é«ë°¡îòÏšAë›]ö[iû–°CX|RÏáešav=¦T·(u ™5àñïf§þ-€ôGú³FVCÒî;ý®ñga·m»:Þ‰Èj<ë¼cpÜ‹·ÉÚZ[áû´;6oíų¶0ÇÜËŸy4oч;ݘ§!eRݱ/Žj>X5þ~±Ý «ÓˆÏÞ9¦<÷U·šn«™se×–9œ¤ú1´ãÎ¥´¦2K¢¶ð–mr†'Î~žgûvpZœù•ë{f­°yÏbeîÁÙùÉógï4¨¬Û'U-6ßþHåò·©Aú“éôg‡þìÆ7‹ë§Ϭ†3Jßëþ•Ç|£Oæ`§Ö®Å±ÌãÔË.©Ä^\§â]Ù}ÿØI]™.F–,ùüfJeïNÿœ+9ÜåÍ!=³[§Búpüù._§¼awWÅüûå¼ÞýϾ÷o¶~9„'‡Ÿ›ë¢0[÷»¼^ç²á=¿›ÙÇ#Âé3Z^“0w·½&êÏÏî…\/»4ÛÁ $+^l5¹"ýIôGú³BVƒ{š÷áG[÷Cåû9‡˜¬zÔÆ®W³ÓꪩùØÉÜD÷A°¼óÁ…Ôûd`7ÖMýѳì³ žpDí³ŽÿÊ ‰r¦6yh;+2xÞ‘žÊÙ|©â¢ÕvÔ°½ñZa—î‚«[¶…_ ÚØ:Á;ýÌ$ì“f_çøÐ«øÉRÅ'ê_MO¶‹QŽ·ü©4ÁÛ#S>‚ò‡+'†´_ž§{n>…i™û˜oîŸm:DúSéôgþ¬×7ì÷ nî}þýÍfù"aʼn{‡+…¬­œ’±¤<ù"·]jâ²Yª/Xþáö²GõgÒ&÷IæŒñk&äæ@è¾í3ɼÓMazßFØŽ Ý›=ÒMÆäk¨Bß›;âߺ<ýkÿJø [Åþ¸Ö`ÌÙÑ^;›Y:YõŸÓN•N›ø´ðÕ¹à=³¤³Yãí6¡\äkÈÕ«×17•1ߤ}Þ’ÂÄ&>â`¯5 jÝ &ðMŒÓ˜?3~Ò# ¯„_. ‰1¨Û? +švãH‚t*¾N«j…¤œXÒÛÁG)?*J¥€raõ ™4*’|W¤?ÒéÏZýØ q[¯óÜ ,2௠Ã÷ÄÈOT2c ¸‰R3´JÜÓ u]ÏoÖ~„si¬òeyÅÓïÿŸ»¢È`Ö>À„¾†¤(Z†@™ 8E§4^ €hU²~Or®BEœ¸h¥ÅÆð‚Z äb>*J¥WÀ$ 5Åbf¤?ÒéÏ^ýØ ö ^« ‚Ù Ñ Ýÿ&þFo=A® ÌO0z¥@ìï³Io½Šûü>ëuF>ÀD¾Å±&€4Œ—nÚyðn™EÓˆà|®(±Á¿ÒU¼Š~ÿ¢ð$ ű‹?<å€(Ãä"©^Å*ê.ŽÛE ¥‰Eú#ý‘þìÕÝPÎ]ŠÿUê4ŒÝ#0Á"õÆh&ÞOÃ<á:ƒFÑà6 –ÆçDYí  ôÒ¥ýw”V­‹U33bxïT'iš·NA¢L-ƒ ¢$\KðœÃà ý–¥azm$Ĥ\¥^eÁZúaRAd4&ÕSwqK@¤?ÒéÏ^ýØ "‰Äu039w]­zI€<Â)7VƬ¡E™pU¶P×”8Ã-PA2m>Iû<Ç¢µï'~%1 û?Áx§5™ %¡!¹:q<(ÇãO1¡÷jƒ &Ç©8_ÌÑG[HZ “ð¢$ CK`¤?ÒéÏZýX Ü}”‰ÃWâÿå¥0 œ™×" ô¤Æ@Ê_³RLÒ^@ê֔Ƴªýðå J¹Ð7¸4FÅø1”rýr^:Ðxeë,xÓd|?  ñ‹a@Ä$ÁÆ^ €\È‹‹¢LZÀ†4`¸:Ú‚àåQä÷…ô‡H¤?kõG`7pçQ,pÅ`¾ÆKôÞªø_C="M>î®F¸Á5qÓ7û|ÇÀwn^'rò4"oÎ:ý œ?LœÝÆ“qœ˜#" (‰×`a ‘Á8È9ÊC0™@£¦JZ4Xq¡”šODú¿ä#ý‘þìÓÕkRS´JÁ’ø5 ²WÍkÂø‹iñá2Xb0Ÿ§ 0Á·™™mi_èfÐûË׬st‰ÉCÚø†4oiqS+‚ÛѰ¨(1'ƒîÌ!hL]F$5,_Â…pÕ:Š¹Ëø£°40þª‚ dÊ\¸}#"ý_ñ‘þH¶éÀn‘#bíÏšR!w.H±Æ{n¬‹ŸXýãÉKÌÒ5ÓiĢ͵uVö‚Ï÷\£ÂÇ"|÷ôkV5 ƒâµ 2‡DÜÓð²_iÀˆ˜h%©®Å€±®0L©‹"çSE‘þ¦|¤?ÒŸ]ú#°ø;'ÁÌDãÖ@âï]׆µ8tø“òœan"Éë$Áb¬nÈÂ]`&(ågi•˜ÐǬa‹Ä-×¹0‘Áü#|Ð$y5ÒÀùBa¬†, Øú€€ÈÔ2±^MžFRYË ÒߌôGú³JVà]FÌñ€Š"}ãÖ˜h!ø^g} ˆŸ˜«âׯªIÞFD+EEô×Þ˜“¡Œ»,RŸe%ߨ¾$KÒHü#Släe—†¹Ækè÷3L”bbi&ãc²4€œ¯UÊ„@Kš$‹"ý[´ôGú³Fvà¾8ßsâšGÄ–ši«Û’†k…O¬þñŒ,Ñ“ÏV%Òˆ9LÑšÖ,å:%§¯”ä6ÌdÆ„z5W’m³Œ?ýН§½G¨L7O!Vcq¢t-ܘȣ#å2¾:ZIf[[F‘þ$í#ý‘þ,ÑÕ &ÿˆ"VBC¶^ýjë q]“Ô–4œE~ÃêŸô4-Õj"WÌ`-“šeç´ŒhÀq*‰mËýó\űùLÒx&· òMŽ–†$ii.B@ÈI4K5â6Yĉm™ÆN\«A´šˆ t’4`‹ ÒŸ¼}¤?ÒŸ ú#°ÄÚ¾óc£Ì¶þoÿ6¤á,ó&ḾÜü“ŠèÅpKQ# H#–g¤i#¡$$°Àú-EñNìç_Dï -¸b PO@Ó×’ÐØfC " (Šiž¤3‰V©Àù" I°EéOQÒéÏýX bçHQ¨LNÕ©š½,˜`üAÛ†4 %ŸXýâÝ´ù'Å¡‡*‡iïÿá®Y©xo"¾Ä™fUÏX‘,ÂæYÚO‹š*à¥i˜4BAšà$!ðeqÍM–…úf|:L¤ÔDÇu¸±h±¨YéOUÒéÿß×Õ°qíOa I´ ã,ÍÎhË—9)øÄê\’—9Ÿë˜ŸÌ¬}Ü¿ w[ÒðUŒ·|5ó5<ÉyKs5aILw‡F/}e.aøäâPEгÙM‹ƒR[ØBÜJJ8Zó/ƒŒÙê@&0î'ÒôeÐfÀ4ˆô§¬éôÿÏêÿ*%%`qõÌ(M¯Ù7gãsõ¸xÆÀôQûoº­4NæÍ]üÇO“ ¦Iu I¹b×|ÕƒÙüÖóŽV+‰_žŸ–Ÿï^³²óºlÃÛq¾Žëß(ÒŸHˆô·zýlX·‹t×wÂs¾÷vÊþ9ªb{•¤ÏÎgn¦  ä·x—*†Ïï;þ+?ë^W»±W¶ëØòÕ#0ïäpXVå0;C‰‹ÆWy>ºx¹¹õ†AC‡Ìv¹^#zÔ¹[^æMfqoÏkv5ðü@²”ëbç´»‰™ š?£ürå@Ó3Ííþ·û¡ê_`ÈÖîÛ]Ž$0–öM¿}Þc¿&!›ª•c÷<1IÝx{Îì±iµ?‘þ´@úëô·fýl Eߨgž‚c/ÜÝEC™gOïâˆ, ·Ø†)_’>%~òŸ ŸÙ÷^ÍJ—å·qÛ¬ÚPÁÑšOÈø€îÝ^WL©KˆI(“ ;øÙ1…™Õæ—~5äö›àQÁ>-ªÇñi›lwƸLmÕg/õ½þqN`Q^÷Œ‰%ŒŒm§O¼#T™Þíã×GÞò;R—~I|l óÎ<š4{…þ§ü²kÇ}7ïD<ˆm¸{à·ãµ¿þ´@ú×éo½ú#Ø4D ñ½gàÍÞ;ämréšX„Ïà6Åûþf©þ’WWJ]/´8С—й#[ ¯¥ÎoÞ*”Ü&áæÙi÷Yqµ¢Eã\æŒ ¸q±÷ôžæÕZÖe…ÝÂÖ…ßgÂO¤®]¿8ïÁ6‰×¾ÿ°/÷.ìV;ë†ß]•ùrQ!ÓÆ#`†Ç—½ª©nIÖž¼øzFÚÝ‹yúË µwO=ÊüÞÂv+æ9®»ˆ¾½úà„Sj³†9?,rØmý¤?=þõ@ú[«þ¶I¯ŒÛùq˜VÝv±ó+ú²ýä9Nwn•¦YjLj?Èu+~ò×vvìËÈ«Çû@ó¸sŪ2Y§¶r¹×²äKÇk†-äþö?LΡšß¤Åû9?kü×kˆŸúj±ÞEÁ¹Ñßçqr=/Ô] бÊž^ŸÐÏ¢â-ûÞ™Üü{ê×`ß=j÷{=†úèh '"~ËâÌŽW;‹ÿ8X5§9¯Ò¡ÓÇïR2ê\'¾Ôÿô§Ò¿HëÔÁ¦Á;ÔkøÓR(½pè6SVuâÉ>®Oœ-6eÈÇN”|ïÒÞÙnÅaZ.{y¡ðfˆš5ãØ_n~¨8ñvO“¬r‡»úíS¹×ì™Ò¡òþÞÇȋ˜7%aíÎüº†‹"ÑæéBŸÃùa ÍÙkTû(Í’ªÿÒ2º•ŽÝèœKswüª^Û\Gì«!W:Yl¬‘ÏsÑVÿç×–Þ[?¢ûÞM!˜>O—:¿€-ßÀ¢ 'À¾[£lšê0*nëÆŠlî ™jÆ>ûmïɳګ¹}´¿WK_œç¶iQbºßk/ƒ€j¿îÍ+ƒF9ØÑ-¥ŽþôÙUñ'tâOú̬©>š7iqQðÃÇÌèëÛÍ ¢„’ý£îßâ3Øí¢Þ'a¤k@ú3éߤHkÓÁ¶á›=ºº×Ñ"8úðû=ßf±e_önßåìÒÖ?Zj®ÿM‘‡à8¼1»l)Å‚ZLïøÏ—Vg¯2çêµ²óìÏ´&_ø—}NýõUÛòw\íÙw(ú¹YNâÈúëÎ/.zàæÀŃˆ¿»xÅá;aD;€ÍjÛþÞS@½Ê fÄ·óø(„þ…”»àÒ´'Y•YËÒ“½§Ó2× yØÞ!v) AóŸH–¤v˜ukm} ÒŸHÿ¦@ú[™þ6 iëã—•÷ÃØ ­Wüy’C$îý”¹vÏ'Ná²f‡‰ßòy™Ãfx­tûóø×îÍþ==ÁÕd›¬!Þ:ý1dÐ+ð?<ŠfZ5â·–÷Üf­çfmºfxôÞŸDІ‚äØîC_œv† ²B3¼&LkÛ$1j´Û´¢¤ŸFµ£|Õ³¾Ø”ôGç#T·êàÙül«â=ºNÎX…_¿ñÿË\Ož—ûŸMw=M¾>ºtÞàÌû‚Ú¥ÌHf ýô·&ýl³ü;\-;ªïŸ¾•5*…@àÅçÀO-¶Iò}=“ö¹®ƒw÷üè¿ÃL:ÞUs°rh—~ {ynÚ¹_ñ¿þèˆU7]ò—ý±«MÎ9¡‚o«W‰#×̸o0‘Z&°smYÀJþ4G½[9¾Ê¨sRñ¯„·3÷P0äç–'F=®`tÃ$ß.ûtYæL¶@ê4íˆ][š$áï yçÞ-ݲ²ù‘þÌ@ú›éo=ú#Ø4b®eDÈú þ]évbè*Ž,YÛu§Çíyü‘¥VIþ_ƒ»fþ ä•(ƒ`„ð—N‹âvÉ]èîƒ#ë{õš=‰?Žº!ùRžwA¦:.¶–µp]’Eõ8ßgEZœÀ?_g.IP*i@¹0"#í)õõT&Æ™¾~€Ib’‰gi¼¤Ñ)J–—$ öù ¾T¨Sòõ·ã”õS§HÚ‚þH«×Á¦ ŽI¢} ,MTÅÇR}V@âÍÛ¨3ý49[ âŸu”7,IQ±— $ÁK7i¹Û'¾nžOQººîaw]`Aý.Z¦[®‚²HÑr™| ãÁ4Um ”ñ%©j6>a,&ƒªY|‘4IÕèš.ˆc{€ j #õËtŠ&ˆxûêºaÒŸ¾ ¤¿>ÒߊõG°m€K…Ñ0/M£ èþë æjÖi,v|¢[, ‚k•”.ǸŠBÔ\5×+À%ᾫÓU± F ÎRq°dlW›MÔ—„©RÍã,†—£©¥o8J‘Äö¤„›JM ÊC´`?^«hhòEVï#H¾0¾©º@&¯‹ÿ!ýì"ýk Cú[­þ6 âã‹£ü ¦Pk4IÔ$å^˜ÅöÍ1X1æZÁB<3GK=ä0åÇÌ/IçhŸhîaKKš´W€ñç—¦š[b *ZI6#€ ²•¬“x†•ùåéZ &æ%kŒÏJÔ£™ç$ø’¦þ]qà"eã/éã5jƒwM$$Ôô§-éßP7¤¿uê`Û ãC/ &«i»ÿú|²%æ…áùÄ÷½®JW³Æêù NUK€ci<Òéôg4cÍúg°YA°j8Áï”2rïOQóÑ”À…sàea@òóõçAø/ òUåR†ñÈÆ¹0•åOvóàø¦‘=ª\P¹˜òÔ€Kyñ,G‚,šG]E’/‹Ž3 Èi`q™À·”õÏŠL ¡ò@äÌït¤?ÒéÏhÅšõW³ZA°f`‘îËS¢BaærÖ£?¨ð¨ùÙôa8FªLà3´Kór,â×3¯$‚O´ÿhŒ•lguLè›Êr¤'QÔBš C§&10É@c>ÝZeòHψDã(áÖ¹TNî%òÏѰPq™„úEþH¤¿ÍêþþŸmàâe¡ÄÿÅIªx‹–ƒ’a<ú0bÒ(/X˜ª÷±„ßh?bEiô¢¬œÖ‚<Êcó‘ D|Ai*õZ!2 ’­¥ï‚“ÑCýnc0Q¤ñ‘ @ÆÓrÜž0þ‚Â5³ë¸HAãOþH¤¿íêÿ…Mþ.€Ìxœí]w\G¶FcITlŸ±!Ö5F¿+QQ±! *Š ½\ãêÎpp•ƒéRD5Š5V¬`b‹[4E‰1ŸFcŠÝo¸²{··üçÎóÜÎ<3³ûìÌïyçm˜ŒNΛ¦†›»vú`×ÒlZEl÷vÞÕü™<Ö>O¶àµd*œXóê§2:|£’žÍ©:V$š\Œø±âô¡ñ-Fθh‹.q÷îø^ÎÂCëHs8û?Lëí¿usa*§‹C¯«üGW÷’°Sîû½ýw‰¤·çsõ›Þg]?Þm¼xç÷*º§­–×Á=dæ Xèɹ܃¸yu¨© îÔýQ Òéôg®þÌÆ‰àSU50׿wÆ’âK4» (ÝëXU8:Ü.’ç×+Ëw·“žjÛ¦ˆß1¢ Ô;>­0n~àNÎ]ÝØ·úž´Í|"-–ž:¯ I_v;¥Ç§ÝvW‘¤»ÏX¼ò‹m:®%Lu[­¢Òtèº<¬â¶Þ6ÿ·?¬'Ë4°öçtç© H=þHfêÀl<˜îµ3§¼áªB°„$Û b8v–¹ÙÃØú÷ë¡0RØãÃX|s<ŠžåÕùbKýo/·±g:8¿ƒÿÌÞ«…󸲣Di¼ê'Û^TLs(&§KF•–„ l™B;–$¦÷·Z}´ë¶‡Õþ0óÃ"^LLiPÿêlJó1÷µ{yß>U›ìèå¯!ÎZ†>Þ¿`}éoÒéÏDý˜Ã•]…0Í·µ ÈanØ­Må#i—ÄŸf?hBÁ˜×aéNÁI:| €±âÒ®KÝß.Ò¹:Ýt\ðýî²ÍÖi víàèU“*M³Lrò×ø6YG¬ñî_tËh3º¨Â"¥Ý ù 7ÿB470‚{Yzjøe÷åº_'º9}Û¼o&•†ƒ©s#‹]úLþ¬Ï•’‰{ZÈs­`y>í´åu¤ÿ[ ý‘þ ÔÙ¨Q€ Ïökõ0'6/¼ºu€Ï8ºEÙÅŸ°k—ÕaiàÐ7sèð À¾ÁYðC¥ØPþ“ˆgÎÍ™_D™ïÛ[¾ïnÄüB‹ŽŠ)¯•{UÝì~ß:jû[óGWüd>‡Y^ÔjG¯Omufйý—§µ}ÿî¥oñÊ„«¥^”Ú½h–b÷â³ ’[½#Ë.r˜0—ÎUþç}Ëéߤ?ÒŸqú#0#/Bx)ÔËirK%„«ïôY¯yxaݨó±OïE»@ññpîŠÆm)M­b àr?/µÿwØñüœ&ªª|ríà÷ë)ŒK¼èßÎì28·{GMÊ€¡ƒlÐÁ½Ùü5¾ãºÏ4݉+84âéé_û_±Y½¨L¡ë¿ÛñZ±~Ù{×mq•Si5ø|¿ÒÅÂhÖ±2ÇA¥¬ÃY¹xöàÉÂ,ö#ý€ôGú3LfãàtxúZ±Û9aIÝÏ7¾n '†)éG•Ï–,Ѧxìÿõ¹%¿_ ÝúÝcß—+€Ý3Šï¹î’s'RZC«È™vÕçÈ”I•¦—Ûlý3ùÉœžlâ¥5#V\èÜ¢KÑ8“P›—ÏxûRðæ…~P1bÂÜþÝd½…~¿?ùý¥VÏ›ø“ǹü¿Åo/Øsשù^x½Úu»·ùU¤¿1þHféÀtä¼÷ùÍj‡õ«^cf´ÃvþA?V”ßý~»½>OÍ÷c7«çO˜ù†n4°ämQ_÷æ jvý¥óWw¦þ‡8(‡Ü‹‘ÿü¶oªÎøâèé»ï¯¸uó"sÜ· oë—€(ã½BƒÎ´ïîrsYø ¦I,xžŸ´æLáÑ])”ød¤´j怺{E¶r>Ñ,ë‘«<ŸáÜÓrdEúéôg–þÌÆÙ€ýË—å5ü=Œ³ïD{ºåQâwåð3ì|rÃä]ænôü€GqCéÖï=gÕÚƒëÞ^.÷{ï_m†)Ü¿k»¯tÄ‘±¿`ÿç‡GúøÒJ o#†]­˜õh̾ƸúlÝâVF©zðWíÅ!Ÿ.ÊëuëMÅñ.”8sÆÌê°ô¬¡u¢#-ž-ªþzPŸJó\Ó‡Œ¾þÄriéo ¤?ÒŸIú#0/%Ÿl ¹Íxikþ*fÇ‚>³îb¶ù¢ÊÝâ”0,çáÜÉ–ûbç¯J=ú¿IŽ´Ý€ýÓ·æ ûçgöÀÑÕß'ØÏ}(÷’Œû 1–ÇtvÇKÇ<Q‹ŸÁªZ¿ú¼\¸çãúg*nöÞš—µlA±ú˜Ø¥}æH[ö‡·ó”ÀÑQqn–ÓÛ_¡s C~Éóü¢À<^ÙíâcÙþ]f‘þ@ú#ý£?³Q»Èu³j¢™~éøÑ’[Wªiï±Å÷³%ha¨ó|¹·–(}÷‡ãZýxà¾k@gÛ]ù•äNeнjtià5Ç¿w.Zo±GWè†x¶"Ÿ3®[¿¼e‹³oŸìr¯²ùv›îÃz¬~èt'&có ÅdJ;€àÌaÃÇzžk˜žÌ¨.ùýõøÄ»Ÿ™²C…­¹<ƬHK ý‘þLÑÑÐ};<´Õ±SÞ¢ZIßYÞÐ_-²Îÿo¦né÷ç°¸÷ûXÆËê!==2äás‰CY(€ÛüVFf¬¨hZ½­LáIÇ#R¼®¾o„Þ«eKª¨ŸOæ8°6vA§©†ÝÇû.¹ŸÚa‡ïmÄ¢In]¼æý|ˆRvÐÃ!ùÆl§†ßX‹7Om®©Ü6¶ºF,¾2a"ý ôGú3Bf#çDåªÕý ŽÝâjê·kn/Bóœ ¬ñ±;/Ûž¼Çüôâb2™.P›Ëvzq»%½Ú…¡çÎuà<{õª-5ÚS’ÆöüªhúB½¹, ®PËg~Ìjnÿƒ ƒ%²o¥êwýDLvÒd³o³ƒ.½rlêèÞƒçxRóNï÷&Ì뼑2fýíøÜze|þ‰hÍÏ™Gn›Ìªþ$@ú#ý ?³1öô™_ò‰?]5.{d‹±©½€vñ£¸Þ‡ ðEíŠ~NäËQ}ÅåºP]J§n¾Kj±Î-´Ækøaj4®Lxuç¬ò›¸y½Kâ),-ä~iÏ®dIVNM†`µ¢K,”Núù©®úúD»ªgŸyÚjí3‡%ó©|¶tlS;g ñ%¿A>Ï_wŒ3aÜKöÎ7ùÎ ÒŸH¤ÿ;¯?³1êu»ñmÈ|d…ÝGõâåEÐþ2'þÿÜýõ·Ô¡“7k.YãKÖülðr%O¤SóÆã¯¥øAtL®’aZ¹Ìšz@Ì×? ¤?ÒéÏ\ý˜ ©Dí‡ÿ••'X}ƒ¬Þ"m‰Ê>6þÚó}øê" þžÓá…Åx'g™v1¼W³V®Ë°Ö­ø‚`iÿÖ§óý´J+éÂH¹Žt|rƒs­¶`"v¼VÞÈÇ’¦&2ÌŠSn¼:ÞÚ† !ñ…ôGú#ý™«?³!ñ|Ä07Q¸ª ƒ¢ÅI ò²“¿ôœåp]:n¡ÇÒá›ÕÏY²)٘铛®¢öÒãþ²¢$²úññ!f[+ Hc‚Ó´ñ„(>:ùgY·¾” ¢5q =H£c“(ìøà‘ ¹Uœ•I†”«!¼=¤¿ôGú3QfC `@MžF…ø•éè¯qˆ¯=üºW~5,Ò) ËŽöò-ëg­(7êez›|u~*Åþ¯çG¯Ù@\?‚P~žÆª Å\V†šˆóáòI 'EY¿‹8VÖ M¨RÜø—©€Ÿ¨ ]ÂÅ!&¼¤=éôgžþÌ—ë aA¢*^‹ÅÛ5ôO‡Àìâë_øà0Xª•׿•öñ ó Íô=ȯ`-õE/}7gŽú¤b’ÁÁ(S´d­‚€$Q¼LòÕÃú\˜„+Mª@™@Ñ%ŠWÌÆ§>8?Fš@êR¾BAðp‘þ |¤?ÒŸqú#0‘á¡0%K¿·øÄ]œV l‚Î>ÀÄÎØš34–¯ŸÄâ3*1O®Ž'sCŠbˆ!‘þF|¤?ÒŸaú#0>%*ãêìF \^œß7U>þ²ŠØÞ0/Ue¼dÕôúÙKKuñ†$ ,J±iv›ñ¹KÊ-êP½¬”Ô=h”OÊIO0w”BeiS¿&ÊJ68D0$CEqÐ0Ðÿƒ 9Z%±dOéoÂGú#ý¥?³á3SÕrYlýºS`@y"}GU¾>ú'ÂnL4[ kzý‘++´2ýŽ¢˜àâdŠ>´:E‡[zú€„³´8Ea{4ÀsrÒÌ‚ŽðB#`*vŸÏ¯s‰I´Œê ·_ H”º„«µZ‘þ&t¤?ÒŸQú#0.kqn#,füJÝ7 %¾>úÇ#+ÑZD­ø´ U G‹›âAaIƒr¬ð…á ÍÌòÆ;˜w–µ^c¾( &ËMî Hجlªá<˜˜ õѼX +ê ú @Ý"¢„5Dn@üΤ–aHHs>ÒéÏý˜ ˜“¢29ú`ì\}œ `"î2˜™Aà®Òó×g4¥~žû†µrŒ¹)Éîþ_çFôOÕ™˜ëx‘~ZÊËqRAxb¢ñ}áôÕëmljÌ ¥¢(&>VžDuÇnã Ž/æ*Un@ å©äæ3Òß’ôGú3EfÃE^˜ À_MS{5Â{ÓÚ&ÄâØä¿þ)hŒx1å³–—&7¥þh¯2Ð]’D°›‡ Ÿã¹Åx³ Àb‚ Õ#ÂLèPÂÍÔ4Þ™~k²VG9üV¿6¬„úg¦]¯!ëŸð—ksé×0î2,M"‹†±Í†Å7 ªÚhOø ÀD¬¸ï#r‚òíò½áˆÃboH¤ºhh2¨sŠyqêx³ˆyæ[€þ$|¤?ÒŸú#0‰Jó·Ä€E/ÍÏj‘œVøo£rÒ¬Y‰›´EitëÇ-`¶Ì\ׄDR¾_V’Üp8>ð.K²«ë© ,9Á0þà†·_6Õ¾ü–¥Âpi6Usaä&ŒþsÕJÓñÕ€Ù 'HÒú‘þHÿw^f#¢îèÂ$ ói’Ž”¯÷pE®’ÝüH §np˜ã“£¶Ø×ëL˰WNýª .ÑÉíú@ €^D†Z‡¸yªH±sK“>¤«¬=!ã̦HìÄUµi3þäe ý‘þïºþÌGGþÝ/ XÁÞª¥ï1"ãã½3Æ?ÊøðOb`¢Àà­´bVêú¿º0>*º~Ì‹þb‚º#Añ¡À³˜èh0[`‹RôÎ@ÅˤêÌk K9+uII Jße³˜è¯Y Šß‘Hc2""ý­‚ôGú¿Ûúÿ³„Ú.ýxœí]w\TǶFņÆX¢yŠTì5F1Šh̳ ‚T–²ËöÝ{g([`—&KG:VTŒ½ÇD»Æš§Dõi‚C4úîÒËîÞâ_;ß?°÷Î7gö~÷ÌoΜ™ÙvÍïwB¾Õè]à’þ¹²Âií†ù —ýøE%~UµõyI¾D˜sch™’¶aÎóv“ŸáA¶Í¡Åv…Ó® >ö3%½æ…^·þX•½ø3³Wjšü9r&Ø”ìzß'@{òÃ!çÐ"ËJ#Dº?¸S»Ú–Æ;>/þ}¡eó‹Ø›=_y»‡»^ª¿²‚;01îM“Çô7¤?Ò¿mëÀnÌßi^©0q?ÀZøç€o½N3­ß_¼í€MŸrhWå,!á;Û|6c÷Ô‰÷išõ;uÜé‹Êª3wgqRJÿêJ“ßË%aI÷÷bv÷ewÉBéÒÁ3Ѧ—£{Ì•ÝûmxÐCzäg{n¶³]RþÐòñ޲Â3ºc]/Ƕ¸ÊÃn[Te&ÿ”_w!ξXÕÿ—ÆHÓ@ú#ýÛ²þì†wÁÊ\Ó%Udr*ûpµL-´æ{Û“ÅÙ ï<Ù[Ùƒ|(ú÷0/åñIÜõ´ŒºgjŠ\Æâ·Ù^åôúæÅc.ùÚ0ðmS’‚.ï+s=÷$Ÿ¼|KˆgÛœWݾ§ §7ð^ó³Eß?…:Ì;å;Ù&ФÕ.UmÕêºs»á6Ç8š­ÑÔ|䛿7~ƒªá6ÒŸH¤ÖÝØû¨<’¬Œouv§G`c-ùt¹W­^q[é^Jfœêß%û h§ ×‡º~+(U¿ë[ðÐrïj²PÃø|úÉöœi/&fÂ÷9ôvÌÊÝŸ ¥×‰I“ŸÚU¯HÞݳðƒüí·M—žÖá‹%®?´ ˆZ,¢æ8êžõÜÖ%Bÿ±zÅðNsç6ÜEú“éôo³ú#°¥’Âl,Ækû~jÍÔHs>Vþfä0o8îÞ‚3Y”øaX•Cäe'êçÛ ÿÔž·æûTÿÉ¿GÇ¡AC¼h¿áÔ>8dñì}ÝeÆ÷jtD(Rš¶›oêëÒ[ë{t¯;‰–ý={ÿ ¦ ãO‹_´û÷Hwdg?T½évÍö³ï‰Øžóû~ZšYéOH¤ÕÝøä%§p;§rè›—µ“©™¦ü `ïígÂûýË9Pˆš[a¹ïS(½@ÕÞg}ߌîùxýÙµŸGU›_’ïÅ4ñ%«r÷XöáXKÃ?™Ñs¼yÅÞ#tbÅ©f·­¦T@Q|Â)[Ï„SÄ'uLu»Ò: Àq=úÙ߯~?{´™Ôþl éOH¤ÛÔÝ%]XR‡SFìªÐô¦¿·A…UŸ.ÀŠ{oOþIÝŸ.ÄuÌ1vˆŽZië_u7;+Š®Ô_)¨´…¹ -è-Á­ž1¯rbáz•5£@AFÒ¹®ç¹SFüF‹vÕÕzeéâ?ŸÂÎ7Î^2b|¶»=¨ë"Cå5÷«NT.RÃ…—Ÿõ¨¾@úSÒéß6õG`7ujæùv÷Æ¦êø ‹½m~íå—Ý& AÇŸWÿjqãð«*…œz½À*dLõ©†K’3¿ŒÍûƾ“µ/ |äfÏá‘?[ôžÄ€¡Õ“û7ö»± _ð,Ï~H–PV£ÑdŽRsÛÖ3ú¼ÑÒãŸ._yÕ`@|3¿þß=«¼’ðbí·¾añAu‘ÒŸ þéß&õG@  Éx?<½Ý»ñ,:n _¼pwC2-~À™ØYŽö3©¤!;ÄßéÔã’sÙÕ#M.®8ÎÏÏzÚÞŽ–ÑZ˜wqJ:4¡êï‹!dâ:¾·Fú憺 :óä¸5|ZåÛ›þ[Ûå`wîu™½÷¤ßKc1 ö£ÿ½2V™¸¸ÓûíŽO}=øÍïîw‡Ñi}-þH¤?{õG`;æn'¹80÷]ø®Ù­UÀ¨¯—XN5µóج—ÎøêÍÜŽ‡ÈÊÇkžùºÃ÷»š]ïÏ)þÁñq•ñ!´1L¬/ÿ;õ¦,xÙŒ^ÑæCY÷U+—=}VjÒ§.¹®ÇˆS8Sþh_÷)ÌY”¾ñàF.mýkÒP÷«qFk[=-;ùt÷öÃUçbÇ ý‘þHöêÀvœZÏe]BiÎ0®Kê{}lJÞæ¦ß£ÏOïçñð?·ÎÇk€_žÃ©îTù[l‹³ÍX>4tò›ë=7ƒãC‡'"Ž*²«4kïqî1ýÝÄç\ªò‡š¯Ÿê–Ë«ºA‘Å÷Ïó ìóQC?é|}ú©ûö“žt1(važWÿ%£MÔ7ýÐ7iÇž¦H—T3[ŒôGú#ýÙ«?Ûqq±Ï–{éž„ÙÙÂÑùðxÿÒ’÷¶3àK7,s«Ï£&ó–ØžÊÎþ¡ç¦…¶¼ÅO9ç¿§rÎUz¡‡Ÿëô³¹Ö‰)gáªn‡å°'IÔ 3mÆþó{ø¢MvK}z >r|6Å£DövŽ[¶_Ãgð‘G÷Ë­úÖPiËr/÷k¦š†U.x:ä—ö;¸eé$_›éôGú³W–ƒËlºåù[93v€¿ë¹ó3¡_N4ŠêÚãæX)øqù€é]L‘¥èN|Ì/Õ}iŸÝúæbQÉ’aëü†Ó±É;#÷ îõñ¿uTž½<ù•åI¼- ü±ãœ£ÿ@ð2'tð¥‡Y”Î#YŽßùnª¿Io';Z–ÿà̸¾×ÒZ—–Ÿ°T ^j:AÊ×Tl·ÿÎç ƒ8¤?ÒéÏ^ýØŽ þ¿×ŽÞÏ(ƒ4§ÜfæêìÒc"=jD·­ÖÃÍ2w- áÏpp÷bo«tC·ÿ¸föÐ5fãC÷ŒT8jõÞÒ‘ ïOÑ;"~Ðæ»<݆DZ‡’cv½ýGÌ(Í'œN"ÉŸé÷Á– !ë =fݯhö¨9³Ìz„M³–µ^Ê<¬lúzë$±‰k?O¬Ø'ýûÃÌú_¤?ÒéÏfýØŽu¥##žÎ\NŸˆ··_z×uìøôÜô¼hü:¬,IÙSzYK}9ú×›ïÞ/ŒÍ}éø`Ðò8Ê¿çaÊ6vWGÖvY³ î]cú—˜<«~*ÖÄúgÔ˜\}ÕýDöçGO–‘Ó̽S~:uãŸæçokou`~Ñé-gAåûßÛú/‡1$u‚Qé.ûpô±¡Lw!ý‘þHöêÀrñëž*mÎ"º<~Î î<´:–ôÝ<&üz–½õ¢{7#iHî˜ô¾<ûž^YŒ q9 –؇ü|,ŸbN^ûiÒÐ «//|@º 'dªÝ4χýZ8*èh1ض۴‹³Zž(:xçÀ›^d„2Åô„Ô±ÏW8]¥Üþ @ú#ý‘þÿ÷ú›Sn?B[„8*ÂıØðâŠÔŒ/Ú0@\¶êÒb¢HŽä¸È!=]I?Q€”監‰y&$+ü pq€:Q1¾kF’Šv=—„(ãz¾wž&‚ñšÄ(¡B£ `IX‚ÂÀƒDFG5˜PÙìq ýMÛGú#ýÛ²þì†42šzê’—ÜòÅ¢C|1I¨'Ì^§Ž4i»–Ï[^”HÛ>áÿ\·Ä,M$áyN›â£Þ¡ýï̸(Lè£IUÓw⫊×i"Ø7)Žn+€,D© sc£#É-,Lݪ‡DÄרù@*ÒF6)…ô'³ôGú·]ýØ 9© éZŸ-ñ4Ç®&ùÈEk`Q¬ÊtßSWZÆñ(¦ûÎ\ºR—CÐ/rÛ¦aüÎ(ãfªd~0£µ{Qá¹€«SaA0‰îÀàžN å"A¼Š\&C@­}‰H«¬çM¸ªÉ÷@ú“Õ„ôGú·]ýØ <œÜqñ¼$†ùn‘–|Â9…n2E‘&ŠÒ‹H¼Ù«……Ñ´œàÒÔ´h½ÛüµÒLzüæö¥Ab WšìÑÏEÊÕ"í&ÄÀâ¹ár>« {VD¤¤4ÔC‚/Âcu}-‡i›tH ö‘þHÿ6ª?»(ŒÀ oâ;¦d«˜‡ÍøbÒ07˜–M–þkä ²SèØ¸$Ø+=U]ë±®ÈH¢’F3V›È70rS,Ó ‚tûâ[hO¼.-'ÆôúÆS“%K5\&PÔ=m¢˜<¦IBéO¥6¤?Ò¿MêÀnPòý›ìZ˜ô.i´F>˜8ÄæÅSHÿ5òC]6&P·¯÷8ïÌdu½ÇéÓˆ›i'à«â5~Ù)ŒWÎ(ç­ÈÖÑž¢µiú¬#áÁbnœÚtÐX›§ÆW7®¨BúSªéôo“ú#°”ÿHWûǾK°ž€Lä 7j•TÒü@¯mZªö ÿç¬Z¯S7 t¤!Åt—à6¡”ë®Ëd”¬« È#+YE7) V×F È…â8¥©ÓxPËK´ =—5Y„ô§TÒéß&õG`7hüþ7.Z wF¿C°–¯ß”ÂwñY1ô&äˆÁ°Ox6Å5¸Dˆè›ÔÄÿkÆðáLÖðÂÚñ»svŒ ’Á úñ<’ÃUñ¤i¼æ,\ÀKVÖ%îˆÇ®1Å7Ô¦…0&*B/DdÃ×@úSªéôo“ú# PÀÜ23”ï¬áCLÂõ€YI$ÓY†ø|Ç<%ûøç®k¾Ò•𦕉ŒÚ°°™I ñšÄXfiD€ ½Óc°`­–jÒ³†¤k×ÕgëjÒ€Ñ&’¦DÀ3±UJŸä«ÔQáPÆg´éôGú³W¶È9îÖ1Ÿ<ªá'@q ?,Œ%ßÓb€ºbs<¹}âU®]›—Ør§ s]¶Ä1h?Àú ÀrþªF{‰ß P%*0a°.šÆ÷rÞ˜öÔgNy&Ò¦&€Z¾D¨QE Îl&éôGú³W¶H¼8ÔÓp†ùýEp“–ÞTX?ÀgéúUÂÿþœüDeË‚ú½<Ülú/¿~0ÈŒ‰€@*LQ3h9…ÒÔá@Æ·ê–LÚ Hk2g©ÏJâŒ%NI€šú0‘L… ôû˜éôGú³W¶.Q«¿=úI@âOr*éáŸFø@è®Í É_(®)L0ÐÅ òW&ÓÍ\¼6,W?ò¸„£H¤¿`|ÏMD8À¥ÜÈXÊ| ŽnºZ§æìÔHc;§ÆU™îÜô|a„RŸˆ‚ôGú#ýÙ«?ËA¼dÎ9©LH@¢fLOUÑMÿ5Úç;®3=Ì…rÂHQ¼A7#øÎFÊ©H8«7ikfâ&ôKŽUМ¼$Fò«uúƒHõ{y‚â©ö~ÄÓâë”MméOOåi  €8Œì°T@ô@|©4ñ ¤?ÒéÏ^ýØ 𢒆3È2Ñ„¹ÉJÚé¿Fû!n[MÆ¡?tÓ]¼!ÎÈ0ȸ®[iíÄ8ÜcS\­Ó(ã¯Í¤yQÖîÖw¡:j»Ÿõ‡—éZ é ¾ˆoøHP 瑵|Iˆ:žYüUSÒéôg­þl»vhLÖíþQ§¯’3â×—® )2þ¢þÏwÁ7Æ[««wFQ4Ñk…º%Ô×GðC¥:zçhNpýb¢º0YB«ì¤Ašœ Z|p¹P«h¤Ôˆ `†øTôGú#ýÙ«?Ë¡?’3±€þ‘ 5³Wî0]§’82á7Ú-KK5vŽá_|g¸ÉÄ^ý‚-õ_äÐÿ ˆKþºÆòF'ÐÙ D úÝ ‚€KBUZ |¢¡i­æê–†)£[ó)5߇ËMVS;€Ýp³þH¤ÿÿ»þÿÊ- ¯xœí]gXTWV$ѵE±ÄžØ{ì‰&¨1jÄ‚é }€éížËÐf` C—¢4Åu-&®XÐXƒ\m×U Ö5qïE)÷Þ¹Ìà>Üóþš9ç¼÷;3ï|ßs¾Ó¦ ÁdÌ:l)3°û¿ÚaãšÉwRe£œ„úiOO6Î~É{âz¶öQ]X»ùCüîyBMÊŸ1~h]æc¶ô¬ýyùi—³j–§¼.éâX›õn0ï39Íþr2zfo¸–9¥á-R-Ð3ɧ·$Ñ /ãïa§ò¶í6.æ–9tŠæØ•fP,ùúßç;3ÛÙΓƒJ?™æ]õ§¨¿1 þ­Aÿ:š½‡hˆËsI²”Û­ü\DsùCt‡f§B'rmÎv°³€¯=ƒŠe¦55Ý/¹)÷‡ ØFõðÊ¥½wfÆz”ѱ5Úy͸»:Ó3&Uý¼Ï·çéõ£¿tÏ ¸KwžR5|Î;1”¼EK½;U.Š0­ðïU¹ñ<¿îÃÏâõK{ç>µó¾¨5ÛÙco/xïáñP¨¿…€ú¿ýúÑëDè†Èâûó,à#ÌvÿØEqq®FÅN £¯m¯$Ò^Ã翇n«ÛóÌNâ­ù¸£×ãn·\5,ž÷Û C½6•S†™¬>Ù¶ÝêÈQÿÒ/ëû{˜bèùοfPðž¿lo¯9øŒ¨ ¹Ó¶è?mÉli*ëW³Èç’ù€õ½ŸzÒ_¡þP¨?cõw¡ÑqˆVŒU>ßè¸íÿßõÓœ ûÎèÉGóG/R´ˆý)ÕÉá~ê™ ¸÷Ș9­ë<¯8süA÷ž½<÷á°ûfš…œò×dŽ7£rðË€Õ'lÿõêI<‚ËW_¤Jø-¥;V{ þ®b«»IóÁï\që~¨#ñ'áòs—:tfehKÄÙ[ wo¶;èѪ„Õ @ý¡þPæêo¾DëÆÝŽ#îÌp|Dþl9>òÌÁw˜cí1G27Ö5úµöËS®ô¯^Ñ)K¯èÓ içÕwNÞç®2,Žð§o’HÓóYœ0•3{Ý.’j·_â—ÿÐsM›aµûâ{Ù| ò¿v³Ž õ‡úCý™¬?ÓÑéBÑ©¼=ož½ö¸¶v:fovE¿½-f_r®¿24fäó&_cûáßF÷z?`ïT:»s¹ßò¹Šâ÷”m¤kjµ£=M,%S)7“Bçf™V`”Mè´)5üÆåìgŸß® ÛA³ÿð¸`ÑTés‡xß— GÊr ‘ZýňU™é †îýò õ‡úCý™«?Ã!ØW>È67ôñ›æ¯øãÔèn™zmf Ú÷®¸Ð?sáà ïûÔì«~Yêx&w°ùi9+Ê®¼\¯([JÞÙº ?ùååNÉDµí:þå%Ѥ$ê& ×Ðòîz˜T€¿Ž¶°j뱊 wóî²·#Úô Ò·'Ÿ>3cê³W»yßuÝXáû“ùذ¸Ãê_Aý¡þPæêÁt|Q7?Þ~ô˼7ʵg4Ï^¢ÂaÛl&úеö{O³Ù9sà¿¿{õζܫ|¿_ÐhYWzþ¢/Ü=Ãò²/^$mp'ëeg‘‰ÒLÂZpdóع[Žîx—ʆ¤×?Ðß~«$XÉ%¶}xõó2d6á*ßõâQW}ŠQ<:b™ó•:å:ðñð$”G±FºN hÞŽÍ´†—P¨?ÔŸ¹úC0û©3˦gѽξèÄ»1óþ@kc¯/—Þjiû¢!Úé Ú‡¡Amr·…eŠs§<ÿ¢M—y²ÝÏOŽ:IúÌ“ý onÝf’zÞP»ûß°¦Þ šÅ<£ªü~dþÂy€û{ÝuçîÏu¾>¨Ù›Ñ†r/Ó’#‹:¾ïüýÏ]±/°Í\Í-¿Ÿˆ“ ¨¾üúõk¨?ÔêÏ\ý!˜Ž½6•s¯„ Þßßk÷  t Ïê?~xVÚçÇ˾Yš:ứf­^uëAŒýoÍà‡óºÔå¾VC|dȾd[þ© ;Ã’ò]– ,~:ÖNGÚÂ~±®:øùõ³ÄµÓfçd”W‰ç”šÔ ŽcT}žZAÙ}ÐÉ^"=zË«\T#Ý&R6¯G´Ý ½wP¨?ÔŸ¹úC0l×n£ÏSý¦ø3ª—¥ÅhÑëûv™ˆÈK¬µ¿ÜgÈø‚6N]dûæìHvTŸ˜ÐïF³ø³XCw}ù¤áÙ»[]޹ñ;¿Ò¯K¥ÿî@²z¸çž£a#/‘-3"× ËJï-q(V׌}tmvå@3Ý•žúá[wûRîóñ¢~54€ÇõßAý¡þPæêÁtŒüxrT‡ªu4~9ðe,Œ(Ÿ]°¦C»š¾Ä>b­ý‡k¯gØîÖþ—빚—~|FónÎ׸pþ¿6>›SÎò°ÀÝÚGïÛ5šjEQ–3tMÙ*" 2ÇY³ïì®Lz[ÏcS©bÄT—F³ ¼ÛL­öyfÑ€ÀQ]=Ïuí;î+î§;G¬žd®9Ö#£óQP¨?ÔŸ¹úC0ráÀ»aճߟvzÛò©èv·3ï8] jÐöÁŒª¨¶ãÁªÁŸLš99êÒ‰æòŃû­\¾ä ÒäB.ÎíI¶uÕ}ó8ÔþûC¯s¥Â-Ä÷™<ü|åƒêɦ3|¯±z2³böÔƒg ‹,–,™”øÐ|ÿíóz§JÜ£¦hÝ–ù_±$ŒBý¡þPæêÁp Þ¥’’Bñœ–ç/ëós Í Ôåø¯ÓÞ˜}öÇ/Ý{±ælñh¿ëPóù~c³¹ÊcÁ›ñçÇrN´ó9eîÿºÞ?÷pÿø-¢KÅÓ¹·*JÄO©øØõìzcxŸõú…nEâ„!OÌÞf†}}úÛ_m»G¤ áA# xÔêõg¬þL‡ßãô5œ§”ÿJaôÖ\»ºñÚ}ýgãBN“ªÞˆBhr¢5ß?Ôêõ»õ·øÖeˆV¶Fn¹Šƒü¶6“ ß—‹–ª°1°|CûžÛUD|Ä7ù&U¥w ; 8ÙÔµÛÊx>ÉÙ }c•p"²•ôøõ}Šd&6õ …üè´ÄX3‹Sü´Â)4 F| NTÒøN±ÇÆÆK„qP¨¿…€ú¿ýúSýñ DëÇoEaºÉè â(UAR¼¹Ù9Ì­}Ót æ'ñ" âš$ „ª4TÓŒ}õÎSN8be'%Só$*†dž §’èÄ$ƒ0¤Q Z "'Ê­þþ¡þP¨ÿ[«¿Åߣ²IBÀ"H´&1VZ‘f$u| Ôêõg®þæÛA´n‘Ð6µËpôùE$\7 /MÖ›´²Ú¾8Ìëëd>@Dl¯´œ$Zn‰ŠÙáë’ÌØÇWïÖlÒ$ø^£h’ :C¼l“ÙJ¤\¾Žb3¦"ØÔÄÕzË€ô‘,)êõ‡ú3Y¦á/GË•V,Òåã›V£=ÑÌL¥Á”—•öøÅåìÍE„lIæöÖ4ò…!ò ²vcI¤{‰Žp¦Ë6"äºó;yeÏ û"‰’«É—1ž€pPŸ“×ȧŸÈ8Êú«È þP¨?sõ‡`8휷–â'ÖB|üôO„?Z’hxnÅzû\§]ÈDá¾Ù™4ýçó¼²uT«…•D»¦‘89 ƒtj3»ð7¿ gâa1BDÆÇš•E5¢ÇwUE+•|Ú  Szõ‡úCý™ª?Ó¤¡kJutϲXÈǧÿþQèµñ©•°é¶EÓÈÇü1Ìm¦’®ÿãüh×­ä“lxŽknÙ†€Jy¬Ü$êþ •§†ŒÏLSôË=äÔ'•ö‰¹¬wx#,ûáÒLøšÆ—P¨?ÔŸ±úC0@´&Âh­¥ù §Të’&»¬µˆCƒ7½öbv„!yéŠfÄ|›C>l2®Or6E=D ÒÔŸ_‘GòŒÏk‰ã –žDdQÏOÖשׂê—Ué&(7ÿúCý¡þÌÕ‚é@x_)·(,v@óü†Ó?9iJ©.+íDà­ÊÆ‡×øÝZÁAùiÍñÿúas‚l†óA’G5ˆ("^Kµ ˆÅ×R5Ù#ðCKqj¢F,6…ª©’“úFøÞªØúsÕôDÿÔêõg®þ ~–¦ Óò3!æøø54-Ò(ä„^b½}îÊ)ñ1• ‚BÖ§RƉø<÷¢:´>ºGQ;!#Xé*òeDÌ/5)¤§ñ´%BKt%(E‹RÍ.âˈœdüd5ýÀ  Ôêõg®þL„xoÖZ± GÅÇG¨õ@ÓÖ*ãÈÊVÚÇ\,ˆW ñý# u\o…»¨(‹ pà^¥sW…á7JRI· I£Xë)×8ñÓÄ2É•¢X\‹¥õ_%‘òeªøY¤’V`ú¨?ÔêÏXý!üJÍ´Bë®ä$æã§Ø~M—¾)û×,­Ô—[œB÷fnc>KezšsL¶GI S¾ˆ0\Ir%(ñ¼ò5Ô~Œ%Q‰ÆW‚bD¶¹@ -QDÌWÊEŠ7øp¶½÷Í4ÿðß‚ŒKøuÊë œ^P|^SymÖ5ïô'—Ü=îšú6Ð6äg)sgn­w¸Þ£úÈžaCó¿ræŸoô>Äéz,ãë– ¼€B3›[™þߘñMùº›û¿±¯¢êo–Rð«×~%ÙåÓÆo!•_Dì­ÿcöóC—m$ö"¸pÆ‚n‡Ÿ\åc'wWý£!ˆaT§^·ëtïòÀþ´â·…ÖÊ>C.½à£þ­__ÿÉ÷n § óÇü1æòÇbºî®¹v”5¦øEøç÷þee¹.(kXÑe'ªÿ°Ò‡ê{‚bËËÛ“~sÖˆñÇvϽ±àˆé÷djþV%äŸÍß_ø¸§Éþy_]ƒ¬«þd6…Ú´LòfÁïu^3òZ¯ 0qB]²Û4ÿ$öà]«~ÐÅØcŽçWßàžùÙýñÏs!£JþM ÎY>-ÌóÇü™Ë‹áŽ«º}y2í…@­~ÐÃT?Rq ©6/4å û# ¹ÅdÝèE)ÓC*Iwï‹÷«SýóÞ®ÿsh)í…°3ò¯¬¨ f%Aé’)]ÜEúÛç®'꿱ÇuÿðkÚæïáÃbJLìžÄ¼ºZgÕ4Þa+Œ{w|kQ1úlÿÃÝq=Wåù‡^ÜÔõÝ&óÇü1æòÇbº&ïÉ9øå••Îï|®ß¼ëõý>˜áwlç‹ï!„¿Z5èÆ”ª½ÛO£O|Ù*Ýýé[å’ÒNUëŒvœ?;ëìwNW?K?}Òmðœ_ÖB¿·LiAY”ìʲ¢5D¿ Yo4Õx¹‡{õä#sçšPýâøNìû~3#ç&kʯF}ãs =ëšJ¯ß"Î÷ûß{ÉSÆ)stæùcþÌåÅt•ûÖxþõ< ½•¤Ñ`¶Êûž~ðsÉK¡¨%š>~ar¿¸¯½õãñŸ töuF À+ ¨îÈ ZîfÉ'™×<Œ8÷õY¯´©»ŽQ]Å}yt 'rÝ©ÝßNìþütáDÖt?ûø‰©<"ÿU:KðãÖ>?£O?rÿV–6pÅøi[Y3‡GÊjzÑÅü1ÌŸ¹ü±.°®`:ëÑ®ø‡‰<2?‡Ý^ó}å<•¾¼]‰àÊYÉe_Ôu<àFEJö·G“L#yMÓnüð-³?üiòÊ…,.ízÚÍïÒ©w·ÏÚGÙï=ÅÜ ÐÔö±¦¬øóÁ‘èNÅÿÎèCozÞcéujü§ Gš)øŸ#Ê ޳ñ>±uÙ!ŠånæùcþÌåÅtq¦n]Ÿ2Ló=mÿ¤€—ÿyiº;\²`ôH.õžø’9uòwæÜBº™^¾e¥5¹Êë¯>ž²aÂÃï7ž\„nKlÙúfÈ%Ö£×ÓÁý/t¾ïºcaþ˜?æÏ\þXL—Gçÿ+0‡¨SiÚcÇJæCh>ä«ûÒÙòpaÂü݃“ÔêHÄžëÓÉ 3ŸätÊ’ívæ&D:½«m5éÇ:¡ÜàAg"TNLýàÜú°„‚·›tRú¨Fñ¦mvÛ¾öÖçsF­¢°ꀾVyÞÞÜ÷éYX!Ü90eçuGÂü1ÌŸ¹ü±˜.'¼°£p8=óì7ϼµ VØ6ù8­ÀGÕ@Ï_çk‡äEcÜæD¹i&šG· y)û]]Tºè+1Ýu0â«7.øÂsïpzq´¨Ã7k»»²þ]_iCHø×”‡R‹ŠòJElJ›õ º‡Ó›8Ù7lBãçQ©Ãn>úbÚçé΂bþ˜?æÏ\þX 9{éåÈ^þcéX_3ý.Ɇ075ħ„fþO·þwúŒtvŸLó¯ Á—îán÷®Gõ÷òú彨tš ™b t;o®ý.‡n 2Á½÷Œuóz¹uîý®u6åR€n,{£ë0b…ç·[RUuÞÚøYYÛßOü2›ëUM5çfaþ˜?æÏ\þXLWð¹;G+Îî­r~§ƒ„Û{ÔÈ+ç$Åÿ{Pƒùêþf͸SÕ{ñôìÓÏ¿Kaóÿy>KîÛÝ¡’xÕ2¹Ó*î=Z™‹:éûÇÆŽÜ8·?-¿­ŸY|èÌoâî¶…²7hLÄñ¼ïyµnÅvÕ×5úAÏð–CÔùÜ=–—YU ;)N>¶ óÇü1æòÇbº-y¼ymÕ[Zçw¶k¾62¥.Œ°y «~¨¾­àñ~îóîáÍøûû‡¾4ØsÜã§:Ù¥ýÖk¥{'–ÑÈZ¾dÄÉÍ}¿VMoHž¸‹†ß.É‚ËI¯‰ÆMê3°sÕY$Þš1ƒú¢NâmK{uÁÚòÕ¯¾fäÎî#_šEev[aþ˜?æÿßÃÏ`=- ߘª¢½ã·C?€J¹˜5EF >?ió¤4"¥kh¦ œW`lç.ÉÏÒ¡$ !ägë’ŸºE‚8×i6¿DdÑ&·yJ€È3RŽÍ/ãŠ2-ÚóÇü1ÆòÇbºHé"¸Ù@©H~”‰ü`¸2S¯Irúbº”¿­š —BM©é鈜B"‡ÌÒµ-'PŠ‚Ì¹z´&9´¤! fÅ­³ºR~I„%½MK”’åjj“b«°“Ù±¥³¥š†Ð/·–¸£ºÕä\MªùçØü’нáI?#ÌóÇüË‹éD<»ØJ» íèTˆƒe°Ä”‚Ö-µûËÒéäoë= –Á2”õiª+åùo4?)?)N(1"WA ILޱýoµ+bU™Z”Zió˸}‹(żl$c‹_Á ÉMשèÿÀü1ÌŸ±ü±˜.Sar! ØÖ™(dÃÔ|ƒÓðß\È&#õü)&•™ÔD|èFý0¢­ ñWµLºRÆ Û`Ö O©Ù§!Å™í¢}ÊyÜ|äID…Dš®mzZ¶–#Æb¤ÐšÙËkJ"Ìú“€˜?æù3—?ÓEJ'Uê\>ñÛ¥ðBa^•I)R¤Í×QíÂÚê?Ÿ­.1j’€4"%‡J¯Ù!! ‹K¶6ùm0!¸$ !vÙ® Üä´”6 l0£O"**SS|ÂBe>ÓÖz鵤XePÓoÁ1Ìóg.,† ü%+] £5û$ It<\—JiJʤƳ4xAúuöèPŠ}‹]X ”’М4{§ß¾¤‡½Þ’B­1JYlº©M”F¤YRP»ä*¹&ƒÝOqPcVb‹š” õ:WÂÀ˜?æù3•?Óœ za¸v~Ø´û–)NH"!b2^°yMcµ±÷›—–Ó_ lßy\lLN@!`­±RŒHˆ9Ù­+qm­‡È¦J)ߢ³Ÿ9*×RXÔ80èU@™(2k]cþ˜?æÏXþXL-çm2ÑýƤÆÝ?™+õjÔð_‹HytT…ž¯½ÓœbÉkªÿUŽ»–JÏÙ!9 çJst*¨äe#mvð+‰Ú–0¢‚Uˆ¼Š¸Ù/–§¥¨ RÄÏ¡2ühh’IH rеƒt0Ìóg,,† ñ'¦RýÀî/VËâ#áj‹–úd”íEÈÌMA CÚê¿,>,3× nét“²©YgîÚå/‹ÕYR”âåæ\=‘ ¹šÔ¦üRÌ^“F¥ß´žImÒ@YL•@¶¶†k´µ{ö•×"µž~óÇü1æòÇbº€’·tm–+a4ÞÒ\c”Ñ›ŠJ¡?rÏ^ÿ9áÙ¶‘Fk—(E~¥(ûnŸ™¿88ß ˆP®¦TÛ”Hk5ÚËckK¢uVªQDÛ/â¥êH¡’Ú  ¦@ÓˆHhÔ¡ì»~FJ˜?æù3–?ÓÑ¡.ì¦@ÊP_èüðÏgåŸÀF ã5Ö¶¨•Ù펿 Þ² Z•·9M… Ì"—šÔôŠ1×~$(ò‰ó#@;ðK…?’³yÐèWÊ$fÄ×'…ùcþ˜?Sùc1]¤Ì‡páHNBÍ«iïF 1R¼^rt$¤±Ñ«²ôíÞvûѲ|êá»'~Yl8,K¥°ØÁ/–$l:'“Úô n ¶¨eÐä—t[_»0Ìóg.,† "ßÌB-­î/$ iLœmPjp! 'ùdM–óüm}]It\~¦Î¡·k« 9VJxÛÛe1‘Yy.,$"e z³†”„ä¤ÓhElÏP§XEsÐ8,RˆR\:óÇü1¦òÇbº€2aY‘•Úâ•&£íݳ\§[ŸIÃßš?? 4Ý™ßþßgE&XëS‘Zº]²r;Yù©™vùí‡rÇfi Ž*‹Ö™$¶$ÚW !{Û`Ól&¤ãן‘æùcþŒåÅtyDd¹™Æe¢ ¦¯2€(:þ6ùs‚Ij¯ÿaü5Ú¢]@Î]^AãHÑÆdüeùf¹À•! D<ƒT–OïTR àE™uéÂxmMùËd. ‹ùcþ˜ÿ ÿÿ_r=À§xœí]y\×ÚV,W«âVÄ*¶ÕzÕºVoëBÅ}÷V@Evd ²“mβvA@DQQA«­¶ý´Z+~jE?­¶nU\oq©·.U‹_& È$3ɯÈœçÈÌ<óžÌ“÷üÎyßóžé„B@ÁøIï¡5W&Å£Nr]Cÿ‰¾èôCä)&y~+ Ï–Ö}þ?}Rð/¡ý]W½pQÀ/nÛŸùpËÄܺ©JÒ–¥%¿yñ êćûÅü{Ii~#Br¾Xu%í>ç±äà†=ÿ×üâóYº£Ä±/Wº»Dy4îqÏ&Ä_þGîoÉvØÇõ‡úCý©«?Å!º½jÎYƾn$(ÂkŸo÷7zée¡wq>y¾bn8(±ð3Ü "^n¯ÿ Zž^·t:èÇP:×ûN$Y»àòá CÐÆþëÕβúb¹œì šÐ)7‡>ŸOO#O•zŽœ¯ðyúÙòQS³þXGˆRåçs½Uo%úîÕ•wœüèÝjòöoõ‡úCý)«?Õñ¹ÏÌáf)#LˆI¾újÞ´ób¹ómO y~Œ’¼ é<®×÷8§ƒÏ'ÄÜís¿æ½ó?Y¾ gÉú½wg?½JÒl/¯ “{€½ç_ýV#~ä^é/’ü&êYß>𯋮ü—Œ4wȽ†±²›µþ£~¾,ºŠ#æ÷93ºE›u–Œçú:»æ³‚LÒöõ‡úCý©«?Õqz_xÿ?²„3Ãìž/žM4  {‘æy~;¬›u¨XzáJ†Å“˪'½Œì1s÷WÇqè€U)™ù´ô"RF?­ ®‰j(–,öéÜíÒ˜†§U$›Ýh¼*ª‡_ñ§+½7œ%Ëeñ\k¦ûªîç}ø ÷i'A¼Šé 1׳͎-¨YWÓÏ'ïæXÙ4êõ‡úSWªã×Ä NH}¶í :kß^÷ÇE´Æk|ßGûÈó-@´£püñmGÎXr€ê.CÒІ[só¿Ãåsµ"FÿÞý®‘qï+˜~=…E£ׯu×»ÚÄCGM,6ØéFjù½yÅ$¹_Ì8vÐ}ÓÚo“u{txטiæ‘·–žÌ¸z±†‘¤ýf@ý¡þPêêÑ!0ø†½LŽâûyz»ᳪ߹_±~ºîÏ‘c“óÉó-"D1ùîø¾•ýÛŸñXSóùi´ßáWVø‹R%ßåWËF·¸ »X6cêe öi¢aÛÊK·¯&?‡‰œ²û¤p×êúÀ©[ Ô¤¸ËrEÏ“§¡ÒÓß³þ3k—gmŽ-JɘvÐêÚö´‚һ̗‡»Cý êßPÿŽ ? e¢£a2ý¸Í&éºM!Ä_¹P'sŸ†n­Â?<¢eá-a>ºŸ»2·‹þÛÝmöœÿ¶lÑ’ëÁ;­òo÷yw5·b/þ$¡ ˜¿²5,ÞÛèKàÈ‚ý]÷>#¶»¤¨S&>vÌš8 Ûä¾gñ¯­/&ÆÇGè/Å#{ÍÖšØÿTàhç´Ÿv{VX§#ŸŒ\×Ï)$XË#ðpÎô gL¨*o:À´Åï£>û7‘k58ÿpzТµuWcoú(¥SúŸŒˆß?»?}ƒ->#(~ø€^g· âIû'ï?>bèæCAžº£š: ©VOçs••œ#d¨ç¨£[Ý|räÛ&5!nAÙ©;o-Übú\G<Ø´«_§™V':áµ'~m M·pFzwÔêõ§¬þƒH5¢Ã!vXhïüå·“°‹)¹1¨P ªþÙ½È%ºm͉£ö—|:oFLÑ?ž´Aþ{Âi_7Ážú%N…¶ùÓ§-R§}v£SÈQUÊg¶¡uÎÒmå‘ôbÎt2µ”8µžPõdÊ[óÄǾoÕ?8n“ªâ-DZµŸü_þêõ‡úSWª#èHX²‡Fo׆V6øËæd~©Dï'Ïw®_Š7ÆvÔþ'w\OGÄ^6þ+ÐX>{îí2¿|=aþ‡ÏfW —εðÂV^=¢òq/Yh—ößâÉP_7Æ-—!Ä‚x쯭»¹ïL^s|Rúßè÷VŒ>@`Sñh·eïpM3[Û,ФI˜ï«Ñ[Ž¢ôfÜIÚ-+¨?ÔêO]ý!¨ŽßG_ìþTÒÍî!ñøàý-ý`4úcdÀsÑ+ü…¶ŽÚßýõ·½Þƒ QóܳÎ>]ÏtsM&±,Ý/rQ"C6[¹†~0$¸8móº…WoˆcâNyLì=oSr3 šþªniç6žh9Äÿ‡ëù~uܳMæ–‡Ýeó<̆7pÞz~è°‹»Å'Tµ(ç~ÜLk·…úCý¡þÔÕ‚êô‚¡ëYF¦•Ÿÿ“÷=!ýQyfw¬ÞÜAûâ ´…‰^»p¼T;g8zdW-¡d4ƒwâÈWßÔºãwÜA7ý¾Ì{È>oqšB+¹Ãä¼_µ˜È¢£~ÎSœÆ<öžÕzºàƒ\ß7ëð3æv[ä)ÓRÇy–1ÛNn&Ä*ÎcƒROX €¤³cFÐn[Ÿ@ý¡þPjéÿ ÆB@´x£Õjr¯®("IJˆB 3ÔrÔ~ë[¤´H•l%Ѐ˜Æ+ÉP¦X¸ÈÈùVùx·EÅÿ‚\¥$ÍRÚÁoº "N A·êåöÜ û{0¨?ÔêO’ßܼ7]ªÃÛuDƒPÆ_œD˜Žæä©å'’| öãÂwhpøÆQ27ÝhHŽ¿±‡HˆÝ¨&iH4F…^Ž&ù‰¼\²ü×·Aʼnáù2¡"ÏHRtžV†1_˜¦$Äk7@MzÄ}±}€úCý¡þÔÕ‚ê@ø>);UÄÒxXúO@§£ÅéÊæ°¾¥[A¨f­å4@Äì ´< ßÿI™›Jjlä0"+ô¦ÈŸqB'Ï$Ço¾”\ª¬”4ò| JD±á¼ñ;rd:9 |~› @S@6EM„¨?ÔêO]ý!:€ýCp)Ûo}~Û–åKQ©˜,EËu­‚N$ø8ö¹¾3-ñ"b£›Ò¬/’RÞŠÍ2ö>ŸVnhrZ åGçèöñM•Š$Å´dÓpÆV3Öbã3&êÔø–&&MDÊ®eHM-úCý¡þo¶þv—[BtÄ¥;†3B+ˆð±„gª+Òš­;%ÌǵŸd)gôVºYok‘,³·‘Hã£'­*Í|=騄S¤!ß~ã}âyj*á1³Õä‚pXòP—f²i|ªNºÒ&ßâ ‘/ä¥@ý¡þvêÿæëOè Ë8;µö¯IAø¦êf$º6[%7OYããÅ&”·ÛÇé¬Uh…Îft [NË/ œÆ@Ì *ÊnIÛù‰ÂlÒi<€ŠÙ!Ø:" æˆð–)ã‘%lAöë)ó$úT[i@Ëì" €úCý¡þ„ÐõW’i8D‡Â]nب²¿ø¦šÓèD´Ô Liã’„øÖn‚²sSÍÒˆ¦ÈX¨l³Ž@‰Ž‘­É&˜†Ãü6`m^kWÂR‚ªt²i< å…å§§b+¡!S©'SK„µ8_+{=ADìT >Þã;úü¡þP¨ÿ›«¿ÝO¢cHJsIÃÙä7Uÿ ›t©íƒUŽÛç¬Ü”Ñ:‰ù?3LY¦%äV@Ê]¹Ù@( Їè Ì#~XQÐZlM0™6#ItYŽ©ØØXA\¦†8 "fr‹7¬H¯nÛ¯¶áàMP¨?ÔêOeý!¨ ¢El58P‹c‹Uÿ°ÂÐÌ|ËÛN9l_œRÙ*‡¹DÂ]±­aq ?1²LK$gôõI‰ÖÜY±mÁâתɤ±D"³¨©|Éøtxì,‚Õ¼h\Ô|3‰€g°šÄŸ˜ÎBý¡þPÊêAu IÞ Jcw-Ž ¾©ú'ކeàm:å }„1Âõê×÷Æü?>"½øY@Èä© D ¥‚FE»5¿˜;K3ɤñ° H¶¤½žtùlÄJµr»ÖÒõi­»€H¸ˆÕÕN@” ·2€úCý¡þÔÕ‚âÀ¶ÔÌ]¯t g…oªþ 6nþ‰s‰ÃöùËK²S_'Ť‚¸¨ÌÂþoâG¦gÚœ/DÀˆÚlaëOì„Ö@-nm±Ñ´ŸžœkíÍžFÿgáü LHÎ öfP å–̉³’mlZÖDæÆç·OWùÜd­e>Ög¤Ù꜠þP¨?µôÿNŸÊ.ÐGxœí]y\SǶ´ôUŸVëÒ‡¥RÄ­âϵn­¶UQ7ÜU–HBöÜ @€ ²/ŠŠ"UÄ­j‹}Šu}n϶V}¶Úª¨ukU¬­¼änI|ýãÝùþ‚{ç›3äË9¿93g†.¡Ò“½ª Mÿó¥òWJÆ?ž¾ ^©tpÖ¯ýŸÚ<0µ¢dHÃí%ë¶ÍÈ÷H2ïñE÷U9-#y/Odó¬»û쿟øåIþg—ii-y¿Ê_[ÒØØ%¥ãCÐýøÏ‘¼Î×ë¨ÉâºÖ9x5^2~®ºtõ•9§ö>ZcÊñªp8}“7ºc¤?ÒéÏ^ýØ×wNžÝRþµ›šÇŸdÛÃë†~ué—ÈcSÿÇöÿá+êßµ ~šÚÎíà6l†Ú\¾ ;¸ï§ï‰ßª¶.-Œ÷·6’ÐÁ™Ï{—\süòotvămwå=ßÐù±¢ÀvGÃ×3?J d_¾X©sعߴ‘ d‘ªTô؇ŸbüðÝUpoäÒŒ éôGú³W¶ã~¨z¥hSüËâ+~O|ÍqôÞýxÇò»ôÝZk_9Ïc®f£Íªº}üÐÑÔnD7¡¦z§îÁw¢›Žüì ß<œ3†,C€’q}Ïg#¼½‹Ú Ø‘÷¸ß¾?m¿¾YrbÀŒ©Øþ7¾¢ÑŽÙ@ðjù¹ ‡zOzËÖøô(|Òõo:õ° Òéôg³þlÇQѵÆ2ó]‡˜¹Á~àkoÛAþ¬þ‡½}1ÿv”}·q¼án–D‘(õpqο]K&x×Oq€¿I‡Š) ß ÷.½#¾Eie¸kפ¯klãLÿÌis‹ßœM3ÊÉɪEÁüý}ýƽö.>Ï–»ô ¬3zÎÙ±ó÷&ƒéôGú³W–#&Âûø(ûK”SPÆüŸäïnEkòÞüögï` 9ðÞ¨–e3b]'Ïí7ùÓ7“/u[{нñú1“õµŽÔçÛ¥—¿ãR…°`×WÜúÊÑ— J€»ë´[#·G•¦‘²‡õìRµ M'|©Ø__x³aP3ù/É<=ýrÔ ª·éôGú³W¶cäŠÄߪ{Õè­çcýçeûÂÏ?µý ÒQóWØÿPf—6YoýŠ|™ŽïôÚ>ébÉãçK>}à]¡Ù7|5%]U9+8µäí¤ûäM䣃¶Þ:#ø ¢—~eX/AÇ‘,~ ô¼NÓ/H^GN}ÍfÍé'K:æ0À¯öç60JþH¤?{õG`;tÛ&¥õtr·š{jñÉgÇÂI§•á\aîVØw^véçé0ñ¢H¡%ž!ÓC>ÒYçµ÷§#o )í?vÜíÃ…úõ4ü˜ß=³ðEmYpÁi¶vÖqGâ$ðDÄc»ýY“Ðÿ©>é³·t'i†áZõ¬ßÃÑå‡vèÞ=i³ô[¾ ÍÈ[ôGú#ýÙ«?Ëb~ñ÷~9ó¬ä¿/¸·piŽV ðŠ>°í/±ÿÎèQ|/lHÑ–íuÅ–¦¡miš?.¾¦ÓYžègGÿaJÕóý´ü…ƒíòîíëdèãԇΠ‹N‘Qaߘ<.µ+&|»ìó‘ƒÓ® 5lzŽš0þÄÔÚöG˲݃¸ y´CoiôGú#ýY«?ÛÚ­7ñÄá€5|çÚ ×ä¹×!×¹›í=?êU³—d¼ÑýŽS1:âÆ¯—ƒ?3“ÿÎc7ó²g­ëÛá‘t§Ï¼÷ý7s¯0à7-ñxÐ}¿÷lâE¼ˆ”ÏFµëVGXhl€ê¤jZ椡¯cD‹¦ÊáÃjýjfަ0/-¨þ¤©ˆ¿§}u¾"¹úLôLCoÒéôg¯þlGŠÒϪåît‡v)ø%5ܓߜ ox¤~“þ^Œ—`{Ô žx Žýñõ¢~“µâEÕ^›Ì4Û°•7¡ëÙÞ{^æ–Ã[§Í_‹k±ßhÎ=ª+G†/ý|øó+ØA峿ôHœË´îÈ⻟5dÚ{´Uébç—=¢›Ï¬²xU]º§W·ß”eïw”;ÍñM÷¡êiYÁ×sšòL«„x¡¶ îúñjûã†rܸë[7^Ýb‚¯™Åhè-@ú#ý‘þìÕåPö9Z¹wØköÒçLZ8&„÷¼û[¿ÑRûa¹nÌŠ#›Îï sv®Ü‹ÏÉïÜ/ŸÆ³Àt3¼îÏ+L>ðZbk¥Í«ÁºYÛ•æ2½YtJƒïuý!¸ÏôÀÐüS=¾ÑÞóB]¢Ôû^ü¹±Š§÷ŒËvAŸ÷lh«iŽI«n<ÏþfT=´kΰ’G·¸·ÍIþH¤?{õG`;–W}?äÔhOÒJV*¨úÖ¯+Y§$hWÿkv†Åößx<ùÓö²­ÚdïÈ_ÂGhfn7üîtEž±?ZdG÷Gÿ©wíÓõió/ÎîNŽÎó{ë.ãÂbpyÈŽü˜iß 7N~b¾–\þ`бÁ4EQŠJ°&B\`´xê–šsܦ§Å-!-‰ n†÷ Î4\*>›ãÒ¯>f6Ó±7éôGú³W¶ãzSøÅSï™}™6„ÂcK¿Ÿ~ï:|£ñú1MtÐbÿÓwŽ”½Â°zHœÍë÷ì´çVÏ÷[cVÎWj~·'i¥ TØÞ5Nk{oÁžãx°·Kù¢õî…Ìù7l^ÚŸº·Îò`³=½Z2ýu:~dÛœë}WõúµS‘Ù\92ÍÍy½}ï[*—ëïø49&@ìCî gîí|zRG ý‘þHöêÀvØÖïzú ¸–¾¡Vðqjo€Û?ÉüáÛ\óùm8{fü±µ Œ6Ý„’wK#î劜õh›Kwi1ߺâ– ~Õ㳿ÿ®úÁoûî™Ôôóžjsøêw¦ëÄ>nƒFûšüã?/£ÕÌU¯Ïžµ;²¦ãæø `޸Ŕ@­èW|¾\< œ.¾N®uWsoÒéôg¯þ,‡¸6cÎtžÿoæ±À¨&‡µ ¡ƒË’ ƒ›ÏoGHu˜¦vdÓ@M£¼OÏt»´cAü_ÛgüË+Õyÿî¿ÛâË/\7 &ÌŸ¦òç]ÚöDÿÊ®ËNŒ—#[0¨¶Kè‡×zé;^ÈåÝg·By#4ÁvxRoÏ/__t¤Ãu¡a«œÓÏÿ›‰yå×W}ñô£qÖŒYQʽcv€ôGú#ýÿõ§¿È5˜À£¨0ÉÒ+3ˆù`²ØVh“ã㨻¶Þ¾hiyVPŠCùEÙ) ÐÌž»273‰”€B蕟¯I iTRn¦NMóW¶X’pRW'wn  J¥M£å ]•™n:œ/¤¤òJ,ÉJ¤ëéôGú³V¶(#ý6f‘}¿-â ”  ®(MMïÖÛñÚ¬â`Aq¶Ælÿ7ðž[´¤þ "Ÿô¢4Òñ¨ŒåP¼oodÀÄ¡E©„mp¾D¦K2ý¤™&H¤?ÒŸ½ú#°˜xQr•ƲiÊÇ}F$†ë2’,ŒYo`?©–fZäÿ¾tUáìºÙ‰Â"6¥'Ru 0Y”:“˜ß±'Q@af"Ñ“Ǩµ”|[Â92ˆÜ¶_–­¥ †(ÃUçh·ê JÊËH¥Ú*aT!¹…/‹Ñ¦G[æ Òéôg¯þlP„nʰbîß°ü'ãÃìÜÔD&Ë/Á>À'ÀÞ–ë©=Ú¾ °‚`-‘Aåô“{¨E¤RŸÂGñKHšà136f5Eþ€„«'X=lçKDFñÏœéôGú³W¶H=Å[Ó,_lã–£Äá‘°$K“ÀÜÿ­²0¹pÌ—«ÖYþm7¬°ÉòL¶ññýKõ4Ûs-üùjŠvxˆznÒ‘í$*•I¤| ˆV¬¦CSŠ•é#.T¤Œ¤?ÒéÏ^ýX€Å.ÉZŸly ÐÂ7x£h>×2Ýþ³Ú>nQàƒTd“lã1ëEÂMË2âÜÚ§˜¾¼§™/åi(V J¤×“O5¢“µd|üÓ -&®jmñ(˜”Ò‘oˆiŒC"Òéôg¯þlPE{•娭ØÄùÙêæÓ?šÒ´Ds·ã,´óe_X¡KBÊ kÆ/òÜ ëÄo>œ—ŸÂhe÷pN>i­°a—R•OIš·3S‰£&îˑɔ“y_®éÀ73@ú#ý‘þìÕíò°*gp~eª<Šó³5flÿYe¿¹üÅnÐá|Ÿj§qI{RD‡¯é¸GgØØ[‘^œÆ,” Fç‘Ü‚‡>§Œô¨q+_,Ô—1ºÎ'«jçK$º¤|³¤?ÒéÏ^ýØLâ·¥Zq築ÁÒŒd|"mþ7¯Å¾y ‡¸ÿGÀé‰ñqȸÊ"7¡ê ÈxªUº†û=‚äëµ€øòh•žx÷`¯Š º*a…ËH$àL–M=ZZ)E@û"òšŸ ý‘þHöêÀrL¸,¿Øâm@|–]þIa¿Äœ+A ë^ÑqµÍn0ñ²R½5WŠJB3ÛÏé6®dtÅg_¡M'>ç+Õ_JÐJÆO%¸@y´’ª¨­™J.Ln;KdA€ôGú#ýÙ«?ÛT<Ÿ ½eÛhͧ"9¸ÿëÌÞþëhßœm<ƒÿG%–·ÕÎNoN·fPèQ¥U·Í ¥áœ :3ÊŠðáƤšf xn).¤ªáiãK¢ô>>—çPV½0ƒIºÖâ+œ$#¹7„¼¤?ÒéÏZýØ ánI·dÚh8ý# ÀÚÅtÍŒ yDàgiŒ —¡RÊ I-MkŸ´Ë£VV1p²":º¨eÚl¨ê ZŸI7k7æ E¦5Ãø Þp(}`@+ÎJ2ŠŸ†ð¡¡®jçK¤-ñ×P6”iv€ôGú#ýÙ«?Û‰Ášó·ñɧ<Öƒë|-â¿°/Y™ÈtÏpùE$GW’ھ耔£Î3Ëiº”F$4/ÕáOTÀZªƒ½„|LÎ7¹5¨D~EY4w‰µò1ñéFÛ€@)ä1ûLp¾(¾ùJP ¤?ÒéÏ^ýXÃæ,.0w à_R™ÐÆW¤%Ä.7ŸßѾpÙzfÛx¸ÿ‹#¸YE.ÐÄŸ-©°¢ôççf$r‰hߢóS(•4<#½ó6žá„±:—Q(1Ô4ñµ¯5ü Ñ\Ú  ü–ÿ -LþH¤ÿÿ¡þÿ8xã.àÿxœíg\ׯÕhìQcbObì¢÷zÕ•X1vA¤K]`{?ØÊv¥HQ)®hbÅh4¶k,Q¯Éµ+š(ÆDQïÌ‚Š°eÎ|sžOìîyÎ;ËÞù¾M MºÞåkö“GÙ(ÑϺñÿh× ~çvj(×ÜÙ_[ïõ|{óá¬k[œ ûXýxë€Ì{ó>?—Uëífn·N(Îý–nü›þØòéΔOÜò®ö>¢]¾¹\ÚïÉì·â_¾Åo:¼©kgWõa*~!hövd…Yø‰âeʪs‚Õ‰”â³fÏÙû?{Úß7D[9Ó¯bþ˜?æÏdþXL׿èöÇ|hŽw^ò…–åôñ9vþ0Ì;jÒ­Èþ×ÿ¸í‰Žß¤wR, û§;‡ú$뺋vYj¿|}ï&8}ÝW¦¡.ãì»{í9¥‹ñøöýZÅ|ºM耢²»wÂîì0·7·óÛc{ Ò‘¦©Ü+Ë˳o÷ûÞcôÎch^I“îÛnŒ¸vùaјå×#×óÇü1æòÇjº×‘®SòXûÆcÎÙõK[ïÙÒiÂHx«¢¹±mz ²ß™Ânf嗻Ϭó¶ìÒµ‚m¡²tLÛö7úú\Ø3¢Ç‚ߨhQ¥…ñ‘Y3Öi«ö8oè²YOc#°U.2¾é6¨³¢i~©~Œ3&76d…ì=,*93+i„C?ú›Ž,óúl¾óGæÿB˜càÿ.zd¬F$NéÊÛOëÊ] ÝißÏÚ½è×#Ý{Ãvƒ ûošhkÃc¿s .Œ<غS÷#¯½)9|`êûFèåsñÞs'Ãjoí}¶ÝJvä§¢ÜhõÓ^Ç«jé)Ú´æWÿÓð³‡ÒÓUN§ÕxGÇ(n†’>m ;2üþX4*‹È#¿öEã?h^Ž~åVq\}Q–³n©'½#ÉBž¼sõô©!{yÑ8°›¿Î,œíþ½ê!æùcþÔÕÈøÏ£«±è^ʳÉO?@l?RñËû?vù@;¥ôÐþ°ï/Š/þâöÑ.sßx•?¼å浑3,ãÅ]¶]u¾¬†kùbøžQ-ÛS_3ì/oÑ»§Ý³×’¯Â îæò·õL¦qí¤î¾3;c×å¾CÖÐôÔõø"Óhß!»Ðlâ;•sbC«²Ag?ÌóÇüËÿgš±‰x™].Ž)ûWåŸíç_Õyò½pa|F‹{Rû ÞÐø>–î”ÿVô}ñš ¼f·æ«7Ë;GÅ?#íȶvßÇRþE¬n!wVùþÐä@õëÑY§Ú¨†}J¯ïÕ÷ñŽÅïú˜ÎdÑ\ =C}¡[—}Q‡S‘l};LÞž$š1Ìóg2,¦ëãìü««Ìøsý).ð›Ë£aêþªÛiCQÝÐømž¯öh*þ¦æ@®èÀ.•»ãKmJ ¸,¶räbí¤á_ž VÚo¥æ?3Ÿ½9$äNÍàˆEÐe·/œ¯_W÷Å3,‘® ­óHÄ]]ú.4Þ|4<`*Ê^ñ¥C.»Bï[óÇü1†òG„_ 6¨âÅQ&zÿÌóÇü™Ë‹é’ó<’J5Ôï¢Ñ)æú@X¨W'’Ɉê¯Wß×”é¬ÅKÜçüИLKRbÝ‚@. ÒY¨¶˜mÔ,F* ’`qžjÒÖñ‹X*ã«øD¦RnÁ“~qœR¯|QD‘z[žèI¸‰IP ¦ÛÀü1ÌŸ¹ü±. ‹[´2êÝCÿ‰â .W§L°Þµh~[ñ9žEfÇ~"ÿyAœ,‹¶^þ“~î‚âä†ÄçùiÙ⃒ÞCÈ᩺ây!ËDhŒý)aŒñåƒ Hã¸é„+!ü"ŽJÆI§ÛÀü1ÌŸ¹ü±˜. (M¦8gE48Qá0+U£LxqÏ#ømÇñq<äR®¿ ;Mc#ÿIœ÷zŠsn¶*â(Xh¢Û‰PÂc¥k«ã“#Š!Hs’ää&Û\3 ä‚àL´)Mr‘–O¿€ùcþ˜?sùc1]r¡§hC•í.ÈÅ[îÔ-ô÷œ¦Wˆ?âø3—?ÓÅŸ»w{'ìX{ùÃwøtrÚï Gœ™}&8û/?óß÷¤«o'èí8£#<Ÿ}cÔ˜4üc=ºò_lõF©fÞ¤…¬­ÓJÕÍ/÷[òÊ]O·õÓ4Ÿ;0håþ±>z–›üÈÄBgAúøýŸ¿ M¶xx š½ÁùÜ$®oa«w¸7Âøåëªòé—|×ÍP\SཎŸ«ä%›è=¶èÖw)Ó§Ð*>+Êýòv‡c¾£æs¾““#ÎkvñGüæòGb¸äS§?­Ù6k´ý~þÚ¥Ù7·Á)«×«Vnø›â³ûî <ïU÷E°N-»b¼ZD×à´{7€­¶Ø\½U3ŸSÙ)gwÛ‘ÂÜ.C§9ãõÛhÄtûòßßåŸ=A6V£;N<Îm¸a°êj®ß¢jjü.@ÐÕqv}ÝöÞXAÅ&ÚÇ>‘òjóKˆ?âø3—?Óµøì±§n¢³rfÒ¿$é½ô'=vÃÀ[¢¾[ç¤ýmñߨœ³íÇ÷&_áwÔ†¹­^¯§ˆ:òïY¸eÊ»cè’éghªŸýdè‚Jn©Oⱊô—\÷Tß _à'ç;T”ü«—Òš­™‡lžêYáBüWœŸ­,½T¡¢²éÕ묫‘sZ^CüÄŸ¹ü‘˜®³ÖtßRÖ‡ö>”þU§]7S„»Ãñ—zEÎwTý}ñÁ’Í?Ôðßì·pàFvÓBPêtzäÁM£ÊÍÞ±@ñYñ¶ÑÓb:˜ªä2®dï”ÚÉc¨æAiĨÒý •"ºiÝŽ?õö)Ÿ¨Ãë¨?²œùF–Kè DòŲî!{NU½ÕËÙú”«hëç[ζiéÄñg.$¦kèÛ®ðâÉoìò+ÜwÕ„ ‹ç<1Ü4>ëòSm*Axîf—ÊÚ‡ï˜ëB‡ž¿9hL'_‡ëãMW1öº»KÊ ·=¨¶>t;|¹rèÈI)Ï^/ÔäæËò¨çòŒñžUQž}¸é•› l\Z•F]mÕ×í¤ûÐñm/#þˆ?âÏ\þH —øÒŸ±½*;Ûîÿ$x·çãмÔá–¦ìoŒ7ô×+…ðfÿM£õ¶@haÍÇA¿êoºÙŠ&­âôÏ>²UlnŒâvtç„˽…Éq”¢}v»jäá¾ÊQ;ž_éyúXÅ·Oí§ºšp~Éä']㟵GøÍ+g¸Õܶ–Ü+¬•nª•BüÄŸ¹ü‘˜®Ù›5¨ç`JûHL©çèb—ae•PþËÉë9R¬Ú-¾ìj‡Á}–Âãµ'Vh;¤ïo’SF¹[™Ão?šzãvºÓ'h ¿ZkÎ.{UYãD%ç?c—¿í»eæ/šÙêWàâïwާ˜ËsΟ9ùÌóÇBÑÜaógD.·²©óöAýM¾ø#þˆ?sù#1]5ë óÚ¿€­$ïs·lÄÓvwLöÁ=jýàö‰/9Q[µÏ¾^"’q~o¸jk÷VÎÍê‘Ñ¿üzaÛ·d.ýÖðÒþëÍLó~ìã^5ÎÂÕw·P•QV=zËø[›¯’Fþ«xìõÚ”?ÎQzZŸá»÷÷1¼öâÊâkƒ8ÞçTwžZœz”¼f.]ñGüæòGbº¾úäòÖs–“a͈ûmøn×Yºë~‚òV˜öˆm­^~}~ñ´bý¶ƒs'_³­ƒ0Ê0󕘎¿¶éBƒëŽešOoÅW[òD{ÕëEöµ>øéñ©&ïÀÉqi-ó†gx³Ÿ®rùf:•1Ì£ý±zRïÄf×Þ=% ç=÷@‹G¯v(¹`ö=ÄñGü™Ë‰áâ⥬¹';\¦ï\”8f­k ?óÔñõjÚi¸öÄ®íùrùϤ±/ÇŸñ]±{ÇÆðÐ=–ûä›e^[w¡»oœ8sâù!/ï³ì;ÙåÐÁi¬åòx»Î µö²ö|ËËàQ çç#ÿ0æ'š¶5×[ÃwÞû@”Ôb˼f_äCâq5²¯øY<óo"þˆ?âÏ\þHL×ûxmøü/iÚ€ëПŸ-Z ¬½_·ù]¿=ñ£ãÓOL‡ë§Oí;<îNÝG×nùµ­ñ¯8 ›óV—Š£­žêe§3Á7Öìžö“;¾ÉÓÓg¾ÀxËòm‚îÚÁ3ÿÐunëýÄâ˜ò®…ôµšË•ûãý;[nÖ7r<%vjÎgæ'`ZÜd…ø#þˆ?sù#1]Yuä›Xôx°?ª¾ÕÎ*†pl­ûôÂ=´ýöÄg{~x*nÕ;ôQBð‰KxÍ£À¦YLBÒ “¾‰ìÅJßç!ÿŒž+ñ»Ÿëbõ±x]üêpíñ‹¹<ø®¡ñ¾Õ_9µÝïzaÉvDzkGY‰¾Þãz¤cÿ£y­®{l¿^Ñ{Ô•ãõæž”ge1âø#þÿÇü[)‰˜_t¥6ÆæZj Kø¾%©bÐrÑöÆÇ%¬Èµ¢Ñ€ c/K(ÒÄ)¨–€$‚——@í~âfî"c–&öÅg".q°4ŠþV¥A)oáÊ$È—¤¨lñ%Èx¬L¥Xšoí¯ÜÒ&çIõqÏ ˆ?âø3—?À`ž®4Áö @\Žq`ÌJM|¬Õšmw|\´8%=žŒCÔ{¹6_£¤QŸŽéRã©´@Hù>š²ym#üì=%ëâä QÅQñIq¶´€DèåzBÊÓÐñ fÔþ‰Äñg.$¦ È9ÞEi¶w[û‰ú/Å"–ÁÔ u\,…Ž©ýñù^¥d‡–¨ÿÂ0¶>'‘^mrgY…øD]°TTªS¶,ž¨ÇKstJ:]ð&Ž… sc¡\Ä6hèû‰ç‘pÄiª9ÆIR[oi_øZÄñg.$¦ H—®Nе½¶ð€K„Á|˜§OPR›˜²?~”ïm,ñ¯hY„!‹fý'ýÑ>•‰Vã(†F¬jÓY'gòX¹jºÏOÎ..ÓÅ‘y‚hc•¶²U rAPž†øÜ2_¯¢ì'¬ÔæÄñGü™Ë‰é±yòõ‰Ô~«ÛŠ_G ßÂb]¼2†âwÒÎøÄ7: ËKˆ‘ C8ÆÌD%ÝÙ4¢*²¥j+6@ôÔÖ—˜˜ì#üQ²TšËxDsÂ[TB–F®,Êõñt«$ñ±ÃãRˆæà2¾<‰ò²gÛâø#þÌåÄpœï™V ²cîO?€¸ ãÁ„ ñ…¦Z ýñ… r a ?#]M»þ7.#'¬ € .4˜ªç„Ÿ¥M¦;ñ( OoÚ<p,J­¥=p‘q#²Éž<ñGsUT>M€Ç£ þˆ?âÏ\þHLG.*IUÚ± ×ä—ŠXá0èVÒ™Ò²?>wAal–™fKýoìÏ/O²àâÈ€<3Sg@ÎÎ¥µŒU iš7$B¶1‘Þ2 Ñê,34=3áÇ8É Ô–Œ'Ó·ú ÄñGü™Ë‰é’Ð5:Û×…žù\"ðÃaA²Šâò_;Å@a¶‘Î^˜æ~(‰ Ï×Xˆp gqf†Út³€”Çɤ±®F¢•%Å=+ ŸŸª¢³ŒH”%IS5}\rû“POiËÀØ©m~ÃñGüæòGbºpÑ\¸AmÇ2 éWáÏÂ-ùU¦WíŠOÎEÀôŒDÛêSµ€i fÝ À©Ùf;éˆ#¡AE}ÒSÎ÷OK}q?1rІÉÔ³—Éùšç;¯p)j©øÉ@zÛˈ?âø3—?ÃpžWvN¼Ëp<¯ÌtyT(Ôg&ÒXþkøDý—ðA˜•e¾[/LÓÇ›­ßR™g¶Y¸h¹^Gu¸; Ïj±[.ŽÐj©Ï_’¹¼ñ)Ïã(—p)ì"Z:V¡É'BüÄŸ©ü‘˜. ‹ð+5Ø“‹Ã H a¶!!ŽÞôŸ½ñÉ/?Ïf*BíÊ%’qVèLû D«,mÓP&ÉÕP‹OŽBK´Í‡dŽQ„1‘z.”Õ¼@ŽEë­çƒ™7Äñ7ùø#1]@¼”½Vkã2™ýÃõÔÿlßøDýóü`ar gy™íé­D'?’›cÒOVîÐÈÒ$‹§}‘«zBjG‚(åz¯Ô·lNÈSÆD&÷›,…[ìZ"üB±Õ#A‰€¹CüÄŸ¹ü‘˜.\衬L°iîÏì˜Gîd±±ÚŸ¬ÿÑK`‘^ƒ©Ó©/õ)ˆXqF•œÜ£Vl-Q—Ü&¬¤t$(y€‡.­u]¸$:VGíHÑÆÌccËÏ p)O¡µr*™ÿi0ÄñGü™Ë‰á"siò3m9!¢1û'œcåéyvÔ@[â“0ÑþpE²*Êž¥vœpAÔKÿœä¶Ë|M À)V;÷@.Z–ª3¿Løü>c sÛœX þˆ?âÏXþHLÀñÖièHq¹˜ëOþ'óåÓöÛŸÜúWêS`É#=¹…6ý2ç³Ò$Xf+cpF•í9„?Zl´²ŒGžîS”bjªÜk,I±~$(¹†h*ë˜ð d: Ë€Öê?âø#þÿÇüÿë&<openimageio-1.3.12~dfsg0.orig/testsuite/texture-skinny/run.py0000755000175000017500000000015112271062644022541 0ustar mfvmfv#!/usr/bin/python command = testtex_command ("vertgrid.tx", " --scalest 4 1 ") outputs = [ "out.exr" ] openimageio-1.3.12~dfsg0.orig/testsuite/dpx/0000755000175000017500000000000012271062644017145 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/dpx/ref/0000755000175000017500000000000012271062644017721 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/dpx/ref/out.txt0000644000175000017500000001023712271062644021274 0ustar mfvmfvReading ../../../../../oiio-images/dpx_nuke_10bits_rgb.dpx ../../../../../oiio-images/dpx_nuke_10bits_rgb.dpx : 512 x 512, 3 channel, uint10 dpx SHA-1: D63D2EC8C60AB41B1C0F72A65AE8FF27DA8A620E channel list: R, G, B oiio:BitsPerSample: 10 Orientation: 1 (normal) dpx:Transfer: "User defined" dpx:Colorimetric: "User defined" Software: "Nuke" DateTime: "2011:03:08 14:47:25" PixelAspectRatio: 1 dpx:ImageDescriptor: "RGB" dpx:DittoKey: 1 dpx:LowQuantity: 2.1391e+09 dpx:HighQuantity: 2.1391e+09 dpx:EndOfLinePadding: 0 dpx:EndOfImagePadding: 0 dpx:XScannedSize: 0 dpx:YScannedSize: 0 dpx:FramePosition: 32895 dpx:FrameRate: 0 dpx:ShutterAngle: 0 dpx:Version: "V1.0" dpx:Interlace: 0 dpx:FieldNumber: 0 dpx:HorizontalSampleRate: 0 dpx:VerticalSampleRate: 0 dpx:TemporalFrameRate: 0 dpx:TimeOffset: 0 dpx:BlackLevel: 0 dpx:BlackGain: 0 dpx:BreakPoint: 0 dpx:WhiteLevel: 0 dpx:IntegrationTimes: 0 dpx:Packing: "Filled, method A" smpte:TimeCode: 0, 0 dpx:TimeCode: "00:00:00:00" dpx:UserBits: 0 dpx:Signal: "Undefined" Comparing "../../../../../oiio-images/dpx_nuke_10bits_rgb.dpx" and "dpx_nuke_10bits_rgb.dpx" PASS Reading ../../../../../oiio-images/dpx_nuke_16bits_rgba.dpx ../../../../../oiio-images/dpx_nuke_16bits_rgba.dpx : 512 x 512, 4 channel, uint10 dpx SHA-1: E9FECE70CD875C5654F58DA9EC576399F089D855 channel list: R, G, B, A oiio:BitsPerSample: 10 Orientation: 1 (normal) dpx:Transfer: "User defined" dpx:Colorimetric: "User defined" Software: "Nuke" DateTime: "2011:03:08 14:47:01" PixelAspectRatio: 1 dpx:ImageDescriptor: "RGBA" dpx:DittoKey: 1 dpx:LowQuantity: 2.1391e+09 dpx:HighQuantity: 2.1391e+09 dpx:EndOfLinePadding: 0 dpx:EndOfImagePadding: 0 dpx:XScannedSize: 0 dpx:YScannedSize: 0 dpx:FramePosition: 32895 dpx:FrameRate: 0 dpx:ShutterAngle: 0 dpx:Version: "V1.0" dpx:Interlace: 0 dpx:FieldNumber: 0 dpx:HorizontalSampleRate: 0 dpx:VerticalSampleRate: 0 dpx:TemporalFrameRate: 0 dpx:TimeOffset: 0 dpx:BlackLevel: 0 dpx:BlackGain: 0 dpx:BreakPoint: 0 dpx:WhiteLevel: 0 dpx:IntegrationTimes: 0 dpx:Packing: "Filled, method A" smpte:TimeCode: 0, 0 dpx:TimeCode: "00:00:00:00" dpx:UserBits: 0 dpx:Signal: "Undefined" Comparing "../../../../../oiio-images/dpx_nuke_16bits_rgba.dpx" and "dpx_nuke_16bits_rgba.dpx" PASS Comparing "input_rgb_mattes.tif" and "output_rgb_mattes.dpx" PASS Reading stereo.dpx stereo.dpx : 80 x 60, 3 channel, uint10 dpx 2 subimages: 80x60 80x60 subimage 0: 80 x 60, 3 channel, uint10 dpx channel list: R, G, B oiio:BitsPerSample: 10 Orientation: 1 (normal) dpx:Transfer: "Undefined" dpx:Colorimetric: "User defined" ImageDescription: "view angle: left" PixelAspectRatio: 1 dpx:ImageDescriptor: "RGB" dpx:DittoKey: 1 dpx:EndOfLinePadding: 0 dpx:EndOfImagePadding: 0 dpx:Version: "V2.0" dpx:Packing: "Filled, method A" dpx:Signal: "Undefined" Stats Min: 0 0 0 (of 1023) Stats Max: 1023 1023 1023 (of 1023) Stats Avg: 18.64 18.64 18.64 (of 1023) Stats StdDev: 131.01 131.01 131.01 (of 1023) Stats NanCount: 0 0 0 Stats InfCount: 0 0 0 Stats FiniteCount: 4800 4800 4800 Constant: No Monochrome: Yes subimage 1: 80 x 60, 3 channel, uint10 dpx channel list: R, G, B oiio:BitsPerSample: 10 Orientation: 1 (normal) dpx:Transfer: "Undefined" dpx:Colorimetric: "User defined" ImageDescription: "view angle: right" PixelAspectRatio: 1 dpx:ImageDescriptor: "RGB" dpx:DittoKey: 1 dpx:EndOfLinePadding: 0 dpx:EndOfImagePadding: 0 dpx:Version: "V2.0" dpx:Packing: "Filled, method A" dpx:Signal: "Undefined" Stats Min: 0 0 0 (of 1023) Stats Max: 1023 1023 1023 (of 1023) Stats Avg: 24.44 24.44 24.44 (of 1023) Stats StdDev: 147.83 147.83 147.83 (of 1023) Stats NanCount: 0 0 0 Stats InfCount: 0 0 0 Stats FiniteCount: 4800 4800 4800 Constant: No Monochrome: Yes Comparing "stereo.dpx" and "ref/stereo.dpx" PASS openimageio-1.3.12~dfsg0.orig/testsuite/dpx/ref/L.dpx0000644000175000017500000005140012271062644020631 0ustar mfvmfvXPDSV2.0S€€L.dpxOpenImageIO 1.3.2dev http://www.openimageio.orgÿÿÿÿP<ÿÿÿÿÀÿÿÿÿÀ2ÿ view angle: leftÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€OÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀP<ÿÿÿÿÿÿÿÿÀÀÿÿÿÿÿÿÿÿÿÿÿÿÀÀÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÀÀÀÀUTQ¬¿þúüÿÿÿ<ÿüóÜ}÷Ýk¬±üÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿ¬¿þúUTQl¾ùæüÿÿÿüÿÿÿüÿÿÿüÿÿÿä”SNœ|òÉl¿ýöl½õÖ$•TR~øáüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿÌ=÷ÜüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿtÕUWXj©¥B!`€°Â +È+¯¼tÔQGüÿÿÿüÿÿÿüÿÿÿ\}õÕ°ÁPB %L<ñÄüÿÿÿüÿÿÿüÿÿÿüÿÿÿŒ?þøüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿl¿ýöüÿÿÿüÿÿÿüÿÿÿüÿÿÿì¼ó΀ (üÿÿÿüÿÿÿpÀüÿÿÿüÿÿÿ¤”RJ<üðÃ`ƒ 6@ °À ƒ 2Øj«­üÿÿÿ¬¿þúUTQAÔV[mÜ|óÍüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿ„RH¬¼òÊœþùŒ>úèØi§àüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿUTQ¬¿þúì¿ÿþ,¾øâi¤‘Aopenimageio-1.3.12~dfsg0.orig/testsuite/dpx/ref/R.dpx0000644000175000017500000005140012271062644020637 0ustar mfvmfvXPDSV2.0S€€R.dpxOpenImageIO 1.3.2dev http://www.openimageio.orgÿÿÿÿP<ÿÿÿÿÀÿÿÿÿÀ2ÿ view angle: rightÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€OÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀP<ÿÿÿÿÿÿÿÿÀÀÿÿÿÿÿÿÿÿÿÿÿÿÀÀÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÀÀÀÀüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿÌ>ûìøé§Ÿüÿÿÿl¾ùæüÿÿÿA)¤øê«¯üÿÿÿüÿÿÿüÿÿÿÐ@ üñPB %üÿÿÿüÿÿÿDYdüý÷ßL?ýô¨ªªªðÀüÿÿÿüÿÿÿüÿÿÿPB %l¼ñÆÌ?ÿü¬¿þúUTQÌ=÷Üüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿ@À „^xøè£üÿÿÿTUUU<üðÃ0Â#P@°Â +¸è¢‹üÿÿÿüÿÿÿ8묳°Â +@UTQ¬¿þúüÿÿÿüÿÿÿüÿÿÿüÿÿÿ,¿üòVXaüÿÿÿ =ôÐÐB -`ƒ 6üÿÿÿüÿÿÿ€üÿÿÿüÿÿÿüÿÿÿh©¥–”TRIüÿÿÿL?ýô@ °À üÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿ €˜jª©p 'üÿÿÿ =ôÐÀ ,C9üÿÿÿüÿÿÿüÿÿÿüÿÿÿpÀüÿÿÿ€誫®üÿÿÿTUUUÈ+¯¼€0ÀÀ ,Xi¥•üÿÿÿüÿÿÿüÿÿÿ¬¿þúUTQAÔV[mÜ|óÍüÿÿÿüÿÿÿüÿÿÿˆ(¢ˆ~øáüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿTVYe >øàl¿ýöØj«­0ÁüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿUTQ¬¿þúì¿ÿþ,¾øâi¤‘AAœþù@È(£ŒÈ)§œ`€ä—_~ì¿ÿþüÿÿÿ ?üðh 0Àopenimageio-1.3.12~dfsg0.orig/testsuite/dpx/ref/stereo.dpx0000644000175000017500000011700012271062644021736 0ustar mfvmfvXPDSV2.0ž€€stereo.dpxOpenImageIO 1.3.2dev http://www.openimageio.orgÿÿÿÿP<ÿÿÿÿÀÿÿÿÿÀ2ÿ view angle: leftÿÿÿÿÀÿÿÿÿÀ2ÿ Sview angle: leftÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Oÿÿÿÿ€OÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀP<ÿÿÿÿÿÿÿÿÀÀÿÿÿÿÿÿÿÿÿÿÿÿÀÀÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÀÀÀÀUTQ¬¿þúüÿÿÿ<ÿüóÜ}÷Ýk¬±üÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿ¬¿þúUTQl¾ùæüÿÿÿüÿÿÿüÿÿÿüÿÿÿä”SNœ|òÉl¿ýöl½õÖ$•TR~øáüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿÌ=÷ÜüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿtÕUWXj©¥B!`€°Â +È+¯¼tÔQGüÿÿÿüÿÿÿüÿÿÿ\}õÕ°ÁPB %L<ñÄüÿÿÿüÿÿÿüÿÿÿüÿÿÿŒ?þøüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿl¿ýöüÿÿÿüÿÿÿüÿÿÿüÿÿÿì¼ó΀ (üÿÿÿüÿÿÿpÀüÿÿÿüÿÿÿ¤”RJ<üðÃ`ƒ 6@ °À ƒ 2Øj«­üÿÿÿ¬¿þúUTQAÔV[mÜ|óÍüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿ„RH¬¼òÊœþùŒ>úèØi§àüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿUTQ¬¿þúì¿ÿþ,¾øâi¤‘AüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿÌ>ûìøé§Ÿüÿÿÿl¾ùæüÿÿÿA)¤øê«¯üÿÿÿüÿÿÿüÿÿÿÐ@ üñPB %üÿÿÿüÿÿÿDYdüý÷ßL?ýô¨ªªªðÀüÿÿÿüÿÿÿüÿÿÿPB %l¼ñÆÌ?ÿü¬¿þúUTQÌ=÷Üüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿ@À „^xøè£üÿÿÿTUUU<üðÃ0Â#P@°Â +¸è¢‹üÿÿÿüÿÿÿ8묳°Â +@UTQ¬¿þúüÿÿÿüÿÿÿüÿÿÿüÿÿÿ,¿üòVXaüÿÿÿ =ôÐÐB -`ƒ 6üÿÿÿüÿÿÿ€üÿÿÿüÿÿÿüÿÿÿh©¥–”TRIüÿÿÿL?ýô@ °À üÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿ €˜jª©p 'üÿÿÿ =ôÐÀ ,C9üÿÿÿüÿÿÿüÿÿÿüÿÿÿpÀüÿÿÿ€誫®üÿÿÿTUUUÈ+¯¼€0ÀÀ ,Xi¥•üÿÿÿüÿÿÿüÿÿÿ¬¿þúUTQAÔV[mÜ|óÍüÿÿÿüÿÿÿüÿÿÿˆ(¢ˆ~øáüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿTVYe >øàl¿ýöØj«­0ÁüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿüÿÿÿUTQ¬¿þúì¿ÿþ,¾øâi¤‘AAœþù@È(£ŒÈ)§œ`€ä—_~ì¿ÿþüÿÿÿ ?üðh 0Àopenimageio-1.3.12~dfsg0.orig/testsuite/dpx/run.py0000755000175000017500000000210012271062644020317 0ustar mfvmfv#!/usr/bin/python imagedir = parent + "/oiio-images" files = [ "dpx_nuke_10bits_rgb.dpx", "dpx_nuke_16bits_rgba.dpx" ] for f in files: command += rw_command (imagedir, f) # Additionally, test for regressions for endian issues with 16 bit DPX output # (related to issue #354) command += oiio_app("oiiotool") + " input_rgb_mattes.tif -o output_rgb_mattes.dpx >> out.txt;" command += oiio_app("idiff") + " input_rgb_mattes.tif output_rgb_mattes.dpx >> out.txt;" # Test reading and writing of stereo DPX (multi-image) #command += (oiio_app("oiiotool") + "--create 80x60 3 --text:x=10 Left " # + "--caption \"view angle: left\" -d uint10 -o L.dpx >> out.txt;") #command += (oiio_app("oiiotool") + "--create 80x60 3 --text:x=10 Right " # + "--caption \"view angle: right\" -d uint10 -o R.dpx >> out.txt;") command += (oiio_app("oiiotool") + "ref/L.dpx ref/R.dpx --siappend -o stereo.dpx >> out.txt;") command += info_command("stereo.dpx", safematch=True, hash=False, extraargs="--stats") command += oiio_app("idiff") + "-a stereo.dpx ref/stereo.dpx >> out.txt;" openimageio-1.3.12~dfsg0.orig/testsuite/dpx/input_rgb_mattes.tif0000644000175000017500000002306012271062644023220 0ustar mfvmfvII*h%xœíÝ÷”U¾Àqºj „€€¨€t¤D¤„¡C¤†NHHH! !½g&e’é}¢k¹‹â*¸Ö‚²®(6° vQdA×ê}}æûËýí&y^—œÏû?€ó:™yæ<ßÓ¤‰ª¾ŠmŠw»Á7+"°2 59øQ‡R#N90ŇÒZMåúmña•לðÙdÅzzU#«]ËðKVg¡p? qðEâØ 4ïƒÕ-¡õjU©T7ÖÈÛPÖÿ™„O·bj*šbd%.›qÎ…Zh½·5vå~Õ>„{ð±™v¼dA ç XQ«¥8W€1Ù˜Šv£Í&윉¼~˜×Z¯S•Ju3Í Äï¿¡±Ø›‰àR¼hÀ^ö`W-´Þá/ÙÛOøàÁY'fØá° Öˆ>)ÇåR´.ÄòltMÃñ8¸ ?ÏÆ_ ´^¡*•êfšØwÇ€qøx-:'#4_é°ÑˆL¾ñ¢°ZïsW¿ÓŒp!Á޽„fÀ¥rCj½Ï5Fñ~Y^<íÂGv˜,eÄÉ*£•Á~„:±ÐŠènÀ£zŒ*A¾¿YX™ŠE ˆÜŠÙ‹0l0:ùÓzUªTªºéöNø}BàB zÀð"¨Ä½\øÈõ|¦á%ù=ãÅ\¶Ø`0A~WîW‚îùpgâì~´IÀ[Ð}1C1#Z¯G•JU7]nŽw{འ8µ]’p,o”¢¦U6,ó`q-´Þí#93“åÆûv³áAÆV¡ÌßËøw&ÎíCA,>ŒÄÕ9øi t€Ö+Q¥RÕ}GƒðÖH|º‹váR*Öä!H‡?ªñ‘ [=PçgÞ$¿£lvà73šU#C9EhšIûñv,Ž®Gâ,ô¸ ýÚBë5¨R©ê¾»Ûá±¾ÈCÜV¼œ„–™XX„ý8lòsà¢êùLC’÷…Oz±Ê…SVh½óÝúäÉÌ)¹ñ›?™W= 0ût»ñüjøÆaG0´^w*•ª~ëÖÅý±m6žÝŒ{±)› °B‡ñDšî@?/¢j¡õþwë“IbýXëÄ:+n3âÍ <[ŒltKÆ›1| î wKh½úT*U}µ¤æuÇÔ±XƒWc1!½rQ^‚¯*dÄ5+ö¹0ßõ|¦¾É¿ðBÜ'3{Mb)e7U“Óðy Š¡l v„Ö«O¥RÕo±0x cüœM†L :Rˆ!zȽ?w[ç€Ãƒ µÐzÿ»õuô‹õàˆs-ÐWc~9ÒŠ0!OïÁkk16cB õºS©TõÛùV˜Ýq3°fr`N‡3;Ja©„Ì”Ïoº oPªé‘õMÞ/øÐ‹¥.L´a»ó*ñM šæbÂ~„mÇÏ3Ñ·ÚBëÕ§R©ê«t¿Í·C? rOÓÄXܽÿÎF\1RÊñD5ä®·(õ -´Þÿn}rËínÈý«ÍøOFëðQ>r`Ãn¼° =G¡«?­WŸJ¥ªßŽãûÑ8²Ç¢Ña/ú;\€!:l©Â£&ô¶£•;}PÏÞë›|?êîÃ5'd’XZ dð’"X³àNƬ­8<ÓïÀÒÖÐzõ©Tªú*µ"†À¸qÛ0"ÿJGPJü­¨ÀÅøÇ Z‡;qȃ9µÐzÿ»õ…ù¥zPm‡œxï[…§KQ‘‹ORqï.¬_Š£['h½úT*U}u<O÷ÁC¦‘È|‡RQ›û‹0GD¶™‘iÇ,7R|Ps ê›ü {|Uäïlv5ëq®ý3°#ëðl(þ‚O›Bë5¨R©ê«!ˆ¸÷=‚'v¡ K2‘W€]eÛ´7Ñ̆wœXå…¼M©õþwë“ù/{°Ã “*q´Ó³ñi2äÎŽe3± Ö@ëÕ§R©ê«qÛ0,]Œ9Q§îò6ÓŠ<*Á™r©†ÜÇ7Ú3n\öAëïÖ'¿n,óᜠlH«F´ò»jlZïBÅr„ Cngh½úT*U}5®-~釿@îÜì°¯¦A&–4)Fœ“ ÏŠ:äù@/ÔLà†!óÄ<·†Û™±´3‹ñf&–&aùlšˆ£= õêS©TõÕøæìÅcèz\‹Åæý(ÊBb!dA—*ì7BNk„:aö@n—Ðzç»õɧ÷‘>È Úm“3¿é05åû±9 çà|?üÚZ¯A•JU_õî†i£1l‚b²rçru>Ú•áû Ì©Arfc²‘>¨S‘ cœ_òé½³ë Óf–Äøœ@³‘ØŒ‰M R©n½þÞ à¶ùð_©·5# rââ÷\Tci9Vãbmá‚̶Z\ ­w¾[Ÿœœ‘· â\xÍ ùË+³"ß΃ܚýØ6ü' ]ú"+Z¯A•JU÷å´Â}P2±!ç!CÓ oªÊyÈçu¨®Ây#þnE7'º{ð…Zï|År¿6^è˜cÆÀ*4)ÅCYˆÛk+px8 ¡õT©TõÕê8öB× [,)è›…— 0¨ TÂ]™EæÀv7Æø[ ­w¾[ßÿ¾‰¯©½l˜Vƒíz\ÌÇúTœßÿ‘ÉI={cD+h½U*UÝw²+–ŒÅâ°GaD2ä<ä™<|R‚…sw fL¶ÃäÂZ§¢erfbP?Œ €ÖëQ¥RÕMú–pôĉ‡°»wbá^è3°5ƒJYŽqÕ“Õ§mó§=h[ ­÷¼ÆBÞ,Èóá€ò;ˆÜÄw¦á%؉ó HXþ#ña´^*•ª.ûK0ŽEXÆàý$¤À¹\-‚œ þ¤ ƒMóÕ­˜æAµêm¦†$o¿ïA{'LÈÄÈz$äÃ?ì9õìvŒ™Žè>Èh­×£J¥ª›îDÓ¡½Û±$×Ò0)g qµ ßWâË”ZÐÌ9yÕ õd¦!¥û½à…Üķņ'èW‰U%Xùô^»Žà h½U*UÝt9ž¾øxÆE""R!ócâr)¶TÀ[#f|fC?¶x¡ÎC6$ù–TáƒÉOí8`†œnzB‡; P‘ŠÚí¸4úà³Û õªT©T¶½ÍÝe°n5.ìÄ+ûÐ?2EvB) Êa7@æCÊܪµNȬB9©îïhH2+ò¸œH´ÂZƒà ´)†Ìê—“3WVá“aÈ ‚Ö«R¥RÕM¯Ã=O­€7 ÉÈÎÀî<Ì-ÁÀr´5 ÖˆÙVä9ð77ÔS÷†'ߕ俔ñ.œ°!Ô„±UЕâŽ<¿Tìß“Óñ|@ëU©R©n¾Ö­Ðµ;žÊ%8¾ ú=8—™0sªr².¿ =Œˆ±àvœpá}/ä9°Ö{^c!oÈÛLw»qÂŽg̘] ÿÑ'½sâ1ú×Bë=¯±'`fÚzð²­0Ô °ãJ0(¿íCò6ÔLÇÒ>èÓZ¯P•Ju3uì„à{ñä\ÌXƒ·áƒÝ‚–™ÏGq)ÖV@_fÕã²MhoƒÌþ}Ò}P÷î5$¹;{¿òNÙQƘfÀ=æb~&,‰¸‰ “àꉤ–ÐzªTª+¸ûûu.lÄŠXD%CNBŽ;ˆ´\|]„Wt_è¶!¿¨;0ß7¼yãZïy…Ì»âÅë.øì;³ž®Æså[V»çàÐ~´Áç =ÛCëuªR©n¬íའsgá÷õ˜ û^ø_NM—w^úç!¶­uY ™0iœ¬¶» sNÂj¡õž×XÈ09ë.SÖ;ð³­AûJÈÛ ÅyX~]ãñÒj”Þ‡7»BëuªR©n¬ÐÖØ|'Z?Œ_× rÞÞ‹k°0Wò1¯Yeßæ’ªÑÄ 2ûWÎZ÷©…Ö{^ãòO"=ˆsâ”±¨ t8\€…–ïfäNÅwàj+h½ZU*Õõ6±š…À0'VbD4R“ÑõÜ9,Äç%ð ×ͪÀ9¢M(²â¤¿»qØõ‹jCîì…¼/|ц¯LÈ2@§Gf^ÈB›”Gù-ÆÀAì­W«J¥º±ÆtÂ7ƒqiJ¶at"äf]6,…y¿¿ê‘\‰àjÈgBùî¯n´ðAý¢ÚdžL˜ñ¸Pb‡Å 9Ý”RŽ/Š1/­Ò°<ËVcÝhDw…ÖëT¥RÝXÍðàX7+#±.»RñbNÀ[ ÙVáßÕØb‚ׂívìs¡¥sj¡õž×XÈ_Ò^>ÜëF¸ò¿#¿äx ¿¨ö³A&Ìœ¬‚C‡ÈBìËÂû ï8´Yޝ†#©3´^§*•êÆz1±÷!d Ø ™<`JÅçÙ°á´òžã=FL¶ ¹ÇÈwAîìèꃚëÞ:úÉ31ù%ïÿ`—|£‡L ú8'÷ã­]xó| ÿKiÝ´^§*•êÆºØ_@óÅ8±[wãp ¶dÂP€ée˜T‰ðÈÛ1òä'&»ñ³[|û=µÞó ¹i€é.ȳ²™‘VKåU‚š\D¥cS<oÀ“Т'¢›@¥RýÉÚ G^8ÞÜ„3qèžy;Õ’‡¥%35ÕèoÆ(Bpû3z!§Üå­I­÷¼Æ"Þï^4uã;;Y ‘¿¯@|)Öå£[H¿¶ ËL\¹¯·†Ö«U¥R]oÿ DÊPìX€Ï6âB,Âö!-™¹ÉŸéðˆ…&è¬xÇ7Nz!sN´ÞíÙÛå–Ã7äÕï,eD¥¿Eeð m&:ìEæ, ‡Ì”ÛÔZ¯V•Ju½=ß¿ Æîy¸´±(Ü‹æ蜋´"|Z†¸JÈ ª/Yð°­ÜÈ÷"²Zïv‹ür=Þ‡|7ôÈi™gŒwTçê]ˆê,¤ z'Ì+pd$æwÖ«U¥R]o2[¦à.œÃ=‘(ˆ…ìíÓ204MŠà)CLlÕ0˜1ÁyÆ+Ï{åÆ7­w»ÆENB:|¸äÆ7|`Åz䤓L†ÔAîaY”Š)q¸c *ïGóh½ZU*Õõv¹®öFά[¶±Ø¼¦¸-G ‘^†û*ЯòÓKV8qЙp¢Î·7$ù×>âCwîsbˆ GM~œÕÃUŒÐ\,KG‹=Ù¿c¦`|/|Ó Z¯Y•Jõ·Ñ¯yw¼?×" ÁÏIxál9x©?•â® ¼h@䮟Ñd¹郺Aµ!É¿¶Ç¹­ãq'džÛp3ä®=¹ß|M æåáÃtìñ÷󴘉œ¾˜ÔZ¯Y•Ju½µ ‚Ü›yp)žÛ¶‰¸–†.9-„œ„ìXÿ¥m†'8oH°ÝÿaЕ䅚åÞäsû¶zp͉+6„›!Ýå›×àRåcdÞOBÈvøGE.ü`Zµ‡Ö«U¥R]oOvÀÄAh;Æ-Ø™€1©”s0–âÕr 1@Þg·`”g'3ç}POfR[¿¿ypÅéçßÛ Í¸P ™-Ó® ÷àóƒßY^Âô¥x}ž„Ö«U¥R]o+Ûà½>Ø8 #6`[,MAu&>ʇLš’Ù2Ý ;˜fXÐÆ‹rƒê2ÔLȆtŸßÿ~;5ÄŽ3fÈܰ¥•H*ÑüW&ïÃßcðöJ\ƒ²®ÐzµªTªë­ )v† s("#Ð#i{ñY‚òð}1*G kÁG6$:ÑÖƒé>¤ÔBë=¯±Xì·Ê‹.ÈÛ©ò÷×Zw%äŽìòBÈ·³ ûñß»à¿zkuæèßZ¯V•Juc…âë!è¶_lCa"ÞIÇé¼S„ouØR…‹5aÁû6È”ª—ÝèäCz-´Þó ¹ÓpϹð³¥È[ ßWBîIL)„LìoŠð8Ä¬ÇºÉø°'Þm ­W«J¥ºÞ^@Ÿ~(ƒ¼£jˆÇ½iè…x½ rOÇŽÈÄ’6ÌpâÏx±¶ZïyE”ß_¼rCf¹?nìí?Uâ=–ao6ÒRÑ6þƒN‘K°æNìm ­W«J¥ºÞj›aþíxòA\^‹„]8½27,¼Ÿ”ÂXÂj 2cœ ­(qCvµ·7$ÙÛ^ w#Ì+L3BÞN½¤ÃEx=]Ó°9ç6ã·Ùø¥¾k ­W«J¥º± A˜7rFâ¡(|“yGUæ†=P‚MåxÂyƒé +Ò˜åÆÛ^¨I¿ Iöv™*³Ü ù‰µâ #d–{/=ä9›¼Åð^ÚìÌ|~k,wãBh½NU*Õu¸"ûaÝLlƘ¼š†è¼R„=lUXn„|2”§»¸ 3!Õܰ†${ûû^ÈÔe™*“h…¼kvŸr;v›bÏÁt|¿G·Â2mïÁñvÐzªTª«¸¸¿=€u«±hæìGçl"² rš®°2Kv©\“xj¶LC’SIòiºò¹]&vö1a»Ë!“žÊ…Ìrݹ‡k÷"¼6¦ÐzªTª›©´3†"`1Š¢PžŒì „æ£I)¦T ©͈µ¡Ú ¹ßMÝÚä ØO^,vc—)VD›e€¹W±ùvÈ\2 ú¡õ U©T7Ó÷mðp윎Êx$£Ó!“!uÅ(‡Ì˜jÂ!+d¡œ„Œ÷AÝÚ0ä™Ì^<â†|n7Xñ  ²·ËT™ì8ó°)»’pz;²aä<Ó Z¯P•Juóvƒ¼“»p5þa`Yù…X¨CBzQiAOä™À/Ôýz CÞnçÃz7ÌdX1Ò™UŽŒœÉCàAœMÆüh„.Ųø9Z¯M•JuóõêˆUpz.mCË$ŒË@m>Z”BfOµ«œu—§îY.„{1¡Zï|·>ùåZ~Å–3ÿå€<“lB˜åXU‚óðjšîÅÕhD¬ÄþûP­×¦J¥ºùR[ÁÚñâÀ:|‡ÄTÈ©¹¼b\Öã>0a¢ Ï:áðà²ê©{}“· d§Üššé@„¡&Œ7àW=v” c>Žg`ð^\ˆÁw«Ð4ºA뵩R©þl» ÷0ÈsW{ÚîÃØLÄb ©„L†œdEž&7’|PÝëÛ$¿É^ÈIÔ`†[qÞˆù,-‡Lq—7žÎÀÒ½ŠÁm`ʼ­W¥J¥ú³å ¤VMEûŸ€é蟇]%øºGªñ­2¥êužóBîkÖzÿ»•ɉÓÎ^È,ý+vÈŒ}ÙÛås{³rÄ—@Ÿo^LÆo1ˆÀKãñZ´^•*•ªnº=¡÷áÄJ,ŒÁÎ< ¹Mµò,÷° á6œrâ¼ê¬{}à'{»Éy›LÞ,Ë3âh>Õã‡b¬ÉÃãø*¢±t\㠞ɨT·RÛã£þxwžÝŒ{‘œ|Kѳ¿Ö È 9ƒ÷77Ì>¨§îõç'ÞðÀî ;dV˜¼A|° {õx£mò ¿’Nƈh4[ Ýhl†ÖëQ¥RÕMÍšcaâFã…œÅæý蟃cŧ¸r/ç63Òìø‡ V/Ô„™ú 1ßñ¡Üƒ¥.$ØcA2Ÿ¹½£Šñu.šgàJÞˆBÀ*xCQ ­×£J¥ªËN¶ƒ³? sPºÇ’0õ –`®/Vá#®Y±Ð 933¼Zï…·ù:χ(ÞqbœþÁ0–j0± êpµ£r1ñ¦$£E4RWàƒ±X ­W¢J¥ªË.ùÍèyú:y5íÆci¸™)'ÞeÎŒÜøs›»Ý˜íƒ:3S·äs»Ç‡^È䇯m8aFR *ýýUSÚå¢ë\K„{ú®À·£ðT´^‰*•ªîKï€û¡v&fmEl2¢3q{!*t(4 ]ìXå‚Ì[P ­wÄ[‡ü­,òáw7äž” Ì­Lx‹ÖAîæ˜žƒ’ttJDùvô[ŽÍ£0µ ´^ƒ*•ª¾êØ GáÚ lŒENäfÕ‹%ßU‡‘cÅôõà°êwÕº"{îòá¨eÃ3jªñ{,eÈ*IJ4OÇÂ=¸‹‘6¾@h½úTõÛÿ_µàCxœíÝûS”×€q%5¢Œ¼‹(±j¼D-^ë%Å šÁè¨x+Ö;!PT..°r]Ü…ea—]´Ñ´Dk“Ú–š(Ú©aMSÓ‰ÖK;&biÕi¦Óé<ïéé¤ãLªgÁïóùö=sx9ïyÏÛ®ôô–ÑïÆ—X½Sw¡%™&l. ²*ì@zQ‹øÖâ —Ü(ráïÕèYß Ì/‡µã;&ìÈB@F$áØFôYßXçÝ£O’¤ÇÛÚx^ÄÔ,Þ {ñr6^3c)6XñkÐÅuÐ=/¶‹ ï¸áBQ5Zì°ØVަbD›ñÚ!ÜÉ@クŸˆÈ8\¹Pt3Ò=î$Iz¼ÅvÆøøçd\\‹ÊOÇû&äÁ¯ŸUà¬u!ÇstÏŽ­[¨!Þ ?ÆT#ÎŽl¸mAF1~Z{.Vd ,¶·°o=î.@Ê0¼ÝºÇ$IO"Kw|2#½WS™f¨»÷«Vt«B{'Fº±¬ºgÇÖ­¡»)Nœv ÈŽ÷­˜bAX1º˜±0éIÅx$¬…s.Ú Åê.Ð=â$IzÅâð·‘èƒe h8€Ñ&¨µ÷eå¸Ußj¸ŒNyP\Ýsdë£~·N†Kµu"Ç[%^²¢ª Š0°§s“ŽÐ˜wàB,¾œ…AØÐºGœ$IO®âޏÓa8·–]hÎD|²KqÒŠÐ*;ñ#7vÕA÷LÙú¨¹ý7$×â5và™Jüò†”aB–ä#*iàØyÛñáJ|2§úB÷(“$IO|„©3ði–ìAv6B­ú:+ îÞ»ÖBÝyêž)[õ´â¨Qµ¨1ºQõ;ÿ Jq´yPëf¶ý¨Ý…¾[‘¾õ“ðƒ^Ð=¾$IÒY‹„Àج·áûÑ1SK°Ù Ÿ*Ltâ¡ûê {¾lM² ó=ð©EB T!¥ÇËÑ\‚úÃp›às=÷áæNX¶àX îÅ0èY’$éïAOÌ Eà<ämÇtüµ}-°T@íèø£ -èž/[“õ†[n¸Ð\UøÚõ¤CýUm0#Ä„1Y¸·““°r–¼ŽìшîÝcJ’$ý5øøãÊ0¼ í˜˜…W ÑXŽ«v¨Uâ27¶ÖA÷¬Ù:L3ä»1Â…üjÔÛ‘lƒO9‹hƘC¸™÷ö }"ºÇá‹perý {LI’ä]%ô@Sþ< ¶âüADC=]]ã€z§òº²sæQ„‚Ýhr¢W5¦ÚáoÃ\ Æcw^ÊE ,HÅÙ”®ÃH̆<_èG’$yc7ºÁŒ¦é²7³PS‚† Ì®Áj7Ô{ôºçNo§žP|î†Ã‰bÞ®„z#ølŽapÔîǮ鸛ŒÂx¯A»p$ádgèA’$yowŸÃ•A˜c _Ý1*ƒ:—à9J<»÷G1ÞÐàÂVâö,)ÃýBlÊÇ‘l@ûdŒÚó*Ìž‰Èpú@÷Ø‘$ÉÛ{µòûáæ8”ECíÖèiÚ›=­Ö`¬'ëž;½ú ãñoP¹™G Þ ~µoæá·qlÚíBý¤-ÇÅ0tèÝãE’¤Ö×È´ŒÂ‰…˜”Œk¥ð©Æ¯Ý#Eªaž£ho…)Jã"²ðp/:$¡aJ—âwcññóÐ=F$Ij­ÙýÐs8¾žƒ+‰P§Zm¨ÁäT±GñºAí)-­Äð2DFÆ!LÎDÍ4½…ã`ç¹xã(<ôƒîÑ!IRëîM_…`|8Râ±­•5øÈYÿßÔï£ö©3Ù¬()ÄäCØ–K©è”€¯ÖáÄ<œ ÁP_è’$µ…žéЍ`Ü Gÿ¨(@t ÔA÷ êíL†ÁT:0Ê‚<£¡PçƒíˆÇ©X¨2»Áú,tI’ÚNݰ4§Âq<õyPû·e†jþV-úÙ±ªbn ò·áô ”LÃËý1»=tI’ÚZsº#%{"q&;MP_Rû$uÏ ÞN}¹ã]'š­°šqgÔ‰Ÿ/à ¸Ý×_’¤¶Ü_zà‹Püd²ˆæCPßròõ@ž´~õË,ò@Hð•ê7œ½Q+=Óý¡ûÊK’ÔöóàÔHt\‚«;QiB ×BvK~“/Ûø~Çe;Þ(Á™L¨•™õ³0a‚ž…î+/IR[îºFõÆÙш^ŽÁ©=VŒ©EltϦÞH}}ï¼¾h1cNòc±|,Ö@÷•—$©í·§¾è‡Q¿ÁiøU.[ápAÞiýoj‡äÔúÌ•r¤š`KÂä(\ Á=_è¾ò’$µýª»à•A™{ÎìGÓaü܆I. ­ƒî9Õ»$.ÖB}¼©'³ð³-7KÙº¯¼$Im?u?9ügãüôÊDKü+ñ™ ‹ë {Nõ.ÏÚ»ÐhCêa|”†¸X4Ãñ^8Ñ’$I»ó~(AÖ\|NÙPç¨Ì´C=C”¯~ü'µ>“èÁÂj ,ÇÎ$áÆ"ü~^ðƒîk.IÒÓRfO” Ç„Åèž„Æ\l/ÃÝ*ŒqC½Ñ£{fõj}Æ\‹ ;î#1 3¶âÚ œ ÄŸ…îk.IÒÓÒ§½ø]ÜZ…7R“w9VV£ƒê+ÒºgVoqÙƒN4ZñŽi¸‹ ãð½ÞÐ}µ¥ÿÿÉ„ út &²€&W& &(&("FHHopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/0000755000175000017500000000000012271062644020207 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/ref/0000755000175000017500000000000012271062644020763 5ustar mfvmfvopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/ref/histogram_cumulative.tif0000644000175000017500000000443112271062644025724 0ustar mfvmfvII*Î î2=S20.,*(!þþþþþùùÿ2012:07:26 1:26:25€?À8$ „BaP¸d6ˆDbQ8¤V‹C`Q˜äv=HdQÄŽ“JeR¹d¶'%“J%Ó9¤Öm˜HæSyäö}<œÈ§sú% Èhtze6 ¤È)tú¥VQÔêÕºäÒ±­WlV9~;a²ZmQK4rÑk¸\j«}Êív¶Æn·{åªó½ßpUÛüWƒÄU0±L>'GÅÄñ¸ü¤û#ÉåsS\¼G3›ÐK3± þ‡M#ÑÃôº}d{SÕëvQ]|kg·™ía›Æö/tßpu]ÄãrvœŽW6!º…ï9ÛÞ„+¥ÓÛõa=~ÆËµ€€€?À8$ „BaP¸d6ˆDbQ8¤V‹C`Q˜äv=HdQÄŽ“JeR¹d¶'%“J%Ó9¤Öm˜HæSyäö}<œÈ§sú% Èhtze6 ¤È)tú¥VQÔêÕºäÒ±­WlV9~;a²ZmQK4rÑk¸\j«}Êív¶Æn·{åªó½ßpUÛüWƒÄU0±L>'GÅÄñ¸ü¤û#ÉåsS\¼G3›ÐK3± þ‡M#ÑÃôº}d{SÕëvQ]|kg·™ía›Æö/tßpu]ÄãrvœŽW6!º…ï9ÛÞ„+¥ÓÛõa=~ÆËµ€€€?À8$ „BaP¸d6ˆDbQ8¤V‹C`Q˜äv=HdQÄŽ“JeR¹d¶'%“J%Ó9¤Öm˜HæSyäö}<œÈ§sú% Èhtze6 ¤È)tú¥VQÔêÕºäÒ±­WlV9~;a²ZmQK4rÑk¸\j«}Êív¶Æn·{åªó½ßpUÛüWƒÄU0±L>'GÅÄñ¸ü¤û#ÉåsS\¼G3›ÐK3± þ‡M#ÑÃôº}d{SÕëvQ]|kg·™ía›Æö/tßpu]ÄãrvœŽW6!º…ï9ÛÞ„+¥ÓÛõa=~ÆËµ€€€?À8$ „BaP¸d6ˆDbQ8¤V‹C`Q˜äv=HdQÄŽ“JeR¹d¶'%“J%Ó9¤Öm˜HæSyäö}<œÈ§sú% Èhtze6 ¤È)tú¥VQÔêÕºäÒ±­WlV9~;a²ZmQK4rÑk¸\j«}Êív¶Æn·{åªó½ßpUÛüWƒÄU0±L>'GÅÄñ¸ü¤û#ÉåsS\¼G3›ÐK3± þ‡M#ÑÃôº}d{SÕëvQ]|kg·™ía›Æö/tßpu]ÄãrvœŽW6!º…ï9ÛÞ„+¥ÓÛõa=~ÆËµ€€€?À8$ „BaP¸d6ˆDbQ8¤V‹C`Q˜äv=HdQÄŽ“JeR¹d¶'%“J%Ó9¤Öm˜HæSyäö}<œÈ§sú% Èhtze6 ¤È)tú¥VQÔêÕºäÒ±­WlV9~;a²ZmQK4rÑk¸\j«}Êív¶Æn·{åªó½ßpUÛüWƒÄU0±L>'GÅÄñ¸ü¤û#ÉåsS\¼G3›ÐK3± þ‡M#ÑÃôº}d{SÕëvQ]|kg·™ía›Æö/tßpu]ÄãrvœŽW6!º…ï9ÛÞ„+¥ÓÛõa=~ÆËµ€€€?À8$ „BaP¸d6ÃâQ8¤V-ŒBàQ˜äv= ˆÇäR9$–“JePy ®]/˜Aå¤v[5œNc³9Ôö!> Pa³Ê7£RgÔJU‘M¨Li•Í>©W“Tëµn½;¯Î«¶$Rµe“Xí¸Õ²aj·\`–{”Úëw„]/{…îÑz¿E/¸ ÁáëxlT3ªc2œ~N›’ËA²¹š6c9GÏÙsÙüÞ†£ÎitÓÝFgU«œërÚý„×e“Úmj[¨nçy.Ûä7ÛùWÃâVy9N^_›,çÒxØ®GF=ÓÃõzÑÈ€?À8$ „BaP¸d6ÃâQ8¤V-ŒBàQ˜äv= ˆÇäR9$–“JePy ®]/˜Aå¤v[5œNc³9Ôö!> Pa³Ê7£RgÔJU‘M¨Li•Í>©W“Tëµn½;¯Î«¶$Rµe“Xí¸Õ²aj·\`–{”Úëw„]/{…îÑz¿E/¸ ÁáëxlT3ªc2œ~N›’ËA²¹š6c9GÏÙsÙüÞ†£ÎitÓÝFgU«œërÚý„×e“Úmj[¨nçy.Ûä7ÛùWÃâVy9N^_›,çÒxØ®GF=ÓÃõzÑÈ€?À8$ „B0˜d6ˆDbQ8¤V-ŒDàQ˜|.9HdR9$–“@ãÒ™d¶]/˜Ce™\Æm7œNcRé¬ê}? L&riíG¤EèrZ-&O¨A)rJmF­WŸTäuZÅv½-­H«•û%–?aØìÖ»dFÑ µ[nW8-¾?qº^m—håâõ¯ß#7ì­‚Œa0غN"/ŠÆdhè¶C%—œe"¹lÆv_šŠg3Ú96‚'¢Òjd:h–£U¯Œk":í†Öw-Úm·Pí”Cs»àIçœ&¯‡ÅälxüžfÞY¿æí·±ÞVÓ‡t:Ú®Ä7µÛÒ@@openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/ref/fit.tif0000644000175000017500000015427112271062644022263 0ustar mfvmfvII*ÐÓððf ÜænFNV^(1vf2â=RS^¼r‚h‚ð»ƒöHH<OpenImageIO 1.3.5dev : ../../oiiotool/oiiotool ../../../../..//oiio-images/grid.tif --fit 360x240 -d uint8 -o fit.tifg.tif2013:10:17 15:06:22AuOpenImageIO 1.3.5dev : ../../oiiotool/oiiotool ../../../../..//oiio-images/grid.tif --fit 360x240 -d uint8 -o fit.tif xœíX LÔç~„ãë¾ùZ„‘/ØLÕ¹ºUSês5ÖÚ¬[cæºl ˲d[s©vµ´©¦ËªÝljÛlZ¤R”àêZ#8î€S>ŽïO¹ƒûàëàö¼aC½në²tHryïþÿçž÷Gîy~Ïïÿ†É垇¢£a‡F&ƒsr² óñÓí†ÆÏC\¾¾p{n…JÎkM¼·Ø+Þjµ ,L‡ªªÑÙy[·îçzƒü‰÷ùïÁñ%ðÿžx¸‹~Ák¯%`µNç9¹};j¨©$ꢓyÄ^.4Ñ>2‚Dêæ†Ó‰èÀ@Œ°÷;Øã¡ÞNà½.âåĪøj#>Y©„™:zøQâíÄÇ <¯%òÞ ¿È“V— I¼v“k´üòw3—§ë™á{'Q§%õõ0±ï¼°n>ïïGò]õ{«GÔ㥞ùÄ_G~}H(òËÏãOm¾Ø—{ý·ª¨‹$æM'û I##mP*“© 3dïeow ((†×x/Ñ+Þno Ž’P__‚Þ^Ö­{ýýŸ“?ù>ÿ=x;ñ±_ÿ¯ùŠ$®MÌ_%Þ~{;6$$xŠŸ{ƾ>è©©.zUÌgb«FJx8ZØëupQ?·Øÿc¨‘FâBC1Dùr®Sr†3 ?’ã&ñÂ{BkVÎr‹¨Ë:^KÕhÐÉïÉ©·`¹Ô^´È j7–ü#ä‘ð¢g}ªÕè` jÖ"^BÇ‚¿½&™{d0à së`Nj¹¦1¯g×?ƒÿG="¿¿Ðøt=Þðs¿žù›ÂüýMÑŸ‘ߢÀÏôWtõ©Y=œÎ.i>s˜ÐбÍv“ºXÂþïàÜf¥nñZ4šT¯x«µ¡¡É0>bn]ANÎA®µN›wüjuý~›bÂAÝæ·ZMä_JL±jÎãÚ{ê^õ¨TwÖ#fe™LM|=ñ©¼W/ùxjÊ9¿‹04Ô õ—ëÎz4QO³”¿ÇŽ-ÅÃqqžžz Wù›§Ñg­ìárf£ÈÇAúÕ‡ú8RQ—³³1Hï ë©›Óf3Ôƒž{$!qÔžŸ—Ñs&ö‘.êm˜ާW¼–JݵӳaÌ’~îWxó&R¸g({ÄŠ¨(ôp¯ öÌÜß~Š£=†êUô-õÙÌþ j4ˆ|á~E&jº»q˜µ}Æ{ÏÔ¯¦¦gð&êÚ[=KY7ü\ç¯aÏ[ŽKÏád›?~¼ç/èù’ÆÞÝJýÈ%ý¸\ÍÒ5‡Ã$õüÉI—ôl%—ÇS#Fjj©W¼Ýn Öõ0™ŠÐÝ]ƒììÃ̱ϨõeóŠßél䜽•ÌÇ(fž˜omÜKG.39¾ÎÏÝôÝæÏˆ…{êÿƒz‚¤àrµpÏtÞ«¥ƒéõaéyWð[­5ˆŒ\ÍÕ(ù÷Ÿõ‹l&^…'²ñH|¼§øé§qe`éô¥…`>>@´´ ÷Ô)<¼d JèñvêÈN ½XV†ŒFÌþ;²iÖ''Cçï/éMÇï ½‰s‘ÕÔ”ÐV/?ç•–¢˜Ù3ûï%jø{™™R>‹92åõ×Y³ gX›ð®’mbméÔxõÐÒù¬x–5\§þ_ݰŸôô cº~¡gq¶Ó87pooõ¿xÃÏuþ*öÑÌð…8PrÇ-ÈûþEôô]fïN§,ÓúÔð}£¤Ÿáa5¦“ô&ÎMDv WKzö†ªæ³b:ŒÆ³ÔÿulØð*zz>!Ƽá÷õUÒ—œ«»QXø,ví*§‡ý%iµËˆ/§&ØNaá deí¥×ª%Ž/ªG¥ZÆyØ"eiCC ®^=Ê=|“…5k~ÍA÷’?Þ\½~23w°GŒ2ßC¤~¢R¥s­£Õxó͵x”ósIn.®s†Í³¬˜o©‡HjD—ŸæáÙÝ»¥ù6€ÞÜuîÞ»v ߢ§ Ô]λïbœºúp×.lIJ‚\âÙLœ‡ZùÏÉ×83fEF"ÿÂäÑÿßÐéðÛ¡¡w³Ù#Ú©éBöˆ±±ˆbÖY,ØòÖ[øNZNoÛÆÿaMÌš4j\ÊyΟì•]]8´y3®qÍb¦µˆy’õ Ï›ù^àä5Ì®Gxh9ïyÃÏu~q–‘‰ýÅgp´EŽŸýð"º{¯S™üí[¤ùÍÏO+õq&z6Rc Òù¦˜Å{¡qf¹W¼Ífàü¹Œógºº*±yó!®×˜GYó‚_EMÔ(qìFÍ3MLEÑAˆ€ËØàSiï¡(ŠR¤Ã£+2ë\Ðɘ÷¼üîåœ}÷Ù×·Ö^ëœ;ÑÅ¥=14ª²2¸›š¢¼±=utÐ?2=ºw‡rÅ <¨¨€‹•&'#41_¾÷Ö Ë®]QÙÚŠ†– Ü·u¼¯]µ UìtuÑÜÖ†ê/`«¯ ^o(•˜þûï˜ëå…è¹s¡*/‡»…r++øë¯x®V#+<>x\S“W¯`¾s'æùøàðìÙ¸Ï:\ÍÍ‘_] ™¥%.deáNQ6…„@É«çÊêëaЭ XûCÞ;ó1×»ÿ«ÇÐ÷9æÊ9MñÚžÿ~U\ml±-á~xdˆu˯¢¨T33wÔ×—¡[7tïnÀû‡05uFMÍ#¼‹¶¶f¼xQ CC[ŽÝçœ«Æøêê|XZÊ•uEEw²‰W%ÌÍ=´>¿Z]Ìçí—w Ñј93nnÈh´·· µµ‚kÙ£k×V>'ONŨQÛ0n\ÊÊò˜Ãíÿêim­†‘‘-jkó™W†½{û¢¢B‰ðp+èë[3>0¦‹gÂÑÑ—÷…hi鎴ÃС˜2eóßg~WÔÕBGÇ‘‘nÖ§Oû±Y³Áßܸ¨koGÊ“'øòôi|æç‡äémrÛ“ØúúìY$ƒ‚‚0ÚÛ–]º „Ü5êÑá'Oâ1õÑGèco#¾q sÕ¿| {r¹œ\êÂâ!CQZ riü‘#¸NŽÅ‘ï^NNp=ŸzÝ‹œúìÔ)ĪTøŸ ¦¾’»‚¿5ä¦ ç’ç+ÉѳŒ9Ęùƒ!ï3€yŸ2feBNfgã»Ñ£ñ-ûÃâb éÕ aì#¿¥§#vÎôwt„SϞȬ­E?êöiƧ2n9ŸZR?j¨GŸ¾ÀŒµåã¾Ì/¯«“xß@ü‹z\©eéÌ!ÖÖŸImÓæüÌßßÚëÏFdV/½‰’ç÷¨=ƒÐØøÚ¡O=2#Îò`bâË~.'Žœ‰·⬆ÚáÊþŸÎ¹ãkj2‰­~ÈÎ>ââTLš´%%©Ìï§ÕùMLR/‹ùì3ìßïgç±X¸ðr;“¼wy“_OÏ™¼|Jþÿññ¡9r={À&Æ¥±/ üK=‚sñ—F=Áœ9gè2É÷þŒ+ÂÝ»GÉáøøÌ¥æG³w¤ÀÖv0®\ÙŽ«W¿Å´iQpu à{8¢¡!—=É”5Âhgçö?>ýwèM½Ùÿ«É¹¹11¸UP€ý3f`¹˜BžÙ‘7Aâ>ï¯-X@7‡u·€=߆Øú2.§¨'?OžŒ@OO0Oëkþo¹Ä–¤ÑÄk¹8ÆÅ™Ô__öŒgÔ”Í/âxf&6Ž… ¸N<ØÒÞ¼‰µ—/KcsèÛí‰U9õ¥×%þÓ·kÂ$±Çô'þ :ñlJ=zÀ{Ñ“²ˆÿ>¬±‘ø¯í¬'ƒcbmMñ¢?hqþtòw • 6\ˆÅǺXž„Ò²[Äg?â¹@Âs·n¦¼@üô#Þ²ˆ·>ÄQ#ñVKü»p,ƒs¾ãkk3øû üÇ÷é˜0añ–D~õ×êüÆÆ>ôȵäYy¶ C†,%·÷R£o“¿Îoòëéõ‘8—“s ‰‰K0|øêæ&úbÑcþ¥ž×ñ))1¸~}3üüaâÄÝÔãt©ž—/‹XK<Ο_™l,µ9‘½à¬­‡Ò£G#6v>Ÿ C`à ¾‹=õ7úkBÏ=#éŸO‘O÷„—¥÷ª!çæŸ8̧O±gútÌóðælÉßiÔß<ò<ž|7#þØó é߬èçVÇÇ#žÚºküxŒ$õé—ëÈM'Îç“çßÄÆJû(ûÂ(™ âÌ“k–—ß“£§år|3r$"ø/™¾ò}kküD°žsˇÇǃÚ^QøIOúÏö 9q¿?™þÓ›Ø-ä:zŒ1fmÛ^ìI¯:túOQà‚ð˜Â»kŠWÚœ_Îþàki…—õ¤;–…§N%V:ü¡ŽŽû¸±„m##/ÉOêé9tú½: {juŽä·5Å×Õ‰½›'ñ›@ÜË1vìvâ-™ù½µ:¿ðÖ::MHJÚƒ[·~Ř1›ðþû_ÑËÞfN§7ù…~õª¹¹7qáÂ7ÜŸ.£Ž 3$}»ßÖVJîîGzz† [€€UR¼¨§­­JåUòw 5?³gÇH½ÀÜ|½ó=DEM†““?>üp7ߣ÷ÿ|ðàLpqi?·p!r‰Ÿ¾ô^£>Œ»……ø÷ܹ˜åë 1æN¾Näøùü|ÄÏœ ?ò¯õ÷YCl©3ŽGl^NLŠ1ÔlãNÿ\E½èÍùRáŸÉñcÔœÃS¦`ž¿?”ôìÔœJÆ„S¿…ÞͽàWcÆ ‹<÷µ³ÃoÔß°ÄDl¡þ.6 fÔ™<âÓÍÒç²²B=ßÌ| Æ{±ÆÖcH=2"žï“çâŒ'Ÿ}BÆ„~Iõ°g(9&ÖÖŸW]­ÕùUì·î6¶ø.á$vàoË®¡¨TìùúÒ{•°‡Fô“g<âüÄÀ@Ö©UÄqoŽ)9ç¡1¾º:{87éü¦¸8S¦l&ÎÄ›—Vç75õâóýê:ܸñ=uù'j^85:9ÝÞä××ïÍk9ù gÎ|LîneXËÐqöv=ñeì ?3¹7Jñ¢F#—ŸÁÙ³¡ôÈ“±`A¼´/·¶öÂãÇrüò‹/y„Y³¢¹÷¶á{<æ;™cï^ urjâ~6‹¿¹ðeõÜÿŠ}ê­‡±UðŒZz—ž¹/õ"‚<Š£fDKÁ>>0g¬à¥!±#¼q½àarÛ‘ûV៛©Áâ¼EhG%ÿ>””„#ii'w—ScgÔ‹bbr5ù›Æžñ#× áš÷¨ó~Äø?’“±‡Ï­æšã¹¦µæ1+ÎÊ/äæ"‡:½|O½@œ…ýésó¨ÉÛ&M‚û~¹WN> Þ·݉¡ò+¤ó¨>ìüÏ@Uk+ÌÉïbò\Î=õxêô$WW$Ѓ+ij…îqíÀ &åK—›º›M<{ÛØàãcÇ$ÍN ƒkߥTÔ_wr;QèukKH²yõf)f-â{ŠIçyŽyò€Z%õ¦Îï/ã~CS¼Šú¨Íù•ì‹Ôß­ÔßÝÔßµÔßâÒ}ih(îüžb"áÌÔT|ïx aWœ­v|qàX.½`_ñÕÕ*ê—;õ+‘º•‚-¼foÞZßÄÄ›úÛˆ´´CHHXJŸ»†sÛ©¿*©÷½Î¯¯ïÀës(—÷ ½ðŒ÷7êiõ׳³cÔ~À --E\#Ÿ^8ÚD/ÎÓÜS‰+W6ãöír½ÁÁ+ÉÛ,ôêå+‘=„?Çøñ[ùV|§G¤–9"#=ñ_œ…xœÝXiPTW=ìK7 Ý€ 4K³ºÄX£VãcaŒq©Q3.q˜qÆ¥f&©‰Mâ’Ç8šh:nc´&¢ ŒŽkTD#›Í¾+K³6Ð4‹lsî³u,«Mò©zõ.÷}÷ÜïÁ9ßùî{ÙÏoàä¢Eø±¹ar9šúúWW‡…GbAd$âccq£¡|ÖÚÙ‰Ñ_|¹•/^Œi¾¾¨ïíÅôt|xþ<^ Å¿æÎEVK zF\//G¯…„‡£~`C­­1᫯ÐÂg—V¬€³‹ Fòúœëמ9ƒpâš7žŒËko‡†{¾fî{mÕ*4p/L†»Â]]‘”›‹ìÚZl›6 טs¤BJÆ:2?1Ê::áä„\b sp@ß­þŽŽÐC¼¯¹øœAŽŸÝÖ†‘îC±å?gpðž-Ö¬HA}ã-89E ³³VVް¶V ££LškoÏ…ƒÃ0ôõu ·· ŽŽþ0´ËÃÌÆ 9pu Gnnjk³1mÚ6ÔÕ]ƒB9¨ñœÂ‰ÑˆÆÆ:ô&Ôê,\˜ˆ¦¦tbú=Æ·³óá¸ùùW‘’ò'Œ¿ÑÑï2.ÎΣ¤|D¼¥%o€­­RÊÇÒÒûöýŠs}Xµê*óê$–zzªpüøJètZÌŸ”ûNg7áá1ׯŽ 6búô- ›J O¾S)ïNHH˜†ÉþþÉÔbzc#¢œQFmy+ó©ßtrëþúõ¨ìî†ÒÖvvøèÊüãêU¨=<°{útÜ!ïÞOM…-9”¸t)¢U*T0þdf&6PÓâçµjK®Eÿ0çW~÷TÔí_cb`C>Æ%%¤,[ï!C$ýV>x€&½SÀ{'bcdŽ£¹.«µQŒ;¥Õ"ƒ9îœ1—u:Œ"~9,øìLŒŽ£¨‰òy9/øßÚÓƒ@Ö€,Î ½˜‹ìø™¬Ÿ£‡zbSê)ÄWØaýo¯@WŸFnE‘Ã&>;s\BMD¡­-‡|!ñ³§§2Y ç²$½˜‹omÍÂ!QÐjO‘ÿ˜1c'¹wYâîàÇ/§Þ\©ß7 ×`Íš2twWÀÞÞWÂïëk'F(5XÍõpúôrLšô^}u2¤š!´ÚÕÕƒÔÔµ0ë¨íO Rùs]ΟŸšÜŽqãV`òä?sO5nÝÚ‹“'ã0t¨‹Ÿâ^Øc&ÜÝÇáÈ‘×PZz«Wgóð=ƒ‰Y@ý*ðõׯ`ªZ=úöÛÈ Ç m”°Ö+Éëee˜zäNÌ™ƒhú§uÖM5ö÷#!- SÃ~¼É™ƒŒóóôD5^ÅØ ……Xš˜;¡;ï¼êWmo/ùõ§×®açëmY’Þz üüPÍúÄýk¸Ïêú@v6*Ö­ƒð!ÁYæ˜C~Fº¹!1'·kj°uÖ,Üá} =­œëe䳋 9Ž &´Ô‹š˜Fî­ç%ÆBC#ùÌ\ü`ÇÏfÝ‹òðÂß’¿ÅîrG¼»ú jë2àâ2šÿûròYŽ ÉŸrEKΫÉI#/½4wvi6¾¥%nn‘ÈÉIDMÍmÌšµ•÷;ô´1ƒß`(¦Î†áöíƒ8{võt>>d©‚ú±FEÅ9œ;·è³ Œ¯¡÷»/˜5£’>¹!!PU•‹ýû_’øýúëûé“ÉóáŒ)D|ü8®mExø›’~oÜØX²$ ÞÞc¸’u$Ÿ{¸cûv®‹ þMOÎbŽ#¹§Ð¯+¾ür&Ž1pdÁd±ÖP#UìÇlÙóúQ“óNœ@Zi)ö±¿~I©„žž(<@hèLe¥äͼÆzyAE}jÉ›0®: £¿ì¥NwüðnÄÅ¡E`R¿U]]PÒKjÉ¿[õõR/hÅkŒ»;täŸøÄß•‘Oéëœ4 ËÇŽE/÷®¢¯‹ž:½£†1ßçåAKÿß4e n²þ„šòw Ÿ„‡s,â X“|¸w'k‚ùg!æ‚ùÌ\ü`Çÿ7w|v>Çî[á÷¿IDCSûC {¯*òÙq’zK¹\C.°æû ¿¿Sê÷†Ksry°Ùxƒ!µ@ƒ¼¼ïÙwj1eŠðž›Ä}NðíÙ×zbïÞq’6.Œ§^œ©§~út&ÒÓ¿•ê„çû9î¡þÀµõ˜0^ã3‚µ¢/î@II*ýýãz7æ¨ç³V¤¥EQÑiªÛ’½€¦NÝÂ~Ùº­•ü×ÂBÏõ{™ù –/?Ï|U|§R)ÿÎή“ãàÁ9˜8pvùrPK!¬ÿõä…èÇäôÑ|jl ûèjO»–½yÑJþ­–3ÎÒλ%“kJ©¿ò²ŒþâOˆIH@{ºl®-jjBŸÕ1Þž¬æ3%÷¬d_<œüìç;^ôcÅæÍX6j6³·ìçžrΕr­À/aPSï)ôæ›ÕÕØ4{6òy×°fˆüe䲌~ô(^ʇž%ðõì?•Ì¿ˆs"sñƒ¿ˆµ8ÈS‰-I'ðY™Ö\Dµ®€µ;„ÿ¯zrYø‘L⃋Ký¨ŒžåÏÞ°‹ý§žQr®ˆÏ‚ÌÆëõ%ìíÔÈÎNAuõMÌž½‰÷|òPó\à[ZÚSË Ü½{ ÇŽ- /üsç¦îÔŸ‘^ëAŒjbysÎ@l'z+8®ãÞž¬EÔb=¸»w«±bEWRï^Ô®ŽútãØ†çå|©Ž•Üo8µÛ!Õ77oê{/NŠcoþÄÄlí‹ÏæßÖv9ºaÏžà‡þ;¾ä¿!¢þÓ…¾DOÖHݸs¼‡^¸öÅ%íŠN|KÉgÞ¢ÏñŽäÂTÿƒ9WMŽåÝ»‡Í—.aËÌ™xÅי䬿)|Âø"æíKý ogš°æúòl¸‰çÞBî#zp…ÿJ1ùׯ'ýË„ÿ,ÿj7åÿØ¿ÌÄvüÇþûßd|sß¿þÛ(ü7„ç²*þïʿڥoAüË\üÿý+Åä_û×ó‚/. ‹\â™õc¬\y™š³âYXÿ_&{ˆÿ´¿ÅŒQQkˆŸÃµ©¿jÎp} qm¥x1~˜O.±UôðnÖŸ6öÔ$$L—W(ÏÕïqm7k„³„/“…Hþkaá$ù ä•+‘OÿœÒQKâû²œõ¼Hh”žPÇ9ñM©ÓTÿ…ÿ²þ‹xzî£xqvV ¿ o‹^Ù‚kêÉ/ñ=¬sÏŠ/å³ú±Ào&¾·à1ã|¸NŠ'ΓñŬô¯ä¬,¤WUáÃØXäÑ¿B™ëÏáÿ’ü;¾ä¿^Jl>}/sÀë.¡F÷°ÖwtèÈ79ù 'K8'Ί¥pt  ušüKEÿ*ä³`É/žŽ×ë‹é_ÈÊJ¦Ç¤#6öCúWý+Ôlü`Å7 ©¡`§KçekkKj©‘øÞÏÄçY£±Šº®\ùãÇÿýtëC>ûÍSñÅÄ$V)u`úþÖ±Šçì‹ì¹£ùLg:¿;=Æ7*¥óï®]ŒV*¶FGK5[|׬åÓÞäÕLBð¦Ø¤%Ñ¿µó^ æÔOÅ /¢öbLûê.zÆPÑÛ±,sñ%ŒW™úçGø…äbyj.¾Xô‰¼33âqØ0®èÿ›/p¯R£Á÷Gp7’ƒ/¾ƒøÒòòÊ‘J…¡Råp¨¹ž—b++Aää‘N§8’ÈÍ5!™ p¯L6_ÜËÏ/ÃÌŒñ¸€†b±q¨ÕÿKýdR4ŸE¿   ‚0Lý,–7¨ÿà™þ"ájþ£G!lØ¡¡sxÝl^ûéàAL…B¨.*âïÅ¡ÍÎ SåF#B‹‹(%xüQ2¢×éà ‡QÅ=¹|aa%%´ÛqÓçáînLr®1™ž«þµ'ú‡{z09=­è?É÷ÏÏ£²¼½}ßâĘÇ?¾ Ÿ0…¢¢j)?;[+¦“©ŒÆr,.† Ñ”Šòd$ NpØÇ½*Ùü…%%°Û¯Á绉žžÃ˜žž„ÉT£èÿGPÒïî>ÄùùéG"óÈÊ*Boo5vÖÖ®}½kœäÁ¬ÕÂOïVgeAÇ1ŵ…ÜŒ.-¡’µ!¹ºŠG5×bl3÷äò½üM‹Á€¯nú‘¶6Ü™……Ü)ú™×÷ðo)*Æ¿_ÁÅé,ØwsóÃÐjͬ ~~{5‡Žë)rcÁÒÒ(½¾««IŽ×ÕRL£Ù,›{a0Xàõ r£­ífgï;‹¢Ÿq}3–—°þjqáÂ[°Õׯõïß{¹æÂBäBC?7ðÀ’33c÷éÿ ä"NvÄ~m#Ϲ‡±&2(—?B/°ã‡·ý~ëêÂ=Î-bíQô3®ïe}o,-ÇñËßãó p BÐ…ÂÂfr!ÐÏ5ôs9eÌLÿ¿O.ÈN\ê×´ÚŒyÈ`“l~8<‚âb Ž_à÷ßFW×1Î÷XZý ë f©×W©Špúô¼¼iÓÚ{öà/~óúÿd"z¹žLŒóN,ÆÜ䢚÷µeòe‘¯ﶢǓ#¹|'÷šÉâe·Ž@';:pƒu¦U¯Wô×Aßbkq >ûígœŸÊŇïþŠ™9Ñÿ[x¯š¤— =}|\ŠÅãnÞ«ÉÏ2{¸(ïnudÄEŽ¶ÈæÇbN²Ø ·û2::N²ÎÜ€^ߪèg\¿YªÍ*•çÎuàÕººµþ½{q{nVúùC2 ò` c\[É”“<Ô’‘Ÿý_¬ÃŒ‰¼ÉåG"°ò.}Éå‚|ž²Ù0 b›¢¿.ú³6o/)ÅÑKøêa>:pÁ™?éÝV2ðð ®ÇÈ”Ѩ“ÌÔJü¤R©D£Ãorù‘È0ïÒV¸\—ȧ6Û)ƒƒÔߦègX_§³òüzx~õ8{ö¼Æþy`ß>ØyÿÚÎÞkBìÇÈC¡ØqÝB¦\ä­žÌ,ÑûÃâZdp+÷äòä§ÕdBŸÓ‰»‚€⼃5GÑϼ¾ƒý¹õ…2|Úÿ¾œ(À'ï_G dg¯¶ß~‚<ˆýX¡äãC ys‘™zzÿGXZ‹  [eó0™ZátöAóç!ÖœŠþ:èÇb#<¿Fœ9³ /ÕÖ®}³{7†Å;“ø®É~,_|¡Ÿ‹½Y#{´öoUj5é4b䧆½œß»äòÅ÷“FzÁ.ö…GÛÛq‹þФ诋¾›µ¹ÅTŒÞ«ýøn: ï½Ý‡Ùy;½»‘ý˜<äÓÏuRo¦Õ6²Z]…t:A~bìåj¤˜øÞ%—‹yèðx®°/t¡½ý(fgoQ¿IÑϰ¾øÞ•HŒÐâüù7ñr xœí™IlSW…‰#Ù±_ìØ¦QD„8âD1VmÕE•Dr£¸‹."•tÓAtQ©‹ˆÐ¤6DBBBÀ¢U[]dBmÕJQ Ɖ§Ìâ1Q<&Ž”Á=Ïu%ok¯Þê=ý÷×ÙÜïÿÜûÞniÉ÷÷#ÃZ[‹x6 µBuUøÞ¬Óa1™Ä!µ›;;Hlm¡^£Á,kf®IõÏ'0óxð(ÂY— >mz½¬_ýÙµ5˜ëêñíÐÏø~Qƒ/?ù¡hµµVd³q(jTU©ù¾®Éä"ÔêCØÙÙÄÖVM=k³\3Kö'ó0MðxÆ =‚Ëu–Ïôz›¬_ýtz ZðzSSþ‡¾>¸¹ç­‚€››PVT@ Ïs9ØÈJ\4¨TÈ‘Ÿìö6ð=Àš•kRýþL6zÁ¨Ïo,†®.<¤?Øeý²èû¨ßn0â»ß‡ñ㲟úñÕ'„Vln¾àÞ+É„€\î9Y™ B¥j ?9logù~€µ×¬’ý™ŒŸ^`ƒÏ7ŠXÌ‹®®Äã©o—õK®oÅÆÆ<öìpýú;è6™òwOžÄã•¥w/ll º²µôó2Ò¡Õb*Fsu5ÖÉO’þoæ,˜L¥p„kRýO9nOOc"Æ…žLD"8&ë—EßMýïÔá«‘Û\Rá³þF$ö˜Þ}”{¿€ÊÊjúy-™VÛA?ŸBuu3ùY§ÿ'9 ÌH¥&¹vD²?™| ƒÁééÛ‡'ÐÓs‘ÈõÉúeÐý¡¢B‡+WŽâ­ææüÝ'ðhuîýR‘ý|ŽïŽšxÈOùÙ ?)òÓB~ܬupMªßM¶Ì‚wÈç$¹¼ètâ^4ŠÃäSÖ/½þ$¿ßW÷ÖáÌØ\}¦Ä§ÜC4þ€{ï K ßçPSã ?òÓD~6ÈOŠü´°ææZ‡d*åfù¼C.'át^D4z|–õK¬/¬¯û8µ¸zõ ¼Éü|ëøq¯Âé÷G™Ÿ'ȃL<;©èç56¡­àç*Uc1¿¥ ,e2¾BÞ–êO§½Ì‡væÃ!r9…îîó̇÷©ß.ë—X_£±ó9[ÈÏ×®9áliÉœ:?ùi%S‘õuhèçy˜eïHæéç&z¾èÿkôÿž±¬Ù¸&Õ?“HÀb4bÄãÁ8óá@o/¼¡Ú8sdýÒëéÅÖºz|3ô ..©ñÅ鿊Šg²Vzw„~®!óØw$Éä<=ßTôÿ52ÒÀZ€k6ÉþDbF£Ïóá8z{ y9sÚdý2è§ÓÏXÓãòe^;x0³¯qÏéÝ¡—îCDoïHÄsÕ>¥¹ÝÝÂýÉ~αfæšT€³ÁJŽÆü~øb1œéìÄ8Ï×6Y¿,úâ¼¶ë ¸ôÇ(~ú§¾w +«nú¹xzé>d¹p"ž«”Ê}ØÝýÿþd¡¦Ñ˜%û3‘-+üþ1Äb>tvžÁÊÊ8õm²~‰õÕj Ÿ œ¿ܸñ.œ&S~¤¿^Îß62¦Ÿ‹ÿ#´Åû ksôzñÌ•-þ¿ha­•çe©þ ç‹•óeXœ/œ+ç\.LóÙÎù.ë—^?@/¶qþ~Íù{‰ó÷sÎßpÔK¦DÿÿGh Œètzý\á̵³“-þ¿hdÍÏór«d"ä|±r¾ s®ŒÃå:Çç4ç{»¬_b}­ÖBXä7­Çà ÿ%(*xœí˜[lSuÇ¿ì"k{ÚÓ]¶[wé`+ŒìÍDƒY\F–eú!!Á ‰¨ ê‹/*#x "áyÀ˜xIŒ³£AH l"£mÚîÒn+ЭÝÅuëuË.õû?$zð‰îé<4çŸßùåûr>ý~¿ç¼¸eKæû}ûðÇô4êFÜO§¡ÏÍ…)/é”2ó&ؤÓ!µ´„Øâ"*ôzxâql•$Õ}7ïm+,D—× W8Œ“--¸9>Ž“IÓ_}W,†í%ëpüçqñÁs8ò†S¿Ãh¬G:}¹¹zäå™J +³D n––RX\ŒA¯¯@<î$mUÝÇÝ(,ܯ· á° --'1>~&Sƒ¦ŸuýmH&“cÄ… -x¹¢"cß¿=SS°É2‚d@𠓇Ï62å&ådFð3»°€*ƒNÎojûÎÙYØŠŠpÙãA/ù<ÝÚŠë‘vhú«¢ofëÖ£óêe|\‹÷ß¼ÈÄmȲ Wxy)b17™)WøYX˜…ÁPÅ™SáMmvÖ‰¢"<žËä³­­§‰\§þM?ËúF£ÿ_ÿ¿&œ?ÿ^±X2W@ïä$ÍfŒ$“0s~>x®'Sòf!3Iz”?q nç=µ}7ùi(.Æ%·wÆÆp¢­ wyÝÉÌÑô³¯ïŠFa{~>¶‡ÏFôøà÷Âlnä³!äç›—åzòæ!3z’¿¨r ÊòvÕý™7Š‹àv_ÂØØ´µàõ.3g§¦¿ úñx?ÿ¿…8wn^(/Ï|¹w/œìÏVv¯û˜Ž<é碛YÙÑúÙß6 ½¼Œ8ùÙÌ.'f5¼§¶ïc·³Ò ®ø|ð°v67£›þP§é¯Š¾—Ù\_\‚S¿ØñÕÃ\¼ýú%LþÙKï¶²…ȃŽ~nTº™$YÙßúQP°ËËiòg—Û¬Ì$©Fu?÷Ñ ¬ðù®°zÐÜ܉ÉÉnê×iúYÖ7jy pñâ«Ø]U•ùéàAôOL –þ?A. dÁ@?â¹’œ 3/*èùsìoQö·R22ÈY5ï©íèÿ–’8\.tŽ¢³½}¼ZÙ5ýìëÒ‹«×—âx×·85,áÃ#×0é§ÿ×’‹ ² üÜÀó9«d^ “‹ ö·9ö·(¹)ål÷ªU÷£ÑJJ,p¹íF{{'¯}ìŒVMôc±Ìßbœ=[ówþîÙ£äo­ðÿ¹9èrržêÿ úÿ¦'ý_eÿQ¾8Vòåè“ù¢ég]ÿqþþjÇ×óð–Èß)‘¿µ˜› ñÙÿŸÿ'”o)ü_mÿŸ|q¬äËÑÇù¢égWÿQþ®YcTò·µº:c?t}Ì_ÁT$•‚Ä>&ÑÏdÄÂÙßµ*õz¤Wü¿ŒŒ ÐÿkÄ>ß¹þ½ïg¾T1_ìN'zB!ëè€ùRÇ|QÛ×ôŸ­¾’¿JñÉßàÓa>zï7ŒEú¦R©û˜D?—ÈH€3ñ®5½¾’þŸ^ñÿ2úÿïÕðë¿ûѨŸùR§ÓŽP¨ǘ/>æK꾦ÿìôeÙB¸¯¼ÿž9cEciiæÄ®]Šg‹ïšáùyÐÏÅ7áíb #eôÑßü‰,ðsfyʾ_ô8“ ·‚AøÉÒá¦&ÜL‘;M?ûúƒ"›e3¾¸{]ãkñÚîÓˆÎx”ïšóóa>û囈ðv1K&ôÿ2¥¿--%”,H&ýÊwµýD“©Áà-LOûÑÔt˜×{ä®ZÓ_ýTj„3 Ç»ø ¤Ž* xœí˜[H›gÇÿ§hNÆè~ ¡+*ø{ h AAÈT­ÑˆÐÚªÉ^¼@ŒŒèu:x#4pO®Þ¿ºŠºª*ŒÛl¸ïõâÄÐæÑd2)úyÐ÷­¬ ¾¶Ã#ßáìŒg>¹ ¯R}a¡V”“©ŒÆZ¬­… ÑT y2ƒN§G$âå^ƒlýêªUUu°ÙÆáõÞÇÐÐ ,.ÎÃdjRôó ®   ÃÃØßܼõÍp³V ½[]P×c ¹™N&QÏÞÞÜDœ«‘±Èíäž\½‡¿i10æñÀE_8ÙÓƒGá0,äNÑϽ¾›çxWE%¾üý®-àØ‘kX^™„Vk¦¯ûøß«¹tŒÈÉä4{C=67Ó\qÆRN£Ù)[ŸHx`0XàñŒ!r¡§ç$ÂáGä΢èç\ߌõõص¸zõmô·¶n= 'g¹ÎòrøÉ…†~nàŸ&gfæžÒÿÛÈE‚ìˆym;Ϲ›¹2(W?E/°TVâ¦Ýއ>Nâ ¿]¢÷(ú9×÷°¿·W×âÌðÅœ'>‡?èDyy'¹ðÓÏ5ôs9›fÎLÿJ.ÚÈNBš×´Úí̹É`‡l}$2…ÊJ ìö›ðùbpð4¿Oغýë fiW©*páÂ.¼ºcÇÖO‡á/þç]ôÿùT eôr=™˜åXä\䢑÷µuòc“o)+ƒSx<9’«wp¯“,Þp¹`p®¯÷ØgºõzE?úöX »+«ðùo¿àÊB1>zïW,- ÿïB*5O//#zúø¬”K$\¼¯5’ŸuÎp1”•µ'9Ú%[;Èb'\®ìèë;Ç>sz}·¢ŸsýN©7«T:\¾Ü‡×[Z¶FÆÃåeXéçÏÈ€àÁ@f[É”ƒ<4“ÁO”þ/zÁ$s‚7¹úÉhVÞ¥¯;°‘Ïóýý¸ b¢Ÿý¿Ù›÷VUãÔØu|ý¬»‹àÒŸôn+xöÆ3dÊŠXÌAfš%~2™¨Ô b±I‰7¹úht’wi+œÎëäÓ†þþóïP¢Ÿc}ÎÊóëæùÕãÒ¥×ðçç±#G`ãýk/g¯91‘‡r11î"SNòÖJf’ôþ—ˆƒ»¹'Wï ?Ý&F<öûqv`üîcÏQôs¯oç|n}©Ÿþˆ¯æÊðéwÙ8«íå?GÄmz½¬_ýÙµ5˜ëêñíÐÏø~Qƒ/?ù¡hµµVd³q(jTU©ù¾®Éä"ÔêCØÙÙÄÖVM=k³\3Kö'ó0MðxÆ =‚Ëu–Ïôz›¬_ýtz ZðzSSþ‡¾>¸¹ç­‚€››PVT@ Ïs9ØÈJ\4¨TÈ‘Ÿìö6ð=Àš•kRýþL6zÁ¨Ïo,†®.<¤?Øeý²èû¨ßn0â»ß‡ñ㲟úñÕ'„Vln¾àÞ+É„€\î9Y™ B¥j ?9logù~€µ×¬’ý™ŒŸ^`ƒÏ7ŠXÌ‹®®Äã©o—õK®oÅÆÆ<öìpýú;è6™òwOžÄã•¥w/ll º²µôó2Ò¡Õb*Fsu5ÖÉO’þoæ,˜L¥p„kRýO9nOOc"Æ…žLD"8&ë—EßMýïÔá«‘Û\Rá³þF$ö˜Þ}”{¿€ÊÊjúy-™VÛA?ŸBuu3ùY§ÿ'9 ÌH¥&¹vD²?™| ƒÁééÛ‡'ÐÓs‘ÈõÉúeÐý¡¢B‡+WŽâ­ææüÝ'ðhuîýR‘ý|ŽïŽšxÈOùÙ ?)òÓB~ܬupMªßM¶Ì‚wÈç$¹¼ètâ^4ŠÃäSÖ/½þ$¿ßW÷ÖáÌØ\}¦Ä§ÜC4þ€{ï K ßçPSã ?òÓD~6ÈOŠü´°ææZ‡d*åfù¼C.'át^D4z|–õK¬/¬¯û8µ¸zõ ¼Éü|ëøq¯Âé÷G™Ÿ'ȃL<;©èç56¡­àç*Uc1¿¥ ,e2¾BÞ–êO§½Ì‡væÃ!r9…îîó̇÷©ß.ë—X_£±ó9[ÈÏ×®9áliÉœ:?ùi%S‘õuhèçy˜eïHæéç&z¾èÿkôÿž±¬Ù¸&Õ?“HÀb4bÄãÁ8óá@o/¼¡Ú8sdýÒëéÅÖºz|3ô ..©ñÅ鿊Šg²Vzw„~®!óØw$Éä<=ßTôÿ52ÒÀZ€k6ÉþDbF£Ïóá8z{ y9sÚdý2è§ÓÏXÓãòe^;x0³¯qÏéÝ¡—îCDoïHÄsÕ>¥¹ÝÝÂýÉ~αfæšT€³ÁJŽÆü~øb1œéìÄ8Ï×6Y¿,úâ¼¶ë ¸ôÇ(~ú§¾w +«nú¹xzé>d¹p"ž«”Ê}ØÝýÿþd¡¦Ñ˜%û3‘-+üþ1Äb>tvžÁÊÊ8õm²~‰õÕj Ÿ œ¿ܸñ.œ&S~¤¿^Îß62¦Ÿ‹ÿ#´Åû ksôzñÌ•-þ¿ha­•çe©þ ç‹•óeXœ/œ+ç\.LóÙÎù.ë—^?@/¶qþ~Íù{‰ó÷sÎßpÔK¦DÿÿGh Œètzý\á̵³“-þ¿hdÍÏór«d"ä|±r¾ s®ŒÃå:Çç4ç{»¬_b}­ÖBXä7­Çà ÿ%(*xœí˜[lSuÇ¿ì"k{ÚÓ]¶[wé`+ŒìÍDƒY\F–eú!!Á ‰¨ ê‹/*#x "áyÀ˜xIŒ³£AH l"£mÚîÒn+ЭÝÅuëuË.õû?$zð‰îé<4çŸßùåûr>ý~¿ç¼¸eKæû}ûðÇô4êFÜO§¡ÏÍ…)/é”2ó&ؤÓ!µ´„Øâ"*ôzxâql•$Õ}7ïm+,D—× W8Œ“--¸9>Ž“IÓ_}W,†í%ëpüçqñÁs8ò†S¿Ãh¬G:}¹¹zäå™J +³D n––RX\ŒA¯¯@<î$mUÝÇÝ(,ܯ· á° --'1>~&Sƒ¦ŸuýmH&“cÄ… -x¹¢"cß¿=SS°É2‚d@𠓇Ï62å&ådFð3»°€*ƒNÎojûÎÙYØŠŠpÙãA/ù<ÝÚŠë‘vhú«¢ofëÖ£óêe|\‹÷ß¼ÈÄmȲ Wxy)b17™)WøYX˜…ÁPÅ™SáMmvÖ‰¢"<žËä³­­§‰\§þM?ËúF£ÿ_ÿ¿&œ?ÿ^±X2W@ïä$ÍfŒ$“0s~>x®'Sòf!3Iz”?q nç=µ}7ùi(.Æ%·wÆÆp¢­ wyÝÉÌÑô³¯ïŠFa{~>¶‡ÏFôøà÷Âlnä³!äç›—åzòæ!3z’¿¨r ÊòvÕý™7Š‹àv_ÂØØ´µàõ.3g§¦¿ úñx?ÿ¿…8wn^(/Ï|¹w/œìÏVv¯û˜Ž<é碛YÙÑúÙß6 ½¼Œ8ùÙÌ.'f5¼§¶ïc·³Ò ®ø|ð°v67£›þP§é¯Š¾—Ù\_\‚S¿ØñÕÃ\¼ýú%LþÙKï¶²…ȃŽ~nTº™$YÙßúQP°ËËiòg—Û¬Ì$©Fu?÷Ñ ¬ðù®°zÐÜ܉ÉÉnê×iúYÖ7jy pñâ«Ø]U•ùéàAôOL –þ?A. dÁ@?â¹’œ 3/*èùsìoQö·R22ÈY5ï©íèÿ–’8\.tŽ¢³½}¼ZÙ5ýìëÒ‹«×—âx×·85,áÃ#×0é§ÿ×’‹ ² üÜÀó9«d^ “‹ ö·9ö·(¹)ål÷ªU÷£ÑJJ,p¹íF{{'¯}ìŒVMôc±Ìßbœ=[ówþîÙ£äo­ðÿ¹9èrržêÿ úÿ¦'ý_eÿQ¾8Vòåè“ù¢ég]ÿqþþjÇ×óð–Èß)‘¿µ˜› ñÙÿŸÿ'”o)ü_mÿŸ|q¬äËÑÇù¢égWÿQþ®YcTò·µº:c?t}Ì_ÁT$•‚Ä>&ÑÏdÄÂÙßµ*õz¤Wü¿ŒŒ ÐÿkÄ>ß¹þ½ïg¾T1_ìN'zB!ëè€ùRÇ|QÛ×ôŸ­¾’¿JñÉßàÓa>zï7ŒEú¦R©û˜D?—ÈH€3ñ®5½¾’þŸ^ñÿ2úÿïÕðë¿ûѨŸùR§ÓŽP¨ǘ/>æK꾦ÿìôeÙB¸¯¼ÿž9cEciiæÄ®]Šg‹ïšáùyÐÏÅ7áíb #eôÑßü‰,ðsfyʾ_ô8“ ·‚AøÉÒá¦&ÜL‘;M?ûúƒ"›e3¾¸{]ãkñÚîÓˆÎx”ïšóóa>û囈ðv1K&ôÿ2¥¿--%”,H&ýÊwµýD“©Áà-LOûÑÔt˜×{ä®ZÓ_ýTj„3 Ç»ø ¤Ž* xœí˜[H›gÇÿ§hNÆè~ ¡+*ø{ h AAÈT­ÑˆÐÚªÉ^¼@ŒŒèu:x#4pO®Þ¿ºŠºª*ŒÛl¸ïõâÄÐæÑd2)úyÐ÷­¬ ¾¶Ã#ßáìŒg>¹ ¯R}a¡V”“©ŒÆZ¬­… ÑT y2ƒN§G$âå^ƒlýêªUUu°ÙÆáõÞÇÐÐ ,.ÎÃdjRôó ®   ÃÃØßܼõÍp³V ½[]P×c ¹™N&QÏÞÞÜDœ«‘±Èíäž\½‡¿i10æñÀE_8ÙÓƒGá0,äNÑϽ¾›çxWE%¾üý®-àØ‘kX^™„Vk¦¯ûøß«¹tŒÈÉä4{C=67Ó\qÆRN£Ù)[ŸHx`0XàñŒ!r¡§ç$ÂáGä΢èç\ߌõõص¸zõmô·¶n= 'g¹ÎòrøÉ…†~nàŸ&gfæžÒÿÛÈE‚ìˆym;Ϲ›¹2(W?E/°TVâ¦Ýއ>Nâ ¿]¢÷(ú9×÷°¿·W×âÌðÅœ'>‡?èDyy'¹ðÓÏ5ôs9›fÎLÿJ.ÚÈNBš×´Úí̹É`‡l}$2…ÊJ ìö›ðùbpð4¿Oغýë fiW©*páÂ.¼ºcÇÖO‡á/þç]ôÿùT eôr=™˜åXä\䢑÷µuòc“o)+ƒSx<9’«wp¯“,Þp¹`p®¯÷ØgºõzE?úöX »+«ðùo¿àÊB1>zïW,- ÿïB*5O//#zúø¬”K$\¼¯5’ŸuÎp1”•µ'9Ú%[;Èb'\®ìèë;Ç>sz}·¢ŸsýN©7«T:\¾Ü‡×[Z¶FÆÃåeXéçÏÈ€àÁ@f[É”ƒ<4“ÁO”þ/zÁ$s‚7¹úÉhVÞ¥¯;°‘Ïóýý¸ b¢Ÿý¿Ù›÷VUãÔØu|ý¬»‹àÒŸôn+xöÆ3dÊŠXÌAfš%~2™¨Ô b±I‰7¹úht’wi+œÎëäÓ†þþóïP¢Ÿc}ÎÊóëæùÕãÒ¥×ðçç±#G`ãýk/g¯91‘‡r11î"SNòÖJf’ôþ—ˆƒ»¹'Wï ?Ý&F<öûqv`üîcÏQôs¯oç|n}©Ÿþˆ¯æÊðéwÙ8«íå?GÄmz½¬_ýÙµ5˜ëêñíÐÏø~Qƒ/?ù¡hµµVd³q(jTU©ù¾®Éä"ÔêCØÙÙÄÖVM=k³\3Kö'ó0MðxÆ =‚Ëu–Ïôz›¬_ýtz ZðzSSþ‡¾>¸¹ç­‚€››PVT@ Ïs9ØÈJ\4¨TÈ‘Ÿìö6ð=Àš•kRýþL6zÁ¨Ïo,†®.<¤?Øeý²èû¨ßn0â»ß‡ñ㲟úñÕ'„Vln¾àÞ+É„€\î9Y™ B¥j ?9logù~€µ×¬’ý™ŒŸ^`ƒÏ7ŠXÌ‹®®Äã©o—õK®oÅÆÆ<öìpýú;è6™òwOžÄã•¥w/ll º²µôó2Ò¡Õb*Fsu5ÖÉO’þoæ,˜L¥p„kRýO9nOOc"Æ…žLD"8&ë—EßMýïÔá«‘Û\Rá³þF$ö˜Þ}”{¿€ÊÊjúy-™VÛA?ŸBuu3ùY§ÿ'9 ÌH¥&¹vD²?™| ƒÁééÛ‡'ÐÓs‘ÈõÉúeÐý¡¢B‡+WŽâ­ææüÝ'ðhuîýR‘ý|ŽïŽšxÈOùÙ ?)òÓB~ܬupMªßM¶Ì‚wÈç$¹¼ètâ^4ŠÃäSÖ/½þ$¿ßW÷ÖáÌØ\}¦Ä§ÜC4þ€{ï K ßçPSã ?òÓD~6ÈOŠü´°ææZ‡d*åfù¼C.'át^D4z|–õK¬/¬¯û8µ¸zõ ¼Éü|ëøq¯Âé÷G™Ÿ'ȃL<;©èç56¡­àç*Uc1¿¥ ,e2¾BÞ–êO§½Ì‡væÃ!r9…îîó̇÷©ß.ë—X_£±ó9[ÈÏ×®9áliÉœ:?ùi%S‘õuhèçy˜eïHæéç&z¾èÿkôÿž±¬Ù¸&Õ?“HÀb4bÄãÁ8óá@o/¼¡Ú8sdýÒëéÅÖºz|3ô ..©ñÅ鿊Šg²Vzw„~®!óØw$Éä<=ßTôÿ52ÒÀZ€k6ÉþDbF£Ïóá8z{ y9sÚdý2è§ÓÏXÓãòe^;x0³¯qÏéÝ¡—îCDoïHÄsÕ>¥¹ÝÝÂýÉ~αfæšT€³ÁJŽÆü~øb1œéìÄ8Ï×6Y¿,úâ¼¶ë ¸ôÇ(~ú§¾w +«nú¹xzé>d¹p"ž«”Ê}ØÝýÿþd¡¦Ñ˜%û3‘-+üþ1Äb>tvžÁÊÊ8õm²~‰õÕj Ÿ œ¿ܸñ.œ&S~¤¿^Îß62¦Ÿ‹ÿ#´Åû ksôzñÌ•-þ¿ha­•çe©þ ç‹•óeXœ/œ+ç\.LóÙÎù.ë—^?@/¶qþ~Íù{‰ó÷sÎßpÔK¦DÿÿGh Œètzý\á̵³“-þ¿hdÍÏór«d"ä|±r¾ s®ŒÃå:Çç4ç{»¬_b}­ÖBXä7­Çà ÿ%(*xœí˜[lSuÇ¿ì"k{ÚÓ]¶[wé`+ŒìÍDƒY\F–eú!!Á ‰¨ ê‹/*#x "áyÀ˜xIŒ³£AH l"£mÚîÒn+ЭÝÅuëuË.õû?$zð‰îé<4çŸßùåûr>ý~¿ç¼¸eKæû}ûðÇô4êFÜO§¡ÏÍ…)/é”2ó&ؤÓ!µ´„Øâ"*ôzxâql•$Õ}7ïm+,D—× W8Œ“--¸9>Ž“IÓ_}W,†í%ëpüçqñÁs8ò†S¿Ãh¬G:}¹¹zäå™J +³D n––RX\ŒA¯¯@<î$mUÝÇÝ(,ܯ· á° --'1>~&Sƒ¦ŸuýmH&“cÄ… -x¹¢"cß¿=SS°É2‚d@𠓇Ï62å&ådFð3»°€*ƒNÎojûÎÙYØŠŠpÙãA/ù<ÝÚŠë‘vhú«¢ofëÖ£óêe|\‹÷ß¼ÈÄmȲ Wxy)b17™)WøYX˜…ÁPÅ™SáMmvÖ‰¢"<žËä³­­§‰\§þM?ËúF£ÿ_ÿ¿&œ?ÿ^±X2W@ïä$ÍfŒ$“0s~>x®'Sòf!3Iz”?q nç=µ}7ùi(.Æ%·wÆÆp¢­ wyÝÉÌÑô³¯ïŠFa{~>¶‡ÏFôøà÷Âlnä³!äç›—åzòæ!3z’¿¨r ÊòvÕý™7Š‹àv_ÂØØ´µàõ.3g§¦¿ úñx?ÿ¿…8wn^(/Ï|¹w/œìÏVv¯û˜Ž<é碛YÙÑúÙß6 ½¼Œ8ùÙÌ.'f5¼§¶ïc·³Ò ®ø|ð°v67£›þP§é¯Š¾—Ù\_\‚S¿ØñÕÃ\¼ýú%LþÙKï¶²…ȃŽ~nTº™$YÙßúQP°ËËiòg—Û¬Ì$©Fu?÷Ñ ¬ðù®°zÐÜ܉ÉÉnê×iúYÖ7jy pñâ«Ø]U•ùéàAôOL –þ?A. dÁ@?â¹’œ 3/*èùsìoQö·R22ÈY5ï©íèÿ–’8\.tŽ¢³½}¼ZÙ5ýìëÒ‹«×—âx×·85,áÃ#×0é§ÿ×’‹ ² üÜÀó9«d^ “‹ ö·9ö·(¹)ål÷ªU÷£ÑJJ,p¹íF{{'¯}ìŒVMôc±Ìßbœ=[ówþîÙ£äo­ðÿ¹9èrržêÿ úÿ¦'ý_eÿQ¾8Vòåè“ù¢ég]ÿqþþjÇ×óð–Èß)‘¿µ˜› ñÙÿŸÿ'”o)ü_mÿŸ|q¬äËÑÇù¢égWÿQþ®YcTò·µº:c?t}Ì_ÁT$•‚Ä>&ÑÏdÄÂÙßµ*õz¤Wü¿ŒŒ ÐÿkÄ>ß¹þ½ïg¾T1_ìN'zB!ëè€ùRÇ|QÛ×ôŸ­¾’¿JñÉßàÓa>zï7ŒEú¦R©û˜D?—ÈH€3ñ®5½¾’þŸ^ñÿ2úÿïÕðë¿ûѨŸùR§ÓŽP¨ǘ/>æK꾦ÿìôeÙB¸¯¼ÿž9cEciiæÄ®]Šg‹ïšáùyÐÏÅ7áíb #eôÑßü‰,ðsfyʾ_ô8“ ·‚AøÉÒá¦&ÜL‘;M?ûúƒ"›e3¾¸{]ãkñÚîÓˆÎx”ïšóóa>û囈ðv1K&ôÿ2¥¿--%”,H&ýÊwµýD“©Áà-LOûÑÔt˜×{ä®ZÓ_ýTj„3 Ç»ø ¤Ž* xœí˜[H›gÇÿ§hNÆè~ ¡+*ø{ h AAÈT­ÑˆÐÚªÉ^¼@ŒŒèu:x#4pO®Þ¿ºŠºª*ŒÛl¸ïõâÄÐæÑd2)úyÐ÷­¬ ¾¶Ã#ßáìŒg>¹ ¯R}a¡V”“©ŒÆZ¬­… ÑT y2ƒN§G$âå^ƒlýêªUUu°ÙÆáõÞÇÐÐ ,.ÎÃdjRôó ®   ÃÃØßܼõÍp³V ½[]P×c ¹™N&QÏÞÞÜDœ«‘±Èíäž\½‡¿i10æñÀE_8ÙÓƒGá0,äNÑϽ¾›çxWE%¾üý®-àØ‘kX^™„Vk¦¯ûøß«¹tŒÈÉä4{C=67Ó\qÆRN£Ù)[ŸHx`0XàñŒ!r¡§ç$ÂáGä΢èç\ߌõõص¸zõmô·¶n= 'g¹ÎòrøÉ…†~nàŸ&gfæžÒÿÛÈE‚ìˆym;Ϲ›¹2(W?E/°TVâ¦Ýއ>Nâ ¿]¢÷(ú9×÷°¿·W×âÌðÅœ'>‡?èDyy'¹ðÓÏ5ôs9›fÎLÿJ.ÚÈNBš×´Úí̹É`‡l}$2…ÊJ ìö›ðùbpð4¿Oغýë fiW©*páÂ.¼ºcÇÖO‡á/þç]ôÿùT eôr=™˜åXä\䢑÷µuòc“o)+ƒSx<9’«wp¯“,Þp¹`p®¯÷ØgºõzE?úöX »+«ðùo¿àÊB1>zïW,- ÿïB*5O//#zúø¬”K$\¼¯5’ŸuÎp1”•µ'9Ú%[;Èb'\®ìèë;Ç>sz}·¢ŸsýN©7«T:\¾Ü‡×[Z¶FÆÃåeXéçÏÈ€àÁ@f[É”ƒ<4“ÁO”þ/zÁ$s‚7¹úÉhVÞ¥¯;°‘Ïóýý¸ b¢Ÿý¿Ù›÷VUãÔØu|ý¬»‹àÒŸôn+xöÆ3dÊŠXÌAfš%~2™¨Ô b±I‰7¹úht’wi+œÎëäÓ†þþóïP¢Ÿc}ÎÊóëæùÕãÒ¥×ðçç±#G`ãýk/g¯91‘‡r11î"SNòÖJf’ôþ—ˆƒ»¹'Wï ?Ý&F<öûqv`üîcÏQôs¯oç|n}©Ÿþˆ¯æÊðéwÙ8«íå?GľçrlsFÙz¯×A/0Án¿ —kUUXX¸O}sTÿëá÷!&F‹«W£º°0|ëØ1ÙzçRS-èïoÆìl7jkÏan®›ú¢ú; /üA¡ÐãÒ¥ýø¨  |ëèQt>} ×~2ƒž~>ÊwKRlä'ŸüøÉÏ2ù)"?½«àœ\}/Ù²0 Þ Ÿ=äòBM îÎÏc/ùŒê¿yýîßwv§ãTÇ \žJÄ7ŸÝÅüÂß\{ y˜”xˆ‹Óó}IIòc#?ùäÇO~–ÉOÇz9W![¿¼ÜË,(ø¼A.{PSsóówÉçÞ¨þÖ×j-X]µ³ÿêpùòøùù·#GðùÙ̵ŸfS2%ÑÏeÌt"ïeGòÛ ó›`Id4‘·åêÈ–™ù°•ù°\ž­®Æ=æÃò¨þkÕYYdf±E~žb½ÈàýÔ›ùù‡ß[ñót<¾lhg~î&ff°'äA)å1¿JÊt"«)•9‘ü¶"±äõÚ¥¼ˆ³–’þŸ$±¤Õ–‘­æC3óa+¹ìCuõYæÃ{Ô/—­ýB©ÌŽê¿}ÆÌ爔Ÿ¯\©AMQQ¸ýøq8ÈO)™š[]…Fð@~F˜ÇÄÉý¼ž/ü‰þŸEn9fâœ\ý°Ûƒí6º˜ëê0àt¢Œ='ªÿêú"—0IwUÔ\Ü_ }ÇJ©áì÷8ÖOsOçp Ó‹s32q¾å:ÎŽkÐxâOÌÌNÒÿóéÝnî_ âùîäX&ÇÈLaÄÿ—ÈHÜn;ç̬™å^×Hüø|ÏïTÜîa %°ÙÚ™»PW×§s€=§Œõs’~|¼ößzgŒ=å¿úÏ çL²õQý—믬Lq,/šð~^^ø§úzظæFz·ó…ûÑ Ä‰à(31­-éþ$‡½@Œ ¦äêÉ‘‘œv8°»\8UY‰.ž¯MQýWÒOˆ‰‘êç××aa¸«z+!žµ5©ÿæ²ÿŠsïkí\·4þÌùYþ-z³ƒù<]©BóÃNÜYŒÅáONÂëû· ëë‹ôó]ôï]ä`˜¬ñWÅý›MvV¥3˜V[Dßãx)ù™D8 ~Fµ5§tâõ ¶Œp8:àrÙQYyŠÐÅÏ™ :_¸o™–êŹ-11[[Û÷39Ò˜FS,[Õÿ}µº„Ïq®Ÿ×®}ŠšÂÂp{CØËÈÊ,ý_|¡ÛöŽÒëÅ™Ëñÿìmÿgo«b1²7´‰þ¾rÆjE?Ÿåì Qý—ë?aM:÷`÷ã}Žè ˜‡ßKOÇnæk/ÿGª8ë²n†Ù»ed-CC˜ážUpßoq³•¤¥á«ï¢}І;n5>>xŽë¿íŸ„-JK­ÈÏ?„¼¼2)[+!éþ$Ò`zºUºõ#-­‚õ»ðìÙóžàñl÷—6ö•.X­gøìgf,ôkñ}‡NbP¯/aý¨t¦ …|‘ïG²9æày¼T¶Þí¢¾1ª/£¯Ó•Ð&¸V)hj2ã—õ)xœí˜‰SÔçÇ¿À²À,§á¹/kÇØÁ =°¡0ŠG¢5Z¯GSM:µM1™jMŒ¶±t¢ñŠ˜Xâ˜HŒ Z¥Eã \]NE¹AXv—ea—£ß߯ÆÝüËÌÎïå}Ÿßw™y?Ïó}RfΜørÕ*<èïÇ,¥M&Èà*‘ yhHÜ«D‹ †ÆÆ E¨LµÁ€8…Âj|ÏâÝÝq¹º•Ø—–†ÛÝÝHpuµé[ÑßOý›]]˜Ã½>¾_ªÑàdI êµZØ;:ÂL] ÷•üŽm/¾ˆ_ÍžJñÔ²·Ç¿›š°!'ã˜!—ãèÊ•X…_Çñ)vl»ƒÞ¾ÈÍýššŠ üÌŸ¿))oÂÞÞ:]ŠžÝÅ7ßìÁÐvvFPfóÏü1oÞ6„…%B&‹@)<=¡V®®J¤¥íCw÷m¸º&Àdz $Wê4C©œ…ÁÁj¸¸all££zj„Â`PS7Îj¼ÁPw÷xTW_Fg§Mj|<ŒÆzÞ›'N¤ág¡¡ùkÖàþÓ§HT©ÐBÆÞTä­‘ëD2[¥×#„L |ê,D‘ î <[‹¯ [‰ÈU«QF>³ÒÓQD>gÛô­ê`þÞïëC€TŠÕ/âóqëܹXš”„dQ_5>Žì°ÿî]$úûcÿ¦Ÿò¬žµ€Œ“'Ñe4⇾¾øxùrD»¹cϵK8ñØ¿}ýŒ¦ܺu÷ïówÅŠsð÷"7áÌßJäço‡FS‚¹s·"9yÆÇ[E¶úûëPZzŒŸOàçÏ÷¾âÛ:ž…‘ϯÉgÒÓ³˜ÇEP©f“±–g¼©¸n$³‰Ðë«ÈdˆÈ§Å¢ƒ\Á½ ‘gkñ:]<<„úkÓŸ¯T&2k˜¿®8~üÇx9<|âêúõ(ëíÅÜÜ !ròæÆº_Ïõ,2«&oádÒHÐò#¬“xf-¾j` žž¸XU…ÒŽ|°p!ò)ø‹Mª~ u÷-Z„û­­Øž›‹;mm8ÈÜÜš’‚jÞI=ö?ÔŠ¤—;ÑÿxãþRXˆPþ-êÍ›¡³³Cý?5;[ÌßyÌíOV¬@¼× ü)ÿ ÔÈðöonB?(äïaܹóW1W¯ÎCPP’迟~šŒööb¤¦¾‹—^z›§ hµå"o&“†… ¸ø._Þoï$¼úê!$£¼üKòù ~€ŽŽ‡ôœ9dKCÞäptt}B¥šEžÕd2œÞbäG+®ÆUª$«ñUô÷TU]¤n©MZ¼ÁPÇ{sÇáó1?$dâ4û­ öÏ1d¥ýž ySÒ/„Þ/†ÜÔ‘gg˜èòLŽ„½(žY‹¯¡'İ\©©š}çî PLcmúÿ§_E_?‘_œ:…{Í͈ À¯½“ÙŒ¶áañNê©åçä#}VÊ:ðÎ¥K¸NN ÅþÅ‹Åü]{æ ž þNOÞ»d ¢Ý=ðáõ|œkuÀë/À8ô÷îAII¶˜¿Ë–Ahè\ºô.®qýî}Ä^®]ô¹< Ãí쥥Ìá0œ>ÖÖJ&`ýú2Ï¡§§ ìFoo1½!–ùÞFÞ\èJ±÷S(b¨Ygçzº‰|èùÁâžBe5Þ`¨›[ jj®°ïTÛô'ÅËåÑ|6Š5ö³Ï–"#"b"oãFÔõôðÎÝÑCädMNNš¸#gÍô‹PzÊ0ùѲ?ô%ƒ ܋䙵øFÎmá^^(¨¬Dq{;vgf¢–ÏöŒ6ýïôóÊËQϺ™ŽØ#Gļú;½þ-öμH41'ë©mO­ÛáçgÏŠñǘ«¿ŒEDVzŸÌü?Ãzâýö^>›Øùæ¿0`èÅÍ›q¾}O|oÓ¦‡ìÑÔÈÉY+þ¾reââÒ¸×Ê\ ¤‡4ÁHrÔÃZïĺ¯âû{qåÊN1~ÆbòfAcãU,Yòý»–=cŒ/‘~!纉aÔj&w¡ì‡ÙjÉ¥ïýéñZm#¼¼ÂQYY ö™™»mú“âõú'¼O:…dúï?ØoU)Á„šïboÿÜ/¢¹'ô}¢¿Ïçþ½(2e-¾ö™¿ÔÖŠþµ+5õ;ÿ²é?×Ï«®F;gÛ.þ~¶‚ý=öcÞE8먔}që4ý!j0w™Ç/sÞ5ñˆƒì¿—²Öò»è¿ïÓ“£ÝJï-"2úi>ë¾ Ìf-Ÿ‚ÿÖ=óß6²â ''OzI1.\øFFtˆÍDt´àÇÅô—??÷—ÿÅOö—hÑËûÎ_¦êO7jEÿª­-ý+5u—MR¼0ÛÙ)pêÔ+ÈˆŠœÈÛ² Ý=ˆôpGï ç5‰dô a3ÝÝÐ2 CYã|g¶ÀG©À#í"xf-¾¹_‹Poo\-+Cq[;v-[Šºö6DÓ¿lúßê{ázE% 5¢H£Ayg'æúù!ÿõ}Ÿ¾0_3g}\•H:ð7TvvÁƒûåolÁŽCë@2óùóµkì=ïçžEV£ »~/ø¯……Y(*Ú#æïºu7è¥o±ÿ­†O"¶o¯ +Býד³ô&Îka¬ùOÅùK*u!S­ÈÎ~…³\ ý%))ïpN{‚Å‹wÒ_è/‘b¼D¢`Mp&Ç-Ô¡—}_0ù´ˆõaºþôøþ~ çì™(+»†¶¶{ìëwÙô'ÅëõíÌiÖçW¹Oü::-ÃC:¡oÔÂÚogzÆÓQ3üù^»ežG˜9ß OŒÃ›ë6îù;Zo3ÃßÙê¾^´ XF“úÎ6ýgú~NôhíSÔ ô¡E¯ƒvd2–GÇÃv¢g[Ó7Qÿ‰‡ªËÐ9d„3}}Cô,œ®¯†ÁbF \‰E1ðs–áFKn¤˜¿–Ñ>2ô]]Åbþ†…eâÉ“Bæë çÝì7‘&&FÈ‹÷;ÈŒ¯øÿ;;GÑƒÇÆ´¨¯Ïcýï`>+™÷óx>Œ  âÿ¹¤R¿)ñ£üNAÃb颦;ûm3õ‡¿WÿÛx³¹“~䃾¾ZÖŒ§S¿Ù¦ÿ,~t´›7H>ÕÙø/L2xœíXùS”÷~`—cÙ{ASXûÐP£¦f"V§–‘¡C‚™±aƤ8Îô—6µedŒGÆNP4Ú8NEcEÉ€ÜÅÁ3’Ê-·0 Dzœ‹{À²l¿ßob»í_°ðþï»Ïû¼ ïó|Ÿçóu“yØ…kV`Qk…‹ˆ »e.®Ü\`7‘cvƒ .>ÑÑ ¸¸¸ ""ÃÃc°ZÀç{áÝw0;;›Í//O &…|X,³puå€Ëå`nn ¨ÕZv¾r¥ÜÜÜ —C£ÑC$zƒwsãÀDžI¯Q.Ï“q/,8æ_Š×ëéw^P©Ô Jžéä7ÍäÿÏEKK¢Ò¢ì˳198™\£Æ®€ËÞ‹Aa€,D R ~¶Eæ5óy ¡ÒB&qˆ¥Ð`EˆZkŸCùL‰=9»1: „w„“ÿ ¿7:žv¡íz;†A3¤AÈûÁøô_û‰×wwwÇü¯æ!]!ŹÎcøû¸ Ý‘Ýô®oûºQãø]á>øú៹·À«áãÁ³ûÐé ÈËû ¹¹Ç™ç‹‹ïâàÁ˜œœDrr2𛛉—mD{:x{Ë044‚°°UÄ—:¦•êöîÍÄýûµÀáÃGˆ§çðùç"¾$k‚|^¡P"$$Jå8‚‚°¸ò½úò¿Æ+£ä3µµðìÙ¿‘“óW'ÿüää4d2Y7CúËP{FA4í£„˜#~'k=ÕœEa ZcŸžžd}_Ä‚q¼Œ½F"ñ†^$Q¼¨y©î)lÍÙ U£ Âh'ÿRþÞÚ^Œ6ŽBÙ¬„ªOY2ò3à&p‡ÏqÌo y)çãÆÎ˜~1 ¾˜n~„¬B˜gÌX™¸é'Ò!‹‘¡út58–B1¬À­[·píÚ5æß‹/âܹsDWXµjÊÊʈwõdm7²óÞÞ^’‘ƒ§§'ÓõúÑ£GÑÙÙ‰ððpdeeaddÇŽCSS¢££žÇã1¼B¡`×úúúHò}–ñ‡„„,ãO¿‹ŠŠBMM º»»‰þsÐØØèä'xÊûòåKvž‘‘ˆÔûþªý˜îš†$^Ó¸ \>É ±Ó Õ™¶Ÿ¬ÿ«Éúo´Áª±B,€¶G q¬Ø!^Ó«w4É—ÊŒ5Œ1=uŽAš uò/áo+kƒº_ í°Í_7ÃtßOÊ?ÿÀ0õ™–ñSïÒgpVp’Äò÷äø°ìCœ;ó´ï"óz&|#|Qô—"jxÔðˆyïÂ… 8uêóokk+Ž?Žòòr–õƒƒƒðñña8êßžžÄÆÆ’Î=Núœ$ ó(ÕÌðð0²³³Ùqmm-㤞NHH`x>Ÿ±XÌtIõÖßßÕ«W3mj4/ãOµKu]YY‰††œ8qÂÉ¿OßÍ߸¸8„}fÿ¸øc¨›Õ&a±€Cæ7.™õ̃fvÍØmd™b3“~®_€—Ü †.q‡xC‡Òx)º+º1Ñ>íg¶cªn ¢D‘“ gi't üýQ˜YÈ|µõðV¬ûlæmó˜SÌA ø™ßJædùRNáfÚM†Oû" á¿ Ç7Û¾Emÿ;þØý·ÝðNðFyñæî¨|T‰AÒß pùòev_ii)óãÉ“'Ù9½¾}ûv¶ÆS-uuu1}Ð|õðð`ù@ï?räѾmÅÓ§OqöìYÔÕÕ!11‘á©ßE"ÓÕ,Í š)f³™e¼\._Æÿ6¾££ñññ¨¨¨@{{;Μ9ãäÿ Oy©…B!{_ò_Éíûªöa¦aâ$1ÌÃæõ&&z0C”$‚¾C¯P/¦O«Îʲ@ߦgzv„×µé K’¡ën&Z'š—ŠÉÇ“¯uò/ã/éÂxË8Òϧãòû—1R7ß0_ìÿa?lvó;}&åç­â1nOž'*ÿ\‰ŽÂÄeÆ!ýËthÉ|\ðÛ–¿¿Àž {à“äƒÒ£¥ðøÞ뢿¯W¯^E~~>óßíÛ·±~ýz8p€õ¼ 6àÎ;˜žž&sZË ª7ª:»Ó,زe žþœéæ1͆ªª*ìØ±ƒyûÊ•+HIIAqq1Û÷:}ú4ZZZ}í{´oÓœ ùB³„Þg2™X?¤ÇTŸkÖ¬qˆ§z¦Ú-))aÁÉ¿Oû¹T*eï'tS¨=óÛL¨ÛHŽ!ýYIúä…˺Ÿ FÀöb<ƒ<±hùqÿ„fÛŸ‰8Äz ÄHÐS݃©®)lËÝU½ŠiÑÉÿßütL×£ƒM`CÙÊØZ‘š€ä½ÉðÛäÇææ9ëšÿÑŒ¶’6„¥„!%;¾ë}a5cÞ2ë™×ayeaûWç2 £â‹ pë¹(®*ÆøØ8óï7˜/]ºÄ4F×}º·Bgaª»ÔÔTæaš¯s€ú•ι7nd÷ÍÌÌ0Oß»wå4õ}}}=Ëh¥RÉö[h¿£Ý/&&†é-((‹ƒáçý1:Ë9ÂÓ|¡ŸÕÕÕLÛNþ7x:WÓ¦ûW»ví ©)¡xœí™ILwÆ?À63cÏØY„X‚ 6K€(©ˆÒ´Šª6ÍZå€rˆ*5JOUŽí¡ D%—ÜzL+õPµjDz`«ŠZ‘68ƒÙ1ˆYLc{Ìx+8î¼?1ŠZ§í¡ÉÉ–¬‘ÇÏ?Yúï}ï½±¾kM^ê¸ß„’M‚âS á4ÐrZ(b©ˆàlÜ~‰X ðù<‚SAˆebÚøÀL;-;áêvÁÛïÅ™«gà÷Âd7eø/à/º±§j”€‚Á¯áüÖ‰èZB±€Äz±H ;rw þ£zÔ_®‡üHFî¾\l¬làÁ—Ðói蕥ɹ/ΡþÃz|÷ñwàáqgàz{{qùòeÌḬ̀¸³gÏâÚµk¨¬¬ÄŠ‹‹qóæM\¿~:ÇÁëõÂl6ãÊ•+8~ü8ŠŠŠ099‰òòrtww£¿¿W¯^Åøø8ìv;|>û½=JKK1;;‹ýû÷#‹! ??SSS(++KOÿÑb±dø/àÓyљД¼^’lü¦~§B…€Øã²uÙÐDç£àí<” úB=Ñ6•Mè÷ꡌ+àm|Úøõ±uHv £]£Xu¯âæwà»çƒP™á¿ßïcñqo\‡¬Ü,,ö,")$Ùï̵fHžÆžF æ‰ÁãöÀÓã¹ÜŒ¶OÚÀýÌ1ÿAuu5VVVX-§ó'UTT`xx˜ÕõP(ÄÞ”£¤)ÒÊââ"²³³a4™njkkñðáCvmkkÃÀÀólº>|˜yD^^$Iby^SS³Í‡Ãƒ¬V áàÁƒiã3üæÓ¹‰¢ˆC‡¡ô­ÒäÅ/â÷þßa¬Uõ6·¥7¨Ad:C­!—ªÏUŸUŸ²ªO+‡3C!m¼ì”aª5aäö–‡–Ñp£+}+ëÄ ÿ¿ò„§ÃŒÁêñÉßåÍ¿ñ™¿«ñ‘™»Gü=¯íÁÿ€Ü;¹èêï}¿âÀxôèÓå#iƒ¼Õår¡¤¤‘H²,3-‘Sñ”珞ééi¦KòaºÞ¾}›éìÆèëëc¬¹¹9Æ>þ¯|«ÕʤÅtñþ?óGGGÙù;v %o–$/ܺÿ †J¢ Qd볡5h™6„*õ{ú¢gýah“ii}tõÛéâCî¤Jµ?lÅÊð N´ž€ï®†ê ÿÿäój¾cñƒÚŸÏEY¼<,cWÝ.´7µCû›]½]¬®ªªb³“^¯‡Á``Ú {TÏi®¥þü—´D!oNO=!õ‚íííÌ;Z[[q÷î]æïþËå—fcêŸ`m°&?èü¾1¤ áå0rxµßÔ~lJa;˜àLœ…ÛòÿøBÁñ D»˜6>0ÀÎòpuº°äXÂéæÓðº½0U™2üWÀ÷Oø‘oËÇ÷Ÿ}î'½ŽÞí^yyy<ϳóOíHRûªÿ~¿ŸÍb©}KºøÔþª³³“ÍÉ4ß‘fI‹þËçSODûú~ßÑ}ÉÆ¯áwù!ØļÏí[T/  ÍmºžFŸnígŠõì_Ƨ__‡h1Ö=†ÕÑU¼Ýô6ÖklnËð__õksµ]Ÿw!Ç‘ƒ[·àt²y–öÉ©}ÕvºGz+((ØÞŸÐ.šî‘VÒŧv+´_%Ÿhjjb:%=eø/—OuæÊéóçÏÃÒ`I^꼟۱J­çKá­çÆ­}‹X®Öÿé ›¹ʳç#Ejý ÂXaL˜PýŦúK‡ ^‡gZÎÀ;â…T-eø¯€ïWý×®ú離ÿölùoªþ/--±y–æ§”OÐ\E3i‡ž_P/—òëtñ©ÝVGGÓeKKËö~,Ãù|zÞDþK½ôŸˆRÞxœí˜KH[YÆ?L¬yÜ$7ji#¢6&ÑøŠén`¤CéPJ]µ …Ò…;wÝÌŒ 3ºs;0ËnZèD¨3¦µE1Ö“ÄGâ“hb,yÞ›XŒÍÜsZÅÜa 3fu!7'¿ÍýÎ÷ýϹôÕ¥â_ï ñ6M»ùíÚÚÚ099 ¯×‹±±1ÌÌÌ ££CâŸ1ŸpWWW¡ÑhÐ××ãׯâ]Ç]¼›M‡ÜVî£t‚Â9hmZd|¨TÔ?Gé#¨Íjd<ê71}Ú“F¥­þ ?¢î(®_Cl:]—Ä/?µ”Â…/.`âá*^WàÕÂ+ÌÍÎÁf³akk‹úA§Ó!Ó5â·††êŸt: ³Ù ÇCý&¦'ÿ‘ ¸ÝnŒczz]]]¿ü`0H÷soo/LߘŠ÷~¿‡÷Ønü&™Z†r¶ü*]»ij“¾€B²@Ÿ‰u:Q}Ê—BUG|vööp}ô:ö÷ ïÑKüð“Þ$.Ú.âéçPý¡¢û—ø¨»»›››P«Õ`Y–æ8É’õ&“ <Ï#™LÒgâŸÎÎNQ=ññ–ÝnÇÂÂFGG±¸¸ˆžž‰_þÊÊ ôz=̓†/Š·ÝFÂ#ÌÏVa~Žó˜RÈsœÎfŒ•·ÂAQ«À‡ü²(ë•tibDõÙ`¬•Ep*ˆ}ÿ>®_Å뚉_ ~&AuG5?: sÉ`wÚá~ë†ÕjE$R©¤ó™ÍÈñCmm-òù<²Ù,êëëéZSS“¨žä?ùžšš¢Þ†ËåBKK‹Ä?c~ss3ía†aÐßßó·æâýßî#¾‡¾Y.ÎA®–£\]nÛÈ"µ‘‚Ú¨Æñ¡0¿%À¤ÖR`-¬¨>N¢ÚT ¯Ó‹]×.n ßÀîò.*­•¿üÄZ‹O¾æ9ƒ®ÔäÝÇãqšçä³¾¾ŽÆÆFz®"g®ÃÃCšÿƒkkk°X,¢zâÒN§“ú’øsyy™zQâŸ=ggUUUt“þ½õèÖÇþmÖà0rˆ2eÙ?ç?W w)'ù/¦?íç§~ú«_$þÙóOû÷'ä.9ìSBÿ.ºéþý·üç8ŽÞ¥|N¿’~úì~‘øÿÒ¿ä7é_Ë5KñãâËqê©\,#œ§!ÏÃBž›X¤×ÓP5ªpœÿ”ÿ5Bþ¯ ùß$œ—cüßôÉÐ/æjxDæ#¸9r»A¡_Z*EõÿÿåŸôïãïCù\‰—ó/Oó?‹ÑÙ‹|Nzâ$׉Hþ×ÔÔгñ˜> Ñ;‡ÃùùyŒŒŒPÏJü³ç“}Lοä}º Å+£Whf“{Í÷Ñ÷(S”Ñ;’ídóPÔ(èüvÌÓ.àC<½GÓs!ÚF-¶f·%pyà2K 0Fâ—‚¿&ìãfs¿Ì¡Â[ñŸÇá÷ù©§¢Ñ( ÇH¶“5â â2¿‘ü']@l' ß‚aOWF¯àÔv U§Jä—€Ÿô&Qmª†uÒ ‰M‚§/žÂaw ££@€ör•JE×tgg'¶··ÑÐÐ@{2™¤¾ µöövA=™+ä¾°°ÇƒÑÑQØl6Zù_–O¾áû÷ïéš¾uë CáÁüœ¸O éÑ L¡œ)ösV ~›‡¦CƒØN±ÿ·1Èóyš×”MJļ1°]¬ >ºEug5œsNÖ¸>~Í8'òKÀø"¨7ÖãÙOÏÀ¼b°¸¶·Ûžž:†˲Ô#Ä;;;hkk£½žäµ¦¦&x½^tuu ê·¶¶¨ïæææ°¶¶†ññqlnnÂd2‰üðI'ó·»»—¾½T¸óÇDÞE 2©p~x‰B‚ru9Ò{iZã=<äÍräÓyä9(ZHº“Pv+õIW1ÇõpðÌzr†049„ðrê^µÈ/?áL ¦¿/~~Šå ¼|ó¶UõÉq …‚f4âR#3‚ôüt:Mó[kk+]ïÄBz—ËE{Áìì,œN'&''±¼¼ŒÞÞ^‘ÿ…ù„KÖ1™ÇCCChý®µpwþ.>®}kf‘>Hÿï¶è‡Ý4Ôf5®zõO6ž¥³ áHP¿ éãŽ8ªÌUpϸ²‡`™²àxél¿È/?öo µ_ÕbæÑ *ßTâõúk¼ýç-Ìf3¨H?ßÝÝ¥5â7½^OýÇé,p8ÔoBzòŽÜgff`·Û155…¥¥%ô÷÷‹üðÉl&ëùòåË0|o(Ü[¸‡Sû)4Åü¼Ÿ‚„‘@ª‘Ò=kbwÇÁäR9ä¢9úL<Èö±‚ú˜+m¯®i‚ëA\›¸†àFÜ 'òKÀ:£¨3×áù£çPü­ ë—øh``ûûû4i4ÚÇIÿ'½Þ`0 •JÑüFž‰úúúõÄoÄ[ÓÓÓX__ÇÄÄ666088(òKÀ'ùœœW“~ ÿF_¸ýûmDÅül,æç£b“û¹ªœf3¥Q ~‹‡¬Q†‹ó ä’9È[ä´Fλ„ôäüDcÔÀkõ"ìãêØUœ®žBÕ%òKÁOx¨î­Æü¯ó¬J0ýröwvFz®Iþ{ ù‹d3R#~ gçççôü„œ“’Ùk éIÿ'w«ÕJ½766†ÕÕUº_ù_–OöÕd“ó«ááaüÎ:·xœí™ÍOWÅÀ–lfl Qdñƒ 6Å XµQUÉBY ,¢HáoH7m 6ü]t‘D`ÒTJÔ€®ÁÆÛ|cÃÇf°‘qç=⨋ÙâÕ,Јç«ßfΜ{î}®]…þ©~k¬n+dA†ŽÑAÏè!oËà9H;˜g8OŸƒµ³6$pMœj}z+*g"3ð ÇQì·ná8p “Gã—„¯ôëÊöJø÷£ÚÚÚ099 ¯×‹±±1ÌÌÌ ££CâŸ1ŸpWWW¡ÑhÐ××ãׯâ]Ç]¼›M‡ÜVî£t‚Â9hmZd|¨TÔ?Gé#¨Íjd<ê71}Ú“F¥­þ ?¢î(®_Cl:]—Ä/?µ”Â…/.`âá*^WàÕÂ+ÌÍÎÁf³akk‹úA§Ó!Ó5â·††êŸt: ³Ù ÇCý&¦'ÿ‘ ¸ÝnŒczz]]]¿ü`0H÷soo/LߘŠ÷~¿‡÷Ønü&™Z†r¶ü*]»ij“¾€B²@Ÿ‰u:Q}Ê—BUG|vööp}ô:ö÷ ïÑKüð“Þ$.Ú.âéçPý¡¢û—ø¨»»›››P«Õ`Y–æ8É’õ&“ <Ï#™LÒgâŸÎÎNQ=ññ–ÝnÇÂÂFGG±¸¸ˆžž‰_þÊÊ ôz=̓†/Š·ÝFÂ#ÌÏVa~Žó˜RÈsœÎfŒ•·ÂAQ«À‡ü²(ë•tibDõÙ`¬•Ep*ˆ}ÿ>®_Å뚉_ ~&AuG5?: sÉ`wÚá~ë†ÕjE$R©¤ó™ÍÈñCmm-òù<²Ù,êëëéZSS“¨žä?ùžšš¢Þ†ËåBKK‹Ä?c~ss3ía†aÐßßó·æâýßî#¾‡¾Y.ÎA®–£\]nÛÈ"µ‘‚Ú¨Æñ¡0¿%À¤ÖR`-¬¨>N¢ÚT ¯Ó‹]×.n ßÀîò.*­•¿üÄZ‹O¾æ9ƒ®ÔäÝÇãqšçä³¾¾ŽÆÆFz®"g®ÃÃCšÿƒkkk°X,¢zâÒN§“ú’øsyy™zQâŸ=ggUUUt“þ½õèÖÇþmÖà0rˆ2eÙ?ç?W w)'ù/¦?íç§~ú«_$þÙóOû÷'ä.9ìSBÿ.ºéþý·üç8ŽÞ¥|N¿’~úì~‘øÿÒ¿ä7é_Ë5KñãâËqê©\,#œ§!ÏÃBž›X¤×ÓP5ªpœÿ”ÿ5Bþ¯ ùß$œ—cüßôÉÐ/æjxDæ#¸9r»A¡_Z*EõÿÿåŸôïãïCù\‰—ó/Oó?‹ÑÙ‹|Nzâ$׉Hþ×ÔÔгñ˜> Ñ;‡ÃùùyŒŒŒPÏJü³ç“}Lοä}º Å+£Whf“{Í÷Ñ÷(S”Ñ;’ídóPÔ(èüvÌÓ.àC<½GÓs!ÚF-¶f·%pyà2K 0Fâ—‚¿&ìãfs¿Ì¡Â[ñŸÇá÷ù©§¢Ñ( ÇH¶“5â â2¿‘ü']@l' ß‚aOWF¯àÔv U§Jä—€Ÿô&Qmª†uÒ ‰M‚§/žÂaw ££@€ör•JE×tgg'¶··ÑÐÐ@{2™¤¾ µöövA=™+ä¾°°ÇƒÑÑQØl6Zù_–O¾áû÷ïéš¾uë CáÁüœ¸O éÑ L¡œ)ösV ~›‡¦CƒØN±ÿ·1Èóyš×”MJļ1°]¬ >ºEug5œsNÖ¸>~Í8'òKÀø"¨7ÖãÙOÏÀ¼b°¸¶·Ûžž:†˲Ô#Ä;;;hkk£½žäµ¦¦&x½^tuu ê·¶¶¨ïæææ°¶¶†ññqlnnÂd2‰üðI'ó·»»—¾½T¸óÇDÞE 2©p~x‰B‚ru9Ò{iZã=<äÍräÓyä9(ZHº“Pv+õIW1ÇõpðÌzr†049„ðrê^µÈ/?áL ¦¿/~~Šå ¼|ó¶UõÉq …‚f4âR#3‚ôüt:Mó[kk+]ïÄBz—ËE{Áìì,œN'&''±¼¼ŒÞÞ^‘ÿ…ù„KÖ1™ÇCCChý®µpwþ.>®}kf‘>Hÿï¶è‡Ý4Ôf5®zõO6ž¥³ áHP¿ éãŽ8ªÌUpϸ²‡`™²àxél¿È/?öo µ_ÕbæÑ *ßTâõúk¼ýç-Ìf3¨H?ßÝÝ¥5â7½^OýÇé,p8ÔoBzòŽÜgff`·Û155…¥¥%ô÷÷‹üðÉl&ëùòåË0|o(Ü[¸‡Sû)4Åü¼Ÿ‚„‘@ª‘Ò=kbwÇÁäR9ä¢9úL<Èö±‚ú˜+m¯®i‚ëA\›¸†àFÜ 'òKÀ:£¨3×áù£çPü­ ë—øh``ûûû4i4ÚÇIÿ'½Þ`0 •JÑüFž‰úúúõÄoÄ[ÓÓÓX__ÇÄÄ666088(òKÀ'ùœœW“~ ÿF_¸ýûmDÅül,æç£b“û¹ªœf3¥Q ~‹‡¬Q†‹ó ä’9È[ä´Fλ„ôäüDcÔÀkõ"ìãêØUœ®žBÕ%òKÁOx¨î­Æü¯ó¬J0ýröwvFz®Iþ{ ù‹d3R#~ gçççôü„œ“’Ùk éIÿ'w«ÕJ½766†ÕÕUº_ù_–OöÕd“ó«ááaüÎ:·xœí™ÍOWÅÀ–lfl Qdñƒ 6Å XµQUÉBY ,¢HáoH7m 6ü]t‘D`ÒTJÔ€®ÁÆÛ|cÃÇf°‘qç=⨋ÙâÕ,Јç«ßfΜ{î}®]…þ©~k¬n+dA†ŽÑAÏè!oËà9H;˜g8OŸƒµ³6$pMœj}z+*g"3ð ÇQì·ná8p “Gã—„¯ôëÊöJø÷£ïÏCß©Gp*ˆ¸/ŽñìÏîCÛ­•øàç|9œî='?<Á©ÙSp½tá•ûººº°½½ •J­V‹ º ÑÔÔ„B¡€\.£Ñˆ@ €ŽŽQ½ßïGgg'¦¦¦àóù0>>ŽÙÙYtwwKüæîÚÚ4 `üÚX¾å¼…7 o ³ëPØ*|ðƒNðC´­]‹œ?U‹Šúç]öÔf5rÞõ›˜>ëÍ¢Ö^‹ÀdqO—'.#1“€®WâW‚ŸYÎàÌg0y5/kðbñæçæa·Û±µµEý ÓéFéñ[KK õO6›…Ùl†×ë¥~Ó“ÿÈ÷ää$<&&&033ƒÞÞ^‰_~(¢ûùÂ… 0}c*ßþý6<`ûXð›lnnB­VƒeYšã$ÿIÖ›L&ðUâùÂóOùŸH$èìE>Ç=qœëÄ?$ÿèY‹øGL‰Dè‹ÓéÄÂÂFGG©g‰?%þÉóÉ>&ç_ò> }†òű‹4³É½æÛø[T)ªèÉv²ÆGy(t~;âŽhðžÞ£ˆé¹m«[s[HER8?t©å #ñ+Á ûØÊbþ—yÔøj0ñóþõT<‡B¡ óÉv²F|A}„”—â<{ŽóÌ9*4È3¨Ô ëÉ;¹VŽcÏ1’$Z[‘ØM@V/ù¥à2`xÿðBº/ŽïïÁwàC]]"‘¤R)d2NOOiíèè<Ï#›Í"“É@£Ñ  B«Õ ê?½óx<Äîî.êëëE~ ø¡Pr¹=Bûwí…¿?@ÈBUs’É$ÊÙrH‹W"˜_Ç#Š‚©e+^ÙxJ•‘ÃøF^P„QS_낇ˇ¸>tïÞCÓ¢ù%àŸúOQßPÇ?=;ÇâåòKø|>477S=˲ ?â‘O~¨­­¥µx<•J…ÃÃC466 ê‰'‰°¼¼Œ¡¡! ¥¥Eä—€OÖqUUýžº/u…¿Ü@ÄÛÎ"ãÏ@"“@¢” ã+öq#ƒÔV ²ò™<ò‰G.žƒB¯@™ÛÉ êŽbŽëâášv!hb`|¡¥TÝ*‘_~ÜGMo žÿøKxñúÖVÖ¨HŽS(4£™¤ç§Óišßôz=]ïÄBz‡ÃA{Áôô4ìv;ÆÇDZ´´„îîn‘ÿ™ù„KÖ1™ßУ/Ü™½ƒ«ÀY8¤÷Óÿú+úa' •E…¸#…NAý“eé,ˆÛâÔoBú˜-†*KœSN­A N âhñ\¯È/?úwµ_Ôbêá*_WâÕú+¼ùë , ö÷÷©H?ßÙÙ¡5â7NGý‹Åè,°ÙlÔoBzòŽÜ§¦¦`µZ111ÅÅEôööŠüðÉl&ëùâÅ‹0|k(Ü¿‹ë Ô}Åü¼—‚„‘@ª–Ò=gæsÆÀäR9ä"9úL<Èõp‚ú¨# M·ŽIë\»‚ÀF|?/òKÀØ#ÐZ´xöð*èú%>êëëÃÞÞÍcjµšöqÒÿI¯7 H¥R4¿‘g⟞žA=ññÖää$Ö××166† ô÷÷‹üðI>'çÕ¤è¾Ònýz a[1?›Šùù°˜ÇäÅ~®,§ÙŒ5±Hz“5Êp~vŽ\"y‹œÖÈy—žœŸ¨Mj¸çÜ9C¸·xœí™ÍOWÅÀ–lfl Qdñƒ 6Å XµQUÉBY ,¢HáoH7m 6ü]t‘D`ÒTJÔ€®ÁÆÛ|cÃÇf°‘qç=⨋ÙâÕ,Јç«ßfΜ{î}®]…þ©~k¬n+dA†ŽÑAÏè!oËà9H;˜g8OŸƒµ³6$pMœj}z+*g"3ð ÇQì·ná8p “Gã—„¯ôëÊöJø÷£á®¬¬@¡P ¯¯_7oZnb×¾ •I…ÜFî½Tœ9(MJ¤ÝiÈdT?oSo!×Ë‘v¦©ÞøêSÎ*M•ðŒ{qDpaì¢ÓQ¨º~)øÉÅ$N|qã÷ÆQñ¼ÏæŸanv&“ T*• @€ž½544Pý¤R)èõz8Nª7¾zòŽ|Ãáp`ll ÓÓÓèîîø%àû|>ÚÏgÏž…î]ñÖï·°ãØºGìz"¹åêrdW²Pu¨ò¤ ×ÉQÈPHè3Ñ ªKÅ[Ÿt'QÕY·Ù­ù-\¹ˆ­…-hz5¿ü„+“¦“xtïdÈhÿõôô`}}r¹jµšú8ñâõ:Ùl‰D‚>ýtuuñÖ½m™ÍfÌÏÏcdd èííø%à///C£ÑP?hø²¡xýþuÄÜüläæç7I9?WˆélưË,$µ¼Ë¿C!S€´^JϘf†·>ãË@mTÃ7éögç‡ÎcǶE«À/?íM£º³–-ÙD0[Íp¼tÀh4" A*•Òù‹ÌfäŒè¡¶¶ù|™Lõõõô¬¹¹™·žø?ùžœœ¤Ú‚ÍfCkk«À?b~KK Ía†apõêUè¿Õoÿv±å4-°1b¹åòr°k,ÔMj$ƒIÈåØßãæ·Ä[0ZÉÕ$Ô5o}"@µ®.« a[—†.!¼F¥±Rà—€_CkÐâá÷ÁþG>é_Â'ýû9ù¤Éý—üŸÚmñÜÈ9êÙd¯ù&òe’2º!ÞNβ,$5:¿í³û4 ²þ,Ý£ðÕ³~JÁ© v—wqfà ^/¼c`>¿I‰Ù Äýqœî?øb\àðW¹>nQcî—9T¸*0ö󯌌À`0Àï÷Ãëõ"..ÃÃÃHJJŠˆ_ëèè€ÙlFyy9zzz’’òÿðz½Á`“““Ðjµ¼ö4ü÷á·X,ˆ‰‰Á§Ÿ~мŸå…Þÿò}X,ˆM‹…Óé„L-ƒ\|:†0$`¶B¬Æ”øœ´OB£ÕÀ:d…>U—Ó©Z …ø ãm„Dñ99!Ö¯Ó2ÞjˆÌ?"ò'©ï·û™|`†4ó?‰7#!%Æ+F Õ aÕ¶UìD\z\DþGë ó?­žéÎßt)3Sðù>‡ºZ‹u100€´´4Æ«ÕjЃz$܉‰‰¼f·Û¹ß†††ššO=O½~åÊÔÕÕaÛ¶mèïïGzzúsÉÖÞ³ò?ZÏÄÄt:Ý3ãÃüƒƒƒ˜5kVD<é866–ÿž?ʽù×7am5”§†×ä…T)…T#…wÀ U® ¾3¸˜rMA™ª„³Ó M¡†÷zH™Vß B¾W— Ê™JLy§p“ÃkB®Àüä¤yO¿‡ïéîv³÷~Ê!ò§+áë€Ïìƒ4FÊxª‡øNèòuè¨é€¥Í‚—¶¿„±†1hò5ÿSÿ“õ0šò±zžÄOw~G»ñÅñ¨Þ[ iƒÇ¿:ŽFc#òòò`2™x/×h4¬éüü|tuuaæÌ™¼÷;î ZËÍ͈'ߢךš´µµaûöíhhhàµç‰Ÿ4”““ƒîînÖ»Ûíf=…ùéé’¼4÷d=ç1ü£õ& OkwîÜam‡ë§}„Ö233Y³ÄÆÓßꡟW¯^ìòìкsë0Ú: ýÑOꢧ â~®“ÃÞaGbA"î|} K “ÈàõB—®ƒ«Wì©L±ú\œÕ¢äQ˜è˜€¡@ô‹;¢_ä˜rŠ~mýz–¶vt…âçL.ÖºR£„gÐý,=,¨ ÔŒ÷ÛüRtŸíFÞOó`7Û!$Pèpv9¡ÏÓÃÚiE|~<šÎ6ÁToÂë»_‡©ÅC±á±úÃøG롼©ž¥þo=ðÓ¼cÉÉ8ñ». ¸R­­­˜3g{ ì ÔSÔÔ+Ô‹Ôk”×hßoooGaaaD|gg'÷éÙ³gQ__Ý»w£¥¥ÅÅÅÏ?é¼  €¹²³³pïÞ=ÖcøšÍfƒB¡€J¥z¦zH¿¤GòOÊìYYYìýÄér¹˜´|ëÖ-,X°€÷ÚK­Ÿ>GŸ/**BæòÌÐÛã7Ç¡)Ö°'JURþÙCènéFõ¦j¼Wû¦ÜS%Ëpé·—ÐUÓÅž÷ó<,Û² 2—¨ËÙ¢¦;]칄 ØPe©àhu@]¨†oȇ¨è(xÅgou/úû  ¨ðêǯÂ5ìâÕépøÇ‡‘¶" +6¬À¤w’ÏÓî7×èhsâÚδa¸ie{Ë`©µ@;Wû°~Ú#Âxg›3r=EêˆøéÎoo²#¡4_íø ŠZÎ_;†ë ÜŸÔ+ÔkäÔ´FDýCþBùzŠôNý ßÜÜÌ{Á™3gÐÔÔ„½{÷¢¶¶sçÎ}nøIÔS£¢¢°~ýz9r„uGþXRR‚k×®qæ=qâgÚ7Þxƒ5Jÿ¯Ò/é‘> …pûömŒ±.·lÙÂ{iž<™øÖ­[‡Å‹3©~ª›ð¤é²²2d½˜ª8W{õ÷ +ÑÁÝçF”" št š6á‹­_`Ñ/¡ìP<1ô9qìWÇ`í·¢huäÑr4~Ö¹LŽŠSH-OÅxÃ8„,ûÍ?ágï°ß¶C¿@ÑÛ£8²ôŸåÂÙ g£¢¶ö>;çmC©M5¡jS­Y„Wþü |~¼}^hK´˜hœ@lI,Z«Z1lFùrŒ\®ôAýÜÏ:±Ÿïºoo¶C•¡z¼žF;ë%~ºóÛnÛ¸0U[«}-ßÜøßýó;¾>îOÚÏïÞ½ËkÔÏÜ't^#ïhllä^Œ„§kôZUU£ÑˆàêÕ«(--}.ø)ß’Æ(_¯Y³ .ÄåË—YÏäÓûöícý†6là5Êà䙑ê!­?i|Ó¦MŒ ?¨ÊtoÚè~„9xð gÒ1ÍÂè:a‰ƒö£^xÙ¯d‡Þ­ycÆ1èç‹ù¹Ç© …2Q‰g|}¦Ç* I3lŒ§VžBË—-Xüîb¬úË*xÜ|»÷[\Ü}+ °öÔZŒ5A«FÀà<¬ÎVsOÅ•ÆÁl4£æ75(üE!çíÚj‘¿<k¯®…ÝbGÐDLv ‚¦ .ᅩºuøà_ >;¶fô%z~›‡æÓÍ0ß0ãµ=¯Á|Ë ÃçzªŸüšÎˆºb&Z' d |~Xüž4¤›§‹ˆŸîüÖ&+’J’pjë)¨¾V±~©OçÏŸÞÞ^öšÒ>N~DÞ@ùòå=zO=>oÞ¼ˆxêOÒÆéÓ§qãÆ ìÙ³çaÞ{ø£££ù¼K¿/òË .°w’gžÔh¸òRÊÃô>|t»téRžyÓlºººšuH³4šc‘~ OuоpþüyöeÒ+evª›ò?ù1ñeü$#´æok0Þ(æç Üýn¨SÔ0ž4âÒï/á­£o!19­^§Ÿ,û ­ï~±ócáêÏ_*>{û3Øúl¨¼P •Ti¬˜¿}¡ó«ôžw y|&”ñJh3µ¨ÿS=Îýñr—äbåÑ•pšœºƒ<Ÿñôx ‰—àТCÈy)+?^ k»Ú"-Ïgôz´W·ÃÒjÁË»^ÆØõ1ž§y†<<ï’idæc⹚îM3· 'øX=4;‹„Ÿîüö6;âçÆóïVz]ŠÓçOÃxÓÈçµð¼…òeEZ£~ 3Í[ÂóZ£³V$<íÿôJ½G½ºk×.\¿~ýa>œÎü4#š1cn޼ɾ·ÿ~,Y²„5Mç_Ò#gé=äÙ›7ofQþ çò§ÕC31úí-äûtoâ?zô(ŸÉ³‰Ÿpä¹”‘+++yFNüt& Aó+ÊØÿu…·xœÕYyP”w}ƒÀœ\"Šr+(‰Çª¨‰$³DYK£ÙP®I¬5e¼ãmWe×sQwS庫ѸKN±2xr rà­ §s‡Ùé6c²†*ÿž¢¨©ú¾ž÷kø^÷{Ý_`\ ))# íõí…È`h3ÀAê€ãŽÃÐlÀúöõÐ=ÐÁu¤+ªrªðÝÜïô~Ž'Àq¨#Lj†Š¶" '*0ÿü|„Ï $€©Ç„¾Î>ˆ¼DP7ª! ’Aߦ‡ƒ $.¦"}M:B§‡âù'Ðè50ꌯR¨àê‰S‚â¿ ¬nZAæá0!Ô÷ÔppGev%”EJÄR¡„k¨+ôízØ í!  ¿¯‡Ì_õ5„#…0ö›Ïñ÷:­_Õ¨‚WÎo=Q®ò"9êëë‚ööv…Bþ½ÿ>üýýñàÁŒ9===èìì„——4`ü½{÷€ììlaÇŽP( µzüÖÖV <sçÎE^^z{{ñôéS >œñÕj5† ¸¹¹¹X²d vïÞM›6¡¡¡ÁÁÁoÌÇÉÉ b±ÀÚµk1}útÈårèõzèt:Ž·Ëo²Ÿ)ñL"T*ˆBD0>7BõT…Ó‰§0= Ï,DGIÜÆ¸¡àï¸qàÆ|43V΀í`[ô<íáú-ü¶ùËGÔÒ(Ä,ÉÉS¯ /ô/àäã½BÏø=M=°Ø@4\„òc帲ÿ ‚&˜ûÁ¹è”:ôw÷s¼®F÷hw.Àµ}×0wÏ\„L ­§- ¸„º 6«m5m˜µsÚoµC¯ÇëêtÖ_kþßqGÆî Øß²ÇW~ÀíÒÛ5jšššàèèÈüyüø1s–¸âííîînæó™ø3P|]]fee¡¦¦;wîÄ­[·0zôh«Æ§k\'óæÍÃÛo¿´´4ܹs‡ë—ð©¾è,Š»yó&¾þúk|ñÅX³f ªªªöùP¼¯¯ï«|¨8880Þ±cǰÿ~L˜0ç΃R©äïPþ”Wtt4öîÝ‹£GâÈ‘#;v,÷êô÷|ðÁ˜`Z–³ eD˜ES”ý³ Ù²1mÛ4ÌÙ>ÍeÍpçŽËŸ_FYjfþe&¢FÃn˜ºîwA¯Çk*4V¯.7×o´'ÒÖ¥Áñº#n–ßDa~!söáÇÌgzþwïÞåk•••ðóóCWW4 ™³Äõâé}’6/SRRX‹"##­?<<œknß¾}8|ø0’¿%m¦z´àÓY¤•ä¯I{7lØÀõK=€ê÷MùPýÒý={ö`ûöí˜ÅS^Ô¯èlòÐ111¬×¤å¤ïR©S¦L_ŒŸiÑ…EPÝ6ûç`sývÛâæ!óó>Yˆw¶¾ƒÉk&£-¿ýsî®\”ž(ÅÔµSýûhö²ÝOºÙ?Ÿ.FÞ®<„/ Ǭ5³`þ쟵/˜{äéÄ£ÄOó¯ØGŒ²ƒeÈIÎAÐÄ ,¸´º§fÿÜÕÏñÚ-\"\ÐTÒ„Óñ§á;ÉóSæCà-`ïè2Úì?ÓkÑZÕŠÙɳўßI¸„ñml!˜Ûâ01ûU§á?ûÏòy=žÏ¶b|M•‘Hß–A¡YyY(-)eÿIºAó—D"a.‘ߣ~nñ‡Z­–¹U[[Ë~{ xòv„•žžÎZC:’ŸŸÏü·f|òÏ„qèÐ!œüχÐ+õèïé‡Óˆ—ñä1ë³ëùÌÈ‘ˆù<¶¶0Ü5ð®¼.»mµm˜¹m&:Š; 3þ«}yƒÏ…ŽÃy7Æù˜ñéš(H4`Ë>‡´€®?‡ öjÿCúB׈ëÅ[v1´¿%~mÛ¶ë€ødÍøO5G¾š¼3Õ.i0ùb´àÓYT¿¤Ùtÿ³Ï>ÃêÕ«Q]]Í5G}bèСŒeÙ§Yzå#XŸSSS¹†Ç3gμÚ_ÑY”#i9Õ5åAüå—_ònœê—zRBBbLI™Ih¯1ëo˜½Ï{¡mÕâHøøÆøbEÞ t4˜¹,ÆOúŸâ™£Ñzç4âÝÐ5›=¯©©R¡kÒá«g_AÐ%€ÀK€^U/¿ïK¡Uh! •òû&š×¤2) R ^é/¿?Òix^&}QU›5$Ü 9»sØ$þˆ€IpìM½î!fýʨ„²X‰ø]ñPV+áîÂøü>EúrŸ# 6ë×]5÷&ÚñûsïPשÙo ßYßiÕøôîÍ+Ô¬¿›Íú{õ¥þZô…v$ô.…æ'‹®Ð\H3qö7– qq xË»ŒŒ æý®]»˜»äo­Ÿ¾OxTSqqqcùᓞR}‘Ž^½zK—.eýÞ²eË+ K>T'„çîîÎ}‚<;Õ(ùgîëׯǴiÓx–~þü9Ï¿„oÁ¢9œüù©S§8¢ý3é/áýªªXÞxœíX{LTwþ`æÍÌðPTD@`x ¾³­®ÝFKe›•ªk»jŒ†nÿÐhºîn4º>’Æ>l³šv-©šÆT­‚Ïå± DáíÌ0o``öžcÆ6î´ë»ÉÒôÎsó»çž{æÎ÷ï;¿Ø¹±ÞwξS™ ª4œ-NÈÂd8ù»“h×·ccÝFxŒ ‚T!Eáï ¡¿¤GÆ[Xr| ÜF7î|z7ß¿‰”Å)È>ž¾ê>8]Näÿ!ö.;2ßÏDlZ,‚ÆÁÝæ†7À e´WàòþËÐÍÒ!ûT6lOlÀ ˆWÀZeEè´Päþ:Æ#Þ-}pòD9l´iZÔœ¯A‡¾‹ö/B×í.„¤‡ÀÕâ‚H.BPHœœPMRÁ^c‡,Z†!ç¢óÓµÖÖV(•JdggÃl6óõ††DEEq~—ËÅyÛÛÛQTT„õë×cÇŽصkÊËË‘˜˜ÈÏ Ä¡C‡ÐÓÓƒM›6!""‚k¤ûÂÃË}ûöaçΘ7o®]»†'Ožpü¸qãP]]™3gbÕªU¸pá®_¿Ž   þm>„J¥Â¢E‹· λªpzïõB¡†£ÉE¤M÷›ðÕo¾BÖ'YHýU*†¤Cð`À:€ü-ùhù¶Ú±Zˆ$"ô6÷"")Kÿ¶a3ÂàlpÂÔe±EÇ@ǽ”y)L £¬Ÿ/ø?tÌÝ>ówχåŸ8œ82û^Ùü î^ˆÞò^h¦jÐWهЌPò è¨è@æ¡Lt^ï„zŠÎÇÎgxV xnt"$#„{~a¼wÍ7kÐSÑÃÜp‘ÄW!‰‘À\kFùßËsƒO!+ƒ«Ý…àð`ô›û1ñµ‰Ðeéàzââ>Qwªﵿy„ÖZ+4éXª,KCU^ÚKÛ‘µ/ íåíÐNÓÂÑì€H!‚X#†ãêIjôúXÓ=yòd¿ñÄâa»´´”u„°5mÚ´ŸŸ4š¸Ê÷ž8q‚9Àš{ðàAÖy­VË<öx<¬·8|ø0¿gª#''·nÝBnn.sšz ÕµvíZH$ ,, ‹…{õ‚Í›7cݺuÜ Ž=ʺNœ÷ÕM}§¾¾žŸMý&fvŒwÅ—+`ªüs²Šým€$Òp)ºËº‘»&Q Qx»àm¸»ÝðØ=PÆ+1Ð:eŠàßZŸù·á€aØÚ¡Jü›ÁŠð)á0VñÅâ/°òìJhC´ìŸ;ý«xî÷”iÊçþpØ-ähr$¨P´½%_– ë¯YÐeêàñzÐßÖe²¶Z4ÉÔ^¬E—¡ ¯íz =%=P¥¨àjê‘ z¤ boIñÔO¤QR »„wmó@6AÆkJÒoüHÏo­Þz8 ÷BT"BÞ¥wáÂ…Ì_ª/22’5wôèÑ\õ zf]]×ìv»™·Ôˆ»{öìÁêÕ«Y“ûûûa4‘””ÄzÌ’%KŸï]W¸ݵÝФúÛá@2"•žNLfÎ,=ƒ5w×@&‘1‡•QJ˜ fhÒ„x£ƒù¬ †ã¡ÐÿÔ°6[Œ£¿8 iˆ9·r`y`Z§æüÒ@ˆµbØëìŒcK½ŠDcÓÓç6Z‹#ó cM¦¾5•k—h$°5sc¢æ3ÂῨçÙøÍÝoÂh0òLé«_¬ÃöPˆOÐÂÒhaÍ"¯@B5NKPO²ÚoüHÏoª7aLÒœúÓ)(¯(Qt¯ˆ1KX! ÒOø!|‘×$<fÈ’nv S„Oñ4ÒœGø'ÜïÞ½›ñL3åO)?Í¢W®\aMç^¯ÝÝÝìƒÉÓLœòé;õ ¿¨žåË—³/'ÎúžMù©Ÿ|?žê¡kv»ë'/>cÆ LŸ>µžžK~ÙW7õ òôûâæÅyWæ­„©ÜÄÚé~âfÿLúèht üÕpôü£Ò±R ŸAËàwû'ßÓ_Šw5»ž­5¹Ð?ÜÚSµHÿm:BŸÍd´?æný.?ǧ úR+èïx†\CÌai´ær3ÆÌKµ…ýá÷ãyÿ*U C÷^?ðúóýŸÿ˜ÿ…ýñ#=¿µÚŠˆÉøúÏ_C|[ŒË·.£ô^)ãöH?„ò–´FÜ&L’~½¸ÿCû9/Æû®°·;pàÀóý%ñ#5SSfÏž“'O²'&]&~ùòS?|ñ}ÒÝGžzûöí¼wE³/ùtßþØÕOþø{îÜ9¬X±‚{=—ôÝOsõÒö¨™QÞÌ3™'äÇh?Y$A¤1—å r¸¹˜¿§Cö!öºövÖÌçñ‚^–:Ïaò rˆ%‚&´ÚØû9?/\“Ž“2>}ùi/F#Egÿ¿Å“wT'ªÑX܈Þú^ÌÚ2 OËžB™¤|éü?VÿˆÏ/øšÐÔPT I…Ÿÿ úJ=ûIÒ ©TÊÿ?a‰Ö¨¯“f~H?„êõþâ}Þ”fA:ß²e ï·–ü·òÓµâââÿYþ—­Ÿt”<õ¨Q£x¾~™üTñ‘ÖÉ“oöiçËÖOK9è~Ÿÿ§xÊá›ÑiNïnÿ|ü|ü|ü_ÿžÅ³`ðð.Õ ¤Ö®Õ6ÕÕÕÕ&Õ(1v.Ö2ªÖ=RS&Ö¼:ׂh‚𻃾ÖHH<µ ë x Û[•[•[•£h < Ì(zW(zW*W_B â  ñ¦‘ 'ä,e2À7U=ÖB1HÆMGS¢X7^ÚdBn~wJ~rƒìˆCŽk“å˜<žf£å¨<®›³Ý½¿ÉOpenImageIO 1.3.5dev : ../../oiiotool/oiiotool ../../../../..//oiio-images/grid.tif --fit 360x240 -d uint8 -o fit.tifg.tif2013:10:17 15:06:22AuOpenImageIO 1.3.5dev : ../../oiiotool/oiiotool ../../../../..//oiio-images/grid.tif --fit 360x240 -d uint8 -o fit.tif openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/ref/flop.tif0000644000175000017500000001621612271062644022435 0ustar mfvmfvII*ê@ð( òú1IN2˜=SH¼$ˆ»ƒ7¬OpenImageIO 1.2.0 : ../../oiiotool/oiiotool image.tif --flop -o flop.tif2013:04:18 11:09:45A‰OpenImageIO 1.2.0 : oiiotool --pattern constant:color=.5,.5,.5 320x240 3 -d uint8 --text:x=90:color=.05,.05,.4:size=50 image -o image.tifAHOpenImageIO 1.2.0 : ../../oiiotool/oiiotool image.tif --flop -o flop.tif 32 1 2 1 5 € @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶@K¦S9¤Öm7œNgS¹äö}? PhPé…G¤RiTºe6O¨TjZ•V­W¬VkUºåv½UªWìV;%–Íg´ZmS{ ®Ýo¸\nW;¥Öwm»^oW»åöý¯^0<& ‡ÄbbØ,V7ÈdrUÌfO-—ÌfsY¹W9ŸÐhtZ<~{I§ÔjuZ»›Y¯Ølv[;di·Ünw[¸Î»y¿àpxZM÷Çärpœ^W7ÏèY9§W­×£tû¾çw½'íwü^?'–_¶óz}^¿g‡Ùïø|x>ï—×í÷Õ}?¿ç÷&ý?Ð ¯Ð ÁJÓAPlªÐd! ªƒ BÐÌ5 ¥°Ä9Ä 9DQ,M¡q$QÅ‘ € @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶@K¦S9¤Öm7œNgS¹äö}? PhPé…G¤RiTºe6O¨TjZ•V­W¬VkUºåv½UªWìV;%–Íg´ZmS{ ®Ýo¸\nW;¥Öwm»^oW»åöý¯^0<& ‡ÄbbØ,V7ÈdrUÌfO-—ÌfsY¹W9ŸÐhtZ<~{I§ÔjuZ»›Y¯Ølv[;di·Ünw[¸Î»y¿àpxZM÷Çärpœ^W7ÏèY9§W­×£tû¾çw½'íwü^?'–_¶óz}^¿g‡Ùïø|x>ï—×í÷Õ}?¿ç÷&ý?Ð ¯Ð ÁJÓAPlªÐd! ªƒ BÐÌ5 ¥°Ä9Ä 9DQ,M¡q$QÅ‘ € @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶@K¦S9¤Öm7œNgS¹äö}? PhPé…G¤RiTºe6O¨TjZ•V­W¬VkUºåv½UªWìV;%–Íg´ZmS{ ®Ýo¸\nW;¥Öwm»^oW»åöý¯^0<& ‡ÄbbØ,V7ÈdrUÌfO-—ÌfsY¹W9ŸÐhtZ<~{I§ÔjuZ»›Y¯Ølv[;di·Ünw[¸Î»y¿àpxZM÷Çärpœ^W7ÏèY9§W­×£tû¾çw½'íwü^?'–_¶óz}^¿g‡Ùïø|x>ï—×í÷Õ}?¿ç÷&ý?Ð ¤iÌ„c˜5­ð¾Ð,ƒÁ0\ ´Áм4õÂPD ¬ðÌA¼Pì)Ä‹EÅŽ¼LƒB±j¿ÆQ¬m¥‘¤qÇ‘ê7GÒ …!¡H€ @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶@K¦S9¤Öm7œNgS¹äö}? PhPé…G¤CÞO'ëq¸øo·ß÷{õìö~ÁA@ H$ˆAQ(  ÈÔÊgcÎú‡Îa¨]EðØl=ÜÎgÛÑéY‚YÀa€ÀN'ˆÄ`p6vû}¿ï{³¥Òû{½ßÏÚÈ$¯0€Pàp ¥j@RÇòÈd=‡Ö4 FC ^( r¹_[žÏ"ÿC;­å‡F£\ÐîP´Z Jz=8¶Œ¶[ Ò|^?$R‹åôzf—ËùŽÇz3ÙïWóû‘;°XÜn5HêÖ¶­ëŠæ‚§iö\‹f¸"À°,ˆ¢(ÂÉ©¼oÉrx*çò4@ P²HR€à;V²e±lwŸïº…`Pˆ"ïÈmG¹jZïª@HŒ# sº€Ë¬ì;N’/ ;îËÕ-ËŠCÏ.Ì 6xž'áZVÊ¡ø‚¬ ;ƒ`Ø qxz¾Ž õ Ùð‚‚`˜(Š ¤ÎÚ ¹GÀ|–e™Ü}GûPDp±ÊYû Ÿ&‰¢zÔ@@%‰`‚È¥†©ª{A‡‚ À8X0ÄèU@ BugÚö}T–!ö„PàÈ2èìÈ~% ŠÈ†a˜À\jO†1ŒyŸÁüßBPS ¿Àp¾¬’óqt¡þ=|Ñp:oE ”dŃá$¿„á˜j ¥Ÿ…)JvD48% @€4 C(´R¶:à¦,‘à€²,‚…YVvŸ‡áþÀP€ À( ;!×y„aF z±Â€  SnzIŸeDvF§ü*¡hMF±¬{²uø°,KHÙx^51ë7‰‚`"…âAPvžg™úÏLÉü€@ž'‚HYØveQTvîÈF ÊØ.‡qœjm…ñÜ‹ÐÎûqÛº¢˜¦ E¹â3JÅq\wO@ (ºàžuÏ#yK¿¯ð€r;|=ç˜Bèº ÓËJEæ¹®{†¡¨ݳÆM“gMD. €«p¡ÖV$vrˆ.Jê¡ËqõË^¸ éÄ;€É}ŸjIÈ}ߊ‚e™g¦~yY¾ +ÝõˆëØ?žÚjvNÑçæRAZKF&Ø `;†èÝ •XÚɘ¡<åž™9ãÂ8s-ðÞÀÊ>"#4fA€0‘ ¡´  2†Pôc¸§ÎM™Kë~Q"bbA8f#üN ÁÓB¨Ujà’‘È9È©#µ>VÞ­q EàÈ€h Œ$ØDÑÔ½CaÀD€B@ÊCr00ñÄDZŒ#JøŠ/Q#äêäÒ?Cø“#ä~FJd€=Ôˆï5\+¶Y‡dWA !€õ0Èë)G($€ JUª²Àô€å¸#¼cˆQö]H²%#H¼À}šJÌX‹$æ4É#­²ªyZ%Y2–JÔç ¤ßHã) ¡4‚`L¬ D—“1R(9rúeÙâ˜DVu‘IÛ#%쎙SÍÆL‰é=È £c¬u.àÊ@²žŽÄ¹ˆ=Ô³VzÑ›1ŽÐ@É=cª4€0̨TŒl`·ñöš“ ýƒ«”úŸgV‹@ë¦Ð:@4|$3¾_σM¦„Ÿí„OjyOÈ\‰ãÔÀȺƒp•1ޤ° IJïBHs£èORˆü$´¨3po§<Ä"ÔЈÖB]Yªi)4úµVÔœ9Þé=ªÐ¢¥¾šaYÝQ25NªŸª¯XH àÑ¡ŠTÍS»(øöò®?gèüCˆ|‘²=×y? €úëX§e8´3¢_*Ñ[mA@­–¦Öw`&DÈéx3þŒ‘¦Sá Còƒ[0Ëmh]¤žDmÐ QŠ<Ïõ[òÞZ@Zop®} ÖˆšÚ{[uɽ«»l•Áñ‡u/ÁX+Iâ2Ê[HMä¦q 1ß`€8T “š¬ÝBE%Å ´ïxì!‹£N­Ò"wX•`K¹ÉUÚÁ,‘ ¡t<˜ÓÀì€ÕälùI$$„˜0I劳¹²ÞÀH«†Háxñ…ƒÕš9ñ605–û< ƒ1Á!ÁXçgþ&„Ðé_Ax/\Œö. Œ¡Œ1ÐèÖGãhœçØ1 -W1.3$C¸wÁ>'ÇQ‚ ážàS[¡Xñ®4Ìñ4ãÜÜGñÞoÎD4_‹ñâ3†põš³_À…9©‘BÈw ±¶>1n/$L¦8cBIœ¥oŒ¡Ä8ÕŒ€.žkÓ8 fÜç§È¶qÔŠñ^;H)ߨK$Q§ÓE[‹±?ðŽœKŒîæD´U”F6é5€•þ$KN7'@FeÍZse錧‰f7Ô{L…j-¨ãPŽG`?#’h®>u2“R¶pŸÍzúY+‚f È‚ðÁû9¯$AwŒAˆ<³ÃDª  åÈ*>”€=]µr?­Î$Þ3oé½™¶aÚ[ÿMm~,Q"?‰œSŽÅމírŸG‘˜— ¢øHÒŸñGÌ¿ôî]惦À;Á ºÆªUNªUZ­UéUôʹeŸ€FðܔЗh‘O³+ŒmŽé|cš8¯áö›hq®½µºóâô^Œ=ÈAÕ°@ªG@Ýóv˃ðpŽó, éÄ`Ú\‰ÖÓb6„_V!T/ I|H 'ùÀãry\¾g7 çtz]>§V3Èëv{]¾æû±Ýðx|^<÷Éçôz}Wï7¯Ýïø|lß—×í÷üP~ŸŸç÷üÿ¡¯ÜÀ+ã@ÐL»PD‹‡BP¬- µ¤1 Ãë/ CÑ E°QIÅJôèEQl]®‘4aÆ‘ªFÑÌu£‘ÄyÈ ‘HR,#¢H€ @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶@K¦S9¤Öm7œNgS¹äö}? PhPé…G¤RiTºe6O¨TjZ•V­W¬VkUºåv½UªWìV;%–Íg´ZmS{ ®Ýo¸\nW;¥Öwm»^oW»åöý¯^0<& ‡ÄbbØ,V7ÈdrUÌfO-—ÌfsY¹W9ŸÐhtZ<~{I§ÔjuZ»›Y¯Ølv[;di·Ünw[¸Î»y¿àpxZM÷Çärpœ^W7ÏèY9§W­×£tû¾çw½'íwü^?'–_¶óz}^¿g‡Ùïø|x>ï—×í÷Õ}?¿ç÷&ý?Ð ¯Ð ÁJÓAPlªÐd! ªƒ BÐÌ5 ¥°Ä9Ä 9DQ,M¡q$QÅ‘ € @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶@K¦S9¤Öm7œNgS¹äö}? PhPé…G¤RiTºe6O¨TjZ•V­W¬VkUºåv½UªWìV;%–Íg´ZmS{ ®Ýo¸\nW;¥Öwm»^oW»åöý¯^0<& ‡ÄbbØ,V7ÈdrUÌfO-—ÌfsY¹W9ŸÐhtZ<~{I§ÔjuZ»›Y¯Ølv[;di·Ünw[¸Î»y¿àpxZM÷Çärpœ^W7ÏèY9§W­×£tû¾çw½'íwü^?'–_¶óz}^¿g‡Ùïø|x>ï—×í÷Õ}?¿ç÷&ý?Ð ¯Ð ÁJÓAPlªÐd! ªƒ BÐÌ5 ¥°Ä9Ä 9DQ,M¡q$QÅ‘ € @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'”JeR¹d¶@K¦S9¤Öm7œNgS¹äö}? PhPé…G¤RiTºe6O¨TjZ•V­W¬VkUºåv½UªWìV;%–Íg´ZmS{ ®Ýo¸\nW;¥Öwm»^oW»åöý¯^0<& ‡ÄbbØ,V7ÈdrUÌfO-—ÌfsY¹W9ŸÐhtZ<~{I§ÔjuZ»›Y¯Ølv[;di·Ünw[¸Î»y¿àpxZM÷Çärp@ðä  êÔÜ1I02z=S*¼$j»ƒ7Ž[[x÷ }[[æ¬bÚÑN©OpenImageIO 1.2.0 : ../../oiiotool/oiiotool image.tif --flop -o flop.tif2013:04:18 11:09:45A‰OpenImageIO 1.2.0 : oiiotool --pattern constant:color=.5,.5,.5 320x240 3 -d uint8 --text:x=90:color=.05,.05,.4:size=50 image -o image.tifAHOpenImageIO 1.2.0 : ../../oiiotool/oiiotool image.tif --flop -o flop.tif 32 1 2 1 5 openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/ref/premult.exr0000644000175000017500000000452312271062644023177 0ustar mfvmfvv/1Exif:ImageHistorystring ../../oiiotool/oiiotool --pattern constant:color=.1,.1,.1,1 100x100 4 --fill:color=.2,.2,.2,.5 30x30+50+50 -d half -o premulttarget.exr ../../oiiotool/oiiotool premulttarget.exr --unpremult -o unpremult.exr ../../oiiotool/oiiotool unpremult.exr --premult -o premult.exrSoftwarestringROpenImageIO 1.2.0 : ../../oiiotool/oiiotool unpremult.exr --premult -o premult.exrcapDatestring2013:04:12 17:50:00channelschlistIABGRcompressioncompressiondataWindowbox2iccdisplayWindowbox2icclineOrderlineOrderpixelAspectRatiofloat€?screenWindowCenterv2fscreenWindowWidthfloat€?9 Û¬ê+üÉxœíÓÁiДLVz͸¹w²B'ø7Á Ï·èã1’×òÚ»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›~¿'|ý=!î§¾lÿàsùÜünþ7ÿ€›ÀÍ?àæpó¸ùÜünþ7ÿ€›ÀÍ?àö¢åÂCÉxœíÓÁiДLVz͸¹w²B'ø7Á Ï·èã1’×òÚ»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›~¿'|ý=!î§¾lÿàsùÜünþ7ÿ€›ÀÍ?àæpó¸ùÜünþ7ÿ€›ÀÍ?àö¢åÂC ÉxœíÓÁiДLVz͸¹w²B'ø7Á Ï·èã1’×òÚ»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›~¿'|ý=!î§¾lÿàsùÜünþ7ÿ€›ÀÍ?àæpó¸ùÜünþ7ÿ€›ÀÍ?àö¢åÂC06xœí“±A h‰RŠ¢(r %2ÇÏñÖ½å• ¸Ù³vYLr{Pº}gïz«ÌþGêYÅvïd튿zÇ;ûÎpŒq$jÁ~»ráHÔ"‚ýv周E?úíÊ…#Q‹~ôÛ• G¢üè·+ŽD-"øÑoW.‰ZDð£ß®\8µˆàG¿]¹p$jÁ~»ráHÔ"‚ýv周E?úíÊ…#Q‹~ôÛ• G¢üè·+ŽçÅ¢‡÷‰ÒÍ{¾lü û-~üÐÏq¼Ó/ Ç~ìë’ÂEï!)øQô’ÂEï!)øQô’ÂEï!)øQô’ÂEï!)øQô’ÂEï!)øQô’ÂEï!)øQô’±šã Çfa@9xœí“± Ah‰)EQ9 Јlã×ó6ZïØÜÖ³,†ÜÈÚ7n}_çíuüŽý9„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8„ZTðcÞ®R8ž—ˆÞ'}?ÇíuüŽÝ9®_6~Ø ~4½‡¥pàGÓ{X ~4½‡¥pàGÓ{X ~4½‡¥pàGÓ{X ~4½‡¥pàGÓ{X ~4½‡¥pàGÓ{X ~4½‡¥pàGÓ{X ~4½‡¥pàGÓ{X ÇjŽ/$0¢aPÉxœíÓÁiДLVz͸¹w²B'ø7Á Ï·èã1’×òÚ»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›Ú»N¥Ý#›~¿'|ý=!î§¾lÿàsùÜünþ7ÿ€›ÀÍ?àæpó¸ùÜünþ7ÿ€›ÀÍ?àö¢åÂC`OxœíÓÁ BѢɢkãvo²  º †|ߢ¥„d.@ϽkUÜ="“{ת¸{D&÷®Uq÷ˆL»G¨§rþlþñào–€ðTopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/ref/histogram_regular.tif0000644000175000017500000000476612271062644025222 0ustar mfvmfvII*Î î2=S26:>BKq­ &<I2012:07:26 1:25:46€?À8$ „BaP¸d6ˆDbQ8¤VE¡q˜Ôv=HdR8„bIŽIåR¹d¶]“Iå2ù¤Öm7Ld“9Äö}?œN¤sÊGФTJE6O„Ò¤4Ê…V­F©H*•zåviYÖëÖ;$ŠÁ±YmV¸ž;i¶\nU„Rës¼\­Ñ«½æýe½Å¯·ü%sÁáqTü=Û¶cbxœ†V}’‰e2Ù¹®b#šÎhe™è†ƒE§‘é!úmF¶=ª‡k5Û8¦Â²Únaûhfãu¿…o#|$“… ßqy\xO'•ÄæB9ÜýÿFÓênzÐnÇggÛ‚÷{Ú߀?À8$ „BaP¸d6ˆDbQ8¤VE¡q˜Ôv=HdR8„bIŽIåR¹d¶]“Iå2ù¤Öm7Ld“9Äö}?œN¤sÊGФTJE6O„Ò¤4Ê…V­F©H*•zåviYÖëÖ;$ŠÁ±YmV¸ž;i¶\nU„Rës¼\­Ñ«½æýe½Å¯·ü%sÁáqTü=Û¶cbxœ†V}’‰e2Ù¹®b#šÎhe™è†ƒE§‘é!úmF¶=ª‡k5Û8¦Â²Únaûhfãu¿…o#|$“… ßqy\xO'•ÄæB9ÜýÿFÓênzÐnÇggÛ‚÷{Ú߀?À8$ „BaP¸d6ˆDbQ8¤VE¡q˜Ôv=HdR8„bIŽIåR¹d¶]“Iå2ù¤Öm7Ld“9Äö}?œN¤sÊGФTJE6O„Ò¤4Ê…V­F©H*•zåviYÖëÖ;$ŠÁ±YmV¸ž;i¶\nU„Rës¼\­Ñ«½æýe½Å¯·ü%sÁáqTü=Û¶cbxœ†V}’‰e2Ù¹®b#šÎhe™è†ƒE§‘é!úmF¶=ª‡k5Û8¦Â²Únaûhfãu¿…o#|$“… ßqy\xO'•ÄæB9ÜýÿFÓênzÐnÇggÛ‚÷{Ú߀?À8$ „BaP¸d6ˆDbQ8¤VE¡q˜Ôv=HdR8„bIŽIåR¹d¶]“Iå2ù¤Öm7Ld“9Äö}?œN¤sÊGФTJE6O„Ò¤4Ê…V­F©H*•zåviYÖëÖ;$ŠÁ±YmV¸ž;i¶\nU„Rës¼\­Ñ«½æýe½Å¯·ü%sÁáqTü=Û¶cbxœ†V}’‰e2Ù¹®b#šÎhe™è†ƒE§‘é!úmF¶=ª‡k5Û8¦Â²Únaûhfãu¿…o#|$“… ßqy\xO'•ÄæB9ÜýÿFÓênzÐnÇggÛ‚÷{Ú߀?À8$ „BaP¸d6ˆDbQ8¤VE¡q˜Ôv=HdR8„bIŽIåR¹d¶]“Iå2ù¤Öm7Ld“9Äö}?œN¤sÊGФTJE6O„Ò¤4Ê…V­F©H*•zåviYÖëÖ;$ŠÁ±YmV¸ž;i¶\nU„Rës¼\­Ñ«½æýe½Å¯·ü%sÁáqTü=Û¶cbxœ†V}’‰e2Ù¹®b#šÎhe™è†ƒE§‘é!úmF¶=ª‡k5Û8¦Â²Únaûhfãu¿…o#|$“… ßcøûN\#“‹æëº0n~+§¨ëÁ:¸^΋ºíá;ùÎÿ†ÿãÍ÷à €?À8$ „BaP¸d6À¡ñ8¤V-‰ÄcØ”n=CcR$–M ‘ÉÀÙT¶](–KæS8T¦O1šNd“iÔöe<’Î'Ô8­‰GQ¤4*E6aN¨G©R eF£S«VaˆõVµH®WëöÅzÅC²YêöhݲÕ9´Ûé·­ºå?»]è÷H¥æõ*¾_çX}û%Âaïì6*“ÇKñ1ÌŒ÷'•“eáy Ä[5Çã4<þŽ7¥„g4Ñ V®¥­Í륺”ga Ûí`ÛMÔ‹s©Þâ7üfò ÃÞñ¸•¾G—¡çä¹°NžË•Ñ‚uå}?W¹Úïjû]r1ãèù|Ùï§½íÑú9þ¯\SåËú}aÿ~'çôß?éÛ¼€€€?À8$ „BaP¸d6À¡ñ8¤V-‰ÄcØ”n=CcR$–M ‘ÉÀÙT¶](–KæS8T¦O1šNd“iÔöe<’Î'Ô8­‰GQ¤4*E6aN¨G©R eF£S«VaˆõVµH®WëöÅzÅC²YêöhݲÕ9´Ûé·­ºå?»]è÷H¥æõ*¾_çX}û%Âaïì4[PÇ⥹^6‹–µä«YHVb3ž§g3S½Vg¢¢j4qýTK"×Þö:½fζ§èõ»H¾î ¸­ð0|-äS}âAxóN_!ÉäÁ9¸¾v˧èõ:¶Ž‡cWÓíîe]‚]æðÁ¹~OFÉéõw{Y/oÃËò—ýd߯O¯¼Ý=ï²ÿ>lSøðÀÌ÷@KƒðóÁi<í¹h€?À8$ „B0(L6ˆD`¸”V-ŒFbÑHÔ>ˆG$8ÔŠI'”JaÒiT~U–KæQ9tÎm7ŠÌeY”êq(ŸOèT* Žy/¢Ðä´zU6gIŽÓ%5 tæ¥U¬Hꑚ¼ž·Y•×l:´ÚÅZ³Ù!5ûU¶ l‹Zc· péuµ]â7*]â7|¿^p\^õ‚Àâmx[ÜÿdÇâ©Yn2Ë’°æ3YHNZ%œ¬h3Tüô;K!ÓÖtZ:F¦®†êé»-eaÛ·9=ÞÖI´ïf,w}}™ñ®Ü©·sár¹Ü^}ãÒæi:·^¿S·ÓíßìÝßèù9þo>£Ç8öv½¶>ïó=ûü÷^ù¿Çðý,«úü¥Oô·½/³Ã@飸æÀŠœ#ÀP„ Àð«äòÜ€€openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/ref/fit2.tif0000644000175000017500000015427512271062644022351 0ustar mfvmfvII*ÒÓððf ÞænFNV^(1wf2ä=RS^¼t‚ð‚h»ƒøHH<OpenImageIO 1.3.5dev : ../../oiiotool/oiiotool ../../../../..//oiio-images/grid.tif --fit 240x360 -d uint8 -o fit2.tifg.tif2013:10:17 15:06:26AvOpenImageIO 1.3.5dev : ../../oiiotool/oiiotool ../../../../..//oiio-images/grid.tif --fit 240x360 -d uint8 -o fit2.tif xœíX LÔç~„ãë¾ùZ„‘/ØLÕ¹ºUSês5ÖÚ¬[cæºl ˲d[s©vµ´©¦ËªÝljÛlZ¤R”àêZ#8î€S>ŽïO¹ƒûàëàö¼aC½në²tHryïþÿçž÷Gîy~Ïïÿ†É垇¢£a‡F&ƒsr² óñÓí†ÆÏC\¾¾p{n…JÎkM¼·Ø+Þjµ ,L‡ªªÑÙy[·îçzƒü‰÷ùïÁñ%ðÿžx¸‹~Ák¯%`µNç9¹};j¨©$ꢓyÄ^.4Ñ>2‚Dêæ†Ó‰èÀ@Œ°÷;Øã¡ÞNà½.âåĪøj#>Y©„™:zøQâíÄÇ <¯%òÞ ¿È“V— I¼v“k´üòw3—§ë™á{'Q§%õõ0±ï¼°n>ïïGò]õ{«GÔ㥞ùÄ_G~}H(òËÏãOm¾Ø—{ý·ª¨‹$æM'û I##mP*“© 3dïeow ((†×x/Ñ+Þno Ž’P__‚Þ^Ö­{ýýŸ“?ù>ÿ=x;ñ±_ÿ¯ùŠ$®MÌ_%Þ~{;6$$xŠŸ{ƾ>è©©.zUÌgb«FJx8ZØëupQ?·Øÿc¨‘FâBC1Dùr®Sr†3 ?’ã&ñÂ{BkVÎr‹¨Ë:^KÕhÐÉïÉ©·`¹Ô^´È j7–ü#ä‘ð¢g}ªÕè` jÖ"^BÇ‚¿½&™{d0à së`Nj¹¦1¯g×?ƒÿG="¿¿Ðøt=Þðs¿žù›ÂüýMÑŸ‘ߢÀÏôWtõ©Y=œÎ.i>s˜ÐбÍv“ºXÂþïàÜf¥nñZ4šT¯x«µ¡¡É0>bn]ANÎA®µN›wüjuý~›bÂAÝæ·ZMä_JL±jÎãÚ{ê^õ¨TwÖ#fe™LM|=ñ©¼W/ùxjÊ9¿‹04Ô õ—ëÎz4QO³”¿ÇŽ-ÅÃqqžžz Wù›§Ñg­ìárf£ÈÇAúÕ‡ú8RQ—³³1Hï ë©›Óf3Ôƒž{$!qÔžŸ—Ñs&ö‘.êm˜ާW¼–JݵӳaÌ’~îWxó&R¸g({ÄŠ¨(ôp¯ öÌÜß~Š£=†êUô-õÙÌþ j4ˆ|á~E&jº»q˜µ}Æ{ÏÔ¯¦¦gð&êÚ[=KY7ü\ç¯aÏ[ŽKÏád›?~¼ç/èù’ÆÞÝJýÈ%ý¸\ÍÒ5‡Ã$õüÉI—ôl%—ÇS#Fjj©W¼Ýn Öõ0™ŠÐÝ]ƒììÃ̱ϨõeóŠßél䜽•ÌÇ(fž˜omÜKG.39¾ÎÏÝôÝæÏˆ…{êÿƒz‚¤àrµpÏtÞ«¥ƒéõaéyWð[­5ˆŒ\ÍÕ(ù÷Ÿõ‹l&^…'²ñH|¼§øé§qe`éô¥…`>>@´´ ÷Ô)<¼d JèñvêÈN ½XV†ŒFÌþ;²iÖ''Cçï/éMÇï ½‰s‘ÕÔ”ÐV/?ç•–¢˜Ù3ûï%jø{™™R>‹92åõ×Y³ gX›ð®’mbméÔxõÐÒù¬x–5\§þ_ݰŸôô cº~¡gq¶Ó87pooõ¿xÃÏuþ*öÑÌð…8PrÇ-ÈûþEôô]fïN§,ÓúÔð}£¤Ÿáa5¦“ô&ÎMDv WKzö†ªæ³b:ŒÆ³ÔÿulØð*zz>!Ƽá÷õUÒ—œ«»QXø,ví*§‡ý%iµËˆ/§&ØNaá deí¥×ª%Ž/ªG¥ZÆyØ"eiCC ®^=Ê=|“…5k~ÍA÷’?Þ\½~23w°GŒ2ßC¤~¢R¥s­£Õxó͵x”ósIn.®s†Í³¬˜o©‡HjD—ŸæáÙÝ»¥ù6€ÞÜuîÞ»v ߢ§ Ô]λïbœºúp×.lIJ‚\âÙLœ‡ZùÏÉ×83fEF"ÿÂäÑÿßÐéðÛ¡¡w³Ù#Ú©éBöˆ±±ˆbÖY,ØòÖ[øNZNoÛÆÿaMÌš4j\ÊyΟì•]]8´y3®qÍb¦µˆy’õ Ï›ù^àä5Ì®Gxh9ïyÃÏu~q–‘‰ýÅgp´EŽŸýð"º{¯S™üí[¤ùÍÏO+õq&z6Rc Òù¦˜Å{¡qf¹W¼Ífàü¹Œógºº*±yó!®×˜GYó‚_EMÔ(qìFÍ3MLEÑAˆ€ËØàSiï¡(ŠR¤Ã£+2ë\Ðɘ÷¼üîåœ}÷Ù×·Ö^ëœ;ÑÅ¥=14ª²2¸›š¢¼±=utÐ?2=ºw‡rÅ <¨¨€‹•&'#41_¾÷Ö Ë®]QÙÚŠ†– Ü·u¼¯]µ UìtuÑÜÖ†ê/`«¯ ^o(•˜þûï˜ëå…è¹s¡*/‡»…r++øë¯x®V#+<>x\S“W¯`¾s'æùøàðìÙ¸Ï:\ÍÍ‘_] ™¥%.deáNQ6…„@É«çÊêëaЭ XûCÞ;ó1×»ÿ«ÇÐ÷9æÊ9MñÚžÿ~U\ml±-á~xdˆu˯¢¨T33wÔ×—¡[7tïnÀû‡05uFMÍ#¼‹¶¶f¼xQ CC[ŽÝçœ«Æøêê|XZÊ•uEEw²‰W%ÌÍ=´>¿Z]Ìçí—w Ñј93nnÈh´·· µµ‚kÙ£k×V>'ONŨQÛ0n\ÊÊò˜Ãíÿêim­†‘‘-jkó™W†½{û¢¢B‰ðp+èë[3>0¦‹gÂÑÑ—÷…hi鎴ÃС˜2eóßg~WÔÕBGÇ‘‘nÖ§Oû±Y³Áßܸ¨koGÊ“'øòôi|æç‡äémrÛ“ØúúìY$ƒ‚‚0ÚÛ–]º „Ü5êÑá'Oâ1õÑGèco#¾q sÕ¿| {r¹œ\êÂâ!CQZ riü‘#¸NŽÅ‘ï^NNp=ŸzÝ‹œúìÔ)ĪTøŸ ¦¾’»‚¿5ä¦ ç’ç+ÉѳŒ9Ęùƒ!ï3€yŸ2feBNfgã»Ñ£ñ-ûÃâb éÕ aì#¿¥§#vÎôwt„SϞȬ­E?êöiƧ2n9ŸZR?j¨GŸ¾ÀŒµåã¾Ì/¯«“xß@ü‹z\©eéÌ!ÖÖŸImÓæüÌßßÚëÏFdV/½‰’ç÷¨=ƒÐØøÚ¡O=2#Îò`bâË~.'Žœ‰·⬆ÚáÊþŸÎ¹ãkj2‰­~ÈÎ>ââTLš´%%©Ìï§ÕùMLR/‹ùì3ìßïgç±X¸ðr;“¼wy“_OÏ™¼|Jþÿññ¡9r={À&Æ¥±/ üK=‚sñ—F=Áœ9gè2É÷þŒ+ÂÝ»GÉáøøÌ¥æG³w¤ÀÖv0®\ÙŽ«W¿Å´iQpu à{8¢¡!—=É”5Âhgçö?>ýwèM½Ùÿ«É¹¹11¸UP€ý3f`¹˜BžÙ‘7Aâ>ï¯-X@7‡u·€=߆Øú2.§¨'?OžŒ@OO0Oëkþo¹Ä–¤ÑÄk¹8ÆÅ™Ô__öŒgÔ”Í/âxf&6Ž… ¸N<ØÒÞ¼‰µ—/KcsèÛí‰U9õ¥×%þÓ·kÂ$±Çô'þ :ñlJ=zÀ{Ñ“²ˆÿ>¬±‘ø¯í¬'ƒcbmMñ¢?hqþtòw • 6\ˆÅǺXž„Ò²[Äg?â¹@Âs·n¦¼@üô#Þ²ˆ·>ÄQ#ñVKü»p,ƒs¾ãkk3øû üÇ÷é˜0añ–D~õ×êüÆÆ>ôȵäYy¶ C†,%·÷R£o“¿Îoòëéõ‘8—“s ‰‰K0|øêæ&úbÑcþ¥ž×ñ))1¸~}3üüaâÄÝÔãt©ž—/‹XK<Ο_™l,µ9‘½à¬­‡Ò£G#6v>Ÿ C`à ¾‹=õ7úkBÏ=#éŸO‘O÷„—¥÷ª!çæŸ8̧O±gútÌóðælÉßiÔß<ò<ž|7#þØó é߬èçVÇÇ#žÚºküxŒ$õé—ëÈM'Îç“çßÄÆJû(ûÂ(™ âÌ“k–—ß“£§år|3r$"ø/™¾ò}kküD°žsˇÇǃÚ^QøIOúÏö 9q¿?™þÓ›Ø-ä:zŒ1fmÛ^ìI¯:túOQà‚ð˜Â»kŠWÚœ_Îþàki…—õ¤;–…§N%V:ü¡ŽŽû¸±„m##/ÉOêé9tú½: {juŽä·5Å×Õ‰½›'ñ›@ÜË1vìvâ-™ù½µ:¿ðÖ::MHJÚƒ[·~Ř1›ðþû_ÑËÞfN§7ù…~õª¹¹7qáÂ7ÜŸ.£Ž 3$}»ßÖVJîîGzz† [€€UR¼¨§­­JåUòw 5?³gÇH½ÀÜ|½ó=DEM†““?>üp7ߣ÷ÿ|ðàLpqi?·p!r‰Ÿ¾ô^£>Œ»……ø÷ܹ˜åë 1æN¾Näøùü|ÄÏœ ?ò¯õ÷YCl©3ŽGl^NLŠ1ÔlãNÿ\E½èÍùRáŸÉñcÔœÃS¦`ž¿?”ôìÔœJÆ„S¿…ÞͽàWcÆ ‹<÷µ³ÃoÔß°ÄDl¡þ.6 fÔ™<âÓÍÒç²²B=ßÌ| Æ{±ÆÖcH=2"žï“çâŒ'Ÿ}BÆ„~Iõ°g(9&ÖÖŸW]­ÕùUì·î6¶ø.á$vàoË®¡¨TìùúÒ{•°‡Fô“g<âüÄÀ@Ö©UÄqoŽ)9ç¡1¾º:{87éü¦¸8S¦l&ÎÄ›—Vç75õâóýê:ܸñ=uù'j^85:9ÝÞä××ïÍk9ù gÎ|LîneXËÐqöv=ñeì ?3¹7Jñ¢F#—ŸÁÙ³¡ôÈ“±`A¼´/·¶öÂãÇrüò‹/y„Y³¢¹÷¶á{<æ;™cï^ urjâ~6‹¿¹ðeõÜÿŠ}ê­‡±UðŒZz—ž¹/õ"‚<Š£fDKÁ>>0g¬à¥!±#¼q½àarÛ‘ûV៛©Áâ¼EhG%ÿ>””„#ii'w—ScgÔ‹bbr5ù›Æžñ#× áš÷¨ó~Äø?’“±‡Ï­æšã¹¦µæ1+ÎÊ/äæ"‡:½|O½@œ…ýésó¨ÉÛ&M‚û~¹WN> Þ·݉¡ò+¤ó¨>ìüÏ@Uk+ÌÉïbò\Î=õxêô$WW$Ѓ+ij…îqíÀ &åK—›º›M<{ÛØàãcÇ$ÍN ƒkߥTÔ_wr;QèukKH²yõf)f-â{ŠIçyŽyò€Z%õ¦Îï/ã~CS¼Šú¨Íù•ì‹Ôß­ÔßÝÔßµÔßâÒ}ih(îüžb"áÌÔT|ïx aWœ­v|qàX.½`_ñÕÕ*ê—;õ+‘º•‚-¼foÞZßÄÄ›úÛˆ´´CHHXJŸ»†sÛ©¿*©÷½Î¯¯ïÀës(—÷ ½ðŒ÷7êiõ׳³cÔ~À --E\#Ÿ^8ÚD/ÎÓÜS‰+W6ãöír½ÁÁ+ÉÛ,ôêå+‘=„?Çøñ[ùV|§G¤–9"#=ñ_œ…xœÝXiPTW=ìK7 Ý€ 4K³ºÄX£VãcaŒq©Q3.q˜qÆ¥f&©‰Mâ’Ç8šh:nc´&¢ ŒŽkTD#›Í¾+K³6Ð4‹lsî³u,«Mò©zõ.÷}÷ÜïÁ9ßùî{ÙÏoàä¢Eø±¹ar9šúúWW‡…GbAd$âccq£¡|ÖÚÙ‰Ñ_|¹•/^Œi¾¾¨ïíÅôt|xþ<^ Å¿æÎEVK zF\//G¯…„‡£~`C­­1᫯ÐÂg—V¬€³‹ Fòúœëמ9ƒpâš7žŒËko‡†{¾fî{mÕ*4p/L†»Â]]‘”›‹ìÚZl›6 טs¤BJÆ:2?1Ê::áä„\b sp@ß­þŽŽÐC¼¯¹øœAŽŸÝÖ†‘îC±å?gpðž-Ö¬HA}ã-89E ³³VVް¶V ££LškoÏ…ƒÃ0ôõu ·· ŽŽþ0´ËÃÌÆ 9pu Gnnjk³1mÚ6ÔÕ]ƒB9¨ñœÂ‰ÑˆÆÆ:ô&Ôê,\˜ˆ¦¦tbú=Æ·³óá¸ùùW‘’ò'Œ¿ÑÑï2.ÎΣ¤|D¼¥%o€­­RÊÇÒÒûöýŠs}Xµê*óê$–zzªpüøJètZÌŸ”ûNg7áá1ׯŽ 6búô- ›J O¾S)ïNHH˜†ÉþþÉÔbzc#¢œQFmy+ó©ßtrëþúõ¨ìî†ÒÖvvøèÊüãêU¨=<°{útÜ!ïÞOM…-9”¸t)¢U*T0þdf&6PÓâçµjK®Eÿ0çW~÷TÔí_cb`C>Æ%%¤,[ï!C$ýV>x€&½SÀ{'bcdŽ£¹.«µQŒ;¥Õ"ƒ9îœ1—u:Œ"~9,øìLŒŽ£¨‰òy9/øßÚÓƒ@Ö€,Î ½˜‹ìø™¬Ÿ£‡zbSê)ÄWØaýo¯@WŸFnE‘Ã&>;s\BMD¡­-‡|!ñ³§§2Y ç²$½˜‹omÍÂ!QÐjO‘ÿ˜1c'¹wYâîàÇ/§Þ\©ß7 ×`Íš2twWÀÞÞWÂïëk'F(5XÍõpúôrLšô^}u2¤š!´ÚÕÕƒÔÔµ0ë¨íO Rùs]ΟŸšÜŽqãV`òä?sO5nÝÚ‹“'ã0t¨‹Ÿâ^Øc&ÜÝÇáÈ‘×PZz«Wgóð=ƒ‰Y@ý*ðõׯ`ªZ=úöÛÈ Ç m”°Ö+Éëee˜zäNÌ™ƒhú§uÖM5ö÷#!- SÃ~¼É™ƒŒóóôD5^ÅØ ……Xš˜;¡;ï¼êWmo/ùõ§×®açëmY’Þz üüPÍúÄýk¸Ïêú@v6*Ö­ƒð!ÁYæ˜C~Fº¹!1'·kj°uÖ,Üá} =­œëe䳋 9Ž &´Ô‹š˜Fî­ç%ÆBC#ùÌ\ü`ÇÏfÝ‹òðÂß’¿ÅîrG¼»ú jë2àâ2šÿûròYŽ ÉŸrEKΫÉI#/½4wvi6¾¥%nn‘ÈÉIDMÍmÌšµ•÷;ô´1ƒß`(¦Î†áöíƒ8{võt>>d©‚ú±FEÅ9œ;·è³ Œ¯¡÷»/˜5£’>¹!!PU•‹ýû_’øýúëûé“ÉóáŒ)D|ü8®mExø›’~oÜØX²$ ÞÞc¸’u$Ÿ{¸cûv®‹ þMOÎbŽ#¹§Ð¯+¾ür&Ž1pdÁd±ÖP#UìÇlÙóúQ“óNœ@Zi)ö±¿~I©„žž(<@hèLe¥äͼÆzyAE}jÉ›0®: £¿ì¥NwüðnÄÅ¡E`R¿U]]PÒKjÉ¿[õõR/hÅkŒ»;täŸøÄß•‘Oéëœ4 ËÇŽE/÷®¢¯‹ž:½£†1ßçåAKÿß4e n²þ„šòw Ÿ„‡s,â X“|¸w'k‚ùg!æ‚ùÌ\ü`Çÿ7w|v>Çî[á÷¿IDCSûC {¯*òÙq’zK¹\C.°æû ¿¿Sê÷†Ksry°Ùxƒ!µ@ƒ¼¼ïÙwj1eŠðž›Ä}NðíÙ×zbïÞq’6.Œ§^œ©§~út&ÒÓ¿•ê„çû9î¡þÀµõ˜0^ã3‚µ¢/î@II*ýýãz7æ¨ç³V¤¥EQÑiªÛ’½€¦NÝÂ~Ùº­•ü×ÂBÏõ{™ù –/?Ï|U|§R)ÿÎή“ãàÁ9˜8pvùrPK!¬ÿõä…èÇäôÑ|jl ûèjO»–½yÑJþ­–3ÎÒλ%“kJ©¿ò²ŒþâOˆIH@{ºl®-jjBŸÕ1Þž¬æ3%÷¬d_<œüìç;^ôcÅæÍX6j6³·ìçžrΕr­À/aPSï)ôæ›ÕÕØ4{6òy×°fˆüe䲌~ô(^ʇž%ðõì?•Ì¿ˆs"sñƒ¿ˆµ8ÈS‰-I'ðY™Ö\Dµ®€µ;„ÿ¯zrYø‘L⃋Ký¨ŒžåÏÞ°‹ý§žQr®ˆÏ‚ÌÆëõ%ìíÔÈÎNAuõMÌž½‰÷|òPó\à[ZÚSË Ü½{ ÇŽ- /üsç¦îÔŸ‘^ëAŒjbysÎ@l'z+8®ãÞž¬EÔb=¸»w«±bEWRï^Ô®ŽútãØ†çå|©Ž•Üo8µÛ!Õ77oê{/NŠcoþÄÄlí‹ÏæßÖv9ºaÏžà‡þ;¾ä¿!¢þÓ…¾DOÖHݸs¼‡^¸öÅ%íŠN|KÉgÞ¢ÏñŽäÂTÿƒ9WMŽåÝ»‡Í—.aËÌ™xÅי䬿)|Âø"æíKý ogš°æúòl¸‰çÞBî#zp…ÿJ1ùׯ'ýË„ÿ,ÿj7åÿØ¿ÌÄvüÇþûßd|sß¿þÛ(ü7„ç²*þïʿڥoAüË\üÿý+Åä_û×ó‚/. ‹\â™õc¬\y™š³âYXÿ_&{ˆÿ´¿ÅŒQQkˆŸÃµ©¿jÎp} qm¥x1~˜O.±UôðnÖŸ6öÔ$$L—W(ÏÕïqm7k„³„/“…Hþkaá$ù ä•+‘OÿœÒQKâû²œõ¼Hh”žPÇ9ñM©ÓTÿ…ÿ²þ‹xzî£xqvV ¿ o‹^Ù‚kêÉ/ñ=¬sÏŠ/å³ú±Ào&¾·à1ã|¸NŠ'ΓñŬô¯ä¬,¤WUáÃØXäÑ¿B™ëÏáÿ’ü;¾ä¿^Jl>}/sÀë.¡F÷°ÖwtèÈ79ù 'K8'Ί¥pt  ušüKEÿ*ä³`É/žŽ×ë‹é_ÈÊJ¦Ç¤#6öCúWý+Ôlü`Å7 ©¡`§KçekkKj©‘øÞÏÄçY£±Šº®\ùãÇÿýtëC>ûÍSñÅÄ$V)u`úþÖ±Šçì‹ì¹£ùLg:¿;=Æ7*¥óï®]ŒV*¶FGK5[|׬åÓÞäÕLBð¦Ø¤%Ñ¿µó^ æÔOÅ /¢öbLûê.zÆPÑÛ±,sñ%ŒW™úçGø…äbyj.¾Xô‰¼33âqØ0®èÿ›/p¯R£Á÷Gp7’ƒ/¾ƒøÒòòÊ‘J…¡Råp¨¹ž—b++Aää‘N§8’ÈÍ5!™ p¯L6_ÜËÏ/ÃÌŒñ¸€†b±q¨ÕÿKýdR4ŸE¿   ‚0Lý,–7¨ÿà™þ"ájþ£G!lØ¡¡sxÝl^ûéàAL…B¨.*âïÅ¡ÍÎ SåF#B‹‹(%xüQ2¢×éà ‡QÅ=¹|aa%%´ÛqÓçáînLr®1™ž«þµ'ú‡{z09=­è?É÷ÏÏ£²¼½}ßâĘÇ?¾ Ÿ0…¢¢j)?;[+¦“©ŒÆr,.† Ñ”Šòd$ NpØÇ½*Ùü…%%°Û¯Á绉žžÃ˜žž„ÉT£èÿGPÒïî>ÄùùéG"óÈÊ*Boo5vÖÖ®}½kœäÁ¬ÕÂOïVgeAÇ1ŵ…ÜŒ.-¡’µ!¹ºŠG5×bl3÷äò½üM‹Á€¯nú‘¶6Ü™……Ü)ú™×÷ðo)*Æ¿_ÁÅé,ØwsóÃÐjͬ ~~{5‡Žë)rcÁÒÒ(½¾««IŽ×ÕRL£Ù,›{a0Xàõ r£­ífgï;‹¢Ÿq}3–—°þjqáÂ[°Õׯõïß{¹æÂBäBC?7ðÀ’33c÷éÿ ä"NvÄ~m#Ϲ‡±&2(—?B/°ã‡·ý~ëêÂ=Î-bíQô3®ïe}o,-ÇñËßãó p BÐ…ÂÂfr!ÐÏ5ôs9eÌLÿ¿O.ÈN\ê×´ÚŒyÈ`“l~8<‚âb Ž_à÷ßFW×1Î÷XZý ë f©×W©Špúô¼¼iÓÚ{öà/~óúÿd"z¹žLŒóN,ÆÜ䢚÷µeòe‘¯ﶢǓ#¹|'÷šÉâe·Ž@';:pƒu¦U¯Wô×Aßbkq >ûígœŸÊŇïþŠ™9Ñÿ[x¯š¤— =}|\ŠÅãnÞ«ÉÏ2{¸(ïnudÄEŽ¶ÈæÇbN²Ø ·û2::N²ÎÜ€^ߪèg\¿YªÍ*•çÎuàÕººµþ½{q{nVúùC2 ò` c\[É”“<Ô’‘Ÿý_¬ÃŒ‰¼ÉåG"°ò.}Éå‚|ž²Ù0 b›¢¿.ú³6o/)ÅÑKøêa>:pÁ™?éÝV2ðð ®ÇÈ”Ѩ“ÌÔJü¤R©D£Ãorù‘È0ïÒV¸\—ȧ6Û)ƒƒÔߦègX_§³òüzx~õ8{ö¼Æþy`ß>ØyÿÚÎÞkBìÇÈC¡ØqÝB¦\ä­žÌ,ÑûÃâZdp+÷äòä§ÕdBŸÓ‰»‚€⼃5GÑϼ¾ƒý¹õ…2|Úÿ¾œ(À'ï_G dg¯¶ß~‚<ˆýX¡äãC ys‘™zzÿGXZ‹  [eó0™ZátöAóç!ÖœŠþ:èÇb#<¿Fœ9³ /ÕÖ®}³{7†Å;“ø®É~,_|¡Ÿ‹½Y#{´öoUj5é4b䧆½œß»äòÅ÷“FzÁ.ö…GÛÛq‹þФ诋¾›µ¹ÅTŒÞ«ýøn: ï½Ý‡Ùy;½»‘ý˜<äÓÏuRo¦Õ6²Z]…t:A~bìåj¤˜øÞ%—‹yèðx®°/t¡½ý(fgoQ¿IÑϰ¾øÞ•HŒÐâüù7ñr xœí™IlSW…‰#Ù±_ìØ¦QD„8âD1VmÕE•Dr£¸‹."•tÓAtQ©‹ˆÐ¤6DBBBÀ¢U[]dBmÕJQ Ɖ§Ìâ1Q<&Ž”Á=Ïu%ok¯Þê=ý÷×ÙÜïÿÜûÞniÉ÷÷#ÃZ[‹x6 µBuUøÞ¬Óa1™Ä!µ›;;Hlm¡^£Á,kf®IõÏ'0óxð(ÂY— >mz½¬_ýÙµ5˜ëêñíÐÏø~Qƒ/?ù¡hµµVd³q(jTU©ù¾®Éä"ÔêCØÙÙÄÖVM=k³\3Kö'ó0MðxÆ =‚Ëu–Ïôz›¬_ýtz ZðzSSþ‡¾>¸¹ç­‚€››PVT@ Ïs9ØÈJ\4¨TÈ‘Ÿìö6ð=Àš•kRýþL6zÁ¨Ïo,†®.<¤?Øeý²èû¨ßn0â»ß‡ñ㲟úñÕ'„Vln¾àÞ+É„€\î9Y™ B¥j ?9logù~€µ×¬’ý™ŒŸ^`ƒÏ7ŠXÌ‹®®Äã©o—õK®oÅÆÆ<öìpýú;è6™òwOžÄã•¥w/ll º²µôó2Ò¡Õb*Fsu5ÖÉO’þoæ,˜L¥p„kRýO9nOOc"Æ…žLD"8&ë—EßMýïÔá«‘Û\Rá³þF$ö˜Þ}”{¿€ÊÊjúy-™VÛA?ŸBuu3ùY§ÿ'9 ÌH¥&¹vD²?™| ƒÁééÛ‡'ÐÓs‘ÈõÉúeÐý¡¢B‡+WŽâ­ææüÝ'ðhuîýR‘ý|ŽïŽšxÈOùÙ ?)òÓB~ܬupMªßM¶Ì‚wÈç$¹¼ètâ^4ŠÃäSÖ/½þ$¿ßW÷ÖáÌØ\}¦Ä§ÜC4þ€{ï K ßçPSã ?òÓD~6ÈOŠü´°ææZ‡d*åfù¼C.'át^D4z|–õK¬/¬¯û8µ¸zõ ¼Éü|ëøq¯Âé÷G™Ÿ'ȃL<;©èç56¡­àç*Uc1¿¥ ,e2¾BÞ–êO§½Ì‡væÃ!r9…îîó̇÷©ß.ë—X_£±ó9[ÈÏ×®9áliÉœ:?ùi%S‘õuhèçy˜eïHæéç&z¾èÿkôÿž±¬Ù¸&Õ?“HÀb4bÄãÁ8óá@o/¼¡Ú8sdýÒëéÅÖºz|3ô ..©ñÅ鿊Šg²Vzw„~®!óØw$Éä<=ßTôÿ52ÒÀZ€k6ÉþDbF£Ïóá8z{ y9sÚdý2è§ÓÏXÓãòe^;x0³¯qÏéÝ¡—îCDoïHÄsÕ>¥¹ÝÝÂýÉ~αfæšT€³ÁJŽÆü~øb1œéìÄ8Ï×6Y¿,úâ¼¶ë ¸ôÇ(~ú§¾w +«nú¹xzé>d¹p"ž«”Ê}ØÝýÿþd¡¦Ñ˜%û3‘-+üþ1Äb>tvžÁÊÊ8õm²~‰õÕj Ÿ œ¿ܸñ.œ&S~¤¿^Îß62¦Ÿ‹ÿ#´Åû ksôzñÌ•-þ¿ha­•çe©þ ç‹•óeXœ/œ+ç\.LóÙÎù.ë—^?@/¶qþ~Íù{‰ó÷sÎßpÔK¦DÿÿGh Œètzý\á̵³“-þ¿hdÍÏór«d"ä|±r¾ s®ŒÃå:Çç4ç{»¬_b}­ÖBXä7­Çà ÿ%(*xœí˜[lSuÇ¿ì"k{ÚÓ]¶[wé`+ŒìÍDƒY\F–eú!!Á ‰¨ ê‹/*#x "áyÀ˜xIŒ³£AH l"£mÚîÒn+ЭÝÅuëuË.õû?$zð‰îé<4çŸßùåûr>ý~¿ç¼¸eKæû}ûðÇô4êFÜO§¡ÏÍ…)/é”2ó&ؤÓ!µ´„Øâ"*ôzxâql•$Õ}7ïm+,D—× W8Œ“--¸9>Ž“IÓ_}W,†í%ëpüçqñÁs8ò†S¿Ãh¬G:}¹¹zäå™J +³D n––RX\ŒA¯¯@<î$mUÝÇÝ(,ܯ· á° --'1>~&Sƒ¦ŸuýmH&“cÄ… -x¹¢"cß¿=SS°É2‚d@𠓇Ï62å&ådFð3»°€*ƒNÎojûÎÙYØŠŠpÙãA/ù<ÝÚŠë‘vhú«¢ofëÖ£óêe|\‹÷ß¼ÈÄmȲ Wxy)b17™)WøYX˜…ÁPÅ™SáMmvÖ‰¢"<žËä³­­§‰\§þM?ËúF£ÿ_ÿ¿&œ?ÿ^±X2W@ïä$ÍfŒ$“0s~>x®'Sòf!3Iz”?q nç=µ}7ùi(.Æ%·wÆÆp¢­ wyÝÉÌÑô³¯ïŠFa{~>¶‡ÏFôøà÷Âlnä³!äç›—åzòæ!3z’¿¨r ÊòvÕý™7Š‹àv_ÂØØ´µàõ.3g§¦¿ úñx?ÿ¿…8wn^(/Ï|¹w/œìÏVv¯û˜Ž<é碛YÙÑúÙß6 ½¼Œ8ùÙÌ.'f5¼§¶ïc·³Ò ®ø|ð°v67£›þP§é¯Š¾—Ù\_\‚S¿ØñÕÃ\¼ýú%LþÙKï¶²…ȃŽ~nTº™$YÙßúQP°ËËiòg—Û¬Ì$©Fu?÷Ñ ¬ðù®°zÐÜ܉ÉÉnê×iúYÖ7jy pñâ«Ø]U•ùéàAôOL –þ?A. dÁ@?â¹’œ 3/*èùsìoQö·R22ÈY5ï©íèÿ–’8\.tŽ¢³½}¼ZÙ5ýìëÒ‹«×—âx×·85,áÃ#×0é§ÿ×’‹ ² üÜÀó9«d^ “‹ ö·9ö·(¹)ål÷ªU÷£ÑJJ,p¹íF{{'¯}ìŒVMôc±Ìßbœ=[ówþîÙ£äo­ðÿ¹9èrržêÿ úÿ¦'ý_eÿQ¾8Vòåè“ù¢ég]ÿqþþjÇ×óð–Èß)‘¿µ˜› ñÙÿŸÿ'”o)ü_mÿŸ|q¬äËÑÇù¢égWÿQþ®YcTò·µº:c?t}Ì_ÁT$•‚Ä>&ÑÏdÄÂÙßµ*õz¤Wü¿ŒŒ ÐÿkÄ>ß¹þ½ïg¾T1_ìN'zB!ëè€ùRÇ|QÛ×ôŸ­¾’¿JñÉßàÓa>zï7ŒEú¦R©û˜D?—ÈH€3ñ®5½¾’þŸ^ñÿ2úÿïÕðë¿ûѨŸùR§ÓŽP¨ǘ/>æK꾦ÿìôeÙB¸¯¼ÿž9cEciiæÄ®]Šg‹ïšáùyÐÏÅ7áíb #eôÑßü‰,ðsfyʾ_ô8“ ·‚AøÉÒá¦&ÜL‘;M?ûúƒ"›e3¾¸{]ãkñÚîÓˆÎx”ïšóóa>û囈ðv1K&ôÿ2¥¿--%”,H&ýÊwµýD“©Áà-LOûÑÔt˜×{ä®ZÓ_ýTj„3 Ç»ø ¤Ž* xœí˜[H›gÇÿ§hNÆè~ ¡+*ø{ h AAÈT­ÑˆÐÚªÉ^¼@ŒŒèu:x#4pO®Þ¿ºŠºª*ŒÛl¸ïõâÄÐæÑd2)úyÐ÷­¬ ¾¶Ã#ßáìŒg>¹ ¯R}a¡V”“©ŒÆZ¬­… ÑT y2ƒN§G$âå^ƒlýêªUUu°ÙÆáõÞÇÐÐ ,.ÎÃdjRôó ®   ÃÃØßܼõÍp³V ½[]P×c ¹™N&QÏÞÞÜDœ«‘±Èíäž\½‡¿i10æñÀE_8ÙÓƒGá0,äNÑϽ¾›çxWE%¾üý®-àØ‘kX^™„Vk¦¯ûøß«¹tŒÈÉä4{C=67Ó\qÆRN£Ù)[ŸHx`0XàñŒ!r¡§ç$ÂáGä΢èç\ߌõõص¸zõmô·¶n= 'g¹ÎòrøÉ…†~nàŸ&gfæžÒÿÛÈE‚ìˆym;Ϲ›¹2(W?E/°TVâ¦Ýއ>Nâ ¿]¢÷(ú9×÷°¿·W×âÌðÅœ'>‡?èDyy'¹ðÓÏ5ôs9›fÎLÿJ.ÚÈNBš×´Úí̹É`‡l}$2…ÊJ ìö›ðùbpð4¿Oغýë fiW©*páÂ.¼ºcÇÖO‡á/þç]ôÿùT eôr=™˜åXä\䢑÷µuòc“o)+ƒSx<9’«wp¯“,Þp¹`p®¯÷ØgºõzE?úöX »+«ðùo¿àÊB1>zïW,- ÿïB*5O//#zúø¬”K$\¼¯5’ŸuÎp1”•µ'9Ú%[;Èb'\®ìèë;Ç>sz}·¢ŸsýN©7«T:\¾Ü‡×[Z¶FÆÃåeXéçÏÈ€àÁ@f[É”ƒ<4“ÁO”þ/zÁ$s‚7¹úÉhVÞ¥¯;°‘Ïóýý¸ b¢Ÿý¿Ù›÷VUãÔØu|ý¬»‹àÒŸôn+xöÆ3dÊŠXÌAfš%~2™¨Ô b±I‰7¹úht’wi+œÎëäÓ†þþóïP¢Ÿc}ÎÊóëæùÕãÒ¥×ðçç±#G`ãýk/g¯91‘‡r11î"SNòÖJf’ôþ—ˆƒ»¹'Wï ?Ý&F<öûqv`üîcÏQôs¯oç|n}©Ÿþˆ¯æÊðéwÙ8«íå?GÄmz½¬_ýÙµ5˜ëêñíÐÏø~Qƒ/?ù¡hµµVd³q(jTU©ù¾®Éä"ÔêCØÙÙÄÖVM=k³\3Kö'ó0MðxÆ =‚Ëu–Ïôz›¬_ýtz ZðzSSþ‡¾>¸¹ç­‚€››PVT@ Ïs9ØÈJ\4¨TÈ‘Ÿìö6ð=Àš•kRýþL6zÁ¨Ïo,†®.<¤?Øeý²èû¨ßn0â»ß‡ñ㲟úñÕ'„Vln¾àÞ+É„€\î9Y™ B¥j ?9logù~€µ×¬’ý™ŒŸ^`ƒÏ7ŠXÌ‹®®Äã©o—õK®oÅÆÆ<öìpýú;è6™òwOžÄã•¥w/ll º²µôó2Ò¡Õb*Fsu5ÖÉO’þoæ,˜L¥p„kRýO9nOOc"Æ…žLD"8&ë—EßMýïÔá«‘Û\Rá³þF$ö˜Þ}”{¿€ÊÊjúy-™VÛA?ŸBuu3ùY§ÿ'9 ÌH¥&¹vD²?™| ƒÁééÛ‡'ÐÓs‘ÈõÉúeÐý¡¢B‡+WŽâ­ææüÝ'ðhuîýR‘ý|ŽïŽšxÈOùÙ ?)òÓB~ܬupMªßM¶Ì‚wÈç$¹¼ètâ^4ŠÃäSÖ/½þ$¿ßW÷ÖáÌØ\}¦Ä§ÜC4þ€{ï K ßçPSã ?òÓD~6ÈOŠü´°ææZ‡d*åfù¼C.'át^D4z|–õK¬/¬¯û8µ¸zõ ¼Éü|ëøq¯Âé÷G™Ÿ'ȃL<;©èç56¡­àç*Uc1¿¥ ,e2¾BÞ–êO§½Ì‡væÃ!r9…îîó̇÷©ß.ë—X_£±ó9[ÈÏ×®9áliÉœ:?ùi%S‘õuhèçy˜eïHæéç&z¾èÿkôÿž±¬Ù¸&Õ?“HÀb4bÄãÁ8óá@o/¼¡Ú8sdýÒëéÅÖºz|3ô ..©ñÅ鿊Šg²Vzw„~®!óØw$Éä<=ßTôÿ52ÒÀZ€k6ÉþDbF£Ïóá8z{ y9sÚdý2è§ÓÏXÓãòe^;x0³¯qÏéÝ¡—îCDoïHÄsÕ>¥¹ÝÝÂýÉ~αfæšT€³ÁJŽÆü~øb1œéìÄ8Ï×6Y¿,úâ¼¶ë ¸ôÇ(~ú§¾w +«nú¹xzé>d¹p"ž«”Ê}ØÝýÿþd¡¦Ñ˜%û3‘-+üþ1Äb>tvžÁÊÊ8õm²~‰õÕj Ÿ œ¿ܸñ.œ&S~¤¿^Îß62¦Ÿ‹ÿ#´Åû ksôzñÌ•-þ¿ha­•çe©þ ç‹•óeXœ/œ+ç\.LóÙÎù.ë—^?@/¶qþ~Íù{‰ó÷sÎßpÔK¦DÿÿGh Œètzý\á̵³“-þ¿hdÍÏór«d"ä|±r¾ s®ŒÃå:Çç4ç{»¬_b}­ÖBXä7­Çà ÿ%(*xœí˜[lSuÇ¿ì"k{ÚÓ]¶[wé`+ŒìÍDƒY\F–eú!!Á ‰¨ ê‹/*#x "áyÀ˜xIŒ³£AH l"£mÚîÒn+ЭÝÅuëuË.õû?$zð‰îé<4çŸßùåûr>ý~¿ç¼¸eKæû}ûðÇô4êFÜO§¡ÏÍ…)/é”2ó&ؤÓ!µ´„Øâ"*ôzxâql•$Õ}7ïm+,D—× W8Œ“--¸9>Ž“IÓ_}W,†í%ëpüçqñÁs8ò†S¿Ãh¬G:}¹¹zäå™J +³D n––RX\ŒA¯¯@<î$mUÝÇÝ(,ܯ· á° --'1>~&Sƒ¦ŸuýmH&“cÄ… -x¹¢"cß¿=SS°É2‚d@𠓇Ï62å&ådFð3»°€*ƒNÎojûÎÙYØŠŠpÙãA/ù<ÝÚŠë‘vhú«¢ofëÖ£óêe|\‹÷ß¼ÈÄmȲ Wxy)b17™)WøYX˜…ÁPÅ™SáMmvÖ‰¢"<žËä³­­§‰\§þM?ËúF£ÿ_ÿ¿&œ?ÿ^±X2W@ïä$ÍfŒ$“0s~>x®'Sòf!3Iz”?q nç=µ}7ùi(.Æ%·wÆÆp¢­ wyÝÉÌÑô³¯ïŠFa{~>¶‡ÏFôøà÷Âlnä³!äç›—åzòæ!3z’¿¨r ÊòvÕý™7Š‹àv_ÂØØ´µàõ.3g§¦¿ úñx?ÿ¿…8wn^(/Ï|¹w/œìÏVv¯û˜Ž<é碛YÙÑúÙß6 ½¼Œ8ùÙÌ.'f5¼§¶ïc·³Ò ®ø|ð°v67£›þP§é¯Š¾—Ù\_\‚S¿ØñÕÃ\¼ýú%LþÙKï¶²…ȃŽ~nTº™$YÙßúQP°ËËiòg—Û¬Ì$©Fu?÷Ñ ¬ðù®°zÐÜ܉ÉÉnê×iúYÖ7jy pñâ«Ø]U•ùéàAôOL –þ?A. dÁ@?â¹’œ 3/*èùsìoQö·R22ÈY5ï©íèÿ–’8\.tŽ¢³½}¼ZÙ5ýìëÒ‹«×—âx×·85,áÃ#×0é§ÿ×’‹ ² üÜÀó9«d^ “‹ ö·9ö·(¹)ål÷ªU÷£ÑJJ,p¹íF{{'¯}ìŒVMôc±Ìßbœ=[ówþîÙ£äo­ðÿ¹9èrržêÿ úÿ¦'ý_eÿQ¾8Vòåè“ù¢ég]ÿqþþjÇ×óð–Èß)‘¿µ˜› ñÙÿŸÿ'”o)ü_mÿŸ|q¬äËÑÇù¢égWÿQþ®YcTò·µº:c?t}Ì_ÁT$•‚Ä>&ÑÏdÄÂÙßµ*õz¤Wü¿ŒŒ ÐÿkÄ>ß¹þ½ïg¾T1_ìN'zB!ëè€ùRÇ|QÛ×ôŸ­¾’¿JñÉßàÓa>zï7ŒEú¦R©û˜D?—ÈH€3ñ®5½¾’þŸ^ñÿ2úÿïÕðë¿ûѨŸùR§ÓŽP¨ǘ/>æK꾦ÿìôeÙB¸¯¼ÿž9cEciiæÄ®]Šg‹ïšáùyÐÏÅ7áíb #eôÑßü‰,ðsfyʾ_ô8“ ·‚AøÉÒá¦&ÜL‘;M?ûúƒ"›e3¾¸{]ãkñÚîÓˆÎx”ïšóóa>û囈ðv1K&ôÿ2¥¿--%”,H&ýÊwµýD“©Áà-LOûÑÔt˜×{ä®ZÓ_ýTj„3 Ç»ø ¤Ž* xœí˜[H›gÇÿ§hNÆè~ ¡+*ø{ h AAÈT­ÑˆÐÚªÉ^¼@ŒŒèu:x#4pO®Þ¿ºŠºª*ŒÛl¸ïõâÄÐæÑd2)úyÐ÷­¬ ¾¶Ã#ßáìŒg>¹ ¯R}a¡V”“©ŒÆZ¬­… ÑT y2ƒN§G$âå^ƒlýêªUUu°ÙÆáõÞÇÐÐ ,.ÎÃdjRôó ®   ÃÃØßܼõÍp³V ½[]P×c ¹™N&QÏÞÞÜDœ«‘±Èíäž\½‡¿i10æñÀE_8ÙÓƒGá0,äNÑϽ¾›çxWE%¾üý®-àØ‘kX^™„Vk¦¯ûøß«¹tŒÈÉä4{C=67Ó\qÆRN£Ù)[ŸHx`0XàñŒ!r¡§ç$ÂáGä΢èç\ߌõõص¸zõmô·¶n= 'g¹ÎòrøÉ…†~nàŸ&gfæžÒÿÛÈE‚ìˆym;Ϲ›¹2(W?E/°TVâ¦Ýއ>Nâ ¿]¢÷(ú9×÷°¿·W×âÌðÅœ'>‡?èDyy'¹ðÓÏ5ôs9›fÎLÿJ.ÚÈNBš×´Úí̹É`‡l}$2…ÊJ ìö›ðùbpð4¿Oغýë fiW©*páÂ.¼ºcÇÖO‡á/þç]ôÿùT eôr=™˜åXä\䢑÷µuòc“o)+ƒSx<9’«wp¯“,Þp¹`p®¯÷ØgºõzE?úöX »+«ðùo¿àÊB1>zïW,- ÿïB*5O//#zúø¬”K$\¼¯5’ŸuÎp1”•µ'9Ú%[;Èb'\®ìèë;Ç>sz}·¢ŸsýN©7«T:\¾Ü‡×[Z¶FÆÃåeXéçÏÈ€àÁ@f[É”ƒ<4“ÁO”þ/zÁ$s‚7¹úÉhVÞ¥¯;°‘Ïóýý¸ b¢Ÿý¿Ù›÷VUãÔØu|ý¬»‹àÒŸôn+xöÆ3dÊŠXÌAfš%~2™¨Ô b±I‰7¹úht’wi+œÎëäÓ†þþóïP¢Ÿc}ÎÊóëæùÕãÒ¥×ðçç±#G`ãýk/g¯91‘‡r11î"SNòÖJf’ôþ—ˆƒ»¹'Wï ?Ý&F<öûqv`üîcÏQôs¯oç|n}©Ÿþˆ¯æÊðéwÙ8«íå?GÄmz½¬_ýÙµ5˜ëêñíÐÏø~Qƒ/?ù¡hµµVd³q(jTU©ù¾®Éä"ÔêCØÙÙÄÖVM=k³\3Kö'ó0MðxÆ =‚Ëu–Ïôz›¬_ýtz ZðzSSþ‡¾>¸¹ç­‚€››PVT@ Ïs9ØÈJ\4¨TÈ‘Ÿìö6ð=Àš•kRýþL6zÁ¨Ïo,†®.<¤?Øeý²èû¨ßn0â»ß‡ñ㲟úñÕ'„Vln¾àÞ+É„€\î9Y™ B¥j ?9logù~€µ×¬’ý™ŒŸ^`ƒÏ7ŠXÌ‹®®Äã©o—õK®oÅÆÆ<öìpýú;è6™òwOžÄã•¥w/ll º²µôó2Ò¡Õb*Fsu5ÖÉO’þoæ,˜L¥p„kRýO9nOOc"Æ…žLD"8&ë—EßMýïÔá«‘Û\Rá³þF$ö˜Þ}”{¿€ÊÊjúy-™VÛA?ŸBuu3ùY§ÿ'9 ÌH¥&¹vD²?™| ƒÁééÛ‡'ÐÓs‘ÈõÉúeÐý¡¢B‡+WŽâ­ææüÝ'ðhuîýR‘ý|ŽïŽšxÈOùÙ ?)òÓB~ܬupMªßM¶Ì‚wÈç$¹¼ètâ^4ŠÃäSÖ/½þ$¿ßW÷ÖáÌØ\}¦Ä§ÜC4þ€{ï K ßçPSã ?òÓD~6ÈOŠü´°ææZ‡d*åfù¼C.'át^D4z|–õK¬/¬¯û8µ¸zõ ¼Éü|ëøq¯Âé÷G™Ÿ'ȃL<;©èç56¡­àç*Uc1¿¥ ,e2¾BÞ–êO§½Ì‡væÃ!r9…îîó̇÷©ß.ë—X_£±ó9[ÈÏ×®9áliÉœ:?ùi%S‘õuhèçy˜eïHæéç&z¾èÿkôÿž±¬Ù¸&Õ?“HÀb4bÄãÁ8óá@o/¼¡Ú8sdýÒëéÅÖºz|3ô ..©ñÅ鿊Šg²Vzw„~®!óØw$Éä<=ßTôÿ52ÒÀZ€k6ÉþDbF£Ïóá8z{ y9sÚdý2è§ÓÏXÓãòe^;x0³¯qÏéÝ¡—îCDoïHÄsÕ>¥¹ÝÝÂýÉ~αfæšT€³ÁJŽÆü~øb1œéìÄ8Ï×6Y¿,úâ¼¶ë ¸ôÇ(~ú§¾w +«nú¹xzé>d¹p"ž«”Ê}ØÝýÿþd¡¦Ñ˜%û3‘-+üþ1Äb>tvžÁÊÊ8õm²~‰õÕj Ÿ œ¿ܸñ.œ&S~¤¿^Îß62¦Ÿ‹ÿ#´Åû ksôzñÌ•-þ¿ha­•çe©þ ç‹•óeXœ/œ+ç\.LóÙÎù.ë—^?@/¶qþ~Íù{‰ó÷sÎßpÔK¦DÿÿGh Œètzý\á̵³“-þ¿hdÍÏór«d"ä|±r¾ s®ŒÃå:Çç4ç{»¬_b}­ÖBXä7­Çà ÿ%(*xœí˜[lSuÇ¿ì"k{ÚÓ]¶[wé`+ŒìÍDƒY\F–eú!!Á ‰¨ ê‹/*#x "áyÀ˜xIŒ³£AH l"£mÚîÒn+ЭÝÅuëuË.õû?$zð‰îé<4çŸßùåûr>ý~¿ç¼¸eKæû}ûðÇô4êFÜO§¡ÏÍ…)/é”2ó&ؤÓ!µ´„Øâ"*ôzxâql•$Õ}7ïm+,D—× W8Œ“--¸9>Ž“IÓ_}W,†í%ëpüçqñÁs8ò†S¿Ãh¬G:}¹¹zäå™J +³D n––RX\ŒA¯¯@<î$mUÝÇÝ(,ܯ· á° --'1>~&Sƒ¦ŸuýmH&“cÄ… -x¹¢"cß¿=SS°É2‚d@𠓇Ï62å&ådFð3»°€*ƒNÎojûÎÙYØŠŠpÙãA/ù<ÝÚŠë‘vhú«¢ofëÖ£óêe|\‹÷ß¼ÈÄmȲ Wxy)b17™)WøYX˜…ÁPÅ™SáMmvÖ‰¢"<žËä³­­§‰\§þM?ËúF£ÿ_ÿ¿&œ?ÿ^±X2W@ïä$ÍfŒ$“0s~>x®'Sòf!3Iz”?q nç=µ}7ùi(.Æ%·wÆÆp¢­ wyÝÉÌÑô³¯ïŠFa{~>¶‡ÏFôøà÷Âlnä³!äç›—åzòæ!3z’¿¨r ÊòvÕý™7Š‹àv_ÂØØ´µàõ.3g§¦¿ úñx?ÿ¿…8wn^(/Ï|¹w/œìÏVv¯û˜Ž<é碛YÙÑúÙß6 ½¼Œ8ùÙÌ.'f5¼§¶ïc·³Ò ®ø|ð°v67£›þP§é¯Š¾—Ù\_\‚S¿ØñÕÃ\¼ýú%LþÙKï¶²…ȃŽ~nTº™$YÙßúQP°ËËiòg—Û¬Ì$©Fu?÷Ñ ¬ðù®°zÐÜ܉ÉÉnê×iúYÖ7jy pñâ«Ø]U•ùéàAôOL –þ?A. dÁ@?â¹’œ 3/*èùsìoQö·R22ÈY5ï©íèÿ–’8\.tŽ¢³½}¼ZÙ5ýìëÒ‹«×—âx×·85,áÃ#×0é§ÿ×’‹ ² üÜÀó9«d^ “‹ ö·9ö·(¹)ål÷ªU÷£ÑJJ,p¹íF{{'¯}ìŒVMôc±Ìßbœ=[ówþîÙ£äo­ðÿ¹9èrržêÿ úÿ¦'ý_eÿQ¾8Vòåè“ù¢ég]ÿqþþjÇ×óð–Èß)‘¿µ˜› ñÙÿŸÿ'”o)ü_mÿŸ|q¬äËÑÇù¢égWÿQþ®YcTò·µº:c?t}Ì_ÁT$•‚Ä>&ÑÏdÄÂÙßµ*õz¤Wü¿ŒŒ ÐÿkÄ>ß¹þ½ïg¾T1_ìN'zB!ëè€ùRÇ|QÛ×ôŸ­¾’¿JñÉßàÓa>zï7ŒEú¦R©û˜D?—ÈH€3ñ®5½¾’þŸ^ñÿ2úÿïÕðë¿ûѨŸùR§ÓŽP¨ǘ/>æK꾦ÿìôeÙB¸¯¼ÿž9cEciiæÄ®]Šg‹ïšáùyÐÏÅ7áíb #eôÑßü‰,ðsfyʾ_ô8“ ·‚AøÉÒá¦&ÜL‘;M?ûúƒ"›e3¾¸{]ãkñÚîÓˆÎx”ïšóóa>û囈ðv1K&ôÿ2¥¿--%”,H&ýÊwµýD“©Áà-LOûÑÔt˜×{ä®ZÓ_ýTj„3 Ç»ø ¤Ž* xœí˜[H›gÇÿ§hNÆè~ ¡+*ø{ h AAÈT­ÑˆÐÚªÉ^¼@ŒŒèu:x#4pO®Þ¿ºŠºª*ŒÛl¸ïõâÄÐæÑd2)úyÐ÷­¬ ¾¶Ã#ßáìŒg>¹ ¯R}a¡V”“©ŒÆZ¬­… ÑT y2ƒN§G$âå^ƒlýêªUUu°ÙÆáõÞÇÐÐ ,.ÎÃdjRôó ®   ÃÃØßܼõÍp³V ½[]P×c ¹™N&QÏÞÞÜDœ«‘±Èíäž\½‡¿i10æñÀE_8ÙÓƒGá0,äNÑϽ¾›çxWE%¾üý®-àØ‘kX^™„Vk¦¯ûøß«¹tŒÈÉä4{C=67Ó\qÆRN£Ù)[ŸHx`0XàñŒ!r¡§ç$ÂáGä΢èç\ߌõõص¸zõmô·¶n= 'g¹ÎòrøÉ…†~nàŸ&gfæžÒÿÛÈE‚ìˆym;Ϲ›¹2(W?E/°TVâ¦Ýއ>Nâ ¿]¢÷(ú9×÷°¿·W×âÌðÅœ'>‡?èDyy'¹ðÓÏ5ôs9›fÎLÿJ.ÚÈNBš×´Úí̹É`‡l}$2…ÊJ ìö›ðùbpð4¿Oغýë fiW©*páÂ.¼ºcÇÖO‡á/þç]ôÿùT eôr=™˜åXä\䢑÷µuòc“o)+ƒSx<9’«wp¯“,Þp¹`p®¯÷ØgºõzE?úöX »+«ðùo¿àÊB1>zïW,- ÿïB*5O//#zúø¬”K$\¼¯5’ŸuÎp1”•µ'9Ú%[;Èb'\®ìèë;Ç>sz}·¢ŸsýN©7«T:\¾Ü‡×[Z¶FÆÃåeXéçÏÈ€àÁ@f[É”ƒ<4“ÁO”þ/zÁ$s‚7¹úÉhVÞ¥¯;°‘Ïóýý¸ b¢Ÿý¿Ù›÷VUãÔØu|ý¬»‹àÒŸôn+xöÆ3dÊŠXÌAfš%~2™¨Ô b±I‰7¹úht’wi+œÎëäÓ†þþóïP¢Ÿc}ÎÊóëæùÕãÒ¥×ðçç±#G`ãýk/g¯91‘‡r11î"SNòÖJf’ôþ—ˆƒ»¹'Wï ?Ý&F<öûqv`üîcÏQôs¯oç|n}©Ÿþˆ¯æÊðéwÙ8«íå?GľçrlsFÙz¯×A/0Án¿ —kUUXX¸O}sTÿëá÷!&F‹«W£º°0|ëØ1ÙzçRS-èïoÆìl7jkÏan®›ú¢ú; /üA¡ÐãÒ¥ýø¨  |ëèQt>} ×~2ƒž~>ÊwKRlä'ŸüøÉÏ2ù)"?½«àœ\}/Ù²0 Þ Ÿ=äòBM îÎÏc/ùŒê¿yýîßwv§ãTÇ \žJÄ7ŸÝÅüÂß\{ y˜”xˆ‹Óó}IIòc#?ùäÇO~–ÉOÇz9W![¿¼ÜË,(ø¼A.{PSsóówÉçÞ¨þÖ×j-X]µ³ÿêpùòøùù·#GðùÙ̵ŸfS2%ÑÏeÌt"ïeGòÛ ó›`Id4‘·åêÈ–™ù°•ù°\ž­®Æ=æÃò¨þkÕYYdf±E~žb½ÈàýÔ›ùù‡ß[ñót<¾lhg~î&ff°'äA)å1¿JÊt"«)•9‘ü¶"±äõÚ¥¼ˆ³–’þŸ$±¤Õ–‘­æC3óa+¹ìCuõYæÃ{Ô/—­ýB©ÌŽê¿}ÆÌ爔Ÿ¯\©AMQQ¸ýøq8ÈO)™š[]…Fð@~F˜ÇÄÉý¼ž/ü‰þŸEn9fâœ\ý°Ûƒí6º˜ëê0àt¢Œ='ªÿêú"—0IwUÔ\Ü_ }ÇJ©áì÷8ÖOsOçp Ó‹s32q¾å:ÎŽkÐxâOÌÌNÒÿóéÝnî_ âùîäX&ÇÈLaÄÿ—ÈHÜn;ç̬™å^×Hüø|ÏïTÜîa %°ÙÚ™»PW×§s€=§Œõs’~|¼ößzgŒ=å¿úÏ çL²õQý—믬Lq,/šð~^^ø§úzظæFz·ó…ûÑ Ä‰à(31­-éþ$‡½@Œ ¦äêÉ‘‘œv8°»\8UY‰.ž¯MQýWÒOˆ‰‘êç××aa¸«z+!žµ5©ÿæ²ÿŠsïkí\·4þÌùYþ-z³ƒù<]©BóÃNÜYŒÅáONÂëû· ëë‹ôó]ôï]ä`˜¬ñWÅý›MvV¥3˜V[Dßãx)ù™D8 ~Fµ5§tâõ ¶Œp8:àrÙQYyŠÐÅÏ™ :_¸o™–êŹ-11[[Û÷39Ò˜FS,[Õÿ}µº„Ïq®Ÿ×®}ŠšÂÂp{CØËÈÊ,ý_|¡ÛöŽÒëÅ™Ëñÿìmÿgo«b1²7´‰þ¾rÆjE?Ÿåì Qý—ë?aM:÷`÷ã}Žè ˜‡ßKOÇnæk/ÿGª8ë²n†Ù»ed-CC˜ážUpßoq³•¤¥á«ï¢}І;n5>>xŽë¿íŸ„-JK­ÈÏ?„¼¼2)[+!éþ$Ò`zºUºõ#-­‚õ»ðìÙóžàñl÷—6ö•.X­gøìgf,ôkñ}‡NbP¯/aý¨t¦ …|‘ïG²9æày¼T¶Þí¢¾1ª/£¯Ó•Ð&¸V)hj2ã—õ)xœí˜‰SÔçÇ¿À²À,§á¹/kÇØÁ =°¡0ŠG¢5Z¯GSM:µM1™jMŒ¶±t¢ñŠ˜Xâ˜HŒ Z¥Eã \]NE¹AXv—ea—£ß߯ÆÝüËÌÎïå}Ÿßw™y?Ïó}RfΜørÕ*<èïÇ,¥M&Èà*‘ yhHÜ«D‹ †ÆÆ E¨LµÁ€8…Âj|ÏâÝÝq¹º•Ø—–†ÛÝÝHpuµé[ÑßOý›]]˜Ã½>¾_ªÑàdI êµZØ;:ÂL] ÷•üŽm/¾ˆ_ÍžJñÔ²·Ç¿›š°!'ã˜!—ãèÊ•X…_Çñ)vl»ƒÞ¾ÈÍýššŠ üÌŸ¿))oÂÞÞ:]ŠžÝÅ7ßìÁÐvvFPfóÏü1oÞ6„…%B&‹@)<=¡V®®J¤¥íCw÷m¸º&Àdz $Wê4C©œ…ÁÁj¸¸all££zj„Â`PS7Îj¼ÁPw÷xTW_Fg§Mj|<ŒÆzÞ›'N¤ág¡¡ùkÖàþÓ§HT©ÐBÆÞTä­‘ëD2[¥×#„L |ê,D‘ î <[‹¯ [‰ÈU«QF>³ÒÓQD>gÛô­ê`þÞïëC€TŠÕ/âóqëܹXš”„dQ_5>Žì°ÿî]$úûcÿ¦Ÿò¬žµ€Œ“'Ñe4⇾¾øxùrD»¹cϵK8ñØ¿}ýŒ¦ܺu÷ïówÅŠsð÷"7áÌßJäço‡FS‚¹s·"9yÆÇ[E¶úûëPZzŒŸOàçÏ÷¾âÛ:ž…‘ϯÉgÒÓ³˜ÇEP©f“±–g¼©¸n$³‰Ðë«ÈdˆÈ§Å¢ƒ\Á½ ‘gkñ:]<<„úkÓŸ¯T&2k˜¿®8~üÇx9<|âêúõ(ëíÅÜÜ !ròæÆº_Ïõ,2«&oádÒHÐò#¬“xf-¾j` žž¸XU…ÒŽ|°p!ò)ø‹Mª~ u÷-Z„û­­Øž›‹;mm8ÈÜÜš’‚jÞI=ö?ÔŠ¤—;ÑÿxãþRXˆPþ-êÍ›¡³³Cý?5;[ÌßyÌíOV¬@¼× ü)ÿ ÔÈðöonB?(äïaܹóW1W¯ÎCPP’迟~šŒööb¤¦¾‹—^z›§ hµå"o&“†… ¸ø._Þoï$¼úê!$£¼üKòù ~€ŽŽ‡ôœ9dKCÞäptt}B¥šEžÕd2œÞbäG+®ÆUª$«ñUô÷TU]¤n©MZ¼ÁPÇ{sÇáó1?$dâ4û­ öÏ1d¥ýž ySÒ/„Þ/†ÜÔ‘gg˜èòLŽ„½(žY‹¯¡'İ\©©š}çî PLcmúÿ§_E_?‘_œ:…{Í͈ À¯½“ÙŒ¶áañNê©åçä#}VÊ:ðÎ¥K¸NN ÅþÅ‹Åü]{æ ž þNOÞ»d ¢Ý=ðáõ|œkuÀë/À8ô÷îAII¶˜¿Ë–Ahè\ºô.®qýî}Ä^®]ô¹< Ãí쥥Ìá0œ>ÖÖJ&`ýú2Ï¡§§ ìFoo1½!–ùÞFÞ\èJ±÷S(b¨Ygçzº‰|èùÁâžBe5Þ`¨›[ jj®°ïTÛô'ÅËåÑ|6Š5ö³Ï–"#"b"oãFÔõôðÎÝÑCädMNNš¸#gÍô‹PzÊ0ùѲ?ô%ƒ ܋䙵øFÎmá^^(¨¬Dq{;vgf¢–ÏöŒ6ýïôóÊËQϺ™ŽØ#Gļú;½þ-öμH41'ë©mO­ÛáçgÏŠñǘ«¿ŒEDVzŸÌü?Ãzâýö^>›Øùæ¿0`èÅÍ›q¾}O|oÓ¦‡ìÑÔÈÉY+þ¾reââÒ¸×Ê\ ¤‡4ÁHrÔÃZïĺ¯âû{qåÊN1~ÆbòfAcãU,Yòý»–=cŒ/‘~!纉aÔj&w¡ì‡ÙjÉ¥ïýéñZm#¼¼ÂQYY ö™™»mú“âõú'¼O:…dúï?ØoU)Á„šïboÿÜ/¢¹'ô}¢¿Ïçþ½(2e-¾ö™¿ÔÖŠþµ+5õ;ÿ²é?×Ï«®F;gÛ.þ~¶‚ý=öcÞE8먔}që4ý!j0w™Ç/sÞ5ñˆƒì¿—²Öò»è¿ïÓ“£ÝJï-"2úi>ë¾ Ìf-Ÿ‚ÿÖ=óß6²â ''OzI1.\øFFtˆÍDt´àÇÅô—??÷—ÿÅOö—hÑËûÎ_¦êO7jEÿª­-ý+5u—MR¼0ÛÙ)pêÔ+ÈˆŠœÈÛ² Ý=ˆôpGï ç5‰dô a3ÝÝÐ2 CYã|g¶ÀG©À#í"xf-¾¹_‹Poo\-+Cq[;v-[Šºö6DÓ¿lúßê{ázE% 5¢H£Ayg'æúù!ÿõ}Ÿ¾0_3g}\•H:ð7TvvÁƒûåolÁŽCë@2óùóµkì=ïçžEV£ »~/ø¯……Y(*Ú#æïºu7è¥o±ÿ­†O"¶o¯ +Býד³ô&Îka¬ùOÅùK*u!S­ÈÎ~…³\ ý%))ïpN{‚Å‹wÒ_è/‘b¼D¢`Mp&Ç-Ô¡—}_0ù´ˆõaºþôøþ~ çì™(+»†¶¶{ìëwÙô'ÅëõíÌiÖçW¹Oü::-ÃC:¡oÔÂÚogzÆÓQ3üù^»ežG˜9ß OŒÃ›ë6îù;Zo3ÃßÙê¾^´ XF“úÎ6ýgú~NôhíSÔ ô¡E¯ƒvd2–GÇÃv¢g[Ó7Qÿ‰‡ªËÐ9d„3}}Cô,œ®¯†ÁbF \‰E1ðs–áFKn¤˜¿–Ñ>2ô]]Åbþ†…eâÉ“Bæë çÝì7‘&&FÈ‹÷;ÈŒ¯øÿ;;GÑƒÇÆ´¨¯Ïcýï`>+™÷óx>Œ  âÿ¹¤R¿)ñ£üNAÃb颦;ûm3õ‡¿WÿÛx³¹“~䃾¾ZÖŒ§S¿Ù¦ÿ,~t´›7H>ÕÙø/L2xœíXùS”÷~`—cÙ{ASXûÐP£¦f"V§–‘¡C‚™±aƤ8Îô—6µedŒGÆNP4Ú8NEcEÉ€ÜÅÁ3’Ê-·0 Dzœ‹{À²l¿ßob»í_°ðþï»Ïû¼ ïó|Ÿçóu“yØ…kV`Qk…‹ˆ »e.®Ü\`7‘cvƒ .>ÑÑ ¸¸¸ ""ÃÃc°ZÀç{áÝw0;;›Í//O &…|X,³puå€Ëå`nn ¨ÕZv¾r¥ÜÜÜ —C£ÑC$zƒwsãÀDžI¯Q.Ï“q/,8æ_Š×ëéw^P©Ô Jžéä7ÍäÿÏEKK¢Ò¢ì˳198™\£Æ®€ËÞ‹Aa€,D R ~¶Eæ5óy ¡ÒB&qˆ¥Ð`EˆZkŸCùL‰=9»1: „w„“ÿ ¿7:žv¡íz;†A3¤AÈûÁøô_û‰×wwwÇü¯æ!]!ŹÎcøû¸ Ý‘Ýô®oûºQãø]á>øú៹·À«áãÁ³ûÐé ÈËû ¹¹Ç™ç‹‹ïâàÁ˜œœDrr2𛛉—mD{:x{Ë044‚°°UÄ—:¦•êöîÍÄýûµÀáÃGˆ§çðùç"¾$k‚|^¡P"$$Jå8‚‚°¸ò½úò¿Æ+£ä3µµðìÙ¿‘“óW'ÿüää4d2Y7CúËP{FA4í£„˜#~'k=ÕœEa ZcŸžžd}_Ä‚q¼Œ½F"ñ†^$Q¼¨y©î)lÍÙ U£ Âh'ÿRþÞÚ^Œ6ŽBÙ¬„ªOY2ò3à&p‡ÏqÌo y)çãÆÎ˜~1 ¾˜n~„¬B˜gÌX™¸é'Ò!‹‘¡út58–B1¬À­[·píÚ5æß‹/âܹsDWXµjÊÊʈwõdm7²óÞÞ^’‘ƒ§§'ÓõúÑ£GÑÙÙ‰ððpdeeaddÇŽCSS¢££žÇã1¼B¡`×úúúHò}–ñ‡„„,ãO¿‹ŠŠBMM º»»‰þsÐØØèä'xÊûòåKvž‘‘ˆÔûþªý˜îš†$^Ó¸ \>É ±Ó Õ™¶Ÿ¬ÿ«Éúo´Áª±B,€¶G q¬Ø!^Ó«w4É—ÊŒ5Œ1=uŽAš uò/áo+kƒº_ í°Í_7ÃtßOÊ?ÿÀ0õ™–ñSïÒgpVp’Äò÷äø°ìCœ;ó´ï"óz&|#|Qô—"jxÔðˆyïÂ… 8uêóokk+Ž?Žòòr–õƒƒƒðñña8êßžžÄÆÆ’Î=Núœ$ ó(ÕÌðð0²³³Ùqmm-㤞NHH`x>Ÿ±XÌtIõÖßßÕ«W3mj4/ãOµKu]YY‰††œ8qÂÉ¿OßÍ߸¸8„}fÿ¸øc¨›Õ&a±€Cæ7.™õ̃fvÍØmd™b3“~®_€—Ü †.q‡xC‡Òx)º+º1Ñ>íg¶cªn ¢D‘“ gi't üýQ˜YÈ|µõðV¬ûlæmó˜SÌA ø™ßJædùRNáfÚM†Oû" á¿ Ç7Û¾Emÿ;þØý·ÝðNðFyñæî¨|T‰AÒß pùòev_ii)óãÉ“'Ù9½¾}ûv¶ÆS-uuu1}Ð|õðð`ù@ï?räѾmÅÓ§OqöìYÔÕÕ!11‘á©ßE"ÓÕ,Í š)f³™e¼\._Æÿ6¾££ñññ¨¨¨@{{;Μ9ãäÿ Oy©…B!{_ò_Éíûªöa¦aâ$1ÌÃæõ&&z0C”$‚¾C¯P/¦O«Îʲ@ߦgzv„×µé K’¡ën&Z'š—ŠÉÇ“¯uò/ã/éÂxË8Òϧãòû—1R7ß0_ìÿa?lvó;}&åç­â1nOž'*ÿ\‰ŽÂÄeÆ!ýËthÉ|\ðÛ–¿¿Àž {à“äƒÒ£¥ðøÞ뢿¯W¯^E~~>óßíÛ·±~ýz8p€õ¼ 6àÎ;˜žž&sZË ª7ª:»Ó,زe žþœéæ1͆ªª*ìØ±ƒyûÊ•+HIIAqq1Û÷:}ú4ZZZ}í{´oÓœ ùB³„Þg2™X?¤ÇTŸkÖ¬qˆ§z¦Ú-))aÁÉ¿Oû¹T*eï'tS¨=óÛL¨ÛHŽ!ýYIúä…˺Ÿ FÀöb<ƒ<±hùqÿ„fÛŸ‰8Äz ÄHÐS݃©®)lËÝU½ŠiÑÉÿßütL×£ƒM`CÙÊØZ‘š€ä½ÉðÛäÇææ9ëšÿÑŒ¶’6„¥„!%;¾ë}a5cÞ2ë™×ayeaûWç2 £â‹ pë¹(®*ÆøØ8óï7˜/]ºÄ4F×}º·Bgaª»ÔÔTæaš¯s€ú•ι7nd÷ÍÌÌ0Oß»wå4õ}}}=Ëh¥RÉö[h¿£Ý/&&†é-((‹ƒáçý1:Ë9ÂÓ|¡ŸÕÕÕLÛNþ7x:WÓ¦ûW»ví ©)¡xœí™ILwÆ?À63cÏØY„X‚ 6K€(©ˆÒ´Šª6ÍZå€rˆ*5JOUŽí¡ D%—ÜzL+õPµjDz`«ŠZ‘68ƒÙ1ˆYLc{Ìx+8î¼?1ŠZ§í¡ÉÉ–¬‘ÇÏ?Yúï}ï½±¾kM^ê¸ß„’M‚âS á4ÐrZ(b©ˆàlÜ~‰X ðù<‚SAˆebÚøÀL;-;áêvÁÛïÅ™«gà÷Âd7eø/à/º±§j”€‚Á¯áüÖ‰èZB±€Äz±H ;rw þ£zÔ_®‡üHFî¾\l¬làÁ—Ðói蕥ɹ/ΡþÃz|÷ñwàáqgàz{{qùòeÌḬ̀¸³gÏâÚµk¨¬¬ÄŠ‹‹qóæM\¿~:ÇÁëõÂl6ãÊ•+8~ü8ŠŠŠ099‰òòrtww£¿¿W¯^Åøø8ìv;|>û½=JKK1;;‹ýû÷#‹! ??SSS(++KOÿÑb±dø/àÓyљД¼^’lü¦~§B…€Øã²uÙÐDç£àí<” úB=Ñ6•Mè÷ꡌ+àm|Úøõ±uHv £]£Xu¯âæwà»çƒP™á¿ßïcñqo\‡¬Ü,,ö,")$Ùï̵fHžÆžF æ‰ÁãöÀÓã¹ÜŒ¶OÚÀýÌ1ÿAuu5VVVX-§ó'UTT`xx˜ÕõP(ÄÞ”£¤)ÒÊââ"²³³a4™njkkñðáCvmkkÃÀÀólº>|˜yD^^$Iby^SS³Í‡Ãƒ¬V áàÁƒiã3üæÓ¹‰¢ˆC‡¡ô­ÒäÅ/â÷þßa¬Uõ6·¥7¨Ad:C­!—ªÏUŸUŸ²ªO+‡3C!m¼ì”aª5aäö–‡–Ñp£+}+ëÄ ÿ¿ò„§ÃŒÁêñÉßåÍ¿ñ™¿«ñ‘™»Gü=¯íÁÿ€Ü;¹èêï}¿âÀxôèÓå#iƒ¼Õår¡¤¤‘H²,3-‘Sñ”珞ééi¦KòaºÞ¾}›éìÆèëëc¬¹¹9Æ>þ¯|«ÕʤÅtñþ?óGGGÙù;v %o–$/ܺÿ †J¢ Qd볡5h™6„*õ{ú¢gýah“ii}tõÛéâCî¤Jµ?lÅÊð N´ž€ï®†ê ÿÿäój¾cñƒÚŸÏEY¼<,cWÝ.´7µCû›]½]¬®ªªb³“^¯‡Á``Ú {TÏi®¥þü—´D!oNO=!õ‚íííÌ;Z[[q÷î]æïþËå—fcêŸ`m°&?èü¾1¤ áå0rxµßÔ~lJa;˜àLœ…ÛòÿøBÁñ D»˜6>0ÀÎòpuº°äXÂéæÓðº½0U™2üWÀ÷Oø‘oËÇ÷Ÿ}î'½ŽÞí^yyy<ϳóOíHRûªÿ~¿ŸÍb©}KºøÔþª³³“ÍÉ4ß‘fI‹þËçSODûú~ßÑ}ÉÆ¯áwù!ØļÏí[T/  ÍmºžFŸnígŠõì_Ƨ__‡h1Ö=†ÕÑU¼Ýô6ÖklnËð__õksµ]Ÿw!Ç‘ƒ[·àt²y–öÉ©}ÕvºGz+((ØÞŸÐ.šî‘VÒŧv+´_%Ÿhjjb:%=eø/—OuæÊéóçÏÃÒ`I^꼟۱J­çKá­çÆ­}‹X®Öÿé ›¹ʳç#Ejý ÂXaL˜PýŦúK‡ ^‡gZÎÀ;â…T-eø¯€ïWý×®ú離ÿölùoªþ/--±y–æ§”OÐ\E3i‡ž_P/—òëtñ©ÝVGGÓeKKËö~,Ãù|zÞDþK½ôŸˆRÞxœí˜KH[YÆ?L¬yÜ$7ji#¢6&ÑøŠén`¤CéPJ]µ …Ò…;wÝÌŒ 3ºs;0ËnZèD¨3¦µE1Ö“ÄGâ“hb,yÞ›XŒÍÜsZÅÜa 3fu!7'¿ÍýÎ÷ýϹôÕ¥â_ï ñ6M»ùíÚÚÚ099 ¯×‹±±1ÌÌÌ ££CâŸ1ŸpWWW¡ÑhÐ××ãׯâ]Ç]¼›M‡ÜVî£t‚Â9hmZd|¨TÔ?Gé#¨Íjd<ê71}Ú“F¥­þ ?¢î(®_Cl:]—Ä/?µ”Â…/.`âá*^WàÕÂ+ÌÍÎÁf³akk‹úA§Ó!Ó5â·††êŸt: ³Ù ÇCý&¦'ÿ‘ ¸ÝnŒczz]]]¿ü`0H÷soo/LߘŠ÷~¿‡÷Ønü&™Z†r¶ü*]»ij“¾€B²@Ÿ‰u:Q}Ê—BUG|vööp}ô:ö÷ ïÑKüð“Þ$.Ú.âéçPý¡¢û—ø¨»»›››P«Õ`Y–æ8É’õ&“ <Ï#™LÒgâŸÎÎNQ=ññ–ÝnÇÂÂFGG±¸¸ˆžž‰_þÊÊ ôz=̓†/Š·ÝFÂ#ÌÏVa~Žó˜RÈsœÎfŒ•·ÂAQ«À‡ü²(ë•tibDõÙ`¬•Ep*ˆ}ÿ>®_Å뚉_ ~&AuG5?: sÉ`wÚá~ë†ÕjE$R©¤ó™ÍÈñCmm-òù<²Ù,êëëéZSS“¨žä?ùžšš¢Þ†ËåBKK‹Ä?c~ss3ía†aÐßßó·æâýßî#¾‡¾Y.ÎA®–£\]nÛÈ"µ‘‚Ú¨Æñ¡0¿%À¤ÖR`-¬¨>N¢ÚT ¯Ó‹]×.n ßÀîò.*­•¿üÄZ‹O¾æ9ƒ®ÔäÝÇãqšçä³¾¾ŽÆÆFz®"g®ÃÃCšÿƒkkk°X,¢zâÒN§“ú’øsyy™zQâŸ=ggUUUt“þ½õèÖÇþmÖà0rˆ2eÙ?ç?W w)'ù/¦?íç§~ú«_$þÙóOû÷'ä.9ìSBÿ.ºéþý·üç8ŽÞ¥|N¿’~úì~‘øÿÒ¿ä7é_Ë5KñãâËqê©\,#œ§!ÏÃBž›X¤×ÓP5ªpœÿ”ÿ5Bþ¯ ùß$œ—cüßôÉÐ/æjxDæ#¸9r»A¡_Z*EõÿÿåŸôïãïCù\‰—ó/Oó?‹ÑÙ‹|Nzâ$׉Hþ×ÔÔгñ˜> Ñ;‡ÃùùyŒŒŒPÏJü³ç“}Lοä}º Å+£Whf“{Í÷Ñ÷(S”Ñ;’ídóPÔ(èüvÌÓ.àC<½GÓs!ÚF-¶f·%pyà2K 0Fâ—‚¿&ìãfs¿Ì¡Â[ñŸÇá÷ù©§¢Ñ( ÇH¶“5â â2¿‘ü']@l' ß‚aOWF¯àÔv U§Jä—€Ÿô&Qmª†uÒ ‰M‚§/žÂaw ££@€ör•JE×tgg'¶··ÑÐÐ@{2™¤¾ µöövA=™+ä¾°°ÇƒÑÑQØl6Zù_–O¾áû÷ïéš¾uë CáÁüœ¸O éÑ L¡œ)ösV ~›‡¦CƒØN±ÿ·1Èóyš×”MJļ1°]¬ >ºEug5œsNÖ¸>~Í8'òKÀø"¨7ÖãÙOÏÀ¼b°¸¶·Ûžž:†˲Ô#Ä;;;hkk£½žäµ¦¦&x½^tuu ê·¶¶¨ïæææ°¶¶†ññqlnnÂd2‰üðI'ó·»»—¾½T¸óÇDÞE 2©p~x‰B‚ru9Ò{iZã=<äÍräÓyä9(ZHº“Pv+õIW1ÇõpðÌzr†049„ðrê^µÈ/?áL ¦¿/~~Šå ¼|ó¶UõÉq …‚f4âR#3‚ôüt:Mó[kk+]ïÄBz—ËE{Áìì,œN'&''±¼¼ŒÞÞ^‘ÿ…ù„KÖ1™ÇCCChý®µpwþ.>®}kf‘>Hÿï¶è‡Ý4Ôf5®zõO6ž¥³ áHP¿ éãŽ8ªÌUpϸ²‡`™²àxél¿È/?öo µ_ÕbæÑ *ßTâõúk¼ýç-Ìf3¨H?ßÝÝ¥5â7½^OýÇé,p8ÔoBzòŽÜgff`·Û155…¥¥%ô÷÷‹üðÉl&ëùòåË0|o(Ü[¸‡Sû)4Åü¼Ÿ‚„‘@ª‘Ò=kbwÇÁäR9ä¢9úL<Èö±‚ú˜+m¯®i‚ëA\›¸†àFÜ 'òKÀ:£¨3×áù£çPü­ ë—øh``ûûû4i4ÚÇIÿ'½Þ`0 •JÑüFž‰úúúõÄoÄ[ÓÓÓX__ÇÄÄ666088(òKÀ'ùœœW“~ ÿF_¸ýûmDÅül,æç£b“û¹ªœf3¥Q ~‹‡¬Q†‹ó ä’9È[ä´Fλ„ôäüDcÔÀkõ"ìãêØUœ®žBÕ%òKÁOx¨î­Æü¯ó¬J0ýröwvFz®Iþ{ ù‹d3R#~ gçççôü„œ“’Ùk éIÿ'w«ÕJ½766†ÕÕUº_ù_–OöÕd“ó«ááaüÎ:·xœí™ÍOWÅÀ–lfl Qdñƒ 6Å XµQUÉBY ,¢HáoH7m 6ü]t‘D`ÒTJÔ€®ÁÆÛ|cÃÇf°‘qç=⨋ÙâÕ,Јç«ßfΜ{î}®]…þ©~k¬n+dA†ŽÑAÏè!oËà9H;˜g8OŸƒµ³6$pMœj}z+*g"3ð ÇQì·ná8p “Gã—„¯ôëÊöJø÷£ÚÚÚ099 ¯×‹±±1ÌÌÌ ££CâŸ1ŸpWWW¡ÑhÐ××ãׯâ]Ç]¼›M‡ÜVî£t‚Â9hmZd|¨TÔ?Gé#¨Íjd<ê71}Ú“F¥­þ ?¢î(®_Cl:]—Ä/?µ”Â…/.`âá*^WàÕÂ+ÌÍÎÁf³akk‹úA§Ó!Ó5â·††êŸt: ³Ù ÇCý&¦'ÿ‘ ¸ÝnŒczz]]]¿ü`0H÷soo/LߘŠ÷~¿‡÷Ønü&™Z†r¶ü*]»ij“¾€B²@Ÿ‰u:Q}Ê—BUG|vööp}ô:ö÷ ïÑKüð“Þ$.Ú.âéçPý¡¢û—ø¨»»›››P«Õ`Y–æ8É’õ&“ <Ï#™LÒgâŸÎÎNQ=ññ–ÝnÇÂÂFGG±¸¸ˆžž‰_þÊÊ ôz=̓†/Š·ÝFÂ#ÌÏVa~Žó˜RÈsœÎfŒ•·ÂAQ«À‡ü²(ë•tibDõÙ`¬•Ep*ˆ}ÿ>®_Å뚉_ ~&AuG5?: sÉ`wÚá~ë†ÕjE$R©¤ó™ÍÈñCmm-òù<²Ù,êëëéZSS“¨žä?ùžšš¢Þ†ËåBKK‹Ä?c~ss3ía†aÐßßó·æâýßî#¾‡¾Y.ÎA®–£\]nÛÈ"µ‘‚Ú¨Æñ¡0¿%À¤ÖR`-¬¨>N¢ÚT ¯Ó‹]×.n ßÀîò.*­•¿üÄZ‹O¾æ9ƒ®ÔäÝÇãqšçä³¾¾ŽÆÆFz®"g®ÃÃCšÿƒkkk°X,¢zâÒN§“ú’øsyy™zQâŸ=ggUUUt“þ½õèÖÇþmÖà0rˆ2eÙ?ç?W w)'ù/¦?íç§~ú«_$þÙóOû÷'ä.9ìSBÿ.ºéþý·üç8ŽÞ¥|N¿’~úì~‘øÿÒ¿ä7é_Ë5KñãâËqê©\,#œ§!ÏÃBž›X¤×ÓP5ªpœÿ”ÿ5Bþ¯ ùß$œ—cüßôÉÐ/æjxDæ#¸9r»A¡_Z*EõÿÿåŸôïãïCù\‰—ó/Oó?‹ÑÙ‹|Nzâ$׉Hþ×ÔÔгñ˜> Ñ;‡ÃùùyŒŒŒPÏJü³ç“}Lοä}º Å+£Whf“{Í÷Ñ÷(S”Ñ;’ídóPÔ(èüvÌÓ.àC<½GÓs!ÚF-¶f·%pyà2K 0Fâ—‚¿&ìãfs¿Ì¡Â[ñŸÇá÷ù©§¢Ñ( ÇH¶“5â â2¿‘ü']@l' ß‚aOWF¯àÔv U§Jä—€Ÿô&Qmª†uÒ ‰M‚§/žÂaw ££@€ör•JE×tgg'¶··ÑÐÐ@{2™¤¾ µöövA=™+ä¾°°ÇƒÑÑQØl6Zù_–O¾áû÷ïéš¾uë CáÁüœ¸O éÑ L¡œ)ösV ~›‡¦CƒØN±ÿ·1Èóyš×”MJļ1°]¬ >ºEug5œsNÖ¸>~Í8'òKÀø"¨7ÖãÙOÏÀ¼b°¸¶·Ûžž:†˲Ô#Ä;;;hkk£½žäµ¦¦&x½^tuu ê·¶¶¨ïæææ°¶¶†ññqlnnÂd2‰üðI'ó·»»—¾½T¸óÇDÞE 2©p~x‰B‚ru9Ò{iZã=<äÍräÓyä9(ZHº“Pv+õIW1ÇõpðÌzr†049„ðrê^µÈ/?áL ¦¿/~~Šå ¼|ó¶UõÉq …‚f4âR#3‚ôüt:Mó[kk+]ïÄBz—ËE{Áìì,œN'&''±¼¼ŒÞÞ^‘ÿ…ù„KÖ1™ÇCCChý®µpwþ.>®}kf‘>Hÿï¶è‡Ý4Ôf5®zõO6ž¥³ áHP¿ éãŽ8ªÌUpϸ²‡`™²àxél¿È/?öo µ_ÕbæÑ *ßTâõúk¼ýç-Ìf3¨H?ßÝÝ¥5â7½^OýÇé,p8ÔoBzòŽÜgff`·Û155…¥¥%ô÷÷‹üðÉl&ëùòåË0|o(Ü[¸‡Sû)4Åü¼Ÿ‚„‘@ª‘Ò=kbwÇÁäR9ä¢9úL<Èö±‚ú˜+m¯®i‚ëA\›¸†àFÜ 'òKÀ:£¨3×áù£çPü­ ë—øh``ûûû4i4ÚÇIÿ'½Þ`0 •JÑüFž‰úúúõÄoÄ[ÓÓÓX__ÇÄÄ666088(òKÀ'ùœœW“~ ÿF_¸ýûmDÅül,æç£b“û¹ªœf3¥Q ~‹‡¬Q†‹ó ä’9È[ä´Fλ„ôäüDcÔÀkõ"ìãêØUœ®žBÕ%òKÁOx¨î­Æü¯ó¬J0ýröwvFz®Iþ{ ù‹d3R#~ gçççôü„œ“’Ùk éIÿ'w«ÕJ½766†ÕÕUº_ù_–OöÕd“ó«ááaüÎ:·xœí™ÍOWÅÀ–lfl Qdñƒ 6Å XµQUÉBY ,¢HáoH7m 6ü]t‘D`ÒTJÔ€®ÁÆÛ|cÃÇf°‘qç=⨋ÙâÕ,Јç«ßfΜ{î}®]…þ©~k¬n+dA†ŽÑAÏè!oËà9H;˜g8OŸƒµ³6$pMœj}z+*g"3ð ÇQì·ná8p “Gã—„¯ôëÊöJø÷£ïÏCß©Gp*ˆ¸/ŽñìÏîCÛ­•øàç|9œî='?<Á©ÙSp½tá•ûººº°½½ •J­V‹ º ÑÔÔ„B¡€\.£Ñˆ@ €ŽŽQ½ßïGgg'¦¦¦àóù0>>ŽÙÙYtwwKüæîÚÚ4 `üÚX¾å¼…7 o ³ëPØ*|ðƒNðC´­]‹œ?U‹Šúç]öÔf5rÞõ›˜>ëÍ¢Ö^‹ÀdqO—'.#1“€®WâW‚ŸYÎàÌg0y5/kðbñæçæa·Û±µµEý ÓéFéñ[KK õO6›…Ùl†×ë¥~Ó“ÿÈ÷ää$<&&&033ƒÞÞ^‰_~(¢ûùÂ… 0}c*ßþý6<`ûXð›lnnB­VƒeYšã$ÿIÖ›L&ðUâùÂóOùŸH$èìE>Ç=qœëÄ?$ÿèY‹øGL‰Dè‹ÓéÄÂÂFGG©g‰?%þÉóÉ>&ç_ò> }†òű‹4³É½æÛø[T)ªèÉv²ÆGy(t~;âŽhðžÞ£ˆé¹m«[s[HER8?t©å #ñ+Á ûØÊbþ—yÔøj0ñóþõT<‡B¡ óÉv²F|A}„”—â<{ŽóÌ9*4È3¨Ô ëÉ;¹VŽcÏ1’$Z[‘ØM@V/ù¥à2`xÿðBº/ŽïïÁwàC]]"‘¤R)d2NOOiíèè<Ï#›Í"“É@£Ñ  B«Õ ê?½óx<Äîî.êëëE~ ø¡Pr¹=Bûwí…¿?@ÈBUs’É$ÊÙrH‹W"˜_Ç#Š‚©e+^ÙxJ•‘ÃøF^P„QS_낇ˇ¸>tïÞCÓ¢ù%àŸúOQßPÇ?=;ÇâåòKø|>477S=˲ ?â‘O~¨­­¥µx<•J…ÃÃC466 ê‰'‰°¼¼Œ¡¡! ¥¥Eä—€OÖqUUýžº/u…¿Ü@ÄÛÎ"ãÏ@"“@¢” ã+öq#ƒÔV ²ò™<ò‰G.žƒB¯@™ÛÉ êŽbŽëâášv!hb`|¡¥TÝ*‘_~ÜGMo žÿøKxñúÖVÖ¨HŽS(4£™¤ç§Óišßôz=]ïÄBz‡ÃA{Áôô4ìv;ÆÇDZ´´„îîn‘ÿ™ù„KÖ1™ßУ/Ü™½ƒ«ÀY8¤÷Óÿú+úa' •E…¸#…NAý“eé,ˆÛâÔoBú˜-†*KœSN­A N âhñ\¯È/?úwµ_Ôbêá*_WâÕú+¼ùë , ö÷÷©H?ßÙÙ¡5â7NGý‹Åè,°ÙlÔoBzòŽÜ§¦¦`µZ111ÅÅEôööŠüðÉl&ëùâÅ‹0|k(Ü¿‹ë Ô}Åü¼—‚„‘@ª–Ò=gæsÆÀäR9ä"9úL<Èõp‚ú¨# M·ŽIë\»‚ÀF|?/òKÀØ#ÐZ´xöð*èú%>êëëÃÞÞÍcjµšöqÒÿI¯7 H¥R4¿‘g⟞žA=ññÖää$Ö××166† ô÷÷‹üðI>'çÕ¤è¾Ònýz a[1?›Šùù°˜ÇäÅ~®,§ÙŒ5±Hz“5Êp~vŽ\"y‹œÖÈy—žœŸ¨Mj¸çÜ9C¸·xœí™ÍOWÅÀ–lfl Qdñƒ 6Å XµQUÉBY ,¢HáoH7m 6ü]t‘D`ÒTJÔ€®ÁÆÛ|cÃÇf°‘qç=⨋ÙâÕ,Јç«ßfΜ{î}®]…þ©~k¬n+dA†ŽÑAÏè!oËà9H;˜g8OŸƒµ³6$pMœj}z+*g"3ð ÇQì·ná8p “Gã—„¯ôëÊöJø÷£á®¬¬@¡P ¯¯_7oZnb×¾ •I…ÜFî½Tœ9(MJ¤ÝiÈdT?oSo!×Ë‘v¦©ÞøêSÎ*M•ðŒ{qDpaì¢ÓQ¨º~)øÉÅ$N|qã÷ÆQñ¼ÏæŸanv&“ T*• @€ž½544Pý¤R)èõz8Nª7¾zòŽ|Ãáp`ll ÓÓÓèîîø%àû|>ÚÏgÏž…î]ñÖï·°ãØºGìz"¹åêrdW²Pu¨ò¤ ×ÉQÈPHè3Ñ ªKÅ[Ÿt'QÕY·Ù­ù-\¹ˆ­…-hz5¿ü„+“¦“xtïdÈhÿõôô`}}r¹jµšú8ñâõ:Ùl‰D‚>ýtuuñÖ½m™ÍfÌÏÏcdd èííø%à///C£ÑP?hø²¡xýþuÄÜüläæç7I9?WˆélưË,$µ¼Ë¿C!S€´^JϘf†·>ãË@mTÃ7éögç‡ÎcǶE«À/?íM£º³–-ÙD0[Íp¼tÀh4" A*•Òù‹ÌfäŒè¡¶¶ù|™Lõõõô¬¹¹™·žø?ùžœœ¤Ú‚ÍfCkk«À?b~KK Ía†apõêUè¿Õoÿv±å4-°1b¹åòr°k,ÔMj$ƒIÈåØßãæ·Ä[0ZÉÕ$Ô5o}"@µ®.« a[—†.!¼F¥±Rà—€_CkÐâá÷ÁþG>é_Â'ýû9ù¤Éý—üŸÚmñÜÈ9êÙd¯ù&òe’2º!ÞNβ,$5:¿í³û4 ²þ,Ý£ðÕ³~JÁ© v—wqfà ^/¼c`>¿I‰Ù Äýqœî?øb\àðW¹>nQcî—9T¸*0ö󯌌À`0Àï÷Ãëõ"..ÃÃÃHJJŠˆ_ëèè€ÙlFyy9zzz’’òÿðz½Á`“““Ðjµ¼ö4ü÷á·X,ˆ‰‰Á§Ÿ~мŸå…Þÿò}X,ˆM‹…Óé„L-ƒ\|:†0$`¶B¬Æ”øœ´OB£ÕÀ:d…>U—Ó©Z …ø ãm„Dñ99!Ö¯Ó2ÞjˆÌ?"ò'©ï·û™|`†4ó?‰7#!%Æ+F Õ aÕ¶UìD\z\DþGë ó?­žéÎßt)3Sðù>‡ºZ‹u100€´´4Æ«ÕjЃz$܉‰‰¼f·Û¹ß†††ššO=O½~åÊÔÕÕaÛ¶mèïïGzzúsÉÖÞ³ò?ZÏÄÄt:Ý3ãÃüƒƒƒ˜5kVD<é866–ÿž?ʽù×7am5”§†×ä…T)…T#…wÀ U® ¾3¸˜rMA™ª„³Ó M¡†÷zH™Vß B¾W— Ê™JLy§p“ÃkB®Àüä¤yO¿‡ïéîv³÷~Ê!ò§+áë€Ïìƒ4FÊxª‡øNèòuè¨é€¥Í‚—¶¿„±†1hò5ÿSÿ“õ0šò±zžÄOw~G»ñÅñ¨Þ[ iƒÇ¿:ŽFc#òòò`2™x/×h4¬éüü|tuuaæÌ™¼÷;î ZËÍ͈'ߢךš´µµaûöíhhhàµç‰Ÿ4”““ƒîînÖ»Ûíf=…ùéé’¼4÷d=ç1ü£õ& OkwîÜam‡ë§}„Ö233Y³ÄÆÓßꡟW¯^ìòìкsë0Ú: ýÑOꢧ â~®“ÃÞaGbA"î|} K “ÈàõB—®ƒ«Wì©L±ú\œÕ¢äQ˜è˜€¡@ô‹;¢_ä˜rŠ~mýz–¶vt…âçL.ÖºR£„gÐý,=,¨ ÔŒ÷ÛüRtŸíFÞOó`7Û!$Pèpv9¡ÏÓÃÚiE|~<šÎ6ÁToÂë»_‡©ÅC±á±úÃøG롼©ž¥þo=ðÓ¼cÉÉ8ñ». ¸R­­­˜3g{ ì ÔSÔÔ+Ô‹Ôk”×hßoooGaaaD|gg'÷éÙ³gQ__Ý»w£¥¥ÅÅÅÏ?é¼  €¹²³³pïÞ=ÖcøšÍfƒB¡€J¥z¦zH¿¤GòOÊìYYYìýÄér¹˜´|ëÖ-,X°€÷ÚK­Ÿ>GŸ/**BæòÌÐÛã7Ç¡)Ö°'JURþÙCènéFõ¦j¼Wû¦ÜS%Ëpé·—ÐUÓÅž÷ó<,Û² 2—¨ËÙ¢¦;]칄 ØPe©àhu@]¨†oȇ¨è(xÅgou/úû  ¨ðêǯÂ5ìâÕépøÇ‡‘¶" +6¬À¤w’ÏÓî7×èhsâÚδa¸ie{Ë`©µ@;Wû°~Ú#Âxg›3r=EêˆøéÎoo²#¡4_íø ŠZÎ_;†ë ÜŸÔ+ÔkäÔ´FDýCþBùzŠôNý ßÜÜÌ{Á™3gÐÔÔ„½{÷¢¶¶sçÎ}nøIÔS£¢¢°~ýz9r„uGþXRR‚k×®qæ=qâgÚ7Þxƒ5Jÿ¯Ò/é‘> …pûömŒ±.·lÙÂ{iž<™øÖ­[‡Å‹3©~ª›ð¤é²²2d½˜ª8W{õ÷ +ÑÁÝçF”" št š6á‹­_`Ñ/¡ìP<1ô9qìWÇ`í·¢huäÑr4~Ö¹LŽŠSH-OÅxÃ8„,ûÍ?ágï°ß¶C¿@ÑÛ£8²ôŸåÂÙ g£¢¶ö>;çmC©M5¡jS­Y„Wþü |~¼}^hK´˜hœ@lI,Z«Z1lFùrŒ\®ôAýÜÏ:±Ÿïºoo¶C•¡z¼žF;ë%~ºóÛnÛ¸0U[«}-ßÜøßýó;¾>îOÚÏïÞ½ËkÔÏÜ't^#ïhllä^Œ„§kôZUU£ÑˆàêÕ«(--}.ø)ß’Æ(_¯Y³ .ÄåË—YÏäÓûöícý†6là5Êà䙑ê!­?i|Ó¦MŒ ?¨ÊtoÚè~„9xð gÒ1ÍÂè:a‰ƒö£^xÙ¯d‡Þ­ycÆ1èç‹ù¹Ç© …2Q‰g|}¦Ç* I3lŒ§VžBË—-Xüîb¬úË*xÜ|»÷[\Ü}+ °öÔZŒ5A«FÀà<¬ÎVsOÅ•ÆÁl4£æ75(üE!çíÚj‘¿<k¯®…ÝbGÐDLv ‚¦ .ᅩºuøà_ >;¶fô%z~›‡æÓÍ0ß0ãµ=¯Á|Ë ÃçzªŸüšÎˆºb&Z' d |~Xüž4¤›§‹ˆŸîüÖ&+’J’pjë)¨¾V±~©OçÏŸÞÞ^öšÒ>N~DÞ@ùòå=zO=>oÞ¼ˆxêOÒÆéÓ§qãÆ ìÙ³çaÞ{ø£££ù¼K¿/òË .°w’gžÔh¸òRÊÃô>|t»téRžyÓlºººšuH³4šc‘~ OuоpþüyöeÒ+evª›ò?ù1ñeü$#´æok0Þ(æç Üýn¨SÔ0ž4âÒï/á­£o!19­^§Ÿ,û ­ï~±ócáêÏ_*>{û3Øúl¨¼P •Ti¬˜¿}¡ó«ôžw y|&”ñJh3µ¨ÿS=Îýñr—äbåÑ•pšœºƒ<Ÿñôx ‰—àТCÈy)+?^ k»Ú"-Ïgôz´W·ÃÒjÁË»^ÆØõ1ž§y†<<ï’idæc⹚îM3· 'øX=4;‹„Ÿîüö6;âçÆóïVz]ŠÓçOÃxÓÈçµð¼…òeEZ£~ 3Í[ÂóZ£³V$<íÿôJ½G½ºk×.\¿~ýa>œÎü4#š1cn޼ɾ·ÿ~,Y²„5Mç_Ò#gé=äÙ›7ofQþ çò§ÕC31úí-äûtoâ?zô(ŸÉ³‰Ÿpä¹”‘+++yFNüt& Aó+ÊØÿu…·xœÕYyP”w}ƒÀœ\"Šr+(‰Çª¨‰$³DYK£ÙP®I¬5e¼ãmWe×sQwS庫ѸKN±2xr rà­ §s‡Ùé6c²†*ÿž¢¨©ú¾ž÷kø^÷{Ý_`\ ))# íõí…È`h3ÀAê€ãŽÃÐlÀúöõÐ=ÐÁu¤+ªrªðÝÜïô~Ž'Àq¨#Lj†Š¶" '*0ÿü|„Ï $€©Ç„¾Î>ˆ¼DP7ª! ’Aߦ‡ƒ $.¦"}M:B§‡âù'Ðè50ꌯR¨àê‰S‚â¿ ¬nZAæá0!Ô÷ÔppGev%”EJÄR¡„k¨+ôízØ í!  ¿¯‡Ì_õ5„#…0ö›Ïñ÷:­_Õ¨‚WÎo=Q®ò"9êëë‚ööv…Bþ½ÿ>üýýñàÁŒ9===èìì„——4`ü½{÷€ììlaÇŽP( µzüÖÖV <sçÎE^^z{{ñôéS >œñÕj5† ¸¹¹¹X²d vïÞM›6¡¡¡ÁÁÁoÌÇÉÉ b±ÀÚµk1}útÈårèõzèt:Ž·Ëo²Ÿ)ñL"T*ˆBD0>7BõT…Ó‰§0= Ï,DGIÜÆ¸¡àï¸qàÆ|43V΀í`[ô<íáú-ü¶ùËGÔÒ(Ä,ÉÉS¯ /ô/àäã½BÏø=M=°Ø@4\„òc帲ÿ ‚&˜ûÁ¹è”:ôw÷s¼®F÷hw.Àµ}×0wÏ\„L ­§- ¸„º 6«m5m˜µsÚoµC¯ÇëêtÖ_kþßqGÆî Øß²ÇW~ÀíÒÛ5jšššàèèÈüyüø1s–¸âííîînæó™ø3P|]]fee¡¦¦;wîÄ­[·0zôh«Æ§k\'óæÍÃÛo¿´´4ܹs‡ë—ð©¾è,Š»yó&¾þúk|ñÅX³f ªªªöùP¼¯¯ï«|¨8880Þ±cǰÿ~L˜0ç΃R©äïPþ”Wtt4öîÝ‹£GâÈ‘#;v,÷êô÷|ðÁ˜`Z–³ eD˜ES”ý³ Ù²1mÛ4ÌÙ>ÍeÍpçŽËŸ_FYjfþe&¢FÃn˜ºîwA¯Çk*4V¯.7×o´'ÒÖ¥Áñº#n–ßDa~!söáÇÌgzþwïÞåk•••ðóóCWW4 ™³Äõâé}’6/SRRX‹"##­?<<œknß¾}8|ø0’¿%m¦z´àÓY¤•ä¯I{7lØÀõK=€ê÷MùPýÒý={ö`ûöí˜ÅS^Ô¯èlòÐ111¬×¤å¤ïR©S¦L_ŒŸiÑ…EPÝ6ûç`sývÛâæ!óó>Yˆw¶¾ƒÉk&£-¿ýsî®\”ž(ÅÔµSýûhö²ÝOºÙ?Ÿ.FÞ®<„/ Ǭ5³`þ쟵/˜{äéÄ£ÄOó¯ØGŒ²ƒeÈIÎAÐÄ ,¸´º§fÿÜÕÏñÚ-\"\ÐTÒ„Óñ§á;ÉóSæCà-`ïè2Úì?ÓkÑZÕŠÙɳўßI¸„ñml!˜Ûâ01ûU§á?ûÏòy=žÏ¶b|M•‘Hß–A¡YyY(-)eÿIºAó—D"a.‘ߣ~nñ‡Z­–¹U[[Ë~{ xòv„•žžÎZC:’ŸŸÏü·f|òÏ„qèÐ!œüχÐ+õèïé‡Óˆ—ñä1ë³ëùÌÈ‘ˆù<¶¶0Ü5ð®¼.»mµm˜¹m&:Š; 3þ«}yƒÏ…ŽÃy7Æù˜ñéš(H4`Ë>‡´€®?‡ öjÿCúB׈ëÅ[v1´¿%~mÛ¶ë€ødÍøO5G¾š¼3Õ.i0ùb´àÓYT¿¤Ùtÿ³Ï>ÃêÕ«Q]]Í5G}bèСŒeÙ§Yzå#XŸSSS¹†Ç3gμÚ_ÑY”#i9Õ5åAüå—_ònœê—zRBBbLI™Ih¯1ëo˜½Ï{¡mÕâHøøÆøbEÞ t4˜¹,ÆOúŸâ™£Ñzç4âÝÐ5›=¯©©R¡kÒá«g_AÐ%€ÀK€^U/¿ïK¡Uh! •òû&š×¤2) R ^é/¿?Òix^&}QU›5$Ü 9»sØ$þˆ€IpìM½î!fýʨ„²X‰ø]ñPV+áîÂøü>EúrŸ# 6ë×]5÷&ÚñûsïPשÙo ßYßiÕøôîÍ+Ô¬¿›Íú{õ¥þZô…v$ô.…æ'‹®Ð\H3qö7– qq xË»ŒŒ æý®]»˜»äo­Ÿ¾OxTSqqqcùᓞR}‘Ž^½zK—.eýÞ²eË+ K>T'„çîîÎ}‚<;Õ(ùgîëׯǴiÓx–~þü9Ï¿„oÁ¢9œüù©S§8¢ý3é/áýªªXÞxœíX{LTwþ`æÍÌðPTD@`x ¾³­®ÝFKe›•ªk»jŒ†nÿÐhºîn4º>’Æ>l³šv-©šÆT­‚Ïå± DáíÌ0o``öžcÆ6î´ë»ÉÒôÎsó»çž{æÎ÷ï;¿Ø¹±ÞwξS™ ª4œ-NÈÂd8ù»“h×·ccÝFxŒ ‚T!Eáï ¡¿¤GÆ[Xr| ÜF7î|z7ß¿‰”Å)È>ž¾ê>8]Näÿ!ö.;2ßÏDlZ,‚ÆÁÝæ†7À e´WàòþËÐÍÒ!ûT6lOlÀ ˆWÀZeEè´Päþ:Æ#Þ-}pòD9l´iZÔœ¯A‡¾‹ö/B×í.„¤‡ÀÕâ‚H.BPHœœPMRÁ^c‡,Z†!ç¢óÓµÖÖV(•JdggÃl6óõ††DEEq~—ËÅyÛÛÛQTT„õë×cÇŽصkÊËË‘˜˜ÈÏ Ä¡C‡ÐÓÓƒM›6!""‚k¤ûÂÃË}ûöaçΘ7o®]»†'Ožpü¸qãP]]™3gbÕªU¸pá®_¿Ž   þm>„J¥Â¢E‹· λªpzïõB¡†£ÉE¤M÷›ðÕo¾BÖ'YHýU*†¤Cð`À:€ü-ùhù¶Ú±Zˆ$"ô6÷"")Kÿ¶a3ÂàlpÂÔe±EÇ@ǽ”y)L £¬Ÿ/ø?tÌÝ>ówχåŸ8œ82û^Ùü î^ˆÞò^h¦jÐWهЌPò è¨è@æ¡Lt^ï„zŠÎÇÎgxV xnt"$#„{~a¼wÍ7kÐSÑÃÜp‘ÄW!‰‘À\kFùßËsƒO!+ƒ«Ý…àð`ô›û1ñµ‰Ðeéàzââ>Qwªﵿy„ÖZ+4éXª,KCU^ÚKÛ‘µ/ íåíÐNÓÂÑì€H!‚X#†ãêIjôúXÓ=yòd¿ñÄâa»´´”u„°5mÚ´ŸŸ4š¸Ê÷ž8q‚9Àš{ðàAÖy­VË<öx<¬·8|ø0¿gª#''·nÝBnn.sšz ÕµvíZH$ ,, ‹…{õ‚Í›7cݺuÜ Ž=ʺNœ÷ÕM}§¾¾žŸMý&fvŒwÅ—+`ªüs²Šým€$Òp)ºËº‘»&Q Qx»àm¸»ÝðØ=PÆ+1Ð:eŠàßZŸù·á€aØÚ¡Jü›ÁŠð)á0VñÅâ/°òìJhC´ìŸ;ý«xî÷”iÊçþpØ-ähr$¨P´½%_– ë¯YÐeêàñzÐßÖe²¶Z4ÉÔ^¬E—¡ ¯íz =%=P¥¨àjê‘ z¤ boIñÔO¤QR »„wmó@6AÆkJÒoüHÏo­Þz8 ÷BT"BÞ¥wáÂ…Ì_ª/22’5wôèÑ\õ zf]]×ìv»™·Ôˆ»{öìÁêÕ«Y“ûûûa4‘””ÄzÌ’%KŸï]W¸ݵÝФúÛá@2"•žNLfÎ,=ƒ5w×@&‘1‡•QJ˜ fhÒ„x£ƒù¬ †ã¡ÐÿÔ°6[Œ£¿8 iˆ9·r`y`Z§æüÒ@ˆµbØëìŒcK½ŠDcÓÓç6Z‹#ó cM¦¾5•k—h$°5sc¢æ3ÂῨçÙøÍÝoÂh0òLé«_¬ÃöPˆOÐÂÒhaÍ"¯@B5NKPO²ÚoüHÏoª7aLÒœúÓ)(¯(Qt¯ˆ1KX! ÒOø!|‘×$<fÈ’nv S„Oñ4ÒœGø'ÜïÞ½›ñL3åO)?Í¢W®\aMç^¯ÝÝÝìƒÉÓLœòé;õ ¿¨žåË—³/'ÎúžMù©Ÿ|?žê¡kv»ë'/>cÆ LŸ>µžžK~ÙW7õ òôûâæÅyWæ­„©ÜÄÚé~âfÿLúèht üÕpôü£Ò±R ŸAËàwû'ßÓ_Šw5»ž­5¹Ð?ÜÚSµHÿm:BŸÍd´?æný.?ǧ úR+èïx†\CÌai´ær3ÆÌKµ…ýá÷ãyÿ*U C÷^?ðúóýŸÿ˜ÿ…ýñ#=¿µÚŠˆÉøúÏ_C|[ŒË·.£ô^)ãöH?„ò–´FÜ&L’~½¸ÿCû9/Æû®°·;pàÀóý%ñ#5SSfÏž“'O²'&]&~ùòS?|ñ}ÒÝGžzûöí¼wE³/ùtßþØÕOþø{îÜ9¬X±‚{=—ôÝOsõÒö¨™QÞÌ3™'äÇh?Y$A¤1—å r¸¹˜¿§Cö!öºövÖÌçñ‚^–:Ïaò rˆ%‚&´ÚØû9?/\“Ž“2>}ùi/F#Egÿ¿Å“wT'ªÑX܈Þú^ÌÚ2 OËžB™¤|éü?VÿˆÏ/øšÐÔPT I…Ÿÿ úJ=ûIÒ ©TÊÿ?a‰Ö¨¯“f~H?„êõþâ}Þ”fA:ß²e ï·–ü·òÓµâââÿYþ—­Ÿt”<õ¨Q£x¾~™üTñ‘ÖÉ“oöiçËÖOK9è~Ÿÿ§xÊá›ÑiNïnÿ|ü|ü|ü_ÿžÅ³`ðð0Õ ¨Ö°Õ8ÕÕÕ Õ(Õ(1w0Ö2®Ö=RS(Ö¼>ׂð‚h»ƒÂÖHH<µ ë x Û[•[•[•£h < Ì(zW(zW*W_B â  ó¨“ 'æ,g2Â7W=ØB3HÈMIS¤X9^ÜdDn€wL~tƒîˆEŽm“ç˜>žh£ç¨>®³ß½ÁÉOpenImageIO 1.3.5dev : ../../oiiotool/oiiotool ../../../../..//oiio-images/grid.tif --fit 240x360 -d uint8 -o fit2.tifg.tif2013:10:17 15:06:26AvOpenImageIO 1.3.5dev : ../../oiiotool/oiiotool ../../../../..//oiio-images/grid.tif --fit 240x360 -d uint8 -o fit2.tif openimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/ref/transpose.tif0000644000175000017500000001552612271062644023516 0ustar mfvmfvII*Lð@ö $  üæî1SR2¦=SL»ƒºOpenImageIO 1.2.0 : ../../oiiotool/oiiotool image.tif --transpose -o transpose.tif2013:04:18 11:25:06AROpenImageIO 1.2.0 : ../../oiiotool/oiiotool image.tif --transpose -o transpose.tif€ @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'ˆ@‰d¶]/˜LfS9¤Öm7œNeò©Ôö}? PhT:%GˆÏ)ºe6O¨TjU8½*©W¬VkUºåv½«WìV;%–Íg´J`v›e¶Ýo¸\g•Öíw¼^o7KÕöýÀ`i—Ì ‡ÄbdLV7Èb1™¦W-—³dó¼æw=FÍgôZ=&–O¡ÓjuZ½d7Q­ØlvYí~Ïm·Üaö»æ÷}pÝïø\>%oƒÅäryZ _/ÏèQ8ý§W­‹æõû]¾ä{§Ýðx{½ÿ—ÍÏòyý^½ÿ§Ùïøl}ß§×Góû~Y_Çïüÿ·NÌÀŒ³ûÁJÜ€€€ @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'ˆ@‰d¶]/˜LfS9¤Öm7œNeò©Ôö}? PhT:%GˆÏ)ºe6O¨TjU8½*©W¬VkUºåv½«WìV;%–Íg´J`v›e¶Ýo¸\g•Öíw¼^o7KÕöýÀ`i—Ì ‡ÄbdLV7Èb1™¦W-—³dó¼æw=FÍgôZ=&–O¡ÓjuZ½d7Q­ØlvYí~Ïm·Üaö»æ÷}pÝïø\>%oƒÅäryZ _/ÏèQ8ý§W­‹æõû]¾ä{§Ýðx{½ÿ—ÍÏòyý^½ÿ§Ùïøl}ß§×Góû~Y_Çïüÿ·NÌÀŒ³ûÁJÜ€€€ @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'ˆ@‰d¶]/˜LfS9¤Öm7œNeò©Ôö}? PhT:%GˆÏ)ºe6O¨TjU8½*©W¬VkUºåv½«WìV;%–Íg´J`v›e¶Ýo¸\g•Öíw¼^o7KÕöýÀ`i—Ì ‡ÄbdLV7Èb1™¦W-—³dó¼æw=FÍgôZ=&–O¡ÓjuZ½d7Q­ØlvYí~Ïm·Üaö»æ÷}pÝïø\>%oƒÅäryZ _/ÏèQ8ý§W­‹æõû]¾ä{§Ýðx{½ÿ—ÍÏòyý^½ÿ§Ùïøl}ß§×Góû~Y_Çïüÿ·NÌÀŒ³û³e1Lv ¢Ð´ A*€ @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸â5悜Îa¨ä–M'”JeR¹d¶] %ó9¤Öm7œCTªW\[-…'0˜ô‚ "’PéTºe6O‹Lj:¥V­¢ÈdtúÍ·W°XlV;JÉg´ZeÕÐ"¹­RmW;¥Öí³]ïW»Ý²ÝN¿Wï˜<&§yÃbqVú5·LÀܱy<¦V5ˆËfsR|Ž2ã›Ðht9–ûp†ßá™Ü£’ÓlvW}&Ïmd¶BõP½Í‡w·àpjÛ^=©Ç·¶ ÿÏšñ:>¤cYÕìvc}.×w½ë÷ü^8GsÉççx}¾×›ÙïÙz¾>7»é÷Ìü¿½Ûøÿ°¯Ô²Ïô ®°4¬0T! ®pt) ©Å1Lv ¢Ð´¡C *ÄQ,M¾´QÅ‘kûEÑŒe´ÑTiÇÊËGQì}¬Q´€èCPâ D l‹ÃòœŒHR{‹ &Ò¤¥+ òŒ°ÛÊɤ»-ÊòÔÀøµÎj‡/ÌrtÅ4´®Z¯3M’Ü×8´r­8N’”ç<´éú–ÜpÈ!Øv† C€+\ÊäÏ“ yJº…¹nwšÆ±î ¢(‚@È2&óE1  € @$ „BaP¸d6ˆDbQ8¤V-ŒFb-öûá\®w€ÀÉd)'Æ¢èÔkš s9†¥S9¤Öm7œNgS¹äÒ€žÐhT:%V«]®ä€@ Æ`Ê<L¦vAKE ¥V½_°XlV9¬þÉg´ZmS4¢QÐù|¿€¸,µÞoW»åöü³_ðX<$å*•t>ãQ¨0 €°¹<¦W-”ÀåóY¼­&—M d?9§ÔjuSlί]¯¯9\¯¥R©Øþ‚@@Øl „À’,–ÃÇäa5¼žg6fÚm=× ‡ƒíöÿ´Ì&\îçwaËïx|PÇ“Éú¤R:Þï}͵ãø|yP?—×Âü~?Ö‹G{uº|`‡ kB€0Jz–%È#ÞûBŠÆðBP«Též©ª{ h(Š * ¥*,—¦0´U§°¤Y°oñðXpBèº Àp¯DðtSH’*-HÒJÒU•giÄq"„†!ˆ°ªêÊ­«²T½/ òDÁ1¨ëjÞ¸®kªï2M“jÃ1MÓŠrI’g9ô}ãHÒ @Rñ9P s8PT*/&IÒ‚¤)àu GÒ¥ HÒˆaÆqŸ4Aþìá8†®„€ +SÑôQU ÆÁ°{—EÓªë»2Y[³uUq[ž'‰øe™gª8|g™ûM«ð}we²uÕ™gÈ lPíÚªùgZÖÌiHV¥µo¬–ÅÁq¦’e\—Jq]Wj),«JåÝy¨Weé{ßÌÞú_Wíý¬W¶à˜*#`ØN„á]tÑœg´¹ô{Çó `Ø ©`Ð4aÙ*†äÓ‰†ažVéd"-ðQÙNM”fÎjàeÖ€°,K¨‘~_ž8™ë@áp\àxz‡é¨jæQ”z7þi™g8Vq°¹ z—¥éâ Æ1‚ÈŒeÐP˜&!0L¡Ö^Wîµ6Þ Ç³þÉì|;aDIçÈp¡Øv¡ÔÙþOÇYàx;HÓ"eÉrxjç°nàyšñWïÖµ¹üÃ:èÄ1Àˆ#¡¼m€  Òâ"”¹òÚ È2K…ú€€€ @$ „BaP¸d6ˆDbQ8¤V-ŒFb-æóá^¯wB Rñx+`°^LÆcÐX,Èá»áðþJ¥]€@Ök F¨T:%G¤RiTºd L¨TjU:¥V„Âa<™l· Ün ÑR©Úãq¾ID ˆ¤R ‹¿ŸÏôz=ÎN'ÍZýÀ`pX:; ‡ÄbqU -žÒQ(„„B DE4št¼ÞoÓ€* bï§Óù&“Ïgô^·]¯Ølbm–×m·¿¦—«Õúf3Á ÐGNèÒ?F À$‹»µ …Ö  åð¶ã½ßðxc[O—Íç„Ý\÷'ùÀà€À1r9Ìÿ€/a›ÇÎ,išg±t]@P‰bX"ôAl×<|% ±d‘$sŸgÙþ6 À : Hçéû ðüBŠ•ÅqÜo›çÂÖ-ÀT)ÇÊ‹ÇQì|¤“dÙÒyGèÄ1Àˆ""-Óxß £(.Î*&wÇá@POˆ3ŒàºyÇó,ÍÇ“<Õ5¡å‘dwfÜd%FLlˆeÖuGÛ¶ » &Èáð€`~¬seGÁ“M!IÍpÀð*Š š#7Nž'‚A HÊ¢¡¨{%Éá€# È ¹Ó%)[ׂ\בü2“„áÒ{ÇðŒ#h[;¡††yFRº¯¬4jt9IRvŸ‡áÿƵíÅq°t•ÉsÁ”5¾t@…àT¨ù]ˆ)®kžå±lwƒàø* ”ò,…APvç¹ü…`P$&—F%‰©µÞ)‹¼æ©«Kž/c9Ž`Ö1‘äˆÍ’å ‰ÚvŸfI’zGòÞŸÌA‘e9Îs“çYírF‘§2 ›çÚ./žhÚL× hH&‰¥jê‘Ι¡ä:®µHjzÞ½Å1Ø‚‹BÐ)¯í.»´í›nÝ·¶x¶á¹î›®ëµîÛÎõ½åÆù¿ð q¿p\/ ÃÇ<'Åñœk¿ÅqÜ%ɰœ‡)¤çyù8Ÿ Â|ó'æš €PI@%2„Á0g/Ùª¼·i’H‡íœy&Éîü#¬ ‡¡èáÊÝ¿•î^^“Cå¹à›Ò÷†É€àÀ0¹ÞN~ÛÚ8|›Áïóf„5G÷¢½·á^N'¹fYþF ˆÀ` y$PzAú/…ðñs‹Ô&„Ð" A)p~pL†¿((£ÖÀú`õôrAÐ:¥(d æ1F(óKÁ`,7´ˆ¹h/ÕÁw¡²f?üR AØŸØ0,!„0TÅø¿#8gP,€(\ €Qvâ$qÈ"(/°å¾Cˆ¸†àÜÄXŽåægb€ŠÅA_¥±ÔîU¥TäQ«´æ³ÛÔ^äZ‹QÞùG»ÅÀØôG£»xh%‘8ê|{n¤€ @$ „BaP¸d6ˆDbQ8¤V-ŒFb)Ôë©àð~ËáP P ‹»]¯µÖ †@´QsANg0Ô¢}? PhT:%G (ôºe6O¨J);ñøÿ6›C`0 £}>ŸÉ4› ›Íá™´âu<¯ÜnW;¥Öí ¤ÝïW»åö‡SªÕ͆ÀÀ^¸ØlvP p8["syÌw=¿fsY¼åÆóÐhtWäz@^/uR{‹±ØûP¨]a€ÆcšäíÙk†}¿àp3ü' [­Ýíf³Üx<ÆàÛ“)”ôa°ÞB‘H$”JÄ^Ïgê].é®k9.?·Ýï£pþ?¦i¾ß|+•Îà`01 @¨ ± aö}ŸÄñ!ð̉&Ñæ1 ó`,†©á,B‹¨gŒñê/…ðñR€""ÚeY‹F"*HN ÁÒ=_Ì9‡pö-ÀXµQ)ú§Ü|„€X+WÆê43Â+ áLm€Ç‡Áäqõ£©Û›p,mD„-*!Å ‡jìÍJ+Éd@@€ @$ „BaP¸d6ˆDbQ8¤V-ŒFb)$“öû›Á€(F£\ÐS™Ì5z=©”ˤ ™ŒÁxÔö}? PhT:%G (ôºe6O¨Oc‘éŠI&”J¥’è»õúÿH$à0àp ÔmV»e¶Ýo§Rn;¥ÖíKN'O‹ðÆc JÌ® -—ÅŸ/—òQ(è²Y­|¦W-—ÌDnYœæw=kV«]®äH Å`¬-ox<‰Ôë¨ M!Œþ÷}¿àF³|' g3ž«õûÄB!”ŠA=n¹o·ß ås¸2‹AN?—ÍçÊðý¿eÝäò~íOçóü²Y ƒ@hŒ§ 1¹ŠbžFAzáx"€{ÛŠ€õBP¬,£˜äf™§ €‚èº à:N†¿Ír.SÇaÎsŸB`˜„á8 ÇÌu GQì|‰1gñJR‡yÞ~;à3¤ DN„Å.³^ˆÇqøO“çS"5 @¸ IñüÅ1¸1äÉ3Í áù‡±ìCàŒ#ð<¡Œë¢Eñ|x™æyêH–%‚3EE³35GÇOyøY–gÐtH(8Á`X è M“gTTˆgYöR‡[è ‚à* ‚à-![× e\ׂ¼¹'¬8z§©ü‡@(NS‡1Ì}!H% TM{kÛ %wlÛAø~æñ¼|GõŸV)ü|òδ¢`€\K0Û·Íôˆ[wÝýà ý~àX. ƒáî „á˜n‡·¸^!‰â˜®,¸ x¾5ã˜ê}‰cÙE‘â™I“åM÷“eYn]—ÑYfa™æ™¬!™fÙÎuâ8ÎyŸèz¥hZ.£®yÆ‘¥éšj%¥iÚŽ¥©jž­«èZ®±­ë™¦µ®ìI¯ì[.Í‹l›>ÕµáNÙ·îÒ€ @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'ˆ@‰d¶]/˜LfS9¤Öm7œNeò©Ôö}? PhT:%GˆÏ)ºe6O¨TjU8½*©W¬VkUºåv½«WìV;%–Íg´J`v›e¶Ýo¸\g•Öíw¼^o7KÕöýÀ`i—Ì ‡ÄbdLV7Èb1™¦W-—³dó¼æw=FÍgôZ=&–O¡ÓjuZ½d7Q­ØlvYí~Ïm·Üaö»æ÷}pÝïø\>%oƒÅäryZ _/ÏèQ8ý§W­‹æõû]¾ä{§Ýðx{½ÿ—ÍÏòyý^½ÿ§Ùïøl}ß§×Góû~Y_Çïüÿ·NÌÀŒ³ûÁJÜ€€€ @$ „BaP¸d6ˆDbQ8¤V-ŒFcQ¸äv=HdR9$–M'ˆ@‰d¶]/˜LfS9¤Öm7œNeò©Ôö}? PhT:%GˆÏ)ºe6O¨TjU8½*©W¬VkUºåv½«WìV;%–Íg´J`v›e¶Ýo¸\g•Öíw¼^o7KÕöýÀ`i—Ì ‡ÄbdLV7Èb1™¦W-—³dó¼æw=FÍgôZ=&–O¡ÓjuZ½d7Q­ØlvYí~Ïm·Üaö»æ÷}pÝïø\>%oƒÅäryZ _/ÏèQ8ý§W­‹æõû]¾ä{§Ýðx{½ÿ—ÍÏòyý^½ÿ§Ùïøl}ß§×Góû~Y_Çïüÿ·NÌÀŒ³ûÁJÜ€€ð@: h  @*21S–2ê=S»ƒþ008ùelˆð00Brª£ tüìOpenImageIO 1.2.0 : ../../oiiotool/oiiotool image.tif --transpose -o transpose.tif2013:04:18 11:25:06AROpenImageIO 1.2.0 : ../../oiiotool/oiiotool image.tif --transpose -o transpose.tifopenimageio-1.3.12~dfsg0.orig/testsuite/oiiotool/ref/hole.tif0000644000175000017500000157333412271062644022436 0ustar mfvmfvII*ó€6 n  >&.(1 ¦2²=RSž»ƒDÆHHOpenImageIO 1.2.0 : oiiotool ../oiio-images/tahoe-gps.jpg --resize 512x384 --ch R,G,B,A=1.0 --fill:color=0,0,0,0 100x100+200+200 --fill:color=0,0,0,0 4x4+30+30 --fill:color=0,0,0,0 4x4+50+130 --fill:color=0,0,0,0 4x4+70+230 --fill:color=0,0,0,0 4x4+90+330 -o hole.tif2013:04:05 15:35:20A OpenImageIO 1.2.0 : oiiotool ../oiio-images/tahoe-gps.jpg --resize 512x384 --ch R,G,B,A=1.0 --fill:color=0,0,0,0 100x100+200+200 --fill:color=0,0,0,0 4x4+30+30 --fill:color=0,0,0,0 4x4+50+130 --fill:color=0,0,0,0 4x4+70+230 --fill:color=0,0,0,0 4x4+90+330 -o hole.tif€ #gûôþ>€ Kô|¿¡×ãè}ÅŸ`Ü<†Cä@ü‰ý‘ÊapÀ8˜fð  Â!ïÀ½þqiä!û!†H_Àpù5΀rWìéþž€'S˜` †Ãïˆsì %„SãàHð¡œØ €LÔø<ÞQ7õºÁ~¾eïØsñùl}TëPPûhÅ?âS\’ÍaöËV<žÃ­Ñ(e Kl§€À·)Íi÷0}S ktñž¾@`uâÏ a =°ž½é²ðPžÖ,úhKÐAÉ%áö¶c×&û{ò€¯—ˆùå‚ßplYî¯ÅßóÛíº<)é+ö–*ê P|,é"´Ë3(Û€$ªJH›¨,˪+Zþ3JÉÿ%©x®¿jl>qI­Ð"Eªê{ÜѳOr{±¬Ì—¤-:I£é ’Èoô  €IêÄ Èè2~32L”‘±ÒD£¡ìœlžŸ‰ EHí?ÊLZAb¬ët‹Ëq2àšeh’þ‘a3òJĨ5©Æ”,¶IÌ]qL_ø|‚¬&vSIðË À±ü7‡N¶¶¨€!à-®—­Z²§ÔTv ¤41}1æ6¾W*Ýp–ä­2hegQB‘F56!lΗW+V¾vÌ-к›DDü4“ cWÛ5$4t%Ç\ŒÛ?WÐäLFûdKŠÌ ÚÆej»8™fÉ¥ ;G’Œ‰xTZ–£•òQ¬s¨jsM=§]–­wÔšG(«3DË+CØ>ý jìË1««2ÕB¬Üuâ¤Þ ®ÊéÔùØ×6×EÑyoý&ÌßQz•åjÿq_¤I Ë«eçµC{Ýßáj²¬šÒ‹ñoÊÝ7’•tÕÕ£¢W,yQ¾çl‰ß)Ml,½ò‘Ÿ1`|Ä©ù>ˆ*•à Í€ÆTp: H+<Å=c”•ŠAHpFE‹$5–HK1fT+ÇâÚ’K*K u±•Ü…P# sÇ ÓBë¡ijÍxž€6¾×Ñ‘Wre4á°„@LƒÐ‡…®§˜QšP* O€€e€4b¦|’êOΈÿc˜šÃ”OKªŽ"ÉÙR²:ÇÚ¤«ø–6&2{šâpª‰`BÃ'˜ªŸAK €2ØeÀXãä{· [Œ…0Äíô€ }G†ˆ Áh6¼yÀ;‡Ð"æÌ’p0ÊxýgD|ò´<åðÿCÈ÷hÞÀ¸."àŒ$"‰^ ¹–% %1倘:~Hdõ¯»E®ÞX?_H©ê5@Käy“WÍ3tÂÙJÊå~ÑLœ²„Kj+z Õ7·bDYØZ Œ’)’¯É \³ÞvA¾¶›ÛÃú'æç’&!Í|·*¨Û*¤ÏÉØ¥E Î\z*¬€E¶¤‘Q4è•Ø¶d¾`¹; Ð]%‘8xÕ¨d&Ì¹Š”š`©©‚—3*>u$HÞ‰é`x¨ÊÑW„ÊÉZ_“ ­¼²¶¤M”´¬{j4¿—(¡ÉÄY4ü$wì¦Ö* Mb¬FÈò(†ÂFUµ)KM]Í£úÙã½u ~‡¬«"„)Z ­$,°XgRìICw%ÊÁ…„cl‰’`ÐcÒÔTT׫¥3U5Vè %pEs¡í6&¬‡Ù]"k]Ñ%W C!Ú¸$*ù¼ÎfÌ›A?è‘Æ ;,úW«ÂØ«cF”4šKmд"´(õî¤Îí%¥•ÙVËP¡ ÕøÔ“þAW]Ò±*’’×ö 𠚨v\š0¤U‘/-«f–‘Ы)׊ÝN%$ÉÎwòïà,y'[Þ»i Y4Fû?„ËŽàÂVÙ 5*SyÞÍØÅèÛ½¤Öï²­Kõr‘8 ×ßl©Mu&µLùr;䇸™d»““ÊV%Í/µü@êRÔo>b2—ó&=\ßx³íx–ýx7ºŒýà,ÄhmU¼µ‘šŠ!ÄÈêPD K~”CðÁ%Ó6J †D–œ’\g©ò$¤l¶9UØ¥ÒYhM©*¼œT²‰ (ÕO>‡ÊÏáJ%?P€jŒ²!$¥˜bI(ó‡(‚§¢k^̹n@0i0 KÀH!à/kaÖ1vËFÇø”ó@Ž(#¥¨‹€y,'ø0J­}  J`øJ €Â´±ó¥bÒ„‘ÖI ñlܼ%p `ûÒÃé@6géÄ$V"àŽ¡óxˆ`ŸAÒ69Zät{ñ£h•r(Eâ/Ë àãà‚#† þ»h{´±ú­ @*¸‡A´‡o*1Ö(ÍYÃvӘ݂¤ÙÚ^‚Ȳo?‹æILt¨µ)MX¥UƒÐN–bËíUšÊ@}ú—D$ºê£3ÜcÔ%'•cºãÆ+³ù:°(íò-”}‹Ñ&½=¨Õ‹9üiIè«øª`JšÙ¡Éï-ÂFÈ™ÃoxÄ ªÑ8jÅ2*Ù©òx\þ‚°Å=NQá,mÎ$å€rûI—©(d¬Dü³±ú'–(o,×®°¾Œ`“ø´Yð€7€ƒ•U,Ý%ÖCéÃðëÚé¡&Ý,¡ÛÄšf«„(GÐÅX ~Ä–gÄÜž¯8bf¬Z¬8W%lgfbíFì¯Ë‚].°-ÂIOb¦ŠÈzËÀ"o\¸ìF©%8Èå°oiîcJÈ…ÏÎWF@¾ÄÆRd´‘æˆ4¢t#d¸òäÖet"gb²"FHmÌÆøìÆšû¢¥,~Ðäø5«¬‚LºÊìªj1BƒgDÂæ#z,JÌh"ÌÄ,{L.Ê¥GO`ÊHƒÌèÉè0Qè4î°vÍÇ´$o²oÄ^3 @`|áê£ÚÒƒnFBŽ8Åh†BžE)]ƒ„þ$fVúeP>¸bh¤ç¨*ÊV@¢tâØ(J7BŒ…V`¢ÒŸÅüJmHâ"d†“Â.‘ðŽúaø5­ä6 d-ˆ¬8Ä<íª@:CÜ J<¡Ð$áš2Áî™ "Haêò¤lyÃx†Â<0N '¡ô*V‡ÀøÃ,¢êbÈE ô*€Ã^áhâCS˜eˆ@þdö_bçaö",ùnø?Ç + kÆ”$ü( š5#¶˜bJÝÉBQÃ1æ$"5 @@1©°ÝI3Cbä@n|€8çÅl˜æ ø$4Æ @ÆÜOÀid†Ôe®µ.¬àŒÄ–Lv3"n.¾î Ö¾ÅÒ"MÈRËöI D«äðü$žãQðÉíÈd†9rÑiÔËæª]h«ÏÐH#÷Ç^°,Æ¥fíHÒ\¯_!ïÀdä¸z…ŠE¬"“†h´L¿ †:5*ˆ3IN¤TgÂF¨Äê{†ì²' #b@?Ó>]N¾Ì¢ eHkÀȨ­ª0WéØKÄ$U"ÀõªûBy!"tÜñºEö¼%fDïhkBùbÕê|¥¤®TD8:Ä@¡êZã0EÄDk/D¥-2œTTRÈ¥Ï*N¥M=o€©Oµ;ÂxgÄ"L„ e/¨N£Çnùå˜òN¾Lk¹ŠrÔÅšw¥p…äN­&òvLf‹‘QºOç… çà·N°^ê¢jtZJŠ£# C4b¤³ÆÃ$X2k¸p+겦¤E0RUß,#J½‰!R Æ®6O¨ï* Ãs…öWlÍ@ä^³GNâŽaH.¡ˆ¸IFÊ¸ë‚øèÁ$…òžŠ`§>ÆF¬“ðAT@Lë gƒ24Ôk|0El,D±pj!¥#®Ó;Ñ Ò½‚T„„ÂE„23Ú eäuåøÅ¦`WÄØÏ\2“$’ÀKƒÜ‚êVĈ‰£=UÒNÆ€D¢ê!xkf@Û@@j Àf$€æ!òî¬.Vê vàƒÈÁÆ$P¡ÆÙòT8D˜ÄV"ÒÚ_pŽaæ"Áô‘#Ž$P"¢_*‘hãLÈ|l(`#*“>CÈ«k ¹d&-ˆê•"(“»âºÜ=#•pd”5cÜwnÀ*DW¡ß&{––ÀÀr! *b!K";„-Î:oSÉLR¯C§RÆOJ^qÄYË cÇ>‘ê|Ozkà ßaîƒO¿ÂnT)¬ä„y£O¬#—eºGÏ¢PúO~žæuÄ›ËÄ~!ÙOÃj-g^%È*²8ƒ ˆ^â¦â0<$«„+no*¢pGšIˆù¢s"…+Õ$¦J¸ÂE„p$¦¼ÈÇcEýþÈ|òo'ƒ¨µÏÆ…aÑ,}ð–È:-Ÿ wÔ-˜^.y•|Êjouƾ?bs*W'g_La„¤©ú}ÖŒÚma^:ÄÑ4}ú@µÌ±çâóÍ êPvÞ8€Éá¦~/é:ZÇ1¤löà™ù‘hž¦€Q[çì$)L¥Á<.%Bt^ Aþ8‚˜òb !Ê=Áð=¥4[#0BªÇX2]Ù i“às`Oè+b·@-ÍÜ*~#¢,»|KRN¦¢F@%öLîÂݘþ 7ˆ¬ÂK-«ﯭâª5/}‚Žì yü˜áúƒ@I´ X ¢ÃxÃtÄZ!ΜÚ€MÁ "ø!îaÐb¹f¡ Pœ-¥4â6ÜœŠ3jdeHv0fâ Æ'Äê•}”n„g›™°n­€ŠÖØ? Þʆ£<Å0ŸDâµÁ¢j#¢ ´Àd Š@phDà ôÿGÀÑx+ùø~€ÀR`¤ÿ‹ñÈ´Y÷Mcàx,&cÅ¥˜ä~9OÀ7ôyÿ=‚Êc`+úˆ™ÒÀZà ~¿ª€)tV“Ô$ÑÛTj?d‹Ò#’š¤¾Ô¶¿¨ñÙ´n=AŒÓdÓh¬ZcJmÑ Ú=¦Õvx­åòÿª`çÑù` —¤Êd±ê¤za‚£bcð­$îS Æ¿ò4œŽ¶í€¶@65û+Šç¯;Øþx=™Ï®Ù¶z3TÒæ¢Ú„î,úÉpíö+‚±c´øKÍŽ“’–Êx¹š¦ö<¼b°”‰4{sEP­¹µGd‹3oŠ˜½­ªkè¶°N;½.ÇÚÖ–ºŠÊ°å/J¢Ø².Î;m ¬jŽÚ(Œ²ôÌ¥ìC›±k3öÆ£±[ZÓ3Í$¼0ŽÛ¨± Jì?éóœÓ%)sꌰpü²#ˆÒf¤,JQ 'ªbTŒ3nûü„Áíû»#°À™-Rc3)[Ï#rÔ¶¤­¢JܨéJBŽ#å© ûBÙ¼Í3¢²¶èвL)Ú2ØÈkRú¼Ëo›0)Šò¬Ã¬1/­Í¤L”6ˆÂšø®+lÂö°+’Ú«(q \ãËqºžŸM;3+Cuj*ÆÑŒÛÈÌE’#çÕì?F,ö n²LëLÙHÌ›nöέ´Ô‘G¶“®¡­.š.ÆË\ê›R¬Lqg8v,9WØÕ³Àá± µÑ ]µâÕiJ­¼íĶýòÍ[u ¤ÄÚï#ȘVU”,÷_Ð=·r·×•¢ÛÒUÕÐÍY”•®·`q;?8–;;Í69]ËEj·RMºÁyÑ—õË‘×÷=Œ~ÙSúÍuVQZ°ÄåÔ­`™þù3·[±‰£àÈp9²Ç™æ'ñÖ‹ž‡(}s2=+óD-àRL÷¡I(}Ÿ 3î‚€‰}F È £'⨭é¸{içöÑ 6IIö$¹Ð…).ø·)¢.~Íçü}QÖfÉÐ UaKû ñêÊDƒI £²@ ¹ŸÀ˜@¤€›‚ È*ЇÉê`;!ª‡±ž[&çi¢½P»= B äG ü|ù þ÷,ÄJSñr%ós=#çÛßOà0¨å@0¨ùÈö¼})ò啎tMÎϼ~€j’B*ÀàL‘p8 ȤŒ,ÔnƒUXz#õ«RZUÍ!é3X‹5â>ØJ6]æ5Æ5ósËÁTj¤›ò~F¹é+Kd|€kU±ûE˲¢bGÜ<)Ž¥_+e|Jò`+á—ÖjKÊ,ÆÐ»öÄeÖ 4: •’Vª#¦ú+ÄR™},nuæ®$8³Ì¹ãQ&š(ð†ê9g›RdkË)èXH¬ŽSFHÀüD§äù*Oã‚J¤¢.¡ˆlQ\Y…Ž=œ9,KÒ.d\¬sRM™š<(©Ë2RnTdZ`’E’Òúêë•I€²J#FbëS¬Á—”G~Mñ¿4ê½Qƒr·WÑó#òp–3ŠG‡Ùy:P¥B÷Öªí;èMQ·Sö¢N yBÒˆ’£¥úHNLJ1h¦N§8Ò[_.( ¦¥·:´XùþM Œã£CÛ"—óe-$ÔHI®ƒ`“§MHÒZ+¶PYI+,$I ΓÈt›ù½”¤xµZ…VjF)LL™›ä¾ßØtÏ0iF–3aJŠ1lN$²)Ⲭ£'él¶r* —Û &s‡”Šd˜•ë3YØŸŸóåEÕ•TVÕ5-U¾ÎY²*3Mg3F:y*ªÓ\ËÆo­¸àmk’UBÌ<»ÇÅ„¸Ñ9”LÅMT‹Lq6ž V¾’9ª`ª4$TÖ£4tmر672Ǹu fk:û~+¡_Ìcä–ýU:ê2xvYdWEŠ[ì)‰2lÐUq¨5õ1wW²½Xê1r-¬ÉÑÙª [«1c0ÆT¼XeÅ`‡Éz[¥e+]-X…Ñþ>‡»Rrƒ´Ô·±ô>›)$<§õW’WÌH¸Y:qö= o Dd|)LƒGè!”0âBGãx2¯ ÛòNòýˆN„¯ŸU·KMœAã蓤2„S‹É›²ªÉÉœáûÜʲ“†ÁÀ€"C@Ñ pß½ù~ú†|ªÀÀøIð9ÆYIÁå3$0Ò@pdúõ¦Úñ(2 ¬¬8£s(iK**´Å•Gƒ!Ê8= "÷€pÈKljÃíÝ9”ICï %0|›‘üÛ˜x¬`NR@AÏ@„Œ€LÔV²0úd R(>ÛÖwh *‚€­ÊÁQ/IƒâªY1-µÉ$x„9 Ÿ$!:Ò”©J<6[âT\ÑI§,}íf2Ú ‹:WÖéŒ$¤|KrÆN¦Ò[†¬—b1)I® ‰K¿¨ä±f™ ,i$µi“Ñ*‘ gŽŠ„˜çÇK×)³ ‹H°|Li÷‘«`Í*Va!jz%¤ŒšŒ`Bq¡¤ì¼DB:Á©As/;)(ë›)I×…å¦CÓët•?eÒ̳nzÅPg¹©ŸbKUGBOYeUuˆÀ•èœM‚CUaHqiü`‘?;Z»ÙŠ®â*I Ý$ÓËŠþ,&ªdú|zÎþŒ©h°v0Ûã^uA~ÒƒR[a?<Œ±,Á&ξ„ ¡ ÙmSl¡ÐÝ_Xæ¼ØÅr’™öŠ^ê%ý)“° š7Çi‚ rCÊš¶K³„<Çåí¬b(š”E H/É[„ЗK2Ÿ¼š\j<ÿKe¨ucÊîÞ³Ù„)¦Ü£,:RêÄ­4V¾ÖŚܪý'ÊÝ;תžsXEœ¶kÇö$­XÃ9@ŒÒY“c¬NbÔ½Z_Þ,m·&70[)VÌ…¨[îð3Ñbµ²‹\Ã}²X5;ëÝd‚S:8VjãZ÷õ«—Ë· Ý™ÚÕ,Êߪ‘‚ÂW®r½. Ø­2G,û¾ö&RØIv:1¢–‰J•úe*9‹ÛÛ¦¢ã•3uŒ¹_À GŒ¸€È”ñä ´£šW‡é ØÞˆÀ»BПQ52 1Ø€ø˜Ø¨uñ½Aãè€Q°‡ðy²3(X›Ø’¯’±ˆà˜ÂB ²")¨Ø¶‡Òœ9BÌ‹°®Œƒa$ûÈœÚÊ—kKŠ|B`“0`‹€ˆ€È-Â(t&¨tÂ(hÀ›‡„BŠ\,¸w "K ±Ý ø™.XáÁ!ˆ*+€¯ k9*i´ i²Œ‘J¡¸”ˆBý3ÈŒ€BõX3P{‡±¼ñ« !ÝŒ@ Ô3˜~@€8€Iû»È’ÆŽ(pØ!ø@Ù8 |š|€„ vÄ>!h€ˆà €ÚŸ ú<¥1<±}B|ˆŽ"ƒº ™¢º€ÀÉ «>›º `±¯‰ƒ Q7‰¯5ñµ°„¿˜–i†3€æ“›v¸ùD‹+È ²ü”€PÆ´Ò)Ä2©@ŠB "Àç¦Yyœ€9“l”ªнøã•P›’ƒŠ­Q(º Î5+=ãݪK ø£ óïºÜpÕ¹¬…««àï“¢y¤ °ûõ.€£“45ᚯy]‹±A;.Èø¢°¨àŒhÝÀžŽq^œjVÂañkË — Kè¬éΕb"¼³ÃJÆÊÛ¹¶°“ؘóVŒŒ Æ¡ú{¤ ÊØºL+²ûÙ ¼ÉÙ†˜„y­|Ë:ÌÜÌ—:i˜¹“Ä7°¼)¢3ÇLx˜k¦–jk¢|É©B/M©&\Û™šÕ ±g¥Hå¿Â8™º‚qÀÄȤ ³ù–2R«±%É1%²Õª²Ì·x•+È ƒ”•éy*Z¼õ‹,< "·ÒؤŠÁŒ "Œ¾"z+K¬Õ™sßÃKý{äÀy‚ òÌa¦3ú™¿!2½&Ûî«ÐÁ%yy­Î"°˜!C˜9t>ùz­J˜bÍ­Ù&TÏ‹¸›BcbãCêY]µ‘šQk·«Í QQ âW²ß\ ŒÐËÀPù$åÑ>ÑIš${ü–z˜sæ¬ñPÒ½Ãq”b§@ € ”ðŽÑESÀ–º:#À¤ž “Д³QSCø ´‡Á©Ðv°òŠ€‰ ñ òù ¶‰‚¦èÙù•  «ù.*3¦›DÒ%‰Ž «)¤ø¯‰ ¼Ü.²m9‹8€;:šr€`‚˜Œ€;àu‡ˆ‡dŒQ÷ûB©§Ø{F é(ôÃ*QJ(ô0‹€2‰P᳡h”ðz»-{˜#ˆIË*õx¥c/‘ÜÀÁÐ¥B‚Öà³Ca#È‹x»Et5+è 0!‰Q½‡èsÔCF/h~X ˆ¨wØ ±pg‡ˆ s<ˆ» ˜ñ¬Þ™8} È èÍŠ]r"й&2kÇàÓÉØô‰©(¶ätÚ¢NULøU(ù4£Ú{iQµÐß‹ˆ¼Í!‰‡¨ôÙCWˆü á ZZW9œ–:@ݹ[¶H2X I&è© ‚½©‰›º æZðò#ÛÍàÿÇÑJQ.rºÍâáM! ˜ªŸ‘§-’‹G‰£OÈq" Ÿ˜°³!Ò%ˆøÊ¶‚Q™d©[h”ŒQ ¸JØŒÛõ `½¨ŸYm¦)‰Úì›Të‰yVª¼™ˆñ/¦{Ó ¢ôh®ÎBÇ•qº¥ÊÆ#(Ð3Üp²Ó™6#ú]*kô¬øŸÀë $6¼ Á@—PÓ–ºe›ù, Y˜;™%•‚A ‘æ¬$wÔ™Ú1{ˆŸº¥hŒM8“P¦žXŸ ëºÈÅ]½±0Úã/+ D“ŒÑCqB§bÀÑ)øH©©ß€äÝ‘¿¿òÙØÌ`uÂYÙŒÔb+”žÏKß›ª`‰šKóÕå’ 1_ày+xÓ¦ØÒE–_u±IÕ#ÒùŠ_%.#Ò,zЫш¿}µ­‚3‹¹æÐöŠ,SQa‹m Ó™ªÑ“¢}.)’?é“P]2½ÂÈÒ¥Ò㥶õ-æ K[q Ëý*pà.2,R[ë«Á‚Òéнéͬö+¡ùVQ•!OkkLþ0жNÂݘa—_®/cŠOûø9Ûý\f?“<¿ƒà Û9O2Ý<¶úƲ ÉŠðß2àÉžAº²Ø~§‘VŸH܇à ñ½€!Ë2ý  Š€p† ‡¸sxyÄ(ÚÖé!§H©ò©ü]’¸Ð Ïɤ”d°•@‘Ai Ñ´0˜•‰Ñ­¯lÍIÚ G56ˆèz/Ds»¸ˆ¡ü }‡å_ÃÙ@ŒØ}3$È’€Lb åk1Ø{ðz‡¨x$8ô‡ˆ{ (|}¤µ”ÙJÂìÎI‘ú2™ò«á !º2²Ê£/x+hY@Î ˜Šé „‡¸` g#7 ¸ušð}€k¯ °€ P‹8"UÉþœéäÌøï‹NÉ"i‘áRœñ595MY@ãTáJS©Ÿ¢œ(P¥ßÅÙ"˜ËÞ±—Ü{ªÚÛQß`‘·Ö»å¢CxLU6õ €QË&X—  |OÆ‘Œrô!úߤã²,ÀÓÚ†º´øà”NAR ]>sQØÀÒµ,P¨ eï)F±½y&ãK˜ß¡SyA¥¯àso”X¡Ç«{9ÜyºóºÐ’޵ÐWÙ²©:âÄÔtëã5Ï KùP“‘TÔÒFÈ‘)Œ•ê™Ú:@¹*CLÆH´‘ƒã•) *m¢£S9Ñ=:±¬ÐNP¡;¸Ë£ÛÛ¥A+©£`^Q+`é^ ¨¡UJO‘¼­Þª±àÑ6¼¬bÏ@ÙC øî|÷ÌлݛÉ(¹M-‘I-ØÈ–B¬è—!É;O·ÂKÓ€ŒÐ¢Ç|Þ^9]À(bk’SO ñ•!8·,ž5Y%xþamÖâ)–JÑ_kƒÉ“ï jFLp‹¬‘-RçÏs²É¼ºKNÆ©]}¨ºeŒîï륎¥)IS$ cË,ËùZèc%½ÎÑ–ã ˜•—`‘*ªÎ2`ûõÍ`ÄÔ¡ëߪiªuâ†(&6']ù¯‘X®ã´€«‰yaø¢+A‘[K{™¹pc2Œ*®ÿPžFÌ Í’áÊ?ªv<—‚µ:Ö?’Ó¿‚H«‰,%xò áCÑÆ¥®Kc½¿úÙäJ¢Ã˜Þ d2»a몘ÔLC™\•Ø  LMgL0ù³Àµ&º²Ž¯3Àcá ä ùT ž»èˆ‚€8‘:%›DV3PŸ›@|°w•°°ß¬Ï2ð´‰@™iÀä td€`è°Œ‡Xjˆøzöû¦ŠiÝYò_½Û¬rE,¨³Qg‰’AˆdN^hµÀæ[D\€z° ^¡4CÁ§ŒäMð€PŒ<”ÎS!û‰ ~@|\ˆšìçuc²k¯Q =­Ž(›˜`áAàÆ%nAÑ÷¥ˆÝê¨}Óh~/@/Qð²È|_ù«iTVwh(ŠÈ %ÎÈv«/ßkr+‘pY*_íºÂ€É Ó°ábló`Þœiuˆ°± m<ð—"‡Hò# È9øÞÍ F=1mʨUÑÃC‚føµHàÚ"[x:A‚[CJؽ›ãcÙ௠‹j“‹|Ãɼ†û± ‡ -ˆ÷2¬ªÈ³¾rÞ+IP¸”ù—Ö+µ£UJù• ´óuMö©ê\8Ã-ü Ò²•ÿ•Dt‡±ƒ›È!¸ªHRÊ/\&Á~OPÞ§J¾t2u ±>lÚ—”êäü‰L¶í±ÓoJš»Ìª’p¤ íÛ(°Å0šj•Ðî’Š†c2g·ðPßý€@ð @€p`øý¿ßð F`Ñx¼ÁäÐgäv1Å¡ql‚.‡Á ‘ù˜fJeÑÐ*†Èâ)+èÅ)qxô.¥J’À T¸l>EßÒ:¼;«>¬)$qÿˆÕŸöl - ªËá¯ÀP ]©Hä7ØèÁ™É©À¥q>éx—ü+r°î1™ŽV¢Âìp¹üBñWÈè0°h…J/£ƒà²é4*?V”À®¶{CóS.ÅC¤ÙøŒò­®Èqð¬ÎrÁÛNðµhÏånÔÄ!\NC«L-ÙÎï[‡3·÷å])N¯ÙE#hÜbg‡y,½ÅË/ƒ£Ìñ‹c¤º¸osÒó¢« Þõ:O£×´-K»Á®”Ô€ŒÂô0¨âç!Ë;Nô:Q ÿ¬ êЈ¾n³ç »£°8\ç¢ Ô$æA¬|^è¦òàø;¬+òô;Nƒ¬í9ðD ì°‘}DPL ñ­Ñ\™'ï:~ YþÎ!ü”Ÿ'ËV¶²Ê`Å2*©ø¯éJsŠ~«.ºŒ•,8…‚!˜}'ç¹¦Žž§r€ƒÇëÜò¢P¬S=i ¢³H€0O 5ºç±ÚÆŸÇÔÉë®ßŸé+ü€ #d1HkÜ~!GÐ  àŽÑìñ䃮 !ø”à1îŽÑô|SÌr.¥ øRç¡øŠ@-Š–¡óhžç¥¢tÐ ÇÉ÷Kž§­/8¤uãÀõÍ­ìÚÛ¬Mn NÈ›@†ÌwšTN .ª³} }RéäøÅÍ’ ‚@ŠÀð€ ƒ¬IòxÛ™B" é 2Á o„4)£ Ä kj K£ï¤Æ¯$Θè°Iõ~:Ê28–¡©Òþ‹¿3G$ÑÔpÆèî¸Ç‘{bïßx.]¡gò’ϭ辺š¢+ä9+èÒr¶Bû=xµ¥íB8|5Íš2Š+Qú¡DiR ³êê²ÎFï¢Î§¤É*2¢¥ÜJÚ‹ š³ˆ§êÇ¿ˆ ~±MÒ‰3ªfx‡¯ÌzSÈÏ©Âþ¬ Ò.£‰óÙÍÍãÅ'Ts\ü>©JÆÅN¸Þ4°† ®ÖñÀ;¶’š>Œ³:öû°çŒ™¶Rœ×ËãÒê­¬Ú$°&tæþÖúÉY#€:ãç®î\Òœ„T€Íù +MXוuö|ÎIiô᜾l A|('ˆÒ\cÑb>]6# Bù3z&l›ÈîÙ>ÅÈ——ÎX’™®x¿¥CPÐ $0S}úYÜ)‰ƒFµy™ñö?ŒSr‚¸Š7A]iˆ)fÈú>³ÖHØr-hæÀ¸ÓfHZgåž+RÛ 4VDHr)9Ó‚ÐÊÛ~…õÁ’ä TÓ¨g¨*>÷Îtܪ)HÇx­¢ä8Õ <_A‹n/žY U©ý7ÈI%¢'Bv2CBh1¤Ä \$ʱFi §ÜÛúg‡ ¯Ê”y%dI”CQyŸJ¨öAÐÂ@eø3æ¬O2 8„Þ˜ÃÙ& ¼–‹òÅ¤ÃÆYt®AˆêE•b¸\‰×6¤E±8$ìÕBgÒ ©ˆ‹’tªI~£¹–Z%">3–ÎùX•åO“’D«`8 ÈáqR ”¶ü™ê¸P,8‘®ðÏÈ¡](ÒÅÌÈh˜MP `9OÐB€T±£´k·5XEÉ)Weð× ââB¸k N€ê>˜ûê|}­ÑU"Ÿ@U’‘Ö·Òt‘­`Ž&†X•ļu£øp"Í€ J)TÑì7Љ«ÁÄD@@ö©*ÕY€ãÙ{Ï"€‘²€˜ÇÅ}|@q’QòÅ–ä}¯¤P}Är¥À(!Cö>©9ÀM“ÒÆ(Åj˜´Å>SpX£ì|)po@Bò"5榒’B«ÂccéVPÀ ¸!ò¦‡Àôä~)p —Èä€ÃÍPІˆÊŸãé7Ë|\sf©Ÿ @‡L Ã2ŽÃ7äP顊1VUÇEÃMÙyˆk¬pžT.®çEÈ“.äô;hñ®‘"Q]#ñíH¦Xœ9ƒfžÜ3pÅKŸc餯‹í&8’´AâiŸ,n5²FÂC†*OD’Ó] »Älá³3LD5¥HÔ$v´¯ùk‰Õ=F2HeaâŽ-NˆíËž¶R¿‹$š5Rh[ Mú/ aî—–¦å‘„åèúaSNöÜÍ{¤±ÑòwˆÒ~‹FáD þ^É‚ŒŒ(8”ë2™y„‡m„hÛΞmËÄb^ºôŽS!ZüƒÀ‘’R‹˜O#~0H¡±C¶àߊŠik* –îënÄ…‡eÕƒaS¡Üƒ> é"’PäŠÙ®žúÌ¢¬>N¹zx&™µ––Î9k)?I½”G—£!^•ÓÜáÃ<Âàö¤M'$¥åŽc4sgô°“éì÷‚ûÖ†@ùGô œ'ýúÁ¡"¾BwRl¿òá¯ËÕ+.õ¼ÅJFáù/Û¸\9ãÓ/ é0c.žï±ôJ´!&g¬Ü[Ðô0é1?R(:²íºÇô Ž‹:±ãçÿ!& Å¢ùç1ˆB –ºjw_*¼ #é¯1QC]5…¢çNÿ´f+ÝÖ\Š@Ç çÂ5‰ƒéh½±æw¤9ψì˜N9 4¤ÔŠ:’¤ €U±.åó‚•Ÿ1ü¦TQgK‚ÞvxE”¾®¥æ*Ò«°b‡¹qµ“\÷4,”( Ô¬S° ¯ŒSCÝh‘Õêb@(ôÌÕ à‰ ±þ\ˆ”¨]74Šº(ÏçòŠ™X ä€µGˆädƒ¸j,¢R ˆ ¼:=¼›œ ’§}çˆï,êµ—@£,Wù&ÕŸ)îÀA%y­VЧkdañ„‘:–²?`À^Úä¡GÈõ3ÎA2ž#T…à†HL/.Qgö€Rå€"«ï‚V£â8£<'ÖfŒ*"6kB7GtÃ"Ò'(%†‚£H,I$g‚ðzÃ%ªX"Rçä4 $jã‚‚†~ Írª¬ËåL†¸rã1Ã2éâ,r"4ÅD–WÉ⢠‚[‚ÀyãØu#Œ;£`= Ì"DgÈ¢¤Ã´D4àŽD¿B2$'ˆMÍvmÂ]ÉxÓÖ)ƒ¢?dˆ2" rj ;§ZJ1$5Ât$aò:'ÀXʦ—‹¬gfŒŒL„<Ìâtφî"¢b`¢¿ -À/ê*ü¤ÜÖ(¢¨ô*Åh‡Ê2»‚Ìè5¢üzc>0G"Œ‰6‡f¾*GH0æàðÈfÂÇn16%L~ÌnGæ°™F¬ãC /nˆ•¤×(ª=†³„;­²4Ž<Œ$b™c @"àM¢ŸÉ|ã#ìä“.tÎI8ç)ÐéßFŽV2¾DCÊRXžrÒ•cž|ÄdÊ£Û $&2d r©¨´î2“Ivër äf•Â~8D¡g$ÒBMêMc+$˜âŽæ. ŽTFÉþ@&BÖ£¶êV5AúP"2'ÞDã&ÌTJfÔŠ"gxSAø¤Æá‚‰kb±1~ù¨`j` V£„òy€€Lbð¹B&U€°b"À>o1¡èŒ&òÆÂSGè%.Üÿ±wLÚsŸ¦@àebÖeÏx~ðdðáæ°U„.P.ú±üûO<$aö+KFP/%!êëÊ€(!Å.Ċ¸&^Å+dÄȯj&!åXòÏ7ŸN퀄?;¤ÆèÂH!¯<ÒAþRêšbå>à€ ÿÀX« pÂâ `áù< .‡ö`zÄ€¹DÐw²Z¯0*+ — X0RŸëª~§j»5d-…Ã@äêãB€¢¤¶¼Ë²ÄgÎMg&Þ?4Æ„*ÕBU’\rtÒÓ"„GjiCèE ¾„!N‚f[ä,d’ôbHHF´6Fè>ôÒ’M¦:jX%Ãð?'¢ì‘Ê€bäLr'‚Rã„!†-Ç"Cði i¸†H§žëØ=çŽGê*‚âÐ!符 ¢N§x8'¬Ç89"y .Q6©ª…‰ðE§ôÂx£¤i".pM£B²|°1&è5Áð®Šj<£¶OòtL¨gbU‰éä2ƒMÀJ‚$0ëQÌ… Õšfy”ÃMªYKî %’hÒ®Q\‰xÇ#åWɆ"¢ rŽ¿RˆÓCZ9üŽÂóZðRˆ"FPÃ!  CþŠTü‹F ³P´‡¤‰\(ÎWÔʪi- N©aU(|2Ã(q(WÑ^<©¶ÛÁð>"'ac‡&æ9 =Wí«'+è/ís'Iþæl(Í– ®D"&ÈßÈþ¡bÐSI.@ì,C‹œ›Nm,k´”’ŽtQ;lDj™bÏ&©6=JJ'å-ä,ämŽE-N‡,pl„­ &@­åRímQü&pJ<ã·U²nÊDxߤ5mH"àävH¬7n v•d‰‹`‘ð™DXI–Øëc€AŽ^šÉ<[‰Ö=VààVÑ ×s‡Ñ2(k,dtž„\A’”ßWAr‰v;$ŠFsC0 Ïn)Ío¶¿vƒ†. (àG5cÈ‘¥.}bBÏf%X¤ub{Ðú!6(¡DT¥¦ýi ¯&µ‹1¤æ#¡ïyÆBçZ<¥ˆP#6Ö12¬¥ XE´1K^ Aê€6 "´% HÒ4w$Ï-›E‘ÄIuäÄxÏt‚Ñ™ÂkLr³KT€"¥Lq¤Ålb&lÖîÃ!ìW(TA`+ÖåY»­I„ƒÂ>|l Yh ’Šªá‚ù+÷À`¹îXõÙ{;dg&aC„|üë ð$Û½§ÿbG¼‡eøvkô;¤Pq§`“ÉVVÒÐŒYí²ÐÃÀŽ>N#e[½{£°v@…<;‚.ètgaÒ^QÒŽC Âx?; ÈÇK¶âˆ0;Õ±Éy‡9¬…¥U5ÃN˜M„™ëåkµ†ëˆ ”äÒ*ËÍÛñTBŠc©yô3ØónYúȈ°ÈÑè!âAÚ$:%‰(›Û-$káÅ•þîK¹V!¨Uÿ¦¤ú"T)dcfy™cÚ`»–`–4*ã¡m-v®Œ5ÿ2Úk¥RŒ¢†xk+0bEo nÜP––Ì„=èöyMÐ…Ñè-æÅµýDAºø—9Ø'ö—•¶ûy‰Ý¯6D–§½Î9¤¨V# GLªD— |ÄIvSDŸI!xÖ¾™»œBràk3xÒs©.E¹[vñrúõ&“Dœ{G«©(iíÒàzioDxÏ;—/·;qû æ.HŸN2銦>ãpc»î2¸AH‰1è^@Õ_ _XŸ ]^dš>¯µ7jåNOím¤É2ÞžzE÷·sl¿:@4ÀAºÂ0ƒ2€* Rï'ë,&S^d ê'ªE‡çÎÿ¤6±Røg‹Tk‘L-¥öR/Ë6¢¡ƒý-ÞÂRÆP¦@€à7àüÿ{€Oð8 ÿ€pÈ$ x ýÄÀP  àˆC@@È#éܾݑÇümù†?Ÿ Xý!˜œŽü>â€@t@.‚Áà«ÅÑU`@0ðý¦4ÇûõëÂÞïYö¥ ]ßpp* @Á€¸ñðù>Ÿ¨„¦N‡¾Ÿ¸çÓæ*ÈÀ8x *&¶‡` ® UßÀšî+:¢¿§P€žG´I(Sí´‚%È œXl€ÄâuJx6àðãéÝÿ  õc‘läN/kîà(¼xþÓzðqcòV%w½ñ|¨¼“‹ÖŽS$]Ò~¢¦Ž#j‘¨Oøë¯i¤ê€-£†åºŠzà»(â7·Nêê C¨}¾h›hõ"`B"ª£h}¸Ž²&A)\¶p²¦-È ƒÁI ®}B±œ.A/þŽD(˜ÝC"4±ºè“צH²Îá:é¤`„¬qšƒ >`üÚ:J¡£’bŠŒ¡sº­è¤,ì¨,c';ã¢õ¼në•<¡Ò~à*,;<ºp 3©öðGQój‚>Ê¢6†ÍT£ºé6²8ÐÛÇÔhÿ2#ñb$MÜÔû"ò,5 ϳr¿º-´<îã“?“c â>gムªÌÜø<hLí¬ŠRޤ5׎ʙ'/ê*‰Á ¥È­,Ém²÷ZWpº*~¼ËñuHˆâ‚Ìœ²þlj †63“|áÀp4'BÐë­EÒ¯tºˆÂ4óˆ÷Stõ+;QÔÓžòÀˆÃÕ6>Øc‹R¥w“º ÁötÑE¼3¯"ÖOeþß8NëÔŽ&‰óˆØ¢ Ó0ŸHö.IMîÏ&ÔyÞ—“MVt ’¡¥{:¯u¦ÓzV¦?StÕ·Yƒç›ft¥ñ7¸3ºõÓôü;°»µuG8é›së¹mp¥í³T¾W?fU¬6¡]¯Ý‹g@ø«²æ(³…ÀjºÞÙÈOü 5µ8“î§jé\Ã{¼BüÖ)¿oww²S+Îúèzg'lë}Žù¸Y É%°|)áüYÈÙŽÉb”ÁûK@þ `$²NȨøp|–•qú>ÇcCØÇ€Ô.dÇÑ ˆÐ|€SDŠ`ü„,‚?R€!L(œÛ¥…â~ÇñL¦h„$‡ÎuGÑcèªqûÀPÀ0¸YyÃôz°ˆù½ZØìœþENAÞ8¨ôŸ ôÆÙOQnQˆ!h)ÂÄøYª r©L½!ƒƒ%X¾o(,ëÃEFH¤r»Sïê€2Š¥Ö©LŒE°Ú“ò&ã*”zÎß6æšñ¼x$pˆœ*°Rh'5FE0pRBE;ìØ‰½”føTÌ¿A ì€c‚€¥;RYgÁ9¶51Bàxˆ8Š˜¥0qIQÌBѼõ›B\øU, ;¦tŠ€CôÙD6;h줜à_d¯~ ¥Süu_d¢L¾F3”DÅóšh“)À©¶*”úlMÉ,àŸÅF׎±âmˆ=k¾Ó~Õ̾>h \´j§”ÊÔ"'¬  ’„µ:çf…3skÓQº§gpܶR~@ÉôGläý26bBM¢XoåA–"†åÙÄ0ê‰:¿²þ™^²Ë“IÍ2‘f¼HÄPZDpŸ¦;8H¢H!ª^X¼7z×ÔÝ,‰èºm¦ŠX]ßÚ-DgõP4åI‘œ‹_å<ðUdj»žëG%j¥J+C¨Åk*úZkTƒ¡ÖÑ&¹½)q·#À¶2U¨qº`éHI6•N<4ªë\ ÈoOͤ“‰_œ3(ؘ璲R;((HÅʺwl»]0dï%üÆQNífm½µPzݺλ¯Qœ©ÎX£<¸ÌÍàªUŠÒÎ67þüV†›šÖxò˜²µlã”E#zU•š¸özðÓ’¿Rä_wnì”ã vøqÝa—„ÔR£Qu-m·;'\Öž6 rXYÇKY‡[â›r7>¬µ¬jÌÚó„¤xTð00 (ƒpԻГКl/¤A(%Ò/'ž©µÅ x˜ãIÒè”L\½·ôHàÙ %ØD‰¾5³\×GÜŠFP“ËÕ¬rõÊÖûS” bk¿£cÑH¤11cýørg¤0`dˆQÔGKû€©ØÃd’mÖ¬D$Ø@>›‹ˆøc•è¾™@6M` ‘ Mˆ)ŠãÔ…Åí`ˆ÷0¤¢âeJ  K © W¯£ÒÀ`/V)“ ü´Á´‹&8|È"t +A$pPN‡qaŽ„é"öû˜R3ÌâC` ¡‰úÐO²9 ôFú\í¿CÑÁL±SÞHS•, ha.¤¤cŒåŒNFmlJŒaax&v–ϸ?+€úQG7E¿¤œzÚÃTŒ•KÃ)út>— xš’’ËQzP¬^¬$íå1“‘AáÆíGS‰F–­•æö#÷Üq;0E ¥Ê3‰°ä˜»á2ì“ÆRƒdNZH”Iᢣj¼OÁE#IžGFV^Ò¬Á³ksRˆIÓG&j Ó*5PèN—{3¥Œìú†ÈI Ë6i‘S­˜C«É)óŠt¹2o÷~Ìñk Øž‚$€nkœ;€Ç‘ƒ¬˜„Z³á4ã|84Œ"µ‹Ðœ#P{áãBÈÅ6x:n´Xº Äêù*ÏÄPzçÓ5!(a$JÎ{O,9k9âPN'z”w–_½ ÊQÏÅh™éPq;YÁ;«U9ïžò&ñ”,ËØE#…Û*è).ÒÿWŠÃ_™¥ˆö.) ­¹ ª‚Øiž¢yœò´b‡/±â“úv°šn¬éѾsÑ±ì ·™á›¨°š’¡Wž"®y±·™Â±‚S<J(!Ú?´ ®«ÀBt1Ì™ÉÙ+Éš°«ÿ2£›ƒ× ¢šª*J‘°AäA# ‰l˜:ñ£–©í1 BQ䟳 /IÈÀä-œqk:Q­Á»"ë/±²÷CËñÒ™éZ&Ž€ ˜)T,âÕ‘sL»´aa_>ZXy3–ú_ŸHå˜÷¡÷ˆ@~ˆxΔpª‰S¯¡Ž HûxÛ¼ˆ§³@ ˜èˆØ½ ¸'ÄQëC9ô=KÔŠ ŠpŠ  ¢`³8} ê¦!TŠ#¦˜é—(‰P~€P à| è²%’«`€(•(¡è P§$ƒâb>òÐŽ‰ ‘’+Ȧa%Ãr€’è½ÄSª’y9—Üߺ¬ž¸˜ªA¨¿Á ’„\,1Ó)ß+Šœšn™Ì7™?®¹äšðˆœ Á+ª"ºÀœÃ[ –ÊÚ­Ú½’¡A‘™lÂÉÚ©@ññ´B|°JC±Ã3ÉÚBŒAѲ²¤Æ«ñjCœ3Ï9JR©R’<±Óà¯ÕBÒx¿´4@*OÁ¹Dž3&¸öRúcBô1ÐóþÒÉCIØB’íÀÇ.Ó.ê˜Q9ª ©TˆIø"`}‡@n•ð}$”•«÷‡³àʼn¥„˜8Ç#jI¾…@š*³„¡N˃ I ؃¨q,;U ë‡ÙWEDRÄXƒ‘‹„·¨7±4k|9ÿ+Ð 9”CÎX› ŠDg4Ät‹…¢(w¾B̹¸èúÕ¨Ÿ<]À|"=\x~¸ Q6¢š&G©WOq_ ÅPÁ¼@ py‡Àè€0Ç Ùr€A«ØÅÆ`±×tÞ€pG(~¢•‰ˆ ‡¥¤p€B ¨”äè` |"Àˆd^€@•>’YS; bØØˆÀì¾” 7jœ)ü‚G„–’R¯`ù*”`õ$ªÜH¤S‹‘¥#âSˆÅŽ¢‚ ° ±jL²É5 •´Ò›ªʤᓨ¢® ± ƒœâ÷'ØÛ¥C‘Lð‰€I±x¡«œúû'cåþ°ñá/Í?Ã4‹ Ã¶Ñ B €ÐøË@Ÿ8i {5P‘‰ˆ~Êà’¢Wˆ9o«@Ö³8-ן™ªSÆ@‘ $E^$B‰Õ‚[Šˆ+¼ª1C@• *®ÍÌ \w¸);lP}U°ÇÞ6•€DgÈ47Xҵnèy‡X±µAœ¢Ñ” Þ£‘XkäÕP»›Â-Y,OؽŠ`¿–ᜠ½°·¨‡²9:Ò ”:“²&Kc£P‰`˜y pz‡³\ –ŸÐX†ð‹`Ç(½Ÿ€|}zA‡È|Öà^– lÂJöUzÖòPDÁ²ûèf0‰ Ü«ñ1ÉÔÓ;A)u¬Þ¡'`‹©1.hý€¦:}:વñ ¶†Í„“e˜sºY™Îè,vÁôOOþ¡’+}:±`ÜIüŒz´™›>ÝÔ …Ë|($— Ɉš°&1?Ðñ â.™|šæ(é ºk  ˆ©FÉ«É/ZF-’³0à&Ú›\%þexŽ¡G²F;ØåKØÿªFÖl– ãÚÔÝ/šuI `ÛĶ٩@޺˪ñ‹,)‚d!š)âz¸Ð¿Ë%g0$wˆ”?mõÙ\ðýµW•BUȨ©»½/ºÇN˽PÛ;”&ÖM¬1¬]’u;ùËk‘΂m½QFo‰ ›™z•Ðë‘5q]`鰲¼‰¼‚m:ѩ΄H²J0­fì–¸ˆöð±á Üì+™) ášeS•T_:³m¤&»ªa¾?Áò86#Ã{Éö!ᢪCe Ñžæd“c5û¢òâ–šˆ9 :ΓdJý-©ÖmÉÀž¦Qf=ähñÖã/¬\>vJbÀñœ,óßÛçBìCg 1 ™ BaÕ8ü³pä ne™@O2_+­CÎ 0—qžân(aZìâá²››ª=6¼3îѾca£I÷/ãß:d.0šÿ±…:©§H$þ'/ÔrÍàãc€î€Øø…#j,U§ "Ýnljåf¯Å8xÚ ± v =ÈÏ؃’ *˜¢·•#€&Š@ÊôøVa Ÿƒ›ah›]˜`)`\ˆÎvƒ Û:œÐñQ#;•ñ.˜¸2Ȭ Å‡ð• KJ‡à|Ũ ²/D©ž÷P— ø}‡È¸”6U zå—Œøãö 2ŽQnA_*ÉRÞIÚÞÀ‚­[C;X”i)Ç¢P”MPì‰Pè[¢0•ñH àÆ Ò«OÛø€"ˆ`È´^o£¬Ÿ²A/wz;¨§[  HßKášU1­€ä>)üZò¸¼ª©éFÄ´YÝôëÕæ¥1@÷Àˆ© Š`³ì¹¤Sž¸‚(¢HÒ5ɦâu?‰cÖtä3é[/äÞæè$„ÖÎÛ‰J—R•&A©}rH}ÁhòÓ–í½ ñx¹àÚ¯YžïÙž›É *˜¼`ùÒÄ•#$Oˆ‘L¡±ùô™êF%sB™•l°r‘R››ÿà*¦BHôXê†Ú*ŸÜIp€ Oè @0'ûü ‡B€P(¤Nþ…Ãá@$:'…ÄaàTz$DãQH[øŤóp ý›Ê¥RH ÿŠI#1™M3  Ã(ô$œ *~Ñà€ ©À¥TФf³\Ê£:˜U>Ta•8Ü>NªÉè3°%z)rÆeðZd½r¢Pâ€9œÎ—,¤Ç05ª›þѽ\¥“¼žó ŠUàqGÖ,¾Ã+XŠUú 'Âh¡5ºÄVw’„Ñè’ÍÞ×£ØîdxšÌÆÂÚhs¬´e÷“v°û>·u Þber^«1Ÿ¶Eyu5OjŽfkŸÖ ¨^´4õ¾ç׫[òš_â…¤¦Fj¶Û¦fÖ kzšÝNóH˺ðCv¶­ L£¿ð# †Boº’ „‚ þŸ§º8€ôª!ç¹Ø«Ê~b„ ˆ2Z ‘Ø!)Ân”! º~€Q % *Ê"”€€8~¸òX«€à@"‡Ùá%ŸÀ,g⬱àk0²à Ì}RÐ7¹‘ñþ«¯1 @…Ÿ§ê§€d”`˜A%€`€rÆØ|g\Îðûާ²8}´lôŸSor<Ro ø—-Ñ n„. ¤çÓ<Â+ƒ5Q¤€€èš}Ÿlt¶Ç ìE4¶8à#RL­Pe<(™ô~!k‚`X)J<¼ ȆBê¨ `àjÀ€‰ îÜ ¸ã¨ÊŸj± ÃÚ©9÷(¨[4’2èëÂÔ'q|ÀêZ8BB•.¶¬v|#h”I¢*E¡E5#º‡Gqç-¡3Ô`”: ”B’¡ïjŠ &vÓ.ëÚ£†±+j÷/!ÔÛ‰À¨p^¨¨î›; ÔáŸ=ÍŠBìáÈtC]LÓÄE3JÊïc%óÑú¼`È:­®­Ð𢍣@¤èÂ}.Kƒü޲ñ–7m$-ò0œ'iT¸‰ÏHêЫ¥µö ½±Šç|¥‹b@¤m úƲr[ ÚßÊÒ¹4ã)DØ!©j÷M3èß%·ÉÍ­)Ò6Â!j&ÙÁ©³ñ1~ìÝÚˆt×NŠôÉ'ü´©Ü¯‘}µÔ%(GJ”&cá7¢êEùOOd-¶Fž’î½@­j_ÚïÉFåÖsÍÿE…ü¬dšm9›ý<*‹OáD›\,HŸá_|o¸Í0òÚA›‰3?f伯ävPˆ!æ#Šùþ3øWyö(/ Ó=óä|ê5%¹¶ –¢tÊ ÆsFÙ½ Ñü\HL'qE´¹ #HÌŽœ*/gÔ08bÓ™éús°Ž­G`n!ÁÔ‡o”ݱÍJ#•†g‰˜u´}ŠÌL2Ä CˆTÓéÖ7Ĥ±@"HÏ!!׉­ˆƒc[u}§^#4“üu£¬;GÙ6H€|KL)-xíÚ$"µ†æfªH›Ëü%EVDšUiø-‘DÄœ´gº¦é¨£ú\b±r:6Q¸²ŽVÌ´…ƒÑüK$ƒ ¡Ò:@\ƒ*äò^lCõ5ÓŽ?Çê-Yî ¼tvßÒsîIDÅ&€„Ž×±‹¥±™õX“ˆZ^*å˜ Ò-CÌr’AòÉÕ[DÆ€|„F½ˆOƒé8ƒ.fú®zPí>*2"yâ+iê~VÍ>ˆp Dzθz=8 ¦‘Ö5’XþDd<« UtZ©Téi±§¥¨h º*RЍ$ª÷gµ!pÍ[!ö–Ï2ÅjÒJLuzÜÊ@Éè€äð•RXú4c8Õä>H"£¦‘ìŒÐe¶ž€X @ƒ ¦sôC’BP6 ,NPT¡é©!°DÈAÒ‰GÚpU„!±>Ù=Jˆ› ?¤aÚ’p ^ëûÉD0•ƒ“b>] )/„|£‚ÐqÞqªQ&x gÒ¡ŠNˆBÉ¢ˆÎG³cF%¡;¾¦@ÝáÓ+0HÙ §Ð]ே¬ª£ƒÜɘu ^3´G5J]£º ¤X±Â÷ÐG‘ÝÑ@¤…ƒ‹ÈÚ¬F«h—=$@òçU„ÔŠ%ãtƒÖ}5ò|­¡ø÷PRp–$Ò——.Š‚K2Ï”ÇEì„c««/·s7¥,X1´pÇŒ®‰$­Ô`—jö’4ôÛÑâŸC¨‚! Oˆ;:•“Êj]D5R¬¸œ[p}˜=­Õуè(K­ô…0ØæBÄ‚5dT:r\åCò» $q½_Wtõ”“æ÷ôû¯b÷Ah¯$%MLJ˜kBo£çKku8†&&;…ÀÀ3"3"  7R)yæ]‘e ?*‚¶!×Âó8”CKaúü²8´ [&»É±dZº—*„<}¡äÀAÄå`$‰¥TTÌë1¥ÑŒ§bBbÛéìWåvá;–‹ïdÞH w@ WÚ—ÏTIĦ}"‘ì‰êZ*Tkµ•yæˆG¾$%äv¨8U´DÕígŽ]BÆ|KxFÍÑTtKô+ê†|Ûí¶… ê?#¤„âv•4-̖Ü&|# {­¤„"šbŒâJ„þ-¾ˆ±Â.1ƒ \ßÍî°ét0-ï@ƒ–°íÐÊ‘?¤Ôl›£–OãTPÀþðˆI —1ÚD‹€”INÒ{ÈX‰ñŽáˆ6Ѝþƒqœ@b’…ò)ÑÒµ-ý ÑØ>½Cð< + ÈhCÀ‹-Ô¯òÙ’Òí Í$ƒ—%jÈä7 ; êá17iBŒza§:„-2Àc~s­ë'$ @,®$«%¶ûlR$å¨ý¨^âÄfªJnÂÌGëΡm´¼‚º™†‚Åü*Çæ[…VžŠz™¯ú‰"®ªb8ù2vH":ôD¨º§æsERV¢@~.˜eeLGb|J¶ÿ‹NXjB¥€E¯ºŒéÂfBKKÖLàE¡èï:¾é0kL SYè'«žEn$Dô¾Aü€¢àëD¢ZD²E!êäçºüDÎW¾òÄDje%ž!Ì€ Zö*aôâz:#Lfà „R`8*€ ÄÎàbD@;øæ¶/ƒ"G²6.FÇÏ”1Ðîm®¡ÐdE$$Lz@´ æSfÉ㮑 2)L AòNíÈzCæˆA´zÃJÃò"ÐAOŽG">a¤„WÐŽ±”S%´4º³ç~,pÕ2§„§£Úœ22¦‚-Ö_b¨…ën ‚PH ŽÉ™";"zBÐ’‡Êäâ4ËÇ’%â"Ï‚.fSú¬ƒ—&N’nÃô4ˆâvÝ¢’×òh;‰BÚR4>ÆÛä+ŽhU#þALýSÄ,䃧†”1à•É>”ÂwÎ (•T?òm0jû^ÉB†óH­b˜¯ÍÈá+»bâˆÛ«’qmˆ95`mÞ1’:Œö Oab(Ä/V°…•„Ûéd ñcF @2à^™.ÉÄh'´äÁätíCl|C4È¥XD+îîÇ:¼åŠ“â3©8e¹.“ÀJPÁÿ8ÄDž¢FNˆ| IAÒ`¢’ *v¶b®¾ú»†:±7 Ï^O„ôñå6‡Äl$€\¨^ëEVæ÷>éØ;FªŽ´™šêjLŒ<§±è~D ²½Æ`uÞNHöT àb® œ¡òÁêE!æ¤e|°¥€E  XĪ˜â¼£>3RÆ*ÃÌYEÊ &„RædJã>ó¾@LèzWÁöAÜ*€Td–À&3ð¹=3U5äP¶C˜eQaò»ÅPÍ•UK|Æ`°§Ö$ƒ5wƒíH¦dK†‚(ðLËF¥4B„,äB`e:`%ø¤ðæ¶öŽ6Ë9”è¡ÅüY'YC±kF—ª$äZF&D†ô<r,"@äÁg$O¾4ðãF+dµ1bNÛMôé¤èy'ıç„Kõ*%¢™°9"©šGÁ>‡¨ŽÃkpgßLl cXäfd#|9~X¹ÈIXƒf‹D2†ˆ{CŠ¿ì(¬ÑŒÅu‹ty§Ø„C.Hj*u}©6‰¦KË8 :¹Å¨6£öòƒ>±€f }?F–5wSìJ¶Ñ|Žhv`kœ¼ËXGÎFGˆ(<–üvøÑ8V/+éÇ µFé?‰"’„wÂD,i„§?cGB‘mBäaEP4´D„”½Ö[!ñ‰mLÈr_`+`G-ÝQ-È’)d‹mÐ2t‡’:HBÛÃHé’ 0ƒ²Ñâªq¹RdÐ —VLÃQšÞ¸.þ•¨Å.þªÔñfÍzséegÂHÖ9vEŸ#¥¢z“BÎ’t…l -dÒŠŒmÇiuy(mÎf‰e%2hwõ÷`çÜ*üÛùæàšuC=GéHŠÃ_¨r?Z­Ýj1ÖB±ˆ4(™cãB°è\•úT„V s 2Lê^ ¤[F8EBW-f¬ÇèþìÐ+W¨=@#eFO@/r3¢@,v^aàž`@&žEäÁã E´N…VÒAŸrB‚Š7«Æ˜G3=Q$GRgæME~$ôÁîKZ¼ ¦ײIoðöHáý´"xûhöYŠF›¤ž4îâ­8ˆî禮IºöïH¾æ5ê–[à*àEË´¢aë@:›Í‡^ìHòpUfK}Iôõàœ `6¶à WîAéz @F!à&­áÚ#@àI< ª¡bÓ¸£€&²8ºp²c|3¶ŸÎíMÚBÀoë\"¦˜LñÁ¨…PôÝ9<`B6… ”ÉnšÐ™†ûDìnI'–&q§n¼ŽÂ¯O"R´…Uq4¨%™ Í‡2øî„)ùbZ»'T¶Âz‰ävÛ0ÍFƒÔ±ªOs™µ„yFp3¬2´#r²& |¤”h'’1̤TÊPlÎ.¸+¬'œV(‚ã5Y‚ŽÃï«GqZyt”&gýH‹c¹« (H1ÏŸ­lú4kÎjCµ^/ÚN>'L„8ndI[ df4•¸É"Þ§§‚¥M?-n!Y ‰ŽXÍ|¸ê2Â4"âFþhÚùB—+‘¬`"Òª£ÅSÉÆèGQ±Æ” C)WNv"9múßUõ!ÞÑLê‚V^+ÝÿN¡™^”–‡½ñÙq™¥Z¤mâÆkŸ-c#p”¹Ó™¨d”dïâá~OQªá¶ _]Þ("€B¢gûø‚à)ôé>ŽPõö÷ßÏÀþG1Y G!~ÈŸ¯øð! )d™÷cÏùdÒU2~%èèi €Ó9Ômë~H  út8ZÒz-vŠ ‰_õ9` @‚¤À:Cùó&LŸÓÀíù7³ä2 0 8~ÕßTHëöõ\‚Ë'’7ð FšÑhè AD¢?2À3úFú‚Ñ€ @"‰S̾$q­X*dú“H_.nz—tú;«ê8ø~Q1`5R3ÉdôT@8›1£ÁÓ‰Óýóo#¯˜àìö«‚Á]7ø'yßᑤt8$Œ*@I”fAWžÂhØJž_ʨ‰ºj“€«2¨ú®· Â'LrF‚ªàNË$2*Ц©Ãвˆÿ´I"’4íÄO¦ðœ ©µn2h–%hì4Ï@lzk§ Ñü¹€HŽ*ê“,£AHó"¨²çúô£¡ vÅ$ìòF~#èJé$É` ÉIÔ£‰”.Æ%°Ò;3& 8Ìóº“êà¿ïÃ$–Î ÃŒ©ÇͲV¢/I“êŒÈj,\‘ÏPbz7êø³$.C6Ú$²¨¥Í< ž´'ì–ÊkêF}Ë3B?F62úY §z»Q¬l#b²ÆÌªZ®D‰¾ìòB¢¨PÍ"ºBÕ…^©¶5ÊqfÙŒUŸÆË¢cWu¼r®QPr’¥³ò;d£Ò\µÐ1¢Z¥ÖI•¤Ô"´ƒD¢¯“Ó¾Z*,;ÉL:N½B­ XDÐ3väÖcº½¦¶¤ØÂn5r˶*½„zZ}Îì”fÊ5Œ¾&³ª½EWÓŠjÍ%‰}}$Þx½Ã'Û¬lmfH ’?3¡n×Jì©Vl,ÚšÒ–t;:ÂúC*Çwúk>Ü »+¨°µbŽæY>qcÚ ˆ“ÇÖ«kê2NÛmZ¾N¾Zi½é .“Ü×µä¹%6îzò»’Nšöá;k0ꊨéÜ6Á[—ÖOÂZh®×ïzâ¹ËíùG¾ëy?´ñœ|é¬sÜžÁºí–gA¾«ÜGÅóI´âMÛ-\r«±D˜¿\ÂÞœÕJ[UYΛ^ý}yS^Нv»æo§o½5R|ýEáú‰=¿u]þƒ [?#Þ}¢Š „"à )1æi"'Q¬ºŸk|Ü™N[*AÅÀÀ,\•iÆ]ŽÈ6¬h@’yÊ˜Š¥ƒ$dO‘/¥Y.“%6N‹±oCŒj»6N¸",iд”KØAK*å\Ž!ÑøJNIC^`ð”S`±0gQ›Hxd‡é°8+JA#ˆa §Py7#b¤?J\6=a¶Bt“é–%€0ªqöHǸ÷6ÄÏ¢n” %æHŽr®Àp K¤t|/ Ixþ7À°I€P# 5øŒdxúÐ ‡À%€ H¤¬d’ÃQäèÚ«˜jdP)rZË0Í’Ãj}M²Òkä¬7Ê}šyLÁ=¥D2t áex«ÍŽÇ³$IÊZÞK©¢>Æ úZ[:YK‰ Ldà^ˆ)übÑL˜µ†ÜYs$ Ò,Ó„¸ ñ2Në-*ÃtKÜÜŒí¢ WL×ç9Ãmˆ’k±æŸ™LÓWÏ@ØËdª¢“ËR) ÍŸ0’.Øël’‰) °^¦ÂÓ?)‰gMæêc;8‚±ËT8Ù+†š&YÙ¼Sw7¤Ò>I(ൺôôRËÛCÌðÊš´ nK.k}‡Î²BP[|uè1w:‡¨‘2@?®I›ªôÚÄ“Å[é韡6lU ä4IÇé°/cþpÚúû.…ŒÃ—Âh‘N1šVu~0‰yN©Õ|ª°‘§zÔq#%òÔ“•àÆˆéµ k¾‚"êþ³ÛÓ:1²¹¼-#„ò¨ƒ& }Ïš6JßÚ2¸b-²@ÉÕµ@xîl¶ €ßšÓvªˆ ³£4çU㳟îÅå´Ò:q^d¬™Ö»/lW \Ÿåñ[7UšN+ÖstH“Ï;)YŽr*õ©ºÄ;NÕšr.¦{¡ÕlñÝ#AW-ÅÞ”²Újuãy´§=w^êÛܾëB;0د𷖱Õ^YXg»·Ö6†@óß W´¬åÁ¯‹Ø’œŠ‡MO>Âg„ÚJ‘fNQ°D‰1‘$Å¿‘½6t¯WÑ„}_®6 ¹,@‚ž?G˜Î2CØv¹$̘ ±Ý›…Œ–è~˜—˜«1;“#:Gc9‚CˆÕYA´LÂ™Ê 1Ñd·#xhÐÊ0%\’^Ù7¤Ü”ÀD€?NiÇGª"Br¥ás€Ê‹— #›@õ£à˜ÔÂX ­h™Y ÌRÖ¤É`ªybÛahŠro€,éZÀ KŽ&?Mš0lÔ[hÖN;²W6$´H6匂ôÄn3íXRt1j€«PF Ì ~£à{‘§"¢Áð 4óÇ%9EÌ“ZQ©elD¯ÍQ¸M©~¦b ‚MrËé/jI¸ KŒ¥ èKÆ°î”Ækó%lºƒb>úfM%× SÛ™HY"²±(º*‚‡7¶•W±,š}_^aP6Çe“+žÌÃÅ“Dt{±#Œ¨:⹤µ ­:õ„CÁ$œ¡¦î}¥©†áˆ&ŠLÒõ0–MVÑØÍgJàUKEQÕ2}šÔجhüÕÅY«s˜©Ê28’0ö…k{…g$E–·M+º{§TàÿÊPˆÍ:`¸Ö¤¥|¹²¡±ž5%]syyƒÜÓhf›å“væi÷g³±äÐÇ3ãHæ-ªó¡·¹%¥GzÍ£¼F _P¾“rË-o%³'Î-IžéºÛôð,ZˆhqÁ1&„‚ð+˜ ÓFg-Ó‡g}öd†ò§¹ékÖ!´Åu´]‡Ž•YÊÌnÙØ·y›gÖa·þhÝèÚyŸºõðöuìŠàDÁº¸l>ù#•\ Õ3”4NŠ# õ#¶LëÆ¸‰ŠCHœnÄíÂà¼n"0¯îžç¾µ…lþg¨d«^Z§2v ÚxÏèýì ýÏŠoÏíÎúy#G ¾ðJkËV¾LJ¾ËJ@¦Üýfù Ht îDçBÁëÖvã¶O¯¨„gEö@‡ªCc*Rgb§K@§«p¾lWÞZ”·'D·ŠÀhBX;"Lª#¡àf0” ´*‚ôAââ"‡ÚÈ~Ob„&C4Ìʬ”ŠŠ-Ú?pÞ7ªD®@ÌÆÿ «R˜äLŽBPŽ adh‚ôØÀ$#È$-ÁÎ8€›¢úA£0—dŽÐLþœâ@€ )p-áþÈj@ÌÌbä1ð?–Gˆ6cF#”Yª0Ž€b)HQ(t&îLÙ.'ì$'(Âtìà6åþBîL©œæ¯x J0"@D”(ò™#( à.Â*ÁÐà.! D àà(h|mI¼_.B¥ Cä©ïð”CF–&˜æŠƒƒªÆ&D°81l3Åü`¢®žlm¢4PË·" 4UB"cªŠ6*ìi²k/x4æ>#‘´DFy#ò\e„áE"¦´UbqØb/0]B®j8¢d…„E«d|ƒþ[¤˜0Žf…Èaä¤F’&SEr1áü%áòƒƒö4ivcãä(øfÎï< ¨Žc`>ç¼(©>æSDwi–[§ÐYïŽ6#<ž²k…R˜d¶Ô.fÃ<ô‚ZP2ðQ:OH‚c#ühª‡"ôxŪYe`á¢É.ÃD¼Çžjˆ†òÉεCDOBÆÁÄòÎ’h§vɇ¨'Y¤j…öêP˜Ò óÇ8D àCæn¤Ðšª3A#Cøb&)K.² !þïClv®}-?2f$ˆM2Â[fæªd¾Jë“5)ž.irýæàø¤N.hfTgÁ%¼Fu°$¶²è+Ò1PDà&sbЏ ŒVÌF÷ßo}†t¨˜¦.ÄÅ踑hýдàP&{’hlP.¹†Jy-ç4ô1ç6K‚Н-èk‘ýïl¾çˆ¸Ô+Bä;½@åôReþ?¢hGÎïŒ5¥œ|Sã'"¸”t+¯; O¾§ûZ@ÀKŠÜ³ëƒ7)Šj‡TGˆv¾fsDf€þe¾·°‚NÆóHF@â”?7'T˜¯¼_ðvÿ«çA¬hz熿ð~¼‡x¾ojv`N Láæº"¡äæ0!mT–€/Aø,Š!æB*/ö9KÂLCld)nÜ&ñ\/ÆÔ0áü‘Q vÂæIâøCl,â:7E^AöâÙdÄq:.ñšØÉ’ L%Âè!Õ ¢ØPÑv$ÈiJ Ò±ÆbÂr&êC`Î ›;‚ D®–I+b\â€2P\JÖñBT‚ê‡%à qÕ9\pcÂn0h~©HC„XI“ÂÜMŒ0ñ$øcÊ0Œê:ÃFF¨Á_d@;BŒ<áÎÀd! J$\вp$`èUHž£VÂÞ0¤EE_†cŽ<["DD dUí,`LÅ$Æšš6NYï¢HtÅÆ)Ë’gÿ$0ŽÊ\7‰•Þb&ˆjÃÿ.Núˆ*&*vNËîL$ƒ‚? X?å>õî13fj˜ÄTD¨w$š²åXq@j$.XòQK.W&hxþc.ªjiT/œQˆö6<.­Ô/„¾²ðô6ÄHÔƒƒåvj ÆZÆ´¦Ž²fÐ6V̱NôžªÆaÐbâ¨DjƵªA0è­kDU'ðçLÃÿ/n›Å°ú…Fˆ3ÆKrhŽ  ¦æ¤$ÐûÉŸ/†cˆ["hDmAI@T…¤áDʬä²V£xTâZžÒî a¥,e-ÉX6„ 2 µä™Ä~3&´¨ª™î×såd3Ê/Êà¶²ÖZf('… uêDKÃŒýd°®p„PLd¬ãBË)zBë kzÄGXÿŠÝ-Æ£)XCŠ0€-Iª94ÖhÞ`Aü&ï"‚\Š¢Ì&Q|>åQ ,ÞkUØ› bl"_ÂÎQ|cÆØ©)1æàR 0±)à(™:â\XC~vá9-•‰ÆX—dr³¢6*ä´¥¬å®FYQpŠÎ%©Â4L¢¬† ™A7C ¢ÅZñ=ÓkÄpħ>ôÆïÓ)‹YsÞdÉÜ¥¦³.ÓŒÌ?M³òÝkÙ@<°m,§p°r4©ŠÉÍ-´QŠ ŽþHÊ$!¨b"!È&d"Û¡ø6ð!Ô'o:$cÉ\§ICyJMiC9DˆK%0ݱ‘yõLÝ£ê<¨'`â*÷«ù+ ìc7„lÓ'·rX´á ‚Ò—¾“ZÅZ‹Æ!+¤ÖÃTUŠ!­(…eS¿"N÷ža?6/ìÅAxQL‹fÐEp˜#C`»ä{åI—È2\ž _4†` “˜ ¨ ƒß, †BW´gSËG¤ –™²} AK/Fqöø,I‹ü/„¨Œ¸x áÌ;€P Û–“JêKt¦iøÈ’`"ñ£&Q0h )Iî>öò™˜Ë0/ðÔar?ÇèõE£ðÐéBÃøx!à8Àñclé$tÖ!Ò"Íxr€j'4ÙÚÎ'jlØê$0Cݪj)L}¤ô>@ÀHFk„ˆéhM@09ÃØè±ò;S)3ÉO€Ä€Ùfè|)„?‡àö]­A@”èÊÑ+¶WGÐp2…€P ´rH£Ôv•¨õ3Pî¢ÕzJ@Iž8`)ÒR>Çê€E-Ë2Wd‰üH¬ÍOF–}Ì’Îb§Ìô£Âu #pD¤¼"–“–®hªôf :e2ÔÁ€ÐƒÀ( „h@>@¤ËÒ´Ý“Â=ÆàÓL ¤šc&-rrVûTû$€Cù#‘UŽIÒêsð Ž&£èÊ]’-BëÇ2pDT j¨ñ©Ç£LìˆÍ4äìê’µ„ÌàÓ®bªíŒfzs—SXÌ¥½W¢ž R¡|¦Zš˜ôö‹Kñ)b•ƒ,[I#š/­ùZØ&ò×ÚÃh(Ùš1EÊBè{5sêÕ™Œjë{UlµüÌ‘p?çƒpiÉß+b[j¬™fÅAjXƒ¬Y#‘»vdqåH{kÃÉ]Œ%æWYþL\Œ+ëÀ¸²[‰UÁc!`$¼¶‚ÐQ˜!®{Ì¥;Н• ôV*˜©ØG›hLÛz½Ñp/¤koit‘Ð%7jre{A]¤Ø§=sìBü_[²‘䱸‚IZ¡= Ö¤5b*?‰óWD€ÌÄb„ÄÙ”Ue}vJâOJåvWIZ¹B5F £uÄUU¶cbhÁõ1¶QÛК¬¬ðÄ7ŠF®Cƒ‘K\3wØö»rò]cKV!x º§Ò¾º]±lŽ™f½•ÐIŸI/€P)jÂø% óÜ#4’ÁÒ=S]þZ{X#8ßh$_ ~;¸é¦f¸\ø3¾GÐPî%ä¼’JÓÚtÅ=Û¾·1Û܃F(¼Ñ‡¸­"#pq“hwõ"tDI$y¨_##tX):?ãTaÉyV†3"ÞÐä “Ü±t½¬½C°]þñŸ[l"== ^¥4†‰*D(‘¾»‡p‘ð»’LkAi'y9 ÙÊ`ö‘@ }È:ÀìcZEŽÓ¢Šq1Éø” ÀRc¬q1øpŠ‚â\aRkl>düz„¤€ÉècѰàÀ 3JÈ<}¹¨[J?쟈`='A£±œ™¤]H{%(ͨû¢¨ÚÀ¸|¨ÑÄ7†êÒ8ïÇéJeh¶‹§ê.’ˆùJÇ(ê_ƒ­7Jr»E%’{PõÔ>»Qkà!3Æ?ü¸TÄŽ%ÊmC¬ª-Åè™Èp Ôš€,Pð& ˆ°TBGqû¿À( Dh„3œ­1Hð~ô¡ü<Íð’`|…!›³ãye¡"§åöW‡ÁôdµÃ¸& oØYö$(·!vâèž²þ í:ÇN¢–¸ËJBLä­ðNìÏm£ O4„;ß^¸^µ Õ8‹<“~Ëm}àrì»^1`^9iúÇyRºbÈ[Ûßgd2Ëüaþˆ4Ž~-5‘ÖÒa~p0}X³iŸ)¦:¸’«ã÷€¹-Ú&ˆüy«¶Qˆ¹:zV)—-jÐŒ’‚á[À°§’x‰³¤¾ªí!á¸qÛÊñ/B´Œ8ú  ±‡Ž»Eœé¢ ’J’ Èù™€5)È=ˆÕ­k%˜1ÀP8X‡«Zœ¼ŸI“r¿‰è…™çÂ@Ö1ÑZ ˆô£žAX˜zñ@öŠ„Bâ k_ÂJ­+¿sç›Ñh¿\yÜ ’IÃÚ b5 âÊ j(#p·²£> ˆ¿Â ™ ˆ¼’Iö¨ÃF¨SU5¡!‹W™R ±ÙÛ¶›<ŒásKH k£1Û6š- D¢û73h–¡©3Ëë2h‚Aò-ŒÜF"ô[!T]ÈŒ’l> #šÄR´2"!;8: ©±žÒ/ÅE %Ä'4!ý²{P6:="% yýE)$Å j +OÛ³Ú& 0– asEûWˆÖµšT Kk# ,5n5sb³ û,5Ó\R)GûUA£<¯¸¸ ìx5€–!“€XƒH^øzps7xðÀŽ}ñ@;—€tÉyˆèÉA;‚Ûñ0¥¨}‡©ç¿‰7¬ž@@‹.Š£Ð”¹‚!øå8Ý€A•éxpÊ`¨X}ˆy9—x˜€¥p‘à”šº¨~€:[9¬Ko™«Œ;@ž.Ó.‘˜ýIø{ &‘¦:é«höº'£¤”}Àžªâ©¸;ÿ¢Û¾º0¨øë€~7£ªŒñ@9¨™¿“Ž$ îˆ€K»¥¢M‰ªž¸:M€0 J˜€@ÿ‡Øx†K€cp9 ø®) €ýai'½YzBɸY}1p@“ûêÆ o˜V™ÊÆ醖@‚€:šaÚˆP|¹Ä ³º‰‹™º¿ãºªq™™rÊ*‰ƒ¬‘¡¼0¬&Œü?\aÖ!X¨à•¨‘²©“¨ž¢£²¡SxµIœj&´â ’iqÊC†˜b¸è”H (©‰kºº‹Ã ª<¸†/b› sUAK_Yøíɰ¸‚+¬FLPÂRµÔSH¦? Ÿ(ö½é߱ܿ ýKÃâïÔý±£. <>âÈ2›Õr¦Ñ¬RÄxYEs‰”!U¹ù²3l õIPº ÝsV Í“2Hˆ!;T‹ã85ë)e³B´ ³Ök7²œSF Ö¬¢Ò)íÇÂ35vXNDë\²‹Xˆ˜Ø²˜ÅF":‰lŸŠ’!µÍS‰5•ˆ™tŠÝT4µð—5v|RÀϵÎQ5þbœ« dÖÆÚûÄãY¢¢-EÌ 6ªîW5 ÈMWµysğØîflk˜Ú ÃÙéGÞ…DUåó2úçCÌCCØ«3fZ€Y‘\–pm·p{‡Zˆ°}9Xõ&»…:±(á@€z^ú•Žv†ápŽxÝ€aË2‘³¶} ^“Àý£ˆc,JRÂË}WЛ—'ЇÀˆÀ1>’˜†“dLJý× ‰´ž$ù:ˆˆƒVЄP‘åÈ9¹–%ˆ|Zª§?9][Þ8ë-ŠêÊ`ìlAÊð»a (¸²L¹ޱ ¥i¥h‚‡ìðáÑ¡2Âi™«”xˆ€Xɸ{%ñø†Jr¤À€nC‡ÍËÉ㿼š?D¹É¸$Ø{b‡‡{—0|€ANŸl!‰‰Ÿ˜2—«QÆR{/ÑQQ"‹‘F†:œà„n•&Ûðöá2«œq«Bå¶ ˜Ñ¹¨ì؈Á†šbÊBµ ûúŠÆqÂD-¯°J$éÔT ñëBˆ°å•¼é‰H|P¼œyX¨a5?AÓÿÀ‘¨²° :µ¡Çΰ—í‰=Bu¡jAj¸â0iô¸Uµb8ÍC*™aºQ*0(»~NCÃóÙê¸>r+Ré{â"x RúåÀèÅÖSZÉâGÛÑÁ¿'€ÃÒMÔÔ‰º­+]ÉÑXŽÂ•¥¸u†ÓwXrøpÈš€IN‡|Âzy‰ª¿@iZ^Ž Žp&A”‰Ikeò_’Xï˜?:À\ ð:b/³˜ÊâA½áè“ñVKNù½ ·Ô!#°Íhv!ýhÈôÅ[k¯Õ‡F BJŠ(µt¥4BJ=ºW¢›ú²/p $f¥EN2+EQõXÞÑhš>¡ðB¤xDàÉ!Ø«w}XÇŸ¡Ùô  ÄªiáüÃÌC÷6PÚóE2$j ¯{>Ë^÷1ñÈ` ‰„BíU W#ÕèØäÅÙ&d÷²ïé¤{6`Ç(Ƴ•j-^5ùß²«3¶¸ÇФzÓD]yI±£)¡¬n¡/x „ˆG¶™¶ÌrYtjw2ƼZöíŠùž–0™Hœ˜ã1V·ª°¢@66è¦éˆapt†P§¤;¤¢ÛÉÝrÞÍ Üº±6êÒDhà‚I3Ê`Á8 ßh…I9ÃR3 N1‡¦·¤©)€p'€°ŽP|¤P‡v°ø|{‚Ú(lá]òr#Ñxz1,€؇ô§°Ð•›‘‹?,’KÚAȨjl 2ŸÈ 8Üò+†±Æ@ZÌr]ޤé¥2Ûµ¨ÇäˆN¢áO¬¿cW*cþ]¿Êì"º œY÷оQ@3è¥JGGµf"»­U&—i¹Ö¯¾n6ÎG£€¾Ói–ßÝã‰%ºÈ•Åqöý¯|Юç/k²,ò#Ÿ2*aü~>n²œ%i#¡²‹«–Ñ¥ê“êÔ¼êkPÓž§ }ŸG»ö²€8€¹î{+¬8 9âw$¨øƒ LTÁ¢ (/MÔ´ÂÍÚ.á>kúf²9ͪ΋¨J¸—#-ƒÆÎ5.#ˆéHÊÊZó"êsà«#ÐR¢É¤ÏR@Ã=I<’©8’Sg#óŒNSŠvKSZލCO”½ 2sËjÂ9J:L¦ÈEÕ3 3ˆÚŠ:/;$2L“:S‚µ<¨îDï7Ó*”µLS-ºLº€kD0“(ðê^‘Ô± >ë@,’v©‰1ú©9iÊm#‰4К@5ò•)W5µ û´Õ *ŒSÊ#שPĽ7ÌTD4ýTÖóiTTÌ;Ìô[ MWÍòÓi5ÐU­QU«Õo¦Ó1ÏÕEZ>IލºWýÖîV²íxóßpÕm…a—âñD<Ô 1ZóÍ 4Ü{déMÖ…SDK—³ƒR8¨éR´Ì’ùLv~]OM´æ>õ6Uˆ er*t› 9ºcù掀Â,  ñYñG)tž‘±ü}Ÿ)ý~ŸŸŠpćÐIÉ =62"·ì¾„Ä€X€€R?4àhÀüB~FÀ!îtlGz~L«tL€to pÊŸ ë€mLäDÁÀªBNäè(õ@õ¤çÂá"§ä;âVˆŸ‡æ¿ïÇæèòm¢œŽ©Ð#®' ûö¨A[À ¯ç±ÉëÑ<ÔïTáóÇ¡ïÇ¥ÛÀ‚ÜǧÜyöéà¦`ØZý³q9êy!@ €òù¨(€W2€CÐŽe/Ð Ý0 ?¤%ëW¹Ú+ŒHø‘å‚`ARRåÀî’TI êỔ§çfÎÊQÕËA±(ë™…ÑwI Óbçf ކȂëGØÝ%O'Ýr¬õàEæb\"êA¼™êhÀ©i©<Ê]•(¥¢¸å=ô™M¯š{HL§YêÒŸ²–eÒèìŒù&±ôÍ”‰¾, íI˜ÚDy¹æ1Œ-†¬e¦«•BâP ©‡Wà­ê2µ¦2i”*dçGê ©†Ñý×%eIÕ­ ¡«¹~+x¼¸ÓåqeÊø›%£ |ž£UüL:õH¢òÝQ&Î1fPYMqBëÅw­¸éc+‰ÄT‡ÝyU:“Y,â€c•ަ[E#ì[œS¬­”®›UR™ÃpWñê7gˆ£dŸ€ÀDÞA 3EcÕÅY WG˜Ú!Ã¹ì€ ` $ãÙÅ1ö‹€$Ï'à.Oª"i«qïp®d>@ x€N{Àb\GpçXíà‚)Ðë_ð#p‹V’Z¬mACúg<#çs.<ˆ‘d`ßz!H(È Bœ?§°XMÒJK‡¸ð5ÊAc?ˆ‡ñr„Y8ˆˆT—JÅD§xD€:Å1#â$@ɳޢà =‡Ùaù4@K™?`ˆQêÒS y|€°6IÜò%oPƒ0"hu#íÌpÓý_nñ¼€strþ=Ð ¯Á72j1AYrEšâü°mÅpÁ”u‚j 1ЧRpÊÑý!ëiö.Vb•ÐåeÔHDÖ2 |FE*Æqd£s«`U& xbŒ–ºT¨ÝM2’?³”'Ìî®L*ôŠ€‚ ]jò 8°ŠíÒöBPi'$I­âŸ³~\@2JŸ¦1Žf¡‘a_§v:Â%€çJ¤ÊÂ(É=Žuá`)ʬ­®Še4-êäþCs©O¨ £“ªôœ–×XcØ&¶*ªWWJEvèøYØJ2íY¹Ä€x8œCDº^áK¤ƒ¥4+¨ÊXƒÖVØÉ*•ÔjC‡=ÞÆï`Ž€‹ëA§Ž‘Èö@óùÐನáw@AÌÔÈ!oðyŽ×è#+ À0K$RÓ†´7LÎG‚4– ‘g](b°1í¢VÖžOÉà›ªÒm²d|¤½Gbb¡•½dáÜbÓy2~×ZùYö2¦GʨNanQÕ‚rPT¨muÕõÙfÚº2]}vò°S*áÛ 8¬<Á´P’jPÚacO2£†«X®Û†üp‰6•~ÝZÑ3Â’wÚºe¿ƒÛÖpþ/¼R,¥L.%õo¼o«®•1‘ýmPlA‡¬ö1Y:ò»è¢¥¦ÌƒÏ¤ŸäºèmMmh¥ÄÖK«²å´*ºYí¢\Šú­¥¼ˆæpKpòÏ6‹Ï´þ¥Œ^+zb/r·+8Ob?OHSF]6¬*’b-¨T P Ax"èÁî$@`€ ÄTaòB  !ÐÇš'Æ–FŽç6ÁÌ"NNÆÁð£N}£FbPs&æqâ:AJxâÞ'Áðæø@2òGaÊœ‰¬JÀ0º@.!AÊâ8 È¡äbºÂ¢Ú%@ o(o€Dl!BœrLPAâÒ0kîD"xzŒ~·ÀCP . ¬laÌ»ÃÈ7 Ï€ÐgÆl„@ŧÆðºã@ "89(E Ru†œuÔ‡™áü@4+ Ëàì"8̺àÏÀ¬üÁîì` n® b('ÄDHAð,àJ¦ö"@‚À̪EgüšãP @DN`N-⸿"%!Vb"zž1bj$–åÅ( †%…ò<êø8bh4"l5F{¢^<ˆ¢·düC Lä¶)£þ¬è˜>âd!%.+Ã8H$Ü#üÕc5mø1ílvhR/¨âåÃ(1Íxp!ú%ÂÜ%Ô-.ãªãÄ6€C¸—hü$"®IH°ˆƒä’ÜÂ`6@Çǘ,È.#ò,¨CîX#´…ZÂ/85í¼%ñ- &¯.Xð4`Î`X©^L*2…#!²¸„²åbä±rº2¨Ð?e¸—#®ãCà#"Æ$E1‡˜%ÒªåÃÒ5è1ä2Fd˜JÈø,i.ÓgH=ÅÔbþ_î&jH"mbaE~¦õáûBhAAâðî!èÈAòIBô3@Ffð%Áä૬ pÊa—'+!ì| Ïpâ0! " èŒÆI"Ø?HðXÌ:$)I*mð1æ&¨X®¥HÕb\Dš]¤“,ïd™úøh¬èþòŠ„^†s?KXÖ/¾ñ^³ÒV¯ü6ës@b^¥p/XfôÔ&Q-‚M«F´Ï¨#îT…>3ÅÄôRÂýlŠað0‰ 0ý¯\õ¤÷Ê‘Äôý…ð:”(ñósCQ¼²Ô$®í¼°ë ˆBˆ¤JøöTrïån²Jà¯È…AÆDTÍiC¯b¨F´“GDÔMå’ÞðñÏd‘ž¨´`©ªô-ÊjüT\ø¥ïHï>2bÜø´©Jp ´æV˜Ð £êÆ(”®´+ffúÎçGÆv6/ñEÂ. Ö¡þ%Ü• «ÂÈDó; ‚¸öš0d@AÀ»ÃËà DzÔºDq€@G¬‚Ç”s&º~ôEÂVsbo€0,0b0èÐ膿Ì„Ž–?aÄ¢~ð¦= F¾hĀϑŒ}dF{3 Þ+¤@ñÀ€Aô,ô¸"¤P5(‹ÈÐãaÝûVäìGÆb~Ig€L "¦ž!5œÀßâN‡¦ÉÔD!ßS ±6À}b47-lEaé `/ÀÀi#D" l¾µnÈ$+µ¦F𛬾€}cžAN€ÅstD(+±œ ` B$‚ ! |H"$'ªú'e88)"ˆe~…dô:åæ+Þ¥B‡=în:Â6yb,*Ê# Ά ðö°eF×K„ì= Â1èîÜÃ4]@ #2¬y“A]"Dñ•H†hÆWhn/êjæ‚<ßí@Ó²È<䪉CŸ£hqîHRáÍÈ0ä¤NSHÂF™‘x M"3Òl®XšÂÜ”bJ–HšÂ#ïdJ8b††.^-ŽŽƒô%mípc u¯l‰ZŽÛâŽ0vʉ*“–²W)`=788³¼µtl³ð fÃ"jÊ—ÈMnmÜ$c †Ò£)Òû* R"ïÞ¡.r‰'ãÔ۪ʘ֨+!ýd a²ÖHU„G‡XêÀ´$B¼ò$Ñ.oŒO1â#€$}`:,Á× ¡Ø5: BgRÈ&Ð#€€ ,‡¦£dböÜ1ƒwlת²&1•cÒdäw%”µ¨ei.–.µÊvó„'ÂÒªsòþ¥ÇG/ŸO+X¦kILt$„ýNWOZ… ‰ãS&ë2mø¨®ÅLõ4ýL…â/‹ŠÓ¥ëJQ”|=e(ó´­lü¯<ò«6ŠOÆõ×Þ]¸Ì³ ú¬KÊ{¸ì6tN/γ¹s´ˆµ†O.ëG2>¤Tê¨j»-†a·*MåÝ ë‘t4±Ïô´æŽ2@Y–£B…?ŒXrejD¡·3’D±Ð–0´†R6Ug tFâºýøßCb¶ø¯Jµ Ž”Êc…L ÒáþÏÒ" 'BN¢œ!öDú0¦ÍY¡èÇU‚ ÀF¨ A²ÄBâè2nž4àiAù 9ÁYÉ¢À‚€«öêà“kžàÆ’Ä'á޻ºEH^"8>š'‡štMÚ<÷f/Q'Q§o' %Ìbàê€ê™rB¸àÔ€EQÀFb(v!ý vΉræ„Nœ! J«È!°qAê"+ Fè®Æ£G1ŽÌ1çDy‹öƧbPý£ Ç€EAø,øÜc:yg3 BÆðG@iêpšb'%"œ¸4'är.Gt'€SÇ¢D$àQÆ}©†/Ì0K9wÉý;GY#d-,4Ù/‚5kd^J„N’ÇŽ‚(@·:Ãì1å.(£8ØÜ0cÅbG-bâ'#.à®7çh…xNíÂl00$j€²å41¾0Îb-Š:®4R£JA$HâaÒ×1´7ƒ2=[èȧGw»þJƒþ8Mí¶)HLÛʇ¾aÓÚ;ÂNý2pçJòyv("‚L¬Ž­t%S<¡š+Íšüƒ¤ªÉû&øÕ$ìäÆáÚ0†!Õºâp4Œ¾á !Ù  Ö º‘n`Vjq."!ÂAyb‡­b€:žàÊ€!ÅS @*@L `Ï‚V)À ]BPLЦ¯ê†ƒª.(ÎÜ/‰5NóÇJ¨L“²(çˆþ`Î%êζYg—kYEëáòúÏîþÕDhÿ>$ó=åµHûåÏÃ¥@ªØ´ÏëD9{ÓãçKPZi“9T®zù&pXÊÍJñB” öÝ\/¾õ…žXÈþÿcfZdþ°‹mIYÐÔ@:…)J˜•ÙÖ0J[†ô—ˆöE““˜ÝjÑIJZý½ŒÒûýw‹ãÕ“ŽxTT÷³_—J“J¹‡Å×Pf KJ²·´gL‹Õ&ü†uDt;;jè¨<'Ù¦L¸"ÀÚ"¬Ü—ÎD@ÒHþ"âqý«¡ðlbºà„#€7fÁÈèL»:"ºu âyLøõ¹Ôl½†e†Àr #Np†Á¼º Qˆ«Özšº!DH•°jDB¹Háv+±¨"VðÉŒ’‚»qáìÓÌÂä)ÁêB0Ä|-¾ê9Wý5šQÆ}lÐÄM ™¢"X€)ÁôZ3U‚ÝQÈ Ú_æ$ÎÜY§h‚À nÖÆàÊâ,¸=šâmŽEÀgáß vuAúVŽ®Ô0‚®v˜ 1‡P!îkúÒ! ŽÌx¾€ÃGY"ç'ÄËñ¶±°û¡§`4®l†ºD²¤È¢üï"b¦ã¸m÷lNó|ê}¶)9Ï÷peHG³EÅ"A'œãv#A$wΩ„×ö÷l´i2Òͼ"½'iÉl"þ¿Àôà ð}à€˜TR?aOРò4œ)?äy þÃ@PÙ @ü„€òXü‚ Æ@0È+öW¡Ô׸ ƒ³PYùC‡L¥`´Â¯3šÈ&S[®›‚@æ0©.Tþ’¿åQ© Íü_È"eAG¤ 8}†M^´Mb2Ù5fÿѱÓéú7P¤ÃÀ²é®›.…Á¥uÊ ,âaº¨tΫ{­fp8& šß¦rÍ‚ïE‡d­òmFÑ=²bŸs¸fÞW° žÇ=Ýù ÝÜ}½ß@( À§‡„ ÎºÈæçnðˆ "6hYæv§‡Ò}+€`:ËPÔ'Ú^çªî †€À Ç1KBN票:Ö®50Ú’—¤Êãrµ­ š7)±z¶Ò®ìJ¬¤0¨ÌvÇ®“D“Æj²\ÇD’#·l¤’Ñ'pÒC#Ä(Rt›ÅÒ€’5’¬ˆÅn<˜Â±12L!JÓ‹"¥³\ˆˆKr§#­É³]ÊÑ\ÃI û51Ò<¼Ï0è£-Ï 4ß-GT"‰ ÌÑò^–ÅëÓJ&ê³°ô¼9¥Çõ77NÉ -Æi;@£J‰ ö–Í4rlÑD5œ‘YµÌsOCµiº[ ªµ{´çâ[ÖJëEVÕiD©JÈTV›L•IM”Å2Ä!ku§mN¥ÁÕT„§>Ü´­‘[E·Dï?Òj½À·TuuOJÉuMÖÑQI ;hP”ÝÏÊSl— ªÒ<ø»ƒi~â$ kÄ{žàèl—I ÒfK‡àRÀ (@"G¡¼þ†z® †€ìá ‡ ƒA[Ä¥º‡éÔ†©„‚‡3¨Â/æ,ª  ÎlfÊ|h€¤ x=¢€Çb rÉ í¢ ¨€ ð‘ð}‰ß¯(o((ÌÑê|D„4‚gÑí¢Ÿp» –1€.Œè¨ÿ¹:h6v) §€h(…°çÒÀÁnx@Ü{=ä†ÇaÄÔP1ð=âòû €(¦§Ñæ‰Zð€ê¸oG¦vÇ"|¡õCž‚ÏÖt$'wxȾ§Ø$$ [Ñ.`›¬X ¸?»yÀ@"ÝŠ© ãð…€2"dÊ1Z# ‘ŽP•òa4êu2”*šŒ{‚- ¡B _€†0¤¨Ð£”²J l(/ ¢^Œù‡!𦛂LT\„&:«â›X‘6*Ðy“P jŠXéx»Dd´šŠa…vF&»‹²n4†¤½Ô…ÊAH%…EÒa‹ 3+DxÆ£VI‰%%f¤±VR¼q25ž(Bs¡Z¿"$ ›¥¢ÍY?Wî "rY¹3†j u6C!ñ@K’<´!u$C)AM¸´C6gÈl}ÄqÄ) ĕҿ‚ÐqØt£ô}¡2z€"´ˆ²:#r4ôÓ aÈù.F•И¥Q±‘+ˆÅ*¤EZ˜Õúe!JA,23&ê‡U¦¸×*Ä~ŠÓzíNé¡-’tÖ‘Ø*‹!SñÚ#p ×ã©[Œe‘³ÀtQ\*9o›¥­(j[3F¼—¬5©óŽWÊ´n8«ÕP´ú‰+ºßƒ©7&…¾µ"G©eÞ´Uêš°WB•0åUÒSƤiÁMØ9­ rG¦ÊÒÐØê<¹ÕU/‹öÂÒ¤…ÊR\µed°«ÀQÂŽ.ÉòΪEjKVj[°¤5±Þ[¡É!ãÔn4‚I)€²cù ±Ø×€0ù§ñY°&ÏÀìÜòAž4 ®P4çQHLÛ@³:ž•ïnP€4 ÑI¨üW„~Ý£ D@ zRdô@ $¨  ´3ð"Hã…‘¨4È€ 8ú¦‚S ùÊ ~ÎÁò;ÉXøA$ ÎÐ óÁà&¡»yãå‹qæ<™Ö6ŽPÀtUÀ“ÕÄDÔyÑâx‡ƒÏÇü€Vä)[&¤±Jc'¤r"ÅJ´Ý£jïÑi”B”`,œ‹Eq¨„ƒ£ÔÔ‰…h¡m—GBˆf>) *ƒ>K¡fˆ·†¬¢uK¤©GF¤‡À©hãì¹)ÃS‚Aa»¢TöPC9º­RLŸÄ„¬ïÈf\Q‘MùL®“Qñ­H¥¼‘ÚÅ-ë%SI”Ù/h¼…,¢qkYz‘EX’R2/Ž1r=Z½=Ðâ‘ D’)\¿Yz¿)>ÁPÞŒô(“ ª>ªÖ@ºÅ †,Z°8ÙE¬!^-k¿ªqw¢“à’(¯–Bˆ½¡ *Ò×”BâÀô —+à©ò‡Ék”ªŒ«’j¬‰P”³à¿´ r£¾0ÓP6 ã’PwØrê÷znYÒ(} P€ÿ‡ØЙ;+{‹@} ð‡ m†ˆê¨rŸ`®/ø Ž  ˆi·!Þù Ä€™õ¤ØuYÂÈÔX«‡Xi({š pô#I¢—°|‡é܇ªð±{z‡èÀø…ÄÀñɼ€R!êZ$P PÎŒp¦8‚Aè§Éß p{À‡Eà“È‹#` €é°0ˆø˜pr›Èiˆl ¼E( ~€ ¦‰[I +;äV¨s™Q €H ™|0(‡¸¤H ³9Õ(±È\7¸y ‡© €žL‡ð|444aŠ`~€I¹(˜Ì¡èˆ{…"X°£ÐÖ¶@Ê `»(¯%päzÈ"&‰Õ"¸8=9ZacŒj/‘ˆ‚;s¹x« ¢€Œ“{›Ÿ!üž•l› Ü\‰ËûÑéI*05ð»‹i~‰h¦` ¸°C² åÊU E„ް ȇúDª(¨¤ êE#â,*×·¨ 2l‘)W&,¸¤¬³‰r¬k—£@â—²÷¬ÊŒ¸°#Ëd ä­ˆ•” Hµ©3¾à½Œ9XbIR”Â%iÊŠ‹Á7<Áœ7:Áé à»!Q2 2·’ˆµ‹˜·°Ž£Á|ÊÚ…I‹@Ì1؆`s°x|‡¡€°™K#Ðy‡1–pnY‹‡›?h¨€±Ò‡@kx€Ù€È3ž`‡é‹°{´T™ !Ÿ€ ÑL@³!!IH1R¼Šb#«È¡Ê:E)4’ƒùºõËÜ@ò‘•è×1¡j*%“x¯«|“+ŠÂyªÓôÑ,*5¸•<ØIœ!}• LÚÕ+@× Ä-,Ç–)sÐܬ)l‘›Ö“«ðâ‰|’òRP2Ÿ!<Á2½šºkÖ–lÎ@Qv«}•¤%¬³ü,hè‘XûÑAnÀ%)ÐòÒÁÁw%¹„»ß-ò½ÚØÐÍ«m?RÓd«%Í&T ®5 )<¯A—D¾š­J±0(*u.Ù—#BZ>‚ÄŽ)Ò3òËiJÑßMÚÞ–Y9­!>Ôãè+“•?p@7BºhçÀ 8¦c¸q01Ì@€üøÈAê¥uN5膀*Y‰—pØ« °™™ }´°hð€;Á1é|¹QŠ`êŸ(‡"÷ ᯠž¨~‡‹À !æ;QÊ‚E¨¤Èy»IcÍ»E= X€Õ¹X,Wš)0‹¤ „E˜ˆ”“2Âé˜(X~1›‘áŠD4˜׉öyñà3ƒX‡¹Ÿ…`X…øhr¯À€õd1؇hïLétu°ð¼xñ˜êDO#´à §ˆ€±ÙÈxåˆ(²èBð‡°pŽð|2ó ¯KÊ¢÷²Ø£’$j5ˆ¥#)±¼‰«‹1 ”ÑŠ4 ”Ä´ŒÄ8+š´ ;]Ò¹Ï;ºˆ¿,È©7œ3_$j5"¸¡ àŽ!ëq%qh%±„‹2¨@Ó‘ ¹;¨IHµ8‹¬‘l™‰:ò ôÓš1(x{V|€@}¦L’ŒÐÉÍè„=™ 8’H$‚J LˆàÛ”¼¦ pJS”‹{5ªì¬PÙ? ‚C¢9ƒÔ%Ò7ˆ(û¸ë¡Ã—¥0Ò¤¨€»£9ŒP¨ Ú:MÑ1LXÕ"¡d úŸ:. RH˜KÈÒ6²$—”;cÊj·%5þL„R Øz3ðwÑ ( F¨ £9‡Ñ¼‡XlP~‡Àš€Èo†0^Ú ˜3ú7(û èÑÙ2ê&FPà½An#O?3Î ›ÛÂÓÝÿ–åFÕsãÀŒ(Ê>¢À‹BTQå" Òœ‰Ap=h›RÙGÁ{ð¾ >‘Ž>µ>q-<âò›I¤• b\SãC§ëöÒ“ÝÝ2QÝ –Ê¥ 5¶©š’Ý=E©2AH«ÐÄÇÔé[Á`éÕSa­™*äÒ¦¢jÙл“S5T¬»èÂapÊT%,½”‘Y*­]0Í«… ¾å:SHÊÁ`Ó«åÒùi 0ÓËm#ëìÁ[ÀMËv2äùG^9+Vã+Þ@9jÂ4&@>K·ùB>2Âe3þ]ÊÑÐÌ%¨˜›—:³!Y‚Œ8ƒhaI•ÄÒve* 9 Ë4T‹ñKü\ãòLߺÅ#8|-«ž`@ô¸–‡¥² €kC òð‡XðˆØz0xÉí€XÍÈà‡pïh׃B£ÌˆØŠ`‡ÓR‡¸zhH©F•‰*€¹Hܹ3FC"ˆÐ|ÏÀ•Ù2“Ê/€ˆꇨ{Càí(~5÷€ ¼Œ‘Ƹ~#9öØz˜°Êó<ƒØ0p˜°e† Ð7æH!X¹ Â1Ž8Ñž2ÍéX ‹Ó l#6„gE2·ºŒ* %¹Ô¾:°Š#@á8i*%‘QÛÀÕ>TÅ¥X–8‡™ãˆ)â^­¸JI{›‘DàM¨¾Tcê0·7`¦HÏËãÖâ•?vR †J hƒ¡©ˆcæ]¡. ¯Kcg@íÜ"˜‡•èÌ`]½0Õ$ á¥Ë'ÔÖ¥0ÄÆXÌbãULÖ‘„œ:¤ ¶ŠD—95ÐàD¦9&Ëê@²x(ƒŒèÈê8 ´ÅbQt™ÍI¢”ÜÍ„XAHŒÆ¤ƒ] OuáÖÊá,®‹JC:qä(˜°qØp™Þ‡`t¯Âq¶ÁœÖ(wèü¤OX/H €UF‹È¦h ™’5é©ïȈ•€¡2 ¹ÈYKé*›qná Ò8 fÆ]ò½P£ŠˆJI"”ÐtœÄ“v+@ž-^h•îRGªZB䨩n=jÄòR›õ‘ºS©GÓ.]6Žp-¦–VãçK©Ñéu -µE.gSTÏ!#m?Q9F®UA¡y+äåvÄ%’äíTQãò“­)‚™•Z»ª=")+®!ͪijÀÄ R©É>(Ý =LQ6u—m+]!ÄÜ*Ò$Rž>k¨Žk¨dcÞQŒ:—q„ŸJ£fÜøž)SXRï‰À´ eÇumO©zÀMÛÿåŠÍÖm6Ôú·87µ·² Ó ÀMÈ­$á ‰K¢x…¥’ ¹› k½"и[©*X`}¨þYêþx‡A퇸xsz°…‡“À9‹ ž¨x€ riȈ²hCîi¼²‰ò‡ìûš(¹×BÞ;…<ÔÏK4]¡Â(먘ˆ}‡¶º1óF@{p§Èˆ|9µ m”/Ãωa¹®…€¡õ€À‚¡¢ÙÐy›ñ|3òu±À5ˆ{O˜'‹)›È b2 HòœtIÆÊ÷‡ëKÐ (Ô<Ï òŸgÎ'¹Œèp¹Äô†× ýúíì² è!ô¶%Øèߢ)ßëÙú8ä\@¬ùºK:í`oH`Öˆ½„Ž•¸ áK³£æ(€?_àè?àÀx@þ€0h,û b@Ûýû`€8£ö>€â@v#ƒAÀ‘9X—€€ ÆY?àq8 ˆAä“'ûú%*‚D`tz ‚iBÄèræ¹8i°‰Ôü¤Ä§SÙ}:{°Aç@8Põo Á¢w;1 §>€6·ýÎi,~Ná´:DÞWÅH®XÛ¬sûÆÂ uvÍ NŸÚ8l/ƒ¿€Tx-…p¥[ö¨”Fé}Í$iÖºáoׯìØ;„+dÇk zïÍœã Ô¸ÝoO¯…GÀ`)P;ˆ÷ÀwC ½Àð\1´ÞqÁnŠCµß;‚€Ðø~ rv¨¯HušFx Á`áPz/ˆ* Йæ|'``$°`z~3Ùò{)Éê‡QÔ  0’Ÿ&€Óµî$nﮩêÊá¸i£>˜±È²bÙ# ¬ˆ•³òŒ’šÊ»èûR˜ŸÒâbê(éÚ³,²ëg)ÈÒ‡3&òClˆÇÒD›$MŒª_82b^œÊR4޳O2#5Ïò’ÌŠÊ+¢å$K”É'ÊÓÅ !ÉŠbÔ"+R³5RÜûC3ò¤"'ê¡9Ȳ“ƒ8ÑÎ*”ï»tòoX6Ó*bŽÑèD–ÛPÌó3)¸NòS•lÛ'ÏÔ¬¥&Ò4]\›µ4p¸N¡P6*³S;Ê–m»;Ö¶Ô­\S ¯cÝ }hÊÕôåiYR­C@Röª”³Š„‘MJ“¥í*Ñ’]ëeÈwš{²mý ÏÐwŒ}o%‰’Ë€Û¸Šv²³˜¥-kOÕ)nã.}Rãq„…*êK¶Ñ HâË_/2Š>§eiÚ’™§MÊ7 Ì-N58ן´éþ†<ø~(jüzqa¨X¡I¬ˆ¨çÉþ‘"àj2 †`ð€®&ç¡Êé’„ÇšF¬â :~¬J„ñ^ìNú–ËW¸ K* #›Œ®}îÀP F’gtV}FVÌg@îu‰[ÔÛH‰¹ây?çß`|€Àˆ ¡·n Àè„(æÐ‰(Ñø{(AÂfX4?àœfŸÒdÖ 8{zÇÁäxJç¾¢¾h ,ÿ`8&›ŸPãΠàCô…L9󸸡­#žLK "¹’q`$ÅÈ’"GÍêº'D°ã•ò^™ñB9fèבÒôM 9n_ ”Ò¤"XØéS]g5E”äØ]È8.§Š #¦½0ø# u¬?³w »&‰”’zЊp(ÉLè´˜ŠC_…8 NFÉQK¥¹JÑüJŠ S,¬@ƒˆ`—ÑÓÍøŸÃAˆ‚n'i.3«s<¹ŠôA!¤ñþ“2œ¹á¼1FìÅ7åmŒ9+&j?“r ýû,Eü­†Ï• uˆN”sã9%j”¹²ö"Ó9"eå9Cõ¡bRS¦ Ñ)xÎT£ùË/ ÇÆ´$G„L§8R‰$Cˆm 04ÆCX*ä‘‘Ø8ÊCÀ\óçZ=æÀ`h ´" Ø`vñ´ƒÁ{cйð 0€ˆ8y«ì=ùCÄP üi%Û³õ ú£0p¾B‘s|Æàºñdiî5$ä¬l“Âì[ |²€T€LLJ²2© ª¥dØÇUS#6G¶ÆÆ¹ÒAÔHj!;-% u èY+PÐ?ØÖÂR™Îeç ðã\ ôLäÍn¤š$”Xú¤Så(˜ÒSÄ¢b;ZÊ®ª© ŘÒFUu$³à©Rú_PË’MUJ|K΢VR±2 £UÉŸ-2B”S”WrÆ©ôMnTÕ°¿Y…¢ë¬Ô¨*Jê-=!Š¡±V1,,‘•R§~Œ0æ¼—ŠLL‰qvI2Ãׂâ£Q„Ùà©Ù@MŠÆ©°R|±¥ºdbjíg-åt·SR…N6Þ·¥Ê£G­ê”& ¥“SˆG‹r< Ãæ¦Öh–€2eP" 9Øfqhº’v/!\”İœAúM©zS¤Ç<Û°õÃŽÓèGé÷!H ¦ê?[Àð®€À*WG’/ÜiAÏ9À2&+­8®1øbhYv¯XÀY30ß"‘a, 0 yy8’€¼×†€ÄÔC˜û€î;›SY'k|ÔD€º@zn’ÐÆøÄJãÀl’ªˆ €€!¼ÐH@ö?.ˆ|¾&8ïã« y3üÓ ± € &Ó>‡ÚZpôÏÃTN‡À D@¦`R4?´${J„*K°ÂŠAË,,Ýj;³Õ1 %E8Ì[C&Þ¡!]é9K30@”aŠ-Æz¶¢Ut3#ÅÂ*4&^oQÆ–.¦§c=K#2I«6ÜRœ4WŠG}œ™3¤b9›†l['"êg!N**¿æ'‰ H³èŬT„¬ôÚŠhEÒ˦q1 AÓŒF ÃhŽ˜‘r))ëÒÌ]õé1KöÚ'¾jàÿ'‘°ÄЂ6ª‘ Œ¤Ü¼S[b"df"RÖ*‘)äC(Z¾Zݳªläb%OX£€‚Æh˜I (r­KîJÁQêRèÓpî òW±clÀQİlÒ$S£ó1.•§03î;FÈß ƒÝpŠ€Ψx N§»°ék”à@¡ÃCthŒ4` œH”Ü}ž (OÐótt쀣iƒ,iB& ØYº@;bGqn¼ÖJO*XÝ’°©b³¿;Š‹•daw œÔ÷ÿDÔ2ˆ6IÆ+õY[Ù%HÎT…ŸF˜²L¸…"WXežÅªg8N¥KÞ¿ë«VexÑuv¦§ Gd™j¿M‰$Î[DêÂìÅ¿ó~x¦Vï}S–±¤6‹È©_eZœM•±}§¾"¤ýjF«íK,òÒ¿4õŸQȘ¨†B°ïX°ãŽ¢¦¨ÅF´Ã¾HèHͺHäàP‚côV·OF÷„ž€®mRó.(¸ Î\F4]°D³Æ*¦Ï4±+ân޵P ¸Eâúf M&·­¨ò‚”£bbÃĸÐwëxJ RˆæC–& H‰£LÂü*Ä´‚Daà>î/ aÌÇPV'RCçší ‡zAè‚zÁøɨßÀâl'g , !Þ¿®d^aüzÁúŠ*&ì@!î"t (ưɀáÄb8¡ "AöEZ–¤~!ÆŠJ¦ŠzÃFˆ®€( Þ,+Ð) ò?벆¦Äz¤VLöu py @ ت!ôvçt "#·ZÄ l@$'D¡`'aÖ¿@#€F`€„m@Lrø#ú!š'aÞÂ'€$?Áò¬®âŽbE„3€ \‚Ø.®cºŒÌò bÅ DŒb-ØFâ ã,è®kºèñæäÈø×ÂeÍí%Að)mº(#z#ø'D #µ HÐÙÃN¥e±ü—£""Q"¢ÆQˆ1MlM¯ˆ1È#`-ÃH"7%Ì4Ã(Ü„º/BÌ(ò$ËQòj½ƒ•£Å "ô‚¢h$Eˆbĺ bP#îâˆõ)ÀP®ë`*+è’1(è, þ$‚H$z8†h^Dˆ Ê@"ÍdTzÓÀ(4¢dΦ²)ÀZ !Àœà3âÇ‚€Á¨wÁÆð¡ô¤PAö!€u €>l Œ¼bvŸFÌÙ€!‚RXôÖ`G­$âpCH$åt1 ©fu â8ëCþãè»g`klu, „>ÁØœaôâD§žvàZºkbSªéÂvàIÀ`Â8¡x.ÇÊaâȬ'@Ày \cþ! áÁ€Cb$€ˆ"@Nçü¤-ð$VuØFèè²¢)!J‰ãa *X¹ã‰#Ó<"Ñþc0%ZKAë%rpJâmÅ6Xh†!)I.iZ€í¯)Ž.-p>6oð"> ĪˆÕBß&¤t' ð$ˆï0¡þƒ"ÊAüÓ¢ð‚#$­ì„*Jǵ6|SZ¨ÐQ¢Àè­àßc°#Y2Œb"‚pC5itIG²’N×-kêÚJʼn#¢ß .nOrÃMMй(ˆ¢; b&UÃBâdò‡tÔkz®„¥y)?Kz_”±ŠØ’„²edŠårPO²6DvS0q-`P¥)kzÛ£‚¦JˆþË+ðH[u<´9çè÷f ©%ŸS¯ÆR´Ù+C†ôTª[µ[LpmJ'ñIÆe)+Reþ™Dªt¢ç*Aöúæ4»P«|p£eCF¯¥2FeQ¹ISÐaHx–ª#PB·9Nø§…#DÐl9ê¢9ÐXþ¸ÂLã8£F¶…E’*°uSŸN¥â`ÙU BQ`!-ÀPƒ¶(vp¡£aø¤ìX.Ö|}‡`Ä$®~Âí"RÐñØAàR¢nÒ!ây!ü³“q9…çü>àÀ~Xd½îŠˆÀ@lLò<ÁÔƨ¬(2ÄJBèÃp‚qIŠá­ÈÄ¢î‘gÀŒÂnIÎwÁÎ=`-^€†ÄÁÖt¡ðØF@wAÚW’©¨š‡¸î>„(œd±mÀÇ‚hó'J˜FWC¾qˆ59áøCÛi`'(@NwXh!ãÔAîEÄX@,40BXÐä R£Ã6; œÕõ’æ$’øð fìÝ „CáðF&Ì&}p"×~EKo (gÂH'F¼/˜âä±w0’0‰zîK^1¨Ðß&X‡ ’"¶f‚1åÜ(©I‹2äî@ C W-aCUxERbň•¬d¬yG¨ø€Ã,%F€“gPb"º7£!;Ñ’ñ4ù:ŠÅæ0h°,h2M®‘)ĦMˆŸ{jmm„¡5§cb%8’‚öc„êV.@’o0ï= &.h.çk€,Í|:#‰$¤º×º<(#{ú–î`"òOÄCÀ‘êŠ 1qÄ '¨åläÚhXãn}ŒîOw8…òëÆÔ%h˜î á’à@*F`>ðำ¤ú’Áú=AØú’àM…òεþ~,ü€ë¡öÛ¢¸33ÈÿköQ™¬J¸ù0-Ð*cŽ“¸Àp¨hK~#” ÿäÑÅÊ@ª¯‹‹´ÌIäš-"rüÅ]‹iG‡HÆwLµŽ9‘¥Ó’7þÿ·Næð.O˜À¬˜¤ø¦ ¢Ãdxþ©Êò…—NYœî8)Aˆ¹1—…¾´¨·2Vä¾p£8R’ëIPÎq”¥E.Hþc+>8!úL9fIT;“©ËwÚä÷M…¼£]RMÐY*bÌ_˜ø¦ý0‰Tk‚tÊc YIMض³éJL´ç‰+Jé”ÃRÿû½™py9‰Ú·ÑJXÁÛô²Ï;N/|HÏ‚Nb¤_Y<û]‡Î†&ùê,ÀÚ7Ê-¶c4oÌk7ÃjéT¡Ü¤Xabï q‡NdV;ff5nŽ4LèJà*?ÀÖX€6AÀ 渵b"AómÌlB* m ‚AîºÁó©!òV¡Ë\¡ô&¢?ã$`b"K‘dS’œ®6¢²,f™q Œ‚§sd¯8KCB!úØtCüúBÇäÊÀ(@A륡ԃ̋Æ<à@Ȧ“aæÒ p BÂzˆÁ¡êÝe6à@@5¯‚ì<aômõC `®wÑ# CàZ ¾›Ÿ èšë¡ô>Êi’\‰‹Ô,ÃrÒÆ|÷'aaù`ã„­³Á ÜæÁ÷#AÝÊAîáhŸ 9ì ŒÀRÄ)D!ô'(My"LÒÅ;Åw)úÄt ÿAÀ þ?@x ü?¡Ð¨09 ˆ€Ïø ÿÅbP8, üƒAàÐè<UˆÀ€°"ÿˆ@ où î;…Mæs ›êp†Â"TÈ«î=šKÀ‘Ð3úùœW ñ(0$—Ç àY4Î!-‰Yjø‚_.·ÎRèõ¼¡Y¤ó¸¬"çe~Ü,±Ë|Î/aŽÉa`)­Þ ÿ¿Ò_wŠ-Ÿ-€ƒd¤s‹4 (‹Rp …†?¨.T¨0E7³Ìóº ÌÎ]³™€ì»H;çk ‡@áQÈt·YŸ¡Þw›‰¤Ì ~côzXö‡JéÜ:=ìæJÍgŽì4‘Üì&@²D.‡$åô÷Bá¼ æîv$ÉìÀp x`€*H`ˆ@r" \(€€Z`‰h£Üâ£çÊdá-CZˆ1È:†Ö¢Ï½®mdjÁ¡i{˜‚.h*£¢h8Á°è9ú—¸:²é;˃ɬ铼~Æ‹+8ó=-t\Ñ= ´–F‹¬–«$ œt¸IHDdÍÌS^µÅ-âÊè"1»x¹½l˦Ò&q£P²Æí¼äÞ.«*¨š13 jöŲ«:Ť³t%7½s›—ʉ™ðÄ®`+ÑSTƒ8ÄE´JAR *’õ¨ª,]I±1‹Å;4’½ÔêDdºÓ”‹]aOµå/IV¨%yGªé¤îÎI3-$ÍÖu›>Uij0­Å*ÔUëœW®Í'>;¯ yURTÜåZXU¬aEï«&Û-uÝ,^•LæÖÒ÷DÓOQ«Á>ÑV#pÊ4’’€€€ MÌûä_à  °à ÿC/‡ÈÞåi€`€8$€mPòÜdÅ@1€-5ˆ€Ÿ±Ø´” €`øÂA  éÒÛ‰9‘@B*&Àp(üúxÄ€ ˆh*ºño0âí•üUöõ­¢ÏÀhÌ•"OçXâÈSíó(ëøü‰F!¯øÀLÀ€P.$Œ?Ÿ`(Xo.CÎ) ô % wëÚ\_œrá»Y€hëê.z€¨¯ð 7&š<Ý@˜à­B ×_íÇ”TF>,ºke|í{ ±-ÜJD£@Ø —P¡®¦çÖà‹‡Æ=e hjš‡‰( }£§àÃg‘܉‹ êzŸ¹ø‹)° àÇ‚À *@ ؇g:¼ ¿g±Èú€‡1¼“Ê ðÃçø2Ø€gó ~Ÿìx2` ¯§˜zqx ƒŒ€ "à &~H`­(Lb¼± Ã1è¹þ‹#š®€qì±.Ìis%*!³ ÅÎlb14¡ªºƒ¡ ìâ1:i*«ÈË~†1Èl¾ÅÀGë$²H£~†ŸÌ|zƱHeDÇ“ŸÌm>!'ú&P‡º+U¡eEE7àDt±RøQЧÝ,"0].N(@¡‘ã6Èhj7è4ýP2 }oF#­ `ÙˆC Ã23í*±!”«2É!hh ~ÌŒyû9Ò¨EÏ8Û6Ä1 jd„",3tÀTüÌUÖe *Ì7…-Y’êi2H> ßÛXBÈKW+~š_·õµˆTv…™*δÄç‡1Ueû(ÒŒ}Ä„ÑØ^7F1tIø~5ÇÑð¸€T*ÏÌŠ¼~À'ÜÆ9‚ Œ€á"$‰¡ :ÈjexégÕº-=¡ÌSJ3 …%[êó9S8ÊdèË4ÛK‰ë»nË9àWŽó0ä»Å–ùm¸r3•m(l1³n8F%Kq™…¯˜nœ™’Òt&ë…áôž •RÛo1ÇÙ›‚/:À\>ñ’ÍX1ôÅQ<}#ºaÏeÒÎHi÷Âðs3ÎñØ-ÿcåY)¸Ù•‰³ß¶=³Ïoœ5ÿÉáým%¶`\<ÃÖú^‡?éxtaïo¾^ÇlÓÛ?»ìø/ÄÃw½öaÉ@X•=²m]š+’Ãe çQ_7düÞûc} î@ZºÝÓqZd]ö6WZØ^ÛåvO鯲…VÛ]k¢|pàÀWrýÛý‰n :xå Ø{N Ê=vå›Ä11ðAÁ=‡qÛsoÙÖ0Gøõ+m¹a Ç–‡PÃñ-±Æ3í‚ä£RÈÉ) c|‹¢:H‰ ,Ä\‘Ž0ÀPà¢rº çÅ!€è9hô&-+€ J@`!.ÃøÖ‘Ú6ðà ÈdFIÉ¿ÀtôÐnsǨê¥4e˜ú>ª=@)US¾Ã˜ xxÀ’QüȘ`LÉ‚°¤p!cŽDð …Gàñ$ˆòD O@ÚÄÅ.BN”¨äŠü{’¸ôQáøÚDH•Њ('ì|€T€ÇÀð;#¬úŽá¼2‘üä8PÏØ e$4 =Ç1õ€ €J Ðü:£Ðoê9¤Dü"ãôÄã?Çšˆ¥X°2xd aà=çüé{Ž™ðÇ€×(ÀpåBÏHFq òÜC@p.äo# Zp ŒqÎmÈÊS ¨ ³>=ÀÙV£ÜŒÂà?‡¢ÀA&•¥’€Òò­1Céì,B²úSŒr¼)$´½VÅw(J}hX'È‘AK|+gÙÙ:ò! Yf%åídÔ1Œ! 鈼6@ˆ$#bL¤RºC¥~¦ 3„–%;±2_Hšf$ÝC2¶ð­ÙRt"Ñ…1#³$DÔÝ}pËúSZÕä­S"Zpil®3ÑÍy^nUw1gb°HBŽ30^Â¥&Í\–SAm­Ö¥§auƳäÍD<øDüY:`b-}!…ˆ«^3¨~0©Š7†ÔíHj§z¤P‡¡…Ôo×Ñ•ì¹(Ù…ƒ)ˆ˜ñÈŒÿ‘–e‡Ý¡ATaÐ6Æ`Ä= 5+IDpéD`4 ¡ðr"+¬‰«ÖĦ”2f>D`Èßåi”›¦~+²ÜÀåË#wìŵ¿[Ë’oƒ®mïÖ&dÈ>äßô8{¹í7'ÄŸŸÝ‰N.:ÜêÛ‰yYŽÂb3[ÂÒw¦ý>Øæ›>e‡—ùæ½¼ë³9ŠU * å—fåŸÓz`J. :—¥ŸqóÑ|I‡Dç–ÜrÙ‹ÐZZåÔêïséo.¦¾wÝ t‹úýú¹7Xø´t.`JGEAEÿ Ý“È/33êÕþð›ËeÌÙFÁ"+¢TSÖØ—ïQ»H1œ²²’À#YërÏ¢Sq·ŒµïCYRû´{z³hëËß  VÖÏÎ8¸ôÀ@QF0¢šL±‘@ 55#Ò-l¢RšX‡´l‹bš5ÙUJ… ”À’è0À®Pè ä¸l^e‡ÐdH%qò;Q0ÿ§Ôs–=™° q&¦’0=Ð!ÔÕѦ@ •ï¹ Sž>lÃ#P!òuP Ê-;7%g*”f3DtÑ 0gÇèŽ`¼86Ň2¥tzc,:Gtx 4ý”@VK‡|\ƒÌq!4 ä¸aò9Ʊe@{ŽâàÁ‰Y5@†Y†¤¦"#¸iðaü<‰Àʦø’€À-X% <ƒ²2nÀöç^Xµq":=à@& ŠN‚U8!(ñÙ>Ǩî>£øz‘0 ðF|{?B=´ã8ˆ îRhïC“Œ=8@e‡ƒ‚<;ÀìâÜæ >€dl€xØ‘àDÂ\HÁð‰ö3B"`dèðHæeW„ú~(à¹e‰‹²TÅ¢w„Â2""­M¨Ý¬Q…„P€ Áe.Ì&Wë^dÅÚP¨ŠÊ àdrj(QË0²fT+ô1Ð"ÇEŠu&àG%ðP…@1ˆ!†‰ƒ · Ü£¦!„ðÚ…&[¦`G¬p»dvl+^´LBh2HŠcpxLJì`¤ËÍÆFaį$´ebO­tÓGºÇ(’ÁLr0ìä]Â) aô]†{Œ¾f¯FxÊ4sªd{äIJc$R°–@Bº¸ä¶u‘$pÍ §¤Ë B(‚¹§ˆ_,¢‚˲pbaðUB¼7Řvñ*"Àà˜-C²5ÀD\ÁÞHÂÆ@ÃR! Hir`,yæG„"¬RfÊÔœrçôÛ†úÊänhFÈåÔÉL¢o¥,mñÄLL¬ØGÙÈ*o xRpî¼§ÜÎ'e,Ù†(añãǾÑÇ´ÖL~Úh1Pi h Gì´|GfÓ1Ðrò `ÆKH‡¸oñÀÚ'ºrÆæÝë˜Í‡["aÑRÒðZæÐogÜÐgÞÝFø‚±LsçbÓˆlÔMfÔè+"‰SgÔ"uˆbV¢¼QaàAÈ)¡œí b¦2c,÷NLéâÄU@c,¡b îà‹+„7"¼HØ ¥ƪÐ1Aöâb,Ã\€+¡ê„!új$&Åz |Dh |¸aâ¼$Œ³‚Œ>DtÙ N~ëv˜@"àKÅj†–`ZD"8ÁîC–áîDrÖžAðÂàAê+  <âƒb6ªœÎô!þâú3|# I ©"*ˆâ\.F ‚øB¾ƒÚIö`6ŽaúC¸Á†¥ ¬ã䜬fRÁöY!ò,#ˆ8Àíb…CbŠ6©À + B `Б JðáÐ!¡ØAâF"!ÌÁf+@‚~Haæ( €UEÖX JåŠJ$üÔXJNî7¡ö¢+@²$¡ÿìÄ"¡øHÀg"š‚2£±DèØ@R„A/£ã(\¬f[ Fab0¥K<ˆ‰QBaï2»âÄ"ÄxpÇvNëæ#îP€\¨4d…uñÌU«¢'Jð½MÞÛøÁuJ!ÄrPÅ6^ Rtµ°ðP…¶1+SSDÔˆ­+g.M+Rq„ï'Õ\Yì—E(0À àc0±¥¨@c J‰t…‰P®R°{Å%Sg|…Eñ †'0ëj>E„MM”!à`ÈY•Ê¥[PëX{àS ž`,så3 t°s!Hf¿&3 f ‹*cM4Êõ>"U&îUdÈ%É@LOœÂÈ¥x(Î(ÎïB¡Í1àX`8ßB€"ÈLd†XÂåÙL¬d­°Vqú½Âd6!À×çÐídkâ˧êpæÊz‡õ]vqò·.ŒšÔq4ÊÄÂàsà`Ô ñ2zWv¡-‹‡g¿ˆppLªz«t6z]VžuÒk 1¶q‡¿¨og†z•6ÚñøÙlÚFUk†Å`ì€ÐÖakñþÍÇDÎŒ‚ ÞÜH>¼±ðÒ¬ÈRÉLlè"¨x€qm’–o,ùsVøs2s‡÷}ÆÖ1Pd ãµ5‰Œ+äˆ4ÈJÔ`V ¢ŒD€a²ÄAæ‚ÔqŽ1„!¡ò$ ®îuiöh+eÊ®°àA|`? ª"˜!Ì‘èÁ\.D€Ø,)`”4Òò¤†@j f2ÞÀ¶F Dà¡c†S&@i0@.îì@ ã°Aç…áìazD…TÀ"Cáî®tÁõLêcŒ¤æ•J©h@(ø°0*¯tÈ*Áê‚:VETœ¥4‚ â˜KÂ,€ <¡ü¢ìJ„ŒB˜AU$µÇêbQFbdGe pô±!낌Xñ åW-e4¼eáäï ìVEfX‹hÙ ¸G¥Nä0mäÔoðõ%‰T+¬z‘aÕF³6þ!&'ˆ-Yð>Éeîtc2[âåaö€kuzx1l¤¢UÇѤxÀ¼×…âhrŒ} °ÊG…Zàz¾KQë_q Z)PwYÖz˜²íª•öÜëªTÖ¶ùæl%CkEtßäÅ TËKÆÝµEVRŒwĨ_+®Á…¬9Þ! èdH1p¢Tq&hP\"@ Y01~âÆ6á¸ÁšH€”" )€WÔ±å§v‘m²×.22(Í(>à`{ÚÀÀ(+-¦?Oì¬Ì"ÔQ¶´‡ìwònMßl#zwp0ìŽÒç>nìÎ}ƒmwnYGÙR¼pÆ  Ãj&É¡öÓ!¶Ü1#CdOìŒ7ŒR-°L1´ÊkÝ&zê~‚+r»ÀÌ-¤Xñ¹º Õy š{òR&Ë·Õ(€2Yu¨@|+x‡9i±òw²»ǽlŸ–{n‡‹tv×q’Çv–}W«´’½F zí#vœ%zÛ¢ÛÚí&àqñøÖfGÂI'7Á0uå= ÛÙyääÔ!œ0qͱ,²¦T¨FR\5_líe'ê @¥LC]•càâàz$@jâ…ƒËú[užk£jÆ)¡Î?bBŒïHâ0ûÁü`l22À"¦ؘpbU@ãØ’b’áÞ/°8ÁþÅ´@ïi¬&dûk¤†b–(ÁöHÁän6à~ ªªÊ!ÁˆÂ.Ô(UT)Uâeef¤â"#ˆC  Z~B™8/ü=®`+À8À"Xåö]ŒÀ.äo60áÒ6é@Ÿbe4®2+¡øD†M$AôžQn«áú/£€5À/\ 1|aê"ÔAÖç@ׯ *ÁäâÚ¡èDÐ"àH@î MÉ ŽúùBàA:+Á´&7ì8ÀãÊ XèìBÈA¾¨ÀbBAÞ9b,„t”aýšâ bâ÷)b˜HH¿bçœÀý@ 6!ÞaüÎú•¤ÐÿbŒï¼2 h:"„š5Õf`+Û FHb§hSLà3+º¥4\¢g *îKZætm²lWMÀO« 2n³¼µL¼Àš÷£"Y†æ30ܲ'@@B:_7‚NçPÕÐ\›rR¹þXQ×eæÂ†[d¢¾Vð²KXZ'eÇ¥ -i"»+½Sx7LµgÅ¡öRUsìDSx}t³·6ÍåÂÏ5-*zÆ@G¨PY b·¥fæ» m"ˆ¹î7Õ,Uå°ˆ¤rÕñ bÄ®% mÑüye¬l±/n¦`ÆÀgu÷`÷ø¿Æh8áH!®ƒ¸ Œðyö$ [úúó1øg¨R[.ѱø²Oº%%+ôÀÒ Á,Ž|úQ£v‡Ø_ÄÒÆ`×d ¿à`(.‚€ápXl2Á_и¼Z%‚D` Hóþ*ý…Æ`qQ }J€Q(\T”?#8|j+ÀßÒ9œÒ5>…à )Cö $ DÀIÔM…€ã9õS ”LaÑÈ}‰€`¶ˆ´zÕ ¶Ôª’yÌ \­º¨w«Ç¦éìÎ#e‹C)8ÄqѬôÙ†'l´Ô¼Ó/k±Á-4ܶ~Eq²].V+½Ú•ŸÄh²–ÙýÚÝ¡ÏÇcØ-¾vk£¾d*Ú †O…Á†V0ôüж̤{ÀVU?ÚÂv˜HLkmÅÄT9ô˜X1{€Ý«æsc2Èå!¸­ƒ”ˆŸüо€…aˆ®¨„+2©<ˆ@ ¤ÇÈ©çñèç9´òžp±ôs˜à~ gö€€H*E€L}žx¦hé0‘Aæ¡~p‚îp±än!(@³@)ðz€˜ €Pt&ˇi®†Qsgt&~žbœæ½0‚LD`"ª}·GÙúŒ« 1ü¡PËÈ ‚@¬À`Üwžð˜ ‡ñðÐJ $Fž4Ž}Ò‚!Ë`8€¯€R{G(|ÈR8 qudyÂGh`„,yÄd؆¬Ôàâj‚‹¹Úi¯‡¬Ú|£êTN †‚új ìªGéÎjˆ)O ž‡ÑpÆÇäN{Ÿ€‹ÑÌðZkÆ(ø}Dgèò`" 'ÚäX+AF‡ñìÏàKú—Ú¸<®à$$zP±ù-\'»Òbj‡`$òí=*²­Æ)RÐùã‚Ò½hÔþKóš…/BbNËãºß®çýȵ%«€ß.š%¥É'»¦‚kÚz~´!T¢Ò…Zé0$©†{¬ÌìlR}àS8?¯èʤ0ZÚ2Î4*ævô#gëó ñ°“"‚6Œ¡ bVæ ™ï(“µiIþò((QøÖÄèRL„<èT¢ÌçM«`ëÊ Ù£ÆÊùÆFÀ !ª³/‚}"°Êª©Kb ™-X;@ç½gn麪–…€z?¥³(Ê3×»*‹ÎžoþbüãúÚŸiÖw‹j÷C.Rkܾ-rñìÉ<çyNÀ"¤|'Uˆo ‚¢?T°ï# àvÀñ (æ?–¬Q9>…ì†=B nN!Ö/Fð÷¶ª[J Ÿ}…܇œÎõ_´#N)@‹Òò{àá®6F”Á÷*í4ƒæÈ¶fšmÎ% ¨²TcaiÅ&ƘóPe Át#Ð体G qL8ÍÐãsªô Y%ƒñ„‚—²ÞVLô;ƒ'ÚB#`vÎQá8pÈŠ#\ô¡ä_;‡òG&òjŽ©-kQäù*’ q˜!…”ŧ¤b${_†LÞ:ŸâsÈ«?‡$ú/;ƒw¤¼uއÛÃXìqqº;Ð}Š{d¼*mÆÌçA÷í#QÍ(–FãeO.—0nabÊH^™WŒçÝ‘¦sK´§•GäBb&È+ãð‘ˆü? £Ð Aq©KÁò?”Ðýa#üu¦að7†G£($b?kVM†"qè?@y5ˆ¬0>‘Ç8Ë cÄožüF@8 @þ° ³fú# ªö¬@‘5`déA‡´þqͬ0€ù#2—Ž4ž=GýVIÀTyèÉ Deá;ãÒŸ^ÒG/•-½0H€4ÀK‡ÈZ°p ”Î=êÔ9ƒèŒÖ2‡á&ÓЂ´€ÀXªÅY¦qô¥ŸP`Af€Ö ëvW”<€õƒË¥±ðĵs.à“ü•0ø @$¥ð‚Ñ|Hy ‘iKƈ·*-zx3@I€üAõ-<5júñ`騯.ài@R Q2´òoE€(…‹°s äw,%EÒáø€ÙQ‚ÂBM@­.)„A®Á˜BBIñnŽ¥ô™ÐéËmv©Ý¨£éËépFè´"‚@S¦v `¿7Lý$i@h “§æ¾ÎâœMi¤@|Å0RÌ{Æ}ì$¸´˜Tü^ùxFeâ8Öÿ Ìp‚Ó„övûÇÓŒC)ü'féœ\‹»‰$¬U:§uê:ø M\®¨EÈŸ¿*\ä–ÒbéÈÛI?ÏvÝ/Ê”åÚÉ«gd´§:'NfN«?M‘œ,?bÉwq$¤…X2:úHQä!MЄ95ùnšó¬£.°5¨c•¤‘“nîÈÉ™ÌËÉ!¬¶Ô²¶×‰‹¦„n ç²+RÉbáFúÐÁ§#pm€p‚è¼}g\i ÐÔ\jtÊBÃd]£Aiz0ê%Íw½_½8¯¦ø¥©>4”B© r\l€„1Tꞣq ޤ?‰Ï‰ÛÂR)$ÊÞð‰ÑþVÆã|påa âå&ià å, ¦Ã’ûºœssÆe¦iÅj)r3)-`ܪ’sQˉ—*MQn˱˂MNu™08ÒOí~sQô…† Öó­ ‰£Ã5;/”Ý­¶»TÛæòîCèïè) ü{gúšõɝи@0 @c`‘ítИê*Èl‹ÃÐ:©óKi »HœZW`¥I$%F¬Gøõ²À}° ©H ?¶ýaêI”DdOô‹¼(X A €SÒ?ÃH㪋€pR‹à^£øpdmë'úpOm‚4ÆvÌa1=kd!é—÷šÑé`)z J À1I|` ÑtPâû ªÌÁ‰4@…@„8=!qšª°’é› €»ù=ù‰ v5x¿°¸¥ ’x›A|+€@µ¨}ŠP!€ ‚'røX‘ˆn† w 1 ¸ ¥¬ É¿ˆL âo¶X"—‡É„³¹‡Òܨ¸è+¨d-¡s( {¬Èš€ô¨É„€h '€ˆ ˆ€Âɬ!€rñ•)*À¯2í•ø¼°‘¿aã ùÊx–“úýœS/ЈØÐˆA* 0úú!K ²¹( ˜¬2™½* ‘›!˯ª9D€Œ‰ÀŒ€Yö Šþºq·O8Ö‰¢%¸ˆ iî”Ѓ¬QÓ ÔI BVDƒ?ˆ(–#ùò³øÂ2ªiÕ‹ð‹¯±Ô¡±~ÔOº¹Ú˜ (œcF‘3‹2ã;4ˆ!¸™éÝ ¹È·ò6™á?ŒºúEôªaêž¡¥²ˆ¤·iì û‚3JE³è„‘7¯ì_ ùì±sC’H鉢û4rŠ;ºPÕ¨*qËžˆÁ:âÍžÌ&Cç8zzIX€Xz“€x± €Ê•‡hg–8 "€!³Y*«#høÈò\¸Ë«£Pï ÐâH€¨9B‘àì£XÙ›˜‘¸ø³£#6ÄÉÛŠ0瘖Þ/™éÈÞ% Õ!c¯ Â&Hå¶ó´ó»KH5ä¥#Z8 #|Ÿj¤$·ŒÂN?#pÓsÕ%,±'6[t 4¢4:¬ˆ6+e¶Pè8[©¢¯&°ß!Êk¶˜¨ ëª&+©9x뤢§gÈ€”S¡Ê:Y·Ú[Š£‡¦!î6Ô«M°ˆ’kˆ“Ÿ¹¢œÙú»º‹ë¡;ÌÎÒ%¤Ý7ôÇ;2£c¬¥(¯ ôÔ Jc²Á¹¥Àî¡+mqè ²øºÈ†èÙž½à~š# ’ о°?X$ ˆ‘;/‡àz­Ày¨_ˆ q¨ ‡Ñ ˆuœ¹kŽbÑ €9{Œ©Õ€J’§`ô”²•€Ü^€K'ù6C {• §XÁU‡ào¢‡1€Zv¯H|rèy¬°ô”>³x!Ö‚©‹Yà £É𪳬]§".ÚÂ9F (ˆz‡áHpwˆ‡á„‡Ø}˜ÁäUœºªðí‡Õ1ˆ°Œ€58.¨ô‡ÑO‘Švˆ +ãì•’Ê`Ãh{˜@‚Ñ8 áKA¸‡è©EF ¨ˆz@vÐ9€‰‡ÀlP~“ʘ =€9*àÆ‡À|Ô;c1»ÇŠ‹{’KÇC*Î.™¤‡üI€j—P@ƒœ…˜S… ¨€QD«›¨Ò”R¯ „Ø„2$õ€ <‡èÀÕ9L“;¢xÝH[)i Â[ŸÁ P‘ÑöW Õ3ãÌc&ÀÍ1ḢÒÿ´ƒ+Dé8˜úGÉꈩ·(ºˆÆšŠ{•D)õDù±¤°ŠU€êVs »@:ìçÄÈÙ²Œà–¢˜´b HÀBJ‰ÌE“øÝ ņǫ%ê<S´™ê R|Oœ¹¥iï9™ |z $"×3š(Ü›ƒ5GñÊ £|±É›S†ÙÜvQ»XrâúkÙ!­RIÌ 1óØàµ3Mp¢ ^ Äš8ŸÉáAøðg‘Èj…èX½@ǘªôz€(yŸè %KÀ”H/‚1*Ta:K ß ìÜÊ©H×9ãeˆ”µÌû%{e¢U¢ ˤ[œÝŠÎ5‰ò+ޤk:‚- Ó¤‹H¯Œ>L5Ñ7Lº¡›ºŸl¶ =Ò‹ª'r,8¥ˆ4C;],ߢˆà›rN¢Ò‹øªM›rŽ(Šùé4 ×‹<Ù˜–£ e°¦ß„Š«Œ^|¶¦š_Ý‹;*U;™îŒú+º‹cJb<Í,·;@çÊÒÎóH¾ÙMè àîÝíì¶jH4N´ÌÒ¦BŽ\L&"û¡Ý÷£´9C¦ÎÈç:íýû¦%Ýï¶Õ׽ю(öÔÞ#,î5ü¤qª‡ó9£5ÚŽ( €°U˜º=UŠƒ°“€’¾/ãHQé †Ãæʼs‡è{½ð šå‰­Fª@…`¸}‘‰K(1Y*ù ²Yˆ 0£ý (ªð|zÜ Á* ô‡˜z‡!x-Â娍hº²Êhò 0~"ªÀŒñ?W;;Ÿa¸ÈQìŠxˆ1@¡˜¯£Á*øèÉ¢P)‰¹B5ÎCÔH’ © •ROˆò¼ p €²•‡`v¬³¿Ô8Ú¤A-€#`ªñ2…²¯‡àx•–8áø€šÅ°¬Rì 0vu(¼9˜~;Wrþd.fZ¦Ž©ÆÈFzṪ P~‘9ü—¨ýªû·N=3ðÖ3ÓÑŠ’Md½qZ)ˆÃ` æipU1k‡ÐuÐHéªú—äcŠ™½­RyôshEˆ:BØÌËÇ‘¯ž$±¢?“ÍSO0î«4 5J[pš©áa ¹ÇÓ!¡¿Ì}Œ9½»–FšH°] qºÕ|d8®Ø˜®³¾” 5'™á²KAë‚Ñí±vHËzƨíµÚ#Ú8¬gl"ŒK ¬®%y ±ê¥œ¨Ç)à낱ˆiêD¡Éœe|k­†ŒpÄΉXµF¨¦ …péë ×ëtÆF.¤ñ$ë>Cˆ @@r(¹Š•øz‡Z(^…p™, \98 §€‚ñ‡°x 0yXPæoC€yÚò¯RG­ƒS……õÎÎ Š¡Ù]+<Ë;i6ÍÑ]ì•Ò‹íæï%´`ÐàÍF À£ Í_fN¥± øŸjÆ«IúY¶|шb»aöˆ£±®:7’f¸Ó* ²ZÎÃ!ðã!,ÞJüÃŒJD_¬wà“m$‹z#¬ÄºÕÝ$nð6ÚI³2-–ë^®ë¤OØ«ŒÌЊ9Äæà¯kØÀF$ºŽ¬\DHŒ$ß ]ö k¯Ëì %´×Ž-á;?"d°Ù ª¶íù j£Ýy:NÚÁÈËŒž:)K)øñ“o/Þ4&¾‹tÛ›¡Êñ•ï ˆ»˜ \žÒ'tÚD2Áa†EßјÍR7`’V$ʼ…¬In¶«L†';~X6$^£?œÕ´ûµ‰¿lpÉÞieÞn“¬M¶Ç]·¿¬»<þcwœQc¶(Í%8‹ÛßùÈíÎ?¤¡âk:`¶sc“h÷2iî>7?»í®ðŽ&–“æD(3ð?‹‰ëoÚ‹.±ŠµU,êîF‘PœX±ý•÷š•\z~)ÎË~òåë¸{ú—`”ý¿¯C$§“ÆéÀ°:LͬªK–Ù®¯úv ÁAþá+:"ö)©€`:ƒ€ ` ÀôDÉðy±ÒoD‡‰Ô€9èÜŸ§Ërz¥` öv€Ùñ#!±ü•€€2š€àDŽ~"(ŠðئŸg˃!h* ½€2ª({@ð|HP1`(0g™îx·'úCÑÐÌk<“¥gáú%hŠL}ˆK¢„Ÿ§éæ°‚mËñ ý+€!÷M Ê].ÒÔ(¾¢ :'.€ÑÐ Ö­ÌuhƒÇšŸU(«#à"†Ù'Ùí8B¨ø…ÖhYîÍ`àp0€©õLÆ©p®ñ8 aìwqŠP«‡Áß#«“ú=0° "R°é¦Öt³rT¨D°Âø2 ¢6,©2WH0 ¥`J˜®J@ò~$IH BV Ê> …MÈ.«€-CèíJ‡Ð **×ÛªÙ©±jpˆä5Ê7áu¦¿I[Ø„¡(ƒ\Èl¢Š?¸Ñ…hªlIJj’¥&h^Œˆ,(66æCQfä$i²ú ά;±¦oެà/èmD}îëû>„ìCÇ&šŽÅÉ„à¼[Ù(ã<ˆ¦8Þ¬«ahyð“¥*kx°¢ºÂª†¹ÊÈ~&oÒ ‚¥zZ|‚ó©N•Ò<üFÅ®+ךäæó|5‚±©k ÃÅ´¦¢¤‰«uœ¡ò ¶À¬ ÎïižÂ¶îsgÔû=:O¤},ŽPRvsjÀH‘f©¤Fá®d@o‡ ‚•™âréð8‘Ð+lu¤aî<`À¬*×$#à8ªÓ k A­?$IΙ‚°±žÃ…,…Üö«Jü%êÅ$êÝá¿w0”–Ÿ’ý Žq?mEt¡VÚM #¶=Ј¬Â]Ü#…$É4ºÄ²Ñ Ûc¶‹'Ðí i}Ý ?&±äí€' xü+¦@ᘓ "ìT6ñ‚XB3Îqa$Ÿ=À %’‰GbðƒÇ&]i_Ïtq6ÓöÈ O¼a,nÃ8¢M[Qÿ@‡r!HH|K¸€ Ê"NBJa I•¨€0 Ç\8 €öФ♃Ôu’rg™ =`ÊðÈåJ S‡1iAéÜ_ÉXñHÈ~´z€3. ¢ £F(èp HXüJȰ}&ö>žJ² ãàz€è>‘êlŽ9òD?M ‘¸2Òþ+ª™º‰„}‘ô¢PñM „€°Ç[(õªlb͘°JÀpžVñ*1èGÈô^%D%¤×ÙçuL À{¯ðŸfb—#fR2¼JÇØû Mé¦QO'»¸qÕ#*<Áäµx¡ÒªûPJ´ØúÞ^51ƒä…€à,‰Ô:~ãÉü%ôØÌ¬{jñƒÐn,ÀÛB¸øŠ*‡h‘âžu-ny«øQB–-pêz"Ìa'ÌFÔ#(B8˃ð@f:1Á,T(ƬâVaêG¡ÀÁ˜Þª:Åf®¥šCÆ‚Jb€S¡ú¤€!ª@ š 0ÿÀ ¬i–zÈè%‚+ì!蛃,ôŽ0¤…brÝèTÜ.‰¢l†‚¨+cþÛMV#£®Ë¢ê+br’¨] -ætˆäwÑêš’^æÑ;#hà’fÇí\âMŒØcš–i¢Ø¢d(RÞÅÄÛ âàŒbh…28„ãæA©O+z9ˆVâ.•±6šî&æÃH5N|;ãd片+Î 7†ú؈f@´Ø£-+â܈N‚@#ã.r„2Îp‰ÄˆN&´äÂ`*éì­/ô n⾬`3ÉÎ`G4'F:ú|QÆ/DÖµÄ8¤ä`H ($¤@ù ­@õåZ B2 J„ºNĬs"ÎT°\F°Šª¼‘w5ShN‰¦È+мÖb¾¯8”BQ§TC^fÅæMèc.ÌDÖÀ<eZIì‹.FjªrÈ‘f`Ñ>Ì& iÄ7åFŸeŒbIÐiS”®†Žæ%Å¢+ŠN­åxsjdp7 â#©(XrOöRé œ‹`2áôtà$DºIÏÎ+Ę&€ÓÇRç…Œ!Æ|Vd%gÒD˜­%@,$P@’E„& q¿)d¼LçŒC-V!!ò9 ½ì2_%rí äÿ KsK ÃÑv¶*LNÔÃrAÂGO$P‚SaúéÜiØêi_âàÀåD)‚ü"%.$B¬s…LMäÊ,,nLFîfê&fHiÇÔ?L|Úm23Ò‘ÈYèÒÄ‚lVgVlD,h¦ÞaÎ60ôúÃÆ±=Óð´{B =”æj¾bAC kL«ò&ò´–´õg®“í¯O²0“å ¤9ê/n@ƒ¦ÞsTöáȦ›HÆ|'8?¦Ã,A"ã/ ‡˜.ÃRƒÈ/g(,¥^šèY¡üQ6Mépª¡è„ŒÁÚHÁøåÔÈ  XHk!Ï n  ¾+€NÇŒŠ'œ’Â,*.í¢¼QÌ#„Î…f´PŒ]%dЇA%‰˜¿ç°®ÎšÃ8‘/)í~Œö –'H&©ž8Œo¦ÔVð7*`áÄÖfƒiYö5,"îÛÎ Ørµ(È8;ˆÊ?)œàŠß£˜š(œÇ2‡r)#¸µcxÙˆ¦'m•)r…*&lÌr•© ;ˆŠ’–Xá6Êä¶giqèÑó'Hh(£d’BC"ðø7TãbŽš6Ágƒî:Ä ÙN”èNgkqh;gœ,MÚßnPݲkXƒï ø@r[*2Œãrn$¶é ,ŸÃ’"ò nÖ}OãÍ2<. ,àDÃÑ`Pl4thÙ&…XB¤Ã:q b 0fdMd´VjxMåH0áî=J.Vjò‚Ss?Àè2.Áì¢üMêHDù1¨a$€Á$â_`Vd TµÀ pMœX3Ra%öþ`ôŒ99Jxs"º¥ô¾òÂI$àÌ5ÀG@¹æø"ì“U©ÌU‚¬PÊtD‰Þ="tÊ»ÊaD/̆”c‚9 i£[lBR!o, F™iܨ(#먰ÁãJª OÂSsàP6v*çãúuL`!¯’ô… ÀóVÈŠ¥D ̃@8%‚eëre  @¶#à0DfÎ ±îæ"!ðìb¹CÕxœsN'E‚nâE‹³ˆc¢\nä°@D®s,Õõ¶"%$ AôDŒ¡Öøô°@4¤H^/5D¦ÛãÐi•PltŸ~D ‰Fnø&ÛZ,%Ýñ%e/b- ¹ bâÅF›XS³Ã„2çŒ6ÔTÉxk‚ºttéT°4,{!Ã{ExÍëN4ëDuÆÆ^l'"æ¹g¨)TéZ¸0 öÄ<Ì +Fªp2$'Yc" #g$b­‘1Ž9D†-,X6¬Ê̇.óà$õ)9)‚Hâ´t3!!ÚM&a–åäÄF«¤Þ¤Ê¸…š@&ƒ!ä$üÁÏA Tª­"f @Ê!«s~ÄÞbGj#]›Vûhî¿¢—GLA¶Ÿg 5ké<Œù?gIU(c/&£¶éR4à,÷Q¤¯€ÛÃ!j&Øy6ì–(Žˆ-îŽck éQžHô&V,7¨r"–ˆŽèë‚TÕǬ5.r»:™ˆ¸á8âÄã,_jÚª6$wÒ§,¬\æn„3Rþ×±ÆA®•(#©©’ï Šàö»)Ö–/ýs'°W+¦rEf—SiRŽrtX£ý©Ÿ{m:ÞÖ³u.èÏs‡%z”7h£‚z(ys„põk«Öä–rx炊Œ)·trŽw&A#ÝpiZÉé–(Ó<à( J5òô³eJC‘1T,78ÅžÃËbW4D:£ONBªªÉj¹IìM~Æ ÁüVàBš"D N$XLÔJjª³l*ù¤ðäkñƒÙ¹û ¸zL{ìX°dÍøjQ¯”&õ5 Î¹JY~†:ò¤²ª!!þVdÒhÔ$«"H  <^¥[}æD›yKÌ.ŠºJæ*teJ`Ùͤ„4ôŒ$òç!ï[øj³mÞ$D¤ƒ6D R¦!óÚÔtÄ®Éjî.8ð4lC¢Yo†L@¤¤©BÌP'ºôŠªgÅr‡P¢Wz%J @@hÄp/¶Faꪠ.\ÒàjÊdpCôÉ&ÅŽ†0D¨Eê¨áÚÓÛIë²:٨íÌu™6€;bvç˜þÿµºj‰Îa® Cï“¥Ò@ÿ1Iû3ÙÈwD1ÿ<™néÒ ÷N?­– ݱ×uN70ß5«Éž˜£dà&B‡‚'EKU¤:4JPe.QÏH1İø‰} EÑBO‰Âöò› z…º‚ 2'MêF @®øMet!W½‡@O$žžBû~¿€Wƒœ}¾€PÿDßÀ <$ €ˆLLÄŸÏ×àK'‰¿@Ùdµý$€br0ò+co·”¢ƒÀ°@†–<mh›êA"UP Aþÿ€àT¢§(~¾#u˜‹öHˆ>Ÿð@ù÷!0Ý@(“ê Wí@X‹Ýã›Ê,ÖÚØgyÖ-R‹Ì&æ}?aÌå–%"ˆ­øÉdÒ¶—^@Ó@("èù¨ïØð@ê¯ûˆ9´‚^@—€àln¶œ S¶ 6›¥¨ ¡ À°$X#ðA½@Còo²>Þnè+ w;ÞˆV €h( Ú®"Hz °$)¢7‡úÖgÙìžgHzç"¸@ @& $ :ð~¸ª ¬´'úN‡Áè’ëÁˆL—ÀÐL¿&z>ЦËz««úi#Çðd~Å$Üš³4RrP8húК´ŒÂj¶Âô|Áà$&ÉB¤•2 ¬|˜¥¨üÔº±H‚¨¢)²g#A’:B¿FòDÈ« “lí%ÏðT+Î K±MãP©N©¤­ÉÑôêµ+k4í+4q«¿+q´{&‡ì—9A2íOSAô¸Ȫ²› ­±r'=ɳ²&¥Jqº È×¢lšÆŠ|>®­X Ã%§áæ&Y‚®€sô~$àXkG)ÅIáJ¼‡ÚÍ&ØrpøJ$ €.…K•pÕŸ'Ä0½#Hj°R5åyÆx*@œ¯.O_X4mrºA8 ‹‰Wq½qÊÒU…5×ÔÜ8FÖ$™FUV1‚e(úkc¨Œg\Ø1ý‰dŸe;ƒÖy¹\Q´ú&Ægì~Açõ\Y¹^-bIÙÞ(–Ш›yž2ØœêŠVº¦_aêtlZá韥æRf9ŽX:ÆÄRÉ^+¥¤Uöç)Ø;–Ñ·jؾ±ŽW2´á¥JÙ^e'gÚ¾c«×UÕkšliõÌX :Šav¡Kiç [ou®ënu]á;¦íËeZÞºeÚn™×Ò×+[ö¹žs‘sX¦5Wlý®ÞöI#cq]‡]¹²»/}µqÒΫ€º~Õ`ÞÓ±ê[æGío5Ÿu­í›Ø: „­ó,‘¢@@º“T°ÅN‰:ü–@é’hº&’¬‘8«6rLd¬ ¾ÃR?”ÓñLí$›PcËÛQ&ƒìáÁÊú'ƒèrÆJQV M§.^HÐÿ¥á-¬^K 0ù3 ,óÒ¶IßÑ¥&%ÐSÜ?Éøý>ˆpJù!$ãÐ{Ÿd^D¡Óhåáé%NçÒ!pbl )¤æœKQt#…l€rh?Ùq丙è&™Ÿ›r$f“EÒNaQ"5!k‘³²TÉ8ú‹@Ž Ÿ:[ I;?2ìf‹bBKT­€Pa€ "ëpž°µÇ¨ë…Ô’À$°°4×XçcÔ®@P "„Ü{Jä9Fðøİ^ Ð3çã”n’ì:Í ê\P#À ÂAš€¸€ïh­PGRœœ‹&KeÕ=0„fi‚M‘9OÁ¨HÖxf-ôÆM!ƒùIiô‘ÂÍ@S²_:í¬–8b!Ô] JÌ%ÏÀúPknsåàá´#"ÐèÃúO…$+Ò¥OY,.Q05'¥ÄÌØ›¹Y ‰I¡ÔŠšj˜š¢m 3°b@J›š_WÍ ÃTBBŽ[ …!#æY1¾3ˆØ÷$èjx€I)À z#r\„@*P+ã¼i  3ÅÈ´Ì$„ðÁ\Æs|¼¦¢Y ¢YŒYE:‚èZmAà˜8ÄrŽÝ“¾¯ A\¶W ìZc­xL5€Ñ×|뫉nèý–²¦èÇÝÒÉa…мÕyk—»uz¶¾´Ñ‚Zä­Óàt•½®Ñ—VH.Š?QLe_\g8ñRk6jY½»³tš[Ľè18#ôrÏÓ§yйÁ2æWrݳB£mM´hÅ.£|eoù¹…|ømòV®È<Ò¼WÜÅ] 0wÌ…¹¦Kì¦ê#3ºØù\f–ñÛã8k×̺æ¾óñmYˆVÞ²¦G‹°.>q7§a¨ÚÕÖ ŸÀ!¨$§[ï {IWy¨+T¬£[ºÉv÷Vá%Ä‚®²s÷%±³ÆÀϘ˜Èj cé©¥$Åз’p q*•™QÇÚšŠ¹[Lf¿CNÓÖ'\ÂTß‹¨#Ö$˜Fô=ÈHû"L”‚ð>ÇÉçÈcD“ÀI8ùK¥ª€B‰K‰“"C퇑'ÒE!†ìœx b¡¹†Î¶5lŽbXËh$|šWýFu¥)h ó" †$û*²(,6’:Ãxž‰b!d°{òfM¹ç‹ eÇ)½¾CT‹«4DwÏ@e§.¯œ†Döô£‘Á"Áé¸ÒÍÈ “<‹Æ¢Xpfv‡F{rÈ@²% A0(x.Æ H`ÀN çXÝ„ wŽ;|@QÔ'z >PÇ/; 8 ËPÉ'Œ0>K@DÔ`0žÂ.\HƒC¬$Ù€NBê>!~£xk€Þ8†Èlñ€Ða‡à;ãô "TOäjGΉÇY9ò$’­EBEU-Vó@z-½Ê厞CJI/KªL¦  ë*q7«)-M%ÒÏF;T¥ÖÖ4…]áI§vñÒâx§ò™uõ,jˆHóùBéÉ©Ot.š4©GÌQxRúѤlò(ϙم¬Kj_êN¡“ŽVKKdmß Vü7¯èÈÛ"VÜš;góuX,ÌHÒûgܬ¼«6‹ýu[?€w*N ˜ ÄGXä+DdŒSü‚ð;¥p ÂZ­^!¢‰ÐÀ†(M8ø¥ÈC‡ÀÚ‰¸Ày‡ŠP€J;,pù›:q8­ÊBŒšRþ‘‘d1©´c{Yšø-ã@ù¿œI‘³$+)1aDqÓ3õñX?!ë©­¶¢ ¯ñs³2ìêíY½²öœ‰†™ÉM¶ ‘É2¤›"ã1A2)s± 2Ù¼ƒ^›ä1‘Ä®<’𱩲/“1>©¼.ã ˜qßJ+A%Â֔껛A¥@)ž!„™¢î2³-ÔÄbã鲯“°ª¶JîBBú²‰«–LHA¡‹/dT›Ûœñ“’ •ÃùE.D®Š•˜¬./41š¢A-²¶°iM›»$˜µDK/ÃùïÌ)«­²ŒÅ±lWà ‡O¹&QsòÓ‰Ñ-ÁDœKE$2¡M²±T0™&°zà@û+›™ÓE­KSƒ+ž¹FáÌDQ¹»¡®Œ!UÐÑ!]Bã š¢0íż(2P„ž58°{,-ôZ0#/mbArûAš¦1‰Ú“[E”VÂi«*ë±M®4Û(ÕI˜ YÔl2œ±™üQ¯‹21›¼íqÅ4QB¡4ð‰ x 8­‹ÑI«Yˆ»´%¼\&Tð‰€ð<²AZ†JZ’«0š"9^‹ ¸«‘ ùb`Ãð 1S7%€3ÆÙÌo*M‡º!¬pŽø¶‹ˆ}„6ãV¡QLœß‹ˆ" €è„%,@¦5œÉ˜µ‰± ‘p‰ð¸‰ÒèÄ€P ½úÐj8ø S€ãþ‰`y‡"gX ,h}€¥æ‰C`7©+ï3|–)ƒ?Y‹ @Ôèâ~¨˜¾˜ˆ³ æ÷ˆ˜{¾±@ëã‘Õ±á¯1:ˆ©;‰*b‘…¤‰!=ˆ¾0’ È–% ö)åAœkóáFW)-H™½† @ከaab)'QÌε‹Šÿ9XQ‰ÂܲI“ºšªÒBÐùbŒ€× ²èš8Ñ“Ü×Ái`æ\6ò¡í¨°™-qåa¤-/©Qv²Œ“#(yí¼‰vˆc· Hï†@W(¸%¸Øq9 P²˜ $Ø€˜`8¯µ<㎠;Vž•‹ž-P2Î1fq±Žå+t3 ÄÜË ®Œ8M{.*·ètYœåST6‚åiäçaÎÖÕ Å;#¯]±p° «’o\f†øa\.Zó¶†l0™œÂQ½­­TN‹3Tc%ÃÒܾyô=CúçC[ âNrWÙ¦ÕcÀù™U!\gzBevÓþ™ç™áå+ÞÄæ[•Ô8VWšÝ—Fçãòi±ßåNkç·§çÕESÅ‹4W2W_ï£ižšÙ8.7¡âzàBM×0—®u‡@–Øe‹  ¸»Xž9ð¼ ñ³çÉ Åš žî‰é¹¼ÔMO‘¬A§z±æ«¢¡Ö5Ø0a€h8¸šx <ûHä’íq[‡à^4ˆ €ÉóZ‰È0­œúÊ Í«B '1`DYˆü` Ãöë ÝÀˆzë }È!:!áÃ;ºŽ –j36=á÷M˜‹À€¸ˆH^hr†ÊÊtØÍ‰9ˆ¸Ó8± _Ü ¨ë«0´!sSF°ÐÃA' ’2À†ß‰@àì:M’8²p¢@€ ù¾}»°€ôþ€ÿ€'ð&ÿÅ€¯è¸CŠ¿ßr€Q‹I"qX¼80M"‘§Üb.ü_ñWðC$¢?dñ¹œh —Ñ'ÛÙùG¢pé]öü«ÀpyõW¢‘y¾g.™Eâk£þoË¢Õwì:™£W- X4, Ãà3¥Î|½Þ (àýzZ_Ó¨td-C‚ pE”}]ÒÐ xÏÇCA¡X ŒåµxÞXöÈ@ö×óñït:°€p, ¾jîfjâ7g†dÝæéß¹œÀˆT5Ùîž žh!ÿŠÑ)‘8ÔVùk¤K~sK„~,£@’5(ó6‹%ÉZB³.ˆº*‰%À#‚”$/êFÿ¿ Z”ÿ®ð’Vú·°1ýBgä&¸¥Ð{Þ´CŠ"tŸ&ê,˜!èêP”­  `£%h¢*œ£Ií Bp’‚“¡ÊÔ ¢‰ A ­qR‡­j:fºI‰’rø®‘@—±Šèø"èkéA«¤7+¿ðB)"ôÊ M¤òSæ¥IÉÌÒ¡K Œ°þ&Rj'2£R ËÉË]²Àôt3(ñ,£G¹Ör±†œ¶*à4 €IÊq€‘¦`€è\;!XX†ažÁ´¡˜¢+·ç¢V}Ÿ,Éò}2`ˆ$ £`3š¥Îs*¤à2hÔ¢Çì´˜QÑdýAÉcÿ-/Sè¸ÑÓ˜“®ÏúOs­ÖêÙ4Û‹»çg?Ƚ±,$ôœiv?V¬çB¦‰\Ú¬&‘¤çÒjc‚¯À`¥á áG¨×j—K>˜éÉS ¼²âÆ%fP«ªtšRxœÓŠ£q¦U‰ÞKlf¬$ôtLºÞcqM9•}ÞéŠd¯X2—fª^kÆøšiˆiù û4å3—jç’^yÆ”$tiø~¯é÷Æ›©t|— àq·í4Ï Í6Êé‡g9æ|þ'W™ºà»îɧnVõ¶®+ª$†’®wg…ÀhnGXܰDòÊD楺VgÝ;UGO[þÕ€Fwǽìùfí¼C |%Ç‹2gÎvé $ ªàøJÏžg’©qîvŸ > ¬€ 92¬¦“K¨p, Çø¿(QrHã¯ØP >²Ä€-+(#ÈÂH~€«"\sGÀørCô~BrâÇé+)P)™@²ÇùgGÅ”ÀffÊ /@æ‘§ª˜POØzb-H˜!ÇÈáê?ܱkØ—’â R,.`¿ÄüÑ 4(-,¼€œ°|¼{@" Nàø°îŽ!ˆÀÓ ?0H“hCÙ¹$…ÙE"‘ügHÉl>.ét¸NS!Mj0¹#5òø ñ]*$ÝÁðD€hÀxáæDÀ;þOÃô|½S‹ŸBD«§epHЃKÔ B “”DšmCñ„ ºK`؆`< ¬Ü<y NHʺ@C“ %  ʈfT 8XÔ¹!ø>¨ f|<0&„´ ƒˆLÐDI.rB?G€ñ0€ æAØ7ˆØêS€ ˜s,F‡ÀêœCäuŽ) €Ï3àK¢;KH 1`)v€QÒÜK‡Π"Ð|P:@2‡G'R†”9~7¤’5ƒì—dÚ-Ñ2¾>ý$Ýc$j7IuÒÖªÎOÉL“æ·‰6PëmwÃä~¡Ê5?K µÓô„ŒßÚi„iŒ:µø™PPGôÍŸ’†€E$FiEt$„ˆ¼%6Qe1¸–[üuN5Þ§Š<™“mX¡kͺ&"`\Y”’7µvµGho™XZ­?`=‹8¶â@h Àè2Ä€éz@L3‚ÎÆ <HØ üM2 Á¡- ~œr6>Ë8ëóØYz])–,’&›5%Ìß›Êðm4Á/Hò£¨K¯K§ñq¤†&œèuidQé¶Ä—sªÚbTÉ.®2pÎ,J`­™w4và ®ªÕd¥a¶;EæÒ™åOl·M¬¶äºÍKÕðŽ× ¿·^ÔÙÄ¿íœý®F$˜°óeõæå¶vdžðk¥¾—z­–²ƒYrêÁÍ݉±åæÁɦ¿Åâð7þ¿0Êíq-Žäµ%Þà.Òð[*™2uÇŒšíûÆŠÿ»tÙŽnë=p´ó Ü[ŽÁVn1Å$\½˜L©FØøœu¹!ð=I “d~BV dƒ X‰4Ù]WF)¹(59Ózn¼²XÆw â.[¶Ê”˜øä„|hnk@åÏT{²*¡ÎþBaÌ7ÎP QV¼ºöƒ–Ÿ%¹P8ß-Ô@Hü½hdÑ ZÖ- S\Ìù,åT•Áú¢£pÿ—E ½âW%jÐö£¢œoˆð¡À’賓˜ûÊHŽ èZ¨ )YPäx|CâÒýS4|*à»ÒòQ$ "o¾0IQ÷ Ë\$ 1ü>ž¬¨”´E“X¢ ¶¨KÊjDàp*´Eæ¯ äAJf¯DÉÀaÌ`á¶ò¡ø©üê­( Ž B&œ€!2@8霚À%H!ð!¤†`F @º¡¢ ‹d<€"Þa¨%P`z €<<ìü$Š$e«¦lf^.-nA裭‚ĬlÅå&”B6_,Òü'N]ÅœÍÇ gbt&HÒÇì M…œuË¢¦êTp®.°ƒ@g,0Ç£ø¯ÜÂ+ô[Çt[ÇLbFÌ–u+®läÖ¹xÇÌ.p¬ Ø©¬"û± vgpý¦ØuÅ&Eq Oƒ,îÀ†L΋Ò^‹äaqO&dEl^mk„È¥£Eö¼eàq&Ÿ,릥‹cæßèO1ÁK¹±Om Îi ²uLŠeLì½ Šò$!Ä¡á¡Ô2`íæè„À4ð¾$ Fi²™D f¥±f´]¥ÊlFFjÑHl‘ek¬ÈD®a8ã¼$€lÈf‡H1¶U!Þ!ÁäÈL¡Ø–!ü,¤‚¢\€l™áé!g¬Â<("¤HÀP‹¤hÂ\Ø"ml¼-T¶ ~BÕ%`4©4!Æ,ÂNáö3 €°²Òí€#"‚(¢.çoþXbÒ|ËH*Ë&…`I6"î¬@áô²*RÈÎ$\—B45 ¤Ø"ÈÝëªæ Lþt‚Ú%M¦”‚ZÜ‚ä$âz!Ò€ï0©Ðº§4à—¡ôÅP–it¡âŠˆ"„Áöˆ¤L“!øÚ¢†ð#„œhƒèQDÜIBâŒiN@bH#‚^ŽFðn,]#âÓTKˆ@¿"d tðÄÀѶDb®—¬ô—Ê/*˜'†“Ä^9ªÛð--¼D.Ê5"˜Ÿ£šñ‚ÈÊâΤ6#ÄhÉè*,®VÕÂÈ$‡ª4ƒ>:@ š.C ï*Ø1î’Ÿ1¾žãfàF£²€‚"ï"n´˜î„ÁÞA¤-!Ù0@$Ë AÐ àÐåM(ô3 FŸî\iÄ 8šÀsüÇ &(nGfN'ŒÌ~z¢ÐœùìnQ"d@B¸OÑ®H#Bš橊Î!¤üEÖÐ…kô¤„¸Ã Še Rd(/hf~ã3R¨°Ê¿G+?*æc&H°õèÆ,¦ÚIŠJ£4¤fnsMJÄüÏE(kíIå¼£I@2¤¦¾âb~ƒ âi$ ¨“?GÊ&ÞIKýJ‚ÁæôEêIPé Œâ"DCa”AbV–C²¢4à—Lº3à@ —à"Ò“3!°aT Ü6 v6à6´aæ£23$aüÚaðœTˆ,à3Ú`<ÀàZâS ɈZ¢ý)辫€!õ4ˆZ¬Õи¯Ó\¦0Y±ò©¬æÂ¦"^ÆæKQsOð Õì]Ãy.2lóU^ŸŒë ävPdoq lZ¼ØP Ñ jècB–¤Å$¸Œ‰+ƒ¬zÂ/Öc5˨g¦‹lºe·_¬+$2­~B®)Äf,â€<ÐÊ~"µÂB<` æ(”%§xJ‰’íæáî*áêX’¦èxAÄíaÅ–® Â× 9¢ú+†ã  wI¶('ú!š-"úÕtþ£˜—rV-b².¨2ú,íz‡¶2`‰tê@V"`‰ò 8! ,6aþ¥H$ØvQaîÊ@a»¡Å 0Ct,÷p¡À±¾*˜.RˆÉž×It49#V@87ò|iˆë&š@RV.”zØ)2]ƒFcáhgövè'‹BAKe·´¬æ-XBb.î—eìßFÏz« î"Щ/@šd¥JÃãM†„0rEÕfi2F˜Å¸Ì%ŠX)\n…Ì¡0ªU\HoMOæD¦&Æ\ù' œ9Šø´ÀŒwŽ"p5F0JLZ›ê²üye ê‰N/н«‰aŒDEö>`¶:˜•Úý"è™Îáåb„„ÍbÅ8ÜžØ4t`Q#ÊÓ#Á–¡82æ5`NO6!ºò±À4 R̓Ÿ±¿ŽÖÒ9  : ŠCyç6ÚžX«u£t ,†e]"hIQZÈfnô’È«üû‹ˆ£FSi¢ZÅtaLY5Íj4FØñ«¤Çl]dËZ!_Äbá†ÔÁ6t^†1BtaöQÈòº'p' )kv¦çVbjo±š&`ë¼ÇVo‘©o±Ý˸¥e,)²¦¿eË_:*_6©¢t¨ÀQDwB”p¶¤ÐÖmÕ[¬1hqðÀu+öêmBp¿Û(×­4Þ[ÚÁaV¡`¼LF†¾ÅÜIVVuQs›"& ð"ÁšéòTì#šÁ¾‘¿w` MCà4xRŸÅœ{©vcLØÂ›¼ƒ÷p0M3HÅ'luÖQgè]!éˆì¦ÂBA¾*áâIÐ@00âr›7Ê8ñÅjÄXÉzÀ 3âL×"Và4†`J`Z.ÒÖ¤âÒçªòä’¬^ôÂPE àÌÍôf…$¬…m´‰D¬Œm‘MJÖÕÊ he%*ô¡#‚#Ä×* ì"]:WÍ…šÚ$3¤#Áò‹ï¾+m-¥ŠÄÌÖÈ>̵XI+   J"à>šÀ K@áÛVÁòA®Ÿ !÷Y4<(ä l%cH‰"ב82‚%‚B˜úCú‹¢ø¯¯{ÌÂ%ELÚ ‰‘R®+wÐéÚÜ©-T@bØd@áú–í²ƒ¼¿y<àŠÁê3 ˜bXè¾#ä?DGØ£;_¢`›ŒnGCò&M¼Öùèø¤º+H,™¥£š·Q½bÍI3’êˆÀ#Ç@Pr@~6ÀàZ!§.TèZÂ*2¨,X3C !²2˜ÚR¤A³A`«@ IÝáðétAâ„À ˆƒ(™bÊÕØÄ/ÉŠEÎç5´¡"rM rYtdŽ„Œt¦†Fö}ëÎ@DHM¢<,XHtóc—ŒåÚ‡¡ã9z…&ÏÖ”ìOÞ6Qgl™œÅÝ­hßMB‘µÅÿØØAó“ èìBª~¢Ù¤ÒDÄ'Â$Œ¤Ëëw-âÚ“Lr,äú‹BmÜBn>ä"Ûj™çS9âÚDFø¶«ãJï¢vOµÑ¨º*5eF ºk¦)`,‚@AͨÀ&iu('%‘"4¹ m`ršxŽI?C2a†‰ÀV aÆS¡ÝBîœ` œãnK@ÑjÞèL(¾ØŠ˜z†ÿ,0€.´(•¤`Fì®…*Ü5Ÿ»zµ'_6¦cêUgÆ_$v‹Q[ûff\«ùÃ)äûUe&ÃÂâOPùb¯ÙôÕ²Ì v ÁQhÕùïF&ÛÕÌ ¿àÐ þ á¨46 ¡@Œ4ýŒ"˜öÃ_ШŒZ+G#QxŒ2 Çáqh´â9/Å% ôÚ™Ì q¸”6W>§'¨~iBžÅêTéäªQ…Ntmeû¨Î§±Jez“?‘P­ôð6C³€•ËEªÛrŠR­õZÔfù ¦Û©òÛ­nG ²Ö OÇÜ!àꂹÜ€Ùîï;Ýîp8Ä‚(4W‹ð^@ x-ŽU_¢ÜiuI>"[‹ÇÀuØ4GT…PhQæ}àO„ÀyN÷€&ú—@(z<»ï—³Ô @°˜^„ú‚Ÿ³Ì kÈLÇùø¥'éö}¥ç₨hĺ º^¶€8 ì(òzH„`20€‰K§ŸÇòH€J@FªãâH—€HÀê$ˆÁô}¤lÀ‚ ’'‘æà4D`3Ü|-‰è{¥ñò@¼ð* 0¹€éòò&'ñþóGì[º2B#*DGÈü 8$…ŸËÈ‚À?‡ñÔo€ÁÜi<‡»é:ÇÇãÌnÁö¨X9)!ø{«ƒh¹¥(ƒh‚¤‰J 5$ª6I € G‡ÛhòÉx  ¢ÀcL|T,;Hlð}>ˆLâ„&îÂŒ‚€àU@„ øq›†º ù#ª1͈$ܹ£±ë¢„N5Š,*‚bÌwPìS)Iÿ4ªyùs€À«t0¢¸öuŽÉ=À€xÈ4;’øŠì …eJ{‹ªÖ/‰Ñ¦áÒ)Òa˜V&H t° C´wIþB({±„`xH;GI´(¬QÐ=èõ4@N “î€î3Ó(õ\ÈÀg€ R0 €Ð+æ<ðÕTü£› ¨-k¿9a.•¡ìƒÑú¹}g™BRŒËÊ‚,—è=‰BS‡ä¢`–QCäú¤¨™€1y¼x’›HF©y—v”À l!fÑ CÑSß.id—º"¼\2\.j¾ð I04ÌüØXb,<ѮἹU±°Jè—1ÄKÇÃIAEÑ1Ôv´œŒÐü“õ†¿RhßR2ºça"7ej˜Ñ£Z`!&qäªùi%áP7B‚^áP‹±2ÁìxÀ(ü>’MÜ:óŠÞ{𥨔AöAQ™,¨<=dxµß¡Ér WZ•dÀ³•ÅW·mX ‚#ØyS “ ·à”¯uæ­¸‚¬Íô±µˆÀù`¢‚À”PÅÁ¢ÇÚøÓôtvŒa}«ù «„ͬv.[CcÞ€qécÀQú^ä `†Å Èë¹DÛB 8@³¦Kãû±(EË&Åþß4 ÖtIȲ*‹™>© ѵhÞo‰UÆ$±¦fAp¡x¿ÅؤªÂ¼pæ"*$ú› ýI º>#rœ©’ «€úw…X½ü<ðˇúø“’UÓ:cÁüȽd€À]éÆ:î~c  @ÑWÃüØjƒÀ\=Ù'Çú/Iò} e!)ÑæH7çožLT]Qô§LFõ)œ$ÚãV1A`,¦œƒÂAbGê‡Côzß ®ÀPI£ðq3¡Ò8y›ðèwކ>À¨% ‚ 7FðÚ!xá6%ñê–À5B@àä€-º¬v¯`–û%à8r¸ @”F޲cHY·)ž|{„1z=ÑÝ×1:jømf#©>éÍ äÁV|/œà–ˆæA‹½0ošK!9Q¥\È£DHèF%óÙ¤'Hî%=0Æé!”“|½îA—ø±&æla:¹÷½â¥Ë‰ky];ÆQîå&4®.ók®:‚Ó0ÈUV)Ñ’twB¸<ÊÊd»xJSb ©Uosqã•Y<ñL *~YËõ¹Kj±Šïe½¾¼xã(Ÿ,¢¾s­ö³.‹|´,¤tA¬4l{S@"²“Ͷë‰U{à|@0€óKèð~šÐº×»d´Ò^“ÎÉÔ%Ùhí¤¨¢xÝÙZpöI 8h†`ó*ÄÈhÁD x ‡ €€té)Ђªy]‡pw z‡Èó(Á)‰ €°ìpˆ€C‚·ø?ßO¸Kùþ ý~€è¸öŽ@À0 €@ @6†J¡ð·Ðû„De²Ð8 .~ãϘä2]8—!à cÏgœn.J߯7¸øý‰€k2À!ÿR@²@âfÿ’>ŸÑÉL¸²Ià(Cö ‰ÅߘH ùLÃäàà401´„Qp€€íw;@€Uþót€/W¤Ø0#¶¹‘·K>/N´Å%À dAï5¿RÀPB.û§¾ßïi`'{»óo·¬l 5~?Á³`˜lú{ia[·ûûKe•ܺ`8RJúåK»€€Híï´¿¡—{5þIlŒWŸøJü¬)çð˜ŸÉøüŸèR¼¡€*Ä—"ºüˆi$ÅA‰d"—(@8Ž©h ðª\¹¢‘1ì}¦§‰ìæŸgÂè%iëÚÀ@ € ƒè~7À`J&ÀøL„¯è•ŸkªV‡ªPlP{gŠ\~* 0(Æ€Ç1Æ‹&ó®j—ËH退°H)¨z«Ç!¸æñ¬ àT„‚€Ò¼‚ëH * rG®¨:!çôh‹€2£®ˆ/ˆ‚—LªK¼ îÓ²ðŽ! ZépM8©…2—%*•Ø¢p44¾ÂÊËO!ìJì„¥•4”¾µ :ƒ£‹:¹Ê`- :¬¶T•²)YÓ4}­kI•¢êŸÖÕqü´V’Z¥Óµ¢—s£©ýà±V"r„Ÿè˜Q[´u«t­çt Ê•ŸDõ Ä­•žZ¢­ÿ„áV-ÝtËil7Rb*J—b)˜Ô ~%¬ 4—%kµ\uç.¿‚ È:'‰ÔÑ è <ͤzG ys9âsÍPûu¦Ø…ŒÒ·HGÕ!à9Øw€2óg« ºÀ(+ gÒH„TJ¨å‡²&Àðà«:iŸÂ Ž1„p˜Ø´TýÑdØ}eÇp™Á„"Ü.4¥­”ò-ÏÈ®¸ê-ÖIÝÙ„dWõvrüŽ7×c\®A×%Éiù€ó¨â(¥¯q:ÑÝ)•R–wœGÁÞ}Wt]ipdTÿŒxoÁÕ«µÑÓ∺Ùaw|“áô>d7Â`<t}–ÅÕò5/uð0‡×Ä`8ÿGVKGÀíB!}îæ.Ô6ó£¸~‰ô:Ó ”v Uö»èàŸ;Ÿ} á¾wœµTûôbð6¹—ôã áFÀ6M¨ð4 k áÌEéÍÀDéuàÉ0àl³AâG $€PŸ€pB`Ű¿¸DÂü_³¼%®…v¾hØ º%$=_!Ì9Hxã0”&ºHÐújƒ¬s% , IŒì’AÊ9•‰ïk€< tHÔg4 °˜À, ìxzœ@Dˆ!SIQÞ–S¥Èðÿ(EÈšr&¯Ù ?L'´ª"üC 'ä`©.r&YÒ¡_%$õå—ܳ@òh’K"4FaØ9¤@ŸÆRŸ$RăIæl@:ãè¾Y4Á•$O˜¥4úæñ̓ð˜¢h1,b( X¯ G€JKKÌÌ|À€¹Ç†G4‚&‡ àHCh\©âºZÌ`ýÜŸ”ù>S\÷†h}’„ˆN ã°’­aü?Iª!8ãø€ÐáO 4ëK&?G[. $é—²H‹Ð&£ìu¡€ˆàk ³bG°ÿ)ïñL’²N@ ‡zåAgË¢î©;*Rµƒ­â’L 9!Ĭ¬ôhCÀ0!0‘©4oÈxî'4{¡7ªœø%<“°"T0 ÀѰNK04C„h¹¨ôL\Ê‘/D|*„#\P°å sQfEÇĆÀiCÁœ-€LiÄÉ€"Gø:Ætô³KoÙ1€PY!úÉLdn,JKØ1x%…é;X­9zB*¬³-µÜQ`y²T/qˆ«ÂŽ¸Þ £]·um0ŠÜûÔÉ„K⫹õ@ãË=cp7…|\ÇŽþ”‰¿EÞ±¼WRò˜&‚%Õ[€g ¢³$’Ôº²g€µ {ñ]e[¼Ó1XT\B0j\]%Å{oêÅ#õüguÛ˜xoVýÂ3„K€DndèÀQêg‡ªZŸ§|v-a &øuaÎXö3Cd\ŠâÙÀ3 P á¤5S#H8||ÇÉ£´åp†ȸóV#Üz›°×€ªw#š@YíRľ·@ÿ`“³dÁé®?€!$ƒJYŠâB[¥äÓX³D½˜òŠ][z,«±s`#‘s—-ʡೢԸAû12Ó [™Ó ‚뮋߫ƒ|¬ŽðÁXÅtUás+ }JåஞyŽ÷cÀ=xì ì'zˆAÊëÖ§™&™dìaç`û½‰«¾²uÚ÷j>WytKÕ xBMa»¢Ã uªsa==äítnÚ_zÃOâÜRþ·Û¨Æ»‹ln'–ïЃH"c°q}P†ààeÀ\’@ΘðfHA ŒÀ<Ÿ€¨‹.\Ùw…¼˜@ü^ÝÖpp ÒÃF@öKM vÁê=ÕˆÑ~‚j:Ç! €0’€:{GPí9£öËIj˜á Y Ê á†•3PÀ¸$UÊÚV’ÉdlR¢ÂÅ…<}µ<ðá÷XµXç÷gyˆ, (H%Ý£ƒ• J€öàFBMU‰l$úÕN†? !A!Q&"öDü«µ!ëBÑ÷,͉)•LJv’C¢‰Õ ‡6t²~ê@EÉF„þßÐ̰ ,ÑG+b@iŒ#pk€Šö#¶ÔpŠMðà—ð8¡€ )ão–îîHùFŠÏ@¢(ò&¸£Ú ÂÞ6ÃŽ@2åkúa”^Â<£|à$Ic™òÈ¢(CÐ"\!ÒOb.&¡ì$Æ)%мgìD,¿%<Òé80%¸ÙeçŠüàlX*B²ô`\‚<1 #B¢! è0ìâlPd#BfŸà.o@Žé¥šp 4l å ª,¿ptrb¤d‰jXƒrF¶Â<êáÖ``ï§D*"¤a°#Æ‚j,°õÀædOò!’L&¡òb/b'Ž^0ÄÈK,Æ&fÇ‚ï°4Aê!àFnªÜBÎî8¥£¯ Žˆ#`W*v#Áà8æ$Ô>DÆ XB˜ˆÌáx&Ï$-!èeÓè@1€z4CvÁâeÂ()ähžà+ÃÜDÎ!üÔ*¥VxÀDžI‘QÏB0"‰ªÄ4î„A$R®–#ÚõÂbCëbeD-"Ô¼B6Ÿ ’£J­DÆH#²Y‚'à:Rnà0±à@ˆ:àG¤0‚B:çL%ÀÚ~”ê¸:áækºX-!ö7`(ÆfÏä%Õœæðö6  P¢.K’@D2êCÁýTfJ%P^€BáŒPt,D#…Î'!ü(EÎY® R 2‚2t/‘©QF|ñd6Sx!æL)Eo“:\+×Ó Üf8B«Þ(¬¦nÒKaò9BÀ#@ŠdtA®3@C/üˆ¡Ú"»$bºè3ÖÆf jDb¸*¦ÚåH“õ’*"„/ƒ ¥’‡c Fd"V–*\òà–käw± ºÂ„‚O„"Eƒ‰C"&ã8#¢èwC„V ®)5nɬ4CòUnš0‚aiÅ„t$. ξ,ãðW%"«+¶0€>BÉ(BÀ0à*ˆbl&ì3dæ M\¡ëBR©¢JËF0ª€BB™@AÖ¡EZ"`E¤þS#Û#aÑ`ÁòVâýÀðþ@0nÁþðà:Ë|íÁúA:éüD*¯¢‘¼­1H˜aöãjS&ú­~>j^"ê¨aøY§m=Eöe4°"®E„ªbŒÂE:L)j¬%ÎVÚn—ãç¥DF$€›L&"áò&bd^"”„Ð"V£"~ QÖ‚º+Ô„# Z©v Žf•FnîüU¢âpBÂÖöZèÎêt`ìƒBæšk 6©D˜¡æ¤ÚˆGÓôêiXCÌ 5àà·ÕY•‚8àú)͹>'â#ö„^ ¢2´¾¶ºbàOdX‚ôZÂ4…‘óE‘^D"öÐa-:"ut)$P¦êJs*3¬R¾QX.ÊÒ%Bl#ˆ_%C¡cÜS§š…ÌVj¯)EÎ!‰Î`"~á„w„ mEhØÓ%ÐJq„/q¬VÓfõK£dŠMxÆT¬âÂ.«úÀ$žòL0èn/¬yEõv !<pâ#€À d„ë£0äùÁü…€‰î®¶M-g"|¹y hcÓNƒÓ8zx 5òq'\ÆB]ç~¸Í/÷ç‡בxç"Ô²z( šÓÈ;€’‰z“ p³¬Üü¨ƒZêdÆM(!ŒWéy x‚§¶ÖÓ@xöG37¯/­ëz ®×ù+Ò€Ò¬c\±ÒƒØcx2çÎ2™Àò•¾ÍôÜG«QçÒ<ã3&ÂÿÁÒŽæg0ÝkÃ*s¯y1,y˜jC|¡wÈv‡‡Ï'šq¹-2ÑÊW„$fP®Âˆ%Á¾¢ªÖ#š—9€%aÚuX pH!¢UXA¦Lâ¹!ä¨öP2Õ*%Ðì-(¶× 3Œ˜QÒ2xè5‚·½&„ÖâÂËNd‚"â–OB8ùP ¦kbžáàfáàÁÖÏ 9¢¨n"ºÈ7!ü”§>_v¤ÁYª“‘¨TEš÷§j\€$€ C£sHLÒ(*¢¤<3@£*ƒB$b ¢Íß»Áø9¢š˜©DШÈE4>Eõ=B&«BÀ6[ÂñB7rûZB[8]‰n{"À,>.îÛÂ/ Ø#€8RÅAòL`0´Ê2"äíÁÚÃVÆj",2fÌç ø r¿¡€m*)OœGê*U“8žÌ¢€9È¡T M¦Õ€øj›Ó¦ô ËøP€hÖi¸ý›>À”K¥Ùo½Òj8üä€<À•Ð 7t¸ ¦ì3"€ÀˆV‚û‹Ô¦ÏÊ¥jÆ­?@U ôÞ}Z¢Ó@s`-îï9|ÚÀ»åïm|Äqu*­–©…¥lìS{Úñ»¤\ëUY¼Öqˆ£QzT—çeùF¦aæàYŸ“w›¿)5Ðf©Á®^â“wí'éàü8kzºÞ=«Ø®;'Ù𙞇‘Ü`˜$¥0- ÊåAÌpÁàB.w§K‚·fÑzY&€>‰# !‰â” ©¸ €o\ü¾ªÚpÿ½ü…#? Œ ¯/„†èÈÑêðôÀ°#ºÞJî2n÷42ª)+Ð ´¤·2;œþ¨Ñì®=²ê» ÂïÃU0»R+ðýËKÜÈÃ>Ò:—.̶æ@Ôó;0ïåéBÓt‡M’Ô×"64L‡,ÈnËgIîþóÏr ,N4+‰ÉL:òúSP½^ü>/Âó1£ò é8Vú×HÏ‹ãúœS¯m-#Pu¤û<·Š3/STÕqM×µ-`­ökâøØÏ¤ßZ­õLÿMÚzº¼¼Ï”±_¯,œœùðÖ!Ð:Ç5äiš°xœÀ*µìp0‚ÀÌu5Gñêw€F#4$( ¹î¸)¸"½5”?HÍhÚÔU—q9ÕsïJÜ Õä¦Êlwž‡Ø ÙÞtª *è¨{ž7”Sy`¸(§rN|Ÿ Òu€4 „  )NP@Oºs¦mÚå?)jÑöði §.¥ƒÀ2/¨Ñî{"‡ËTÜïÙ(2§‰îÊ® fŒÊ+Gãf{Ÿ)ŠŸÁŸÇÚb±2­r€Ø''Ùøõ¯ÏceÎ/€#v}) W*é4úIü~& -~¶5Kõä~óZ|ݯŒ¨ˆ‰`@€@ €¸.£ŸÈøðgÄÌ(J Ç™°l©Gž&Á‡™³ †™€˜Ø0 ›"€v%JÖoŠ8(:‘$£Œñ”.äL˜“1ôÕÕñ¯@,–礇`±;Pz‚@ ô°€œ²*Èû`ƒØyÞÏXáÁÅ|—RÖ|Îy¬樶©R œùhðX¥”Aöà̉'o(¤‹¨#¶Q¢NG·Âø?öWØ|`?ð‚ÃÕ;P.€ ¥ñâÒ€@-`t ðV ’ñ@+F¼áœ‚´<Ø"a:S~ˆd€ÇAä;° H,qŒð>¸ºF )©`F ÀãÏ0|ÒXA\k´Q¦0KXûg p¢( 2<% qìÇ y6*™¼”²Ò"€Tg¸æÔˆr‹CdG¤ØLãVÊg&F¹Pœ†nË™`ReÌå’r>‹R+G¨Ú¥v]ŽA“ ž€ÀÈHÂ3ƒTa‹0Á7¨"„âd>Ì©tr‰H±NÓ†] ™þ-'œ€4Ï7Ù99£‡)NT€ÙÉt' Ô,t!Á×,J#ÄŽ~3I³u%&5T‘çRX¤é\¤ô.s”òÝ] ‰T¸QI1’C¨” P ª%|LƦ:G:ûÆ €ð$…Xsa”Lšò!$1€2 A3Š=çð˜Ójè®RÚ[>«•!¥µ_QV~W.ÁgØs곫e*4¸²©¾ëÂ[Q ™k% mÊz\évÊ  (¶”äZ‹} x^Çê¸S -¤³¿h”•£8ŠiOTu{_ IB¦+Þ¦+€mÒXÇù,Âßk-R®'–fÑæg^W!{¦¨'ŸåÖ¹ŽÊ»H‰éYÛë·«ý²?åPS+‚ž®áÿf ðýep”’5˜º':ó©+!L¯%‚Ifð²Ô y,Ê›³†ó% µ®º§TTƤØòn991CežÖƒ€à+@˜ÖA¨4¡î¤L€b ôk íŽ ðTÃG2! PP ž³M-éOUʇWÍkZd‹zÏõe÷ ¾!lހɰë`€x"r“SÂdvñô<™ðª#ÕÁÀ‡Xê•à{Gùœ@"„<€Ò/šIÈ`Œ¥€iF ;«É…›°ȹ¿1(%M` (‚ÍÔÝŸ²r>»=&D|¸è@tPFLæâ‚ þDŒ€s?ɘõ³¤}’2ŠÏ@8Æà™]?‡ójÃܘ£¢g|€Æãìó¹Æ ÝJ¡Xvå…J“b™§¿ÓDÍÒ–—ZN¸n5‚hÜQÍø1¨}m¶9‡ÌÐt ?]¦!ƒè“€P ªÀN7£†Œ1o@AøW/€d‡!Âÿ¨ÉP.]PŠŽ(àe‹7á¡«È|:¤)4uÌ}‘ÊRŽÈ 1Ü{Ž1ŒE›¶¡Ö²3LJã\Ú­90 ‘¡ª&$ù9'qô?ŒT?-´rå:‘¡7fìÕLÂråMQ®+Cà};ˆ~Ð¥ò<¤|€m’^ú‰•ŽoHƒ | _CäÕÛíŒg!ìáH`H“ÇæâtGèï•øsÊQÖöª jæ?x 0œwÇå†é4¨l|rfA†ÆŠ”I³³§1P,‘¤ìâ½UiÌLHï¬ ¸|øl¸@µ‡r&b¨x&™¥QÄŠª6Âo,©¸‹Xð ‘Ž&ðÔ´': ðï c›¨÷,Ø£éP{šTÒˆÀž¢‰êx?÷!¸¦–Øî‰°¹ñ#¡™sèú‡Ñ1ŠJ•O6S',’ù!™'”òÝ ¡s‰ÓbT£Y‘ H«È¡©‡y†PUИɉ‘˜Êµúª¡À|‰(2ƒØ €¸…‡y ù×™è ð ª#á™+Ãë( Õ¯éº–‘A—7AÑi¯ñD”éY”à½È½‹+”Éjx㦉<–1góL+ÔI²LR.aX!PŽqXŠ0~-`õ–ü4)O?ä"°qš)SAù® -®ðÖãŒAM.Àì–ë«øâFLKÅ„gèþDpÿÅ"¬¼Å¢í™i@®Ü!tjÆjŸFZÍ-ù"®òìÄôf. ØEYv›‹á(’ÔhÇ"üì-¢£)M-\>ƪÈ,ªg–‘1•²è»! ÊÅ-*ŸB@½‡| €q†à߇ m 0 ¢¨€À m¹ ‰1{!:Ú“2+ vB­À£p *¨”@ ¸}Z¬ŒzGúý:ò-RÙ éO4).toÇЙÈwX¨˜w&°øx€¨ t‰°x‡Š­¢ð‘€x !檈æ¨yœà9ˆK|€¸ŠŠ€Ðµ“pÀ°ÂÀ ¨€2œK‰“M PŠè†48ÐËÙÅ’J °€“‘©‹¡Y®Èw$ ‡º­€Pó‰°™€‡Á¹ R‰@  è~Øß€ ~ËÃE€J‡‘ 8ªˆ±šk‰‹8ˆXIá‡ÉÁ‡Ðò‰À™¤©¦¡¨°¢ó¹éÊ9èзàŠê› X*‰ ˆXwÚR€p»È}Ì@R0 ˜`}[¥Ãâº2o5Õ1B )©†°e€ ‡Ð 9X}RR‡`cŸËw— “†ˆ1ˆtøQo*ôç€`™€Xb[ ˜`w†Øf‰ug%@‡š8§†5ðŠ! 4ÄÀ2©Ù€Ýc™AØ™"‚/‘ȺŒ èšh|Û¨›¤X’¢ ’8Šx߇é9)3lІ~Qpà€¨H~‰z¡éæP ‚03²° £˜ó’ ‰Ú« Ùß ¢ç>yÑŠ8¸èÙ‡À‰"X Ó-!Ì £‰ò‰€v%@³Î‡xl…ð™Hn  £»‰ˆº‹Q‘€ ±¸Ù}(kˆÆ$h‘‡`mƒ@ ÐÊ ØÓ‘ð»‰èð ±Ð!µ`¬D,╤ò’Ê’Žo ºó:šq¯{î Ê'À²s&à­ ¤ óþ'¯Žê>À€»¿  TÕ øs2­‡às†¸˜0ÌààéåÔÑ êf&$.1dŽ, Œ¡Wʾ‹˜÷I¼UÛ" €t†ðiŠUu(Ðȱ°“è²`¾ŠhóÄl),kF3ÅD©V­ªÉÆáXk(™¦úš¬”ÄHý4àò‰°˜™èkKƒÐp؈Š"ùž€¨ гè8t 0~5J€xˆš0ò©z:Á Ó_ Ê/È è€pÓÓå-d¿Çäy ¡ÔMy*šDhB9S¢ªÜ.ä’Õn—_“¡È*9S¬“"-2ŽzâG‚È+Û(ÄdRG M0|ìö öÛd»EâëH2Ä-0çE¨ÃŽaNŽÉ•ï’tK•éÈ/j˜­4‚EdEéMÂJDn(Øø°ìFœvG[[$GªšFLnBc'WÒÁjÜ}ÆÇ±\²*é•!s— "¬ø¤¬•ÀݨüY‰EÁ)ÉÙ?–é’¯ZŒÛñI)cB}µ²2Ÿ è~»úLá¥Àa…¨Ì|ˆøÁ‘‡Po†ù·¨–US½{1 ˜ßÎ1º‡±ž‡&©‹‰ú:=x“£J }OÑÉyx 4¨°$Ñ€@ ²•´o`Ý‚ÇWÊðFákÜ\¶¨˜+¸t˜ m˜èy R“¨‰µ± ± ¸oч¸xpÑ›ó|‡€w‰ˆ ¼?Òà™¦¸²¢¹±¹º´Ä·à;©£è~ °}€A© áÁ€@€»•½ª2‡mwº,Ñ›uÑ`{~Ìð²€Ø<é¾ ÙqÓ¸u‡+y€Áš8Ê9#¢é±€(½ã—»Óx&côеdé9‡ý99,ç¢ {Ñ@`KH¾=©º€Ú]‡Å+LN^S°ìGÜz(âÔ X߇Øt`ó€ ¼è~Ï uj€Àt ť©¥6˜kº†ÊLKŠ;Æ Ã´9Ç€ó·¸q±º‡jТ|š!£ =   !y¸~®IÎsÚ´ãÿÌÂ<·"¨‡ìÑß}½gbð|à¥?\?€PÏ@|V=‡ù¦Ñ9KÉ>`àÚX¾€Рtˆ˜‹!€‡ÑÍ€è!#XJp Þ7W l€Q (ˆò>¡ÀÝŠÐ{bI¥TH€”Ô*К>ž<ð#pw+˜€@ x€™°ÍD‡ k9~‡&xHi°wØ“âNx#QˆX·Ãm‡ñ¹Ò:ˆ{7ŠPš hØžò&„$ ¼‹Àä”-h›ô¦ú™¦À™„e1U¦™sŒWáoÊl“p«Á7¥ùiÚçªT5Ø Xkˆh‰åÑÔë»ò#µ a’Ý9•€ì‡Ð|7XáÍõ9'‚?ÎY“Žà}˜ð|Ò.˜tvÚ0È›€r²=ª Žt+Ê섎Sm:¢ ŠèJJŸRá>•ÆÅæΓíô¥¾®Ñ"ð¡Ðxªpj&oÈrWp{鈷È[€à—‡lÑv†˜d†ï€( ѰR9À[V;{—uZtüù}H KÕ7ó© €{³=Ar†•w x³Ú‚=x´<$\ãÕ•_2òÇ%è.ALÛÒù–2Ò./•Óù4®ÙM_*Âm$V-ÎHYe_Z[ë2UÔ’rÈ,i,n|rÕϯ4KÞ¡hH"ÈX,¤2q=Üf÷/vr·(~¶’£ÿ1Q¹O“BÖD:¦Œ#D¾[ùj”Üd.Ýóï/Â.“Ñi+æý*1’ÞàöÞ¢ÊîIóÑÄõÜ‚õõKÍÜÙ(ˆg7øЉw†ò§€«˜€¹ØkkØcæŠ; xݳ!žÒÉÁ†ài9Œ@¢2,à J«ÊHÕvéàjªØzh“˜˜¸ €Ñe³k0I'Æý^Dá„a’:Ö÷“Å6ÛN°“íª8Ž ŽX›‡°w‹þ‰‡š˜t 0{‡ª8€P›š]‡€z Pøµ¾ÊIKOzˆ¸»»s€à›‡ÖU$¨·ÒÈ™bà§ ˆè¾…‡œ;ɱ‰€h [”éÞŒ<¢È¦ÓÒcáɹ\@‚O`|‡ùèx%B‘À€n”‡¯—%æ—€Ì7ò8‹P©˜³µ(­‹FT VŽ|ÂgȺŒ`éæ°(Б‡èoqºðð›G‡ê“'¡lg¹1NÖ €~ˆq†‰þ`‘À >G‡xq`~i ‡˜n*ð Á‹¼+Óá ð߀P éJ©›[Õ´R:( wØ"Yix™Ëá©øS^Öaðy ÃÿÍ¡1  ’zX |áaàx‘a 6e2‡ÐxcÈ™éÒ ††qmXÍÝâJè{˜%. ˆa –o‘¢¸zjð˜€Ð„ër¹€·ð@‡ü%êèv€¡ ð€¯à?€/Ð  {½wK–Ùg€¡˜ìïxBŸo€ .’¾€0d9H Ç@àyS•ް‡· pdR|¿(òx0( S PXBà“îB |=¬ ¹ }¬Ó…†`@±¾J2ü!ÅJŸ¯÷ý–OˆÈ¾ñ¬8 ‡Ãäq0˜TªM¡Ã[4¹Œ&Päs8œD®S¬…g³Ò«k±’â¶{Wü£e‹•_Û­.ZýdAYS¨Ñ=\Îöê¬@  tV‰@Óó"Úr6Oð“o×gµRNêÝm×Ip4iÑøÝ3m2’8MÊ^y€¸h™`ð„€ÎúÇÑ%Ƭ6ã¥@;êTïñöéK, tñøè‡ÈìL@ ‚ã²IÉ*mülŒB¹v«$Å•›sð‰  È²€?ÌOš1âºAωläPHKÇXç ã¹³œÖÆ>À*$m(Ã,v‰B5CøÂ€ò v@Qd  œ  œ@¸3')öÔB‡À„À ?@>—a!À%v¶g Aê2 (˜QÚ8á±Ä•8qÛÈõ鈒rpRÀ( 0£ÐxC óçbèêW;s(€b€Aд§zR¦N‚ƒtAãÐé ˜Ä€Ç @JŸƒ°„Ó%cjÊ "1®²VþiÌù(>Éi1C:iLÙ–5öŒ³u|fù®~&DÇ‚M[I›VË<’·ð@•´ü9Ãú³ sZeÝ#ˆþ¡à—€ôR Œ S ¢ù‡\F°•,CÜl q ƒ¤„}òz7ÅÀ²-€ €ZÀ rИxƇ¸ù!*„ìñÀ6@¾$Qʇ°$ xàÀÉeÍÍ-?µn³GØò'£8` Ah*&Àz¤sl86èñ]œ…À¸ºéw-E©°‡\¯šAö\ðuR!æ9Òò†¨‡@Âqßi Ø dâ;Ý(÷p?Œ7‘‰D¨pìAà4¸`8â„”)ðÈèú$ôc‹1[oAˆ=»`而/Á|Q,£’“"@²œa6ž›B±Ìå›7¬˜•¿vZ»ŒòWñšœŒ¬>]¡ ÊÑ©‰±£~¹Ø‰%4 o'öBÀr²àd‹ç25°’o†bVîéŸd%ûמv½ÊÝ¥æ*‚ù  K…–¿Ä´Ø’)fL-—1´}{8i _4cÞÍ4Q¸bKu&/„P“Ý’ì4 õ¬0âÌòÄe¹—@¢ƒ„ÓXÚùY¤‹1;v¢ÎQF®_®ÉšºäŒ½Y2Øf HÝ;¥µƒÔºÕ¢…wžVæ»Ïlél/‡dÃÚåÒ ÝPbŽìI!q!#kÁä:4"nÀlÅñã¼Î¨ì¤Rô %h*€RhME­ø7‘¸7†Ð aBe‘È5ÆqÜãå»:Ð’À$¶à$¦ a àtÂå,Ü6’ÈXÛø±ñ­Ýq·~ ¶m¡ò]€ŠÑ¬•9H9FÚ•£´”@8aA%$ƒ¼u¡Æ8Š8ìC€’Â*ÀY9¤! ŠAÒ𠂤x>‘ý4¸ºRÕs´VŸ°riiUqûÄ 6J+‰<·>‰R5.Mc™ú<ʨrf<„¼² J‰)0·€ $êGÐõ" ,E+‰R•mØ/¤¼±äY@-p^må+™c Tˆ…x¶¥Àß›sånÃðIhbÊu#ì\Ñþêqè+’á#úS"aIPö1h¤„€âFG€ w)…Qþ‰ÈíC …‚0Z[9k—|ó3Ð9íæëé \‘òŸ •¤s bt9©,áì¸RææX‚BAª¥Ò ÄX‚¯œrc Ê§è‡ÒýIP;çî+áî%G*Ül§@‚ ÀÞËr¡v; (S…ß/0ÀŠÌH,ƒþ ÌôÀ ¬H p ci–`o à \‹40Áè(ƒÂØâÈ#ã\Šc1ë,K|%DæN€Bìð„%,%!ðnÌ”(æÆnÁÞÁ®(&”`6Á*¡¡ìO°b¸‡&ÊbÊDåâ,"@ŠÀÈ¢^FAÌ·„F# .ÈdÀ>©ú•È¥ã #–¬ƒJ~ãê²Ä”®¥¬5ƒ*4ÊÆ9¯LikåeÈVÊÆ[%씤z@îù ‹,ÐEþ®1tΈÖ~ c´4JÃÔŽ!Ö Vü( IȬ`  çX‰â4¯6ŒÀVÂ>%Ôáz:¡ÎÊ‚r ‡J dD b¶¯#ÈY¡ðE*®/ˆ¬‚ ÈéÀa¾°Ã⎀ ,€F¬l ŠÃ68¤r¢P¿Îaðôe' 2Àb, ndž9EpÙCyä˜Ê% gnvRT0ÎâI¤¢Ñ¤® ¤¡ø%¼¡˜Rɲ<F¢RÞ;€(EƒªâPìaînÁôî ¾2BM`\ à®#Ñ ÚÁ¼Äâjv%*ê„Ð*$!DÌ-ê;ü8I®,Ž*M¨¤&¡äP€µ ZcÇB@.'0ž4¥¤Ö¦¤Ê–Õ¤|Æ`ÉÊÖj&€_MrÛÆ«kèÏå«…pj­gÅxÕ-xgÌ>_žfÅâdÍN˦ˆaÀZm¬Ò+æÒc–î"W$ñÀÎf~ÐÎã7 Hv¥ú|­ Z¤ ؾg¤¼¬ÄׯŒg³NÌfØS:æhi3°Ïs=:óqìÀWÄŠÛsžÌóabäg2`jÓ`äf{í"VóÆJ,äÙlàÖd”gÍ2Ðsl]“澓‚_ÆXdŒÍåòäSʬ&pxbR9H\(ðÄ!AæH87@£Å°ú!¶à²ˆÅÌòDÐBT#‚ÏH¬¡Á,’”D쎒 Æ m'(*ï# Î0( mÀNq"謎¦i@ÍÏÑ]3eA£È4V!/0çÀ!O,2 ‚TäKŒ40ˆļÀJûƒ,"><ƒ¾¡È; Zt@4äâÀL ƒ-0ú=ì—èkm"ƒÂH8ã¾BèY£ ®  À ¥Ä|…bdAö% èL (‚°-áñC⣾´6aÒ¤HD2À KÄ´}T¼ê( fœ \@,èÈ‚  '$J'Aþ„+‚X#H1’\6íº—®hK54Ø Yâø. C–àdÊBBÅÌ8êÖ%&b2Â]ÐÉj^0áâ+ ƒ¦ò`Mððú>#!ñF₳Ȕ¡À¤Iìraôkš¸ÂTÀà¡äÌN 0¡õF¤¾@H0@2OÆÁž»AðÁx"ÁôlóJ FÁ訞!èÖ?âR  D„(¹¶X%À*NjÁjª¯ø’`L0I (B2À’ÀèHÖzÂûj%AOÆ Ê; šÃ|­ê'âtE6Î)&Mª® ªL[£b¾6¢€g‘,¡‘À9-Áä¼Ujr|!âKÔ€Mµ¼FÆA¾TÀ,DÖàN0¬¤oGQÂÞ´.-ëð¼8#")ç'_$Ö€¨€U7Ix1ÔdÎL ŒÕQ»cZcÚ%g§K†•PƒK]#¾_jêGÕR=Ô±6ă8â1C„[…šFQEÂKaÆ;(„ÐÊ$¡Î¤AàJŽ¢X(*àD€Tà¸=Sã¾ÖólУf_bB(áŽ8(.¤( ~úsBЀ`0©Gé Bìƒ#Av‚âd¦ò-ýÄ´µ¥ É’Bn`,î-¢¬êaJ,%÷Á8FÆo >e #ÃR6…ÜgÍo%åøÑØvÓeÆHîDW%´]ƒu"£P6øÆìýŒ*¤#úS$©:%áø~€6‹Æ&(à €HÖ¤ ÊVúiÁ‚!áànÀ2àt; n~”zã@0,áân“w¸œà®ôæÀÀ8Á!ðd¡´¥`PB:ò+š€v @@2F½%P£<Ò‹2e†\¦ÐnHaj×6f{&‘lÑmÖ9X½ìÄ奘XÅ{–ÅóŸDIå¿9¨¦[¥zd4ahêÐÌ‚1âÈ/Ëy'BP°LLŽ!æÁÂlDlÅ+šÃÒ1"`"ÀraàB“ /B~•R}Ìž4¢H“¤mR…*´¼| RË6Ôlë@¹×˜îFE7ÂV‚ã"K”®H6BP€>— ÚÅ$0áÜh*A°%Â܃J%áî0ñ;îçJ`e(`P|8!òt©x²ÀmÉÀƒAöt@bŽ>Bˆ±41Àrq p؉wœ†ÆEGJ>"B)èLà,áýi˜¸%ÆVGôô`ÁóB‹Œ0ã$6.é3úÈæev#"+¨*¶Å*H2>5¢Ž•äMyŠ®5Šë’sæÌÂQYƒ²ùQPu(;yÁç,‚Ê,èÁ ¨¾Œ(¬šõÑXcˆB€~€^ƒù‘¸Ë‚B£ÑgcÔ~€&ocÐfëj.ÌH1”ŠjfC0ŠÀxxAáù‚¢¿"î‚ 0 ,lm}H¤AüN aœ´Àâ*€0<áúÅ>aø%Á耂J˜g;(` ¤×Æá”¢±¥- ²TÑ8lnòr`2Æ .Rü‚šeB¦x„¼ D‹áä"ÊR†`F0Nù@(áôGX4C`‡÷bLªeæˆÃ[°øÁêÕÔd ÁÄÌ‚”P„'A°üèôX&ò E$‰àárŠŠ§RÀP0Aè“b%*ËÁV¡Ø'  BdƒF,# „mRÃtoƹâΟ‚€=z¨ÙP¨!-¦å*¸7|ÛÏb4ƒ‚§›zoV®Æ¶WqX«‚L;óØJ#GJMÈ/§|ÃpBÃeAé ab¨¸!áî;ÞPÔ .#77£8I¦G;¨Áš&K‡d\³›—ŒÁšÓðäwœƒ•¢€JáÍ,ꙣªêDß«šÀYV™„ÈFM!¶oÀCž2 A²:‰Zô`H€¦µ J-|è2ÀÄlaìla¸/°A¹9u!Ö°ú©¢sUâQ¨¥*%æìÀ$naî `?(`Hø©VÖ=Cq=KêØ¸|>d|-Zdz¦]Ì¢I¬zŒÿé3ó;9וå‡é jä^•=ÃØIfe3ón+Ý¢^e³ÏžÓó¡eöm¯›Ò\_²Y†U=?u>cbÈ&74­|G%ÚÖ­G-:X«ÚHÞœW g-"k?Õ¡My™÷ë›÷Sq%Â?À08 Á@Èú‡Aâ‘Gð ÿF!PèdrC!q˜Ü‚?ŠÂ`À v+1†æ ô~*„I à9ÔŠ%?h2HdþE<…N`ïgÄAÄÞy `X¬0P hñwÄ.רÄÐo€õ@&*Œ€0àbØé|g ¸>ß“G[©¸†•ˆæô½€€`p< „U€°dAÂÖlâ„¡ð`; †ãl´"{"Pg±9„®7ÁÀ’§³ò4ò{A]K88ÎÜ`Ì ñg¶9£N‡ êÂíw€A0… Øõ¨Õ¿ŽH"0ŒXO¿ßnì%&Ïøúy(iøy¥À0çùøªçàÁ ÈV¬ºv› öy)° ò€Gúˆ€Šót}gÊ3Gð ï€ÇôV ç°u0󿢀BÁ€áöˆ`@PE EðÙñ²‰ «GÉíŸÇ»¶}ŸJ˜,è*0~Ÿé£(ì!hƒÎåÇÚˆ‡¤(‹Â'Ú0~%àPK+€å¥Àx:€P—/)þ?çêöŸŽÁôž©²JŸÉ ¼§èš§±ÚHÀ Q€H>ÈtÐ4B 0:2p A‡Û„>€ÊHGêˆvœ+øz6, &ÀÃL­Bê#,~¢¼iOÇ‚þÁ¸|Žø(€ UÅ`X#>Ÿ:¼¹Gž_ÔÁ×a‚m3µg'9®†ëø+@XLˆV#N Z®}+ j˜“©Äg`6º¨È@ŒJ4MÈŽ'ÊLýH6-07TLŒ¾ñæp[ añÀ¨Oa‚ð‰Üo´gÁéàø@†q€O° z>ÇËt‚¦‡¹×Á>†bHqš¦ZxI° Ñ'û,ç É€HNÉ'¬ nà€aˆ²ê»{ JÒ òŸÈMF¢"W¢ ŒL` Ô—'hÂ4ŒqÈÒ 1üÊtX*+n›NI9u¨âb~LmµÒ¨uúšR`"7AۆѢ&É·D€ŽÄÁ”.}¯ * Â0Bö¹6P® ØZ›Nˆ_> ¥I kbÂqLéøu&Ǧ.ÏO ¨H«ø\ªàÒäÅLc‹¡hH$ÄØå®0E‘,8(Ã2̸l>Ì;”Ð;ª4Ë2’ö=Çñ{cÀtaðLÈ!Ðsyv„qÖ©³vâ‰É:#‹hØ!û‰RŸ!îQó28X€ó/eô¿¨5ø}WàïÄ}gârR@6 a|—ƒò=Gr¨ ŒAl*Òó@ 4‚B9pˆx82¡îC¹~â<@õFà` ˜Ð¸îjhT.ˆÀ zŠ$ϪŠ?¹Ê€‚€ <“ð$à £?) (Dr˜èÉY $ª!:¢œ¨%D°¡2èxNÈqNК§&lˆ‰J˜²ø—·"§Éù*˜d1Ç؆íÈÙG).c(Ò#0H¡G'$âq:©¦K&\ç7„ê^‘Ãç!¼i nЛhzP§¬¶DD~L‰¼Eb,܉ƒÍÓzB‰DïóúÏ÷jG¦ @›†ÌšÏâHùŠ2q6ðî~MÒF¥á:£ÆÞ‘Aú§Ê;œô}Pé±?¬C–2ÔŠ– y= ­töqÉ}'=5uÒˆM: 8Ž#¬¢ ႆ€?!šh µ‡ùp#MѰ5P°òCÀŒš`Or“,àDJ®¹ZcUQ¸ñ@!9çËS¢Ð L óG¸÷>Îðˆ 2^ô,༠€ ŠÓ½¨IЖ”$M:È©G›Tt§Ò‡ˆåxm QØ9TÐ |³,YÈÒD#ùTu48Æô+<'(Ì'Ñú>P¸íl2® (D?Ð,€#Ê> Pü<ä¸~4^ÓñšLœĘtAŽ&Г<‚W˜ƒ¼r6ÆÜ?±XÇñ8Ô*<À  ÄÐE´„ÌGëX+i€bö=TÁCÅœ~€À`@€ëùé@¡ŽåœÀÉʃØí¼5‰°þÀ‰º?);°}á5¥’eh°”ü~× ù*`,  Ø B#è ƒ¢¨ ÁŠ EÀÿƒç0J ¥œó”Kü˜™Á#ðˆœR_ 9Ù…`y´!€þ3 ð @¡ù†* ß»g8ÊÓ‹I$2¹²^MÓXû!ƒµ»€Ô5 p.ƒì2qü=G¡€;Å Pžbˆ˜Œ8ŤÁ¾9Š=À8¤ˆð^LjÌcH·üÒ,H,\` ¨ö>¸ü(hâúL•ÄQЪB†DÝ ™'Cè’³g:…UJWÕc8`j±°0À ˆ=mªÃ9¹ €sø<Æãë€å%BµTa]ã…yÜü`PÀöŠ¡ââí´e•"ˆ½eœ™”ü_ó¿à|ÀI‡]ê LæÁŬX„A\£©&ìÔ¯ªºÝÙ%#mÔ¾DÇ1çˆïÓ4Ï=IDäë­ÎOIêAQáw6€¯N5ÖïN2 £Ðu6áÙ²RKLx£¥TeàXâ[ T µ’;‚mÔ ‚P^PnØM‡nèŽI*h¬{AÎ(ÓÜÃÔo°JZXI€,¯) SãÄoVaº2Ô2ËCÅgW•ÇäÀA »²Î9G€`çP=@ˆW)¼ˆ \·´t<€$ws*÷ÓËaHd uSȆP2M, ¤Ý *$Žd2"§ÇÈì*c¬x TƒÕ(c®CUœ žW…¥L~iç¦ Ÿà…]!!š/—Ê^ÒÉTò€wǘwpy=1PHþ1“€Èã¿;¾€Pzà€‘«í—"JH’@<éA£„;0€)“¥Xü‡“È`î b›j]b†¹¸Ž>ˆŠ&›i' ªbp”s’Áá9)Ó©Ñò»æ-:›AšpÂR‘©»i&úÓ*D%‰Šw(Ü Âš[r…¨Å'QÓ>qÕ(X–*0‘' !3:š' ›ÁÚ[©Rp­e¨³ç“–AºtÁ‚$B,;)ˆ˜©2w™´?Ãp§|D$)“Œ?CE)p”¼@©ÌAü;šÔ‰ŒD “D1Ñ´&&â—»¢uÂ8ÂúÕCu‡˜v(gõ®ig Œ°‰¸€Ð<`h ¿‡lp@ìx@ë`‘˜­€ñÿ‡Òæ—"‡l [þ°KÆ(’@€¨¸$ 0mˆ¹€ˆ ˆ‹ˆÐAYU‹FˆjCé•© ¦§2n Ð|%˜|œHzŠ˜¶-°¾q A>­y šØ@qŠ˜{ªCK‡Áu½€j¹”é3}‚6[¾$9€ b¶š!7 ˜} dŒ~p~€PËY¨@€âü. †‡Ð½€X ÓbŠ˜w‡Jý€Z†Š°‚‡¸xœøˆ€9$&¤‰€éˆiH’.˜0pŸˆ{;܇pìð˜h`!𻉰r@oR€X{µp›¥˜ ØÇÒ––0™4“ ‚+¦ˆTÅñ,ADPs@Ä’ëý€AF p€Éî8Ó øåH˜˜ &yʉ)˜’Ð i•ˆ(|”ú4ˆÀ)üvˆiçÚ3‰´„ÚDLž•At[êG FbÅ<€‚ŽÐ6¡ˆ øÀ¹ø‡™Xðˆ‡À½‡Ñí”¨Ø "3!X}àe˜ <`€Ú ¢)šˆJ`.ìWˆhw¸zãK ³€8  ¸ëé ²ð¸|%ÁۈТ")R‚´52 œ4hu»0y†ª!9·JÚ ð ”@NP‡Èì(jx†±’I‡z€hùÞ¸ °vϘ q pȰÑD8èiÛ$0t‡ W€°è~; (€±ÿ’¨‚È#£“ ‰€¡)¹:±BÐéMpšCáÕ» ¯6Û¢¢aÔˆ³º‰sŸH¡—¬©¤! tT}–¢6é0(±ñ7Xa$áHxˆl†P]›”\€ €@Š *•Ÿ¼ˆ„ÃRFŠ|”Ðr+ áØ¡@i4°€Á$Sf§pºH”Ú‹øi~øÄ€@Žù7‹€®‚D;5O‹<Pz‘grÀÐ ’ü5XváÞ‹8ý(}‡¨í€ NˆR–ÒÒ©$4*^'²u¥ŠpÐŒxyQT0p†ð¬0ìÀf[ÕÈ€I°µ—>€’Ü {Ïù ¿€ˆÉ3á (r‡PlÉÄÞŠ"Ì "çðÕ°¬8˜æ1ðW u‡Xí†èe €H½ŽÓO¯P`‹ v®J €Ú 88¢€u›¸ • ©ÌD¢"‚E'Ô &#èÁzqøܡ½µ‰!*hGíC§ƒäªT1ÄT.&Ô/“’i¢D :[Ì,©1ªm½'zÑ6´-¢@‹ª ‚Ü*‹Ä\-úp©ä"'ã’Ûͼ[Â`Ô2q)Ã[ÚmÛõÁ ¬P9ÜBÇ퀉’~C:ˆB “&%Á­ÊWòÃj~&!ļµµ¥ÚZC‚vDRw&ƒåXŸ)´!ªeÄÜZvÑ!Ê {ˆÓ!ˆ(yxq:´þ :Ç+ ƒÍ…%®‰TI”ðå.€ˆEÈxºˆ(€òT€P@Èð|†ãq‡èx¯Û 8KzÍJ>‘ºñ›s½°èŽP€|¡‡í‚ ´ž1&JÙ6¯Ð¡¯øüJ;È{ódb¡¶¤˜~-+ÀXy€9¸€H š€‡ðûO€0d$áÝŒyH‰¡KÁÈB™u‰¡ÞˆÐÁˆ1‘x‚‡rO‹h˜JFIh‡¡%ˆh !€îŒÑ‡Ém;, €–A ŠÐŒ©ÖÇÓ¹ˆØ­‚€¯H¡€ š*ùel– ߈}€8ò•å 6¡ò%°æâ‡À€‰‰P|kè„z£DÍÛ<`u€ AM‘2“;å´1a(Á:‡©T<ùK >ˆ$Å6¦w^tV §ØŒ[jðˆ¹Ü‰Q-ý<‡Øv»0s†`cŠ P ·PŠ  €x9yFR-x»;8y Ø€‰F!šhméVbèÈ«‰ póaO ш(É€—ÈºŠ ˆj¸BCž%P 3ÒÁó¥2¸å ŒÊ§™’o\¢‰#i¹0ÓM3”mE½}C1­µÔÓ+š¢#¢b| — ¹<&܃½îÐsXy€“À˜šY€ˆ@ùt’ ÓȇËO†x`ÂU¡A#<‡ÐˆP¢PpXXåtÝߘ •ÈA&Q†1‡(¿ŽÞPÔú7´ø¢ëx†€`ü€ U°V†PuK8É0 OáPûpŒx’°—¹»¾ù‡¸Œh€’:Îê4Û'ÙLkèy‘»¥Æ«O‡°p˜èÀŸÿ¡ h8f¡ˆy ø›ŠÐäX°ÈÁ d!$‡ÛOжáãO”Ê×4胭ö’Q=<ÍÑ!S‡s•àÃ÷À(pf¹zg•¸ Cu€2 s¡MI(¸dY¸–ÉÊ (…mœô)‰bQêmææQœÈ|‰S[D´A1“1 ™qy¶˜š$§ù;™«ù¶ÔØfmÜ¢4‘\Ž“˜‚Íãž­ûâqÑfH³“ÈË~ ¦ûf(qPaø—&Ù XÇë“`ÕÜ­ùÛ—Y™Õ? þÌWÔ‰|ÈÀŠ>+ˆÐ{èÀjøN0m†S À€; ð(0†ƒ íð¿@°8L€€ ãÁ¹z¼G›ž ![ÕäîŽBò§ûîTÆï0íôÿàÑìö‚àûéèò °p §  40 ¦?¨är~Ã"H€ÒÐoðòAöð ^g/ëU¾Ù}¹Úp›­n¦®¸ vRÉ@ÅF3WÛe±ùg¿çs·ÐEŽ'b,®³<ãl´€€XxÀp°&ìü¾„BÛ``Rö}á-`;m©#z»“( __¡*ëõ¹7Ò7½1ûH,‘™  @†ãh%mÆ@Ú€øIü|&͸»èªF€X. ¤`:R¬@çĘF‘ zº€[f „€‚H€ º¬ib³³±¡þÐ4Kôl²@¨‚òŽJyÈkš éät €R‡b: ®§1¬o€0 ›‡Éê!P'QÒ†Á˜ëØifH!Ø„¨X æ€\7`”Z-.™¬_-:f ŒÃHm™­‘¶b`8/§à~ TÐWNGÚ€BÀØsL`(œ`ª´ ÏÈ!ø ” ÒÆGîR±ÇêbÎÏÇ "ÎÎ- aüƬK ³‡ë”гLªü±ÚÊÉ]Y(ÂÎÆ²ì½¨³×±ºÈ~¬õÕ«3«çqØ‹` ±ÜQËA_Ú‹`ÎX•ÕÒ¶F•í¡±Ëdb³—5ù`åî¿_xd“kÞˉ^Ú'ó9Æ¸Ê ±Ÿ×-aß‘¥ç„)–þIvÆ–%Á}\xÓo`™ä9¢Õ€^u‰ÇY³;nc¹ë—hçØ ®³Þ7¹tfqÆ›´XÚ²XYå§'Y%£æº㣲öÞ%‹Þ5µëøuÚ®€éÀ EÞ‡0*±â¬q™"ƒ À)9„ êÛiªjªà:l ¡]: ‚î¯.ó@'&Q‚bÐv7`ÿ÷¯ €¼É€u']m.¸¾°‹Éö{Ó耥ƒ,L}Ÿ¹æ^Ñ]{>i©°ö–{Æžè˜x$ISÆw:@Þv!ç±ä¾žGÞ28 ÍÓÕÄ'"$ŽæJv+µ€9ô9ƺ>q 4¤ªY€ì0w‘ð=‰€ä”=©&£Ô‡€@$ˆ` ppp JGúVèè–ÚGÈ!)#àÒ5Šaw=à-Ê€0X ÷¤Œ—ÔP±-Ý.òl?€< €„aê’ðãD0ú?TÁ +  R™"ú âP#ø´€8ÐlÀQ¾à$ÝÁìDÇp„„”J M˜#I •1ðºÇòæ'&<Ƥb]Ëêñ#fǰ6ˆ_ÉÈ.…2N,Í#Kª÷„£þJS(¶^:ÂVŒpì°âÄPÉ—0‹0Г‡öµ‹I@Fò-50ÇöF%ji^ä{—ß)÷W&Ž˜EÉ X±~_QqBr¹Âà“„äœ³Åù3˜$É …è¼ÒBàϯ¬ qì;ñL£ÄŠBž@{•Ãì|™stxCDT”ŽáÅc±O£Pb‘ôyAhO n¼tò¦¨ % u·aä:`XðçØ€ƒÀ)üàÈ&¥P!XÙ$0ÇÐ> ÁÑd±ô|ƒÊ))=ñÕ¯‘˜Jc@ Ê[“Í™š_¦¢ìil•“d·Q¡s›†Qk,fJg*êå[åô¸€>IñïP Ú‘GPÚq€$aÚ8]¨Ò}Îqþ? {|7IÝÄÒù@ø#6pEŒŽšÅ°¤l £Ä]‹+·E \9!ô é#dˆ?ÒÈA*‰|“  è÷sôWÒ8?§í(?‰(®¹s€Å©žDõâ€Ú=Íô"*`-ZÜa´~@(*`tERP MNX̤1%ìaê»i4ežâ–…ÀXÇ é$Ð$r«jgïê`g‹ñ~.ªr M1ÂI†ØÂ÷p¤RÜM€@ B€|„BH8 ¤p h¶TÌ ßçØiª*à²ó pTÝ"eH£¼pS50P°+ƒ ŒŠ€R&ãRÞ’HåD`•ÐBˆ¸ö… ƒZÑ$á¢xëqÕz®ò²‰h/)^¨†´#O´æO-VbhƒHªà ]MåÎÍ—B¿kµ1Ÿ¯…øÇ3Qd£Š"²I½1Ø:¾e¥‘n.–ÈÕ3³6Fz¢†‹ d»ÎWmXÑI¥ØÄ–pf1¦<¶F^™9 `¹º¯#œ©§oW«æòf ¤;WG/xš;½¦Ö«ÌÑù»N³7ŽÖôb5Ó¬§Wh&¡¯ÙÎ³Õ ‰¡/zÌösÍg/ Q®DÆ`È€ xl Š ÚdˆzŽè†€Á Ô¤1Ðì€ - X¹PF ‰»n$÷–AÜ< HøEb ¡‚PP ƒ"†‰°Þ®Èq Æì=‡ì]ð¬}4œ0§ð€2ê Ñ¥$o(´µŸX¾gÔÌùÍê˜>Zøò¤älmsî;'èȘ¦—Ѧ2Æì+ %Ö>²[ècYìmÀK¬¤ ó„ÐOÿŽ„Prt‘ü7ü,& €àåI]#÷nàH8ü‘ô€r¦’œ¨ð§”vQtYR„Pä|Ô²8œªÎ1Ätˆ’x@:`JÅw§ ¬É°ÿc¨Œwãf $>.£¼f ƒÞ<ݨ*bD› Óg0§º4À Ùü@º|”mÀø>6àc'žò6>@º 2FèÒ˜Aðd‰ìœ2g¼ÐͶîúï0Œ,È“œ^±K‘j/²ekJCpcA”„äzBêÇeÌáåYå̪‚tªj°•¯xaϼЦ¾bÉ®4&:' Y"þ/!ì2…–0)Â0%´«bÒSÒ–)[HÚ[)p3F0Ö©¤ûƨ¯ã"0C4©/xû–ôú„­ÈøÂBrÁæ&þ©è¡â 8BˆN‰ áúëÀxœO€dÆîP' *È8Ÿ  âÐçü">.j~&EG,P§`B2+@,¤äì$#Ž:9¾? ,kó/"Y)l-©ºXÊŠ^Æ_£.1 Âc¦0ÊÄ„£B—F-.X] ¬–©Ñckï¶4J’$AÜÉân> Œ¶Là"DЧÀJ(€G*¬Cê€'")ìÄ`v¢ï”MÖ²a.F€ 'À#dH 8Àn € 2iø>áÆÈaôÇÎ`&p`0äR¡ÎbÐ C"+ B$¢Lg¨¢&T„!Ô#à:àJ‰gÚ|à<#l|0À@6Àƒä|BžÈÞÀ(piúÏMFѦhÂÚmÌ3§Š(ð'!â(†¼é JŒžBÃ|Áè<®Ê`H„Ræàa¶ªa°‡ @"eî"` }‚ Ç 0€2éúн¤,€Ìúh2ùÂr‘N;gHš bŠw…AlÖÈC®$Kct`:tŒr7ÁÊËÚ 2&hØ,ˆŠ7@& &¼Ãæ-M$¥š×GfˆËf'^hIÕ#lm1ÂÇ4£8y0LfÌ·2çŽ_Eêj ÐspÙFÂÒG’j)¥<¦²Ñì²Óñ<ÖG•4s¾d¦žÙ®¬@yí‹3M6ÕkÈbM†Ó¦ 6¦m mžä¶Á~‡©è %!Òiè ,ÝBE|/ ­£núà6@áîŠÞƒ|^*É@êîvA¾Jf`I ë:Éá~A°.ÇÊ$c(âÌŠ}`$AªØ%*j7@"U`³¢µ@jÈ]E†æÇ˜Fú¬ Ð&ÒÍí$3…D,Ìã&Þ{ÁÚ"bÀSø!À¡þKaòƒV݃fGê’&À€A„áà¢>@/H8DZ@.>Aãéê:@¤8+ÚîöJµ GÔ޶1Ä‹‚£$dLD°Î¨ ¥AÊ9áàêRçd/bž‹äL¥"¬›0§ü$¨'"6@h G,B–ÁòŸ ä¶®¢É)s-Bzè¶áòž‚2/%Þö°`q`-Âê@/$,%1Ò+@.¤¾!È$ÁøUCÞ€^P¢fÁClÍ©.ÎL#…†4)4›©`¤Ð“Œ¼Ëi¢œmc•„hBÎC”x¢ru j*È,õ¦Ó†O£B5Bã©0'¬äSö%)"-®ÏE¶-` Θ¥”Ö"º'"&ji&2*Î-Dh±>ýÃF<$iZlö7¸3Ö,O¼(E‚j˜å0¶œrÒl.Á¶>Â#J*¿ò<¡à HàNN@B.íèœÁ,(¡ÎqŠ€ï€6#-Ç^„‹.KU)…0€8tâôr;ÊÈx:à6Äî"´`:±@µiΆc•$`è„Õ2ö:—gJ–2/Öw ö!–~jÑ.»¬²bÂò.&d1êÈ,¶‚^ïÖZ5ö2€Gáòja€Pö1fCø¤¦(6è,ÕFL#®ÍÔ솩"´:$(à.±@P`¢2âÒÁ^‚7$"d(ëlAØ)ç µ4ºEK.a¦6Aú‚>€.q b‰B£|áØ|ìØ&Å„'…L ` ¬øSõ"ììø,²`T(…zàߊرc| $µ1ø&ÀÒÎöE²:,­2æ³ã3s™u fY!Æbó$MrNø¬BÈ¡šMÁÆDÎo2( C ±Ìv@*¢º Î’.*ÂKaîÜÀn@=à p`NàajD""„æQº`6°ózáÜIˆE¨$%4§¾$N£GçTaîK`„L*-KåÆ9LÙ<Ø]bÆ¢cÆ„e- FŒ¶2Æ«`&4V:ó@8šÓ-}9®Z“§3fšÙæžËf$­§&„ÿÍ)͇6“ÎʳÂy >dEá;³á4%å4I¼’Í6¶jÖã"ÌG¤Ú…˘ù3†Yn¼fÐ`YÏ'”©“ªf“o5æ¼í!1ÒcL£;%ø_Ë•&5gœYS”Sß=Í„Î~Ø %69’dWXߤrËmj1ØÊ²k ¼©ú­r!V´ê$¢TÂÒ!í °æB r¨R/²¨vB|vBîþáêS °`0B¾‘àårÁÒ|ñj!`íÔt, )õÎ'!ð`?’æ&`äLYbmbÒ 0@âš( P›¥“hÂ!:s6ùº4sžZ ti"Î}"€áÌ'!Ú¢Ò¤¤Žbò¬ÝbxŽ$p–-gzA¤`ˆìrÁÚô€6‚ íâzz"zW¦Cò6ƒÆƒlwðMØ€"0.¨N!` ÃmkzjRøîˆ<"zãºâ`á ¢ìb>àâ˜Epì&ÅTr¬@7AèAx!’~rÀE uÖàHS€ Ä(9 úŽÉè(§ÎA¦ƒÞh†;" ¢lŒ"Ñ^têÓ‰².¸º*e\+@°®BáÄI  ~$bªB0Ø#2€Ã)vKÌ‘q0G„Ô8 B3P*û1 Ñ“FÊö:&Ä`L¼”i¸œ5d“c.S,'g77P’9Ú4#>R£ 7EF\\.Ìè“,ÃÀÅ|à#9 ¢6üBìÓå––f_qpPM¾ô"ü2eÅvèКÃ4,WW0èVh)bFW¬ÂÑ{ž/âûMâ"-èvX<¬Xž i`:ãÐ8TÖÎa›-"Rv[”…` û$+Q¿¬ q.J/*)ê{Xµ GøM‰îú} >( D(€2 YÊœo„A‚äbÐÑÂÜ0)ZXJÉa§0,Ñ ý)a›ù´-’OÁ9n;#F1†Fé­8Ã*üÃ)Ðç¼×’Ç=ÈC¥B„Mƒt#†\€´ƒd!tÀ€W A(¡œZéèà` Ú¼œS˜F !ú>tƒ’7AÖ´GÐH .!aãN00€&g+ #žaþ<¼–ß!öÏ¡àGêvB<¡Ì¿äªBöþEB„>áâvV |àÏ  ¢`º=à& àcø I]aÔˆ†.b)gY5ûWY[—³E7BÙkb&é¢9G¾ˆg¢"a¸Av- ZÌ@>>GZÈaÐ(?à2‚áäˆd/ @ z"–¢ 8¡l;Ta´¦`TÛÂçná MSDÄðpÃÔ¨WOЃf[B»WÁÄI¸ÑÖ~™ “Yò]9$y\xã,[êhvž-[8¤rÌ9'KY×’F’-†)ãÌàÓª™ïÓM—ÿ–3”1Ù‹•™Ïª-¥<÷q𢩓ñ<ö1Ù£—†¶cMk59ã9‘’g’ecŸs½J³žÿdmíç˜[$bЬÖÍ3ÐZ`Ô¹fìÚk¿Š-›@,¦‚xAdLà$ÞDÑ®g×AÃfG!âKaÞU)}„" Ѐòà—Ð(n‡ äñ‰€Ÿ¯pÃ!@ ‚=^`8~£Ï‡¤-úþÃàD,6šn0Èt EáPu®õ9ÐÌh `(ÍãvÝt`–Y+ ð Ói¶Ze ú»k›¿m/§Ô´®»7GÅìéoÞ/§åj¹.|¾ÇS”9A´¬@0 nÿ™f€ÕÇàtýwЀ®¦˜ áPæûyWžŽý€(/*ƒë¯÷Øôö©Yrw[šå£µ(Ï[Š´öp€ÙH&'—>²÷¶À&~Æ@‡øü”Á±Àö{^÷@¬hx‡Ë4}IÒn½§#VŸø#H:ü~Ÿ‹¢jÅŸçó+aü à( A0H0:æ3V{6êðD $axvɨJáö«€+`ö¬²[ ­‰jØ}® )þ–Ÿ’ °.‰¸;ºjº-°ââ´¦éjÄ|.lÔœ°­’²ØÎ¾‹Œ¨ìLÐÜž·³‹¤ƒ*¬ð¢[/ÐÚ»>®Gû;"³è ~¦ðòø³­«a3&²1hÚé(OPòÔ¸Ë®ÂÆC ‚ÉËsZ6–¯ ¤9$LÐ ®£Ô´r{êrßs°¿ÏAöv¨Gšc+Ç‚4ƒäªÇ‰¶j€Aü+éiòw`ï_¥@Rt€êT2´Š® *À(“‡‹n-¸@+’º|§[Ò{ž@*£gâØ©ð¶`ØN3@P$âWM€Å€4#`¾Ëî ‚/Òë?-8䄳Wk‰jQÔD­S.Œä«,iµS>Ð4b¼ çÉÞs€rW¶aÈÚWÈH¿§ýŽ§Ô‚ ϹÜyß')€[ÈB€P|%€·‚ RØof:àiòx¾¢|‚*QÚ‚€¨8¤`š”yê‘ÚnÛP«À‚WRYdKÏ8´âŸÀ[KoeF%èªÍU VGÑ<•†3ÌÌM.©x·–(§ž²_VÅÀ¸²T¶¢Óú^,CõM–ôˆÇcfˆql¹%èµS4FŠÉr;§ã3b¼€‹OQšøÛ\ê~zoFFÅè‹#Tš‹%ºFIyÉRäˆfª,¶³I £ÌÑ °H5Sùb‹1FF©¸ß%âa]+òè¶æ8­¤‰d,S_–öBÈ@ [{Þ[JY?T\¡,Ò¶gÆí.ä"zÅÆ0âÞMR«*-O>Q­’¤ØÓ_%t ¡«˜¡ XàÔº9A‡ ¤‚(Znkd~OàðA7à ÞŽd GˈŸqà: 2hD”À0RlÀˆycÐw1Ô9`õwCô}‘0Üà‹$k ÇFÀ:MìCq²‰?±Ù'=H•é¶YÑÎ:Žú$´ 2¸¨ (è+£¸t‘¢ À£àøA õX±tc¶®QÀ6 ¸ÿ#@{Žã°?ÐàÙà^z@!-JI ÖCü©Œ„Ë+£Èq ¢µÀ tÃØs4!ù6@% }›£]²í=¬äÀ$O¢"6ƒTXãnÀè7 €2ãîÀq#nAÈý@0ù"jÝ!3„“)‹³' .+žË’€§L Á8%~À‰ !¨u ô% $b®7Ç$D’J™‚BR…yz¤âîÊ€!6M’Q=3Dâ§e̺—20|$J_4€,ï`½¥2n°”å…jJžÔÌ•“»ÑU8V²Z§Õ=Jf±Ø»–•ƒL \›*yq‚“fi™T¨Ò6ŸT9f„°–œ5\f§*.Šñ*±²7 -ƒ”j P9F¨Ì#ôüúÑÔŽ€ä/ ”Ù€AêbÇÃ`€uÜ>Σn<` ›ÑüAëx7pzQ’º”ãœIlvØ>¬u§w¢ºD¡øBÜÉ-yü†æöÕªàX£à$Q¯¨ÿ)I]á4Ü\ñœÁC©›p*0š—ÃVûHÍOËa\%©†?¨Œ)!•5„^£è{›qð;ÇI]Eí€l,ñå6@–lZ¨€pÇ@Þ5c¤b RFC‹kcÌw3° yÍ`4£óa€‘üSa½` î1úWv“.MÅ¥Üð9†rÀrÕQüdhÞYàT0‘åB;AdPAw Ø5`,’aæ;*à$ v“®º1Z8D"«°¹Gö2dg1Ì:+ÀþkçK!áoO£€œ-ç#Ìä”ì`ºÆé$[oÙuŒêoØ09ÇAR´{ o ñd}+õ€vÕ`ŠŽÁlá $­‘è€@ˆ(Æhº±ÆPšZü¥í¼v6ˆ¬k™­š'ÔF“ã€Ô"NÁð3Ŭ€VdGiRîVа&¨Î-¨tU͈$@  ØÄøB"Ô[âDVвÅ/½Y‡+ v®S²)+ã‰QŽ%TN%ß&È©C9ç$Òeï>hôï}."ÓÕø’žo}/zy¼ŽQú£Çé³®LäÚ×XæEKrÝ/ª[%˜qc¤_bÉ*te—‘ú¤Þ›#åtЋwòK£’D¥JK"²S>ƒí"z&’ša½›ß¿ð±%ƒ¤[¤¾^>â7¿›#l½úF½Òa 40"k¿).%=¤’3&º*¤Ì#B@‹ˆ|¨›µúÂ:Xߊè€A” n˜¼ˆe–x„ˆ˜{»Hÿ`Û€;ØÅ‘ð¶øº-AÎh x¸éµ€ñ‡ p§hxP“È{AP˜¼4à›ˆóa0°¶PพXs¼HuЇŒX‘;Ô›PyˆÐ¡9¬€²Å€§ ŠQ°‹¥R>>kõ r–¨áiJPt £;¨d% Q-‡pu ¸rø¡XŠà€Yîø@«Có5±Š}1ȸx«À €`×€Hð€8‡À~‰¢` Q\ €~+Á_8‘€tD8XxÑlðnû#Ÿ’p³'Xxjõ¦Y|ŽR®—Ž v°ú°®€2ô!ÓL0z‡ ã–Èö‡Ð¼8 z‡¸pØz ø…‡Ñ-ÈP2 ±Šá ‹ñ]8 ûÐÞ`‡HšØ{ ü/†Ó΀ ÒH‚AÎÉ6¿#Óóq ½’0 9š!:1U$±7€¯ ;v•yL’i=#;ðP~*Óô‹`¼ á]µÈ¼1 “´3ž«N p·¨X¿Y*$ùRµP˜þ*Ê]¢)Ž™ )QDÚ=%4“™”Ì£Jl4‹TIú Ðpmˆ¹»,‡pq€Œ8ø¸²´Hw—à:ÿÀa èu†xÍDè¡d€Ø'pâ@à@~›x€0ƒ‡Hqޏ‡ØáÈŇhpŽ»Õ.à|™K €H¶( ʘqÊ—(ŽðØê*¾<êµ+ž¢¢Ò\‰¸•ä’sR“ +¤ñŠÑKd¬295%Câ/Œ?Œ#_ }‰¸Aœ‹¨†øk€ÐÀÍ‘ÈAÑH͘•)ŠÓ€©‡Hw›x‡¸È`‘唃€8ÅTf Ø~€Qr‡˜oÇЀèû€33Âú¸‹Py ~àÝ qŽ-IäKŸ‡`o† ø8¸H0©OÉr…”0¼hxyž{‹` I¼8¡Þ+,€yBøy·J 1tˆyŽ£ZJª*¿dÏ ¦"‚^/ã& hpðpZXÍr߀8—(㳇 o €“ÌXù‡Àá€;°ÛãÂ(§H˜Ê XQûC¨—ðá€Ûg ĺˆ`…Èö´ÈSŸ€8~‰ÐzؼH `Chx¼™µ’y‡›,€À x ïò™!¸;0Fy7¤QìXÆ¥/ÀÂ)šs¤K”sò*[ï*kôÉà´€+âOI[$O¿Ål¾]&5f"©[ úVÔ •v&ÑEžÃÿ%íy±ÂoVùWûòÏ6ÖÊ3?ãžÐ· ·´ÚkØ*/>J-ÏB8¤ÑF¾ Û¦Ó¨DÊ[¿j:óê±BO¦Q6•"M$¤1%uÒd?²FÙE3‹KÚ£<”ms¢m™VÚ/"jhÁ5™ÁMœÙ‚>¿ë¢¿…yN˜®‡8qˆXg|Œ~`+!´†.P›­–†c«À}+„/©8§ÂéJ“Dä òÝ€ Hƒ¬É·€%!²ÊÒÖøn7¨dý‘º– ’^‡“œ–…»` 0yø§†øê(i0 «­Ó ¶h <ËLH}‡¸…€€ ¯Bƒ‹À Ìd%éHZÎ1X…vXä”j*‡…Õ讇ÔN¡"q‰hw‡qœˆ€€¨ù@‹d2„h‡ø¼IÄ0‘šOÈ»™¢ýˆXœµ±)“¼ÉB à{6(Œ˜˜Š{,ÄÐzš¹N8‡È¡¸sI¼ÌΖH~ÁÔÆÐ{†ò ÍÐЧ@y—(|]`µMшˆ8p®¨Xú‚7›”ÁFxšŒƒ ƒxÊiä2Bx9½´È¥XmHð Ñèl6Áy’ ø, è \ÐŒ#ü/±@“ >Šü­?©¡‘@Š5™G’ ÌÖ±D 9$K1W¦É5küŠòµ¸…±j#â,œAš#´ä˜ Jù!$Œ­Uº‹`Å”´ 8£±âx›’;W Ε³=cZæž‘!z[Jkâx²˜\‹À¼á ’£€M­›PjRßPF (†ºÈ€ž]&˜pzЈ«€@  (n…ù«ÇRا8­P î‡lBˆ!|GèJ^‡j« :h ¯@}€!î=xN8ˆz͈|ýœàÍ’ ²2s«ø³ÈÈö%€¸˜ N’ÚÁ“áz’\óJþ>£‰5“t~Æx–$Žu½ƒP¯à¯‹»ñÈ`®ˆ›†0\…iã«Î€4ƒ0ÀÝøà å`Ðø °z¹ÎÛ™€(˜so ¸ 8‰Áå‡8v p¢(ɨ‘ø¸y­ñã߇XuRÈP—zMpׇppÇÒ«¯@ú   JŒÐ“cZÂ"®IF0‡‡4Џ-ÊŠpÒ(ø À—Ü<‡ ÈàìV VÏSZÄľ>D’œ ¥%½ ìņ@ŠZ\ü p H‰UP€_‹•&` Vä†áC‹¤Œ ¸}+h§†HbLI ©À½ˆ¥Œ0µ¶¸žà €þ€ |É2̦=3̇¸|’ ŒXžs©8Ù*I˜ú €˜ Š4‹ éŽ4ãZ“ièûÄÌ õh¦¢/*Cç¢ÙìW"W×ñ@x´ÖŠ£x°W‚'¥­8¢ÛïØ9F: ´ÊÖŠ4”ÓònJG×µ˜ }w>¦ó¿êµDÁ[? iÙãï?¶õ"Ô±>¬½Õ‡@É6Ù†ý¾Ä%òTXËõ#4×ã÷Wú¤¾tÙäV½¡àËëA#¾œ ˜ä¤À¸&3ûOeœ>%ŽñóÖ¤ø£óÙ”jo‹m}+H¯/xnŠpY…AaÖƒ‚°1Teä´@›–¸¡ømÌ`­žàá­€¸ à ñÎäÐWÇ ˆƒ8˜™ €w‡XÊTð§ÉЇJ|‰VUT›€eC€tæ*¹ •À–È'±Îp∥éÝ™²”Å›(ƒ‡À{“@ ™h ‹ðk€§)¨¶ø Ð{ʹ,0ÓÙey'"ü Â]pÈ‘ƒ, Äå‹`z‡ˆ¼iåÝÑΨǨ0…‚AÞáç ä&w %@’áö(u  ‰H¨‘^ÀàIhÑO8{˜y†˜^ðpéd⬱È1oÒzH‹‹ 6‰"}ßH®àÈhx¼cˆU˜¯Q­ô(쳟àX£PÉr‡ÐtPwÍS7„­˜ â^!çÝ+®`q(ø¹’ 2ñ½† e­ùõ ñ`€„`‹P¼ÉŒç0"*d‹]½f‰@•Ù+µ± ’F5"Ì”ß J ;®y;ÊÑ!=€­¼«ÎóßW ’ù#¼Nⵓñ-ÛZ>Ç0”'øP±*«Y¦È~™TÁã» 5É7JM}5ë§ z¦[Y¥± Öœ÷˜ÈβX­c`­ £À{S°— À €è«"ˆ{ pÛ%¬Øƒ€>†èd†8µ!ñ²a~áÎ`¼X Hïxpœ€¹'¬Ä†È¡R˜×Ј¹2`àd³+Õð|à.»>èúfÌÂW£[JU“\¢Þm5ªþy®( Åj•LŒÆm0%‹*(®I" æµë*21¶"9• A·‡mP£a‡Ðuޏ}+5ýlŒ… t˜pŽ 0Ï ‡òÚhz¢÷ˆüƒ€°°˜'’pPÝi5ah¤ðu;À×›Ð!€g³ÀÚc/Àç3 „`ñ8ðíwGÝ®  “½Ð0xd„Rßo0‚C³ +æ–ñ|@'¸òäg °àF4#n˜ð$úƒB 81x~€0HªY¯ø,ÁaÀxÌf?/ëõ²Ôïd/€ñh¸ h€€°l\4Á  ñøý³1ïì ùûwº] Y˜Ÿ·°Æ±øÔ‡°U Ä¯8Û2ùÐê ›Ââ@)ï]~¿+ p…ìôAÃ}Pv78ÏwcžòÁð’ð‚ò}·8ªÇzº€kø$ê[|0çëp³0¬S ²(ßÌ[¬Èý €,”:ÃÄÌ”Y2 4IÆÑNÌŸ2Oó 3 L³,Ñ4GR»ÑìaüÂÍ3*DZåP|}0É´äQAЬ$ÍVÒóü‘JϤç;€9„uŽf€h`«ˆB`XçºL¯æÉ¤æùªç ¶™€ê 4 „ 4 À¨.#g»ph&°}ŠÑç€ “Ú àHÊSìo¸‡c~€ ]Òo ˜“ž*ƒvºeèš^€\B³oiØz, @Ç€`b {©P}¬!RXÇÓ# àø£ f‰Š®‚ ‘êÁ` ƒw£uEÖ °µ¬{è,9öÝàGºþuž ÁÄp®‡qÌxƈñêyf  úÚÐàŠ@š'ü¡/ÈÚNpšÿ.‡áþ¡èûc"Ÿ`"$‰Šô ËKBÍ›Žög–Èyí]gúŽ}€`‚µ'Ùø•N{ÛlÇŸçîj~€H~ÜGÔ–¿*€ «À…¶ƒm„¡íxyjÑôuœi”U!çÂEL¨òÒþ~Ÿ;Fz½®Ãq¢J•ăËI˜ißGbR™‚j¸ Ix&¥`ohZ«èö¿±|ÓcZ€r”pÆÆŠ¤W}Õ®Û *†áæ€#hR*S O¹$¤žÂ“+ÏÙ:£ƒ$Ù_©í/ê4~"'ä— ÿ‚ÈÁ´4D€Ü ¹Ø.…þÁvÿÊóúm©mw:cbßÜù/Ð\°ó[Š…*þ¿hÚŒë}&Ð}C³b›ØìDb,yœèþ+@tžòê€^‹" ÃR?€*4Ôab&NÐç`CXÁhD-ø߀ÑþWGšÇ,Å&87 8 ˜À(ˆë_@vœ`@€€&ÈPø`³A“ÚØxÑ€'–¡Œ“d†Àª9èx@JrY0=¨ûÍŠ'y²Âʶ~ýSRoNrÐAÀ8Fðb¨RÇ?@q©à‚L°FF‡Í&loŒõ¸ Báò,~fj;#»Ã裢6ö;&à`´¨ü=ˆòŽDøP2kÈïuŽ2€Á⃴rÐ1LЃaw€·T8‡ÙDàd¼QÈ´S³ôà)ÕPR0陣ät-Qö=ŠÐüEtÀ~AÑt£€ëAü{A 6¤}Ž¡æÕ€¸eƒõɰQ ZkH†  ”º¦RéŒ}d½¥Irþ:æ3cfŒàpˆù•`PÄ?²L)»mœõ•Ñê:Ç»b쥾°\ÙÌ‚vX3!.BäW”°XGБ``’g(ÍIÕ}¨Fþ¡åjtAê¥B?D–d.Ú0mîëÞûZ—_¢”¼I<'D؇îÄE­G©¶‚˜fuÀiÁK§…g*Sú»J©O?Tššp~2*©4¬4j²„G K ûïôÆÀFæê7ÄÕ)q2ªR)Ó Þ¹s…QA…P uÝtpçñ& ºñ)´<.@‡¨ó/ã,cŸ¡œ0Æ0ásÊ@Î` uÕä܆ÌWÑàë`$jA°6­ƒxrOæTMQšf—’ˆ)'¬€‹”„Àø+QtætIÇñ]À!ÕQ¼îáÛ{(HM›þ>Pk=ae!èÖ€‡Ì— @ÙóŠÆÂ16¡ö܇0â©ô‚ð*HÁY°~2âô¿[º£Ú#ô1up‚dHNíjC­‘ÊÞÇïf§¤ØìT8‚m Ú7Û[ 2!ºn[ˆ¯M ßcë‰$ —ø_ÇÀ÷ŸÃôÀ1þXGˆÈk¤rц¹g*âDfáͼQüçGë ehÛ‚?€üeu(@2 ãµÒ,ÀlxgÁ/Søy1c>UÐðâ ¨í³ÊÖ \[›¹¹,DŠ:/®‚åX ÁX ‰mœ¾‡@é…xÌ–QØb£{áÛr7eþ óqt%ùí„I!M<\9¼lJ¼!À€e¦Ì{]1pZŸêvÃ< ôÜš×uòKKLv‰¡µïE0þ÷VÉMÌ´ðÝŸ¥X4Y»â\‰&àÌ âdû+ðP·c+jâû[û*€Z¼ˆ;Ç¡*Ã\ëæ² ” Àñ´<°—¤B`ttP\€ö¥„s ¹š:ÆP²`CœiI (^xA €i S†>HÝbDH —½œ9ë3·éòXöí¢´€)´V×’ˆàQ ãø+Áú^ðEÆ‚€&Œ*‚èC§N0¿äLîÀKŒPKˆd‡d¶tîtðøbc°Æ¥>E2&ºGb Þ'¡è¦¬ãbÒ’Z´XÁÄ]$‚®Áä(à0”­N'@)@BƒDà.‘aÖÙã6pêÊz P#@®¡¹âåÐà,>ä%¢áîW@ bèAƒÈB4@b$Á¾"\¶#Ú,ˆ!Ö à*³&0!îÔb‚¢ŽëîŽN¶*Šâ+AºÁ®"à2“ mva¨Z PËT B®@H[nö†Ä€Ã.î« XÙ ÎņˆÜDtA@ÇØClT¨ L†#pÛbºù„&æŸÁàÂTâƒRÀ6Á®á°aL#áæÖïÒ!@#¡Æ6)àåÄ€`` )`’«xZ p+ $"<Árßà:FL\„þáÀ>« À0ÕÊÃjêND2~‹ê«¤¨ÂkÊPÌ7dn•¥;"ëÐQl¼±ZÅ…RãTåH¾&‚Ɖˆ¼ËàMìˆMäR:‚ ªV'êP$¶ÀŒRí¤JÁ ؤÍã°¿ð"IÌ"Æ%#'e2 Å& Õ"lÂ}($ÈhðG%ä²LL)òy%ä–ÙÓ%ÏNUò?#Ð(PŒ‚»,fG¬€Èð gÅÅ6„RW)E0]ÁüÝážA֚ʂòfä+‚À„¥‚ü×Ä–A WÁðjÌ@n@)¥þr %@I*6bÂ3"8º íêf¡èxÄâèàÃÚ€^‰T>aèfj è$áàjÈ, èÐ,F„ à`"\BxÖà ai,ºÀãæ0F5ck-oBâ+d€b{Â$@B7c#!Òƒ.2Þ•¤|ØbŒ7 µ;à=§( aÖ7åŒ(ã莞éD6ÃÚ¡Ûç>`mxãÚÅ< oföm!þ"Gà~ˆ˜îf=®È0QÜ8·@ïÌ!ᄪ\S$`îgvvæ¬Q5 nˆ¬ ‚Î,C&ö®N%ï&HeŒ´†ZB¨â-ÎEtƒ³_6¢ÄɾAôô°=¢éIƒqI‡ÚJ@ ÊÚ®ä ˆ¸ê“Ccâ¢&YFö B[tÆz‡ûGè.SÄcC°/Ãh/â$€¤Vy«ÐH~«æPE 7ÅÓ.î$áÞWA®Ã4a¬&E®+´ºo 6†`)+3c $‚L•‡1„*,ø6!Ü àéüçŒ<  Áì¦"&°jÀ&È 31_#æ!ø*Z[`8€^`AÔ£ÊEªëÓÄ5 ÂÒi'Î|¢–€ˆàí0ºiæj@8)Aªe|)#ÀÀL¶¡ÞÏç@C‚ÌδàH2¾dš«KªFmÅ"ă%-MO„]ÈY%Äк „0êlÞ–4ëª0ôºË„—>¼^€°páPÂ^’ø@h$À<ÔvaöjÁÒ 0,ÆÏïÍä¤ "¢Eèïb!»nž@.¦è ÞFbŽÀ$ëV°>Ôo`O0£Fv‚¥-×^ò‹ÁAìÀËË+ þSdñ%,MŽÒhÒ£t²|ÈÄÿ!’†»L}R²jGU,É/tL(ÆU‹(F|Á ¿ ÄÙ¹Ì:MrqƒÅ0K8 'Ì.ºLŠRrÅ’é,†|N’U)Ø. %,òƼI[e˜†x#Q¸„O,V „2¿GG=‹é-ØBT%Y‚X|ÉZ1‡é)„yel ÁDºÃm†LAƒhá~£êÃJCÂ.Ã>é "”Þ¡ïÀ",b®ÆnbÂ$@ÑB¢ÉÞΞ/Â$¡Ú* 8¦"«àö&MÁò¢¨"&ŸQ` ä'~I€nKŠëA¾*Ìæ*ÄnFPnCa5™G1½”æáÊ* &ÀB*àBlÀo`DEé,Lv˜˜Y„$/ªº0áê/B´¡â$AøÓ€¹/6mœcô`r4 ` €mø~€`ï° ÿƒ€1Ü@÷àà€üP`ê ü}= àèþ}OG€ÖÑ`€ÎÇ.€A#é×:z<§@`/Wu<ùß¿7ü+o½ –ñ!]¨ÓÿÍDâG=QÈ„Bÿäù¡\_œo€ø`>>¨‡CÔï+–Ý2¨CŽ8Mò ‡ ï2 €p*6È#Nb½)b ÝA9ô€¨9ò•ç™Ô— pv&ÌVmš  `(  ƒÀæ{¤áú&gˆt› -ƒ£›æ‰E*ùúv€ ¢ò‰BÒ\ ¨Q–[€Aœc4à€%…âxž‘9òsÒ:<§R@„J¤wìPÃ`Ë ^¶‚áX—K™ì¥°Â4ƒ²¯M1©Ôƒêè"ÏÒ¾Á3ïA•tõ"i"FïV s*?/2NûÕî”W»€,¯*Hó:~ÃmðxŠ9ÄiÊ`9ðy¦Æé”€ ¢ê‰âviÇLЃ¡3N 4À8L¦¼”j˜`#À& 鱤fGǪTæ%  ær"çV A[”Ÿ‡´êÀš²vÚª¼…yÊi™¬3œ@«`€·È2„à¸l. ©  ¨Ÿ'‚¸~¹hå H0¸晼Á €±„!Bt|‰¨žg,N‚JÁ÷ ºÊeK-R7VóSÖ ¾í»é]C´V)rZ#t¹àwi ø{€¾ž„h^Â ÉæuÎR@.êZm”WiØR˜¶2€iz]o7Ø'Šâ°zßÖ9Ø¥¨pô Ñ u áÂiZm˜o²œZ ¨A Ì Àã®ahv'Ilûm»c-¸/»ï ·UÆÖÝ¥~¶Û £uz‰ {Ûuc {îM!ïûž8õÖÓ¾àú;ˆÀ*vlZKSì䀱ªÂt_ V-™ð¿Wàúá}å9ú)¸õÔÄ‚¼‹ÃuŸ1À}¯¤í‘e|ùÐáÛ{0~>ãÖw´!¯±ö>§¾…ž|"…Ði´¾ÕBØá™N:/¡úžwÖ¬a,4UN+/"ƒõ>ñõu[1¿ÏnײÜMúšW­µP¬EŠB‡ ß%¢ø\t²;á§¥D7à9Ç1G¥L—!ð;‡)và€¬â4ËaN%< > P%Ìsò:Çbuã襄ø!(D"±ØU@3¾#ãèÅ€4 H㨮"»ijm5káü°€h#ă0j QXëohnFàH"²ÈÒ€8ÆùC”±Éd`2Q'µŸS‡^¬J;Ð=¤qÜeFÀÓ% Ý‘ÌX‡èù%£¸v(01‹˜xó*D(Ï °H’*²) À,[ˆD/£°e@1x"ã¬r–¡ÜOGÈåICüz!ö‘¨ À´±¤N=†øË)À–ñêÓ@:”'@%ÄÐ ÀE`zŽ1¤WÀ1m -pXGˆÝ0ƒ¤mà (ø š Í€ìÕH±NR0èB Î˜—ÆG”Ñ-1f$¼¶ò8dÁ®$ à@X0aC(m’¡òè  °”ê€CÆà‰…)|öNIõlrú¼¾óħ`Ê! ¡ˆyʉ•S$ÈóR ŸÒ7g¹·%deeqÑ‚¶Ñb=D/ Ûð!V¨Ø’CÎsŽ3ô#VôáÁcnŸ¢@Þ¤2¥Õµw!R‘ó¥Ð-¦ƒ‚ ±–0E¤P4ŠÇRƒ‘ùôS”icõüšâ â£ÑŽxâj‰ÅT€•ر ‹3ECðUÆ”xè”ÈV†€aƒõ‰ðTÉ'ÂÃmÔpSX%¤€»ÞG¬5¦ÀT¬Pb7˜É•d©5^ð& ¦AÚ¢¨’Q$6`ãð?³”˶5‰l›"š> e ;_ŽùmÑ[C!nÁ:¢V€¢¤ØOQå-Cå¼ ±‘zpÔM Ýh0$gÀ\XfŒvˆÂX@¨C~3Eø¶"ãÁ‚7Ž™RøX‚“LŒ¸î.ìÅŽ±¸¿hüN  ¯–®´1C…<¯sܺ—-£ðzÑÐ0° å¼A¢S  r gt5…ø¹$#ðÂÜ^¢€©mÏÕü~¿9‡1=!D4“"Lרí_F[{Jh˜X‚àhTˆ‘c@­­ìΘ&}¢Jª‡âš¶CèN9¾7æ5Â47F¼q‚þô0Fi€ð(e#`piRˆ@Ø+@Å‚`V¹…ø³ lŒ¤Íx ¹Êkc$nw@Ú›&zž·` Áº9­”Âì9 PôktuG7Æ~ǃ¸®K$?Á^ÄÀx ÍÄÂKX}îrG"D2:0j+‡£À.sò#qð VÁ`pVW´ Ö½f!¤8„Í ÁñòeEð¸J`ŒWðF ÊÆÔ"è÷‘µµÁzOÍî÷…„o"q‡ šÀïÜa2¿ƒ÷B.N¦?Þà«Ü̱r1[¯ a³éó°×ÛBè™sg;í„ðùúë51kP±I"&ü–߀zÎ<6í²Äó½à£ ðm—xséNþ|ͯ»BšíÎäWgaÂ,:(£¡§L€ð.jo7”`*Fî"áä&-²]ôfc b¢`^QëöQ!ô€°¸€X(úD Ád…ìŽb\+Év*£AfÜŰP)Кò¡â)B¤o¤j³àB†ú/ ©à"MFœÇò/-²6<šÀ4 ÁüyÇø%¢f" 1fúq,ÖWÂß(6‡Or†‡Ôã4ªÛáÄ%@ǸBˆ£Ü8AÖ@ê$<$ˆÁœRú#ÃêC*; ’žfÜŸ"@aÜ`îÀÂ8åºi‚Žaö%@… €.jXÁÞãÊ` áê&£œyÀq 3¾B€€b—bìfbšÀZ ‚–(aîA|tbü(€Mfdf G¡úâ†0B@BubðHÁÎA80Áö$3åH%¢@ËhB“ÂZ:ƒ$Äæ€P\ÀF J”$êÁHnú#`”Á¬â”2B^¸cҕĺcjzä ³çàCŒà~Å:>4*(8H&Ü8‹–WãÔõê;ä ¬ÒŠ¥V>è¶#ä8lÄøâN»ç¦:„»ï>C‘¨ó¢‹FÞîíf¡ë£~Ë69Ê(@çœ'E^ýÅ.¢B†/!öêÐçt .:ÿ¡Ü¦N '@$xÀ0ɬ€ÁêK % –B8ªŽ2®#‰è9€F‚8Î2ÝÎ[©'  åòÀPoáäå„J"áÎhoF & M‹ö£d°@f!ð,AÂz$"J3£)ÑŠ,`8Qà& n íZ7‚ Œ1¯¶c–‚Gôœ‚#$òh~kÏÂ=êðïpœ†b>r8Þò¥6„ÂCºÂ:ß%BƒtÁ“+Áæd\@NOÁÜbÆ@g`Zaâ¦@ã ¢#áÒ› ¤T 4 @RC‡éf…&&Aâ*¡ø'tê+‚/`$b@† ãÁ²ÂF2 "O¢ˆj¥aÐ0PÁÔb‚ÆIe/‚ ‰8+óä0Ã8¼‚záÆŽ-t6à§@ `$*ÌÞó¼áÐ.À6Œ,qÖ¡Ü)@0% \e)ò„È0U#î‹ÏnU(ÄCl%e„%…0·°~!AôC*À ÁîyΔ(á¨QvÄ"@ÓB¥¸P%ðÂÉôµs¼a ›aʈÜ&à 0OÀ`à£ÂÚꂸÇbÚPâSBUáÞ"ª²e 8&”¬€ §=àe!ÂI@Ç\E `TOÀ 'ätdC$¤÷g¾Í%`¹‡Ôí¨.üGÊ;Ô¨VKœyîÐŒ1ÞléÔ·îÒ·ÇÞ̯zˆ!÷„D$¤gtªÄÖ½L,ÿ%òÂ*SÅF%cªôNõXÅTŠˆ4B+F÷o†û†OD;c~‰èŒîç¸óèZ=vU1¶V5í%NÞ„(zUH¦Îé Ô|ç¥JuhŒ‚,•šáœHÁ¾ÂT q TbÚåïkÂüÆËë`‡«‚5þŠhÂ@ˆ‰ Ò¹À d5Úøä/]õÀü/Ñ7Åbˆ -âUFó¼3ÅØá¶ ªIB /.à#À eòY$ŒbOÁÞøÁæå ‚ö½ :) 2Dj!ò*!Ä‚lÄŒAžŽ6¼_ .„z™Š¤N”0(êêcàÁ¢u£ >ˆðãNÅòX%©$½à¤jÜ%Õ…`B+*&$H¯§:‚!Z”)AáSæˆâà¡î2¶6.p‚®œ‚5î‰C˜"‚6•"bGÅ "æðtpÆðdáÔZN£ ’š“aþµ%^7Â@2²žf>Ú‚@¡ºª¡äA†)ÂúdÂÀã`áìµ@ ]€ Âæ!»{áúÂ{DDUçòD3DMaò%Ì6-3þb¾C €T¢ˆB4 £&:)äCg‚‡<âÚ°rªÅÈ0.¾Ìá ÇC‘iù'ÏÜ  Û¾0±¼\v<IQølJ€®€Á_X  ¬¥(*þàGô¼S#’D#Œ6™` Ê=‰†»â2òªj@#!Ä2TŒÖD(žd,TÃÈð‡äµ§®=è²Ê ›sv%c*»#ð2ˆ>*ðRÅ`2b„ï*B¥ =¡üRë3ŠR=Pœ„ Óz0 ÒÏ”Æ.À")däXáÒP$L£ P¥¨éeÂjÁ–' !†¡èã á²c  ÂÄÀ*_"T+Ì(AáB Bš¼IC!@8 P!ø1j"#ÁöùLm=‘Š.xîXáÊ'©&¬P *q.dDTà)Ch* 6 Ž¨ =ãd(jJK"½è¶…cØÉb @ ÃKŒÓ Ó\¶d=ªœû’4à/ƃ@y×L¡Ü(á®%¦@H4Àj ¨ÒªÀ$($Dü`*.@ha´˜ +Ú#ö¶3² ¨0Õ¸)Ì@1òHƒ„ä@I`N² &xÁΪ:AÜKÞb€*x˜ÛNDo!Â[ fåc!Þ'¡Òìx9!"‘ì8š×1V—¦Ã;.“<.üÄb¬¤kŒáì+€CTà>3¼$ÉCÞb<˜Z8@¥ÍD‘/ˆ~Ë¡^"-8Îü|ëzþ¹‚†\&%lÂò´haúvÀ~`¡Nã Dêשœ±baÄ„*(¼ ÀÅ!iaõ B`0ÀF :¤r> j-¥bApsº Rär boäf áŠp+!Êh`>Är`zy¾Ì„¨¶ŒàƒTŒ-!íx!÷[«?VgÝX¬Á4¨pzÔ™avgâ6n»^'¤mnÝ_¢‡˜ÞùõÈú¸X$‰éX ᬂìbðd€`xÀ"KS¿Å&ï1_õÈËOÅWÅ1&OÔó6Me‘_.æ7ï/ÁcíÇÚ‚æ@†Ú@ þ‹Qß"ÈG`o}Y/x†•uÈo3&ECVÁÌ&›Ãèâjå„XÀ$J¬[€l½ê÷¬øË4¶\ˆŒóõ}]ÇÎÍfÝ…è'6o®‹ä.È#ǧë]wŽXòUonCWzÁ˜0¡®HÜneº%ñ±5ž$)R6аµ£º>ÂÁðÃ%ä*ÂTºL"\"¢Ê BZ *.i¼Q:*1aß/#VÌ,gô\m²Xô„^À:½îXáÆDôÀq •¤©9^×$C‚T E@TêþÁ”[ EØ BbAê8KÔq!šEºáãB³ò1`neÀdùÈNAèr…çÊœµÐ‹¼{¸ë6aò0 mײ³¼+¤2Ã*a!þ®ª!#Ü»ðz0¡æ¯â’:£®%ºÁ¼Ž cÇ—Û|ôt*L!Ö.À ³¼j’*C dý†YŠ0€ F  *8Êàªæ@;¢"@áŠÂ.í¤E"à@Dud@2@â4X—§‡ì¡~+!ÎØäRöž#”¼#áûx;8C Æš>nÂæ¹5¯àL(¢¡Œ჈@F à< ”(™Í±BJ 5¤@UÀ2¦»&«^û7gߌÕÛŸðW&‚¿‹˜ò!#+á=:K^Ìe^|ƒ.øh0»c΢¸ô|c*;_X»c’Xßd?#î ŠâUƒÏ""6$Â=6b¹b6/8î=0¹$v2ƒë†<âXÍ‚2K˜ ¢@Áf"Ç:@#T§$ö¥º¡Ë„`.ÊY÷¥ØA™¼à“ʬ¥ {ª1b›†$ àxŒ À‡ÛÌþ€wëÔíw»€·ü8úyï´‚P(#{<]`ØŒN{¾ è  Àˆ„Ðð¨ˆÈRWÐ?¡À944‡@0‚œÿ­Ù€ ­šM`­Úaµ°#þÍ%“G$À;%²»h·Nn÷¨ˆ ÌÝi3ÀF[üt4€\$A  °hx;à“Q”Ãù€@óp8, éËéî÷Uq$ôð˜ÁâÐvjÍ\¯GÔå¶t5˜“g«²š ̃Á¡pÕêð£8N‡?yêînCß±úÃâNÿÂ_Ö0Út€Í–dŸi:¢¨FX& #¨R‚MiÖï ð\Û€hqìn¿gi®h© C2 …ᘠ„N5µ¯{"¶0‹jÞ­¯¹ò}ªÀ´}Ÿ( ¥€ ­çc¨`–eˆ¡K¶}9g ¬È æq–!X`Ñé‰þx‰X– ÎÓ⑟Ǽf`r;.  ªzÁ)Ñø•¬`\" `8‡)ЖæñÄ¡f“¼¨êZ¡(d„€oyÌo›(‰Üs  b´¨¡È€xz¤bátÈl° O¡0ÆŸ‹2 °/ lZ­ÅërØ“.Õëo®Ë¥|®$Ê­†¿ØUý£e6"Ý_ÚÏ¥k­Ð¥´·. Ùaö´_XjÜâ“gƒl`ÆH¡Piš €4ƒ€4µ ˜!)?ë²9kXW-­r¤ØEÓm[)b¶öýƒcá‹ex­Ï ß…ZVµ‰_Ü™¿mc­½¯“ÚyÚ·/£ikâξX8•Áa/&9$jd€à:Ài™4Ù¢a² @ ¡ 3ržÇRV —tAW6—$Çîb¶Åy6Whܱ\¥T#àÐq 0 +@X"ªŸËbç°/ë¶~h7‚¹lÖŽ!pÓ°xîZšªœ§ jšÆ‚V½çÁç¸' 58<M4 ¡΢nŠ B´ƒ—à6Éí¸G^ª}Ÿ©óÞ.2–°“Äg¸‡²r€Ë±õ;*(„⪀àPˆ Éö}=€Ì'Ò!+Së€2í§‚r›Áñíö§ºˆ™Šaø~7*^øì=ƒhkâ  3Ô+@¸4ðhNÐú)ÅA]±¸0²™!wYL¡Ã—ÇšF€Ûà˜»AîrËIì"kðÞ™x €!òm‡Ë°n `ˆ9:Äô¤f€!ìC0’FæF¹‘s ž•QòŒ°ø€€“;²¬?i±â#2rfGèK@a,¿ùÞƒh]šÑ¬0b° B?‡Ù%€P‘8­€ëpôcŠ¢L>Nó4Cø=g˜mˆÙ€%h´•¡þ?Gy*Å„À ŸÓ´0¡ª!ª5Ø’Ò7ðÁ¬V(HÛ'Šh0À¦òªÏJém')Ùf€ß( °ÿ†ìø’QöÅKZ++•¡ø_Ëp†RX³ÁƵ ‰y.%¤²+Òô®ËdadA½–Ò8Ç¡%‚¬t´3&Â]Uéc,к–âK4‹1'+YšMÆ;9–üY%`¿0YÞØ v ó²‚­™ÔíÙ죈ØPõ”ycÀtÌ5( Gf60á¾ø€Y¹$ôåЛH¨Ú ­bª A1#Z¢aÎ6å"§ð€À@°%&£¸z’PŠ`ïi€D‚?JÐPI a²3Œ`ç…ø> ¹'(ƒ>Öèøf@P BIt+Ò– ØÕÈYŠ©`*+³…–Š›$³c³fC€C­xmU!Ä5qMÇxŸŸqÛL‰øNÀ0ÒZ<ÉÈ 3,8†yû %ëpy.ÇhÇ^#ÌzSLYCŒÖŽáªõÉ` eEø=/¤ä¨ H2Ť$ú—Ñûb1¬ Eë>Ò0€9¹$§ÝžÇAî3Öcô‡Àõ‡(í#à5âðI@°VÃêc°ÀÈ#RCŒ~aÆ6Æê«%„*qÖ7à@$¤ wô>!@m§ÞHÀ°&I.²d³[@ÀI`£¤†A˜h =ã¨t¾ ŠÁØ#^è ÁH' "ºcPf‹åHíÙ@÷€EDA@!ïÃâQ›ôSGÉïù Æ‘ÁòÝ å0yùF>‡z§좟NÙLUÆ9Z»ðþÄ|­Ò¨õ ¡FíÀ¿PMÌ0zÀ„zíÇä­ðíŽöá)ÚÀ5 z?#µ K1ï ¬©.…αa”c 9¯ÊU”Äý–\LmdkéfÉ×?Zì´¦±&`YÖárÛ%…ŒQp¼SI€1Q1ÒF%i9 ŒáPYtÀ( ³¬¶m£;•h,§c³¦n´–o²Û‰±=š[X*Þg,†meÁ²çÎÏØûùdívg¿Zpœ®.(XKpôiÛ/)±à8.²=ãô}à(õHˆ$£äð [+&¤çf á›+aLK‹‘½wb@êg°wŽ¢J=¹)+æ€\[‘JÆ.ü-±ñYgbœ$+…˜|’À1F §DÄ 2nGàøJ@\  ~½†M«6Œ€$ìy÷J„«`P@kúyǰ˜‘ƒÐ€QøŒÉ­#Á¾ÒFÞÖw$t€_˜5#Äwøc æ$~->Ÿxà`MEØ·: ˆ4ðX ÐêÁ„W@ÚôBOêÔF`%¿ÄƒqZK„`~ü2Š` î‘8•¡Ì:cD!ÀÔ yUAWW›m®ïw lªœ„‘Býž!¶j ¡<( ¦›« P¸ˆp;Ș‡xp±Q[h y‡8oŒhr16”Ø{jF€pH}µ( —¨ø†‡³üb줸Ö‚2ŒˆÐŽY/®ÈЈ(ˆpz†Øý€y±o‰É‰09Ȇ€Ø iY hvª}D »š1‹÷‡ùµ,H­ ¨ˆ ¢Ê p}‡Ø¹y«Y<0·9ÈöŠÜØ øÛ€Òü ¸r†@Ö€íhÈÓLŒ­JP‰h» ÷– ±(b ‘šiBù^Ѝœ‹šy()™ œÀhŒ$H Ò‰2Úƒ‰+aŒ”,p†ÄX¶,1]ŠÐާRƒˆ¿•ꀋ ™üÙŽ§Ø« Á,Áb‹YüD§z~² Ч¦1b© l‡à»!ª&Ú¦ °¥ ³X®3;6€t‡:ëHj—ˆ}†Ú ’e¢@°ЕÁ’xxÀ !‡(b…€•‡Ññ#ˆèx‰+è“h{€þ>x}‰ƒÃc5ŽX~A[@p‡€xª‡8nÀ z€¨ ÐrÐj k†ÀüB!éäEÐ’€À’IºŽÐÄI\ºN˜ˆ¯¬RËÆê ÅQa YŠ?S ‰á–³&e¶)ˆ‹òÉxhêèg†8›Rè°‹¼J£Á;¸­Â¬šxh<>ÛÚ¥ ‡g3¸"€w€q6‡¨nª €©ëðw£— I~H!aÅ3p\i¸€À„ªuÈv B³`ÓÀ™Œ°€ˆá °°Ö¨yš¨u†8Æp ©ù€!;¥Yçyt¹Ðì¢ð‘BTωÑÓ@m”À€ð¤¾ˆž‡t®¤†D× ¹6Í18s1üŒ"°– )‰ÀH°(s ˆ)óä¤ëØ~‡àå1¬Ê HiÃä×’3Ó€16€€%Ùÿ"ˆv!9ù‡ÉÿÑBù”™¸6€Šã ˆ ÈÈð0n†ha!TÛ©Ï)»€*…€OBH½@C¾”{ Px󹑘 Ðj>¸èÒ XͬqϺh€€Ë-êC€Ä} †À"w8Å&ˆŽ Û¢'E&²n¸2§ e'±  5,:!œºm§;ƒÒý1 Ämº~¦]$ˆrã (j4•p8 ¹s:Q€ø”U Ù6&â|œ¯69jŠÜUꌀ˜£±–•C›2 ¸¹p-H¶ŽSˆ—oÄYœ¸óˆ˜­GÒó|8eFÑdÌE—HŽ)“˜fqÈØ>ˆˆ«¦ ðy%hÈ‘˜ C² €PžžH‡À"yG€àž¯ƒ…TзÔjÅY 1ÜaÊ °½˜€¸ž€Ø±A ,¢!—¸x»Ô!‰§ÑÕ¡›Ð¨ 0{ °Hb p†Ê©€‹}*Dg yÕp|‡YMÐ@“¨—ày‡œ‡Hs.€y­€¨ #é £|J—•À³; Üɹ€¨Ñð‰u8˜€`“Áž°˜ó¾ X;?¥l׋0 ˆÜ‡¸~ ÐÏŽ£5È{Z%}ahyIyáEÒg!ˆ°€!á³0“XŽœJ%° <§Š©í ŽÐ Ðp³Ik¯T¥EÅYj‘[‡( øŽP“À‘Ò0ž‰9µC‹‰O ‹{ È~™•IÛøy‡ Ϩ倈#Ì‘›A«8~@¹Ú.p•€JPX0ŸâN§°r ƒÅŒ°uï`Ðê1‡@l-#ð L†ˆÈr `|·@Û‘Ð‚ÆøŒ•ÀŽÐ Û‡Ù;Ùf«d¾‡¸† i]óoÒRÅk“°~Vd1}+›ƒÃЂÉÒ0í‡Øû¡¬ˆ%X‡¤ ›ÖXè!‚P°€‰‹Ñç¡´ÂÛg¨lnŠˆ 4Q&­£õ6q”Þ=*‹€ª¨á’\,R dl&9»Ôâ‚‹„0ˆÊ~‹brà‡$ΖI¿¨\ûˆÉdž"„¡’pÍ©§Rx–0³@!ˆ¥¸'{i–K‚˜ÂÅDaJCk¦“{Šxø¬À²à‹ÏaCø}4!LY'è{‡±SÂ!ññu~p±($²qS°|œ†XR„`ˆø˜ž‡Êoˆèt‰ˆ~ÝòKˆBKŸ“¨å€»R0 ¨š>€ h{b—‡ðz•>!‰+ɱ¸Cì ŒŠQ[èÖ‡&AQ—"B&ZȦš…À1ÅþU &ý.Ê%5¥B‚ Ö‰ƒ:P®ˆpl\>*€¢€TÓ °Ì õ°0几n"™&’x-Äë®È ·j ÒQ€{ç”Ë/Ú5c¨• €8 °k(Nž¸³€ày)}(hCýÌHªÍ•4hû€Èš}±Š¨l…©EÀõUÅ#X¨PûµXêìˆÍæ\öU€£è€y¬xn* º>œÐ÷€  `w‡0Pˆí ™~~9¶ºV€8 ” š×"žÓcѸo®°lMÙè iŒ°‰(d…ÀU‰ª6¸ª€£èÐ&€IVˆh! Ý!³Õ$I )‰Á¸ P°gZè@xØ$³)‡@g† ‡‘.³H€i6©öWˆöQ’ހݠՔië!ýh€– À‚à.r†¸¢†àfÝx‡2©3@œ€yY‡@v À‚ú´z ²TòЙµÔ¥iå]g¸2Ï&ÉeI¹i ›}mií}Q·ùoÒ{h(@ŽS1ž “xtp]…PY Xˆø+@ç{Ä€õöÕÙSKž½P ŒËÑ»‹ÄYRªtYîÜ—Q·òÏÒc|Ôƒ±]+™{{T—;€S™T)…mTU¸ó_ÔvÞ¸­TUEUÔBt¿a ™èÀØZ”Às‡C<€ílèŠIB‹‰ ŒÞ‹Õp‡ø ¨ Q§€h ‚A,¹Ž[r‹ý% t‡(Ѝ ‰.•práM‡@súÀÛyŠªU$!ŽÜäFnô Ù…R¡p¼á©ÄRà} òs˜œß­Caú쇈p.Ë3 5Õ ž…èr”5ÇÌð -Å눀Å(vPê r<¼Ådë`w ´LpÁ)(ºA¢ˆ…“µ…•8°y¹8x‡¨ªÀxód/ãŠ#ëí©)%9QâH†ïI[È!ëAŒôr•XŠ`*/pf -Ýš¨ áN€’ `ZBEQmoIžíé‘TmIÔ@À`xp|*ùT€Š-èC†ªPŠx§1rtko™¼T"#ÂB0c¼:Pv†ò ¯<ìšÙ\ Êý ˧Ø}•€‘yJ°†µ^*-ñ‡¸˜©S€Y%%v†¦£š‡ðà) –óä[¼ö%%€1¸(HއÑ)$é6‘ë³RP¸lKO0ø“°sLÛ,œDâ“€x¡Pꊀ­9M È̱˜š€^ª  P´¡¹^Œ¢8TK–ÊJc(†§ì'é5ø±¸)¼Iø’˜å•ìF˜ÌDâµiÓQ_ºd&ëƒ!¨µ‹b ¸°¶NÄ[g‹­·Ce‹¡M%Ò_#_дá(² p呱’ ŠwŠün¨’Ü(ˆ ‘;pm¤ogˆe‚ €Ñ.€wL è­’H+§ €¦ Ú>Š¢ÉëXuy†€^R0<)úuLàÕhøÉÿùè a8¹Ü”ؙ܀ `ƒÈ~†êF¦È„ðª`èZÂØÿ¥‡ !å)H),ÄŸ™œ`· ºÉ6Ô£6¹™ùjS7¶DW(“BÙ ˆèt»W£È(À €ôt8¢n&°àäo!  æów€ï˜SéìôƒÀôa ë9 {¾%ƒò©x ÛÎ&ȦÇb/9`D>?ßP­¬ÈO$~>à@ x\ ‡@à ìv>À± 9Ö剂 ©Â `4dxº+¡a€ýª»À ;ÿ` =͘ÔA€(Œf}¾$¯G\X AÞ¯|@L#]¿±`X>/×@ö00ÿ~ï°  •¤j²)¡€¨ïo6'ŽJN±ó<aÂ!u8=€=¢8°öp@oï@¡i³š@Úx l!8 ¨&ÀfkþŸÊø ²m›©â–§b,œ¦ÚÀ€ÀƒJéï g€Gûæ«4¬RÞ~µ¨>Úƒ3jvžO€NJ¨è»n¥êÈæÓ È-(4Xí`3 ¹+§û ª«±lÏ2ÌӪͳTÏ8¬<ÄÞLs)û¬âͳÒÁ7ÌólçAÌs;|ÞM ôÊ+ DÍ]9D”Jà®Çƒpx2È9Ü’›)Òb{ * Hg‘ìèÀðJë†Í¨ 7`ýRZÇØ/º»:Ó4µBMôÿfÑóí=3-ŽÐ,]3ÏV<âÞÎÔ5*ªÚT%µqÑTµÉ:[SiûgOvEá>^íÏyÞ–Õê~M3h 1S(tÇ›X~ÉÁ·SÙš`“‚à°yP~+îË´18* (öŸ–³$t$õH+§yê߯ñôæ”A.d`ðP·…ê$}Œp¦‡©þñ‚@ªBõ·g‘ô¹¡; ó,õ@Q”±ûlLà%3Ÿ“üÄÚYlûîS烀y–ñ›¦±¦ùžPéÿšÏÑô0àIúx€0@@øMÅ€t¯J +y•8 _@8 ö€@BÆ ëRÛí¸•!GIÄsÖ@Jä~ÑÉ(~€‹’gêä{€+«½ÀK ã½§™ôñ ‹ !,”™ìÊ€“PÉdgׄ@êó,`ð=³­ðJ³É6Ù[ ¿BÒÙmÝv« $Êiš¨QÄmÆø~°qð>Œ¸EãPæ6c?ócF µ*§âÁ‹’aLíEC£ ý j%|{“p†ÌpÆ}":<ˆ¼$É\~¥ôÀ9›1È’û‡Œ{€ *žÙ)`Pì“âÞ¦@Bl­ÖÖj=ÇÑ_mežø?Ó0åÄß:â€r_¥Œ™Bìo€`b€4 Ä3 ÚØÖã©)“Òð!.cX€1âà€#  €$&'ÕK™Aü¶MñÎEäÅD;µ XÛRh QùÕÚo”#`“í‰<)• ¯¤Ár=ª³Aù%ÑyÐ,iþQ,Òä}Ñ‚#~ëà5Òo‘ƒ+:Ô·¦¸'K4@o"ù*?Ïj×[+ZbÀŠÙf:ŽPò2šÄ¤UWÐ,¤ðvRÈ>X8}(‘ü1îo€‰6t£¼‹œ/‰í+ä¢0$ pï#9=޾W@(=ÀUŠÒ: x@Ô˜ J"Í(ú¡jÈ”àJH˜ Bc¼pÑö;hX —Ï4’`: Ɉô@cø}¸!ø¢]a4 A€P&dGБÀHƒtHi—QÃí2¿†²tÌ\ɸ宥û¢Ë,9u]5€gÞL[ “‘i;¨uÖ·ç ”ìß t ®dp‘$IïdH|¦îÍ "%€XHz†—€9¡£DešÁâ8ÈX> @@ŒÀØn£h_ ð + ÃñèeÇðì#§âópUk¡/¢ÐZ’È/(`M‘Ž!®5ÜHô$ (šØ8JIÉ @2Ù& Aˆ#ÉIâ> íÖtM!‘ܾ€m3&  ÝaßèÔ² L Gà,‹pð&\ÃRºbQlî$QP°X L@ “‰ˆtŽgT=‡)ƒh tq¢‹G±%é\pFÐ0à%¢§±ð@Ž» &²gˆï’äÀ­I­:€qZSrè“)=m!¶·ö^‘{(½¤[öÚ-ÜzCF¯=źw‰‚RüùŽä`7²§㈋îF‡šà9ŠkU† }@ÆÍ@É€\+Š)  5±GÓy¡T¶‡cEtl ²JD#À-ô9ü$=pWÇâÔXZjÍÀ(d`D °N ™“ê5e¯Y&üS«(™;Mø¦´ÔÛY]E` ±šxÈÄÕ–Rhkjhë!PlÜ£’ÁJèû,ÄÇM=3U†K5¼{¸!úÁ€„ÌÔWô@I¨uÅÚ…k\€$CÌ»àÁ¸9½Tò.…±\1=¦2ÀMlŸvÍoTiÄL %S¡Úc\‡à£áRX~Œþƒ`ƒ3‚?ÌeO¹AèÔÕºJ¾Z›{ðØ}uè¦PuŽB°8Æê biÄÄÓcŒ `¨–ÌÊ“Bumm^ËØ¸˜Ïj½áwùÁ˜wÉÜ>QÁø$¡ðòGÀm€¢Bœ¢bÆec(FXjÞt¢Â¾+ ¢JÛDÄŠB  daú§TƒáÖOoª§iŽD‚ÀêXe²•Í&,-é. -À8(ü#$À¦‹Æ8!¤CH3§ @5Å„¦©Þ&4欯  8 ø¦úØ…¼%¼.Èz]ê²|–ÄZ‚EÈ[m)MÀæ\O)>™å¼làPÌ_BÌÐFÖ=ÇÝôkM\ÐMÈÐäâ–l–LÂäèçÖ7þ”†\+èÆÒƒ(lÅ$•çØÜ… Ø”éŽk$¤k¢äÞñf¡Ò,&á¾4‚xpAòý0æ(€¡À£äkºÁàpJ\0àÇÀ#!ìà`dNà./A®n áª'€ b€¾döî¼(ð`Dà$`N,‰ÂáÒ0h+ bBMX¿£Baì À"°h£PdJ-æØAü8 ƒŠ@x ƒXý(b1=§ð=© Òç— –^唪kÌÉMØ\EêÝlÉe¼’i†‚@PPŒŠ¾”M$ÝÉŠmèÄX"F&!æpAâc%N+ Éì`*ž…Àh€JÀΧTÁÜ0`DÇ ï >½ ¿Ø!†0ÈD„L+¡à$°"2énò&4#Bh¦L¤F ´O`0b¨Ü7j7À°"$Z2!܈ðÁÜãà*—ÊoEô|X,€ 7aú¬6@0¤!ôÜ’¢æé@€T>AÆl&vã(KƒÒCf,€5@dlXÑaÊb !¬¸‡¶DáÔpLA˜DöAâî#Ò B½!Ðã.@æºJL(lTXIDᡎÁp-áì#«Ö41h‡aø J>@$ÂBó„D‹ÖÝ‚ì $-GÂ!ÀÊC lŠ„°ÂbF%€zÐ*eô@ = LŠXà +àBhàB©AðË( Dà6C´ :$"ì\ÀÛ… km¯"± YåêZLªºY-3F%²RnžÝÇâùdÚÉ…¾RNœ®gâÞæXÝn¦ÿäÎÊ»)BX¡fC©‚uJ÷?Áîðf£êÖŬ=¦Œ¤ D#jÀ8¡À‡ZÜ%$OÊ^Pd]æ¸^íЋ$ÔeÄå$t|ÚŠ¸X¦X\F Ìù”jR ê-FGçPŽœN-æÜÔ`S ™.‚Áj0axšDCÆš|`DDà†/‚-*0L F΀b€†(rÃ|T"iØ5…2`21f–÷´|mŠéÎÞÔ_A²b$Æ‚’Ö¢hdKA´xÙb7†Dà:Š-ìHX(²ÙðÌéE°[u‹4VRnö+²dØ‘0…ú5„ÚA´+áž’¸xó"Ô¡Ê$ d 2bˆ†` .A¦ÆØAÔD ¶ƒ./\nÆÆNÂb¢h $BaÒ–&a½gëhrà.ÁìfcðÙoF @/B Á¾'aò!÷!‚ä4 & bœ‰êæjz¢Ôë¢TaŠ4²Ò(` è~XGƒ¢R…Ô¶bì­åôŒÈë!”@2ÃBú+•&¤öŠ ¡ü/×gׂ}Æ*­íFoªöÐé ¤Í‡!öÈðaŸ;úcW#Óme!r0» ˆn#Ž I­È’2áìž²BJ¿"ýé*&DBÜ W§k®`áýÅäö§oæ!òæâª7Ä¡ÉO}S(*ÝÂåwfk ‚Æh¤‡‰Ãv>Ã`†FÁ€’$ÀFÀ‚¯_=TÅ;¬ž-´YŦ9i´êލO0éqéŠeúP'×çîÞé’ÂbhÐQ5:‹H°D„¥!$Ƭér˜—îQÕM—ž_¡ylWG-22xNfVÅoæ]§þš&PZÆËüOƲN±2’I.REŒn–Rⲽ²ƒH .$5b*¡è74ãÒÀ'iOõ8`0"ÞâÜ›",n'…87„X:‚ T©@"Æ(áʇaÐiø¸|4†¡Ø`ŠH`2€Š#À2¤!Ì#¼*ð/æãÜlcÿ$BYwïà;ø*hÂåvNoŠ1ÖÚ¬3q[Q©•†²—áN€P0ô ‚Â@/øT$‡@(Kú B@€p‰Ä!/Øp q7Û ã]ªŠ@Q¢y¸e Àì÷|>¸3õêì ¸£ñì „Ã@“â:òvº@ ÅT€AaHÜÕ\Anˆ;ö;‹¾cÀ@ÇŸ” ¼ üû‡?À¯ÈÂ7€€6î—€êñ˃¸×ó‘Áx ªÏÐTâç@Ј•Ñþö¨‚`Xˆ8À€à ¸,.‡•ít‚€Ô°À„ qA]ø8c”Âh—än#¸Áßñù ,o4Z@ËÝî ƒ~5ÈñzàºqìxÈ"<`È<²Hêì‹ŸÈØ ¢Ç!´r€)^U f¦ÇT‚ Ì àØv+‡Às8†™‚Gˆ pxʨ{"ÇzV÷ à}¾'áØu€ <€X8#Ç’¸}›ÆÄp}8çñþæ ˆè £``-„A „¡ZÎ|<¨R»¡ˆ2I70èRFƒ#ƒÓ H„æ…£ÈÌæˆN Ó@$h™úƒðÇúH#ðÙ£œƒÚŸ qø|`“£è8žnàuRÖ°ÇÈN°‚Jp" ±¦ùÒv€éºo€`»Ÿ§ÆŽ|Ÿ¨FüÕ£ 8Ðí_8‹¡ÇÑî À*ÿd`"í°·.Jî ƒ–1Üz°Ø·*ƒ 81¦ÙÈýß "ÇúÍm°(ÑÈ(Ù¼nÅ H „Àƒrö0û·€;~…kØ:/gÚMÒ¡“ÔæÒ(áPD mâ6ÐS …¸|ŽóŽ>@³<¤X¡Ÿô>Q˜X`#a¦?Ï "Ê|“0 BÈ#l†‘bþ@›;"ƒÝY1¼0‰ÐÕgò bÇhúVcÔcŠ>ʈù¨˜@v{‡€êðzŽò(<ÇRa AþA©Íè}Ž!ro‰  ¤Zyª9…8²Að<q}?oŒ B&¡Þ²õlë‰i­²L€¦4 ÄL ÁÄ_‚ün΋8 J(‚쾈@üuޱKÁâ,”Ñ]䆮s€)"Ä ‡)Rï)"pbh P¶úˆé • ÖÂ3Мùlp…%@ 2Ø"nKÖË8¢¡%*x„óIb7Ë"Ãò@b$ˉ$kø…%B?Ôr!Î)bžÔ(ü! èa’/  à' AEìÛM©ò-8r ‘˜QG¡Q ¨+:té¤Ì®€/€ÀØ„ ,M†8È8LÛŸ?€Ì{!EݶaöŒ€€¼ð‚@ërŠˆq ¶&<ʉM4ã´m“˜üED J|L_€>’‘@9{vÆÙJÍÇúÄÀ ¿OÀ±±8^e2r!+"³%(¡S‚ˆKqòuåôŸ üÛ!iÖòâ=¡ ‰ŽŠˆ8xÎ3ˆP4ÈÏé{9&\Ôg4íÀô`¥wài( ‡P“ŽÃšD8qÄ`?IEÐ~ûp]åñ)†ëJúÔx[Aá  0*t-Ûz£Ý½ÇÒG‡™Ý=äyê–E€®@Áõc™qÜ’O‰Ü·€T™ žXª |#1Ø9Í`´¥Úª‘UÀ§Ðb@P 4îØ€KŠÆ&¬ä kÕj¯_[!qN .1âPÁ8s@0܈÷"ΠðD D”¾‰çÉÄ¢.…p±(„²<ˆèàµ|–Ž€AC@hÎ5®#G@ô+„d|XùE­ âj>GJI`@ÄÑbhÜ&#ôu)ÐÑÀJ»Œ qÙIAÖj€p`0rð"oáK®5äµ–þl ©@¿Åâ§'BÏ›ó¨¹/5§æÆ…Ó Û iªË£È‰Î€Â3ÆC™CD˜#ö>Gƒ•X ²ãNÀA‰!Åì; œkÕ$´u³ð_qK|K6Á¢p“0 ‡¦Ö¶%É„´„O éyF¹fúéÙÚ2mU©:T´ßÑjG™£ÀŽQÆ‹Ghè+€0˜Í3Ð!@rT A¿@ÆÛ×@º%ƒ çUf%TƒÈH !Š#܇¡Ò@ÆèØI9 ö!Þåm‹GsŒyÁñ³ ë=;FO§Z£àBG©Cdn Ú~9†uƒì~ÜH 6¤n¯—°  ´#~x 6rþ’íÈeÜb´üÀÏ™ÍùH •Q9™@DÈÀ@zñªÃ¨Ë€Ž¦ØÊˆ'¨˜sŽT*=G’³”Ç5›‘±ô>Ú8…V¾pH Ž ,4”z+5rd á¶IDhKÝÐA‡»mÃ\„aÚ~Çpï?w…Ê€@þ°¢šdý¡XHB‚T%©¡SY~Œ0ˆØò²S&é>‡è‡€w‹py†˜Y’Pr¨i›Œ€~€`³€()(_’Sɧ@½‡¨ªØ‰€*1x±‡øÿ X³*%òφûƒ d…hˆ@½a‘‡À}؇º£ÁàzAÀ¾š8*=‰€ý®*^ˆpà 3x¢Ð»€»0¸ª¾Á€ÛÞ€Y…gˆ ‚ ƒ®øÕ¤H A%rŸÑÀ”è¿¿RSJ¿”᳡Qz±rQ«|/ z¸ˆXÄ;P F+1D0Šc´únÄðŒ&ʱ-§Š>¥räˆz᥊r`8£I0“zn´I7EFë¡b¶´Iy#êvšÙ?'«#ˆØÃ)¡v 2Z@Ê’pŽ8qH^Šwˆ€¹™î‡€t¨š€2; È{‡[6 ÁšÛ [¶ H¸ :Pp•pz†û6'Á ‡Ðs•pÖx碈 Ø €øX™Iа}iÊ¢‰£€ŠFpu¢€o† b÷ £þ)( €ù`³ÊõŒH=)ëŒ-ð…Æ$·‚7u—SK'´[+Œ›Žàð4X£´‘v¼¬J§`¨b¨ðu†¸e,øs<` ¤²50(˜nƒƒXjC°İÌÐË€Ð3èm†`f¡Ðú‚Ð;Ho©THWjW‡{ƒJ>8-Ø… ØÂ ØÚ±Ù=Râ`Ž‡Ú¾ } (©)¡Ñ£ˆp{È1‰‡ º@¸Ž`»‡z 0{–`xþª=‡à¢Ó=ðœüÓ¨Ñ&‡jKS3†˜‚0³,£“®€ ½À —óôˆ² ¸|›ZØ,]—kH&ùE —ˆ@möHP€©cLA¶°Ð„·Èø°Ó9 °Y…0S³ðºH|‡¨º0™šð‹jš”Y…(¼3Ñ€1c1ˆÓ‡êé ó¯YcP-Pæºp @Y·¹Ê‡8l‰j­ ŠÀ„w˜“ˆq‘x3*÷LR¼€ °´êW4ã9)@KA4K«7#L–óHˆcm7w—}´kB°«F–£¿OAªPm¢€xa†‡Ó¸ˆèzä|‡É„­È´XÍ‘ ?8˜Ñ ho°mZŽ€T…À ‹¿¶‹lÉjÑP´óN¶ù€—Rf´Õ" ¸T*>Êé—¡t—19«ËM}%1}q%a°´Bt·cTâoØ@` Pk†„Ü•PÃà½Ò°Õ*ÍÌø¨Ñ€}(ˆ’ɪ†`e2X€H‹P‹Ø&ÑT 2)’ó‡XqŠ vˇPwŠ@Ã-0ËØu(–P@kÀ®ªÒŠ˜|Jœ 8ªÉ{u@Ž1‘P†[•r Ø ‹¥øÕø'G°€ëôzŠ3¥kĆƒÆðj,ƒÃ‹ ¸AÒˆ°{¡£€À ¨€XÃ@Ⱦ ª‡e€ðˆrÕ0Õ€xɪ™(‡0c…x ¬uÝš8.ˆÞ Þ ÁÍ›ßÛ’øÊ+†èb‹[);0 <ú-[@È8@ z5€x ;0pÁWÀ‚Õ‡qhr½Žl)  €HÈ|„Íð™H³{”ˆ¥ãzáó­ CCkÒ(ïÙ‚ëÿ6ÑÆ#ΚY“rØmcƒØ]…AW›ÐÇ ¥Ø@©ˆHæÝ¨e¬ýÆ¢‰½(}" €£ß@Ù†¾q½ØMèªÐ«(X«q+€u p}ÃùCŒ1ƒ¥çp ™E¡|Š‹É7úP€å õ¹Н .Z YΡ|Šüpm¨‚ˆØ ‹>Âi§)ððzŒºixR±Q€˜è.3˜‡«ñ,ðÃðŽ†¨h(kŽmü P£ÜuˆFPŽ ¯#Ù6˜ wÔ„¡“ÜD‡° ¨{ !]Œ‚@ɳÿLZtÞ–8\…’‚$¢hm9Xm ¨"“B.Ño†–W€€sÐcH{¢ ” h/€Õ‡â*Ðz"€Ìç‚âäÚ=•Rrª€øÂHއ8jåx€P‹s¬î¤¸Ѝj=Š˜Æ†ÀjšXs‡Xãà!éxÁ7[p·¡lÔe?6qJ6“uñþ7¿“ÙEÄàŽ6ÕKTCyï FTŵÀUŒ†xeSpyG€r†ù¥‡tX=È¢9£ }Ë"ª‡ˆrŠT̈pÔ{°p:W½;oE¾¶ñm ú¿ÒvTû Ñv4•?É´ýG› _Ôqyïx4ì[Ôûwñ6”mO¿dš—ñjqUDba8‡lŠˆw!Y‡m¼bcš=¯0  Øß€ˆ Ñm†œµ1Ü)Ðk^vP±Y ©£€©&Щ'Œ5£ ˆƒEh8zÌð¨ˆ8{ÛŸ‰hw‡È BÓ³è ˆØ )&† j3`{ ÒÕÕÑP*ºzkψIæ „‡hu‹ mÁ††¸f@ ¥.øÈµÀ©`-P€ÙÀȇ˜|n˜ý†ÈdÈàs‡I†€ˆ –0h­   €€h Œ€¼×hyŒ3Ç"¢é"£ˆp~½`€½«TŠ#ΈK¡ û!Œ2èåž‘ Nþ Ä˜(ÛÈŽõÈÒkX»‡G“H™Hcµ>0ÕØÀ§°Ü!N²€}Š Öž²Ö§p‹>Ãß_˜› 6*ùŽ/tÝœàÞ0h††Ÿ ¨÷ç#€ÀÜh)( €Â±+Èò“€s­Xð„ºêó³1½˜eP¾°¥œ"@j ,ñ9”fyfhô)Ñ8y-¸ëXPЀx"¸$˜Q8ôY0 -P£¤‡ª˜˜{>€5å/9P€P é.8 µu‘‰ÐkKPàƒ3 § z ºp±x½‡æÈ0§\!‡¸xH{ï6G%J8Ï9:‹°½Ì(‹Ù-ˆÌªr=xކÞ0X…i<8½²1‡ø g@ ±4)°ÆŠ¶¬%]zˆ+ÝLsõ O«2ß!|]ˆñ8›— XÃâ°Ã-ö`C@§8ySõSË ¸»«àÁ¥Ê¹>D’Hñ<Ñë­ âáçªTD ‚ˆ°£}«ª&굚Ýe!ùø’ˆAœ‹»/˜ho†œs†ø˜Œ€?@Рpþ¿€pPü~>áa¨ €NgæâlBÀÀ 8(>ž1×Ëú$ïq8@a ÜõÆ^mvdYòë?À@0 ~ €D(R‘ Ll¦}0J$?_À( =߈´(ö|½å6«(@' ÚÀ@,, Ÿð§¬"J?€@ °Â€X¸8”Ëd09  ýÿ•ÈtY­3@fŸÙün@ ‡ê@ ¬×™< L v¹šÀƒÆ …ÀC­Þr´Øœ€Èwfë?ŸVÉüvù€>ÞÃÙÏÄ}° 7´,ùƒàòÔl°.ž }ÄŸïÏîˆ „a€Š4yœ€âs›éJ ¢Lµ +F@[ n!Út çÁ懼F +Aîy,€Ø^&çcà~¥È<À`RîrFÐÆÛQ ñ2Êí€Ø25€ ·Îx# @3µ Äk·‡ñæøA¨|¡¸l”µhYþÆ4lƒY8Íó“4ÉÎÌ„ñ€Lò}µŒ ·Ç£àa—&@øwðI¢^¨°.€ zH AÐuh‡-ï(îYŠZà y« `J4uÂu8à‡G©Ì ¡2ÊòÔÀu‡rН´Ê–†Aj´hè;`…*È‚ÕÑÆyÀ<¤ ºž`ÊR~³í.Ó4"ˆÒ² ƒ,ÓO­ æÓ3Ó¼óz€wû9η­é…´×£I€µ±þÈ0Ì Ý8ÎŒÕàÏà a¨g¸æÉ¢oOÇczK9Än2ÇéôÞ‚éAÜŽ6`d4Î  á`W$Ÿ­HP:ÕN # x)œŸ­†Ì4‡æÎa­1ü·3:Íë‡ß­#:Èz³5§³T ìx|kZý÷9jØ[\ÖmÞ½¶aø5ë=ï:ÜâÒ3-‰|´À%îÐW ûÆGb{œ â õgÛ KAÐnÁ§AÈuT«` @¨.Ç¡3ë>Ÿ –ƒ ¸ˆa5\±‡Î^òK¬²Üwkaêy¢Gè—'2¢WêYÌsd‡Ñô¹i¬ûÆwÐZÇ)»XŸÇÃRðÑ|[™ÑÓÇŸ Š åç‰à‰/ˆPÊaNp?…„™òøŸEг+£¬pÒ‚û€ø")ãˆoü?x¬äãDK`éªÄ˯²ˆgÈ1€! –ôYÀC@ 'Ñö>ˆÈÅôr€}ãÑgCr$kGÀû,…Å÷ಇóx%ó ©P°ËB=‡Ã/`8’ÁþËÀ` C@l .áà\(ƒµâLx"«¸~ÆÒ>LHû>¥.‚Ð`]Êq©F´0VîbˆTi!PÕ°Tû" `õ.@l ¢È<(ñI#äç„14ù|1é麙’Cˆ÷ƒüÒÈ@‡àHCüy+è=Ž8þWX|¬3\ŒQr<%ô·d"äcÊU–qµ?$¤”².IÈìXcÍ1*èº?#JÏ}À }–ã(?€2ȃ—‚>Oi)°@ó‡